summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CREDITS12
-rw-r--r--Documentation/Changes13
-rw-r--r--Documentation/DocBook/Makefile2
-rw-r--r--Documentation/DocBook/journal-api.tmpl2
-rw-r--r--Documentation/DocBook/kernel-api.tmpl17
-rw-r--r--Documentation/DocBook/libata.tmpl1072
-rw-r--r--Documentation/DocBook/rapidio.tmpl160
-rw-r--r--Documentation/DocBook/usb.tmpl2
-rw-r--r--Documentation/DocBook/writing_usb_driver.tmpl3
-rw-r--r--Documentation/MSI-HOWTO.txt174
-rw-r--r--Documentation/RCU/torture.txt122
-rw-r--r--Documentation/RCU/whatisRCU.txt2
-rw-r--r--Documentation/arm/README7
-rw-r--r--Documentation/arm/Samsung-S3C24XX/Overview.txt41
-rw-r--r--Documentation/block/biodoc.txt113
-rw-r--r--Documentation/cachetlb.txt9
-rw-r--r--Documentation/connector/cn_test.c4
-rw-r--r--Documentation/cpusets.txt2
-rw-r--r--Documentation/device-mapper/snapshot.txt5
-rw-r--r--Documentation/driver-model/driver.txt68
-rw-r--r--Documentation/driver-model/porting.txt2
-rw-r--r--Documentation/dvb/bt8xx.txt64
-rw-r--r--Documentation/dvb/cards.txt37
-rw-r--r--Documentation/dvb/contributors.txt17
-rw-r--r--Documentation/dvb/get_dvb_firmware19
-rw-r--r--Documentation/fb/fbcon.txt152
-rw-r--r--Documentation/fb/vesafb.txt4
-rw-r--r--Documentation/feature-removal-schedule.txt45
-rw-r--r--Documentation/filesystems/dentry-locking.txt173
-rw-r--r--Documentation/filesystems/devfs/README5
-rw-r--r--Documentation/filesystems/ext2.txt2
-rw-r--r--Documentation/filesystems/ntfs.txt42
-rw-r--r--Documentation/filesystems/ramfs-rootfs-initramfs.txt195
-rw-r--r--Documentation/filesystems/vfs.txt434
-rw-r--r--Documentation/filesystems/xfs.txt142
-rw-r--r--Documentation/firmware_class/firmware_sample_driver.c1
-rw-r--r--Documentation/firmware_class/firmware_sample_firmware_class.c2
-rw-r--r--Documentation/hpet.txt34
-rw-r--r--Documentation/hwmon/it878
-rw-r--r--Documentation/hwmon/lm9047
-rw-r--r--Documentation/hwmon/smsc47b3978
-rw-r--r--Documentation/hwmon/smsc47m17
-rw-r--r--Documentation/hwmon/sysfs-interface3
-rw-r--r--Documentation/hwmon/via686a17
-rw-r--r--Documentation/i2c/busses/i2c-i8101
-rw-r--r--Documentation/i2c/busses/i2c-viapro29
-rw-r--r--Documentation/i2c/chips/x120538
-rw-r--r--Documentation/i2c/functionality7
-rw-r--r--Documentation/i2c/porting-clients2
-rw-r--r--Documentation/i2c/writing-clients30
-rw-r--r--Documentation/input/yealink.txt19
-rw-r--r--Documentation/ioctl-number.txt2
-rw-r--r--Documentation/kernel-parameters.txt4
-rw-r--r--Documentation/keys.txt22
-rw-r--r--Documentation/m68k/kernel-options.txt24
-rw-r--r--Documentation/magic-number.txt2
-rw-r--r--Documentation/md.txt119
-rw-r--r--Documentation/mips/AU1xxx_IDE.README168
-rw-r--r--Documentation/networking/README.ipw2100132
-rw-r--r--Documentation/networking/README.ipw2200196
-rw-r--r--Documentation/networking/bonding.txt5
-rw-r--r--Documentation/networking/dccp.txt56
-rw-r--r--Documentation/networking/decnet.txt2
-rw-r--r--Documentation/networking/ip-sysctl.txt7
-rw-r--r--Documentation/networking/s2io.txt199
-rw-r--r--Documentation/oops-tracing.txt2
-rw-r--r--Documentation/power/video.txt17
-rw-r--r--Documentation/s390/Debugging390.txt2
-rw-r--r--Documentation/s390/driver-model.txt21
-rw-r--r--Documentation/sched-arch.txt89
-rw-r--r--Documentation/scsi/LICENSE.qla2xxx45
-rw-r--r--Documentation/serial/driver66
-rw-r--r--Documentation/sharedsubtree.txt1060
-rw-r--r--Documentation/sound/alsa/ALSA-Configuration.txt29
-rw-r--r--Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl56
-rw-r--r--Documentation/sparse.txt4
-rw-r--r--Documentation/video4linux/API.html2
-rw-r--r--Documentation/video4linux/CARDLIST.bttv279
-rw-r--r--Documentation/video4linux/CARDLIST.cx8869
-rw-r--r--Documentation/video4linux/CARDLIST.em28xx10
-rw-r--r--Documentation/video4linux/CARDLIST.saa713429
-rw-r--r--Documentation/video4linux/CARDLIST.tuner4
-rw-r--r--Documentation/video4linux/README.cx888
-rw-r--r--Documentation/video4linux/README.saa71342
-rw-r--r--Documentation/video4linux/bttv/Cards18
-rw-r--r--Documentation/video4linux/bttv/README6
-rw-r--r--Documentation/video4linux/bttv/README.freeze6
-rw-r--r--Documentation/video4linux/bttv/Sound-FAQ12
-rw-r--r--Documentation/video4linux/bttv/Tuners4
-rw-r--r--Documentation/video4linux/lifeview.txt58
-rw-r--r--Documentation/vm/hugetlbpage.txt25
-rw-r--r--MAINTAINERS116
-rw-r--r--Makefile18
-rw-r--r--README4
-rw-r--r--arch/alpha/kernel/pci-noop.c2
-rw-r--r--arch/alpha/kernel/pci_iommu.c2
-rw-r--r--arch/alpha/kernel/process.c10
-rw-r--r--arch/alpha/kernel/time.c4
-rw-r--r--arch/alpha/mm/numa.c3
-rw-r--r--arch/alpha/mm/remap.c6
-rw-r--r--arch/arm/Kconfig33
-rw-r--r--arch/arm/Makefile19
-rw-r--r--arch/arm/boot/compressed/misc.c8
-rw-r--r--arch/arm/common/amba.c2
-rw-r--r--arch/arm/common/dmabounce.c165
-rw-r--r--arch/arm/common/locomo.c12
-rw-r--r--arch/arm/common/sa1111.c13
-rw-r--r--arch/arm/common/scoop.c32
-rw-r--r--arch/arm/configs/ixdp2400_defconfig2
-rw-r--r--arch/arm/configs/ixdp2401_defconfig4
-rw-r--r--arch/arm/configs/ixdp2800_defconfig2
-rw-r--r--arch/arm/configs/ixdp2801_defconfig2
-rw-r--r--arch/arm/configs/ixp4xx_defconfig2
-rw-r--r--arch/arm/configs/omap_h2_1610_defconfig97
-rw-r--r--arch/arm/configs/realview_defconfig789
-rw-r--r--arch/arm/kernel/Makefile2
-rw-r--r--arch/arm/kernel/armksyms.c4
-rw-r--r--arch/arm/kernel/arthur.c1
-rw-r--r--arch/arm/kernel/asm-offsets.c1
-rw-r--r--arch/arm/kernel/entry-armv.S25
-rw-r--r--arch/arm/kernel/head.S57
-rw-r--r--arch/arm/kernel/irq.c34
-rw-r--r--arch/arm/kernel/module.c1
-rw-r--r--arch/arm/kernel/process.c29
-rw-r--r--arch/arm/kernel/ptrace.c49
-rw-r--r--arch/arm/kernel/setup.c10
-rw-r--r--arch/arm/kernel/signal.c96
-rw-r--r--arch/arm/kernel/smp.c156
-rw-r--r--arch/arm/kernel/time.c4
-rw-r--r--arch/arm/kernel/traps.c47
-rw-r--r--arch/arm/kernel/vmlinux.lds.S11
-rw-r--r--arch/arm/lib/Makefile24
-rw-r--r--arch/arm/lib/ashldi3.S48
-rw-r--r--arch/arm/lib/ashldi3.c56
-rw-r--r--arch/arm/lib/ashrdi3.S48
-rw-r--r--arch/arm/lib/ashrdi3.c57
-rw-r--r--arch/arm/lib/bitops.h6
-rw-r--r--arch/arm/lib/clear_user.S52
-rw-r--r--arch/arm/lib/copy_from_user.S101
-rw-r--r--arch/arm/lib/copy_template.S255
-rw-r--r--arch/arm/lib/copy_to_user.S101
-rw-r--r--arch/arm/lib/csumpartial.S4
-rw-r--r--arch/arm/lib/gcclib.h22
-rw-r--r--arch/arm/lib/lshrdi3.S48
-rw-r--r--arch/arm/lib/lshrdi3.c56
-rw-r--r--arch/arm/lib/memcpy.S410
-rw-r--r--arch/arm/lib/memmove.S206
-rw-r--r--arch/arm/lib/muldi3.S44
-rw-r--r--arch/arm/lib/muldi3.c72
-rw-r--r--arch/arm/lib/sha1.S206
-rw-r--r--arch/arm/lib/uaccess.S170
-rw-r--r--arch/arm/lib/ucmpdi2.S35
-rw-r--r--arch/arm/lib/ucmpdi2.c49
-rw-r--r--arch/arm/mach-aaec2000/Makefile2
-rw-r--r--arch/arm/mach-aaec2000/aaed2000.c50
-rw-r--r--arch/arm/mach-aaec2000/clock.c111
-rw-r--r--arch/arm/mach-aaec2000/clock.h23
-rw-r--r--arch/arm/mach-aaec2000/core.c135
-rw-r--r--arch/arm/mach-aaec2000/core.h11
-rw-r--r--arch/arm/mach-clps711x/autcpu12.c12
-rw-r--r--arch/arm/mach-clps711x/cdb89712.c7
-rw-r--r--arch/arm/mach-clps711x/ceiva.c12
-rw-r--r--arch/arm/mach-clps711x/edb7211-mm.c30
-rw-r--r--arch/arm/mach-clps711x/mm.c8
-rw-r--r--arch/arm/mach-clps711x/p720t.c14
-rw-r--r--arch/arm/mach-clps7500/core.c25
-rw-r--r--arch/arm/mach-ebsa110/core.c64
-rw-r--r--arch/arm/mach-ebsa110/io.c1
-rw-r--r--arch/arm/mach-epxa10db/mm.c38
-rw-r--r--arch/arm/mach-footbridge/common.c57
-rw-r--r--arch/arm/mach-h720x/common.c7
-rw-r--r--arch/arm/mach-h720x/h7202-eval.c2
-rw-r--r--arch/arm/mach-imx/generic.c12
-rw-r--r--arch/arm/mach-imx/mx1ads.c39
-rw-r--r--arch/arm/mach-integrator/clock.c1
-rw-r--r--arch/arm/mach-integrator/impd1.c3
-rw-r--r--arch/arm/mach-integrator/integrator_ap.c82
-rw-r--r--arch/arm/mach-integrator/integrator_cp.c69
-rw-r--r--arch/arm/mach-integrator/lm.c1
-rw-r--r--arch/arm/mach-iop3xx/iop321-setup.c20
-rw-r--r--arch/arm/mach-iop3xx/iop331-setup.c20
-rw-r--r--arch/arm/mach-iop3xx/iq31244-mm.c10
-rw-r--r--arch/arm/mach-iop3xx/iq31244-pci.c2
-rw-r--r--arch/arm/mach-iop3xx/iq80321-mm.c10
-rw-r--r--arch/arm/mach-iop3xx/iq80321-pci.c2
-rw-r--r--arch/arm/mach-iop3xx/iq80331-pci.c2
-rw-r--r--arch/arm/mach-iop3xx/iq80332-pci.c2
-rw-r--r--arch/arm/mach-ixp2000/Makefile2
-rw-r--r--arch/arm/mach-ixp2000/core.c130
-rw-r--r--arch/arm/mach-ixp2000/enp2611.c33
-rw-r--r--arch/arm/mach-ixp2000/ixdp2x00.c8
-rw-r--r--arch/arm/mach-ixp2000/ixdp2x01.c13
-rw-r--r--arch/arm/mach-ixp2000/pci.c6
-rw-r--r--arch/arm/mach-ixp2000/uengine.c473
-rw-r--r--arch/arm/mach-ixp4xx/Kconfig10
-rw-r--r--arch/arm/mach-ixp4xx/Makefile1
-rw-r--r--arch/arm/mach-ixp4xx/common-pci.c2
-rw-r--r--arch/arm/mach-ixp4xx/common.c9
-rw-r--r--arch/arm/mach-ixp4xx/nslu2-pci.c77
-rw-r--r--arch/arm/mach-ixp4xx/nslu2-power.c92
-rw-r--r--arch/arm/mach-ixp4xx/nslu2-setup.c134
-rw-r--r--arch/arm/mach-lh7a40x/arch-kev7a400.c13
-rw-r--r--arch/arm/mach-lh7a40x/arch-lpd7a40x.c88
-rw-r--r--arch/arm/mach-omap1/Kconfig32
-rw-r--r--arch/arm/mach-omap1/Makefile5
-rw-r--r--arch/arm/mach-omap1/board-generic.c33
-rw-r--r--arch/arm/mach-omap1/board-h2.c17
-rw-r--r--arch/arm/mach-omap1/board-h3.c21
-rw-r--r--arch/arm/mach-omap1/board-innovator.c52
-rw-r--r--arch/arm/mach-omap1/board-netstar.c17
-rw-r--r--arch/arm/mach-omap1/board-osk.c19
-rw-r--r--arch/arm/mach-omap1/board-palmte.c87
-rw-r--r--arch/arm/mach-omap1/board-perseus2.c33
-rw-r--r--arch/arm/mach-omap1/board-voiceblue.c11
-rw-r--r--arch/arm/mach-omap1/clock.c792
-rw-r--r--arch/arm/mach-omap1/clock.h768
-rw-r--r--arch/arm/mach-omap1/devices.c223
-rw-r--r--arch/arm/mach-omap1/id.c9
-rw-r--r--arch/arm/mach-omap1/io.c59
-rw-r--r--arch/arm/mach-omap1/irq.c23
-rw-r--r--arch/arm/mach-omap1/leds-h2p2-debug.c44
-rw-r--r--arch/arm/mach-omap1/leds.c1
-rw-r--r--arch/arm/mach-omap1/mux.c289
-rw-r--r--arch/arm/mach-omap1/serial.c9
-rw-r--r--arch/arm/mach-omap1/time.c4
-rw-r--r--arch/arm/mach-omap2/Kconfig22
-rw-r--r--arch/arm/mach-omap2/Makefile13
-rw-r--r--arch/arm/mach-omap2/Makefile.boot3
-rw-r--r--arch/arm/mach-omap2/board-generic.c80
-rw-r--r--arch/arm/mach-omap2/board-h4.c197
-rw-r--r--arch/arm/mach-omap2/clock.c1129
-rw-r--r--arch/arm/mach-omap2/clock.h2103
-rw-r--r--arch/arm/mach-omap2/devices.c89
-rw-r--r--arch/arm/mach-omap2/id.c124
-rw-r--r--arch/arm/mach-omap2/io.c53
-rw-r--r--arch/arm/mach-omap2/irq.c149
-rw-r--r--arch/arm/mach-omap2/mux.c65
-rw-r--r--arch/arm/mach-omap2/prcm.h419
-rw-r--r--arch/arm/mach-omap2/serial.c180
-rw-r--r--arch/arm/mach-omap2/sram-fn.S333
-rw-r--r--arch/arm/mach-omap2/timer-gp.c126
-rw-r--r--arch/arm/mach-pxa/Kconfig16
-rw-r--r--arch/arm/mach-pxa/Makefile6
-rw-r--r--arch/arm/mach-pxa/corgi.c70
-rw-r--r--arch/arm/mach-pxa/corgi_lcd.c3
-rw-r--r--arch/arm/mach-pxa/corgi_ssp.c28
-rw-r--r--arch/arm/mach-pxa/generic.c85
-rw-r--r--arch/arm/mach-pxa/idp.c23
-rw-r--r--arch/arm/mach-pxa/lubbock.c172
-rw-r--r--arch/arm/mach-pxa/mainstone.c124
-rw-r--r--arch/arm/mach-pxa/pm.c16
-rw-r--r--arch/arm/mach-pxa/poodle.c55
-rw-r--r--arch/arm/mach-pxa/pxa25x.c2
-rw-r--r--arch/arm/mach-pxa/pxa27x.c4
-rw-r--r--arch/arm/mach-pxa/sharpsl.h87
-rw-r--r--arch/arm/mach-pxa/sharpsl_pm.c992
-rw-r--r--arch/arm/mach-pxa/sleep.S7
-rw-r--r--arch/arm/mach-pxa/spitz.c116
-rw-r--r--arch/arm/mach-pxa/ssp.c128
-rw-r--r--arch/arm/mach-pxa/standby.S2
-rw-r--r--arch/arm/mach-pxa/time.c8
-rw-r--r--arch/arm/mach-pxa/tosa.c306
-rw-r--r--arch/arm/mach-realview/Kconfig20
-rw-r--r--arch/arm/mach-realview/Makefile9
-rw-r--r--arch/arm/mach-realview/Makefile.boot4
-rw-r--r--arch/arm/mach-realview/clock.c145
-rw-r--r--arch/arm/mach-realview/clock.h25
-rw-r--r--arch/arm/mach-realview/core.c610
-rw-r--r--arch/arm/mach-realview/core.h119
-rw-r--r--arch/arm/mach-realview/headsmp.S39
-rw-r--r--arch/arm/mach-realview/hotplug.c138
-rw-r--r--arch/arm/mach-realview/localtimer.c130
-rw-r--r--arch/arm/mach-realview/platsmp.c200
-rw-r--r--arch/arm/mach-realview/realview_eb.c177
-rw-r--r--arch/arm/mach-rpc/riscpc.c19
-rw-r--r--arch/arm/mach-s3c2410/Kconfig8
-rw-r--r--arch/arm/mach-s3c2410/clock.c2
-rw-r--r--arch/arm/mach-s3c2410/cpu.c2
-rw-r--r--arch/arm/mach-s3c2410/cpu.h2
-rw-r--r--arch/arm/mach-s3c2410/devs.c38
-rw-r--r--arch/arm/mach-s3c2410/devs.h1
-rw-r--r--arch/arm/mach-s3c2410/gpio.c22
-rw-r--r--arch/arm/mach-s3c2410/mach-anubis.c53
-rw-r--r--arch/arm/mach-s3c2410/mach-bast.c115
-rw-r--r--arch/arm/mach-s3c2410/mach-h1940.c4
-rw-r--r--arch/arm/mach-s3c2410/mach-n30.c2
-rw-r--r--arch/arm/mach-s3c2410/mach-nexcoder.c2
-rw-r--r--arch/arm/mach-s3c2410/mach-otom.c2
-rw-r--r--arch/arm/mach-s3c2410/mach-rx3715.c84
-rw-r--r--arch/arm/mach-s3c2410/mach-smdk2410.c1
-rw-r--r--arch/arm/mach-s3c2410/mach-smdk2440.c94
-rw-r--r--arch/arm/mach-s3c2410/mach-vr1000.c56
-rw-r--r--arch/arm/mach-s3c2410/s3c2410.c2
-rw-r--r--arch/arm/mach-s3c2410/s3c2440.c2
-rw-r--r--arch/arm/mach-sa1100/assabet.c14
-rw-r--r--arch/arm/mach-sa1100/badge4.c22
-rw-r--r--arch/arm/mach-sa1100/cerf.c10
-rw-r--r--arch/arm/mach-sa1100/collie.c16
-rw-r--r--arch/arm/mach-sa1100/generic.c30
-rw-r--r--arch/arm/mach-sa1100/h3600.c20
-rw-r--r--arch/arm/mach-sa1100/hackkit.c8
-rw-r--r--arch/arm/mach-sa1100/jornada720.c86
-rw-r--r--arch/arm/mach-sa1100/lart.c14
-rw-r--r--arch/arm/mach-sa1100/neponset.c46
-rw-r--r--arch/arm/mach-sa1100/pleb.c2
-rw-r--r--arch/arm/mach-sa1100/simpad.c18
-rw-r--r--arch/arm/mach-sa1100/time.c8
-rw-r--r--arch/arm/mach-shark/core.c7
-rw-r--r--arch/arm/mach-versatile/clock.c1
-rw-r--r--arch/arm/mach-versatile/core.c84
-rw-r--r--arch/arm/mm/Kconfig22
-rw-r--r--arch/arm/mm/consistent.c14
-rw-r--r--arch/arm/mm/copypage-v6.c16
-rw-r--r--arch/arm/mm/fault-armv.c7
-rw-r--r--arch/arm/mm/init.c495
-rw-r--r--arch/arm/mm/ioremap.c5
-rw-r--r--arch/arm/mm/mm-armv.c235
-rw-r--r--arch/arm/mm/proc-v6.S26
-rw-r--r--arch/arm/nwfpe/fpa11.h2
-rw-r--r--arch/arm/nwfpe/fpa11_cpdt.c10
-rw-r--r--arch/arm/nwfpe/fpopcode.c16
-rw-r--r--arch/arm/nwfpe/softfloat-specialize1
-rw-r--r--arch/arm/nwfpe/softfloat.c6
-rw-r--r--arch/arm/nwfpe/softfloat.h14
-rw-r--r--arch/arm/oprofile/Makefile4
-rw-r--r--arch/arm/oprofile/backtrace.c46
-rw-r--r--arch/arm/oprofile/common.c185
-rw-r--r--arch/arm/oprofile/init.c33
-rw-r--r--arch/arm/oprofile/op_arm_model.h4
-rw-r--r--arch/arm/plat-omap/Makefile2
-rw-r--r--arch/arm/plat-omap/clock.c1316
-rw-r--r--arch/arm/plat-omap/clock.h120
-rw-r--r--arch/arm/plat-omap/common.c50
-rw-r--r--arch/arm/plat-omap/devices.c381
-rw-r--r--arch/arm/plat-omap/dma.c910
-rw-r--r--arch/arm/plat-omap/gpio.c40
-rw-r--r--arch/arm/plat-omap/mcbsp.c22
-rw-r--r--arch/arm/plat-omap/mux.c65
-rw-r--r--arch/arm/plat-omap/ocpi.c1
-rw-r--r--arch/arm/plat-omap/pm.c103
-rw-r--r--arch/arm/plat-omap/sleep.S139
-rw-r--r--arch/arm/plat-omap/sram.c145
-rw-r--r--arch/arm/plat-omap/sram.h21
-rw-r--r--arch/arm/plat-omap/usb.c13
-rw-r--r--arch/arm26/kernel/process.c12
-rw-r--r--arch/arm26/kernel/ptrace.c49
-rw-r--r--arch/arm26/kernel/time.c4
-rw-r--r--arch/arm26/mm/memc.c18
-rw-r--r--arch/cris/arch-v10/README.mm6
-rw-r--r--arch/cris/arch-v10/drivers/axisflashmap.c1
-rw-r--r--arch/cris/arch-v10/drivers/pcf8563.c1
-rw-r--r--arch/cris/arch-v10/kernel/fasttimer.c1
-rw-r--r--arch/cris/arch-v10/kernel/ptrace.c51
-rw-r--r--arch/cris/arch-v10/kernel/signal.c2
-rw-r--r--arch/cris/arch-v32/drivers/axisflashmap.c1
-rw-r--r--arch/cris/arch-v32/drivers/cryptocop.c14
-rw-r--r--arch/cris/arch-v32/drivers/nandflash.c1
-rw-r--r--arch/cris/arch-v32/drivers/pcf8563.c1
-rw-r--r--arch/cris/arch-v32/kernel/ptrace.c51
-rw-r--r--arch/cris/arch-v32/kernel/signal.c2
-rw-r--r--arch/cris/arch-v32/kernel/smp.c1
-rw-r--r--arch/cris/arch-v32/mm/tlb.c6
-rw-r--r--arch/cris/kernel/process.c2
-rw-r--r--arch/cris/kernel/time.c5
-rw-r--r--arch/cris/mm/ioremap.c6
-rw-r--r--arch/frv/kernel/process.c6
-rw-r--r--arch/frv/kernel/ptrace.c43
-rw-r--r--arch/frv/kernel/time.c4
-rw-r--r--arch/frv/mb93090-mb00/pci-dma-nommu.c2
-rw-r--r--arch/frv/mb93090-mb00/pci-dma.c2
-rw-r--r--arch/frv/mm/dma-alloc.c7
-rw-r--r--arch/frv/mm/pgalloc.c4
-rw-r--r--arch/h8300/kernel/process.c28
-rw-r--r--arch/h8300/kernel/ptrace.c39
-rw-r--r--arch/h8300/kernel/time.c4
-rw-r--r--arch/i386/Kconfig328
-rw-r--r--arch/i386/Kconfig.cpu309
-rw-r--r--arch/i386/Kconfig.debug10
-rw-r--r--arch/i386/Makefile31
-rw-r--r--arch/i386/Makefile.cpu41
-rw-r--r--arch/i386/kernel/apic.c15
-rw-r--r--arch/i386/kernel/apm.c65
-rw-r--r--arch/i386/kernel/cpu/common.c20
-rw-r--r--arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c4
-rw-r--r--arch/i386/kernel/cpu/cpufreq/p4-clockmod.c1
-rw-r--r--arch/i386/kernel/cpu/cpufreq/powernow-k7.c12
-rw-r--r--arch/i386/kernel/cpu/cpufreq/powernow-k8.c20
-rw-r--r--arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c6
-rw-r--r--arch/i386/kernel/cpu/intel_cacheinfo.c87
-rw-r--r--arch/i386/kernel/cpu/mcheck/k7.c2
-rw-r--r--arch/i386/kernel/cpu/mcheck/mce.c4
-rw-r--r--arch/i386/kernel/cpu/mcheck/p4.c4
-rw-r--r--arch/i386/kernel/cpu/mcheck/p5.c2
-rw-r--r--arch/i386/kernel/cpu/mcheck/p6.c13
-rw-r--r--arch/i386/kernel/cpu/mcheck/winchip.c2
-rw-r--r--arch/i386/kernel/cpu/mtrr/if.c119
-rw-r--r--arch/i386/kernel/cpu/proc.c2
-rw-r--r--arch/i386/kernel/cpuid.c2
-rw-r--r--arch/i386/kernel/crash.c7
-rw-r--r--arch/i386/kernel/io_apic.c147
-rw-r--r--arch/i386/kernel/ioport.c3
-rw-r--r--arch/i386/kernel/irq.c8
-rw-r--r--arch/i386/kernel/kprobes.c180
-rw-r--r--arch/i386/kernel/ldt.c1
-rw-r--r--arch/i386/kernel/mca.c2
-rw-r--r--arch/i386/kernel/mpparse.c41
-rw-r--r--arch/i386/kernel/msr.c2
-rw-r--r--arch/i386/kernel/nmi.c39
-rw-r--r--arch/i386/kernel/process.c68
-rw-r--r--arch/i386/kernel/ptrace.c44
-rw-r--r--arch/i386/kernel/reboot_fixups.c5
-rw-r--r--arch/i386/kernel/scx200.c1
-rw-r--r--arch/i386/kernel/setup.c26
-rw-r--r--arch/i386/kernel/smpboot.c9
-rw-r--r--arch/i386/kernel/srat.c7
-rw-r--r--arch/i386/kernel/time.c4
-rw-r--r--arch/i386/kernel/time_hpet.c20
-rw-r--r--arch/i386/kernel/timers/timer_hpet.c17
-rw-r--r--arch/i386/kernel/timers/timer_tsc.c21
-rw-r--r--arch/i386/kernel/traps.c1
-rw-r--r--arch/i386/kernel/vm86.c17
-rw-r--r--arch/i386/mach-es7000/es7000.h11
-rw-r--r--arch/i386/mach-es7000/es7000plat.c11
-rw-r--r--arch/i386/mm/discontig.c4
-rw-r--r--arch/i386/mm/fault.c2
-rw-r--r--arch/i386/mm/init.c62
-rw-r--r--arch/i386/mm/ioremap.c4
-rw-r--r--arch/i386/mm/pgtable.c11
-rw-r--r--arch/i386/oprofile/Kconfig6
-rw-r--r--arch/i386/oprofile/backtrace.c38
-rw-r--r--arch/i386/pci/fixup.c58
-rw-r--r--arch/i386/pci/irq.c55
-rw-r--r--arch/i386/power/cpu.c13
-rw-r--r--arch/ia64/Kconfig116
-rw-r--r--arch/ia64/Kconfig.debug11
-rw-r--r--arch/ia64/configs/bigsur_defconfig395
-rw-r--r--arch/ia64/configs/gensparse_defconfig1319
-rw-r--r--arch/ia64/configs/tiger_defconfig86
-rw-r--r--arch/ia64/configs/zx1_defconfig92
-rw-r--r--arch/ia64/defconfig265
-rw-r--r--arch/ia64/hp/common/hwsw_iommu.c15
-rw-r--r--arch/ia64/hp/common/sba_iommu.c47
-rw-r--r--arch/ia64/hp/sim/simscsi.c13
-rw-r--r--arch/ia64/hp/sim/simserial.c6
-rw-r--r--arch/ia64/ia32/ia32_ioctl.c4
-rw-r--r--arch/ia64/ia32/sys_ia32.c1
-rw-r--r--arch/ia64/kernel/acpi.c13
-rw-r--r--arch/ia64/kernel/cyclone.c1
-rw-r--r--arch/ia64/kernel/efi.c510
-rw-r--r--arch/ia64/kernel/irq.c12
-rw-r--r--arch/ia64/kernel/kprobes.c144
-rw-r--r--arch/ia64/kernel/mca.c124
-rw-r--r--arch/ia64/kernel/mca_drv.c20
-rw-r--r--arch/ia64/kernel/module.c6
-rw-r--r--arch/ia64/kernel/patch.c16
-rw-r--r--arch/ia64/kernel/perfmon.c5
-rw-r--r--arch/ia64/kernel/process.c40
-rw-r--r--arch/ia64/kernel/ptrace.c28
-rw-r--r--arch/ia64/kernel/setup.c71
-rw-r--r--arch/ia64/kernel/signal.c11
-rw-r--r--arch/ia64/kernel/smp.c10
-rw-r--r--arch/ia64/kernel/smpboot.c7
-rw-r--r--arch/ia64/kernel/time.c4
-rw-r--r--arch/ia64/kernel/traps.c44
-rw-r--r--arch/ia64/kernel/uncached.c17
-rw-r--r--arch/ia64/lib/Makefile2
-rw-r--r--arch/ia64/mm/Makefile5
-rw-r--r--arch/ia64/mm/contig.c4
-rw-r--r--arch/ia64/mm/discontig.c69
-rw-r--r--arch/ia64/mm/fault.c34
-rw-r--r--arch/ia64/mm/init.c15
-rw-r--r--arch/ia64/mm/numa.c24
-rw-r--r--arch/ia64/mm/tlb.c100
-rw-r--r--arch/ia64/oprofile/Kconfig6
-rw-r--r--arch/ia64/pci/pci.c164
-rw-r--r--arch/ia64/sn/kernel/bte.c2
-rw-r--r--arch/ia64/sn/kernel/io_init.c6
-rw-r--r--arch/ia64/sn/kernel/setup.c160
-rw-r--r--arch/ia64/sn/kernel/sn2/sn2_smp.c31
-rw-r--r--arch/ia64/sn/kernel/sn2/sn_hwperf.c4
-rw-r--r--arch/ia64/sn/kernel/tiocx.c67
-rw-r--r--arch/ia64/sn/kernel/xpc.h370
-rw-r--r--arch/ia64/sn/kernel/xpc_channel.c329
-rw-r--r--arch/ia64/sn/kernel/xpc_main.c432
-rw-r--r--arch/ia64/sn/kernel/xpc_partition.c483
-rw-r--r--arch/ia64/sn/pci/pci_dma.c48
-rw-r--r--arch/ia64/sn/pci/pcibr/pcibr_provider.c4
-rw-r--r--arch/ia64/sn/pci/pcibr/pcibr_reg.c59
-rw-r--r--arch/ia64/sn/pci/tioca_provider.c32
-rw-r--r--arch/ia64/sn/pci/tioce_provider.c36
-rw-r--r--arch/m32r/kernel/entry.S2
-rw-r--r--arch/m32r/kernel/io_m32700ut.c6
-rw-r--r--arch/m32r/kernel/io_mappi.c2
-rw-r--r--arch/m32r/kernel/io_mappi2.c11
-rw-r--r--arch/m32r/kernel/io_mappi3.c7
-rw-r--r--arch/m32r/kernel/io_oaks32r.c2
-rw-r--r--arch/m32r/kernel/io_opsput.c8
-rw-r--r--arch/m32r/kernel/io_usrv.c2
-rw-r--r--arch/m32r/kernel/process.c2
-rw-r--r--arch/m32r/kernel/ptrace.c2
-rw-r--r--arch/m32r/kernel/setup.c24
-rw-r--r--arch/m32r/kernel/setup_m32700ut.c2
-rw-r--r--arch/m32r/kernel/setup_mappi.c2
-rw-r--r--arch/m32r/kernel/setup_mappi2.c2
-rw-r--r--arch/m32r/kernel/setup_mappi3.c2
-rw-r--r--arch/m32r/kernel/setup_opsput.c2
-rw-r--r--arch/m32r/kernel/smpboot.c1
-rw-r--r--arch/m32r/kernel/time.c4
-rw-r--r--arch/m32r/lib/csum_partial_copy.c2
-rw-r--r--arch/m32r/mm/init.c9
-rw-r--r--arch/m32r/mm/ioremap.c4
-rw-r--r--arch/m68k/Kconfig24
-rw-r--r--arch/m68k/atari/stram.c918
-rw-r--r--arch/m68k/atari/time.c6
-rw-r--r--arch/m68k/kernel/process.c2
-rw-r--r--arch/m68k/kernel/ptrace.c47
-rw-r--r--arch/m68k/kernel/time.c4
-rw-r--r--arch/m68k/mm/kmap.c2
-rw-r--r--arch/m68k/sun3x/dvma.c2
-rw-r--r--arch/m68knommu/Kconfig17
-rw-r--r--arch/m68knommu/Makefile7
-rw-r--r--arch/m68knommu/defconfig3
-rw-r--r--arch/m68knommu/kernel/asm-offsets.c1
-rw-r--r--arch/m68knommu/kernel/ptrace.c39
-rw-r--r--arch/m68knommu/kernel/setup.c5
-rw-r--r--arch/m68knommu/kernel/time.c4
-rw-r--r--arch/m68knommu/kernel/vmlinux.lds.S9
-rw-r--r--arch/m68knommu/platform/520x/Makefile19
-rw-r--r--arch/m68knommu/platform/520x/config.c65
-rw-r--r--arch/m68knommu/platform/5307/Makefile1
-rw-r--r--arch/m68knommu/platform/5307/head.S3
-rw-r--r--arch/m68knommu/platform/5307/ints.c1
-rw-r--r--arch/m68knommu/platform/5307/pit.c12
-rw-r--r--arch/mips/Kconfig1510
-rw-r--r--arch/mips/Makefile118
-rw-r--r--arch/mips/arc/Makefile2
-rw-r--r--arch/mips/arc/identify.c5
-rw-r--r--arch/mips/au1000/common/Makefile2
-rw-r--r--arch/mips/au1000/common/au1xxx_irqmap.c32
-rw-r--r--arch/mips/au1000/common/cputable.c3
-rw-r--r--arch/mips/au1000/common/dbdma.c319
-rw-r--r--arch/mips/au1000/common/dma.c1
-rw-r--r--arch/mips/au1000/common/gpio.c119
-rw-r--r--arch/mips/au1000/common/irq.c105
-rw-r--r--arch/mips/au1000/common/platform.c249
-rw-r--r--arch/mips/au1000/common/power.c19
-rw-r--r--arch/mips/au1000/common/prom.c3
-rw-r--r--arch/mips/au1000/common/puts.c77
-rw-r--r--arch/mips/au1000/common/setup.c23
-rw-r--r--arch/mips/au1000/common/time.c26
-rw-r--r--arch/mips/au1000/common/usbdev.c12
-rw-r--r--arch/mips/au1000/csb250/init.c1
-rw-r--r--arch/mips/au1000/db1x00/irqmap.c32
-rw-r--r--arch/mips/au1000/db1x00/mirage_ts.c16
-rw-r--r--arch/mips/au1000/hydrogen3/init.c1
-rw-r--r--arch/mips/au1000/mtx-1/init.c1
-rw-r--r--arch/mips/au1000/mtx-1/irqmap.c11
-rw-r--r--arch/mips/au1000/pb1000/init.c1
-rw-r--r--arch/mips/au1000/pb1200/Makefile5
-rw-r--r--arch/mips/au1000/pb1200/board_setup.c193
-rw-r--r--arch/mips/au1000/pb1200/init.c69
-rw-r--r--arch/mips/au1000/pb1200/irqmap.c182
-rw-r--r--arch/mips/au1000/pb1500/irqmap.c5
-rw-r--r--arch/mips/au1000/pb1550/irqmap.c5
-rw-r--r--arch/mips/boot/.gitignore4
-rw-r--r--arch/mips/boot/Makefile4
-rw-r--r--arch/mips/cobalt/Makefile2
-rw-r--r--arch/mips/cobalt/int-handler.S4
-rw-r--r--arch/mips/cobalt/irq.c111
-rw-r--r--arch/mips/cobalt/promcon.c87
-rw-r--r--arch/mips/cobalt/reset.c59
-rw-r--r--arch/mips/cobalt/setup.c104
-rw-r--r--arch/mips/configs/atlas_defconfig660
-rw-r--r--arch/mips/configs/bigsur_defconfig881
-rw-r--r--arch/mips/configs/capcella_defconfig450
-rw-r--r--arch/mips/configs/cobalt_defconfig367
-rw-r--r--arch/mips/configs/db1000_defconfig498
-rw-r--r--arch/mips/configs/db1100_defconfig558
-rw-r--r--arch/mips/configs/db1200_defconfig987
-rw-r--r--arch/mips/configs/db1500_defconfig459
-rw-r--r--arch/mips/configs/db1550_defconfig441
-rw-r--r--arch/mips/configs/ddb5476_defconfig390
-rw-r--r--arch/mips/configs/ddb5477_defconfig377
-rw-r--r--arch/mips/configs/decstation_defconfig463
-rw-r--r--arch/mips/configs/e55_defconfig403
-rw-r--r--arch/mips/configs/ev64120_defconfig376
-rw-r--r--arch/mips/configs/ev96100_defconfig359
-rw-r--r--arch/mips/configs/ip22_defconfig479
-rw-r--r--arch/mips/configs/ip27_defconfig466
-rw-r--r--arch/mips/configs/ip32_defconfig390
-rw-r--r--arch/mips/configs/it8172_defconfig372
-rw-r--r--arch/mips/configs/ivr_defconfig376
-rw-r--r--arch/mips/configs/jaguar-atx_defconfig339
-rw-r--r--arch/mips/configs/jmr3927_defconfig389
-rw-r--r--arch/mips/configs/lasat200_defconfig378
-rw-r--r--arch/mips/configs/malta_defconfig724
-rw-r--r--arch/mips/configs/mipssim_defconfig775
-rw-r--r--arch/mips/configs/mpc30x_defconfig607
-rw-r--r--arch/mips/configs/ocelot_3_defconfig458
-rw-r--r--arch/mips/configs/ocelot_c_defconfig372
-rw-r--r--arch/mips/configs/ocelot_defconfig359
-rw-r--r--arch/mips/configs/ocelot_g_defconfig372
-rw-r--r--arch/mips/configs/pb1100_defconfig434
-rw-r--r--arch/mips/configs/pb1500_defconfig512
-rw-r--r--arch/mips/configs/pb1550_defconfig508
-rw-r--r--arch/mips/configs/pnx8550-jbs_defconfig1070
-rw-r--r--arch/mips/configs/pnx8550-v2pci_defconfig1252
-rw-r--r--arch/mips/configs/qemu_defconfig106
-rw-r--r--arch/mips/configs/rbhma4500_defconfig1258
-rw-r--r--arch/mips/configs/rm200_defconfig801
-rw-r--r--arch/mips/configs/sb1250-swarm_defconfig397
-rw-r--r--arch/mips/configs/sead_defconfig234
-rw-r--r--arch/mips/configs/tb0226_defconfig684
-rw-r--r--arch/mips/configs/tb0229_defconfig541
-rw-r--r--arch/mips/configs/tb0287_defconfig170
-rw-r--r--arch/mips/configs/workpad_defconfig416
-rw-r--r--arch/mips/configs/yosemite_defconfig346
-rw-r--r--arch/mips/ddb5xxx/Kconfig4
-rw-r--r--arch/mips/ddb5xxx/common/rtc_ds1386.c6
-rw-r--r--arch/mips/ddb5xxx/ddb5074/nile4_pic.c15
-rw-r--r--arch/mips/ddb5xxx/ddb5074/setup.c4
-rw-r--r--arch/mips/ddb5xxx/ddb5476/setup.c4
-rw-r--r--arch/mips/ddb5xxx/ddb5476/vrc5476_irq.c15
-rw-r--r--arch/mips/ddb5xxx/ddb5477/irq_5477.c15
-rw-r--r--arch/mips/ddb5xxx/ddb5477/setup.c6
-rw-r--r--arch/mips/dec/Makefile4
-rw-r--r--arch/mips/dec/ecc-berr.c48
-rw-r--r--arch/mips/dec/int-handler.S18
-rw-r--r--arch/mips/dec/kn01-berr.c201
-rw-r--r--arch/mips/dec/kn02-irq.c13
-rw-r--r--arch/mips/dec/kn02xa-berr.c139
-rw-r--r--arch/mips/dec/prom/identify.c28
-rw-r--r--arch/mips/dec/prom/init.c16
-rw-r--r--arch/mips/dec/prom/memory.c14
-rw-r--r--arch/mips/dec/reset.c2
-rw-r--r--arch/mips/dec/setup.c57
-rw-r--r--arch/mips/dec/time.c24
-rw-r--r--arch/mips/defconfig479
-rw-r--r--arch/mips/galileo-boards/ev96100/setup.c4
-rw-r--r--arch/mips/gt64120/ev64120/Kconfig3
-rw-r--r--arch/mips/gt64120/ev64120/setup.c4
-rw-r--r--arch/mips/gt64120/momenco_ocelot/setup.c4
-rw-r--r--arch/mips/ite-boards/Kconfig8
-rw-r--r--arch/mips/ite-boards/generic/irq.c30
-rw-r--r--arch/mips/ite-boards/generic/it8172_setup.c4
-rw-r--r--arch/mips/jazz/Kconfig33
-rw-r--r--arch/mips/jazz/irq.c15
-rw-r--r--arch/mips/jazz/setup.c4
-rw-r--r--arch/mips/jmr3927/common/rtc_ds1742.c6
-rw-r--r--arch/mips/jmr3927/rbhma3100/irq.c14
-rw-r--r--arch/mips/jmr3927/rbhma3100/setup.c38
-rw-r--r--arch/mips/kernel/Makefile14
-rw-r--r--arch/mips/kernel/asm-offsets.c25
-rw-r--r--arch/mips/kernel/binfmt_elfn32.c4
-rw-r--r--arch/mips/kernel/binfmt_elfo32.c35
-rw-r--r--arch/mips/kernel/branch.c29
-rw-r--r--arch/mips/kernel/cpu-probe.c256
-rw-r--r--arch/mips/kernel/dma-no-isa.c28
-rw-r--r--arch/mips/kernel/entry.S54
-rw-r--r--arch/mips/kernel/gdb-low.S5
-rw-r--r--arch/mips/kernel/gdb-stub.c23
-rw-r--r--arch/mips/kernel/genex.S44
-rw-r--r--arch/mips/kernel/genrtc.c64
-rw-r--r--arch/mips/kernel/head.S70
-rw-r--r--arch/mips/kernel/i8259.c21
-rw-r--r--arch/mips/kernel/ioctl32.c10
-rw-r--r--arch/mips/kernel/irixelf.c254
-rw-r--r--arch/mips/kernel/irixinv.c7
-rw-r--r--arch/mips/kernel/irixioctl.c63
-rw-r--r--arch/mips/kernel/irixsig.c405
-rw-r--r--arch/mips/kernel/irq-msc01.c38
-rw-r--r--arch/mips/kernel/irq-mv6434x.c15
-rw-r--r--arch/mips/kernel/irq-rm7000.c14
-rw-r--r--arch/mips/kernel/irq-rm9000.c28
-rw-r--r--arch/mips/kernel/irq_cpu.c91
-rw-r--r--arch/mips/kernel/linux32.c164
-rw-r--r--arch/mips/kernel/module-elf32.c250
-rw-r--r--arch/mips/kernel/module-elf64.c274
-rw-r--r--arch/mips/kernel/module.c336
-rw-r--r--arch/mips/kernel/proc.c135
-rw-r--r--arch/mips/kernel/process.c215
-rw-r--r--arch/mips/kernel/ptrace.c283
-rw-r--r--arch/mips/kernel/ptrace32.c150
-rw-r--r--arch/mips/kernel/r4k_fpu.S5
-rw-r--r--arch/mips/kernel/rtlx.c330
-rw-r--r--arch/mips/kernel/scall32-o32.S13
-rw-r--r--arch/mips/kernel/scall64-64.S4
-rw-r--r--arch/mips/kernel/scall64-n32.S32
-rw-r--r--arch/mips/kernel/scall64-o32.S14
-rw-r--r--arch/mips/kernel/semaphore.c12
-rw-r--r--arch/mips/kernel/setup.c46
-rw-r--r--arch/mips/kernel/signal-common.h90
-rw-r--r--arch/mips/kernel/signal.c146
-rw-r--r--arch/mips/kernel/signal32.c123
-rw-r--r--arch/mips/kernel/signal_n32.c37
-rw-r--r--arch/mips/kernel/smp.c55
-rw-r--r--arch/mips/kernel/smp_mt.c366
-rw-r--r--arch/mips/kernel/syscall.c34
-rw-r--r--arch/mips/kernel/sysirix.c539
-rw-r--r--arch/mips/kernel/time.c16
-rw-r--r--arch/mips/kernel/traps.c499
-rw-r--r--arch/mips/kernel/unaligned.c10
-rw-r--r--arch/mips/kernel/vmlinux.lds.S13
-rw-r--r--arch/mips/kernel/vpe.c1284
-rw-r--r--arch/mips/lasat/Kconfig15
-rw-r--r--arch/mips/lasat/ds1603.c9
-rw-r--r--arch/mips/lasat/interrupt.c15
-rw-r--r--arch/mips/lasat/setup.c6
-rw-r--r--arch/mips/lib-32/dump_tlb.c106
-rw-r--r--arch/mips/lib-32/r3k_dump_tlb.c10
-rw-r--r--arch/mips/lib-64/dump_tlb.c10
-rw-r--r--arch/mips/lib/Makefile4
-rw-r--r--arch/mips/lib/csum_partial_copy.c8
-rw-r--r--arch/mips/lib/memcpy.S15
-rw-r--r--arch/mips/lib/uncached.c76
-rw-r--r--arch/mips/math-emu/cp1emu.c229
-rw-r--r--arch/mips/math-emu/dp_sqrt.c2
-rw-r--r--arch/mips/math-emu/dsemul.c17
-rw-r--r--arch/mips/math-emu/dsemul.h10
-rw-r--r--arch/mips/math-emu/ieee754.c16
-rw-r--r--arch/mips/math-emu/ieee754.h180
-rw-r--r--arch/mips/math-emu/kernel_linkage.c6
-rw-r--r--arch/mips/mips-boards/atlas/atlas_int.c15
-rw-r--r--arch/mips/mips-boards/atlas/atlas_setup.c8
-rw-r--r--arch/mips/mips-boards/generic/init.c91
-rw-r--r--arch/mips/mips-boards/generic/memory.c29
-rw-r--r--arch/mips/mips-boards/generic/mipsIRQ.S110
-rw-r--r--arch/mips/mips-boards/generic/pci.c167
-rw-r--r--arch/mips/mips-boards/generic/time.c88
-rw-r--r--arch/mips/mips-boards/malta/malta_int.c153
-rw-r--r--arch/mips/mips-boards/malta/malta_setup.c8
-rw-r--r--arch/mips/mips-boards/sead/sead_int.c12
-rw-r--r--arch/mips/mips-boards/sead/sead_setup.c2
-rw-r--r--arch/mips/mips-boards/sim/Makefile20
-rw-r--r--arch/mips/mips-boards/sim/cmdline.c59
-rw-r--r--arch/mips/mips-boards/sim/sim_IRQ.c148
-rw-r--r--arch/mips/mips-boards/sim/sim_cmdline.c33
-rw-r--r--arch/mips/mips-boards/sim/sim_int.c41
-rw-r--r--arch/mips/mips-boards/sim/sim_irq.S99
-rw-r--r--arch/mips/mips-boards/sim/sim_mem.c129
-rw-r--r--arch/mips/mips-boards/sim/sim_printf.c74
-rw-r--r--arch/mips/mips-boards/sim/sim_setup.c101
-rw-r--r--arch/mips/mips-boards/sim/sim_smp.c151
-rw-r--r--arch/mips/mips-boards/sim/sim_time.c215
-rw-r--r--arch/mips/mm/Makefile2
-rw-r--r--arch/mips/mm/c-r3k.c6
-rw-r--r--arch/mips/mm/c-r4k.c145
-rw-r--r--arch/mips/mm/c-sb1.c10
-rw-r--r--arch/mips/mm/c-tx39.c16
-rw-r--r--arch/mips/mm/cache.c106
-rw-r--r--arch/mips/mm/cerr-sb1.c54
-rw-r--r--arch/mips/mm/cex-sb1.S5
-rw-r--r--arch/mips/mm/dma-coherent.c6
-rw-r--r--arch/mips/mm/dma-ip27.c4
-rw-r--r--arch/mips/mm/dma-ip32.c4
-rw-r--r--arch/mips/mm/dma-noncoherent.c50
-rw-r--r--arch/mips/mm/fault.c17
-rw-r--r--arch/mips/mm/highmem.c19
-rw-r--r--arch/mips/mm/init.c34
-rw-r--r--arch/mips/mm/ioremap.c32
-rw-r--r--arch/mips/mm/pg-r4k.c21
-rw-r--r--arch/mips/mm/pg-sb1.c65
-rw-r--r--arch/mips/mm/pgtable-32.c36
-rw-r--r--arch/mips/mm/sc-rm7k.c39
-rw-r--r--arch/mips/mm/tlb-andes.c4
-rw-r--r--arch/mips/mm/tlb-r4k.c70
-rw-r--r--arch/mips/mm/tlb-sb1.c376
-rw-r--r--arch/mips/mm/tlbex.c245
-rw-r--r--arch/mips/momentum/Kconfig6
-rw-r--r--arch/mips/momentum/jaguar_atx/prom.c3
-rw-r--r--arch/mips/momentum/jaguar_atx/setup.c12
-rw-r--r--arch/mips/momentum/ocelot_3/prom.c3
-rw-r--r--arch/mips/momentum/ocelot_3/setup.c12
-rw-r--r--arch/mips/momentum/ocelot_c/cpci-irq.c15
-rw-r--r--arch/mips/momentum/ocelot_c/setup.c10
-rw-r--r--arch/mips/momentum/ocelot_c/uart-irq.c15
-rw-r--r--arch/mips/momentum/ocelot_g/setup.c6
-rw-r--r--arch/mips/oprofile/Kconfig2
-rw-r--r--arch/mips/oprofile/common.c28
-rw-r--r--arch/mips/oprofile/op_impl.h5
-rw-r--r--arch/mips/oprofile/op_model_mipsxx.c215
-rw-r--r--arch/mips/oprofile/op_model_rm9000.c3
-rw-r--r--arch/mips/pci/Makefile3
-rw-r--r--arch/mips/pci/fixup-atlas.c41
-rw-r--r--arch/mips/pci/fixup-au1000.c78
-rw-r--r--arch/mips/pci/fixup-cobalt.c55
-rw-r--r--arch/mips/pci/fixup-pnx8550.c57
-rw-r--r--arch/mips/pci/fixup-tx4938.c92
-rw-r--r--arch/mips/pci/ops-au1000.c14
-rw-r--r--arch/mips/pci/ops-bonito64.c14
-rw-r--r--arch/mips/pci/ops-gt64111.c10
-rw-r--r--arch/mips/pci/ops-gt64120.c10
-rw-r--r--arch/mips/pci/ops-msc.c31
-rw-r--r--arch/mips/pci/ops-nile4.c2
-rw-r--r--arch/mips/pci/ops-pnx8550.c284
-rw-r--r--arch/mips/pci/ops-tx4938.c198
-rw-r--r--arch/mips/pci/pci-bcm1480.c265
-rw-r--r--arch/mips/pci/pci-bcm1480ht.c224
-rw-r--r--arch/mips/pci/pci-ip27.c7
-rw-r--r--arch/mips/pci/pci-ip32.c4
-rw-r--r--arch/mips/pci/pci-lasat.c56
-rw-r--r--arch/mips/pci/pci.c19
-rw-r--r--arch/mips/philips/pnx8550/common/Kconfig1
-rw-r--r--arch/mips/philips/pnx8550/common/Makefile27
-rw-r--r--arch/mips/philips/pnx8550/common/gdb_hook.c109
-rw-r--r--arch/mips/philips/pnx8550/common/int.c293
-rw-r--r--arch/mips/philips/pnx8550/common/mipsIRQ.S76
-rw-r--r--arch/mips/philips/pnx8550/common/pci.c133
-rw-r--r--arch/mips/philips/pnx8550/common/platform.c135
-rw-r--r--arch/mips/philips/pnx8550/common/proc.c113
-rw-r--r--arch/mips/philips/pnx8550/common/prom.c138
-rw-r--r--arch/mips/philips/pnx8550/common/reset.c49
-rw-r--r--arch/mips/philips/pnx8550/common/setup.c149
-rw-r--r--arch/mips/philips/pnx8550/common/time.c105
-rw-r--r--arch/mips/philips/pnx8550/jbs/Makefile4
-rw-r--r--arch/mips/philips/pnx8550/jbs/board_setup.c65
-rw-r--r--arch/mips/philips/pnx8550/jbs/init.c57
-rw-r--r--arch/mips/philips/pnx8550/jbs/irqmap.c36
-rw-r--r--arch/mips/pmc-sierra/Kconfig3
-rw-r--r--arch/mips/pmc-sierra/yosemite/atmel_read_eeprom.h1
-rw-r--r--arch/mips/pmc-sierra/yosemite/ht-irq.c1
-rw-r--r--arch/mips/pmc-sierra/yosemite/ht.c1
-rw-r--r--arch/mips/pmc-sierra/yosemite/prom.c3
-rw-r--r--arch/mips/pmc-sierra/yosemite/setup.c12
-rw-r--r--arch/mips/pmc-sierra/yosemite/smp.c2
-rw-r--r--arch/mips/qemu/q-setup.c5
-rw-r--r--arch/mips/sgi-ip22/ip22-eisa.c148
-rw-r--r--arch/mips/sgi-ip22/ip22-setup.c6
-rw-r--r--arch/mips/sgi-ip22/ip22-time.c6
-rw-r--r--arch/mips/sgi-ip27/Kconfig54
-rw-r--r--arch/mips/sgi-ip27/ip27-berr.c1
-rw-r--r--arch/mips/sgi-ip27/ip27-console.c4
-rw-r--r--arch/mips/sgi-ip27/ip27-init.c50
-rw-r--r--arch/mips/sgi-ip27/ip27-irq.c66
-rw-r--r--arch/mips/sgi-ip27/ip27-smp.c25
-rw-r--r--arch/mips/sgi-ip32/ip32-irq.c75
-rw-r--r--arch/mips/sgi-ip32/ip32-memory.c4
-rw-r--r--arch/mips/sgi-ip32/ip32-setup.c6
-rw-r--r--arch/mips/sibyte/Kconfig161
-rw-r--r--arch/mips/sibyte/bcm1480/Makefile5
-rw-r--r--arch/mips/sibyte/bcm1480/irq.c476
-rw-r--r--arch/mips/sibyte/bcm1480/irq_handler.S165
-rw-r--r--arch/mips/sibyte/bcm1480/setup.c136
-rw-r--r--arch/mips/sibyte/bcm1480/smp.c110
-rw-r--r--arch/mips/sibyte/bcm1480/time.c138
-rw-r--r--arch/mips/sibyte/cfe/smp.c14
-rw-r--r--arch/mips/sibyte/sb1250/bcm1250_tbprof.c154
-rw-r--r--arch/mips/sibyte/sb1250/bus_watcher.c2
-rw-r--r--arch/mips/sibyte/sb1250/irq.c121
-rw-r--r--arch/mips/sibyte/sb1250/setup.c4
-rw-r--r--arch/mips/sibyte/sb1250/smp.c18
-rw-r--r--arch/mips/sibyte/sb1250/time.c44
-rw-r--r--arch/mips/sibyte/swarm/rtc_m41t81.c54
-rw-r--r--arch/mips/sibyte/swarm/rtc_xicor1241.c48
-rw-r--r--arch/mips/sibyte/swarm/setup.c41
-rw-r--r--arch/mips/sibyte/swarm/time.c44
-rw-r--r--arch/mips/sni/irq.c15
-rw-r--r--arch/mips/sni/setup.c6
-rw-r--r--arch/mips/tx4927/Kconfig3
-rw-r--r--arch/mips/tx4927/common/tx4927_setup.c6
-rw-r--r--arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c23
-rw-r--r--arch/mips/tx4938/Kconfig24
-rw-r--r--arch/mips/tx4938/common/Makefile11
-rw-r--r--arch/mips/tx4938/common/dbgio.c50
-rw-r--r--arch/mips/tx4938/common/irq.c424
-rw-r--r--arch/mips/tx4938/common/irq_handler.S84
-rw-r--r--arch/mips/tx4938/common/prom.c129
-rw-r--r--arch/mips/tx4938/common/rtc_rx5c348.c202
-rw-r--r--arch/mips/tx4938/common/setup.c91
-rw-r--r--arch/mips/tx4938/toshiba_rbtx4938/Makefile9
-rw-r--r--arch/mips/tx4938/toshiba_rbtx4938/irq.c243
-rw-r--r--arch/mips/tx4938/toshiba_rbtx4938/prom.c78
-rw-r--r--arch/mips/tx4938/toshiba_rbtx4938/setup.c1035
-rw-r--r--arch/mips/tx4938/toshiba_rbtx4938/spi_eeprom.c219
-rw-r--r--arch/mips/tx4938/toshiba_rbtx4938/spi_txx9.c159
-rw-r--r--arch/mips/vr41xx/Kconfig88
-rw-r--r--arch/mips/vr41xx/common/cmu.c2
-rw-r--r--arch/mips/vr41xx/common/init.c14
-rw-r--r--arch/mips/vr41xx/common/vrc4173.c4
-rw-r--r--arch/mips/vr41xx/nec-cmbvr4133/setup.c5
-rw-r--r--arch/parisc/Kconfig5
-rw-r--r--arch/parisc/Makefile13
-rw-r--r--arch/parisc/configs/712_defconfig456
-rw-r--r--arch/parisc/configs/a500_defconfig551
-rw-r--r--arch/parisc/configs/b180_defconfig309
-rw-r--r--arch/parisc/configs/c3000_defconfig676
-rw-r--r--arch/parisc/defconfig618
-rw-r--r--arch/parisc/kernel/asm-offsets.c1
-rw-r--r--arch/parisc/kernel/cache.c34
-rw-r--r--arch/parisc/kernel/drivers.c273
-rw-r--r--arch/parisc/kernel/entry.S188
-rw-r--r--arch/parisc/kernel/firmware.c16
-rw-r--r--arch/parisc/kernel/head.S73
-rw-r--r--arch/parisc/kernel/ioctl32.c37
-rw-r--r--arch/parisc/kernel/pacache.S186
-rw-r--r--arch/parisc/kernel/pci-dma.c56
-rw-r--r--arch/parisc/kernel/pci.c3
-rw-r--r--arch/parisc/kernel/pdc_cons.c46
-rw-r--r--arch/parisc/kernel/perf.c12
-rw-r--r--arch/parisc/kernel/process.c38
-rw-r--r--arch/parisc/kernel/processor.c8
-rw-r--r--arch/parisc/kernel/ptrace.c50
-rw-r--r--arch/parisc/kernel/real2.S36
-rw-r--r--arch/parisc/kernel/signal.c22
-rw-r--r--arch/parisc/kernel/smp.c3
-rw-r--r--arch/parisc/kernel/syscall.S37
-rw-r--r--arch/parisc/kernel/syscall_table.S10
-rw-r--r--arch/parisc/kernel/time.c30
-rw-r--r--arch/parisc/kernel/traps.c37
-rw-r--r--arch/parisc/kernel/unaligned.c16
-rw-r--r--arch/parisc/lib/fixup.S4
-rw-r--r--arch/parisc/lib/memcpy.c2
-rw-r--r--arch/parisc/mm/init.c3
-rw-r--r--arch/parisc/mm/ioremap.c6
-rw-r--r--arch/powerpc/Kconfig957
-rw-r--r--arch/powerpc/Kconfig.debug118
-rw-r--r--arch/powerpc/Makefile219
-rw-r--r--arch/powerpc/configs/cell_defconfig1024
-rw-r--r--arch/powerpc/configs/g5_defconfig1543
-rw-r--r--arch/powerpc/configs/iseries_defconfig998
-rw-r--r--arch/powerpc/configs/maple_defconfig1062
-rw-r--r--arch/powerpc/configs/pseries_defconfig1371
-rw-r--r--arch/powerpc/kernel/Makefile68
-rw-r--r--arch/powerpc/kernel/asm-offsets.c275
-rw-r--r--arch/powerpc/kernel/binfmt_elf32.c (renamed from arch/ppc64/kernel/binfmt_elf32.c)3
-rw-r--r--arch/powerpc/kernel/btext.c853
-rw-r--r--arch/powerpc/kernel/cpu_setup_power4.S (renamed from arch/ppc64/kernel/cpu_setup_power4.S)8
-rw-r--r--arch/powerpc/kernel/cputable.c (renamed from arch/ppc/kernel/cputable.c)806
-rw-r--r--arch/powerpc/kernel/entry_32.S1000
-rw-r--r--arch/powerpc/kernel/entry_64.S (renamed from arch/ppc64/kernel/entry.S)49
-rw-r--r--arch/powerpc/kernel/firmware.c (renamed from arch/ppc64/kernel/firmware.c)2
-rw-r--r--arch/powerpc/kernel/fpu.S (renamed from arch/ppc/kernel/fpu.S)105
-rw-r--r--arch/powerpc/kernel/head_32.S1381
-rw-r--r--arch/powerpc/kernel/head_44x.S782
-rw-r--r--arch/powerpc/kernel/head_4xx.S1022
-rw-r--r--arch/powerpc/kernel/head_64.S2010
-rw-r--r--arch/powerpc/kernel/head_8xx.S860
-rw-r--r--arch/powerpc/kernel/head_fsl_booke.S1063
-rw-r--r--arch/powerpc/kernel/idle_6xx.S233
-rw-r--r--arch/powerpc/kernel/idle_power4.S (renamed from arch/ppc64/kernel/idle_power4.S)9
-rw-r--r--arch/powerpc/kernel/init_task.c (renamed from arch/ppc64/kernel/init_task.c)0
-rw-r--r--arch/powerpc/kernel/ioctl32.c (renamed from arch/ppc64/kernel/ioctl32.c)8
-rw-r--r--arch/powerpc/kernel/irq.c (renamed from arch/ppc64/kernel/irq.c)267
-rw-r--r--arch/powerpc/kernel/lparcfg.c (renamed from arch/ppc64/kernel/lparcfg.c)21
-rw-r--r--arch/powerpc/kernel/lparmap.c (renamed from arch/ppc64/kernel/lparmap.c)4
-rw-r--r--arch/powerpc/kernel/misc_32.S1016
-rw-r--r--arch/powerpc/kernel/misc_64.S950
-rw-r--r--arch/powerpc/kernel/of_device.c (renamed from arch/ppc64/kernel/of_device.c)6
-rw-r--r--arch/powerpc/kernel/paca.c (renamed from arch/ppc64/kernel/pacaData.c)11
-rw-r--r--arch/powerpc/kernel/pmc.c (renamed from arch/ppc64/kernel/pmc.c)30
-rw-r--r--arch/powerpc/kernel/ppc32.h (renamed from include/asm-ppc64/ppc32.h)30
-rw-r--r--arch/powerpc/kernel/ppc_ksyms.c261
-rw-r--r--arch/powerpc/kernel/proc_ppc64.c (renamed from arch/ppc64/kernel/proc_ppc64.c)12
-rw-r--r--arch/powerpc/kernel/process.c (renamed from arch/ppc64/kernel/process.c)500
-rw-r--r--arch/powerpc/kernel/prom.c2168
-rw-r--r--arch/powerpc/kernel/prom_init.c2195
-rw-r--r--arch/powerpc/kernel/ptrace.c (renamed from arch/ppc/kernel/ptrace.c)213
-rw-r--r--arch/powerpc/kernel/ptrace32.c (renamed from arch/ppc64/kernel/ptrace32.c)9
-rw-r--r--arch/powerpc/kernel/rtas-proc.c (renamed from arch/ppc64/kernel/rtas-proc.c)3
-rw-r--r--arch/powerpc/kernel/rtas.c (renamed from arch/ppc64/kernel/rtas.c)273
-rw-r--r--arch/powerpc/kernel/rtas_flash.c (renamed from arch/ppc64/kernel/rtas_flash.c)113
-rw-r--r--arch/powerpc/kernel/rtas_pci.c (renamed from arch/ppc64/kernel/rtas_pci.c)62
-rw-r--r--arch/powerpc/kernel/semaphore.c135
-rw-r--r--arch/powerpc/kernel/setup-common.c592
-rw-r--r--arch/powerpc/kernel/setup.h6
-rw-r--r--arch/powerpc/kernel/setup_32.c369
-rw-r--r--arch/powerpc/kernel/setup_64.c (renamed from arch/ppc64/kernel/setup.c)678
-rw-r--r--arch/powerpc/kernel/signal_32.c (renamed from arch/ppc64/kernel/signal32.c)995
-rw-r--r--arch/powerpc/kernel/signal_64.c (renamed from arch/ppc64/kernel/signal.c)3
-rw-r--r--arch/powerpc/kernel/smp-tbsync.c (renamed from arch/ppc64/kernel/smp-tbsync.c)112
-rw-r--r--arch/powerpc/kernel/smp.c (renamed from arch/ppc64/kernel/smp.c)108
-rw-r--r--arch/powerpc/kernel/sys_ppc32.c (renamed from arch/ppc64/kernel/sys_ppc32.c)321
-rw-r--r--arch/powerpc/kernel/syscalls.c (renamed from arch/ppc64/kernel/syscalls.c)187
-rw-r--r--arch/powerpc/kernel/sysfs.c (renamed from arch/ppc64/kernel/sysfs.c)3
-rw-r--r--arch/powerpc/kernel/systbl.S321
-rw-r--r--arch/powerpc/kernel/time.c (renamed from arch/ppc64/kernel/time.c)597
-rw-r--r--arch/powerpc/kernel/traps.c1086
-rw-r--r--arch/powerpc/kernel/vecemu.c (renamed from arch/ppc/kernel/vecemu.c)0
-rw-r--r--arch/powerpc/kernel/vector.S (renamed from arch/ppc64/kernel/vector.S)71
-rw-r--r--arch/powerpc/kernel/vio.c (renamed from arch/ppc64/kernel/vio.c)41
-rw-r--r--arch/powerpc/kernel/vmlinux.lds.S258
-rw-r--r--arch/powerpc/lib/Makefile20
-rw-r--r--arch/powerpc/lib/bitops.c (renamed from arch/ppc64/kernel/bitops.c)97
-rw-r--r--arch/powerpc/lib/checksum_32.S225
-rw-r--r--arch/powerpc/lib/checksum_64.S (renamed from arch/ppc64/lib/checksum.S)0
-rw-r--r--arch/powerpc/lib/copy_32.S543
-rw-r--r--arch/powerpc/lib/copypage_64.S (renamed from arch/ppc64/lib/copypage.S)2
-rw-r--r--arch/powerpc/lib/copyuser_64.S (renamed from arch/ppc64/lib/copyuser.S)4
-rw-r--r--arch/powerpc/lib/div64.S59
-rw-r--r--arch/powerpc/lib/e2a.c (renamed from arch/ppc64/lib/e2a.c)0
-rw-r--r--arch/powerpc/lib/locks.c (renamed from arch/ppc64/lib/locks.c)6
-rw-r--r--arch/powerpc/lib/mem_64.S119
-rw-r--r--arch/powerpc/lib/memcpy_64.S (renamed from arch/ppc64/lib/memcpy.S)0
-rw-r--r--arch/powerpc/lib/rheap.c693
-rw-r--r--arch/powerpc/lib/sstep.c (renamed from arch/ppc64/lib/sstep.c)17
-rw-r--r--arch/powerpc/lib/strcase.c (renamed from arch/ppc64/lib/strcase.c)8
-rw-r--r--arch/powerpc/lib/string.S (renamed from arch/ppc64/lib/string.S)147
-rw-r--r--arch/powerpc/lib/usercopy_64.c (renamed from arch/ppc64/lib/usercopy.c)0
-rw-r--r--arch/powerpc/mm/44x_mmu.c120
-rw-r--r--arch/powerpc/mm/4xx_mmu.c141
-rw-r--r--arch/powerpc/mm/Makefile21
-rw-r--r--arch/powerpc/mm/fault.c (renamed from arch/ppc64/mm/fault.c)121
-rw-r--r--arch/powerpc/mm/fsl_booke_mmu.c237
-rw-r--r--arch/powerpc/mm/hash_low_32.S618
-rw-r--r--arch/powerpc/mm/hash_low_64.S847
-rw-r--r--arch/powerpc/mm/hash_native_64.c (renamed from arch/ppc64/mm/hash_native.c)386
-rw-r--r--arch/powerpc/mm/hash_utils_64.c775
-rw-r--r--arch/powerpc/mm/hugetlbpage.c (renamed from arch/ppc64/mm/hugetlbpage.c)140
-rw-r--r--arch/powerpc/mm/imalloc.c (renamed from arch/ppc64/mm/imalloc.c)5
-rw-r--r--arch/powerpc/mm/init_32.c251
-rw-r--r--arch/powerpc/mm/init_64.c234
-rw-r--r--arch/powerpc/mm/lmb.c (renamed from arch/ppc64/kernel/lmb.c)105
-rw-r--r--arch/powerpc/mm/mem.c554
-rw-r--r--arch/powerpc/mm/mmap.c (renamed from arch/ppc64/mm/mmap.c)0
-rw-r--r--arch/powerpc/mm/mmu_context_32.c86
-rw-r--r--arch/powerpc/mm/mmu_context_64.c63
-rw-r--r--arch/powerpc/mm/mmu_decl.h87
-rw-r--r--arch/powerpc/mm/numa.c (renamed from arch/ppc64/mm/numa.c)3
-rw-r--r--arch/powerpc/mm/pgtable_32.c467
-rw-r--r--arch/powerpc/mm/pgtable_64.c335
-rw-r--r--arch/powerpc/mm/ppc_mmu_32.c300
-rw-r--r--arch/powerpc/mm/slb.c (renamed from arch/ppc64/mm/slb.c)102
-rw-r--r--arch/powerpc/mm/slb_low.S240
-rw-r--r--arch/powerpc/mm/stab.c (renamed from arch/ppc64/mm/stab.c)47
-rw-r--r--arch/powerpc/mm/tlb_32.c183
-rw-r--r--arch/powerpc/mm/tlb_64.c (renamed from arch/ppc64/mm/tlb.c)51
-rw-r--r--arch/powerpc/oprofile/Kconfig (renamed from arch/ppc/oprofile/Kconfig)6
-rw-r--r--arch/powerpc/oprofile/Makefile (renamed from arch/ppc/oprofile/Makefile)7
-rw-r--r--arch/powerpc/oprofile/common.c (renamed from arch/ppc64/oprofile/common.c)84
-rw-r--r--arch/powerpc/oprofile/op_model_fsl_booke.c (renamed from arch/ppc/oprofile/op_model_fsl_booke.c)7
-rw-r--r--arch/powerpc/oprofile/op_model_power4.c (renamed from arch/ppc64/oprofile/op_model_power4.c)29
-rw-r--r--arch/powerpc/oprofile/op_model_rs64.c (renamed from arch/ppc64/oprofile/op_model_rs64.c)2
-rw-r--r--arch/powerpc/platforms/4xx/Kconfig280
-rw-r--r--arch/powerpc/platforms/4xx/Makefile1
-rw-r--r--arch/powerpc/platforms/85xx/Kconfig86
-rw-r--r--arch/powerpc/platforms/85xx/Makefile1
-rw-r--r--arch/powerpc/platforms/8xx/Kconfig352
-rw-r--r--arch/powerpc/platforms/Makefile14
-rw-r--r--arch/powerpc/platforms/apus/Kconfig130
-rw-r--r--arch/powerpc/platforms/cell/Makefile2
-rw-r--r--arch/powerpc/platforms/cell/interrupt.c (renamed from arch/ppc64/kernel/bpa_iic.c)8
-rw-r--r--arch/powerpc/platforms/cell/interrupt.h (renamed from arch/ppc64/kernel/bpa_iic.h)8
-rw-r--r--arch/powerpc/platforms/cell/iommu.c (renamed from arch/ppc64/kernel/bpa_iommu.c)46
-rw-r--r--arch/powerpc/platforms/cell/iommu.h (renamed from arch/ppc64/kernel/bpa_iommu.h)10
-rw-r--r--arch/powerpc/platforms/cell/setup.c (renamed from arch/ppc64/kernel/bpa_setup.c)49
-rw-r--r--arch/powerpc/platforms/cell/smp.c230
-rw-r--r--arch/powerpc/platforms/cell/spider-pic.c (renamed from arch/ppc64/kernel/spider-pic.c)2
-rw-r--r--arch/powerpc/platforms/chrp/Makefile4
-rw-r--r--arch/powerpc/platforms/chrp/chrp.h12
-rw-r--r--arch/powerpc/platforms/chrp/nvram.c89
-rw-r--r--arch/powerpc/platforms/chrp/pci.c310
-rw-r--r--arch/powerpc/platforms/chrp/pegasos_eth.c214
-rw-r--r--arch/powerpc/platforms/chrp/setup.c524
-rw-r--r--arch/powerpc/platforms/chrp/smp.c85
-rw-r--r--arch/powerpc/platforms/chrp/time.c188
-rw-r--r--arch/powerpc/platforms/embedded6xx/Kconfig318
-rw-r--r--arch/powerpc/platforms/iseries/Kconfig31
-rw-r--r--arch/powerpc/platforms/iseries/Makefile9
-rw-r--r--arch/powerpc/platforms/iseries/call_hpt.h (renamed from include/asm-ppc64/iSeries/HvCallHpt.h)11
-rw-r--r--arch/powerpc/platforms/iseries/call_pci.h (renamed from include/asm-ppc64/iSeries/HvCallPci.h)253
-rw-r--r--arch/powerpc/platforms/iseries/call_sm.h (renamed from include/asm-ppc64/iSeries/HvCallSm.h)11
-rw-r--r--arch/powerpc/platforms/iseries/htab.c (renamed from arch/ppc64/kernel/iSeries_htab.c)74
-rw-r--r--arch/powerpc/platforms/iseries/hvcall.S (renamed from arch/ppc64/kernel/hvCall.S)22
-rw-r--r--arch/powerpc/platforms/iseries/hvlog.c (renamed from arch/ppc64/kernel/HvCall.c)11
-rw-r--r--arch/powerpc/platforms/iseries/hvlpconfig.c (renamed from arch/ppc64/kernel/HvLpConfig.c)3
-rw-r--r--arch/powerpc/platforms/iseries/iommu.c (renamed from arch/ppc64/kernel/iSeries_iommu.c)92
-rw-r--r--arch/powerpc/platforms/iseries/ipl_parms.h (renamed from include/asm-ppc64/iSeries/ItIplParmsReal.h)7
-rw-r--r--arch/powerpc/platforms/iseries/irq.c (renamed from arch/ppc64/kernel/iSeries_irq.c)52
-rw-r--r--arch/powerpc/platforms/iseries/irq.h (renamed from include/asm-ppc64/iSeries/iSeries_irq.h)6
-rw-r--r--arch/powerpc/platforms/iseries/ksyms.c27
-rw-r--r--arch/powerpc/platforms/iseries/lpardata.c (renamed from arch/ppc64/kernel/LparData.c)40
-rw-r--r--arch/powerpc/platforms/iseries/lpevents.c (renamed from arch/ppc64/kernel/ItLpQueue.c)83
-rw-r--r--arch/powerpc/platforms/iseries/main_store.h (renamed from include/asm-ppc64/iSeries/IoHriMainStore.h)7
-rw-r--r--arch/powerpc/platforms/iseries/mf.c (renamed from arch/ppc64/kernel/mf.c)106
-rw-r--r--arch/powerpc/platforms/iseries/misc.S56
-rw-r--r--arch/powerpc/platforms/iseries/naca.h (renamed from include/asm-ppc64/naca.h)8
-rw-r--r--arch/powerpc/platforms/iseries/pci.c (renamed from arch/ppc64/kernel/iSeries_pci.c)206
-rw-r--r--arch/powerpc/platforms/iseries/pci.h (renamed from include/asm-ppc64/iSeries/iSeries_pci.h)49
-rw-r--r--arch/powerpc/platforms/iseries/proc.c (renamed from arch/ppc64/kernel/iSeries_proc.c)19
-rw-r--r--arch/powerpc/platforms/iseries/processor_vpd.h (renamed from include/asm-ppc64/iSeries/IoHriProcessorVpd.h)7
-rw-r--r--arch/powerpc/platforms/iseries/release_data.h (renamed from include/asm-ppc64/iSeries/HvReleaseData.h)9
-rw-r--r--arch/powerpc/platforms/iseries/setup.c (renamed from arch/ppc64/kernel/iSeries_setup.c)599
-rw-r--r--arch/powerpc/platforms/iseries/setup.h (renamed from arch/ppc64/kernel/iSeries_setup.h)4
-rw-r--r--arch/powerpc/platforms/iseries/smp.c (renamed from arch/ppc64/kernel/iSeries_smp.c)49
-rw-r--r--arch/powerpc/platforms/iseries/spcomm_area.h (renamed from include/asm-ppc64/iSeries/ItSpCommArea.h)7
-rw-r--r--arch/powerpc/platforms/iseries/vio.c (renamed from arch/ppc64/kernel/iSeries_vio.c)48
-rw-r--r--arch/powerpc/platforms/iseries/viopath.c (renamed from arch/ppc64/kernel/viopath.c)31
-rw-r--r--arch/powerpc/platforms/iseries/vpd_areas.h (renamed from include/asm-ppc64/iSeries/ItVpdAreas.h)7
-rw-r--r--arch/powerpc/platforms/iseries/vpdinfo.c (renamed from arch/ppc64/kernel/iSeries_VpdInfo.c)21
-rw-r--r--arch/powerpc/platforms/maple/Makefile1
-rw-r--r--arch/powerpc/platforms/maple/maple.h12
-rw-r--r--arch/powerpc/platforms/maple/pci.c (renamed from arch/ppc64/kernel/maple_pci.c)10
-rw-r--r--arch/powerpc/platforms/maple/setup.c (renamed from arch/ppc64/kernel/maple_setup.c)13
-rw-r--r--arch/powerpc/platforms/maple/time.c (renamed from arch/ppc64/kernel/maple_time.c)9
-rw-r--r--arch/powerpc/platforms/powermac/Makefile9
-rw-r--r--arch/powerpc/platforms/powermac/backlight.c202
-rw-r--r--arch/powerpc/platforms/powermac/cache.S359
-rw-r--r--arch/powerpc/platforms/powermac/cpufreq_32.c727
-rw-r--r--arch/powerpc/platforms/powermac/cpufreq_64.c323
-rw-r--r--arch/powerpc/platforms/powermac/feature.c3063
-rw-r--r--arch/powerpc/platforms/powermac/low_i2c.c (renamed from arch/ppc64/kernel/pmac_low_i2c.c)0
-rw-r--r--arch/powerpc/platforms/powermac/nvram.c (renamed from arch/ppc64/kernel/pmac_nvram.c)282
-rw-r--r--arch/powerpc/platforms/powermac/pci.c1167
-rw-r--r--arch/powerpc/platforms/powermac/pic.c681
-rw-r--r--arch/powerpc/platforms/powermac/pic.h11
-rw-r--r--arch/powerpc/platforms/powermac/pmac.h51
-rw-r--r--arch/powerpc/platforms/powermac/setup.c782
-rw-r--r--arch/powerpc/platforms/powermac/sleep.S396
-rw-r--r--arch/powerpc/platforms/powermac/smp.c876
-rw-r--r--arch/powerpc/platforms/powermac/time.c360
-rw-r--r--arch/powerpc/platforms/prep/Kconfig22
-rw-r--r--arch/powerpc/platforms/pseries/Kconfig33
-rw-r--r--arch/powerpc/platforms/pseries/Makefile7
-rw-r--r--arch/powerpc/platforms/pseries/eeh.c (renamed from arch/ppc64/kernel/eeh.c)659
-rw-r--r--arch/powerpc/platforms/pseries/eeh_event.c155
-rw-r--r--arch/powerpc/platforms/pseries/hvCall.S (renamed from arch/ppc64/kernel/pSeries_hvCall.S)0
-rw-r--r--arch/powerpc/platforms/pseries/iommu.c (renamed from arch/ppc64/kernel/pSeries_iommu.c)38
-rw-r--r--arch/powerpc/platforms/pseries/lpar.c (renamed from arch/ppc64/kernel/pSeries_lpar.c)134
-rw-r--r--arch/powerpc/platforms/pseries/nvram.c (renamed from arch/ppc64/kernel/pSeries_nvram.c)0
-rw-r--r--arch/powerpc/platforms/pseries/pci.c (renamed from arch/ppc64/kernel/pSeries_pci.c)6
-rw-r--r--arch/powerpc/platforms/pseries/plpar_wrappers.h110
-rw-r--r--arch/powerpc/platforms/pseries/ras.c (renamed from arch/ppc64/kernel/ras.c)13
-rw-r--r--arch/powerpc/platforms/pseries/reconfig.c (renamed from arch/ppc64/kernel/pSeries_reconfig.c)8
-rw-r--r--arch/powerpc/platforms/pseries/rtasd.c (renamed from arch/ppc64/kernel/rtasd.c)8
-rw-r--r--arch/powerpc/platforms/pseries/scanlog.c (renamed from arch/ppc64/kernel/scanlog.c)3
-rw-r--r--arch/powerpc/platforms/pseries/setup.c (renamed from arch/ppc64/kernel/pSeries_setup.c)92
-rw-r--r--arch/powerpc/platforms/pseries/smp.c (renamed from arch/ppc64/kernel/pSeries_smp.c)58
-rw-r--r--arch/powerpc/platforms/pseries/vio.c (renamed from arch/ppc64/kernel/pSeries_vio.c)1
-rw-r--r--arch/powerpc/platforms/pseries/xics.c (renamed from arch/ppc64/kernel/xics.c)37
-rw-r--r--arch/powerpc/platforms/pseries/xics.h (renamed from include/asm-ppc64/xics.h)10
-rw-r--r--arch/powerpc/sysdev/Makefile8
-rw-r--r--arch/powerpc/sysdev/dart.h59
-rw-r--r--arch/powerpc/sysdev/dcr.S (renamed from arch/ppc/syslib/dcr.S)0
-rw-r--r--arch/powerpc/sysdev/grackle.c64
-rw-r--r--arch/powerpc/sysdev/i8259.c (renamed from arch/ppc/syslib/i8259.c)66
-rw-r--r--arch/powerpc/sysdev/indirect_pci.c (renamed from arch/ppc/syslib/indirect_pci.c)0
-rw-r--r--arch/powerpc/sysdev/mmio_nvram.c (renamed from arch/ppc64/kernel/bpa_nvram.c)60
-rw-r--r--arch/powerpc/sysdev/mpic.c (renamed from arch/ppc64/kernel/mpic.c)53
-rw-r--r--arch/powerpc/sysdev/u3_iommu.c (renamed from arch/ppc64/kernel/u3_iommu.c)54
-rw-r--r--arch/powerpc/xmon/Makefile11
-rw-r--r--arch/powerpc/xmon/ansidecl.h (renamed from arch/ppc64/xmon/ansidecl.h)0
-rw-r--r--arch/powerpc/xmon/nonstdio.c134
-rw-r--r--arch/powerpc/xmon/nonstdio.h14
-rw-r--r--arch/powerpc/xmon/ppc-dis.c (renamed from arch/ppc64/xmon/ppc-dis.c)0
-rw-r--r--arch/powerpc/xmon/ppc-opc.c (renamed from arch/ppc64/xmon/ppc-opc.c)0
-rw-r--r--arch/powerpc/xmon/ppc.h (renamed from arch/ppc64/xmon/ppc.h)0
-rw-r--r--arch/powerpc/xmon/setjmp.S135
-rw-r--r--arch/powerpc/xmon/start_32.c441
-rw-r--r--arch/powerpc/xmon/start_64.c34
-rw-r--r--arch/powerpc/xmon/start_8xx.c44
-rw-r--r--arch/powerpc/xmon/xmon.c (renamed from arch/ppc64/xmon/xmon.c)443
-rw-r--r--arch/ppc/4xx_io/serial_sicc.c17
-rw-r--r--arch/ppc/8260_io/fcc_enet.c3
-rw-r--r--arch/ppc/8xx_io/commproc.c25
-rw-r--r--arch/ppc/8xx_io/cs4218.h2
-rw-r--r--arch/ppc/8xx_io/cs4218_tdm.c7
-rw-r--r--arch/ppc/Kconfig58
-rw-r--r--arch/ppc/Makefile15
-rw-r--r--arch/ppc/boot/include/of1275.h3
-rw-r--r--arch/ppc/boot/of1275/Makefile2
-rw-r--r--arch/ppc/boot/of1275/call_prom.c74
-rw-r--r--arch/ppc/boot/of1275/claim.c96
-rw-r--r--arch/ppc/boot/of1275/finddevice.c19
-rw-r--r--arch/ppc/boot/openfirmware/Makefile3
-rw-r--r--arch/ppc/boot/openfirmware/chrpmain.c2
-rw-r--r--arch/ppc/boot/openfirmware/coffmain.c2
-rw-r--r--arch/ppc/boot/simple/Makefile27
-rw-r--r--arch/ppc/boot/simple/misc.c16
-rw-r--r--arch/ppc/boot/simple/openbios.c106
-rw-r--r--arch/ppc/configs/ev64360_defconfig73
-rw-r--r--arch/ppc/configs/mpc834x_sys_defconfig431
-rw-r--r--arch/ppc/configs/stx_gp3_defconfig86
-rw-r--r--arch/ppc/kernel/Makefile28
-rw-r--r--arch/ppc/kernel/align.c4
-rw-r--r--arch/ppc/kernel/asm-offsets.c3
-rw-r--r--arch/ppc/kernel/bitops.c126
-rw-r--r--arch/ppc/kernel/cpu_setup_6xx.S6
-rw-r--r--arch/ppc/kernel/cpu_setup_power4.S6
-rw-r--r--arch/ppc/kernel/dma-mapping.c10
-rw-r--r--arch/ppc/kernel/entry.S12
-rw-r--r--arch/ppc/kernel/head.S100
-rw-r--r--arch/ppc/kernel/head_44x.S36
-rw-r--r--arch/ppc/kernel/head_4xx.S68
-rw-r--r--arch/ppc/kernel/head_8xx.S42
-rw-r--r--arch/ppc/kernel/head_booke.h6
-rw-r--r--arch/ppc/kernel/head_fsl_booke.S47
-rw-r--r--arch/ppc/kernel/idle.c28
-rw-r--r--arch/ppc/kernel/irq.c164
-rw-r--r--arch/ppc/kernel/l2cr.S2
-rw-r--r--arch/ppc/kernel/machine_kexec.c2
-rw-r--r--arch/ppc/kernel/misc.S384
-rw-r--r--arch/ppc/kernel/pci.c47
-rw-r--r--arch/ppc/kernel/perfmon.c96
-rw-r--r--arch/ppc/kernel/perfmon_fsl_booke.c2
-rw-r--r--arch/ppc/kernel/ppc_ksyms.c46
-rw-r--r--arch/ppc/kernel/process.c142
-rw-r--r--arch/ppc/kernel/rio.c52
-rw-r--r--arch/ppc/kernel/setup.c40
-rw-r--r--arch/ppc/kernel/signal.c771
-rw-r--r--arch/ppc/kernel/smp.c23
-rw-r--r--arch/ppc/kernel/syscalls.c268
-rw-r--r--arch/ppc/kernel/time.c14
-rw-r--r--arch/ppc/kernel/traps.c62
-rw-r--r--arch/ppc/kernel/vector.S217
-rw-r--r--arch/ppc/kernel/vmlinux.lds.S26
-rw-r--r--arch/ppc/lib/string.S24
-rw-r--r--arch/ppc/math-emu/sfp-machine.h2
-rw-r--r--arch/ppc/mm/4xx_mmu.c4
-rw-r--r--arch/ppc/mm/init.c23
-rw-r--r--arch/ppc/mm/pgtable.c8
-rw-r--r--arch/ppc/oprofile/common.c161
-rw-r--r--arch/ppc/oprofile/op_impl.h45
-rw-r--r--arch/ppc/platforms/4xx/Kconfig19
-rw-r--r--arch/ppc/platforms/4xx/Makefile2
-rw-r--r--arch/ppc/platforms/4xx/bamboo.c14
-rw-r--r--arch/ppc/platforms/4xx/bubinga.c2
-rw-r--r--arch/ppc/platforms/4xx/bubinga.h64
-rw-r--r--arch/ppc/platforms/4xx/ebony.c15
-rw-r--r--arch/ppc/platforms/4xx/ebony.h4
-rw-r--r--arch/ppc/platforms/4xx/ibm440ep.c1
-rw-r--r--arch/ppc/platforms/4xx/ibmstb4.c1
-rw-r--r--arch/ppc/platforms/4xx/luan.c13
-rw-r--r--arch/ppc/platforms/4xx/ocotea.c31
-rw-r--r--arch/ppc/platforms/4xx/ppc440spe.c148
-rw-r--r--arch/ppc/platforms/4xx/ppc440spe.h66
-rw-r--r--arch/ppc/platforms/4xx/redwood5.c2
-rw-r--r--arch/ppc/platforms/4xx/redwood6.c2
-rw-r--r--arch/ppc/platforms/4xx/sycamore.c7
-rw-r--r--arch/ppc/platforms/4xx/sycamore.h67
-rw-r--r--arch/ppc/platforms/4xx/walnut.c2
-rw-r--r--arch/ppc/platforms/4xx/walnut.h67
-rw-r--r--arch/ppc/platforms/4xx/yucca.c395
-rw-r--r--arch/ppc/platforms/4xx/yucca.h111
-rw-r--r--arch/ppc/platforms/83xx/mpc834x_sys.c23
-rw-r--r--arch/ppc/platforms/83xx/mpc834x_sys.h1
-rw-r--r--arch/ppc/platforms/85xx/mpc8540_ads.c30
-rw-r--r--arch/ppc/platforms/85xx/mpc8560_ads.c25
-rw-r--r--arch/ppc/platforms/85xx/mpc85xx_ads_common.c10
-rw-r--r--arch/ppc/platforms/85xx/mpc85xx_ads_common.h1
-rw-r--r--arch/ppc/platforms/85xx/mpc85xx_cds_common.c39
-rw-r--r--arch/ppc/platforms/85xx/sbc8560.c22
-rw-r--r--arch/ppc/platforms/85xx/stx_gp3.c35
-rw-r--r--arch/ppc/platforms/Makefile3
-rw-r--r--arch/ppc/platforms/chestnut.c1
-rw-r--r--arch/ppc/platforms/chrp_nvram.c83
-rw-r--r--arch/ppc/platforms/chrp_pci.c10
-rw-r--r--arch/ppc/platforms/chrp_pegasos_eth.c126
-rw-r--r--arch/ppc/platforms/chrp_setup.c33
-rw-r--r--arch/ppc/platforms/chrp_smp.c3
-rw-r--r--arch/ppc/platforms/chrp_time.c8
-rw-r--r--arch/ppc/platforms/cpci690.c1
-rw-r--r--arch/ppc/platforms/ev64260.c1
-rw-r--r--arch/ppc/platforms/ev64360.c14
-rw-r--r--arch/ppc/platforms/fads.h2
-rw-r--r--arch/ppc/platforms/gemini_setup.c4
-rw-r--r--arch/ppc/platforms/hdpu.c10
-rw-r--r--arch/ppc/platforms/katana.c4
-rw-r--r--arch/ppc/platforms/lite5200.c1
-rw-r--r--arch/ppc/platforms/lopec.c17
-rw-r--r--arch/ppc/platforms/mpc885ads.h2
-rw-r--r--arch/ppc/platforms/mvme5100.c6
-rw-r--r--arch/ppc/platforms/pal4_setup.c1
-rw-r--r--arch/ppc/platforms/pmac_backlight.c16
-rw-r--r--arch/ppc/platforms/pmac_cpufreq.c36
-rw-r--r--arch/ppc/platforms/pmac_feature.c176
-rw-r--r--arch/ppc/platforms/pmac_nvram.c42
-rw-r--r--arch/ppc/platforms/pmac_pci.c28
-rw-r--r--arch/ppc/platforms/pmac_pic.c30
-rw-r--r--arch/ppc/platforms/pmac_setup.c19
-rw-r--r--arch/ppc/platforms/pmac_sleep.S4
-rw-r--r--arch/ppc/platforms/pmac_smp.c11
-rw-r--r--arch/ppc/platforms/pmac_time.c8
-rw-r--r--arch/ppc/platforms/pplus.c17
-rw-r--r--arch/ppc/platforms/prep_pci.c64
-rw-r--r--arch/ppc/platforms/prep_setup.c79
-rw-r--r--arch/ppc/platforms/radstone_ppc7d.c16
-rw-r--r--arch/ppc/platforms/residual.c2
-rw-r--r--arch/ppc/platforms/sandpoint.c21
-rw-r--r--arch/ppc/syslib/Makefile61
-rw-r--r--arch/ppc/syslib/btext.c6
-rw-r--r--arch/ppc/syslib/gt64260_pic.c1
-rw-r--r--arch/ppc/syslib/ibm440gx_common.c6
-rw-r--r--arch/ppc/syslib/ibm440sp_common.c4
-rw-r--r--arch/ppc/syslib/ibm44x_common.c49
-rw-r--r--arch/ppc/syslib/ibm44x_common.h3
-rw-r--r--arch/ppc/syslib/m8260_setup.c4
-rw-r--r--arch/ppc/syslib/m82xx_pci.c4
-rw-r--r--arch/ppc/syslib/m8xx_setup.c49
-rw-r--r--arch/ppc/syslib/m8xx_wdt.c15
-rw-r--r--arch/ppc/syslib/mpc52xx_devices.c1
-rw-r--r--arch/ppc/syslib/mpc52xx_pci.c3
-rw-r--r--arch/ppc/syslib/mpc83xx_devices.c13
-rw-r--r--arch/ppc/syslib/mpc83xx_sys.c24
-rw-r--r--arch/ppc/syslib/mpc85xx_devices.c17
-rw-r--r--arch/ppc/syslib/mpc85xx_sys.c44
-rw-r--r--arch/ppc/syslib/mpc8xx_sys.c4
-rw-r--r--arch/ppc/syslib/mv64360_pic.c1
-rw-r--r--arch/ppc/syslib/mv64x60.c3
-rw-r--r--arch/ppc/syslib/mv64x60_dbg.c1
-rw-r--r--arch/ppc/syslib/of_device.c276
-rw-r--r--arch/ppc/syslib/open_pic.c3
-rw-r--r--arch/ppc/syslib/open_pic2.c1
-rw-r--r--arch/ppc/syslib/ppc403_pic.c1
-rw-r--r--arch/ppc/syslib/ppc405_pci.c7
-rw-r--r--arch/ppc/syslib/ppc440spe_pcie.c442
-rw-r--r--arch/ppc/syslib/ppc440spe_pcie.h149
-rw-r--r--arch/ppc/syslib/ppc4xx_pic.c38
-rw-r--r--arch/ppc/syslib/ppc4xx_setup.c2
-rw-r--r--arch/ppc/syslib/ppc83xx_setup.c1
-rw-r--r--arch/ppc/syslib/ppc85xx_rio.c938
-rw-r--r--arch/ppc/syslib/ppc85xx_rio.h21
-rw-r--r--arch/ppc/syslib/ppc85xx_setup.c1
-rw-r--r--arch/ppc/syslib/ppc8xx_pic.c17
-rw-r--r--arch/ppc/syslib/ppc_sys.c4
-rw-r--r--arch/ppc/syslib/pq2_devices.c3
-rw-r--r--arch/ppc/syslib/prep_nvram.c13
-rw-r--r--arch/ppc/syslib/prom.c27
-rw-r--r--arch/ppc/syslib/prom_init.c1
-rw-r--r--arch/ppc/syslib/xilinx_pic.c1
-rw-r--r--arch/ppc/xmon/start.c3
-rw-r--r--arch/ppc/xmon/xmon.c14
-rw-r--r--arch/ppc64/Kconfig64
-rw-r--r--arch/ppc64/Kconfig.debug4
-rw-r--r--arch/ppc64/Makefile19
-rw-r--r--arch/ppc64/boot/Makefile67
-rw-r--r--arch/ppc64/boot/addRamDisk.c207
-rw-r--r--arch/ppc64/boot/crt0.S53
-rw-r--r--arch/ppc64/boot/install.sh2
-rw-r--r--arch/ppc64/boot/main.c273
-rw-r--r--arch/ppc64/boot/string.S4
-rw-r--r--arch/ppc64/boot/string.h1
-rw-r--r--arch/ppc64/boot/zImage.lds64
-rw-r--r--arch/ppc64/boot/zlib.c2195
-rw-r--r--arch/ppc64/boot/zlib.h432
-rw-r--r--arch/ppc64/defconfig4
-rw-r--r--arch/ppc64/kernel/HvLpEvent.c88
-rw-r--r--arch/ppc64/kernel/Makefile87
-rw-r--r--arch/ppc64/kernel/align.c4
-rw-r--r--arch/ppc64/kernel/asm-offsets.c9
-rw-r--r--arch/ppc64/kernel/btext.c42
-rw-r--r--arch/ppc64/kernel/cputable.c308
-rw-r--r--arch/ppc64/kernel/head.S660
-rw-r--r--arch/ppc64/kernel/hvcserver.c2
-rw-r--r--arch/ppc64/kernel/i8259.c177
-rw-r--r--arch/ppc64/kernel/i8259.h17
-rw-r--r--arch/ppc64/kernel/idle.c25
-rw-r--r--arch/ppc64/kernel/kprobes.c139
-rw-r--r--arch/ppc64/kernel/machine_kexec.c2
-rw-r--r--arch/ppc64/kernel/misc.S742
-rw-r--r--arch/ppc64/kernel/nvram.c5
-rw-r--r--arch/ppc64/kernel/pci.c73
-rw-r--r--arch/ppc64/kernel/pci.h54
-rw-r--r--arch/ppc64/kernel/pci_direct_iommu.c3
-rw-r--r--arch/ppc64/kernel/pci_dn.c29
-rw-r--r--arch/ppc64/kernel/pci_iommu.c21
-rw-r--r--arch/ppc64/kernel/pmac.h31
-rw-r--r--arch/ppc64/kernel/pmac_feature.c767
-rw-r--r--arch/ppc64/kernel/pmac_pci.c793
-rw-r--r--arch/ppc64/kernel/pmac_setup.c525
-rw-r--r--arch/ppc64/kernel/pmac_smp.c330
-rw-r--r--arch/ppc64/kernel/pmac_time.c195
-rw-r--r--arch/ppc64/kernel/ppc_ksyms.c20
-rw-r--r--arch/ppc64/kernel/prom.c135
-rw-r--r--arch/ppc64/kernel/prom_init.c11
-rw-r--r--arch/ppc64/kernel/ptrace.c363
-rw-r--r--arch/ppc64/kernel/rtc.c48
-rw-r--r--arch/ppc64/kernel/traps.c568
-rw-r--r--arch/ppc64/kernel/udbg.c55
-rw-r--r--arch/ppc64/kernel/udbg_scc.c1
-rw-r--r--arch/ppc64/kernel/vdso.c13
-rw-r--r--arch/ppc64/kernel/vdso64/sigtramp.S1
-rw-r--r--arch/ppc64/kernel/vecemu.c346
-rw-r--r--arch/ppc64/kernel/vmlinux.lds.S17
-rw-r--r--arch/ppc64/lib/Makefile18
-rw-r--r--arch/ppc64/mm/Makefile11
-rw-r--r--arch/ppc64/mm/hash_low.S288
-rw-r--r--arch/ppc64/mm/hash_utils.c438
-rw-r--r--arch/ppc64/mm/init.c869
-rw-r--r--arch/ppc64/mm/slb_low.S151
-rw-r--r--arch/ppc64/oprofile/Kconfig23
-rw-r--r--arch/ppc64/oprofile/Makefile9
-rw-r--r--arch/ppc64/xmon/Makefile5
-rw-r--r--arch/ppc64/xmon/nonstdio.h22
-rw-r--r--arch/ppc64/xmon/setjmp.S73
-rw-r--r--arch/ppc64/xmon/start.c187
-rw-r--r--arch/ppc64/xmon/subr_prf.c55
-rw-r--r--arch/s390/Makefile4
-rw-r--r--arch/s390/appldata/appldata_base.c7
-rw-r--r--arch/s390/kernel/Makefile4
-rw-r--r--arch/s390/kernel/compat_ioctl.c9
-rw-r--r--arch/s390/kernel/debug.c12
-rw-r--r--arch/s390/kernel/entry.S4
-rw-r--r--arch/s390/kernel/entry64.S4
-rw-r--r--arch/s390/kernel/head.S427
-rw-r--r--arch/s390/kernel/head31.S336
-rw-r--r--arch/s390/kernel/head64.S497
-rw-r--r--arch/s390/kernel/process.c24
-rw-r--r--arch/s390/kernel/setup.c186
-rw-r--r--arch/s390/kernel/smp.c1
-rw-r--r--arch/s390/kernel/time.c12
-rw-r--r--arch/s390/kernel/traps.c29
-rw-r--r--arch/s390/kernel/vtime.c18
-rw-r--r--arch/s390/mm/extmem.c8
-rw-r--r--arch/s390/mm/fault.c115
-rw-r--r--arch/s390/mm/ioremap.c4
-rw-r--r--arch/sh/Kconfig28
-rw-r--r--arch/sh/Makefile8
-rw-r--r--arch/sh/boards/renesas/rts7751r2d/mach.c2
-rw-r--r--arch/sh/boards/superh/microdev/setup.c2
-rw-r--r--arch/sh/cchips/voyagergx/consistent.c2
-rw-r--r--arch/sh/drivers/Makefile5
-rw-r--r--arch/sh/drivers/dma/dma-sysfs.c1
-rw-r--r--arch/sh/drivers/pci/dma-dreamcast.c2
-rw-r--r--arch/sh/drivers/superhyway/Makefile6
-rw-r--r--arch/sh/drivers/superhyway/ops-sh4-202.c171
-rw-r--r--arch/sh/kernel/cpufreq.c1
-rw-r--r--arch/sh/kernel/process.c14
-rw-r--r--arch/sh/kernel/ptrace.c44
-rw-r--r--arch/sh/kernel/setup.c26
-rw-r--r--arch/sh/kernel/smp.c5
-rw-r--r--arch/sh/kernel/time.c4
-rw-r--r--arch/sh/mm/consistent.c2
-rw-r--r--arch/sh/mm/fault.c40
-rw-r--r--arch/sh/mm/hugetlbpage.c2
-rw-r--r--arch/sh/mm/init.c21
-rw-r--r--arch/sh/mm/ioremap.c4
-rw-r--r--arch/sh/mm/tlb-sh3.c19
-rw-r--r--arch/sh/ramdisk/Makefile20
-rw-r--r--arch/sh/ramdisk/ld.script9
-rw-r--r--arch/sh64/kernel/process.c16
-rw-r--r--arch/sh64/kernel/ptrace.c83
-rw-r--r--arch/sh64/kernel/syscalls.S2
-rw-r--r--arch/sh64/kernel/time.c3
-rw-r--r--arch/sh64/mm/cache.c68
-rw-r--r--arch/sh64/mm/hugetlbpage.c188
-rw-r--r--arch/sh64/mm/ioremap.c4
-rw-r--r--arch/sparc/Kconfig8
-rw-r--r--arch/sparc/kernel/Makefile1
-rw-r--r--arch/sparc/kernel/cpu.c4
-rw-r--r--arch/sparc/kernel/led.c139
-rw-r--r--arch/sparc/kernel/pcic.c6
-rw-r--r--arch/sparc/kernel/process.c35
-rw-r--r--arch/sparc/kernel/sunos_ioctl.c1
-rw-r--r--arch/sparc/kernel/time.c4
-rw-r--r--arch/sparc/mm/fault.c2
-rw-r--r--arch/sparc/mm/generic.c7
-rw-r--r--arch/sparc64/Kconfig13
-rw-r--r--arch/sparc64/Kconfig.debug10
-rw-r--r--arch/sparc64/kernel/binfmt_aout32.c1
-rw-r--r--arch/sparc64/kernel/cpu.c4
-rw-r--r--arch/sparc64/kernel/ioctl32.c468
-rw-r--r--arch/sparc64/kernel/kprobes.c165
-rw-r--r--arch/sparc64/kernel/process.c24
-rw-r--r--arch/sparc64/kernel/sbus.c2
-rw-r--r--arch/sparc64/kernel/setup.c12
-rw-r--r--arch/sparc64/kernel/signal32.c6
-rw-r--r--arch/sparc64/kernel/smp.c95
-rw-r--r--arch/sparc64/kernel/sunos_ioctl32.c1
-rw-r--r--arch/sparc64/kernel/time.c17
-rw-r--r--arch/sparc64/kernel/us2e_cpufreq.c7
-rw-r--r--arch/sparc64/kernel/us3_cpufreq.c7
-rw-r--r--arch/sparc64/mm/fault.c4
-rw-r--r--arch/sparc64/mm/generic.c9
-rw-r--r--arch/sparc64/mm/tlb.c7
-rw-r--r--arch/sparc64/oprofile/Kconfig6
-rw-r--r--arch/sparc64/solaris/socksys.c2
-rw-r--r--arch/sparc64/solaris/timod.c2
-rw-r--r--arch/um/Kconfig56
-rw-r--r--arch/um/Kconfig.x86_645
-rw-r--r--arch/um/Makefile2
-rw-r--r--arch/um/Makefile-i38614
-rw-r--r--arch/um/drivers/chan_user.c1
-rw-r--r--arch/um/drivers/harddog_kern.c1
-rw-r--r--arch/um/drivers/harddog_user.c1
-rw-r--r--arch/um/drivers/net_kern.c77
-rw-r--r--arch/um/drivers/net_user.c1
-rw-r--r--arch/um/drivers/port_user.c1
-rw-r--r--arch/um/drivers/random.c6
-rw-r--r--arch/um/drivers/slip_user.c1
-rw-r--r--arch/um/drivers/slirp_user.c1
-rw-r--r--arch/um/drivers/ubd_kern.c1
-rw-r--r--arch/um/drivers/xterm.c1
-rw-r--r--arch/um/include/helper.h27
-rw-r--r--arch/um/include/mem_user.h2
-rw-r--r--arch/um/include/net_kern.h9
-rw-r--r--arch/um/include/net_user.h2
-rw-r--r--arch/um/include/os.h16
-rw-r--r--arch/um/include/sysdep-i386/stub.h64
-rw-r--r--arch/um/include/sysdep-i386/syscalls.h1
-rw-r--r--arch/um/include/sysdep-x86_64/stub.h61
-rw-r--r--arch/um/include/tlb.h1
-rw-r--r--arch/um/include/uml_uaccess.h4
-rw-r--r--arch/um/kernel/Makefile7
-rw-r--r--arch/um/kernel/ksyms.c1
-rw-r--r--arch/um/kernel/mem.c6
-rw-r--r--arch/um/kernel/physmem.c4
-rw-r--r--arch/um/kernel/process_kern.c10
-rw-r--r--arch/um/kernel/ptrace.c50
-rw-r--r--arch/um/kernel/sigio_user.c3
-rw-r--r--arch/um/kernel/skas/include/mmu-skas.h2
-rw-r--r--arch/um/kernel/skas/include/skas.h3
-rw-r--r--arch/um/kernel/skas/mem.c2
-rw-r--r--arch/um/kernel/skas/mmu.c48
-rw-r--r--arch/um/kernel/skas/process.c17
-rw-r--r--arch/um/kernel/skas/process_kern.c2
-rw-r--r--arch/um/kernel/time_kern.c4
-rw-r--r--arch/um/kernel/tt/tlb.c36
-rw-r--r--arch/um/kernel/tt/uaccess_user.c1
-rw-r--r--arch/um/kernel/uaccess.c30
-rw-r--r--arch/um/kernel/uaccess_user.c64
-rw-r--r--arch/um/kernel/um_arch.c10
-rw-r--r--arch/um/kernel/user_util.c1
-rw-r--r--arch/um/os-Linux/Makefile9
-rw-r--r--arch/um/os-Linux/aio.c1
-rw-r--r--arch/um/os-Linux/drivers/ethertap_user.c1
-rw-r--r--arch/um/os-Linux/drivers/tuntap_user.c1
-rw-r--r--arch/um/os-Linux/helper.c (renamed from arch/um/kernel/helper.c)18
-rw-r--r--arch/um/os-Linux/main.c (renamed from arch/um/kernel/main.c)49
-rw-r--r--arch/um/os-Linux/mem.c6
-rw-r--r--arch/um/os-Linux/start_up.c77
-rw-r--r--arch/um/os-Linux/uaccess.c32
-rw-r--r--arch/um/scripts/Makefile.rules7
-rw-r--r--arch/um/sys-i386/ldt.c506
-rw-r--r--arch/um/sys-x86_64/Makefile5
-rw-r--r--arch/um/sys-x86_64/syscalls.c75
-rw-r--r--arch/v850/kernel/process.c16
-rw-r--r--arch/v850/kernel/ptrace.c43
-rw-r--r--arch/v850/kernel/time.c4
-rw-r--r--arch/x86_64/Kconfig13
-rw-r--r--arch/x86_64/Kconfig.debug10
-rw-r--r--arch/x86_64/ia32/ia32_aout.c1
-rw-r--r--arch/x86_64/ia32/ia32_ioctl.c131
-rw-r--r--arch/x86_64/kernel/Makefile2
-rw-r--r--arch/x86_64/kernel/i8259.c8
-rw-r--r--arch/x86_64/kernel/kprobes.c183
-rw-r--r--arch/x86_64/kernel/pci-gart.c4
-rw-r--r--arch/x86_64/kernel/pci-nommu.c2
-rw-r--r--arch/x86_64/kernel/process.c69
-rw-r--r--arch/x86_64/kernel/ptrace.c43
-rw-r--r--arch/x86_64/kernel/setup.c2
-rw-r--r--arch/x86_64/kernel/smpboot.c3
-rw-r--r--arch/x86_64/kernel/suspend.c95
-rw-r--r--arch/x86_64/kernel/time.c32
-rw-r--r--arch/x86_64/lib/bitops.c66
-rw-r--r--arch/x86_64/mm/ioremap.c4
-rw-r--r--arch/x86_64/oprofile/Kconfig6
-rw-r--r--arch/xtensa/kernel/pci-dma.c2
-rw-r--r--arch/xtensa/kernel/platform.c1
-rw-r--r--arch/xtensa/kernel/process.c3
-rw-r--r--arch/xtensa/kernel/ptrace.c55
-rw-r--r--arch/xtensa/kernel/time.c3
-rw-r--r--arch/xtensa/platform-iss/network.c34
-rw-r--r--block/Kconfig14
-rw-r--r--block/Kconfig.iosched (renamed from drivers/block/Kconfig.iosched)28
-rw-r--r--block/Makefile10
-rw-r--r--block/as-iosched.c (renamed from drivers/block/as-iosched.c)640
-rw-r--r--block/cfq-iosched.c (renamed from drivers/block/cfq-iosched.c)398
-rw-r--r--block/deadline-iosched.c (renamed from drivers/block/deadline-iosched.c)125
-rw-r--r--block/elevator.c (renamed from drivers/block/elevator.c)396
-rw-r--r--block/genhd.c (renamed from drivers/block/genhd.c)54
-rw-r--r--block/ioctl.c (renamed from drivers/block/ioctl.c)0
-rw-r--r--block/ll_rw_blk.c (renamed from drivers/block/ll_rw_blk.c)241
-rw-r--r--block/noop-iosched.c46
-rw-r--r--block/scsi_ioctl.c (renamed from drivers/block/scsi_ioctl.c)0
-rw-r--r--crypto/api.c5
-rw-r--r--crypto/hmac.c19
-rw-r--r--crypto/tcrypt.c56
-rw-r--r--drivers/Makefile4
-rw-r--r--drivers/acorn/char/pcf8583.c80
-rw-r--r--drivers/acpi/acpi_memhotplug.c5
-rw-r--r--drivers/acpi/container.c6
-rw-r--r--drivers/acpi/glue.c1
-rw-r--r--drivers/acpi/osl.c6
-rw-r--r--drivers/acpi/processor_idle.c38
-rw-r--r--drivers/acpi/scan.c6
-rw-r--r--drivers/acpi/sleep/main.c8
-rw-r--r--drivers/acpi/video.c12
-rw-r--r--drivers/atm/horizon.c4
-rw-r--r--drivers/base/Makefile1
-rw-r--r--drivers/base/attribute_container.c2
-rw-r--r--drivers/base/base.h12
-rw-r--r--drivers/base/class.c151
-rw-r--r--drivers/base/core.c21
-rw-r--r--drivers/base/cpu.c17
-rw-r--r--drivers/base/driver.c3
-rw-r--r--drivers/base/firmware.c3
-rw-r--r--drivers/base/firmware_class.c69
-rw-r--r--drivers/base/init.c12
-rw-r--r--drivers/base/memory.c452
-rw-r--r--drivers/base/platform.c178
-rw-r--r--drivers/base/power/main.c26
-rw-r--r--drivers/base/power/power.h13
-rw-r--r--drivers/base/power/runtime.c1
-rw-r--r--drivers/base/power/sysfs.c74
-rw-r--r--drivers/base/sys.c1
-rw-r--r--drivers/block/DAC960.c31
-rw-r--r--drivers/block/Kconfig12
-rw-r--r--drivers/block/Makefile14
-rw-r--r--drivers/block/amiflop.c1
-rw-r--r--drivers/block/aoe/aoe.h2
-rw-r--r--drivers/block/aoe/aoechr.c2
-rw-r--r--drivers/block/aoe/aoecmd.c28
-rw-r--r--drivers/block/cciss.c12
-rw-r--r--drivers/block/cciss_scsi.c10
-rw-r--r--drivers/block/floppy.c11
-rw-r--r--drivers/block/loop.c2
-rw-r--r--drivers/block/noop-iosched.c83
-rw-r--r--drivers/block/paride/paride.c1
-rw-r--r--drivers/block/paride/pf.c4
-rw-r--r--drivers/block/paride/pg.c4
-rw-r--r--drivers/block/paride/pt.c5
-rw-r--r--drivers/block/pktcdvd.c3
-rw-r--r--drivers/block/rd.c2
-rw-r--r--drivers/block/swim3.c20
-rw-r--r--drivers/block/sx8.c51
-rw-r--r--drivers/block/ub.c4
-rw-r--r--drivers/block/viodasd.c17
-rw-r--r--drivers/bluetooth/Kconfig8
-rw-r--r--drivers/bluetooth/bcm203x.c4
-rw-r--r--drivers/bluetooth/bfusb.c4
-rw-r--r--drivers/bluetooth/bluecard_cs.c3
-rw-r--r--drivers/bluetooth/bpa10x.c11
-rw-r--r--drivers/bluetooth/bt3c_cs.c3
-rw-r--r--drivers/bluetooth/btuart_cs.c3
-rw-r--r--drivers/bluetooth/dtl1_cs.c3
-rw-r--r--drivers/bluetooth/hci_bcsp.c163
-rw-r--r--drivers/bluetooth/hci_bcsp.h70
-rw-r--r--drivers/bluetooth/hci_h4.c103
-rw-r--r--drivers/bluetooth/hci_h4.h44
-rw-r--r--drivers/bluetooth/hci_ldisc.c136
-rw-r--r--drivers/bluetooth/hci_uart.h84
-rw-r--r--drivers/bluetooth/hci_usb.c11
-rw-r--r--drivers/bluetooth/hci_vhci.c4
-rw-r--r--drivers/cdrom/mcdx.c4
-rw-r--r--drivers/cdrom/viocd.c15
-rw-r--r--drivers/char/Kconfig16
-rw-r--r--drivers/char/Makefile1
-rw-r--r--drivers/char/agp/Kconfig16
-rw-r--r--drivers/char/agp/ali-agp.c1
-rw-r--r--drivers/char/agp/amd-k7-agp.c7
-rw-r--r--drivers/char/agp/amd64-agp.c2
-rw-r--r--drivers/char/agp/ati-agp.c9
-rw-r--r--drivers/char/agp/backend.c15
-rw-r--r--drivers/char/agp/efficeon-agp.c2
-rw-r--r--drivers/char/agp/frontend.c15
-rw-r--r--drivers/char/agp/generic.c19
-rw-r--r--drivers/char/agp/i460-agp.c25
-rw-r--r--drivers/char/agp/intel-agp.c5
-rw-r--r--drivers/char/agp/isoch.c1
-rw-r--r--drivers/char/agp/sgi-agp.c3
-rw-r--r--drivers/char/agp/sworks-agp.c30
-rw-r--r--drivers/char/consolemap.c12
-rw-r--r--drivers/char/cyclades.c2
-rw-r--r--drivers/char/drm/ati_pcigart.c152
-rw-r--r--drivers/char/drm/drm.h295
-rw-r--r--drivers/char/drm/drmP.h886
-rw-r--r--drivers/char/drm/drm_agpsupport.c150
-rw-r--r--drivers/char/drm/drm_auth.c68
-rw-r--r--drivers/char/drm/drm_bufs.c891
-rw-r--r--drivers/char/drm/drm_context.c308
-rw-r--r--drivers/char/drm/drm_dma.c87
-rw-r--r--drivers/char/drm/drm_drawable.c8
-rw-r--r--drivers/char/drm/drm_drv.c361
-rw-r--r--drivers/char/drm/drm_fops.c296
-rw-r--r--drivers/char/drm/drm_init.c7
-rw-r--r--drivers/char/drm/drm_ioc32.c225
-rw-r--r--drivers/char/drm/drm_ioctl.c168
-rw-r--r--drivers/char/drm/drm_irq.c169
-rw-r--r--drivers/char/drm/drm_lock.c177
-rw-r--r--drivers/char/drm/drm_memory.c54
-rw-r--r--drivers/char/drm/drm_memory.h73
-rw-r--r--drivers/char/drm/drm_memory_debug.h224
-rw-r--r--drivers/char/drm/drm_os_linux.h17
-rw-r--r--drivers/char/drm/drm_pci.c10
-rw-r--r--drivers/char/drm/drm_pciids.h1
-rw-r--r--drivers/char/drm/drm_proc.c272
-rw-r--r--drivers/char/drm/drm_sarea.h30
-rw-r--r--drivers/char/drm/drm_scatter.c183
-rw-r--r--drivers/char/drm/drm_stub.c112
-rw-r--r--drivers/char/drm/drm_sysfs.c2
-rw-r--r--drivers/char/drm/drm_vm.c365
-rw-r--r--drivers/char/drm/ffb_context.c236
-rw-r--r--drivers/char/drm/ffb_drv.c137
-rw-r--r--drivers/char/drm/ffb_drv.h433
-rw-r--r--drivers/char/drm/i810_dma.c1087
-rw-r--r--drivers/char/drm/i810_drm.h75
-rw-r--r--drivers/char/drm/i810_drv.c63
-rw-r--r--drivers/char/drm/i810_drv.h41
-rw-r--r--drivers/char/drm/i830_dma.c1315
-rw-r--r--drivers/char/drm/i830_drm.h90
-rw-r--r--drivers/char/drm/i830_drv.c62
-rw-r--r--drivers/char/drm/i830_drv.h83
-rw-r--r--drivers/char/drm/i830_irq.c137
-rw-r--r--drivers/char/drm/i915_dma.c32
-rw-r--r--drivers/char/drm/i915_drv.c64
-rw-r--r--drivers/char/drm/i915_drv.h16
-rw-r--r--drivers/char/drm/i915_ioc32.c64
-rw-r--r--drivers/char/drm/i915_mem.c8
-rw-r--r--drivers/char/drm/mga_dma.c511
-rw-r--r--drivers/char/drm/mga_drm.h142
-rw-r--r--drivers/char/drm/mga_drv.c80
-rw-r--r--drivers/char/drm/mga_drv.h45
-rw-r--r--drivers/char/drm/mga_ioc32.c60
-rw-r--r--drivers/char/drm/mga_irq.c42
-rw-r--r--drivers/char/drm/mga_state.c856
-rw-r--r--drivers/char/drm/mga_ucode.h16070
-rw-r--r--drivers/char/drm/mga_warp.c120
-rw-r--r--drivers/char/drm/r128_cce.c596
-rw-r--r--drivers/char/drm/r128_drm.h32
-rw-r--r--drivers/char/drm/r128_drv.c63
-rw-r--r--drivers/char/drm/r128_drv.h73
-rw-r--r--drivers/char/drm/r128_ioc32.c35
-rw-r--r--drivers/char/drm/r128_irq.c53
-rw-r--r--drivers/char/drm/r128_state.c1386
-rw-r--r--drivers/char/drm/r300_cmdbuf.c502
-rw-r--r--drivers/char/drm/r300_reg.h192
-rw-r--r--drivers/char/drm/radeon_cp.c2483
-rw-r--r--drivers/char/drm/radeon_drm.h286
-rw-r--r--drivers/char/drm/radeon_drv.c69
-rw-r--r--drivers/char/drm/radeon_drv.h200
-rw-r--r--drivers/char/drm/radeon_ioc32.c51
-rw-r--r--drivers/char/drm/radeon_irq.c127
-rw-r--r--drivers/char/drm/radeon_mem.c148
-rw-r--r--drivers/char/drm/radeon_state.c2473
-rw-r--r--drivers/char/drm/savage_bci.c189
-rw-r--r--drivers/char/drm/savage_drm.h53
-rw-r--r--drivers/char/drm/savage_drv.c59
-rw-r--r--drivers/char/drm/savage_drv.h61
-rw-r--r--drivers/char/drm/savage_state.c485
-rw-r--r--drivers/char/drm/sis_drm.h2
-rw-r--r--drivers/char/drm/sis_drv.c61
-rw-r--r--drivers/char/drm/sis_drv.h13
-rw-r--r--drivers/char/drm/sis_ds.c82
-rw-r--r--drivers/char/drm/sis_ds.h40
-rw-r--r--drivers/char/drm/sis_mm.c127
-rw-r--r--drivers/char/drm/tdfx_drv.c52
-rw-r--r--drivers/char/drm/via_3d_reg.h1
-rw-r--r--drivers/char/drm/via_dma.c259
-rw-r--r--drivers/char/drm/via_drm.h4
-rw-r--r--drivers/char/drm/via_drv.c22
-rw-r--r--drivers/char/drm/via_drv.h22
-rw-r--r--drivers/char/drm/via_irq.c106
-rw-r--r--drivers/char/drm/via_map.c4
-rw-r--r--drivers/char/drm/via_mm.c17
-rw-r--r--drivers/char/drm/via_verifier.c483
-rw-r--r--drivers/char/drm/via_verifier.h22
-rw-r--r--drivers/char/drm/via_video.c30
-rw-r--r--drivers/char/dsp56k.c2
-rw-r--r--drivers/char/ftape/zftape/zftape-init.c12
-rw-r--r--drivers/char/hangcheck-timer.c2
-rw-r--r--drivers/char/hpet.c168
-rw-r--r--drivers/char/hvc_vio.c2
-rw-r--r--drivers/char/hvcs.c5
-rw-r--r--drivers/char/ip2.c1
-rw-r--r--drivers/char/ip2/i2ellis.c4
-rw-r--r--drivers/char/ip2main.c10
-rw-r--r--drivers/char/ipmi/ipmi_bt_sm.c38
-rw-r--r--drivers/char/ipmi/ipmi_devintf.c2
-rw-r--r--drivers/char/ipmi/ipmi_kcs_sm.c48
-rw-r--r--drivers/char/ipmi/ipmi_msghandler.c952
-rw-r--r--drivers/char/ipmi/ipmi_poweroff.c4
-rw-r--r--drivers/char/ipmi/ipmi_si_intf.c183
-rw-r--r--drivers/char/ipmi/ipmi_si_sm.h1
-rw-r--r--drivers/char/ipmi/ipmi_smic_sm.c15
-rw-r--r--drivers/char/ipmi/ipmi_watchdog.c259
-rw-r--r--drivers/char/istallion.c10
-rw-r--r--drivers/char/lcd.c4
-rw-r--r--drivers/char/lcd.h2
-rw-r--r--drivers/char/lp.c2
-rw-r--r--drivers/char/mem.c7
-rw-r--r--drivers/char/misc.c2
-rw-r--r--drivers/char/mmtimer.c4
-rw-r--r--drivers/char/mwave/3780i.c2
-rw-r--r--drivers/char/mwave/tp3780i.c1
-rw-r--r--drivers/char/mxser.c48
-rw-r--r--drivers/char/n_hdlc.c3
-rw-r--r--drivers/char/n_tty.c2
-rw-r--r--drivers/char/pcmcia/synclink_cs.c3
-rw-r--r--drivers/char/ppdev.c2
-rw-r--r--drivers/char/qtronix.c5
-rw-r--r--drivers/char/raw.c4
-rw-r--r--drivers/char/rocket.c16
-rw-r--r--drivers/char/rtc.c65
-rw-r--r--drivers/char/s3c2410-rtc.c22
-rw-r--r--drivers/char/selection.c3
-rw-r--r--drivers/char/ser_a2232.c2
-rw-r--r--drivers/char/snsc.c6
-rw-r--r--drivers/char/sonypi.c107
-rw-r--r--drivers/char/specialix.c343
-rw-r--r--drivers/char/stallion.c10
-rw-r--r--drivers/char/synclink.c10
-rw-r--r--drivers/char/synclinkmp.c9
-rw-r--r--drivers/char/sysrq.c4
-rw-r--r--drivers/char/tb0219.c2
-rw-r--r--drivers/char/tipar.c2
-rw-r--r--drivers/char/tlclk.c897
-rw-r--r--drivers/char/tpm/tpm.c104
-rw-r--r--drivers/char/tpm/tpm.h13
-rw-r--r--drivers/char/tpm/tpm_atmel.c147
-rw-r--r--drivers/char/tpm/tpm_infineon.c179
-rw-r--r--drivers/char/tpm/tpm_nsc.c165
-rw-r--r--drivers/char/tty_io.c21
-rw-r--r--drivers/char/vc_screen.c10
-rw-r--r--drivers/char/viocons.c11
-rw-r--r--drivers/char/viotape.c24
-rw-r--r--drivers/char/vr41xx_giu.c2
-rw-r--r--drivers/char/vr41xx_rtc.c2
-rw-r--r--drivers/char/vt_ioctl.c6
-rw-r--r--drivers/char/watchdog/cpu5wdt.c1
-rw-r--r--drivers/char/watchdog/mixcomwd.c2
-rw-r--r--drivers/char/watchdog/mpcore_wdt.c3
-rw-r--r--drivers/char/watchdog/mv64x60_wdt.c3
-rw-r--r--drivers/char/watchdog/pcwd.c2
-rw-r--r--drivers/char/watchdog/pcwd_pci.c6
-rw-r--r--drivers/char/watchdog/s3c2410_wdt.c33
-rw-r--r--drivers/char/watchdog/sc520_wdt.c1
-rw-r--r--drivers/char/watchdog/softdog.c2
-rw-r--r--drivers/char/watchdog/w83627hf_wdt.c2
-rw-r--r--drivers/connector/Kconfig8
-rw-r--r--drivers/connector/Makefile1
-rw-r--r--drivers/connector/cn_proc.c222
-rw-r--r--drivers/cpufreq/cpufreq.c86
-rw-r--r--drivers/cpufreq/cpufreq_ondemand.c18
-rw-r--r--drivers/cpufreq/cpufreq_stats.c54
-rw-r--r--drivers/crypto/Kconfig2
-rw-r--r--drivers/dio/dio.c3
-rw-r--r--drivers/eisa/eisa-bus.c8
-rw-r--r--drivers/eisa/virtual_root.c2
-rw-r--r--drivers/fc4/fc.c32
-rw-r--r--drivers/fc4/soc.c3
-rw-r--r--drivers/fc4/socal.c3
-rw-r--r--drivers/firmware/Kconfig3
-rw-r--r--drivers/firmware/dcdbas.c2
-rw-r--r--drivers/firmware/dell_rbu.c124
-rw-r--r--drivers/firmware/edd.c3
-rw-r--r--drivers/firmware/efivars.c10
-rw-r--r--drivers/hwmon/adm1021.c5
-rw-r--r--drivers/hwmon/adm1025.c3
-rw-r--r--drivers/hwmon/adm1026.c22
-rw-r--r--drivers/hwmon/adm1031.c3
-rw-r--r--drivers/hwmon/adm9240.c429
-rw-r--r--drivers/hwmon/asb100.c11
-rw-r--r--drivers/hwmon/atxp1.c5
-rw-r--r--drivers/hwmon/ds1621.c9
-rw-r--r--drivers/hwmon/fscher.c3
-rw-r--r--drivers/hwmon/fscpos.c5
-rw-r--r--drivers/hwmon/gl518sm.c3
-rw-r--r--drivers/hwmon/gl520sm.c3
-rw-r--r--drivers/hwmon/hdaps.c8
-rw-r--r--drivers/hwmon/hwmon.c3
-rw-r--r--drivers/hwmon/it87.c56
-rw-r--r--drivers/hwmon/lm63.c3
-rw-r--r--drivers/hwmon/lm75.c3
-rw-r--r--drivers/hwmon/lm77.c3
-rw-r--r--drivers/hwmon/lm78.c6
-rw-r--r--drivers/hwmon/lm80.c5
-rw-r--r--drivers/hwmon/lm83.c3
-rw-r--r--drivers/hwmon/lm85.c15
-rw-r--r--drivers/hwmon/lm87.c3
-rw-r--r--drivers/hwmon/lm90.c181
-rw-r--r--drivers/hwmon/lm92.c3
-rw-r--r--drivers/hwmon/max1619.c17
-rw-r--r--drivers/hwmon/pc87360.c3
-rw-r--r--drivers/hwmon/sis5595.c3
-rw-r--r--drivers/hwmon/smsc47b397.c10
-rw-r--r--drivers/hwmon/smsc47m1.c10
-rw-r--r--drivers/hwmon/via686a.c28
-rw-r--r--drivers/hwmon/w83627ehf.c16
-rw-r--r--drivers/hwmon/w83627hf.c48
-rw-r--r--drivers/hwmon/w83781d.c17
-rw-r--r--drivers/hwmon/w83792d.c7
-rw-r--r--drivers/hwmon/w83l785ts.c42
-rw-r--r--drivers/i2c/algos/i2c-algo-pca.c2
-rw-r--r--drivers/i2c/algos/i2c-algo-sibyte.c2
-rw-r--r--drivers/i2c/busses/Kconfig3
-rw-r--r--drivers/i2c/busses/i2c-ali1535.c6
-rw-r--r--drivers/i2c/busses/i2c-ali1563.c6
-rw-r--r--drivers/i2c/busses/i2c-ali15x3.c9
-rw-r--r--drivers/i2c/busses/i2c-amd756-s4882.c10
-rw-r--r--drivers/i2c/busses/i2c-amd756.c7
-rw-r--r--drivers/i2c/busses/i2c-amd8111.c15
-rw-r--r--drivers/i2c/busses/i2c-elektor.c138
-rw-r--r--drivers/i2c/busses/i2c-i801.c60
-rw-r--r--drivers/i2c/busses/i2c-i810.c1
-rw-r--r--drivers/i2c/busses/i2c-ibm_iic.c3
-rw-r--r--drivers/i2c/busses/i2c-iop3xx.c20
-rw-r--r--drivers/i2c/busses/i2c-isa.c2
-rw-r--r--drivers/i2c/busses/i2c-ixp2000.c10
-rw-r--r--drivers/i2c/busses/i2c-ixp4xx.c10
-rw-r--r--drivers/i2c/busses/i2c-keywest.c5
-rw-r--r--drivers/i2c/busses/i2c-mpc.c6
-rw-r--r--drivers/i2c/busses/i2c-mv64xxx.c8
-rw-r--r--drivers/i2c/busses/i2c-nforce2.c15
-rw-r--r--drivers/i2c/busses/i2c-parport.c11
-rw-r--r--drivers/i2c/busses/i2c-piix4.c12
-rw-r--r--drivers/i2c/busses/i2c-pmac-smu.c3
-rw-r--r--drivers/i2c/busses/i2c-prosavage.c9
-rw-r--r--drivers/i2c/busses/i2c-pxa.c1
-rw-r--r--drivers/i2c/busses/i2c-s3c2410.c19
-rw-r--r--drivers/i2c/busses/i2c-sis5595.c9
-rw-r--r--drivers/i2c/busses/i2c-sis630.c8
-rw-r--r--drivers/i2c/busses/i2c-sis96x.c7
-rw-r--r--drivers/i2c/busses/i2c-via.c6
-rw-r--r--drivers/i2c/busses/i2c-viapro.c279
-rw-r--r--drivers/i2c/busses/scx200_acb.c3
-rw-r--r--drivers/i2c/chips/Kconfig9
-rw-r--r--drivers/i2c/chips/Makefile1
-rw-r--r--drivers/i2c/chips/ds1337.c7
-rw-r--r--drivers/i2c/chips/ds1374.c7
-rw-r--r--drivers/i2c/chips/eeprom.c9
-rw-r--r--drivers/i2c/chips/isp1301_omap.c3
-rw-r--r--drivers/i2c/chips/m41t00.c4
-rw-r--r--drivers/i2c/chips/max6875.c6
-rw-r--r--drivers/i2c/chips/pca9539.c3
-rw-r--r--drivers/i2c/chips/pcf8574.c5
-rw-r--r--drivers/i2c/chips/pcf8591.c5
-rw-r--r--drivers/i2c/chips/rtc8564.c5
-rw-r--r--drivers/i2c/chips/tps65010.c3
-rw-r--r--drivers/i2c/chips/x1205.c698
-rw-r--r--drivers/i2c/i2c-core.c199
-rw-r--r--drivers/i2c/i2c-dev.c18
-rw-r--r--drivers/ide/Kconfig40
-rw-r--r--drivers/ide/ide-cd.c76
-rw-r--r--drivers/ide/ide-disk.c4
-rw-r--r--drivers/ide/ide-floppy.c10
-rw-r--r--drivers/ide/ide-iops.c6
-rw-r--r--drivers/ide/ide-probe.c9
-rw-r--r--drivers/ide/ide-proc.c1
-rw-r--r--drivers/ide/ide-tape.c42
-rw-r--r--drivers/ide/ide-taskfile.c20
-rw-r--r--drivers/ide/ide.c7
-rw-r--r--drivers/ide/legacy/ide-cs.c13
-rw-r--r--drivers/ide/mips/au1xxx-ide.c1250
-rw-r--r--drivers/ide/pci/Makefile1
-rw-r--r--drivers/ide/pci/amd74xx.c3
-rw-r--r--drivers/ide/pci/cs5535.c305
-rw-r--r--drivers/ide/pci/cy82c693.c2
-rw-r--r--drivers/ide/pci/hpt366.c3
-rw-r--r--drivers/ide/pci/it821x.c3
-rw-r--r--drivers/ide/pci/siimage.c9
-rw-r--r--drivers/ide/ppc/pmac.c89
-rw-r--r--drivers/ide/setup-pci.c12
-rw-r--r--drivers/ieee1394/amdtp.c3
-rw-r--r--drivers/ieee1394/dv1394.c2
-rw-r--r--drivers/ieee1394/eth1394.c2
-rw-r--r--drivers/ieee1394/nodemgr.c4
-rw-r--r--drivers/ieee1394/raw1394.c2
-rw-r--r--drivers/ieee1394/video1394.c2
-rw-r--r--drivers/infiniband/Kconfig2
-rw-r--r--drivers/infiniband/Makefile1
-rw-r--r--drivers/infiniband/core/agent.c297
-rw-r--r--drivers/infiniband/core/agent.h14
-rw-r--r--drivers/infiniband/core/agent_priv.h62
-rw-r--r--drivers/infiniband/core/cache.c1
-rw-r--r--drivers/infiniband/core/cm.c223
-rw-r--r--drivers/infiniband/core/cm_msgs.h1
-rw-r--r--drivers/infiniband/core/device.c22
-rw-r--r--drivers/infiniband/core/mad.c368
-rw-r--r--drivers/infiniband/core/mad_priv.h8
-rw-r--r--drivers/infiniband/core/mad_rmpp.c114
-rw-r--r--drivers/infiniband/core/mad_rmpp.h2
-rw-r--r--drivers/infiniband/core/packer.c2
-rw-r--r--drivers/infiniband/core/sa_query.c271
-rw-r--r--drivers/infiniband/core/smi.h2
-rw-r--r--drivers/infiniband/core/sysfs.c25
-rw-r--r--drivers/infiniband/core/ucm.c272
-rw-r--r--drivers/infiniband/core/ucm.h83
-rw-r--r--drivers/infiniband/core/ud_header.c1
-rw-r--r--drivers/infiniband/core/user_mad.c576
-rw-r--r--drivers/infiniband/core/uverbs.h63
-rw-r--r--drivers/infiniband/core/uverbs_cmd.c867
-rw-r--r--drivers/infiniband/core/uverbs_main.c510
-rw-r--r--drivers/infiniband/core/verbs.c31
-rw-r--r--drivers/infiniband/hw/mthca/Makefile3
-rw-r--r--drivers/infiniband/hw/mthca/mthca_av.c2
-rw-r--r--drivers/infiniband/hw/mthca/mthca_catas.c156
-rw-r--r--drivers/infiniband/hw/mthca/mthca_cmd.c15
-rw-r--r--drivers/infiniband/hw/mthca/mthca_cmd.h2
-rw-r--r--drivers/infiniband/hw/mthca/mthca_cq.c47
-rw-r--r--drivers/infiniband/hw/mthca/mthca_dev.h28
-rw-r--r--drivers/infiniband/hw/mthca/mthca_eq.c25
-rw-r--r--drivers/infiniband/hw/mthca/mthca_mad.c75
-rw-r--r--drivers/infiniband/hw/mthca/mthca_main.c14
-rw-r--r--drivers/infiniband/hw/mthca/mthca_mcg.c13
-rw-r--r--drivers/infiniband/hw/mthca/mthca_memfree.c5
-rw-r--r--drivers/infiniband/hw/mthca/mthca_memfree.h5
-rw-r--r--drivers/infiniband/hw/mthca/mthca_mr.c4
-rw-r--r--drivers/infiniband/hw/mthca/mthca_profile.c6
-rw-r--r--drivers/infiniband/hw/mthca/mthca_provider.c54
-rw-r--r--drivers/infiniband/hw/mthca/mthca_provider.h1
-rw-r--r--drivers/infiniband/hw/mthca/mthca_qp.c138
-rw-r--r--drivers/infiniband/hw/mthca/mthca_reset.c1
-rw-r--r--drivers/infiniband/hw/mthca/mthca_srq.c81
-rw-r--r--drivers/infiniband/hw/mthca/mthca_uar.c2
-rw-r--r--drivers/infiniband/hw/mthca/mthca_user.h6
-rw-r--r--drivers/infiniband/hw/mthca/mthca_wqe.h3
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib.h41
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_fs.c177
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_ib.c133
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_main.c103
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_multicast.c34
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_verbs.c13
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_vlan.c7
-rw-r--r--drivers/infiniband/ulp/srp/Kbuild1
-rw-r--r--drivers/infiniband/ulp/srp/Kconfig11
-rw-r--r--drivers/infiniband/ulp/srp/ib_srp.c1699
-rw-r--r--drivers/infiniband/ulp/srp/ib_srp.h150
-rw-r--r--drivers/input/evdev.c20
-rw-r--r--drivers/input/gameport/gameport.c1
-rw-r--r--drivers/input/input.c456
-rw-r--r--drivers/input/joydev.c16
-rw-r--r--drivers/input/joystick/a3d.c1
-rw-r--r--drivers/input/joystick/adi.c94
-rw-r--r--drivers/input/joystick/amijoy.c85
-rw-r--r--drivers/input/joystick/analog.c97
-rw-r--r--drivers/input/joystick/cobra.c67
-rw-r--r--drivers/input/joystick/db9.c292
-rw-r--r--drivers/input/joystick/gamecon.c396
-rw-r--r--drivers/input/joystick/gf2k.c70
-rw-r--r--drivers/input/joystick/grip.c78
-rw-r--r--drivers/input/joystick/grip_mp.c150
-rw-r--r--drivers/input/joystick/guillemot.c52
-rw-r--r--drivers/input/joystick/iforce/iforce-main.c106
-rw-r--r--drivers/input/joystick/iforce/iforce-packets.c5
-rw-r--r--drivers/input/joystick/iforce/iforce-serio.c10
-rw-r--r--drivers/input/joystick/iforce/iforce-usb.c22
-rw-r--r--drivers/input/joystick/iforce/iforce.h2
-rw-r--r--drivers/input/joystick/interact.c54
-rw-r--r--drivers/input/joystick/joydump.c1
-rw-r--r--drivers/input/joystick/magellan.c71
-rw-r--r--drivers/input/joystick/sidewinder.c71
-rw-r--r--drivers/input/joystick/spaceball.c82
-rw-r--r--drivers/input/joystick/spaceorb.c78
-rw-r--r--drivers/input/joystick/stinger.c75
-rw-r--r--drivers/input/joystick/tmdc.c325
-rw-r--r--drivers/input/joystick/turbografx.c215
-rw-r--r--drivers/input/joystick/twidjoy.c120
-rw-r--r--drivers/input/joystick/warrior.c83
-rw-r--r--drivers/input/keyboard/Kconfig4
-rw-r--r--drivers/input/keyboard/amikbd.c59
-rw-r--r--drivers/input/keyboard/atkbd.c188
-rw-r--r--drivers/input/keyboard/corgikbd.c98
-rw-r--r--drivers/input/keyboard/hil_kbd.c28
-rw-r--r--drivers/input/keyboard/hilkbd.c8
-rw-r--r--drivers/input/keyboard/lkkbd.c225
-rw-r--r--drivers/input/keyboard/locomokbd.c63
-rw-r--r--drivers/input/keyboard/maple_keyb.c72
-rw-r--r--drivers/input/keyboard/newtonkbd.c83
-rw-r--r--drivers/input/keyboard/spitzkbd.c121
-rw-r--r--drivers/input/keyboard/sunkbd.c117
-rw-r--r--drivers/input/keyboard/xtkbd.c80
-rw-r--r--drivers/input/misc/Kconfig2
-rw-r--r--drivers/input/misc/m68kspkr.c36
-rw-r--r--drivers/input/misc/pcspkr.c30
-rw-r--r--drivers/input/misc/sparcspkr.c49
-rw-r--r--drivers/input/misc/uinput.c10
-rw-r--r--drivers/input/mouse/Kconfig2
-rw-r--r--drivers/input/mouse/alps.c63
-rw-r--r--drivers/input/mouse/alps.h2
-rw-r--r--drivers/input/mouse/amimouse.c49
-rw-r--r--drivers/input/mouse/hil_ptr.c33
-rw-r--r--drivers/input/mouse/inport.c96
-rw-r--r--drivers/input/mouse/lifebook.c16
-rw-r--r--drivers/input/mouse/logibm.c88
-rw-r--r--drivers/input/mouse/logips2pp.c23
-rw-r--r--drivers/input/mouse/maplemouse.c10
-rw-r--r--drivers/input/mouse/pc110pad.c64
-rw-r--r--drivers/input/mouse/psmouse-base.c99
-rw-r--r--drivers/input/mouse/psmouse.h2
-rw-r--r--drivers/input/mouse/rpcmouse.c43
-rw-r--r--drivers/input/mouse/sermouse.c82
-rw-r--r--drivers/input/mouse/synaptics.c6
-rw-r--r--drivers/input/mouse/vsxxxaa.c84
-rw-r--r--drivers/input/mousedev.c25
-rw-r--r--drivers/input/serio/ct82c710.c1
-rw-r--r--drivers/input/serio/gscps2.c17
-rw-r--r--drivers/input/serio/hil_mlc.c14
-rw-r--r--drivers/input/serio/hp_sdc.c8
-rw-r--r--drivers/input/serio/hp_sdc_mlc.c1
-rw-r--r--drivers/input/serio/i8042.c14
-rw-r--r--drivers/input/serio/maceps2.c2
-rw-r--r--drivers/input/serio/q40kbd.c1
-rw-r--r--drivers/input/serio/rpckbd.c1
-rw-r--r--drivers/input/touchscreen/corgi_ts.c129
-rw-r--r--drivers/input/touchscreen/elo.c89
-rw-r--r--drivers/input/touchscreen/gunze.c66
-rw-r--r--drivers/input/touchscreen/h3600_ts_input.c149
-rw-r--r--drivers/input/touchscreen/hp680_ts_input.c50
-rw-r--r--drivers/input/touchscreen/mk712.c80
-rw-r--r--drivers/input/touchscreen/mtouch.c64
-rw-r--r--drivers/input/tsdev.c19
-rw-r--r--drivers/isdn/capi/capi.c2
-rw-r--r--drivers/isdn/capi/capifs.c1
-rw-r--r--drivers/isdn/divert/divert_init.c1
-rw-r--r--drivers/isdn/divert/divert_procfs.c1
-rw-r--r--drivers/isdn/divert/isdn_divert.c1
-rw-r--r--drivers/isdn/hardware/avm/avm_cs.c5
-rw-r--r--drivers/isdn/hisax/avm_pci.c12
-rw-r--r--drivers/isdn/hisax/avma1_cs.c4
-rw-r--r--drivers/isdn/hisax/config.c9
-rw-r--r--drivers/isdn/hisax/hfc4s8s_l1.c10
-rw-r--r--drivers/isdn/hisax/hfc_2bds0.c18
-rw-r--r--drivers/isdn/hisax/hfc_2bs0.c12
-rw-r--r--drivers/isdn/hisax/hfc_usb.c292
-rw-r--r--drivers/isdn/hisax/hfc_usb.h6
-rw-r--r--drivers/isdn/hisax/hisax_fcpcipnp.c1
-rw-r--r--drivers/isdn/hisax/hscx.c12
-rw-r--r--drivers/isdn/hisax/icc.c12
-rw-r--r--drivers/isdn/hisax/ipacx.c12
-rw-r--r--drivers/isdn/hisax/isac.c15
-rw-r--r--drivers/isdn/hisax/isar.c6
-rw-r--r--drivers/isdn/hisax/jade.c12
-rw-r--r--drivers/isdn/hisax/netjet.c32
-rw-r--r--drivers/isdn/hisax/st5481_init.c1
-rw-r--r--drivers/isdn/hisax/st5481_usb.c12
-rw-r--r--drivers/isdn/hisax/w6692.c12
-rw-r--r--drivers/isdn/hysdn/hycapi.c1
-rw-r--r--drivers/isdn/hysdn/hysdn_init.c1
-rw-r--r--drivers/isdn/hysdn/hysdn_net.c1
-rw-r--r--drivers/isdn/hysdn/hysdn_procconf.c4
-rw-r--r--drivers/isdn/hysdn/hysdn_proclog.c1
-rw-r--r--drivers/isdn/i4l/isdn_common.c1
-rw-r--r--drivers/isdn/i4l/isdn_ppp.c21
-rw-r--r--drivers/isdn/i4l/isdn_tty.c27
-rw-r--r--drivers/isdn/icn/icn.c3
-rw-r--r--drivers/isdn/icn/icn.h1
-rw-r--r--drivers/isdn/isdnloop/isdnloop.c9
-rw-r--r--drivers/isdn/isdnloop/isdnloop.h1
-rw-r--r--drivers/isdn/pcbit/drv.c6
-rw-r--r--drivers/isdn/sc/includes.h1
-rw-r--r--drivers/isdn/sc/init.c3
-rw-r--r--drivers/isdn/sc/message.c3
-rw-r--r--drivers/macintosh/Kconfig19
-rw-r--r--drivers/macintosh/Makefile9
-rw-r--r--drivers/macintosh/adb.c2
-rw-r--r--drivers/macintosh/adbhid.c226
-rw-r--r--drivers/macintosh/ans-lcd.c10
-rw-r--r--drivers/macintosh/apm_emu.c8
-rw-r--r--drivers/macintosh/mac_hid.c40
-rw-r--r--drivers/macintosh/macio_asic.c2
-rw-r--r--drivers/macintosh/macio_sysfs.c26
-rw-r--r--drivers/macintosh/mediabay.c56
-rw-r--r--drivers/macintosh/smu.c178
-rw-r--r--drivers/macintosh/therm_pm72.c3
-rw-r--r--drivers/macintosh/via-cuda.c1
-rw-r--r--drivers/macintosh/via-pmu.c181
-rw-r--r--drivers/macintosh/via-pmu68k.c15
-rw-r--r--drivers/macintosh/windfarm.h131
-rw-r--r--drivers/macintosh/windfarm_core.c426
-rw-r--r--drivers/macintosh/windfarm_cpufreq_clamp.c105
-rw-r--r--drivers/macintosh/windfarm_lm75_sensor.c263
-rw-r--r--drivers/macintosh/windfarm_pid.c145
-rw-r--r--drivers/macintosh/windfarm_pid.h84
-rw-r--r--drivers/macintosh/windfarm_pm81.c879
-rw-r--r--drivers/macintosh/windfarm_pm91.c814
-rw-r--r--drivers/macintosh/windfarm_smu_controls.c282
-rw-r--r--drivers/macintosh/windfarm_smu_sensors.c479
-rw-r--r--drivers/mca/mca-device.c1
-rw-r--r--drivers/md/bitmap.c36
-rw-r--r--drivers/md/dm-crypt.c14
-rw-r--r--drivers/md/linear.c10
-rw-r--r--drivers/md/md.c640
-rw-r--r--drivers/md/multipath.c41
-rw-r--r--drivers/md/raid0.c10
-rw-r--r--drivers/md/raid1.c228
-rw-r--r--drivers/md/raid10.c75
-rw-r--r--drivers/md/raid5.c274
-rw-r--r--drivers/md/raid6main.c55
-rw-r--r--drivers/media/common/ir-common.c6
-rw-r--r--drivers/media/dvb/b2c2/flexcop-fe-tuner.c54
-rw-r--r--drivers/media/dvb/b2c2/flexcop-misc.c1
-rw-r--r--drivers/media/dvb/b2c2/flexcop-reg.h1
-rw-r--r--drivers/media/dvb/b2c2/flexcop.c1
-rw-r--r--drivers/media/dvb/bt8xx/Kconfig4
-rw-r--r--drivers/media/dvb/bt8xx/dst.c144
-rw-r--r--drivers/media/dvb/bt8xx/dst_ca.c123
-rw-r--r--drivers/media/dvb/bt8xx/dst_common.h5
-rw-r--r--drivers/media/dvb/bt8xx/dvb-bt8xx.c114
-rw-r--r--drivers/media/dvb/bt8xx/dvb-bt8xx.h1
-rw-r--r--drivers/media/dvb/cinergyT2/cinergyT2.c108
-rw-r--r--drivers/media/dvb/dvb-core/demux.h5
-rw-r--r--drivers/media/dvb/dvb-core/dvb_ca_en50221.c1
-rw-r--r--drivers/media/dvb/dvb-core/dvb_demux.c2
-rw-r--r--drivers/media/dvb/dvb-core/dvb_frontend.c118
-rw-r--r--drivers/media/dvb/dvb-core/dvb_frontend.h3
-rw-r--r--drivers/media/dvb/dvb-core/dvbdev.c2
-rw-r--r--drivers/media/dvb/dvb-usb/a800.c4
-rw-r--r--drivers/media/dvb/dvb-usb/dibusb-mb.c59
-rw-r--r--drivers/media/dvb/dvb-usb/dibusb.h4
-rw-r--r--drivers/media/dvb/dvb-usb/dtt200u.c4
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-ids.h5
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-remote.c50
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-urb.c4
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb.h3
-rw-r--r--drivers/media/dvb/dvb-usb/vp7045.c2
-rw-r--r--drivers/media/dvb/frontends/Kconfig8
-rw-r--r--drivers/media/dvb/frontends/Makefile1
-rw-r--r--drivers/media/dvb/frontends/bcm3510.c3
-rw-r--r--drivers/media/dvb/frontends/cx24110.c1
-rw-r--r--drivers/media/dvb/frontends/dib3000mb.c2
-rw-r--r--drivers/media/dvb/frontends/dib3000mc.c2
-rw-r--r--drivers/media/dvb/frontends/dvb-pll.c54
-rw-r--r--drivers/media/dvb/frontends/dvb-pll.h4
-rw-r--r--drivers/media/dvb/frontends/dvb_dummy_fe.c6
-rw-r--r--drivers/media/dvb/frontends/l64781.c3
-rw-r--r--drivers/media/dvb/frontends/lgdt330x.c31
-rw-r--r--drivers/media/dvb/frontends/lgdt330x.h4
-rw-r--r--drivers/media/dvb/frontends/mt312.c5
-rw-r--r--drivers/media/dvb/frontends/mt352.c2
-rw-r--r--drivers/media/dvb/frontends/nxt2002.c2
-rw-r--r--drivers/media/dvb/frontends/nxt200x.c1205
-rw-r--r--drivers/media/dvb/frontends/nxt200x.h61
-rw-r--r--drivers/media/dvb/frontends/or51132.c12
-rw-r--r--drivers/media/dvb/frontends/or51211.c10
-rw-r--r--drivers/media/dvb/frontends/s5h1420.c2
-rw-r--r--drivers/media/dvb/frontends/sp8870.c2
-rw-r--r--drivers/media/dvb/frontends/sp887x.c2
-rw-r--r--drivers/media/dvb/frontends/stv0297.c2
-rw-r--r--drivers/media/dvb/frontends/stv0299.c101
-rw-r--r--drivers/media/dvb/frontends/stv0299.h3
-rw-r--r--drivers/media/dvb/frontends/tda1004x.c25
-rw-r--r--drivers/media/dvb/frontends/tda8083.c1
-rw-r--r--drivers/media/dvb/pluto2/pluto2.c9
-rw-r--r--drivers/media/dvb/ttpci/av7110.c6
-rw-r--r--drivers/media/dvb/ttpci/av7110_ir.c37
-rw-r--r--drivers/media/dvb/ttpci/budget-av.c4
-rw-r--r--drivers/media/dvb/ttpci/budget-ci.c28
-rw-r--r--drivers/media/dvb/ttpci/budget-patch.c3
-rw-r--r--drivers/media/dvb/ttpci/budget.c120
-rw-r--r--drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c5
-rw-r--r--drivers/media/dvb/ttusb-dec/ttusb_dec.c51
-rw-r--r--drivers/media/radio/miropcm20-rds.c1
-rw-r--r--drivers/media/video/Kconfig63
-rw-r--r--drivers/media/video/Makefile5
-rw-r--r--drivers/media/video/arv.c13
-rw-r--r--drivers/media/video/bt832.c89
-rw-r--r--drivers/media/video/bt832.h4
-rw-r--r--drivers/media/video/bttv-cards.c5307
-rw-r--r--drivers/media/video/bttv-driver.c385
-rw-r--r--drivers/media/video/bttv-gpio.c2
-rw-r--r--drivers/media/video/bttv-i2c.c61
-rw-r--r--drivers/media/video/bttv-if.c4
-rw-r--r--drivers/media/video/bttv-risc.c110
-rw-r--r--drivers/media/video/bttv.h282
-rw-r--r--drivers/media/video/bttvp.h16
-rw-r--r--drivers/media/video/cs53l32a.c240
-rw-r--r--drivers/media/video/cx88/Kconfig91
-rw-r--r--drivers/media/video/cx88/Makefile6
-rw-r--r--drivers/media/video/cx88/cx88-blackbird.c677
-rw-r--r--drivers/media/video/cx88/cx88-cards.c474
-rw-r--r--drivers/media/video/cx88/cx88-core.c55
-rw-r--r--drivers/media/video/cx88/cx88-dvb.c59
-rw-r--r--drivers/media/video/cx88/cx88-i2c.c22
-rw-r--r--drivers/media/video/cx88/cx88-input.c60
-rw-r--r--drivers/media/video/cx88/cx88-mpeg.c25
-rw-r--r--drivers/media/video/cx88/cx88-reg.h12
-rw-r--r--drivers/media/video/cx88/cx88-tvaudio.c1184
-rw-r--r--drivers/media/video/cx88/cx88-video.c38
-rw-r--r--drivers/media/video/cx88/cx88.h55
-rw-r--r--drivers/media/video/em28xx/Kconfig12
-rw-r--r--drivers/media/video/em28xx/Makefile6
-rw-r--r--drivers/media/video/em28xx/em28xx-cards.c292
-rw-r--r--drivers/media/video/em28xx/em28xx-core.c817
-rw-r--r--drivers/media/video/em28xx/em28xx-i2c.c586
-rw-r--r--drivers/media/video/em28xx/em28xx-input.c184
-rw-r--r--drivers/media/video/em28xx/em28xx-video.c1933
-rw-r--r--drivers/media/video/em28xx/em28xx.h513
-rw-r--r--drivers/media/video/indycam.c272
-rw-r--r--drivers/media/video/indycam.h88
-rw-r--r--drivers/media/video/ir-kbd-gpio.c151
-rw-r--r--drivers/media/video/ir-kbd-i2c.c195
-rw-r--r--drivers/media/video/msp3400.c974
-rw-r--r--drivers/media/video/mt20xx.c206
-rw-r--r--drivers/media/video/saa6588.c11
-rw-r--r--drivers/media/video/saa711x.c593
-rw-r--r--drivers/media/video/saa7134/Kconfig68
-rw-r--r--drivers/media/video/saa7134/Makefile9
-rw-r--r--drivers/media/video/saa7134/saa6752hs.c187
-rw-r--r--drivers/media/video/saa7134/saa7134-alsa.c1047
-rw-r--r--drivers/media/video/saa7134/saa7134-cards.c587
-rw-r--r--drivers/media/video/saa7134/saa7134-core.c120
-rw-r--r--drivers/media/video/saa7134/saa7134-dvb.c370
-rw-r--r--drivers/media/video/saa7134/saa7134-empress.c6
-rw-r--r--drivers/media/video/saa7134/saa7134-i2c.c28
-rw-r--r--drivers/media/video/saa7134/saa7134-input.c442
-rw-r--r--drivers/media/video/saa7134/saa7134-oss.c375
-rw-r--r--drivers/media/video/saa7134/saa7134-reg.h27
-rw-r--r--drivers/media/video/saa7134/saa7134-ts.c29
-rw-r--r--drivers/media/video/saa7134/saa7134-tvaudio.c27
-rw-r--r--drivers/media/video/saa7134/saa7134-video.c185
-rw-r--r--drivers/media/video/saa7134/saa7134.h64
-rw-r--r--drivers/media/video/saa7191.c545
-rw-r--r--drivers/media/video/saa7191.h172
-rw-r--r--drivers/media/video/tda7432.c17
-rw-r--r--drivers/media/video/tda8290.c681
-rw-r--r--drivers/media/video/tda9875.c57
-rw-r--r--drivers/media/video/tda9887.c167
-rw-r--r--drivers/media/video/tea5767.c8
-rw-r--r--drivers/media/video/tuner-core.c78
-rw-r--r--drivers/media/video/tuner-simple.c143
-rw-r--r--drivers/media/video/tvaudio.c23
-rw-r--r--drivers/media/video/tveeprom.c458
-rw-r--r--drivers/media/video/tvmixer.c54
-rw-r--r--drivers/media/video/tvp5150.c829
-rw-r--r--drivers/media/video/tvp5150_reg.h173
-rw-r--r--drivers/media/video/v4l1-compat.c12
-rw-r--r--drivers/media/video/video-buf.c18
-rw-r--r--drivers/media/video/videocodec.c6
-rw-r--r--drivers/media/video/videodev.c3
-rw-r--r--drivers/media/video/vino.c1177
-rw-r--r--drivers/media/video/wm8775.c254
-rw-r--r--drivers/media/video/zoran_card.c14
-rw-r--r--drivers/media/video/zoran_driver.c4
-rw-r--r--drivers/media/video/zr36016.c1
-rw-r--r--drivers/media/video/zr36050.c1
-rw-r--r--drivers/media/video/zr36060.c1
-rw-r--r--drivers/message/fusion/mptbase.c7
-rw-r--r--drivers/message/fusion/mptbase.h19
-rw-r--r--drivers/message/fusion/mptctl.c1
-rw-r--r--drivers/message/fusion/mptctl.h1
-rw-r--r--drivers/message/fusion/mptlan.c10
-rw-r--r--drivers/message/fusion/mptlan.h1
-rw-r--r--drivers/message/fusion/mptsas.c323
-rw-r--r--drivers/message/fusion/mptscsih.c6
-rw-r--r--drivers/message/i2o/core.h3
-rw-r--r--drivers/message/i2o/debug.c2
-rw-r--r--drivers/message/i2o/device.c274
-rw-r--r--drivers/message/i2o/driver.c6
-rw-r--r--drivers/message/i2o/exec-osm.c5
-rw-r--r--drivers/message/i2o/iop.c48
-rw-r--r--drivers/mfd/mcp-core.c2
-rw-r--r--drivers/mfd/mcp-sa11x0.c22
-rw-r--r--drivers/mfd/ucb1x00-ts.c117
-rw-r--r--drivers/misc/hdpuftrs/hdpu_cpustate.c3
-rw-r--r--drivers/misc/hdpuftrs/hdpu_nexus.c3
-rw-r--r--drivers/misc/ibmasm/ibmasm.h1
-rw-r--r--drivers/mmc/Kconfig9
-rw-r--r--drivers/mmc/Makefile1
-rw-r--r--drivers/mmc/au1xmmc.c1026
-rw-r--r--drivers/mmc/au1xmmc.h96
-rw-r--r--drivers/mmc/mmc.c2
-rw-r--r--drivers/mmc/mmc_block.c11
-rw-r--r--drivers/mmc/mmci.c1
-rw-r--r--drivers/mmc/pxamci.c11
-rw-r--r--drivers/mmc/wbsd.c143
-rw-r--r--drivers/mtd/Kconfig40
-rw-r--r--drivers/mtd/Makefile5
-rw-r--r--drivers/mtd/afs.c16
-rw-r--r--drivers/mtd/chips/Kconfig22
-rw-r--r--drivers/mtd/chips/Makefile4
-rw-r--r--drivers/mtd/chips/amd_flash.c80
-rw-r--r--drivers/mtd/chips/cfi_cmdset_0001.c487
-rw-r--r--drivers/mtd/chips/cfi_cmdset_0002.c160
-rw-r--r--drivers/mtd/chips/cfi_cmdset_0020.c184
-rw-r--r--drivers/mtd/chips/cfi_probe.c98
-rw-r--r--drivers/mtd/chips/cfi_util.c25
-rw-r--r--drivers/mtd/chips/chipreg.c6
-rw-r--r--drivers/mtd/chips/fwh_lock.h6
-rw-r--r--drivers/mtd/chips/gen_probe.c33
-rw-r--r--drivers/mtd/chips/jedec.c207
-rw-r--r--drivers/mtd/chips/jedec_probe.c48
-rw-r--r--drivers/mtd/chips/map_absent.c8
-rw-r--r--drivers/mtd/chips/sharp.c23
-rw-r--r--drivers/mtd/cmdlinepart.c56
-rw-r--r--drivers/mtd/devices/Kconfig8
-rw-r--r--drivers/mtd/devices/blkmtd.c17
-rw-r--r--drivers/mtd/devices/block2mtd.c8
-rw-r--r--drivers/mtd/devices/doc2000.c42
-rw-r--r--drivers/mtd/devices/doc2001.c24
-rw-r--r--drivers/mtd/devices/doc2001plus.c20
-rw-r--r--drivers/mtd/devices/docecc.c40
-rw-r--r--drivers/mtd/devices/docprobe.c84
-rw-r--r--drivers/mtd/devices/lart.c9
-rw-r--r--drivers/mtd/devices/phram.c15
-rw-r--r--drivers/mtd/devices/pmc551.c25
-rw-r--r--drivers/mtd/devices/slram.c30
-rw-r--r--drivers/mtd/ftl.c128
-rw-r--r--drivers/mtd/inftlcore.c60
-rw-r--r--drivers/mtd/inftlmount.c26
-rw-r--r--drivers/mtd/maps/Kconfig115
-rw-r--r--drivers/mtd/maps/Makefile7
-rw-r--r--drivers/mtd/maps/alchemy-flash.c12
-rw-r--r--drivers/mtd/maps/amd76xrom.c20
-rw-r--r--drivers/mtd/maps/arctic-mtd.c6
-rw-r--r--drivers/mtd/maps/autcpu12-nvram.c18
-rw-r--r--drivers/mtd/maps/bast-flash.c25
-rw-r--r--drivers/mtd/maps/beech-mtd.c6
-rw-r--r--drivers/mtd/maps/cdb89712.c34
-rw-r--r--drivers/mtd/maps/ceiva.c4
-rw-r--r--drivers/mtd/maps/cfi_flagadm.c12
-rw-r--r--drivers/mtd/maps/cstm_mips_ixx.c24
-rw-r--r--drivers/mtd/maps/dbox2-flash.c38
-rw-r--r--drivers/mtd/maps/dc21285.c35
-rw-r--r--drivers/mtd/maps/dilnetpc.c37
-rw-r--r--drivers/mtd/maps/dmv182.c8
-rw-r--r--drivers/mtd/maps/ebony.c7
-rw-r--r--drivers/mtd/maps/edb7312.c10
-rw-r--r--drivers/mtd/maps/epxa10db-flash.c17
-rw-r--r--drivers/mtd/maps/fortunet.c9
-rw-r--r--drivers/mtd/maps/h720x-flash.c16
-rw-r--r--drivers/mtd/maps/ichxrom.c21
-rw-r--r--drivers/mtd/maps/impa7.c16
-rw-r--r--drivers/mtd/maps/integrator-flash.c22
-rw-r--r--drivers/mtd/maps/ipaq-flash.c37
-rw-r--r--drivers/mtd/maps/iq80310.c7
-rw-r--r--drivers/mtd/maps/ixp2000.c42
-rw-r--r--drivers/mtd/maps/ixp4xx.c64
-rw-r--r--drivers/mtd/maps/l440gx.c18
-rw-r--r--drivers/mtd/maps/lubbock-flash.c20
-rw-r--r--drivers/mtd/maps/mainstone-flash.c25
-rw-r--r--drivers/mtd/maps/mbx860.c6
-rw-r--r--drivers/mtd/maps/mtx-1_flash.c96
-rw-r--r--drivers/mtd/maps/netsc520.c32
-rw-r--r--drivers/mtd/maps/nettel.c8
-rw-r--r--drivers/mtd/maps/ocelot.c10
-rw-r--r--drivers/mtd/maps/ocotea.c1
-rw-r--r--drivers/mtd/maps/octagon-5066.c36
-rw-r--r--drivers/mtd/maps/omap-toto-flash.c25
-rw-r--r--drivers/mtd/maps/omap_nor.c6
-rw-r--r--drivers/mtd/maps/pci.c7
-rw-r--r--drivers/mtd/maps/pcmciamtd.c30
-rw-r--r--drivers/mtd/maps/physmap.c8
-rw-r--r--drivers/mtd/maps/plat-ram.c15
-rw-r--r--drivers/mtd/maps/pnc2000.c8
-rw-r--r--drivers/mtd/maps/pq2fads.c88
-rw-r--r--drivers/mtd/maps/redwood.c4
-rw-r--r--drivers/mtd/maps/sa1100-flash.c86
-rw-r--r--drivers/mtd/maps/sbc8240.c4
-rw-r--r--drivers/mtd/maps/sbc_gxx.c46
-rw-r--r--drivers/mtd/maps/sc520cdp.c6
-rw-r--r--drivers/mtd/maps/scx200_docflash.c46
-rw-r--r--drivers/mtd/maps/sharpsl-flash.c12
-rw-r--r--drivers/mtd/maps/solutionengine.c4
-rw-r--r--drivers/mtd/maps/sun_uflash.c16
-rw-r--r--drivers/mtd/maps/tqm834x.c291
-rw-r--r--drivers/mtd/maps/tqm8xxl.c30
-rw-r--r--drivers/mtd/maps/ts5500_flash.c44
-rw-r--r--drivers/mtd/maps/tsunami_flash.c6
-rw-r--r--drivers/mtd/maps/uclinux.c4
-rw-r--r--drivers/mtd/maps/vmax301.c24
-rw-r--r--drivers/mtd/maps/walnut.c17
-rw-r--r--drivers/mtd/maps/wr_sbc82xx_flash.c6
-rw-r--r--drivers/mtd/mtd_blkdevs.c44
-rw-r--r--drivers/mtd/mtdblock.c52
-rw-r--r--drivers/mtd/mtdchar.c89
-rw-r--r--drivers/mtd/mtdconcat.c11
-rw-r--r--drivers/mtd/mtdcore.c62
-rw-r--r--drivers/mtd/mtdpart.c99
-rw-r--r--drivers/mtd/nand/Kconfig26
-rw-r--r--drivers/mtd/nand/au1550nd.c166
-rw-r--r--drivers/mtd/nand/autcpu12.c23
-rw-r--r--drivers/mtd/nand/diskonchip.c100
-rw-r--r--drivers/mtd/nand/edb7312.c48
-rw-r--r--drivers/mtd/nand/h1910.c48
-rw-r--r--drivers/mtd/nand/nand_base.c534
-rw-r--r--drivers/mtd/nand/nand_bbt.c248
-rw-r--r--drivers/mtd/nand/nand_ecc.c44
-rw-r--r--drivers/mtd/nand/nand_ids.c30
-rw-r--r--drivers/mtd/nand/nandsim.c162
-rw-r--r--drivers/mtd/nand/ppchameleonevb.c6
-rw-r--r--drivers/mtd/nand/rtc_from4.c58
-rw-r--r--drivers/mtd/nand/s3c2410.c64
-rw-r--r--drivers/mtd/nand/sharpsl.c41
-rw-r--r--drivers/mtd/nand/spia.c6
-rw-r--r--drivers/mtd/nand/toto.c20
-rw-r--r--drivers/mtd/nftlcore.c92
-rw-r--r--drivers/mtd/nftlmount.c56
-rw-r--r--drivers/mtd/onenand/Kconfig38
-rw-r--r--drivers/mtd/onenand/Makefile11
-rw-r--r--drivers/mtd/onenand/generic.c147
-rw-r--r--drivers/mtd/onenand/onenand_base.c1590
-rw-r--r--drivers/mtd/onenand/onenand_bbt.c246
-rw-r--r--drivers/mtd/redboot.c4
-rw-r--r--drivers/mtd/rfd_ftl.c856
-rw-r--r--drivers/net/3c59x.c586
-rw-r--r--drivers/net/8139cp.c5
-rw-r--r--drivers/net/8139too.c5
-rw-r--r--drivers/net/Kconfig126
-rw-r--r--drivers/net/Makefile8
-rw-r--r--drivers/net/acenic.c6
-rw-r--r--[-rwxr-xr-x]drivers/net/amd8111e.c0
-rw-r--r--[-rwxr-xr-x]drivers/net/amd8111e.h0
-rw-r--r--drivers/net/arm/am79c961a.c42
-rw-r--r--drivers/net/arm/am79c961a.h2
-rw-r--r--drivers/net/au1000_eth.c19
-rw-r--r--drivers/net/b44.c334
-rw-r--r--drivers/net/b44.h77
-rw-r--r--drivers/net/bmac.c7
-rw-r--r--drivers/net/bnx2.c496
-rw-r--r--drivers/net/bnx2.h119
-rw-r--r--drivers/net/bnx2_fw.h4053
-rw-r--r--drivers/net/bonding/bond_main.c89
-rw-r--r--drivers/net/bonding/bonding.h7
-rw-r--r--drivers/net/cassini.c5
-rw-r--r--drivers/net/cris/eth_v10.c149
-rw-r--r--drivers/net/declance.c37
-rw-r--r--drivers/net/depca.c26
-rw-r--r--drivers/net/dgrs.c16
-rw-r--r--drivers/net/dm9000.c10
-rw-r--r--drivers/net/e100.c10
-rw-r--r--drivers/net/e1000/e1000.h74
-rw-r--r--drivers/net/e1000/e1000_ethtool.c104
-rw-r--r--drivers/net/e1000/e1000_hw.c321
-rw-r--r--drivers/net/e1000/e1000_hw.h138
-rw-r--r--drivers/net/e1000/e1000_main.c1102
-rw-r--r--drivers/net/e1000/e1000_param.c10
-rw-r--r--drivers/net/eepro.c57
-rw-r--r--drivers/net/epic100.c4
-rw-r--r--drivers/net/fec.c240
-rw-r--r--drivers/net/fec.h10
-rw-r--r--drivers/net/fec_8xx/Kconfig8
-rw-r--r--drivers/net/fec_8xx/fec_mii.c42
-rw-r--r--drivers/net/forcedeth.c310
-rw-r--r--drivers/net/fs_enet/Kconfig20
-rw-r--r--drivers/net/fs_enet/Makefile10
-rw-r--r--drivers/net/fs_enet/fs_enet-main.c1230
-rw-r--r--drivers/net/fs_enet/fs_enet-mii.c507
-rw-r--r--drivers/net/fs_enet/fs_enet.h244
-rw-r--r--drivers/net/fs_enet/mac-fcc.c579
-rw-r--r--drivers/net/fs_enet/mac-fec.c654
-rw-r--r--drivers/net/fs_enet/mac-scc.c525
-rw-r--r--drivers/net/fs_enet/mii-bitbang.c405
-rw-r--r--drivers/net/fs_enet/mii-fixed.c92
-rw-r--r--drivers/net/gianfar.c415
-rw-r--r--drivers/net/gianfar.h31
-rw-r--r--drivers/net/gianfar_ethtool.c101
-rw-r--r--drivers/net/gianfar_mii.c219
-rw-r--r--drivers/net/gianfar_mii.h45
-rw-r--r--drivers/net/gianfar_phy.c661
-rw-r--r--drivers/net/gianfar_phy.h213
-rw-r--r--drivers/net/hamradio/Kconfig1
-rw-r--r--drivers/net/hamradio/bpqether.c9
-rw-r--r--drivers/net/hamradio/dmascc.c10
-rw-r--r--drivers/net/hamradio/mkiss.c188
-rw-r--r--drivers/net/hamradio/mkiss.h62
-rw-r--r--drivers/net/hp100.c49
-rw-r--r--drivers/net/ibm_emac/Makefile13
-rw-r--r--drivers/net/ibm_emac/ibm_emac.h428
-rw-r--r--drivers/net/ibm_emac/ibm_emac_core.c3400
-rw-r--r--drivers/net/ibm_emac/ibm_emac_core.h313
-rw-r--r--drivers/net/ibm_emac/ibm_emac_debug.c363
-rw-r--r--drivers/net/ibm_emac/ibm_emac_debug.h63
-rw-r--r--drivers/net/ibm_emac/ibm_emac_mal.c674
-rw-r--r--drivers/net/ibm_emac/ibm_emac_mal.h333
-rw-r--r--drivers/net/ibm_emac/ibm_emac_phy.c347
-rw-r--r--drivers/net/ibm_emac/ibm_emac_phy.h105
-rw-r--r--drivers/net/ibm_emac/ibm_emac_rgmii.c201
-rw-r--r--drivers/net/ibm_emac/ibm_emac_rgmii.h60
-rw-r--r--drivers/net/ibm_emac/ibm_emac_tah.c111
-rw-r--r--drivers/net/ibm_emac/ibm_emac_tah.h96
-rw-r--r--drivers/net/ibm_emac/ibm_emac_zmii.c255
-rw-r--r--drivers/net/ibm_emac/ibm_emac_zmii.h104
-rw-r--r--drivers/net/ibmveth.c203
-rw-r--r--drivers/net/ibmveth.h23
-rw-r--r--drivers/net/ioc3-eth.c42
-rw-r--r--drivers/net/irda/Kconfig10
-rw-r--r--drivers/net/irda/Makefile1
-rw-r--r--drivers/net/irda/donauboe.c20
-rw-r--r--drivers/net/irda/irda-usb.c6
-rw-r--r--drivers/net/irda/irport.c3
-rw-r--r--drivers/net/irda/pxaficp_ir.c866
-rw-r--r--drivers/net/irda/sa1100_ir.c10
-rw-r--r--drivers/net/irda/sir_dev.c3
-rw-r--r--drivers/net/irda/smsc-ircc2.c140
-rw-r--r--drivers/net/irda/stir4200.c7
-rw-r--r--drivers/net/irda/vlsi_ir.c3
-rw-r--r--drivers/net/iseries_veth.c27
-rw-r--r--drivers/net/ixgb/ixgb_ethtool.c10
-rw-r--r--drivers/net/ixgb/ixgb_hw.c31
-rw-r--r--drivers/net/ixgb/ixgb_hw.h17
-rw-r--r--drivers/net/ixgb/ixgb_main.c5
-rw-r--r--drivers/net/jazzsonic.c30
-rw-r--r--drivers/net/lance.c4
-rw-r--r--drivers/net/lasi_82596.c30
-rw-r--r--drivers/net/lne390.c2
-rw-r--r--drivers/net/mac8390.c1
-rw-r--r--drivers/net/mace.c7
-rw-r--r--drivers/net/macsonic.c29
-rw-r--r--drivers/net/mii.c15
-rw-r--r--drivers/net/mipsnet.c372
-rw-r--r--drivers/net/mipsnet.h127
-rw-r--r--drivers/net/mv643xx_eth.c5
-rw-r--r--drivers/net/mv643xx_eth.h1
-rw-r--r--drivers/net/myri_sbus.c2
-rw-r--r--drivers/net/myri_sbus.h2
-rw-r--r--drivers/net/ne.c15
-rw-r--r--drivers/net/ne2k-pci.c3
-rw-r--r--drivers/net/ni65.c9
-rw-r--r--drivers/net/ns83820.c16
-rw-r--r--drivers/net/pcmcia/pcnet_cs.c6
-rw-r--r--drivers/net/pcnet32.c323
-rw-r--r--drivers/net/phy/Kconfig8
-rw-r--r--drivers/net/phy/cicada.c1
-rw-r--r--drivers/net/phy/davicom.c1
-rw-r--r--drivers/net/phy/lxt.c1
-rw-r--r--drivers/net/phy/marvell.c1
-rw-r--r--drivers/net/phy/mdio_bus.c24
-rw-r--r--drivers/net/phy/phy.c9
-rw-r--r--drivers/net/phy/phy_device.c4
-rw-r--r--drivers/net/phy/qsemi.c1
-rw-r--r--drivers/net/ppp_async.c17
-rw-r--r--drivers/net/ppp_generic.c90
-rw-r--r--drivers/net/ppp_mppe.c724
-rw-r--r--drivers/net/ppp_mppe.h86
-rw-r--r--drivers/net/r8169.c2
-rw-r--r--drivers/net/rionet.c574
-rw-r--r--drivers/net/rrunner.c6
-rw-r--r--drivers/net/s2io-regs.h11
-rw-r--r--drivers/net/s2io.c1582
-rw-r--r--drivers/net/s2io.h141
-rw-r--r--drivers/net/saa9730.c8
-rw-r--r--drivers/net/sb1250-mac.c1384
-rw-r--r--drivers/net/sgiseeq.c37
-rw-r--r--drivers/net/sis190.c2
-rw-r--r--drivers/net/sis900.c16
-rw-r--r--drivers/net/sk98lin/h/skdrv1st.h3
-rw-r--r--drivers/net/sk_mca.c1
-rw-r--r--drivers/net/sk_mca.h2
-rw-r--r--drivers/net/skfp/smt.c2
-rw-r--r--drivers/net/skge.c269
-rw-r--r--drivers/net/skge.h2
-rw-r--r--drivers/net/smc91x.c14
-rw-r--r--drivers/net/smc91x.h12
-rw-r--r--drivers/net/spider_net.c1
-rw-r--r--drivers/net/starfire.c5
-rw-r--r--drivers/net/sunbmac.c3
-rw-r--r--drivers/net/sunbmac.h2
-rw-r--r--drivers/net/sundance.c111
-rw-r--r--drivers/net/tg3.c91
-rw-r--r--drivers/net/tg3.h12
-rw-r--r--drivers/net/tokenring/ibmtr.c9
-rw-r--r--drivers/net/tokenring/olympic.c2
-rw-r--r--drivers/net/tokenring/proteon.c1
-rw-r--r--drivers/net/tokenring/skisa.c1
-rw-r--r--drivers/net/tokenring/tms380tr.c3
-rw-r--r--drivers/net/tulip/de2104x.c11
-rw-r--r--drivers/net/tulip/tulip_core.c6
-rw-r--r--drivers/net/typhoon.c7
-rw-r--r--drivers/net/via-rhine.c38
-rw-r--r--drivers/net/via-velocity.c7
-rw-r--r--drivers/net/wan/cosa.c8
-rw-r--r--drivers/net/wan/cycx_drv.c7
-rw-r--r--drivers/net/wan/cycx_main.c2
-rw-r--r--drivers/net/wan/cycx_x25.c5
-rw-r--r--drivers/net/wan/dscc4.c23
-rw-r--r--drivers/net/wan/farsync.c27
-rw-r--r--drivers/net/wan/hdlc_fr.c2
-rw-r--r--drivers/net/wan/lmc/lmc_debug.c10
-rw-r--r--drivers/net/wan/lmc/lmc_media.c8
-rw-r--r--drivers/net/wan/pc300.h16
-rw-r--r--drivers/net/wan/pc300_drv.c87
-rw-r--r--drivers/net/wan/pc300_tty.c18
-rw-r--r--drivers/net/wan/sdla.c20
-rw-r--r--drivers/net/wan/sdla_fr.c4
-rw-r--r--drivers/net/wan/sdla_x25.c8
-rw-r--r--drivers/net/wan/sdladrv.c16
-rw-r--r--drivers/net/wan/syncppp.c10
-rw-r--r--drivers/net/wireless/airo.c132
-rw-r--r--drivers/net/wireless/airo.h9
-rw-r--r--drivers/net/wireless/airo_cs.c16
-rw-r--r--drivers/net/wireless/airport.c19
-rw-r--r--drivers/net/wireless/atmel.c32
-rw-r--r--drivers/net/wireless/atmel_cs.c9
-rw-r--r--drivers/net/wireless/hermes.c49
-rw-r--r--drivers/net/wireless/hermes.h113
-rw-r--r--drivers/net/wireless/hostap/hostap.c7
-rw-r--r--drivers/net/wireless/hostap/hostap_80211_rx.c43
-rw-r--r--drivers/net/wireless/hostap/hostap_80211_tx.c28
-rw-r--r--drivers/net/wireless/hostap/hostap_ap.c80
-rw-r--r--drivers/net/wireless/hostap/hostap_ap.h6
-rw-r--r--drivers/net/wireless/hostap/hostap_cs.c50
-rw-r--r--drivers/net/wireless/hostap/hostap_hw.c23
-rw-r--r--drivers/net/wireless/hostap/hostap_ioctl.c32
-rw-r--r--drivers/net/wireless/hostap/hostap_pci.c22
-rw-r--r--drivers/net/wireless/hostap/hostap_plx.c12
-rw-r--r--drivers/net/wireless/hostap/hostap_wlan.h2
-rw-r--r--drivers/net/wireless/ipw2100.c2882
-rw-r--r--drivers/net/wireless/ipw2100.h172
-rw-r--r--drivers/net/wireless/ipw2200.c6637
-rw-r--r--drivers/net/wireless/ipw2200.h579
-rw-r--r--drivers/net/wireless/netwave_cs.c185
-rw-r--r--drivers/net/wireless/orinoco.c248
-rw-r--r--drivers/net/wireless/orinoco.h17
-rw-r--r--drivers/net/wireless/orinoco_cs.c110
-rw-r--r--drivers/net/wireless/orinoco_nortel.c20
-rw-r--r--drivers/net/wireless/orinoco_pci.c18
-rw-r--r--drivers/net/wireless/orinoco_plx.c18
-rw-r--r--drivers/net/wireless/orinoco_tmd.c18
-rw-r--r--drivers/net/wireless/prism54/isl_38xx.c13
-rw-r--r--drivers/net/wireless/prism54/isl_38xx.h1
-rw-r--r--drivers/net/wireless/prism54/isl_ioctl.c11
-rw-r--r--drivers/net/wireless/prism54/islpci_dev.c14
-rw-r--r--drivers/net/wireless/prism54/islpci_dev.h3
-rw-r--r--drivers/net/wireless/prism54/islpci_eth.c23
-rw-r--r--drivers/net/wireless/prism54/islpci_hotplug.c1
-rw-r--r--drivers/net/wireless/prism54/islpci_mgt.c7
-rw-r--r--drivers/net/wireless/prism54/oid_mgt.c9
-rw-r--r--drivers/net/wireless/ray_cs.c46
-rw-r--r--drivers/net/wireless/spectrum_cs.c79
-rw-r--r--drivers/net/wireless/strip.c38
-rw-r--r--drivers/net/wireless/wavelan.c8
-rw-r--r--drivers/net/wireless/wavelan.p.h4
-rw-r--r--drivers/net/wireless/wavelan_cs.c11
-rw-r--r--drivers/net/wireless/wavelan_cs.p.h4
-rw-r--r--drivers/net/wireless/wl3501.h2
-rw-r--r--drivers/net/wireless/wl3501_cs.c3
-rw-r--r--drivers/parisc/asp.c6
-rw-r--r--drivers/parisc/ccio-dma.c144
-rw-r--r--drivers/parisc/ccio-rm-dma.c2
-rw-r--r--drivers/parisc/dino.c42
-rw-r--r--drivers/parisc/eisa.c4
-rw-r--r--drivers/parisc/gsc.c11
-rw-r--r--drivers/parisc/hppb.c10
-rw-r--r--drivers/parisc/iosapic.c2
-rw-r--r--drivers/parisc/lasi.c4
-rw-r--r--drivers/parisc/lba_pci.c14
-rw-r--r--drivers/parisc/led.c225
-rw-r--r--drivers/parisc/pdc_stable.c2
-rw-r--r--drivers/parisc/sba_iommu.c166
-rw-r--r--drivers/parisc/superio.c3
-rw-r--r--drivers/parisc/wax.c2
-rw-r--r--drivers/parport/parport_gsc.c5
-rw-r--r--drivers/parport/probe.c21
-rw-r--r--drivers/parport/share.c19
-rw-r--r--drivers/pci/access.c91
-rw-r--r--drivers/pci/hotplug/acpiphp_glue.c8
-rw-r--r--drivers/pci/hotplug/cpcihp_generic.c1
-rw-r--r--drivers/pci/hotplug/cpcihp_zt5550.c26
-rw-r--r--drivers/pci/hotplug/cpqphp_core.c24
-rw-r--r--drivers/pci/hotplug/cpqphp_pci.c15
-rw-r--r--drivers/pci/hotplug/fakephp.c2
-rw-r--r--drivers/pci/hotplug/ibmphp_core.c2
-rw-r--r--drivers/pci/hotplug/pciehp.h135
-rw-r--r--drivers/pci/hotplug/pciehp_core.c108
-rw-r--r--drivers/pci/hotplug/pciehp_ctrl.c1979
-rw-r--r--drivers/pci/hotplug/pciehp_hpc.c113
-rw-r--r--drivers/pci/hotplug/pciehp_pci.c840
-rw-r--r--drivers/pci/hotplug/pciehprm.h52
-rw-r--r--drivers/pci/hotplug/pciehprm_acpi.c1727
-rw-r--r--drivers/pci/hotplug/pciehprm_nonacpi.c464
-rw-r--r--drivers/pci/hotplug/pciehprm_nonacpi.h56
-rw-r--r--drivers/pci/hotplug/rpadlpar_core.c84
-rw-r--r--drivers/pci/hotplug/rpaphp.h5
-rw-r--r--drivers/pci/hotplug/rpaphp_core.c5
-rw-r--r--drivers/pci/hotplug/rpaphp_pci.c91
-rw-r--r--drivers/pci/hotplug/rpaphp_slot.c3
-rw-r--r--drivers/pci/hotplug/shpchp.h124
-rw-r--r--drivers/pci/hotplug/shpchp_core.c111
-rw-r--r--drivers/pci/hotplug/shpchp_ctrl.c2034
-rw-r--r--drivers/pci/hotplug/shpchp_hpc.c175
-rw-r--r--drivers/pci/hotplug/shpchp_pci.c861
-rw-r--r--drivers/pci/hotplug/shpchp_sysfs.c119
-rw-r--r--drivers/pci/hotplug/shpchprm.h55
-rw-r--r--drivers/pci/hotplug/shpchprm_acpi.c1649
-rw-r--r--drivers/pci/hotplug/shpchprm_legacy.c395
-rw-r--r--drivers/pci/hotplug/shpchprm_legacy.h113
-rw-r--r--drivers/pci/hotplug/shpchprm_nonacpi.c391
-rw-r--r--drivers/pci/hotplug/shpchprm_nonacpi.h56
-rw-r--r--drivers/pci/msi.c22
-rw-r--r--drivers/pci/pci-acpi.c11
-rw-r--r--drivers/pci/pci-driver.c31
-rw-r--r--drivers/pci/pci-sysfs.c20
-rw-r--r--drivers/pci/pci.c68
-rw-r--r--drivers/pci/pci.h7
-rw-r--r--drivers/pci/pcie/portdrv_core.c6
-rw-r--r--drivers/pci/pcie/portdrv_pci.c1
-rw-r--r--drivers/pci/probe.c1
-rw-r--r--drivers/pci/proc.c28
-rw-r--r--drivers/pci/quirks.c313
-rw-r--r--drivers/pci/rom.c1
-rw-r--r--drivers/pci/syscall.c14
-rw-r--r--drivers/pcmcia/Kconfig10
-rw-r--r--drivers/pcmcia/Makefile6
-rw-r--r--drivers/pcmcia/au1000_db1x00.c22
-rw-r--r--drivers/pcmcia/au1000_generic.c31
-rw-r--r--drivers/pcmcia/au1000_generic.h6
-rw-r--r--drivers/pcmcia/au1000_pb1x00.c2
-rw-r--r--drivers/pcmcia/au1000_xxs1500.c2
-rw-r--r--drivers/pcmcia/cistpl.c12
-rw-r--r--drivers/pcmcia/cs.c6
-rw-r--r--drivers/pcmcia/ds.c6
-rw-r--r--drivers/pcmcia/hd64465_ss.c22
-rw-r--r--drivers/pcmcia/i82365.c23
-rw-r--r--drivers/pcmcia/m32r_cfc.c23
-rw-r--r--drivers/pcmcia/m32r_pcc.c23
-rw-r--r--drivers/pcmcia/m8xx_pcmcia.c1272
-rw-r--r--drivers/pcmcia/omap_cf.c20
-rw-r--r--drivers/pcmcia/pxa2xx_base.c27
-rw-r--r--drivers/pcmcia/pxa2xx_mainstone.c2
-rw-r--r--drivers/pcmcia/pxa2xx_sharpsl.c151
-rw-r--r--drivers/pcmcia/rsrc_nonstatic.c8
-rw-r--r--drivers/pcmcia/sa1100_generic.c28
-rw-r--r--drivers/pcmcia/sa1111_generic.c2
-rw-r--r--drivers/pcmcia/socket_sysfs.c6
-rw-r--r--drivers/pcmcia/tcic.c22
-rw-r--r--drivers/pcmcia/vrc4171_card.c25
-rw-r--r--drivers/pcmcia/yenta_socket.c42
-rw-r--r--drivers/pnp/card.c4
-rw-r--r--drivers/pnp/core.c5
-rw-r--r--drivers/pnp/driver.c2
-rw-r--r--drivers/pnp/isapnp/core.c2
-rw-r--r--drivers/pnp/manager.c4
-rw-r--r--drivers/pnp/pnpacpi/core.c6
-rw-r--r--drivers/pnp/pnpbios/rsparser.c2
-rw-r--r--drivers/pnp/resource.c2
-rw-r--r--drivers/rapidio/Kconfig18
-rw-r--r--drivers/rapidio/Makefile6
-rw-r--r--drivers/rapidio/rio-access.c175
-rw-r--r--drivers/rapidio/rio-driver.c229
-rw-r--r--drivers/rapidio/rio-scan.c945
-rw-r--r--drivers/rapidio/rio-sysfs.c230
-rw-r--r--drivers/rapidio/rio.c510
-rw-r--r--drivers/rapidio/rio.h60
-rw-r--r--drivers/rapidio/switches/Makefile5
-rw-r--r--drivers/rapidio/switches/tsi500.c60
-rw-r--r--drivers/s390/block/dasd.c12
-rw-r--r--drivers/s390/block/dasd_devmap.c3
-rw-r--r--drivers/s390/block/dasd_diag.c64
-rw-r--r--drivers/s390/block/dasd_diag.h10
-rw-r--r--drivers/s390/char/con3215.c3
-rw-r--r--drivers/s390/char/con3270.c7
-rw-r--r--drivers/s390/char/fs3270.c234
-rw-r--r--drivers/s390/char/keyboard.c15
-rw-r--r--drivers/s390/char/keyboard.h4
-rw-r--r--drivers/s390/char/raw3270.c103
-rw-r--r--drivers/s390/char/raw3270.h7
-rw-r--r--drivers/s390/char/tape_class.c1
-rw-r--r--drivers/s390/char/tape_core.c9
-rw-r--r--drivers/s390/char/tty3270.c27
-rw-r--r--drivers/s390/char/vmcp.c4
-rw-r--r--drivers/s390/char/vmlogrdr.c1
-rw-r--r--drivers/s390/cio/ccwgroup.c6
-rw-r--r--drivers/s390/cio/cmf.c6
-rw-r--r--drivers/s390/cio/device.c20
-rw-r--r--drivers/s390/cio/device_fsm.c2
-rw-r--r--drivers/s390/cio/device_ops.c6
-rw-r--r--drivers/s390/cio/qdio.c17
-rw-r--r--drivers/s390/cio/qdio.h8
-rw-r--r--drivers/s390/crypto/z90main.c8
-rw-r--r--drivers/s390/net/claw.c37
-rw-r--r--drivers/s390/net/fsm.c5
-rw-r--r--drivers/s390/net/fsm.h8
-rw-r--r--drivers/s390/net/iucv.c12
-rw-r--r--drivers/s390/net/lcs.c3
-rw-r--r--drivers/s390/net/qeth.h45
-rw-r--r--drivers/s390/net/qeth_eddp.c3
-rw-r--r--drivers/s390/net/qeth_fs.h12
-rw-r--r--drivers/s390/net/qeth_main.c419
-rw-r--r--drivers/s390/net/qeth_mpc.c6
-rw-r--r--drivers/s390/net/qeth_mpc.h15
-rw-r--r--drivers/s390/net/qeth_sys.c28
-rw-r--r--drivers/s390/s390mach.h2
-rw-r--r--drivers/s390/scsi/zfcp_aux.c3
-rw-r--r--drivers/sbus/char/cpwatchdog.c24
-rw-r--r--drivers/sbus/char/display7seg.c32
-rw-r--r--drivers/sbus/char/envctrl.c31
-rw-r--r--drivers/sbus/char/openprom.c36
-rw-r--r--drivers/sbus/char/rtc.c22
-rw-r--r--drivers/scsi/3w-9xxx.c7
-rw-r--r--drivers/scsi/3w-xxxx.c4
-rw-r--r--drivers/scsi/3w-xxxx.h1
-rw-r--r--drivers/scsi/53c700.c89
-rw-r--r--drivers/scsi/53c700.h8
-rw-r--r--drivers/scsi/Kconfig61
-rw-r--r--drivers/scsi/Makefile6
-rw-r--r--drivers/scsi/NCR5380.c26
-rw-r--r--drivers/scsi/NCR53C9x.c16
-rw-r--r--drivers/scsi/NCR53c406a.c2
-rw-r--r--drivers/scsi/a100u2w.c2
-rw-r--r--drivers/scsi/a2091.c1
-rw-r--r--drivers/scsi/aacraid/README2
-rw-r--r--drivers/scsi/aacraid/TODO1
-rw-r--r--drivers/scsi/aacraid/aachba.c88
-rw-r--r--drivers/scsi/aacraid/aacraid.h27
-rw-r--r--drivers/scsi/aacraid/commctrl.c6
-rw-r--r--drivers/scsi/aacraid/comminit.c25
-rw-r--r--drivers/scsi/aacraid/commsup.c102
-rw-r--r--drivers/scsi/aacraid/dpcsup.c115
-rw-r--r--drivers/scsi/aacraid/linit.c37
-rw-r--r--drivers/scsi/aacraid/rkt.c178
-rw-r--r--drivers/scsi/aacraid/rx.c163
-rw-r--r--drivers/scsi/aacraid/sa.c44
-rw-r--r--drivers/scsi/advansys.c12
-rw-r--r--drivers/scsi/aha152x.c3
-rw-r--r--drivers/scsi/aha1542.c39
-rw-r--r--drivers/scsi/aha1740.c2
-rw-r--r--drivers/scsi/ahci.c113
-rw-r--r--drivers/scsi/aic7xxx/aic79xx_osm.c39
-rw-r--r--drivers/scsi/aic7xxx/aic79xx_osm.h1
-rw-r--r--drivers/scsi/aic7xxx/aic7xxx_osm.c32
-rw-r--r--drivers/scsi/aic7xxx/aic7xxx_osm.h1
-rw-r--r--drivers/scsi/aic7xxx_old.c3
-rw-r--r--drivers/scsi/amiga7xx.c1
-rw-r--r--drivers/scsi/arm/queue.c3
-rw-r--r--drivers/scsi/arm/scsi.h6
-rw-r--r--drivers/scsi/ata_piix.c22
-rw-r--r--drivers/scsi/atari_dma_emul.c2
-rw-r--r--drivers/scsi/atp870u.c29
-rw-r--r--drivers/scsi/bvme6000.c1
-rw-r--r--drivers/scsi/ch.c6
-rw-r--r--drivers/scsi/constants.c5
-rw-r--r--drivers/scsi/cpqfcTS.h19
-rw-r--r--drivers/scsi/cpqfcTSchip.h238
-rw-r--r--drivers/scsi/cpqfcTScontrol.c2231
-rw-r--r--drivers/scsi/cpqfcTSi2c.c493
-rw-r--r--drivers/scsi/cpqfcTSinit.c2096
-rw-r--r--drivers/scsi/cpqfcTSioctl.h94
-rw-r--r--drivers/scsi/cpqfcTSstructs.h1530
-rw-r--r--drivers/scsi/cpqfcTStrigger.c33
-rw-r--r--drivers/scsi/cpqfcTStrigger.h8
-rw-r--r--drivers/scsi/cpqfcTSworker.c6516
-rw-r--r--drivers/scsi/dc395x.c16
-rw-r--r--drivers/scsi/dec_esp.c23
-rw-r--r--drivers/scsi/dpt_i2o.c61
-rw-r--r--drivers/scsi/eata.c61
-rw-r--r--drivers/scsi/eata_pio.c21
-rw-r--r--drivers/scsi/fd_mcs.c4
-rw-r--r--drivers/scsi/fdomain.c4
-rw-r--r--drivers/scsi/gvp11.c1
-rw-r--r--drivers/scsi/hosts.c14
-rw-r--r--drivers/scsi/ibmmca.c11
-rw-r--r--drivers/scsi/ibmvscsi/ibmvscsi.c9
-rw-r--r--drivers/scsi/ibmvscsi/iseries_vscsi.c8
-rw-r--r--drivers/scsi/ide-scsi.c35
-rw-r--r--drivers/scsi/imm.c2
-rw-r--r--drivers/scsi/in2000.c2
-rw-r--r--drivers/scsi/ipr.c2
-rw-r--r--drivers/scsi/ipr.h5
-rw-r--r--drivers/scsi/ips.c171
-rw-r--r--drivers/scsi/ips.h1
-rw-r--r--drivers/scsi/iscsi_tcp.c3642
-rw-r--r--drivers/scsi/iscsi_tcp.h322
-rw-r--r--drivers/scsi/lasi700.c6
-rw-r--r--drivers/scsi/libata-core.c1159
-rw-r--r--drivers/scsi/libata-scsi.c1532
-rw-r--r--drivers/scsi/libata.h21
-rw-r--r--drivers/scsi/lpfc/lpfc.h4
-rw-r--r--drivers/scsi/lpfc/lpfc_attr.c201
-rw-r--r--drivers/scsi/lpfc/lpfc_crtn.h21
-rw-r--r--drivers/scsi/lpfc/lpfc_ct.c14
-rw-r--r--drivers/scsi/lpfc/lpfc_disc.h1
-rw-r--r--drivers/scsi/lpfc/lpfc_els.c45
-rw-r--r--drivers/scsi/lpfc/lpfc_hbadisc.c122
-rw-r--r--drivers/scsi/lpfc/lpfc_init.c74
-rw-r--r--drivers/scsi/lpfc/lpfc_mbox.c14
-rw-r--r--drivers/scsi/lpfc/lpfc_mem.c2
-rw-r--r--drivers/scsi/lpfc/lpfc_nportdisc.c21
-rw-r--r--drivers/scsi/lpfc/lpfc_scsi.c407
-rw-r--r--drivers/scsi/lpfc/lpfc_sli.c530
-rw-r--r--drivers/scsi/lpfc/lpfc_sli.h22
-rw-r--r--drivers/scsi/lpfc/lpfc_version.h2
-rw-r--r--drivers/scsi/megaraid/mega_common.h1
-rw-r--r--drivers/scsi/megaraid/megaraid_mbox.c15
-rw-r--r--drivers/scsi/megaraid/megaraid_mm.c11
-rw-r--r--drivers/scsi/megaraid/megaraid_mm.h1
-rw-r--r--drivers/scsi/megaraid/megaraid_sas.c6
-rw-r--r--drivers/scsi/mesh.c2
-rw-r--r--drivers/scsi/mvme147.c1
-rw-r--r--drivers/scsi/mvme16x.c1
-rw-r--r--drivers/scsi/ncr53c8xx.c30
-rw-r--r--drivers/scsi/nsp32.c8
-rw-r--r--drivers/scsi/nsp32.h1
-rw-r--r--drivers/scsi/osst.c23
-rw-r--r--drivers/scsi/pci2000.h3
-rw-r--r--drivers/scsi/pcmcia/nsp_cs.c10
-rw-r--r--drivers/scsi/pcmcia/sym53c500_cs.c2
-rw-r--r--drivers/scsi/pdc_adma.c740
-rw-r--r--drivers/scsi/ppa.c2
-rw-r--r--drivers/scsi/psi240i.c2
-rw-r--r--drivers/scsi/qla2xxx/ql2100.c9
-rw-r--r--drivers/scsi/qla2xxx/ql2100_fw.c22
-rw-r--r--drivers/scsi/qla2xxx/ql2200.c9
-rw-r--r--drivers/scsi/qla2xxx/ql2200_fw.c22
-rw-r--r--drivers/scsi/qla2xxx/ql2300.c9
-rw-r--r--drivers/scsi/qla2xxx/ql2300_fw.c13851
-rw-r--r--drivers/scsi/qla2xxx/ql2322.c7
-rw-r--r--drivers/scsi/qla2xxx/ql2322_fw.c14483
-rw-r--r--drivers/scsi/qla2xxx/ql6312.c7
-rw-r--r--drivers/scsi/qla2xxx/ql6312_fw.c13882
-rw-r--r--drivers/scsi/qla2xxx/qla_attr.c111
-rw-r--r--drivers/scsi/qla2xxx/qla_dbg.c18
-rw-r--r--drivers/scsi/qla2xxx/qla_dbg.h23
-rw-r--r--drivers/scsi/qla2xxx/qla_def.h36
-rw-r--r--drivers/scsi/qla2xxx/qla_fw.h30
-rw-r--r--drivers/scsi/qla2xxx/qla_gbl.h35
-rw-r--r--drivers/scsi/qla2xxx/qla_gs.c18
-rw-r--r--drivers/scsi/qla2xxx/qla_init.c117
-rw-r--r--drivers/scsi/qla2xxx/qla_inline.h19
-rw-r--r--drivers/scsi/qla2xxx/qla_iocb.c63
-rw-r--r--drivers/scsi/qla2xxx/qla_isr.c25
-rw-r--r--drivers/scsi/qla2xxx/qla_mbx.c18
-rw-r--r--drivers/scsi/qla2xxx/qla_os.c112
-rw-r--r--drivers/scsi/qla2xxx/qla_rscn.c25
-rw-r--r--drivers/scsi/qla2xxx/qla_settings.h22
-rw-r--r--drivers/scsi/qla2xxx/qla_sup.c23
-rw-r--r--drivers/scsi/qla2xxx/qla_version.h22
-rw-r--r--drivers/scsi/qlogicfas408.c4
-rw-r--r--drivers/scsi/raid_class.c2
-rw-r--r--drivers/scsi/sata_mv.c1156
-rw-r--r--drivers/scsi/sata_nv.c14
-rw-r--r--drivers/scsi/sata_promise.c53
-rw-r--r--drivers/scsi/sata_qstor.c46
-rw-r--r--drivers/scsi/sata_sil.c16
-rw-r--r--drivers/scsi/sata_sil24.c891
-rw-r--r--drivers/scsi/sata_sis.c20
-rw-r--r--drivers/scsi/sata_svw.c32
-rw-r--r--drivers/scsi/sata_sx4.c59
-rw-r--r--drivers/scsi/sata_uli.c12
-rw-r--r--drivers/scsi/sata_via.c45
-rw-r--r--drivers/scsi/sata_vsc.c40
-rw-r--r--drivers/scsi/scsi.c34
-rw-r--r--drivers/scsi/scsi_debug.c21
-rw-r--r--drivers/scsi/scsi_error.c48
-rw-r--r--drivers/scsi/scsi_ioctl.c17
-rw-r--r--drivers/scsi/scsi_lib.c39
-rw-r--r--drivers/scsi/scsi_scan.c37
-rw-r--r--drivers/scsi/scsi_transport_fc.c477
-rw-r--r--drivers/scsi/scsi_transport_iscsi.c1383
-rw-r--r--drivers/scsi/scsi_transport_sas.c77
-rw-r--r--drivers/scsi/scsi_transport_spi.c24
-rw-r--r--drivers/scsi/sd.c116
-rw-r--r--drivers/scsi/sg.c56
-rw-r--r--drivers/scsi/sgiwd93.c6
-rw-r--r--drivers/scsi/sgiwd93.h24
-rw-r--r--drivers/scsi/sr.c17
-rw-r--r--drivers/scsi/st.c30
-rw-r--r--drivers/scsi/sym53c416.c2
-rw-r--r--drivers/scsi/sym53c8xx_2/sym_hipd.c4
-rw-r--r--drivers/scsi/sym53c8xx_2/sym_hipd.h2
-rw-r--r--drivers/scsi/sym53c8xx_defs.h13
-rw-r--r--drivers/scsi/tmscsim.c12
-rw-r--r--drivers/scsi/u14-34f.c56
-rw-r--r--drivers/scsi/wd33c93.c1
-rw-r--r--drivers/scsi/zalon.c4
-rw-r--r--drivers/serial/8250.c88
-rw-r--r--drivers/serial/8250.h1
-rw-r--r--drivers/serial/8250_au1x00.c102
-rw-r--r--drivers/serial/8250_early.c2
-rw-r--r--drivers/serial/8250_gsc.c6
-rw-r--r--drivers/serial/Kconfig8
-rw-r--r--drivers/serial/Makefile1
-rw-r--r--drivers/serial/amba-pl010.c1
-rw-r--r--drivers/serial/amba-pl011.c1
-rw-r--r--drivers/serial/crisv10.c9
-rw-r--r--drivers/serial/imx.c11
-rw-r--r--drivers/serial/ioc4_serial.c80
-rw-r--r--drivers/serial/mcfserial.c37
-rw-r--r--drivers/serial/mpc52xx_uart.c10
-rw-r--r--drivers/serial/mpsc.c4
-rw-r--r--drivers/serial/mux.c11
-rw-r--r--drivers/serial/pxa.c31
-rw-r--r--drivers/serial/s3c2410.c11
-rw-r--r--drivers/serial/sa1100.c10
-rw-r--r--drivers/serial/serial_core.c8
-rw-r--r--drivers/serial/sunsu.c2
-rw-r--r--drivers/serial/vr41xx_siu.c12
-rw-r--r--drivers/sh/superhyway/superhyway-sysfs.c2
-rw-r--r--drivers/sh/superhyway/superhyway.c77
-rw-r--r--drivers/tc/.gitignore1
-rw-r--r--drivers/tc/tc.c89
-rw-r--r--drivers/tc/zs.c32
-rw-r--r--drivers/telephony/ixj.h1
-rw-r--r--drivers/usb/Makefile2
-rw-r--r--drivers/usb/class/Kconfig23
-rw-r--r--drivers/usb/class/Makefile1
-rw-r--r--drivers/usb/class/bluetty.c1279
-rw-r--r--drivers/usb/class/cdc-acm.c5
-rw-r--r--drivers/usb/class/usblp.c3
-rw-r--r--drivers/usb/core/Kconfig11
-rw-r--r--drivers/usb/core/Makefile2
-rw-r--r--drivers/usb/core/buffer.c2
-rw-r--r--drivers/usb/core/config.c22
-rw-r--r--drivers/usb/core/devio.c192
-rw-r--r--drivers/usb/core/file.c23
-rw-r--r--drivers/usb/core/hcd-pci.c106
-rw-r--r--drivers/usb/core/hcd.c156
-rw-r--r--drivers/usb/core/hcd.h77
-rw-r--r--drivers/usb/core/hub.c426
-rw-r--r--drivers/usb/core/hub.h2
-rw-r--r--drivers/usb/core/inode.c44
-rw-r--r--drivers/usb/core/message.c90
-rw-r--r--drivers/usb/core/notify.c120
-rw-r--r--drivers/usb/core/sysfs.c319
-rw-r--r--drivers/usb/core/urb.c7
-rw-r--r--drivers/usb/core/usb.c167
-rw-r--r--drivers/usb/core/usb.h33
-rw-r--r--drivers/usb/gadget/dummy_hcd.c57
-rw-r--r--drivers/usb/gadget/ether.c23
-rw-r--r--drivers/usb/gadget/file_storage.c52
-rw-r--r--drivers/usb/gadget/goku_udc.c6
-rw-r--r--drivers/usb/gadget/lh7a40x_udc.c15
-rw-r--r--drivers/usb/gadget/lh7a40x_udc.h1
-rw-r--r--drivers/usb/gadget/net2280.c6
-rw-r--r--drivers/usb/gadget/omap_udc.c30
-rw-r--r--drivers/usb/gadget/pxa2xx_udc.c29
-rw-r--r--drivers/usb/gadget/pxa2xx_udc.h8
-rw-r--r--drivers/usb/gadget/rndis.c1
-rw-r--r--drivers/usb/gadget/serial.c16
-rw-r--r--drivers/usb/gadget/zero.c9
-rw-r--r--drivers/usb/host/Makefile5
-rw-r--r--drivers/usb/host/ehci-hcd.c545
-rw-r--r--drivers/usb/host/ehci-hub.c8
-rw-r--r--drivers/usb/host/ehci-mem.c6
-rw-r--r--drivers/usb/host/ehci-pci.c414
-rw-r--r--drivers/usb/host/ehci-q.c6
-rw-r--r--drivers/usb/host/ehci-sched.c14
-rw-r--r--drivers/usb/host/ehci.h1
-rw-r--r--drivers/usb/host/hc_crisv10.c1
-rw-r--r--drivers/usb/host/isp116x-hcd.c58
-rw-r--r--drivers/usb/host/isp116x.h1
-rw-r--r--drivers/usb/host/ohci-au1xxx.c8
-rw-r--r--drivers/usb/host/ohci-dbg.c4
-rw-r--r--drivers/usb/host/ohci-hcd.c6
-rw-r--r--drivers/usb/host/ohci-hub.c52
-rw-r--r--drivers/usb/host/ohci-lh7a404.c8
-rw-r--r--drivers/usb/host/ohci-mem.c5
-rw-r--r--drivers/usb/host/ohci-omap.c59
-rw-r--r--drivers/usb/host/ohci-pci.c48
-rw-r--r--drivers/usb/host/ohci-ppc-soc.c11
-rw-r--r--drivers/usb/host/ohci-pxa27x.c14
-rw-r--r--drivers/usb/host/ohci-s3c2410.c11
-rw-r--r--drivers/usb/host/ohci-sa1111.c7
-rw-r--r--drivers/usb/host/ohci.h1
-rw-r--r--drivers/usb/host/pci-quirks.c319
-rw-r--r--drivers/usb/host/sl811-hcd.c30
-rw-r--r--drivers/usb/host/sl811_cs.c1
-rw-r--r--drivers/usb/host/uhci-debug.c5
-rw-r--r--drivers/usb/host/uhci-hcd.c177
-rw-r--r--drivers/usb/host/uhci-hcd.h98
-rw-r--r--drivers/usb/host/uhci-q.c64
-rw-r--r--drivers/usb/image/mdc800.c33
-rw-r--r--drivers/usb/image/microtek.c3
-rw-r--r--drivers/usb/input/acecad.c76
-rw-r--r--drivers/usb/input/aiptek.c209
-rw-r--r--drivers/usb/input/appletouch.c130
-rw-r--r--drivers/usb/input/ati_remote.c173
-rw-r--r--drivers/usb/input/hid-core.c56
-rw-r--r--drivers/usb/input/hid-input.c56
-rw-r--r--drivers/usb/input/hid-lgff.c17
-rw-r--r--drivers/usb/input/hid-tmff.c11
-rw-r--r--drivers/usb/input/hid.h2
-rw-r--r--drivers/usb/input/hiddev.c3
-rw-r--r--drivers/usb/input/itmtouch.c70
-rw-r--r--drivers/usb/input/kbtab.c82
-rw-r--r--drivers/usb/input/keyspan_remote.c210
-rw-r--r--drivers/usb/input/map_to_7segment.h2
-rw-r--r--drivers/usb/input/mtouchusb.c111
-rw-r--r--drivers/usb/input/pid.c14
-rw-r--r--drivers/usb/input/powermate.c136
-rw-r--r--drivers/usb/input/touchkitusb.c118
-rw-r--r--drivers/usb/input/usbkbd.c105
-rw-r--r--drivers/usb/input/usbmouse.c93
-rw-r--r--drivers/usb/input/wacom.c142
-rw-r--r--drivers/usb/input/xpad.c95
-rw-r--r--drivers/usb/input/yealink.c66
-rw-r--r--drivers/usb/media/dabusb.c3
-rw-r--r--drivers/usb/media/konicawc.c89
-rw-r--r--drivers/usb/media/pwc/pwc-if.c1
-rw-r--r--drivers/usb/media/pwc/pwc.h2
-rw-r--r--drivers/usb/media/w9968cf.c1
-rw-r--r--drivers/usb/misc/auerswald.c3
-rw-r--r--drivers/usb/misc/idmouse.c21
-rw-r--r--drivers/usb/misc/legousbtower.c5
-rw-r--r--drivers/usb/misc/rio500.c3
-rw-r--r--drivers/usb/misc/sisusbvga/sisusb.c8
-rw-r--r--drivers/usb/misc/sisusbvga/sisusb.h1
-rw-r--r--drivers/usb/misc/sisusbvga/sisusb_con.c1
-rw-r--r--drivers/usb/misc/sisusbvga/sisusb_init.c1
-rw-r--r--drivers/usb/misc/usblcd.c9
-rw-r--r--drivers/usb/misc/usbtest.c18
-rw-r--r--drivers/usb/misc/uss720.c6
-rw-r--r--drivers/usb/mon/mon_main.c23
-rw-r--r--drivers/usb/net/Kconfig2
-rw-r--r--drivers/usb/net/asix.c2
-rw-r--r--drivers/usb/net/gl620a.c2
-rw-r--r--drivers/usb/net/kaweth.c8
-rw-r--r--drivers/usb/net/net1080.c2
-rw-r--r--drivers/usb/net/pegasus.c2
-rw-r--r--drivers/usb/net/pegasus.h2
-rw-r--r--drivers/usb/net/rndis_host.c2
-rw-r--r--drivers/usb/net/rtl8150.c1
-rw-r--r--drivers/usb/net/usbnet.c4
-rw-r--r--drivers/usb/net/usbnet.h2
-rw-r--r--drivers/usb/net/zaurus.c2
-rw-r--r--drivers/usb/net/zd1201.c2
-rw-r--r--drivers/usb/serial/ChangeLog.old730
-rw-r--r--drivers/usb/serial/Kconfig9
-rw-r--r--drivers/usb/serial/Makefile1
-rw-r--r--drivers/usb/serial/airprime.c8
-rw-r--r--drivers/usb/serial/belkin_sa.c10
-rw-r--r--drivers/usb/serial/bus.c37
-rw-r--r--drivers/usb/serial/cp2101.c10
-rw-r--r--drivers/usb/serial/cyberjack.c10
-rw-r--r--drivers/usb/serial/cypress_m8.c20
-rw-r--r--drivers/usb/serial/digi_acceleport.c20
-rw-r--r--drivers/usb/serial/empeg.c8
-rw-r--r--drivers/usb/serial/ftdi_sio.c16
-rw-r--r--drivers/usb/serial/ftdi_sio.h16
-rw-r--r--drivers/usb/serial/garmin_gps.c15
-rw-r--r--drivers/usb/serial/generic.c9
-rw-r--r--drivers/usb/serial/hp4x.c10
-rw-r--r--drivers/usb/serial/io_edgeport.c219
-rw-r--r--drivers/usb/serial/io_tables.h30
-rw-r--r--drivers/usb/serial/io_ti.c20
-rw-r--r--drivers/usb/serial/ipaq.c247
-rw-r--r--drivers/usb/serial/ipw.c10
-rw-r--r--drivers/usb/serial/ir-usb.c9
-rw-r--r--drivers/usb/serial/keyspan.h40
-rw-r--r--drivers/usb/serial/keyspan_pda.c30
-rw-r--r--drivers/usb/serial/kl5kusb105.c10
-rw-r--r--drivers/usb/serial/kobil_sct.c9
-rw-r--r--drivers/usb/serial/mct_u232.c10
-rw-r--r--drivers/usb/serial/nokia_dku2.c142
-rw-r--r--drivers/usb/serial/omninet.c10
-rw-r--r--drivers/usb/serial/option.c10
-rw-r--r--drivers/usb/serial/pl2303.c35
-rw-r--r--drivers/usb/serial/safe_serial.c10
-rw-r--r--drivers/usb/serial/ti_usb_3410_5052.c18
-rw-r--r--drivers/usb/serial/usb-serial.c378
-rw-r--r--drivers/usb/serial/usb-serial.h81
-rw-r--r--drivers/usb/serial/visor.c170
-rw-r--r--drivers/usb/serial/whiteheat.c42
-rw-r--r--drivers/usb/storage/Kconfig3
-rw-r--r--drivers/usb/storage/onetouch.c99
-rw-r--r--drivers/usb/storage/shuttle_usbat.c314
-rw-r--r--drivers/usb/storage/shuttle_usbat.h66
-rw-r--r--drivers/usb/storage/transport.c6
-rw-r--r--drivers/usb/storage/transport.h2
-rw-r--r--drivers/usb/storage/unusual_devs.h44
-rw-r--r--drivers/usb/storage/usb.c163
-rw-r--r--drivers/usb/storage/usb.h5
-rw-r--r--drivers/usb/usb-skeleton.c3
-rw-r--r--drivers/video/68328fb.c1
-rw-r--r--drivers/video/Kconfig196
-rw-r--r--drivers/video/Makefile3
-rw-r--r--drivers/video/acornfb.c3
-rw-r--r--drivers/video/amba-clcd.c8
-rw-r--r--drivers/video/amifb.c1
-rw-r--r--drivers/video/arcfb.c27
-rw-r--r--drivers/video/asiliantfb.c1
-rw-r--r--drivers/video/aty/ati_ids.h1
-rw-r--r--drivers/video/aty/aty128fb.c1
-rw-r--r--drivers/video/aty/atyfb_base.c59
-rw-r--r--drivers/video/aty/radeon_base.c3
-rw-r--r--drivers/video/aty/radeonfb.h3
-rw-r--r--drivers/video/au1100fb.c971
-rw-r--r--drivers/video/au1100fb.h614
-rw-r--r--drivers/video/backlight/backlight.c1
-rw-r--r--drivers/video/backlight/corgi_bl.c18
-rw-r--r--drivers/video/backlight/lcd.c1
-rw-r--r--drivers/video/bw2.c1
-rw-r--r--drivers/video/cfbcopyarea.c36
-rw-r--r--drivers/video/cfbfillrect.c24
-rw-r--r--drivers/video/cfbimgblt.c26
-rw-r--r--drivers/video/cg14.c1
-rw-r--r--drivers/video/cg3.c1
-rw-r--r--drivers/video/cg6.c7
-rw-r--r--drivers/video/chipsfb.c1
-rw-r--r--drivers/video/cirrusfb.c25
-rw-r--r--drivers/video/clps711xfb.c1
-rw-r--r--drivers/video/console/Kconfig29
-rw-r--r--drivers/video/console/Makefile7
-rw-r--r--drivers/video/console/bitblit.c53
-rw-r--r--drivers/video/console/fbcon.c487
-rw-r--r--drivers/video/console/fbcon.h62
-rw-r--r--drivers/video/console/fbcon_ccw.c428
-rw-r--r--drivers/video/console/fbcon_cw.c412
-rw-r--r--drivers/video/console/fbcon_rotate.c117
-rw-r--r--drivers/video/console/fbcon_rotate.h105
-rw-r--r--drivers/video/console/fbcon_ud.c454
-rw-r--r--drivers/video/console/font_rl.c4374
-rw-r--r--drivers/video/console/fonts.c4
-rw-r--r--drivers/video/console/newport_con.c1
-rw-r--r--drivers/video/console/softcursor.c (renamed from drivers/video/softcursor.c)8
-rw-r--r--drivers/video/console/sticore.c126
-rw-r--r--drivers/video/console/tileblit.c13
-rw-r--r--drivers/video/console/vgacon.c5
-rw-r--r--drivers/video/controlfb.c1
-rw-r--r--drivers/video/cyber2000fb.c1
-rw-r--r--drivers/video/cyblafb.c1
-rw-r--r--drivers/video/dnfb.c3
-rw-r--r--drivers/video/epson1355fb.c3
-rw-r--r--drivers/video/fbmem.c303
-rw-r--r--drivers/video/fbmon.c48
-rw-r--r--drivers/video/fbsysfs.c67
-rw-r--r--drivers/video/ffb.c3
-rw-r--r--drivers/video/fm2fb.c1
-rw-r--r--drivers/video/gbefb.c41
-rw-r--r--drivers/video/geode/Kconfig1
-rw-r--r--drivers/video/geode/gx1fb_core.c1
-rw-r--r--drivers/video/hitfb.c1
-rw-r--r--drivers/video/hpfb.c1
-rw-r--r--drivers/video/i810/i810-i2c.c135
-rw-r--r--drivers/video/i810/i810.h3
-rw-r--r--drivers/video/i810/i810_main.c22
-rw-r--r--drivers/video/i810/i810_regs.h1
-rw-r--r--drivers/video/imsttfb.c1
-rw-r--r--drivers/video/imxfb.c13
-rw-r--r--drivers/video/intelfb/intelfb.h6
-rw-r--r--drivers/video/intelfb/intelfbdrv.c11
-rw-r--r--drivers/video/intelfb/intelfbhw.c6
-rw-r--r--drivers/video/kyro/fbdev.c1
-rw-r--r--drivers/video/leo.c1
-rw-r--r--drivers/video/logo/Kconfig2
-rw-r--r--drivers/video/macfb.c1
-rw-r--r--drivers/video/matrox/matroxfb_DAC1064.c4
-rw-r--r--drivers/video/matrox/matroxfb_accel.c2
-rw-r--r--drivers/video/matrox/matroxfb_base.c29
-rw-r--r--drivers/video/matrox/matroxfb_base.h5
-rw-r--r--drivers/video/matrox/matroxfb_crtc2.c1
-rw-r--r--drivers/video/maxinefb.c1
-rw-r--r--drivers/video/modedb.c88
-rw-r--r--drivers/video/neofb.c1
-rw-r--r--drivers/video/nvidia/nv_local.h2
-rw-r--r--drivers/video/nvidia/nv_of.c64
-rw-r--r--drivers/video/nvidia/nv_proto.h18
-rw-r--r--drivers/video/nvidia/nv_setup.c16
-rw-r--r--drivers/video/nvidia/nvidia.c136
-rw-r--r--drivers/video/offb.c1
-rw-r--r--drivers/video/p9100.c1
-rw-r--r--drivers/video/platinumfb.c1
-rw-r--r--drivers/video/pm2fb.c17
-rw-r--r--drivers/video/pmag-ba-fb.c1
-rw-r--r--drivers/video/pmagb-b-fb.c1
-rw-r--r--drivers/video/pvr2fb.c1
-rw-r--r--drivers/video/pxafb.c13
-rw-r--r--drivers/video/q40fb.c2
-rw-r--r--drivers/video/radeonfb.c1
-rw-r--r--drivers/video/s1d13xxxfb.c10
-rw-r--r--drivers/video/s3c2410fb.c30
-rw-r--r--drivers/video/sa1100fb.c13
-rw-r--r--drivers/video/savage/savagefb.h206
-rw-r--r--drivers/video/savage/savagefb_driver.c850
-rw-r--r--drivers/video/sgivwfb.c27
-rw-r--r--drivers/video/sis/sis_main.c2
-rw-r--r--drivers/video/skeletonfb.c9
-rw-r--r--drivers/video/sstfb.c1
-rw-r--r--drivers/video/stifb.c1
-rw-r--r--drivers/video/tcx.c1
-rw-r--r--drivers/video/tdfxfb.c1
-rw-r--r--drivers/video/tgafb.c1
-rw-r--r--drivers/video/tridentfb.c1
-rw-r--r--drivers/video/tx3912fb.c1
-rw-r--r--drivers/video/valkyriefb.c1
-rw-r--r--drivers/video/vesafb.c61
-rw-r--r--drivers/video/vfb.c3
-rw-r--r--drivers/video/vga16fb.c170
-rw-r--r--drivers/video/vgastate.c5
-rw-r--r--drivers/video/w100fb.c49
-rw-r--r--drivers/w1/w1_ds2433.c6
-rw-r--r--drivers/w1/w1_family.c1
-rw-r--r--drivers/zorro/zorro-sysfs.c1
-rw-r--r--drivers/zorro/zorro.c2
-rw-r--r--fs/9p/error.c1
-rw-r--r--fs/9p/trans_sock.c3
-rw-r--r--fs/9p/v9fs.c6
-rw-r--r--fs/9p/vfs_file.c1
-rw-r--r--fs/9p/vfs_inode.c10
-rw-r--r--fs/Kconfig79
-rw-r--r--fs/Kconfig.binfmt2
-rw-r--r--fs/Makefile2
-rw-r--r--fs/adfs/adfs.h1
-rw-r--r--fs/affs/file.c18
-rw-r--r--fs/affs/super.c16
-rw-r--r--fs/afs/file.c41
-rw-r--r--fs/afs/inode.c2
-rw-r--r--fs/afs/internal.h1
-rw-r--r--fs/aio.c31
-rw-r--r--fs/attr.c3
-rw-r--r--fs/autofs/waitq.c6
-rw-r--r--fs/autofs4/inode.c6
-rw-r--r--fs/autofs4/waitq.c6
-rw-r--r--fs/befs/linuxvfs.c20
-rw-r--r--fs/binfmt_aout.c1
-rw-r--r--fs/binfmt_elf.c8
-rw-r--r--fs/binfmt_elf_fdpic.c22
-rw-r--r--fs/binfmt_flat.c1
-rw-r--r--fs/binfmt_misc.c2
-rw-r--r--fs/binfmt_som.c1
-rw-r--r--fs/bio.c4
-rw-r--r--fs/buffer.c31
-rw-r--r--fs/cifs/AUTHORS4
-rw-r--r--fs/cifs/CHANGES60
-rw-r--r--fs/cifs/README24
-rw-r--r--fs/cifs/TODO50
-rw-r--r--fs/cifs/asn1.c6
-rw-r--r--fs/cifs/cifs_debug.c103
-rw-r--r--fs/cifs/cifs_debug.h5
-rw-r--r--fs/cifs/cifs_fs_sb.h3
-rw-r--r--fs/cifs/cifs_unicode.c5
-rw-r--r--fs/cifs/cifsfs.c85
-rw-r--r--fs/cifs/cifsfs.h3
-rw-r--r--fs/cifs/cifsglob.h98
-rw-r--r--fs/cifs/cifspdu.h499
-rw-r--r--fs/cifs/cifsproto.h34
-rw-r--r--fs/cifs/cifssmb.c661
-rw-r--r--fs/cifs/cn_cifs.h37
-rw-r--r--fs/cifs/connect.c301
-rw-r--r--fs/cifs/dir.c108
-rw-r--r--fs/cifs/fcntl.c12
-rw-r--r--fs/cifs/file.c466
-rw-r--r--fs/cifs/inode.c152
-rw-r--r--fs/cifs/link.c28
-rw-r--r--fs/cifs/misc.c138
-rw-r--r--fs/cifs/netmisc.c15
-rw-r--r--fs/cifs/ntlmssp.h12
-rw-r--r--fs/cifs/readdir.c84
-rw-r--r--fs/cifs/rfc1002pdu.h13
-rw-r--r--fs/cifs/transport.c331
-rw-r--r--fs/cifs/xattr.c15
-rw-r--r--fs/coda/psdev.c4
-rw-r--r--fs/compat.c1
-rw-r--r--fs/compat_ioctl.c161
-rw-r--r--fs/dcache.c12
-rw-r--r--fs/devfs/base.c6
-rw-r--r--fs/direct-io.c4
-rw-r--r--fs/dquot.c23
-rw-r--r--fs/exec.c88
-rw-r--r--fs/ext2/CHANGES157
-rw-r--r--fs/ext2/acl.c6
-rw-r--r--fs/ext2/balloc.c73
-rw-r--r--fs/ext2/ialloc.c40
-rw-r--r--fs/ext2/inode.c4
-rw-r--r--fs/ext2/super.c16
-rw-r--r--fs/ext3/balloc.c80
-rw-r--r--fs/ext3/bitmap.c2
-rw-r--r--fs/ext3/bitmap.h8
-rw-r--r--fs/ext3/ialloc.c44
-rw-r--r--fs/ext3/inode.c13
-rw-r--r--fs/ext3/namei.c2
-rw-r--r--fs/ext3/namei.h8
-rw-r--r--fs/ext3/resize.c10
-rw-r--r--fs/ext3/super.c47
-rw-r--r--fs/ext3/xattr.c8
-rw-r--r--fs/fat/dir.c230
-rw-r--r--fs/fat/inode.c11
-rw-r--r--fs/file_table.c18
-rw-r--r--fs/filesystems.c1
-rw-r--r--fs/freevxfs/vxfs_extern.h4
-rw-r--r--fs/freevxfs/vxfs_inode.c11
-rw-r--r--fs/fs-writeback.c35
-rw-r--r--fs/fuse/dev.c13
-rw-r--r--fs/fuse/dir.c177
-rw-r--r--fs/fuse/file.c132
-rw-r--r--fs/fuse/fuse_i.h29
-rw-r--r--fs/hfs/hfs_fs.h1
-rw-r--r--fs/hfs/inode.c3
-rw-r--r--fs/hfsplus/bnode.c1
-rw-r--r--fs/hfsplus/dir.c1
-rw-r--r--fs/hfsplus/extents.c1
-rw-r--r--fs/hfsplus/hfsplus_fs.h1
-rw-r--r--fs/hfsplus/inode.c3
-rw-r--r--fs/hfsplus/super.c1
-rw-r--r--fs/hfsplus/wrapper.c1
-rw-r--r--fs/hostfs/hostfs_kern.c4
-rw-r--r--fs/hpfs/dnode.c8
-rw-r--r--fs/hpfs/file.c7
-rw-r--r--fs/hpfs/super.c10
-rw-r--r--fs/hugetlbfs/inode.c206
-rw-r--r--fs/inode.c3
-rw-r--r--fs/inotify.c2
-rw-r--r--fs/isofs/inode.c12
-rw-r--r--fs/jbd/commit.c6
-rw-r--r--fs/jbd/journal.c2
-rw-r--r--fs/jbd/recovery.c4
-rw-r--r--fs/jbd/transaction.c11
-rw-r--r--fs/jffs/intrep.c18
-rw-r--r--fs/jffs2/Makefile5
-rw-r--r--fs/jffs2/TODO38
-rw-r--r--fs/jffs2/background.c5
-rw-r--r--fs/jffs2/build.c171
-rw-r--r--fs/jffs2/compr.c40
-rw-r--r--fs/jffs2/compr.h12
-rw-r--r--fs/jffs2/compr_rtime.c32
-rw-r--r--fs/jffs2/compr_rubin.c37
-rw-r--r--fs/jffs2/compr_rubin.h6
-rw-r--r--fs/jffs2/compr_zlib.c14
-rw-r--r--fs/jffs2/comprtest.c30
-rw-r--r--fs/jffs2/debug.c705
-rw-r--r--fs/jffs2/debug.h279
-rw-r--r--fs/jffs2/dir.c121
-rw-r--r--fs/jffs2/erase.c37
-rw-r--r--fs/jffs2/file.c29
-rw-r--r--fs/jffs2/fs.c104
-rw-r--r--fs/jffs2/gc.c156
-rw-r--r--fs/jffs2/histo.h2
-rw-r--r--fs/jffs2/histo_mips.h2
-rw-r--r--fs/jffs2/ioctl.c6
-rw-r--r--fs/jffs2/malloc.c84
-rw-r--r--fs/jffs2/nodelist.c1226
-rw-r--r--fs/jffs2/nodelist.h163
-rw-r--r--fs/jffs2/nodemgmt.c471
-rw-r--r--fs/jffs2/os-linux.h47
-rw-r--r--fs/jffs2/read.c17
-rw-r--r--fs/jffs2/readinode.c1153
-rw-r--r--fs/jffs2/scan.c300
-rw-r--r--fs/jffs2/summary.c730
-rw-r--r--fs/jffs2/summary.h183
-rw-r--r--fs/jffs2/super.c24
-rw-r--r--fs/jffs2/symlink.c32
-rw-r--r--fs/jffs2/wbuf.c217
-rw-r--r--fs/jffs2/write.c157
-rw-r--r--fs/jffs2/writev.c35
-rw-r--r--fs/jfs/jfs_dmap.c20
-rw-r--r--fs/jfs/jfs_imap.c10
-rw-r--r--fs/jfs/jfs_metapage.c22
-rw-r--r--fs/jfs/jfs_txnmgr.c2
-rw-r--r--fs/jfs/jfs_xtree.c18
-rw-r--r--fs/jfs/namei.c3
-rw-r--r--fs/jfs/super.c1
-rw-r--r--fs/lockd/clntproc.c3
-rw-r--r--fs/lockd/host.c4
-rw-r--r--fs/lockd/svcsubs.c43
-rw-r--r--fs/locks.c48
-rw-r--r--fs/mbcache.c9
-rw-r--r--fs/msdos/namei.c14
-rw-r--r--fs/namei.c165
-rw-r--r--fs/namespace.c699
-rw-r--r--fs/ncpfs/ioctl.c34
-rw-r--r--fs/nfs/delegation.c43
-rw-r--r--fs/nfs/delegation.h17
-rw-r--r--fs/nfs/dir.c70
-rw-r--r--fs/nfs/direct.c10
-rw-r--r--fs/nfs/file.c31
-rw-r--r--fs/nfs/inode.c224
-rw-r--r--fs/nfs/nfs2xdr.c1
-rw-r--r--fs/nfs/nfs3proc.c92
-rw-r--r--fs/nfs/nfs3xdr.c1
-rw-r--r--fs/nfs/nfs4_fs.h57
-rw-r--r--fs/nfs/nfs4proc.c835
-rw-r--r--fs/nfs/nfs4state.c265
-rw-r--r--fs/nfs/nfs4xdr.c305
-rw-r--r--fs/nfs/proc.c44
-rw-r--r--fs/nfs/read.c5
-rw-r--r--fs/nfs/unlink.c3
-rw-r--r--fs/nfs/write.c16
-rw-r--r--fs/nfsd/export.c6
-rw-r--r--fs/nfsd/nfs3xdr.c3
-rw-r--r--fs/nfsd/nfs4xdr.c9
-rw-r--r--fs/nfsd/nfscache.c3
-rw-r--r--fs/nfsd/nfsctl.c98
-rw-r--r--fs/nfsd/nfssvc.c80
-rw-r--r--fs/nfsd/vfs.c9
-rw-r--r--fs/ntfs/ChangeLog85
-rw-r--r--fs/ntfs/Makefile2
-rw-r--r--fs/ntfs/aops.c832
-rw-r--r--fs/ntfs/attrib.c983
-rw-r--r--fs/ntfs/attrib.h10
-rw-r--r--fs/ntfs/file.c2256
-rw-r--r--fs/ntfs/inode.c514
-rw-r--r--fs/ntfs/layout.h31
-rw-r--r--fs/ntfs/lcnalloc.c56
-rw-r--r--fs/ntfs/lcnalloc.h43
-rw-r--r--fs/ntfs/malloc.h3
-rw-r--r--fs/ntfs/mft.c26
-rw-r--r--fs/ntfs/super.c2
-rw-r--r--fs/open.c112
-rw-r--r--fs/openpromfs/inode.c3
-rw-r--r--fs/partitions/check.c36
-rw-r--r--fs/partitions/ibm.c15
-rw-r--r--fs/pnode.c305
-rw-r--r--fs/pnode.h37
-rw-r--r--fs/proc/array.c2
-rw-r--r--fs/proc/base.c62
-rw-r--r--fs/proc/generic.c2
-rw-r--r--fs/proc/inode.c17
-rw-r--r--fs/proc/proc_devtree.c57
-rw-r--r--fs/proc/proc_misc.c8
-rw-r--r--fs/proc/task_mmu.c51
-rw-r--r--fs/quota.c9
-rw-r--r--fs/reiserfs/file.c4
-rw-r--r--fs/reiserfs/fix_node.c2
-rw-r--r--fs/reiserfs/inode.c2
-rw-r--r--fs/reiserfs/super.c25
-rw-r--r--fs/reiserfs/xattr.c2
-rw-r--r--fs/reiserfs/xattr_acl.c3
-rw-r--r--fs/seq_file.c12
-rw-r--r--fs/smbfs/request.c3
-rw-r--r--fs/smbfs/symlink.c4
-rw-r--r--fs/super.c5
-rw-r--r--fs/udf/file.c2
-rw-r--r--fs/udf/udf_sb.h3
-rw-r--r--fs/ufs/super.c14
-rw-r--r--fs/vfat/namei.c20
-rw-r--r--fs/xattr.c23
-rw-r--r--fs/xfs/Kconfig2
-rw-r--r--fs/xfs/Makefile-linux-2.61
-rw-r--r--fs/xfs/linux-2.6/kmem.c61
-rw-r--r--fs/xfs/linux-2.6/kmem.h62
-rw-r--r--fs/xfs/linux-2.6/mrlock.h36
-rw-r--r--fs/xfs/linux-2.6/mutex.h36
-rw-r--r--fs/xfs/linux-2.6/sema.h36
-rw-r--r--fs/xfs/linux-2.6/spin.h36
-rw-r--r--fs/xfs/linux-2.6/sv.h36
-rw-r--r--fs/xfs/linux-2.6/time.h36
-rw-r--r--fs/xfs/linux-2.6/xfs_aops.c82
-rw-r--r--fs/xfs/linux-2.6/xfs_aops.h36
-rw-r--r--fs/xfs/linux-2.6/xfs_buf.c227
-rw-r--r--fs/xfs/linux-2.6/xfs_buf.h73
-rw-r--r--fs/xfs/linux-2.6/xfs_cred.h36
-rw-r--r--fs/xfs/linux-2.6/xfs_export.c47
-rw-r--r--fs/xfs/linux-2.6/xfs_export.h36
-rw-r--r--fs/xfs/linux-2.6/xfs_file.c41
-rw-r--r--fs/xfs/linux-2.6/xfs_fs_subr.c38
-rw-r--r--fs/xfs/linux-2.6/xfs_fs_subr.h57
-rw-r--r--fs/xfs/linux-2.6/xfs_globals.c42
-rw-r--r--fs/xfs/linux-2.6/xfs_globals.h41
-rw-r--r--fs/xfs/linux-2.6/xfs_ioctl.c55
-rw-r--r--fs/xfs/linux-2.6/xfs_ioctl32.c38
-rw-r--r--fs/xfs/linux-2.6/xfs_ioctl32.h44
-rw-r--r--fs/xfs/linux-2.6/xfs_iops.c180
-rw-r--r--fs/xfs/linux-2.6/xfs_iops.h40
-rw-r--r--fs/xfs/linux-2.6/xfs_linux.h57
-rw-r--r--fs/xfs/linux-2.6/xfs_lrw.c69
-rw-r--r--fs/xfs/linux-2.6/xfs_lrw.h41
-rw-r--r--fs/xfs/linux-2.6/xfs_stats.c37
-rw-r--r--fs/xfs/linux-2.6/xfs_stats.h36
-rw-r--r--fs/xfs/linux-2.6/xfs_super.c132
-rw-r--r--fs/xfs/linux-2.6/xfs_super.h37
-rw-r--r--fs/xfs/linux-2.6/xfs_sysctl.c56
-rw-r--r--fs/xfs/linux-2.6/xfs_sysctl.h37
-rw-r--r--fs/xfs/linux-2.6/xfs_version.h41
-rw-r--r--fs/xfs/linux-2.6/xfs_vfs.c38
-rw-r--r--fs/xfs/linux-2.6/xfs_vfs.h37
-rw-r--r--fs/xfs/linux-2.6/xfs_vnode.c40
-rw-r--r--fs/xfs/linux-2.6/xfs_vnode.h55
-rw-r--r--fs/xfs/quota/Makefile1
-rw-r--r--fs/xfs/quota/Makefile-linux-2.653
-rw-r--r--fs/xfs/quota/xfs_dquot.c237
-rw-r--r--fs/xfs/quota/xfs_dquot.h36
-rw-r--r--fs/xfs/quota/xfs_dquot_item.c53
-rw-r--r--fs/xfs/quota/xfs_dquot_item.h36
-rw-r--r--fs/xfs/quota/xfs_qm.c187
-rw-r--r--fs/xfs/quota/xfs_qm.h42
-rw-r--r--fs/xfs/quota/xfs_qm_bhv.c53
-rw-r--r--fs/xfs/quota/xfs_qm_stats.c53
-rw-r--r--fs/xfs/quota/xfs_qm_stats.h37
-rw-r--r--fs/xfs/quota/xfs_qm_syscalls.c173
-rw-r--r--fs/xfs/quota/xfs_quota_priv.h36
-rw-r--r--fs/xfs/quota/xfs_trans_dquot.c102
-rw-r--r--fs/xfs/support/debug.c38
-rw-r--r--fs/xfs/support/debug.h43
-rw-r--r--fs/xfs/support/ktrace.c39
-rw-r--r--fs/xfs/support/ktrace.h38
-rw-r--r--fs/xfs/support/move.c37
-rw-r--r--fs/xfs/support/move.h36
-rw-r--r--fs/xfs/support/qsort.c155
-rw-r--r--fs/xfs/support/qsort.h41
-rw-r--r--fs/xfs/support/uuid.c37
-rw-r--r--fs/xfs/support/uuid.h52
-rw-r--r--fs/xfs/xfs.h41
-rw-r--r--fs/xfs/xfs_acl.c55
-rw-r--r--fs/xfs/xfs_acl.h36
-rw-r--r--fs/xfs/xfs_ag.h242
-rw-r--r--fs/xfs/xfs_alloc.c200
-rw-r--r--fs/xfs/xfs_alloc.h36
-rw-r--r--fs/xfs/xfs_alloc_btree.c475
-rw-r--r--fs/xfs/xfs_alloc_btree.h186
-rw-r--r--fs/xfs/xfs_arch.h51
-rw-r--r--fs/xfs/xfs_attr.c230
-rw-r--r--fs/xfs/xfs_attr.h44
-rw-r--r--fs/xfs/xfs_attr_leaf.c273
-rw-r--r--fs/xfs/xfs_attr_leaf.h129
-rw-r--r--fs/xfs/xfs_attr_sf.h65
-rw-r--r--fs/xfs/xfs_behavior.c37
-rw-r--r--fs/xfs/xfs_behavior.h36
-rw-r--r--fs/xfs/xfs_bit.c44
-rw-r--r--fs/xfs/xfs_bit.h72
-rw-r--r--fs/xfs/xfs_bmap.c244
-rw-r--r--fs/xfs/xfs_bmap.h58
-rw-r--r--fs/xfs/xfs_bmap_btree.c286
-rw-r--r--fs/xfs/xfs_bmap_btree.h644
-rw-r--r--fs/xfs/xfs_btree.c160
-rw-r--r--fs/xfs/xfs_btree.h211
-rw-r--r--fs/xfs/xfs_buf_item.c54
-rw-r--r--fs/xfs/xfs_buf_item.h36
-rw-r--r--fs/xfs/xfs_cap.h36
-rw-r--r--fs/xfs/xfs_clnt.h52
-rw-r--r--fs/xfs/xfs_da_btree.c101
-rw-r--r--fs/xfs/xfs_da_btree.h108
-rw-r--r--fs/xfs/xfs_dfrag.c123
-rw-r--r--fs/xfs/xfs_dfrag.h36
-rw-r--r--fs/xfs/xfs_dinode.h205
-rw-r--r--fs/xfs/xfs_dir.c70
-rw-r--r--fs/xfs/xfs_dir.h36
-rw-r--r--fs/xfs/xfs_dir2.c57
-rw-r--r--fs/xfs/xfs_dir2.h36
-rw-r--r--fs/xfs/xfs_dir2_block.c56
-rw-r--r--fs/xfs/xfs_dir2_block.h98
-rw-r--r--fs/xfs/xfs_dir2_data.c52
-rw-r--r--fs/xfs/xfs_dir2_data.h129
-rw-r--r--fs/xfs/xfs_dir2_leaf.c54
-rw-r--r--fs/xfs/xfs_dir2_leaf.h350
-rw-r--r--fs/xfs/xfs_dir2_node.c52
-rw-r--r--fs/xfs/xfs_dir2_node.h147
-rw-r--r--fs/xfs/xfs_dir2_sf.c59
-rw-r--r--fs/xfs/xfs_dir2_sf.h230
-rw-r--r--fs/xfs/xfs_dir2_trace.c47
-rw-r--r--fs/xfs/xfs_dir2_trace.h36
-rw-r--r--fs/xfs/xfs_dir_leaf.c64
-rw-r--r--fs/xfs/xfs_dir_leaf.h73
-rw-r--r--fs/xfs/xfs_dir_sf.h109
-rw-r--r--fs/xfs/xfs_dmapi.h37
-rw-r--r--fs/xfs/xfs_dmops.c41
-rw-r--r--fs/xfs/xfs_error.c46
-rw-r--r--fs/xfs/xfs_error.h104
-rw-r--r--fs/xfs/xfs_extfree_item.c47
-rw-r--r--fs/xfs/xfs_extfree_item.h36
-rw-r--r--fs/xfs/xfs_fs.h40
-rw-r--r--fs/xfs/xfs_fsops.c161
-rw-r--r--fs/xfs/xfs_fsops.h74
-rw-r--r--fs/xfs/xfs_ialloc.c133
-rw-r--r--fs/xfs/xfs_ialloc.h76
-rw-r--r--fs/xfs/xfs_ialloc_btree.c306
-rw-r--r--fs/xfs/xfs_ialloc_btree.h247
-rw-r--r--fs/xfs/xfs_iget.c54
-rw-r--r--fs/xfs/xfs_imap.h36
-rw-r--r--fs/xfs/xfs_inode.c153
-rw-r--r--fs/xfs/xfs_inode.h132
-rw-r--r--fs/xfs/xfs_inode_item.c60
-rw-r--r--fs/xfs/xfs_inode_item.h77
-rw-r--r--fs/xfs/xfs_inum.h140
-rw-r--r--fs/xfs/xfs_iocore.c57
-rw-r--r--fs/xfs/xfs_iomap.c69
-rw-r--r--fs/xfs/xfs_iomap.h36
-rw-r--r--fs/xfs/xfs_itable.c52
-rw-r--r--fs/xfs/xfs_itable.h33
-rw-r--r--fs/xfs/xfs_log.c281
-rw-r--r--fs/xfs/xfs_log.h45
-rw-r--r--fs/xfs/xfs_log_priv.h179
-rw-r--r--fs/xfs/xfs_log_recover.c174
-rw-r--r--fs/xfs/xfs_log_recover.h36
-rw-r--r--fs/xfs/xfs_mac.h36
-rw-r--r--fs/xfs/xfs_macros.c2141
-rw-r--r--fs/xfs/xfs_macros.h104
-rw-r--r--fs/xfs/xfs_mount.c73
-rw-r--r--fs/xfs/xfs_mount.h186
-rw-r--r--fs/xfs/xfs_qmops.c41
-rw-r--r--fs/xfs/xfs_quota.h80
-rw-r--r--fs/xfs/xfs_refcache.h36
-rw-r--r--fs/xfs/xfs_rename.c49
-rw-r--r--fs/xfs/xfs_rtalloc.c55
-rw-r--r--fs/xfs/xfs_rtalloc.h36
-rw-r--r--fs/xfs/xfs_rw.c58
-rw-r--r--fs/xfs/xfs_rw.h135
-rw-r--r--fs/xfs/xfs_sb.h448
-rw-r--r--fs/xfs/xfs_trans.c112
-rw-r--r--fs/xfs/xfs_trans.h176
-rw-r--r--fs/xfs/xfs_trans_ail.c41
-rw-r--r--fs/xfs/xfs_trans_buf.c53
-rw-r--r--fs/xfs/xfs_trans_extfree.c41
-rw-r--r--fs/xfs/xfs_trans_inode.c54
-rw-r--r--fs/xfs/xfs_trans_item.c41
-rw-r--r--fs/xfs/xfs_trans_priv.h36
-rw-r--r--fs/xfs/xfs_trans_space.h36
-rw-r--r--fs/xfs/xfs_types.h42
-rw-r--r--fs/xfs/xfs_utils.c47
-rw-r--r--fs/xfs/xfs_utils.h36
-rw-r--r--fs/xfs/xfs_vfsops.c181
-rw-r--r--fs/xfs/xfs_vnodeops.c144
-rw-r--r--include/asm-alpha/barrier.h2
-rw-r--r--include/asm-alpha/dma-mapping.h2
-rw-r--r--include/asm-alpha/ide.h4
-rw-r--r--include/asm-alpha/pgtable.h3
-rw-r--r--include/asm-alpha/ptrace.h3
-rw-r--r--include/asm-alpha/rwsem.h5
-rw-r--r--include/asm-alpha/semaphore.h3
-rw-r--r--include/asm-arm/arch-aaec2000/aaec2000.h56
-rw-r--r--include/asm-arm/arch-aaec2000/aaed2000.h40
-rw-r--r--include/asm-arm/arch-aaec2000/hardware.h3
-rw-r--r--include/asm-arm/arch-aaec2000/io.h2
-rw-r--r--include/asm-arm/arch-aaec2000/memory.h2
-rw-r--r--include/asm-arm/arch-cl7500/io.h2
-rw-r--r--include/asm-arm/arch-cl7500/memory.h2
-rw-r--r--include/asm-arm/arch-clps711x/io.h2
-rw-r--r--include/asm-arm/arch-clps711x/memory.h2
-rw-r--r--include/asm-arm/arch-ebsa110/memory.h2
-rw-r--r--include/asm-arm/arch-ebsa285/io.h2
-rw-r--r--include/asm-arm/arch-ebsa285/memory.h10
-rw-r--r--include/asm-arm/arch-epxa10db/io.h2
-rw-r--r--include/asm-arm/arch-epxa10db/memory.h2
-rw-r--r--include/asm-arm/arch-h720x/io.h2
-rw-r--r--include/asm-arm/arch-h720x/memory.h2
-rw-r--r--include/asm-arm/arch-imx/io.h2
-rw-r--r--include/asm-arm/arch-imx/memory.h2
-rw-r--r--include/asm-arm/arch-integrator/hardware.h9
-rw-r--r--include/asm-arm/arch-integrator/io.h8
-rw-r--r--include/asm-arm/arch-integrator/memory.h4
-rw-r--r--include/asm-arm/arch-iop3xx/io.h2
-rw-r--r--include/asm-arm/arch-iop3xx/iop321.h2
-rw-r--r--include/asm-arm/arch-iop3xx/iop331.h2
-rw-r--r--include/asm-arm/arch-iop3xx/memory.h4
-rw-r--r--include/asm-arm/arch-ixp2000/enp2611.h16
-rw-r--r--include/asm-arm/arch-ixp2000/io.h2
-rw-r--r--include/asm-arm/arch-ixp2000/irqs.h35
-rw-r--r--include/asm-arm/arch-ixp2000/ixdp2x01.h2
-rw-r--r--include/asm-arm/arch-ixp2000/ixp2000-regs.h50
-rw-r--r--include/asm-arm/arch-ixp2000/memory.h2
-rw-r--r--include/asm-arm/arch-ixp2000/platform.h50
-rw-r--r--include/asm-arm/arch-ixp2000/system.h23
-rw-r--r--include/asm-arm/arch-ixp2000/uengine.h62
-rw-r--r--include/asm-arm/arch-ixp4xx/hardware.h1
-rw-r--r--include/asm-arm/arch-ixp4xx/io.h74
-rw-r--r--include/asm-arm/arch-ixp4xx/irqs.h7
-rw-r--r--include/asm-arm/arch-ixp4xx/ixp4xx-regs.h75
-rw-r--r--include/asm-arm/arch-ixp4xx/memory.h2
-rw-r--r--include/asm-arm/arch-ixp4xx/nslu2.h96
-rw-r--r--include/asm-arm/arch-l7200/io.h2
-rw-r--r--include/asm-arm/arch-l7200/memory.h2
-rw-r--r--include/asm-arm/arch-lh7a40x/io.h2
-rw-r--r--include/asm-arm/arch-lh7a40x/memory.h2
-rw-r--r--include/asm-arm/arch-omap/board-h4.h6
-rw-r--r--include/asm-arm/arch-omap/board-innovator.h4
-rw-r--r--include/asm-arm/arch-omap/clock.h91
-rw-r--r--include/asm-arm/arch-omap/common.h2
-rw-r--r--include/asm-arm/arch-omap/cpu.h82
-rw-r--r--include/asm-arm/arch-omap/dma.h261
-rw-r--r--include/asm-arm/arch-omap/entry-macro.S14
-rw-r--r--include/asm-arm/arch-omap/fpga.h4
-rw-r--r--include/asm-arm/arch-omap/gpio.h2
-rw-r--r--include/asm-arm/arch-omap/hardware.h8
-rw-r--r--include/asm-arm/arch-omap/io.h34
-rw-r--r--include/asm-arm/arch-omap/irqs.h13
-rw-r--r--include/asm-arm/arch-omap/memory.h10
-rw-r--r--include/asm-arm/arch-omap/menelaus.h22
-rw-r--r--include/asm-arm/arch-omap/mux.h327
-rw-r--r--include/asm-arm/arch-omap/omap1510.h6
-rw-r--r--include/asm-arm/arch-omap/omap24xx.h17
-rw-r--r--include/asm-arm/arch-omap/omapfb.h281
-rw-r--r--include/asm-arm/arch-omap/pm.h40
-rw-r--r--include/asm-arm/arch-omap/prcm.h429
-rw-r--r--include/asm-arm/arch-omap/sram.h38
-rw-r--r--include/asm-arm/arch-omap/system.h35
-rw-r--r--include/asm-arm/arch-omap/timex.h8
-rw-r--r--include/asm-arm/arch-omap/uncompress.h6
-rw-r--r--include/asm-arm/arch-pxa/hardware.h4
-rw-r--r--include/asm-arm/arch-pxa/io.h2
-rw-r--r--include/asm-arm/arch-pxa/irda.h17
-rw-r--r--include/asm-arm/arch-pxa/memory.h2
-rw-r--r--include/asm-arm/arch-pxa/pm.h12
-rw-r--r--include/asm-arm/arch-pxa/pxa-regs.h42
-rw-r--r--include/asm-arm/arch-pxa/sharpsl.h8
-rw-r--r--include/asm-arm/arch-pxa/ssp.h8
-rw-r--r--include/asm-arm/arch-pxa/tosa.h166
-rw-r--r--include/asm-arm/arch-pxa/uncompress.h1
-rw-r--r--include/asm-arm/arch-realview/debug-macro.S38
-rw-r--r--include/asm-arm/arch-realview/dma.h (renamed from include/asm-ppc64/pmc.h)24
-rw-r--r--include/asm-arm/arch-realview/entry-macro.S74
-rw-r--r--include/asm-arm/arch-realview/hardware.h31
-rw-r--r--include/asm-arm/arch-realview/io.h34
-rw-r--r--include/asm-arm/arch-realview/irqs.h106
-rw-r--r--include/asm-arm/arch-realview/memory.h38
-rw-r--r--include/asm-arm/arch-realview/param.h19
-rw-r--r--include/asm-arm/arch-realview/platform.h450
-rw-r--r--include/asm-arm/arch-realview/smp.h31
-rw-r--r--include/asm-arm/arch-realview/system.h51
-rw-r--r--include/asm-arm/arch-realview/timex.h23
-rw-r--r--include/asm-arm/arch-realview/uncompress.h54
-rw-r--r--include/asm-arm/arch-realview/vmalloc.h21
-rw-r--r--include/asm-arm/arch-rpc/io.h2
-rw-r--r--include/asm-arm/arch-rpc/memory.h2
-rw-r--r--include/asm-arm/arch-s3c2410/fb.h3
-rw-r--r--include/asm-arm/arch-s3c2410/io.h2
-rw-r--r--include/asm-arm/arch-s3c2410/memory.h4
-rw-r--r--include/asm-arm/arch-s3c2410/regs-gpio.h6
-rw-r--r--include/asm-arm/arch-s3c2410/regs-iis.h1
-rw-r--r--include/asm-arm/arch-s3c2410/uncompress.h22
-rw-r--r--include/asm-arm/arch-sa1100/hardware.h7
-rw-r--r--include/asm-arm/arch-sa1100/io.h8
-rw-r--r--include/asm-arm/arch-sa1100/memory.h2
-rw-r--r--include/asm-arm/arch-sa1100/system.h1
-rw-r--r--include/asm-arm/arch-shark/io.h2
-rw-r--r--include/asm-arm/arch-shark/memory.h2
-rw-r--r--include/asm-arm/arch-versatile/memory.h2
-rw-r--r--include/asm-arm/assembler.h9
-rw-r--r--include/asm-arm/cpu.h1
-rw-r--r--include/asm-arm/dma-mapping.h4
-rw-r--r--include/asm-arm/hardirq.h1
-rw-r--r--include/asm-arm/hardware/amba_clcd.h2
-rw-r--r--include/asm-arm/hardware/arm_scu.h13
-rw-r--r--include/asm-arm/hardware/scoop.h10
-rw-r--r--include/asm-arm/io.h1
-rw-r--r--include/asm-arm/irq.h1
-rw-r--r--include/asm-arm/mach/arch.h7
-rw-r--r--include/asm-arm/mach/flash.h5
-rw-r--r--include/asm-arm/mach/map.h5
-rw-r--r--include/asm-arm/memory.h25
-rw-r--r--include/asm-arm/mmu_context.h4
-rw-r--r--include/asm-arm/pgtable.h3
-rw-r--r--include/asm-arm/semaphore.h2
-rw-r--r--include/asm-arm/smp.h64
-rw-r--r--include/asm-arm/spinlock.h6
-rw-r--r--include/asm-arm/tlb.h23
-rw-r--r--include/asm-arm/unistd.h1
-rw-r--r--include/asm-arm26/pgtable.h2
-rw-r--r--include/asm-arm26/semaphore.h3
-rw-r--r--include/asm-arm26/tlb.h47
-rw-r--r--include/asm-arm26/unistd.h1
-rw-r--r--include/asm-cris/arch-v10/byteorder.h4
-rw-r--r--include/asm-cris/arch-v10/checksum.h2
-rw-r--r--include/asm-cris/arch-v10/delay.h2
-rw-r--r--include/asm-cris/arch-v10/ide.h8
-rw-r--r--include/asm-cris/arch-v10/system.h8
-rw-r--r--include/asm-cris/arch-v10/thread_info.h2
-rw-r--r--include/asm-cris/arch-v10/timex.h2
-rw-r--r--include/asm-cris/arch-v10/uaccess.h4
-rw-r--r--include/asm-cris/arch-v32/bitops.h10
-rw-r--r--include/asm-cris/arch-v32/byteorder.h4
-rw-r--r--include/asm-cris/arch-v32/checksum.h2
-rw-r--r--include/asm-cris/arch-v32/delay.h2
-rw-r--r--include/asm-cris/arch-v32/ide.h4
-rw-r--r--include/asm-cris/arch-v32/io.h6
-rw-r--r--include/asm-cris/arch-v32/system.h6
-rw-r--r--include/asm-cris/arch-v32/thread_info.h2
-rw-r--r--include/asm-cris/arch-v32/timex.h2
-rw-r--r--include/asm-cris/arch-v32/uaccess.h4
-rw-r--r--include/asm-cris/atomic.h22
-rw-r--r--include/asm-cris/bitops.h18
-rw-r--r--include/asm-cris/checksum.h8
-rw-r--r--include/asm-cris/current.h2
-rw-r--r--include/asm-cris/delay.h2
-rw-r--r--include/asm-cris/dma-mapping.h4
-rw-r--r--include/asm-cris/io.h6
-rw-r--r--include/asm-cris/irq.h2
-rw-r--r--include/asm-cris/pgalloc.h12
-rw-r--r--include/asm-cris/pgtable.h46
-rw-r--r--include/asm-cris/processor.h6
-rw-r--r--include/asm-cris/semaphore.h19
-rw-r--r--include/asm-cris/system.h2
-rw-r--r--include/asm-cris/timex.h2
-rw-r--r--include/asm-cris/tlbflush.h4
-rw-r--r--include/asm-cris/uaccess.h22
-rw-r--r--include/asm-cris/unistd.h21
-rw-r--r--include/asm-frv/dma-mapping.h2
-rw-r--r--include/asm-frv/pci.h2
-rw-r--r--include/asm-frv/pgtable.h4
-rw-r--r--include/asm-frv/semaphore.h3
-rw-r--r--include/asm-generic/4level-fixup.h11
-rw-r--r--include/asm-generic/dma-mapping-broken.h2
-rw-r--r--include/asm-generic/pgtable.h3
-rw-r--r--include/asm-generic/tlb.h23
-rw-r--r--include/asm-generic/vmlinux.lds.h7
-rw-r--r--include/asm-h8300/semaphore.h3
-rw-r--r--include/asm-h8300/unistd.h1
-rw-r--r--include/asm-i386/desc.h8
-rw-r--r--include/asm-i386/elf.h2
-rw-r--r--include/asm-i386/ide.h6
-rw-r--r--include/asm-i386/kprobes.h17
-rw-r--r--include/asm-i386/mach-es7000/mach_mpparse.h2
-rw-r--r--include/asm-i386/mach-summit/mach_mpparse.h3
-rw-r--r--include/asm-i386/mmzone.h6
-rw-r--r--include/asm-i386/msi.h9
-rw-r--r--include/asm-i386/pgtable-2level.h5
-rw-r--r--include/asm-i386/pgtable-3level.h5
-rw-r--r--include/asm-i386/pgtable.h13
-rw-r--r--include/asm-i386/processor.h6
-rw-r--r--include/asm-i386/rwsem.h5
-rw-r--r--include/asm-i386/semaphore.h3
-rw-r--r--include/asm-i386/smp.h6
-rw-r--r--include/asm-i386/system.h33
-rw-r--r--include/asm-i386/unistd.h1
-rw-r--r--include/asm-ia64/dma-mapping.h7
-rw-r--r--include/asm-ia64/kdebug.h30
-rw-r--r--include/asm-ia64/kprobes.h13
-rw-r--r--include/asm-ia64/machvec.h4
-rw-r--r--include/asm-ia64/machvec_hpzx1.h21
-rw-r--r--include/asm-ia64/machvec_hpzx1_swiotlb.h3
-rw-r--r--include/asm-ia64/meminit.h6
-rw-r--r--include/asm-ia64/mmu_context.h81
-rw-r--r--include/asm-ia64/mmzone.h10
-rw-r--r--include/asm-ia64/msi.h3
-rw-r--r--include/asm-ia64/nodedata.h4
-rw-r--r--include/asm-ia64/page.h7
-rw-r--r--include/asm-ia64/pgtable.h4
-rw-r--r--include/asm-ia64/ptrace.h3
-rw-r--r--include/asm-ia64/rwsem.h5
-rw-r--r--include/asm-ia64/semaphore.h2
-rw-r--r--include/asm-ia64/sn/arch.h36
-rw-r--r--include/asm-ia64/sn/io.h11
-rw-r--r--include/asm-ia64/sn/klconfig.h34
-rw-r--r--include/asm-ia64/sn/l1.h12
-rw-r--r--include/asm-ia64/sn/nodepda.h1
-rw-r--r--include/asm-ia64/sn/sn_cpuid.h3
-rw-r--r--include/asm-ia64/sn/sn_sal.h59
-rw-r--r--include/asm-ia64/sn/tioca_provider.h14
-rw-r--r--include/asm-ia64/sn/tiocx.h3
-rw-r--r--include/asm-ia64/sn/xp.h16
-rw-r--r--include/asm-ia64/sparsemem.h20
-rw-r--r--include/asm-ia64/tlb.h19
-rw-r--r--include/asm-ia64/tlbflush.h1
-rw-r--r--include/asm-ia64/unistd.h2
-rw-r--r--include/asm-m32r/dma-mapping.h2
-rw-r--r--include/asm-m32r/mmzone.h6
-rw-r--r--include/asm-m32r/pgtable.h5
-rw-r--r--include/asm-m32r/ptrace.h3
-rw-r--r--include/asm-m32r/semaphore.h3
-rw-r--r--include/asm-m32r/thread_info.h2
-rw-r--r--include/asm-m32r/unistd.h1
-rw-r--r--include/asm-m68k/kbio.h1
-rw-r--r--include/asm-m68k/semaphore.h3
-rw-r--r--include/asm-m68k/sun3xflop.h2
-rw-r--r--include/asm-m68k/unistd.h1
-rw-r--r--include/asm-m68k/vuid_event.h4
-rw-r--r--include/asm-m68knommu/anchor.h4
-rw-r--r--include/asm-m68knommu/asm-offsets.h49
-rw-r--r--include/asm-m68knommu/atomic.h4
-rw-r--r--include/asm-m68knommu/cacheflush.h4
-rw-r--r--include/asm-m68knommu/coldfire.h10
-rw-r--r--include/asm-m68knommu/delay.h4
-rw-r--r--include/asm-m68knommu/ide.h444
-rw-r--r--include/asm-m68knommu/io.h8
-rw-r--r--include/asm-m68knommu/irq.h31
-rw-r--r--include/asm-m68knommu/irqnode.h36
-rw-r--r--include/asm-m68knommu/m520xsim.h54
-rw-r--r--include/asm-m68knommu/mcfcache.h14
-rw-r--r--include/asm-m68knommu/mcfne.h18
-rw-r--r--include/asm-m68knommu/mcfpit.h8
-rw-r--r--include/asm-m68knommu/mcfsim.h15
-rw-r--r--include/asm-m68knommu/mcfuart.h4
-rw-r--r--include/asm-m68knommu/mcfwdebug.h2
-rw-r--r--include/asm-m68knommu/mmu_context.h4
-rw-r--r--include/asm-m68knommu/processor.h4
-rw-r--r--include/asm-m68knommu/semaphore.h13
-rw-r--r--include/asm-m68knommu/system.h13
-rw-r--r--include/asm-m68knommu/tlbflush.h4
-rw-r--r--include/asm-m68knommu/unistd.h1
-rw-r--r--include/asm-mips/.gitignore1
-rw-r--r--include/asm-mips/abi.h25
-rw-r--r--include/asm-mips/addrspace.h90
-rw-r--r--include/asm-mips/asm.h4
-rw-r--r--include/asm-mips/atomic.h40
-rw-r--r--include/asm-mips/bitops.h209
-rw-r--r--include/asm-mips/bootinfo.h5
-rw-r--r--include/asm-mips/break.h1
-rw-r--r--include/asm-mips/bug.h11
-rw-r--r--include/asm-mips/bugs.h6
-rw-r--r--include/asm-mips/cache.h3
-rw-r--r--include/asm-mips/cacheflush.h31
-rw-r--r--include/asm-mips/checksum.h159
-rw-r--r--include/asm-mips/cobalt/cobalt.h52
-rw-r--r--include/asm-mips/cobalt/mach-gt64120.h1
-rw-r--r--include/asm-mips/compat.h12
-rw-r--r--include/asm-mips/cpu-features.h66
-rw-r--r--include/asm-mips/cpu-info.h2
-rw-r--r--include/asm-mips/cpu.h87
-rw-r--r--include/asm-mips/dec/ecc.h3
-rw-r--r--include/asm-mips/dec/ioasic_addrs.h3
-rw-r--r--include/asm-mips/dec/kn01.h34
-rw-r--r--include/asm-mips/dec/kn02.h33
-rw-r--r--include/asm-mips/dec/kn02xa.h46
-rw-r--r--include/asm-mips/dec/kn03.h13
-rw-r--r--include/asm-mips/dec/kn05.h76
-rw-r--r--include/asm-mips/dec/prom.h30
-rw-r--r--include/asm-mips/dec/system.h18
-rw-r--r--include/asm-mips/dec/tc.h10
-rw-r--r--include/asm-mips/delay.h17
-rw-r--r--include/asm-mips/dma-mapping.h4
-rw-r--r--include/asm-mips/dsp.h83
-rw-r--r--include/asm-mips/elf.h98
-rw-r--r--include/asm-mips/fcntl.h17
-rw-r--r--include/asm-mips/fixmap.h7
-rw-r--r--include/asm-mips/fpu.h9
-rw-r--r--include/asm-mips/fpu_emulator.h19
-rw-r--r--include/asm-mips/futex.h50
-rw-r--r--include/asm-mips/hazards.h58
-rw-r--r--include/asm-mips/highmem.h2
-rw-r--r--include/asm-mips/inst.h10
-rw-r--r--include/asm-mips/interrupt.h137
-rw-r--r--include/asm-mips/inventory.h8
-rw-r--r--include/asm-mips/io.h164
-rw-r--r--include/asm-mips/ip32/mace.h26
-rw-r--r--include/asm-mips/irq.h4
-rw-r--r--include/asm-mips/jmr3927/jmr3927.h14
-rw-r--r--include/asm-mips/mach-au1x00/au1000.h554
-rw-r--r--include/asm-mips/mach-au1x00/au1xxx.h44
-rw-r--r--include/asm-mips/mach-au1x00/au1xxx_dbdma.h128
-rw-r--r--include/asm-mips/mach-au1x00/au1xxx_gpio.h20
-rw-r--r--include/asm-mips/mach-au1x00/au1xxx_ide.h301
-rw-r--r--include/asm-mips/mach-au1x00/au1xxx_psc.h2
-rw-r--r--include/asm-mips/mach-au1x00/ioremap.h32
-rw-r--r--include/asm-mips/mach-db1x00/db1200.h224
-rw-r--r--include/asm-mips/mach-dec/mc146818rtc.h11
-rw-r--r--include/asm-mips/mach-generic/cpu-feature-overrides.h2
-rw-r--r--include/asm-mips/mach-generic/ide.h77
-rw-r--r--include/asm-mips/mach-generic/ioremap.h23
-rw-r--r--include/asm-mips/mach-generic/kernel-entry-init.h25
-rw-r--r--include/asm-mips/mach-generic/kmalloc.h13
-rw-r--r--include/asm-mips/mach-generic/spaces.h10
-rw-r--r--include/asm-mips/mach-ip22/cpu-feature-overrides.h8
-rw-r--r--include/asm-mips/mach-ip22/spaces.h2
-rw-r--r--include/asm-mips/mach-ip27/cpu-feature-overrides.h1
-rw-r--r--include/asm-mips/mach-ip27/kernel-entry-init.h52
-rw-r--r--include/asm-mips/mach-ip27/kmalloc.h8
-rw-r--r--include/asm-mips/mach-ip27/mmzone.h2
-rw-r--r--include/asm-mips/mach-ip27/spaces.h1
-rw-r--r--include/asm-mips/mach-ip27/topology.h3
-rw-r--r--include/asm-mips/mach-ip32/cpu-feature-overrides.h1
-rw-r--r--include/asm-mips/mach-ip32/kmalloc.h12
-rw-r--r--include/asm-mips/mach-ip32/spaces.h8
-rw-r--r--include/asm-mips/mach-ja/cpu-feature-overrides.h7
-rw-r--r--include/asm-mips/mach-mips/cpu-feature-overrides.h6
-rw-r--r--include/asm-mips/mach-mips/irq.h14
-rw-r--r--include/asm-mips/mach-ocelot3/cpu-feature-overrides.h7
-rw-r--r--include/asm-mips/mach-pb1x00/pb1200.h252
-rw-r--r--include/asm-mips/mach-pnx8550/cm.h43
-rw-r--r--include/asm-mips/mach-pnx8550/glb.h86
-rw-r--r--include/asm-mips/mach-pnx8550/int.h140
-rw-r--r--include/asm-mips/mach-pnx8550/kernel-entry-init.h262
-rw-r--r--include/asm-mips/mach-pnx8550/nand.h121
-rw-r--r--include/asm-mips/mach-pnx8550/pci.h185
-rw-r--r--include/asm-mips/mach-pnx8550/uart.h16
-rw-r--r--include/asm-mips/mach-pnx8550/usb.h32
-rw-r--r--include/asm-mips/mach-rm200/cpu-feature-overrides.h3
-rw-r--r--include/asm-mips/mach-sibyte/cpu-feature-overrides.h1
-rw-r--r--include/asm-mips/mach-sim/cpu-feature-overrides.h66
-rw-r--r--include/asm-mips/mach-yosemite/cpu-feature-overrides.h7
-rw-r--r--include/asm-mips/mc146818-time.h24
-rw-r--r--include/asm-mips/mips-boards/generic.h7
-rw-r--r--include/asm-mips/mips-boards/maltaint.h58
-rw-r--r--include/asm-mips/mips-boards/msc01_pci.h241
-rw-r--r--include/asm-mips/mips-boards/sim.h40
-rw-r--r--include/asm-mips/mips-boards/simint.h34
-rw-r--r--include/asm-mips/mipsmtregs.h391
-rw-r--r--include/asm-mips/mipsregs.h394
-rw-r--r--include/asm-mips/mmu_context.h4
-rw-r--r--include/asm-mips/mmzone.h1
-rw-r--r--include/asm-mips/module.h90
-rw-r--r--include/asm-mips/paccess.h8
-rw-r--r--include/asm-mips/page.h42
-rw-r--r--include/asm-mips/pci.h36
-rw-r--r--include/asm-mips/pgalloc.h19
-rw-r--r--include/asm-mips/pgtable-32.h53
-rw-r--r--include/asm-mips/pgtable-64.h71
-rw-r--r--include/asm-mips/pgtable-bits.h6
-rw-r--r--include/asm-mips/pgtable.h27
-rw-r--r--include/asm-mips/processor.h22
-rw-r--r--include/asm-mips/ptrace.h19
-rw-r--r--include/asm-mips/r4kcache.h72
-rw-r--r--include/asm-mips/rtc.h46
-rw-r--r--include/asm-mips/rtlx.h52
-rw-r--r--include/asm-mips/semaphore.h3
-rw-r--r--include/asm-mips/serial.h35
-rw-r--r--include/asm-mips/sgi/hpc3.h40
-rw-r--r--include/asm-mips/sibyte/bcm1480_int.h310
-rw-r--r--include/asm-mips/sibyte/bcm1480_l2c.h176
-rw-r--r--include/asm-mips/sibyte/bcm1480_mc.h962
-rw-r--r--include/asm-mips/sibyte/bcm1480_regs.h869
-rw-r--r--include/asm-mips/sibyte/bcm1480_scd.h436
-rw-r--r--include/asm-mips/sibyte/bigsur.h49
-rw-r--r--include/asm-mips/sibyte/board.h16
-rw-r--r--include/asm-mips/sibyte/sb1250.h13
-rw-r--r--include/asm-mips/sibyte/sb1250_defs.h33
-rw-r--r--include/asm-mips/sibyte/sb1250_dma.h70
-rw-r--r--include/asm-mips/sibyte/sb1250_genbus.h230
-rw-r--r--include/asm-mips/sibyte/sb1250_int.h8
-rw-r--r--include/asm-mips/sibyte/sb1250_l2c.h11
-rw-r--r--include/asm-mips/sibyte/sb1250_ldt.h2
-rw-r--r--include/asm-mips/sibyte/sb1250_mac.h35
-rw-r--r--include/asm-mips/sibyte/sb1250_mc.h6
-rw-r--r--include/asm-mips/sibyte/sb1250_regs.h35
-rw-r--r--include/asm-mips/sibyte/sb1250_scd.h102
-rw-r--r--include/asm-mips/sibyte/sb1250_smbus.h58
-rw-r--r--include/asm-mips/sibyte/sb1250_syncser.h2
-rw-r--r--include/asm-mips/sibyte/sb1250_uart.h13
-rw-r--r--include/asm-mips/sibyte/swarm.h2
-rw-r--r--include/asm-mips/sigcontext.h60
-rw-r--r--include/asm-mips/siginfo.h1
-rw-r--r--include/asm-mips/signal.h29
-rw-r--r--include/asm-mips/sn/sn0/arch.h5
-rw-r--r--include/asm-mips/socket.h5
-rw-r--r--include/asm-mips/spinlock.h26
-rw-r--r--include/asm-mips/stackframe.h29
-rw-r--r--include/asm-mips/system.h71
-rw-r--r--include/asm-mips/thread_info.h11
-rw-r--r--include/asm-mips/time.h3
-rw-r--r--include/asm-mips/traps.h3
-rw-r--r--include/asm-mips/tx4938/rbtx4938.h207
-rw-r--r--include/asm-mips/tx4938/spi.h74
-rw-r--r--include/asm-mips/tx4938/tx4938.h706
-rw-r--r--include/asm-mips/tx4938/tx4938_mips.h54
-rw-r--r--include/asm-mips/uaccess.h158
-rw-r--r--include/asm-mips/unistd.h26
-rw-r--r--include/asm-mips/vga.h25
-rw-r--r--include/asm-mips/war.h14
-rw-r--r--include/asm-parisc/assembly.h71
-rw-r--r--include/asm-parisc/bitops.h290
-rw-r--r--include/asm-parisc/cacheflush.h35
-rw-r--r--include/asm-parisc/dma-mapping.h8
-rw-r--r--include/asm-parisc/errno.h1
-rw-r--r--include/asm-parisc/grfioctl.h2
-rw-r--r--include/asm-parisc/ide.h1
-rw-r--r--include/asm-parisc/led.h3
-rw-r--r--include/asm-parisc/mmzone.h6
-rw-r--r--include/asm-parisc/parisc-device.h7
-rw-r--r--include/asm-parisc/pci.h2
-rw-r--r--include/asm-parisc/pgtable.h5
-rw-r--r--include/asm-parisc/processor.h19
-rw-r--r--include/asm-parisc/psw.h51
-rw-r--r--include/asm-parisc/ptrace.h2
-rw-r--r--include/asm-parisc/semaphore.h3
-rw-r--r--include/asm-parisc/spinlock.h5
-rw-r--r--include/asm-parisc/spinlock_types.h8
-rw-r--r--include/asm-parisc/system.h48
-rw-r--r--include/asm-parisc/tlbflush.h32
-rw-r--r--include/asm-parisc/types.h2
-rw-r--r--include/asm-parisc/unistd.h17
-rw-r--r--include/asm-powerpc/a.out.h (renamed from include/asm-ppc64/a.out.h)21
-rw-r--r--include/asm-powerpc/abs_addr.h (renamed from include/asm-ppc64/abs_addr.h)13
-rw-r--r--include/asm-powerpc/asm-compat.h55
-rw-r--r--include/asm-powerpc/atomic.h379
-rw-r--r--include/asm-powerpc/auxvec.h (renamed from include/asm-ppc64/auxvec.h)8
-rw-r--r--include/asm-powerpc/backlight.h (renamed from include/asm-ppc/backlight.h)9
-rw-r--r--include/asm-powerpc/bitops.h428
-rw-r--r--include/asm-powerpc/bug.h (renamed from include/asm-ppc64/bug.h)31
-rw-r--r--include/asm-powerpc/byteorder.h (renamed from include/asm-ppc64/byteorder.h)11
-rw-r--r--include/asm-powerpc/cache.h40
-rw-r--r--include/asm-powerpc/cacheflush.h (renamed from include/asm-ppc64/cacheflush.h)52
-rw-r--r--include/asm-powerpc/checksum.h (renamed from include/asm-ppc64/checksum.h)47
-rw-r--r--include/asm-powerpc/compat.h (renamed from include/asm-ppc64/compat.h)8
-rw-r--r--include/asm-powerpc/cputable.h434
-rw-r--r--include/asm-powerpc/current.h27
-rw-r--r--include/asm-powerpc/dbdma.h (renamed from include/asm-ppc/dbdma.h)0
-rw-r--r--include/asm-powerpc/dma.h (renamed from include/asm-ppc/dma.h)91
-rw-r--r--include/asm-powerpc/eeh_event.h52
-rw-r--r--include/asm-powerpc/elf.h (renamed from include/asm-ppc64/elf.h)114
-rw-r--r--include/asm-powerpc/firmware.h (renamed from include/asm-ppc64/firmware.h)16
-rw-r--r--include/asm-powerpc/futex.h (renamed from include/asm-ppc64/futex.h)48
-rw-r--r--include/asm-powerpc/grackle.h7
-rw-r--r--include/asm-powerpc/hardirq.h (renamed from include/asm-ppc/hardirq.h)14
-rw-r--r--include/asm-powerpc/heathrow.h (renamed from include/asm-ppc/heathrow.h)0
-rw-r--r--include/asm-powerpc/hvcall.h (renamed from include/asm-ppc64/hvcall.h)14
-rw-r--r--include/asm-powerpc/hw_irq.h (renamed from include/asm-ppc64/hw_irq.h)67
-rw-r--r--include/asm-powerpc/i8259.h12
-rw-r--r--include/asm-powerpc/ide.h (renamed from include/asm-ppc/ide.h)29
-rw-r--r--include/asm-powerpc/ioctls.h3
-rw-r--r--include/asm-powerpc/iommu.h (renamed from include/asm-ppc64/iommu.h)46
-rw-r--r--include/asm-powerpc/ipcbuf.h34
-rw-r--r--include/asm-powerpc/irq.h (renamed from include/asm-ppc/irq.h)167
-rw-r--r--include/asm-powerpc/iseries/hv_call.h (renamed from include/asm-ppc64/iSeries/HvCall.h)10
-rw-r--r--include/asm-powerpc/iseries/hv_call_event.h (renamed from include/asm-ppc64/iSeries/HvCallEvent.h)10
-rw-r--r--include/asm-powerpc/iseries/hv_call_sc.h (renamed from include/asm-ppc64/iSeries/HvCallSc.h)6
-rw-r--r--include/asm-powerpc/iseries/hv_call_xm.h (renamed from include/asm-ppc64/iSeries/HvCallXm.h)10
-rw-r--r--include/asm-powerpc/iseries/hv_lp_config.h (renamed from include/asm-ppc64/iSeries/HvLpConfig.h)12
-rw-r--r--include/asm-powerpc/iseries/hv_lp_event.h (renamed from include/asm-ppc64/iSeries/HvLpEvent.h)10
-rw-r--r--include/asm-powerpc/iseries/hv_types.h (renamed from include/asm-ppc64/iSeries/HvTypes.h)6
-rw-r--r--include/asm-powerpc/iseries/iseries_io.h (renamed from include/asm-ppc64/iSeries/iSeries_io.h)6
-rw-r--r--include/asm-powerpc/iseries/it_exp_vpd_panel.h (renamed from include/asm-ppc64/iSeries/ItExtVpdPanel.h)6
-rw-r--r--include/asm-powerpc/iseries/it_lp_naca.h (renamed from include/asm-ppc64/iSeries/ItLpNaca.h)6
-rw-r--r--include/asm-powerpc/iseries/it_lp_queue.h (renamed from include/asm-ppc64/iSeries/ItLpQueue.h)6
-rw-r--r--include/asm-powerpc/iseries/it_lp_reg_save.h (renamed from include/asm-ppc64/iSeries/ItLpRegSave.h)4
-rw-r--r--include/asm-powerpc/iseries/lpar_map.h (renamed from include/asm-ppc64/iSeries/LparMap.h)6
-rw-r--r--include/asm-powerpc/iseries/mf.h (renamed from include/asm-ppc64/iSeries/mf.h)10
-rw-r--r--include/asm-powerpc/iseries/vio.h (renamed from include/asm-ppc64/iSeries/vio.h)10
-rw-r--r--include/asm-powerpc/kdebug.h (renamed from include/asm-ppc64/kdebug.h)11
-rw-r--r--include/asm-powerpc/kexec.h49
-rw-r--r--include/asm-powerpc/keylargo.h (renamed from include/asm-ppc/keylargo.h)0
-rw-r--r--include/asm-powerpc/kmap_types.h33
-rw-r--r--include/asm-powerpc/kprobes.h (renamed from include/asm-ppc64/kprobes.h)22
-rw-r--r--include/asm-powerpc/lmb.h (renamed from include/asm-ppc64/lmb.h)2
-rw-r--r--include/asm-powerpc/lppaca.h (renamed from include/asm-ppc64/lppaca.h)9
-rw-r--r--include/asm-powerpc/machdep.h (renamed from include/asm-ppc64/machdep.h)140
-rw-r--r--include/asm-powerpc/macio.h (renamed from include/asm-ppc/macio.h)0
-rw-r--r--include/asm-powerpc/mediabay.h (renamed from include/asm-ppc/mediabay.h)0
-rw-r--r--include/asm-powerpc/mpic.h (renamed from arch/ppc64/kernel/mpic.h)14
-rw-r--r--include/asm-powerpc/numnodes.h7
-rw-r--r--include/asm-powerpc/of_device.h (renamed from include/asm-ppc/of_device.h)7
-rw-r--r--include/asm-powerpc/ohare.h (renamed from include/asm-ppc/ohare.h)0
-rw-r--r--include/asm-powerpc/oprofile_impl.h (renamed from include/asm-ppc64/oprofile_impl.h)24
-rw-r--r--include/asm-powerpc/pSeries_reconfig.h (renamed from include/asm-ppc64/pSeries_reconfig.h)0
-rw-r--r--include/asm-powerpc/paca.h (renamed from include/asm-ppc64/paca.h)30
-rw-r--r--include/asm-powerpc/parport.h (renamed from include/asm-ppc/parport.h)6
-rw-r--r--include/asm-powerpc/pmac_feature.h (renamed from include/asm-ppc/pmac_feature.h)0
-rw-r--r--include/asm-powerpc/pmac_low_i2c.h (renamed from include/asm-ppc/pmac_low_i2c.h)0
-rw-r--r--include/asm-powerpc/pmc.h47
-rw-r--r--include/asm-powerpc/posix_types.h (renamed from include/asm-ppc64/posix_types.h)40
-rw-r--r--include/asm-powerpc/ppc-pci.h99
-rw-r--r--include/asm-powerpc/ppc_asm.h (renamed from include/asm-ppc/ppc_asm.h)283
-rw-r--r--include/asm-powerpc/processor.h287
-rw-r--r--include/asm-powerpc/prom.h227
-rw-r--r--include/asm-powerpc/ptrace.h (renamed from include/asm-ppc64/ptrace.h)143
-rw-r--r--include/asm-powerpc/reg.h (renamed from include/asm-ppc/reg.h)309
-rw-r--r--include/asm-powerpc/reg_8xx.h42
-rw-r--r--include/asm-powerpc/rtas.h (renamed from include/asm-ppc64/rtas.h)33
-rw-r--r--include/asm-powerpc/rtc.h78
-rw-r--r--include/asm-powerpc/rwsem.h (renamed from include/asm-ppc64/rwsem.h)23
-rw-r--r--include/asm-powerpc/scatterlist.h (renamed from include/asm-ppc64/scatterlist.h)24
-rw-r--r--include/asm-powerpc/seccomp.h (renamed from include/asm-ppc64/seccomp.h)11
-rw-r--r--include/asm-powerpc/sections.h (renamed from include/asm-ppc64/sections.h)21
-rw-r--r--include/asm-powerpc/semaphore.h (renamed from include/asm-ppc64/semaphore.h)9
-rw-r--r--include/asm-powerpc/sigcontext.h (renamed from include/asm-ppc64/sigcontext.h)41
-rw-r--r--include/asm-powerpc/signal.h (renamed from include/asm-ppc/signal.h)41
-rw-r--r--include/asm-powerpc/smp.h (renamed from include/asm-ppc64/smp.h)48
-rw-r--r--include/asm-powerpc/smu.h (renamed from include/asm-ppc64/smu.h)199
-rw-r--r--include/asm-powerpc/sparsemem.h (renamed from include/asm-ppc64/sparsemem.h)10
-rw-r--r--include/asm-powerpc/spinlock_types.h (renamed from include/asm-ppc64/spinlock_types.h)4
-rw-r--r--include/asm-powerpc/sstep.h (renamed from include/asm-ppc64/sstep.h)4
-rw-r--r--include/asm-powerpc/stat.h81
-rw-r--r--include/asm-powerpc/statfs.h (renamed from include/asm-ppc64/statfs.h)19
-rw-r--r--include/asm-powerpc/synch.h51
-rw-r--r--include/asm-powerpc/system.h411
-rw-r--r--include/asm-powerpc/systemcfg.h (renamed from include/asm-ppc64/systemcfg.h)6
-rw-r--r--include/asm-powerpc/tce.h64
-rw-r--r--include/asm-powerpc/termios.h135
-rw-r--r--include/asm-powerpc/thread_info.h (renamed from include/asm-ppc64/thread_info.h)63
-rw-r--r--include/asm-powerpc/time.h226
-rw-r--r--include/asm-powerpc/tlb.h (renamed from include/asm-ppc/tlb.h)59
-rw-r--r--include/asm-powerpc/tlbflush.h147
-rw-r--r--include/asm-powerpc/types.h (renamed from include/asm-ppc64/types.h)37
-rw-r--r--include/asm-powerpc/uaccess.h464
-rw-r--r--include/asm-powerpc/ucontext.h40
-rw-r--r--include/asm-powerpc/uninorth.h (renamed from include/asm-ppc/uninorth.h)0
-rw-r--r--include/asm-powerpc/unistd.h (renamed from include/asm-ppc/unistd.h)92
-rw-r--r--include/asm-powerpc/vga.h (renamed from include/asm-ppc64/vga.h)20
-rw-r--r--include/asm-powerpc/vio.h (renamed from include/asm-ppc64/vio.h)22
-rw-r--r--include/asm-powerpc/xmon.h12
-rw-r--r--include/asm-ppc/a.out.h26
-rw-r--r--include/asm-ppc/atomic.h214
-rw-r--r--include/asm-ppc/auxvec.h14
-rw-r--r--include/asm-ppc/bitops.h460
-rw-r--r--include/asm-ppc/btext.h22
-rw-r--r--include/asm-ppc/bug.h58
-rw-r--r--include/asm-ppc/byteorder.h76
-rw-r--r--include/asm-ppc/cache.h87
-rw-r--r--include/asm-ppc/cacheflush.h49
-rw-r--r--include/asm-ppc/checksum.h107
-rw-r--r--include/asm-ppc/commproc.h2
-rw-r--r--include/asm-ppc/cpm2.h3
-rw-r--r--include/asm-ppc/cputable.h129
-rw-r--r--include/asm-ppc/current.h11
-rw-r--r--include/asm-ppc/dma-mapping.h2
-rw-r--r--include/asm-ppc/elf.h151
-rw-r--r--include/asm-ppc/futex.h53
-rw-r--r--include/asm-ppc/hw_irq.h74
-rw-r--r--include/asm-ppc/i8259.h11
-rw-r--r--include/asm-ppc/ibm44x.h76
-rw-r--r--include/asm-ppc/ibm4xx.h4
-rw-r--r--include/asm-ppc/ibm_ocp.h19
-rw-r--r--include/asm-ppc/io.h23
-rw-r--r--include/asm-ppc/ipcbuf.h29
-rw-r--r--include/asm-ppc/kexec.h40
-rw-r--r--include/asm-ppc/kgdb.h2
-rw-r--r--include/asm-ppc/kmap_types.h25
-rw-r--r--include/asm-ppc/machdep.h4
-rw-r--r--include/asm-ppc/mmu_context.h6
-rw-r--r--include/asm-ppc/mpc8260.h4
-rw-r--r--include/asm-ppc/mpc83xx.h1
-rw-r--r--include/asm-ppc/mpc85xx.h3
-rw-r--r--include/asm-ppc/mpc8xx.h4
-rw-r--r--include/asm-ppc/mv64x60.h2
-rw-r--r--include/asm-ppc/open_pic.h3
-rw-r--r--include/asm-ppc/page.h18
-rw-r--r--include/asm-ppc/pci-bridge.h5
-rw-r--r--include/asm-ppc/pci.h6
-rw-r--r--include/asm-ppc/perfmon.h22
-rw-r--r--include/asm-ppc/pgtable.h3
-rw-r--r--include/asm-ppc/posix_types.h111
-rw-r--r--include/asm-ppc/ppc_sys.h2
-rw-r--r--include/asm-ppc/ppcboot.h6
-rw-r--r--include/asm-ppc/processor.h201
-rw-r--r--include/asm-ppc/prom.h2
-rw-r--r--include/asm-ppc/ptrace.h152
-rw-r--r--include/asm-ppc/rio.h18
-rw-r--r--include/asm-ppc/rwsem.h172
-rw-r--r--include/asm-ppc/scatterlist.h25
-rw-r--r--include/asm-ppc/seccomp.h10
-rw-r--r--include/asm-ppc/sections.h33
-rw-r--r--include/asm-ppc/semaphore.h111
-rw-r--r--include/asm-ppc/sigcontext.h15
-rw-r--r--include/asm-ppc/smp.h28
-rw-r--r--include/asm-ppc/spinlock.h8
-rw-r--r--include/asm-ppc/spinlock_types.h20
-rw-r--r--include/asm-ppc/stat.h69
-rw-r--r--include/asm-ppc/statfs.h8
-rw-r--r--include/asm-ppc/system.h28
-rw-r--r--include/asm-ppc/thread_info.h107
-rw-r--r--include/asm-ppc/tlbflush.h115
-rw-r--r--include/asm-ppc/types.h69
-rw-r--r--include/asm-ppc/uaccess.h393
-rw-r--r--include/asm-ppc/ucontext.h27
-rw-r--r--include/asm-ppc/vga.h46
-rw-r--r--include/asm-ppc/xmon.h17
-rw-r--r--include/asm-ppc64/atomic.h197
-rw-r--r--include/asm-ppc64/bitops.h360
-rw-r--r--include/asm-ppc64/bootinfo.h70
-rw-r--r--include/asm-ppc64/btext.h1
-rw-r--r--include/asm-ppc64/cache.h36
-rw-r--r--include/asm-ppc64/cputable.h167
-rw-r--r--include/asm-ppc64/current.h16
-rw-r--r--include/asm-ppc64/dbdma.h2
-rw-r--r--include/asm-ppc64/dma.h329
-rw-r--r--include/asm-ppc64/eeh.h46
-rw-r--r--include/asm-ppc64/hardirq.h27
-rw-r--r--include/asm-ppc64/ide.h30
-rw-r--r--include/asm-ppc64/io.h4
-rw-r--r--include/asm-ppc64/ipcbuf.h28
-rw-r--r--include/asm-ppc64/irq.h120
-rw-r--r--include/asm-ppc64/kexec.h41
-rw-r--r--include/asm-ppc64/keylargo.h2
-rw-r--r--include/asm-ppc64/kmap_types.h23
-rw-r--r--include/asm-ppc64/macio.h2
-rw-r--r--include/asm-ppc64/memory.h61
-rw-r--r--include/asm-ppc64/mmu.h213
-rw-r--r--include/asm-ppc64/mmu_context.h26
-rw-r--r--include/asm-ppc64/mmzone.h11
-rw-r--r--include/asm-ppc64/numnodes.h7
-rw-r--r--include/asm-ppc64/nvram.h2
-rw-r--r--include/asm-ppc64/of_device.h2
-rw-r--r--include/asm-ppc64/page.h149
-rw-r--r--include/asm-ppc64/parport.h18
-rw-r--r--include/asm-ppc64/pci-bridge.h23
-rw-r--r--include/asm-ppc64/pci.h10
-rw-r--r--include/asm-ppc64/pgalloc.h47
-rw-r--r--include/asm-ppc64/pgtable-4k.h91
-rw-r--r--include/asm-ppc64/pgtable-64k.h90
-rw-r--r--include/asm-ppc64/pgtable.h165
-rw-r--r--include/asm-ppc64/plpar_wrappers.h120
-rw-r--r--include/asm-ppc64/pmac_feature.h2
-rw-r--r--include/asm-ppc64/pmac_low_i2c.h2
-rw-r--r--include/asm-ppc64/ppc_asm.h242
-rw-r--r--include/asm-ppc64/ppcdebug.h108
-rw-r--r--include/asm-ppc64/processor.h558
-rw-r--r--include/asm-ppc64/prom.h16
-rw-r--r--include/asm-ppc64/signal.h132
-rw-r--r--include/asm-ppc64/spinlock.h2
-rw-r--r--include/asm-ppc64/stat.h60
-rw-r--r--include/asm-ppc64/system.h24
-rw-r--r--include/asm-ppc64/time.h124
-rw-r--r--include/asm-ppc64/tlb.h39
-rw-r--r--include/asm-ppc64/tlbflush.h55
-rw-r--r--include/asm-ppc64/uaccess.h341
-rw-r--r--include/asm-ppc64/ucontext.h22
-rw-r--r--include/asm-ppc64/udbg.h6
-rw-r--r--include/asm-ppc64/uninorth.h2
-rw-r--r--include/asm-ppc64/unistd.h487
-rw-r--r--include/asm-s390/bitops.h4
-rw-r--r--include/asm-s390/debug.h16
-rw-r--r--include/asm-s390/ebcdic.h2
-rw-r--r--include/asm-s390/elf.h1
-rw-r--r--include/asm-s390/io.h8
-rw-r--r--include/asm-s390/lowcore.h2
-rw-r--r--include/asm-s390/mmu_context.h2
-rw-r--r--include/asm-s390/pgtable.h69
-rw-r--r--include/asm-s390/ptrace.h2
-rw-r--r--include/asm-s390/rwsem.h5
-rw-r--r--include/asm-s390/semaphore.h3
-rw-r--r--include/asm-s390/setup.h50
-rw-r--r--include/asm-s390/sigp.h6
-rw-r--r--include/asm-s390/smp.h2
-rw-r--r--include/asm-s390/uaccess.h28
-rw-r--r--include/asm-s390/unistd.h1
-rw-r--r--include/asm-s390/vtoc.h505
-rw-r--r--include/asm-sh/dma-mapping.h4
-rw-r--r--include/asm-sh/elf.h1
-rw-r--r--include/asm-sh/ide.h4
-rw-r--r--include/asm-sh/machvec.h2
-rw-r--r--include/asm-sh/mmzone.h61
-rw-r--r--include/asm-sh/page.h7
-rw-r--r--include/asm-sh/pgtable.h6
-rw-r--r--include/asm-sh/rwsem.h5
-rw-r--r--include/asm-sh/semaphore.h3
-rw-r--r--include/asm-sh/unistd.h1
-rw-r--r--include/asm-sh64/dma-mapping.h2
-rw-r--r--include/asm-sh64/ide.h4
-rw-r--r--include/asm-sh64/pgtable.h5
-rw-r--r--include/asm-sh64/semaphore.h3
-rw-r--r--include/asm-sparc/audioio.h234
-rw-r--r--include/asm-sparc/dma-mapping.h2
-rw-r--r--include/asm-sparc/floppy.h2
-rw-r--r--include/asm-sparc/kbio.h56
-rw-r--r--include/asm-sparc/pgtable.h2
-rw-r--r--include/asm-sparc/ptrace.h3
-rw-r--r--include/asm-sparc/semaphore.h3
-rw-r--r--include/asm-sparc/termios.h9
-rw-r--r--include/asm-sparc/vuid_event.h41
-rw-r--r--include/asm-sparc64/audioio.h234
-rw-r--r--include/asm-sparc64/dma-mapping.h2
-rw-r--r--include/asm-sparc64/ebus.h1
-rw-r--r--include/asm-sparc64/kbio.h56
-rw-r--r--include/asm-sparc64/kprobes.h20
-rw-r--r--include/asm-sparc64/mmu_context.h46
-rw-r--r--include/asm-sparc64/pgtable.h3
-rw-r--r--include/asm-sparc64/ptrace.h3
-rw-r--r--include/asm-sparc64/rwsem.h5
-rw-r--r--include/asm-sparc64/semaphore.h3
-rw-r--r--include/asm-sparc64/termios.h9
-rw-r--r--include/asm-sparc64/tlb.h37
-rw-r--r--include/asm-sparc64/vuid_event.h40
-rw-r--r--include/asm-um/cache.h19
-rw-r--r--include/asm-um/dma-mapping.h2
-rw-r--r--include/asm-um/ldt-i386.h69
-rw-r--r--include/asm-um/ldt.h69
-rw-r--r--include/asm-um/linkage.h8
-rw-r--r--include/asm-um/mmu_context.h3
-rw-r--r--include/asm-um/page.h2
-rw-r--r--include/asm-um/pgtable.h2
-rw-r--r--include/asm-v850/atomic.h2
-rw-r--r--include/asm-v850/bitops.h6
-rw-r--r--include/asm-v850/delay.h4
-rw-r--r--include/asm-v850/hw_irq.h2
-rw-r--r--include/asm-v850/processor.h4
-rw-r--r--include/asm-v850/semaphore.h13
-rw-r--r--include/asm-v850/system.h2
-rw-r--r--include/asm-v850/tlbflush.h4
-rw-r--r--include/asm-v850/uaccess.h2
-rw-r--r--include/asm-v850/unaligned.h6
-rw-r--r--include/asm-v850/unistd.h1
-rw-r--r--include/asm-x86_64/dma-mapping.h33
-rw-r--r--include/asm-x86_64/elf.h2
-rw-r--r--include/asm-x86_64/kprobes.h19
-rw-r--r--include/asm-x86_64/msi.h4
-rw-r--r--include/asm-x86_64/mtrr.h33
-rw-r--r--include/asm-x86_64/pgtable.h4
-rw-r--r--include/asm-x86_64/rwsem.h5
-rw-r--r--include/asm-x86_64/semaphore.h3
-rw-r--r--include/asm-x86_64/smp.h6
-rw-r--r--include/asm-x86_64/swiotlb.h10
-rw-r--r--include/asm-x86_64/unistd.h2
-rw-r--r--include/asm-xtensa/dma-mapping.h2
-rw-r--r--include/asm-xtensa/elf.h2
-rw-r--r--include/asm-xtensa/pgtable.h3
-rw-r--r--include/asm-xtensa/semaphore.h4
-rw-r--r--include/keys/user-type.h47
-rw-r--r--include/linux/acct.h3
-rw-r--r--include/linux/aio.h5
-rw-r--r--include/linux/ata.h41
-rw-r--r--include/linux/audit.h4
-rw-r--r--include/linux/bio.h2
-rw-r--r--include/linux/bitmap.h6
-rw-r--r--include/linux/blkdev.h50
-rw-r--r--include/linux/buffer_head.h9
-rw-r--r--include/linux/cn_proc.h127
-rw-r--r--include/linux/compat_ioctl.h15
-rw-r--r--include/linux/config.h4
-rw-r--r--include/linux/connector.h8
-rw-r--r--include/linux/console_struct.h2
-rw-r--r--include/linux/cpu.h6
-rw-r--r--include/linux/cpufreq.h1
-rw-r--r--include/linux/cpumask.h20
-rw-r--r--include/linux/cyclomx.h2
-rw-r--r--include/linux/cycx_drv.h1
-rw-r--r--include/linux/dcache.h1
-rw-r--r--include/linux/device.h141
-rw-r--r--include/linux/dmi.h2
-rw-r--r--include/linux/dqblk_xfs.h20
-rw-r--r--include/linux/eeprom.h136
-rw-r--r--include/linux/elevator.h22
-rw-r--r--include/linux/etherdevice.h35
-rw-r--r--include/linux/ethtool.h11
-rw-r--r--include/linux/fb.h28
-rw-r--r--include/linux/file.h6
-rw-r--r--include/linux/font.h2
-rw-r--r--include/linux/fs.h39
-rw-r--r--include/linux/fs_enet_pd.h135
-rw-r--r--include/linux/fsl_devices.h13
-rw-r--r--include/linux/fuse.h30
-rw-r--r--include/linux/gameport.h1
-rw-r--r--include/linux/genetlink.h51
-rw-r--r--include/linux/genhd.h13
-rw-r--r--include/linux/gfp.h39
-rw-r--r--include/linux/hil.h483
-rw-r--r--include/linux/hil_mlc.h168
-rw-r--r--include/linux/hp_sdc.h300
-rw-r--r--include/linux/hugetlb.h2
-rw-r--r--include/linux/i2c-algo-bit.h4
-rw-r--r--include/linux/i2c-algo-pca.h2
-rw-r--r--include/linux/i2c-algo-pcf.h4
-rw-r--r--include/linux/i2c-dev.h2
-rw-r--r--include/linux/i2c-id.h21
-rw-r--r--include/linux/i2c.h39
-rw-r--r--include/linux/i2o.h16
-rw-r--r--include/linux/ibmtr.h4
-rw-r--r--include/linux/ide.h10
-rw-r--r--include/linux/idr.h2
-rw-r--r--include/linux/if_arp.h1
-rw-r--r--include/linux/if_ether.h4
-rw-r--r--include/linux/if_ppp.h7
-rw-r--r--include/linux/if_wanpipe_common.h2
-rw-r--r--include/linux/input.h29
-rw-r--r--include/linux/ioport.h2
-rw-r--r--include/linux/ipmi.h5
-rw-r--r--include/linux/irq.h1
-rw-r--r--include/linux/istallion.h2
-rw-r--r--include/linux/jbd.h7
-rw-r--r--include/linux/jffs2.h41
-rw-r--r--include/linux/jffs2_fs_i.h7
-rw-r--r--include/linux/jffs2_fs_sb.h19
-rw-r--r--include/linux/kernel.h5
-rw-r--r--include/linux/kernel_stat.h8
-rw-r--r--include/linux/key-ui.h3
-rw-r--r--include/linux/key.h13
-rw-r--r--include/linux/kobj_map.h2
-rw-r--r--include/linux/kobject.h2
-rw-r--r--include/linux/kprobes.h40
-rw-r--r--include/linux/kthread.h12
-rw-r--r--include/linux/libata.h201
-rw-r--r--include/linux/list.h13
-rw-r--r--include/linux/loop.h2
-rw-r--r--include/linux/mbcache.h2
-rw-r--r--include/linux/memory.h97
-rw-r--r--include/linux/memory_hotplug.h104
-rw-r--r--include/linux/mempolicy.h13
-rw-r--r--include/linux/mii.h1
-rw-r--r--include/linux/mm.h160
-rw-r--r--include/linux/mmc/mmc.h4
-rw-r--r--include/linux/mmzone.h30
-rw-r--r--include/linux/mod_devicetable.h5
-rw-r--r--include/linux/module.h4
-rw-r--r--include/linux/mount.h29
-rw-r--r--include/linux/msdos_fs.h11
-rw-r--r--include/linux/mtd/bbm.h122
-rw-r--r--include/linux/mtd/blktrans.h4
-rw-r--r--include/linux/mtd/cfi.h34
-rw-r--r--include/linux/mtd/doc2000.h18
-rw-r--r--include/linux/mtd/flashchip.h14
-rw-r--r--include/linux/mtd/ftl.h6
-rw-r--r--include/linux/mtd/gen_probe.h4
-rw-r--r--include/linux/mtd/jedec.h20
-rw-r--r--include/linux/mtd/map.h17
-rw-r--r--include/linux/mtd/mtd.h37
-rw-r--r--include/linux/mtd/nand.h57
-rw-r--r--include/linux/mtd/onenand.h155
-rw-r--r--include/linux/mtd/onenand_regs.h180
-rw-r--r--include/linux/mtd/partitions.h20
-rw-r--r--include/linux/mtd/physmap.h12
-rw-r--r--include/linux/mtd/pmc551.h12
-rw-r--r--include/linux/mtd/xip.h20
-rw-r--r--include/linux/namei.h10
-rw-r--r--include/linux/namespace.h3
-rw-r--r--include/linux/net.h1
-rw-r--r--include/linux/netdevice.h14
-rw-r--r--include/linux/netfilter/nf_conntrack_common.h159
-rw-r--r--include/linux/netfilter/nf_conntrack_ftp.h44
-rw-r--r--include/linux/netfilter/nf_conntrack_sctp.h27
-rw-r--r--include/linux/netfilter/nf_conntrack_tcp.h56
-rw-r--r--include/linux/netfilter/nf_conntrack_tuple_common.h13
-rw-r--r--include/linux/netfilter/nfnetlink.h2
-rw-r--r--include/linux/netfilter_arp/arp_tables.h20
-rw-r--r--include/linux/netfilter_ipv4/ip_conntrack.h152
-rw-r--r--include/linux/netfilter_ipv4/ip_conntrack_ftp.h39
-rw-r--r--include/linux/netfilter_ipv4/ip_conntrack_icmp.h9
-rw-r--r--include/linux/netfilter_ipv4/ip_conntrack_sctp.h21
-rw-r--r--include/linux/netfilter_ipv4/ip_conntrack_tcp.h47
-rw-r--r--include/linux/netfilter_ipv4/ip_conntrack_tuple.h10
-rw-r--r--include/linux/netfilter_ipv6.h1
-rw-r--r--include/linux/netfilter_ipv6/ip6_tables.h27
-rw-r--r--include/linux/netlink.h24
-rw-r--r--include/linux/nfs_fs.h30
-rw-r--r--include/linux/nfs_xdr.h65
-rw-r--r--include/linux/nfsd/nfsd.h2
-rw-r--r--include/linux/nfsd/syscall.h17
-rw-r--r--include/linux/nfsd/xdr3.h2
-rw-r--r--include/linux/nodemask.h20
-rw-r--r--include/linux/pagemap.h13
-rw-r--r--include/linux/pci-acpi.h5
-rw-r--r--include/linux/pci.h20
-rw-r--r--include/linux/pci_ids.h578
-rw-r--r--include/linux/phonedev.h1
-rw-r--r--include/linux/phy.h3
-rw-r--r--include/linux/pkt_sched.h50
-rw-r--r--include/linux/platform_device.h46
-rw-r--r--include/linux/pm.h41
-rw-r--r--include/linux/pnp.h2
-rw-r--r--include/linux/ppp-comp.h9
-rw-r--r--include/linux/proc_fs.h10
-rw-r--r--include/linux/ptrace.h2
-rw-r--r--include/linux/quota.h1
-rw-r--r--include/linux/quotaops.h12
-rw-r--r--include/linux/radix-tree.h3
-rw-r--r--include/linux/raid/bitmap.h11
-rw-r--r--include/linux/raid/md.h5
-rw-r--r--include/linux/raid/md_k.h40
-rw-r--r--include/linux/raid/raid1.h4
-rw-r--r--include/linux/raid/raid5.h2
-rw-r--r--include/linux/rcupdate.h1
-rw-r--r--include/linux/reiserfs_fs.h2
-rw-r--r--include/linux/rio.h325
-rw-r--r--include/linux/rio_drv.h469
-rw-r--r--include/linux/rio_ids.h24
-rw-r--r--include/linux/rio_regs.h215
-rw-r--r--include/linux/rmap.h4
-rw-r--r--include/linux/rslib.h28
-rw-r--r--include/linux/rwsem-spinlock.h5
-rw-r--r--include/linux/scatterlist.h17
-rw-r--r--include/linux/sched.h75
-rw-r--r--include/linux/sdladrv.h4
-rw-r--r--include/linux/security.h86
-rw-r--r--include/linux/sem.h2
-rw-r--r--include/linux/serial.h1
-rw-r--r--include/linux/serial_8250.h3
-rw-r--r--include/linux/serial_core.h5
-rw-r--r--include/linux/serial_ip3106.h81
-rw-r--r--include/linux/shm.h1
-rw-r--r--include/linux/signal.h1
-rw-r--r--include/linux/skbuff.h94
-rw-r--r--include/linux/slab.h4
-rw-r--r--include/linux/spinlock.h31
-rw-r--r--include/linux/stallion.h2
-rw-r--r--include/linux/sunrpc/auth.h7
-rw-r--r--include/linux/sunrpc/debug.h3
-rw-r--r--include/linux/sunrpc/gss_api.h27
-rw-r--r--include/linux/sunrpc/gss_err.h10
-rw-r--r--include/linux/sunrpc/gss_krb5.h27
-rw-r--r--include/linux/sunrpc/gss_spkm3.h4
-rw-r--r--include/linux/sunrpc/msg_prot.h25
-rw-r--r--include/linux/sunrpc/svc.h3
-rw-r--r--include/linux/sunrpc/xdr.h6
-rw-r--r--include/linux/sunrpc/xprt.h227
-rw-r--r--include/linux/superhyway.h38
-rw-r--r--include/linux/suspend.h9
-rw-r--r--include/linux/swap.h4
-rw-r--r--include/linux/syscalls.h1
-rw-r--r--include/linux/sysctl.h41
-rw-r--r--include/linux/tcp.h16
-rw-r--r--include/linux/textsearch.h5
-rw-r--r--include/linux/timer.h17
-rw-r--r--include/linux/timex.h7
-rw-r--r--include/linux/types.h9
-rw-r--r--include/linux/usb.h171
-rw-r--r--include/linux/usb_gadget.h12
-rw-r--r--include/linux/usb_otg.h13
-rw-r--r--include/linux/usbdevice_fs.h7
-rw-r--r--include/linux/videodev.h82
-rw-r--r--include/linux/videodev2.h207
-rw-r--r--include/linux/vmalloc.h8
-rw-r--r--include/linux/wait.h1
-rw-r--r--include/linux/wanpipe.h9
-rw-r--r--include/linux/x1205.h31
-rw-r--r--include/linux/zutil.h1
-rw-r--r--include/media/audiochip.h17
-rw-r--r--include/media/id.h35
-rw-r--r--include/media/ir-common.h6
-rw-r--r--include/media/ir-kbd-i2c.h22
-rw-r--r--include/media/ovcamchip.h14
-rw-r--r--include/media/saa7146_vv.h2
-rw-r--r--include/media/tuner.h22
-rw-r--r--include/media/video-buf.h4
-rw-r--r--include/mtd/inftl-user.h4
-rw-r--r--include/mtd/mtd-abi.h7
-rw-r--r--include/mtd/nftl-user.h4
-rw-r--r--include/net/ax25.h3
-rw-r--r--include/net/bluetooth/bluetooth.h10
-rw-r--r--include/net/bluetooth/hci.h116
-rw-r--r--include/net/bluetooth/hci_core.h9
-rw-r--r--include/net/bluetooth/rfcomm.h5
-rw-r--r--include/net/dst.h1
-rw-r--r--include/net/genetlink.h154
-rw-r--r--include/net/ieee80211.h525
-rw-r--r--include/net/ieee80211_crypt.h39
-rw-r--r--include/net/ieee80211_radiotap.h231
-rw-r--r--include/net/inet_ecn.h28
-rw-r--r--include/net/inet_hashtables.h2
-rw-r--r--include/net/ipv6.h67
-rw-r--r--include/net/netfilter/ipv4/nf_conntrack_icmp.h11
-rw-r--r--include/net/netfilter/ipv4/nf_conntrack_ipv4.h43
-rw-r--r--include/net/netfilter/ipv6/nf_conntrack_icmpv6.h27
-rw-r--r--include/net/netfilter/nf_conntrack.h354
-rw-r--r--include/net/netfilter/nf_conntrack_compat.h108
-rw-r--r--include/net/netfilter/nf_conntrack_core.h76
-rw-r--r--include/net/netfilter/nf_conntrack_helper.h51
-rw-r--r--include/net/netfilter/nf_conntrack_l3proto.h93
-rw-r--r--include/net/netfilter/nf_conntrack_protocol.h105
-rw-r--r--include/net/netfilter/nf_conntrack_tuple.h190
-rw-r--r--include/net/netlink.h883
-rw-r--r--include/net/netrom.h3
-rw-r--r--include/net/red.h325
-rw-r--r--include/net/sctp/user.h8
-rw-r--r--include/net/sock.h28
-rw-r--r--include/net/syncppp.h1
-rw-r--r--include/net/tcp.h74
-rw-r--r--include/pcmcia/ss.h1
-rw-r--r--include/rdma/ib_cm.h10
-rw-r--r--include/rdma/ib_mad.h66
-rw-r--r--include/rdma/ib_user_cm.h27
-rw-r--r--include/rdma/ib_user_verbs.h229
-rw-r--r--include/rdma/ib_verbs.h8
-rw-r--r--include/scsi/iscsi_if.h245
-rw-r--r--include/scsi/iscsi_proto.h589
-rw-r--r--include/scsi/scsi.h3
-rw-r--r--include/scsi/scsi_cmnd.h3
-rw-r--r--include/scsi/scsi_device.h22
-rw-r--r--include/scsi/scsi_host.h6
-rw-r--r--include/scsi/scsi_request.h2
-rw-r--r--include/scsi/scsi_transport_fc.h34
-rw-r--r--include/scsi/scsi_transport_iscsi.h202
-rw-r--r--include/scsi/scsi_transport_sas.h27
-rw-r--r--include/scsi/srp.h226
-rw-r--r--include/sound/ac97_codec.h10
-rw-r--r--include/sound/core.h94
-rw-r--r--include/sound/driver.h17
-rw-r--r--include/sound/emu10k1.h4
-rw-r--r--include/sound/memalloc.h2
-rw-r--r--include/sound/minors.h8
-rw-r--r--include/sound/pcm.h3
-rw-r--r--include/sound/timer.h1
-rw-r--r--include/sound/version.h4
-rw-r--r--init/Kconfig8
-rw-r--r--init/main.c4
-rw-r--r--ipc/mqueue.c2
-rw-r--r--ipc/shm.c17
-rw-r--r--ipc/util.c9
-rw-r--r--kernel/Makefile2
-rw-r--r--kernel/acct.c94
-rw-r--r--kernel/audit.c6
-rw-r--r--kernel/auditsc.c2
-rw-r--r--kernel/cpu.c34
-rw-r--r--kernel/cpuset.c466
-rw-r--r--kernel/exit.c36
-rw-r--r--kernel/fork.c40
-rw-r--r--kernel/futex.c11
-rw-r--r--kernel/irq/handle.c6
-rw-r--r--kernel/irq/manage.c1
-rw-r--r--kernel/kallsyms.c1
-rw-r--r--kernel/kexec.c11
-rw-r--r--kernel/kmod.c6
-rw-r--r--kernel/kprobes.c135
-rw-r--r--kernel/kthread.c13
-rw-r--r--kernel/module.c1
-rw-r--r--kernel/params.c1
-rw-r--r--kernel/posix-cpu-timers.c22
-rw-r--r--kernel/posix-timers.c19
-rw-r--r--kernel/power/Makefile2
-rw-r--r--kernel/power/disk.c22
-rw-r--r--kernel/power/main.c5
-rw-r--r--kernel/power/power.h17
-rw-r--r--kernel/power/snapshot.c453
-rw-r--r--kernel/power/swsusp.c756
-rw-r--r--kernel/printk.c79
-rw-r--r--kernel/ptrace.c91
-rw-r--r--kernel/rcupdate.c10
-rw-r--r--kernel/rcutorture.c492
-rw-r--r--kernel/sched.c170
-rw-r--r--kernel/signal.c152
-rw-r--r--kernel/softirq.c3
-rw-r--r--kernel/softlockup.c6
-rw-r--r--kernel/sys.c24
-rw-r--r--kernel/sysctl.c141
-rw-r--r--kernel/time.c26
-rw-r--r--kernel/timer.c337
-rw-r--r--kernel/workqueue.c35
-rw-r--r--lib/Kconfig.debug27
-rw-r--r--lib/Makefile2
-rw-r--r--lib/bitmap.c166
-rw-r--r--lib/extable.c3
-rw-r--r--lib/idr.c37
-rw-r--r--lib/kobject.c3
-rw-r--r--lib/kobject_uevent.c6
-rw-r--r--lib/radix-tree.c51
-rw-r--r--lib/reed_solomon/Makefile2
-rw-r--r--lib/reed_solomon/decode_rs.c36
-rw-r--r--lib/reed_solomon/encode_rs.c14
-rw-r--r--lib/reed_solomon/reed_solomon.c64
-rw-r--r--lib/smp_processor_id.c1
-rw-r--r--lib/sort.c1
-rw-r--r--lib/string.c125
-rw-r--r--lib/swiotlb.c (renamed from arch/ia64/lib/swiotlb.c)246
-rw-r--r--lib/textsearch.c2
-rw-r--r--lib/vsprintf.c1
-rw-r--r--lib/zlib_inflate/inflate.c1
-rw-r--r--mm/Kconfig23
-rw-r--r--mm/Makefile2
-rw-r--r--mm/bootmem.c1
-rw-r--r--mm/filemap.c24
-rw-r--r--mm/filemap_xip.c22
-rw-r--r--mm/fremap.c86
-rw-r--r--mm/highmem.c14
-rw-r--r--mm/hugetlb.c211
-rw-r--r--mm/madvise.c2
-rw-r--r--mm/memory.c993
-rw-r--r--mm/memory_hotplug.c138
-rw-r--r--mm/mempolicy.c463
-rw-r--r--mm/mempool.c2
-rw-r--r--mm/mmap.c132
-rw-r--r--mm/mprotect.c19
-rw-r--r--mm/mremap.c193
-rw-r--r--mm/msync.c78
-rw-r--r--mm/nommu.c22
-rw-r--r--mm/page-writeback.c1
-rw-r--r--mm/page_alloc.c241
-rw-r--r--mm/page_io.c6
-rw-r--r--mm/pdflush.c13
-rw-r--r--mm/readahead.c31
-rw-r--r--mm/rmap.c146
-rw-r--r--mm/shmem.c32
-rw-r--r--mm/slab.c87
-rw-r--r--mm/sparse.c99
-rw-r--r--mm/swap.c11
-rw-r--r--mm/swap_state.c12
-rw-r--r--mm/swapfile.c43
-rw-r--r--mm/thrash.c2
-rw-r--r--mm/tiny-shmem.c5
-rw-r--r--mm/truncate.c11
-rw-r--r--mm/vmalloc.c77
-rw-r--r--mm/vmscan.c14
-rw-r--r--net/802/p8023.c3
-rw-r--r--net/ax25/af_ax25.c6
-rw-r--r--net/ax25/ax25_in.c6
-rw-r--r--net/ax25/ax25_route.c19
-rw-r--r--net/bluetooth/af_bluetooth.c18
-rw-r--r--net/bluetooth/hci_core.c6
-rw-r--r--net/bluetooth/hci_event.c6
-rw-r--r--net/bluetooth/hci_sock.c14
-rw-r--r--net/bluetooth/hci_sysfs.c4
-rw-r--r--net/bluetooth/hidp/Kconfig2
-rw-r--r--net/bluetooth/hidp/core.c17
-rw-r--r--net/bluetooth/l2cap.c98
-rw-r--r--net/bluetooth/rfcomm/Makefile2
-rw-r--r--net/bluetooth/rfcomm/core.c167
-rw-r--r--net/bluetooth/rfcomm/crc.c71
-rw-r--r--net/bluetooth/rfcomm/sock.c90
-rw-r--r--net/bluetooth/sco.c92
-rw-r--r--net/bridge/br_fdb.c12
-rw-r--r--net/bridge/br_input.c2
-rw-r--r--net/bridge/br_stp_if.c9
-rw-r--r--net/core/datagram.c25
-rw-r--r--net/core/dev.c26
-rw-r--r--net/core/dev_mcast.c3
-rw-r--r--net/core/ethtool.c53
-rw-r--r--net/core/neighbour.c5
-rw-r--r--net/core/netpoll.c18
-rw-r--r--net/core/pktgen.c506
-rw-r--r--net/core/rtnetlink.c83
-rw-r--r--net/core/skbuff.c92
-rw-r--r--net/core/sock.c5
-rw-r--r--net/core/stream.c12
-rw-r--r--net/dccp/dccp.h1
-rw-r--r--net/dccp/ipv4.c38
-rw-r--r--net/dccp/output.c36
-rw-r--r--net/dccp/proto.c3
-rw-r--r--net/decnet/af_decnet.c13
-rw-r--r--net/decnet/dn_table.c14
-rw-r--r--net/ethernet/eth.c17
-rw-r--r--net/ethernet/pe2.c3
-rw-r--r--net/ieee80211/Makefile3
-rw-r--r--net/ieee80211/ieee80211_crypt.c186
-rw-r--r--net/ieee80211/ieee80211_crypt_ccmp.c76
-rw-r--r--net/ieee80211/ieee80211_crypt_tkip.c151
-rw-r--r--net/ieee80211/ieee80211_crypt_wep.c27
-rw-r--r--net/ieee80211/ieee80211_geo.c140
-rw-r--r--net/ieee80211/ieee80211_module.c66
-rw-r--r--net/ieee80211/ieee80211_rx.c613
-rw-r--r--net/ieee80211/ieee80211_tx.c322
-rw-r--r--net/ieee80211/ieee80211_wx.c376
-rw-r--r--net/ipv4/af_inet.c3
-rw-r--r--net/ipv4/devinet.c3
-rw-r--r--net/ipv4/fib_frontend.c5
-rw-r--r--net/ipv4/fib_trie.c2
-rw-r--r--net/ipv4/icmp.c11
-rw-r--r--net/ipv4/igmp.c24
-rw-r--r--net/ipv4/inet_connection_sock.c14
-rw-r--r--net/ipv4/inet_diag.c9
-rw-r--r--net/ipv4/ip_gre.c15
-rw-r--r--net/ipv4/ip_options.c3
-rw-r--r--net/ipv4/ip_output.c103
-rw-r--r--net/ipv4/ip_sockglue.c12
-rw-r--r--net/ipv4/ipvs/ip_vs_app.c6
-rw-r--r--net/ipv4/ipvs/ip_vs_core.c7
-rw-r--r--net/ipv4/multipath_wrandom.c10
-rw-r--r--net/ipv4/netfilter/Kconfig41
-rw-r--r--net/ipv4/netfilter/Makefile6
-rw-r--r--net/ipv4/netfilter/arp_tables.c201
-rw-r--r--net/ipv4/netfilter/ip_conntrack_core.c132
-rw-r--r--net/ipv4/netfilter/ip_conntrack_helper_pptp.c4
-rw-r--r--net/ipv4/netfilter/ip_conntrack_netlink.c104
-rw-r--r--net/ipv4/netfilter/ip_conntrack_proto_icmp.c26
-rw-r--r--net/ipv4/netfilter/ip_conntrack_proto_tcp.c11
-rw-r--r--net/ipv4/netfilter/ip_nat_core.c6
-rw-r--r--net/ipv4/netfilter/ip_nat_helper_pptp.c30
-rw-r--r--net/ipv4/netfilter/ip_nat_proto_gre.c4
-rw-r--r--net/ipv4/netfilter/ip_nat_proto_unknown.c2
-rw-r--r--net/ipv4/netfilter/ip_nat_snmp_basic.c3
-rw-r--r--net/ipv4/netfilter/ipt_CLUSTERIP.c12
-rw-r--r--net/ipv4/netfilter/ipt_CONNMARK.c23
-rw-r--r--net/ipv4/netfilter/ipt_NOTRACK.c4
-rw-r--r--net/ipv4/netfilter/ipt_addrtype.c2
-rw-r--r--net/ipv4/netfilter/ipt_connbytes.c39
-rw-r--r--net/ipv4/netfilter/ipt_connmark.c10
-rw-r--r--net/ipv4/netfilter/ipt_conntrack.c96
-rw-r--r--net/ipv4/netfilter/ipt_helper.c54
-rw-r--r--net/ipv4/netfilter/ipt_state.c6
-rw-r--r--net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c571
-rw-r--r--net/ipv4/netfilter/nf_conntrack_proto_icmp.c301
-rw-r--r--net/ipv4/proc.c4
-rw-r--r--net/ipv4/sysctl_net_ipv4.c8
-rw-r--r--net/ipv4/tcp.c4
-rw-r--r--net/ipv4/tcp_bic.c14
-rw-r--r--net/ipv4/tcp_cong.c40
-rw-r--r--net/ipv4/tcp_highspeed.c11
-rw-r--r--net/ipv4/tcp_htcp.c13
-rw-r--r--net/ipv4/tcp_hybla.c6
-rw-r--r--net/ipv4/tcp_input.c288
-rw-r--r--net/ipv4/tcp_ipv4.c33
-rw-r--r--net/ipv4/tcp_minisocks.c7
-rw-r--r--net/ipv4/tcp_output.c61
-rw-r--r--net/ipv4/tcp_scalable.c14
-rw-r--r--net/ipv4/tcp_timer.c4
-rw-r--r--net/ipv4/tcp_vegas.c42
-rw-r--r--net/ipv4/udp.c7
-rw-r--r--net/ipv6/addrconf.c446
-rw-r--r--net/ipv6/icmp.c30
-rw-r--r--net/ipv6/ip6_fib.c54
-rw-r--r--net/ipv6/ip6_input.c5
-rw-r--r--net/ipv6/ip6_output.c92
-rw-r--r--net/ipv6/ip6_tunnel.c7
-rw-r--r--net/ipv6/ipcomp6.c3
-rw-r--r--net/ipv6/ipv6_sockglue.c3
-rw-r--r--net/ipv6/ipv6_syms.c2
-rw-r--r--net/ipv6/mcast.c25
-rw-r--r--net/ipv6/netfilter/Kconfig14
-rw-r--r--net/ipv6/netfilter/Makefile6
-rw-r--r--net/ipv6/netfilter/ip6_tables.c298
-rw-r--r--net/ipv6/netfilter/ip6t_MARK.c8
-rw-r--r--net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c556
-rw-r--r--net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c272
-rw-r--r--net/ipv6/netfilter/nf_conntrack_reasm.c885
-rw-r--r--net/ipv6/proc.c4
-rw-r--r--net/ipv6/raw.c46
-rw-r--r--net/ipv6/route.c4
-rw-r--r--net/ipv6/tcp_ipv6.c35
-rw-r--r--net/ipv6/udp.c25
-rw-r--r--net/irda/discovery.c3
-rw-r--r--net/irda/irias_object.c16
-rw-r--r--net/netfilter/Kconfig74
-rw-r--r--net/netfilter/Makefile8
-rw-r--r--net/netfilter/nf_conntrack_core.c1538
-rw-r--r--net/netfilter/nf_conntrack_ftp.c698
-rw-r--r--net/netfilter/nf_conntrack_l3proto_generic.c98
-rw-r--r--net/netfilter/nf_conntrack_proto_generic.c85
-rw-r--r--net/netfilter/nf_conntrack_proto_sctp.c670
-rw-r--r--net/netfilter/nf_conntrack_proto_tcp.c1162
-rw-r--r--net/netfilter/nf_conntrack_proto_udp.c216
-rw-r--r--net/netfilter/nf_conntrack_standalone.c869
-rw-r--r--net/netfilter/nf_queue.c2
-rw-r--r--net/netfilter/nfnetlink.c21
-rw-r--r--net/netfilter/nfnetlink_log.c6
-rw-r--r--net/netfilter/nfnetlink_queue.c6
-rw-r--r--net/netlink/Makefile2
-rw-r--r--net/netlink/af_netlink.c102
-rw-r--r--net/netlink/attr.c328
-rw-r--r--net/netlink/genetlink.c579
-rw-r--r--net/rose/rose_route.c8
-rw-r--r--net/rose/rose_timer.c1
-rw-r--r--net/rxrpc/transport.c15
-rw-r--r--net/sched/Kconfig394
-rw-r--r--net/sched/cls_fw.c3
-rw-r--r--net/sched/cls_route.c3
-rw-r--r--net/sched/cls_rsvp.h3
-rw-r--r--net/sched/cls_tcindex.c9
-rw-r--r--net/sched/cls_u32.c4
-rw-r--r--net/sched/em_meta.c3
-rw-r--r--net/sched/ematch.c5
-rw-r--r--net/sched/sch_gred.c841
-rw-r--r--net/sched/sch_netem.c122
-rw-r--r--net/sched/sch_red.c418
-rw-r--r--net/sctp/associola.c4
-rw-r--r--net/sctp/proc.c4
-rw-r--r--net/sctp/sm_make_chunk.c8
-rw-r--r--net/sctp/socket.c90
-rw-r--r--net/sctp/ulpevent.c6
-rw-r--r--net/sunrpc/Makefile2
-rw-r--r--net/sunrpc/auth.c16
-rw-r--r--net/sunrpc/auth_gss/Makefile2
-rw-r--r--net/sunrpc/auth_gss/auth_gss.c187
-rw-r--r--net/sunrpc/auth_gss/gss_krb5_crypto.c275
-rw-r--r--net/sunrpc/auth_gss/gss_krb5_mech.c41
-rw-r--r--net/sunrpc/auth_gss/gss_krb5_seal.c46
-rw-r--r--net/sunrpc/auth_gss/gss_krb5_unseal.c41
-rw-r--r--net/sunrpc/auth_gss/gss_krb5_wrap.c363
-rw-r--r--net/sunrpc/auth_gss/gss_mech_switch.c32
-rw-r--r--net/sunrpc/auth_gss/gss_spkm3_mech.c21
-rw-r--r--net/sunrpc/auth_gss/gss_spkm3_seal.c7
-rw-r--r--net/sunrpc/auth_gss/gss_spkm3_token.c3
-rw-r--r--net/sunrpc/auth_gss/gss_spkm3_unseal.c8
-rw-r--r--net/sunrpc/auth_gss/svcauth_gss.c9
-rw-r--r--net/sunrpc/auth_null.c2
-rw-r--r--net/sunrpc/auth_unix.c2
-rw-r--r--net/sunrpc/clnt.c177
-rw-r--r--net/sunrpc/pmap_clnt.c12
-rw-r--r--net/sunrpc/rpc_pipe.c35
-rw-r--r--net/sunrpc/socklib.c180
-rw-r--r--net/sunrpc/sunrpc_syms.c3
-rw-r--r--net/sunrpc/svc.c21
-rw-r--r--net/sunrpc/svcsock.c12
-rw-r--r--net/sunrpc/sysctl.c25
-rw-r--r--net/sunrpc/xdr.c180
-rw-r--r--net/sunrpc/xprt.c1613
-rw-r--r--net/sunrpc/xprtsock.c1261
-rw-r--r--net/unix/af_unix.c2
-rw-r--r--net/wanrouter/af_wanpipe.c20
-rw-r--r--net/wanrouter/wanmain.c12
-rw-r--r--net/xfrm/xfrm_policy.c43
-rw-r--r--net/xfrm/xfrm_state.c18
-rw-r--r--net/xfrm/xfrm_user.c69
-rw-r--r--scripts/kconfig/Makefile51
-rw-r--r--scripts/kconfig/conf.c37
-rw-r--r--scripts/kconfig/confdata.c112
-rw-r--r--scripts/kconfig/expr.h1
-rw-r--r--scripts/kconfig/lex.zconf.c_shipped1749
-rw-r--r--scripts/kconfig/lkc.h22
-rw-r--r--scripts/kconfig/lkc_proto.h1
-rw-r--r--scripts/kconfig/mconf.c3
-rw-r--r--scripts/kconfig/menu.c15
-rw-r--r--scripts/kconfig/symbol.c80
-rw-r--r--scripts/kconfig/zconf.gperf43
-rw-r--r--scripts/kconfig/zconf.hash.c_shipped231
-rw-r--r--scripts/kconfig/zconf.l96
-rw-r--r--scripts/kconfig/zconf.tab.c_shipped1177
-rw-r--r--scripts/kconfig/zconf.tab.h_shipped125
-rw-r--r--scripts/kconfig/zconf.y315
-rw-r--r--scripts/mod/file2alias.c10
-rw-r--r--security/dummy.c27
-rw-r--r--security/keys/key.c59
-rw-r--r--security/keys/keyctl.c13
-rw-r--r--security/keys/keyring.c25
-rw-r--r--security/keys/permission.c7
-rw-r--r--security/keys/process_keys.c9
-rw-r--r--security/keys/user_defined.c49
-rw-r--r--security/selinux/hooks.c85
-rw-r--r--security/selinux/netif.c3
-rw-r--r--security/selinux/selinuxfs.c93
-rw-r--r--security/selinux/ss/conditional.c12
-rw-r--r--security/selinux/ss/ebitmap.c9
-rw-r--r--security/selinux/ss/hashtab.c6
-rw-r--r--security/selinux/ss/mls.c5
-rw-r--r--security/selinux/ss/policydb.c63
-rw-r--r--security/selinux/ss/services.c11
-rw-r--r--sound/Kconfig8
-rw-r--r--sound/arm/aaci.c1
-rw-r--r--sound/arm/pxa2xx-ac97.c10
-rw-r--r--sound/core/Kconfig6
-rw-r--r--sound/core/Makefile3
-rw-r--r--sound/core/control.c18
-rw-r--r--sound/core/hwdep.c10
-rw-r--r--sound/core/info.c2
-rw-r--r--sound/core/init.c23
-rw-r--r--sound/core/memalloc.c4
-rw-r--r--sound/core/memory.c216
-rw-r--r--sound/core/misc.c14
-rw-r--r--sound/core/oss/mixer_oss.c62
-rw-r--r--sound/core/oss/pcm_oss.c20
-rw-r--r--sound/core/pcm.c3
-rw-r--r--sound/core/pcm_lib.c5
-rw-r--r--sound/core/pcm_native.c27
-rw-r--r--sound/core/rawmidi.c12
-rw-r--r--sound/core/rtctimer.c24
-rw-r--r--sound/core/seq/instr/ainstr_gf1.c5
-rw-r--r--sound/core/seq/instr/ainstr_iw.c4
-rw-r--r--sound/core/seq/instr/ainstr_simple.c3
-rw-r--r--sound/core/seq/seq_instr.c12
-rw-r--r--sound/core/seq/seq_lock.c3
-rw-r--r--sound/core/seq/seq_memory.c3
-rw-r--r--sound/core/seq/seq_midi.c2
-rw-r--r--sound/core/seq/seq_timer.c29
-rw-r--r--sound/core/sound.c26
-rw-r--r--sound/core/timer.c380
-rw-r--r--sound/core/wrappers.c50
-rw-r--r--sound/drivers/mpu401/mpu401_uart.c5
-rw-r--r--sound/drivers/mtpav.c5
-rw-r--r--sound/drivers/opl3/opl3_lib.c10
-rw-r--r--sound/drivers/opl4/opl4_lib.c10
-rw-r--r--sound/drivers/serial-u16550.c5
-rw-r--r--sound/drivers/vx/vx_hwdep.c1
-rw-r--r--sound/drivers/vx/vx_pcm.c4
-rw-r--r--sound/i2c/cs8427.c17
-rw-r--r--sound/i2c/other/ak4114.c6
-rw-r--r--sound/i2c/other/ak4117.c8
-rw-r--r--sound/i2c/tea6330t.c2
-rw-r--r--sound/isa/ad1816a/ad1816a_lib.c5
-rw-r--r--sound/isa/ad1848/ad1848_lib.c27
-rw-r--r--sound/isa/cs423x/cs4231_lib.c10
-rw-r--r--sound/isa/cs423x/cs4236.c8
-rw-r--r--sound/isa/cs423x/cs4236_lib.c5
-rw-r--r--sound/isa/es1688/es1688_lib.c3
-rw-r--r--sound/isa/es18xx.c49
-rw-r--r--sound/isa/gus/gus_dma.c2
-rw-r--r--sound/isa/gus/gus_io.c94
-rw-r--r--sound/isa/gus/gus_main.c25
-rw-r--r--sound/isa/gus/gus_mem.c2
-rw-r--r--sound/isa/gus/gus_pcm.c5
-rw-r--r--sound/isa/gus/gus_reset.c4
-rw-r--r--sound/isa/gus/gus_simple.c2
-rw-r--r--sound/isa/gus/gus_uart.c4
-rw-r--r--sound/isa/gus/gus_volume.c6
-rw-r--r--sound/isa/gus/interwave.c9
-rw-r--r--sound/isa/opl3sa2.c5
-rw-r--r--sound/isa/opti9xx/opti92x-ad1848.c25
-rw-r--r--sound/isa/sb/emu8000.c24
-rw-r--r--sound/isa/sb/emu8000_patch.c3
-rw-r--r--sound/isa/sb/emu8000_pcm.c3
-rw-r--r--sound/isa/sb/emu8000_synth.c2
-rw-r--r--sound/isa/sb/sb16.c5
-rw-r--r--sound/isa/sb/sb16_main.c8
-rw-r--r--sound/isa/sb/sb8.c5
-rw-r--r--sound/isa/sb/sb8_main.c3
-rw-r--r--sound/isa/sb/sb_common.c12
-rw-r--r--sound/isa/sb/sb_mixer.c4
-rw-r--r--sound/isa/sscape.c23
-rw-r--r--sound/isa/wavefront/wavefront.c5
-rw-r--r--sound/isa/wavefront/wavefront_synth.c6
-rw-r--r--sound/mips/au1x00.c13
-rw-r--r--sound/oss/Kconfig73
-rw-r--r--sound/oss/ac97_codec.c1
-rw-r--r--sound/oss/au1000.c6
-rw-r--r--sound/oss/au1550_ac97.c1
-rw-r--r--sound/oss/awe_wave.c2
-rw-r--r--sound/oss/cs4232.c6
-rw-r--r--sound/oss/dmasound/dmasound.h2
-rw-r--r--sound/oss/dmasound/dmasound_atari.c4
-rw-r--r--sound/oss/dmasound/dmasound_awacs.c35
-rw-r--r--sound/oss/dmasound/dmasound_paula.c4
-rw-r--r--sound/oss/dmasound/dmasound_q40.c4
-rw-r--r--sound/oss/msnd.c1
-rw-r--r--sound/oss/nec_vrc5477.c6
-rw-r--r--sound/oss/os.h2
-rw-r--r--sound/oss/rme96xx.c1
-rw-r--r--sound/oss/sequencer_syms.c1
-rw-r--r--sound/oss/sh_dac_audio.c1
-rw-r--r--sound/oss/soundcard.c4
-rw-r--r--sound/oss/wavfront.c38
-rw-r--r--sound/oss/ymfpci.c17
-rw-r--r--sound/parisc/harmony.c116
-rw-r--r--sound/parisc/harmony.h17
-rw-r--r--sound/pci/Kconfig9
-rw-r--r--sound/pci/ac97/ac97_bus.c6
-rw-r--r--sound/pci/ac97/ac97_codec.c56
-rw-r--r--sound/pci/ac97/ac97_patch.c80
-rw-r--r--sound/pci/ac97/ac97_pcm.c9
-rw-r--r--sound/pci/ad1889.c6
-rw-r--r--sound/pci/ali5451/ali5451.c93
-rw-r--r--sound/pci/als4000.c9
-rw-r--r--sound/pci/atiixp.c51
-rw-r--r--sound/pci/atiixp_modem.c38
-rw-r--r--sound/pci/au88x0/au8810.h5
-rw-r--r--sound/pci/au88x0/au8820.h5
-rw-r--r--sound/pci/au88x0/au8830.h5
-rw-r--r--sound/pci/au88x0/au88x0.c3
-rw-r--r--sound/pci/au88x0/au88x0.h8
-rw-r--r--sound/pci/au88x0/au88x0_a3d.c2
-rw-r--r--sound/pci/au88x0/au88x0_core.c10
-rw-r--r--sound/pci/au88x0/au88x0_eq.c2
-rw-r--r--sound/pci/au88x0/au88x0_synth.c8
-rw-r--r--sound/pci/azt3328.c1006
-rw-r--r--sound/pci/azt3328.h135
-rw-r--r--sound/pci/bt87x.c16
-rw-r--r--sound/pci/ca0106/Makefile2
-rw-r--r--sound/pci/ca0106/ca0106.h27
-rw-r--r--sound/pci/ca0106/ca0106_main.c124
-rw-r--r--sound/pci/ca0106/ca_midi.c306
-rw-r--r--sound/pci/ca0106/ca_midi.h69
-rw-r--r--sound/pci/cmipci.c127
-rw-r--r--sound/pci/cs4281.c7
-rw-r--r--sound/pci/cs46xx/cs46xx.c1
-rw-r--r--sound/pci/cs46xx/cs46xx_lib.c43
-rw-r--r--sound/pci/emu10k1/emu10k1.c3
-rw-r--r--sound/pci/emu10k1/emu10k1_callback.c4
-rw-r--r--sound/pci/emu10k1/emu10k1_main.c39
-rw-r--r--sound/pci/emu10k1/emu10k1x.c7
-rw-r--r--sound/pci/emu10k1/emufx.c59
-rw-r--r--sound/pci/emu10k1/emupcm.c3
-rw-r--r--sound/pci/emu10k1/irq.c2
-rw-r--r--sound/pci/emu10k1/memory.c6
-rw-r--r--sound/pci/emu10k1/p16v.c2
-rw-r--r--sound/pci/ens1370.c18
-rw-r--r--sound/pci/es1938.c39
-rw-r--r--sound/pci/es1968.c23
-rw-r--r--sound/pci/fm801.c26
-rw-r--r--sound/pci/hda/hda_codec.c52
-rw-r--r--sound/pci/hda/hda_codec.h2
-rw-r--r--sound/pci/hda/hda_intel.c73
-rw-r--r--sound/pci/hda/hda_local.h22
-rw-r--r--sound/pci/hda/hda_proc.c5
-rw-r--r--sound/pci/hda/patch_analog.c133
-rw-r--r--sound/pci/hda/patch_realtek.c274
-rw-r--r--sound/pci/hda/patch_si3054.c2
-rw-r--r--sound/pci/ice1712/aureon.c6
-rw-r--r--sound/pci/ice1712/delta.c2
-rw-r--r--sound/pci/ice1712/ews.c6
-rw-r--r--sound/pci/ice1712/ice1712.c11
-rw-r--r--sound/pci/ice1712/ice1724.c44
-rw-r--r--sound/pci/ice1712/pontis.c3
-rw-r--r--sound/pci/ice1712/revo.c13
-rw-r--r--sound/pci/ice1712/vt1720_mobo.c20
-rw-r--r--sound/pci/intel8x0.c161
-rw-r--r--sound/pci/intel8x0m.c56
-rw-r--r--sound/pci/korg1212/korg1212.c1
-rw-r--r--sound/pci/maestro3.c22
-rw-r--r--sound/pci/mixart/mixart.c4
-rw-r--r--sound/pci/nm256/nm256.c146
-rw-r--r--sound/pci/rme32.c5
-rw-r--r--sound/pci/rme96.c5
-rw-r--r--sound/pci/rme9652/hdsp.c589
-rw-r--r--sound/pci/rme9652/hdspm.c4
-rw-r--r--sound/pci/rme9652/rme9652.c7
-rw-r--r--sound/pci/sonicvibes.c25
-rw-r--r--sound/pci/trident/trident.c1
-rw-r--r--sound/pci/trident/trident_main.c18
-rw-r--r--sound/pci/trident/trident_memory.c4
-rw-r--r--sound/pci/via82xx.c376
-rw-r--r--sound/pci/via82xx_modem.c50
-rw-r--r--sound/pci/vx222/vx222.c1
-rw-r--r--sound/pci/ymfpci/ymfpci.c19
-rw-r--r--sound/pci/ymfpci/ymfpci_main.c75
-rw-r--r--sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c6
-rw-r--r--sound/ppc/beep.c68
-rw-r--r--sound/ppc/pmac.c16
-rw-r--r--sound/ppc/pmac.h1
-rw-r--r--sound/sound_core.c2
-rw-r--r--sound/sparc/cs4231.c654
-rw-r--r--sound/sparc/dbri.c5
-rw-r--r--sound/synth/emux/emux_synth.c1
-rw-r--r--sound/usb/usbaudio.c144
-rw-r--r--sound/usb/usbaudio.h8
-rw-r--r--sound/usb/usbmidi.c100
-rw-r--r--sound/usb/usbmixer.c2
-rw-r--r--sound/usb/usbquirks.h40
-rw-r--r--sound/usb/usx2y/usX2Yhwdep.c10
-rw-r--r--sound/usb/usx2y/usbusx2y.c5
-rw-r--r--sound/usb/usx2y/usbusx2yaudio.c23
-rw-r--r--sound/usb/usx2y/usx2yhwdeppcm.c4
5318 files changed, 361692 insertions, 206066 deletions
diff --git a/CREDITS b/CREDITS
index a347520bef2d..7fb4c73e0228 100644
--- a/CREDITS
+++ b/CREDITS
@@ -2247,6 +2247,12 @@ S: 249 Nichols Avenue
S: Syracuse, New York 13206
S: USA
+N: Kyle McMartin
+E: kyle@parisc-linux.org
+D: Linux/PARISC hacker
+D: AD1889 sound driver
+S: Ottawa, Canada
+
N: Dirk Melchers
E: dirk@merlin.nbg.sub.org
D: 8 bit XT hard disk driver for OMTI5520
@@ -3636,11 +3642,9 @@ S: Beaverton, OR 97005
S: USA
N: Michal Wronski
-E: wrona@mat.uni.torun.pl
-W: http://www.mat.uni.torun.pl/~wrona
+E: Michal.Wronski@motorola.com
D: POSIX message queues fs (with K. Benedyczak)
-S: ul. Teczowa 23/12
-S: 80-680 Gdansk-Sobieszewo
+S: Krakow
S: Poland
N: Frank Xia
diff --git a/Documentation/Changes b/Documentation/Changes
index 27232be26e1a..86b86399d61d 100644
--- a/Documentation/Changes
+++ b/Documentation/Changes
@@ -65,7 +65,7 @@ o isdn4k-utils 3.1pre1 # isdnctrl 2>&1|grep version
o nfs-utils 1.0.5 # showmount --version
o procps 3.2.0 # ps --version
o oprofile 0.9 # oprofiled --version
-o udev 058 # udevinfo -V
+o udev 071 # udevinfo -V
Kernel compilation
==================
@@ -139,9 +139,14 @@ You'll probably want to upgrade.
Ksymoops
--------
-If the unthinkable happens and your kernel oopses, you'll need a 2.4
-version of ksymoops to decode the report; see REPORTING-BUGS in the
-root of the Linux source for more information.
+If the unthinkable happens and your kernel oopses, you may need the
+ksymoops tool to decode it, but in most cases you don't.
+In the 2.6 kernel it is generally preferred to build the kernel with
+CONFIG_KALLSYMS so that it produces readable dumps that can be used as-is
+(this also produces better output than ksymoops).
+If for some reason your kernel is not build with CONFIG_KALLSYMS and
+you have no way to rebuild and reproduce the Oops with that option, then
+you can still decode that Oops with ksymoops.
Module-Init-Tools
-----------------
diff --git a/Documentation/DocBook/Makefile b/Documentation/DocBook/Makefile
index fa3e29ad8a46..7018f5c6a447 100644
--- a/Documentation/DocBook/Makefile
+++ b/Documentation/DocBook/Makefile
@@ -10,7 +10,7 @@ DOCBOOKS := wanbook.xml z8530book.xml mcabook.xml videobook.xml \
kernel-hacking.xml kernel-locking.xml deviceiobook.xml \
procfs-guide.xml writing_usb_driver.xml \
sis900.xml kernel-api.xml journal-api.xml lsm.xml usb.xml \
- gadget.xml libata.xml mtdnand.xml librs.xml
+ gadget.xml libata.xml mtdnand.xml librs.xml rapidio.xml
###
# The build process is as follows (targets):
diff --git a/Documentation/DocBook/journal-api.tmpl b/Documentation/DocBook/journal-api.tmpl
index 341aaa4ce481..2077f9a28c19 100644
--- a/Documentation/DocBook/journal-api.tmpl
+++ b/Documentation/DocBook/journal-api.tmpl
@@ -306,7 +306,7 @@ an example.
</para>
<sect1><title>Journal Level</title>
!Efs/jbd/journal.c
-!Efs/jbd/recovery.c
+!Ifs/jbd/recovery.c
</sect1>
<sect1><title>Transasction Level</title>
!Efs/jbd/transaction.c
diff --git a/Documentation/DocBook/kernel-api.tmpl b/Documentation/DocBook/kernel-api.tmpl
index d650ce36485f..a8316b1a3e3d 100644
--- a/Documentation/DocBook/kernel-api.tmpl
+++ b/Documentation/DocBook/kernel-api.tmpl
@@ -118,7 +118,7 @@ X!Ilib/string.c
</sect1>
<sect1><title>User Space Memory Access</title>
!Iinclude/asm-i386/uaccess.h
-!Iarch/i386/lib/usercopy.c
+!Earch/i386/lib/usercopy.c
</sect1>
<sect1><title>More Memory Management Functions</title>
!Iinclude/linux/rmap.h
@@ -174,7 +174,6 @@ X!Ilib/string.c
<title>The Linux VFS</title>
<sect1><title>The Filesystem types</title>
!Iinclude/linux/fs.h
-!Einclude/linux/fs.h
</sect1>
<sect1><title>The Directory Cache</title>
!Efs/dcache.c
@@ -239,9 +238,9 @@ X!Ilib/string.c
<title>Network device support</title>
<sect1><title>Driver Support</title>
!Enet/core/dev.c
- </sect1>
- <sect1><title>8390 Based Network Cards</title>
-!Edrivers/net/8390.c
+!Enet/ethernet/eth.c
+!Einclude/linux/etherdevice.h
+!Enet/core/wireless.c
</sect1>
<sect1><title>Synchronous PPP</title>
!Edrivers/net/wan/syncppp.c
@@ -266,7 +265,7 @@ X!Ekernel/module.c
<chapter id="hardware">
<title>Hardware Interfaces</title>
<sect1><title>Interrupt Handling</title>
-!Ikernel/irq/manage.c
+!Ekernel/irq/manage.c
</sect1>
<sect1><title>Resources Management</title>
@@ -286,7 +285,9 @@ X!Edrivers/pci/search.c
-->
!Edrivers/pci/msi.c
!Edrivers/pci/bus.c
-!Edrivers/pci/hotplug.c
+<!-- FIXME: Removed for now since no structured comments in source
+X!Edrivers/pci/hotplug.c
+-->
!Edrivers/pci/probe.c
!Edrivers/pci/rom.c
</sect1>
@@ -499,7 +500,7 @@ KAO -->
!Edrivers/video/modedb.c
</sect1>
<sect1><title>Frame Buffer Macintosh Video Mode Database</title>
-!Idrivers/video/macmodes.c
+!Edrivers/video/macmodes.c
</sect1>
<sect1><title>Frame Buffer Fonts</title>
<para>
diff --git a/Documentation/DocBook/libata.tmpl b/Documentation/DocBook/libata.tmpl
index 375ae760dc1e..d260d92089ad 100644
--- a/Documentation/DocBook/libata.tmpl
+++ b/Documentation/DocBook/libata.tmpl
@@ -415,6 +415,362 @@ and other resources, etc.
</sect1>
</chapter>
+ <chapter id="libataEH">
+ <title>Error handling</title>
+
+ <para>
+ This chapter describes how errors are handled under libata.
+ Readers are advised to read SCSI EH
+ (Documentation/scsi/scsi_eh.txt) and ATA exceptions doc first.
+ </para>
+
+ <sect1><title>Origins of commands</title>
+ <para>
+ In libata, a command is represented with struct ata_queued_cmd
+ or qc. qc's are preallocated during port initialization and
+ repetitively used for command executions. Currently only one
+ qc is allocated per port but yet-to-be-merged NCQ branch
+ allocates one for each tag and maps each qc to NCQ tag 1-to-1.
+ </para>
+ <para>
+ libata commands can originate from two sources - libata itself
+ and SCSI midlayer. libata internal commands are used for
+ initialization and error handling. All normal blk requests
+ and commands for SCSI emulation are passed as SCSI commands
+ through queuecommand callback of SCSI host template.
+ </para>
+ </sect1>
+
+ <sect1><title>How commands are issued</title>
+
+ <variablelist>
+
+ <varlistentry><term>Internal commands</term>
+ <listitem>
+ <para>
+ First, qc is allocated and initialized using
+ ata_qc_new_init(). Although ata_qc_new_init() doesn't
+ implement any wait or retry mechanism when qc is not
+ available, internal commands are currently issued only during
+ initialization and error recovery, so no other command is
+ active and allocation is guaranteed to succeed.
+ </para>
+ <para>
+ Once allocated qc's taskfile is initialized for the command to
+ be executed. qc currently has two mechanisms to notify
+ completion. One is via qc->complete_fn() callback and the
+ other is completion qc->waiting. qc->complete_fn() callback
+ is the asynchronous path used by normal SCSI translated
+ commands and qc->waiting is the synchronous (issuer sleeps in
+ process context) path used by internal commands.
+ </para>
+ <para>
+ Once initialization is complete, host_set lock is acquired
+ and the qc is issued.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry><term>SCSI commands</term>
+ <listitem>
+ <para>
+ All libata drivers use ata_scsi_queuecmd() as
+ hostt->queuecommand callback. scmds can either be simulated
+ or translated. No qc is involved in processing a simulated
+ scmd. The result is computed right away and the scmd is
+ completed.
+ </para>
+ <para>
+ For a translated scmd, ata_qc_new_init() is invoked to
+ allocate a qc and the scmd is translated into the qc. SCSI
+ midlayer's completion notification function pointer is stored
+ into qc->scsidone.
+ </para>
+ <para>
+ qc->complete_fn() callback is used for completion
+ notification. ATA commands use ata_scsi_qc_complete() while
+ ATAPI commands use atapi_qc_complete(). Both functions end up
+ calling qc->scsidone to notify upper layer when the qc is
+ finished. After translation is completed, the qc is issued
+ with ata_qc_issue().
+ </para>
+ <para>
+ Note that SCSI midlayer invokes hostt->queuecommand while
+ holding host_set lock, so all above occur while holding
+ host_set lock.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </sect1>
+
+ <sect1><title>How commands are processed</title>
+ <para>
+ Depending on which protocol and which controller are used,
+ commands are processed differently. For the purpose of
+ discussion, a controller which uses taskfile interface and all
+ standard callbacks is assumed.
+ </para>
+ <para>
+ Currently 6 ATA command protocols are used. They can be
+ sorted into the following four categories according to how
+ they are processed.
+ </para>
+
+ <variablelist>
+ <varlistentry><term>ATA NO DATA or DMA</term>
+ <listitem>
+ <para>
+ ATA_PROT_NODATA and ATA_PROT_DMA fall into this category.
+ These types of commands don't require any software
+ intervention once issued. Device will raise interrupt on
+ completion.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry><term>ATA PIO</term>
+ <listitem>
+ <para>
+ ATA_PROT_PIO is in this category. libata currently
+ implements PIO with polling. ATA_NIEN bit is set to turn
+ off interrupt and pio_task on ata_wq performs polling and
+ IO.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry><term>ATAPI NODATA or DMA</term>
+ <listitem>
+ <para>
+ ATA_PROT_ATAPI_NODATA and ATA_PROT_ATAPI_DMA are in this
+ category. packet_task is used to poll BSY bit after
+ issuing PACKET command. Once BSY is turned off by the
+ device, packet_task transfers CDB and hands off processing
+ to interrupt handler.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry><term>ATAPI PIO</term>
+ <listitem>
+ <para>
+ ATA_PROT_ATAPI is in this category. ATA_NIEN bit is set
+ and, as in ATAPI NODATA or DMA, packet_task submits cdb.
+ However, after submitting cdb, further processing (data
+ transfer) is handed off to pio_task.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </sect1>
+
+ <sect1><title>How commands are completed</title>
+ <para>
+ Once issued, all qc's are either completed with
+ ata_qc_complete() or time out. For commands which are handled
+ by interrupts, ata_host_intr() invokes ata_qc_complete(), and,
+ for PIO tasks, pio_task invokes ata_qc_complete(). In error
+ cases, packet_task may also complete commands.
+ </para>
+ <para>
+ ata_qc_complete() does the following.
+ </para>
+
+ <orderedlist>
+
+ <listitem>
+ <para>
+ DMA memory is unmapped.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ ATA_QCFLAG_ACTIVE is clared from qc->flags.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ qc->complete_fn() callback is invoked. If the return value of
+ the callback is not zero. Completion is short circuited and
+ ata_qc_complete() returns.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ __ata_qc_complete() is called, which does
+ <orderedlist>
+
+ <listitem>
+ <para>
+ qc->flags is cleared to zero.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ ap->active_tag and qc->tag are poisoned.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ qc->waiting is claread &amp; completed (in that order).
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ qc is deallocated by clearing appropriate bit in ap->qactive.
+ </para>
+ </listitem>
+
+ </orderedlist>
+ </para>
+ </listitem>
+
+ </orderedlist>
+
+ <para>
+ So, it basically notifies upper layer and deallocates qc. One
+ exception is short-circuit path in #3 which is used by
+ atapi_qc_complete().
+ </para>
+ <para>
+ For all non-ATAPI commands, whether it fails or not, almost
+ the same code path is taken and very little error handling
+ takes place. A qc is completed with success status if it
+ succeeded, with failed status otherwise.
+ </para>
+ <para>
+ However, failed ATAPI commands require more handling as
+ REQUEST SENSE is needed to acquire sense data. If an ATAPI
+ command fails, ata_qc_complete() is invoked with error status,
+ which in turn invokes atapi_qc_complete() via
+ qc->complete_fn() callback.
+ </para>
+ <para>
+ This makes atapi_qc_complete() set scmd->result to
+ SAM_STAT_CHECK_CONDITION, complete the scmd and return 1. As
+ the sense data is empty but scmd->result is CHECK CONDITION,
+ SCSI midlayer will invoke EH for the scmd, and returning 1
+ makes ata_qc_complete() to return without deallocating the qc.
+ This leads us to ata_scsi_error() with partially completed qc.
+ </para>
+
+ </sect1>
+
+ <sect1><title>ata_scsi_error()</title>
+ <para>
+ ata_scsi_error() is the current hostt->eh_strategy_handler()
+ for libata. As discussed above, this will be entered in two
+ cases - timeout and ATAPI error completion. This function
+ calls low level libata driver's eng_timeout() callback, the
+ standard callback for which is ata_eng_timeout(). It checks
+ if a qc is active and calls ata_qc_timeout() on the qc if so.
+ Actual error handling occurs in ata_qc_timeout().
+ </para>
+ <para>
+ If EH is invoked for timeout, ata_qc_timeout() stops BMDMA and
+ completes the qc. Note that as we're currently in EH, we
+ cannot call scsi_done. As described in SCSI EH doc, a
+ recovered scmd should be either retried with
+ scsi_queue_insert() or finished with scsi_finish_command().
+ Here, we override qc->scsidone with scsi_finish_command() and
+ calls ata_qc_complete().
+ </para>
+ <para>
+ If EH is invoked due to a failed ATAPI qc, the qc here is
+ completed but not deallocated. The purpose of this
+ half-completion is to use the qc as place holder to make EH
+ code reach this place. This is a bit hackish, but it works.
+ </para>
+ <para>
+ Once control reaches here, the qc is deallocated by invoking
+ __ata_qc_complete() explicitly. Then, internal qc for REQUEST
+ SENSE is issued. Once sense data is acquired, scmd is
+ finished by directly invoking scsi_finish_command() on the
+ scmd. Note that as we already have completed and deallocated
+ the qc which was associated with the scmd, we don't need
+ to/cannot call ata_qc_complete() again.
+ </para>
+
+ </sect1>
+
+ <sect1><title>Problems with the current EH</title>
+
+ <itemizedlist>
+
+ <listitem>
+ <para>
+ Error representation is too crude. Currently any and all
+ error conditions are represented with ATA STATUS and ERROR
+ registers. Errors which aren't ATA device errors are treated
+ as ATA device errors by setting ATA_ERR bit. Better error
+ descriptor which can properly represent ATA and other
+ errors/exceptions is needed.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ When handling timeouts, no action is taken to make device
+ forget about the timed out command and ready for new commands.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ EH handling via ata_scsi_error() is not properly protected
+ from usual command processing. On EH entrance, the device is
+ not in quiescent state. Timed out commands may succeed or
+ fail any time. pio_task and atapi_task may still be running.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Too weak error recovery. Devices / controllers causing HSM
+ mismatch errors and other errors quite often require reset to
+ return to known state. Also, advanced error handling is
+ necessary to support features like NCQ and hotplug.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ ATA errors are directly handled in the interrupt handler and
+ PIO errors in pio_task. This is problematic for advanced
+ error handling for the following reasons.
+ </para>
+ <para>
+ First, advanced error handling often requires context and
+ internal qc execution.
+ </para>
+ <para>
+ Second, even a simple failure (say, CRC error) needs
+ information gathering and could trigger complex error handling
+ (say, resetting &amp; reconfiguring). Having multiple code
+ paths to gather information, enter EH and trigger actions
+ makes life painful.
+ </para>
+ <para>
+ Third, scattered EH code makes implementing low level drivers
+ difficult. Low level drivers override libata callbacks. If
+ EH is scattered over several places, each affected callbacks
+ should perform its part of error handling. This can be error
+ prone and painful.
+ </para>
+ </listitem>
+
+ </itemizedlist>
+ </sect1>
+ </chapter>
+
<chapter id="libataExt">
<title>libata Library</title>
!Edrivers/scsi/libata-core.c
@@ -431,6 +787,722 @@ and other resources, etc.
!Idrivers/scsi/libata-scsi.c
</chapter>
+ <chapter id="ataExceptions">
+ <title>ATA errors &amp; exceptions</title>
+
+ <para>
+ This chapter tries to identify what error/exception conditions exist
+ for ATA/ATAPI devices and describe how they should be handled in
+ implementation-neutral way.
+ </para>
+
+ <para>
+ The term 'error' is used to describe conditions where either an
+ explicit error condition is reported from device or a command has
+ timed out.
+ </para>
+
+ <para>
+ The term 'exception' is either used to describe exceptional
+ conditions which are not errors (say, power or hotplug events), or
+ to describe both errors and non-error exceptional conditions. Where
+ explicit distinction between error and exception is necessary, the
+ term 'non-error exception' is used.
+ </para>
+
+ <sect1 id="excat">
+ <title>Exception categories</title>
+ <para>
+ Exceptions are described primarily with respect to legacy
+ taskfile + bus master IDE interface. If a controller provides
+ other better mechanism for error reporting, mapping those into
+ categories described below shouldn't be difficult.
+ </para>
+
+ <para>
+ In the following sections, two recovery actions - reset and
+ reconfiguring transport - are mentioned. These are described
+ further in <xref linkend="exrec"/>.
+ </para>
+
+ <sect2 id="excatHSMviolation">
+ <title>HSM violation</title>
+ <para>
+ This error is indicated when STATUS value doesn't match HSM
+ requirement during issuing or excution any ATA/ATAPI command.
+ </para>
+
+ <itemizedlist>
+ <title>Examples</title>
+
+ <listitem>
+ <para>
+ ATA_STATUS doesn't contain !BSY &amp;&amp; DRDY &amp;&amp; !DRQ while trying
+ to issue a command.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ !BSY &amp;&amp; !DRQ during PIO data transfer.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ DRQ on command completion.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ !BSY &amp;&amp; ERR after CDB tranfer starts but before the
+ last byte of CDB is transferred. ATA/ATAPI standard states
+ that &quot;The device shall not terminate the PACKET command
+ with an error before the last byte of the command packet has
+ been written&quot; in the error outputs description of PACKET
+ command and the state diagram doesn't include such
+ transitions.
+ </para>
+ </listitem>
+
+ </itemizedlist>
+
+ <para>
+ In these cases, HSM is violated and not much information
+ regarding the error can be acquired from STATUS or ERROR
+ register. IOW, this error can be anything - driver bug,
+ faulty device, controller and/or cable.
+ </para>
+
+ <para>
+ As HSM is violated, reset is necessary to restore known state.
+ Reconfiguring transport for lower speed might be helpful too
+ as transmission errors sometimes cause this kind of errors.
+ </para>
+ </sect2>
+
+ <sect2 id="excatDevErr">
+ <title>ATA/ATAPI device error (non-NCQ / non-CHECK CONDITION)</title>
+
+ <para>
+ These are errors detected and reported by ATA/ATAPI devices
+ indicating device problems. For this type of errors, STATUS
+ and ERROR register values are valid and describe error
+ condition. Note that some of ATA bus errors are detected by
+ ATA/ATAPI devices and reported using the same mechanism as
+ device errors. Those cases are described later in this
+ section.
+ </para>
+
+ <para>
+ For ATA commands, this type of errors are indicated by !BSY
+ &amp;&amp; ERR during command execution and on completion.
+ </para>
+
+ <para>For ATAPI commands,</para>
+
+ <itemizedlist>
+
+ <listitem>
+ <para>
+ !BSY &amp;&amp; ERR &amp;&amp; ABRT right after issuing PACKET
+ indicates that PACKET command is not supported and falls in
+ this category.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ !BSY &amp;&amp; ERR(==CHK) &amp;&amp; !ABRT after the last
+ byte of CDB is transferred indicates CHECK CONDITION and
+ doesn't fall in this category.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ !BSY &amp;&amp; ERR(==CHK) &amp;&amp; ABRT after the last byte
+ of CDB is transferred *probably* indicates CHECK CONDITION and
+ doesn't fall in this category.
+ </para>
+ </listitem>
+
+ </itemizedlist>
+
+ <para>
+ Of errors detected as above, the followings are not ATA/ATAPI
+ device errors but ATA bus errors and should be handled
+ according to <xref linkend="excatATAbusErr"/>.
+ </para>
+
+ <variablelist>
+
+ <varlistentry>
+ <term>CRC error during data transfer</term>
+ <listitem>
+ <para>
+ This is indicated by ICRC bit in the ERROR register and
+ means that corruption occurred during data transfer. Upto
+ ATA/ATAPI-7, the standard specifies that this bit is only
+ applicable to UDMA transfers but ATA/ATAPI-8 draft revision
+ 1f says that the bit may be applicable to multiword DMA and
+ PIO.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>ABRT error during data transfer or on completion</term>
+ <listitem>
+ <para>
+ Upto ATA/ATAPI-7, the standard specifies that ABRT could be
+ set on ICRC errors and on cases where a device is not able
+ to complete a command. Combined with the fact that MWDMA
+ and PIO transfer errors aren't allowed to use ICRC bit upto
+ ATA/ATAPI-7, it seems to imply that ABRT bit alone could
+ indicate tranfer errors.
+ </para>
+ <para>
+ However, ATA/ATAPI-8 draft revision 1f removes the part
+ that ICRC errors can turn on ABRT. So, this is kind of
+ gray area. Some heuristics are needed here.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+
+ <para>
+ ATA/ATAPI device errors can be further categorized as follows.
+ </para>
+
+ <variablelist>
+
+ <varlistentry>
+ <term>Media errors</term>
+ <listitem>
+ <para>
+ This is indicated by UNC bit in the ERROR register. ATA
+ devices reports UNC error only after certain number of
+ retries cannot recover the data, so there's nothing much
+ else to do other than notifying upper layer.
+ </para>
+ <para>
+ READ and WRITE commands report CHS or LBA of the first
+ failed sector but ATA/ATAPI standard specifies that the
+ amount of transferred data on error completion is
+ indeterminate, so we cannot assume that sectors preceding
+ the failed sector have been transferred and thus cannot
+ complete those sectors successfully as SCSI does.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Media changed / media change requested error</term>
+ <listitem>
+ <para>
+ &lt;&lt;TODO: fill here&gt;&gt;
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry><term>Address error</term>
+ <listitem>
+ <para>
+ This is indicated by IDNF bit in the ERROR register.
+ Report to upper layer.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry><term>Other errors</term>
+ <listitem>
+ <para>
+ This can be invalid command or parameter indicated by ABRT
+ ERROR bit or some other error condition. Note that ABRT
+ bit can indicate a lot of things including ICRC and Address
+ errors. Heuristics needed.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+
+ <para>
+ Depending on commands, not all STATUS/ERROR bits are
+ applicable. These non-applicable bits are marked with
+ &quot;na&quot; in the output descriptions but upto ATA/ATAPI-7
+ no definition of &quot;na&quot; can be found. However,
+ ATA/ATAPI-8 draft revision 1f describes &quot;N/A&quot; as
+ follows.
+ </para>
+
+ <blockquote>
+ <variablelist>
+ <varlistentry><term>3.2.3.3a N/A</term>
+ <listitem>
+ <para>
+ A keyword the indicates a field has no defined value in
+ this standard and should not be checked by the host or
+ device. N/A fields should be cleared to zero.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </blockquote>
+
+ <para>
+ So, it seems reasonable to assume that &quot;na&quot; bits are
+ cleared to zero by devices and thus need no explicit masking.
+ </para>
+
+ </sect2>
+
+ <sect2 id="excatATAPIcc">
+ <title>ATAPI device CHECK CONDITION</title>
+
+ <para>
+ ATAPI device CHECK CONDITION error is indicated by set CHK bit
+ (ERR bit) in the STATUS register after the last byte of CDB is
+ transferred for a PACKET command. For this kind of errors,
+ sense data should be acquired to gather information regarding
+ the errors. REQUEST SENSE packet command should be used to
+ acquire sense data.
+ </para>
+
+ <para>
+ Once sense data is acquired, this type of errors can be
+ handled similary to other SCSI errors. Note that sense data
+ may indicate ATA bus error (e.g. Sense Key 04h HARDWARE ERROR
+ &amp;&amp; ASC/ASCQ 47h/00h SCSI PARITY ERROR). In such
+ cases, the error should be considered as an ATA bus error and
+ handled according to <xref linkend="excatATAbusErr"/>.
+ </para>
+
+ </sect2>
+
+ <sect2 id="excatNCQerr">
+ <title>ATA device error (NCQ)</title>
+
+ <para>
+ NCQ command error is indicated by cleared BSY and set ERR bit
+ during NCQ command phase (one or more NCQ commands
+ outstanding). Although STATUS and ERROR registers will
+ contain valid values describing the error, READ LOG EXT is
+ required to clear the error condition, determine which command
+ has failed and acquire more information.
+ </para>
+
+ <para>
+ READ LOG EXT Log Page 10h reports which tag has failed and
+ taskfile register values describing the error. With this
+ information the failed command can be handled as a normal ATA
+ command error as in <xref linkend="excatDevErr"/> and all
+ other in-flight commands must be retried. Note that this
+ retry should not be counted - it's likely that commands
+ retried this way would have completed normally if it were not
+ for the failed command.
+ </para>
+
+ <para>
+ Note that ATA bus errors can be reported as ATA device NCQ
+ errors. This should be handled as described in <xref
+ linkend="excatATAbusErr"/>.
+ </para>
+
+ <para>
+ If READ LOG EXT Log Page 10h fails or reports NQ, we're
+ thoroughly screwed. This condition should be treated
+ according to <xref linkend="excatHSMviolation"/>.
+ </para>
+
+ </sect2>
+
+ <sect2 id="excatATAbusErr">
+ <title>ATA bus error</title>
+
+ <para>
+ ATA bus error means that data corruption occurred during
+ transmission over ATA bus (SATA or PATA). This type of errors
+ can be indicated by
+ </para>
+
+ <itemizedlist>
+
+ <listitem>
+ <para>
+ ICRC or ABRT error as described in <xref linkend="excatDevErr"/>.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Controller-specific error completion with error information
+ indicating transmission error.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ On some controllers, command timeout. In this case, there may
+ be a mechanism to determine that the timeout is due to
+ transmission error.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Unknown/random errors, timeouts and all sorts of weirdities.
+ </para>
+ </listitem>
+
+ </itemizedlist>
+
+ <para>
+ As described above, transmission errors can cause wide variety
+ of symptoms ranging from device ICRC error to random device
+ lockup, and, for many cases, there is no way to tell if an
+ error condition is due to transmission error or not;
+ therefore, it's necessary to employ some kind of heuristic
+ when dealing with errors and timeouts. For example,
+ encountering repetitive ABRT errors for known supported
+ command is likely to indicate ATA bus error.
+ </para>
+
+ <para>
+ Once it's determined that ATA bus errors have possibly
+ occurred, lowering ATA bus transmission speed is one of
+ actions which may alleviate the problem. See <xref
+ linkend="exrecReconf"/> for more information.
+ </para>
+
+ </sect2>
+
+ <sect2 id="excatPCIbusErr">
+ <title>PCI bus error</title>
+
+ <para>
+ Data corruption or other failures during transmission over PCI
+ (or other system bus). For standard BMDMA, this is indicated
+ by Error bit in the BMDMA Status register. This type of
+ errors must be logged as it indicates something is very wrong
+ with the system. Resetting host controller is recommended.
+ </para>
+
+ </sect2>
+
+ <sect2 id="excatLateCompletion">
+ <title>Late completion</title>
+
+ <para>
+ This occurs when timeout occurs and the timeout handler finds
+ out that the timed out command has completed successfully or
+ with error. This is usually caused by lost interrupts. This
+ type of errors must be logged. Resetting host controller is
+ recommended.
+ </para>
+
+ </sect2>
+
+ <sect2 id="excatUnknown">
+ <title>Unknown error (timeout)</title>
+
+ <para>
+ This is when timeout occurs and the command is still
+ processing or the host and device are in unknown state. When
+ this occurs, HSM could be in any valid or invalid state. To
+ bring the device to known state and make it forget about the
+ timed out command, resetting is necessary. The timed out
+ command may be retried.
+ </para>
+
+ <para>
+ Timeouts can also be caused by transmission errors. Refer to
+ <xref linkend="excatATAbusErr"/> for more details.
+ </para>
+
+ </sect2>
+
+ <sect2 id="excatHoplugPM">
+ <title>Hotplug and power management exceptions</title>
+
+ <para>
+ &lt;&lt;TODO: fill here&gt;&gt;
+ </para>
+
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="exrec">
+ <title>EH recovery actions</title>
+
+ <para>
+ This section discusses several important recovery actions.
+ </para>
+
+ <sect2 id="exrecClr">
+ <title>Clearing error condition</title>
+
+ <para>
+ Many controllers require its error registers to be cleared by
+ error handler. Different controllers may have different
+ requirements.
+ </para>
+
+ <para>
+ For SATA, it's strongly recommended to clear at least SError
+ register during error handling.
+ </para>
+ </sect2>
+
+ <sect2 id="exrecRst">
+ <title>Reset</title>
+
+ <para>
+ During EH, resetting is necessary in the following cases.
+ </para>
+
+ <itemizedlist>
+
+ <listitem>
+ <para>
+ HSM is in unknown or invalid state
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ HBA is in unknown or invalid state
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ EH needs to make HBA/device forget about in-flight commands
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ HBA/device behaves weirdly
+ </para>
+ </listitem>
+
+ </itemizedlist>
+
+ <para>
+ Resetting during EH might be a good idea regardless of error
+ condition to improve EH robustness. Whether to reset both or
+ either one of HBA and device depends on situation but the
+ following scheme is recommended.
+ </para>
+
+ <itemizedlist>
+
+ <listitem>
+ <para>
+ When it's known that HBA is in ready state but ATA/ATAPI
+ device in in unknown state, reset only device.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ If HBA is in unknown state, reset both HBA and device.
+ </para>
+ </listitem>
+
+ </itemizedlist>
+
+ <para>
+ HBA resetting is implementation specific. For a controller
+ complying to taskfile/BMDMA PCI IDE, stopping active DMA
+ transaction may be sufficient iff BMDMA state is the only HBA
+ context. But even mostly taskfile/BMDMA PCI IDE complying
+ controllers may have implementation specific requirements and
+ mechanism to reset themselves. This must be addressed by
+ specific drivers.
+ </para>
+
+ <para>
+ OTOH, ATA/ATAPI standard describes in detail ways to reset
+ ATA/ATAPI devices.
+ </para>
+
+ <variablelist>
+
+ <varlistentry><term>PATA hardware reset</term>
+ <listitem>
+ <para>
+ This is hardware initiated device reset signalled with
+ asserted PATA RESET- signal. There is no standard way to
+ initiate hardware reset from software although some
+ hardware provides registers that allow driver to directly
+ tweak the RESET- signal.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry><term>Software reset</term>
+ <listitem>
+ <para>
+ This is achieved by turning CONTROL SRST bit on for at
+ least 5us. Both PATA and SATA support it but, in case of
+ SATA, this may require controller-specific support as the
+ second Register FIS to clear SRST should be transmitted
+ while BSY bit is still set. Note that on PATA, this resets
+ both master and slave devices on a channel.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry><term>EXECUTE DEVICE DIAGNOSTIC command</term>
+ <listitem>
+ <para>
+ Although ATA/ATAPI standard doesn't describe exactly, EDD
+ implies some level of resetting, possibly similar level
+ with software reset. Host-side EDD protocol can be handled
+ with normal command processing and most SATA controllers
+ should be able to handle EDD's just like other commands.
+ As in software reset, EDD affects both devices on a PATA
+ bus.
+ </para>
+ <para>
+ Although EDD does reset devices, this doesn't suit error
+ handling as EDD cannot be issued while BSY is set and it's
+ unclear how it will act when device is in unknown/weird
+ state.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry><term>ATAPI DEVICE RESET command</term>
+ <listitem>
+ <para>
+ This is very similar to software reset except that reset
+ can be restricted to the selected device without affecting
+ the other device sharing the cable.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry><term>SATA phy reset</term>
+ <listitem>
+ <para>
+ This is the preferred way of resetting a SATA device. In
+ effect, it's identical to PATA hardware reset. Note that
+ this can be done with the standard SCR Control register.
+ As such, it's usually easier to implement than software
+ reset.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+
+ <para>
+ One more thing to consider when resetting devices is that
+ resetting clears certain configuration parameters and they
+ need to be set to their previous or newly adjusted values
+ after reset.
+ </para>
+
+ <para>
+ Parameters affected are.
+ </para>
+
+ <itemizedlist>
+
+ <listitem>
+ <para>
+ CHS set up with INITIALIZE DEVICE PARAMETERS (seldomly used)
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Parameters set with SET FEATURES including transfer mode setting
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Block count set with SET MULTIPLE MODE
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Other parameters (SET MAX, MEDIA LOCK...)
+ </para>
+ </listitem>
+
+ </itemizedlist>
+
+ <para>
+ ATA/ATAPI standard specifies that some parameters must be
+ maintained across hardware or software reset, but doesn't
+ strictly specify all of them. Always reconfiguring needed
+ parameters after reset is required for robustness. Note that
+ this also applies when resuming from deep sleep (power-off).
+ </para>
+
+ <para>
+ Also, ATA/ATAPI standard requires that IDENTIFY DEVICE /
+ IDENTIFY PACKET DEVICE is issued after any configuration
+ parameter is updated or a hardware reset and the result used
+ for further operation. OS driver is required to implement
+ revalidation mechanism to support this.
+ </para>
+
+ </sect2>
+
+ <sect2 id="exrecReconf">
+ <title>Reconfigure transport</title>
+
+ <para>
+ For both PATA and SATA, a lot of corners are cut for cheap
+ connectors, cables or controllers and it's quite common to see
+ high transmission error rate. This can be mitigated by
+ lowering transmission speed.
+ </para>
+
+ <para>
+ The following is a possible scheme Jeff Garzik suggested.
+ </para>
+
+ <blockquote>
+ <para>
+ If more than $N (3?) transmission errors happen in 15 minutes,
+ </para>
+ <itemizedlist>
+ <listitem>
+ <para>
+ if SATA, decrease SATA PHY speed. if speed cannot be decreased,
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ decrease UDMA xfer speed. if at UDMA0, switch to PIO4,
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ decrease PIO xfer speed. if at PIO3, complain, but continue
+ </para>
+ </listitem>
+ </itemizedlist>
+ </blockquote>
+
+ </sect2>
+
+ </sect1>
+
+ </chapter>
+
<chapter id="PiixInt">
<title>ata_piix Internals</title>
!Idrivers/scsi/ata_piix.c
diff --git a/Documentation/DocBook/rapidio.tmpl b/Documentation/DocBook/rapidio.tmpl
new file mode 100644
index 000000000000..1becf27ba27e
--- /dev/null
+++ b/Documentation/DocBook/rapidio.tmpl
@@ -0,0 +1,160 @@
+<?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" [
+ <!ENTITY rapidio SYSTEM "rapidio.xml">
+ ]>
+
+<book id="RapidIO-Guide">
+ <bookinfo>
+ <title>RapidIO Subsystem Guide</title>
+
+ <authorgroup>
+ <author>
+ <firstname>Matt</firstname>
+ <surname>Porter</surname>
+ <affiliation>
+ <address>
+ <email>mporter@kernel.crashing.org</email>
+ <email>mporter@mvista.com</email>
+ </address>
+ </affiliation>
+ </author>
+ </authorgroup>
+
+ <copyright>
+ <year>2005</year>
+ <holder>MontaVista Software, Inc.</holder>
+ </copyright>
+
+ <legalnotice>
+ <para>
+ This documentation 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.
+ </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>
+ RapidIO is a high speed switched fabric interconnect with
+ features aimed at the embedded market. RapidIO provides
+ support for memory-mapped I/O as well as message-based
+ transactions over the switched fabric network. RapidIO has
+ a standardized discovery mechanism not unlike the PCI bus
+ standard that allows simple detection of devices in a
+ network.
+ </para>
+ <para>
+ This documentation is provided for developers intending
+ to support RapidIO on new architectures, write new drivers,
+ or to understand the subsystem internals.
+ </para>
+ </chapter>
+
+ <chapter id="bugs">
+ <title>Known Bugs and Limitations</title>
+
+ <sect1>
+ <title>Bugs</title>
+ <para>None. ;)</para>
+ </sect1>
+ <sect1>
+ <title>Limitations</title>
+ <para>
+ <orderedlist>
+ <listitem><para>Access/management of RapidIO memory regions is not supported</para></listitem>
+ <listitem><para>Multiple host enumeration is not supported</para></listitem>
+ </orderedlist>
+ </para>
+ </sect1>
+ </chapter>
+
+ <chapter id="drivers">
+ <title>RapidIO driver interface</title>
+ <para>
+ Drivers are provided a set of calls in order
+ to interface with the subsystem to gather info
+ on devices, request/map memory region resources,
+ and manage mailboxes/doorbells.
+ </para>
+ <sect1>
+ <title>Functions</title>
+!Iinclude/linux/rio_drv.h
+!Edrivers/rapidio/rio-driver.c
+!Edrivers/rapidio/rio.c
+ </sect1>
+ </chapter>
+
+ <chapter id="internals">
+ <title>Internals</title>
+
+ <para>
+ This chapter contains the autogenerated documentation of the RapidIO
+ subsystem.
+ </para>
+
+ <sect1><title>Structures</title>
+!Iinclude/linux/rio.h
+ </sect1>
+ <sect1><title>Enumeration and Discovery</title>
+!Idrivers/rapidio/rio-scan.c
+ </sect1>
+ <sect1><title>Driver functionality</title>
+!Idrivers/rapidio/rio.c
+!Idrivers/rapidio/rio-access.c
+ </sect1>
+ <sect1><title>Device model support</title>
+!Idrivers/rapidio/rio-driver.c
+ </sect1>
+ <sect1><title>Sysfs support</title>
+!Idrivers/rapidio/rio-sysfs.c
+ </sect1>
+ <sect1><title>PPC32 support</title>
+!Iarch/ppc/kernel/rio.c
+!Earch/ppc/syslib/ppc85xx_rio.c
+!Iarch/ppc/syslib/ppc85xx_rio.c
+ </sect1>
+ </chapter>
+
+ <chapter id="credits">
+ <title>Credits</title>
+ <para>
+ The following people have contributed to the RapidIO
+ subsystem directly or indirectly:
+ <orderedlist>
+ <listitem><para>Matt Porter<email>mporter@kernel.crashing.org</email></para></listitem>
+ <listitem><para>Randy Vinson<email>rvinson@mvista.com</email></para></listitem>
+ <listitem><para>Dan Malek<email>dan@embeddedalley.com</email></para></listitem>
+ </orderedlist>
+ </para>
+ <para>
+ The following people have contributed to this document:
+ <orderedlist>
+ <listitem><para>Matt Porter<email>mporter@kernel.crashing.org</email></para></listitem>
+ </orderedlist>
+ </para>
+ </chapter>
+</book>
diff --git a/Documentation/DocBook/usb.tmpl b/Documentation/DocBook/usb.tmpl
index 705c442c7bf4..15ce0f21e5e0 100644
--- a/Documentation/DocBook/usb.tmpl
+++ b/Documentation/DocBook/usb.tmpl
@@ -291,7 +291,7 @@
!Edrivers/usb/core/hcd.c
!Edrivers/usb/core/hcd-pci.c
-!Edrivers/usb/core/buffer.c
+!Idrivers/usb/core/buffer.c
</chapter>
<chapter>
diff --git a/Documentation/DocBook/writing_usb_driver.tmpl b/Documentation/DocBook/writing_usb_driver.tmpl
index 51f3bfb6fb6e..008a341234d0 100644
--- a/Documentation/DocBook/writing_usb_driver.tmpl
+++ b/Documentation/DocBook/writing_usb_driver.tmpl
@@ -345,8 +345,7 @@ if (!retval) {
<programlisting>
static inline void skel_delete (struct usb_skel *dev)
{
- if (dev->bulk_in_buffer != NULL)
- kfree (dev->bulk_in_buffer);
+ kfree (dev->bulk_in_buffer);
if (dev->bulk_out_buffer != NULL)
usb_buffer_free (dev->udev, dev->bulk_out_size,
dev->bulk_out_buffer,
diff --git a/Documentation/MSI-HOWTO.txt b/Documentation/MSI-HOWTO.txt
index 63edc5f847c4..3ec6c720b016 100644
--- a/Documentation/MSI-HOWTO.txt
+++ b/Documentation/MSI-HOWTO.txt
@@ -10,14 +10,22 @@
This guide describes the basics of Message Signaled Interrupts (MSI),
the advantages of using MSI over traditional interrupt mechanisms,
and how to enable your driver to use MSI or MSI-X. Also included is
-a Frequently Asked Questions.
+a Frequently Asked Questions (FAQ) section.
+
+1.1 Terminology
+
+PCI devices can be single-function or multi-function. In either case,
+when this text talks about enabling or disabling MSI on a "device
+function," it is referring to one specific PCI device and function and
+not to all functions on a PCI device (unless the PCI device has only
+one function).
2. Copyright 2003 Intel Corporation
3. What is MSI/MSI-X?
Message Signaled Interrupt (MSI), as described in the PCI Local Bus
-Specification Revision 2.3 or latest, is an optional feature, and a
+Specification Revision 2.3 or later, is an optional feature, and a
required feature for PCI Express devices. MSI enables a device function
to request service by sending an Inbound Memory Write on its PCI bus to
the FSB as a Message Signal Interrupt transaction. Because MSI is
@@ -27,7 +35,7 @@ supported.
A PCI device that supports MSI must also support pin IRQ assertion
interrupt mechanism to provide backward compatibility for systems that
-do not support MSI. In Systems, which support MSI, the bus driver is
+do not support MSI. In systems which support MSI, the bus driver is
responsible for initializing the message address and message data of
the device function's MSI/MSI-X capability structure during device
initial configuration.
@@ -61,17 +69,17 @@ over the MSI capability structure as described below.
- MSI and MSI-X both support per-vector masking. Per-vector
masking is an optional extension of MSI but a required
- feature for MSI-X. Per-vector masking provides the kernel
- the ability to mask/unmask MSI when servicing its software
- interrupt service routing handler. If per-vector masking is
+ feature for MSI-X. Per-vector masking provides the kernel the
+ ability to mask/unmask a single MSI while running its
+ interrupt service routine. If per-vector masking is
not supported, then the device driver should provide the
hardware/software synchronization to ensure that the device
generates MSI when the driver wants it to do so.
4. Why use MSI?
-As a benefit the simplification of board design, MSI allows board
-designers to remove out of band interrupt routing. MSI is another
+As a benefit to the simplification of board design, MSI allows board
+designers to remove out-of-band interrupt routing. MSI is another
step towards a legacy-free environment.
Due to increasing pressure on chipset and processor packages to
@@ -87,7 +95,7 @@ support. As a result, the PCI Express technology requires MSI
support for better interrupt performance.
Using MSI enables the device functions to support two or more
-vectors, which can be configured to target different CPU's to
+vectors, which can be configured to target different CPUs to
increase scalability.
5. Configuring a driver to use MSI/MSI-X
@@ -119,13 +127,13 @@ pci_enable_msi() explicitly.
int pci_enable_msi(struct pci_dev *dev)
-With this new API, any existing device driver, which like to have
-MSI enabled on its device function, must call this API to enable MSI
+With this new API, a device driver that wants to have MSI
+enabled on its device function must call this API to enable MSI.
A successful call will initialize the MSI capability structure
with ONE vector, regardless of whether a device function is
capable of supporting multiple messages. This vector replaces the
-pre-assigned dev->irq with a new MSI vector. To avoid the conflict
-of new assigned vector with existing pre-assigned vector requires
+pre-assigned dev->irq with a new MSI vector. To avoid a conflict
+of the new assigned vector with existing pre-assigned vector requires
a device driver to call this API before calling request_irq().
5.2.2 API pci_disable_msi
@@ -137,14 +145,14 @@ when a device driver is unloading. This API restores dev->irq with
the pre-assigned IOAPIC vector and switches a device's interrupt
mode to PCI pin-irq assertion/INTx emulation mode.
-Note that a device driver should always call free_irq() on MSI vector
-it has done request_irq() on before calling this API. Failure to do
-so results a BUG_ON() and a device will be left with MSI enabled and
+Note that a device driver should always call free_irq() on the MSI vector
+that it has done request_irq() on before calling this API. Failure to do
+so results in a BUG_ON() and a device will be left with MSI enabled and
leaks its vector.
5.2.3 MSI mode vs. legacy mode diagram
-The below diagram shows the events, which switches the interrupt
+The below diagram shows the events which switch the interrupt
mode on the MSI-capable device function between MSI mode and
PIN-IRQ assertion mode.
@@ -155,9 +163,9 @@ PIN-IRQ assertion mode.
------------ pci_disable_msi ------------------------
-Figure 1.0 MSI Mode vs. Legacy Mode
+Figure 1. MSI Mode vs. Legacy Mode
-In Figure 1.0, a device operates by default in legacy mode. Legacy
+In Figure 1, a device operates by default in legacy mode. Legacy
in this context means PCI pin-irq assertion or PCI-Express INTx
emulation. A successful MSI request (using pci_enable_msi()) switches
a device's interrupt mode to MSI mode. A pre-assigned IOAPIC vector
@@ -166,11 +174,11 @@ assigned MSI vector will replace dev->irq.
To return back to its default mode, a device driver should always call
pci_disable_msi() to undo the effect of pci_enable_msi(). Note that a
-device driver should always call free_irq() on MSI vector it has done
-request_irq() on before calling pci_disable_msi(). Failure to do so
-results a BUG_ON() and a device will be left with MSI enabled and
+device driver should always call free_irq() on the MSI vector it has
+done request_irq() on before calling pci_disable_msi(). Failure to do
+so results in a BUG_ON() and a device will be left with MSI enabled and
leaks its vector. Otherwise, the PCI subsystem restores a device's
-dev->irq with a pre-assigned IOAPIC vector and marks released
+dev->irq with a pre-assigned IOAPIC vector and marks the released
MSI vector as unused.
Once being marked as unused, there is no guarantee that the PCI
@@ -178,8 +186,8 @@ subsystem will reserve this MSI vector for a device. Depending on
the availability of current PCI vector resources and the number of
MSI/MSI-X requests from other drivers, this MSI may be re-assigned.
-For the case where the PCI subsystem re-assigned this MSI vector
-another driver, a request to switching back to MSI mode may result
+For the case where the PCI subsystem re-assigns this MSI vector to
+another driver, a request to switch back to MSI mode may result
in being assigned a different MSI vector or a failure if no more
vectors are available.
@@ -208,12 +216,12 @@ Unlike the function pci_enable_msi(), the function pci_enable_msix()
does not replace the pre-assigned IOAPIC dev->irq with a new MSI
vector because the PCI subsystem writes the 1:1 vector-to-entry mapping
into the field vector of each element contained in a second argument.
-Note that the pre-assigned IO-APIC dev->irq is valid only if the device
-operates in PIN-IRQ assertion mode. In MSI-X mode, any attempt of
+Note that the pre-assigned IOAPIC dev->irq is valid only if the device
+operates in PIN-IRQ assertion mode. In MSI-X mode, any attempt at
using dev->irq by the device driver to request for interrupt service
may result unpredictabe behavior.
-For each MSI-X vector granted, a device driver is responsible to call
+For each MSI-X vector granted, a device driver is responsible for calling
other functions like request_irq(), enable_irq(), etc. to enable
this vector with its corresponding interrupt service handler. It is
a device driver's choice to assign all vectors with the same
@@ -224,13 +232,13 @@ service handler.
The PCI 3.0 specification has implementation notes that MMIO address
space for a device's MSI-X structure should be isolated so that the
-software system can set different page for controlling accesses to
-the MSI-X structure. The implementation of MSI patch requires the PCI
+software system can set different pages for controlling accesses to the
+MSI-X structure. The implementation of MSI support requires the PCI
subsystem, not a device driver, to maintain full control of the MSI-X
-table/MSI-X PBA and MMIO address space of the MSI-X table/MSI-X PBA.
-A device driver is prohibited from requesting the MMIO address space
-of the MSI-X table/MSI-X PBA. Otherwise, the PCI subsystem will fail
-enabling MSI-X on its hardware device when it calls the function
+table/MSI-X PBA (Pending Bit Array) and MMIO address space of the MSI-X
+table/MSI-X PBA. A device driver is prohibited from requesting the MMIO
+address space of the MSI-X table/MSI-X PBA. Otherwise, the PCI subsystem
+will fail enabling MSI-X on its hardware device when it calls the function
pci_enable_msix().
5.3.2 Handling MSI-X allocation
@@ -274,9 +282,9 @@ For the case where fewer MSI-X vectors are allocated to a function
than requested, the function pci_enable_msix() will return the
maximum number of MSI-X vectors available to the caller. A device
driver may re-send its request with fewer or equal vectors indicated
-in a return. For example, if a device driver requests 5 vectors, but
-the number of available vectors is 3 vectors, a value of 3 will be a
-return as a result of pci_enable_msix() call. A function could be
+in the return. For example, if a device driver requests 5 vectors, but
+the number of available vectors is 3 vectors, a value of 3 will be
+returned as a result of pci_enable_msix() call. A function could be
designed for its driver to use only 3 MSI-X table entries as
different combinations as ABC--, A-B-C, A--CB, etc. Note that this
patch does not support multiple entries with the same vector. Such
@@ -285,49 +293,46 @@ as ABBCC, AABCC, BCCBA, etc will result as a failure by the function
pci_enable_msix(). Below are the reasons why supporting multiple
entries with the same vector is an undesirable solution.
- - The PCI subsystem can not determine which entry, which
- generated the message, to mask/unmask MSI while handling
+ - The PCI subsystem cannot determine the entry that
+ generated the message to mask/unmask MSI while handling
software driver ISR. Attempting to walk through all MSI-X
table entries (2048 max) to mask/unmask any match vector
is an undesirable solution.
- - Walk through all MSI-X table entries (2048 max) to handle
+ - Walking through all MSI-X table entries (2048 max) to handle
SMP affinity of any match vector is an undesirable solution.
5.3.4 API pci_enable_msix
-int pci_enable_msix(struct pci_dev *dev, u32 *entries, int nvec)
+int pci_enable_msix(struct pci_dev *dev, struct msix_entry *entries, int nvec)
This API enables a device driver to request the PCI subsystem
-for enabling MSI-X messages on its hardware device. Depending on
+to enable MSI-X messages on its hardware device. Depending on
the availability of PCI vectors resources, the PCI subsystem enables
-either all or nothing.
+either all or none of the requested vectors.
-Argument dev points to the device (pci_dev) structure.
+Argument 'dev' points to the device (pci_dev) structure.
-Argument entries is a pointer of unsigned integer type. The number of
-elements is indicated in argument nvec. The content of each element
-will be mapped to the following struct defined in /driver/pci/msi.h.
+Argument 'entries' is a pointer to an array of msix_entry structs.
+The number of entries is indicated in argument 'nvec'.
+struct msix_entry is defined in /driver/pci/msi.h:
struct msix_entry {
u16 vector; /* kernel uses to write alloc vector */
u16 entry; /* driver uses to specify entry */
};
-A device driver is responsible for initializing the field entry of
-each element with unique entry supported by MSI-X table. Otherwise,
+A device driver is responsible for initializing the field 'entry' of
+each element with a unique entry supported by MSI-X table. Otherwise,
-EINVAL will be returned as a result. A successful return of zero
-indicates the PCI subsystem completes initializing each of requested
+indicates the PCI subsystem completed initializing each of the requested
entries of the MSI-X table with message address and message data.
Last but not least, the PCI subsystem will write the 1:1
-vector-to-entry mapping into the field vector of each element. A
-device driver is responsible of keeping track of allocated MSI-X
+vector-to-entry mapping into the field 'vector' of each element. A
+device driver is responsible for keeping track of allocated MSI-X
vectors in its internal data structure.
-Argument nvec is an integer indicating the number of messages
-requested.
-
-A return of zero indicates that the number of MSI-X vectors is
+A return of zero indicates that the number of MSI-X vectors was
successfully allocated. A return of greater than zero indicates
MSI-X vector shortage. Or a return of less than zero indicates
a failure. This failure may be a result of duplicate entries
@@ -341,12 +346,12 @@ void pci_disable_msix(struct pci_dev *dev)
This API should always be used to undo the effect of pci_enable_msix()
when a device driver is unloading. Note that a device driver should
always call free_irq() on all MSI-X vectors it has done request_irq()
-on before calling this API. Failure to do so results a BUG_ON() and
+on before calling this API. Failure to do so results in a BUG_ON() and
a device will be left with MSI-X enabled and leaks its vectors.
5.3.6 MSI-X mode vs. legacy mode diagram
-The below diagram shows the events, which switches the interrupt
+The below diagram shows the events which switch the interrupt
mode on the MSI-X capable device function between MSI-X mode and
PIN-IRQ assertion mode (legacy).
@@ -356,22 +361,22 @@ PIN-IRQ assertion mode (legacy).
| | ===============> | |
------------ pci_disable_msix ------------------------
-Figure 2.0 MSI-X Mode vs. Legacy Mode
+Figure 2. MSI-X Mode vs. Legacy Mode
-In Figure 2.0, a device operates by default in legacy mode. A
+In Figure 2, a device operates by default in legacy mode. A
successful MSI-X request (using pci_enable_msix()) switches a
device's interrupt mode to MSI-X mode. A pre-assigned IOAPIC vector
stored in dev->irq will be saved by the PCI subsystem; however,
unlike MSI mode, the PCI subsystem will not replace dev->irq with
assigned MSI-X vector because the PCI subsystem already writes the 1:1
-vector-to-entry mapping into the field vector of each element
+vector-to-entry mapping into the field 'vector' of each element
specified in second argument.
To return back to its default mode, a device driver should always call
pci_disable_msix() to undo the effect of pci_enable_msix(). Note that
a device driver should always call free_irq() on all MSI-X vectors it
has done request_irq() on before calling pci_disable_msix(). Failure
-to do so results a BUG_ON() and a device will be left with MSI-X
+to do so results in a BUG_ON() and a device will be left with MSI-X
enabled and leaks its vectors. Otherwise, the PCI subsystem switches a
device function's interrupt mode from MSI-X mode to legacy mode and
marks all allocated MSI-X vectors as unused.
@@ -383,53 +388,56 @@ MSI/MSI-X requests from other drivers, these MSI-X vectors may be
re-assigned.
For the case where the PCI subsystem re-assigned these MSI-X vectors
-to other driver, a request to switching back to MSI-X mode may result
+to other drivers, a request to switch back to MSI-X mode may result
being assigned with another set of MSI-X vectors or a failure if no
more vectors are available.
-5.4 Handling function implementng both MSI and MSI-X capabilities
+5.4 Handling function implementing both MSI and MSI-X capabilities
For the case where a function implements both MSI and MSI-X
capabilities, the PCI subsystem enables a device to run either in MSI
mode or MSI-X mode but not both. A device driver determines whether it
wants MSI or MSI-X enabled on its hardware device. Once a device
-driver requests for MSI, for example, it is prohibited to request for
+driver requests for MSI, for example, it is prohibited from requesting
MSI-X; in other words, a device driver is not permitted to ping-pong
between MSI mod MSI-X mode during a run-time.
5.5 Hardware requirements for MSI/MSI-X support
+
MSI/MSI-X support requires support from both system hardware and
individual hardware device functions.
5.5.1 System hardware support
+
Since the target of MSI address is the local APIC CPU, enabling
-MSI/MSI-X support in Linux kernel is dependent on whether existing
-system hardware supports local APIC. Users should verify their
-system whether it runs when CONFIG_X86_LOCAL_APIC=y.
+MSI/MSI-X support in the Linux kernel is dependent on whether existing
+system hardware supports local APIC. Users should verify that their
+system supports local APIC operation by testing that it runs when
+CONFIG_X86_LOCAL_APIC=y.
In SMP environment, CONFIG_X86_LOCAL_APIC is automatically set;
however, in UP environment, users must manually set
CONFIG_X86_LOCAL_APIC. Once CONFIG_X86_LOCAL_APIC=y, setting
-CONFIG_PCI_MSI enables the VECTOR based scheme and
-the option for MSI-capable device drivers to selectively enable
-MSI/MSI-X.
+CONFIG_PCI_MSI enables the VECTOR based scheme and the option for
+MSI-capable device drivers to selectively enable MSI/MSI-X.
Note that CONFIG_X86_IO_APIC setting is irrelevant because MSI/MSI-X
vector is allocated new during runtime and MSI/MSI-X support does not
depend on BIOS support. This key independency enables MSI/MSI-X
-support on future IOxAPIC free platform.
+support on future IOxAPIC free platforms.
5.5.2 Device hardware support
+
The hardware device function supports MSI by indicating the
MSI/MSI-X capability structure on its PCI capability list. By
default, this capability structure will not be initialized by
the kernel to enable MSI during the system boot. In other words,
the device function is running on its default pin assertion mode.
Note that in many cases the hardware supporting MSI have bugs,
-which may result in system hang. The software driver of specific
-MSI-capable hardware is responsible for whether calling
+which may result in system hangs. The software driver of specific
+MSI-capable hardware is responsible for deciding whether to call
pci_enable_msi or not. A return of zero indicates the kernel
-successfully initializes the MSI/MSI-X capability structure of the
+successfully initialized the MSI/MSI-X capability structure of the
device function. The device function is now running on MSI/MSI-X mode.
5.6 How to tell whether MSI/MSI-X is enabled on device function
@@ -439,10 +447,10 @@ pci_enable_msi()/pci_enable_msix() indicates to a device driver that
its device function is initialized successfully and ready to run in
MSI/MSI-X mode.
-At the user level, users can use command 'cat /proc/interrupts'
-to display the vector allocated for a device and its interrupt
-MSI/MSI-X mode ("PCI MSI"/"PCI MSIX"). Below shows below MSI mode is
-enabled on a SCSI Adaptec 39320D Ultra320.
+At the user level, users can use the command 'cat /proc/interrupts'
+to display the vectors allocated for devices and their interrupt
+MSI/MSI-X modes ("PCI-MSI"/"PCI-MSI-X"). Below shows MSI mode is
+enabled on a SCSI Adaptec 39320D Ultra320 controller.
CPU0 CPU1
0: 324639 0 IO-APIC-edge timer
@@ -453,8 +461,8 @@ enabled on a SCSI Adaptec 39320D Ultra320.
15: 1 0 IO-APIC-edge ide1
169: 0 0 IO-APIC-level uhci-hcd
185: 0 0 IO-APIC-level uhci-hcd
-193: 138 10 PCI MSI aic79xx
-201: 30 0 PCI MSI aic79xx
+193: 138 10 PCI-MSI aic79xx
+201: 30 0 PCI-MSI aic79xx
225: 30 0 IO-APIC-level aic7xxx
233: 30 0 IO-APIC-level aic7xxx
NMI: 0 0
@@ -490,8 +498,8 @@ target address set as 0xfeexxxxx, as conformed to PCI
specification 2.3 or latest, then it should work.
Q4. From the driver point of view, if the MSI is lost because
-of the errors occur during inbound memory write, then it may
-wait for ever. Is there a mechanism for it to recover?
+of errors occurring during inbound memory write, then it may
+wait forever. Is there a mechanism for it to recover?
A4. Since the target of the transaction is an inbound memory
write, all transaction termination conditions (Retry,
diff --git a/Documentation/RCU/torture.txt b/Documentation/RCU/torture.txt
new file mode 100644
index 000000000000..e4c38152f7f7
--- /dev/null
+++ b/Documentation/RCU/torture.txt
@@ -0,0 +1,122 @@
+RCU Torture Test Operation
+
+
+CONFIG_RCU_TORTURE_TEST
+
+The CONFIG_RCU_TORTURE_TEST config option is available for all RCU
+implementations. It creates an rcutorture kernel module that can
+be loaded to run a torture test. The test periodically outputs
+status messages via printk(), which can be examined via the dmesg
+command (perhaps grepping for "rcutorture"). The test is started
+when the module is loaded, and stops when the module is unloaded.
+
+However, actually setting this config option to "y" results in the system
+running the test immediately upon boot, and ending only when the system
+is taken down. Normally, one will instead want to build the system
+with CONFIG_RCU_TORTURE_TEST=m and to use modprobe and rmmod to control
+the test, perhaps using a script similar to the one shown at the end of
+this document. Note that you will need CONFIG_MODULE_UNLOAD in order
+to be able to end the test.
+
+
+MODULE PARAMETERS
+
+This module has the following parameters:
+
+nreaders This is the number of RCU reading threads supported.
+ The default is twice the number of CPUs. Why twice?
+ To properly exercise RCU implementations with preemptible
+ read-side critical sections.
+
+stat_interval The number of seconds between output of torture
+ statistics (via printk()). Regardless of the interval,
+ statistics are printed when the module is unloaded.
+ Setting the interval to zero causes the statistics to
+ be printed -only- when the module is unloaded, and this
+ is the default.
+
+verbose Enable debug printk()s. Default is disabled.
+
+
+OUTPUT
+
+The statistics output is as follows:
+
+ rcutorture: --- Start of test: nreaders=16 stat_interval=0 verbose=0
+ rcutorture: rtc: 0000000000000000 ver: 1916 tfle: 0 rta: 1916 rtaf: 0 rtf: 1915
+ rcutorture: Reader Pipe: 1466408 9747 0 0 0 0 0 0 0 0 0
+ rcutorture: Reader Batch: 1464477 11678 0 0 0 0 0 0 0 0
+ rcutorture: Free-Block Circulation: 1915 1915 1915 1915 1915 1915 1915 1915 1915 1915 0
+ rcutorture: --- End of test
+
+The command "dmesg | grep rcutorture:" will extract this information on
+most systems. On more esoteric configurations, it may be necessary to
+use other commands to access the output of the printk()s used by
+the RCU torture test. The printk()s use KERN_ALERT, so they should
+be evident. ;-)
+
+The entries are as follows:
+
+o "ggp": The number of counter flips (or batches) since boot.
+
+o "rtc": The hexadecimal address of the structure currently visible
+ to readers.
+
+o "ver": The number of times since boot that the rcutw writer task
+ has changed the structure visible to readers.
+
+o "tfle": If non-zero, indicates that the "torture freelist"
+ containing structure to be placed into the "rtc" area is empty.
+ This condition is important, since it can fool you into thinking
+ that RCU is working when it is not. :-/
+
+o "rta": Number of structures allocated from the torture freelist.
+
+o "rtaf": Number of allocations from the torture freelist that have
+ failed due to the list being empty.
+
+o "rtf": Number of frees into the torture freelist.
+
+o "Reader Pipe": Histogram of "ages" of structures seen by readers.
+ If any entries past the first two are non-zero, RCU is broken.
+ And rcutorture prints the error flag string "!!!" to make sure
+ you notice. The age of a newly allocated structure is zero,
+ it becomes one when removed from reader visibility, and is
+ incremented once per grace period subsequently -- and is freed
+ after passing through (RCU_TORTURE_PIPE_LEN-2) grace periods.
+
+ The output displayed above was taken from a correctly working
+ RCU. If you want to see what it looks like when broken, break
+ it yourself. ;-)
+
+o "Reader Batch": Another histogram of "ages" of structures seen
+ by readers, but in terms of counter flips (or batches) rather
+ than in terms of grace periods. The legal number of non-zero
+ entries is again two. The reason for this separate view is
+ that it is easier to get the third entry to show up in the
+ "Reader Batch" list than in the "Reader Pipe" list.
+
+o "Free-Block Circulation": Shows the number of torture structures
+ that have reached a given point in the pipeline. The first element
+ should closely correspond to the number of structures allocated,
+ the second to the number that have been removed from reader view,
+ and all but the last remaining to the corresponding number of
+ passes through a grace period. The last entry should be zero,
+ as it is only incremented if a torture structure's counter
+ somehow gets incremented farther than it should.
+
+
+USAGE
+
+The following script may be used to torture RCU:
+
+ #!/bin/sh
+
+ modprobe rcutorture
+ sleep 100
+ rmmod rcutorture
+ dmesg | grep rcutorture:
+
+The output can be manually inspected for the error flag of "!!!".
+One could of course create a more elaborate script that automatically
+checked for such errors.
diff --git a/Documentation/RCU/whatisRCU.txt b/Documentation/RCU/whatisRCU.txt
index 354d89c78377..15da16861fa3 100644
--- a/Documentation/RCU/whatisRCU.txt
+++ b/Documentation/RCU/whatisRCU.txt
@@ -772,8 +772,6 @@ RCU pointer/list traversal:
list_for_each_entry_rcu
list_for_each_continue_rcu (to be deprecated in favor of new
list_for_each_entry_continue_rcu)
- hlist_for_each_rcu (to be deprecated in favor of
- hlist_for_each_entry_rcu)
hlist_for_each_entry_rcu
RCU pointer update:
diff --git a/Documentation/arm/README b/Documentation/arm/README
index a6f718e90a86..5ed6f3530b86 100644
--- a/Documentation/arm/README
+++ b/Documentation/arm/README
@@ -8,10 +8,9 @@ Compilation of kernel
---------------------
In order to compile ARM Linux, you will need a compiler capable of
- generating ARM ELF code with GNU extensions. GCC 2.95.1, EGCS
- 1.1.2, and GCC 3.3 are known to be good compilers. Fortunately, you
- needn't guess. The kernel will report an error if your compiler is
- a recognized offender.
+ generating ARM ELF code with GNU extensions. GCC 3.3 is known to be
+ a good compiler. Fortunately, you needn't guess. The kernel will report
+ an error if your compiler is a recognized offender.
To build ARM Linux natively, you shouldn't have to alter the ARCH = line
in the top level Makefile. However, if you don't have the ARM Linux ELF
diff --git a/Documentation/arm/Samsung-S3C24XX/Overview.txt b/Documentation/arm/Samsung-S3C24XX/Overview.txt
index 3af4d29a8938..89aa89d526ac 100644
--- a/Documentation/arm/Samsung-S3C24XX/Overview.txt
+++ b/Documentation/arm/Samsung-S3C24XX/Overview.txt
@@ -81,7 +81,8 @@ Adding New Machines
Any large scale modifications, or new drivers should be discussed
on the ARM kernel mailing list (linux-arm-kernel) before being
- attempted.
+ attempted. See http://www.arm.linux.org.uk/mailinglists/ for the
+ mailing list information.
NAND
@@ -120,6 +121,43 @@ Clock Management
various clock units
+Platform Data
+-------------
+
+ Whenever a device has platform specific data that is specified
+ on a per-machine basis, care should be taken to ensure the
+ following:
+
+ 1) that default data is not left in the device to confuse the
+ driver if a machine does not set it at startup
+
+ 2) the data should (if possible) be marked as __initdata,
+ to ensure that the data is thrown away if the machine is
+ not the one currently in use.
+
+ The best way of doing this is to make a function that
+ kmalloc()s an area of memory, and copies the __initdata
+ and then sets the relevant device's platform data. Making
+ the function `__init` takes care of ensuring it is discarded
+ with the rest of the initialisation code
+
+ static __init void s3c24xx_xxx_set_platdata(struct xxx_data *pd)
+ {
+ struct s3c2410_xxx_mach_info *npd;
+
+ npd = kmalloc(sizeof(struct s3c2410_xxx_mach_info), GFP_KERNEL);
+ if (npd) {
+ memcpy(npd, pd, sizeof(struct s3c2410_xxx_mach_info));
+ s3c_device_xxx.dev.platform_data = npd;
+ } else {
+ printk(KERN_ERR "no memory for xxx platform data\n");
+ }
+ }
+
+ Note, since the code is marked as __init, it should not be
+ exported outside arch/arm/mach-s3c2410/, or exported to
+ modules via EXPORT_SYMBOL() and related functions.
+
Port Contributors
-----------------
@@ -149,6 +187,7 @@ Document Changes
06 Mar 2005 - BJD - Added Christer Weinigel
08 Mar 2005 - BJD - Added LCVR to list of people, updated introduction
08 Mar 2005 - BJD - Added section on adding machines
+ 09 Sep 2005 - BJD - Added section on platform data
Document Author
---------------
diff --git a/Documentation/block/biodoc.txt b/Documentation/block/biodoc.txt
index 6dd274d7e1cf..2d65c2182161 100644
--- a/Documentation/block/biodoc.txt
+++ b/Documentation/block/biodoc.txt
@@ -906,9 +906,20 @@ Aside:
4. The I/O scheduler
-I/O schedulers are now per queue. They should be runtime switchable and modular
-but aren't yet. Jens has most bits to do this, but the sysfs implementation is
-missing.
+I/O scheduler, a.k.a. elevator, is implemented in two layers. Generic dispatch
+queue and specific I/O schedulers. Unless stated otherwise, elevator is used
+to refer to both parts and I/O scheduler to specific I/O schedulers.
+
+Block layer implements generic dispatch queue in ll_rw_blk.c and elevator.c.
+The generic dispatch queue is responsible for properly ordering barrier
+requests, requeueing, handling non-fs requests and all other subtleties.
+
+Specific I/O schedulers are responsible for ordering normal filesystem
+requests. They can also choose to delay certain requests to improve
+throughput or whatever purpose. As the plural form indicates, there are
+multiple I/O schedulers. They can be built as modules but at least one should
+be built inside the kernel. Each queue can choose different one and can also
+change to another one dynamically.
A block layer call to the i/o scheduler follows the convention elv_xxx(). This
calls elevator_xxx_fn in the elevator switch (drivers/block/elevator.c). Oh,
@@ -921,44 +932,36 @@ keeping work.
The functions an elevator may implement are: (* are mandatory)
elevator_merge_fn called to query requests for merge with a bio
-elevator_merge_req_fn " " " with another request
+elevator_merge_req_fn called when two requests get merged. the one
+ which gets merged into the other one will be
+ never seen by I/O scheduler again. IOW, after
+ being merged, the request is gone.
elevator_merged_fn called when a request in the scheduler has been
involved in a merge. It is used in the deadline
scheduler for example, to reposition the request
if its sorting order has changed.
-*elevator_next_req_fn returns the next scheduled request, or NULL
- if there are none (or none are ready).
+elevator_dispatch_fn fills the dispatch queue with ready requests.
+ I/O schedulers are free to postpone requests by
+ not filling the dispatch queue unless @force
+ is non-zero. Once dispatched, I/O schedulers
+ are not allowed to manipulate the requests -
+ they belong to generic dispatch queue.
-*elevator_add_req_fn called to add a new request into the scheduler
+elevator_add_req_fn called to add a new request into the scheduler
elevator_queue_empty_fn returns true if the merge queue is empty.
Drivers shouldn't use this, but rather check
if elv_next_request is NULL (without losing the
request if one exists!)
-elevator_remove_req_fn This is called when a driver claims ownership of
- the target request - it now belongs to the
- driver. It must not be modified or merged.
- Drivers must not lose the request! A subsequent
- call of elevator_next_req_fn must return the
- _next_ request.
-
-elevator_requeue_req_fn called to add a request to the scheduler. This
- is used when the request has alrnadebeen
- returned by elv_next_request, but hasn't
- completed. If this is not implemented then
- elevator_add_req_fn is called instead.
-
elevator_former_req_fn
elevator_latter_req_fn These return the request before or after the
one specified in disk sort order. Used by the
block layer to find merge possibilities.
-elevator_completed_req_fn called when a request is completed. This might
- come about due to being merged with another or
- when the device completes the request.
+elevator_completed_req_fn called when a request is completed.
elevator_may_queue_fn returns true if the scheduler wants to allow the
current context to queue a new request even if
@@ -967,13 +970,33 @@ elevator_may_queue_fn returns true if the scheduler wants to allow the
elevator_set_req_fn
elevator_put_req_fn Must be used to allocate and free any elevator
- specific storate for a request.
+ specific storage for a request.
+
+elevator_activate_req_fn Called when device driver first sees a request.
+ I/O schedulers can use this callback to
+ determine when actual execution of a request
+ starts.
+elevator_deactivate_req_fn Called when device driver decides to delay
+ a request by requeueing it.
elevator_init_fn
elevator_exit_fn Allocate and free any elevator specific storage
for a queue.
-4.2 I/O scheduler implementation
+4.2 Request flows seen by I/O schedulers
+All requests seens by I/O schedulers strictly follow one of the following three
+flows.
+
+ set_req_fn ->
+
+ i. add_req_fn -> (merged_fn ->)* -> dispatch_fn -> activate_req_fn ->
+ (deactivate_req_fn -> activate_req_fn ->)* -> completed_req_fn
+ ii. add_req_fn -> (merged_fn ->)* -> merge_req_fn
+ iii. [none]
+
+ -> put_req_fn
+
+4.3 I/O scheduler implementation
The generic i/o scheduler algorithm attempts to sort/merge/batch requests for
optimal disk scan and request servicing performance (based on generic
principles and device capabilities), optimized for:
@@ -993,18 +1016,7 @@ request in sort order to prevent binary tree lookups.
This arrangement is not a generic block layer characteristic however, so
elevators may implement queues as they please.
-ii. Last merge hint
-The last merge hint is part of the generic queue layer. I/O schedulers must do
-some management on it. For the most part, the most important thing is to make
-sure q->last_merge is cleared (set to NULL) when the request on it is no longer
-a candidate for merging (for example if it has been sent to the driver).
-
-The last merge performed is cached as a hint for the subsequent request. If
-sequential data is being submitted, the hint is used to perform merges without
-any scanning. This is not sufficient when there are multiple processes doing
-I/O though, so a "merge hash" is used by some schedulers.
-
-iii. Merge hash
+ii. Merge hash
AS and deadline use a hash table indexed by the last sector of a request. This
enables merging code to quickly look up "back merge" candidates, even when
multiple I/O streams are being performed at once on one disk.
@@ -1013,29 +1025,8 @@ multiple I/O streams are being performed at once on one disk.
are far less common than "back merges" due to the nature of most I/O patterns.
Front merges are handled by the binary trees in AS and deadline schedulers.
-iv. Handling barrier cases
-A request with flags REQ_HARDBARRIER or REQ_SOFTBARRIER must not be ordered
-around. That is, they must be processed after all older requests, and before
-any newer ones. This includes merges!
-
-In AS and deadline schedulers, barriers have the effect of flushing the reorder
-queue. The performance cost of this will vary from nothing to a lot depending
-on i/o patterns and device characteristics. Obviously they won't improve
-performance, so their use should be kept to a minimum.
-
-v. Handling insertion position directives
-A request may be inserted with a position directive. The directives are one of
-ELEVATOR_INSERT_BACK, ELEVATOR_INSERT_FRONT, ELEVATOR_INSERT_SORT.
-
-ELEVATOR_INSERT_SORT is a general directive for non-barrier requests.
-ELEVATOR_INSERT_BACK is used to insert a barrier to the back of the queue.
-ELEVATOR_INSERT_FRONT is used to insert a barrier to the front of the queue, and
-overrides the ordering requested by any previous barriers. In practice this is
-harmless and required, because it is used for SCSI requeueing. This does not
-require flushing the reorder queue, so does not impose a performance penalty.
-
-vi. Plugging the queue to batch requests in anticipation of opportunities for
- merge/sort optimizations
+iii. Plugging the queue to batch requests in anticipation of opportunities for
+ merge/sort optimizations
This is just the same as in 2.4 so far, though per-device unplugging
support is anticipated for 2.5. Also with a priority-based i/o scheduler,
@@ -1069,7 +1060,7 @@ Aside:
blk_kick_queue() to unplug a specific queue (right away ?)
or optionally, all queues, is in the plan.
-4.3 I/O contexts
+4.4 I/O contexts
I/O contexts provide a dynamically allocated per process data area. They may
be used in I/O schedulers, and in the block layer (could be used for IO statis,
priorities for example). See *io_context in drivers/block/ll_rw_blk.c, and
diff --git a/Documentation/cachetlb.txt b/Documentation/cachetlb.txt
index e132fb1163b0..7eb715e07eda 100644
--- a/Documentation/cachetlb.txt
+++ b/Documentation/cachetlb.txt
@@ -49,9 +49,6 @@ changes occur:
page table operations such as what happens during
fork, and exec.
- Platform developers note that generic code will always
- invoke this interface without mm->page_table_lock held.
-
3) void flush_tlb_range(struct vm_area_struct *vma,
unsigned long start, unsigned long end)
@@ -72,9 +69,6 @@ changes occur:
call flush_tlb_page (see below) for each entry which may be
modified.
- Platform developers note that generic code will always
- invoke this interface with mm->page_table_lock held.
-
4) void flush_tlb_page(struct vm_area_struct *vma, unsigned long addr)
This time we need to remove the PAGE_SIZE sized translation
@@ -93,9 +87,6 @@ changes occur:
This is used primarily during fault processing.
- Platform developers note that generic code will always
- invoke this interface with mm->page_table_lock held.
-
5) void flush_tlb_pgtables(struct mm_struct *mm,
unsigned long start, unsigned long end)
diff --git a/Documentation/connector/cn_test.c b/Documentation/connector/cn_test.c
index b7de82e9c0e0..3e73231695b3 100644
--- a/Documentation/connector/cn_test.c
+++ b/Documentation/connector/cn_test.c
@@ -25,7 +25,7 @@
#include <linux/skbuff.h>
#include <linux/timer.h>
-#include "connector.h"
+#include <linux/connector.h>
static struct cb_id cn_test_id = { 0x123, 0x456 };
static char cn_test_name[] = "cn_test";
@@ -104,7 +104,7 @@ static int cn_test_want_notify(void)
req->first = cn_test_id.val + 20;
req->range = 10;
- NETLINK_CB(skb).dst_groups = ctl->group;
+ NETLINK_CB(skb).dst_group = ctl->group;
//netlink_broadcast(nls, skb, 0, ctl->group, GFP_ATOMIC);
netlink_unicast(nls, skb, 0, 0);
diff --git a/Documentation/cpusets.txt b/Documentation/cpusets.txt
index d17b7d2dd771..a09a8eb80665 100644
--- a/Documentation/cpusets.txt
+++ b/Documentation/cpusets.txt
@@ -94,7 +94,7 @@ the available CPU and Memory resources amongst the requesting tasks.
But larger systems, which benefit more from careful processor and
memory placement to reduce memory access times and contention,
and which typically represent a larger investment for the customer,
-can benefit from explictly placing jobs on properly sized subsets of
+can benefit from explicitly placing jobs on properly sized subsets of
the system.
This can be especially valuable on:
diff --git a/Documentation/device-mapper/snapshot.txt b/Documentation/device-mapper/snapshot.txt
index dca274ff4005..a5009c8300f3 100644
--- a/Documentation/device-mapper/snapshot.txt
+++ b/Documentation/device-mapper/snapshot.txt
@@ -19,7 +19,6 @@ There are two dm targets available: snapshot and snapshot-origin.
*) snapshot-origin <origin>
which will normally have one or more snapshots based on it.
-You must create the snapshot-origin device before you can create snapshots.
Reads will be mapped directly to the backing device. For each write, the
original data will be saved in the <COW device> of each snapshot to keep
its visible content unchanged, at least until the <COW device> fills up.
@@ -27,7 +26,7 @@ its visible content unchanged, at least until the <COW device> fills up.
*) snapshot <origin> <COW device> <persistent?> <chunksize>
-A snapshot is created of the <origin> block device. Changed chunks of
+A snapshot of the <origin> block device is created. Changed chunks of
<chunksize> sectors will be stored on the <COW device>. Writes will
only go to the <COW device>. Reads will come from the <COW device> or
from <origin> for unchanged data. <COW device> will often be
@@ -37,6 +36,8 @@ the amount of free space and expand the <COW device> before it fills up.
<persistent?> is P (Persistent) or N (Not persistent - will not survive
after reboot).
+The difference is that for transient snapshots less metadata must be
+saved on disk - they can be kept in memory by the kernel.
How this is used by LVM2
diff --git a/Documentation/driver-model/driver.txt b/Documentation/driver-model/driver.txt
index fabaca1ab1b0..59806c9761f7 100644
--- a/Documentation/driver-model/driver.txt
+++ b/Documentation/driver-model/driver.txt
@@ -14,8 +14,8 @@ struct device_driver {
int (*probe) (struct device * dev);
int (*remove) (struct device * dev);
- int (*suspend) (struct device * dev, pm_message_t state, u32 level);
- int (*resume) (struct device * dev, u32 level);
+ int (*suspend) (struct device * dev, pm_message_t state);
+ int (*resume) (struct device * dev);
};
@@ -194,69 +194,13 @@ device; i.e. anything in the device's driver_data field.
If the device is still present, it should quiesce the device and place
it into a supported low-power state.
- int (*suspend) (struct device * dev, pm_message_t state, u32 level);
+ int (*suspend) (struct device * dev, pm_message_t state);
-suspend is called to put the device in a low power state. There are
-several stages to successfully suspending a device, which is denoted in
-the @level parameter. Breaking the suspend transition into several
-stages affords the platform flexibility in performing device power
-management based on the requirements of the system and the
-user-defined policy.
+suspend is called to put the device in a low power state.
-SUSPEND_NOTIFY notifies the device that a suspend transition is about
-to happen. This happens on system power state transitions to verify
-that all devices can successfully suspend.
+ int (*resume) (struct device * dev);
-A driver may choose to fail on this call, which should cause the
-entire suspend transition to fail. A driver should fail only if it
-knows that the device will not be able to be resumed properly when the
-system wakes up again. It could also fail if it somehow determines it
-is in the middle of an operation too important to stop.
-
-SUSPEND_DISABLE tells the device to stop I/O transactions. When it
-stops transactions, or what it should do with unfinished transactions
-is a policy of the driver. After this call, the driver should not
-accept any other I/O requests.
-
-SUSPEND_SAVE_STATE tells the device to save the context of the
-hardware. This includes any bus-specific hardware state and
-device-specific hardware state. A pointer to this saved state can be
-stored in the device's saved_state field.
-
-SUSPEND_POWER_DOWN tells the driver to place the device in the low
-power state requested.
-
-Whether suspend is called with a given level is a policy of the
-platform. Some levels may be omitted; drivers must not assume the
-reception of any level. However, all levels must be called in the
-order above; i.e. notification will always come before disabling;
-disabling the device will come before suspending the device.
-
-All calls are made with interrupts enabled, except for the
-SUSPEND_POWER_DOWN level.
-
- int (*resume) (struct device * dev, u32 level);
-
-Resume is used to bring a device back from a low power state. Like the
-suspend transition, it happens in several stages.
-
-RESUME_POWER_ON tells the driver to set the power state to the state
-before the suspend call (The device could have already been in a low
-power state before the suspend call to put in a lower power state).
-
-RESUME_RESTORE_STATE tells the driver to restore the state saved by
-the SUSPEND_SAVE_STATE suspend call.
-
-RESUME_ENABLE tells the driver to start accepting I/O transactions
-again. Depending on driver policy, the device may already have pending
-I/O requests.
-
-RESUME_POWER_ON is called with interrupts disabled. The other resume
-levels are called with interrupts enabled.
-
-As with the various suspend stages, the driver must not assume that
-any other resume calls have been or will be made. Each call should be
-self-contained and not dependent on any external state.
+Resume is used to bring a device back from a low power state.
Attributes
diff --git a/Documentation/driver-model/porting.txt b/Documentation/driver-model/porting.txt
index ff2fef2107f0..98b233cb8b36 100644
--- a/Documentation/driver-model/porting.txt
+++ b/Documentation/driver-model/porting.txt
@@ -350,7 +350,7 @@ When a driver is registered, the bus's list of devices is iterated
over. bus->match() is called for each device that is not already
claimed by a driver.
-When a device is successfully bound to a device, device->driver is
+When a device is successfully bound to a driver, device->driver is
set, the device is added to a per-driver list of devices, and a
symlink is created in the driver's sysfs directory that points to the
device's physical directory:
diff --git a/Documentation/dvb/bt8xx.txt b/Documentation/dvb/bt8xx.txt
index cb63b7a93c82..df6c05453cb5 100644
--- a/Documentation/dvb/bt8xx.txt
+++ b/Documentation/dvb/bt8xx.txt
@@ -1,5 +1,5 @@
-How to get the Nebula, PCTV and Twinhan DST cards working
-=========================================================
+How to get the Nebula, PCTV, FusionHDTV Lite and Twinhan DST cards working
+==========================================================================
This class of cards has a bt878a as the PCI interface, and
require the bttv driver.
@@ -26,27 +26,31 @@ Furthermore you need to enable
In general you need to load the bttv driver, which will handle the gpio and
i2c communication for us, plus the common dvb-bt8xx device driver.
-The frontends for Nebula (nxt6000), Pinnacle PCTV (cx24110) and
-TwinHan (dst) are loaded automatically by the dvb-bt8xx device driver.
+The frontends for Nebula (nxt6000), Pinnacle PCTV (cx24110), TwinHan (dst),
+FusionHDTV DVB-T Lite (mt352) and FusionHDTV5 Lite (lgdt330x) are loaded
+automatically by the dvb-bt8xx device driver.
-3a) Nebula / Pinnacle PCTV
---------------------------
+3a) Nebula / Pinnacle PCTV / FusionHDTV Lite
+---------------------------------------------
$ modprobe bttv (normally bttv is being loaded automatically by kmod)
- $ modprobe dvb-bt8xx (or just place dvb-bt8xx in /etc/modules for automatic loading)
+ $ modprobe dvb-bt8xx
+
+(or just place dvb-bt8xx in /etc/modules for automatic loading)
3b) TwinHan and Clones
--------------------------
- $ modprobe bttv i2c_hw=1 card=0x71
+ $ modprobe bttv card=0x71
$ modprobe dvb-bt8xx
$ modprobe dst
The value 0x71 will override the PCI type detection for dvb-bt8xx,
-which is necessary for TwinHan cards.
+which is necessary for TwinHan cards. Omission of this parameter might result
+in a system lockup.
-If you're having an older card (blue color circuit) and card=0x71 locks
+If you're having an older card (blue color PCB) and card=0x71 locks up
your machine, try using 0x68, too. If that does not work, ask on the
mailing list.
@@ -64,11 +68,47 @@ verbose=0 means complete disabling of messages
dst_addons takes values 0 and 0x20. A value of 0 means it is a FTA card.
0x20 means it has a Conditional Access slot.
-The autodected values are determined bythe cards 'response
-string' which you can see in your logs e.g.
+The autodetected values are determined by the cards 'response string'
+which you can see in your logs e.g.
dst_get_device_id: Recognise [DSTMCI]
+If you need to sent in bug reports on the dst, please do send in a complete
+log with the verbose=4 module parameter. For general usage, the default setting
+of verbose=1 is ideal.
+
+
+4) Multiple cards
+--------------------------
+
+If you happen to be running multiple cards, it would be advisable to load
+the bttv module with the card id. This would help to solve any module loading
+problems that you might face.
+
+For example, if you have a Twinhan and Clones card along with a FusionHDTV5 Lite
+
+ $ modprobe bttv card=0x71 card=0x87
+
+Here the order of the card id is important and should be the same as that of the
+physical order of the cards. Here card=0x71 represents the Twinhan and clones
+and card=0x87 represents Fusion HDTV5 Lite. These arguments can also be
+specified in decimal, rather than hex:
+
+ $ modprobe bttv card=113 card=135
+
+Some examples of card-id's
+
+Pinnacle Sat 0x5e (94)
+Nebula Digi TV 0x68 (104)
+PC HDTV 0x70 (112)
+Twinhan 0x71 (113)
+FusionHDTV DVB-T Lite 0x80 (128)
+FusionHDTV5 Lite 0x87 (135)
+
+For a full list of card-id's, see the V4L Documentation within the kernel
+source: linux/Documentation/video4linux/CARDLIST.bttv
+
+If you have problems with this please do ask on the mailing list.
--
Authors: Richard Walker, Jamie Honan, Michael Hunold, Manu Abraham
diff --git a/Documentation/dvb/cards.txt b/Documentation/dvb/cards.txt
index efdc4ee9d40c..19329cf7b097 100644
--- a/Documentation/dvb/cards.txt
+++ b/Documentation/dvb/cards.txt
@@ -41,6 +41,12 @@ o Frontends drivers:
- dib3000mb : DiBcom 3000-MB demodulator
DVB-S/C/T:
- dst : TwinHan DST Frontend
+ ATSC:
+ - nxt200x : Nxtwave NXT2002 & NXT2004
+ - or51211 : or51211 based (pcHDTV HD2000 card)
+ - or51132 : or51132 based (pcHDTV HD3000 card)
+ - bcm3510 : Broadcom BCM3510
+ - lgdt330x : LG Electronics DT3302 & DT3303
o Cards based on the Phillips saa7146 multimedia PCI bridge chip:
@@ -62,6 +68,10 @@ o Cards based on the Conexant Bt8xx PCI bridge:
- Nebula Electronics DigiTV
- TwinHan DST
- Avermedia DVB-T
+ - ChainTech digitop DST-1000 DVB-S
+ - pcHDTV HD-2000 TV
+ - DViCO FusionHDTV DVB-T Lite
+ - DViCO FusionHDTV5 Lite
o Technotrend / Hauppauge DVB USB devices:
- Nova USB
@@ -83,3 +93,30 @@ o DiBcom DVB-T USB based devices:
- DiBcom USB2.0 DVB-T reference device (non-public)
o Experimental support for the analog module of the Siemens DVB-C PCI card
+
+o Cards based on the Conexant cx2388x PCI bridge:
+ - ADS Tech Instant TV DVB-T PCI
+ - ATI HDTV Wonder
+ - digitalnow DNTV Live! DVB-T
+ - DViCO FusionHDTV DVB-T1
+ - DViCO FusionHDTV DVB-T Plus
+ - DViCO FusionHDTV3 Gold-Q
+ - DViCO FusionHDTV3 Gold-T
+ - DViCO FusionHDTV5 Gold
+ - Hauppauge Nova-T DVB-T
+ - KWorld/VStream XPert DVB-T
+ - pcHDTV HD3000 HDTV
+ - TerraTec Cinergy 1400 DVB-T
+ - WinFast DTV1000-T
+
+o Cards based on the Phillips saa7134 PCI bridge:
+ - Medion 7134
+ - Pinnacle PCTV 300i DVB-T + PAL
+ - LifeView FlyDVB-T DUO
+ - Typhoon DVB-T Duo Digital/Analog Cardbus
+ - Philips TOUGH DVB-T reference design
+ - Philips EUROPA V3 reference design
+ - Compro Videomate DVB-T300
+ - Compro Videomate DVB-T200
+ - AVerMedia AVerTVHD MCE A180
+
diff --git a/Documentation/dvb/contributors.txt b/Documentation/dvb/contributors.txt
index c9d5ce370701..2cbd2d0f6fdf 100644
--- a/Documentation/dvb/contributors.txt
+++ b/Documentation/dvb/contributors.txt
@@ -75,5 +75,22 @@ Ernst Peinlich <e.peinlich@inode.at>
Peter Beutner <p.beutner@gmx.net>
for the IR code for the ttusb-dec driver
+Wilson Michaels <wilsonmichaels@earthlink.net>
+ for the lgdt330x frontend driver, and various bugfixes
+
+Michael Krufky <mkrufky@m1k.net>
+ for maintaining v4l/dvb inter-tree dependencies
+
+Taylor Jacob <rtjacob@earthlink.net>
+ for the nxt2002 frontend driver
+
+Jean-Francois Thibert <jeanfrancois@sagetv.com>
+ for the nxt2004 frontend driver
+
+Kirk Lapray <kirk.lapray@gmail.com>
+ for the or51211 and or51132 frontend drivers, and
+ for merging the nxt2002 and nxt2004 modules into a
+ single nxt200x frontend driver.
+
(If you think you should be in this list, but you are not, drop a
line to the DVB mailing list)
diff --git a/Documentation/dvb/get_dvb_firmware b/Documentation/dvb/get_dvb_firmware
index a750f0101d9d..be6eb4c75991 100644
--- a/Documentation/dvb/get_dvb_firmware
+++ b/Documentation/dvb/get_dvb_firmware
@@ -22,7 +22,7 @@ use File::Temp qw/ tempdir /;
use IO::Handle;
@components = ( "sp8870", "sp887x", "tda10045", "tda10046", "av7110", "dec2000t",
- "dec2540t", "dec3000s", "vp7041", "dibusb", "nxt2002",
+ "dec2540t", "dec3000s", "vp7041", "dibusb", "nxt2002", "nxt2004",
"or51211", "or51132_qam", "or51132_vsb");
# Check args
@@ -252,6 +252,23 @@ sub nxt2002 {
$outfile;
}
+sub nxt2004 {
+ my $sourcefile = "AVerTVHD_MCE_A180_Drv_v1.2.2.16.zip";
+ my $url = "http://www.aver.com/support/Drivers/$sourcefile";
+ my $hash = "111cb885b1e009188346d72acfed024c";
+ my $outfile = "dvb-fe-nxt2004.fw";
+ my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 1);
+
+ checkstandard();
+
+ wgetfile($sourcefile, $url);
+ unzip($sourcefile, $tmpdir);
+ verify("$tmpdir/3xHybrid.sys", $hash);
+ extract("$tmpdir/3xHybrid.sys", 465304, 9584, $outfile);
+
+ $outfile;
+}
+
sub or51211 {
my $fwfile = "dvb-fe-or51211.fw";
my $url = "http://linuxtv.org/downloads/firmware/$fwfile";
diff --git a/Documentation/fb/fbcon.txt b/Documentation/fb/fbcon.txt
new file mode 100644
index 000000000000..08dce0f631bf
--- /dev/null
+++ b/Documentation/fb/fbcon.txt
@@ -0,0 +1,152 @@
+The Framebuffer Console
+=======================
+
+ The framebuffer console (fbcon), as its name implies, is a text
+console running on top of the framebuffer device. It has the functionality of
+any standard text console driver, such as the VGA console, with the added
+features that can be attributed to the graphical nature of the framebuffer.
+
+ In the x86 architecture, the framebuffer console is optional, and
+some even treat it as a toy. For other architectures, it is the only available
+display device, text or graphical.
+
+ What are the features of fbcon? The framebuffer console supports
+high resolutions, varying font types, display rotation, primitive multihead,
+etc. Theoretically, multi-colored fonts, blending, aliasing, and any feature
+made available by the underlying graphics card are also possible.
+
+A. Configuration
+
+ The framebuffer console can be enabled by using your favorite kernel
+configuration tool. It is under Device Drivers->Graphics Support->Support for
+framebuffer devices->Framebuffer Console Support. Select 'y' to compile
+support statically, or 'm' for module support. The module will be fbcon.
+
+ In order for fbcon to activate, at least one framebuffer driver is
+required, so choose from any of the numerous drivers available. For x86
+systems, they almost universally have VGA cards, so vga16fb and vesafb will
+always be available. However, using a chipset-specific driver will give you
+more speed and features, such as the ability to change the video mode
+dynamically.
+
+ To display the penguin logo, choose any logo available in Logo
+Configuration->Boot up logo.
+
+ Also, you will need to select at least one compiled-in fonts, but if
+you don't do anything, the kernel configuration tool will select one for you,
+usually an 8x16 font.
+
+GOTCHA: A common bug report is enabling the framebuffer without enabling the
+framebuffer console. Depending on the driver, you may get a blanked or
+garbled display, but the system still boots to completion. If you are
+fortunate to have a driver that does not alter the graphics chip, then you
+will still get a VGA console.
+
+B. Loading
+
+Possible scenarios:
+
+1. Driver and fbcon are compiled statically
+
+ Usually, fbcon will automatically take over your console. The notable
+ exception is vesafb. It needs to be explicitly activated with the
+ vga= boot option parameter.
+
+2. Driver is compiled statically, fbcon is compiled as a module
+
+ Depending on the driver, you either get a standard console, or a
+ garbled display, as mentioned above. To get a framebuffer console,
+ do a 'modprobe fbcon'.
+
+3. Driver is compiled as a module, fbcon is compiled statically
+
+ You get your standard console. Once the driver is loaded with
+ 'modprobe xxxfb', fbcon automatically takes over the console with
+ the possible exception of using the fbcon=map:n option. See below.
+
+4. Driver and fbcon are compiled as a module.
+
+ You can load them in any order. Once both are loaded, fbcon will take
+ over the console.
+
+C. Boot options
+
+ The framebuffer console has several, largely unknown, boot options
+ that can change its behavior.
+
+1. fbcon=font:<name>
+
+ Select the initial font to use. The value 'name' can be any of the
+ compiled-in fonts: VGA8x16, 7x14, 10x18, VGA8x8, MINI4x6, RomanLarge,
+ SUN8x16, SUN12x22, ProFont6x11, Acorn8x8, PEARL8x8.
+
+ Note, not all drivers can handle font with widths not divisible by 8,
+ such as vga16fb.
+
+2. fbcon=scrollback:<value>[k]
+
+ The scrollback buffer is memory that is used to preserve display
+ contents that has already scrolled past your view. This is accessed
+ by using the Shift-PageUp key combination. The value 'value' is any
+ integer. It defaults to 32KB. The 'k' suffix is optional, and will
+ multiply the 'value' by 1024.
+
+3. fbcon=map:<0123>
+
+ This is an interesting option. It tells which driver gets mapped to
+ which console. The value '0123' is a sequence that gets repeated until
+ the total length is 64 which is the number of consoles available. In
+ the above example, it is expanded to 012301230123... and the mapping
+ will be:
+
+ tty | 1 2 3 4 5 6 7 8 9 ...
+ fb | 0 1 2 3 0 1 2 3 0 ...
+
+ ('cat /proc/fb' should tell you what the fb numbers are)
+
+ One side effect that may be useful is using a map value that exceeds
+ the number of loaded fb drivers. For example, if only one driver is
+ available, fb0, adding fbcon=map:1 tells fbcon not to take over the
+ console.
+
+ Later on, when you want to map the console the to the framebuffer
+ device, you can use the con2fbmap utility.
+
+4. fbcon=vc:<n1>-<n2>
+
+ This option tells fbcon to take over only a range of consoles as
+ specified by the values 'n1' and 'n2'. The rest of the consoles
+ outside the given range will still be controlled by the standard
+ console driver.
+
+ NOTE: For x86 machines, the standard console is the VGA console which
+ is typically located on the same video card. Thus, the consoles that
+ are controlled by the VGA console will be garbled.
+
+4. fbcon=rotate:<n>
+
+ This option changes the orientation angle of the console display. The
+ value 'n' accepts the following:
+
+ 0 - normal orientation (0 degree)
+ 1 - clockwise orientation (90 degrees)
+ 2 - upside down orientation (180 degrees)
+ 3 - counterclockwise orientation (270 degrees)
+
+ The angle can be changed anytime afterwards by 'echoing' the same
+ numbers to any one of the 2 attributes found in
+ /sys/class/graphics/fb{x}
+
+ con_rotate - rotate the display of the active console
+ con_rotate_all - rotate the display of all consoles
+
+ Console rotation will only become available if Console Rotation
+ Support is compiled in your kernel.
+
+ NOTE: This is purely console rotation. Any other applications that
+ use the framebuffer will remain at their 'normal'orientation.
+ Actually, the underlying fb driver is totally ignorant of console
+ rotation.
+
+---
+Antonino Daplas <adaplas@pol.net>
diff --git a/Documentation/fb/vesafb.txt b/Documentation/fb/vesafb.txt
index 62db6758d1c1..ee277dd204b0 100644
--- a/Documentation/fb/vesafb.txt
+++ b/Documentation/fb/vesafb.txt
@@ -146,10 +146,10 @@ pmipal Use the protected mode interface for palette changes.
mtrr:n setup memory type range registers for the vesafb framebuffer
where n:
- 0 - disabled (equivalent to nomtrr)
+ 0 - disabled (equivalent to nomtrr) (default)
1 - uncachable
2 - write-back
- 3 - write-combining (default)
+ 3 - write-combining
4 - write-through
If you see the following in dmesg, choose the type that matches the
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
index b67189a8d8d4..429db4bf98ec 100644
--- a/Documentation/feature-removal-schedule.txt
+++ b/Documentation/feature-removal-schedule.txt
@@ -25,6 +25,13 @@ Who: Adrian Bunk <bunk@stusta.de>
---------------------------
+What: drivers depending on OBSOLETE_OSS_DRIVER
+When: January 2006
+Why: OSS drivers with ALSA replacements
+Who: Adrian Bunk <bunk@stusta.de>
+
+---------------------------
+
What: RCU API moves to EXPORT_SYMBOL_GPL
When: April 2006
Files: include/linux/rcupdate.h, kernel/rcupdate.c
@@ -60,6 +67,21 @@ Who: Jody McIntyre <scjody@steamballoon.com>
---------------------------
+What: Video4Linux API 1 ioctls and video_decoder.h from Video devices.
+When: July 2006
+Why: V4L1 AP1 was replaced by V4L2 API. during migration from 2.4 to 2.6
+ series. The old API have lots of drawbacks and don't provide enough
+ means to work with all video and audio standards. The newer API is
+ already available on the main drivers and should be used instead.
+ Newer drivers should use v4l_compat_translate_ioctl function to handle
+ old calls, replacing to newer ones.
+ Decoder iocts are using internally to allow video drivers to
+ communicate with video decoders. This should also be improved to allow
+ V4L2 calls being translated into compatible internal ioctls.
+Who: Mauro Carvalho Chehab <mchehab@brturbo.com.br>
+
+---------------------------
+
What: i2c sysfs name change: in1_ref, vid deprecated in favour of cpu0_vid
When: November 2005
Files: drivers/i2c/chips/adm1025.c, drivers/i2c/chips/adm1026.c
@@ -69,6 +91,22 @@ Who: Grant Coady <gcoady@gmail.com>
---------------------------
+What: remove EXPORT_SYMBOL(panic_timeout)
+When: April 2006
+Files: kernel/panic.c
+Why: No modular usage in the kernel.
+Who: Adrian Bunk <bunk@stusta.de>
+
+---------------------------
+
+What: remove EXPORT_SYMBOL(insert_resource)
+When: April 2006
+Files: kernel/resource.c
+Why: No modular usage in the kernel.
+Who: Adrian Bunk <bunk@stusta.de>
+
+---------------------------
+
What: PCMCIA control ioctl (needed for pcmcia-cs [cardmgr, cardctl])
When: November 2005
Files: drivers/pcmcia/: pcmcia_ioctl.c
@@ -95,3 +133,10 @@ Why: This interface has been obsoleted by the new layer3-independent
to link against API-compatible library on top of libnfnetlink_queue
instead of the current 'libipq'.
Who: Harald Welte <laforge@netfilter.org>
+
+---------------------------
+
+What: EXPORT_SYMBOL(lookup_hash)
+When: January 2006
+Why: Too low-level interface. Use lookup_one_len or lookup_create instead.
+Who: Christoph Hellwig <hch@lst.de>
diff --git a/Documentation/filesystems/dentry-locking.txt b/Documentation/filesystems/dentry-locking.txt
new file mode 100644
index 000000000000..4c0c575a4012
--- /dev/null
+++ b/Documentation/filesystems/dentry-locking.txt
@@ -0,0 +1,173 @@
+RCU-based dcache locking model
+==============================
+
+On many workloads, the most common operation on dcache is to look up a
+dentry, given a parent dentry and the name of the child. Typically,
+for every open(), stat() etc., the dentry corresponding to the
+pathname will be looked up by walking the tree starting with the first
+component of the pathname and using that dentry along with the next
+component to look up the next level and so on. Since it is a frequent
+operation for workloads like multiuser environments and web servers,
+it is important to optimize this path.
+
+Prior to 2.5.10, dcache_lock was acquired in d_lookup and thus in
+every component during path look-up. Since 2.5.10 onwards, fast-walk
+algorithm changed this by holding the dcache_lock at the beginning and
+walking as many cached path component dentries as possible. This
+significantly decreases the number of acquisition of
+dcache_lock. However it also increases the lock hold time
+significantly and affects performance in large SMP machines. Since
+2.5.62 kernel, dcache has been using a new locking model that uses RCU
+to make dcache look-up lock-free.
+
+The current dcache locking model is not very different from the
+existing dcache locking model. Prior to 2.5.62 kernel, dcache_lock
+protected the hash chain, d_child, d_alias, d_lru lists as well as
+d_inode and several other things like mount look-up. RCU-based changes
+affect only the way the hash chain is protected. For everything else
+the dcache_lock must be taken for both traversing as well as
+updating. The hash chain updates too take the dcache_lock. The
+significant change is the way d_lookup traverses the hash chain, it
+doesn't acquire the dcache_lock for this and rely on RCU to ensure
+that the dentry has not been *freed*.
+
+
+Dcache locking details
+======================
+
+For many multi-user workloads, open() and stat() on files are very
+frequently occurring operations. Both involve walking of path names to
+find the dentry corresponding to the concerned file. In 2.4 kernel,
+dcache_lock was held during look-up of each path component. Contention
+and cache-line bouncing of this global lock caused significant
+scalability problems. With the introduction of RCU in Linux kernel,
+this was worked around by making the look-up of path components during
+path walking lock-free.
+
+
+Safe lock-free look-up of dcache hash table
+===========================================
+
+Dcache is a complex data structure with the hash table entries also
+linked together in other lists. In 2.4 kernel, dcache_lock protected
+all the lists. We applied RCU only on hash chain walking. The rest of
+the lists are still protected by dcache_lock. Some of the important
+changes are :
+
+1. The deletion from hash chain is done using hlist_del_rcu() macro
+ which doesn't initialize next pointer of the deleted dentry and
+ this allows us to walk safely lock-free while a deletion is
+ happening.
+
+2. Insertion of a dentry into the hash table is done using
+ hlist_add_head_rcu() which take care of ordering the writes - the
+ writes to the dentry must be visible before the dentry is
+ inserted. This works in conjunction with hlist_for_each_rcu() while
+ walking the hash chain. The only requirement is that all
+ initialization to the dentry must be done before
+ hlist_add_head_rcu() since we don't have dcache_lock protection
+ while traversing the hash chain. This isn't different from the
+ existing code.
+
+3. The dentry looked up without holding dcache_lock by cannot be
+ returned for walking if it is unhashed. It then may have a NULL
+ d_inode or other bogosity since RCU doesn't protect the other
+ fields in the dentry. We therefore use a flag DCACHE_UNHASHED to
+ indicate unhashed dentries and use this in conjunction with a
+ per-dentry lock (d_lock). Once looked up without the dcache_lock,
+ we acquire the per-dentry lock (d_lock) and check if the dentry is
+ unhashed. If so, the look-up is failed. If not, the reference count
+ of the dentry is increased and the dentry is returned.
+
+4. Once a dentry is looked up, it must be ensured during the path walk
+ for that component it doesn't go away. In pre-2.5.10 code, this was
+ done holding a reference to the dentry. dcache_rcu does the same.
+ In some sense, dcache_rcu path walking looks like the pre-2.5.10
+ version.
+
+5. All dentry hash chain updates must take the dcache_lock as well as
+ the per-dentry lock in that order. dput() does this to ensure that
+ a dentry that has just been looked up in another CPU doesn't get
+ deleted before dget() can be done on it.
+
+6. There are several ways to do reference counting of RCU protected
+ objects. One such example is in ipv4 route cache where deferred
+ freeing (using call_rcu()) is done as soon as the reference count
+ goes to zero. This cannot be done in the case of dentries because
+ tearing down of dentries require blocking (dentry_iput()) which
+ isn't supported from RCU callbacks. Instead, tearing down of
+ dentries happen synchronously in dput(), but actual freeing happens
+ later when RCU grace period is over. This allows safe lock-free
+ walking of the hash chains, but a matched dentry may have been
+ partially torn down. The checking of DCACHE_UNHASHED flag with
+ d_lock held detects such dentries and prevents them from being
+ returned from look-up.
+
+
+Maintaining POSIX rename semantics
+==================================
+
+Since look-up of dentries is lock-free, it can race against a
+concurrent rename operation. For example, during rename of file A to
+B, look-up of either A or B must succeed. So, if look-up of B happens
+after A has been removed from the hash chain but not added to the new
+hash chain, it may fail. Also, a comparison while the name is being
+written concurrently by a rename may result in false positive matches
+violating rename semantics. Issues related to race with rename are
+handled as described below :
+
+1. Look-up can be done in two ways - d_lookup() which is safe from
+ simultaneous renames and __d_lookup() which is not. If
+ __d_lookup() fails, it must be followed up by a d_lookup() to
+ correctly determine whether a dentry is in the hash table or
+ not. d_lookup() protects look-ups using a sequence lock
+ (rename_lock).
+
+2. The name associated with a dentry (d_name) may be changed if a
+ rename is allowed to happen simultaneously. To avoid memcmp() in
+ __d_lookup() go out of bounds due to a rename and false positive
+ comparison, the name comparison is done while holding the
+ per-dentry lock. This prevents concurrent renames during this
+ operation.
+
+3. Hash table walking during look-up may move to a different bucket as
+ the current dentry is moved to a different bucket due to rename.
+ But we use hlists in dcache hash table and they are
+ null-terminated. So, even if a dentry moves to a different bucket,
+ hash chain walk will terminate. [with a list_head list, it may not
+ since termination is when the list_head in the original bucket is
+ reached]. Since we redo the d_parent check and compare name while
+ holding d_lock, lock-free look-up will not race against d_move().
+
+4. There can be a theoretical race when a dentry keeps coming back to
+ original bucket due to double moves. Due to this look-up may
+ consider that it has never moved and can end up in a infinite loop.
+ But this is not any worse that theoretical livelocks we already
+ have in the kernel.
+
+
+Important guidelines for filesystem developers related to dcache_rcu
+====================================================================
+
+1. Existing dcache interfaces (pre-2.5.62) exported to filesystem
+ don't change. Only dcache internal implementation changes. However
+ filesystems *must not* delete from the dentry hash chains directly
+ using the list macros like allowed earlier. They must use dcache
+ APIs like d_drop() or __d_drop() depending on the situation.
+
+2. d_flags is now protected by a per-dentry lock (d_lock). All access
+ to d_flags must be protected by it.
+
+3. For a hashed dentry, checking of d_count needs to be protected by
+ d_lock.
+
+
+Papers and other documentation on dcache locking
+================================================
+
+1. Scaling dcache with RCU (http://linuxjournal.com/article.php?sid=7124).
+
+2. http://lse.sourceforge.net/locking/dcache/dcache.html
+
+
+
diff --git a/Documentation/filesystems/devfs/README b/Documentation/filesystems/devfs/README
index 54366ecc241f..aabfba24bc2e 100644
--- a/Documentation/filesystems/devfs/README
+++ b/Documentation/filesystems/devfs/README
@@ -1812,11 +1812,6 @@ it may overflow the messages buffer, but try to get as much of it as
you can
-if you get an Oops, run ksymoops to decode it so that the
-names of the offending functions are provided. A non-decoded Oops is
-pretty useless
-
-
send a copy of your devfsd configuration file(s)
send the bug report to me first.
diff --git a/Documentation/filesystems/ext2.txt b/Documentation/filesystems/ext2.txt
index d16334ec48ba..a8edb376b041 100644
--- a/Documentation/filesystems/ext2.txt
+++ b/Documentation/filesystems/ext2.txt
@@ -17,8 +17,6 @@ set using tune2fs(8). Kernel-determined defaults are indicated by (*).
bsddf (*) Makes `df' act like BSD.
minixdf Makes `df' act like Minix.
-check Check block and inode bitmaps at mount time
- (requires CONFIG_EXT2_CHECK).
check=none, nocheck (*) Don't do extra checking of bitmaps on mount
(check=normal and check=strict options removed)
diff --git a/Documentation/filesystems/ntfs.txt b/Documentation/filesystems/ntfs.txt
index a5fbc8e897fa..614de3124901 100644
--- a/Documentation/filesystems/ntfs.txt
+++ b/Documentation/filesystems/ntfs.txt
@@ -50,9 +50,14 @@ userspace utilities, etc.
Features
========
-- This is a complete rewrite of the NTFS driver that used to be in the kernel.
- This new driver implements NTFS read support and is functionally equivalent
- to the old ntfs driver.
+- This is a complete rewrite of the NTFS driver that used to be in the 2.4 and
+ earlier kernels. This new driver implements NTFS read support and is
+ functionally equivalent to the old ntfs driver and it also implements limited
+ write support. The biggest limitation at present is that files/directories
+ cannot be created or deleted. See below for the list of write features that
+ are so far supported. Another limitation is that writing to compressed files
+ is not implemented at all. Also, neither read nor write access to encrypted
+ files is so far implemented.
- The new driver has full support for sparse files on NTFS 3.x volumes which
the old driver isn't happy with.
- The new driver supports execution of binaries due to mmap() now being
@@ -78,7 +83,20 @@ Features
- The new driver supports fsync(2), fdatasync(2), and msync(2).
- The new driver supports readv(2) and writev(2).
- The new driver supports access time updates (including mtime and ctime).
-
+- The new driver supports truncate(2) and open(2) with O_TRUNC. But at present
+ only very limited support for highly fragmented files, i.e. ones which have
+ their data attribute split across multiple extents, is included. Another
+ limitation is that at present truncate(2) will never create sparse files,
+ since to mark a file sparse we need to modify the directory entry for the
+ file and we do not implement directory modifications yet.
+- The new driver supports write(2) which can both overwrite existing data and
+ extend the file size so that you can write beyond the existing data. Also,
+ writing into sparse regions is supported and the holes are filled in with
+ clusters. But at present only limited support for highly fragmented files,
+ i.e. ones which have their data attribute split across multiple extents, is
+ included. Another limitation is that write(2) will never create sparse
+ files, since to mark a file sparse we need to modify the directory entry for
+ the file and we do not implement directory modifications yet.
Supported mount options
=======================
@@ -439,6 +457,22 @@ ChangeLog
Note, a technical ChangeLog aimed at kernel hackers is in fs/ntfs/ChangeLog.
+2.1.25:
+ - Write support is now extended with write(2) being able to both
+ overwrite existing file data and to extend files. Also, if a write
+ to a sparse region occurs, write(2) will fill in the hole. Note,
+ mmap(2) based writes still do not support writing into holes or
+ writing beyond the initialized size.
+ - Write support has a new feature and that is that truncate(2) and
+ open(2) with O_TRUNC are now implemented thus files can be both made
+ smaller and larger.
+ - Note: Both write(2) and truncate(2)/open(2) with O_TRUNC still have
+ limitations in that they
+ - only provide limited support for highly fragmented files.
+ - only work on regular, i.e. uncompressed and unencrypted files.
+ - never create sparse files although this will change once directory
+ operations are implemented.
+ - Lots of bug fixes and enhancements across the board.
2.1.24:
- Support journals ($LogFile) which have been modified by chkdsk. This
means users can boot into Windows after we marked the volume dirty.
diff --git a/Documentation/filesystems/ramfs-rootfs-initramfs.txt b/Documentation/filesystems/ramfs-rootfs-initramfs.txt
new file mode 100644
index 000000000000..b3404a032596
--- /dev/null
+++ b/Documentation/filesystems/ramfs-rootfs-initramfs.txt
@@ -0,0 +1,195 @@
+ramfs, rootfs and initramfs
+October 17, 2005
+Rob Landley <rob@landley.net>
+=============================
+
+What is ramfs?
+--------------
+
+Ramfs is a very simple filesystem that exports Linux's disk caching
+mechanisms (the page cache and dentry cache) as a dynamically resizable
+ram-based filesystem.
+
+Normally all files are cached in memory by Linux. Pages of data read from
+backing store (usually the block device the filesystem is mounted on) are kept
+around in case it's needed again, but marked as clean (freeable) in case the
+Virtual Memory system needs the memory for something else. Similarly, data
+written to files is marked clean as soon as it has been written to backing
+store, but kept around for caching purposes until the VM reallocates the
+memory. A similar mechanism (the dentry cache) greatly speeds up access to
+directories.
+
+With ramfs, there is no backing store. Files written into ramfs allocate
+dentries and page cache as usual, but there's nowhere to write them to.
+This means the pages are never marked clean, so they can't be freed by the
+VM when it's looking to recycle memory.
+
+The amount of code required to implement ramfs is tiny, because all the
+work is done by the existing Linux caching infrastructure. Basically,
+you're mounting the disk cache as a filesystem. Because of this, ramfs is not
+an optional component removable via menuconfig, since there would be negligible
+space savings.
+
+ramfs and ramdisk:
+------------------
+
+The older "ram disk" mechanism created a synthetic block device out of
+an area of ram and used it as backing store for a filesystem. This block
+device was of fixed size, so the filesystem mounted on it was of fixed
+size. Using a ram disk also required unnecessarily copying memory from the
+fake block device into the page cache (and copying changes back out), as well
+as creating and destroying dentries. Plus it needed a filesystem driver
+(such as ext2) to format and interpret this data.
+
+Compared to ramfs, this wastes memory (and memory bus bandwidth), creates
+unnecessary work for the CPU, and pollutes the CPU caches. (There are tricks
+to avoid this copying by playing with the page tables, but they're unpleasantly
+complicated and turn out to be about as expensive as the copying anyway.)
+More to the point, all the work ramfs is doing has to happen _anyway_,
+since all file access goes through the page and dentry caches. The ram
+disk is simply unnecessary, ramfs is internally much simpler.
+
+Another reason ramdisks are semi-obsolete is that the introduction of
+loopback devices offered a more flexible and convenient way to create
+synthetic block devices, now from files instead of from chunks of memory.
+See losetup (8) for details.
+
+ramfs and tmpfs:
+----------------
+
+One downside of ramfs is you can keep writing data into it until you fill
+up all memory, and the VM can't free it because the VM thinks that files
+should get written to backing store (rather than swap space), but ramfs hasn't
+got any backing store. Because of this, only root (or a trusted user) should
+be allowed write access to a ramfs mount.
+
+A ramfs derivative called tmpfs was created to add size limits, and the ability
+to write the data to swap space. Normal users can be allowed write access to
+tmpfs mounts. See Documentation/filesystems/tmpfs.txt for more information.
+
+What is rootfs?
+---------------
+
+Rootfs is a special instance of ramfs, which is always present in 2.6 systems.
+(It's used internally as the starting and stopping point for searches of the
+kernel's doubly-linked list of mount points.)
+
+Most systems just mount another filesystem over it and ignore it. The
+amount of space an empty instance of ramfs takes up is tiny.
+
+What is initramfs?
+------------------
+
+All 2.6 Linux kernels contain a gzipped "cpio" format archive, which is
+extracted into rootfs when the kernel boots up. After extracting, the kernel
+checks to see if rootfs contains a file "init", and if so it executes it as PID
+1. If found, this init process is responsible for bringing the system the
+rest of the way up, including locating and mounting the real root device (if
+any). If rootfs does not contain an init program after the embedded cpio
+archive is extracted into it, the kernel will fall through to the older code
+to locate and mount a root partition, then exec some variant of /sbin/init
+out of that.
+
+All this differs from the old initrd in several ways:
+
+ - The old initrd was a separate file, while the initramfs archive is linked
+ into the linux kernel image. (The directory linux-*/usr is devoted to
+ generating this archive during the build.)
+
+ - The old initrd file was a gzipped filesystem image (in some file format,
+ such as ext2, that had to be built into the kernel), while the new
+ initramfs archive is a gzipped cpio archive (like tar only simpler,
+ see cpio(1) and Documentation/early-userspace/buffer-format.txt).
+
+ - The program run by the old initrd (which was called /initrd, not /init) did
+ some setup and then returned to the kernel, while the init program from
+ initramfs is not expected to return to the kernel. (If /init needs to hand
+ off control it can overmount / with a new root device and exec another init
+ program. See the switch_root utility, below.)
+
+ - When switching another root device, initrd would pivot_root and then
+ umount the ramdisk. But initramfs is rootfs: you can neither pivot_root
+ rootfs, nor unmount it. Instead delete everything out of rootfs to
+ free up the space (find -xdev / -exec rm '{}' ';'), overmount rootfs
+ with the new root (cd /newmount; mount --move . /; chroot .), attach
+ stdin/stdout/stderr to the new /dev/console, and exec the new init.
+
+ Since this is a remarkably persnickity process (and involves deleting
+ commands before you can run them), the klibc package introduced a helper
+ program (utils/run_init.c) to do all this for you. Most other packages
+ (such as busybox) have named this command "switch_root".
+
+Populating initramfs:
+---------------------
+
+The 2.6 kernel build process always creates a gzipped cpio format initramfs
+archive and links it into the resulting kernel binary. By default, this
+archive is empty (consuming 134 bytes on x86). The config option
+CONFIG_INITRAMFS_SOURCE (for some reason buried under devices->block devices
+in menuconfig, and living in usr/Kconfig) can be used to specify a source for
+the initramfs archive, which will automatically be incorporated into the
+resulting binary. This option can point to an existing gzipped cpio archive, a
+directory containing files to be archived, or a text file specification such
+as the following example:
+
+ dir /dev 755 0 0
+ nod /dev/console 644 0 0 c 5 1
+ nod /dev/loop0 644 0 0 b 7 0
+ dir /bin 755 1000 1000
+ slink /bin/sh busybox 777 0 0
+ file /bin/busybox initramfs/busybox 755 0 0
+ dir /proc 755 0 0
+ dir /sys 755 0 0
+ dir /mnt 755 0 0
+ file /init initramfs/init.sh 755 0 0
+
+One advantage of the text file is that root access is not required to
+set permissions or create device nodes in the new archive. (Note that those
+two example "file" entries expect to find files named "init.sh" and "busybox" in
+a directory called "initramfs", under the linux-2.6.* directory. See
+Documentation/early-userspace/README for more details.)
+
+If you don't already understand what shared libraries, devices, and paths
+you need to get a minimal root filesystem up and running, here are some
+references:
+http://www.tldp.org/HOWTO/Bootdisk-HOWTO/
+http://www.tldp.org/HOWTO/From-PowerUp-To-Bash-Prompt-HOWTO.html
+http://www.linuxfromscratch.org/lfs/view/stable/
+
+The "klibc" package (http://www.kernel.org/pub/linux/libs/klibc) is
+designed to be a tiny C library to statically link early userspace
+code against, along with some related utilities. It is BSD licensed.
+
+I use uClibc (http://www.uclibc.org) and busybox (http://www.busybox.net)
+myself. These are LGPL and GPL, respectively.
+
+In theory you could use glibc, but that's not well suited for small embedded
+uses like this. (A "hello world" program statically linked against glibc is
+over 400k. With uClibc it's 7k. Also note that glibc dlopens libnss to do
+name lookups, even when otherwise statically linked.)
+
+Future directions:
+------------------
+
+Today (2.6.14), initramfs is always compiled in, but not always used. The
+kernel falls back to legacy boot code that is reached only if initramfs does
+not contain an /init program. The fallback is legacy code, there to ensure a
+smooth transition and allowing early boot functionality to gradually move to
+"early userspace" (I.E. initramfs).
+
+The move to early userspace is necessary because finding and mounting the real
+root device is complex. Root partitions can span multiple devices (raid or
+separate journal). They can be out on the network (requiring dhcp, setting a
+specific mac address, logging into a server, etc). They can live on removable
+media, with dynamically allocated major/minor numbers and persistent naming
+issues requiring a full udev implementation to sort out. They can be
+compressed, encrypted, copy-on-write, loopback mounted, strangely partitioned,
+and so on.
+
+This kind of complexity (which inevitably includes policy) is rightly handled
+in userspace. Both klibc and busybox/uClibc are working on simple initramfs
+packages to drop into a kernel build, and when standard solutions are ready
+and widely deployed, the kernel's legacy early boot code will become obsolete
+and a candidate for the feature removal schedule.
+
+But that's a while off yet.
diff --git a/Documentation/filesystems/vfs.txt b/Documentation/filesystems/vfs.txt
index f042c12e0ed2..ee4c0a8b8db7 100644
--- a/Documentation/filesystems/vfs.txt
+++ b/Documentation/filesystems/vfs.txt
@@ -3,7 +3,7 @@
Original author: Richard Gooch <rgooch@atnf.csiro.au>
- Last updated on August 25, 2005
+ Last updated on October 28, 2005
Copyright (C) 1999 Richard Gooch
Copyright (C) 2005 Pekka Enberg
@@ -11,62 +11,61 @@
This file is released under the GPLv2.
-What is it?
-===========
+Introduction
+============
-The Virtual File System (otherwise known as the Virtual Filesystem
-Switch) is the software layer in the kernel that provides the
-filesystem interface to userspace programs. It also provides an
-abstraction within the kernel which allows different filesystem
-implementations to coexist.
+The Virtual File System (also known as the Virtual Filesystem Switch)
+is the software layer in the kernel that provides the filesystem
+interface to userspace programs. It also provides an abstraction
+within the kernel which allows different filesystem implementations to
+coexist.
+VFS system calls open(2), stat(2), read(2), write(2), chmod(2) and so
+on are called from a process context. Filesystem locking is described
+in the document Documentation/filesystems/Locking.
-A Quick Look At How It Works
-============================
-In this section I'll briefly describe how things work, before
-launching into the details. I'll start with describing what happens
-when user programs open and manipulate files, and then look from the
-other view which is how a filesystem is supported and subsequently
-mounted.
-
-
-Opening a File
---------------
-
-The VFS implements the open(2), stat(2), chmod(2) and similar system
-calls. The pathname argument is used by the VFS to search through the
-directory entry cache (dentry cache or "dcache"). This provides a very
-fast look-up mechanism to translate a pathname (filename) into a
-specific dentry.
-
-An individual dentry usually has a pointer to an inode. Inodes are the
-things that live on disc drives, and can be regular files (you know:
-those things that you write data into), directories, FIFOs and other
-beasts. Dentries live in RAM and are never saved to disc: they exist
-only for performance. Inodes live on disc and are copied into memory
-when required. Later any changes are written back to disc. The inode
-that lives in RAM is a VFS inode, and it is this which the dentry
-points to. A single inode can be pointed to by multiple dentries
-(think about hardlinks).
-
-The dcache is meant to be a view into your entire filespace. Unlike
-Linus, most of us losers can't fit enough dentries into RAM to cover
-all of our filespace, so the dcache has bits missing. In order to
-resolve your pathname into a dentry, the VFS may have to resort to
-creating dentries along the way, and then loading the inode. This is
-done by looking up the inode.
-
-To look up an inode (usually read from disc) requires that the VFS
-calls the lookup() method of the parent directory inode. This method
-is installed by the specific filesystem implementation that the inode
-lives in. There will be more on this later.
+Directory Entry Cache (dcache)
+------------------------------
-Once the VFS has the required dentry (and hence the inode), we can do
-all those boring things like open(2) the file, or stat(2) it to peek
-at the inode data. The stat(2) operation is fairly simple: once the
-VFS has the dentry, it peeks at the inode data and passes some of it
-back to userspace.
+The VFS implements the open(2), stat(2), chmod(2), and similar system
+calls. The pathname argument that is passed to them is used by the VFS
+to search through the directory entry cache (also known as the dentry
+cache or dcache). This provides a very fast look-up mechanism to
+translate a pathname (filename) into a specific dentry. Dentries live
+in RAM and are never saved to disc: they exist only for performance.
+
+The dentry cache is meant to be a view into your entire filespace. As
+most computers cannot fit all dentries in the RAM at the same time,
+some bits of the cache are missing. In order to resolve your pathname
+into a dentry, the VFS may have to resort to creating dentries along
+the way, and then loading the inode. This is done by looking up the
+inode.
+
+
+The Inode Object
+----------------
+
+An individual dentry usually has a pointer to an inode. Inodes are
+filesystem objects such as regular files, directories, FIFOs and other
+beasts. They live either on the disc (for block device filesystems)
+or in the memory (for pseudo filesystems). Inodes that live on the
+disc are copied into the memory when required and changes to the inode
+are written back to disc. A single inode can be pointed to by multiple
+dentries (hard links, for example, do this).
+
+To look up an inode requires that the VFS calls the lookup() method of
+the parent directory inode. This method is installed by the specific
+filesystem implementation that the inode lives in. Once the VFS has
+the required dentry (and hence the inode), we can do all those boring
+things like open(2) the file, or stat(2) it to peek at the inode
+data. The stat(2) operation is fairly simple: once the VFS has the
+dentry, it peeks at the inode data and passes some of it back to
+userspace.
+
+
+The File Object
+---------------
Opening a file requires another operation: allocation of a file
structure (this is the kernel-side implementation of file
@@ -74,51 +73,39 @@ descriptors). The freshly allocated file structure is initialized with
a pointer to the dentry and a set of file operation member functions.
These are taken from the inode data. The open() file method is then
called so the specific filesystem implementation can do it's work. You
-can see that this is another switch performed by the VFS.
-
-The file structure is placed into the file descriptor table for the
-process.
+can see that this is another switch performed by the VFS. The file
+structure is placed into the file descriptor table for the process.
Reading, writing and closing files (and other assorted VFS operations)
is done by using the userspace file descriptor to grab the appropriate
-file structure, and then calling the required file structure method
-function to do whatever is required.
-
-For as long as the file is open, it keeps the dentry "open" (in use),
-which in turn means that the VFS inode is still in use.
-
-All VFS system calls (i.e. open(2), stat(2), read(2), write(2),
-chmod(2) and so on) are called from a process context. You should
-assume that these calls are made without any kernel locks being
-held. This means that the processes may be executing the same piece of
-filesystem or driver code at the same time, on different
-processors. You should ensure that access to shared resources is
-protected by appropriate locks.
+file structure, and then calling the required file structure method to
+do whatever is required. For as long as the file is open, it keeps the
+dentry in use, which in turn means that the VFS inode is still in use.
Registering and Mounting a Filesystem
--------------------------------------
+=====================================
-If you want to support a new kind of filesystem in the kernel, all you
-need to do is call register_filesystem(). You pass a structure
-describing the filesystem implementation (struct file_system_type)
-which is then added to an internal table of supported filesystems. You
-can do:
+To register and unregister a filesystem, use the following API
+functions:
-% cat /proc/filesystems
+ #include <linux/fs.h>
-to see what filesystems are currently available on your system.
+ extern int register_filesystem(struct file_system_type *);
+ extern int unregister_filesystem(struct file_system_type *);
-When a request is made to mount a block device onto a directory in
-your filespace the VFS will call the appropriate method for the
-specific filesystem. The dentry for the mount point will then be
-updated to point to the root inode for the new filesystem.
+The passed struct file_system_type describes your filesystem. When a
+request is made to mount a device onto a directory in your filespace,
+the VFS will call the appropriate get_sb() method for the specific
+filesystem. The dentry for the mount point will then be updated to
+point to the root inode for the new filesystem.
-It's now time to look at things in more detail.
+You can see all filesystems that are registered to the kernel in the
+file /proc/filesystems.
struct file_system_type
-=======================
+-----------------------
This describes the filesystem. As of kernel 2.6.13, the following
members are defined:
@@ -197,8 +184,14 @@ A fill_super() method implementation has the following arguments:
int silent: whether or not to be silent on error
+The Superblock Object
+=====================
+
+A superblock object represents a mounted filesystem.
+
+
struct super_operations
-=======================
+-----------------------
This describes how the VFS can manipulate the superblock of your
filesystem. As of kernel 2.6.13, the following members are defined:
@@ -286,9 +279,9 @@ or bottom half).
a superblock. The second parameter indicates whether the method
should wait until the write out has been completed. Optional.
- write_super_lockfs: called when VFS is locking a filesystem and forcing
- it into a consistent state. This function is currently used by the
- Logical Volume Manager (LVM).
+ write_super_lockfs: called when VFS is locking a filesystem and
+ forcing it into a consistent state. This method is currently
+ used by the Logical Volume Manager (LVM).
unlockfs: called when VFS is unlocking a filesystem and making it writable
again.
@@ -317,8 +310,14 @@ field. This is a pointer to a "struct inode_operations" which
describes the methods that can be performed on individual inodes.
+The Inode Object
+================
+
+An inode object represents an object within the filesystem.
+
+
struct inode_operations
-=======================
+-----------------------
This describes how the VFS can manipulate an inode in your
filesystem. As of kernel 2.6.13, the following members are defined:
@@ -394,51 +393,62 @@ otherwise noted.
will probably need to call d_instantiate() just as you would
in the create() method
+ rename: called by the rename(2) system call to rename the object to
+ have the parent and name given by the second inode and dentry.
+
readlink: called by the readlink(2) system call. Only required if
you want to support reading symbolic links
follow_link: called by the VFS to follow a symbolic link to the
inode it points to. Only required if you want to support
- symbolic links. This function returns a void pointer cookie
+ symbolic links. This method returns a void pointer cookie
that is passed to put_link().
put_link: called by the VFS to release resources allocated by
- follow_link(). The cookie returned by follow_link() is passed to
- to this function as the last parameter. It is used by filesystems
- such as NFS where page cache is not stable (i.e. page that was
- installed when the symbolic link walk started might not be in the
- page cache at the end of the walk).
-
- truncate: called by the VFS to change the size of a file. The i_size
- field of the inode is set to the desired size by the VFS before
- this function is called. This function is called by the truncate(2)
- system call and related functionality.
+ follow_link(). The cookie returned by follow_link() is passed
+ to to this method as the last parameter. It is used by
+ filesystems such as NFS where page cache is not stable
+ (i.e. page that was installed when the symbolic link walk
+ started might not be in the page cache at the end of the
+ walk).
+
+ truncate: called by the VFS to change the size of a file. The
+ i_size field of the inode is set to the desired size by the
+ VFS before this method is called. This method is called by
+ the truncate(2) system call and related functionality.
permission: called by the VFS to check for access rights on a POSIX-like
filesystem.
- setattr: called by the VFS to set attributes for a file. This function is
- called by chmod(2) and related system calls.
+ setattr: called by the VFS to set attributes for a file. This method
+ is called by chmod(2) and related system calls.
- getattr: called by the VFS to get attributes of a file. This function is
- called by stat(2) and related system calls.
+ getattr: called by the VFS to get attributes of a file. This method
+ is called by stat(2) and related system calls.
setxattr: called by the VFS to set an extended attribute for a file.
- Extended attribute is a name:value pair associated with an inode. This
- function is called by setxattr(2) system call.
+ Extended attribute is a name:value pair associated with an
+ inode. This method is called by setxattr(2) system call.
+
+ getxattr: called by the VFS to retrieve the value of an extended
+ attribute name. This method is called by getxattr(2) function
+ call.
- getxattr: called by the VFS to retrieve the value of an extended attribute
- name. This function is called by getxattr(2) function call.
+ listxattr: called by the VFS to list all extended attributes for a
+ given file. This method is called by listxattr(2) system call.
- listxattr: called by the VFS to list all extended attributes for a given
- file. This function is called by listxattr(2) system call.
+ removexattr: called by the VFS to remove an extended attribute from
+ a file. This method is called by removexattr(2) system call.
- removexattr: called by the VFS to remove an extended attribute from a file.
- This function is called by removexattr(2) system call.
+
+The Address Space Object
+========================
+
+The address space object is used to identify pages in the page cache.
struct address_space_operations
-===============================
+-------------------------------
This describes how the VFS can manipulate mapping of a file to page cache in
your filesystem. As of kernel 2.6.13, the following members are defined:
@@ -502,8 +512,14 @@ struct address_space_operations {
it. An example implementation can be found in fs/ext2/xip.c.
+The File Object
+===============
+
+A file object represents a file opened by a process.
+
+
struct file_operations
-======================
+----------------------
This describes how the VFS can manipulate an open file. As of kernel
2.6.13, the following members are defined:
@@ -661,7 +677,7 @@ of child dentries. Child dentries are basically like files in a
directory.
-Directory Entry Cache APIs
+Directory Entry Cache API
--------------------------
There are a number of functions defined which permit a filesystem to
@@ -705,178 +721,24 @@ manipulate dentries:
and the dentry is returned. The caller must use d_put()
to free the dentry when it finishes using it.
+For further information on dentry locking, please refer to the document
+Documentation/filesystems/dentry-locking.txt.
-RCU-based dcache locking model
-------------------------------
-On many workloads, the most common operation on dcache is
-to look up a dentry, given a parent dentry and the name
-of the child. Typically, for every open(), stat() etc.,
-the dentry corresponding to the pathname will be looked
-up by walking the tree starting with the first component
-of the pathname and using that dentry along with the next
-component to look up the next level and so on. Since it
-is a frequent operation for workloads like multiuser
-environments and web servers, it is important to optimize
-this path.
-
-Prior to 2.5.10, dcache_lock was acquired in d_lookup and thus
-in every component during path look-up. Since 2.5.10 onwards,
-fast-walk algorithm changed this by holding the dcache_lock
-at the beginning and walking as many cached path component
-dentries as possible. This significantly decreases the number
-of acquisition of dcache_lock. However it also increases the
-lock hold time significantly and affects performance in large
-SMP machines. Since 2.5.62 kernel, dcache has been using
-a new locking model that uses RCU to make dcache look-up
-lock-free.
-
-The current dcache locking model is not very different from the existing
-dcache locking model. Prior to 2.5.62 kernel, dcache_lock
-protected the hash chain, d_child, d_alias, d_lru lists as well
-as d_inode and several other things like mount look-up. RCU-based
-changes affect only the way the hash chain is protected. For everything
-else the dcache_lock must be taken for both traversing as well as
-updating. The hash chain updates too take the dcache_lock.
-The significant change is the way d_lookup traverses the hash chain,
-it doesn't acquire the dcache_lock for this and rely on RCU to
-ensure that the dentry has not been *freed*.
-
-
-Dcache locking details
-----------------------
+Resources
+=========
+
+(Note some of these resources are not up-to-date with the latest kernel
+ version.)
+
+Creating Linux virtual filesystems. 2002
+ <http://lwn.net/Articles/13325/>
+
+The Linux Virtual File-system Layer by Neil Brown. 1999
+ <http://www.cse.unsw.edu.au/~neilb/oss/linux-commentary/vfs.html>
+
+A tour of the Linux VFS by Michael K. Johnson. 1996
+ <http://www.tldp.org/LDP/khg/HyperNews/get/fs/vfstour.html>
-For many multi-user workloads, open() and stat() on files are
-very frequently occurring operations. Both involve walking
-of path names to find the dentry corresponding to the
-concerned file. In 2.4 kernel, dcache_lock was held
-during look-up of each path component. Contention and
-cache-line bouncing of this global lock caused significant
-scalability problems. With the introduction of RCU
-in Linux kernel, this was worked around by making
-the look-up of path components during path walking lock-free.
-
-
-Safe lock-free look-up of dcache hash table
-===========================================
-
-Dcache is a complex data structure with the hash table entries
-also linked together in other lists. In 2.4 kernel, dcache_lock
-protected all the lists. We applied RCU only on hash chain
-walking. The rest of the lists are still protected by dcache_lock.
-Some of the important changes are :
-
-1. The deletion from hash chain is done using hlist_del_rcu() macro which
- doesn't initialize next pointer of the deleted dentry and this
- allows us to walk safely lock-free while a deletion is happening.
-
-2. Insertion of a dentry into the hash table is done using
- hlist_add_head_rcu() which take care of ordering the writes -
- the writes to the dentry must be visible before the dentry
- is inserted. This works in conjunction with hlist_for_each_rcu()
- while walking the hash chain. The only requirement is that
- all initialization to the dentry must be done before hlist_add_head_rcu()
- since we don't have dcache_lock protection while traversing
- the hash chain. This isn't different from the existing code.
-
-3. The dentry looked up without holding dcache_lock by cannot be
- returned for walking if it is unhashed. It then may have a NULL
- d_inode or other bogosity since RCU doesn't protect the other
- fields in the dentry. We therefore use a flag DCACHE_UNHASHED to
- indicate unhashed dentries and use this in conjunction with a
- per-dentry lock (d_lock). Once looked up without the dcache_lock,
- we acquire the per-dentry lock (d_lock) and check if the
- dentry is unhashed. If so, the look-up is failed. If not, the
- reference count of the dentry is increased and the dentry is returned.
-
-4. Once a dentry is looked up, it must be ensured during the path
- walk for that component it doesn't go away. In pre-2.5.10 code,
- this was done holding a reference to the dentry. dcache_rcu does
- the same. In some sense, dcache_rcu path walking looks like
- the pre-2.5.10 version.
-
-5. All dentry hash chain updates must take the dcache_lock as well as
- the per-dentry lock in that order. dput() does this to ensure
- that a dentry that has just been looked up in another CPU
- doesn't get deleted before dget() can be done on it.
-
-6. There are several ways to do reference counting of RCU protected
- objects. One such example is in ipv4 route cache where
- deferred freeing (using call_rcu()) is done as soon as
- the reference count goes to zero. This cannot be done in
- the case of dentries because tearing down of dentries
- require blocking (dentry_iput()) which isn't supported from
- RCU callbacks. Instead, tearing down of dentries happen
- synchronously in dput(), but actual freeing happens later
- when RCU grace period is over. This allows safe lock-free
- walking of the hash chains, but a matched dentry may have
- been partially torn down. The checking of DCACHE_UNHASHED
- flag with d_lock held detects such dentries and prevents
- them from being returned from look-up.
-
-
-Maintaining POSIX rename semantics
-==================================
-
-Since look-up of dentries is lock-free, it can race against
-a concurrent rename operation. For example, during rename
-of file A to B, look-up of either A or B must succeed.
-So, if look-up of B happens after A has been removed from the
-hash chain but not added to the new hash chain, it may fail.
-Also, a comparison while the name is being written concurrently
-by a rename may result in false positive matches violating
-rename semantics. Issues related to race with rename are
-handled as described below :
-
-1. Look-up can be done in two ways - d_lookup() which is safe
- from simultaneous renames and __d_lookup() which is not.
- If __d_lookup() fails, it must be followed up by a d_lookup()
- to correctly determine whether a dentry is in the hash table
- or not. d_lookup() protects look-ups using a sequence
- lock (rename_lock).
-
-2. The name associated with a dentry (d_name) may be changed if
- a rename is allowed to happen simultaneously. To avoid memcmp()
- in __d_lookup() go out of bounds due to a rename and false
- positive comparison, the name comparison is done while holding the
- per-dentry lock. This prevents concurrent renames during this
- operation.
-
-3. Hash table walking during look-up may move to a different bucket as
- the current dentry is moved to a different bucket due to rename.
- But we use hlists in dcache hash table and they are null-terminated.
- So, even if a dentry moves to a different bucket, hash chain
- walk will terminate. [with a list_head list, it may not since
- termination is when the list_head in the original bucket is reached].
- Since we redo the d_parent check and compare name while holding
- d_lock, lock-free look-up will not race against d_move().
-
-4. There can be a theoretical race when a dentry keeps coming back
- to original bucket due to double moves. Due to this look-up may
- consider that it has never moved and can end up in a infinite loop.
- But this is not any worse that theoretical livelocks we already
- have in the kernel.
-
-
-Important guidelines for filesystem developers related to dcache_rcu
-====================================================================
-
-1. Existing dcache interfaces (pre-2.5.62) exported to filesystem
- don't change. Only dcache internal implementation changes. However
- filesystems *must not* delete from the dentry hash chains directly
- using the list macros like allowed earlier. They must use dcache
- APIs like d_drop() or __d_drop() depending on the situation.
-
-2. d_flags is now protected by a per-dentry lock (d_lock). All
- access to d_flags must be protected by it.
-
-3. For a hashed dentry, checking of d_count needs to be protected
- by d_lock.
-
-
-Papers and other documentation on dcache locking
-================================================
-
-1. Scaling dcache with RCU (http://linuxjournal.com/article.php?sid=7124).
-
-2. http://lse.sourceforge.net/locking/dcache/dcache.html
+A small trail through the Linux kernel by Andries Brouwer. 2001
+ <http://www.win.tue.nl/~aeb/linux/vfs/trail.html>
diff --git a/Documentation/filesystems/xfs.txt b/Documentation/filesystems/xfs.txt
index c7d5d0c7067d..74aeb142ae5f 100644
--- a/Documentation/filesystems/xfs.txt
+++ b/Documentation/filesystems/xfs.txt
@@ -19,15 +19,43 @@ Mount Options
When mounting an XFS filesystem, the following options are accepted.
- biosize=size
- Sets the preferred buffered I/O size (default size is 64K).
- "size" must be expressed as the logarithm (base2) of the
- desired I/O size.
- Valid values for this option are 14 through 16, inclusive
- (i.e. 16K, 32K, and 64K bytes). On machines with a 4K
- pagesize, 13 (8K bytes) is also a valid size.
- The preferred buffered I/O size can also be altered on an
- individual file basis using the ioctl(2) system call.
+ allocsize=size
+ Sets the buffered I/O end-of-file preallocation size when
+ doing delayed allocation writeout (default size is 64KiB).
+ Valid values for this option are page size (typically 4KiB)
+ through to 1GiB, inclusive, in power-of-2 increments.
+
+ attr2/noattr2
+ The options enable/disable (default is disabled for backward
+ compatibility on-disk) an "opportunistic" improvement to be
+ made in the way inline extended attributes are stored on-disk.
+ When the new form is used for the first time (by setting or
+ removing extended attributes) the on-disk superblock feature
+ bit field will be updated to reflect this format being in use.
+
+ barrier
+ Enables the use of block layer write barriers for writes into
+ the journal and unwritten extent conversion. This allows for
+ drive level write caching to be enabled, for devices that
+ support write barriers.
+
+ dmapi
+ Enable the DMAPI (Data Management API) event callouts.
+ Use with the "mtpt" option.
+
+ grpid/bsdgroups and nogrpid/sysvgroups
+ These options define what group ID a newly created file gets.
+ When grpid is set, it takes the group ID of the directory in
+ which it is created; otherwise (the default) it takes the fsgid
+ of the current process, unless the directory has the setgid bit
+ set, in which case it takes the gid from the parent directory,
+ and also gets the setgid bit set if it is a directory itself.
+
+ ihashsize=value
+ Sets the number of hash buckets available for hashing the
+ in-memory inodes of the specified mount point. If a value
+ of zero is used, the value selected by the default algorithm
+ will be displayed in /proc/mounts.
ikeep/noikeep
When inode clusters are emptied of inodes, keep them around
@@ -35,12 +63,31 @@ When mounting an XFS filesystem, the following options are accepted.
and is still the default for now. Using the noikeep option,
inode clusters are returned to the free space pool.
+ inode64
+ Indicates that XFS is allowed to create inodes at any location
+ in the filesystem, including those which will result in inode
+ numbers occupying more than 32 bits of significance. This is
+ provided for backwards compatibility, but causes problems for
+ backup applications that cannot handle large inode numbers.
+
+ largeio/nolargeio
+ If "nolargeio" is specified, the optimal I/O reported in
+ st_blksize by stat(2) will be as small as possible to allow user
+ applications to avoid inefficient read/modify/write I/O.
+ If "largeio" specified, a filesystem that has a "swidth" specified
+ will return the "swidth" value (in bytes) in st_blksize. If the
+ filesystem does not have a "swidth" specified but does specify
+ an "allocsize" then "allocsize" (in bytes) will be returned
+ instead.
+ If neither of these two options are specified, then filesystem
+ will behave as if "nolargeio" was specified.
+
logbufs=value
Set the number of in-memory log buffers. Valid numbers range
from 2-8 inclusive.
The default value is 8 buffers for filesystems with a
- blocksize of 64K, 4 buffers for filesystems with a blocksize
- of 32K, 3 buffers for filesystems with a blocksize of 16K
+ blocksize of 64KiB, 4 buffers for filesystems with a blocksize
+ of 32KiB, 3 buffers for filesystems with a blocksize of 16KiB
and 2 buffers for all other configurations. Increasing the
number of buffers may increase performance on some workloads
at the cost of the memory used for the additional log buffers
@@ -49,10 +96,10 @@ When mounting an XFS filesystem, the following options are accepted.
logbsize=value
Set the size of each in-memory log buffer.
Size may be specified in bytes, or in kilobytes with a "k" suffix.
- Valid sizes for version 1 and version 2 logs are 16384 (16k) and
- 32768 (32k). Valid sizes for version 2 logs also include
+ Valid sizes for version 1 and version 2 logs are 16384 (16k) and
+ 32768 (32k). Valid sizes for version 2 logs also include
65536 (64k), 131072 (128k) and 262144 (256k).
- The default value for machines with more than 32MB of memory
+ The default value for machines with more than 32MiB of memory
is 32768, machines with less memory use 16384 by default.
logdev=device and rtdev=device
@@ -62,6 +109,11 @@ When mounting an XFS filesystem, the following options are accepted.
optional, and the log section can be separate from the data
section or contained within it.
+ mtpt=mountpoint
+ Use with the "dmapi" option. The value specified here will be
+ included in the DMAPI mount event, and should be the path of
+ the actual mountpoint that is used.
+
noalign
Data allocations will not be aligned at stripe unit boundaries.
@@ -91,13 +143,17 @@ When mounting an XFS filesystem, the following options are accepted.
O_SYNC writes can be lost if the system crashes.
If timestamp updates are critical, use the osyncisosync option.
- quota/usrquota/uqnoenforce
+ uquota/usrquota/uqnoenforce/quota
User disk quota accounting enabled, and limits (optionally)
- enforced.
+ enforced. Refer to xfs_quota(8) for further details.
- grpquota/gqnoenforce
+ gquota/grpquota/gqnoenforce
Group disk quota accounting enabled and limits (optionally)
- enforced.
+ enforced. Refer to xfs_quota(8) for further details.
+
+ pquota/prjquota/pqnoenforce
+ Project disk quota accounting enabled and limits (optionally)
+ enforced. Refer to xfs_quota(8) for further details.
sunit=value and swidth=value
Used to specify the stripe unit and width for a RAID device or
@@ -113,15 +169,21 @@ When mounting an XFS filesystem, the following options are accepted.
The "swidth" option is required if the "sunit" option has been
specified, and must be a multiple of the "sunit" value.
+ swalloc
+ Data allocations will be rounded up to stripe width boundaries
+ when the current end of file is being extended and the file
+ size is larger than the stripe width size.
+
+
sysctls
=======
The following sysctls are available for the XFS filesystem:
fs.xfs.stats_clear (Min: 0 Default: 0 Max: 1)
- Setting this to "1" clears accumulated XFS statistics
+ Setting this to "1" clears accumulated XFS statistics
in /proc/fs/xfs/stat. It then immediately resets to "0".
-
+
fs.xfs.xfssyncd_centisecs (Min: 100 Default: 3000 Max: 720000)
The interval at which the xfssyncd thread flushes metadata
out to disk. This thread will flush log activity out, and
@@ -143,9 +205,9 @@ The following sysctls are available for the XFS filesystem:
XFS_ERRLEVEL_HIGH: 5
fs.xfs.panic_mask (Min: 0 Default: 0 Max: 127)
- Causes certain error conditions to call BUG(). Value is a bitmask;
+ Causes certain error conditions to call BUG(). Value is a bitmask;
AND together the tags which represent errors which should cause panics:
-
+
XFS_NO_PTAG 0
XFS_PTAG_IFLUSH 0x00000001
XFS_PTAG_LOGRES 0x00000002
@@ -155,7 +217,7 @@ The following sysctls are available for the XFS filesystem:
XFS_PTAG_SHUTDOWN_IOERROR 0x00000020
XFS_PTAG_SHUTDOWN_LOGERROR 0x00000040
- This option is intended for debugging only.
+ This option is intended for debugging only.
fs.xfs.irix_symlink_mode (Min: 0 Default: 0 Max: 1)
Controls whether symlinks are created with mode 0777 (default)
@@ -164,25 +226,37 @@ The following sysctls are available for the XFS filesystem:
fs.xfs.irix_sgid_inherit (Min: 0 Default: 0 Max: 1)
Controls files created in SGID directories.
If the group ID of the new file does not match the effective group
- ID or one of the supplementary group IDs of the parent dir, the
- ISGID bit is cleared if the irix_sgid_inherit compatibility sysctl
+ ID or one of the supplementary group IDs of the parent dir, the
+ ISGID bit is cleared if the irix_sgid_inherit compatibility sysctl
is set.
fs.xfs.restrict_chown (Min: 0 Default: 1 Max: 1)
Controls whether unprivileged users can use chown to "give away"
a file to another user.
- fs.xfs.inherit_sync (Min: 0 Default: 1 Max 1)
- Setting this to "1" will cause the "sync" flag set
- by the chattr(1) command on a directory to be
+ fs.xfs.inherit_sync (Min: 0 Default: 1 Max: 1)
+ Setting this to "1" will cause the "sync" flag set
+ by the xfs_io(8) chattr command on a directory to be
inherited by files in that directory.
- fs.xfs.inherit_nodump (Min: 0 Default: 1 Max 1)
- Setting this to "1" will cause the "nodump" flag set
- by the chattr(1) command on a directory to be
+ fs.xfs.inherit_nodump (Min: 0 Default: 1 Max: 1)
+ Setting this to "1" will cause the "nodump" flag set
+ by the xfs_io(8) chattr command on a directory to be
inherited by files in that directory.
- fs.xfs.inherit_noatime (Min: 0 Default: 1 Max 1)
- Setting this to "1" will cause the "noatime" flag set
- by the chattr(1) command on a directory to be
+ fs.xfs.inherit_noatime (Min: 0 Default: 1 Max: 1)
+ Setting this to "1" will cause the "noatime" flag set
+ by the xfs_io(8) chattr command on a directory to be
inherited by files in that directory.
+
+ fs.xfs.inherit_nosymlinks (Min: 0 Default: 1 Max: 1)
+ Setting this to "1" will cause the "nosymlinks" flag set
+ by the xfs_io(8) chattr command on a directory to be
+ inherited by files in that directory.
+
+ fs.xfs.rotorstep (Min: 1 Default: 1 Max: 256)
+ In "inode32" allocation mode, this option determines how many
+ files the allocator attempts to allocate in the same allocation
+ group before moving to the next allocation group. The intent
+ is to control the rate at which the allocator moves between
+ allocation groups when allocating extents for new files.
diff --git a/Documentation/firmware_class/firmware_sample_driver.c b/Documentation/firmware_class/firmware_sample_driver.c
index 4bef8c25172c..d3ad2c24490a 100644
--- a/Documentation/firmware_class/firmware_sample_driver.c
+++ b/Documentation/firmware_class/firmware_sample_driver.c
@@ -13,6 +13,7 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/device.h>
+#include <linux/string.h>
#include "linux/firmware.h"
diff --git a/Documentation/firmware_class/firmware_sample_firmware_class.c b/Documentation/firmware_class/firmware_sample_firmware_class.c
index 09eab2f1b373..57b956aecbc5 100644
--- a/Documentation/firmware_class/firmware_sample_firmware_class.c
+++ b/Documentation/firmware_class/firmware_sample_firmware_class.c
@@ -14,6 +14,8 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/timer.h>
+#include <linux/slab.h>
+#include <linux/string.h>
#include <linux/firmware.h>
diff --git a/Documentation/hpet.txt b/Documentation/hpet.txt
index 4e7cc8d3359b..e52457581f47 100644
--- a/Documentation/hpet.txt
+++ b/Documentation/hpet.txt
@@ -1,18 +1,21 @@
High Precision Event Timer Driver for Linux
-The High Precision Event Timer (HPET) hardware is the future replacement for the 8254 and Real
-Time Clock (RTC) periodic timer functionality. Each HPET can have up two 32 timers. It is possible
-to configure the first two timers as legacy replacements for 8254 and RTC periodic. A specification
-done by INTEL and Microsoft can be found at http://www.intel.com/labs/platcomp/hpet/hpetspec.htm.
-
-The driver supports detection of HPET driver allocation and initialization of the HPET before the
-driver module_init routine is called. This enables platform code which uses timer 0 or 1 as the
-main timer to intercept HPET initialization. An example of this initialization can be found in
+The High Precision Event Timer (HPET) hardware is the future replacement
+for the 8254 and Real Time Clock (RTC) periodic timer functionality.
+Each HPET can have up two 32 timers. It is possible to configure the
+first two timers as legacy replacements for 8254 and RTC periodic timers.
+A specification done by Intel and Microsoft can be found at
+<http://www.intel.com/hardwaredesign/hpetspec.htm>.
+
+The driver supports detection of HPET driver allocation and initialization
+of the HPET before the driver module_init routine is called. This enables
+platform code which uses timer 0 or 1 as the main timer to intercept HPET
+initialization. An example of this initialization can be found in
arch/i386/kernel/time_hpet.c.
-The driver provides two APIs which are very similar to the API found in the rtc.c driver.
-There is a user space API and a kernel space API. An example user space program is provided
-below.
+The driver provides two APIs which are very similar to the API found in
+the rtc.c driver. There is a user space API and a kernel space API.
+An example user space program is provided below.
#include <stdio.h>
#include <stdlib.h>
@@ -290,9 +293,8 @@ The kernel API has three interfaces exported from the driver:
hpet_unregister(struct hpet_task *tp)
hpet_control(struct hpet_task *tp, unsigned int cmd, unsigned long arg)
-The kernel module using this interface fills in the ht_func and ht_data members of the
-hpet_task structure before calling hpet_register. hpet_control simply vectors to the hpet_ioctl
-routine and has the same commands and respective arguments as the user API. hpet_unregister
+The kernel module using this interface fills in the ht_func and ht_data
+members of the hpet_task structure before calling hpet_register.
+hpet_control simply vectors to the hpet_ioctl routine and has the same
+commands and respective arguments as the user API. hpet_unregister
is used to terminate usage of the HPET timer reserved by hpet_register.
-
-
diff --git a/Documentation/hwmon/it87 b/Documentation/hwmon/it87
index 0d0195040d88..7f42e441c645 100644
--- a/Documentation/hwmon/it87
+++ b/Documentation/hwmon/it87
@@ -4,18 +4,18 @@ Kernel driver it87
Supported chips:
* IT8705F
Prefix: 'it87'
- Addresses scanned: from Super I/O config space, or default ISA 0x290 (8 I/O ports)
+ Addresses scanned: from Super I/O config space (8 I/O ports)
Datasheet: Publicly available at the ITE website
http://www.ite.com.tw/
* IT8712F
Prefix: 'it8712'
Addresses scanned: I2C 0x28 - 0x2f
- from Super I/O config space, or default ISA 0x290 (8 I/O ports)
+ from Super I/O config space (8 I/O ports)
Datasheet: Publicly available at the ITE website
http://www.ite.com.tw/
* SiS950 [clone of IT8705F]
- Prefix: 'sis950'
- Addresses scanned: from Super I/O config space, or default ISA 0x290 (8 I/O ports)
+ Prefix: 'it87'
+ Addresses scanned: from Super I/O config space (8 I/O ports)
Datasheet: No longer be available
Author: Christophe Gauthron <chrisg@0-in.com>
diff --git a/Documentation/hwmon/lm90 b/Documentation/hwmon/lm90
index 2c4cf39471f4..438cb24cee5b 100644
--- a/Documentation/hwmon/lm90
+++ b/Documentation/hwmon/lm90
@@ -24,14 +24,14 @@ Supported chips:
http://www.national.com/pf/LM/LM86.html
* Analog Devices ADM1032
Prefix: 'adm1032'
- Addresses scanned: I2C 0x4c
+ Addresses scanned: I2C 0x4c and 0x4d
Datasheet: Publicly available at the Analog Devices website
- http://products.analog.com/products/info.asp?product=ADM1032
+ http://www.analog.com/en/prod/0,2877,ADM1032,00.html
* Analog Devices ADT7461
Prefix: 'adt7461'
- Addresses scanned: I2C 0x4c
+ Addresses scanned: I2C 0x4c and 0x4d
Datasheet: Publicly available at the Analog Devices website
- http://products.analog.com/products/info.asp?product=ADT7461
+ http://www.analog.com/en/prod/0,2877,ADT7461,00.html
Note: Only if in ADM1032 compatibility mode
* Maxim MAX6657
Prefix: 'max6657'
@@ -71,8 +71,8 @@ increased resolution of the remote temperature measurement.
The different chipsets of the family are not strictly identical, although
very similar. This driver doesn't handle any specific feature for now,
-but could if there ever was a need for it. For reference, here comes a
-non-exhaustive list of specific features:
+with the exception of SMBus PEC. For reference, here comes a non-exhaustive
+list of specific features:
LM90:
* Filter and alert configuration register at 0xBF.
@@ -91,6 +91,7 @@ ADM1032:
* Conversion averaging.
* Up to 64 conversions/s.
* ALERT is triggered by open remote sensor.
+ * SMBus PEC support for Write Byte and Receive Byte transactions.
ADT7461
* Extended temperature range (breaks compatibility)
@@ -119,3 +120,37 @@ The lm90 driver will not update its values more frequently than every
other second; reading them more often will do no harm, but will return
'old' values.
+PEC Support
+-----------
+
+The ADM1032 is the only chip of the family which supports PEC. It does
+not support PEC on all transactions though, so some care must be taken.
+
+When reading a register value, the PEC byte is computed and sent by the
+ADM1032 chip. However, in the case of a combined transaction (SMBus Read
+Byte), the ADM1032 computes the CRC value over only the second half of
+the message rather than its entirety, because it thinks the first half
+of the message belongs to a different transaction. As a result, the CRC
+value differs from what the SMBus master expects, and all reads fail.
+
+For this reason, the lm90 driver will enable PEC for the ADM1032 only if
+the bus supports the SMBus Send Byte and Receive Byte transaction types.
+These transactions will be used to read register values, instead of
+SMBus Read Byte, and PEC will work properly.
+
+Additionally, the ADM1032 doesn't support SMBus Send Byte with PEC.
+Instead, it will try to write the PEC value to the register (because the
+SMBus Send Byte transaction with PEC is similar to a Write Byte transaction
+without PEC), which is not what we want. Thus, PEC is explicitely disabled
+on SMBus Send Byte transactions in the lm90 driver.
+
+PEC on byte data transactions represents a significant increase in bandwidth
+usage (+33% for writes, +25% for reads) in normal conditions. With the need
+to use two SMBus transaction for reads, this overhead jumps to +50%. Worse,
+two transactions will typically mean twice as much delay waiting for
+transaction completion, effectively doubling the register cache refresh time.
+I guess reliability comes at a price, but it's quite expensive this time.
+
+So, as not everyone might enjoy the slowdown, PEC can be disabled through
+sysfs. Just write 0 to the "pec" file and PEC will be disabled. Write 1
+to that file to enable PEC again.
diff --git a/Documentation/hwmon/smsc47b397 b/Documentation/hwmon/smsc47b397
index da9d80c96432..20682f15ae41 100644
--- a/Documentation/hwmon/smsc47b397
+++ b/Documentation/hwmon/smsc47b397
@@ -3,6 +3,7 @@ Kernel driver smsc47b397
Supported chips:
* SMSC LPC47B397-NC
+ * SMSC SCH5307-NS
Prefix: 'smsc47b397'
Addresses scanned: none, address read from Super I/O config space
Datasheet: In this file
@@ -12,11 +13,14 @@ Authors: Mark M. Hoffman <mhoffman@lightlink.com>
November 23, 2004
-The following specification describes the SMSC LPC47B397-NC sensor chip
+The following specification describes the SMSC LPC47B397-NC[1] sensor chip
(for which there is no public datasheet available). This document was
provided by Craig Kelly (In-Store Broadcast Network) and edited/corrected
by Mark M. Hoffman <mhoffman@lightlink.com>.
+[1] And SMSC SCH5307-NS, which has a different device ID but is otherwise
+compatible.
+
* * * * *
Methods for detecting the HP SIO and reading the thermal data on a dc7100.
@@ -127,7 +131,7 @@ OUT DX,AL
The registers of interest for identifying the SIO on the dc7100 are Device ID
(0x20) and Device Rev (0x21).
-The Device ID will read 0X6F
+The Device ID will read 0x6F (for SCH5307-NS, 0x81)
The Device Rev currently reads 0x01
Obtaining the HWM Base Address.
diff --git a/Documentation/hwmon/smsc47m1 b/Documentation/hwmon/smsc47m1
index 34e6478c1425..c15bbe68264e 100644
--- a/Documentation/hwmon/smsc47m1
+++ b/Documentation/hwmon/smsc47m1
@@ -12,6 +12,10 @@ Supported chips:
http://www.smsc.com/main/datasheets/47m14x.pdf
http://www.smsc.com/main/tools/discontinued/47m15x.pdf
http://www.smsc.com/main/datasheets/47m192.pdf
+ * SMSC LPC47M997
+ Addresses scanned: none, address read from Super I/O config space
+ Prefix: 'smsc47m1'
+ Datasheet: none
Authors:
Mark D. Studebaker <mdsxyz123@yahoo.com>,
@@ -30,6 +34,9 @@ The 47M15x and 47M192 chips contain a full 'hardware monitoring block'
in addition to the fan monitoring and control. The hardware monitoring
block is not supported by the driver.
+No documentation is available for the 47M997, but it has the same device
+ID as the 47M15x and 47M192 chips and seems to be compatible.
+
Fan rotation speeds are reported in RPM (rotations per minute). An alarm is
triggered if the rotation speed has dropped below a programmable limit. Fan
readings can be divided by a programmable divider (1, 2, 4 or 8) to give
diff --git a/Documentation/hwmon/sysfs-interface b/Documentation/hwmon/sysfs-interface
index 346400519d0d..764cdc5480e7 100644
--- a/Documentation/hwmon/sysfs-interface
+++ b/Documentation/hwmon/sysfs-interface
@@ -272,3 +272,6 @@ beep_mask Bitmask for beep.
eeprom Raw EEPROM data in binary form.
Read only.
+
+pec Enable or disable PEC (SMBus only)
+ Read/Write
diff --git a/Documentation/hwmon/via686a b/Documentation/hwmon/via686a
index b82014cb7c53..a936fb3824b2 100644
--- a/Documentation/hwmon/via686a
+++ b/Documentation/hwmon/via686a
@@ -18,8 +18,9 @@ Authors:
Module Parameters
-----------------
-force_addr=0xaddr Set the I/O base address. Useful for Asus A7V boards
- that don't set the address in the BIOS. Does not do a
+force_addr=0xaddr Set the I/O base address. Useful for boards that
+ don't set the address in the BIOS. Look for a BIOS
+ upgrade before resorting to this. Does not do a
PCI force; the via686a must still be present in lspci.
Don't use this unless the driver complains that the
base address is not set.
@@ -63,3 +64,15 @@ miss once-only alarms.
The driver only updates its values each 1.5 seconds; reading it more often
will do no harm, but will return 'old' values.
+
+Known Issues
+------------
+
+This driver handles sensors integrated in some VIA south bridges. It is
+possible that a motherboard maker used a VT82C686A/B chip as part of a
+product design but was not interested in its hardware monitoring features,
+in which case the sensor inputs will not be wired. This is the case of
+the Asus K7V, A7V and A7V133 motherboards, to name only a few of them.
+So, if you need the force_addr parameter, and end up with values which
+don't seem to make any sense, don't look any further: your chip is simply
+not wired for hardware monitoring.
diff --git a/Documentation/i2c/busses/i2c-i810 b/Documentation/i2c/busses/i2c-i810
index 0544eb332887..83c3b9743c3c 100644
--- a/Documentation/i2c/busses/i2c-i810
+++ b/Documentation/i2c/busses/i2c-i810
@@ -2,6 +2,7 @@ Kernel driver i2c-i810
Supported adapters:
* Intel 82810, 82810-DC100, 82810E, and 82815 (GMCH)
+ * Intel 82845G (GMCH)
Authors:
Frodo Looijaard <frodol@dds.nl>,
diff --git a/Documentation/i2c/busses/i2c-viapro b/Documentation/i2c/busses/i2c-viapro
index 702f5ac68c09..16775663b9f5 100644
--- a/Documentation/i2c/busses/i2c-viapro
+++ b/Documentation/i2c/busses/i2c-viapro
@@ -4,17 +4,16 @@ Supported adapters:
* VIA Technologies, Inc. VT82C596A/B
Datasheet: Sometimes available at the VIA website
- * VIA Technologies, Inc. VT82C686A/B
+ * VIA Technologies, Inc. VT82C686A/B
Datasheet: Sometimes available at the VIA website
- * VIA Technologies, Inc. VT8231, VT8233, VT8233A, VT8235, VT8237
- Datasheet: available on request from Via
+ * VIA Technologies, Inc. VT8231, VT8233, VT8233A, VT8235, VT8237R
+ Datasheet: available on request from VIA
Authors:
- Frodo Looijaard <frodol@dds.nl>,
- Philip Edelbrock <phil@netroedge.com>,
- Kyösti Mälkki <kmalkki@cc.hut.fi>,
- Mark D. Studebaker <mdsxyz123@yahoo.com>
+ Kyösti Mälkki <kmalkki@cc.hut.fi>,
+ Mark D. Studebaker <mdsxyz123@yahoo.com>,
+ Jean Delvare <khali@linux-fr.org>
Module Parameters
-----------------
@@ -28,20 +27,22 @@ Description
-----------
i2c-viapro is a true SMBus host driver for motherboards with one of the
-supported VIA southbridges.
+supported VIA south bridges.
Your lspci -n listing must show one of these :
- device 1106:3050 (VT82C596 function 3)
- device 1106:3051 (VT82C596 function 3)
+ device 1106:3050 (VT82C596A function 3)
+ device 1106:3051 (VT82C596B function 3)
device 1106:3057 (VT82C686 function 4)
device 1106:3074 (VT8233)
device 1106:3147 (VT8233A)
- device 1106:8235 (VT8231)
- devide 1106:3177 (VT8235)
- devide 1106:3227 (VT8237)
+ device 1106:8235 (VT8231 function 4)
+ device 1106:3177 (VT8235)
+ device 1106:3227 (VT8237R)
If none of these show up, you should look in the BIOS for settings like
enable ACPI / SMBus or even USB.
-
+Except for the oldest chips (VT82C596A/B, VT82C686A and most probably
+VT8231), this driver supports I2C block transactions. Such transactions
+are mainly useful to read from and write to EEPROMs.
diff --git a/Documentation/i2c/chips/x1205 b/Documentation/i2c/chips/x1205
new file mode 100644
index 000000000000..09407c991fe5
--- /dev/null
+++ b/Documentation/i2c/chips/x1205
@@ -0,0 +1,38 @@
+Kernel driver x1205
+===================
+
+Supported chips:
+ * Xicor X1205 RTC
+ Prefix: 'x1205'
+ Addresses scanned: none
+ Datasheet: http://www.intersil.com/cda/deviceinfo/0,1477,X1205,00.html
+
+Authors:
+ Karen Spearel <kas11@tampabay.rr.com>,
+ Alessandro Zummo <a.zummo@towertech.it>
+
+Description
+-----------
+
+This module aims to provide complete access to the Xicor X1205 RTC.
+Recently Xicor has merged with Intersil, but the chip is
+still sold under the Xicor brand.
+
+This chip is located at address 0x6f and uses a 2-byte register addressing.
+Two bytes need to be written to read a single register, while most
+other chips just require one and take the second one as the data
+to be written. To prevent corrupting unknown chips, the user must
+explicitely set the probe parameter.
+
+example:
+
+modprobe x1205 probe=0,0x6f
+
+The module supports one more option, hctosys, which is used to set the
+software clock from the x1205. On systems where the x1205 is the
+only hardware rtc, this parameter could be used to achieve a correct
+date/time earlier in the system boot sequence.
+
+example:
+
+modprobe x1205 probe=0,0x6f hctosys=1
diff --git a/Documentation/i2c/functionality b/Documentation/i2c/functionality
index 41ffefbdc60c..60cca249e452 100644
--- a/Documentation/i2c/functionality
+++ b/Documentation/i2c/functionality
@@ -17,9 +17,10 @@ For the most up-to-date list of functionality constants, please check
I2C_FUNC_I2C Plain i2c-level commands (Pure SMBus
adapters typically can not do these)
I2C_FUNC_10BIT_ADDR Handles the 10-bit address extensions
- I2C_FUNC_PROTOCOL_MANGLING Knows about the I2C_M_REV_DIR_ADDR,
- I2C_M_REV_DIR_ADDR and I2C_M_REV_DIR_NOSTART
- flags (which modify the i2c protocol!)
+ I2C_FUNC_PROTOCOL_MANGLING Knows about the I2C_M_IGNORE_NAK,
+ I2C_M_REV_DIR_ADDR, I2C_M_NOSTART and
+ I2C_M_NO_RD_ACK flags (which modify the
+ I2C protocol!)
I2C_FUNC_SMBUS_QUICK Handles the SMBus write_quick command
I2C_FUNC_SMBUS_READ_BYTE Handles the SMBus read_byte command
I2C_FUNC_SMBUS_WRITE_BYTE Handles the SMBus write_byte command
diff --git a/Documentation/i2c/porting-clients b/Documentation/i2c/porting-clients
index 4849dfd6961c..184fac2377aa 100644
--- a/Documentation/i2c/porting-clients
+++ b/Documentation/i2c/porting-clients
@@ -82,7 +82,7 @@ Technical changes:
exit and exit_free. For i2c+isa drivers, labels should be named
ERROR0, ERROR1 and ERROR2. Don't forget to properly set err before
jumping to error labels. By the way, labels should be left-aligned.
- Use memset to fill the client and data area with 0x00.
+ Use kzalloc instead of kmalloc.
Use i2c_set_clientdata to set the client data (as opposed to
a direct access to client->data).
Use strlcpy instead of strcpy to copy the client name.
diff --git a/Documentation/i2c/writing-clients b/Documentation/i2c/writing-clients
index 077275722a7c..d19993cc0604 100644
--- a/Documentation/i2c/writing-clients
+++ b/Documentation/i2c/writing-clients
@@ -33,8 +33,8 @@ static struct i2c_driver foo_driver = {
.command = &foo_command /* may be NULL */
}
-The name can be chosen freely, and may be upto 40 characters long. Please
-use something descriptive here.
+The name field must match the driver name, including the case. It must not
+contain spaces, and may be up to 31 characters long.
Don't worry about the flags field; just put I2C_DF_NOTIFY into it. This
means that your driver will be notified when new adapters are found.
@@ -43,9 +43,6 @@ This is almost always what you want.
All other fields are for call-back functions which will be explained
below.
-There use to be two additional fields in this structure, inc_use et dec_use,
-for module usage count, but these fields were obsoleted and removed.
-
Extra client data
=================
@@ -58,6 +55,7 @@ be very useful.
An example structure is below.
struct foo_data {
+ struct i2c_client client;
struct semaphore lock; /* For ISA access in `sensors' drivers. */
int sysctl_id; /* To keep the /proc directory entry for
`sensors' drivers. */
@@ -275,6 +273,7 @@ For now, you can ignore the `flags' parameter. It is there for future use.
if (is_isa) {
/* Discard immediately if this ISA range is already used */
+ /* FIXME: never use check_region(), only request_region() */
if (check_region(address,FOO_EXTENT))
goto ERROR0;
@@ -310,22 +309,15 @@ For now, you can ignore the `flags' parameter. It is there for future use.
client structure, even though we cannot fill it completely yet.
But it allows us to access several i2c functions safely */
- /* Note that we reserve some space for foo_data too. If you don't
- need it, remove it. We do it here to help to lessen memory
- fragmentation. */
- if (! (new_client = kmalloc(sizeof(struct i2c_client) +
- sizeof(struct foo_data),
- GFP_KERNEL))) {
+ if (!(data = kzalloc(sizeof(struct foo_data), GFP_KERNEL))) {
err = -ENOMEM;
goto ERROR0;
}
- /* This is tricky, but it will set the data to the right value. */
- client->data = new_client + 1;
- data = (struct foo_data *) (client->data);
+ new_client = &data->client;
+ i2c_set_clientdata(new_client, data);
new_client->addr = address;
- new_client->data = data;
new_client->adapter = adapter;
new_client->driver = &foo_driver;
new_client->flags = 0;
@@ -420,7 +412,7 @@ For now, you can ignore the `flags' parameter. It is there for future use.
release_region(address,FOO_EXTENT);
/* SENSORS ONLY END */
ERROR1:
- kfree(new_client);
+ kfree(data);
ERROR0:
return err;
}
@@ -451,7 +443,7 @@ much simpler than the attachment code, fortunately!
release_region(client->addr,LM78_EXTENT);
/* HYBRID SENSORS CHIP ONLY END */
- kfree(client); /* Frees client data too, if allocated at the same time */
+ kfree(i2c_get_clientdata(client));
return 0;
}
@@ -576,12 +568,12 @@ SMBus communication
extern s32 i2c_smbus_write_block_data(struct i2c_client * client,
u8 command, u8 length,
u8 *values);
+ extern s32 i2c_smbus_read_i2c_block_data(struct i2c_client * client,
+ u8 command, u8 *values);
These ones were removed in Linux 2.6.10 because they had no users, but could
be added back later if needed:
- extern s32 i2c_smbus_read_i2c_block_data(struct i2c_client * client,
- u8 command, u8 *values);
extern s32 i2c_smbus_read_block_data(struct i2c_client * client,
u8 command, u8 *values);
extern s32 i2c_smbus_write_i2c_block_data(struct i2c_client * client,
diff --git a/Documentation/input/yealink.txt b/Documentation/input/yealink.txt
index 85f095a7ad04..0962c5c948be 100644
--- a/Documentation/input/yealink.txt
+++ b/Documentation/input/yealink.txt
@@ -2,7 +2,6 @@ Driver documentation for yealink usb-p1k phones
0. Status
~~~~~~~~~
-
The p1k is a relatively cheap usb 1.1 phone with:
- keyboard full support, yealink.ko / input event API
- LCD full support, yealink.ko / sysfs API
@@ -17,9 +16,8 @@ For vendor documentation see http://www.yealink.com
1. Compilation (stand alone version)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
Currently only kernel 2.6.x.y versions are supported.
-In order to build the yealink.ko module do:
+In order to build the yealink.ko module do
make
@@ -28,6 +26,21 @@ the Makefile is pointing to the location where your kernel sources
are located, default /usr/src/linux.
+1.1 Troubleshooting
+~~~~~~~~~~~~~~~~~~~
+Q: Module yealink compiled and installed without any problem but phone
+ is not initialized and does not react to any actions.
+A: If you see something like:
+ hiddev0: USB HID v1.00 Device [Yealink Network Technology Ltd. VOIP USB Phone
+ in dmesg, it means that the hid driver has grabbed the device first. Try to
+ load module yealink before any other usb hid driver. Please see the
+ instructions provided by your distribution on module configuration.
+
+Q: Phone is working now (displays version and accepts keypad input) but I can't
+ find the sysfs files.
+A: The sysfs files are located on the particular usb endpoint. On most
+ distributions you can do: "find /sys/ -name get_icons" for a hint.
+
2. keyboard features
~~~~~~~~~~~~~~~~~~~~
diff --git a/Documentation/ioctl-number.txt b/Documentation/ioctl-number.txt
index 769f925c8526..87f4d052e39c 100644
--- a/Documentation/ioctl-number.txt
+++ b/Documentation/ioctl-number.txt
@@ -130,8 +130,6 @@ Code Seq# Include File Comments
<mailto:zapman@interlan.net>
'i' 00-3F linux/i2o.h
'j' 00-3F linux/joystick.h
-'k' all asm-sparc/kbio.h
- asm-sparc64/kbio.h
'l' 00-3F linux/tcfs_fs.h transparent cryptographic file system
<http://mikonos.dia.unisa.it/tcfs>
'l' 40-7F linux/udf_fs_i.h in development:
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 971589a9752d..5dffcfefc3c7 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -1460,8 +1460,6 @@ running once the system is up.
stifb= [HW]
Format: bpp:<bpp1>[:<bpp2>[:<bpp3>...]]
- stram_swap= [HW,M68k]
-
swiotlb= [IA-64] Number of I/O TLB slabs
switches= [HW,M68k]
@@ -1517,8 +1515,6 @@ running once the system is up.
uart6850= [HW,OSS]
Format: <io>,<irq>
- usb-handoff [HW] Enable early USB BIOS -> OS handoff
-
usbhid.mousepoll=
[USBHID] The interval which mice are to be polled at.
diff --git a/Documentation/keys.txt b/Documentation/keys.txt
index 4afe03a58c5b..31154882000a 100644
--- a/Documentation/keys.txt
+++ b/Documentation/keys.txt
@@ -196,7 +196,7 @@ KEY ACCESS PERMISSIONS
Keys have an owner user ID, a group access ID, and a permissions mask. The mask
has up to eight bits each for possessor, user, group and other access. Only
-five of each set of eight bits are defined. These permissions granted are:
+six of each set of eight bits are defined. These permissions granted are:
(*) View
@@ -224,6 +224,10 @@ five of each set of eight bits are defined. These permissions granted are:
keyring to a key, a process must have Write permission on the keyring and
Link permission on the key.
+ (*) Set Attribute
+
+ This permits a key's UID, GID and permissions mask to be changed.
+
For changing the ownership, group ID or permissions mask, being the owner of
the key or having the sysadmin capability is sufficient.
@@ -242,15 +246,15 @@ about the status of the key service:
this way:
SERIAL FLAGS USAGE EXPY PERM UID GID TYPE DESCRIPTION: SUMMARY
- 00000001 I----- 39 perm 1f1f0000 0 0 keyring _uid_ses.0: 1/4
- 00000002 I----- 2 perm 1f1f0000 0 0 keyring _uid.0: empty
- 00000007 I----- 1 perm 1f1f0000 0 0 keyring _pid.1: empty
- 0000018d I----- 1 perm 1f1f0000 0 0 keyring _pid.412: empty
- 000004d2 I--Q-- 1 perm 1f1f0000 32 -1 keyring _uid.32: 1/4
- 000004d3 I--Q-- 3 perm 1f1f0000 32 -1 keyring _uid_ses.32: empty
+ 00000001 I----- 39 perm 1f3f0000 0 0 keyring _uid_ses.0: 1/4
+ 00000002 I----- 2 perm 1f3f0000 0 0 keyring _uid.0: empty
+ 00000007 I----- 1 perm 1f3f0000 0 0 keyring _pid.1: empty
+ 0000018d I----- 1 perm 1f3f0000 0 0 keyring _pid.412: empty
+ 000004d2 I--Q-- 1 perm 1f3f0000 32 -1 keyring _uid.32: 1/4
+ 000004d3 I--Q-- 3 perm 1f3f0000 32 -1 keyring _uid_ses.32: empty
00000892 I--QU- 1 perm 1f000000 0 0 user metal:copper: 0
- 00000893 I--Q-N 1 35s 1f1f0000 0 0 user metal:silver: 0
- 00000894 I--Q-- 1 10h 001f0000 0 0 user metal:gold: 0
+ 00000893 I--Q-N 1 35s 1f3f0000 0 0 user metal:silver: 0
+ 00000894 I--Q-- 1 10h 003f0000 0 0 user metal:gold: 0
The flags are:
diff --git a/Documentation/m68k/kernel-options.txt b/Documentation/m68k/kernel-options.txt
index e191baad8308..d5d3f064f552 100644
--- a/Documentation/m68k/kernel-options.txt
+++ b/Documentation/m68k/kernel-options.txt
@@ -626,7 +626,7 @@ ignored (others aren't affected).
can be performed in optimal order. Not all SCSI devices support
tagged queuing (:-().
-4.6 switches=
+4.5 switches=
-------------
Syntax: switches=<list of switches>
@@ -661,28 +661,6 @@ correctly.
earlier initialization ("ov_"-less) takes precedence. But the
switching-off on reset still happens in this case.
-4.5) stram_swap=
-----------------
-
-Syntax: stram_swap=<do_swap>[,<max_swap>]
-
- This option is available only if the kernel has been compiled with
-CONFIG_STRAM_SWAP enabled. Normally, the kernel then determines
-dynamically whether to actually use ST-RAM as swap space. (Currently,
-the fraction of ST-RAM must be less or equal 1/3 of total memory to
-enable this swapping.) You can override the kernel's decision by
-specifying this option. 1 for <do_swap> means always enable the swap,
-even if you have less alternate RAM. 0 stands for never swap to
-ST-RAM, even if it's small enough compared to the rest of memory.
-
- If ST-RAM swapping is enabled, the kernel usually uses all free
-ST-RAM as swap "device". If the kernel resides in ST-RAM, the region
-allocated by it is obviously never used for swapping :-) You can also
-limit this amount by specifying the second parameter, <max_swap>, if
-you want to use parts of ST-RAM as normal system memory. <max_swap> is
-in kBytes and the number should be a multiple of 4 (otherwise: rounded
-down).
-
5) Options for Amiga Only:
==========================
diff --git a/Documentation/magic-number.txt b/Documentation/magic-number.txt
index bd8eefa17587..af67faccf4de 100644
--- a/Documentation/magic-number.txt
+++ b/Documentation/magic-number.txt
@@ -120,7 +120,7 @@ ISDN_NET_MAGIC 0x49344C02 isdn_net_local_s drivers/isdn/i4l/isdn_net_li
SAVEKMSG_MAGIC2 0x4B4D5347 savekmsg arch/*/amiga/config.c
STLI_BOARDMAGIC 0x4bc6c825 stlibrd include/linux/istallion.h
CS_STATE_MAGIC 0x4c4f4749 cs_state sound/oss/cs46xx.c
-SLAB_C_MAGIC 0x4f17a36d kmem_cache_s mm/slab.c
+SLAB_C_MAGIC 0x4f17a36d kmem_cache mm/slab.c
COW_MAGIC 0x4f4f4f4d cow_header_v1 arch/um/drivers/ubd_user.c
I810_CARD_MAGIC 0x5072696E i810_card sound/oss/i810_audio.c
TRIDENT_CARD_MAGIC 0x5072696E trident_card sound/oss/trident.c
diff --git a/Documentation/md.txt b/Documentation/md.txt
index e2b536992a27..23e6cce40f9c 100644
--- a/Documentation/md.txt
+++ b/Documentation/md.txt
@@ -116,3 +116,122 @@ and it's role in the array.
Once started with RUN_ARRAY, uninitialized spares can be added with
HOT_ADD_DISK.
+
+
+
+MD devices in sysfs
+-------------------
+md devices appear in sysfs (/sys) as regular block devices,
+e.g.
+ /sys/block/md0
+
+Each 'md' device will contain a subdirectory called 'md' which
+contains further md-specific information about the device.
+
+All md devices contain:
+ level
+ a text file indicating the 'raid level'. This may be a standard
+ numerical level prefixed by "RAID-" - e.g. "RAID-5", or some
+ other name such as "linear" or "multipath".
+ If no raid level has been set yet (array is still being
+ assembled), this file will be empty.
+
+ raid_disks
+ a text file with a simple number indicating the number of devices
+ in a fully functional array. If this is not yet known, the file
+ will be empty. If an array is being resized (not currently
+ possible) this will contain the larger of the old and new sizes.
+
+As component devices are added to an md array, they appear in the 'md'
+directory as new directories named
+ dev-XXX
+where XXX is a name that the kernel knows for the device, e.g. hdb1.
+Each directory contains:
+
+ block
+ a symlink to the block device in /sys/block, e.g.
+ /sys/block/md0/md/dev-hdb1/block -> ../../../../block/hdb/hdb1
+
+ super
+ A file containing an image of the superblock read from, or
+ written to, that device.
+
+ state
+ A file recording the current state of the device in the array
+ which can be a comma separated list of
+ faulty - device has been kicked from active use due to
+ a detected fault
+ in_sync - device is a fully in-sync member of the array
+ spare - device is working, but not a full member.
+ This includes spares that are in the process
+ of being recoverred to
+ This list make grow in future.
+
+
+An active md device will also contain and entry for each active device
+in the array. These are named
+
+ rdNN
+
+where 'NN' is the possition in the array, starting from 0.
+So for a 3 drive array there will be rd0, rd1, rd2.
+These are symbolic links to the appropriate 'dev-XXX' entry.
+Thus, for example,
+ cat /sys/block/md*/md/rd*/state
+will show 'in_sync' on every line.
+
+
+
+Active md devices for levels that support data redundancy (1,4,5,6)
+also have
+
+ sync_action
+ a text file that can be used to monitor and control the rebuild
+ process. It contains one word which can be one of:
+ resync - redundancy is being recalculated after unclean
+ shutdown or creation
+ recover - a hot spare is being built to replace a
+ failed/missing device
+ idle - nothing is happening
+ check - A full check of redundancy was requested and is
+ happening. This reads all block and checks
+ them. A repair may also happen for some raid
+ levels.
+ repair - A full check and repair is happening. This is
+ similar to 'resync', but was requested by the
+ user, and the write-intent bitmap is NOT used to
+ optimise the process.
+
+ This file is writable, and each of the strings that could be
+ read are meaningful for writing.
+
+ 'idle' will stop an active resync/recovery etc. There is no
+ guarantee that another resync/recovery may not be automatically
+ started again, though some event will be needed to trigger
+ this.
+ 'resync' or 'recovery' can be used to restart the
+ corresponding operation if it was stopped with 'idle'.
+ 'check' and 'repair' will start the appropriate process
+ providing the current state is 'idle'.
+
+ mismatch_count
+ When performing 'check' and 'repair', and possibly when
+ performing 'resync', md will count the number of errors that are
+ found. The count in 'mismatch_cnt' is the number of sectors
+ that were re-written, or (for 'check') would have been
+ re-written. As most raid levels work in units of pages rather
+ than sectors, this my be larger than the number of actual errors
+ by a factor of the number of sectors in a page.
+
+Each active md device may also have attributes specific to the
+personality module that manages it.
+These are specific to the implementation of the module and could
+change substantially if the implementation changes.
+
+These currently include
+
+ stripe_cache_size (currently raid5 only)
+ number of entries in the stripe cache. This is writable, but
+ there are upper and lower limits (32768, 16). Default is 128.
+ strip_cache_active (currently raid5 only)
+ number of active entries in the stripe cache
diff --git a/Documentation/mips/AU1xxx_IDE.README b/Documentation/mips/AU1xxx_IDE.README
new file mode 100644
index 000000000000..a7e4c4ea3560
--- /dev/null
+++ b/Documentation/mips/AU1xxx_IDE.README
@@ -0,0 +1,168 @@
+README for MIPS AU1XXX IDE driver - Released 2005-07-15
+
+ABOUT
+-----
+This file describes the 'drivers/ide/mips/au1xxx-ide.c', related files and the
+services they provide.
+
+If you are short in patience and just want to know how to add your hard disc to
+the white or black list, go to the 'ADD NEW HARD DISC TO WHITE OR BLACK LIST'
+section.
+
+
+LICENSE
+-------
+
+Copyright (c) 2003-2005 AMD, Personal Connectivity Solutions
+
+This program is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free Software
+Foundation; either version 2 of the License, or (at your option) any later
+version.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR
+BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+
+You should have received a copy of the GNU General Public License along with
+this program; if not, write to the Free Software Foundation, Inc.,
+675 Mass Ave, Cambridge, MA 02139, USA.
+
+Note: for more information, please refer "AMD Alchemy Au1200/Au1550 IDE
+ Interface and Linux Device Driver" Application Note.
+
+
+FILES, CONFIGS AND COMPATABILITY
+--------------------------------
+
+Two files are introduced:
+
+ a) 'include/asm-mips/mach-au1x00/au1xxx_ide.h'
+ containes : struct _auide_hwif
+ struct drive_list_entry dma_white_list
+ struct drive_list_entry dma_black_list
+ timing parameters for PIO mode 0/1/2/3/4
+ timing parameters for MWDMA 0/1/2
+
+ b) 'drivers/ide/mips/au1xxx-ide.c'
+ contains the functionality of the AU1XXX IDE driver
+
+Four configs variables are introduced:
+
+ CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA - enable the PIO+DBDMA mode
+ CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA - enable the MWDMA mode
+ CONFIG_BLK_DEV_IDE_AU1XXX_BURSTABLE_ON - set Burstable FIFO in DBDMA
+ controler
+ CONFIG_BLK_DEV_IDE_AU1XXX_SEQTS_PER_RQ - maximum transfer size
+ per descriptor
+
+If MWDMA is enabled and the connected hard disc is not on the white list, the
+kernel switches to a "safe mwdma mode" at boot time. In this mode the IDE
+performance is substantial slower then in full speed mwdma. In this case
+please add your hard disc to the white list (follow instruction from 'ADD NEW
+HARD DISC TO WHITE OR BLACK LIST' section).
+
+
+SUPPORTED IDE MODES
+-------------------
+
+The AU1XXX IDE driver supported all PIO modes - PIO mode 0/1/2/3/4 - and all
+MWDMA modes - MWDMA 0/1/2 -. There is no support for SWDMA and UDMA mode.
+
+To change the PIO mode use the program hdparm with option -p, e.g.
+'hdparm -p0 [device]' for PIO mode 0. To enable the MWDMA mode use the option
+-X, e.g. 'hdparm -X32 [device]' for MWDMA mode 0.
+
+
+PERFORMANCE CONFIGURATIONS
+--------------------------
+
+If the used system doesn't need USB support enable the following kernel configs:
+
+CONFIG_IDE=y
+CONFIG_BLK_DEV_IDE=y
+CONFIG_IDE_GENERIC=y
+CONFIG_BLK_DEV_IDEPCI=y
+CONFIG_BLK_DEV_GENERIC=y
+CONFIG_BLK_DEV_IDEDMA_PCI=y
+CONFIG_IDEDMA_PCI_AUTO=y
+CONFIG_BLK_DEV_IDE_AU1XXX=y
+CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA=y
+CONFIG_BLK_DEV_IDE_AU1XXX_BURSTABLE_ON=y
+CONFIG_BLK_DEV_IDE_AU1XXX_SEQTS_PER_RQ=128
+CONFIG_BLK_DEV_IDEDMA=y
+CONFIG_IDEDMA_AUTO=y
+
+If the used system need the USB support enable the following kernel configs for
+high IDE to USB throughput.
+
+CONFIG_BLK_DEV_IDEDISK=y
+CONFIG_IDE_GENERIC=y
+CONFIG_BLK_DEV_IDEPCI=y
+CONFIG_BLK_DEV_GENERIC=y
+CONFIG_BLK_DEV_IDEDMA_PCI=y
+CONFIG_IDEDMA_PCI_AUTO=y
+CONFIG_BLK_DEV_IDE_AU1XXX=y
+CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA=y
+CONFIG_BLK_DEV_IDE_AU1XXX_SEQTS_PER_RQ=128
+CONFIG_BLK_DEV_IDEDMA=y
+CONFIG_IDEDMA_AUTO=y
+
+
+ADD NEW HARD DISC TO WHITE OR BLACK LIST
+----------------------------------------
+
+Step 1 : detect the model name of your hard disc
+
+ a) connect your hard disc to the AU1XXX
+
+ b) boot your kernel and get the hard disc model.
+
+ Example boot log:
+
+ --snipped--
+ Uniform Multi-Platform E-IDE driver Revision: 7.00alpha2
+ ide: Assuming 50MHz system bus speed for PIO modes; override with idebus=xx
+ Au1xxx IDE(builtin) configured for MWDMA2
+ Probing IDE interface ide0...
+ hda: Maxtor 6E040L0, ATA DISK drive
+ ide0 at 0xac800000-0xac800007,0xac8001c0 on irq 64
+ hda: max request size: 64KiB
+ hda: 80293248 sectors (41110 MB) w/2048KiB Cache, CHS=65535/16/63, (U)DMA
+ --snipped--
+
+ In this example 'Maxtor 6E040L0'.
+
+Step 2 : edit 'include/asm-mips/mach-au1x00/au1xxx_ide.h'
+
+ Add your hard disc to the dma_white_list or dma_black_list structur.
+
+Step 3 : Recompile the kernel
+
+ Enable MWDMA support in the kernel configuration. Recompile the kernel and
+ reboot.
+
+Step 4 : Tests
+
+ If you have add a hard disc to the white list, please run some stress tests
+ for verification.
+
+
+ACKNOWLEDGMENTS
+---------------
+
+These drivers wouldn't have been done without the base of kernel 2.4.x AU1XXX
+IDE driver from AMD.
+
+Additional input also from:
+Matthias Lenk <matthias.lenk@amd.com>
+
+Happy hacking!
+Enrico Walther <enrico.walther@amd.com>
diff --git a/Documentation/networking/README.ipw2100 b/Documentation/networking/README.ipw2100
index 2046948b020d..3ab40379d1cf 100644
--- a/Documentation/networking/README.ipw2100
+++ b/Documentation/networking/README.ipw2100
@@ -1,27 +1,82 @@
-===========================
-Intel(R) PRO/Wireless 2100 Network Connection Driver for Linux
+Intel(R) PRO/Wireless 2100 Driver for Linux in support of:
+
+Intel(R) PRO/Wireless 2100 Network Connection
+
+Copyright (C) 2003-2005, Intel Corporation
+
README.ipw2100
-March 14, 2005
+Version: 1.1.3
+Date : October 17, 2005
-===========================
Index
----------------------------
-0. Introduction
-1. Release 1.1.0 Current Features
-2. Command Line Parameters
-3. Sysfs Helper Files
-4. Radio Kill Switch
-5. Dynamic Firmware
-6. Power Management
-7. Support
-8. License
-
-
-===========================
-0. Introduction
------------- ----- ----- ---- --- -- -
+-----------------------------------------------
+0. IMPORTANT INFORMATION BEFORE USING THIS DRIVER
+1. Introduction
+2. Release 1.1.3 Current Features
+3. Command Line Parameters
+4. Sysfs Helper Files
+5. Radio Kill Switch
+6. Dynamic Firmware
+7. Power Management
+8. Support
+9. License
+
+
+0. IMPORTANT INFORMATION BEFORE USING THIS DRIVER
+-----------------------------------------------
+
+Important Notice FOR ALL USERS OR DISTRIBUTORS!!!!
+
+Intel wireless LAN adapters are engineered, manufactured, tested, and
+quality checked to ensure that they meet all necessary local and
+governmental regulatory agency requirements for the regions that they
+are designated and/or marked to ship into. Since wireless LANs are
+generally unlicensed devices that share spectrum with radars,
+satellites, and other licensed and unlicensed devices, it is sometimes
+necessary to dynamically detect, avoid, and limit usage to avoid
+interference with these devices. In many instances Intel is required to
+provide test data to prove regional and local compliance to regional and
+governmental regulations before certification or approval to use the
+product is granted. Intel's wireless LAN's EEPROM, firmware, and
+software driver are designed to carefully control parameters that affect
+radio operation and to ensure electromagnetic compliance (EMC). These
+parameters include, without limitation, RF power, spectrum usage,
+channel scanning, and human exposure.
+
+For these reasons Intel cannot permit any manipulation by third parties
+of the software provided in binary format with the wireless WLAN
+adapters (e.g., the EEPROM and firmware). Furthermore, if you use any
+patches, utilities, or code with the Intel wireless LAN adapters that
+have been manipulated by an unauthorized party (i.e., patches,
+utilities, or code (including open source code modifications) which have
+not been validated by Intel), (i) you will be solely responsible for
+ensuring the regulatory compliance of the products, (ii) Intel will bear
+no liability, under any theory of liability for any issues associated
+with the modified products, including without limitation, claims under
+the warranty and/or issues arising from regulatory non-compliance, and
+(iii) Intel will not provide or be required to assist in providing
+support to any third parties for such modified products.
+
+Note: Many regulatory agencies consider Wireless LAN adapters to be
+modules, and accordingly, condition system-level regulatory approval
+upon receipt and review of test data documenting that the antennas and
+system configuration do not cause the EMC and radio operation to be
+non-compliant.
+
+The drivers available for download from SourceForge are provided as a
+part of a development project. Conformance to local regulatory
+requirements is the responsibility of the individual developer. As
+such, if you are interested in deploying or shipping a driver as part of
+solution intended to be used for purposes other than development, please
+obtain a tested driver from Intel Customer Support at:
+
+http://support.intel.com/support/notebook/sb/CS-006408.htm
+
+
+1. Introduction
+-----------------------------------------------
This document provides a brief overview of the features supported by the
IPW2100 driver project. The main project website, where the latest
@@ -34,9 +89,8 @@ potential fixes and patches, as well as links to the development mailing list
for the driver project.
-===========================
-1. Release 1.1.0 Current Supported Features
----------------------------
+2. Release 1.1.3 Current Supported Features
+-----------------------------------------------
- Managed (BSS) and Ad-Hoc (IBSS)
- WEP (shared key and open)
- Wireless Tools support
@@ -51,9 +105,8 @@ on the amount of validation and interoperability testing that has been
performed on a given feature.
-===========================
-2. Command Line Parameters
----------------------------
+3. Command Line Parameters
+-----------------------------------------------
If the driver is built as a module, the following optional parameters are used
by entering them on the command line with the modprobe command using this
@@ -75,9 +128,9 @@ associate boolean associate=0 /* Do NOT auto associate */
disable boolean disable=1 /* Do not power the HW */
-===========================
-3. Sysfs Helper Files
+4. Sysfs Helper Files
---------------------------
+-----------------------------------------------
There are several ways to control the behavior of the driver. Many of the
general capabilities are exposed through the Wireless Tools (iwconfig). There
@@ -120,9 +173,8 @@ For the device level files, see /sys/bus/pci/drivers/ipw2100:
based RF kill from ON -> OFF -> ON, the radio will NOT come back on
-===========================
-4. Radio Kill Switch
----------------------------
+5. Radio Kill Switch
+-----------------------------------------------
Most laptops provide the ability for the user to physically disable the radio.
Some vendors have implemented this as a physical switch that requires no
software to turn the radio off and on. On other laptops, however, the switch
@@ -134,9 +186,8 @@ See the Sysfs helper file 'rf_kill' for determining the state of the RF switch
on your system.
-===========================
-5. Dynamic Firmware
----------------------------
+6. Dynamic Firmware
+-----------------------------------------------
As the firmware is licensed under a restricted use license, it can not be
included within the kernel sources. To enable the IPW2100 you will need a
firmware image to load into the wireless NIC's processors.
@@ -146,9 +197,8 @@ You can obtain these images from <http://ipw2100.sf.net/firmware.php>.
See INSTALL for instructions on installing the firmware.
-===========================
-6. Power Management
----------------------------
+7. Power Management
+-----------------------------------------------
The IPW2100 supports the configuration of the Power Save Protocol
through a private wireless extension interface. The IPW2100 supports
the following different modes:
@@ -200,9 +250,8 @@ xxxx/yyyy will be replaced with 'off' -- the level reported will be the active
level if `iwconfig eth1 power on` is invoked.
-===========================
-7. Support
----------------------------
+8. Support
+-----------------------------------------------
For general development information and support,
go to:
@@ -218,9 +267,8 @@ For installation support on the ipw2100 1.1.0 driver on Linux kernels
http://supportmail.intel.com
-===========================
-8. License
----------------------------
+9. License
+-----------------------------------------------
Copyright(c) 2003 - 2005 Intel Corporation. All rights reserved.
diff --git a/Documentation/networking/README.ipw2200 b/Documentation/networking/README.ipw2200
index 6916080c5f03..c6492d3839fa 100644
--- a/Documentation/networking/README.ipw2200
+++ b/Documentation/networking/README.ipw2200
@@ -1,33 +1,89 @@
Intel(R) PRO/Wireless 2915ABG Driver for Linux in support of:
-Intel(R) PRO/Wireless 2200BG Network Connection
-Intel(R) PRO/Wireless 2915ABG Network Connection
+Intel(R) PRO/Wireless 2200BG Network Connection
+Intel(R) PRO/Wireless 2915ABG Network Connection
-Note: The Intel(R) PRO/Wireless 2915ABG Driver for Linux and Intel(R)
-PRO/Wireless 2200BG Driver for Linux is a unified driver that works on
-both hardware adapters listed above. In this document the Intel(R)
-PRO/Wireless 2915ABG Driver for Linux will be used to reference the
+Note: The Intel(R) PRO/Wireless 2915ABG Driver for Linux and Intel(R)
+PRO/Wireless 2200BG Driver for Linux is a unified driver that works on
+both hardware adapters listed above. In this document the Intel(R)
+PRO/Wireless 2915ABG Driver for Linux will be used to reference the
unified driver.
Copyright (C) 2004-2005, Intel Corporation
README.ipw2200
-Version: 1.0.0
-Date : January 31, 2005
+Version: 1.0.8
+Date : October 20, 2005
Index
-----------------------------------------------
+0. IMPORTANT INFORMATION BEFORE USING THIS DRIVER
1. Introduction
1.1. Overview of features
1.2. Module parameters
1.3. Wireless Extension Private Methods
1.4. Sysfs Helper Files
-2. About the Version Numbers
-3. Support
-4. License
+2. Ad-Hoc Networking
+3. Interacting with Wireless Tools
+3.1. iwconfig mode
+4. About the Version Numbers
+5. Firmware installation
+6. Support
+7. License
+
+
+0. IMPORTANT INFORMATION BEFORE USING THIS DRIVER
+-----------------------------------------------
+
+Important Notice FOR ALL USERS OR DISTRIBUTORS!!!!
+
+Intel wireless LAN adapters are engineered, manufactured, tested, and
+quality checked to ensure that they meet all necessary local and
+governmental regulatory agency requirements for the regions that they
+are designated and/or marked to ship into. Since wireless LANs are
+generally unlicensed devices that share spectrum with radars,
+satellites, and other licensed and unlicensed devices, it is sometimes
+necessary to dynamically detect, avoid, and limit usage to avoid
+interference with these devices. In many instances Intel is required to
+provide test data to prove regional and local compliance to regional and
+governmental regulations before certification or approval to use the
+product is granted. Intel's wireless LAN's EEPROM, firmware, and
+software driver are designed to carefully control parameters that affect
+radio operation and to ensure electromagnetic compliance (EMC). These
+parameters include, without limitation, RF power, spectrum usage,
+channel scanning, and human exposure.
+
+For these reasons Intel cannot permit any manipulation by third parties
+of the software provided in binary format with the wireless WLAN
+adapters (e.g., the EEPROM and firmware). Furthermore, if you use any
+patches, utilities, or code with the Intel wireless LAN adapters that
+have been manipulated by an unauthorized party (i.e., patches,
+utilities, or code (including open source code modifications) which have
+not been validated by Intel), (i) you will be solely responsible for
+ensuring the regulatory compliance of the products, (ii) Intel will bear
+no liability, under any theory of liability for any issues associated
+with the modified products, including without limitation, claims under
+the warranty and/or issues arising from regulatory non-compliance, and
+(iii) Intel will not provide or be required to assist in providing
+support to any third parties for such modified products.
+
+Note: Many regulatory agencies consider Wireless LAN adapters to be
+modules, and accordingly, condition system-level regulatory approval
+upon receipt and review of test data documenting that the antennas and
+system configuration do not cause the EMC and radio operation to be
+non-compliant.
+
+The drivers available for download from SourceForge are provided as a
+part of a development project. Conformance to local regulatory
+requirements is the responsibility of the individual developer. As
+such, if you are interested in deploying or shipping a driver as part of
+solution intended to be used for purposes other than development, please
+obtain a tested driver from Intel Customer Support at:
+
+http://support.intel.com/support/notebook/sb/CS-006408.htm
1. Introduction
@@ -45,7 +101,7 @@ file.
1.1. Overview of Features
-----------------------------------------------
-The current release (1.0.0) supports the following features:
+The current release (1.0.8) supports the following features:
+ BSS mode (Infrastructure, Managed)
+ IBSS mode (Ad-Hoc)
@@ -56,17 +112,27 @@ The current release (1.0.0) supports the following features:
+ Full A rate support (2915 only)
+ Transmit power control
+ S state support (ACPI suspend/resume)
+
+The following features are currently enabled, but not officially
+supported:
+
++ WPA
+ long/short preamble support
++ Monitor mode (aka RFMon)
+
+The distinction between officially supported and enabled is a reflection
+on the amount of validation and interoperability testing that has been
+performed on a given feature.
1.2. Command Line Parameters
-----------------------------------------------
-Like many modules used in the Linux kernel, the Intel(R) PRO/Wireless
-2915ABG Driver for Linux allows certain configuration options to be
-provided as module parameters. The most common way to specify a module
-parameter is via the command line.
+Like many modules used in the Linux kernel, the Intel(R) PRO/Wireless
+2915ABG Driver for Linux allows configuration options to be provided
+as module parameters. The most common way to specify a module parameter
+is via the command line.
The general form is:
@@ -96,14 +162,18 @@ Where the supported parameter are:
debug
If using a debug build, this is used to control the amount of debug
- info is logged. See the 'dval' and 'load' script for more info on
- how to use this (the dval and load scripts are provided as part
+ info is logged. See the 'dvals' and 'load' script for more info on
+ how to use this (the dvals and load scripts are provided as part
of the ipw2200 development snapshot releases available from the
SourceForge project at http://ipw2200.sf.net)
+
+ led
+ Can be used to turn on experimental LED code.
+ 0 = Off, 1 = On. Default is 0.
mode
Can be used to set the default mode of the adapter.
- 0 = Managed, 1 = Ad-Hoc
+ 0 = Managed, 1 = Ad-Hoc, 2 = Monitor
1.3. Wireless Extension Private Methods
@@ -164,8 +234,8 @@ The supported private methods are:
-----------------------------------------------
The Linux kernel provides a pseudo file system that can be used to
-access various components of the operating system. The Intel(R)
-PRO/Wireless 2915ABG Driver for Linux exposes several configuration
+access various components of the operating system. The Intel(R)
+PRO/Wireless 2915ABG Driver for Linux exposes several configuration
parameters through this mechanism.
An entry in the sysfs can support reading and/or writing. You can
@@ -184,13 +254,13 @@ You can set the debug level via:
Where $VALUE would be a number in the case of this sysfs entry. The
input to sysfs files does not have to be a number. For example, the
-firmware loader used by hotplug utilizes sysfs entries for transferring
+firmware loader used by hotplug utilizes sysfs entries for transfering
the firmware image from user space into the driver.
The Intel(R) PRO/Wireless 2915ABG Driver for Linux exposes sysfs entries
-at two levels -- driver level, which apply to all instances of the
-driver (in the event that there are more than one device installed) and
-device level, which applies only to the single specific instance.
+at two levels -- driver level, which apply to all instances of the driver
+(in the event that there are more than one device installed) and device
+level, which applies only to the single specific instance.
1.4.1 Driver Level Sysfs Helper Files
@@ -203,6 +273,7 @@ For the driver level files, look in /sys/bus/pci/drivers/ipw2200/
This controls the same global as the 'debug' module parameter
+
1.4.2 Device Level Sysfs Helper Files
-----------------------------------------------
@@ -213,7 +284,7 @@ For the device level files, look in
For example:
/sys/bus/pci/drivers/ipw2200/0000:02:01.0
-For the device level files, see /sys/bus/pci/[drivers/ipw2200:
+For the device level files, see /sys/bus/pci/drivers/ipw2200:
rf_kill
read -
@@ -231,8 +302,59 @@ For the device level files, see /sys/bus/pci/[drivers/ipw2200:
ucode
read-only access to the ucode version number
+ led
+ read -
+ 0 = LED code disabled
+ 1 = LED code enabled
+ write -
+ 0 = Disable LED code
+ 1 = Enable LED code
+
+ NOTE: The LED code has been reported to hang some systems when
+ running ifconfig and is therefore disabled by default.
+
+
+2. Ad-Hoc Networking
+-----------------------------------------------
+
+When using a device in an Ad-Hoc network, it is useful to understand the
+sequence and requirements for the driver to be able to create, join, or
+merge networks.
+
+The following attempts to provide enough information so that you can
+have a consistent experience while using the driver as a member of an
+Ad-Hoc network.
+
+2.1. Joining an Ad-Hoc Network
+-----------------------------------------------
+
+The easiest way to get onto an Ad-Hoc network is to join one that
+already exists.
-2. About the Version Numbers
+2.2. Creating an Ad-Hoc Network
+-----------------------------------------------
+
+An Ad-Hoc networks is created using the syntax of the Wireless tool.
+
+For Example:
+iwconfig eth1 mode ad-hoc essid testing channel 2
+
+2.3. Merging Ad-Hoc Networks
+-----------------------------------------------
+
+
+3. Interaction with Wireless Tools
+-----------------------------------------------
+
+3.1 iwconfig mode
+-----------------------------------------------
+
+When configuring the mode of the adapter, all run-time configured parameters
+are reset to the value used when the module was loaded. This includes
+channels, rates, ESSID, etc.
+
+
+4. About the Version Numbers
-----------------------------------------------
Due to the nature of open source development projects, there are
@@ -259,12 +381,23 @@ available as quickly as possible, unknown anomalies should be expected.
The major version number will be incremented when significant changes
are made to the driver. Currently, there are no major changes planned.
+5. Firmware installation
+----------------------------------------------
+
+The driver requires a firmware image, download it and extract the
+files under /lib/firmware (or wherever your hotplug's firmware.agent
+will look for firmware files)
+
+The firmware can be downloaded from the following URL:
-3. Support
+ http://ipw2200.sf.net/
+
+
+6. Support
-----------------------------------------------
-For installation support of the 1.0.0 version, you can contact
-http://supportmail.intel.com, or you can use the open source project
+For direct support of the 1.0.0 version, you can contact
+http://supportmail.intel.com, or you can use the open source project
support.
For general information and support, go to:
@@ -272,7 +405,7 @@ For general information and support, go to:
http://ipw2200.sf.net/
-4. License
+7. License
-----------------------------------------------
Copyright(c) 2003 - 2005 Intel Corporation. All rights reserved.
@@ -297,4 +430,3 @@ For general information and support, go to:
James P. Ketrenos <ipw2100-admin@linux.intel.com>
Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
-
diff --git a/Documentation/networking/bonding.txt b/Documentation/networking/bonding.txt
index a55f0f95b171..b0fe41da007b 100644
--- a/Documentation/networking/bonding.txt
+++ b/Documentation/networking/bonding.txt
@@ -777,7 +777,7 @@ doing so is the same as described in the "Configuring Multiple Bonds
Manually" section, below.
NOTE: It has been observed that some Red Hat supplied kernels
-are apparently unable to rename modules at load time (the "-obonding1"
+are apparently unable to rename modules at load time (the "-o bond1"
part). Attempts to pass that option to modprobe will produce an
"Operation not permitted" error. This has been reported on some
Fedora Core kernels, and has been seen on RHEL 4 as well. On kernels
@@ -883,7 +883,8 @@ the above does not work, and the second bonding instance never sees
its options. In that case, the second options line can be substituted
as follows:
-install bonding1 /sbin/modprobe bonding -obond1 mode=balance-alb miimon=50
+install bond1 /sbin/modprobe --ignore-install bonding -o bond1 \
+ mode=balance-alb miimon=50
This may be repeated any number of times, specifying a new and
unique name in place of bond1 for each subsequent instance.
diff --git a/Documentation/networking/dccp.txt b/Documentation/networking/dccp.txt
new file mode 100644
index 000000000000..c45daabd3bfe
--- /dev/null
+++ b/Documentation/networking/dccp.txt
@@ -0,0 +1,56 @@
+DCCP protocol
+============
+
+Last updated: 10 November 2005
+
+Contents
+========
+
+- Introduction
+- Missing features
+- Socket options
+- Notes
+
+Introduction
+============
+
+Datagram Congestion Control Protocol (DCCP) is an unreliable, connection
+based protocol designed to solve issues present in UDP and TCP particularly
+for real time and multimedia traffic.
+
+It has a base protocol and pluggable congestion control IDs (CCIDs).
+
+It is at draft RFC status and the homepage for DCCP as a protocol is at:
+ http://www.icir.org/kohler/dcp/
+
+Missing features
+================
+
+The DCCP implementation does not currently have all the features that are in
+the draft RFC.
+
+In particular the following are missing:
+- CCID2 support
+- feature negotiation
+
+When testing against other implementations it appears that elapsed time
+options are not coded compliant to the specification.
+
+Socket options
+==============
+
+DCCP_SOCKOPT_PACKET_SIZE is used for CCID3 to set default packet size for
+calculations.
+
+DCCP_SOCKOPT_SERVICE sets the service. This is compulsory as per the
+specification. If you don't set it you will get EPROTO.
+
+Notes
+=====
+
+SELinux does not yet have support for DCCP. You will need to turn it off or
+else you will get EACCES.
+
+DCCP does not travel through NAT successfully at present. This is because
+the checksum covers the psuedo-header as per TCP and UDP. It should be
+relatively trivial to add Linux NAT support for DCCP.
diff --git a/Documentation/networking/decnet.txt b/Documentation/networking/decnet.txt
index c6bd25f5d61d..e6c39c5831f5 100644
--- a/Documentation/networking/decnet.txt
+++ b/Documentation/networking/decnet.txt
@@ -176,8 +176,6 @@ information (_most_ of which _is_ _essential_) includes:
- Which client caused the problem ?
- How much data was being transferred ?
- Was the network congested ?
- - If there was a kernel panic, please run the output through ksymoops
- before sending it to me, otherwise its _useless_.
- How can the problem be reproduced ?
- Can you use tcpdump to get a trace ? (N.B. Most (all?) versions of
tcpdump don't understand how to dump DECnet properly, so including
diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt
index b433c8a27e2d..ebc09a159f62 100644
--- a/Documentation/networking/ip-sysctl.txt
+++ b/Documentation/networking/ip-sysctl.txt
@@ -78,6 +78,11 @@ inet_peer_gc_maxtime - INTEGER
TCP variables:
+tcp_abc - INTEGER
+ Controls Appropriate Byte Count defined in RFC3465. If set to
+ 0 then does congestion avoid once per ack. 1 is conservative
+ value, and 2 is more agressive.
+
tcp_syn_retries - INTEGER
Number of times initial SYNs for an active TCP connection attempt
will be retransmitted. Should not be higher than 255. Default value
@@ -309,7 +314,7 @@ tcp_tso_win_divisor - INTEGER
can be consumed by a single TSO frame.
The setting of this parameter is a choice between burstiness and
building larger TSO frames.
- Default: 8
+ Default: 3
tcp_frto - BOOLEAN
Enables F-RTO, an enhanced recovery algorithm for TCP retransmission
diff --git a/Documentation/networking/s2io.txt b/Documentation/networking/s2io.txt
index 6726b524ec45..bd528ffbeb4b 100644
--- a/Documentation/networking/s2io.txt
+++ b/Documentation/networking/s2io.txt
@@ -1,48 +1,153 @@
-S2IO Technologies XFrame 10 Gig adapter.
--------------------------------------------
-
-I. Module loadable parameters.
-When loaded as a module, the driver provides a host of Module loadable
-parameters, so the device can be tuned as per the users needs.
-A list of the Module params is given below.
-(i) ring_num: This can be used to program the number of
- receive rings used in the driver.
-(ii) ring_len: This defines the number of descriptors each ring
- can have. There can be a maximum of 8 rings.
-(iii) frame_len: This is an array of size 8. Using this we can
- set the maximum size of the received frame that can
- be steered into the corrsponding receive ring.
-(iv) fifo_num: This defines the number of Tx FIFOs thats used in
- the driver.
-(v) fifo_len: Each element defines the number of
- Tx descriptors that can be associated with each
- corresponding FIFO. There are a maximum of 8 FIFOs.
-(vi) tx_prio: This is a bool, if module is loaded with a non-zero
- value for tx_prio multi FIFO scheme is activated.
-(vii) rx_prio: This is a bool, if module is loaded with a non-zero
- value for tx_prio multi RING scheme is activated.
-(viii) latency_timer: The value given against this param will be
- loaded into the latency timer register in PCI Config
- space, else the register is left with its reset value.
-
-II. Performance tuning.
- By changing a few sysctl parameters.
- Copy the following lines into a file and run the following command,
- "sysctl -p <file_name>"
-### IPV4 specific settings
-net.ipv4.tcp_timestamps = 0 # turns TCP timestamp support off, default 1, reduces CPU use
-net.ipv4.tcp_sack = 0 # turn SACK support off, default on
-# on systems with a VERY fast bus -> memory interface this is the big gainer
-net.ipv4.tcp_rmem = 10000000 10000000 10000000 # sets min/default/max TCP read buffer, default 4096 87380 174760
-net.ipv4.tcp_wmem = 10000000 10000000 10000000 # sets min/pressure/max TCP write buffer, default 4096 16384 131072
-net.ipv4.tcp_mem = 10000000 10000000 10000000 # sets min/pressure/max TCP buffer space, default 31744 32256 32768
-
-### CORE settings (mostly for socket and UDP effect)
-net.core.rmem_max = 524287 # maximum receive socket buffer size, default 131071
-net.core.wmem_max = 524287 # maximum send socket buffer size, default 131071
-net.core.rmem_default = 524287 # default receive socket buffer size, default 65535
-net.core.wmem_default = 524287 # default send socket buffer size, default 65535
-net.core.optmem_max = 524287 # maximum amount of option memory buffers, default 10240
-net.core.netdev_max_backlog = 300000 # number of unprocessed input packets before kernel starts dropping them, default 300
----End of performance tuning file---
+Release notes for Neterion's (Formerly S2io) Xframe I/II PCI-X 10GbE driver.
+
+Contents
+=======
+- 1. Introduction
+- 2. Identifying the adapter/interface
+- 3. Features supported
+- 4. Command line parameters
+- 5. Performance suggestions
+- 6. Available Downloads
+
+
+1. Introduction:
+This Linux driver supports Neterion's Xframe I PCI-X 1.0 and
+Xframe II PCI-X 2.0 adapters. It supports several features
+such as jumbo frames, MSI/MSI-X, checksum offloads, TSO, UFO and so on.
+See below for complete list of features.
+All features are supported for both IPv4 and IPv6.
+
+2. Identifying the adapter/interface:
+a. Insert the adapter(s) in your system.
+b. Build and load driver
+# insmod s2io.ko
+c. View log messages
+# dmesg | tail -40
+You will see messages similar to:
+eth3: Neterion Xframe I 10GbE adapter (rev 3), Version 2.0.9.1, Intr type INTA
+eth4: Neterion Xframe II 10GbE adapter (rev 2), Version 2.0.9.1, Intr type INTA
+eth4: Device is on 64 bit 133MHz PCIX(M1) bus
+
+The above messages identify the adapter type(Xframe I/II), adapter revision,
+driver version, interface name(eth3, eth4), Interrupt type(INTA, MSI, MSI-X).
+In case of Xframe II, the PCI/PCI-X bus width and frequency are displayed
+as well.
+
+To associate an interface with a physical adapter use "ethtool -p <ethX>".
+The corresponding adapter's LED will blink multiple times.
+
+3. Features supported:
+a. Jumbo frames. Xframe I/II supports MTU upto 9600 bytes,
+modifiable using ifconfig command.
+
+b. Offloads. Supports checksum offload(TCP/UDP/IP) on transmit
+and receive, TSO.
+
+c. Multi-buffer receive mode. Scattering of packet across multiple
+buffers. Currently driver supports 2-buffer mode which yields
+significant performance improvement on certain platforms(SGI Altix,
+IBM xSeries).
+
+d. MSI/MSI-X. Can be enabled on platforms which support this feature
+(IA64, Xeon) resulting in noticeable performance improvement(upto 7%
+on certain platforms).
+
+e. NAPI. Compile-time option(CONFIG_S2IO_NAPI) for better Rx interrupt
+moderation.
+
+f. Statistics. Comprehensive MAC-level and software statistics displayed
+using "ethtool -S" option.
+
+g. Multi-FIFO/Ring. Supports up to 8 transmit queues and receive rings,
+with multiple steering options.
+
+4. Command line parameters
+a. tx_fifo_num
+Number of transmit queues
+Valid range: 1-8
+Default: 1
+
+b. rx_ring_num
+Number of receive rings
+Valid range: 1-8
+Default: 1
+
+c. tx_fifo_len
+Size of each transmit queue
+Valid range: Total length of all queues should not exceed 8192
+Default: 4096
+
+d. rx_ring_sz
+Size of each receive ring(in 4K blocks)
+Valid range: Limited by memory on system
+Default: 30
+
+e. intr_type
+Specifies interrupt type. Possible values 1(INTA), 2(MSI), 3(MSI-X)
+Valid range: 1-3
+Default: 1
+
+5. Performance suggestions
+General:
+a. Set MTU to maximum(9000 for switch setup, 9600 in back-to-back configuration)
+b. Set TCP windows size to optimal value.
+For instance, for MTU=1500 a value of 210K has been observed to result in
+good performance.
+# sysctl -w net.ipv4.tcp_rmem="210000 210000 210000"
+# sysctl -w net.ipv4.tcp_wmem="210000 210000 210000"
+For MTU=9000, TCP window size of 10 MB is recommended.
+# sysctl -w net.ipv4.tcp_rmem="10000000 10000000 10000000"
+# sysctl -w net.ipv4.tcp_wmem="10000000 10000000 10000000"
+
+Transmit performance:
+a. By default, the driver respects BIOS settings for PCI bus parameters.
+However, you may want to experiment with PCI bus parameters
+max-split-transactions(MOST) and MMRBC (use setpci command).
+A MOST value of 2 has been found optimal for Opterons and 3 for Itanium.
+It could be different for your hardware.
+Set MMRBC to 4K**.
+
+For example you can set
+For opteron
+#setpci -d 17d5:* 62=1d
+For Itanium
+#setpci -d 17d5:* 62=3d
+
+For detailed description of the PCI registers, please see Xframe User Guide.
+
+b. Ensure Transmit Checksum offload is enabled. Use ethtool to set/verify this
+parameter.
+c. Turn on TSO(using "ethtool -K")
+# ethtool -K <ethX> tso on
+
+Receive performance:
+a. By default, the driver respects BIOS settings for PCI bus parameters.
+However, you may want to set PCI latency timer to 248.
+#setpci -d 17d5:* LATENCY_TIMER=f8
+For detailed description of the PCI registers, please see Xframe User Guide.
+b. Use 2-buffer mode. This results in large performance boost on
+on certain platforms(eg. SGI Altix, IBM xSeries).
+c. Ensure Receive Checksum offload is enabled. Use "ethtool -K ethX" command to
+set/verify this option.
+d. Enable NAPI feature(in kernel configuration Device Drivers ---> Network
+device support ---> Ethernet (10000 Mbit) ---> S2IO 10Gbe Xframe NIC) to
+bring down CPU utilization.
+
+** For AMD opteron platforms with 8131 chipset, MMRBC=1 and MOST=1 are
+recommended as safe parameters.
+For more information, please review the AMD8131 errata at
+http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/26310.pdf
+
+6. Available Downloads
+Neterion "s2io" driver in Red Hat and Suse 2.6-based distributions is kept up
+to date, also the latest "s2io" code (including support for 2.4 kernels) is
+available via "Support" link on the Neterion site: http://www.neterion.com.
+
+For Xframe User Guide (Programming manual), visit ftp site ns1.s2io.com,
+user: linuxdocs password: HALdocs
+
+7. Support
+For further support please contact either your 10GbE Xframe NIC vendor (IBM,
+HP, SGI etc.) or click on the "Support" link on the Neterion site:
+http://www.neterion.com.
diff --git a/Documentation/oops-tracing.txt b/Documentation/oops-tracing.txt
index 66eaaab7773d..c563842ed805 100644
--- a/Documentation/oops-tracing.txt
+++ b/Documentation/oops-tracing.txt
@@ -1,6 +1,6 @@
NOTE: ksymoops is useless on 2.6. Please use the Oops in its original format
(from dmesg, etc). Ignore any references in this or other docs to "decoding
-the Oops" or "running it through ksymoops". If you post an Oops fron 2.6 that
+the Oops" or "running it through ksymoops". If you post an Oops from 2.6 that
has been run through ksymoops, people will just tell you to repost it.
Quick Summary
diff --git a/Documentation/power/video.txt b/Documentation/power/video.txt
index 526d6dd267ea..912bed87c758 100644
--- a/Documentation/power/video.txt
+++ b/Documentation/power/video.txt
@@ -11,9 +11,9 @@ boot video card. (Kernel usually does not even contain video card
driver -- vesafb and vgacon are widely used).
This is not problem for swsusp, because during swsusp resume, BIOS is
-run normally so video card is normally initialized. S3 has absolutely
-no chance of working with SMP/HT. Be sure it to turn it off before
-testing (swsusp should work ok, OTOH).
+run normally so video card is normally initialized. It should not be
+problem for S1 standby, because hardware should retain its state over
+that.
There are a few types of systems where video works after S3 resume:
@@ -64,7 +64,7 @@ your video card (good luck getting docs :-(). Maybe suspending from X
(proper X, knowing your hardware, not XF68_FBcon) might have better
chance of working.
-Table of known working systems:
+Table of known working notebooks:
Model hack (or "how to do it")
------------------------------------------------------------------------------
@@ -73,7 +73,7 @@ Acer TM 242FX vbetool (6)
Acer TM C110 video_post (8)
Acer TM C300 vga=normal (only suspend on console, not in X), vbetool (6) or video_post (8)
Acer TM 4052LCi s3_bios (2)
-Acer TM 636Lci s3_bios vga=normal (2)
+Acer TM 636Lci s3_bios,s3_mode (4)
Acer TM 650 (Radeon M7) vga=normal plus boot-radeon (5) gets text console back
Acer TM 660 ??? (*)
Acer TM 800 vga=normal, X patches, see webpage (5) or vbetool (6)
@@ -137,6 +137,13 @@ Toshiba Satellite P10-554 s3_bios,s3_mode (4)(****)
Toshiba M30 (2) xor X with nvidia driver using internal AGP
Uniwill 244IIO ??? (*)
+Known working desktop systems
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Mainboard Graphics card hack (or "how to do it")
+------------------------------------------------------------------------------
+Asus A7V8X nVidia RIVA TNT2 model 64 s3_bios,s3_mode (4)
+
(*) from http://www.ubuntulinux.org/wiki/HoaryPMResults, not sure
which options to use. If you know, please tell me.
diff --git a/Documentation/s390/Debugging390.txt b/Documentation/s390/Debugging390.txt
index adbfe620c061..844c03fe7921 100644
--- a/Documentation/s390/Debugging390.txt
+++ b/Documentation/s390/Debugging390.txt
@@ -871,7 +871,7 @@ by playing with the --adjust-vma parameter to objdump.
-extern inline void spin_lock(spinlock_t *lp)
+static inline void spin_lock(spinlock_t *lp)
{
a0: 18 34 lr %r3,%r4
a2: a7 3a 03 bc ahi %r3,956
diff --git a/Documentation/s390/driver-model.txt b/Documentation/s390/driver-model.txt
index 19461958e2bd..df09758bf3fe 100644
--- a/Documentation/s390/driver-model.txt
+++ b/Documentation/s390/driver-model.txt
@@ -8,11 +8,10 @@ All devices which can be addressed by means of ccws are called 'CCW devices' -
even if they aren't actually driven by ccws.
All ccw devices are accessed via a subchannel, this is reflected in the
-structures under root/:
+structures under devices/:
-root/
- - sys
- - legacy
+devices/
+ - system/
- css0/
- 0.0.0000/0.0.0815/
- 0.0.0001/0.0.4711/
@@ -36,7 +35,7 @@ availability: Can be 'good' or 'boxed'; 'no path' or 'no device' for
online: An interface to set the device online and offline.
In the special case of the device being disconnected (see the
- notify function under 1.2), piping 0 to online will focibly delete
+ notify function under 1.2), piping 0 to online will forcibly delete
the device.
The device drivers can add entries to export per-device data and interfaces.
@@ -222,7 +221,7 @@ and are called 'chp0.<chpid>'. They have no driver and do not belong to any bus.
Please note, that unlike /proc/chpids in 2.4, the channel path objects reflect
only the logical state and not the physical state, since we cannot track the
latter consistently due to lacking machine support (we don't need to be aware
-of anyway).
+of it anyway).
status - Can be 'online' or 'offline'.
Piping 'on' or 'off' sets the chpid logically online/offline.
@@ -235,12 +234,16 @@ status - Can be 'online' or 'offline'.
3. System devices
-----------------
-Note: cpus may yet be added here.
-
3.1 xpram
---------
-xpram shows up under sys/ as 'xpram'.
+xpram shows up under devices/system/ as 'xpram'.
+
+3.2 cpus
+--------
+
+For each cpu, a directory is created under devices/system/cpu/. Each cpu has an
+attribute 'online' which can be 0 or 1.
4. Other devices
diff --git a/Documentation/sched-arch.txt b/Documentation/sched-arch.txt
new file mode 100644
index 000000000000..941615a9769b
--- /dev/null
+++ b/Documentation/sched-arch.txt
@@ -0,0 +1,89 @@
+ CPU Scheduler implementation hints for architecture specific code
+
+ Nick Piggin, 2005
+
+Context switch
+==============
+1. Runqueue locking
+By default, the switch_to arch function is called with the runqueue
+locked. This is usually not a problem unless switch_to may need to
+take the runqueue lock. This is usually due to a wake up operation in
+the context switch. See include/asm-ia64/system.h for an example.
+
+To request the scheduler call switch_to with the runqueue unlocked,
+you must `#define __ARCH_WANT_UNLOCKED_CTXSW` in a header file
+(typically the one where switch_to is defined).
+
+Unlocked context switches introduce only a very minor performance
+penalty to the core scheduler implementation in the CONFIG_SMP case.
+
+2. Interrupt status
+By default, the switch_to arch function is called with interrupts
+disabled. Interrupts may be enabled over the call if it is likely to
+introduce a significant interrupt latency by adding the line
+`#define __ARCH_WANT_INTERRUPTS_ON_CTXSW` in the same place as for
+unlocked context switches. This define also implies
+`__ARCH_WANT_UNLOCKED_CTXSW`. See include/asm-arm/system.h for an
+example.
+
+
+CPU idle
+========
+Your cpu_idle routines need to obey the following rules:
+
+1. Preempt should now disabled over idle routines. Should only
+ be enabled to call schedule() then disabled again.
+
+2. need_resched/TIF_NEED_RESCHED is only ever set, and will never
+ be cleared until the running task has called schedule(). Idle
+ threads need only ever query need_resched, and may never set or
+ clear it.
+
+3. When cpu_idle finds (need_resched() == 'true'), it should call
+ schedule(). It should not call schedule() otherwise.
+
+4. The only time interrupts need to be disabled when checking
+ need_resched is if we are about to sleep the processor until
+ the next interrupt (this doesn't provide any protection of
+ need_resched, it prevents losing an interrupt).
+
+ 4a. Common problem with this type of sleep appears to be:
+ local_irq_disable();
+ if (!need_resched()) {
+ local_irq_enable();
+ *** resched interrupt arrives here ***
+ __asm__("sleep until next interrupt");
+ }
+
+5. TIF_POLLING_NRFLAG can be set by idle routines that do not
+ need an interrupt to wake them up when need_resched goes high.
+ In other words, they must be periodically polling need_resched,
+ although it may be reasonable to do some background work or enter
+ a low CPU priority.
+
+ 5a. If TIF_POLLING_NRFLAG is set, and we do decide to enter
+ an interrupt sleep, it needs to be cleared then a memory
+ barrier issued (followed by a test of need_resched with
+ interrupts disabled, as explained in 3).
+
+arch/i386/kernel/process.c has examples of both polling and
+sleeping idle functions.
+
+
+Possible arch/ problems
+=======================
+
+Possible arch problems I found (and either tried to fix or didn't):
+
+h8300 - Is such sleeping racy vs interrupts? (See #4a).
+ The H8/300 manual I found indicates yes, however disabling IRQs
+ over the sleep mean only NMIs can wake it up, so can't fix easily
+ without doing spin waiting.
+
+ia64 - is safe_halt call racy vs interrupts? (does it sleep?) (See #4a)
+
+sh64 - Is sleeping racy vs interrupts? (See #4a)
+
+sparc - IRQs on at this point(?), change local_irq_save to _disable.
+ - TODO: needs secondary CPUs to disable preempt (See #1)
+
diff --git a/Documentation/scsi/LICENSE.qla2xxx b/Documentation/scsi/LICENSE.qla2xxx
new file mode 100644
index 000000000000..9e15b4f9cd28
--- /dev/null
+++ b/Documentation/scsi/LICENSE.qla2xxx
@@ -0,0 +1,45 @@
+Copyright (c) 2003-2005 QLogic Corporation
+QLogic Linux Fibre Channel HBA Driver
+
+This program includes a device driver for Linux 2.6 that may be
+distributed with QLogic hardware specific firmware binary file.
+You may modify and redistribute the device driver code under the
+GNU General Public License as published by the Free Software
+Foundation (version 2 or a later version).
+
+You may redistribute the hardware specific firmware binary file
+under the following terms:
+
+ 1. Redistribution of source code (only if applicable),
+ must retain the above copyright notice, this list of
+ conditions and the following disclaimer.
+
+ 2. Redistribution in binary form must reproduce the above
+ copyright notice, this list of conditions and the
+ following disclaimer in the documentation and/or other
+ materials provided with the distribution.
+
+ 3. The name of QLogic Corporation may not be used to
+ endorse or promote products derived from this software
+ without specific prior written permission
+
+REGARDLESS OF WHAT LICENSING MECHANISM IS USED OR APPLICABLE,
+THIS PROGRAM IS PROVIDED BY QLOGIC CORPORATION "AS IS'' AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR
+BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+
+USER ACKNOWLEDGES AND AGREES THAT USE OF THIS PROGRAM WILL NOT
+CREATE OR GIVE GROUNDS FOR A LICENSE BY IMPLICATION, ESTOPPEL, OR
+OTHERWISE IN ANY INTELLECTUAL PROPERTY RIGHTS (PATENT, COPYRIGHT,
+TRADE SECRET, MASK WORK, OR OTHER PROPRIETARY RIGHT) EMBODIED IN
+ANY OTHER QLOGIC HARDWARE OR SOFTWARE EITHER SOLELY OR IN
+COMBINATION WITH THIS PROGRAM.
diff --git a/Documentation/serial/driver b/Documentation/serial/driver
index 87856d3cfb67..42ef9970bc86 100644
--- a/Documentation/serial/driver
+++ b/Documentation/serial/driver
@@ -116,12 +116,15 @@ hardware.
line becoming inactive or the tty layer indicating we want
to stop transmission due to an XOFF character.
+ The driver should stop transmitting characters as soon as
+ possible.
+
Locking: port->lock taken.
Interrupts: locally disabled.
This call must not sleep
start_tx(port)
- start transmitting characters.
+ Start transmitting characters.
Locking: port->lock taken.
Interrupts: locally disabled.
@@ -281,26 +284,31 @@ hardware.
Other functions
---------------
-uart_update_timeout(port,cflag,quot)
+uart_update_timeout(port,cflag,baud)
Update the FIFO drain timeout, port->timeout, according to the
- number of bits, parity, stop bits and quotient.
+ number of bits, parity, stop bits and baud rate.
Locking: caller is expected to take port->lock
Interrupts: n/a
-uart_get_baud_rate(port,termios)
+uart_get_baud_rate(port,termios,old,min,max)
Return the numeric baud rate for the specified termios, taking
account of the special 38400 baud "kludge". The B0 baud rate
is mapped to 9600 baud.
+ If the baud rate is not within min..max, then if old is non-NULL,
+ the original baud rate will be tried. If that exceeds the
+ min..max constraint, 9600 baud will be returned. termios will
+ be updated to the baud rate in use.
+
+ Note: min..max must always allow 9600 baud to be selected.
+
Locking: caller dependent.
Interrupts: n/a
-uart_get_divisor(port,termios,oldtermios)
- Return the divsor (baud_base / baud) for the selected baud rate
- specified by termios. If the baud rate is out of range, try
- the original baud rate specified by oldtermios (if non-NULL).
- If that fails, try 9600 baud.
+uart_get_divisor(port,baud)
+ Return the divsor (baud_base / baud) for the specified baud
+ rate, appropriately rounded.
If 38400 baud and custom divisor is selected, return the
custom divisor instead.
@@ -308,6 +316,46 @@ uart_get_divisor(port,termios,oldtermios)
Locking: caller dependent.
Interrupts: n/a
+uart_match_port(port1,port2)
+ This utility function can be used to determine whether two
+ uart_port structures describe the same port.
+
+ Locking: n/a
+ Interrupts: n/a
+
+uart_write_wakeup(port)
+ A driver is expected to call this function when the number of
+ characters in the transmit buffer have dropped below a threshold.
+
+ Locking: port->lock should be held.
+ Interrupts: n/a
+
+uart_register_driver(drv)
+ Register a uart driver with the core driver. We in turn register
+ with the tty layer, and initialise the core driver per-port state.
+
+ drv->port should be NULL, and the per-port structures should be
+ registered using uart_add_one_port after this call has succeeded.
+
+ Locking: none
+ Interrupts: enabled
+
+uart_unregister_driver()
+ Remove all references to a driver from the core driver. The low
+ level driver must have removed all its ports via the
+ uart_remove_one_port() if it registered them with uart_add_one_port().
+
+ Locking: none
+ Interrupts: enabled
+
+uart_suspend_port()
+
+uart_resume_port()
+
+uart_add_one_port()
+
+uart_remove_one_port()
+
Other notes
-----------
diff --git a/Documentation/sharedsubtree.txt b/Documentation/sharedsubtree.txt
new file mode 100644
index 000000000000..2d8f403eb6eb
--- /dev/null
+++ b/Documentation/sharedsubtree.txt
@@ -0,0 +1,1060 @@
+Shared Subtrees
+---------------
+
+Contents:
+ 1) Overview
+ 2) Features
+ 3) smount command
+ 4) Use-case
+ 5) Detailed semantics
+ 6) Quiz
+ 7) FAQ
+ 8) Implementation
+
+
+1) Overview
+-----------
+
+Consider the following situation:
+
+A process wants to clone its own namespace, but still wants to access the CD
+that got mounted recently. Shared subtree semantics provide the necessary
+mechanism to accomplish the above.
+
+It provides the necessary building blocks for features like per-user-namespace
+and versioned filesystem.
+
+2) Features
+-----------
+
+Shared subtree provides four different flavors of mounts; struct vfsmount to be
+precise
+
+ a. shared mount
+ b. slave mount
+ c. private mount
+ d. unbindable mount
+
+
+2a) A shared mount can be replicated to as many mountpoints and all the
+replicas continue to be exactly same.
+
+ Here is an example:
+
+ Lets say /mnt has a mount that is shared.
+ mount --make-shared /mnt
+
+ note: mount command does not yet support the --make-shared flag.
+ I have included a small C program which does the same by executing
+ 'smount /mnt shared'
+
+ #mount --bind /mnt /tmp
+ The above command replicates the mount at /mnt to the mountpoint /tmp
+ and the contents of both the mounts remain identical.
+
+ #ls /mnt
+ a b c
+
+ #ls /tmp
+ a b c
+
+ Now lets say we mount a device at /tmp/a
+ #mount /dev/sd0 /tmp/a
+
+ #ls /tmp/a
+ t1 t2 t2
+
+ #ls /mnt/a
+ t1 t2 t2
+
+ Note that the mount has propagated to the mount at /mnt as well.
+
+ And the same is true even when /dev/sd0 is mounted on /mnt/a. The
+ contents will be visible under /tmp/a too.
+
+
+2b) A slave mount is like a shared mount except that mount and umount events
+ only propagate towards it.
+
+ All slave mounts have a master mount which is a shared.
+
+ Here is an example:
+
+ Lets say /mnt has a mount which is shared.
+ #mount --make-shared /mnt
+
+ Lets bind mount /mnt to /tmp
+ #mount --bind /mnt /tmp
+
+ the new mount at /tmp becomes a shared mount and it is a replica of
+ the mount at /mnt.
+
+ Now lets make the mount at /tmp; a slave of /mnt
+ #mount --make-slave /tmp
+ [or smount /tmp slave]
+
+ lets mount /dev/sd0 on /mnt/a
+ #mount /dev/sd0 /mnt/a
+
+ #ls /mnt/a
+ t1 t2 t3
+
+ #ls /tmp/a
+ t1 t2 t3
+
+ Note the mount event has propagated to the mount at /tmp
+
+ However lets see what happens if we mount something on the mount at /tmp
+
+ #mount /dev/sd1 /tmp/b
+
+ #ls /tmp/b
+ s1 s2 s3
+
+ #ls /mnt/b
+
+ Note how the mount event has not propagated to the mount at
+ /mnt
+
+
+2c) A private mount does not forward or receive propagation.
+
+ This is the mount we are familiar with. Its the default type.
+
+
+2d) A unbindable mount is a unbindable private mount
+
+ lets say we have a mount at /mnt and we make is unbindable
+
+ #mount --make-unbindable /mnt
+ [ smount /mnt unbindable ]
+
+ Lets try to bind mount this mount somewhere else.
+ # mount --bind /mnt /tmp
+ mount: wrong fs type, bad option, bad superblock on /mnt,
+ or too many mounted file systems
+
+ Binding a unbindable mount is a invalid operation.
+
+
+3) smount command
+
+ Currently the mount command is not aware of shared subtree features.
+ Work is in progress to add the support in mount ( util-linux package ).
+ Till then use the following program.
+
+ ------------------------------------------------------------------------
+ //
+ //this code was developed my Miklos Szeredi <miklos@szeredi.hu>
+ //and modified by Ram Pai <linuxram@us.ibm.com>
+ // sample usage:
+ // smount /tmp shared
+ //
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <unistd.h>
+ #include <sys/mount.h>
+ #include <sys/fsuid.h>
+
+ #ifndef MS_REC
+ #define MS_REC 0x4000 /* 16384: Recursive loopback */
+ #endif
+
+ #ifndef MS_SHARED
+ #define MS_SHARED 1<<20 /* Shared */
+ #endif
+
+ #ifndef MS_PRIVATE
+ #define MS_PRIVATE 1<<18 /* Private */
+ #endif
+
+ #ifndef MS_SLAVE
+ #define MS_SLAVE 1<<19 /* Slave */
+ #endif
+
+ #ifndef MS_UNBINDABLE
+ #define MS_UNBINDABLE 1<<17 /* Unbindable */
+ #endif
+
+ int main(int argc, char *argv[])
+ {
+ int type;
+ if(argc != 3) {
+ fprintf(stderr, "usage: %s dir "
+ "<rshared|rslave|rprivate|runbindable|shared|slave"
+ "|private|unbindable>\n" , argv[0]);
+ return 1;
+ }
+
+ fprintf(stdout, "%s %s %s\n", argv[0], argv[1], argv[2]);
+
+ if (strcmp(argv[2],"rshared")==0)
+ type=(MS_SHARED|MS_REC);
+ else if (strcmp(argv[2],"rslave")==0)
+ type=(MS_SLAVE|MS_REC);
+ else if (strcmp(argv[2],"rprivate")==0)
+ type=(MS_PRIVATE|MS_REC);
+ else if (strcmp(argv[2],"runbindable")==0)
+ type=(MS_UNBINDABLE|MS_REC);
+ else if (strcmp(argv[2],"shared")==0)
+ type=MS_SHARED;
+ else if (strcmp(argv[2],"slave")==0)
+ type=MS_SLAVE;
+ else if (strcmp(argv[2],"private")==0)
+ type=MS_PRIVATE;
+ else if (strcmp(argv[2],"unbindable")==0)
+ type=MS_UNBINDABLE;
+ else {
+ fprintf(stderr, "invalid operation: %s\n", argv[2]);
+ return 1;
+ }
+ setfsuid(getuid());
+
+ if(mount("", argv[1], "dontcare", type, "") == -1) {
+ perror("mount");
+ return 1;
+ }
+ return 0;
+ }
+ -----------------------------------------------------------------------
+
+ Copy the above code snippet into smount.c
+ gcc -o smount smount.c
+
+
+ (i) To mark all the mounts under /mnt as shared execute the following
+ command:
+
+ smount /mnt rshared
+ the corresponding syntax planned for mount command is
+ mount --make-rshared /mnt
+
+ just to mark a mount /mnt as shared, execute the following
+ command:
+ smount /mnt shared
+ the corresponding syntax planned for mount command is
+ mount --make-shared /mnt
+
+ (ii) To mark all the shared mounts under /mnt as slave execute the
+ following
+
+ command:
+ smount /mnt rslave
+ the corresponding syntax planned for mount command is
+ mount --make-rslave /mnt
+
+ just to mark a mount /mnt as slave, execute the following
+ command:
+ smount /mnt slave
+ the corresponding syntax planned for mount command is
+ mount --make-slave /mnt
+
+ (iii) To mark all the mounts under /mnt as private execute the
+ following command:
+
+ smount /mnt rprivate
+ the corresponding syntax planned for mount command is
+ mount --make-rprivate /mnt
+
+ just to mark a mount /mnt as private, execute the following
+ command:
+ smount /mnt private
+ the corresponding syntax planned for mount command is
+ mount --make-private /mnt
+
+ NOTE: by default all the mounts are created as private. But if
+ you want to change some shared/slave/unbindable mount as
+ private at a later point in time, this command can help.
+
+ (iv) To mark all the mounts under /mnt as unbindable execute the
+ following
+
+ command:
+ smount /mnt runbindable
+ the corresponding syntax planned for mount command is
+ mount --make-runbindable /mnt
+
+ just to mark a mount /mnt as unbindable, execute the following
+ command:
+ smount /mnt unbindable
+ the corresponding syntax planned for mount command is
+ mount --make-unbindable /mnt
+
+
+4) Use cases
+------------
+
+ A) A process wants to clone its own namespace, but still wants to
+ access the CD that got mounted recently.
+
+ Solution:
+
+ The system administrator can make the mount at /cdrom shared
+ mount --bind /cdrom /cdrom
+ mount --make-shared /cdrom
+
+ Now any process that clones off a new namespace will have a
+ mount at /cdrom which is a replica of the same mount in the
+ parent namespace.
+
+ So when a CD is inserted and mounted at /cdrom that mount gets
+ propagated to the other mount at /cdrom in all the other clone
+ namespaces.
+
+ B) A process wants its mounts invisible to any other process, but
+ still be able to see the other system mounts.
+
+ Solution:
+
+ To begin with, the administrator can mark the entire mount tree
+ as shareable.
+
+ mount --make-rshared /
+
+ A new process can clone off a new namespace. And mark some part
+ of its namespace as slave
+
+ mount --make-rslave /myprivatetree
+
+ Hence forth any mounts within the /myprivatetree done by the
+ process will not show up in any other namespace. However mounts
+ done in the parent namespace under /myprivatetree still shows
+ up in the process's namespace.
+
+
+ Apart from the above semantics this feature provides the
+ building blocks to solve the following problems:
+
+ C) Per-user namespace
+
+ The above semantics allows a way to share mounts across
+ namespaces. But namespaces are associated with processes. If
+ namespaces are made first class objects with user API to
+ associate/disassociate a namespace with userid, then each user
+ could have his/her own namespace and tailor it to his/her
+ requirements. Offcourse its needs support from PAM.
+
+ D) Versioned files
+
+ If the entire mount tree is visible at multiple locations, then
+ a underlying versioning file system can return different
+ version of the file depending on the path used to access that
+ file.
+
+ An example is:
+
+ mount --make-shared /
+ mount --rbind / /view/v1
+ mount --rbind / /view/v2
+ mount --rbind / /view/v3
+ mount --rbind / /view/v4
+
+ and if /usr has a versioning filesystem mounted, than that
+ mount appears at /view/v1/usr, /view/v2/usr, /view/v3/usr and
+ /view/v4/usr too
+
+ A user can request v3 version of the file /usr/fs/namespace.c
+ by accessing /view/v3/usr/fs/namespace.c . The underlying
+ versioning filesystem can then decipher that v3 version of the
+ filesystem is being requested and return the corresponding
+ inode.
+
+5) Detailed semantics:
+-------------------
+ The section below explains the detailed semantics of
+ bind, rbind, move, mount, umount and clone-namespace operations.
+
+ Note: the word 'vfsmount' and the noun 'mount' have been used
+ to mean the same thing, throughout this document.
+
+5a) Mount states
+
+ A given mount can be in one of the following states
+ 1) shared
+ 2) slave
+ 3) shared and slave
+ 4) private
+ 5) unbindable
+
+ A 'propagation event' is defined as event generated on a vfsmount
+ that leads to mount or unmount actions in other vfsmounts.
+
+ A 'peer group' is defined as a group of vfsmounts that propagate
+ events to each other.
+
+ (1) Shared mounts
+
+ A 'shared mount' is defined as a vfsmount that belongs to a
+ 'peer group'.
+
+ For example:
+ mount --make-shared /mnt
+ mount --bin /mnt /tmp
+
+ The mount at /mnt and that at /tmp are both shared and belong
+ to the same peer group. Anything mounted or unmounted under
+ /mnt or /tmp reflect in all the other mounts of its peer
+ group.
+
+
+ (2) Slave mounts
+
+ A 'slave mount' is defined as a vfsmount that receives
+ propagation events and does not forward propagation events.
+
+ A slave mount as the name implies has a master mount from which
+ mount/unmount events are received. Events do not propagate from
+ the slave mount to the master. Only a shared mount can be made
+ a slave by executing the following command
+
+ mount --make-slave mount
+
+ A shared mount that is made as a slave is no more shared unless
+ modified to become shared.
+
+ (3) Shared and Slave
+
+ A vfsmount can be both shared as well as slave. This state
+ indicates that the mount is a slave of some vfsmount, and
+ has its own peer group too. This vfsmount receives propagation
+ events from its master vfsmount, and also forwards propagation
+ events to its 'peer group' and to its slave vfsmounts.
+
+ Strictly speaking, the vfsmount is shared having its own
+ peer group, and this peer-group is a slave of some other
+ peer group.
+
+ Only a slave vfsmount can be made as 'shared and slave' by
+ either executing the following command
+ mount --make-shared mount
+ or by moving the slave vfsmount under a shared vfsmount.
+
+ (4) Private mount
+
+ A 'private mount' is defined as vfsmount that does not
+ receive or forward any propagation events.
+
+ (5) Unbindable mount
+
+ A 'unbindable mount' is defined as vfsmount that does not
+ receive or forward any propagation events and cannot
+ be bind mounted.
+
+
+ State diagram:
+ The state diagram below explains the state transition of a mount,
+ in response to various commands.
+ ------------------------------------------------------------------------
+ | |make-shared | make-slave | make-private |make-unbindab|
+ --------------|------------|--------------|--------------|-------------|
+ |shared |shared |*slave/private| private | unbindable |
+ | | | | | |
+ |-------------|------------|--------------|--------------|-------------|
+ |slave |shared | **slave | private | unbindable |
+ | |and slave | | | |
+ |-------------|------------|--------------|--------------|-------------|
+ |shared |shared | slave | private | unbindable |
+ |and slave |and slave | | | |
+ |-------------|------------|--------------|--------------|-------------|
+ |private |shared | **private | private | unbindable |
+ |-------------|------------|--------------|--------------|-------------|
+ |unbindable |shared |**unbindable | private | unbindable |
+ ------------------------------------------------------------------------
+
+ * if the shared mount is the only mount in its peer group, making it
+ slave, makes it private automatically. Note that there is no master to
+ which it can be slaved to.
+
+ ** slaving a non-shared mount has no effect on the mount.
+
+ Apart from the commands listed below, the 'move' operation also changes
+ the state of a mount depending on type of the destination mount. Its
+ explained in section 5d.
+
+5b) Bind semantics
+
+ Consider the following command
+
+ mount --bind A/a B/b
+
+ where 'A' is the source mount, 'a' is the dentry in the mount 'A', 'B'
+ is the destination mount and 'b' is the dentry in the destination mount.
+
+ The outcome depends on the type of mount of 'A' and 'B'. The table
+ below contains quick reference.
+ ---------------------------------------------------------------------------
+ | BIND MOUNT OPERATION |
+ |**************************************************************************
+ |source(A)->| shared | private | slave | unbindable |
+ | dest(B) | | | | |
+ | | | | | | |
+ | v | | | | |
+ |**************************************************************************
+ | shared | shared | shared | shared & slave | invalid |
+ | | | | | |
+ |non-shared| shared | private | slave | invalid |
+ ***************************************************************************
+
+ Details:
+
+ 1. 'A' is a shared mount and 'B' is a shared mount. A new mount 'C'
+ which is clone of 'A', is created. Its root dentry is 'a' . 'C' is
+ mounted on mount 'B' at dentry 'b'. Also new mount 'C1', 'C2', 'C3' ...
+ are created and mounted at the dentry 'b' on all mounts where 'B'
+ propagates to. A new propagation tree containing 'C1',..,'Cn' is
+ created. This propagation tree is identical to the propagation tree of
+ 'B'. And finally the peer-group of 'C' is merged with the peer group
+ of 'A'.
+
+ 2. 'A' is a private mount and 'B' is a shared mount. A new mount 'C'
+ which is clone of 'A', is created. Its root dentry is 'a'. 'C' is
+ mounted on mount 'B' at dentry 'b'. Also new mount 'C1', 'C2', 'C3' ...
+ are created and mounted at the dentry 'b' on all mounts where 'B'
+ propagates to. A new propagation tree is set containing all new mounts
+ 'C', 'C1', .., 'Cn' with exactly the same configuration as the
+ propagation tree for 'B'.
+
+ 3. 'A' is a slave mount of mount 'Z' and 'B' is a shared mount. A new
+ mount 'C' which is clone of 'A', is created. Its root dentry is 'a' .
+ 'C' is mounted on mount 'B' at dentry 'b'. Also new mounts 'C1', 'C2',
+ 'C3' ... are created and mounted at the dentry 'b' on all mounts where
+ 'B' propagates to. A new propagation tree containing the new mounts
+ 'C','C1',.. 'Cn' is created. This propagation tree is identical to the
+ propagation tree for 'B'. And finally the mount 'C' and its peer group
+ is made the slave of mount 'Z'. In other words, mount 'C' is in the
+ state 'slave and shared'.
+
+ 4. 'A' is a unbindable mount and 'B' is a shared mount. This is a
+ invalid operation.
+
+ 5. 'A' is a private mount and 'B' is a non-shared(private or slave or
+ unbindable) mount. A new mount 'C' which is clone of 'A', is created.
+ Its root dentry is 'a'. 'C' is mounted on mount 'B' at dentry 'b'.
+
+ 6. 'A' is a shared mount and 'B' is a non-shared mount. A new mount 'C'
+ which is a clone of 'A' is created. Its root dentry is 'a'. 'C' is
+ mounted on mount 'B' at dentry 'b'. 'C' is made a member of the
+ peer-group of 'A'.
+
+ 7. 'A' is a slave mount of mount 'Z' and 'B' is a non-shared mount. A
+ new mount 'C' which is a clone of 'A' is created. Its root dentry is
+ 'a'. 'C' is mounted on mount 'B' at dentry 'b'. Also 'C' is set as a
+ slave mount of 'Z'. In other words 'A' and 'C' are both slave mounts of
+ 'Z'. All mount/unmount events on 'Z' propagates to 'A' and 'C'. But
+ mount/unmount on 'A' do not propagate anywhere else. Similarly
+ mount/unmount on 'C' do not propagate anywhere else.
+
+ 8. 'A' is a unbindable mount and 'B' is a non-shared mount. This is a
+ invalid operation. A unbindable mount cannot be bind mounted.
+
+5c) Rbind semantics
+
+ rbind is same as bind. Bind replicates the specified mount. Rbind
+ replicates all the mounts in the tree belonging to the specified mount.
+ Rbind mount is bind mount applied to all the mounts in the tree.
+
+ If the source tree that is rbind has some unbindable mounts,
+ then the subtree under the unbindable mount is pruned in the new
+ location.
+
+ eg: lets say we have the following mount tree.
+
+ A
+ / \
+ B C
+ / \ / \
+ D E F G
+
+ Lets say all the mount except the mount C in the tree are
+ of a type other than unbindable.
+
+ If this tree is rbound to say Z
+
+ We will have the following tree at the new location.
+
+ Z
+ |
+ A'
+ /
+ B' Note how the tree under C is pruned
+ / \ in the new location.
+ D' E'
+
+
+
+5d) Move semantics
+
+ Consider the following command
+
+ mount --move A B/b
+
+ where 'A' is the source mount, 'B' is the destination mount and 'b' is
+ the dentry in the destination mount.
+
+ The outcome depends on the type of the mount of 'A' and 'B'. The table
+ below is a quick reference.
+ ---------------------------------------------------------------------------
+ | MOVE MOUNT OPERATION |
+ |**************************************************************************
+ | source(A)->| shared | private | slave | unbindable |
+ | dest(B) | | | | |
+ | | | | | | |
+ | v | | | | |
+ |**************************************************************************
+ | shared | shared | shared |shared and slave| invalid |
+ | | | | | |
+ |non-shared| shared | private | slave | unbindable |
+ ***************************************************************************
+ NOTE: moving a mount residing under a shared mount is invalid.
+
+ Details follow:
+
+ 1. 'A' is a shared mount and 'B' is a shared mount. The mount 'A' is
+ mounted on mount 'B' at dentry 'b'. Also new mounts 'A1', 'A2'...'An'
+ are created and mounted at dentry 'b' on all mounts that receive
+ propagation from mount 'B'. A new propagation tree is created in the
+ exact same configuration as that of 'B'. This new propagation tree
+ contains all the new mounts 'A1', 'A2'... 'An'. And this new
+ propagation tree is appended to the already existing propagation tree
+ of 'A'.
+
+ 2. 'A' is a private mount and 'B' is a shared mount. The mount 'A' is
+ mounted on mount 'B' at dentry 'b'. Also new mount 'A1', 'A2'... 'An'
+ are created and mounted at dentry 'b' on all mounts that receive
+ propagation from mount 'B'. The mount 'A' becomes a shared mount and a
+ propagation tree is created which is identical to that of
+ 'B'. This new propagation tree contains all the new mounts 'A1',
+ 'A2'... 'An'.
+
+ 3. 'A' is a slave mount of mount 'Z' and 'B' is a shared mount. The
+ mount 'A' is mounted on mount 'B' at dentry 'b'. Also new mounts 'A1',
+ 'A2'... 'An' are created and mounted at dentry 'b' on all mounts that
+ receive propagation from mount 'B'. A new propagation tree is created
+ in the exact same configuration as that of 'B'. This new propagation
+ tree contains all the new mounts 'A1', 'A2'... 'An'. And this new
+ propagation tree is appended to the already existing propagation tree of
+ 'A'. Mount 'A' continues to be the slave mount of 'Z' but it also
+ becomes 'shared'.
+
+ 4. 'A' is a unbindable mount and 'B' is a shared mount. The operation
+ is invalid. Because mounting anything on the shared mount 'B' can
+ create new mounts that get mounted on the mounts that receive
+ propagation from 'B'. And since the mount 'A' is unbindable, cloning
+ it to mount at other mountpoints is not possible.
+
+ 5. 'A' is a private mount and 'B' is a non-shared(private or slave or
+ unbindable) mount. The mount 'A' is mounted on mount 'B' at dentry 'b'.
+
+ 6. 'A' is a shared mount and 'B' is a non-shared mount. The mount 'A'
+ is mounted on mount 'B' at dentry 'b'. Mount 'A' continues to be a
+ shared mount.
+
+ 7. 'A' is a slave mount of mount 'Z' and 'B' is a non-shared mount.
+ The mount 'A' is mounted on mount 'B' at dentry 'b'. Mount 'A'
+ continues to be a slave mount of mount 'Z'.
+
+ 8. 'A' is a unbindable mount and 'B' is a non-shared mount. The mount
+ 'A' is mounted on mount 'B' at dentry 'b'. Mount 'A' continues to be a
+ unbindable mount.
+
+5e) Mount semantics
+
+ Consider the following command
+
+ mount device B/b
+
+ 'B' is the destination mount and 'b' is the dentry in the destination
+ mount.
+
+ The above operation is the same as bind operation with the exception
+ that the source mount is always a private mount.
+
+
+5f) Unmount semantics
+
+ Consider the following command
+
+ umount A
+
+ where 'A' is a mount mounted on mount 'B' at dentry 'b'.
+
+ If mount 'B' is shared, then all most-recently-mounted mounts at dentry
+ 'b' on mounts that receive propagation from mount 'B' and does not have
+ sub-mounts within them are unmounted.
+
+ Example: Lets say 'B1', 'B2', 'B3' are shared mounts that propagate to
+ each other.
+
+ lets say 'A1', 'A2', 'A3' are first mounted at dentry 'b' on mount
+ 'B1', 'B2' and 'B3' respectively.
+
+ lets say 'C1', 'C2', 'C3' are next mounted at the same dentry 'b' on
+ mount 'B1', 'B2' and 'B3' respectively.
+
+ if 'C1' is unmounted, all the mounts that are most-recently-mounted on
+ 'B1' and on the mounts that 'B1' propagates-to are unmounted.
+
+ 'B1' propagates to 'B2' and 'B3'. And the most recently mounted mount
+ on 'B2' at dentry 'b' is 'C2', and that of mount 'B3' is 'C3'.
+
+ So all 'C1', 'C2' and 'C3' should be unmounted.
+
+ If any of 'C2' or 'C3' has some child mounts, then that mount is not
+ unmounted, but all other mounts are unmounted. However if 'C1' is told
+ to be unmounted and 'C1' has some sub-mounts, the umount operation is
+ failed entirely.
+
+5g) Clone Namespace
+
+ A cloned namespace contains all the mounts as that of the parent
+ namespace.
+
+ Lets say 'A' and 'B' are the corresponding mounts in the parent and the
+ child namespace.
+
+ If 'A' is shared, then 'B' is also shared and 'A' and 'B' propagate to
+ each other.
+
+ If 'A' is a slave mount of 'Z', then 'B' is also the slave mount of
+ 'Z'.
+
+ If 'A' is a private mount, then 'B' is a private mount too.
+
+ If 'A' is unbindable mount, then 'B' is a unbindable mount too.
+
+
+6) Quiz
+
+ A. What is the result of the following command sequence?
+
+ mount --bind /mnt /mnt
+ mount --make-shared /mnt
+ mount --bind /mnt /tmp
+ mount --move /tmp /mnt/1
+
+ what should be the contents of /mnt /mnt/1 /mnt/1/1 should be?
+ Should they all be identical? or should /mnt and /mnt/1 be
+ identical only?
+
+
+ B. What is the result of the following command sequence?
+
+ mount --make-rshared /
+ mkdir -p /v/1
+ mount --rbind / /v/1
+
+ what should be the content of /v/1/v/1 be?
+
+
+ C. What is the result of the following command sequence?
+
+ mount --bind /mnt /mnt
+ mount --make-shared /mnt
+ mkdir -p /mnt/1/2/3 /mnt/1/test
+ mount --bind /mnt/1 /tmp
+ mount --make-slave /mnt
+ mount --make-shared /mnt
+ mount --bind /mnt/1/2 /tmp1
+ mount --make-slave /mnt
+
+ At this point we have the first mount at /tmp and
+ its root dentry is 1. Lets call this mount 'A'
+ And then we have a second mount at /tmp1 with root
+ dentry 2. Lets call this mount 'B'
+ Next we have a third mount at /mnt with root dentry
+ mnt. Lets call this mount 'C'
+
+ 'B' is the slave of 'A' and 'C' is a slave of 'B'
+ A -> B -> C
+
+ at this point if we execute the following command
+
+ mount --bind /bin /tmp/test
+
+ The mount is attempted on 'A'
+
+ will the mount propagate to 'B' and 'C' ?
+
+ what would be the contents of
+ /mnt/1/test be?
+
+7) FAQ
+
+ Q1. Why is bind mount needed? How is it different from symbolic links?
+ symbolic links can get stale if the destination mount gets
+ unmounted or moved. Bind mounts continue to exist even if the
+ other mount is unmounted or moved.
+
+ Q2. Why can't the shared subtree be implemented using exportfs?
+
+ exportfs is a heavyweight way of accomplishing part of what
+ shared subtree can do. I cannot imagine a way to implement the
+ semantics of slave mount using exportfs?
+
+ Q3 Why is unbindable mount needed?
+
+ Lets say we want to replicate the mount tree at multiple
+ locations within the same subtree.
+
+ if one rbind mounts a tree within the same subtree 'n' times
+ the number of mounts created is an exponential function of 'n'.
+ Having unbindable mount can help prune the unneeded bind
+ mounts. Here is a example.
+
+ step 1:
+ lets say the root tree has just two directories with
+ one vfsmount.
+ root
+ / \
+ tmp usr
+
+ And we want to replicate the tree at multiple
+ mountpoints under /root/tmp
+
+ step2:
+ mount --make-shared /root
+
+ mkdir -p /tmp/m1
+
+ mount --rbind /root /tmp/m1
+
+ the new tree now looks like this:
+
+ root
+ / \
+ tmp usr
+ /
+ m1
+ / \
+ tmp usr
+ /
+ m1
+
+ it has two vfsmounts
+
+ step3:
+ mkdir -p /tmp/m2
+ mount --rbind /root /tmp/m2
+
+ the new tree now looks like this:
+
+ root
+ / \
+ tmp usr
+ / \
+ m1 m2
+ / \ / \
+ tmp usr tmp usr
+ / \ /
+ m1 m2 m1
+ / \ / \
+ tmp usr tmp usr
+ / / \
+ m1 m1 m2
+ / \
+ tmp usr
+ / \
+ m1 m2
+
+ it has 6 vfsmounts
+
+ step 4:
+ mkdir -p /tmp/m3
+ mount --rbind /root /tmp/m3
+
+ I wont' draw the tree..but it has 24 vfsmounts
+
+
+ at step i the number of vfsmounts is V[i] = i*V[i-1].
+ This is an exponential function. And this tree has way more
+ mounts than what we really needed in the first place.
+
+ One could use a series of umount at each step to prune
+ out the unneeded mounts. But there is a better solution.
+ Unclonable mounts come in handy here.
+
+ step 1:
+ lets say the root tree has just two directories with
+ one vfsmount.
+ root
+ / \
+ tmp usr
+
+ How do we set up the same tree at multiple locations under
+ /root/tmp
+
+ step2:
+ mount --bind /root/tmp /root/tmp
+
+ mount --make-rshared /root
+ mount --make-unbindable /root/tmp
+
+ mkdir -p /tmp/m1
+
+ mount --rbind /root /tmp/m1
+
+ the new tree now looks like this:
+
+ root
+ / \
+ tmp usr
+ /
+ m1
+ / \
+ tmp usr
+
+ step3:
+ mkdir -p /tmp/m2
+ mount --rbind /root /tmp/m2
+
+ the new tree now looks like this:
+
+ root
+ / \
+ tmp usr
+ / \
+ m1 m2
+ / \ / \
+ tmp usr tmp usr
+
+ step4:
+
+ mkdir -p /tmp/m3
+ mount --rbind /root /tmp/m3
+
+ the new tree now looks like this:
+
+ root
+ / \
+ tmp usr
+ / \ \
+ m1 m2 m3
+ / \ / \ / \
+ tmp usr tmp usr tmp usr
+
+8) Implementation
+
+8A) Datastructure
+
+ 4 new fields are introduced to struct vfsmount
+ ->mnt_share
+ ->mnt_slave_list
+ ->mnt_slave
+ ->mnt_master
+
+ ->mnt_share links togather all the mount to/from which this vfsmount
+ send/receives propagation events.
+
+ ->mnt_slave_list links all the mounts to which this vfsmount propagates
+ to.
+
+ ->mnt_slave links togather all the slaves that its master vfsmount
+ propagates to.
+
+ ->mnt_master points to the master vfsmount from which this vfsmount
+ receives propagation.
+
+ ->mnt_flags takes two more flags to indicate the propagation status of
+ the vfsmount. MNT_SHARE indicates that the vfsmount is a shared
+ vfsmount. MNT_UNCLONABLE indicates that the vfsmount cannot be
+ replicated.
+
+ All the shared vfsmounts in a peer group form a cyclic list through
+ ->mnt_share.
+
+ All vfsmounts with the same ->mnt_master form on a cyclic list anchored
+ in ->mnt_master->mnt_slave_list and going through ->mnt_slave.
+
+ ->mnt_master can point to arbitrary (and possibly different) members
+ of master peer group. To find all immediate slaves of a peer group
+ you need to go through _all_ ->mnt_slave_list of its members.
+ Conceptually it's just a single set - distribution among the
+ individual lists does not affect propagation or the way propagation
+ tree is modified by operations.
+
+ A example propagation tree looks as shown in the figure below.
+ [ NOTE: Though it looks like a forest, if we consider all the shared
+ mounts as a conceptual entity called 'pnode', it becomes a tree]
+
+
+ A <--> B <--> C <---> D
+ /|\ /| |\
+ / F G J K H I
+ /
+ E<-->K
+ /|\
+ M L N
+
+ In the above figure A,B,C and D all are shared and propagate to each
+ other. 'A' has got 3 slave mounts 'E' 'F' and 'G' 'C' has got 2 slave
+ mounts 'J' and 'K' and 'D' has got two slave mounts 'H' and 'I'.
+ 'E' is also shared with 'K' and they propagate to each other. And
+ 'K' has 3 slaves 'M', 'L' and 'N'
+
+ A's ->mnt_share links with the ->mnt_share of 'B' 'C' and 'D'
+
+ A's ->mnt_slave_list links with ->mnt_slave of 'E', 'K', 'F' and 'G'
+
+ E's ->mnt_share links with ->mnt_share of K
+ 'E', 'K', 'F', 'G' have their ->mnt_master point to struct
+ vfsmount of 'A'
+ 'M', 'L', 'N' have their ->mnt_master point to struct vfsmount of 'K'
+ K's ->mnt_slave_list links with ->mnt_slave of 'M', 'L' and 'N'
+
+ C's ->mnt_slave_list links with ->mnt_slave of 'J' and 'K'
+ J and K's ->mnt_master points to struct vfsmount of C
+ and finally D's ->mnt_slave_list links with ->mnt_slave of 'H' and 'I'
+ 'H' and 'I' have their ->mnt_master pointing to struct vfsmount of 'D'.
+
+
+ NOTE: The propagation tree is orthogonal to the mount tree.
+
+
+8B Algorithm:
+
+ The crux of the implementation resides in rbind/move operation.
+
+ The overall algorithm breaks the operation into 3 phases: (look at
+ attach_recursive_mnt() and propagate_mnt())
+
+ 1. prepare phase.
+ 2. commit phases.
+ 3. abort phases.
+
+ Prepare phase:
+
+ for each mount in the source tree:
+ a) Create the necessary number of mount trees to
+ be attached to each of the mounts that receive
+ propagation from the destination mount.
+ b) Do not attach any of the trees to its destination.
+ However note down its ->mnt_parent and ->mnt_mountpoint
+ c) Link all the new mounts to form a propagation tree that
+ is identical to the propagation tree of the destination
+ mount.
+
+ If this phase is successful, there should be 'n' new
+ propagation trees; where 'n' is the number of mounts in the
+ source tree. Go to the commit phase
+
+ Also there should be 'm' new mount trees, where 'm' is
+ the number of mounts to which the destination mount
+ propagates to.
+
+ if any memory allocations fail, go to the abort phase.
+
+ Commit phase
+ attach each of the mount trees to their corresponding
+ destination mounts.
+
+ Abort phase
+ delete all the newly created trees.
+
+ NOTE: all the propagation related functionality resides in the file
+ pnode.c
+
+
+------------------------------------------------------------------------
+
+version 0.1 (created the initial document, Ram Pai linuxram@us.ibm.com)
+version 0.2 (Incorporated comments from Al Viro)
diff --git a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt
index 13cba955cb5a..2f27f391c7cc 100644
--- a/Documentation/sound/alsa/ALSA-Configuration.txt
+++ b/Documentation/sound/alsa/ALSA-Configuration.txt
@@ -167,7 +167,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
spdif - Support SPDIF I/O
- Default: disabled
- Module supports autoprobe and multiple chips (max 8).
+ This module supports one chip and autoprobe.
The power-management is supported.
@@ -206,7 +206,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
See "AC97 Quirk Option" section below.
spdif_aclink - S/PDIF transfer over AC-link (default = 1)
- This module supports up to 8 cards and autoprobe.
+ This module supports one card and autoprobe.
ATI IXP has two different methods to control SPDIF output. One is
over AC-link and another is over the "direct" SPDIF output. The
@@ -218,7 +218,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
Module for ATI IXP 150/200/250 AC97 modem controllers.
- Module supports up to 8 cards.
+ This module supports one card and autoprobe.
Note: The default index value of this module is -2, i.e. the first
slot is excluded.
@@ -637,7 +637,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
model - force the model name
position_fix - Fix DMA pointer (0 = auto, 1 = none, 2 = POSBUF, 3 = FIFO size)
- Module supports up to 8 cards.
+ This module supports one card and autoprobe.
Each codec may have a model table for different configurations.
If your machine isn't listed there, the default (usually minimal)
@@ -663,6 +663,10 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
adjusted. Appearing only when compiled with
$CONFIG_SND_DEBUG=y
+ ALC260
+ hp HP machines
+ fujitsu Fujitsu S7020
+
CMI9880
minimal 3-jack in back
min_fp 3-jack in back, 2-jack in front
@@ -811,7 +815,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
semaphores (e.g. on some ASUS laptops)
(default off)
- Module supports autoprobe and multiple bus-master chips (max 8).
+ This module supports one chip and autoprobe.
Note: the latest driver supports auto-detection of chip clock.
if you still encounter too fast playback, specify the clock
@@ -830,7 +834,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
ac97_clock - AC'97 codec clock base (0 = auto-detect)
- This module supports up to 8 cards and autoprobe.
+ This module supports one card and autoprobe.
Note: The default index value of this module is -2, i.e. the first
slot is excluded.
@@ -950,8 +954,10 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
use_cache - 0 or 1 (disabled by default)
vaio_hack - alias buffer_top=0x25a800
reset_workaround - enable AC97 RESET workaround for some laptops
+ reset_workaround2 - enable extended AC97 RESET workaround for some
+ other laptops
- Module supports autoprobe and multiple chips (max 8).
+ This module supports one chip and autoprobe.
The power-management is supported.
@@ -980,6 +986,11 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
workaround is enabled automatically. For other laptops with a
hard freeze, you can try reset_workaround=1 option.
+ Note: Dell Latitude CSx laptops have another problem regarding
+ AC97 RESET. On these laptops, reset_workaround2 option is
+ turned on as default. This option is worth to try if the
+ previous reset_workaround option doesn't help.
+
Note: This driver is really crappy. It's a porting from the
OSS driver, which is a result of black-magic reverse engineering.
The detection of codec will fail if the driver is loaded *after*
@@ -1310,7 +1321,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
ac97_quirk - AC'97 workaround for strange hardware
See "AC97 Quirk Option" section below.
- Module supports autoprobe and multiple bus-master chips (max 8).
+ This module supports one chip and autoprobe.
Note: on some SMP motherboards like MSI 694D the interrupts might
not be generated properly. In such a case, please try to
@@ -1352,7 +1363,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
ac97_clock - AC'97 codec clock base (default 48000Hz)
- Module supports up to 8 cards.
+ This module supports one card and autoprobe.
Note: The default index value of this module is -2, i.e. the first
slot is excluded.
diff --git a/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl b/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl
index 24e85520890b..260334c98d95 100644
--- a/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl
+++ b/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl
@@ -18,8 +18,8 @@
</affiliation>
</author>
- <date>March 6, 2005</date>
- <edition>0.3.4</edition>
+ <date>October 6, 2005</date>
+ <edition>0.3.5</edition>
<abstract>
<para>
@@ -30,7 +30,7 @@
<legalnotice>
<para>
- Copyright (c) 2002-2004 Takashi Iwai <email>tiwai@suse.de</email>
+ Copyright (c) 2002-2005 Takashi Iwai <email>tiwai@suse.de</email>
</para>
<para>
@@ -1433,25 +1433,10 @@
<informalexample>
<programlisting>
<![CDATA[
- if (chip->res_port) {
- release_resource(chip->res_port);
- kfree_nocheck(chip->res_port);
- }
+ release_and_free_resource(chip->res_port);
]]>
</programlisting>
</informalexample>
-
- As you can see, the resource pointer is also to be freed
- via <function>kfree_nocheck()</function> after
- <function>release_resource()</function> is called. You
- cannot use <function>kfree()</function> here, because on ALSA,
- <function>kfree()</function> may be a wrapper to its own
- allocator with the memory debugging. Since the resource pointer
- is allocated externally outside the ALSA, it must be released
- via the native
- <function>kfree()</function>.
- <function>kfree_nocheck()</function> is used for that; it calls
- the native <function>kfree()</function> without wrapper.
</para>
<para>
@@ -2190,8 +2175,7 @@ struct _snd_pcm_runtime {
unsigned int rate_den;
/* -- SW params -- */
- int tstamp_timespec; /* use timeval (0) or timespec (1) */
- snd_pcm_tstamp_t tstamp_mode; /* mmap timestamp is updated */
+ struct timespec tstamp_mode; /* mmap timestamp is updated */
unsigned int period_step;
unsigned int sleep_min; /* min ticks to sleep */
snd_pcm_uframes_t xfer_align; /* xfer size need to be a multiple */
@@ -3709,8 +3693,7 @@ struct _snd_pcm_runtime {
<para>
Here, the chip instance is retrieved via
<function>snd_kcontrol_chip()</function> macro. This macro
- converts from kcontrol-&gt;private_data to the type defined by
- <type>chip_t</type>. The
+ just accesses to kcontrol-&gt;private_data. The
kcontrol-&gt;private_data field is
given as the argument of <function>snd_ctl_new()</function>
(see the later subsection
@@ -5998,32 +5981,23 @@ struct _snd_pcm_runtime {
The first argument is the expression to evaluate, and the
second argument is the action if it fails. When
<constant>CONFIG_SND_DEBUG</constant>, is set, it will show an
- error message such as <computeroutput>BUG? (xxx) (called from
- yyy)</computeroutput>. When no debug flag is set, this is
- ignored.
+ error message such as <computeroutput>BUG? (xxx)</computeroutput>
+ together with stack trace.
</para>
- </section>
-
- <section id="useful-functions-snd-runtime-check">
- <title><function>snd_runtime_check()</function></title>
<para>
- This macro is quite similar with
- <function>snd_assert()</function>. Unlike
- <function>snd_assert()</function>, the expression is always
- evaluated regardless of
- <constant>CONFIG_SND_DEBUG</constant>. When
- <constant>CONFIG_SND_DEBUG</constant> is set, the macro will
- show a message like <computeroutput>ERROR (xx) (called from
- yyy)</computeroutput>.
+ When no debug flag is set, this macro is ignored.
</para>
</section>
<section id="useful-functions-snd-bug">
<title><function>snd_BUG()</function></title>
<para>
- It calls <function>snd_assert(0,)</function> -- that is, just
- prints the error message at the point. It's useful to show that
- a fatal error happens there.
+ It shows <computeroutput>BUG?</computeroutput> message and
+ stack trace as well as <function>snd_assert</function> at the point.
+ It's useful to show that a fatal error happens there.
+ </para>
+ <para>
+ When no debug flag is set, this macro is ignored.
</para>
</section>
</chapter>
diff --git a/Documentation/sparse.txt b/Documentation/sparse.txt
index 1829009db771..3f1c5464b1c9 100644
--- a/Documentation/sparse.txt
+++ b/Documentation/sparse.txt
@@ -41,9 +41,9 @@ sure that bitwise types don't get mixed up (little-endian vs big-endian
vs cpu-endian vs whatever), and there the constant "0" really _is_
special.
-Modify top-level Makefile to say
+Use
-CHECK = sparse -Wbitwise
+ make C=[12] CF=-Wbitwise
or you don't get any checking at all.
diff --git a/Documentation/video4linux/API.html b/Documentation/video4linux/API.html
index 441407b12a9f..afbe9ae7ee96 100644
--- a/Documentation/video4linux/API.html
+++ b/Documentation/video4linux/API.html
@@ -8,7 +8,7 @@ V4L original API</a>
</td><td>
Obsoleted by V4L2 API
</td></tr><tr><td>
-<A HREF=http://www.linuxtv.org/downloads/video4linux/API/V4L2_API.html>
+<A HREF=http://www.linuxtv.org/downloads/video4linux/API/V4L2_API>
V4L2 API</a>
</td><td>
Should be used for new projects
diff --git a/Documentation/video4linux/CARDLIST.bttv b/Documentation/video4linux/CARDLIST.bttv
index ec785f9f15a3..2404099996ac 100644
--- a/Documentation/video4linux/CARDLIST.bttv
+++ b/Documentation/video4linux/CARDLIST.bttv
@@ -1,137 +1,142 @@
-card=0 - *** UNKNOWN/GENERIC ***
-card=1 - MIRO PCTV
-card=2 - Hauppauge (bt848)
-card=3 - STB, Gateway P/N 6000699 (bt848)
-card=4 - Intel Create and Share PCI/ Smart Video Recorder III
-card=5 - Diamond DTV2000
-card=6 - AVerMedia TVPhone
-card=7 - MATRIX-Vision MV-Delta
-card=8 - Lifeview FlyVideo II (Bt848) LR26 / MAXI TV Video PCI2 LR26
-card=9 - IMS/IXmicro TurboTV
-card=10 - Hauppauge (bt878)
-card=11 - MIRO PCTV pro
-card=12 - ADS Technologies Channel Surfer TV (bt848)
-card=13 - AVerMedia TVCapture 98
-card=14 - Aimslab Video Highway Xtreme (VHX)
-card=15 - Zoltrix TV-Max
-card=16 - Prolink Pixelview PlayTV (bt878)
-card=17 - Leadtek WinView 601
-card=18 - AVEC Intercapture
-card=19 - Lifeview FlyVideo II EZ /FlyKit LR38 Bt848 (capture only)
-card=20 - CEI Raffles Card
-card=21 - Lifeview FlyVideo 98/ Lucky Star Image World ConferenceTV LR50
-card=22 - Askey CPH050/ Phoebe Tv Master + FM
-card=23 - Modular Technology MM201/MM202/MM205/MM210/MM215 PCTV, bt878
-card=24 - Askey CPH05X/06X (bt878) [many vendors]
-card=25 - Terratec TerraTV+ Version 1.0 (Bt848)/ Terra TValue Version 1.0/ Vobis TV-Boostar
-card=26 - Hauppauge WinCam newer (bt878)
-card=27 - Lifeview FlyVideo 98/ MAXI TV Video PCI2 LR50
-card=28 - Terratec TerraTV+ Version 1.1 (bt878)
-card=29 - Imagenation PXC200
-card=30 - Lifeview FlyVideo 98 LR50
-card=31 - Formac iProTV, Formac ProTV I (bt848)
-card=32 - Intel Create and Share PCI/ Smart Video Recorder III
-card=33 - Terratec TerraTValue Version Bt878
-card=34 - Leadtek WinFast 2000/ WinFast 2000 XP
-card=35 - Lifeview FlyVideo 98 LR50 / Chronos Video Shuttle II
-card=36 - Lifeview FlyVideo 98FM LR50 / Typhoon TView TV/FM Tuner
-card=37 - Prolink PixelView PlayTV pro
-card=38 - Askey CPH06X TView99
-card=39 - Pinnacle PCTV Studio/Rave
-card=40 - STB TV PCI FM, Gateway P/N 6000704 (bt878), 3Dfx VoodooTV 100
-card=41 - AVerMedia TVPhone 98
-card=42 - ProVideo PV951
-card=43 - Little OnAir TV
-card=44 - Sigma TVII-FM
-card=45 - MATRIX-Vision MV-Delta 2
-card=46 - Zoltrix Genie TV/FM
-card=47 - Terratec TV/Radio+
-card=48 - Askey CPH03x/ Dynalink Magic TView
-card=49 - IODATA GV-BCTV3/PCI
-card=50 - Prolink PV-BT878P+4E / PixelView PlayTV PAK / Lenco MXTV-9578 CP
-card=51 - Eagle Wireless Capricorn2 (bt878A)
-card=52 - Pinnacle PCTV Studio Pro
-card=53 - Typhoon TView RDS + FM Stereo / KNC1 TV Station RDS
-card=54 - Lifeview FlyVideo 2000 /FlyVideo A2/ Lifetec LT 9415 TV [LR90]
-card=55 - Askey CPH031/ BESTBUY Easy TV
-card=56 - Lifeview FlyVideo 98FM LR50
-card=57 - GrandTec 'Grand Video Capture' (Bt848)
-card=58 - Askey CPH060/ Phoebe TV Master Only (No FM)
-card=59 - Askey CPH03x TV Capturer
-card=60 - Modular Technology MM100PCTV
-card=61 - AG Electronics GMV1
-card=62 - Askey CPH061/ BESTBUY Easy TV (bt878)
-card=63 - ATI TV-Wonder
-card=64 - ATI TV-Wonder VE
-card=65 - Lifeview FlyVideo 2000S LR90
-card=66 - Terratec TValueRadio
-card=67 - IODATA GV-BCTV4/PCI
-card=68 - 3Dfx VoodooTV FM (Euro), VoodooTV 200 (USA)
-card=69 - Active Imaging AIMMS
-card=70 - Prolink Pixelview PV-BT878P+ (Rev.4C,8E)
-card=71 - Lifeview FlyVideo 98EZ (capture only) LR51
-card=72 - Prolink Pixelview PV-BT878P+9B (PlayTV Pro rev.9B FM+NICAM)
-card=73 - Sensoray 311
-card=74 - RemoteVision MX (RV605)
-card=75 - Powercolor MTV878/ MTV878R/ MTV878F
-card=76 - Canopus WinDVR PCI (COMPAQ Presario 3524JP, 5112JP)
-card=77 - GrandTec Multi Capture Card (Bt878)
-card=78 - Jetway TV/Capture JW-TV878-FBK, Kworld KW-TV878RF
-card=79 - DSP Design TCVIDEO
-card=80 - Hauppauge WinTV PVR
-card=81 - IODATA GV-BCTV5/PCI
-card=82 - Osprey 100/150 (878)
-card=83 - Osprey 100/150 (848)
-card=84 - Osprey 101 (848)
-card=85 - Osprey 101/151
-card=86 - Osprey 101/151 w/ svid
-card=87 - Osprey 200/201/250/251
-card=88 - Osprey 200/250
-card=89 - Osprey 210/220
-card=90 - Osprey 500
-card=91 - Osprey 540
-card=92 - Osprey 2000
-card=93 - IDS Eagle
-card=94 - Pinnacle PCTV Sat
-card=95 - Formac ProTV II (bt878)
-card=96 - MachTV
-card=97 - Euresys Picolo
-card=98 - ProVideo PV150
-card=99 - AD-TVK503
-card=100 - Hercules Smart TV Stereo
-card=101 - Pace TV & Radio Card
-card=102 - IVC-200
-card=103 - Grand X-Guard / Trust 814PCI
-card=104 - Nebula Electronics DigiTV
-card=105 - ProVideo PV143
-card=106 - PHYTEC VD-009-X1 MiniDIN (bt878)
-card=107 - PHYTEC VD-009-X1 Combi (bt878)
-card=108 - PHYTEC VD-009 MiniDIN (bt878)
-card=109 - PHYTEC VD-009 Combi (bt878)
-card=110 - IVC-100
-card=111 - IVC-120G
-card=112 - pcHDTV HD-2000 TV
-card=113 - Twinhan DST + clones
-card=114 - Winfast VC100
-card=115 - Teppro TEV-560/InterVision IV-560
-card=116 - SIMUS GVC1100
-card=117 - NGS NGSTV+
-card=118 - LMLBT4
-card=119 - Tekram M205 PRO
-card=120 - Conceptronic CONTVFMi
-card=121 - Euresys Picolo Tetra
-card=122 - Spirit TV Tuner
-card=123 - AVerMedia AVerTV DVB-T 771
-card=124 - AverMedia AverTV DVB-T 761
-card=125 - MATRIX Vision Sigma-SQ
-card=126 - MATRIX Vision Sigma-SLC
-card=127 - APAC Viewcomp 878(AMAX)
-card=128 - DViCO FusionHDTV DVB-T Lite
-card=129 - V-Gear MyVCD
-card=130 - Super TV Tuner
-card=131 - Tibet Systems 'Progress DVR' CS16
-card=132 - Kodicom 4400R (master)
-card=133 - Kodicom 4400R (slave)
-card=134 - Adlink RTV24
-card=135 - DViCO FusionHDTV 5 Lite
-card=136 - Acorp Y878F
+ 0 -> *** UNKNOWN/GENERIC ***
+ 1 -> MIRO PCTV
+ 2 -> Hauppauge (bt848)
+ 3 -> STB, Gateway P/N 6000699 (bt848)
+ 4 -> Intel Create and Share PCI/ Smart Video Recorder III
+ 5 -> Diamond DTV2000
+ 6 -> AVerMedia TVPhone
+ 7 -> MATRIX-Vision MV-Delta
+ 8 -> Lifeview FlyVideo II (Bt848) LR26 / MAXI TV Video PCI2 LR26
+ 9 -> IMS/IXmicro TurboTV
+ 10 -> Hauppauge (bt878) [0070:13eb,0070:3900,2636:10b4]
+ 11 -> MIRO PCTV pro
+ 12 -> ADS Technologies Channel Surfer TV (bt848)
+ 13 -> AVerMedia TVCapture 98 [1461:0002,1461:0004,1461:0300]
+ 14 -> Aimslab Video Highway Xtreme (VHX)
+ 15 -> Zoltrix TV-Max [a1a0:a0fc]
+ 16 -> Prolink Pixelview PlayTV (bt878)
+ 17 -> Leadtek WinView 601
+ 18 -> AVEC Intercapture
+ 19 -> Lifeview FlyVideo II EZ /FlyKit LR38 Bt848 (capture only)
+ 20 -> CEI Raffles Card
+ 21 -> Lifeview FlyVideo 98/ Lucky Star Image World ConferenceTV LR50
+ 22 -> Askey CPH050/ Phoebe Tv Master + FM [14ff:3002]
+ 23 -> Modular Technology MM201/MM202/MM205/MM210/MM215 PCTV, bt878 [14c7:0101]
+ 24 -> Askey CPH05X/06X (bt878) [many vendors] [144f:3002,144f:3005,144f:5000,14ff:3000]
+ 25 -> Terratec TerraTV+ Version 1.0 (Bt848)/ Terra TValue Version 1.0/ Vobis TV-Boostar
+ 26 -> Hauppauge WinCam newer (bt878)
+ 27 -> Lifeview FlyVideo 98/ MAXI TV Video PCI2 LR50
+ 28 -> Terratec TerraTV+ Version 1.1 (bt878) [153b:1127,1852:1852]
+ 29 -> Imagenation PXC200 [1295:200a]
+ 30 -> Lifeview FlyVideo 98 LR50 [1f7f:1850]
+ 31 -> Formac iProTV, Formac ProTV I (bt848)
+ 32 -> Intel Create and Share PCI/ Smart Video Recorder III
+ 33 -> Terratec TerraTValue Version Bt878 [153b:1117,153b:1118,153b:1119,153b:111a,153b:1134,153b:5018]
+ 34 -> Leadtek WinFast 2000/ WinFast 2000 XP [107d:6606,107d:6609,6606:217d,f6ff:fff6]
+ 35 -> Lifeview FlyVideo 98 LR50 / Chronos Video Shuttle II [1851:1850,1851:a050]
+ 36 -> Lifeview FlyVideo 98FM LR50 / Typhoon TView TV/FM Tuner [1852:1852]
+ 37 -> Prolink PixelView PlayTV pro
+ 38 -> Askey CPH06X TView99 [144f:3000,144f:a005,a04f:a0fc]
+ 39 -> Pinnacle PCTV Studio/Rave [11bd:0012,bd11:1200,bd11:ff00,11bd:ff12]
+ 40 -> STB TV PCI FM, Gateway P/N 6000704 (bt878), 3Dfx VoodooTV 100 [10b4:2636,10b4:2645,121a:3060]
+ 41 -> AVerMedia TVPhone 98 [1461:0001,1461:0003]
+ 42 -> ProVideo PV951 [aa0c:146c]
+ 43 -> Little OnAir TV
+ 44 -> Sigma TVII-FM
+ 45 -> MATRIX-Vision MV-Delta 2
+ 46 -> Zoltrix Genie TV/FM [15b0:4000,15b0:400a,15b0:400d,15b0:4010,15b0:4016]
+ 47 -> Terratec TV/Radio+ [153b:1123]
+ 48 -> Askey CPH03x/ Dynalink Magic TView
+ 49 -> IODATA GV-BCTV3/PCI [10fc:4020]
+ 50 -> Prolink PV-BT878P+4E / PixelView PlayTV PAK / Lenco MXTV-9578 CP
+ 51 -> Eagle Wireless Capricorn2 (bt878A)
+ 52 -> Pinnacle PCTV Studio Pro
+ 53 -> Typhoon TView RDS + FM Stereo / KNC1 TV Station RDS
+ 54 -> Lifeview FlyVideo 2000 /FlyVideo A2/ Lifetec LT 9415 TV [LR90]
+ 55 -> Askey CPH031/ BESTBUY Easy TV
+ 56 -> Lifeview FlyVideo 98FM LR50 [a051:41a0]
+ 57 -> GrandTec 'Grand Video Capture' (Bt848) [4344:4142]
+ 58 -> Askey CPH060/ Phoebe TV Master Only (No FM)
+ 59 -> Askey CPH03x TV Capturer
+ 60 -> Modular Technology MM100PCTV
+ 61 -> AG Electronics GMV1 [15cb:0101]
+ 62 -> Askey CPH061/ BESTBUY Easy TV (bt878)
+ 63 -> ATI TV-Wonder [1002:0001]
+ 64 -> ATI TV-Wonder VE [1002:0003]
+ 65 -> Lifeview FlyVideo 2000S LR90
+ 66 -> Terratec TValueRadio [153b:1135,153b:ff3b]
+ 67 -> IODATA GV-BCTV4/PCI [10fc:4050]
+ 68 -> 3Dfx VoodooTV FM (Euro), VoodooTV 200 (USA) [121a:3000,10b4:2637]
+ 69 -> Active Imaging AIMMS
+ 70 -> Prolink Pixelview PV-BT878P+ (Rev.4C,8E)
+ 71 -> Lifeview FlyVideo 98EZ (capture only) LR51 [1851:1851]
+ 72 -> Prolink Pixelview PV-BT878P+9B (PlayTV Pro rev.9B FM+NICAM) [1554:4011]
+ 73 -> Sensoray 311 [6000:0311]
+ 74 -> RemoteVision MX (RV605)
+ 75 -> Powercolor MTV878/ MTV878R/ MTV878F
+ 76 -> Canopus WinDVR PCI (COMPAQ Presario 3524JP, 5112JP) [0e11:0079]
+ 77 -> GrandTec Multi Capture Card (Bt878)
+ 78 -> Jetway TV/Capture JW-TV878-FBK, Kworld KW-TV878RF [0a01:17de]
+ 79 -> DSP Design TCVIDEO
+ 80 -> Hauppauge WinTV PVR [0070:4500]
+ 81 -> IODATA GV-BCTV5/PCI [10fc:4070,10fc:d018]
+ 82 -> Osprey 100/150 (878) [0070:ff00]
+ 83 -> Osprey 100/150 (848)
+ 84 -> Osprey 101 (848)
+ 85 -> Osprey 101/151
+ 86 -> Osprey 101/151 w/ svid
+ 87 -> Osprey 200/201/250/251
+ 88 -> Osprey 200/250 [0070:ff01]
+ 89 -> Osprey 210/220
+ 90 -> Osprey 500 [0070:ff02]
+ 91 -> Osprey 540 [0070:ff04]
+ 92 -> Osprey 2000 [0070:ff03]
+ 93 -> IDS Eagle
+ 94 -> Pinnacle PCTV Sat [11bd:001c]
+ 95 -> Formac ProTV II (bt878)
+ 96 -> MachTV
+ 97 -> Euresys Picolo
+ 98 -> ProVideo PV150 [aa00:1460,aa01:1461,aa02:1462,aa03:1463,aa04:1464,aa05:1465,aa06:1466,aa07:1467]
+ 99 -> AD-TVK503
+100 -> Hercules Smart TV Stereo
+101 -> Pace TV & Radio Card
+102 -> IVC-200 [0000:a155,0001:a155,0002:a155,0003:a155,0100:a155,0101:a155,0102:a155,0103:a155]
+103 -> Grand X-Guard / Trust 814PCI [0304:0102]
+104 -> Nebula Electronics DigiTV [0071:0101]
+105 -> ProVideo PV143 [aa00:1430,aa00:1431,aa00:1432,aa00:1433,aa03:1433]
+106 -> PHYTEC VD-009-X1 MiniDIN (bt878)
+107 -> PHYTEC VD-009-X1 Combi (bt878)
+108 -> PHYTEC VD-009 MiniDIN (bt878)
+109 -> PHYTEC VD-009 Combi (bt878)
+110 -> IVC-100 [ff00:a132]
+111 -> IVC-120G [ff00:a182,ff01:a182,ff02:a182,ff03:a182,ff04:a182,ff05:a182,ff06:a182,ff07:a182,ff08:a182,ff09:a182,ff0a:a182,ff0b:a182,ff0c:a182,ff0d:a182,ff0e:a182,ff0f:a182]
+112 -> pcHDTV HD-2000 TV [7063:2000]
+113 -> Twinhan DST + clones [11bd:0026,1822:0001,270f:fc00]
+114 -> Winfast VC100 [107d:6607]
+115 -> Teppro TEV-560/InterVision IV-560
+116 -> SIMUS GVC1100 [aa6a:82b2]
+117 -> NGS NGSTV+
+118 -> LMLBT4
+119 -> Tekram M205 PRO
+120 -> Conceptronic CONTVFMi
+121 -> Euresys Picolo Tetra [1805:0105,1805:0106,1805:0107,1805:0108]
+122 -> Spirit TV Tuner
+123 -> AVerMedia AVerTV DVB-T 771 [1461:0771]
+124 -> AverMedia AverTV DVB-T 761 [1461:0761]
+125 -> MATRIX Vision Sigma-SQ
+126 -> MATRIX Vision Sigma-SLC
+127 -> APAC Viewcomp 878(AMAX)
+128 -> DViCO FusionHDTV DVB-T Lite [18ac:db10]
+129 -> V-Gear MyVCD
+130 -> Super TV Tuner
+131 -> Tibet Systems 'Progress DVR' CS16
+132 -> Kodicom 4400R (master)
+133 -> Kodicom 4400R (slave)
+134 -> Adlink RTV24
+135 -> DViCO FusionHDTV 5 Lite [18ac:d500]
+136 -> Acorp Y878F [9511:1540]
+137 -> Conceptronic CTVFMi v2
+138 -> Prolink Pixelview PV-BT878P+ (Rev.2E)
+139 -> Prolink PixelView PlayTV MPEG2 PV-M4900
+140 -> Osprey 440 [0070:ff07]
+141 -> Asound Skyeye PCTV
diff --git a/Documentation/video4linux/CARDLIST.cx88 b/Documentation/video4linux/CARDLIST.cx88
index 03deb0726aa4..a1017d1a85d4 100644
--- a/Documentation/video4linux/CARDLIST.cx88
+++ b/Documentation/video4linux/CARDLIST.cx88
@@ -1,32 +1,37 @@
-card=0 - UNKNOWN/GENERIC
-card=1 - Hauppauge WinTV 34xxx models
-card=2 - GDI Black Gold
-card=3 - PixelView
-card=4 - ATI TV Wonder Pro
-card=5 - Leadtek Winfast 2000XP Expert
-card=6 - AverTV Studio 303 (M126)
-card=7 - MSI TV-@nywhere Master
-card=8 - Leadtek Winfast DV2000
-card=9 - Leadtek PVR 2000
-card=10 - IODATA GV-VCP3/PCI
-card=11 - Prolink PlayTV PVR
-card=12 - ASUS PVR-416
-card=13 - MSI TV-@nywhere
-card=14 - KWorld/VStream XPert DVB-T
-card=15 - DViCO FusionHDTV DVB-T1
-card=16 - KWorld LTV883RF
-card=17 - DViCO FusionHDTV 3 Gold-Q
-card=18 - Hauppauge Nova-T DVB-T
-card=19 - Conexant DVB-T reference design
-card=20 - Provideo PV259
-card=21 - DViCO FusionHDTV DVB-T Plus
-card=22 - digitalnow DNTV Live! DVB-T
-card=23 - pcHDTV HD3000 HDTV
-card=24 - Hauppauge WinTV 28xxx (Roslyn) models
-card=25 - Digital-Logic MICROSPACE Entertainment Center (MEC)
-card=26 - IODATA GV/BCTV7E
-card=27 - PixelView PlayTV Ultra Pro (Stereo)
-card=28 - DViCO FusionHDTV 3 Gold-T
-card=29 - ADS Tech Instant TV DVB-T PCI
-card=30 - TerraTec Cinergy 1400 DVB-T
-card=31 - DViCO FusionHDTV 5 Gold
+ 0 -> UNKNOWN/GENERIC
+ 1 -> Hauppauge WinTV 34xxx models [0070:3400,0070:3401]
+ 2 -> GDI Black Gold [14c7:0106,14c7:0107]
+ 3 -> PixelView [1554:4811]
+ 4 -> ATI TV Wonder Pro [1002:00f8]
+ 5 -> Leadtek Winfast 2000XP Expert [107d:6611,107d:6613]
+ 6 -> AverTV Studio 303 (M126) [1461:000b]
+ 7 -> MSI TV-@nywhere Master [1462:8606]
+ 8 -> Leadtek Winfast DV2000 [107d:6620]
+ 9 -> Leadtek PVR 2000 [107d:663b,107d:663C]
+ 10 -> IODATA GV-VCP3/PCI [10fc:d003]
+ 11 -> Prolink PlayTV PVR
+ 12 -> ASUS PVR-416 [1043:4823]
+ 13 -> MSI TV-@nywhere
+ 14 -> KWorld/VStream XPert DVB-T [17de:08a6]
+ 15 -> DViCO FusionHDTV DVB-T1 [18ac:db00]
+ 16 -> KWorld LTV883RF
+ 17 -> DViCO FusionHDTV 3 Gold-Q [18ac:d810]
+ 18 -> Hauppauge Nova-T DVB-T [0070:9002]
+ 19 -> Conexant DVB-T reference design [14f1:0187]
+ 20 -> Provideo PV259 [1540:2580]
+ 21 -> DViCO FusionHDTV DVB-T Plus [18ac:db10]
+ 22 -> pcHDTV HD3000 HDTV [7063:3000]
+ 23 -> digitalnow DNTV Live! DVB-T [17de:a8a6]
+ 24 -> Hauppauge WinTV 28xxx (Roslyn) models [0070:2801]
+ 25 -> Digital-Logic MICROSPACE Entertainment Center (MEC) [14f1:0342]
+ 26 -> IODATA GV/BCTV7E [10fc:d035]
+ 27 -> PixelView PlayTV Ultra Pro (Stereo)
+ 28 -> DViCO FusionHDTV 3 Gold-T [18ac:d820]
+ 29 -> ADS Tech Instant TV DVB-T PCI [1421:0334]
+ 30 -> TerraTec Cinergy 1400 DVB-T [153b:1166]
+ 31 -> DViCO FusionHDTV 5 Gold [18ac:d500]
+ 32 -> AverMedia UltraTV Media Center PCI 550 [1461:8011]
+ 33 -> Kworld V-Stream Xpert DVD
+ 34 -> ATI HDTV Wonder [1002:a101]
+ 35 -> WinFast DTV1000-T [107d:665f]
+ 36 -> AVerTV 303 (M126) [1461:000a]
diff --git a/Documentation/video4linux/CARDLIST.em28xx b/Documentation/video4linux/CARDLIST.em28xx
new file mode 100644
index 000000000000..a0c7cad20971
--- /dev/null
+++ b/Documentation/video4linux/CARDLIST.em28xx
@@ -0,0 +1,10 @@
+ 0 -> Unknown EM2800 video grabber (em2800) [eb1a:2800]
+ 1 -> Unknown EM2820/2840 video grabber (em2820/em2840)
+ 2 -> Terratec Cinergy 250 USB (em2820/em2840) [0ccd:0036]
+ 3 -> Pinnacle PCTV USB 2 (em2820/em2840) [2304:0208]
+ 4 -> Hauppauge WinTV USB 2 (em2820/em2840) [2040:4200]
+ 5 -> MSI VOX USB 2.0 (em2820/em2840) [eb1a:2820]
+ 6 -> Terratec Cinergy 200 USB (em2800)
+ 7 -> Leadtek Winfast USB II (em2800)
+ 8 -> Kworld USB2800 (em2800)
+ 9 -> Pinnacle Dazzle DVC 90 (em2820/em2840) [2304:0207]
diff --git a/Documentation/video4linux/CARDLIST.saa7134 b/Documentation/video4linux/CARDLIST.saa7134
index dc57225f39be..57c9d631db56 100644
--- a/Documentation/video4linux/CARDLIST.saa7134
+++ b/Documentation/video4linux/CARDLIST.saa7134
@@ -6,10 +6,10 @@
5 -> SKNet Monster TV [1131:4e85]
6 -> Tevion MD 9717
7 -> KNC One TV-Station RDS / Typhoon TV Tuner RDS [1131:fe01,1894:fe01]
- 8 -> Terratec Cinergy 400 TV [153B:1142]
+ 8 -> Terratec Cinergy 400 TV [153b:1142]
9 -> Medion 5044
10 -> Kworld/KuroutoShikou SAA7130-TVPCI
- 11 -> Terratec Cinergy 600 TV [153B:1143]
+ 11 -> Terratec Cinergy 600 TV [153b:1143]
12 -> Medion 7134 [16be:0003]
13 -> Typhoon TV+Radio 90031
14 -> ELSA EX-VISION 300TV [1048:226b]
@@ -36,8 +36,8 @@
35 -> AverMedia AverTV Studio 305 [1461:2115]
36 -> UPMOST PURPLE TV [12ab:0800]
37 -> Items MuchTV Plus / IT-005
- 38 -> Terratec Cinergy 200 TV [153B:1152]
- 39 -> LifeView FlyTV Platinum Mini [5168:0212]
+ 38 -> Terratec Cinergy 200 TV [153b:1152]
+ 39 -> LifeView FlyTV Platinum Mini [5168:0212,4e42:0212]
40 -> Compro VideoMate TV PVR/FM [185b:c100]
41 -> Compro VideoMate TV Gold+ [185b:c100]
42 -> Sabrent SBT-TVFM (saa7130)
@@ -46,7 +46,7 @@
45 -> Avermedia AVerTV Studio 307 [1461:9715]
46 -> AVerMedia Cardbus TV/Radio (E500) [1461:d6ee]
47 -> Terratec Cinergy 400 mobile [153b:1162]
- 48 -> Terratec Cinergy 600 TV MK3 [153B:1158]
+ 48 -> Terratec Cinergy 600 TV MK3 [153b:1158]
49 -> Compro VideoMate Gold+ Pal [185b:c200]
50 -> Pinnacle PCTV 300i DVB-T + PAL [11bd:002d]
51 -> ProVideo PV952 [1540:9524]
@@ -56,12 +56,27 @@
55 -> LifeView FlyDVB-T DUO [5168:0502,5168:0306]
56 -> Avermedia AVerTV 307 [1461:a70a]
57 -> Avermedia AVerTV GO 007 FM [1461:f31f]
- 58 -> ADS Tech Instant TV (saa7135) [1421:0350,1421:0370]
+ 58 -> ADS Tech Instant TV (saa7135) [1421:0350,1421:0370,1421:1370]
59 -> Kworld/Tevion V-Stream Xpert TV PVR7134
60 -> Typhoon DVB-T Duo Digital/Analog Cardbus [4e42:0502]
61 -> Philips TOUGH DVB-T reference design [1131:2004]
62 -> Compro VideoMate TV Gold+II
63 -> Kworld Xpert TV PVR7134
- 64 -> FlyTV mini Asus Digimatrix [1043:0210,1043:0210]
+ 64 -> FlyTV mini Asus Digimatrix [1043:0210]
65 -> V-Stream Studio TV Terminator
66 -> Yuan TUN-900 (saa7135)
+ 67 -> Beholder BeholdTV 409 FM [0000:4091]
+ 68 -> GoTView 7135 PCI [5456:7135]
+ 69 -> Philips EUROPA V3 reference design [1131:2004]
+ 70 -> Compro Videomate DVB-T300 [185b:c900]
+ 71 -> Compro Videomate DVB-T200 [185b:c901]
+ 72 -> RTD Embedded Technologies VFG7350 [1435:7350]
+ 73 -> RTD Embedded Technologies VFG7330 [1435:7330]
+ 74 -> LifeView FlyTV Platinum Mini2 [14c0:1212]
+ 75 -> AVerMedia AVerTVHD MCE A180 [1461:1044]
+ 76 -> SKNet MonsterTV Mobile [1131:4ee9]
+ 77 -> Pinnacle PCTV 110i (saa7133) [11bd:002e]
+ 78 -> ASUSTeK P7131 Dual [1043:4862]
+ 79 -> Sedna/MuchTV PC TV Cardbus TV/Radio (ITO25 Rev:2B)
+ 80 -> ASUS Digimatrix TV [1043:0210]
+ 81 -> Philips Tiger reference design [1131:2018]
diff --git a/Documentation/video4linux/CARDLIST.tuner b/Documentation/video4linux/CARDLIST.tuner
index f5876be658a6..ec840ca6f455 100644
--- a/Documentation/video4linux/CARDLIST.tuner
+++ b/Documentation/video4linux/CARDLIST.tuner
@@ -53,7 +53,7 @@ tuner=51 - Philips PAL/SECAM_D (FM 1256 I-H3)
tuner=52 - Thomson DDT 7610 (ATSC/NTSC)
tuner=53 - Philips FQ1286
tuner=54 - tda8290+75
-tuner=55 - LG PAL (TAPE series)
+tuner=55 - TCL 2002MB
tuner=56 - Philips PAL/SECAM multi (FQ1216AME MK4)
tuner=57 - Philips FQ1236A MK4
tuner=58 - Ymec TVision TVF-8531MF/8831MF/8731MF
@@ -65,3 +65,5 @@ tuner=63 - Philips FMD1216ME MK3 Hybrid Tuner
tuner=64 - LG TDVS-H062F/TUA6034
tuner=65 - Ymec TVF66T5-B/DFF
tuner=66 - LG NTSC (TALN mini series)
+tuner=67 - Philips TD1316 Hybrid Tuner
+tuner=68 - Philips TUV1236D ATSC/NTSC dual in
diff --git a/Documentation/video4linux/README.cx88 b/Documentation/video4linux/README.cx88
index 897ab834839a..06a33a4f52fd 100644
--- a/Documentation/video4linux/README.cx88
+++ b/Documentation/video4linux/README.cx88
@@ -17,9 +17,9 @@ audio
- The chip specs for the on-chip TV sound decoder are next
to useless :-/
- Neverless the builtin TV sound decoder starts working now,
- at least for PAL-BG. Other TV norms need other code ...
- FOR ANY REPORTS ON THIS PLEASE MENTION THE TV NORM YOU ARE
- USING.
+ at least for PAL-BG. Other TV norms need other code ...
+ FOR ANY REPORTS ON THIS PLEASE MENTION THE TV NORM YOU ARE
+ USING.
- Most tuner chips do provide mono sound, which may or may not
be useable depending on the board design. With the Hauppauge
cards it works, so there is mono sound available as fallback.
@@ -65,5 +65,5 @@ Have fun,
Gerd
---
+--
Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
diff --git a/Documentation/video4linux/README.saa7134 b/Documentation/video4linux/README.saa7134
index 1f788e498eff..b911f0871874 100644
--- a/Documentation/video4linux/README.saa7134
+++ b/Documentation/video4linux/README.saa7134
@@ -78,5 +78,5 @@ Have fun,
Gerd
---
+--
Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
diff --git a/Documentation/video4linux/bttv/Cards b/Documentation/video4linux/bttv/Cards
index 8f1941ede4da..d3389655ad96 100644
--- a/Documentation/video4linux/bttv/Cards
+++ b/Documentation/video4linux/bttv/Cards
@@ -149,11 +149,11 @@ Lifeview Flyvideo Series:
2) There is a print on the PCB:
LR25 = Flyvideo (Zoran ZR36120, SAA7110A)
LR26 Rev.N = Flyvideo II (Bt848)
- Rev.O = Flyvideo II (Bt878)
+ Rev.O = Flyvideo II (Bt878)
LR37 Rev.C = Flyvideo EZ (Capture only, ZR36120 + SAA7110)
LR38 Rev.A1= Flyvideo II EZ (Bt848 capture only)
LR50 Rev.Q = Flyvideo 98 (w/eeprom and PCI subsystem ID)
- Rev.W = Flyvideo 98 (no eeprom)
+ Rev.W = Flyvideo 98 (no eeprom)
LR51 Rev.E = Flyvideo 98 EZ (capture only)
LR90 = Flyvideo 2000 (Bt878)
Flyvideo 2000S (Bt878) w/Stereo TV (Package incl. LR91 daughterboard)
@@ -163,7 +163,7 @@ Lifeview Flyvideo Series:
LR136 = Flyvideo 2100/3100 (Low profile, SAA7130/SAA7134)
LR137 = Flyvideo DV2000/DV3000 (SAA7130/SAA7134 + IEEE1394)
LR138 Rev.C= Flyvideo 2000 (SAA7130)
- or Flyvideo 3000 (SAA7134) w/Stereo TV
+ or Flyvideo 3000 (SAA7134) w/Stereo TV
These exist in variations w/FM and w/Remote sometimes denoted
by suffixes "FM" and "R".
3) You have a laptop (miniPCI card):
@@ -197,7 +197,7 @@ Typhoon TV card series:
50680 "TV Tuner Pal BG" (blue package)= Pixelview PV-BT878P+ (Rev 9B)
50681 "TV Tuner PCI Pal I" (variant of 50680)
50682 "TView TV/FM Tuner Pal BG" = Flyvideo 98FM (LR50 Rev.Q)
- Note: The package has a picture of CPH05x (which would be a real TView)
+ Note: The package has a picture of CPH05x (which would be a real TView)
50683 "TV Tuner PCI SECAM" (variant of 50680)
50684 "TV Tuner Pal BG" = Pixelview 878TV(Rev.3D)
50686 "TV Tuner" = KNC1 TV Station
@@ -418,9 +418,9 @@ Lifetec/Medion/Tevion/Aldi
--------------------------
LT9306/MD9306 = CPH061
LT9415/MD9415 = LR90 Rev.F or Rev.G
- MD9592 = Avermedia TVphone98 (PCI_ID=1461:0003), PCB-Rev=M168II-B (w/TDA9873H)
- MD9717 = KNC One (Rev D4, saa7134, FM1216 MK2 tuner)
- MD5044 = KNC One (Rev D4, saa7134, FM1216ME MK3 tuner)
+ MD9592 = Avermedia TVphone98 (PCI_ID=1461:0003), PCB-Rev=M168II-B (w/TDA9873H)
+ MD9717 = KNC One (Rev D4, saa7134, FM1216 MK2 tuner)
+ MD5044 = KNC One (Rev D4, saa7134, FM1216ME MK3 tuner)
Modular Technologies (www.modulartech.com) UK
---------------------------------------------
@@ -453,10 +453,10 @@ Technisat
Discos ADR PC-Karte ISA (no TV!)
Discos ADR PC-Karte PCI (probably no TV?)
Techni-PC-Sat (Sat. analog)
- Rev 1.2 (zr36120, vpx3220, stv0030, saa5246, BSJE3-494A)
+ Rev 1.2 (zr36120, vpx3220, stv0030, saa5246, BSJE3-494A)
Mediafocus I (zr36120/zr36125, drp3510, Sat. analog + ADR Radio)
Mediafocus II (saa7146, Sat. analog)
- SatADR Rev 2.1 (saa7146a, saa7113h, stv0056a, msp3400c, drp3510a, BSKE3-307A)
+ SatADR Rev 2.1 (saa7146a, saa7113h, stv0056a, msp3400c, drp3510a, BSKE3-307A)
SkyStar 1 DVB (AV7110) = Technotrend Premium
SkyStar 2 DVB (B2C2) (=Sky2PC)
diff --git a/Documentation/video4linux/bttv/README b/Documentation/video4linux/bttv/README
index a72f4c94fb0b..7ca2154c2bf5 100644
--- a/Documentation/video4linux/bttv/README
+++ b/Documentation/video4linux/bttv/README
@@ -42,9 +42,9 @@ bttv uses the PCI Subsystem ID to autodetect the card type. lspci lists
the Subsystem ID in the second line, looks like this:
00:0a.0 Multimedia video controller: Brooktree Corporation Bt878 (rev 02)
- Subsystem: Hauppauge computer works Inc. WinTV/GO
- Flags: bus master, medium devsel, latency 32, IRQ 5
- Memory at e2000000 (32-bit, prefetchable) [size=4K]
+ Subsystem: Hauppauge computer works Inc. WinTV/GO
+ Flags: bus master, medium devsel, latency 32, IRQ 5
+ Memory at e2000000 (32-bit, prefetchable) [size=4K]
only bt878-based cards can have a subsystem ID (which does not mean
that every card really has one). bt848 cards can't have a Subsystem
diff --git a/Documentation/video4linux/bttv/README.freeze b/Documentation/video4linux/bttv/README.freeze
index 51f8d4379a94..4259dccc8287 100644
--- a/Documentation/video4linux/bttv/README.freeze
+++ b/Documentation/video4linux/bttv/README.freeze
@@ -27,9 +27,9 @@ information out of a register+stack dump printed by the kernel on
protection faults (so-called "kernel oops").
If you run into some kind of deadlock, you can try to dump a call trace
-for each process using sysrq-t (see Documentation/sysrq.txt). ksymoops
-will translate these dumps into kernel symbols too. This way it is
-possible to figure where *exactly* some process in "D" state is stuck.
+for each process using sysrq-t (see Documentation/sysrq.txt).
+This way it is possible to figure where *exactly* some process in "D"
+state is stuck.
I've seen reports that bttv 0.7.x crashes whereas 0.8.x works rock solid
for some people. Thus probably a small buglet left somewhere in bttv
diff --git a/Documentation/video4linux/bttv/Sound-FAQ b/Documentation/video4linux/bttv/Sound-FAQ
index b8c9c2605ce2..1e6328f91083 100644
--- a/Documentation/video4linux/bttv/Sound-FAQ
+++ b/Documentation/video4linux/bttv/Sound-FAQ
@@ -61,8 +61,8 @@ line for your board. The important fields are these two:
struct tvcard
{
[ ... ]
- u32 gpiomask;
- u32 audiomux[6]; /* Tuner, Radio, external, internal, mute, stereo */
+ u32 gpiomask;
+ u32 audiomux[6]; /* Tuner, Radio, external, internal, mute, stereo */
};
gpiomask specifies which pins are used to control the audio mux chip.
@@ -126,11 +126,11 @@ muxsel - video mux, input->registervalue mapping
pll - same as pll= insmod option
tuner_type - same as tuner= insmod option
*_modulename - hint whenever some card needs this or that audio
- module loaded to work properly.
+ module loaded to work properly.
has_radio - whenever this TV card has a radio tuner.
no_msp34xx - "1" disables loading of msp3400.o module
-no_tda9875 - "1" disables loading of tda9875.o module
-needs_tvaudio - set to "1" to load tvaudio.o module
+no_tda9875 - "1" disables loading of tda9875.o module
+needs_tvaudio - set to "1" to load tvaudio.o module
If some config item is specified both from the tvcards array and as
insmod option, the insmod option takes precedence.
@@ -144,5 +144,5 @@ Good luck,
PS: If you have a new working entry, mail it to me.
---
+--
Gerd Knorr <kraxel@bytesex.org>
diff --git a/Documentation/video4linux/bttv/Tuners b/Documentation/video4linux/bttv/Tuners
index d18fbc70c0e0..0a371d349542 100644
--- a/Documentation/video4linux/bttv/Tuners
+++ b/Documentation/video4linux/bttv/Tuners
@@ -21,7 +21,7 @@ SAMSUNG Tuner identification: (e.g. TCPM9091PD27)
J= NTSC-Japan
L= Secam LL
M= BG+I+DK
- N= NTSC
+ N= NTSC
Q= BG+I+DK+LL
[89]: ?
[125]:
@@ -96,7 +96,7 @@ LG Innotek Tuner:
TADC-H002F: NTSC (L,175/410?; 2-B, C-W+11, W+12-69)
TADC-M201D: PAL D/K+B/G+I (L,143/425) (sound control at I2C address 0xc8)
TADC-T003F: NTSC Taiwan (L,175/410?; 2-B, C-W+11, W+12-69)
- Suffix:
+ Suffix:
P= Standard phono female socket
D= IEC female socket
F= F-connector
diff --git a/Documentation/video4linux/lifeview.txt b/Documentation/video4linux/lifeview.txt
index b07ea79c2b7e..05f9eb57aac9 100644
--- a/Documentation/video4linux/lifeview.txt
+++ b/Documentation/video4linux/lifeview.txt
@@ -10,33 +10,33 @@ bt878:
------------------------------------------------------------------------------
saa7134:
- /* LifeView FlyTV Platinum FM (LR214WF) */
- /* "Peter Missel <peter.missel@onlinehome.de> */
- .name = "LifeView FlyTV Platinum FM",
- /* GP27 MDT2005 PB4 pin 10 */
- /* GP26 MDT2005 PB3 pin 9 */
- /* GP25 MDT2005 PB2 pin 8 */
- /* GP23 MDT2005 PB1 pin 7 */
- /* GP22 MDT2005 PB0 pin 6 */
- /* GP21 MDT2005 PB5 pin 11 */
- /* GP20 MDT2005 PB6 pin 12 */
- /* GP19 MDT2005 PB7 pin 13 */
- /* nc MDT2005 PA3 pin 2 */
- /* Remote MDT2005 PA2 pin 1 */
- /* GP18 MDT2005 PA1 pin 18 */
- /* nc MDT2005 PA0 pin 17 strap low */
+ /* LifeView FlyTV Platinum FM (LR214WF) */
+ /* "Peter Missel <peter.missel@onlinehome.de> */
+ .name = "LifeView FlyTV Platinum FM",
+ /* GP27 MDT2005 PB4 pin 10 */
+ /* GP26 MDT2005 PB3 pin 9 */
+ /* GP25 MDT2005 PB2 pin 8 */
+ /* GP23 MDT2005 PB1 pin 7 */
+ /* GP22 MDT2005 PB0 pin 6 */
+ /* GP21 MDT2005 PB5 pin 11 */
+ /* GP20 MDT2005 PB6 pin 12 */
+ /* GP19 MDT2005 PB7 pin 13 */
+ /* nc MDT2005 PA3 pin 2 */
+ /* Remote MDT2005 PA2 pin 1 */
+ /* GP18 MDT2005 PA1 pin 18 */
+ /* nc MDT2005 PA0 pin 17 strap low */
- /* GP17 Strap "GP7"=High */
- /* GP16 Strap "GP6"=High
- 0=Radio 1=TV
- Drives SA630D ENCH1 and HEF4052 A1 pins
- to do FM radio through SIF input */
- /* GP15 nc */
- /* GP14 nc */
- /* GP13 nc */
- /* GP12 Strap "GP5" = High */
- /* GP11 Strap "GP4" = High */
- /* GP10 Strap "GP3" = High */
- /* GP09 Strap "GP2" = Low */
- /* GP08 Strap "GP1" = Low */
- /* GP07.00 nc */
+ /* GP17 Strap "GP7"=High */
+ /* GP16 Strap "GP6"=High
+ 0=Radio 1=TV
+ Drives SA630D ENCH1 and HEF4052 A1 pins
+ to do FM radio through SIF input */
+ /* GP15 nc */
+ /* GP14 nc */
+ /* GP13 nc */
+ /* GP12 Strap "GP5" = High */
+ /* GP11 Strap "GP4" = High */
+ /* GP10 Strap "GP3" = High */
+ /* GP09 Strap "GP2" = Low */
+ /* GP08 Strap "GP1" = Low */
+ /* GP07.00 nc */
diff --git a/Documentation/vm/hugetlbpage.txt b/Documentation/vm/hugetlbpage.txt
index 1b9bcd1fe98b..1ad9af1ca4d0 100644
--- a/Documentation/vm/hugetlbpage.txt
+++ b/Documentation/vm/hugetlbpage.txt
@@ -13,12 +13,13 @@ This optimization is more critical now as bigger and bigger physical memories
Users can use the huge page support in Linux kernel by either using the mmap
system call or standard SYSv shared memory system calls (shmget, shmat).
-First the Linux kernel needs to be built with CONFIG_HUGETLB_PAGE (present
-under Processor types and feature) and CONFIG_HUGETLBFS (present under file
-system option on config menu) config options.
+First the Linux kernel needs to be built with the CONFIG_HUGETLBFS
+(present under "File systems") and CONFIG_HUGETLB_PAGE (selected
+automatically when CONFIG_HUGETLBFS is selected) configuration
+options.
The kernel built with hugepage support should show the number of configured
-hugepages in the system by running the "cat /proc/meminfo" command.
+hugepages in the system by running the "cat /proc/meminfo" command.
/proc/meminfo also provides information about the total number of hugetlb
pages configured in the kernel. It also displays information about the
@@ -38,19 +39,19 @@ in the kernel.
/proc/sys/vm/nr_hugepages indicates the current number of configured hugetlb
pages in the kernel. Super user can dynamically request more (or free some
-pre-configured) hugepages.
-The allocation( or deallocation) of hugetlb pages is posible only if there are
+pre-configured) hugepages.
+The allocation (or deallocation) of hugetlb pages is possible only if there are
enough physically contiguous free pages in system (freeing of hugepages is
-possible only if there are enough hugetlb pages free that can be transfered
+possible only if there are enough hugetlb pages free that can be transfered
back to regular memory pool).
Pages that are used as hugetlb pages are reserved inside the kernel and can
-not be used for other purposes.
+not be used for other purposes.
Once the kernel with Hugetlb page support is built and running, a user can
use either the mmap system call or shared memory system calls to start using
the huge pages. It is required that the system administrator preallocate
-enough memory for huge page purposes.
+enough memory for huge page purposes.
Use the following command to dynamically allocate/deallocate hugepages:
@@ -80,9 +81,9 @@ memory (huge pages) allowed for that filesystem (/mnt/huge). The size is
rounded down to HPAGE_SIZE. The option nr_inode sets the maximum number of
inodes that /mnt/huge can use. If the size or nr_inode options are not
provided on command line then no limits are set. For size and nr_inodes
-options, you can use [G|g]/[M|m]/[K|k] to represent giga/mega/kilo. For
-example, size=2K has the same meaning as size=2048. An example is given at
-the end of this document.
+options, you can use [G|g]/[M|m]/[K|k] to represent giga/mega/kilo. For
+example, size=2K has the same meaning as size=2048. An example is given at
+the end of this document.
read and write system calls are not supported on files that reside on hugetlb
file systems.
diff --git a/MAINTAINERS b/MAINTAINERS
index 767fb610963e..0b03a88e88be 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -116,12 +116,6 @@ M: ajk@iehk.rwth-aachen.de
L: linux-hams@vger.kernel.org
S: Maintained
-YEALINK PHONE DRIVER
-P: Henk Vergonet
-M: Henk.Vergonet@gmail.com
-L: usbb2k-api-dev@nongnu.org
-S: Maintained
-
8139CP 10/100 FAST ETHERNET DRIVER
P: Jeff Garzik
M: jgarzik@pobox.com
@@ -197,6 +191,15 @@ M: Thorsten Knabe <linux@thorsten-knabe.de>
W: http://linux.thorsten-knabe.de
S: Maintained
+AD1889 SOUND DRIVER
+P: Kyle McMartin
+M: kyle@parisc-linux.org
+P: Thibaut Varene
+M: T-Bone@parisc-linux.org
+W: http://wiki.parisc-linux.org/AD1889
+L: parisc-linux@lists.parisc-linux.org
+S: Maintained
+
ADM1025 HARDWARE MONITOR DRIVER
P: Jean Delvare
M: khali@linux-fr.org
@@ -294,6 +297,11 @@ P: Richard Purdie
M: rpurdie@rpsys.net
S: Maintained
+ARM/TOSA MACHINE SUPPORT
+P: Dirk Opfer
+M: dirk@opfer-online.de
+S: Maintained
+
ARM/PLEB SUPPORT
P: Peter Chubb
M: pleb@gelato.unsw.edu.au
@@ -699,7 +707,7 @@ DCCP PROTOCOL
P: Arnaldo Carvalho de Melo
M: acme@mandriva.com
L: dccp@vger.kernel.org
-W: http://www.wlug.org.nz/DCCP
+W: http://linux-net.osdl.org/index.php/DCCP
S: Maintained
DECnet NETWORK LAYER
@@ -907,6 +915,15 @@ L: linux-fbdev-devel@lists.sourceforge.net
W: http://linux-fbdev.sourceforge.net/
S: Maintained
+FREESCALE SOC FS_ENET DRIVER
+P: Pantelis Antoniou
+M: pantelis.antoniou@gmail.com
+P: Vitaly Bordug
+M: vbordug@ru.mvista.com
+L: linuxppc-embedded@ozlabs.org
+L: netdev@vger.kernel.org
+S: Maintained
+
FILE LOCKING (flock() and fcntl()/lockf())
P: Matthew Wilcox
M: matthew@wil.cx
@@ -1060,6 +1077,26 @@ P: Jaroslav Kysela
M: perex@suse.cz
S: Maintained
+HPET: High Precision Event Timers driver (hpet.c)
+P: Clemens Ladisch
+M: clemens@ladisch.de
+S: Maintained
+
+HPET: i386
+P: Venkatesh Pallipadi (Venki)
+M: venkatesh.pallipadi@intel.com
+S: Maintained
+
+HPET: x86_64
+P: Andi Kleen and Vojtech Pavlik
+M: ak@muc.de and vojtech@suse.cz
+S: Maintained
+
+HPET: ACPI hpet.c
+P: Bob Picco
+M: bob.picco@hp.com
+S: Maintained
+
HPFS FILESYSTEM
P: Mikulas Patocka
M: mikulas@artax.karlin.mff.cuni.cz
@@ -1293,6 +1330,24 @@ M: john.ronciak@intel.com
W: http://sourceforge.net/projects/e1000/
S: Supported
+INTEL PRO/WIRELESS 2100 NETWORK CONNECTION SUPPORT
+P: Yi Zhu
+M: yi.zhu@intel.com
+P: James Ketrenos
+M: jketreno@linux.intel.com
+L: http://lists.sourceforge.net/mailman/listinfo/ipw2100-devel
+W: http://ipw2100.sourceforge.net
+S: Supported
+
+INTEL PRO/WIRELESS 2915ABG NETWORK CONNECTION SUPPORT
+P: Yi Zhu
+M: yi.zhu@intel.com
+P: James Ketrenos
+M: jketreno@linux.intel.com
+L: http://lists.sourceforge.net/mailman/listinfo/ipw2100-devel
+W: http://ipw2200.sourceforge.net
+S: Supported
+
IOC3 DRIVER
P: Ralf Baechle
M: ralf@linux-mips.org
@@ -1640,7 +1695,7 @@ S: Maintained
MIPS
P: Ralf Baechle
M: ralf@linux-mips.org
-W: http://oss.sgi.com/mips/mips-howto.html
+W: http://www.linux-mips.org/
L: linux-mips@linux-mips.org
S: Maintained
@@ -1942,6 +1997,14 @@ M: george@mvista.com
L: netdev@vger.kernel.org
S: Supported
+POWERPC 4xx EMAC DRIVER
+P: Eugene Surovegin
+M: ebs@ebshome.net
+W: http://kernel.ebshome.net/emac/
+L: linuxppc-embedded@ozlabs.org
+L: netdev@vger.kernel.org
+S: Maintained
+
PNP SUPPORT
P: Adam Belay
M: ambx1@neo.rr.com
@@ -2026,6 +2089,12 @@ P: Matt Mackall
M: mpm@selenic.com
S: Maintained
+RAPIDIO SUBSYSTEM
+P: Matt Porter
+M: mporter@kernel.crashing.org
+L: linux-kernel@vger.kernel.org
+S: Maintained
+
REAL TIME CLOCK DRIVER
P: Paul Gortmaker
M: p_gortmaker@yahoo.com
@@ -2275,6 +2344,11 @@ W: http://tpmdd.sourceforge.net
L: tpmdd-devel@lists.sourceforge.net
S: Maintained
+Telecom Clock Driver for MCPL0010
+P: Mark Gross
+M: mark.gross@intel.com
+S: Supported
+
TENSILICA XTENSA PORT (xtensa):
P: Chris Zankel
M: chris@zankel.net
@@ -2425,10 +2499,10 @@ L: linux-kernel@vger.kernel.org
S: Maintained
TRIVIAL PATCHES
-P: Rusty Russell
-M: trivial@rustcorp.com.au
+P: Adrian Bunk
+M: trivial@kernel.org
L: linux-kernel@vger.kernel.org
-W: http://www.kernel.org/pub/linux/kernel/people/rusty/trivial/
+W: http://www.kernel.org/pub/linux/kernel/people/bunk/trivial/
S: Maintained
TMS380 TOKEN-RING NETWORK DRIVER
@@ -2486,14 +2560,6 @@ L: linux-kernel@vger.kernel.org
L: linux-usb-devel@lists.sourceforge.net
S: Supported
-USB BLUETOOTH TTY CONVERTER DRIVER
-P: Greg Kroah-Hartman
-M: greg@kroah.com
-L: linux-usb-users@lists.sourceforge.net
-L: linux-usb-devel@lists.sourceforge.net
-S: Maintained
-W: http://www.kroah.com/linux-usb/
-
USB CDC ETHERNET DRIVER
P: Greg Kroah-Hartman
M: greg@kroah.com
@@ -2727,6 +2793,12 @@ P: Roger Luethi
M: rl@hellgate.ch
S: Maintained
+VIAPRO SMBUS DRIVER
+P: Jean Delvare
+M: khali@linux-fr.org
+L: lm-sensors@lm-sensors.org
+S: Maintained
+
UCLINUX (AND M68KNOMMU)
P: Greg Ungerer
M: gerg@uclinux.org
@@ -2848,6 +2920,12 @@ M: jpr@f6fbb.org
L: linux-hams@vger.kernel.org
S: Maintained
+YEALINK PHONE DRIVER
+P: Henk Vergonet
+M: Henk.Vergonet@gmail.com
+L: usbb2k-api-dev@nongnu.org
+S: Maintained
+
YMFPCI YAMAHA PCI SOUND (Use ALSA instead)
P: Pete Zaitcev
M: zaitcev@yahoo.com
diff --git a/Makefile b/Makefile
index 1fa7e5343464..6d1f727f4399 100644
--- a/Makefile
+++ b/Makefile
@@ -334,7 +334,7 @@ KALLSYMS = scripts/kallsyms
PERL = perl
CHECK = sparse
-CHECKFLAGS := -D__linux__ -Dlinux -D__STDC__ -Dunix -D__unix__ $(CF)
+CHECKFLAGS := -D__linux__ -Dlinux -D__STDC__ -Dunix -D__unix__ -Wbitwise $(CF)
MODFLAGS = -DMODULE
CFLAGS_MODULE = $(MODFLAGS)
AFLAGS_MODULE = $(MODFLAGS)
@@ -346,7 +346,8 @@ AFLAGS_KERNEL =
# Use LINUXINCLUDE when you must reference the include/ directory.
# Needed to be compatible with the O= option
LINUXINCLUDE := -Iinclude \
- $(if $(KBUILD_SRC),-Iinclude2 -I$(srctree)/include)
+ $(if $(KBUILD_SRC),-Iinclude2 -I$(srctree)/include) \
+ -include include/linux/autoconf.h
CPPFLAGS := -D__KERNEL__ $(LINUXINCLUDE)
@@ -371,8 +372,8 @@ export MODVERDIR := $(if $(KBUILD_EXTMOD),$(firstword $(KBUILD_EXTMOD))/).tmp_ve
# Files to ignore in find ... statements
-RCS_FIND_IGNORE := \( -name SCCS -o -name BitKeeper -o -name .svn -o -name CVS -o -name .pc -o -name .hg \) -prune -o
-export RCS_TAR_IGNORE := --exclude SCCS --exclude BitKeeper --exclude .svn --exclude CVS --exclude .pc --exclude .hg
+RCS_FIND_IGNORE := \( -name SCCS -o -name BitKeeper -o -name .svn -o -name CVS -o -name .pc -o -name .hg -o -name .git \) -prune -o
+export RCS_TAR_IGNORE := --exclude SCCS --exclude BitKeeper --exclude .svn --exclude CVS --exclude .pc --exclude .hg --exclude .git
# ===========================================================================
# Rules shared between *config targets and build targets
@@ -406,7 +407,7 @@ outputmakefile:
# of make so .config is not included in this case either (for *config).
no-dot-config-targets := clean mrproper distclean \
- cscope TAGS tags help %docs check%
+ cscope TAGS tags help %docs check% kernelrelease
config-targets := 0
mixed-targets := 0
@@ -582,7 +583,7 @@ export MODLIB
ifeq ($(KBUILD_EXTMOD),)
-core-y += kernel/ mm/ fs/ ipc/ security/ crypto/
+core-y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/
vmlinux-dirs := $(patsubst %/,%,$(filter %/, $(init-y) $(init-m) \
$(core-y) $(core-m) $(drivers-y) $(drivers-m) \
@@ -1249,11 +1250,6 @@ tags: FORCE
# Scripts to check various things for consistency
# ---------------------------------------------------------------------------
-configcheck:
- find * $(RCS_FIND_IGNORE) \
- -name '*.[hcS]' -type f -print | sort \
- | xargs $(PERL) -w scripts/checkconfig.pl
-
includecheck:
find * $(RCS_FIND_IGNORE) \
-name '*.[hcS]' -type f -print | sort \
diff --git a/README b/README
index d1edcc7adabe..4ee7dda88ba3 100644
--- a/README
+++ b/README
@@ -54,6 +54,10 @@ INSTALLING the kernel:
gzip -cd linux-2.6.XX.tar.gz | tar xvf -
+ or
+ bzip2 -dc linux-2.6.XX.tar.bz2 | tar xvf -
+
+
Replace "XX" with the version number of the latest kernel.
Do NOT use the /usr/src/linux area! This area has a (usually
diff --git a/arch/alpha/kernel/pci-noop.c b/arch/alpha/kernel/pci-noop.c
index 582a3519fb28..9903e3a79102 100644
--- a/arch/alpha/kernel/pci-noop.c
+++ b/arch/alpha/kernel/pci-noop.c
@@ -154,7 +154,7 @@ pci_dma_supported(struct pci_dev *hwdev, dma_addr_t mask)
void *
dma_alloc_coherent(struct device *dev, size_t size,
- dma_addr_t *dma_handle, int gfp)
+ dma_addr_t *dma_handle, gfp_t gfp)
{
void *ret;
diff --git a/arch/alpha/kernel/pci_iommu.c b/arch/alpha/kernel/pci_iommu.c
index 7cb23f12ecbd..c468e312e5f8 100644
--- a/arch/alpha/kernel/pci_iommu.c
+++ b/arch/alpha/kernel/pci_iommu.c
@@ -397,7 +397,7 @@ pci_alloc_consistent(struct pci_dev *pdev, size_t size, dma_addr_t *dma_addrp)
{
void *cpu_addr;
long order = get_order(size);
- int gfp = GFP_ATOMIC;
+ gfp_t gfp = GFP_ATOMIC;
try_again:
cpu_addr = (void *)__get_free_pages(gfp, order);
diff --git a/arch/alpha/kernel/process.c b/arch/alpha/kernel/process.c
index eb20c3afff58..a8682612abc0 100644
--- a/arch/alpha/kernel/process.c
+++ b/arch/alpha/kernel/process.c
@@ -43,21 +43,17 @@
#include "proto.h"
#include "pci_impl.h"
-void default_idle(void)
-{
- barrier();
-}
-
void
cpu_idle(void)
{
+ set_thread_flag(TIF_POLLING_NRFLAG);
+
while (1) {
- void (*idle)(void) = default_idle;
/* FIXME -- EV6 and LCA45 know how to power down
the CPU. */
while (!need_resched())
- idle();
+ cpu_relax();
schedule();
}
}
diff --git a/arch/alpha/kernel/time.c b/arch/alpha/kernel/time.c
index 67be50b7d80a..6b2921be1909 100644
--- a/arch/alpha/kernel/time.c
+++ b/arch/alpha/kernel/time.c
@@ -55,10 +55,6 @@
#include "proto.h"
#include "irq_impl.h"
-u64 jiffies_64 = INITIAL_JIFFIES;
-
-EXPORT_SYMBOL(jiffies_64);
-
extern unsigned long wall_jiffies; /* kernel/timer.c */
static int set_rtc_mmss(unsigned long);
diff --git a/arch/alpha/mm/numa.c b/arch/alpha/mm/numa.c
index c7481d59b6df..6d5251254f68 100644
--- a/arch/alpha/mm/numa.c
+++ b/arch/alpha/mm/numa.c
@@ -371,6 +371,8 @@ show_mem(void)
show_free_areas();
printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10));
for_each_online_node(nid) {
+ unsigned long flags;
+ pgdat_resize_lock(NODE_DATA(nid), &flags);
i = node_spanned_pages(nid);
while (i-- > 0) {
struct page *page = nid_page_nr(nid, i);
@@ -384,6 +386,7 @@ show_mem(void)
else
shared += page_count(page) - 1;
}
+ pgdat_resize_unlock(NODE_DATA(nid), &flags);
}
printk("%ld pages of RAM\n",total);
printk("%ld free pages\n",free);
diff --git a/arch/alpha/mm/remap.c b/arch/alpha/mm/remap.c
index 19817ad3d89b..a78356c3ead5 100644
--- a/arch/alpha/mm/remap.c
+++ b/arch/alpha/mm/remap.c
@@ -2,7 +2,6 @@
#include <asm/pgalloc.h>
#include <asm/cacheflush.h>
-/* called with the page_table_lock held */
static inline void
remap_area_pte(pte_t * pte, unsigned long address, unsigned long size,
unsigned long phys_addr, unsigned long flags)
@@ -31,7 +30,6 @@ remap_area_pte(pte_t * pte, unsigned long address, unsigned long size,
} while (address && (address < end));
}
-/* called with the page_table_lock held */
static inline int
remap_area_pmd(pmd_t * pmd, unsigned long address, unsigned long size,
unsigned long phys_addr, unsigned long flags)
@@ -46,7 +44,7 @@ remap_area_pmd(pmd_t * pmd, unsigned long address, unsigned long size,
if (address >= end)
BUG();
do {
- pte_t * pte = pte_alloc_kernel(&init_mm, pmd, address);
+ pte_t * pte = pte_alloc_kernel(pmd, address);
if (!pte)
return -ENOMEM;
remap_area_pte(pte, address, end - address,
@@ -70,7 +68,6 @@ __alpha_remap_area_pages(unsigned long address, unsigned long phys_addr,
flush_cache_all();
if (address >= end)
BUG();
- spin_lock(&init_mm.page_table_lock);
do {
pmd_t *pmd;
pmd = pmd_alloc(&init_mm, dir, address);
@@ -84,7 +81,6 @@ __alpha_remap_area_pages(unsigned long address, unsigned long phys_addr,
address = (address + PGDIR_SIZE) & PGDIR_MASK;
dir++;
} while (address && (address < end));
- spin_unlock(&init_mm.page_table_lock);
return error;
}
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 11fff042aa81..3df7cbd924a1 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -194,6 +194,13 @@ config ARCH_VERSATILE
help
This enables support for ARM Ltd Versatile board.
+config ARCH_REALVIEW
+ bool "RealView"
+ select ARM_AMBA
+ select ICST307
+ help
+ This enables support for ARM Ltd RealView boards.
+
config ARCH_IMX
bool "IMX"
@@ -204,6 +211,7 @@ config ARCH_H720X
config ARCH_AAEC2000
bool "Agilent AAEC-2000 based"
+ select ARM_AMBA
help
This enables support for systems based on the Agilent AAEC-2000
@@ -231,6 +239,8 @@ source "arch/arm/plat-omap/Kconfig"
source "arch/arm/mach-omap1/Kconfig"
+source "arch/arm/mach-omap2/Kconfig"
+
source "arch/arm/mach-s3c2410/Kconfig"
source "arch/arm/mach-lh7a40x/Kconfig"
@@ -243,6 +253,8 @@ source "arch/arm/mach-versatile/Kconfig"
source "arch/arm/mach-aaec2000/Kconfig"
+source "arch/arm/mach-realview/Kconfig"
+
# Definitions to make life easier
config ARCH_ACORN
bool
@@ -314,7 +326,7 @@ menu "Kernel Features"
config SMP
bool "Symmetric Multi-Processing (EXPERIMENTAL)"
- depends on EXPERIMENTAL && BROKEN #&& n
+ depends on EXPERIMENTAL && REALVIEW_MPCORE
help
This enables support for systems with more than one CPU. If you have
a system with only one CPU, like most personal computers, say N. If
@@ -339,6 +351,23 @@ config NR_CPUS
depends on SMP
default "4"
+config HOTPLUG_CPU
+ bool "Support for hot-pluggable CPUs (EXPERIMENTAL)"
+ depends on SMP && HOTPLUG && EXPERIMENTAL
+ help
+ Say Y here to experiment with turning CPUs off and on. CPUs
+ can be controlled through /sys/devices/system/cpu.
+
+config LOCAL_TIMERS
+ bool "Use local timer interrupts"
+ depends on SMP && REALVIEW_MPCORE
+ default y
+ help
+ Enable support for local timers on SMP platforms, rather then the
+ legacy IPI broadcast method. Local timers allows the system
+ accounting to be spread across the timer interval, preventing a
+ "thundering herd" at every timer tick.
+
config PREEMPT
bool "Preemptible Kernel (EXPERIMENTAL)"
depends on EXPERIMENTAL
@@ -568,7 +597,7 @@ config FPE_NWFPE
config FPE_NWFPE_XP
bool "Support extended precision"
- depends on FPE_NWFPE && !CPU_BIG_ENDIAN
+ depends on FPE_NWFPE
help
Say Y to include 80-bit support in the kernel floating-point
emulator. Otherwise, only 32 and 64-bit support is compiled in.
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 299bc0468702..81bd2193fe6d 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -8,7 +8,7 @@
# Copyright (C) 1995-2001 by Russell King
LDFLAGS_vmlinux :=-p --no-undefined -X
-CPPFLAGS_vmlinux.lds = -DTEXTADDR=$(TEXTADDR) -DDATAADDR=$(DATAADDR)
+CPPFLAGS_vmlinux.lds = -DKERNEL_RAM_ADDR=$(TEXTADDR)
OBJCOPYFLAGS :=-O binary -R .note -R .comment -S
GZFLAGS :=-9
#CFLAGS +=-pipe
@@ -38,6 +38,7 @@ comma = ,
# macro, but instead defines a whole series of macros which makes
# testing for a specific architecture or later rather impossible.
arch-$(CONFIG_CPU_32v6) :=-D__LINUX_ARM_ARCH__=6 $(call cc-option,-march=armv6,-march=armv5t -Wa$(comma)-march=armv6)
+arch-$(CONFIG_CPU_32v6K) :=-D__LINUX_ARM_ARCH__=6 $(call cc-option,-march=armv6k,-march=armv5t -Wa$(comma)-march=armv6k)
arch-$(CONFIG_CPU_32v5) :=-D__LINUX_ARM_ARCH__=5 $(call cc-option,-march=armv5te,-march=armv4)
arch-$(CONFIG_CPU_32v4) :=-D__LINUX_ARM_ARCH__=4 -march=armv4
arch-$(CONFIG_CPU_32v3) :=-D__LINUX_ARM_ARCH__=3 -march=armv3
@@ -92,6 +93,7 @@ textaddr-$(CONFIG_ARCH_FORTUNET) := 0xc0008000
machine-$(CONFIG_ARCH_IXP4XX) := ixp4xx
machine-$(CONFIG_ARCH_IXP2000) := ixp2000
machine-$(CONFIG_ARCH_OMAP1) := omap1
+ machine-$(CONFIG_ARCH_OMAP2) := omap2
incdir-$(CONFIG_ARCH_OMAP) := omap
machine-$(CONFIG_ARCH_S3C2410) := s3c2410
machine-$(CONFIG_ARCH_LH7A40X) := lh7a40x
@@ -99,6 +101,7 @@ textaddr-$(CONFIG_ARCH_FORTUNET) := 0xc0008000
machine-$(CONFIG_ARCH_IMX) := imx
machine-$(CONFIG_ARCH_H720X) := h720x
machine-$(CONFIG_ARCH_AAEC2000) := aaec2000
+ machine-$(CONFIG_ARCH_REALVIEW) := realview
ifeq ($(CONFIG_ARCH_EBSA110),y)
# This is what happens if you forget the IOCS16 line.
@@ -108,27 +111,19 @@ export CFLAGS_3c589_cs.o
endif
TEXTADDR := $(textaddr-y)
-ifeq ($(CONFIG_XIP_KERNEL),y)
- DATAADDR := $(TEXTADDR)
- xipaddr-$(CONFIG_ARCH_CO285) := 0x5f000000
- xipaddr-y ?= 0xbf000000
- # Replace phys addr with virt addr while keeping offset from base.
- TEXTADDR := $(shell echo $(CONFIG_XIP_PHYS_ADDR) $(xipaddr-y) | \
- awk --non-decimal-data '/[:xdigit:]/ \
- { printf("0x%x\n", and($$1, 0x000fffff) + $$2) }' )
-endif
ifeq ($(incdir-y),)
incdir-y := $(machine-y)
endif
INCDIR := arch-$(incdir-y)
+
ifneq ($(machine-y),)
MACHINE := arch/arm/mach-$(machine-y)/
else
MACHINE :=
endif
-export TEXTADDR DATAADDR GZFLAGS
+export TEXTADDR GZFLAGS
# Do we have FASTFPE?
FASTFPE :=arch/arm/fastfpe
@@ -150,7 +145,7 @@ drivers-$(CONFIG_OPROFILE) += arch/arm/oprofile/
drivers-$(CONFIG_ARCH_CLPS7500) += drivers/acorn/char/
drivers-$(CONFIG_ARCH_L7200) += drivers/acorn/char/
-libs-y += arch/arm/lib/
+libs-y := arch/arm/lib/ $(libs-y)
# Default target when executing plain make
ifeq ($(CONFIG_XIP_KERNEL),y)
diff --git a/arch/arm/boot/compressed/misc.c b/arch/arm/boot/compressed/misc.c
index 23434b56786a..5ab94584baee 100644
--- a/arch/arm/boot/compressed/misc.c
+++ b/arch/arm/boot/compressed/misc.c
@@ -30,7 +30,7 @@ unsigned int __machine_arch_type;
#define putstr icedcc_putstr
#define putc icedcc_putc
-extern void idedcc_putc(int ch);
+extern void icedcc_putc(int ch);
static void
icedcc_putstr(const char *ptr)
@@ -283,8 +283,14 @@ void flush_window(void)
putstr(".");
}
+#ifndef arch_error
+#define arch_error(x)
+#endif
+
static void error(char *x)
{
+ arch_error(x);
+
putstr("\n\n");
putstr(x);
putstr("\n\n -- System halted");
diff --git a/arch/arm/common/amba.c b/arch/arm/common/amba.c
index c6beb751f2a9..e1013112c354 100644
--- a/arch/arm/common/amba.c
+++ b/arch/arm/common/amba.c
@@ -10,6 +10,8 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/device.h>
+#include <linux/string.h>
+#include <linux/slab.h>
#include <asm/io.h>
#include <asm/irq.h>
diff --git a/arch/arm/common/dmabounce.c b/arch/arm/common/dmabounce.c
index cbf2165476b0..ad6c89a555bb 100644
--- a/arch/arm/common/dmabounce.c
+++ b/arch/arm/common/dmabounce.c
@@ -33,8 +33,8 @@
#include <asm/cacheflush.h>
#undef DEBUG
-
#undef STATS
+
#ifdef STATS
#define DO_STATS(X) do { X ; } while (0)
#else
@@ -52,26 +52,31 @@ struct safe_buffer {
int direction;
/* safe buffer info */
- struct dma_pool *pool;
+ struct dmabounce_pool *pool;
void *safe;
dma_addr_t safe_dma_addr;
};
+struct dmabounce_pool {
+ unsigned long size;
+ struct dma_pool *pool;
+#ifdef STATS
+ unsigned long allocs;
+#endif
+};
+
struct dmabounce_device_info {
struct list_head node;
struct device *dev;
- struct dma_pool *small_buffer_pool;
- struct dma_pool *large_buffer_pool;
struct list_head safe_buffers;
- unsigned long small_buffer_size, large_buffer_size;
#ifdef STATS
- unsigned long sbp_allocs;
- unsigned long lbp_allocs;
unsigned long total_allocs;
unsigned long map_op_count;
unsigned long bounce_count;
#endif
+ struct dmabounce_pool small;
+ struct dmabounce_pool large;
};
static LIST_HEAD(dmabounce_devs);
@@ -82,9 +87,9 @@ static void print_alloc_stats(struct dmabounce_device_info *device_info)
printk(KERN_INFO
"%s: dmabounce: sbp: %lu, lbp: %lu, other: %lu, total: %lu\n",
device_info->dev->bus_id,
- device_info->sbp_allocs, device_info->lbp_allocs,
- device_info->total_allocs - device_info->sbp_allocs -
- device_info->lbp_allocs,
+ device_info->small.allocs, device_info->large.allocs,
+ device_info->total_allocs - device_info->small.allocs -
+ device_info->large.allocs,
device_info->total_allocs);
}
#endif
@@ -106,18 +111,22 @@ find_dmabounce_dev(struct device *dev)
/* allocate a 'safe' buffer and keep track of it */
static inline struct safe_buffer *
alloc_safe_buffer(struct dmabounce_device_info *device_info, void *ptr,
- size_t size, enum dma_data_direction dir)
+ size_t size, enum dma_data_direction dir)
{
struct safe_buffer *buf;
- struct dma_pool *pool;
+ struct dmabounce_pool *pool;
struct device *dev = device_info->dev;
- void *safe;
- dma_addr_t safe_dma_addr;
dev_dbg(dev, "%s(ptr=%p, size=%d, dir=%d)\n",
__func__, ptr, size, dir);
- DO_STATS ( device_info->total_allocs++ );
+ if (size <= device_info->small.size) {
+ pool = &device_info->small;
+ } else if (size <= device_info->large.size) {
+ pool = &device_info->large;
+ } else {
+ pool = NULL;
+ }
buf = kmalloc(sizeof(struct safe_buffer), GFP_ATOMIC);
if (buf == NULL) {
@@ -125,41 +134,35 @@ alloc_safe_buffer(struct dmabounce_device_info *device_info, void *ptr,
return NULL;
}
- if (size <= device_info->small_buffer_size) {
- pool = device_info->small_buffer_pool;
- safe = dma_pool_alloc(pool, GFP_ATOMIC, &safe_dma_addr);
-
- DO_STATS ( device_info->sbp_allocs++ );
- } else if (size <= device_info->large_buffer_size) {
- pool = device_info->large_buffer_pool;
- safe = dma_pool_alloc(pool, GFP_ATOMIC, &safe_dma_addr);
+ buf->ptr = ptr;
+ buf->size = size;
+ buf->direction = dir;
+ buf->pool = pool;
- DO_STATS ( device_info->lbp_allocs++ );
+ if (pool) {
+ buf->safe = dma_pool_alloc(pool->pool, GFP_ATOMIC,
+ &buf->safe_dma_addr);
} else {
- pool = NULL;
- safe = dma_alloc_coherent(dev, size, &safe_dma_addr, GFP_ATOMIC);
+ buf->safe = dma_alloc_coherent(dev, size, &buf->safe_dma_addr,
+ GFP_ATOMIC);
}
- if (safe == NULL) {
- dev_warn(device_info->dev,
- "%s: could not alloc dma memory (size=%d)\n",
- __func__, size);
+ if (buf->safe == NULL) {
+ dev_warn(dev,
+ "%s: could not alloc dma memory (size=%d)\n",
+ __func__, size);
kfree(buf);
return NULL;
}
#ifdef STATS
+ if (pool)
+ pool->allocs++;
+ device_info->total_allocs++;
if (device_info->total_allocs % 1000 == 0)
print_alloc_stats(device_info);
#endif
- buf->ptr = ptr;
- buf->size = size;
- buf->direction = dir;
- buf->pool = pool;
- buf->safe = safe;
- buf->safe_dma_addr = safe_dma_addr;
-
list_add(&buf->node, &device_info->safe_buffers);
return buf;
@@ -186,7 +189,7 @@ free_safe_buffer(struct dmabounce_device_info *device_info, struct safe_buffer *
list_del(&buf->node);
if (buf->pool)
- dma_pool_free(buf->pool, buf->safe, buf->safe_dma_addr);
+ dma_pool_free(buf->pool->pool, buf->safe, buf->safe_dma_addr);
else
dma_free_coherent(device_info->dev, buf->size, buf->safe,
buf->safe_dma_addr);
@@ -197,12 +200,10 @@ free_safe_buffer(struct dmabounce_device_info *device_info, struct safe_buffer *
/* ************************************************** */
#ifdef STATS
-
static void print_map_stats(struct dmabounce_device_info *device_info)
{
- printk(KERN_INFO
- "%s: dmabounce: map_op_count=%lu, bounce_count=%lu\n",
- device_info->dev->bus_id,
+ dev_info(device_info->dev,
+ "dmabounce: map_op_count=%lu, bounce_count=%lu\n",
device_info->map_op_count, device_info->bounce_count);
}
#endif
@@ -258,13 +259,13 @@ map_single(struct device *dev, void *ptr, size_t size,
__func__, ptr, buf->safe, size);
memcpy(buf->safe, ptr, size);
}
- consistent_sync(buf->safe, size, dir);
+ ptr = buf->safe;
dma_addr = buf->safe_dma_addr;
- } else {
- consistent_sync(ptr, size, dir);
}
+ consistent_sync(ptr, size, dir);
+
return dma_addr;
}
@@ -278,7 +279,7 @@ unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
/*
* Trying to unmap an invalid mapping
*/
- if (dma_addr == ~0) {
+ if (dma_mapping_error(dma_addr)) {
dev_err(dev, "Trying to unmap invalid mapping\n");
return;
}
@@ -570,11 +571,25 @@ dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nents,
local_irq_restore(flags);
}
+static int
+dmabounce_init_pool(struct dmabounce_pool *pool, struct device *dev, const char *name,
+ unsigned long size)
+{
+ pool->size = size;
+ DO_STATS(pool->allocs = 0);
+ pool->pool = dma_pool_create(name, dev, size,
+ 0 /* byte alignment */,
+ 0 /* no page-crossing issues */);
+
+ return pool->pool ? 0 : -ENOMEM;
+}
+
int
dmabounce_register_dev(struct device *dev, unsigned long small_buffer_size,
unsigned long large_buffer_size)
{
struct dmabounce_device_info *device_info;
+ int ret;
device_info = kmalloc(sizeof(struct dmabounce_device_info), GFP_ATOMIC);
if (!device_info) {
@@ -584,45 +599,31 @@ dmabounce_register_dev(struct device *dev, unsigned long small_buffer_size,
return -ENOMEM;
}
- device_info->small_buffer_pool =
- dma_pool_create("small_dmabounce_pool",
- dev,
- small_buffer_size,
- 0 /* byte alignment */,
- 0 /* no page-crossing issues */);
- if (!device_info->small_buffer_pool) {
- printk(KERN_ERR
- "dmabounce: could not allocate small DMA pool for %s\n",
- dev->bus_id);
- kfree(device_info);
- return -ENOMEM;
+ ret = dmabounce_init_pool(&device_info->small, dev,
+ "small_dmabounce_pool", small_buffer_size);
+ if (ret) {
+ dev_err(dev,
+ "dmabounce: could not allocate DMA pool for %ld byte objects\n",
+ small_buffer_size);
+ goto err_free;
}
if (large_buffer_size) {
- device_info->large_buffer_pool =
- dma_pool_create("large_dmabounce_pool",
- dev,
- large_buffer_size,
- 0 /* byte alignment */,
- 0 /* no page-crossing issues */);
- if (!device_info->large_buffer_pool) {
- printk(KERN_ERR
- "dmabounce: could not allocate large DMA pool for %s\n",
- dev->bus_id);
- dma_pool_destroy(device_info->small_buffer_pool);
-
- return -ENOMEM;
+ ret = dmabounce_init_pool(&device_info->large, dev,
+ "large_dmabounce_pool",
+ large_buffer_size);
+ if (ret) {
+ dev_err(dev,
+ "dmabounce: could not allocate DMA pool for %ld byte objects\n",
+ large_buffer_size);
+ goto err_destroy;
}
}
device_info->dev = dev;
- device_info->small_buffer_size = small_buffer_size;
- device_info->large_buffer_size = large_buffer_size;
INIT_LIST_HEAD(&device_info->safe_buffers);
#ifdef STATS
- device_info->sbp_allocs = 0;
- device_info->lbp_allocs = 0;
device_info->total_allocs = 0;
device_info->map_op_count = 0;
device_info->bounce_count = 0;
@@ -634,6 +635,12 @@ dmabounce_register_dev(struct device *dev, unsigned long small_buffer_size,
dev->bus_id, dev->bus->name);
return 0;
+
+ err_destroy:
+ dma_pool_destroy(device_info->small.pool);
+ err_free:
+ kfree(device_info);
+ return ret;
}
void
@@ -655,10 +662,10 @@ dmabounce_unregister_dev(struct device *dev)
BUG();
}
- if (device_info->small_buffer_pool)
- dma_pool_destroy(device_info->small_buffer_pool);
- if (device_info->large_buffer_pool)
- dma_pool_destroy(device_info->large_buffer_pool);
+ if (device_info->small.pool)
+ dma_pool_destroy(device_info->small.pool);
+ if (device_info->large.pool)
+ dma_pool_destroy(device_info->large.pool);
#ifdef STATS
print_alloc_stats(device_info);
diff --git a/arch/arm/common/locomo.c b/arch/arm/common/locomo.c
index e8053d16829b..ad55680726ed 100644
--- a/arch/arm/common/locomo.c
+++ b/arch/arm/common/locomo.c
@@ -22,7 +22,7 @@
#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/ioport.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
@@ -550,15 +550,12 @@ struct locomo_save_data {
u16 LCM_SPIMD;
};
-static int locomo_suspend(struct device *dev, pm_message_t state, u32 level)
+static int locomo_suspend(struct device *dev, pm_message_t state)
{
struct locomo *lchip = dev_get_drvdata(dev);
struct locomo_save_data *save;
unsigned long flags;
- if (level != SUSPEND_DISABLE)
- return 0;
-
save = kmalloc(sizeof(struct locomo_save_data), GFP_KERNEL);
if (!save)
return -ENOMEM;
@@ -597,16 +594,13 @@ static int locomo_suspend(struct device *dev, pm_message_t state, u32 level)
return 0;
}
-static int locomo_resume(struct device *dev, u32 level)
+static int locomo_resume(struct device *dev)
{
struct locomo *lchip = dev_get_drvdata(dev);
struct locomo_save_data *save;
unsigned long r;
unsigned long flags;
- if (level != RESUME_ENABLE)
- return 0;
-
save = (struct locomo_save_data *) dev->power.saved_state;
if (!save)
return 0;
diff --git a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c
index 1a47fbf9cbbc..174aa86ee816 100644
--- a/arch/arm/common/sa1111.c
+++ b/arch/arm/common/sa1111.c
@@ -22,7 +22,7 @@
#include <linux/ptrace.h>
#include <linux/errno.h>
#include <linux/ioport.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/dma-mapping.h>
@@ -801,7 +801,7 @@ struct sa1111_save_data {
#ifdef CONFIG_PM
-static int sa1111_suspend(struct device *dev, pm_message_t state, u32 level)
+static int sa1111_suspend(struct device *dev, pm_message_t state)
{
struct sa1111 *sachip = dev_get_drvdata(dev);
struct sa1111_save_data *save;
@@ -809,9 +809,6 @@ static int sa1111_suspend(struct device *dev, pm_message_t state, u32 level)
unsigned int val;
void __iomem *base;
- if (level != SUSPEND_DISABLE)
- return 0;
-
save = kmalloc(sizeof(struct sa1111_save_data), GFP_KERNEL);
if (!save)
return -ENOMEM;
@@ -856,23 +853,19 @@ static int sa1111_suspend(struct device *dev, pm_message_t state, u32 level)
/*
* sa1111_resume - Restore the SA1111 device state.
* @dev: device to restore
- * @level: resume level
*
* Restore the general state of the SA1111; clock control and
* interrupt controller. Other parts of the SA1111 must be
* restored by their respective drivers, and must be called
* via LDM after this function.
*/
-static int sa1111_resume(struct device *dev, u32 level)
+static int sa1111_resume(struct device *dev)
{
struct sa1111 *sachip = dev_get_drvdata(dev);
struct sa1111_save_data *save;
unsigned long flags, id;
void __iomem *base;
- if (level != RESUME_ENABLE)
- return 0;
-
save = (struct sa1111_save_data *)dev->power.saved_state;
if (!save)
return 0;
diff --git a/arch/arm/common/scoop.c b/arch/arm/common/scoop.c
index 9e5245c702de..c7fdf390cef9 100644
--- a/arch/arm/common/scoop.c
+++ b/arch/arm/common/scoop.c
@@ -12,17 +12,13 @@
*/
#include <linux/device.h>
+#include <linux/string.h>
+#include <linux/platform_device.h>
#include <asm/io.h>
#include <asm/hardware/scoop.h>
#define SCOOP_REG(d,adr) (*(volatile unsigned short*)(d +(adr)))
-/* PCMCIA to Scoop linkage structures for pxa2xx_sharpsl.c
- There is no easy way to link multiple scoop devices into one
- single entity for the pxa2xx_pcmcia device */
-int scoop_num;
-struct scoop_pcmcia_dev *scoop_devs;
-
struct scoop_dev {
void *base;
spinlock_t scoop_lock;
@@ -102,26 +98,24 @@ static void check_scoop_reg(struct scoop_dev *sdev)
}
#ifdef CONFIG_PM
-static int scoop_suspend(struct device *dev, pm_message_t state, uint32_t level)
+static int scoop_suspend(struct device *dev, pm_message_t state)
{
- if (level == SUSPEND_POWER_DOWN) {
- struct scoop_dev *sdev = dev_get_drvdata(dev);
+ struct scoop_dev *sdev = dev_get_drvdata(dev);
+
+ check_scoop_reg(sdev);
+ sdev->scoop_gpwr = SCOOP_REG(sdev->base, SCOOP_GPWR);
+ SCOOP_REG(sdev->base, SCOOP_GPWR) = (sdev->scoop_gpwr & ~sdev->suspend_clr) | sdev->suspend_set;
- check_scoop_reg(sdev);
- sdev->scoop_gpwr = SCOOP_REG(sdev->base, SCOOP_GPWR);
- SCOOP_REG(sdev->base, SCOOP_GPWR) = (sdev->scoop_gpwr & ~sdev->suspend_clr) | sdev->suspend_set;
- }
return 0;
}
-static int scoop_resume(struct device *dev, uint32_t level)
+static int scoop_resume(struct device *dev)
{
- if (level == RESUME_POWER_ON) {
- struct scoop_dev *sdev = dev_get_drvdata(dev);
+ struct scoop_dev *sdev = dev_get_drvdata(dev);
+
+ check_scoop_reg(sdev);
+ SCOOP_REG(sdev->base,SCOOP_GPWR) = sdev->scoop_gpwr;
- check_scoop_reg(sdev);
- SCOOP_REG(sdev->base,SCOOP_GPWR) = sdev->scoop_gpwr;
- }
return 0;
}
#else
diff --git a/arch/arm/configs/ixdp2400_defconfig b/arch/arm/configs/ixdp2400_defconfig
index 678720fa2e2e..ddeb9f99d662 100644
--- a/arch/arm/configs/ixdp2400_defconfig
+++ b/arch/arm/configs/ixdp2400_defconfig
@@ -559,7 +559,7 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
#
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_NR_UARTS=2
+CONFIG_SERIAL_8250_NR_UARTS=1
# CONFIG_SERIAL_8250_EXTENDED is not set
#
diff --git a/arch/arm/configs/ixdp2401_defconfig b/arch/arm/configs/ixdp2401_defconfig
index 38c9a721d5c9..32bd552e0986 100644
--- a/arch/arm/configs/ixdp2401_defconfig
+++ b/arch/arm/configs/ixdp2401_defconfig
@@ -152,7 +152,7 @@ CONFIG_ALIGNMENT_TRAP=y
#
CONFIG_ZBOOT_ROM_TEXT=0x0
CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="console=ttyS0,57600 root=/dev/nfs ip=bootp mem=64M@0x0 pci=firmware"
+CONFIG_CMDLINE="console=ttyS0,115200 root=/dev/nfs ip=bootp mem=64M@0x0 pci=firmware"
# CONFIG_XIP_KERNEL is not set
#
@@ -560,7 +560,7 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
#
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_NR_UARTS=2
+CONFIG_SERIAL_8250_NR_UARTS=3
# CONFIG_SERIAL_8250_EXTENDED is not set
#
diff --git a/arch/arm/configs/ixdp2800_defconfig b/arch/arm/configs/ixdp2800_defconfig
index 261e2343903b..81d3a0606f95 100644
--- a/arch/arm/configs/ixdp2800_defconfig
+++ b/arch/arm/configs/ixdp2800_defconfig
@@ -559,7 +559,7 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
#
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_NR_UARTS=2
+CONFIG_SERIAL_8250_NR_UARTS=1
# CONFIG_SERIAL_8250_EXTENDED is not set
#
diff --git a/arch/arm/configs/ixdp2801_defconfig b/arch/arm/configs/ixdp2801_defconfig
index 12ef23d1c016..66ac0885df3e 100644
--- a/arch/arm/configs/ixdp2801_defconfig
+++ b/arch/arm/configs/ixdp2801_defconfig
@@ -560,7 +560,7 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
#
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_NR_UARTS=2
+CONFIG_SERIAL_8250_NR_UARTS=3
# CONFIG_SERIAL_8250_EXTENDED is not set
#
diff --git a/arch/arm/configs/ixp4xx_defconfig b/arch/arm/configs/ixp4xx_defconfig
index c279e41ed10e..f74c926beb42 100644
--- a/arch/arm/configs/ixp4xx_defconfig
+++ b/arch/arm/configs/ixp4xx_defconfig
@@ -104,7 +104,7 @@ CONFIG_ARCH_IXCDP1100=y
CONFIG_ARCH_PRPMC1100=y
CONFIG_ARCH_IXDP4XX=y
CONFIG_CPU_IXP46X=y
-CONFIG_MACH_GTWX5715=y
+# CONFIG_MACH_GTWX5715 is not set
#
# IXP4xx Options
diff --git a/arch/arm/configs/omap_h2_1610_defconfig b/arch/arm/configs/omap_h2_1610_defconfig
index 4198677cd394..529f0f72e1e9 100644
--- a/arch/arm/configs/omap_h2_1610_defconfig
+++ b/arch/arm/configs/omap_h2_1610_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.13
-# Mon Sep 5 18:07:12 2005
+# Linux kernel version: 2.6.14
+# Wed Nov 9 18:53:40 2005
#
CONFIG_ARM=y
CONFIG_MMU=y
@@ -22,6 +22,7 @@ CONFIG_INIT_ENV_ARG_LIMIT=32
# General setup
#
CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
# CONFIG_POSIX_MQUEUE is not set
@@ -31,6 +32,7 @@ CONFIG_SYSCTL=y
# CONFIG_HOTPLUG is not set
CONFIG_KOBJECT_UEVENT=y
# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
# CONFIG_EMBEDDED is not set
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
@@ -60,6 +62,23 @@ CONFIG_OBSOLETE_MODPARM=y
# CONFIG_KMOD is not set
#
+# Block layer
+#
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
+#
# System Type
#
# CONFIG_ARCH_CLPS7500 is not set
@@ -81,6 +100,7 @@ CONFIG_OBSOLETE_MODPARM=y
# CONFIG_ARCH_LH7A40X is not set
CONFIG_ARCH_OMAP=y
# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_REALVIEW is not set
# CONFIG_ARCH_IMX is not set
# CONFIG_ARCH_H720X is not set
# CONFIG_ARCH_AAEC2000 is not set
@@ -112,7 +132,7 @@ CONFIG_OMAP_SERIAL_WAKE=y
# OMAP Core Type
#
# CONFIG_ARCH_OMAP730 is not set
-# CONFIG_ARCH_OMAP1510 is not set
+# CONFIG_ARCH_OMAP15XX is not set
CONFIG_ARCH_OMAP16XX=y
#
@@ -177,6 +197,8 @@ CONFIG_FLATMEM_MANUAL=y
# CONFIG_SPARSEMEM_MANUAL is not set
CONFIG_FLATMEM=y
CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4096
# CONFIG_LEDS is not set
CONFIG_ALIGNMENT_TRAP=y
@@ -258,14 +280,19 @@ CONFIG_IP_PNP_BOOTP=y
# CONFIG_INET_ESP is not set
# CONFIG_INET_IPCOMP is not set
# CONFIG_INET_TUNNEL is not set
-CONFIG_IP_TCPDIAG=y
-# CONFIG_IP_TCPDIAG_IPV6 is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
# CONFIG_TCP_CONG_ADVANCED is not set
CONFIG_TCP_CONG_BIC=y
# CONFIG_IPV6 is not set
# CONFIG_NETFILTER is not set
#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
# SCTP Configuration (EXPERIMENTAL)
#
# CONFIG_IP_SCTP is not set
@@ -281,6 +308,10 @@ CONFIG_TCP_CONG_BIC=y
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
# CONFIG_NET_SCHED is not set
# CONFIG_NET_CLS_ROUTE is not set
@@ -291,6 +322,7 @@ CONFIG_TCP_CONG_BIC=y
# CONFIG_HAMRADIO is not set
# CONFIG_IRDA is not set
# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
#
# Device Drivers
@@ -328,21 +360,13 @@ CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=8192
CONFIG_BLK_DEV_INITRD=y
-CONFIG_INITRAMFS_SOURCE=""
# CONFIG_CDROM_PKTCDVD is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
CONFIG_ATA_OVER_ETH=m
#
# SCSI device support
#
+# CONFIG_RAID_ATTRS is not set
CONFIG_SCSI=y
CONFIG_SCSI_PROC_FS=y
@@ -369,10 +393,12 @@ CONFIG_SCSI_PROC_FS=y
# CONFIG_SCSI_SPI_ATTRS is not set
# CONFIG_SCSI_FC_ATTRS is not set
# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_ATTRS is not set
#
# SCSI low-level drivers
#
+# CONFIG_ISCSI_TCP is not set
# CONFIG_SCSI_SATA is not set
# CONFIG_SCSI_DEBUG is not set
@@ -404,6 +430,11 @@ CONFIG_NETDEVICES=y
# CONFIG_TUN is not set
#
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
+#
# Ethernet (10 or 100Mbit)
#
CONFIG_NET_ETHERNET=y
@@ -439,6 +470,7 @@ CONFIG_PPP=y
# CONFIG_PPP_SYNC_TTY is not set
# CONFIG_PPP_DEFLATE is not set
# CONFIG_PPP_BSDCOMP is not set
+# CONFIG_PPP_MPPE is not set
# CONFIG_PPPOE is not set
CONFIG_SLIP=y
CONFIG_SLIP_COMPRESSED=y
@@ -541,18 +573,18 @@ CONFIG_WATCHDOG_NOWAYOUT=y
#
# TPM devices
#
+# CONFIG_TELCLOCK is not set
#
# I2C support
#
# CONFIG_I2C is not set
-# CONFIG_I2C_SENSOR is not set
-CONFIG_ISP1301_OMAP=y
#
# Hardware Monitoring support
#
CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
# CONFIG_HWMON_DEBUG_CHIP is not set
#
@@ -560,6 +592,10 @@ CONFIG_HWMON=y
#
#
+# Multimedia Capabilities Port drivers
+#
+
+#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
@@ -576,7 +612,6 @@ CONFIG_FB=y
# CONFIG_FB_CFB_FILLRECT is not set
# CONFIG_FB_CFB_COPYAREA is not set
# CONFIG_FB_CFB_IMAGEBLIT is not set
-# CONFIG_FB_SOFT_CURSOR is not set
# CONFIG_FB_MACMODES is not set
CONFIG_FB_MODE_HELPERS=y
# CONFIG_FB_TILEBLITTING is not set
@@ -589,6 +624,7 @@ CONFIG_FB_MODE_HELPERS=y
# CONFIG_VGA_CONSOLE is not set
CONFIG_DUMMY_CONSOLE=y
CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
CONFIG_FONTS=y
CONFIG_FONT_8x8=y
CONFIG_FONT_8x16=y
@@ -600,6 +636,7 @@ CONFIG_FONT_8x16=y
# CONFIG_FONT_SUN8x16 is not set
# CONFIG_FONT_SUN12x22 is not set
# CONFIG_FONT_10x18 is not set
+# CONFIG_FONT_RL is not set
#
# Logo configuration
@@ -624,10 +661,10 @@ CONFIG_SOUND=y
# Open Sound System
#
CONFIG_SOUND_PRIME=y
+# CONFIG_OBSOLETE_OSS_DRIVER is not set
# CONFIG_SOUND_MSNDCLAS is not set
# CONFIG_SOUND_MSNDPIN is not set
# CONFIG_SOUND_OSS is not set
-# CONFIG_SOUND_AD1980 is not set
#
# USB support
@@ -637,22 +674,21 @@ CONFIG_USB_ARCH_HAS_OHCI=y
# CONFIG_USB is not set
#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
# USB Gadget Support
#
-CONFIG_USB_GADGET=y
-# CONFIG_USB_GADGET_DEBUG_FILES is not set
-CONFIG_USB_GADGET_SELECTED=y
+# CONFIG_USB_GADGET is not set
# CONFIG_USB_GADGET_NET2280 is not set
# CONFIG_USB_GADGET_PXA2XX is not set
# CONFIG_USB_GADGET_GOKU is not set
# CONFIG_USB_GADGET_LH7A40X is not set
-CONFIG_USB_GADGET_OMAP=y
-CONFIG_USB_OMAP=y
+# CONFIG_USB_GADGET_OMAP is not set
# CONFIG_USB_GADGET_DUMMY_HCD is not set
-# CONFIG_USB_GADGET_DUALSPEED is not set
# CONFIG_USB_ZERO is not set
-CONFIG_USB_ETH=y
-CONFIG_USB_ETH_RNDIS=y
+# CONFIG_USB_ETH is not set
# CONFIG_USB_GADGETFS is not set
# CONFIG_USB_FILE_STORAGE is not set
# CONFIG_USB_G_SERIAL is not set
@@ -673,10 +709,6 @@ CONFIG_EXT2_FS=y
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
# CONFIG_FS_POSIX_ACL is not set
-
-#
-# XFS support
-#
# CONFIG_XFS_FS is not set
# CONFIG_MINIX_FS is not set
CONFIG_ROMFS_FS=y
@@ -685,6 +717,7 @@ CONFIG_INOTIFY=y
CONFIG_DNOTIFY=y
# CONFIG_AUTOFS_FS is not set
# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
#
# CD-ROM/DVD Filesystems
@@ -706,10 +739,10 @@ CONFIG_FAT_DEFAULT_CODEPAGE=437
#
CONFIG_PROC_FS=y
CONFIG_SYSFS=y
-# CONFIG_DEVPTS_FS_XATTR is not set
# CONFIG_TMPFS is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
+# CONFIG_RELAYFS_FS is not set
#
# Miscellaneous filesystems
@@ -750,6 +783,7 @@ CONFIG_RPCSEC_GSS_KRB5=y
# CONFIG_NCP_FS is not set
# CONFIG_CODA_FS is not set
# CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
#
# Partition Types
@@ -859,6 +893,7 @@ CONFIG_CRYPTO_DES=y
# Library routines
#
# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
CONFIG_CRC32=y
# CONFIG_LIBCRC32C is not set
CONFIG_ZLIB_INFLATE=y
diff --git a/arch/arm/configs/realview_defconfig b/arch/arm/configs/realview_defconfig
new file mode 100644
index 000000000000..0485b2f1cc20
--- /dev/null
+++ b/arch/arm/configs/realview_defconfig
@@ -0,0 +1,789 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.14-rc2
+# Thu Sep 29 14:50:10 2005
+#
+CONFIG_ARM=y
+CONFIG_MMU=y
+CONFIG_UID16=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+
+#
+# Code maturity level options
+#
+# CONFIG_EXPERIMENTAL is not set
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_HOTPLUG=y
+CONFIG_KOBJECT_UEVENT=y
+# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_EMBEDDED is not set
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_OBSOLETE_MODPARM=y
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+# CONFIG_KMOD is not set
+
+#
+# System Type
+#
+# 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_CAMELOT is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_IOP3XX is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_L7200 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_OMAP is not set
+# CONFIG_ARCH_VERSATILE is not set
+CONFIG_ARCH_REALVIEW=y
+# CONFIG_ARCH_IMX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_AAEC2000 is not set
+
+#
+# RealView platform type
+#
+CONFIG_MACH_REALVIEW_EB=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_ARM926T=y
+# CONFIG_CPU_V6 is not set
+CONFIG_CPU_32v5=y
+CONFIG_CPU_ABRT_EV5TJ=y
+CONFIG_CPU_CACHE_VIVT=y
+CONFIG_CPU_COPY_V4WB=y
+CONFIG_CPU_TLB_V4WBI=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_ARM_GIC=y
+CONFIG_ICST307=y
+
+#
+# Bus support
+#
+CONFIG_ARM_AMBA=y
+CONFIG_ISA_DMA_API=y
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+# CONFIG_NO_IDLE_HZ is not set
+# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="root=/dev/nfs nfsroot=10.1.69.3:/work/nfsroot ip=dhcp console=ttyAMA0 mem=128M"
+# CONFIG_XIP_KERNEL is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_NWFPE_XP is not set
+# CONFIG_VFP is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_ARTHUR is not set
+
+#
+# Power management options
+#
+# CONFIG_PM is not set
+
+#
+# Networking
+#
+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=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE 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_TUNNEL is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+# CONFIG_IPV6 is not set
+# CONFIG_NETFILTER 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_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+# CONFIG_DEBUG_DRIVER is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+# CONFIG_MTD_AFS_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_CFI_AMDSTD_RETRY=0
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PHYSMAP is not set
+CONFIG_MTD_ARM_INTEGRATOR=y
+# CONFIG_MTD_EDB7312 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_BLKMTD 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
+
+#
+# NAND Flash Device Drivers
+#
+# CONFIG_MTD_NAND is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_RAM is not set
+CONFIG_BLK_DEV_RAM_COUNT=16
+# CONFIG_CDROM_PKTCDVD is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+# CONFIG_IOSCHED_AS is not set
+CONFIG_IOSCHED_DEADLINE=y
+# CONFIG_IOSCHED_CFQ is not set
+# CONFIG_ATA_OVER_ETH is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+
+#
+# I2O device support
+#
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+
+#
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+CONFIG_SMC91X=y
+# CONFIG_DM9000 is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+
+#
+# Ethernet (10000 Mbit)
+#
+
+#
+# Token Ring devices
+#
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+CONFIG_KEYBOARD_ATKBD=y
+# 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_INPUT_MOUSE=y
+CONFIG_MOUSE_PS2=y
+# CONFIG_MOUSE_SERIAL is not set
+# CONFIG_MOUSE_VSXXXAA is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_SERPORT is not set
+CONFIG_SERIO_AMBAKMI=y
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_AMBA_PL010 is not set
+CONFIG_SERIAL_AMBA_PL011=y
+CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=16
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_RAW_DRIVER is not set
+
+#
+# TPM devices
+#
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
+#
+# Misc devices
+#
+
+#
+# Multimedia Capabilities Port drivers
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+CONFIG_FB=y
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+CONFIG_FB_SOFT_CURSOR=y
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+CONFIG_FB_ARMCLCD=y
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_VIRTUAL is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FONTS is not set
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+
+#
+# Logo configuration
+#
+CONFIG_LOGO=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+CONFIG_LOGO_LINUX_CLUT224=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Sound
+#
+CONFIG_SOUND=y
+
+#
+# Advanced Linux Sound Architecture
+#
+CONFIG_SND=y
+CONFIG_SND_TIMER=y
+CONFIG_SND_PCM=y
+# CONFIG_SND_SEQUENCER is not set
+CONFIG_SND_OSSEMUL=y
+CONFIG_SND_MIXER_OSS=y
+CONFIG_SND_PCM_OSS=y
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+
+#
+# Generic devices
+#
+# CONFIG_SND_DUMMY is not set
+# CONFIG_SND_MTPAV is not set
+# CONFIG_SND_SERIAL_U16550 is not set
+# CONFIG_SND_MPU401 is not set
+
+#
+# ALSA ARM devices
+#
+# CONFIG_SND_ARMAACI is not set
+
+#
+# Open Sound System
+#
+# CONFIG_SOUND_PRIME is not set
+
+#
+# USB support
+#
+CONFIG_USB_ARCH_HAS_HCD=y
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+# CONFIG_USB is not set
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# File systems
+#
+# CONFIG_EXT2_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD 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_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+# CONFIG_MSDOS_FS is not set
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+# CONFIG_RELAYFS_FS is not set
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_JFFS_FS is not set
+# CONFIG_JFFS2_FS is not set
+CONFIG_CRAMFS=y
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFSD is not set
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_DEBUG_KERNEL=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_FS is not set
+CONFIG_FRAME_POINTER=y
+CONFIG_DEBUG_USER=y
+# CONFIG_DEBUG_WAITQ is not set
+CONFIG_DEBUG_ERRORS=y
+# CONFIG_DEBUG_LL is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
+
+#
+# Hardware crypto devices
+#
+
+#
+# Library routines
+#
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+CONFIG_CRC32=y
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
index 3e1b0327e4d7..c11169b5ed9a 100644
--- a/arch/arm/kernel/Makefile
+++ b/arch/arm/kernel/Makefile
@@ -2,7 +2,7 @@
# Makefile for the linux kernel.
#
-AFLAGS_head.o := -DTEXTADDR=$(TEXTADDR) -DDATAADDR=$(DATAADDR)
+AFLAGS_head.o := -DKERNEL_RAM_ADDR=$(TEXTADDR)
# Object file lists.
diff --git a/arch/arm/kernel/armksyms.c b/arch/arm/kernel/armksyms.c
index 7b17a87a3311..7a3261f0bf79 100644
--- a/arch/arm/kernel/armksyms.c
+++ b/arch/arm/kernel/armksyms.c
@@ -9,6 +9,7 @@
*/
#include <linux/module.h>
#include <linux/string.h>
+#include <linux/cryptohash.h>
#include <linux/delay.h>
#include <linux/in6.h>
#include <linux/syscalls.h>
@@ -126,6 +127,9 @@ EXPORT_SYMBOL(__put_user_2);
EXPORT_SYMBOL(__put_user_4);
EXPORT_SYMBOL(__put_user_8);
+ /* crypto hash */
+EXPORT_SYMBOL(sha_transform);
+
/* gcc lib functions */
EXPORT_SYMBOL(__ashldi3);
EXPORT_SYMBOL(__ashrdi3);
diff --git a/arch/arm/kernel/arthur.c b/arch/arm/kernel/arthur.c
index a418dad6692c..0ee2e9819631 100644
--- a/arch/arm/kernel/arthur.c
+++ b/arch/arm/kernel/arthur.c
@@ -18,6 +18,7 @@
#include <linux/stddef.h>
#include <linux/signal.h>
#include <linux/init.h>
+#include <linux/sched.h>
#include <asm/ptrace.h>
diff --git a/arch/arm/kernel/asm-offsets.c b/arch/arm/kernel/asm-offsets.c
index c1ff4d1f1bfd..04d3082a7b94 100644
--- a/arch/arm/kernel/asm-offsets.c
+++ b/arch/arm/kernel/asm-offsets.c
@@ -94,7 +94,6 @@ int main(void)
DEFINE(VM_EXEC, VM_EXEC);
BLANK();
DEFINE(PAGE_SZ, PAGE_SIZE);
- DEFINE(VIRT_OFFSET, PAGE_OFFSET);
BLANK();
DEFINE(SYS_ERROR0, 0x9f0000);
BLANK();
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
index 93b5e8e5292e..d9fb819bf7cc 100644
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@ -15,6 +15,7 @@
*/
#include <linux/config.h>
+#include <asm/memory.h>
#include <asm/glue.h>
#include <asm/vfpmacros.h>
#include <asm/hardware.h> /* should be moved into entry-macro.S */
@@ -46,6 +47,13 @@
movne r0, sp
adrne lr, 1b
bne do_IPI
+
+#ifdef CONFIG_LOCAL_TIMERS
+ test_for_ltirq r0, r6, r5, lr
+ movne r0, sp
+ adrne lr, 1b
+ bne do_local_timer
+#endif
#endif
.endm
@@ -310,7 +318,7 @@ __pabt_svc:
#if __LINUX_ARM_ARCH__ < 6 && !defined(CONFIG_NEEDS_SYSCALL_FOR_CMPXCHG)
@ make sure our user space atomic helper is aborted
- cmp r2, #VIRT_OFFSET
+ cmp r2, #TASK_SIZE
bichs r3, r3, #PSR_Z_BIT
#endif
@@ -784,7 +792,7 @@ __kuser_helper_end:
* SP points to a minimal amount of processor-private memory, the address
* of which is copied into r0 for the mode specific abort handler.
*/
- .macro vector_stub, name, correction=0
+ .macro vector_stub, name, mode, correction=0
.align 5
vector_\name:
@@ -804,15 +812,14 @@ vector_\name:
@ Prepare for SVC32 mode. IRQs remain disabled.
@
mrs r0, cpsr
- bic r0, r0, #MODE_MASK
- orr r0, r0, #SVC_MODE
+ eor r0, r0, #(\mode ^ SVC_MODE)
msr spsr_cxsf, r0
@
@ the branch table must immediately follow this code
@
- mov r0, sp
and lr, lr, #0x0f
+ mov r0, sp
ldr lr, [pc, lr, lsl #2]
movs pc, lr @ branch to handler in SVC mode
.endm
@@ -822,7 +829,7 @@ __stubs_start:
/*
* Interrupt dispatcher
*/
- vector_stub irq, 4
+ vector_stub irq, IRQ_MODE, 4
.long __irq_usr @ 0 (USR_26 / USR_32)
.long __irq_invalid @ 1 (FIQ_26 / FIQ_32)
@@ -845,7 +852,7 @@ __stubs_start:
* Data abort dispatcher
* Enter in ABT mode, spsr = USR CPSR, lr = USR PC
*/
- vector_stub dabt, 8
+ vector_stub dabt, ABT_MODE, 8
.long __dabt_usr @ 0 (USR_26 / USR_32)
.long __dabt_invalid @ 1 (FIQ_26 / FIQ_32)
@@ -868,7 +875,7 @@ __stubs_start:
* Prefetch abort dispatcher
* Enter in ABT mode, spsr = USR CPSR, lr = USR PC
*/
- vector_stub pabt, 4
+ vector_stub pabt, ABT_MODE, 4
.long __pabt_usr @ 0 (USR_26 / USR_32)
.long __pabt_invalid @ 1 (FIQ_26 / FIQ_32)
@@ -891,7 +898,7 @@ __stubs_start:
* Undef instr entry dispatcher
* Enter in UND mode, spsr = SVC/USR CPSR, lr = SVC/USR PC
*/
- vector_stub und
+ vector_stub und, UND_MODE
.long __und_usr @ 0 (USR_26 / USR_32)
.long __und_invalid @ 1 (FIQ_26 / FIQ_32)
diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
index 539626351348..8d8748407cbe 100644
--- a/arch/arm/kernel/head.S
+++ b/arch/arm/kernel/head.S
@@ -21,6 +21,7 @@
#include <asm/procinfo.h>
#include <asm/ptrace.h>
#include <asm/asm-offsets.h>
+#include <asm/memory.h>
#include <asm/thread_info.h>
#include <asm/system.h>
@@ -33,52 +34,28 @@
#define MACHINFO_PGOFFIO 12
#define MACHINFO_NAME 16
-#ifndef CONFIG_XIP_KERNEL
/*
- * We place the page tables 16K below TEXTADDR. Therefore, we must make sure
- * that TEXTADDR is correctly set. Currently, we expect the least significant
- * 16 bits to be 0x8000, but we could probably relax this restriction to
- * TEXTADDR >= PAGE_OFFSET + 0x4000
- *
- * Note that swapper_pg_dir is the virtual address of the page tables, and
- * pgtbl gives us a position-independent reference to these tables. We can
- * do this because stext == TEXTADDR
+ * swapper_pg_dir is the virtual address of the initial page table.
+ * We place the page tables 16K below KERNEL_RAM_ADDR. Therefore, we must
+ * make sure that KERNEL_RAM_ADDR is correctly set. Currently, we expect
+ * the least significant 16 bits to be 0x8000, but we could probably
+ * relax this restriction to KERNEL_RAM_ADDR >= PAGE_OFFSET + 0x4000.
*/
-#if (TEXTADDR & 0xffff) != 0x8000
-#error TEXTADDR must start at 0xXXXX8000
+#if (KERNEL_RAM_ADDR & 0xffff) != 0x8000
+#error KERNEL_RAM_ADDR must start at 0xXXXX8000
#endif
.globl swapper_pg_dir
- .equ swapper_pg_dir, TEXTADDR - 0x4000
+ .equ swapper_pg_dir, KERNEL_RAM_ADDR - 0x4000
- .macro pgtbl, rd, phys
- adr \rd, stext
- sub \rd, \rd, #0x4000
+ .macro pgtbl, rd
+ ldr \rd, =(__virt_to_phys(KERNEL_RAM_ADDR - 0x4000))
.endm
-#else
-/*
- * XIP Kernel:
- *
- * We place the page tables 16K below DATAADDR. Therefore, we must make sure
- * that DATAADDR is correctly set. Currently, we expect the least significant
- * 16 bits to be 0x8000, but we could probably relax this restriction to
- * DATAADDR >= PAGE_OFFSET + 0x4000
- *
- * Note that pgtbl is meant to return the physical address of swapper_pg_dir.
- * We can't make it relative to the kernel position in this case since
- * the kernel can physically be anywhere.
- */
-#if (DATAADDR & 0xffff) != 0x8000
-#error DATAADDR must start at 0xXXXX8000
-#endif
-
- .globl swapper_pg_dir
- .equ swapper_pg_dir, DATAADDR - 0x4000
- .macro pgtbl, rd, phys
- ldr \rd, =((DATAADDR - 0x4000) - VIRT_OFFSET)
- add \rd, \rd, \phys
- .endm
+#ifdef CONFIG_XIP_KERNEL
+#define TEXTADDR XIP_VIRT_ADDR(CONFIG_XIP_PHYS_ADDR)
+#else
+#define TEXTADDR KERNEL_RAM_ADDR
#endif
/*
@@ -279,7 +256,7 @@ __turn_mmu_on:
.type __create_page_tables, %function
__create_page_tables:
ldr r5, [r8, #MACHINFO_PHYSRAM] @ physram
- pgtbl r4, r5 @ page table address
+ pgtbl r4 @ page table address
/*
* Clear the 16K level 1 swapper page table
@@ -324,7 +301,7 @@ __create_page_tables:
/*
* Then map first 1MB of ram in case it contains our boot params.
*/
- add r0, r4, #VIRT_OFFSET >> 18
+ add r0, r4, #PAGE_OFFSET >> 18
orr r6, r5, r7
str r6, [r0]
diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c
index 3284118f356b..d7099dbbb879 100644
--- a/arch/arm/kernel/irq.c
+++ b/arch/arm/kernel/irq.c
@@ -264,6 +264,7 @@ unlock:
#endif
#ifdef CONFIG_SMP
show_ipi_list(p);
+ show_local_irqs(p);
#endif
seq_printf(p, "Err: %10lu\n", irq_err_count);
}
@@ -995,7 +996,7 @@ void __init init_irq_proc(void)
struct proc_dir_entry *dir;
int irq;
- dir = proc_mkdir("irq", 0);
+ dir = proc_mkdir("irq", NULL);
if (!dir)
return;
@@ -1050,3 +1051,34 @@ static int __init noirqdebug_setup(char *str)
}
__setup("noirqdebug", noirqdebug_setup);
+
+#ifdef CONFIG_HOTPLUG_CPU
+/*
+ * The CPU has been marked offline. Migrate IRQs off this CPU. If
+ * the affinity settings do not allow other CPUs, force them onto any
+ * available CPU.
+ */
+void migrate_irqs(void)
+{
+ unsigned int i, cpu = smp_processor_id();
+
+ for (i = 0; i < NR_IRQS; i++) {
+ struct irqdesc *desc = irq_desc + i;
+
+ if (desc->cpu == cpu) {
+ unsigned int newcpu = any_online_cpu(desc->affinity);
+
+ if (newcpu == NR_CPUS) {
+ if (printk_ratelimit())
+ printk(KERN_INFO "IRQ%u no longer affine to CPU%u\n",
+ i, cpu);
+
+ cpus_setall(desc->affinity);
+ newcpu = any_online_cpu(desc->affinity);
+ }
+
+ route_irq(desc, i, newcpu);
+ }
+ }
+}
+#endif /* CONFIG_HOTPLUG_CPU */
diff --git a/arch/arm/kernel/module.c b/arch/arm/kernel/module.c
index 1a85cfdad5ac..6055e1427ba3 100644
--- a/arch/arm/kernel/module.c
+++ b/arch/arm/kernel/module.c
@@ -11,6 +11,7 @@
*/
#include <linux/config.h>
#include <linux/module.h>
+#include <linux/moduleloader.h>
#include <linux/kernel.h>
#include <linux/elf.h>
#include <linux/vmalloc.h>
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index 409db6d5ec99..30494aab829a 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -26,6 +26,7 @@
#include <linux/interrupt.h>
#include <linux/kallsyms.h>
#include <linux/init.h>
+#include <linux/cpu.h>
#include <asm/system.h>
#include <asm/io.h>
@@ -85,12 +86,16 @@ EXPORT_SYMBOL(pm_power_off);
*/
void default_idle(void)
{
- local_irq_disable();
- if (!need_resched() && !hlt_counter) {
- timer_dyn_reprogram();
- arch_idle();
+ if (hlt_counter)
+ cpu_relax();
+ else {
+ local_irq_disable();
+ if (!need_resched()) {
+ timer_dyn_reprogram();
+ arch_idle();
+ }
+ local_irq_enable();
}
- local_irq_enable();
}
/*
@@ -105,15 +110,23 @@ void cpu_idle(void)
/* endless idle loop with no priority at all */
while (1) {
void (*idle)(void) = pm_idle;
+
+#ifdef CONFIG_HOTPLUG_CPU
+ if (cpu_is_offline(smp_processor_id())) {
+ leds_event(led_idle_start);
+ cpu_die();
+ }
+#endif
+
if (!idle)
idle = default_idle;
- preempt_disable();
leds_event(led_idle_start);
while (!need_resched())
idle();
leds_event(led_idle_end);
- preempt_enable();
+ preempt_enable_no_resched();
schedule();
+ preempt_disable();
}
}
@@ -346,7 +359,7 @@ copy_thread(int nr, unsigned long clone_flags, unsigned long stack_start,
struct thread_info *thread = p->thread_info;
struct pt_regs *childregs;
- childregs = ((struct pt_regs *)((unsigned long)thread + THREAD_START_SP)) - 1;
+ childregs = (void *)thread + THREAD_START_SP - sizeof(*regs);
*childregs = *regs;
childregs->ARM_r0 = 0;
childregs->ARM_sp = stack_start;
diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c
index cd99b83f14c2..9a340e790da5 100644
--- a/arch/arm/kernel/ptrace.c
+++ b/arch/arm/kernel/ptrace.c
@@ -648,7 +648,7 @@ static int ptrace_setwmmxregs(struct task_struct *tsk, void __user *ufp)
#endif
-static int do_ptrace(int request, struct task_struct *child, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request, long addr, long data)
{
unsigned long tmp;
int ret;
@@ -782,53 +782,6 @@ static int do_ptrace(int request, struct task_struct *child, long addr, long dat
return ret;
}
-asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
-{
- struct task_struct *child;
- int ret;
-
- lock_kernel();
- ret = -EPERM;
- if (request == PTRACE_TRACEME) {
- /* are we already being traced? */
- if (current->ptrace & PT_PTRACED)
- goto out;
- ret = security_ptrace(current->parent, current);
- if (ret)
- goto out;
- /* set the ptrace bit in the process flags. */
- current->ptrace |= PT_PTRACED;
- ret = 0;
- goto out;
- }
- ret = -ESRCH;
- read_lock(&tasklist_lock);
- child = find_task_by_pid(pid);
- if (child)
- get_task_struct(child);
- read_unlock(&tasklist_lock);
- if (!child)
- goto out;
-
- ret = -EPERM;
- if (pid == 1) /* you may not mess with init */
- goto out_tsk;
-
- if (request == PTRACE_ATTACH) {
- ret = ptrace_attach(child);
- goto out_tsk;
- }
- ret = ptrace_check_attach(child, request == PTRACE_KILL);
- if (ret == 0)
- ret = do_ptrace(request, child, addr, data);
-
-out_tsk:
- put_task_struct(child);
-out:
- unlock_kernel();
- return ret;
-}
-
asmlinkage void syscall_trace(int why, struct pt_regs *regs)
{
unsigned long ip;
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index c9b69771f92e..85774165e9fd 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -338,7 +338,8 @@ void cpu_init(void)
BUG();
}
- dump_cpu_info(cpu);
+ if (system_state == SYSTEM_BOOTING)
+ dump_cpu_info(cpu);
/*
* setup stacks for re-entrant exception handlers
@@ -838,7 +839,12 @@ static int c_show(struct seq_file *m, void *v)
#if defined(CONFIG_SMP)
for_each_online_cpu(i) {
- seq_printf(m, "Processor\t: %d\n", i);
+ /*
+ * glibc reads /proc/cpuinfo to determine the number of
+ * online processors, looking for lines beginning with
+ * "processor". Give glibc what it expects.
+ */
+ seq_printf(m, "processor\t: %d\n", i);
seq_printf(m, "BogoMIPS\t: %lu.%02lu\n\n",
per_cpu(cpu_data, i).loops_per_jiffy / (500000UL/HZ),
(per_cpu(cpu_data, i).loops_per_jiffy / (5000UL/HZ)) % 100);
diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c
index a94d75fef598..a917e3dd3666 100644
--- a/arch/arm/kernel/signal.c
+++ b/arch/arm/kernel/signal.c
@@ -139,93 +139,33 @@ struct iwmmxt_sigframe {
unsigned long storage[0x98/4];
};
-static int page_present(struct mm_struct *mm, void __user *uptr, int wr)
-{
- unsigned long addr = (unsigned long)uptr;
- pgd_t *pgd = pgd_offset(mm, addr);
- if (pgd_present(*pgd)) {
- pmd_t *pmd = pmd_offset(pgd, addr);
- if (pmd_present(*pmd)) {
- pte_t *pte = pte_offset_map(pmd, addr);
- return (pte_present(*pte) && (!wr || pte_write(*pte)));
- }
- }
- return 0;
-}
-
-static int copy_locked(void __user *uptr, void *kptr, size_t size, int write,
- void (*copyfn)(void *, void __user *))
-{
- unsigned char v, __user *userptr = uptr;
- int err = 0;
-
- do {
- struct mm_struct *mm;
-
- if (write) {
- __put_user_error(0, userptr, err);
- __put_user_error(0, userptr + size - 1, err);
- } else {
- __get_user_error(v, userptr, err);
- __get_user_error(v, userptr + size - 1, err);
- }
-
- if (err)
- break;
-
- mm = current->mm;
- spin_lock(&mm->page_table_lock);
- if (page_present(mm, userptr, write) &&
- page_present(mm, userptr + size - 1, write)) {
- copyfn(kptr, uptr);
- } else
- err = 1;
- spin_unlock(&mm->page_table_lock);
- } while (err);
-
- return err;
-}
-
static int preserve_iwmmxt_context(struct iwmmxt_sigframe *frame)
{
- int err = 0;
+ char kbuf[sizeof(*frame) + 8];
+ struct iwmmxt_sigframe *kframe;
/* the iWMMXt context must be 64 bit aligned */
- WARN_ON((unsigned long)frame & 7);
-
- __put_user_error(IWMMXT_MAGIC0, &frame->magic0, err);
- __put_user_error(IWMMXT_MAGIC1, &frame->magic1, err);
-
- /*
- * iwmmxt_task_copy() doesn't check user permissions.
- * Let's do a dummy write on the upper boundary to ensure
- * access to user mem is OK all way up.
- */
- err |= copy_locked(&frame->storage, current_thread_info(),
- sizeof(frame->storage), 1, iwmmxt_task_copy);
- return err;
+ kframe = (struct iwmmxt_sigframe *)((unsigned long)(kbuf + 8) & ~7);
+ kframe->magic0 = IWMMXT_MAGIC0;
+ kframe->magic1 = IWMMXT_MAGIC1;
+ iwmmxt_task_copy(current_thread_info(), &kframe->storage);
+ return __copy_to_user(frame, kframe, sizeof(*frame));
}
static int restore_iwmmxt_context(struct iwmmxt_sigframe *frame)
{
- unsigned long magic0, magic1;
- int err = 0;
+ char kbuf[sizeof(*frame) + 8];
+ struct iwmmxt_sigframe *kframe;
- /* the iWMMXt context is 64 bit aligned */
- WARN_ON((unsigned long)frame & 7);
-
- /*
- * Validate iWMMXt context signature.
- * Also, iwmmxt_task_restore() doesn't check user permissions.
- * Let's do a dummy write on the upper boundary to ensure
- * access to user mem is OK all way up.
- */
- __get_user_error(magic0, &frame->magic0, err);
- __get_user_error(magic1, &frame->magic1, err);
- if (!err && magic0 == IWMMXT_MAGIC0 && magic1 == IWMMXT_MAGIC1)
- err = copy_locked(&frame->storage, current_thread_info(),
- sizeof(frame->storage), 0, iwmmxt_task_restore);
- return err;
+ /* the iWMMXt context must be 64 bit aligned */
+ kframe = (struct iwmmxt_sigframe *)((unsigned long)(kbuf + 8) & ~7);
+ if (__copy_from_user(kframe, frame, sizeof(*frame)))
+ return -1;
+ if (kframe->magic0 != IWMMXT_MAGIC0 ||
+ kframe->magic1 != IWMMXT_MAGIC1)
+ return -1;
+ iwmmxt_task_restore(current_thread_info(), &kframe->storage);
+ return 0;
}
#endif
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index 826164945747..e55ea952f7aa 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -80,19 +80,23 @@ static DEFINE_SPINLOCK(smp_call_function_lock);
int __cpuinit __cpu_up(unsigned int cpu)
{
- struct task_struct *idle;
+ struct cpuinfo_arm *ci = &per_cpu(cpu_data, cpu);
+ struct task_struct *idle = ci->idle;
pgd_t *pgd;
pmd_t *pmd;
int ret;
/*
- * Spawn a new process manually. Grab a pointer to
- * its task struct so we can mess with it
+ * Spawn a new process manually, if not already done.
+ * Grab a pointer to its task struct so we can mess with it
*/
- idle = fork_idle(cpu);
- if (IS_ERR(idle)) {
- printk(KERN_ERR "CPU%u: fork() failed\n", cpu);
- return PTR_ERR(idle);
+ if (!idle) {
+ idle = fork_idle(cpu);
+ if (IS_ERR(idle)) {
+ printk(KERN_ERR "CPU%u: fork() failed\n", cpu);
+ return PTR_ERR(idle);
+ }
+ ci->idle = idle;
}
/*
@@ -138,7 +142,7 @@ int __cpuinit __cpu_up(unsigned int cpu)
ret = -EIO;
}
- secondary_data.stack = 0;
+ secondary_data.stack = NULL;
secondary_data.pgdir = 0;
*pmd_offset(pgd, PHYS_OFFSET) = __pmd(0);
@@ -155,6 +159,96 @@ int __cpuinit __cpu_up(unsigned int cpu)
return ret;
}
+#ifdef CONFIG_HOTPLUG_CPU
+/*
+ * __cpu_disable runs on the processor to be shutdown.
+ */
+int __cpuexit __cpu_disable(void)
+{
+ unsigned int cpu = smp_processor_id();
+ struct task_struct *p;
+ int ret;
+
+ ret = mach_cpu_disable(cpu);
+ if (ret)
+ return ret;
+
+ /*
+ * Take this CPU offline. Once we clear this, we can't return,
+ * and we must not schedule until we're ready to give up the cpu.
+ */
+ cpu_clear(cpu, cpu_online_map);
+
+ /*
+ * OK - migrate IRQs away from this CPU
+ */
+ migrate_irqs();
+
+ /*
+ * Stop the local timer for this CPU.
+ */
+ local_timer_stop(cpu);
+
+ /*
+ * Flush user cache and TLB mappings, and then remove this CPU
+ * from the vm mask set of all processes.
+ */
+ flush_cache_all();
+ local_flush_tlb_all();
+
+ read_lock(&tasklist_lock);
+ for_each_process(p) {
+ if (p->mm)
+ cpu_clear(cpu, p->mm->cpu_vm_mask);
+ }
+ read_unlock(&tasklist_lock);
+
+ return 0;
+}
+
+/*
+ * called on the thread which is asking for a CPU to be shutdown -
+ * waits until shutdown has completed, or it is timed out.
+ */
+void __cpuexit __cpu_die(unsigned int cpu)
+{
+ if (!platform_cpu_kill(cpu))
+ printk("CPU%u: unable to kill\n", cpu);
+}
+
+/*
+ * Called from the idle thread for the CPU which has been shutdown.
+ *
+ * Note that we disable IRQs here, but do not re-enable them
+ * before returning to the caller. This is also the behaviour
+ * of the other hotplug-cpu capable cores, so presumably coming
+ * out of idle fixes this.
+ */
+void __cpuexit cpu_die(void)
+{
+ unsigned int cpu = smp_processor_id();
+
+ local_irq_disable();
+ idle_task_exit();
+
+ /*
+ * actual CPU shutdown procedure is at least platform (if not
+ * CPU) specific
+ */
+ platform_cpu_die(cpu);
+
+ /*
+ * Do not return to the idle loop - jump back to the secondary
+ * cpu initialisation. There's some initialisation which needs
+ * to be repeated to undo the effects of taking the CPU offline.
+ */
+ __asm__("mov sp, %0\n"
+ " b secondary_start_kernel"
+ :
+ : "r" ((void *)current->thread_info + THREAD_SIZE - 8));
+}
+#endif /* CONFIG_HOTPLUG_CPU */
+
/*
* This is the secondary CPU boot entry. We're using this CPUs
* idle thread stack, but a set of temporary page tables.
@@ -162,7 +256,9 @@ int __cpuinit __cpu_up(unsigned int cpu)
asmlinkage void __cpuinit secondary_start_kernel(void)
{
struct mm_struct *mm = &init_mm;
- unsigned int cpu = smp_processor_id();
+ unsigned int cpu;
+
+ cpu = smp_processor_id();
printk("CPU%u: Booted secondary processor\n", cpu);
@@ -179,6 +275,7 @@ asmlinkage void __cpuinit secondary_start_kernel(void)
local_flush_tlb_all();
cpu_init();
+ preempt_disable();
/*
* Give the platform a chance to do its own initialisation.
@@ -201,6 +298,11 @@ asmlinkage void __cpuinit secondary_start_kernel(void)
cpu_set(cpu, cpu_online_map);
/*
+ * Setup local timer for this CPU.
+ */
+ local_timer_setup(cpu);
+
+ /*
* OK, it's off to the idle thread for us
*/
cpu_idle();
@@ -236,6 +338,8 @@ void __init smp_prepare_boot_cpu(void)
{
unsigned int cpu = smp_processor_id();
+ per_cpu(cpu_data, cpu).idle = current;
+
cpu_set(cpu, cpu_possible_map);
cpu_set(cpu, cpu_present_map);
cpu_set(cpu, cpu_online_map);
@@ -268,8 +372,8 @@ static void send_ipi_message(cpumask_t callmap, enum ipi_msg_type msg)
* You must not call this function with disabled interrupts, from a
* hardware interrupt handler, nor from a bottom half handler.
*/
-int smp_call_function_on_cpu(void (*func)(void *info), void *info, int retry,
- int wait, cpumask_t callmap)
+static int smp_call_function_on_cpu(void (*func)(void *info), void *info,
+ int retry, int wait, cpumask_t callmap)
{
struct smp_call_struct data;
unsigned long timeout;
@@ -309,8 +413,8 @@ int smp_call_function_on_cpu(void (*func)(void *info), void *info, int retry,
printk(KERN_CRIT
"CPU%u: smp_call_function timeout for %p(%p)\n"
" callmap %lx pending %lx, %swait\n",
- smp_processor_id(), func, info, callmap, data.pending,
- wait ? "" : "no ");
+ smp_processor_id(), func, info, *cpus_addr(callmap),
+ *cpus_addr(data.pending), wait ? "" : "no ");
/*
* TRACE
@@ -363,6 +467,18 @@ void show_ipi_list(struct seq_file *p)
seq_putc(p, '\n');
}
+void show_local_irqs(struct seq_file *p)
+{
+ unsigned int cpu;
+
+ seq_printf(p, "LOC: ");
+
+ for_each_present_cpu(cpu)
+ seq_printf(p, "%10u ", irq_stat[cpu].local_timer_irqs);
+
+ seq_putc(p, '\n');
+}
+
static void ipi_timer(struct pt_regs *regs)
{
int user = user_mode(regs);
@@ -373,6 +489,18 @@ static void ipi_timer(struct pt_regs *regs)
irq_exit();
}
+#ifdef CONFIG_LOCAL_TIMERS
+asmlinkage void do_local_timer(struct pt_regs *regs)
+{
+ int cpu = smp_processor_id();
+
+ if (local_timer_ack()) {
+ irq_stat[cpu].local_timer_irqs++;
+ ipi_timer(regs);
+ }
+}
+#endif
+
/*
* ipi_call_function - handle IPI from smp_call_function()
*
@@ -424,7 +552,7 @@ static void ipi_cpu_stop(unsigned int cpu)
*
* Bit 0 - Inter-processor function call
*/
-void do_IPI(struct pt_regs *regs)
+asmlinkage void do_IPI(struct pt_regs *regs)
{
unsigned int cpu = smp_processor_id();
struct ipi_data *ipi = &per_cpu(ipi_data, cpu);
diff --git a/arch/arm/kernel/time.c b/arch/arm/kernel/time.c
index 69449a818dcc..fc4729106a32 100644
--- a/arch/arm/kernel/time.c
+++ b/arch/arm/kernel/time.c
@@ -36,10 +36,6 @@
#include <asm/thread_info.h>
#include <asm/mach/time.h>
-u64 jiffies_64 = INITIAL_JIFFIES;
-
-EXPORT_SYMBOL(jiffies_64);
-
/*
* Our system timer.
*/
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index f6de76e0a45d..45e9ea6cd2a5 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -198,25 +198,16 @@ void show_stack(struct task_struct *tsk, unsigned long *sp)
barrier();
}
-DEFINE_SPINLOCK(die_lock);
-
-/*
- * This function is protected against re-entrancy.
- */
-NORET_TYPE void die(const char *str, struct pt_regs *regs, int err)
+static void __die(const char *str, int err, struct thread_info *thread, struct pt_regs *regs)
{
- struct task_struct *tsk = current;
+ struct task_struct *tsk = thread->task;
static int die_counter;
- console_verbose();
- spin_lock_irq(&die_lock);
- bust_spinlocks(1);
-
printk("Internal error: %s: %x [#%d]\n", str, err, ++die_counter);
print_modules();
__show_regs(regs);
printk("Process %s (pid: %d, stack limit = 0x%p)\n",
- tsk->comm, tsk->pid, tsk->thread_info + 1);
+ tsk->comm, tsk->pid, thread + 1);
if (!user_mode(regs) || in_interrupt()) {
dump_mem("Stack: ", regs->ARM_sp,
@@ -224,7 +215,21 @@ NORET_TYPE void die(const char *str, struct pt_regs *regs, int err)
dump_backtrace(regs, tsk);
dump_instr(regs);
}
+}
+
+DEFINE_SPINLOCK(die_lock);
+
+/*
+ * This function is protected against re-entrancy.
+ */
+NORET_TYPE void die(const char *str, struct pt_regs *regs, int err)
+{
+ struct thread_info *thread = current_thread_info();
+ console_verbose();
+ spin_lock_irq(&die_lock);
+ bust_spinlocks(1);
+ __die(str, err, thread, regs);
bust_spinlocks(0);
spin_unlock_irq(&die_lock);
do_exit(SIGSEGV);
@@ -345,7 +350,9 @@ static int bad_syscall(int n, struct pt_regs *regs)
struct thread_info *thread = current_thread_info();
siginfo_t info;
- if (current->personality != PER_LINUX && thread->exec_domain->handler) {
+ if (current->personality != PER_LINUX &&
+ current->personality != PER_LINUX_32BIT &&
+ thread->exec_domain->handler) {
thread->exec_domain->handler(n, regs);
return regs->ARM_r0;
}
@@ -481,29 +488,33 @@ asmlinkage int arm_syscall(int no, struct pt_regs *regs)
unsigned long addr = regs->ARM_r2;
struct mm_struct *mm = current->mm;
pgd_t *pgd; pmd_t *pmd; pte_t *pte;
+ spinlock_t *ptl;
regs->ARM_cpsr &= ~PSR_C_BIT;
- spin_lock(&mm->page_table_lock);
+ down_read(&mm->mmap_sem);
pgd = pgd_offset(mm, addr);
if (!pgd_present(*pgd))
goto bad_access;
pmd = pmd_offset(pgd, addr);
if (!pmd_present(*pmd))
goto bad_access;
- pte = pte_offset_map(pmd, addr);
- if (!pte_present(*pte) || !pte_write(*pte))
+ pte = pte_offset_map_lock(mm, pmd, addr, &ptl);
+ if (!pte_present(*pte) || !pte_write(*pte)) {
+ pte_unmap_unlock(pte, ptl);
goto bad_access;
+ }
val = *(unsigned long *)addr;
val -= regs->ARM_r0;
if (val == 0) {
*(unsigned long *)addr = regs->ARM_r1;
regs->ARM_cpsr |= PSR_C_BIT;
}
- spin_unlock(&mm->page_table_lock);
+ pte_unmap_unlock(pte, ptl);
+ up_read(&mm->mmap_sem);
return val;
bad_access:
- spin_unlock(&mm->page_table_lock);
+ up_read(&mm->mmap_sem);
/* simulate a write access fault */
do_DataAbort(addr, 15 + (1 << 11), regs);
return -1;
diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S
index 0d5db5279c5c..80c8e4c8cefa 100644
--- a/arch/arm/kernel/vmlinux.lds.S
+++ b/arch/arm/kernel/vmlinux.lds.S
@@ -6,14 +6,23 @@
#include <asm-generic/vmlinux.lds.h>
#include <linux/config.h>
#include <asm/thread_info.h>
+#include <asm/memory.h>
OUTPUT_ARCH(arm)
ENTRY(stext)
+
#ifndef __ARMEB__
jiffies = jiffies_64;
#else
jiffies = jiffies_64 + 4;
#endif
+
+#ifdef CONFIG_XIP_KERNEL
+#define TEXTADDR XIP_VIRT_ADDR(CONFIG_XIP_PHYS_ADDR)
+#else
+#define TEXTADDR KERNEL_RAM_ADDR
+#endif
+
SECTIONS
{
. = TEXTADDR;
@@ -95,7 +104,7 @@ SECTIONS
#ifdef CONFIG_XIP_KERNEL
__data_loc = ALIGN(4); /* location in binary */
- . = DATAADDR;
+ . = KERNEL_RAM_ADDR;
#else
. = ALIGN(THREAD_SIZE);
__data_loc = .;
diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile
index 8725d63e4219..391f3ab3ff32 100644
--- a/arch/arm/lib/Makefile
+++ b/arch/arm/lib/Makefile
@@ -7,13 +7,27 @@
lib-y := backtrace.o changebit.o csumipv6.o csumpartial.o \
csumpartialcopy.o csumpartialcopyuser.o clearbit.o \
copy_page.o delay.o findbit.o memchr.o memcpy.o \
- memset.o memzero.o setbit.o strncpy_from_user.o \
- strnlen_user.o strchr.o strrchr.o testchangebit.o \
- testclearbit.o testsetbit.o uaccess.o getuser.o \
- putuser.o ashldi3.o ashrdi3.o lshrdi3.o muldi3.o \
- ucmpdi2.o lib1funcs.o div64.o \
+ memmove.o memset.o memzero.o setbit.o \
+ strncpy_from_user.o strnlen_user.o \
+ strchr.o strrchr.o \
+ testchangebit.o testclearbit.o testsetbit.o \
+ getuser.o putuser.o clear_user.o \
+ ashldi3.o ashrdi3.o lshrdi3.o muldi3.o \
+ ucmpdi2.o lib1funcs.o div64.o sha1.o \
io-readsb.o io-writesb.o io-readsl.o io-writesl.o
+# the code in uaccess.S is not preemption safe and
+# probably faster on ARMv3 only
+ifeq ($CONFIG_PREEMPT,y)
+ lib-y += copy_from_user.o copy_to_user.o
+else
+ifneq ($(CONFIG_CPU_32v3),y)
+ lib-y += copy_from_user.o copy_to_user.o
+else
+ lib-y += uaccess.o
+endif
+endif
+
ifeq ($(CONFIG_CPU_32v3),y)
lib-y += io-readsw-armv3.o io-writesw-armv3.o
else
diff --git a/arch/arm/lib/ashldi3.S b/arch/arm/lib/ashldi3.S
new file mode 100644
index 000000000000..561e20717b30
--- /dev/null
+++ b/arch/arm/lib/ashldi3.S
@@ -0,0 +1,48 @@
+/* Copyright 1995, 1996, 1998, 1999, 2000, 2003, 2004, 2005
+ Free Software Foundation, Inc.
+
+This file is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option) any
+later version.
+
+In addition to the permissions in the GNU General Public License, the
+Free Software Foundation gives you unlimited permission to link the
+compiled version of this file into combinations with other programs,
+and to distribute those combinations without any restriction coming
+from the use of this file. (The General Public License restrictions
+do apply in other respects; for example, they cover modification of
+the file, and distribution when not linked into a combine
+executable.)
+
+This file 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, 51 Franklin Street, Fifth Floor,
+Boston, MA 02110-1301, USA. */
+
+
+#include <linux/linkage.h>
+
+#ifdef __ARMEB__
+#define al r1
+#define ah r0
+#else
+#define al r0
+#define ah r1
+#endif
+
+ENTRY(__ashldi3)
+
+ subs r3, r2, #32
+ rsb ip, r2, #32
+ movmi ah, ah, lsl r2
+ movpl ah, al, lsl r3
+ orrmi ah, ah, al, lsr ip
+ mov al, al, lsl r2
+ mov pc, lr
+
diff --git a/arch/arm/lib/ashldi3.c b/arch/arm/lib/ashldi3.c
deleted file mode 100644
index b62875cfd8f8..000000000000
--- a/arch/arm/lib/ashldi3.c
+++ /dev/null
@@ -1,56 +0,0 @@
-/* More subroutines needed by GCC output code on some machines. */
-/* Compile this one with gcc. */
-/* Copyright (C) 1989, 92-98, 1999 Free Software Foundation, Inc.
-
-This file is part of GNU CC.
-
-GNU CC is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
-
-GNU CC 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 GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
-
-/* As a special exception, if you link this library with other files,
- some of which are compiled with GCC, to produce an executable,
- this library does not by itself cause the resulting executable
- to be covered by the GNU General Public License.
- This exception does not however invalidate any other reasons why
- the executable file might be covered by the GNU General Public License.
- */
-/* support functions required by the kernel. based on code from gcc-2.95.3 */
-/* I Molton 29/07/01 */
-
-#include "gcclib.h"
-
-s64 __ashldi3(s64 u, int b)
-{
- DIunion w;
- int bm;
- DIunion uu;
-
- if (b == 0)
- return u;
-
- uu.ll = u;
-
- bm = (sizeof(s32) * BITS_PER_UNIT) - b;
- if (bm <= 0) {
- w.s.low = 0;
- w.s.high = (u32) uu.s.low << -bm;
- } else {
- u32 carries = (u32) uu.s.low >> bm;
- w.s.low = (u32) uu.s.low << b;
- w.s.high = ((u32) uu.s.high << b) | carries;
- }
-
- return w.ll;
-}
diff --git a/arch/arm/lib/ashrdi3.S b/arch/arm/lib/ashrdi3.S
new file mode 100644
index 000000000000..86fb2a90c301
--- /dev/null
+++ b/arch/arm/lib/ashrdi3.S
@@ -0,0 +1,48 @@
+/* Copyright 1995, 1996, 1998, 1999, 2000, 2003, 2004, 2005
+ Free Software Foundation, Inc.
+
+This file is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option) any
+later version.
+
+In addition to the permissions in the GNU General Public License, the
+Free Software Foundation gives you unlimited permission to link the
+compiled version of this file into combinations with other programs,
+and to distribute those combinations without any restriction coming
+from the use of this file. (The General Public License restrictions
+do apply in other respects; for example, they cover modification of
+the file, and distribution when not linked into a combine
+executable.)
+
+This file 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, 51 Franklin Street, Fifth Floor,
+Boston, MA 02110-1301, USA. */
+
+
+#include <linux/linkage.h>
+
+#ifdef __ARMEB__
+#define al r1
+#define ah r0
+#else
+#define al r0
+#define ah r1
+#endif
+
+ENTRY(__ashrdi3)
+
+ subs r3, r2, #32
+ rsb ip, r2, #32
+ movmi al, al, lsr r2
+ movpl al, ah, asr r3
+ orrmi al, al, ah, lsl ip
+ mov ah, ah, asr r2
+ mov pc, lr
+
diff --git a/arch/arm/lib/ashrdi3.c b/arch/arm/lib/ashrdi3.c
deleted file mode 100644
index 9a8600a7543f..000000000000
--- a/arch/arm/lib/ashrdi3.c
+++ /dev/null
@@ -1,57 +0,0 @@
-/* More subroutines needed by GCC output code on some machines. */
-/* Compile this one with gcc. */
-/* Copyright (C) 1989, 92-98, 1999 Free Software Foundation, Inc.
-
-This file is part of GNU CC.
-
-GNU CC is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
-
-GNU CC 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 GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
-
-/* As a special exception, if you link this library with other files,
- some of which are compiled with GCC, to produce an executable,
- this library does not by itself cause the resulting executable
- to be covered by the GNU General Public License.
- This exception does not however invalidate any other reasons why
- the executable file might be covered by the GNU General Public License.
- */
-/* support functions required by the kernel. based on code from gcc-2.95.3 */
-/* I Molton 29/07/01 */
-
-#include "gcclib.h"
-
-s64 __ashrdi3(s64 u, int b)
-{
- DIunion w;
- int bm;
- DIunion uu;
-
- if (b == 0)
- return u;
-
- uu.ll = u;
-
- bm = (sizeof(s32) * BITS_PER_UNIT) - b;
- if (bm <= 0) {
- /* w.s.high = 1..1 or 0..0 */
- w.s.high = uu.s.high >> (sizeof(s32) * BITS_PER_UNIT - 1);
- w.s.low = uu.s.high >> -bm;
- } else {
- u32 carries = (u32) uu.s.high << bm;
- w.s.high = uu.s.high >> b;
- w.s.low = ((u32) uu.s.low >> b) | carries;
- }
-
- return w.ll;
-}
diff --git a/arch/arm/lib/bitops.h b/arch/arm/lib/bitops.h
index 64a988c1ad44..b8c14e936697 100644
--- a/arch/arm/lib/bitops.h
+++ b/arch/arm/lib/bitops.h
@@ -1,6 +1,6 @@
#include <linux/config.h>
-#if __LINUX_ARM_ARCH__ >= 6 && defined(CONFIG_CPU_MPCORE)
+#if __LINUX_ARM_ARCH__ >= 6 && defined(CONFIG_CPU_32v6K)
.macro bitop, instr
mov r2, #1
and r3, r0, #7 @ Get bit offset
@@ -34,7 +34,7 @@
and r2, r0, #7
mov r3, #1
mov r3, r3, lsl r2
- save_and_disable_irqs ip, r2
+ save_and_disable_irqs ip
ldrb r2, [r1, r0, lsr #3]
\instr r2, r2, r3
strb r2, [r1, r0, lsr #3]
@@ -54,7 +54,7 @@
add r1, r1, r0, lsr #3
and r3, r0, #7
mov r0, #1
- save_and_disable_irqs ip, r2
+ save_and_disable_irqs ip
ldrb r2, [r1]
tst r2, r0, lsl r3
\instr r2, r2, r0, lsl r3
diff --git a/arch/arm/lib/clear_user.S b/arch/arm/lib/clear_user.S
new file mode 100644
index 000000000000..7ff9f831b3f9
--- /dev/null
+++ b/arch/arm/lib/clear_user.S
@@ -0,0 +1,52 @@
+/*
+ * linux/arch/arm/lib/clear_user.S
+ *
+ * Copyright (C) 1995, 1996,1997,1998 Russell King
+ *
+ * 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>
+
+ .text
+
+/* Prototype: int __arch_clear_user(void *addr, size_t sz)
+ * Purpose : clear some user memory
+ * Params : addr - user memory address to clear
+ * : sz - number of bytes to clear
+ * Returns : number of bytes NOT cleared
+ */
+ENTRY(__arch_clear_user)
+ stmfd sp!, {r1, lr}
+ mov r2, #0
+ cmp r1, #4
+ blt 2f
+ ands ip, r0, #3
+ beq 1f
+ cmp ip, #2
+USER( strbt r2, [r0], #1)
+USER( strlebt r2, [r0], #1)
+USER( strltbt r2, [r0], #1)
+ rsb ip, ip, #4
+ sub r1, r1, ip @ 7 6 5 4 3 2 1
+1: subs r1, r1, #8 @ -1 -2 -3 -4 -5 -6 -7
+USER( strplt r2, [r0], #4)
+USER( strplt r2, [r0], #4)
+ bpl 1b
+ adds r1, r1, #4 @ 3 2 1 0 -1 -2 -3
+USER( strplt r2, [r0], #4)
+2: tst r1, #2 @ 1x 1x 0x 0x 1x 1x 0x
+USER( strnebt r2, [r0], #1)
+USER( strnebt r2, [r0], #1)
+ tst r1, #1 @ x1 x0 x1 x0 x1 x0 x1
+USER( strnebt r2, [r0], #1)
+ mov r0, #0
+ LOADREGS(fd,sp!, {r1, pc})
+
+ .section .fixup,"ax"
+ .align 0
+9001: LOADREGS(fd,sp!, {r0, pc})
+ .previous
+
diff --git a/arch/arm/lib/copy_from_user.S b/arch/arm/lib/copy_from_user.S
new file mode 100644
index 000000000000..7497393a0e81
--- /dev/null
+++ b/arch/arm/lib/copy_from_user.S
@@ -0,0 +1,101 @@
+/*
+ * linux/arch/arm/lib/copy_from_user.S
+ *
+ * Author: Nicolas Pitre
+ * Created: Sep 29, 2005
+ * Copyright: MontaVista Software, 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.
+ */
+
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+
+/*
+ * Prototype:
+ *
+ * size_t __arch_copy_from_user(void *to, const void *from, size_t n)
+ *
+ * Purpose:
+ *
+ * copy a block to kernel memory from user memory
+ *
+ * Params:
+ *
+ * to = kernel memory
+ * from = user memory
+ * n = number of bytes to copy
+ *
+ * Return value:
+ *
+ * Number of bytes NOT copied.
+ */
+
+ .macro ldr1w ptr reg abort
+100: ldrt \reg, [\ptr], #4
+ .section __ex_table, "a"
+ .long 100b, \abort
+ .previous
+ .endm
+
+ .macro ldr4w ptr reg1 reg2 reg3 reg4 abort
+ ldr1w \ptr, \reg1, \abort
+ ldr1w \ptr, \reg2, \abort
+ ldr1w \ptr, \reg3, \abort
+ ldr1w \ptr, \reg4, \abort
+ .endm
+
+ .macro ldr8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
+ ldr4w \ptr, \reg1, \reg2, \reg3, \reg4, \abort
+ ldr4w \ptr, \reg5, \reg6, \reg7, \reg8, \abort
+ .endm
+
+ .macro ldr1b ptr reg cond=al abort
+100: ldr\cond\()bt \reg, [\ptr], #1
+ .section __ex_table, "a"
+ .long 100b, \abort
+ .previous
+ .endm
+
+ .macro str1w ptr reg abort
+ str \reg, [\ptr], #4
+ .endm
+
+ .macro str8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
+ stmia \ptr!, {\reg1, \reg2, \reg3, \reg4, \reg5, \reg6, \reg7, \reg8}
+ .endm
+
+ .macro str1b ptr reg cond=al abort
+ str\cond\()b \reg, [\ptr], #1
+ .endm
+
+ .macro enter reg1 reg2
+ mov r3, #0
+ stmdb sp!, {r0, r2, r3, \reg1, \reg2}
+ .endm
+
+ .macro exit reg1 reg2
+ add sp, sp, #8
+ ldmfd sp!, {r0, \reg1, \reg2}
+ .endm
+
+ .text
+
+ENTRY(__arch_copy_from_user)
+
+#include "copy_template.S"
+
+ .section .fixup,"ax"
+ .align 0
+ copy_abort_preamble
+ ldmfd sp!, {r1, r2}
+ sub r3, r0, r1
+ rsb r1, r3, r2
+ str r1, [sp]
+ bl __memzero
+ ldr r0, [sp], #4
+ copy_abort_end
+ .previous
+
diff --git a/arch/arm/lib/copy_template.S b/arch/arm/lib/copy_template.S
new file mode 100644
index 000000000000..838e435e4922
--- /dev/null
+++ b/arch/arm/lib/copy_template.S
@@ -0,0 +1,255 @@
+/*
+ * linux/arch/arm/lib/copy_template.s
+ *
+ * Code template for optimized memory copy functions
+ *
+ * Author: Nicolas Pitre
+ * Created: Sep 28, 2005
+ * Copyright: MontaVista Software, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/*
+ * This can be used to enable code to cacheline align the source pointer.
+ * Experiments on tested architectures (StrongARM and XScale) didn't show
+ * this a worthwhile thing to do. That might be different in the future.
+ */
+//#define CALGN(code...) code
+#define CALGN(code...)
+
+/*
+ * Theory of operation
+ * -------------------
+ *
+ * This file provides the core code for a forward memory copy used in
+ * the implementation of memcopy(), copy_to_user() and copy_from_user().
+ *
+ * The including file must define the following accessor macros
+ * according to the need of the given function:
+ *
+ * ldr1w ptr reg abort
+ *
+ * This loads one word from 'ptr', stores it in 'reg' and increments
+ * 'ptr' to the next word. The 'abort' argument is used for fixup tables.
+ *
+ * ldr4w ptr reg1 reg2 reg3 reg4 abort
+ * ldr8w ptr, reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
+ *
+ * This loads four or eight words starting from 'ptr', stores them
+ * in provided registers and increments 'ptr' past those words.
+ * The'abort' argument is used for fixup tables.
+ *
+ * ldr1b ptr reg cond abort
+ *
+ * Similar to ldr1w, but it loads a byte and increments 'ptr' one byte.
+ * It also must apply the condition code if provided, otherwise the
+ * "al" condition is assumed by default.
+ *
+ * str1w ptr reg abort
+ * str8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
+ * str1b ptr reg cond abort
+ *
+ * Same as their ldr* counterparts, but data is stored to 'ptr' location
+ * rather than being loaded.
+ *
+ * enter reg1 reg2
+ *
+ * Preserve the provided registers on the stack plus any additional
+ * data as needed by the implementation including this code. Called
+ * upon code entry.
+ *
+ * exit reg1 reg2
+ *
+ * Restore registers with the values previously saved with the
+ * 'preserv' macro. Called upon code termination.
+ */
+
+
+ enter r4, lr
+
+ subs r2, r2, #4
+ blt 8f
+ ands ip, r0, #3
+ PLD( pld [r1, #0] )
+ bne 9f
+ ands ip, r1, #3
+ bne 10f
+
+1: subs r2, r2, #(28)
+ stmfd sp!, {r5 - r8}
+ blt 5f
+
+ CALGN( ands ip, r1, #31 )
+ CALGN( rsb r3, ip, #32 )
+ CALGN( sbcnes r4, r3, r2 ) @ C is always set here
+ CALGN( bcs 2f )
+ CALGN( adr r4, 6f )
+ CALGN( subs r2, r2, r3 ) @ C gets set
+ CALGN( add pc, r4, ip )
+
+ PLD( pld [r1, #0] )
+2: PLD( subs r2, r2, #96 )
+ PLD( pld [r1, #28] )
+ PLD( blt 4f )
+ PLD( pld [r1, #60] )
+ PLD( pld [r1, #92] )
+
+3: PLD( pld [r1, #124] )
+4: ldr8w r1, r3, r4, r5, r6, r7, r8, ip, lr, abort=20f
+ subs r2, r2, #32
+ str8w r0, r3, r4, r5, r6, r7, r8, ip, lr, abort=20f
+ bge 3b
+ PLD( cmn r2, #96 )
+ PLD( bge 4b )
+
+5: ands ip, r2, #28
+ rsb ip, ip, #32
+ addne pc, pc, ip @ C is always clear here
+ b 7f
+6: nop
+ ldr1w r1, r3, abort=20f
+ ldr1w r1, r4, abort=20f
+ ldr1w r1, r5, abort=20f
+ ldr1w r1, r6, abort=20f
+ ldr1w r1, r7, abort=20f
+ ldr1w r1, r8, abort=20f
+ ldr1w r1, lr, abort=20f
+
+ add pc, pc, ip
+ nop
+ nop
+ str1w r0, r3, abort=20f
+ str1w r0, r4, abort=20f
+ str1w r0, r5, abort=20f
+ str1w r0, r6, abort=20f
+ str1w r0, r7, abort=20f
+ str1w r0, r8, abort=20f
+ str1w r0, lr, abort=20f
+
+ CALGN( bcs 2b )
+
+7: ldmfd sp!, {r5 - r8}
+
+8: movs r2, r2, lsl #31
+ ldr1b r1, r3, ne, abort=21f
+ ldr1b r1, r4, cs, abort=21f
+ ldr1b r1, ip, cs, abort=21f
+ str1b r0, r3, ne, abort=21f
+ str1b r0, r4, cs, abort=21f
+ str1b r0, ip, cs, abort=21f
+
+ exit r4, pc
+
+9: rsb ip, ip, #4
+ cmp ip, #2
+ ldr1b r1, r3, gt, abort=21f
+ ldr1b r1, r4, ge, abort=21f
+ ldr1b r1, lr, abort=21f
+ str1b r0, r3, gt, abort=21f
+ str1b r0, r4, ge, abort=21f
+ subs r2, r2, ip
+ str1b r0, lr, abort=21f
+ blt 8b
+ ands ip, r1, #3
+ beq 1b
+
+10: bic r1, r1, #3
+ cmp ip, #2
+ ldr1w r1, lr, abort=21f
+ beq 17f
+ bgt 18f
+
+
+ .macro forward_copy_shift pull push
+
+ subs r2, r2, #28
+ blt 14f
+
+ CALGN( ands ip, r1, #31 )
+ CALGN( rsb ip, ip, #32 )
+ CALGN( sbcnes r4, ip, r2 ) @ C is always set here
+ CALGN( subcc r2, r2, ip )
+ CALGN( bcc 15f )
+
+11: stmfd sp!, {r5 - r9}
+
+ PLD( pld [r1, #0] )
+ PLD( subs r2, r2, #96 )
+ PLD( pld [r1, #28] )
+ PLD( blt 13f )
+ PLD( pld [r1, #60] )
+ PLD( pld [r1, #92] )
+
+12: PLD( pld [r1, #124] )
+13: ldr4w r1, r4, r5, r6, r7, abort=19f
+ mov r3, lr, pull #\pull
+ subs r2, r2, #32
+ ldr4w r1, r8, r9, ip, lr, abort=19f
+ orr r3, r3, r4, push #\push
+ mov r4, r4, pull #\pull
+ orr r4, r4, r5, push #\push
+ mov r5, r5, pull #\pull
+ orr r5, r5, r6, push #\push
+ mov r6, r6, pull #\pull
+ orr r6, r6, r7, push #\push
+ mov r7, r7, pull #\pull
+ orr r7, r7, r8, push #\push
+ mov r8, r8, pull #\pull
+ orr r8, r8, r9, push #\push
+ mov r9, r9, pull #\pull
+ orr r9, r9, ip, push #\push
+ mov ip, ip, pull #\pull
+ orr ip, ip, lr, push #\push
+ str8w r0, r3, r4, r5, r6, r7, r8, r9, ip, , abort=19f
+ bge 12b
+ PLD( cmn r2, #96 )
+ PLD( bge 13b )
+
+ ldmfd sp!, {r5 - r9}
+
+14: ands ip, r2, #28
+ beq 16f
+
+15: mov r3, lr, pull #\pull
+ ldr1w r1, lr, abort=21f
+ subs ip, ip, #4
+ orr r3, r3, lr, push #\push
+ str1w r0, r3, abort=21f
+ bgt 15b
+ CALGN( cmp r2, #0 )
+ CALGN( bge 11b )
+
+16: sub r1, r1, #(\push / 8)
+ b 8b
+
+ .endm
+
+
+ forward_copy_shift pull=8 push=24
+
+17: forward_copy_shift pull=16 push=16
+
+18: forward_copy_shift pull=24 push=8
+
+
+/*
+ * Abort preanble and completion macros.
+ * If a fixup handler is required then those macros must surround it.
+ * It is assumed that the fixup code will handle the private part of
+ * the exit macro.
+ */
+
+ .macro copy_abort_preamble
+19: ldmfd sp!, {r5 - r9}
+ b 21f
+20: ldmfd sp!, {r5 - r8}
+21:
+ .endm
+
+ .macro copy_abort_end
+ ldmfd sp!, {r4, pc}
+ .endm
+
diff --git a/arch/arm/lib/copy_to_user.S b/arch/arm/lib/copy_to_user.S
new file mode 100644
index 000000000000..4a6d8ea14022
--- /dev/null
+++ b/arch/arm/lib/copy_to_user.S
@@ -0,0 +1,101 @@
+/*
+ * linux/arch/arm/lib/copy_to_user.S
+ *
+ * Author: Nicolas Pitre
+ * Created: Sep 29, 2005
+ * Copyright: MontaVista Software, 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.
+ */
+
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+
+/*
+ * Prototype:
+ *
+ * size_t __arch_copy_to_user(void *to, const void *from, size_t n)
+ *
+ * Purpose:
+ *
+ * copy a block to user memory from kernel memory
+ *
+ * Params:
+ *
+ * to = user memory
+ * from = kernel memory
+ * n = number of bytes to copy
+ *
+ * Return value:
+ *
+ * Number of bytes NOT copied.
+ */
+
+ .macro ldr1w ptr reg abort
+ ldr \reg, [\ptr], #4
+ .endm
+
+ .macro ldr4w ptr reg1 reg2 reg3 reg4 abort
+ ldmia \ptr!, {\reg1, \reg2, \reg3, \reg4}
+ .endm
+
+ .macro ldr8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
+ ldmia \ptr!, {\reg1, \reg2, \reg3, \reg4, \reg5, \reg6, \reg7, \reg8}
+ .endm
+
+ .macro ldr1b ptr reg cond=al abort
+ ldr\cond\()b \reg, [\ptr], #1
+ .endm
+
+ .macro str1w ptr reg abort
+100: strt \reg, [\ptr], #4
+ .section __ex_table, "a"
+ .long 100b, \abort
+ .previous
+ .endm
+
+ .macro str8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
+ str1w \ptr, \reg1, \abort
+ str1w \ptr, \reg2, \abort
+ str1w \ptr, \reg3, \abort
+ str1w \ptr, \reg4, \abort
+ str1w \ptr, \reg5, \abort
+ str1w \ptr, \reg6, \abort
+ str1w \ptr, \reg7, \abort
+ str1w \ptr, \reg8, \abort
+ .endm
+
+ .macro str1b ptr reg cond=al abort
+100: str\cond\()bt \reg, [\ptr], #1
+ .section __ex_table, "a"
+ .long 100b, \abort
+ .previous
+ .endm
+
+ .macro enter reg1 reg2
+ mov r3, #0
+ stmdb sp!, {r0, r2, r3, \reg1, \reg2}
+ .endm
+
+ .macro exit reg1 reg2
+ add sp, sp, #8
+ ldmfd sp!, {r0, \reg1, \reg2}
+ .endm
+
+ .text
+
+ENTRY(__arch_copy_to_user)
+
+#include "copy_template.S"
+
+ .section .fixup,"ax"
+ .align 0
+ copy_abort_preamble
+ ldmfd sp!, {r1, r2, r3}
+ sub r0, r0, r1
+ rsb r0, r0, r2
+ copy_abort_end
+ .previous
+
diff --git a/arch/arm/lib/csumpartial.S b/arch/arm/lib/csumpartial.S
index cb5e3708f118..fe797cf320bb 100644
--- a/arch/arm/lib/csumpartial.S
+++ b/arch/arm/lib/csumpartial.S
@@ -39,6 +39,7 @@ td3 .req lr
/* we must have at least one byte. */
tst buf, #1 @ odd address?
+ movne sum, sum, ror #8
ldrneb td0, [buf], #1
subne len, len, #1
adcnes sum, sum, td0, put_byte_1
@@ -103,6 +104,9 @@ ENTRY(csum_partial)
cmp len, #8 @ Ensure that we have at least
blo .less8 @ 8 bytes to copy.
+ tst buf, #1
+ movne sum, sum, ror #8
+
adds sum, sum, #0 @ C = 0
tst buf, #3 @ Test destination alignment
blne .not_aligned @ aligh destination, return here
diff --git a/arch/arm/lib/gcclib.h b/arch/arm/lib/gcclib.h
deleted file mode 100644
index 8b6dcc656de7..000000000000
--- a/arch/arm/lib/gcclib.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/* gcclib.h -- definitions for various functions 'borrowed' from gcc-2.95.3 */
-/* I Molton 29/07/01 */
-
-#include <linux/types.h>
-
-#define BITS_PER_UNIT 8
-#define SI_TYPE_SIZE (sizeof(s32) * BITS_PER_UNIT)
-
-#ifdef __ARMEB__
-struct DIstruct {
- s32 high, low;
-};
-#else
-struct DIstruct {
- s32 low, high;
-};
-#endif
-
-typedef union {
- struct DIstruct s;
- s64 ll;
-} DIunion;
diff --git a/arch/arm/lib/lshrdi3.S b/arch/arm/lib/lshrdi3.S
new file mode 100644
index 000000000000..46c2ed19ec95
--- /dev/null
+++ b/arch/arm/lib/lshrdi3.S
@@ -0,0 +1,48 @@
+/* Copyright 1995, 1996, 1998, 1999, 2000, 2003, 2004, 2005
+ Free Software Foundation, Inc.
+
+This file is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option) any
+later version.
+
+In addition to the permissions in the GNU General Public License, the
+Free Software Foundation gives you unlimited permission to link the
+compiled version of this file into combinations with other programs,
+and to distribute those combinations without any restriction coming
+from the use of this file. (The General Public License restrictions
+do apply in other respects; for example, they cover modification of
+the file, and distribution when not linked into a combine
+executable.)
+
+This file 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, 51 Franklin Street, Fifth Floor,
+Boston, MA 02110-1301, USA. */
+
+
+#include <linux/linkage.h>
+
+#ifdef __ARMEB__
+#define al r1
+#define ah r0
+#else
+#define al r0
+#define ah r1
+#endif
+
+ENTRY(__lshrdi3)
+
+ subs r3, r2, #32
+ rsb ip, r2, #32
+ movmi al, al, lsr r2
+ movpl al, ah, lsr r3
+ orrmi al, al, ah, lsl ip
+ mov ah, ah, lsr r2
+ mov pc, lr
+
diff --git a/arch/arm/lib/lshrdi3.c b/arch/arm/lib/lshrdi3.c
deleted file mode 100644
index 3681f49d2b6e..000000000000
--- a/arch/arm/lib/lshrdi3.c
+++ /dev/null
@@ -1,56 +0,0 @@
-/* More subroutines needed by GCC output code on some machines. */
-/* Compile this one with gcc. */
-/* Copyright (C) 1989, 92-98, 1999 Free Software Foundation, Inc.
-
-This file is part of GNU CC.
-
-GNU CC is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
-
-GNU CC 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 GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
-
-/* As a special exception, if you link this library with other files,
- some of which are compiled with GCC, to produce an executable,
- this library does not by itself cause the resulting executable
- to be covered by the GNU General Public License.
- This exception does not however invalidate any other reasons why
- the executable file might be covered by the GNU General Public License.
- */
-/* support functions required by the kernel. based on code from gcc-2.95.3 */
-/* I Molton 29/07/01 */
-
-#include "gcclib.h"
-
-s64 __lshrdi3(s64 u, int b)
-{
- DIunion w;
- int bm;
- DIunion uu;
-
- if (b == 0)
- return u;
-
- uu.ll = u;
-
- bm = (sizeof(s32) * BITS_PER_UNIT) - b;
- if (bm <= 0) {
- w.s.high = 0;
- w.s.low = (u32) uu.s.high >> -bm;
- } else {
- u32 carries = (u32) uu.s.high << bm;
- w.s.high = (u32) uu.s.high >> b;
- w.s.low = ((u32) uu.s.low >> b) | carries;
- }
-
- return w.ll;
-}
diff --git a/arch/arm/lib/memcpy.S b/arch/arm/lib/memcpy.S
index f5a593ceb8cc..7e71d6708a8d 100644
--- a/arch/arm/lib/memcpy.S
+++ b/arch/arm/lib/memcpy.S
@@ -1,393 +1,59 @@
/*
* linux/arch/arm/lib/memcpy.S
*
- * Copyright (C) 1995-1999 Russell King
+ * Author: Nicolas Pitre
+ * Created: Sep 28, 2005
+ * Copyright: MontaVista Software, 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.
- *
- * ASM optimised string functions
+ * 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>
- .text
-
-#define ENTER \
- mov ip,sp ;\
- stmfd sp!,{r0,r4-r9,fp,ip,lr,pc} ;\
- sub fp,ip,#4
-
-#define EXIT \
- LOADREGS(ea, fp, {r0, r4 - r9, fp, sp, pc})
-
-#define EXITEQ \
- LOADREGS(eqea, fp, {r0, r4 - r9, fp, sp, pc})
-
-/*
- * Prototype: void memcpy(void *to,const void *from,unsigned long n);
- */
-ENTRY(memcpy)
-ENTRY(memmove)
- ENTER
- cmp r1, r0
- bcc 23f
- subs r2, r2, #4
- blt 6f
- PLD( pld [r1, #0] )
- ands ip, r0, #3
- bne 7f
- ands ip, r1, #3
- bne 8f
+ .macro ldr1w ptr reg abort
+ ldr \reg, [\ptr], #4
+ .endm
-1: subs r2, r2, #8
- blt 5f
- subs r2, r2, #20
- blt 4f
- PLD( pld [r1, #28] )
- PLD( subs r2, r2, #64 )
- PLD( blt 3f )
-2: PLD( pld [r1, #60] )
- PLD( pld [r1, #92] )
- ldmia r1!, {r3 - r9, ip}
- subs r2, r2, #32
- stmgeia r0!, {r3 - r9, ip}
- ldmgeia r1!, {r3 - r9, ip}
- subges r2, r2, #32
- stmia r0!, {r3 - r9, ip}
- bge 2b
-3: PLD( ldmia r1!, {r3 - r9, ip} )
- PLD( adds r2, r2, #32 )
- PLD( stmgeia r0!, {r3 - r9, ip} )
- PLD( ldmgeia r1!, {r3 - r9, ip} )
- PLD( subges r2, r2, #32 )
- PLD( stmia r0!, {r3 - r9, ip} )
-4: cmn r2, #16
- ldmgeia r1!, {r3 - r6}
- subge r2, r2, #16
- stmgeia r0!, {r3 - r6}
- adds r2, r2, #20
- ldmgeia r1!, {r3 - r5}
- subge r2, r2, #12
- stmgeia r0!, {r3 - r5}
-5: adds r2, r2, #8
- blt 6f
- subs r2, r2, #4
- ldrlt r3, [r1], #4
- ldmgeia r1!, {r4, r5}
- subge r2, r2, #4
- strlt r3, [r0], #4
- stmgeia r0!, {r4, r5}
+ .macro ldr4w ptr reg1 reg2 reg3 reg4 abort
+ ldmia \ptr!, {\reg1, \reg2, \reg3, \reg4}
+ .endm
-6: adds r2, r2, #4
- EXITEQ
- cmp r2, #2
- ldrb r3, [r1], #1
- ldrgeb r4, [r1], #1
- ldrgtb r5, [r1], #1
- strb r3, [r0], #1
- strgeb r4, [r0], #1
- strgtb r5, [r0], #1
- EXIT
+ .macro ldr8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
+ ldmia \ptr!, {\reg1, \reg2, \reg3, \reg4, \reg5, \reg6, \reg7, \reg8}
+ .endm
-7: rsb ip, ip, #4
- cmp ip, #2
- ldrb r3, [r1], #1
- ldrgeb r4, [r1], #1
- ldrgtb r5, [r1], #1
- strb r3, [r0], #1
- strgeb r4, [r0], #1
- strgtb r5, [r0], #1
- subs r2, r2, ip
- blt 6b
- ands ip, r1, #3
- beq 1b
+ .macro ldr1b ptr reg cond=al abort
+ ldr\cond\()b \reg, [\ptr], #1
+ .endm
-8: bic r1, r1, #3
- ldr r7, [r1], #4
- cmp ip, #2
- bgt 18f
- beq 13f
- cmp r2, #12
- blt 11f
- PLD( pld [r1, #12] )
- sub r2, r2, #12
- PLD( subs r2, r2, #32 )
- PLD( blt 10f )
- PLD( pld [r1, #28] )
-9: PLD( pld [r1, #44] )
-10: mov r3, r7, pull #8
- ldmia r1!, {r4 - r7}
- subs r2, r2, #16
- orr r3, r3, r4, push #24
- mov r4, r4, pull #8
- orr r4, r4, r5, push #24
- mov r5, r5, pull #8
- orr r5, r5, r6, push #24
- mov r6, r6, pull #8
- orr r6, r6, r7, push #24
- stmia r0!, {r3 - r6}
- bge 9b
- PLD( cmn r2, #32 )
- PLD( bge 10b )
- PLD( add r2, r2, #32 )
- adds r2, r2, #12
- blt 12f
-11: mov r3, r7, pull #8
- ldr r7, [r1], #4
- subs r2, r2, #4
- orr r3, r3, r7, push #24
- str r3, [r0], #4
- bge 11b
-12: sub r1, r1, #3
- b 6b
+ .macro str1w ptr reg abort
+ str \reg, [\ptr], #4
+ .endm
-13: cmp r2, #12
- blt 16f
- PLD( pld [r1, #12] )
- sub r2, r2, #12
- PLD( subs r2, r2, #32 )
- PLD( blt 15f )
- PLD( pld [r1, #28] )
-14: PLD( pld [r1, #44] )
-15: mov r3, r7, pull #16
- ldmia r1!, {r4 - r7}
- subs r2, r2, #16
- orr r3, r3, r4, push #16
- mov r4, r4, pull #16
- orr r4, r4, r5, push #16
- mov r5, r5, pull #16
- orr r5, r5, r6, push #16
- mov r6, r6, pull #16
- orr r6, r6, r7, push #16
- stmia r0!, {r3 - r6}
- bge 14b
- PLD( cmn r2, #32 )
- PLD( bge 15b )
- PLD( add r2, r2, #32 )
- adds r2, r2, #12
- blt 17f
-16: mov r3, r7, pull #16
- ldr r7, [r1], #4
- subs r2, r2, #4
- orr r3, r3, r7, push #16
- str r3, [r0], #4
- bge 16b
-17: sub r1, r1, #2
- b 6b
+ .macro str8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
+ stmia \ptr!, {\reg1, \reg2, \reg3, \reg4, \reg5, \reg6, \reg7, \reg8}
+ .endm
-18: cmp r2, #12
- blt 21f
- PLD( pld [r1, #12] )
- sub r2, r2, #12
- PLD( subs r2, r2, #32 )
- PLD( blt 20f )
- PLD( pld [r1, #28] )
-19: PLD( pld [r1, #44] )
-20: mov r3, r7, pull #24
- ldmia r1!, {r4 - r7}
- subs r2, r2, #16
- orr r3, r3, r4, push #8
- mov r4, r4, pull #24
- orr r4, r4, r5, push #8
- mov r5, r5, pull #24
- orr r5, r5, r6, push #8
- mov r6, r6, pull #24
- orr r6, r6, r7, push #8
- stmia r0!, {r3 - r6}
- bge 19b
- PLD( cmn r2, #32 )
- PLD( bge 20b )
- PLD( add r2, r2, #32 )
- adds r2, r2, #12
- blt 22f
-21: mov r3, r7, pull #24
- ldr r7, [r1], #4
- subs r2, r2, #4
- orr r3, r3, r7, push #8
- str r3, [r0], #4
- bge 21b
-22: sub r1, r1, #1
- b 6b
+ .macro str1b ptr reg cond=al abort
+ str\cond\()b \reg, [\ptr], #1
+ .endm
+ .macro enter reg1 reg2
+ stmdb sp!, {r0, \reg1, \reg2}
+ .endm
-23: add r1, r1, r2
- add r0, r0, r2
- subs r2, r2, #4
- blt 29f
- PLD( pld [r1, #-4] )
- ands ip, r0, #3
- bne 30f
- ands ip, r1, #3
- bne 31f
+ .macro exit reg1 reg2
+ ldmfd sp!, {r0, \reg1, \reg2}
+ .endm
-24: subs r2, r2, #8
- blt 28f
- subs r2, r2, #20
- blt 27f
- PLD( pld [r1, #-32] )
- PLD( subs r2, r2, #64 )
- PLD( blt 26f )
-25: PLD( pld [r1, #-64] )
- PLD( pld [r1, #-96] )
- ldmdb r1!, {r3 - r9, ip}
- subs r2, r2, #32
- stmgedb r0!, {r3 - r9, ip}
- ldmgedb r1!, {r3 - r9, ip}
- subges r2, r2, #32
- stmdb r0!, {r3 - r9, ip}
- bge 25b
-26: PLD( ldmdb r1!, {r3 - r9, ip} )
- PLD( adds r2, r2, #32 )
- PLD( stmgedb r0!, {r3 - r9, ip} )
- PLD( ldmgedb r1!, {r3 - r9, ip} )
- PLD( subges r2, r2, #32 )
- PLD( stmdb r0!, {r3 - r9, ip} )
-27: cmn r2, #16
- ldmgedb r1!, {r3 - r6}
- subge r2, r2, #16
- stmgedb r0!, {r3 - r6}
- adds r2, r2, #20
- ldmgedb r1!, {r3 - r5}
- subge r2, r2, #12
- stmgedb r0!, {r3 - r5}
-28: adds r2, r2, #8
- blt 29f
- subs r2, r2, #4
- ldrlt r3, [r1, #-4]!
- ldmgedb r1!, {r4, r5}
- subge r2, r2, #4
- strlt r3, [r0, #-4]!
- stmgedb r0!, {r4, r5}
+ .text
-29: adds r2, r2, #4
- EXITEQ
- cmp r2, #2
- ldrb r3, [r1, #-1]!
- ldrgeb r4, [r1, #-1]!
- ldrgtb r5, [r1, #-1]!
- strb r3, [r0, #-1]!
- strgeb r4, [r0, #-1]!
- strgtb r5, [r0, #-1]!
- EXIT
+/* Prototype: void *memcpy(void *dest, const void *src, size_t n); */
-30: cmp ip, #2
- ldrb r3, [r1, #-1]!
- ldrgeb r4, [r1, #-1]!
- ldrgtb r5, [r1, #-1]!
- strb r3, [r0, #-1]!
- strgeb r4, [r0, #-1]!
- strgtb r5, [r0, #-1]!
- subs r2, r2, ip
- blt 29b
- ands ip, r1, #3
- beq 24b
-
-31: bic r1, r1, #3
- ldr r3, [r1], #0
- cmp ip, #2
- blt 41f
- beq 36f
- cmp r2, #12
- blt 34f
- PLD( pld [r1, #-16] )
- sub r2, r2, #12
- PLD( subs r2, r2, #32 )
- PLD( blt 33f )
- PLD( pld [r1, #-32] )
-32: PLD( pld [r1, #-48] )
-33: mov r7, r3, push #8
- ldmdb r1!, {r3, r4, r5, r6}
- subs r2, r2, #16
- orr r7, r7, r6, pull #24
- mov r6, r6, push #8
- orr r6, r6, r5, pull #24
- mov r5, r5, push #8
- orr r5, r5, r4, pull #24
- mov r4, r4, push #8
- orr r4, r4, r3, pull #24
- stmdb r0!, {r4, r5, r6, r7}
- bge 32b
- PLD( cmn r2, #32 )
- PLD( bge 33b )
- PLD( add r2, r2, #32 )
- adds r2, r2, #12
- blt 35f
-34: mov ip, r3, push #8
- ldr r3, [r1, #-4]!
- subs r2, r2, #4
- orr ip, ip, r3, pull #24
- str ip, [r0, #-4]!
- bge 34b
-35: add r1, r1, #3
- b 29b
-
-36: cmp r2, #12
- blt 39f
- PLD( pld [r1, #-16] )
- sub r2, r2, #12
- PLD( subs r2, r2, #32 )
- PLD( blt 38f )
- PLD( pld [r1, #-32] )
-37: PLD( pld [r1, #-48] )
-38: mov r7, r3, push #16
- ldmdb r1!, {r3, r4, r5, r6}
- subs r2, r2, #16
- orr r7, r7, r6, pull #16
- mov r6, r6, push #16
- orr r6, r6, r5, pull #16
- mov r5, r5, push #16
- orr r5, r5, r4, pull #16
- mov r4, r4, push #16
- orr r4, r4, r3, pull #16
- stmdb r0!, {r4, r5, r6, r7}
- bge 37b
- PLD( cmn r2, #32 )
- PLD( bge 38b )
- PLD( add r2, r2, #32 )
- adds r2, r2, #12
- blt 40f
-39: mov ip, r3, push #16
- ldr r3, [r1, #-4]!
- subs r2, r2, #4
- orr ip, ip, r3, pull #16
- str ip, [r0, #-4]!
- bge 39b
-40: add r1, r1, #2
- b 29b
+ENTRY(memcpy)
-41: cmp r2, #12
- blt 44f
- PLD( pld [r1, #-16] )
- sub r2, r2, #12
- PLD( subs r2, r2, #32 )
- PLD( blt 43f )
- PLD( pld [r1, #-32] )
-42: PLD( pld [r1, #-48] )
-43: mov r7, r3, push #24
- ldmdb r1!, {r3, r4, r5, r6}
- subs r2, r2, #16
- orr r7, r7, r6, pull #8
- mov r6, r6, push #24
- orr r6, r6, r5, pull #8
- mov r5, r5, push #24
- orr r5, r5, r4, pull #8
- mov r4, r4, push #24
- orr r4, r4, r3, pull #8
- stmdb r0!, {r4, r5, r6, r7}
- bge 42b
- PLD( cmn r2, #32 )
- PLD( bge 43b )
- PLD( add r2, r2, #32 )
- adds r2, r2, #12
- blt 45f
-44: mov ip, r3, push #24
- ldr r3, [r1, #-4]!
- subs r2, r2, #4
- orr ip, ip, r3, pull #8
- str ip, [r0, #-4]!
- bge 44b
-45: add r1, r1, #1
- b 29b
+#include "copy_template.S"
diff --git a/arch/arm/lib/memmove.S b/arch/arm/lib/memmove.S
new file mode 100644
index 000000000000..ef7fddc14ac9
--- /dev/null
+++ b/arch/arm/lib/memmove.S
@@ -0,0 +1,206 @@
+/*
+ * linux/arch/arm/lib/memmove.S
+ *
+ * Author: Nicolas Pitre
+ * Created: Sep 28, 2005
+ * Copyright: (C) MontaVista Software 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.
+ */
+
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+
+/*
+ * This can be used to enable code to cacheline align the source pointer.
+ * Experiments on tested architectures (StrongARM and XScale) didn't show
+ * this a worthwhile thing to do. That might be different in the future.
+ */
+//#define CALGN(code...) code
+#define CALGN(code...)
+
+ .text
+
+/*
+ * Prototype: void *memmove(void *dest, const void *src, size_t n);
+ *
+ * Note:
+ *
+ * If the memory regions don't overlap, we simply branch to memcpy which is
+ * normally a bit faster. Otherwise the copy is done going downwards. This
+ * is a transposition of the code from copy_template.S but with the copy
+ * occurring in the opposite direction.
+ */
+
+ENTRY(memmove)
+
+ subs ip, r0, r1
+ cmphi r2, ip
+ bls memcpy
+
+ stmfd sp!, {r0, r4, lr}
+ add r1, r1, r2
+ add r0, r0, r2
+ subs r2, r2, #4
+ blt 8f
+ ands ip, r0, #3
+ PLD( pld [r1, #-4] )
+ bne 9f
+ ands ip, r1, #3
+ bne 10f
+
+1: subs r2, r2, #(28)
+ stmfd sp!, {r5 - r8}
+ blt 5f
+
+ CALGN( ands ip, r1, #31 )
+ CALGN( sbcnes r4, ip, r2 ) @ C is always set here
+ CALGN( bcs 2f )
+ CALGN( adr r4, 6f )
+ CALGN( subs r2, r2, ip ) @ C is set here
+ CALGN( add pc, r4, ip )
+
+ PLD( pld [r1, #-4] )
+2: PLD( subs r2, r2, #96 )
+ PLD( pld [r1, #-32] )
+ PLD( blt 4f )
+ PLD( pld [r1, #-64] )
+ PLD( pld [r1, #-96] )
+
+3: PLD( pld [r1, #-128] )
+4: ldmdb r1!, {r3, r4, r5, r6, r7, r8, ip, lr}
+ subs r2, r2, #32
+ stmdb r0!, {r3, r4, r5, r6, r7, r8, ip, lr}
+ bge 3b
+ PLD( cmn r2, #96 )
+ PLD( bge 4b )
+
+5: ands ip, r2, #28
+ rsb ip, ip, #32
+ addne pc, pc, ip @ C is always clear here
+ b 7f
+6: nop
+ ldr r3, [r1, #-4]!
+ ldr r4, [r1, #-4]!
+ ldr r5, [r1, #-4]!
+ ldr r6, [r1, #-4]!
+ ldr r7, [r1, #-4]!
+ ldr r8, [r1, #-4]!
+ ldr lr, [r1, #-4]!
+
+ add pc, pc, ip
+ nop
+ nop
+ str r3, [r0, #-4]!
+ str r4, [r0, #-4]!
+ str r5, [r0, #-4]!
+ str r6, [r0, #-4]!
+ str r7, [r0, #-4]!
+ str r8, [r0, #-4]!
+ str lr, [r0, #-4]!
+
+ CALGN( bcs 2b )
+
+7: ldmfd sp!, {r5 - r8}
+
+8: movs r2, r2, lsl #31
+ ldrneb r3, [r1, #-1]!
+ ldrcsb r4, [r1, #-1]!
+ ldrcsb ip, [r1, #-1]
+ strneb r3, [r0, #-1]!
+ strcsb r4, [r0, #-1]!
+ strcsb ip, [r0, #-1]
+ ldmfd sp!, {r0, r4, pc}
+
+9: cmp ip, #2
+ ldrgtb r3, [r1, #-1]!
+ ldrgeb r4, [r1, #-1]!
+ ldrb lr, [r1, #-1]!
+ strgtb r3, [r0, #-1]!
+ strgeb r4, [r0, #-1]!
+ subs r2, r2, ip
+ strb lr, [r0, #-1]!
+ blt 8b
+ ands ip, r1, #3
+ beq 1b
+
+10: bic r1, r1, #3
+ cmp ip, #2
+ ldr r3, [r1, #0]
+ beq 17f
+ blt 18f
+
+
+ .macro backward_copy_shift push pull
+
+ subs r2, r2, #28
+ blt 14f
+
+ CALGN( ands ip, r1, #31 )
+ CALGN( rsb ip, ip, #32 )
+ CALGN( sbcnes r4, ip, r2 ) @ C is always set here
+ CALGN( subcc r2, r2, ip )
+ CALGN( bcc 15f )
+
+11: stmfd sp!, {r5 - r9}
+
+ PLD( pld [r1, #-4] )
+ PLD( subs r2, r2, #96 )
+ PLD( pld [r1, #-32] )
+ PLD( blt 13f )
+ PLD( pld [r1, #-64] )
+ PLD( pld [r1, #-96] )
+
+12: PLD( pld [r1, #-128] )
+13: ldmdb r1!, {r7, r8, r9, ip}
+ mov lr, r3, push #\push
+ subs r2, r2, #32
+ ldmdb r1!, {r3, r4, r5, r6}
+ orr lr, lr, ip, pull #\pull
+ mov ip, ip, push #\push
+ orr ip, ip, r9, pull #\pull
+ mov r9, r9, push #\push
+ orr r9, r9, r8, pull #\pull
+ mov r8, r8, push #\push
+ orr r8, r8, r7, pull #\pull
+ mov r7, r7, push #\push
+ orr r7, r7, r6, pull #\pull
+ mov r6, r6, push #\push
+ orr r6, r6, r5, pull #\pull
+ mov r5, r5, push #\push
+ orr r5, r5, r4, pull #\pull
+ mov r4, r4, push #\push
+ orr r4, r4, r3, pull #\pull
+ stmdb r0!, {r4 - r9, ip, lr}
+ bge 12b
+ PLD( cmn r2, #96 )
+ PLD( bge 13b )
+
+ ldmfd sp!, {r5 - r9}
+
+14: ands ip, r2, #28
+ beq 16f
+
+15: mov lr, r3, push #\push
+ ldr r3, [r1, #-4]!
+ subs ip, ip, #4
+ orr lr, lr, r3, pull #\pull
+ str lr, [r0, #-4]!
+ bgt 15b
+ CALGN( cmp r2, #0 )
+ CALGN( bge 11b )
+
+16: add r1, r1, #(\pull / 8)
+ b 8b
+
+ .endm
+
+
+ backward_copy_shift push=8 pull=24
+
+17: backward_copy_shift push=16 pull=16
+
+18: backward_copy_shift push=24 pull=8
+
diff --git a/arch/arm/lib/muldi3.S b/arch/arm/lib/muldi3.S
new file mode 100644
index 000000000000..c7fbdf005319
--- /dev/null
+++ b/arch/arm/lib/muldi3.S
@@ -0,0 +1,44 @@
+/*
+ * linux/arch/arm/lib/muldi3.S
+ *
+ * Author: Nicolas Pitre
+ * Created: Oct 19, 2005
+ * Copyright: Monta Vista Software, 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.
+ */
+
+#include <linux/linkage.h>
+
+#ifdef __ARMEB__
+#define xh r0
+#define xl r1
+#define yh r2
+#define yl r3
+#else
+#define xl r0
+#define xh r1
+#define yl r2
+#define yh r3
+#endif
+
+ENTRY(__muldi3)
+
+ mul xh, yl, xh
+ mla xh, xl, yh, xh
+ mov ip, xl, asr #16
+ mov yh, yl, asr #16
+ bic xl, xl, ip, lsl #16
+ bic yl, yl, yh, lsl #16
+ mla xh, yh, ip, xh
+ mul yh, xl, yh
+ mul xl, yl, xl
+ mul ip, yl, ip
+ adds xl, xl, yh, lsl #16
+ adc xh, xh, yh, lsr #16
+ adds xl, xl, ip, lsl #16
+ adc xh, xh, ip, lsr #16
+ mov pc, lr
+
diff --git a/arch/arm/lib/muldi3.c b/arch/arm/lib/muldi3.c
deleted file mode 100644
index 0a3b93313f18..000000000000
--- a/arch/arm/lib/muldi3.c
+++ /dev/null
@@ -1,72 +0,0 @@
-/* More subroutines needed by GCC output code on some machines. */
-/* Compile this one with gcc. */
-/* Copyright (C) 1989, 92-98, 1999 Free Software Foundation, Inc.
-
-This file is part of GNU CC.
-
-GNU CC is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
-
-GNU CC 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 GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
-
-/* As a special exception, if you link this library with other files,
- some of which are compiled with GCC, to produce an executable,
- this library does not by itself cause the resulting executable
- to be covered by the GNU General Public License.
- This exception does not however invalidate any other reasons why
- the executable file might be covered by the GNU General Public License.
- */
-/* support functions required by the kernel. based on code from gcc-2.95.3 */
-/* I Molton 29/07/01 */
-
-#include "gcclib.h"
-
-#define umul_ppmm(xh, xl, a, b) \
-{register u32 __t0, __t1, __t2; \
- __asm__ ("%@ Inlined umul_ppmm \n\
- mov %2, %5, lsr #16 \n\
- mov %0, %6, lsr #16 \n\
- bic %3, %5, %2, lsl #16 \n\
- bic %4, %6, %0, lsl #16 \n\
- mul %1, %3, %4 \n\
- mul %4, %2, %4 \n\
- mul %3, %0, %3 \n\
- mul %0, %2, %0 \n\
- adds %3, %4, %3 \n\
- addcs %0, %0, #65536 \n\
- adds %1, %1, %3, lsl #16 \n\
- adc %0, %0, %3, lsr #16" \
- : "=&r" ((u32) (xh)), \
- "=r" ((u32) (xl)), \
- "=&r" (__t0), "=&r" (__t1), "=r" (__t2) \
- : "r" ((u32) (a)), \
- "r" ((u32) (b)));}
-
-#define __umulsidi3(u, v) \
- ({DIunion __w; \
- umul_ppmm (__w.s.high, __w.s.low, u, v); \
- __w.ll; })
-
-s64 __muldi3(s64 u, s64 v)
-{
- DIunion w;
- DIunion uu, vv;
-
- uu.ll = u, vv.ll = v;
-
- w.ll = __umulsidi3(uu.s.low, vv.s.low);
- w.s.high += ((u32) uu.s.low * (u32) vv.s.high
- + (u32) uu.s.high * (u32) vv.s.low);
-
- return w.ll;
-}
diff --git a/arch/arm/lib/sha1.S b/arch/arm/lib/sha1.S
new file mode 100644
index 000000000000..ff6ece487ffc
--- /dev/null
+++ b/arch/arm/lib/sha1.S
@@ -0,0 +1,206 @@
+/*
+ * linux/arch/arm/lib/sha1.S
+ *
+ * SHA transform optimized for ARM
+ *
+ * Copyright: (C) 2005 by Nicolas Pitre <nico@cam.org>
+ * Created: September 17, 2005
+ *
+ * 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.
+ *
+ * The reference implementation for this code is linux/lib/sha1.c
+ */
+
+#include <linux/linkage.h>
+
+ .text
+
+
+/*
+ * void sha_transform(__u32 *digest, const char *in, __u32 *W)
+ *
+ * Note: the "in" ptr may be unaligned.
+ */
+
+ENTRY(sha_transform)
+
+ stmfd sp!, {r4 - r8, lr}
+
+ @ for (i = 0; i < 16; i++)
+ @ W[i] = be32_to_cpu(in[i]); */
+
+#ifdef __ARMEB__
+ mov r4, r0
+ mov r0, r2
+ mov r2, #64
+ bl memcpy
+ mov r2, r0
+ mov r0, r4
+#else
+ mov r3, r2
+ mov lr, #16
+1: ldrb r4, [r1], #1
+ ldrb r5, [r1], #1
+ ldrb r6, [r1], #1
+ ldrb r7, [r1], #1
+ subs lr, lr, #1
+ orr r5, r5, r4, lsl #8
+ orr r6, r6, r5, lsl #8
+ orr r7, r7, r6, lsl #8
+ str r7, [r3], #4
+ bne 1b
+#endif
+
+ @ for (i = 0; i < 64; i++)
+ @ W[i+16] = ror(W[i+13] ^ W[i+8] ^ W[i+2] ^ W[i], 31);
+
+ sub r3, r2, #4
+ mov lr, #64
+2: ldr r4, [r3, #4]!
+ subs lr, lr, #1
+ ldr r5, [r3, #8]
+ ldr r6, [r3, #32]
+ ldr r7, [r3, #52]
+ eor r4, r4, r5
+ eor r4, r4, r6
+ eor r4, r4, r7
+ mov r4, r4, ror #31
+ str r4, [r3, #64]
+ bne 2b
+
+ /*
+ * The SHA functions are:
+ *
+ * f1(B,C,D) = (D ^ (B & (C ^ D)))
+ * f2(B,C,D) = (B ^ C ^ D)
+ * f3(B,C,D) = ((B & C) | (D & (B | C)))
+ *
+ * Then the sub-blocks are processed as follows:
+ *
+ * A' = ror(A, 27) + f(B,C,D) + E + K + *W++
+ * B' = A
+ * C' = ror(B, 2)
+ * D' = C
+ * E' = D
+ *
+ * We therefore unroll each loop 5 times to avoid register shuffling.
+ * Also the ror for C (and also D and E which are successivelyderived
+ * from it) is applied in place to cut on an additional mov insn for
+ * each round.
+ */
+
+ .macro sha_f1, A, B, C, D, E
+ ldr r3, [r2], #4
+ eor ip, \C, \D
+ add \E, r1, \E, ror #2
+ and ip, \B, ip, ror #2
+ add \E, \E, \A, ror #27
+ eor ip, ip, \D, ror #2
+ add \E, \E, r3
+ add \E, \E, ip
+ .endm
+
+ .macro sha_f2, A, B, C, D, E
+ ldr r3, [r2], #4
+ add \E, r1, \E, ror #2
+ eor ip, \B, \C, ror #2
+ add \E, \E, \A, ror #27
+ eor ip, ip, \D, ror #2
+ add \E, \E, r3
+ add \E, \E, ip
+ .endm
+
+ .macro sha_f3, A, B, C, D, E
+ ldr r3, [r2], #4
+ add \E, r1, \E, ror #2
+ orr ip, \B, \C, ror #2
+ add \E, \E, \A, ror #27
+ and ip, ip, \D, ror #2
+ add \E, \E, r3
+ and r3, \B, \C, ror #2
+ orr ip, ip, r3
+ add \E, \E, ip
+ .endm
+
+ ldmia r0, {r4 - r8}
+
+ mov lr, #4
+ ldr r1, .L_sha_K + 0
+
+ /* adjust initial values */
+ mov r6, r6, ror #30
+ mov r7, r7, ror #30
+ mov r8, r8, ror #30
+
+3: subs lr, lr, #1
+ sha_f1 r4, r5, r6, r7, r8
+ sha_f1 r8, r4, r5, r6, r7
+ sha_f1 r7, r8, r4, r5, r6
+ sha_f1 r6, r7, r8, r4, r5
+ sha_f1 r5, r6, r7, r8, r4
+ bne 3b
+
+ ldr r1, .L_sha_K + 4
+ mov lr, #4
+
+4: subs lr, lr, #1
+ sha_f2 r4, r5, r6, r7, r8
+ sha_f2 r8, r4, r5, r6, r7
+ sha_f2 r7, r8, r4, r5, r6
+ sha_f2 r6, r7, r8, r4, r5
+ sha_f2 r5, r6, r7, r8, r4
+ bne 4b
+
+ ldr r1, .L_sha_K + 8
+ mov lr, #4
+
+5: subs lr, lr, #1
+ sha_f3 r4, r5, r6, r7, r8
+ sha_f3 r8, r4, r5, r6, r7
+ sha_f3 r7, r8, r4, r5, r6
+ sha_f3 r6, r7, r8, r4, r5
+ sha_f3 r5, r6, r7, r8, r4
+ bne 5b
+
+ ldr r1, .L_sha_K + 12
+ mov lr, #4
+
+6: subs lr, lr, #1
+ sha_f2 r4, r5, r6, r7, r8
+ sha_f2 r8, r4, r5, r6, r7
+ sha_f2 r7, r8, r4, r5, r6
+ sha_f2 r6, r7, r8, r4, r5
+ sha_f2 r5, r6, r7, r8, r4
+ bne 6b
+
+ ldmia r0, {r1, r2, r3, ip, lr}
+ add r4, r1, r4
+ add r5, r2, r5
+ add r6, r3, r6, ror #2
+ add r7, ip, r7, ror #2
+ add r8, lr, r8, ror #2
+ stmia r0, {r4 - r8}
+
+ ldmfd sp!, {r4 - r8, pc}
+
+.L_sha_K:
+ .word 0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6
+
+
+/*
+ * void sha_init(__u32 *buf)
+ */
+
+.L_sha_initial_digest:
+ .word 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0
+
+ENTRY(sha_init)
+
+ str lr, [sp, #-4]!
+ adr r1, .L_sha_initial_digest
+ ldmia r1, {r1, r2, r3, ip, lr}
+ stmia r0, {r1, r2, r3, ip, lr}
+ ldr pc, [sp], #4
+
diff --git a/arch/arm/lib/uaccess.S b/arch/arm/lib/uaccess.S
index d3ed0636c008..6f1b5b49fe4c 100644
--- a/arch/arm/lib/uaccess.S
+++ b/arch/arm/lib/uaccess.S
@@ -43,8 +43,6 @@ ENTRY(__arch_copy_to_user)
stmfd sp!, {r2, r4 - r7, lr}
cmp r2, #4
blt .c2u_not_enough
- PLD( pld [r1, #0] )
- PLD( pld [r0, #0] )
ands ip, r0, #3
bne .c2u_dest_not_aligned
.c2u_dest_aligned:
@@ -73,25 +71,13 @@ USER( strt r3, [r0], #4) @ May fault
sub r2, r2, ip
subs ip, ip, #32
blt .c2u_0rem8lp
- PLD( pld [r1, #28] )
- PLD( pld [r0, #28] )
- PLD( subs ip, ip, #64 )
- PLD( blt .c2u_0cpynopld )
- PLD( pld [r1, #60] )
- PLD( pld [r0, #60] )
-
-.c2u_0cpy8lp:
- PLD( pld [r1, #92] )
- PLD( pld [r0, #92] )
-.c2u_0cpynopld: ldmia r1!, {r3 - r6}
+
+.c2u_0cpy8lp: ldmia r1!, {r3 - r6}
stmia r0!, {r3 - r6} @ Shouldnt fault
ldmia r1!, {r3 - r6}
subs ip, ip, #32
stmia r0!, {r3 - r6} @ Shouldnt fault
bpl .c2u_0cpy8lp
- PLD( cmn ip, #64 )
- PLD( bge .c2u_0cpynopld )
- PLD( add ip, ip, #64 )
.c2u_0rem8lp: cmn ip, #16
ldmgeia r1!, {r3 - r6}
@@ -143,17 +129,8 @@ USER( strt r3, [r0], #4) @ May fault
sub r2, r2, ip
subs ip, ip, #16
blt .c2u_1rem8lp
- PLD( pld [r1, #12] )
- PLD( pld [r0, #12] )
- PLD( subs ip, ip, #32 )
- PLD( blt .c2u_1cpynopld )
- PLD( pld [r1, #28] )
- PLD( pld [r0, #28] )
-
-.c2u_1cpy8lp:
- PLD( pld [r1, #44] )
- PLD( pld [r0, #44] )
-.c2u_1cpynopld: mov r3, r7, pull #8
+
+.c2u_1cpy8lp: mov r3, r7, pull #8
ldmia r1!, {r4 - r7}
subs ip, ip, #16
orr r3, r3, r4, push #24
@@ -165,9 +142,6 @@ USER( strt r3, [r0], #4) @ May fault
orr r6, r6, r7, push #24
stmia r0!, {r3 - r6} @ Shouldnt fault
bpl .c2u_1cpy8lp
- PLD( cmn ip, #32 )
- PLD( bge .c2u_1cpynopld )
- PLD( add ip, ip, #32 )
.c2u_1rem8lp: tst ip, #8
movne r3, r7, pull #8
@@ -210,17 +184,8 @@ USER( strt r3, [r0], #4) @ May fault
sub r2, r2, ip
subs ip, ip, #16
blt .c2u_2rem8lp
- PLD( pld [r1, #12] )
- PLD( pld [r0, #12] )
- PLD( subs ip, ip, #32 )
- PLD( blt .c2u_2cpynopld )
- PLD( pld [r1, #28] )
- PLD( pld [r0, #28] )
-
-.c2u_2cpy8lp:
- PLD( pld [r1, #44] )
- PLD( pld [r0, #44] )
-.c2u_2cpynopld: mov r3, r7, pull #16
+
+.c2u_2cpy8lp: mov r3, r7, pull #16
ldmia r1!, {r4 - r7}
subs ip, ip, #16
orr r3, r3, r4, push #16
@@ -232,9 +197,6 @@ USER( strt r3, [r0], #4) @ May fault
orr r6, r6, r7, push #16
stmia r0!, {r3 - r6} @ Shouldnt fault
bpl .c2u_2cpy8lp
- PLD( cmn ip, #32 )
- PLD( bge .c2u_2cpynopld )
- PLD( add ip, ip, #32 )
.c2u_2rem8lp: tst ip, #8
movne r3, r7, pull #16
@@ -277,17 +239,8 @@ USER( strt r3, [r0], #4) @ May fault
sub r2, r2, ip
subs ip, ip, #16
blt .c2u_3rem8lp
- PLD( pld [r1, #12] )
- PLD( pld [r0, #12] )
- PLD( subs ip, ip, #32 )
- PLD( blt .c2u_3cpynopld )
- PLD( pld [r1, #28] )
- PLD( pld [r0, #28] )
-
-.c2u_3cpy8lp:
- PLD( pld [r1, #44] )
- PLD( pld [r0, #44] )
-.c2u_3cpynopld: mov r3, r7, pull #24
+
+.c2u_3cpy8lp: mov r3, r7, pull #24
ldmia r1!, {r4 - r7}
subs ip, ip, #16
orr r3, r3, r4, push #8
@@ -299,9 +252,6 @@ USER( strt r3, [r0], #4) @ May fault
orr r6, r6, r7, push #8
stmia r0!, {r3 - r6} @ Shouldnt fault
bpl .c2u_3cpy8lp
- PLD( cmn ip, #32 )
- PLD( bge .c2u_3cpynopld )
- PLD( add ip, ip, #32 )
.c2u_3rem8lp: tst ip, #8
movne r3, r7, pull #24
@@ -356,8 +306,6 @@ ENTRY(__arch_copy_from_user)
stmfd sp!, {r0, r2, r4 - r7, lr}
cmp r2, #4
blt .cfu_not_enough
- PLD( pld [r1, #0] )
- PLD( pld [r0, #0] )
ands ip, r0, #3
bne .cfu_dest_not_aligned
.cfu_dest_aligned:
@@ -385,25 +333,13 @@ USER( ldrt r3, [r1], #4)
sub r2, r2, ip
subs ip, ip, #32
blt .cfu_0rem8lp
- PLD( pld [r1, #28] )
- PLD( pld [r0, #28] )
- PLD( subs ip, ip, #64 )
- PLD( blt .cfu_0cpynopld )
- PLD( pld [r1, #60] )
- PLD( pld [r0, #60] )
-
-.cfu_0cpy8lp:
- PLD( pld [r1, #92] )
- PLD( pld [r0, #92] )
-.cfu_0cpynopld: ldmia r1!, {r3 - r6} @ Shouldnt fault
+
+.cfu_0cpy8lp: ldmia r1!, {r3 - r6} @ Shouldnt fault
stmia r0!, {r3 - r6}
ldmia r1!, {r3 - r6} @ Shouldnt fault
subs ip, ip, #32
stmia r0!, {r3 - r6}
bpl .cfu_0cpy8lp
- PLD( cmn ip, #64 )
- PLD( bge .cfu_0cpynopld )
- PLD( add ip, ip, #64 )
.cfu_0rem8lp: cmn ip, #16
ldmgeia r1!, {r3 - r6} @ Shouldnt fault
@@ -456,17 +392,8 @@ USER( ldrt r7, [r1], #4) @ May fault
sub r2, r2, ip
subs ip, ip, #16
blt .cfu_1rem8lp
- PLD( pld [r1, #12] )
- PLD( pld [r0, #12] )
- PLD( subs ip, ip, #32 )
- PLD( blt .cfu_1cpynopld )
- PLD( pld [r1, #28] )
- PLD( pld [r0, #28] )
-
-.cfu_1cpy8lp:
- PLD( pld [r1, #44] )
- PLD( pld [r0, #44] )
-.cfu_1cpynopld: mov r3, r7, pull #8
+
+.cfu_1cpy8lp: mov r3, r7, pull #8
ldmia r1!, {r4 - r7} @ Shouldnt fault
subs ip, ip, #16
orr r3, r3, r4, push #24
@@ -478,9 +405,6 @@ USER( ldrt r7, [r1], #4) @ May fault
orr r6, r6, r7, push #24
stmia r0!, {r3 - r6}
bpl .cfu_1cpy8lp
- PLD( cmn ip, #32 )
- PLD( bge .cfu_1cpynopld )
- PLD( add ip, ip, #32 )
.cfu_1rem8lp: tst ip, #8
movne r3, r7, pull #8
@@ -523,17 +447,8 @@ USER( ldrt r7, [r1], #4) @ May fault
sub r2, r2, ip
subs ip, ip, #16
blt .cfu_2rem8lp
- PLD( pld [r1, #12] )
- PLD( pld [r0, #12] )
- PLD( subs ip, ip, #32 )
- PLD( blt .cfu_2cpynopld )
- PLD( pld [r1, #28] )
- PLD( pld [r0, #28] )
-
-.cfu_2cpy8lp:
- PLD( pld [r1, #44] )
- PLD( pld [r0, #44] )
-.cfu_2cpynopld: mov r3, r7, pull #16
+
+.cfu_2cpy8lp: mov r3, r7, pull #16
ldmia r1!, {r4 - r7} @ Shouldnt fault
subs ip, ip, #16
orr r3, r3, r4, push #16
@@ -545,9 +460,6 @@ USER( ldrt r7, [r1], #4) @ May fault
orr r6, r6, r7, push #16
stmia r0!, {r3 - r6}
bpl .cfu_2cpy8lp
- PLD( cmn ip, #32 )
- PLD( bge .cfu_2cpynopld )
- PLD( add ip, ip, #32 )
.cfu_2rem8lp: tst ip, #8
movne r3, r7, pull #16
@@ -590,17 +502,8 @@ USER( ldrt r7, [r1], #4) @ May fault
sub r2, r2, ip
subs ip, ip, #16
blt .cfu_3rem8lp
- PLD( pld [r1, #12] )
- PLD( pld [r0, #12] )
- PLD( subs ip, ip, #32 )
- PLD( blt .cfu_3cpynopld )
- PLD( pld [r1, #28] )
- PLD( pld [r0, #28] )
-
-.cfu_3cpy8lp:
- PLD( pld [r1, #44] )
- PLD( pld [r0, #44] )
-.cfu_3cpynopld: mov r3, r7, pull #24
+
+.cfu_3cpy8lp: mov r3, r7, pull #24
ldmia r1!, {r4 - r7} @ Shouldnt fault
orr r3, r3, r4, push #8
mov r4, r4, pull #24
@@ -612,9 +515,6 @@ USER( ldrt r7, [r1], #4) @ May fault
stmia r0!, {r3 - r6}
subs ip, ip, #16
bpl .cfu_3cpy8lp
- PLD( cmn ip, #32 )
- PLD( bge .cfu_3cpynopld )
- PLD( add ip, ip, #32 )
.cfu_3rem8lp: tst ip, #8
movne r3, r7, pull #24
@@ -657,41 +557,3 @@ USER( ldrgtbt r3, [r1], #1) @ May fault
LOADREGS(fd,sp!, {r4 - r7, pc})
.previous
-/* Prototype: int __arch_clear_user(void *addr, size_t sz)
- * Purpose : clear some user memory
- * Params : addr - user memory address to clear
- * : sz - number of bytes to clear
- * Returns : number of bytes NOT cleared
- */
-ENTRY(__arch_clear_user)
- stmfd sp!, {r1, lr}
- mov r2, #0
- cmp r1, #4
- blt 2f
- ands ip, r0, #3
- beq 1f
- cmp ip, #2
-USER( strbt r2, [r0], #1)
-USER( strlebt r2, [r0], #1)
-USER( strltbt r2, [r0], #1)
- rsb ip, ip, #4
- sub r1, r1, ip @ 7 6 5 4 3 2 1
-1: subs r1, r1, #8 @ -1 -2 -3 -4 -5 -6 -7
-USER( strplt r2, [r0], #4)
-USER( strplt r2, [r0], #4)
- bpl 1b
- adds r1, r1, #4 @ 3 2 1 0 -1 -2 -3
-USER( strplt r2, [r0], #4)
-2: tst r1, #2 @ 1x 1x 0x 0x 1x 1x 0x
-USER( strnebt r2, [r0], #1)
-USER( strnebt r2, [r0], #1)
- tst r1, #1 @ x1 x0 x1 x0 x1 x0 x1
-USER( strnebt r2, [r0], #1)
- mov r0, #0
- LOADREGS(fd,sp!, {r1, pc})
-
- .section .fixup,"ax"
- .align 0
-9001: LOADREGS(fd,sp!, {r0, pc})
- .previous
-
diff --git a/arch/arm/lib/ucmpdi2.S b/arch/arm/lib/ucmpdi2.S
new file mode 100644
index 000000000000..112630f93e5d
--- /dev/null
+++ b/arch/arm/lib/ucmpdi2.S
@@ -0,0 +1,35 @@
+/*
+ * linux/arch/arm/lib/ucmpdi2.S
+ *
+ * Author: Nicolas Pitre
+ * Created: Oct 19, 2005
+ * Copyright: Monta Vista Software, 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.
+ */
+
+#include <linux/linkage.h>
+
+#ifdef __ARMEB__
+#define xh r0
+#define xl r1
+#define yh r2
+#define yl r3
+#else
+#define xl r0
+#define xh r1
+#define yl r2
+#define yh r3
+#endif
+
+ENTRY(__ucmpdi2)
+
+ cmp xh, yh
+ cmpeq xl, yl
+ movlo r0, #0
+ moveq r0, #1
+ movhi r0, #2
+ mov pc, lr
+
diff --git a/arch/arm/lib/ucmpdi2.c b/arch/arm/lib/ucmpdi2.c
deleted file mode 100644
index 57f3f2df3850..000000000000
--- a/arch/arm/lib/ucmpdi2.c
+++ /dev/null
@@ -1,49 +0,0 @@
-/* More subroutines needed by GCC output code on some machines. */
-/* Compile this one with gcc. */
-/* Copyright (C) 1989, 92-98, 1999 Free Software Foundation, Inc.
-
-This file is part of GNU CC.
-
-GNU CC is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
-
-GNU CC 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 GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
-
-/* As a special exception, if you link this library with other files,
- some of which are compiled with GCC, to produce an executable,
- this library does not by itself cause the resulting executable
- to be covered by the GNU General Public License.
- This exception does not however invalidate any other reasons why
- the executable file might be covered by the GNU General Public License.
- */
-/* support functions required by the kernel. based on code from gcc-2.95.3 */
-/* I Molton 29/07/01 */
-
-#include "gcclib.h"
-
-int __ucmpdi2(s64 a, s64 b)
-{
- DIunion au, bu;
-
- au.ll = a, bu.ll = b;
-
- if ((u32) au.s.high < (u32) bu.s.high)
- return 0;
- else if ((u32) au.s.high > (u32) bu.s.high)
- return 2;
- if ((u32) au.s.low < (u32) bu.s.low)
- return 0;
- else if ((u32) au.s.low > (u32) bu.s.low)
- return 2;
- return 1;
-}
diff --git a/arch/arm/mach-aaec2000/Makefile b/arch/arm/mach-aaec2000/Makefile
index 20ec83896c37..a8e462f58bc9 100644
--- a/arch/arm/mach-aaec2000/Makefile
+++ b/arch/arm/mach-aaec2000/Makefile
@@ -3,7 +3,7 @@
#
# Common support (must be linked before board specific support)
-obj-y += core.o
+obj-y += core.o clock.o
# Specific board support
obj-$(CONFIG_MACH_AAED2000) += aaed2000.o
diff --git a/arch/arm/mach-aaec2000/aaed2000.c b/arch/arm/mach-aaec2000/aaed2000.c
index c9d899886648..f5ef69702296 100644
--- a/arch/arm/mach-aaec2000/aaed2000.c
+++ b/arch/arm/mach-aaec2000/aaed2000.c
@@ -27,16 +27,65 @@
#include <asm/mach/map.h>
#include <asm/mach/irq.h>
+#include <asm/arch/aaed2000.h>
+
#include "core.h"
+static void aaed2000_clcd_disable(struct clcd_fb *fb)
+{
+ AAED_EXT_GPIO &= ~AAED_EGPIO_LCD_PWR_EN;
+}
+
+static void aaed2000_clcd_enable(struct clcd_fb *fb)
+{
+ AAED_EXT_GPIO |= AAED_EGPIO_LCD_PWR_EN;
+}
+
+struct aaec2000_clcd_info clcd_info = {
+ .enable = aaed2000_clcd_enable,
+ .disable = aaed2000_clcd_disable,
+ .panel = {
+ .mode = {
+ .name = "Sharp",
+ .refresh = 60,
+ .xres = 640,
+ .yres = 480,
+ .pixclock = 39721,
+ .left_margin = 20,
+ .right_margin = 44,
+ .upper_margin = 21,
+ .lower_margin = 34,
+ .hsync_len = 96,
+ .vsync_len = 2,
+ .sync = 0,
+ .vmode = FB_VMODE_NONINTERLACED,
+ },
+ .width = -1,
+ .height = -1,
+ .tim2 = TIM2_IVS | TIM2_IHS,
+ .cntl = CNTL_LCDTFT,
+ .bpp = 16,
+ },
+};
+
static void __init aaed2000_init_irq(void)
{
aaec2000_init_irq();
}
+static void __init aaed2000_init(void)
+{
+ aaec2000_set_clcd_plat_data(&clcd_info);
+}
+
+static struct map_desc aaed2000_io_desc[] __initdata = {
+ { EXT_GPIO_VBASE, EXT_GPIO_PBASE, EXT_GPIO_LENGTH, MT_DEVICE }, /* Ext GPIO */
+};
+
static void __init aaed2000_map_io(void)
{
aaec2000_map_io();
+ iotable_init(aaed2000_io_desc, ARRAY_SIZE(aaed2000_io_desc));
}
MACHINE_START(AAED2000, "Agilent AAED-2000 Development Platform")
@@ -47,4 +96,5 @@ MACHINE_START(AAED2000, "Agilent AAED-2000 Development Platform")
.map_io = aaed2000_map_io,
.init_irq = aaed2000_init_irq,
.timer = &aaec2000_timer,
+ .init_machine = aaed2000_init,
MACHINE_END
diff --git a/arch/arm/mach-aaec2000/clock.c b/arch/arm/mach-aaec2000/clock.c
new file mode 100644
index 000000000000..0340ddc4824e
--- /dev/null
+++ b/arch/arm/mach-aaec2000/clock.c
@@ -0,0 +1,111 @@
+/*
+ * linux/arch/arm/mach-aaec2000/clock.c
+ *
+ * Copyright (C) 2005 Nicolas Bellido Y Ortega
+ *
+ * Based on linux/arch/arm/mach-integrator/clock.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/string.h>
+
+#include <asm/semaphore.h>
+#include <asm/hardware/clock.h>
+
+#include "clock.h"
+
+static LIST_HEAD(clocks);
+static DECLARE_MUTEX(clocks_sem);
+
+struct clk *clk_get(struct device *dev, const char *id)
+{
+ struct clk *p, *clk = ERR_PTR(-ENOENT);
+
+ down(&clocks_sem);
+ list_for_each_entry(p, &clocks, node) {
+ if (strcmp(id, p->name) == 0 && try_module_get(p->owner)) {
+ clk = p;
+ break;
+ }
+ }
+ up(&clocks_sem);
+
+ return clk;
+}
+EXPORT_SYMBOL(clk_get);
+
+void clk_put(struct clk *clk)
+{
+ module_put(clk->owner);
+}
+EXPORT_SYMBOL(clk_put);
+
+int clk_enable(struct clk *clk)
+{
+ return 0;
+}
+EXPORT_SYMBOL(clk_enable);
+
+void clk_disable(struct clk *clk)
+{
+}
+EXPORT_SYMBOL(clk_disable);
+
+int clk_use(struct clk *clk)
+{
+ return 0;
+}
+EXPORT_SYMBOL(clk_use);
+
+void clk_unuse(struct clk *clk)
+{
+}
+EXPORT_SYMBOL(clk_unuse);
+
+unsigned long clk_get_rate(struct clk *clk)
+{
+ return clk->rate;
+}
+EXPORT_SYMBOL(clk_get_rate);
+
+long clk_round_rate(struct clk *clk, unsigned long rate)
+{
+ return rate;
+}
+EXPORT_SYMBOL(clk_round_rate);
+
+int clk_set_rate(struct clk *clk, unsigned long rate)
+{
+ return 0;
+}
+EXPORT_SYMBOL(clk_set_rate);
+
+int clk_register(struct clk *clk)
+{
+ down(&clocks_sem);
+ list_add(&clk->node, &clocks);
+ up(&clocks_sem);
+ return 0;
+}
+EXPORT_SYMBOL(clk_register);
+
+void clk_unregister(struct clk *clk)
+{
+ down(&clocks_sem);
+ list_del(&clk->node);
+ up(&clocks_sem);
+}
+EXPORT_SYMBOL(clk_unregister);
+
+static int __init clk_init(void)
+{
+ return 0;
+}
+arch_initcall(clk_init);
diff --git a/arch/arm/mach-aaec2000/clock.h b/arch/arm/mach-aaec2000/clock.h
new file mode 100644
index 000000000000..d4bb74ff613f
--- /dev/null
+++ b/arch/arm/mach-aaec2000/clock.h
@@ -0,0 +1,23 @@
+/*
+ * linux/arch/arm/mach-aaec2000/clock.h
+ *
+ * Copyright (C) 2005 Nicolas Bellido Y Ortega
+ *
+ * Based on linux/arch/arm/mach-integrator/clock.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.
+ */
+struct module;
+
+struct clk {
+ struct list_head node;
+ unsigned long rate;
+ struct module *owner;
+ const char *name;
+ void *data;
+};
+
+int clk_register(struct clk *clk);
+void clk_unregister(struct clk *clk);
diff --git a/arch/arm/mach-aaec2000/core.c b/arch/arm/mach-aaec2000/core.c
index aece0cd4f0a3..4e706d9ad368 100644
--- a/arch/arm/mach-aaec2000/core.c
+++ b/arch/arm/mach-aaec2000/core.c
@@ -13,19 +13,27 @@
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
+#include <linux/platform_device.h>
#include <linux/list.h>
#include <linux/errno.h>
+#include <linux/dma-mapping.h>
#include <linux/interrupt.h>
#include <linux/timex.h>
#include <linux/signal.h>
#include <asm/hardware.h>
#include <asm/irq.h>
+#include <asm/sizes.h>
+#include <asm/hardware/amba.h>
+#include <asm/mach/flash.h>
#include <asm/mach/irq.h>
#include <asm/mach/time.h>
#include <asm/mach/map.h>
+#include "core.h"
+#include "clock.h"
+
/*
* Common I/O mapping:
*
@@ -40,9 +48,17 @@
* default mapping provided here.
*/
static struct map_desc standard_io_desc[] __initdata = {
- /* virtual physical length type */
- { VIO_APB_BASE, PIO_APB_BASE, IO_APB_LENGTH, MT_DEVICE },
- { VIO_AHB_BASE, PIO_AHB_BASE, IO_AHB_LENGTH, MT_DEVICE }
+ {
+ .virtual = VIO_APB_BASE,
+ .physical = __phys_to_pfn(PIO_APB_BASE),
+ .length = IO_APB_LENGTH,
+ .type = MT_DEVICE
+ }, {
+ .virtual = VIO_AHB_BASE,
+ .physical = __phys_to_pfn(PIO_AHB_BASE),
+ .length = IO_AHB_LENGTH,
+ .type = MT_DEVICE
+ }
};
void __init aaec2000_map_io(void)
@@ -155,3 +171,116 @@ struct sys_timer aaec2000_timer = {
.offset = aaec2000_gettimeoffset,
};
+static struct clcd_panel mach_clcd_panel;
+
+static int aaec2000_clcd_setup(struct clcd_fb *fb)
+{
+ dma_addr_t dma;
+
+ fb->panel = &mach_clcd_panel;
+
+ fb->fb.screen_base = dma_alloc_writecombine(&fb->dev->dev, SZ_1M,
+ &dma, GFP_KERNEL);
+
+ if (!fb->fb.screen_base) {
+ printk(KERN_ERR "CLCD: unable to map framebuffer\n");
+ return -ENOMEM;
+ }
+
+ fb->fb.fix.smem_start = dma;
+ fb->fb.fix.smem_len = SZ_1M;
+
+ return 0;
+}
+
+static int aaec2000_clcd_mmap(struct clcd_fb *fb, struct vm_area_struct *vma)
+{
+ return dma_mmap_writecombine(&fb->dev->dev, vma,
+ fb->fb.screen_base,
+ fb->fb.fix.smem_start,
+ fb->fb.fix.smem_len);
+}
+
+static void aaec2000_clcd_remove(struct clcd_fb *fb)
+{
+ dma_free_writecombine(&fb->dev->dev, fb->fb.fix.smem_len,
+ fb->fb.screen_base, fb->fb.fix.smem_start);
+}
+
+static struct clcd_board clcd_plat_data = {
+ .name = "AAEC-2000",
+ .check = clcdfb_check,
+ .decode = clcdfb_decode,
+ .setup = aaec2000_clcd_setup,
+ .mmap = aaec2000_clcd_mmap,
+ .remove = aaec2000_clcd_remove,
+};
+
+static struct amba_device clcd_device = {
+ .dev = {
+ .bus_id = "mb:16",
+ .coherent_dma_mask = ~0,
+ .platform_data = &clcd_plat_data,
+ },
+ .res = {
+ .start = AAEC_CLCD_PHYS,
+ .end = AAEC_CLCD_PHYS + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ .irq = { INT_LCD, NO_IRQ },
+ .periphid = 0x41110,
+};
+
+static struct amba_device *amba_devs[] __initdata = {
+ &clcd_device,
+};
+
+static struct clk aaec2000_clcd_clk = {
+ .name = "CLCDCLK",
+};
+
+void __init aaec2000_set_clcd_plat_data(struct aaec2000_clcd_info *clcd)
+{
+ clcd_plat_data.enable = clcd->enable;
+ clcd_plat_data.disable = clcd->disable;
+ memcpy(&mach_clcd_panel, &clcd->panel, sizeof(struct clcd_panel));
+}
+
+static struct flash_platform_data aaec2000_flash_data = {
+ .map_name = "cfi_probe",
+ .width = 4,
+};
+
+static struct resource aaec2000_flash_resource = {
+ .start = AAEC_FLASH_BASE,
+ .end = AAEC_FLASH_BASE + AAEC_FLASH_SIZE,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device aaec2000_flash_device = {
+ .name = "armflash",
+ .id = 0,
+ .dev = {
+ .platform_data = &aaec2000_flash_data,
+ },
+ .num_resources = 1,
+ .resource = &aaec2000_flash_resource,
+};
+
+static int __init aaec2000_init(void)
+{
+ int i;
+
+ clk_register(&aaec2000_clcd_clk);
+
+ for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
+ struct amba_device *d = amba_devs[i];
+ amba_device_register(d, &iomem_resource);
+ }
+
+ platform_device_register(&aaec2000_flash_device);
+
+ return 0;
+};
+arch_initcall(aaec2000_init);
+
diff --git a/arch/arm/mach-aaec2000/core.h b/arch/arm/mach-aaec2000/core.h
index 91893d848c16..daefc0ea14a1 100644
--- a/arch/arm/mach-aaec2000/core.h
+++ b/arch/arm/mach-aaec2000/core.h
@@ -9,8 +9,19 @@
*
*/
+#include <asm/hardware/amba_clcd.h>
+
struct sys_timer;
extern struct sys_timer aaec2000_timer;
extern void __init aaec2000_map_io(void);
extern void __init aaec2000_init_irq(void);
+
+struct aaec2000_clcd_info {
+ struct clcd_panel panel;
+ void (*disable)(struct clcd_fb *);
+ void (*enable)(struct clcd_fb *);
+};
+
+extern void __init aaec2000_set_clcd_plat_data(struct aaec2000_clcd_info *);
+
diff --git a/arch/arm/mach-clps711x/autcpu12.c b/arch/arm/mach-clps711x/autcpu12.c
index dc73feb1ffb0..43b9423d1440 100644
--- a/arch/arm/mach-clps711x/autcpu12.c
+++ b/arch/arm/mach-clps711x/autcpu12.c
@@ -46,10 +46,14 @@
*/
static struct map_desc autcpu12_io_desc[] __initdata = {
- /* virtual, physical, length, type */
- /* memory-mapped extra io and CS8900A Ethernet chip */
- /* ethernet chip */
- { AUTCPU12_VIRT_CS8900A, AUTCPU12_PHYS_CS8900A, SZ_1M, MT_DEVICE }
+ /* memory-mapped extra io and CS8900A Ethernet chip */
+ /* ethernet chip */
+ {
+ .virtual = AUTCPU12_VIRT_CS8900A,
+ .pfn = __phys_to_pfn(AUTCPU12_PHYS_CS8900A),
+ .length = SZ_1M,
+ .type = MT_DEVICE
+ }
};
void __init autcpu12_map_io(void)
diff --git a/arch/arm/mach-clps711x/cdb89712.c b/arch/arm/mach-clps711x/cdb89712.c
index a46c82cd2711..cba7be5a06c3 100644
--- a/arch/arm/mach-clps711x/cdb89712.c
+++ b/arch/arm/mach-clps711x/cdb89712.c
@@ -39,7 +39,12 @@
* ethernet driver, perhaps.
*/
static struct map_desc cdb89712_io_desc[] __initdata = {
- { ETHER_BASE, ETHER_START, ETHER_SIZE, MT_DEVICE }
+ {
+ .virtual = ETHER_BASE,
+ .pfn =__phys_to_pfn(ETHER_START),
+ .length = ETHER_SIZE,
+ .type = MT_DEVICE
+ }
};
static void __init cdb89712_map_io(void)
diff --git a/arch/arm/mach-clps711x/ceiva.c b/arch/arm/mach-clps711x/ceiva.c
index 780d91805984..35d51a759b59 100644
--- a/arch/arm/mach-clps711x/ceiva.c
+++ b/arch/arm/mach-clps711x/ceiva.c
@@ -37,11 +37,13 @@
#include "common.h"
static struct map_desc ceiva_io_desc[] __initdata = {
- /* virtual, physical, length, type */
-
- /* SED1355 controlled video RAM & registers */
- { CEIVA_VIRT_SED1355, CEIVA_PHYS_SED1355, SZ_2M, MT_DEVICE }
-
+ /* SED1355 controlled video RAM & registers */
+ {
+ .virtual = CEIVA_VIRT_SED1355,
+ .pfn = __phys_to_pfn(CEIVA_PHYS_SED1355),
+ .length = SZ_2M,
+ .type = MT_DEVICE
+ }
};
diff --git a/arch/arm/mach-clps711x/edb7211-mm.c b/arch/arm/mach-clps711x/edb7211-mm.c
index 7fd7b01822d0..0d52e0851251 100644
--- a/arch/arm/mach-clps711x/edb7211-mm.c
+++ b/arch/arm/mach-clps711x/edb7211-mm.c
@@ -51,15 +51,27 @@ extern void clps711x_map_io(void);
* happens).
*/
static struct map_desc edb7211_io_desc[] __initdata = {
- /* virtual, physical, length, type */
-
- /* memory-mapped extra keyboard row and CS8900A Ethernet chip */
- { EP7211_VIRT_EXTKBD, EP7211_PHYS_EXTKBD, SZ_1M, MT_DEVICE },
- { EP7211_VIRT_CS8900A, EP7211_PHYS_CS8900A, SZ_1M, MT_DEVICE },
-
- /* flash banks */
- { EP7211_VIRT_FLASH1, EP7211_PHYS_FLASH1, SZ_8M, MT_DEVICE },
- { EP7211_VIRT_FLASH2, EP7211_PHYS_FLASH2, SZ_8M, MT_DEVICE }
+ { /* memory-mapped extra keyboard row */
+ .virtual = EP7211_VIRT_EXTKBD,
+ .pfn = __phys_to_pfn(EP7211_PHYS_EXTKBD),
+ .length = SZ_1M,
+ .type = MT_DEVICE,
+ }, { /* and CS8900A Ethernet chip */
+ .virtual = EP7211_VIRT_CS8900A,
+ .pfn = __phys_to_pfn(EP7211_PHYS_CS8900A),
+ .length = SZ_1M,
+ .type = MT_DEVICE,
+ }, { /* flash banks */
+ .virtual = EP7211_VIRT_FLASH1,
+ .pfn = __phys_to_pfn(EP7211_PHYS_FLASH1),
+ .length = SZ_8M,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = EP7211_VIRT_FLASH2,
+ .pfn = __phys_to_pfn(EP7211_PHYS_FLASH2),
+ .length = SZ_8M,
+ .type = MT_DEVICE,
+ }
};
void __init edb7211_map_io(void)
diff --git a/arch/arm/mach-clps711x/mm.c b/arch/arm/mach-clps711x/mm.c
index 120b7cac84b5..a00f77ef8df8 100644
--- a/arch/arm/mach-clps711x/mm.c
+++ b/arch/arm/mach-clps711x/mm.c
@@ -24,6 +24,7 @@
#include <linux/init.h>
#include <linux/bootmem.h>
+#include <asm/sizes.h>
#include <asm/hardware.h>
#include <asm/pgtable.h>
#include <asm/page.h>
@@ -34,7 +35,12 @@
* This maps the generic CLPS711x registers
*/
static struct map_desc clps711x_io_desc[] __initdata = {
- { CLPS7111_VIRT_BASE, CLPS7111_PHYS_BASE, 1048576, MT_DEVICE }
+ {
+ .virtual = CLPS7111_VIRT_BASE,
+ .pfn = __phys_to_pfn(CLPS7111_PHYS_BASE),
+ .length = SZ_1M,
+ .type = MT_DEVICE
+ }
};
void __init clps711x_map_io(void)
diff --git a/arch/arm/mach-clps711x/p720t.c b/arch/arm/mach-clps711x/p720t.c
index 5bdb90edf992..a1acb945fb51 100644
--- a/arch/arm/mach-clps711x/p720t.c
+++ b/arch/arm/mach-clps711x/p720t.c
@@ -29,6 +29,7 @@
#include <asm/pgtable.h>
#include <asm/page.h>
#include <asm/setup.h>
+#include <asm/sizes.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
@@ -42,8 +43,17 @@
* We map both here.
*/
static struct map_desc p720t_io_desc[] __initdata = {
- { SYSPLD_VIRT_BASE, SYSPLD_PHYS_BASE, 1048576, MT_DEVICE },
- { 0xfe400000, 0x10400000, 1048576, MT_DEVICE }
+ {
+ .virtual = SYSPLD_VIRT_BASE,
+ .pfn = __phys_to_pfn(SYSPLD_PHYS_BASE),
+ .length = SZ_1M,
+ .type = MT_DEVICE
+ }, {
+ .virtual = 0xfe400000,
+ .pfn = __phys_to_pfn(0x10400000),
+ .length = SZ_1M,
+ .type = MT_DEVICE
+ }
};
static void __init
diff --git a/arch/arm/mach-clps7500/core.c b/arch/arm/mach-clps7500/core.c
index e216ab8b9e8f..0364ba4b539e 100644
--- a/arch/arm/mach-clps7500/core.c
+++ b/arch/arm/mach-clps7500/core.c
@@ -259,10 +259,27 @@ static void __init clps7500_init_irq(void)
}
static struct map_desc cl7500_io_desc[] __initdata = {
- { IO_BASE, IO_START, IO_SIZE, MT_DEVICE }, /* IO space */
- { ISA_BASE, ISA_START, ISA_SIZE, MT_DEVICE }, /* ISA space */
- { FLASH_BASE, FLASH_START, FLASH_SIZE, MT_DEVICE }, /* Flash */
- { LED_BASE, LED_START, LED_SIZE, MT_DEVICE } /* LED */
+ { /* IO space */
+ .virtual = IO_BASE,
+ .pfn = __phys_to_pfn(IO_START),
+ .length = IO_SIZE,
+ .type = MT_DEVICE
+ }, { /* ISA space */
+ .virtual = ISA_BASE,
+ .pfn = __phys_to_pfn(ISA_START),
+ .length = ISA_SIZE,
+ .type = MT_DEVICE
+ }, { /* Flash */
+ .virtual = FLASH_BASE,
+ .pfn = __phys_to_pfn(FLASH_START),
+ .length = FLASH_SIZE,
+ .type = MT_DEVICE
+ }, { /* LED */
+ .virtual = LED_BASE,
+ .pfn = __phys_to_pfn(LED_START),
+ .length = LED_SIZE,
+ .type = MT_DEVICE
+ }
};
static void __init clps7500_map_io(void)
diff --git a/arch/arm/mach-ebsa110/core.c b/arch/arm/mach-ebsa110/core.c
index 5aeadfd72143..ed4614983adb 100644
--- a/arch/arm/mach-ebsa110/core.c
+++ b/arch/arm/mach-ebsa110/core.c
@@ -76,16 +76,42 @@ static struct map_desc ebsa110_io_desc[] __initdata = {
/*
* sparse external-decode ISAIO space
*/
- { IRQ_STAT, TRICK4_PHYS, PGDIR_SIZE, MT_DEVICE }, /* IRQ_STAT/IRQ_MCLR */
- { IRQ_MASK, TRICK3_PHYS, PGDIR_SIZE, MT_DEVICE }, /* IRQ_MASK/IRQ_MSET */
- { SOFT_BASE, TRICK1_PHYS, PGDIR_SIZE, MT_DEVICE }, /* SOFT_BASE */
- { PIT_BASE, TRICK0_PHYS, PGDIR_SIZE, MT_DEVICE }, /* PIT_BASE */
+ { /* IRQ_STAT/IRQ_MCLR */
+ .virtual = IRQ_STAT,
+ .pfn = __phys_to_pfn(TRICK4_PHYS),
+ .length = PGDIR_SIZE,
+ .type = MT_DEVICE
+ }, { /* IRQ_MASK/IRQ_MSET */
+ .virtual = IRQ_MASK,
+ .pfn = __phys_to_pfn(TRICK3_PHYS),
+ .length = PGDIR_SIZE,
+ .type = MT_DEVICE
+ }, { /* SOFT_BASE */
+ .virtual = SOFT_BASE,
+ .pfn = __phys_to_pfn(TRICK1_PHYS),
+ .length = PGDIR_SIZE,
+ .type = MT_DEVICE
+ }, { /* PIT_BASE */
+ .virtual = PIT_BASE,
+ .pfn = __phys_to_pfn(TRICK0_PHYS),
+ .length = PGDIR_SIZE,
+ .type = MT_DEVICE
+ },
/*
* self-decode ISAIO space
*/
- { ISAIO_BASE, ISAIO_PHYS, ISAIO_SIZE, MT_DEVICE },
- { ISAMEM_BASE, ISAMEM_PHYS, ISAMEM_SIZE, MT_DEVICE }
+ {
+ .virtual = ISAIO_BASE,
+ .pfn = __phys_to_pfn(ISAIO_PHYS),
+ .length = ISAIO_SIZE,
+ .type = MT_DEVICE
+ }, {
+ .virtual = ISAMEM_BASE,
+ .pfn = __phys_to_pfn(ISAMEM_PHYS),
+ .length = ISAMEM_SIZE,
+ .type = MT_DEVICE
+ }
};
static void __init ebsa110_map_io(void)
@@ -225,9 +251,33 @@ static struct platform_device serial_device = {
},
};
+static struct resource am79c961_resources[] = {
+ {
+ .start = 0x220,
+ .end = 0x238,
+ .flags = IORESOURCE_IO,
+ }, {
+ .start = IRQ_EBSA110_ETHERNET,
+ .end = IRQ_EBSA110_ETHERNET,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device am79c961_device = {
+ .name = "am79c961",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(am79c961_resources),
+ .resource = am79c961_resources,
+};
+
+static struct platform_device *ebsa110_devices[] = {
+ &serial_device,
+ &am79c961_device,
+};
+
static int __init ebsa110_init(void)
{
- return platform_device_register(&serial_device);
+ return platform_add_devices(ebsa110_devices, ARRAY_SIZE(ebsa110_devices));
}
arch_initcall(ebsa110_init);
diff --git a/arch/arm/mach-ebsa110/io.c b/arch/arm/mach-ebsa110/io.c
index ef7eb5dc91bd..c648bfb676a1 100644
--- a/arch/arm/mach-ebsa110/io.c
+++ b/arch/arm/mach-ebsa110/io.c
@@ -24,6 +24,7 @@
#include <linux/kernel.h>
#include <linux/types.h>
+#include <asm/hardware.h>
#include <asm/io.h>
#include <asm/page.h>
diff --git a/arch/arm/mach-epxa10db/mm.c b/arch/arm/mach-epxa10db/mm.c
index 2aa57fa46da3..cfd0d2182d44 100644
--- a/arch/arm/mach-epxa10db/mm.c
+++ b/arch/arm/mach-epxa10db/mm.c
@@ -25,18 +25,44 @@
#include <asm/hardware.h>
#include <asm/io.h>
#include <asm/sizes.h>
+#include <asm/page.h>
#include <asm/mach/map.h>
/* Page table mapping for I/O region */
static struct map_desc epxa10db_io_desc[] __initdata = {
- { IO_ADDRESS(EXC_REGISTERS_BASE), EXC_REGISTERS_BASE, SZ_16K, MT_DEVICE },
- { IO_ADDRESS(EXC_PLD_BLOCK0_BASE), EXC_PLD_BLOCK0_BASE, SZ_16K, MT_DEVICE },
- { IO_ADDRESS(EXC_PLD_BLOCK1_BASE), EXC_PLD_BLOCK1_BASE, SZ_16K, MT_DEVICE },
- { IO_ADDRESS(EXC_PLD_BLOCK2_BASE), EXC_PLD_BLOCK2_BASE, SZ_16K, MT_DEVICE },
- { IO_ADDRESS(EXC_PLD_BLOCK3_BASE), EXC_PLD_BLOCK3_BASE, SZ_16K, MT_DEVICE },
- { FLASH_VADDR(EXC_EBI_BLOCK0_BASE), EXC_EBI_BLOCK0_BASE, SZ_16M, MT_DEVICE }
+ {
+ .virtual = IO_ADDRESS(EXC_REGISTERS_BASE),
+ .pfn = __phys_to_pfn(EXC_REGISTERS_BASE),
+ .length = SZ_16K,
+ .type = MT_DEVICE
+ }, {
+ .virtual = IO_ADDRESS(EXC_PLD_BLOCK0_BASE),
+ .pfn = __phys_to_pfn(EXC_PLD_BLOCK0_BASE),
+ .length = SZ_16K,
+ .type = MT_DEVICE
+ }, {
+ .virtual = IO_ADDRESS(EXC_PLD_BLOCK1_BASE),
+ .pfn =__phys_to_pfn(EXC_PLD_BLOCK1_BASE),
+ .length = SZ_16K,
+ .type = MT_DEVICE
+ }, {
+ .virtual = IO_ADDRESS(EXC_PLD_BLOCK2_BASE),
+ .physical = __phys_to_pfn(EXC_PLD_BLOCK2_BASE),
+ .length = SZ_16K,
+ .type = MT_DEVICE
+ }, {
+ .virtual = IO_ADDRESS(EXC_PLD_BLOCK3_BASE),
+ .pfn = __phys_to_pfn(EXC_PLD_BLOCK3_BASE),
+ .length = SZ_16K,
+ .type = MT_DEVICE
+ }, {
+ .virtual = FLASH_VADDR(EXC_EBI_BLOCK0_BASE),
+ .pfn = __phys_to_pfn(EXC_EBI_BLOCK0_BASE),
+ .length = SZ_16M,
+ .type = MT_DEVICE
+ }
};
void __init epxa10db_map_io(void)
diff --git a/arch/arm/mach-footbridge/common.c b/arch/arm/mach-footbridge/common.c
index eb8238c1ef06..dc09fd200c16 100644
--- a/arch/arm/mach-footbridge/common.c
+++ b/arch/arm/mach-footbridge/common.c
@@ -130,8 +130,17 @@ void __init footbridge_init_irq(void)
* it means that we have extra bullet protection on our feet.
*/
static struct map_desc fb_common_io_desc[] __initdata = {
- { ARMCSR_BASE, DC21285_ARMCSR_BASE, ARMCSR_SIZE, MT_DEVICE },
- { XBUS_BASE, 0x40000000, XBUS_SIZE, MT_DEVICE }
+ {
+ .virtual = ARMCSR_BASE,
+ .pfn = DC21285_ARMCSR_BASE,
+ .length = ARMCSR_SIZE,
+ .type = MT_DEVICE
+ }, {
+ .virtual = XBUS_BASE,
+ .pfn = __phys_to_pfn(0x40000000),
+ .length = XBUS_SIZE,
+ .type = MT_DEVICE
+ }
};
/*
@@ -140,11 +149,32 @@ static struct map_desc fb_common_io_desc[] __initdata = {
*/
static struct map_desc ebsa285_host_io_desc[] __initdata = {
#if defined(CONFIG_ARCH_FOOTBRIDGE) && defined(CONFIG_FOOTBRIDGE_HOST)
- { PCIMEM_BASE, DC21285_PCI_MEM, PCIMEM_SIZE, MT_DEVICE },
- { PCICFG0_BASE, DC21285_PCI_TYPE_0_CONFIG, PCICFG0_SIZE, MT_DEVICE },
- { PCICFG1_BASE, DC21285_PCI_TYPE_1_CONFIG, PCICFG1_SIZE, MT_DEVICE },
- { PCIIACK_BASE, DC21285_PCI_IACK, PCIIACK_SIZE, MT_DEVICE },
- { PCIO_BASE, DC21285_PCI_IO, PCIO_SIZE, MT_DEVICE }
+ {
+ .virtual = PCIMEM_BASE,
+ .pfn = __phys_to_pfn(DC21285_PCI_MEM),
+ .length = PCIMEM_SIZE,
+ .type = MT_DEVICE
+ }, {
+ .virtual = PCICFG0_BASE,
+ .pfn = __phys_to_pfn(DC21285_PCI_TYPE_0_CONFIG),
+ .length = PCICFG0_SIZE,
+ .type = MT_DEVICE
+ }, {
+ .virtual = PCICFG1_BASE,
+ .pfn = __phys_to_pfn(DC21285_PCI_TYPE_1_CONFIG),
+ .length = PCICFG1_SIZE,
+ .type = MT_DEVICE
+ }, {
+ .virtual = PCIIACK_BASE,
+ .pfn = __phys_to_pfn(DC21285_PCI_IACK),
+ .length = PCIIACK_SIZE,
+ .type = MT_DEVICE
+ }, {
+ .virtual = PCIO_BASE,
+ .pfn = __phys_to_pfn(DC21285_PCI_IO),
+ .length = PCIO_SIZE,
+ .type = MT_DEVICE
+ }
#endif
};
@@ -153,8 +183,17 @@ static struct map_desc ebsa285_host_io_desc[] __initdata = {
*/
static struct map_desc co285_io_desc[] __initdata = {
#ifdef CONFIG_ARCH_CO285
- { PCIO_BASE, DC21285_PCI_IO, PCIO_SIZE, MT_DEVICE },
- { PCIMEM_BASE, DC21285_PCI_MEM, PCIMEM_SIZE, MT_DEVICE }
+ {
+ .virtual = PCIO_BASE,
+ .pfn = __phys_to_pfn(DC21285_PCI_IO),
+ .length = PCIO_SIZE,
+ .type = MT_DEVICE
+ }, {
+ .virtual = PCIMEM_BASE,
+ .pfn = __phys_to_pfn(DC21285_PCI_MEM),
+ .length = PCIMEM_SIZE,
+ .type = MT_DEVICE
+ }
#endif
};
diff --git a/arch/arm/mach-h720x/common.c b/arch/arm/mach-h720x/common.c
index 5110e2e65ddd..c096b4569308 100644
--- a/arch/arm/mach-h720x/common.c
+++ b/arch/arm/mach-h720x/common.c
@@ -237,7 +237,12 @@ void __init h720x_init_irq (void)
}
static struct map_desc h720x_io_desc[] __initdata = {
- { IO_VIRT, IO_PHYS, IO_SIZE, MT_DEVICE },
+ {
+ .virtual = IO_VIRT,
+ .pfn = __phys_to_pfn(IO_PHYS),
+ .length = IO_SIZE,
+ .type = MT_DEVICE
+ },
};
/* Initialize io tables */
diff --git a/arch/arm/mach-h720x/h7202-eval.c b/arch/arm/mach-h720x/h7202-eval.c
index db9078ad008c..d75c8221d2a5 100644
--- a/arch/arm/mach-h720x/h7202-eval.c
+++ b/arch/arm/mach-h720x/h7202-eval.c
@@ -18,7 +18,7 @@
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/string.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <asm/setup.h>
#include <asm/types.h>
diff --git a/arch/arm/mach-imx/generic.c b/arch/arm/mach-imx/generic.c
index f8a742bb2d5b..37613ad68366 100644
--- a/arch/arm/mach-imx/generic.c
+++ b/arch/arm/mach-imx/generic.c
@@ -22,10 +22,12 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/string.h>
+
#include <asm/arch/imxfb.h>
#include <asm/hardware.h>
#include <asm/arch/imx-regs.h>
@@ -273,8 +275,12 @@ static struct platform_device *devices[] __initdata = {
};
static struct map_desc imx_io_desc[] __initdata = {
- /* virtual physical length type */
- {IMX_IO_BASE, IMX_IO_PHYS, IMX_IO_SIZE, MT_DEVICE},
+ {
+ .virtual = IMX_IO_BASE,
+ .pfn = __phys_to_pfn(IMX_IO_PHYS),
+ .length = IMX_IO_SIZE,
+ .type = MT_DEVICE
+ }
};
void __init
diff --git a/arch/arm/mach-imx/mx1ads.c b/arch/arm/mach-imx/mx1ads.c
index a7511ddfe364..708e1b3faa14 100644
--- a/arch/arm/mach-imx/mx1ads.c
+++ b/arch/arm/mach-imx/mx1ads.c
@@ -14,6 +14,7 @@
#include <linux/device.h>
#include <linux/init.h>
+#include <linux/platform_device.h>
#include <asm/system.h>
#include <asm/hardware.h>
#include <asm/irq.h>
@@ -61,13 +62,37 @@ mx1ads_init(void)
}
static struct map_desc mx1ads_io_desc[] __initdata = {
- /* virtual physical length type */
- {IMX_CS0_VIRT, IMX_CS0_PHYS, IMX_CS0_SIZE, MT_DEVICE},
- {IMX_CS1_VIRT, IMX_CS1_PHYS, IMX_CS1_SIZE, MT_DEVICE},
- {IMX_CS2_VIRT, IMX_CS2_PHYS, IMX_CS2_SIZE, MT_DEVICE},
- {IMX_CS3_VIRT, IMX_CS3_PHYS, IMX_CS3_SIZE, MT_DEVICE},
- {IMX_CS4_VIRT, IMX_CS4_PHYS, IMX_CS4_SIZE, MT_DEVICE},
- {IMX_CS5_VIRT, IMX_CS5_PHYS, IMX_CS5_SIZE, MT_DEVICE},
+ {
+ .virtual = IMX_CS0_VIRT,
+ .pfn = __phys_to_pfn(IMX_CS0_PHYS),
+ .length = IMX_CS0_SIZE,
+ .type = MT_DEVICE
+ }, {
+ .virtual = IMX_CS1_VIRT,
+ .pfn = __phys_to_pfn(IMX_CS1_PHYS),
+ .length = IMX_CS1_SIZE,
+ .type = MT_DEVICE
+ }, {
+ .virtual = IMX_CS2_VIRT,
+ .pfn = __phys_to_pfn(IMX_CS2_PHYS),
+ .length = IMX_CS2_SIZE,
+ .type = MT_DEVICE
+ }, {
+ .virtual = IMX_CS3_VIRT,
+ .pfn = __phys_to_pfn(IMX_CS3_PHYS),
+ .length = IMX_CS3_SIZE,
+ .type = MT_DEVICE
+ }, {
+ .virtual = IMX_CS4_VIRT,
+ .pfn = __phys_to_pfn(IMX_CS4_PHYS),
+ .length = IMX_CS4_SIZE,
+ .type = MT_DEVICE
+ }, {
+ .virtual = IMX_CS5_VIRT,
+ .pfn = __phys_to_pfn(IMX_CS5_PHYS),
+ .length = IMX_CS5_SIZE,
+ .type = MT_DEVICE
+ }
};
static void __init
diff --git a/arch/arm/mach-integrator/clock.c b/arch/arm/mach-integrator/clock.c
index 56200594db3c..73c360685cad 100644
--- a/arch/arm/mach-integrator/clock.c
+++ b/arch/arm/mach-integrator/clock.c
@@ -13,6 +13,7 @@
#include <linux/list.h>
#include <linux/errno.h>
#include <linux/err.h>
+#include <linux/string.h>
#include <asm/semaphore.h>
#include <asm/hardware/clock.h>
diff --git a/arch/arm/mach-integrator/impd1.c b/arch/arm/mach-integrator/impd1.c
index a1b153d1626c..a4bafee77a06 100644
--- a/arch/arm/mach-integrator/impd1.c
+++ b/arch/arm/mach-integrator/impd1.c
@@ -420,8 +420,7 @@ static int impd1_probe(struct lm_device *dev)
free_impd1:
if (impd1 && impd1->base)
iounmap(impd1->base);
- if (impd1)
- kfree(impd1);
+ kfree(impd1);
release_lm:
release_mem_region(dev->resource.start, SZ_4K);
return ret;
diff --git a/arch/arm/mach-integrator/integrator_ap.c b/arch/arm/mach-integrator/integrator_ap.c
index 36e2b6eb67b7..4c0f7c65facf 100644
--- a/arch/arm/mach-integrator/integrator_ap.c
+++ b/arch/arm/mach-integrator/integrator_ap.c
@@ -21,7 +21,7 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/list.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/sysdev.h>
@@ -30,6 +30,7 @@
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/setup.h>
+#include <asm/param.h> /* HZ */
#include <asm/mach-types.h>
#include <asm/hardware/amba.h>
#include <asm/hardware/amba_kmi.h>
@@ -75,19 +76,72 @@
*/
static struct map_desc ap_io_desc[] __initdata = {
- { IO_ADDRESS(INTEGRATOR_HDR_BASE), INTEGRATOR_HDR_BASE, SZ_4K, MT_DEVICE },
- { IO_ADDRESS(INTEGRATOR_SC_BASE), INTEGRATOR_SC_BASE, SZ_4K, MT_DEVICE },
- { IO_ADDRESS(INTEGRATOR_EBI_BASE), INTEGRATOR_EBI_BASE, SZ_4K, MT_DEVICE },
- { IO_ADDRESS(INTEGRATOR_CT_BASE), INTEGRATOR_CT_BASE, SZ_4K, MT_DEVICE },
- { IO_ADDRESS(INTEGRATOR_IC_BASE), INTEGRATOR_IC_BASE, SZ_4K, MT_DEVICE },
- { IO_ADDRESS(INTEGRATOR_UART0_BASE), INTEGRATOR_UART0_BASE, SZ_4K, MT_DEVICE },
- { IO_ADDRESS(INTEGRATOR_UART1_BASE), INTEGRATOR_UART1_BASE, SZ_4K, MT_DEVICE },
- { IO_ADDRESS(INTEGRATOR_DBG_BASE), INTEGRATOR_DBG_BASE, SZ_4K, MT_DEVICE },
- { IO_ADDRESS(INTEGRATOR_GPIO_BASE), INTEGRATOR_GPIO_BASE, SZ_4K, MT_DEVICE },
- { PCI_MEMORY_VADDR, PHYS_PCI_MEM_BASE, SZ_16M, MT_DEVICE },
- { PCI_CONFIG_VADDR, PHYS_PCI_CONFIG_BASE, SZ_16M, MT_DEVICE },
- { PCI_V3_VADDR, PHYS_PCI_V3_BASE, SZ_64K, MT_DEVICE },
- { PCI_IO_VADDR, PHYS_PCI_IO_BASE, SZ_64K, MT_DEVICE }
+ {
+ .virtual = IO_ADDRESS(INTEGRATOR_HDR_BASE),
+ .pfn = __phys_to_pfn(INTEGRATOR_HDR_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE
+ }, {
+ .virtual = IO_ADDRESS(INTEGRATOR_SC_BASE),
+ .pfn = __phys_to_pfn(INTEGRATOR_SC_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE
+ }, {
+ .virtual = IO_ADDRESS(INTEGRATOR_EBI_BASE),
+ .pfn = __phys_to_pfn(INTEGRATOR_EBI_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE
+ }, {
+ .virtual = IO_ADDRESS(INTEGRATOR_CT_BASE),
+ .pfn = __phys_to_pfn(INTEGRATOR_CT_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE
+ }, {
+ .virtual = IO_ADDRESS(INTEGRATOR_IC_BASE),
+ .pfn = __phys_to_pfn(INTEGRATOR_IC_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE
+ }, {
+ .virtual = IO_ADDRESS(INTEGRATOR_UART0_BASE),
+ .pfn = __phys_to_pfn(INTEGRATOR_UART0_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE
+ }, {
+ .virtual = IO_ADDRESS(INTEGRATOR_UART1_BASE),
+ .pfn = __phys_to_pfn(INTEGRATOR_UART1_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE
+ }, {
+ .virtual = IO_ADDRESS(INTEGRATOR_DBG_BASE),
+ .pfn = __phys_to_pfn(INTEGRATOR_DBG_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE
+ }, {
+ .virtual = IO_ADDRESS(INTEGRATOR_GPIO_BASE),
+ .pfn = __phys_to_pfn(INTEGRATOR_GPIO_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE
+ }, {
+ .virtual = PCI_MEMORY_VADDR,
+ .pfn = __phys_to_pfn(PHYS_PCI_MEM_BASE),
+ .length = SZ_16M,
+ .type = MT_DEVICE
+ }, {
+ .virtual = PCI_CONFIG_VADDR,
+ .pfn = __phys_to_pfn(PHYS_PCI_CONFIG_BASE),
+ .length = SZ_16M,
+ .type = MT_DEVICE
+ }, {
+ .virtual = PCI_V3_VADDR,
+ .pfn = __phys_to_pfn(PHYS_PCI_V3_BASE),
+ .length = SZ_64K,
+ .type = MT_DEVICE
+ }, {
+ .virtual = PCI_IO_VADDR,
+ .pfn = __phys_to_pfn(PHYS_PCI_IO_BASE),
+ .length = SZ_64K,
+ .type = MT_DEVICE
+ }
};
static void __init ap_map_io(void)
diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c
index 2be5c03ab87f..93f7ccb22c27 100644
--- a/arch/arm/mach-integrator/integrator_cp.c
+++ b/arch/arm/mach-integrator/integrator_cp.c
@@ -11,7 +11,7 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/list.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
#include <linux/slab.h>
#include <linux/string.h>
@@ -74,17 +74,62 @@
*/
static struct map_desc intcp_io_desc[] __initdata = {
- { IO_ADDRESS(INTEGRATOR_HDR_BASE), INTEGRATOR_HDR_BASE, SZ_4K, MT_DEVICE },
- { IO_ADDRESS(INTEGRATOR_SC_BASE), INTEGRATOR_SC_BASE, SZ_4K, MT_DEVICE },
- { IO_ADDRESS(INTEGRATOR_EBI_BASE), INTEGRATOR_EBI_BASE, SZ_4K, MT_DEVICE },
- { IO_ADDRESS(INTEGRATOR_CT_BASE), INTEGRATOR_CT_BASE, SZ_4K, MT_DEVICE },
- { IO_ADDRESS(INTEGRATOR_IC_BASE), INTEGRATOR_IC_BASE, SZ_4K, MT_DEVICE },
- { IO_ADDRESS(INTEGRATOR_UART0_BASE), INTEGRATOR_UART0_BASE, SZ_4K, MT_DEVICE },
- { IO_ADDRESS(INTEGRATOR_UART1_BASE), INTEGRATOR_UART1_BASE, SZ_4K, MT_DEVICE },
- { IO_ADDRESS(INTEGRATOR_DBG_BASE), INTEGRATOR_DBG_BASE, SZ_4K, MT_DEVICE },
- { IO_ADDRESS(INTEGRATOR_GPIO_BASE), INTEGRATOR_GPIO_BASE, SZ_4K, MT_DEVICE },
- { 0xfca00000, 0xca000000, SZ_4K, MT_DEVICE },
- { 0xfcb00000, 0xcb000000, SZ_4K, MT_DEVICE },
+ {
+ .virtual = IO_ADDRESS(INTEGRATOR_HDR_BASE),
+ .pfn = __phys_to_pfn(INTEGRATOR_HDR_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE
+ }, {
+ .virtual = IO_ADDRESS(INTEGRATOR_SC_BASE),
+ .pfn = __phys_to_pfn(INTEGRATOR_SC_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE
+ }, {
+ .virtual = IO_ADDRESS(INTEGRATOR_EBI_BASE),
+ .pfn = __phys_to_pfn(INTEGRATOR_EBI_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE
+ }, {
+ .virtual = IO_ADDRESS(INTEGRATOR_CT_BASE),
+ .pfn = __phys_to_pfn(INTEGRATOR_CT_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE
+ }, {
+ .virtual = IO_ADDRESS(INTEGRATOR_IC_BASE),
+ .pfn = __phys_to_pfn(INTEGRATOR_IC_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE
+ }, {
+ .virtual = IO_ADDRESS(INTEGRATOR_UART0_BASE),
+ .pfn = __phys_to_pfn(INTEGRATOR_UART0_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE
+ }, {
+ .virtual = IO_ADDRESS(INTEGRATOR_UART1_BASE),
+ .pfn = __phys_to_pfn(INTEGRATOR_UART1_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE
+ }, {
+ .virtual = IO_ADDRESS(INTEGRATOR_DBG_BASE),
+ .pfn = __phys_to_pfn(INTEGRATOR_DBG_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE
+ }, {
+ .virtual = IO_ADDRESS(INTEGRATOR_GPIO_BASE),
+ .pfn = __phys_to_pfn(INTEGRATOR_GPIO_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE
+ }, {
+ .virtual = 0xfca00000,
+ .pfn = __phys_to_pfn(0xca000000),
+ .length = SZ_4K,
+ .type = MT_DEVICE
+ }, {
+ .virtual = 0xfcb00000,
+ .pfn = __phys_to_pfn(0xcb000000),
+ .length = SZ_4K,
+ .type = MT_DEVICE
+ }
};
static void __init intcp_map_io(void)
diff --git a/arch/arm/mach-integrator/lm.c b/arch/arm/mach-integrator/lm.c
index c5f19d160598..5b41e3a724e1 100644
--- a/arch/arm/mach-integrator/lm.c
+++ b/arch/arm/mach-integrator/lm.c
@@ -10,6 +10,7 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/device.h>
+#include <linux/slab.h>
#include <asm/arch/lm.h>
diff --git a/arch/arm/mach-iop3xx/iop321-setup.c b/arch/arm/mach-iop3xx/iop321-setup.c
index 0f921ba2750c..80770233b8d4 100644
--- a/arch/arm/mach-iop3xx/iop321-setup.c
+++ b/arch/arm/mach-iop3xx/iop321-setup.c
@@ -16,7 +16,7 @@
#include <linux/init.h>
#include <linux/major.h>
#include <linux/fs.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <linux/serial.h>
#include <linux/tty.h>
#include <linux/serial_core.h>
@@ -38,13 +38,17 @@
* Standard IO mapping for all IOP321 based systems
*/
static struct map_desc iop321_std_desc[] __initdata = {
- /* virtual physical length type */
-
- /* mem mapped registers */
- { IOP321_VIRT_MEM_BASE, IOP321_PHYS_MEM_BASE, 0x00002000, MT_DEVICE },
-
- /* PCI IO space */
- { IOP321_PCI_LOWER_IO_VA, IOP321_PCI_LOWER_IO_PA, IOP321_PCI_IO_WINDOW_SIZE, MT_DEVICE }
+ { /* mem mapped registers */
+ .virtual = IOP321_VIRT_MEM_BASE,
+ .pfn = __phys_to_pfn(IOP321_PHYS_MEM_BASE),
+ .length = 0x00002000,
+ .type = MT_DEVICE
+ }, { /* PCI IO space */
+ .virtual = IOP321_PCI_LOWER_IO_VA,
+ .pfn = __phys_to_pfn(IOP321_PCI_LOWER_IO_PA),
+ .length = IOP321_PCI_IO_WINDOW_SIZE,
+ .type = MT_DEVICE
+ }
};
#ifdef CONFIG_ARCH_IQ80321
diff --git a/arch/arm/mach-iop3xx/iop331-setup.c b/arch/arm/mach-iop3xx/iop331-setup.c
index fc74b722f72f..53f60614498b 100644
--- a/arch/arm/mach-iop3xx/iop331-setup.c
+++ b/arch/arm/mach-iop3xx/iop331-setup.c
@@ -15,7 +15,7 @@
#include <linux/init.h>
#include <linux/major.h>
#include <linux/fs.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <linux/serial.h>
#include <linux/tty.h>
#include <linux/serial_core.h>
@@ -37,13 +37,17 @@
* Standard IO mapping for all IOP331 based systems
*/
static struct map_desc iop331_std_desc[] __initdata = {
- /* virtual physical length type */
-
- /* mem mapped registers */
- { IOP331_VIRT_MEM_BASE, IOP331_PHYS_MEM_BASE, 0x00002000, MT_DEVICE },
-
- /* PCI IO space */
- { IOP331_PCI_LOWER_IO_VA, IOP331_PCI_LOWER_IO_PA, IOP331_PCI_IO_WINDOW_SIZE, MT_DEVICE }
+ { /* mem mapped registers */
+ .virtual = IOP331_VIRT_MEM_BASE,
+ .pfn = __phys_to_pfn(IOP331_PHYS_MEM_BASE),
+ .length = 0x00002000,
+ .type = MT_DEVICE
+ }, { /* PCI IO space */
+ .virtual = IOP331_PCI_LOWER_IO_VA,
+ .pfn = __phys_to_pfn(IOP331_PCI_LOWER_IO_PA),
+ .length = IOP331_PCI_IO_WINDOW_SIZE,
+ .type = MT_DEVICE
+ }
};
static struct uart_port iop331_serial_ports[] = {
diff --git a/arch/arm/mach-iop3xx/iq31244-mm.c b/arch/arm/mach-iop3xx/iq31244-mm.c
index 55992ab586ba..e874b54eefe3 100644
--- a/arch/arm/mach-iop3xx/iq31244-mm.c
+++ b/arch/arm/mach-iop3xx/iq31244-mm.c
@@ -29,10 +29,12 @@
* We use RedBoot's setup for the onboard devices.
*/
static struct map_desc iq31244_io_desc[] __initdata = {
- /* virtual physical length type */
-
- /* on-board devices */
- { IQ31244_UART, IQ31244_UART, 0x00100000, MT_DEVICE }
+ { /* on-board devices */
+ .virtual = IQ31244_UART,
+ .pfn = __phys_to_pfn(IQ31244_UART),
+ .length = 0x00100000,
+ .type = MT_DEVICE
+ }
};
void __init iq31244_map_io(void)
diff --git a/arch/arm/mach-iop3xx/iq31244-pci.c b/arch/arm/mach-iop3xx/iq31244-pci.c
index f997daa800bf..c6a973ba8fc6 100644
--- a/arch/arm/mach-iop3xx/iq31244-pci.c
+++ b/arch/arm/mach-iop3xx/iq31244-pci.c
@@ -14,6 +14,8 @@
#include <linux/kernel.h>
#include <linux/pci.h>
#include <linux/init.h>
+#include <linux/string.h>
+#include <linux/slab.h>
#include <asm/hardware.h>
#include <asm/irq.h>
diff --git a/arch/arm/mach-iop3xx/iq80321-mm.c b/arch/arm/mach-iop3xx/iq80321-mm.c
index bb3e9e5a9aff..d9cac5e1fc3d 100644
--- a/arch/arm/mach-iop3xx/iq80321-mm.c
+++ b/arch/arm/mach-iop3xx/iq80321-mm.c
@@ -29,10 +29,12 @@
* We use RedBoot's setup for the onboard devices.
*/
static struct map_desc iq80321_io_desc[] __initdata = {
- /* virtual physical length type */
-
- /* on-board devices */
- { IQ80321_UART, IQ80321_UART, 0x00100000, MT_DEVICE }
+ { /* on-board devices */
+ .virtual = IQ80321_UART,
+ .pfn = __phys_to_pfn(IQ80321_UART),
+ .length = 0x00100000,
+ .type = MT_DEVICE
+ }
};
void __init iq80321_map_io(void)
diff --git a/arch/arm/mach-iop3xx/iq80321-pci.c b/arch/arm/mach-iop3xx/iq80321-pci.c
index 79fea3d20b66..802f6d091b75 100644
--- a/arch/arm/mach-iop3xx/iq80321-pci.c
+++ b/arch/arm/mach-iop3xx/iq80321-pci.c
@@ -14,6 +14,8 @@
#include <linux/kernel.h>
#include <linux/pci.h>
#include <linux/init.h>
+#include <linux/string.h>
+#include <linux/slab.h>
#include <asm/hardware.h>
#include <asm/irq.h>
diff --git a/arch/arm/mach-iop3xx/iq80331-pci.c b/arch/arm/mach-iop3xx/iq80331-pci.c
index f37a0e26b466..654e450a1311 100644
--- a/arch/arm/mach-iop3xx/iq80331-pci.c
+++ b/arch/arm/mach-iop3xx/iq80331-pci.c
@@ -13,6 +13,8 @@
#include <linux/kernel.h>
#include <linux/pci.h>
#include <linux/init.h>
+#include <linux/string.h>
+#include <linux/slab.h>
#include <asm/hardware.h>
#include <asm/irq.h>
diff --git a/arch/arm/mach-iop3xx/iq80332-pci.c b/arch/arm/mach-iop3xx/iq80332-pci.c
index b9807aa2aade..65951ffe4631 100644
--- a/arch/arm/mach-iop3xx/iq80332-pci.c
+++ b/arch/arm/mach-iop3xx/iq80332-pci.c
@@ -13,6 +13,8 @@
#include <linux/kernel.h>
#include <linux/pci.h>
#include <linux/init.h>
+#include <linux/string.h>
+#include <linux/slab.h>
#include <asm/hardware.h>
#include <asm/irq.h>
diff --git a/arch/arm/mach-ixp2000/Makefile b/arch/arm/mach-ixp2000/Makefile
index 1e6139d42a92..9621aeb61f46 100644
--- a/arch/arm/mach-ixp2000/Makefile
+++ b/arch/arm/mach-ixp2000/Makefile
@@ -1,7 +1,7 @@
#
# Makefile for the linux kernel.
#
-obj-y := core.o pci.o
+obj-y := core.o pci.o uengine.o
obj-m :=
obj-n :=
obj- :=
diff --git a/arch/arm/mach-ixp2000/core.c b/arch/arm/mach-ixp2000/core.c
index f4d7f1f6ef85..6851abaf5524 100644
--- a/arch/arm/mach-ixp2000/core.c
+++ b/arch/arm/mach-ixp2000/core.c
@@ -1,5 +1,5 @@
/*
- * arch/arm/mach-ixp2000/common.c
+ * arch/arm/mach-ixp2000/core.c
*
* Common routines used by all IXP2400/2800 based platforms.
*
@@ -49,7 +49,6 @@ static unsigned long ixp2000_slowport_irq_flags;
*************************************************************************/
void ixp2000_acquire_slowport(struct slowport_cfg *new_cfg, struct slowport_cfg *old_cfg)
{
-
spin_lock_irqsave(&ixp2000_slowport_lock, ixp2000_slowport_irq_flags);
old_cfg->CCR = *IXP2000_SLOWPORT_CCR;
@@ -62,7 +61,7 @@ void ixp2000_acquire_slowport(struct slowport_cfg *new_cfg, struct slowport_cfg
ixp2000_reg_write(IXP2000_SLOWPORT_WTC2, new_cfg->WTC);
ixp2000_reg_write(IXP2000_SLOWPORT_RTC2, new_cfg->RTC);
ixp2000_reg_write(IXP2000_SLOWPORT_PCR, new_cfg->PCR);
- ixp2000_reg_write(IXP2000_SLOWPORT_ADC, new_cfg->ADC);
+ ixp2000_reg_wrb(IXP2000_SLOWPORT_ADC, new_cfg->ADC);
}
void ixp2000_release_slowport(struct slowport_cfg *old_cfg)
@@ -71,7 +70,7 @@ void ixp2000_release_slowport(struct slowport_cfg *old_cfg)
ixp2000_reg_write(IXP2000_SLOWPORT_WTC2, old_cfg->WTC);
ixp2000_reg_write(IXP2000_SLOWPORT_RTC2, old_cfg->RTC);
ixp2000_reg_write(IXP2000_SLOWPORT_PCR, old_cfg->PCR);
- ixp2000_reg_write(IXP2000_SLOWPORT_ADC, old_cfg->ADC);
+ ixp2000_reg_wrb(IXP2000_SLOWPORT_ADC, old_cfg->ADC);
spin_unlock_irqrestore(&ixp2000_slowport_lock,
ixp2000_slowport_irq_flags);
@@ -83,69 +82,60 @@ void ixp2000_release_slowport(struct slowport_cfg *old_cfg)
static struct map_desc ixp2000_io_desc[] __initdata = {
{
.virtual = IXP2000_CAP_VIRT_BASE,
- .physical = IXP2000_CAP_PHYS_BASE,
+ .pfn = __phys_to_pfn(IXP2000_CAP_PHYS_BASE),
.length = IXP2000_CAP_SIZE,
- .type = MT_DEVICE
+ .type = MT_IXP2000_DEVICE,
}, {
.virtual = IXP2000_INTCTL_VIRT_BASE,
- .physical = IXP2000_INTCTL_PHYS_BASE,
+ .pfn = __phys_to_pfn(IXP2000_INTCTL_PHYS_BASE),
.length = IXP2000_INTCTL_SIZE,
- .type = MT_DEVICE
+ .type = MT_IXP2000_DEVICE,
}, {
.virtual = IXP2000_PCI_CREG_VIRT_BASE,
- .physical = IXP2000_PCI_CREG_PHYS_BASE,
+ .pfn = __phys_to_pfn(IXP2000_PCI_CREG_PHYS_BASE),
.length = IXP2000_PCI_CREG_SIZE,
- .type = MT_DEVICE
+ .type = MT_IXP2000_DEVICE,
}, {
.virtual = IXP2000_PCI_CSR_VIRT_BASE,
- .physical = IXP2000_PCI_CSR_PHYS_BASE,
+ .pfn = __phys_to_pfn(IXP2000_PCI_CSR_PHYS_BASE),
.length = IXP2000_PCI_CSR_SIZE,
- .type = MT_DEVICE
+ .type = MT_IXP2000_DEVICE,
}, {
.virtual = IXP2000_MSF_VIRT_BASE,
- .physical = IXP2000_MSF_PHYS_BASE,
+ .pfn = __phys_to_pfn(IXP2000_MSF_PHYS_BASE),
.length = IXP2000_MSF_SIZE,
- .type = MT_DEVICE
+ .type = MT_IXP2000_DEVICE,
}, {
.virtual = IXP2000_PCI_IO_VIRT_BASE,
- .physical = IXP2000_PCI_IO_PHYS_BASE,
+ .pfn = __phys_to_pfn(IXP2000_PCI_IO_PHYS_BASE),
.length = IXP2000_PCI_IO_SIZE,
- .type = MT_DEVICE
+ .type = MT_IXP2000_DEVICE,
}, {
.virtual = IXP2000_PCI_CFG0_VIRT_BASE,
- .physical = IXP2000_PCI_CFG0_PHYS_BASE,
+ .pfn = __phys_to_pfn(IXP2000_PCI_CFG0_PHYS_BASE),
.length = IXP2000_PCI_CFG0_SIZE,
- .type = MT_DEVICE
+ .type = MT_IXP2000_DEVICE,
}, {
.virtual = IXP2000_PCI_CFG1_VIRT_BASE,
- .physical = IXP2000_PCI_CFG1_PHYS_BASE,
+ .pfn = __phys_to_pfn(IXP2000_PCI_CFG1_PHYS_BASE),
.length = IXP2000_PCI_CFG1_SIZE,
- .type = MT_DEVICE
+ .type = MT_IXP2000_DEVICE,
}
};
void __init ixp2000_map_io(void)
{
- extern unsigned int processor_id;
-
/*
- * On IXP2400 CPUs we need to use MT_IXP2000_DEVICE for
- * tweaking the PMDs so XCB=101. On IXP2800s we use the normal
- * PMD flags.
+ * On IXP2400 CPUs we need to use MT_IXP2000_DEVICE so that
+ * XCB=101 (to avoid triggering erratum #66), and given that
+ * this mode speeds up I/O accesses and we have write buffer
+ * flushes in the right places anyway, it doesn't hurt to use
+ * XCB=101 for all IXP2000s.
*/
- if ((processor_id & 0xfffffff0) == 0x69054190) {
- int i;
-
- printk(KERN_INFO "Enabling IXP2400 erratum #66 workaround\n");
-
- for(i=0;i<ARRAY_SIZE(ixp2000_io_desc);i++)
- ixp2000_io_desc[i].type = MT_IXP2000_DEVICE;
- }
-
iotable_init(ixp2000_io_desc, ARRAY_SIZE(ixp2000_io_desc));
/* Set slowport to 8-bit mode. */
- ixp2000_reg_write(IXP2000_SLOWPORT_FRM, 1);
+ ixp2000_reg_wrb(IXP2000_SLOWPORT_FRM, 1);
}
@@ -209,7 +199,7 @@ static int ixp2000_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
write_seqlock(&xtime_lock);
/* clear timer 1 */
- ixp2000_reg_write(IXP2000_T1_CLR, 1);
+ ixp2000_reg_wrb(IXP2000_T1_CLR, 1);
while ((next_jiffy_time - *missing_jiffy_timer_csr) > ticks_per_jiffy) {
timer_tick(regs);
@@ -252,12 +242,12 @@ void __init ixp2000_init_time(unsigned long tick_rate)
ixp2000_reg_write(IXP2000_T4_CLR, 0);
ixp2000_reg_write(IXP2000_T4_CLD, -1);
- ixp2000_reg_write(IXP2000_T4_CTL, (1 << 7));
+ ixp2000_reg_wrb(IXP2000_T4_CTL, (1 << 7));
missing_jiffy_timer_csr = IXP2000_T4_CSR;
} else {
ixp2000_reg_write(IXP2000_T2_CLR, 0);
ixp2000_reg_write(IXP2000_T2_CLD, -1);
- ixp2000_reg_write(IXP2000_T2_CTL, (1 << 7));
+ ixp2000_reg_wrb(IXP2000_T2_CTL, (1 << 7));
missing_jiffy_timer_csr = IXP2000_T2_CSR;
}
next_jiffy_time = 0xffffffff;
@@ -279,7 +269,7 @@ static void update_gpio_int_csrs(void)
ixp2000_reg_write(IXP2000_GPIO_FEDR, GPIO_IRQ_falling_edge);
ixp2000_reg_write(IXP2000_GPIO_REDR, GPIO_IRQ_rising_edge);
ixp2000_reg_write(IXP2000_GPIO_LSLR, GPIO_IRQ_level_low);
- ixp2000_reg_write(IXP2000_GPIO_LSHR, GPIO_IRQ_level_high);
+ ixp2000_reg_wrb(IXP2000_GPIO_LSHR, GPIO_IRQ_level_high);
}
void gpio_line_config(int line, int direction)
@@ -297,9 +287,9 @@ void gpio_line_config(int line, int direction)
GPIO_IRQ_level_high &= ~(1 << line);
update_gpio_int_csrs();
- ixp2000_reg_write(IXP2000_GPIO_PDSR, 1 << line);
+ ixp2000_reg_wrb(IXP2000_GPIO_PDSR, 1 << line);
} else if (direction == GPIO_IN) {
- ixp2000_reg_write(IXP2000_GPIO_PDCR, 1 << line);
+ ixp2000_reg_wrb(IXP2000_GPIO_PDCR, 1 << line);
}
local_irq_restore(flags);
}
@@ -365,12 +355,12 @@ static void ixp2000_GPIO_irq_mask_ack(unsigned int irq)
ixp2000_reg_write(IXP2000_GPIO_EDSR, (1 << (irq - IRQ_IXP2000_GPIO0)));
ixp2000_reg_write(IXP2000_GPIO_LDSR, (1 << (irq - IRQ_IXP2000_GPIO0)));
- ixp2000_reg_write(IXP2000_GPIO_INST, (1 << (irq - IRQ_IXP2000_GPIO0)));
+ ixp2000_reg_wrb(IXP2000_GPIO_INST, (1 << (irq - IRQ_IXP2000_GPIO0)));
}
static void ixp2000_GPIO_irq_mask(unsigned int irq)
{
- ixp2000_reg_write(IXP2000_GPIO_INCR, (1 << (irq - IRQ_IXP2000_GPIO0)));
+ ixp2000_reg_wrb(IXP2000_GPIO_INCR, (1 << (irq - IRQ_IXP2000_GPIO0)));
}
static void ixp2000_GPIO_irq_unmask(unsigned int irq)
@@ -389,9 +379,9 @@ static void ixp2000_pci_irq_mask(unsigned int irq)
{
unsigned long temp = *IXP2000_PCI_XSCALE_INT_ENABLE;
if (irq == IRQ_IXP2000_PCIA)
- ixp2000_reg_write(IXP2000_PCI_XSCALE_INT_ENABLE, (temp & ~(1 << 26)));
+ ixp2000_reg_wrb(IXP2000_PCI_XSCALE_INT_ENABLE, (temp & ~(1 << 26)));
else if (irq == IRQ_IXP2000_PCIB)
- ixp2000_reg_write(IXP2000_PCI_XSCALE_INT_ENABLE, (temp & ~(1 << 27)));
+ ixp2000_reg_wrb(IXP2000_PCI_XSCALE_INT_ENABLE, (temp & ~(1 << 27)));
}
static void ixp2000_pci_irq_unmask(unsigned int irq)
@@ -403,6 +393,40 @@ static void ixp2000_pci_irq_unmask(unsigned int irq)
ixp2000_reg_write(IXP2000_PCI_XSCALE_INT_ENABLE, (temp | (1 << 27)));
}
+/*
+ * Error interrupts. These are used extensively by the microengine drivers
+ */
+static void ixp2000_err_irq_handler(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs)
+{
+ int i;
+ unsigned long status = *IXP2000_IRQ_ERR_STATUS;
+
+ for(i = 31; i >= 0; i--) {
+ if(status & (1 << i)) {
+ desc = irq_desc + IRQ_IXP2000_DRAM0_MIN_ERR + i;
+ desc->handle(IRQ_IXP2000_DRAM0_MIN_ERR + i, desc, regs);
+ }
+ }
+}
+
+static void ixp2000_err_irq_mask(unsigned int irq)
+{
+ ixp2000_reg_write(IXP2000_IRQ_ERR_ENABLE_CLR,
+ (1 << (irq - IRQ_IXP2000_DRAM0_MIN_ERR)));
+}
+
+static void ixp2000_err_irq_unmask(unsigned int irq)
+{
+ ixp2000_reg_write(IXP2000_IRQ_ERR_ENABLE_SET,
+ (1 << (irq - IRQ_IXP2000_DRAM0_MIN_ERR)));
+}
+
+static struct irqchip ixp2000_err_irq_chip = {
+ .ack = ixp2000_err_irq_mask,
+ .mask = ixp2000_err_irq_mask,
+ .unmask = ixp2000_err_irq_unmask
+};
+
static struct irqchip ixp2000_pci_irq_chip = {
.ack = ixp2000_pci_irq_mask,
.mask = ixp2000_pci_irq_mask,
@@ -411,7 +435,7 @@ static struct irqchip ixp2000_pci_irq_chip = {
static void ixp2000_irq_mask(unsigned int irq)
{
- ixp2000_reg_write(IXP2000_IRQ_ENABLE_CLR, (1 << irq));
+ ixp2000_reg_wrb(IXP2000_IRQ_ENABLE_CLR, (1 << irq));
}
static void ixp2000_irq_unmask(unsigned int irq)
@@ -443,7 +467,7 @@ void __init ixp2000_init_irq(void)
ixp2000_reg_write(IXP2000_GPIO_INCR, -1);
/* clear PCI interrupt sources */
- ixp2000_reg_write(IXP2000_PCI_XSCALE_INT_ENABLE, 0);
+ ixp2000_reg_wrb(IXP2000_PCI_XSCALE_INT_ENABLE, 0);
/*
* Certain bits in the IRQ status register of the
@@ -460,6 +484,18 @@ void __init ixp2000_init_irq(void)
} else set_irq_flags(irq, 0);
}
+ for (irq = IRQ_IXP2000_DRAM0_MIN_ERR; irq <= IRQ_IXP2000_SP_INT; irq++) {
+ if((1 << (irq - IRQ_IXP2000_DRAM0_MIN_ERR)) &
+ IXP2000_VALID_ERR_IRQ_MASK) {
+ set_irq_chip(irq, &ixp2000_err_irq_chip);
+ set_irq_handler(irq, do_level_IRQ);
+ set_irq_flags(irq, IRQF_VALID);
+ }
+ else
+ set_irq_flags(irq, 0);
+ }
+ set_irq_chained_handler(IRQ_IXP2000_ERRSUM, ixp2000_err_irq_handler);
+
/*
* GPIO IRQs are invalid until someone sets the interrupt mode
* by calling set_irq_type().
diff --git a/arch/arm/mach-ixp2000/enp2611.c b/arch/arm/mach-ixp2000/enp2611.c
index 9aa54de44740..61f6006241bd 100644
--- a/arch/arm/mach-ixp2000/enp2611.c
+++ b/arch/arm/mach-ixp2000/enp2611.c
@@ -32,7 +32,7 @@
#include <linux/serial.h>
#include <linux/tty.h>
#include <linux/serial_core.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <asm/io.h>
#include <asm/irq.h>
@@ -64,6 +64,35 @@ static struct sys_timer enp2611_timer = {
/*************************************************************************
+ * ENP-2611 I/O
+ *************************************************************************/
+static struct map_desc enp2611_io_desc[] __initdata = {
+ {
+ .virtual = ENP2611_CALEB_VIRT_BASE,
+ .pfn = __phys_to_pfn(ENP2611_CALEB_PHYS_BASE),
+ .length = ENP2611_CALEB_SIZE,
+ .type = MT_IXP2000_DEVICE,
+ }, {
+ .virtual = ENP2611_PM3386_0_VIRT_BASE,
+ .pfn = __phys_to_pfn(ENP2611_PM3386_0_PHYS_BASE),
+ .length = ENP2611_PM3386_0_SIZE,
+ .type = MT_IXP2000_DEVICE,
+ }, {
+ .virtual = ENP2611_PM3386_1_VIRT_BASE,
+ .pfn = __phys_to_pfn(ENP2611_PM3386_1_PHYS_BASE),
+ .length = ENP2611_PM3386_1_SIZE,
+ .type = MT_IXP2000_DEVICE,
+ }
+};
+
+void __init enp2611_map_io(void)
+{
+ ixp2000_map_io();
+ iotable_init(enp2611_io_desc, ARRAY_SIZE(enp2611_io_desc));
+}
+
+
+/*************************************************************************
* ENP-2611 PCI
*************************************************************************/
static int enp2611_pci_setup(int nr, struct pci_sys_data *sys)
@@ -229,7 +258,7 @@ MACHINE_START(ENP2611, "Radisys ENP-2611 PCI network processor board")
.phys_io = IXP2000_UART_PHYS_BASE,
.io_pg_offst = ((IXP2000_UART_VIRT_BASE) >> 18) & 0xfffc,
.boot_params = 0x00000100,
- .map_io = ixp2000_map_io,
+ .map_io = enp2611_map_io,
.init_irq = ixp2000_init_irq,
.timer = &enp2611_timer,
.init_machine = enp2611_init_machine,
diff --git a/arch/arm/mach-ixp2000/ixdp2x00.c b/arch/arm/mach-ixp2000/ixdp2x00.c
index 63ba0191aa65..d628da56b4bc 100644
--- a/arch/arm/mach-ixp2000/ixdp2x00.c
+++ b/arch/arm/mach-ixp2000/ixdp2x00.c
@@ -20,7 +20,7 @@
#include <linux/mm.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <linux/bitops.h>
#include <linux/pci.h>
#include <linux/ioport.h>
@@ -81,7 +81,7 @@ static void ixdp2x00_irq_mask(unsigned int irq)
dummy = *board_irq_mask;
dummy |= IXP2000_BOARD_IRQ_MASK(irq);
- ixp2000_reg_write(board_irq_mask, dummy);
+ ixp2000_reg_wrb(board_irq_mask, dummy);
#ifdef CONFIG_ARCH_IXDP2400
if (machine_is_ixdp2400())
@@ -101,7 +101,7 @@ static void ixdp2x00_irq_unmask(unsigned int irq)
dummy = *board_irq_mask;
dummy &= ~IXP2000_BOARD_IRQ_MASK(irq);
- ixp2000_reg_write(board_irq_mask, dummy);
+ ixp2000_reg_wrb(board_irq_mask, dummy);
if (machine_is_ixdp2400())
ixp2000_release_slowport(&old_cfg);
@@ -176,7 +176,7 @@ void ixdp2x00_init_irq(volatile unsigned long *stat_reg, volatile unsigned long
*************************************************************************/
static struct map_desc ixdp2x00_io_desc __initdata = {
.virtual = IXDP2X00_VIRT_CPLD_BASE,
- .physical = IXDP2X00_PHYS_CPLD_BASE,
+ .pfn = __phys_to_pfn(IXDP2X00_PHYS_CPLD_BASE),
.length = IXDP2X00_CPLD_SIZE,
.type = MT_DEVICE
};
diff --git a/arch/arm/mach-ixp2000/ixdp2x01.c b/arch/arm/mach-ixp2000/ixdp2x01.c
index 7a5109921287..e6a882f35da2 100644
--- a/arch/arm/mach-ixp2000/ixdp2x01.c
+++ b/arch/arm/mach-ixp2000/ixdp2x01.c
@@ -29,7 +29,7 @@
#include <linux/serial.h>
#include <linux/tty.h>
#include <linux/serial_core.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <asm/io.h>
#include <asm/irq.h>
@@ -51,7 +51,7 @@
*************************************************************************/
static void ixdp2x01_irq_mask(unsigned int irq)
{
- ixp2000_reg_write(IXDP2X01_INT_MASK_SET_REG,
+ ixp2000_reg_wrb(IXDP2X01_INT_MASK_SET_REG,
IXP2000_BOARD_IRQ_MASK(irq));
}
@@ -114,7 +114,7 @@ void __init ixdp2x01_init_irq(void)
/* Mask all interrupts from CPLD, disable simulation */
ixp2000_reg_write(IXDP2X01_INT_MASK_SET_REG, 0xffffffff);
- ixp2000_reg_write(IXDP2X01_INT_SIM_REG, 0);
+ ixp2000_reg_wrb(IXDP2X01_INT_SIM_REG, 0);
for (irq = NR_IXP2000_IRQS; irq < NR_IXDP2X01_IRQS; irq++) {
if (irq & valid_irq_mask) {
@@ -136,7 +136,7 @@ void __init ixdp2x01_init_irq(void)
*************************************************************************/
static struct map_desc ixdp2x01_io_desc __initdata = {
.virtual = IXDP2X01_VIRT_CPLD_BASE,
- .physical = IXDP2X01_PHYS_CPLD_BASE,
+ .pfn = __phys_to_pfn(IXDP2X01_PHYS_CPLD_BASE),
.length = IXDP2X01_CPLD_REGION_SIZE,
.type = MT_DEVICE
};
@@ -299,7 +299,6 @@ struct hw_pci ixdp2x01_pci __initdata = {
int __init ixdp2x01_pci_init(void)
{
-
pci_common_init(&ixdp2x01_pci);
return 0;
}
@@ -316,7 +315,7 @@ static struct flash_platform_data ixdp2x01_flash_platform_data = {
static unsigned long ixdp2x01_flash_bank_setup(unsigned long ofs)
{
- ixp2000_reg_write(IXDP2X01_CPLD_FLASH_REG,
+ ixp2000_reg_wrb(IXDP2X01_CPLD_FLASH_REG,
((ofs >> IXDP2X01_FLASH_WINDOW_BITS) | IXDP2X01_CPLD_FLASH_INTERN));
return (ofs & IXDP2X01_FLASH_WINDOW_MASK);
}
@@ -363,7 +362,7 @@ static struct platform_device *ixdp2x01_devices[] __initdata = {
static void __init ixdp2x01_init_machine(void)
{
- ixp2000_reg_write(IXDP2X01_CPLD_FLASH_REG,
+ ixp2000_reg_wrb(IXDP2X01_CPLD_FLASH_REG,
(IXDP2X01_CPLD_FLASH_BANK_MASK | IXDP2X01_CPLD_FLASH_INTERN));
ixdp2x01_flash_data.nr_banks =
diff --git a/arch/arm/mach-ixp2000/pci.c b/arch/arm/mach-ixp2000/pci.c
index 522205acb316..d4bf1e1c0031 100644
--- a/arch/arm/mach-ixp2000/pci.c
+++ b/arch/arm/mach-ixp2000/pci.c
@@ -148,7 +148,7 @@ int ixp2000_pci_abort_handler(unsigned long addr, unsigned int fsr, struct pt_re
local_irq_save(flags);
temp = *(IXP2000_PCI_CONTROL);
if (temp & ((1 << 8) | (1 << 5))) {
- ixp2000_reg_write(IXP2000_PCI_CONTROL, temp);
+ ixp2000_reg_wrb(IXP2000_PCI_CONTROL, temp);
}
temp = *(IXP2000_PCI_CMDSTAT);
@@ -178,8 +178,8 @@ clear_master_aborts(void)
local_irq_save(flags);
temp = *(IXP2000_PCI_CONTROL);
- if (temp & ((1 << 8) | (1 << 5))) {
- ixp2000_reg_write(IXP2000_PCI_CONTROL, temp);
+ if (temp & ((1 << 8) | (1 << 5))) {
+ ixp2000_reg_wrb(IXP2000_PCI_CONTROL, temp);
}
temp = *(IXP2000_PCI_CMDSTAT);
diff --git a/arch/arm/mach-ixp2000/uengine.c b/arch/arm/mach-ixp2000/uengine.c
new file mode 100644
index 000000000000..ec4e007a22ef
--- /dev/null
+++ b/arch/arm/mach-ixp2000/uengine.c
@@ -0,0 +1,473 @@
+/*
+ * Generic library functions for the microengines found on the Intel
+ * IXP2000 series of network processors.
+ *
+ * Copyright (C) 2004, 2005 Lennert Buytenhek <buytenh@wantstofly.org>
+ * Dedicated to Marija Kulikova.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of the
+ * License, or (at your option) any later version.
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <asm/hardware.h>
+#include <asm/arch/ixp2000-regs.h>
+#include <asm/arch/uengine.h>
+#include <asm/io.h>
+
+#define USTORE_ADDRESS 0x000
+#define USTORE_DATA_LOWER 0x004
+#define USTORE_DATA_UPPER 0x008
+#define CTX_ENABLES 0x018
+#define CC_ENABLE 0x01c
+#define CSR_CTX_POINTER 0x020
+#define INDIRECT_CTX_STS 0x040
+#define ACTIVE_CTX_STS 0x044
+#define INDIRECT_CTX_SIG_EVENTS 0x048
+#define INDIRECT_CTX_WAKEUP_EVENTS 0x050
+#define NN_PUT 0x080
+#define NN_GET 0x084
+#define TIMESTAMP_LOW 0x0c0
+#define TIMESTAMP_HIGH 0x0c4
+#define T_INDEX_BYTE_INDEX 0x0f4
+#define LOCAL_CSR_STATUS 0x180
+
+u32 ixp2000_uengine_mask;
+
+static void *ixp2000_uengine_csr_area(int uengine)
+{
+ return ((void *)IXP2000_UENGINE_CSR_VIRT_BASE) + (uengine << 10);
+}
+
+/*
+ * LOCAL_CSR_STATUS=1 after a read or write to a microengine's CSR
+ * space means that the microengine we tried to access was also trying
+ * to access its own CSR space on the same clock cycle as we did. When
+ * this happens, we lose the arbitration process by default, and the
+ * read or write we tried to do was not actually performed, so we try
+ * again until it succeeds.
+ */
+u32 ixp2000_uengine_csr_read(int uengine, int offset)
+{
+ void *uebase;
+ u32 *local_csr_status;
+ u32 *reg;
+ u32 value;
+
+ uebase = ixp2000_uengine_csr_area(uengine);
+
+ local_csr_status = (u32 *)(uebase + LOCAL_CSR_STATUS);
+ reg = (u32 *)(uebase + offset);
+ do {
+ value = ixp2000_reg_read(reg);
+ } while (ixp2000_reg_read(local_csr_status) & 1);
+
+ return value;
+}
+EXPORT_SYMBOL(ixp2000_uengine_csr_read);
+
+void ixp2000_uengine_csr_write(int uengine, int offset, u32 value)
+{
+ void *uebase;
+ u32 *local_csr_status;
+ u32 *reg;
+
+ uebase = ixp2000_uengine_csr_area(uengine);
+
+ local_csr_status = (u32 *)(uebase + LOCAL_CSR_STATUS);
+ reg = (u32 *)(uebase + offset);
+ do {
+ ixp2000_reg_write(reg, value);
+ } while (ixp2000_reg_read(local_csr_status) & 1);
+}
+EXPORT_SYMBOL(ixp2000_uengine_csr_write);
+
+void ixp2000_uengine_reset(u32 uengine_mask)
+{
+ ixp2000_reg_wrb(IXP2000_RESET1, uengine_mask & ixp2000_uengine_mask);
+ ixp2000_reg_wrb(IXP2000_RESET1, 0);
+}
+EXPORT_SYMBOL(ixp2000_uengine_reset);
+
+void ixp2000_uengine_set_mode(int uengine, u32 mode)
+{
+ /*
+ * CTL_STR_PAR_EN: unconditionally enable parity checking on
+ * control store.
+ */
+ mode |= 0x10000000;
+ ixp2000_uengine_csr_write(uengine, CTX_ENABLES, mode);
+
+ /*
+ * Enable updating of condition codes.
+ */
+ ixp2000_uengine_csr_write(uengine, CC_ENABLE, 0x00002000);
+
+ /*
+ * Initialise other per-microengine registers.
+ */
+ ixp2000_uengine_csr_write(uengine, NN_PUT, 0x00);
+ ixp2000_uengine_csr_write(uengine, NN_GET, 0x00);
+ ixp2000_uengine_csr_write(uengine, T_INDEX_BYTE_INDEX, 0);
+}
+EXPORT_SYMBOL(ixp2000_uengine_set_mode);
+
+static int make_even_parity(u32 x)
+{
+ return hweight32(x) & 1;
+}
+
+static void ustore_write(int uengine, u64 insn)
+{
+ /*
+ * Generate even parity for top and bottom 20 bits.
+ */
+ insn |= (u64)make_even_parity((insn >> 20) & 0x000fffff) << 41;
+ insn |= (u64)make_even_parity(insn & 0x000fffff) << 40;
+
+ /*
+ * Write to microstore. The second write auto-increments
+ * the USTORE_ADDRESS index register.
+ */
+ ixp2000_uengine_csr_write(uengine, USTORE_DATA_LOWER, (u32)insn);
+ ixp2000_uengine_csr_write(uengine, USTORE_DATA_UPPER, (u32)(insn >> 32));
+}
+
+void ixp2000_uengine_load_microcode(int uengine, u8 *ucode, int insns)
+{
+ int i;
+
+ /*
+ * Start writing to microstore at address 0.
+ */
+ ixp2000_uengine_csr_write(uengine, USTORE_ADDRESS, 0x80000000);
+ for (i = 0; i < insns; i++) {
+ u64 insn;
+
+ insn = (((u64)ucode[0]) << 32) |
+ (((u64)ucode[1]) << 24) |
+ (((u64)ucode[2]) << 16) |
+ (((u64)ucode[3]) << 8) |
+ ((u64)ucode[4]);
+ ucode += 5;
+
+ ustore_write(uengine, insn);
+ }
+
+ /*
+ * Pad with a few NOPs at the end (to avoid the microengine
+ * aborting as it prefetches beyond the last instruction), unless
+ * we run off the end of the instruction store first, at which
+ * point the address register will wrap back to zero.
+ */
+ for (i = 0; i < 4; i++) {
+ u32 addr;
+
+ addr = ixp2000_uengine_csr_read(uengine, USTORE_ADDRESS);
+ if (addr == 0x80000000)
+ break;
+ ustore_write(uengine, 0xf0000c0300ULL);
+ }
+
+ /*
+ * End programming.
+ */
+ ixp2000_uengine_csr_write(uengine, USTORE_ADDRESS, 0x00000000);
+}
+EXPORT_SYMBOL(ixp2000_uengine_load_microcode);
+
+void ixp2000_uengine_init_context(int uengine, int context, int pc)
+{
+ /*
+ * Select the right context for indirect access.
+ */
+ ixp2000_uengine_csr_write(uengine, CSR_CTX_POINTER, context);
+
+ /*
+ * Initialise signal masks to immediately go to Ready state.
+ */
+ ixp2000_uengine_csr_write(uengine, INDIRECT_CTX_SIG_EVENTS, 1);
+ ixp2000_uengine_csr_write(uengine, INDIRECT_CTX_WAKEUP_EVENTS, 1);
+
+ /*
+ * Set program counter.
+ */
+ ixp2000_uengine_csr_write(uengine, INDIRECT_CTX_STS, pc);
+}
+EXPORT_SYMBOL(ixp2000_uengine_init_context);
+
+void ixp2000_uengine_start_contexts(int uengine, u8 ctx_mask)
+{
+ u32 mask;
+
+ /*
+ * Enable the specified context to go to Executing state.
+ */
+ mask = ixp2000_uengine_csr_read(uengine, CTX_ENABLES);
+ mask |= ctx_mask << 8;
+ ixp2000_uengine_csr_write(uengine, CTX_ENABLES, mask);
+}
+EXPORT_SYMBOL(ixp2000_uengine_start_contexts);
+
+void ixp2000_uengine_stop_contexts(int uengine, u8 ctx_mask)
+{
+ u32 mask;
+
+ /*
+ * Disable the Ready->Executing transition. Note that this
+ * does not stop the context until it voluntarily yields.
+ */
+ mask = ixp2000_uengine_csr_read(uengine, CTX_ENABLES);
+ mask &= ~(ctx_mask << 8);
+ ixp2000_uengine_csr_write(uengine, CTX_ENABLES, mask);
+}
+EXPORT_SYMBOL(ixp2000_uengine_stop_contexts);
+
+static int check_ixp_type(struct ixp2000_uengine_code *c)
+{
+ u32 product_id;
+ u32 rev;
+
+ product_id = ixp2000_reg_read(IXP2000_PRODUCT_ID);
+ if (((product_id >> 16) & 0x1f) != 0)
+ return 0;
+
+ switch ((product_id >> 8) & 0xff) {
+ case 0: /* IXP2800 */
+ if (!(c->cpu_model_bitmask & 4))
+ return 0;
+ break;
+
+ case 1: /* IXP2850 */
+ if (!(c->cpu_model_bitmask & 8))
+ return 0;
+ break;
+
+ case 2: /* IXP2400 */
+ if (!(c->cpu_model_bitmask & 2))
+ return 0;
+ break;
+
+ default:
+ return 0;
+ }
+
+ rev = product_id & 0xff;
+ if (rev < c->cpu_min_revision || rev > c->cpu_max_revision)
+ return 0;
+
+ return 1;
+}
+
+static void generate_ucode(u8 *ucode, u32 *gpr_a, u32 *gpr_b)
+{
+ int offset;
+ int i;
+
+ offset = 0;
+
+ for (i = 0; i < 128; i++) {
+ u8 b3;
+ u8 b2;
+ u8 b1;
+ u8 b0;
+
+ b3 = (gpr_a[i] >> 24) & 0xff;
+ b2 = (gpr_a[i] >> 16) & 0xff;
+ b1 = (gpr_a[i] >> 8) & 0xff;
+ b0 = gpr_a[i] & 0xff;
+
+ // immed[@ai, (b1 << 8) | b0]
+ // 11110000 0000VVVV VVVV11VV VVVVVV00 1IIIIIII
+ ucode[offset++] = 0xf0;
+ ucode[offset++] = (b1 >> 4);
+ ucode[offset++] = (b1 << 4) | 0x0c | (b0 >> 6);
+ ucode[offset++] = (b0 << 2);
+ ucode[offset++] = 0x80 | i;
+
+ // immed_w1[@ai, (b3 << 8) | b2]
+ // 11110100 0100VVVV VVVV11VV VVVVVV00 1IIIIIII
+ ucode[offset++] = 0xf4;
+ ucode[offset++] = 0x40 | (b3 >> 4);
+ ucode[offset++] = (b3 << 4) | 0x0c | (b2 >> 6);
+ ucode[offset++] = (b2 << 2);
+ ucode[offset++] = 0x80 | i;
+ }
+
+ for (i = 0; i < 128; i++) {
+ u8 b3;
+ u8 b2;
+ u8 b1;
+ u8 b0;
+
+ b3 = (gpr_b[i] >> 24) & 0xff;
+ b2 = (gpr_b[i] >> 16) & 0xff;
+ b1 = (gpr_b[i] >> 8) & 0xff;
+ b0 = gpr_b[i] & 0xff;
+
+ // immed[@bi, (b1 << 8) | b0]
+ // 11110000 0000VVVV VVVV001I IIIIII11 VVVVVVVV
+ ucode[offset++] = 0xf0;
+ ucode[offset++] = (b1 >> 4);
+ ucode[offset++] = (b1 << 4) | 0x02 | (i >> 6);
+ ucode[offset++] = (i << 2) | 0x03;
+ ucode[offset++] = b0;
+
+ // immed_w1[@bi, (b3 << 8) | b2]
+ // 11110100 0100VVVV VVVV001I IIIIII11 VVVVVVVV
+ ucode[offset++] = 0xf4;
+ ucode[offset++] = 0x40 | (b3 >> 4);
+ ucode[offset++] = (b3 << 4) | 0x02 | (i >> 6);
+ ucode[offset++] = (i << 2) | 0x03;
+ ucode[offset++] = b2;
+ }
+
+ // ctx_arb[kill]
+ ucode[offset++] = 0xe0;
+ ucode[offset++] = 0x00;
+ ucode[offset++] = 0x01;
+ ucode[offset++] = 0x00;
+ ucode[offset++] = 0x00;
+}
+
+static int set_initial_registers(int uengine, struct ixp2000_uengine_code *c)
+{
+ int per_ctx_regs;
+ u32 *gpr_a;
+ u32 *gpr_b;
+ u8 *ucode;
+ int i;
+
+ gpr_a = kmalloc(128 * sizeof(u32), GFP_KERNEL);
+ gpr_b = kmalloc(128 * sizeof(u32), GFP_KERNEL);
+ ucode = kmalloc(513 * 5, GFP_KERNEL);
+ if (gpr_a == NULL || gpr_b == NULL || ucode == NULL) {
+ kfree(ucode);
+ kfree(gpr_b);
+ kfree(gpr_a);
+ return 1;
+ }
+
+ per_ctx_regs = 16;
+ if (c->uengine_parameters & IXP2000_UENGINE_4_CONTEXTS)
+ per_ctx_regs = 32;
+
+ memset(gpr_a, 0, sizeof(gpr_a));
+ memset(gpr_b, 0, sizeof(gpr_b));
+ for (i = 0; i < 256; i++) {
+ struct ixp2000_reg_value *r = c->initial_reg_values + i;
+ u32 *bank;
+ int inc;
+ int j;
+
+ if (r->reg == -1)
+ break;
+
+ bank = (r->reg & 0x400) ? gpr_b : gpr_a;
+ inc = (r->reg & 0x80) ? 128 : per_ctx_regs;
+
+ j = r->reg & 0x7f;
+ while (j < 128) {
+ bank[j] = r->value;
+ j += inc;
+ }
+ }
+
+ generate_ucode(ucode, gpr_a, gpr_b);
+ ixp2000_uengine_load_microcode(uengine, ucode, 513);
+ ixp2000_uengine_init_context(uengine, 0, 0);
+ ixp2000_uengine_start_contexts(uengine, 0x01);
+ for (i = 0; i < 100; i++) {
+ u32 status;
+
+ status = ixp2000_uengine_csr_read(uengine, ACTIVE_CTX_STS);
+ if (!(status & 0x80000000))
+ break;
+ }
+ ixp2000_uengine_stop_contexts(uengine, 0x01);
+
+ kfree(ucode);
+ kfree(gpr_b);
+ kfree(gpr_a);
+
+ return !!(i == 100);
+}
+
+int ixp2000_uengine_load(int uengine, struct ixp2000_uengine_code *c)
+{
+ int ctx;
+
+ if (!check_ixp_type(c))
+ return 1;
+
+ if (!(ixp2000_uengine_mask & (1 << uengine)))
+ return 1;
+
+ ixp2000_uengine_reset(1 << uengine);
+ ixp2000_uengine_set_mode(uengine, c->uengine_parameters);
+ if (set_initial_registers(uengine, c))
+ return 1;
+ ixp2000_uengine_load_microcode(uengine, c->insns, c->num_insns);
+
+ for (ctx = 0; ctx < 8; ctx++)
+ ixp2000_uengine_init_context(uengine, ctx, 0);
+
+ return 0;
+}
+EXPORT_SYMBOL(ixp2000_uengine_load);
+
+
+static int __init ixp2000_uengine_init(void)
+{
+ int uengine;
+ u32 value;
+
+ /*
+ * Determine number of microengines present.
+ */
+ switch ((ixp2000_reg_read(IXP2000_PRODUCT_ID) >> 8) & 0x1fff) {
+ case 0: /* IXP2800 */
+ case 1: /* IXP2850 */
+ ixp2000_uengine_mask = 0x00ff00ff;
+ break;
+
+ case 2: /* IXP2400 */
+ ixp2000_uengine_mask = 0x000f000f;
+ break;
+
+ default:
+ printk(KERN_INFO "Detected unknown IXP2000 model (%.8x)\n",
+ (unsigned int)ixp2000_reg_read(IXP2000_PRODUCT_ID));
+ ixp2000_uengine_mask = 0x00000000;
+ break;
+ }
+
+ /*
+ * Reset microengines.
+ */
+ ixp2000_uengine_reset(ixp2000_uengine_mask);
+
+ /*
+ * Synchronise timestamp counters across all microengines.
+ */
+ value = ixp2000_reg_read(IXP2000_MISC_CONTROL);
+ ixp2000_reg_wrb(IXP2000_MISC_CONTROL, value & ~0x80);
+ for (uengine = 0; uengine < 32; uengine++) {
+ if (ixp2000_uengine_mask & (1 << uengine)) {
+ ixp2000_uengine_csr_write(uengine, TIMESTAMP_LOW, 0);
+ ixp2000_uengine_csr_write(uengine, TIMESTAMP_HIGH, 0);
+ }
+ }
+ ixp2000_reg_wrb(IXP2000_MISC_CONTROL, value | 0x80);
+
+ return 0;
+}
+
+subsys_initcall(ixp2000_uengine_init);
diff --git a/arch/arm/mach-ixp4xx/Kconfig b/arch/arm/mach-ixp4xx/Kconfig
index 89762a26495c..385285851cb5 100644
--- a/arch/arm/mach-ixp4xx/Kconfig
+++ b/arch/arm/mach-ixp4xx/Kconfig
@@ -8,6 +8,16 @@ menu "Intel IXP4xx Implementation Options"
comment "IXP4xx Platforms"
+# This entry is placed on top because otherwise it would have
+# been shown as a submenu.
+config MACH_NSLU2
+ bool
+ prompt "NSLU2" if !(MACH_IXDP465 || MACH_IXDPG425 || ARCH_IXDP425 || ARCH_ADI_COYOTE || ARCH_AVILA || ARCH_IXCDP1100 || ARCH_PRPMC1100 || MACH_GTWX5715)
+ help
+ Say 'Y' here if you want your kernel to support Linksys's
+ NSLU2 NAS device. For more information on this platform,
+ see http://www.nslu2-linux.org
+
config ARCH_AVILA
bool "Avila"
help
diff --git a/arch/arm/mach-ixp4xx/Makefile b/arch/arm/mach-ixp4xx/Makefile
index ddecbda4a633..7a15629c18d0 100644
--- a/arch/arm/mach-ixp4xx/Makefile
+++ b/arch/arm/mach-ixp4xx/Makefile
@@ -8,4 +8,5 @@ obj-$(CONFIG_ARCH_IXDP4XX) += ixdp425-pci.o ixdp425-setup.o
obj-$(CONFIG_MACH_IXDPG425) += ixdpg425-pci.o coyote-setup.o
obj-$(CONFIG_ARCH_ADI_COYOTE) += coyote-pci.o coyote-setup.o
obj-$(CONFIG_MACH_GTWX5715) += gtwx5715-pci.o gtwx5715-setup.o
+obj-$(CONFIG_MACH_NSLU2) += nslu2-pci.o nslu2-setup.o nslu2-power.o
diff --git a/arch/arm/mach-ixp4xx/common-pci.c b/arch/arm/mach-ixp4xx/common-pci.c
index 2b544363c078..9795da270e3a 100644
--- a/arch/arm/mach-ixp4xx/common-pci.c
+++ b/arch/arm/mach-ixp4xx/common-pci.c
@@ -427,7 +427,7 @@ void __init ixp4xx_pci_preinit(void)
#ifdef __ARMEB__
*PCI_CSR = PCI_CSR_IC | PCI_CSR_ABE | PCI_CSR_PDS | PCI_CSR_ADS;
#else
- *PCI_CSR = PCI_CSR_IC;
+ *PCI_CSR = PCI_CSR_IC | PCI_CSR_ABE;
#endif
pr_debug("DONE\n");
diff --git a/arch/arm/mach-ixp4xx/common.c b/arch/arm/mach-ixp4xx/common.c
index 36b6045213ee..f3c687cf0071 100644
--- a/arch/arm/mach-ixp4xx/common.c
+++ b/arch/arm/mach-ixp4xx/common.c
@@ -20,6 +20,7 @@
#include <linux/serial.h>
#include <linux/sched.h>
#include <linux/tty.h>
+#include <linux/platform_device.h>
#include <linux/serial_core.h>
#include <linux/bootmem.h>
#include <linux/interrupt.h>
@@ -44,24 +45,24 @@
static struct map_desc ixp4xx_io_desc[] __initdata = {
{ /* UART, Interrupt ctrl, GPIO, timers, NPEs, MACs, USB .... */
.virtual = IXP4XX_PERIPHERAL_BASE_VIRT,
- .physical = IXP4XX_PERIPHERAL_BASE_PHYS,
+ .pfn = __phys_to_pfn(IXP4XX_PERIPHERAL_BASE_PHYS),
.length = IXP4XX_PERIPHERAL_REGION_SIZE,
.type = MT_DEVICE
}, { /* Expansion Bus Config Registers */
.virtual = IXP4XX_EXP_CFG_BASE_VIRT,
- .physical = IXP4XX_EXP_CFG_BASE_PHYS,
+ .pfn = __phys_to_pfn(IXP4XX_EXP_CFG_BASE_PHYS),
.length = IXP4XX_EXP_CFG_REGION_SIZE,
.type = MT_DEVICE
}, { /* PCI Registers */
.virtual = IXP4XX_PCI_CFG_BASE_VIRT,
- .physical = IXP4XX_PCI_CFG_BASE_PHYS,
+ .pfn = __phys_to_pfn(IXP4XX_PCI_CFG_BASE_PHYS),
.length = IXP4XX_PCI_CFG_REGION_SIZE,
.type = MT_DEVICE
},
#ifdef CONFIG_DEBUG_LL
{ /* Debug UART mapping */
.virtual = IXP4XX_DEBUG_UART_BASE_VIRT,
- .physical = IXP4XX_DEBUG_UART_BASE_PHYS,
+ .pfn = __phys_to_pfn(IXP4XX_DEBUG_UART_BASE_PHYS),
.length = IXP4XX_DEBUG_UART_REGION_SIZE,
.type = MT_DEVICE
}
diff --git a/arch/arm/mach-ixp4xx/nslu2-pci.c b/arch/arm/mach-ixp4xx/nslu2-pci.c
new file mode 100644
index 000000000000..a575f2e0b2c8
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/nslu2-pci.c
@@ -0,0 +1,77 @@
+/*
+ * arch/arm/mach-ixp4xx/nslu2-pci.c
+ *
+ * NSLU2 board-level PCI initialization
+ *
+ * based on ixdp425-pci.c:
+ * Copyright (C) 2002 Intel Corporation.
+ * Copyright (C) 2003-2004 MontaVista Software, Inc.
+ *
+ * Maintainer: http://www.nslu2-linux.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/config.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+
+#include <asm/mach/pci.h>
+#include <asm/mach-types.h>
+
+void __init nslu2_pci_preinit(void)
+{
+ set_irq_type(IRQ_NSLU2_PCI_INTA, IRQT_LOW);
+ set_irq_type(IRQ_NSLU2_PCI_INTB, IRQT_LOW);
+ set_irq_type(IRQ_NSLU2_PCI_INTC, IRQT_LOW);
+
+ gpio_line_isr_clear(NSLU2_PCI_INTA_PIN);
+ gpio_line_isr_clear(NSLU2_PCI_INTB_PIN);
+ gpio_line_isr_clear(NSLU2_PCI_INTC_PIN);
+
+ /* INTD is not configured as GPIO is used
+ * for the power input button.
+ */
+
+ ixp4xx_pci_preinit();
+}
+
+static int __init nslu2_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+ static int pci_irq_table[NSLU2_PCI_IRQ_LINES] = {
+ IRQ_NSLU2_PCI_INTA,
+ IRQ_NSLU2_PCI_INTB,
+ IRQ_NSLU2_PCI_INTC,
+ };
+
+ int irq = -1;
+
+ if (slot >= 1 && slot <= NSLU2_PCI_MAX_DEV &&
+ pin >= 1 && pin <= NSLU2_PCI_IRQ_LINES) {
+ irq = pci_irq_table[(slot + pin - 2) % NSLU2_PCI_IRQ_LINES];
+ }
+
+ return irq;
+}
+
+struct hw_pci __initdata nslu2_pci = {
+ .nr_controllers = 1,
+ .preinit = nslu2_pci_preinit,
+ .swizzle = pci_std_swizzle,
+ .setup = ixp4xx_setup,
+ .scan = ixp4xx_scan_bus,
+ .map_irq = nslu2_map_irq,
+};
+
+int __init nslu2_pci_init(void) /* monkey see, monkey do */
+{
+ if (machine_is_nslu2())
+ pci_common_init(&nslu2_pci);
+
+ return 0;
+}
+
+subsys_initcall(nslu2_pci_init);
diff --git a/arch/arm/mach-ixp4xx/nslu2-power.c b/arch/arm/mach-ixp4xx/nslu2-power.c
new file mode 100644
index 000000000000..18fbc8c0fb30
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/nslu2-power.c
@@ -0,0 +1,92 @@
+/*
+ * arch/arm/mach-ixp4xx/nslu2-power.c
+ *
+ * NSLU2 Power/Reset driver
+ *
+ * Copyright (C) 2005 Tower Technologies
+ *
+ * based on nslu2-io.c
+ * Copyright (C) 2004 Karen Spearel
+ *
+ * Author: Alessandro Zummo <a.zummo@towertech.it>
+ * Maintainers: http://www.nslu2-linux.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/module.h>
+#include <linux/reboot.h>
+#include <linux/interrupt.h>
+
+#include <asm/mach-types.h>
+
+extern void ctrl_alt_del(void);
+
+static irqreturn_t nslu2_power_handler(int irq, void *dev_id, struct pt_regs *regs)
+{
+ /* Signal init to do the ctrlaltdel action, this will bypass init if
+ * it hasn't started and do a kernel_restart.
+ */
+ ctrl_alt_del();
+
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t nslu2_reset_handler(int irq, void *dev_id, struct pt_regs *regs)
+{
+ /* This is the paper-clip reset, it shuts the machine down directly.
+ */
+ machine_power_off();
+
+ return IRQ_HANDLED;
+}
+
+static int __init nslu2_power_init(void)
+{
+ if (!(machine_is_nslu2()))
+ return 0;
+
+ *IXP4XX_GPIO_GPISR = 0x20400000; /* read the 2 irqs to clr */
+
+ set_irq_type(NSLU2_RB_IRQ, IRQT_LOW);
+ set_irq_type(NSLU2_PB_IRQ, IRQT_HIGH);
+
+ gpio_line_isr_clear(NSLU2_RB_GPIO);
+ gpio_line_isr_clear(NSLU2_PB_GPIO);
+
+ if (request_irq(NSLU2_RB_IRQ, &nslu2_reset_handler,
+ SA_INTERRUPT, "NSLU2 reset button", NULL) < 0) {
+
+ printk(KERN_DEBUG "Reset Button IRQ %d not available\n",
+ NSLU2_RB_IRQ);
+
+ return -EIO;
+ }
+
+ if (request_irq(NSLU2_PB_IRQ, &nslu2_power_handler,
+ SA_INTERRUPT, "NSLU2 power button", NULL) < 0) {
+
+ printk(KERN_DEBUG "Power Button IRQ %d not available\n",
+ NSLU2_PB_IRQ);
+
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static void __exit nslu2_power_exit(void)
+{
+ free_irq(NSLU2_RB_IRQ, NULL);
+ free_irq(NSLU2_PB_IRQ, NULL);
+}
+
+module_init(nslu2_power_init);
+module_exit(nslu2_power_exit);
+
+MODULE_AUTHOR("Alessandro Zummo <a.zummo@towertech.it>");
+MODULE_DESCRIPTION("NSLU2 Power/Reset driver");
+MODULE_LICENSE("GPL");
diff --git a/arch/arm/mach-ixp4xx/nslu2-setup.c b/arch/arm/mach-ixp4xx/nslu2-setup.c
new file mode 100644
index 000000000000..289e94cb65c2
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/nslu2-setup.c
@@ -0,0 +1,134 @@
+/*
+ * arch/arm/mach-ixp4xx/nslu2-setup.c
+ *
+ * NSLU2 board-setup
+ *
+ * based ixdp425-setup.c:
+ * Copyright (C) 2003-2004 MontaVista Software, Inc.
+ *
+ * Author: Mark Rakes <mrakes at mac.com>
+ * Maintainers: http://www.nslu2-linux.org/
+ *
+ * Fixed missing init_time in MACHINE_START kas11 10/22/04
+ * Changed to conform to new style __init ixdp425 kas11 10/22/04
+ */
+
+#include <linux/kernel.h>
+#include <linux/serial.h>
+#include <linux/serial_8250.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/flash.h>
+
+static struct flash_platform_data nslu2_flash_data = {
+ .map_name = "cfi_probe",
+ .width = 2,
+};
+
+static struct resource nslu2_flash_resource = {
+ .start = NSLU2_FLASH_BASE,
+ .end = NSLU2_FLASH_BASE + NSLU2_FLASH_SIZE,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device nslu2_flash = {
+ .name = "IXP4XX-Flash",
+ .id = 0,
+ .dev.platform_data = &nslu2_flash_data,
+ .num_resources = 1,
+ .resource = &nslu2_flash_resource,
+};
+
+static struct ixp4xx_i2c_pins nslu2_i2c_gpio_pins = {
+ .sda_pin = NSLU2_SDA_PIN,
+ .scl_pin = NSLU2_SCL_PIN,
+};
+
+static struct platform_device nslu2_i2c_controller = {
+ .name = "IXP4XX-I2C",
+ .id = 0,
+ .dev.platform_data = &nslu2_i2c_gpio_pins,
+ .num_resources = 0,
+};
+
+static struct resource nslu2_uart_resources[] = {
+ {
+ .start = IXP4XX_UART1_BASE_PHYS,
+ .end = IXP4XX_UART1_BASE_PHYS + 0x0fff,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IXP4XX_UART2_BASE_PHYS,
+ .end = IXP4XX_UART2_BASE_PHYS + 0x0fff,
+ .flags = IORESOURCE_MEM,
+ }
+};
+
+static struct plat_serial8250_port nslu2_uart_data[] = {
+ {
+ .mapbase = IXP4XX_UART1_BASE_PHYS,
+ .membase = (char *)IXP4XX_UART1_BASE_VIRT + REG_OFFSET,
+ .irq = IRQ_IXP4XX_UART1,
+ .flags = UPF_BOOT_AUTOCONF,
+ .iotype = UPIO_MEM,
+ .regshift = 2,
+ .uartclk = IXP4XX_UART_XTAL,
+ },
+ {
+ .mapbase = IXP4XX_UART2_BASE_PHYS,
+ .membase = (char *)IXP4XX_UART2_BASE_VIRT + REG_OFFSET,
+ .irq = IRQ_IXP4XX_UART2,
+ .flags = UPF_BOOT_AUTOCONF,
+ .iotype = UPIO_MEM,
+ .regshift = 2,
+ .uartclk = IXP4XX_UART_XTAL,
+ },
+ { }
+};
+
+static struct platform_device nslu2_uart = {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM,
+ .dev.platform_data = nslu2_uart_data,
+ .num_resources = 2,
+ .resource = nslu2_uart_resources,
+};
+
+static struct platform_device *nslu2_devices[] __initdata = {
+ &nslu2_i2c_controller,
+ &nslu2_flash,
+ &nslu2_uart,
+};
+
+static void nslu2_power_off(void)
+{
+ /* This causes the box to drop the power and go dead. */
+
+ /* enable the pwr cntl gpio */
+ gpio_line_config(NSLU2_PO_GPIO, IXP4XX_GPIO_OUT);
+
+ /* do the deed */
+ gpio_line_set(NSLU2_PO_GPIO, IXP4XX_GPIO_HIGH);
+}
+
+static void __init nslu2_init(void)
+{
+ ixp4xx_sys_init();
+
+ pm_power_off = nslu2_power_off;
+
+ platform_add_devices(nslu2_devices, ARRAY_SIZE(nslu2_devices));
+}
+
+MACHINE_START(NSLU2, "Linksys NSLU2")
+ /* Maintainer: www.nslu2-linux.org */
+ .phys_ram = PHYS_OFFSET,
+ .phys_io = IXP4XX_PERIPHERAL_BASE_PHYS,
+ .io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xFFFC,
+ .boot_params = 0x00000100,
+ .map_io = ixp4xx_map_io,
+ .init_irq = ixp4xx_init_irq,
+ .timer = &ixp4xx_timer,
+ .init_machine = nslu2_init,
+MACHINE_END
diff --git a/arch/arm/mach-lh7a40x/arch-kev7a400.c b/arch/arm/mach-lh7a40x/arch-kev7a400.c
index cb3dcd3bd00a..19f2fa2244c4 100644
--- a/arch/arm/mach-lh7a40x/arch-kev7a400.c
+++ b/arch/arm/mach-lh7a40x/arch-kev7a400.c
@@ -26,8 +26,17 @@
/* This function calls the board specific IRQ initialization function. */
static struct map_desc kev7a400_io_desc[] __initdata = {
- { IO_VIRT, IO_PHYS, IO_SIZE, MT_DEVICE },
- { CPLD_VIRT, CPLD_PHYS, CPLD_SIZE, MT_DEVICE },
+ {
+ .virtual = IO_VIRT,
+ .pfn = __phys_to_pfn(IO_PHYS),
+ .length = IO_SIZE,
+ .type = MT_DEVICE
+ }, {
+ .virtual = CPLD_VIRT,
+ .pfn = __phys_to_pfn(CPLD_PHYS),
+ .length = CPLD_SIZE,
+ .type = MT_DEVICE
+ }
};
void __init kev7a400_map_io(void)
diff --git a/arch/arm/mach-lh7a40x/arch-lpd7a40x.c b/arch/arm/mach-lh7a40x/arch-lpd7a40x.c
index 6eb61a17c63b..4eb962fdb3a8 100644
--- a/arch/arm/mach-lh7a40x/arch-lpd7a40x.c
+++ b/arch/arm/mach-lh7a40x/arch-lpd7a40x.c
@@ -10,7 +10,7 @@
#include <linux/tty.h>
#include <linux/init.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <linux/interrupt.h>
#include <asm/hardware.h>
@@ -227,23 +227,79 @@ void __init lh7a40x_init_board_irq (void)
}
static struct map_desc lpd7a400_io_desc[] __initdata = {
- { IO_VIRT, IO_PHYS, IO_SIZE, MT_DEVICE },
- /* Mapping added to work around chip select problems */
- { IOBARRIER_VIRT, IOBARRIER_PHYS, IOBARRIER_SIZE, MT_DEVICE },
- { CF_VIRT, CF_PHYS, CF_SIZE, MT_DEVICE },
+ {
+ .virtual = IO_VIRT,
+ .pfn = __phys_to_pfn(IO_PHYS),
+ .length = IO_SIZE,
+ .type = MT_DEVICE
+ }, { /* Mapping added to work around chip select problems */
+ .virtual = IOBARRIER_VIRT,
+ .pfn = __phys_to_pfn(IOBARRIER_PHYS),
+ .length = IOBARRIER_SIZE,
+ .type = MT_DEVICE
+ }, {
+ .virtual = CF_VIRT,
+ .pfn = __phys_to_pfn(CF_PHYS),
+ .length = CF_SIZE,
+ .type = MT_DEVICE
+ }, {
+ .virtual = CPLD02_VIRT,
+ .pfn = __phys_to_pfn(CPLD02_PHYS),
+ .length = CPLD02_SIZE,
+ .type = MT_DEVICE
+ }, {
+ .virtual = CPLD06_VIRT,
+ .pfn = __phys_to_pfn(CPLD06_PHYS),
+ .length = CPLD06_SIZE,
+ .type = MT_DEVICE
+ }, {
+ .virtual = CPLD08_VIRT,
+ .pfn = __phys_to_pfn(CPLD08_PHYS),
+ .length = CPLD08_SIZE,
+ .type = MT_DEVICE
+ }, {
+ .virtual = CPLD0C_VIRT,
+ .pfn = __phys_to_pfn(CPLD0C_PHYS),
+ .length = CPLD0C_SIZE,
+ .type = MT_DEVICE
+ }, {
+ .virtual = CPLD0E_VIRT,
+ .pfn = __phys_to_pfn(CPLD0E_PHYS),
+ .length = CPLD0E_SIZE,
+ .type = MT_DEVICE
+ }, {
+ .virtual = CPLD10_VIRT,
+ .pfn = __phys_to_pfn(CPLD10_PHYS),
+ .length = CPLD10_SIZE,
+ .type = MT_DEVICE
+ }, {
+ .virtual = CPLD12_VIRT,
+ .pfn = __phys_to_pfn(CPLD12_PHYS),
+ .length = CPLD12_SIZE,
+ .type = MT_DEVICE
+ }, {
+ .virtual = CPLD14_VIRT,
+ .pfn = __phys_to_pfn(CPLD14_PHYS),
+ .length = CPLD14_SIZE,
+ .type = MT_DEVICE
+ }, {
+ .virtual = CPLD16_VIRT,
+ .pfn = __phys_to_pfn(CPLD16_PHYS),
+ .length = CPLD16_SIZE,
+ .type = MT_DEVICE
+ }, {
+ .virtual = CPLD18_VIRT,
+ .pfn = __phys_to_pfn(CPLD18_PHYS),
+ .length = CPLD18_SIZE,
+ .type = MT_DEVICE
+ }, {
+ .virtual = CPLD1A_VIRT,
+ .pfn = __phys_to_pfn(CPLD1A_PHYS),
+ .length = CPLD1A_SIZE,
+ .type = MT_DEVICE
+ },
/* This mapping is redundant since the smc driver performs another. */
/* { CPLD00_VIRT, CPLD00_PHYS, CPLD00_SIZE, MT_DEVICE }, */
- { CPLD02_VIRT, CPLD02_PHYS, CPLD02_SIZE, MT_DEVICE },
- { CPLD06_VIRT, CPLD06_PHYS, CPLD06_SIZE, MT_DEVICE },
- { CPLD08_VIRT, CPLD08_PHYS, CPLD08_SIZE, MT_DEVICE },
- { CPLD0C_VIRT, CPLD0C_PHYS, CPLD0C_SIZE, MT_DEVICE },
- { CPLD0E_VIRT, CPLD0E_PHYS, CPLD0E_SIZE, MT_DEVICE },
- { CPLD10_VIRT, CPLD10_PHYS, CPLD10_SIZE, MT_DEVICE },
- { CPLD12_VIRT, CPLD12_PHYS, CPLD12_SIZE, MT_DEVICE },
- { CPLD14_VIRT, CPLD14_PHYS, CPLD14_SIZE, MT_DEVICE },
- { CPLD16_VIRT, CPLD16_PHYS, CPLD16_SIZE, MT_DEVICE },
- { CPLD18_VIRT, CPLD18_PHYS, CPLD18_SIZE, MT_DEVICE },
- { CPLD1A_VIRT, CPLD1A_PHYS, CPLD1A_SIZE, MT_DEVICE },
};
void __init
diff --git a/arch/arm/mach-omap1/Kconfig b/arch/arm/mach-omap1/Kconfig
index 27fc2e8e5fca..86a0f0d14345 100644
--- a/arch/arm/mach-omap1/Kconfig
+++ b/arch/arm/mach-omap1/Kconfig
@@ -6,10 +6,10 @@ config ARCH_OMAP730
bool "OMAP730 Based System"
select ARCH_OMAP_OTG
-config ARCH_OMAP1510
+config ARCH_OMAP15XX
depends on ARCH_OMAP1
default y
- bool "OMAP1510 Based System"
+ bool "OMAP15xx Based System"
config ARCH_OMAP16XX
depends on ARCH_OMAP1
@@ -21,7 +21,7 @@ comment "OMAP Board Type"
config MACH_OMAP_INNOVATOR
bool "TI Innovator"
- depends on ARCH_OMAP1 && (ARCH_OMAP1510 || ARCH_OMAP16XX)
+ depends on ARCH_OMAP1 && (ARCH_OMAP15XX || ARCH_OMAP16XX)
help
TI OMAP 1510 or 1610 Innovator board support. Say Y here if you
have such a board.
@@ -64,20 +64,30 @@ config MACH_OMAP_PERSEUS2
config MACH_VOICEBLUE
bool "Voiceblue"
- depends on ARCH_OMAP1 && ARCH_OMAP1510
+ depends on ARCH_OMAP1 && ARCH_OMAP15XX
help
Support for Voiceblue GSM/VoIP gateway. Say Y here if you have
such a board.
config MACH_NETSTAR
bool "NetStar"
- depends on ARCH_OMAP1 && ARCH_OMAP1510
+ depends on ARCH_OMAP1 && ARCH_OMAP15XX
help
Support for NetStar PBX. Say Y here if you have such a board.
+config MACH_OMAP_PALMTE
+ bool "Palm Tungsten E"
+ depends on ARCH_OMAP1 && ARCH_OMAP15XX
+ help
+ Support for the Palm Tungsten E PDA. Currently only the LCD panel
+ is supported. To boot the kernel, you'll need a PalmOS compatible
+ bootloader; check out http://palmtelinux.sourceforge.net for more
+ informations.
+ Say Y here if you have such a PDA, say NO otherwise.
+
config MACH_OMAP_GENERIC
bool "Generic OMAP board"
- depends on ARCH_OMAP1 && (ARCH_OMAP1510 || ARCH_OMAP16XX)
+ depends on ARCH_OMAP1 && (ARCH_OMAP15XX || ARCH_OMAP16XX)
help
Support for generic OMAP-1510, 1610 or 1710 board with
no FPGA. Can be used as template for porting Linux to
@@ -121,32 +131,32 @@ config OMAP_ARM_182MHZ
config OMAP_ARM_168MHZ
bool "OMAP ARM 168 MHz CPU"
- depends on ARCH_OMAP1 && (ARCH_OMAP1510 || ARCH_OMAP16XX || ARCH_OMAP730)
+ depends on ARCH_OMAP1 && (ARCH_OMAP15XX || ARCH_OMAP16XX || ARCH_OMAP730)
help
Enable 168MHz clock for OMAP CPU. If unsure, say N.
config OMAP_ARM_150MHZ
bool "OMAP ARM 150 MHz CPU"
- depends on ARCH_OMAP1 && ARCH_OMAP1510
+ depends on ARCH_OMAP1 && ARCH_OMAP15XX
help
Enable 150MHz clock for OMAP CPU. If unsure, say N.
config OMAP_ARM_120MHZ
bool "OMAP ARM 120 MHz CPU"
- depends on ARCH_OMAP1 && (ARCH_OMAP1510 || ARCH_OMAP16XX || ARCH_OMAP730)
+ depends on ARCH_OMAP1 && (ARCH_OMAP15XX || ARCH_OMAP16XX || ARCH_OMAP730)
help
Enable 120MHz clock for OMAP CPU. If unsure, say N.
config OMAP_ARM_60MHZ
bool "OMAP ARM 60 MHz CPU"
- depends on ARCH_OMAP1 && (ARCH_OMAP1510 || ARCH_OMAP16XX || ARCH_OMAP730)
+ depends on ARCH_OMAP1 && (ARCH_OMAP15XX || ARCH_OMAP16XX || ARCH_OMAP730)
default y
help
Enable 60MHz clock for OMAP CPU. If unsure, say Y.
config OMAP_ARM_30MHZ
bool "OMAP ARM 30 MHz CPU"
- depends on ARCH_OMAP1 && (ARCH_OMAP1510 || ARCH_OMAP16XX || ARCH_OMAP730)
+ depends on ARCH_OMAP1 && (ARCH_OMAP15XX || ARCH_OMAP16XX || ARCH_OMAP730)
help
Enable 30MHz clock for OMAP CPU. If unsure, say N.
diff --git a/arch/arm/mach-omap1/Makefile b/arch/arm/mach-omap1/Makefile
index 181a93deaaee..b0b00156faae 100644
--- a/arch/arm/mach-omap1/Makefile
+++ b/arch/arm/mach-omap1/Makefile
@@ -3,7 +3,7 @@
#
# Common support
-obj-y := io.o id.o irq.o time.o serial.o devices.o
+obj-y := io.o id.o clock.o irq.o time.o mux.o serial.o devices.o
led-y := leds.o
# Specific board support
@@ -15,8 +15,9 @@ obj-$(CONFIG_MACH_OMAP_OSK) += board-osk.o
obj-$(CONFIG_MACH_OMAP_H3) += board-h3.o
obj-$(CONFIG_MACH_VOICEBLUE) += board-voiceblue.o
obj-$(CONFIG_MACH_NETSTAR) += board-netstar.o
+obj-$(CONFIG_MACH_OMAP_PALMTE) += board-palmte.o
-ifeq ($(CONFIG_ARCH_OMAP1510),y)
+ifeq ($(CONFIG_ARCH_OMAP15XX),y)
# Innovator-1510 FPGA
obj-$(CONFIG_MACH_OMAP_INNOVATOR) += fpga.o
endif
diff --git a/arch/arm/mach-omap1/board-generic.c b/arch/arm/mach-omap1/board-generic.c
index c209c7172a9a..4b292e93fbe2 100644
--- a/arch/arm/mach-omap1/board-generic.c
+++ b/arch/arm/mach-omap1/board-generic.c
@@ -15,7 +15,7 @@
#include <linux/kernel.h>
#include <linux/init.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <asm/hardware.h>
#include <asm/mach-types.h>
@@ -28,8 +28,6 @@
#include <asm/arch/board.h>
#include <asm/arch/common.h>
-static int __initdata generic_serial_ports[OMAP_MAX_NR_PORTS] = {1, 1, 1};
-
static void __init omap_generic_init_irq(void)
{
omap_init_irq();
@@ -37,7 +35,7 @@ static void __init omap_generic_init_irq(void)
/* assume no Mini-AB port */
-#ifdef CONFIG_ARCH_OMAP1510
+#ifdef CONFIG_ARCH_OMAP15XX
static struct omap_usb_config generic1510_usb_config __initdata = {
.register_host = 1,
.register_dev = 1,
@@ -76,21 +74,19 @@ static struct omap_mmc_config generic_mmc_config __initdata = {
#endif
+static struct omap_uart_config generic_uart_config __initdata = {
+ .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)),
+};
+
static struct omap_board_config_kernel generic_config[] = {
{ OMAP_TAG_USB, NULL },
{ OMAP_TAG_MMC, &generic_mmc_config },
+ { OMAP_TAG_UART, &generic_uart_config },
};
static void __init omap_generic_init(void)
{
- const struct omap_uart_config *uart_conf;
-
- /*
- * Make sure the serial ports are muxed on at this point.
- * You have to mux them off in device drivers later on
- * if not needed.
- */
-#ifdef CONFIG_ARCH_OMAP1510
+#ifdef CONFIG_ARCH_OMAP15XX
if (cpu_is_omap1510()) {
generic_config[0].data = &generic1510_usb_config;
}
@@ -101,20 +97,9 @@ static void __init omap_generic_init(void)
}
#endif
- uart_conf = omap_get_config(OMAP_TAG_UART, struct omap_uart_config);
- if (uart_conf != NULL) {
- unsigned int enabled_ports, i;
-
- enabled_ports = uart_conf->enabled_uarts;
- for (i = 0; i < 3; i++) {
- if (!(enabled_ports & (1 << i)))
- generic_serial_ports[i] = 0;
- }
- }
-
omap_board_config = generic_config;
omap_board_config_size = ARRAY_SIZE(generic_config);
- omap_serial_init(generic_serial_ports);
+ omap_serial_init();
}
static void __init omap_generic_map_io(void)
diff --git a/arch/arm/mach-omap1/board-h2.c b/arch/arm/mach-omap1/board-h2.c
index d46a70063b0c..a07e2c9307fa 100644
--- a/arch/arm/mach-omap1/board-h2.c
+++ b/arch/arm/mach-omap1/board-h2.c
@@ -21,7 +21,7 @@
#include <linux/kernel.h>
#include <linux/init.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <linux/delay.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
@@ -40,8 +40,6 @@
extern int omap_gpio_init(void);
-static int __initdata h2_serial_ports[OMAP_MAX_NR_PORTS] = {1, 1, 1};
-
static struct mtd_partition h2_partitions[] = {
/* bootloader (U-Boot, etc) in first sector */
{
@@ -160,9 +158,20 @@ static struct omap_mmc_config h2_mmc_config __initdata = {
},
};
+static struct omap_uart_config h2_uart_config __initdata = {
+ .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)),
+};
+
+static struct omap_lcd_config h2_lcd_config __initdata = {
+ .panel_name = "h2",
+ .ctrl_name = "internal",
+};
+
static struct omap_board_config_kernel h2_config[] = {
{ OMAP_TAG_USB, &h2_usb_config },
{ OMAP_TAG_MMC, &h2_mmc_config },
+ { OMAP_TAG_UART, &h2_uart_config },
+ { OMAP_TAG_LCD, &h2_lcd_config },
};
static void __init h2_init(void)
@@ -180,12 +189,12 @@ static void __init h2_init(void)
platform_add_devices(h2_devices, ARRAY_SIZE(h2_devices));
omap_board_config = h2_config;
omap_board_config_size = ARRAY_SIZE(h2_config);
+ omap_serial_init();
}
static void __init h2_map_io(void)
{
omap_map_common_io();
- omap_serial_init(h2_serial_ports);
}
MACHINE_START(OMAP_H2, "TI-H2")
diff --git a/arch/arm/mach-omap1/board-h3.c b/arch/arm/mach-omap1/board-h3.c
index 2798613696fa..668e278433c2 100644
--- a/arch/arm/mach-omap1/board-h3.c
+++ b/arch/arm/mach-omap1/board-h3.c
@@ -19,7 +19,7 @@
#include <linux/init.h>
#include <linux/major.h>
#include <linux/kernel.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <linux/errno.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
@@ -41,8 +41,6 @@
extern int omap_gpio_init(void);
-static int __initdata h3_serial_ports[OMAP_MAX_NR_PORTS] = {1, 1, 1};
-
static struct mtd_partition h3_partitions[] = {
/* bootloader (U-Boot, etc) in first sector */
{
@@ -168,9 +166,20 @@ static struct omap_mmc_config h3_mmc_config __initdata = {
},
};
+static struct omap_uart_config h3_uart_config __initdata = {
+ .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)),
+};
+
+static struct omap_lcd_config h3_lcd_config __initdata = {
+ .panel_name = "h3",
+ .ctrl_name = "internal",
+};
+
static struct omap_board_config_kernel h3_config[] = {
- { OMAP_TAG_USB, &h3_usb_config },
- { OMAP_TAG_MMC, &h3_mmc_config },
+ { OMAP_TAG_USB, &h3_usb_config },
+ { OMAP_TAG_MMC, &h3_mmc_config },
+ { OMAP_TAG_UART, &h3_uart_config },
+ { OMAP_TAG_LCD, &h3_lcd_config },
};
static void __init h3_init(void)
@@ -180,6 +189,7 @@ static void __init h3_init(void)
(void) platform_add_devices(devices, ARRAY_SIZE(devices));
omap_board_config = h3_config;
omap_board_config_size = ARRAY_SIZE(h3_config);
+ omap_serial_init();
}
static void __init h3_init_smc91x(void)
@@ -201,7 +211,6 @@ void h3_init_irq(void)
static void __init h3_map_io(void)
{
omap_map_common_io();
- omap_serial_init(h3_serial_ports);
}
MACHINE_START(OMAP_H3, "TI OMAP1710 H3 board")
diff --git a/arch/arm/mach-omap1/board-innovator.c b/arch/arm/mach-omap1/board-innovator.c
index df0312b596e4..95f1ff36cdcb 100644
--- a/arch/arm/mach-omap1/board-innovator.c
+++ b/arch/arm/mach-omap1/board-innovator.c
@@ -18,7 +18,7 @@
#include <linux/kernel.h>
#include <linux/init.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <linux/delay.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
@@ -36,8 +36,6 @@
#include <asm/arch/usb.h>
#include <asm/arch/common.h>
-static int __initdata innovator_serial_ports[OMAP_MAX_NR_PORTS] = {1, 1, 1};
-
static struct mtd_partition innovator_partitions[] = {
/* bootloader (U-Boot, etc) in first sector */
{
@@ -99,12 +97,16 @@ static struct platform_device innovator_flash_device = {
.resource = &innovator_flash_resource,
};
-#ifdef CONFIG_ARCH_OMAP1510
+#ifdef CONFIG_ARCH_OMAP15XX
/* Only FPGA needs to be mapped here. All others are done with ioremap */
static struct map_desc innovator1510_io_desc[] __initdata = {
-{ OMAP1510_FPGA_BASE, OMAP1510_FPGA_START, OMAP1510_FPGA_SIZE,
- MT_DEVICE },
+ {
+ .virtual = OMAP1510_FPGA_BASE,
+ .pfn = __phys_to_pfn(OMAP1510_FPGA_START),
+ .length = OMAP1510_FPGA_SIZE,
+ .type = MT_DEVICE
+ }
};
static struct resource innovator1510_smc91x_resources[] = {
@@ -132,7 +134,7 @@ static struct platform_device *innovator1510_devices[] __initdata = {
&innovator1510_smc91x_device,
};
-#endif /* CONFIG_ARCH_OMAP1510 */
+#endif /* CONFIG_ARCH_OMAP15XX */
#ifdef CONFIG_ARCH_OMAP16XX
@@ -181,7 +183,7 @@ void innovator_init_irq(void)
{
omap_init_irq();
omap_gpio_init();
-#ifdef CONFIG_ARCH_OMAP1510
+#ifdef CONFIG_ARCH_OMAP15XX
if (cpu_is_omap1510()) {
omap1510_fpga_init_irq();
}
@@ -189,7 +191,7 @@ void innovator_init_irq(void)
innovator_init_smc91x();
}
-#ifdef CONFIG_ARCH_OMAP1510
+#ifdef CONFIG_ARCH_OMAP15XX
static struct omap_usb_config innovator1510_usb_config __initdata = {
/* for bundled non-standard host and peripheral cables */
.hmc_mode = 4,
@@ -201,6 +203,11 @@ static struct omap_usb_config innovator1510_usb_config __initdata = {
.register_dev = 1,
.pins[0] = 2,
};
+
+static struct omap_lcd_config innovator1510_lcd_config __initdata = {
+ .panel_name = "inn1510",
+ .ctrl_name = "internal",
+};
#endif
#ifdef CONFIG_ARCH_OMAP16XX
@@ -218,6 +225,11 @@ static struct omap_usb_config h2_usb_config __initdata = {
.pins[1] = 3,
};
+
+static struct omap_lcd_config innovator1610_lcd_config __initdata = {
+ .panel_name = "inn1610",
+ .ctrl_name = "internal",
+};
#endif
static struct omap_mmc_config innovator_mmc_config __initdata = {
@@ -230,14 +242,20 @@ static struct omap_mmc_config innovator_mmc_config __initdata = {
},
};
+static struct omap_uart_config innovator_uart_config __initdata = {
+ .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)),
+};
+
static struct omap_board_config_kernel innovator_config[] = {
{ OMAP_TAG_USB, NULL },
+ { OMAP_TAG_LCD, NULL },
{ OMAP_TAG_MMC, &innovator_mmc_config },
+ { OMAP_TAG_UART, &innovator_uart_config },
};
static void __init innovator_init(void)
{
-#ifdef CONFIG_ARCH_OMAP1510
+#ifdef CONFIG_ARCH_OMAP15XX
if (cpu_is_omap1510()) {
platform_add_devices(innovator1510_devices, ARRAY_SIZE(innovator1510_devices));
}
@@ -248,23 +266,28 @@ static void __init innovator_init(void)
}
#endif
-#ifdef CONFIG_ARCH_OMAP1510
- if (cpu_is_omap1510())
+#ifdef CONFIG_ARCH_OMAP15XX
+ if (cpu_is_omap1510()) {
innovator_config[0].data = &innovator1510_usb_config;
+ innovator_config[1].data = &innovator1510_lcd_config;
+ }
#endif
#ifdef CONFIG_ARCH_OMAP16XX
- if (cpu_is_omap1610())
+ if (cpu_is_omap1610()) {
innovator_config[0].data = &h2_usb_config;
+ innovator_config[1].data = &innovator1610_lcd_config;
+ }
#endif
omap_board_config = innovator_config;
omap_board_config_size = ARRAY_SIZE(innovator_config);
+ omap_serial_init();
}
static void __init innovator_map_io(void)
{
omap_map_common_io();
-#ifdef CONFIG_ARCH_OMAP1510
+#ifdef CONFIG_ARCH_OMAP15XX
if (cpu_is_omap1510()) {
iotable_init(innovator1510_io_desc, ARRAY_SIZE(innovator1510_io_desc));
udelay(10); /* Delay needed for FPGA */
@@ -276,7 +299,6 @@ static void __init innovator_map_io(void)
fpga_read(OMAP1510_FPGA_BOARD_REV));
}
#endif
- omap_serial_init(innovator_serial_ports);
}
MACHINE_START(OMAP_INNOVATOR, "TI-Innovator")
diff --git a/arch/arm/mach-omap1/board-netstar.c b/arch/arm/mach-omap1/board-netstar.c
index d904e643f5ec..0448fa7de8a4 100644
--- a/arch/arm/mach-omap1/board-netstar.c
+++ b/arch/arm/mach-omap1/board-netstar.c
@@ -11,7 +11,7 @@
*/
#include <linux/delay.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/kernel.h>
@@ -55,6 +55,14 @@ static struct platform_device *netstar_devices[] __initdata = {
&netstar_smc91x_device,
};
+static struct omap_uart_config netstar_uart_config __initdata = {
+ .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)),
+};
+
+static struct omap_board_config_kernel netstar_config[] = {
+ { OMAP_TAG_UART, &netstar_uart_config },
+};
+
static void __init netstar_init_irq(void)
{
omap_init_irq();
@@ -92,14 +100,15 @@ static void __init netstar_init(void)
/* Switch off red LED */
omap_writeb(0x00, OMAP_LPG1_PMR); /* Disable clock */
omap_writeb(0x80, OMAP_LPG1_LCR);
-}
-static int __initdata omap_serial_ports[OMAP_MAX_NR_PORTS] = {1, 1, 1};
+ omap_board_config = netstar_config;
+ omap_board_config_size = ARRAY_SIZE(netstar_config);
+ omap_serial_init();
+}
static void __init netstar_map_io(void)
{
omap_map_common_io();
- omap_serial_init(omap_serial_ports);
}
#define MACHINE_PANICED 1
diff --git a/arch/arm/mach-omap1/board-osk.c b/arch/arm/mach-omap1/board-osk.c
index 21103df50415..e990e1bc1669 100644
--- a/arch/arm/mach-omap1/board-osk.c
+++ b/arch/arm/mach-omap1/board-osk.c
@@ -28,7 +28,7 @@
#include <linux/kernel.h>
#include <linux/init.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <linux/interrupt.h>
#include <linux/mtd/mtd.h>
@@ -46,8 +46,6 @@
#include <asm/arch/tc.h>
#include <asm/arch/common.h>
-static int __initdata osk_serial_ports[OMAP_MAX_NR_PORTS] = {1, 0, 0};
-
static struct mtd_partition osk_partitions[] = {
/* bootloader (U-Boot, etc) in first sector */
{
@@ -155,7 +153,7 @@ static void __init osk_init_smc91x(void)
}
/* Check EMIFS wait states to fix errors with SMC_GET_PKT_HDR */
- EMIFS_CCS(1) |= 0x2;
+ EMIFS_CCS(1) |= 0x3;
}
static void __init osk_init_cf(void)
@@ -193,8 +191,19 @@ static struct omap_usb_config osk_usb_config __initdata = {
.pins[0] = 2,
};
+static struct omap_uart_config osk_uart_config __initdata = {
+ .enabled_uarts = (1 << 0),
+};
+
+static struct omap_lcd_config osk_lcd_config __initdata = {
+ .panel_name = "osk",
+ .ctrl_name = "internal",
+};
+
static struct omap_board_config_kernel osk_config[] = {
{ OMAP_TAG_USB, &osk_usb_config },
+ { OMAP_TAG_UART, &osk_uart_config },
+ { OMAP_TAG_LCD, &osk_lcd_config },
};
#ifdef CONFIG_OMAP_OSK_MISTRAL
@@ -254,13 +263,13 @@ static void __init osk_init(void)
omap_board_config_size = ARRAY_SIZE(osk_config);
USB_TRANSCEIVER_CTRL_REG |= (3 << 1);
+ omap_serial_init();
osk_mistral_init();
}
static void __init osk_map_io(void)
{
omap_map_common_io();
- omap_serial_init(osk_serial_ports);
}
MACHINE_START(OMAP_OSK, "TI-OSK")
diff --git a/arch/arm/mach-omap1/board-palmte.c b/arch/arm/mach-omap1/board-palmte.c
new file mode 100644
index 000000000000..540b20d78cca
--- /dev/null
+++ b/arch/arm/mach-omap1/board-palmte.c
@@ -0,0 +1,87 @@
+/*
+ * linux/arch/arm/mach-omap1/board-palmte.c
+ *
+ * Modified from board-generic.c
+ *
+ * Support for the Palm Tungsten E PDA.
+ *
+ * Original version : Laurent Gonzalez
+ *
+ * Maintainters : http://palmtelinux.sf.net
+ * palmtelinux-developpers@lists.sf.net
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/notifier.h>
+
+#include <asm/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <asm/arch/gpio.h>
+#include <asm/arch/mux.h>
+#include <asm/arch/usb.h>
+#include <asm/arch/board.h>
+#include <asm/arch/common.h>
+#include <asm/hardware/clock.h>
+
+static void __init omap_generic_init_irq(void)
+{
+ omap_init_irq();
+}
+
+static struct omap_usb_config palmte_usb_config __initdata = {
+ .register_dev = 1,
+ .hmc_mode = 0,
+ .pins[0] = 3,
+};
+
+static struct omap_mmc_config palmte_mmc_config __initdata = {
+ .mmc [0] = {
+ .enabled = 1,
+ .wire4 = 1,
+ .wp_pin = OMAP_MPUIO(3),
+ .power_pin = -1,
+ .switch_pin = -1,
+ },
+};
+
+static struct omap_lcd_config palmte_lcd_config __initdata = {
+ .panel_name = "palmte",
+ .ctrl_name = "internal",
+};
+
+static struct omap_board_config_kernel palmte_config[] = {
+ { OMAP_TAG_USB, &palmte_usb_config },
+ { OMAP_TAG_MMC, &palmte_mmc_config },
+ { OMAP_TAG_LCD, &palmte_lcd_config },
+};
+
+static void __init omap_generic_init(void)
+{
+ omap_board_config = palmte_config;
+ omap_board_config_size = ARRAY_SIZE(palmte_config);
+}
+
+static void __init omap_generic_map_io(void)
+{
+ omap_map_common_io();
+}
+
+MACHINE_START(OMAP_PALMTE, "OMAP310 based Palm Tungsten E")
+ .phys_ram = 0x10000000,
+ .phys_io = 0xfff00000,
+ .io_pg_offst = ((0xfef00000) >> 18) & 0xfffc,
+ .boot_params = 0x10000100,
+ .map_io = omap_generic_map_io,
+ .init_irq = omap_generic_init_irq,
+ .init_machine = omap_generic_init,
+ .timer = &omap_timer,
+MACHINE_END
diff --git a/arch/arm/mach-omap1/board-perseus2.c b/arch/arm/mach-omap1/board-perseus2.c
index 107c68c8ab54..bd900b7ab33c 100644
--- a/arch/arm/mach-omap1/board-perseus2.c
+++ b/arch/arm/mach-omap1/board-perseus2.c
@@ -13,7 +13,7 @@
#include <linux/kernel.h>
#include <linux/init.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <linux/delay.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
@@ -29,6 +29,7 @@
#include <asm/arch/mux.h>
#include <asm/arch/fpga.h>
#include <asm/arch/common.h>
+#include <asm/arch/board.h>
static struct resource smc91x_resources[] = {
[0] = {
@@ -43,8 +44,6 @@ static struct resource smc91x_resources[] = {
},
};
-static int __initdata p2_serial_ports[OMAP_MAX_NR_PORTS] = {1, 1, 0};
-
static struct mtd_partition p2_partitions[] = {
/* bootloader (U-Boot, etc) in first sector */
{
@@ -111,9 +110,27 @@ static struct platform_device *devices[] __initdata = {
&smc91x_device,
};
+static struct omap_uart_config perseus2_uart_config __initdata = {
+ .enabled_uarts = ((1 << 0) | (1 << 1)),
+};
+
+static struct omap_lcd_config perseus2_lcd_config __initdata = {
+ .panel_name = "p2",
+ .ctrl_name = "internal",
+};
+
+static struct omap_board_config_kernel perseus2_config[] = {
+ { OMAP_TAG_UART, &perseus2_uart_config },
+ { OMAP_TAG_LCD, &perseus2_lcd_config },
+};
+
static void __init omap_perseus2_init(void)
{
(void) platform_add_devices(devices, ARRAY_SIZE(devices));
+
+ omap_board_config = perseus2_config;
+ omap_board_config_size = ARRAY_SIZE(perseus2_config);
+ omap_serial_init();
}
static void __init perseus2_init_smc91x(void)
@@ -131,11 +148,14 @@ void omap_perseus2_init_irq(void)
omap_gpio_init();
perseus2_init_smc91x();
}
-
/* Only FPGA needs to be mapped here. All others are done with ioremap */
static struct map_desc omap_perseus2_io_desc[] __initdata = {
- {H2P2_DBG_FPGA_BASE, H2P2_DBG_FPGA_START, H2P2_DBG_FPGA_SIZE,
- MT_DEVICE},
+ {
+ .virtual = H2P2_DBG_FPGA_BASE,
+ .pfn = __phys_to_pfn(H2P2_DBG_FPGA_START),
+ .length = H2P2_DBG_FPGA_SIZE,
+ .type = MT_DEVICE
+ }
};
static void __init omap_perseus2_map_io(void)
@@ -175,7 +195,6 @@ static void __init omap_perseus2_map_io(void)
* It is used as the Ethernet controller interrupt
*/
omap_writel(omap_readl(OMAP730_IO_CONF_9) & 0x1FFFFFFF, OMAP730_IO_CONF_9);
- omap_serial_init(p2_serial_ports);
}
MACHINE_START(OMAP_PERSEUS2, "OMAP730 Perseus2")
diff --git a/arch/arm/mach-omap1/board-voiceblue.c b/arch/arm/mach-omap1/board-voiceblue.c
index bf30b1acda0b..6f9a6220e78a 100644
--- a/arch/arm/mach-omap1/board-voiceblue.c
+++ b/arch/arm/mach-omap1/board-voiceblue.c
@@ -13,7 +13,7 @@
*/
#include <linux/delay.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/kernel.h>
@@ -150,9 +150,14 @@ static struct omap_mmc_config voiceblue_mmc_config __initdata = {
},
};
+static struct omap_uart_config voiceblue_uart_config __initdata = {
+ .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)),
+};
+
static struct omap_board_config_kernel voiceblue_config[] = {
{ OMAP_TAG_USB, &voiceblue_usb_config },
{ OMAP_TAG_MMC, &voiceblue_mmc_config },
+ { OMAP_TAG_UART, &voiceblue_uart_config },
};
static void __init voiceblue_init_irq(void)
@@ -191,6 +196,7 @@ static void __init voiceblue_init(void)
platform_add_devices(voiceblue_devices, ARRAY_SIZE(voiceblue_devices));
omap_board_config = voiceblue_config;
omap_board_config_size = ARRAY_SIZE(voiceblue_config);
+ omap_serial_init();
/* There is a good chance board is going up, so enable power LED
* (it is connected through invertor) */
@@ -198,12 +204,9 @@ static void __init voiceblue_init(void)
omap_writeb(0x00, OMAP_LPG1_PMR); /* Disable clock */
}
-static int __initdata omap_serial_ports[OMAP_MAX_NR_PORTS] = {1, 1, 1};
-
static void __init voiceblue_map_io(void)
{
omap_map_common_io();
- omap_serial_init(omap_serial_ports);
}
#define MACHINE_PANICED 1
diff --git a/arch/arm/mach-omap1/clock.c b/arch/arm/mach-omap1/clock.c
new file mode 100644
index 000000000000..4277eee44ed5
--- /dev/null
+++ b/arch/arm/mach-omap1/clock.c
@@ -0,0 +1,792 @@
+/*
+ * linux/arch/arm/mach-omap1/clock.c
+ *
+ * Copyright (C) 2004 - 2005 Nokia corporation
+ * Written by Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>
+ *
+ * Modified to use omap shared clock framework by
+ * Tony Lindgren <tony@atomide.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/kernel.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+
+#include <asm/io.h>
+#include <asm/hardware/clock.h>
+
+#include <asm/arch/usb.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/sram.h>
+
+#include "clock.h"
+
+__u32 arm_idlect1_mask;
+
+/*-------------------------------------------------------------------------
+ * Omap1 specific clock functions
+ *-------------------------------------------------------------------------*/
+
+static void omap1_watchdog_recalc(struct clk * clk)
+{
+ clk->rate = clk->parent->rate / 14;
+}
+
+static void omap1_uart_recalc(struct clk * clk)
+{
+ unsigned int val = omap_readl(clk->enable_reg);
+ if (val & clk->enable_bit)
+ clk->rate = 48000000;
+ else
+ clk->rate = 12000000;
+}
+
+static int omap1_clk_enable_dsp_domain(struct clk *clk)
+{
+ int retval;
+
+ retval = omap1_clk_use(&api_ck.clk);
+ if (!retval) {
+ retval = omap1_clk_enable(clk);
+ omap1_clk_unuse(&api_ck.clk);
+ }
+
+ return retval;
+}
+
+static void omap1_clk_disable_dsp_domain(struct clk *clk)
+{
+ if (omap1_clk_use(&api_ck.clk) == 0) {
+ omap1_clk_disable(clk);
+ omap1_clk_unuse(&api_ck.clk);
+ }
+}
+
+static int omap1_clk_enable_uart_functional(struct clk *clk)
+{
+ int ret;
+ struct uart_clk *uclk;
+
+ ret = omap1_clk_enable(clk);
+ if (ret == 0) {
+ /* Set smart idle acknowledgement mode */
+ uclk = (struct uart_clk *)clk;
+ omap_writeb((omap_readb(uclk->sysc_addr) & ~0x10) | 8,
+ uclk->sysc_addr);
+ }
+
+ return ret;
+}
+
+static void omap1_clk_disable_uart_functional(struct clk *clk)
+{
+ struct uart_clk *uclk;
+
+ /* Set force idle acknowledgement mode */
+ uclk = (struct uart_clk *)clk;
+ omap_writeb((omap_readb(uclk->sysc_addr) & ~0x18), uclk->sysc_addr);
+
+ omap1_clk_disable(clk);
+}
+
+static void omap1_clk_allow_idle(struct clk *clk)
+{
+ struct arm_idlect1_clk * iclk = (struct arm_idlect1_clk *)clk;
+
+ if (!(clk->flags & CLOCK_IDLE_CONTROL))
+ return;
+
+ if (iclk->no_idle_count > 0 && !(--iclk->no_idle_count))
+ arm_idlect1_mask |= 1 << iclk->idlect_shift;
+}
+
+static void omap1_clk_deny_idle(struct clk *clk)
+{
+ struct arm_idlect1_clk * iclk = (struct arm_idlect1_clk *)clk;
+
+ if (!(clk->flags & CLOCK_IDLE_CONTROL))
+ return;
+
+ if (iclk->no_idle_count++ == 0)
+ arm_idlect1_mask &= ~(1 << iclk->idlect_shift);
+}
+
+static __u16 verify_ckctl_value(__u16 newval)
+{
+ /* This function checks for following limitations set
+ * by the hardware (all conditions must be true):
+ * DSPMMU_CK == DSP_CK or DSPMMU_CK == DSP_CK/2
+ * ARM_CK >= TC_CK
+ * DSP_CK >= TC_CK
+ * DSPMMU_CK >= TC_CK
+ *
+ * In addition following rules are enforced:
+ * LCD_CK <= TC_CK
+ * ARMPER_CK <= TC_CK
+ *
+ * However, maximum frequencies are not checked for!
+ */
+ __u8 per_exp;
+ __u8 lcd_exp;
+ __u8 arm_exp;
+ __u8 dsp_exp;
+ __u8 tc_exp;
+ __u8 dspmmu_exp;
+
+ per_exp = (newval >> CKCTL_PERDIV_OFFSET) & 3;
+ lcd_exp = (newval >> CKCTL_LCDDIV_OFFSET) & 3;
+ arm_exp = (newval >> CKCTL_ARMDIV_OFFSET) & 3;
+ dsp_exp = (newval >> CKCTL_DSPDIV_OFFSET) & 3;
+ tc_exp = (newval >> CKCTL_TCDIV_OFFSET) & 3;
+ dspmmu_exp = (newval >> CKCTL_DSPMMUDIV_OFFSET) & 3;
+
+ if (dspmmu_exp < dsp_exp)
+ dspmmu_exp = dsp_exp;
+ if (dspmmu_exp > dsp_exp+1)
+ dspmmu_exp = dsp_exp+1;
+ if (tc_exp < arm_exp)
+ tc_exp = arm_exp;
+ if (tc_exp < dspmmu_exp)
+ tc_exp = dspmmu_exp;
+ if (tc_exp > lcd_exp)
+ lcd_exp = tc_exp;
+ if (tc_exp > per_exp)
+ per_exp = tc_exp;
+
+ newval &= 0xf000;
+ newval |= per_exp << CKCTL_PERDIV_OFFSET;
+ newval |= lcd_exp << CKCTL_LCDDIV_OFFSET;
+ newval |= arm_exp << CKCTL_ARMDIV_OFFSET;
+ newval |= dsp_exp << CKCTL_DSPDIV_OFFSET;
+ newval |= tc_exp << CKCTL_TCDIV_OFFSET;
+ newval |= dspmmu_exp << CKCTL_DSPMMUDIV_OFFSET;
+
+ return newval;
+}
+
+static int calc_dsor_exp(struct clk *clk, unsigned long rate)
+{
+ /* Note: If target frequency is too low, this function will return 4,
+ * which is invalid value. Caller must check for this value and act
+ * accordingly.
+ *
+ * Note: This function does not check for following limitations set
+ * by the hardware (all conditions must be true):
+ * DSPMMU_CK == DSP_CK or DSPMMU_CK == DSP_CK/2
+ * ARM_CK >= TC_CK
+ * DSP_CK >= TC_CK
+ * DSPMMU_CK >= TC_CK
+ */
+ unsigned long realrate;
+ struct clk * parent;
+ unsigned dsor_exp;
+
+ if (unlikely(!(clk->flags & RATE_CKCTL)))
+ return -EINVAL;
+
+ parent = clk->parent;
+ if (unlikely(parent == 0))
+ return -EIO;
+
+ realrate = parent->rate;
+ for (dsor_exp=0; dsor_exp<4; dsor_exp++) {
+ if (realrate <= rate)
+ break;
+
+ realrate /= 2;
+ }
+
+ return dsor_exp;
+}
+
+static void omap1_ckctl_recalc(struct clk * clk)
+{
+ int dsor;
+
+ /* Calculate divisor encoded as 2-bit exponent */
+ dsor = 1 << (3 & (omap_readw(ARM_CKCTL) >> clk->rate_offset));
+
+ if (unlikely(clk->rate == clk->parent->rate / dsor))
+ return; /* No change, quick exit */
+ clk->rate = clk->parent->rate / dsor;
+
+ if (unlikely(clk->flags & RATE_PROPAGATES))
+ propagate_rate(clk);
+}
+
+static void omap1_ckctl_recalc_dsp_domain(struct clk * clk)
+{
+ int dsor;
+
+ /* Calculate divisor encoded as 2-bit exponent
+ *
+ * The clock control bits are in DSP domain,
+ * so api_ck is needed for access.
+ * Note that DSP_CKCTL virt addr = phys addr, so
+ * we must use __raw_readw() instead of omap_readw().
+ */
+ omap1_clk_use(&api_ck.clk);
+ dsor = 1 << (3 & (__raw_readw(DSP_CKCTL) >> clk->rate_offset));
+ omap1_clk_unuse(&api_ck.clk);
+
+ if (unlikely(clk->rate == clk->parent->rate / dsor))
+ return; /* No change, quick exit */
+ clk->rate = clk->parent->rate / dsor;
+
+ if (unlikely(clk->flags & RATE_PROPAGATES))
+ propagate_rate(clk);
+}
+
+/* MPU virtual clock functions */
+static int omap1_select_table_rate(struct clk * clk, unsigned long rate)
+{
+ /* Find the highest supported frequency <= rate and switch to it */
+ struct mpu_rate * ptr;
+
+ if (clk != &virtual_ck_mpu)
+ return -EINVAL;
+
+ for (ptr = rate_table; ptr->rate; ptr++) {
+ if (ptr->xtal != ck_ref.rate)
+ continue;
+
+ /* DPLL1 cannot be reprogrammed without risking system crash */
+ if (likely(ck_dpll1.rate!=0) && ptr->pll_rate != ck_dpll1.rate)
+ continue;
+
+ /* Can check only after xtal frequency check */
+ if (ptr->rate <= rate)
+ break;
+ }
+
+ if (!ptr->rate)
+ return -EINVAL;
+
+ /*
+ * In most cases we should not need to reprogram DPLL.
+ * Reprogramming the DPLL is tricky, it must be done from SRAM.
+ */
+ omap_sram_reprogram_clock(ptr->dpllctl_val, ptr->ckctl_val);
+
+ ck_dpll1.rate = ptr->pll_rate;
+ propagate_rate(&ck_dpll1);
+ return 0;
+}
+
+static int omap1_clk_set_rate_dsp_domain(struct clk *clk, unsigned long rate)
+{
+ int ret = -EINVAL;
+ int dsor_exp;
+ __u16 regval;
+
+ if (clk->flags & RATE_CKCTL) {
+ dsor_exp = calc_dsor_exp(clk, rate);
+ if (dsor_exp > 3)
+ dsor_exp = -EINVAL;
+ if (dsor_exp < 0)
+ return dsor_exp;
+
+ regval = __raw_readw(DSP_CKCTL);
+ regval &= ~(3 << clk->rate_offset);
+ regval |= dsor_exp << clk->rate_offset;
+ __raw_writew(regval, DSP_CKCTL);
+ clk->rate = clk->parent->rate / (1 << dsor_exp);
+ ret = 0;
+ }
+
+ if (unlikely(ret == 0 && (clk->flags & RATE_PROPAGATES)))
+ propagate_rate(clk);
+
+ return ret;
+}
+
+static long omap1_round_to_table_rate(struct clk * clk, unsigned long rate)
+{
+ /* Find the highest supported frequency <= rate */
+ struct mpu_rate * ptr;
+ long highest_rate;
+
+ if (clk != &virtual_ck_mpu)
+ return -EINVAL;
+
+ highest_rate = -EINVAL;
+
+ for (ptr = rate_table; ptr->rate; ptr++) {
+ if (ptr->xtal != ck_ref.rate)
+ continue;
+
+ highest_rate = ptr->rate;
+
+ /* Can check only after xtal frequency check */
+ if (ptr->rate <= rate)
+ break;
+ }
+
+ return highest_rate;
+}
+
+static unsigned calc_ext_dsor(unsigned long rate)
+{
+ unsigned dsor;
+
+ /* MCLK and BCLK divisor selection is not linear:
+ * freq = 96MHz / dsor
+ *
+ * RATIO_SEL range: dsor <-> RATIO_SEL
+ * 0..6: (RATIO_SEL+2) <-> (dsor-2)
+ * 6..48: (8+(RATIO_SEL-6)*2) <-> ((dsor-8)/2+6)
+ * Minimum dsor is 2 and maximum is 96. Odd divisors starting from 9
+ * can not be used.
+ */
+ for (dsor = 2; dsor < 96; ++dsor) {
+ if ((dsor & 1) && dsor > 8)
+ continue;
+ if (rate >= 96000000 / dsor)
+ break;
+ }
+ return dsor;
+}
+
+/* Only needed on 1510 */
+static int omap1_set_uart_rate(struct clk * clk, unsigned long rate)
+{
+ unsigned int val;
+
+ val = omap_readl(clk->enable_reg);
+ if (rate == 12000000)
+ val &= ~(1 << clk->enable_bit);
+ else if (rate == 48000000)
+ val |= (1 << clk->enable_bit);
+ else
+ return -EINVAL;
+ omap_writel(val, clk->enable_reg);
+ clk->rate = rate;
+
+ return 0;
+}
+
+/* External clock (MCLK & BCLK) functions */
+static int omap1_set_ext_clk_rate(struct clk * clk, unsigned long rate)
+{
+ unsigned dsor;
+ __u16 ratio_bits;
+
+ dsor = calc_ext_dsor(rate);
+ clk->rate = 96000000 / dsor;
+ if (dsor > 8)
+ ratio_bits = ((dsor - 8) / 2 + 6) << 2;
+ else
+ ratio_bits = (dsor - 2) << 2;
+
+ ratio_bits |= omap_readw(clk->enable_reg) & ~0xfd;
+ omap_writew(ratio_bits, clk->enable_reg);
+
+ return 0;
+}
+
+static long omap1_round_ext_clk_rate(struct clk * clk, unsigned long rate)
+{
+ return 96000000 / calc_ext_dsor(rate);
+}
+
+static void omap1_init_ext_clk(struct clk * clk)
+{
+ unsigned dsor;
+ __u16 ratio_bits;
+
+ /* Determine current rate and ensure clock is based on 96MHz APLL */
+ ratio_bits = omap_readw(clk->enable_reg) & ~1;
+ omap_writew(ratio_bits, clk->enable_reg);
+
+ ratio_bits = (ratio_bits & 0xfc) >> 2;
+ if (ratio_bits > 6)
+ dsor = (ratio_bits - 6) * 2 + 8;
+ else
+ dsor = ratio_bits + 2;
+
+ clk-> rate = 96000000 / dsor;
+}
+
+static int omap1_clk_use(struct clk *clk)
+{
+ int ret = 0;
+ if (clk->usecount++ == 0) {
+ if (likely(clk->parent)) {
+ ret = omap1_clk_use(clk->parent);
+
+ if (unlikely(ret != 0)) {
+ clk->usecount--;
+ return ret;
+ }
+
+ if (clk->flags & CLOCK_NO_IDLE_PARENT)
+ if (!cpu_is_omap24xx())
+ omap1_clk_deny_idle(clk->parent);
+ }
+
+ ret = clk->enable(clk);
+
+ if (unlikely(ret != 0) && clk->parent) {
+ omap1_clk_unuse(clk->parent);
+ clk->usecount--;
+ }
+ }
+
+ return ret;
+}
+
+static void omap1_clk_unuse(struct clk *clk)
+{
+ if (clk->usecount > 0 && !(--clk->usecount)) {
+ clk->disable(clk);
+ if (likely(clk->parent)) {
+ omap1_clk_unuse(clk->parent);
+ if (clk->flags & CLOCK_NO_IDLE_PARENT)
+ if (!cpu_is_omap24xx())
+ omap1_clk_allow_idle(clk->parent);
+ }
+ }
+}
+
+static int omap1_clk_enable(struct clk *clk)
+{
+ __u16 regval16;
+ __u32 regval32;
+
+ if (clk->flags & ALWAYS_ENABLED)
+ return 0;
+
+ if (unlikely(clk->enable_reg == 0)) {
+ printk(KERN_ERR "clock.c: Enable for %s without enable code\n",
+ clk->name);
+ return 0;
+ }
+
+ if (clk->flags & ENABLE_REG_32BIT) {
+ if (clk->flags & VIRTUAL_IO_ADDRESS) {
+ regval32 = __raw_readl(clk->enable_reg);
+ regval32 |= (1 << clk->enable_bit);
+ __raw_writel(regval32, clk->enable_reg);
+ } else {
+ regval32 = omap_readl(clk->enable_reg);
+ regval32 |= (1 << clk->enable_bit);
+ omap_writel(regval32, clk->enable_reg);
+ }
+ } else {
+ if (clk->flags & VIRTUAL_IO_ADDRESS) {
+ regval16 = __raw_readw(clk->enable_reg);
+ regval16 |= (1 << clk->enable_bit);
+ __raw_writew(regval16, clk->enable_reg);
+ } else {
+ regval16 = omap_readw(clk->enable_reg);
+ regval16 |= (1 << clk->enable_bit);
+ omap_writew(regval16, clk->enable_reg);
+ }
+ }
+
+ return 0;
+}
+
+static void omap1_clk_disable(struct clk *clk)
+{
+ __u16 regval16;
+ __u32 regval32;
+
+ if (clk->enable_reg == 0)
+ return;
+
+ if (clk->flags & ENABLE_REG_32BIT) {
+ if (clk->flags & VIRTUAL_IO_ADDRESS) {
+ regval32 = __raw_readl(clk->enable_reg);
+ regval32 &= ~(1 << clk->enable_bit);
+ __raw_writel(regval32, clk->enable_reg);
+ } else {
+ regval32 = omap_readl(clk->enable_reg);
+ regval32 &= ~(1 << clk->enable_bit);
+ omap_writel(regval32, clk->enable_reg);
+ }
+ } else {
+ if (clk->flags & VIRTUAL_IO_ADDRESS) {
+ regval16 = __raw_readw(clk->enable_reg);
+ regval16 &= ~(1 << clk->enable_bit);
+ __raw_writew(regval16, clk->enable_reg);
+ } else {
+ regval16 = omap_readw(clk->enable_reg);
+ regval16 &= ~(1 << clk->enable_bit);
+ omap_writew(regval16, clk->enable_reg);
+ }
+ }
+}
+
+static long omap1_clk_round_rate(struct clk *clk, unsigned long rate)
+{
+ int dsor_exp;
+
+ if (clk->flags & RATE_FIXED)
+ return clk->rate;
+
+ if (clk->flags & RATE_CKCTL) {
+ dsor_exp = calc_dsor_exp(clk, rate);
+ if (dsor_exp < 0)
+ return dsor_exp;
+ if (dsor_exp > 3)
+ dsor_exp = 3;
+ return clk->parent->rate / (1 << dsor_exp);
+ }
+
+ if(clk->round_rate != 0)
+ return clk->round_rate(clk, rate);
+
+ return clk->rate;
+}
+
+static int omap1_clk_set_rate(struct clk *clk, unsigned long rate)
+{
+ int ret = -EINVAL;
+ int dsor_exp;
+ __u16 regval;
+
+ if (clk->set_rate)
+ ret = clk->set_rate(clk, rate);
+ else if (clk->flags & RATE_CKCTL) {
+ dsor_exp = calc_dsor_exp(clk, rate);
+ if (dsor_exp > 3)
+ dsor_exp = -EINVAL;
+ if (dsor_exp < 0)
+ return dsor_exp;
+
+ regval = omap_readw(ARM_CKCTL);
+ regval &= ~(3 << clk->rate_offset);
+ regval |= dsor_exp << clk->rate_offset;
+ regval = verify_ckctl_value(regval);
+ omap_writew(regval, ARM_CKCTL);
+ clk->rate = clk->parent->rate / (1 << dsor_exp);
+ ret = 0;
+ }
+
+ if (unlikely(ret == 0 && (clk->flags & RATE_PROPAGATES)))
+ propagate_rate(clk);
+
+ return ret;
+}
+
+/*-------------------------------------------------------------------------
+ * Omap1 clock reset and init functions
+ *-------------------------------------------------------------------------*/
+
+#ifdef CONFIG_OMAP_RESET_CLOCKS
+/*
+ * Resets some clocks that may be left on from bootloader,
+ * but leaves serial clocks on. See also omap_late_clk_reset().
+ */
+static inline void omap1_early_clk_reset(void)
+{
+ //omap_writel(0x3 << 29, MOD_CONF_CTRL_0);
+}
+
+static int __init omap1_late_clk_reset(void)
+{
+ /* Turn off all unused clocks */
+ struct clk *p;
+ __u32 regval32;
+
+ /* USB_REQ_EN will be disabled later if necessary (usb_dc_ck) */
+ regval32 = omap_readw(SOFT_REQ_REG) & (1 << 4);
+ omap_writew(regval32, SOFT_REQ_REG);
+ omap_writew(0, SOFT_REQ_REG2);
+
+ list_for_each_entry(p, &clocks, node) {
+ if (p->usecount > 0 || (p->flags & ALWAYS_ENABLED) ||
+ p->enable_reg == 0)
+ continue;
+
+ /* Clocks in the DSP domain need api_ck. Just assume bootloader
+ * has not enabled any DSP clocks */
+ if ((u32)p->enable_reg == DSP_IDLECT2) {
+ printk(KERN_INFO "Skipping reset check for DSP domain "
+ "clock \"%s\"\n", p->name);
+ continue;
+ }
+
+ /* Is the clock already disabled? */
+ if (p->flags & ENABLE_REG_32BIT) {
+ if (p->flags & VIRTUAL_IO_ADDRESS)
+ regval32 = __raw_readl(p->enable_reg);
+ else
+ regval32 = omap_readl(p->enable_reg);
+ } else {
+ if (p->flags & VIRTUAL_IO_ADDRESS)
+ regval32 = __raw_readw(p->enable_reg);
+ else
+ regval32 = omap_readw(p->enable_reg);
+ }
+
+ if ((regval32 & (1 << p->enable_bit)) == 0)
+ continue;
+
+ /* FIXME: This clock seems to be necessary but no-one
+ * has asked for its activation. */
+ if (p == &tc2_ck // FIX: pm.c (SRAM), CCP, Camera
+ || p == &ck_dpll1out.clk // FIX: SoSSI, SSR
+ || p == &arm_gpio_ck // FIX: GPIO code for 1510
+ ) {
+ printk(KERN_INFO "FIXME: Clock \"%s\" seems unused\n",
+ p->name);
+ continue;
+ }
+
+ printk(KERN_INFO "Disabling unused clock \"%s\"... ", p->name);
+ p->disable(p);
+ printk(" done\n");
+ }
+
+ return 0;
+}
+late_initcall(omap1_late_clk_reset);
+
+#else
+#define omap1_early_clk_reset() {}
+#endif
+
+static struct clk_functions omap1_clk_functions = {
+ .clk_use = omap1_clk_use,
+ .clk_unuse = omap1_clk_unuse,
+ .clk_round_rate = omap1_clk_round_rate,
+ .clk_set_rate = omap1_clk_set_rate,
+};
+
+int __init omap1_clk_init(void)
+{
+ struct clk ** clkp;
+ const struct omap_clock_config *info;
+ int crystal_type = 0; /* Default 12 MHz */
+
+ omap1_early_clk_reset();
+ clk_init(&omap1_clk_functions);
+
+ /* By default all idlect1 clocks are allowed to idle */
+ arm_idlect1_mask = ~0;
+
+ for (clkp = onchip_clks; clkp < onchip_clks+ARRAY_SIZE(onchip_clks); clkp++) {
+ if (((*clkp)->flags &CLOCK_IN_OMAP1510) && cpu_is_omap1510()) {
+ clk_register(*clkp);
+ continue;
+ }
+
+ if (((*clkp)->flags &CLOCK_IN_OMAP16XX) && cpu_is_omap16xx()) {
+ clk_register(*clkp);
+ continue;
+ }
+
+ if (((*clkp)->flags &CLOCK_IN_OMAP730) && cpu_is_omap730()) {
+ clk_register(*clkp);
+ continue;
+ }
+ }
+
+ info = omap_get_config(OMAP_TAG_CLOCK, struct omap_clock_config);
+ if (info != NULL) {
+ if (!cpu_is_omap1510())
+ crystal_type = info->system_clock_type;
+ }
+
+#if defined(CONFIG_ARCH_OMAP730)
+ ck_ref.rate = 13000000;
+#elif defined(CONFIG_ARCH_OMAP16XX)
+ if (crystal_type == 2)
+ ck_ref.rate = 19200000;
+#endif
+
+ printk("Clocks: ARM_SYSST: 0x%04x DPLL_CTL: 0x%04x ARM_CKCTL: 0x%04x\n",
+ omap_readw(ARM_SYSST), omap_readw(DPLL_CTL),
+ omap_readw(ARM_CKCTL));
+
+ /* We want to be in syncronous scalable mode */
+ omap_writew(0x1000, ARM_SYSST);
+
+#ifdef CONFIG_OMAP_CLOCKS_SET_BY_BOOTLOADER
+ /* Use values set by bootloader. Determine PLL rate and recalculate
+ * dependent clocks as if kernel had changed PLL or divisors.
+ */
+ {
+ unsigned pll_ctl_val = omap_readw(DPLL_CTL);
+
+ ck_dpll1.rate = ck_ref.rate; /* Base xtal rate */
+ if (pll_ctl_val & 0x10) {
+ /* PLL enabled, apply multiplier and divisor */
+ if (pll_ctl_val & 0xf80)
+ ck_dpll1.rate *= (pll_ctl_val & 0xf80) >> 7;
+ ck_dpll1.rate /= ((pll_ctl_val & 0x60) >> 5) + 1;
+ } else {
+ /* PLL disabled, apply bypass divisor */
+ switch (pll_ctl_val & 0xc) {
+ case 0:
+ break;
+ case 0x4:
+ ck_dpll1.rate /= 2;
+ break;
+ default:
+ ck_dpll1.rate /= 4;
+ break;
+ }
+ }
+ }
+ propagate_rate(&ck_dpll1);
+#else
+ /* Find the highest supported frequency and enable it */
+ if (omap1_select_table_rate(&virtual_ck_mpu, ~0)) {
+ printk(KERN_ERR "System frequencies not set. Check your config.\n");
+ /* Guess sane values (60MHz) */
+ omap_writew(0x2290, DPLL_CTL);
+ omap_writew(0x1005, ARM_CKCTL);
+ ck_dpll1.rate = 60000000;
+ propagate_rate(&ck_dpll1);
+ }
+#endif
+ /* Cache rates for clocks connected to ck_ref (not dpll1) */
+ propagate_rate(&ck_ref);
+ printk(KERN_INFO "Clocking rate (xtal/DPLL1/MPU): "
+ "%ld.%01ld/%ld.%01ld/%ld.%01ld MHz\n",
+ ck_ref.rate / 1000000, (ck_ref.rate / 100000) % 10,
+ ck_dpll1.rate / 1000000, (ck_dpll1.rate / 100000) % 10,
+ arm_ck.rate / 1000000, (arm_ck.rate / 100000) % 10);
+
+#ifdef CONFIG_MACH_OMAP_PERSEUS2
+ /* Select slicer output as OMAP input clock */
+ omap_writew(omap_readw(OMAP730_PCC_UPLD_CTRL) & ~0x1, OMAP730_PCC_UPLD_CTRL);
+#endif
+
+ /* Turn off DSP and ARM_TIMXO. Make sure ARM_INTHCK is not divided */
+ omap_writew(omap_readw(ARM_CKCTL) & 0x0fff, ARM_CKCTL);
+
+ /* Put DSP/MPUI into reset until needed */
+ omap_writew(0, ARM_RSTCT1);
+ omap_writew(1, ARM_RSTCT2);
+ omap_writew(0x400, ARM_IDLECT1);
+
+ /*
+ * According to OMAP5910 Erratum SYS_DMA_1, bit DMACK_REQ (bit 8)
+ * of the ARM_IDLECT2 register must be set to zero. The power-on
+ * default value of this bit is one.
+ */
+ omap_writew(0x0000, ARM_IDLECT2); /* Turn LCD clock off also */
+
+ /*
+ * Only enable those clocks we will need, let the drivers
+ * enable other clocks as necessary
+ */
+ clk_use(&armper_ck.clk);
+ clk_use(&armxor_ck.clk);
+ clk_use(&armtim_ck.clk); /* This should be done by timer code */
+
+ if (cpu_is_omap1510())
+ clk_enable(&arm_gpio_ck);
+
+ return 0;
+}
+
diff --git a/arch/arm/mach-omap1/clock.h b/arch/arm/mach-omap1/clock.h
new file mode 100644
index 000000000000..f3bdfb50e01a
--- /dev/null
+++ b/arch/arm/mach-omap1/clock.h
@@ -0,0 +1,768 @@
+/*
+ * linux/arch/arm/mach-omap1/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
+ *
+ * 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 __ARCH_ARM_MACH_OMAP1_CLOCK_H
+#define __ARCH_ARM_MACH_OMAP1_CLOCK_H
+
+static int omap1_clk_enable(struct clk * clk);
+static void omap1_clk_disable(struct clk * clk);
+static void omap1_ckctl_recalc(struct clk * clk);
+static void omap1_watchdog_recalc(struct clk * clk);
+static void omap1_ckctl_recalc_dsp_domain(struct clk * clk);
+static int omap1_clk_enable_dsp_domain(struct clk * clk);
+static int omap1_clk_set_rate_dsp_domain(struct clk * clk, unsigned long rate);
+static void omap1_clk_disable_dsp_domain(struct clk * clk);
+static int omap1_set_uart_rate(struct clk * clk, unsigned long rate);
+static void omap1_uart_recalc(struct clk * clk);
+static int omap1_clk_enable_uart_functional(struct clk * clk);
+static void omap1_clk_disable_uart_functional(struct clk * clk);
+static int omap1_set_ext_clk_rate(struct clk * clk, unsigned long rate);
+static long omap1_round_ext_clk_rate(struct clk * clk, unsigned long rate);
+static void omap1_init_ext_clk(struct clk * clk);
+static int omap1_select_table_rate(struct clk * clk, unsigned long rate);
+static long omap1_round_to_table_rate(struct clk * clk, unsigned long rate);
+static int omap1_clk_use(struct clk *clk);
+static void omap1_clk_unuse(struct clk *clk);
+
+struct mpu_rate {
+ unsigned long rate;
+ unsigned long xtal;
+ unsigned long pll_rate;
+ __u16 ckctl_val;
+ __u16 dpllctl_val;
+};
+
+struct uart_clk {
+ struct clk clk;
+ unsigned long sysc_addr;
+};
+
+/* Provide a method for preventing idling some ARM IDLECT clocks */
+struct arm_idlect1_clk {
+ struct clk clk;
+ unsigned long no_idle_count;
+ __u8 idlect_shift;
+};
+
+/* ARM_CKCTL bit shifts */
+#define CKCTL_PERDIV_OFFSET 0
+#define CKCTL_LCDDIV_OFFSET 2
+#define CKCTL_ARMDIV_OFFSET 4
+#define CKCTL_DSPDIV_OFFSET 6
+#define CKCTL_TCDIV_OFFSET 8
+#define CKCTL_DSPMMUDIV_OFFSET 10
+/*#define ARM_TIMXO 12*/
+#define EN_DSPCK 13
+/*#define ARM_INTHCK_SEL 14*/ /* Divide-by-2 for mpu inth_ck */
+/* DSP_CKCTL bit shifts */
+#define CKCTL_DSPPERDIV_OFFSET 0
+
+/* ARM_IDLECT2 bit shifts */
+#define EN_WDTCK 0
+#define EN_XORPCK 1
+#define EN_PERCK 2
+#define EN_LCDCK 3
+#define EN_LBCK 4 /* Not on 1610/1710 */
+/*#define EN_HSABCK 5*/
+#define EN_APICK 6
+#define EN_TIMCK 7
+#define DMACK_REQ 8
+#define EN_GPIOCK 9 /* Not on 1610/1710 */
+/*#define EN_LBFREECK 10*/
+#define EN_CKOUT_ARM 11
+
+/* ARM_IDLECT3 bit shifts */
+#define EN_OCPI_CK 0
+#define EN_TC1_CK 2
+#define EN_TC2_CK 4
+
+/* DSP_IDLECT2 bit shifts (0,1,2 are same as for ARM_IDLECT2) */
+#define EN_DSPTIMCK 5
+
+/* Various register defines for clock controls scattered around OMAP chip */
+#define USB_MCLK_EN_BIT 4 /* In ULPD_CLKC_CTRL */
+#define USB_HOST_HHC_UHOST_EN 9 /* In MOD_CONF_CTRL_0 */
+#define SWD_ULPD_PLL_CLK_REQ 1 /* In SWD_CLK_DIV_CTRL_SEL */
+#define COM_ULPD_PLL_CLK_REQ 1 /* In COM_CLK_DIV_CTRL_SEL */
+#define SWD_CLK_DIV_CTRL_SEL 0xfffe0874
+#define COM_CLK_DIV_CTRL_SEL 0xfffe0878
+#define SOFT_REQ_REG 0xfffe0834
+#define SOFT_REQ_REG2 0xfffe0880
+
+/*-------------------------------------------------------------------------
+ * Omap1 MPU rate table
+ *-------------------------------------------------------------------------*/
+static struct mpu_rate rate_table[] = {
+ /* MPU MHz, xtal MHz, dpll1 MHz, CKCTL, DPLL_CTL
+ * NOTE: Comment order here is different from bits in CKCTL value:
+ * armdiv, dspdiv, dspmmu, tcdiv, perdiv, lcddiv
+ */
+#if defined(CONFIG_OMAP_ARM_216MHZ)
+ { 216000000, 12000000, 216000000, 0x050d, 0x2910 }, /* 1/1/2/2/2/8 */
+#endif
+#if defined(CONFIG_OMAP_ARM_195MHZ)
+ { 195000000, 13000000, 195000000, 0x050e, 0x2790 }, /* 1/1/2/2/4/8 */
+#endif
+#if defined(CONFIG_OMAP_ARM_192MHZ)
+ { 192000000, 19200000, 192000000, 0x050f, 0x2510 }, /* 1/1/2/2/8/8 */
+ { 192000000, 12000000, 192000000, 0x050f, 0x2810 }, /* 1/1/2/2/8/8 */
+ { 96000000, 12000000, 192000000, 0x055f, 0x2810 }, /* 2/2/2/2/8/8 */
+ { 48000000, 12000000, 192000000, 0x0baf, 0x2810 }, /* 4/4/4/8/8/8 */
+ { 24000000, 12000000, 192000000, 0x0fff, 0x2810 }, /* 8/8/8/8/8/8 */
+#endif
+#if defined(CONFIG_OMAP_ARM_182MHZ)
+ { 182000000, 13000000, 182000000, 0x050e, 0x2710 }, /* 1/1/2/2/4/8 */
+#endif
+#if defined(CONFIG_OMAP_ARM_168MHZ)
+ { 168000000, 12000000, 168000000, 0x010f, 0x2710 }, /* 1/1/1/2/8/8 */
+#endif
+#if defined(CONFIG_OMAP_ARM_150MHZ)
+ { 150000000, 12000000, 150000000, 0x010a, 0x2cb0 }, /* 1/1/1/2/4/4 */
+#endif
+#if defined(CONFIG_OMAP_ARM_120MHZ)
+ { 120000000, 12000000, 120000000, 0x010a, 0x2510 }, /* 1/1/1/2/4/4 */
+#endif
+#if defined(CONFIG_OMAP_ARM_96MHZ)
+ { 96000000, 12000000, 96000000, 0x0005, 0x2410 }, /* 1/1/1/1/2/2 */
+#endif
+#if defined(CONFIG_OMAP_ARM_60MHZ)
+ { 60000000, 12000000, 60000000, 0x0005, 0x2290 }, /* 1/1/1/1/2/2 */
+#endif
+#if defined(CONFIG_OMAP_ARM_30MHZ)
+ { 30000000, 12000000, 60000000, 0x0555, 0x2290 }, /* 2/2/2/2/2/2 */
+#endif
+ { 0, 0, 0, 0, 0 },
+};
+
+/*-------------------------------------------------------------------------
+ * Omap1 clocks
+ *-------------------------------------------------------------------------*/
+
+static struct clk ck_ref = {
+ .name = "ck_ref",
+ .rate = 12000000,
+ .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
+ ALWAYS_ENABLED,
+ .enable = &omap1_clk_enable,
+ .disable = &omap1_clk_disable,
+};
+
+static struct clk ck_dpll1 = {
+ .name = "ck_dpll1",
+ .parent = &ck_ref,
+ .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
+ RATE_PROPAGATES | ALWAYS_ENABLED,
+ .enable = &omap1_clk_enable,
+ .disable = &omap1_clk_disable,
+};
+
+static struct arm_idlect1_clk ck_dpll1out = {
+ .clk = {
+ .name = "ck_dpll1out",
+ .parent = &ck_dpll1,
+ .flags = CLOCK_IN_OMAP16XX | CLOCK_IDLE_CONTROL,
+ .enable_reg = (void __iomem *)ARM_IDLECT2,
+ .enable_bit = EN_CKOUT_ARM,
+ .recalc = &followparent_recalc,
+ .enable = &omap1_clk_enable,
+ .disable = &omap1_clk_disable,
+ },
+ .idlect_shift = 12,
+};
+
+static struct clk arm_ck = {
+ .name = "arm_ck",
+ .parent = &ck_dpll1,
+ .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
+ RATE_CKCTL | RATE_PROPAGATES | ALWAYS_ENABLED,
+ .rate_offset = CKCTL_ARMDIV_OFFSET,
+ .recalc = &omap1_ckctl_recalc,
+ .enable = &omap1_clk_enable,
+ .disable = &omap1_clk_disable,
+};
+
+static struct arm_idlect1_clk armper_ck = {
+ .clk = {
+ .name = "armper_ck",
+ .parent = &ck_dpll1,
+ .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
+ RATE_CKCTL | CLOCK_IDLE_CONTROL,
+ .enable_reg = (void __iomem *)ARM_IDLECT2,
+ .enable_bit = EN_PERCK,
+ .rate_offset = CKCTL_PERDIV_OFFSET,
+ .recalc = &omap1_ckctl_recalc,
+ .enable = &omap1_clk_enable,
+ .disable = &omap1_clk_disable,
+ },
+ .idlect_shift = 2,
+};
+
+static struct clk arm_gpio_ck = {
+ .name = "arm_gpio_ck",
+ .parent = &ck_dpll1,
+ .flags = CLOCK_IN_OMAP1510,
+ .enable_reg = (void __iomem *)ARM_IDLECT2,
+ .enable_bit = EN_GPIOCK,
+ .recalc = &followparent_recalc,
+ .enable = &omap1_clk_enable,
+ .disable = &omap1_clk_disable,
+};
+
+static struct arm_idlect1_clk armxor_ck = {
+ .clk = {
+ .name = "armxor_ck",
+ .parent = &ck_ref,
+ .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
+ CLOCK_IDLE_CONTROL,
+ .enable_reg = (void __iomem *)ARM_IDLECT2,
+ .enable_bit = EN_XORPCK,
+ .recalc = &followparent_recalc,
+ .enable = &omap1_clk_enable,
+ .disable = &omap1_clk_disable,
+ },
+ .idlect_shift = 1,
+};
+
+static struct arm_idlect1_clk armtim_ck = {
+ .clk = {
+ .name = "armtim_ck",
+ .parent = &ck_ref,
+ .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
+ CLOCK_IDLE_CONTROL,
+ .enable_reg = (void __iomem *)ARM_IDLECT2,
+ .enable_bit = EN_TIMCK,
+ .recalc = &followparent_recalc,
+ .enable = &omap1_clk_enable,
+ .disable = &omap1_clk_disable,
+ },
+ .idlect_shift = 9,
+};
+
+static struct arm_idlect1_clk armwdt_ck = {
+ .clk = {
+ .name = "armwdt_ck",
+ .parent = &ck_ref,
+ .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
+ CLOCK_IDLE_CONTROL,
+ .enable_reg = (void __iomem *)ARM_IDLECT2,
+ .enable_bit = EN_WDTCK,
+ .recalc = &omap1_watchdog_recalc,
+ .enable = &omap1_clk_enable,
+ .disable = &omap1_clk_disable,
+ },
+ .idlect_shift = 0,
+};
+
+static struct clk arminth_ck16xx = {
+ .name = "arminth_ck",
+ .parent = &arm_ck,
+ .flags = CLOCK_IN_OMAP16XX | ALWAYS_ENABLED,
+ .recalc = &followparent_recalc,
+ /* Note: On 16xx the frequency can be divided by 2 by programming
+ * ARM_CKCTL:ARM_INTHCK_SEL(14) to 1
+ *
+ * 1510 version is in TC clocks.
+ */
+ .enable = &omap1_clk_enable,
+ .disable = &omap1_clk_disable,
+};
+
+static struct clk dsp_ck = {
+ .name = "dsp_ck",
+ .parent = &ck_dpll1,
+ .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
+ RATE_CKCTL,
+ .enable_reg = (void __iomem *)ARM_CKCTL,
+ .enable_bit = EN_DSPCK,
+ .rate_offset = CKCTL_DSPDIV_OFFSET,
+ .recalc = &omap1_ckctl_recalc,
+ .enable = &omap1_clk_enable,
+ .disable = &omap1_clk_disable,
+};
+
+static struct clk dspmmu_ck = {
+ .name = "dspmmu_ck",
+ .parent = &ck_dpll1,
+ .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
+ RATE_CKCTL | ALWAYS_ENABLED,
+ .rate_offset = CKCTL_DSPMMUDIV_OFFSET,
+ .recalc = &omap1_ckctl_recalc,
+ .enable = &omap1_clk_enable,
+ .disable = &omap1_clk_disable,
+};
+
+static struct clk dspper_ck = {
+ .name = "dspper_ck",
+ .parent = &ck_dpll1,
+ .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
+ RATE_CKCTL | VIRTUAL_IO_ADDRESS,
+ .enable_reg = (void __iomem *)DSP_IDLECT2,
+ .enable_bit = EN_PERCK,
+ .rate_offset = CKCTL_PERDIV_OFFSET,
+ .recalc = &omap1_ckctl_recalc_dsp_domain,
+ .set_rate = &omap1_clk_set_rate_dsp_domain,
+ .enable = &omap1_clk_enable_dsp_domain,
+ .disable = &omap1_clk_disable_dsp_domain,
+};
+
+static struct clk dspxor_ck = {
+ .name = "dspxor_ck",
+ .parent = &ck_ref,
+ .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
+ VIRTUAL_IO_ADDRESS,
+ .enable_reg = (void __iomem *)DSP_IDLECT2,
+ .enable_bit = EN_XORPCK,
+ .recalc = &followparent_recalc,
+ .enable = &omap1_clk_enable_dsp_domain,
+ .disable = &omap1_clk_disable_dsp_domain,
+};
+
+static struct clk dsptim_ck = {
+ .name = "dsptim_ck",
+ .parent = &ck_ref,
+ .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
+ VIRTUAL_IO_ADDRESS,
+ .enable_reg = (void __iomem *)DSP_IDLECT2,
+ .enable_bit = EN_DSPTIMCK,
+ .recalc = &followparent_recalc,
+ .enable = &omap1_clk_enable_dsp_domain,
+ .disable = &omap1_clk_disable_dsp_domain,
+};
+
+/* Tie ARM_IDLECT1:IDLIF_ARM to this logical clock structure */
+static struct arm_idlect1_clk tc_ck = {
+ .clk = {
+ .name = "tc_ck",
+ .parent = &ck_dpll1,
+ .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
+ CLOCK_IN_OMAP730 | RATE_CKCTL |
+ RATE_PROPAGATES | ALWAYS_ENABLED |
+ CLOCK_IDLE_CONTROL,
+ .rate_offset = CKCTL_TCDIV_OFFSET,
+ .recalc = &omap1_ckctl_recalc,
+ .enable = &omap1_clk_enable,
+ .disable = &omap1_clk_disable,
+ },
+ .idlect_shift = 6,
+};
+
+static struct clk arminth_ck1510 = {
+ .name = "arminth_ck",
+ .parent = &tc_ck.clk,
+ .flags = CLOCK_IN_OMAP1510 | ALWAYS_ENABLED,
+ .recalc = &followparent_recalc,
+ /* Note: On 1510 the frequency follows TC_CK
+ *
+ * 16xx version is in MPU clocks.
+ */
+ .enable = &omap1_clk_enable,
+ .disable = &omap1_clk_disable,
+};
+
+static struct clk tipb_ck = {
+ /* No-idle controlled by "tc_ck" */
+ .name = "tibp_ck",
+ .parent = &tc_ck.clk,
+ .flags = CLOCK_IN_OMAP1510 | ALWAYS_ENABLED,
+ .recalc = &followparent_recalc,
+ .enable = &omap1_clk_enable,
+ .disable = &omap1_clk_disable,
+};
+
+static struct clk l3_ocpi_ck = {
+ /* No-idle controlled by "tc_ck" */
+ .name = "l3_ocpi_ck",
+ .parent = &tc_ck.clk,
+ .flags = CLOCK_IN_OMAP16XX,
+ .enable_reg = (void __iomem *)ARM_IDLECT3,
+ .enable_bit = EN_OCPI_CK,
+ .recalc = &followparent_recalc,
+ .enable = &omap1_clk_enable,
+ .disable = &omap1_clk_disable,
+};
+
+static struct clk tc1_ck = {
+ .name = "tc1_ck",
+ .parent = &tc_ck.clk,
+ .flags = CLOCK_IN_OMAP16XX,
+ .enable_reg = (void __iomem *)ARM_IDLECT3,
+ .enable_bit = EN_TC1_CK,
+ .recalc = &followparent_recalc,
+ .enable = &omap1_clk_enable,
+ .disable = &omap1_clk_disable,
+};
+
+static struct clk tc2_ck = {
+ .name = "tc2_ck",
+ .parent = &tc_ck.clk,
+ .flags = CLOCK_IN_OMAP16XX,
+ .enable_reg = (void __iomem *)ARM_IDLECT3,
+ .enable_bit = EN_TC2_CK,
+ .recalc = &followparent_recalc,
+ .enable = &omap1_clk_enable,
+ .disable = &omap1_clk_disable,
+};
+
+static struct clk dma_ck = {
+ /* No-idle controlled by "tc_ck" */
+ .name = "dma_ck",
+ .parent = &tc_ck.clk,
+ .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
+ ALWAYS_ENABLED,
+ .recalc = &followparent_recalc,
+ .enable = &omap1_clk_enable,
+ .disable = &omap1_clk_disable,
+};
+
+static struct clk dma_lcdfree_ck = {
+ .name = "dma_lcdfree_ck",
+ .parent = &tc_ck.clk,
+ .flags = CLOCK_IN_OMAP16XX | ALWAYS_ENABLED,
+ .recalc = &followparent_recalc,
+ .enable = &omap1_clk_enable,
+ .disable = &omap1_clk_disable,
+};
+
+static struct arm_idlect1_clk api_ck = {
+ .clk = {
+ .name = "api_ck",
+ .parent = &tc_ck.clk,
+ .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
+ CLOCK_IDLE_CONTROL,
+ .enable_reg = (void __iomem *)ARM_IDLECT2,
+ .enable_bit = EN_APICK,
+ .recalc = &followparent_recalc,
+ .enable = &omap1_clk_enable,
+ .disable = &omap1_clk_disable,
+ },
+ .idlect_shift = 8,
+};
+
+static struct arm_idlect1_clk lb_ck = {
+ .clk = {
+ .name = "lb_ck",
+ .parent = &tc_ck.clk,
+ .flags = CLOCK_IN_OMAP1510 | CLOCK_IDLE_CONTROL,
+ .enable_reg = (void __iomem *)ARM_IDLECT2,
+ .enable_bit = EN_LBCK,
+ .recalc = &followparent_recalc,
+ .enable = &omap1_clk_enable,
+ .disable = &omap1_clk_disable,
+ },
+ .idlect_shift = 4,
+};
+
+static struct clk rhea1_ck = {
+ .name = "rhea1_ck",
+ .parent = &tc_ck.clk,
+ .flags = CLOCK_IN_OMAP16XX | ALWAYS_ENABLED,
+ .recalc = &followparent_recalc,
+ .enable = &omap1_clk_enable,
+ .disable = &omap1_clk_disable,
+};
+
+static struct clk rhea2_ck = {
+ .name = "rhea2_ck",
+ .parent = &tc_ck.clk,
+ .flags = CLOCK_IN_OMAP16XX | ALWAYS_ENABLED,
+ .recalc = &followparent_recalc,
+ .enable = &omap1_clk_enable,
+ .disable = &omap1_clk_disable,
+};
+
+static struct clk lcd_ck_16xx = {
+ .name = "lcd_ck",
+ .parent = &ck_dpll1,
+ .flags = CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP730 | RATE_CKCTL,
+ .enable_reg = (void __iomem *)ARM_IDLECT2,
+ .enable_bit = EN_LCDCK,
+ .rate_offset = CKCTL_LCDDIV_OFFSET,
+ .recalc = &omap1_ckctl_recalc,
+ .enable = &omap1_clk_enable,
+ .disable = &omap1_clk_disable,
+};
+
+static struct arm_idlect1_clk lcd_ck_1510 = {
+ .clk = {
+ .name = "lcd_ck",
+ .parent = &ck_dpll1,
+ .flags = CLOCK_IN_OMAP1510 | RATE_CKCTL |
+ CLOCK_IDLE_CONTROL,
+ .enable_reg = (void __iomem *)ARM_IDLECT2,
+ .enable_bit = EN_LCDCK,
+ .rate_offset = CKCTL_LCDDIV_OFFSET,
+ .recalc = &omap1_ckctl_recalc,
+ .enable = &omap1_clk_enable,
+ .disable = &omap1_clk_disable,
+ },
+ .idlect_shift = 3,
+};
+
+static struct clk uart1_1510 = {
+ .name = "uart1_ck",
+ /* Direct from ULPD, no real parent */
+ .parent = &armper_ck.clk,
+ .rate = 12000000,
+ .flags = CLOCK_IN_OMAP1510 | ENABLE_REG_32BIT |
+ ALWAYS_ENABLED | CLOCK_NO_IDLE_PARENT,
+ .enable_reg = (void __iomem *)MOD_CONF_CTRL_0,
+ .enable_bit = 29, /* Chooses between 12MHz and 48MHz */
+ .set_rate = &omap1_set_uart_rate,
+ .recalc = &omap1_uart_recalc,
+ .enable = &omap1_clk_enable,
+ .disable = &omap1_clk_disable,
+};
+
+static struct uart_clk uart1_16xx = {
+ .clk = {
+ .name = "uart1_ck",
+ /* Direct from ULPD, no real parent */
+ .parent = &armper_ck.clk,
+ .rate = 48000000,
+ .flags = CLOCK_IN_OMAP16XX | RATE_FIXED |
+ ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
+ .enable_reg = (void __iomem *)MOD_CONF_CTRL_0,
+ .enable_bit = 29,
+ .enable = &omap1_clk_enable_uart_functional,
+ .disable = &omap1_clk_disable_uart_functional,
+ },
+ .sysc_addr = 0xfffb0054,
+};
+
+static struct clk uart2_ck = {
+ .name = "uart2_ck",
+ /* Direct from ULPD, no real parent */
+ .parent = &armper_ck.clk,
+ .rate = 12000000,
+ .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
+ ENABLE_REG_32BIT | ALWAYS_ENABLED |
+ CLOCK_NO_IDLE_PARENT,
+ .enable_reg = (void __iomem *)MOD_CONF_CTRL_0,
+ .enable_bit = 30, /* Chooses between 12MHz and 48MHz */
+ .set_rate = &omap1_set_uart_rate,
+ .recalc = &omap1_uart_recalc,
+ .enable = &omap1_clk_enable,
+ .disable = &omap1_clk_disable,
+};
+
+static struct clk uart3_1510 = {
+ .name = "uart3_ck",
+ /* Direct from ULPD, no real parent */
+ .parent = &armper_ck.clk,
+ .rate = 12000000,
+ .flags = CLOCK_IN_OMAP1510 | ENABLE_REG_32BIT |
+ ALWAYS_ENABLED | CLOCK_NO_IDLE_PARENT,
+ .enable_reg = (void __iomem *)MOD_CONF_CTRL_0,
+ .enable_bit = 31, /* Chooses between 12MHz and 48MHz */
+ .set_rate = &omap1_set_uart_rate,
+ .recalc = &omap1_uart_recalc,
+ .enable = &omap1_clk_enable,
+ .disable = &omap1_clk_disable,
+};
+
+static struct uart_clk uart3_16xx = {
+ .clk = {
+ .name = "uart3_ck",
+ /* Direct from ULPD, no real parent */
+ .parent = &armper_ck.clk,
+ .rate = 48000000,
+ .flags = CLOCK_IN_OMAP16XX | RATE_FIXED |
+ ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
+ .enable_reg = (void __iomem *)MOD_CONF_CTRL_0,
+ .enable_bit = 31,
+ .enable = &omap1_clk_enable_uart_functional,
+ .disable = &omap1_clk_disable_uart_functional,
+ },
+ .sysc_addr = 0xfffb9854,
+};
+
+static struct clk usb_clko = { /* 6 MHz output on W4_USB_CLKO */
+ .name = "usb_clko",
+ /* Direct from ULPD, no parent */
+ .rate = 6000000,
+ .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
+ RATE_FIXED | ENABLE_REG_32BIT,
+ .enable_reg = (void __iomem *)ULPD_CLOCK_CTRL,
+ .enable_bit = USB_MCLK_EN_BIT,
+ .enable = &omap1_clk_enable,
+ .disable = &omap1_clk_disable,
+};
+
+static struct clk usb_hhc_ck1510 = {
+ .name = "usb_hhc_ck",
+ /* Direct from ULPD, no parent */
+ .rate = 48000000, /* Actually 2 clocks, 12MHz and 48MHz */
+ .flags = CLOCK_IN_OMAP1510 |
+ RATE_FIXED | ENABLE_REG_32BIT,
+ .enable_reg = (void __iomem *)MOD_CONF_CTRL_0,
+ .enable_bit = USB_HOST_HHC_UHOST_EN,
+ .enable = &omap1_clk_enable,
+ .disable = &omap1_clk_disable,
+};
+
+static struct clk usb_hhc_ck16xx = {
+ .name = "usb_hhc_ck",
+ /* Direct from ULPD, no parent */
+ .rate = 48000000,
+ /* OTG_SYSCON_2.OTG_PADEN == 0 (not 1510-compatible) */
+ .flags = CLOCK_IN_OMAP16XX |
+ RATE_FIXED | ENABLE_REG_32BIT,
+ .enable_reg = (void __iomem *)OTG_BASE + 0x08 /* OTG_SYSCON_2 */,
+ .enable_bit = 8 /* UHOST_EN */,
+ .enable = &omap1_clk_enable,
+ .disable = &omap1_clk_disable,
+};
+
+static struct clk usb_dc_ck = {
+ .name = "usb_dc_ck",
+ /* Direct from ULPD, no parent */
+ .rate = 48000000,
+ .flags = CLOCK_IN_OMAP16XX | RATE_FIXED,
+ .enable_reg = (void __iomem *)SOFT_REQ_REG,
+ .enable_bit = 4,
+ .enable = &omap1_clk_enable,
+ .disable = &omap1_clk_disable,
+};
+
+static struct clk mclk_1510 = {
+ .name = "mclk",
+ /* Direct from ULPD, no parent. May be enabled by ext hardware. */
+ .rate = 12000000,
+ .flags = CLOCK_IN_OMAP1510 | RATE_FIXED,
+ .enable = &omap1_clk_enable,
+ .disable = &omap1_clk_disable,
+};
+
+static struct clk mclk_16xx = {
+ .name = "mclk",
+ /* Direct from ULPD, no parent. May be enabled by ext hardware. */
+ .flags = CLOCK_IN_OMAP16XX,
+ .enable_reg = (void __iomem *)COM_CLK_DIV_CTRL_SEL,
+ .enable_bit = COM_ULPD_PLL_CLK_REQ,
+ .set_rate = &omap1_set_ext_clk_rate,
+ .round_rate = &omap1_round_ext_clk_rate,
+ .init = &omap1_init_ext_clk,
+ .enable = &omap1_clk_enable,
+ .disable = &omap1_clk_disable,
+};
+
+static struct clk bclk_1510 = {
+ .name = "bclk",
+ /* Direct from ULPD, no parent. May be enabled by ext hardware. */
+ .rate = 12000000,
+ .flags = CLOCK_IN_OMAP1510 | RATE_FIXED,
+ .enable = &omap1_clk_enable,
+ .disable = &omap1_clk_disable,
+};
+
+static struct clk bclk_16xx = {
+ .name = "bclk",
+ /* Direct from ULPD, no parent. May be enabled by ext hardware. */
+ .flags = CLOCK_IN_OMAP16XX,
+ .enable_reg = (void __iomem *)SWD_CLK_DIV_CTRL_SEL,
+ .enable_bit = SWD_ULPD_PLL_CLK_REQ,
+ .set_rate = &omap1_set_ext_clk_rate,
+ .round_rate = &omap1_round_ext_clk_rate,
+ .init = &omap1_init_ext_clk,
+ .enable = &omap1_clk_enable,
+ .disable = &omap1_clk_disable,
+};
+
+static struct clk mmc1_ck = {
+ .name = "mmc1_ck",
+ /* Functional clock is direct from ULPD, interface clock is ARMPER */
+ .parent = &armper_ck.clk,
+ .rate = 48000000,
+ .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
+ RATE_FIXED | ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
+ .enable_reg = (void __iomem *)MOD_CONF_CTRL_0,
+ .enable_bit = 23,
+ .enable = &omap1_clk_enable,
+ .disable = &omap1_clk_disable,
+};
+
+static struct clk mmc2_ck = {
+ .name = "mmc2_ck",
+ /* Functional clock is direct from ULPD, interface clock is ARMPER */
+ .parent = &armper_ck.clk,
+ .rate = 48000000,
+ .flags = CLOCK_IN_OMAP16XX |
+ RATE_FIXED | ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
+ .enable_reg = (void __iomem *)MOD_CONF_CTRL_0,
+ .enable_bit = 20,
+ .enable = &omap1_clk_enable,
+ .disable = &omap1_clk_disable,
+};
+
+static struct clk virtual_ck_mpu = {
+ .name = "mpu",
+ .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
+ VIRTUAL_CLOCK | ALWAYS_ENABLED,
+ .parent = &arm_ck, /* Is smarter alias for */
+ .recalc = &followparent_recalc,
+ .set_rate = &omap1_select_table_rate,
+ .round_rate = &omap1_round_to_table_rate,
+ .enable = &omap1_clk_enable,
+ .disable = &omap1_clk_disable,
+};
+
+static struct clk * onchip_clks[] = {
+ /* non-ULPD clocks */
+ &ck_ref,
+ &ck_dpll1,
+ /* CK_GEN1 clocks */
+ &ck_dpll1out.clk,
+ &arm_ck,
+ &armper_ck.clk,
+ &arm_gpio_ck,
+ &armxor_ck.clk,
+ &armtim_ck.clk,
+ &armwdt_ck.clk,
+ &arminth_ck1510, &arminth_ck16xx,
+ /* CK_GEN2 clocks */
+ &dsp_ck,
+ &dspmmu_ck,
+ &dspper_ck,
+ &dspxor_ck,
+ &dsptim_ck,
+ /* CK_GEN3 clocks */
+ &tc_ck.clk,
+ &tipb_ck,
+ &l3_ocpi_ck,
+ &tc1_ck,
+ &tc2_ck,
+ &dma_ck,
+ &dma_lcdfree_ck,
+ &api_ck.clk,
+ &lb_ck.clk,
+ &rhea1_ck,
+ &rhea2_ck,
+ &lcd_ck_16xx,
+ &lcd_ck_1510.clk,
+ /* ULPD clocks */
+ &uart1_1510,
+ &uart1_16xx.clk,
+ &uart2_ck,
+ &uart3_1510,
+ &uart3_16xx.clk,
+ &usb_clko,
+ &usb_hhc_ck1510, &usb_hhc_ck16xx,
+ &usb_dc_ck,
+ &mclk_1510, &mclk_16xx,
+ &bclk_1510, &bclk_16xx,
+ &mmc1_ck,
+ &mmc2_ck,
+ /* Virtual clocks */
+ &virtual_ck_mpu,
+};
+
+#endif
diff --git a/arch/arm/mach-omap1/devices.c b/arch/arm/mach-omap1/devices.c
index e8b3981444cd..ecbc47514adc 100644
--- a/arch/arm/mach-omap1/devices.c
+++ b/arch/arm/mach-omap1/devices.c
@@ -13,7 +13,7 @@
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <asm/hardware.h>
#include <asm/io.h>
@@ -25,56 +25,7 @@
#include <asm/arch/mux.h>
#include <asm/arch/gpio.h>
-
-static void omap_nop_release(struct device *dev)
-{
- /* Nothing */
-}
-
-/*-------------------------------------------------------------------------*/
-
-#if defined(CONFIG_I2C_OMAP) || defined(CONFIG_I2C_OMAP_MODULE)
-
-#define OMAP_I2C_BASE 0xfffb3800
-
-static struct resource i2c_resources[] = {
- {
- .start = OMAP_I2C_BASE,
- .end = OMAP_I2C_BASE + 0x3f,
- .flags = IORESOURCE_MEM,
- },
- {
- .start = INT_I2C,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-/* DMA not used; works around erratum writing to non-empty i2c fifo */
-
-static struct platform_device omap_i2c_device = {
- .name = "i2c_omap",
- .id = -1,
- .dev = {
- .release = omap_nop_release,
- },
- .num_resources = ARRAY_SIZE(i2c_resources),
- .resource = i2c_resources,
-};
-
-static void omap_init_i2c(void)
-{
- /* FIXME define and use a boot tag, in case of boards that
- * either don't wire up I2C, or chips that mux it differently...
- * it can include clocking and address info, maybe more.
- */
- omap_cfg_reg(I2C_SCL);
- omap_cfg_reg(I2C_SDA);
-
- (void) platform_device_register(&omap_i2c_device);
-}
-#else
-static inline void omap_init_i2c(void) {}
-#endif
+extern void omap_nop_release(struct device *dev);
/*-------------------------------------------------------------------------*/
@@ -110,137 +61,6 @@ static inline void omap_init_irda(void) {}
/*-------------------------------------------------------------------------*/
-#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE)
-
-#define OMAP_MMC1_BASE 0xfffb7800
-#define OMAP_MMC2_BASE 0xfffb7c00 /* omap16xx only */
-
-static struct omap_mmc_conf mmc1_conf;
-
-static u64 mmc1_dmamask = 0xffffffff;
-
-static struct resource mmc1_resources[] = {
- {
- .start = IO_ADDRESS(OMAP_MMC1_BASE),
- .end = IO_ADDRESS(OMAP_MMC1_BASE) + 0x7f,
- .flags = IORESOURCE_MEM,
- },
- {
- .start = INT_MMC,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-static struct platform_device mmc_omap_device1 = {
- .name = "mmci-omap",
- .id = 1,
- .dev = {
- .release = omap_nop_release,
- .dma_mask = &mmc1_dmamask,
- .platform_data = &mmc1_conf,
- },
- .num_resources = ARRAY_SIZE(mmc1_resources),
- .resource = mmc1_resources,
-};
-
-#ifdef CONFIG_ARCH_OMAP16XX
-
-static struct omap_mmc_conf mmc2_conf;
-
-static u64 mmc2_dmamask = 0xffffffff;
-
-static struct resource mmc2_resources[] = {
- {
- .start = IO_ADDRESS(OMAP_MMC2_BASE),
- .end = IO_ADDRESS(OMAP_MMC2_BASE) + 0x7f,
- .flags = IORESOURCE_MEM,
- },
- {
- .start = INT_1610_MMC2,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-static struct platform_device mmc_omap_device2 = {
- .name = "mmci-omap",
- .id = 2,
- .dev = {
- .release = omap_nop_release,
- .dma_mask = &mmc2_dmamask,
- .platform_data = &mmc2_conf,
- },
- .num_resources = ARRAY_SIZE(mmc2_resources),
- .resource = mmc2_resources,
-};
-#endif
-
-static void __init omap_init_mmc(void)
-{
- const struct omap_mmc_config *mmc_conf;
- const struct omap_mmc_conf *mmc;
-
- /* NOTE: assumes MMC was never (wrongly) enabled */
- mmc_conf = omap_get_config(OMAP_TAG_MMC, struct omap_mmc_config);
- if (!mmc_conf)
- return;
-
- /* block 1 is always available and has just one pinout option */
- mmc = &mmc_conf->mmc[0];
- if (mmc->enabled) {
- omap_cfg_reg(MMC_CMD);
- omap_cfg_reg(MMC_CLK);
- omap_cfg_reg(MMC_DAT0);
- if (cpu_is_omap1710()) {
- omap_cfg_reg(M15_1710_MMC_CLKI);
- omap_cfg_reg(P19_1710_MMC_CMDDIR);
- omap_cfg_reg(P20_1710_MMC_DATDIR0);
- }
- if (mmc->wire4) {
- omap_cfg_reg(MMC_DAT1);
- /* NOTE: DAT2 can be on W10 (here) or M15 */
- if (!mmc->nomux)
- omap_cfg_reg(MMC_DAT2);
- omap_cfg_reg(MMC_DAT3);
- }
- mmc1_conf = *mmc;
- (void) platform_device_register(&mmc_omap_device1);
- }
-
-#ifdef CONFIG_ARCH_OMAP16XX
- /* block 2 is on newer chips, and has many pinout options */
- mmc = &mmc_conf->mmc[1];
- if (mmc->enabled) {
- if (!mmc->nomux) {
- omap_cfg_reg(Y8_1610_MMC2_CMD);
- omap_cfg_reg(Y10_1610_MMC2_CLK);
- omap_cfg_reg(R18_1610_MMC2_CLKIN);
- omap_cfg_reg(W8_1610_MMC2_DAT0);
- if (mmc->wire4) {
- omap_cfg_reg(V8_1610_MMC2_DAT1);
- omap_cfg_reg(W15_1610_MMC2_DAT2);
- omap_cfg_reg(R10_1610_MMC2_DAT3);
- }
-
- /* These are needed for the level shifter */
- omap_cfg_reg(V9_1610_MMC2_CMDDIR);
- omap_cfg_reg(V5_1610_MMC2_DATDIR0);
- omap_cfg_reg(W19_1610_MMC2_DATDIR1);
- }
-
- /* Feedback clock must be set on OMAP-1710 MMC2 */
- if (cpu_is_omap1710())
- omap_writel(omap_readl(MOD_CONF_CTRL_1) | (1 << 24),
- MOD_CONF_CTRL_1);
- mmc2_conf = *mmc;
- (void) platform_device_register(&mmc_omap_device2);
- }
-#endif
- return;
-}
-#else
-static inline void omap_init_mmc(void) {}
-#endif
-
#if defined(CONFIG_OMAP_RTC) || defined(CONFIG_OMAP_RTC)
#define OMAP_RTC_BASE 0xfffb4800
@@ -279,38 +99,6 @@ static void omap_init_rtc(void)
static inline void omap_init_rtc(void) {}
#endif
-/*-------------------------------------------------------------------------*/
-
-#if defined(CONFIG_OMAP16XX_WATCHDOG) || defined(CONFIG_OMAP16XX_WATCHDOG_MODULE)
-
-#define OMAP_WDT_BASE 0xfffeb000
-
-static struct resource wdt_resources[] = {
- {
- .start = OMAP_WDT_BASE,
- .end = OMAP_WDT_BASE + 0x4f,
- .flags = IORESOURCE_MEM,
- },
-};
-
-static struct platform_device omap_wdt_device = {
- .name = "omap1610_wdt",
- .id = -1,
- .dev = {
- .release = omap_nop_release,
- },
- .num_resources = ARRAY_SIZE(wdt_resources),
- .resource = wdt_resources,
-};
-
-static void omap_init_wdt(void)
-{
- (void) platform_device_register(&omap_wdt_device);
-}
-#else
-static inline void omap_init_wdt(void) {}
-#endif
-
/*-------------------------------------------------------------------------*/
@@ -334,18 +122,15 @@ static inline void omap_init_wdt(void) {}
* may be handled by the boot loader, and drivers should expect it will
* normally have been done by the time they're probed.
*/
-static int __init omap_init_devices(void)
+static int __init omap1_init_devices(void)
{
/* please keep these calls, and their implementations above,
* in alphabetical order so they're easier to sort through.
*/
- omap_init_i2c();
omap_init_irda();
- omap_init_mmc();
omap_init_rtc();
- omap_init_wdt();
return 0;
}
-arch_initcall(omap_init_devices);
+arch_initcall(omap1_init_devices);
diff --git a/arch/arm/mach-omap1/id.c b/arch/arm/mach-omap1/id.c
index 986c3b7e09bb..5c637c048368 100644
--- a/arch/arm/mach-omap1/id.c
+++ b/arch/arm/mach-omap1/id.c
@@ -18,6 +18,13 @@
#include <asm/io.h>
+#define OMAP_DIE_ID_0 0xfffe1800
+#define OMAP_DIE_ID_1 0xfffe1804
+#define OMAP_PRODUCTION_ID_0 0xfffe2000
+#define OMAP_PRODUCTION_ID_1 0xfffe2004
+#define OMAP32_ID_0 0xfffed400
+#define OMAP32_ID_1 0xfffed404
+
struct omap_id {
u16 jtag_id; /* Used to determine OMAP type */
u8 die_rev; /* Processor revision */
@@ -27,6 +34,7 @@ struct omap_id {
/* Register values to detect the OMAP version */
static struct omap_id omap_ids[] __initdata = {
+ { .jtag_id = 0xb574, .die_rev = 0x2, .omap_id = 0x03310315, .type = 0x03100000},
{ .jtag_id = 0x355f, .die_rev = 0x0, .omap_id = 0x03320000, .type = 0x07300100},
{ .jtag_id = 0xb55f, .die_rev = 0x0, .omap_id = 0x03320000, .type = 0x07300300},
{ .jtag_id = 0xb470, .die_rev = 0x0, .omap_id = 0x03310100, .type = 0x15100000},
@@ -164,6 +172,7 @@ void __init omap_check_revision(void)
case 0x07:
system_rev |= 0x07;
break;
+ case 0x03:
case 0x15:
system_rev |= 0x15;
break;
diff --git a/arch/arm/mach-omap1/io.c b/arch/arm/mach-omap1/io.c
index eb8261d7dead..a7a19f75b9e1 100644
--- a/arch/arm/mach-omap1/io.c
+++ b/arch/arm/mach-omap1/io.c
@@ -15,9 +15,10 @@
#include <asm/mach/map.h>
#include <asm/io.h>
+#include <asm/arch/mux.h>
#include <asm/arch/tc.h>
-extern int clk_init(void);
+extern int omap1_clk_init(void);
extern void omap_check_revision(void);
extern void omap_sram_init(void);
@@ -26,27 +27,59 @@ extern void omap_sram_init(void);
* default mapping provided here.
*/
static struct map_desc omap_io_desc[] __initdata = {
- { IO_VIRT, IO_PHYS, IO_SIZE, MT_DEVICE },
+ {
+ .virtual = IO_VIRT,
+ .pfn = __phys_to_pfn(IO_PHYS),
+ .length = IO_SIZE,
+ .type = MT_DEVICE
+ }
};
#ifdef CONFIG_ARCH_OMAP730
static struct map_desc omap730_io_desc[] __initdata = {
- { OMAP730_DSP_BASE, OMAP730_DSP_START, OMAP730_DSP_SIZE, MT_DEVICE },
- { OMAP730_DSPREG_BASE, OMAP730_DSPREG_START, OMAP730_DSPREG_SIZE, MT_DEVICE },
+ {
+ .virtual = OMAP730_DSP_BASE,
+ .pfn = __phys_to_pfn(OMAP730_DSP_START),
+ .length = OMAP730_DSP_SIZE,
+ .type = MT_DEVICE
+ }, {
+ .virtual = OMAP730_DSPREG_BASE,
+ .pfn = __phys_to_pfn(OMAP730_DSPREG_START),
+ .length = OMAP730_DSPREG_SIZE,
+ .type = MT_DEVICE
+ }
};
#endif
-#ifdef CONFIG_ARCH_OMAP1510
+#ifdef CONFIG_ARCH_OMAP15XX
static struct map_desc omap1510_io_desc[] __initdata = {
- { OMAP1510_DSP_BASE, OMAP1510_DSP_START, OMAP1510_DSP_SIZE, MT_DEVICE },
- { OMAP1510_DSPREG_BASE, OMAP1510_DSPREG_START, OMAP1510_DSPREG_SIZE, MT_DEVICE },
+ {
+ .virtual = OMAP1510_DSP_BASE,
+ .pfn = __phys_to_pfn(OMAP1510_DSP_START),
+ .length = OMAP1510_DSP_SIZE,
+ .type = MT_DEVICE
+ }, {
+ .virtual = OMAP1510_DSPREG_BASE,
+ .pfn = __phys_to_pfn(OMAP1510_DSPREG_START),
+ .length = OMAP1510_DSPREG_SIZE,
+ .type = MT_DEVICE
+ }
};
#endif
#if defined(CONFIG_ARCH_OMAP16XX)
static struct map_desc omap16xx_io_desc[] __initdata = {
- { OMAP16XX_DSP_BASE, OMAP16XX_DSP_START, OMAP16XX_DSP_SIZE, MT_DEVICE },
- { OMAP16XX_DSPREG_BASE, OMAP16XX_DSPREG_START, OMAP16XX_DSPREG_SIZE, MT_DEVICE },
+ {
+ .virtual = OMAP16XX_DSP_BASE,
+ .pfn = __phys_to_pfn(OMAP16XX_DSP_START),
+ .length = OMAP16XX_DSP_SIZE,
+ .type = MT_DEVICE
+ }, {
+ .virtual = OMAP16XX_DSPREG_BASE,
+ .pfn = __phys_to_pfn(OMAP16XX_DSPREG_START),
+ .length = OMAP16XX_DSPREG_SIZE,
+ .type = MT_DEVICE
+ }
};
#endif
@@ -66,7 +99,7 @@ static void __init _omap_map_io(void)
iotable_init(omap730_io_desc, ARRAY_SIZE(omap730_io_desc));
}
#endif
-#ifdef CONFIG_ARCH_OMAP1510
+#ifdef CONFIG_ARCH_OMAP15XX
if (cpu_is_omap1510()) {
iotable_init(omap1510_io_desc, ARRAY_SIZE(omap1510_io_desc));
}
@@ -87,7 +120,7 @@ static void __init _omap_map_io(void)
/* Must init clocks early to assure that timer interrupt works
*/
- clk_init();
+ omap1_clk_init();
}
/*
@@ -95,7 +128,9 @@ static void __init _omap_map_io(void)
*/
void __init omap_map_common_io(void)
{
- if (!initialized)
+ if (!initialized) {
_omap_map_io();
+ omap1_mux_init();
+ }
}
diff --git a/arch/arm/mach-omap1/irq.c b/arch/arm/mach-omap1/irq.c
index 192ce6055faa..ed65a7d2e941 100644
--- a/arch/arm/mach-omap1/irq.c
+++ b/arch/arm/mach-omap1/irq.c
@@ -47,6 +47,7 @@
#include <asm/irq.h>
#include <asm/mach/irq.h>
#include <asm/arch/gpio.h>
+#include <asm/arch/cpu.h>
#include <asm/io.h>
@@ -147,11 +148,15 @@ static struct omap_irq_bank omap730_irq_banks[] = {
};
#endif
-#ifdef CONFIG_ARCH_OMAP1510
+#ifdef CONFIG_ARCH_OMAP15XX
static struct omap_irq_bank omap1510_irq_banks[] = {
{ .base_reg = OMAP_IH1_BASE, .trigger_map = 0xb3febfff },
{ .base_reg = OMAP_IH2_BASE, .trigger_map = 0xffbfffed },
};
+static struct omap_irq_bank omap310_irq_banks[] = {
+ { .base_reg = OMAP_IH1_BASE, .trigger_map = 0xb3faefc3 },
+ { .base_reg = OMAP_IH2_BASE, .trigger_map = 0x65b3c061 },
+};
#endif
#if defined(CONFIG_ARCH_OMAP16XX)
@@ -181,11 +186,15 @@ void __init omap_init_irq(void)
irq_bank_count = ARRAY_SIZE(omap730_irq_banks);
}
#endif
-#ifdef CONFIG_ARCH_OMAP1510
+#ifdef CONFIG_ARCH_OMAP15XX
if (cpu_is_omap1510()) {
irq_banks = omap1510_irq_banks;
irq_bank_count = ARRAY_SIZE(omap1510_irq_banks);
}
+ if (cpu_is_omap310()) {
+ irq_banks = omap310_irq_banks;
+ irq_bank_count = ARRAY_SIZE(omap310_irq_banks);
+ }
#endif
#if defined(CONFIG_ARCH_OMAP16XX)
if (cpu_is_omap16xx()) {
@@ -226,9 +235,11 @@ void __init omap_init_irq(void)
}
/* Unmask level 2 handler */
- if (cpu_is_omap730()) {
+
+ if (cpu_is_omap730())
omap_unmask_irq(INT_730_IH2_IRQ);
- } else {
- omap_unmask_irq(INT_IH2_IRQ);
- }
+ else if (cpu_is_omap1510())
+ omap_unmask_irq(INT_1510_IH2_IRQ);
+ else if (cpu_is_omap16xx())
+ omap_unmask_irq(INT_1610_IH2_IRQ);
}
diff --git a/arch/arm/mach-omap1/leds-h2p2-debug.c b/arch/arm/mach-omap1/leds-h2p2-debug.c
index be283cda63dd..650650815915 100644
--- a/arch/arm/mach-omap1/leds-h2p2-debug.c
+++ b/arch/arm/mach-omap1/leds-h2p2-debug.c
@@ -13,12 +13,12 @@
#include <linux/init.h>
#include <linux/kernel_stat.h>
#include <linux/sched.h>
-#include <linux/version.h>
#include <asm/io.h>
#include <asm/hardware.h>
#include <asm/leds.h>
#include <asm/system.h>
+#include <asm/mach-types.h>
#include <asm/arch/fpga.h>
#include <asm/arch/gpio.h>
@@ -64,14 +64,19 @@ void h2p2_dbg_leds_event(led_event_t evt)
case led_stop:
case led_halted:
/* all leds off during suspend or shutdown */
- omap_set_gpio_dataout(GPIO_TIMER, 0);
- omap_set_gpio_dataout(GPIO_IDLE, 0);
+
+ if (! machine_is_omap_perseus2()) {
+ omap_set_gpio_dataout(GPIO_TIMER, 0);
+ omap_set_gpio_dataout(GPIO_IDLE, 0);
+ }
+
__raw_writew(~0, &fpga->leds);
led_state &= ~LED_STATE_ENABLED;
if (evt == led_halted) {
iounmap(fpga);
fpga = NULL;
}
+
goto done;
case led_claim:
@@ -86,18 +91,37 @@ void h2p2_dbg_leds_event(led_event_t evt)
#ifdef CONFIG_LEDS_TIMER
case led_timer:
led_state ^= LED_TIMER_ON;
- omap_set_gpio_dataout(GPIO_TIMER, led_state & LED_TIMER_ON);
- goto done;
+
+ if (machine_is_omap_perseus2())
+ hw_led_state ^= H2P2_DBG_FPGA_P2_LED_TIMER;
+ else {
+ omap_set_gpio_dataout(GPIO_TIMER, led_state & LED_TIMER_ON);
+ goto done;
+ }
+
+ break;
#endif
#ifdef CONFIG_LEDS_CPU
case led_idle_start:
- omap_set_gpio_dataout(GPIO_IDLE, 1);
- goto done;
+ if (machine_is_omap_perseus2())
+ hw_led_state |= H2P2_DBG_FPGA_P2_LED_IDLE;
+ else {
+ omap_set_gpio_dataout(GPIO_IDLE, 1);
+ goto done;
+ }
+
+ break;
case led_idle_end:
- omap_set_gpio_dataout(GPIO_IDLE, 0);
- goto done;
+ if (machine_is_omap_perseus2())
+ hw_led_state &= ~H2P2_DBG_FPGA_P2_LED_IDLE;
+ else {
+ omap_set_gpio_dataout(GPIO_IDLE, 0);
+ goto done;
+ }
+
+ break;
#endif
case led_green_on:
@@ -136,7 +160,7 @@ void h2p2_dbg_leds_event(led_event_t evt)
/*
* Actually burn the LEDs
*/
- if (led_state & LED_STATE_CLAIMED)
+ if (led_state & LED_STATE_ENABLED)
__raw_writew(~hw_led_state, &fpga->leds);
done:
diff --git a/arch/arm/mach-omap1/leds.c b/arch/arm/mach-omap1/leds.c
index 5c6b1bb6e722..3f9dcac4fd41 100644
--- a/arch/arm/mach-omap1/leds.c
+++ b/arch/arm/mach-omap1/leds.c
@@ -33,7 +33,6 @@ omap_leds_init(void)
if (machine_is_omap_h2()
|| machine_is_omap_h3()
- || machine_is_omap_perseus2()
#ifdef CONFIG_OMAP_OSK_MISTRAL
|| machine_is_omap_osk()
#endif
diff --git a/arch/arm/mach-omap1/mux.c b/arch/arm/mach-omap1/mux.c
new file mode 100644
index 000000000000..d4b8d624e742
--- /dev/null
+++ b/arch/arm/mach-omap1/mux.c
@@ -0,0 +1,289 @@
+/*
+ * linux/arch/arm/mach-omap1/mux.c
+ *
+ * OMAP1 pin multiplexing configurations
+ *
+ * Copyright (C) 2003 - 2005 Nokia Corporation
+ *
+ * Written by Tony Lindgren <tony.lindgren@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * 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/config.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <asm/system.h>
+#include <asm/io.h>
+#include <linux/spinlock.h>
+
+#include <asm/arch/mux.h>
+
+#ifdef CONFIG_OMAP_MUX
+
+#ifdef CONFIG_ARCH_OMAP730
+struct pin_config __initdata_or_module omap730_pins[] = {
+MUX_CFG_730("E2_730_KBR0", 12, 21, 0, 0, 20, 1, NA, 0, 0)
+MUX_CFG_730("J7_730_KBR1", 12, 25, 0, 0, 24, 1, NA, 0, 0)
+MUX_CFG_730("E1_730_KBR2", 12, 29, 0, 0, 28, 1, NA, 0, 0)
+MUX_CFG_730("F3_730_KBR3", 13, 1, 0, 0, 0, 1, NA, 0, 0)
+MUX_CFG_730("D2_730_KBR4", 13, 5, 0, 0, 4, 1, NA, 0, 0)
+MUX_CFG_730("C2_730_KBC0", 13, 9, 0, 0, 8, 1, NA, 0, 0)
+MUX_CFG_730("D3_730_KBC1", 13, 13, 0, 0, 12, 1, NA, 0, 0)
+MUX_CFG_730("E4_730_KBC2", 13, 17, 0, 0, 16, 1, NA, 0, 0)
+MUX_CFG_730("F4_730_KBC3", 13, 21, 0, 0, 20, 1, NA, 0, 0)
+MUX_CFG_730("E3_730_KBC4", 13, 25, 0, 0, 24, 1, NA, 0, 0)
+};
+#endif
+
+#if defined(CONFIG_ARCH_OMAP15XX) || defined(CONFIG_ARCH_OMAP16XX)
+struct pin_config __initdata_or_module omap1xxx_pins[] = {
+/*
+ * description mux mode mux pull pull pull pu_pd pu dbg
+ * reg offset mode reg bit ena reg
+ */
+MUX_CFG("UART1_TX", 9, 21, 1, 2, 3, 0, NA, 0, 0)
+MUX_CFG("UART1_RTS", 9, 12, 1, 2, 0, 0, NA, 0, 0)
+
+/* UART2 (COM_UART_GATING), conflicts with USB2 */
+MUX_CFG("UART2_TX", C, 27, 1, 3, 3, 0, NA, 0, 0)
+MUX_CFG("UART2_RX", C, 18, 0, 3, 1, 1, NA, 0, 0)
+MUX_CFG("UART2_CTS", C, 21, 0, 3, 1, 1, NA, 0, 0)
+MUX_CFG("UART2_RTS", C, 24, 1, 3, 2, 0, NA, 0, 0)
+
+/* UART3 (GIGA_UART_GATING) */
+MUX_CFG("UART3_TX", 6, 0, 1, 0, 30, 0, NA, 0, 0)
+MUX_CFG("UART3_RX", 6, 3, 0, 0, 31, 1, NA, 0, 0)
+MUX_CFG("UART3_CTS", 5, 12, 2, 0, 24, 0, NA, 0, 0)
+MUX_CFG("UART3_RTS", 5, 15, 2, 0, 25, 0, NA, 0, 0)
+MUX_CFG("UART3_CLKREQ", 9, 27, 0, 2, 5, 0, NA, 0, 0)
+MUX_CFG("UART3_BCLK", A, 0, 0, 2, 6, 0, NA, 0, 0)
+MUX_CFG("Y15_1610_UART3_RTS", A, 0, 1, 2, 6, 0, NA, 0, 0)
+
+/* PWT & PWL, conflicts with UART3 */
+MUX_CFG("PWT", 6, 0, 2, 0, 30, 0, NA, 0, 0)
+MUX_CFG("PWL", 6, 3, 1, 0, 31, 1, NA, 0, 0)
+
+/* USB internal master generic */
+MUX_CFG("R18_USB_VBUS", 7, 9, 2, 1, 11, 0, NA, 0, 1)
+MUX_CFG("R18_1510_USB_GPIO0", 7, 9, 0, 1, 11, 1, NA, 0, 1)
+/* works around erratum: W4_USB_PUEN and W4_USB_PUDIS are switched! */
+MUX_CFG("W4_USB_PUEN", D, 3, 3, 3, 5, 1, NA, 0, 1)
+MUX_CFG("W4_USB_CLKO", D, 3, 1, 3, 5, 0, NA, 0, 1)
+MUX_CFG("W4_USB_HIGHZ", D, 3, 4, 3, 5, 0, 3, 0, 1)
+MUX_CFG("W4_GPIO58", D, 3, 7, 3, 5, 0, 3, 0, 1)
+
+/* USB1 master */
+MUX_CFG("USB1_SUSP", 8, 27, 2, 1, 27, 0, NA, 0, 1)
+MUX_CFG("USB1_SE0", 9, 0, 2, 1, 28, 0, NA, 0, 1)
+MUX_CFG("W13_1610_USB1_SE0", 9, 0, 4, 1, 28, 0, NA, 0, 1)
+MUX_CFG("USB1_TXEN", 9, 3, 2, 1, 29, 0, NA, 0, 1)
+MUX_CFG("USB1_TXD", 9, 24, 1, 2, 4, 0, NA, 0, 1)
+MUX_CFG("USB1_VP", A, 3, 1, 2, 7, 0, NA, 0, 1)
+MUX_CFG("USB1_VM", A, 6, 1, 2, 8, 0, NA, 0, 1)
+MUX_CFG("USB1_RCV", A, 9, 1, 2, 9, 0, NA, 0, 1)
+MUX_CFG("USB1_SPEED", A, 12, 2, 2, 10, 0, NA, 0, 1)
+MUX_CFG("R13_1610_USB1_SPEED", A, 12, 5, 2, 10, 0, NA, 0, 1)
+MUX_CFG("R13_1710_USB1_SEO", A, 12, 5, 2, 10, 0, NA, 0, 1)
+
+/* USB2 master */
+MUX_CFG("USB2_SUSP", B, 3, 1, 2, 17, 0, NA, 0, 1)
+MUX_CFG("USB2_VP", B, 6, 1, 2, 18, 0, NA, 0, 1)
+MUX_CFG("USB2_TXEN", B, 9, 1, 2, 19, 0, NA, 0, 1)
+MUX_CFG("USB2_VM", C, 18, 1, 3, 0, 0, NA, 0, 1)
+MUX_CFG("USB2_RCV", C, 21, 1, 3, 1, 0, NA, 0, 1)
+MUX_CFG("USB2_SE0", C, 24, 2, 3, 2, 0, NA, 0, 1)
+MUX_CFG("USB2_TXD", C, 27, 2, 3, 3, 0, NA, 0, 1)
+
+/* OMAP-1510 GPIO */
+MUX_CFG("R18_1510_GPIO0", 7, 9, 0, 1, 11, 1, 0, 0, 1)
+MUX_CFG("R19_1510_GPIO1", 7, 6, 0, 1, 10, 1, 0, 0, 1)
+MUX_CFG("M14_1510_GPIO2", 7, 3, 0, 1, 9, 1, 0, 0, 1)
+
+/* OMAP1610 GPIO */
+MUX_CFG("P18_1610_GPIO3", 7, 0, 0, 1, 8, 0, NA, 0, 1)
+MUX_CFG("Y15_1610_GPIO17", A, 0, 7, 2, 6, 0, NA, 0, 1)
+
+/* OMAP-1710 GPIO */
+MUX_CFG("R18_1710_GPIO0", 7, 9, 0, 1, 11, 1, 1, 1, 1)
+MUX_CFG("V2_1710_GPIO10", F, 27, 1, 4, 3, 1, 4, 1, 1)
+MUX_CFG("N21_1710_GPIO14", 6, 9, 0, 1, 1, 1, 1, 1, 1)
+MUX_CFG("W15_1710_GPIO40", 9, 27, 7, 2, 5, 1, 2, 1, 1)
+
+/* MPUIO */
+MUX_CFG("MPUIO2", 7, 18, 0, 1, 14, 1, NA, 0, 1)
+MUX_CFG("N15_1610_MPUIO2", 7, 18, 0, 1, 14, 1, 1, 0, 1)
+MUX_CFG("MPUIO4", 7, 15, 0, 1, 13, 1, NA, 0, 1)
+MUX_CFG("MPUIO5", 7, 12, 0, 1, 12, 1, NA, 0, 1)
+
+MUX_CFG("T20_1610_MPUIO5", 7, 12, 0, 1, 12, 0, 3, 0, 1)
+MUX_CFG("W11_1610_MPUIO6", 10, 15, 2, 3, 8, 0, 3, 0, 1)
+MUX_CFG("V10_1610_MPUIO7", A, 24, 2, 2, 14, 0, 2, 0, 1)
+MUX_CFG("W11_1610_MPUIO9", 10, 15, 1, 3, 8, 0, 3, 0, 1)
+MUX_CFG("V10_1610_MPUIO10", A, 24, 1, 2, 14, 0, 2, 0, 1)
+MUX_CFG("W10_1610_MPUIO11", A, 18, 2, 2, 11, 0, 2, 0, 1)
+MUX_CFG("E20_1610_MPUIO13", 3, 21, 1, 0, 7, 0, 0, 0, 1)
+MUX_CFG("U20_1610_MPUIO14", 9, 6, 6, 0, 30, 0, 0, 0, 1)
+MUX_CFG("E19_1610_MPUIO15", 3, 18, 1, 0, 6, 0, 0, 0, 1)
+
+/* MCBSP2 */
+MUX_CFG("MCBSP2_CLKR", C, 6, 0, 2, 27, 1, NA, 0, 1)
+MUX_CFG("MCBSP2_CLKX", C, 9, 0, 2, 29, 1, NA, 0, 1)
+MUX_CFG("MCBSP2_DR", C, 0, 0, 2, 26, 1, NA, 0, 1)
+MUX_CFG("MCBSP2_DX", C, 15, 0, 2, 31, 1, NA, 0, 1)
+MUX_CFG("MCBSP2_FSR", C, 12, 0, 2, 30, 1, NA, 0, 1)
+MUX_CFG("MCBSP2_FSX", C, 3, 0, 2, 27, 1, NA, 0, 1)
+
+/* MCBSP3 NOTE: Mode must 1 for clock */
+MUX_CFG("MCBSP3_CLKX", 9, 3, 1, 1, 29, 0, NA, 0, 1)
+
+/* Misc ballouts */
+MUX_CFG("BALLOUT_V8_ARMIO3", B, 18, 0, 2, 25, 1, NA, 0, 1)
+MUX_CFG("N20_HDQ", 6, 18, 1, 1, 4, 0, 1, 4, 0)
+
+/* OMAP-1610 MMC2 */
+MUX_CFG("W8_1610_MMC2_DAT0", B, 21, 6, 2, 23, 1, 2, 1, 1)
+MUX_CFG("V8_1610_MMC2_DAT1", B, 27, 6, 2, 25, 1, 2, 1, 1)
+MUX_CFG("W15_1610_MMC2_DAT2", 9, 12, 6, 2, 5, 1, 2, 1, 1)
+MUX_CFG("R10_1610_MMC2_DAT3", B, 18, 6, 2, 22, 1, 2, 1, 1)
+MUX_CFG("Y10_1610_MMC2_CLK", B, 3, 6, 2, 17, 0, 2, 0, 1)
+MUX_CFG("Y8_1610_MMC2_CMD", B, 24, 6, 2, 24, 1, 2, 1, 1)
+MUX_CFG("V9_1610_MMC2_CMDDIR", B, 12, 6, 2, 20, 0, 2, 1, 1)
+MUX_CFG("V5_1610_MMC2_DATDIR0", B, 15, 6, 2, 21, 0, 2, 1, 1)
+MUX_CFG("W19_1610_MMC2_DATDIR1", 8, 15, 6, 1, 23, 0, 1, 1, 1)
+MUX_CFG("R18_1610_MMC2_CLKIN", 7, 9, 6, 1, 11, 0, 1, 11, 1)
+
+/* OMAP-1610 External Trace Interface */
+MUX_CFG("M19_1610_ETM_PSTAT0", 5, 27, 1, 0, 29, 0, 0, 0, 1)
+MUX_CFG("L15_1610_ETM_PSTAT1", 5, 24, 1, 0, 28, 0, 0, 0, 1)
+MUX_CFG("L18_1610_ETM_PSTAT2", 5, 21, 1, 0, 27, 0, 0, 0, 1)
+MUX_CFG("L19_1610_ETM_D0", 5, 18, 1, 0, 26, 0, 0, 0, 1)
+MUX_CFG("J19_1610_ETM_D6", 5, 0, 1, 0, 20, 0, 0, 0, 1)
+MUX_CFG("J18_1610_ETM_D7", 5, 27, 1, 0, 19, 0, 0, 0, 1)
+
+/* OMAP16XX GPIO */
+MUX_CFG("P20_1610_GPIO4", 6, 27, 0, 1, 7, 0, 1, 1, 1)
+MUX_CFG("V9_1610_GPIO7", B, 12, 1, 2, 20, 0, 2, 1, 1)
+MUX_CFG("W8_1610_GPIO9", B, 21, 0, 2, 23, 0, 2, 1, 1)
+MUX_CFG("N20_1610_GPIO11", 6, 18, 0, 1, 4, 0, 1, 1, 1)
+MUX_CFG("N19_1610_GPIO13", 6, 12, 0, 1, 2, 0, 1, 1, 1)
+MUX_CFG("P10_1610_GPIO22", C, 0, 7, 2, 26, 0, 2, 1, 1)
+MUX_CFG("V5_1610_GPIO24", B, 15, 7, 2, 21, 0, 2, 1, 1)
+MUX_CFG("AA20_1610_GPIO_41", 9, 9, 7, 1, 31, 0, 1, 1, 1)
+MUX_CFG("W19_1610_GPIO48", 8, 15, 7, 1, 23, 1, 1, 0, 1)
+MUX_CFG("M7_1610_GPIO62", 10, 0, 0, 4, 24, 0, 4, 0, 1)
+MUX_CFG("V14_16XX_GPIO37", 9, 18, 7, 2, 2, 0, 2, 2, 0)
+MUX_CFG("R9_16XX_GPIO18", C, 18, 7, 3, 0, 0, 3, 0, 0)
+MUX_CFG("L14_16XX_GPIO49", 6, 3, 7, 0, 31, 0, 0, 31, 0)
+
+/* OMAP-1610 uWire */
+MUX_CFG("V19_1610_UWIRE_SCLK", 8, 6, 0, 1, 20, 0, 1, 1, 1)
+MUX_CFG("U18_1610_UWIRE_SDI", 8, 0, 0, 1, 18, 0, 1, 1, 1)
+MUX_CFG("W21_1610_UWIRE_SDO", 8, 3, 0, 1, 19, 0, 1, 1, 1)
+MUX_CFG("N14_1610_UWIRE_CS0", 8, 9, 1, 1, 21, 0, 1, 1, 1)
+MUX_CFG("P15_1610_UWIRE_CS3", 8, 12, 1, 1, 22, 0, 1, 1, 1)
+MUX_CFG("N15_1610_UWIRE_CS1", 7, 18, 2, 1, 14, 0, NA, 0, 1)
+
+/* OMAP-1610 Flash */
+MUX_CFG("L3_1610_FLASH_CS2B_OE",10, 6, 1, NA, 0, 0, NA, 0, 1)
+MUX_CFG("M8_1610_FLASH_CS2B_WE",10, 3, 1, NA, 0, 0, NA, 0, 1)
+
+/* First MMC interface, same on 1510, 1610 and 1710 */
+MUX_CFG("MMC_CMD", A, 27, 0, 2, 15, 1, 2, 1, 1)
+MUX_CFG("MMC_DAT1", A, 24, 0, 2, 14, 1, 2, 1, 1)
+MUX_CFG("MMC_DAT2", A, 18, 0, 2, 12, 1, 2, 1, 1)
+MUX_CFG("MMC_DAT0", B, 0, 0, 2, 16, 1, 2, 1, 1)
+MUX_CFG("MMC_CLK", A, 21, 0, NA, 0, 0, NA, 0, 1)
+MUX_CFG("MMC_DAT3", 10, 15, 0, 3, 8, 1, 3, 1, 1)
+MUX_CFG("M15_1710_MMC_CLKI", 6, 21, 2, 0, 0, 0, NA, 0, 1)
+MUX_CFG("P19_1710_MMC_CMDDIR", 6, 24, 6, 0, 0, 0, NA, 0, 1)
+MUX_CFG("P20_1710_MMC_DATDIR0", 6, 27, 5, 0, 0, 0, NA, 0, 1)
+
+/* OMAP-1610 USB0 alternate configuration */
+MUX_CFG("W9_USB0_TXEN", B, 9, 5, 2, 19, 0, 2, 0, 1)
+MUX_CFG("AA9_USB0_VP", B, 6, 5, 2, 18, 0, 2, 0, 1)
+MUX_CFG("Y5_USB0_RCV", C, 21, 5, 3, 1, 0, 1, 0, 1)
+MUX_CFG("R9_USB0_VM", C, 18, 5, 3, 0, 0, 3, 0, 1)
+MUX_CFG("V6_USB0_TXD", C, 27, 5, 3, 3, 0, 3, 0, 1)
+MUX_CFG("W5_USB0_SE0", C, 24, 5, 3, 2, 0, 3, 0, 1)
+MUX_CFG("V9_USB0_SPEED", B, 12, 5, 2, 20, 0, 2, 0, 1)
+MUX_CFG("Y10_USB0_SUSP", B, 3, 5, 2, 17, 0, 2, 0, 1)
+
+/* USB2 interface */
+MUX_CFG("W9_USB2_TXEN", B, 9, 1, NA, 0, 0, NA, 0, 1)
+MUX_CFG("AA9_USB2_VP", B, 6, 1, NA, 0, 0, NA, 0, 1)
+MUX_CFG("Y5_USB2_RCV", C, 21, 1, NA, 0, 0, NA, 0, 1)
+MUX_CFG("R9_USB2_VM", C, 18, 1, NA, 0, 0, NA, 0, 1)
+MUX_CFG("V6_USB2_TXD", C, 27, 2, NA, 0, 0, NA, 0, 1)
+MUX_CFG("W5_USB2_SE0", C, 24, 2, NA, 0, 0, NA, 0, 1)
+
+/* 16XX UART */
+MUX_CFG("R13_1610_UART1_TX", A, 12, 6, 2, 10, 0, 2, 10, 1)
+MUX_CFG("V14_16XX_UART1_RX", 9, 18, 0, 2, 2, 0, 2, 2, 1)
+MUX_CFG("R14_1610_UART1_CTS", 9, 15, 0, 2, 1, 0, 2, 1, 1)
+MUX_CFG("AA15_1610_UART1_RTS", 9, 12, 1, 2, 0, 0, 2, 0, 1)
+MUX_CFG("R9_16XX_UART2_RX", C, 18, 0, 3, 0, 0, 3, 0, 1)
+MUX_CFG("L14_16XX_UART3_RX", 6, 3, 0, 0, 31, 0, 0, 31, 1)
+
+/* I2C interface */
+MUX_CFG("I2C_SCL", 7, 24, 0, NA, 0, 0, NA, 0, 0)
+MUX_CFG("I2C_SDA", 7, 27, 0, NA, 0, 0, NA, 0, 0)
+
+/* Keypad */
+MUX_CFG("F18_1610_KBC0", 3, 15, 0, 0, 5, 1, 0, 0, 0)
+MUX_CFG("D20_1610_KBC1", 3, 12, 0, 0, 4, 1, 0, 0, 0)
+MUX_CFG("D19_1610_KBC2", 3, 9, 0, 0, 3, 1, 0, 0, 0)
+MUX_CFG("E18_1610_KBC3", 3, 6, 0, 0, 2, 1, 0, 0, 0)
+MUX_CFG("C21_1610_KBC4", 3, 3, 0, 0, 1, 1, 0, 0, 0)
+MUX_CFG("G18_1610_KBR0", 4, 0, 0, 0, 10, 1, 0, 1, 0)
+MUX_CFG("F19_1610_KBR1", 3, 27, 0, 0, 9, 1, 0, 1, 0)
+MUX_CFG("H14_1610_KBR2", 3, 24, 0, 0, 8, 1, 0, 1, 0)
+MUX_CFG("E20_1610_KBR3", 3, 21, 0, 0, 7, 1, 0, 1, 0)
+MUX_CFG("E19_1610_KBR4", 3, 18, 0, 0, 6, 1, 0, 1, 0)
+MUX_CFG("N19_1610_KBR5", 6, 12, 1, 1, 2, 1, 1, 1, 0)
+
+/* Power management */
+MUX_CFG("T20_1610_LOW_PWR", 7, 12, 1, NA, 0, 0, NA, 0, 0)
+
+/* MCLK Settings */
+MUX_CFG("V5_1710_MCLK_ON", B, 15, 0, NA, 0, 0, NA, 0, 0)
+MUX_CFG("V5_1710_MCLK_OFF", B, 15, 6, NA, 0, 0, NA, 0, 0)
+MUX_CFG("R10_1610_MCLK_ON", B, 18, 0, NA, 22, 0, NA, 1, 0)
+MUX_CFG("R10_1610_MCLK_OFF", B, 18, 6, 2, 22, 1, 2, 1, 1)
+
+/* CompactFlash controller, conflicts with MMC1 */
+MUX_CFG("P11_1610_CF_CD2", A, 27, 3, 2, 15, 1, 2, 1, 1)
+MUX_CFG("R11_1610_CF_IOIS16", B, 0, 3, 2, 16, 1, 2, 1, 1)
+MUX_CFG("V10_1610_CF_IREQ", A, 24, 3, 2, 14, 0, 2, 0, 1)
+MUX_CFG("W10_1610_CF_RESET", A, 18, 3, 2, 12, 1, 2, 1, 1)
+MUX_CFG("W11_1610_CF_CD1", 10, 15, 3, 3, 8, 1, 3, 1, 1)
+};
+#endif /* CONFIG_ARCH_OMAP15XX || CONFIG_ARCH_OMAP16XX */
+
+int __init omap1_mux_init(void)
+{
+
+#ifdef CONFIG_ARCH_OMAP730
+ omap_mux_register(omap730_pins, ARRAY_SIZE(omap730_pins));
+#endif
+
+#if defined(CONFIG_ARCH_OMAP15XX) || defined(CONFIG_ARCH_OMAP16XX)
+ omap_mux_register(omap1xxx_pins, ARRAY_SIZE(omap1xxx_pins));
+#endif
+
+ return 0;
+}
+
+#endif
diff --git a/arch/arm/mach-omap1/serial.c b/arch/arm/mach-omap1/serial.c
index 40c4f7c40e73..6810cfb84462 100644
--- a/arch/arm/mach-omap1/serial.c
+++ b/arch/arm/mach-omap1/serial.c
@@ -109,9 +109,10 @@ static struct platform_device serial_device = {
* By default UART2 does not work on Innovator-1510 if you have
* USB OHCI enabled. To use UART2, you must disable USB2 first.
*/
-void __init omap_serial_init(int ports[OMAP_MAX_NR_PORTS])
+void __init omap_serial_init(void)
{
int i;
+ const struct omap_uart_config *info;
if (cpu_is_omap730()) {
serial_platform_data[0].regshift = 0;
@@ -126,10 +127,14 @@ void __init omap_serial_init(int ports[OMAP_MAX_NR_PORTS])
serial_platform_data[2].uartclk = OMAP1510_BASE_BAUD * 16;
}
+ info = omap_get_config(OMAP_TAG_UART, struct omap_uart_config);
+ if (info == NULL)
+ return;
+
for (i = 0; i < OMAP_MAX_NR_PORTS; i++) {
unsigned char reg;
- if (ports[i] == 0) {
+ if (!((1 << i) & info->enabled_uarts)) {
serial_platform_data[i].membase = NULL;
serial_platform_data[i].mapbase = 0;
continue;
diff --git a/arch/arm/mach-omap1/time.c b/arch/arm/mach-omap1/time.c
index 191a9b1ee9b7..cdbf4d7620c6 100644
--- a/arch/arm/mach-omap1/time.c
+++ b/arch/arm/mach-omap1/time.c
@@ -226,8 +226,8 @@ unsigned long long sched_clock(void)
#ifdef CONFIG_OMAP_32K_TIMER
-#ifdef CONFIG_ARCH_OMAP1510
-#error OMAP 32KHz timer does not currently work on 1510!
+#ifdef CONFIG_ARCH_OMAP15XX
+#error OMAP 32KHz timer does not currently work on 15XX!
#endif
/*
diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig
new file mode 100644
index 000000000000..578880943cf2
--- /dev/null
+++ b/arch/arm/mach-omap2/Kconfig
@@ -0,0 +1,22 @@
+comment "OMAP Core Type"
+ depends on ARCH_OMAP2
+
+config ARCH_OMAP24XX
+ bool "OMAP24xx Based System"
+ depends on ARCH_OMAP2
+
+config ARCH_OMAP2420
+ bool "OMAP2420 support"
+ depends on ARCH_OMAP24XX
+
+comment "OMAP Board Type"
+ depends on ARCH_OMAP2
+
+config MACH_OMAP_GENERIC
+ bool "Generic OMAP board"
+ depends on ARCH_OMAP2 && ARCH_OMAP24XX
+
+config MACH_OMAP_H4
+ bool "OMAP 2420 H4 board"
+ depends on ARCH_OMAP2 && ARCH_OMAP24XX
+
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
new file mode 100644
index 000000000000..42041166435c
--- /dev/null
+++ b/arch/arm/mach-omap2/Makefile
@@ -0,0 +1,13 @@
+#
+# Makefile for the linux kernel.
+#
+
+# Common support
+obj-y := irq.o id.o io.o sram-fn.o clock.o mux.o devices.o serial.o
+
+obj-$(CONFIG_OMAP_MPU_TIMER) += timer-gp.o
+
+# Specific board support
+obj-$(CONFIG_MACH_OMAP_GENERIC) += board-generic.o
+obj-$(CONFIG_MACH_OMAP_H4) += board-h4.o
+
diff --git a/arch/arm/mach-omap2/Makefile.boot b/arch/arm/mach-omap2/Makefile.boot
new file mode 100644
index 000000000000..565aff7f37a9
--- /dev/null
+++ b/arch/arm/mach-omap2/Makefile.boot
@@ -0,0 +1,3 @@
+ zreladdr-y := 0x80008000
+params_phys-y := 0x80000100
+initrd_phys-y := 0x80800000
diff --git a/arch/arm/mach-omap2/board-generic.c b/arch/arm/mach-omap2/board-generic.c
new file mode 100644
index 000000000000..c602e7a3d93e
--- /dev/null
+++ b/arch/arm/mach-omap2/board-generic.c
@@ -0,0 +1,80 @@
+/*
+ * linux/arch/arm/mach-omap/omap2/board-generic.c
+ *
+ * Copyright (C) 2005 Nokia Corporation
+ * Author: Paul Mundt <paul.mundt@nokia.com>
+ *
+ * Modified from mach-omap/omap1/board-generic.c
+ *
+ * Code for generic OMAP2 board. Should work on many OMAP2 systems where
+ * the bootloader passes the board-specific data to the kernel.
+ * Do not put any board specific code to this file; create a new machine
+ * type if you need custom low-level initializations.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/device.h>
+
+#include <asm/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <asm/arch/gpio.h>
+#include <asm/arch/mux.h>
+#include <asm/arch/usb.h>
+#include <asm/arch/board.h>
+#include <asm/arch/common.h>
+
+static void __init omap_generic_init_irq(void)
+{
+ omap_init_irq();
+}
+
+static struct omap_uart_config generic_uart_config __initdata = {
+ .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)),
+};
+
+static struct omap_mmc_config generic_mmc_config __initdata = {
+ .mmc [0] = {
+ .enabled = 0,
+ .wire4 = 0,
+ .wp_pin = -1,
+ .power_pin = -1,
+ .switch_pin = -1,
+ },
+};
+
+static struct omap_board_config_kernel generic_config[] = {
+ { OMAP_TAG_UART, &generic_uart_config },
+ { OMAP_TAG_MMC, &generic_mmc_config },
+};
+
+static void __init omap_generic_init(void)
+{
+ omap_board_config = generic_config;
+ omap_board_config_size = ARRAY_SIZE(generic_config);
+ omap_serial_init();
+}
+
+static void __init omap_generic_map_io(void)
+{
+ omap_map_common_io();
+}
+
+MACHINE_START(OMAP_GENERIC, "Generic OMAP24xx")
+ /* Maintainer: Paul Mundt <paul.mundt@nokia.com> */
+ .phys_ram = 0x80000000,
+ .phys_io = 0x48000000,
+ .io_pg_offst = ((0xd8000000) >> 18) & 0xfffc,
+ .boot_params = 0x80000100,
+ .map_io = omap_generic_map_io,
+ .init_irq = omap_generic_init_irq,
+ .init_machine = omap_generic_init,
+ .timer = &omap_timer,
+MACHINE_END
diff --git a/arch/arm/mach-omap2/board-h4.c b/arch/arm/mach-omap2/board-h4.c
new file mode 100644
index 000000000000..f2554469a76a
--- /dev/null
+++ b/arch/arm/mach-omap2/board-h4.c
@@ -0,0 +1,197 @@
+/*
+ * linux/arch/arm/mach-omap/omap2/board-h4.c
+ *
+ * Copyright (C) 2005 Nokia Corporation
+ * Author: Paul Mundt <paul.mundt@nokia.com>
+ *
+ * Modified from mach-omap/omap1/board-generic.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/delay.h>
+
+#include <asm/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/flash.h>
+
+#include <asm/arch/gpio.h>
+#include <asm/arch/mux.h>
+#include <asm/arch/usb.h>
+#include <asm/arch/board.h>
+#include <asm/arch/common.h>
+#include <asm/arch/prcm.h>
+
+#include <asm/io.h>
+#include <asm/delay.h>
+
+static struct mtd_partition h4_partitions[] = {
+ /* bootloader (U-Boot, etc) in first sector */
+ {
+ .name = "bootloader",
+ .offset = 0,
+ .size = SZ_128K,
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ },
+ /* bootloader params in the next sector */
+ {
+ .name = "params",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_128K,
+ .mask_flags = 0,
+ },
+ /* kernel */
+ {
+ .name = "kernel",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_2M,
+ .mask_flags = 0
+ },
+ /* file system */
+ {
+ .name = "filesystem",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ .mask_flags = 0
+ }
+};
+
+static struct flash_platform_data h4_flash_data = {
+ .map_name = "cfi_probe",
+ .width = 2,
+ .parts = h4_partitions,
+ .nr_parts = ARRAY_SIZE(h4_partitions),
+};
+
+static struct resource h4_flash_resource = {
+ .start = H4_CS0_BASE,
+ .end = H4_CS0_BASE + SZ_64M - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device h4_flash_device = {
+ .name = "omapflash",
+ .id = 0,
+ .dev = {
+ .platform_data = &h4_flash_data,
+ },
+ .num_resources = 1,
+ .resource = &h4_flash_resource,
+};
+
+static struct resource h4_smc91x_resources[] = {
+ [0] = {
+ .start = OMAP24XX_ETHR_START, /* Physical */
+ .end = OMAP24XX_ETHR_START + 0xf,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = OMAP_GPIO_IRQ(OMAP24XX_ETHR_GPIO_IRQ),
+ .end = OMAP_GPIO_IRQ(OMAP24XX_ETHR_GPIO_IRQ),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device h4_smc91x_device = {
+ .name = "smc91x",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(h4_smc91x_resources),
+ .resource = h4_smc91x_resources,
+};
+
+static struct platform_device *h4_devices[] __initdata = {
+ &h4_smc91x_device,
+ &h4_flash_device,
+};
+
+static inline void __init h4_init_smc91x(void)
+{
+ /* Make sure CS1 timings are correct */
+ GPMC_CONFIG1_1 = 0x00011200;
+ GPMC_CONFIG2_1 = 0x001f1f01;
+ GPMC_CONFIG3_1 = 0x00080803;
+ GPMC_CONFIG4_1 = 0x1c091c09;
+ GPMC_CONFIG5_1 = 0x041f1f1f;
+ GPMC_CONFIG6_1 = 0x000004c4;
+ GPMC_CONFIG7_1 = 0x00000f40 | (0x08000000 >> 24);
+ udelay(100);
+
+ omap_cfg_reg(M15_24XX_GPIO92);
+ if (omap_request_gpio(OMAP24XX_ETHR_GPIO_IRQ) < 0) {
+ printk(KERN_ERR "Failed to request GPIO%d for smc91x IRQ\n",
+ OMAP24XX_ETHR_GPIO_IRQ);
+ return;
+ }
+ omap_set_gpio_direction(OMAP24XX_ETHR_GPIO_IRQ, 1);
+}
+
+static void __init omap_h4_init_irq(void)
+{
+ omap_init_irq();
+ omap_gpio_init();
+ h4_init_smc91x();
+}
+
+static struct omap_uart_config h4_uart_config __initdata = {
+ .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)),
+};
+
+static struct omap_mmc_config h4_mmc_config __initdata = {
+ .mmc [0] = {
+ .enabled = 1,
+ .wire4 = 1,
+ .wp_pin = -1,
+ .power_pin = -1,
+ .switch_pin = -1,
+ },
+};
+
+static struct omap_lcd_config h4_lcd_config __initdata = {
+ .panel_name = "h4",
+ .ctrl_name = "internal",
+};
+
+static struct omap_board_config_kernel h4_config[] = {
+ { OMAP_TAG_UART, &h4_uart_config },
+ { OMAP_TAG_MMC, &h4_mmc_config },
+ { OMAP_TAG_LCD, &h4_lcd_config },
+};
+
+static void __init omap_h4_init(void)
+{
+ /*
+ * Make sure the serial ports are muxed on at this point.
+ * You have to mux them off in device drivers later on
+ * if not needed.
+ */
+ platform_add_devices(h4_devices, ARRAY_SIZE(h4_devices));
+ omap_board_config = h4_config;
+ omap_board_config_size = ARRAY_SIZE(h4_config);
+ omap_serial_init();
+}
+
+static void __init omap_h4_map_io(void)
+{
+ omap_map_common_io();
+}
+
+MACHINE_START(OMAP_H4, "OMAP2420 H4 board")
+ /* Maintainer: Paul Mundt <paul.mundt@nokia.com> */
+ .phys_ram = 0x80000000,
+ .phys_io = 0x48000000,
+ .io_pg_offst = ((0xd8000000) >> 18) & 0xfffc,
+ .boot_params = 0x80000100,
+ .map_io = omap_h4_map_io,
+ .init_irq = omap_h4_init_irq,
+ .init_machine = omap_h4_init,
+ .timer = &omap_timer,
+MACHINE_END
diff --git a/arch/arm/mach-omap2/clock.c b/arch/arm/mach-omap2/clock.c
new file mode 100644
index 000000000000..85818d9f2635
--- /dev/null
+++ b/arch/arm/mach-omap2/clock.c
@@ -0,0 +1,1129 @@
+/*
+ * linux/arch/arm/mach-omap2/clock.c
+ *
+ * Copyright (C) 2005 Texas Instruments Inc.
+ * Richard Woodruff <r-woodruff2@ti.com>
+ * Created for OMAP2.
+ *
+ * Cleaned up and modified to use omap shared clock framework by
+ * Tony Lindgren <tony@atomide.com>
+ *
+ * Based on omap1 clock.c, Copyright (C) 2004 - 2005 Nokia corporation
+ * Written by Tuukka Tikkanen <tuukka.tikkanen@elektrobit.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/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/delay.h>
+
+#include <asm/io.h>
+
+#include <asm/hardware/clock.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/sram.h>
+#include <asm/arch/prcm.h>
+
+#include "clock.h"
+
+//#define DOWN_VARIABLE_DPLL 1 /* Experimental */
+
+static struct prcm_config *curr_prcm_set;
+static struct memory_timings mem_timings;
+static u32 curr_perf_level = PRCM_FULL_SPEED;
+
+/*-------------------------------------------------------------------------
+ * Omap2 specific clock functions
+ *-------------------------------------------------------------------------*/
+
+/* Recalculate SYST_CLK */
+static void omap2_sys_clk_recalc(struct clk * clk)
+{
+ u32 div = PRCM_CLKSRC_CTRL;
+ div &= (1 << 7) | (1 << 6); /* Test if ext clk divided by 1 or 2 */
+ div >>= clk->rate_offset;
+ clk->rate = (clk->parent->rate / div);
+ propagate_rate(clk);
+}
+
+static u32 omap2_get_dpll_rate(struct clk * tclk)
+{
+ int dpll_clk, dpll_mult, dpll_div, amult;
+
+ dpll_mult = (CM_CLKSEL1_PLL >> 12) & 0x03ff; /* 10 bits */
+ dpll_div = (CM_CLKSEL1_PLL >> 8) & 0x0f; /* 4 bits */
+ dpll_clk = (tclk->parent->rate * dpll_mult) / (dpll_div + 1);
+ amult = CM_CLKSEL2_PLL & 0x3;
+ dpll_clk *= amult;
+
+ return dpll_clk;
+}
+
+static void omap2_followparent_recalc(struct clk *clk)
+{
+ followparent_recalc(clk);
+}
+
+static void omap2_propagate_rate(struct clk * clk)
+{
+ if (!(clk->flags & RATE_FIXED))
+ clk->rate = clk->parent->rate;
+
+ propagate_rate(clk);
+}
+
+/* Enable an APLL if off */
+static void omap2_clk_fixed_enable(struct clk *clk)
+{
+ u32 cval, i=0;
+
+ if (clk->enable_bit == 0xff) /* Parent will do it */
+ return;
+
+ cval = CM_CLKEN_PLL;
+
+ if ((cval & (0x3 << clk->enable_bit)) == (0x3 << clk->enable_bit))
+ return;
+
+ cval &= ~(0x3 << clk->enable_bit);
+ cval |= (0x3 << clk->enable_bit);
+ CM_CLKEN_PLL = cval;
+
+ if (clk == &apll96_ck)
+ cval = (1 << 8);
+ else if (clk == &apll54_ck)
+ cval = (1 << 6);
+
+ while (!CM_IDLEST_CKGEN & cval) { /* Wait for lock */
+ ++i;
+ udelay(1);
+ if (i == 100000)
+ break;
+ }
+}
+
+/* Enables clock without considering parent dependencies or use count
+ * REVISIT: Maybe change this to use clk->enable like on omap1?
+ */
+static int omap2_clk_enable(struct clk * clk)
+{
+ u32 regval32;
+
+ if (clk->flags & ALWAYS_ENABLED)
+ return 0;
+
+ if (unlikely(clk->enable_reg == 0)) {
+ printk(KERN_ERR "clock.c: Enable for %s without enable code\n",
+ clk->name);
+ return 0;
+ }
+
+ if (clk->enable_reg == (void __iomem *)&CM_CLKEN_PLL) {
+ omap2_clk_fixed_enable(clk);
+ return 0;
+ }
+
+ regval32 = __raw_readl(clk->enable_reg);
+ regval32 |= (1 << clk->enable_bit);
+ __raw_writel(regval32, clk->enable_reg);
+
+ return 0;
+}
+
+/* Stop APLL */
+static void omap2_clk_fixed_disable(struct clk *clk)
+{
+ u32 cval;
+
+ if(clk->enable_bit == 0xff) /* let parent off do it */
+ return;
+
+ cval = CM_CLKEN_PLL;
+ cval &= ~(0x3 << clk->enable_bit);
+ CM_CLKEN_PLL = cval;
+}
+
+/* Disables clock without considering parent dependencies or use count */
+static void omap2_clk_disable(struct clk *clk)
+{
+ u32 regval32;
+
+ if (clk->enable_reg == 0)
+ return;
+
+ if (clk->enable_reg == (void __iomem *)&CM_CLKEN_PLL) {
+ omap2_clk_fixed_disable(clk);
+ return;
+ }
+
+ regval32 = __raw_readl(clk->enable_reg);
+ regval32 &= ~(1 << clk->enable_bit);
+ __raw_writel(regval32, clk->enable_reg);
+}
+
+static int omap2_clk_use(struct clk *clk)
+{
+ int ret = 0;
+
+ if (clk->usecount++ == 0) {
+ if (likely((u32)clk->parent))
+ ret = omap2_clk_use(clk->parent);
+
+ if (unlikely(ret != 0)) {
+ clk->usecount--;
+ return ret;
+ }
+
+ ret = omap2_clk_enable(clk);
+
+ if (unlikely(ret != 0) && clk->parent) {
+ omap2_clk_unuse(clk->parent);
+ clk->usecount--;
+ }
+ }
+
+ return ret;
+}
+
+static void omap2_clk_unuse(struct clk *clk)
+{
+ if (clk->usecount > 0 && !(--clk->usecount)) {
+ omap2_clk_disable(clk);
+ if (likely((u32)clk->parent))
+ omap2_clk_unuse(clk->parent);
+ }
+}
+
+/*
+ * Uses the current prcm set to tell if a rate is valid.
+ * You can go slower, but not faster within a given rate set.
+ */
+static u32 omap2_dpll_round_rate(unsigned long target_rate)
+{
+ u32 high, low;
+
+ if ((CM_CLKSEL2_PLL & 0x3) == 1) { /* DPLL clockout */
+ high = curr_prcm_set->dpll_speed * 2;
+ low = curr_prcm_set->dpll_speed;
+ } else { /* DPLL clockout x 2 */
+ high = curr_prcm_set->dpll_speed;
+ low = curr_prcm_set->dpll_speed / 2;
+ }
+
+#ifdef DOWN_VARIABLE_DPLL
+ if (target_rate > high)
+ return high;
+ else
+ return target_rate;
+#else
+ if (target_rate > low)
+ return high;
+ else
+ return low;
+#endif
+
+}
+
+/*
+ * Used for clocks that are part of CLKSEL_xyz governed clocks.
+ * REVISIT: Maybe change to use clk->enable() functions like on omap1?
+ */
+static void omap2_clksel_recalc(struct clk * clk)
+{
+ u32 fixed = 0, div = 0;
+
+ if (clk == &dpll_ck) {
+ clk->rate = omap2_get_dpll_rate(clk);
+ fixed = 1;
+ div = 0;
+ }
+
+ if (clk == &iva1_mpu_int_ifck) {
+ div = 2;
+ fixed = 1;
+ }
+
+ if ((clk == &dss1_fck) && ((CM_CLKSEL1_CORE & (0x1f << 8)) == 0)) {
+ clk->rate = sys_ck.rate;
+ return;
+ }
+
+ if (!fixed) {
+ div = omap2_clksel_get_divisor(clk);
+ if (div == 0)
+ return;
+ }
+
+ if (div != 0) {
+ if (unlikely(clk->rate == clk->parent->rate / div))
+ return;
+ clk->rate = clk->parent->rate / div;
+ }
+
+ if (unlikely(clk->flags & RATE_PROPAGATES))
+ propagate_rate(clk);
+}
+
+/*
+ * Finds best divider value in an array based on the source and target
+ * rates. The divider array must be sorted with smallest divider first.
+ */
+static inline u32 omap2_divider_from_table(u32 size, u32 *div_array,
+ u32 src_rate, u32 tgt_rate)
+{
+ int i, test_rate;
+
+ if (div_array == NULL)
+ return ~1;
+
+ for (i=0; i < size; i++) {
+ test_rate = src_rate / *div_array;
+ if (test_rate <= tgt_rate)
+ return *div_array;
+ ++div_array;
+ }
+
+ return ~0; /* No acceptable divider */
+}
+
+/*
+ * Find divisor for the given clock and target rate.
+ *
+ * Note that this will not work for clocks which are part of CONFIG_PARTICIPANT,
+ * they are only settable as part of virtual_prcm set.
+ */
+static u32 omap2_clksel_round_rate(struct clk *tclk, u32 target_rate,
+ u32 *new_div)
+{
+ u32 gfx_div[] = {2, 3, 4};
+ u32 sysclkout_div[] = {1, 2, 4, 8, 16};
+ u32 dss1_div[] = {1, 2, 3, 4, 5, 6, 8, 9, 12, 16};
+ u32 vylnq_div[] = {1, 2, 3, 4, 6, 8, 9, 12, 16, 18};
+ u32 best_div = ~0, asize = 0;
+ u32 *div_array = NULL;
+
+ switch (tclk->flags & SRC_RATE_SEL_MASK) {
+ case CM_GFX_SEL1:
+ asize = 3;
+ div_array = gfx_div;
+ break;
+ case CM_PLL_SEL1:
+ return omap2_dpll_round_rate(target_rate);
+ case CM_SYSCLKOUT_SEL1:
+ asize = 5;
+ div_array = sysclkout_div;
+ break;
+ case CM_CORE_SEL1:
+ if(tclk == &dss1_fck){
+ if(tclk->parent == &core_ck){
+ asize = 10;
+ div_array = dss1_div;
+ } else {
+ *new_div = 0; /* fixed clk */
+ return(tclk->parent->rate);
+ }
+ } else if((tclk == &vlynq_fck) && cpu_is_omap2420()){
+ if(tclk->parent == &core_ck){
+ asize = 10;
+ div_array = vylnq_div;
+ } else {
+ *new_div = 0; /* fixed clk */
+ return(tclk->parent->rate);
+ }
+ }
+ break;
+ }
+
+ best_div = omap2_divider_from_table(asize, div_array,
+ tclk->parent->rate, target_rate);
+ if (best_div == ~0){
+ *new_div = 1;
+ return best_div; /* signal error */
+ }
+
+ *new_div = best_div;
+ return (tclk->parent->rate / best_div);
+}
+
+/* Given a clock and a rate apply a clock specific rounding function */
+static long omap2_clk_round_rate(struct clk *clk, unsigned long rate)
+{
+ u32 new_div = 0;
+ int valid_rate;
+
+ if (clk->flags & RATE_FIXED)
+ return clk->rate;
+
+ if (clk->flags & RATE_CKCTL) {
+ valid_rate = omap2_clksel_round_rate(clk, rate, &new_div);
+ return valid_rate;
+ }
+
+ if (clk->round_rate != 0)
+ return clk->round_rate(clk, rate);
+
+ return clk->rate;
+}
+
+/*
+ * Check the DLL lock state, and return tue if running in unlock mode.
+ * This is needed to compenste for the shifted DLL value in unlock mode.
+ */
+static u32 omap2_dll_force_needed(void)
+{
+ u32 dll_state = SDRC_DLLA_CTRL; /* dlla and dllb are a set */
+
+ if ((dll_state & (1 << 2)) == (1 << 2))
+ return 1;
+ else
+ return 0;
+}
+
+static void omap2_init_memory_params(u32 force_lock_to_unlock_mode)
+{
+ unsigned long dll_cnt;
+ u32 fast_dll = 0;
+
+ mem_timings.m_type = !((SDRC_MR_0 & 0x3) == 0x1); /* DDR = 1, SDR = 0 */
+
+ /* 2422 es2.05 and beyond has a single SIP DDR instead of 2 like others.
+ * In the case of 2422, its ok to use CS1 instead of CS0.
+ */
+
+#if 0 /* FIXME: Enable after 24xx cpu detection works */
+ ctype = get_cpu_type();
+ if (cpu_is_omap2422())
+ mem_timings.base_cs = 1;
+ else
+#endif
+ mem_timings.base_cs = 0;
+
+ if (mem_timings.m_type != M_DDR)
+ return;
+
+ /* With DDR we need to determine the low frequency DLL value */
+ if (((mem_timings.fast_dll_ctrl & (1 << 2)) == M_LOCK_CTRL))
+ mem_timings.dll_mode = M_UNLOCK;
+ else
+ mem_timings.dll_mode = M_LOCK;
+
+ if (mem_timings.base_cs == 0) {
+ fast_dll = SDRC_DLLA_CTRL;
+ dll_cnt = SDRC_DLLA_STATUS & 0xff00;
+ } else {
+ fast_dll = SDRC_DLLB_CTRL;
+ dll_cnt = SDRC_DLLB_STATUS & 0xff00;
+ }
+ if (force_lock_to_unlock_mode) {
+ fast_dll &= ~0xff00;
+ fast_dll |= dll_cnt; /* Current lock mode */
+ }
+ mem_timings.fast_dll_ctrl = fast_dll;
+
+ /* No disruptions, DDR will be offline & C-ABI not followed */
+ omap2_sram_ddr_init(&mem_timings.slow_dll_ctrl,
+ mem_timings.fast_dll_ctrl,
+ mem_timings.base_cs,
+ force_lock_to_unlock_mode);
+ mem_timings.slow_dll_ctrl &= 0xff00; /* Keep lock value */
+
+ /* Turn status into unlock ctrl */
+ mem_timings.slow_dll_ctrl |=
+ ((mem_timings.fast_dll_ctrl & 0xF) | (1 << 2));
+
+ /* 90 degree phase for anything below 133Mhz */
+ mem_timings.slow_dll_ctrl |= (1 << 1);
+}
+
+static u32 omap2_reprogram_sdrc(u32 level, u32 force)
+{
+ u32 prev = curr_perf_level, flags;
+
+ if ((curr_perf_level == level) && !force)
+ return prev;
+
+ if (level == PRCM_HALF_SPEED) {
+ local_irq_save(flags);
+ PRCM_VOLTSETUP = 0xffff;
+ omap2_sram_reprogram_sdrc(PRCM_HALF_SPEED,
+ mem_timings.slow_dll_ctrl,
+ mem_timings.m_type);
+ curr_perf_level = PRCM_HALF_SPEED;
+ local_irq_restore(flags);
+ }
+ if (level == PRCM_FULL_SPEED) {
+ local_irq_save(flags);
+ PRCM_VOLTSETUP = 0xffff;
+ omap2_sram_reprogram_sdrc(PRCM_FULL_SPEED,
+ mem_timings.fast_dll_ctrl,
+ mem_timings.m_type);
+ curr_perf_level = PRCM_FULL_SPEED;
+ local_irq_restore(flags);
+ }
+
+ return prev;
+}
+
+static int omap2_reprogram_dpll(struct clk * clk, unsigned long rate)
+{
+ u32 flags, cur_rate, low, mult, div, valid_rate, done_rate;
+ u32 bypass = 0;
+ struct prcm_config tmpset;
+ int ret = -EINVAL;
+
+ local_irq_save(flags);
+ cur_rate = omap2_get_dpll_rate(&dpll_ck);
+ mult = CM_CLKSEL2_PLL & 0x3;
+
+ if ((rate == (cur_rate / 2)) && (mult == 2)) {
+ omap2_reprogram_sdrc(PRCM_HALF_SPEED, 1);
+ } else if ((rate == (cur_rate * 2)) && (mult == 1)) {
+ omap2_reprogram_sdrc(PRCM_FULL_SPEED, 1);
+ } else if (rate != cur_rate) {
+ valid_rate = omap2_dpll_round_rate(rate);
+ if (valid_rate != rate)
+ goto dpll_exit;
+
+ if ((CM_CLKSEL2_PLL & 0x3) == 1)
+ low = curr_prcm_set->dpll_speed;
+ else
+ low = curr_prcm_set->dpll_speed / 2;
+
+ tmpset.cm_clksel1_pll = CM_CLKSEL1_PLL;
+ tmpset.cm_clksel1_pll &= ~(0x3FFF << 8);
+ div = ((curr_prcm_set->xtal_speed / 1000000) - 1);
+ tmpset.cm_clksel2_pll = CM_CLKSEL2_PLL;
+ tmpset.cm_clksel2_pll &= ~0x3;
+ if (rate > low) {
+ tmpset.cm_clksel2_pll |= 0x2;
+ mult = ((rate / 2) / 1000000);
+ done_rate = PRCM_FULL_SPEED;
+ } else {
+ tmpset.cm_clksel2_pll |= 0x1;
+ mult = (rate / 1000000);
+ done_rate = PRCM_HALF_SPEED;
+ }
+ tmpset.cm_clksel1_pll |= ((div << 8) | (mult << 12));
+
+ /* Worst case */
+ tmpset.base_sdrc_rfr = V24XX_SDRC_RFR_CTRL_BYPASS;
+
+ if (rate == curr_prcm_set->xtal_speed) /* If asking for 1-1 */
+ bypass = 1;
+
+ omap2_reprogram_sdrc(PRCM_FULL_SPEED, 1); /* For init_mem */
+
+ /* Force dll lock mode */
+ omap2_set_prcm(tmpset.cm_clksel1_pll, tmpset.base_sdrc_rfr,
+ bypass);
+
+ /* Errata: ret dll entry state */
+ omap2_init_memory_params(omap2_dll_force_needed());
+ omap2_reprogram_sdrc(done_rate, 0);
+ }
+ omap2_clksel_recalc(&dpll_ck);
+ ret = 0;
+
+dpll_exit:
+ local_irq_restore(flags);
+ return(ret);
+}
+
+/* Just return the MPU speed */
+static void omap2_mpu_recalc(struct clk * clk)
+{
+ clk->rate = curr_prcm_set->mpu_speed;
+}
+
+/*
+ * Look for a rate equal or less than the target rate given a configuration set.
+ *
+ * What's not entirely clear is "which" field represents the key field.
+ * Some might argue L3-DDR, others ARM, others IVA. This code is simple and
+ * just uses the ARM rates.
+ */
+static long omap2_round_to_table_rate(struct clk * clk, unsigned long rate)
+{
+ struct prcm_config * ptr;
+ long highest_rate;
+
+ if (clk != &virt_prcm_set)
+ return -EINVAL;
+
+ highest_rate = -EINVAL;
+
+ for (ptr = rate_table; ptr->mpu_speed; ptr++) {
+ if (ptr->xtal_speed != sys_ck.rate)
+ continue;
+
+ highest_rate = ptr->mpu_speed;
+
+ /* Can check only after xtal frequency check */
+ if (ptr->mpu_speed <= rate)
+ break;
+ }
+ return highest_rate;
+}
+
+/*
+ * omap2_convert_field_to_div() - turn field value into integer divider
+ */
+static u32 omap2_clksel_to_divisor(u32 div_sel, u32 field_val)
+{
+ u32 i;
+ u32 clkout_array[] = {1, 2, 4, 8, 16};
+
+ if ((div_sel & SRC_RATE_SEL_MASK) == CM_SYSCLKOUT_SEL1) {
+ for (i = 0; i < 5; i++) {
+ if (field_val == i)
+ return clkout_array[i];
+ }
+ return ~0;
+ } else
+ return field_val;
+}
+
+/*
+ * Returns the CLKSEL divider register value
+ * REVISIT: This should be cleaned up to work nicely with void __iomem *
+ */
+static u32 omap2_get_clksel(u32 *div_sel, u32 *field_mask,
+ struct clk *clk)
+{
+ int ret = ~0;
+ u32 reg_val, div_off;
+ u32 div_addr = 0;
+ u32 mask = ~0;
+
+ div_off = clk->rate_offset;
+
+ switch ((*div_sel & SRC_RATE_SEL_MASK)) {
+ case CM_MPU_SEL1:
+ div_addr = (u32)&CM_CLKSEL_MPU;
+ mask = 0x1f;
+ break;
+ case CM_DSP_SEL1:
+ div_addr = (u32)&CM_CLKSEL_DSP;
+ if (cpu_is_omap2420()) {
+ if ((div_off == 0) || (div_off == 8))
+ mask = 0x1f;
+ else if (div_off == 5)
+ mask = 0x3;
+ } else if (cpu_is_omap2430()) {
+ if (div_off == 0)
+ mask = 0x1f;
+ else if (div_off == 5)
+ mask = 0x3;
+ }
+ break;
+ case CM_GFX_SEL1:
+ div_addr = (u32)&CM_CLKSEL_GFX;
+ if (div_off == 0)
+ mask = 0x7;
+ break;
+ case CM_MODEM_SEL1:
+ div_addr = (u32)&CM_CLKSEL_MDM;
+ if (div_off == 0)
+ mask = 0xf;
+ break;
+ case CM_SYSCLKOUT_SEL1:
+ div_addr = (u32)&PRCM_CLKOUT_CTRL;
+ if ((div_off == 3) || (div_off = 11))
+ mask= 0x3;
+ break;
+ case CM_CORE_SEL1:
+ div_addr = (u32)&CM_CLKSEL1_CORE;
+ switch (div_off) {
+ case 0: /* l3 */
+ case 8: /* dss1 */
+ case 15: /* vylnc-2420 */
+ case 20: /* ssi */
+ mask = 0x1f; break;
+ case 5: /* l4 */
+ mask = 0x3; break;
+ case 13: /* dss2 */
+ mask = 0x1; break;
+ case 25: /* usb */
+ mask = 0xf; break;
+ }
+ }
+
+ *field_mask = mask;
+
+ if (unlikely(mask == ~0))
+ div_addr = 0;
+
+ *div_sel = div_addr;
+
+ if (unlikely(div_addr == 0))
+ return ret;
+
+ /* Isolate field */
+ reg_val = __raw_readl((void __iomem *)div_addr) & (mask << div_off);
+
+ /* Normalize back to divider value */
+ reg_val >>= div_off;
+
+ return reg_val;
+}
+
+/*
+ * Return divider to be applied to parent clock.
+ * Return 0 on error.
+ */
+static u32 omap2_clksel_get_divisor(struct clk *clk)
+{
+ int ret = 0;
+ u32 div, div_sel, div_off, field_mask, field_val;
+
+ /* isolate control register */
+ div_sel = (SRC_RATE_SEL_MASK & clk->flags);
+
+ div_off = clk->rate_offset;
+ field_val = omap2_get_clksel(&div_sel, &field_mask, clk);
+ if (div_sel == 0)
+ return ret;
+
+ div_sel = (SRC_RATE_SEL_MASK & clk->flags);
+ div = omap2_clksel_to_divisor(div_sel, field_val);
+
+ return div;
+}
+
+/* Set the clock rate for a clock source */
+static int omap2_clk_set_rate(struct clk *clk, unsigned long rate)
+
+{
+ int ret = -EINVAL;
+ void __iomem * reg;
+ u32 div_sel, div_off, field_mask, field_val, reg_val, validrate;
+ u32 new_div = 0;
+
+ if (!(clk->flags & CONFIG_PARTICIPANT) && (clk->flags & RATE_CKCTL)) {
+ if (clk == &dpll_ck)
+ return omap2_reprogram_dpll(clk, rate);
+
+ /* Isolate control register */
+ div_sel = (SRC_RATE_SEL_MASK & clk->flags);
+ div_off = clk->src_offset;
+
+ validrate = omap2_clksel_round_rate(clk, rate, &new_div);
+ if(validrate != rate)
+ return(ret);
+
+ field_val = omap2_get_clksel(&div_sel, &field_mask, clk);
+ if (div_sel == 0)
+ return ret;
+
+ if(clk->flags & CM_SYSCLKOUT_SEL1){
+ switch(new_div){
+ case 16: field_val = 4; break;
+ case 8: field_val = 3; break;
+ case 4: field_val = 2; break;
+ case 2: field_val = 1; break;
+ case 1: field_val = 0; break;
+ }
+ }
+ else
+ field_val = new_div;
+
+ reg = (void __iomem *)div_sel;
+
+ reg_val = __raw_readl(reg);
+ reg_val &= ~(field_mask << div_off);
+ reg_val |= (field_val << div_off);
+
+ __raw_writel(reg_val, reg);
+ clk->rate = clk->parent->rate / field_val;
+
+ if (clk->flags & DELAYED_APP)
+ __raw_writel(0x1, (void __iomem *)&PRCM_CLKCFG_CTRL);
+ ret = 0;
+ } else if (clk->set_rate != 0)
+ ret = clk->set_rate(clk, rate);
+
+ if (unlikely(ret == 0 && (clk->flags & RATE_PROPAGATES)))
+ propagate_rate(clk);
+
+ return ret;
+}
+
+/* Converts encoded control register address into a full address */
+static u32 omap2_get_src_field(u32 *type_to_addr, u32 reg_offset,
+ struct clk *src_clk, u32 *field_mask)
+{
+ u32 val = ~0, src_reg_addr = 0, mask = 0;
+
+ /* Find target control register.*/
+ switch ((*type_to_addr & SRC_RATE_SEL_MASK)) {
+ case CM_CORE_SEL1:
+ src_reg_addr = (u32)&CM_CLKSEL1_CORE;
+ if (reg_offset == 13) { /* DSS2_fclk */
+ mask = 0x1;
+ if (src_clk == &sys_ck)
+ val = 0;
+ if (src_clk == &func_48m_ck)
+ val = 1;
+ } else if (reg_offset == 8) { /* DSS1_fclk */
+ mask = 0x1f;
+ if (src_clk == &sys_ck)
+ val = 0;
+ else if (src_clk == &core_ck) /* divided clock */
+ val = 0x10; /* rate needs fixing */
+ } else if ((reg_offset == 15) && cpu_is_omap2420()){ /*vlnyq*/
+ mask = 0x1F;
+ if(src_clk == &func_96m_ck)
+ val = 0;
+ else if (src_clk == &core_ck)
+ val = 0x10;
+ }
+ break;
+ case CM_CORE_SEL2:
+ src_reg_addr = (u32)&CM_CLKSEL2_CORE;
+ mask = 0x3;
+ if (src_clk == &func_32k_ck)
+ val = 0x0;
+ if (src_clk == &sys_ck)
+ val = 0x1;
+ if (src_clk == &alt_ck)
+ val = 0x2;
+ break;
+ case CM_WKUP_SEL1:
+ src_reg_addr = (u32)&CM_CLKSEL2_CORE;
+ mask = 0x3;
+ if (src_clk == &func_32k_ck)
+ val = 0x0;
+ if (src_clk == &sys_ck)
+ val = 0x1;
+ if (src_clk == &alt_ck)
+ val = 0x2;
+ break;
+ case CM_PLL_SEL1:
+ src_reg_addr = (u32)&CM_CLKSEL1_PLL;
+ mask = 0x1;
+ if (reg_offset == 0x3) {
+ if (src_clk == &apll96_ck)
+ val = 0;
+ if (src_clk == &alt_ck)
+ val = 1;
+ }
+ else if (reg_offset == 0x5) {
+ if (src_clk == &apll54_ck)
+ val = 0;
+ if (src_clk == &alt_ck)
+ val = 1;
+ }
+ break;
+ case CM_PLL_SEL2:
+ src_reg_addr = (u32)&CM_CLKSEL2_PLL;
+ mask = 0x3;
+ if (src_clk == &func_32k_ck)
+ val = 0x0;
+ if (src_clk == &dpll_ck)
+ val = 0x2;
+ break;
+ case CM_SYSCLKOUT_SEL1:
+ src_reg_addr = (u32)&PRCM_CLKOUT_CTRL;
+ mask = 0x3;
+ if (src_clk == &dpll_ck)
+ val = 0;
+ if (src_clk == &sys_ck)
+ val = 1;
+ if (src_clk == &func_54m_ck)
+ val = 2;
+ if (src_clk == &func_96m_ck)
+ val = 3;
+ break;
+ }
+
+ if (val == ~0) /* Catch errors in offset */
+ *type_to_addr = 0;
+ else
+ *type_to_addr = src_reg_addr;
+ *field_mask = mask;
+
+ return val;
+}
+
+static int omap2_clk_set_parent(struct clk *clk, struct clk *new_parent)
+{
+ void __iomem * reg;
+ u32 src_sel, src_off, field_val, field_mask, reg_val, rate;
+ int ret = -EINVAL;
+
+ if (unlikely(clk->flags & CONFIG_PARTICIPANT))
+ return ret;
+
+ if (clk->flags & SRC_SEL_MASK) { /* On-chip SEL collection */
+ src_sel = (SRC_RATE_SEL_MASK & clk->flags);
+ src_off = clk->src_offset;
+
+ if (src_sel == 0)
+ goto set_parent_error;
+
+ field_val = omap2_get_src_field(&src_sel, src_off, new_parent,
+ &field_mask);
+
+ reg = (void __iomem *)src_sel;
+
+ if (clk->usecount > 0)
+ omap2_clk_disable(clk);
+
+ /* Set new source value (previous dividers if any in effect) */
+ reg_val = __raw_readl(reg) & ~(field_mask << src_off);
+ reg_val |= (field_val << src_off);
+ __raw_writel(reg_val, reg);
+
+ if (clk->flags & DELAYED_APP)
+ __raw_writel(0x1, (void __iomem *)&PRCM_CLKCFG_CTRL);
+
+ if (clk->usecount > 0)
+ omap2_clk_enable(clk);
+
+ clk->parent = new_parent;
+
+ /* SRC_RATE_SEL_MASK clocks follow their parents rates.*/
+ if ((new_parent == &core_ck) && (clk == &dss1_fck))
+ clk->rate = new_parent->rate / 0x10;
+ else
+ clk->rate = new_parent->rate;
+
+ if (unlikely(clk->flags & RATE_PROPAGATES))
+ propagate_rate(clk);
+
+ return 0;
+ } else {
+ clk->parent = new_parent;
+ rate = new_parent->rate;
+ omap2_clk_set_rate(clk, rate);
+ ret = 0;
+ }
+
+ set_parent_error:
+ return ret;
+}
+
+/* Sets basic clocks based on the specified rate */
+static int omap2_select_table_rate(struct clk * clk, unsigned long rate)
+{
+ u32 flags, cur_rate, done_rate, bypass = 0;
+ u8 cpu_mask = 0;
+ struct prcm_config *prcm;
+ unsigned long found_speed = 0;
+
+ if (clk != &virt_prcm_set)
+ return -EINVAL;
+
+ /* FIXME: Change cpu_is_omap2420() to cpu_is_omap242x() */
+ if (cpu_is_omap2420())
+ cpu_mask = RATE_IN_242X;
+ else if (cpu_is_omap2430())
+ cpu_mask = RATE_IN_243X;
+
+ for (prcm = rate_table; prcm->mpu_speed; prcm++) {
+ if (!(prcm->flags & cpu_mask))
+ continue;
+
+ if (prcm->xtal_speed != sys_ck.rate)
+ continue;
+
+ if (prcm->mpu_speed <= rate) {
+ found_speed = prcm->mpu_speed;
+ break;
+ }
+ }
+
+ if (!found_speed) {
+ printk(KERN_INFO "Could not set MPU rate to %luMHz\n",
+ rate / 1000000);
+ return -EINVAL;
+ }
+
+ curr_prcm_set = prcm;
+ cur_rate = omap2_get_dpll_rate(&dpll_ck);
+
+ if (prcm->dpll_speed == cur_rate / 2) {
+ omap2_reprogram_sdrc(PRCM_HALF_SPEED, 1);
+ } else if (prcm->dpll_speed == cur_rate * 2) {
+ omap2_reprogram_sdrc(PRCM_FULL_SPEED, 1);
+ } else if (prcm->dpll_speed != cur_rate) {
+ local_irq_save(flags);
+
+ if (prcm->dpll_speed == prcm->xtal_speed)
+ bypass = 1;
+
+ if ((prcm->cm_clksel2_pll & 0x3) == 2)
+ done_rate = PRCM_FULL_SPEED;
+ else
+ done_rate = PRCM_HALF_SPEED;
+
+ /* MPU divider */
+ CM_CLKSEL_MPU = prcm->cm_clksel_mpu;
+
+ /* dsp + iva1 div(2420), iva2.1(2430) */
+ CM_CLKSEL_DSP = prcm->cm_clksel_dsp;
+
+ CM_CLKSEL_GFX = prcm->cm_clksel_gfx;
+
+ /* Major subsystem dividers */
+ CM_CLKSEL1_CORE = prcm->cm_clksel1_core;
+ if (cpu_is_omap2430())
+ CM_CLKSEL_MDM = prcm->cm_clksel_mdm;
+
+ /* x2 to enter init_mem */
+ omap2_reprogram_sdrc(PRCM_FULL_SPEED, 1);
+
+ omap2_set_prcm(prcm->cm_clksel1_pll, prcm->base_sdrc_rfr,
+ bypass);
+
+ omap2_init_memory_params(omap2_dll_force_needed());
+ omap2_reprogram_sdrc(done_rate, 0);
+
+ local_irq_restore(flags);
+ }
+ omap2_clksel_recalc(&dpll_ck);
+
+ return 0;
+}
+
+/*-------------------------------------------------------------------------
+ * Omap2 clock reset and init functions
+ *-------------------------------------------------------------------------*/
+
+static struct clk_functions omap2_clk_functions = {
+ .clk_enable = omap2_clk_enable,
+ .clk_disable = omap2_clk_disable,
+ .clk_use = omap2_clk_use,
+ .clk_unuse = omap2_clk_unuse,
+ .clk_round_rate = omap2_clk_round_rate,
+ .clk_set_rate = omap2_clk_set_rate,
+ .clk_set_parent = omap2_clk_set_parent,
+};
+
+static void __init omap2_get_crystal_rate(struct clk *osc, struct clk *sys)
+{
+ u32 div, aplls, sclk = 13000000;
+
+ aplls = CM_CLKSEL1_PLL;
+ aplls &= ((1 << 23) | (1 << 24) | (1 << 25));
+ aplls >>= 23; /* Isolate field, 0,2,3 */
+
+ if (aplls == 0)
+ sclk = 19200000;
+ else if (aplls == 2)
+ sclk = 13000000;
+ else if (aplls == 3)
+ sclk = 12000000;
+
+ div = PRCM_CLKSRC_CTRL;
+ div &= ((1 << 7) | (1 << 6));
+ div >>= sys->rate_offset;
+
+ osc->rate = sclk * div;
+ sys->rate = sclk;
+}
+
+#ifdef CONFIG_OMAP_RESET_CLOCKS
+static void __init omap2_disable_unused_clocks(void)
+{
+ struct clk *ck;
+ u32 regval32;
+
+ list_for_each_entry(ck, &clocks, node) {
+ if (ck->usecount > 0 || (ck->flags & ALWAYS_ENABLED) ||
+ ck->enable_reg == 0)
+ continue;
+
+ regval32 = __raw_readl(ck->enable_reg);
+ if ((regval32 & (1 << ck->enable_bit)) == 0)
+ continue;
+
+ printk(KERN_INFO "Disabling unused clock \"%s\"\n", ck->name);
+ omap2_clk_disable(ck);
+ }
+}
+late_initcall(omap2_disable_unused_clocks);
+#endif
+
+/*
+ * Switch the MPU rate if specified on cmdline.
+ * We cannot do this early until cmdline is parsed.
+ */
+static int __init omap2_clk_arch_init(void)
+{
+ if (!mpurate)
+ return -EINVAL;
+
+ if (omap2_select_table_rate(&virt_prcm_set, mpurate))
+ printk(KERN_ERR "Could not find matching MPU rate\n");
+
+ propagate_rate(&osc_ck); /* update main root fast */
+ propagate_rate(&func_32k_ck); /* update main root slow */
+
+ printk(KERN_INFO "Switched to new clocking rate (Crystal/DPLL/MPU): "
+ "%ld.%01ld/%ld/%ld MHz\n",
+ (sys_ck.rate / 1000000), (sys_ck.rate / 100000) % 10,
+ (dpll_ck.rate / 1000000), (mpu_ck.rate / 1000000)) ;
+
+ return 0;
+}
+arch_initcall(omap2_clk_arch_init);
+
+int __init omap2_clk_init(void)
+{
+ struct prcm_config *prcm;
+ struct clk ** clkp;
+ u32 clkrate;
+
+ clk_init(&omap2_clk_functions);
+ omap2_get_crystal_rate(&osc_ck, &sys_ck);
+
+ for (clkp = onchip_clks; clkp < onchip_clks + ARRAY_SIZE(onchip_clks);
+ clkp++) {
+
+ if ((*clkp)->flags & CLOCK_IN_OMAP242X && cpu_is_omap2420()) {
+ clk_register(*clkp);
+ continue;
+ }
+
+ if ((*clkp)->flags & CLOCK_IN_OMAP243X && cpu_is_omap2430()) {
+ clk_register(*clkp);
+ continue;
+ }
+ }
+
+ /* Check the MPU rate set by bootloader */
+ clkrate = omap2_get_dpll_rate(&dpll_ck);
+ for (prcm = rate_table; prcm->mpu_speed; prcm++) {
+ if (prcm->xtal_speed != sys_ck.rate)
+ continue;
+ if (prcm->dpll_speed <= clkrate)
+ break;
+ }
+ curr_prcm_set = prcm;
+
+ propagate_rate(&osc_ck); /* update main root fast */
+ propagate_rate(&func_32k_ck); /* update main root slow */
+
+ printk(KERN_INFO "Clocking rate (Crystal/DPLL/MPU): "
+ "%ld.%01ld/%ld/%ld MHz\n",
+ (sys_ck.rate / 1000000), (sys_ck.rate / 100000) % 10,
+ (dpll_ck.rate / 1000000), (mpu_ck.rate / 1000000)) ;
+
+ /*
+ * Only enable those clocks we will need, let the drivers
+ * enable other clocks as necessary
+ */
+ clk_use(&sync_32k_ick);
+ clk_use(&omapctrl_ick);
+ if (cpu_is_omap2430())
+ clk_use(&sdrc_ick);
+
+ return 0;
+}
diff --git a/arch/arm/mach-omap2/clock.h b/arch/arm/mach-omap2/clock.h
new file mode 100644
index 000000000000..4aeab5591bd3
--- /dev/null
+++ b/arch/arm/mach-omap2/clock.h
@@ -0,0 +1,2103 @@
+/*
+ * linux/arch/arm/mach-omap24xx/clock.h
+ *
+ * Copyright (C) 2005 Texas Instruments Inc.
+ * Richard Woodruff <r-woodruff2@ti.com>
+ * Created for OMAP2.
+ *
+ * Copyright (C) 2004 Nokia corporation
+ * Written by Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>
+ * Based on clocks.h by Tony Lindgren, Gordon McNutt and RidgeRun, 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.
+ */
+
+#ifndef __ARCH_ARM_MACH_OMAP2_CLOCK_H
+#define __ARCH_ARM_MACH_OMAP2_CLOCK_H
+
+static void omap2_sys_clk_recalc(struct clk * clk);
+static void omap2_clksel_recalc(struct clk * clk);
+static void omap2_followparent_recalc(struct clk * clk);
+static void omap2_propagate_rate(struct clk * clk);
+static void omap2_mpu_recalc(struct clk * clk);
+static int omap2_select_table_rate(struct clk * clk, unsigned long rate);
+static long omap2_round_to_table_rate(struct clk * clk, unsigned long rate);
+static void omap2_clk_unuse(struct clk *clk);
+static void omap2_sys_clk_recalc(struct clk * clk);
+static u32 omap2_clksel_to_divisor(u32 div_sel, u32 field_val);
+static u32 omap2_clksel_get_divisor(struct clk *clk);
+
+
+#define RATE_IN_242X (1 << 0)
+#define RATE_IN_243X (1 << 1)
+
+/* Memory timings */
+#define M_DDR 1
+#define M_LOCK_CTRL (1 << 2)
+#define M_UNLOCK 0
+#define M_LOCK 1
+
+struct memory_timings {
+ u32 m_type; /* ddr = 1, sdr = 0 */
+ u32 dll_mode; /* use lock mode = 1, unlock mode = 0 */
+ u32 slow_dll_ctrl; /* unlock mode, dll value for slow speed */
+ u32 fast_dll_ctrl; /* unlock mode, dll value for fast speed */
+ u32 base_cs; /* base chip select to use for calculations */
+};
+
+/* Key dividers which make up a PRCM set. Ratio's for a PRCM are mandated.
+ * xtal_speed, dpll_speed, mpu_speed, CM_CLKSEL_MPU,CM_CLKSEL_DSP
+ * CM_CLKSEL_GFX, CM_CLKSEL1_CORE, CM_CLKSEL1_PLL CM_CLKSEL2_PLL, CM_CLKSEL_MDM
+ */
+struct prcm_config {
+ unsigned long xtal_speed; /* crystal rate */
+ unsigned long dpll_speed; /* dpll: out*xtal*M/(N-1)table_recalc */
+ unsigned long mpu_speed; /* speed of MPU */
+ unsigned long cm_clksel_mpu; /* mpu divider */
+ unsigned long cm_clksel_dsp; /* dsp+iva1 div(2420), iva2.1(2430) */
+ unsigned long cm_clksel_gfx; /* gfx dividers */
+ unsigned long cm_clksel1_core; /* major subsystem dividers */
+ unsigned long cm_clksel1_pll; /* m,n */
+ unsigned long cm_clksel2_pll; /* dpllx1 or x2 out */
+ unsigned long cm_clksel_mdm; /* modem dividers 2430 only */
+ unsigned long base_sdrc_rfr; /* base refresh timing for a set */
+ unsigned char flags;
+};
+
+/* Mask for clksel which support parent settign in set_rate */
+#define SRC_SEL_MASK (CM_CORE_SEL1 | CM_CORE_SEL2 | CM_WKUP_SEL1 | \
+ CM_PLL_SEL1 | CM_PLL_SEL2 | CM_SYSCLKOUT_SEL1)
+
+/* Mask for clksel regs which support rate operations */
+#define SRC_RATE_SEL_MASK (CM_MPU_SEL1 | CM_DSP_SEL1 | CM_GFX_SEL1 | \
+ CM_MODEM_SEL1 | CM_CORE_SEL1 | CM_CORE_SEL2 | \
+ CM_WKUP_SEL1 | CM_PLL_SEL1 | CM_PLL_SEL2 | \
+ CM_SYSCLKOUT_SEL1)
+
+/*
+ * The OMAP2 processor can be run at several discrete 'PRCM configurations'.
+ * These configurations are characterized by voltage and speed for clocks.
+ * The device is only validated for certain combinations. One way to express
+ * these combinations is via the 'ratio's' which the clocks operate with
+ * respect to each other. These ratio sets are for a given voltage/DPLL
+ * setting. All configurations can be described by a DPLL setting and a ratio
+ * There are 3 ratio sets for the 2430 and X ratio sets for 2420.
+ *
+ * 2430 differs from 2420 in that there are no more phase synchronizers used.
+ * They both have a slightly different clock domain setup. 2420(iva1,dsp) vs
+ * 2430 (iva2.1, NOdsp, mdm)
+ */
+
+/* Core fields for cm_clksel, not ratio governed */
+#define RX_CLKSEL_DSS1 (0x10 << 8)
+#define RX_CLKSEL_DSS2 (0x0 << 13)
+#define RX_CLKSEL_SSI (0x5 << 20)
+
+/*-------------------------------------------------------------------------
+ * Voltage/DPLL ratios
+ *-------------------------------------------------------------------------*/
+
+/* 2430 Ratio's, 2430-Ratio Config 1 */
+#define R1_CLKSEL_L3 (4 << 0)
+#define R1_CLKSEL_L4 (2 << 5)
+#define R1_CLKSEL_USB (4 << 25)
+#define R1_CM_CLKSEL1_CORE_VAL R1_CLKSEL_USB | RX_CLKSEL_SSI | \
+ RX_CLKSEL_DSS2 | RX_CLKSEL_DSS1 | \
+ R1_CLKSEL_L4 | R1_CLKSEL_L3
+#define R1_CLKSEL_MPU (2 << 0)
+#define R1_CM_CLKSEL_MPU_VAL R1_CLKSEL_MPU
+#define R1_CLKSEL_DSP (2 << 0)
+#define R1_CLKSEL_DSP_IF (2 << 5)
+#define R1_CM_CLKSEL_DSP_VAL R1_CLKSEL_DSP | R1_CLKSEL_DSP_IF
+#define R1_CLKSEL_GFX (2 << 0)
+#define R1_CM_CLKSEL_GFX_VAL R1_CLKSEL_GFX
+#define R1_CLKSEL_MDM (4 << 0)
+#define R1_CM_CLKSEL_MDM_VAL R1_CLKSEL_MDM
+
+/* 2430-Ratio Config 2 */
+#define R2_CLKSEL_L3 (6 << 0)
+#define R2_CLKSEL_L4 (2 << 5)
+#define R2_CLKSEL_USB (2 << 25)
+#define R2_CM_CLKSEL1_CORE_VAL R2_CLKSEL_USB | RX_CLKSEL_SSI | \
+ RX_CLKSEL_DSS2 | RX_CLKSEL_DSS1 | \
+ R2_CLKSEL_L4 | R2_CLKSEL_L3
+#define R2_CLKSEL_MPU (2 << 0)
+#define R2_CM_CLKSEL_MPU_VAL R2_CLKSEL_MPU
+#define R2_CLKSEL_DSP (2 << 0)
+#define R2_CLKSEL_DSP_IF (3 << 5)
+#define R2_CM_CLKSEL_DSP_VAL R2_CLKSEL_DSP | R2_CLKSEL_DSP_IF
+#define R2_CLKSEL_GFX (2 << 0)
+#define R2_CM_CLKSEL_GFX_VAL R2_CLKSEL_GFX
+#define R2_CLKSEL_MDM (6 << 0)
+#define R2_CM_CLKSEL_MDM_VAL R2_CLKSEL_MDM
+
+/* 2430-Ratio Bootm (BYPASS) */
+#define RB_CLKSEL_L3 (1 << 0)
+#define RB_CLKSEL_L4 (1 << 5)
+#define RB_CLKSEL_USB (1 << 25)
+#define RB_CM_CLKSEL1_CORE_VAL RB_CLKSEL_USB | RX_CLKSEL_SSI | \
+ RX_CLKSEL_DSS2 | RX_CLKSEL_DSS1 | \
+ RB_CLKSEL_L4 | RB_CLKSEL_L3
+#define RB_CLKSEL_MPU (1 << 0)
+#define RB_CM_CLKSEL_MPU_VAL RB_CLKSEL_MPU
+#define RB_CLKSEL_DSP (1 << 0)
+#define RB_CLKSEL_DSP_IF (1 << 5)
+#define RB_CM_CLKSEL_DSP_VAL RB_CLKSEL_DSP | RB_CLKSEL_DSP_IF
+#define RB_CLKSEL_GFX (1 << 0)
+#define RB_CM_CLKSEL_GFX_VAL RB_CLKSEL_GFX
+#define RB_CLKSEL_MDM (1 << 0)
+#define RB_CM_CLKSEL_MDM_VAL RB_CLKSEL_MDM
+
+/* 2420 Ratio Equivalents */
+#define RXX_CLKSEL_VLYNQ (0x12 << 15)
+#define RXX_CLKSEL_SSI (0x8 << 20)
+
+/* 2420-PRCM III 532MHz core */
+#define RIII_CLKSEL_L3 (4 << 0) /* 133MHz */
+#define RIII_CLKSEL_L4 (2 << 5) /* 66.5MHz */
+#define RIII_CLKSEL_USB (4 << 25) /* 33.25MHz */
+#define RIII_CM_CLKSEL1_CORE_VAL RIII_CLKSEL_USB | RXX_CLKSEL_SSI | \
+ RXX_CLKSEL_VLYNQ | RX_CLKSEL_DSS2 | \
+ RX_CLKSEL_DSS1 | RIII_CLKSEL_L4 | \
+ RIII_CLKSEL_L3
+#define RIII_CLKSEL_MPU (2 << 0) /* 266MHz */
+#define RIII_CM_CLKSEL_MPU_VAL RIII_CLKSEL_MPU
+#define RIII_CLKSEL_DSP (3 << 0) /* c5x - 177.3MHz */
+#define RIII_CLKSEL_DSP_IF (2 << 5) /* c5x - 88.67MHz */
+#define RIII_SYNC_DSP (1 << 7) /* Enable sync */
+#define RIII_CLKSEL_IVA (6 << 8) /* iva1 - 88.67MHz */
+#define RIII_SYNC_IVA (1 << 13) /* Enable sync */
+#define RIII_CM_CLKSEL_DSP_VAL RIII_SYNC_IVA | RIII_CLKSEL_IVA | \
+ RIII_SYNC_DSP | RIII_CLKSEL_DSP_IF | \
+ RIII_CLKSEL_DSP
+#define RIII_CLKSEL_GFX (2 << 0) /* 66.5MHz */
+#define RIII_CM_CLKSEL_GFX_VAL RIII_CLKSEL_GFX
+
+/* 2420-PRCM II 600MHz core */
+#define RII_CLKSEL_L3 (6 << 0) /* 100MHz */
+#define RII_CLKSEL_L4 (2 << 5) /* 50MHz */
+#define RII_CLKSEL_USB (2 << 25) /* 50MHz */
+#define RII_CM_CLKSEL1_CORE_VAL RII_CLKSEL_USB | \
+ RXX_CLKSEL_SSI | RXX_CLKSEL_VLYNQ | \
+ RX_CLKSEL_DSS2 | RX_CLKSEL_DSS1 | \
+ RII_CLKSEL_L4 | RII_CLKSEL_L3
+#define RII_CLKSEL_MPU (2 << 0) /* 300MHz */
+#define RII_CM_CLKSEL_MPU_VAL RII_CLKSEL_MPU
+#define RII_CLKSEL_DSP (3 << 0) /* c5x - 200MHz */
+#define RII_CLKSEL_DSP_IF (2 << 5) /* c5x - 100MHz */
+#define RII_SYNC_DSP (0 << 7) /* Bypass sync */
+#define RII_CLKSEL_IVA (6 << 8) /* iva1 - 200MHz */
+#define RII_SYNC_IVA (0 << 13) /* Bypass sync */
+#define RII_CM_CLKSEL_DSP_VAL RII_SYNC_IVA | RII_CLKSEL_IVA | \
+ RII_SYNC_DSP | RII_CLKSEL_DSP_IF | \
+ RII_CLKSEL_DSP
+#define RII_CLKSEL_GFX (2 << 0) /* 50MHz */
+#define RII_CM_CLKSEL_GFX_VAL RII_CLKSEL_GFX
+
+/* 2420-PRCM VII (boot) */
+#define RVII_CLKSEL_L3 (1 << 0)
+#define RVII_CLKSEL_L4 (1 << 5)
+#define RVII_CLKSEL_DSS1 (1 << 8)
+#define RVII_CLKSEL_DSS2 (0 << 13)
+#define RVII_CLKSEL_VLYNQ (1 << 15)
+#define RVII_CLKSEL_SSI (1 << 20)
+#define RVII_CLKSEL_USB (1 << 25)
+
+#define RVII_CM_CLKSEL1_CORE_VAL RVII_CLKSEL_USB | RVII_CLKSEL_SSI | \
+ RVII_CLKSEL_VLYNQ | RVII_CLKSEL_DSS2 | \
+ RVII_CLKSEL_DSS1 | RVII_CLKSEL_L4 | RVII_CLKSEL_L3
+
+#define RVII_CLKSEL_MPU (1 << 0) /* all divide by 1 */
+#define RVII_CM_CLKSEL_MPU_VAL RVII_CLKSEL_MPU
+
+#define RVII_CLKSEL_DSP (1 << 0)
+#define RVII_CLKSEL_DSP_IF (1 << 5)
+#define RVII_SYNC_DSP (0 << 7)
+#define RVII_CLKSEL_IVA (1 << 8)
+#define RVII_SYNC_IVA (0 << 13)
+#define RVII_CM_CLKSEL_DSP_VAL RVII_SYNC_IVA | RVII_CLKSEL_IVA | RVII_SYNC_DSP | \
+ RVII_CLKSEL_DSP_IF | RVII_CLKSEL_DSP
+
+#define RVII_CLKSEL_GFX (1 << 0)
+#define RVII_CM_CLKSEL_GFX_VAL RVII_CLKSEL_GFX
+
+/*-------------------------------------------------------------------------
+ * 2430 Target modes: Along with each configuration the CPU has several
+ * modes which goes along with them. Modes mainly are the addition of
+ * describe DPLL combinations to go along with a ratio.
+ *-------------------------------------------------------------------------*/
+
+/* Hardware governed */
+#define MX_48M_SRC (0 << 3)
+#define MX_54M_SRC (0 << 5)
+#define MX_APLLS_CLIKIN_12 (3 << 23)
+#define MX_APLLS_CLIKIN_13 (2 << 23)
+#define MX_APLLS_CLIKIN_19_2 (0 << 23)
+
+/*
+ * 2430 - standalone, 2*ref*M/(n+1), M/N is for exactness not relock speed
+ * #2 (ratio1) baseport-target
+ * #5a (ratio1) baseport-target, target DPLL = 266*2 = 532MHz
+ */
+#define M5A_DPLL_MULT_12 (133 << 12)
+#define M5A_DPLL_DIV_12 (5 << 8)
+#define M5A_CM_CLKSEL1_PLL_12_VAL MX_48M_SRC | MX_54M_SRC | \
+ M5A_DPLL_DIV_12 | M5A_DPLL_MULT_12 | \
+ MX_APLLS_CLIKIN_12
+#define M5A_DPLL_MULT_13 (266 << 12)
+#define M5A_DPLL_DIV_13 (12 << 8)
+#define M5A_CM_CLKSEL1_PLL_13_VAL MX_48M_SRC | MX_54M_SRC | \
+ M5A_DPLL_DIV_13 | M5A_DPLL_MULT_13 | \
+ MX_APLLS_CLIKIN_13
+#define M5A_DPLL_MULT_19 (180 << 12)
+#define M5A_DPLL_DIV_19 (12 << 8)
+#define M5A_CM_CLKSEL1_PLL_19_VAL MX_48M_SRC | MX_54M_SRC | \
+ M5A_DPLL_DIV_19 | M5A_DPLL_MULT_19 | \
+ MX_APLLS_CLIKIN_19_2
+/* #5b (ratio1) target DPLL = 200*2 = 400MHz */
+#define M5B_DPLL_MULT_12 (50 << 12)
+#define M5B_DPLL_DIV_12 (2 << 8)
+#define M5B_CM_CLKSEL1_PLL_12_VAL MX_48M_SRC | MX_54M_SRC | \
+ M5B_DPLL_DIV_12 | M5B_DPLL_MULT_12 | \
+ MX_APLLS_CLIKIN_12
+#define M5B_DPLL_MULT_13 (200 << 12)
+#define M5B_DPLL_DIV_13 (12 << 8)
+
+#define M5B_CM_CLKSEL1_PLL_13_VAL MX_48M_SRC | MX_54M_SRC | \
+ M5B_DPLL_DIV_13 | M5B_DPLL_MULT_13 | \
+ MX_APLLS_CLIKIN_13
+#define M5B_DPLL_MULT_19 (125 << 12)
+#define M5B_DPLL_DIV_19 (31 << 8)
+#define M5B_CM_CLKSEL1_PLL_19_VAL MX_48M_SRC | MX_54M_SRC | \
+ M5B_DPLL_DIV_19 | M5B_DPLL_MULT_19 | \
+ MX_APLLS_CLIKIN_19_2
+/*
+ * #4 (ratio2)
+ * #3 (ratio2) baseport-target, target DPLL = 330*2 = 660MHz
+ */
+#define M3_DPLL_MULT_12 (55 << 12)
+#define M3_DPLL_DIV_12 (1 << 8)
+#define M3_CM_CLKSEL1_PLL_12_VAL MX_48M_SRC | MX_54M_SRC | \
+ M3_DPLL_DIV_12 | M3_DPLL_MULT_12 | \
+ MX_APLLS_CLIKIN_12
+#define M3_DPLL_MULT_13 (330 << 12)
+#define M3_DPLL_DIV_13 (12 << 8)
+#define M3_CM_CLKSEL1_PLL_13_VAL MX_48M_SRC | MX_54M_SRC | \
+ M3_DPLL_DIV_13 | M3_DPLL_MULT_13 | \
+ MX_APLLS_CLIKIN_13
+#define M3_DPLL_MULT_19 (275 << 12)
+#define M3_DPLL_DIV_19 (15 << 8)
+#define M3_CM_CLKSEL1_PLL_19_VAL MX_48M_SRC | MX_54M_SRC | \
+ M3_DPLL_DIV_19 | M3_DPLL_MULT_19 | \
+ MX_APLLS_CLIKIN_19_2
+/* boot (boot) */
+#define MB_DPLL_MULT (1 << 12)
+#define MB_DPLL_DIV (0 << 8)
+#define MB_CM_CLKSEL1_PLL_12_VAL MX_48M_SRC | MX_54M_SRC | MB_DPLL_DIV |\
+ MB_DPLL_MULT | MX_APLLS_CLIKIN_12
+
+#define MB_CM_CLKSEL1_PLL_13_VAL MX_48M_SRC | MX_54M_SRC | MB_DPLL_DIV |\
+ MB_DPLL_MULT | MX_APLLS_CLIKIN_13
+
+#define MB_CM_CLKSEL1_PLL_19_VAL MX_48M_SRC | MX_54M_SRC | MB_DPLL_DIV |\
+ MB_DPLL_MULT | MX_APLLS_CLIKIN_19
+
+/*
+ * 2430 - chassis (sedna)
+ * 165 (ratio1) same as above #2
+ * 150 (ratio1)
+ * 133 (ratio2) same as above #4
+ * 110 (ratio2) same as above #3
+ * 104 (ratio2)
+ * boot (boot)
+ */
+
+/*
+ * 2420 Equivalent - mode registers
+ * PRCM II , target DPLL = 2*300MHz = 600MHz
+ */
+#define MII_DPLL_MULT_12 (50 << 12)
+#define MII_DPLL_DIV_12 (1 << 8)
+#define MII_CM_CLKSEL1_PLL_12_VAL MX_48M_SRC | MX_54M_SRC | \
+ MII_DPLL_DIV_12 | MII_DPLL_MULT_12 | \
+ MX_APLLS_CLIKIN_12
+#define MII_DPLL_MULT_13 (300 << 12)
+#define MII_DPLL_DIV_13 (12 << 8)
+#define MII_CM_CLKSEL1_PLL_13_VAL MX_48M_SRC | MX_54M_SRC | \
+ MII_DPLL_DIV_13 | MII_DPLL_MULT_13 | \
+ MX_APLLS_CLIKIN_13
+
+/* PRCM III target DPLL = 2*266 = 532MHz*/
+#define MIII_DPLL_MULT_12 (133 << 12)
+#define MIII_DPLL_DIV_12 (5 << 8)
+#define MIII_CM_CLKSEL1_PLL_12_VAL MX_48M_SRC | MX_54M_SRC | \
+ MIII_DPLL_DIV_12 | MIII_DPLL_MULT_12 | \
+ MX_APLLS_CLIKIN_12
+#define MIII_DPLL_MULT_13 (266 << 12)
+#define MIII_DPLL_DIV_13 (12 << 8)
+#define MIII_CM_CLKSEL1_PLL_13_VAL MX_48M_SRC | MX_54M_SRC | \
+ MIII_DPLL_DIV_13 | MIII_DPLL_MULT_13 | \
+ MX_APLLS_CLIKIN_13
+
+/* PRCM VII (boot bypass) */
+#define MVII_CM_CLKSEL1_PLL_12_VAL MB_CM_CLKSEL1_PLL_12_VAL
+#define MVII_CM_CLKSEL1_PLL_13_VAL MB_CM_CLKSEL1_PLL_13_VAL
+
+/* High and low operation value */
+#define MX_CLKSEL2_PLL_2x_VAL (2 << 0)
+#define MX_CLKSEL2_PLL_1x_VAL (1 << 0)
+
+/*
+ * These represent optimal values for common parts, it won't work for all.
+ * As long as you scale down, most parameters are still work, they just
+ * become sub-optimal. The RFR value goes in the oppisite direction. If you
+ * don't adjust it down as your clock period increases the refresh interval
+ * will not be met. Setting all parameters for complete worst case may work,
+ * but may cut memory performance by 2x. Due to errata the DLLs need to be
+ * unlocked and their value needs run time calibration. A dynamic call is
+ * need for that as no single right value exists acorss production samples.
+ *
+ * Only the FULL speed values are given. Current code is such that rate
+ * changes must be made at DPLLoutx2. The actual value adjustment for low
+ * frequency operation will be handled by omap_set_performance()
+ *
+ * By having the boot loader boot up in the fastest L4 speed available likely
+ * will result in something which you can switch between.
+ */
+#define V24XX_SDRC_RFR_CTRL_133MHz (0x0003de00 | 1)
+#define V24XX_SDRC_RFR_CTRL_100MHz (0x0002da01 | 1)
+#define V24XX_SDRC_RFR_CTRL_110MHz (0x0002da01 | 1) /* Need to calc */
+#define V24XX_SDRC_RFR_CTRL_BYPASS (0x00005000 | 1) /* Need to calc */
+
+/* MPU speed defines */
+#define S12M 12000000
+#define S13M 13000000
+#define S19M 19200000
+#define S26M 26000000
+#define S100M 100000000
+#define S133M 133000000
+#define S150M 150000000
+#define S165M 165000000
+#define S200M 200000000
+#define S266M 266000000
+#define S300M 300000000
+#define S330M 330000000
+#define S400M 400000000
+#define S532M 532000000
+#define S600M 600000000
+#define S660M 660000000
+
+/*-------------------------------------------------------------------------
+ * Key dividers which make up a PRCM set. Ratio's for a PRCM are mandated.
+ * xtal_speed, dpll_speed, mpu_speed, CM_CLKSEL_MPU,
+ * CM_CLKSEL_DSP, CM_CLKSEL_GFX, CM_CLKSEL1_CORE, CM_CLKSEL1_PLL,
+ * CM_CLKSEL2_PLL, CM_CLKSEL_MDM
+ *
+ * Filling in table based on H4 boards and 2430-SDPs variants available.
+ * There are quite a few more rates combinations which could be defined.
+ *
+ * When multiple values are defiend the start up will try and choose the
+ * fastest one. If a 'fast' value is defined, then automatically, the /2
+ * one should be included as it can be used. Generally having more that
+ * one fast set does not make sense, as static timings need to be changed
+ * to change the set. The exception is the bypass setting which is
+ * availble for low power bypass.
+ *
+ * Note: This table needs to be sorted, fastest to slowest.
+ *-------------------------------------------------------------------------*/
+static struct prcm_config rate_table[] = {
+ /* PRCM II - FAST */
+ {S12M, S600M, S300M, RII_CM_CLKSEL_MPU_VAL, /* 300MHz ARM */
+ RII_CM_CLKSEL_DSP_VAL, RII_CM_CLKSEL_GFX_VAL,
+ RII_CM_CLKSEL1_CORE_VAL, MII_CM_CLKSEL1_PLL_12_VAL,
+ MX_CLKSEL2_PLL_2x_VAL, 0, V24XX_SDRC_RFR_CTRL_100MHz,
+ RATE_IN_242X},
+
+ {S13M, S600M, S300M, RII_CM_CLKSEL_MPU_VAL, /* 300MHz ARM */
+ RII_CM_CLKSEL_DSP_VAL, RII_CM_CLKSEL_GFX_VAL,
+ RII_CM_CLKSEL1_CORE_VAL, MII_CM_CLKSEL1_PLL_13_VAL,
+ MX_CLKSEL2_PLL_2x_VAL, 0, V24XX_SDRC_RFR_CTRL_100MHz,
+ RATE_IN_242X},
+
+ /* PRCM III - FAST */
+ {S12M, S532M, S266M, RIII_CM_CLKSEL_MPU_VAL, /* 266MHz ARM */
+ RIII_CM_CLKSEL_DSP_VAL, RIII_CM_CLKSEL_GFX_VAL,
+ RIII_CM_CLKSEL1_CORE_VAL, MIII_CM_CLKSEL1_PLL_12_VAL,
+ MX_CLKSEL2_PLL_2x_VAL, 0, V24XX_SDRC_RFR_CTRL_133MHz,
+ RATE_IN_242X},
+
+ {S13M, S532M, S266M, RIII_CM_CLKSEL_MPU_VAL, /* 266MHz ARM */
+ RIII_CM_CLKSEL_DSP_VAL, RIII_CM_CLKSEL_GFX_VAL,
+ RIII_CM_CLKSEL1_CORE_VAL, MIII_CM_CLKSEL1_PLL_13_VAL,
+ MX_CLKSEL2_PLL_2x_VAL, 0, V24XX_SDRC_RFR_CTRL_133MHz,
+ RATE_IN_242X},
+
+ /* PRCM II - SLOW */
+ {S12M, S300M, S150M, RII_CM_CLKSEL_MPU_VAL, /* 150MHz ARM */
+ RII_CM_CLKSEL_DSP_VAL, RII_CM_CLKSEL_GFX_VAL,
+ RII_CM_CLKSEL1_CORE_VAL, MII_CM_CLKSEL1_PLL_12_VAL,
+ MX_CLKSEL2_PLL_2x_VAL, 0, V24XX_SDRC_RFR_CTRL_100MHz,
+ RATE_IN_242X},
+
+ {S13M, S300M, S150M, RII_CM_CLKSEL_MPU_VAL, /* 150MHz ARM */
+ RII_CM_CLKSEL_DSP_VAL, RII_CM_CLKSEL_GFX_VAL,
+ RII_CM_CLKSEL1_CORE_VAL, MII_CM_CLKSEL1_PLL_13_VAL,
+ MX_CLKSEL2_PLL_2x_VAL, 0, V24XX_SDRC_RFR_CTRL_100MHz,
+ RATE_IN_242X},
+
+ /* PRCM III - SLOW */
+ {S12M, S266M, S133M, RIII_CM_CLKSEL_MPU_VAL, /* 133MHz ARM */
+ RIII_CM_CLKSEL_DSP_VAL, RIII_CM_CLKSEL_GFX_VAL,
+ RIII_CM_CLKSEL1_CORE_VAL, MIII_CM_CLKSEL1_PLL_12_VAL,
+ MX_CLKSEL2_PLL_2x_VAL, 0, V24XX_SDRC_RFR_CTRL_133MHz,
+ RATE_IN_242X},
+
+ {S13M, S266M, S133M, RIII_CM_CLKSEL_MPU_VAL, /* 133MHz ARM */
+ RIII_CM_CLKSEL_DSP_VAL, RIII_CM_CLKSEL_GFX_VAL,
+ RIII_CM_CLKSEL1_CORE_VAL, MIII_CM_CLKSEL1_PLL_13_VAL,
+ MX_CLKSEL2_PLL_2x_VAL, 0, V24XX_SDRC_RFR_CTRL_133MHz,
+ RATE_IN_242X},
+
+ /* PRCM-VII (boot-bypass) */
+ {S12M, S12M, S12M, RVII_CM_CLKSEL_MPU_VAL, /* 12MHz ARM*/
+ RVII_CM_CLKSEL_DSP_VAL, RVII_CM_CLKSEL_GFX_VAL,
+ RVII_CM_CLKSEL1_CORE_VAL, MVII_CM_CLKSEL1_PLL_12_VAL,
+ MX_CLKSEL2_PLL_2x_VAL, 0, V24XX_SDRC_RFR_CTRL_BYPASS,
+ RATE_IN_242X},
+
+ /* PRCM-VII (boot-bypass) */
+ {S13M, S13M, S13M, RVII_CM_CLKSEL_MPU_VAL, /* 13MHz ARM */
+ RVII_CM_CLKSEL_DSP_VAL, RVII_CM_CLKSEL_GFX_VAL,
+ RVII_CM_CLKSEL1_CORE_VAL, MVII_CM_CLKSEL1_PLL_13_VAL,
+ MX_CLKSEL2_PLL_2x_VAL, 0, V24XX_SDRC_RFR_CTRL_BYPASS,
+ RATE_IN_242X},
+
+ /* PRCM #3 - ratio2 (ES2) - FAST */
+ {S13M, S660M, S330M, R2_CM_CLKSEL_MPU_VAL, /* 330MHz ARM */
+ R2_CM_CLKSEL_DSP_VAL, R2_CM_CLKSEL_GFX_VAL,
+ R2_CM_CLKSEL1_CORE_VAL, M3_CM_CLKSEL1_PLL_13_VAL,
+ MX_CLKSEL2_PLL_2x_VAL, R2_CM_CLKSEL_MDM_VAL,
+ V24XX_SDRC_RFR_CTRL_110MHz,
+ RATE_IN_243X},
+
+ /* PRCM #5a - ratio1 - FAST */
+ {S13M, S532M, S266M, R1_CM_CLKSEL_MPU_VAL, /* 266MHz ARM */
+ R1_CM_CLKSEL_DSP_VAL, R1_CM_CLKSEL_GFX_VAL,
+ R1_CM_CLKSEL1_CORE_VAL, M5A_CM_CLKSEL1_PLL_13_VAL,
+ MX_CLKSEL2_PLL_2x_VAL, R1_CM_CLKSEL_MDM_VAL,
+ V24XX_SDRC_RFR_CTRL_133MHz,
+ RATE_IN_243X},
+
+ /* PRCM #5b - ratio1 - FAST */
+ {S13M, S400M, S200M, R1_CM_CLKSEL_MPU_VAL, /* 200MHz ARM */
+ R1_CM_CLKSEL_DSP_VAL, R1_CM_CLKSEL_GFX_VAL,
+ R1_CM_CLKSEL1_CORE_VAL, M5B_CM_CLKSEL1_PLL_13_VAL,
+ MX_CLKSEL2_PLL_2x_VAL, R1_CM_CLKSEL_MDM_VAL,
+ V24XX_SDRC_RFR_CTRL_100MHz,
+ RATE_IN_243X},
+
+ /* PRCM #3 - ratio2 (ES2) - SLOW */
+ {S13M, S330M, S165M, R2_CM_CLKSEL_MPU_VAL, /* 165MHz ARM */
+ R2_CM_CLKSEL_DSP_VAL, R2_CM_CLKSEL_GFX_VAL,
+ R2_CM_CLKSEL1_CORE_VAL, M3_CM_CLKSEL1_PLL_13_VAL,
+ MX_CLKSEL2_PLL_1x_VAL, R2_CM_CLKSEL_MDM_VAL,
+ V24XX_SDRC_RFR_CTRL_110MHz,
+ RATE_IN_243X},
+
+ /* PRCM #5a - ratio1 - SLOW */
+ {S13M, S266M, S133M, R1_CM_CLKSEL_MPU_VAL, /* 133MHz ARM */
+ R1_CM_CLKSEL_DSP_VAL, R1_CM_CLKSEL_GFX_VAL,
+ R1_CM_CLKSEL1_CORE_VAL, M5A_CM_CLKSEL1_PLL_13_VAL,
+ MX_CLKSEL2_PLL_1x_VAL, R1_CM_CLKSEL_MDM_VAL,
+ V24XX_SDRC_RFR_CTRL_133MHz,
+ RATE_IN_243X},
+
+ /* PRCM #5b - ratio1 - SLOW*/
+ {S13M, S200M, S100M, R1_CM_CLKSEL_MPU_VAL, /* 100MHz ARM */
+ R1_CM_CLKSEL_DSP_VAL, R1_CM_CLKSEL_GFX_VAL,
+ R1_CM_CLKSEL1_CORE_VAL, M5B_CM_CLKSEL1_PLL_13_VAL,
+ MX_CLKSEL2_PLL_1x_VAL, R1_CM_CLKSEL_MDM_VAL,
+ V24XX_SDRC_RFR_CTRL_100MHz,
+ RATE_IN_243X},
+
+ /* PRCM-boot/bypass */
+ {S13M, S13M, S13M, RB_CM_CLKSEL_MPU_VAL, /* 13Mhz */
+ RB_CM_CLKSEL_DSP_VAL, RB_CM_CLKSEL_GFX_VAL,
+ RB_CM_CLKSEL1_CORE_VAL, MB_CM_CLKSEL1_PLL_13_VAL,
+ MX_CLKSEL2_PLL_2x_VAL, RB_CM_CLKSEL_MDM_VAL,
+ V24XX_SDRC_RFR_CTRL_BYPASS,
+ RATE_IN_243X},
+
+ /* PRCM-boot/bypass */
+ {S12M, S12M, S12M, RB_CM_CLKSEL_MPU_VAL, /* 12Mhz */
+ RB_CM_CLKSEL_DSP_VAL, RB_CM_CLKSEL_GFX_VAL,
+ RB_CM_CLKSEL1_CORE_VAL, MB_CM_CLKSEL1_PLL_12_VAL,
+ MX_CLKSEL2_PLL_2x_VAL, RB_CM_CLKSEL_MDM_VAL,
+ V24XX_SDRC_RFR_CTRL_BYPASS,
+ RATE_IN_243X},
+
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+};
+
+/*-------------------------------------------------------------------------
+ * 24xx clock tree.
+ *
+ * NOTE:In many cases here we are assigning a 'default' parent. In many
+ * cases the parent is selectable. The get/set parent calls will also
+ * switch sources.
+ *
+ * Many some clocks say always_enabled, but they can be auto idled for
+ * power savings. They will always be available upon clock request.
+ *
+ * Several sources are given initial rates which may be wrong, this will
+ * be fixed up in the init func.
+ *
+ * Things are broadly separated below by clock domains. It is
+ * noteworthy that most periferals have dependencies on multiple clock
+ * domains. Many get their interface clocks from the L4 domain, but get
+ * functional clocks from fixed sources or other core domain derived
+ * clocks.
+ *-------------------------------------------------------------------------*/
+
+/* Base external input clocks */
+static struct clk func_32k_ck = {
+ .name = "func_32k_ck",
+ .rate = 32000,
+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
+ RATE_FIXED | ALWAYS_ENABLED,
+};
+
+/* Typical 12/13MHz in standalone mode, will be 26Mhz in chassis mode */
+static struct clk osc_ck = { /* (*12, *13, 19.2, *26, 38.4)MHz */
+ .name = "osc_ck",
+ .rate = 26000000, /* fixed up in clock init */
+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
+ RATE_FIXED | ALWAYS_ENABLED | RATE_PROPAGATES,
+};
+
+/* With out modem likely 12MHz, with modem likely 13MHz */
+static struct clk sys_ck = { /* (*12, *13, 19.2, 26, 38.4)MHz */
+ .name = "sys_ck", /* ~ ref_clk also */
+ .parent = &osc_ck,
+ .rate = 13000000,
+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
+ RATE_FIXED | ALWAYS_ENABLED | RATE_PROPAGATES,
+ .rate_offset = 6, /* sysclkdiv 1 or 2, already handled or no boot */
+ .recalc = &omap2_sys_clk_recalc,
+};
+
+static struct clk alt_ck = { /* Typical 54M or 48M, may not exist */
+ .name = "alt_ck",
+ .rate = 54000000,
+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
+ RATE_FIXED | ALWAYS_ENABLED | RATE_PROPAGATES,
+ .recalc = &omap2_propagate_rate,
+};
+
+/*
+ * Analog domain root source clocks
+ */
+
+/* dpll_ck, is broken out in to special cases through clksel */
+static struct clk dpll_ck = {
+ .name = "dpll_ck",
+ .parent = &sys_ck, /* Can be func_32k also */
+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
+ RATE_PROPAGATES | RATE_CKCTL | CM_PLL_SEL1,
+ .recalc = &omap2_clksel_recalc,
+};
+
+static struct clk apll96_ck = {
+ .name = "apll96_ck",
+ .parent = &sys_ck,
+ .rate = 96000000,
+ .flags = CLOCK_IN_OMAP242X |CLOCK_IN_OMAP243X |
+ RATE_FIXED | RATE_PROPAGATES,
+ .enable_reg = (void __iomem *)&CM_CLKEN_PLL,
+ .enable_bit = 0x2,
+ .recalc = &omap2_propagate_rate,
+};
+
+static struct clk apll54_ck = {
+ .name = "apll54_ck",
+ .parent = &sys_ck,
+ .rate = 54000000,
+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
+ RATE_FIXED | RATE_PROPAGATES,
+ .enable_reg = (void __iomem *)&CM_CLKEN_PLL,
+ .enable_bit = 0x6,
+ .recalc = &omap2_propagate_rate,
+};
+
+/*
+ * PRCM digital base sources
+ */
+static struct clk func_54m_ck = {
+ .name = "func_54m_ck",
+ .parent = &apll54_ck, /* can also be alt_clk */
+ .rate = 54000000,
+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
+ RATE_FIXED | CM_PLL_SEL1 | RATE_PROPAGATES,
+ .src_offset = 5,
+ .enable_reg = (void __iomem *)&CM_CLKEN_PLL,
+ .enable_bit = 0xff,
+ .recalc = &omap2_propagate_rate,
+};
+
+static struct clk core_ck = {
+ .name = "core_ck",
+ .parent = &dpll_ck, /* can also be 32k */
+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
+ ALWAYS_ENABLED | RATE_PROPAGATES,
+ .recalc = &omap2_propagate_rate,
+};
+
+static struct clk sleep_ck = { /* sys_clk or 32k */
+ .name = "sleep_ck",
+ .parent = &func_32k_ck,
+ .rate = 32000,
+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+ .recalc = &omap2_propagate_rate,
+};
+
+static struct clk func_96m_ck = {
+ .name = "func_96m_ck",
+ .parent = &apll96_ck,
+ .rate = 96000000,
+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
+ RATE_FIXED | RATE_PROPAGATES,
+ .enable_reg = (void __iomem *)&CM_CLKEN_PLL,
+ .enable_bit = 0xff,
+ .recalc = &omap2_propagate_rate,
+};
+
+static struct clk func_48m_ck = {
+ .name = "func_48m_ck",
+ .parent = &apll96_ck, /* 96M or Alt */
+ .rate = 48000000,
+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
+ RATE_FIXED | CM_PLL_SEL1 | RATE_PROPAGATES,
+ .src_offset = 3,
+ .enable_reg = (void __iomem *)&CM_CLKEN_PLL,
+ .enable_bit = 0xff,
+ .recalc = &omap2_propagate_rate,
+};
+
+static struct clk func_12m_ck = {
+ .name = "func_12m_ck",
+ .parent = &func_48m_ck,
+ .rate = 12000000,
+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
+ RATE_FIXED | RATE_PROPAGATES,
+ .recalc = &omap2_propagate_rate,
+ .enable_reg = (void __iomem *)&CM_CLKEN_PLL,
+ .enable_bit = 0xff,
+};
+
+/* Secure timer, only available in secure mode */
+static struct clk wdt1_osc_ck = {
+ .name = "ck_wdt1_osc",
+ .parent = &osc_ck,
+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+ .recalc = &omap2_followparent_recalc,
+};
+
+static struct clk sys_clkout = {
+ .name = "sys_clkout",
+ .parent = &func_54m_ck,
+ .rate = 54000000,
+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
+ CM_SYSCLKOUT_SEL1 | RATE_CKCTL,
+ .src_offset = 0,
+ .enable_reg = (void __iomem *)&PRCM_CLKOUT_CTRL,
+ .enable_bit = 7,
+ .rate_offset = 3,
+ .recalc = &omap2_clksel_recalc,
+};
+
+/* In 2430, new in 2420 ES2 */
+static struct clk sys_clkout2 = {
+ .name = "sys_clkout2",
+ .parent = &func_54m_ck,
+ .rate = 54000000,
+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
+ CM_SYSCLKOUT_SEL1 | RATE_CKCTL,
+ .src_offset = 8,
+ .enable_reg = (void __iomem *)&PRCM_CLKOUT_CTRL,
+ .enable_bit = 15,
+ .rate_offset = 11,
+ .recalc = &omap2_clksel_recalc,
+};
+
+/*
+ * MPU clock domain
+ * Clocks:
+ * MPU_FCLK, MPU_ICLK
+ * INT_M_FCLK, INT_M_I_CLK
+ *
+ * - Individual clocks are hardware managed.
+ * - Base divider comes from: CM_CLKSEL_MPU
+ *
+ */
+static struct clk mpu_ck = { /* Control cpu */
+ .name = "mpu_ck",
+ .parent = &core_ck,
+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | RATE_CKCTL |
+ ALWAYS_ENABLED | CM_MPU_SEL1 | DELAYED_APP |
+ CONFIG_PARTICIPANT | RATE_PROPAGATES,
+ .rate_offset = 0, /* bits 0-4 */
+ .recalc = &omap2_clksel_recalc,
+};
+
+/*
+ * DSP (2430-IVA2.1) (2420-UMA+IVA1) clock domain
+ * Clocks:
+ * 2430: IVA2.1_FCLK, IVA2.1_ICLK
+ * 2420: UMA_FCLK, UMA_ICLK, IVA_MPU, IVA_COP
+ */
+static struct clk iva2_1_fck = {
+ .name = "iva2_1_fck",
+ .parent = &core_ck,
+ .flags = CLOCK_IN_OMAP243X | RATE_CKCTL | CM_DSP_SEL1 |
+ DELAYED_APP | RATE_PROPAGATES |
+ CONFIG_PARTICIPANT,
+ .rate_offset = 0,
+ .enable_reg = (void __iomem *)&CM_FCLKEN_DSP,
+ .enable_bit = 0,
+ .recalc = &omap2_clksel_recalc,
+};
+
+static struct clk iva2_1_ick = {
+ .name = "iva2_1_ick",
+ .parent = &iva2_1_fck,
+ .flags = CLOCK_IN_OMAP243X | RATE_CKCTL | CM_DSP_SEL1 |
+ DELAYED_APP | CONFIG_PARTICIPANT,
+ .rate_offset = 5,
+ .recalc = &omap2_clksel_recalc,
+};
+
+/*
+ * Won't be too specific here. The core clock comes into this block
+ * it is divided then tee'ed. One branch goes directly to xyz enable
+ * controls. The other branch gets further divided by 2 then possibly
+ * routed into a synchronizer and out of clocks abc.
+ */
+static struct clk dsp_fck = {
+ .name = "dsp_fck",
+ .parent = &core_ck,
+ .flags = CLOCK_IN_OMAP242X | RATE_CKCTL | CM_DSP_SEL1 |
+ DELAYED_APP | CONFIG_PARTICIPANT | RATE_PROPAGATES,
+ .rate_offset = 0,
+ .enable_reg = (void __iomem *)&CM_FCLKEN_DSP,
+ .enable_bit = 0,
+ .recalc = &omap2_clksel_recalc,
+};
+
+static struct clk dsp_ick = {
+ .name = "dsp_ick", /* apparently ipi and isp */
+ .parent = &dsp_fck,
+ .flags = CLOCK_IN_OMAP242X | RATE_CKCTL | CM_DSP_SEL1 |
+ DELAYED_APP | CONFIG_PARTICIPANT,
+ .rate_offset = 5,
+ .enable_reg = (void __iomem *)&CM_ICLKEN_DSP,
+ .enable_bit = 1, /* for ipi */
+ .recalc = &omap2_clksel_recalc,
+};
+
+static struct clk iva1_ifck = {
+ .name = "iva1_ifck",
+ .parent = &core_ck,
+ .flags = CLOCK_IN_OMAP242X | CM_DSP_SEL1 | RATE_CKCTL |
+ CONFIG_PARTICIPANT | RATE_PROPAGATES | DELAYED_APP,
+ .rate_offset= 8,
+ .enable_reg = (void __iomem *)&CM_FCLKEN_DSP,
+ .enable_bit = 10,
+ .recalc = &omap2_clksel_recalc,
+};
+
+/* IVA1 mpu/int/i/f clocks are /2 of parent */
+static struct clk iva1_mpu_int_ifck = {
+ .name = "iva1_mpu_int_ifck",
+ .parent = &iva1_ifck,
+ .flags = CLOCK_IN_OMAP242X | RATE_CKCTL | CM_DSP_SEL1,
+ .enable_reg = (void __iomem *)&CM_FCLKEN_DSP,
+ .enable_bit = 8,
+ .recalc = &omap2_clksel_recalc,
+};
+
+/*
+ * L3 clock domain
+ * L3 clocks are used for both interface and functional clocks to
+ * multiple entities. Some of these clocks are completely managed
+ * by hardware, and some others allow software control. Hardware
+ * managed ones general are based on directly CLK_REQ signals and
+ * various auto idle settings. The functional spec sets many of these
+ * as 'tie-high' for their enables.
+ *
+ * I-CLOCKS:
+ * L3-Interconnect, SMS, GPMC, SDRC, OCM_RAM, OCM_ROM, SDMA
+ * CAM, HS-USB.
+ * F-CLOCK
+ * SSI.
+ *
+ * GPMC memories and SDRC have timing and clock sensitive registers which
+ * may very well need notification when the clock changes. Currently for low
+ * operating points, these are taken care of in sleep.S.
+ */
+static struct clk core_l3_ck = { /* Used for ick and fck, interconnect */
+ .name = "core_l3_ck",
+ .parent = &core_ck,
+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
+ RATE_CKCTL | ALWAYS_ENABLED | CM_CORE_SEL1 |
+ DELAYED_APP | CONFIG_PARTICIPANT |
+ RATE_PROPAGATES,
+ .rate_offset = 0,
+ .recalc = &omap2_clksel_recalc,
+};
+
+static struct clk usb_l4_ick = { /* FS-USB interface clock */
+ .name = "usb_l4_ick",
+ .parent = &core_ck,
+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
+ RATE_CKCTL | CM_CORE_SEL1 | DELAYED_APP |
+ CONFIG_PARTICIPANT,
+ .enable_reg = (void __iomem *)&CM_ICLKEN2_CORE,
+ .enable_bit = 0,
+ .rate_offset = 25,
+ .recalc = &omap2_clksel_recalc,
+};
+
+/*
+ * SSI is in L3 management domain, its direct parent is core not l3,
+ * many core power domain entities are grouped into the L3 clock
+ * domain.
+ * SSI_SSR_FCLK, SSI_SST_FCLK, SSI_L4_CLIK
+ *
+ * ssr = core/1/2/3/4/5, sst = 1/2 ssr.
+ */
+static struct clk ssi_ssr_sst_fck = {
+ .name = "ssi_fck",
+ .parent = &core_ck,
+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
+ RATE_CKCTL | CM_CORE_SEL1 | DELAYED_APP,
+ .enable_reg = (void __iomem *)&CM_FCLKEN2_CORE, /* bit 1 */
+ .enable_bit = 1,
+ .rate_offset = 20,
+ .recalc = &omap2_clksel_recalc,
+};
+
+/*
+ * GFX clock domain
+ * Clocks:
+ * GFX_FCLK, GFX_ICLK
+ * GFX_CG1(2d), GFX_CG2(3d)
+ *
+ * GFX_FCLK runs from L3, and is divided by (1,2,3,4)
+ * The 2d and 3d clocks run at a hardware determined
+ * divided value of fclk.
+ *
+ */
+static struct clk gfx_3d_fck = {
+ .name = "gfx_3d_fck",
+ .parent = &core_l3_ck,
+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
+ RATE_CKCTL | CM_GFX_SEL1,
+ .enable_reg = (void __iomem *)&CM_FCLKEN_GFX,
+ .enable_bit = 2,
+ .rate_offset= 0,
+ .recalc = &omap2_clksel_recalc,
+};
+
+static struct clk gfx_2d_fck = {
+ .name = "gfx_2d_fck",
+ .parent = &core_l3_ck,
+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
+ RATE_CKCTL | CM_GFX_SEL1,
+ .enable_reg = (void __iomem *)&CM_FCLKEN_GFX,
+ .enable_bit = 1,
+ .rate_offset= 0,
+ .recalc = &omap2_clksel_recalc,
+};
+
+static struct clk gfx_ick = {
+ .name = "gfx_ick", /* From l3 */
+ .parent = &core_l3_ck,
+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
+ RATE_CKCTL,
+ .enable_reg = (void __iomem *)&CM_ICLKEN_GFX, /* bit 0 */
+ .enable_bit = 0,
+ .recalc = &omap2_followparent_recalc,
+};
+
+/*
+ * Modem clock domain (2430)
+ * CLOCKS:
+ * MDM_OSC_CLK
+ * MDM_ICLK
+ */
+static struct clk mdm_ick = { /* used both as a ick and fck */
+ .name = "mdm_ick",
+ .parent = &core_ck,
+ .flags = CLOCK_IN_OMAP243X | RATE_CKCTL | CM_MODEM_SEL1 |
+ DELAYED_APP | CONFIG_PARTICIPANT,
+ .rate_offset = 0,
+ .enable_reg = (void __iomem *)&CM_ICLKEN_MDM,
+ .enable_bit = 0,
+ .recalc = &omap2_clksel_recalc,
+};
+
+static struct clk mdm_osc_ck = {
+ .name = "mdm_osc_ck",
+ .rate = 26000000,
+ .parent = &osc_ck,
+ .flags = CLOCK_IN_OMAP243X | RATE_FIXED,
+ .enable_reg = (void __iomem *)&CM_FCLKEN_MDM,
+ .enable_bit = 1,
+ .recalc = &omap2_followparent_recalc,
+};
+
+/*
+ * L4 clock management domain
+ *
+ * This domain contains lots of interface clocks from the L4 interface, some
+ * functional clocks. Fixed APLL functional source clocks are managed in
+ * this domain.
+ */
+static struct clk l4_ck = { /* used both as an ick and fck */
+ .name = "l4_ck",
+ .parent = &core_l3_ck,
+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
+ RATE_CKCTL | ALWAYS_ENABLED | CM_CORE_SEL1 |
+ DELAYED_APP | RATE_PROPAGATES,
+ .rate_offset = 5,
+ .recalc = &omap2_clksel_recalc,
+};
+
+static struct clk ssi_l4_ick = {
+ .name = "ssi_l4_ick",
+ .parent = &l4_ck,
+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | RATE_CKCTL,
+ .enable_reg = (void __iomem *)&CM_ICLKEN2_CORE, /* bit 1 */
+ .enable_bit = 1,
+ .recalc = &omap2_followparent_recalc,
+};
+
+/*
+ * DSS clock domain
+ * CLOCKs:
+ * DSS_L4_ICLK, DSS_L3_ICLK,
+ * DSS_CLK1, DSS_CLK2, DSS_54MHz_CLK
+ *
+ * DSS is both initiator and target.
+ */
+static struct clk dss_ick = { /* Enables both L3,L4 ICLK's */
+ .name = "dss_ick",
+ .parent = &l4_ck, /* really both l3 and l4 */
+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | RATE_CKCTL,
+ .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE,
+ .enable_bit = 0,
+ .recalc = &omap2_followparent_recalc,
+};
+
+static struct clk dss1_fck = {
+ .name = "dss1_fck",
+ .parent = &core_ck, /* Core or sys */
+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
+ RATE_CKCTL | CM_CORE_SEL1 | DELAYED_APP,
+ .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE,
+ .enable_bit = 0,
+ .rate_offset = 8,
+ .src_offset = 8,
+ .recalc = &omap2_clksel_recalc,
+};
+
+static struct clk dss2_fck = { /* Alt clk used in power management */
+ .name = "dss2_fck",
+ .parent = &sys_ck, /* fixed at sys_ck or 48MHz */
+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
+ RATE_CKCTL | CM_CORE_SEL1 | RATE_FIXED,
+ .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE,
+ .enable_bit = 1,
+ .src_offset = 13,
+ .recalc = &omap2_followparent_recalc,
+};
+
+static struct clk dss_54m_fck = { /* Alt clk used in power management */
+ .name = "dss_54m_fck", /* 54m tv clk */
+ .parent = &func_54m_ck,
+ .rate = 54000000,
+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
+ RATE_FIXED | RATE_PROPAGATES,
+ .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE,
+ .enable_bit = 2,
+ .recalc = &omap2_propagate_rate,
+};
+
+/*
+ * CORE power domain ICLK & FCLK defines.
+ * Many of the these can have more than one possible parent. Entries
+ * here will likely have an L4 interface parent, and may have multiple
+ * functional clock parents.
+ */
+static struct clk gpt1_ick = {
+ .name = "gpt1_ick",
+ .parent = &l4_ck,
+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+ .enable_reg = (void __iomem *)&CM_ICLKEN_WKUP, /* Bit4 */
+ .enable_bit = 0,
+ .recalc = &omap2_followparent_recalc,
+};
+
+static struct clk gpt1_fck = {
+ .name = "gpt1_fck",
+ .parent = &func_32k_ck,
+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
+ CM_WKUP_SEL1,
+ .enable_reg = (void __iomem *)&CM_FCLKEN_WKUP,
+ .enable_bit = 0,
+ .src_offset = 0,
+ .recalc = &omap2_followparent_recalc,
+};
+
+static struct clk gpt2_ick = {
+ .name = "gpt2_ick",
+ .parent = &l4_ck,
+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+ .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE, /* bit4 */
+ .enable_bit = 0,
+ .recalc = &omap2_followparent_recalc,
+};
+
+static struct clk gpt2_fck = {
+ .name = "gpt2_fck",
+ .parent = &func_32k_ck,
+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
+ CM_CORE_SEL2,
+ .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE,
+ .enable_bit = 4,
+ .src_offset = 2,
+ .recalc = &omap2_followparent_recalc,
+};
+
+static struct clk gpt3_ick = {
+ .name = "gpt3_ick",
+ .parent = &l4_ck,
+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+ .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE, /* Bit5 */
+ .enable_bit = 5,
+ .recalc = &omap2_followparent_recalc,
+};
+
+static struct clk gpt3_fck = {
+ .name = "gpt3_fck",
+ .parent = &func_32k_ck,
+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
+ CM_CORE_SEL2,
+ .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE,
+ .enable_bit = 5,
+ .src_offset = 4,
+ .recalc = &omap2_followparent_recalc,
+};
+
+static struct clk gpt4_ick = {
+ .name = "gpt4_ick",
+ .parent = &l4_ck,
+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+ .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE, /* Bit6 */
+ .enable_bit = 6,
+ .recalc = &omap2_followparent_recalc,
+};
+
+static struct clk gpt4_fck = {
+ .name = "gpt4_fck",
+ .parent = &func_32k_ck,
+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
+ CM_CORE_SEL2,
+ .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE,
+ .enable_bit = 6,
+ .src_offset = 6,
+ .recalc = &omap2_followparent_recalc,
+};
+
+static struct clk gpt5_ick = {
+ .name = "gpt5_ick",
+ .parent = &l4_ck,
+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+ .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE, /* Bit7 */
+ .enable_bit = 7,
+ .recalc = &omap2_followparent_recalc,
+};
+
+static struct clk gpt5_fck = {
+ .name = "gpt5_fck",
+ .parent = &func_32k_ck,
+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
+ CM_CORE_SEL2,
+ .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE,
+ .enable_bit = 7,
+ .src_offset = 8,
+ .recalc = &omap2_followparent_recalc,
+};
+
+static struct clk gpt6_ick = {
+ .name = "gpt6_ick",
+ .parent = &l4_ck,
+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+ .enable_bit = 8,
+ .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE, /* bit8 */
+ .recalc = &omap2_followparent_recalc,
+};
+
+static struct clk gpt6_fck = {
+ .name = "gpt6_fck",
+ .parent = &func_32k_ck,
+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
+ CM_CORE_SEL2,
+ .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE,
+ .enable_bit = 8,
+ .src_offset = 10,
+ .recalc = &omap2_followparent_recalc,
+};
+
+static struct clk gpt7_ick = {
+ .name = "gpt7_ick",
+ .parent = &l4_ck,
+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+ .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE, /* bit9 */
+ .enable_bit = 9,
+ .recalc = &omap2_followparent_recalc,
+};
+
+static struct clk gpt7_fck = {
+ .name = "gpt7_fck",
+ .parent = &func_32k_ck,
+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
+ CM_CORE_SEL2,
+ .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE,
+ .enable_bit = 9,
+ .src_offset = 12,
+ .recalc = &omap2_followparent_recalc,
+};
+
+static struct clk gpt8_ick = {
+ .name = "gpt8_ick",
+ .parent = &l4_ck,
+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+ .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE, /* bit10 */
+ .enable_bit = 10,
+ .recalc = &omap2_followparent_recalc,
+};
+
+static struct clk gpt8_fck = {
+ .name = "gpt8_fck",
+ .parent = &func_32k_ck,
+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
+ CM_CORE_SEL2,
+ .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE,
+ .enable_bit = 10,
+ .src_offset = 14,
+ .recalc = &omap2_followparent_recalc,
+};
+
+static struct clk gpt9_ick = {
+ .name = "gpt9_ick",
+ .parent = &l4_ck,
+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+ .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE,
+ .enable_bit = 11,
+ .recalc = &omap2_followparent_recalc,
+};
+
+static struct clk gpt9_fck = {
+ .name = "gpt9_fck",
+ .parent = &func_32k_ck,
+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
+ CM_CORE_SEL2,
+ .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE,
+ .enable_bit = 11,
+ .src_offset = 16,
+ .recalc = &omap2_followparent_recalc,
+};
+
+static struct clk gpt10_ick = {
+ .name = "gpt10_ick",
+ .parent = &l4_ck,
+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+ .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE,
+ .enable_bit = 12,
+ .recalc = &omap2_followparent_recalc,
+};
+
+static struct clk gpt10_fck = {
+ .name = "gpt10_fck",
+ .parent = &func_32k_ck,
+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
+ CM_CORE_SEL2,
+ .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE,
+ .enable_bit = 12,
+ .src_offset = 18,
+ .recalc = &omap2_followparent_recalc,
+};
+
+static struct clk gpt11_ick = {
+ .name = "gpt11_ick",
+ .parent = &l4_ck,
+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+ .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE,
+ .enable_bit = 13,
+ .recalc = &omap2_followparent_recalc,
+};
+
+static struct clk gpt11_fck = {
+ .name = "gpt11_fck",
+ .parent = &func_32k_ck,
+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
+ CM_CORE_SEL2,
+ .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE,
+ .enable_bit = 13,
+ .src_offset = 20,
+ .recalc = &omap2_followparent_recalc,
+};
+
+static struct clk gpt12_ick = {
+ .name = "gpt12_ick",
+ .parent = &l4_ck,
+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+ .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE, /* bit14 */
+ .enable_bit = 14,
+ .recalc = &omap2_followparent_recalc,
+};
+
+static struct clk gpt12_fck = {
+ .name = "gpt12_fck",
+ .parent = &func_32k_ck,
+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
+ CM_CORE_SEL2,
+ .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE,
+ .enable_bit = 14,
+ .src_offset = 22,
+ .recalc = &omap2_followparent_recalc,
+};
+
+static struct clk mcbsp1_ick = {
+ .name = "mcbsp1_ick",
+ .parent = &l4_ck,
+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+ .enable_bit = 15,
+ .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE, /* bit16 */
+ .recalc = &omap2_followparent_recalc,
+};
+
+static struct clk mcbsp1_fck = {
+ .name = "mcbsp1_fck",
+ .parent = &func_96m_ck,
+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+ .enable_bit = 15,
+ .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE,
+ .recalc = &omap2_followparent_recalc,
+};
+
+static struct clk mcbsp2_ick = {
+ .name = "mcbsp2_ick",
+ .parent = &l4_ck,
+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+ .enable_bit = 16,
+ .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE,
+ .recalc = &omap2_followparent_recalc,
+};
+
+static struct clk mcbsp2_fck = {
+ .name = "mcbsp2_fck",
+ .parent = &func_96m_ck,
+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+ .enable_bit = 16,
+ .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE,
+ .recalc = &omap2_followparent_recalc,
+};
+
+static struct clk mcbsp3_ick = {
+ .name = "mcbsp3_ick",
+ .parent = &l4_ck,
+ .flags = CLOCK_IN_OMAP243X,
+ .enable_reg = (void __iomem *)&CM_ICLKEN2_CORE,
+ .enable_bit = 3,
+ .recalc = &omap2_followparent_recalc,
+};
+
+static struct clk mcbsp3_fck = {
+ .name = "mcbsp3_fck",
+ .parent = &func_96m_ck,
+ .flags = CLOCK_IN_OMAP243X,
+ .enable_reg = (void __iomem *)&CM_FCLKEN2_CORE,
+ .enable_bit = 3,
+ .recalc = &omap2_followparent_recalc,
+};
+
+static struct clk mcbsp4_ick = {
+ .name = "mcbsp4_ick",
+ .parent = &l4_ck,
+ .flags = CLOCK_IN_OMAP243X,
+ .enable_reg = (void __iomem *)&CM_ICLKEN2_CORE,
+ .enable_bit = 4,
+ .recalc = &omap2_followparent_recalc,
+};
+
+static struct clk mcbsp4_fck = {
+ .name = "mcbsp4_fck",
+ .parent = &func_96m_ck,
+ .flags = CLOCK_IN_OMAP243X,
+ .enable_reg = (void __iomem *)&CM_FCLKEN2_CORE,
+ .enable_bit = 4,
+ .recalc = &omap2_followparent_recalc,
+};
+
+static struct clk mcbsp5_ick = {
+ .name = "mcbsp5_ick",
+ .parent = &l4_ck,
+ .flags = CLOCK_IN_OMAP243X,
+ .enable_reg = (void __iomem *)&CM_ICLKEN2_CORE,
+ .enable_bit = 5,
+ .recalc = &omap2_followparent_recalc,
+};
+
+static struct clk mcbsp5_fck = {
+ .name = "mcbsp5_fck",
+ .parent = &func_96m_ck,
+ .flags = CLOCK_IN_OMAP243X,
+ .enable_reg = (void __iomem *)&CM_FCLKEN2_CORE,
+ .enable_bit = 5,
+ .recalc = &omap2_followparent_recalc,
+};
+
+static struct clk mcspi1_ick = {
+ .name = "mcspi1_ick",
+ .parent = &l4_ck,
+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+ .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE,
+ .enable_bit = 17,
+ .recalc = &omap2_followparent_recalc,
+};
+
+static struct clk mcspi1_fck = {
+ .name = "mcspi1_fck",
+ .parent = &func_48m_ck,
+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+ .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE,
+ .enable_bit = 17,
+ .recalc = &omap2_followparent_recalc,
+};
+
+static struct clk mcspi2_ick = {
+ .name = "mcspi2_ick",
+ .parent = &l4_ck,
+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+ .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE,
+ .enable_bit = 18,
+ .recalc = &omap2_followparent_recalc,
+};
+
+static struct clk mcspi2_fck = {
+ .name = "mcspi2_fck",
+ .parent = &func_48m_ck,
+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+ .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE,
+ .enable_bit = 18,
+ .recalc = &omap2_followparent_recalc,
+};
+
+static struct clk mcspi3_ick = {
+ .name = "mcspi3_ick",
+ .parent = &l4_ck,
+ .flags = CLOCK_IN_OMAP243X,
+ .enable_reg = (void __iomem *)&CM_ICLKEN2_CORE,
+ .enable_bit = 9,
+ .recalc = &omap2_followparent_recalc,
+};
+
+static struct clk mcspi3_fck = {
+ .name = "mcspi3_fck",
+ .parent = &func_48m_ck,
+ .flags = CLOCK_IN_OMAP243X,
+ .enable_reg = (void __iomem *)&CM_FCLKEN2_CORE,
+ .enable_bit = 9,
+ .recalc = &omap2_followparent_recalc,
+};
+
+static struct clk uart1_ick = {
+ .name = "uart1_ick",
+ .parent = &l4_ck,
+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+ .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE,
+ .enable_bit = 21,
+ .recalc = &omap2_followparent_recalc,
+};
+
+static struct clk uart1_fck = {
+ .name = "uart1_fck",
+ .parent = &func_48m_ck,
+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+ .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE,
+ .enable_bit = 21,
+ .recalc = &omap2_followparent_recalc,
+};
+
+static struct clk uart2_ick = {
+ .name = "uart2_ick",
+ .parent = &l4_ck,
+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+ .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE,
+ .enable_bit = 22,
+ .recalc = &omap2_followparent_recalc,
+};
+
+static struct clk uart2_fck = {
+ .name = "uart2_fck",
+ .parent = &func_48m_ck,
+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+ .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE,
+ .enable_bit = 22,
+ .recalc = &omap2_followparent_recalc,
+};
+
+static struct clk uart3_ick = {
+ .name = "uart3_ick",
+ .parent = &l4_ck,
+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+ .enable_reg = (void __iomem *)&CM_ICLKEN2_CORE,
+ .enable_bit = 2,
+ .recalc = &omap2_followparent_recalc,
+};
+
+static struct clk uart3_fck = {
+ .name = "uart3_fck",
+ .parent = &func_48m_ck,
+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+ .enable_reg = (void __iomem *)&CM_FCLKEN2_CORE,
+ .enable_bit = 2,
+ .recalc = &omap2_followparent_recalc,
+};
+
+static struct clk gpios_ick = {
+ .name = "gpios_ick",
+ .parent = &l4_ck,
+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+ .enable_reg = (void __iomem *)&CM_ICLKEN_WKUP,
+ .enable_bit = 2,
+ .recalc = &omap2_followparent_recalc,
+};
+
+static struct clk gpios_fck = {
+ .name = "gpios_fck",
+ .parent = &func_32k_ck,
+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+ .enable_reg = (void __iomem *)&CM_FCLKEN_WKUP,
+ .enable_bit = 2,
+ .recalc = &omap2_followparent_recalc,
+};
+
+static struct clk mpu_wdt_ick = {
+ .name = "mpu_wdt_ick",
+ .parent = &l4_ck,
+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+ .enable_reg = (void __iomem *)&CM_ICLKEN_WKUP,
+ .enable_bit = 3,
+ .recalc = &omap2_followparent_recalc,
+};
+
+static struct clk mpu_wdt_fck = {
+ .name = "mpu_wdt_fck",
+ .parent = &func_32k_ck,
+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+ .enable_reg = (void __iomem *)&CM_FCLKEN_WKUP,
+ .enable_bit = 3,
+ .recalc = &omap2_followparent_recalc,
+};
+
+static struct clk sync_32k_ick = {
+ .name = "sync_32k_ick",
+ .parent = &l4_ck,
+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+ .enable_reg = (void __iomem *)&CM_ICLKEN_WKUP,
+ .enable_bit = 1,
+ .recalc = &omap2_followparent_recalc,
+};
+static struct clk wdt1_ick = {
+ .name = "wdt1_ick",
+ .parent = &l4_ck,
+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+ .enable_reg = (void __iomem *)&CM_ICLKEN_WKUP,
+ .enable_bit = 4,
+ .recalc = &omap2_followparent_recalc,
+};
+static struct clk omapctrl_ick = {
+ .name = "omapctrl_ick",
+ .parent = &l4_ck,
+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+ .enable_reg = (void __iomem *)&CM_ICLKEN_WKUP,
+ .enable_bit = 5,
+ .recalc = &omap2_followparent_recalc,
+};
+static struct clk icr_ick = {
+ .name = "icr_ick",
+ .parent = &l4_ck,
+ .flags = CLOCK_IN_OMAP243X,
+ .enable_reg = (void __iomem *)&CM_ICLKEN_WKUP,
+ .enable_bit = 6,
+ .recalc = &omap2_followparent_recalc,
+};
+
+static struct clk cam_ick = {
+ .name = "cam_ick",
+ .parent = &l4_ck,
+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+ .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE,
+ .enable_bit = 31,
+ .recalc = &omap2_followparent_recalc,
+};
+
+static struct clk cam_fck = {
+ .name = "cam_fck",
+ .parent = &func_96m_ck,
+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+ .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE,
+ .enable_bit = 31,
+ .recalc = &omap2_followparent_recalc,
+};
+
+static struct clk mailboxes_ick = {
+ .name = "mailboxes_ick",
+ .parent = &l4_ck,
+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+ .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE,
+ .enable_bit = 30,
+ .recalc = &omap2_followparent_recalc,
+};
+
+static struct clk wdt4_ick = {
+ .name = "wdt4_ick",
+ .parent = &l4_ck,
+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+ .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE,
+ .enable_bit = 29,
+ .recalc = &omap2_followparent_recalc,
+};
+
+static struct clk wdt4_fck = {
+ .name = "wdt4_fck",
+ .parent = &func_32k_ck,
+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+ .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE,
+ .enable_bit = 29,
+ .recalc = &omap2_followparent_recalc,
+};
+
+static struct clk wdt3_ick = {
+ .name = "wdt3_ick",
+ .parent = &l4_ck,
+ .flags = CLOCK_IN_OMAP242X,
+ .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE,
+ .enable_bit = 28,
+ .recalc = &omap2_followparent_recalc,
+};
+
+static struct clk wdt3_fck = {
+ .name = "wdt3_fck",
+ .parent = &func_32k_ck,
+ .flags = CLOCK_IN_OMAP242X,
+ .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE,
+ .enable_bit = 28,
+ .recalc = &omap2_followparent_recalc,
+};
+
+static struct clk mspro_ick = {
+ .name = "mspro_ick",
+ .parent = &l4_ck,
+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+ .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE,
+ .enable_bit = 27,
+ .recalc = &omap2_followparent_recalc,
+};
+
+static struct clk mspro_fck = {
+ .name = "mspro_fck",
+ .parent = &func_96m_ck,
+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+ .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE,
+ .enable_bit = 27,
+ .recalc = &omap2_followparent_recalc,
+};
+
+static struct clk mmc_ick = {
+ .name = "mmc_ick",
+ .parent = &l4_ck,
+ .flags = CLOCK_IN_OMAP242X,
+ .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE,
+ .enable_bit = 26,
+ .recalc = &omap2_followparent_recalc,
+};
+
+static struct clk mmc_fck = {
+ .name = "mmc_fck",
+ .parent = &func_96m_ck,
+ .flags = CLOCK_IN_OMAP242X,
+ .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE,
+ .enable_bit = 26,
+ .recalc = &omap2_followparent_recalc,
+};
+
+static struct clk fac_ick = {
+ .name = "fac_ick",
+ .parent = &l4_ck,
+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+ .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE,
+ .enable_bit = 25,
+ .recalc = &omap2_followparent_recalc,
+};
+
+static struct clk fac_fck = {
+ .name = "fac_fck",
+ .parent = &func_12m_ck,
+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+ .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE,
+ .enable_bit = 25,
+ .recalc = &omap2_followparent_recalc,
+};
+
+static struct clk eac_ick = {
+ .name = "eac_ick",
+ .parent = &l4_ck,
+ .flags = CLOCK_IN_OMAP242X,
+ .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE,
+ .enable_bit = 24,
+ .recalc = &omap2_followparent_recalc,
+};
+
+static struct clk eac_fck = {
+ .name = "eac_fck",
+ .parent = &func_96m_ck,
+ .flags = CLOCK_IN_OMAP242X,
+ .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE,
+ .enable_bit = 24,
+ .recalc = &omap2_followparent_recalc,
+};
+
+static struct clk hdq_ick = {
+ .name = "hdq_ick",
+ .parent = &l4_ck,
+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+ .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE,
+ .enable_bit = 23,
+ .recalc = &omap2_followparent_recalc,
+};
+
+static struct clk hdq_fck = {
+ .name = "hdq_fck",
+ .parent = &func_12m_ck,
+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+ .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE,
+ .enable_bit = 23,
+ .recalc = &omap2_followparent_recalc,
+};
+
+static struct clk i2c2_ick = {
+ .name = "i2c2_ick",
+ .parent = &l4_ck,
+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+ .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE,
+ .enable_bit = 20,
+ .recalc = &omap2_followparent_recalc,
+};
+
+static struct clk i2c2_fck = {
+ .name = "i2c2_fck",
+ .parent = &func_12m_ck,
+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+ .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE,
+ .enable_bit = 20,
+ .recalc = &omap2_followparent_recalc,
+};
+
+static struct clk i2chs2_fck = {
+ .name = "i2chs2_fck",
+ .parent = &func_96m_ck,
+ .flags = CLOCK_IN_OMAP243X,
+ .enable_reg = (void __iomem *)&CM_FCLKEN2_CORE,
+ .enable_bit = 20,
+ .recalc = &omap2_followparent_recalc,
+};
+
+static struct clk i2c1_ick = {
+ .name = "i2c1_ick",
+ .parent = &l4_ck,
+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+ .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE,
+ .enable_bit = 19,
+ .recalc = &omap2_followparent_recalc,
+};
+
+static struct clk i2c1_fck = {
+ .name = "i2c1_fck",
+ .parent = &func_12m_ck,
+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+ .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE,
+ .enable_bit = 19,
+ .recalc = &omap2_followparent_recalc,
+};
+
+static struct clk i2chs1_fck = {
+ .name = "i2chs1_fck",
+ .parent = &func_96m_ck,
+ .flags = CLOCK_IN_OMAP243X,
+ .enable_reg = (void __iomem *)&CM_FCLKEN2_CORE,
+ .enable_bit = 19,
+ .recalc = &omap2_followparent_recalc,
+};
+
+static struct clk vlynq_ick = {
+ .name = "vlynq_ick",
+ .parent = &core_l3_ck,
+ .flags = CLOCK_IN_OMAP242X,
+ .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE,
+ .enable_bit = 3,
+ .recalc = &omap2_followparent_recalc,
+};
+
+static struct clk vlynq_fck = {
+ .name = "vlynq_fck",
+ .parent = &func_96m_ck,
+ .flags = CLOCK_IN_OMAP242X | RATE_CKCTL | CM_CORE_SEL1 | DELAYED_APP,
+ .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE,
+ .enable_bit = 3,
+ .src_offset = 15,
+ .recalc = &omap2_followparent_recalc,
+};
+
+static struct clk sdrc_ick = {
+ .name = "sdrc_ick",
+ .parent = &l4_ck,
+ .flags = CLOCK_IN_OMAP243X,
+ .enable_reg = (void __iomem *)&CM_ICLKEN3_CORE,
+ .enable_bit = 2,
+ .recalc = &omap2_followparent_recalc,
+};
+
+static struct clk des_ick = {
+ .name = "des_ick",
+ .parent = &l4_ck,
+ .flags = CLOCK_IN_OMAP243X | CLOCK_IN_OMAP242X,
+ .enable_reg = (void __iomem *)&CM_ICLKEN4_CORE,
+ .enable_bit = 0,
+ .recalc = &omap2_followparent_recalc,
+};
+
+static struct clk sha_ick = {
+ .name = "sha_ick",
+ .parent = &l4_ck,
+ .flags = CLOCK_IN_OMAP243X | CLOCK_IN_OMAP242X,
+ .enable_reg = (void __iomem *)&CM_ICLKEN4_CORE,
+ .enable_bit = 1,
+ .recalc = &omap2_followparent_recalc,
+};
+
+static struct clk rng_ick = {
+ .name = "rng_ick",
+ .parent = &l4_ck,
+ .flags = CLOCK_IN_OMAP243X | CLOCK_IN_OMAP242X,
+ .enable_reg = (void __iomem *)&CM_ICLKEN4_CORE,
+ .enable_bit = 2,
+ .recalc = &omap2_followparent_recalc,
+};
+
+static struct clk aes_ick = {
+ .name = "aes_ick",
+ .parent = &l4_ck,
+ .flags = CLOCK_IN_OMAP243X | CLOCK_IN_OMAP242X,
+ .enable_reg = (void __iomem *)&CM_ICLKEN4_CORE,
+ .enable_bit = 3,
+ .recalc = &omap2_followparent_recalc,
+};
+
+static struct clk pka_ick = {
+ .name = "pka_ick",
+ .parent = &l4_ck,
+ .flags = CLOCK_IN_OMAP243X | CLOCK_IN_OMAP242X,
+ .enable_reg = (void __iomem *)&CM_ICLKEN4_CORE,
+ .enable_bit = 4,
+ .recalc = &omap2_followparent_recalc,
+};
+
+static struct clk usb_fck = {
+ .name = "usb_fck",
+ .parent = &func_48m_ck,
+ .flags = CLOCK_IN_OMAP243X | CLOCK_IN_OMAP242X,
+ .enable_reg = (void __iomem *)&CM_FCLKEN2_CORE,
+ .enable_bit = 0,
+ .recalc = &omap2_followparent_recalc,
+};
+
+static struct clk usbhs_ick = {
+ .name = "usbhs_ick",
+ .parent = &l4_ck,
+ .flags = CLOCK_IN_OMAP243X,
+ .enable_reg = (void __iomem *)&CM_ICLKEN2_CORE,
+ .enable_bit = 6,
+ .recalc = &omap2_followparent_recalc,
+};
+
+static struct clk mmchs1_ick = {
+ .name = "mmchs1_ick",
+ .parent = &l4_ck,
+ .flags = CLOCK_IN_OMAP243X,
+ .enable_reg = (void __iomem *)&CM_ICLKEN2_CORE,
+ .enable_bit = 7,
+ .recalc = &omap2_followparent_recalc,
+};
+
+static struct clk mmchs1_fck = {
+ .name = "mmchs1_fck",
+ .parent = &func_96m_ck,
+ .flags = CLOCK_IN_OMAP243X,
+ .enable_reg = (void __iomem *)&CM_FCLKEN2_CORE,
+ .enable_bit = 7,
+ .recalc = &omap2_followparent_recalc,
+};
+
+static struct clk mmchs2_ick = {
+ .name = "mmchs2_ick",
+ .parent = &l4_ck,
+ .flags = CLOCK_IN_OMAP243X,
+ .enable_reg = (void __iomem *)&CM_ICLKEN2_CORE,
+ .enable_bit = 8,
+ .recalc = &omap2_followparent_recalc,
+};
+
+static struct clk mmchs2_fck = {
+ .name = "mmchs2_fck",
+ .parent = &func_96m_ck,
+ .flags = CLOCK_IN_OMAP243X,
+ .enable_reg = (void __iomem *)&CM_FCLKEN2_CORE,
+ .enable_bit = 8,
+ .recalc = &omap2_followparent_recalc,
+};
+
+static struct clk gpio5_ick = {
+ .name = "gpio5_ick",
+ .parent = &l4_ck,
+ .flags = CLOCK_IN_OMAP243X,
+ .enable_reg = (void __iomem *)&CM_ICLKEN2_CORE,
+ .enable_bit = 10,
+ .recalc = &omap2_followparent_recalc,
+};
+
+static struct clk gpio5_fck = {
+ .name = "gpio5_fck",
+ .parent = &func_32k_ck,
+ .flags = CLOCK_IN_OMAP243X,
+ .enable_reg = (void __iomem *)&CM_FCLKEN2_CORE,
+ .enable_bit = 10,
+ .recalc = &omap2_followparent_recalc,
+};
+
+static struct clk mdm_intc_ick = {
+ .name = "mdm_intc_ick",
+ .parent = &l4_ck,
+ .flags = CLOCK_IN_OMAP243X,
+ .enable_reg = (void __iomem *)&CM_ICLKEN2_CORE,
+ .enable_bit = 11,
+ .recalc = &omap2_followparent_recalc,
+};
+
+static struct clk mmchsdb1_fck = {
+ .name = "mmchsdb1_fck",
+ .parent = &func_32k_ck,
+ .flags = CLOCK_IN_OMAP243X,
+ .enable_reg = (void __iomem *)&CM_FCLKEN2_CORE,
+ .enable_bit = 16,
+ .recalc = &omap2_followparent_recalc,
+};
+
+static struct clk mmchsdb2_fck = {
+ .name = "mmchsdb2_fck",
+ .parent = &func_32k_ck,
+ .flags = CLOCK_IN_OMAP243X,
+ .enable_reg = (void __iomem *)&CM_FCLKEN2_CORE,
+ .enable_bit = 17,
+ .recalc = &omap2_followparent_recalc,
+};
+
+/*
+ * This clock is a composite clock which does entire set changes then
+ * forces a rebalance. It keys on the MPU speed, but it really could
+ * be any key speed part of a set in the rate table.
+ *
+ * to really change a set, you need memory table sets which get changed
+ * in sram, pre-notifiers & post notifiers, changing the top set, without
+ * having low level display recalc's won't work... this is why dpm notifiers
+ * work, isr's off, walk a list of clocks already _off_ and not messing with
+ * the bus.
+ *
+ * This clock should have no parent. It embodies the entire upper level
+ * active set. A parent will mess up some of the init also.
+ */
+static struct clk virt_prcm_set = {
+ .name = "virt_prcm_set",
+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
+ VIRTUAL_CLOCK | ALWAYS_ENABLED | DELAYED_APP,
+ .parent = &mpu_ck, /* Indexed by mpu speed, no parent */
+ .recalc = &omap2_mpu_recalc, /* sets are keyed on mpu rate */
+ .set_rate = &omap2_select_table_rate,
+ .round_rate = &omap2_round_to_table_rate,
+};
+
+static struct clk *onchip_clks[] = {
+ /* external root sources */
+ &func_32k_ck,
+ &osc_ck,
+ &sys_ck,
+ &alt_ck,
+ /* internal analog sources */
+ &dpll_ck,
+ &apll96_ck,
+ &apll54_ck,
+ /* internal prcm root sources */
+ &func_54m_ck,
+ &core_ck,
+ &sleep_ck,
+ &func_96m_ck,
+ &func_48m_ck,
+ &func_12m_ck,
+ &wdt1_osc_ck,
+ &sys_clkout,
+ &sys_clkout2,
+ /* mpu domain clocks */
+ &mpu_ck,
+ /* dsp domain clocks */
+ &iva2_1_fck, /* 2430 */
+ &iva2_1_ick,
+ &dsp_ick, /* 2420 */
+ &dsp_fck,
+ &iva1_ifck,
+ &iva1_mpu_int_ifck,
+ /* GFX domain clocks */
+ &gfx_3d_fck,
+ &gfx_2d_fck,
+ &gfx_ick,
+ /* Modem domain clocks */
+ &mdm_ick,
+ &mdm_osc_ck,
+ /* DSS domain clocks */
+ &dss_ick,
+ &dss1_fck,
+ &dss2_fck,
+ &dss_54m_fck,
+ /* L3 domain clocks */
+ &core_l3_ck,
+ &ssi_ssr_sst_fck,
+ &usb_l4_ick,
+ /* L4 domain clocks */
+ &l4_ck, /* used as both core_l4 and wu_l4 */
+ &ssi_l4_ick,
+ /* virtual meta-group clock */
+ &virt_prcm_set,
+ /* general l4 interface ck, multi-parent functional clk */
+ &gpt1_ick,
+ &gpt1_fck,
+ &gpt2_ick,
+ &gpt2_fck,
+ &gpt3_ick,
+ &gpt3_fck,
+ &gpt4_ick,
+ &gpt4_fck,
+ &gpt5_ick,
+ &gpt5_fck,
+ &gpt6_ick,
+ &gpt6_fck,
+ &gpt7_ick,
+ &gpt7_fck,
+ &gpt8_ick,
+ &gpt8_fck,
+ &gpt9_ick,
+ &gpt9_fck,
+ &gpt10_ick,
+ &gpt10_fck,
+ &gpt11_ick,
+ &gpt11_fck,
+ &gpt12_ick,
+ &gpt12_fck,
+ &mcbsp1_ick,
+ &mcbsp1_fck,
+ &mcbsp2_ick,
+ &mcbsp2_fck,
+ &mcbsp3_ick,
+ &mcbsp3_fck,
+ &mcbsp4_ick,
+ &mcbsp4_fck,
+ &mcbsp5_ick,
+ &mcbsp5_fck,
+ &mcspi1_ick,
+ &mcspi1_fck,
+ &mcspi2_ick,
+ &mcspi2_fck,
+ &mcspi3_ick,
+ &mcspi3_fck,
+ &uart1_ick,
+ &uart1_fck,
+ &uart2_ick,
+ &uart2_fck,
+ &uart3_ick,
+ &uart3_fck,
+ &gpios_ick,
+ &gpios_fck,
+ &mpu_wdt_ick,
+ &mpu_wdt_fck,
+ &sync_32k_ick,
+ &wdt1_ick,
+ &omapctrl_ick,
+ &icr_ick,
+ &cam_fck,
+ &cam_ick,
+ &mailboxes_ick,
+ &wdt4_ick,
+ &wdt4_fck,
+ &wdt3_ick,
+ &wdt3_fck,
+ &mspro_ick,
+ &mspro_fck,
+ &mmc_ick,
+ &mmc_fck,
+ &fac_ick,
+ &fac_fck,
+ &eac_ick,
+ &eac_fck,
+ &hdq_ick,
+ &hdq_fck,
+ &i2c1_ick,
+ &i2c1_fck,
+ &i2chs1_fck,
+ &i2c2_ick,
+ &i2c2_fck,
+ &i2chs2_fck,
+ &vlynq_ick,
+ &vlynq_fck,
+ &sdrc_ick,
+ &des_ick,
+ &sha_ick,
+ &rng_ick,
+ &aes_ick,
+ &pka_ick,
+ &usb_fck,
+ &usbhs_ick,
+ &mmchs1_ick,
+ &mmchs1_fck,
+ &mmchs2_ick,
+ &mmchs2_fck,
+ &gpio5_ick,
+ &gpio5_fck,
+ &mdm_intc_ick,
+ &mmchsdb1_fck,
+ &mmchsdb2_fck,
+};
+
+#endif
diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c
new file mode 100644
index 000000000000..7181edb89352
--- /dev/null
+++ b/arch/arm/mach-omap2/devices.c
@@ -0,0 +1,89 @@
+/*
+ * linux/arch/arm/mach-omap2/devices.c
+ *
+ * OMAP2 platform device setup/initialization
+ *
+ * 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/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/mach-types.h>
+#include <asm/mach/map.h>
+
+#include <asm/arch/tc.h>
+#include <asm/arch/board.h>
+#include <asm/arch/mux.h>
+#include <asm/arch/gpio.h>
+
+extern void omap_nop_release(struct device *dev);
+
+/*-------------------------------------------------------------------------*/
+
+#if defined(CONFIG_I2C_OMAP) || defined(CONFIG_I2C_OMAP_MODULE)
+
+#define OMAP2_I2C_BASE2 0x48072000
+#define OMAP2_I2C_INT2 57
+
+static struct resource i2c_resources2[] = {
+ {
+ .start = OMAP2_I2C_BASE2,
+ .end = OMAP2_I2C_BASE2 + 0x3f,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = OMAP2_I2C_INT2,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device omap_i2c_device2 = {
+ .name = "i2c_omap",
+ .id = 2,
+ .dev = {
+ .release = omap_nop_release,
+ },
+ .num_resources = ARRAY_SIZE(i2c_resources2),
+ .resource = i2c_resources2,
+};
+
+/* See also arch/arm/plat-omap/devices.c for first I2C on 24xx */
+static void omap_init_i2c(void)
+{
+ /* REVISIT: Second I2C not in use on H4? */
+ if (machine_is_omap_h4())
+ return;
+
+ omap_cfg_reg(J15_24XX_I2C2_SCL);
+ omap_cfg_reg(H19_24XX_I2C2_SDA);
+ (void) platform_device_register(&omap_i2c_device2);
+}
+
+#else
+
+static void omap_init_i2c(void) {}
+
+#endif
+
+/*-------------------------------------------------------------------------*/
+
+static int __init omap2_init_devices(void)
+{
+ /* please keep these calls, and their implementations above,
+ * in alphabetical order so they're easier to sort through.
+ */
+ omap_init_i2c();
+
+ return 0;
+}
+arch_initcall(omap2_init_devices);
+
diff --git a/arch/arm/mach-omap2/id.c b/arch/arm/mach-omap2/id.c
new file mode 100644
index 000000000000..76187300f2b6
--- /dev/null
+++ b/arch/arm/mach-omap2/id.c
@@ -0,0 +1,124 @@
+/*
+ * linux/arch/arm/mach-omap2/id.c
+ *
+ * OMAP2 CPU identification code
+ *
+ * Copyright (C) 2005 Nokia Corporation
+ * Written by Tony Lindgren <tony@atomide.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/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include <asm/io.h>
+
+#define OMAP24XX_TAP_BASE io_p2v(0x48014000)
+
+#define OMAP_TAP_IDCODE 0x0204
+#define OMAP_TAP_PROD_ID 0x0208
+
+#define OMAP_TAP_DIE_ID_0 0x0218
+#define OMAP_TAP_DIE_ID_1 0x021C
+#define OMAP_TAP_DIE_ID_2 0x0220
+#define OMAP_TAP_DIE_ID_3 0x0224
+
+/* system_rev fields for OMAP2 processors:
+ * CPU id bits [31:16],
+ * CPU device type [15:12], (unprg,normal,POP)
+ * CPU revision [11:08]
+ * CPU class bits [07:00]
+ */
+
+struct omap_id {
+ u16 hawkeye; /* Silicon type (Hawkeye id) */
+ u8 dev; /* Device type from production_id reg */
+ u32 type; /* combined type id copied to system_rev */
+};
+
+/* Register values to detect the OMAP version */
+static struct omap_id omap_ids[] __initdata = {
+ { .hawkeye = 0xb5d9, .dev = 0x0, .type = 0x24200000 },
+ { .hawkeye = 0xb5d9, .dev = 0x1, .type = 0x24201000 },
+ { .hawkeye = 0xb5d9, .dev = 0x2, .type = 0x24202000 },
+ { .hawkeye = 0xb5d9, .dev = 0x4, .type = 0x24220000 },
+ { .hawkeye = 0xb5d9, .dev = 0x8, .type = 0x24230000 },
+ { .hawkeye = 0xb68a, .dev = 0x0, .type = 0x24300000 },
+};
+
+static u32 __init read_tap_reg(int reg)
+{
+ return __raw_readl(OMAP24XX_TAP_BASE + reg);
+}
+
+void __init omap2_check_revision(void)
+{
+ int i, j;
+ u32 idcode;
+ u32 prod_id;
+ u16 hawkeye;
+ u8 dev_type;
+ u8 rev;
+
+ idcode = read_tap_reg(OMAP_TAP_IDCODE);
+ prod_id = read_tap_reg(OMAP_TAP_PROD_ID);
+ hawkeye = (idcode >> 12) & 0xffff;
+ rev = (idcode >> 28) & 0x0f;
+ dev_type = (prod_id >> 16) & 0x0f;
+
+#ifdef DEBUG
+ printk(KERN_DEBUG "OMAP_TAP_IDCODE 0x%08x REV %i HAWKEYE 0x%04x MANF %03x\n",
+ idcode, rev, hawkeye, (idcode >> 1) & 0x7ff);
+ printk(KERN_DEBUG "OMAP_TAP_DIE_ID_0: 0x%08x\n",
+ read_tap_reg(OMAP_TAP_DIE_ID_0));
+ printk(KERN_DEBUG "OMAP_TAP_DIE_ID_1: 0x%08x DEV_REV: %i\n",
+ read_tap_reg(OMAP_TAP_DIE_ID_1),
+ (read_tap_reg(OMAP_TAP_DIE_ID_1) >> 28) & 0xf);
+ printk(KERN_DEBUG "OMAP_TAP_DIE_ID_2: 0x%08x\n",
+ read_tap_reg(OMAP_TAP_DIE_ID_2));
+ printk(KERN_DEBUG "OMAP_TAP_DIE_ID_3: 0x%08x\n",
+ read_tap_reg(OMAP_TAP_DIE_ID_3));
+ printk(KERN_DEBUG "OMAP_TAP_PROD_ID_0: 0x%08x DEV_TYPE: %i\n",
+ prod_id, dev_type);
+#endif
+
+ /* Check hawkeye ids */
+ for (i = 0; i < ARRAY_SIZE(omap_ids); i++) {
+ if (hawkeye == omap_ids[i].hawkeye)
+ break;
+ }
+
+ if (i == ARRAY_SIZE(omap_ids)) {
+ printk(KERN_ERR "Unknown OMAP CPU id\n");
+ return;
+ }
+
+ for (j = i; j < ARRAY_SIZE(omap_ids); j++) {
+ if (dev_type == omap_ids[j].dev)
+ break;
+ }
+
+ if (j == ARRAY_SIZE(omap_ids)) {
+ printk(KERN_ERR "Unknown OMAP device type. "
+ "Handling it as OMAP%04x\n",
+ omap_ids[i].type >> 16);
+ j = i;
+ }
+ system_rev = omap_ids[j].type;
+
+ system_rev |= rev << 8;
+
+ /* Add the cpu class info (24xx) */
+ system_rev |= 0x24;
+
+ pr_info("OMAP%04x", system_rev >> 16);
+ if ((system_rev >> 8) & 0x0f)
+ printk("%x", (system_rev >> 8) & 0x0f);
+ printk("\n");
+}
+
diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c
new file mode 100644
index 000000000000..8ea67bf196a5
--- /dev/null
+++ b/arch/arm/mach-omap2/io.c
@@ -0,0 +1,53 @@
+/*
+ * linux/arch/arm/mach-omap2/io.c
+ *
+ * OMAP2 I/O mapping code
+ *
+ * Copyright (C) 2005 Nokia Corporation
+ * Author: Juha Yrjölä <juha.yrjola@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include <asm/mach/map.h>
+#include <asm/io.h>
+#include <asm/arch/mux.h>
+
+extern void omap_sram_init(void);
+extern int omap2_clk_init(void);
+extern void omap2_check_revision(void);
+
+/*
+ * The machine specific code may provide the extra mapping besides the
+ * default mapping provided here.
+ */
+static struct map_desc omap2_io_desc[] __initdata = {
+ {
+ .virtual = L3_24XX_VIRT,
+ .pfn = __phys_to_pfn(L3_24XX_PHYS),
+ .length = L3_24XX_SIZE,
+ .type = MT_DEVICE
+ },
+ {
+ .virtual = L4_24XX_VIRT,
+ .pfn = __phys_to_pfn(L4_24XX_PHYS),
+ .length = L4_24XX_SIZE,
+ .type = MT_DEVICE
+ }
+};
+
+void __init omap_map_common_io(void)
+{
+ iotable_init(omap2_io_desc, ARRAY_SIZE(omap2_io_desc));
+ omap2_check_revision();
+ omap_sram_init();
+ omap2_mux_init();
+ omap2_clk_init();
+}
diff --git a/arch/arm/mach-omap2/irq.c b/arch/arm/mach-omap2/irq.c
new file mode 100644
index 000000000000..d7baff675cfe
--- /dev/null
+++ b/arch/arm/mach-omap2/irq.c
@@ -0,0 +1,149 @@
+/*
+ * linux/arch/arm/mach-omap/omap2/irq.c
+ *
+ * Interrupt handler for OMAP2 boards.
+ *
+ * Copyright (C) 2005 Nokia Corporation
+ * Author: Paul Mundt <paul.mundt@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.
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/config.h>
+#include <linux/interrupt.h>
+#include <asm/hardware.h>
+#include <asm/mach/irq.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+
+#define INTC_REVISION 0x0000
+#define INTC_SYSCONFIG 0x0010
+#define INTC_SYSSTATUS 0x0014
+#define INTC_CONTROL 0x0048
+#define INTC_MIR_CLEAR0 0x0088
+#define INTC_MIR_SET0 0x008c
+
+/*
+ * OMAP2 has a number of different interrupt controllers, each interrupt
+ * controller is identified as its own "bank". Register definitions are
+ * fairly consistent for each bank, but not all registers are implemented
+ * for each bank.. when in doubt, consult the TRM.
+ */
+static struct omap_irq_bank {
+ unsigned long base_reg;
+ unsigned int nr_irqs;
+} __attribute__ ((aligned(4))) irq_banks[] = {
+ {
+ /* MPU INTC */
+ .base_reg = OMAP24XX_IC_BASE,
+ .nr_irqs = 96,
+ }, {
+ /* XXX: DSP INTC */
+
+#if 0
+ /*
+ * Commented out for now until we fix the IVA clocking
+ */
+#ifdef CONFIG_ARCH_OMAP2420
+ }, {
+ /* IVA INTC (2420 only) */
+ .base_reg = OMAP24XX_IVA_INTC_BASE,
+ .nr_irqs = 16, /* Actually 32, but only 16 are used */
+#endif
+#endif
+ }
+};
+
+/* XXX: FIQ and additional INTC support (only MPU at the moment) */
+static void omap_ack_irq(unsigned int irq)
+{
+ omap_writel(0x1, irq_banks[0].base_reg + INTC_CONTROL);
+}
+
+static void omap_mask_irq(unsigned int irq)
+{
+ int offset = (irq >> 5) << 5;
+
+ if (irq >= 64) {
+ irq %= 64;
+ } else if (irq >= 32) {
+ irq %= 32;
+ }
+
+ omap_writel(1 << irq, irq_banks[0].base_reg + INTC_MIR_SET0 + offset);
+}
+
+static void omap_unmask_irq(unsigned int irq)
+{
+ int offset = (irq >> 5) << 5;
+
+ if (irq >= 64) {
+ irq %= 64;
+ } else if (irq >= 32) {
+ irq %= 32;
+ }
+
+ omap_writel(1 << irq, irq_banks[0].base_reg + INTC_MIR_CLEAR0 + offset);
+}
+
+static void omap_mask_ack_irq(unsigned int irq)
+{
+ omap_mask_irq(irq);
+ omap_ack_irq(irq);
+}
+
+static struct irqchip omap_irq_chip = {
+ .ack = omap_mask_ack_irq,
+ .mask = omap_mask_irq,
+ .unmask = omap_unmask_irq,
+};
+
+static void __init omap_irq_bank_init_one(struct omap_irq_bank *bank)
+{
+ unsigned long tmp;
+
+ tmp = omap_readl(bank->base_reg + INTC_REVISION) & 0xff;
+ printk(KERN_INFO "IRQ: Found an INTC at 0x%08lx "
+ "(revision %ld.%ld) with %d interrupts\n",
+ bank->base_reg, tmp >> 4, tmp & 0xf, bank->nr_irqs);
+
+ tmp = omap_readl(bank->base_reg + INTC_SYSCONFIG);
+ tmp |= 1 << 1; /* soft reset */
+ omap_writel(tmp, bank->base_reg + INTC_SYSCONFIG);
+
+ while (!(omap_readl(bank->base_reg + INTC_SYSSTATUS) & 0x1))
+ /* Wait for reset to complete */;
+}
+
+void __init omap_init_irq(void)
+{
+ unsigned long nr_irqs = 0;
+ unsigned int nr_banks = 0;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(irq_banks); i++) {
+ struct omap_irq_bank *bank = irq_banks + i;
+
+ /* XXX */
+ if (!bank->base_reg)
+ continue;
+
+ omap_irq_bank_init_one(bank);
+
+ nr_irqs += bank->nr_irqs;
+ nr_banks++;
+ }
+
+ printk(KERN_INFO "Total of %ld interrupts on %d active controller%s\n",
+ nr_irqs, nr_banks, nr_banks > 1 ? "s" : "");
+
+ for (i = 0; i < nr_irqs; i++) {
+ set_irq_chip(i, &omap_irq_chip);
+ set_irq_handler(i, do_level_IRQ);
+ set_irq_flags(i, IRQF_VALID);
+ }
+}
+
diff --git a/arch/arm/mach-omap2/mux.c b/arch/arm/mach-omap2/mux.c
new file mode 100644
index 000000000000..ea4654815dd1
--- /dev/null
+++ b/arch/arm/mach-omap2/mux.c
@@ -0,0 +1,65 @@
+/*
+ * linux/arch/arm/mach-omap2/mux.c
+ *
+ * OMAP1 pin multiplexing configurations
+ *
+ * Copyright (C) 2003 - 2005 Nokia Corporation
+ *
+ * Written by Tony Lindgren <tony.lindgren@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * 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/config.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <asm/system.h>
+#include <asm/io.h>
+#include <linux/spinlock.h>
+
+#include <asm/arch/mux.h>
+
+#ifdef CONFIG_OMAP_MUX
+
+/* NOTE: See mux.h for the enumeration */
+
+struct pin_config __initdata_or_module omap24xx_pins[] = {
+/*
+ * description mux mux pull pull debug
+ * offset mode ena type
+ */
+
+/* 24xx I2C */
+MUX_CFG_24XX("M19_24XX_I2C1_SCL", 0x111, 0, 0, 0, 1)
+MUX_CFG_24XX("L15_24XX_I2C1_SDA", 0x112, 0, 0, 0, 1)
+MUX_CFG_24XX("J15_24XX_I2C2_SCL", 0x113, 0, 0, 0, 1)
+MUX_CFG_24XX("H19_24XX_I2C2_SDA", 0x114, 0, 0, 0, 1)
+
+/* Menelaus interrupt */
+MUX_CFG_24XX("W19_24XX_SYS_NIRQ", 0x12c, 0, 1, 1, 1)
+
+/* 24xx GPIO */
+MUX_CFG_24XX("Y20_24XX_GPIO60", 0x12c, 3, 0, 0, 1)
+MUX_CFG_24XX("M15_24XX_GPIO92", 0x10a, 3, 0, 0, 1)
+
+};
+
+int __init omap2_mux_init(void)
+{
+ omap_mux_register(omap24xx_pins, ARRAY_SIZE(omap24xx_pins));
+ return 0;
+}
+
+#endif
diff --git a/arch/arm/mach-omap2/prcm.h b/arch/arm/mach-omap2/prcm.h
new file mode 100644
index 000000000000..2eb89b936c83
--- /dev/null
+++ b/arch/arm/mach-omap2/prcm.h
@@ -0,0 +1,419 @@
+/*
+ * prcm.h - Access definations for use in OMAP24XX clock and power management
+ *
+ * Copyright (C) 2005 Texas Instruments, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License 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 __ASM_ARM_ARCH_DPM_PRCM_H
+#define __ASM_ARM_ARCH_DPM_PRCM_H
+
+/* SET_PERFORMANCE_LEVEL PARAMETERS */
+#define PRCM_HALF_SPEED 1
+#define PRCM_FULL_SPEED 2
+
+#ifndef __ASSEMBLER__
+
+#define PRCM_REG32(offset) __REG32(OMAP24XX_PRCM_BASE + (offset))
+
+#define PRCM_REVISION PRCM_REG32(0x000)
+#define PRCM_SYSCONFIG PRCM_REG32(0x010)
+#define PRCM_IRQSTATUS_MPU PRCM_REG32(0x018)
+#define PRCM_IRQENABLE_MPU PRCM_REG32(0x01C)
+#define PRCM_VOLTCTRL PRCM_REG32(0x050)
+#define PRCM_VOLTST PRCM_REG32(0x054)
+#define PRCM_CLKSRC_CTRL PRCM_REG32(0x060)
+#define PRCM_CLKOUT_CTRL PRCM_REG32(0x070)
+#define PRCM_CLKEMUL_CTRL PRCM_REG32(0x078)
+#define PRCM_CLKCFG_CTRL PRCM_REG32(0x080)
+#define PRCM_CLKCFG_STATUS PRCM_REG32(0x084)
+#define PRCM_VOLTSETUP PRCM_REG32(0x090)
+#define PRCM_CLKSSETUP PRCM_REG32(0x094)
+#define PRCM_POLCTRL PRCM_REG32(0x098)
+
+/* GENERAL PURPOSE */
+#define GENERAL_PURPOSE1 PRCM_REG32(0x0B0)
+#define GENERAL_PURPOSE2 PRCM_REG32(0x0B4)
+#define GENERAL_PURPOSE3 PRCM_REG32(0x0B8)
+#define GENERAL_PURPOSE4 PRCM_REG32(0x0BC)
+#define GENERAL_PURPOSE5 PRCM_REG32(0x0C0)
+#define GENERAL_PURPOSE6 PRCM_REG32(0x0C4)
+#define GENERAL_PURPOSE7 PRCM_REG32(0x0C8)
+#define GENERAL_PURPOSE8 PRCM_REG32(0x0CC)
+#define GENERAL_PURPOSE9 PRCM_REG32(0x0D0)
+#define GENERAL_PURPOSE10 PRCM_REG32(0x0D4)
+#define GENERAL_PURPOSE11 PRCM_REG32(0x0D8)
+#define GENERAL_PURPOSE12 PRCM_REG32(0x0DC)
+#define GENERAL_PURPOSE13 PRCM_REG32(0x0E0)
+#define GENERAL_PURPOSE14 PRCM_REG32(0x0E4)
+#define GENERAL_PURPOSE15 PRCM_REG32(0x0E8)
+#define GENERAL_PURPOSE16 PRCM_REG32(0x0EC)
+#define GENERAL_PURPOSE17 PRCM_REG32(0x0F0)
+#define GENERAL_PURPOSE18 PRCM_REG32(0x0F4)
+#define GENERAL_PURPOSE19 PRCM_REG32(0x0F8)
+#define GENERAL_PURPOSE20 PRCM_REG32(0x0FC)
+
+/* MPU */
+#define CM_CLKSEL_MPU PRCM_REG32(0x140)
+#define CM_CLKSTCTRL_MPU PRCM_REG32(0x148)
+#define RM_RSTST_MPU PRCM_REG32(0x158)
+#define PM_WKDEP_MPU PRCM_REG32(0x1C8)
+#define PM_EVGENCTRL_MPU PRCM_REG32(0x1D4)
+#define PM_EVEGENONTIM_MPU PRCM_REG32(0x1D8)
+#define PM_EVEGENOFFTIM_MPU PRCM_REG32(0x1DC)
+#define PM_PWSTCTRL_MPU PRCM_REG32(0x1E0)
+#define PM_PWSTST_MPU PRCM_REG32(0x1E4)
+
+/* CORE */
+#define CM_FCLKEN1_CORE PRCM_REG32(0x200)
+#define CM_FCLKEN2_CORE PRCM_REG32(0x204)
+#define CM_FCLKEN3_CORE PRCM_REG32(0x208)
+#define CM_ICLKEN1_CORE PRCM_REG32(0x210)
+#define CM_ICLKEN2_CORE PRCM_REG32(0x214)
+#define CM_ICLKEN3_CORE PRCM_REG32(0x218)
+#define CM_ICLKEN4_CORE PRCM_REG32(0x21C)
+#define CM_IDLEST1_CORE PRCM_REG32(0x220)
+#define CM_IDLEST2_CORE PRCM_REG32(0x224)
+#define CM_IDLEST3_CORE PRCM_REG32(0x228)
+#define CM_IDLEST4_CORE PRCM_REG32(0x22C)
+#define CM_AUTOIDLE1_CORE PRCM_REG32(0x230)
+#define CM_AUTOIDLE2_CORE PRCM_REG32(0x234)
+#define CM_AUTOIDLE3_CORE PRCM_REG32(0x238)
+#define CM_AUTOIDLE4_CORE PRCM_REG32(0x23C)
+#define CM_CLKSEL1_CORE PRCM_REG32(0x240)
+#define CM_CLKSEL2_CORE PRCM_REG32(0x244)
+#define CM_CLKSTCTRL_CORE PRCM_REG32(0x248)
+#define PM_WKEN1_CORE PRCM_REG32(0x2A0)
+#define PM_WKEN2_CORE PRCM_REG32(0x2A4)
+#define PM_WKST1_CORE PRCM_REG32(0x2B0)
+#define PM_WKST2_CORE PRCM_REG32(0x2B4)
+#define PM_WKDEP_CORE PRCM_REG32(0x2C8)
+#define PM_PWSTCTRL_CORE PRCM_REG32(0x2E0)
+#define PM_PWSTST_CORE PRCM_REG32(0x2E4)
+
+/* GFX */
+#define CM_FCLKEN_GFX PRCM_REG32(0x300)
+#define CM_ICLKEN_GFX PRCM_REG32(0x310)
+#define CM_IDLEST_GFX PRCM_REG32(0x320)
+#define CM_CLKSEL_GFX PRCM_REG32(0x340)
+#define CM_CLKSTCTRL_GFX PRCM_REG32(0x348)
+#define RM_RSTCTRL_GFX PRCM_REG32(0x350)
+#define RM_RSTST_GFX PRCM_REG32(0x358)
+#define PM_WKDEP_GFX PRCM_REG32(0x3C8)
+#define PM_PWSTCTRL_GFX PRCM_REG32(0x3E0)
+#define PM_PWSTST_GFX PRCM_REG32(0x3E4)
+
+/* WAKE-UP */
+#define CM_FCLKEN_WKUP PRCM_REG32(0x400)
+#define CM_ICLKEN_WKUP PRCM_REG32(0x410)
+#define CM_IDLEST_WKUP PRCM_REG32(0x420)
+#define CM_AUTOIDLE_WKUP PRCM_REG32(0x430)
+#define CM_CLKSEL_WKUP PRCM_REG32(0x440)
+#define RM_RSTCTRL_WKUP PRCM_REG32(0x450)
+#define RM_RSTTIME_WKUP PRCM_REG32(0x454)
+#define RM_RSTST_WKUP PRCM_REG32(0x458)
+#define PM_WKEN_WKUP PRCM_REG32(0x4A0)
+#define PM_WKST_WKUP PRCM_REG32(0x4B0)
+
+/* CLOCKS */
+#define CM_CLKEN_PLL PRCM_REG32(0x500)
+#define CM_IDLEST_CKGEN PRCM_REG32(0x520)
+#define CM_AUTOIDLE_PLL PRCM_REG32(0x530)
+#define CM_CLKSEL1_PLL PRCM_REG32(0x540)
+#define CM_CLKSEL2_PLL PRCM_REG32(0x544)
+
+/* DSP */
+#define CM_FCLKEN_DSP PRCM_REG32(0x800)
+#define CM_ICLKEN_DSP PRCM_REG32(0x810)
+#define CM_IDLEST_DSP PRCM_REG32(0x820)
+#define CM_AUTOIDLE_DSP PRCM_REG32(0x830)
+#define CM_CLKSEL_DSP PRCM_REG32(0x840)
+#define CM_CLKSTCTRL_DSP PRCM_REG32(0x848)
+#define RM_RSTCTRL_DSP PRCM_REG32(0x850)
+#define RM_RSTST_DSP PRCM_REG32(0x858)
+#define PM_WKEN_DSP PRCM_REG32(0x8A0)
+#define PM_WKDEP_DSP PRCM_REG32(0x8C8)
+#define PM_PWSTCTRL_DSP PRCM_REG32(0x8E0)
+#define PM_PWSTST_DSP PRCM_REG32(0x8E4)
+#define PRCM_IRQSTATUS_DSP PRCM_REG32(0x8F0)
+#define PRCM_IRQENABLE_DSP PRCM_REG32(0x8F4)
+
+/* IVA */
+#define PRCM_IRQSTATUS_IVA PRCM_REG32(0x8F8)
+#define PRCM_IRQENABLE_IVA PRCM_REG32(0x8FC)
+
+/* Modem on 2430 */
+#define CM_FCLKEN_MDM PRCM_REG32(0xC00)
+#define CM_ICLKEN_MDM PRCM_REG32(0xC10)
+#define CM_IDLEST_MDM PRCM_REG32(0xC20)
+#define CM_CLKSEL_MDM PRCM_REG32(0xC40)
+
+/* FIXME: Move to header for 2430 */
+#define DISP_BASE (OMAP24XX_L4_IO_BASE+0x50000)
+#define DISP_REG32(offset) __REG32(DISP_BASE + (offset))
+
+#define GPMC_BASE (OMAP24XX_GPMC_BASE)
+#define GPMC_REG32(offset) __REG32(GPMC_BASE + (offset))
+
+#define GPT1_BASE (OMAP24XX_GPT1)
+#define GPT1_REG32(offset) __REG32(GPT1_BASE + (offset))
+
+/* Misc sysconfig */
+#define DISPC_SYSCONFIG DISP_REG32(0x410)
+#define SPI_BASE (OMAP24XX_L4_IO_BASE+0x98000)
+#define MCSPI1_SYSCONFIG __REG32(SPI_BASE + 0x10)
+#define MCSPI2_SYSCONFIG __REG32(SPI_BASE+0x2000 + 0x10)
+
+//#define DSP_MMU_SYSCONFIG 0x5A000010
+#define CAMERA_MMU_SYSCONFIG __REG32(DISP_BASE+0x2C10)
+//#define IVA_MMU_SYSCONFIG 0x5D000010
+//#define DSP_DMA_SYSCONFIG 0x00FCC02C
+#define CAMERA_DMA_SYSCONFIG __REG32(DISP_BASE+0x282C)
+#define SYSTEM_DMA_SYSCONFIG __REG32(DISP_BASE+0x602C)
+#define GPMC_SYSCONFIG GPMC_REG32(0x010)
+#define MAILBOXES_SYSCONFIG __REG32(OMAP24XX_L4_IO_BASE+0x94010)
+#define UART1_SYSCONFIG __REG32(OMAP24XX_L4_IO_BASE+0x6A054)
+#define UART2_SYSCONFIG __REG32(OMAP24XX_L4_IO_BASE+0x6C054)
+#define UART3_SYSCONFIG __REG32(OMAP24XX_L4_IO_BASE+0x6E054)
+//#define IVA_SYSCONFIG 0x5C060010
+#define SDRC_SYSCONFIG __REG32(OMAP24XX_SDRC_BASE+0x10)
+#define SMS_SYSCONFIG __REG32(OMAP24XX_SMS_BASE+0x10)
+#define SSI_SYSCONFIG __REG32(DISP_BASE+0x8010)
+//#define VLYNQ_SYSCONFIG 0x67FFFE10
+
+/* rkw - good cannidates for PM_ to start what nm was trying */
+#define OMAP24XX_GPT2 (OMAP24XX_L4_IO_BASE+0x2A000)
+#define OMAP24XX_GPT3 (OMAP24XX_L4_IO_BASE+0x78000)
+#define OMAP24XX_GPT4 (OMAP24XX_L4_IO_BASE+0x7A000)
+#define OMAP24XX_GPT5 (OMAP24XX_L4_IO_BASE+0x7C000)
+#define OMAP24XX_GPT6 (OMAP24XX_L4_IO_BASE+0x7E000)
+#define OMAP24XX_GPT7 (OMAP24XX_L4_IO_BASE+0x80000)
+#define OMAP24XX_GPT8 (OMAP24XX_L4_IO_BASE+0x82000)
+#define OMAP24XX_GPT9 (OMAP24XX_L4_IO_BASE+0x84000)
+#define OMAP24XX_GPT10 (OMAP24XX_L4_IO_BASE+0x86000)
+#define OMAP24XX_GPT11 (OMAP24XX_L4_IO_BASE+0x88000)
+#define OMAP24XX_GPT12 (OMAP24XX_L4_IO_BASE+0x8A000)
+
+#define GPTIMER1_SYSCONFIG GPT1_REG32(0x010)
+#define GPTIMER2_SYSCONFIG __REG32(OMAP24XX_GPT2 + 0x10)
+#define GPTIMER3_SYSCONFIG __REG32(OMAP24XX_GPT3 + 0x10)
+#define GPTIMER4_SYSCONFIG __REG32(OMAP24XX_GPT4 + 0x10)
+#define GPTIMER5_SYSCONFIG __REG32(OMAP24XX_GPT5 + 0x10)
+#define GPTIMER6_SYSCONFIG __REG32(OMAP24XX_GPT6 + 0x10)
+#define GPTIMER7_SYSCONFIG __REG32(OMAP24XX_GPT7 + 0x10)
+#define GPTIMER8_SYSCONFIG __REG32(OMAP24XX_GPT8 + 0x10)
+#define GPTIMER9_SYSCONFIG __REG32(OMAP24XX_GPT9 + 0x10)
+#define GPTIMER10_SYSCONFIG __REG32(OMAP24XX_GPT10 + 0x10)
+#define GPTIMER11_SYSCONFIG __REG32(OMAP24XX_GPT11 + 0x10)
+#define GPTIMER12_SYSCONFIG __REG32(OMAP24XX_GPT12 + 0x10)
+
+#define GPIOX_BASE(X) (OMAP24XX_GPIO_BASE+(0x2000*((X)-1)))
+
+#define GPIO1_SYSCONFIG __REG32((GPIOX_BASE(1)+0x10))
+#define GPIO2_SYSCONFIG __REG32((GPIOX_BASE(2)+0x10))
+#define GPIO3_SYSCONFIG __REG32((GPIOX_BASE(3)+0x10))
+#define GPIO4_SYSCONFIG __REG32((GPIOX_BASE(4)+0x10))
+
+/* GP TIMER 1 */
+#define GPTIMER1_TISTAT GPT1_REG32(0x014)
+#define GPTIMER1_TISR GPT1_REG32(0x018)
+#define GPTIMER1_TIER GPT1_REG32(0x01C)
+#define GPTIMER1_TWER GPT1_REG32(0x020)
+#define GPTIMER1_TCLR GPT1_REG32(0x024)
+#define GPTIMER1_TCRR GPT1_REG32(0x028)
+#define GPTIMER1_TLDR GPT1_REG32(0x02C)
+#define GPTIMER1_TTGR GPT1_REG32(0x030)
+#define GPTIMER1_TWPS GPT1_REG32(0x034)
+#define GPTIMER1_TMAR GPT1_REG32(0x038)
+#define GPTIMER1_TCAR1 GPT1_REG32(0x03C)
+#define GPTIMER1_TSICR GPT1_REG32(0x040)
+#define GPTIMER1_TCAR2 GPT1_REG32(0x044)
+
+/* rkw -- base fix up please... */
+#define GPTIMER3_TISR __REG32(OMAP24XX_L4_IO_BASE+0x78018)
+
+/* SDRC */
+#define SDRC_DLLA_CTRL __REG32(OMAP24XX_SDRC_BASE+0x060)
+#define SDRC_DLLA_STATUS __REG32(OMAP24XX_SDRC_BASE+0x064)
+#define SDRC_DLLB_CTRL __REG32(OMAP24XX_SDRC_BASE+0x068)
+#define SDRC_DLLB_STATUS __REG32(OMAP24XX_SDRC_BASE+0x06C)
+#define SDRC_POWER __REG32(OMAP24XX_SDRC_BASE+0x070)
+#define SDRC_MR_0 __REG32(OMAP24XX_SDRC_BASE+0x084)
+
+/* GPIO 1 */
+#define GPIO1_BASE GPIOX_BASE(1)
+#define GPIO1_REG32(offset) __REG32(GPIO1_BASE + (offset))
+#define GPIO1_IRQENABLE1 GPIO1_REG32(0x01C)
+#define GPIO1_IRQSTATUS1 GPIO1_REG32(0x018)
+#define GPIO1_IRQENABLE2 GPIO1_REG32(0x02C)
+#define GPIO1_IRQSTATUS2 GPIO1_REG32(0x028)
+#define GPIO1_WAKEUPENABLE GPIO1_REG32(0x020)
+#define GPIO1_RISINGDETECT GPIO1_REG32(0x048)
+#define GPIO1_DATAIN GPIO1_REG32(0x038)
+#define GPIO1_OE GPIO1_REG32(0x034)
+#define GPIO1_DATAOUT GPIO1_REG32(0x03C)
+
+/* GPIO2 */
+#define GPIO2_BASE GPIOX_BASE(2)
+#define GPIO2_REG32(offset) __REG32(GPIO2_BASE + (offset))
+#define GPIO2_IRQENABLE1 GPIO2_REG32(0x01C)
+#define GPIO2_IRQSTATUS1 GPIO2_REG32(0x018)
+#define GPIO2_IRQENABLE2 GPIO2_REG32(0x02C)
+#define GPIO2_IRQSTATUS2 GPIO2_REG32(0x028)
+#define GPIO2_WAKEUPENABLE GPIO2_REG32(0x020)
+#define GPIO2_RISINGDETECT GPIO2_REG32(0x048)
+#define GPIO2_DATAIN GPIO2_REG32(0x038)
+#define GPIO2_OE GPIO2_REG32(0x034)
+#define GPIO2_DATAOUT GPIO2_REG32(0x03C)
+
+/* GPIO 3 */
+#define GPIO3_BASE GPIOX_BASE(3)
+#define GPIO3_REG32(offset) __REG32(GPIO3_BASE + (offset))
+#define GPIO3_IRQENABLE1 GPIO3_REG32(0x01C)
+#define GPIO3_IRQSTATUS1 GPIO3_REG32(0x018)
+#define GPIO3_IRQENABLE2 GPIO3_REG32(0x02C)
+#define GPIO3_IRQSTATUS2 GPIO3_REG32(0x028)
+#define GPIO3_WAKEUPENABLE GPIO3_REG32(0x020)
+#define GPIO3_RISINGDETECT GPIO3_REG32(0x048)
+#define GPIO3_FALLINGDETECT GPIO3_REG32(0x04C)
+#define GPIO3_DATAIN GPIO3_REG32(0x038)
+#define GPIO3_OE GPIO3_REG32(0x034)
+#define GPIO3_DATAOUT GPIO3_REG32(0x03C)
+#define GPIO3_DEBOUNCENABLE GPIO3_REG32(0x050)
+#define GPIO3_DEBOUNCINGTIME GPIO3_REG32(0x054)
+
+/* GPIO 4 */
+#define GPIO4_BASE GPIOX_BASE(4)
+#define GPIO4_REG32(offset) __REG32(GPIO4_BASE + (offset))
+#define GPIO4_IRQENABLE1 GPIO4_REG32(0x01C)
+#define GPIO4_IRQSTATUS1 GPIO4_REG32(0x018)
+#define GPIO4_IRQENABLE2 GPIO4_REG32(0x02C)
+#define GPIO4_IRQSTATUS2 GPIO4_REG32(0x028)
+#define GPIO4_WAKEUPENABLE GPIO4_REG32(0x020)
+#define GPIO4_RISINGDETECT GPIO4_REG32(0x048)
+#define GPIO4_FALLINGDETECT GPIO4_REG32(0x04C)
+#define GPIO4_DATAIN GPIO4_REG32(0x038)
+#define GPIO4_OE GPIO4_REG32(0x034)
+#define GPIO4_DATAOUT GPIO4_REG32(0x03C)
+#define GPIO4_DEBOUNCENABLE GPIO4_REG32(0x050)
+#define GPIO4_DEBOUNCINGTIME GPIO4_REG32(0x054)
+
+
+/* IO CONFIG */
+#define CONTROL_BASE (OMAP24XX_CTRL_BASE)
+#define CONTROL_REG32(offset) __REG32(CONTROL_BASE + (offset))
+
+#define CONTROL_PADCONF_SPI1_NCS2 CONTROL_REG32(0x104)
+#define CONTROL_PADCONF_SYS_XTALOUT CONTROL_REG32(0x134)
+#define CONTROL_PADCONF_UART1_RX CONTROL_REG32(0x0C8)
+#define CONTROL_PADCONF_MCBSP1_DX CONTROL_REG32(0x10C)
+#define CONTROL_PADCONF_GPMC_NCS4 CONTROL_REG32(0x090)
+#define CONTROL_PADCONF_DSS_D5 CONTROL_REG32(0x0B8)
+#define CONTROL_PADCONF_DSS_D9 CONTROL_REG32(0x0BC)
+#define CONTROL_PADCONF_DSS_D13 CONTROL_REG32(0x0C0)
+#define CONTROL_PADCONF_DSS_VSYNC CONTROL_REG32(0x0CC)
+
+/* CONTROL */
+#define CONTROL_DEVCONF CONTROL_REG32(0x274)
+
+/* INTERRUPT CONTROLLER */
+#define INTC_BASE (OMAP24XX_L4_IO_BASE+0xfe000)
+#define INTC_REG32(offset) __REG32(INTC_BASE + (offset))
+
+#define INTC1_U_BASE INTC_REG32(0x000)
+#define INTC_MIR0 INTC_REG32(0x084)
+#define INTC_MIR_SET0 INTC_REG32(0x08C)
+#define INTC_MIR_CLEAR0 INTC_REG32(0x088)
+#define INTC_ISR_CLEAR0 INTC_REG32(0x094)
+#define INTC_MIR1 INTC_REG32(0x0A4)
+#define INTC_MIR_SET1 INTC_REG32(0x0AC)
+#define INTC_MIR_CLEAR1 INTC_REG32(0x0A8)
+#define INTC_ISR_CLEAR1 INTC_REG32(0x0B4)
+#define INTC_MIR2 INTC_REG32(0x0C4)
+#define INTC_MIR_SET2 INTC_REG32(0x0CC)
+#define INTC_MIR_CLEAR2 INTC_REG32(0x0C8)
+#define INTC_ISR_CLEAR2 INTC_REG32(0x0D4)
+#define INTC_SIR_IRQ INTC_REG32(0x040)
+#define INTC_CONTROL INTC_REG32(0x048)
+#define INTC_ILR11 INTC_REG32(0x12C)
+#define INTC_ILR32 INTC_REG32(0x180)
+#define INTC_ILR37 INTC_REG32(0x194)
+#define INTC_SYSCONFIG INTC_REG32(0x010)
+
+/* RAM FIREWALL */
+#define RAMFW_BASE (0x68005000)
+#define RAMFW_REG32(offset) __REG32(RAMFW_BASE + (offset))
+
+#define RAMFW_REQINFOPERM0 RAMFW_REG32(0x048)
+#define RAMFW_READPERM0 RAMFW_REG32(0x050)
+#define RAMFW_WRITEPERM0 RAMFW_REG32(0x058)
+
+/* GPMC CS1 FPGA ON USER INTERFACE MODULE */
+//#define DEBUG_BOARD_LED_REGISTER 0x04000014
+
+/* GPMC CS0 */
+#define GPMC_CONFIG1_0 GPMC_REG32(0x060)
+#define GPMC_CONFIG2_0 GPMC_REG32(0x064)
+#define GPMC_CONFIG3_0 GPMC_REG32(0x068)
+#define GPMC_CONFIG4_0 GPMC_REG32(0x06C)
+#define GPMC_CONFIG5_0 GPMC_REG32(0x070)
+#define GPMC_CONFIG6_0 GPMC_REG32(0x074)
+#define GPMC_CONFIG7_0 GPMC_REG32(0x078)
+
+/* DSS */
+#define DSS_CONTROL DISP_REG32(0x040)
+#define DISPC_CONTROL DISP_REG32(0x440)
+#define DISPC_SYSSTATUS DISP_REG32(0x414)
+#define DISPC_IRQSTATUS DISP_REG32(0x418)
+#define DISPC_IRQENABLE DISP_REG32(0x41C)
+#define DISPC_CONFIG DISP_REG32(0x444)
+#define DISPC_DEFAULT_COLOR0 DISP_REG32(0x44C)
+#define DISPC_DEFAULT_COLOR1 DISP_REG32(0x450)
+#define DISPC_TRANS_COLOR0 DISP_REG32(0x454)
+#define DISPC_TRANS_COLOR1 DISP_REG32(0x458)
+#define DISPC_LINE_NUMBER DISP_REG32(0x460)
+#define DISPC_TIMING_H DISP_REG32(0x464)
+#define DISPC_TIMING_V DISP_REG32(0x468)
+#define DISPC_POL_FREQ DISP_REG32(0x46C)
+#define DISPC_DIVISOR DISP_REG32(0x470)
+#define DISPC_SIZE_DIG DISP_REG32(0x478)
+#define DISPC_SIZE_LCD DISP_REG32(0x47C)
+#define DISPC_GFX_BA0 DISP_REG32(0x480)
+#define DISPC_GFX_BA1 DISP_REG32(0x484)
+#define DISPC_GFX_POSITION DISP_REG32(0x488)
+#define DISPC_GFX_SIZE DISP_REG32(0x48C)
+#define DISPC_GFX_ATTRIBUTES DISP_REG32(0x4A0)
+#define DISPC_GFX_FIFO_THRESHOLD DISP_REG32(0x4A4)
+#define DISPC_GFX_ROW_INC DISP_REG32(0x4AC)
+#define DISPC_GFX_PIXEL_INC DISP_REG32(0x4B0)
+#define DISPC_GFX_WINDOW_SKIP DISP_REG32(0x4B4)
+#define DISPC_GFX_TABLE_BA DISP_REG32(0x4B8)
+#define DISPC_DATA_CYCLE1 DISP_REG32(0x5D4)
+#define DISPC_DATA_CYCLE2 DISP_REG32(0x5D8)
+#define DISPC_DATA_CYCLE3 DISP_REG32(0x5DC)
+
+/* Wake up define for board */
+#define GPIO97 (1 << 1)
+#define GPIO88 (1 << 24)
+
+#endif /* __ASSEMBLER__ */
+
+#endif
+
+
+
+
+
diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c
new file mode 100644
index 000000000000..f4df04fe1dd8
--- /dev/null
+++ b/arch/arm/mach-omap2/serial.c
@@ -0,0 +1,180 @@
+/*
+ * arch/arm/mach-omap/omap2/serial.c
+ *
+ * OMAP2 serial support.
+ *
+ * Copyright (C) 2005 Nokia Corporation
+ * Author: Paul Mundt <paul.mundt@nokia.com>
+ *
+ * Based off of arch/arm/mach-omap/omap1/serial.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/kernel.h>
+#include <linux/init.h>
+#include <linux/serial_8250.h>
+#include <linux/serial_reg.h>
+
+#include <asm/io.h>
+#include <asm/hardware/clock.h>
+
+#include <asm/arch/common.h>
+#include <asm/arch/board.h>
+
+static struct clk * uart1_ick = NULL;
+static struct clk * uart1_fck = NULL;
+static struct clk * uart2_ick = NULL;
+static struct clk * uart2_fck = NULL;
+static struct clk * uart3_ick = NULL;
+static struct clk * uart3_fck = NULL;
+
+static struct plat_serial8250_port serial_platform_data[] = {
+ {
+ .membase = (char *)IO_ADDRESS(OMAP_UART1_BASE),
+ .mapbase = (unsigned long)OMAP_UART1_BASE,
+ .irq = 72,
+ .flags = UPF_BOOT_AUTOCONF,
+ .iotype = UPIO_MEM,
+ .regshift = 2,
+ .uartclk = OMAP16XX_BASE_BAUD * 16,
+ }, {
+ .membase = (char *)IO_ADDRESS(OMAP_UART2_BASE),
+ .mapbase = (unsigned long)OMAP_UART2_BASE,
+ .irq = 73,
+ .flags = UPF_BOOT_AUTOCONF,
+ .iotype = UPIO_MEM,
+ .regshift = 2,
+ .uartclk = OMAP16XX_BASE_BAUD * 16,
+ }, {
+ .membase = (char *)IO_ADDRESS(OMAP_UART3_BASE),
+ .mapbase = (unsigned long)OMAP_UART3_BASE,
+ .irq = 74,
+ .flags = UPF_BOOT_AUTOCONF,
+ .iotype = UPIO_MEM,
+ .regshift = 2,
+ .uartclk = OMAP16XX_BASE_BAUD * 16,
+ }, {
+ .flags = 0
+ }
+};
+
+static inline unsigned int serial_read_reg(struct plat_serial8250_port *up,
+ int offset)
+{
+ offset <<= up->regshift;
+ return (unsigned int)__raw_readb(up->membase + offset);
+}
+
+static inline void serial_write_reg(struct plat_serial8250_port *p, int offset,
+ int value)
+{
+ offset <<= p->regshift;
+ __raw_writeb(value, (unsigned long)(p->membase + offset));
+}
+
+/*
+ * Internal UARTs need to be initialized for the 8250 autoconfig to work
+ * properly. Note that the TX watermark initialization may not be needed
+ * once the 8250.c watermark handling code is merged.
+ */
+static inline void __init omap_serial_reset(struct plat_serial8250_port *p)
+{
+ serial_write_reg(p, UART_OMAP_MDR1, 0x07);
+ serial_write_reg(p, UART_OMAP_SCR, 0x08);
+ serial_write_reg(p, UART_OMAP_MDR1, 0x00);
+ serial_write_reg(p, UART_OMAP_SYSC, 0x01);
+}
+
+void __init omap_serial_init()
+{
+ int i;
+ const struct omap_uart_config *info;
+
+ /*
+ * Make sure the serial ports are muxed on at this point.
+ * You have to mux them off in device drivers later on
+ * if not needed.
+ */
+
+ info = omap_get_config(OMAP_TAG_UART,
+ struct omap_uart_config);
+
+ if (info == NULL)
+ return;
+
+ for (i = 0; i < OMAP_MAX_NR_PORTS; i++) {
+ struct plat_serial8250_port *p = serial_platform_data + i;
+
+ if (!(info->enabled_uarts & (1 << i))) {
+ p->membase = 0;
+ p->mapbase = 0;
+ continue;
+ }
+
+ switch (i) {
+ case 0:
+ uart1_ick = clk_get(NULL, "uart1_ick");
+ if (IS_ERR(uart1_ick))
+ printk("Could not get uart1_ick\n");
+ else {
+ clk_use(uart1_ick);
+ }
+
+ uart1_fck = clk_get(NULL, "uart1_fck");
+ if (IS_ERR(uart1_fck))
+ printk("Could not get uart1_fck\n");
+ else {
+ clk_use(uart1_fck);
+ }
+ break;
+ case 1:
+ uart2_ick = clk_get(NULL, "uart2_ick");
+ if (IS_ERR(uart2_ick))
+ printk("Could not get uart2_ick\n");
+ else {
+ clk_use(uart2_ick);
+ }
+
+ uart2_fck = clk_get(NULL, "uart2_fck");
+ if (IS_ERR(uart2_fck))
+ printk("Could not get uart2_fck\n");
+ else {
+ clk_use(uart2_fck);
+ }
+ break;
+ case 2:
+ uart3_ick = clk_get(NULL, "uart3_ick");
+ if (IS_ERR(uart3_ick))
+ printk("Could not get uart3_ick\n");
+ else {
+ clk_use(uart3_ick);
+ }
+
+ uart3_fck = clk_get(NULL, "uart3_fck");
+ if (IS_ERR(uart3_fck))
+ printk("Could not get uart3_fck\n");
+ else {
+ clk_use(uart3_fck);
+ }
+ break;
+ }
+
+ omap_serial_reset(p);
+ }
+}
+
+static struct platform_device serial_device = {
+ .name = "serial8250",
+ .id = 0,
+ .dev = {
+ .platform_data = serial_platform_data,
+ },
+};
+
+static int __init omap_init(void)
+{
+ return platform_device_register(&serial_device);
+}
+arch_initcall(omap_init);
diff --git a/arch/arm/mach-omap2/sram-fn.S b/arch/arm/mach-omap2/sram-fn.S
new file mode 100644
index 000000000000..2a869e203342
--- /dev/null
+++ b/arch/arm/mach-omap2/sram-fn.S
@@ -0,0 +1,333 @@
+/*
+ * linux/arch/arm/mach-omap1/sram.S
+ *
+ * Omap2 specific functions that need to be run in internal SRAM
+ *
+ * (C) Copyright 2004
+ * Texas Instruments, <www.ti.com>
+ * Richard Woodruff <r-woodruff2@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR /PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+#include <linux/config.h>
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <asm/arch/io.h>
+#include <asm/hardware.h>
+
+#include <asm/arch/prcm.h>
+
+#define TIMER_32KSYNCT_CR_V IO_ADDRESS(OMAP24XX_32KSYNCT_BASE + 0x010)
+
+#define CM_CLKSEL2_PLL_V IO_ADDRESS(OMAP24XX_PRCM_BASE + 0x544)
+#define PRCM_VOLTCTRL_V IO_ADDRESS(OMAP24XX_PRCM_BASE + 0x050)
+#define PRCM_CLKCFG_CTRL_V IO_ADDRESS(OMAP24XX_PRCM_BASE + 0x080)
+#define CM_CLKEN_PLL_V IO_ADDRESS(OMAP24XX_PRCM_BASE + 0x500)
+#define CM_IDLEST_CKGEN_V IO_ADDRESS(OMAP24XX_PRCM_BASE + 0x520)
+#define CM_CLKSEL1_PLL_V IO_ADDRESS(OMAP24XX_PRCM_BASE + 0x540)
+
+#define SDRC_DLLA_CTRL_V IO_ADDRESS(OMAP24XX_SDRC_BASE + 0x060)
+#define SDRC_RFR_CTRL_V IO_ADDRESS(OMAP24XX_SDRC_BASE + 0x0a4)
+
+ .text
+
+ENTRY(sram_ddr_init)
+ stmfd sp!, {r0 - r12, lr} @ save registers on stack
+
+ mov r12, r2 @ capture CS1 vs CS0
+ mov r8, r3 @ capture force parameter
+
+ /* frequency shift down */
+ ldr r2, cm_clksel2_pll @ get address of dpllout reg
+ mov r3, #0x1 @ value for 1x operation
+ str r3, [r2] @ go to L1-freq operation
+
+ /* voltage shift down */
+ mov r9, #0x1 @ set up for L1 voltage call
+ bl voltage_shift @ go drop voltage
+
+ /* dll lock mode */
+ ldr r11, sdrc_dlla_ctrl @ addr of dlla ctrl
+ ldr r10, [r11] @ get current val
+ cmp r12, #0x1 @ cs1 base (2422 es2.05/1)
+ addeq r11, r11, #0x8 @ if cs1 base, move to DLLB
+ mvn r9, #0x4 @ mask to get clear bit2
+ and r10, r10, r9 @ clear bit2 for lock mode.
+ orr r10, r10, #0x8 @ make sure DLL on (es2 bit pos)
+ orr r10, r10, #0x2 @ 90 degree phase for all below 133Mhz
+ str r10, [r11] @ commit to DLLA_CTRL
+ bl i_dll_wait @ wait for dll to lock
+
+ /* get dll value */
+ add r11, r11, #0x4 @ get addr of status reg
+ ldr r10, [r11] @ get locked value
+
+ /* voltage shift up */
+ mov r9, #0x0 @ shift back to L0-voltage
+ bl voltage_shift @ go raise voltage
+
+ /* frequency shift up */
+ mov r3, #0x2 @ value for 2x operation
+ str r3, [r2] @ go to L0-freq operation
+
+ /* reset entry mode for dllctrl */
+ sub r11, r11, #0x4 @ move from status to ctrl
+ cmp r12, #0x1 @ normalize if cs1 based
+ subeq r11, r11, #0x8 @ possibly back to DLLA
+ cmp r8, #0x1 @ if forced unlock exit
+ orreq r1, r1, #0x4 @ make sure exit with unlocked value
+ str r1, [r11] @ restore DLLA_CTRL high value
+ add r11, r11, #0x8 @ move to DLLB_CTRL addr
+ str r1, [r11] @ set value DLLB_CTRL
+ bl i_dll_wait @ wait for possible lock
+
+ /* set up for return, DDR should be good */
+ str r10, [r0] @ write dll_status and return counter
+ ldmfd sp!, {r0 - r12, pc} @ restore regs and return
+
+ /* ensure the DLL has relocked */
+i_dll_wait:
+ mov r4, #0x800 @ delay DLL relock, min 0x400 L3 clocks
+i_dll_delay:
+ subs r4, r4, #0x1
+ bne i_dll_delay
+ mov pc, lr
+
+ /*
+ * shift up or down voltage, use R9 as input to tell level.
+ * wait for it to finish, use 32k sync counter, 1tick=31uS.
+ */
+voltage_shift:
+ ldr r4, prcm_voltctrl @ get addr of volt ctrl.
+ ldr r5, [r4] @ get value.
+ ldr r6, prcm_mask_val @ get value of mask
+ and r5, r5, r6 @ apply mask to clear bits
+ orr r5, r5, r9 @ bulld value for L0/L1-volt operation.
+ str r5, [r4] @ set up for change.
+ mov r3, #0x4000 @ get val for force
+ orr r5, r5, r3 @ build value for force
+ str r5, [r4] @ Force transition to L1
+
+ ldr r3, timer_32ksynct_cr @ get addr of counter
+ ldr r5, [r3] @ get value
+ add r5, r5, #0x3 @ give it at most 93uS
+volt_delay:
+ ldr r7, [r3] @ get timer value
+ cmp r5, r7 @ time up?
+ bhi volt_delay @ not yet->branch
+ mov pc, lr @ back to caller.
+
+/* relative load constants */
+cm_clksel2_pll:
+ .word CM_CLKSEL2_PLL_V
+sdrc_dlla_ctrl:
+ .word SDRC_DLLA_CTRL_V
+prcm_voltctrl:
+ .word PRCM_VOLTCTRL_V
+prcm_mask_val:
+ .word 0xFFFF3FFC
+timer_32ksynct_cr:
+ .word TIMER_32KSYNCT_CR_V
+ENTRY(sram_ddr_init_sz)
+ .word . - sram_ddr_init
+
+/*
+ * Reprograms memory timings.
+ * r0 = [PRCM_FULL | PRCM_HALF] r1 = SDRC_DLLA_CTRL value r2 = [DDR | SDR]
+ * PRCM_FULL = 2, PRCM_HALF = 1, DDR = 1, SDR = 0
+ */
+ENTRY(sram_reprogram_sdrc)
+ stmfd sp!, {r0 - r10, lr} @ save registers on stack
+ mov r3, #0x0 @ clear for mrc call
+ mcr p15, 0, r3, c7, c10, 4 @ memory barrier, finish ARM SDR/DDR
+ nop
+ nop
+ ldr r6, ddr_sdrc_rfr_ctrl @ get addr of refresh reg
+ ldr r5, [r6] @ get value
+ mov r5, r5, lsr #8 @ isolate rfr field and drop burst
+
+ cmp r0, #0x1 @ going to half speed?
+ movne r9, #0x0 @ if up set flag up for pre up, hi volt
+
+ blne voltage_shift_c @ adjust voltage
+
+ cmp r0, #0x1 @ going to half speed (post branch link)
+ moveq r5, r5, lsr #1 @ divide by 2 if to half
+ movne r5, r5, lsl #1 @ mult by 2 if to full
+ mov r5, r5, lsl #8 @ put rfr field back into place
+ add r5, r5, #0x1 @ turn on burst of 1
+ ldr r4, ddr_cm_clksel2_pll @ get address of out reg
+ ldr r3, [r4] @ get curr value
+ orr r3, r3, #0x3
+ bic r3, r3, #0x3 @ clear lower bits
+ orr r3, r3, r0 @ new state value
+ str r3, [r4] @ set new state (pll/x, x=1 or 2)
+ nop
+ nop
+
+ moveq r9, #0x1 @ if speed down, post down, drop volt
+ bleq voltage_shift_c
+
+ mcr p15, 0, r3, c7, c10, 4 @ memory barrier
+ str r5, [r6] @ set new RFR_1 value
+ add r6, r6, #0x30 @ get RFR_2 addr
+ str r5, [r6] @ set RFR_2
+ nop
+ cmp r2, #0x1 @ (SDR or DDR) do we need to adjust DLL
+ bne freq_out @ leave if SDR, no DLL function
+
+ /* With DDR, we need to take care of the DLL for the frequency change */
+ ldr r2, ddr_sdrc_dlla_ctrl @ addr of dlla ctrl
+ str r1, [r2] @ write out new SDRC_DLLA_CTRL
+ add r2, r2, #0x8 @ addr to SDRC_DLLB_CTRL
+ str r1, [r2] @ commit to SDRC_DLLB_CTRL
+ mov r1, #0x2000 @ wait DLL relock, min 0x400 L3 clocks
+dll_wait:
+ subs r1, r1, #0x1
+ bne dll_wait
+freq_out:
+ ldmfd sp!, {r0 - r10, pc} @ restore regs and return
+
+ /*
+ * shift up or down voltage, use R9 as input to tell level.
+ * wait for it to finish, use 32k sync counter, 1tick=31uS.
+ */
+voltage_shift_c:
+ ldr r10, ddr_prcm_voltctrl @ get addr of volt ctrl
+ ldr r8, [r10] @ get value
+ ldr r7, ddr_prcm_mask_val @ get value of mask
+ and r8, r8, r7 @ apply mask to clear bits
+ orr r8, r8, r9 @ bulld value for L0/L1-volt operation.
+ str r8, [r10] @ set up for change.
+ mov r7, #0x4000 @ get val for force
+ orr r8, r8, r7 @ build value for force
+ str r8, [r10] @ Force transition to L1
+
+ ldr r10, ddr_timer_32ksynct @ get addr of counter
+ ldr r8, [r10] @ get value
+ add r8, r8, #0x2 @ give it at most 62uS (min 31+)
+volt_delay_c:
+ ldr r7, [r10] @ get timer value
+ cmp r8, r7 @ time up?
+ bhi volt_delay_c @ not yet->branch
+ mov pc, lr @ back to caller
+
+ddr_cm_clksel2_pll:
+ .word CM_CLKSEL2_PLL_V
+ddr_sdrc_dlla_ctrl:
+ .word SDRC_DLLA_CTRL_V
+ddr_sdrc_rfr_ctrl:
+ .word SDRC_RFR_CTRL_V
+ddr_prcm_voltctrl:
+ .word PRCM_VOLTCTRL_V
+ddr_prcm_mask_val:
+ .word 0xFFFF3FFC
+ddr_timer_32ksynct:
+ .word TIMER_32KSYNCT_CR_V
+
+ENTRY(sram_reprogram_sdrc_sz)
+ .word . - sram_reprogram_sdrc
+
+/*
+ * Set dividers and pll. Also recalculate DLL value for DDR and unlock mode.
+ */
+ENTRY(sram_set_prcm)
+ stmfd sp!, {r0-r12, lr} @ regs to stack
+ adr r4, pbegin @ addr of preload start
+ adr r8, pend @ addr of preload end
+ mcrr p15, 1, r8, r4, c12 @ preload into icache
+pbegin:
+ /* move into fast relock bypass */
+ ldr r8, pll_ctl @ get addr
+ ldr r5, [r8] @ get val
+ mvn r6, #0x3 @ clear mask
+ and r5, r5, r6 @ clear field
+ orr r7, r5, #0x2 @ fast relock val
+ str r7, [r8] @ go to fast relock
+ ldr r4, pll_stat @ addr of stat
+block:
+ /* wait for bypass */
+ ldr r8, [r4] @ stat value
+ and r8, r8, #0x3 @ mask for stat
+ cmp r8, #0x1 @ there yet
+ bne block @ loop if not
+
+ /* set new dpll dividers _after_ in bypass */
+ ldr r4, pll_div @ get addr
+ str r0, [r4] @ set dpll ctrl val
+
+ ldr r4, set_config @ get addr
+ mov r8, #1 @ valid cfg msk
+ str r8, [r4] @ make dividers take
+
+ mov r4, #100 @ dead spin a bit
+wait_a_bit:
+ subs r4, r4, #1 @ dec loop
+ bne wait_a_bit @ delay done?
+
+ /* check if staying in bypass */
+ cmp r2, #0x1 @ stay in bypass?
+ beq pend @ jump over dpll relock
+
+ /* relock DPLL with new vals */
+ ldr r5, pll_stat @ get addr
+ ldr r4, pll_ctl @ get addr
+ orr r8, r7, #0x3 @ val for lock dpll
+ str r8, [r4] @ set val
+ mov r0, #1000 @ dead spin a bit
+wait_more:
+ subs r0, r0, #1 @ dec loop
+ bne wait_more @ delay done?
+wait_lock:
+ ldr r8, [r5] @ get lock val
+ and r8, r8, #3 @ isolate field
+ cmp r8, #2 @ locked?
+ bne wait_lock @ wait if not
+pend:
+ /* update memory timings & briefly lock dll */
+ ldr r4, sdrc_rfr @ get addr
+ str r1, [r4] @ update refresh timing
+ ldr r11, dlla_ctrl @ get addr of DLLA ctrl
+ ldr r10, [r11] @ get current val
+ mvn r9, #0x4 @ mask to get clear bit2
+ and r10, r10, r9 @ clear bit2 for lock mode
+ orr r10, r10, #0x8 @ make sure DLL on (es2 bit pos)
+ str r10, [r11] @ commit to DLLA_CTRL
+ add r11, r11, #0x8 @ move to dllb
+ str r10, [r11] @ hit DLLB also
+
+ mov r4, #0x800 @ relock time (min 0x400 L3 clocks)
+wait_dll_lock:
+ subs r4, r4, #0x1
+ bne wait_dll_lock
+ nop
+ ldmfd sp!, {r0-r12, pc} @ restore regs and return
+
+set_config:
+ .word PRCM_CLKCFG_CTRL_V
+pll_ctl:
+ .word CM_CLKEN_PLL_V
+pll_stat:
+ .word CM_IDLEST_CKGEN_V
+pll_div:
+ .word CM_CLKSEL1_PLL_V
+sdrc_rfr:
+ .word SDRC_RFR_CTRL_V
+dlla_ctrl:
+ .word SDRC_DLLA_CTRL_V
+
+ENTRY(sram_set_prcm_sz)
+ .word . - sram_set_prcm
diff --git a/arch/arm/mach-omap2/timer-gp.c b/arch/arm/mach-omap2/timer-gp.c
new file mode 100644
index 000000000000..9ec11443200f
--- /dev/null
+++ b/arch/arm/mach-omap2/timer-gp.c
@@ -0,0 +1,126 @@
+/*
+ * linux/arch/arm/mach-omap2/timer-gp.c
+ *
+ * OMAP2 GP timer support.
+ *
+ * Copyright (C) 2005 Nokia Corporation
+ * Author: Paul Mundt <paul.mundt@nokia.com>
+ * Juha Yrjölä <juha.yrjola@nokia.com>
+ *
+ * Some parts based off of TI's 24xx code:
+ *
+ * Copyright (C) 2004 Texas Instruments, Inc.
+ *
+ * Roughly modelled after the OMAP1 MPU timer code.
+ *
+ * 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/time.h>
+#include <linux/interrupt.h>
+#include <linux/err.h>
+#include <asm/mach/time.h>
+#include <asm/delay.h>
+#include <asm/io.h>
+#include <asm/hardware/clock.h>
+
+#define OMAP2_GP_TIMER1_BASE 0x48028000
+#define OMAP2_GP_TIMER2_BASE 0x4802a000
+#define OMAP2_GP_TIMER3_BASE 0x48078000
+#define OMAP2_GP_TIMER4_BASE 0x4807a000
+
+#define GP_TIMER_TIDR 0x00
+#define GP_TIMER_TISR 0x18
+#define GP_TIMER_TIER 0x1c
+#define GP_TIMER_TCLR 0x24
+#define GP_TIMER_TCRR 0x28
+#define GP_TIMER_TLDR 0x2c
+#define GP_TIMER_TSICR 0x40
+
+#define OS_TIMER_NR 1 /* GP timer 2 */
+
+static unsigned long timer_base[] = {
+ IO_ADDRESS(OMAP2_GP_TIMER1_BASE),
+ IO_ADDRESS(OMAP2_GP_TIMER2_BASE),
+ IO_ADDRESS(OMAP2_GP_TIMER3_BASE),
+ IO_ADDRESS(OMAP2_GP_TIMER4_BASE),
+};
+
+static inline unsigned int timer_read_reg(int nr, unsigned int reg)
+{
+ return __raw_readl(timer_base[nr] + reg);
+}
+
+static inline void timer_write_reg(int nr, unsigned int reg, unsigned int val)
+{
+ __raw_writel(val, timer_base[nr] + reg);
+}
+
+/* Note that we always enable the clock prescale divider bit */
+static inline void omap2_gp_timer_start(int nr, unsigned long load_val)
+{
+ unsigned int tmp;
+
+ tmp = 0xffffffff - load_val;
+
+ timer_write_reg(nr, GP_TIMER_TLDR, tmp);
+ timer_write_reg(nr, GP_TIMER_TCRR, tmp);
+ timer_write_reg(nr, GP_TIMER_TIER, 1 << 1);
+ timer_write_reg(nr, GP_TIMER_TCLR, (1 << 5) | (1 << 1) | 1);
+}
+
+static irqreturn_t omap2_gp_timer_interrupt(int irq, void *dev_id,
+ struct pt_regs *regs)
+{
+ write_seqlock(&xtime_lock);
+
+ timer_write_reg(OS_TIMER_NR, GP_TIMER_TISR, 1 << 1);
+ timer_tick(regs);
+
+ write_sequnlock(&xtime_lock);
+
+ return IRQ_HANDLED;
+}
+
+static struct irqaction omap2_gp_timer_irq = {
+ .name = "gp timer",
+ .flags = SA_INTERRUPT,
+ .handler = omap2_gp_timer_interrupt,
+};
+
+static void __init omap2_gp_timer_init(void)
+{
+ struct clk * sys_ck;
+ u32 tick_period = 120000;
+ u32 l;
+
+ /* Reset clock and prescale value */
+ timer_write_reg(OS_TIMER_NR, GP_TIMER_TCLR, 0);
+
+ sys_ck = clk_get(NULL, "sys_ck");
+ if (IS_ERR(sys_ck))
+ printk(KERN_ERR "Could not get sys_ck\n");
+ else {
+ clk_use(sys_ck);
+ tick_period = clk_get_rate(sys_ck) / 100;
+ clk_put(sys_ck);
+ }
+
+ tick_period /= 2; /* Minimum prescale divider is 2 */
+ tick_period -= 1;
+
+ l = timer_read_reg(OS_TIMER_NR, GP_TIMER_TIDR);
+ printk(KERN_INFO "OMAP2 GP timer (HW version %d.%d)\n",
+ (l >> 4) & 0x0f, l & 0x0f);
+
+ setup_irq(38, &omap2_gp_timer_irq);
+
+ omap2_gp_timer_start(OS_TIMER_NR, tick_period);
+}
+
+struct sys_timer omap_timer = {
+ .init = omap2_gp_timer_init,
+};
+
diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig
index 3e5f69bb5ac4..e201aa9765b9 100644
--- a/arch/arm/mach-pxa/Kconfig
+++ b/arch/arm/mach-pxa/Kconfig
@@ -27,7 +27,8 @@ config PXA_SHARPSL
Say Y here if you intend to run this kernel on a
Sharp Zaurus SL-5600 (Poodle), SL-C700 (Corgi),
SL-C750 (Shepherd), SL-C760 (Husky), SL-C1000 (Akita),
- SL-C3000 (Spitz) or SL-C3100 (Borzoi) handheld computer.
+ SL-C3000 (Spitz), SL-C3100 (Borzoi) or SL-C6000x (Tosa)
+ handheld computer.
endchoice
@@ -37,7 +38,7 @@ choice
prompt "Select target Sharp Zaurus device range"
config PXA_SHARPSL_25x
- bool "Sharp PXA25x models (SL-5600 and SL-C7xx)"
+ bool "Sharp PXA25x models (SL-5600, SL-C7xx and SL-C6000x)"
select PXA25x
config PXA_SHARPSL_27x
@@ -59,6 +60,7 @@ config MACH_CORGI
bool "Enable Sharp SL-C700 (Corgi) Support"
depends PXA_SHARPSL_25x
select PXA_SHARP_C7xx
+ select PXA_SSP
config MACH_SHEPHERD
bool "Enable Sharp SL-C750 (Shepherd) Support"
@@ -80,6 +82,10 @@ config MACH_BORZOI
depends PXA_SHARPSL_27x
select PXA_SHARP_Cxx00
+config MACH_TOSA
+ bool "Enable Sharp SL-6000x (Tosa) Support"
+ depends PXA_SHARPSL
+
config PXA25x
bool
help
@@ -97,12 +103,18 @@ config IWMMXT
config PXA_SHARP_C7xx
bool
+ select PXA_SSP
help
Enable support for all Sharp C7xx models
config PXA_SHARP_Cxx00
bool
+ select PXA_SSP
help
Enable common support for Sharp Cxx00 models
+config PXA_SSP
+ tristate
+ help
+ Enable support for PXA2xx SSP ports
endif
diff --git a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile
index f609a0f232cb..d210bd5032ce 100644
--- a/arch/arm/mach-pxa/Makefile
+++ b/arch/arm/mach-pxa/Makefile
@@ -11,9 +11,10 @@ obj-$(CONFIG_PXA27x) += pxa27x.o
obj-$(CONFIG_ARCH_LUBBOCK) += lubbock.o
obj-$(CONFIG_MACH_MAINSTONE) += mainstone.o
obj-$(CONFIG_ARCH_PXA_IDP) += idp.o
-obj-$(CONFIG_PXA_SHARP_C7xx) += corgi.o corgi_ssp.o corgi_lcd.o ssp.o
-obj-$(CONFIG_PXA_SHARP_Cxx00) += spitz.o corgi_ssp.o corgi_lcd.o ssp.o
+obj-$(CONFIG_PXA_SHARP_C7xx) += corgi.o corgi_ssp.o corgi_lcd.o
+obj-$(CONFIG_PXA_SHARP_Cxx00) += spitz.o corgi_ssp.o corgi_lcd.o
obj-$(CONFIG_MACH_POODLE) += poodle.o
+obj-$(CONFIG_MACH_TOSA) += tosa.o
# Support for blinky lights
led-y := leds.o
@@ -25,6 +26,7 @@ obj-$(CONFIG_LEDS) += $(led-y)
# Misc features
obj-$(CONFIG_PM) += pm.o sleep.o
+obj-$(CONFIG_PXA_SSP) += ssp.o
ifeq ($(CONFIG_PXA27x),y)
obj-$(CONFIG_PM) += standby.o
diff --git a/arch/arm/mach-pxa/corgi.c b/arch/arm/mach-pxa/corgi.c
index 60c8b9d8bb9c..100fb31b5156 100644
--- a/arch/arm/mach-pxa/corgi.c
+++ b/arch/arm/mach-pxa/corgi.c
@@ -14,7 +14,7 @@
#include <linux/kernel.h>
#include <linux/init.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <linux/major.h>
#include <linux/fs.h>
#include <linux/interrupt.h>
@@ -33,6 +33,7 @@
#include <asm/arch/pxa-regs.h>
#include <asm/arch/irq.h>
+#include <asm/arch/irda.h>
#include <asm/arch/mmc.h>
#include <asm/arch/udc.h>
#include <asm/arch/corgi.h>
@@ -61,6 +62,37 @@ static struct scoop_config corgi_scoop_setup = {
.io_out = CORGI_SCOOP_IO_OUT,
};
+struct platform_device corgiscoop_device = {
+ .name = "sharp-scoop",
+ .id = -1,
+ .dev = {
+ .platform_data = &corgi_scoop_setup,
+ },
+ .num_resources = ARRAY_SIZE(corgi_scoop_resources),
+ .resource = corgi_scoop_resources,
+};
+
+static void corgi_pcmcia_init(void)
+{
+ /* Setup default state of GPIO outputs
+ before we enable them as outputs. */
+ GPSR(GPIO48_nPOE) = GPIO_bit(GPIO48_nPOE) |
+ GPIO_bit(GPIO49_nPWE) | GPIO_bit(GPIO50_nPIOR) |
+ GPIO_bit(GPIO51_nPIOW) | GPIO_bit(GPIO52_nPCE_1) |
+ GPIO_bit(GPIO53_nPCE_2);
+
+ pxa_gpio_mode(GPIO48_nPOE_MD);
+ pxa_gpio_mode(GPIO49_nPWE_MD);
+ pxa_gpio_mode(GPIO50_nPIOR_MD);
+ pxa_gpio_mode(GPIO51_nPIOW_MD);
+ pxa_gpio_mode(GPIO55_nPREG_MD);
+ pxa_gpio_mode(GPIO56_nPWAIT_MD);
+ pxa_gpio_mode(GPIO57_nIOIS16_MD);
+ pxa_gpio_mode(GPIO52_nPCE_1_MD);
+ pxa_gpio_mode(GPIO53_nPCE_2_MD);
+ pxa_gpio_mode(GPIO54_pSKTSEL_MD);
+}
+
static struct scoop_pcmcia_dev corgi_pcmcia_scoop[] = {
{
.dev = &corgiscoop_device.dev,
@@ -70,16 +102,14 @@ static struct scoop_pcmcia_dev corgi_pcmcia_scoop[] = {
},
};
-struct platform_device corgiscoop_device = {
- .name = "sharp-scoop",
- .id = -1,
- .dev = {
- .platform_data = &corgi_scoop_setup,
- },
- .num_resources = ARRAY_SIZE(corgi_scoop_resources),
- .resource = corgi_scoop_resources,
+static struct scoop_pcmcia_config corgi_pcmcia_config = {
+ .devs = &corgi_pcmcia_scoop[0],
+ .num_devs = 1,
+ .pcmcia_init = corgi_pcmcia_init,
};
+EXPORT_SYMBOL(corgiscoop_device);
+
/*
* Corgi SSP Device
@@ -224,6 +254,22 @@ static struct pxamci_platform_data corgi_mci_platform_data = {
};
+/*
+ * Irda
+ */
+static void corgi_irda_transceiver_mode(struct device *dev, int mode)
+{
+ if (mode & IR_OFF)
+ GPSR(CORGI_GPIO_IR_ON) = GPIO_bit(CORGI_GPIO_IR_ON);
+ else
+ GPCR(CORGI_GPIO_IR_ON) = GPIO_bit(CORGI_GPIO_IR_ON);
+}
+
+static struct pxaficp_platform_data corgi_ficp_platform_data = {
+ .transceiver_cap = IR_SIRMODE | IR_OFF,
+ .transceiver_mode = corgi_irda_transceiver_mode,
+};
+
/*
* USB Device Controller
@@ -269,13 +315,15 @@ static void __init corgi_init(void)
corgi_ssp_set_machinfo(&corgi_ssp_machinfo);
+ pxa_gpio_mode(CORGI_GPIO_IR_ON | GPIO_OUT);
pxa_gpio_mode(CORGI_GPIO_USB_PULLUP | GPIO_OUT);
pxa_gpio_mode(CORGI_GPIO_HSYNC | GPIO_IN);
+
pxa_set_udc_info(&udc_info);
pxa_set_mci_info(&corgi_mci_platform_data);
+ pxa_set_ficp_info(&corgi_ficp_platform_data);
- scoop_num = 1;
- scoop_devs = &corgi_pcmcia_scoop[0];
+ platform_scoop_config = &corgi_pcmcia_config;
platform_add_devices(devices, ARRAY_SIZE(devices));
}
diff --git a/arch/arm/mach-pxa/corgi_lcd.c b/arch/arm/mach-pxa/corgi_lcd.c
index 370df113dc06..698eb06545c4 100644
--- a/arch/arm/mach-pxa/corgi_lcd.c
+++ b/arch/arm/mach-pxa/corgi_lcd.c
@@ -17,8 +17,9 @@
#include <linux/delay.h>
#include <linux/kernel.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <linux/module.h>
+#include <linux/string.h>
#include <asm/arch/akita.h>
#include <asm/arch/corgi.h>
#include <asm/arch/hardware.h>
diff --git a/arch/arm/mach-pxa/corgi_ssp.c b/arch/arm/mach-pxa/corgi_ssp.c
index 0ef428287055..bdf10cfa9440 100644
--- a/arch/arm/mach-pxa/corgi_ssp.c
+++ b/arch/arm/mach-pxa/corgi_ssp.c
@@ -15,7 +15,7 @@
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/delay.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <asm/hardware.h>
#include <asm/mach-types.h>
@@ -203,7 +203,7 @@ static int __init corgi_ssp_probe(struct device *dev)
GPDR(ssp_machinfo->cs_ads7846) |= GPIO_bit(ssp_machinfo->cs_ads7846); /* output */
GPSR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846); /* High - Disable ADS7846*/
- ret = ssp_init(&corgi_ssp_dev,ssp_machinfo->port);
+ ret = ssp_init(&corgi_ssp_dev, ssp_machinfo->port, 0);
if (ret)
printk(KERN_ERR "Unable to register SSP handler!\n");
@@ -222,24 +222,22 @@ static int corgi_ssp_remove(struct device *dev)
return 0;
}
-static int corgi_ssp_suspend(struct device *dev, pm_message_t state, u32 level)
+static int corgi_ssp_suspend(struct device *dev, pm_message_t state)
{
- if (level == SUSPEND_POWER_DOWN) {
- ssp_flush(&corgi_ssp_dev);
- ssp_save_state(&corgi_ssp_dev,&corgi_ssp_state);
- }
+ ssp_flush(&corgi_ssp_dev);
+ ssp_save_state(&corgi_ssp_dev,&corgi_ssp_state);
+
return 0;
}
-static int corgi_ssp_resume(struct device *dev, u32 level)
+static int corgi_ssp_resume(struct device *dev)
{
- if (level == RESUME_POWER_ON) {
- GPSR(ssp_machinfo->cs_lcdcon) = GPIO_bit(ssp_machinfo->cs_lcdcon); /* High - Disable LCD Control/Timing Gen */
- GPSR(ssp_machinfo->cs_max1111) = GPIO_bit(ssp_machinfo->cs_max1111); /* High - Disable MAX1111*/
- GPSR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846); /* High - Disable ADS7846*/
- ssp_restore_state(&corgi_ssp_dev,&corgi_ssp_state);
- ssp_enable(&corgi_ssp_dev);
- }
+ GPSR(ssp_machinfo->cs_lcdcon) = GPIO_bit(ssp_machinfo->cs_lcdcon); /* High - Disable LCD Control/Timing Gen */
+ GPSR(ssp_machinfo->cs_max1111) = GPIO_bit(ssp_machinfo->cs_max1111); /* High - Disable MAX1111*/
+ GPSR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846); /* High - Disable ADS7846*/
+ ssp_restore_state(&corgi_ssp_dev,&corgi_ssp_state);
+ ssp_enable(&corgi_ssp_dev);
+
return 0;
}
diff --git a/arch/arm/mach-pxa/generic.c b/arch/arm/mach-pxa/generic.c
index 1d7677669a76..9b48a90aefce 100644
--- a/arch/arm/mach-pxa/generic.c
+++ b/arch/arm/mach-pxa/generic.c
@@ -20,9 +20,10 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/delay.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <linux/ioport.h>
#include <linux/pm.h>
+#include <linux/string.h>
#include <asm/hardware.h>
#include <asm/irq.h>
@@ -34,6 +35,7 @@
#include <asm/arch/udc.h>
#include <asm/arch/pxafb.h>
#include <asm/arch/mmc.h>
+#include <asm/arch/irda.h>
#include <asm/arch/i2c.h>
#include "generic.h"
@@ -92,14 +94,42 @@ EXPORT_SYMBOL(pxa_set_cken);
* and cache flush area.
*/
static struct map_desc standard_io_desc[] __initdata = {
- /* virtual physical length type */
- { 0xf2000000, 0x40000000, 0x02000000, MT_DEVICE }, /* Devs */
- { 0xf4000000, 0x44000000, 0x00100000, MT_DEVICE }, /* LCD */
- { 0xf6000000, 0x48000000, 0x00100000, MT_DEVICE }, /* Mem Ctl */
- { 0xf8000000, 0x4c000000, 0x00100000, MT_DEVICE }, /* USB host */
- { 0xfa000000, 0x50000000, 0x00100000, MT_DEVICE }, /* Camera */
- { 0xfe000000, 0x58000000, 0x00100000, MT_DEVICE }, /* IMem ctl */
- { 0xff000000, 0x00000000, 0x00100000, MT_DEVICE } /* UNCACHED_PHYS_0 */
+ { /* Devs */
+ .virtual = 0xf2000000,
+ .pfn = __phys_to_pfn(0x40000000),
+ .length = 0x02000000,
+ .type = MT_DEVICE
+ }, { /* LCD */
+ .virtual = 0xf4000000,
+ .pfn = __phys_to_pfn(0x44000000),
+ .length = 0x00100000,
+ .type = MT_DEVICE
+ }, { /* Mem Ctl */
+ .virtual = 0xf6000000,
+ .pfn = __phys_to_pfn(0x48000000),
+ .length = 0x00100000,
+ .type = MT_DEVICE
+ }, { /* USB host */
+ .virtual = 0xf8000000,
+ .pfn = __phys_to_pfn(0x4c000000),
+ .length = 0x00100000,
+ .type = MT_DEVICE
+ }, { /* Camera */
+ .virtual = 0xfa000000,
+ .pfn = __phys_to_pfn(0x50000000),
+ .length = 0x00100000,
+ .type = MT_DEVICE
+ }, { /* IMem ctl */
+ .virtual = 0xfe000000,
+ .pfn = __phys_to_pfn(0x58000000),
+ .length = 0x00100000,
+ .type = MT_DEVICE
+ }, { /* UNCACHED_PHYS_0 */
+ .virtual = 0xff000000,
+ .pfn = __phys_to_pfn(0x00000000),
+ .length = 0x00100000,
+ .type = MT_DEVICE
+ }
};
void __init pxa_map_io(void)
@@ -225,6 +255,10 @@ static struct platform_device stuart_device = {
.name = "pxa2xx-uart",
.id = 2,
};
+static struct platform_device hwuart_device = {
+ .name = "pxa2xx-uart",
+ .id = 3,
+};
static struct resource i2c_resources[] = {
{
@@ -265,10 +299,26 @@ static struct resource i2s_resources[] = {
static struct platform_device i2s_device = {
.name = "pxa2xx-i2s",
.id = -1,
- .resource = i2c_resources,
+ .resource = i2s_resources,
.num_resources = ARRAY_SIZE(i2s_resources),
};
+static u64 pxaficp_dmamask = ~(u32)0;
+
+static struct platform_device pxaficp_device = {
+ .name = "pxa2xx-ir",
+ .id = -1,
+ .dev = {
+ .dma_mask = &pxaficp_dmamask,
+ .coherent_dma_mask = 0xffffffff,
+ },
+};
+
+void __init pxa_set_ficp_info(struct pxaficp_platform_data *info)
+{
+ pxaficp_device.dev.platform_data = info;
+}
+
static struct platform_device *devices[] __initdata = {
&pxamci_device,
&udc_device,
@@ -276,13 +326,26 @@ static struct platform_device *devices[] __initdata = {
&ffuart_device,
&btuart_device,
&stuart_device,
+ &pxaficp_device,
&i2c_device,
&i2s_device,
};
static int __init pxa_init(void)
{
- return platform_add_devices(devices, ARRAY_SIZE(devices));
+ int cpuid, ret;
+
+ ret = platform_add_devices(devices, ARRAY_SIZE(devices));
+ if (ret)
+ return ret;
+
+ /* Only add HWUART for PXA255/26x; PXA210/250/27x do not have it. */
+ cpuid = read_cpuid(CPUID_ID);
+ if (((cpuid >> 4) & 0xfff) == 0x2d0 ||
+ ((cpuid >> 4) & 0xfff) == 0x290)
+ ret = platform_device_register(&hwuart_device);
+
+ return ret;
}
subsys_initcall(pxa_init);
diff --git a/arch/arm/mach-pxa/idp.c b/arch/arm/mach-pxa/idp.c
index 386e107b53cc..7de159e2ab42 100644
--- a/arch/arm/mach-pxa/idp.c
+++ b/arch/arm/mach-pxa/idp.c
@@ -18,7 +18,7 @@
#include <linux/init.h>
#include <linux/interrupt.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <linux/fb.h>
#include <asm/setup.h>
@@ -152,16 +152,17 @@ static void __init idp_init_irq(void)
}
static struct map_desc idp_io_desc[] __initdata = {
- /* virtual physical length type */
-
- { IDP_COREVOLT_VIRT,
- IDP_COREVOLT_PHYS,
- IDP_COREVOLT_SIZE,
- MT_DEVICE },
- { IDP_CPLD_VIRT,
- IDP_CPLD_PHYS,
- IDP_CPLD_SIZE,
- MT_DEVICE }
+ {
+ .virtual = IDP_COREVOLT_VIRT,
+ .pfn = __phys_to_pfn(IDP_COREVOLT_PHYS),
+ .length = IDP_COREVOLT_SIZE,
+ .type = MT_DEVICE
+ }, {
+ .virtual = IDP_CPLD_VIRT,
+ .pfn = __phys_to_pfn(IDP_CPLD_PHYS),
+ .length = IDP_CPLD_SIZE,
+ .type = MT_DEVICE
+ }
};
static void __init idp_map_io(void)
diff --git a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c
index 1f38033921e9..b464bc88ff93 100644
--- a/arch/arm/mach-pxa/lubbock.c
+++ b/arch/arm/mach-pxa/lubbock.c
@@ -14,27 +14,32 @@
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <linux/sysdev.h>
#include <linux/major.h>
#include <linux/fb.h>
#include <linux/interrupt.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
#include <asm/setup.h>
#include <asm/memory.h>
#include <asm/mach-types.h>
#include <asm/hardware.h>
#include <asm/irq.h>
+#include <asm/sizes.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <asm/mach/irq.h>
+#include <asm/mach/flash.h>
#include <asm/hardware/sa1111.h>
#include <asm/arch/pxa-regs.h>
#include <asm/arch/lubbock.h>
#include <asm/arch/udc.h>
+#include <asm/arch/irda.h>
#include <asm/arch/pxafb.h>
#include <asm/arch/mmc.h>
@@ -174,7 +179,7 @@ static struct platform_device sa1111_device = {
static struct resource smc91x_resources[] = {
[0] = {
.name = "smc91x-regs",
- .start = 0x0c000000,
+ .start = 0x0c000c00,
.end = 0x0c0fffff,
.flags = IORESOURCE_MEM,
},
@@ -198,10 +203,75 @@ static struct platform_device smc91x_device = {
.resource = smc91x_resources,
};
+static struct resource flash_resources[] = {
+ [0] = {
+ .start = 0x00000000,
+ .end = SZ_64M - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 0x04000000,
+ .end = 0x04000000 + SZ_64M - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct mtd_partition lubbock_partitions[] = {
+ {
+ .name = "Bootloader",
+ .size = 0x00040000,
+ .offset = 0,
+ .mask_flags = MTD_WRITEABLE /* force read-only */
+ },{
+ .name = "Kernel",
+ .size = 0x00100000,
+ .offset = 0x00040000,
+ },{
+ .name = "Filesystem",
+ .size = MTDPART_SIZ_FULL,
+ .offset = 0x00140000
+ }
+};
+
+static struct flash_platform_data lubbock_flash_data[2] = {
+ {
+ .map_name = "cfi_probe",
+ .parts = lubbock_partitions,
+ .nr_parts = ARRAY_SIZE(lubbock_partitions),
+ }, {
+ .map_name = "cfi_probe",
+ .parts = NULL,
+ .nr_parts = 0,
+ }
+};
+
+static struct platform_device lubbock_flash_device[2] = {
+ {
+ .name = "pxa2xx-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &lubbock_flash_data[0],
+ },
+ .resource = &flash_resources[0],
+ .num_resources = 1,
+ },
+ {
+ .name = "pxa2xx-flash",
+ .id = 1,
+ .dev = {
+ .platform_data = &lubbock_flash_data[1],
+ },
+ .resource = &flash_resources[1],
+ .num_resources = 1,
+ },
+};
+
static struct platform_device *devices[] __initdata = {
&sa1111_device,
&lub_audio_device,
&smc91x_device,
+ &lubbock_flash_device[0],
+ &lubbock_flash_device[1],
};
static struct pxafb_mach_info sharp_lm8v31 __initdata = {
@@ -223,30 +293,122 @@ static struct pxafb_mach_info sharp_lm8v31 __initdata = {
.lccr3 = LCCR3_PCP | LCCR3_Acb(255),
};
-static int lubbock_mci_init(struct device *dev, irqreturn_t (*lubbock_detect_int)(int, void *, struct pt_regs *), void *data)
+#define MMC_POLL_RATE msecs_to_jiffies(1000)
+
+static void lubbock_mmc_poll(unsigned long);
+static irqreturn_t (*mmc_detect_int)(int, void *, struct pt_regs *);
+
+static struct timer_list mmc_timer = {
+ .function = lubbock_mmc_poll,
+};
+
+static void lubbock_mmc_poll(unsigned long data)
+{
+ unsigned long flags;
+
+ /* clear any previous irq state, then ... */
+ local_irq_save(flags);
+ LUB_IRQ_SET_CLR &= ~(1 << 0);
+ local_irq_restore(flags);
+
+ /* poll until mmc/sd card is removed */
+ if (LUB_IRQ_SET_CLR & (1 << 0))
+ mod_timer(&mmc_timer, jiffies + MMC_POLL_RATE);
+ else {
+ (void) mmc_detect_int(LUBBOCK_SD_IRQ, (void *)data, NULL);
+ enable_irq(LUBBOCK_SD_IRQ);
+ }
+}
+
+static irqreturn_t lubbock_detect_int(int irq, void *data, struct pt_regs *regs)
+{
+ /* IRQ is level triggered; disable, and poll for removal */
+ disable_irq(irq);
+ mod_timer(&mmc_timer, jiffies + MMC_POLL_RATE);
+
+ return mmc_detect_int(irq, data, regs);
+}
+
+static int lubbock_mci_init(struct device *dev,
+ irqreturn_t (*detect_int)(int, void *, struct pt_regs *),
+ void *data)
{
/* setup GPIO for PXA25x MMC controller */
pxa_gpio_mode(GPIO6_MMCCLK_MD);
pxa_gpio_mode(GPIO8_MMCCS0_MD);
- return 0;
+ /* detect card insert/eject */
+ mmc_detect_int = detect_int;
+ init_timer(&mmc_timer);
+ mmc_timer.data = (unsigned long) data;
+ return request_irq(LUBBOCK_SD_IRQ, lubbock_detect_int,
+ SA_SAMPLE_RANDOM, "lubbock-sd-detect", data);
+}
+
+static int lubbock_mci_get_ro(struct device *dev)
+{
+ return (LUB_MISC_RD & (1 << 2)) != 0;
+}
+
+static void lubbock_mci_exit(struct device *dev, void *data)
+{
+ free_irq(LUBBOCK_SD_IRQ, data);
+ del_timer_sync(&mmc_timer);
}
static struct pxamci_platform_data lubbock_mci_platform_data = {
.ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34,
+ .detect_delay = 1,
.init = lubbock_mci_init,
+ .get_ro = lubbock_mci_get_ro,
+ .exit = lubbock_mci_exit,
+};
+
+static void lubbock_irda_transceiver_mode(struct device *dev, int mode)
+{
+ unsigned long flags;
+
+ local_irq_save(flags);
+ if (mode & IR_SIRMODE) {
+ LUB_MISC_WR &= ~(1 << 4);
+ } else if (mode & IR_FIRMODE) {
+ LUB_MISC_WR |= 1 << 4;
+ }
+ local_irq_restore(flags);
+}
+
+static struct pxaficp_platform_data lubbock_ficp_platform_data = {
+ .transceiver_cap = IR_SIRMODE | IR_FIRMODE,
+ .transceiver_mode = lubbock_irda_transceiver_mode,
};
static void __init lubbock_init(void)
{
+ int flashboot = (LUB_CONF_SWITCHES & 1);
+
pxa_set_udc_info(&udc_info);
set_pxa_fb_info(&sharp_lm8v31);
pxa_set_mci_info(&lubbock_mci_platform_data);
+ pxa_set_ficp_info(&lubbock_ficp_platform_data);
+
+ lubbock_flash_data[0].width = lubbock_flash_data[1].width =
+ (BOOT_DEF & 1) ? 2 : 4;
+ /* Compensate for the nROMBT switch which swaps the flash banks */
+ printk(KERN_NOTICE "Lubbock configured to boot from %s (bank %d)\n",
+ flashboot?"Flash":"ROM", flashboot);
+
+ lubbock_flash_data[flashboot^1].name = "application-flash";
+ lubbock_flash_data[flashboot].name = "boot-rom";
(void) platform_add_devices(devices, ARRAY_SIZE(devices));
}
static struct map_desc lubbock_io_desc[] __initdata = {
- { LUBBOCK_FPGA_VIRT, LUBBOCK_FPGA_PHYS, 0x00100000, MT_DEVICE }, /* CPLD */
+ { /* CPLD */
+ .virtual = LUBBOCK_FPGA_VIRT,
+ .pfn = __phys_to_pfn(LUBBOCK_FPGA_PHYS),
+ .length = 0x00100000,
+ .type = MT_DEVICE
+ }
};
static void __init lubbock_map_io(void)
diff --git a/arch/arm/mach-pxa/mainstone.c b/arch/arm/mach-pxa/mainstone.c
index 85fdb5b1470a..07892f4012d8 100644
--- a/arch/arm/mach-pxa/mainstone.c
+++ b/arch/arm/mach-pxa/mainstone.c
@@ -14,12 +14,15 @@
*/
#include <linux/init.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <linux/sysdev.h>
#include <linux/interrupt.h>
#include <linux/sched.h>
#include <linux/bitops.h>
#include <linux/fb.h>
+#include <linux/ioport.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
#include <asm/types.h>
#include <asm/setup.h>
@@ -27,16 +30,19 @@
#include <asm/mach-types.h>
#include <asm/hardware.h>
#include <asm/irq.h>
+#include <asm/sizes.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <asm/mach/irq.h>
+#include <asm/mach/flash.h>
#include <asm/arch/pxa-regs.h>
#include <asm/arch/mainstone.h>
#include <asm/arch/audio.h>
#include <asm/arch/pxafb.h>
#include <asm/arch/mmc.h>
+#include <asm/arch/irda.h>
#include "generic.h"
@@ -189,6 +195,69 @@ static struct platform_device mst_audio_device = {
.dev = { .platform_data = &mst_audio_ops },
};
+static struct resource flash_resources[] = {
+ [0] = {
+ .start = PXA_CS0_PHYS,
+ .end = PXA_CS0_PHYS + SZ_64M - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = PXA_CS1_PHYS,
+ .end = PXA_CS1_PHYS + SZ_64M - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct mtd_partition mainstoneflash0_partitions[] = {
+ {
+ .name = "Bootloader",
+ .size = 0x00040000,
+ .offset = 0,
+ .mask_flags = MTD_WRITEABLE /* force read-only */
+ },{
+ .name = "Kernel",
+ .size = 0x00400000,
+ .offset = 0x00040000,
+ },{
+ .name = "Filesystem",
+ .size = MTDPART_SIZ_FULL,
+ .offset = 0x00440000
+ }
+};
+
+static struct flash_platform_data mst_flash_data[2] = {
+ {
+ .map_name = "cfi_probe",
+ .parts = mainstoneflash0_partitions,
+ .nr_parts = ARRAY_SIZE(mainstoneflash0_partitions),
+ }, {
+ .map_name = "cfi_probe",
+ .parts = NULL,
+ .nr_parts = 0,
+ }
+};
+
+static struct platform_device mst_flash_device[2] = {
+ {
+ .name = "pxa2xx-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &mst_flash_data[0],
+ },
+ .resource = &flash_resources[0],
+ .num_resources = 1,
+ },
+ {
+ .name = "pxa2xx-flash",
+ .id = 1,
+ .dev = {
+ .platform_data = &mst_flash_data[1],
+ },
+ .resource = &flash_resources[1],
+ .num_resources = 1,
+ },
+};
+
static void mainstone_backlight_power(int on)
{
if (on) {
@@ -294,16 +363,57 @@ static struct pxamci_platform_data mainstone_mci_platform_data = {
.exit = mainstone_mci_exit,
};
+static void mainstone_irda_transceiver_mode(struct device *dev, int mode)
+{
+ unsigned long flags;
+
+ local_irq_save(flags);
+ if (mode & IR_SIRMODE) {
+ MST_MSCWR1 &= ~MST_MSCWR1_IRDA_FIR;
+ } else if (mode & IR_FIRMODE) {
+ MST_MSCWR1 |= MST_MSCWR1_IRDA_FIR;
+ }
+ if (mode & IR_OFF) {
+ MST_MSCWR1 = (MST_MSCWR1 & ~MST_MSCWR1_IRDA_MASK) | MST_MSCWR1_IRDA_OFF;
+ } else {
+ MST_MSCWR1 = (MST_MSCWR1 & ~MST_MSCWR1_IRDA_MASK) | MST_MSCWR1_IRDA_FULL;
+ }
+ local_irq_restore(flags);
+}
+
+static struct pxaficp_platform_data mainstone_ficp_platform_data = {
+ .transceiver_cap = IR_SIRMODE | IR_FIRMODE | IR_OFF,
+ .transceiver_mode = mainstone_irda_transceiver_mode,
+};
+
+static struct platform_device *platform_devices[] __initdata = {
+ &smc91x_device,
+ &mst_audio_device,
+ &mst_flash_device[0],
+ &mst_flash_device[1],
+};
+
static void __init mainstone_init(void)
{
+ int SW7 = 0; /* FIXME: get from SCR (Mst doc section 3.2.1.1) */
+
+ mst_flash_data[0].width = (BOOT_DEF & 1) ? 2 : 4;
+ mst_flash_data[1].width = 4;
+
+ /* Compensate for SW7 which swaps the flash banks */
+ mst_flash_data[SW7].name = "processor-flash";
+ mst_flash_data[SW7 ^ 1].name = "mainboard-flash";
+
+ printk(KERN_NOTICE "Mainstone configured to boot from %s\n",
+ mst_flash_data[0].name);
+
/*
* On Mainstone, we route AC97_SYSCLK via GPIO45 to
* the audio daughter card
*/
pxa_gpio_mode(GPIO45_SYSCLK_AC97_MD);
- platform_device_register(&smc91x_device);
- platform_device_register(&mst_audio_device);
+ platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
/* reading Mainstone's "Virtual Configuration Register"
might be handy to select LCD type here */
@@ -313,11 +423,17 @@ static void __init mainstone_init(void)
set_pxa_fb_info(&toshiba_ltm035a776c);
pxa_set_mci_info(&mainstone_mci_platform_data);
+ pxa_set_ficp_info(&mainstone_ficp_platform_data);
}
static struct map_desc mainstone_io_desc[] __initdata = {
- { MST_FPGA_VIRT, MST_FPGA_PHYS, 0x00100000, MT_DEVICE }, /* CPLD */
+ { /* CPLD */
+ .virtual = MST_FPGA_VIRT,
+ .pfn = __phys_to_pfn(MST_FPGA_PHYS),
+ .length = 0x00100000,
+ .type = MT_DEVICE
+ }
};
static void __init mainstone_map_io(void)
diff --git a/arch/arm/mach-pxa/pm.c b/arch/arm/mach-pxa/pm.c
index ac4dd4336160..f74b9af112dc 100644
--- a/arch/arm/mach-pxa/pm.c
+++ b/arch/arm/mach-pxa/pm.c
@@ -12,6 +12,7 @@
*/
#include <linux/config.h>
#include <linux/init.h>
+#include <linux/module.h>
#include <linux/suspend.h>
#include <linux/errno.h>
#include <linux/time.h>
@@ -19,6 +20,7 @@
#include <asm/hardware.h>
#include <asm/memory.h>
#include <asm/system.h>
+#include <asm/arch/pm.h>
#include <asm/arch/pxa-regs.h>
#include <asm/arch/lubbock.h>
#include <asm/mach/time.h>
@@ -72,7 +74,7 @@ enum { SLEEP_SAVE_START = 0,
};
-static int pxa_pm_enter(suspend_state_t state)
+int pxa_pm_enter(suspend_state_t state)
{
unsigned long sleep_save[SLEEP_SAVE_SIZE];
unsigned long checksum = 0;
@@ -191,6 +193,8 @@ static int pxa_pm_enter(suspend_state_t state)
return 0;
}
+EXPORT_SYMBOL_GPL(pxa_pm_enter);
+
unsigned long sleep_phys_sp(void *sp)
{
return virt_to_phys(sp);
@@ -199,21 +203,25 @@ unsigned long sleep_phys_sp(void *sp)
/*
* Called after processes are frozen, but before we shut down devices.
*/
-static int pxa_pm_prepare(suspend_state_t state)
+int pxa_pm_prepare(suspend_state_t state)
{
extern int pxa_cpu_pm_prepare(suspend_state_t state);
return pxa_cpu_pm_prepare(state);
}
+EXPORT_SYMBOL_GPL(pxa_pm_prepare);
+
/*
* Called after devices are re-setup, but before processes are thawed.
*/
-static int pxa_pm_finish(suspend_state_t state)
+int pxa_pm_finish(suspend_state_t state)
{
return 0;
}
+EXPORT_SYMBOL_GPL(pxa_pm_finish);
+
/*
* Set to PM_DISK_FIRMWARE so we can quickly veto suspend-to-disk.
*/
@@ -230,4 +238,4 @@ static int __init pxa_pm_init(void)
return 0;
}
-late_initcall(pxa_pm_init);
+device_initcall(pxa_pm_init);
diff --git a/arch/arm/mach-pxa/poodle.c b/arch/arm/mach-pxa/poodle.c
index f25638810017..eef3de26ad37 100644
--- a/arch/arm/mach-pxa/poodle.c
+++ b/arch/arm/mach-pxa/poodle.c
@@ -16,7 +16,7 @@
*/
#include <linux/kernel.h>
#include <linux/init.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <linux/fb.h>
#include <asm/hardware.h>
@@ -32,6 +32,7 @@
#include <asm/arch/irq.h>
#include <asm/arch/mmc.h>
#include <asm/arch/udc.h>
+#include <asm/arch/irda.h>
#include <asm/arch/poodle.h>
#include <asm/arch/pxafb.h>
@@ -64,6 +65,27 @@ struct platform_device poodle_scoop_device = {
.resource = poodle_scoop_resources,
};
+static void poodle_pcmcia_init(void)
+{
+ /* Setup default state of GPIO outputs
+ before we enable them as outputs. */
+ GPSR(GPIO48_nPOE) = GPIO_bit(GPIO48_nPOE) |
+ GPIO_bit(GPIO49_nPWE) | GPIO_bit(GPIO50_nPIOR) |
+ GPIO_bit(GPIO51_nPIOW) | GPIO_bit(GPIO52_nPCE_1) |
+ GPIO_bit(GPIO53_nPCE_2);
+
+ pxa_gpio_mode(GPIO48_nPOE_MD);
+ pxa_gpio_mode(GPIO49_nPWE_MD);
+ pxa_gpio_mode(GPIO50_nPIOR_MD);
+ pxa_gpio_mode(GPIO51_nPIOW_MD);
+ pxa_gpio_mode(GPIO55_nPREG_MD);
+ pxa_gpio_mode(GPIO56_nPWAIT_MD);
+ pxa_gpio_mode(GPIO57_nIOIS16_MD);
+ pxa_gpio_mode(GPIO52_nPCE_1_MD);
+ pxa_gpio_mode(GPIO53_nPCE_2_MD);
+ pxa_gpio_mode(GPIO54_pSKTSEL_MD);
+}
+
static struct scoop_pcmcia_dev poodle_pcmcia_scoop[] = {
{
.dev = &poodle_scoop_device.dev,
@@ -73,6 +95,14 @@ static struct scoop_pcmcia_dev poodle_pcmcia_scoop[] = {
},
};
+static struct scoop_pcmcia_config poodle_pcmcia_config = {
+ .devs = &poodle_pcmcia_scoop[0],
+ .num_devs = 1,
+ .pcmcia_init = poodle_pcmcia_init,
+};
+
+EXPORT_SYMBOL(poodle_scoop_device);
+
/* LoCoMo device */
static struct resource locomo_resources[] = {
@@ -152,6 +182,24 @@ static struct pxamci_platform_data poodle_mci_platform_data = {
/*
+ * Irda
+ */
+static void poodle_irda_transceiver_mode(struct device *dev, int mode)
+{
+ if (mode & IR_OFF) {
+ GPSR(POODLE_GPIO_IR_ON) = GPIO_bit(POODLE_GPIO_IR_ON);
+ } else {
+ GPCR(POODLE_GPIO_IR_ON) = GPIO_bit(POODLE_GPIO_IR_ON);
+ }
+}
+
+static struct pxaficp_platform_data poodle_ficp_platform_data = {
+ .transceiver_cap = IR_SIRMODE | IR_OFF,
+ .transceiver_mode = poodle_irda_transceiver_mode,
+};
+
+
+/*
* USB Device Controller
*/
static void poodle_udc_command(int cmd)
@@ -244,11 +292,12 @@ static void __init poodle_init(void)
set_pxa_fb_info(&poodle_fb_info);
pxa_gpio_mode(POODLE_GPIO_USB_PULLUP | GPIO_OUT);
+ pxa_gpio_mode(POODLE_GPIO_IR_ON | GPIO_OUT);
pxa_set_udc_info(&udc_info);
pxa_set_mci_info(&poodle_mci_platform_data);
+ pxa_set_ficp_info(&poodle_ficp_platform_data);
- scoop_num = 1;
- scoop_devs = &poodle_pcmcia_scoop[0];
+ platform_scoop_config = &poodle_pcmcia_config;
ret = platform_add_devices(devices, ARRAY_SIZE(devices));
if (ret) {
diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c
index 7869c3b4e62f..573a5758e781 100644
--- a/arch/arm/mach-pxa/pxa25x.c
+++ b/arch/arm/mach-pxa/pxa25x.c
@@ -129,7 +129,7 @@ void pxa_cpu_pm_enter(suspend_state_t state)
case PM_SUSPEND_MEM:
/* set resume return address */
PSPR = virt_to_phys(pxa_cpu_resume);
- pxa_cpu_suspend(3);
+ pxa_cpu_suspend(PWRMODE_SLEEP);
break;
}
}
diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c
index 9a791b07118d..c722a9a91fcc 100644
--- a/arch/arm/mach-pxa/pxa27x.c
+++ b/arch/arm/mach-pxa/pxa27x.c
@@ -16,7 +16,7 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/pm.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <asm/hardware.h>
#include <asm/irq.h>
@@ -157,7 +157,7 @@ void pxa_cpu_pm_enter(suspend_state_t state)
case PM_SUSPEND_MEM:
/* set resume return address */
PSPR = virt_to_phys(pxa_cpu_resume);
- pxa_cpu_suspend(3);
+ pxa_cpu_suspend(PWRMODE_SLEEP);
break;
}
}
diff --git a/arch/arm/mach-pxa/sharpsl.h b/arch/arm/mach-pxa/sharpsl.h
index 3977a77aacdd..4879c0f7da72 100644
--- a/arch/arm/mach-pxa/sharpsl.h
+++ b/arch/arm/mach-pxa/sharpsl.h
@@ -32,3 +32,90 @@ void corgi_put_hsync(void);
void spitz_put_hsync(void);
void corgi_wait_hsync(void);
void spitz_wait_hsync(void);
+
+/*
+ * SharpSL Battery/PM Driver
+ */
+
+struct sharpsl_charger_machinfo {
+ void (*init)(void);
+ int gpio_acin;
+ int gpio_batfull;
+ int gpio_batlock;
+ int gpio_fatal;
+ int (*status_acin)(void);
+ void (*discharge)(int);
+ void (*discharge1)(int);
+ void (*charge)(int);
+ void (*chargeled)(int);
+ void (*measure_temp)(int);
+ void (*presuspend)(void);
+ void (*postsuspend)(void);
+ unsigned long (*charger_wakeup)(void);
+ int (*should_wakeup)(unsigned int resume_on_alarm);
+ int bat_levels;
+ struct battery_thresh *bat_levels_noac;
+ struct battery_thresh *bat_levels_acin;
+ int status_high_acin;
+ int status_low_acin;
+ int status_high_noac;
+ int status_low_noac;
+};
+
+struct battery_thresh {
+ int voltage;
+ int percentage;
+};
+
+struct battery_stat {
+ int ac_status; /* APM AC Present/Not Present */
+ int mainbat_status; /* APM Main Battery Status */
+ int mainbat_percent; /* Main Battery Percentage Charge */
+ int mainbat_voltage; /* Main Battery Voltage */
+};
+
+struct sharpsl_pm_status {
+ struct device *dev;
+ struct timer_list ac_timer;
+ struct timer_list chrg_full_timer;
+
+ int charge_mode;
+#define CHRG_ERROR (-1)
+#define CHRG_OFF (0)
+#define CHRG_ON (1)
+#define CHRG_DONE (2)
+
+ unsigned int flags;
+#define SHARPSL_SUSPENDED (1 << 0) /* Device is Suspended */
+#define SHARPSL_ALARM_ACTIVE (1 << 1) /* Alarm is for charging event (not user) */
+#define SHARPSL_BL_LIMIT (1 << 2) /* Backlight Intensity Limited */
+#define SHARPSL_APM_QUEUED (1 << 3) /* APM Event Queued */
+#define SHARPSL_DO_OFFLINE_CHRG (1 << 4) /* Trigger the offline charger */
+
+ int full_count;
+ unsigned long charge_start_time;
+ struct sharpsl_charger_machinfo *machinfo;
+ struct battery_stat battstat;
+};
+
+extern struct sharpsl_pm_status sharpsl_pm;
+extern struct battery_thresh spitz_battery_levels_acin[];
+extern struct battery_thresh spitz_battery_levels_noac[];
+
+#define READ_GPIO_BIT(x) (GPLR(x) & GPIO_bit(x))
+
+#define SHARPSL_LED_ERROR 2
+#define SHARPSL_LED_ON 1
+#define SHARPSL_LED_OFF 0
+
+#define CHARGE_ON() sharpsl_pm.machinfo->charge(1)
+#define CHARGE_OFF() sharpsl_pm.machinfo->charge(0)
+#define CHARGE_LED_ON() sharpsl_pm.machinfo->chargeled(SHARPSL_LED_ON)
+#define CHARGE_LED_OFF() sharpsl_pm.machinfo->chargeled(SHARPSL_LED_OFF)
+#define CHARGE_LED_ERR() sharpsl_pm.machinfo->chargeled(SHARPSL_LED_ERROR)
+#define DISCHARGE_ON() sharpsl_pm.machinfo->discharge(1)
+#define DISCHARGE_OFF() sharpsl_pm.machinfo->discharge(0)
+#define STATUS_AC_IN sharpsl_pm.machinfo->status_acin()
+#define STATUS_BATT_LOCKED READ_GPIO_BIT(sharpsl_pm.machinfo->gpio_batlock)
+#define STATUS_CHRG_FULL READ_GPIO_BIT(sharpsl_pm.machinfo->gpio_batfull)
+#define STATUS_FATAL READ_GPIO_BIT(sharpsl_pm.machinfo->gpio_fatal)
diff --git a/arch/arm/mach-pxa/sharpsl_pm.c b/arch/arm/mach-pxa/sharpsl_pm.c
new file mode 100644
index 000000000000..6c9e871c53d8
--- /dev/null
+++ b/arch/arm/mach-pxa/sharpsl_pm.c
@@ -0,0 +1,992 @@
+/*
+ * Battery and Power Management code for the Sharp SL-C7xx and SL-Cxx00
+ * series of PDAs
+ *
+ * Copyright (c) 2004-2005 Richard Purdie
+ *
+ * Based on code written by Sharp for 2.4 kernels
+ *
+ * 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.
+ *
+ */
+
+#undef DEBUG
+
+#include <linux/module.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/apm_bios.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/device.h>
+
+#include <asm/hardware.h>
+#include <asm/hardware/scoop.h>
+#include <asm/mach-types.h>
+#include <asm/irq.h>
+#include <asm/apm.h>
+
+#include <asm/arch/pm.h>
+#include <asm/arch/pxa-regs.h>
+#include <asm/arch/sharpsl.h>
+#include "sharpsl.h"
+
+/*
+ * Constants
+ */
+#define SHARPSL_CHARGE_ON_TIME_INTERVAL (msecs_to_jiffies(1*60*1000)) /* 1 min */
+#define SHARPSL_CHARGE_FINISH_TIME (msecs_to_jiffies(10*60*1000)) /* 10 min */
+#define SHARPSL_BATCHK_TIME (msecs_to_jiffies(15*1000)) /* 15 sec */
+#define SHARPSL_BATCHK_TIME_SUSPEND (60*10) /* 10 min */
+#define SHARPSL_WAIT_CO_TIME 15 /* 15 sec */
+#define SHARPSL_WAIT_DISCHARGE_ON 100 /* 100 msec */
+#define SHARPSL_CHECK_BATTERY_WAIT_TIME_TEMP 10 /* 10 msec */
+#define SHARPSL_CHECK_BATTERY_WAIT_TIME_VOLT 10 /* 10 msec */
+#define SHARPSL_CHECK_BATTERY_WAIT_TIME_JKVAD 10 /* 10 msec */
+#define SHARPSL_CHARGE_WAIT_TIME 15 /* 15 msec */
+#define SHARPSL_CHARGE_CO_CHECK_TIME 5 /* 5 msec */
+#define SHARPSL_CHARGE_RETRY_CNT 1 /* eqv. 10 min */
+
+#define SHARPSL_CHARGE_ON_VOLT 0x99 /* 2.9V */
+#define SHARPSL_CHARGE_ON_TEMP 0xe0 /* 2.9V */
+#define SHARPSL_CHARGE_ON_JKVAD_HIGH 0x9b /* 6V */
+#define SHARPSL_CHARGE_ON_JKVAD_LOW 0x34 /* 2V */
+#define SHARPSL_FATAL_ACIN_VOLT 182 /* 3.45V */
+#define SHARPSL_FATAL_NOACIN_VOLT 170 /* 3.40V */
+
+struct battery_thresh spitz_battery_levels_acin[] = {
+ { 213, 100},
+ { 212, 98},
+ { 211, 95},
+ { 210, 93},
+ { 209, 90},
+ { 208, 88},
+ { 207, 85},
+ { 206, 83},
+ { 205, 80},
+ { 204, 78},
+ { 203, 75},
+ { 202, 73},
+ { 201, 70},
+ { 200, 68},
+ { 199, 65},
+ { 198, 63},
+ { 197, 60},
+ { 196, 58},
+ { 195, 55},
+ { 194, 53},
+ { 193, 50},
+ { 192, 48},
+ { 192, 45},
+ { 191, 43},
+ { 191, 40},
+ { 190, 38},
+ { 190, 35},
+ { 189, 33},
+ { 188, 30},
+ { 187, 28},
+ { 186, 25},
+ { 185, 23},
+ { 184, 20},
+ { 183, 18},
+ { 182, 15},
+ { 181, 13},
+ { 180, 10},
+ { 179, 8},
+ { 178, 5},
+ { 0, 0},
+};
+
+struct battery_thresh spitz_battery_levels_noac[] = {
+ { 213, 100},
+ { 212, 98},
+ { 211, 95},
+ { 210, 93},
+ { 209, 90},
+ { 208, 88},
+ { 207, 85},
+ { 206, 83},
+ { 205, 80},
+ { 204, 78},
+ { 203, 75},
+ { 202, 73},
+ { 201, 70},
+ { 200, 68},
+ { 199, 65},
+ { 198, 63},
+ { 197, 60},
+ { 196, 58},
+ { 195, 55},
+ { 194, 53},
+ { 193, 50},
+ { 192, 48},
+ { 191, 45},
+ { 190, 43},
+ { 189, 40},
+ { 188, 38},
+ { 187, 35},
+ { 186, 33},
+ { 185, 30},
+ { 184, 28},
+ { 183, 25},
+ { 182, 23},
+ { 181, 20},
+ { 180, 18},
+ { 179, 15},
+ { 178, 13},
+ { 177, 10},
+ { 176, 8},
+ { 175, 5},
+ { 0, 0},
+};
+
+/* MAX1111 Commands */
+#define MAXCTRL_PD0 1u << 0
+#define MAXCTRL_PD1 1u << 1
+#define MAXCTRL_SGL 1u << 2
+#define MAXCTRL_UNI 1u << 3
+#define MAXCTRL_SEL_SH 4
+#define MAXCTRL_STR 1u << 7
+
+/* MAX1111 Channel Definitions */
+#define BATT_AD 4u
+#define BATT_THM 2u
+#define JK_VAD 6u
+
+
+/*
+ * Prototypes
+ */
+static int sharpsl_read_MainBattery(void);
+static int sharpsl_off_charge_battery(void);
+static int sharpsl_check_battery(int mode);
+static int sharpsl_ac_check(void);
+static int sharpsl_fatal_check(void);
+static int sharpsl_average_value(int ad);
+static void sharpsl_average_clear(void);
+static void sharpsl_charge_toggle(void *private_);
+static void sharpsl_battery_thread(void *private_);
+
+
+/*
+ * Variables
+ */
+struct sharpsl_pm_status sharpsl_pm;
+DECLARE_WORK(toggle_charger, sharpsl_charge_toggle, NULL);
+DECLARE_WORK(sharpsl_bat, sharpsl_battery_thread, NULL);
+
+
+static int get_percentage(int voltage)
+{
+ int i = sharpsl_pm.machinfo->bat_levels - 1;
+ struct battery_thresh *thresh;
+
+ if (sharpsl_pm.charge_mode == CHRG_ON)
+ thresh=sharpsl_pm.machinfo->bat_levels_acin;
+ else
+ thresh=sharpsl_pm.machinfo->bat_levels_noac;
+
+ while (i > 0 && (voltage > thresh[i].voltage))
+ i--;
+
+ return thresh[i].percentage;
+}
+
+static int get_apm_status(int voltage)
+{
+ int low_thresh, high_thresh;
+
+ if (sharpsl_pm.charge_mode == CHRG_ON) {
+ high_thresh = sharpsl_pm.machinfo->status_high_acin;
+ low_thresh = sharpsl_pm.machinfo->status_low_acin;
+ } else {
+ high_thresh = sharpsl_pm.machinfo->status_high_noac;
+ low_thresh = sharpsl_pm.machinfo->status_low_noac;
+ }
+
+ if (voltage >= high_thresh)
+ return APM_BATTERY_STATUS_HIGH;
+ if (voltage >= low_thresh)
+ return APM_BATTERY_STATUS_LOW;
+ return APM_BATTERY_STATUS_CRITICAL;
+}
+
+void sharpsl_battery_kick(void)
+{
+ schedule_delayed_work(&sharpsl_bat, msecs_to_jiffies(125));
+}
+EXPORT_SYMBOL(sharpsl_battery_kick);
+
+
+static void sharpsl_battery_thread(void *private_)
+{
+ int voltage, percent, apm_status, i = 0;
+
+ if (!sharpsl_pm.machinfo)
+ return;
+
+ sharpsl_pm.battstat.ac_status = (!(STATUS_AC_IN) ? APM_AC_OFFLINE : APM_AC_ONLINE);
+
+ /* Corgi cannot confirm when battery fully charged so periodically kick! */
+ if (machine_is_corgi() && (sharpsl_pm.charge_mode == CHRG_ON)
+ && time_after(jiffies, sharpsl_pm.charge_start_time + SHARPSL_CHARGE_ON_TIME_INTERVAL))
+ schedule_work(&toggle_charger);
+
+ while(1) {
+ voltage = sharpsl_read_MainBattery();
+ if (voltage > 0) break;
+ if (i++ > 5) {
+ voltage = sharpsl_pm.machinfo->bat_levels_noac[0].voltage;
+ dev_warn(sharpsl_pm.dev, "Warning: Cannot read main battery!\n");
+ break;
+ }
+ }
+
+ voltage = sharpsl_average_value(voltage);
+ apm_status = get_apm_status(voltage);
+ percent = get_percentage(voltage);
+
+ /* At low battery voltages, the voltage has a tendency to start
+ creeping back up so we try to avoid this here */
+ if ((sharpsl_pm.battstat.ac_status == APM_AC_ONLINE) || (apm_status == APM_BATTERY_STATUS_HIGH) || percent <= sharpsl_pm.battstat.mainbat_percent) {
+ sharpsl_pm.battstat.mainbat_voltage = voltage;
+ sharpsl_pm.battstat.mainbat_status = apm_status;
+ sharpsl_pm.battstat.mainbat_percent = percent;
+ }
+
+ dev_dbg(sharpsl_pm.dev, "Battery: voltage: %d, status: %d, percentage: %d, time: %d\n", voltage,
+ sharpsl_pm.battstat.mainbat_status, sharpsl_pm.battstat.mainbat_percent, jiffies);
+
+ /* If battery is low. limit backlight intensity to save power. */
+ if ((sharpsl_pm.battstat.ac_status != APM_AC_ONLINE)
+ && ((sharpsl_pm.battstat.mainbat_status == APM_BATTERY_STATUS_LOW) ||
+ (sharpsl_pm.battstat.mainbat_status == APM_BATTERY_STATUS_CRITICAL))) {
+ if (!(sharpsl_pm.flags & SHARPSL_BL_LIMIT)) {
+ corgibl_limit_intensity(1);
+ sharpsl_pm.flags |= SHARPSL_BL_LIMIT;
+ }
+ } else if (sharpsl_pm.flags & SHARPSL_BL_LIMIT) {
+ corgibl_limit_intensity(0);
+ sharpsl_pm.flags &= ~SHARPSL_BL_LIMIT;
+ }
+
+ /* Suspend if critical battery level */
+ if ((sharpsl_pm.battstat.ac_status != APM_AC_ONLINE)
+ && (sharpsl_pm.battstat.mainbat_status == APM_BATTERY_STATUS_CRITICAL)
+ && !(sharpsl_pm.flags & SHARPSL_APM_QUEUED)) {
+ sharpsl_pm.flags |= SHARPSL_APM_QUEUED;
+ dev_err(sharpsl_pm.dev, "Fatal Off\n");
+ apm_queue_event(APM_CRITICAL_SUSPEND);
+ }
+
+ schedule_delayed_work(&sharpsl_bat, SHARPSL_BATCHK_TIME);
+}
+
+static void sharpsl_charge_on(void)
+{
+ dev_dbg(sharpsl_pm.dev, "Turning Charger On\n");
+
+ sharpsl_pm.full_count = 0;
+ sharpsl_pm.charge_mode = CHRG_ON;
+ schedule_delayed_work(&toggle_charger, msecs_to_jiffies(250));
+ schedule_delayed_work(&sharpsl_bat, msecs_to_jiffies(500));
+}
+
+static void sharpsl_charge_off(void)
+{
+ dev_dbg(sharpsl_pm.dev, "Turning Charger Off\n");
+
+ CHARGE_OFF();
+ CHARGE_LED_OFF();
+ sharpsl_pm.charge_mode = CHRG_OFF;
+
+ schedule_work(&sharpsl_bat);
+}
+
+static void sharpsl_charge_error(void)
+{
+ CHARGE_LED_ERR();
+ CHARGE_OFF();
+ sharpsl_pm.charge_mode = CHRG_ERROR;
+}
+
+static void sharpsl_charge_toggle(void *private_)
+{
+ dev_dbg(sharpsl_pm.dev, "Toogling Charger at time: %lx\n", jiffies);
+
+ if (STATUS_AC_IN == 0) {
+ sharpsl_charge_off();
+ return;
+ } else if ((sharpsl_check_battery(1) < 0) || (sharpsl_ac_check() < 0)) {
+ sharpsl_charge_error();
+ return;
+ }
+
+ CHARGE_LED_ON();
+ CHARGE_OFF();
+ mdelay(SHARPSL_CHARGE_WAIT_TIME);
+ CHARGE_ON();
+
+ sharpsl_pm.charge_start_time = jiffies;
+}
+
+static void sharpsl_ac_timer(unsigned long data)
+{
+ int acin = STATUS_AC_IN;
+
+ dev_dbg(sharpsl_pm.dev, "AC Status: %d\n",acin);
+
+ sharpsl_average_clear();
+ if (acin && (sharpsl_pm.charge_mode != CHRG_ON))
+ sharpsl_charge_on();
+ else if (sharpsl_pm.charge_mode == CHRG_ON)
+ sharpsl_charge_off();
+
+ schedule_work(&sharpsl_bat);
+}
+
+
+static irqreturn_t sharpsl_ac_isr(int irq, void *dev_id, struct pt_regs *fp)
+{
+ /* Delay the event slightly to debounce */
+ /* Must be a smaller delay than the chrg_full_isr below */
+ mod_timer(&sharpsl_pm.ac_timer, jiffies + msecs_to_jiffies(250));
+
+ return IRQ_HANDLED;
+}
+
+static void sharpsl_chrg_full_timer(unsigned long data)
+{
+ dev_dbg(sharpsl_pm.dev, "Charge Full at time: %lx\n", jiffies);
+
+ sharpsl_pm.full_count++;
+
+ if (STATUS_AC_IN == 0) {
+ dev_dbg(sharpsl_pm.dev, "Charge Full: AC removed - stop charging!\n");
+ if (sharpsl_pm.charge_mode == CHRG_ON)
+ sharpsl_charge_off();
+ } else if (sharpsl_pm.full_count < 2) {
+ dev_dbg(sharpsl_pm.dev, "Charge Full: Count too low\n");
+ schedule_work(&toggle_charger);
+ } else if (time_after(jiffies, sharpsl_pm.charge_start_time + SHARPSL_CHARGE_FINISH_TIME)) {
+ dev_dbg(sharpsl_pm.dev, "Charge Full: Interrupt generated too slowly - retry.\n");
+ schedule_work(&toggle_charger);
+ } else {
+ sharpsl_charge_off();
+ sharpsl_pm.charge_mode = CHRG_DONE;
+ dev_dbg(sharpsl_pm.dev, "Charge Full: Charging Finished\n");
+ }
+}
+
+/* Charging Finished Interrupt (Not present on Corgi) */
+/* Can trigger at the same time as an AC staus change so
+ delay until after that has been processed */
+static irqreturn_t sharpsl_chrg_full_isr(int irq, void *dev_id, struct pt_regs *fp)
+{
+ if (sharpsl_pm.flags & SHARPSL_SUSPENDED)
+ return IRQ_HANDLED;
+
+ /* delay until after any ac interrupt */
+ mod_timer(&sharpsl_pm.chrg_full_timer, jiffies + msecs_to_jiffies(500));
+
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t sharpsl_fatal_isr(int irq, void *dev_id, struct pt_regs *fp)
+{
+ int is_fatal = 0;
+
+ if (STATUS_BATT_LOCKED == 0) {
+ dev_err(sharpsl_pm.dev, "Battery now Unlocked! Suspending.\n");
+ is_fatal = 1;
+ }
+
+ if (sharpsl_pm.machinfo->gpio_fatal && (STATUS_FATAL == 0)) {
+ dev_err(sharpsl_pm.dev, "Fatal Batt Error! Suspending.\n");
+ is_fatal = 1;
+ }
+
+ if (!(sharpsl_pm.flags & SHARPSL_APM_QUEUED) && is_fatal) {
+ sharpsl_pm.flags |= SHARPSL_APM_QUEUED;
+ apm_queue_event(APM_CRITICAL_SUSPEND);
+ }
+
+ return IRQ_HANDLED;
+}
+
+/*
+ * Maintain an average of the last 10 readings
+ */
+#define SHARPSL_CNV_VALUE_NUM 10
+static int sharpsl_ad_index;
+
+static void sharpsl_average_clear(void)
+{
+ sharpsl_ad_index = 0;
+}
+
+static int sharpsl_average_value(int ad)
+{
+ int i, ad_val = 0;
+ static int sharpsl_ad[SHARPSL_CNV_VALUE_NUM+1];
+
+ if (sharpsl_pm.battstat.mainbat_status != APM_BATTERY_STATUS_HIGH) {
+ sharpsl_ad_index = 0;
+ return ad;
+ }
+
+ sharpsl_ad[sharpsl_ad_index] = ad;
+ sharpsl_ad_index++;
+ if (sharpsl_ad_index >= SHARPSL_CNV_VALUE_NUM) {
+ for (i=0; i < (SHARPSL_CNV_VALUE_NUM-1); i++)
+ sharpsl_ad[i] = sharpsl_ad[i+1];
+ sharpsl_ad_index = SHARPSL_CNV_VALUE_NUM - 1;
+ }
+ for (i=0; i < sharpsl_ad_index; i++)
+ ad_val += sharpsl_ad[i];
+
+ return (ad_val / sharpsl_ad_index);
+}
+
+
+/*
+ * Read MAX1111 ADC
+ */
+static int read_max1111(int channel)
+{
+ return corgi_ssp_max1111_get((channel << MAXCTRL_SEL_SH) | MAXCTRL_PD0 | MAXCTRL_PD1
+ | MAXCTRL_SGL | MAXCTRL_UNI | MAXCTRL_STR);
+}
+
+static int sharpsl_read_MainBattery(void)
+{
+ return read_max1111(BATT_AD);
+}
+
+static int sharpsl_read_Temp(void)
+{
+ int temp;
+
+ sharpsl_pm.machinfo->measure_temp(1);
+
+ mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_TEMP);
+ temp = read_max1111(BATT_THM);
+
+ sharpsl_pm.machinfo->measure_temp(0);
+
+ return temp;
+}
+
+static int sharpsl_read_jkvad(void)
+{
+ return read_max1111(JK_VAD);
+}
+
+/*
+ * Take an array of 5 integers, remove the maximum and minimum values
+ * and return the average.
+ */
+static int get_select_val(int *val)
+{
+ int i, j, k, temp, sum = 0;
+
+ /* Find MAX val */
+ temp = val[0];
+ j=0;
+ for (i=1; i<5; i++) {
+ if (temp < val[i]) {
+ temp = val[i];
+ j = i;
+ }
+ }
+
+ /* Find MIN val */
+ temp = val[4];
+ k=4;
+ for (i=3; i>=0; i--) {
+ if (temp > val[i]) {
+ temp = val[i];
+ k = i;
+ }
+ }
+
+ for (i=0; i<5; i++)
+ if (i != j && i != k )
+ sum += val[i];
+
+ dev_dbg(sharpsl_pm.dev, "Average: %d from values: %d, %d, %d, %d, %d\n", sum/3, val[0], val[1], val[2], val[3], val[4]);
+
+ return (sum/3);
+}
+
+/* mode 0 - Check temperature and voltage
+ * 1 - Check temperature only */
+static int sharpsl_check_battery(int mode)
+{
+ int val, i, buff[5];
+
+ /* Check battery temperature */
+ for (i=0; i<5; i++) {
+ mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_TEMP);
+ buff[i] = sharpsl_read_Temp();
+ }
+
+ val = get_select_val(buff);
+
+ dev_dbg(sharpsl_pm.dev, "Temperature: %d\n", val);
+ if (val > SHARPSL_CHARGE_ON_TEMP)
+ return -1;
+ if (mode == 1)
+ return 0;
+
+ /* disable charge, enable discharge */
+ CHARGE_OFF();
+ DISCHARGE_ON();
+ mdelay(SHARPSL_WAIT_DISCHARGE_ON);
+
+ if (sharpsl_pm.machinfo->discharge1)
+ sharpsl_pm.machinfo->discharge1(1);
+
+ /* Check battery voltage */
+ for (i=0; i<5; i++) {
+ buff[i] = sharpsl_read_MainBattery();
+ mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_VOLT);
+ }
+
+ if (sharpsl_pm.machinfo->discharge1)
+ sharpsl_pm.machinfo->discharge1(0);
+
+ DISCHARGE_OFF();
+
+ val = get_select_val(buff);
+ dev_dbg(sharpsl_pm.dev, "Battery Voltage: %d\n", val);
+
+ if (val < SHARPSL_CHARGE_ON_VOLT)
+ return -1;
+
+ return 0;
+}
+
+static int sharpsl_ac_check(void)
+{
+ int temp, i, buff[5];
+
+ for (i=0; i<5; i++) {
+ buff[i] = sharpsl_read_jkvad();
+ mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_JKVAD);
+ }
+
+ temp = get_select_val(buff);
+ dev_dbg(sharpsl_pm.dev, "AC Voltage: %d\n",temp);
+
+ if ((temp > SHARPSL_CHARGE_ON_JKVAD_HIGH) || (temp < SHARPSL_CHARGE_ON_JKVAD_LOW)) {
+ dev_err(sharpsl_pm.dev, "Error: AC check failed.\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int sharpsl_pm_suspend(struct device *dev, pm_message_t state)
+{
+ sharpsl_pm.flags |= SHARPSL_SUSPENDED;
+ flush_scheduled_work();
+
+ if (sharpsl_pm.charge_mode == CHRG_ON)
+ sharpsl_pm.flags |= SHARPSL_DO_OFFLINE_CHRG;
+ else
+ sharpsl_pm.flags &= ~SHARPSL_DO_OFFLINE_CHRG;
+
+ return 0;
+}
+
+static int sharpsl_pm_resume(struct device *dev)
+{
+ /* Clear the reset source indicators as they break the bootloader upon reboot */
+ RCSR = 0x0f;
+ sharpsl_average_clear();
+ sharpsl_pm.flags &= ~SHARPSL_APM_QUEUED;
+ sharpsl_pm.flags &= ~SHARPSL_SUSPENDED;
+
+ return 0;
+}
+
+static void corgi_goto_sleep(unsigned long alarm_time, unsigned int alarm_enable, suspend_state_t state)
+{
+ dev_dbg(sharpsl_pm.dev, "Time is: %08x\n",RCNR);
+
+ dev_dbg(sharpsl_pm.dev, "Offline Charge Activate = %d\n",sharpsl_pm.flags & SHARPSL_DO_OFFLINE_CHRG);
+ /* not charging and AC-IN! */
+
+ if ((sharpsl_pm.flags & SHARPSL_DO_OFFLINE_CHRG) && (STATUS_AC_IN != 0)) {
+ dev_dbg(sharpsl_pm.dev, "Activating Offline Charger...\n");
+ sharpsl_pm.charge_mode = CHRG_OFF;
+ sharpsl_pm.flags &= ~SHARPSL_DO_OFFLINE_CHRG;
+ sharpsl_off_charge_battery();
+ }
+
+ sharpsl_pm.machinfo->presuspend();
+
+ PEDR = 0xffffffff; /* clear it */
+
+ sharpsl_pm.flags &= ~SHARPSL_ALARM_ACTIVE;
+ if ((sharpsl_pm.charge_mode == CHRG_ON) && ((alarm_enable && ((alarm_time - RCNR) > (SHARPSL_BATCHK_TIME_SUSPEND + 30))) || !alarm_enable)) {
+ RTSR &= RTSR_ALE;
+ RTAR = RCNR + SHARPSL_BATCHK_TIME_SUSPEND;
+ dev_dbg(sharpsl_pm.dev, "Charging alarm at: %08x\n",RTAR);
+ sharpsl_pm.flags |= SHARPSL_ALARM_ACTIVE;
+ } else if (alarm_enable) {
+ RTSR &= RTSR_ALE;
+ RTAR = alarm_time;
+ dev_dbg(sharpsl_pm.dev, "User alarm at: %08x\n",RTAR);
+ } else {
+ dev_dbg(sharpsl_pm.dev, "No alarms set.\n");
+ }
+
+ pxa_pm_enter(state);
+
+ sharpsl_pm.machinfo->postsuspend();
+
+ dev_dbg(sharpsl_pm.dev, "Corgi woken up from suspend: %08x\n",PEDR);
+}
+
+static int corgi_enter_suspend(unsigned long alarm_time, unsigned int alarm_enable, suspend_state_t state)
+{
+ if (!sharpsl_pm.machinfo->should_wakeup(!(sharpsl_pm.flags & SHARPSL_ALARM_ACTIVE) && alarm_enable) )
+ {
+ if (!(sharpsl_pm.flags & SHARPSL_ALARM_ACTIVE)) {
+ dev_dbg(sharpsl_pm.dev, "No user triggered wakeup events and not charging. Strange. Suspend.\n");
+ corgi_goto_sleep(alarm_time, alarm_enable, state);
+ return 1;
+ }
+ if(sharpsl_off_charge_battery()) {
+ dev_dbg(sharpsl_pm.dev, "Charging. Suspend...\n");
+ corgi_goto_sleep(alarm_time, alarm_enable, state);
+ return 1;
+ }
+ dev_dbg(sharpsl_pm.dev, "User triggered wakeup in offline charger.\n");
+ }
+
+ if ((STATUS_BATT_LOCKED == 0) || (sharpsl_fatal_check() < 0) )
+ {
+ dev_err(sharpsl_pm.dev, "Fatal condition. Suspend.\n");
+ corgi_goto_sleep(alarm_time, alarm_enable, state);
+ return 1;
+ }
+
+ return 0;
+}
+
+static int corgi_pxa_pm_enter(suspend_state_t state)
+{
+ unsigned long alarm_time = RTAR;
+ unsigned int alarm_status = ((RTSR & RTSR_ALE) != 0);
+
+ dev_dbg(sharpsl_pm.dev, "SharpSL suspending for first time.\n");
+
+ corgi_goto_sleep(alarm_time, alarm_status, state);
+
+ while (corgi_enter_suspend(alarm_time,alarm_status,state))
+ {}
+
+ dev_dbg(sharpsl_pm.dev, "SharpSL resuming...\n");
+
+ return 0;
+}
+#endif
+
+
+/*
+ * Check for fatal battery errors
+ * Fatal returns -1
+ */
+static int sharpsl_fatal_check(void)
+{
+ int buff[5], temp, i, acin;
+
+ dev_dbg(sharpsl_pm.dev, "sharpsl_fatal_check entered\n");
+
+ /* Check AC-Adapter */
+ acin = STATUS_AC_IN;
+
+ if (acin && (sharpsl_pm.charge_mode == CHRG_ON)) {
+ CHARGE_OFF();
+ udelay(100);
+ DISCHARGE_ON(); /* enable discharge */
+ mdelay(SHARPSL_WAIT_DISCHARGE_ON);
+ }
+
+ if (sharpsl_pm.machinfo->discharge1)
+ sharpsl_pm.machinfo->discharge1(1);
+
+ /* Check battery : check inserting battery ? */
+ for (i=0; i<5; i++) {
+ buff[i] = sharpsl_read_MainBattery();
+ mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_VOLT);
+ }
+
+ if (sharpsl_pm.machinfo->discharge1)
+ sharpsl_pm.machinfo->discharge1(0);
+
+ if (acin && (sharpsl_pm.charge_mode == CHRG_ON)) {
+ udelay(100);
+ CHARGE_ON();
+ DISCHARGE_OFF();
+ }
+
+ temp = get_select_val(buff);
+ dev_dbg(sharpsl_pm.dev, "sharpsl_fatal_check: acin: %d, discharge voltage: %d, no discharge: %d\n", acin, temp, sharpsl_read_MainBattery());
+
+ if ((acin && (temp < SHARPSL_FATAL_ACIN_VOLT)) ||
+ (!acin && (temp < SHARPSL_FATAL_NOACIN_VOLT)))
+ return -1;
+ return 0;
+}
+
+static int sharpsl_off_charge_error(void)
+{
+ dev_err(sharpsl_pm.dev, "Offline Charger: Error occured.\n");
+ CHARGE_OFF();
+ CHARGE_LED_ERR();
+ sharpsl_pm.charge_mode = CHRG_ERROR;
+ return 1;
+}
+
+/*
+ * Charging Control while suspended
+ * Return 1 - go straight to sleep
+ * Return 0 - sleep or wakeup depending on other factors
+ */
+static int sharpsl_off_charge_battery(void)
+{
+ int time;
+
+ dev_dbg(sharpsl_pm.dev, "Charge Mode: %d\n", sharpsl_pm.charge_mode);
+
+ if (sharpsl_pm.charge_mode == CHRG_OFF) {
+ dev_dbg(sharpsl_pm.dev, "Offline Charger: Step 1\n");
+
+ /* AC Check */
+ if ((sharpsl_ac_check() < 0) || (sharpsl_check_battery(1) < 0))
+ return sharpsl_off_charge_error();
+
+ /* Start Charging */
+ CHARGE_LED_ON();
+ CHARGE_OFF();
+ mdelay(SHARPSL_CHARGE_WAIT_TIME);
+ CHARGE_ON();
+
+ sharpsl_pm.charge_mode = CHRG_ON;
+ sharpsl_pm.full_count = 0;
+
+ return 1;
+ } else if (sharpsl_pm.charge_mode != CHRG_ON) {
+ return 1;
+ }
+
+ if (sharpsl_pm.full_count == 0) {
+ int time;
+
+ dev_dbg(sharpsl_pm.dev, "Offline Charger: Step 2\n");
+
+ if (sharpsl_check_battery(0) < 0)
+ return sharpsl_off_charge_error();
+
+ CHARGE_OFF();
+ mdelay(SHARPSL_CHARGE_WAIT_TIME);
+ CHARGE_ON();
+ sharpsl_pm.charge_mode = CHRG_ON;
+
+ mdelay(SHARPSL_CHARGE_CO_CHECK_TIME);
+
+ time = RCNR;
+ while(1) {
+ /* Check if any wakeup event had occured */
+ if (sharpsl_pm.machinfo->charger_wakeup() != 0)
+ return 0;
+ /* Check for timeout */
+ if ((RCNR - time) > SHARPSL_WAIT_CO_TIME)
+ return 1;
+ if (STATUS_CHRG_FULL) {
+ dev_dbg(sharpsl_pm.dev, "Offline Charger: Charge full occured. Retrying to check\n");
+ sharpsl_pm.full_count++;
+ CHARGE_OFF();
+ mdelay(SHARPSL_CHARGE_WAIT_TIME);
+ CHARGE_ON();
+ return 1;
+ }
+ }
+ }
+
+ dev_dbg(sharpsl_pm.dev, "Offline Charger: Step 3\n");
+
+ mdelay(SHARPSL_CHARGE_CO_CHECK_TIME);
+
+ time = RCNR;
+ while(1) {
+ /* Check if any wakeup event had occured */
+ if (sharpsl_pm.machinfo->charger_wakeup() != 0)
+ return 0;
+ /* Check for timeout */
+ if ((RCNR-time) > SHARPSL_WAIT_CO_TIME) {
+ if (sharpsl_pm.full_count > SHARPSL_CHARGE_RETRY_CNT) {
+ dev_dbg(sharpsl_pm.dev, "Offline Charger: Not charged sufficiently. Retrying.\n");
+ sharpsl_pm.full_count = 0;
+ }
+ sharpsl_pm.full_count++;
+ return 1;
+ }
+ if (STATUS_CHRG_FULL) {
+ dev_dbg(sharpsl_pm.dev, "Offline Charger: Charging complete.\n");
+ CHARGE_LED_OFF();
+ CHARGE_OFF();
+ sharpsl_pm.charge_mode = CHRG_DONE;
+ return 1;
+ }
+ }
+}
+
+
+static ssize_t battery_percentage_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ return sprintf(buf, "%d\n",sharpsl_pm.battstat.mainbat_percent);
+}
+
+static ssize_t battery_voltage_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ return sprintf(buf, "%d\n",sharpsl_pm.battstat.mainbat_voltage);
+}
+
+static DEVICE_ATTR(battery_percentage, 0444, battery_percentage_show, NULL);
+static DEVICE_ATTR(battery_voltage, 0444, battery_voltage_show, NULL);
+
+extern void (*apm_get_power_status)(struct apm_power_info *);
+
+static void sharpsl_apm_get_power_status(struct apm_power_info *info)
+{
+ info->ac_line_status = sharpsl_pm.battstat.ac_status;
+
+ if (sharpsl_pm.charge_mode == CHRG_ON)
+ info->battery_status = APM_BATTERY_STATUS_CHARGING;
+ else
+ info->battery_status = sharpsl_pm.battstat.mainbat_status;
+
+ info->battery_flag = (1 << info->battery_status);
+ info->battery_life = sharpsl_pm.battstat.mainbat_percent;
+}
+
+static struct pm_ops sharpsl_pm_ops = {
+ .pm_disk_mode = PM_DISK_FIRMWARE,
+ .prepare = pxa_pm_prepare,
+ .enter = corgi_pxa_pm_enter,
+ .finish = pxa_pm_finish,
+};
+
+static int __init sharpsl_pm_probe(struct device *dev)
+{
+ if (!dev->platform_data)
+ return -EINVAL;
+
+ sharpsl_pm.dev = dev;
+ sharpsl_pm.machinfo = dev->platform_data;
+ sharpsl_pm.charge_mode = CHRG_OFF;
+ sharpsl_pm.flags = 0;
+
+ sharpsl_pm.machinfo->init();
+
+ init_timer(&sharpsl_pm.ac_timer);
+ sharpsl_pm.ac_timer.function = sharpsl_ac_timer;
+
+ init_timer(&sharpsl_pm.chrg_full_timer);
+ sharpsl_pm.chrg_full_timer.function = sharpsl_chrg_full_timer;
+
+ pxa_gpio_mode(sharpsl_pm.machinfo->gpio_acin | GPIO_IN);
+ pxa_gpio_mode(sharpsl_pm.machinfo->gpio_batfull | GPIO_IN);
+ pxa_gpio_mode(sharpsl_pm.machinfo->gpio_batlock | GPIO_IN);
+
+ /* Register interrupt handlers */
+ if (request_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_acin), sharpsl_ac_isr, SA_INTERRUPT, "AC Input Detect", sharpsl_ac_isr)) {
+ dev_err(sharpsl_pm.dev, "Could not get irq %d.\n", IRQ_GPIO(sharpsl_pm.machinfo->gpio_acin));
+ }
+ else set_irq_type(IRQ_GPIO(sharpsl_pm.machinfo->gpio_acin),IRQT_BOTHEDGE);
+
+ if (request_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batlock), sharpsl_fatal_isr, SA_INTERRUPT, "Battery Cover", sharpsl_fatal_isr)) {
+ dev_err(sharpsl_pm.dev, "Could not get irq %d.\n", IRQ_GPIO(sharpsl_pm.machinfo->gpio_batlock));
+ }
+ else set_irq_type(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batlock),IRQT_FALLING);
+
+ if (sharpsl_pm.machinfo->gpio_fatal) {
+ if (request_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_fatal), sharpsl_fatal_isr, SA_INTERRUPT, "Fatal Battery", sharpsl_fatal_isr)) {
+ dev_err(sharpsl_pm.dev, "Could not get irq %d.\n", IRQ_GPIO(sharpsl_pm.machinfo->gpio_fatal));
+ }
+ else set_irq_type(IRQ_GPIO(sharpsl_pm.machinfo->gpio_fatal),IRQT_FALLING);
+ }
+
+ if (!machine_is_corgi())
+ {
+ /* Register interrupt handler. */
+ if (request_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batfull), sharpsl_chrg_full_isr, SA_INTERRUPT, "CO", sharpsl_chrg_full_isr)) {
+ dev_err(sharpsl_pm.dev, "Could not get irq %d.\n", IRQ_GPIO(sharpsl_pm.machinfo->gpio_batfull));
+ }
+ else set_irq_type(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batfull),IRQT_RISING);
+ }
+
+ device_create_file(dev, &dev_attr_battery_percentage);
+ device_create_file(dev, &dev_attr_battery_voltage);
+
+ apm_get_power_status = sharpsl_apm_get_power_status;
+
+ pm_set_ops(&sharpsl_pm_ops);
+
+ mod_timer(&sharpsl_pm.ac_timer, jiffies + msecs_to_jiffies(250));
+
+ return 0;
+}
+
+static int sharpsl_pm_remove(struct device *dev)
+{
+ pm_set_ops(NULL);
+
+ device_remove_file(dev, &dev_attr_battery_percentage);
+ device_remove_file(dev, &dev_attr_battery_voltage);
+
+ free_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_acin), sharpsl_ac_isr);
+ free_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batlock), sharpsl_fatal_isr);
+
+ if (sharpsl_pm.machinfo->gpio_fatal)
+ free_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_fatal), sharpsl_fatal_isr);
+
+ if (!machine_is_corgi())
+ free_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batfull), sharpsl_chrg_full_isr);
+
+ del_timer_sync(&sharpsl_pm.chrg_full_timer);
+ del_timer_sync(&sharpsl_pm.ac_timer);
+
+ return 0;
+}
+
+static struct device_driver sharpsl_pm_driver = {
+ .name = "sharpsl-pm",
+ .bus = &platform_bus_type,
+ .probe = sharpsl_pm_probe,
+ .remove = sharpsl_pm_remove,
+ .suspend = sharpsl_pm_suspend,
+ .resume = sharpsl_pm_resume,
+};
+
+static int __devinit sharpsl_pm_init(void)
+{
+ return driver_register(&sharpsl_pm_driver);
+}
+
+static void sharpsl_pm_exit(void)
+{
+ driver_unregister(&sharpsl_pm_driver);
+}
+
+late_initcall(sharpsl_pm_init);
+module_exit(sharpsl_pm_exit);
diff --git a/arch/arm/mach-pxa/sleep.S b/arch/arm/mach-pxa/sleep.S
index 5786ccad938c..c9862688ff3d 100644
--- a/arch/arm/mach-pxa/sleep.S
+++ b/arch/arm/mach-pxa/sleep.S
@@ -28,7 +28,9 @@
/*
* pxa_cpu_suspend()
*
- * Forces CPU into sleep state
+ * Forces CPU into sleep state.
+ *
+ * r0 = value for PWRMODE M field for desired sleep state
*/
ENTRY(pxa_cpu_suspend)
@@ -53,6 +55,7 @@ ENTRY(pxa_cpu_suspend)
mov r10, sp
stmfd sp!, {r3 - r10}
+ mov r5, r0 @ save sleep mode
@ preserve phys address of stack
mov r0, sp
bl sleep_phys_sp
@@ -66,7 +69,7 @@ ENTRY(pxa_cpu_suspend)
@ (also workaround for sighting 28071)
@ prepare value for sleep mode
- mov r1, #3 @ sleep mode
+ mov r1, r5 @ sleep mode
@ prepare pointer to physical address 0 (virtual mapping in generic.c)
mov r2, #UNCACHED_PHYS_0
diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c
index d0ab428c2d7d..4e9a699ee428 100644
--- a/arch/arm/mach-pxa/spitz.c
+++ b/arch/arm/mach-pxa/spitz.c
@@ -14,7 +14,7 @@
#include <linux/kernel.h>
#include <linux/init.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <linux/delay.h>
#include <linux/major.h>
#include <linux/fs.h>
@@ -34,6 +34,7 @@
#include <asm/arch/pxa-regs.h>
#include <asm/arch/irq.h>
+#include <asm/arch/irda.h>
#include <asm/arch/mmc.h>
#include <asm/arch/udc.h>
#include <asm/arch/pxafb.h>
@@ -103,6 +104,66 @@ struct platform_device spitzscoop2_device = {
.resource = spitz_scoop2_resources,
};
+#define SPITZ_PWR_SD 0x01
+#define SPITZ_PWR_CF 0x02
+
+/* Power control is shared with between one of the CF slots and SD */
+static void spitz_card_pwr_ctrl(int device, unsigned short new_cpr)
+{
+ unsigned short cpr = read_scoop_reg(&spitzscoop_device.dev, SCOOP_CPR);
+
+ if (new_cpr & 0x0007) {
+ set_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_CF_POWER);
+ if (!(cpr & 0x0002) && !(cpr & 0x0004))
+ mdelay(5);
+ if (device == SPITZ_PWR_CF)
+ cpr |= 0x0002;
+ if (device == SPITZ_PWR_SD)
+ cpr |= 0x0004;
+ write_scoop_reg(&spitzscoop_device.dev, SCOOP_CPR, cpr | new_cpr);
+ } else {
+ if (device == SPITZ_PWR_CF)
+ cpr &= ~0x0002;
+ if (device == SPITZ_PWR_SD)
+ cpr &= ~0x0004;
+ write_scoop_reg(&spitzscoop_device.dev, SCOOP_CPR, cpr | new_cpr);
+ if (!(cpr & 0x0002) && !(cpr & 0x0004)) {
+ mdelay(1);
+ reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_CF_POWER);
+ }
+ }
+}
+
+static void spitz_pcmcia_init(void)
+{
+ /* Setup default state of GPIO outputs
+ before we enable them as outputs. */
+ GPSR(GPIO48_nPOE) = GPIO_bit(GPIO48_nPOE) |
+ GPIO_bit(GPIO49_nPWE) | GPIO_bit(GPIO50_nPIOR) |
+ GPIO_bit(GPIO51_nPIOW) | GPIO_bit(GPIO54_nPCE_2);
+ GPSR(GPIO85_nPCE_1) = GPIO_bit(GPIO85_nPCE_1);
+
+ pxa_gpio_mode(GPIO48_nPOE_MD);
+ pxa_gpio_mode(GPIO49_nPWE_MD);
+ pxa_gpio_mode(GPIO50_nPIOR_MD);
+ pxa_gpio_mode(GPIO51_nPIOW_MD);
+ pxa_gpio_mode(GPIO55_nPREG_MD);
+ pxa_gpio_mode(GPIO56_nPWAIT_MD);
+ pxa_gpio_mode(GPIO57_nIOIS16_MD);
+ pxa_gpio_mode(GPIO85_nPCE_1_MD);
+ pxa_gpio_mode(GPIO54_nPCE_2_MD);
+ pxa_gpio_mode(GPIO104_pSKTSEL_MD);
+}
+
+static void spitz_pcmcia_pwr(struct device *scoop, unsigned short cpr, int nr)
+{
+ /* Only need to override behaviour for slot 0 */
+ if (nr == 0)
+ spitz_card_pwr_ctrl(SPITZ_PWR_CF, cpr);
+ else
+ write_scoop_reg(scoop, SCOOP_CPR, cpr);
+}
+
static struct scoop_pcmcia_dev spitz_pcmcia_scoop[] = {
{
.dev = &spitzscoop_device.dev,
@@ -116,6 +177,16 @@ static struct scoop_pcmcia_dev spitz_pcmcia_scoop[] = {
},
};
+static struct scoop_pcmcia_config spitz_pcmcia_config = {
+ .devs = &spitz_pcmcia_scoop[0],
+ .num_devs = 2,
+ .pcmcia_init = spitz_pcmcia_init,
+ .power_ctrl = spitz_pcmcia_pwr,
+};
+
+EXPORT_SYMBOL(spitzscoop_device);
+EXPORT_SYMBOL(spitzscoop2_device);
+
/*
* Spitz SSP Device
@@ -234,27 +305,14 @@ static int spitz_mci_init(struct device *dev, irqreturn_t (*spitz_detect_int)(in
return 0;
}
-/* Power control is shared with one of the CF slots so we have a mess */
static void spitz_mci_setpower(struct device *dev, unsigned int vdd)
{
struct pxamci_platform_data* p_d = dev->platform_data;
- unsigned short cpr = read_scoop_reg(&spitzscoop_device.dev, SCOOP_CPR);
-
- if (( 1 << vdd) & p_d->ocr_mask) {
- /* printk(KERN_DEBUG "%s: on\n", __FUNCTION__); */
- set_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_CF_POWER);
- mdelay(2);
- write_scoop_reg(&spitzscoop_device.dev, SCOOP_CPR, cpr | 0x04);
- } else {
- /* printk(KERN_DEBUG "%s: off\n", __FUNCTION__); */
- write_scoop_reg(&spitzscoop_device.dev, SCOOP_CPR, cpr & ~0x04);
-
- if (!(cpr | 0x02)) {
- mdelay(1);
- reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_CF_POWER);
- }
- }
+ if (( 1 << vdd) & p_d->ocr_mask)
+ spitz_card_pwr_ctrl(SPITZ_PWR_SD, 0x0004);
+ else
+ spitz_card_pwr_ctrl(SPITZ_PWR_SD, 0x0000);
}
static int spitz_mci_get_ro(struct device *dev)
@@ -277,6 +335,23 @@ static struct pxamci_platform_data spitz_mci_platform_data = {
/*
+ * Irda
+ */
+static void spitz_irda_transceiver_mode(struct device *dev, int mode)
+{
+ if (mode & IR_OFF)
+ set_scoop_gpio(&spitzscoop2_device.dev, SPITZ_SCP2_IR_ON);
+ else
+ reset_scoop_gpio(&spitzscoop2_device.dev, SPITZ_SCP2_IR_ON);
+}
+
+static struct pxaficp_platform_data spitz_ficp_platform_data = {
+ .transceiver_cap = IR_SIRMODE | IR_OFF,
+ .transceiver_mode = spitz_irda_transceiver_mode,
+};
+
+
+/*
* Spitz PXA Framebuffer
*/
static struct pxafb_mach_info spitz_pxafb_info __initdata = {
@@ -326,14 +401,15 @@ static void __init common_init(void)
platform_add_devices(devices, ARRAY_SIZE(devices));
pxa_set_mci_info(&spitz_mci_platform_data);
+ pxa_set_ficp_info(&spitz_ficp_platform_data);
set_pxa_fb_parent(&spitzssp_device.dev);
set_pxa_fb_info(&spitz_pxafb_info);
}
static void __init spitz_init(void)
{
- scoop_num = 2;
- scoop_devs = &spitz_pcmcia_scoop[0];
+ platform_scoop_config = &spitz_pcmcia_config;
+
spitz_bl_machinfo.set_bl_intensity = spitz_bl_set_intensity;
common_init();
diff --git a/arch/arm/mach-pxa/ssp.c b/arch/arm/mach-pxa/ssp.c
index 4d826c021315..a68b30eff4d2 100644
--- a/arch/arm/mach-pxa/ssp.c
+++ b/arch/arm/mach-pxa/ssp.c
@@ -19,6 +19,8 @@
* 22nd Aug 2003 Initial version.
* 20th Dec 2004 Added ssp_config for changing port config without
* closing the port.
+ * 4th Aug 2005 Added option to disable irq handler registration and
+ * cleaned up irq and clock detection.
*/
#include <linux/module.h>
@@ -37,6 +39,26 @@
#define PXA_SSP_PORTS 3
+struct ssp_info_ {
+ int irq;
+ u32 clock;
+};
+
+/*
+ * SSP port clock and IRQ settings
+ */
+static const struct ssp_info_ ssp_info[PXA_SSP_PORTS] = {
+#if defined (CONFIG_PXA27x)
+ {IRQ_SSP, CKEN23_SSP1},
+ {IRQ_SSP2, CKEN3_SSP2},
+ {IRQ_SSP3, CKEN4_SSP3},
+#else
+ {IRQ_SSP, CKEN3_SSP},
+ {IRQ_NSSP, CKEN9_NSSP},
+ {IRQ_ASSP, CKEN10_ASSP},
+#endif
+};
+
static DECLARE_MUTEX(sem);
static int use_count[PXA_SSP_PORTS] = {0, 0, 0};
@@ -210,9 +232,9 @@ int ssp_config(struct ssp_dev *dev, u32 mode, u32 flags, u32 psp_flags, u32 spee
* %-EBUSY if the resources are already in use
* %0 on success
*/
-int ssp_init(struct ssp_dev *dev, u32 port)
+int ssp_init(struct ssp_dev *dev, u32 port, u32 init_flags)
{
- int ret, irq;
+ int ret;
if (port > PXA_SSP_PORTS || port == 0)
return -ENODEV;
@@ -229,61 +251,20 @@ int ssp_init(struct ssp_dev *dev, u32 port)
up(&sem);
return -EBUSY;
}
-
- switch (port) {
- case 1:
- irq = IRQ_SSP;
- break;
-#if defined (CONFIG_PXA27x)
- case 2:
- irq = IRQ_SSP2;
- break;
- case 3:
- irq = IRQ_SSP3;
- break;
-#else
- case 2:
- irq = IRQ_NSSP;
- break;
- case 3:
- irq = IRQ_ASSP;
- break;
-#endif
- default:
- return -ENODEV;
- }
-
dev->port = port;
- ret = request_irq(irq, ssp_interrupt, 0, "SSP", dev);
- if (ret)
- goto out_region;
+ /* do we need to get irq */
+ if (!(init_flags & SSP_NO_IRQ)) {
+ ret = request_irq(ssp_info[port-1].irq, ssp_interrupt,
+ 0, "SSP", dev);
+ if (ret)
+ goto out_region;
+ dev->irq = ssp_info[port-1].irq;
+ } else
+ dev->irq = 0;
/* turn on SSP port clock */
- switch (dev->port) {
-#if defined (CONFIG_PXA27x)
- case 1:
- pxa_set_cken(CKEN23_SSP1, 1);
- break;
- case 2:
- pxa_set_cken(CKEN3_SSP2, 1);
- break;
- case 3:
- pxa_set_cken(CKEN4_SSP3, 1);
- break;
-#else
- case 1:
- pxa_set_cken(CKEN3_SSP, 1);
- break;
- case 2:
- pxa_set_cken(CKEN9_NSSP, 1);
- break;
- case 3:
- pxa_set_cken(CKEN10_ASSP, 1);
- break;
-#endif
- }
-
+ pxa_set_cken(ssp_info[port-1].clock, 1);
up(&sem);
return 0;
@@ -301,46 +282,17 @@ out_region:
*/
void ssp_exit(struct ssp_dev *dev)
{
- int irq;
-
down(&sem);
SSCR0_P(dev->port) &= ~SSCR0_SSE;
- /* find irq, save power and turn off SSP port clock */
- switch (dev->port) {
-#if defined (CONFIG_PXA27x)
- case 1:
- irq = IRQ_SSP;
- pxa_set_cken(CKEN23_SSP1, 0);
- break;
- case 2:
- irq = IRQ_SSP2;
- pxa_set_cken(CKEN3_SSP2, 0);
- break;
- case 3:
- irq = IRQ_SSP3;
- pxa_set_cken(CKEN4_SSP3, 0);
- break;
-#else
- case 1:
- irq = IRQ_SSP;
- pxa_set_cken(CKEN3_SSP, 0);
- break;
- case 2:
- irq = IRQ_NSSP;
- pxa_set_cken(CKEN9_NSSP, 0);
- break;
- case 3:
- irq = IRQ_ASSP;
- pxa_set_cken(CKEN10_ASSP, 0);
- break;
-#endif
- default:
- printk(KERN_WARNING "SSP: tried to close invalid port\n");
- return;
+ if (dev->port > PXA_SSP_PORTS || dev->port == 0) {
+ printk(KERN_WARNING "SSP: tried to close invalid port\n");
+ return;
}
- free_irq(irq, dev);
+ pxa_set_cken(ssp_info[dev->port-1].clock, 0);
+ if (dev->irq)
+ free_irq(dev->irq, dev);
release_mem_region(__PREG(SSCR0_P(dev->port)), 0x2c);
use_count[dev->port - 1]--;
up(&sem);
diff --git a/arch/arm/mach-pxa/standby.S b/arch/arm/mach-pxa/standby.S
index 8a3f27b76784..6f6dbbd08021 100644
--- a/arch/arm/mach-pxa/standby.S
+++ b/arch/arm/mach-pxa/standby.S
@@ -21,7 +21,7 @@
ENTRY(pxa_cpu_standby)
ldr r0, =PSSR
mov r1, #(PSSR_PH | PSSR_STS)
- mov r2, #2
+ mov r2, #PWRMODE_STANDBY
mov r3, #UNCACHED_PHYS_0 @ Read mem context in.
ldr ip, [r3]
b 1f
diff --git a/arch/arm/mach-pxa/time.c b/arch/arm/mach-pxa/time.c
index 7dad3f1465e0..b9b2057349eb 100644
--- a/arch/arm/mach-pxa/time.c
+++ b/arch/arm/mach-pxa/time.c
@@ -132,11 +132,13 @@ static void __init pxa_timer_init(void)
tv.tv_sec = pxa_get_rtc_time();
do_settimeofday(&tv);
- OSMR0 = 0; /* set initial match at 0 */
+ OIER = 0; /* disable any timer interrupts */
+ OSCR = LATCH*2; /* push OSCR out of the way */
+ OSMR0 = LATCH; /* set initial match */
OSSR = 0xf; /* clear status on all timers */
setup_irq(IRQ_OST0, &pxa_timer_irq);
- OIER |= OIER_E0; /* enable match on timer 0 to cause interrupts */
- OSCR = 0; /* initialize free-running timer, force first match */
+ OIER = OIER_E0; /* enable match on timer 0 to cause interrupts */
+ OSCR = 0; /* initialize free-running timer */
}
#ifdef CONFIG_NO_IDLE_HZ
diff --git a/arch/arm/mach-pxa/tosa.c b/arch/arm/mach-pxa/tosa.c
new file mode 100644
index 000000000000..c312054dfb88
--- /dev/null
+++ b/arch/arm/mach-pxa/tosa.c
@@ -0,0 +1,306 @@
+/*
+ * Support for Sharp SL-C6000x PDAs
+ * Model: (Tosa)
+ *
+ * Copyright (c) 2005 Dirk Opfer
+ *
+ * Based on code written by Sharp/Lineo for 2.4 kernels
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/major.h>
+#include <linux/fs.h>
+#include <linux/interrupt.h>
+#include <linux/mmc/host.h>
+
+#include <asm/setup.h>
+#include <asm/memory.h>
+#include <asm/mach-types.h>
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/arch/irda.h>
+#include <asm/arch/mmc.h>
+#include <asm/arch/udc.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <asm/arch/pxa-regs.h>
+#include <asm/arch/irq.h>
+#include <asm/arch/tosa.h>
+
+#include <asm/hardware/scoop.h>
+#include <asm/mach/sharpsl_param.h>
+
+#include "generic.h"
+
+
+/*
+ * SCOOP Device
+ */
+static struct resource tosa_scoop_resources[] = {
+ [0] = {
+ .start = TOSA_CF_PHYS,
+ .end = TOSA_CF_PHYS + 0xfff,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct scoop_config tosa_scoop_setup = {
+ .io_dir = TOSA_SCOOP_IO_DIR,
+ .io_out = TOSA_SCOOP_IO_OUT,
+
+};
+
+struct platform_device tosascoop_device = {
+ .name = "sharp-scoop",
+ .id = 0,
+ .dev = {
+ .platform_data = &tosa_scoop_setup,
+ },
+ .num_resources = ARRAY_SIZE(tosa_scoop_resources),
+ .resource = tosa_scoop_resources,
+};
+
+
+/*
+ * SCOOP Device Jacket
+ */
+static struct resource tosa_scoop_jc_resources[] = {
+ [0] = {
+ .start = TOSA_SCOOP_PHYS + 0x40,
+ .end = TOSA_SCOOP_PHYS + 0xfff,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct scoop_config tosa_scoop_jc_setup = {
+ .io_dir = TOSA_SCOOP_JC_IO_DIR,
+ .io_out = TOSA_SCOOP_JC_IO_OUT,
+};
+
+struct platform_device tosascoop_jc_device = {
+ .name = "sharp-scoop",
+ .id = 1,
+ .dev = {
+ .platform_data = &tosa_scoop_jc_setup,
+ .parent = &tosascoop_device.dev,
+ },
+ .num_resources = ARRAY_SIZE(tosa_scoop_jc_resources),
+ .resource = tosa_scoop_jc_resources,
+};
+
+/*
+ * PCMCIA
+ */
+static struct scoop_pcmcia_dev tosa_pcmcia_scoop[] = {
+{
+ .dev = &tosascoop_device.dev,
+ .irq = TOSA_IRQ_GPIO_CF_IRQ,
+ .cd_irq = TOSA_IRQ_GPIO_CF_CD,
+ .cd_irq_str = "PCMCIA0 CD",
+},{
+ .dev = &tosascoop_jc_device.dev,
+ .irq = TOSA_IRQ_GPIO_JC_CF_IRQ,
+ .cd_irq = -1,
+},
+};
+
+static void tosa_pcmcia_init(void)
+{
+ /* Setup default state of GPIO outputs
+ before we enable them as outputs. */
+ GPSR(GPIO48_nPOE) = GPIO_bit(GPIO48_nPOE) |
+ GPIO_bit(GPIO49_nPWE) | GPIO_bit(GPIO50_nPIOR) |
+ GPIO_bit(GPIO51_nPIOW) | GPIO_bit(GPIO52_nPCE_1) |
+ GPIO_bit(GPIO53_nPCE_2);
+
+ pxa_gpio_mode(GPIO48_nPOE_MD);
+ pxa_gpio_mode(GPIO49_nPWE_MD);
+ pxa_gpio_mode(GPIO50_nPIOR_MD);
+ pxa_gpio_mode(GPIO51_nPIOW_MD);
+ pxa_gpio_mode(GPIO55_nPREG_MD);
+ pxa_gpio_mode(GPIO56_nPWAIT_MD);
+ pxa_gpio_mode(GPIO57_nIOIS16_MD);
+ pxa_gpio_mode(GPIO52_nPCE_1_MD);
+ pxa_gpio_mode(GPIO53_nPCE_2_MD);
+ pxa_gpio_mode(GPIO54_pSKTSEL_MD);
+}
+
+static struct scoop_pcmcia_config tosa_pcmcia_config = {
+ .devs = &tosa_pcmcia_scoop[0],
+ .num_devs = 2,
+ .pcmcia_init = tosa_pcmcia_init,
+};
+
+/*
+ * USB Device Controller
+ */
+static void tosa_udc_command(int cmd)
+{
+ switch(cmd) {
+ case PXA2XX_UDC_CMD_CONNECT:
+ set_scoop_gpio(&tosascoop_jc_device.dev,TOSA_SCOOP_JC_USB_PULLUP);
+ break;
+ case PXA2XX_UDC_CMD_DISCONNECT:
+ reset_scoop_gpio(&tosascoop_jc_device.dev,TOSA_SCOOP_JC_USB_PULLUP);
+ break;
+ }
+}
+
+static int tosa_udc_is_connected(void)
+{
+ return ((GPLR(TOSA_GPIO_USB_IN) & GPIO_bit(TOSA_GPIO_USB_IN)) == 0);
+}
+
+
+static struct pxa2xx_udc_mach_info udc_info __initdata = {
+ .udc_command = tosa_udc_command,
+ .udc_is_connected = tosa_udc_is_connected,
+};
+
+/*
+ * MMC/SD Device
+ */
+static struct pxamci_platform_data tosa_mci_platform_data;
+
+static int tosa_mci_init(struct device *dev, irqreturn_t (*tosa_detect_int)(int, void *, struct pt_regs *), void *data)
+{
+ int err;
+
+ /* setup GPIO for PXA25x MMC controller */
+ pxa_gpio_mode(GPIO6_MMCCLK_MD);
+ pxa_gpio_mode(GPIO8_MMCCS0_MD);
+ pxa_gpio_mode(TOSA_GPIO_nSD_DETECT | GPIO_IN);
+
+ tosa_mci_platform_data.detect_delay = msecs_to_jiffies(250);
+
+ err = request_irq(TOSA_IRQ_GPIO_nSD_DETECT, tosa_detect_int, SA_INTERRUPT,
+ "MMC/SD card detect", data);
+ if (err) {
+ printk(KERN_ERR "tosa_mci_init: MMC/SD: can't request MMC card detect IRQ\n");
+ return -1;
+ }
+
+ set_irq_type(TOSA_IRQ_GPIO_nSD_DETECT, IRQT_BOTHEDGE);
+
+ return 0;
+}
+
+static void tosa_mci_setpower(struct device *dev, unsigned int vdd)
+{
+ struct pxamci_platform_data* p_d = dev->platform_data;
+
+ if (( 1 << vdd) & p_d->ocr_mask) {
+ set_scoop_gpio(&tosascoop_device.dev,TOSA_SCOOP_PWR_ON);
+ } else {
+ reset_scoop_gpio(&tosascoop_device.dev,TOSA_SCOOP_PWR_ON);
+ }
+}
+
+static int tosa_mci_get_ro(struct device *dev)
+{
+ return (read_scoop_reg(&tosascoop_device.dev, SCOOP_GPWR)&TOSA_SCOOP_SD_WP);
+}
+
+static void tosa_mci_exit(struct device *dev, void *data)
+{
+ free_irq(TOSA_IRQ_GPIO_nSD_DETECT, data);
+}
+
+static struct pxamci_platform_data tosa_mci_platform_data = {
+ .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34,
+ .init = tosa_mci_init,
+ .get_ro = tosa_mci_get_ro,
+ .setpower = tosa_mci_setpower,
+ .exit = tosa_mci_exit,
+};
+
+/*
+ * Irda
+ */
+static void tosa_irda_transceiver_mode(struct device *dev, int mode)
+{
+ if (mode & IR_OFF) {
+ reset_scoop_gpio(&tosascoop_device.dev,TOSA_SCOOP_IR_POWERDWN);
+ pxa_gpio_mode(GPIO47_STTXD|GPIO_DFLT_LOW);
+ pxa_gpio_mode(GPIO47_STTXD|GPIO_OUT);
+ } else {
+ pxa_gpio_mode(GPIO47_STTXD_MD);
+ set_scoop_gpio(&tosascoop_device.dev,TOSA_SCOOP_IR_POWERDWN);
+ }
+}
+
+static struct pxaficp_platform_data tosa_ficp_platform_data = {
+ .transceiver_cap = IR_SIRMODE | IR_OFF,
+ .transceiver_mode = tosa_irda_transceiver_mode,
+};
+
+/*
+ * Tosa Keyboard
+ */
+static struct platform_device tosakbd_device = {
+ .name = "tosa-keyboard",
+ .id = -1,
+};
+
+static struct platform_device *devices[] __initdata = {
+ &tosascoop_device,
+ &tosascoop_jc_device,
+ &tosakbd_device,
+};
+
+static void __init tosa_init(void)
+{
+ pxa_gpio_mode(TOSA_GPIO_ON_RESET | GPIO_IN);
+ pxa_gpio_mode(TOSA_GPIO_TC6393_INT | GPIO_IN);
+ pxa_gpio_mode(TOSA_GPIO_USB_IN | GPIO_IN);
+
+ /* setup sleep mode values */
+ PWER = 0x00000002;
+ PFER = 0x00000000;
+ PRER = 0x00000002;
+ PGSR0 = 0x00000000;
+ PGSR1 = 0x00FF0002;
+ PGSR2 = 0x00014000;
+ PCFR |= PCFR_OPDE;
+
+ /* enable batt_fault */
+ PMCR = 0x01;
+
+ pxa_set_mci_info(&tosa_mci_platform_data);
+ pxa_set_udc_info(&udc_info);
+ pxa_set_ficp_info(&tosa_ficp_platform_data);
+ platform_scoop_config = &tosa_pcmcia_config;
+
+ platform_add_devices(devices, ARRAY_SIZE(devices));
+}
+
+static void __init fixup_tosa(struct machine_desc *desc,
+ struct tag *tags, char **cmdline, struct meminfo *mi)
+{
+ sharpsl_save_param();
+ mi->nr_banks=1;
+ mi->bank[0].start = 0xa0000000;
+ mi->bank[0].node = 0;
+ mi->bank[0].size = (64*1024*1024);
+}
+
+MACHINE_START(TOSA, "SHARP Tosa")
+ .phys_ram = 0xa0000000,
+ .phys_io = 0x40000000,
+ .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
+ .fixup = fixup_tosa,
+ .map_io = pxa_map_io,
+ .init_irq = pxa_init_irq,
+ .init_machine = tosa_init,
+ .timer = &pxa_timer,
+MACHINE_END
diff --git a/arch/arm/mach-realview/Kconfig b/arch/arm/mach-realview/Kconfig
new file mode 100644
index 000000000000..129976866d47
--- /dev/null
+++ b/arch/arm/mach-realview/Kconfig
@@ -0,0 +1,20 @@
+menu "RealView platform type"
+ depends on ARCH_REALVIEW
+
+config MACH_REALVIEW_EB
+ bool "Support RealView/EB platform"
+ default n
+ select ARM_GIC
+ help
+ Include support for the ARM(R) RealView Emulation Baseboard platform.
+
+config REALVIEW_MPCORE
+ bool "Support MPcore tile"
+ depends on MACH_REALVIEW_EB
+ help
+ Enable support for the MPCore tile on the Realview platform.
+ Since there are device address and interrupt differences, a
+ kernel built with this option enabled is not compatible with
+ other tiles.
+
+endmenu
diff --git a/arch/arm/mach-realview/Makefile b/arch/arm/mach-realview/Makefile
new file mode 100644
index 000000000000..36e76ba937fc
--- /dev/null
+++ b/arch/arm/mach-realview/Makefile
@@ -0,0 +1,9 @@
+#
+# Makefile for the linux kernel.
+#
+
+obj-y := core.o clock.o
+obj-$(CONFIG_MACH_REALVIEW_EB) += realview_eb.o
+obj-$(CONFIG_SMP) += platsmp.o headsmp.o
+obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
+obj-$(CONFIG_LOCAL_TIMERS) += localtimer.o
diff --git a/arch/arm/mach-realview/Makefile.boot b/arch/arm/mach-realview/Makefile.boot
new file mode 100644
index 000000000000..c7e75acfe6c9
--- /dev/null
+++ b/arch/arm/mach-realview/Makefile.boot
@@ -0,0 +1,4 @@
+ zreladdr-y := 0x00008000
+params_phys-y := 0x00000100
+initrd_phys-y := 0x00800000
+
diff --git a/arch/arm/mach-realview/clock.c b/arch/arm/mach-realview/clock.c
new file mode 100644
index 000000000000..002635c97bb6
--- /dev/null
+++ b/arch/arm/mach-realview/clock.c
@@ -0,0 +1,145 @@
+/*
+ * linux/arch/arm/mach-realview/clock.c
+ *
+ * Copyright (C) 2004 ARM Limited.
+ * Written by Deep Blue Solutions Limited.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+
+#include <asm/semaphore.h>
+#include <asm/hardware/clock.h>
+#include <asm/hardware/icst307.h>
+
+#include "clock.h"
+
+static LIST_HEAD(clocks);
+static DECLARE_MUTEX(clocks_sem);
+
+struct clk *clk_get(struct device *dev, const char *id)
+{
+ struct clk *p, *clk = ERR_PTR(-ENOENT);
+
+ down(&clocks_sem);
+ list_for_each_entry(p, &clocks, node) {
+ if (strcmp(id, p->name) == 0 && try_module_get(p->owner)) {
+ clk = p;
+ break;
+ }
+ }
+ up(&clocks_sem);
+
+ return clk;
+}
+EXPORT_SYMBOL(clk_get);
+
+void clk_put(struct clk *clk)
+{
+ module_put(clk->owner);
+}
+EXPORT_SYMBOL(clk_put);
+
+int clk_enable(struct clk *clk)
+{
+ return 0;
+}
+EXPORT_SYMBOL(clk_enable);
+
+void clk_disable(struct clk *clk)
+{
+}
+EXPORT_SYMBOL(clk_disable);
+
+int clk_use(struct clk *clk)
+{
+ return 0;
+}
+EXPORT_SYMBOL(clk_use);
+
+void clk_unuse(struct clk *clk)
+{
+}
+EXPORT_SYMBOL(clk_unuse);
+
+unsigned long clk_get_rate(struct clk *clk)
+{
+ return clk->rate;
+}
+EXPORT_SYMBOL(clk_get_rate);
+
+long clk_round_rate(struct clk *clk, unsigned long rate)
+{
+ return rate;
+}
+EXPORT_SYMBOL(clk_round_rate);
+
+int clk_set_rate(struct clk *clk, unsigned long rate)
+{
+ int ret = -EIO;
+
+ if (clk->setvco) {
+ struct icst307_vco vco;
+
+ vco = icst307_khz_to_vco(clk->params, rate / 1000);
+ clk->rate = icst307_khz(clk->params, vco) * 1000;
+
+ printk("Clock %s: setting VCO reg params: S=%d R=%d V=%d\n",
+ clk->name, vco.s, vco.r, vco.v);
+
+ clk->setvco(clk, vco);
+ ret = 0;
+ }
+ return ret;
+}
+EXPORT_SYMBOL(clk_set_rate);
+
+/*
+ * These are fixed clocks.
+ */
+static struct clk kmi_clk = {
+ .name = "KMIREFCLK",
+ .rate = 24000000,
+};
+
+static struct clk uart_clk = {
+ .name = "UARTCLK",
+ .rate = 24000000,
+};
+
+static struct clk mmci_clk = {
+ .name = "MCLK",
+ .rate = 33000000,
+};
+
+int clk_register(struct clk *clk)
+{
+ down(&clocks_sem);
+ list_add(&clk->node, &clocks);
+ up(&clocks_sem);
+ return 0;
+}
+EXPORT_SYMBOL(clk_register);
+
+void clk_unregister(struct clk *clk)
+{
+ down(&clocks_sem);
+ list_del(&clk->node);
+ up(&clocks_sem);
+}
+EXPORT_SYMBOL(clk_unregister);
+
+static int __init clk_init(void)
+{
+ clk_register(&kmi_clk);
+ clk_register(&uart_clk);
+ clk_register(&mmci_clk);
+ return 0;
+}
+arch_initcall(clk_init);
diff --git a/arch/arm/mach-realview/clock.h b/arch/arm/mach-realview/clock.h
new file mode 100644
index 000000000000..dadba695e181
--- /dev/null
+++ b/arch/arm/mach-realview/clock.h
@@ -0,0 +1,25 @@
+/*
+ * linux/arch/arm/mach-realview/clock.h
+ *
+ * Copyright (C) 2004 ARM Limited.
+ * Written by Deep Blue Solutions Limited.
+ *
+ * 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.
+ */
+struct module;
+struct icst307_params;
+
+struct clk {
+ struct list_head node;
+ unsigned long rate;
+ struct module *owner;
+ const char *name;
+ const struct icst307_params *params;
+ void *data;
+ void (*setvco)(struct clk *, struct icst307_vco vco);
+};
+
+int clk_register(struct clk *clk);
+void clk_unregister(struct clk *clk);
diff --git a/arch/arm/mach-realview/core.c b/arch/arm/mach-realview/core.c
new file mode 100644
index 000000000000..e2c6fa23d3cd
--- /dev/null
+++ b/arch/arm/mach-realview/core.c
@@ -0,0 +1,610 @@
+/*
+ * linux/arch/arm/mach-realview/core.c
+ *
+ * Copyright (C) 1999 - 2003 ARM Limited
+ * Copyright (C) 2000 Deep Blue Solutions Ltd
+ *
+ * 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/config.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+#include <linux/sysdev.h>
+#include <linux/interrupt.h>
+
+#include <asm/system.h>
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/leds.h>
+#include <asm/mach-types.h>
+#include <asm/hardware/amba.h>
+#include <asm/hardware/amba_clcd.h>
+#include <asm/hardware/arm_timer.h>
+#include <asm/hardware/icst307.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/flash.h>
+#include <asm/mach/irq.h>
+#include <asm/mach/time.h>
+#include <asm/mach/map.h>
+#include <asm/mach/mmc.h>
+
+#include <asm/hardware/gic.h>
+
+#include "core.h"
+#include "clock.h"
+
+#define REALVIEW_REFCOUNTER (__io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_24MHz_OFFSET)
+
+/*
+ * This is the RealView sched_clock implementation. This has
+ * a resolution of 41.7ns, and a maximum value of about 179s.
+ */
+unsigned long long sched_clock(void)
+{
+ unsigned long long v;
+
+ v = (unsigned long long)readl(REALVIEW_REFCOUNTER) * 125;
+ do_div(v, 3);
+
+ return v;
+}
+
+
+#define REALVIEW_FLASHCTRL (__io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_FLASH_OFFSET)
+
+static int realview_flash_init(void)
+{
+ u32 val;
+
+ val = __raw_readl(REALVIEW_FLASHCTRL);
+ val &= ~REALVIEW_FLASHPROG_FLVPPEN;
+ __raw_writel(val, REALVIEW_FLASHCTRL);
+
+ return 0;
+}
+
+static void realview_flash_exit(void)
+{
+ u32 val;
+
+ val = __raw_readl(REALVIEW_FLASHCTRL);
+ val &= ~REALVIEW_FLASHPROG_FLVPPEN;
+ __raw_writel(val, REALVIEW_FLASHCTRL);
+}
+
+static void realview_flash_set_vpp(int on)
+{
+ u32 val;
+
+ val = __raw_readl(REALVIEW_FLASHCTRL);
+ if (on)
+ val |= REALVIEW_FLASHPROG_FLVPPEN;
+ else
+ val &= ~REALVIEW_FLASHPROG_FLVPPEN;
+ __raw_writel(val, REALVIEW_FLASHCTRL);
+}
+
+static struct flash_platform_data realview_flash_data = {
+ .map_name = "cfi_probe",
+ .width = 4,
+ .init = realview_flash_init,
+ .exit = realview_flash_exit,
+ .set_vpp = realview_flash_set_vpp,
+};
+
+static struct resource realview_flash_resource = {
+ .start = REALVIEW_FLASH_BASE,
+ .end = REALVIEW_FLASH_BASE + REALVIEW_FLASH_SIZE,
+ .flags = IORESOURCE_MEM,
+};
+
+struct platform_device realview_flash_device = {
+ .name = "armflash",
+ .id = 0,
+ .dev = {
+ .platform_data = &realview_flash_data,
+ },
+ .num_resources = 1,
+ .resource = &realview_flash_resource,
+};
+
+static struct resource realview_smc91x_resources[] = {
+ [0] = {
+ .start = REALVIEW_ETH_BASE,
+ .end = REALVIEW_ETH_BASE + SZ_64K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_ETH,
+ .end = IRQ_ETH,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device realview_smc91x_device = {
+ .name = "smc91x",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(realview_smc91x_resources),
+ .resource = realview_smc91x_resources,
+};
+
+#define REALVIEW_SYSMCI (__io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_MCI_OFFSET)
+
+static unsigned int realview_mmc_status(struct device *dev)
+{
+ struct amba_device *adev = container_of(dev, struct amba_device, dev);
+ u32 mask;
+
+ if (adev->res.start == REALVIEW_MMCI0_BASE)
+ mask = 1;
+ else
+ mask = 2;
+
+ return readl(REALVIEW_SYSMCI) & mask;
+}
+
+struct mmc_platform_data realview_mmc0_plat_data = {
+ .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34,
+ .status = realview_mmc_status,
+};
+
+struct mmc_platform_data realview_mmc1_plat_data = {
+ .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34,
+ .status = realview_mmc_status,
+};
+
+/*
+ * Clock handling
+ */
+static const struct icst307_params realview_oscvco_params = {
+ .ref = 24000,
+ .vco_max = 200000,
+ .vd_min = 4 + 8,
+ .vd_max = 511 + 8,
+ .rd_min = 1 + 2,
+ .rd_max = 127 + 2,
+};
+
+static void realview_oscvco_set(struct clk *clk, struct icst307_vco vco)
+{
+ void __iomem *sys_lock = __io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_LOCK_OFFSET;
+ void __iomem *sys_osc = __io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_OSC1_OFFSET;
+ u32 val;
+
+ val = readl(sys_osc) & ~0x7ffff;
+ val |= vco.v | (vco.r << 9) | (vco.s << 16);
+
+ writel(0xa05f, sys_lock);
+ writel(val, sys_osc);
+ writel(0, sys_lock);
+}
+
+struct clk realview_clcd_clk = {
+ .name = "CLCDCLK",
+ .params = &realview_oscvco_params,
+ .setvco = realview_oscvco_set,
+};
+
+/*
+ * CLCD support.
+ */
+#define SYS_CLCD_MODE_MASK (3 << 0)
+#define SYS_CLCD_MODE_888 (0 << 0)
+#define SYS_CLCD_MODE_5551 (1 << 0)
+#define SYS_CLCD_MODE_565_RLSB (2 << 0)
+#define SYS_CLCD_MODE_565_BLSB (3 << 0)
+#define SYS_CLCD_NLCDIOON (1 << 2)
+#define SYS_CLCD_VDDPOSSWITCH (1 << 3)
+#define SYS_CLCD_PWR3V5SWITCH (1 << 4)
+#define SYS_CLCD_ID_MASK (0x1f << 8)
+#define SYS_CLCD_ID_SANYO_3_8 (0x00 << 8)
+#define SYS_CLCD_ID_UNKNOWN_8_4 (0x01 << 8)
+#define SYS_CLCD_ID_EPSON_2_2 (0x02 << 8)
+#define SYS_CLCD_ID_SANYO_2_5 (0x07 << 8)
+#define SYS_CLCD_ID_VGA (0x1f << 8)
+
+static struct clcd_panel vga = {
+ .mode = {
+ .name = "VGA",
+ .refresh = 60,
+ .xres = 640,
+ .yres = 480,
+ .pixclock = 39721,
+ .left_margin = 40,
+ .right_margin = 24,
+ .upper_margin = 32,
+ .lower_margin = 11,
+ .hsync_len = 96,
+ .vsync_len = 2,
+ .sync = 0,
+ .vmode = FB_VMODE_NONINTERLACED,
+ },
+ .width = -1,
+ .height = -1,
+ .tim2 = TIM2_BCD | TIM2_IPC,
+ .cntl = CNTL_LCDTFT | CNTL_LCDVCOMP(1),
+ .bpp = 16,
+};
+
+static struct clcd_panel sanyo_3_8_in = {
+ .mode = {
+ .name = "Sanyo QVGA",
+ .refresh = 116,
+ .xres = 320,
+ .yres = 240,
+ .pixclock = 100000,
+ .left_margin = 6,
+ .right_margin = 6,
+ .upper_margin = 5,
+ .lower_margin = 5,
+ .hsync_len = 6,
+ .vsync_len = 6,
+ .sync = 0,
+ .vmode = FB_VMODE_NONINTERLACED,
+ },
+ .width = -1,
+ .height = -1,
+ .tim2 = TIM2_BCD,
+ .cntl = CNTL_LCDTFT | CNTL_LCDVCOMP(1),
+ .bpp = 16,
+};
+
+static struct clcd_panel sanyo_2_5_in = {
+ .mode = {
+ .name = "Sanyo QVGA Portrait",
+ .refresh = 116,
+ .xres = 240,
+ .yres = 320,
+ .pixclock = 100000,
+ .left_margin = 20,
+ .right_margin = 10,
+ .upper_margin = 2,
+ .lower_margin = 2,
+ .hsync_len = 10,
+ .vsync_len = 2,
+ .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+ .vmode = FB_VMODE_NONINTERLACED,
+ },
+ .width = -1,
+ .height = -1,
+ .tim2 = TIM2_IVS | TIM2_IHS | TIM2_IPC,
+ .cntl = CNTL_LCDTFT | CNTL_LCDVCOMP(1),
+ .bpp = 16,
+};
+
+static struct clcd_panel epson_2_2_in = {
+ .mode = {
+ .name = "Epson QCIF",
+ .refresh = 390,
+ .xres = 176,
+ .yres = 220,
+ .pixclock = 62500,
+ .left_margin = 3,
+ .right_margin = 2,
+ .upper_margin = 1,
+ .lower_margin = 0,
+ .hsync_len = 3,
+ .vsync_len = 2,
+ .sync = 0,
+ .vmode = FB_VMODE_NONINTERLACED,
+ },
+ .width = -1,
+ .height = -1,
+ .tim2 = TIM2_BCD | TIM2_IPC,
+ .cntl = CNTL_LCDTFT | CNTL_LCDVCOMP(1),
+ .bpp = 16,
+};
+
+/*
+ * Detect which LCD panel is connected, and return the appropriate
+ * clcd_panel structure. Note: we do not have any information on
+ * the required timings for the 8.4in panel, so we presently assume
+ * VGA timings.
+ */
+static struct clcd_panel *realview_clcd_panel(void)
+{
+ void __iomem *sys_clcd = __io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_CLCD_OFFSET;
+ struct clcd_panel *panel = &vga;
+ u32 val;
+
+ val = readl(sys_clcd) & SYS_CLCD_ID_MASK;
+ if (val == SYS_CLCD_ID_SANYO_3_8)
+ panel = &sanyo_3_8_in;
+ else if (val == SYS_CLCD_ID_SANYO_2_5)
+ panel = &sanyo_2_5_in;
+ else if (val == SYS_CLCD_ID_EPSON_2_2)
+ panel = &epson_2_2_in;
+ else if (val == SYS_CLCD_ID_VGA)
+ panel = &vga;
+ else {
+ printk(KERN_ERR "CLCD: unknown LCD panel ID 0x%08x, using VGA\n",
+ val);
+ panel = &vga;
+ }
+
+ return panel;
+}
+
+/*
+ * Disable all display connectors on the interface module.
+ */
+static void realview_clcd_disable(struct clcd_fb *fb)
+{
+ void __iomem *sys_clcd = __io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_CLCD_OFFSET;
+ u32 val;
+
+ val = readl(sys_clcd);
+ val &= ~SYS_CLCD_NLCDIOON | SYS_CLCD_PWR3V5SWITCH;
+ writel(val, sys_clcd);
+}
+
+/*
+ * Enable the relevant connector on the interface module.
+ */
+static void realview_clcd_enable(struct clcd_fb *fb)
+{
+ void __iomem *sys_clcd = __io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_CLCD_OFFSET;
+ u32 val;
+
+ val = readl(sys_clcd);
+ val &= ~SYS_CLCD_MODE_MASK;
+
+ switch (fb->fb.var.green.length) {
+ case 5:
+ val |= SYS_CLCD_MODE_5551;
+ break;
+ case 6:
+ val |= SYS_CLCD_MODE_565_RLSB;
+ break;
+ case 8:
+ val |= SYS_CLCD_MODE_888;
+ break;
+ }
+
+ /*
+ * Set the MUX
+ */
+ writel(val, sys_clcd);
+
+ /*
+ * And now enable the PSUs
+ */
+ val |= SYS_CLCD_NLCDIOON | SYS_CLCD_PWR3V5SWITCH;
+ writel(val, sys_clcd);
+}
+
+static unsigned long framesize = SZ_1M;
+
+static int realview_clcd_setup(struct clcd_fb *fb)
+{
+ dma_addr_t dma;
+
+ fb->panel = realview_clcd_panel();
+
+ fb->fb.screen_base = dma_alloc_writecombine(&fb->dev->dev, framesize,
+ &dma, GFP_KERNEL);
+ if (!fb->fb.screen_base) {
+ printk(KERN_ERR "CLCD: unable to map framebuffer\n");
+ return -ENOMEM;
+ }
+
+ fb->fb.fix.smem_start = dma;
+ fb->fb.fix.smem_len = framesize;
+
+ return 0;
+}
+
+static int realview_clcd_mmap(struct clcd_fb *fb, struct vm_area_struct *vma)
+{
+ return dma_mmap_writecombine(&fb->dev->dev, vma,
+ fb->fb.screen_base,
+ fb->fb.fix.smem_start,
+ fb->fb.fix.smem_len);
+}
+
+static void realview_clcd_remove(struct clcd_fb *fb)
+{
+ dma_free_writecombine(&fb->dev->dev, fb->fb.fix.smem_len,
+ fb->fb.screen_base, fb->fb.fix.smem_start);
+}
+
+struct clcd_board clcd_plat_data = {
+ .name = "RealView",
+ .check = clcdfb_check,
+ .decode = clcdfb_decode,
+ .disable = realview_clcd_disable,
+ .enable = realview_clcd_enable,
+ .setup = realview_clcd_setup,
+ .mmap = realview_clcd_mmap,
+ .remove = realview_clcd_remove,
+};
+
+#ifdef CONFIG_LEDS
+#define VA_LEDS_BASE (__io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_LED_OFFSET)
+
+void realview_leds_event(led_event_t ledevt)
+{
+ unsigned long flags;
+ u32 val;
+
+ local_irq_save(flags);
+ val = readl(VA_LEDS_BASE);
+
+ switch (ledevt) {
+ case led_idle_start:
+ val = val & ~REALVIEW_SYS_LED0;
+ break;
+
+ case led_idle_end:
+ val = val | REALVIEW_SYS_LED0;
+ break;
+
+ case led_timer:
+ val = val ^ REALVIEW_SYS_LED1;
+ break;
+
+ case led_halted:
+ val = 0;
+ break;
+
+ default:
+ break;
+ }
+
+ writel(val, VA_LEDS_BASE);
+ local_irq_restore(flags);
+}
+#endif /* CONFIG_LEDS */
+
+/*
+ * Where is the timer (VA)?
+ */
+#define TIMER0_VA_BASE __io_address(REALVIEW_TIMER0_1_BASE)
+#define TIMER1_VA_BASE (__io_address(REALVIEW_TIMER0_1_BASE) + 0x20)
+#define TIMER2_VA_BASE __io_address(REALVIEW_TIMER2_3_BASE)
+#define TIMER3_VA_BASE (__io_address(REALVIEW_TIMER2_3_BASE) + 0x20)
+
+/*
+ * How long is the timer interval?
+ */
+#define TIMER_INTERVAL (TICKS_PER_uSEC * mSEC_10)
+#if TIMER_INTERVAL >= 0x100000
+#define TIMER_RELOAD (TIMER_INTERVAL >> 8)
+#define TIMER_DIVISOR (TIMER_CTRL_DIV256)
+#define TICKS2USECS(x) (256 * (x) / TICKS_PER_uSEC)
+#elif TIMER_INTERVAL >= 0x10000
+#define TIMER_RELOAD (TIMER_INTERVAL >> 4) /* Divide by 16 */
+#define TIMER_DIVISOR (TIMER_CTRL_DIV16)
+#define TICKS2USECS(x) (16 * (x) / TICKS_PER_uSEC)
+#else
+#define TIMER_RELOAD (TIMER_INTERVAL)
+#define TIMER_DIVISOR (TIMER_CTRL_DIV1)
+#define TICKS2USECS(x) ((x) / TICKS_PER_uSEC)
+#endif
+
+/*
+ * Returns number of ms since last clock interrupt. Note that interrupts
+ * will have been disabled by do_gettimeoffset()
+ */
+static unsigned long realview_gettimeoffset(void)
+{
+ unsigned long ticks1, ticks2, status;
+
+ /*
+ * Get the current number of ticks. Note that there is a race
+ * condition between us reading the timer and checking for
+ * an interrupt. We get around this by ensuring that the
+ * counter has not reloaded between our two reads.
+ */
+ ticks2 = readl(TIMER0_VA_BASE + TIMER_VALUE) & 0xffff;
+ do {
+ ticks1 = ticks2;
+ status = __raw_readl(__io_address(REALVIEW_GIC_DIST_BASE + GIC_DIST_PENDING_SET)
+ + ((IRQ_TIMERINT0_1 >> 5) << 2));
+ ticks2 = readl(TIMER0_VA_BASE + TIMER_VALUE) & 0xffff;
+ } while (ticks2 > ticks1);
+
+ /*
+ * Number of ticks since last interrupt.
+ */
+ ticks1 = TIMER_RELOAD - ticks2;
+
+ /*
+ * Interrupt pending? If so, we've reloaded once already.
+ *
+ * FIXME: Need to check this is effectively timer 0 that expires
+ */
+ if (status & IRQMASK_TIMERINT0_1)
+ ticks1 += TIMER_RELOAD;
+
+ /*
+ * Convert the ticks to usecs
+ */
+ return TICKS2USECS(ticks1);
+}
+
+/*
+ * IRQ handler for the timer
+ */
+static irqreturn_t realview_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+ write_seqlock(&xtime_lock);
+
+ // ...clear the interrupt
+ writel(1, TIMER0_VA_BASE + TIMER_INTCLR);
+
+ timer_tick(regs);
+
+#if defined(CONFIG_SMP) && !defined(CONFIG_LOCAL_TIMERS)
+ smp_send_timer();
+ update_process_times(user_mode(regs));
+#endif
+
+ write_sequnlock(&xtime_lock);
+
+ return IRQ_HANDLED;
+}
+
+static struct irqaction realview_timer_irq = {
+ .name = "RealView Timer Tick",
+ .flags = SA_INTERRUPT | SA_TIMER,
+ .handler = realview_timer_interrupt,
+};
+
+/*
+ * Set up timer interrupt, and return the current time in seconds.
+ */
+static void __init realview_timer_init(void)
+{
+ u32 val;
+
+ /*
+ * set clock frequency:
+ * REALVIEW_REFCLK is 32KHz
+ * REALVIEW_TIMCLK is 1MHz
+ */
+ val = readl(__io_address(REALVIEW_SCTL_BASE));
+ writel((REALVIEW_TIMCLK << REALVIEW_TIMER1_EnSel) |
+ (REALVIEW_TIMCLK << REALVIEW_TIMER2_EnSel) |
+ (REALVIEW_TIMCLK << REALVIEW_TIMER3_EnSel) |
+ (REALVIEW_TIMCLK << REALVIEW_TIMER4_EnSel) | val,
+ __io_address(REALVIEW_SCTL_BASE));
+
+ /*
+ * Initialise to a known state (all timers off)
+ */
+ writel(0, TIMER0_VA_BASE + TIMER_CTRL);
+ writel(0, TIMER1_VA_BASE + TIMER_CTRL);
+ writel(0, TIMER2_VA_BASE + TIMER_CTRL);
+ writel(0, TIMER3_VA_BASE + TIMER_CTRL);
+
+ writel(TIMER_RELOAD, TIMER0_VA_BASE + TIMER_LOAD);
+ writel(TIMER_RELOAD, TIMER0_VA_BASE + TIMER_VALUE);
+ writel(TIMER_DIVISOR | TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC |
+ TIMER_CTRL_IE, TIMER0_VA_BASE + TIMER_CTRL);
+
+ /*
+ * Make irqs happen for the system timer
+ */
+ setup_irq(IRQ_TIMERINT0_1, &realview_timer_irq);
+}
+
+struct sys_timer realview_timer = {
+ .init = realview_timer_init,
+ .offset = realview_gettimeoffset,
+};
diff --git a/arch/arm/mach-realview/core.h b/arch/arm/mach-realview/core.h
new file mode 100644
index 000000000000..d83e8bad2038
--- /dev/null
+++ b/arch/arm/mach-realview/core.h
@@ -0,0 +1,119 @@
+/*
+ * linux/arch/arm/mach-realview/core.h
+ *
+ * Copyright (C) 2004 ARM Limited
+ * Copyright (C) 2000 Deep Blue Solutions Ltd
+ *
+ * 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 __ASM_ARCH_REALVIEW_H
+#define __ASM_ARCH_REALVIEW_H
+
+#include <asm/hardware/amba.h>
+#include <asm/leds.h>
+#include <asm/io.h>
+
+#define __io_address(n) __io(IO_ADDRESS(n))
+
+extern struct sys_timer realview_timer;
+
+#define AMBA_DEVICE(name,busid,base,plat) \
+static struct amba_device name##_device = { \
+ .dev = { \
+ .coherent_dma_mask = ~0, \
+ .bus_id = busid, \
+ .platform_data = plat, \
+ }, \
+ .res = { \
+ .start = REALVIEW_##base##_BASE, \
+ .end = (REALVIEW_##base##_BASE) + SZ_4K - 1,\
+ .flags = IORESOURCE_MEM, \
+ }, \
+ .dma_mask = ~0, \
+ .irq = base##_IRQ, \
+ /* .dma = base##_DMA,*/ \
+}
+
+/*
+ * These devices are connected via the core APB bridge
+ */
+#define GPIO2_IRQ { IRQ_GPIOINT2, NO_IRQ }
+#define GPIO2_DMA { 0, 0 }
+#define GPIO3_IRQ { IRQ_GPIOINT3, NO_IRQ }
+#define GPIO3_DMA { 0, 0 }
+
+#define AACI_IRQ { IRQ_AACI, NO_IRQ }
+#define AACI_DMA { 0x80, 0x81 }
+#define MMCI0_IRQ { IRQ_MMCI0A,IRQ_MMCI0B }
+#define MMCI0_DMA { 0x84, 0 }
+#define KMI0_IRQ { IRQ_KMI0, NO_IRQ }
+#define KMI0_DMA { 0, 0 }
+#define KMI1_IRQ { IRQ_KMI1, NO_IRQ }
+#define KMI1_DMA { 0, 0 }
+
+/*
+ * These devices are connected directly to the multi-layer AHB switch
+ */
+#define SMC_IRQ { NO_IRQ, NO_IRQ }
+#define SMC_DMA { 0, 0 }
+#define MPMC_IRQ { NO_IRQ, NO_IRQ }
+#define MPMC_DMA { 0, 0 }
+#define CLCD_IRQ { IRQ_CLCDINT, NO_IRQ }
+#define CLCD_DMA { 0, 0 }
+#define DMAC_IRQ { IRQ_DMAINT, NO_IRQ }
+#define DMAC_DMA { 0, 0 }
+
+/*
+ * These devices are connected via the core APB bridge
+ */
+#define SCTL_IRQ { NO_IRQ, NO_IRQ }
+#define SCTL_DMA { 0, 0 }
+#define WATCHDOG_IRQ { IRQ_WDOGINT, NO_IRQ }
+#define WATCHDOG_DMA { 0, 0 }
+#define GPIO0_IRQ { IRQ_GPIOINT0, NO_IRQ }
+#define GPIO0_DMA { 0, 0 }
+#define GPIO1_IRQ { IRQ_GPIOINT1, NO_IRQ }
+#define GPIO1_DMA { 0, 0 }
+#define RTC_IRQ { IRQ_RTCINT, NO_IRQ }
+#define RTC_DMA { 0, 0 }
+
+/*
+ * These devices are connected via the DMA APB bridge
+ */
+#define SCI_IRQ { IRQ_SCIINT, NO_IRQ }
+#define SCI_DMA { 7, 6 }
+#define UART0_IRQ { IRQ_UARTINT0, NO_IRQ }
+#define UART0_DMA { 15, 14 }
+#define UART1_IRQ { IRQ_UARTINT1, NO_IRQ }
+#define UART1_DMA { 13, 12 }
+#define UART2_IRQ { IRQ_UARTINT2, NO_IRQ }
+#define UART2_DMA { 11, 10 }
+#define UART3_IRQ { IRQ_UART3, NO_IRQ }
+#define UART3_DMA { 0x86, 0x87 }
+#define SSP_IRQ { IRQ_SSPINT, NO_IRQ }
+#define SSP_DMA { 9, 8 }
+
+
+extern struct platform_device realview_flash_device;
+extern struct platform_device realview_smc91x_device;
+extern struct mmc_platform_data realview_mmc0_plat_data;
+extern struct mmc_platform_data realview_mmc1_plat_data;
+extern struct clk realview_clcd_clk;
+extern struct clcd_board clcd_plat_data;
+
+extern void realview_leds_event(led_event_t ledevt);
+
+#endif
diff --git a/arch/arm/mach-realview/headsmp.S b/arch/arm/mach-realview/headsmp.S
new file mode 100644
index 000000000000..4075473cf68a
--- /dev/null
+++ b/arch/arm/mach-realview/headsmp.S
@@ -0,0 +1,39 @@
+/*
+ * linux/arch/arm/mach-realview/headsmp.S
+ *
+ * Copyright (c) 2003 ARM Limited
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/linkage.h>
+#include <linux/init.h>
+
+ __INIT
+
+/*
+ * Realview specific entry point for secondary CPUs. This provides
+ * a "holding pen" into which all secondary cores are held until we're
+ * ready for them to initialise.
+ */
+ENTRY(realview_secondary_startup)
+ mrc p15, 0, r0, c0, c0, 5
+ and r0, r0, #15
+ adr r4, 1f
+ ldmia r4, {r5, r6}
+ sub r4, r4, r5
+ add r6, r6, r4
+pen: ldr r7, [r6]
+ cmp r7, r0
+ bne pen
+
+ /*
+ * we've been released from the holding pen: secondary_stack
+ * should now contain the SVC stack for this core
+ */
+ b secondary_startup
+
+1: .long .
+ .long pen_release
diff --git a/arch/arm/mach-realview/hotplug.c b/arch/arm/mach-realview/hotplug.c
new file mode 100644
index 000000000000..09748cbcd10e
--- /dev/null
+++ b/arch/arm/mach-realview/hotplug.c
@@ -0,0 +1,138 @@
+/*
+ * linux/arch/arm/mach-realview/hotplug.c
+ *
+ * Copyright (C) 2002 ARM Ltd.
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/smp.h>
+#include <linux/completion.h>
+
+extern volatile int pen_release;
+
+static DECLARE_COMPLETION(cpu_killed);
+
+static inline void cpu_enter_lowpower(void)
+{
+ unsigned int v;
+
+ asm volatile( "mcr p15, 0, %1, c7, c14, 0\n"
+ " mcr p15, 0, %1, c7, c5, 0\n"
+ " mcr p15, 0, %1, c7, c10, 4\n"
+ /*
+ * Turn off coherency
+ */
+ " mrc p15, 0, %0, c1, c0, 1\n"
+ " bic %0, %0, #0x20\n"
+ " mcr p15, 0, %0, c1, c0, 1\n"
+ " mrc p15, 0, %0, c1, c0, 0\n"
+ " bic %0, %0, #0x04\n"
+ " mcr p15, 0, %0, c1, c0, 0\n"
+ : "=&r" (v)
+ : "r" (0)
+ : "cc");
+}
+
+static inline void cpu_leave_lowpower(void)
+{
+ unsigned int v;
+
+ asm volatile( "mrc p15, 0, %0, c1, c0, 0\n"
+ " orr %0, %0, #0x04\n"
+ " mcr p15, 0, %0, c1, c0, 0\n"
+ " mrc p15, 0, %0, c1, c0, 1\n"
+ " orr %0, %0, #0x20\n"
+ " mcr p15, 0, %0, c1, c0, 1\n"
+ : "=&r" (v)
+ :
+ : "cc");
+}
+
+static inline void platform_do_lowpower(unsigned int cpu)
+{
+ /*
+ * there is no power-control hardware on this platform, so all
+ * we can do is put the core into WFI; this is safe as the calling
+ * code will have already disabled interrupts
+ */
+ for (;;) {
+ /*
+ * here's the WFI
+ */
+ asm(".word 0xe320f003\n"
+ :
+ :
+ : "memory", "cc");
+
+ if (pen_release == cpu) {
+ /*
+ * OK, proper wakeup, we're done
+ */
+ break;
+ }
+
+ /*
+ * getting here, means that we have come out of WFI without
+ * having been woken up - this shouldn't happen
+ *
+ * The trouble is, letting people know about this is not really
+ * possible, since we are currently running incoherently, and
+ * therefore cannot safely call printk() or anything else
+ */
+#ifdef DEBUG
+ printk("CPU%u: spurious wakeup call\n", cpu);
+#endif
+ }
+}
+
+int platform_cpu_kill(unsigned int cpu)
+{
+ return wait_for_completion_timeout(&cpu_killed, 5000);
+}
+
+/*
+ * platform-specific code to shutdown a CPU
+ *
+ * Called with IRQs disabled
+ */
+void platform_cpu_die(unsigned int cpu)
+{
+#ifdef DEBUG
+ unsigned int this_cpu = hard_smp_processor_id();
+
+ if (cpu != this_cpu) {
+ printk(KERN_CRIT "Eek! platform_cpu_die running on %u, should be %u\n",
+ this_cpu, cpu);
+ BUG();
+ }
+#endif
+
+ printk(KERN_NOTICE "CPU%u: shutdown\n", cpu);
+ complete(&cpu_killed);
+
+ /*
+ * we're ready for shutdown now, so do it
+ */
+ cpu_enter_lowpower();
+ platform_do_lowpower(cpu);
+
+ /*
+ * bring this CPU back into the world of cache
+ * coherency, and then restore interrupts
+ */
+ cpu_leave_lowpower();
+}
+
+int mach_cpu_disable(unsigned int cpu)
+{
+ /*
+ * we don't allow CPU 0 to be shutdown (it is still too special
+ * e.g. clock tick interrupts)
+ */
+ return cpu == 0 ? -EPERM : 0;
+}
diff --git a/arch/arm/mach-realview/localtimer.c b/arch/arm/mach-realview/localtimer.c
new file mode 100644
index 000000000000..5e917e37d095
--- /dev/null
+++ b/arch/arm/mach-realview/localtimer.c
@@ -0,0 +1,130 @@
+/*
+ * linux/arch/arm/mach-realview/localtimer.c
+ *
+ * Copyright (C) 2002 ARM Ltd.
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/smp.h>
+
+#include <asm/mach/time.h>
+#include <asm/hardware/arm_twd.h>
+#include <asm/hardware/gic.h>
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+
+#include "core.h"
+
+#define TWD_BASE(cpu) (__io_address(REALVIEW_TWD_BASE) + \
+ ((cpu) * REALVIEW_TWD_SIZE))
+
+static unsigned long mpcore_timer_rate;
+
+/*
+ * local_timer_ack: checks for a local timer interrupt.
+ *
+ * If a local timer interrupt has occured, acknowledge and return 1.
+ * Otherwise, return 0.
+ */
+int local_timer_ack(void)
+{
+ void __iomem *base = TWD_BASE(smp_processor_id());
+
+ if (__raw_readl(base + TWD_TIMER_INTSTAT)) {
+ __raw_writel(1, base + TWD_TIMER_INTSTAT);
+ return 1;
+ }
+
+ return 0;
+}
+
+void __cpuinit local_timer_setup(unsigned int cpu)
+{
+ void __iomem *base = TWD_BASE(cpu);
+ unsigned int load, offset;
+ u64 waitjiffies;
+ unsigned int count;
+
+ /*
+ * If this is the first time round, we need to work out how fast
+ * the timer ticks
+ */
+ if (mpcore_timer_rate == 0) {
+ printk("Calibrating local timer... ");
+
+ /* Wait for a tick to start */
+ waitjiffies = get_jiffies_64() + 1;
+
+ while (get_jiffies_64() < waitjiffies)
+ udelay(10);
+
+ /* OK, now the tick has started, let's get the timer going */
+ waitjiffies += 5;
+
+ /* enable, no interrupt or reload */
+ __raw_writel(0x1, base + TWD_TIMER_CONTROL);
+
+ /* maximum value */
+ __raw_writel(0xFFFFFFFFU, base + TWD_TIMER_COUNTER);
+
+ while (get_jiffies_64() < waitjiffies)
+ udelay(10);
+
+ count = __raw_readl(base + TWD_TIMER_COUNTER);
+
+ mpcore_timer_rate = (0xFFFFFFFFU - count) * (HZ / 5);
+
+ printk("%lu.%02luMHz.\n", mpcore_timer_rate / 1000000,
+ (mpcore_timer_rate / 100000) % 100);
+ }
+
+ load = mpcore_timer_rate / HZ;
+
+ __raw_writel(load, base + TWD_TIMER_LOAD);
+ __raw_writel(0x7, base + TWD_TIMER_CONTROL);
+
+ /*
+ * Now maneuver our local tick into the right part of the jiffy.
+ * Start by working out where within the tick our local timer
+ * interrupt should go.
+ */
+ offset = ((mpcore_timer_rate / HZ) / (NR_CPUS + 1)) * (cpu + 1);
+
+ /*
+ * gettimeoffset() will return a number of us since the last tick.
+ * Convert this number of us to a local timer tick count.
+ * Be careful of integer overflow whilst keeping maximum precision.
+ *
+ * with HZ=100 and 1MHz (fpga) ~ 1GHz processor:
+ * load = 1 ~ 10,000
+ * mpcore_timer_rate/10000 = 100 ~ 100,000
+ *
+ * so the multiply value will be less than 10^9 always.
+ */
+ load = (system_timer->offset() * (mpcore_timer_rate / 10000)) / 100;
+
+ /* Add on our offset to get the load value */
+ load = (load + offset) % (mpcore_timer_rate / HZ);
+
+ __raw_writel(load, base + TWD_TIMER_COUNTER);
+
+ /* Make sure our local interrupt controller has this enabled */
+ __raw_writel(1 << IRQ_LOCALTIMER,
+ __io_address(REALVIEW_GIC_DIST_BASE) + GIC_DIST_ENABLE_SET);
+}
+
+/*
+ * take a local timer down
+ */
+void __cpuexit local_timer_stop(unsigned int cpu)
+{
+ __raw_writel(0, TWD_BASE(cpu) + TWD_TIMER_CONTROL);
+}
diff --git a/arch/arm/mach-realview/platsmp.c b/arch/arm/mach-realview/platsmp.c
new file mode 100644
index 000000000000..0c7d4ac9a7b3
--- /dev/null
+++ b/arch/arm/mach-realview/platsmp.c
@@ -0,0 +1,200 @@
+/*
+ * linux/arch/arm/mach-realview/platsmp.c
+ *
+ * Copyright (C) 2002 ARM Ltd.
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/smp.h>
+
+#include <asm/cacheflush.h>
+#include <asm/hardware/arm_scu.h>
+#include <asm/hardware.h>
+
+#include "core.h"
+
+extern void realview_secondary_startup(void);
+
+/*
+ * control for which core is the next to come out of the secondary
+ * boot "holding pen"
+ */
+volatile int __cpuinitdata pen_release = -1;
+
+static unsigned int __init get_core_count(void)
+{
+ unsigned int ncores;
+
+ ncores = __raw_readl(__io_address(REALVIEW_MPCORE_SCU_BASE) + SCU_CONFIG);
+
+ return (ncores & 0x03) + 1;
+}
+
+static DEFINE_SPINLOCK(boot_lock);
+
+void __cpuinit platform_secondary_init(unsigned int cpu)
+{
+ /*
+ * the primary core may have used a "cross call" soft interrupt
+ * to get this processor out of WFI in the BootMonitor - make
+ * sure that we are no longer being sent this soft interrupt
+ */
+ smp_cross_call_done(cpumask_of_cpu(cpu));
+
+ /*
+ * if any interrupts are already enabled for the primary
+ * core (e.g. timer irq), then they will not have been enabled
+ * for us: do so
+ */
+ gic_cpu_init(__io_address(REALVIEW_GIC_CPU_BASE));
+
+ /*
+ * let the primary processor know we're out of the
+ * pen, then head off into the C entry point
+ */
+ pen_release = -1;
+
+ /*
+ * Synchronise with the boot thread.
+ */
+ spin_lock(&boot_lock);
+ spin_unlock(&boot_lock);
+}
+
+int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
+{
+ unsigned long timeout;
+
+ /*
+ * set synchronisation state between this boot processor
+ * and the secondary one
+ */
+ spin_lock(&boot_lock);
+
+ /*
+ * The secondary processor is waiting to be released from
+ * the holding pen - release it, then wait for it to flag
+ * that it has been released by resetting pen_release.
+ *
+ * Note that "pen_release" is the hardware CPU ID, whereas
+ * "cpu" is Linux's internal ID.
+ */
+ pen_release = cpu;
+ flush_cache_all();
+
+ /*
+ * XXX
+ *
+ * This is a later addition to the booting protocol: the
+ * bootMonitor now puts secondary cores into WFI, so
+ * poke_milo() no longer gets the cores moving; we need
+ * to send a soft interrupt to wake the secondary core.
+ * Use smp_cross_call() for this, since there's little
+ * point duplicating the code here
+ */
+ smp_cross_call(cpumask_of_cpu(cpu));
+
+ timeout = jiffies + (1 * HZ);
+ while (time_before(jiffies, timeout)) {
+ if (pen_release == -1)
+ break;
+
+ udelay(10);
+ }
+
+ /*
+ * now the secondary core is starting up let it run its
+ * calibrations, then wait for it to finish
+ */
+ spin_unlock(&boot_lock);
+
+ return pen_release != -1 ? -ENOSYS : 0;
+}
+
+static void __init poke_milo(void)
+{
+ extern void secondary_startup(void);
+
+ /* nobody is to be released from the pen yet */
+ pen_release = -1;
+
+ /*
+ * write the address of secondary startup into the system-wide
+ * flags register, then clear the bottom two bits, which is what
+ * BootMonitor is waiting for
+ */
+#if 1
+#define REALVIEW_SYS_FLAGSS_OFFSET 0x30
+ __raw_writel(virt_to_phys(realview_secondary_startup),
+ __io_address(REALVIEW_SYS_BASE) +
+ REALVIEW_SYS_FLAGSS_OFFSET);
+#define REALVIEW_SYS_FLAGSC_OFFSET 0x34
+ __raw_writel(3,
+ __io_address(REALVIEW_SYS_BASE) +
+ REALVIEW_SYS_FLAGSC_OFFSET);
+#endif
+
+ mb();
+}
+
+void __init smp_prepare_cpus(unsigned int max_cpus)
+{
+ unsigned int ncores = get_core_count();
+ unsigned int cpu = smp_processor_id();
+ int i;
+
+ /* sanity check */
+ if (ncores == 0) {
+ printk(KERN_ERR
+ "Realview: strange CM count of 0? Default to 1\n");
+
+ ncores = 1;
+ }
+
+ if (ncores > NR_CPUS) {
+ printk(KERN_WARNING
+ "Realview: no. of cores (%d) greater than configured "
+ "maximum of %d - clipping\n",
+ ncores, NR_CPUS);
+ ncores = NR_CPUS;
+ }
+
+ smp_store_cpu_info(cpu);
+
+ /*
+ * are we trying to boot more cores than exist?
+ */
+ if (max_cpus > ncores)
+ max_cpus = ncores;
+
+ /*
+ * Enable the local timer for primary CPU
+ */
+ local_timer_setup(cpu);
+
+ /*
+ * Initialise the possible/present maps.
+ * cpu_possible_map describes the set of CPUs which may be present
+ * cpu_present_map describes the set of CPUs populated
+ */
+ for (i = 0; i < max_cpus; i++) {
+ cpu_set(i, cpu_possible_map);
+ cpu_set(i, cpu_present_map);
+ }
+
+ /*
+ * Do we need any more CPUs? If so, then let them know where
+ * to start. Note that, on modern versions of MILO, the "poke"
+ * doesn't actually do anything until each individual core is
+ * sent a soft interrupt to get it out of WFI
+ */
+ if (max_cpus > 1)
+ poke_milo();
+}
diff --git a/arch/arm/mach-realview/realview_eb.c b/arch/arm/mach-realview/realview_eb.c
new file mode 100644
index 000000000000..7dc32503fdf2
--- /dev/null
+++ b/arch/arm/mach-realview/realview_eb.c
@@ -0,0 +1,177 @@
+/*
+ * linux/arch/arm/mach-realview/realview_eb.c
+ *
+ * Copyright (C) 2004 ARM Limited
+ * Copyright (C) 2000 Deep Blue Solutions Ltd
+ *
+ * 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/config.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/sysdev.h>
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/leds.h>
+#include <asm/mach-types.h>
+#include <asm/hardware/gic.h>
+#include <asm/hardware/amba.h>
+#include <asm/hardware/icst307.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/mmc.h>
+
+#include <asm/arch/irqs.h>
+
+#include "core.h"
+#include "clock.h"
+
+static struct map_desc realview_eb_io_desc[] __initdata = {
+ {
+ .virtual = IO_ADDRESS(REALVIEW_SYS_BASE),
+ .pfn = __phys_to_pfn(REALVIEW_SYS_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = IO_ADDRESS(REALVIEW_GIC_CPU_BASE),
+ .pfn = __phys_to_pfn(REALVIEW_GIC_CPU_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = IO_ADDRESS(REALVIEW_GIC_DIST_BASE),
+ .pfn = __phys_to_pfn(REALVIEW_GIC_DIST_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = IO_ADDRESS(REALVIEW_SCTL_BASE),
+ .pfn = __phys_to_pfn(REALVIEW_SCTL_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = IO_ADDRESS(REALVIEW_TIMER0_1_BASE),
+ .pfn = __phys_to_pfn(REALVIEW_TIMER0_1_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = IO_ADDRESS(REALVIEW_TIMER2_3_BASE),
+ .pfn = __phys_to_pfn(REALVIEW_TIMER2_3_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ },
+#ifdef CONFIG_DEBUG_LL
+ {
+ .virtual = IO_ADDRESS(REALVIEW_UART0_BASE),
+ .pfn = __phys_to_pfn(REALVIEW_UART0_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }
+#endif
+};
+
+static void __init realview_eb_map_io(void)
+{
+ iotable_init(realview_eb_io_desc, ARRAY_SIZE(realview_eb_io_desc));
+}
+
+/* FPGA Primecells */
+AMBA_DEVICE(aaci, "fpga:04", AACI, NULL);
+AMBA_DEVICE(mmc0, "fpga:05", MMCI0, &realview_mmc0_plat_data);
+AMBA_DEVICE(kmi0, "fpga:06", KMI0, NULL);
+AMBA_DEVICE(kmi1, "fpga:07", KMI1, NULL);
+AMBA_DEVICE(uart3, "fpga:09", UART3, NULL);
+
+/* DevChip Primecells */
+AMBA_DEVICE(smc, "dev:00", SMC, NULL);
+AMBA_DEVICE(clcd, "dev:20", CLCD, &clcd_plat_data);
+AMBA_DEVICE(dmac, "dev:30", DMAC, NULL);
+AMBA_DEVICE(sctl, "dev:e0", SCTL, NULL);
+AMBA_DEVICE(wdog, "dev:e1", WATCHDOG, NULL);
+AMBA_DEVICE(gpio0, "dev:e4", GPIO0, NULL);
+AMBA_DEVICE(gpio1, "dev:e5", GPIO1, NULL);
+AMBA_DEVICE(gpio2, "dev:e6", GPIO2, NULL);
+AMBA_DEVICE(rtc, "dev:e8", RTC, NULL);
+AMBA_DEVICE(sci0, "dev:f0", SCI, NULL);
+AMBA_DEVICE(uart0, "dev:f1", UART0, NULL);
+AMBA_DEVICE(uart1, "dev:f2", UART1, NULL);
+AMBA_DEVICE(uart2, "dev:f3", UART2, NULL);
+AMBA_DEVICE(ssp0, "dev:f4", SSP, NULL);
+
+static struct amba_device *amba_devs[] __initdata = {
+ &dmac_device,
+ &uart0_device,
+ &uart1_device,
+ &uart2_device,
+ &uart3_device,
+ &smc_device,
+ &clcd_device,
+ &sctl_device,
+ &wdog_device,
+ &gpio0_device,
+ &gpio1_device,
+ &gpio2_device,
+ &rtc_device,
+ &sci0_device,
+ &ssp0_device,
+ &aaci_device,
+ &mmc0_device,
+ &kmi0_device,
+ &kmi1_device,
+};
+
+static void __init gic_init_irq(void)
+{
+#ifdef CONFIG_REALVIEW_MPCORE
+ writel(0x0000a05f, __io_address(REALVIEW_SYS_LOCK));
+ writel(0x008003c0, __io_address(REALVIEW_SYS_BASE) + 0xd8);
+ writel(0x00000000, __io_address(REALVIEW_SYS_LOCK));
+#endif
+ gic_dist_init(__io_address(REALVIEW_GIC_DIST_BASE));
+ gic_cpu_init(__io_address(REALVIEW_GIC_CPU_BASE));
+}
+
+static void __init realview_eb_init(void)
+{
+ int i;
+
+ clk_register(&realview_clcd_clk);
+
+ platform_device_register(&realview_flash_device);
+ platform_device_register(&realview_smc91x_device);
+
+ for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
+ struct amba_device *d = amba_devs[i];
+ amba_device_register(d, &iomem_resource);
+ }
+
+#ifdef CONFIG_LEDS
+ leds_event = realview_leds_event;
+#endif
+}
+
+MACHINE_START(REALVIEW_EB, "ARM-RealView EB")
+ /* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
+ .phys_ram = 0x00000000,
+ .phys_io = REALVIEW_UART0_BASE,
+ .io_pg_offst = (IO_ADDRESS(REALVIEW_UART0_BASE) >> 18) & 0xfffc,
+ .boot_params = 0x00000100,
+ .map_io = realview_eb_map_io,
+ .init_irq = gic_init_irq,
+ .timer = &realview_timer,
+ .init_machine = realview_eb_init,
+MACHINE_END
diff --git a/arch/arm/mach-rpc/riscpc.c b/arch/arm/mach-rpc/riscpc.c
index e3587efec4bf..5c4ac1c008a6 100644
--- a/arch/arm/mach-rpc/riscpc.c
+++ b/arch/arm/mach-rpc/riscpc.c
@@ -61,9 +61,22 @@ static int __init parse_tag_acorn(const struct tag *tag)
__tagtable(ATAG_ACORN, parse_tag_acorn);
static struct map_desc rpc_io_desc[] __initdata = {
- { SCREEN_BASE, SCREEN_START, 2*1048576, MT_DEVICE }, /* VRAM */
- { (u32)IO_BASE, IO_START, IO_SIZE , MT_DEVICE }, /* IO space */
- { EASI_BASE, EASI_START, EASI_SIZE, MT_DEVICE } /* EASI space */
+ { /* VRAM */
+ .virtual = SCREEN_BASE,
+ .pfn = __phys_to_pfn(SCREEN_START),
+ .length = 2*1048576,
+ .type = MT_DEVICE
+ }, { /* IO space */
+ .virtual = (u32)IO_BASE,
+ .pfn = __phys_to_pfn(IO_START),
+ .length = IO_SIZE ,
+ .type = MT_DEVICE
+ }, { /* EASI space */
+ .virtual = EASI_BASE,
+ .pfn = __phys_to_pfn(EASI_START),
+ .length = EASI_SIZE,
+ .type = MT_DEVICE
+ }
};
static void __init rpc_map_io(void)
diff --git a/arch/arm/mach-s3c2410/Kconfig b/arch/arm/mach-s3c2410/Kconfig
index c796bcdd6158..0b9d7ca49ec1 100644
--- a/arch/arm/mach-s3c2410/Kconfig
+++ b/arch/arm/mach-s3c2410/Kconfig
@@ -121,6 +121,14 @@ config S3C2410_BOOT_WATCHDOG
system resets depends on the value of PCLK. The timeout on an
200MHz s3c2410 should be about 30 seconds.
+config S3C2410_BOOT_ERROR_RESET
+ bool "S3C2410 Reboot on decompression error"
+ depends on ARCH_S3C2410
+ help
+ Say y here to use the watchdog to reset the system if the
+ kernel decompressor detects an error during decompression.
+
+
comment "S3C2410 Setup"
config S3C2410_DMA
diff --git a/arch/arm/mach-s3c2410/clock.c b/arch/arm/mach-s3c2410/clock.c
index 8b3d5dc35de5..82e8253b1fa0 100644
--- a/arch/arm/mach-s3c2410/clock.c
+++ b/arch/arm/mach-s3c2410/clock.c
@@ -32,7 +32,7 @@
#include <linux/list.h>
#include <linux/errno.h>
#include <linux/err.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <linux/sysdev.h>
#include <linux/interrupt.h>
diff --git a/arch/arm/mach-s3c2410/cpu.c b/arch/arm/mach-s3c2410/cpu.c
index ca366e9e264d..687fe371369d 100644
--- a/arch/arm/mach-s3c2410/cpu.c
+++ b/arch/arm/mach-s3c2410/cpu.c
@@ -26,7 +26,7 @@
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/ioport.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <asm/hardware.h>
#include <asm/irq.h>
diff --git a/arch/arm/mach-s3c2410/cpu.h b/arch/arm/mach-s3c2410/cpu.h
index 478c15c0e36a..9cbe5eef492b 100644
--- a/arch/arm/mach-s3c2410/cpu.h
+++ b/arch/arm/mach-s3c2410/cpu.h
@@ -21,7 +21,7 @@
/* todo - fix when rmk changes iodescs to use `void __iomem *` */
-#define IODESC_ENT(x) { (unsigned long)S3C24XX_VA_##x, S3C2410_PA_##x, S3C24XX_SZ_##x, MT_DEVICE }
+#define IODESC_ENT(x) { (unsigned long)S3C24XX_VA_##x, __phys_to_pfn(S3C2410_PA_##x), S3C24XX_SZ_##x, MT_DEVICE }
#ifndef MHZ
#define MHZ (1000*1000)
diff --git a/arch/arm/mach-s3c2410/devs.c b/arch/arm/mach-s3c2410/devs.c
index 0077937a7ab8..f58406e6ef5a 100644
--- a/arch/arm/mach-s3c2410/devs.c
+++ b/arch/arm/mach-s3c2410/devs.c
@@ -24,7 +24,7 @@
#include <linux/list.h>
#include <linux/timer.h>
#include <linux/init.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
@@ -47,7 +47,7 @@ struct platform_device *s3c24xx_uart_devs[3];
static struct resource s3c_usb_resource[] = {
[0] = {
.start = S3C2410_PA_USBHOST,
- .end = S3C2410_PA_USBHOST + S3C24XX_SZ_USBHOST,
+ .end = S3C2410_PA_USBHOST + S3C24XX_SZ_USBHOST - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
@@ -77,7 +77,7 @@ EXPORT_SYMBOL(s3c_device_usb);
static struct resource s3c_lcd_resource[] = {
[0] = {
.start = S3C2410_PA_LCD,
- .end = S3C2410_PA_LCD + S3C24XX_SZ_LCD,
+ .end = S3C2410_PA_LCD + S3C24XX_SZ_LCD - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
@@ -103,21 +103,25 @@ struct platform_device s3c_device_lcd = {
EXPORT_SYMBOL(s3c_device_lcd);
-static struct s3c2410fb_mach_info s3c2410fb_info;
-
-void __init set_s3c2410fb_info(struct s3c2410fb_mach_info *hard_s3c2410fb_info)
+void __init s3c24xx_fb_set_platdata(struct s3c2410fb_mach_info *pd)
{
- memcpy(&s3c2410fb_info,hard_s3c2410fb_info,sizeof(struct s3c2410fb_mach_info));
- s3c_device_lcd.dev.platform_data = &s3c2410fb_info;
+ struct s3c2410fb_mach_info *npd;
+
+ npd = kmalloc(sizeof(*npd), GFP_KERNEL);
+ if (npd) {
+ memcpy(npd, pd, sizeof(*npd));
+ s3c_device_lcd.dev.platform_data = npd;
+ } else {
+ printk(KERN_ERR "no memory for LCD platform data\n");
+ }
}
-EXPORT_SYMBOL(set_s3c2410fb_info);
/* NAND Controller */
static struct resource s3c_nand_resource[] = {
[0] = {
.start = S3C2410_PA_NAND,
- .end = S3C2410_PA_NAND + S3C24XX_SZ_NAND,
+ .end = S3C2410_PA_NAND + S3C24XX_SZ_NAND - 1,
.flags = IORESOURCE_MEM,
}
};
@@ -136,7 +140,7 @@ EXPORT_SYMBOL(s3c_device_nand);
static struct resource s3c_usbgadget_resource[] = {
[0] = {
.start = S3C2410_PA_USBDEV,
- .end = S3C2410_PA_USBDEV + S3C24XX_SZ_USBDEV,
+ .end = S3C2410_PA_USBDEV + S3C24XX_SZ_USBDEV - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
@@ -161,7 +165,7 @@ EXPORT_SYMBOL(s3c_device_usbgadget);
static struct resource s3c_wdt_resource[] = {
[0] = {
.start = S3C2410_PA_WATCHDOG,
- .end = S3C2410_PA_WATCHDOG + S3C24XX_SZ_WATCHDOG,
+ .end = S3C2410_PA_WATCHDOG + S3C24XX_SZ_WATCHDOG - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
@@ -186,7 +190,7 @@ EXPORT_SYMBOL(s3c_device_wdt);
static struct resource s3c_i2c_resource[] = {
[0] = {
.start = S3C2410_PA_IIC,
- .end = S3C2410_PA_IIC + S3C24XX_SZ_IIC,
+ .end = S3C2410_PA_IIC + S3C24XX_SZ_IIC - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
@@ -211,7 +215,7 @@ EXPORT_SYMBOL(s3c_device_i2c);
static struct resource s3c_iis_resource[] = {
[0] = {
.start = S3C2410_PA_IIS,
- .end = S3C2410_PA_IIS + S3C24XX_SZ_IIS,
+ .end = S3C2410_PA_IIS + S3C24XX_SZ_IIS -1,
.flags = IORESOURCE_MEM,
}
};
@@ -265,7 +269,7 @@ EXPORT_SYMBOL(s3c_device_rtc);
static struct resource s3c_adc_resource[] = {
[0] = {
.start = S3C2410_PA_ADC,
- .end = S3C2410_PA_ADC + S3C24XX_SZ_ADC,
+ .end = S3C2410_PA_ADC + S3C24XX_SZ_ADC - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
@@ -288,7 +292,7 @@ struct platform_device s3c_device_adc = {
static struct resource s3c_sdi_resource[] = {
[0] = {
.start = S3C2410_PA_SDI,
- .end = S3C2410_PA_SDI + S3C24XX_SZ_SDI,
+ .end = S3C2410_PA_SDI + S3C24XX_SZ_SDI - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
@@ -465,7 +469,7 @@ EXPORT_SYMBOL(s3c_device_timer3);
static struct resource s3c_camif_resource[] = {
[0] = {
.start = S3C2440_PA_CAMIF,
- .end = S3C2440_PA_CAMIF + S3C2440_SZ_CAMIF,
+ .end = S3C2440_PA_CAMIF + S3C2440_SZ_CAMIF - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
diff --git a/arch/arm/mach-s3c2410/devs.h b/arch/arm/mach-s3c2410/devs.h
index d6328f96728b..52c4bab5c761 100644
--- a/arch/arm/mach-s3c2410/devs.h
+++ b/arch/arm/mach-s3c2410/devs.h
@@ -15,6 +15,7 @@
* 10-Feb-2005 BJD Added camera from guillaume.gourat@nexvision.tv
*/
#include <linux/config.h>
+#include <linux/platform_device.h>
extern struct platform_device *s3c24xx_uart_devs[];
diff --git a/arch/arm/mach-s3c2410/gpio.c b/arch/arm/mach-s3c2410/gpio.c
index 94f1776cf312..23ea3d5fa09c 100644
--- a/arch/arm/mach-s3c2410/gpio.c
+++ b/arch/arm/mach-s3c2410/gpio.c
@@ -30,6 +30,7 @@
* 04-Oct-2004 BJD Added irq filter controls for GPIO
* 05-Nov-2004 BJD EXPORT_SYMBOL() added for all code
* 13-Mar-2005 BJD Updates for __iomem
+ * 26-Oct-2005 BJD Added generic configuration types
*/
@@ -58,6 +59,27 @@ void s3c2410_gpio_cfgpin(unsigned int pin, unsigned int function)
mask = 3 << S3C2410_GPIO_OFFSET(pin)*2;
}
+ switch (function) {
+ case S3C2410_GPIO_LEAVE:
+ mask = 0;
+ function = 0;
+ break;
+
+ case S3C2410_GPIO_INPUT:
+ case S3C2410_GPIO_OUTPUT:
+ case S3C2410_GPIO_SFN2:
+ case S3C2410_GPIO_SFN3:
+ if (pin < S3C2410_GPIO_BANKB) {
+ function &= 1;
+ function <<= S3C2410_GPIO_OFFSET(pin);
+ } else {
+ function &= 3;
+ function <<= S3C2410_GPIO_OFFSET(pin)*2;
+ }
+ }
+
+ /* modify the specified register wwith IRQs off */
+
local_irq_save(flags);
con = __raw_readl(base + 0x00);
diff --git a/arch/arm/mach-s3c2410/mach-anubis.c b/arch/arm/mach-s3c2410/mach-anubis.c
index 5ae80f4e3e67..0f81fc0c2f7f 100644
--- a/arch/arm/mach-s3c2410/mach-anubis.c
+++ b/arch/arm/mach-s3c2410/mach-anubis.c
@@ -21,7 +21,7 @@
#include <linux/list.h>
#include <linux/timer.h>
#include <linux/init.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
@@ -56,8 +56,16 @@
static struct map_desc anubis_iodesc[] __initdata = {
/* ISA IO areas */
- { (u32)S3C24XX_VA_ISA_BYTE, 0x0, SZ_16M, MT_DEVICE },
- { (u32)S3C24XX_VA_ISA_WORD, 0x0, SZ_16M, MT_DEVICE },
+ {
+ .virtual = (u32)S3C24XX_VA_ISA_BYTE,
+ .pfn = __phys_to_pfn(0x0),
+ .length = SZ_4M,
+ .type = MT_DEVICE
+ }, {
+ .virtual = (u32)S3C24XX_VA_ISA_WORD,
+ .pfn = __phys_to_pfn(0x0),
+ .length = SZ_4M, MT_DEVICE
+ },
/* we could possibly compress the next set down into a set of smaller tables
* pagetables, but that would mean using an L2 section, and it still means
@@ -66,16 +74,41 @@ static struct map_desc anubis_iodesc[] __initdata = {
/* CPLD control registers */
- { (u32)ANUBIS_VA_CTRL1, ANUBIS_PA_CTRL1, SZ_4K, MT_DEVICE },
- { (u32)ANUBIS_VA_CTRL2, ANUBIS_PA_CTRL2, SZ_4K, MT_DEVICE },
+ {
+ .virtual = (u32)ANUBIS_VA_CTRL1,
+ .pfn = __phys_to_pfn(ANUBIS_PA_CTRL1),
+ .length = SZ_4K,
+ .type = MT_DEVICE
+ }, {
+ .virtual = (u32)ANUBIS_VA_CTRL2,
+ .pfn = __phys_to_pfn(ANUBIS_PA_CTRL2),
+ .length = SZ_4K,
+ .type =MT_DEVICE
+ },
/* IDE drives */
- { (u32)ANUBIS_IDEPRI, S3C2410_CS3, SZ_1M, MT_DEVICE },
- { (u32)ANUBIS_IDEPRIAUX, S3C2410_CS3+(1<<26), SZ_1M, MT_DEVICE },
-
- { (u32)ANUBIS_IDESEC, S3C2410_CS4, SZ_1M, MT_DEVICE },
- { (u32)ANUBIS_IDESECAUX, S3C2410_CS4+(1<<26), SZ_1M, MT_DEVICE },
+ {
+ .virtual = (u32)ANUBIS_IDEPRI,
+ .pfn = __phys_to_pfn(S3C2410_CS3),
+ .length = SZ_1M,
+ .type = MT_DEVICE
+ }, {
+ .virtual = (u32)ANUBIS_IDEPRIAUX,
+ .pfn = __phys_to_pfn(S3C2410_CS3+(1<<26)),
+ .length = SZ_1M,
+ .type = MT_DEVICE
+ }, {
+ .virtual = (u32)ANUBIS_IDESEC,
+ .pfn = __phys_to_pfn(S3C2410_CS4),
+ .length = SZ_1M,
+ .type = MT_DEVICE
+ }, {
+ .virtual = (u32)ANUBIS_IDESECAUX,
+ .pfn = __phys_to_pfn(S3C2410_CS4+(1<<26)),
+ .length = SZ_1M,
+ .type = MT_DEVICE
+ },
};
#define UCON S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK
diff --git a/arch/arm/mach-s3c2410/mach-bast.c b/arch/arm/mach-s3c2410/mach-bast.c
index 7b51bfd0ba6d..1be2567a7486 100644
--- a/arch/arm/mach-s3c2410/mach-bast.c
+++ b/arch/arm/mach-s3c2410/mach-bast.c
@@ -32,6 +32,7 @@
* 25-Jul-2005 BJD Removed ASIX static mappings
* 27-Jul-2005 BJD Ensure maximum frequency of i2c bus
* 20-Sep-2005 BJD Added static to non-exported items
+ * 26-Oct-2005 BJD Added FB platform data
*/
#include <linux/kernel.h>
@@ -40,7 +41,7 @@
#include <linux/list.h>
#include <linux/timer.h>
#include <linux/init.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <linux/dm9000.h>
#include <asm/mach/arch.h>
@@ -61,8 +62,10 @@
#include <asm/arch/regs-gpio.h>
#include <asm/arch/regs-mem.h>
#include <asm/arch/regs-lcd.h>
+
#include <asm/arch/nand.h>
#include <asm/arch/iic.h>
+#include <asm/arch/fb.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/nand.h>
@@ -86,32 +89,63 @@
/* macros to modify the physical addresses for io space */
-#define PA_CS2(item) ((item) + S3C2410_CS2)
-#define PA_CS3(item) ((item) + S3C2410_CS3)
-#define PA_CS4(item) ((item) + S3C2410_CS4)
-#define PA_CS5(item) ((item) + S3C2410_CS5)
+#define PA_CS2(item) (__phys_to_pfn((item) + S3C2410_CS2))
+#define PA_CS3(item) (__phys_to_pfn((item) + S3C2410_CS3))
+#define PA_CS4(item) (__phys_to_pfn((item) + S3C2410_CS4))
+#define PA_CS5(item) (__phys_to_pfn((item) + S3C2410_CS5))
static struct map_desc bast_iodesc[] __initdata = {
/* ISA IO areas */
-
- { (u32)S3C24XX_VA_ISA_BYTE, PA_CS2(BAST_PA_ISAIO), SZ_16M, MT_DEVICE },
- { (u32)S3C24XX_VA_ISA_WORD, PA_CS3(BAST_PA_ISAIO), SZ_16M, MT_DEVICE },
-
- /* we could possibly compress the next set down into a set of smaller tables
- * pagetables, but that would mean using an L2 section, and it still means
- * we cannot actually feed the same register to an LDR due to 16K spacing
- */
-
+ {
+ .virtual = (u32)S3C24XX_VA_ISA_BYTE,
+ .pfn = PA_CS2(BAST_PA_ISAIO),
+ .length = SZ_16M,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (u32)S3C24XX_VA_ISA_WORD,
+ .pfn = PA_CS3(BAST_PA_ISAIO),
+ .length = SZ_16M,
+ .type = MT_DEVICE,
+ },
/* bast CPLD control registers, and external interrupt controls */
- { (u32)BAST_VA_CTRL1, BAST_PA_CTRL1, SZ_1M, MT_DEVICE },
- { (u32)BAST_VA_CTRL2, BAST_PA_CTRL2, SZ_1M, MT_DEVICE },
- { (u32)BAST_VA_CTRL3, BAST_PA_CTRL3, SZ_1M, MT_DEVICE },
- { (u32)BAST_VA_CTRL4, BAST_PA_CTRL4, SZ_1M, MT_DEVICE },
-
+ {
+ .virtual = (u32)BAST_VA_CTRL1,
+ .pfn = __phys_to_pfn(BAST_PA_CTRL1),
+ .length = SZ_1M,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (u32)BAST_VA_CTRL2,
+ .pfn = __phys_to_pfn(BAST_PA_CTRL2),
+ .length = SZ_1M,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (u32)BAST_VA_CTRL3,
+ .pfn = __phys_to_pfn(BAST_PA_CTRL3),
+ .length = SZ_1M,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (u32)BAST_VA_CTRL4,
+ .pfn = __phys_to_pfn(BAST_PA_CTRL4),
+ .length = SZ_1M,
+ .type = MT_DEVICE,
+ },
/* PC104 IRQ mux */
- { (u32)BAST_VA_PC104_IRQREQ, BAST_PA_PC104_IRQREQ, SZ_1M, MT_DEVICE },
- { (u32)BAST_VA_PC104_IRQRAW, BAST_PA_PC104_IRQRAW, SZ_1M, MT_DEVICE },
- { (u32)BAST_VA_PC104_IRQMASK, BAST_PA_PC104_IRQMASK, SZ_1M, MT_DEVICE },
+ {
+ .virtual = (u32)BAST_VA_PC104_IRQREQ,
+ .pfn = __phys_to_pfn(BAST_PA_PC104_IRQREQ),
+ .length = SZ_1M,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (u32)BAST_VA_PC104_IRQRAW,
+ .pfn = __phys_to_pfn(BAST_PA_PC104_IRQRAW),
+ .length = SZ_1M,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (u32)BAST_VA_PC104_IRQMASK,
+ .pfn = __phys_to_pfn(BAST_PA_PC104_IRQMASK),
+ .length = SZ_1M,
+ .type = MT_DEVICE,
+ },
/* peripheral space... one for each of fast/slow/byte/16bit */
/* note, ide is only decoded in word space, even though some registers
@@ -399,6 +433,38 @@ static struct s3c2410_platform_i2c bast_i2c_info = {
.max_freq = 130*1000,
};
+
+static struct s3c2410fb_mach_info __initdata bast_lcd_info = {
+ .width = 640,
+ .height = 480,
+
+ .xres = {
+ .min = 320,
+ .max = 1024,
+ .defval = 640,
+ },
+
+ .yres = {
+ .min = 240,
+ .max = 600,
+ .defval = 480,
+ },
+
+ .bpp = {
+ .min = 4,
+ .max = 16,
+ .defval = 8,
+ },
+
+ .regs = {
+ .lcdcon1 = 0x00000176,
+ .lcdcon2 = 0x1d77c7c2,
+ .lcdcon3 = 0x013a7f13,
+ .lcdcon4 = 0x00000057,
+ .lcdcon5 = 0x00014b02,
+ }
+};
+
/* Standard BAST devices */
static struct platform_device *bast_devices[] __initdata = {
@@ -454,6 +520,10 @@ static void __init bast_map_io(void)
usb_simtec_init();
}
+static void __init bast_init(void)
+{
+ s3c24xx_fb_set_platdata(&bast_lcd_info);
+}
MACHINE_START(BAST, "Simtec-BAST")
/* Maintainer: Ben Dooks <ben@simtec.co.uk> */
@@ -463,5 +533,6 @@ MACHINE_START(BAST, "Simtec-BAST")
.boot_params = S3C2410_SDRAM_PA + 0x100,
.map_io = bast_map_io,
.init_irq = s3c24xx_init_irq,
+ .init_machine = bast_init,
.timer = &s3c24xx_timer,
MACHINE_END
diff --git a/arch/arm/mach-s3c2410/mach-h1940.c b/arch/arm/mach-s3c2410/mach-h1940.c
index fb3cb01266e5..0aa8760598f7 100644
--- a/arch/arm/mach-s3c2410/mach-h1940.c
+++ b/arch/arm/mach-s3c2410/mach-h1940.c
@@ -25,6 +25,7 @@
* 14-Jan-2005 BJD Added clock init
* 10-Mar-2005 LCVR Changed S3C2410_VA to S3C24XX_VA
* 20-Sep-2005 BJD Added static to non-exported items
+ * 26-Oct-2005 BJD Changed name of fb init call
*/
#include <linux/kernel.h>
@@ -33,6 +34,7 @@
#include <linux/list.h>
#include <linux/timer.h>
#include <linux/init.h>
+#include <linux/platform_device.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
@@ -164,7 +166,7 @@ static void __init h1940_init_irq(void)
static void __init h1940_init(void)
{
- set_s3c2410fb_info(&h1940_lcdcfg);
+ s3c24xx_fb_set_platdata(&h1940_lcdcfg);
}
MACHINE_START(H1940, "IPAQ-H1940")
diff --git a/arch/arm/mach-s3c2410/mach-n30.c b/arch/arm/mach-s3c2410/mach-n30.c
index 5c0f2b091f95..378d640ab00b 100644
--- a/arch/arm/mach-s3c2410/mach-n30.c
+++ b/arch/arm/mach-s3c2410/mach-n30.c
@@ -20,7 +20,7 @@
#include <linux/timer.h>
#include <linux/init.h>
#include <linux/delay.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <linux/kthread.h>
#include <asm/mach/arch.h>
diff --git a/arch/arm/mach-s3c2410/mach-nexcoder.c b/arch/arm/mach-s3c2410/mach-nexcoder.c
index c22f8216032d..42b0eeff2e0f 100644
--- a/arch/arm/mach-s3c2410/mach-nexcoder.c
+++ b/arch/arm/mach-s3c2410/mach-nexcoder.c
@@ -19,7 +19,7 @@
#include <linux/timer.h>
#include <linux/init.h>
#include <linux/string.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <linux/mtd/map.h>
diff --git a/arch/arm/mach-s3c2410/mach-otom.c b/arch/arm/mach-s3c2410/mach-otom.c
index ad1459e402e2..a2eb9ed48fcd 100644
--- a/arch/arm/mach-s3c2410/mach-otom.c
+++ b/arch/arm/mach-s3c2410/mach-otom.c
@@ -15,7 +15,7 @@
#include <linux/list.h>
#include <linux/timer.h>
#include <linux/init.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
diff --git a/arch/arm/mach-s3c2410/mach-rx3715.c b/arch/arm/mach-s3c2410/mach-rx3715.c
index 22d9e070fd68..f8d86d1e16b6 100644
--- a/arch/arm/mach-s3c2410/mach-rx3715.c
+++ b/arch/arm/mach-s3c2410/mach-rx3715.c
@@ -17,6 +17,7 @@
* 10-Mar-2005 LCVR Changed S3C2410_VA to S3C24XX_VA
* 14-Mar-2005 BJD Fixed __iomem warnings
* 20-Sep-2005 BJD Added static to non-exported items
+ * 31-Oct-2005 BJD Added LCD setup for framebuffer
*/
#include <linux/kernel.h>
@@ -27,6 +28,7 @@
#include <linux/init.h>
#include <linux/tty.h>
#include <linux/console.h>
+#include <linux/platform_device.h>
#include <linux/serial_core.h>
#include <linux/serial.h>
@@ -42,6 +44,9 @@
#include <asm/arch/regs-serial.h>
#include <asm/arch/regs-gpio.h>
+#include <asm/arch/regs-lcd.h>
+
+#include <asm/arch/fb.h>
#include "clock.h"
#include "devs.h"
@@ -51,8 +56,17 @@
static struct map_desc rx3715_iodesc[] __initdata = {
/* dump ISA space somewhere unused */
- { (u32)S3C24XX_VA_ISA_WORD, S3C2410_CS3, SZ_16M, MT_DEVICE },
- { (u32)S3C24XX_VA_ISA_BYTE, S3C2410_CS3, SZ_16M, MT_DEVICE },
+ {
+ .virtual = (u32)S3C24XX_VA_ISA_WORD,
+ .pfn = __phys_to_pfn(S3C2410_CS3),
+ .length = SZ_1M,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (u32)S3C24XX_VA_ISA_BYTE,
+ .pfn = __phys_to_pfn(S3C2410_CS3),
+ .length = SZ_1M,
+ .type = MT_DEVICE,
+ },
};
@@ -96,6 +110,66 @@ static struct s3c2410_uartcfg rx3715_uartcfgs[] = {
}
};
+/* framebuffer lcd controller information */
+
+static struct s3c2410fb_mach_info rx3715_lcdcfg __initdata = {
+ .regs = {
+ .lcdcon1 = S3C2410_LCDCON1_TFT16BPP | \
+ S3C2410_LCDCON1_TFT | \
+ S3C2410_LCDCON1_CLKVAL(0x0C),
+
+ .lcdcon2 = S3C2410_LCDCON2_VBPD(5) | \
+ S3C2410_LCDCON2_LINEVAL(319) | \
+ S3C2410_LCDCON2_VFPD(6) | \
+ S3C2410_LCDCON2_VSPW(2),
+
+ .lcdcon3 = S3C2410_LCDCON3_HBPD(35) | \
+ S3C2410_LCDCON3_HOZVAL(239) | \
+ S3C2410_LCDCON3_HFPD(35),
+
+ .lcdcon4 = S3C2410_LCDCON4_MVAL(0) | \
+ S3C2410_LCDCON4_HSPW(7),
+
+ .lcdcon5 = S3C2410_LCDCON5_INVVLINE |
+ S3C2410_LCDCON5_FRM565 |
+ S3C2410_LCDCON5_HWSWP,
+ },
+
+ .lpcsel = 0xf82,
+
+ .gpccon = 0xaa955699,
+ .gpccon_mask = 0xffc003cc,
+ .gpcup = 0x0000ffff,
+ .gpcup_mask = 0xffffffff,
+
+ .gpdcon = 0xaa95aaa1,
+ .gpdcon_mask = 0xffc0fff0,
+ .gpdup = 0x0000faff,
+ .gpdup_mask = 0xffffffff,
+
+ .fixed_syncs = 1,
+ .width = 240,
+ .height = 320,
+
+ .xres = {
+ .min = 240,
+ .max = 240,
+ .defval = 240,
+ },
+
+ .yres = {
+ .max = 320,
+ .min = 320,
+ .defval = 320,
+ },
+
+ .bpp = {
+ .min = 16,
+ .max = 16,
+ .defval = 16,
+ },
+};
+
static struct platform_device *rx3715_devices[] __initdata = {
&s3c_device_usb,
&s3c_device_lcd,
@@ -122,14 +196,12 @@ static void __init rx3715_init_irq(void)
s3c24xx_init_irq();
}
-#ifdef CONFIG_PM
static void __init rx3715_init_machine(void)
{
s3c2410_pm_init();
+ s3c24xx_fb_set_platdata(&rx3715_lcdcfg);
}
-#else
-#define rx3715_init_machine NULL
-#endif
+
MACHINE_START(RX3715, "IPAQ-RX3715")
/* Maintainer: Ben Dooks <ben@fluff.org> */
diff --git a/arch/arm/mach-s3c2410/mach-smdk2410.c b/arch/arm/mach-s3c2410/mach-smdk2410.c
index 2eda55a6b678..2c91965ee1c8 100644
--- a/arch/arm/mach-s3c2410/mach-smdk2410.c
+++ b/arch/arm/mach-s3c2410/mach-smdk2410.c
@@ -38,6 +38,7 @@
#include <linux/list.h>
#include <linux/timer.h>
#include <linux/init.h>
+#include <linux/platform_device.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
diff --git a/arch/arm/mach-s3c2410/mach-smdk2440.c b/arch/arm/mach-s3c2410/mach-smdk2440.c
index 722ef46b630a..4e31118533e6 100644
--- a/arch/arm/mach-s3c2410/mach-smdk2440.c
+++ b/arch/arm/mach-s3c2410/mach-smdk2440.c
@@ -19,6 +19,7 @@
* 10-Mar-2005 LCVR Replaced S3C2410_VA by S3C24XX_VA
* 14-Mar-2005 BJD void __iomem fixes
* 20-Sep-2005 BJD Added static to non-exported items
+ * 26-Oct-2005 BJD Added framebuffer data
*/
#include <linux/kernel.h>
@@ -27,6 +28,7 @@
#include <linux/list.h>
#include <linux/timer.h>
#include <linux/init.h>
+#include <linux/platform_device.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
@@ -41,7 +43,10 @@
//#include <asm/debug-ll.h>
#include <asm/arch/regs-serial.h>
#include <asm/arch/regs-gpio.h>
+#include <asm/arch/regs-lcd.h>
+
#include <asm/arch/idle.h>
+#include <asm/arch/fb.h>
#include "s3c2410.h"
#include "s3c2440.h"
@@ -53,8 +58,27 @@
static struct map_desc smdk2440_iodesc[] __initdata = {
/* ISA IO Space map (memory space selected by A24) */
- { (u32)S3C24XX_VA_ISA_WORD, S3C2410_CS2, SZ_16M, MT_DEVICE },
- { (u32)S3C24XX_VA_ISA_BYTE, S3C2410_CS2, SZ_16M, MT_DEVICE },
+ {
+ .virtual = (u32)S3C24XX_VA_ISA_WORD,
+ .pfn = __phys_to_pfn(S3C2410_CS2),
+ .length = 0x10000,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (u32)S3C24XX_VA_ISA_WORD + 0x10000,
+ .pfn = __phys_to_pfn(S3C2410_CS2 + (1<<24)),
+ .length = SZ_4M,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (u32)S3C24XX_VA_ISA_BYTE,
+ .pfn = __phys_to_pfn(S3C2410_CS2),
+ .length = 0x10000,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (u32)S3C24XX_VA_ISA_BYTE + 0x10000,
+ .pfn = __phys_to_pfn(S3C2410_CS2 + (1<<24)),
+ .length = SZ_4M,
+ .type = MT_DEVICE,
+ }
};
#define UCON S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK
@@ -86,6 +110,70 @@ static struct s3c2410_uartcfg smdk2440_uartcfgs[] = {
}
};
+/* LCD driver info */
+
+static struct s3c2410fb_mach_info smdk2440_lcd_cfg __initdata = {
+ .regs = {
+
+ .lcdcon1 = S3C2410_LCDCON1_TFT16BPP |
+ S3C2410_LCDCON1_TFT |
+ S3C2410_LCDCON1_CLKVAL(0x04),
+
+ .lcdcon2 = S3C2410_LCDCON2_VBPD(7) |
+ S3C2410_LCDCON2_LINEVAL(319) |
+ S3C2410_LCDCON2_VFPD(6) |
+ S3C2410_LCDCON2_VSPW(3),
+
+ .lcdcon3 = S3C2410_LCDCON3_HBPD(19) |
+ S3C2410_LCDCON3_HOZVAL(239) |
+ S3C2410_LCDCON3_HFPD(7),
+
+ .lcdcon4 = S3C2410_LCDCON4_MVAL(0) |
+ S3C2410_LCDCON4_HSPW(3),
+
+ .lcdcon5 = S3C2410_LCDCON5_FRM565 |
+ S3C2410_LCDCON5_INVVLINE |
+ S3C2410_LCDCON5_INVVFRAME |
+ S3C2410_LCDCON5_PWREN |
+ S3C2410_LCDCON5_HWSWP,
+ },
+
+#if 0
+ /* currently setup by downloader */
+ .gpccon = 0xaa940659,
+ .gpccon_mask = 0xffffffff,
+ .gpcup = 0x0000ffff,
+ .gpcup_mask = 0xffffffff,
+ .gpdcon = 0xaa84aaa0,
+ .gpdcon_mask = 0xffffffff,
+ .gpdup = 0x0000faff,
+ .gpdup_mask = 0xffffffff,
+#endif
+
+ .lpcsel = ((0xCE6) & ~7) | 1<<4,
+
+ .width = 240,
+ .height = 320,
+
+ .xres = {
+ .min = 240,
+ .max = 240,
+ .defval = 240,
+ },
+
+ .yres = {
+ .min = 320,
+ .max = 320,
+ .defval = 320,
+ },
+
+ .bpp = {
+ .min = 16,
+ .max = 16,
+ .defval = 16,
+ },
+};
+
static struct platform_device *smdk2440_devices[] __initdata = {
&s3c_device_usb,
&s3c_device_lcd,
@@ -121,6 +209,8 @@ static void __init smdk2440_machine_init(void)
s3c2410_gpio_setpin(S3C2410_GPF6, 0);
s3c2410_gpio_setpin(S3C2410_GPF7, 0);
+ s3c24xx_fb_set_platdata(&smdk2440_lcd_cfg);
+
s3c2410_pm_init();
}
diff --git a/arch/arm/mach-s3c2410/mach-vr1000.c b/arch/arm/mach-s3c2410/mach-vr1000.c
index 46b259673c18..ae7e099bf6c8 100644
--- a/arch/arm/mach-s3c2410/mach-vr1000.c
+++ b/arch/arm/mach-s3c2410/mach-vr1000.c
@@ -74,27 +74,47 @@
/* macros to modify the physical addresses for io space */
-#define PA_CS2(item) ((item) + S3C2410_CS2)
-#define PA_CS3(item) ((item) + S3C2410_CS3)
-#define PA_CS4(item) ((item) + S3C2410_CS4)
-#define PA_CS5(item) ((item) + S3C2410_CS5)
+#define PA_CS2(item) (__phys_to_pfn((item) + S3C2410_CS2))
+#define PA_CS3(item) (__phys_to_pfn((item) + S3C2410_CS3))
+#define PA_CS4(item) (__phys_to_pfn((item) + S3C2410_CS4))
+#define PA_CS5(item) (__phys_to_pfn((item) + S3C2410_CS5))
static struct map_desc vr1000_iodesc[] __initdata = {
/* ISA IO areas */
-
- { (u32)S3C24XX_VA_ISA_BYTE, PA_CS2(BAST_PA_ISAIO), SZ_16M, MT_DEVICE },
- { (u32)S3C24XX_VA_ISA_WORD, PA_CS3(BAST_PA_ISAIO), SZ_16M, MT_DEVICE },
-
- /* we could possibly compress the next set down into a set of smaller tables
- * pagetables, but that would mean using an L2 section, and it still means
- * we cannot actually feed the same register to an LDR due to 16K spacing
- */
-
- /* bast CPLD control registers, and external interrupt controls */
- { (u32)VR1000_VA_CTRL1, VR1000_PA_CTRL1, SZ_1M, MT_DEVICE },
- { (u32)VR1000_VA_CTRL2, VR1000_PA_CTRL2, SZ_1M, MT_DEVICE },
- { (u32)VR1000_VA_CTRL3, VR1000_PA_CTRL3, SZ_1M, MT_DEVICE },
- { (u32)VR1000_VA_CTRL4, VR1000_PA_CTRL4, SZ_1M, MT_DEVICE },
+ {
+ .virtual = (u32)S3C24XX_VA_ISA_BYTE,
+ .pfn = PA_CS2(BAST_PA_ISAIO),
+ .length = SZ_16M,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (u32)S3C24XX_VA_ISA_WORD,
+ .pfn = PA_CS3(BAST_PA_ISAIO),
+ .length = SZ_16M,
+ .type = MT_DEVICE,
+ },
+
+ /* CPLD control registers, and external interrupt controls */
+ {
+ .virtual = (u32)VR1000_VA_CTRL1,
+ .pfn = __phys_to_pfn(VR1000_PA_CTRL1),
+ .length = SZ_1M,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (u32)VR1000_VA_CTRL2,
+ .pfn = __phys_to_pfn(VR1000_PA_CTRL2),
+ .length = SZ_1M,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (u32)VR1000_VA_CTRL3,
+ .pfn = __phys_to_pfn(VR1000_PA_CTRL3),
+ .length = SZ_1M,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (u32)VR1000_VA_CTRL4,
+ .pfn = __phys_to_pfn(VR1000_PA_CTRL4),
+ .length = SZ_1M,
+ .type = MT_DEVICE,
+ },
/* peripheral space... one for each of fast/slow/byte/16bit */
/* note, ide is only decoded in word space, even though some registers
diff --git a/arch/arm/mach-s3c2410/s3c2410.c b/arch/arm/mach-s3c2410/s3c2410.c
index a8bf5ec82602..0a2013a76549 100644
--- a/arch/arm/mach-s3c2410/s3c2410.c
+++ b/arch/arm/mach-s3c2410/s3c2410.c
@@ -27,7 +27,7 @@
#include <linux/list.h>
#include <linux/timer.h>
#include <linux/init.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
diff --git a/arch/arm/mach-s3c2410/s3c2440.c b/arch/arm/mach-s3c2410/s3c2440.c
index 833fa36bce05..4d63e7133b48 100644
--- a/arch/arm/mach-s3c2410/s3c2440.c
+++ b/arch/arm/mach-s3c2410/s3c2440.c
@@ -26,7 +26,7 @@
#include <linux/list.h>
#include <linux/timer.h>
#include <linux/init.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <linux/sysdev.h>
#include <asm/mach/arch.h>
diff --git a/arch/arm/mach-sa1100/assabet.c b/arch/arm/mach-sa1100/assabet.c
index 24687f511bf5..75efb5da5b6d 100644
--- a/arch/arm/mach-sa1100/assabet.c
+++ b/arch/arm/mach-sa1100/assabet.c
@@ -388,9 +388,17 @@ static struct sa1100_port_fns assabet_port_fns __initdata = {
};
static struct map_desc assabet_io_desc[] __initdata = {
- /* virtual physical length type */
- { 0xf1000000, 0x12000000, 0x00100000, MT_DEVICE }, /* Board Control Register */
- { 0xf2800000, 0x4b800000, 0x00800000, MT_DEVICE } /* MQ200 */
+ { /* Board Control Register */
+ .virtual = 0xf1000000,
+ .pfn = __phys_to_pfn(0x12000000),
+ .length = 0x00100000,
+ .type = MT_DEVICE
+ }, { /* MQ200 */
+ .virtual = 0xf2800000,
+ .pfn = __phys_to_pfn(0x4b800000),
+ .length = 0x00800000,
+ .type = MT_DEVICE
+ }
};
static void __init assabet_map_io(void)
diff --git a/arch/arm/mach-sa1100/badge4.c b/arch/arm/mach-sa1100/badge4.c
index b6169cb09196..edccd5eb06be 100644
--- a/arch/arm/mach-sa1100/badge4.c
+++ b/arch/arm/mach-sa1100/badge4.c
@@ -16,7 +16,7 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <linux/delay.h>
#include <linux/tty.h>
#include <linux/mtd/mtd.h>
@@ -254,10 +254,22 @@ EXPORT_SYMBOL(badge4_set_5V);
static struct map_desc badge4_io_desc[] __initdata = {
- /* virtual physical length type */
- {0xf1000000, 0x08000000, 0x00100000, MT_DEVICE },/* SRAM bank 1 */
- {0xf2000000, 0x10000000, 0x00100000, MT_DEVICE },/* SRAM bank 2 */
- {0xf4000000, 0x48000000, 0x00100000, MT_DEVICE } /* SA-1111 */
+ { /* SRAM bank 1 */
+ .virtual = 0xf1000000,
+ .pfn = __phys_to_pfn(0x08000000),
+ .length = 0x00100000,
+ .type = MT_DEVICE
+ }, { /* SRAM bank 2 */
+ .virtual = 0xf2000000,
+ .pfn = __phys_to_pfn(0x10000000),
+ .length = 0x00100000,
+ .type = MT_DEVICE
+ }, { /* SA-1111 */
+ .virtual = 0xf4000000,
+ .pfn = __phys_to_pfn(0x48000000),
+ .length = 0x00100000,
+ .type = MT_DEVICE
+ }
};
static void
diff --git a/arch/arm/mach-sa1100/cerf.c b/arch/arm/mach-sa1100/cerf.c
index 9484be7dc671..508593722bc7 100644
--- a/arch/arm/mach-sa1100/cerf.c
+++ b/arch/arm/mach-sa1100/cerf.c
@@ -14,7 +14,7 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/tty.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
@@ -100,8 +100,12 @@ static void __init cerf_init_irq(void)
}
static struct map_desc cerf_io_desc[] __initdata = {
- /* virtual physical length type */
- { 0xf0000000, 0x08000000, 0x00100000, MT_DEVICE } /* Crystal Ethernet Chip */
+ { /* Crystal Ethernet Chip */
+ .virtual = 0xf0000000,
+ .pfn = __phys_to_pfn(0x08000000),
+ .length = 0x00100000,
+ .type = MT_DEVICE
+ }
};
static void __init cerf_map_io(void)
diff --git a/arch/arm/mach-sa1100/collie.c b/arch/arm/mach-sa1100/collie.c
index 6ecab7e2c238..522abc036d3a 100644
--- a/arch/arm/mach-sa1100/collie.c
+++ b/arch/arm/mach-sa1100/collie.c
@@ -21,7 +21,7 @@
#include <linux/kernel.h>
#include <linux/tty.h>
#include <linux/delay.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <linux/timer.h>
@@ -171,9 +171,17 @@ static void __init collie_init(void)
}
static struct map_desc collie_io_desc[] __initdata = {
- /* virtual physical length type */
- {0xe8000000, 0x00000000, 0x02000000, MT_DEVICE}, /* 32M main flash (cs0) */
- {0xea000000, 0x08000000, 0x02000000, MT_DEVICE}, /* 32M boot flash (cs1) */
+ { /* 32M main flash (cs0) */
+ .virtual = 0xe8000000,
+ .pfn = __phys_to_pfn(0x00000000),
+ .length = 0x02000000,
+ .type = MT_DEVICE
+ }, { /* 32M boot flash (cs1) */
+ .virtual = 0xea000000,
+ .pfn = __phys_to_pfn(0x08000000),
+ .length = 0x02000000,
+ .type = MT_DEVICE
+ }
};
static void __init collie_map_io(void)
diff --git a/arch/arm/mach-sa1100/generic.c b/arch/arm/mach-sa1100/generic.c
index 3f1e358455e5..2abdc419e984 100644
--- a/arch/arm/mach-sa1100/generic.c
+++ b/arch/arm/mach-sa1100/generic.c
@@ -17,12 +17,15 @@
#include <linux/pm.h>
#include <linux/cpufreq.h>
#include <linux/ioport.h>
+#include <linux/sched.h> /* just for sched_clock() - funny that */
+#include <linux/platform_device.h>
#include <asm/div64.h>
#include <asm/hardware.h>
#include <asm/system.h>
#include <asm/pgtable.h>
#include <asm/mach/map.h>
+#include <asm/mach/flash.h>
#include <asm/irq.h>
#include "generic.h"
@@ -283,6 +286,7 @@ static struct platform_device sa11x0mtd_device = {
void sa11x0_set_flash_data(struct flash_platform_data *flash,
struct resource *res, int nr)
{
+ flash->name = "sa1100";
sa11x0mtd_device.dev.platform_data = flash;
sa11x0mtd_device.resource = res;
sa11x0mtd_device.num_resources = nr;
@@ -369,11 +373,27 @@ EXPORT_SYMBOL(sa1100fb_lcd_power);
*/
static struct map_desc standard_io_desc[] __initdata = {
- /* virtual physical length type */
- { 0xf8000000, 0x80000000, 0x00100000, MT_DEVICE }, /* PCM */
- { 0xfa000000, 0x90000000, 0x00100000, MT_DEVICE }, /* SCM */
- { 0xfc000000, 0xa0000000, 0x00100000, MT_DEVICE }, /* MER */
- { 0xfe000000, 0xb0000000, 0x00200000, MT_DEVICE } /* LCD + DMA */
+ { /* PCM */
+ .virtual = 0xf8000000,
+ .pfn = __phys_to_pfn(0x80000000),
+ .length = 0x00100000,
+ .type = MT_DEVICE
+ }, { /* SCM */
+ .virtual = 0xfa000000,
+ .pfn = __phys_to_pfn(0x90000000),
+ .length = 0x00100000,
+ .type = MT_DEVICE
+ }, { /* MER */
+ .virtual = 0xfc000000,
+ .pfn = __phys_to_pfn(0xa0000000),
+ .length = 0x00100000,
+ .type = MT_DEVICE
+ }, { /* LCD + DMA */
+ .virtual = 0xfe000000,
+ .pfn = __phys_to_pfn(0xb0000000),
+ .length = 0x00200000,
+ .type = MT_DEVICE
+ },
};
void __init sa1100_map_io(void)
diff --git a/arch/arm/mach-sa1100/h3600.c b/arch/arm/mach-sa1100/h3600.c
index e7aa2681ca64..e8352b7f74b0 100644
--- a/arch/arm/mach-sa1100/h3600.c
+++ b/arch/arm/mach-sa1100/h3600.c
@@ -223,10 +223,22 @@ static void h3xxx_lcd_power(int enable)
}
static struct map_desc h3600_io_desc[] __initdata = {
- /* virtual physical length type */
- { H3600_BANK_2_VIRT, SA1100_CS2_PHYS, 0x02800000, MT_DEVICE }, /* static memory bank 2 CS#2 */
- { H3600_BANK_4_VIRT, SA1100_CS4_PHYS, 0x00800000, MT_DEVICE }, /* static memory bank 4 CS#4 */
- { H3600_EGPIO_VIRT, H3600_EGPIO_PHYS, 0x01000000, MT_DEVICE }, /* EGPIO 0 CS#5 */
+ { /* static memory bank 2 CS#2 */
+ .virtual = H3600_BANK_2_VIRT,
+ .pfn = __phys_to_pfn(SA1100_CS2_PHYS),
+ .length = 0x02800000,
+ .type = MT_DEVICE
+ }, { /* static memory bank 4 CS#4 */
+ .virtual = H3600_BANK_4_VIRT,
+ .pfn = __phys_to_pfn(SA1100_CS4_PHYS),
+ .length = 0x00800000,
+ .type = MT_DEVICE
+ }, { /* EGPIO 0 CS#5 */
+ .virtual = H3600_EGPIO_VIRT,
+ .pfn = __phys_to_pfn(H3600_EGPIO_PHYS),
+ .length = 0x01000000,
+ .type = MT_DEVICE
+ }
};
/*
diff --git a/arch/arm/mach-sa1100/hackkit.c b/arch/arm/mach-sa1100/hackkit.c
index 502d65cfe654..c922e043c424 100644
--- a/arch/arm/mach-sa1100/hackkit.c
+++ b/arch/arm/mach-sa1100/hackkit.c
@@ -57,8 +57,12 @@ static void hackkit_uart_pm(struct uart_port *port, u_int state, u_int oldstate)
*/
static struct map_desc hackkit_io_desc[] __initdata = {
- /* virtual physical length type */
- { 0xe8000000, 0x00000000, 0x01000000, MT_DEVICE } /* Flash bank 0 */
+ { /* Flash bank 0 */
+ .virtual = 0xe8000000,
+ .pfn = __phys_to_pfn(0x00000000),
+ .length = 0x01000000,
+ .type = MT_DEVICE
+ },
};
static struct sa1100_port_fns hackkit_port_fns __initdata = {
diff --git a/arch/arm/mach-sa1100/jornada720.c b/arch/arm/mach-sa1100/jornada720.c
index 2f497112c96a..2f671cc3cb99 100644
--- a/arch/arm/mach-sa1100/jornada720.c
+++ b/arch/arm/mach-sa1100/jornada720.c
@@ -6,8 +6,10 @@
#include <linux/kernel.h>
#include <linux/tty.h>
#include <linux/delay.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <linux/ioport.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
#include <asm/hardware.h>
#include <asm/hardware/sa1111.h>
@@ -16,6 +18,7 @@
#include <asm/setup.h>
#include <asm/mach/arch.h>
+#include <asm/mach/flash.h>
#include <asm/mach/map.h>
#include <asm/mach/serial_sa1100.h>
@@ -81,10 +84,22 @@ static int __init jornada720_init(void)
arch_initcall(jornada720_init);
static struct map_desc jornada720_io_desc[] __initdata = {
- /* virtual physical length type */
- { 0xf0000000, 0x48000000, 0x00100000, MT_DEVICE }, /* Epson registers */
- { 0xf1000000, 0x48200000, 0x00100000, MT_DEVICE }, /* Epson frame buffer */
- { 0xf4000000, 0x40000000, 0x00100000, MT_DEVICE } /* SA-1111 */
+ { /* Epson registers */
+ .virtual = 0xf0000000,
+ .pfn = __phys_to_pfn(0x48000000),
+ .length = 0x00100000,
+ .type = MT_DEVICE
+ }, { /* Epson frame buffer */
+ .virtual = 0xf1000000,
+ .pfn = __phys_to_pfn(0x48200000),
+ .length = 0x00100000,
+ .type = MT_DEVICE
+ }, { /* SA-1111 */
+ .virtual = 0xf4000000,
+ .pfn = __phys_to_pfn(0x40000000),
+ .length = 0x00100000,
+ .type = MT_DEVICE
+ }
};
static void __init jornada720_map_io(void)
@@ -96,6 +111,66 @@ static void __init jornada720_map_io(void)
sa1100_register_uart(1, 1);
}
+static struct mtd_partition jornada720_partitions[] = {
+ {
+ .name = "JORNADA720 boot firmware",
+ .size = 0x00040000,
+ .offset = 0,
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ }, {
+ .name = "JORNADA720 kernel",
+ .size = 0x000c0000,
+ .offset = 0x00040000,
+ }, {
+ .name = "JORNADA720 params",
+ .size = 0x00040000,
+ .offset = 0x00100000,
+ }, {
+ .name = "JORNADA720 initrd",
+ .size = 0x00100000,
+ .offset = 0x00140000,
+ }, {
+ .name = "JORNADA720 root cramfs",
+ .size = 0x00300000,
+ .offset = 0x00240000,
+ }, {
+ .name = "JORNADA720 usr cramfs",
+ .size = 0x00800000,
+ .offset = 0x00540000,
+ }, {
+ .name = "JORNADA720 usr local",
+ .size = 0, /* will expand to the end of the flash */
+ .offset = 0x00d00000,
+ }
+};
+
+static void jornada720_set_vpp(int vpp)
+{
+ if (vpp)
+ PPSR |= 0x80;
+ else
+ PPSR &= ~0x80;
+ PPDR |= 0x80;
+}
+
+static struct flash_platform_data jornada720_flash_data = {
+ .map_name = "cfi_probe",
+ .set_vpp = jornada720_set_vpp,
+ .parts = jornada720_partitions,
+ .nr_parts = ARRAY_SIZE(jornada720_partitions),
+};
+
+static struct resource jornada720_flash_resource = {
+ .start = SA1100_CS0_PHYS,
+ .end = SA1100_CS0_PHYS + SZ_32M - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+static void __init jornada720_mach_init(void)
+{
+ sa11x0_set_flash_data(&jornada720_flash_data, &jornada720_flash_resource, 1);
+}
+
MACHINE_START(JORNADA720, "HP Jornada 720")
/* Maintainer: Michael Gernoth <michael@gernoth.net> */
.phys_ram = 0xc0000000,
@@ -105,4 +180,5 @@ MACHINE_START(JORNADA720, "HP Jornada 720")
.map_io = jornada720_map_io,
.init_irq = sa1100_init_irq,
.timer = &sa1100_timer,
+ .init_machine = jornada720_mach_init,
MACHINE_END
diff --git a/arch/arm/mach-sa1100/lart.c b/arch/arm/mach-sa1100/lart.c
index ed6744d480af..8c9e3dd52942 100644
--- a/arch/arm/mach-sa1100/lart.c
+++ b/arch/arm/mach-sa1100/lart.c
@@ -31,9 +31,17 @@ static void __init lart_init(void)
}
static struct map_desc lart_io_desc[] __initdata = {
- /* virtual physical length type */
- { 0xe8000000, 0x00000000, 0x00400000, MT_DEVICE }, /* main flash memory */
- { 0xec000000, 0x08000000, 0x00400000, MT_DEVICE } /* main flash, alternative location */
+ { /* main flash memory */
+ .virtual = 0xe8000000,
+ .pfn = __phys_to_pfn(0x00000000),
+ .length = 0x00400000,
+ .type = MT_DEVICE
+ }, { /* main flash, alternative location */
+ .virtual = 0xec000000,
+ .pfn = __phys_to_pfn(0x08000000),
+ .length = 0x00400000,
+ .type = MT_DEVICE
+ }
};
static void __init lart_map_io(void)
diff --git a/arch/arm/mach-sa1100/neponset.c b/arch/arm/mach-sa1100/neponset.c
index fc061641b7be..69f1970646c6 100644
--- a/arch/arm/mach-sa1100/neponset.c
+++ b/arch/arm/mach-sa1100/neponset.c
@@ -8,7 +8,7 @@
#include <linux/tty.h>
#include <linux/ioport.h>
#include <linux/serial_core.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <linux/slab.h>
#include <asm/hardware.h>
@@ -178,33 +178,27 @@ static int neponset_probe(struct device *dev)
/*
* LDM power management.
*/
-static int neponset_suspend(struct device *dev, pm_message_t state, u32 level)
+static int neponset_suspend(struct device *dev, pm_message_t state)
{
/*
* Save state.
*/
- if (level == SUSPEND_SAVE_STATE ||
- level == SUSPEND_DISABLE ||
- level == SUSPEND_POWER_DOWN) {
- if (!dev->power.saved_state)
- dev->power.saved_state = kmalloc(sizeof(unsigned int), GFP_KERNEL);
- if (!dev->power.saved_state)
- return -ENOMEM;
-
- *(unsigned int *)dev->power.saved_state = NCR_0;
- }
+ if (!dev->power.saved_state)
+ dev->power.saved_state = kmalloc(sizeof(unsigned int), GFP_KERNEL);
+ if (!dev->power.saved_state)
+ return -ENOMEM;
+
+ *(unsigned int *)dev->power.saved_state = NCR_0;
return 0;
}
-static int neponset_resume(struct device *dev, u32 level)
+static int neponset_resume(struct device *dev)
{
- if (level == RESUME_RESTORE_STATE || level == RESUME_ENABLE) {
- if (dev->power.saved_state) {
- NCR_0 = *(unsigned int *)dev->power.saved_state;
- kfree(dev->power.saved_state);
- dev->power.saved_state = NULL;
- }
+ if (dev->power.saved_state) {
+ NCR_0 = *(unsigned int *)dev->power.saved_state;
+ kfree(dev->power.saved_state);
+ dev->power.saved_state = NULL;
}
return 0;
@@ -331,9 +325,17 @@ static int __init neponset_init(void)
subsys_initcall(neponset_init);
static struct map_desc neponset_io_desc[] __initdata = {
- /* virtual physical length type */
- { 0xf3000000, 0x10000000, SZ_1M, MT_DEVICE }, /* System Registers */
- { 0xf4000000, 0x40000000, SZ_1M, MT_DEVICE } /* SA-1111 */
+ { /* System Registers */
+ .virtual = 0xf3000000,
+ .pfn = __phys_to_pfn(0x10000000),
+ .length = SZ_1M,
+ .type = MT_DEVICE
+ }, { /* SA-1111 */
+ .virtual = 0xf4000000,
+ .pfn = __phys_to_pfn(0x40000000),
+ .length = SZ_1M,
+ .type = MT_DEVICE
+ }
};
void __init neponset_map_io(void)
diff --git a/arch/arm/mach-sa1100/pleb.c b/arch/arm/mach-sa1100/pleb.c
index e17b58fb9c9c..58c18f9e9b7b 100644
--- a/arch/arm/mach-sa1100/pleb.c
+++ b/arch/arm/mach-sa1100/pleb.c
@@ -6,7 +6,7 @@
#include <linux/kernel.h>
#include <linux/tty.h>
#include <linux/ioport.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <linux/mtd/partitions.h>
diff --git a/arch/arm/mach-sa1100/simpad.c b/arch/arm/mach-sa1100/simpad.c
index 07f6d5fd7bb0..439ddc9b06d6 100644
--- a/arch/arm/mach-sa1100/simpad.c
+++ b/arch/arm/mach-sa1100/simpad.c
@@ -10,7 +10,7 @@
#include <linux/proc_fs.h>
#include <linux/string.h>
#include <linux/pm.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
@@ -60,11 +60,17 @@ EXPORT_SYMBOL(set_cs3_bit);
EXPORT_SYMBOL(clear_cs3_bit);
static struct map_desc simpad_io_desc[] __initdata = {
- /* virtual physical length type */
- /* MQ200 */
- { 0xf2800000, 0x4b800000, 0x00800000, MT_DEVICE },
- /* Paules CS3, write only */
- { 0xf1000000, 0x18000000, 0x00100000, MT_DEVICE },
+ { /* MQ200 */
+ .virtual = 0xf2800000,
+ .pfn = __phys_to_pfn(0x4b800000),
+ .length = 0x00800000,
+ .type = MT_DEVICE
+ }, { /* Paules CS3, write only */
+ .virtual = 0xf1000000,
+ .pfn = __phys_to_pfn(0x18000000),
+ .length = 0x00100000,
+ .type = MT_DEVICE
+ },
};
diff --git a/arch/arm/mach-sa1100/time.c b/arch/arm/mach-sa1100/time.c
index 47e0420623fc..e4b435e634e4 100644
--- a/arch/arm/mach-sa1100/time.c
+++ b/arch/arm/mach-sa1100/time.c
@@ -124,11 +124,13 @@ static void __init sa1100_timer_init(void)
tv.tv_sec = sa1100_get_rtc_time();
do_settimeofday(&tv);
- OSMR0 = 0; /* set initial match at 0 */
+ OIER = 0; /* disable any timer interrupts */
+ OSCR = LATCH*2; /* push OSCR out of the way */
+ OSMR0 = LATCH; /* set initial match */
OSSR = 0xf; /* clear status on all timers */
setup_irq(IRQ_OST0, &sa1100_timer_irq);
- OIER |= OIER_E0; /* enable match on timer 0 to cause interrupts */
- OSCR = 0; /* initialize free-running timer, force first match */
+ OIER = OIER_E0; /* enable match on timer 0 to cause interrupts */
+ OSCR = 0; /* initialize free-running timer */
}
#ifdef CONFIG_NO_IDLE_HZ
diff --git a/arch/arm/mach-shark/core.c b/arch/arm/mach-shark/core.c
index 946c0d11c73b..2d428b6dbb58 100644
--- a/arch/arm/mach-shark/core.c
+++ b/arch/arm/mach-shark/core.c
@@ -62,7 +62,12 @@ arch_initcall(shark_init);
extern void shark_init_irq(void);
static struct map_desc shark_io_desc[] __initdata = {
- { IO_BASE , IO_START , IO_SIZE , MT_DEVICE }
+ {
+ .virtual = IO_BASE,
+ .pfn = __phys_to_pfn(IO_START),
+ .length = IO_SIZE,
+ .type = MT_DEVICE
+ }
};
static void __init shark_map_io(void)
diff --git a/arch/arm/mach-versatile/clock.c b/arch/arm/mach-versatile/clock.c
index 48025c2b9987..b96a2ea15d41 100644
--- a/arch/arm/mach-versatile/clock.c
+++ b/arch/arm/mach-versatile/clock.c
@@ -13,6 +13,7 @@
#include <linux/list.h>
#include <linux/errno.h>
#include <linux/err.h>
+#include <linux/string.h>
#include <asm/semaphore.h>
#include <asm/hardware/clock.h>
diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c
index a30e0451df72..a1ca46630dda 100644
--- a/arch/arm/mach-versatile/core.c
+++ b/arch/arm/mach-versatile/core.c
@@ -22,6 +22,7 @@
#include <linux/init.h>
#include <linux/device.h>
#include <linux/dma-mapping.h>
+#include <linux/platform_device.h>
#include <linux/sysdev.h>
#include <linux/interrupt.h>
@@ -186,25 +187,82 @@ void __init versatile_init_irq(void)
}
static struct map_desc versatile_io_desc[] __initdata = {
- { IO_ADDRESS(VERSATILE_SYS_BASE), VERSATILE_SYS_BASE, SZ_4K, MT_DEVICE },
- { IO_ADDRESS(VERSATILE_SIC_BASE), VERSATILE_SIC_BASE, SZ_4K, MT_DEVICE },
- { IO_ADDRESS(VERSATILE_VIC_BASE), VERSATILE_VIC_BASE, SZ_4K, MT_DEVICE },
- { IO_ADDRESS(VERSATILE_SCTL_BASE), VERSATILE_SCTL_BASE, SZ_4K * 9, MT_DEVICE },
+ {
+ .virtual = IO_ADDRESS(VERSATILE_SYS_BASE),
+ .pfn = __phys_to_pfn(VERSATILE_SYS_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE
+ }, {
+ .virtual = IO_ADDRESS(VERSATILE_SIC_BASE),
+ .pfn = __phys_to_pfn(VERSATILE_SIC_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE
+ }, {
+ .virtual = IO_ADDRESS(VERSATILE_VIC_BASE),
+ .pfn = __phys_to_pfn(VERSATILE_VIC_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE
+ }, {
+ .virtual = IO_ADDRESS(VERSATILE_SCTL_BASE),
+ .pfn = __phys_to_pfn(VERSATILE_SCTL_BASE),
+ .length = SZ_4K * 9,
+ .type = MT_DEVICE
+ },
#ifdef CONFIG_MACH_VERSATILE_AB
- { IO_ADDRESS(VERSATILE_GPIO0_BASE), VERSATILE_GPIO0_BASE, SZ_4K, MT_DEVICE },
- { IO_ADDRESS(VERSATILE_IB2_BASE), VERSATILE_IB2_BASE, SZ_64M, MT_DEVICE },
+ {
+ .virtual = IO_ADDRESS(VERSATILE_GPIO0_BASE),
+ .pfn = __phys_to_pfn(VERSATILE_GPIO0_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE
+ }, {
+ .virtual = IO_ADDRESS(VERSATILE_IB2_BASE),
+ .pfn = __phys_to_pfn(VERSATILE_IB2_BASE),
+ .length = SZ_64M,
+ .type = MT_DEVICE
+ },
#endif
#ifdef CONFIG_DEBUG_LL
- { IO_ADDRESS(VERSATILE_UART0_BASE), VERSATILE_UART0_BASE, SZ_4K, MT_DEVICE },
+ {
+ .virtual = IO_ADDRESS(VERSATILE_UART0_BASE),
+ .pfn = __phys_to_pfn(VERSATILE_UART0_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE
+ },
#endif
#ifdef CONFIG_PCI
- { IO_ADDRESS(VERSATILE_PCI_CORE_BASE), VERSATILE_PCI_CORE_BASE, SZ_4K, MT_DEVICE },
- { VERSATILE_PCI_VIRT_BASE, VERSATILE_PCI_BASE, VERSATILE_PCI_BASE_SIZE, MT_DEVICE },
- { VERSATILE_PCI_CFG_VIRT_BASE, VERSATILE_PCI_CFG_BASE, VERSATILE_PCI_CFG_BASE_SIZE, MT_DEVICE },
+ {
+ .virtual = IO_ADDRESS(VERSATILE_PCI_CORE_BASE),
+ .pfn = __phys_to_pfn(VERSATILE_PCI_CORE_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE
+ }, {
+ .virtual = VERSATILE_PCI_VIRT_BASE,
+ .pfn = __phys_to_pfn(VERSATILE_PCI_BASE),
+ .length = VERSATILE_PCI_BASE_SIZE,
+ .type = MT_DEVICE
+ }, {
+ .virtual = VERSATILE_PCI_CFG_VIRT_BASE,
+ .pfn = __phys_to_pfn(VERSATILE_PCI_CFG_BASE),
+ .length = VERSATILE_PCI_CFG_BASE_SIZE,
+ .type = MT_DEVICE
+ },
#if 0
- { VERSATILE_PCI_VIRT_MEM_BASE0, VERSATILE_PCI_MEM_BASE0, SZ_16M, MT_DEVICE },
- { VERSATILE_PCI_VIRT_MEM_BASE1, VERSATILE_PCI_MEM_BASE1, SZ_16M, MT_DEVICE },
- { VERSATILE_PCI_VIRT_MEM_BASE2, VERSATILE_PCI_MEM_BASE2, SZ_16M, MT_DEVICE },
+ {
+ .virtual = VERSATILE_PCI_VIRT_MEM_BASE0,
+ .pfn = __phys_to_pfn(VERSATILE_PCI_MEM_BASE0),
+ .length = SZ_16M,
+ .type = MT_DEVICE
+ }, {
+ .virtual = VERSATILE_PCI_VIRT_MEM_BASE1,
+ .pfn = __phys_to_pfn(VERSATILE_PCI_MEM_BASE1),
+ .length = SZ_16M,
+ .type = MT_DEVICE
+ }, {
+ .virtual = VERSATILE_PCI_VIRT_MEM_BASE2,
+ .pfn = __phys_to_pfn(VERSATILE_PCI_MEM_BASE2),
+ .length = SZ_16M,
+ .type = MT_DEVICE
+ },
#endif
#endif
};
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index c54e04c995ee..e84fdde6edf8 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -102,8 +102,8 @@ config CPU_ARM922T
# ARM925T
config CPU_ARM925T
bool "Support ARM925T processor" if ARCH_OMAP1
- depends on ARCH_OMAP1510
- default y if ARCH_OMAP1510
+ depends on ARCH_OMAP15XX
+ default y if ARCH_OMAP15XX
select CPU_32v4
select CPU_ABRT_EV4T
select CPU_CACHE_V4WT
@@ -120,8 +120,8 @@ config CPU_ARM925T
# ARM926T
config CPU_ARM926T
- bool "Support ARM926T processor" if ARCH_INTEGRATOR
- depends on ARCH_INTEGRATOR || ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX
+ bool "Support ARM926T processor"
+ depends on ARCH_INTEGRATOR || ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX || MACH_REALVIEW_EB
default y if ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX
select CPU_32v5
select CPU_ABRT_EV5TJ
@@ -242,7 +242,7 @@ config CPU_XSCALE
# ARMv6
config CPU_V6
bool "Support ARM V6 processor"
- depends on ARCH_INTEGRATOR
+ depends on ARCH_INTEGRATOR || MACH_REALVIEW_EB || ARCH_OMAP2
select CPU_32v6
select CPU_ABRT_EV6
select CPU_CACHE_V6
@@ -250,6 +250,18 @@ config CPU_V6
select CPU_COPY_V6
select CPU_TLB_V6
+# ARMv6k
+config CPU_32v6K
+ bool "Support ARM V6K processor extensions" if !SMP
+ depends on CPU_V6
+ default y if SMP
+ help
+ Say Y here if your ARMv6 processor supports the 'K' extension.
+ This enables the kernel to use some instructions not present
+ on previous processors, and as such a kernel build with this
+ enabled will not boot on processors with do not support these
+ instructions.
+
# Figure out what processor architecture version we should be using.
# This defines the compiler instruction set which depends on the machine type.
config CPU_32v3
diff --git a/arch/arm/mm/consistent.c b/arch/arm/mm/consistent.c
index 26356ce4da54..47b0b767f080 100644
--- a/arch/arm/mm/consistent.c
+++ b/arch/arm/mm/consistent.c
@@ -75,7 +75,7 @@ static struct vm_region consistent_head = {
};
static struct vm_region *
-vm_region_alloc(struct vm_region *head, size_t size, int gfp)
+vm_region_alloc(struct vm_region *head, size_t size, gfp_t gfp)
{
unsigned long addr = head->vm_start, end = head->vm_end - size;
unsigned long flags;
@@ -133,7 +133,7 @@ static struct vm_region *vm_region_find(struct vm_region *head, unsigned long ad
#endif
static void *
-__dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, int gfp,
+__dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp,
pgprot_t prot)
{
struct page *page;
@@ -251,7 +251,7 @@ __dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, int gfp,
* virtual and bus address for that space.
*/
void *
-dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *handle, int gfp)
+dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp)
{
return __dma_alloc(dev, size, handle, gfp,
pgprot_noncached(pgprot_kernel));
@@ -263,7 +263,7 @@ EXPORT_SYMBOL(dma_alloc_coherent);
* dma_alloc_coherent above.
*/
void *
-dma_alloc_writecombine(struct device *dev, size_t size, dma_addr_t *handle, int gfp)
+dma_alloc_writecombine(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp)
{
return __dma_alloc(dev, size, handle, gfp,
pgprot_writecombine(pgprot_kernel));
@@ -397,8 +397,6 @@ static int __init consistent_init(void)
pte_t *pte;
int ret = 0;
- spin_lock(&init_mm.page_table_lock);
-
do {
pgd = pgd_offset(&init_mm, CONSISTENT_BASE);
pmd = pmd_alloc(&init_mm, pgd, CONSISTENT_BASE);
@@ -409,7 +407,7 @@ static int __init consistent_init(void)
}
WARN_ON(!pmd_none(*pmd));
- pte = pte_alloc_kernel(&init_mm, pmd, CONSISTENT_BASE);
+ pte = pte_alloc_kernel(pmd, CONSISTENT_BASE);
if (!pte) {
printk(KERN_ERR "%s: no pte tables\n", __func__);
ret = -ENOMEM;
@@ -419,8 +417,6 @@ static int __init consistent_init(void)
consistent_pte = pte;
} while (0);
- spin_unlock(&init_mm.page_table_lock);
-
return ret;
}
diff --git a/arch/arm/mm/copypage-v6.c b/arch/arm/mm/copypage-v6.c
index 27d041574ea7..269ce6913ee9 100644
--- a/arch/arm/mm/copypage-v6.c
+++ b/arch/arm/mm/copypage-v6.c
@@ -22,9 +22,7 @@
#endif
#define from_address (0xffff8000)
-#define from_pgprot PAGE_KERNEL
#define to_address (0xffffc000)
-#define to_pgprot PAGE_KERNEL
#define TOP_PTE(x) pte_offset_kernel(top_pmd, x)
@@ -34,7 +32,7 @@ static DEFINE_SPINLOCK(v6_lock);
* Copy the user page. No aliasing to deal with so we can just
* attack the kernel's existing mapping of these pages.
*/
-void v6_copy_user_page_nonaliasing(void *kto, const void *kfrom, unsigned long vaddr)
+static void v6_copy_user_page_nonaliasing(void *kto, const void *kfrom, unsigned long vaddr)
{
copy_page(kto, kfrom);
}
@@ -43,7 +41,7 @@ void v6_copy_user_page_nonaliasing(void *kto, const void *kfrom, unsigned long v
* Clear the user page. No aliasing to deal with so we can just
* attack the kernel's existing mapping of this page.
*/
-void v6_clear_user_page_nonaliasing(void *kaddr, unsigned long vaddr)
+static void v6_clear_user_page_nonaliasing(void *kaddr, unsigned long vaddr)
{
clear_page(kaddr);
}
@@ -51,7 +49,7 @@ void v6_clear_user_page_nonaliasing(void *kaddr, unsigned long vaddr)
/*
* Copy the page, taking account of the cache colour.
*/
-void v6_copy_user_page_aliasing(void *kto, const void *kfrom, unsigned long vaddr)
+static void v6_copy_user_page_aliasing(void *kto, const void *kfrom, unsigned long vaddr)
{
unsigned int offset = CACHE_COLOUR(vaddr);
unsigned long from, to;
@@ -72,8 +70,8 @@ void v6_copy_user_page_aliasing(void *kto, const void *kfrom, unsigned long vadd
*/
spin_lock(&v6_lock);
- set_pte(TOP_PTE(from_address) + offset, pfn_pte(__pa(kfrom) >> PAGE_SHIFT, from_pgprot));
- set_pte(TOP_PTE(to_address) + offset, pfn_pte(__pa(kto) >> PAGE_SHIFT, to_pgprot));
+ set_pte(TOP_PTE(from_address) + offset, pfn_pte(__pa(kfrom) >> PAGE_SHIFT, PAGE_KERNEL));
+ set_pte(TOP_PTE(to_address) + offset, pfn_pte(__pa(kto) >> PAGE_SHIFT, PAGE_KERNEL));
from = from_address + (offset << PAGE_SHIFT);
to = to_address + (offset << PAGE_SHIFT);
@@ -91,7 +89,7 @@ void v6_copy_user_page_aliasing(void *kto, const void *kfrom, unsigned long vadd
* so remap the kernel page into the same cache colour as the user
* page.
*/
-void v6_clear_user_page_aliasing(void *kaddr, unsigned long vaddr)
+static void v6_clear_user_page_aliasing(void *kaddr, unsigned long vaddr)
{
unsigned int offset = CACHE_COLOUR(vaddr);
unsigned long to = to_address + (offset << PAGE_SHIFT);
@@ -112,7 +110,7 @@ void v6_clear_user_page_aliasing(void *kaddr, unsigned long vaddr)
*/
spin_lock(&v6_lock);
- set_pte(TOP_PTE(to_address) + offset, pfn_pte(__pa(kaddr) >> PAGE_SHIFT, to_pgprot));
+ set_pte(TOP_PTE(to_address) + offset, pfn_pte(__pa(kaddr) >> PAGE_SHIFT, PAGE_KERNEL));
flush_tlb_kernel_page(to);
clear_page((void *)to);
diff --git a/arch/arm/mm/fault-armv.c b/arch/arm/mm/fault-armv.c
index be4ab3d73c91..7fc1b35a6746 100644
--- a/arch/arm/mm/fault-armv.c
+++ b/arch/arm/mm/fault-armv.c
@@ -26,6 +26,11 @@ static unsigned long shared_pte_mask = L_PTE_CACHEABLE;
/*
* We take the easy way out of this problem - we make the
* PTE uncacheable. However, we leave the write buffer on.
+ *
+ * Note that the pte lock held when calling update_mmu_cache must also
+ * guard the pte (somewhere else in the same mm) that we modify here.
+ * Therefore those configurations which might call adjust_pte (those
+ * without CONFIG_CPU_CACHE_VIPT) cannot support split page_table_lock.
*/
static int adjust_pte(struct vm_area_struct *vma, unsigned long address)
{
@@ -127,7 +132,7 @@ void __flush_dcache_page(struct address_space *mapping, struct page *page);
* 2. If we have multiple shared mappings of the same space in
* an object, we need to deal with the cache aliasing issues.
*
- * Note that the page_table_lock will be held.
+ * Note that the pte lock will be held.
*/
void update_mmu_cache(struct vm_area_struct *vma, unsigned long addr, pte_t pte)
{
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index edffa47a4b2a..c168f322ef8c 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -1,7 +1,7 @@
/*
* linux/arch/arm/mm/init.c
*
- * Copyright (C) 1995-2002 Russell King
+ * Copyright (C) 1995-2005 Russell King
*
* 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
@@ -86,14 +86,19 @@ void show_mem(void)
printk("%d pages swap cached\n", cached);
}
-struct node_info {
- unsigned int start;
- unsigned int end;
- int bootmap_pages;
-};
+static inline pmd_t *pmd_off(pgd_t *pgd, unsigned long virt)
+{
+ return pmd_offset(pgd, virt);
+}
+
+static inline pmd_t *pmd_off_k(unsigned long virt)
+{
+ return pmd_off(pgd_offset_k(virt), virt);
+}
-#define O_PFN_DOWN(x) ((x) >> PAGE_SHIFT)
-#define O_PFN_UP(x) (PAGE_ALIGN(x) >> PAGE_SHIFT)
+#define for_each_nodebank(iter,mi,no) \
+ for (iter = 0; iter < mi->nr_banks; iter++) \
+ if (mi->bank[iter].node == no)
/*
* FIXME: We really want to avoid allocating the bootmap bitmap
@@ -106,15 +111,12 @@ find_bootmap_pfn(int node, struct meminfo *mi, unsigned int bootmap_pages)
{
unsigned int start_pfn, bank, bootmap_pfn;
- start_pfn = O_PFN_UP(__pa(&_end));
+ start_pfn = PAGE_ALIGN(__pa(&_end)) >> PAGE_SHIFT;
bootmap_pfn = 0;
- for (bank = 0; bank < mi->nr_banks; bank ++) {
+ for_each_nodebank(bank, mi, node) {
unsigned int start, end;
- if (mi->bank[bank].node != node)
- continue;
-
start = mi->bank[bank].start >> PAGE_SHIFT;
end = (mi->bank[bank].size +
mi->bank[bank].start) >> PAGE_SHIFT;
@@ -140,92 +142,6 @@ find_bootmap_pfn(int node, struct meminfo *mi, unsigned int bootmap_pages)
return bootmap_pfn;
}
-/*
- * Scan the memory info structure and pull out:
- * - the end of memory
- * - the number of nodes
- * - the pfn range of each node
- * - the number of bootmem bitmap pages
- */
-static unsigned int __init
-find_memend_and_nodes(struct meminfo *mi, struct node_info *np)
-{
- unsigned int i, bootmem_pages = 0, memend_pfn = 0;
-
- for (i = 0; i < MAX_NUMNODES; i++) {
- np[i].start = -1U;
- np[i].end = 0;
- np[i].bootmap_pages = 0;
- }
-
- for (i = 0; i < mi->nr_banks; i++) {
- unsigned long start, end;
- int node;
-
- if (mi->bank[i].size == 0) {
- /*
- * Mark this bank with an invalid node number
- */
- mi->bank[i].node = -1;
- continue;
- }
-
- node = mi->bank[i].node;
-
- /*
- * Make sure we haven't exceeded the maximum number of nodes
- * that we have in this configuration. If we have, we're in
- * trouble. (maybe we ought to limit, instead of bugging?)
- */
- if (node >= MAX_NUMNODES)
- BUG();
- node_set_online(node);
-
- /*
- * Get the start and end pfns for this bank
- */
- start = mi->bank[i].start >> PAGE_SHIFT;
- end = (mi->bank[i].start + mi->bank[i].size) >> PAGE_SHIFT;
-
- if (np[node].start > start)
- np[node].start = start;
-
- if (np[node].end < end)
- np[node].end = end;
-
- if (memend_pfn < end)
- memend_pfn = end;
- }
-
- /*
- * Calculate the number of pages we require to
- * store the bootmem bitmaps.
- */
- for_each_online_node(i) {
- if (np[i].end == 0)
- continue;
-
- np[i].bootmap_pages = bootmem_bootmap_pages(np[i].end -
- np[i].start);
- bootmem_pages += np[i].bootmap_pages;
- }
-
- high_memory = __va(memend_pfn << PAGE_SHIFT);
-
- /*
- * This doesn't seem to be used by the Linux memory
- * manager any more. If we can get rid of it, we
- * also get rid of some of the stuff above as well.
- *
- * Note: max_low_pfn and max_pfn reflect the number
- * of _pages_ in the system, not the maximum PFN.
- */
- max_low_pfn = memend_pfn - O_PFN_DOWN(PHYS_OFFSET);
- max_pfn = memend_pfn - O_PFN_DOWN(PHYS_OFFSET);
-
- return bootmem_pages;
-}
-
static int __init check_initrd(struct meminfo *mi)
{
int initrd_node = -2;
@@ -266,9 +182,8 @@ static int __init check_initrd(struct meminfo *mi)
/*
* Reserve the various regions of node 0
*/
-static __init void reserve_node_zero(unsigned int bootmap_pfn, unsigned int bootmap_pages)
+static __init void reserve_node_zero(pg_data_t *pgdat)
{
- pg_data_t *pgdat = NODE_DATA(0);
unsigned long res_size = 0;
/*
@@ -289,13 +204,6 @@ static __init void reserve_node_zero(unsigned int bootmap_pfn, unsigned int boot
PTRS_PER_PGD * sizeof(pgd_t));
/*
- * And don't forget to reserve the allocator bitmap,
- * which will be freed later.
- */
- reserve_bootmem_node(pgdat, bootmap_pfn << PAGE_SHIFT,
- bootmap_pages << PAGE_SHIFT);
-
- /*
* Hmm... This should go elsewhere, but we really really need to
* stop things allocating the low memory; ideally we need a better
* implementation of GFP_DMA which does not assume that DMA-able
@@ -324,183 +232,291 @@ static __init void reserve_node_zero(unsigned int bootmap_pfn, unsigned int boot
reserve_bootmem_node(pgdat, PHYS_OFFSET, res_size);
}
-/*
- * Register all available RAM in this node with the bootmem allocator.
- */
-static inline void free_bootmem_node_bank(int node, struct meminfo *mi)
+void __init build_mem_type_table(void);
+void __init create_mapping(struct map_desc *md);
+
+static unsigned long __init
+bootmem_init_node(int node, int initrd_node, struct meminfo *mi)
{
- pg_data_t *pgdat = NODE_DATA(node);
- int bank;
+ unsigned long zone_size[MAX_NR_ZONES], zhole_size[MAX_NR_ZONES];
+ unsigned long start_pfn, end_pfn, boot_pfn;
+ unsigned int boot_pages;
+ pg_data_t *pgdat;
+ int i;
- for (bank = 0; bank < mi->nr_banks; bank++)
- if (mi->bank[bank].node == node)
- free_bootmem_node(pgdat, mi->bank[bank].start,
- mi->bank[bank].size);
-}
+ start_pfn = -1UL;
+ end_pfn = 0;
-/*
- * Initialise the bootmem allocator for all nodes. This is called
- * early during the architecture specific initialisation.
- */
-static void __init bootmem_init(struct meminfo *mi)
-{
- struct node_info node_info[MAX_NUMNODES], *np = node_info;
- unsigned int bootmap_pages, bootmap_pfn, map_pg;
- int node, initrd_node;
+ /*
+ * Calculate the pfn range, and map the memory banks for this node.
+ */
+ for_each_nodebank(i, mi, node) {
+ unsigned long start, end;
+ struct map_desc map;
+
+ start = mi->bank[i].start >> PAGE_SHIFT;
+ end = (mi->bank[i].start + mi->bank[i].size) >> PAGE_SHIFT;
+
+ if (start_pfn > start)
+ start_pfn = start;
+ if (end_pfn < end)
+ end_pfn = end;
- bootmap_pages = find_memend_and_nodes(mi, np);
- bootmap_pfn = find_bootmap_pfn(0, mi, bootmap_pages);
- initrd_node = check_initrd(mi);
+ map.pfn = __phys_to_pfn(mi->bank[i].start);
+ map.virtual = __phys_to_virt(mi->bank[i].start);
+ map.length = mi->bank[i].size;
+ map.type = MT_MEMORY;
- map_pg = bootmap_pfn;
+ create_mapping(&map);
+ }
/*
- * Initialise the bootmem nodes.
- *
- * What we really want to do is:
- *
- * unmap_all_regions_except_kernel();
- * for_each_node_in_reverse_order(node) {
- * map_node(node);
- * allocate_bootmem_map(node);
- * init_bootmem_node(node);
- * free_bootmem_node(node);
- * }
- *
- * but this is a 2.5-type change. For now, we just set
- * the nodes up in reverse order.
- *
- * (we could also do with rolling bootmem_init and paging_init
- * into one generic "memory_init" type function).
+ * If there is no memory in this node, ignore it.
*/
- np += num_online_nodes() - 1;
- for (node = num_online_nodes() - 1; node >= 0; node--, np--) {
- /*
- * If there are no pages in this node, ignore it.
- * Note that node 0 must always have some pages.
- */
- if (np->end == 0 || !node_online(node)) {
- if (node == 0)
- BUG();
- continue;
- }
+ if (end_pfn == 0)
+ return end_pfn;
- /*
- * Initialise the bootmem allocator.
- */
- init_bootmem_node(NODE_DATA(node), map_pg, np->start, np->end);
- free_bootmem_node_bank(node, mi);
- map_pg += np->bootmap_pages;
+ /*
+ * Allocate the bootmem bitmap page.
+ */
+ boot_pages = bootmem_bootmap_pages(end_pfn - start_pfn);
+ boot_pfn = find_bootmap_pfn(node, mi, boot_pages);
- /*
- * If this is node 0, we need to reserve some areas ASAP -
- * we may use bootmem on node 0 to setup the other nodes.
- */
- if (node == 0)
- reserve_node_zero(bootmap_pfn, bootmap_pages);
- }
+ /*
+ * Initialise the bootmem allocator for this node, handing the
+ * memory banks over to bootmem.
+ */
+ node_set_online(node);
+ pgdat = NODE_DATA(node);
+ init_bootmem_node(pgdat, boot_pfn, start_pfn, end_pfn);
+ for_each_nodebank(i, mi, node)
+ free_bootmem_node(pgdat, mi->bank[i].start, mi->bank[i].size);
+
+ /*
+ * Reserve the bootmem bitmap for this node.
+ */
+ reserve_bootmem_node(pgdat, boot_pfn << PAGE_SHIFT,
+ boot_pages << PAGE_SHIFT);
#ifdef CONFIG_BLK_DEV_INITRD
- if (phys_initrd_size && initrd_node >= 0) {
- reserve_bootmem_node(NODE_DATA(initrd_node), phys_initrd_start,
+ /*
+ * If the initrd is in this node, reserve its memory.
+ */
+ if (node == initrd_node) {
+ reserve_bootmem_node(pgdat, phys_initrd_start,
phys_initrd_size);
initrd_start = __phys_to_virt(phys_initrd_start);
initrd_end = initrd_start + phys_initrd_size;
}
#endif
- BUG_ON(map_pg != bootmap_pfn + bootmap_pages);
+ /*
+ * Finally, reserve any node zero regions.
+ */
+ if (node == 0)
+ reserve_node_zero(pgdat);
+
+ /*
+ * initialise the zones within this node.
+ */
+ memset(zone_size, 0, sizeof(zone_size));
+ memset(zhole_size, 0, sizeof(zhole_size));
+
+ /*
+ * The size of this node has already been determined. If we need
+ * to do anything fancy with the allocation of this memory to the
+ * zones, now is the time to do it.
+ */
+ zone_size[0] = end_pfn - start_pfn;
+
+ /*
+ * For each bank in this node, calculate the size of the holes.
+ * holes = node_size - sum(bank_sizes_in_node)
+ */
+ zhole_size[0] = zone_size[0];
+ for_each_nodebank(i, mi, node)
+ zhole_size[0] -= mi->bank[i].size >> PAGE_SHIFT;
+
+ /*
+ * Adjust the sizes according to any special requirements for
+ * this machine type.
+ */
+ arch_adjust_zones(node, zone_size, zhole_size);
+
+ free_area_init_node(node, pgdat, zone_size, start_pfn, zhole_size);
+
+ return end_pfn;
}
-/*
- * paging_init() sets up the page tables, initialises the zone memory
- * maps, and sets up the zero page, bad page and bad page tables.
- */
-void __init paging_init(struct meminfo *mi, struct machine_desc *mdesc)
+static void __init bootmem_init(struct meminfo *mi)
{
- void *zero_page;
- int node;
+ unsigned long addr, memend_pfn = 0;
+ int node, initrd_node, i;
- bootmem_init(mi);
+ /*
+ * Invalidate the node number for empty or invalid memory banks
+ */
+ for (i = 0; i < mi->nr_banks; i++)
+ if (mi->bank[i].size == 0 || mi->bank[i].node >= MAX_NUMNODES)
+ mi->bank[i].node = -1;
memcpy(&meminfo, mi, sizeof(meminfo));
/*
- * allocate the zero page. Note that we count on this going ok.
+ * Clear out all the mappings below the kernel image.
*/
- zero_page = alloc_bootmem_low_pages(PAGE_SIZE);
+ for (addr = 0; addr < MODULE_START; addr += PGDIR_SIZE)
+ pmd_clear(pmd_off_k(addr));
+#ifdef CONFIG_XIP_KERNEL
+ /* The XIP kernel is mapped in the module area -- skip over it */
+ addr = ((unsigned long)&_etext + PGDIR_SIZE - 1) & PGDIR_MASK;
+#endif
+ for ( ; addr < PAGE_OFFSET; addr += PGDIR_SIZE)
+ pmd_clear(pmd_off_k(addr));
/*
- * initialise the page tables.
+ * Clear out all the kernel space mappings, except for the first
+ * memory bank, up to the end of the vmalloc region.
*/
- memtable_init(mi);
- if (mdesc->map_io)
- mdesc->map_io();
- local_flush_tlb_all();
+ for (addr = __phys_to_virt(mi->bank[0].start + mi->bank[0].size);
+ addr < VMALLOC_END; addr += PGDIR_SIZE)
+ pmd_clear(pmd_off_k(addr));
/*
- * initialise the zones within each node
+ * Locate which node contains the ramdisk image, if any.
*/
- for_each_online_node(node) {
- unsigned long zone_size[MAX_NR_ZONES];
- unsigned long zhole_size[MAX_NR_ZONES];
- struct bootmem_data *bdata;
- pg_data_t *pgdat;
- int i;
+ initrd_node = check_initrd(mi);
- /*
- * Initialise the zone size information.
- */
- for (i = 0; i < MAX_NR_ZONES; i++) {
- zone_size[i] = 0;
- zhole_size[i] = 0;
- }
+ /*
+ * Run through each node initialising the bootmem allocator.
+ */
+ for_each_node(node) {
+ unsigned long end_pfn;
- pgdat = NODE_DATA(node);
- bdata = pgdat->bdata;
+ end_pfn = bootmem_init_node(node, initrd_node, mi);
/*
- * The size of this node has already been determined.
- * If we need to do anything fancy with the allocation
- * of this memory to the zones, now is the time to do
- * it.
+ * Remember the highest memory PFN.
*/
- zone_size[0] = bdata->node_low_pfn -
- (bdata->node_boot_start >> PAGE_SHIFT);
+ if (end_pfn > memend_pfn)
+ memend_pfn = end_pfn;
+ }
- /*
- * If this zone has zero size, skip it.
- */
- if (!zone_size[0])
- continue;
+ high_memory = __va(memend_pfn << PAGE_SHIFT);
- /*
- * For each bank in this node, calculate the size of the
- * holes. holes = node_size - sum(bank_sizes_in_node)
- */
- zhole_size[0] = zone_size[0];
- for (i = 0; i < mi->nr_banks; i++) {
- if (mi->bank[i].node != node)
- continue;
+ /*
+ * This doesn't seem to be used by the Linux memory manager any
+ * more, but is used by ll_rw_block. If we can get rid of it, we
+ * also get rid of some of the stuff above as well.
+ *
+ * Note: max_low_pfn and max_pfn reflect the number of _pages_ in
+ * the system, not the maximum PFN.
+ */
+ max_pfn = max_low_pfn = memend_pfn - PHYS_PFN_OFFSET;
+}
- zhole_size[0] -= mi->bank[i].size >> PAGE_SHIFT;
- }
+/*
+ * Set up device the mappings. Since we clear out the page tables for all
+ * mappings above VMALLOC_END, we will remove any debug device mappings.
+ * This means you have to be careful how you debug this function, or any
+ * called function. (Do it by code inspection!)
+ */
+static void __init devicemaps_init(struct machine_desc *mdesc)
+{
+ struct map_desc map;
+ unsigned long addr;
+ void *vectors;
- /*
- * Adjust the sizes according to any special
- * requirements for this machine type.
- */
- arch_adjust_zones(node, zone_size, zhole_size);
+ for (addr = VMALLOC_END; addr; addr += PGDIR_SIZE)
+ pmd_clear(pmd_off_k(addr));
- free_area_init_node(node, pgdat, zone_size,
- bdata->node_boot_start >> PAGE_SHIFT, zhole_size);
+ /*
+ * Map the kernel if it is XIP.
+ * It is always first in the modulearea.
+ */
+#ifdef CONFIG_XIP_KERNEL
+ map.pfn = __phys_to_pfn(CONFIG_XIP_PHYS_ADDR & PGDIR_MASK);
+ map.virtual = MODULE_START;
+ map.length = ((unsigned long)&_etext - map.virtual + ~PGDIR_MASK) & PGDIR_MASK;
+ map.type = MT_ROM;
+ create_mapping(&map);
+#endif
+
+ /*
+ * Map the cache flushing regions.
+ */
+#ifdef FLUSH_BASE
+ map.pfn = __phys_to_pfn(FLUSH_BASE_PHYS);
+ map.virtual = FLUSH_BASE;
+ map.length = PGDIR_SIZE;
+ map.type = MT_CACHECLEAN;
+ create_mapping(&map);
+#endif
+#ifdef FLUSH_BASE_MINICACHE
+ map.pfn = __phys_to_pfn(FLUSH_BASE_PHYS + PGDIR_SIZE);
+ map.virtual = FLUSH_BASE_MINICACHE;
+ map.length = PGDIR_SIZE;
+ map.type = MT_MINICLEAN;
+ create_mapping(&map);
+#endif
+
+ flush_cache_all();
+ local_flush_tlb_all();
+
+ vectors = alloc_bootmem_low_pages(PAGE_SIZE);
+ BUG_ON(!vectors);
+
+ /*
+ * Create a mapping for the machine vectors at the high-vectors
+ * location (0xffff0000). If we aren't using high-vectors, also
+ * create a mapping at the low-vectors virtual address.
+ */
+ map.pfn = __phys_to_pfn(virt_to_phys(vectors));
+ map.virtual = 0xffff0000;
+ map.length = PAGE_SIZE;
+ map.type = MT_HIGH_VECTORS;
+ create_mapping(&map);
+
+ if (!vectors_high()) {
+ map.virtual = 0;
+ map.type = MT_LOW_VECTORS;
+ create_mapping(&map);
}
/*
- * finish off the bad pages once
- * the mem_map is initialised
+ * Ask the machine support to map in the statically mapped devices.
+ */
+ if (mdesc->map_io)
+ mdesc->map_io();
+
+ /*
+ * Finally flush the tlb again - this ensures that we're in a
+ * consistent state wrt the writebuffer if the writebuffer needs
+ * draining. After this point, we can start to touch devices
+ * again.
*/
+ local_flush_tlb_all();
+}
+
+/*
+ * paging_init() sets up the page tables, initialises the zone memory
+ * maps, and sets up the zero page, bad page and bad page tables.
+ */
+void __init paging_init(struct meminfo *mi, struct machine_desc *mdesc)
+{
+ void *zero_page;
+
+ build_mem_type_table();
+ bootmem_init(mi);
+ devicemaps_init(mdesc);
+
+ top_pmd = pmd_off_k(0xffff0000);
+
+ /*
+ * allocate the zero page. Note that we count on this going ok.
+ */
+ zero_page = alloc_bootmem_low_pages(PAGE_SIZE);
memzero(zero_page, PAGE_SIZE);
empty_zero_page = virt_to_page(zero_page);
flush_dcache_page(empty_zero_page);
@@ -562,10 +578,7 @@ static void __init free_unused_memmap_node(int node, struct meminfo *mi)
* may not be the case, especially if the user has provided the
* information on the command line.
*/
- for (i = 0; i < mi->nr_banks; i++) {
- if (mi->bank[i].size == 0 || mi->bank[i].node != node)
- continue;
-
+ for_each_nodebank(i, mi, node) {
bank_start = mi->bank[i].start >> PAGE_SHIFT;
if (bank_start < prev_bank_end) {
printk(KERN_ERR "MEM: unordered memory banks. "
diff --git a/arch/arm/mm/ioremap.c b/arch/arm/mm/ioremap.c
index 7110e54182b1..0f128c28fee4 100644
--- a/arch/arm/mm/ioremap.c
+++ b/arch/arm/mm/ioremap.c
@@ -26,6 +26,7 @@
#include <linux/vmalloc.h>
#include <asm/cacheflush.h>
+#include <asm/hardware.h>
#include <asm/io.h>
#include <asm/tlbflush.h>
@@ -74,7 +75,7 @@ remap_area_pmd(pmd_t * pmd, unsigned long address, unsigned long size,
pgprot = __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY | L_PTE_WRITE | flags);
do {
- pte_t * pte = pte_alloc_kernel(&init_mm, pmd, address);
+ pte_t * pte = pte_alloc_kernel(pmd, address);
if (!pte)
return -ENOMEM;
remap_area_pte(pte, address, end - address, address + phys_addr, pgprot);
@@ -96,7 +97,6 @@ remap_area_pages(unsigned long start, unsigned long phys_addr,
phys_addr -= address;
dir = pgd_offset(&init_mm, address);
BUG_ON(address >= end);
- spin_lock(&init_mm.page_table_lock);
do {
pmd_t *pmd = pmd_alloc(&init_mm, dir, address);
if (!pmd) {
@@ -113,7 +113,6 @@ remap_area_pages(unsigned long start, unsigned long phys_addr,
dir++;
} while (address && (address < end));
- spin_unlock(&init_mm.page_table_lock);
flush_cache_vmap(start, end);
return err;
}
diff --git a/arch/arm/mm/mm-armv.c b/arch/arm/mm/mm-armv.c
index d125a3dc061c..9e50127be635 100644
--- a/arch/arm/mm/mm-armv.c
+++ b/arch/arm/mm/mm-armv.c
@@ -1,7 +1,7 @@
/*
* linux/arch/arm/mm/mm-armv.c
*
- * Copyright (C) 1998-2002 Russell King
+ * Copyright (C) 1998-2005 Russell King
*
* 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
@@ -180,11 +180,6 @@ pgd_t *get_pgd_slow(struct mm_struct *mm)
if (!vectors_high()) {
/*
- * This lock is here just to satisfy pmd_alloc and pte_lock
- */
- spin_lock(&mm->page_table_lock);
-
- /*
* On ARM, first page must always be allocated since it
* contains the machine vectors.
*/
@@ -201,23 +196,14 @@ pgd_t *get_pgd_slow(struct mm_struct *mm)
set_pte(new_pte, *init_pte);
pte_unmap_nested(init_pte);
pte_unmap(new_pte);
-
- spin_unlock(&mm->page_table_lock);
}
return new_pgd;
no_pte:
- spin_unlock(&mm->page_table_lock);
pmd_free(new_pmd);
- free_pages((unsigned long)new_pgd, 2);
- return NULL;
-
no_pmd:
- spin_unlock(&mm->page_table_lock);
free_pages((unsigned long)new_pgd, 2);
- return NULL;
-
no_pgd:
return NULL;
}
@@ -243,6 +229,7 @@ void free_pgd_slow(pgd_t *pgd)
pte = pmd_page(*pmd);
pmd_clear(pmd);
dec_page_state(nr_page_table_pages);
+ pte_lock_deinit(pte);
pte_free(pte);
pmd_free(pmd);
free:
@@ -305,16 +292,6 @@ alloc_init_page(unsigned long virt, unsigned long phys, unsigned int prot_l1, pg
set_pte(ptep, pfn_pte(phys >> PAGE_SHIFT, prot));
}
-/*
- * Clear any PGD mapping. On a two-level page table system,
- * the clearance is done by the middle-level functions (pmd)
- * rather than the top-level (pgd) functions.
- */
-static inline void clear_mapping(unsigned long virt)
-{
- pmd_clear(pmd_off_k(virt));
-}
-
struct mem_types {
unsigned int prot_pte;
unsigned int prot_l1;
@@ -373,11 +350,11 @@ static struct mem_types mem_types[] __initdata = {
/*
* Adjust the PMD section entries according to the CPU in use.
*/
-static void __init build_mem_type_table(void)
+void __init build_mem_type_table(void)
{
struct cachepolicy *cp;
unsigned int cr = get_cr();
- unsigned int user_pgprot;
+ unsigned int user_pgprot, kern_pgprot;
int cpu_arch = cpu_architecture();
int i;
@@ -404,7 +381,7 @@ static void __init build_mem_type_table(void)
}
cp = &cache_policies[cachepolicy];
- user_pgprot = cp->pte;
+ kern_pgprot = user_pgprot = cp->pte;
/*
* ARMv6 and above have extended page tables.
@@ -416,6 +393,7 @@ static void __init build_mem_type_table(void)
*/
mem_types[MT_MEMORY].prot_sect &= ~PMD_BIT4;
mem_types[MT_ROM].prot_sect &= ~PMD_BIT4;
+
/*
* Mark cache clean areas and XIP ROM read only
* from SVC mode and no access from userspace.
@@ -435,32 +413,47 @@ static void __init build_mem_type_table(void)
* (iow, non-global)
*/
user_pgprot |= L_PTE_ASID;
+
+#ifdef CONFIG_SMP
+ /*
+ * Mark memory with the "shared" attribute for SMP systems
+ */
+ user_pgprot |= L_PTE_SHARED;
+ kern_pgprot |= L_PTE_SHARED;
+ mem_types[MT_MEMORY].prot_sect |= PMD_SECT_S;
+#endif
}
+ for (i = 0; i < 16; i++) {
+ unsigned long v = pgprot_val(protection_map[i]);
+ v = (v & ~(L_PTE_BUFFERABLE|L_PTE_CACHEABLE)) | user_pgprot;
+ protection_map[i] = __pgprot(v);
+ }
+
+ mem_types[MT_LOW_VECTORS].prot_pte |= kern_pgprot;
+ mem_types[MT_HIGH_VECTORS].prot_pte |= kern_pgprot;
+
if (cpu_arch >= CPU_ARCH_ARMv5) {
- mem_types[MT_LOW_VECTORS].prot_pte |= cp->pte & PTE_CACHEABLE;
- mem_types[MT_HIGH_VECTORS].prot_pte |= cp->pte & PTE_CACHEABLE;
+#ifndef CONFIG_SMP
+ /*
+ * Only use write-through for non-SMP systems
+ */
+ mem_types[MT_LOW_VECTORS].prot_pte &= ~L_PTE_BUFFERABLE;
+ mem_types[MT_HIGH_VECTORS].prot_pte &= ~L_PTE_BUFFERABLE;
+#endif
} else {
- mem_types[MT_LOW_VECTORS].prot_pte |= cp->pte;
- mem_types[MT_HIGH_VECTORS].prot_pte |= cp->pte;
mem_types[MT_MINICLEAN].prot_sect &= ~PMD_SECT_TEX(1);
}
+ pgprot_kernel = __pgprot(L_PTE_PRESENT | L_PTE_YOUNG |
+ L_PTE_DIRTY | L_PTE_WRITE |
+ L_PTE_EXEC | kern_pgprot);
+
mem_types[MT_LOW_VECTORS].prot_l1 |= ecc_mask;
mem_types[MT_HIGH_VECTORS].prot_l1 |= ecc_mask;
mem_types[MT_MEMORY].prot_sect |= ecc_mask | cp->pmd;
mem_types[MT_ROM].prot_sect |= cp->pmd;
- for (i = 0; i < 16; i++) {
- unsigned long v = pgprot_val(protection_map[i]);
- v = (v & ~(PTE_BUFFERABLE|PTE_CACHEABLE)) | user_pgprot;
- protection_map[i] = __pgprot(v);
- }
-
- pgprot_kernel = __pgprot(L_PTE_PRESENT | L_PTE_YOUNG |
- L_PTE_DIRTY | L_PTE_WRITE |
- L_PTE_EXEC | cp->pte);
-
switch (cp->pmd) {
case PMD_SECT_WT:
mem_types[MT_CACHECLEAN].prot_sect |= PMD_SECT_WT;
@@ -483,25 +476,25 @@ static void __init build_mem_type_table(void)
* offsets, and we take full advantage of sections and
* supersections.
*/
-static void __init create_mapping(struct map_desc *md)
+void __init create_mapping(struct map_desc *md)
{
unsigned long virt, length;
int prot_sect, prot_l1, domain;
pgprot_t prot_pte;
- long off;
+ unsigned long off = (u32)__pfn_to_phys(md->pfn);
if (md->virtual != vectors_base() && md->virtual < TASK_SIZE) {
printk(KERN_WARNING "BUG: not creating mapping for "
- "0x%08lx at 0x%08lx in user region\n",
- md->physical, md->virtual);
+ "0x%08llx at 0x%08lx in user region\n",
+ __pfn_to_phys((u64)md->pfn), md->virtual);
return;
}
if ((md->type == MT_DEVICE || md->type == MT_ROM) &&
md->virtual >= PAGE_OFFSET && md->virtual < VMALLOC_END) {
- printk(KERN_WARNING "BUG: mapping for 0x%08lx at 0x%08lx "
+ printk(KERN_WARNING "BUG: mapping for 0x%08llx at 0x%08lx "
"overlaps vmalloc space\n",
- md->physical, md->virtual);
+ __pfn_to_phys((u64)md->pfn), md->virtual);
}
domain = mem_types[md->type].domain;
@@ -509,15 +502,40 @@ static void __init create_mapping(struct map_desc *md)
prot_l1 = mem_types[md->type].prot_l1 | PMD_DOMAIN(domain);
prot_sect = mem_types[md->type].prot_sect | PMD_DOMAIN(domain);
+ /*
+ * Catch 36-bit addresses
+ */
+ if(md->pfn >= 0x100000) {
+ if(domain) {
+ printk(KERN_ERR "MM: invalid domain in supersection "
+ "mapping for 0x%08llx at 0x%08lx\n",
+ __pfn_to_phys((u64)md->pfn), md->virtual);
+ return;
+ }
+ if((md->virtual | md->length | __pfn_to_phys(md->pfn))
+ & ~SUPERSECTION_MASK) {
+ printk(KERN_ERR "MM: cannot create mapping for "
+ "0x%08llx at 0x%08lx invalid alignment\n",
+ __pfn_to_phys((u64)md->pfn), md->virtual);
+ return;
+ }
+
+ /*
+ * Shift bits [35:32] of address into bits [23:20] of PMD
+ * (See ARMv6 spec).
+ */
+ off |= (((md->pfn >> (32 - PAGE_SHIFT)) & 0xF) << 20);
+ }
+
virt = md->virtual;
- off = md->physical - virt;
+ off -= virt;
length = md->length;
if (mem_types[md->type].prot_l1 == 0 &&
(virt & 0xfffff || (virt + off) & 0xfffff || (virt + length) & 0xfffff)) {
printk(KERN_WARNING "BUG: map for 0x%08lx at 0x%08lx can not "
"be mapped using pages, ignoring.\n",
- md->physical, md->virtual);
+ __pfn_to_phys(md->pfn), md->virtual);
return;
}
@@ -535,13 +553,22 @@ static void __init create_mapping(struct map_desc *md)
* of the actual domain assignments in use.
*/
if (cpu_architecture() >= CPU_ARCH_ARMv6 && domain == 0) {
- /* Align to supersection boundary */
- while ((virt & ~SUPERSECTION_MASK || (virt + off) &
- ~SUPERSECTION_MASK) && length >= (PGDIR_SIZE / 2)) {
- alloc_init_section(virt, virt + off, prot_sect);
-
- virt += (PGDIR_SIZE / 2);
- length -= (PGDIR_SIZE / 2);
+ /*
+ * Align to supersection boundary if !high pages.
+ * High pages have already been checked for proper
+ * alignment above and they will fail the SUPSERSECTION_MASK
+ * check because of the way the address is encoded into
+ * offset.
+ */
+ if (md->pfn <= 0x100000) {
+ while ((virt & ~SUPERSECTION_MASK ||
+ (virt + off) & ~SUPERSECTION_MASK) &&
+ length >= (PGDIR_SIZE / 2)) {
+ alloc_init_section(virt, virt + off, prot_sect);
+
+ virt += (PGDIR_SIZE / 2);
+ length -= (PGDIR_SIZE / 2);
+ }
}
while (length >= SUPERSECTION_SIZE) {
@@ -601,100 +628,6 @@ void setup_mm_for_reboot(char mode)
}
}
-extern void _stext, _etext;
-
-/*
- * Setup initial mappings. We use the page we allocated for zero page to hold
- * the mappings, which will get overwritten by the vectors in traps_init().
- * The mappings must be in virtual address order.
- */
-void __init memtable_init(struct meminfo *mi)
-{
- struct map_desc *init_maps, *p, *q;
- unsigned long address = 0;
- int i;
-
- build_mem_type_table();
-
- init_maps = p = alloc_bootmem_low_pages(PAGE_SIZE);
-
-#ifdef CONFIG_XIP_KERNEL
- p->physical = CONFIG_XIP_PHYS_ADDR & PMD_MASK;
- p->virtual = (unsigned long)&_stext & PMD_MASK;
- p->length = ((unsigned long)&_etext - p->virtual + ~PMD_MASK) & PMD_MASK;
- p->type = MT_ROM;
- p ++;
-#endif
-
- for (i = 0; i < mi->nr_banks; i++) {
- if (mi->bank[i].size == 0)
- continue;
-
- p->physical = mi->bank[i].start;
- p->virtual = __phys_to_virt(p->physical);
- p->length = mi->bank[i].size;
- p->type = MT_MEMORY;
- p ++;
- }
-
-#ifdef FLUSH_BASE
- p->physical = FLUSH_BASE_PHYS;
- p->virtual = FLUSH_BASE;
- p->length = PGDIR_SIZE;
- p->type = MT_CACHECLEAN;
- p ++;
-#endif
-
-#ifdef FLUSH_BASE_MINICACHE
- p->physical = FLUSH_BASE_PHYS + PGDIR_SIZE;
- p->virtual = FLUSH_BASE_MINICACHE;
- p->length = PGDIR_SIZE;
- p->type = MT_MINICLEAN;
- p ++;
-#endif
-
- /*
- * Go through the initial mappings, but clear out any
- * pgdir entries that are not in the description.
- */
- q = init_maps;
- do {
- if (address < q->virtual || q == p) {
- clear_mapping(address);
- address += PGDIR_SIZE;
- } else {
- create_mapping(q);
-
- address = q->virtual + q->length;
- address = (address + PGDIR_SIZE - 1) & PGDIR_MASK;
-
- q ++;
- }
- } while (address != 0);
-
- /*
- * Create a mapping for the machine vectors at the high-vectors
- * location (0xffff0000). If we aren't using high-vectors, also
- * create a mapping at the low-vectors virtual address.
- */
- init_maps->physical = virt_to_phys(init_maps);
- init_maps->virtual = 0xffff0000;
- init_maps->length = PAGE_SIZE;
- init_maps->type = MT_HIGH_VECTORS;
- create_mapping(init_maps);
-
- if (!vectors_high()) {
- init_maps->virtual = 0;
- init_maps->type = MT_LOW_VECTORS;
- create_mapping(init_maps);
- }
-
- flush_cache_all();
- local_flush_tlb_all();
-
- top_pmd = pmd_off_k(0xffff0000);
-}
-
/*
* Create the architecture specific mappings
*/
diff --git a/arch/arm/mm/proc-v6.S b/arch/arm/mm/proc-v6.S
index 9bb5fff406fb..92f3ca31b7b9 100644
--- a/arch/arm/mm/proc-v6.S
+++ b/arch/arm/mm/proc-v6.S
@@ -12,6 +12,7 @@
#include <linux/linkage.h>
#include <asm/assembler.h>
#include <asm/asm-offsets.h>
+#include <asm/hardware/arm_scu.h>
#include <asm/procinfo.h>
#include <asm/pgtable.h>
@@ -112,6 +113,9 @@ ENTRY(cpu_v6_dcache_clean_area)
ENTRY(cpu_v6_switch_mm)
mov r2, #0
ldr r1, [r1, #MM_CONTEXT_ID] @ get mm->context.id
+#ifdef CONFIG_SMP
+ orr r0, r0, #2 @ set shared pgtable
+#endif
mcr p15, 0, r2, c7, c5, 6 @ flush BTAC/BTB
mcr p15, 0, r2, c7, c10, 4 @ drain write buffer
mcr p15, 0, r0, c2, c0, 0 @ set TTB 0
@@ -140,7 +144,7 @@ ENTRY(cpu_v6_switch_mm)
ENTRY(cpu_v6_set_pte)
str r1, [r0], #-2048 @ linux version
- bic r2, r1, #0x000007f0
+ bic r2, r1, #0x000003f0
bic r2, r2, #0x00000003
orr r2, r2, #PTE_EXT_AP0 | 2
@@ -191,6 +195,23 @@ cpu_v6_name:
* - cache type register is implemented
*/
__v6_setup:
+#ifdef CONFIG_SMP
+ /* Set up the SCU on core 0 only */
+ mrc p15, 0, r0, c0, c0, 5 @ CPU core number
+ ands r0, r0, #15
+ moveq r0, #0x10000000 @ SCU_BASE
+ orreq r0, r0, #0x00100000
+ ldreq r5, [r0, #SCU_CTRL]
+ orreq r5, r5, #1
+ streq r5, [r0, #SCU_CTRL]
+
+#ifndef CONFIG_CPU_DCACHE_DISABLE
+ mrc p15, 0, r0, c1, c0, 1 @ Enable SMP/nAMP mode
+ orr r0, r0, #0x20
+ mcr p15, 0, r0, c1, c0, 1
+#endif
+#endif
+
mov r0, #0
mcr p15, 0, r0, c7, c14, 0 @ clean+invalidate D cache
mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
@@ -198,6 +219,9 @@ __v6_setup:
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, c2, c0, 2 @ TTB control register
+#ifdef CONFIG_SMP
+ orr r4, r4, #2 @ set shared pgtable
+#endif
mcr p15, 0, r4, c2, c0, 1 @ load TTB1
#ifdef CONFIG_VFP
mrc p15, 0, r0, c1, c0, 2
diff --git a/arch/arm/nwfpe/fpa11.h b/arch/arm/nwfpe/fpa11.h
index 9677ae8448e8..da4c616b6c49 100644
--- a/arch/arm/nwfpe/fpa11.h
+++ b/arch/arm/nwfpe/fpa11.h
@@ -60,7 +60,7 @@ typedef union tagFPREG {
#ifdef CONFIG_FPE_NWFPE_XP
floatx80 fExtended;
#else
- int padding[3];
+ u32 padding[3];
#endif
} FPREG;
diff --git a/arch/arm/nwfpe/fpa11_cpdt.c b/arch/arm/nwfpe/fpa11_cpdt.c
index b0db5cbcc3b1..32859fa8dcfc 100644
--- a/arch/arm/nwfpe/fpa11_cpdt.c
+++ b/arch/arm/nwfpe/fpa11_cpdt.c
@@ -59,8 +59,13 @@ static inline void loadExtended(const unsigned int Fn, const unsigned int __user
p = (unsigned int *) &fpa11->fpreg[Fn].fExtended;
fpa11->fType[Fn] = typeExtended;
get_user(p[0], &pMem[0]); /* sign & exponent */
+#ifdef __ARMEB__
+ get_user(p[1], &pMem[1]); /* ms bits */
+ get_user(p[2], &pMem[2]); /* ls bits */
+#else
get_user(p[1], &pMem[2]); /* ls bits */
get_user(p[2], &pMem[1]); /* ms bits */
+#endif
}
#endif
@@ -177,8 +182,13 @@ static inline void storeExtended(const unsigned int Fn, unsigned int __user *pMe
}
put_user(val.i[0], &pMem[0]); /* sign & exp */
+#ifdef __ARMEB__
+ put_user(val.i[1], &pMem[1]); /* msw */
+ put_user(val.i[2], &pMem[2]);
+#else
put_user(val.i[1], &pMem[2]);
put_user(val.i[2], &pMem[1]); /* msw */
+#endif
}
#endif
diff --git a/arch/arm/nwfpe/fpopcode.c b/arch/arm/nwfpe/fpopcode.c
index 4c9f5703148c..67ff2ab08ea0 100644
--- a/arch/arm/nwfpe/fpopcode.c
+++ b/arch/arm/nwfpe/fpopcode.c
@@ -29,14 +29,14 @@
#ifdef CONFIG_FPE_NWFPE_XP
const floatx80 floatx80Constant[] = {
- {0x0000, 0x0000000000000000ULL}, /* extended 0.0 */
- {0x3fff, 0x8000000000000000ULL}, /* extended 1.0 */
- {0x4000, 0x8000000000000000ULL}, /* extended 2.0 */
- {0x4000, 0xc000000000000000ULL}, /* extended 3.0 */
- {0x4001, 0x8000000000000000ULL}, /* extended 4.0 */
- {0x4001, 0xa000000000000000ULL}, /* extended 5.0 */
- {0x3ffe, 0x8000000000000000ULL}, /* extended 0.5 */
- {0x4002, 0xa000000000000000ULL} /* extended 10.0 */
+ { .high = 0x0000, .low = 0x0000000000000000ULL},/* extended 0.0 */
+ { .high = 0x3fff, .low = 0x8000000000000000ULL},/* extended 1.0 */
+ { .high = 0x4000, .low = 0x8000000000000000ULL},/* extended 2.0 */
+ { .high = 0x4000, .low = 0xc000000000000000ULL},/* extended 3.0 */
+ { .high = 0x4001, .low = 0x8000000000000000ULL},/* extended 4.0 */
+ { .high = 0x4001, .low = 0xa000000000000000ULL},/* extended 5.0 */
+ { .high = 0x3ffe, .low = 0x8000000000000000ULL},/* extended 0.5 */
+ { .high = 0x4002, .low = 0xa000000000000000ULL},/* extended 10.0 */
};
#endif
diff --git a/arch/arm/nwfpe/softfloat-specialize b/arch/arm/nwfpe/softfloat-specialize
index acf409144763..d4a4c8e06635 100644
--- a/arch/arm/nwfpe/softfloat-specialize
+++ b/arch/arm/nwfpe/softfloat-specialize
@@ -332,6 +332,7 @@ static floatx80 commonNaNToFloatx80( commonNaNT a )
z.low = LIT64( 0xC000000000000000 ) | ( a.high>>1 );
z.high = ( ( (bits16) a.sign )<<15 ) | 0x7FFF;
+ z.__padding = 0;
return z;
}
diff --git a/arch/arm/nwfpe/softfloat.c b/arch/arm/nwfpe/softfloat.c
index f9f049132a17..0f9656e482ba 100644
--- a/arch/arm/nwfpe/softfloat.c
+++ b/arch/arm/nwfpe/softfloat.c
@@ -531,6 +531,7 @@ INLINE floatx80 packFloatx80( flag zSign, int32 zExp, bits64 zSig )
z.low = zSig;
z.high = ( ( (bits16) zSign )<<15 ) + zExp;
+ z.__padding = 0;
return z;
}
@@ -2831,6 +2832,7 @@ static floatx80 subFloatx80Sigs( struct roundingData *roundData, floatx80 a, flo
roundData->exception |= float_flag_invalid;
z.low = floatx80_default_nan_low;
z.high = floatx80_default_nan_high;
+ z.__padding = 0;
return z;
}
if ( aExp == 0 ) {
@@ -2950,6 +2952,7 @@ floatx80 floatx80_mul( struct roundingData *roundData, floatx80 a, floatx80 b )
roundData->exception |= float_flag_invalid;
z.low = floatx80_default_nan_low;
z.high = floatx80_default_nan_high;
+ z.__padding = 0;
return z;
}
return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
@@ -3015,6 +3018,7 @@ floatx80 floatx80_div( struct roundingData *roundData, floatx80 a, floatx80 b )
roundData->exception |= float_flag_invalid;
z.low = floatx80_default_nan_low;
z.high = floatx80_default_nan_high;
+ z.__padding = 0;
return z;
}
roundData->exception |= float_flag_divbyzero;
@@ -3093,6 +3097,7 @@ floatx80 floatx80_rem( struct roundingData *roundData, floatx80 a, floatx80 b )
roundData->exception |= float_flag_invalid;
z.low = floatx80_default_nan_low;
z.high = floatx80_default_nan_high;
+ z.__padding = 0;
return z;
}
normalizeFloatx80Subnormal( bSig, &bExp, &bSig );
@@ -3184,6 +3189,7 @@ floatx80 floatx80_sqrt( struct roundingData *roundData, floatx80 a )
roundData->exception |= float_flag_invalid;
z.low = floatx80_default_nan_low;
z.high = floatx80_default_nan_high;
+ z.__padding = 0;
return z;
}
if ( aExp == 0 ) {
diff --git a/arch/arm/nwfpe/softfloat.h b/arch/arm/nwfpe/softfloat.h
index 14151700b6b2..978c699673c6 100644
--- a/arch/arm/nwfpe/softfloat.h
+++ b/arch/arm/nwfpe/softfloat.h
@@ -51,11 +51,17 @@ input or output the `floatx80' type will be defined.
Software IEC/IEEE floating-point types.
-------------------------------------------------------------------------------
*/
-typedef unsigned long int float32;
-typedef unsigned long long float64;
+typedef u32 float32;
+typedef u64 float64;
typedef struct {
- unsigned short high;
- unsigned long long low;
+#ifdef __ARMEB__
+ u16 __padding;
+ u16 high;
+#else
+ u16 high;
+ u16 __padding;
+#endif
+ u64 low;
} floatx80;
/*
diff --git a/arch/arm/oprofile/Makefile b/arch/arm/oprofile/Makefile
index 8ffb523e6c77..6a94e54848fd 100644
--- a/arch/arm/oprofile/Makefile
+++ b/arch/arm/oprofile/Makefile
@@ -6,6 +6,6 @@ DRIVER_OBJS = $(addprefix ../../../drivers/oprofile/, \
oprofilefs.o oprofile_stats.o \
timer_int.o )
-oprofile-y := $(DRIVER_OBJS) init.o backtrace.o
-oprofile-$(CONFIG_CPU_XSCALE) += common.o op_model_xscale.o
+oprofile-y := $(DRIVER_OBJS) common.o backtrace.o
+oprofile-$(CONFIG_CPU_XSCALE) += op_model_xscale.o
diff --git a/arch/arm/oprofile/backtrace.c b/arch/arm/oprofile/backtrace.c
index df35c452a8bf..7c22c12618cc 100644
--- a/arch/arm/oprofile/backtrace.c
+++ b/arch/arm/oprofile/backtrace.c
@@ -49,42 +49,22 @@ static struct frame_tail* kernel_backtrace(struct frame_tail *tail)
static struct frame_tail* user_backtrace(struct frame_tail *tail)
{
- struct frame_tail buftail;
+ struct frame_tail buftail[2];
- /* hardware pte might not be valid due to dirty/accessed bit emulation
- * so we use copy_from_user and benefit from exception fixups */
- if (copy_from_user(&buftail, tail, sizeof(struct frame_tail)))
+ /* Also check accessibility of one struct frame_tail beyond */
+ if (!access_ok(VERIFY_READ, tail, sizeof(buftail)))
+ return NULL;
+ if (__copy_from_user_inatomic(buftail, tail, sizeof(buftail)))
return NULL;
- oprofile_add_trace(buftail.lr);
+ oprofile_add_trace(buftail[0].lr);
/* frame pointers should strictly progress back up the stack
* (towards higher addresses) */
- if (tail >= buftail.fp)
+ if (tail >= buftail[0].fp)
return NULL;
- return buftail.fp-1;
-}
-
-/* Compare two addresses and see if they're on the same page */
-#define CMP_ADDR_EQUAL(x,y,offset) ((((unsigned long) x) >> PAGE_SHIFT) \
- == ((((unsigned long) y) + offset) >> PAGE_SHIFT))
-
-/* check that the page(s) containing the frame tail are present */
-static int pages_present(struct frame_tail *tail)
-{
- struct mm_struct * mm = current->mm;
-
- if (!check_user_page_readable(mm, (unsigned long)tail))
- return 0;
-
- if (CMP_ADDR_EQUAL(tail, tail, 8))
- return 1;
-
- if (!check_user_page_readable(mm, ((unsigned long)tail) + 8))
- return 0;
-
- return 1;
+ return buftail[0].fp-1;
}
/*
@@ -118,7 +98,6 @@ static int valid_kernel_stack(struct frame_tail *tail, struct pt_regs *regs)
void arm_backtrace(struct pt_regs * const regs, unsigned int depth)
{
struct frame_tail *tail;
- unsigned long last_address = 0;
tail = ((struct frame_tail *) regs->ARM_fp) - 1;
@@ -132,13 +111,6 @@ void arm_backtrace(struct pt_regs * const regs, unsigned int depth)
return;
}
- while (depth-- && tail && !((unsigned long) tail & 3)) {
- if ((!CMP_ADDR_EQUAL(last_address, tail, 0)
- || !CMP_ADDR_EQUAL(last_address, tail, 8))
- && !pages_present(tail))
- return;
- last_address = (unsigned long) tail;
+ while (depth-- && tail && !((unsigned long) tail & 3))
tail = user_backtrace(tail);
- }
}
-
diff --git a/arch/arm/oprofile/common.c b/arch/arm/oprofile/common.c
index e57dde882898..1415930ceee1 100644
--- a/arch/arm/oprofile/common.c
+++ b/arch/arm/oprofile/common.c
@@ -10,74 +10,23 @@
#include <linux/init.h>
#include <linux/oprofile.h>
#include <linux/errno.h>
-#include <asm/semaphore.h>
#include <linux/sysdev.h>
+#include <asm/semaphore.h>
#include "op_counter.h"
#include "op_arm_model.h"
-static struct op_arm_model_spec *pmu_model;
-static int pmu_enabled;
-static struct semaphore pmu_sem;
-
-static int pmu_start(void);
-static int pmu_setup(void);
-static void pmu_stop(void);
-static int pmu_create_files(struct super_block *, struct dentry *);
-
-#ifdef CONFIG_PM
-static int pmu_suspend(struct sys_device *dev, pm_message_t state)
-{
- if (pmu_enabled)
- pmu_stop();
- return 0;
-}
-
-static int pmu_resume(struct sys_device *dev)
-{
- if (pmu_enabled)
- pmu_start();
- return 0;
-}
-
-static struct sysdev_class oprofile_sysclass = {
- set_kset_name("oprofile"),
- .resume = pmu_resume,
- .suspend = pmu_suspend,
-};
-
-static struct sys_device device_oprofile = {
- .id = 0,
- .cls = &oprofile_sysclass,
-};
-
-static int __init init_driverfs(void)
-{
- int ret;
-
- if (!(ret = sysdev_class_register(&oprofile_sysclass)))
- ret = sysdev_register(&device_oprofile);
-
- return ret;
-}
-
-static void exit_driverfs(void)
-{
- sysdev_unregister(&device_oprofile);
- sysdev_class_unregister(&oprofile_sysclass);
-}
-#else
-#define init_driverfs() do { } while (0)
-#define exit_driverfs() do { } while (0)
-#endif /* CONFIG_PM */
+static struct op_arm_model_spec *op_arm_model;
+static int op_arm_enabled;
+static struct semaphore op_arm_sem;
struct op_counter_config counter_config[OP_MAX_COUNTER];
-static int pmu_create_files(struct super_block *sb, struct dentry *root)
+static int op_arm_create_files(struct super_block *sb, struct dentry *root)
{
unsigned int i;
- for (i = 0; i < pmu_model->num_counters; i++) {
+ for (i = 0; i < op_arm_model->num_counters; i++) {
struct dentry *dir;
char buf[2];
@@ -94,63 +43,123 @@ static int pmu_create_files(struct super_block *sb, struct dentry *root)
return 0;
}
-static int pmu_setup(void)
+static int op_arm_setup(void)
{
int ret;
spin_lock(&oprofilefs_lock);
- ret = pmu_model->setup_ctrs();
+ ret = op_arm_model->setup_ctrs();
spin_unlock(&oprofilefs_lock);
return ret;
}
-static int pmu_start(void)
+static int op_arm_start(void)
{
int ret = -EBUSY;
- down(&pmu_sem);
- if (!pmu_enabled) {
- ret = pmu_model->start();
- pmu_enabled = !ret;
+ down(&op_arm_sem);
+ if (!op_arm_enabled) {
+ ret = op_arm_model->start();
+ op_arm_enabled = !ret;
}
- up(&pmu_sem);
+ up(&op_arm_sem);
return ret;
}
-static void pmu_stop(void)
+static void op_arm_stop(void)
+{
+ down(&op_arm_sem);
+ if (op_arm_enabled)
+ op_arm_model->stop();
+ op_arm_enabled = 0;
+ up(&op_arm_sem);
+}
+
+#ifdef CONFIG_PM
+static int op_arm_suspend(struct sys_device *dev, pm_message_t state)
{
- down(&pmu_sem);
- if (pmu_enabled)
- pmu_model->stop();
- pmu_enabled = 0;
- up(&pmu_sem);
+ down(&op_arm_sem);
+ if (op_arm_enabled)
+ op_arm_model->stop();
+ up(&op_arm_sem);
+ return 0;
}
-int __init pmu_init(struct oprofile_operations *ops, struct op_arm_model_spec *spec)
+static int op_arm_resume(struct sys_device *dev)
{
- init_MUTEX(&pmu_sem);
+ down(&op_arm_sem);
+ if (op_arm_enabled && op_arm_model->start())
+ op_arm_enabled = 0;
+ up(&op_arm_sem);
+ return 0;
+}
+
+static struct sysdev_class oprofile_sysclass = {
+ set_kset_name("oprofile"),
+ .resume = op_arm_resume,
+ .suspend = op_arm_suspend,
+};
- if (spec->init() < 0)
- return -ENODEV;
+static struct sys_device device_oprofile = {
+ .id = 0,
+ .cls = &oprofile_sysclass,
+};
- pmu_model = spec;
- init_driverfs();
- ops->create_files = pmu_create_files;
- ops->setup = pmu_setup;
- ops->shutdown = pmu_stop;
- ops->start = pmu_start;
- ops->stop = pmu_stop;
- ops->cpu_type = pmu_model->name;
- printk(KERN_INFO "oprofile: using %s PMU\n", spec->name);
+static int __init init_driverfs(void)
+{
+ int ret;
- return 0;
+ if (!(ret = sysdev_class_register(&oprofile_sysclass)))
+ ret = sysdev_register(&device_oprofile);
+
+ return ret;
+}
+
+static void exit_driverfs(void)
+{
+ sysdev_unregister(&device_oprofile);
+ sysdev_class_unregister(&oprofile_sysclass);
+}
+#else
+#define init_driverfs() do { } while (0)
+#define exit_driverfs() do { } while (0)
+#endif /* CONFIG_PM */
+
+int __init oprofile_arch_init(struct oprofile_operations *ops)
+{
+ struct op_arm_model_spec *spec = NULL;
+ int ret = -ENODEV;
+
+#ifdef CONFIG_CPU_XSCALE
+ spec = &op_xscale_spec;
+#endif
+
+ if (spec) {
+ init_MUTEX(&op_arm_sem);
+
+ if (spec->init() < 0)
+ return -ENODEV;
+
+ op_arm_model = spec;
+ init_driverfs();
+ ops->create_files = op_arm_create_files;
+ ops->setup = op_arm_setup;
+ ops->shutdown = op_arm_stop;
+ ops->start = op_arm_start;
+ ops->stop = op_arm_stop;
+ ops->cpu_type = op_arm_model->name;
+ ops->backtrace = arm_backtrace;
+ printk(KERN_INFO "oprofile: using %s\n", spec->name);
+ }
+
+ return ret;
}
-void pmu_exit(void)
+void oprofile_arch_exit(void)
{
- if (pmu_model) {
+ if (op_arm_model) {
exit_driverfs();
- pmu_model = NULL;
+ op_arm_model = NULL;
}
}
diff --git a/arch/arm/oprofile/init.c b/arch/arm/oprofile/init.c
deleted file mode 100644
index d315a3a86c86..000000000000
--- a/arch/arm/oprofile/init.c
+++ /dev/null
@@ -1,33 +0,0 @@
-/**
- * @file init.c
- *
- * @remark Copyright 2004 Oprofile Authors
- * @remark Read the file COPYING
- *
- * @author Zwane Mwaikambo
- */
-
-#include <linux/oprofile.h>
-#include <linux/init.h>
-#include <linux/errno.h>
-#include "op_arm_model.h"
-
-int __init oprofile_arch_init(struct oprofile_operations *ops)
-{
- int ret = -ENODEV;
-
-#ifdef CONFIG_CPU_XSCALE
- ret = pmu_init(ops, &op_xscale_spec);
-#endif
-
- ops->backtrace = arm_backtrace;
-
- return ret;
-}
-
-void oprofile_arch_exit(void)
-{
-#ifdef CONFIG_CPU_XSCALE
- pmu_exit();
-#endif
-}
diff --git a/arch/arm/oprofile/op_arm_model.h b/arch/arm/oprofile/op_arm_model.h
index 2148d07484b7..38c6ad158547 100644
--- a/arch/arm/oprofile/op_arm_model.h
+++ b/arch/arm/oprofile/op_arm_model.h
@@ -26,6 +26,6 @@ extern struct op_arm_model_spec op_xscale_spec;
extern void arm_backtrace(struct pt_regs * const regs, unsigned int depth);
-extern int __init pmu_init(struct oprofile_operations *ops, struct op_arm_model_spec *spec);
-extern void pmu_exit(void);
+extern int __init op_arm_init(struct oprofile_operations *ops, struct op_arm_model_spec *spec);
+extern void op_arm_exit(void);
#endif /* OP_ARM_MODEL_H */
diff --git a/arch/arm/plat-omap/Makefile b/arch/arm/plat-omap/Makefile
index 7e144f9cad1c..9ccf1943fc94 100644
--- a/arch/arm/plat-omap/Makefile
+++ b/arch/arm/plat-omap/Makefile
@@ -3,7 +3,7 @@
#
# Common support
-obj-y := common.o sram.o sram-fn.o clock.o dma.o mux.o gpio.o mcbsp.o usb.o
+obj-y := common.o sram.o sram-fn.o clock.o devices.o dma.o mux.o gpio.o mcbsp.o usb.o
obj-m :=
obj-n :=
obj- :=
diff --git a/arch/arm/plat-omap/clock.c b/arch/arm/plat-omap/clock.c
index 52a58b2da288..7ce39b986e23 100644
--- a/arch/arm/plat-omap/clock.c
+++ b/arch/arm/plat-omap/clock.c
@@ -1,578 +1,42 @@
/*
* linux/arch/arm/plat-omap/clock.c
*
- * Copyright (C) 2004 Nokia corporation
+ * Copyright (C) 2004 - 2005 Nokia corporation
* Written by Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>
*
+ * Modified for omap shared clock framework by Tony Lindgren <tony@atomide.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/version.h>
+#include <linux/config.h>
#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
#include <linux/list.h>
#include <linux/errno.h>
#include <linux/err.h>
+#include <linux/string.h>
#include <asm/io.h>
#include <asm/semaphore.h>
#include <asm/hardware/clock.h>
-#include <asm/arch/board.h>
-#include <asm/arch/usb.h>
-#include "clock.h"
-#include "sram.h"
+#include <asm/arch/clock.h>
-static LIST_HEAD(clocks);
+LIST_HEAD(clocks);
static DECLARE_MUTEX(clocks_sem);
-static DEFINE_SPINLOCK(clockfw_lock);
-static void propagate_rate(struct clk * clk);
-/* UART clock function */
-static int set_uart_rate(struct clk * clk, unsigned long rate);
-/* External clock (MCLK & BCLK) functions */
-static int set_ext_clk_rate(struct clk * clk, unsigned long rate);
-static long round_ext_clk_rate(struct clk * clk, unsigned long rate);
-static void init_ext_clk(struct clk * clk);
-/* MPU virtual clock functions */
-static int select_table_rate(struct clk * clk, unsigned long rate);
-static long round_to_table_rate(struct clk * clk, unsigned long rate);
-void clk_setdpll(__u16, __u16);
-
-static struct mpu_rate rate_table[] = {
- /* MPU MHz, xtal MHz, dpll1 MHz, CKCTL, DPLL_CTL
- * armdiv, dspdiv, dspmmu, tcdiv, perdiv, lcddiv
- */
-#if defined(CONFIG_OMAP_ARM_216MHZ)
- { 216000000, 12000000, 216000000, 0x050d, 0x2910 }, /* 1/1/2/2/2/8 */
-#endif
-#if defined(CONFIG_OMAP_ARM_195MHZ)
- { 195000000, 13000000, 195000000, 0x050e, 0x2790 }, /* 1/1/2/2/4/8 */
-#endif
-#if defined(CONFIG_OMAP_ARM_192MHZ)
- { 192000000, 19200000, 192000000, 0x050f, 0x2510 }, /* 1/1/2/2/8/8 */
- { 192000000, 12000000, 192000000, 0x050f, 0x2810 }, /* 1/1/2/2/8/8 */
- { 96000000, 12000000, 192000000, 0x055f, 0x2810 }, /* 2/2/2/2/8/8 */
- { 48000000, 12000000, 192000000, 0x0baf, 0x2810 }, /* 4/8/4/4/8/8 */
- { 24000000, 12000000, 192000000, 0x0fff, 0x2810 }, /* 8/8/8/8/8/8 */
-#endif
-#if defined(CONFIG_OMAP_ARM_182MHZ)
- { 182000000, 13000000, 182000000, 0x050e, 0x2710 }, /* 1/1/2/2/4/8 */
-#endif
-#if defined(CONFIG_OMAP_ARM_168MHZ)
- { 168000000, 12000000, 168000000, 0x010f, 0x2710 }, /* 1/1/1/2/8/8 */
-#endif
-#if defined(CONFIG_OMAP_ARM_150MHZ)
- { 150000000, 12000000, 150000000, 0x010a, 0x2cb0 }, /* 1/1/1/2/4/4 */
-#endif
-#if defined(CONFIG_OMAP_ARM_120MHZ)
- { 120000000, 12000000, 120000000, 0x010a, 0x2510 }, /* 1/1/1/2/4/4 */
-#endif
-#if defined(CONFIG_OMAP_ARM_96MHZ)
- { 96000000, 12000000, 96000000, 0x0005, 0x2410 }, /* 1/1/1/1/2/2 */
-#endif
-#if defined(CONFIG_OMAP_ARM_60MHZ)
- { 60000000, 12000000, 60000000, 0x0005, 0x2290 }, /* 1/1/1/1/2/2 */
-#endif
-#if defined(CONFIG_OMAP_ARM_30MHZ)
- { 30000000, 12000000, 60000000, 0x0555, 0x2290 }, /* 2/2/2/2/2/2 */
-#endif
- { 0, 0, 0, 0, 0 },
-};
-
-
-static void ckctl_recalc(struct clk * clk);
-int __clk_enable(struct clk *clk);
-void __clk_disable(struct clk *clk);
-void __clk_unuse(struct clk *clk);
-int __clk_use(struct clk *clk);
-
-
-static void followparent_recalc(struct clk * clk)
-{
- clk->rate = clk->parent->rate;
-}
-
-
-static void watchdog_recalc(struct clk * clk)
-{
- clk->rate = clk->parent->rate / 14;
-}
-
-static void uart_recalc(struct clk * clk)
-{
- unsigned int val = omap_readl(clk->enable_reg);
- if (val & clk->enable_bit)
- clk->rate = 48000000;
- else
- clk->rate = 12000000;
-}
-
-static struct clk ck_ref = {
- .name = "ck_ref",
- .rate = 12000000,
- .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
- ALWAYS_ENABLED,
-};
-
-static struct clk ck_dpll1 = {
- .name = "ck_dpll1",
- .parent = &ck_ref,
- .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
- RATE_PROPAGATES | ALWAYS_ENABLED,
-};
-
-static struct clk ck_dpll1out = {
- .name = "ck_dpll1out",
- .parent = &ck_dpll1,
- .flags = CLOCK_IN_OMAP16XX,
- .enable_reg = ARM_IDLECT2,
- .enable_bit = EN_CKOUT_ARM,
- .recalc = &followparent_recalc,
-};
-
-static struct clk arm_ck = {
- .name = "arm_ck",
- .parent = &ck_dpll1,
- .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
- RATE_CKCTL | RATE_PROPAGATES | ALWAYS_ENABLED,
- .rate_offset = CKCTL_ARMDIV_OFFSET,
- .recalc = &ckctl_recalc,
-};
-
-static struct clk armper_ck = {
- .name = "armper_ck",
- .parent = &ck_dpll1,
- .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
- RATE_CKCTL,
- .enable_reg = ARM_IDLECT2,
- .enable_bit = EN_PERCK,
- .rate_offset = CKCTL_PERDIV_OFFSET,
- .recalc = &ckctl_recalc,
-};
-
-static struct clk arm_gpio_ck = {
- .name = "arm_gpio_ck",
- .parent = &ck_dpll1,
- .flags = CLOCK_IN_OMAP1510,
- .enable_reg = ARM_IDLECT2,
- .enable_bit = EN_GPIOCK,
- .recalc = &followparent_recalc,
-};
-
-static struct clk armxor_ck = {
- .name = "armxor_ck",
- .parent = &ck_ref,
- .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX,
- .enable_reg = ARM_IDLECT2,
- .enable_bit = EN_XORPCK,
- .recalc = &followparent_recalc,
-};
-
-static struct clk armtim_ck = {
- .name = "armtim_ck",
- .parent = &ck_ref,
- .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX,
- .enable_reg = ARM_IDLECT2,
- .enable_bit = EN_TIMCK,
- .recalc = &followparent_recalc,
-};
-
-static struct clk armwdt_ck = {
- .name = "armwdt_ck",
- .parent = &ck_ref,
- .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX,
- .enable_reg = ARM_IDLECT2,
- .enable_bit = EN_WDTCK,
- .recalc = &watchdog_recalc,
-};
-
-static struct clk arminth_ck16xx = {
- .name = "arminth_ck",
- .parent = &arm_ck,
- .flags = CLOCK_IN_OMAP16XX | ALWAYS_ENABLED,
- .recalc = &followparent_recalc,
- /* Note: On 16xx the frequency can be divided by 2 by programming
- * ARM_CKCTL:ARM_INTHCK_SEL(14) to 1
- *
- * 1510 version is in TC clocks.
- */
-};
-
-static struct clk dsp_ck = {
- .name = "dsp_ck",
- .parent = &ck_dpll1,
- .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
- RATE_CKCTL,
- .enable_reg = ARM_CKCTL,
- .enable_bit = EN_DSPCK,
- .rate_offset = CKCTL_DSPDIV_OFFSET,
- .recalc = &ckctl_recalc,
-};
-
-static struct clk dspmmu_ck = {
- .name = "dspmmu_ck",
- .parent = &ck_dpll1,
- .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
- RATE_CKCTL | ALWAYS_ENABLED,
- .rate_offset = CKCTL_DSPMMUDIV_OFFSET,
- .recalc = &ckctl_recalc,
-};
-
-static struct clk dspper_ck = {
- .name = "dspper_ck",
- .parent = &ck_dpll1,
- .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
- RATE_CKCTL | DSP_DOMAIN_CLOCK | VIRTUAL_IO_ADDRESS,
- .enable_reg = DSP_IDLECT2,
- .enable_bit = EN_PERCK,
- .rate_offset = CKCTL_PERDIV_OFFSET,
- .recalc = &followparent_recalc,
- //.recalc = &ckctl_recalc,
-};
-
-static struct clk dspxor_ck = {
- .name = "dspxor_ck",
- .parent = &ck_ref,
- .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
- DSP_DOMAIN_CLOCK | VIRTUAL_IO_ADDRESS,
- .enable_reg = DSP_IDLECT2,
- .enable_bit = EN_XORPCK,
- .recalc = &followparent_recalc,
-};
-
-static struct clk dsptim_ck = {
- .name = "dsptim_ck",
- .parent = &ck_ref,
- .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
- DSP_DOMAIN_CLOCK | VIRTUAL_IO_ADDRESS,
- .enable_reg = DSP_IDLECT2,
- .enable_bit = EN_DSPTIMCK,
- .recalc = &followparent_recalc,
-};
-
-static struct clk tc_ck = {
- .name = "tc_ck",
- .parent = &ck_dpll1,
- .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP730 |
- RATE_CKCTL | RATE_PROPAGATES | ALWAYS_ENABLED,
- .rate_offset = CKCTL_TCDIV_OFFSET,
- .recalc = &ckctl_recalc,
-};
-
-static struct clk arminth_ck1510 = {
- .name = "arminth_ck",
- .parent = &tc_ck,
- .flags = CLOCK_IN_OMAP1510 | ALWAYS_ENABLED,
- .recalc = &followparent_recalc,
- /* Note: On 1510 the frequency follows TC_CK
- *
- * 16xx version is in MPU clocks.
- */
-};
-
-static struct clk tipb_ck = {
- .name = "tibp_ck",
- .parent = &tc_ck,
- .flags = CLOCK_IN_OMAP1510 | ALWAYS_ENABLED,
- .recalc = &followparent_recalc,
-};
-
-static struct clk l3_ocpi_ck = {
- .name = "l3_ocpi_ck",
- .parent = &tc_ck,
- .flags = CLOCK_IN_OMAP16XX,
- .enable_reg = ARM_IDLECT3,
- .enable_bit = EN_OCPI_CK,
- .recalc = &followparent_recalc,
-};
+DEFINE_SPINLOCK(clockfw_lock);
-static struct clk tc1_ck = {
- .name = "tc1_ck",
- .parent = &tc_ck,
- .flags = CLOCK_IN_OMAP16XX,
- .enable_reg = ARM_IDLECT3,
- .enable_bit = EN_TC1_CK,
- .recalc = &followparent_recalc,
-};
+static struct clk_functions *arch_clock;
-static struct clk tc2_ck = {
- .name = "tc2_ck",
- .parent = &tc_ck,
- .flags = CLOCK_IN_OMAP16XX,
- .enable_reg = ARM_IDLECT3,
- .enable_bit = EN_TC2_CK,
- .recalc = &followparent_recalc,
-};
+/*-------------------------------------------------------------------------
+ * Standard clock functions defined in asm/hardware/clock.h
+ *-------------------------------------------------------------------------*/
-static struct clk dma_ck = {
- .name = "dma_ck",
- .parent = &tc_ck,
- .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
- ALWAYS_ENABLED,
- .recalc = &followparent_recalc,
-};
-
-static struct clk dma_lcdfree_ck = {
- .name = "dma_lcdfree_ck",
- .parent = &tc_ck,
- .flags = CLOCK_IN_OMAP16XX | ALWAYS_ENABLED,
- .recalc = &followparent_recalc,
-};
-
-static struct clk api_ck = {
- .name = "api_ck",
- .parent = &tc_ck,
- .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX,
- .enable_reg = ARM_IDLECT2,
- .enable_bit = EN_APICK,
- .recalc = &followparent_recalc,
-};
-
-static struct clk lb_ck = {
- .name = "lb_ck",
- .parent = &tc_ck,
- .flags = CLOCK_IN_OMAP1510,
- .enable_reg = ARM_IDLECT2,
- .enable_bit = EN_LBCK,
- .recalc = &followparent_recalc,
-};
-
-static struct clk rhea1_ck = {
- .name = "rhea1_ck",
- .parent = &tc_ck,
- .flags = CLOCK_IN_OMAP16XX | ALWAYS_ENABLED,
- .recalc = &followparent_recalc,
-};
-
-static struct clk rhea2_ck = {
- .name = "rhea2_ck",
- .parent = &tc_ck,
- .flags = CLOCK_IN_OMAP16XX | ALWAYS_ENABLED,
- .recalc = &followparent_recalc,
-};
-
-static struct clk lcd_ck = {
- .name = "lcd_ck",
- .parent = &ck_dpll1,
- .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP730 |
- RATE_CKCTL,
- .enable_reg = ARM_IDLECT2,
- .enable_bit = EN_LCDCK,
- .rate_offset = CKCTL_LCDDIV_OFFSET,
- .recalc = &ckctl_recalc,
-};
-
-static struct clk uart1_1510 = {
- .name = "uart1_ck",
- /* Direct from ULPD, no parent */
- .rate = 12000000,
- .flags = CLOCK_IN_OMAP1510 | ENABLE_REG_32BIT | ALWAYS_ENABLED,
- .enable_reg = MOD_CONF_CTRL_0,
- .enable_bit = 29, /* Chooses between 12MHz and 48MHz */
- .set_rate = &set_uart_rate,
- .recalc = &uart_recalc,
-};
-
-static struct clk uart1_16xx = {
- .name = "uart1_ck",
- /* Direct from ULPD, no parent */
- .rate = 48000000,
- .flags = CLOCK_IN_OMAP16XX | RATE_FIXED | ENABLE_REG_32BIT,
- .enable_reg = MOD_CONF_CTRL_0,
- .enable_bit = 29,
-};
-
-static struct clk uart2_ck = {
- .name = "uart2_ck",
- /* Direct from ULPD, no parent */
- .rate = 12000000,
- .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | ENABLE_REG_32BIT |
- ALWAYS_ENABLED,
- .enable_reg = MOD_CONF_CTRL_0,
- .enable_bit = 30, /* Chooses between 12MHz and 48MHz */
- .set_rate = &set_uart_rate,
- .recalc = &uart_recalc,
-};
-
-static struct clk uart3_1510 = {
- .name = "uart3_ck",
- /* Direct from ULPD, no parent */
- .rate = 12000000,
- .flags = CLOCK_IN_OMAP1510 | ENABLE_REG_32BIT | ALWAYS_ENABLED,
- .enable_reg = MOD_CONF_CTRL_0,
- .enable_bit = 31, /* Chooses between 12MHz and 48MHz */
- .set_rate = &set_uart_rate,
- .recalc = &uart_recalc,
-};
-
-static struct clk uart3_16xx = {
- .name = "uart3_ck",
- /* Direct from ULPD, no parent */
- .rate = 48000000,
- .flags = CLOCK_IN_OMAP16XX | RATE_FIXED | ENABLE_REG_32BIT,
- .enable_reg = MOD_CONF_CTRL_0,
- .enable_bit = 31,
-};
-
-static struct clk usb_clko = { /* 6 MHz output on W4_USB_CLKO */
- .name = "usb_clko",
- /* Direct from ULPD, no parent */
- .rate = 6000000,
- .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
- RATE_FIXED | ENABLE_REG_32BIT,
- .enable_reg = ULPD_CLOCK_CTRL,
- .enable_bit = USB_MCLK_EN_BIT,
-};
-
-static struct clk usb_hhc_ck1510 = {
- .name = "usb_hhc_ck",
- /* Direct from ULPD, no parent */
- .rate = 48000000, /* Actually 2 clocks, 12MHz and 48MHz */
- .flags = CLOCK_IN_OMAP1510 |
- RATE_FIXED | ENABLE_REG_32BIT,
- .enable_reg = MOD_CONF_CTRL_0,
- .enable_bit = USB_HOST_HHC_UHOST_EN,
-};
-
-static struct clk usb_hhc_ck16xx = {
- .name = "usb_hhc_ck",
- /* Direct from ULPD, no parent */
- .rate = 48000000,
- /* OTG_SYSCON_2.OTG_PADEN == 0 (not 1510-compatible) */
- .flags = CLOCK_IN_OMAP16XX |
- RATE_FIXED | ENABLE_REG_32BIT,
- .enable_reg = OTG_BASE + 0x08 /* OTG_SYSCON_2 */,
- .enable_bit = 8 /* UHOST_EN */,
-};
-
-static struct clk usb_dc_ck = {
- .name = "usb_dc_ck",
- /* Direct from ULPD, no parent */
- .rate = 48000000,
- .flags = CLOCK_IN_OMAP16XX | RATE_FIXED,
- .enable_reg = SOFT_REQ_REG,
- .enable_bit = 4,
-};
-
-static struct clk mclk_1510 = {
- .name = "mclk",
- /* Direct from ULPD, no parent. May be enabled by ext hardware. */
- .rate = 12000000,
- .flags = CLOCK_IN_OMAP1510 | RATE_FIXED,
-};
-
-static struct clk mclk_16xx = {
- .name = "mclk",
- /* Direct from ULPD, no parent. May be enabled by ext hardware. */
- .flags = CLOCK_IN_OMAP16XX,
- .enable_reg = COM_CLK_DIV_CTRL_SEL,
- .enable_bit = COM_ULPD_PLL_CLK_REQ,
- .set_rate = &set_ext_clk_rate,
- .round_rate = &round_ext_clk_rate,
- .init = &init_ext_clk,
-};
-
-static struct clk bclk_1510 = {
- .name = "bclk",
- /* Direct from ULPD, no parent. May be enabled by ext hardware. */
- .rate = 12000000,
- .flags = CLOCK_IN_OMAP1510 | RATE_FIXED,
-};
-
-static struct clk bclk_16xx = {
- .name = "bclk",
- /* Direct from ULPD, no parent. May be enabled by ext hardware. */
- .flags = CLOCK_IN_OMAP16XX,
- .enable_reg = SWD_CLK_DIV_CTRL_SEL,
- .enable_bit = SWD_ULPD_PLL_CLK_REQ,
- .set_rate = &set_ext_clk_rate,
- .round_rate = &round_ext_clk_rate,
- .init = &init_ext_clk,
-};
-
-static struct clk mmc1_ck = {
- .name = "mmc1_ck",
- /* Functional clock is direct from ULPD, interface clock is ARMPER */
- .parent = &armper_ck,
- .rate = 48000000,
- .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
- RATE_FIXED | ENABLE_REG_32BIT,
- .enable_reg = MOD_CONF_CTRL_0,
- .enable_bit = 23,
-};
-
-static struct clk mmc2_ck = {
- .name = "mmc2_ck",
- /* Functional clock is direct from ULPD, interface clock is ARMPER */
- .parent = &armper_ck,
- .rate = 48000000,
- .flags = CLOCK_IN_OMAP16XX |
- RATE_FIXED | ENABLE_REG_32BIT,
- .enable_reg = MOD_CONF_CTRL_0,
- .enable_bit = 20,
-};
-
-static struct clk virtual_ck_mpu = {
- .name = "mpu",
- .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
- VIRTUAL_CLOCK | ALWAYS_ENABLED,
- .parent = &arm_ck, /* Is smarter alias for */
- .recalc = &followparent_recalc,
- .set_rate = &select_table_rate,
- .round_rate = &round_to_table_rate,
-};
-
-
-static struct clk * onchip_clks[] = {
- /* non-ULPD clocks */
- &ck_ref,
- &ck_dpll1,
- /* CK_GEN1 clocks */
- &ck_dpll1out,
- &arm_ck,
- &armper_ck,
- &arm_gpio_ck,
- &armxor_ck,
- &armtim_ck,
- &armwdt_ck,
- &arminth_ck1510, &arminth_ck16xx,
- /* CK_GEN2 clocks */
- &dsp_ck,
- &dspmmu_ck,
- &dspper_ck,
- &dspxor_ck,
- &dsptim_ck,
- /* CK_GEN3 clocks */
- &tc_ck,
- &tipb_ck,
- &l3_ocpi_ck,
- &tc1_ck,
- &tc2_ck,
- &dma_ck,
- &dma_lcdfree_ck,
- &api_ck,
- &lb_ck,
- &rhea1_ck,
- &rhea2_ck,
- &lcd_ck,
- /* ULPD clocks */
- &uart1_1510,
- &uart1_16xx,
- &uart2_ck,
- &uart3_1510,
- &uart3_16xx,
- &usb_clko,
- &usb_hhc_ck1510, &usb_hhc_ck16xx,
- &usb_dc_ck,
- &mclk_1510, &mclk_16xx,
- &bclk_1510, &bclk_16xx,
- &mmc1_ck,
- &mmc2_ck,
- /* Virtual clocks */
- &virtual_ck_mpu,
-};
-
-struct clk *clk_get(struct device *dev, const char *id)
+struct clk * clk_get(struct device *dev, const char *id)
{
struct clk *p, *clk = ERR_PTR(-ENOENT);
@@ -589,534 +53,200 @@ struct clk *clk_get(struct device *dev, const char *id)
}
EXPORT_SYMBOL(clk_get);
-
-void clk_put(struct clk *clk)
-{
- if (clk && !IS_ERR(clk))
- module_put(clk->owner);
-}
-EXPORT_SYMBOL(clk_put);
-
-
-int __clk_enable(struct clk *clk)
-{
- __u16 regval16;
- __u32 regval32;
-
- if (clk->flags & ALWAYS_ENABLED)
- return 0;
-
- if (unlikely(clk->enable_reg == 0)) {
- printk(KERN_ERR "clock.c: Enable for %s without enable code\n",
- clk->name);
- return 0;
- }
-
- if (clk->flags & DSP_DOMAIN_CLOCK) {
- __clk_use(&api_ck);
- }
-
- if (clk->flags & ENABLE_REG_32BIT) {
- if (clk->flags & VIRTUAL_IO_ADDRESS) {
- regval32 = __raw_readl(clk->enable_reg);
- regval32 |= (1 << clk->enable_bit);
- __raw_writel(regval32, clk->enable_reg);
- } else {
- regval32 = omap_readl(clk->enable_reg);
- regval32 |= (1 << clk->enable_bit);
- omap_writel(regval32, clk->enable_reg);
- }
- } else {
- if (clk->flags & VIRTUAL_IO_ADDRESS) {
- regval16 = __raw_readw(clk->enable_reg);
- regval16 |= (1 << clk->enable_bit);
- __raw_writew(regval16, clk->enable_reg);
- } else {
- regval16 = omap_readw(clk->enable_reg);
- regval16 |= (1 << clk->enable_bit);
- omap_writew(regval16, clk->enable_reg);
- }
- }
-
- if (clk->flags & DSP_DOMAIN_CLOCK) {
- __clk_unuse(&api_ck);
- }
-
- return 0;
-}
-
-
-void __clk_disable(struct clk *clk)
-{
- __u16 regval16;
- __u32 regval32;
-
- if (clk->enable_reg == 0)
- return;
-
- if (clk->flags & DSP_DOMAIN_CLOCK) {
- __clk_use(&api_ck);
- }
-
- if (clk->flags & ENABLE_REG_32BIT) {
- if (clk->flags & VIRTUAL_IO_ADDRESS) {
- regval32 = __raw_readl(clk->enable_reg);
- regval32 &= ~(1 << clk->enable_bit);
- __raw_writel(regval32, clk->enable_reg);
- } else {
- regval32 = omap_readl(clk->enable_reg);
- regval32 &= ~(1 << clk->enable_bit);
- omap_writel(regval32, clk->enable_reg);
- }
- } else {
- if (clk->flags & VIRTUAL_IO_ADDRESS) {
- regval16 = __raw_readw(clk->enable_reg);
- regval16 &= ~(1 << clk->enable_bit);
- __raw_writew(regval16, clk->enable_reg);
- } else {
- regval16 = omap_readw(clk->enable_reg);
- regval16 &= ~(1 << clk->enable_bit);
- omap_writew(regval16, clk->enable_reg);
- }
- }
-
- if (clk->flags & DSP_DOMAIN_CLOCK) {
- __clk_unuse(&api_ck);
- }
-}
-
-
-void __clk_unuse(struct clk *clk)
-{
- if (clk->usecount > 0 && !(--clk->usecount)) {
- __clk_disable(clk);
- if (likely(clk->parent))
- __clk_unuse(clk->parent);
- }
-}
-
-
-int __clk_use(struct clk *clk)
-{
- int ret = 0;
- if (clk->usecount++ == 0) {
- if (likely(clk->parent))
- ret = __clk_use(clk->parent);
-
- if (unlikely(ret != 0)) {
- clk->usecount--;
- return ret;
- }
-
- ret = __clk_enable(clk);
-
- if (unlikely(ret != 0) && clk->parent) {
- __clk_unuse(clk->parent);
- clk->usecount--;
- }
- }
-
- return ret;
-}
-
-
int clk_enable(struct clk *clk)
{
unsigned long flags;
- int ret;
+ int ret = 0;
spin_lock_irqsave(&clockfw_lock, flags);
- ret = __clk_enable(clk);
+ if (clk->enable)
+ ret = clk->enable(clk);
+ else if (arch_clock->clk_enable)
+ ret = arch_clock->clk_enable(clk);
+ else
+ printk(KERN_ERR "Could not enable clock %s\n", clk->name);
spin_unlock_irqrestore(&clockfw_lock, flags);
+
return ret;
}
EXPORT_SYMBOL(clk_enable);
-
void clk_disable(struct clk *clk)
{
unsigned long flags;
spin_lock_irqsave(&clockfw_lock, flags);
- __clk_disable(clk);
+ if (clk->disable)
+ clk->disable(clk);
+ else if (arch_clock->clk_disable)
+ arch_clock->clk_disable(clk);
+ else
+ printk(KERN_ERR "Could not disable clock %s\n", clk->name);
spin_unlock_irqrestore(&clockfw_lock, flags);
}
EXPORT_SYMBOL(clk_disable);
-
int clk_use(struct clk *clk)
{
unsigned long flags;
int ret = 0;
spin_lock_irqsave(&clockfw_lock, flags);
- ret = __clk_use(clk);
+ if (arch_clock->clk_use)
+ ret = arch_clock->clk_use(clk);
spin_unlock_irqrestore(&clockfw_lock, flags);
+
return ret;
}
EXPORT_SYMBOL(clk_use);
-
void clk_unuse(struct clk *clk)
{
unsigned long flags;
spin_lock_irqsave(&clockfw_lock, flags);
- __clk_unuse(clk);
+ if (arch_clock->clk_unuse)
+ arch_clock->clk_unuse(clk);
spin_unlock_irqrestore(&clockfw_lock, flags);
}
EXPORT_SYMBOL(clk_unuse);
-
int clk_get_usecount(struct clk *clk)
{
- return clk->usecount;
-}
-EXPORT_SYMBOL(clk_get_usecount);
-
-
-unsigned long clk_get_rate(struct clk *clk)
-{
- return clk->rate;
-}
-EXPORT_SYMBOL(clk_get_rate);
-
-
-static __u16 verify_ckctl_value(__u16 newval)
-{
- /* This function checks for following limitations set
- * by the hardware (all conditions must be true):
- * DSPMMU_CK == DSP_CK or DSPMMU_CK == DSP_CK/2
- * ARM_CK >= TC_CK
- * DSP_CK >= TC_CK
- * DSPMMU_CK >= TC_CK
- *
- * In addition following rules are enforced:
- * LCD_CK <= TC_CK
- * ARMPER_CK <= TC_CK
- *
- * However, maximum frequencies are not checked for!
- */
- __u8 per_exp;
- __u8 lcd_exp;
- __u8 arm_exp;
- __u8 dsp_exp;
- __u8 tc_exp;
- __u8 dspmmu_exp;
-
- per_exp = (newval >> CKCTL_PERDIV_OFFSET) & 3;
- lcd_exp = (newval >> CKCTL_LCDDIV_OFFSET) & 3;
- arm_exp = (newval >> CKCTL_ARMDIV_OFFSET) & 3;
- dsp_exp = (newval >> CKCTL_DSPDIV_OFFSET) & 3;
- tc_exp = (newval >> CKCTL_TCDIV_OFFSET) & 3;
- dspmmu_exp = (newval >> CKCTL_DSPMMUDIV_OFFSET) & 3;
-
- if (dspmmu_exp < dsp_exp)
- dspmmu_exp = dsp_exp;
- if (dspmmu_exp > dsp_exp+1)
- dspmmu_exp = dsp_exp+1;
- if (tc_exp < arm_exp)
- tc_exp = arm_exp;
- if (tc_exp < dspmmu_exp)
- tc_exp = dspmmu_exp;
- if (tc_exp > lcd_exp)
- lcd_exp = tc_exp;
- if (tc_exp > per_exp)
- per_exp = tc_exp;
+ unsigned long flags;
+ int ret = 0;
- newval &= 0xf000;
- newval |= per_exp << CKCTL_PERDIV_OFFSET;
- newval |= lcd_exp << CKCTL_LCDDIV_OFFSET;
- newval |= arm_exp << CKCTL_ARMDIV_OFFSET;
- newval |= dsp_exp << CKCTL_DSPDIV_OFFSET;
- newval |= tc_exp << CKCTL_TCDIV_OFFSET;
- newval |= dspmmu_exp << CKCTL_DSPMMUDIV_OFFSET;
+ spin_lock_irqsave(&clockfw_lock, flags);
+ ret = clk->usecount;
+ spin_unlock_irqrestore(&clockfw_lock, flags);
- return newval;
+ return ret;
}
+EXPORT_SYMBOL(clk_get_usecount);
-
-static int calc_dsor_exp(struct clk *clk, unsigned long rate)
+unsigned long clk_get_rate(struct clk *clk)
{
- /* Note: If target frequency is too low, this function will return 4,
- * which is invalid value. Caller must check for this value and act
- * accordingly.
- *
- * Note: This function does not check for following limitations set
- * by the hardware (all conditions must be true):
- * DSPMMU_CK == DSP_CK or DSPMMU_CK == DSP_CK/2
- * ARM_CK >= TC_CK
- * DSP_CK >= TC_CK
- * DSPMMU_CK >= TC_CK
- */
- unsigned long realrate;
- struct clk * parent;
- unsigned dsor_exp;
-
- if (unlikely(!(clk->flags & RATE_CKCTL)))
- return -EINVAL;
-
- parent = clk->parent;
- if (unlikely(parent == 0))
- return -EIO;
-
- realrate = parent->rate;
- for (dsor_exp=0; dsor_exp<4; dsor_exp++) {
- if (realrate <= rate)
- break;
+ unsigned long flags;
+ unsigned long ret = 0;
- realrate /= 2;
- }
+ spin_lock_irqsave(&clockfw_lock, flags);
+ ret = clk->rate;
+ spin_unlock_irqrestore(&clockfw_lock, flags);
- return dsor_exp;
+ return ret;
}
+EXPORT_SYMBOL(clk_get_rate);
-
-static void ckctl_recalc(struct clk * clk)
+void clk_put(struct clk *clk)
{
- int dsor;
-
- /* Calculate divisor encoded as 2-bit exponent */
- if (clk->flags & DSP_DOMAIN_CLOCK) {
- /* The clock control bits are in DSP domain,
- * so api_ck is needed for access.
- * Note that DSP_CKCTL virt addr = phys addr, so
- * we must use __raw_readw() instead of omap_readw().
- */
- __clk_use(&api_ck);
- dsor = 1 << (3 & (__raw_readw(DSP_CKCTL) >> clk->rate_offset));
- __clk_unuse(&api_ck);
- } else {
- dsor = 1 << (3 & (omap_readw(ARM_CKCTL) >> clk->rate_offset));
- }
- if (unlikely(clk->rate == clk->parent->rate / dsor))
- return; /* No change, quick exit */
- clk->rate = clk->parent->rate / dsor;
-
- if (unlikely(clk->flags & RATE_PROPAGATES))
- propagate_rate(clk);
+ if (clk && !IS_ERR(clk))
+ module_put(clk->owner);
}
+EXPORT_SYMBOL(clk_put);
+/*-------------------------------------------------------------------------
+ * Optional clock functions defined in asm/hardware/clock.h
+ *-------------------------------------------------------------------------*/
long clk_round_rate(struct clk *clk, unsigned long rate)
{
- int dsor_exp;
-
- if (clk->flags & RATE_FIXED)
- return clk->rate;
-
- if (clk->flags & RATE_CKCTL) {
- dsor_exp = calc_dsor_exp(clk, rate);
- if (dsor_exp < 0)
- return dsor_exp;
- if (dsor_exp > 3)
- dsor_exp = 3;
- return clk->parent->rate / (1 << dsor_exp);
- }
+ unsigned long flags;
+ long ret = 0;
- if(clk->round_rate != 0)
- return clk->round_rate(clk, rate);
+ spin_lock_irqsave(&clockfw_lock, flags);
+ if (arch_clock->clk_round_rate)
+ ret = arch_clock->clk_round_rate(clk, rate);
+ spin_unlock_irqrestore(&clockfw_lock, flags);
- return clk->rate;
+ return ret;
}
EXPORT_SYMBOL(clk_round_rate);
-
-static void propagate_rate(struct clk * clk)
-{
- struct clk ** clkp;
-
- for (clkp = onchip_clks; clkp < onchip_clks+ARRAY_SIZE(onchip_clks); clkp++) {
- if (likely((*clkp)->parent != clk)) continue;
- if (likely((*clkp)->recalc))
- (*clkp)->recalc(*clkp);
- }
-}
-
-
-static int select_table_rate(struct clk * clk, unsigned long rate)
+int clk_set_rate(struct clk *clk, unsigned long rate)
{
- /* Find the highest supported frequency <= rate and switch to it */
- struct mpu_rate * ptr;
-
- if (clk != &virtual_ck_mpu)
- return -EINVAL;
-
- for (ptr = rate_table; ptr->rate; ptr++) {
- if (ptr->xtal != ck_ref.rate)
- continue;
-
- /* DPLL1 cannot be reprogrammed without risking system crash */
- if (likely(ck_dpll1.rate!=0) && ptr->pll_rate != ck_dpll1.rate)
- continue;
-
- /* Can check only after xtal frequency check */
- if (ptr->rate <= rate)
- break;
- }
-
- if (!ptr->rate)
- return -EINVAL;
+ unsigned long flags;
+ int ret = 0;
- /*
- * In most cases we should not need to reprogram DPLL.
- * Reprogramming the DPLL is tricky, it must be done from SRAM.
- */
- omap_sram_reprogram_clock(ptr->dpllctl_val, ptr->ckctl_val);
+ spin_lock_irqsave(&clockfw_lock, flags);
+ if (arch_clock->clk_set_rate)
+ ret = arch_clock->clk_set_rate(clk, rate);
+ spin_unlock_irqrestore(&clockfw_lock, flags);
- ck_dpll1.rate = ptr->pll_rate;
- propagate_rate(&ck_dpll1);
- return 0;
+ return ret;
}
+EXPORT_SYMBOL(clk_set_rate);
-
-static long round_to_table_rate(struct clk * clk, unsigned long rate)
+int clk_set_parent(struct clk *clk, struct clk *parent)
{
- /* Find the highest supported frequency <= rate */
- struct mpu_rate * ptr;
- long highest_rate;
-
- if (clk != &virtual_ck_mpu)
- return -EINVAL;
-
- highest_rate = -EINVAL;
-
- for (ptr = rate_table; ptr->rate; ptr++) {
- if (ptr->xtal != ck_ref.rate)
- continue;
-
- highest_rate = ptr->rate;
+ unsigned long flags;
+ int ret = 0;
- /* Can check only after xtal frequency check */
- if (ptr->rate <= rate)
- break;
- }
+ spin_lock_irqsave(&clockfw_lock, flags);
+ if (arch_clock->clk_set_parent)
+ ret = arch_clock->clk_set_parent(clk, parent);
+ spin_unlock_irqrestore(&clockfw_lock, flags);
- return highest_rate;
+ return ret;
}
+EXPORT_SYMBOL(clk_set_parent);
-
-int clk_set_rate(struct clk *clk, unsigned long rate)
+struct clk *clk_get_parent(struct clk *clk)
{
- int ret = -EINVAL;
- int dsor_exp;
- __u16 regval;
- unsigned long flags;
-
- if (clk->flags & RATE_CKCTL) {
- dsor_exp = calc_dsor_exp(clk, rate);
- if (dsor_exp > 3)
- dsor_exp = -EINVAL;
- if (dsor_exp < 0)
- return dsor_exp;
-
- spin_lock_irqsave(&clockfw_lock, flags);
- regval = omap_readw(ARM_CKCTL);
- regval &= ~(3 << clk->rate_offset);
- regval |= dsor_exp << clk->rate_offset;
- regval = verify_ckctl_value(regval);
- omap_writew(regval, ARM_CKCTL);
- clk->rate = clk->parent->rate / (1 << dsor_exp);
- spin_unlock_irqrestore(&clockfw_lock, flags);
- ret = 0;
- } else if(clk->set_rate != 0) {
- spin_lock_irqsave(&clockfw_lock, flags);
- ret = clk->set_rate(clk, rate);
- spin_unlock_irqrestore(&clockfw_lock, flags);
- }
+ unsigned long flags;
+ struct clk * ret = NULL;
- if (unlikely(ret == 0 && (clk->flags & RATE_PROPAGATES)))
- propagate_rate(clk);
+ spin_lock_irqsave(&clockfw_lock, flags);
+ if (arch_clock->clk_get_parent)
+ ret = arch_clock->clk_get_parent(clk);
+ spin_unlock_irqrestore(&clockfw_lock, flags);
return ret;
}
-EXPORT_SYMBOL(clk_set_rate);
+EXPORT_SYMBOL(clk_get_parent);
+/*-------------------------------------------------------------------------
+ * OMAP specific clock functions shared between omap1 and omap2
+ *-------------------------------------------------------------------------*/
-static unsigned calc_ext_dsor(unsigned long rate)
-{
- unsigned dsor;
+unsigned int __initdata mpurate;
- /* MCLK and BCLK divisor selection is not linear:
- * freq = 96MHz / dsor
- *
- * RATIO_SEL range: dsor <-> RATIO_SEL
- * 0..6: (RATIO_SEL+2) <-> (dsor-2)
- * 6..48: (8+(RATIO_SEL-6)*2) <-> ((dsor-8)/2+6)
- * Minimum dsor is 2 and maximum is 96. Odd divisors starting from 9
- * can not be used.
- */
- for (dsor = 2; dsor < 96; ++dsor) {
- if ((dsor & 1) && dsor > 8)
- continue;
- if (rate >= 96000000 / dsor)
- break;
- }
- return dsor;
-}
-
-/* Only needed on 1510 */
-static int set_uart_rate(struct clk * clk, unsigned long rate)
-{
- unsigned int val;
-
- val = omap_readl(clk->enable_reg);
- if (rate == 12000000)
- val &= ~(1 << clk->enable_bit);
- else if (rate == 48000000)
- val |= (1 << clk->enable_bit);
- else
- return -EINVAL;
- omap_writel(val, clk->enable_reg);
- clk->rate = rate;
-
- return 0;
-}
-
-static int set_ext_clk_rate(struct clk * clk, unsigned long rate)
+/*
+ * By default we use the rate set by the bootloader.
+ * You can override this with mpurate= cmdline option.
+ */
+static int __init omap_clk_setup(char *str)
{
- unsigned dsor;
- __u16 ratio_bits;
+ get_option(&str, &mpurate);
- dsor = calc_ext_dsor(rate);
- clk->rate = 96000000 / dsor;
- if (dsor > 8)
- ratio_bits = ((dsor - 8) / 2 + 6) << 2;
- else
- ratio_bits = (dsor - 2) << 2;
+ if (!mpurate)
+ return 1;
- ratio_bits |= omap_readw(clk->enable_reg) & ~0xfd;
- omap_writew(ratio_bits, clk->enable_reg);
+ if (mpurate < 1000)
+ mpurate *= 1000000;
- return 0;
+ return 1;
}
+__setup("mpurate=", omap_clk_setup);
-
-static long round_ext_clk_rate(struct clk * clk, unsigned long rate)
+/* Used for clocks that always have same value as the parent clock */
+void followparent_recalc(struct clk *clk)
{
- return 96000000 / calc_ext_dsor(rate);
+ clk->rate = clk->parent->rate;
}
-
-static void init_ext_clk(struct clk * clk)
+/* Propagate rate to children */
+void propagate_rate(struct clk * tclk)
{
- unsigned dsor;
- __u16 ratio_bits;
+ struct clk *clkp;
- /* Determine current rate and ensure clock is based on 96MHz APLL */
- ratio_bits = omap_readw(clk->enable_reg) & ~1;
- omap_writew(ratio_bits, clk->enable_reg);
-
- ratio_bits = (ratio_bits & 0xfc) >> 2;
- if (ratio_bits > 6)
- dsor = (ratio_bits - 6) * 2 + 8;
- else
- dsor = ratio_bits + 2;
-
- clk-> rate = 96000000 / dsor;
+ list_for_each_entry(clkp, &clocks, node) {
+ if (likely(clkp->parent != tclk))
+ continue;
+ if (likely((u32)clkp->recalc))
+ clkp->recalc(clkp);
+ }
}
-
int clk_register(struct clk *clk)
{
down(&clocks_sem);
@@ -1124,6 +254,7 @@ int clk_register(struct clk *clk)
if (clk->init)
clk->init(clk);
up(&clocks_sem);
+
return 0;
}
EXPORT_SYMBOL(clk_register);
@@ -1136,203 +267,38 @@ void clk_unregister(struct clk *clk)
}
EXPORT_SYMBOL(clk_unregister);
-#ifdef CONFIG_OMAP_RESET_CLOCKS
-/*
- * Resets some clocks that may be left on from bootloader,
- * but leaves serial clocks on. See also omap_late_clk_reset().
- */
-static inline void omap_early_clk_reset(void)
+void clk_deny_idle(struct clk *clk)
{
- //omap_writel(0x3 << 29, MOD_CONF_CTRL_0);
+ unsigned long flags;
+
+ spin_lock_irqsave(&clockfw_lock, flags);
+ if (arch_clock->clk_deny_idle)
+ arch_clock->clk_deny_idle(clk);
+ spin_unlock_irqrestore(&clockfw_lock, flags);
}
-#else
-#define omap_early_clk_reset() {}
-#endif
+EXPORT_SYMBOL(clk_deny_idle);
-int __init clk_init(void)
+void clk_allow_idle(struct clk *clk)
{
- struct clk ** clkp;
- const struct omap_clock_config *info;
- int crystal_type = 0; /* Default 12 MHz */
-
- omap_early_clk_reset();
-
- for (clkp = onchip_clks; clkp < onchip_clks+ARRAY_SIZE(onchip_clks); clkp++) {
- if (((*clkp)->flags &CLOCK_IN_OMAP1510) && cpu_is_omap1510()) {
- clk_register(*clkp);
- continue;
- }
-
- if (((*clkp)->flags &CLOCK_IN_OMAP16XX) && cpu_is_omap16xx()) {
- clk_register(*clkp);
- continue;
- }
-
- if (((*clkp)->flags &CLOCK_IN_OMAP730) && cpu_is_omap730()) {
- clk_register(*clkp);
- continue;
- }
- }
-
- info = omap_get_config(OMAP_TAG_CLOCK, struct omap_clock_config);
- if (info != NULL) {
- if (!cpu_is_omap1510())
- crystal_type = info->system_clock_type;
- }
-
-#if defined(CONFIG_ARCH_OMAP730)
- ck_ref.rate = 13000000;
-#elif defined(CONFIG_ARCH_OMAP16XX)
- if (crystal_type == 2)
- ck_ref.rate = 19200000;
-#endif
-
- printk("Clocks: ARM_SYSST: 0x%04x DPLL_CTL: 0x%04x ARM_CKCTL: 0x%04x\n",
- omap_readw(ARM_SYSST), omap_readw(DPLL_CTL),
- omap_readw(ARM_CKCTL));
-
- /* We want to be in syncronous scalable mode */
- omap_writew(0x1000, ARM_SYSST);
-
-#ifdef CONFIG_OMAP_CLOCKS_SET_BY_BOOTLOADER
- /* Use values set by bootloader. Determine PLL rate and recalculate
- * dependent clocks as if kernel had changed PLL or divisors.
- */
- {
- unsigned pll_ctl_val = omap_readw(DPLL_CTL);
-
- ck_dpll1.rate = ck_ref.rate; /* Base xtal rate */
- if (pll_ctl_val & 0x10) {
- /* PLL enabled, apply multiplier and divisor */
- if (pll_ctl_val & 0xf80)
- ck_dpll1.rate *= (pll_ctl_val & 0xf80) >> 7;
- ck_dpll1.rate /= ((pll_ctl_val & 0x60) >> 5) + 1;
- } else {
- /* PLL disabled, apply bypass divisor */
- switch (pll_ctl_val & 0xc) {
- case 0:
- break;
- case 0x4:
- ck_dpll1.rate /= 2;
- break;
- default:
- ck_dpll1.rate /= 4;
- break;
- }
- }
- }
- propagate_rate(&ck_dpll1);
-#else
- /* Find the highest supported frequency and enable it */
- if (select_table_rate(&virtual_ck_mpu, ~0)) {
- printk(KERN_ERR "System frequencies not set. Check your config.\n");
- /* Guess sane values (60MHz) */
- omap_writew(0x2290, DPLL_CTL);
- omap_writew(0x1005, ARM_CKCTL);
- ck_dpll1.rate = 60000000;
- propagate_rate(&ck_dpll1);
- }
-#endif
- /* Cache rates for clocks connected to ck_ref (not dpll1) */
- propagate_rate(&ck_ref);
- printk(KERN_INFO "Clocking rate (xtal/DPLL1/MPU): "
- "%ld.%01ld/%ld.%01ld/%ld.%01ld MHz\n",
- ck_ref.rate / 1000000, (ck_ref.rate / 100000) % 10,
- ck_dpll1.rate / 1000000, (ck_dpll1.rate / 100000) % 10,
- arm_ck.rate / 1000000, (arm_ck.rate / 100000) % 10);
-
-#ifdef CONFIG_MACH_OMAP_PERSEUS2
- /* Select slicer output as OMAP input clock */
- omap_writew(omap_readw(OMAP730_PCC_UPLD_CTRL) & ~0x1, OMAP730_PCC_UPLD_CTRL);
-#endif
-
- /* Turn off DSP and ARM_TIMXO. Make sure ARM_INTHCK is not divided */
- omap_writew(omap_readw(ARM_CKCTL) & 0x0fff, ARM_CKCTL);
-
- /* Put DSP/MPUI into reset until needed */
- omap_writew(0, ARM_RSTCT1);
- omap_writew(1, ARM_RSTCT2);
- omap_writew(0x400, ARM_IDLECT1);
-
- /*
- * According to OMAP5910 Erratum SYS_DMA_1, bit DMACK_REQ (bit 8)
- * of the ARM_IDLECT2 register must be set to zero. The power-on
- * default value of this bit is one.
- */
- omap_writew(0x0000, ARM_IDLECT2); /* Turn LCD clock off also */
-
- /*
- * Only enable those clocks we will need, let the drivers
- * enable other clocks as necessary
- */
- clk_use(&armper_ck);
- clk_use(&armxor_ck);
- clk_use(&armtim_ck);
-
- if (cpu_is_omap1510())
- clk_enable(&arm_gpio_ck);
+ unsigned long flags;
- return 0;
+ spin_lock_irqsave(&clockfw_lock, flags);
+ if (arch_clock->clk_allow_idle)
+ arch_clock->clk_allow_idle(clk);
+ spin_unlock_irqrestore(&clockfw_lock, flags);
}
+EXPORT_SYMBOL(clk_allow_idle);
+/*-------------------------------------------------------------------------*/
-#ifdef CONFIG_OMAP_RESET_CLOCKS
-
-static int __init omap_late_clk_reset(void)
+int __init clk_init(struct clk_functions * custom_clocks)
{
- /* Turn off all unused clocks */
- struct clk *p;
- __u32 regval32;
-
- /* USB_REQ_EN will be disabled later if necessary (usb_dc_ck) */
- regval32 = omap_readw(SOFT_REQ_REG) & (1 << 4);
- omap_writew(regval32, SOFT_REQ_REG);
- omap_writew(0, SOFT_REQ_REG2);
-
- list_for_each_entry(p, &clocks, node) {
- if (p->usecount > 0 || (p->flags & ALWAYS_ENABLED) ||
- p->enable_reg == 0)
- continue;
-
- /* Assume no DSP clocks have been activated by bootloader */
- if (p->flags & DSP_DOMAIN_CLOCK)
- continue;
-
- /* Is the clock already disabled? */
- if (p->flags & ENABLE_REG_32BIT) {
- if (p->flags & VIRTUAL_IO_ADDRESS)
- regval32 = __raw_readl(p->enable_reg);
- else
- regval32 = omap_readl(p->enable_reg);
- } else {
- if (p->flags & VIRTUAL_IO_ADDRESS)
- regval32 = __raw_readw(p->enable_reg);
- else
- regval32 = omap_readw(p->enable_reg);
- }
-
- if ((regval32 & (1 << p->enable_bit)) == 0)
- continue;
-
- /* FIXME: This clock seems to be necessary but no-one
- * has asked for its activation. */
- if (p == &tc2_ck // FIX: pm.c (SRAM), CCP, Camera
- || p == &ck_dpll1out // FIX: SoSSI, SSR
- || p == &arm_gpio_ck // FIX: GPIO code for 1510
- ) {
- printk(KERN_INFO "FIXME: Clock \"%s\" seems unused\n",
- p->name);
- continue;
- }
-
- printk(KERN_INFO "Disabling unused clock \"%s\"... ", p->name);
- __clk_disable(p);
- printk(" done\n");
+ if (!custom_clocks) {
+ printk(KERN_ERR "No custom clock functions registered\n");
+ BUG();
}
+ arch_clock = custom_clocks;
+
return 0;
}
-
-late_initcall(omap_late_clk_reset);
-
-#endif
diff --git a/arch/arm/plat-omap/clock.h b/arch/arm/plat-omap/clock.h
deleted file mode 100644
index a89e1e8c2519..000000000000
--- a/arch/arm/plat-omap/clock.h
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * linux/arch/arm/plat-omap/clock.h
- *
- * Copyright (C) 2004 Nokia corporation
- * Written by Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>
- * Based on clocks.h by Tony Lindgren, Gordon McNutt and RidgeRun, 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.
- */
-
-#ifndef __ARCH_ARM_OMAP_CLOCK_H
-#define __ARCH_ARM_OMAP_CLOCK_H
-
-struct module;
-
-struct clk {
- struct list_head node;
- struct module *owner;
- const char *name;
- struct clk *parent;
- unsigned long rate;
- __s8 usecount;
- __u16 flags;
- __u32 enable_reg;
- __u8 enable_bit;
- __u8 rate_offset;
- void (*recalc)(struct clk *);
- int (*set_rate)(struct clk *, unsigned long);
- long (*round_rate)(struct clk *, unsigned long);
- void (*init)(struct clk *);
-};
-
-
-struct mpu_rate {
- unsigned long rate;
- unsigned long xtal;
- unsigned long pll_rate;
- __u16 ckctl_val;
- __u16 dpllctl_val;
-};
-
-
-/* Clock flags */
-#define RATE_CKCTL 1
-#define RATE_FIXED 2
-#define RATE_PROPAGATES 4
-#define VIRTUAL_CLOCK 8
-#define ALWAYS_ENABLED 16
-#define ENABLE_REG_32BIT 32
-#define CLOCK_IN_OMAP16XX 64
-#define CLOCK_IN_OMAP1510 128
-#define CLOCK_IN_OMAP730 256
-#define DSP_DOMAIN_CLOCK 512
-#define VIRTUAL_IO_ADDRESS 1024
-
-/* ARM_CKCTL bit shifts */
-#define CKCTL_PERDIV_OFFSET 0
-#define CKCTL_LCDDIV_OFFSET 2
-#define CKCTL_ARMDIV_OFFSET 4
-#define CKCTL_DSPDIV_OFFSET 6
-#define CKCTL_TCDIV_OFFSET 8
-#define CKCTL_DSPMMUDIV_OFFSET 10
-/*#define ARM_TIMXO 12*/
-#define EN_DSPCK 13
-/*#define ARM_INTHCK_SEL 14*/ /* Divide-by-2 for mpu inth_ck */
-/* DSP_CKCTL bit shifts */
-#define CKCTL_DSPPERDIV_OFFSET 0
-
-/* ARM_IDLECT1 bit shifts */
-/*#define IDLWDT_ARM 0*/
-/*#define IDLXORP_ARM 1*/
-/*#define IDLPER_ARM 2*/
-/*#define IDLLCD_ARM 3*/
-/*#define IDLLB_ARM 4*/
-/*#define IDLHSAB_ARM 5*/
-/*#define IDLIF_ARM 6*/
-/*#define IDLDPLL_ARM 7*/
-/*#define IDLAPI_ARM 8*/
-/*#define IDLTIM_ARM 9*/
-/*#define SETARM_IDLE 11*/
-
-/* ARM_IDLECT2 bit shifts */
-#define EN_WDTCK 0
-#define EN_XORPCK 1
-#define EN_PERCK 2
-#define EN_LCDCK 3
-#define EN_LBCK 4 /* Not on 1610/1710 */
-/*#define EN_HSABCK 5*/
-#define EN_APICK 6
-#define EN_TIMCK 7
-#define DMACK_REQ 8
-#define EN_GPIOCK 9 /* Not on 1610/1710 */
-/*#define EN_LBFREECK 10*/
-#define EN_CKOUT_ARM 11
-
-/* ARM_IDLECT3 bit shifts */
-#define EN_OCPI_CK 0
-#define EN_TC1_CK 2
-#define EN_TC2_CK 4
-
-/* DSP_IDLECT2 bit shifts (0,1,2 are same as for ARM_IDLECT2) */
-#define EN_DSPTIMCK 5
-
-/* Various register defines for clock controls scattered around OMAP chip */
-#define USB_MCLK_EN_BIT 4 /* In ULPD_CLKC_CTRL */
-#define USB_HOST_HHC_UHOST_EN 9 /* In MOD_CONF_CTRL_0 */
-#define SWD_ULPD_PLL_CLK_REQ 1 /* In SWD_CLK_DIV_CTRL_SEL */
-#define COM_ULPD_PLL_CLK_REQ 1 /* In COM_CLK_DIV_CTRL_SEL */
-#define SWD_CLK_DIV_CTRL_SEL 0xfffe0874
-#define COM_CLK_DIV_CTRL_SEL 0xfffe0878
-#define SOFT_REQ_REG 0xfffe0834
-#define SOFT_REQ_REG2 0xfffe0880
-
-int clk_register(struct clk *clk);
-void clk_unregister(struct clk *clk);
-int clk_init(void);
-
-#endif
diff --git a/arch/arm/plat-omap/common.c b/arch/arm/plat-omap/common.c
index 02bcc6c1cd1b..ccdb452630cf 100644
--- a/arch/arm/plat-omap/common.c
+++ b/arch/arm/plat-omap/common.c
@@ -31,7 +31,7 @@
#include <asm/arch/mux.h>
#include <asm/arch/fpga.h>
-#include "clock.h"
+#include <asm/arch/clock.h>
#define NO_LENGTH_CHECK 0xffffffff
@@ -117,19 +117,43 @@ EXPORT_SYMBOL(omap_get_var_config);
static int __init omap_add_serial_console(void)
{
- const struct omap_serial_console_config *info;
-
- info = omap_get_config(OMAP_TAG_SERIAL_CONSOLE,
- struct omap_serial_console_config);
- if (info != NULL && info->console_uart) {
- static char speed[11], *opt = NULL;
+ const struct omap_serial_console_config *con_info;
+ const struct omap_uart_config *uart_info;
+ static char speed[11], *opt = NULL;
+ int line, i, uart_idx;
+
+ uart_info = omap_get_config(OMAP_TAG_UART, struct omap_uart_config);
+ con_info = omap_get_config(OMAP_TAG_SERIAL_CONSOLE,
+ struct omap_serial_console_config);
+ if (uart_info == NULL || con_info == NULL)
+ return 0;
+
+ if (con_info->console_uart == 0)
+ return 0;
+
+ if (con_info->console_speed) {
+ snprintf(speed, sizeof(speed), "%u", con_info->console_speed);
+ opt = speed;
+ }
- if (info->console_speed) {
- snprintf(speed, sizeof(speed), "%u", info->console_speed);
- opt = speed;
- }
- return add_preferred_console("ttyS", info->console_uart - 1, opt);
+ uart_idx = con_info->console_uart - 1;
+ if (uart_idx >= OMAP_MAX_NR_PORTS) {
+ printk(KERN_INFO "Console: external UART#%d. "
+ "Not adding it as console this time.\n",
+ uart_idx + 1);
+ return 0;
+ }
+ if (!(uart_info->enabled_uarts & (1 << uart_idx))) {
+ printk(KERN_ERR "Console: Selected UART#%d is "
+ "not enabled for this platform\n",
+ uart_idx + 1);
+ return -1;
+ }
+ line = 0;
+ for (i = 0; i < uart_idx; i++) {
+ if (uart_info->enabled_uarts & (1 << i))
+ line++;
}
- return 0;
+ return add_preferred_console("ttyS", line, opt);
}
console_initcall(omap_add_serial_console);
diff --git a/arch/arm/plat-omap/devices.c b/arch/arm/plat-omap/devices.c
new file mode 100644
index 000000000000..9dcce904b608
--- /dev/null
+++ b/arch/arm/plat-omap/devices.c
@@ -0,0 +1,381 @@
+/*
+ * linux/arch/arm/plat-omap/devices.c
+ *
+ * Common platform device setup/initialization for OMAP1 and OMAP2
+ *
+ * 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/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/mach-types.h>
+#include <asm/mach/map.h>
+
+#include <asm/arch/tc.h>
+#include <asm/arch/board.h>
+#include <asm/arch/mux.h>
+#include <asm/arch/gpio.h>
+
+
+void omap_nop_release(struct device *dev)
+{
+ /* Nothing */
+}
+
+/*-------------------------------------------------------------------------*/
+
+#if defined(CONFIG_I2C_OMAP) || defined(CONFIG_I2C_OMAP_MODULE)
+
+#define OMAP1_I2C_BASE 0xfffb3800
+#define OMAP2_I2C_BASE1 0x48070000
+#define OMAP_I2C_SIZE 0x3f
+#define OMAP1_I2C_INT INT_I2C
+#define OMAP2_I2C_INT1 56
+
+static struct resource i2c_resources1[] = {
+ {
+ .start = 0,
+ .end = 0,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = 0,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+/* DMA not used; works around erratum writing to non-empty i2c fifo */
+
+static struct platform_device omap_i2c_device1 = {
+ .name = "i2c_omap",
+ .id = 1,
+ .dev = {
+ .release = omap_nop_release,
+ },
+ .num_resources = ARRAY_SIZE(i2c_resources1),
+ .resource = i2c_resources1,
+};
+
+/* See also arch/arm/mach-omap2/devices.c for second I2C on 24xx */
+static void omap_init_i2c(void)
+{
+ if (cpu_is_omap24xx()) {
+ i2c_resources1[0].start = OMAP2_I2C_BASE1;
+ i2c_resources1[0].end = OMAP2_I2C_BASE1 + OMAP_I2C_SIZE;
+ i2c_resources1[1].start = OMAP2_I2C_INT1;
+ } else {
+ i2c_resources1[0].start = OMAP1_I2C_BASE;
+ i2c_resources1[0].end = OMAP1_I2C_BASE + OMAP_I2C_SIZE;
+ i2c_resources1[1].start = OMAP1_I2C_INT;
+ }
+
+ /* FIXME define and use a boot tag, in case of boards that
+ * either don't wire up I2C, or chips that mux it differently...
+ * it can include clocking and address info, maybe more.
+ */
+ if (cpu_is_omap24xx()) {
+ omap_cfg_reg(M19_24XX_I2C1_SCL);
+ omap_cfg_reg(L15_24XX_I2C1_SDA);
+ } else {
+ omap_cfg_reg(I2C_SCL);
+ omap_cfg_reg(I2C_SDA);
+ }
+
+ (void) platform_device_register(&omap_i2c_device1);
+}
+
+#else
+static inline void omap_init_i2c(void) {}
+#endif
+
+/*-------------------------------------------------------------------------*/
+
+#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE)
+
+#ifdef CONFIG_ARCH_OMAP24XX
+#define OMAP_MMC1_BASE 0x4809c000
+#define OMAP_MMC1_INT 83
+#else
+#define OMAP_MMC1_BASE 0xfffb7800
+#define OMAP_MMC1_INT INT_MMC
+#endif
+#define OMAP_MMC2_BASE 0xfffb7c00 /* omap16xx only */
+
+static struct omap_mmc_conf mmc1_conf;
+
+static u64 mmc1_dmamask = 0xffffffff;
+
+static struct resource mmc1_resources[] = {
+ {
+ .start = IO_ADDRESS(OMAP_MMC1_BASE),
+ .end = IO_ADDRESS(OMAP_MMC1_BASE) + 0x7f,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = OMAP_MMC1_INT,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device mmc_omap_device1 = {
+ .name = "mmci-omap",
+ .id = 1,
+ .dev = {
+ .release = omap_nop_release,
+ .dma_mask = &mmc1_dmamask,
+ .platform_data = &mmc1_conf,
+ },
+ .num_resources = ARRAY_SIZE(mmc1_resources),
+ .resource = mmc1_resources,
+};
+
+#ifdef CONFIG_ARCH_OMAP16XX
+
+static struct omap_mmc_conf mmc2_conf;
+
+static u64 mmc2_dmamask = 0xffffffff;
+
+static struct resource mmc2_resources[] = {
+ {
+ .start = IO_ADDRESS(OMAP_MMC2_BASE),
+ .end = IO_ADDRESS(OMAP_MMC2_BASE) + 0x7f,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = INT_1610_MMC2,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device mmc_omap_device2 = {
+ .name = "mmci-omap",
+ .id = 2,
+ .dev = {
+ .release = omap_nop_release,
+ .dma_mask = &mmc2_dmamask,
+ .platform_data = &mmc2_conf,
+ },
+ .num_resources = ARRAY_SIZE(mmc2_resources),
+ .resource = mmc2_resources,
+};
+#endif
+
+static void __init omap_init_mmc(void)
+{
+ const struct omap_mmc_config *mmc_conf;
+ const struct omap_mmc_conf *mmc;
+
+ /* NOTE: assumes MMC was never (wrongly) enabled */
+ mmc_conf = omap_get_config(OMAP_TAG_MMC, struct omap_mmc_config);
+ if (!mmc_conf)
+ return;
+
+ /* block 1 is always available and has just one pinout option */
+ mmc = &mmc_conf->mmc[0];
+ if (mmc->enabled) {
+ if (!cpu_is_omap24xx()) {
+ omap_cfg_reg(MMC_CMD);
+ omap_cfg_reg(MMC_CLK);
+ omap_cfg_reg(MMC_DAT0);
+ if (cpu_is_omap1710()) {
+ omap_cfg_reg(M15_1710_MMC_CLKI);
+ omap_cfg_reg(P19_1710_MMC_CMDDIR);
+ omap_cfg_reg(P20_1710_MMC_DATDIR0);
+ }
+ }
+ if (mmc->wire4) {
+ if (!cpu_is_omap24xx()) {
+ omap_cfg_reg(MMC_DAT1);
+ /* NOTE: DAT2 can be on W10 (here) or M15 */
+ if (!mmc->nomux)
+ omap_cfg_reg(MMC_DAT2);
+ omap_cfg_reg(MMC_DAT3);
+ }
+ }
+ mmc1_conf = *mmc;
+ (void) platform_device_register(&mmc_omap_device1);
+ }
+
+#ifdef CONFIG_ARCH_OMAP16XX
+ /* block 2 is on newer chips, and has many pinout options */
+ mmc = &mmc_conf->mmc[1];
+ if (mmc->enabled) {
+ if (!mmc->nomux) {
+ omap_cfg_reg(Y8_1610_MMC2_CMD);
+ omap_cfg_reg(Y10_1610_MMC2_CLK);
+ omap_cfg_reg(R18_1610_MMC2_CLKIN);
+ omap_cfg_reg(W8_1610_MMC2_DAT0);
+ if (mmc->wire4) {
+ omap_cfg_reg(V8_1610_MMC2_DAT1);
+ omap_cfg_reg(W15_1610_MMC2_DAT2);
+ omap_cfg_reg(R10_1610_MMC2_DAT3);
+ }
+
+ /* These are needed for the level shifter */
+ omap_cfg_reg(V9_1610_MMC2_CMDDIR);
+ omap_cfg_reg(V5_1610_MMC2_DATDIR0);
+ omap_cfg_reg(W19_1610_MMC2_DATDIR1);
+ }
+
+ /* Feedback clock must be set on OMAP-1710 MMC2 */
+ if (cpu_is_omap1710())
+ omap_writel(omap_readl(MOD_CONF_CTRL_1) | (1 << 24),
+ MOD_CONF_CTRL_1);
+ mmc2_conf = *mmc;
+ (void) platform_device_register(&mmc_omap_device2);
+ }
+#endif
+ return;
+}
+#else
+static inline void omap_init_mmc(void) {}
+#endif
+
+#if defined(CONFIG_OMAP_WATCHDOG) || defined(CONFIG_OMAP_WATCHDOG_MODULE)
+
+#ifdef CONFIG_ARCH_OMAP24XX
+#define OMAP_WDT_BASE 0x48022000
+#else
+#define OMAP_WDT_BASE 0xfffeb000
+#endif
+
+static struct resource wdt_resources[] = {
+ {
+ .start = OMAP_WDT_BASE,
+ .end = OMAP_WDT_BASE + 0x4f,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device omap_wdt_device = {
+ .name = "omap_wdt",
+ .id = -1,
+ .dev = {
+ .release = omap_nop_release,
+ },
+ .num_resources = ARRAY_SIZE(wdt_resources),
+ .resource = wdt_resources,
+};
+
+static void omap_init_wdt(void)
+{
+ (void) platform_device_register(&omap_wdt_device);
+}
+#else
+static inline void omap_init_wdt(void) {}
+#endif
+
+/*-------------------------------------------------------------------------*/
+
+#if defined(CONFIG_OMAP_RNG) || defined(CONFIG_OMAP_RNG_MODULE)
+
+#ifdef CONFIG_ARCH_OMAP24XX
+#define OMAP_RNG_BASE 0x480A0000
+#else
+#define OMAP_RNG_BASE 0xfffe5000
+#endif
+
+static struct resource rng_resources[] = {
+ {
+ .start = OMAP_RNG_BASE,
+ .end = OMAP_RNG_BASE + 0x4f,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device omap_rng_device = {
+ .name = "omap_rng",
+ .id = -1,
+ .dev = {
+ .release = omap_nop_release,
+ },
+ .num_resources = ARRAY_SIZE(rng_resources),
+ .resource = rng_resources,
+};
+
+static void omap_init_rng(void)
+{
+ (void) platform_device_register(&omap_rng_device);
+}
+#else
+static inline void omap_init_rng(void) {}
+#endif
+
+#if defined(CONFIG_FB_OMAP) || defined(CONFIG_FB_OMAP_MODULE)
+
+static struct omap_lcd_config omap_fb_conf;
+
+static u64 omap_fb_dma_mask = ~(u32)0;
+
+static struct platform_device omap_fb_device = {
+ .name = "omapfb",
+ .id = -1,
+ .dev = {
+ .release = omap_nop_release,
+ .dma_mask = &omap_fb_dma_mask,
+ .coherent_dma_mask = ~(u32)0,
+ .platform_data = &omap_fb_conf,
+ },
+ .num_resources = 0,
+};
+
+static inline void omap_init_fb(void)
+{
+ const struct omap_lcd_config *conf;
+
+ conf = omap_get_config(OMAP_TAG_LCD, struct omap_lcd_config);
+ if (conf != NULL)
+ omap_fb_conf = *conf;
+ platform_device_register(&omap_fb_device);
+}
+
+#else
+
+static inline void omap_init_fb(void) {}
+
+#endif
+
+/*
+ * This gets called after board-specific INIT_MACHINE, and initializes most
+ * on-chip peripherals accessible on this board (except for few like USB):
+ *
+ * (a) Does any "standard config" pin muxing needed. Board-specific
+ * code will have muxed GPIO pins and done "nonstandard" setup;
+ * that code could live in the boot loader.
+ * (b) Populating board-specific platform_data with the data drivers
+ * rely on to handle wiring variations.
+ * (c) Creating platform devices as meaningful on this board and
+ * with this kernel configuration.
+ *
+ * Claiming GPIOs, and setting their direction and initial values, is the
+ * responsibility of the device drivers. So is responding to probe().
+ *
+ * Board-specific knowlege like creating devices or pin setup is to be
+ * kept out of drivers as much as possible. In particular, pin setup
+ * may be handled by the boot loader, and drivers should expect it will
+ * normally have been done by the time they're probed.
+ */
+static int __init omap_init_devices(void)
+{
+ /* please keep these calls, and their implementations above,
+ * in alphabetical order so they're easier to sort through.
+ */
+ omap_init_fb();
+ omap_init_i2c();
+ omap_init_mmc();
+ omap_init_wdt();
+ omap_init_rng();
+
+ return 0;
+}
+arch_initcall(omap_init_devices);
+
diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c
index da7b65145658..f5cc21ad0956 100644
--- a/arch/arm/plat-omap/dma.c
+++ b/arch/arm/plat-omap/dma.c
@@ -6,6 +6,8 @@
* DMA channel linking for 1610 by Samuel Ortiz <samuel.ortiz@nokia.com>
* Graphics DMA and LCD DMA graphics tranformations
* by Imre Deak <imre.deak@nokia.com>
+ * OMAP2 support Copyright (C) 2004-2005 Texas Instruments, Inc.
+ * Merged to support both OMAP1 and OMAP2 by Tony Lindgren <tony@atomide.com>
* Some functions based on earlier dma-omap.c Copyright (C) 2001 RidgeRun, Inc.
*
* Support functions for the OMAP internal DMA channels.
@@ -31,8 +33,15 @@
#include <asm/arch/tc.h>
-#define OMAP_DMA_ACTIVE 0x01
+#define DEBUG_PRINTS
+#undef DEBUG_PRINTS
+#ifdef DEBUG_PRINTS
+#define debug_printk(x) printk x
+#else
+#define debug_printk(x)
+#endif
+#define OMAP_DMA_ACTIVE 0x01
#define OMAP_DMA_CCR_EN (1 << 7)
#define OMAP_FUNC_MUX_ARM_BASE (0xfffe1000 + 0xec)
@@ -55,7 +64,7 @@ static int dma_chan_count;
static spinlock_t dma_chan_lock;
static struct omap_dma_lch dma_chan[OMAP_LOGICAL_DMA_CH_COUNT];
-const static u8 dma_irq[OMAP_LOGICAL_DMA_CH_COUNT] = {
+const static u8 omap1_dma_irq[OMAP_LOGICAL_DMA_CH_COUNT] = {
INT_DMA_CH0_6, INT_DMA_CH1_7, INT_DMA_CH2_8, INT_DMA_CH3,
INT_DMA_CH4, INT_DMA_CH5, INT_1610_DMA_CH6, INT_1610_DMA_CH7,
INT_1610_DMA_CH8, INT_1610_DMA_CH9, INT_1610_DMA_CH10,
@@ -63,6 +72,20 @@ const static u8 dma_irq[OMAP_LOGICAL_DMA_CH_COUNT] = {
INT_1610_DMA_CH14, INT_1610_DMA_CH15, INT_DMA_LCD
};
+#define REVISIT_24XX() printk(KERN_ERR "FIXME: no %s on 24xx\n", \
+ __FUNCTION__);
+
+#ifdef CONFIG_ARCH_OMAP15XX
+/* Returns 1 if the DMA module is in OMAP1510-compatible mode, 0 otherwise */
+int omap_dma_in_1510_mode(void)
+{
+ return enable_1510_mode;
+}
+#else
+#define omap_dma_in_1510_mode() 0
+#endif
+
+#ifdef CONFIG_ARCH_OMAP1
static inline int get_gdma_dev(int req)
{
u32 reg = OMAP_FUNC_MUX_ARM_BASE + ((req - 1) / 5) * 4;
@@ -82,6 +105,9 @@ static inline void set_gdma_dev(int req, int dev)
l |= (dev - 1) << shift;
omap_writel(l, reg);
}
+#else
+#define set_gdma_dev(req, dev) do {} while (0)
+#endif
static void clear_lch_regs(int lch)
{
@@ -121,38 +147,62 @@ void omap_set_dma_priority(int dst_port, int priority)
}
void omap_set_dma_transfer_params(int lch, int data_type, int elem_count,
- int frame_count, int sync_mode)
+ int frame_count, int sync_mode,
+ int dma_trigger, int src_or_dst_synch)
{
- u16 w;
+ OMAP_DMA_CSDP_REG(lch) &= ~0x03;
+ OMAP_DMA_CSDP_REG(lch) |= data_type;
- w = omap_readw(OMAP_DMA_CSDP(lch));
- w &= ~0x03;
- w |= data_type;
- omap_writew(w, OMAP_DMA_CSDP(lch));
+ if (cpu_class_is_omap1()) {
+ OMAP_DMA_CCR_REG(lch) &= ~(1 << 5);
+ if (sync_mode == OMAP_DMA_SYNC_FRAME)
+ OMAP_DMA_CCR_REG(lch) |= 1 << 5;
+
+ OMAP1_DMA_CCR2_REG(lch) &= ~(1 << 2);
+ if (sync_mode == OMAP_DMA_SYNC_BLOCK)
+ OMAP1_DMA_CCR2_REG(lch) |= 1 << 2;
+ }
+
+ if (cpu_is_omap24xx() && dma_trigger) {
+ u32 val = OMAP_DMA_CCR_REG(lch);
+
+ if (dma_trigger > 63)
+ val |= 1 << 20;
+ if (dma_trigger > 31)
+ val |= 1 << 19;
- w = omap_readw(OMAP_DMA_CCR(lch));
- w &= ~(1 << 5);
- if (sync_mode == OMAP_DMA_SYNC_FRAME)
- w |= 1 << 5;
- omap_writew(w, OMAP_DMA_CCR(lch));
+ val |= (dma_trigger & 0x1f);
- w = omap_readw(OMAP_DMA_CCR2(lch));
- w &= ~(1 << 2);
- if (sync_mode == OMAP_DMA_SYNC_BLOCK)
- w |= 1 << 2;
- omap_writew(w, OMAP_DMA_CCR2(lch));
+ if (sync_mode & OMAP_DMA_SYNC_FRAME)
+ val |= 1 << 5;
- omap_writew(elem_count, OMAP_DMA_CEN(lch));
- omap_writew(frame_count, OMAP_DMA_CFN(lch));
+ if (sync_mode & OMAP_DMA_SYNC_BLOCK)
+ val |= 1 << 18;
+ if (src_or_dst_synch)
+ val |= 1 << 24; /* source synch */
+ else
+ val &= ~(1 << 24); /* dest synch */
+
+ OMAP_DMA_CCR_REG(lch) = val;
+ }
+
+ OMAP_DMA_CEN_REG(lch) = elem_count;
+ OMAP_DMA_CFN_REG(lch) = frame_count;
}
+
void omap_set_dma_color_mode(int lch, enum omap_dma_color_mode mode, u32 color)
{
u16 w;
BUG_ON(omap_dma_in_1510_mode());
- w = omap_readw(OMAP_DMA_CCR2(lch)) & ~0x03;
+ if (cpu_is_omap24xx()) {
+ REVISIT_24XX();
+ return;
+ }
+
+ w = OMAP1_DMA_CCR2_REG(lch) & ~0x03;
switch (mode) {
case OMAP_DMA_CONSTANT_FILL:
w |= 0x01;
@@ -165,63 +215,84 @@ void omap_set_dma_color_mode(int lch, enum omap_dma_color_mode mode, u32 color)
default:
BUG();
}
- omap_writew(w, OMAP_DMA_CCR2(lch));
+ OMAP1_DMA_CCR2_REG(lch) = w;
- w = omap_readw(OMAP_DMA_LCH_CTRL(lch)) & ~0x0f;
+ w = OMAP1_DMA_LCH_CTRL_REG(lch) & ~0x0f;
/* Default is channel type 2D */
if (mode) {
- omap_writew((u16)color, OMAP_DMA_COLOR_L(lch));
- omap_writew((u16)(color >> 16), OMAP_DMA_COLOR_U(lch));
+ OMAP1_DMA_COLOR_L_REG(lch) = (u16)color;
+ OMAP1_DMA_COLOR_U_REG(lch) = (u16)(color >> 16);
w |= 1; /* Channel type G */
}
- omap_writew(w, OMAP_DMA_LCH_CTRL(lch));
+ OMAP1_DMA_LCH_CTRL_REG(lch) = w;
}
-
+/* Note that src_port is only for omap1 */
void omap_set_dma_src_params(int lch, int src_port, int src_amode,
- unsigned long src_start)
+ unsigned long src_start,
+ int src_ei, int src_fi)
{
- u16 w;
+ if (cpu_class_is_omap1()) {
+ OMAP_DMA_CSDP_REG(lch) &= ~(0x1f << 2);
+ OMAP_DMA_CSDP_REG(lch) |= src_port << 2;
+ }
+
+ OMAP_DMA_CCR_REG(lch) &= ~(0x03 << 12);
+ OMAP_DMA_CCR_REG(lch) |= src_amode << 12;
+
+ if (cpu_class_is_omap1()) {
+ OMAP1_DMA_CSSA_U_REG(lch) = src_start >> 16;
+ OMAP1_DMA_CSSA_L_REG(lch) = src_start;
+ }
- w = omap_readw(OMAP_DMA_CSDP(lch));
- w &= ~(0x1f << 2);
- w |= src_port << 2;
- omap_writew(w, OMAP_DMA_CSDP(lch));
+ if (cpu_is_omap24xx())
+ OMAP2_DMA_CSSA_REG(lch) = src_start;
- w = omap_readw(OMAP_DMA_CCR(lch));
- w &= ~(0x03 << 12);
- w |= src_amode << 12;
- omap_writew(w, OMAP_DMA_CCR(lch));
+ OMAP_DMA_CSEI_REG(lch) = src_ei;
+ OMAP_DMA_CSFI_REG(lch) = src_fi;
+}
- omap_writew(src_start >> 16, OMAP_DMA_CSSA_U(lch));
- omap_writew(src_start, OMAP_DMA_CSSA_L(lch));
+void omap_set_dma_params(int lch, struct omap_dma_channel_params * params)
+{
+ omap_set_dma_transfer_params(lch, params->data_type,
+ params->elem_count, params->frame_count,
+ params->sync_mode, params->trigger,
+ params->src_or_dst_synch);
+ omap_set_dma_src_params(lch, params->src_port,
+ params->src_amode, params->src_start,
+ params->src_ei, params->src_fi);
+
+ omap_set_dma_dest_params(lch, params->dst_port,
+ params->dst_amode, params->dst_start,
+ params->dst_ei, params->dst_fi);
}
void omap_set_dma_src_index(int lch, int eidx, int fidx)
{
- omap_writew(eidx, OMAP_DMA_CSEI(lch));
- omap_writew(fidx, OMAP_DMA_CSFI(lch));
+ if (cpu_is_omap24xx()) {
+ REVISIT_24XX();
+ return;
+ }
+ OMAP_DMA_CSEI_REG(lch) = eidx;
+ OMAP_DMA_CSFI_REG(lch) = fidx;
}
void omap_set_dma_src_data_pack(int lch, int enable)
{
- u16 w;
-
- w = omap_readw(OMAP_DMA_CSDP(lch)) & ~(1 << 6);
- w |= enable ? (1 << 6) : 0;
- omap_writew(w, OMAP_DMA_CSDP(lch));
+ OMAP_DMA_CSDP_REG(lch) &= ~(1 << 6);
+ if (enable)
+ OMAP_DMA_CSDP_REG(lch) |= (1 << 6);
}
void omap_set_dma_src_burst_mode(int lch, enum omap_dma_burst_mode burst_mode)
{
- u16 w;
+ OMAP_DMA_CSDP_REG(lch) &= ~(0x03 << 7);
- w = omap_readw(OMAP_DMA_CSDP(lch)) & ~(0x03 << 7);
switch (burst_mode) {
case OMAP_DMA_DATA_BURST_DIS:
break;
case OMAP_DMA_DATA_BURST_4:
- w |= (0x01 << 7);
+ OMAP_DMA_CSDP_REG(lch) |= (0x02 << 7);
break;
case OMAP_DMA_DATA_BURST_8:
/* not supported by current hardware
@@ -231,110 +302,283 @@ void omap_set_dma_src_burst_mode(int lch, enum omap_dma_burst_mode burst_mode)
default:
BUG();
}
- omap_writew(w, OMAP_DMA_CSDP(lch));
}
+/* Note that dest_port is only for OMAP1 */
void omap_set_dma_dest_params(int lch, int dest_port, int dest_amode,
- unsigned long dest_start)
+ unsigned long dest_start,
+ int dst_ei, int dst_fi)
{
- u16 w;
+ if (cpu_class_is_omap1()) {
+ OMAP_DMA_CSDP_REG(lch) &= ~(0x1f << 9);
+ OMAP_DMA_CSDP_REG(lch) |= dest_port << 9;
+ }
- w = omap_readw(OMAP_DMA_CSDP(lch));
- w &= ~(0x1f << 9);
- w |= dest_port << 9;
- omap_writew(w, OMAP_DMA_CSDP(lch));
+ OMAP_DMA_CCR_REG(lch) &= ~(0x03 << 14);
+ OMAP_DMA_CCR_REG(lch) |= dest_amode << 14;
+
+ if (cpu_class_is_omap1()) {
+ OMAP1_DMA_CDSA_U_REG(lch) = dest_start >> 16;
+ OMAP1_DMA_CDSA_L_REG(lch) = dest_start;
+ }
- w = omap_readw(OMAP_DMA_CCR(lch));
- w &= ~(0x03 << 14);
- w |= dest_amode << 14;
- omap_writew(w, OMAP_DMA_CCR(lch));
+ if (cpu_is_omap24xx())
+ OMAP2_DMA_CDSA_REG(lch) = dest_start;
- omap_writew(dest_start >> 16, OMAP_DMA_CDSA_U(lch));
- omap_writew(dest_start, OMAP_DMA_CDSA_L(lch));
+ OMAP_DMA_CDEI_REG(lch) = dst_ei;
+ OMAP_DMA_CDFI_REG(lch) = dst_fi;
}
void omap_set_dma_dest_index(int lch, int eidx, int fidx)
{
- omap_writew(eidx, OMAP_DMA_CDEI(lch));
- omap_writew(fidx, OMAP_DMA_CDFI(lch));
+ if (cpu_is_omap24xx()) {
+ REVISIT_24XX();
+ return;
+ }
+ OMAP_DMA_CDEI_REG(lch) = eidx;
+ OMAP_DMA_CDFI_REG(lch) = fidx;
}
void omap_set_dma_dest_data_pack(int lch, int enable)
{
- u16 w;
-
- w = omap_readw(OMAP_DMA_CSDP(lch)) & ~(1 << 13);
- w |= enable ? (1 << 13) : 0;
- omap_writew(w, OMAP_DMA_CSDP(lch));
+ OMAP_DMA_CSDP_REG(lch) &= ~(1 << 13);
+ if (enable)
+ OMAP_DMA_CSDP_REG(lch) |= 1 << 13;
}
void omap_set_dma_dest_burst_mode(int lch, enum omap_dma_burst_mode burst_mode)
{
- u16 w;
+ OMAP_DMA_CSDP_REG(lch) &= ~(0x03 << 14);
- w = omap_readw(OMAP_DMA_CSDP(lch)) & ~(0x03 << 14);
switch (burst_mode) {
case OMAP_DMA_DATA_BURST_DIS:
break;
case OMAP_DMA_DATA_BURST_4:
- w |= (0x01 << 14);
+ OMAP_DMA_CSDP_REG(lch) |= (0x02 << 14);
break;
case OMAP_DMA_DATA_BURST_8:
- w |= (0x03 << 14);
+ OMAP_DMA_CSDP_REG(lch) |= (0x03 << 14);
break;
default:
printk(KERN_ERR "Invalid DMA burst mode\n");
BUG();
return;
}
- omap_writew(w, OMAP_DMA_CSDP(lch));
}
-static inline void init_intr(int lch)
+static inline void omap_enable_channel_irq(int lch)
{
- u16 w;
+ u32 status;
/* Read CSR to make sure it's cleared. */
- w = omap_readw(OMAP_DMA_CSR(lch));
+ status = OMAP_DMA_CSR_REG(lch);
+
/* Enable some nice interrupts. */
- omap_writew(dma_chan[lch].enabled_irqs, OMAP_DMA_CICR(lch));
+ OMAP_DMA_CICR_REG(lch) = dma_chan[lch].enabled_irqs;
+
dma_chan[lch].flags |= OMAP_DMA_ACTIVE;
}
-static inline void enable_lnk(int lch)
+static void omap_disable_channel_irq(int lch)
{
- u16 w;
+ if (cpu_is_omap24xx())
+ OMAP_DMA_CICR_REG(lch) = 0;
+}
+
+void omap_enable_dma_irq(int lch, u16 bits)
+{
+ dma_chan[lch].enabled_irqs |= bits;
+}
- /* Clear the STOP_LNK bits */
- w = omap_readw(OMAP_DMA_CLNK_CTRL(lch));
- w &= ~(1 << 14);
- omap_writew(w, OMAP_DMA_CLNK_CTRL(lch));
+void omap_disable_dma_irq(int lch, u16 bits)
+{
+ dma_chan[lch].enabled_irqs &= ~bits;
+}
+
+static inline void enable_lnk(int lch)
+{
+ if (cpu_class_is_omap1())
+ OMAP_DMA_CLNK_CTRL_REG(lch) &= ~(1 << 14);
- /* And set the ENABLE_LNK bits */
+ /* Set the ENABLE_LNK bits */
if (dma_chan[lch].next_lch != -1)
- omap_writew(dma_chan[lch].next_lch | (1 << 15),
- OMAP_DMA_CLNK_CTRL(lch));
+ OMAP_DMA_CLNK_CTRL_REG(lch) =
+ dma_chan[lch].next_lch | (1 << 15);
}
static inline void disable_lnk(int lch)
{
- u16 w;
-
/* Disable interrupts */
- omap_writew(0, OMAP_DMA_CICR(lch));
+ if (cpu_class_is_omap1()) {
+ OMAP_DMA_CICR_REG(lch) = 0;
+ /* Set the STOP_LNK bit */
+ OMAP_DMA_CLNK_CTRL_REG(lch) |= 1 << 14;
+ }
- /* Set the STOP_LNK bit */
- w = omap_readw(OMAP_DMA_CLNK_CTRL(lch));
- w |= (1 << 14);
- w = omap_writew(w, OMAP_DMA_CLNK_CTRL(lch));
+ if (cpu_is_omap24xx()) {
+ omap_disable_channel_irq(lch);
+ /* Clear the ENABLE_LNK bit */
+ OMAP_DMA_CLNK_CTRL_REG(lch) &= ~(1 << 15);
+ }
dma_chan[lch].flags &= ~OMAP_DMA_ACTIVE;
}
-void omap_start_dma(int lch)
+static inline void omap2_enable_irq_lch(int lch)
{
- u16 w;
+ u32 val;
+
+ if (!cpu_is_omap24xx())
+ return;
+
+ val = omap_readl(OMAP_DMA4_IRQENABLE_L0);
+ val |= 1 << lch;
+ omap_writel(val, OMAP_DMA4_IRQENABLE_L0);
+}
+
+int omap_request_dma(int dev_id, const char *dev_name,
+ void (* callback)(int lch, u16 ch_status, void *data),
+ void *data, int *dma_ch_out)
+{
+ int ch, free_ch = -1;
+ unsigned long flags;
+ struct omap_dma_lch *chan;
+
+ spin_lock_irqsave(&dma_chan_lock, flags);
+ for (ch = 0; ch < dma_chan_count; ch++) {
+ if (free_ch == -1 && dma_chan[ch].dev_id == -1) {
+ free_ch = ch;
+ if (dev_id == 0)
+ break;
+ }
+ }
+ if (free_ch == -1) {
+ spin_unlock_irqrestore(&dma_chan_lock, flags);
+ return -EBUSY;
+ }
+ chan = dma_chan + free_ch;
+ chan->dev_id = dev_id;
+
+ if (cpu_class_is_omap1())
+ clear_lch_regs(free_ch);
+ if (cpu_is_omap24xx())
+ omap_clear_dma(free_ch);
+
+ spin_unlock_irqrestore(&dma_chan_lock, flags);
+
+ chan->dev_name = dev_name;
+ chan->callback = callback;
+ chan->data = data;
+ chan->enabled_irqs = OMAP_DMA_TOUT_IRQ | OMAP_DMA_DROP_IRQ |
+ OMAP_DMA_BLOCK_IRQ;
+
+ if (cpu_is_omap24xx())
+ chan->enabled_irqs |= OMAP2_DMA_TRANS_ERR_IRQ;
+
+ if (cpu_is_omap16xx()) {
+ /* If the sync device is set, configure it dynamically. */
+ if (dev_id != 0) {
+ set_gdma_dev(free_ch + 1, dev_id);
+ dev_id = free_ch + 1;
+ }
+ /* Disable the 1510 compatibility mode and set the sync device
+ * id. */
+ OMAP_DMA_CCR_REG(free_ch) = dev_id | (1 << 10);
+ } else if (cpu_is_omap730() || cpu_is_omap15xx()) {
+ OMAP_DMA_CCR_REG(free_ch) = dev_id;
+ }
+
+ if (cpu_is_omap24xx()) {
+ omap2_enable_irq_lch(free_ch);
+
+ omap_enable_channel_irq(free_ch);
+ /* Clear the CSR register and IRQ status register */
+ OMAP_DMA_CSR_REG(free_ch) = 0x0;
+ omap_writel(~0x0, OMAP_DMA4_IRQSTATUS_L0);
+ }
+
+ *dma_ch_out = free_ch;
+
+ return 0;
+}
+
+void omap_free_dma(int lch)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&dma_chan_lock, flags);
+ if (dma_chan[lch].dev_id == -1) {
+ printk("omap_dma: trying to free nonallocated DMA channel %d\n",
+ lch);
+ spin_unlock_irqrestore(&dma_chan_lock, flags);
+ return;
+ }
+ dma_chan[lch].dev_id = -1;
+ dma_chan[lch].next_lch = -1;
+ dma_chan[lch].callback = NULL;
+ spin_unlock_irqrestore(&dma_chan_lock, flags);
+
+ if (cpu_class_is_omap1()) {
+ /* Disable all DMA interrupts for the channel. */
+ OMAP_DMA_CICR_REG(lch) = 0;
+ /* Make sure the DMA transfer is stopped. */
+ OMAP_DMA_CCR_REG(lch) = 0;
+ }
+
+ if (cpu_is_omap24xx()) {
+ u32 val;
+ /* Disable interrupts */
+ val = omap_readl(OMAP_DMA4_IRQENABLE_L0);
+ val &= ~(1 << lch);
+ omap_writel(val, OMAP_DMA4_IRQENABLE_L0);
+
+ /* Clear the CSR register and IRQ status register */
+ OMAP_DMA_CSR_REG(lch) = 0x0;
+
+ val = omap_readl(OMAP_DMA4_IRQSTATUS_L0);
+ val |= 1 << lch;
+ omap_writel(val, OMAP_DMA4_IRQSTATUS_L0);
+
+ /* Disable all DMA interrupts for the channel. */
+ OMAP_DMA_CICR_REG(lch) = 0;
+
+ /* Make sure the DMA transfer is stopped. */
+ OMAP_DMA_CCR_REG(lch) = 0;
+ omap_clear_dma(lch);
+ }
+}
+
+/*
+ * Clears any DMA state so the DMA engine is ready to restart with new buffers
+ * through omap_start_dma(). Any buffers in flight are discarded.
+ */
+void omap_clear_dma(int lch)
+{
+ unsigned long flags;
+
+ local_irq_save(flags);
+
+ if (cpu_class_is_omap1()) {
+ int status;
+ OMAP_DMA_CCR_REG(lch) &= ~OMAP_DMA_CCR_EN;
+
+ /* Clear pending interrupts */
+ status = OMAP_DMA_CSR_REG(lch);
+ }
+
+ if (cpu_is_omap24xx()) {
+ int i;
+ u32 lch_base = OMAP24XX_DMA_BASE + lch * 0x60 + 0x80;
+ for (i = 0; i < 0x44; i += 4)
+ omap_writel(0, lch_base + i);
+ }
+
+ local_irq_restore(flags);
+}
+
+void omap_start_dma(int lch)
+{
if (!omap_dma_in_1510_mode() && dma_chan[lch].next_lch != -1) {
int next_lch, cur_lch;
char dma_chan_link_map[OMAP_LOGICAL_DMA_CH_COUNT];
@@ -348,31 +592,37 @@ void omap_start_dma(int lch)
do {
next_lch = dma_chan[cur_lch].next_lch;
- /* The loop case: we've been here already */
+ /* The loop case: we've been here already */
if (dma_chan_link_map[cur_lch])
break;
/* Mark the current channel */
dma_chan_link_map[cur_lch] = 1;
enable_lnk(cur_lch);
- init_intr(cur_lch);
+ omap_enable_channel_irq(cur_lch);
cur_lch = next_lch;
} while (next_lch != -1);
+ } else if (cpu_is_omap24xx()) {
+ /* Errata: Need to write lch even if not using chaining */
+ OMAP_DMA_CLNK_CTRL_REG(lch) = lch;
}
- init_intr(lch);
+ omap_enable_channel_irq(lch);
+
+ /* Errata: On ES2.0 BUFFERING disable must be set.
+ * This will always fail on ES1.0 */
+ if (cpu_is_omap24xx()) {
+ OMAP_DMA_CCR_REG(lch) |= OMAP_DMA_CCR_EN;
+ }
+
+ OMAP_DMA_CCR_REG(lch) |= OMAP_DMA_CCR_EN;
- w = omap_readw(OMAP_DMA_CCR(lch));
- w |= OMAP_DMA_CCR_EN;
- omap_writew(w, OMAP_DMA_CCR(lch));
dma_chan[lch].flags |= OMAP_DMA_ACTIVE;
}
void omap_stop_dma(int lch)
{
- u16 w;
-
if (!omap_dma_in_1510_mode() && dma_chan[lch].next_lch != -1) {
int next_lch, cur_lch = lch;
char dma_chan_link_map[OMAP_LOGICAL_DMA_CH_COUNT];
@@ -393,146 +643,83 @@ void omap_stop_dma(int lch)
return;
}
+
/* Disable all interrupts on the channel */
- omap_writew(0, OMAP_DMA_CICR(lch));
+ if (cpu_class_is_omap1())
+ OMAP_DMA_CICR_REG(lch) = 0;
- w = omap_readw(OMAP_DMA_CCR(lch));
- w &= ~OMAP_DMA_CCR_EN;
- omap_writew(w, OMAP_DMA_CCR(lch));
+ OMAP_DMA_CCR_REG(lch) &= ~OMAP_DMA_CCR_EN;
dma_chan[lch].flags &= ~OMAP_DMA_ACTIVE;
}
-void omap_enable_dma_irq(int lch, u16 bits)
+/*
+ * Returns current physical source address for the given DMA channel.
+ * If the channel is running the caller must disable interrupts prior calling
+ * this function and process the returned value before re-enabling interrupt to
+ * prevent races with the interrupt handler. Note that in continuous mode there
+ * is a chance for CSSA_L register overflow inbetween the two reads resulting
+ * in incorrect return value.
+ */
+dma_addr_t omap_get_dma_src_pos(int lch)
{
- dma_chan[lch].enabled_irqs |= bits;
-}
+ dma_addr_t offset;
-void omap_disable_dma_irq(int lch, u16 bits)
-{
- dma_chan[lch].enabled_irqs &= ~bits;
-}
+ if (cpu_class_is_omap1())
+ offset = (dma_addr_t) (OMAP1_DMA_CSSA_L_REG(lch) |
+ (OMAP1_DMA_CSSA_U_REG(lch) << 16));
-static int dma_handle_ch(int ch)
-{
- u16 csr;
+ if (cpu_is_omap24xx())
+ offset = OMAP_DMA_CSAC_REG(lch);
- if (enable_1510_mode && ch >= 6) {
- csr = dma_chan[ch].saved_csr;
- dma_chan[ch].saved_csr = 0;
- } else
- csr = omap_readw(OMAP_DMA_CSR(ch));
- if (enable_1510_mode && ch <= 2 && (csr >> 7) != 0) {
- dma_chan[ch + 6].saved_csr = csr >> 7;
- csr &= 0x7f;
- }
- if ((csr & 0x3f) == 0)
- return 0;
- if (unlikely(dma_chan[ch].dev_id == -1)) {
- printk(KERN_WARNING "Spurious interrupt from DMA channel %d (CSR %04x)\n",
- ch, csr);
- return 0;
- }
- if (unlikely(csr & OMAP_DMA_TOUT_IRQ))
- printk(KERN_WARNING "DMA timeout with device %d\n", dma_chan[ch].dev_id);
- if (unlikely(csr & OMAP_DMA_DROP_IRQ))
- printk(KERN_WARNING "DMA synchronization event drop occurred with device %d\n",
- dma_chan[ch].dev_id);
- if (likely(csr & OMAP_DMA_BLOCK_IRQ))
- dma_chan[ch].flags &= ~OMAP_DMA_ACTIVE;
- if (likely(dma_chan[ch].callback != NULL))
- dma_chan[ch].callback(ch, csr, dma_chan[ch].data);
- return 1;
+ return offset;
}
-static irqreturn_t dma_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
+/*
+ * Returns current physical destination address for the given DMA channel.
+ * If the channel is running the caller must disable interrupts prior calling
+ * this function and process the returned value before re-enabling interrupt to
+ * prevent races with the interrupt handler. Note that in continuous mode there
+ * is a chance for CDSA_L register overflow inbetween the two reads resulting
+ * in incorrect return value.
+ */
+dma_addr_t omap_get_dma_dst_pos(int lch)
{
- int ch = ((int) dev_id) - 1;
- int handled = 0;
+ dma_addr_t offset;
- for (;;) {
- int handled_now = 0;
+ if (cpu_class_is_omap1())
+ offset = (dma_addr_t) (OMAP1_DMA_CDSA_L_REG(lch) |
+ (OMAP1_DMA_CDSA_U_REG(lch) << 16));
- handled_now += dma_handle_ch(ch);
- if (enable_1510_mode && dma_chan[ch + 6].saved_csr)
- handled_now += dma_handle_ch(ch + 6);
- if (!handled_now)
- break;
- handled += handled_now;
- }
+ if (cpu_is_omap24xx())
+ offset = OMAP2_DMA_CDSA_REG(lch);
- return handled ? IRQ_HANDLED : IRQ_NONE;
+ return offset;
}
-int omap_request_dma(int dev_id, const char *dev_name,
- void (* callback)(int lch, u16 ch_status, void *data),
- void *data, int *dma_ch_out)
+/*
+ * Returns current source transfer counting for the given DMA channel.
+ * Can be used to monitor the progress of a transfer inside a block.
+ * It must be called with disabled interrupts.
+ */
+int omap_get_dma_src_addr_counter(int lch)
{
- int ch, free_ch = -1;
- unsigned long flags;
- struct omap_dma_lch *chan;
-
- spin_lock_irqsave(&dma_chan_lock, flags);
- for (ch = 0; ch < dma_chan_count; ch++) {
- if (free_ch == -1 && dma_chan[ch].dev_id == -1) {
- free_ch = ch;
- if (dev_id == 0)
- break;
- }
- }
- if (free_ch == -1) {
- spin_unlock_irqrestore(&dma_chan_lock, flags);
- return -EBUSY;
- }
- chan = dma_chan + free_ch;
- chan->dev_id = dev_id;
- clear_lch_regs(free_ch);
- spin_unlock_irqrestore(&dma_chan_lock, flags);
-
- chan->dev_id = dev_id;
- chan->dev_name = dev_name;
- chan->callback = callback;
- chan->data = data;
- chan->enabled_irqs = OMAP_DMA_TOUT_IRQ | OMAP_DMA_DROP_IRQ | OMAP_DMA_BLOCK_IRQ;
-
- if (cpu_is_omap16xx()) {
- /* If the sync device is set, configure it dynamically. */
- if (dev_id != 0) {
- set_gdma_dev(free_ch + 1, dev_id);
- dev_id = free_ch + 1;
- }
- /* Disable the 1510 compatibility mode and set the sync device
- * id. */
- omap_writew(dev_id | (1 << 10), OMAP_DMA_CCR(free_ch));
- } else {
- omap_writew(dev_id, OMAP_DMA_CCR(free_ch));
- }
- *dma_ch_out = free_ch;
-
- return 0;
+ return (dma_addr_t) OMAP_DMA_CSAC_REG(lch);
}
-void omap_free_dma(int ch)
+int omap_dma_running(void)
{
- unsigned long flags;
+ int lch;
- spin_lock_irqsave(&dma_chan_lock, flags);
- if (dma_chan[ch].dev_id == -1) {
- printk("omap_dma: trying to free nonallocated DMA channel %d\n", ch);
- spin_unlock_irqrestore(&dma_chan_lock, flags);
- return;
- }
- dma_chan[ch].dev_id = -1;
- spin_unlock_irqrestore(&dma_chan_lock, flags);
+ /* Check if LCD DMA is running */
+ if (cpu_is_omap16xx())
+ if (omap_readw(OMAP1610_DMA_LCD_CCR) & OMAP_DMA_CCR_EN)
+ return 1;
- /* Disable all DMA interrupts for the channel. */
- omap_writew(0, OMAP_DMA_CICR(ch));
- /* Make sure the DMA transfer is stopped. */
- omap_writew(0, OMAP_DMA_CCR(ch));
-}
+ for (lch = 0; lch < dma_chan_count; lch++)
+ if (OMAP_DMA_CCR_REG(lch) & OMAP_DMA_CCR_EN)
+ return 1;
-int omap_dma_in_1510_mode(void)
-{
- return enable_1510_mode;
+ return 0;
}
/*
@@ -550,7 +737,8 @@ void omap_dma_link_lch (int lch_head, int lch_queue)
if ((dma_chan[lch_head].dev_id == -1) ||
(dma_chan[lch_queue].dev_id == -1)) {
- printk(KERN_ERR "omap_dma: trying to link non requested channels\n");
+ printk(KERN_ERR "omap_dma: trying to link "
+ "non requested channels\n");
dump_stack();
}
@@ -570,20 +758,149 @@ void omap_dma_unlink_lch (int lch_head, int lch_queue)
if (dma_chan[lch_head].next_lch != lch_queue ||
dma_chan[lch_head].next_lch == -1) {
- printk(KERN_ERR "omap_dma: trying to unlink non linked channels\n");
+ printk(KERN_ERR "omap_dma: trying to unlink "
+ "non linked channels\n");
dump_stack();
}
if ((dma_chan[lch_head].flags & OMAP_DMA_ACTIVE) ||
(dma_chan[lch_head].flags & OMAP_DMA_ACTIVE)) {
- printk(KERN_ERR "omap_dma: You need to stop the DMA channels before unlinking\n");
+ printk(KERN_ERR "omap_dma: You need to stop the DMA channels "
+ "before unlinking\n");
dump_stack();
}
dma_chan[lch_head].next_lch = -1;
}
+/*----------------------------------------------------------------------------*/
+
+#ifdef CONFIG_ARCH_OMAP1
+
+static int omap1_dma_handle_ch(int ch)
+{
+ u16 csr;
+
+ if (enable_1510_mode && ch >= 6) {
+ csr = dma_chan[ch].saved_csr;
+ dma_chan[ch].saved_csr = 0;
+ } else
+ csr = OMAP_DMA_CSR_REG(ch);
+ if (enable_1510_mode && ch <= 2 && (csr >> 7) != 0) {
+ dma_chan[ch + 6].saved_csr = csr >> 7;
+ csr &= 0x7f;
+ }
+ if ((csr & 0x3f) == 0)
+ return 0;
+ if (unlikely(dma_chan[ch].dev_id == -1)) {
+ printk(KERN_WARNING "Spurious interrupt from DMA channel "
+ "%d (CSR %04x)\n", ch, csr);
+ return 0;
+ }
+ if (unlikely(csr & OMAP_DMA_TOUT_IRQ))
+ printk(KERN_WARNING "DMA timeout with device %d\n",
+ dma_chan[ch].dev_id);
+ if (unlikely(csr & OMAP_DMA_DROP_IRQ))
+ printk(KERN_WARNING "DMA synchronization event drop occurred "
+ "with device %d\n", dma_chan[ch].dev_id);
+ if (likely(csr & OMAP_DMA_BLOCK_IRQ))
+ dma_chan[ch].flags &= ~OMAP_DMA_ACTIVE;
+ if (likely(dma_chan[ch].callback != NULL))
+ dma_chan[ch].callback(ch, csr, dma_chan[ch].data);
+ return 1;
+}
+
+static irqreturn_t omap1_dma_irq_handler(int irq, void *dev_id,
+ struct pt_regs *regs)
+{
+ int ch = ((int) dev_id) - 1;
+ int handled = 0;
+
+ for (;;) {
+ int handled_now = 0;
+
+ handled_now += omap1_dma_handle_ch(ch);
+ if (enable_1510_mode && dma_chan[ch + 6].saved_csr)
+ handled_now += omap1_dma_handle_ch(ch + 6);
+ if (!handled_now)
+ break;
+ handled += handled_now;
+ }
+
+ return handled ? IRQ_HANDLED : IRQ_NONE;
+}
+
+#else
+#define omap1_dma_irq_handler NULL
+#endif
+
+#ifdef CONFIG_ARCH_OMAP2
+
+static int omap2_dma_handle_ch(int ch)
+{
+ u32 status = OMAP_DMA_CSR_REG(ch);
+ u32 val;
+
+ if (!status)
+ return 0;
+ if (unlikely(dma_chan[ch].dev_id == -1))
+ return 0;
+ /* REVISIT: According to 24xx TRM, there's no TOUT_IE */
+ if (unlikely(status & OMAP_DMA_TOUT_IRQ))
+ printk(KERN_INFO "DMA timeout with device %d\n",
+ dma_chan[ch].dev_id);
+ if (unlikely(status & OMAP_DMA_DROP_IRQ))
+ printk(KERN_INFO
+ "DMA synchronization event drop occurred with device "
+ "%d\n", dma_chan[ch].dev_id);
+
+ if (unlikely(status & OMAP2_DMA_TRANS_ERR_IRQ))
+ printk(KERN_INFO "DMA transaction error with device %d\n",
+ dma_chan[ch].dev_id);
+
+ OMAP_DMA_CSR_REG(ch) = 0x20;
+
+ val = omap_readl(OMAP_DMA4_IRQSTATUS_L0);
+ /* ch in this function is from 0-31 while in register it is 1-32 */
+ val = 1 << (ch);
+ omap_writel(val, OMAP_DMA4_IRQSTATUS_L0);
+
+ if (likely(dma_chan[ch].callback != NULL))
+ dma_chan[ch].callback(ch, status, dma_chan[ch].data);
+
+ return 0;
+}
+
+/* STATUS register count is from 1-32 while our is 0-31 */
+static irqreturn_t omap2_dma_irq_handler(int irq, void *dev_id,
+ struct pt_regs *regs)
+{
+ u32 val;
+ int i;
+
+ val = omap_readl(OMAP_DMA4_IRQSTATUS_L0);
+
+ for (i = 1; i <= OMAP_LOGICAL_DMA_CH_COUNT; i++) {
+ int active = val & (1 << (i - 1));
+ if (active)
+ omap2_dma_handle_ch(i - 1);
+ }
+
+ return IRQ_HANDLED;
+}
+
+static struct irqaction omap24xx_dma_irq = {
+ .name = "DMA",
+ .handler = omap2_dma_irq_handler,
+ .flags = SA_INTERRUPT
+};
+
+#else
+static struct irqaction omap24xx_dma_irq;
+#endif
+
+/*----------------------------------------------------------------------------*/
static struct lcd_dma_info {
spinlock_t lock;
@@ -795,7 +1112,7 @@ static void set_b1_regs(void)
/* Always set the source port as SDRAM for now*/
w &= ~(0x03 << 6);
if (lcd_dma.callback != NULL)
- w |= 1 << 1; /* Block interrupt enable */
+ w |= 1 << 1; /* Block interrupt enable */
else
w &= ~(1 << 1);
omap_writew(w, OMAP1610_DMA_LCD_CTRL);
@@ -814,7 +1131,8 @@ static void set_b1_regs(void)
omap_writew(fi, OMAP1610_DMA_LCD_SRC_FI_B1_L);
}
-static irqreturn_t lcd_dma_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t lcd_dma_irq_handler(int irq, void *dev_id,
+ struct pt_regs *regs)
{
u16 w;
@@ -870,7 +1188,8 @@ void omap_free_lcd_dma(void)
return;
}
if (!enable_1510_mode)
- omap_writew(omap_readw(OMAP1610_DMA_LCD_CCR) & ~1, OMAP1610_DMA_LCD_CCR);
+ omap_writew(omap_readw(OMAP1610_DMA_LCD_CCR) & ~1,
+ OMAP1610_DMA_LCD_CCR);
lcd_dma.reserved = 0;
spin_unlock(&lcd_dma.lock);
}
@@ -939,93 +1258,24 @@ void omap_stop_lcd_dma(void)
omap_writew(w, OMAP1610_DMA_LCD_CTRL);
}
-/*
- * Clears any DMA state so the DMA engine is ready to restart with new buffers
- * through omap_start_dma(). Any buffers in flight are discarded.
- */
-void omap_clear_dma(int lch)
-{
- unsigned long flags;
- int status;
-
- local_irq_save(flags);
- omap_writew(omap_readw(OMAP_DMA_CCR(lch)) & ~OMAP_DMA_CCR_EN,
- OMAP_DMA_CCR(lch));
- status = OMAP_DMA_CSR(lch); /* clear pending interrupts */
- local_irq_restore(flags);
-}
-
-/*
- * Returns current physical source address for the given DMA channel.
- * If the channel is running the caller must disable interrupts prior calling
- * this function and process the returned value before re-enabling interrupt to
- * prevent races with the interrupt handler. Note that in continuous mode there
- * is a chance for CSSA_L register overflow inbetween the two reads resulting
- * in incorrect return value.
- */
-dma_addr_t omap_get_dma_src_pos(int lch)
-{
- return (dma_addr_t) (omap_readw(OMAP_DMA_CSSA_L(lch)) |
- (omap_readw(OMAP_DMA_CSSA_U(lch)) << 16));
-}
-
-/*
- * Returns current physical destination address for the given DMA channel.
- * If the channel is running the caller must disable interrupts prior calling
- * this function and process the returned value before re-enabling interrupt to
- * prevent races with the interrupt handler. Note that in continuous mode there
- * is a chance for CDSA_L register overflow inbetween the two reads resulting
- * in incorrect return value.
- */
-dma_addr_t omap_get_dma_dst_pos(int lch)
-{
- return (dma_addr_t) (omap_readw(OMAP_DMA_CDSA_L(lch)) |
- (omap_readw(OMAP_DMA_CDSA_U(lch)) << 16));
-}
-
-/*
- * Returns current source transfer counting for the given DMA channel.
- * Can be used to monitor the progress of a transfer inside a block.
- * It must be called with disabled interrupts.
- */
-int omap_get_dma_src_addr_counter(int lch)
-{
- return (dma_addr_t) omap_readw(OMAP_DMA_CSAC(lch));
-}
-
-int omap_dma_running(void)
-{
- int lch;
-
- /* Check if LCD DMA is running */
- if (cpu_is_omap16xx())
- if (omap_readw(OMAP1610_DMA_LCD_CCR) & OMAP_DMA_CCR_EN)
- return 1;
-
- for (lch = 0; lch < dma_chan_count; lch++) {
- u16 w;
-
- w = omap_readw(OMAP_DMA_CCR(lch));
- if (w & OMAP_DMA_CCR_EN)
- return 1;
- }
- return 0;
-}
+/*----------------------------------------------------------------------------*/
static int __init omap_init_dma(void)
{
int ch, r;
- if (cpu_is_omap1510()) {
- printk(KERN_INFO "DMA support for OMAP1510 initialized\n");
+ if (cpu_is_omap15xx()) {
+ printk(KERN_INFO "DMA support for OMAP15xx initialized\n");
dma_chan_count = 9;
enable_1510_mode = 1;
} else if (cpu_is_omap16xx() || cpu_is_omap730()) {
printk(KERN_INFO "OMAP DMA hardware version %d\n",
omap_readw(OMAP_DMA_HW_ID));
printk(KERN_INFO "DMA capabilities: %08x:%08x:%04x:%04x:%04x\n",
- (omap_readw(OMAP_DMA_CAPS_0_U) << 16) | omap_readw(OMAP_DMA_CAPS_0_L),
- (omap_readw(OMAP_DMA_CAPS_1_U) << 16) | omap_readw(OMAP_DMA_CAPS_1_L),
+ (omap_readw(OMAP_DMA_CAPS_0_U) << 16) |
+ omap_readw(OMAP_DMA_CAPS_0_L),
+ (omap_readw(OMAP_DMA_CAPS_1_U) << 16) |
+ omap_readw(OMAP_DMA_CAPS_1_L),
omap_readw(OMAP_DMA_CAPS_2), omap_readw(OMAP_DMA_CAPS_3),
omap_readw(OMAP_DMA_CAPS_4));
if (!enable_1510_mode) {
@@ -1038,6 +1288,11 @@ static int __init omap_init_dma(void)
dma_chan_count = 16;
} else
dma_chan_count = 9;
+ } else if (cpu_is_omap24xx()) {
+ u8 revision = omap_readb(OMAP_DMA4_REVISION);
+ printk(KERN_INFO "OMAP DMA hardware revision %d.%d\n",
+ revision >> 4, revision & 0xf);
+ dma_chan_count = OMAP_LOGICAL_DMA_CH_COUNT;
} else {
dma_chan_count = 0;
return 0;
@@ -1049,41 +1304,56 @@ static int __init omap_init_dma(void)
memset(&dma_chan, 0, sizeof(dma_chan));
for (ch = 0; ch < dma_chan_count; ch++) {
+ omap_clear_dma(ch);
dma_chan[ch].dev_id = -1;
dma_chan[ch].next_lch = -1;
if (ch >= 6 && enable_1510_mode)
continue;
- /* request_irq() doesn't like dev_id (ie. ch) being zero,
- * so we have to kludge around this. */
- r = request_irq(dma_irq[ch], dma_irq_handler, 0, "DMA",
- (void *) (ch + 1));
+ if (cpu_class_is_omap1()) {
+ /* request_irq() doesn't like dev_id (ie. ch) being
+ * zero, so we have to kludge around this. */
+ r = request_irq(omap1_dma_irq[ch],
+ omap1_dma_irq_handler, 0, "DMA",
+ (void *) (ch + 1));
+ if (r != 0) {
+ int i;
+
+ printk(KERN_ERR "unable to request IRQ %d "
+ "for DMA (error %d)\n",
+ omap1_dma_irq[ch], r);
+ for (i = 0; i < ch; i++)
+ free_irq(omap1_dma_irq[i],
+ (void *) (i + 1));
+ return r;
+ }
+ }
+ }
+
+ if (cpu_is_omap24xx())
+ setup_irq(INT_24XX_SDMA_IRQ0, &omap24xx_dma_irq);
+
+ /* FIXME: Update LCD DMA to work on 24xx */
+ if (cpu_class_is_omap1()) {
+ r = request_irq(INT_DMA_LCD, lcd_dma_irq_handler, 0,
+ "LCD DMA", NULL);
if (r != 0) {
int i;
- printk(KERN_ERR "unable to request IRQ %d for DMA (error %d)\n",
- dma_irq[ch], r);
- for (i = 0; i < ch; i++)
- free_irq(dma_irq[i], (void *) (i + 1));
+ printk(KERN_ERR "unable to request IRQ for LCD DMA "
+ "(error %d)\n", r);
+ for (i = 0; i < dma_chan_count; i++)
+ free_irq(omap1_dma_irq[i], (void *) (i + 1));
return r;
}
}
- r = request_irq(INT_DMA_LCD, lcd_dma_irq_handler, 0, "LCD DMA", NULL);
- if (r != 0) {
- int i;
- printk(KERN_ERR "unable to request IRQ for LCD DMA (error %d)\n", r);
- for (i = 0; i < dma_chan_count; i++)
- free_irq(dma_irq[i], (void *) (i + 1));
- return r;
- }
return 0;
}
arch_initcall(omap_init_dma);
-
EXPORT_SYMBOL(omap_get_dma_src_pos);
EXPORT_SYMBOL(omap_get_dma_dst_pos);
EXPORT_SYMBOL(omap_get_dma_src_addr_counter);
@@ -1109,6 +1379,8 @@ EXPORT_SYMBOL(omap_set_dma_dest_index);
EXPORT_SYMBOL(omap_set_dma_dest_data_pack);
EXPORT_SYMBOL(omap_set_dma_dest_burst_mode);
+EXPORT_SYMBOL(omap_set_dma_params);
+
EXPORT_SYMBOL(omap_dma_link_lch);
EXPORT_SYMBOL(omap_dma_unlink_lch);
diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c
index 55059a24ad41..76f721d85137 100644
--- a/arch/arm/plat-omap/gpio.c
+++ b/arch/arm/plat-omap/gpio.c
@@ -140,7 +140,7 @@ static struct gpio_bank gpio_bank_1610[5] = {
};
#endif
-#ifdef CONFIG_ARCH_OMAP1510
+#ifdef CONFIG_ARCH_OMAP15XX
static struct gpio_bank gpio_bank_1510[2] = {
{ OMAP_MPUIO_BASE, INT_MPUIO, IH_MPUIO_BASE, METHOD_MPUIO },
{ OMAP1510_GPIO_BASE, INT_GPIO_BANK1, IH_GPIO_BASE, METHOD_GPIO_1510 }
@@ -173,7 +173,7 @@ static int gpio_bank_count;
static inline struct gpio_bank *get_gpio_bank(int gpio)
{
-#ifdef CONFIG_ARCH_OMAP1510
+#ifdef CONFIG_ARCH_OMAP15XX
if (cpu_is_omap1510()) {
if (OMAP_GPIO_IS_MPUIO(gpio))
return &gpio_bank[0];
@@ -222,7 +222,7 @@ static inline int gpio_valid(int gpio)
return -1;
return 0;
}
-#ifdef CONFIG_ARCH_OMAP1510
+#ifdef CONFIG_ARCH_OMAP15XX
if (cpu_is_omap1510() && gpio < 16)
return 0;
#endif
@@ -654,7 +654,7 @@ int omap_request_gpio(int gpio)
/* Set trigger to none. You need to enable the trigger after request_irq */
_set_gpio_triggering(bank, get_gpio_index(gpio), IRQT_NOEDGE);
-#ifdef CONFIG_ARCH_OMAP1510
+#ifdef CONFIG_ARCH_OMAP15XX
if (bank->method == METHOD_GPIO_1510) {
void __iomem *reg;
@@ -739,7 +739,7 @@ static void gpio_irq_handler(unsigned int irq, struct irqdesc *desc,
bank = (struct gpio_bank *) desc->data;
if (bank->method == METHOD_MPUIO)
isr_reg = bank->base + OMAP_MPUIO_GPIO_INT;
-#ifdef CONFIG_ARCH_OMAP1510
+#ifdef CONFIG_ARCH_OMAP15XX
if (bank->method == METHOD_GPIO_1510)
isr_reg = bank->base + OMAP1510_GPIO_INT_STATUS;
#endif
@@ -774,7 +774,7 @@ static void gpio_irq_handler(unsigned int irq, struct irqdesc *desc,
d = irq_desc + gpio_irq;
desc_handle_irq(gpio_irq, d, regs);
}
- }
+ }
}
static void gpio_ack_irq(unsigned int irq)
@@ -837,8 +837,9 @@ static struct irqchip mpuio_irq_chip = {
.unmask = mpuio_unmask_irq
};
-static int initialized = 0;
-static struct clk * gpio_ck = NULL;
+static int initialized;
+static struct clk * gpio_ick;
+static struct clk * gpio_fck;
static int __init _omap_gpio_init(void)
{
@@ -848,14 +849,26 @@ static int __init _omap_gpio_init(void)
initialized = 1;
if (cpu_is_omap1510()) {
- gpio_ck = clk_get(NULL, "arm_gpio_ck");
- if (IS_ERR(gpio_ck))
+ gpio_ick = clk_get(NULL, "arm_gpio_ck");
+ if (IS_ERR(gpio_ick))
printk("Could not get arm_gpio_ck\n");
else
- clk_use(gpio_ck);
+ clk_use(gpio_ick);
+ }
+ if (cpu_is_omap24xx()) {
+ gpio_ick = clk_get(NULL, "gpios_ick");
+ if (IS_ERR(gpio_ick))
+ printk("Could not get gpios_ick\n");
+ else
+ clk_use(gpio_ick);
+ gpio_fck = clk_get(NULL, "gpios_fck");
+ if (IS_ERR(gpio_ick))
+ printk("Could not get gpios_fck\n");
+ else
+ clk_use(gpio_fck);
}
-#ifdef CONFIG_ARCH_OMAP1510
+#ifdef CONFIG_ARCH_OMAP15XX
if (cpu_is_omap1510()) {
printk(KERN_INFO "OMAP1510 GPIO hardware\n");
gpio_bank_count = 2;
@@ -901,7 +914,7 @@ static int __init _omap_gpio_init(void)
if (bank->method == METHOD_MPUIO) {
omap_writew(0xFFFF, OMAP_MPUIO_BASE + OMAP_MPUIO_GPIO_MASKIT);
}
-#ifdef CONFIG_ARCH_OMAP1510
+#ifdef CONFIG_ARCH_OMAP15XX
if (bank->method == METHOD_GPIO_1510) {
__raw_writew(0xffff, bank->base + OMAP1510_GPIO_INT_MASK);
__raw_writew(0x0000, bank->base + OMAP1510_GPIO_INT_STATUS);
@@ -1038,6 +1051,7 @@ static struct sys_device omap_gpio_device = {
/*
* This may get called early from board specific init
+ * for boards that have interrupts routed via FPGA.
*/
int omap_gpio_init(void)
{
diff --git a/arch/arm/plat-omap/mcbsp.c b/arch/arm/plat-omap/mcbsp.c
index 9c9b7df3faf6..ea9475c86656 100644
--- a/arch/arm/plat-omap/mcbsp.c
+++ b/arch/arm/plat-omap/mcbsp.c
@@ -491,17 +491,20 @@ int omap_mcbsp_xmit_buffer(unsigned int id, dma_addr_t buffer, unsigned int leng
omap_set_dma_transfer_params(mcbsp[id].dma_tx_lch,
OMAP_DMA_DATA_TYPE_S16,
length >> 1, 1,
- OMAP_DMA_SYNC_ELEMENT);
+ OMAP_DMA_SYNC_ELEMENT,
+ 0, 0);
omap_set_dma_dest_params(mcbsp[id].dma_tx_lch,
OMAP_DMA_PORT_TIPB,
OMAP_DMA_AMODE_CONSTANT,
- mcbsp[id].io_base + OMAP_MCBSP_REG_DXR1);
+ mcbsp[id].io_base + OMAP_MCBSP_REG_DXR1,
+ 0, 0);
omap_set_dma_src_params(mcbsp[id].dma_tx_lch,
OMAP_DMA_PORT_EMIFF,
OMAP_DMA_AMODE_POST_INC,
- buffer);
+ buffer,
+ 0, 0);
omap_start_dma(mcbsp[id].dma_tx_lch);
wait_for_completion(&(mcbsp[id].tx_dma_completion));
@@ -531,17 +534,20 @@ int omap_mcbsp_recv_buffer(unsigned int id, dma_addr_t buffer, unsigned int leng
omap_set_dma_transfer_params(mcbsp[id].dma_rx_lch,
OMAP_DMA_DATA_TYPE_S16,
length >> 1, 1,
- OMAP_DMA_SYNC_ELEMENT);
+ OMAP_DMA_SYNC_ELEMENT,
+ 0, 0);
omap_set_dma_src_params(mcbsp[id].dma_rx_lch,
OMAP_DMA_PORT_TIPB,
OMAP_DMA_AMODE_CONSTANT,
- mcbsp[id].io_base + OMAP_MCBSP_REG_DRR1);
+ mcbsp[id].io_base + OMAP_MCBSP_REG_DRR1,
+ 0, 0);
omap_set_dma_dest_params(mcbsp[id].dma_rx_lch,
OMAP_DMA_PORT_EMIFF,
OMAP_DMA_AMODE_POST_INC,
- buffer);
+ buffer,
+ 0, 0);
omap_start_dma(mcbsp[id].dma_rx_lch);
wait_for_completion(&(mcbsp[id].rx_dma_completion));
@@ -643,7 +649,7 @@ static const struct omap_mcbsp_info mcbsp_730[] = {
};
#endif
-#ifdef CONFIG_ARCH_OMAP1510
+#ifdef CONFIG_ARCH_OMAP15XX
static const struct omap_mcbsp_info mcbsp_1510[] = {
[0] = { .virt_base = OMAP1510_MCBSP1_BASE,
.dma_rx_sync = OMAP_DMA_MCBSP1_RX,
@@ -712,7 +718,7 @@ static int __init omap_mcbsp_init(void)
mcbsp_count = ARRAY_SIZE(mcbsp_730);
}
#endif
-#ifdef CONFIG_ARCH_OMAP1510
+#ifdef CONFIG_ARCH_OMAP15XX
if (cpu_is_omap1510()) {
mcbsp_info = mcbsp_1510;
mcbsp_count = ARRAY_SIZE(mcbsp_1510);
diff --git a/arch/arm/plat-omap/mux.c b/arch/arm/plat-omap/mux.c
index 64482040f89e..8c1c016aa689 100644
--- a/arch/arm/plat-omap/mux.c
+++ b/arch/arm/plat-omap/mux.c
@@ -3,7 +3,7 @@
*
* Utility to set the Omap MUX and PULL_DWN registers from a table in mux.h
*
- * Copyright (C) 2003 Nokia Corporation
+ * Copyright (C) 2003 - 2005 Nokia Corporation
*
* Written by Tony Lindgren <tony.lindgren@nokia.com>
*
@@ -25,38 +25,74 @@
#include <linux/config.h>
#include <linux/module.h>
#include <linux/init.h>
+#include <linux/kernel.h>
#include <asm/system.h>
#include <asm/io.h>
#include <linux/spinlock.h>
-
-#define __MUX_C__
#include <asm/arch/mux.h>
#ifdef CONFIG_OMAP_MUX
+#define OMAP24XX_L4_BASE 0x48000000
+#define OMAP24XX_PULL_ENA (1 << 3)
+#define OMAP24XX_PULL_UP (1 << 4)
+
+static struct pin_config * pin_table;
+static unsigned long pin_table_sz;
+
+extern struct pin_config * omap730_pins;
+extern struct pin_config * omap1xxx_pins;
+extern struct pin_config * omap24xx_pins;
+
+int __init omap_mux_register(struct pin_config * pins, unsigned long size)
+{
+ pin_table = pins;
+ pin_table_sz = size;
+
+ return 0;
+}
+
/*
* Sets the Omap MUX and PULL_DWN registers based on the table
*/
-int __init_or_module
-omap_cfg_reg(const reg_cfg_t reg_cfg)
+int __init_or_module omap_cfg_reg(const unsigned long index)
{
static DEFINE_SPINLOCK(mux_spin_lock);
unsigned long flags;
- reg_cfg_set *cfg;
+ struct pin_config *cfg;
unsigned int reg_orig = 0, reg = 0, pu_pd_orig = 0, pu_pd = 0,
pull_orig = 0, pull = 0;
unsigned int mask, warn = 0;
- if (cpu_is_omap7xx())
- return 0;
+ if (!pin_table)
+ BUG();
- if (reg_cfg > ARRAY_SIZE(reg_cfg_table)) {
- printk(KERN_ERR "MUX: reg_cfg %d\n", reg_cfg);
- return -EINVAL;
+ if (index >= pin_table_sz) {
+ printk(KERN_ERR "Invalid pin mux index: %lu (%lu)\n",
+ index, pin_table_sz);
+ dump_stack();
+ return -ENODEV;
}
- cfg = (reg_cfg_set *)&reg_cfg_table[reg_cfg];
+ cfg = (struct pin_config *)&pin_table[index];
+ if (cpu_is_omap24xx()) {
+ u8 reg = 0;
+
+ reg |= cfg->mask & 0x7;
+ if (cfg->pull_val)
+ reg |= OMAP24XX_PULL_ENA;
+ if(cfg->pu_pd_val)
+ reg |= OMAP24XX_PULL_UP;
+#ifdef CONFIG_OMAP_MUX_DEBUG
+ printk("Muxing %s (0x%08x): 0x%02x -> 0x%02x\n",
+ cfg->name, OMAP24XX_L4_BASE + cfg->mux_reg,
+ omap_readb(OMAP24XX_L4_BASE + cfg->mux_reg), reg);
+#endif
+ omap_writeb(reg, OMAP24XX_L4_BASE + cfg->mux_reg);
+
+ return 0;
+ }
/* Check the mux register in question */
if (cfg->mux_reg) {
@@ -157,7 +193,8 @@ omap_cfg_reg(const reg_cfg_t reg_cfg)
return 0;
#endif
}
-
EXPORT_SYMBOL(omap_cfg_reg);
-
+#else
+#define omap_mux_init() do {} while(0)
+#define omap_cfg_reg(x) do {} while(0)
#endif /* CONFIG_OMAP_MUX */
diff --git a/arch/arm/plat-omap/ocpi.c b/arch/arm/plat-omap/ocpi.c
index 1fb16f9edfd5..2ede2ee8cae4 100644
--- a/arch/arm/plat-omap/ocpi.c
+++ b/arch/arm/plat-omap/ocpi.c
@@ -25,7 +25,6 @@
#include <linux/config.h>
#include <linux/module.h>
-#include <linux/version.h>
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/kernel.h>
diff --git a/arch/arm/plat-omap/pm.c b/arch/arm/plat-omap/pm.c
index e15c6c1ddec9..966cca031ca7 100644
--- a/arch/arm/plat-omap/pm.c
+++ b/arch/arm/plat-omap/pm.c
@@ -54,11 +54,12 @@
#include <asm/arch/tps65010.h>
#include <asm/arch/dsp_common.h>
-#include "clock.h"
-#include "sram.h"
+#include <asm/arch/clock.h>
+#include <asm/arch/sram.h>
static unsigned int arm_sleep_save[ARM_SLEEP_SAVE_SIZE];
static unsigned short ulpd_sleep_save[ULPD_SLEEP_SAVE_SIZE];
+static unsigned int mpui730_sleep_save[MPUI730_SLEEP_SAVE_SIZE];
static unsigned int mpui1510_sleep_save[MPUI1510_SLEEP_SAVE_SIZE];
static unsigned int mpui1610_sleep_save[MPUI1610_SLEEP_SAVE_SIZE];
@@ -120,8 +121,8 @@ void omap_pm_idle(void)
*/
static void omap_pm_wakeup_setup(void)
{
- u32 level1_wake = OMAP_IRQ_BIT(INT_IH2_IRQ);
- u32 level2_wake = OMAP_IRQ_BIT(INT_UART2) | OMAP_IRQ_BIT(INT_KEYBOARD);
+ u32 level1_wake = 0;
+ u32 level2_wake = OMAP_IRQ_BIT(INT_UART2);
/*
* Turn off all interrupts except GPIO bank 1, L1-2nd level cascade,
@@ -129,19 +130,29 @@ static void omap_pm_wakeup_setup(void)
* drivers must still separately call omap_set_gpio_wakeup() to
* wake up to a GPIO interrupt.
*/
- if (cpu_is_omap1510() || cpu_is_omap16xx())
- level1_wake |= OMAP_IRQ_BIT(INT_GPIO_BANK1);
- else if (cpu_is_omap730())
- level1_wake |= OMAP_IRQ_BIT(INT_730_GPIO_BANK1);
+ if (cpu_is_omap730())
+ level1_wake = OMAP_IRQ_BIT(INT_730_GPIO_BANK1) |
+ OMAP_IRQ_BIT(INT_730_IH2_IRQ);
+ else if (cpu_is_omap1510())
+ level1_wake = OMAP_IRQ_BIT(INT_GPIO_BANK1) |
+ OMAP_IRQ_BIT(INT_1510_IH2_IRQ);
+ else if (cpu_is_omap16xx())
+ level1_wake = OMAP_IRQ_BIT(INT_GPIO_BANK1) |
+ OMAP_IRQ_BIT(INT_1610_IH2_IRQ);
omap_writel(~level1_wake, OMAP_IH1_MIR);
- if (cpu_is_omap1510())
+ if (cpu_is_omap730()) {
+ omap_writel(~level2_wake, OMAP_IH2_0_MIR);
+ omap_writel(~(OMAP_IRQ_BIT(INT_730_WAKE_UP_REQ) | OMAP_IRQ_BIT(INT_730_MPUIO_KEYPAD)), OMAP_IH2_1_MIR);
+ } else if (cpu_is_omap1510()) {
+ level2_wake |= OMAP_IRQ_BIT(INT_KEYBOARD);
omap_writel(~level2_wake, OMAP_IH2_MIR);
-
- /* INT_1610_WAKE_UP_REQ is needed for GPIO wakeup... */
- if (cpu_is_omap16xx()) {
+ } else if (cpu_is_omap16xx()) {
+ level2_wake |= OMAP_IRQ_BIT(INT_KEYBOARD);
omap_writel(~level2_wake, OMAP_IH2_0_MIR);
+
+ /* INT_1610_WAKE_UP_REQ is needed for GPIO wakeup... */
omap_writel(~OMAP_IRQ_BIT(INT_1610_WAKE_UP_REQ), OMAP_IH2_1_MIR);
omap_writel(~0x0, OMAP_IH2_2_MIR);
omap_writel(~0x0, OMAP_IH2_3_MIR);
@@ -185,7 +196,17 @@ void omap_pm_suspend(void)
* Save interrupt, MPUI, ARM and UPLD control registers.
*/
- if (cpu_is_omap1510()) {
+ if (cpu_is_omap730()) {
+ MPUI730_SAVE(OMAP_IH1_MIR);
+ MPUI730_SAVE(OMAP_IH2_0_MIR);
+ MPUI730_SAVE(OMAP_IH2_1_MIR);
+ MPUI730_SAVE(MPUI_CTRL);
+ MPUI730_SAVE(MPUI_DSP_BOOT_CONFIG);
+ MPUI730_SAVE(MPUI_DSP_API_CONFIG);
+ MPUI730_SAVE(EMIFS_CONFIG);
+ MPUI730_SAVE(EMIFF_SDRAM_CONFIG);
+
+ } else if (cpu_is_omap1510()) {
MPUI1510_SAVE(OMAP_IH1_MIR);
MPUI1510_SAVE(OMAP_IH2_MIR);
MPUI1510_SAVE(MPUI_CTRL);
@@ -280,7 +301,13 @@ void omap_pm_suspend(void)
ULPD_RESTORE(ULPD_CLOCK_CTRL);
ULPD_RESTORE(ULPD_STATUS_REQ);
- if (cpu_is_omap1510()) {
+ if (cpu_is_omap730()) {
+ MPUI730_RESTORE(EMIFS_CONFIG);
+ MPUI730_RESTORE(EMIFF_SDRAM_CONFIG);
+ MPUI730_RESTORE(OMAP_IH1_MIR);
+ MPUI730_RESTORE(OMAP_IH2_0_MIR);
+ MPUI730_RESTORE(OMAP_IH2_1_MIR);
+ } else if (cpu_is_omap1510()) {
MPUI1510_RESTORE(MPUI_CTRL);
MPUI1510_RESTORE(MPUI_DSP_BOOT_CONFIG);
MPUI1510_RESTORE(MPUI_DSP_API_CONFIG);
@@ -355,7 +382,14 @@ static int omap_pm_read_proc(
ULPD_SAVE(ULPD_DPLL_CTRL);
ULPD_SAVE(ULPD_POWER_CTRL);
- if (cpu_is_omap1510()) {
+ if (cpu_is_omap730()) {
+ MPUI730_SAVE(MPUI_CTRL);
+ MPUI730_SAVE(MPUI_DSP_STATUS);
+ MPUI730_SAVE(MPUI_DSP_BOOT_CONFIG);
+ MPUI730_SAVE(MPUI_DSP_API_CONFIG);
+ MPUI730_SAVE(EMIFF_SDRAM_CONFIG);
+ MPUI730_SAVE(EMIFS_CONFIG);
+ } else if (cpu_is_omap1510()) {
MPUI1510_SAVE(MPUI_CTRL);
MPUI1510_SAVE(MPUI_DSP_STATUS);
MPUI1510_SAVE(MPUI_DSP_BOOT_CONFIG);
@@ -404,7 +438,21 @@ static int omap_pm_read_proc(
ULPD_SHOW(ULPD_STATUS_REQ),
ULPD_SHOW(ULPD_POWER_CTRL));
- if (cpu_is_omap1510()) {
+ if (cpu_is_omap730()) {
+ my_buffer_offset += sprintf(my_base + my_buffer_offset,
+ "MPUI730_CTRL_REG 0x%-8x \n"
+ "MPUI730_DSP_STATUS_REG: 0x%-8x \n"
+ "MPUI730_DSP_BOOT_CONFIG_REG: 0x%-8x \n"
+ "MPUI730_DSP_API_CONFIG_REG: 0x%-8x \n"
+ "MPUI730_SDRAM_CONFIG_REG: 0x%-8x \n"
+ "MPUI730_EMIFS_CONFIG_REG: 0x%-8x \n",
+ MPUI730_SHOW(MPUI_CTRL),
+ MPUI730_SHOW(MPUI_DSP_STATUS),
+ MPUI730_SHOW(MPUI_DSP_BOOT_CONFIG),
+ MPUI730_SHOW(MPUI_DSP_API_CONFIG),
+ MPUI730_SHOW(EMIFF_SDRAM_CONFIG),
+ MPUI730_SHOW(EMIFS_CONFIG));
+ } else if (cpu_is_omap1510()) {
my_buffer_offset += sprintf(my_base + my_buffer_offset,
"MPUI1510_CTRL_REG 0x%-8x \n"
"MPUI1510_DSP_STATUS_REG: 0x%-8x \n"
@@ -553,7 +601,12 @@ static int __init omap_pm_init(void)
* These routines need to be in SRAM as that's the only
* memory the MPU can see when it wakes up.
*/
- if (cpu_is_omap1510()) {
+ if (cpu_is_omap730()) {
+ omap_sram_idle = omap_sram_push(omap730_idle_loop_suspend,
+ omap730_idle_loop_suspend_sz);
+ omap_sram_suspend = omap_sram_push(omap730_cpu_suspend,
+ omap730_cpu_suspend_sz);
+ } else if (cpu_is_omap1510()) {
omap_sram_idle = omap_sram_push(omap1510_idle_loop_suspend,
omap1510_idle_loop_suspend_sz);
omap_sram_suspend = omap_sram_push(omap1510_cpu_suspend,
@@ -572,7 +625,11 @@ static int __init omap_pm_init(void)
pm_idle = omap_pm_idle;
- setup_irq(INT_1610_WAKE_UP_REQ, &omap_wakeup_irq);
+ if (cpu_is_omap730())
+ setup_irq(INT_730_WAKE_UP_REQ, &omap_wakeup_irq);
+ else if (cpu_is_omap16xx())
+ setup_irq(INT_1610_WAKE_UP_REQ, &omap_wakeup_irq);
+
#if 0
/* --- BEGIN BOARD-DEPENDENT CODE --- */
/* Sleepx mask direction */
@@ -591,7 +648,9 @@ static int __init omap_pm_init(void)
omap_writew(ULPD_POWER_CTRL_REG_VAL, ULPD_POWER_CTRL);
/* Configure IDLECT3 */
- if (cpu_is_omap16xx())
+ if (cpu_is_omap730())
+ omap_writel(OMAP730_IDLECT3_VAL, OMAP730_IDLECT3);
+ else if (cpu_is_omap16xx())
omap_writel(OMAP1610_IDLECT3_VAL, OMAP1610_IDLECT3);
pm_set_ops(&omap_pm_ops);
@@ -600,8 +659,10 @@ static int __init omap_pm_init(void)
omap_pm_init_proc();
#endif
- /* configure LOW_PWR pin */
- omap_cfg_reg(T20_1610_LOW_PWR);
+ if (cpu_is_omap16xx()) {
+ /* configure LOW_PWR pin */
+ omap_cfg_reg(T20_1610_LOW_PWR);
+ }
return 0;
}
diff --git a/arch/arm/plat-omap/sleep.S b/arch/arm/plat-omap/sleep.S
index 9f745836f6aa..4cd7d292f854 100644
--- a/arch/arm/plat-omap/sleep.S
+++ b/arch/arm/plat-omap/sleep.S
@@ -1,7 +1,7 @@
/*
* linux/arch/arm/plat-omap/sleep.S
*
- * Low-level OMAP1510/1610 sleep/wakeUp support
+ * Low-level OMAP730/1510/1610 sleep/wakeUp support
*
* Initial SA1110 code:
* Copyright (c) 2001 Cliff Brake <cbrake@accelent.com>
@@ -52,7 +52,57 @@
* processor specific functions here.
*/
-#ifdef CONFIG_ARCH_OMAP1510
+#if defined(CONFIG_ARCH_OMAP730)
+ENTRY(omap730_idle_loop_suspend)
+
+ stmfd sp!, {r0 - r12, lr} @ save registers on stack
+
+ @ load base address of ARM_IDLECT1 and ARM_IDLECT2
+ mov r4, #CLKGEN_REG_ASM_BASE & 0xff000000
+ orr r4, r4, #CLKGEN_REG_ASM_BASE & 0x00ff0000
+ orr r4, r4, #CLKGEN_REG_ASM_BASE & 0x0000ff00
+
+ @ turn off clock domains
+ @ get ARM_IDLECT2 into r2
+ ldrh r2, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
+ mov r5, #OMAP730_IDLECT2_SLEEP_VAL & 0xff
+ orr r5, r5, #OMAP730_IDLECT2_SLEEP_VAL & 0xff00
+ strh r5, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
+
+ @ request ARM idle
+ @ get ARM_IDLECT1 into r1
+ ldrh r1, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
+ orr r3, r1, #OMAP730_IDLE_LOOP_REQUEST & 0xffff
+ strh r3, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
+
+ mov r5, #IDLE_WAIT_CYCLES & 0xff
+ orr r5, r5, #IDLE_WAIT_CYCLES & 0xff00
+l_730: subs r5, r5, #1
+ bne l_730
+/*
+ * Let's wait for the next clock tick to wake us up.
+ */
+ mov r0, #0
+ mcr p15, 0, r0, c7, c0, 4 @ wait for interrupt
+/*
+ * omap730_idle_loop_suspend()'s resume point.
+ *
+ * It will just start executing here, so we'll restore stuff from the
+ * stack, reset the ARM_IDLECT1 and ARM_IDLECT2.
+ */
+
+ @ restore ARM_IDLECT1 and ARM_IDLECT2 and return
+ @ r1 has ARM_IDLECT1 and r2 still has ARM_IDLECT2
+ strh r2, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
+ strh r1, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
+
+ ldmfd sp!, {r0 - r12, pc} @ restore regs and return
+
+ENTRY(omap730_idle_loop_suspend_sz)
+ .word . - omap730_idle_loop_suspend
+#endif /* CONFIG_ARCH_OMAP730 */
+
+#ifdef CONFIG_ARCH_OMAP15XX
ENTRY(omap1510_idle_loop_suspend)
stmfd sp!, {r0 - r12, lr} @ save registers on stack
@@ -100,7 +150,7 @@ l_1510: subs r5, r5, #1
ENTRY(omap1510_idle_loop_suspend_sz)
.word . - omap1510_idle_loop_suspend
-#endif /* CONFIG_ARCH_OMAP1510 */
+#endif /* CONFIG_ARCH_OMAP15XX */
#if defined(CONFIG_ARCH_OMAP16XX)
ENTRY(omap1610_idle_loop_suspend)
@@ -169,7 +219,86 @@ ENTRY(omap1610_idle_loop_suspend_sz)
*
*/
-#ifdef CONFIG_ARCH_OMAP1510
+#if defined(CONFIG_ARCH_OMAP730)
+ENTRY(omap730_cpu_suspend)
+
+ @ save registers on stack
+ stmfd sp!, {r0 - r12, lr}
+
+ @ Drain write cache
+ mov r4, #0
+ mcr p15, 0, r0, c7, c10, 4
+ nop
+
+ @ load base address of Traffic Controller
+ mov r6, #TCMIF_ASM_BASE & 0xff000000
+ orr r6, r6, #TCMIF_ASM_BASE & 0x00ff0000
+ orr r6, r6, #TCMIF_ASM_BASE & 0x0000ff00
+
+ @ prepare to put SDRAM into self-refresh manually
+ ldr r7, [r6, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff]
+ orr r9, r7, #SELF_REFRESH_MODE & 0xff000000
+ orr r9, r9, #SELF_REFRESH_MODE & 0x000000ff
+ str r9, [r6, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff]
+
+ @ prepare to put EMIFS to Sleep
+ ldr r8, [r6, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
+ orr r9, r8, #IDLE_EMIFS_REQUEST & 0xff
+ str r9, [r6, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
+
+ @ load base address of ARM_IDLECT1 and ARM_IDLECT2
+ mov r4, #CLKGEN_REG_ASM_BASE & 0xff000000
+ orr r4, r4, #CLKGEN_REG_ASM_BASE & 0x00ff0000
+ orr r4, r4, #CLKGEN_REG_ASM_BASE & 0x0000ff00
+
+ @ turn off clock domains
+ @ do not disable PERCK (0x04)
+ mov r5, #OMAP730_IDLECT2_SLEEP_VAL & 0xff
+ orr r5, r5, #OMAP730_IDLECT2_SLEEP_VAL & 0xff00
+ strh r5, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
+
+ @ request ARM idle
+ mov r3, #OMAP730_IDLECT1_SLEEP_VAL & 0xff
+ orr r3, r3, #OMAP730_IDLECT1_SLEEP_VAL & 0xff00
+ strh r3, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
+
+ @ disable instruction cache
+ mrc p15, 0, r9, c1, c0, 0
+ bic r2, r9, #0x1000
+ mcr p15, 0, r2, c1, c0, 0
+ nop
+
+/*
+ * Let's wait for the next wake up event to wake us up. r0 can't be
+ * used here because r0 holds ARM_IDLECT1
+ */
+ mov r2, #0
+ mcr p15, 0, r2, c7, c0, 4 @ wait for interrupt
+/*
+ * omap730_cpu_suspend()'s resume point.
+ *
+ * It will just start executing here, so we'll restore stuff from the
+ * stack.
+ */
+ @ re-enable Icache
+ mcr p15, 0, r9, c1, c0, 0
+
+ @ reset the ARM_IDLECT1 and ARM_IDLECT2.
+ strh r1, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
+ strh r0, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
+
+ @ Restore EMIFF controls
+ str r7, [r6, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff]
+ str r8, [r6, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
+
+ @ restore regs and return
+ ldmfd sp!, {r0 - r12, pc}
+
+ENTRY(omap730_cpu_suspend_sz)
+ .word . - omap730_cpu_suspend
+#endif /* CONFIG_ARCH_OMAP730 */
+
+#ifdef CONFIG_ARCH_OMAP15XX
ENTRY(omap1510_cpu_suspend)
@ save registers on stack
@@ -241,7 +370,7 @@ l_1510_2:
ENTRY(omap1510_cpu_suspend_sz)
.word . - omap1510_cpu_suspend
-#endif /* CONFIG_ARCH_OMAP1510 */
+#endif /* CONFIG_ARCH_OMAP15XX */
#if defined(CONFIG_ARCH_OMAP16XX)
ENTRY(omap1610_cpu_suspend)
diff --git a/arch/arm/plat-omap/sram.c b/arch/arm/plat-omap/sram.c
index 7719a4062e3a..792f66375830 100644
--- a/arch/arm/plat-omap/sram.c
+++ b/arch/arm/plat-omap/sram.c
@@ -20,10 +20,13 @@
#include <asm/io.h>
#include <asm/cacheflush.h>
-#include "sram.h"
+#include <asm/arch/sram.h>
+
+#define OMAP1_SRAM_PA 0x20000000
+#define OMAP1_SRAM_VA 0xd0000000
+#define OMAP2_SRAM_PA 0x40200000
+#define OMAP2_SRAM_VA 0xd0000000
-#define OMAP1_SRAM_BASE 0xd0000000
-#define OMAP1_SRAM_START 0x20000000
#define SRAM_BOOTLOADER_SZ 0x80
static unsigned long omap_sram_base;
@@ -31,35 +34,42 @@ static unsigned long omap_sram_size;
static unsigned long omap_sram_ceil;
/*
- * The amount of SRAM depends on the core type:
- * 730 = 200K, 1510 = 512K, 5912 = 256K, 1610 = 16K, 1710 = 16K
+ * The amount of SRAM depends on the core type.
* Note that we cannot try to test for SRAM here because writes
* to secure SRAM will hang the system. Also the SRAM is not
* yet mapped at this point.
*/
void __init omap_detect_sram(void)
{
- omap_sram_base = OMAP1_SRAM_BASE;
+ if (!cpu_is_omap24xx())
+ omap_sram_base = OMAP1_SRAM_VA;
+ else
+ omap_sram_base = OMAP2_SRAM_VA;
if (cpu_is_omap730())
- omap_sram_size = 0x32000;
- else if (cpu_is_omap1510())
- omap_sram_size = 0x80000;
+ omap_sram_size = 0x32000; /* 200K */
+ else if (cpu_is_omap15xx())
+ omap_sram_size = 0x30000; /* 192K */
else if (cpu_is_omap1610() || cpu_is_omap1621() || cpu_is_omap1710())
- omap_sram_size = 0x4000;
+ omap_sram_size = 0x4000; /* 16K */
else if (cpu_is_omap1611())
- omap_sram_size = 0x3e800;
+ omap_sram_size = 0x3e800; /* 250K */
+ else if (cpu_is_omap2420())
+ omap_sram_size = 0xa0014; /* 640K */
else {
printk(KERN_ERR "Could not detect SRAM size\n");
omap_sram_size = 0x4000;
}
- printk(KERN_INFO "SRAM size: 0x%lx\n", omap_sram_size);
omap_sram_ceil = omap_sram_base + omap_sram_size;
}
static struct map_desc omap_sram_io_desc[] __initdata = {
- { OMAP1_SRAM_BASE, OMAP1_SRAM_START, 0, MT_DEVICE }
+ { /* .length gets filled in at runtime */
+ .virtual = OMAP1_SRAM_VA,
+ .pfn = __phys_to_pfn(OMAP1_SRAM_PA),
+ .type = MT_DEVICE
+ }
};
/*
@@ -72,10 +82,19 @@ void __init omap_map_sram(void)
if (omap_sram_size == 0)
return;
+ if (cpu_is_omap24xx()) {
+ omap_sram_io_desc[0].virtual = OMAP2_SRAM_VA;
+ omap_sram_io_desc[0].pfn = __phys_to_pfn(OMAP2_SRAM_PA);
+ }
+
omap_sram_io_desc[0].length = (omap_sram_size + PAGE_SIZE-1)/PAGE_SIZE;
omap_sram_io_desc[0].length *= PAGE_SIZE;
iotable_init(omap_sram_io_desc, ARRAY_SIZE(omap_sram_io_desc));
+ printk(KERN_INFO "SRAM: Mapped pa 0x%08lx to va 0x%08lx size: 0x%lx\n",
+ omap_sram_io_desc[0].pfn, omap_sram_io_desc[0].virtual,
+ omap_sram_io_desc[0].length);
+
/*
* Looks like we need to preserve some bootloader code at the
* beginning of SRAM for jumping to flash for reboot to work...
@@ -84,16 +103,6 @@ void __init omap_map_sram(void)
omap_sram_size - SRAM_BOOTLOADER_SZ);
}
-static void (*_omap_sram_reprogram_clock)(u32 dpllctl, u32 ckctl) = NULL;
-
-void omap_sram_reprogram_clock(u32 dpllctl, u32 ckctl)
-{
- if (_omap_sram_reprogram_clock == NULL)
- panic("Cannot use SRAM");
-
- return _omap_sram_reprogram_clock(dpllctl, ckctl);
-}
-
void * omap_sram_push(void * start, unsigned long size)
{
if (size > (omap_sram_ceil - (omap_sram_base + SRAM_BOOTLOADER_SZ))) {
@@ -107,10 +116,94 @@ void * omap_sram_push(void * start, unsigned long size)
return (void *)omap_sram_ceil;
}
-void __init omap_sram_init(void)
+static void omap_sram_error(void)
+{
+ panic("Uninitialized SRAM function\n");
+}
+
+#ifdef CONFIG_ARCH_OMAP1
+
+static void (*_omap_sram_reprogram_clock)(u32 dpllctl, u32 ckctl);
+
+void omap_sram_reprogram_clock(u32 dpllctl, u32 ckctl)
+{
+ if (!_omap_sram_reprogram_clock)
+ omap_sram_error();
+
+ return _omap_sram_reprogram_clock(dpllctl, ckctl);
+}
+
+int __init omap1_sram_init(void)
{
- omap_detect_sram();
- omap_map_sram();
_omap_sram_reprogram_clock = omap_sram_push(sram_reprogram_clock,
sram_reprogram_clock_sz);
+
+ return 0;
+}
+
+#else
+#define omap1_sram_init() do {} while (0)
+#endif
+
+#ifdef CONFIG_ARCH_OMAP2
+
+static void (*_omap2_sram_ddr_init)(u32 *slow_dll_ctrl, u32 fast_dll_ctrl,
+ u32 base_cs, u32 force_unlock);
+
+void omap2_sram_ddr_init(u32 *slow_dll_ctrl, u32 fast_dll_ctrl,
+ u32 base_cs, u32 force_unlock)
+{
+ if (!_omap2_sram_ddr_init)
+ omap_sram_error();
+
+ return _omap2_sram_ddr_init(slow_dll_ctrl, fast_dll_ctrl,
+ base_cs, force_unlock);
+}
+
+static void (*_omap2_sram_reprogram_sdrc)(u32 perf_level, u32 dll_val,
+ u32 mem_type);
+
+void omap2_sram_reprogram_sdrc(u32 perf_level, u32 dll_val, u32 mem_type)
+{
+ if (!_omap2_sram_reprogram_sdrc)
+ omap_sram_error();
+
+ return _omap2_sram_reprogram_sdrc(perf_level, dll_val, mem_type);
+}
+
+static u32 (*_omap2_set_prcm)(u32 dpll_ctrl_val, u32 sdrc_rfr_val, int bypass);
+
+u32 omap2_set_prcm(u32 dpll_ctrl_val, u32 sdrc_rfr_val, int bypass)
+{
+ if (!_omap2_set_prcm)
+ omap_sram_error();
+
+ return _omap2_set_prcm(dpll_ctrl_val, sdrc_rfr_val, bypass);
+}
+
+int __init omap2_sram_init(void)
+{
+ _omap2_sram_ddr_init = omap_sram_push(sram_ddr_init, sram_ddr_init_sz);
+
+ _omap2_sram_reprogram_sdrc = omap_sram_push(sram_reprogram_sdrc,
+ sram_reprogram_sdrc_sz);
+ _omap2_set_prcm = omap_sram_push(sram_set_prcm, sram_set_prcm_sz);
+
+ return 0;
+}
+#else
+#define omap2_sram_init() do {} while (0)
+#endif
+
+int __init omap_sram_init(void)
+{
+ omap_detect_sram();
+ omap_map_sram();
+
+ if (!cpu_is_omap24xx())
+ omap1_sram_init();
+ else
+ omap2_sram_init();
+
+ return 0;
}
diff --git a/arch/arm/plat-omap/sram.h b/arch/arm/plat-omap/sram.h
deleted file mode 100644
index 71984efa6ae8..000000000000
--- a/arch/arm/plat-omap/sram.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * linux/arch/arm/plat-omap/sram.h
- *
- * Interface for functions that need to be run in internal SRAM
- *
- * 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 __ARCH_ARM_OMAP_SRAM_H
-#define __ARCH_ARM_OMAP_SRAM_H
-
-extern void * omap_sram_push(void * start, unsigned long size);
-extern void omap_sram_reprogram_clock(u32 dpllctl, u32 ckctl);
-
-/* Do not use these */
-extern void sram_reprogram_clock(u32 ckctl, u32 dpllctl);
-extern unsigned long sram_reprogram_clock_sz;
-
-#endif
diff --git a/arch/arm/plat-omap/usb.c b/arch/arm/plat-omap/usb.c
index 14a836d7ac25..00afc7a8c2ab 100644
--- a/arch/arm/plat-omap/usb.c
+++ b/arch/arm/plat-omap/usb.c
@@ -26,7 +26,7 @@
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/init.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <linux/usb_otg.h>
#include <asm/io.h>
@@ -91,6 +91,8 @@ EXPORT_SYMBOL(otg_set_transceiver);
/*-------------------------------------------------------------------------*/
+#if defined(CONFIG_ARCH_OMAP_OTG) || defined(CONFIG_ARCH_OMAP15XX)
+
static u32 __init omap_usb0_init(unsigned nwires, unsigned is_device)
{
u32 syscon1 = 0;
@@ -271,6 +273,8 @@ static u32 __init omap_usb2_init(unsigned nwires, unsigned alt_pingroup)
return syscon1 << 24;
}
+#endif
+
/*-------------------------------------------------------------------------*/
#if defined(CONFIG_USB_GADGET_OMAP) || \
@@ -494,7 +498,7 @@ static inline void omap_otg_init(struct omap_usb_config *config) {}
/*-------------------------------------------------------------------------*/
-#ifdef CONFIG_ARCH_OMAP1510
+#ifdef CONFIG_ARCH_OMAP15XX
#define ULPD_DPLL_CTRL_REG __REG16(ULPD_DPLL_CTRL)
#define DPLL_IOB (1 << 13)
@@ -507,7 +511,6 @@ static inline void omap_otg_init(struct omap_usb_config *config) {}
static void __init omap_1510_usb_init(struct omap_usb_config *config)
{
- int status;
unsigned int val;
omap_usb0_init(config->pins[0], is_usb0_device(config));
@@ -539,6 +542,8 @@ static void __init omap_1510_usb_init(struct omap_usb_config *config)
#ifdef CONFIG_USB_GADGET_OMAP
if (config->register_dev) {
+ int status;
+
udc_device.dev.platform_data = config;
status = platform_device_register(&udc_device);
if (status)
@@ -549,6 +554,8 @@ static void __init omap_1510_usb_init(struct omap_usb_config *config)
#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
if (config->register_host) {
+ int status;
+
ohci_device.dev.platform_data = config;
status = platform_device_register(&ohci_device);
if (status)
diff --git a/arch/arm26/kernel/process.c b/arch/arm26/kernel/process.c
index 9eb9964d32a7..15833a0057dd 100644
--- a/arch/arm26/kernel/process.c
+++ b/arch/arm26/kernel/process.c
@@ -74,15 +74,13 @@ __setup("hlt", hlt_setup);
void cpu_idle(void)
{
/* endless idle loop with no priority at all */
- preempt_disable();
while (1) {
- while (!need_resched()) {
- local_irq_disable();
- if (!need_resched() && !hlt_counter)
- local_irq_enable();
- }
+ while (!need_resched())
+ cpu_relax();
+ preempt_enable_no_resched();
+ schedule();
+ preempt_disable();
}
- schedule();
}
static char reboot_mode = 'h';
diff --git a/arch/arm26/kernel/ptrace.c b/arch/arm26/kernel/ptrace.c
index 8a52124de0e1..4e6b7356a722 100644
--- a/arch/arm26/kernel/ptrace.c
+++ b/arch/arm26/kernel/ptrace.c
@@ -546,7 +546,7 @@ static int ptrace_setfpregs(struct task_struct *tsk, void *ufp)
sizeof(struct user_fp)) ? -EFAULT : 0;
}
-static int do_ptrace(int request, struct task_struct *child, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request, long addr, long data)
{
unsigned long tmp;
int ret;
@@ -665,53 +665,6 @@ static int do_ptrace(int request, struct task_struct *child, long addr, long dat
return ret;
}
-asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
-{
- struct task_struct *child;
- int ret;
-
- lock_kernel();
- ret = -EPERM;
- if (request == PTRACE_TRACEME) {
- /* are we already being traced? */
- if (current->ptrace & PT_PTRACED)
- goto out;
- ret = security_ptrace(current->parent, current);
- if (ret)
- goto out;
- /* set the ptrace bit in the process flags. */
- current->ptrace |= PT_PTRACED;
- ret = 0;
- goto out;
- }
- ret = -ESRCH;
- read_lock(&tasklist_lock);
- child = find_task_by_pid(pid);
- if (child)
- get_task_struct(child);
- read_unlock(&tasklist_lock);
- if (!child)
- goto out;
-
- ret = -EPERM;
- if (pid == 1) /* you may not mess with init */
- goto out_tsk;
-
- if (request == PTRACE_ATTACH) {
- ret = ptrace_attach(child);
- goto out_tsk;
- }
- ret = ptrace_check_attach(child, request == PTRACE_KILL);
- if (ret == 0)
- ret = do_ptrace(request, child, addr, data);
-
-out_tsk:
- put_task_struct(child);
-out:
- unlock_kernel();
- return ret;
-}
-
asmlinkage void syscall_trace(int why, struct pt_regs *regs)
{
unsigned long ip;
diff --git a/arch/arm26/kernel/time.c b/arch/arm26/kernel/time.c
index e66aedd02fad..335525339ad6 100644
--- a/arch/arm26/kernel/time.c
+++ b/arch/arm26/kernel/time.c
@@ -34,10 +34,6 @@
#include <asm/irq.h>
#include <asm/ioc.h>
-u64 jiffies_64 = INITIAL_JIFFIES;
-
-EXPORT_SYMBOL(jiffies_64);
-
extern unsigned long wall_jiffies;
/* this needs a better home */
diff --git a/arch/arm26/mm/memc.c b/arch/arm26/mm/memc.c
index 8e8a2bb2487d..34def6397c3c 100644
--- a/arch/arm26/mm/memc.c
+++ b/arch/arm26/mm/memc.c
@@ -79,12 +79,6 @@ pgd_t *get_pgd_slow(struct mm_struct *mm)
goto no_pgd;
/*
- * This lock is here just to satisfy pmd_alloc and pte_lock
- * FIXME: I bet we could avoid taking it pretty much altogether
- */
- spin_lock(&mm->page_table_lock);
-
- /*
* On ARM, first page must always be allocated since it contains
* the machine vectors.
*/
@@ -92,7 +86,7 @@ pgd_t *get_pgd_slow(struct mm_struct *mm)
if (!new_pmd)
goto no_pmd;
- new_pte = pte_alloc_kernel(mm, new_pmd, 0);
+ new_pte = pte_alloc_map(mm, new_pmd, 0);
if (!new_pte)
goto no_pte;
@@ -101,6 +95,7 @@ pgd_t *get_pgd_slow(struct mm_struct *mm)
init_pte = pte_offset(init_pmd, 0);
set_pte(new_pte, *init_pte);
+ pte_unmap(new_pte);
/*
* the page table entries are zeroed
@@ -112,23 +107,14 @@ pgd_t *get_pgd_slow(struct mm_struct *mm)
memcpy(new_pgd + FIRST_KERNEL_PGD_NR, init_pgd + FIRST_KERNEL_PGD_NR,
(PTRS_PER_PGD - FIRST_KERNEL_PGD_NR) * sizeof(pgd_t));
- spin_unlock(&mm->page_table_lock);
-
/* update MEMC tables */
cpu_memc_update_all(new_pgd);
return new_pgd;
no_pte:
- spin_unlock(&mm->page_table_lock);
pmd_free(new_pmd);
- free_pgd_slow(new_pgd);
- return NULL;
-
no_pmd:
- spin_unlock(&mm->page_table_lock);
free_pgd_slow(new_pgd);
- return NULL;
-
no_pgd:
return NULL;
}
diff --git a/arch/cris/arch-v10/README.mm b/arch/cris/arch-v10/README.mm
index 6f08903f3139..517d1f027fe8 100644
--- a/arch/cris/arch-v10/README.mm
+++ b/arch/cris/arch-v10/README.mm
@@ -177,7 +177,7 @@ The example address is 0xd004000c; in binary this is:
Given the top-level Page Directory, the offset in that directory is calculated
using the upper 8 bits:
-extern inline pgd_t * pgd_offset(struct mm_struct * mm, unsigned long address)
+static inline pgd_t * pgd_offset(struct mm_struct * mm, unsigned long address)
{
return mm->pgd + (address >> PGDIR_SHIFT);
}
@@ -190,14 +190,14 @@ The pgd_t from our example will therefore be the 208'th (0xd0) entry in mm->pgd.
Since the Middle Directory does not exist, it is a unity mapping:
-extern inline pmd_t * pmd_offset(pgd_t * dir, unsigned long address)
+static inline pmd_t * pmd_offset(pgd_t * dir, unsigned long address)
{
return (pmd_t *) dir;
}
The Page Table provides the final lookup by using bits 13 to 23 as index:
-extern inline pte_t * pte_offset(pmd_t * dir, unsigned long address)
+static inline pte_t * pte_offset(pmd_t * dir, unsigned long address)
{
return (pte_t *) pmd_page(*dir) + ((address >> PAGE_SHIFT) &
(PTRS_PER_PTE - 1));
diff --git a/arch/cris/arch-v10/drivers/axisflashmap.c b/arch/cris/arch-v10/drivers/axisflashmap.c
index 11ab3836aac6..56b038c8d482 100644
--- a/arch/cris/arch-v10/drivers/axisflashmap.c
+++ b/arch/cris/arch-v10/drivers/axisflashmap.c
@@ -140,6 +140,7 @@
#include <linux/kernel.h>
#include <linux/config.h>
#include <linux/init.h>
+#include <linux/slab.h>
#include <linux/mtd/concat.h>
#include <linux/mtd/map.h>
diff --git a/arch/cris/arch-v10/drivers/pcf8563.c b/arch/cris/arch-v10/drivers/pcf8563.c
index 201f4c90d961..f2c55742e90c 100644
--- a/arch/cris/arch-v10/drivers/pcf8563.c
+++ b/arch/cris/arch-v10/drivers/pcf8563.c
@@ -19,7 +19,6 @@
*/
#include <linux/config.h>
-#include <linux/version.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/types.h>
diff --git a/arch/cris/arch-v10/kernel/fasttimer.c b/arch/cris/arch-v10/kernel/fasttimer.c
index 094ff45ae85b..cac05a5e514c 100644
--- a/arch/cris/arch-v10/kernel/fasttimer.c
+++ b/arch/cris/arch-v10/kernel/fasttimer.c
@@ -112,7 +112,6 @@
#include <asm/rtc.h>
#include <linux/config.h>
-#include <linux/version.h>
#include <asm/arch/svinto.h>
#include <asm/fasttimer.h>
diff --git a/arch/cris/arch-v10/kernel/ptrace.c b/arch/cris/arch-v10/kernel/ptrace.c
index 130dd214e41d..6cbd34a27b90 100644
--- a/arch/cris/arch-v10/kernel/ptrace.c
+++ b/arch/cris/arch-v10/kernel/ptrace.c
@@ -76,55 +76,11 @@ ptrace_disable(struct task_struct *child)
* (in user space) where the result of the ptrace call is written (instead of
* being returned).
*/
-asmlinkage int
-sys_ptrace(long request, long pid, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request, long addr, long data)
{
- struct task_struct *child;
int ret;
unsigned long __user *datap = (unsigned long __user *)data;
- lock_kernel();
- ret = -EPERM;
-
- if (request == PTRACE_TRACEME) {
- /* are we already being traced? */
- if (current->ptrace & PT_PTRACED)
- goto out;
- ret = security_ptrace(current->parent, current);
- if (ret)
- goto out;
- /* set the ptrace bit in the process flags. */
- current->ptrace |= PT_PTRACED;
- ret = 0;
- goto out;
- }
-
- ret = -ESRCH;
- read_lock(&tasklist_lock);
- child = find_task_by_pid(pid);
-
- if (child)
- get_task_struct(child);
-
- read_unlock(&tasklist_lock);
-
- if (!child)
- goto out;
-
- ret = -EPERM;
-
- if (pid == 1) /* Leave the init process alone! */
- goto out_tsk;
-
- if (request == PTRACE_ATTACH) {
- ret = ptrace_attach(child);
- goto out_tsk;
- }
-
- ret = ptrace_check_attach(child, request == PTRACE_KILL);
- if (ret < 0)
- goto out_tsk;
-
switch (request) {
/* Read word at location address. */
case PTRACE_PEEKTEXT:
@@ -289,10 +245,7 @@ sys_ptrace(long request, long pid, long addr, long data)
ret = ptrace_request(child, request, addr, data);
break;
}
-out_tsk:
- put_task_struct(child);
-out:
- unlock_kernel();
+
return ret;
}
diff --git a/arch/cris/arch-v10/kernel/signal.c b/arch/cris/arch-v10/kernel/signal.c
index 693771961f85..19bcad05716f 100644
--- a/arch/cris/arch-v10/kernel/signal.c
+++ b/arch/cris/arch-v10/kernel/signal.c
@@ -476,7 +476,7 @@ give_sigsegv:
* OK, we're invoking a handler
*/
-extern inline void
+static inline void
handle_signal(int canrestart, unsigned long sig,
siginfo_t *info, struct k_sigaction *ka,
sigset_t *oldset, struct pt_regs * regs)
diff --git a/arch/cris/arch-v32/drivers/axisflashmap.c b/arch/cris/arch-v32/drivers/axisflashmap.c
index 78ed52b1cdac..b679f983b90a 100644
--- a/arch/cris/arch-v32/drivers/axisflashmap.c
+++ b/arch/cris/arch-v32/drivers/axisflashmap.c
@@ -20,6 +20,7 @@
#include <linux/kernel.h>
#include <linux/config.h>
#include <linux/init.h>
+#include <linux/slab.h>
#include <linux/mtd/concat.h>
#include <linux/mtd/map.h>
diff --git a/arch/cris/arch-v32/drivers/cryptocop.c b/arch/cris/arch-v32/drivers/cryptocop.c
index ca72076c630a..501fa52d8d3a 100644
--- a/arch/cris/arch-v32/drivers/cryptocop.c
+++ b/arch/cris/arch-v32/drivers/cryptocop.c
@@ -277,7 +277,7 @@ struct file_operations cryptocop_fops = {
static void free_cdesc(struct cryptocop_dma_desc *cdesc)
{
DEBUG(printk("free_cdesc: cdesc 0x%p, from_pool=%d\n", cdesc, cdesc->from_pool));
- if (cdesc->free_buf) kfree(cdesc->free_buf);
+ kfree(cdesc->free_buf);
if (cdesc->from_pool) {
unsigned long int flags;
@@ -2950,15 +2950,15 @@ static int cryptocop_ioctl_process(struct inode *inode, struct file *filp, unsig
put_page(outpages[i]);
}
- if (digest_result) kfree(digest_result);
- if (inpages) kfree(inpages);
- if (outpages) kfree(outpages);
+ kfree(digest_result);
+ kfree(inpages);
+ kfree(outpages);
if (cop){
- if (cop->tfrm_op.indata) kfree(cop->tfrm_op.indata);
- if (cop->tfrm_op.outdata) kfree(cop->tfrm_op.outdata);
+ kfree(cop->tfrm_op.indata);
+ kfree(cop->tfrm_op.outdata);
kfree(cop);
}
- if (jc) kfree(jc);
+ kfree(jc);
DEBUG(print_lock_status());
diff --git a/arch/cris/arch-v32/drivers/nandflash.c b/arch/cris/arch-v32/drivers/nandflash.c
index fc2a619b035d..93ddea4d9564 100644
--- a/arch/cris/arch-v32/drivers/nandflash.c
+++ b/arch/cris/arch-v32/drivers/nandflash.c
@@ -14,7 +14,6 @@
*
*/
-#include <linux/version.h>
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/module.h>
diff --git a/arch/cris/arch-v32/drivers/pcf8563.c b/arch/cris/arch-v32/drivers/pcf8563.c
index f894580b648b..d788bda3578c 100644
--- a/arch/cris/arch-v32/drivers/pcf8563.c
+++ b/arch/cris/arch-v32/drivers/pcf8563.c
@@ -18,7 +18,6 @@
*/
#include <linux/config.h>
-#include <linux/version.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/types.h>
diff --git a/arch/cris/arch-v32/kernel/ptrace.c b/arch/cris/arch-v32/kernel/ptrace.c
index 208489da2a87..5528b83a622b 100644
--- a/arch/cris/arch-v32/kernel/ptrace.c
+++ b/arch/cris/arch-v32/kernel/ptrace.c
@@ -99,55 +99,11 @@ ptrace_disable(struct task_struct *child)
}
-asmlinkage int
-sys_ptrace(long request, long pid, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request, long addr, long data)
{
- struct task_struct *child;
int ret;
unsigned long __user *datap = (unsigned long __user *)data;
- lock_kernel();
- ret = -EPERM;
-
- if (request == PTRACE_TRACEME) {
- /* are we already being traced? */
- if (current->ptrace & PT_PTRACED)
- goto out;
- ret = security_ptrace(current->parent, current);
- if (ret)
- goto out;
- /* set the ptrace bit in the process flags. */
- current->ptrace |= PT_PTRACED;
- ret = 0;
- goto out;
- }
-
- ret = -ESRCH;
- read_lock(&tasklist_lock);
- child = find_task_by_pid(pid);
-
- if (child)
- get_task_struct(child);
-
- read_unlock(&tasklist_lock);
-
- if (!child)
- goto out;
-
- ret = -EPERM;
-
- if (pid == 1) /* Leave the init process alone! */
- goto out_tsk;
-
- if (request == PTRACE_ATTACH) {
- ret = ptrace_attach(child);
- goto out_tsk;
- }
-
- ret = ptrace_check_attach(child, request == PTRACE_KILL);
- if (ret < 0)
- goto out_tsk;
-
switch (request) {
/* Read word at location address. */
case PTRACE_PEEKTEXT:
@@ -347,10 +303,7 @@ sys_ptrace(long request, long pid, long addr, long data)
ret = ptrace_request(child, request, addr, data);
break;
}
-out_tsk:
- put_task_struct(child);
-out:
- unlock_kernel();
+
return ret;
}
diff --git a/arch/cris/arch-v32/kernel/signal.c b/arch/cris/arch-v32/kernel/signal.c
index 0a3614dab887..99e59b3eacf8 100644
--- a/arch/cris/arch-v32/kernel/signal.c
+++ b/arch/cris/arch-v32/kernel/signal.c
@@ -513,7 +513,7 @@ give_sigsegv:
}
/* Invoke a singal handler to, well, handle the signal. */
-extern inline void
+static inline void
handle_signal(int canrestart, unsigned long sig,
siginfo_t *info, struct k_sigaction *ka,
sigset_t *oldset, struct pt_regs * regs)
diff --git a/arch/cris/arch-v32/kernel/smp.c b/arch/cris/arch-v32/kernel/smp.c
index 957f551ba5ce..13867f4fad16 100644
--- a/arch/cris/arch-v32/kernel/smp.c
+++ b/arch/cris/arch-v32/kernel/smp.c
@@ -161,6 +161,7 @@ void __init smp_callin(void)
REG_WR(intr_vect, irq_regs[cpu], rw_mask, vect_mask);
unmask_irq(IPI_INTR_VECT);
unmask_irq(TIMER_INTR_VECT);
+ preempt_disable();
local_irq_enable();
cpu_set(cpu, cpu_online_map);
diff --git a/arch/cris/arch-v32/mm/tlb.c b/arch/cris/arch-v32/mm/tlb.c
index 8233406798d3..b08a28bb58ab 100644
--- a/arch/cris/arch-v32/mm/tlb.c
+++ b/arch/cris/arch-v32/mm/tlb.c
@@ -175,6 +175,8 @@ init_new_context(struct task_struct *tsk, struct mm_struct *mm)
return 0;
}
+static DEFINE_SPINLOCK(mmu_context_lock);
+
/* Called in schedule() just before actually doing the switch_to. */
void
switch_mm(struct mm_struct *prev, struct mm_struct *next,
@@ -183,10 +185,10 @@ switch_mm(struct mm_struct *prev, struct mm_struct *next,
int cpu = smp_processor_id();
/* Make sure there is a MMU context. */
- spin_lock(&next->page_table_lock);
+ spin_lock(&mmu_context_lock);
get_mmu_context(next);
cpu_set(cpu, next->cpu_vm_mask);
- spin_unlock(&next->page_table_lock);
+ spin_unlock(&mmu_context_lock);
/*
* Remember the pgd for the fault handlers. Keep a seperate copy of it
diff --git a/arch/cris/kernel/process.c b/arch/cris/kernel/process.c
index 949a0e40e03c..7c80afb10460 100644
--- a/arch/cris/kernel/process.c
+++ b/arch/cris/kernel/process.c
@@ -218,7 +218,9 @@ void cpu_idle (void)
idle = default_idle;
idle();
}
+ preempt_enable_no_resched();
schedule();
+ preempt_disable();
}
}
diff --git a/arch/cris/kernel/time.c b/arch/cris/kernel/time.c
index a2d99b4aedcd..66ba8898db07 100644
--- a/arch/cris/kernel/time.c
+++ b/arch/cris/kernel/time.c
@@ -31,10 +31,7 @@
#include <linux/timex.h>
#include <linux/init.h>
#include <linux/profile.h>
-
-u64 jiffies_64 = INITIAL_JIFFIES;
-
-EXPORT_SYMBOL(jiffies_64);
+#include <linux/sched.h> /* just for sched_clock() - funny that */
int have_rtc; /* used to remember if we have an RTC or not */;
diff --git a/arch/cris/mm/ioremap.c b/arch/cris/mm/ioremap.c
index ebba11e270fa..1780df3ed9e5 100644
--- a/arch/cris/mm/ioremap.c
+++ b/arch/cris/mm/ioremap.c
@@ -16,7 +16,7 @@
#include <asm/tlbflush.h>
#include <asm/arch/memmap.h>
-extern inline void remap_area_pte(pte_t * pte, unsigned long address, unsigned long size,
+static inline void remap_area_pte(pte_t * pte, unsigned long address, unsigned long size,
unsigned long phys_addr, pgprot_t prot)
{
unsigned long end;
@@ -52,7 +52,7 @@ static inline int remap_area_pmd(pmd_t * pmd, unsigned long address, unsigned lo
if (address >= end)
BUG();
do {
- pte_t * pte = pte_alloc_kernel(&init_mm, pmd, address);
+ pte_t * pte = pte_alloc_kernel(pmd, address);
if (!pte)
return -ENOMEM;
remap_area_pte(pte, address, end - address, address + phys_addr, prot);
@@ -74,7 +74,6 @@ static int remap_area_pages(unsigned long address, unsigned long phys_addr,
flush_cache_all();
if (address >= end)
BUG();
- spin_lock(&init_mm.page_table_lock);
do {
pud_t *pud;
pmd_t *pmd;
@@ -94,7 +93,6 @@ static int remap_area_pages(unsigned long address, unsigned long phys_addr,
address = (address + PGDIR_SIZE) & PGDIR_MASK;
dir++;
} while (address && (address < end));
- spin_unlock(&init_mm.page_table_lock);
flush_tlb_all();
return error;
}
diff --git a/arch/frv/kernel/process.c b/arch/frv/kernel/process.c
index 3001b82b1514..54a452136f00 100644
--- a/arch/frv/kernel/process.c
+++ b/arch/frv/kernel/process.c
@@ -77,16 +77,20 @@ void (*idle)(void) = core_sleep_idle;
*/
void cpu_idle(void)
{
+ int cpu = smp_processor_id();
+
/* endless idle loop with no priority at all */
while (1) {
while (!need_resched()) {
- irq_stat[smp_processor_id()].idle_timestamp = jiffies;
+ irq_stat[cpu].idle_timestamp = jiffies;
if (!frv_dma_inprogress && idle)
idle();
}
+ preempt_enable_no_resched();
schedule();
+ preempt_disable();
}
}
diff --git a/arch/frv/kernel/ptrace.c b/arch/frv/kernel/ptrace.c
index cbe03cba9f02..f953484e7d59 100644
--- a/arch/frv/kernel/ptrace.c
+++ b/arch/frv/kernel/ptrace.c
@@ -106,48 +106,11 @@ void ptrace_enable(struct task_struct *child)
child->thread.frame0->__status |= REG__STATUS_STEP;
}
-asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request, long addr, long data)
{
- struct task_struct *child;
unsigned long tmp;
int ret;
- lock_kernel();
- ret = -EPERM;
- if (request == PTRACE_TRACEME) {
- /* are we already being traced? */
- if (current->ptrace & PT_PTRACED)
- goto out;
- ret = security_ptrace(current->parent, current);
- if (ret)
- goto out;
- /* set the ptrace bit in the process flags. */
- current->ptrace |= PT_PTRACED;
- ret = 0;
- goto out;
- }
- ret = -ESRCH;
- read_lock(&tasklist_lock);
- child = find_task_by_pid(pid);
- if (child)
- get_task_struct(child);
- read_unlock(&tasklist_lock);
- if (!child)
- goto out;
-
- ret = -EPERM;
- if (pid == 1) /* you may not mess with init */
- goto out_tsk;
-
- if (request == PTRACE_ATTACH) {
- ret = ptrace_attach(child);
- goto out_tsk;
- }
-
- ret = ptrace_check_attach(child, request == PTRACE_KILL);
- if (ret < 0)
- goto out_tsk;
-
switch (request) {
/* when I and D space are separate, these will need to be fixed. */
case PTRACE_PEEKTEXT: /* read word at location addr. */
@@ -351,10 +314,6 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
ret = -EIO;
break;
}
-out_tsk:
- put_task_struct(child);
-out:
- unlock_kernel();
return ret;
}
diff --git a/arch/frv/kernel/time.c b/arch/frv/kernel/time.c
index 8d6558b00e44..2e9741227b73 100644
--- a/arch/frv/kernel/time.c
+++ b/arch/frv/kernel/time.c
@@ -34,9 +34,6 @@
extern unsigned long wall_jiffies;
-u64 jiffies_64 = INITIAL_JIFFIES;
-EXPORT_SYMBOL(jiffies_64);
-
unsigned long __nongprelbss __clkin_clock_speed_HZ;
unsigned long __nongprelbss __ext_bus_clock_speed_HZ;
unsigned long __nongprelbss __res_bus_clock_speed_HZ;
@@ -221,6 +218,7 @@ int do_settimeofday(struct timespec *tv)
clock_was_set();
return 0;
}
+EXPORT_SYMBOL(do_settimeofday);
/*
* Scheduler clock - returns current time in nanosec units.
diff --git a/arch/frv/mb93090-mb00/pci-dma-nommu.c b/arch/frv/mb93090-mb00/pci-dma-nommu.c
index 819895cf0b9e..2082a9647f4f 100644
--- a/arch/frv/mb93090-mb00/pci-dma-nommu.c
+++ b/arch/frv/mb93090-mb00/pci-dma-nommu.c
@@ -33,7 +33,7 @@ struct dma_alloc_record {
static DEFINE_SPINLOCK(dma_alloc_lock);
static LIST_HEAD(dma_alloc_list);
-void *dma_alloc_coherent(struct device *hwdev, size_t size, dma_addr_t *dma_handle, int gfp)
+void *dma_alloc_coherent(struct device *hwdev, size_t size, dma_addr_t *dma_handle, gfp_t gfp)
{
struct dma_alloc_record *new;
struct list_head *this = &dma_alloc_list;
diff --git a/arch/frv/mb93090-mb00/pci-dma.c b/arch/frv/mb93090-mb00/pci-dma.c
index 27eb12066507..86fbdadc51b6 100644
--- a/arch/frv/mb93090-mb00/pci-dma.c
+++ b/arch/frv/mb93090-mb00/pci-dma.c
@@ -17,7 +17,7 @@
#include <linux/highmem.h>
#include <asm/io.h>
-void *dma_alloc_coherent(struct device *hwdev, size_t size, dma_addr_t *dma_handle, int gfp)
+void *dma_alloc_coherent(struct device *hwdev, size_t size, dma_addr_t *dma_handle, gfp_t gfp)
{
void *ret;
diff --git a/arch/frv/mm/dma-alloc.c b/arch/frv/mm/dma-alloc.c
index 4b38d45435f6..342823aad758 100644
--- a/arch/frv/mm/dma-alloc.c
+++ b/arch/frv/mm/dma-alloc.c
@@ -55,21 +55,18 @@ static int map_page(unsigned long va, unsigned long pa, pgprot_t prot)
pte_t *pte;
int err = -ENOMEM;
- spin_lock(&init_mm.page_table_lock);
-
/* Use upper 10 bits of VA to index the first level map */
pge = pgd_offset_k(va);
pue = pud_offset(pge, va);
pme = pmd_offset(pue, va);
/* Use middle 10 bits of VA to index the second-level map */
- pte = pte_alloc_kernel(&init_mm, pme, va);
+ pte = pte_alloc_kernel(pme, va);
if (pte != 0) {
err = 0;
set_pte(pte, mk_pte_phys(pa & PAGE_MASK, prot));
}
- spin_unlock(&init_mm.page_table_lock);
return err;
}
@@ -81,7 +78,7 @@ static int map_page(unsigned long va, unsigned long pa, pgprot_t prot)
* portions of the kernel with single large page TLB entries, and
* still get unique uncached pages for consistent DMA.
*/
-void *consistent_alloc(int gfp, size_t size, dma_addr_t *dma_handle)
+void *consistent_alloc(gfp_t gfp, size_t size, dma_addr_t *dma_handle)
{
struct vm_struct *area;
unsigned long page, va, pa;
diff --git a/arch/frv/mm/pgalloc.c b/arch/frv/mm/pgalloc.c
index 4eaec0f3525b..2c67dfe5a6b3 100644
--- a/arch/frv/mm/pgalloc.c
+++ b/arch/frv/mm/pgalloc.c
@@ -87,14 +87,14 @@ static inline void pgd_list_add(pgd_t *pgd)
if (pgd_list)
pgd_list->private = (unsigned long) &page->index;
pgd_list = page;
- page->private = (unsigned long) &pgd_list;
+ set_page_private(page, (unsigned long)&pgd_list);
}
static inline void pgd_list_del(pgd_t *pgd)
{
struct page *next, **pprev, *page = virt_to_page(pgd);
next = (struct page *) page->index;
- pprev = (struct page **) page->private;
+ pprev = (struct page **)page_private(page);
*pprev = next;
if (next)
next->private = (unsigned long) pprev;
diff --git a/arch/h8300/kernel/process.c b/arch/h8300/kernel/process.c
index 27f1fce64ce4..fe21adf3e75e 100644
--- a/arch/h8300/kernel/process.c
+++ b/arch/h8300/kernel/process.c
@@ -53,22 +53,18 @@ asmlinkage void ret_from_fork(void);
#if !defined(CONFIG_H8300H_SIM) && !defined(CONFIG_H8S_SIM)
void default_idle(void)
{
- while(1) {
- if (!need_resched()) {
- local_irq_enable();
- __asm__("sleep");
- local_irq_disable();
- }
- schedule();
- }
+ local_irq_disable();
+ if (!need_resched()) {
+ local_irq_enable();
+ /* XXX: race here! What if need_resched() gets set now? */
+ __asm__("sleep");
+ } else
+ local_irq_enable();
}
#else
void default_idle(void)
{
- while(1) {
- if (need_resched())
- schedule();
- }
+ cpu_relax();
}
#endif
void (*idle)(void) = default_idle;
@@ -81,7 +77,13 @@ void (*idle)(void) = default_idle;
*/
void cpu_idle(void)
{
- idle();
+ while (1) {
+ while (!need_resched())
+ idle();
+ preempt_enable_no_resched();
+ schedule();
+ preempt_disable();
+ }
}
void machine_restart(char * __unused)
diff --git a/arch/h8300/kernel/ptrace.c b/arch/h8300/kernel/ptrace.c
index 05c15e869777..0ff6f79b0fed 100644
--- a/arch/h8300/kernel/ptrace.c
+++ b/arch/h8300/kernel/ptrace.c
@@ -57,43 +57,10 @@ void ptrace_disable(struct task_struct *child)
h8300_disable_trace(child);
}
-asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request, long addr, long data)
{
- struct task_struct *child;
int ret;
- lock_kernel();
- ret = -EPERM;
- if (request == PTRACE_TRACEME) {
- /* are we already being traced? */
- if (current->ptrace & PT_PTRACED)
- goto out;
- /* set the ptrace bit in the process flags. */
- current->ptrace |= PT_PTRACED;
- ret = 0;
- goto out;
- }
- ret = -ESRCH;
- read_lock(&tasklist_lock);
- child = find_task_by_pid(pid);
- if (child)
- get_task_struct(child);
- read_unlock(&tasklist_lock);
- if (!child)
- goto out;
-
- ret = -EPERM;
- if (pid == 1) /* you may not mess with init */
- goto out_tsk;
-
- if (request == PTRACE_ATTACH) {
- ret = ptrace_attach(child);
- goto out_tsk;
- }
- ret = ptrace_check_attach(child, request == PTRACE_KILL);
- if (ret < 0)
- goto out_tsk;
-
switch (request) {
case PTRACE_PEEKTEXT: /* read word at location addr. */
case PTRACE_PEEKDATA: {
@@ -251,10 +218,6 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
ret = -EIO;
break;
}
-out_tsk:
- put_task_struct(child);
-out:
- unlock_kernel();
return ret;
}
diff --git a/arch/h8300/kernel/time.c b/arch/h8300/kernel/time.c
index af8c5d2057dd..688a5100604c 100644
--- a/arch/h8300/kernel/time.c
+++ b/arch/h8300/kernel/time.c
@@ -32,10 +32,6 @@
#define TICK_SIZE (tick_nsec / 1000)
-u64 jiffies_64;
-
-EXPORT_SYMBOL(jiffies_64);
-
/*
* timer_interrupt() needs to keep up the real-time clock,
* as well as call the "do_timer()" routine every clocktick
diff --git a/arch/i386/Kconfig b/arch/i386/Kconfig
index d2703cda61ea..dbf90ad6eac3 100644
--- a/arch/i386/Kconfig
+++ b/arch/i386/Kconfig
@@ -5,7 +5,7 @@
mainmenu "Linux Kernel Configuration"
-config X86
+config X86_32
bool
default y
help
@@ -18,6 +18,10 @@ config SEMAPHORE_SLEEPERS
bool
default y
+config X86
+ bool
+ default y
+
config MMU
bool
default y
@@ -151,304 +155,7 @@ config ES7000_CLUSTERED_APIC
default y
depends on SMP && X86_ES7000 && MPENTIUMIII
-if !X86_ELAN
-
-choice
- prompt "Processor family"
- default M686
-
-config M386
- bool "386"
- ---help---
- This is the processor type of your CPU. This information is used for
- optimizing purposes. In order to compile a kernel that can run on
- all x86 CPU types (albeit not optimally fast), you can specify
- "386" here.
-
- The kernel will not necessarily run on earlier architectures than
- the one you have chosen, e.g. a Pentium optimized kernel will run on
- a PPro, but not necessarily on a i486.
-
- Here are the settings recommended for greatest speed:
- - "386" for the AMD/Cyrix/Intel 386DX/DXL/SL/SLC/SX, Cyrix/TI
- 486DLC/DLC2, UMC 486SX-S and NexGen Nx586. Only "386" kernels
- will run on a 386 class machine.
- - "486" for the AMD/Cyrix/IBM/Intel 486DX/DX2/DX4 or
- SL/SLC/SLC2/SLC3/SX/SX2 and UMC U5D or U5S.
- - "586" for generic Pentium CPUs lacking the TSC
- (time stamp counter) register.
- - "Pentium-Classic" for the Intel Pentium.
- - "Pentium-MMX" for the Intel Pentium MMX.
- - "Pentium-Pro" for the Intel Pentium Pro.
- - "Pentium-II" for the Intel Pentium II or pre-Coppermine Celeron.
- - "Pentium-III" for the Intel Pentium III or Coppermine Celeron.
- - "Pentium-4" for the Intel Pentium 4 or P4-based Celeron.
- - "K6" for the AMD K6, K6-II and K6-III (aka K6-3D).
- - "Athlon" for the AMD K7 family (Athlon/Duron/Thunderbird).
- - "Crusoe" for the Transmeta Crusoe series.
- - "Efficeon" for the Transmeta Efficeon series.
- - "Winchip-C6" for original IDT Winchip.
- - "Winchip-2" for IDT Winchip 2.
- - "Winchip-2A" for IDT Winchips with 3dNow! capabilities.
- - "GeodeGX1" for Geode GX1 (Cyrix MediaGX).
- - "CyrixIII/VIA C3" for VIA Cyrix III or VIA C3.
- - "VIA C3-2 for VIA C3-2 "Nehemiah" (model 9 and above).
-
- If you don't know what to do, choose "386".
-
-config M486
- bool "486"
- help
- Select this for a 486 series processor, either Intel or one of the
- compatible processors from AMD, Cyrix, IBM, or Intel. Includes DX,
- DX2, and DX4 variants; also SL/SLC/SLC2/SLC3/SX/SX2 and UMC U5D or
- U5S.
-
-config M586
- bool "586/K5/5x86/6x86/6x86MX"
- help
- Select this for an 586 or 686 series processor such as the AMD K5,
- the Cyrix 5x86, 6x86 and 6x86MX. This choice does not
- assume the RDTSC (Read Time Stamp Counter) instruction.
-
-config M586TSC
- bool "Pentium-Classic"
- help
- Select this for a Pentium Classic processor with the RDTSC (Read
- Time Stamp Counter) instruction for benchmarking.
-
-config M586MMX
- bool "Pentium-MMX"
- help
- Select this for a Pentium with the MMX graphics/multimedia
- extended instructions.
-
-config M686
- bool "Pentium-Pro"
- help
- Select this for Intel Pentium Pro chips. This enables the use of
- Pentium Pro extended instructions, and disables the init-time guard
- against the f00f bug found in earlier Pentiums.
-
-config MPENTIUMII
- bool "Pentium-II/Celeron(pre-Coppermine)"
- help
- Select this for Intel chips based on the Pentium-II and
- pre-Coppermine Celeron core. This option enables an unaligned
- copy optimization, compiles the kernel with optimization flags
- tailored for the chip, and applies any applicable Pentium Pro
- optimizations.
-
-config MPENTIUMIII
- bool "Pentium-III/Celeron(Coppermine)/Pentium-III Xeon"
- help
- Select this for Intel chips based on the Pentium-III and
- Celeron-Coppermine core. This option enables use of some
- extended prefetch instructions in addition to the Pentium II
- extensions.
-
-config MPENTIUMM
- bool "Pentium M"
- help
- Select this for Intel Pentium M (not Pentium-4 M)
- notebook chips.
-
-config MPENTIUM4
- bool "Pentium-4/Celeron(P4-based)/Pentium-4 M/Xeon"
- help
- Select this for Intel Pentium 4 chips. This includes the
- Pentium 4, P4-based Celeron and Xeon, and Pentium-4 M
- (not Pentium M) chips. This option enables compile flags
- optimized for the chip, uses the correct cache shift, and
- applies any applicable Pentium III optimizations.
-
-config MK6
- bool "K6/K6-II/K6-III"
- help
- Select this for an AMD K6-family processor. Enables use of
- some extended instructions, and passes appropriate optimization
- flags to GCC.
-
-config MK7
- bool "Athlon/Duron/K7"
- help
- Select this for an AMD Athlon K7-family processor. Enables use of
- some extended instructions, and passes appropriate optimization
- flags to GCC.
-
-config MK8
- bool "Opteron/Athlon64/Hammer/K8"
- help
- Select this for an AMD Opteron or Athlon64 Hammer-family processor. Enables
- use of some extended instructions, and passes appropriate optimization
- flags to GCC.
-
-config MCRUSOE
- bool "Crusoe"
- help
- Select this for a Transmeta Crusoe processor. Treats the processor
- like a 586 with TSC, and sets some GCC optimization flags (like a
- Pentium Pro with no alignment requirements).
-
-config MEFFICEON
- bool "Efficeon"
- help
- Select this for a Transmeta Efficeon processor.
-
-config MWINCHIPC6
- bool "Winchip-C6"
- help
- Select this for an IDT Winchip C6 chip. Linux and GCC
- treat this chip as a 586TSC with some extended instructions
- and alignment requirements.
-
-config MWINCHIP2
- bool "Winchip-2"
- help
- Select this for an IDT Winchip-2. Linux and GCC
- treat this chip as a 586TSC with some extended instructions
- and alignment requirements.
-
-config MWINCHIP3D
- bool "Winchip-2A/Winchip-3"
- help
- Select this for an IDT Winchip-2A or 3. Linux and GCC
- treat this chip as a 586TSC with some extended instructions
- and alignment reqirements. Also enable out of order memory
- stores for this CPU, which can increase performance of some
- operations.
-
-config MGEODEGX1
- bool "GeodeGX1"
- help
- Select this for a Geode GX1 (Cyrix MediaGX) chip.
-
-config MCYRIXIII
- bool "CyrixIII/VIA-C3"
- help
- Select this for a Cyrix III or C3 chip. Presently Linux and GCC
- treat this chip as a generic 586. Whilst the CPU is 686 class,
- it lacks the cmov extension which gcc assumes is present when
- generating 686 code.
- Note that Nehemiah (Model 9) and above will not boot with this
- kernel due to them lacking the 3DNow! instructions used in earlier
- incarnations of the CPU.
-
-config MVIAC3_2
- bool "VIA C3-2 (Nehemiah)"
- help
- Select this for a VIA C3 "Nehemiah". Selecting this enables usage
- of SSE and tells gcc to treat the CPU as a 686.
- Note, this kernel will not boot on older (pre model 9) C3s.
-
-endchoice
-
-config X86_GENERIC
- bool "Generic x86 support"
- help
- Instead of just including optimizations for the selected
- x86 variant (e.g. PII, Crusoe or Athlon), include some more
- generic optimizations as well. This will make the kernel
- perform better on x86 CPUs other than that selected.
-
- This is really intended for distributors who need more
- generic optimizations.
-
-endif
-
-#
-# Define implied options from the CPU selection here
-#
-config X86_CMPXCHG
- bool
- depends on !M386
- default y
-
-config X86_XADD
- bool
- depends on !M386
- default y
-
-config X86_L1_CACHE_SHIFT
- int
- default "7" if MPENTIUM4 || X86_GENERIC
- default "4" if X86_ELAN || M486 || M386
- default "5" if MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCRUSOE || MEFFICEON || MCYRIXIII || MK6 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || MVIAC3_2 || MGEODEGX1
- default "6" if MK7 || MK8 || MPENTIUMM
-
-config RWSEM_GENERIC_SPINLOCK
- bool
- depends on M386
- default y
-
-config RWSEM_XCHGADD_ALGORITHM
- bool
- depends on !M386
- default y
-
-config GENERIC_CALIBRATE_DELAY
- bool
- default y
-
-config X86_PPRO_FENCE
- bool
- depends on M686 || M586MMX || M586TSC || M586 || M486 || M386 || MGEODEGX1
- default y
-
-config X86_F00F_BUG
- bool
- depends on M586MMX || M586TSC || M586 || M486 || M386
- default y
-
-config X86_WP_WORKS_OK
- bool
- depends on !M386
- default y
-
-config X86_INVLPG
- bool
- depends on !M386
- default y
-
-config X86_BSWAP
- bool
- depends on !M386
- default y
-
-config X86_POPAD_OK
- bool
- depends on !M386
- default y
-
-config X86_ALIGNMENT_16
- bool
- depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK6 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODEGX1
- default y
-
-config X86_GOOD_APIC
- bool
- depends on MK7 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || MK8 || MEFFICEON
- default y
-
-config X86_INTEL_USERCOPY
- bool
- depends on MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M586MMX || X86_GENERIC || MK8 || MK7 || MEFFICEON
- default y
-
-config X86_USE_PPRO_CHECKSUM
- bool
- depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MK8 || MVIAC3_2 || MEFFICEON
- default y
-
-config X86_USE_3DNOW
- bool
- depends on MCYRIXIII || MK7
- default y
-
-config X86_OOSTORE
- bool
- depends on (MWINCHIP3D || MWINCHIP2 || MWINCHIPC6) && MTRR
- default y
+source "arch/i386/Kconfig.cpu"
config HPET_TIMER
bool "HPET Timer Support"
@@ -561,11 +268,6 @@ config X86_VISWS_APIC
depends on X86_VISWS
default y
-config X86_TSC
- bool
- depends on (MWINCHIP3D || MWINCHIP2 || MCRUSOE || MEFFICEON || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || MK8 || MVIAC3_2 || MGEODEGX1) && !X86_NUMAQ
- default y
-
config X86_MCE
bool "Machine Check Exception"
depends on !X86_VOYAGER
@@ -1295,8 +997,21 @@ source "drivers/Kconfig"
source "fs/Kconfig"
+menu "Instrumentation Support"
+ depends on EXPERIMENTAL
+
source "arch/i386/oprofile/Kconfig"
+config KPROBES
+ bool "Kprobes (EXPERIMENTAL)"
+ help
+ Kprobes allows you to trap at almost any kernel address and
+ execute a callback function. register_kprobe() establishes
+ a probepoint and specifies the callback. Kprobes is useful
+ for kernel debugging, non-intrusive instrumentation and testing.
+ If in doubt, say "N".
+endmenu
+
source "arch/i386/Kconfig.debug"
source "security/Kconfig"
@@ -1340,8 +1055,3 @@ config X86_TRAMPOLINE
bool
depends on X86_SMP || (X86_VOYAGER && SMP)
default y
-
-config PC
- bool
- depends on X86 && !EMBEDDED
- default y
diff --git a/arch/i386/Kconfig.cpu b/arch/i386/Kconfig.cpu
new file mode 100644
index 000000000000..53bbb3c008ee
--- /dev/null
+++ b/arch/i386/Kconfig.cpu
@@ -0,0 +1,309 @@
+# Put here option for CPU selection and depending optimization
+if !X86_ELAN
+
+choice
+ prompt "Processor family"
+ default M686
+
+config M386
+ bool "386"
+ ---help---
+ This is the processor type of your CPU. This information is used for
+ optimizing purposes. In order to compile a kernel that can run on
+ all x86 CPU types (albeit not optimally fast), you can specify
+ "386" here.
+
+ The kernel will not necessarily run on earlier architectures than
+ the one you have chosen, e.g. a Pentium optimized kernel will run on
+ a PPro, but not necessarily on a i486.
+
+ Here are the settings recommended for greatest speed:
+ - "386" for the AMD/Cyrix/Intel 386DX/DXL/SL/SLC/SX, Cyrix/TI
+ 486DLC/DLC2, UMC 486SX-S and NexGen Nx586. Only "386" kernels
+ will run on a 386 class machine.
+ - "486" for the AMD/Cyrix/IBM/Intel 486DX/DX2/DX4 or
+ SL/SLC/SLC2/SLC3/SX/SX2 and UMC U5D or U5S.
+ - "586" for generic Pentium CPUs lacking the TSC
+ (time stamp counter) register.
+ - "Pentium-Classic" for the Intel Pentium.
+ - "Pentium-MMX" for the Intel Pentium MMX.
+ - "Pentium-Pro" for the Intel Pentium Pro.
+ - "Pentium-II" for the Intel Pentium II or pre-Coppermine Celeron.
+ - "Pentium-III" for the Intel Pentium III or Coppermine Celeron.
+ - "Pentium-4" for the Intel Pentium 4 or P4-based Celeron.
+ - "K6" for the AMD K6, K6-II and K6-III (aka K6-3D).
+ - "Athlon" for the AMD K7 family (Athlon/Duron/Thunderbird).
+ - "Crusoe" for the Transmeta Crusoe series.
+ - "Efficeon" for the Transmeta Efficeon series.
+ - "Winchip-C6" for original IDT Winchip.
+ - "Winchip-2" for IDT Winchip 2.
+ - "Winchip-2A" for IDT Winchips with 3dNow! capabilities.
+ - "GeodeGX1" for Geode GX1 (Cyrix MediaGX).
+ - "CyrixIII/VIA C3" for VIA Cyrix III or VIA C3.
+ - "VIA C3-2 for VIA C3-2 "Nehemiah" (model 9 and above).
+
+ If you don't know what to do, choose "386".
+
+config M486
+ bool "486"
+ help
+ Select this for a 486 series processor, either Intel or one of the
+ compatible processors from AMD, Cyrix, IBM, or Intel. Includes DX,
+ DX2, and DX4 variants; also SL/SLC/SLC2/SLC3/SX/SX2 and UMC U5D or
+ U5S.
+
+config M586
+ bool "586/K5/5x86/6x86/6x86MX"
+ help
+ Select this for an 586 or 686 series processor such as the AMD K5,
+ the Cyrix 5x86, 6x86 and 6x86MX. This choice does not
+ assume the RDTSC (Read Time Stamp Counter) instruction.
+
+config M586TSC
+ bool "Pentium-Classic"
+ help
+ Select this for a Pentium Classic processor with the RDTSC (Read
+ Time Stamp Counter) instruction for benchmarking.
+
+config M586MMX
+ bool "Pentium-MMX"
+ help
+ Select this for a Pentium with the MMX graphics/multimedia
+ extended instructions.
+
+config M686
+ bool "Pentium-Pro"
+ help
+ Select this for Intel Pentium Pro chips. This enables the use of
+ Pentium Pro extended instructions, and disables the init-time guard
+ against the f00f bug found in earlier Pentiums.
+
+config MPENTIUMII
+ bool "Pentium-II/Celeron(pre-Coppermine)"
+ help
+ Select this for Intel chips based on the Pentium-II and
+ pre-Coppermine Celeron core. This option enables an unaligned
+ copy optimization, compiles the kernel with optimization flags
+ tailored for the chip, and applies any applicable Pentium Pro
+ optimizations.
+
+config MPENTIUMIII
+ bool "Pentium-III/Celeron(Coppermine)/Pentium-III Xeon"
+ help
+ Select this for Intel chips based on the Pentium-III and
+ Celeron-Coppermine core. This option enables use of some
+ extended prefetch instructions in addition to the Pentium II
+ extensions.
+
+config MPENTIUMM
+ bool "Pentium M"
+ help
+ Select this for Intel Pentium M (not Pentium-4 M)
+ notebook chips.
+
+config MPENTIUM4
+ bool "Pentium-4/Celeron(P4-based)/Pentium-4 M/Xeon"
+ help
+ Select this for Intel Pentium 4 chips. This includes the
+ Pentium 4, P4-based Celeron and Xeon, and Pentium-4 M
+ (not Pentium M) chips. This option enables compile flags
+ optimized for the chip, uses the correct cache shift, and
+ applies any applicable Pentium III optimizations.
+
+config MK6
+ bool "K6/K6-II/K6-III"
+ help
+ Select this for an AMD K6-family processor. Enables use of
+ some extended instructions, and passes appropriate optimization
+ flags to GCC.
+
+config MK7
+ bool "Athlon/Duron/K7"
+ help
+ Select this for an AMD Athlon K7-family processor. Enables use of
+ some extended instructions, and passes appropriate optimization
+ flags to GCC.
+
+config MK8
+ bool "Opteron/Athlon64/Hammer/K8"
+ help
+ Select this for an AMD Opteron or Athlon64 Hammer-family processor. Enables
+ use of some extended instructions, and passes appropriate optimization
+ flags to GCC.
+
+config MCRUSOE
+ bool "Crusoe"
+ help
+ Select this for a Transmeta Crusoe processor. Treats the processor
+ like a 586 with TSC, and sets some GCC optimization flags (like a
+ Pentium Pro with no alignment requirements).
+
+config MEFFICEON
+ bool "Efficeon"
+ help
+ Select this for a Transmeta Efficeon processor.
+
+config MWINCHIPC6
+ bool "Winchip-C6"
+ help
+ Select this for an IDT Winchip C6 chip. Linux and GCC
+ treat this chip as a 586TSC with some extended instructions
+ and alignment requirements.
+
+config MWINCHIP2
+ bool "Winchip-2"
+ help
+ Select this for an IDT Winchip-2. Linux and GCC
+ treat this chip as a 586TSC with some extended instructions
+ and alignment requirements.
+
+config MWINCHIP3D
+ bool "Winchip-2A/Winchip-3"
+ help
+ Select this for an IDT Winchip-2A or 3. Linux and GCC
+ treat this chip as a 586TSC with some extended instructions
+ and alignment reqirements. Also enable out of order memory
+ stores for this CPU, which can increase performance of some
+ operations.
+
+config MGEODEGX1
+ bool "GeodeGX1"
+ help
+ Select this for a Geode GX1 (Cyrix MediaGX) chip.
+
+config MCYRIXIII
+ bool "CyrixIII/VIA-C3"
+ help
+ Select this for a Cyrix III or C3 chip. Presently Linux and GCC
+ treat this chip as a generic 586. Whilst the CPU is 686 class,
+ it lacks the cmov extension which gcc assumes is present when
+ generating 686 code.
+ Note that Nehemiah (Model 9) and above will not boot with this
+ kernel due to them lacking the 3DNow! instructions used in earlier
+ incarnations of the CPU.
+
+config MVIAC3_2
+ bool "VIA C3-2 (Nehemiah)"
+ help
+ Select this for a VIA C3 "Nehemiah". Selecting this enables usage
+ of SSE and tells gcc to treat the CPU as a 686.
+ Note, this kernel will not boot on older (pre model 9) C3s.
+
+endchoice
+
+config X86_GENERIC
+ bool "Generic x86 support"
+ help
+ Instead of just including optimizations for the selected
+ x86 variant (e.g. PII, Crusoe or Athlon), include some more
+ generic optimizations as well. This will make the kernel
+ perform better on x86 CPUs other than that selected.
+
+ This is really intended for distributors who need more
+ generic optimizations.
+
+endif
+
+#
+# Define implied options from the CPU selection here
+#
+config X86_CMPXCHG
+ bool
+ depends on !M386
+ default y
+
+config X86_XADD
+ bool
+ depends on !M386
+ default y
+
+config X86_L1_CACHE_SHIFT
+ int
+ default "7" if MPENTIUM4 || X86_GENERIC
+ default "4" if X86_ELAN || M486 || M386
+ default "5" if MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCRUSOE || MEFFICEON || MCYRIXIII || MK6 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || MVIAC3_2 || MGEODEGX1
+ default "6" if MK7 || MK8 || MPENTIUMM
+
+config RWSEM_GENERIC_SPINLOCK
+ bool
+ depends on M386
+ default y
+
+config RWSEM_XCHGADD_ALGORITHM
+ bool
+ depends on !M386
+ default y
+
+config GENERIC_CALIBRATE_DELAY
+ bool
+ default y
+
+config X86_PPRO_FENCE
+ bool
+ depends on M686 || M586MMX || M586TSC || M586 || M486 || M386 || MGEODEGX1
+ default y
+
+config X86_F00F_BUG
+ bool
+ depends on M586MMX || M586TSC || M586 || M486 || M386
+ default y
+
+config X86_WP_WORKS_OK
+ bool
+ depends on !M386
+ default y
+
+config X86_INVLPG
+ bool
+ depends on !M386
+ default y
+
+config X86_BSWAP
+ bool
+ depends on !M386
+ default y
+
+config X86_POPAD_OK
+ bool
+ depends on !M386
+ default y
+
+config X86_CMPXCHG64
+ bool
+ depends on !M386 && !M486
+ default y
+
+config X86_ALIGNMENT_16
+ bool
+ depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK6 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODEGX1
+ default y
+
+config X86_GOOD_APIC
+ bool
+ depends on MK7 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || MK8 || MEFFICEON
+ default y
+
+config X86_INTEL_USERCOPY
+ bool
+ depends on MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M586MMX || X86_GENERIC || MK8 || MK7 || MEFFICEON
+ default y
+
+config X86_USE_PPRO_CHECKSUM
+ bool
+ depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MK8 || MVIAC3_2 || MEFFICEON
+ default y
+
+config X86_USE_3DNOW
+ bool
+ depends on MCYRIXIII || MK7
+ default y
+
+config X86_OOSTORE
+ bool
+ depends on (MWINCHIP3D || MWINCHIP2 || MWINCHIPC6) && MTRR
+ default y
+
+config X86_TSC
+ bool
+ depends on (MWINCHIP3D || MWINCHIP2 || MCRUSOE || MEFFICEON || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || MK8 || MVIAC3_2 || MGEODEGX1) && !X86_NUMAQ
+ default y
diff --git a/arch/i386/Kconfig.debug b/arch/i386/Kconfig.debug
index 5228c40a6fb2..c48b424dd640 100644
--- a/arch/i386/Kconfig.debug
+++ b/arch/i386/Kconfig.debug
@@ -22,16 +22,6 @@ config DEBUG_STACKOVERFLOW
This option will cause messages to be printed if free stack space
drops below a certain limit.
-config KPROBES
- bool "Kprobes"
- depends on DEBUG_KERNEL
- help
- Kprobes allows you to trap at almost any kernel address and
- execute a callback function. register_kprobe() establishes
- a probepoint and specifies the callback. Kprobes is useful
- for kernel debugging, non-intrusive instrumentation and testing.
- If in doubt, say "N".
-
config DEBUG_STACK_USAGE
bool "Stack utilization instrumentation"
depends on DEBUG_KERNEL
diff --git a/arch/i386/Makefile b/arch/i386/Makefile
index 09951990a622..d121ea18460f 100644
--- a/arch/i386/Makefile
+++ b/arch/i386/Makefile
@@ -34,35 +34,8 @@ CFLAGS += -pipe -msoft-float
# prevent gcc from keeping the stack 16 byte aligned
CFLAGS += $(call cc-option,-mpreferred-stack-boundary=2)
-align := $(cc-option-align)
-cflags-$(CONFIG_M386) += -march=i386
-cflags-$(CONFIG_M486) += -march=i486
-cflags-$(CONFIG_M586) += -march=i586
-cflags-$(CONFIG_M586TSC) += -march=i586
-cflags-$(CONFIG_M586MMX) += $(call cc-option,-march=pentium-mmx,-march=i586)
-cflags-$(CONFIG_M686) += -march=i686
-cflags-$(CONFIG_MPENTIUMII) += -march=i686 $(call cc-option,-mtune=pentium2)
-cflags-$(CONFIG_MPENTIUMIII) += -march=i686 $(call cc-option,-mtune=pentium3)
-cflags-$(CONFIG_MPENTIUMM) += -march=i686 $(call cc-option,-mtune=pentium3)
-cflags-$(CONFIG_MPENTIUM4) += -march=i686 $(call cc-option,-mtune=pentium4)
-cflags-$(CONFIG_MK6) += -march=k6
-# Please note, that patches that add -march=athlon-xp and friends are pointless.
-# They make zero difference whatsosever to performance at this time.
-cflags-$(CONFIG_MK7) += $(call cc-option,-march=athlon,-march=i686 $(align)-functions=4)
-cflags-$(CONFIG_MK8) += $(call cc-option,-march=k8,$(call cc-option,-march=athlon,-march=i686 $(align)-functions=4))
-cflags-$(CONFIG_MCRUSOE) += -march=i686 $(align)-functions=0 $(align)-jumps=0 $(align)-loops=0
-cflags-$(CONFIG_MEFFICEON) += -march=i686 $(call cc-option,-mtune=pentium3) $(align)-functions=0 $(align)-jumps=0 $(align)-loops=0
-cflags-$(CONFIG_MWINCHIPC6) += $(call cc-option,-march=winchip-c6,-march=i586)
-cflags-$(CONFIG_MWINCHIP2) += $(call cc-option,-march=winchip2,-march=i586)
-cflags-$(CONFIG_MWINCHIP3D) += $(call cc-option,-march=winchip2,-march=i586)
-cflags-$(CONFIG_MCYRIXIII) += $(call cc-option,-march=c3,-march=i486) $(align)-functions=0 $(align)-jumps=0 $(align)-loops=0
-cflags-$(CONFIG_MVIAC3_2) += $(call cc-option,-march=c3-2,-march=i686)
-
-# AMD Elan support
-cflags-$(CONFIG_X86_ELAN) += -march=i486
-
-# Geode GX1 support
-cflags-$(CONFIG_MGEODEGX1) += $(call cc-option,-march=pentium-mmx,-march=i486)
+# CPU-specific tuning. Anything which can be shared with UML should go here.
+include $(srctree)/arch/i386/Makefile.cpu
# -mregparm=3 works ok on gcc-3.0 and later
#
diff --git a/arch/i386/Makefile.cpu b/arch/i386/Makefile.cpu
new file mode 100644
index 000000000000..8e51456df23d
--- /dev/null
+++ b/arch/i386/Makefile.cpu
@@ -0,0 +1,41 @@
+# CPU tuning section - shared with UML.
+# Must change only cflags-y (or [yn]), not CFLAGS! That makes a difference for UML.
+
+#-mtune exists since gcc 3.4, and some -mcpu flavors didn't exist in gcc 2.95.
+HAS_MTUNE := $(call cc-option-yn, -mtune=i386)
+ifeq ($(HAS_MTUNE),y)
+tune = $(call cc-option,-mtune=$(1),)
+else
+tune = $(call cc-option,-mcpu=$(1),)
+endif
+
+align := $(cc-option-align)
+cflags-$(CONFIG_M386) += -march=i386
+cflags-$(CONFIG_M486) += -march=i486
+cflags-$(CONFIG_M586) += -march=i586
+cflags-$(CONFIG_M586TSC) += -march=i586
+cflags-$(CONFIG_M586MMX) += $(call cc-option,-march=pentium-mmx,-march=i586)
+cflags-$(CONFIG_M686) += -march=i686
+cflags-$(CONFIG_MPENTIUMII) += -march=i686 $(call tune,pentium2)
+cflags-$(CONFIG_MPENTIUMIII) += -march=i686 $(call tune,pentium3)
+cflags-$(CONFIG_MPENTIUMM) += -march=i686 $(call tune,pentium3)
+cflags-$(CONFIG_MPENTIUM4) += -march=i686 $(call tune,pentium4)
+cflags-$(CONFIG_MK6) += -march=k6
+# Please note, that patches that add -march=athlon-xp and friends are pointless.
+# They make zero difference whatsosever to performance at this time.
+cflags-$(CONFIG_MK7) += $(call cc-option,-march=athlon,-march=i686 $(align)-functions=4)
+cflags-$(CONFIG_MK8) += $(call cc-option,-march=k8,$(call cc-option,-march=athlon,-march=i686 $(align)-functions=4))
+cflags-$(CONFIG_MCRUSOE) += -march=i686 $(align)-functions=0 $(align)-jumps=0 $(align)-loops=0
+cflags-$(CONFIG_MEFFICEON) += -march=i686 $(call tune,pentium3) $(align)-functions=0 $(align)-jumps=0 $(align)-loops=0
+cflags-$(CONFIG_MWINCHIPC6) += $(call cc-option,-march=winchip-c6,-march=i586)
+cflags-$(CONFIG_MWINCHIP2) += $(call cc-option,-march=winchip2,-march=i586)
+cflags-$(CONFIG_MWINCHIP3D) += $(call cc-option,-march=winchip2,-march=i586)
+cflags-$(CONFIG_MCYRIXIII) += $(call cc-option,-march=c3,-march=i486) $(align)-functions=0 $(align)-jumps=0 $(align)-loops=0
+cflags-$(CONFIG_MVIAC3_2) += $(call cc-option,-march=c3-2,-march=i686)
+
+# AMD Elan support
+cflags-$(CONFIG_X86_ELAN) += -march=i486
+
+# Geode GX1 support
+cflags-$(CONFIG_MGEODEGX1) += $(call cc-option,-march=pentium-mmx,-march=i486)
+
diff --git a/arch/i386/kernel/apic.c b/arch/i386/kernel/apic.c
index 5546ddebec33..496a2c9909fe 100644
--- a/arch/i386/kernel/apic.c
+++ b/arch/i386/kernel/apic.c
@@ -559,14 +559,20 @@ void __devinit setup_local_APIC(void)
* If Linux enabled the LAPIC against the BIOS default
* disable it down before re-entering the BIOS on shutdown.
* Otherwise the BIOS may get confused and not power-off.
+ * Additionally clear all LVT entries before disable_local_APIC
+ * for the case where Linux didn't enable the LAPIC.
*/
void lapic_shutdown(void)
{
- if (!cpu_has_apic || !enabled_via_apicbase)
+ if (!cpu_has_apic)
return;
local_irq_disable();
- disable_local_APIC();
+ clear_local_APIC();
+
+ if (enabled_via_apicbase)
+ disable_local_APIC();
+
local_irq_enable();
}
@@ -1046,10 +1052,11 @@ static unsigned int calibration_result;
void __init setup_boot_APIC_clock(void)
{
+ unsigned long flags;
apic_printk(APIC_VERBOSE, "Using local APIC timer interrupts.\n");
using_apic_timer = 1;
- local_irq_disable();
+ local_irq_save(flags);
calibration_result = calibrate_APIC_clock();
/*
@@ -1057,7 +1064,7 @@ void __init setup_boot_APIC_clock(void)
*/
setup_APIC_timer(calibration_result);
- local_irq_enable();
+ local_irq_restore(flags);
}
void __devinit setup_secondary_APIC_clock(void)
diff --git a/arch/i386/kernel/apm.c b/arch/i386/kernel/apm.c
index d7811c4e8b50..003548b8735f 100644
--- a/arch/i386/kernel/apm.c
+++ b/arch/i386/kernel/apm.c
@@ -447,8 +447,7 @@ static char * apm_event_name[] = {
"system standby resume",
"capabilities change"
};
-#define NR_APM_EVENT_NAME \
- (sizeof(apm_event_name) / sizeof(apm_event_name[0]))
+#define NR_APM_EVENT_NAME ARRAY_SIZE(apm_event_name)
typedef struct lookup_t {
int key;
@@ -479,7 +478,7 @@ static const lookup_t error_table[] = {
{ APM_NO_ERROR, "BIOS did not set a return code" },
{ APM_NOT_PRESENT, "No APM present" }
};
-#define ERROR_COUNT (sizeof(error_table)/sizeof(lookup_t))
+#define ERROR_COUNT ARRAY_SIZE(error_table)
/**
* apm_error - display an APM error
@@ -597,12 +596,14 @@ static u8 apm_bios_call(u32 func, u32 ebx_in, u32 ecx_in,
cpumask_t cpus;
int cpu;
struct desc_struct save_desc_40;
+ struct desc_struct *gdt;
cpus = apm_save_cpus();
cpu = get_cpu();
- save_desc_40 = per_cpu(cpu_gdt_table, cpu)[0x40 / 8];
- per_cpu(cpu_gdt_table, cpu)[0x40 / 8] = bad_bios_desc;
+ gdt = get_cpu_gdt_table(cpu);
+ save_desc_40 = gdt[0x40 / 8];
+ gdt[0x40 / 8] = bad_bios_desc;
local_save_flags(flags);
APM_DO_CLI;
@@ -610,7 +611,7 @@ static u8 apm_bios_call(u32 func, u32 ebx_in, u32 ecx_in,
apm_bios_call_asm(func, ebx_in, ecx_in, eax, ebx, ecx, edx, esi);
APM_DO_RESTORE_SEGS;
local_irq_restore(flags);
- per_cpu(cpu_gdt_table, cpu)[0x40 / 8] = save_desc_40;
+ gdt[0x40 / 8] = save_desc_40;
put_cpu();
apm_restore_cpus(cpus);
@@ -639,13 +640,14 @@ static u8 apm_bios_call_simple(u32 func, u32 ebx_in, u32 ecx_in, u32 *eax)
cpumask_t cpus;
int cpu;
struct desc_struct save_desc_40;
-
+ struct desc_struct *gdt;
cpus = apm_save_cpus();
cpu = get_cpu();
- save_desc_40 = per_cpu(cpu_gdt_table, cpu)[0x40 / 8];
- per_cpu(cpu_gdt_table, cpu)[0x40 / 8] = bad_bios_desc;
+ gdt = get_cpu_gdt_table(cpu);
+ save_desc_40 = gdt[0x40 / 8];
+ gdt[0x40 / 8] = bad_bios_desc;
local_save_flags(flags);
APM_DO_CLI;
@@ -653,7 +655,7 @@ static u8 apm_bios_call_simple(u32 func, u32 ebx_in, u32 ecx_in, u32 *eax)
error = apm_bios_call_simple_asm(func, ebx_in, ecx_in, eax);
APM_DO_RESTORE_SEGS;
local_irq_restore(flags);
- __get_cpu_var(cpu_gdt_table)[0x40 / 8] = save_desc_40;
+ gdt[0x40 / 8] = save_desc_40;
put_cpu();
apm_restore_cpus(cpus);
return error;
@@ -767,8 +769,26 @@ static int set_system_power_state(u_short state)
static int apm_do_idle(void)
{
u32 eax;
+ u8 ret = 0;
+ int idled = 0;
+ int polling;
+
+ polling = test_thread_flag(TIF_POLLING_NRFLAG);
+ if (polling) {
+ clear_thread_flag(TIF_POLLING_NRFLAG);
+ smp_mb__after_clear_bit();
+ }
+ if (!need_resched()) {
+ idled = 1;
+ ret = apm_bios_call_simple(APM_FUNC_IDLE, 0, 0, &eax);
+ }
+ if (polling)
+ set_thread_flag(TIF_POLLING_NRFLAG);
+
+ if (!idled)
+ return 0;
- if (apm_bios_call_simple(APM_FUNC_IDLE, 0, 0, &eax)) {
+ if (ret) {
static unsigned long t;
/* This always fails on some SMP boards running UP kernels.
@@ -2295,35 +2315,36 @@ static int __init apm_init(void)
apm_bios_entry.segment = APM_CS;
for (i = 0; i < NR_CPUS; i++) {
- set_base(per_cpu(cpu_gdt_table, i)[APM_CS >> 3],
+ struct desc_struct *gdt = get_cpu_gdt_table(i);
+ set_base(gdt[APM_CS >> 3],
__va((unsigned long)apm_info.bios.cseg << 4));
- set_base(per_cpu(cpu_gdt_table, i)[APM_CS_16 >> 3],
+ set_base(gdt[APM_CS_16 >> 3],
__va((unsigned long)apm_info.bios.cseg_16 << 4));
- set_base(per_cpu(cpu_gdt_table, i)[APM_DS >> 3],
+ set_base(gdt[APM_DS >> 3],
__va((unsigned long)apm_info.bios.dseg << 4));
#ifndef APM_RELAX_SEGMENTS
if (apm_info.bios.version == 0x100) {
#endif
/* For ASUS motherboard, Award BIOS rev 110 (and others?) */
- _set_limit((char *)&per_cpu(cpu_gdt_table, i)[APM_CS >> 3], 64 * 1024 - 1);
+ _set_limit((char *)&gdt[APM_CS >> 3], 64 * 1024 - 1);
/* For some unknown machine. */
- _set_limit((char *)&per_cpu(cpu_gdt_table, i)[APM_CS_16 >> 3], 64 * 1024 - 1);
+ _set_limit((char *)&gdt[APM_CS_16 >> 3], 64 * 1024 - 1);
/* For the DEC Hinote Ultra CT475 (and others?) */
- _set_limit((char *)&per_cpu(cpu_gdt_table, i)[APM_DS >> 3], 64 * 1024 - 1);
+ _set_limit((char *)&gdt[APM_DS >> 3], 64 * 1024 - 1);
#ifndef APM_RELAX_SEGMENTS
} else {
- _set_limit((char *)&per_cpu(cpu_gdt_table, i)[APM_CS >> 3],
+ _set_limit((char *)&gdt[APM_CS >> 3],
(apm_info.bios.cseg_len - 1) & 0xffff);
- _set_limit((char *)&per_cpu(cpu_gdt_table, i)[APM_CS_16 >> 3],
+ _set_limit((char *)&gdt[APM_CS_16 >> 3],
(apm_info.bios.cseg_16_len - 1) & 0xffff);
- _set_limit((char *)&per_cpu(cpu_gdt_table, i)[APM_DS >> 3],
+ _set_limit((char *)&gdt[APM_DS >> 3],
(apm_info.bios.dseg_len - 1) & 0xffff);
/* workaround for broken BIOSes */
if (apm_info.bios.cseg_len <= apm_info.bios.offset)
- _set_limit((char *)&per_cpu(cpu_gdt_table, i)[APM_CS >> 3], 64 * 1024 -1);
+ _set_limit((char *)&gdt[APM_CS >> 3], 64 * 1024 -1);
if (apm_info.bios.dseg_len <= 0x40) { /* 0x40 * 4kB == 64kB */
/* for the BIOS that assumes granularity = 1 */
- per_cpu(cpu_gdt_table, i)[APM_DS >> 3].b |= 0x800000;
+ gdt[APM_DS >> 3].b |= 0x800000;
printk(KERN_NOTICE "apm: we set the granularity of dseg.\n");
}
}
diff --git a/arch/i386/kernel/cpu/common.c b/arch/i386/kernel/cpu/common.c
index 9ad43be9a01f..c145fb30002e 100644
--- a/arch/i386/kernel/cpu/common.c
+++ b/arch/i386/kernel/cpu/common.c
@@ -30,8 +30,6 @@ static int disable_x86_serial_nr __devinitdata = 1;
struct cpu_dev * cpu_devs[X86_VENDOR_NUM] = {};
-extern void mcheck_init(struct cpuinfo_x86 *c);
-
extern int disable_pse;
static void default_init(struct cpuinfo_x86 * c)
@@ -429,9 +427,8 @@ void __devinit identify_cpu(struct cpuinfo_x86 *c)
}
/* Init Machine Check Exception if available. */
-#ifdef CONFIG_X86_MCE
mcheck_init(c);
-#endif
+
if (c == &boot_cpu_data)
sysenter_setup();
enable_sep_cpu();
@@ -573,6 +570,7 @@ void __devinit cpu_init(void)
int cpu = smp_processor_id();
struct tss_struct * t = &per_cpu(init_tss, cpu);
struct thread_struct *thread = &current->thread;
+ struct desc_struct *gdt = get_cpu_gdt_table(cpu);
__u32 stk16_off = (__u32)&per_cpu(cpu_16bit_stack, cpu);
if (cpu_test_and_set(cpu, cpu_initialized)) {
@@ -594,24 +592,16 @@ void __devinit cpu_init(void)
* Initialize the per-CPU GDT with the boot GDT,
* and set up the GDT descriptor:
*/
- memcpy(&per_cpu(cpu_gdt_table, cpu), cpu_gdt_table,
- GDT_SIZE);
+ memcpy(gdt, cpu_gdt_table, GDT_SIZE);
/* Set up GDT entry for 16bit stack */
- *(__u64 *)&(per_cpu(cpu_gdt_table, cpu)[GDT_ENTRY_ESPFIX_SS]) |=
+ *(__u64 *)(&gdt[GDT_ENTRY_ESPFIX_SS]) |=
((((__u64)stk16_off) << 16) & 0x000000ffffff0000ULL) |
((((__u64)stk16_off) << 32) & 0xff00000000000000ULL) |
(CPU_16BIT_STACK_SIZE - 1);
cpu_gdt_descr[cpu].size = GDT_SIZE - 1;
- cpu_gdt_descr[cpu].address =
- (unsigned long)&per_cpu(cpu_gdt_table, cpu);
-
- /*
- * Set up the per-thread TLS descriptor cache:
- */
- memcpy(thread->tls_array, &per_cpu(cpu_gdt_table, cpu),
- GDT_ENTRY_TLS_ENTRIES * 8);
+ cpu_gdt_descr[cpu].address = (unsigned long)gdt;
load_gdt(&cpu_gdt_descr[cpu]);
load_idt(&idt_descr);
diff --git a/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c b/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c
index 822c8ce9d1f1..871366b83b3f 100644
--- a/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c
+++ b/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c
@@ -32,6 +32,7 @@
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/compiler.h>
+#include <linux/sched.h> /* current */
#include <asm/io.h>
#include <asm/delay.h>
#include <asm/uaccess.h>
@@ -376,10 +377,9 @@ acpi_cpufreq_cpu_init (
arg0.buffer.length = 12;
arg0.buffer.pointer = (u8 *) arg0_buf;
- data = kmalloc(sizeof(struct cpufreq_acpi_io), GFP_KERNEL);
+ data = kzalloc(sizeof(struct cpufreq_acpi_io), GFP_KERNEL);
if (!data)
return (-ENOMEM);
- memset(data, 0, sizeof(struct cpufreq_acpi_io));
acpi_io_data[cpu] = data;
diff --git a/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c b/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c
index aa622d52c6e5..270f2188d68b 100644
--- a/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c
+++ b/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c
@@ -28,6 +28,7 @@
#include <linux/cpufreq.h>
#include <linux/slab.h>
#include <linux/cpumask.h>
+#include <linux/sched.h> /* current / set_cpus_allowed() */
#include <asm/processor.h>
#include <asm/msr.h>
diff --git a/arch/i386/kernel/cpu/cpufreq/powernow-k7.c b/arch/i386/kernel/cpu/cpufreq/powernow-k7.c
index 73a5dc5b26b8..edcd626001da 100644
--- a/arch/i386/kernel/cpu/cpufreq/powernow-k7.c
+++ b/arch/i386/kernel/cpu/cpufreq/powernow-k7.c
@@ -171,10 +171,9 @@ static int get_ranges (unsigned char *pst)
unsigned int speed;
u8 fid, vid;
- powernow_table = kmalloc((sizeof(struct cpufreq_frequency_table) * (number_scales + 1)), GFP_KERNEL);
+ powernow_table = kzalloc((sizeof(struct cpufreq_frequency_table) * (number_scales + 1)), GFP_KERNEL);
if (!powernow_table)
return -ENOMEM;
- memset(powernow_table, 0, (sizeof(struct cpufreq_frequency_table) * (number_scales + 1)));
for (j=0 ; j < number_scales; j++) {
fid = *pst++;
@@ -305,16 +304,13 @@ static int powernow_acpi_init(void)
goto err0;
}
- acpi_processor_perf = kmalloc(sizeof(struct acpi_processor_performance),
+ acpi_processor_perf = kzalloc(sizeof(struct acpi_processor_performance),
GFP_KERNEL);
-
if (!acpi_processor_perf) {
retval = -ENOMEM;
goto err0;
}
- memset(acpi_processor_perf, 0, sizeof(struct acpi_processor_performance));
-
if (acpi_processor_register_performance(acpi_processor_perf, 0)) {
retval = -EIO;
goto err1;
@@ -337,14 +333,12 @@ static int powernow_acpi_init(void)
goto err2;
}
- powernow_table = kmalloc((number_scales + 1) * (sizeof(struct cpufreq_frequency_table)), GFP_KERNEL);
+ powernow_table = kzalloc((number_scales + 1) * (sizeof(struct cpufreq_frequency_table)), GFP_KERNEL);
if (!powernow_table) {
retval = -ENOMEM;
goto err2;
}
- memset(powernow_table, 0, ((number_scales + 1) * sizeof(struct cpufreq_frequency_table)));
-
pc.val = (unsigned long) acpi_processor_perf->states[0].control;
for (i = 0; i < number_scales; i++) {
u8 fid, vid;
diff --git a/arch/i386/kernel/cpu/cpufreq/powernow-k8.c b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c
index 58ca98fdc2ca..68a1fc87f4ca 100644
--- a/arch/i386/kernel/cpu/cpufreq/powernow-k8.c
+++ b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c
@@ -32,6 +32,7 @@
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/cpumask.h>
+#include <linux/sched.h> /* for current / set_cpus_allowed() */
#include <asm/msr.h>
#include <asm/io.h>
@@ -461,7 +462,6 @@ static int check_supported_cpu(unsigned int cpu)
oldmask = current->cpus_allowed;
set_cpus_allowed(current, cpumask_of_cpu(cpu));
- schedule();
if (smp_processor_id() != cpu) {
printk(KERN_ERR "limiting to cpu %u failed\n", cpu);
@@ -496,9 +496,7 @@ static int check_supported_cpu(unsigned int cpu)
out:
set_cpus_allowed(current, oldmask);
- schedule();
return rc;
-
}
static int check_pst_table(struct powernow_k8_data *data, struct pst_s *pst, u8 maxvid)
@@ -912,7 +910,6 @@ static int powernowk8_target(struct cpufreq_policy *pol, unsigned targfreq, unsi
/* only run on specific CPU from here on */
oldmask = current->cpus_allowed;
set_cpus_allowed(current, cpumask_of_cpu(pol->cpu));
- schedule();
if (smp_processor_id() != pol->cpu) {
printk(KERN_ERR "limiting to cpu %u failed\n", pol->cpu);
@@ -967,8 +964,6 @@ static int powernowk8_target(struct cpufreq_policy *pol, unsigned targfreq, unsi
err_out:
set_cpus_allowed(current, oldmask);
- schedule();
-
return ret;
}
@@ -990,12 +985,11 @@ static int __init powernowk8_cpu_init(struct cpufreq_policy *pol)
if (!check_supported_cpu(pol->cpu))
return -ENODEV;
- data = kmalloc(sizeof(struct powernow_k8_data), GFP_KERNEL);
+ data = kzalloc(sizeof(struct powernow_k8_data), GFP_KERNEL);
if (!data) {
printk(KERN_ERR PFX "unable to alloc powernow_k8_data");
return -ENOMEM;
}
- memset(data,0,sizeof(struct powernow_k8_data));
data->cpu = pol->cpu;
@@ -1025,7 +1019,6 @@ static int __init powernowk8_cpu_init(struct cpufreq_policy *pol)
/* only run on specific CPU from here on */
oldmask = current->cpus_allowed;
set_cpus_allowed(current, cpumask_of_cpu(pol->cpu));
- schedule();
if (smp_processor_id() != pol->cpu) {
printk(KERN_ERR "limiting to cpu %u failed\n", pol->cpu);
@@ -1044,7 +1037,6 @@ static int __init powernowk8_cpu_init(struct cpufreq_policy *pol)
/* run on any CPU again */
set_cpus_allowed(current, oldmask);
- schedule();
pol->governor = CPUFREQ_DEFAULT_GOVERNOR;
pol->cpus = cpu_core_map[pol->cpu];
@@ -1079,7 +1071,6 @@ static int __init powernowk8_cpu_init(struct cpufreq_policy *pol)
err_out:
set_cpus_allowed(current, oldmask);
- schedule();
powernow_k8_cpu_exit_acpi(data);
kfree(data);
@@ -1115,17 +1106,14 @@ static unsigned int powernowk8_get (unsigned int cpu)
set_cpus_allowed(current, oldmask);
return 0;
}
- preempt_disable();
-
+
if (query_current_values_with_pending_wait(data))
goto out;
khz = find_khz_freq_from_fid(data->currfid);
- out:
- preempt_enable_no_resched();
+out:
set_cpus_allowed(current, oldmask);
-
return khz;
}
diff --git a/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c b/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
index c397b6220430..edb9873e27e3 100644
--- a/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
+++ b/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
@@ -22,6 +22,7 @@
#include <linux/init.h>
#include <linux/cpufreq.h>
#include <linux/config.h>
+#include <linux/sched.h> /* current */
#include <linux/delay.h>
#include <linux/compiler.h>
@@ -66,7 +67,7 @@ static const struct cpu_id cpu_ids[] = {
[CPU_MP4HT_D0] = {15, 3, 4 },
[CPU_MP4HT_E0] = {15, 4, 1 },
};
-#define N_IDS (sizeof(cpu_ids)/sizeof(cpu_ids[0]))
+#define N_IDS ARRAY_SIZE(cpu_ids)
struct cpu_model
{
@@ -422,12 +423,11 @@ static int centrino_cpu_init_acpi(struct cpufreq_policy *policy)
}
}
- centrino_model[cpu] = kmalloc(sizeof(struct cpu_model), GFP_KERNEL);
+ centrino_model[cpu] = kzalloc(sizeof(struct cpu_model), GFP_KERNEL);
if (!centrino_model[cpu]) {
result = -ENOMEM;
goto err_unreg;
}
- memset(centrino_model[cpu], 0, sizeof(struct cpu_model));
centrino_model[cpu]->model_name=NULL;
centrino_model[cpu]->max_freq = p.states[0].core_frequency * 1000;
diff --git a/arch/i386/kernel/cpu/intel_cacheinfo.c b/arch/i386/kernel/cpu/intel_cacheinfo.c
index 9e0d5f83cb9f..4dc42a189ae5 100644
--- a/arch/i386/kernel/cpu/intel_cacheinfo.c
+++ b/arch/i386/kernel/cpu/intel_cacheinfo.c
@@ -3,6 +3,7 @@
*
* Changes:
* Venkatesh Pallipadi : Adding cache identification through cpuid(4)
+ * Ashok Raj <ashok.raj@intel.com>: Work with CPU hotplug infrastructure.
*/
#include <linux/init.h>
@@ -10,6 +11,7 @@
#include <linux/device.h>
#include <linux/compiler.h>
#include <linux/cpu.h>
+#include <linux/sched.h>
#include <asm/processor.h>
#include <asm/smp.h>
@@ -28,7 +30,7 @@ struct _cache_table
};
/* all the cache descriptor types we care about (no TLB or trace cache entries) */
-static struct _cache_table cache_table[] __devinitdata =
+static struct _cache_table cache_table[] __cpuinitdata =
{
{ 0x06, LVL_1_INST, 8 }, /* 4-way set assoc, 32 byte line size */
{ 0x08, LVL_1_INST, 16 }, /* 4-way set assoc, 32 byte line size */
@@ -117,10 +119,9 @@ struct _cpuid4_info {
cpumask_t shared_cpu_map;
};
-#define MAX_CACHE_LEAVES 4
static unsigned short num_cache_leaves;
-static int __devinit cpuid4_cache_lookup(int index, struct _cpuid4_info *this_leaf)
+static int __cpuinit cpuid4_cache_lookup(int index, struct _cpuid4_info *this_leaf)
{
unsigned int eax, ebx, ecx, edx;
union _cpuid4_leaf_eax cache_eax;
@@ -144,23 +145,18 @@ static int __init find_num_cache_leaves(void)
{
unsigned int eax, ebx, ecx, edx;
union _cpuid4_leaf_eax cache_eax;
- int i;
- int retval;
+ int i = -1;
- retval = MAX_CACHE_LEAVES;
- /* Do cpuid(4) loop to find out num_cache_leaves */
- for (i = 0; i < MAX_CACHE_LEAVES; i++) {
+ do {
+ ++i;
+ /* Do cpuid(4) loop to find out num_cache_leaves */
cpuid_count(4, i, &eax, &ebx, &ecx, &edx);
cache_eax.full = eax;
- if (cache_eax.split.type == CACHE_TYPE_NULL) {
- retval = i;
- break;
- }
- }
- return retval;
+ } while (cache_eax.split.type != CACHE_TYPE_NULL);
+ return i;
}
-unsigned int __devinit init_intel_cacheinfo(struct cpuinfo_x86 *c)
+unsigned int __cpuinit init_intel_cacheinfo(struct cpuinfo_x86 *c)
{
unsigned int trace = 0, l1i = 0, l1d = 0, l2 = 0, l3 = 0; /* Cache sizes */
unsigned int new_l1d = 0, new_l1i = 0; /* Cache sizes from cpuid(4) */
@@ -284,13 +280,7 @@ unsigned int __devinit init_intel_cacheinfo(struct cpuinfo_x86 *c)
if ( l3 )
printk(KERN_INFO "CPU: L3 cache: %dK\n", l3);
- /*
- * This assumes the L3 cache is shared; it typically lives in
- * the northbridge. The L1 caches are included by the L2
- * cache, and so should not be included for the purpose of
- * SMP switching weights.
- */
- c->x86_cache_size = l2 ? l2 : (l1i+l1d);
+ c->x86_cache_size = l3 ? l3 : (l2 ? l2 : (l1i+l1d));
}
return l2;
@@ -301,7 +291,7 @@ static struct _cpuid4_info *cpuid4_info[NR_CPUS];
#define CPUID4_INFO_IDX(x,y) (&((cpuid4_info[x])[y]))
#ifdef CONFIG_SMP
-static void __devinit cache_shared_cpu_map_setup(unsigned int cpu, int index)
+static void __cpuinit cache_shared_cpu_map_setup(unsigned int cpu, int index)
{
struct _cpuid4_info *this_leaf;
unsigned long num_threads_sharing;
@@ -334,7 +324,7 @@ static void free_cache_attributes(unsigned int cpu)
cpuid4_info[cpu] = NULL;
}
-static int __devinit detect_cache_attributes(unsigned int cpu)
+static int __cpuinit detect_cache_attributes(unsigned int cpu)
{
struct _cpuid4_info *this_leaf;
unsigned long j;
@@ -511,7 +501,7 @@ static void cpuid4_cache_sysfs_exit(unsigned int cpu)
free_cache_attributes(cpu);
}
-static int __devinit cpuid4_cache_sysfs_init(unsigned int cpu)
+static int __cpuinit cpuid4_cache_sysfs_init(unsigned int cpu)
{
if (num_cache_leaves == 0)
@@ -542,7 +532,7 @@ err_out:
}
/* Add/Remove cache interface for CPU device */
-static int __devinit cache_add_dev(struct sys_device * sys_dev)
+static int __cpuinit cache_add_dev(struct sys_device * sys_dev)
{
unsigned int cpu = sys_dev->id;
unsigned long i, j;
@@ -579,7 +569,7 @@ static int __devinit cache_add_dev(struct sys_device * sys_dev)
return retval;
}
-static int __devexit cache_remove_dev(struct sys_device * sys_dev)
+static void __cpuexit cache_remove_dev(struct sys_device * sys_dev)
{
unsigned int cpu = sys_dev->id;
unsigned long i;
@@ -588,24 +578,49 @@ static int __devexit cache_remove_dev(struct sys_device * sys_dev)
kobject_unregister(&(INDEX_KOBJECT_PTR(cpu,i)->kobj));
kobject_unregister(cache_kobject[cpu]);
cpuid4_cache_sysfs_exit(cpu);
- return 0;
+ return;
+}
+
+static int __cpuinit cacheinfo_cpu_callback(struct notifier_block *nfb,
+ unsigned long action, void *hcpu)
+{
+ unsigned int cpu = (unsigned long)hcpu;
+ struct sys_device *sys_dev;
+
+ sys_dev = get_cpu_sysdev(cpu);
+ switch (action) {
+ case CPU_ONLINE:
+ cache_add_dev(sys_dev);
+ break;
+ case CPU_DEAD:
+ cache_remove_dev(sys_dev);
+ break;
+ }
+ return NOTIFY_OK;
}
-static struct sysdev_driver cache_sysdev_driver = {
- .add = cache_add_dev,
- .remove = __devexit_p(cache_remove_dev),
+static struct notifier_block cacheinfo_cpu_notifier =
+{
+ .notifier_call = cacheinfo_cpu_callback,
};
-/* Register/Unregister the cpu_cache driver */
-static int __devinit cache_register_driver(void)
+static int __cpuinit cache_sysfs_init(void)
{
+ int i;
+
if (num_cache_leaves == 0)
return 0;
- return sysdev_driver_register(&cpu_sysdev_class,&cache_sysdev_driver);
+ register_cpu_notifier(&cacheinfo_cpu_notifier);
+
+ for_each_online_cpu(i) {
+ cacheinfo_cpu_callback(&cacheinfo_cpu_notifier, CPU_ONLINE,
+ (void *)(long)i);
+ }
+
+ return 0;
}
-device_initcall(cache_register_driver);
+device_initcall(cache_sysfs_init);
#endif
-
diff --git a/arch/i386/kernel/cpu/mcheck/k7.c b/arch/i386/kernel/cpu/mcheck/k7.c
index 7c6b9c73522f..fc5d5215e23d 100644
--- a/arch/i386/kernel/cpu/mcheck/k7.c
+++ b/arch/i386/kernel/cpu/mcheck/k7.c
@@ -68,7 +68,7 @@ static fastcall void k7_machine_check(struct pt_regs * regs, long error_code)
/* AMD K7 machine check is Intel like */
-void __devinit amd_mcheck_init(struct cpuinfo_x86 *c)
+void amd_mcheck_init(struct cpuinfo_x86 *c)
{
u32 l, h;
int i;
diff --git a/arch/i386/kernel/cpu/mcheck/mce.c b/arch/i386/kernel/cpu/mcheck/mce.c
index 2cf25d2ba0f1..6170af3c271a 100644
--- a/arch/i386/kernel/cpu/mcheck/mce.c
+++ b/arch/i386/kernel/cpu/mcheck/mce.c
@@ -16,7 +16,7 @@
#include "mce.h"
-int mce_disabled __devinitdata = 0;
+int mce_disabled = 0;
int nr_mce_banks;
EXPORT_SYMBOL_GPL(nr_mce_banks); /* non-fatal.o */
@@ -31,7 +31,7 @@ static fastcall void unexpected_machine_check(struct pt_regs * regs, long error_
void fastcall (*machine_check_vector)(struct pt_regs *, long error_code) = unexpected_machine_check;
/* This has to be run for each processor */
-void __devinit mcheck_init(struct cpuinfo_x86 *c)
+void mcheck_init(struct cpuinfo_x86 *c)
{
if (mce_disabled==1)
return;
diff --git a/arch/i386/kernel/cpu/mcheck/p4.c b/arch/i386/kernel/cpu/mcheck/p4.c
index 1d1e885f500a..fd2c459a31ef 100644
--- a/arch/i386/kernel/cpu/mcheck/p4.c
+++ b/arch/i386/kernel/cpu/mcheck/p4.c
@@ -77,7 +77,7 @@ fastcall void smp_thermal_interrupt(struct pt_regs *regs)
}
/* P4/Xeon Thermal regulation detect and init */
-static void __devinit intel_init_thermal(struct cpuinfo_x86 *c)
+static void intel_init_thermal(struct cpuinfo_x86 *c)
{
u32 l, h;
unsigned int cpu = smp_processor_id();
@@ -231,7 +231,7 @@ static fastcall void intel_machine_check(struct pt_regs * regs, long error_code)
}
-void __devinit intel_p4_mcheck_init(struct cpuinfo_x86 *c)
+void intel_p4_mcheck_init(struct cpuinfo_x86 *c)
{
u32 l, h;
int i;
diff --git a/arch/i386/kernel/cpu/mcheck/p5.c b/arch/i386/kernel/cpu/mcheck/p5.c
index 3a2e24baddc7..94bc43d950cf 100644
--- a/arch/i386/kernel/cpu/mcheck/p5.c
+++ b/arch/i386/kernel/cpu/mcheck/p5.c
@@ -28,7 +28,7 @@ static fastcall void pentium_machine_check(struct pt_regs * regs, long error_cod
}
/* Set up machine check reporting for processors with Intel style MCE */
-void __devinit intel_p5_mcheck_init(struct cpuinfo_x86 *c)
+void intel_p5_mcheck_init(struct cpuinfo_x86 *c)
{
u32 l, h;
diff --git a/arch/i386/kernel/cpu/mcheck/p6.c b/arch/i386/kernel/cpu/mcheck/p6.c
index 3c035b8fa3d9..deeae42ce199 100644
--- a/arch/i386/kernel/cpu/mcheck/p6.c
+++ b/arch/i386/kernel/cpu/mcheck/p6.c
@@ -79,7 +79,7 @@ static fastcall void intel_machine_check(struct pt_regs * regs, long error_code)
}
/* Set up machine check reporting for processors with Intel style MCE */
-void __devinit intel_p6_mcheck_init(struct cpuinfo_x86 *c)
+void intel_p6_mcheck_init(struct cpuinfo_x86 *c)
{
u32 l, h;
int i;
@@ -102,11 +102,16 @@ void __devinit intel_p6_mcheck_init(struct cpuinfo_x86 *c)
wrmsr(MSR_IA32_MCG_CTL, 0xffffffff, 0xffffffff);
nr_mce_banks = l & 0xff;
- /* Don't enable bank 0 on intel P6 cores, it goes bang quickly. */
- for (i=1; i<nr_mce_banks; i++) {
+ /*
+ * Following the example in IA-32 SDM Vol 3:
+ * - MC0_CTL should not be written
+ * - Status registers on all banks should be cleared on reset
+ */
+ for (i=1; i<nr_mce_banks; i++)
wrmsr (MSR_IA32_MC0_CTL+4*i, 0xffffffff, 0xffffffff);
+
+ for (i=0; i<nr_mce_banks; i++)
wrmsr (MSR_IA32_MC0_STATUS+4*i, 0x0, 0x0);
- }
set_in_cr4 (X86_CR4_MCE);
printk (KERN_INFO "Intel machine check reporting enabled on CPU#%d.\n",
diff --git a/arch/i386/kernel/cpu/mcheck/winchip.c b/arch/i386/kernel/cpu/mcheck/winchip.c
index 5b9d2dd411d3..9e424b6c293d 100644
--- a/arch/i386/kernel/cpu/mcheck/winchip.c
+++ b/arch/i386/kernel/cpu/mcheck/winchip.c
@@ -22,7 +22,7 @@ static fastcall void winchip_machine_check(struct pt_regs * regs, long error_cod
}
/* Set up machine check reporting on the Winchip C6 series */
-void __devinit winchip_mcheck_init(struct cpuinfo_x86 *c)
+void winchip_mcheck_init(struct cpuinfo_x86 *c)
{
u32 lo, hi;
machine_check_vector = winchip_machine_check;
diff --git a/arch/i386/kernel/cpu/mtrr/if.c b/arch/i386/kernel/cpu/mtrr/if.c
index 1923e0aed26a..cf39e205d33c 100644
--- a/arch/i386/kernel/cpu/mtrr/if.c
+++ b/arch/i386/kernel/cpu/mtrr/if.c
@@ -149,60 +149,89 @@ mtrr_write(struct file *file, const char __user *buf, size_t len, loff_t * ppos)
return -EINVAL;
}
-static int
-mtrr_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long __arg)
+static long
+mtrr_ioctl(struct file *file, unsigned int cmd, unsigned long __arg)
{
- int err;
+ int err = 0;
mtrr_type type;
struct mtrr_sentry sentry;
struct mtrr_gentry gentry;
void __user *arg = (void __user *) __arg;
switch (cmd) {
+ case MTRRIOC_ADD_ENTRY:
+ case MTRRIOC_SET_ENTRY:
+ case MTRRIOC_DEL_ENTRY:
+ case MTRRIOC_KILL_ENTRY:
+ case MTRRIOC_ADD_PAGE_ENTRY:
+ case MTRRIOC_SET_PAGE_ENTRY:
+ case MTRRIOC_DEL_PAGE_ENTRY:
+ case MTRRIOC_KILL_PAGE_ENTRY:
+ if (copy_from_user(&sentry, arg, sizeof sentry))
+ return -EFAULT;
+ break;
+ case MTRRIOC_GET_ENTRY:
+ case MTRRIOC_GET_PAGE_ENTRY:
+ if (copy_from_user(&gentry, arg, sizeof gentry))
+ return -EFAULT;
+ break;
+#ifdef CONFIG_COMPAT
+ case MTRRIOC32_ADD_ENTRY:
+ case MTRRIOC32_SET_ENTRY:
+ case MTRRIOC32_DEL_ENTRY:
+ case MTRRIOC32_KILL_ENTRY:
+ case MTRRIOC32_ADD_PAGE_ENTRY:
+ case MTRRIOC32_SET_PAGE_ENTRY:
+ case MTRRIOC32_DEL_PAGE_ENTRY:
+ case MTRRIOC32_KILL_PAGE_ENTRY: {
+ struct mtrr_sentry32 __user *s32 = (struct mtrr_sentry32 __user *)__arg;
+ err = get_user(sentry.base, &s32->base);
+ err |= get_user(sentry.size, &s32->size);
+ err |= get_user(sentry.type, &s32->type);
+ if (err)
+ return err;
+ break;
+ }
+ case MTRRIOC32_GET_ENTRY:
+ case MTRRIOC32_GET_PAGE_ENTRY: {
+ struct mtrr_gentry32 __user *g32 = (struct mtrr_gentry32 __user *)__arg;
+ err = get_user(gentry.regnum, &g32->regnum);
+ err |= get_user(gentry.base, &g32->base);
+ err |= get_user(gentry.size, &g32->size);
+ err |= get_user(gentry.type, &g32->type);
+ if (err)
+ return err;
+ break;
+ }
+#endif
+ }
+
+ switch (cmd) {
default:
return -ENOTTY;
case MTRRIOC_ADD_ENTRY:
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
- if (copy_from_user(&sentry, arg, sizeof sentry))
- return -EFAULT;
err =
mtrr_file_add(sentry.base, sentry.size, sentry.type, 1,
file, 0);
- if (err < 0)
- return err;
break;
case MTRRIOC_SET_ENTRY:
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
- if (copy_from_user(&sentry, arg, sizeof sentry))
- return -EFAULT;
err = mtrr_add(sentry.base, sentry.size, sentry.type, 0);
- if (err < 0)
- return err;
break;
case MTRRIOC_DEL_ENTRY:
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
- if (copy_from_user(&sentry, arg, sizeof sentry))
- return -EFAULT;
err = mtrr_file_del(sentry.base, sentry.size, file, 0);
- if (err < 0)
- return err;
break;
case MTRRIOC_KILL_ENTRY:
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
- if (copy_from_user(&sentry, arg, sizeof sentry))
- return -EFAULT;
err = mtrr_del(-1, sentry.base, sentry.size);
- if (err < 0)
- return err;
break;
case MTRRIOC_GET_ENTRY:
- if (copy_from_user(&gentry, arg, sizeof gentry))
- return -EFAULT;
if (gentry.regnum >= num_var_ranges)
return -EINVAL;
mtrr_if->get(gentry.regnum, &gentry.base, &gentry.size, &type);
@@ -217,60 +246,59 @@ mtrr_ioctl(struct inode *inode, struct file *file,
gentry.type = type;
}
- if (copy_to_user(arg, &gentry, sizeof gentry))
- return -EFAULT;
break;
case MTRRIOC_ADD_PAGE_ENTRY:
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
- if (copy_from_user(&sentry, arg, sizeof sentry))
- return -EFAULT;
err =
mtrr_file_add(sentry.base, sentry.size, sentry.type, 1,
file, 1);
- if (err < 0)
- return err;
break;
case MTRRIOC_SET_PAGE_ENTRY:
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
- if (copy_from_user(&sentry, arg, sizeof sentry))
- return -EFAULT;
err = mtrr_add_page(sentry.base, sentry.size, sentry.type, 0);
- if (err < 0)
- return err;
break;
case MTRRIOC_DEL_PAGE_ENTRY:
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
- if (copy_from_user(&sentry, arg, sizeof sentry))
- return -EFAULT;
err = mtrr_file_del(sentry.base, sentry.size, file, 1);
- if (err < 0)
- return err;
break;
case MTRRIOC_KILL_PAGE_ENTRY:
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
- if (copy_from_user(&sentry, arg, sizeof sentry))
- return -EFAULT;
err = mtrr_del_page(-1, sentry.base, sentry.size);
- if (err < 0)
- return err;
break;
case MTRRIOC_GET_PAGE_ENTRY:
- if (copy_from_user(&gentry, arg, sizeof gentry))
- return -EFAULT;
if (gentry.regnum >= num_var_ranges)
return -EINVAL;
mtrr_if->get(gentry.regnum, &gentry.base, &gentry.size, &type);
gentry.type = type;
+ break;
+ }
+
+ if (err)
+ return err;
+ switch(cmd) {
+ case MTRRIOC_GET_ENTRY:
+ case MTRRIOC_GET_PAGE_ENTRY:
if (copy_to_user(arg, &gentry, sizeof gentry))
- return -EFAULT;
+ err = -EFAULT;
+ break;
+#ifdef CONFIG_COMPAT
+ case MTRRIOC32_GET_ENTRY:
+ case MTRRIOC32_GET_PAGE_ENTRY: {
+ struct mtrr_gentry32 __user *g32 = (struct mtrr_gentry32 __user *)__arg;
+ err = put_user(gentry.base, &g32->base);
+ err |= put_user(gentry.size, &g32->size);
+ err |= put_user(gentry.regnum, &g32->regnum);
+ err |= put_user(gentry.type, &g32->type);
break;
}
- return 0;
+#endif
+ }
+ return err;
}
static int
@@ -310,7 +338,8 @@ static struct file_operations mtrr_fops = {
.read = seq_read,
.llseek = seq_lseek,
.write = mtrr_write,
- .ioctl = mtrr_ioctl,
+ .unlocked_ioctl = mtrr_ioctl,
+ .compat_ioctl = mtrr_ioctl,
.release = mtrr_close,
};
diff --git a/arch/i386/kernel/cpu/proc.c b/arch/i386/kernel/cpu/proc.c
index 8bd77d948a84..41b871ecf4b3 100644
--- a/arch/i386/kernel/cpu/proc.c
+++ b/arch/i386/kernel/cpu/proc.c
@@ -44,7 +44,7 @@ static int show_cpuinfo(struct seq_file *m, void *v)
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/* Intel-defined (#2) */
- "pni", NULL, NULL, "monitor", "ds_cpl", NULL, NULL, "est",
+ "pni", NULL, NULL, "monitor", "ds_cpl", "vmx", NULL, "est",
"tm2", NULL, "cid", NULL, NULL, "cx16", "xtpr", NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
diff --git a/arch/i386/kernel/cpuid.c b/arch/i386/kernel/cpuid.c
index 4647db4ad6de..13bae799e626 100644
--- a/arch/i386/kernel/cpuid.c
+++ b/arch/i386/kernel/cpuid.c
@@ -163,7 +163,7 @@ static int cpuid_class_device_create(int i)
int err = 0;
struct class_device *class_err;
- class_err = class_device_create(cpuid_class, MKDEV(CPUID_MAJOR, i), NULL, "cpu%d",i);
+ class_err = class_device_create(cpuid_class, NULL, MKDEV(CPUID_MAJOR, i), NULL, "cpu%d",i);
if (IS_ERR(class_err))
err = PTR_ERR(class_err);
return err;
diff --git a/arch/i386/kernel/crash.c b/arch/i386/kernel/crash.c
index 0248e084017c..af809ccf5fbe 100644
--- a/arch/i386/kernel/crash.c
+++ b/arch/i386/kernel/crash.c
@@ -21,7 +21,6 @@
#include <asm/hardirq.h>
#include <asm/nmi.h>
#include <asm/hw_irq.h>
-#include <asm/apic.h>
#include <mach_ipi.h>
@@ -148,7 +147,6 @@ static int crash_nmi_callback(struct pt_regs *regs, int cpu)
regs = &fixed_regs;
}
crash_save_this_cpu(regs, cpu);
- disable_local_APIC();
atomic_dec(&waiting_for_crash_ipi);
/* Assume hlt works */
halt();
@@ -188,7 +186,6 @@ static void nmi_shootdown_cpus(void)
}
/* Leave the nmi callback set */
- disable_local_APIC();
}
#else
static void nmi_shootdown_cpus(void)
@@ -213,9 +210,5 @@ void machine_crash_shutdown(struct pt_regs *regs)
/* Make a note of crashing cpu. Will be used in NMI callback.*/
crashing_cpu = smp_processor_id();
nmi_shootdown_cpus();
- lapic_shutdown();
-#if defined(CONFIG_X86_IO_APIC)
- disable_IO_APIC();
-#endif
crash_save_self(regs);
}
diff --git a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c
index fb3991e8229e..cc5d7ac5b2e7 100644
--- a/arch/i386/kernel/io_apic.c
+++ b/arch/i386/kernel/io_apic.c
@@ -46,6 +46,9 @@
int (*ioapic_renumber_irq)(int ioapic, int irq);
atomic_t irq_mis_count;
+/* Where if anywhere is the i8259 connect in external int mode */
+static struct { int pin, apic; } ioapic_i8259 = { -1, -1 };
+
static DEFINE_SPINLOCK(ioapic_lock);
/*
@@ -738,7 +741,7 @@ static int find_irq_entry(int apic, int pin, int type)
/*
* Find the pin to which IRQ[irq] (ISA) is connected
*/
-static int find_isa_irq_pin(int irq, int type)
+static int __init find_isa_irq_pin(int irq, int type)
{
int i;
@@ -758,6 +761,33 @@ static int find_isa_irq_pin(int irq, int type)
return -1;
}
+static int __init find_isa_irq_apic(int irq, int type)
+{
+ int i;
+
+ for (i = 0; i < mp_irq_entries; i++) {
+ int lbus = mp_irqs[i].mpc_srcbus;
+
+ if ((mp_bus_id_to_type[lbus] == MP_BUS_ISA ||
+ mp_bus_id_to_type[lbus] == MP_BUS_EISA ||
+ mp_bus_id_to_type[lbus] == MP_BUS_MCA ||
+ mp_bus_id_to_type[lbus] == MP_BUS_NEC98
+ ) &&
+ (mp_irqs[i].mpc_irqtype == type) &&
+ (mp_irqs[i].mpc_srcbusirq == irq))
+ break;
+ }
+ if (i < mp_irq_entries) {
+ int apic;
+ for(apic = 0; apic < nr_ioapics; apic++) {
+ if (mp_ioapics[apic].mpc_apicid == mp_irqs[i].mpc_dstapic)
+ return apic;
+ }
+ }
+
+ return -1;
+}
+
/*
* Find a specific PCI IRQ entry.
* Not an __init, possibly needed by modules
@@ -1253,7 +1283,7 @@ static void __init setup_IO_APIC_irqs(void)
/*
* Set up the 8259A-master output pin:
*/
-static void __init setup_ExtINT_IRQ0_pin(unsigned int pin, int vector)
+static void __init setup_ExtINT_IRQ0_pin(unsigned int apic, unsigned int pin, int vector)
{
struct IO_APIC_route_entry entry;
unsigned long flags;
@@ -1287,8 +1317,8 @@ static void __init setup_ExtINT_IRQ0_pin(unsigned int pin, int vector)
* Add it to the IO-APIC irq-routing table:
*/
spin_lock_irqsave(&ioapic_lock, flags);
- io_apic_write(0, 0x11+2*pin, *(((int *)&entry)+1));
- io_apic_write(0, 0x10+2*pin, *(((int *)&entry)+0));
+ io_apic_write(apic, 0x11+2*pin, *(((int *)&entry)+1));
+ io_apic_write(apic, 0x10+2*pin, *(((int *)&entry)+0));
spin_unlock_irqrestore(&ioapic_lock, flags);
enable_8259A_irq(0);
@@ -1595,7 +1625,8 @@ void /*__init*/ print_PIC(void)
static void __init enable_IO_APIC(void)
{
union IO_APIC_reg_01 reg_01;
- int i;
+ int i8259_apic, i8259_pin;
+ int i, apic;
unsigned long flags;
for (i = 0; i < PIN_MAP_SIZE; i++) {
@@ -1609,11 +1640,52 @@ static void __init enable_IO_APIC(void)
/*
* The number of IO-APIC IRQ registers (== #pins):
*/
- for (i = 0; i < nr_ioapics; i++) {
+ for (apic = 0; apic < nr_ioapics; apic++) {
spin_lock_irqsave(&ioapic_lock, flags);
- reg_01.raw = io_apic_read(i, 1);
+ reg_01.raw = io_apic_read(apic, 1);
spin_unlock_irqrestore(&ioapic_lock, flags);
- nr_ioapic_registers[i] = reg_01.bits.entries+1;
+ nr_ioapic_registers[apic] = reg_01.bits.entries+1;
+ }
+ for(apic = 0; apic < nr_ioapics; apic++) {
+ int pin;
+ /* See if any of the pins is in ExtINT mode */
+ for(pin = 0; pin < nr_ioapic_registers[i]; pin++) {
+ struct IO_APIC_route_entry entry;
+ spin_lock_irqsave(&ioapic_lock, flags);
+ *(((int *)&entry) + 0) = io_apic_read(apic, 0x10 + 2 * pin);
+ *(((int *)&entry) + 1) = io_apic_read(apic, 0x11 + 2 * pin);
+ spin_unlock_irqrestore(&ioapic_lock, flags);
+
+
+ /* If the interrupt line is enabled and in ExtInt mode
+ * I have found the pin where the i8259 is connected.
+ */
+ if ((entry.mask == 0) && (entry.delivery_mode == dest_ExtINT)) {
+ ioapic_i8259.apic = apic;
+ ioapic_i8259.pin = pin;
+ goto found_i8259;
+ }
+ }
+ }
+ found_i8259:
+ /* Look to see what if the MP table has reported the ExtINT */
+ /* If we could not find the appropriate pin by looking at the ioapic
+ * the i8259 probably is not connected the ioapic but give the
+ * mptable a chance anyway.
+ */
+ i8259_pin = find_isa_irq_pin(0, mp_ExtINT);
+ i8259_apic = find_isa_irq_apic(0, mp_ExtINT);
+ /* Trust the MP table if nothing is setup in the hardware */
+ if ((ioapic_i8259.pin == -1) && (i8259_pin >= 0)) {
+ printk(KERN_WARNING "ExtINT not setup in hardware but reported by MP table\n");
+ ioapic_i8259.pin = i8259_pin;
+ ioapic_i8259.apic = i8259_apic;
+ }
+ /* Complain if the MP table and the hardware disagree */
+ if (((ioapic_i8259.apic != i8259_apic) || (ioapic_i8259.pin != i8259_pin)) &&
+ (i8259_pin >= 0) && (ioapic_i8259.pin >= 0))
+ {
+ printk(KERN_WARNING "ExtINT in hardware and MP table differ\n");
}
/*
@@ -1627,7 +1699,6 @@ static void __init enable_IO_APIC(void)
*/
void disable_IO_APIC(void)
{
- int pin;
/*
* Clear the IO-APIC before rebooting:
*/
@@ -1638,8 +1709,7 @@ void disable_IO_APIC(void)
* Put that IOAPIC in virtual wire mode
* so legacy interrupts can be delivered.
*/
- pin = find_isa_irq_pin(0, mp_ExtINT);
- if (pin != -1) {
+ if (ioapic_i8259.pin != -1) {
struct IO_APIC_route_entry entry;
unsigned long flags;
@@ -1650,7 +1720,7 @@ void disable_IO_APIC(void)
entry.polarity = 0; /* High */
entry.delivery_status = 0;
entry.dest_mode = 0; /* Physical */
- entry.delivery_mode = 7; /* ExtInt */
+ entry.delivery_mode = dest_ExtINT; /* ExtInt */
entry.vector = 0;
entry.dest.physical.physical_dest = 0;
@@ -1659,11 +1729,13 @@ void disable_IO_APIC(void)
* Add it to the IO-APIC irq-routing table:
*/
spin_lock_irqsave(&ioapic_lock, flags);
- io_apic_write(0, 0x11+2*pin, *(((int *)&entry)+1));
- io_apic_write(0, 0x10+2*pin, *(((int *)&entry)+0));
+ io_apic_write(ioapic_i8259.apic, 0x11+2*ioapic_i8259.pin,
+ *(((int *)&entry)+1));
+ io_apic_write(ioapic_i8259.apic, 0x10+2*ioapic_i8259.pin,
+ *(((int *)&entry)+0));
spin_unlock_irqrestore(&ioapic_lock, flags);
}
- disconnect_bsp_APIC(pin != -1);
+ disconnect_bsp_APIC(ioapic_i8259.pin != -1);
}
/*
@@ -2113,20 +2185,21 @@ static void setup_nmi (void)
*/
static inline void unlock_ExtINT_logic(void)
{
- int pin, i;
+ int apic, pin, i;
struct IO_APIC_route_entry entry0, entry1;
unsigned char save_control, save_freq_select;
unsigned long flags;
- pin = find_isa_irq_pin(8, mp_INT);
+ pin = find_isa_irq_pin(8, mp_INT);
+ apic = find_isa_irq_apic(8, mp_INT);
if (pin == -1)
return;
spin_lock_irqsave(&ioapic_lock, flags);
- *(((int *)&entry0) + 1) = io_apic_read(0, 0x11 + 2 * pin);
- *(((int *)&entry0) + 0) = io_apic_read(0, 0x10 + 2 * pin);
+ *(((int *)&entry0) + 1) = io_apic_read(apic, 0x11 + 2 * pin);
+ *(((int *)&entry0) + 0) = io_apic_read(apic, 0x10 + 2 * pin);
spin_unlock_irqrestore(&ioapic_lock, flags);
- clear_IO_APIC_pin(0, pin);
+ clear_IO_APIC_pin(apic, pin);
memset(&entry1, 0, sizeof(entry1));
@@ -2139,8 +2212,8 @@ static inline void unlock_ExtINT_logic(void)
entry1.vector = 0;
spin_lock_irqsave(&ioapic_lock, flags);
- io_apic_write(0, 0x11 + 2 * pin, *(((int *)&entry1) + 1));
- io_apic_write(0, 0x10 + 2 * pin, *(((int *)&entry1) + 0));
+ io_apic_write(apic, 0x11 + 2 * pin, *(((int *)&entry1) + 1));
+ io_apic_write(apic, 0x10 + 2 * pin, *(((int *)&entry1) + 0));
spin_unlock_irqrestore(&ioapic_lock, flags);
save_control = CMOS_READ(RTC_CONTROL);
@@ -2158,11 +2231,11 @@ static inline void unlock_ExtINT_logic(void)
CMOS_WRITE(save_control, RTC_CONTROL);
CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT);
- clear_IO_APIC_pin(0, pin);
+ clear_IO_APIC_pin(apic, pin);
spin_lock_irqsave(&ioapic_lock, flags);
- io_apic_write(0, 0x11 + 2 * pin, *(((int *)&entry0) + 1));
- io_apic_write(0, 0x10 + 2 * pin, *(((int *)&entry0) + 0));
+ io_apic_write(apic, 0x11 + 2 * pin, *(((int *)&entry0) + 1));
+ io_apic_write(apic, 0x10 + 2 * pin, *(((int *)&entry0) + 0));
spin_unlock_irqrestore(&ioapic_lock, flags);
}
@@ -2174,7 +2247,7 @@ static inline void unlock_ExtINT_logic(void)
*/
static inline void check_timer(void)
{
- int pin1, pin2;
+ int apic1, pin1, apic2, pin2;
int vector;
/*
@@ -2196,10 +2269,13 @@ static inline void check_timer(void)
timer_ack = 1;
enable_8259A_irq(0);
- pin1 = find_isa_irq_pin(0, mp_INT);
- pin2 = find_isa_irq_pin(0, mp_ExtINT);
+ pin1 = find_isa_irq_pin(0, mp_INT);
+ apic1 = find_isa_irq_apic(0, mp_INT);
+ pin2 = ioapic_i8259.pin;
+ apic2 = ioapic_i8259.apic;
- printk(KERN_INFO "..TIMER: vector=0x%02X pin1=%d pin2=%d\n", vector, pin1, pin2);
+ printk(KERN_INFO "..TIMER: vector=0x%02X apic1=%d pin1=%d apic2=%d pin2=%d\n",
+ vector, apic1, pin1, apic2, pin2);
if (pin1 != -1) {
/*
@@ -2216,8 +2292,9 @@ static inline void check_timer(void)
clear_IO_APIC_pin(0, pin1);
return;
}
- clear_IO_APIC_pin(0, pin1);
- printk(KERN_ERR "..MP-BIOS bug: 8254 timer not connected to IO-APIC\n");
+ clear_IO_APIC_pin(apic1, pin1);
+ printk(KERN_ERR "..MP-BIOS bug: 8254 timer not connected to "
+ "IO-APIC\n");
}
printk(KERN_INFO "...trying to set up timer (IRQ0) through the 8259A ... ");
@@ -2226,13 +2303,13 @@ static inline void check_timer(void)
/*
* legacy devices should be connected to IO APIC #0
*/
- setup_ExtINT_IRQ0_pin(pin2, vector);
+ setup_ExtINT_IRQ0_pin(apic2, pin2, vector);
if (timer_irq_works()) {
printk("works.\n");
if (pin1 != -1)
- replace_pin_at_irq(0, 0, pin1, 0, pin2);
+ replace_pin_at_irq(0, apic1, pin1, apic2, pin2);
else
- add_pin_to_irq(0, 0, pin2);
+ add_pin_to_irq(0, apic2, pin2);
if (nmi_watchdog == NMI_IO_APIC) {
setup_nmi();
}
@@ -2241,7 +2318,7 @@ static inline void check_timer(void)
/*
* Cleanup, just in case ...
*/
- clear_IO_APIC_pin(0, pin2);
+ clear_IO_APIC_pin(apic2, pin2);
}
printk(" failed.\n");
diff --git a/arch/i386/kernel/ioport.c b/arch/i386/kernel/ioport.c
index f2b37654777f..b59a34dbe262 100644
--- a/arch/i386/kernel/ioport.c
+++ b/arch/i386/kernel/ioport.c
@@ -108,8 +108,11 @@ asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int turn_on)
/*
* Sets the lazy trigger so that the next I/O operation will
* reload the correct bitmap.
+ * Reset the owner so that a process switch will not set
+ * tss->io_bitmap_base to IO_BITMAP_OFFSET.
*/
tss->io_bitmap_base = INVALID_IO_BITMAP_OFFSET_LAZY;
+ tss->io_bitmap_owner = NULL;
put_cpu();
diff --git a/arch/i386/kernel/irq.c b/arch/i386/kernel/irq.c
index ce66dcc26d90..1a201a932865 100644
--- a/arch/i386/kernel/irq.c
+++ b/arch/i386/kernel/irq.c
@@ -218,7 +218,7 @@ int show_interrupts(struct seq_file *p, void *v)
if (i == 0) {
seq_printf(p, " ");
- for_each_cpu(j)
+ for_each_online_cpu(j)
seq_printf(p, "CPU%d ",j);
seq_putc(p, '\n');
}
@@ -232,7 +232,7 @@ int show_interrupts(struct seq_file *p, void *v)
#ifndef CONFIG_SMP
seq_printf(p, "%10u ", kstat_irqs(i));
#else
- for_each_cpu(j)
+ for_each_online_cpu(j)
seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
#endif
seq_printf(p, " %14s", irq_desc[i].handler->typename);
@@ -246,12 +246,12 @@ skip:
spin_unlock_irqrestore(&irq_desc[i].lock, flags);
} else if (i == NR_IRQS) {
seq_printf(p, "NMI: ");
- for_each_cpu(j)
+ for_each_online_cpu(j)
seq_printf(p, "%10u ", nmi_count(j));
seq_putc(p, '\n');
#ifdef CONFIG_X86_LOCAL_APIC
seq_printf(p, "LOC: ");
- for_each_cpu(j)
+ for_each_online_cpu(j)
seq_printf(p, "%10u ",
per_cpu(irq_stat,j).apic_timer_irqs);
seq_putc(p, '\n');
diff --git a/arch/i386/kernel/kprobes.c b/arch/i386/kernel/kprobes.c
index 6345b430b105..32b0c24ab9a6 100644
--- a/arch/i386/kernel/kprobes.c
+++ b/arch/i386/kernel/kprobes.c
@@ -31,22 +31,16 @@
#include <linux/config.h>
#include <linux/kprobes.h>
#include <linux/ptrace.h>
-#include <linux/spinlock.h>
#include <linux/preempt.h>
#include <asm/cacheflush.h>
#include <asm/kdebug.h>
#include <asm/desc.h>
-static struct kprobe *current_kprobe;
-static unsigned long kprobe_status, kprobe_old_eflags, kprobe_saved_eflags;
-static struct kprobe *kprobe_prev;
-static unsigned long kprobe_status_prev, kprobe_old_eflags_prev, kprobe_saved_eflags_prev;
-static struct pt_regs jprobe_saved_regs;
-static long *jprobe_saved_esp;
-/* copy of the kernel stack at the probe fire time */
-static kprobe_opcode_t jprobes_stack[MAX_STACK_SIZE];
void jprobe_return_end(void);
+DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
+DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
+
/*
* returns non-zero if opcode modifies the interrupt flag.
*/
@@ -91,29 +85,30 @@ void __kprobes arch_remove_kprobe(struct kprobe *p)
{
}
-static inline void save_previous_kprobe(void)
+static inline void save_previous_kprobe(struct kprobe_ctlblk *kcb)
{
- kprobe_prev = current_kprobe;
- kprobe_status_prev = kprobe_status;
- kprobe_old_eflags_prev = kprobe_old_eflags;
- kprobe_saved_eflags_prev = kprobe_saved_eflags;
+ kcb->prev_kprobe.kp = kprobe_running();
+ kcb->prev_kprobe.status = kcb->kprobe_status;
+ kcb->prev_kprobe.old_eflags = kcb->kprobe_old_eflags;
+ kcb->prev_kprobe.saved_eflags = kcb->kprobe_saved_eflags;
}
-static inline void restore_previous_kprobe(void)
+static inline void restore_previous_kprobe(struct kprobe_ctlblk *kcb)
{
- current_kprobe = kprobe_prev;
- kprobe_status = kprobe_status_prev;
- kprobe_old_eflags = kprobe_old_eflags_prev;
- kprobe_saved_eflags = kprobe_saved_eflags_prev;
+ __get_cpu_var(current_kprobe) = kcb->prev_kprobe.kp;
+ kcb->kprobe_status = kcb->prev_kprobe.status;
+ kcb->kprobe_old_eflags = kcb->prev_kprobe.old_eflags;
+ kcb->kprobe_saved_eflags = kcb->prev_kprobe.saved_eflags;
}
-static inline void set_current_kprobe(struct kprobe *p, struct pt_regs *regs)
+static inline void set_current_kprobe(struct kprobe *p, struct pt_regs *regs,
+ struct kprobe_ctlblk *kcb)
{
- current_kprobe = p;
- kprobe_saved_eflags = kprobe_old_eflags
+ __get_cpu_var(current_kprobe) = p;
+ kcb->kprobe_saved_eflags = kcb->kprobe_old_eflags
= (regs->eflags & (TF_MASK | IF_MASK));
if (is_IF_modifier(p->opcode))
- kprobe_saved_eflags &= ~IF_MASK;
+ kcb->kprobe_saved_eflags &= ~IF_MASK;
}
static inline void prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
@@ -127,6 +122,7 @@ static inline void prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
regs->eip = (unsigned long)&p->ainsn.insn;
}
+/* Called with kretprobe_lock held */
void __kprobes arch_prepare_kretprobe(struct kretprobe *rp,
struct pt_regs *regs)
{
@@ -157,9 +153,15 @@ static int __kprobes kprobe_handler(struct pt_regs *regs)
int ret = 0;
kprobe_opcode_t *addr = NULL;
unsigned long *lp;
+ struct kprobe_ctlblk *kcb;
- /* We're in an interrupt, but this is clear and BUG()-safe. */
+ /*
+ * We don't want to be preempted for the entire
+ * duration of kprobe processing
+ */
preempt_disable();
+ kcb = get_kprobe_ctlblk();
+
/* Check if the application is using LDT entry for its code segment and
* calculate the address by reading the base address from the LDT entry.
*/
@@ -173,15 +175,12 @@ static int __kprobes kprobe_handler(struct pt_regs *regs)
}
/* Check we're not actually recursing */
if (kprobe_running()) {
- /* We *are* holding lock here, so this is safe.
- Disarm the probe we just hit, and ignore it. */
p = get_kprobe(addr);
if (p) {
- if (kprobe_status == KPROBE_HIT_SS &&
+ if (kcb->kprobe_status == KPROBE_HIT_SS &&
*p->ainsn.insn == BREAKPOINT_INSTRUCTION) {
regs->eflags &= ~TF_MASK;
- regs->eflags |= kprobe_saved_eflags;
- unlock_kprobes();
+ regs->eflags |= kcb->kprobe_saved_eflags;
goto no_kprobe;
}
/* We have reentered the kprobe_handler(), since
@@ -190,26 +189,23 @@ static int __kprobes kprobe_handler(struct pt_regs *regs)
* just single step on the instruction of the new probe
* without calling any user handlers.
*/
- save_previous_kprobe();
- set_current_kprobe(p, regs);
+ save_previous_kprobe(kcb);
+ set_current_kprobe(p, regs, kcb);
p->nmissed++;
prepare_singlestep(p, regs);
- kprobe_status = KPROBE_REENTER;
+ kcb->kprobe_status = KPROBE_REENTER;
return 1;
} else {
- p = current_kprobe;
+ p = __get_cpu_var(current_kprobe);
if (p->break_handler && p->break_handler(p, regs)) {
goto ss_probe;
}
}
- /* If it's not ours, can't be delete race, (we hold lock). */
goto no_kprobe;
}
- lock_kprobes();
p = get_kprobe(addr);
if (!p) {
- unlock_kprobes();
if (regs->eflags & VM_MASK) {
/* We are in virtual-8086 mode. Return 0 */
goto no_kprobe;
@@ -232,8 +228,8 @@ static int __kprobes kprobe_handler(struct pt_regs *regs)
goto no_kprobe;
}
- kprobe_status = KPROBE_HIT_ACTIVE;
- set_current_kprobe(p, regs);
+ set_current_kprobe(p, regs, kcb);
+ kcb->kprobe_status = KPROBE_HIT_ACTIVE;
if (p->pre_handler && p->pre_handler(p, regs))
/* handler has already set things up, so skip ss setup */
@@ -241,7 +237,7 @@ static int __kprobes kprobe_handler(struct pt_regs *regs)
ss_probe:
prepare_singlestep(p, regs);
- kprobe_status = KPROBE_HIT_SS;
+ kcb->kprobe_status = KPROBE_HIT_SS;
return 1;
no_kprobe:
@@ -269,9 +265,10 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
struct kretprobe_instance *ri = NULL;
struct hlist_head *head;
struct hlist_node *node, *tmp;
- unsigned long orig_ret_address = 0;
+ unsigned long flags, orig_ret_address = 0;
unsigned long trampoline_address =(unsigned long)&kretprobe_trampoline;
+ spin_lock_irqsave(&kretprobe_lock, flags);
head = kretprobe_inst_table_head(current);
/*
@@ -310,14 +307,15 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
BUG_ON(!orig_ret_address || (orig_ret_address == trampoline_address));
regs->eip = orig_ret_address;
- unlock_kprobes();
+ reset_current_kprobe();
+ spin_unlock_irqrestore(&kretprobe_lock, flags);
preempt_enable_no_resched();
- /*
- * By returning a non-zero value, we are telling
- * kprobe_handler() that we have handled unlocking
- * and re-enabling preemption.
- */
+ /*
+ * By returning a non-zero value, we are telling
+ * kprobe_handler() that we don't want the post_handler
+ * to run (and have re-enabled preemption)
+ */
return 1;
}
@@ -343,7 +341,8 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
* that is atop the stack is the address following the copied instruction.
* We need to make it the address following the original instruction.
*/
-static void __kprobes resume_execution(struct kprobe *p, struct pt_regs *regs)
+static void __kprobes resume_execution(struct kprobe *p,
+ struct pt_regs *regs, struct kprobe_ctlblk *kcb)
{
unsigned long *tos = (unsigned long *)&regs->esp;
unsigned long next_eip = 0;
@@ -353,7 +352,7 @@ static void __kprobes resume_execution(struct kprobe *p, struct pt_regs *regs)
switch (p->ainsn.insn[0]) {
case 0x9c: /* pushfl */
*tos &= ~(TF_MASK | IF_MASK);
- *tos |= kprobe_old_eflags;
+ *tos |= kcb->kprobe_old_eflags;
break;
case 0xc3: /* ret/lret */
case 0xcb:
@@ -394,27 +393,30 @@ static void __kprobes resume_execution(struct kprobe *p, struct pt_regs *regs)
/*
* Interrupts are disabled on entry as trap1 is an interrupt gate and they
- * remain disabled thoroughout this function. And we hold kprobe lock.
+ * remain disabled thoroughout this function.
*/
static inline int post_kprobe_handler(struct pt_regs *regs)
{
- if (!kprobe_running())
+ struct kprobe *cur = kprobe_running();
+ struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
+
+ if (!cur)
return 0;
- if ((kprobe_status != KPROBE_REENTER) && current_kprobe->post_handler) {
- kprobe_status = KPROBE_HIT_SSDONE;
- current_kprobe->post_handler(current_kprobe, regs, 0);
+ if ((kcb->kprobe_status != KPROBE_REENTER) && cur->post_handler) {
+ kcb->kprobe_status = KPROBE_HIT_SSDONE;
+ cur->post_handler(cur, regs, 0);
}
- resume_execution(current_kprobe, regs);
- regs->eflags |= kprobe_saved_eflags;
+ resume_execution(cur, regs, kcb);
+ regs->eflags |= kcb->kprobe_saved_eflags;
/*Restore back the original saved kprobes variables and continue. */
- if (kprobe_status == KPROBE_REENTER) {
- restore_previous_kprobe();
+ if (kcb->kprobe_status == KPROBE_REENTER) {
+ restore_previous_kprobe(kcb);
goto out;
}
- unlock_kprobes();
+ reset_current_kprobe();
out:
preempt_enable_no_resched();
@@ -429,18 +431,19 @@ out:
return 1;
}
-/* Interrupts disabled, kprobe_lock held. */
static inline int kprobe_fault_handler(struct pt_regs *regs, int trapnr)
{
- if (current_kprobe->fault_handler
- && current_kprobe->fault_handler(current_kprobe, regs, trapnr))
+ struct kprobe *cur = kprobe_running();
+ struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
+
+ if (cur->fault_handler && cur->fault_handler(cur, regs, trapnr))
return 1;
- if (kprobe_status & KPROBE_HIT_SS) {
- resume_execution(current_kprobe, regs);
- regs->eflags |= kprobe_old_eflags;
+ if (kcb->kprobe_status & KPROBE_HIT_SS) {
+ resume_execution(cur, regs, kcb);
+ regs->eflags |= kcb->kprobe_old_eflags;
- unlock_kprobes();
+ reset_current_kprobe();
preempt_enable_no_resched();
}
return 0;
@@ -453,39 +456,41 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
unsigned long val, void *data)
{
struct die_args *args = (struct die_args *)data;
+ int ret = NOTIFY_DONE;
+
switch (val) {
case DIE_INT3:
if (kprobe_handler(args->regs))
- return NOTIFY_STOP;
+ ret = NOTIFY_STOP;
break;
case DIE_DEBUG:
if (post_kprobe_handler(args->regs))
- return NOTIFY_STOP;
+ ret = NOTIFY_STOP;
break;
case DIE_GPF:
- if (kprobe_running() &&
- kprobe_fault_handler(args->regs, args->trapnr))
- return NOTIFY_STOP;
- break;
case DIE_PAGE_FAULT:
+ /* kprobe_running() needs smp_processor_id() */
+ preempt_disable();
if (kprobe_running() &&
kprobe_fault_handler(args->regs, args->trapnr))
- return NOTIFY_STOP;
+ ret = NOTIFY_STOP;
+ preempt_enable();
break;
default:
break;
}
- return NOTIFY_DONE;
+ return ret;
}
int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
{
struct jprobe *jp = container_of(p, struct jprobe, kp);
unsigned long addr;
+ struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
- jprobe_saved_regs = *regs;
- jprobe_saved_esp = &regs->esp;
- addr = (unsigned long)jprobe_saved_esp;
+ kcb->jprobe_saved_regs = *regs;
+ kcb->jprobe_saved_esp = &regs->esp;
+ addr = (unsigned long)(kcb->jprobe_saved_esp);
/*
* TBD: As Linus pointed out, gcc assumes that the callee
@@ -494,7 +499,8 @@ int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
* we also save and restore enough stack bytes to cover
* the argument area.
*/
- memcpy(jprobes_stack, (kprobe_opcode_t *) addr, MIN_STACK_SIZE(addr));
+ memcpy(kcb->jprobes_stack, (kprobe_opcode_t *)addr,
+ MIN_STACK_SIZE(addr));
regs->eflags &= ~IF_MASK;
regs->eip = (unsigned long)(jp->entry);
return 1;
@@ -502,36 +508,40 @@ int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
void __kprobes jprobe_return(void)
{
- preempt_enable_no_resched();
+ struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
+
asm volatile (" xchgl %%ebx,%%esp \n"
" int3 \n"
" .globl jprobe_return_end \n"
" jprobe_return_end: \n"
" nop \n"::"b"
- (jprobe_saved_esp):"memory");
+ (kcb->jprobe_saved_esp):"memory");
}
int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
{
+ struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
u8 *addr = (u8 *) (regs->eip - 1);
- unsigned long stack_addr = (unsigned long)jprobe_saved_esp;
+ unsigned long stack_addr = (unsigned long)(kcb->jprobe_saved_esp);
struct jprobe *jp = container_of(p, struct jprobe, kp);
if ((addr > (u8 *) jprobe_return) && (addr < (u8 *) jprobe_return_end)) {
- if (&regs->esp != jprobe_saved_esp) {
+ if (&regs->esp != kcb->jprobe_saved_esp) {
struct pt_regs *saved_regs =
- container_of(jprobe_saved_esp, struct pt_regs, esp);
+ container_of(kcb->jprobe_saved_esp,
+ struct pt_regs, esp);
printk("current esp %p does not match saved esp %p\n",
- &regs->esp, jprobe_saved_esp);
+ &regs->esp, kcb->jprobe_saved_esp);
printk("Saved registers for jprobe %p\n", jp);
show_registers(saved_regs);
printk("Current registers\n");
show_registers(regs);
BUG();
}
- *regs = jprobe_saved_regs;
- memcpy((kprobe_opcode_t *) stack_addr, jprobes_stack,
+ *regs = kcb->jprobe_saved_regs;
+ memcpy((kprobe_opcode_t *) stack_addr, kcb->jprobes_stack,
MIN_STACK_SIZE(stack_addr));
+ preempt_enable_no_resched();
return 1;
}
return 0;
diff --git a/arch/i386/kernel/ldt.c b/arch/i386/kernel/ldt.c
index fe1ffa55587d..983f95707e11 100644
--- a/arch/i386/kernel/ldt.c
+++ b/arch/i386/kernel/ldt.c
@@ -18,6 +18,7 @@
#include <asm/system.h>
#include <asm/ldt.h>
#include <asm/desc.h>
+#include <asm/mmu_context.h>
#ifdef CONFIG_SMP /* avoids "defined but not used" warnig */
static void flush_ldt(void *null)
diff --git a/arch/i386/kernel/mca.c b/arch/i386/kernel/mca.c
index 8600faeea29d..558bb207720f 100644
--- a/arch/i386/kernel/mca.c
+++ b/arch/i386/kernel/mca.c
@@ -132,7 +132,7 @@ static struct resource mca_standard_resources[] = {
{ .start = 0x100, .end = 0x107, .name = "POS (MCA)" }
};
-#define MCA_STANDARD_RESOURCES (sizeof(mca_standard_resources)/sizeof(struct resource))
+#define MCA_STANDARD_RESOURCES ARRAY_SIZE(mca_standard_resources)
/**
* mca_read_and_store_pos - read the POS registers into a memory buffer
diff --git a/arch/i386/kernel/mpparse.c b/arch/i386/kernel/mpparse.c
index 27aabfceb67e..8f767d9aa45d 100644
--- a/arch/i386/kernel/mpparse.c
+++ b/arch/i386/kernel/mpparse.c
@@ -69,7 +69,7 @@ unsigned int def_to_bigsmp = 0;
/* Processor that is doing the boot up */
unsigned int boot_cpu_physical_apicid = -1U;
/* Internal processor count */
-static unsigned int __initdata num_processors;
+static unsigned int __devinitdata num_processors;
/* Bitmask of physically existing CPUs */
physid_mask_t phys_cpu_present_map;
@@ -119,7 +119,7 @@ static int MP_valid_apicid(int apicid, int version)
}
#endif
-static void __init MP_processor_info (struct mpc_config_processor *m)
+static void __devinit MP_processor_info (struct mpc_config_processor *m)
{
int ver, apicid;
physid_mask_t phys_cpu;
@@ -182,17 +182,6 @@ static void __init MP_processor_info (struct mpc_config_processor *m)
boot_cpu_physical_apicid = m->mpc_apicid;
}
- if (num_processors >= NR_CPUS) {
- printk(KERN_WARNING "WARNING: NR_CPUS limit of %i reached."
- " Processor ignored.\n", NR_CPUS);
- return;
- }
-
- if (num_processors >= maxcpus) {
- printk(KERN_WARNING "WARNING: maxcpus limit of %i reached."
- " Processor ignored.\n", maxcpus);
- return;
- }
ver = m->mpc_apicver;
if (!MP_valid_apicid(apicid, ver)) {
@@ -201,11 +190,6 @@ static void __init MP_processor_info (struct mpc_config_processor *m)
return;
}
- cpu_set(num_processors, cpu_possible_map);
- num_processors++;
- phys_cpu = apicid_to_cpu_present(apicid);
- physids_or(phys_cpu_present_map, phys_cpu_present_map, phys_cpu);
-
/*
* Validate version
*/
@@ -216,6 +200,25 @@ static void __init MP_processor_info (struct mpc_config_processor *m)
ver = 0x10;
}
apic_version[m->mpc_apicid] = ver;
+
+ phys_cpu = apicid_to_cpu_present(apicid);
+ physids_or(phys_cpu_present_map, phys_cpu_present_map, phys_cpu);
+
+ if (num_processors >= NR_CPUS) {
+ printk(KERN_WARNING "WARNING: NR_CPUS limit of %i reached."
+ " Processor ignored.\n", NR_CPUS);
+ return;
+ }
+
+ if (num_processors >= maxcpus) {
+ printk(KERN_WARNING "WARNING: maxcpus limit of %i reached."
+ " Processor ignored.\n", maxcpus);
+ return;
+ }
+
+ cpu_set(num_processors, cpu_possible_map);
+ num_processors++;
+
if ((num_processors > 8) &&
APIC_XAPIC(ver) &&
(boot_cpu_data.x86_vendor == X86_VENDOR_INTEL))
@@ -834,7 +837,7 @@ void __init mp_register_lapic_address (
}
-void __init mp_register_lapic (
+void __devinit mp_register_lapic (
u8 id,
u8 enabled)
{
diff --git a/arch/i386/kernel/msr.c b/arch/i386/kernel/msr.c
index 03100d6fc5d6..44470fea4309 100644
--- a/arch/i386/kernel/msr.c
+++ b/arch/i386/kernel/msr.c
@@ -246,7 +246,7 @@ static int msr_class_device_create(int i)
int err = 0;
struct class_device *class_err;
- class_err = class_device_create(msr_class, MKDEV(MSR_MAJOR, i), NULL, "msr%d",i);
+ class_err = class_device_create(msr_class, NULL, MKDEV(MSR_MAJOR, i), NULL, "msr%d",i);
if (IS_ERR(class_err))
err = PTR_ERR(class_err);
return err;
diff --git a/arch/i386/kernel/nmi.c b/arch/i386/kernel/nmi.c
index 72515b8a1b12..d661703ac1cb 100644
--- a/arch/i386/kernel/nmi.c
+++ b/arch/i386/kernel/nmi.c
@@ -100,16 +100,44 @@ int nmi_active;
(P4_CCCR_OVF_PMI0|P4_CCCR_THRESHOLD(15)|P4_CCCR_COMPLEMENT| \
P4_CCCR_COMPARE|P4_CCCR_REQUIRED|P4_CCCR_ESCR_SELECT(4)|P4_CCCR_ENABLE)
+#ifdef CONFIG_SMP
+/* The performance counters used by NMI_LOCAL_APIC don't trigger when
+ * the CPU is idle. To make sure the NMI watchdog really ticks on all
+ * CPUs during the test make them busy.
+ */
+static __init void nmi_cpu_busy(void *data)
+{
+ volatile int *endflag = data;
+ local_irq_enable();
+ /* Intentionally don't use cpu_relax here. This is
+ to make sure that the performance counter really ticks,
+ even if there is a simulator or similar that catches the
+ pause instruction. On a real HT machine this is fine because
+ all other CPUs are busy with "useless" delay loops and don't
+ care if they get somewhat less cycles. */
+ while (*endflag == 0)
+ barrier();
+}
+#endif
+
static int __init check_nmi_watchdog(void)
{
- unsigned int prev_nmi_count[NR_CPUS];
+ volatile int endflag = 0;
+ unsigned int *prev_nmi_count;
int cpu;
if (nmi_watchdog == NMI_NONE)
return 0;
+ prev_nmi_count = kmalloc(NR_CPUS * sizeof(int), GFP_KERNEL);
+ if (!prev_nmi_count)
+ return -1;
+
printk(KERN_INFO "Testing NMI watchdog ... ");
+ if (nmi_watchdog == NMI_LOCAL_APIC)
+ smp_call_function(nmi_cpu_busy, (void *)&endflag, 0, 0);
+
for (cpu = 0; cpu < NR_CPUS; cpu++)
prev_nmi_count[cpu] = per_cpu(irq_stat, cpu).__nmi_count;
local_irq_enable();
@@ -123,12 +151,18 @@ static int __init check_nmi_watchdog(void)
continue;
#endif
if (nmi_count(cpu) - prev_nmi_count[cpu] <= 5) {
- printk("CPU#%d: NMI appears to be stuck!\n", cpu);
+ endflag = 1;
+ printk("CPU#%d: NMI appears to be stuck (%d->%d)!\n",
+ cpu,
+ prev_nmi_count[cpu],
+ nmi_count(cpu));
nmi_active = 0;
lapic_nmi_owner &= ~LAPIC_NMI_WATCHDOG;
+ kfree(prev_nmi_count);
return -1;
}
}
+ endflag = 1;
printk("OK.\n");
/* now that we know it works we can reduce NMI frequency to
@@ -136,6 +170,7 @@ static int __init check_nmi_watchdog(void)
if (nmi_watchdog == NMI_LOCAL_APIC)
nmi_hz = 1;
+ kfree(prev_nmi_count);
return 0;
}
/* This needs to happen later in boot so counters are working */
diff --git a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c
index 7a14fdfd3af9..1cb261f225d5 100644
--- a/arch/i386/kernel/process.c
+++ b/arch/i386/kernel/process.c
@@ -99,14 +99,22 @@ EXPORT_SYMBOL(enable_hlt);
*/
void default_idle(void)
{
+ local_irq_enable();
+
if (!hlt_counter && boot_cpu_data.hlt_works_ok) {
- local_irq_disable();
- if (!need_resched())
- safe_halt();
- else
- local_irq_enable();
+ clear_thread_flag(TIF_POLLING_NRFLAG);
+ smp_mb__after_clear_bit();
+ while (!need_resched()) {
+ local_irq_disable();
+ if (!need_resched())
+ safe_halt();
+ else
+ local_irq_enable();
+ }
+ set_thread_flag(TIF_POLLING_NRFLAG);
} else {
- cpu_relax();
+ while (!need_resched())
+ cpu_relax();
}
}
#ifdef CONFIG_APM_MODULE
@@ -120,29 +128,14 @@ EXPORT_SYMBOL(default_idle);
*/
static void poll_idle (void)
{
- int oldval;
-
local_irq_enable();
- /*
- * Deal with another CPU just having chosen a thread to
- * run here:
- */
- oldval = test_and_clear_thread_flag(TIF_NEED_RESCHED);
-
- if (!oldval) {
- set_thread_flag(TIF_POLLING_NRFLAG);
- asm volatile(
- "2:"
- "testl %0, %1;"
- "rep; nop;"
- "je 2b;"
- : : "i"(_TIF_NEED_RESCHED), "m" (current_thread_info()->flags));
-
- clear_thread_flag(TIF_POLLING_NRFLAG);
- } else {
- set_need_resched();
- }
+ asm volatile(
+ "2:"
+ "testl %0, %1;"
+ "rep; nop;"
+ "je 2b;"
+ : : "i"(_TIF_NEED_RESCHED), "m" (current_thread_info()->flags));
}
#ifdef CONFIG_HOTPLUG_CPU
@@ -179,7 +172,9 @@ static inline void play_dead(void)
*/
void cpu_idle(void)
{
- int cpu = raw_smp_processor_id();
+ int cpu = smp_processor_id();
+
+ set_thread_flag(TIF_POLLING_NRFLAG);
/* endless idle loop with no priority at all */
while (1) {
@@ -201,7 +196,9 @@ void cpu_idle(void)
__get_cpu_var(irq_stat).idle_timestamp = jiffies;
idle();
}
+ preempt_enable_no_resched();
schedule();
+ preempt_disable();
}
}
@@ -244,15 +241,12 @@ static void mwait_idle(void)
{
local_irq_enable();
- if (!need_resched()) {
- set_thread_flag(TIF_POLLING_NRFLAG);
- do {
- __monitor((void *)&current_thread_info()->flags, 0, 0);
- if (need_resched())
- break;
- __mwait(0, 0);
- } while (!need_resched());
- clear_thread_flag(TIF_POLLING_NRFLAG);
+ while (!need_resched()) {
+ __monitor((void *)&current_thread_info()->flags, 0, 0);
+ smp_mb();
+ if (need_resched())
+ break;
+ __mwait(0, 0);
}
}
diff --git a/arch/i386/kernel/ptrace.c b/arch/i386/kernel/ptrace.c
index 7b6368bf8974..5ffbb4b7ad05 100644
--- a/arch/i386/kernel/ptrace.c
+++ b/arch/i386/kernel/ptrace.c
@@ -354,49 +354,12 @@ ptrace_set_thread_area(struct task_struct *child,
return 0;
}
-asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request, long addr, long data)
{
- struct task_struct *child;
struct user * dummy = NULL;
int i, ret;
unsigned long __user *datap = (unsigned long __user *)data;
- lock_kernel();
- ret = -EPERM;
- if (request == PTRACE_TRACEME) {
- /* are we already being traced? */
- if (current->ptrace & PT_PTRACED)
- goto out;
- ret = security_ptrace(current->parent, current);
- if (ret)
- goto out;
- /* set the ptrace bit in the process flags. */
- current->ptrace |= PT_PTRACED;
- ret = 0;
- goto out;
- }
- ret = -ESRCH;
- read_lock(&tasklist_lock);
- child = find_task_by_pid(pid);
- if (child)
- get_task_struct(child);
- read_unlock(&tasklist_lock);
- if (!child)
- goto out;
-
- ret = -EPERM;
- if (pid == 1) /* you may not mess with init */
- goto out_tsk;
-
- if (request == PTRACE_ATTACH) {
- ret = ptrace_attach(child);
- goto out_tsk;
- }
-
- ret = ptrace_check_attach(child, request == PTRACE_KILL);
- if (ret < 0)
- goto out_tsk;
-
switch (request) {
/* when I and D space are separate, these will need to be fixed. */
case PTRACE_PEEKTEXT: /* read word at location addr. */
@@ -663,10 +626,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
ret = ptrace_request(child, request, addr, data);
break;
}
-out_tsk:
- put_task_struct(child);
-out:
- unlock_kernel();
+ out_tsk:
return ret;
}
diff --git a/arch/i386/kernel/reboot_fixups.c b/arch/i386/kernel/reboot_fixups.c
index 1b183b378c2c..10e21a4773dd 100644
--- a/arch/i386/kernel/reboot_fixups.c
+++ b/arch/i386/kernel/reboot_fixups.c
@@ -10,6 +10,7 @@
#include <asm/delay.h>
#include <linux/pci.h>
+#include <linux/reboot_fixups.h>
static void cs5530a_warm_reset(struct pci_dev *dev)
{
@@ -42,9 +43,9 @@ void mach_reboot_fixups(void)
struct pci_dev *dev;
int i;
- for (i=0; i < (sizeof(fixups_table)/sizeof(fixups_table[0])); i++) {
+ for (i=0; i < ARRAY_SIZE(fixups_table); i++) {
cur = &(fixups_table[i]);
- dev = pci_get_device(cur->vendor, cur->device, 0);
+ dev = pci_get_device(cur->vendor, cur->device, NULL);
if (!dev)
continue;
diff --git a/arch/i386/kernel/scx200.c b/arch/i386/kernel/scx200.c
index 69e203a0d330..9c968ae67c43 100644
--- a/arch/i386/kernel/scx200.c
+++ b/arch/i386/kernel/scx200.c
@@ -12,6 +12,7 @@
#include <linux/pci.h>
#include <linux/scx200.h>
+#include <linux/scx200_gpio.h>
/* Verify that the configuration block really is there */
#define scx200_cb_probe(base) (inw((base) + SCx200_CBA) == (base))
diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c
index 9b8c8a19824d..fdfcb0cba9b4 100644
--- a/arch/i386/kernel/setup.c
+++ b/arch/i386/kernel/setup.c
@@ -129,9 +129,7 @@ struct drive_info_struct { char dummy[32]; } drive_info;
EXPORT_SYMBOL(drive_info);
#endif
struct screen_info screen_info;
-#ifdef CONFIG_VT
EXPORT_SYMBOL(screen_info);
-#endif
struct apm_info apm_info;
EXPORT_SYMBOL(apm_info);
struct sys_desc_table_struct {
@@ -389,14 +387,24 @@ static void __init limit_regions(unsigned long long size)
}
}
for (i = 0; i < e820.nr_map; i++) {
- if (e820.map[i].type == E820_RAM) {
- current_addr = e820.map[i].addr + e820.map[i].size;
- if (current_addr >= size) {
- e820.map[i].size -= current_addr-size;
- e820.nr_map = i + 1;
- return;
- }
+ current_addr = e820.map[i].addr + e820.map[i].size;
+ if (current_addr < size)
+ continue;
+
+ if (e820.map[i].type != E820_RAM)
+ continue;
+
+ if (e820.map[i].addr >= size) {
+ /*
+ * This region starts past the end of the
+ * requested size, skip it completely.
+ */
+ e820.nr_map = i;
+ } else {
+ e820.nr_map = i + 1;
+ e820.map[i].size -= current_addr - size;
}
+ return;
}
}
diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c
index 1fb26d0e30b6..bc5a9d97466b 100644
--- a/arch/i386/kernel/smpboot.c
+++ b/arch/i386/kernel/smpboot.c
@@ -68,11 +68,9 @@ EXPORT_SYMBOL(smp_num_siblings);
/* Package ID of each logical CPU */
int phys_proc_id[NR_CPUS] __read_mostly = {[0 ... NR_CPUS-1] = BAD_APICID};
-EXPORT_SYMBOL(phys_proc_id);
/* Core ID of each logical CPU */
int cpu_core_id[NR_CPUS] __read_mostly = {[0 ... NR_CPUS-1] = BAD_APICID};
-EXPORT_SYMBOL(cpu_core_id);
cpumask_t cpu_sibling_map[NR_CPUS] __read_mostly;
EXPORT_SYMBOL(cpu_sibling_map);
@@ -87,7 +85,11 @@ EXPORT_SYMBOL(cpu_online_map);
cpumask_t cpu_callin_map;
cpumask_t cpu_callout_map;
EXPORT_SYMBOL(cpu_callout_map);
+#ifdef CONFIG_HOTPLUG_CPU
+cpumask_t cpu_possible_map = CPU_MASK_ALL;
+#else
cpumask_t cpu_possible_map;
+#endif
EXPORT_SYMBOL(cpu_possible_map);
static cpumask_t smp_commenced_mask;
@@ -483,6 +485,7 @@ static void __devinit start_secondary(void *unused)
* things done here to the most necessary things.
*/
cpu_init();
+ preempt_disable();
smp_callin();
while (!cpu_isset(smp_processor_id(), smp_commenced_mask))
rep_nop();
@@ -608,7 +611,7 @@ static inline void __inquire_remote_apic(int apicid)
printk("Inquiring remote APIC #%d...\n", apicid);
- for (i = 0; i < sizeof(regs) / sizeof(*regs); i++) {
+ for (i = 0; i < ARRAY_SIZE(regs); i++) {
printk("... APIC #%d %s: ", apicid, names[i]);
/*
diff --git a/arch/i386/kernel/srat.c b/arch/i386/kernel/srat.c
index 516bf5653b02..8de658db8146 100644
--- a/arch/i386/kernel/srat.c
+++ b/arch/i386/kernel/srat.c
@@ -327,7 +327,12 @@ int __init get_memcfg_from_srat(void)
int tables = 0;
int i = 0;
- acpi_find_root_pointer(ACPI_PHYSICAL_ADDRESSING, rsdp_address);
+ if (ACPI_FAILURE(acpi_find_root_pointer(ACPI_PHYSICAL_ADDRESSING,
+ rsdp_address))) {
+ printk("%s: System description tables not found\n",
+ __FUNCTION__);
+ goto out_err;
+ }
if (rsdp_address->pointer_type == ACPI_PHYSICAL_POINTER) {
printk("%s: assigning address to rsdp\n", __FUNCTION__);
diff --git a/arch/i386/kernel/time.c b/arch/i386/kernel/time.c
index 2883a4d4f01f..41c5b2dc6200 100644
--- a/arch/i386/kernel/time.c
+++ b/arch/i386/kernel/time.c
@@ -74,10 +74,6 @@ int pit_latch_buggy; /* extern */
#include "do_timer.h"
-u64 jiffies_64 = INITIAL_JIFFIES;
-
-EXPORT_SYMBOL(jiffies_64);
-
unsigned int cpu_khz; /* Detected as we calibrate the TSC */
EXPORT_SYMBOL(cpu_khz);
diff --git a/arch/i386/kernel/time_hpet.c b/arch/i386/kernel/time_hpet.c
index 658c0629ba6a..9caeaa315cd7 100644
--- a/arch/i386/kernel/time_hpet.c
+++ b/arch/i386/kernel/time_hpet.c
@@ -275,6 +275,7 @@ static unsigned long PIE_freq = DEFAULT_RTC_INT_FREQ;
static unsigned long PIE_count;
static unsigned long hpet_rtc_int_freq; /* RTC interrupt frequency */
+static unsigned int hpet_t1_cmp; /* cached comparator register */
/*
* Timer 1 for RTC, we do not use periodic interrupt feature,
@@ -306,10 +307,12 @@ int hpet_rtc_timer_init(void)
cnt = hpet_readl(HPET_COUNTER);
cnt += ((hpet_tick*HZ)/hpet_rtc_int_freq);
hpet_writel(cnt, HPET_T1_CMP);
+ hpet_t1_cmp = cnt;
local_irq_restore(flags);
cfg = hpet_readl(HPET_T1_CFG);
- cfg |= HPET_TN_ENABLE | HPET_TN_SETVAL | HPET_TN_32BIT;
+ cfg &= ~HPET_TN_PERIODIC;
+ cfg |= HPET_TN_ENABLE | HPET_TN_32BIT;
hpet_writel(cfg, HPET_T1_CFG);
return 1;
@@ -319,8 +322,12 @@ static void hpet_rtc_timer_reinit(void)
{
unsigned int cfg, cnt;
- if (!(PIE_on | AIE_on | UIE_on))
+ if (unlikely(!(PIE_on | AIE_on | UIE_on))) {
+ cfg = hpet_readl(HPET_T1_CFG);
+ cfg &= ~HPET_TN_ENABLE;
+ hpet_writel(cfg, HPET_T1_CFG);
return;
+ }
if (PIE_on && (PIE_freq > DEFAULT_RTC_INT_FREQ))
hpet_rtc_int_freq = PIE_freq;
@@ -328,15 +335,10 @@ static void hpet_rtc_timer_reinit(void)
hpet_rtc_int_freq = DEFAULT_RTC_INT_FREQ;
/* It is more accurate to use the comparator value than current count.*/
- cnt = hpet_readl(HPET_T1_CMP);
+ cnt = hpet_t1_cmp;
cnt += hpet_tick*HZ/hpet_rtc_int_freq;
hpet_writel(cnt, HPET_T1_CMP);
-
- cfg = hpet_readl(HPET_T1_CFG);
- cfg |= HPET_TN_ENABLE | HPET_TN_SETVAL | HPET_TN_32BIT;
- hpet_writel(cfg, HPET_T1_CFG);
-
- return;
+ hpet_t1_cmp = cnt;
}
/*
diff --git a/arch/i386/kernel/timers/timer_hpet.c b/arch/i386/kernel/timers/timer_hpet.c
index d973a8b681fd..be242723c339 100644
--- a/arch/i386/kernel/timers/timer_hpet.c
+++ b/arch/i386/kernel/timers/timer_hpet.c
@@ -30,23 +30,28 @@ static seqlock_t monotonic_lock = SEQLOCK_UNLOCKED;
* basic equation:
* ns = cycles / (freq / ns_per_sec)
* ns = cycles * (ns_per_sec / freq)
- * ns = cycles * (10^9 / (cpu_mhz * 10^6))
- * ns = cycles * (10^3 / cpu_mhz)
+ * ns = cycles * (10^9 / (cpu_khz * 10^3))
+ * ns = cycles * (10^6 / cpu_khz)
*
* Then we use scaling math (suggested by george@mvista.com) to get:
- * ns = cycles * (10^3 * SC / cpu_mhz) / SC
+ * ns = cycles * (10^6 * SC / cpu_khz) / SC
* ns = cycles * cyc2ns_scale / SC
*
* And since SC is a constant power of two, we can convert the div
* into a shift.
+ *
+ * We can use khz divisor instead of mhz to keep a better percision, since
+ * cyc2ns_scale is limited to 10^6 * 2^10, which fits in 32 bits.
+ * (mathieu.desnoyers@polymtl.ca)
+ *
* -johnstul@us.ibm.com "math is hard, lets go shopping!"
*/
static unsigned long cyc2ns_scale;
#define CYC2NS_SCALE_FACTOR 10 /* 2^10, carefully chosen */
-static inline void set_cyc2ns_scale(unsigned long cpu_mhz)
+static inline void set_cyc2ns_scale(unsigned long cpu_khz)
{
- cyc2ns_scale = (1000 << CYC2NS_SCALE_FACTOR)/cpu_mhz;
+ cyc2ns_scale = (1000000 << CYC2NS_SCALE_FACTOR)/cpu_khz;
}
static inline unsigned long long cycles_2_ns(unsigned long long cyc)
@@ -163,7 +168,7 @@ static int __init init_hpet(char* override)
printk("Detected %u.%03u MHz processor.\n",
cpu_khz / 1000, cpu_khz % 1000);
}
- set_cyc2ns_scale(cpu_khz/1000);
+ set_cyc2ns_scale(cpu_khz);
}
/* set this only when cpu_has_tsc */
timer_hpet.read_timer = read_timer_tsc;
diff --git a/arch/i386/kernel/timers/timer_tsc.c b/arch/i386/kernel/timers/timer_tsc.c
index 6dd470cc9f72..d395e3b42485 100644
--- a/arch/i386/kernel/timers/timer_tsc.c
+++ b/arch/i386/kernel/timers/timer_tsc.c
@@ -49,23 +49,28 @@ static seqlock_t monotonic_lock = SEQLOCK_UNLOCKED;
* basic equation:
* ns = cycles / (freq / ns_per_sec)
* ns = cycles * (ns_per_sec / freq)
- * ns = cycles * (10^9 / (cpu_mhz * 10^6))
- * ns = cycles * (10^3 / cpu_mhz)
+ * ns = cycles * (10^9 / (cpu_khz * 10^3))
+ * ns = cycles * (10^6 / cpu_khz)
*
* Then we use scaling math (suggested by george@mvista.com) to get:
- * ns = cycles * (10^3 * SC / cpu_mhz) / SC
+ * ns = cycles * (10^6 * SC / cpu_khz) / SC
* ns = cycles * cyc2ns_scale / SC
*
* And since SC is a constant power of two, we can convert the div
- * into a shift.
+ * into a shift.
+ *
+ * We can use khz divisor instead of mhz to keep a better percision, since
+ * cyc2ns_scale is limited to 10^6 * 2^10, which fits in 32 bits.
+ * (mathieu.desnoyers@polymtl.ca)
+ *
* -johnstul@us.ibm.com "math is hard, lets go shopping!"
*/
static unsigned long cyc2ns_scale;
#define CYC2NS_SCALE_FACTOR 10 /* 2^10, carefully chosen */
-static inline void set_cyc2ns_scale(unsigned long cpu_mhz)
+static inline void set_cyc2ns_scale(unsigned long cpu_khz)
{
- cyc2ns_scale = (1000 << CYC2NS_SCALE_FACTOR)/cpu_mhz;
+ cyc2ns_scale = (1000000 << CYC2NS_SCALE_FACTOR)/cpu_khz;
}
static inline unsigned long long cycles_2_ns(unsigned long long cyc)
@@ -286,7 +291,7 @@ time_cpufreq_notifier(struct notifier_block *nb, unsigned long val,
if (use_tsc) {
if (!(freq->flags & CPUFREQ_CONST_LOOPS)) {
fast_gettimeoffset_quotient = cpufreq_scale(fast_gettimeoffset_ref, freq->new, ref_freq);
- set_cyc2ns_scale(cpu_khz/1000);
+ set_cyc2ns_scale(cpu_khz);
}
}
#endif
@@ -536,7 +541,7 @@ static int __init init_tsc(char* override)
printk("Detected %u.%03u MHz processor.\n",
cpu_khz / 1000, cpu_khz % 1000);
}
- set_cyc2ns_scale(cpu_khz/1000);
+ set_cyc2ns_scale(cpu_khz);
return 0;
}
}
diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c
index 19e90bdd84ea..c34d1bfc5161 100644
--- a/arch/i386/kernel/traps.c
+++ b/arch/i386/kernel/traps.c
@@ -488,6 +488,7 @@ fastcall void __kprobes do_general_protection(struct pt_regs * regs,
tss->io_bitmap_max - thread->io_bitmap_max);
tss->io_bitmap_max = thread->io_bitmap_max;
tss->io_bitmap_base = IO_BITMAP_OFFSET;
+ tss->io_bitmap_owner = thread;
put_cpu();
return;
}
diff --git a/arch/i386/kernel/vm86.c b/arch/i386/kernel/vm86.c
index 16b485009622..fc1993564f98 100644
--- a/arch/i386/kernel/vm86.c
+++ b/arch/i386/kernel/vm86.c
@@ -134,17 +134,16 @@ struct pt_regs * fastcall save_v86_state(struct kernel_vm86_regs * regs)
return ret;
}
-static void mark_screen_rdonly(struct task_struct * tsk)
+static void mark_screen_rdonly(struct mm_struct *mm)
{
pgd_t *pgd;
pud_t *pud;
pmd_t *pmd;
- pte_t *pte, *mapped;
+ pte_t *pte;
+ spinlock_t *ptl;
int i;
- preempt_disable();
- spin_lock(&tsk->mm->page_table_lock);
- pgd = pgd_offset(tsk->mm, 0xA0000);
+ pgd = pgd_offset(mm, 0xA0000);
if (pgd_none_or_clear_bad(pgd))
goto out;
pud = pud_offset(pgd, 0xA0000);
@@ -153,16 +152,14 @@ static void mark_screen_rdonly(struct task_struct * tsk)
pmd = pmd_offset(pud, 0xA0000);
if (pmd_none_or_clear_bad(pmd))
goto out;
- pte = mapped = pte_offset_map(pmd, 0xA0000);
+ pte = pte_offset_map_lock(mm, pmd, 0xA0000, &ptl);
for (i = 0; i < 32; i++) {
if (pte_present(*pte))
set_pte(pte, pte_wrprotect(*pte));
pte++;
}
- pte_unmap(mapped);
+ pte_unmap_unlock(pte, ptl);
out:
- spin_unlock(&tsk->mm->page_table_lock);
- preempt_enable();
flush_tlb();
}
@@ -306,7 +303,7 @@ static void do_sys_vm86(struct kernel_vm86_struct *info, struct task_struct *tsk
tsk->thread.screen_bitmap = info->screen_bitmap;
if (info->flags & VM86_SCREEN_BITMAP)
- mark_screen_rdonly(tsk);
+ mark_screen_rdonly(tsk->mm);
__asm__ __volatile__(
"xorl %%eax,%%eax; movl %%eax,%%fs; movl %%eax,%%gs\n\t"
"movl %0,%%esp\n\t"
diff --git a/arch/i386/mach-es7000/es7000.h b/arch/i386/mach-es7000/es7000.h
index 898ed905e119..f1e3204f5dec 100644
--- a/arch/i386/mach-es7000/es7000.h
+++ b/arch/i386/mach-es7000/es7000.h
@@ -24,6 +24,15 @@
* http://www.unisys.com
*/
+/*
+ * ES7000 chipsets
+ */
+
+#define NON_UNISYS 0
+#define ES7000_CLASSIC 1
+#define ES7000_ZORRO 2
+
+
#define MIP_REG 1
#define MIP_PSAI_REG 4
@@ -106,6 +115,6 @@ struct mip_reg {
extern int parse_unisys_oem (char *oemptr);
extern int find_unisys_acpi_oem_table(unsigned long *oem_addr);
-extern void setup_unisys ();
+extern void setup_unisys(void);
extern int es7000_start_cpu(int cpu, unsigned long eip);
extern void es7000_sw_apic(void);
diff --git a/arch/i386/mach-es7000/es7000plat.c b/arch/i386/mach-es7000/es7000plat.c
index dc6660511b07..a9ab0644f403 100644
--- a/arch/i386/mach-es7000/es7000plat.c
+++ b/arch/i386/mach-es7000/es7000plat.c
@@ -62,6 +62,9 @@ static unsigned int base;
static int
es7000_rename_gsi(int ioapic, int gsi)
{
+ if (es7000_plat == ES7000_ZORRO)
+ return gsi;
+
if (!base) {
int i;
for (i = 0; i < nr_ioapics; i++)
@@ -76,7 +79,7 @@ es7000_rename_gsi(int ioapic, int gsi)
#endif /* (CONFIG_X86_IO_APIC) && (CONFIG_ACPI) */
void __init
-setup_unisys ()
+setup_unisys(void)
{
/*
* Determine the generation of the ES7000 currently running.
@@ -86,9 +89,9 @@ setup_unisys ()
*
*/
if (!(boot_cpu_data.x86 <= 15 && boot_cpu_data.x86_model <= 2))
- es7000_plat = 2;
+ es7000_plat = ES7000_ZORRO;
else
- es7000_plat = 1;
+ es7000_plat = ES7000_CLASSIC;
ioapic_renumber_irq = es7000_rename_gsi;
}
@@ -151,7 +154,7 @@ parse_unisys_oem (char *oemptr)
}
if (success < 2) {
- es7000_plat = 0;
+ es7000_plat = NON_UNISYS;
} else
setup_unisys();
return es7000_plat;
diff --git a/arch/i386/mm/discontig.c b/arch/i386/mm/discontig.c
index 244d8ec66be2..c4af9638dbfa 100644
--- a/arch/i386/mm/discontig.c
+++ b/arch/i386/mm/discontig.c
@@ -98,7 +98,7 @@ unsigned long node_memmap_size_bytes(int nid, unsigned long start_pfn,
extern unsigned long find_max_low_pfn(void);
extern void find_max_pfn(void);
-extern void one_highpage_init(struct page *, int, int);
+extern void add_one_highpage_init(struct page *, int, int);
extern struct e820map e820;
extern unsigned long init_pg_tables_end;
@@ -427,7 +427,7 @@ void __init set_highmem_pages_init(int bad_ppro)
if (!pfn_valid(node_pfn))
continue;
page = pfn_to_page(node_pfn);
- one_highpage_init(page, node_pfn, bad_ppro);
+ add_one_highpage_init(page, node_pfn, bad_ppro);
}
}
totalram_pages += totalhigh_pages;
diff --git a/arch/i386/mm/fault.c b/arch/i386/mm/fault.c
index 9edd4485b91e..cf572d9a3b6e 100644
--- a/arch/i386/mm/fault.c
+++ b/arch/i386/mm/fault.c
@@ -108,7 +108,7 @@ static inline unsigned long get_segment_eip(struct pt_regs *regs,
desc = (void *)desc + (seg & ~7);
} else {
/* Must disable preemption while reading the GDT. */
- desc = (u32 *)&per_cpu(cpu_gdt_table, get_cpu());
+ desc = (u32 *)get_cpu_gdt_table(get_cpu());
desc = (void *)desc + (seg & ~7);
}
diff --git a/arch/i386/mm/init.c b/arch/i386/mm/init.c
index 2ebaf75f732e..542d9298da5e 100644
--- a/arch/i386/mm/init.c
+++ b/arch/i386/mm/init.c
@@ -27,6 +27,7 @@
#include <linux/slab.h>
#include <linux/proc_fs.h>
#include <linux/efi.h>
+#include <linux/memory_hotplug.h>
#include <asm/processor.h>
#include <asm/system.h>
@@ -266,17 +267,46 @@ static void __init permanent_kmaps_init(pgd_t *pgd_base)
pkmap_page_table = pte;
}
-void __init one_highpage_init(struct page *page, int pfn, int bad_ppro)
+void __devinit free_new_highpage(struct page *page)
+{
+ set_page_count(page, 1);
+ __free_page(page);
+ totalhigh_pages++;
+}
+
+void __init add_one_highpage_init(struct page *page, int pfn, int bad_ppro)
{
if (page_is_ram(pfn) && !(bad_ppro && page_kills_ppro(pfn))) {
ClearPageReserved(page);
- set_page_count(page, 1);
- __free_page(page);
- totalhigh_pages++;
+ free_new_highpage(page);
} else
SetPageReserved(page);
}
+static int add_one_highpage_hotplug(struct page *page, unsigned long pfn)
+{
+ free_new_highpage(page);
+ totalram_pages++;
+#ifdef CONFIG_FLATMEM
+ max_mapnr = max(pfn, max_mapnr);
+#endif
+ num_physpages++;
+ return 0;
+}
+
+/*
+ * Not currently handling the NUMA case.
+ * Assuming single node and all memory that
+ * has been added dynamically that would be
+ * onlined here is in HIGHMEM
+ */
+void online_page(struct page *page)
+{
+ ClearPageReserved(page);
+ add_one_highpage_hotplug(page, page_to_pfn(page));
+}
+
+
#ifdef CONFIG_NUMA
extern void set_highmem_pages_init(int);
#else
@@ -284,7 +314,7 @@ static void __init set_highmem_pages_init(int bad_ppro)
{
int pfn;
for (pfn = highstart_pfn; pfn < highend_pfn; pfn++)
- one_highpage_init(pfn_to_page(pfn), pfn, bad_ppro);
+ add_one_highpage_init(pfn_to_page(pfn), pfn, bad_ppro);
totalram_pages += totalhigh_pages;
}
#endif /* CONFIG_FLATMEM */
@@ -615,6 +645,28 @@ void __init mem_init(void)
#endif
}
+/*
+ * this is for the non-NUMA, single node SMP system case.
+ * Specifically, in the case of x86, we will always add
+ * memory to the highmem for now.
+ */
+#ifndef CONFIG_NEED_MULTIPLE_NODES
+int add_memory(u64 start, u64 size)
+{
+ struct pglist_data *pgdata = &contig_page_data;
+ struct zone *zone = pgdata->node_zones + MAX_NR_ZONES-1;
+ unsigned long start_pfn = start >> PAGE_SHIFT;
+ unsigned long nr_pages = size >> PAGE_SHIFT;
+
+ return __add_pages(zone, start_pfn, nr_pages);
+}
+
+int remove_memory(u64 start, u64 size)
+{
+ return -EINVAL;
+}
+#endif
+
kmem_cache_t *pgd_cache;
kmem_cache_t *pmd_cache;
diff --git a/arch/i386/mm/ioremap.c b/arch/i386/mm/ioremap.c
index f379b8d67558..5d09de8d1c6b 100644
--- a/arch/i386/mm/ioremap.c
+++ b/arch/i386/mm/ioremap.c
@@ -28,7 +28,7 @@ static int ioremap_pte_range(pmd_t *pmd, unsigned long addr,
unsigned long pfn;
pfn = phys_addr >> PAGE_SHIFT;
- pte = pte_alloc_kernel(&init_mm, pmd, addr);
+ pte = pte_alloc_kernel(pmd, addr);
if (!pte)
return -ENOMEM;
do {
@@ -87,14 +87,12 @@ static int ioremap_page_range(unsigned long addr,
flush_cache_all();
phys_addr -= addr;
pgd = pgd_offset_k(addr);
- spin_lock(&init_mm.page_table_lock);
do {
next = pgd_addr_end(addr, end);
err = ioremap_pud_range(pgd, addr, next, phys_addr+addr, flags);
if (err)
break;
} while (pgd++, addr = next, addr != end);
- spin_unlock(&init_mm.page_table_lock);
flush_tlb_all();
return err;
}
diff --git a/arch/i386/mm/pgtable.c b/arch/i386/mm/pgtable.c
index dcdce2c6c532..9db3242103be 100644
--- a/arch/i386/mm/pgtable.c
+++ b/arch/i386/mm/pgtable.c
@@ -31,11 +31,13 @@ void show_mem(void)
pg_data_t *pgdat;
unsigned long i;
struct page_state ps;
+ unsigned long flags;
printk(KERN_INFO "Mem-info:\n");
show_free_areas();
printk(KERN_INFO "Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10));
for_each_pgdat(pgdat) {
+ pgdat_resize_lock(pgdat, &flags);
for (i = 0; i < pgdat->node_spanned_pages; ++i) {
page = pgdat_page_nr(pgdat, i);
total++;
@@ -48,6 +50,7 @@ void show_mem(void)
else if (page_count(page))
shared += page_count(page) - 1;
}
+ pgdat_resize_unlock(pgdat, &flags);
}
printk(KERN_INFO "%d pages of RAM\n", total);
printk(KERN_INFO "%d pages of HIGHMEM\n", highmem);
@@ -188,19 +191,19 @@ static inline void pgd_list_add(pgd_t *pgd)
struct page *page = virt_to_page(pgd);
page->index = (unsigned long)pgd_list;
if (pgd_list)
- pgd_list->private = (unsigned long)&page->index;
+ set_page_private(pgd_list, (unsigned long)&page->index);
pgd_list = page;
- page->private = (unsigned long)&pgd_list;
+ set_page_private(page, (unsigned long)&pgd_list);
}
static inline void pgd_list_del(pgd_t *pgd)
{
struct page *next, **pprev, *page = virt_to_page(pgd);
next = (struct page *)page->index;
- pprev = (struct page **)page->private;
+ pprev = (struct page **)page_private(page);
*pprev = next;
if (next)
- next->private = (unsigned long)pprev;
+ set_page_private(next, (unsigned long)pprev);
}
void pgd_ctor(void *pgd, kmem_cache_t *cache, unsigned long unused)
diff --git a/arch/i386/oprofile/Kconfig b/arch/i386/oprofile/Kconfig
index 5ade19801b97..d8a84088471a 100644
--- a/arch/i386/oprofile/Kconfig
+++ b/arch/i386/oprofile/Kconfig
@@ -1,7 +1,3 @@
-
-menu "Profiling support"
- depends on EXPERIMENTAL
-
config PROFILING
bool "Profiling support (EXPERIMENTAL)"
help
@@ -19,5 +15,3 @@ config OPROFILE
If unsure, say N.
-endmenu
-
diff --git a/arch/i386/oprofile/backtrace.c b/arch/i386/oprofile/backtrace.c
index 65dfd2edb671..21654be3f73f 100644
--- a/arch/i386/oprofile/backtrace.c
+++ b/arch/i386/oprofile/backtrace.c
@@ -12,6 +12,7 @@
#include <linux/sched.h>
#include <linux/mm.h>
#include <asm/ptrace.h>
+#include <asm/uaccess.h>
struct frame_head {
struct frame_head * ebp;
@@ -21,26 +22,22 @@ struct frame_head {
static struct frame_head *
dump_backtrace(struct frame_head * head)
{
- oprofile_add_trace(head->ret);
+ struct frame_head bufhead[2];
- /* frame pointers should strictly progress back up the stack
- * (towards higher addresses) */
- if (head >= head->ebp)
+ /* Also check accessibility of one struct frame_head beyond */
+ if (!access_ok(VERIFY_READ, head, sizeof(bufhead)))
+ return NULL;
+ if (__copy_from_user_inatomic(bufhead, head, sizeof(bufhead)))
return NULL;
- return head->ebp;
-}
-
-/* check that the page(s) containing the frame head are present */
-static int pages_present(struct frame_head * head)
-{
- struct mm_struct * mm = current->mm;
+ oprofile_add_trace(bufhead[0].ret);
- /* FIXME: only necessary once per page */
- if (!check_user_page_readable(mm, (unsigned long)head))
- return 0;
+ /* frame pointers should strictly progress back up the stack
+ * (towards higher addresses) */
+ if (head >= bufhead[0].ebp)
+ return NULL;
- return check_user_page_readable(mm, (unsigned long)(head + 1));
+ return bufhead[0].ebp;
}
/*
@@ -97,15 +94,6 @@ x86_backtrace(struct pt_regs * const regs, unsigned int depth)
return;
}
-#ifdef CONFIG_SMP
- if (!spin_trylock(&current->mm->page_table_lock))
- return;
-#endif
-
- while (depth-- && head && pages_present(head))
+ while (depth-- && head)
head = dump_backtrace(head);
-
-#ifdef CONFIG_SMP
- spin_unlock(&current->mm->page_table_lock);
-#endif
}
diff --git a/arch/i386/pci/fixup.c b/arch/i386/pci/fixup.c
index 8e8e895e1b5a..eeb1b1f2d548 100644
--- a/arch/i386/pci/fixup.c
+++ b/arch/i386/pci/fixup.c
@@ -2,6 +2,8 @@
* Exceptions for specific devices. Usually work-arounds for fatal design flaws.
*/
+#include <linux/delay.h>
+#include <linux/dmi.h>
#include <linux/pci.h>
#include <linux/init.h>
#include "pci.h"
@@ -384,3 +386,59 @@ static void __devinit pci_fixup_video(struct pci_dev *pdev)
}
}
DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pci_fixup_video);
+
+/*
+ * Some Toshiba laptops need extra code to enable their TI TSB43AB22/A.
+ *
+ * We pretend to bring them out of full D3 state, and restore the proper
+ * IRQ, PCI cache line size, and BARs, otherwise the device won't function
+ * properly. In some cases, the device will generate an interrupt on
+ * the wrong IRQ line, causing any devices sharing the the line it's
+ * *supposed* to use to be disabled by the kernel's IRQ debug code.
+ */
+static u16 toshiba_line_size;
+
+static struct dmi_system_id __devinitdata toshiba_ohci1394_dmi_table[] = {
+ {
+ .ident = "Toshiba PS5 based laptop",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+ DMI_MATCH(DMI_PRODUCT_VERSION, "PS5"),
+ },
+ },
+ {
+ .ident = "Toshiba PSM4 based laptop",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+ DMI_MATCH(DMI_PRODUCT_VERSION, "PSM4"),
+ },
+ },
+ { }
+};
+
+static void __devinit pci_pre_fixup_toshiba_ohci1394(struct pci_dev *dev)
+{
+ if (!dmi_check_system(toshiba_ohci1394_dmi_table))
+ return; /* only applies to certain Toshibas (so far) */
+
+ dev->current_state = PCI_D3cold;
+ pci_read_config_word(dev, PCI_CACHE_LINE_SIZE, &toshiba_line_size);
+}
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_TI, 0x8032,
+ pci_pre_fixup_toshiba_ohci1394);
+
+static void __devinit pci_post_fixup_toshiba_ohci1394(struct pci_dev *dev)
+{
+ if (!dmi_check_system(toshiba_ohci1394_dmi_table))
+ return; /* only applies to certain Toshibas (so far) */
+
+ /* Restore config space on Toshiba laptops */
+ pci_write_config_word(dev, PCI_CACHE_LINE_SIZE, toshiba_line_size);
+ pci_read_config_byte(dev, PCI_INTERRUPT_LINE, (u8 *)&dev->irq);
+ pci_write_config_dword(dev, PCI_BASE_ADDRESS_0,
+ pci_resource_start(dev, 0));
+ pci_write_config_dword(dev, PCI_BASE_ADDRESS_1,
+ pci_resource_start(dev, 1));
+}
+DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_TI, 0x8032,
+ pci_post_fixup_toshiba_ohci1394);
diff --git a/arch/i386/pci/irq.c b/arch/i386/pci/irq.c
index cddafe33ff7c..19e6f4871d1e 100644
--- a/arch/i386/pci/irq.c
+++ b/arch/i386/pci/irq.c
@@ -547,31 +547,48 @@ static __init int intel_router_probe(struct irq_router *r, struct pci_dev *route
return 0;
}
-static __init int via_router_probe(struct irq_router *r, struct pci_dev *router, u16 device)
+static __init int via_router_probe(struct irq_router *r,
+ struct pci_dev *router, u16 device)
{
/* FIXME: We should move some of the quirk fixup stuff here */
- if (router->device == PCI_DEVICE_ID_VIA_82C686 &&
- device == PCI_DEVICE_ID_VIA_82C586_0) {
- /* Asus k7m bios wrongly reports 82C686A as 586-compatible */
- device = PCI_DEVICE_ID_VIA_82C686;
+ /*
+ * work arounds for some buggy BIOSes
+ */
+ if (device == PCI_DEVICE_ID_VIA_82C586_0) {
+ switch(router->device) {
+ case PCI_DEVICE_ID_VIA_82C686:
+ /*
+ * Asus k7m bios wrongly reports 82C686A
+ * as 586-compatible
+ */
+ device = PCI_DEVICE_ID_VIA_82C686;
+ break;
+ case PCI_DEVICE_ID_VIA_8235:
+ /**
+ * Asus a7v-x bios wrongly reports 8235
+ * as 586-compatible
+ */
+ device = PCI_DEVICE_ID_VIA_8235;
+ break;
+ }
}
- switch(device)
- {
- case PCI_DEVICE_ID_VIA_82C586_0:
- r->name = "VIA";
- r->get = pirq_via586_get;
- r->set = pirq_via586_set;
- return 1;
- case PCI_DEVICE_ID_VIA_82C596:
- case PCI_DEVICE_ID_VIA_82C686:
- case PCI_DEVICE_ID_VIA_8231:
+ switch(device) {
+ case PCI_DEVICE_ID_VIA_82C586_0:
+ r->name = "VIA";
+ r->get = pirq_via586_get;
+ r->set = pirq_via586_set;
+ return 1;
+ case PCI_DEVICE_ID_VIA_82C596:
+ case PCI_DEVICE_ID_VIA_82C686:
+ case PCI_DEVICE_ID_VIA_8231:
+ case PCI_DEVICE_ID_VIA_8235:
/* FIXME: add new ones for 8233/5 */
- r->name = "VIA";
- r->get = pirq_via_get;
- r->set = pirq_via_set;
- return 1;
+ r->name = "VIA";
+ r->get = pirq_via_get;
+ r->set = pirq_via_set;
+ return 1;
}
return 0;
}
diff --git a/arch/i386/power/cpu.c b/arch/i386/power/cpu.c
index b27c5acc79d0..50a0bef8c85f 100644
--- a/arch/i386/power/cpu.c
+++ b/arch/i386/power/cpu.c
@@ -51,16 +51,14 @@ void save_processor_state(void)
__save_processor_state(&saved_context);
}
-static void
-do_fpu_end(void)
+static void do_fpu_end(void)
{
- /* restore FPU regs if necessary */
- /* Do it out of line so that gcc does not move cr0 load to some stupid place */
- kernel_fpu_end();
- mxcsr_feature_mask_init();
+ /*
+ * Restore FPU regs if necessary.
+ */
+ kernel_fpu_end();
}
-
static void fix_processor_context(void)
{
int cpu = smp_processor_id();
@@ -120,6 +118,7 @@ void __restore_processor_state(struct saved_context *ctxt)
fix_processor_context();
do_fpu_end();
mtrr_ap_init();
+ mcheck_init(&boot_cpu_data);
}
void restore_processor_state(void)
diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig
index 945c15a0722b..d4de8a4814be 100644
--- a/arch/ia64/Kconfig
+++ b/arch/ia64/Kconfig
@@ -26,6 +26,10 @@ config MMU
bool
default y
+config SWIOTLB
+ bool
+ default y
+
config RWSEM_XCHGADD_ALGORITHM
bool
default y
@@ -63,8 +67,6 @@ config IA64_GENERIC
select ACPI
select NUMA
select ACPI_NUMA
- select VIRTUAL_MEM_MAP
- select DISCONTIGMEM
help
This selects the system type of your hardware. A "generic" kernel
will run on any supported IA-64 system. However, if you configure
@@ -176,40 +178,6 @@ config IA64_L1_CACHE_SHIFT
default "6" if ITANIUM
# align cache-sensitive data to 64 bytes
-config NUMA
- bool "NUMA support"
- depends on !IA64_HP_SIM
- default y if IA64_SGI_SN2
- select ACPI_NUMA
- help
- Say Y to compile the kernel to support NUMA (Non-Uniform Memory
- Access). This option is for configuring high-end multiprocessor
- server systems. If in doubt, say N.
-
-config VIRTUAL_MEM_MAP
- bool "Virtual mem map"
- default y if !IA64_HP_SIM
- help
- Say Y to compile the kernel with support for a virtual mem map.
- This code also only takes effect if a memory hole of greater than
- 1 Gb is found during boot. You must turn this option on if you
- require the DISCONTIGMEM option for your machine. If you are
- unsure, say Y.
-
-config HOLES_IN_ZONE
- bool
- default y if VIRTUAL_MEM_MAP
-
-config ARCH_DISCONTIGMEM_ENABLE
- bool "Discontiguous memory support"
- depends on (IA64_DIG || IA64_SGI_SN2 || IA64_GENERIC || IA64_HP_ZX1 || IA64_HP_ZX1_SWIOTLB) && NUMA && VIRTUAL_MEM_MAP
- default y if (IA64_SGI_SN2 || IA64_GENERIC) && NUMA
- help
- Say Y to support efficient handling of discontiguous physical memory,
- for architectures which are either NUMA (Non-Uniform Memory Access)
- or have huge holes in the physical address space for other reasons.
- See <file:Documentation/vm/numa> for more.
-
config IA64_CYCLONE
bool "Cyclone (EXA) Time Source support"
help
@@ -223,6 +191,7 @@ config IOSAPIC
config IA64_SGI_SN_XP
tristate "Support communication between SGI SSIs"
+ depends on IA64_GENERIC || IA64_SGI_SN2
select IA64_UNCACHED_ALLOCATOR
help
An SGI machine can be divided into multiple Single System
@@ -232,8 +201,10 @@ config IA64_SGI_SN_XP
based on a network adapter and DMA messaging.
config FORCE_MAX_ZONEORDER
- int
- default "18"
+ int "MAX_ORDER (11 - 17)" if !HUGETLB_PAGE
+ range 11 17 if !HUGETLB_PAGE
+ default "17" if HUGETLB_PAGE
+ default "11"
config SMP
bool "Symmetric multi-processing support"
@@ -254,8 +225,8 @@ config SMP
If you don't know what to do here, say N.
config NR_CPUS
- int "Maximum number of CPUs (2-512)"
- range 2 512
+ int "Maximum number of CPUs (2-1024)"
+ range 2 1024
depends on SMP
default "64"
help
@@ -298,6 +269,58 @@ config PREEMPT
source "mm/Kconfig"
+config ARCH_SELECT_MEMORY_MODEL
+ def_bool y
+
+config ARCH_DISCONTIGMEM_ENABLE
+ def_bool y
+ help
+ Say Y to support efficient handling of discontiguous physical memory,
+ for architectures which are either NUMA (Non-Uniform Memory Access)
+ or have huge holes in the physical address space for other reasons.
+ See <file:Documentation/vm/numa> for more.
+
+config ARCH_FLATMEM_ENABLE
+ def_bool y
+
+config ARCH_SPARSEMEM_ENABLE
+ def_bool y
+ depends on ARCH_DISCONTIGMEM_ENABLE
+
+config ARCH_DISCONTIGMEM_DEFAULT
+ def_bool y if (IA64_SGI_SN2 || IA64_GENERIC || IA64_HP_ZX1 || IA64_HP_ZX1_SWIOTLB)
+ depends on ARCH_DISCONTIGMEM_ENABLE
+
+config NUMA
+ bool "NUMA support"
+ depends on !IA64_HP_SIM && !FLATMEM
+ default y if IA64_SGI_SN2
+ help
+ Say Y to compile the kernel to support NUMA (Non-Uniform Memory
+ Access). This option is for configuring high-end multiprocessor
+ server systems. If in doubt, say N.
+
+# VIRTUAL_MEM_MAP and FLAT_NODE_MEM_MAP are functionally equivalent.
+# VIRTUAL_MEM_MAP has been retained for historical reasons.
+config VIRTUAL_MEM_MAP
+ bool "Virtual mem map"
+ depends on !SPARSEMEM
+ default y if !IA64_HP_SIM
+ help
+ Say Y to compile the kernel with support for a virtual mem map.
+ This code also only takes effect if a memory hole of greater than
+ 1 Gb is found during boot. You must turn this option on if you
+ require the DISCONTIGMEM option for your machine. If you are
+ unsure, say Y.
+
+config HOLES_IN_ZONE
+ bool
+ default y if VIRTUAL_MEM_MAP
+
+config HAVE_ARCH_EARLY_PFN_TO_NID
+ def_bool y
+ depends on NEED_MULTIPLE_NODES
+
config IA32_SUPPORT
bool "Support for Linux/x86 binaries"
help
@@ -404,8 +427,21 @@ config GENERIC_PENDING_IRQ
source "arch/ia64/hp/sim/Kconfig"
+menu "Instrumentation Support"
+ depends on EXPERIMENTAL
+
source "arch/ia64/oprofile/Kconfig"
+config KPROBES
+ bool "Kprobes (EXPERIMENTAL)"
+ help
+ Kprobes allows you to trap at almost any kernel address and
+ execute a callback function. register_kprobe() establishes
+ a probepoint and specifies the callback. Kprobes is useful
+ for kernel debugging, non-intrusive instrumentation and testing.
+ If in doubt, say "N".
+endmenu
+
source "arch/ia64/Kconfig.debug"
source "security/Kconfig"
diff --git a/arch/ia64/Kconfig.debug b/arch/ia64/Kconfig.debug
index fda67ac993d7..de9d507ba0fd 100644
--- a/arch/ia64/Kconfig.debug
+++ b/arch/ia64/Kconfig.debug
@@ -2,17 +2,6 @@ menu "Kernel hacking"
source "lib/Kconfig.debug"
-config KPROBES
- bool "Kprobes"
- depends on DEBUG_KERNEL
- help
- Kprobes allows you to trap at almost any kernel address and
- execute a callback function. register_kprobe() establishes
- a probepoint and specifies the callback. Kprobes is useful
- for kernel debugging, non-intrusive instrumentation and testing.
- If in doubt, say "N".
-
-
choice
prompt "Physical memory granularity"
default IA64_GRANULE_64MB
diff --git a/arch/ia64/configs/bigsur_defconfig b/arch/ia64/configs/bigsur_defconfig
index 3b65cbb31b1d..b40672bb3ab0 100644
--- a/arch/ia64/configs/bigsur_defconfig
+++ b/arch/ia64/configs/bigsur_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.10-rc2
-# Mon Nov 29 13:27:48 2004
+# Linux kernel version: 2.6.14-rc1
+# Wed Sep 14 15:18:49 2005
#
#
@@ -10,34 +10,40 @@
CONFIG_EXPERIMENTAL=y
CONFIG_CLEAN_COMPILE=y
CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
#
# General setup
#
CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
CONFIG_POSIX_MQUEUE=y
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=16
CONFIG_HOTPLUG=y
CONFIG_KOBJECT_UEVENT=y
# CONFIG_IKCONFIG is not set
+# CONFIG_CPUSETS is not set
+CONFIG_INITRAMFS_SOURCE=""
# CONFIG_EMBEDDED is not set
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_ALL is not set
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_SHMEM=y
CONFIG_CC_ALIGN_FUNCTIONS=0
CONFIG_CC_ALIGN_LABELS=0
CONFIG_CC_ALIGN_LOOPS=0
CONFIG_CC_ALIGN_JUMPS=0
# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
#
# Loadable module support
@@ -58,12 +64,15 @@ CONFIG_IA64=y
CONFIG_64BIT=y
CONFIG_MMU=y
CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
CONFIG_TIME_INTERPOLATION=y
CONFIG_EFI=y
CONFIG_GENERIC_IOMAP=y
+CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
# CONFIG_IA64_GENERIC is not set
CONFIG_IA64_DIG=y
# CONFIG_IA64_HP_ZX1 is not set
+# CONFIG_IA64_HP_ZX1_SWIOTLB is not set
# CONFIG_IA64_SGI_SN2 is not set
# CONFIG_IA64_HP_SIM is not set
CONFIG_ITANIUM=y
@@ -72,17 +81,30 @@ CONFIG_ITANIUM=y
# CONFIG_IA64_PAGE_SIZE_8KB is not set
CONFIG_IA64_PAGE_SIZE_16KB=y
# CONFIG_IA64_PAGE_SIZE_64KB is not set
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
CONFIG_IA64_BRL_EMU=y
CONFIG_IA64_L1_CACHE_SHIFT=6
# CONFIG_NUMA is not set
# CONFIG_VIRTUAL_MEM_MAP is not set
# CONFIG_IA64_CYCLONE is not set
CONFIG_IOSAPIC=y
+# CONFIG_IA64_SGI_SN_XP is not set
CONFIG_FORCE_MAX_ZONEORDER=18
CONFIG_SMP=y
CONFIG_NR_CPUS=2
# CONFIG_HOTPLUG_CPU is not set
+# CONFIG_SCHED_SMT is not set
CONFIG_PREEMPT=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_HAVE_DEC_LOCK=y
CONFIG_IA32_SUPPORT=y
CONFIG_COMPAT=y
@@ -95,6 +117,7 @@ CONFIG_IA64_PALINFO=y
#
CONFIG_EFI_VARS=y
CONFIG_EFI_PCDP=y
+# CONFIG_DELL_RBU is not set
CONFIG_BINFMT_ELF=y
CONFIG_BINFMT_MISC=m
@@ -102,18 +125,26 @@ CONFIG_BINFMT_MISC=m
# Power management and ACPI
#
CONFIG_PM=y
-CONFIG_ACPI=y
+# CONFIG_PM_DEBUG is not set
#
# ACPI (Advanced Configuration and Power Interface) Support
#
+CONFIG_ACPI=y
CONFIG_ACPI_BUTTON=m
CONFIG_ACPI_FAN=m
CONFIG_ACPI_PROCESSOR=m
CONFIG_ACPI_THERMAL=m
+CONFIG_ACPI_BLACKLIST_YEAR=0
# CONFIG_ACPI_DEBUG is not set
CONFIG_ACPI_POWER=y
CONFIG_ACPI_SYSTEM=y
+# CONFIG_ACPI_CONTAINER is not set
+
+#
+# CPU Frequency scaling
+#
+# CONFIG_CPU_FREQ is not set
#
# Bus options (PCI, PCMCIA)
@@ -122,7 +153,7 @@ CONFIG_PCI=y
CONFIG_PCI_DOMAINS=y
# CONFIG_PCI_MSI is not set
CONFIG_PCI_LEGACY_PROC=y
-CONFIG_PCI_NAMES=y
+# CONFIG_PCI_DEBUG is not set
#
# PCI Hotplug Support
@@ -135,8 +166,70 @@ CONFIG_PCI_NAMES=y
# CONFIG_PCCARD is not set
#
-# PC-card bridges
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+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 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_TUNNEL is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+# CONFIG_IPV6 is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# 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_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_NETFILTER_NETLINK is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
#
# Device Drivers
@@ -151,6 +244,11 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_DEBUG_DRIVER is not set
#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+
+#
# Memory Technology Devices (MTD)
#
# CONFIG_MTD is not set
@@ -163,7 +261,13 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
#
# Plug and Play support
#
-# CONFIG_PNP is not set
+CONFIG_PNP=y
+# CONFIG_PNP_DEBUG is not set
+
+#
+# Protocols
+#
+CONFIG_PNPACPI=y
#
# Block devices
@@ -172,14 +276,15 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_BLK_CPQ_CISS_DA is not set
# CONFIG_BLK_DEV_DAC960 is not set
# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
CONFIG_BLK_DEV_LOOP=m
CONFIG_BLK_DEV_CRYPTOLOOP=m
CONFIG_BLK_DEV_NBD=m
# CONFIG_BLK_DEV_SX8 is not set
# CONFIG_BLK_DEV_UB is not set
CONFIG_BLK_DEV_RAM=m
+CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=4096
-CONFIG_INITRAMFS_SOURCE=""
# CONFIG_CDROM_PKTCDVD is not set
#
@@ -189,6 +294,7 @@ CONFIG_IOSCHED_NOOP=y
CONFIG_IOSCHED_AS=y
CONFIG_IOSCHED_DEADLINE=y
CONFIG_IOSCHED_CFQ=y
+# CONFIG_ATA_OVER_ETH is not set
#
# ATA/ATAPI/MFM/RLL support
@@ -211,7 +317,8 @@ CONFIG_BLK_DEV_IDEFLOPPY=m
#
# IDE chipset support/bugfixes
#
-CONFIG_IDE_GENERIC=m
+# CONFIG_IDE_GENERIC is not set
+# CONFIG_BLK_DEV_IDEPNP is not set
CONFIG_BLK_DEV_IDEPCI=y
CONFIG_IDEPCI_SHARE_IRQ=y
# CONFIG_BLK_DEV_OFFBOARD is not set
@@ -233,6 +340,7 @@ CONFIG_IDEDMA_PCI_AUTO=y
# CONFIG_BLK_DEV_HPT366 is not set
# CONFIG_BLK_DEV_SC1200 is not set
CONFIG_BLK_DEV_PIIX=m
+# CONFIG_BLK_DEV_IT821X is not set
# CONFIG_BLK_DEV_NS87415 is not set
# CONFIG_BLK_DEV_PDC202XX_OLD is not set
# CONFIG_BLK_DEV_PDC202XX_NEW is not set
@@ -250,6 +358,7 @@ CONFIG_IDEDMA_AUTO=y
#
# SCSI device support
#
+# CONFIG_RAID_ATTRS is not set
CONFIG_SCSI=y
CONFIG_SCSI_PROC_FS=y
@@ -261,6 +370,7 @@ CONFIG_BLK_DEV_SD=y
# CONFIG_CHR_DEV_OSST is not set
# CONFIG_BLK_DEV_SR is not set
# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
#
# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
@@ -274,6 +384,8 @@ CONFIG_SCSI_LOGGING=y
#
CONFIG_SCSI_SPI_ATTRS=m
# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_ATTRS is not set
#
# SCSI low-level drivers
@@ -288,18 +400,13 @@ CONFIG_SCSI_SPI_ATTRS=m
# CONFIG_MEGARAID_NEWGEN is not set
# CONFIG_MEGARAID_LEGACY is not set
# CONFIG_SCSI_SATA is not set
-# CONFIG_SCSI_BUSLOGIC is not set
# CONFIG_SCSI_DMX3191D is not set
-# CONFIG_SCSI_EATA is not set
-# CONFIG_SCSI_EATA_PIO is not set
# CONFIG_SCSI_FUTURE_DOMAIN is not set
-# CONFIG_SCSI_GDTH is not set
# CONFIG_SCSI_IPS is not set
# CONFIG_SCSI_INITIO is not set
# CONFIG_SCSI_INIA100 is not set
# CONFIG_SCSI_SYM53C8XX_2 is not set
# CONFIG_SCSI_IPR is not set
-# CONFIG_SCSI_QLOGIC_ISP is not set
# CONFIG_SCSI_QLOGIC_FC is not set
CONFIG_SCSI_QLOGIC_1280=y
# CONFIG_SCSI_QLOGIC_1280_1040 is not set
@@ -309,7 +416,8 @@ CONFIG_SCSI_QLA2XXX=y
# CONFIG_SCSI_QLA2300 is not set
# CONFIG_SCSI_QLA2322 is not set
# CONFIG_SCSI_QLA6312 is not set
-# CONFIG_SCSI_QLA6322 is not set
+# CONFIG_SCSI_QLA24XX is not set
+# CONFIG_SCSI_LPFC is not set
# CONFIG_SCSI_DC395x is not set
# CONFIG_SCSI_DC390T is not set
# CONFIG_SCSI_DEBUG is not set
@@ -332,11 +440,14 @@ CONFIG_DM_CRYPT=m
CONFIG_DM_SNAPSHOT=m
CONFIG_DM_MIRROR=m
CONFIG_DM_ZERO=m
+# CONFIG_DM_MULTIPATH is not set
#
# Fusion MPT device support
#
# CONFIG_FUSION is not set
+# CONFIG_FUSION_SPI is not set
+# CONFIG_FUSION_FC is not set
#
# IEEE 1394 (FireWire) support
@@ -349,72 +460,14 @@ CONFIG_DM_ZERO=m
# CONFIG_I2O is not set
#
-# Networking support
+# Network device support
#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
-# CONFIG_NETLINK_DEV 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_PNP 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_TUNNEL is not set
-CONFIG_IP_TCPDIAG=y
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-# CONFIG_IPV6 is not set
-# CONFIG_NETFILTER is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP 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_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
CONFIG_NETDEVICES=y
CONFIG_DUMMY=y
# CONFIG_BONDING is not set
# CONFIG_EQUALIZER is not set
# CONFIG_TUN is not set
+# CONFIG_NET_SB1000 is not set
#
# ARCnet devices
@@ -422,6 +475,11 @@ CONFIG_DUMMY=y
# CONFIG_ARCNET is not set
#
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
+#
# Ethernet (10 or 100Mbit)
#
CONFIG_NET_ETHERNET=y
@@ -443,7 +501,6 @@ CONFIG_NET_PCI=y
# CONFIG_FORCEDETH is not set
# CONFIG_DGRS is not set
CONFIG_EEPRO100=y
-# CONFIG_EEPRO100_PIO is not set
# CONFIG_E100 is not set
# CONFIG_FEALNX is not set
# CONFIG_NATSEMI is not set
@@ -465,13 +522,17 @@ CONFIG_EEPRO100=y
# CONFIG_HAMACHI is not set
# CONFIG_YELLOWFIN is not set
# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
# CONFIG_SK98LIN is not set
# CONFIG_VIA_VELOCITY is not set
# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
#
# Ethernet (10000 Mbit)
#
+# CONFIG_CHELSIO_T1 is not set
# CONFIG_IXGB is not set
# CONFIG_S2IO is not set
@@ -496,6 +557,8 @@ CONFIG_EEPRO100=y
# CONFIG_NET_FC is not set
# CONFIG_SHAPER is not set
# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
#
# ISDN subsystem
@@ -525,18 +588,6 @@ CONFIG_INPUT_EVDEV=y
# CONFIG_INPUT_EVBUG is not set
#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=y
-CONFIG_SERIO_I8042=y
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_PCIPS2 is not set
-# CONFIG_SERIO_RAW is not set
-
-#
# Input Device Drivers
#
CONFIG_INPUT_KEYBOARD=y
@@ -554,6 +605,17 @@ CONFIG_MOUSE_PS2=y
# CONFIG_INPUT_MISC is not set
#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_I8042=y
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_PCIPS2 is not set
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+
+#
# Character devices
#
CONFIG_VT=y
@@ -571,7 +633,6 @@ CONFIG_SERIAL_8250_NR_UARTS=4
CONFIG_SERIAL_8250_EXTENDED=y
CONFIG_SERIAL_8250_SHARE_IRQ=y
# CONFIG_SERIAL_8250_DETECT_IRQ is not set
-# CONFIG_SERIAL_8250_MULTIPORT is not set
# CONFIG_SERIAL_8250_RSA is not set
#
@@ -579,6 +640,7 @@ CONFIG_SERIAL_8250_SHARE_IRQ=y
#
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
CONFIG_UNIX98_PTYS=y
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
@@ -603,14 +665,22 @@ CONFIG_EFI_RTC=y
#
CONFIG_AGP=m
CONFIG_AGP_I460=m
-CONFIG_DRM=y
+CONFIG_DRM=m
# CONFIG_DRM_TDFX is not set
CONFIG_DRM_R128=m
# CONFIG_DRM_RADEON is not set
# CONFIG_DRM_MGA is not set
# CONFIG_DRM_SIS is not set
+# CONFIG_DRM_VIA is not set
+# CONFIG_DRM_SAVAGE is not set
# CONFIG_RAW_DRIVER is not set
# CONFIG_HPET is not set
+# CONFIG_HANGCHECK_TIMER is not set
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
#
# I2C support
@@ -635,7 +705,7 @@ CONFIG_I2C_ALGOBIT=y
# CONFIG_I2C_AMD8111 is not set
# CONFIG_I2C_I801 is not set
# CONFIG_I2C_I810 is not set
-# CONFIG_I2C_ISA is not set
+# CONFIG_I2C_PIIX4 is not set
# CONFIG_I2C_NFORCE2 is not set
# CONFIG_I2C_PARPORT_LIGHT is not set
# CONFIG_I2C_PROSAVAGE is not set
@@ -651,16 +721,43 @@ CONFIG_I2C_ALGOBIT=y
# CONFIG_I2C_PCA_ISA is not set
#
-# Hardware Sensors Chip support
+# Miscellaneous I2C Chip support
#
-# CONFIG_I2C_SENSOR is not set
+# CONFIG_SENSORS_DS1337 is not set
+# CONFIG_SENSORS_DS1374 is not set
+# CONFIG_SENSORS_EEPROM is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_SENSORS_PCA9539 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_SENSORS_RTC8564 is not set
+# CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
# CONFIG_SENSORS_ADM1021 is not set
# CONFIG_SENSORS_ADM1025 is not set
+# CONFIG_SENSORS_ADM1026 is not set
# CONFIG_SENSORS_ADM1031 is not set
+# CONFIG_SENSORS_ADM9240 is not set
# CONFIG_SENSORS_ASB100 is not set
+# CONFIG_SENSORS_ATXP1 is not set
# CONFIG_SENSORS_DS1621 is not set
# CONFIG_SENSORS_FSCHER is not set
+# CONFIG_SENSORS_FSCPOS is not set
# CONFIG_SENSORS_GL518SM is not set
+# CONFIG_SENSORS_GL520SM is not set
# CONFIG_SENSORS_IT87 is not set
# CONFIG_SENSORS_LM63 is not set
# CONFIG_SENSORS_LM75 is not set
@@ -671,33 +768,26 @@ CONFIG_I2C_ALGOBIT=y
# CONFIG_SENSORS_LM85 is not set
# CONFIG_SENSORS_LM87 is not set
# CONFIG_SENSORS_LM90 is not set
+# CONFIG_SENSORS_LM92 is not set
# CONFIG_SENSORS_MAX1619 is not set
# CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_SIS5595 is not set
# CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_SMSC47B397 is not set
# CONFIG_SENSORS_VIA686A is not set
# CONFIG_SENSORS_W83781D is not set
+# CONFIG_SENSORS_W83792D is not set
# CONFIG_SENSORS_W83L785TS is not set
# CONFIG_SENSORS_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
#
-# Other I2C Chip support
-#
-# CONFIG_SENSORS_EEPROM is not set
-# CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_SENSORS_PCF8591 is not set
-# CONFIG_SENSORS_RTC8564 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
-
-#
-# Dallas's 1-wire bus
+# Misc devices
#
-# CONFIG_W1 is not set
#
-# Misc devices
+# Multimedia Capabilities Port drivers
#
#
@@ -752,11 +842,12 @@ CONFIG_SND_OPL3_LIB=m
# CONFIG_SND_MTPAV is not set
# CONFIG_SND_SERIAL_U16550 is not set
# CONFIG_SND_MPU401 is not set
+CONFIG_SND_AC97_CODEC=m
+CONFIG_SND_AC97_BUS=m
#
# PCI devices
#
-CONFIG_SND_AC97_CODEC=m
# CONFIG_SND_ALI5451 is not set
# CONFIG_SND_ATIIXP is not set
# CONFIG_SND_ATIIXP_MODEM is not set
@@ -768,6 +859,8 @@ CONFIG_SND_AC97_CODEC=m
# CONFIG_SND_CS46XX is not set
CONFIG_SND_CS4281=m
# CONFIG_SND_EMU10K1 is not set
+# CONFIG_SND_EMU10K1X is not set
+# CONFIG_SND_CA0106 is not set
# CONFIG_SND_KORG1212 is not set
# CONFIG_SND_MIXART is not set
# CONFIG_SND_NM256 is not set
@@ -775,9 +868,10 @@ CONFIG_SND_CS4281=m
# CONFIG_SND_RME96 is not set
# CONFIG_SND_RME9652 is not set
# CONFIG_SND_HDSP is not set
+# CONFIG_SND_HDSPM is not set
# CONFIG_SND_TRIDENT is not set
# CONFIG_SND_YMFPCI is not set
-# CONFIG_SND_ALS4000 is not set
+# CONFIG_SND_AD1889 is not set
# CONFIG_SND_CMIPCI is not set
# CONFIG_SND_ENS1370 is not set
# CONFIG_SND_ENS1371 is not set
@@ -791,13 +885,14 @@ CONFIG_SND_CS4281=m
# CONFIG_SND_INTEL8X0M is not set
# CONFIG_SND_SONICVIBES is not set
# CONFIG_SND_VIA82XX is not set
+# CONFIG_SND_VIA82XX_MODEM is not set
# CONFIG_SND_VX222 is not set
+# CONFIG_SND_HDA_INTEL is not set
#
# USB devices
#
# CONFIG_SND_USB_AUDIO is not set
-# CONFIG_SND_USB_USX2Y is not set
#
# Open Sound System
@@ -807,6 +902,8 @@ CONFIG_SND_CS4281=m
#
# USB support
#
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
CONFIG_USB=m
# CONFIG_USB_DEBUG is not set
@@ -818,35 +915,38 @@ CONFIG_USB_DEVICEFS=y
# CONFIG_USB_DYNAMIC_MINORS is not set
# CONFIG_USB_SUSPEND is not set
# CONFIG_USB_OTG is not set
-CONFIG_USB_ARCH_HAS_HCD=y
-CONFIG_USB_ARCH_HAS_OHCI=y
#
# USB Host Controller Drivers
#
# CONFIG_USB_EHCI_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
# CONFIG_USB_OHCI_HCD is not set
CONFIG_USB_UHCI_HCD=m
+# CONFIG_USB_SL811_HCD is not set
#
# USB Device Class drivers
#
-CONFIG_USB_AUDIO=m
+# CONFIG_OBSOLETE_OSS_USB_DRIVER is not set
CONFIG_USB_BLUETOOTH_TTY=m
-CONFIG_USB_MIDI=m
CONFIG_USB_ACM=m
CONFIG_USB_PRINTER=m
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+#
CONFIG_USB_STORAGE=m
# CONFIG_USB_STORAGE_DEBUG is not set
-# CONFIG_USB_STORAGE_RW_DETECT is not set
# CONFIG_USB_STORAGE_DATAFAB is not set
# CONFIG_USB_STORAGE_FREECOM is not set
# CONFIG_USB_STORAGE_ISD200 is not set
# CONFIG_USB_STORAGE_DPCM is not set
-# CONFIG_USB_STORAGE_HP8200e is not set
+# CONFIG_USB_STORAGE_USBAT is not set
# CONFIG_USB_STORAGE_SDDR09 is not set
# CONFIG_USB_STORAGE_SDDR55 is not set
# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ONETOUCH is not set
#
# USB Input Devices
@@ -863,19 +963,23 @@ CONFIG_USB_HIDDEV=y
# CONFIG_USB_MOUSE is not set
# CONFIG_USB_AIPTEK is not set
# CONFIG_USB_WACOM is not set
+# CONFIG_USB_ACECAD is not set
# CONFIG_USB_KBTAB is not set
# CONFIG_USB_POWERMATE is not set
# CONFIG_USB_MTOUCH is not set
+# CONFIG_USB_ITMTOUCH is not set
# CONFIG_USB_EGALAX is not set
+# CONFIG_USB_YEALINK is not set
# CONFIG_USB_XPAD is not set
# CONFIG_USB_ATI_REMOTE is not set
+# CONFIG_USB_KEYSPAN_REMOTE is not set
+# CONFIG_USB_APPLETOUCH is not set
#
# USB Imaging devices
#
# CONFIG_USB_MDC800 is not set
# CONFIG_USB_MICROTEK is not set
-# CONFIG_USB_HPUSBSCSI is not set
#
# USB Multimedia devices
@@ -894,6 +998,7 @@ CONFIG_USB_HIDDEV=y
# CONFIG_USB_PEGASUS is not set
# CONFIG_USB_RTL8150 is not set
# CONFIG_USB_USBNET is not set
+CONFIG_USB_MON=y
#
# USB port drivers
@@ -909,7 +1014,6 @@ CONFIG_USB_HIDDEV=y
#
# CONFIG_USB_EMI62 is not set
# CONFIG_USB_EMI26 is not set
-# CONFIG_USB_TIGL is not set
# CONFIG_USB_AUERSWALD is not set
# CONFIG_USB_RIO500 is not set
# CONFIG_USB_LEGOTOWER is not set
@@ -918,10 +1022,12 @@ CONFIG_USB_HIDDEV=y
# CONFIG_USB_CYTHERM is not set
# CONFIG_USB_PHIDGETKIT is not set
# CONFIG_USB_PHIDGETSERVO is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_LD is not set
# CONFIG_USB_TEST is not set
#
-# USB ATM/DSL drivers
+# USB DSL modem support
#
#
@@ -930,10 +1036,25 @@ CONFIG_USB_HIDDEV=y
# CONFIG_USB_GADGET is not set
#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
+# SN Devices
+#
+
+#
# File systems
#
CONFIG_EXT2_FS=y
# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
CONFIG_EXT3_FS=y
CONFIG_EXT3_FS_XATTR=y
# CONFIG_EXT3_FS_POSIX_ACL is not set
@@ -945,17 +1066,20 @@ CONFIG_FS_MBCACHE=y
# CONFIG_JFS_FS is not set
CONFIG_FS_POSIX_ACL=y
CONFIG_XFS_FS=y
-# CONFIG_XFS_RT is not set
+CONFIG_XFS_EXPORT=y
CONFIG_XFS_QUOTA=y
CONFIG_XFS_SECURITY=y
CONFIG_XFS_POSIX_ACL=y
+# CONFIG_XFS_RT is not set
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
# CONFIG_QUOTA is not set
CONFIG_QUOTACTL=y
CONFIG_DNOTIFY=y
CONFIG_AUTOFS_FS=m
CONFIG_AUTOFS4_FS=m
+# CONFIG_FUSE_FS is not set
#
# CD-ROM/DVD Filesystems
@@ -982,14 +1106,11 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
-CONFIG_DEVPTS_FS_XATTR=y
-CONFIG_DEVPTS_FS_SECURITY=y
CONFIG_TMPFS=y
-# CONFIG_TMPFS_XATTR is not set
CONFIG_HUGETLBFS=y
CONFIG_HUGETLB_PAGE=y
CONFIG_RAMFS=y
+# CONFIG_RELAYFS_FS is not set
#
# Miscellaneous filesystems
@@ -1013,15 +1134,18 @@ CONFIG_RAMFS=y
#
CONFIG_NFS_FS=m
CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
CONFIG_NFS_V4=y
# CONFIG_NFS_DIRECTIO is not set
CONFIG_NFSD=m
CONFIG_NFSD_V3=y
+# CONFIG_NFSD_V3_ACL is not set
CONFIG_NFSD_V4=y
CONFIG_NFSD_TCP=y
CONFIG_LOCKD=m
CONFIG_LOCKD_V4=y
-CONFIG_EXPORTFS=m
+CONFIG_EXPORTFS=y
+CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=m
CONFIG_SUNRPC_GSS=m
CONFIG_RPCSEC_GSS_KRB5=m
@@ -1031,9 +1155,11 @@ CONFIG_CIFS=m
CONFIG_CIFS_STATS=y
CONFIG_CIFS_XATTR=y
CONFIG_CIFS_POSIX=y
+# CONFIG_CIFS_EXPERIMENTAL is not set
# CONFIG_NCP_FS is not set
# CONFIG_CODA_FS is not set
# CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
#
# Partition Types
@@ -1103,8 +1229,12 @@ CONFIG_NLS_UTF8=m
# Library routines
#
# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
CONFIG_CRC32=y
# CONFIG_LIBCRC32C is not set
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_GENERIC_PENDING_IRQ=y
#
# Profiling support
@@ -1115,14 +1245,20 @@ CONFIG_OPROFILE=y
#
# Kernel hacking
#
+# CONFIG_PRINTK_TIME is not set
CONFIG_DEBUG_KERNEL=y
CONFIG_MAGIC_SYSRQ=y
+CONFIG_LOG_BUF_SHIFT=16
+CONFIG_DETECT_SOFTLOCKUP=y
# CONFIG_SCHEDSTATS is not set
# CONFIG_DEBUG_SLAB is not set
+CONFIG_DEBUG_PREEMPT=y
# CONFIG_DEBUG_SPINLOCK is not set
# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
# CONFIG_DEBUG_KOBJECT is not set
# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_KPROBES is not set
# CONFIG_IA64_GRANULE_16MB is not set
CONFIG_IA64_GRANULE_64MB=y
# CONFIG_IA64_PRINT_HAZARDS is not set
@@ -1149,6 +1285,7 @@ CONFIG_CRYPTO_MD5=y
# CONFIG_CRYPTO_SHA256 is not set
# CONFIG_CRYPTO_SHA512 is not set
# CONFIG_CRYPTO_WP512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
CONFIG_CRYPTO_DES=y
# CONFIG_CRYPTO_BLOWFISH is not set
# CONFIG_CRYPTO_TWOFISH is not set
@@ -1164,3 +1301,7 @@ CONFIG_CRYPTO_DES=y
# CONFIG_CRYPTO_MICHAEL_MIC is not set
# CONFIG_CRYPTO_CRC32C is not set
# CONFIG_CRYPTO_TEST is not set
+
+#
+# Hardware crypto devices
+#
diff --git a/arch/ia64/configs/gensparse_defconfig b/arch/ia64/configs/gensparse_defconfig
new file mode 100644
index 000000000000..80f8663bc6d9
--- /dev/null
+++ b/arch/ia64/configs/gensparse_defconfig
@@ -0,0 +1,1319 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.14-rc2
+# Wed Sep 28 08:27:29 2005
+#
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_HOTPLUG=y
+CONFIG_KOBJECT_UEVENT=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+# CONFIG_CPUSETS is not set
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_EMBEDDED is not set
+CONFIG_KALLSYMS=y
+CONFIG_KALLSYMS_ALL=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_OBSOLETE_MODPARM=y
+CONFIG_MODVERSIONS=y
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+CONFIG_STOP_MACHINE=y
+
+#
+# Processor type and features
+#
+CONFIG_IA64=y
+CONFIG_64BIT=y
+CONFIG_MMU=y
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_TIME_INTERPOLATION=y
+CONFIG_EFI=y
+CONFIG_GENERIC_IOMAP=y
+CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+CONFIG_IA64_GENERIC=y
+# CONFIG_IA64_DIG is not set
+# CONFIG_IA64_HP_ZX1 is not set
+# CONFIG_IA64_HP_ZX1_SWIOTLB is not set
+# CONFIG_IA64_SGI_SN2 is not set
+# CONFIG_IA64_HP_SIM is not set
+# CONFIG_ITANIUM is not set
+CONFIG_MCKINLEY=y
+# CONFIG_IA64_PAGE_SIZE_4KB is not set
+# CONFIG_IA64_PAGE_SIZE_8KB is not set
+CONFIG_IA64_PAGE_SIZE_16KB=y
+# CONFIG_IA64_PAGE_SIZE_64KB is not set
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+CONFIG_IA64_L1_CACHE_SHIFT=7
+CONFIG_IA64_CYCLONE=y
+CONFIG_IOSAPIC=y
+# CONFIG_IA64_SGI_SN_XP is not set
+CONFIG_FORCE_MAX_ZONEORDER=17
+CONFIG_SMP=y
+CONFIG_NR_CPUS=512
+CONFIG_HOTPLUG_CPU=y
+# CONFIG_SCHED_SMT is not set
+# CONFIG_PREEMPT 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_NEED_MULTIPLE_NODES=y
+CONFIG_HAVE_MEMORY_PRESENT=y
+# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPARSEMEM_EXTREME=y
+CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_ARCH_DISCONTIGMEM_ENABLE=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_SPARSEMEM_ENABLE=y
+CONFIG_ARCH_DISCONTIGMEM_DEFAULT=y
+CONFIG_NUMA=y
+CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID=y
+CONFIG_IA32_SUPPORT=y
+CONFIG_COMPAT=y
+CONFIG_IA64_MCA_RECOVERY=y
+CONFIG_PERFMON=y
+CONFIG_IA64_PALINFO=y
+
+#
+# Firmware Drivers
+#
+CONFIG_EFI_VARS=y
+CONFIG_EFI_PCDP=y
+# CONFIG_DELL_RBU is not set
+CONFIG_BINFMT_ELF=y
+CONFIG_BINFMT_MISC=m
+
+#
+# Power management and ACPI
+#
+CONFIG_PM=y
+# CONFIG_PM_DEBUG is not set
+
+#
+# ACPI (Advanced Configuration and Power Interface) Support
+#
+CONFIG_ACPI=y
+CONFIG_ACPI_BUTTON=m
+CONFIG_ACPI_FAN=m
+CONFIG_ACPI_PROCESSOR=m
+CONFIG_ACPI_HOTPLUG_CPU=y
+CONFIG_ACPI_THERMAL=m
+CONFIG_ACPI_NUMA=y
+CONFIG_ACPI_BLACKLIST_YEAR=0
+# CONFIG_ACPI_DEBUG is not set
+CONFIG_ACPI_POWER=y
+CONFIG_ACPI_SYSTEM=y
+CONFIG_ACPI_CONTAINER=m
+
+#
+# CPU Frequency scaling
+#
+# CONFIG_CPU_FREQ is not set
+
+#
+# Bus options (PCI, PCMCIA)
+#
+CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
+# CONFIG_PCI_MSI is not set
+CONFIG_PCI_LEGACY_PROC=y
+# CONFIG_PCI_DEBUG is not set
+
+#
+# PCI Hotplug Support
+#
+CONFIG_HOTPLUG_PCI=m
+# CONFIG_HOTPLUG_PCI_FAKE is not set
+CONFIG_HOTPLUG_PCI_ACPI=m
+# CONFIG_HOTPLUG_PCI_ACPI_IBM is not set
+# CONFIG_HOTPLUG_PCI_CPCI is not set
+# CONFIG_HOTPLUG_PCI_SHPC is not set
+# CONFIG_HOTPLUG_PCI_SGI is not set
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# Networking
+#
+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=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+# CONFIG_IP_PNP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+CONFIG_ARPD=y
+CONFIG_SYN_COOKIES=y
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+# CONFIG_IPV6 is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# 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_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=m
+# CONFIG_DEBUG_DRIVER is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+# CONFIG_PNP is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=m
+CONFIG_BLK_DEV_CRYPTOLOOP=m
+CONFIG_BLK_DEV_NBD=m
+# CONFIG_BLK_DEV_SX8 is not set
+# CONFIG_BLK_DEV_UB is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_CDROM_PKTCDVD is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_ATA_OVER_ETH is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+CONFIG_IDE=y
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_IDE_SATA is not set
+CONFIG_BLK_DEV_IDEDISK=y
+# CONFIG_IDEDISK_MULTI_MODE is not set
+CONFIG_BLK_DEV_IDECD=y
+# CONFIG_BLK_DEV_IDETAPE is not set
+CONFIG_BLK_DEV_IDEFLOPPY=y
+CONFIG_BLK_DEV_IDESCSI=m
+# CONFIG_IDE_TASK_IOCTL is not set
+
+#
+# IDE chipset support/bugfixes
+#
+CONFIG_IDE_GENERIC=y
+CONFIG_BLK_DEV_IDEPCI=y
+# CONFIG_IDEPCI_SHARE_IRQ is not set
+# CONFIG_BLK_DEV_OFFBOARD is not set
+CONFIG_BLK_DEV_GENERIC=y
+# CONFIG_BLK_DEV_OPTI621 is not set
+CONFIG_BLK_DEV_IDEDMA_PCI=y
+# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
+CONFIG_IDEDMA_PCI_AUTO=y
+# CONFIG_IDEDMA_ONLYDISK is not set
+# CONFIG_BLK_DEV_AEC62XX is not set
+# CONFIG_BLK_DEV_ALI15X3 is not set
+# CONFIG_BLK_DEV_AMD74XX is not set
+CONFIG_BLK_DEV_CMD64X=y
+# CONFIG_BLK_DEV_TRIFLEX is not set
+# CONFIG_BLK_DEV_CY82C693 is not set
+# CONFIG_BLK_DEV_CS5520 is not set
+# CONFIG_BLK_DEV_CS5530 is not set
+# CONFIG_BLK_DEV_HPT34X is not set
+# CONFIG_BLK_DEV_HPT366 is not set
+# CONFIG_BLK_DEV_SC1200 is not set
+CONFIG_BLK_DEV_PIIX=y
+# CONFIG_BLK_DEV_IT821X is not set
+# CONFIG_BLK_DEV_NS87415 is not set
+# CONFIG_BLK_DEV_PDC202XX_OLD is not set
+# CONFIG_BLK_DEV_PDC202XX_NEW is not set
+# CONFIG_BLK_DEV_SVWKS is not set
+CONFIG_BLK_DEV_SGIIOC4=y
+# CONFIG_BLK_DEV_SIIMAGE is not set
+# CONFIG_BLK_DEV_SLC90E66 is not set
+# CONFIG_BLK_DEV_TRM290 is not set
+# CONFIG_BLK_DEV_VIA82CXXX is not set
+# CONFIG_IDE_ARM is not set
+CONFIG_BLK_DEV_IDEDMA=y
+# CONFIG_IDEDMA_IVB is not set
+CONFIG_IDEDMA_AUTO=y
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_ST=m
+# CONFIG_CHR_DEV_OSST is not set
+CONFIG_BLK_DEV_SR=m
+# CONFIG_BLK_DEV_SR_VENDOR is not set
+CONFIG_CHR_DEV_SG=m
+# 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
+
+#
+# SCSI Transport Attributes
+#
+CONFIG_SCSI_SPI_ATTRS=y
+CONFIG_SCSI_FC_ATTRS=y
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_ATTRS is not set
+
+#
+# SCSI low-level drivers
+#
+# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_ACARD is not set
+# CONFIG_SCSI_AACRAID is not set
+# CONFIG_SCSI_AIC7XXX is not set
+# CONFIG_SCSI_AIC7XXX_OLD is not set
+# CONFIG_SCSI_AIC79XX is not set
+# CONFIG_MEGARAID_NEWGEN is not set
+# CONFIG_MEGARAID_LEGACY is not set
+CONFIG_SCSI_SATA=y
+# CONFIG_SCSI_SATA_AHCI is not set
+# CONFIG_SCSI_SATA_SVW is not set
+# CONFIG_SCSI_ATA_PIIX is not set
+# CONFIG_SCSI_SATA_MV is not set
+# CONFIG_SCSI_SATA_NV is not set
+# CONFIG_SCSI_SATA_PROMISE is not set
+# CONFIG_SCSI_SATA_QSTOR is not set
+# CONFIG_SCSI_SATA_SX4 is not set
+# CONFIG_SCSI_SATA_SIL is not set
+# CONFIG_SCSI_SATA_SIS is not set
+# CONFIG_SCSI_SATA_ULI is not set
+# CONFIG_SCSI_SATA_VIA is not set
+CONFIG_SCSI_SATA_VITESSE=y
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+# CONFIG_SCSI_IPS is not set
+# CONFIG_SCSI_INITIO is not set
+# CONFIG_SCSI_INIA100 is not set
+CONFIG_SCSI_SYM53C8XX_2=y
+CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1
+CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
+CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
+# CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set
+# CONFIG_SCSI_IPR is not set
+# CONFIG_SCSI_QLOGIC_FC is not set
+CONFIG_SCSI_QLOGIC_1280=y
+# CONFIG_SCSI_QLOGIC_1280_1040 is not set
+CONFIG_SCSI_QLA2XXX=y
+CONFIG_SCSI_QLA21XX=m
+CONFIG_SCSI_QLA22XX=m
+CONFIG_SCSI_QLA2300=m
+CONFIG_SCSI_QLA2322=m
+# CONFIG_SCSI_QLA6312 is not set
+# CONFIG_SCSI_QLA24XX is not set
+# CONFIG_SCSI_LPFC is not set
+# CONFIG_SCSI_DC395x is not set
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_DEBUG is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+CONFIG_MD=y
+CONFIG_BLK_DEV_MD=m
+CONFIG_MD_LINEAR=m
+CONFIG_MD_RAID0=m
+CONFIG_MD_RAID1=m
+# CONFIG_MD_RAID10 is not set
+CONFIG_MD_RAID5=m
+CONFIG_MD_RAID6=m
+CONFIG_MD_MULTIPATH=m
+# CONFIG_MD_FAULTY is not set
+CONFIG_BLK_DEV_DM=m
+CONFIG_DM_CRYPT=m
+CONFIG_DM_SNAPSHOT=m
+CONFIG_DM_MIRROR=m
+CONFIG_DM_ZERO=m
+CONFIG_DM_MULTIPATH=m
+# CONFIG_DM_MULTIPATH_EMC is not set
+
+#
+# Fusion MPT device support
+#
+CONFIG_FUSION=y
+CONFIG_FUSION_SPI=y
+CONFIG_FUSION_FC=m
+CONFIG_FUSION_MAX_SGE=128
+# CONFIG_FUSION_CTL is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+CONFIG_DUMMY=m
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
+#
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=m
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_NET_VENDOR_3COM is not set
+
+#
+# Tulip family network device support
+#
+CONFIG_NET_TULIP=y
+# CONFIG_DE2104X is not set
+CONFIG_TULIP=m
+# CONFIG_TULIP_MWI is not set
+# CONFIG_TULIP_MMIO is not set
+# CONFIG_TULIP_NAPI is not set
+# CONFIG_DE4X5 is not set
+# CONFIG_WINBOND_840 is not set
+# CONFIG_DM9102 is not set
+# CONFIG_ULI526X is not set
+# CONFIG_HP100 is not set
+CONFIG_NET_PCI=y
+# CONFIG_PCNET32 is not set
+# CONFIG_AMD8111_ETH is not set
+# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_B44 is not set
+# CONFIG_FORCEDETH is not set
+# CONFIG_DGRS is not set
+CONFIG_EEPRO100=m
+CONFIG_E100=m
+# CONFIG_FEALNX is not set
+# CONFIG_NATSEMI is not set
+# CONFIG_NE2K_PCI is not set
+# CONFIG_8139CP is not set
+# CONFIG_8139TOO is not set
+# CONFIG_SIS900 is not set
+# CONFIG_EPIC100 is not set
+# CONFIG_SUNDANCE is not set
+# CONFIG_VIA_RHINE is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+CONFIG_E1000=y
+# CONFIG_E1000_NAPI is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_VIA_VELOCITY is not set
+CONFIG_TIGON3=y
+# CONFIG_BNX2 is not set
+
+#
+# Ethernet (10000 Mbit)
+#
+# CONFIG_CHELSIO_T1 is not set
+# CONFIG_IXGB is not set
+# CONFIG_S2IO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NET_FC is not set
+# CONFIG_SHAPER is not set
+CONFIG_NETCONSOLE=y
+CONFIG_NETPOLL=y
+# CONFIG_NETPOLL_RX is not set
+# CONFIG_NETPOLL_TRAP is not set
+CONFIG_NET_POLL_CONTROLLER=y
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+CONFIG_KEYBOARD_ATKBD=y
+# 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_INPUT_MOUSE=y
+CONFIG_MOUSE_PS2=y
+# CONFIG_MOUSE_SERIAL is not set
+# CONFIG_MOUSE_VSXXXAA is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_I8042=y
+# CONFIG_SERIO_SERPORT is not set
+# CONFIG_SERIO_PCIPS2 is not set
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_SERIO_RAW is not set
+CONFIG_GAMEPORT=m
+# CONFIG_GAMEPORT_NS558 is not set
+# CONFIG_GAMEPORT_L4 is not set
+# CONFIG_GAMEPORT_EMU10K1 is not set
+# CONFIG_GAMEPORT_FM801 is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+CONFIG_SERIAL_NONSTANDARD=y
+# CONFIG_ROCKETPORT is not set
+# CONFIG_CYCLADES is not set
+# CONFIG_DIGIEPCA is not set
+# CONFIG_MOXA_SMARTIO is not set
+# CONFIG_ISI is not set
+# CONFIG_SYNCLINKMP is not set
+# CONFIG_N_HDLC is not set
+# CONFIG_SPECIALIX is not set
+# CONFIG_SX is not set
+# CONFIG_STALDRV is not set
+CONFIG_SGI_SNSC=y
+CONFIG_SGI_TIOCX=y
+CONFIG_SGI_MBCS=m
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_ACPI=y
+CONFIG_SERIAL_8250_NR_UARTS=6
+CONFIG_SERIAL_8250_EXTENDED=y
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+# CONFIG_SERIAL_8250_DETECT_IRQ is not set
+# CONFIG_SERIAL_8250_RSA is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_SERIAL_SGI_L1_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
+CONFIG_SERIAL_SGI_IOC4=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_HW_RANDOM is not set
+CONFIG_EFI_RTC=y
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+CONFIG_AGP=m
+CONFIG_AGP_I460=m
+CONFIG_AGP_HP_ZX1=m
+CONFIG_AGP_SGI_TIOCA=m
+CONFIG_DRM=m
+CONFIG_DRM_TDFX=m
+CONFIG_DRM_R128=m
+CONFIG_DRM_RADEON=m
+CONFIG_DRM_MGA=m
+CONFIG_DRM_SIS=m
+# CONFIG_DRM_VIA is not set
+# CONFIG_DRM_SAVAGE is not set
+CONFIG_RAW_DRIVER=m
+CONFIG_HPET=y
+# CONFIG_HPET_RTC_IRQ is not set
+CONFIG_HPET_MMAP=y
+CONFIG_MAX_RAW_DEVS=256
+# CONFIG_HANGCHECK_TIMER is not set
+CONFIG_MMTIMER=y
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Misc devices
+#
+
+#
+# Multimedia Capabilities Port drivers
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+# CONFIG_FB is not set
+
+#
+# Console display driver support
+#
+CONFIG_VGA_CONSOLE=y
+CONFIG_DUMMY_CONSOLE=y
+
+#
+# Sound
+#
+CONFIG_SOUND=m
+
+#
+# Advanced Linux Sound Architecture
+#
+CONFIG_SND=m
+CONFIG_SND_TIMER=m
+CONFIG_SND_PCM=m
+CONFIG_SND_HWDEP=m
+CONFIG_SND_RAWMIDI=m
+CONFIG_SND_SEQUENCER=m
+CONFIG_SND_SEQ_DUMMY=m
+CONFIG_SND_OSSEMUL=y
+CONFIG_SND_MIXER_OSS=m
+CONFIG_SND_PCM_OSS=m
+CONFIG_SND_SEQUENCER_OSS=y
+CONFIG_SND_VERBOSE_PRINTK=y
+# CONFIG_SND_DEBUG is not set
+CONFIG_SND_GENERIC_DRIVER=y
+
+#
+# Generic devices
+#
+CONFIG_SND_MPU401_UART=m
+CONFIG_SND_OPL3_LIB=m
+CONFIG_SND_DUMMY=m
+CONFIG_SND_VIRMIDI=m
+CONFIG_SND_MTPAV=m
+CONFIG_SND_SERIAL_U16550=m
+CONFIG_SND_MPU401=m
+CONFIG_SND_AC97_CODEC=m
+CONFIG_SND_AC97_BUS=m
+
+#
+# PCI devices
+#
+# CONFIG_SND_ALI5451 is not set
+# CONFIG_SND_ATIIXP is not set
+# CONFIG_SND_ATIIXP_MODEM is not set
+# CONFIG_SND_AU8810 is not set
+# CONFIG_SND_AU8820 is not set
+# CONFIG_SND_AU8830 is not set
+# CONFIG_SND_AZT3328 is not set
+# CONFIG_SND_BT87X is not set
+CONFIG_SND_CS46XX=m
+CONFIG_SND_CS46XX_NEW_DSP=y
+CONFIG_SND_CS4281=m
+CONFIG_SND_EMU10K1=m
+# CONFIG_SND_EMU10K1X is not set
+# CONFIG_SND_CA0106 is not set
+# CONFIG_SND_KORG1212 is not set
+# CONFIG_SND_MIXART is not set
+# CONFIG_SND_NM256 is not set
+# CONFIG_SND_RME32 is not set
+# CONFIG_SND_RME96 is not set
+# CONFIG_SND_RME9652 is not set
+# CONFIG_SND_HDSP is not set
+# CONFIG_SND_HDSPM is not set
+# CONFIG_SND_TRIDENT is not set
+# CONFIG_SND_YMFPCI is not set
+# CONFIG_SND_AD1889 is not set
+# CONFIG_SND_CMIPCI is not set
+# CONFIG_SND_ENS1370 is not set
+# CONFIG_SND_ENS1371 is not set
+# CONFIG_SND_ES1938 is not set
+# CONFIG_SND_ES1968 is not set
+# CONFIG_SND_MAESTRO3 is not set
+CONFIG_SND_FM801=m
+# CONFIG_SND_FM801_TEA575X is not set
+# CONFIG_SND_ICE1712 is not set
+# CONFIG_SND_ICE1724 is not set
+# CONFIG_SND_INTEL8X0 is not set
+# CONFIG_SND_INTEL8X0M is not set
+# CONFIG_SND_SONICVIBES is not set
+# CONFIG_SND_VIA82XX is not set
+# CONFIG_SND_VIA82XX_MODEM is not set
+# CONFIG_SND_VX222 is not set
+# CONFIG_SND_HDA_INTEL is not set
+
+#
+# USB devices
+#
+# CONFIG_SND_USB_AUDIO is not set
+
+#
+# Open Sound System
+#
+# CONFIG_SOUND_PRIME is not set
+
+#
+# USB support
+#
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB=m
+# CONFIG_USB_DEBUG is not set
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+# CONFIG_USB_BANDWIDTH is not set
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_SUSPEND is not set
+# CONFIG_USB_OTG is not set
+
+#
+# USB Host Controller Drivers
+#
+CONFIG_USB_EHCI_HCD=m
+# CONFIG_USB_EHCI_SPLIT_ISO is not set
+# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
+# CONFIG_USB_ISP116X_HCD is not set
+CONFIG_USB_OHCI_HCD=m
+# CONFIG_USB_OHCI_BIG_ENDIAN is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+CONFIG_USB_UHCI_HCD=m
+# CONFIG_USB_SL811_HCD is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_OBSOLETE_OSS_USB_DRIVER is not set
+# CONFIG_USB_BLUETOOTH_TTY is not set
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+#
+CONFIG_USB_STORAGE=m
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=m
+CONFIG_USB_HIDINPUT=y
+# CONFIG_HID_FF is not set
+# CONFIG_USB_HIDDEV is not set
+
+#
+# USB HID Boot Protocol drivers
+#
+# CONFIG_USB_KBD is not set
+# CONFIG_USB_MOUSE is not set
+# CONFIG_USB_AIPTEK is not set
+# CONFIG_USB_WACOM is not set
+# CONFIG_USB_ACECAD is not set
+# CONFIG_USB_KBTAB is not set
+# CONFIG_USB_POWERMATE is not set
+# CONFIG_USB_MTOUCH is not set
+# CONFIG_USB_ITMTOUCH is not set
+# CONFIG_USB_EGALAX is not set
+# CONFIG_USB_YEALINK is not set
+# CONFIG_USB_XPAD is not set
+# CONFIG_USB_ATI_REMOTE is not set
+# CONFIG_USB_KEYSPAN_REMOTE is not set
+# CONFIG_USB_APPLETOUCH is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+
+#
+# USB Multimedia devices
+#
+# CONFIG_USB_DABUSB is not set
+
+#
+# Video4Linux support is needed for USB Multimedia device support
+#
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET is not set
+CONFIG_USB_MON=y
+
+#
+# USB port drivers
+#
+
+#
+# USB Serial Converter support
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_AUERSWALD is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_PHIDGETKIT is not set
+# CONFIG_USB_PHIDGETSERVO is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_SISUSBVGA is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TEST is not set
+
+#
+# USB DSL modem support
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# InfiniBand support
+#
+CONFIG_INFINIBAND=m
+# CONFIG_INFINIBAND_USER_MAD is not set
+# CONFIG_INFINIBAND_USER_ACCESS is not set
+CONFIG_INFINIBAND_MTHCA=m
+# CONFIG_INFINIBAND_MTHCA_DEBUG is not set
+CONFIG_INFINIBAND_IPOIB=m
+# CONFIG_INFINIBAND_IPOIB_DEBUG is not set
+
+#
+# SN Devices
+#
+CONFIG_SGI_IOC4=y
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_XATTR=y
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+CONFIG_REISERFS_FS=y
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
+CONFIG_REISERFS_FS_XATTR=y
+CONFIG_REISERFS_FS_POSIX_ACL=y
+CONFIG_REISERFS_FS_SECURITY=y
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+CONFIG_XFS_FS=y
+CONFIG_XFS_EXPORT=y
+# CONFIG_XFS_QUOTA is not set
+# CONFIG_XFS_SECURITY is not set
+# CONFIG_XFS_POSIX_ACL is not set
+# CONFIG_XFS_RT is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+CONFIG_AUTOFS_FS=y
+CONFIG_AUTOFS4_FS=y
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=m
+CONFIG_JOLIET=y
+# CONFIG_ZISOFS is not set
+CONFIG_UDF_FS=m
+CONFIG_UDF_NLS=y
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+# CONFIG_MSDOS_FS is not set
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+CONFIG_NTFS_FS=m
+# CONFIG_NTFS_DEBUG is not set
+# CONFIG_NTFS_RW is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+CONFIG_HUGETLBFS=y
+CONFIG_HUGETLB_PAGE=y
+CONFIG_RAMFS=y
+# CONFIG_RELAYFS_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_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=m
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+CONFIG_NFS_V4=y
+CONFIG_NFS_DIRECTIO=y
+CONFIG_NFSD=m
+CONFIG_NFSD_V3=y
+# CONFIG_NFSD_V3_ACL is not set
+CONFIG_NFSD_V4=y
+CONFIG_NFSD_TCP=y
+CONFIG_LOCKD=m
+CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=m
+CONFIG_SUNRPC_GSS=m
+CONFIG_RPCSEC_GSS_KRB5=m
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+CONFIG_SMB_FS=m
+CONFIG_SMB_NLS_DEFAULT=y
+CONFIG_SMB_NLS_REMOTE="cp437"
+CONFIG_CIFS=m
+# CONFIG_CIFS_STATS is not set
+# CONFIG_CIFS_XATTR is not set
+# CONFIG_CIFS_EXPERIMENTAL is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+CONFIG_SGI_PARTITION=y
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+CONFIG_EFI_PARTITION=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_CODEPAGE_737=m
+CONFIG_NLS_CODEPAGE_775=m
+CONFIG_NLS_CODEPAGE_850=m
+CONFIG_NLS_CODEPAGE_852=m
+CONFIG_NLS_CODEPAGE_855=m
+CONFIG_NLS_CODEPAGE_857=m
+CONFIG_NLS_CODEPAGE_860=m
+CONFIG_NLS_CODEPAGE_861=m
+CONFIG_NLS_CODEPAGE_862=m
+CONFIG_NLS_CODEPAGE_863=m
+CONFIG_NLS_CODEPAGE_864=m
+CONFIG_NLS_CODEPAGE_865=m
+CONFIG_NLS_CODEPAGE_866=m
+CONFIG_NLS_CODEPAGE_869=m
+CONFIG_NLS_CODEPAGE_936=m
+CONFIG_NLS_CODEPAGE_950=m
+CONFIG_NLS_CODEPAGE_932=m
+CONFIG_NLS_CODEPAGE_949=m
+CONFIG_NLS_CODEPAGE_874=m
+CONFIG_NLS_ISO8859_8=m
+CONFIG_NLS_CODEPAGE_1250=m
+CONFIG_NLS_CODEPAGE_1251=m
+# CONFIG_NLS_ASCII is not set
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_ISO8859_2=m
+CONFIG_NLS_ISO8859_3=m
+CONFIG_NLS_ISO8859_4=m
+CONFIG_NLS_ISO8859_5=m
+CONFIG_NLS_ISO8859_6=m
+CONFIG_NLS_ISO8859_7=m
+CONFIG_NLS_ISO8859_9=m
+CONFIG_NLS_ISO8859_13=m
+CONFIG_NLS_ISO8859_14=m
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_KOI8_R=m
+CONFIG_NLS_KOI8_U=m
+CONFIG_NLS_UTF8=m
+
+#
+# Library routines
+#
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+CONFIG_CRC32=y
+# CONFIG_LIBCRC32C is not set
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_GENERIC_PENDING_IRQ=y
+
+#
+# HP Simulator drivers
+#
+# CONFIG_HP_SIMETH is not set
+# CONFIG_HP_SIMSERIAL is not set
+# CONFIG_HP_SIMSCSI is not set
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_DEBUG_KERNEL=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_LOG_BUF_SHIFT=20
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_KPROBES is not set
+CONFIG_IA64_GRANULE_16MB=y
+# CONFIG_IA64_GRANULE_64MB is not set
+# CONFIG_IA64_PRINT_HAZARDS is not set
+# CONFIG_DISABLE_VHPT is not set
+# CONFIG_IA64_DEBUG_CMPXCHG is not set
+# CONFIG_IA64_DEBUG_IRQ is not set
+CONFIG_SYSVIPC_COMPAT=y
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+CONFIG_CRYPTO=y
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_MD4 is not set
+CONFIG_CRYPTO_MD5=y
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_WP512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+CONFIG_CRYPTO_DES=m
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Hardware crypto devices
+#
diff --git a/arch/ia64/configs/tiger_defconfig b/arch/ia64/configs/tiger_defconfig
index d452e18ac494..9bc8bcafc905 100644
--- a/arch/ia64/configs/tiger_defconfig
+++ b/arch/ia64/configs/tiger_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.13-rc6-tiger-smp
-# Wed Aug 17 10:19:51 2005
+# Linux kernel version: 2.6.14-rc1
+# Wed Sep 14 15:17:57 2005
#
#
@@ -16,6 +16,7 @@ CONFIG_INIT_ENV_ARG_LIMIT=32
# General setup
#
CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
CONFIG_POSIX_MQUEUE=y
@@ -27,6 +28,7 @@ CONFIG_KOBJECT_UEVENT=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
# CONFIG_CPUSETS is not set
+CONFIG_INITRAMFS_SOURCE=""
# CONFIG_EMBEDDED is not set
CONFIG_KALLSYMS=y
CONFIG_KALLSYMS_ALL=y
@@ -103,6 +105,7 @@ CONFIG_FLATMEM_MANUAL=y
# CONFIG_SPARSEMEM_MANUAL is not set
CONFIG_FLATMEM=y
CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
CONFIG_HAVE_DEC_LOCK=y
CONFIG_IA32_SUPPORT=y
CONFIG_COMPAT=y
@@ -115,6 +118,7 @@ CONFIG_IA64_PALINFO=y
#
CONFIG_EFI_VARS=y
CONFIG_EFI_PCDP=y
+# CONFIG_DELL_RBU is not set
CONFIG_BINFMT_ELF=y
CONFIG_BINFMT_MISC=m
@@ -122,20 +126,27 @@ CONFIG_BINFMT_MISC=m
# Power management and ACPI
#
CONFIG_PM=y
-CONFIG_ACPI=y
+# CONFIG_PM_DEBUG is not set
#
# ACPI (Advanced Configuration and Power Interface) Support
#
+CONFIG_ACPI=y
CONFIG_ACPI_BUTTON=m
CONFIG_ACPI_FAN=m
CONFIG_ACPI_PROCESSOR=m
-# CONFIG_ACPI_HOTPLUG_CPU is not set
+CONFIG_ACPI_HOTPLUG_CPU=y
CONFIG_ACPI_THERMAL=m
+CONFIG_ACPI_BLACKLIST_YEAR=0
# CONFIG_ACPI_DEBUG is not set
CONFIG_ACPI_POWER=y
CONFIG_ACPI_SYSTEM=y
-# CONFIG_ACPI_CONTAINER is not set
+CONFIG_ACPI_CONTAINER=m
+
+#
+# CPU Frequency scaling
+#
+# CONFIG_CPU_FREQ is not set
#
# Bus options (PCI, PCMCIA)
@@ -144,7 +155,6 @@ CONFIG_PCI=y
CONFIG_PCI_DOMAINS=y
# CONFIG_PCI_MSI is not set
CONFIG_PCI_LEGACY_PROC=y
-CONFIG_PCI_NAMES=y
# CONFIG_PCI_DEBUG is not set
#
@@ -188,14 +198,19 @@ CONFIG_SYN_COOKIES=y
# CONFIG_INET_ESP is not set
# CONFIG_INET_IPCOMP is not set
# CONFIG_INET_TUNNEL is not set
-CONFIG_IP_TCPDIAG=y
-# CONFIG_IP_TCPDIAG_IPV6 is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
# CONFIG_TCP_CONG_ADVANCED is not set
CONFIG_TCP_CONG_BIC=y
# CONFIG_IPV6 is not set
# CONFIG_NETFILTER is not set
#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
# SCTP Configuration (EXPERIMENTAL)
#
# CONFIG_IP_SCTP is not set
@@ -218,9 +233,11 @@ CONFIG_TCP_CONG_BIC=y
# Network testing
#
# CONFIG_NET_PKTGEN is not set
+# CONFIG_NETFILTER_NETLINK is not set
# CONFIG_HAMRADIO is not set
# CONFIG_IRDA is not set
# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
#
# Device Drivers
@@ -235,6 +252,11 @@ CONFIG_FW_LOADER=m
# CONFIG_DEBUG_DRIVER is not set
#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+
+#
# Memory Technology Devices (MTD)
#
# CONFIG_MTD is not set
@@ -247,7 +269,13 @@ CONFIG_FW_LOADER=m
#
# Plug and Play support
#
-# CONFIG_PNP is not set
+CONFIG_PNP=y
+# CONFIG_PNP_DEBUG is not set
+
+#
+# Protocols
+#
+CONFIG_PNPACPI=y
#
# Block devices
@@ -266,7 +294,6 @@ CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=4096
CONFIG_BLK_DEV_INITRD=y
-CONFIG_INITRAMFS_SOURCE=""
# CONFIG_CDROM_PKTCDVD is not set
#
@@ -299,7 +326,8 @@ CONFIG_BLK_DEV_IDESCSI=m
#
# IDE chipset support/bugfixes
#
-CONFIG_IDE_GENERIC=y
+# CONFIG_IDE_GENERIC is not set
+# CONFIG_BLK_DEV_IDEPNP is not set
CONFIG_BLK_DEV_IDEPCI=y
# CONFIG_IDEPCI_SHARE_IRQ is not set
# CONFIG_BLK_DEV_OFFBOARD is not set
@@ -339,6 +367,7 @@ CONFIG_IDEDMA_AUTO=y
#
# SCSI device support
#
+# CONFIG_RAID_ATTRS is not set
CONFIG_SCSI=y
CONFIG_SCSI_PROC_FS=y
@@ -366,6 +395,7 @@ CONFIG_CHR_DEV_SG=m
CONFIG_SCSI_SPI_ATTRS=y
CONFIG_SCSI_FC_ATTRS=y
# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_ATTRS is not set
#
# SCSI low-level drivers
@@ -454,6 +484,7 @@ CONFIG_DUMMY=m
# CONFIG_BONDING is not set
# CONFIG_EQUALIZER is not set
# CONFIG_TUN is not set
+# CONFIG_NET_SB1000 is not set
#
# ARCnet devices
@@ -461,6 +492,11 @@ CONFIG_DUMMY=m
# CONFIG_ARCNET is not set
#
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
+#
# Ethernet (10 or 100Mbit)
#
CONFIG_NET_ETHERNET=y
@@ -481,6 +517,7 @@ CONFIG_TULIP=m
# CONFIG_DE4X5 is not set
# CONFIG_WINBOND_840 is not set
# CONFIG_DM9102 is not set
+# CONFIG_ULI526X is not set
# CONFIG_HP100 is not set
CONFIG_NET_PCI=y
# CONFIG_PCNET32 is not set
@@ -512,6 +549,7 @@ CONFIG_E1000=y
# CONFIG_HAMACHI is not set
# CONFIG_YELLOWFIN is not set
# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
# CONFIG_SKGE is not set
# CONFIG_SK98LIN is not set
# CONFIG_VIA_VELOCITY is not set
@@ -521,6 +559,7 @@ CONFIG_TIGON3=y
#
# Ethernet (10000 Mbit)
#
+# CONFIG_CHELSIO_T1 is not set
# CONFIG_IXGB is not set
# CONFIG_S2IO is not set
@@ -618,6 +657,7 @@ CONFIG_HW_CONSOLE=y
CONFIG_SERIAL_NONSTANDARD=y
# CONFIG_ROCKETPORT is not set
# CONFIG_CYCLADES is not set
+# CONFIG_DIGIEPCA is not set
# CONFIG_MOXA_SMARTIO is not set
# CONFIG_ISI is not set
# CONFIG_SYNCLINKMP is not set
@@ -675,6 +715,7 @@ CONFIG_DRM_RADEON=m
CONFIG_DRM_MGA=m
CONFIG_DRM_SIS=m
# CONFIG_DRM_VIA is not set
+# CONFIG_DRM_SAVAGE is not set
CONFIG_RAW_DRIVER=m
CONFIG_HPET=y
# CONFIG_HPET_RTC_IRQ is not set
@@ -691,7 +732,6 @@ CONFIG_MAX_RAW_DEVS=256
# I2C support
#
# CONFIG_I2C is not set
-# CONFIG_I2C_SENSOR is not set
#
# Dallas's 1-wire bus
@@ -702,6 +742,7 @@ CONFIG_MAX_RAW_DEVS=256
# Hardware Monitoring support
#
CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
# CONFIG_HWMON_DEBUG_CHIP is not set
#
@@ -709,6 +750,10 @@ CONFIG_HWMON=y
#
#
+# Multimedia Capabilities Port drivers
+#
+
+#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
@@ -800,9 +845,11 @@ CONFIG_USB_HIDINPUT=y
# CONFIG_USB_MTOUCH is not set
# CONFIG_USB_ITMTOUCH is not set
# CONFIG_USB_EGALAX is not set
+# CONFIG_USB_YEALINK is not set
# CONFIG_USB_XPAD is not set
# CONFIG_USB_ATI_REMOTE is not set
# CONFIG_USB_KEYSPAN_REMOTE is not set
+# CONFIG_USB_APPLETOUCH is not set
#
# USB Imaging devices
@@ -902,16 +949,12 @@ CONFIG_REISERFS_FS_POSIX_ACL=y
CONFIG_REISERFS_FS_SECURITY=y
# CONFIG_JFS_FS is not set
CONFIG_FS_POSIX_ACL=y
-
-#
-# XFS support
-#
CONFIG_XFS_FS=y
CONFIG_XFS_EXPORT=y
-# CONFIG_XFS_RT is not set
# CONFIG_XFS_QUOTA is not set
# CONFIG_XFS_SECURITY is not set
# CONFIG_XFS_POSIX_ACL is not set
+# CONFIG_XFS_RT is not set
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
CONFIG_INOTIFY=y
@@ -919,6 +962,7 @@ CONFIG_INOTIFY=y
CONFIG_DNOTIFY=y
CONFIG_AUTOFS_FS=y
CONFIG_AUTOFS4_FS=y
+# CONFIG_FUSE_FS is not set
#
# CD-ROM/DVD Filesystems
@@ -947,13 +991,11 @@ CONFIG_NTFS_FS=m
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_SYSFS=y
-# CONFIG_DEVPTS_FS_XATTR is not set
CONFIG_TMPFS=y
-CONFIG_TMPFS_XATTR=y
-CONFIG_TMPFS_SECURITY=y
CONFIG_HUGETLBFS=y
CONFIG_HUGETLB_PAGE=y
CONFIG_RAMFS=y
+# CONFIG_RELAYFS_FS is not set
#
# Miscellaneous filesystems
@@ -1003,6 +1045,7 @@ CONFIG_CIFS=m
# CONFIG_NCP_FS is not set
# CONFIG_CODA_FS is not set
# CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
#
# Partition Types
@@ -1072,10 +1115,12 @@ CONFIG_NLS_UTF8=m
# Library routines
#
# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
CONFIG_CRC32=y
# CONFIG_LIBCRC32C is not set
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_GENERIC_PENDING_IRQ=y
#
# Profiling support
@@ -1089,6 +1134,7 @@ CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_DEBUG_KERNEL=y
CONFIG_MAGIC_SYSRQ=y
CONFIG_LOG_BUF_SHIFT=20
+CONFIG_DETECT_SOFTLOCKUP=y
# CONFIG_SCHEDSTATS is not set
# CONFIG_DEBUG_SLAB is not set
# CONFIG_DEBUG_SPINLOCK is not set
diff --git a/arch/ia64/configs/zx1_defconfig b/arch/ia64/configs/zx1_defconfig
index 80b0e9eb7fb3..0856ca67dd50 100644
--- a/arch/ia64/configs/zx1_defconfig
+++ b/arch/ia64/configs/zx1_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.13-rc6
-# Wed Aug 17 10:02:43 2005
+# Linux kernel version: 2.6.14-rc1
+# Wed Sep 14 15:15:01 2005
#
#
@@ -18,6 +18,7 @@ CONFIG_INIT_ENV_ARG_LIMIT=32
# General setup
#
CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
# CONFIG_POSIX_MQUEUE is not set
@@ -29,6 +30,7 @@ CONFIG_HOTPLUG=y
CONFIG_KOBJECT_UEVENT=y
# CONFIG_IKCONFIG is not set
# CONFIG_CPUSETS is not set
+CONFIG_INITRAMFS_SOURCE=""
# CONFIG_EMBEDDED is not set
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_ALL is not set
@@ -103,6 +105,7 @@ CONFIG_FLATMEM_MANUAL=y
# CONFIG_SPARSEMEM_MANUAL is not set
CONFIG_FLATMEM=y
CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
CONFIG_HAVE_DEC_LOCK=y
CONFIG_IA32_SUPPORT=y
CONFIG_COMPAT=y
@@ -115,6 +118,7 @@ CONFIG_IA64_PALINFO=y
#
CONFIG_EFI_VARS=y
CONFIG_EFI_PCDP=y
+# CONFIG_DELL_RBU is not set
CONFIG_BINFMT_ELF=y
CONFIG_BINFMT_MISC=y
@@ -122,28 +126,34 @@ CONFIG_BINFMT_MISC=y
# Power management and ACPI
#
CONFIG_PM=y
-CONFIG_ACPI=y
+# CONFIG_PM_DEBUG is not set
#
# ACPI (Advanced Configuration and Power Interface) Support
#
+CONFIG_ACPI=y
CONFIG_ACPI_BUTTON=y
CONFIG_ACPI_FAN=y
CONFIG_ACPI_PROCESSOR=y
CONFIG_ACPI_THERMAL=y
+CONFIG_ACPI_BLACKLIST_YEAR=0
# CONFIG_ACPI_DEBUG is not set
CONFIG_ACPI_POWER=y
CONFIG_ACPI_SYSTEM=y
# CONFIG_ACPI_CONTAINER is not set
#
+# CPU Frequency scaling
+#
+# CONFIG_CPU_FREQ is not set
+
+#
# Bus options (PCI, PCMCIA)
#
CONFIG_PCI=y
CONFIG_PCI_DOMAINS=y
# CONFIG_PCI_MSI is not set
CONFIG_PCI_LEGACY_PROC=y
-CONFIG_PCI_NAMES=y
# CONFIG_PCI_DEBUG is not set
#
@@ -187,8 +197,8 @@ CONFIG_IP_FIB_HASH=y
# CONFIG_INET_ESP is not set
# CONFIG_INET_IPCOMP is not set
# CONFIG_INET_TUNNEL is not set
-# CONFIG_IP_TCPDIAG is not set
-# CONFIG_IP_TCPDIAG_IPV6 is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
# CONFIG_TCP_CONG_ADVANCED is not set
CONFIG_TCP_CONG_BIC=y
@@ -204,7 +214,6 @@ CONFIG_NETFILTER=y
# IP: Netfilter Configuration
#
# CONFIG_IP_NF_CONNTRACK is not set
-# CONFIG_IP_NF_CONNTRACK_MARK is not set
# CONFIG_IP_NF_QUEUE is not set
# CONFIG_IP_NF_IPTABLES is not set
CONFIG_IP_NF_ARPTABLES=y
@@ -212,6 +221,11 @@ CONFIG_IP_NF_ARPTABLES=y
# CONFIG_IP_NF_ARP_MANGLE is not set
#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
# SCTP Configuration (EXPERIMENTAL)
#
# CONFIG_IP_SCTP is not set
@@ -234,9 +248,11 @@ CONFIG_IP_NF_ARPTABLES=y
# Network testing
#
# CONFIG_NET_PKTGEN is not set
+# CONFIG_NETFILTER_NETLINK is not set
# CONFIG_HAMRADIO is not set
# CONFIG_IRDA is not set
# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
#
# Device Drivers
@@ -251,6 +267,11 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_DEBUG_DRIVER is not set
#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+
+#
# Memory Technology Devices (MTD)
#
# CONFIG_MTD is not set
@@ -263,7 +284,13 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
#
# Plug and Play support
#
-# CONFIG_PNP is not set
+CONFIG_PNP=y
+# CONFIG_PNP_DEBUG is not set
+
+#
+# Protocols
+#
+CONFIG_PNPACPI=y
#
# Block devices
@@ -282,7 +309,6 @@ CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=4096
CONFIG_BLK_DEV_INITRD=y
-CONFIG_INITRAMFS_SOURCE=""
# CONFIG_CDROM_PKTCDVD is not set
#
@@ -315,7 +341,8 @@ CONFIG_BLK_DEV_IDECD=y
#
# IDE chipset support/bugfixes
#
-CONFIG_IDE_GENERIC=y
+# CONFIG_IDE_GENERIC is not set
+# CONFIG_BLK_DEV_IDEPNP is not set
CONFIG_BLK_DEV_IDEPCI=y
CONFIG_IDEPCI_SHARE_IRQ=y
# CONFIG_BLK_DEV_OFFBOARD is not set
@@ -354,6 +381,7 @@ CONFIG_BLK_DEV_IDEDMA=y
#
# SCSI device support
#
+# CONFIG_RAID_ATTRS is not set
CONFIG_SCSI=y
CONFIG_SCSI_PROC_FS=y
@@ -381,6 +409,7 @@ CONFIG_SCSI_LOGGING=y
CONFIG_SCSI_SPI_ATTRS=y
# CONFIG_SCSI_FC_ATTRS is not set
# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_ATTRS is not set
#
# SCSI low-level drivers
@@ -457,6 +486,7 @@ CONFIG_DUMMY=y
# CONFIG_BONDING is not set
# CONFIG_EQUALIZER is not set
# CONFIG_TUN is not set
+# CONFIG_NET_SB1000 is not set
#
# ARCnet devices
@@ -464,6 +494,11 @@ CONFIG_DUMMY=y
# CONFIG_ARCNET is not set
#
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
+#
# Ethernet (10 or 100Mbit)
#
CONFIG_NET_ETHERNET=y
@@ -485,6 +520,7 @@ CONFIG_TULIP_NAPI_HW_MITIGATION=y
# CONFIG_DE4X5 is not set
# CONFIG_WINBOND_840 is not set
# CONFIG_DM9102 is not set
+# CONFIG_ULI526X is not set
# CONFIG_HP100 is not set
CONFIG_NET_PCI=y
# CONFIG_PCNET32 is not set
@@ -516,6 +552,7 @@ CONFIG_E1000=y
# CONFIG_HAMACHI is not set
# CONFIG_YELLOWFIN is not set
# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
# CONFIG_SKGE is not set
# CONFIG_SK98LIN is not set
# CONFIG_VIA_VELOCITY is not set
@@ -525,6 +562,7 @@ CONFIG_TIGON3=y
#
# Ethernet (10000 Mbit)
#
+# CONFIG_CHELSIO_T1 is not set
# CONFIG_IXGB is not set
# CONFIG_S2IO is not set
@@ -650,12 +688,12 @@ CONFIG_AGP=y
CONFIG_AGP_HP_ZX1=y
CONFIG_DRM=y
# CONFIG_DRM_TDFX is not set
-# CONFIG_DRM_GAMMA is not set
# CONFIG_DRM_R128 is not set
CONFIG_DRM_RADEON=y
# CONFIG_DRM_MGA is not set
# CONFIG_DRM_SIS is not set
# CONFIG_DRM_VIA is not set
+# CONFIG_DRM_SAVAGE is not set
# CONFIG_RAW_DRIVER is not set
# CONFIG_HPET is not set
# CONFIG_HANGCHECK_TIMER is not set
@@ -689,7 +727,6 @@ CONFIG_I2C_ALGOPCF=y
# CONFIG_I2C_I801 is not set
# CONFIG_I2C_I810 is not set
# CONFIG_I2C_PIIX4 is not set
-# CONFIG_I2C_ISA is not set
# CONFIG_I2C_NFORCE2 is not set
# CONFIG_I2C_PARPORT_LIGHT is not set
# CONFIG_I2C_PROSAVAGE is not set
@@ -703,7 +740,6 @@ CONFIG_I2C_ALGOPCF=y
# CONFIG_I2C_VIAPRO is not set
# CONFIG_I2C_VOODOO3 is not set
# CONFIG_I2C_PCA_ISA is not set
-# CONFIG_I2C_SENSOR is not set
#
# Miscellaneous I2C Chip support
@@ -730,12 +766,17 @@ CONFIG_I2C_ALGOPCF=y
# Hardware Monitoring support
#
# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
#
# Misc devices
#
#
+# Multimedia Capabilities Port drivers
+#
+
+#
# Multimedia devices
#
CONFIG_VIDEO_DEV=y
@@ -806,6 +847,7 @@ CONFIG_FB_RADEON_DEBUG=y
# CONFIG_FB_KYRO is not set
# CONFIG_FB_3DFX is not set
# CONFIG_FB_VOODOO1 is not set
+# CONFIG_FB_CYBLA is not set
# CONFIG_FB_TRIDENT is not set
# CONFIG_FB_PM3 is not set
# CONFIG_FB_S1D13XXX is not set
@@ -862,11 +904,12 @@ CONFIG_SND_OPL3_LIB=y
# CONFIG_SND_MTPAV is not set
# CONFIG_SND_SERIAL_U16550 is not set
# CONFIG_SND_MPU401 is not set
+CONFIG_SND_AC97_CODEC=y
+CONFIG_SND_AC97_BUS=y
#
# PCI devices
#
-CONFIG_SND_AC97_CODEC=y
# CONFIG_SND_ALI5451 is not set
# CONFIG_SND_ATIIXP is not set
# CONFIG_SND_ATIIXP_MODEM is not set
@@ -890,7 +933,7 @@ CONFIG_SND_AC97_CODEC=y
# CONFIG_SND_HDSPM is not set
# CONFIG_SND_TRIDENT is not set
# CONFIG_SND_YMFPCI is not set
-# CONFIG_SND_ALS4000 is not set
+# CONFIG_SND_AD1889 is not set
# CONFIG_SND_CMIPCI is not set
# CONFIG_SND_ENS1370 is not set
# CONFIG_SND_ENS1371 is not set
@@ -952,9 +995,8 @@ CONFIG_USB_UHCI_HCD=y
#
# USB Device Class drivers
#
-# CONFIG_USB_AUDIO is not set
+# CONFIG_OBSOLETE_OSS_USB_DRIVER is not set
# CONFIG_USB_BLUETOOTH_TTY is not set
-# CONFIG_USB_MIDI is not set
# CONFIG_USB_ACM is not set
# CONFIG_USB_PRINTER is not set
@@ -971,6 +1013,7 @@ CONFIG_USB_STORAGE=y
# CONFIG_USB_STORAGE_SDDR09 is not set
# CONFIG_USB_STORAGE_SDDR55 is not set
# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ONETOUCH is not set
#
# USB Input Devices
@@ -987,9 +1030,11 @@ CONFIG_USB_HIDDEV=y
# CONFIG_USB_MTOUCH is not set
# CONFIG_USB_ITMTOUCH is not set
# CONFIG_USB_EGALAX is not set
+# CONFIG_USB_YEALINK is not set
# CONFIG_USB_XPAD is not set
# CONFIG_USB_ATI_REMOTE is not set
# CONFIG_USB_KEYSPAN_REMOTE is not set
+# CONFIG_USB_APPLETOUCH is not set
#
# USB Imaging devices
@@ -1088,10 +1133,6 @@ CONFIG_FS_MBCACHE=y
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
# CONFIG_FS_POSIX_ACL is not set
-
-#
-# XFS support
-#
# CONFIG_XFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
@@ -1100,6 +1141,7 @@ CONFIG_FS_MBCACHE=y
CONFIG_DNOTIFY=y
CONFIG_AUTOFS_FS=y
# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
#
# CD-ROM/DVD Filesystems
@@ -1126,13 +1168,11 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_SYSFS=y
-# CONFIG_DEVPTS_FS_XATTR is not set
CONFIG_TMPFS=y
-CONFIG_TMPFS_XATTR=y
-CONFIG_TMPFS_SECURITY=y
CONFIG_HUGETLBFS=y
CONFIG_HUGETLB_PAGE=y
CONFIG_RAMFS=y
+# CONFIG_RELAYFS_FS is not set
#
# Miscellaneous filesystems
@@ -1177,6 +1217,7 @@ CONFIG_RPCSEC_GSS_KRB5=y
# CONFIG_NCP_FS is not set
# CONFIG_CODA_FS is not set
# CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
#
# Partition Types
@@ -1246,10 +1287,12 @@ CONFIG_NLS_UTF8=y
# Library routines
#
# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
CONFIG_CRC32=y
# CONFIG_LIBCRC32C is not set
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_GENERIC_PENDING_IRQ=y
#
# Profiling support
@@ -1263,6 +1306,7 @@ CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_DEBUG_KERNEL=y
CONFIG_MAGIC_SYSRQ=y
CONFIG_LOG_BUF_SHIFT=17
+CONFIG_DETECT_SOFTLOCKUP=y
# CONFIG_SCHEDSTATS is not set
# CONFIG_DEBUG_SLAB is not set
# CONFIG_DEBUG_SPINLOCK is not set
diff --git a/arch/ia64/defconfig b/arch/ia64/defconfig
index 5da208115ea1..6e3f147e03e5 100644
--- a/arch/ia64/defconfig
+++ b/arch/ia64/defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12
-# Tue Jun 21 11:30:42 2005
+# Linux kernel version: 2.6.14-rc1
+# Wed Sep 14 15:13:03 2005
#
#
@@ -16,6 +16,7 @@ CONFIG_INIT_ENV_ARG_LIMIT=32
# General setup
#
CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
CONFIG_POSIX_MQUEUE=y
@@ -27,6 +28,7 @@ CONFIG_KOBJECT_UEVENT=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
# CONFIG_CPUSETS is not set
+CONFIG_INITRAMFS_SOURCE=""
# CONFIG_EMBEDDED is not set
CONFIG_KALLSYMS=y
CONFIG_KALLSYMS_ALL=y
@@ -80,6 +82,10 @@ CONFIG_MCKINLEY=y
# CONFIG_IA64_PAGE_SIZE_8KB is not set
CONFIG_IA64_PAGE_SIZE_16KB=y
# CONFIG_IA64_PAGE_SIZE_64KB is not set
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
CONFIG_IA64_L1_CACHE_SHIFT=7
CONFIG_NUMA=y
CONFIG_VIRTUAL_MEM_MAP=y
@@ -87,12 +93,21 @@ CONFIG_HOLES_IN_ZONE=y
CONFIG_ARCH_DISCONTIGMEM_ENABLE=y
CONFIG_IA64_CYCLONE=y
CONFIG_IOSAPIC=y
+# CONFIG_IA64_SGI_SN_XP is not set
CONFIG_FORCE_MAX_ZONEORDER=18
CONFIG_SMP=y
CONFIG_NR_CPUS=512
CONFIG_HOTPLUG_CPU=y
# CONFIG_SCHED_SMT is not set
# CONFIG_PREEMPT is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+# CONFIG_FLATMEM_MANUAL is not set
+CONFIG_DISCONTIGMEM_MANUAL=y
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_DISCONTIGMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_NEED_MULTIPLE_NODES=y
+# CONFIG_SPARSEMEM_STATIC is not set
CONFIG_HAVE_DEC_LOCK=y
CONFIG_IA32_SUPPORT=y
CONFIG_COMPAT=y
@@ -105,6 +120,7 @@ CONFIG_IA64_PALINFO=y
#
CONFIG_EFI_VARS=y
CONFIG_EFI_PCDP=y
+# CONFIG_DELL_RBU is not set
CONFIG_BINFMT_ELF=y
CONFIG_BINFMT_MISC=m
@@ -112,30 +128,36 @@ CONFIG_BINFMT_MISC=m
# Power management and ACPI
#
CONFIG_PM=y
-CONFIG_ACPI=y
+# CONFIG_PM_DEBUG is not set
#
# ACPI (Advanced Configuration and Power Interface) Support
#
+CONFIG_ACPI=y
CONFIG_ACPI_BUTTON=m
CONFIG_ACPI_FAN=m
CONFIG_ACPI_PROCESSOR=m
CONFIG_ACPI_HOTPLUG_CPU=y
CONFIG_ACPI_THERMAL=m
CONFIG_ACPI_NUMA=y
+CONFIG_ACPI_BLACKLIST_YEAR=0
# CONFIG_ACPI_DEBUG is not set
CONFIG_ACPI_POWER=y
CONFIG_ACPI_SYSTEM=y
CONFIG_ACPI_CONTAINER=m
#
+# CPU Frequency scaling
+#
+# CONFIG_CPU_FREQ is not set
+
+#
# Bus options (PCI, PCMCIA)
#
CONFIG_PCI=y
CONFIG_PCI_DOMAINS=y
# CONFIG_PCI_MSI is not set
CONFIG_PCI_LEGACY_PROC=y
-CONFIG_PCI_NAMES=y
# CONFIG_PCI_DEBUG is not set
#
@@ -147,6 +169,7 @@ CONFIG_HOTPLUG_PCI_ACPI=m
# CONFIG_HOTPLUG_PCI_ACPI_IBM is not set
# CONFIG_HOTPLUG_PCI_CPCI is not set
# CONFIG_HOTPLUG_PCI_SHPC is not set
+# CONFIG_HOTPLUG_PCI_SGI is not set
#
# PCCARD (PCMCIA/CardBus) support
@@ -154,6 +177,73 @@ CONFIG_HOTPLUG_PCI_ACPI=m
# CONFIG_PCCARD is not set
#
+# Networking
+#
+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=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+# CONFIG_IP_PNP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+CONFIG_ARPD=y
+CONFIG_SYN_COOKIES=y
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+# CONFIG_IPV6 is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# 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_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_NETFILTER_NETLINK is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
+
+#
# Device Drivers
#
@@ -162,10 +252,15 @@ CONFIG_HOTPLUG_PCI_ACPI=m
#
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
+CONFIG_FW_LOADER=m
# CONFIG_DEBUG_DRIVER is not set
#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+
+#
# Memory Technology Devices (MTD)
#
# CONFIG_MTD is not set
@@ -178,7 +273,13 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
#
# Plug and Play support
#
-# CONFIG_PNP is not set
+CONFIG_PNP=y
+# CONFIG_PNP_DEBUG is not set
+
+#
+# Protocols
+#
+CONFIG_PNPACPI=y
#
# Block devices
@@ -197,7 +298,6 @@ CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=4096
CONFIG_BLK_DEV_INITRD=y
-CONFIG_INITRAMFS_SOURCE=""
# CONFIG_CDROM_PKTCDVD is not set
#
@@ -230,7 +330,8 @@ CONFIG_BLK_DEV_IDESCSI=m
#
# IDE chipset support/bugfixes
#
-CONFIG_IDE_GENERIC=y
+# CONFIG_IDE_GENERIC is not set
+# CONFIG_BLK_DEV_IDEPNP is not set
CONFIG_BLK_DEV_IDEPCI=y
# CONFIG_IDEPCI_SHARE_IRQ is not set
# CONFIG_BLK_DEV_OFFBOARD is not set
@@ -252,6 +353,7 @@ CONFIG_BLK_DEV_CMD64X=y
# CONFIG_BLK_DEV_HPT366 is not set
# CONFIG_BLK_DEV_SC1200 is not set
CONFIG_BLK_DEV_PIIX=y
+# CONFIG_BLK_DEV_IT821X is not set
# CONFIG_BLK_DEV_NS87415 is not set
# CONFIG_BLK_DEV_PDC202XX_OLD is not set
# CONFIG_BLK_DEV_PDC202XX_NEW is not set
@@ -270,6 +372,7 @@ CONFIG_IDEDMA_AUTO=y
#
# SCSI device support
#
+# CONFIG_RAID_ATTRS is not set
CONFIG_SCSI=y
CONFIG_SCSI_PROC_FS=y
@@ -297,6 +400,7 @@ CONFIG_CHR_DEV_SG=m
CONFIG_SCSI_SPI_ATTRS=y
CONFIG_SCSI_FC_ATTRS=y
# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_ATTRS is not set
#
# SCSI low-level drivers
@@ -314,6 +418,7 @@ CONFIG_SCSI_SATA=y
# CONFIG_SCSI_SATA_AHCI is not set
# CONFIG_SCSI_SATA_SVW is not set
# CONFIG_SCSI_ATA_PIIX is not set
+# CONFIG_SCSI_SATA_MV is not set
# CONFIG_SCSI_SATA_NV is not set
# CONFIG_SCSI_SATA_PROMISE is not set
# CONFIG_SCSI_SATA_QSTOR is not set
@@ -335,7 +440,6 @@ CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
# CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set
# CONFIG_SCSI_IPR is not set
# CONFIG_SCSI_QLOGIC_FC is not set
-# CONFIG_SCSI_QLOGIC_FC_FIRMWARE is not set
CONFIG_SCSI_QLOGIC_1280=y
# CONFIG_SCSI_QLOGIC_1280_1040 is not set
CONFIG_SCSI_QLA2XXX=y
@@ -344,6 +448,7 @@ CONFIG_SCSI_QLA22XX=m
CONFIG_SCSI_QLA2300=m
CONFIG_SCSI_QLA2322=m
# CONFIG_SCSI_QLA6312 is not set
+# CONFIG_SCSI_QLA24XX is not set
# CONFIG_SCSI_LPFC is not set
# CONFIG_SCSI_DC395x is not set
# CONFIG_SCSI_DC390T is not set
@@ -390,74 +495,14 @@ CONFIG_FUSION_MAX_SGE=128
# CONFIG_I2O is not set
#
-# Networking support
-#
-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=y
-# CONFIG_IP_ADVANCED_ROUTER is not set
-# CONFIG_IP_PNP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_IP_MROUTE is not set
-CONFIG_ARPD=y
-CONFIG_SYN_COOKIES=y
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-# CONFIG_INET_TUNNEL is not set
-CONFIG_IP_TCPDIAG=y
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-# CONFIG_IPV6 is not set
-# CONFIG_NETFILTER is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP 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_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-
+# Network device support
#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-CONFIG_NETPOLL=y
-# CONFIG_NETPOLL_RX is not set
-# CONFIG_NETPOLL_TRAP is not set
-CONFIG_NET_POLL_CONTROLLER=y
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
CONFIG_NETDEVICES=y
CONFIG_DUMMY=m
# CONFIG_BONDING is not set
# CONFIG_EQUALIZER is not set
# CONFIG_TUN is not set
+# CONFIG_NET_SB1000 is not set
#
# ARCnet devices
@@ -465,6 +510,11 @@ CONFIG_DUMMY=m
# CONFIG_ARCNET is not set
#
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
+#
# Ethernet (10 or 100Mbit)
#
CONFIG_NET_ETHERNET=y
@@ -485,6 +535,7 @@ CONFIG_TULIP=m
# CONFIG_DE4X5 is not set
# CONFIG_WINBOND_840 is not set
# CONFIG_DM9102 is not set
+# CONFIG_ULI526X is not set
# CONFIG_HP100 is not set
CONFIG_NET_PCI=y
# CONFIG_PCNET32 is not set
@@ -516,6 +567,7 @@ CONFIG_E1000=y
# CONFIG_HAMACHI is not set
# CONFIG_YELLOWFIN is not set
# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
# CONFIG_SKGE is not set
# CONFIG_SK98LIN is not set
# CONFIG_VIA_VELOCITY is not set
@@ -525,6 +577,7 @@ CONFIG_TIGON3=y
#
# Ethernet (10000 Mbit)
#
+# CONFIG_CHELSIO_T1 is not set
# CONFIG_IXGB is not set
# CONFIG_S2IO is not set
@@ -549,6 +602,10 @@ CONFIG_TIGON3=y
# CONFIG_NET_FC is not set
# CONFIG_SHAPER is not set
CONFIG_NETCONSOLE=y
+CONFIG_NETPOLL=y
+# CONFIG_NETPOLL_RX is not set
+# CONFIG_NETPOLL_TRAP is not set
+CONFIG_NET_POLL_CONTROLLER=y
#
# ISDN subsystem
@@ -607,9 +664,7 @@ CONFIG_GAMEPORT=m
# CONFIG_GAMEPORT_NS558 is not set
# CONFIG_GAMEPORT_L4 is not set
# CONFIG_GAMEPORT_EMU10K1 is not set
-# CONFIG_GAMEPORT_VORTEX is not set
# CONFIG_GAMEPORT_FM801 is not set
-# CONFIG_GAMEPORT_CS461X is not set
#
# Character devices
@@ -620,6 +675,7 @@ CONFIG_HW_CONSOLE=y
CONFIG_SERIAL_NONSTANDARD=y
# CONFIG_ROCKETPORT is not set
# CONFIG_CYCLADES is not set
+# CONFIG_DIGIEPCA is not set
# CONFIG_MOXA_SMARTIO is not set
# CONFIG_ISI is not set
# CONFIG_SYNCLINKMP is not set
@@ -641,7 +697,6 @@ CONFIG_SERIAL_8250_NR_UARTS=6
CONFIG_SERIAL_8250_EXTENDED=y
CONFIG_SERIAL_8250_SHARE_IRQ=y
# CONFIG_SERIAL_8250_DETECT_IRQ is not set
-# CONFIG_SERIAL_8250_MULTIPORT is not set
# CONFIG_SERIAL_8250_RSA is not set
#
@@ -650,8 +705,8 @@ CONFIG_SERIAL_8250_SHARE_IRQ=y
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
CONFIG_SERIAL_SGI_L1_CONSOLE=y
-CONFIG_SERIAL_SGI_IOC4=y
# CONFIG_SERIAL_JSM is not set
+CONFIG_SERIAL_SGI_IOC4=y
CONFIG_UNIX98_PTYS=y
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
@@ -684,6 +739,8 @@ CONFIG_DRM_R128=m
CONFIG_DRM_RADEON=m
CONFIG_DRM_MGA=m
CONFIG_DRM_SIS=m
+# CONFIG_DRM_VIA is not set
+# CONFIG_DRM_SAVAGE is not set
CONFIG_RAW_DRIVER=m
CONFIG_HPET=y
# CONFIG_HPET_RTC_IRQ is not set
@@ -708,10 +765,21 @@ CONFIG_MMTIMER=y
# CONFIG_W1 is not set
#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
# Misc devices
#
#
+# Multimedia Capabilities Port drivers
+#
+
+#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
@@ -753,6 +821,7 @@ CONFIG_SND_PCM_OSS=m
CONFIG_SND_SEQUENCER_OSS=y
CONFIG_SND_VERBOSE_PRINTK=y
# CONFIG_SND_DEBUG is not set
+CONFIG_SND_GENERIC_DRIVER=y
#
# Generic devices
@@ -764,11 +833,12 @@ CONFIG_SND_VIRMIDI=m
CONFIG_SND_MTPAV=m
CONFIG_SND_SERIAL_U16550=m
CONFIG_SND_MPU401=m
+CONFIG_SND_AC97_CODEC=m
+CONFIG_SND_AC97_BUS=m
#
# PCI devices
#
-CONFIG_SND_AC97_CODEC=m
# CONFIG_SND_ALI5451 is not set
# CONFIG_SND_ATIIXP is not set
# CONFIG_SND_ATIIXP_MODEM is not set
@@ -790,9 +860,10 @@ CONFIG_SND_EMU10K1=m
# CONFIG_SND_RME96 is not set
# CONFIG_SND_RME9652 is not set
# CONFIG_SND_HDSP is not set
+# CONFIG_SND_HDSPM is not set
# CONFIG_SND_TRIDENT is not set
# CONFIG_SND_YMFPCI is not set
-# CONFIG_SND_ALS4000 is not set
+# CONFIG_SND_AD1889 is not set
# CONFIG_SND_CMIPCI is not set
# CONFIG_SND_ENS1370 is not set
# CONFIG_SND_ENS1371 is not set
@@ -844,6 +915,7 @@ CONFIG_USB_DEVICEFS=y
CONFIG_USB_EHCI_HCD=m
# CONFIG_USB_EHCI_SPLIT_ISO is not set
# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
+# CONFIG_USB_ISP116X_HCD is not set
CONFIG_USB_OHCI_HCD=m
# CONFIG_USB_OHCI_BIG_ENDIAN is not set
CONFIG_USB_OHCI_LITTLE_ENDIAN=y
@@ -853,9 +925,8 @@ CONFIG_USB_UHCI_HCD=m
#
# USB Device Class drivers
#
-# CONFIG_USB_AUDIO is not set
+# CONFIG_OBSOLETE_OSS_USB_DRIVER is not set
# CONFIG_USB_BLUETOOTH_TTY is not set
-# CONFIG_USB_MIDI is not set
# CONFIG_USB_ACM is not set
# CONFIG_USB_PRINTER is not set
@@ -888,12 +959,17 @@ CONFIG_USB_HIDINPUT=y
# CONFIG_USB_MOUSE is not set
# CONFIG_USB_AIPTEK is not set
# CONFIG_USB_WACOM is not set
+# CONFIG_USB_ACECAD is not set
# CONFIG_USB_KBTAB is not set
# CONFIG_USB_POWERMATE is not set
# CONFIG_USB_MTOUCH is not set
+# CONFIG_USB_ITMTOUCH is not set
# CONFIG_USB_EGALAX is not set
+# CONFIG_USB_YEALINK is not set
# CONFIG_USB_XPAD is not set
# CONFIG_USB_ATI_REMOTE is not set
+# CONFIG_USB_KEYSPAN_REMOTE is not set
+# CONFIG_USB_APPLETOUCH is not set
#
# USB Imaging devices
@@ -918,7 +994,7 @@ CONFIG_USB_HIDINPUT=y
# CONFIG_USB_PEGASUS is not set
# CONFIG_USB_RTL8150 is not set
# CONFIG_USB_USBNET is not set
-CONFIG_USB_MON=m
+CONFIG_USB_MON=y
#
# USB port drivers
@@ -944,10 +1020,11 @@ CONFIG_USB_MON=m
# CONFIG_USB_PHIDGETSERVO is not set
# CONFIG_USB_IDMOUSE is not set
# CONFIG_USB_SISUSBVGA is not set
+# CONFIG_USB_LD is not set
# CONFIG_USB_TEST is not set
#
-# USB ATM/DSL drivers
+# USB DSL modem support
#
#
@@ -964,6 +1041,8 @@ CONFIG_USB_MON=m
# InfiniBand support
#
CONFIG_INFINIBAND=m
+# CONFIG_INFINIBAND_USER_MAD is not set
+# CONFIG_INFINIBAND_USER_ACCESS is not set
CONFIG_INFINIBAND_MTHCA=m
# CONFIG_INFINIBAND_MTHCA_DEBUG is not set
CONFIG_INFINIBAND_IPOIB=m
@@ -981,6 +1060,7 @@ CONFIG_EXT2_FS=y
CONFIG_EXT2_FS_XATTR=y
CONFIG_EXT2_FS_POSIX_ACL=y
CONFIG_EXT2_FS_SECURITY=y
+# CONFIG_EXT2_FS_XIP is not set
CONFIG_EXT3_FS=y
CONFIG_EXT3_FS_XATTR=y
CONFIG_EXT3_FS_POSIX_ACL=y
@@ -996,22 +1076,20 @@ CONFIG_REISERFS_FS_POSIX_ACL=y
CONFIG_REISERFS_FS_SECURITY=y
# CONFIG_JFS_FS is not set
CONFIG_FS_POSIX_ACL=y
-
-#
-# XFS support
-#
CONFIG_XFS_FS=y
CONFIG_XFS_EXPORT=y
-# CONFIG_XFS_RT is not set
# CONFIG_XFS_QUOTA is not set
# CONFIG_XFS_SECURITY is not set
# CONFIG_XFS_POSIX_ACL is not set
+# CONFIG_XFS_RT is not set
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
# CONFIG_QUOTA is not set
CONFIG_DNOTIFY=y
CONFIG_AUTOFS_FS=y
CONFIG_AUTOFS4_FS=y
+# CONFIG_FUSE_FS is not set
#
# CD-ROM/DVD Filesystems
@@ -1040,14 +1118,11 @@ CONFIG_NTFS_FS=m
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
-# CONFIG_DEVPTS_FS_XATTR is not set
CONFIG_TMPFS=y
-CONFIG_TMPFS_XATTR=y
-CONFIG_TMPFS_SECURITY=y
CONFIG_HUGETLBFS=y
CONFIG_HUGETLB_PAGE=y
CONFIG_RAMFS=y
+# CONFIG_RELAYFS_FS is not set
#
# Miscellaneous filesystems
@@ -1071,15 +1146,18 @@ CONFIG_RAMFS=y
#
CONFIG_NFS_FS=m
CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
CONFIG_NFS_V4=y
CONFIG_NFS_DIRECTIO=y
CONFIG_NFSD=m
CONFIG_NFSD_V3=y
+# CONFIG_NFSD_V3_ACL is not set
CONFIG_NFSD_V4=y
CONFIG_NFSD_TCP=y
CONFIG_LOCKD=m
CONFIG_LOCKD_V4=y
CONFIG_EXPORTFS=y
+CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=m
CONFIG_SUNRPC_GSS=m
CONFIG_RPCSEC_GSS_KRB5=m
@@ -1094,6 +1172,7 @@ CONFIG_CIFS=m
# CONFIG_NCP_FS is not set
# CONFIG_CODA_FS is not set
# CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
#
# Partition Types
@@ -1163,10 +1242,12 @@ CONFIG_NLS_UTF8=m
# Library routines
#
# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
CONFIG_CRC32=y
# CONFIG_LIBCRC32C is not set
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_GENERIC_PENDING_IRQ=y
#
# HP Simulator drivers
@@ -1187,6 +1268,7 @@ CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_DEBUG_KERNEL=y
CONFIG_MAGIC_SYSRQ=y
CONFIG_LOG_BUF_SHIFT=20
+CONFIG_DETECT_SOFTLOCKUP=y
# CONFIG_SCHEDSTATS is not set
# CONFIG_DEBUG_SLAB is not set
# CONFIG_DEBUG_SPINLOCK is not set
@@ -1194,6 +1276,7 @@ CONFIG_LOG_BUF_SHIFT=20
# CONFIG_DEBUG_KOBJECT is not set
# CONFIG_DEBUG_INFO is not set
# CONFIG_DEBUG_FS is not set
+# CONFIG_KPROBES is not set
CONFIG_IA64_GRANULE_16MB=y
# CONFIG_IA64_GRANULE_64MB is not set
# CONFIG_IA64_PRINT_HAZARDS is not set
@@ -1215,7 +1298,7 @@ CONFIG_CRYPTO=y
# CONFIG_CRYPTO_HMAC is not set
# CONFIG_CRYPTO_NULL is not set
# CONFIG_CRYPTO_MD4 is not set
-CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_MD5=y
# CONFIG_CRYPTO_SHA1 is not set
# CONFIG_CRYPTO_SHA256 is not set
# CONFIG_CRYPTO_SHA512 is not set
diff --git a/arch/ia64/hp/common/hwsw_iommu.c b/arch/ia64/hp/common/hwsw_iommu.c
index 80f8ef013939..a5a5637507be 100644
--- a/arch/ia64/hp/common/hwsw_iommu.c
+++ b/arch/ia64/hp/common/hwsw_iommu.c
@@ -17,7 +17,7 @@
#include <asm/machvec.h>
/* swiotlb declarations & definitions: */
-extern void swiotlb_init_with_default_size (size_t size);
+extern int swiotlb_late_init_with_default_size (size_t size);
extern ia64_mv_dma_alloc_coherent swiotlb_alloc_coherent;
extern ia64_mv_dma_free_coherent swiotlb_free_coherent;
extern ia64_mv_dma_map_single swiotlb_map_single;
@@ -67,11 +67,20 @@ void
hwsw_init (void)
{
/* default to a smallish 2MB sw I/O TLB */
- swiotlb_init_with_default_size (2 * (1<<20));
+ if (swiotlb_late_init_with_default_size (2 * (1<<20)) != 0) {
+#ifdef CONFIG_IA64_GENERIC
+ /* Better to have normal DMA than panic */
+ printk(KERN_WARNING "%s: Failed to initialize software I/O TLB,"
+ " reverting to hpzx1 platform vector\n", __FUNCTION__);
+ machvec_init("hpzx1");
+#else
+ panic("Unable to initialize software I/O TLB services");
+#endif
+ }
}
void *
-hwsw_alloc_coherent (struct device *dev, size_t size, dma_addr_t *dma_handle, int flags)
+hwsw_alloc_coherent (struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t flags)
{
if (use_swiotlb(dev))
return swiotlb_alloc_coherent(dev, size, dma_handle, flags);
diff --git a/arch/ia64/hp/common/sba_iommu.c b/arch/ia64/hp/common/sba_iommu.c
index 11957598a8b9..bdccd0b1eb60 100644
--- a/arch/ia64/hp/common/sba_iommu.c
+++ b/arch/ia64/hp/common/sba_iommu.c
@@ -1076,7 +1076,7 @@ void sba_unmap_single(struct device *dev, dma_addr_t iova, size_t size, int dir)
* See Documentation/DMA-mapping.txt
*/
void *
-sba_alloc_coherent (struct device *dev, size_t size, dma_addr_t *dma_handle, int flags)
+sba_alloc_coherent (struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t flags)
{
struct ioc *ioc;
void *addr;
@@ -2028,9 +2028,40 @@ static struct acpi_driver acpi_sba_ioc_driver = {
static int __init
sba_init(void)
{
+ if (!ia64_platform_is("hpzx1") && !ia64_platform_is("hpzx1_swiotlb"))
+ return 0;
+
acpi_bus_register_driver(&acpi_sba_ioc_driver);
- if (!ioc_list)
+ if (!ioc_list) {
+#ifdef CONFIG_IA64_GENERIC
+ extern int swiotlb_late_init_with_default_size (size_t size);
+
+ /*
+ * If we didn't find something sba_iommu can claim, we
+ * need to setup the swiotlb and switch to the dig machvec.
+ */
+ if (swiotlb_late_init_with_default_size(64 * (1<<20)) != 0)
+ panic("Unable to find SBA IOMMU or initialize "
+ "software I/O TLB: Try machvec=dig boot option");
+ machvec_init("dig");
+#else
+ panic("Unable to find SBA IOMMU: Try a generic or DIG kernel");
+#endif
return 0;
+ }
+
+#if defined(CONFIG_IA64_GENERIC) || defined(CONFIG_IA64_HP_ZX1_SWIOTLB)
+ /*
+ * hpzx1_swiotlb needs to have a fairly small swiotlb bounce
+ * buffer setup to support devices with smaller DMA masks than
+ * sba_iommu can handle.
+ */
+ if (ia64_platform_is("hpzx1_swiotlb")) {
+ extern void hwsw_init(void);
+
+ hwsw_init();
+ }
+#endif
#ifdef CONFIG_PCI
{
@@ -2048,18 +2079,6 @@ sba_init(void)
subsys_initcall(sba_init); /* must be initialized after ACPI etc., but before any drivers... */
-extern void dig_setup(char**);
-/*
- * MAX_DMA_ADDRESS needs to be setup prior to paging_init to do any good,
- * so we use the platform_setup hook to fix it up.
- */
-void __init
-sba_setup(char **cmdline_p)
-{
- MAX_DMA_ADDRESS = ~0UL;
- dig_setup(cmdline_p);
-}
-
static int __init
nosbagart(char *str)
{
diff --git a/arch/ia64/hp/sim/simscsi.c b/arch/ia64/hp/sim/simscsi.c
index a18983a3c934..a3fe97531134 100644
--- a/arch/ia64/hp/sim/simscsi.c
+++ b/arch/ia64/hp/sim/simscsi.c
@@ -205,10 +205,11 @@ simscsi_get_disk_size (int fd)
char buf[512];
/*
- * This is a bit kludgey: the simulator doesn't provide a direct way of determining
- * the disk size, so we do a binary search, assuming a maximum disk size of 4GB.
+ * This is a bit kludgey: the simulator doesn't provide a
+ * direct way of determining the disk size, so we do a binary
+ * search, assuming a maximum disk size of 128GB.
*/
- for (bit = (4UL << 30)/512; bit != 0; bit >>= 1) {
+ for (bit = (128UL << 30)/512; bit != 0; bit >>= 1) {
req.addr = __pa(&buf);
req.len = sizeof(buf);
ia64_ssc(fd, 1, __pa(&req), ((sectors | bit) - 1)*512, SSC_READ);
@@ -225,8 +226,10 @@ simscsi_readwrite10 (struct scsi_cmnd *sc, int mode)
{
unsigned long offset;
- offset = ( (sc->cmnd[2] << 24) | (sc->cmnd[3] << 16)
- | (sc->cmnd[4] << 8) | (sc->cmnd[5] << 0))*512;
+ offset = (((unsigned long)sc->cmnd[2] << 24)
+ | ((unsigned long)sc->cmnd[3] << 16)
+ | ((unsigned long)sc->cmnd[4] << 8)
+ | ((unsigned long)sc->cmnd[5] << 0))*512UL;
if (sc->use_sg > 0)
simscsi_sg_readwrite(sc, mode, offset);
else
diff --git a/arch/ia64/hp/sim/simserial.c b/arch/ia64/hp/sim/simserial.c
index b42ec37be51c..19ee635eeb70 100644
--- a/arch/ia64/hp/sim/simserial.c
+++ b/arch/ia64/hp/sim/simserial.c
@@ -642,10 +642,8 @@ static void rs_close(struct tty_struct *tty, struct file * filp)
info->event = 0;
info->tty = 0;
if (info->blocked_open) {
- if (info->close_delay) {
- current->state = TASK_INTERRUPTIBLE;
- schedule_timeout(info->close_delay);
- }
+ if (info->close_delay)
+ schedule_timeout_interruptible(info->close_delay);
wake_up_interruptible(&info->open_wait);
}
info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
diff --git a/arch/ia64/ia32/ia32_ioctl.c b/arch/ia64/ia32/ia32_ioctl.c
index 164b211f4174..88739394f6df 100644
--- a/arch/ia64/ia32/ia32_ioctl.c
+++ b/arch/ia64/ia32/ia32_ioctl.c
@@ -29,10 +29,8 @@
#define CODE
#include "compat_ioctl.c"
-typedef int (* ioctl32_handler_t)(unsigned int, unsigned int, unsigned long, struct file *);
-
#define COMPATIBLE_IOCTL(cmd) HANDLE_IOCTL((cmd),sys_ioctl)
-#define HANDLE_IOCTL(cmd,handler) { (cmd), (ioctl32_handler_t)(handler), NULL },
+#define HANDLE_IOCTL(cmd,handler) { (cmd), (ioctl_trans_handler_t)(handler), NULL },
#define IOCTL_TABLE_START \
struct ioctl_trans ioctl_start[] = {
#define IOCTL_TABLE_END \
diff --git a/arch/ia64/ia32/sys_ia32.c b/arch/ia64/ia32/sys_ia32.c
index 3fa67ecebc83..dc282710421a 100644
--- a/arch/ia64/ia32/sys_ia32.c
+++ b/arch/ia64/ia32/sys_ia32.c
@@ -36,6 +36,7 @@
#include <linux/uio.h>
#include <linux/nfs_fs.h>
#include <linux/quota.h>
+#include <linux/syscalls.h>
#include <linux/sunrpc/svc.h>
#include <linux/nfsd/nfsd.h>
#include <linux/nfsd/cache.h>
diff --git a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c
index 7e926471e4ec..9ad94ddf6687 100644
--- a/arch/ia64/kernel/acpi.c
+++ b/arch/ia64/kernel/acpi.c
@@ -838,7 +838,7 @@ EXPORT_SYMBOL(acpi_unmap_lsapic);
#endif /* CONFIG_ACPI_HOTPLUG_CPU */
#ifdef CONFIG_ACPI_NUMA
-acpi_status __devinit
+static acpi_status __devinit
acpi_map_iosapic(acpi_handle handle, u32 depth, void *context, void **ret)
{
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
@@ -890,7 +890,16 @@ acpi_map_iosapic(acpi_handle handle, u32 depth, void *context, void **ret)
map_iosapic_to_node(gsi_base, node);
return AE_OK;
}
-#endif /* CONFIG_NUMA */
+
+static int __init
+acpi_map_iosapics (void)
+{
+ acpi_get_devices(NULL, acpi_map_iosapic, NULL, NULL);
+ return 0;
+}
+
+fs_initcall(acpi_map_iosapics);
+#endif /* CONFIG_ACPI_NUMA */
int acpi_register_ioapic(acpi_handle handle, u64 phys_addr, u32 gsi_base)
{
diff --git a/arch/ia64/kernel/cyclone.c b/arch/ia64/kernel/cyclone.c
index 768c7e46957c..6ade3790ce07 100644
--- a/arch/ia64/kernel/cyclone.c
+++ b/arch/ia64/kernel/cyclone.c
@@ -2,6 +2,7 @@
#include <linux/smp.h>
#include <linux/time.h>
#include <linux/errno.h>
+#include <linux/timex.h>
#include <asm/io.h>
/* IBM Summit (EXA) Cyclone counter code*/
diff --git a/arch/ia64/kernel/efi.c b/arch/ia64/kernel/efi.c
index 179f230816ed..a3aa45cbcfa0 100644
--- a/arch/ia64/kernel/efi.c
+++ b/arch/ia64/kernel/efi.c
@@ -239,57 +239,30 @@ is_available_memory (efi_memory_desc_t *md)
return 0;
}
-/*
- * Trim descriptor MD so its starts at address START_ADDR. If the descriptor covers
- * memory that is normally available to the kernel, issue a warning that some memory
- * is being ignored.
- */
-static void
-trim_bottom (efi_memory_desc_t *md, u64 start_addr)
-{
- u64 num_skipped_pages;
+typedef struct kern_memdesc {
+ u64 attribute;
+ u64 start;
+ u64 num_pages;
+} kern_memdesc_t;
- if (md->phys_addr >= start_addr || !md->num_pages)
- return;
-
- num_skipped_pages = (start_addr - md->phys_addr) >> EFI_PAGE_SHIFT;
- if (num_skipped_pages > md->num_pages)
- num_skipped_pages = md->num_pages;
-
- if (is_available_memory(md))
- printk(KERN_NOTICE "efi.%s: ignoring %luKB of memory at 0x%lx due to granule hole "
- "at 0x%lx\n", __FUNCTION__,
- (num_skipped_pages << EFI_PAGE_SHIFT) >> 10,
- md->phys_addr, start_addr - IA64_GRANULE_SIZE);
- /*
- * NOTE: Don't set md->phys_addr to START_ADDR because that could cause the memory
- * descriptor list to become unsorted. In such a case, md->num_pages will be
- * zero, so the Right Thing will happen.
- */
- md->phys_addr += num_skipped_pages << EFI_PAGE_SHIFT;
- md->num_pages -= num_skipped_pages;
-}
+static kern_memdesc_t *kern_memmap;
static void
-trim_top (efi_memory_desc_t *md, u64 end_addr)
+walk (efi_freemem_callback_t callback, void *arg, u64 attr)
{
- u64 num_dropped_pages, md_end_addr;
-
- md_end_addr = md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT);
-
- if (md_end_addr <= end_addr || !md->num_pages)
- return;
+ kern_memdesc_t *k;
+ u64 start, end, voff;
- num_dropped_pages = (md_end_addr - end_addr) >> EFI_PAGE_SHIFT;
- if (num_dropped_pages > md->num_pages)
- num_dropped_pages = md->num_pages;
-
- if (is_available_memory(md))
- printk(KERN_NOTICE "efi.%s: ignoring %luKB of memory at 0x%lx due to granule hole "
- "at 0x%lx\n", __FUNCTION__,
- (num_dropped_pages << EFI_PAGE_SHIFT) >> 10,
- md->phys_addr, end_addr);
- md->num_pages -= num_dropped_pages;
+ voff = (attr == EFI_MEMORY_WB) ? PAGE_OFFSET : __IA64_UNCACHED_OFFSET;
+ for (k = kern_memmap; k->start != ~0UL; k++) {
+ if (k->attribute != attr)
+ continue;
+ start = PAGE_ALIGN(k->start);
+ end = (k->start + (k->num_pages << EFI_PAGE_SHIFT)) & PAGE_MASK;
+ if (start < end)
+ if ((*callback)(start + voff, end + voff, arg) < 0)
+ return;
+ }
}
/*
@@ -299,148 +272,19 @@ trim_top (efi_memory_desc_t *md, u64 end_addr)
void
efi_memmap_walk (efi_freemem_callback_t callback, void *arg)
{
- int prev_valid = 0;
- struct range {
- u64 start;
- u64 end;
- } prev, curr;
- void *efi_map_start, *efi_map_end, *p, *q;
- efi_memory_desc_t *md, *check_md;
- u64 efi_desc_size, start, end, granule_addr, last_granule_addr, first_non_wb_addr = 0;
- unsigned long total_mem = 0;
-
- efi_map_start = __va(ia64_boot_param->efi_memmap);
- efi_map_end = efi_map_start + ia64_boot_param->efi_memmap_size;
- efi_desc_size = ia64_boot_param->efi_memdesc_size;
-
- for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) {
- md = p;
-
- /* skip over non-WB memory descriptors; that's all we're interested in... */
- if (!(md->attribute & EFI_MEMORY_WB))
- continue;
-
- /*
- * granule_addr is the base of md's first granule.
- * [granule_addr - first_non_wb_addr) is guaranteed to
- * be contiguous WB memory.
- */
- granule_addr = GRANULEROUNDDOWN(md->phys_addr);
- first_non_wb_addr = max(first_non_wb_addr, granule_addr);
-
- if (first_non_wb_addr < md->phys_addr) {
- trim_bottom(md, granule_addr + IA64_GRANULE_SIZE);
- granule_addr = GRANULEROUNDDOWN(md->phys_addr);
- first_non_wb_addr = max(first_non_wb_addr, granule_addr);
- }
-
- for (q = p; q < efi_map_end; q += efi_desc_size) {
- check_md = q;
-
- if ((check_md->attribute & EFI_MEMORY_WB) &&
- (check_md->phys_addr == first_non_wb_addr))
- first_non_wb_addr += check_md->num_pages << EFI_PAGE_SHIFT;
- else
- break; /* non-WB or hole */
- }
-
- last_granule_addr = GRANULEROUNDDOWN(first_non_wb_addr);
- if (last_granule_addr < md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT))
- trim_top(md, last_granule_addr);
-
- if (is_available_memory(md)) {
- if (md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT) >= max_addr) {
- if (md->phys_addr >= max_addr)
- continue;
- md->num_pages = (max_addr - md->phys_addr) >> EFI_PAGE_SHIFT;
- first_non_wb_addr = max_addr;
- }
-
- if (total_mem >= mem_limit)
- continue;
-
- if (total_mem + (md->num_pages << EFI_PAGE_SHIFT) > mem_limit) {
- unsigned long limit_addr = md->phys_addr;
-
- limit_addr += mem_limit - total_mem;
- limit_addr = GRANULEROUNDDOWN(limit_addr);
-
- if (md->phys_addr > limit_addr)
- continue;
-
- md->num_pages = (limit_addr - md->phys_addr) >>
- EFI_PAGE_SHIFT;
- first_non_wb_addr = max_addr = md->phys_addr +
- (md->num_pages << EFI_PAGE_SHIFT);
- }
- total_mem += (md->num_pages << EFI_PAGE_SHIFT);
-
- if (md->num_pages == 0)
- continue;
-
- curr.start = PAGE_OFFSET + md->phys_addr;
- curr.end = curr.start + (md->num_pages << EFI_PAGE_SHIFT);
-
- if (!prev_valid) {
- prev = curr;
- prev_valid = 1;
- } else {
- if (curr.start < prev.start)
- printk(KERN_ERR "Oops: EFI memory table not ordered!\n");
-
- if (prev.end == curr.start) {
- /* merge two consecutive memory ranges */
- prev.end = curr.end;
- } else {
- start = PAGE_ALIGN(prev.start);
- end = prev.end & PAGE_MASK;
- if ((end > start) && (*callback)(start, end, arg) < 0)
- return;
- prev = curr;
- }
- }
- }
- }
- if (prev_valid) {
- start = PAGE_ALIGN(prev.start);
- end = prev.end & PAGE_MASK;
- if (end > start)
- (*callback)(start, end, arg);
- }
+ walk(callback, arg, EFI_MEMORY_WB);
}
/*
- * Walk the EFI memory map to pull out leftover pages in the lower
- * memory regions which do not end up in the regular memory map and
- * stick them into the uncached allocator
- *
- * The regular walk function is significantly more complex than the
- * uncached walk which means it really doesn't make sense to try and
- * marge the two.
+ * Walks the EFI memory map and calls CALLBACK once for each EFI memory descriptor that
+ * has memory that is available for uncached allocator.
*/
-void __init
-efi_memmap_walk_uc (efi_freemem_callback_t callback)
+void
+efi_memmap_walk_uc (efi_freemem_callback_t callback, void *arg)
{
- void *efi_map_start, *efi_map_end, *p;
- efi_memory_desc_t *md;
- u64 efi_desc_size, start, end;
-
- efi_map_start = __va(ia64_boot_param->efi_memmap);
- efi_map_end = efi_map_start + ia64_boot_param->efi_memmap_size;
- efi_desc_size = ia64_boot_param->efi_memdesc_size;
-
- for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) {
- md = p;
- if (md->attribute == EFI_MEMORY_UC) {
- start = PAGE_ALIGN(md->phys_addr);
- end = PAGE_ALIGN((md->phys_addr+(md->num_pages << EFI_PAGE_SHIFT)) & PAGE_MASK);
- if ((*callback)(start, end, NULL) < 0)
- return;
- }
- }
+ walk(callback, arg, EFI_MEMORY_UC);
}
-
/*
* Look for the PAL_CODE region reported by EFI and maps it using an
* ITR to enable safe PAL calls in virtual mode. See IA-64 Processor
@@ -862,3 +706,307 @@ efi_uart_console_only(void)
printk(KERN_ERR "Malformed %s value\n", name);
return 0;
}
+
+#define efi_md_size(md) (md->num_pages << EFI_PAGE_SHIFT)
+
+static inline u64
+kmd_end(kern_memdesc_t *kmd)
+{
+ return (kmd->start + (kmd->num_pages << EFI_PAGE_SHIFT));
+}
+
+static inline u64
+efi_md_end(efi_memory_desc_t *md)
+{
+ return (md->phys_addr + efi_md_size(md));
+}
+
+static inline int
+efi_wb(efi_memory_desc_t *md)
+{
+ return (md->attribute & EFI_MEMORY_WB);
+}
+
+static inline int
+efi_uc(efi_memory_desc_t *md)
+{
+ return (md->attribute & EFI_MEMORY_UC);
+}
+
+/*
+ * Look for the first granule aligned memory descriptor memory
+ * that is big enough to hold EFI memory map. Make sure this
+ * descriptor is atleast granule sized so it does not get trimmed
+ */
+struct kern_memdesc *
+find_memmap_space (void)
+{
+ u64 contig_low=0, contig_high=0;
+ u64 as = 0, ae;
+ void *efi_map_start, *efi_map_end, *p, *q;
+ efi_memory_desc_t *md, *pmd = NULL, *check_md;
+ u64 space_needed, efi_desc_size;
+ unsigned long total_mem = 0;
+
+ efi_map_start = __va(ia64_boot_param->efi_memmap);
+ efi_map_end = efi_map_start + ia64_boot_param->efi_memmap_size;
+ efi_desc_size = ia64_boot_param->efi_memdesc_size;
+
+ /*
+ * Worst case: we need 3 kernel descriptors for each efi descriptor
+ * (if every entry has a WB part in the middle, and UC head and tail),
+ * plus one for the end marker.
+ */
+ space_needed = sizeof(kern_memdesc_t) *
+ (3 * (ia64_boot_param->efi_memmap_size/efi_desc_size) + 1);
+
+ for (p = efi_map_start; p < efi_map_end; pmd = md, p += efi_desc_size) {
+ md = p;
+ if (!efi_wb(md)) {
+ continue;
+ }
+ if (pmd == NULL || !efi_wb(pmd) || efi_md_end(pmd) != md->phys_addr) {
+ contig_low = GRANULEROUNDUP(md->phys_addr);
+ contig_high = efi_md_end(md);
+ for (q = p + efi_desc_size; q < efi_map_end; q += efi_desc_size) {
+ check_md = q;
+ if (!efi_wb(check_md))
+ break;
+ if (contig_high != check_md->phys_addr)
+ break;
+ contig_high = efi_md_end(check_md);
+ }
+ contig_high = GRANULEROUNDDOWN(contig_high);
+ }
+ if (!is_available_memory(md) || md->type == EFI_LOADER_DATA)
+ continue;
+
+ /* Round ends inward to granule boundaries */
+ as = max(contig_low, md->phys_addr);
+ ae = min(contig_high, efi_md_end(md));
+
+ /* keep within max_addr= command line arg */
+ ae = min(ae, max_addr);
+ if (ae <= as)
+ continue;
+
+ /* avoid going over mem= command line arg */
+ if (total_mem + (ae - as) > mem_limit)
+ ae -= total_mem + (ae - as) - mem_limit;
+
+ if (ae <= as)
+ continue;
+
+ if (ae - as > space_needed)
+ break;
+ }
+ if (p >= efi_map_end)
+ panic("Can't allocate space for kernel memory descriptors");
+
+ return __va(as);
+}
+
+/*
+ * Walk the EFI memory map and gather all memory available for kernel
+ * to use. We can allocate partial granules only if the unavailable
+ * parts exist, and are WB.
+ */
+void
+efi_memmap_init(unsigned long *s, unsigned long *e)
+{
+ struct kern_memdesc *k, *prev = 0;
+ u64 contig_low=0, contig_high=0;
+ u64 as, ae, lim;
+ void *efi_map_start, *efi_map_end, *p, *q;
+ efi_memory_desc_t *md, *pmd = NULL, *check_md;
+ u64 efi_desc_size;
+ unsigned long total_mem = 0;
+
+ k = kern_memmap = find_memmap_space();
+
+ efi_map_start = __va(ia64_boot_param->efi_memmap);
+ efi_map_end = efi_map_start + ia64_boot_param->efi_memmap_size;
+ efi_desc_size = ia64_boot_param->efi_memdesc_size;
+
+ for (p = efi_map_start; p < efi_map_end; pmd = md, p += efi_desc_size) {
+ md = p;
+ if (!efi_wb(md)) {
+ if (efi_uc(md) && (md->type == EFI_CONVENTIONAL_MEMORY ||
+ md->type == EFI_BOOT_SERVICES_DATA)) {
+ k->attribute = EFI_MEMORY_UC;
+ k->start = md->phys_addr;
+ k->num_pages = md->num_pages;
+ k++;
+ }
+ continue;
+ }
+ if (pmd == NULL || !efi_wb(pmd) || efi_md_end(pmd) != md->phys_addr) {
+ contig_low = GRANULEROUNDUP(md->phys_addr);
+ contig_high = efi_md_end(md);
+ for (q = p + efi_desc_size; q < efi_map_end; q += efi_desc_size) {
+ check_md = q;
+ if (!efi_wb(check_md))
+ break;
+ if (contig_high != check_md->phys_addr)
+ break;
+ contig_high = efi_md_end(check_md);
+ }
+ contig_high = GRANULEROUNDDOWN(contig_high);
+ }
+ if (!is_available_memory(md))
+ continue;
+
+ /*
+ * Round ends inward to granule boundaries
+ * Give trimmings to uncached allocator
+ */
+ if (md->phys_addr < contig_low) {
+ lim = min(efi_md_end(md), contig_low);
+ if (efi_uc(md)) {
+ if (k > kern_memmap && (k-1)->attribute == EFI_MEMORY_UC &&
+ kmd_end(k-1) == md->phys_addr) {
+ (k-1)->num_pages += (lim - md->phys_addr) >> EFI_PAGE_SHIFT;
+ } else {
+ k->attribute = EFI_MEMORY_UC;
+ k->start = md->phys_addr;
+ k->num_pages = (lim - md->phys_addr) >> EFI_PAGE_SHIFT;
+ k++;
+ }
+ }
+ as = contig_low;
+ } else
+ as = md->phys_addr;
+
+ if (efi_md_end(md) > contig_high) {
+ lim = max(md->phys_addr, contig_high);
+ if (efi_uc(md)) {
+ if (lim == md->phys_addr && k > kern_memmap &&
+ (k-1)->attribute == EFI_MEMORY_UC &&
+ kmd_end(k-1) == md->phys_addr) {
+ (k-1)->num_pages += md->num_pages;
+ } else {
+ k->attribute = EFI_MEMORY_UC;
+ k->start = lim;
+ k->num_pages = (efi_md_end(md) - lim) >> EFI_PAGE_SHIFT;
+ k++;
+ }
+ }
+ ae = contig_high;
+ } else
+ ae = efi_md_end(md);
+
+ /* keep within max_addr= command line arg */
+ ae = min(ae, max_addr);
+ if (ae <= as)
+ continue;
+
+ /* avoid going over mem= command line arg */
+ if (total_mem + (ae - as) > mem_limit)
+ ae -= total_mem + (ae - as) - mem_limit;
+
+ if (ae <= as)
+ continue;
+ if (prev && kmd_end(prev) == md->phys_addr) {
+ prev->num_pages += (ae - as) >> EFI_PAGE_SHIFT;
+ total_mem += ae - as;
+ continue;
+ }
+ k->attribute = EFI_MEMORY_WB;
+ k->start = as;
+ k->num_pages = (ae - as) >> EFI_PAGE_SHIFT;
+ total_mem += ae - as;
+ prev = k++;
+ }
+ k->start = ~0L; /* end-marker */
+
+ /* reserve the memory we are using for kern_memmap */
+ *s = (u64)kern_memmap;
+ *e = (u64)++k;
+}
+
+void
+efi_initialize_iomem_resources(struct resource *code_resource,
+ struct resource *data_resource)
+{
+ struct resource *res;
+ void *efi_map_start, *efi_map_end, *p;
+ efi_memory_desc_t *md;
+ u64 efi_desc_size;
+ char *name;
+ unsigned long flags;
+
+ efi_map_start = __va(ia64_boot_param->efi_memmap);
+ efi_map_end = efi_map_start + ia64_boot_param->efi_memmap_size;
+ efi_desc_size = ia64_boot_param->efi_memdesc_size;
+
+ res = NULL;
+
+ for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) {
+ md = p;
+
+ if (md->num_pages == 0) /* should not happen */
+ continue;
+
+ flags = IORESOURCE_MEM;
+ switch (md->type) {
+
+ case EFI_MEMORY_MAPPED_IO:
+ case EFI_MEMORY_MAPPED_IO_PORT_SPACE:
+ continue;
+
+ case EFI_LOADER_CODE:
+ case EFI_LOADER_DATA:
+ case EFI_BOOT_SERVICES_DATA:
+ case EFI_BOOT_SERVICES_CODE:
+ case EFI_CONVENTIONAL_MEMORY:
+ if (md->attribute & EFI_MEMORY_WP) {
+ name = "System ROM";
+ flags |= IORESOURCE_READONLY;
+ } else {
+ name = "System RAM";
+ }
+ break;
+
+ case EFI_ACPI_MEMORY_NVS:
+ name = "ACPI Non-volatile Storage";
+ flags |= IORESOURCE_BUSY;
+ break;
+
+ case EFI_UNUSABLE_MEMORY:
+ name = "reserved";
+ flags |= IORESOURCE_BUSY | IORESOURCE_DISABLED;
+ break;
+
+ case EFI_RESERVED_TYPE:
+ case EFI_RUNTIME_SERVICES_CODE:
+ case EFI_RUNTIME_SERVICES_DATA:
+ case EFI_ACPI_RECLAIM_MEMORY:
+ default:
+ name = "reserved";
+ flags |= IORESOURCE_BUSY;
+ break;
+ }
+
+ if ((res = kzalloc(sizeof(struct resource), GFP_KERNEL)) == NULL) {
+ printk(KERN_ERR "failed to alocate resource for iomem\n");
+ return;
+ }
+
+ res->name = name;
+ res->start = md->phys_addr;
+ res->end = md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT) - 1;
+ res->flags = flags;
+
+ if (insert_resource(&iomem_resource, res) < 0)
+ kfree(res);
+ else {
+ /*
+ * We don't know which region contains
+ * kernel data so we try it repeatedly and
+ * let the resource manager test it.
+ */
+ insert_resource(res, code_resource);
+ insert_resource(res, data_resource);
+ }
+ }
+}
diff --git a/arch/ia64/kernel/irq.c b/arch/ia64/kernel/irq.c
index 205d98028261..d33244c32759 100644
--- a/arch/ia64/kernel/irq.c
+++ b/arch/ia64/kernel/irq.c
@@ -57,9 +57,9 @@ int show_interrupts(struct seq_file *p, void *v)
if (i == 0) {
seq_printf(p, " ");
- for (j=0; j<NR_CPUS; j++)
- if (cpu_online(j))
- seq_printf(p, "CPU%d ",j);
+ for_each_online_cpu(j) {
+ seq_printf(p, "CPU%d ",j);
+ }
seq_putc(p, '\n');
}
@@ -72,9 +72,9 @@ int show_interrupts(struct seq_file *p, void *v)
#ifndef CONFIG_SMP
seq_printf(p, "%10u ", kstat_irqs(i));
#else
- for (j = 0; j < NR_CPUS; j++)
- if (cpu_online(j))
- seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
+ for_each_online_cpu(j) {
+ seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
+ }
#endif
seq_printf(p, " %14s", irq_desc[i].handler->typename);
seq_printf(p, " %s", action->name);
diff --git a/arch/ia64/kernel/kprobes.c b/arch/ia64/kernel/kprobes.c
index 471086b808a4..801eeaeaf3de 100644
--- a/arch/ia64/kernel/kprobes.c
+++ b/arch/ia64/kernel/kprobes.c
@@ -26,7 +26,6 @@
#include <linux/config.h>
#include <linux/kprobes.h>
#include <linux/ptrace.h>
-#include <linux/spinlock.h>
#include <linux/string.h>
#include <linux/slab.h>
#include <linux/preempt.h>
@@ -38,13 +37,8 @@
extern void jprobe_inst_return(void);
-/* kprobe_status settings */
-#define KPROBE_HIT_ACTIVE 0x00000001
-#define KPROBE_HIT_SS 0x00000002
-
-static struct kprobe *current_kprobe, *kprobe_prev;
-static unsigned long kprobe_status, kprobe_status_prev;
-static struct pt_regs jprobe_saved_regs;
+DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
+DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
enum instruction_type {A, I, M, F, B, L, X, u};
static enum instruction_type bundle_encoding[32][3] = {
@@ -313,21 +307,22 @@ static int __kprobes valid_kprobe_addr(int template, int slot,
return 0;
}
-static inline void save_previous_kprobe(void)
+static inline void save_previous_kprobe(struct kprobe_ctlblk *kcb)
{
- kprobe_prev = current_kprobe;
- kprobe_status_prev = kprobe_status;
+ kcb->prev_kprobe.kp = kprobe_running();
+ kcb->prev_kprobe.status = kcb->kprobe_status;
}
-static inline void restore_previous_kprobe(void)
+static inline void restore_previous_kprobe(struct kprobe_ctlblk *kcb)
{
- current_kprobe = kprobe_prev;
- kprobe_status = kprobe_status_prev;
+ __get_cpu_var(current_kprobe) = kcb->prev_kprobe.kp;
+ kcb->kprobe_status = kcb->prev_kprobe.status;
}
-static inline void set_current_kprobe(struct kprobe *p)
+static inline void set_current_kprobe(struct kprobe *p,
+ struct kprobe_ctlblk *kcb)
{
- current_kprobe = p;
+ __get_cpu_var(current_kprobe) = p;
}
static void kretprobe_trampoline(void)
@@ -347,11 +342,12 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
struct kretprobe_instance *ri = NULL;
struct hlist_head *head;
struct hlist_node *node, *tmp;
- unsigned long orig_ret_address = 0;
+ unsigned long flags, orig_ret_address = 0;
unsigned long trampoline_address =
((struct fnptr *)kretprobe_trampoline)->ip;
- head = kretprobe_inst_table_head(current);
+ spin_lock_irqsave(&kretprobe_lock, flags);
+ head = kretprobe_inst_table_head(current);
/*
* It is possible to have multiple instances associated with a given
@@ -367,9 +363,9 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
* kretprobe_trampoline
*/
hlist_for_each_entry_safe(ri, node, tmp, head, hlist) {
- if (ri->task != current)
+ if (ri->task != current)
/* another task is sharing our hash bucket */
- continue;
+ continue;
if (ri->rp && ri->rp->handler)
ri->rp->handler(ri, regs);
@@ -389,17 +385,19 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
BUG_ON(!orig_ret_address || (orig_ret_address == trampoline_address));
regs->cr_iip = orig_ret_address;
- unlock_kprobes();
+ reset_current_kprobe();
+ spin_unlock_irqrestore(&kretprobe_lock, flags);
preempt_enable_no_resched();
- /*
- * By returning a non-zero value, we are telling
- * kprobe_handler() that we have handled unlocking
- * and re-enabling preemption.
- */
- return 1;
+ /*
+ * By returning a non-zero value, we are telling
+ * kprobe_handler() that we don't want the post_handler
+ * to run (and have re-enabled preemption)
+ */
+ return 1;
}
+/* Called with kretprobe_lock held */
void __kprobes arch_prepare_kretprobe(struct kretprobe *rp,
struct pt_regs *regs)
{
@@ -606,17 +604,22 @@ static int __kprobes pre_kprobes_handler(struct die_args *args)
int ret = 0;
struct pt_regs *regs = args->regs;
kprobe_opcode_t *addr = (kprobe_opcode_t *)instruction_pointer(regs);
+ struct kprobe_ctlblk *kcb;
+ /*
+ * We don't want to be preempted for the entire
+ * duration of kprobe processing
+ */
preempt_disable();
+ kcb = get_kprobe_ctlblk();
/* Handle recursion cases */
if (kprobe_running()) {
p = get_kprobe(addr);
if (p) {
- if ( (kprobe_status == KPROBE_HIT_SS) &&
+ if ((kcb->kprobe_status == KPROBE_HIT_SS) &&
(p->ainsn.inst_flag == INST_FLAG_BREAK_INST)) {
ia64_psr(regs)->ss = 0;
- unlock_kprobes();
goto no_kprobe;
}
/* We have reentered the pre_kprobe_handler(), since
@@ -625,17 +628,17 @@ static int __kprobes pre_kprobes_handler(struct die_args *args)
* just single step on the instruction of the new probe
* without calling any user handlers.
*/
- save_previous_kprobe();
- set_current_kprobe(p);
+ save_previous_kprobe(kcb);
+ set_current_kprobe(p, kcb);
p->nmissed++;
prepare_ss(p, regs);
- kprobe_status = KPROBE_REENTER;
+ kcb->kprobe_status = KPROBE_REENTER;
return 1;
} else if (args->err == __IA64_BREAK_JPROBE) {
/*
* jprobe instrumented function just completed
*/
- p = current_kprobe;
+ p = __get_cpu_var(current_kprobe);
if (p->break_handler && p->break_handler(p, regs)) {
goto ss_probe;
}
@@ -645,10 +648,8 @@ static int __kprobes pre_kprobes_handler(struct die_args *args)
}
}
- lock_kprobes();
p = get_kprobe(addr);
if (!p) {
- unlock_kprobes();
if (!is_ia64_break_inst(regs)) {
/*
* The breakpoint instruction was removed right
@@ -665,8 +666,8 @@ static int __kprobes pre_kprobes_handler(struct die_args *args)
goto no_kprobe;
}
- kprobe_status = KPROBE_HIT_ACTIVE;
- set_current_kprobe(p);
+ set_current_kprobe(p, kcb);
+ kcb->kprobe_status = KPROBE_HIT_ACTIVE;
if (p->pre_handler && p->pre_handler(p, regs))
/*
@@ -678,7 +679,7 @@ static int __kprobes pre_kprobes_handler(struct die_args *args)
ss_probe:
prepare_ss(p, regs);
- kprobe_status = KPROBE_HIT_SS;
+ kcb->kprobe_status = KPROBE_HIT_SS;
return 1;
no_kprobe:
@@ -688,23 +689,25 @@ no_kprobe:
static int __kprobes post_kprobes_handler(struct pt_regs *regs)
{
- if (!kprobe_running())
+ struct kprobe *cur = kprobe_running();
+ struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
+
+ if (!cur)
return 0;
- if ((kprobe_status != KPROBE_REENTER) && current_kprobe->post_handler) {
- kprobe_status = KPROBE_HIT_SSDONE;
- current_kprobe->post_handler(current_kprobe, regs, 0);
+ if ((kcb->kprobe_status != KPROBE_REENTER) && cur->post_handler) {
+ kcb->kprobe_status = KPROBE_HIT_SSDONE;
+ cur->post_handler(cur, regs, 0);
}
- resume_execution(current_kprobe, regs);
+ resume_execution(cur, regs);
/*Restore back the original saved kprobes variables and continue. */
- if (kprobe_status == KPROBE_REENTER) {
- restore_previous_kprobe();
+ if (kcb->kprobe_status == KPROBE_REENTER) {
+ restore_previous_kprobe(kcb);
goto out;
}
-
- unlock_kprobes();
+ reset_current_kprobe();
out:
preempt_enable_no_resched();
@@ -713,16 +716,15 @@ out:
static int __kprobes kprobes_fault_handler(struct pt_regs *regs, int trapnr)
{
- if (!kprobe_running())
- return 0;
+ struct kprobe *cur = kprobe_running();
+ struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
- if (current_kprobe->fault_handler &&
- current_kprobe->fault_handler(current_kprobe, regs, trapnr))
+ if (cur->fault_handler && cur->fault_handler(cur, regs, trapnr))
return 1;
- if (kprobe_status & KPROBE_HIT_SS) {
- resume_execution(current_kprobe, regs);
- unlock_kprobes();
+ if (kcb->kprobe_status & KPROBE_HIT_SS) {
+ resume_execution(cur, regs);
+ reset_current_kprobe();
preempt_enable_no_resched();
}
@@ -733,31 +735,42 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
unsigned long val, void *data)
{
struct die_args *args = (struct die_args *)data;
+ int ret = NOTIFY_DONE;
+
switch(val) {
case DIE_BREAK:
- if (pre_kprobes_handler(args))
- return NOTIFY_STOP;
+ /* err is break number from ia64_bad_break() */
+ if (args->err == 0x80200 || args->err == 0x80300)
+ if (pre_kprobes_handler(args))
+ ret = NOTIFY_STOP;
break;
- case DIE_SS:
- if (post_kprobes_handler(args->regs))
- return NOTIFY_STOP;
+ case DIE_FAULT:
+ /* err is vector number from ia64_fault() */
+ if (args->err == 36)
+ if (post_kprobes_handler(args->regs))
+ ret = NOTIFY_STOP;
break;
case DIE_PAGE_FAULT:
- if (kprobes_fault_handler(args->regs, args->trapnr))
- return NOTIFY_STOP;
+ /* kprobe_running() needs smp_processor_id() */
+ preempt_disable();
+ if (kprobe_running() &&
+ kprobes_fault_handler(args->regs, args->trapnr))
+ ret = NOTIFY_STOP;
+ preempt_enable();
default:
break;
}
- return NOTIFY_DONE;
+ return ret;
}
int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
{
struct jprobe *jp = container_of(p, struct jprobe, kp);
unsigned long addr = ((struct fnptr *)(jp->entry))->ip;
+ struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
/* save architectural state */
- jprobe_saved_regs = *regs;
+ kcb->jprobe_saved_regs = *regs;
/* after rfi, execute the jprobe instrumented function */
regs->cr_iip = addr & ~0xFULL;
@@ -775,7 +788,10 @@ int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
{
- *regs = jprobe_saved_regs;
+ struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
+
+ *regs = kcb->jprobe_saved_regs;
+ preempt_enable_no_resched();
return 1;
}
diff --git a/arch/ia64/kernel/mca.c b/arch/ia64/kernel/mca.c
index d0a5106fba24..355af15287c7 100644
--- a/arch/ia64/kernel/mca.c
+++ b/arch/ia64/kernel/mca.c
@@ -51,6 +51,9 @@
*
* 2005-08-12 Keith Owens <kaos@sgi.com>
* Convert MCA/INIT handlers to use per event stacks and SAL/OS state.
+ *
+ * 2005-10-07 Keith Owens <kaos@sgi.com>
+ * Add notify_die() hooks.
*/
#include <linux/config.h>
#include <linux/types.h>
@@ -58,7 +61,6 @@
#include <linux/sched.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
-#include <linux/kallsyms.h>
#include <linux/smp_lock.h>
#include <linux/bootmem.h>
#include <linux/acpi.h>
@@ -69,6 +71,7 @@
#include <linux/workqueue.h>
#include <asm/delay.h>
+#include <asm/kdebug.h>
#include <asm/machvec.h>
#include <asm/meminit.h>
#include <asm/page.h>
@@ -132,6 +135,14 @@ extern void salinfo_log_wakeup(int type, u8 *buffer, u64 size, int irqsafe);
static int mca_init;
+
+static void inline
+ia64_mca_spin(const char *func)
+{
+ printk(KERN_EMERG "%s: spinning here, not returning to SAL\n", func);
+ while (1)
+ cpu_relax();
+}
/*
* IA64_MCA log support
*/
@@ -508,9 +519,7 @@ ia64_mca_wakeup_all(void)
int cpu;
/* Clear the Rendez checkin flag for all cpus */
- for(cpu = 0; cpu < NR_CPUS; cpu++) {
- if (!cpu_online(cpu))
- continue;
+ for_each_online_cpu(cpu) {
if (ia64_mc_info.imi_rendez_checkin[cpu] == IA64_MCA_RENDEZ_CHECKIN_DONE)
ia64_mca_wakeup(cpu);
}
@@ -528,13 +537,16 @@ ia64_mca_wakeup_all(void)
* Outputs : None
*/
static irqreturn_t
-ia64_mca_rendez_int_handler(int rendez_irq, void *arg, struct pt_regs *ptregs)
+ia64_mca_rendez_int_handler(int rendez_irq, void *arg, struct pt_regs *regs)
{
unsigned long flags;
int cpu = smp_processor_id();
/* Mask all interrupts */
local_irq_save(flags);
+ if (notify_die(DIE_MCA_RENDZVOUS_ENTER, "MCA", regs, 0, 0, 0)
+ == NOTIFY_STOP)
+ ia64_mca_spin(__FUNCTION__);
ia64_mc_info.imi_rendez_checkin[cpu] = IA64_MCA_RENDEZ_CHECKIN_DONE;
/* Register with the SAL monarch that the slave has
@@ -542,10 +554,18 @@ ia64_mca_rendez_int_handler(int rendez_irq, void *arg, struct pt_regs *ptregs)
*/
ia64_sal_mc_rendez();
+ if (notify_die(DIE_MCA_RENDZVOUS_PROCESS, "MCA", regs, 0, 0, 0)
+ == NOTIFY_STOP)
+ ia64_mca_spin(__FUNCTION__);
+
/* Wait for the monarch cpu to exit. */
while (monarch_cpu != -1)
cpu_relax(); /* spin until monarch leaves */
+ if (notify_die(DIE_MCA_RENDZVOUS_LEAVE, "MCA", regs, 0, 0, 0)
+ == NOTIFY_STOP)
+ ia64_mca_spin(__FUNCTION__);
+
/* Enable all interrupts */
local_irq_restore(flags);
return IRQ_HANDLED;
@@ -935,6 +955,9 @@ ia64_mca_handler(struct pt_regs *regs, struct switch_stack *sw,
oops_in_progress = 1; /* FIXME: make printk NMI/MCA/INIT safe */
previous_current = ia64_mca_modify_original_stack(regs, sw, sos, "MCA");
monarch_cpu = cpu;
+ if (notify_die(DIE_MCA_MONARCH_ENTER, "MCA", regs, 0, 0, 0)
+ == NOTIFY_STOP)
+ ia64_mca_spin(__FUNCTION__);
ia64_wait_for_slaves(cpu);
/* Wakeup all the processors which are spinning in the rendezvous loop.
@@ -944,6 +967,9 @@ ia64_mca_handler(struct pt_regs *regs, struct switch_stack *sw,
* spinning in SAL does not work.
*/
ia64_mca_wakeup_all();
+ if (notify_die(DIE_MCA_MONARCH_PROCESS, "MCA", regs, 0, 0, 0)
+ == NOTIFY_STOP)
+ ia64_mca_spin(__FUNCTION__);
/* Get the MCA error record and log it */
ia64_mca_log_sal_error_record(SAL_INFO_TYPE_MCA);
@@ -962,6 +988,9 @@ ia64_mca_handler(struct pt_regs *regs, struct switch_stack *sw,
ia64_sal_clear_state_info(SAL_INFO_TYPE_MCA);
sos->os_status = IA64_MCA_CORRECTED;
}
+ if (notify_die(DIE_MCA_MONARCH_LEAVE, "MCA", regs, 0, 0, recover)
+ == NOTIFY_STOP)
+ ia64_mca_spin(__FUNCTION__);
set_curr_task(cpu, previous_current);
monarch_cpu = -1;
@@ -1190,6 +1219,37 @@ ia64_mca_cpe_poll (unsigned long dummy)
#endif /* CONFIG_ACPI */
+static int
+default_monarch_init_process(struct notifier_block *self, unsigned long val, void *data)
+{
+ int c;
+ struct task_struct *g, *t;
+ if (val != DIE_INIT_MONARCH_PROCESS)
+ return NOTIFY_DONE;
+ printk(KERN_ERR "Processes interrupted by INIT -");
+ for_each_online_cpu(c) {
+ struct ia64_sal_os_state *s;
+ t = __va(__per_cpu_mca[c] + IA64_MCA_CPU_INIT_STACK_OFFSET);
+ s = (struct ia64_sal_os_state *)((char *)t + MCA_SOS_OFFSET);
+ g = s->prev_task;
+ if (g) {
+ if (g->pid)
+ printk(" %d", g->pid);
+ else
+ printk(" %d (cpu %d task 0x%p)", g->pid, task_cpu(g), g);
+ }
+ }
+ printk("\n\n");
+ if (read_trylock(&tasklist_lock)) {
+ do_each_thread (g, t) {
+ printk("\nBacktrace of pid %d (%s)\n", t->pid, t->comm);
+ show_stack(t, NULL);
+ } while_each_thread (g, t);
+ read_unlock(&tasklist_lock);
+ }
+ return NOTIFY_DONE;
+}
+
/*
* C portion of the OS INIT handler
*
@@ -1214,8 +1274,7 @@ ia64_init_handler(struct pt_regs *regs, struct switch_stack *sw,
static atomic_t slaves;
static atomic_t monarchs;
task_t *previous_current;
- int cpu = smp_processor_id(), c;
- struct task_struct *g, *t;
+ int cpu = smp_processor_id();
oops_in_progress = 1; /* FIXME: make printk NMI/MCA/INIT safe */
console_loglevel = 15; /* make sure printks make it to console */
@@ -1255,8 +1314,17 @@ ia64_init_handler(struct pt_regs *regs, struct switch_stack *sw,
ia64_mc_info.imi_rendez_checkin[cpu] = IA64_MCA_RENDEZ_CHECKIN_INIT;
while (monarch_cpu == -1)
cpu_relax(); /* spin until monarch enters */
+ if (notify_die(DIE_INIT_SLAVE_ENTER, "INIT", regs, 0, 0, 0)
+ == NOTIFY_STOP)
+ ia64_mca_spin(__FUNCTION__);
+ if (notify_die(DIE_INIT_SLAVE_PROCESS, "INIT", regs, 0, 0, 0)
+ == NOTIFY_STOP)
+ ia64_mca_spin(__FUNCTION__);
while (monarch_cpu != -1)
cpu_relax(); /* spin until monarch leaves */
+ if (notify_die(DIE_INIT_SLAVE_LEAVE, "INIT", regs, 0, 0, 0)
+ == NOTIFY_STOP)
+ ia64_mca_spin(__FUNCTION__);
printk("Slave on cpu %d returning to normal service.\n", cpu);
set_curr_task(cpu, previous_current);
ia64_mc_info.imi_rendez_checkin[cpu] = IA64_MCA_RENDEZ_CHECKIN_NOTDONE;
@@ -1265,6 +1333,9 @@ ia64_init_handler(struct pt_regs *regs, struct switch_stack *sw,
}
monarch_cpu = cpu;
+ if (notify_die(DIE_INIT_MONARCH_ENTER, "INIT", regs, 0, 0, 0)
+ == NOTIFY_STOP)
+ ia64_mca_spin(__FUNCTION__);
/*
* Wait for a bit. On some machines (e.g., HP's zx2000 and zx6000, INIT can be
@@ -1275,27 +1346,16 @@ ia64_init_handler(struct pt_regs *regs, struct switch_stack *sw,
printk("Delaying for 5 seconds...\n");
udelay(5*1000000);
ia64_wait_for_slaves(cpu);
- printk(KERN_ERR "Processes interrupted by INIT -");
- for_each_online_cpu(c) {
- struct ia64_sal_os_state *s;
- t = __va(__per_cpu_mca[c] + IA64_MCA_CPU_INIT_STACK_OFFSET);
- s = (struct ia64_sal_os_state *)((char *)t + MCA_SOS_OFFSET);
- g = s->prev_task;
- if (g) {
- if (g->pid)
- printk(" %d", g->pid);
- else
- printk(" %d (cpu %d task 0x%p)", g->pid, task_cpu(g), g);
- }
- }
- printk("\n\n");
- if (read_trylock(&tasklist_lock)) {
- do_each_thread (g, t) {
- printk("\nBacktrace of pid %d (%s)\n", t->pid, t->comm);
- show_stack(t, NULL);
- } while_each_thread (g, t);
- read_unlock(&tasklist_lock);
- }
+ /* If nobody intercepts DIE_INIT_MONARCH_PROCESS then we drop through
+ * to default_monarch_init_process() above and just print all the
+ * tasks.
+ */
+ if (notify_die(DIE_INIT_MONARCH_PROCESS, "INIT", regs, 0, 0, 0)
+ == NOTIFY_STOP)
+ ia64_mca_spin(__FUNCTION__);
+ if (notify_die(DIE_INIT_MONARCH_LEAVE, "INIT", regs, 0, 0, 0)
+ == NOTIFY_STOP)
+ ia64_mca_spin(__FUNCTION__);
printk("\nINIT dump complete. Monarch on cpu %d returning to normal service.\n", cpu);
atomic_dec(&monarchs);
set_curr_task(cpu, previous_current);
@@ -1464,6 +1524,10 @@ ia64_mca_init(void)
s64 rc;
struct ia64_sal_retval isrv;
u64 timeout = IA64_MCA_RENDEZ_TIMEOUT; /* platform specific */
+ static struct notifier_block default_init_monarch_nb = {
+ .notifier_call = default_monarch_init_process,
+ .priority = 0/* we need to notified last */
+ };
IA64_MCA_DEBUG("%s: begin\n", __FUNCTION__);
@@ -1557,6 +1621,10 @@ ia64_mca_init(void)
"(status %ld)\n", rc);
return;
}
+ if (register_die_notifier(&default_init_monarch_nb)) {
+ printk(KERN_ERR "Failed to register default monarch INIT process\n");
+ return;
+ }
IA64_MCA_DEBUG("%s: registered OS INIT handler with SAL\n", __FUNCTION__);
diff --git a/arch/ia64/kernel/mca_drv.c b/arch/ia64/kernel/mca_drv.c
index f081c60ab206..3492e3211a44 100644
--- a/arch/ia64/kernel/mca_drv.c
+++ b/arch/ia64/kernel/mca_drv.c
@@ -88,7 +88,7 @@ mca_page_isolate(unsigned long paddr)
if (!ia64_phys_addr_valid(paddr))
return ISOLATE_NONE;
- if (!pfn_valid(paddr))
+ if (!pfn_valid(paddr >> PAGE_SHIFT))
return ISOLATE_NONE;
/* convert physical address to physical page number */
@@ -108,6 +108,7 @@ mca_page_isolate(unsigned long paddr)
return ISOLATE_NG;
/* add attribute 'Reserved' and register the page */
+ get_page(p);
SetPageReserved(p);
page_isolate[num_page_isolate++] = p;
@@ -546,9 +547,20 @@ recover_from_processor_error(int platform, slidx_table_t *slidx,
(pal_processor_state_info_t*)peidx_psp(peidx);
/*
- * We cannot recover errors with other than bus_check.
+ * Processor recovery status must key off of the PAL recovery
+ * status in the Processor State Parameter.
*/
- if (psp->cc || psp->rc || psp->uc)
+
+ /*
+ * The machine check is corrected.
+ */
+ if (psp->cm == 1)
+ return 1;
+
+ /*
+ * The error was not contained. Software must be reset.
+ */
+ if (psp->us || psp->ci == 0)
return 0;
/*
@@ -569,8 +581,6 @@ recover_from_processor_error(int platform, slidx_table_t *slidx,
return 0;
if (pbci->eb && pbci->bsi > 0)
return 0;
- if (psp->ci == 0)
- return 0;
/*
* This is a local MCA and estimated as recoverble external bus error.
diff --git a/arch/ia64/kernel/module.c b/arch/ia64/kernel/module.c
index f1aca7cffd12..7a2f0a798d12 100644
--- a/arch/ia64/kernel/module.c
+++ b/arch/ia64/kernel/module.c
@@ -947,8 +947,8 @@ void
percpu_modcopy (void *pcpudst, const void *src, unsigned long size)
{
unsigned int i;
- for (i = 0; i < NR_CPUS; i++)
- if (cpu_possible(i))
- memcpy(pcpudst + __per_cpu_offset[i], src, size);
+ for_each_cpu(i) {
+ memcpy(pcpudst + __per_cpu_offset[i], src, size);
+ }
}
#endif /* CONFIG_SMP */
diff --git a/arch/ia64/kernel/patch.c b/arch/ia64/kernel/patch.c
index 367804a605fa..6a4ac7d70b35 100644
--- a/arch/ia64/kernel/patch.c
+++ b/arch/ia64/kernel/patch.c
@@ -64,22 +64,30 @@ ia64_patch (u64 insn_addr, u64 mask, u64 val)
void
ia64_patch_imm64 (u64 insn_addr, u64 val)
{
- ia64_patch(insn_addr,
+ /* The assembler may generate offset pointing to either slot 1
+ or slot 2 for a long (2-slot) instruction, occupying slots 1
+ and 2. */
+ insn_addr &= -16UL;
+ ia64_patch(insn_addr + 2,
0x01fffefe000UL, ( ((val & 0x8000000000000000UL) >> 27) /* bit 63 -> 36 */
| ((val & 0x0000000000200000UL) << 0) /* bit 21 -> 21 */
| ((val & 0x00000000001f0000UL) << 6) /* bit 16 -> 22 */
| ((val & 0x000000000000ff80UL) << 20) /* bit 7 -> 27 */
| ((val & 0x000000000000007fUL) << 13) /* bit 0 -> 13 */));
- ia64_patch(insn_addr - 1, 0x1ffffffffffUL, val >> 22);
+ ia64_patch(insn_addr + 1, 0x1ffffffffffUL, val >> 22);
}
void
ia64_patch_imm60 (u64 insn_addr, u64 val)
{
- ia64_patch(insn_addr,
+ /* The assembler may generate offset pointing to either slot 1
+ or slot 2 for a long (2-slot) instruction, occupying slots 1
+ and 2. */
+ insn_addr &= -16UL;
+ ia64_patch(insn_addr + 2,
0x011ffffe000UL, ( ((val & 0x0800000000000000UL) >> 23) /* bit 59 -> 36 */
| ((val & 0x00000000000fffffUL) << 13) /* bit 0 -> 13 */));
- ia64_patch(insn_addr - 1, 0x1fffffffffcUL, val >> 18);
+ ia64_patch(insn_addr + 1, 0x1fffffffffcUL, val >> 18);
}
/*
diff --git a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c
index d71731ee5b61..410d4804fa6e 100644
--- a/arch/ia64/kernel/perfmon.c
+++ b/arch/ia64/kernel/perfmon.c
@@ -2352,7 +2352,8 @@ pfm_smpl_buffer_alloc(struct task_struct *task, pfm_context_t *ctx, unsigned lon
insert_vm_struct(mm, vma);
mm->total_vm += size >> PAGE_SHIFT;
- vm_stat_account(vma);
+ vm_stat_account(vma->vm_mm, vma->vm_flags, vma->vm_file,
+ vma_pages(vma));
up_write(&task->mm->mmap_sem);
/*
@@ -4939,7 +4940,7 @@ abort_locked:
if (call_made && PFM_CMD_RW_ARG(cmd) && copy_to_user(arg, args_k, base_sz*count)) ret = -EFAULT;
error_args:
- if (args_k) kfree(args_k);
+ kfree(args_k);
DPRINT(("cmd=%s ret=%ld\n", PFM_CMD_NAME(cmd), ret));
diff --git a/arch/ia64/kernel/process.c b/arch/ia64/kernel/process.c
index 051e050359e4..e92ea64d8040 100644
--- a/arch/ia64/kernel/process.c
+++ b/arch/ia64/kernel/process.c
@@ -4,6 +4,9 @@
* Copyright (C) 1998-2003 Hewlett-Packard Co
* David Mosberger-Tang <davidm@hpl.hp.com>
* 04/11/17 Ashok Raj <ashok.raj@intel.com> Added CPU Hotplug Support
+ *
+ * 2005-10-07 Keith Owens <kaos@sgi.com>
+ * Add notify_die() hooks.
*/
#define __KERNEL_SYSCALLS__ /* see <asm/unistd.h> */
#include <linux/config.h>
@@ -34,6 +37,7 @@
#include <asm/elf.h>
#include <asm/ia32.h>
#include <asm/irq.h>
+#include <asm/kdebug.h>
#include <asm/pgalloc.h>
#include <asm/processor.h>
#include <asm/sal.h>
@@ -197,11 +201,15 @@ void
default_idle (void)
{
local_irq_enable();
- while (!need_resched())
- if (can_do_pal_halt)
- safe_halt();
- else
+ while (!need_resched()) {
+ if (can_do_pal_halt) {
+ local_irq_disable();
+ if (!need_resched())
+ safe_halt();
+ local_irq_enable();
+ } else
cpu_relax();
+ }
}
#ifdef CONFIG_HOTPLUG_CPU
@@ -263,16 +271,16 @@ void __attribute__((noreturn))
cpu_idle (void)
{
void (*mark_idle)(int) = ia64_mark_idle;
+ int cpu = smp_processor_id();
+ set_thread_flag(TIF_POLLING_NRFLAG);
/* endless idle loop with no priority at all */
while (1) {
+ if (!need_resched()) {
+ void (*idle)(void);
#ifdef CONFIG_SMP
- if (!need_resched())
min_xtp();
#endif
- while (!need_resched()) {
- void (*idle)(void);
-
if (__get_cpu_var(cpu_idle_state))
__get_cpu_var(cpu_idle_state) = 0;
@@ -284,17 +292,17 @@ cpu_idle (void)
if (!idle)
idle = default_idle;
(*idle)();
- }
-
- if (mark_idle)
- (*mark_idle)(0);
-
+ if (mark_idle)
+ (*mark_idle)(0);
#ifdef CONFIG_SMP
- normal_xtp();
+ normal_xtp();
#endif
+ }
+ preempt_enable_no_resched();
schedule();
+ preempt_disable();
check_pgt_cache();
- if (cpu_is_offline(smp_processor_id()))
+ if (cpu_is_offline(cpu))
play_dead();
}
}
@@ -804,12 +812,14 @@ cpu_halt (void)
void
machine_restart (char *restart_cmd)
{
+ (void) notify_die(DIE_MACHINE_RESTART, restart_cmd, NULL, 0, 0, 0);
(*efi.reset_system)(EFI_RESET_WARM, 0, 0, NULL);
}
void
machine_halt (void)
{
+ (void) notify_die(DIE_MACHINE_HALT, "", NULL, 0, 0, 0);
cpu_halt();
}
diff --git a/arch/ia64/kernel/ptrace.c b/arch/ia64/kernel/ptrace.c
index bbb8bc7c0552..4b19d0410632 100644
--- a/arch/ia64/kernel/ptrace.c
+++ b/arch/ia64/kernel/ptrace.c
@@ -587,8 +587,9 @@ thread_matches (struct task_struct *thread, unsigned long addr)
static struct task_struct *
find_thread_for_addr (struct task_struct *child, unsigned long addr)
{
- struct task_struct *g, *p;
+ struct task_struct *p;
struct mm_struct *mm;
+ struct list_head *this, *next;
int mm_users;
if (!(mm = get_task_mm(child)))
@@ -600,28 +601,21 @@ find_thread_for_addr (struct task_struct *child, unsigned long addr)
goto out; /* not multi-threaded */
/*
- * First, traverse the child's thread-list. Good for scalability with
- * NPTL-threads.
+ * Traverse the current process' children list. Every task that
+ * one attaches to becomes a child. And it is only attached children
+ * of the debugger that are of interest (ptrace_check_attach checks
+ * for this).
*/
- p = child;
- do {
- if (thread_matches(p, addr)) {
- child = p;
- goto out;
- }
- if (mm_users-- <= 1)
- goto out;
- } while ((p = next_thread(p)) != child);
-
- do_each_thread(g, p) {
- if (child->mm != mm)
+ list_for_each_safe(this, next, &current->children) {
+ p = list_entry(this, struct task_struct, sibling);
+ if (p->mm != mm)
continue;
-
if (thread_matches(p, addr)) {
child = p;
goto out;
}
- } while_each_thread(g, p);
+ }
+
out:
mmput(mm);
return child;
diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c
index 1f5c26dbe705..5add0bcf87a7 100644
--- a/arch/ia64/kernel/setup.c
+++ b/arch/ia64/kernel/setup.c
@@ -78,7 +78,27 @@ struct screen_info screen_info;
unsigned long vga_console_iobase;
unsigned long vga_console_membase;
+static struct resource data_resource = {
+ .name = "Kernel data",
+ .flags = IORESOURCE_BUSY | IORESOURCE_MEM
+};
+
+static struct resource code_resource = {
+ .name = "Kernel code",
+ .flags = IORESOURCE_BUSY | IORESOURCE_MEM
+};
+extern void efi_initialize_iomem_resources(struct resource *,
+ struct resource *);
+extern char _text[], _end[], _etext[];
+
unsigned long ia64_max_cacheline_size;
+
+int dma_get_cache_alignment(void)
+{
+ return ia64_max_cacheline_size;
+}
+EXPORT_SYMBOL(dma_get_cache_alignment);
+
unsigned long ia64_iobase; /* virtual address for I/O accesses */
EXPORT_SYMBOL(ia64_iobase);
struct io_space io_space[MAX_IO_SPACES];
@@ -171,6 +191,22 @@ sort_regions (struct rsvd_region *rsvd_region, int max)
}
}
+/*
+ * Request address space for all standard resources
+ */
+static int __init register_memory(void)
+{
+ code_resource.start = ia64_tpa(_text);
+ code_resource.end = ia64_tpa(_etext) - 1;
+ data_resource.start = ia64_tpa(_etext);
+ data_resource.end = ia64_tpa(_end) - 1;
+ efi_initialize_iomem_resources(&code_resource, &data_resource);
+
+ return 0;
+}
+
+__initcall(register_memory);
+
/**
* reserve_memory - setup reserved memory areas
*
@@ -211,6 +247,9 @@ reserve_memory (void)
}
#endif
+ efi_memmap_init(&rsvd_region[n].start, &rsvd_region[n].end);
+ n++;
+
/* end of memory marker */
rsvd_region[n].start = ~0UL;
rsvd_region[n].end = ~0UL;
@@ -244,28 +283,31 @@ find_initrd (void)
static void __init
io_port_init (void)
{
- extern unsigned long ia64_iobase;
unsigned long phys_iobase;
/*
- * Set `iobase' to the appropriate address in region 6 (uncached access range).
+ * Set `iobase' based on the EFI memory map or, failing that, the
+ * value firmware left in ar.k0.
*
- * The EFI memory map is the "preferred" location to get the I/O port space base,
- * rather the relying on AR.KR0. This should become more clear in future SAL
- * specs. We'll fall back to getting it out of AR.KR0 if no appropriate entry is
- * found in the memory map.
+ * Note that in ia32 mode, IN/OUT instructions use ar.k0 to compute
+ * the port's virtual address, so ia32_load_state() loads it with a
+ * user virtual address. But in ia64 mode, glibc uses the
+ * *physical* address in ar.k0 to mmap the appropriate area from
+ * /dev/mem, and the inX()/outX() interfaces use MMIO. In both
+ * cases, user-mode can only use the legacy 0-64K I/O port space.
+ *
+ * ar.k0 is not involved in kernel I/O port accesses, which can use
+ * any of the I/O port spaces and are done via MMIO using the
+ * virtual mmio_base from the appropriate io_space[].
*/
phys_iobase = efi_get_iobase();
- if (phys_iobase)
- /* set AR.KR0 since this is all we use it for anyway */
- ia64_set_kr(IA64_KR_IO_BASE, phys_iobase);
- else {
+ if (!phys_iobase) {
phys_iobase = ia64_get_kr(IA64_KR_IO_BASE);
- printk(KERN_INFO "No I/O port range found in EFI memory map, falling back "
- "to AR.KR0\n");
- printk(KERN_INFO "I/O port base = 0x%lx\n", phys_iobase);
+ printk(KERN_INFO "No I/O port range found in EFI memory map, "
+ "falling back to AR.KR0 (0x%lx)\n", phys_iobase);
}
ia64_iobase = (unsigned long) ioremap(phys_iobase, 0);
+ ia64_set_kr(IA64_KR_IO_BASE, __pa(ia64_iobase));
/* setup legacy IO port space */
io_space[0].mmio_base = ia64_iobase;
@@ -419,6 +461,7 @@ setup_arch (char **cmdline_p)
#endif
cpu_init(); /* initialize the bootstrap CPU */
+ mmu_context_init(); /* initialize context_id bitmap */
#ifdef CONFIG_ACPI
acpi_boot_init();
@@ -526,7 +569,7 @@ show_cpuinfo (struct seq_file *m, void *v)
c->itc_freq / 1000000, c->itc_freq % 1000000,
lpj*HZ/500000, (lpj*HZ/5000) % 100);
#ifdef CONFIG_SMP
- seq_printf(m, "siblings : %u\n", c->num_log);
+ seq_printf(m, "siblings : %u\n", cpus_weight(cpu_core_map[cpunum]));
if (c->threads_per_core > 1 || c->cores_per_socket > 1)
seq_printf(m,
"physical id: %u\n"
diff --git a/arch/ia64/kernel/signal.c b/arch/ia64/kernel/signal.c
index 774f34b675cf..58ce07efc56e 100644
--- a/arch/ia64/kernel/signal.c
+++ b/arch/ia64/kernel/signal.c
@@ -387,15 +387,14 @@ setup_frame (int sig, struct k_sigaction *ka, siginfo_t *info, sigset_t *set,
struct sigscratch *scr)
{
extern char __kernel_sigtramp[];
- unsigned long tramp_addr, new_rbs = 0;
+ unsigned long tramp_addr, new_rbs = 0, new_sp;
struct sigframe __user *frame;
long err;
- frame = (void __user *) scr->pt.r12;
+ new_sp = scr->pt.r12;
tramp_addr = (unsigned long) __kernel_sigtramp;
- if ((ka->sa.sa_flags & SA_ONSTACK) && sas_ss_flags((unsigned long) frame) == 0) {
- frame = (void __user *) ((current->sas_ss_sp + current->sas_ss_size)
- & ~(STACK_ALIGN - 1));
+ if ((ka->sa.sa_flags & SA_ONSTACK) && sas_ss_flags(new_sp) == 0) {
+ new_sp = current->sas_ss_sp + current->sas_ss_size;
/*
* We need to check for the register stack being on the signal stack
* separately, because it's switched separately (memory stack is switched
@@ -404,7 +403,7 @@ setup_frame (int sig, struct k_sigaction *ka, siginfo_t *info, sigset_t *set,
if (!rbs_on_sig_stack(scr->pt.ar_bspstore))
new_rbs = (current->sas_ss_sp + sizeof(long) - 1) & ~(sizeof(long) - 1);
}
- frame = (void __user *) frame - ((sizeof(*frame) + STACK_ALIGN - 1) & ~(STACK_ALIGN - 1));
+ frame = (void __user *) ((new_sp - sizeof(*frame)) & -STACK_ALIGN);
if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
return force_sigsegv_info(sig, frame);
diff --git a/arch/ia64/kernel/smp.c b/arch/ia64/kernel/smp.c
index 0166a9847095..657ac99a451c 100644
--- a/arch/ia64/kernel/smp.c
+++ b/arch/ia64/kernel/smp.c
@@ -185,8 +185,8 @@ send_IPI_allbutself (int op)
{
unsigned int i;
- for (i = 0; i < NR_CPUS; i++) {
- if (cpu_online(i) && i != smp_processor_id())
+ for_each_online_cpu(i) {
+ if (i != smp_processor_id())
send_IPI_single(i, op);
}
}
@@ -199,9 +199,9 @@ send_IPI_all (int op)
{
int i;
- for (i = 0; i < NR_CPUS; i++)
- if (cpu_online(i))
- send_IPI_single(i, op);
+ for_each_online_cpu(i) {
+ send_IPI_single(i, op);
+ }
}
/*
diff --git a/arch/ia64/kernel/smpboot.c b/arch/ia64/kernel/smpboot.c
index 7d72c0d872b3..8f44e7d2df66 100644
--- a/arch/ia64/kernel/smpboot.c
+++ b/arch/ia64/kernel/smpboot.c
@@ -399,6 +399,7 @@ start_secondary (void *unused)
Dprintk("start_secondary: starting CPU 0x%x\n", hard_smp_processor_id());
efi_map_pal_code();
cpu_init();
+ preempt_disable();
smp_callin();
cpu_idle();
@@ -694,9 +695,9 @@ smp_cpus_done (unsigned int dummy)
* Allow the user to impress friends.
*/
- for (cpu = 0; cpu < NR_CPUS; cpu++)
- if (cpu_online(cpu))
- bogosum += cpu_data(cpu)->loops_per_jiffy;
+ for_each_online_cpu(cpu) {
+ bogosum += cpu_data(cpu)->loops_per_jiffy;
+ }
printk(KERN_INFO "Total of %d processors activated (%lu.%02lu BogoMIPS).\n",
(int)num_online_cpus(), bogosum/(500000/HZ), (bogosum/(5000/HZ))%100);
diff --git a/arch/ia64/kernel/time.c b/arch/ia64/kernel/time.c
index 8b8a5a45b621..5b7e736f3b49 100644
--- a/arch/ia64/kernel/time.c
+++ b/arch/ia64/kernel/time.c
@@ -32,10 +32,6 @@
extern unsigned long wall_jiffies;
-u64 jiffies_64 __cacheline_aligned_in_smp = INITIAL_JIFFIES;
-
-EXPORT_SYMBOL(jiffies_64);
-
#define TIME_KEEPER_ID 0 /* smp_processor_id() of time-keeper */
#ifdef CONFIG_IA64_DEBUG_IRQ
diff --git a/arch/ia64/kernel/traps.c b/arch/ia64/kernel/traps.c
index f970359e7edf..fba5fdd1f968 100644
--- a/arch/ia64/kernel/traps.c
+++ b/arch/ia64/kernel/traps.c
@@ -30,17 +30,20 @@ fpswa_interface_t *fpswa_interface;
EXPORT_SYMBOL(fpswa_interface);
struct notifier_block *ia64die_chain;
-static DEFINE_SPINLOCK(die_notifier_lock);
-int register_die_notifier(struct notifier_block *nb)
+int
+register_die_notifier(struct notifier_block *nb)
{
- int err = 0;
- unsigned long flags;
- spin_lock_irqsave(&die_notifier_lock, flags);
- err = notifier_chain_register(&ia64die_chain, nb);
- spin_unlock_irqrestore(&die_notifier_lock, flags);
- return err;
+ return notifier_chain_register(&ia64die_chain, nb);
}
+EXPORT_SYMBOL_GPL(register_die_notifier);
+
+int
+unregister_die_notifier(struct notifier_block *nb)
+{
+ return notifier_chain_unregister(&ia64die_chain, nb);
+}
+EXPORT_SYMBOL_GPL(unregister_die_notifier);
void __init
trap_init (void)
@@ -105,6 +108,7 @@ die (const char *str, struct pt_regs *regs, long err)
if (++die.lock_owner_depth < 3) {
printk("%s[%d]: %s %ld [%d]\n",
current->comm, current->pid, str, err, ++die_counter);
+ (void) notify_die(DIE_OOPS, (char *)str, regs, err, 255, SIGSEGV);
show_regs(regs);
} else
printk(KERN_ERR "Recursive die() failure, output suppressed\n");
@@ -155,9 +159,8 @@ __kprobes ia64_bad_break (unsigned long break_num, struct pt_regs *regs)
switch (break_num) {
case 0: /* unknown error (used by GCC for __builtin_abort()) */
if (notify_die(DIE_BREAK, "break 0", regs, break_num, TRAP_BRKPT, SIGTRAP)
- == NOTIFY_STOP) {
+ == NOTIFY_STOP)
return;
- }
die_if_kernel("bugcheck!", regs, break_num);
sig = SIGILL; code = ILL_ILLOPC;
break;
@@ -210,15 +213,6 @@ __kprobes ia64_bad_break (unsigned long break_num, struct pt_regs *regs)
sig = SIGILL; code = __ILL_BNDMOD;
break;
- case 0x80200:
- case 0x80300:
- if (notify_die(DIE_BREAK, "kprobe", regs, break_num, TRAP_BRKPT, SIGTRAP)
- == NOTIFY_STOP) {
- return;
- }
- sig = SIGTRAP; code = TRAP_BRKPT;
- break;
-
default:
if (break_num < 0x40000 || break_num > 0x100000)
die_if_kernel("Bad break", regs, break_num);
@@ -226,6 +220,9 @@ __kprobes ia64_bad_break (unsigned long break_num, struct pt_regs *regs)
if (break_num < 0x80000) {
sig = SIGILL; code = __ILL_BREAK;
} else {
+ if (notify_die(DIE_BREAK, "bad break", regs, break_num, TRAP_BRKPT, SIGTRAP)
+ == NOTIFY_STOP)
+ return;
sig = SIGTRAP; code = TRAP_BRKPT;
}
}
@@ -578,12 +575,11 @@ ia64_fault (unsigned long vector, unsigned long isr, unsigned long ifa,
#endif
break;
case 35: siginfo.si_code = TRAP_BRANCH; ifa = 0; break;
- case 36:
- if (notify_die(DIE_SS, "ss", &regs, vector,
- vector, SIGTRAP) == NOTIFY_STOP)
- return;
- siginfo.si_code = TRAP_TRACE; ifa = 0; break;
+ case 36: siginfo.si_code = TRAP_TRACE; ifa = 0; break;
}
+ if (notify_die(DIE_FAULT, "ia64_fault", &regs, vector, siginfo.si_code, SIGTRAP)
+ == NOTIFY_STOP)
+ return;
siginfo.si_signo = SIGTRAP;
siginfo.si_errno = 0;
siginfo.si_addr = (void __user *) ifa;
diff --git a/arch/ia64/kernel/uncached.c b/arch/ia64/kernel/uncached.c
index 4e9d06c48a8b..c6d40446c2c4 100644
--- a/arch/ia64/kernel/uncached.c
+++ b/arch/ia64/kernel/uncached.c
@@ -205,23 +205,18 @@ EXPORT_SYMBOL(uncached_free_page);
static int __init
uncached_build_memmap(unsigned long start, unsigned long end, void *arg)
{
- long length;
- unsigned long vstart, vend;
+ long length = end - start;
int node;
- length = end - start;
- vstart = start + __IA64_UNCACHED_OFFSET;
- vend = end + __IA64_UNCACHED_OFFSET;
-
dprintk(KERN_ERR "uncached_build_memmap(%lx %lx)\n", start, end);
- memset((char *)vstart, 0, length);
+ memset((char *)start, 0, length);
- node = paddr_to_nid(start);
+ node = paddr_to_nid(start - __IA64_UNCACHED_OFFSET);
- for (; vstart < vend ; vstart += PAGE_SIZE) {
- dprintk(KERN_INFO "sticking %lx into the pool!\n", vstart);
- gen_pool_free(uncached_pool[node], vstart, PAGE_SIZE);
+ for (; start < end ; start += PAGE_SIZE) {
+ dprintk(KERN_INFO "sticking %lx into the pool!\n", start);
+ gen_pool_free(uncached_pool[node], start, PAGE_SIZE);
}
return 0;
diff --git a/arch/ia64/lib/Makefile b/arch/ia64/lib/Makefile
index cb1af597370b..ac64664a1807 100644
--- a/arch/ia64/lib/Makefile
+++ b/arch/ia64/lib/Makefile
@@ -9,7 +9,7 @@ lib-y := __divsi3.o __udivsi3.o __modsi3.o __umodsi3.o \
bitop.o checksum.o clear_page.o csum_partial_copy.o \
clear_user.o strncpy_from_user.o strlen_user.o strnlen_user.o \
flush.o ip_fast_csum.o do_csum.o \
- memset.o strlen.o swiotlb.o
+ memset.o strlen.o
lib-$(CONFIG_ITANIUM) += copy_page.o copy_user.o memcpy.o
lib-$(CONFIG_MCKINLEY) += copy_page_mck.o memcpy_mck.o
diff --git a/arch/ia64/mm/Makefile b/arch/ia64/mm/Makefile
index 7078f67887ec..d78d20f0a0f0 100644
--- a/arch/ia64/mm/Makefile
+++ b/arch/ia64/mm/Makefile
@@ -7,6 +7,5 @@ obj-y := init.o fault.o tlb.o extable.o
obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
obj-$(CONFIG_NUMA) += numa.o
obj-$(CONFIG_DISCONTIGMEM) += discontig.o
-ifndef CONFIG_DISCONTIGMEM
-obj-y += contig.o
-endif
+obj-$(CONFIG_SPARSEMEM) += discontig.o
+obj-$(CONFIG_FLATMEM) += contig.o
diff --git a/arch/ia64/mm/contig.c b/arch/ia64/mm/contig.c
index 91a055f5731f..acaaec4e4681 100644
--- a/arch/ia64/mm/contig.c
+++ b/arch/ia64/mm/contig.c
@@ -269,7 +269,7 @@ paging_init (void)
efi_memmap_walk(find_largest_hole, (u64 *)&max_gap);
if (max_gap < LARGE_GAP) {
vmem_map = (struct page *) 0;
- free_area_init_node(0, &contig_page_data, zones_size, 0,
+ free_area_init_node(0, NODE_DATA(0), zones_size, 0,
zholes_size);
} else {
unsigned long map_size;
@@ -282,7 +282,7 @@ paging_init (void)
efi_memmap_walk(create_mem_map_page_table, NULL);
NODE_DATA(0)->node_mem_map = vmem_map;
- free_area_init_node(0, &contig_page_data, zones_size,
+ free_area_init_node(0, NODE_DATA(0), zones_size,
0, zholes_size);
printk("Virtual mem_map starts at 0x%p\n", mem_map);
diff --git a/arch/ia64/mm/discontig.c b/arch/ia64/mm/discontig.c
index b5c90e548195..0f776b032d31 100644
--- a/arch/ia64/mm/discontig.c
+++ b/arch/ia64/mm/discontig.c
@@ -350,14 +350,12 @@ static void __init initialize_pernode_data(void)
* for best.
* @nid: node id
* @pernodesize: size of this node's pernode data
- * @align: alignment to use for this node's pernode data
*/
-static void __init *memory_less_node_alloc(int nid, unsigned long pernodesize,
- unsigned long align)
+static void __init *memory_less_node_alloc(int nid, unsigned long pernodesize)
{
void *ptr = NULL;
u8 best = 0xff;
- int bestnode = -1, node;
+ int bestnode = -1, node, anynode = 0;
for_each_online_node(node) {
if (node_isset(node, memory_less_mask))
@@ -366,13 +364,15 @@ static void __init *memory_less_node_alloc(int nid, unsigned long pernodesize,
best = node_distance(nid, node);
bestnode = node;
}
+ anynode = node;
}
- ptr = __alloc_bootmem_node(mem_data[bestnode].pgdat,
- pernodesize, align, __pa(MAX_DMA_ADDRESS));
+ if (bestnode == -1)
+ bestnode = anynode;
+
+ ptr = __alloc_bootmem_node(mem_data[bestnode].pgdat, pernodesize,
+ PERCPU_PAGE_SIZE, __pa(MAX_DMA_ADDRESS));
- if (!ptr)
- panic("NO memory for memory less node\n");
return ptr;
}
@@ -413,14 +413,44 @@ static void __init memory_less_nodes(void)
for_each_node_mask(node, memory_less_mask) {
pernodesize = compute_pernodesize(node);
- pernode = memory_less_node_alloc(node, pernodesize,
- (node) ? (node * PERCPU_PAGE_SIZE) : (1024*1024));
+ pernode = memory_less_node_alloc(node, pernodesize);
fill_pernode(node, __pa(pernode), pernodesize);
}
return;
}
+#ifdef CONFIG_SPARSEMEM
+/**
+ * register_sparse_mem - notify SPARSEMEM that this memory range exists.
+ * @start: physical start of range
+ * @end: physical end of range
+ * @arg: unused
+ *
+ * Simply calls SPARSEMEM to register memory section(s).
+ */
+static int __init register_sparse_mem(unsigned long start, unsigned long end,
+ void *arg)
+{
+ int nid;
+
+ start = __pa(start) >> PAGE_SHIFT;
+ end = __pa(end) >> PAGE_SHIFT;
+ nid = early_pfn_to_nid(start);
+ memory_present(nid, start, end);
+
+ return 0;
+}
+
+static void __init arch_sparse_init(void)
+{
+ efi_memmap_walk(register_sparse_mem, NULL);
+ sparse_init();
+}
+#else
+#define arch_sparse_init() do {} while (0)
+#endif
+
/**
* find_memory - walk the EFI memory map and setup the bootmem allocator
*
@@ -524,12 +554,18 @@ void show_mem(void)
show_free_areas();
printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10));
for_each_pgdat(pgdat) {
- unsigned long present = pgdat->node_present_pages;
+ unsigned long present;
+ unsigned long flags;
int shared = 0, cached = 0, reserved = 0;
+
printk("Node ID: %d\n", pgdat->node_id);
+ pgdat_resize_lock(pgdat, &flags);
+ present = pgdat->node_present_pages;
for(i = 0; i < pgdat->node_spanned_pages; i++) {
- struct page *page = pgdat_page_nr(pgdat, i);
- if (!ia64_pfn_valid(pgdat->node_start_pfn+i))
+ struct page *page;
+ if (pfn_valid(pgdat->node_start_pfn + i))
+ page = pfn_to_page(pgdat->node_start_pfn + i);
+ else
continue;
if (PageReserved(page))
reserved++;
@@ -538,6 +574,7 @@ void show_mem(void)
else if (page_count(page))
shared += page_count(page)-1;
}
+ pgdat_resize_unlock(pgdat, &flags);
total_present += present;
total_reserved += reserved;
total_cached += cached;
@@ -648,12 +685,16 @@ void __init paging_init(void)
max_dma = virt_to_phys((void *) MAX_DMA_ADDRESS) >> PAGE_SHIFT;
+ arch_sparse_init();
+
efi_memmap_walk(filter_rsvd_memory, count_node_pages);
+#ifdef CONFIG_VIRTUAL_MEM_MAP
vmalloc_end -= PAGE_ALIGN(max_low_pfn * sizeof(struct page));
vmem_map = (struct page *) vmalloc_end;
efi_memmap_walk(create_mem_map_page_table, NULL);
printk("Virtual mem_map starts at 0x%p\n", vmem_map);
+#endif
for_each_online_node(node) {
memset(zones_size, 0, sizeof(zones_size));
@@ -690,7 +731,9 @@ void __init paging_init(void)
pfn_offset = mem_data[node].min_pfn;
+#ifdef CONFIG_VIRTUAL_MEM_MAP
NODE_DATA(node)->node_mem_map = vmem_map + pfn_offset;
+#endif
free_area_init_node(node, NODE_DATA(node), zones_size,
pfn_offset, zholes_size);
}
diff --git a/arch/ia64/mm/fault.c b/arch/ia64/mm/fault.c
index 3c32af910d60..af7eb087dca7 100644
--- a/arch/ia64/mm/fault.c
+++ b/arch/ia64/mm/fault.c
@@ -20,32 +20,6 @@
extern void die (char *, struct pt_regs *, long);
/*
- * This routine is analogous to expand_stack() but instead grows the
- * register backing store (which grows towards higher addresses).
- * Since the register backing store is access sequentially, we
- * disallow growing the RBS by more than a page at a time. Note that
- * the VM_GROWSUP flag can be set on any VM area but that's fine
- * because the total process size is still limited by RLIMIT_STACK and
- * RLIMIT_AS.
- */
-static inline long
-expand_backing_store (struct vm_area_struct *vma, unsigned long address)
-{
- unsigned long grow;
-
- grow = PAGE_SIZE >> PAGE_SHIFT;
- if (address - vma->vm_start > current->signal->rlim[RLIMIT_STACK].rlim_cur
- || (((vma->vm_mm->total_vm + grow) << PAGE_SHIFT) > current->signal->rlim[RLIMIT_AS].rlim_cur))
- return -ENOMEM;
- vma->vm_end += PAGE_SIZE;
- vma->vm_mm->total_vm += grow;
- if (vma->vm_flags & VM_LOCKED)
- vma->vm_mm->locked_vm += grow;
- __vm_stat_account(vma->vm_mm, vma->vm_flags, vma->vm_file, grow);
- return 0;
-}
-
-/*
* Return TRUE if ADDRESS points at a page in the kernel's mapped segment
* (inside region 5, on ia64) and that page is present.
*/
@@ -185,7 +159,13 @@ ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *re
if (REGION_NUMBER(address) != REGION_NUMBER(vma->vm_start)
|| REGION_OFFSET(address) >= RGN_MAP_LIMIT)
goto bad_area;
- if (expand_backing_store(vma, address))
+ /*
+ * Since the register backing store is accessed sequentially,
+ * we disallow growing it by more than a page at a time.
+ */
+ if (address > vma->vm_end + PAGE_SIZE - sizeof(long))
+ goto bad_area;
+ if (expand_upwards(vma, address))
goto bad_area;
}
goto good_area;
diff --git a/arch/ia64/mm/init.c b/arch/ia64/mm/init.c
index 1281c609ee98..e3215ba64ffd 100644
--- a/arch/ia64/mm/init.c
+++ b/arch/ia64/mm/init.c
@@ -158,7 +158,7 @@ ia64_init_addr_space (void)
vma->vm_start = current->thread.rbs_bot & PAGE_MASK;
vma->vm_end = vma->vm_start + PAGE_SIZE;
vma->vm_page_prot = protection_map[VM_DATA_DEFAULT_FLAGS & 0x7];
- vma->vm_flags = VM_DATA_DEFAULT_FLAGS | VM_GROWSUP;
+ vma->vm_flags = VM_DATA_DEFAULT_FLAGS|VM_GROWSUP|VM_ACCOUNT;
down_write(&current->mm->mmap_sem);
if (insert_vm_struct(current->mm, vma)) {
up_write(&current->mm->mmap_sem);
@@ -275,26 +275,21 @@ put_kernel_page (struct page *page, unsigned long address, pgprot_t pgprot)
pgd = pgd_offset_k(address); /* note: this is NOT pgd_offset()! */
- spin_lock(&init_mm.page_table_lock);
{
pud = pud_alloc(&init_mm, pgd, address);
if (!pud)
goto out;
-
pmd = pmd_alloc(&init_mm, pud, address);
if (!pmd)
goto out;
- pte = pte_alloc_map(&init_mm, pmd, address);
+ pte = pte_alloc_kernel(pmd, address);
if (!pte)
goto out;
- if (!pte_none(*pte)) {
- pte_unmap(pte);
+ if (!pte_none(*pte))
goto out;
- }
set_pte(pte, mk_pte(page, pgprot));
- pte_unmap(pte);
}
- out: spin_unlock(&init_mm.page_table_lock);
+ out:
/* no need for flush_tlb */
return page;
}
@@ -593,7 +588,7 @@ mem_init (void)
platform_dma_init();
#endif
-#ifndef CONFIG_DISCONTIGMEM
+#ifdef CONFIG_FLATMEM
if (!mem_map)
BUG();
max_mapnr = max_low_pfn;
diff --git a/arch/ia64/mm/numa.c b/arch/ia64/mm/numa.c
index 77118bbf3d8b..4e5c8b36ad93 100644
--- a/arch/ia64/mm/numa.c
+++ b/arch/ia64/mm/numa.c
@@ -47,3 +47,27 @@ paddr_to_nid(unsigned long paddr)
return (i < num_node_memblks) ? node_memblk[i].nid : (num_node_memblks ? -1 : 0);
}
+
+#if defined(CONFIG_SPARSEMEM) && defined(CONFIG_NUMA)
+/*
+ * Because of holes evaluate on section limits.
+ * If the section of memory exists, then return the node where the section
+ * resides. Otherwise return node 0 as the default. This is used by
+ * SPARSEMEM to allocate the SPARSEMEM sectionmap on the NUMA node where
+ * the section resides.
+ */
+int early_pfn_to_nid(unsigned long pfn)
+{
+ int i, section = pfn >> PFN_SECTION_SHIFT, ssec, esec;
+
+ for (i = 0; i < num_node_memblks; i++) {
+ ssec = node_memblk[i].start_paddr >> PA_SECTION_SHIFT;
+ esec = (node_memblk[i].start_paddr + node_memblk[i].size +
+ ((1L << PA_SECTION_SHIFT) - 1)) >> PA_SECTION_SHIFT;
+ if (section >= ssec && section < esec)
+ return node_memblk[i].nid;
+ }
+
+ return 0;
+}
+#endif
diff --git a/arch/ia64/mm/tlb.c b/arch/ia64/mm/tlb.c
index 464557e4ed82..41105d454423 100644
--- a/arch/ia64/mm/tlb.c
+++ b/arch/ia64/mm/tlb.c
@@ -8,6 +8,8 @@
* Modified RID allocation for SMP
* Goutham Rao <goutham.rao@intel.com>
* IPI based ptc implementation and A-step IPI implementation.
+ * Rohit Seth <rohit.seth@intel.com>
+ * Ken Chen <kenneth.w.chen@intel.com>
*/
#include <linux/config.h>
#include <linux/module.h>
@@ -16,80 +18,83 @@
#include <linux/sched.h>
#include <linux/smp.h>
#include <linux/mm.h>
+#include <linux/bootmem.h>
#include <asm/delay.h>
#include <asm/mmu_context.h>
#include <asm/pgalloc.h>
#include <asm/pal.h>
#include <asm/tlbflush.h>
+#include <asm/dma.h>
static struct {
unsigned long mask; /* mask of supported purge page-sizes */
- unsigned long max_bits; /* log2() of largest supported purge page-size */
+ unsigned long max_bits; /* log2 of largest supported purge page-size */
} purge;
struct ia64_ctx ia64_ctx = {
.lock = SPIN_LOCK_UNLOCKED,
.next = 1,
- .limit = (1 << 15) - 1, /* start out with the safe (architected) limit */
.max_ctx = ~0U
};
DEFINE_PER_CPU(u8, ia64_need_tlb_flush);
/*
+ * Initializes the ia64_ctx.bitmap array based on max_ctx+1.
+ * Called after cpu_init() has setup ia64_ctx.max_ctx based on
+ * maximum RID that is supported by boot CPU.
+ */
+void __init
+mmu_context_init (void)
+{
+ ia64_ctx.bitmap = alloc_bootmem((ia64_ctx.max_ctx+1)>>3);
+ ia64_ctx.flushmap = alloc_bootmem((ia64_ctx.max_ctx+1)>>3);
+}
+
+/*
* Acquire the ia64_ctx.lock before calling this function!
*/
void
wrap_mmu_context (struct mm_struct *mm)
{
- unsigned long tsk_context, max_ctx = ia64_ctx.max_ctx;
- struct task_struct *tsk;
- int i;
+ int i, cpu;
+ unsigned long flush_bit;
- if (ia64_ctx.next > max_ctx)
- ia64_ctx.next = 300; /* skip daemons */
- ia64_ctx.limit = max_ctx + 1;
+ for (i=0; i <= ia64_ctx.max_ctx / BITS_PER_LONG; i++) {
+ flush_bit = xchg(&ia64_ctx.flushmap[i], 0);
+ ia64_ctx.bitmap[i] ^= flush_bit;
+ }
+
+ /* use offset at 300 to skip daemons */
+ ia64_ctx.next = find_next_zero_bit(ia64_ctx.bitmap,
+ ia64_ctx.max_ctx, 300);
+ ia64_ctx.limit = find_next_bit(ia64_ctx.bitmap,
+ ia64_ctx.max_ctx, ia64_ctx.next);
/*
- * Scan all the task's mm->context and set proper safe range
+ * can't call flush_tlb_all() here because of race condition
+ * with O(1) scheduler [EF]
*/
-
- read_lock(&tasklist_lock);
- repeat:
- for_each_process(tsk) {
- if (!tsk->mm)
- continue;
- tsk_context = tsk->mm->context;
- if (tsk_context == ia64_ctx.next) {
- if (++ia64_ctx.next >= ia64_ctx.limit) {
- /* empty range: reset the range limit and start over */
- if (ia64_ctx.next > max_ctx)
- ia64_ctx.next = 300;
- ia64_ctx.limit = max_ctx + 1;
- goto repeat;
- }
- }
- if ((tsk_context > ia64_ctx.next) && (tsk_context < ia64_ctx.limit))
- ia64_ctx.limit = tsk_context;
- }
- read_unlock(&tasklist_lock);
- /* can't call flush_tlb_all() here because of race condition with O(1) scheduler [EF] */
- {
- int cpu = get_cpu(); /* prevent preemption/migration */
- for (i = 0; i < NR_CPUS; ++i)
- if (cpu_online(i) && (i != cpu))
- per_cpu(ia64_need_tlb_flush, i) = 1;
- put_cpu();
- }
+ cpu = get_cpu(); /* prevent preemption/migration */
+ for_each_online_cpu(i)
+ if (i != cpu)
+ per_cpu(ia64_need_tlb_flush, i) = 1;
+ put_cpu();
local_flush_tlb_all();
}
void
-ia64_global_tlb_purge (unsigned long start, unsigned long end, unsigned long nbits)
+ia64_global_tlb_purge (struct mm_struct *mm, unsigned long start,
+ unsigned long end, unsigned long nbits)
{
static DEFINE_SPINLOCK(ptcg_lock);
+ if (mm != current->active_mm) {
+ flush_tlb_all();
+ return;
+ }
+
/* HW requires global serialization of ptc.ga. */
spin_lock(&ptcg_lock);
{
@@ -129,36 +134,37 @@ local_flush_tlb_all (void)
}
void
-flush_tlb_range (struct vm_area_struct *vma, unsigned long start, unsigned long end)
+flush_tlb_range (struct vm_area_struct *vma, unsigned long start,
+ unsigned long end)
{
struct mm_struct *mm = vma->vm_mm;
unsigned long size = end - start;
unsigned long nbits;
+#ifndef CONFIG_SMP
if (mm != current->active_mm) {
- /* this does happen, but perhaps it's not worth optimizing for? */
-#ifdef CONFIG_SMP
- flush_tlb_all();
-#else
mm->context = 0;
-#endif
return;
}
+#endif
nbits = ia64_fls(size + 0xfff);
- while (unlikely (((1UL << nbits) & purge.mask) == 0) && (nbits < purge.max_bits))
+ while (unlikely (((1UL << nbits) & purge.mask) == 0) &&
+ (nbits < purge.max_bits))
++nbits;
if (nbits > purge.max_bits)
nbits = purge.max_bits;
start &= ~((1UL << nbits) - 1);
# ifdef CONFIG_SMP
- platform_global_tlb_purge(start, end, nbits);
+ platform_global_tlb_purge(mm, start, end, nbits);
# else
+ preempt_disable();
do {
ia64_ptcl(start, (nbits<<2));
start += (1UL << nbits);
} while (start < end);
+ preempt_enable();
# endif
ia64_srlz_i(); /* srlz.i implies srlz.d */
@@ -186,5 +192,5 @@ ia64_tlb_init (void)
local_cpu_data->ptce_stride[0] = ptce_info.stride[0];
local_cpu_data->ptce_stride[1] = ptce_info.stride[1];
- local_flush_tlb_all(); /* nuke left overs from bootstrapping... */
+ local_flush_tlb_all(); /* nuke left overs from bootstrapping... */
}
diff --git a/arch/ia64/oprofile/Kconfig b/arch/ia64/oprofile/Kconfig
index 56e6f614b04a..97271ab484dc 100644
--- a/arch/ia64/oprofile/Kconfig
+++ b/arch/ia64/oprofile/Kconfig
@@ -1,7 +1,3 @@
-
-menu "Profiling support"
- depends on EXPERIMENTAL
-
config PROFILING
bool "Profiling support (EXPERIMENTAL)"
help
@@ -22,5 +18,3 @@ config OPROFILE
If unsure, say N.
-endmenu
-
diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c
index 9b5de589b82f..20d76fae24e8 100644
--- a/arch/ia64/pci/pci.c
+++ b/arch/ia64/pci/pci.c
@@ -95,7 +95,7 @@ pci_sal_write (unsigned int seg, unsigned int bus, unsigned int devfn,
}
static struct pci_raw_ops pci_sal_ops = {
- .read = pci_sal_read,
+ .read = pci_sal_read,
.write = pci_sal_write
};
@@ -120,29 +120,6 @@ struct pci_ops pci_root_ops = {
.write = pci_write,
};
-#ifdef CONFIG_NUMA
-extern acpi_status acpi_map_iosapic(acpi_handle, u32, void *, void **);
-static void acpi_map_iosapics(void)
-{
- acpi_get_devices(NULL, acpi_map_iosapic, NULL, NULL);
-}
-#else
-static void acpi_map_iosapics(void)
-{
- return;
-}
-#endif /* CONFIG_NUMA */
-
-static int __init
-pci_acpi_init (void)
-{
- acpi_map_iosapics();
-
- return 0;
-}
-
-subsys_initcall(pci_acpi_init);
-
/* Called by ACPI when it finds a new root bus. */
static struct pci_controller * __devinit
@@ -160,35 +137,121 @@ alloc_pci_controller (int seg)
return controller;
}
-static u64 __devinit
-add_io_space (struct acpi_resource_address64 *addr)
+struct pci_root_info {
+ struct pci_controller *controller;
+ char *name;
+};
+
+static unsigned int
+new_space (u64 phys_base, int sparse)
{
- u64 offset;
- int sparse = 0;
+ u64 mmio_base;
int i;
- if (addr->address_translation_offset == 0)
- return IO_SPACE_BASE(0); /* part of legacy IO space */
-
- if (addr->attribute.io.translation_attribute == ACPI_SPARSE_TRANSLATION)
- sparse = 1;
+ if (phys_base == 0)
+ return 0; /* legacy I/O port space */
- offset = (u64) ioremap(addr->address_translation_offset, 0);
+ mmio_base = (u64) ioremap(phys_base, 0);
for (i = 0; i < num_io_spaces; i++)
- if (io_space[i].mmio_base == offset &&
+ if (io_space[i].mmio_base == mmio_base &&
io_space[i].sparse == sparse)
- return IO_SPACE_BASE(i);
+ return i;
if (num_io_spaces == MAX_IO_SPACES) {
- printk("Too many IO port spaces\n");
+ printk(KERN_ERR "PCI: Too many IO port spaces "
+ "(MAX_IO_SPACES=%lu)\n", MAX_IO_SPACES);
return ~0;
}
i = num_io_spaces++;
- io_space[i].mmio_base = offset;
+ io_space[i].mmio_base = mmio_base;
io_space[i].sparse = sparse;
- return IO_SPACE_BASE(i);
+ return i;
+}
+
+static u64 __devinit
+add_io_space (struct pci_root_info *info, struct acpi_resource_address64 *addr)
+{
+ struct resource *resource;
+ char *name;
+ u64 base, min, max, base_port;
+ unsigned int sparse = 0, space_nr, len;
+
+ resource = kzalloc(sizeof(*resource), GFP_KERNEL);
+ if (!resource) {
+ printk(KERN_ERR "PCI: No memory for %s I/O port space\n",
+ info->name);
+ goto out;
+ }
+
+ len = strlen(info->name) + 32;
+ name = kzalloc(len, GFP_KERNEL);
+ if (!name) {
+ printk(KERN_ERR "PCI: No memory for %s I/O port space name\n",
+ info->name);
+ goto free_resource;
+ }
+
+ min = addr->min_address_range;
+ max = min + addr->address_length - 1;
+ if (addr->attribute.io.translation_attribute == ACPI_SPARSE_TRANSLATION)
+ sparse = 1;
+
+ space_nr = new_space(addr->address_translation_offset, sparse);
+ if (space_nr == ~0)
+ goto free_name;
+
+ base = __pa(io_space[space_nr].mmio_base);
+ base_port = IO_SPACE_BASE(space_nr);
+ snprintf(name, len, "%s I/O Ports %08lx-%08lx", info->name,
+ base_port + min, base_port + max);
+
+ /*
+ * The SDM guarantees the legacy 0-64K space is sparse, but if the
+ * mapping is done by the processor (not the bridge), ACPI may not
+ * mark it as sparse.
+ */
+ if (space_nr == 0)
+ sparse = 1;
+
+ resource->name = name;
+ resource->flags = IORESOURCE_MEM;
+ resource->start = base + (sparse ? IO_SPACE_SPARSE_ENCODING(min) : min);
+ resource->end = base + (sparse ? IO_SPACE_SPARSE_ENCODING(max) : max);
+ insert_resource(&iomem_resource, resource);
+
+ return base_port;
+
+free_name:
+ kfree(name);
+free_resource:
+ kfree(resource);
+out:
+ return ~0;
+}
+
+static acpi_status __devinit resource_to_window(struct acpi_resource *resource,
+ struct acpi_resource_address64 *addr)
+{
+ acpi_status status;
+
+ /*
+ * We're only interested in _CRS descriptors that are
+ * - address space descriptors for memory or I/O space
+ * - non-zero size
+ * - producers, i.e., the address space is routed downstream,
+ * not consumed by the bridge itself
+ */
+ status = acpi_resource_to_address64(resource, addr);
+ if (ACPI_SUCCESS(status) &&
+ (addr->resource_type == ACPI_MEMORY_RANGE ||
+ addr->resource_type == ACPI_IO_RANGE) &&
+ addr->address_length &&
+ addr->producer_consumer == ACPI_PRODUCER)
+ return AE_OK;
+
+ return AE_ERROR;
}
static acpi_status __devinit
@@ -198,20 +261,13 @@ count_window (struct acpi_resource *resource, void *data)
struct acpi_resource_address64 addr;
acpi_status status;
- status = acpi_resource_to_address64(resource, &addr);
+ status = resource_to_window(resource, &addr);
if (ACPI_SUCCESS(status))
- if (addr.resource_type == ACPI_MEMORY_RANGE ||
- addr.resource_type == ACPI_IO_RANGE)
- (*windows)++;
+ (*windows)++;
return AE_OK;
}
-struct pci_root_info {
- struct pci_controller *controller;
- char *name;
-};
-
static __devinit acpi_status add_window(struct acpi_resource *res, void *data)
{
struct pci_root_info *info = data;
@@ -221,13 +277,11 @@ static __devinit acpi_status add_window(struct acpi_resource *res, void *data)
unsigned long flags, offset = 0;
struct resource *root;
- status = acpi_resource_to_address64(res, &addr);
+ /* Return AE_OK for non-window resources to keep scanning for more */
+ status = resource_to_window(res, &addr);
if (!ACPI_SUCCESS(status))
return AE_OK;
- if (!addr.address_length)
- return AE_OK;
-
if (addr.resource_type == ACPI_MEMORY_RANGE) {
flags = IORESOURCE_MEM;
root = &iomem_resource;
@@ -235,7 +289,7 @@ static __devinit acpi_status add_window(struct acpi_resource *res, void *data)
} else if (addr.resource_type == ACPI_IO_RANGE) {
flags = IORESOURCE_IO;
root = &ioport_resource;
- offset = add_io_space(&addr);
+ offset = add_io_space(info, &addr);
if (offset == ~0)
return AE_OK;
} else
@@ -245,7 +299,7 @@ static __devinit acpi_status add_window(struct acpi_resource *res, void *data)
window->resource.name = info->name;
window->resource.flags = flags;
window->resource.start = addr.min_address_range + offset;
- window->resource.end = addr.max_address_range + offset;
+ window->resource.end = window->resource.start + addr.address_length - 1;
window->resource.child = NULL;
window->offset = offset;
@@ -743,7 +797,7 @@ int pci_vector_resources(int last, int nr_released)
{
int count = nr_released;
- count += (IA64_LAST_DEVICE_VECTOR - last);
+ count += (IA64_LAST_DEVICE_VECTOR - last);
return count;
}
diff --git a/arch/ia64/sn/kernel/bte.c b/arch/ia64/sn/kernel/bte.c
index 45854c637e9c..d71f4de44f79 100644
--- a/arch/ia64/sn/kernel/bte.c
+++ b/arch/ia64/sn/kernel/bte.c
@@ -87,7 +87,7 @@ bte_result_t bte_copy(u64 src, u64 dest, u64 len, u64 mode, void *notification)
unsigned long irq_flags;
unsigned long itc_end = 0;
int nasid_to_try[MAX_NODES_TO_TRY];
- int my_nasid = get_nasid();
+ int my_nasid = cpuid_to_nasid(raw_smp_processor_id());
int bte_if_index, nasid_index;
int bte_first, btes_per_node = BTES_PER_NODE;
diff --git a/arch/ia64/sn/kernel/io_init.c b/arch/ia64/sn/kernel/io_init.c
index 906622d9f933..05e4ea889981 100644
--- a/arch/ia64/sn/kernel/io_init.c
+++ b/arch/ia64/sn/kernel/io_init.c
@@ -22,8 +22,6 @@
#include "xtalk/hubdev.h"
#include "xtalk/xwidgetdev.h"
-nasid_t master_nasid = INVALID_NASID; /* Partition Master */
-
static struct list_head sn_sysdata_list;
/* sysdata list struct */
@@ -165,7 +163,7 @@ static void sn_fixup_ionodes(void)
* Get SGI Specific HUB chipset information.
* Inform Prom that this kernel can support domain bus numbering.
*/
- for (i = 0; i < numionodes; i++) {
+ for (i = 0; i < num_cnodes; i++) {
hubdev = (struct hubdev_info *)(NODEPDA(i)->pdinfo);
nasid = cnodeid_to_nasid(i);
hubdev->max_segment_number = 0xffffffff;
@@ -351,7 +349,7 @@ void sn_pci_controller_fixup(int segment, int busnum, struct pci_bus *bus)
return; /*bus # does not exist */
prom_bussoft_ptr = __va(prom_bussoft_ptr);
- controller = kcalloc(1,sizeof(struct pci_controller), GFP_KERNEL);
+ controller = kzalloc(sizeof(struct pci_controller), GFP_KERNEL);
controller->segment = segment;
if (!controller)
BUG();
diff --git a/arch/ia64/sn/kernel/setup.c b/arch/ia64/sn/kernel/setup.c
index 6f8c5883716b..0fb579ef18c2 100644
--- a/arch/ia64/sn/kernel/setup.c
+++ b/arch/ia64/sn/kernel/setup.c
@@ -59,8 +59,6 @@ DEFINE_PER_CPU(struct pda_s, pda_percpu);
#define MAX_PHYS_MEMORY (1UL << IA64_MAX_PHYS_BITS) /* Max physical address supported */
-lboard_t *root_lboard[MAX_COMPACT_NODES];
-
extern void bte_init_node(nodepda_t *, cnodeid_t);
extern void sn_timer_init(void);
@@ -97,15 +95,15 @@ u8 sn_region_size;
EXPORT_SYMBOL(sn_region_size);
int sn_prom_type; /* 0=hardware, 1=medusa/realprom, 2=medusa/fakeprom */
-short physical_node_map[MAX_PHYSNODE_ID];
+short physical_node_map[MAX_NUMALINK_NODES];
static unsigned long sn_prom_features[MAX_PROM_FEATURE_SETS];
EXPORT_SYMBOL(physical_node_map);
-int numionodes;
+int num_cnodes;
static void sn_init_pdas(char **);
-static void scan_for_ionodes(void);
+static void build_cnode_tables(void);
static nodepda_t *nodepdaindr[MAX_COMPACT_NODES];
@@ -140,19 +138,6 @@ char drive_info[4 * 16];
#endif
/*
- * Get nasid of current cpu early in boot before nodepda is initialized
- */
-static int
-boot_get_nasid(void)
-{
- int nasid;
-
- if (ia64_sn_get_sapic_info(get_sapicid(), &nasid, NULL, NULL))
- BUG();
- return nasid;
-}
-
-/*
* This routine can only be used during init, since
* smp_boot_data is an init data structure.
* We have to use smp_boot_data.cpu_phys_id to find
@@ -223,7 +208,6 @@ void __init early_sn_setup(void)
}
extern int platform_intr_list[];
-extern nasid_t master_nasid;
static int __initdata shub_1_1_found = 0;
/*
@@ -269,7 +253,6 @@ static void __init sn_check_for_wars(void)
void __init sn_setup(char **cmdline_p)
{
long status, ticks_per_sec, drift;
- int pxm;
u32 version = sn_sal_rev();
extern void sn_cpu_init(void);
@@ -300,11 +283,10 @@ void __init sn_setup(char **cmdline_p)
MAX_DMA_ADDRESS = PAGE_OFFSET + MAX_PHYS_MEMORY;
- memset(physical_node_map, -1, sizeof(physical_node_map));
- for (pxm = 0; pxm < MAX_PXM_DOMAINS; pxm++)
- if (pxm_to_nid_map[pxm] != -1)
- physical_node_map[pxm_to_nasid(pxm)] =
- pxm_to_nid_map[pxm];
+ /*
+ * Build the tables for managing cnodes.
+ */
+ build_cnode_tables();
/*
* Old PROMs do not provide an ACPI FADT. Disable legacy keyboard
@@ -319,8 +301,6 @@ void __init sn_setup(char **cmdline_p)
printk("SGI SAL version %x.%02x\n", version >> 8, version & 0x00FF);
- master_nasid = boot_get_nasid();
-
status =
ia64_sal_freq_base(SAL_FREQ_BASE_REALTIME_CLOCK, &ticks_per_sec,
&drift);
@@ -378,15 +358,6 @@ static void __init sn_init_pdas(char **cmdline_p)
{
cnodeid_t cnode;
- memset(sn_cnodeid_to_nasid, -1,
- sizeof(__ia64_per_cpu_var(__sn_cnodeid_to_nasid)));
- for_each_online_node(cnode)
- sn_cnodeid_to_nasid[cnode] =
- pxm_to_nasid(nid_to_pxm_map[cnode]);
-
- numionodes = num_online_nodes();
- scan_for_ionodes();
-
/*
* Allocate & initalize the nodepda for each node.
*/
@@ -402,7 +373,7 @@ static void __init sn_init_pdas(char **cmdline_p)
/*
* Allocate & initialize nodepda for TIOs. For now, put them on node 0.
*/
- for (cnode = num_online_nodes(); cnode < numionodes; cnode++) {
+ for (cnode = num_online_nodes(); cnode < num_cnodes; cnode++) {
nodepdaindr[cnode] =
alloc_bootmem_node(NODE_DATA(0), sizeof(nodepda_t));
memset(nodepdaindr[cnode], 0, sizeof(nodepda_t));
@@ -411,7 +382,7 @@ static void __init sn_init_pdas(char **cmdline_p)
/*
* Now copy the array of nodepda pointers to each nodepda.
*/
- for (cnode = 0; cnode < numionodes; cnode++)
+ for (cnode = 0; cnode < num_cnodes; cnode++)
memcpy(nodepdaindr[cnode]->pernode_pdaindr, nodepdaindr,
sizeof(nodepdaindr));
@@ -428,7 +399,7 @@ static void __init sn_init_pdas(char **cmdline_p)
* Initialize the per node hubdev. This includes IO Nodes and
* headless/memless nodes.
*/
- for (cnode = 0; cnode < numionodes; cnode++) {
+ for (cnode = 0; cnode < num_cnodes; cnode++) {
hubdev_init_node(nodepdaindr[cnode], cnode);
}
}
@@ -553,87 +524,58 @@ void __init sn_cpu_init(void)
}
/*
- * Scan klconfig for ionodes. Add the nasids to the
- * physical_node_map and the pda and increment numionodes.
+ * Build tables for converting between NASIDs and cnodes.
*/
+static inline int __init board_needs_cnode(int type)
+{
+ return (type == KLTYPE_SNIA || type == KLTYPE_TIO);
+}
-static void __init scan_for_ionodes(void)
+void __init build_cnode_tables(void)
{
- int nasid = 0;
+ int nasid;
+ int node;
lboard_t *brd;
- /* fakeprom does not support klgraph */
- if (IS_RUNNING_ON_FAKE_PROM())
- return;
-
- /* Setup ionodes with memory */
- for (nasid = 0; nasid < MAX_PHYSNODE_ID; nasid += 2) {
- char *klgraph_header;
- cnodeid_t cnodeid;
-
- if (physical_node_map[nasid] == -1)
- continue;
+ memset(physical_node_map, -1, sizeof(physical_node_map));
+ memset(sn_cnodeid_to_nasid, -1,
+ sizeof(__ia64_per_cpu_var(__sn_cnodeid_to_nasid)));
- cnodeid = -1;
- klgraph_header = __va(ia64_sn_get_klconfig_addr(nasid));
- if (!klgraph_header) {
- BUG(); /* All nodes must have klconfig tables! */
- }
- cnodeid = nasid_to_cnodeid(nasid);
- root_lboard[cnodeid] = (lboard_t *)
- NODE_OFFSET_TO_LBOARD((nasid),
- ((kl_config_hdr_t
- *) (klgraph_header))->
- ch_board_info);
+ /*
+ * First populate the tables with C/M bricks. This ensures that
+ * cnode == node for all C & M bricks.
+ */
+ for_each_online_node(node) {
+ nasid = pxm_to_nasid(nid_to_pxm_map[node]);
+ sn_cnodeid_to_nasid[node] = nasid;
+ physical_node_map[nasid] = node;
}
- /* Scan headless/memless IO Nodes. */
- for (nasid = 0; nasid < MAX_PHYSNODE_ID; nasid += 2) {
- /* if there's no nasid, don't try to read the klconfig on the node */
- if (physical_node_map[nasid] == -1)
- continue;
- brd = find_lboard_any((lboard_t *)
- root_lboard[nasid_to_cnodeid(nasid)],
- KLTYPE_SNIA);
- if (brd) {
- brd = KLCF_NEXT_ANY(brd); /* Skip this node's lboard */
- if (!brd)
- continue;
- }
-
- brd = find_lboard_any(brd, KLTYPE_SNIA);
+ /*
+ * num_cnodes is total number of C/M/TIO bricks. Because of the 256 node
+ * limit on the number of nodes, we can't use the generic node numbers
+ * for this. Note that num_cnodes is incremented below as TIOs or
+ * headless/memoryless nodes are discovered.
+ */
+ num_cnodes = num_online_nodes();
- while (brd) {
- sn_cnodeid_to_nasid[numionodes] = brd->brd_nasid;
- physical_node_map[brd->brd_nasid] = numionodes;
- root_lboard[numionodes] = brd;
- numionodes++;
- brd = KLCF_NEXT_ANY(brd);
- if (!brd)
- break;
-
- brd = find_lboard_any(brd, KLTYPE_SNIA);
- }
- }
+ /* fakeprom does not support klgraph */
+ if (IS_RUNNING_ON_FAKE_PROM())
+ return;
- /* Scan for TIO nodes. */
- for (nasid = 0; nasid < MAX_PHYSNODE_ID; nasid += 2) {
- /* if there's no nasid, don't try to read the klconfig on the node */
- if (physical_node_map[nasid] == -1)
- continue;
- brd = find_lboard_any((lboard_t *)
- root_lboard[nasid_to_cnodeid(nasid)],
- KLTYPE_TIO);
+ /* Find TIOs & headless/memoryless nodes and add them to the tables */
+ for_each_online_node(node) {
+ kl_config_hdr_t *klgraph_header;
+ nasid = cnodeid_to_nasid(node);
+ if ((klgraph_header = ia64_sn_get_klconfig_addr(nasid)) == NULL)
+ BUG();
+ brd = NODE_OFFSET_TO_LBOARD(nasid, klgraph_header->ch_board_info);
while (brd) {
- sn_cnodeid_to_nasid[numionodes] = brd->brd_nasid;
- physical_node_map[brd->brd_nasid] = numionodes;
- root_lboard[numionodes] = brd;
- numionodes++;
- brd = KLCF_NEXT_ANY(brd);
- if (!brd)
- break;
-
- brd = find_lboard_any(brd, KLTYPE_TIO);
+ if (board_needs_cnode(brd->brd_type) && physical_node_map[brd->brd_nasid] < 0) {
+ sn_cnodeid_to_nasid[num_cnodes] = brd->brd_nasid;
+ physical_node_map[brd->brd_nasid] = num_cnodes++;
+ }
+ brd = find_lboard_next(brd);
}
}
}
diff --git a/arch/ia64/sn/kernel/sn2/sn2_smp.c b/arch/ia64/sn/kernel/sn2/sn2_smp.c
index 0a4ee50c302f..49b530c39a42 100644
--- a/arch/ia64/sn/kernel/sn2/sn2_smp.c
+++ b/arch/ia64/sn/kernel/sn2/sn2_smp.c
@@ -177,6 +177,7 @@ void sn_tlb_migrate_finish(struct mm_struct *mm)
/**
* sn2_global_tlb_purge - globally purge translation cache of virtual address range
+ * @mm: mm_struct containing virtual address range
* @start: start of virtual address range
* @end: end of virtual address range
* @nbits: specifies number of bytes to purge per instruction (num = 1<<(nbits & 0xfc))
@@ -188,21 +189,22 @@ void sn_tlb_migrate_finish(struct mm_struct *mm)
* - cpu_vm_mask is a bit mask that indicates which cpus have loaded the context.
* - cpu_vm_mask is converted into a nodemask of the nodes containing the
* cpus in cpu_vm_mask.
- * - if only one bit is set in cpu_vm_mask & it is the current cpu,
- * then only the local TLB needs to be flushed. This flushing can be done
- * using ptc.l. This is the common case & avoids the global spinlock.
+ * - if only one bit is set in cpu_vm_mask & it is the current cpu & the
+ * process is purging its own virtual address range, then only the
+ * local TLB needs to be flushed. This flushing can be done using
+ * ptc.l. This is the common case & avoids the global spinlock.
* - if multiple cpus have loaded the context, then flushing has to be
* done with ptc.g/MMRs under protection of the global ptc_lock.
*/
void
-sn2_global_tlb_purge(unsigned long start, unsigned long end,
- unsigned long nbits)
+sn2_global_tlb_purge(struct mm_struct *mm, unsigned long start,
+ unsigned long end, unsigned long nbits)
{
int i, opt, shub1, cnode, mynasid, cpu, lcpu = 0, nasid, flushed = 0;
+ int mymm = (mm == current->active_mm);
volatile unsigned long *ptc0, *ptc1;
- unsigned long itc, itc2, flags, data0 = 0, data1 = 0;
- struct mm_struct *mm = current->active_mm;
+ unsigned long itc, itc2, flags, data0 = 0, data1 = 0, rr_value;
short nasids[MAX_NUMNODES], nix;
nodemask_t nodes_flushed;
@@ -216,9 +218,12 @@ sn2_global_tlb_purge(unsigned long start, unsigned long end,
i++;
}
+ if (i == 0)
+ return;
+
preempt_disable();
- if (likely(i == 1 && lcpu == smp_processor_id())) {
+ if (likely(i == 1 && lcpu == smp_processor_id() && mymm)) {
do {
ia64_ptcl(start, nbits << 2);
start += (1UL << nbits);
@@ -229,7 +234,7 @@ sn2_global_tlb_purge(unsigned long start, unsigned long end,
return;
}
- if (atomic_read(&mm->mm_users) == 1) {
+ if (atomic_read(&mm->mm_users) == 1 && mymm) {
flush_tlb_mm(mm);
__get_cpu_var(ptcstats).change_rid++;
preempt_enable();
@@ -241,11 +246,13 @@ sn2_global_tlb_purge(unsigned long start, unsigned long end,
for_each_node_mask(cnode, nodes_flushed)
nasids[nix++] = cnodeid_to_nasid(cnode);
+ rr_value = (mm->context << 3) | REGION_NUMBER(start);
+
shub1 = is_shub1();
if (shub1) {
data0 = (1UL << SH1_PTC_0_A_SHFT) |
(nbits << SH1_PTC_0_PS_SHFT) |
- ((ia64_get_rr(start) >> 8) << SH1_PTC_0_RID_SHFT) |
+ (rr_value << SH1_PTC_0_RID_SHFT) |
(1UL << SH1_PTC_0_START_SHFT);
ptc0 = (long *)GLOBAL_MMR_PHYS_ADDR(0, SH1_PTC_0);
ptc1 = (long *)GLOBAL_MMR_PHYS_ADDR(0, SH1_PTC_1);
@@ -254,7 +261,7 @@ sn2_global_tlb_purge(unsigned long start, unsigned long end,
(nbits << SH2_PTC_PS_SHFT) |
(1UL << SH2_PTC_START_SHFT);
ptc0 = (long *)GLOBAL_MMR_PHYS_ADDR(0, SH2_PTC +
- ((ia64_get_rr(start) >> 8) << SH2_PTC_RID_SHFT) );
+ (rr_value << SH2_PTC_RID_SHFT));
ptc1 = NULL;
}
@@ -275,7 +282,7 @@ sn2_global_tlb_purge(unsigned long start, unsigned long end,
data0 = (data0 & ~SH2_PTC_ADDR_MASK) | (start & SH2_PTC_ADDR_MASK);
for (i = 0; i < nix; i++) {
nasid = nasids[i];
- if ((!(sn2_ptctest & 3)) && unlikely(nasid == mynasid)) {
+ if ((!(sn2_ptctest & 3)) && unlikely(nasid == mynasid && mymm)) {
ia64_ptcga(start, nbits << 2);
ia64_srlz_i();
} else {
diff --git a/arch/ia64/sn/kernel/sn2/sn_hwperf.c b/arch/ia64/sn/kernel/sn2/sn_hwperf.c
index 0513aacac8c1..6c6fbca3229c 100644
--- a/arch/ia64/sn/kernel/sn2/sn_hwperf.c
+++ b/arch/ia64/sn/kernel/sn2/sn_hwperf.c
@@ -476,8 +476,8 @@ static int sn_topology_show(struct seq_file *s, void *d)
for_each_online_cpu(j) {
seq_printf(s, j ? ":%d" : ", dist %d",
node_distance(
- cpuid_to_cnodeid(i),
- cpuid_to_cnodeid(j)));
+ cpu_to_node(i),
+ cpu_to_node(j)));
}
seq_putc(s, '\n');
}
diff --git a/arch/ia64/sn/kernel/tiocx.c b/arch/ia64/sn/kernel/tiocx.c
index b45db5133f55..0d8592a745a7 100644
--- a/arch/ia64/sn/kernel/tiocx.c
+++ b/arch/ia64/sn/kernel/tiocx.c
@@ -183,11 +183,12 @@ int cx_driver_unregister(struct cx_drv *cx_driver)
* @part_num: device's part number
* @mfg_num: device's manufacturer number
* @hubdev: hub info associated with this device
+ * @bt: board type of the device
*
*/
int
cx_device_register(nasid_t nasid, int part_num, int mfg_num,
- struct hubdev_info *hubdev)
+ struct hubdev_info *hubdev, int bt)
{
struct cx_dev *cx_dev;
@@ -200,6 +201,7 @@ cx_device_register(nasid_t nasid, int part_num, int mfg_num,
cx_dev->cx_id.mfg_num = mfg_num;
cx_dev->cx_id.nasid = nasid;
cx_dev->hubdev = hubdev;
+ cx_dev->bt = bt;
cx_dev->dev.parent = NULL;
cx_dev->dev.bus = &tiocx_bus_type;
@@ -238,7 +240,8 @@ static int cx_device_reload(struct cx_dev *cx_dev)
{
cx_device_unregister(cx_dev);
return cx_device_register(cx_dev->cx_id.nasid, cx_dev->cx_id.part_num,
- cx_dev->cx_id.mfg_num, cx_dev->hubdev);
+ cx_dev->cx_id.mfg_num, cx_dev->hubdev,
+ cx_dev->bt);
}
static inline uint64_t tiocx_intr_alloc(nasid_t nasid, int widget,
@@ -365,26 +368,20 @@ static void tio_corelet_reset(nasid_t nasid, int corelet)
udelay(2000);
}
-static int tiocx_btchar_get(int nasid)
+static int is_fpga_tio(int nasid, int *bt)
{
- moduleid_t module_id;
- geoid_t geoid;
- int cnodeid;
-
- cnodeid = nasid_to_cnodeid(nasid);
- geoid = cnodeid_get_geoid(cnodeid);
- module_id = geo_module(geoid);
- return MODULE_GET_BTCHAR(module_id);
-}
+ int ioboard_type;
-static int is_fpga_brick(int nasid)
-{
- switch (tiocx_btchar_get(nasid)) {
+ ioboard_type = ia64_sn_sysctl_ioboard_get(nasid);
+
+ switch (ioboard_type) {
case L1_BRICKTYPE_SA:
case L1_BRICKTYPE_ATHENA:
- case L1_BRICKTYPE_DAYTONA:
+ case L1_BOARDTYPE_DAYTONA:
+ *bt = ioboard_type;
return 1;
}
+
return 0;
}
@@ -407,16 +404,22 @@ static int tiocx_reload(struct cx_dev *cx_dev)
if (bitstream_loaded(nasid)) {
uint64_t cx_id;
-
- cx_id =
- *(volatile uint64_t *)(TIO_SWIN_BASE(nasid, TIOCX_CORELET) +
+ int rv;
+
+ rv = ia64_sn_sysctl_tio_clock_reset(nasid);
+ if (rv) {
+ printk(KERN_ALERT "CX port JTAG reset failed.\n");
+ } else {
+ cx_id = *(volatile uint64_t *)
+ (TIO_SWIN_BASE(nasid, TIOCX_CORELET) +
WIDGET_ID);
- part_num = XWIDGET_PART_NUM(cx_id);
- mfg_num = XWIDGET_MFG_NUM(cx_id);
- DBG("part= 0x%x, mfg= 0x%x\n", part_num, mfg_num);
- /* just ignore it if it's a CE */
- if (part_num == TIO_CE_ASIC_PARTNUM)
- return 0;
+ part_num = XWIDGET_PART_NUM(cx_id);
+ mfg_num = XWIDGET_MFG_NUM(cx_id);
+ DBG("part= 0x%x, mfg= 0x%x\n", part_num, mfg_num);
+ /* just ignore it if it's a CE */
+ if (part_num == TIO_CE_ASIC_PARTNUM)
+ return 0;
+ }
}
cx_dev->cx_id.part_num = part_num;
@@ -436,10 +439,10 @@ static ssize_t show_cxdev_control(struct device *dev, struct device_attribute *a
{
struct cx_dev *cx_dev = to_cx_dev(dev);
- return sprintf(buf, "0x%x 0x%x 0x%x %d\n",
+ return sprintf(buf, "0x%x 0x%x 0x%x 0x%x\n",
cx_dev->cx_id.nasid,
cx_dev->cx_id.part_num, cx_dev->cx_id.mfg_num,
- tiocx_btchar_get(cx_dev->cx_id.nasid));
+ cx_dev->bt);
}
static ssize_t store_cxdev_control(struct device *dev, struct device_attribute *attr, const char *buf,
@@ -486,13 +489,13 @@ static int __init tiocx_init(void)
bus_register(&tiocx_bus_type);
- for (cnodeid = 0; cnodeid < MAX_COMPACT_NODES; cnodeid++) {
+ for (cnodeid = 0; cnodeid < num_cnodes; cnodeid++) {
nasid_t nasid;
+ int bt;
- if ((nasid = cnodeid_to_nasid(cnodeid)) < 0)
- break; /* No more nasids .. bail out of loop */
+ nasid = cnodeid_to_nasid(cnodeid);
- if ((nasid & 0x1) && is_fpga_brick(nasid)) {
+ if ((nasid & 0x1) && is_fpga_tio(nasid, &bt)) {
struct hubdev_info *hubdev;
struct xwidget_info *widgetp;
@@ -512,7 +515,7 @@ static int __init tiocx_init(void)
if (cx_device_register
(nasid, widgetp->xwi_hwid.part_num,
- widgetp->xwi_hwid.mfg_num, hubdev) < 0)
+ widgetp->xwi_hwid.mfg_num, hubdev, bt) < 0)
return -ENXIO;
else
found_tiocx_device++;
diff --git a/arch/ia64/sn/kernel/xpc.h b/arch/ia64/sn/kernel/xpc.h
index d0ee635daf2e..5483a9f227d4 100644
--- a/arch/ia64/sn/kernel/xpc.h
+++ b/arch/ia64/sn/kernel/xpc.h
@@ -57,7 +57,7 @@
#define XPC_NASID_FROM_W_B(_w, _b) (((_w) * 64 + (_b)) * 2)
#define XPC_HB_DEFAULT_INTERVAL 5 /* incr HB every x secs */
-#define XPC_HB_CHECK_DEFAULT_TIMEOUT 20 /* check HB every x secs */
+#define XPC_HB_CHECK_DEFAULT_INTERVAL 20 /* check HB every x secs */
/* define the process name of HB checker and the CPU it is pinned to */
#define XPC_HB_CHECK_THREAD_NAME "xpc_hb"
@@ -67,34 +67,82 @@
#define XPC_DISCOVERY_THREAD_NAME "xpc_discovery"
-#define XPC_HB_ALLOWED(_p, _v) ((_v)->heartbeating_to_mask & (1UL << (_p)))
-#define XPC_ALLOW_HB(_p, _v) (_v)->heartbeating_to_mask |= (1UL << (_p))
-#define XPC_DISALLOW_HB(_p, _v) (_v)->heartbeating_to_mask &= (~(1UL << (_p)))
-
-
/*
- * Reserved Page provided by SAL.
+ * the reserved page
+ *
+ * SAL reserves one page of memory per partition for XPC. Though a full page
+ * in length (16384 bytes), its starting address is not page aligned, but it
+ * is cacheline aligned. The reserved page consists of the following:
+ *
+ * reserved page header
+ *
+ * The first cacheline of the reserved page contains the header
+ * (struct xpc_rsvd_page). Before SAL initialization has completed,
+ * SAL has set up the following fields of the reserved page header:
+ * SAL_signature, SAL_version, partid, and nasids_size. The other
+ * fields are set up by XPC. (xpc_rsvd_page points to the local
+ * partition's reserved page.)
*
- * SAL provides one page per partition of reserved memory. When SAL
- * initialization is complete, SAL_signature, SAL_version, partid,
- * part_nasids, and mach_nasids are set.
+ * part_nasids mask
+ * mach_nasids mask
+ *
+ * SAL also sets up two bitmaps (or masks), one that reflects the actual
+ * nasids in this partition (part_nasids), and the other that reflects
+ * the actual nasids in the entire machine (mach_nasids). We're only
+ * interested in the even numbered nasids (which contain the processors
+ * and/or memory), so we only need half as many bits to represent the
+ * nasids. The part_nasids mask is located starting at the first cacheline
+ * following the reserved page header. The mach_nasids mask follows right
+ * after the part_nasids mask. The size in bytes of each mask is reflected
+ * by the reserved page header field 'nasids_size'. (Local partition's
+ * mask pointers are xpc_part_nasids and xpc_mach_nasids.)
+ *
+ * vars
+ * vars part
+ *
+ * Immediately following the mach_nasids mask are the XPC variables
+ * required by other partitions. First are those that are generic to all
+ * partitions (vars), followed on the next available cacheline by those
+ * which are partition specific (vars part). These are setup by XPC.
+ * (Local partition's vars pointers are xpc_vars and xpc_vars_part.)
*
* Note: Until vars_pa is set, the partition XPC code has not been initialized.
*/
struct xpc_rsvd_page {
- u64 SAL_signature; /* SAL unique signature */
- u64 SAL_version; /* SAL specified version */
- u8 partid; /* partition ID from SAL */
+ u64 SAL_signature; /* SAL: unique signature */
+ u64 SAL_version; /* SAL: version */
+ u8 partid; /* SAL: partition ID */
u8 version;
- u8 pad[6]; /* pad to u64 align */
+ u8 pad1[6]; /* align to next u64 in cacheline */
volatile u64 vars_pa;
- u64 part_nasids[XP_NASID_MASK_WORDS] ____cacheline_aligned;
- u64 mach_nasids[XP_NASID_MASK_WORDS] ____cacheline_aligned;
+ struct timespec stamp; /* time when reserved page was setup by XPC */
+ u64 pad2[9]; /* align to last u64 in cacheline */
+ u64 nasids_size; /* SAL: size of each nasid mask in bytes */
};
-#define XPC_RP_VERSION _XPC_VERSION(1,0) /* version 1.0 of the reserved page */
-#define XPC_RSVD_PAGE_ALIGNED_SIZE \
- (L1_CACHE_ALIGN(sizeof(struct xpc_rsvd_page)))
+#define XPC_RP_VERSION _XPC_VERSION(1,1) /* version 1.1 of the reserved page */
+
+#define XPC_SUPPORTS_RP_STAMP(_version) \
+ (_version >= _XPC_VERSION(1,1))
+
+/*
+ * compare stamps - the return value is:
+ *
+ * < 0, if stamp1 < stamp2
+ * = 0, if stamp1 == stamp2
+ * > 0, if stamp1 > stamp2
+ */
+static inline int
+xpc_compare_stamps(struct timespec *stamp1, struct timespec *stamp2)
+{
+ int ret;
+
+
+ if ((ret = stamp1->tv_sec - stamp2->tv_sec) == 0) {
+ ret = stamp1->tv_nsec - stamp2->tv_nsec;
+ }
+ return ret;
+}
/*
@@ -115,17 +163,64 @@ struct xpc_vars {
u8 version;
u64 heartbeat;
u64 heartbeating_to_mask;
- u64 kdb_status; /* 0 = machine running */
+ u64 heartbeat_offline; /* if 0, heartbeat should be changing */
int act_nasid;
int act_phys_cpuid;
u64 vars_part_pa;
u64 amos_page_pa; /* paddr of page of AMOs from MSPEC driver */
AMO_t *amos_page; /* vaddr of page of AMOs from MSPEC driver */
- AMO_t *act_amos; /* pointer to the first activation AMO */
};
-#define XPC_V_VERSION _XPC_VERSION(3,0) /* version 3.0 of the cross vars */
-#define XPC_VARS_ALIGNED_SIZE (L1_CACHE_ALIGN(sizeof(struct xpc_vars)))
+#define XPC_V_VERSION _XPC_VERSION(3,1) /* version 3.1 of the cross vars */
+
+#define XPC_SUPPORTS_DISENGAGE_REQUEST(_version) \
+ (_version >= _XPC_VERSION(3,1))
+
+
+static inline int
+xpc_hb_allowed(partid_t partid, struct xpc_vars *vars)
+{
+ return ((vars->heartbeating_to_mask & (1UL << partid)) != 0);
+}
+
+static inline void
+xpc_allow_hb(partid_t partid, struct xpc_vars *vars)
+{
+ u64 old_mask, new_mask;
+
+ do {
+ old_mask = vars->heartbeating_to_mask;
+ new_mask = (old_mask | (1UL << partid));
+ } while (cmpxchg(&vars->heartbeating_to_mask, old_mask, new_mask) !=
+ old_mask);
+}
+
+static inline void
+xpc_disallow_hb(partid_t partid, struct xpc_vars *vars)
+{
+ u64 old_mask, new_mask;
+
+ do {
+ old_mask = vars->heartbeating_to_mask;
+ new_mask = (old_mask & ~(1UL << partid));
+ } while (cmpxchg(&vars->heartbeating_to_mask, old_mask, new_mask) !=
+ old_mask);
+}
+
+
+/*
+ * The AMOs page consists of a number of AMO variables which are divided into
+ * four groups, The first two groups are used to identify an IRQ's sender.
+ * These two groups consist of 64 and 128 AMO variables respectively. The last
+ * two groups, consisting of just one AMO variable each, are used to identify
+ * the remote partitions that are currently engaged (from the viewpoint of
+ * the XPC running on the remote partition).
+ */
+#define XPC_NOTIFY_IRQ_AMOS 0
+#define XPC_ACTIVATE_IRQ_AMOS (XPC_NOTIFY_IRQ_AMOS + XP_MAX_PARTITIONS)
+#define XPC_ENGAGED_PARTITIONS_AMO (XPC_ACTIVATE_IRQ_AMOS + XP_NASID_MASK_WORDS)
+#define XPC_DISENGAGE_REQUEST_AMO (XPC_ENGAGED_PARTITIONS_AMO + 1)
+
/*
* The following structure describes the per partition specific variables.
@@ -165,6 +260,16 @@ struct xpc_vars_part {
#define XPC_VP_MAGIC2 0x0073726176435058L /* 'XPCvars\0'L (little endian) */
+/* the reserved page sizes and offsets */
+
+#define XPC_RP_HEADER_SIZE L1_CACHE_ALIGN(sizeof(struct xpc_rsvd_page))
+#define XPC_RP_VARS_SIZE L1_CACHE_ALIGN(sizeof(struct xpc_vars))
+
+#define XPC_RP_PART_NASIDS(_rp) (u64 *) ((u8 *) _rp + XPC_RP_HEADER_SIZE)
+#define XPC_RP_MACH_NASIDS(_rp) (XPC_RP_PART_NASIDS(_rp) + xp_nasid_mask_words)
+#define XPC_RP_VARS(_rp) ((struct xpc_vars *) XPC_RP_MACH_NASIDS(_rp) + xp_nasid_mask_words)
+#define XPC_RP_VARS_PART(_rp) (struct xpc_vars_part *) ((u8 *) XPC_RP_VARS(rp) + XPC_RP_VARS_SIZE)
+
/*
* Functions registered by add_timer() or called by kernel_thread() only
@@ -349,6 +454,9 @@ struct xpc_channel {
atomic_t n_on_msg_allocate_wq; /* #on msg allocation wait queue */
wait_queue_head_t msg_allocate_wq; /* msg allocation wait queue */
+ u8 delayed_IPI_flags; /* IPI flags received, but delayed */
+ /* action until channel disconnected */
+
/* queue of msg senders who want to be notified when msg received */
atomic_t n_to_notify; /* #of msg senders to notify */
@@ -358,7 +466,7 @@ struct xpc_channel {
void *key; /* pointer to user's key */
struct semaphore msg_to_pull_sema; /* next msg to pull serialization */
- struct semaphore teardown_sema; /* wait for teardown completion */
+ struct semaphore wdisconnect_sema; /* wait for channel disconnect */
struct xpc_openclose_args *local_openclose_args; /* args passed on */
/* opening or closing of channel */
@@ -410,6 +518,8 @@ struct xpc_channel {
#define XPC_C_DISCONNECTED 0x00002000 /* channel is disconnected */
#define XPC_C_DISCONNECTING 0x00004000 /* channel is being disconnected */
+#define XPC_C_DISCONNECTCALLOUT 0x00008000 /* chan disconnected callout made */
+#define XPC_C_WDISCONNECT 0x00010000 /* waiting for channel disconnect */
@@ -422,6 +532,8 @@ struct xpc_partition {
/* XPC HB infrastructure */
+ u8 remote_rp_version; /* version# of partition's rsvd pg */
+ struct timespec remote_rp_stamp;/* time when rsvd pg was initialized */
u64 remote_rp_pa; /* phys addr of partition's rsvd pg */
u64 remote_vars_pa; /* phys addr of partition's vars */
u64 remote_vars_part_pa; /* phys addr of partition's vars part */
@@ -432,14 +544,18 @@ struct xpc_partition {
u32 act_IRQ_rcvd; /* IRQs since activation */
spinlock_t act_lock; /* protect updating of act_state */
u8 act_state; /* from XPC HB viewpoint */
+ u8 remote_vars_version; /* version# of partition's vars */
enum xpc_retval reason; /* reason partition is deactivating */
int reason_line; /* line# deactivation initiated from */
int reactivate_nasid; /* nasid in partition to reactivate */
+ unsigned long disengage_request_timeout; /* timeout in jiffies */
+ struct timer_list disengage_request_timer;
+
/* XPC infrastructure referencing and teardown control */
- volatile u8 setup_state; /* infrastructure setup state */
+ volatile u8 setup_state; /* infrastructure setup state */
wait_queue_head_t teardown_wq; /* kthread waiting to teardown infra */
atomic_t references; /* #of references to infrastructure */
@@ -454,6 +570,7 @@ struct xpc_partition {
u8 nchannels; /* #of defined channels supported */
atomic_t nchannels_active; /* #of channels that are not DISCONNECTED */
+ atomic_t nchannels_engaged;/* #of channels engaged with remote part */
struct xpc_channel *channels;/* array of channel structures */
void *local_GPs_base; /* base address of kmalloc'd space */
@@ -518,6 +635,7 @@ struct xpc_partition {
#define XPC_P_TORNDOWN 0x03 /* infrastructure is torndown */
+
/*
* struct xpc_partition IPI_timer #of seconds to wait before checking for
* dropped IPIs. These occur whenever an IPI amo write doesn't complete until
@@ -526,6 +644,13 @@ struct xpc_partition {
#define XPC_P_DROPPED_IPI_WAIT (0.25 * HZ)
+/* number of seconds to wait for other partitions to disengage */
+#define XPC_DISENGAGE_REQUEST_DEFAULT_TIMELIMIT 90
+
+/* interval in seconds to print 'waiting disengagement' messages */
+#define XPC_DISENGAGE_PRINTMSG_INTERVAL 10
+
+
#define XPC_PARTID(_p) ((partid_t) ((_p) - &xpc_partitions[0]))
@@ -534,24 +659,20 @@ struct xpc_partition {
extern struct xpc_registration xpc_registrations[];
-/* >>> found in xpc_main.c only */
+/* found in xpc_main.c */
extern struct device *xpc_part;
extern struct device *xpc_chan;
+extern int xpc_disengage_request_timelimit;
extern irqreturn_t xpc_notify_IRQ_handler(int, void *, struct pt_regs *);
extern void xpc_dropped_IPI_check(struct xpc_partition *);
+extern void xpc_activate_partition(struct xpc_partition *);
extern void xpc_activate_kthreads(struct xpc_channel *, int);
extern void xpc_create_kthreads(struct xpc_channel *, int);
extern void xpc_disconnect_wait(int);
-/* found in xpc_main.c and efi-xpc.c */
-extern void xpc_activate_partition(struct xpc_partition *);
-
-
/* found in xpc_partition.c */
extern int xpc_exiting;
-extern int xpc_hb_interval;
-extern int xpc_hb_check_interval;
extern struct xpc_vars *xpc_vars;
extern struct xpc_rsvd_page *xpc_rsvd_page;
extern struct xpc_vars_part *xpc_vars_part;
@@ -561,6 +682,7 @@ extern struct xpc_rsvd_page *xpc_rsvd_page_init(void);
extern void xpc_allow_IPI_ops(void);
extern void xpc_restrict_IPI_ops(void);
extern int xpc_identify_act_IRQ_sender(void);
+extern int xpc_partition_disengaged(struct xpc_partition *);
extern enum xpc_retval xpc_mark_partition_active(struct xpc_partition *);
extern void xpc_mark_partition_inactive(struct xpc_partition *);
extern void xpc_discovery(void);
@@ -585,8 +707,8 @@ extern void xpc_connected_callout(struct xpc_channel *);
extern void xpc_deliver_msg(struct xpc_channel *);
extern void xpc_disconnect_channel(const int, struct xpc_channel *,
enum xpc_retval, unsigned long *);
-extern void xpc_disconnected_callout(struct xpc_channel *);
-extern void xpc_partition_down(struct xpc_partition *, enum xpc_retval);
+extern void xpc_disconnecting_callout(struct xpc_channel *);
+extern void xpc_partition_going_down(struct xpc_partition *, enum xpc_retval);
extern void xpc_teardown_infrastructure(struct xpc_partition *);
@@ -674,6 +796,157 @@ xpc_part_ref(struct xpc_partition *part)
/*
+ * This next set of inlines are used to keep track of when a partition is
+ * potentially engaged in accessing memory belonging to another partition.
+ */
+
+static inline void
+xpc_mark_partition_engaged(struct xpc_partition *part)
+{
+ unsigned long irq_flags;
+ AMO_t *amo = (AMO_t *) __va(part->remote_amos_page_pa +
+ (XPC_ENGAGED_PARTITIONS_AMO * sizeof(AMO_t)));
+
+
+ local_irq_save(irq_flags);
+
+ /* set bit corresponding to our partid in remote partition's AMO */
+ FETCHOP_STORE_OP(TO_AMO((u64) &amo->variable), FETCHOP_OR,
+ (1UL << sn_partition_id));
+ /*
+ * We must always use the nofault function regardless of whether we
+ * are on a Shub 1.1 system or a Shub 1.2 slice 0xc processor. If we
+ * didn't, we'd never know that the other partition is down and would
+ * keep sending IPIs and AMOs to it until the heartbeat times out.
+ */
+ (void) xp_nofault_PIOR((u64 *) GLOBAL_MMR_ADDR(NASID_GET(&amo->
+ variable), xp_nofault_PIOR_target));
+
+ local_irq_restore(irq_flags);
+}
+
+static inline void
+xpc_mark_partition_disengaged(struct xpc_partition *part)
+{
+ unsigned long irq_flags;
+ AMO_t *amo = (AMO_t *) __va(part->remote_amos_page_pa +
+ (XPC_ENGAGED_PARTITIONS_AMO * sizeof(AMO_t)));
+
+
+ local_irq_save(irq_flags);
+
+ /* clear bit corresponding to our partid in remote partition's AMO */
+ FETCHOP_STORE_OP(TO_AMO((u64) &amo->variable), FETCHOP_AND,
+ ~(1UL << sn_partition_id));
+ /*
+ * We must always use the nofault function regardless of whether we
+ * are on a Shub 1.1 system or a Shub 1.2 slice 0xc processor. If we
+ * didn't, we'd never know that the other partition is down and would
+ * keep sending IPIs and AMOs to it until the heartbeat times out.
+ */
+ (void) xp_nofault_PIOR((u64 *) GLOBAL_MMR_ADDR(NASID_GET(&amo->
+ variable), xp_nofault_PIOR_target));
+
+ local_irq_restore(irq_flags);
+}
+
+static inline void
+xpc_request_partition_disengage(struct xpc_partition *part)
+{
+ unsigned long irq_flags;
+ AMO_t *amo = (AMO_t *) __va(part->remote_amos_page_pa +
+ (XPC_DISENGAGE_REQUEST_AMO * sizeof(AMO_t)));
+
+
+ local_irq_save(irq_flags);
+
+ /* set bit corresponding to our partid in remote partition's AMO */
+ FETCHOP_STORE_OP(TO_AMO((u64) &amo->variable), FETCHOP_OR,
+ (1UL << sn_partition_id));
+ /*
+ * We must always use the nofault function regardless of whether we
+ * are on a Shub 1.1 system or a Shub 1.2 slice 0xc processor. If we
+ * didn't, we'd never know that the other partition is down and would
+ * keep sending IPIs and AMOs to it until the heartbeat times out.
+ */
+ (void) xp_nofault_PIOR((u64 *) GLOBAL_MMR_ADDR(NASID_GET(&amo->
+ variable), xp_nofault_PIOR_target));
+
+ local_irq_restore(irq_flags);
+}
+
+static inline void
+xpc_cancel_partition_disengage_request(struct xpc_partition *part)
+{
+ unsigned long irq_flags;
+ AMO_t *amo = (AMO_t *) __va(part->remote_amos_page_pa +
+ (XPC_DISENGAGE_REQUEST_AMO * sizeof(AMO_t)));
+
+
+ local_irq_save(irq_flags);
+
+ /* clear bit corresponding to our partid in remote partition's AMO */
+ FETCHOP_STORE_OP(TO_AMO((u64) &amo->variable), FETCHOP_AND,
+ ~(1UL << sn_partition_id));
+ /*
+ * We must always use the nofault function regardless of whether we
+ * are on a Shub 1.1 system or a Shub 1.2 slice 0xc processor. If we
+ * didn't, we'd never know that the other partition is down and would
+ * keep sending IPIs and AMOs to it until the heartbeat times out.
+ */
+ (void) xp_nofault_PIOR((u64 *) GLOBAL_MMR_ADDR(NASID_GET(&amo->
+ variable), xp_nofault_PIOR_target));
+
+ local_irq_restore(irq_flags);
+}
+
+static inline u64
+xpc_partition_engaged(u64 partid_mask)
+{
+ AMO_t *amo = xpc_vars->amos_page + XPC_ENGAGED_PARTITIONS_AMO;
+
+
+ /* return our partition's AMO variable ANDed with partid_mask */
+ return (FETCHOP_LOAD_OP(TO_AMO((u64) &amo->variable), FETCHOP_LOAD) &
+ partid_mask);
+}
+
+static inline u64
+xpc_partition_disengage_requested(u64 partid_mask)
+{
+ AMO_t *amo = xpc_vars->amos_page + XPC_DISENGAGE_REQUEST_AMO;
+
+
+ /* return our partition's AMO variable ANDed with partid_mask */
+ return (FETCHOP_LOAD_OP(TO_AMO((u64) &amo->variable), FETCHOP_LOAD) &
+ partid_mask);
+}
+
+static inline void
+xpc_clear_partition_engaged(u64 partid_mask)
+{
+ AMO_t *amo = xpc_vars->amos_page + XPC_ENGAGED_PARTITIONS_AMO;
+
+
+ /* clear bit(s) based on partid_mask in our partition's AMO */
+ FETCHOP_STORE_OP(TO_AMO((u64) &amo->variable), FETCHOP_AND,
+ ~partid_mask);
+}
+
+static inline void
+xpc_clear_partition_disengage_request(u64 partid_mask)
+{
+ AMO_t *amo = xpc_vars->amos_page + XPC_DISENGAGE_REQUEST_AMO;
+
+
+ /* clear bit(s) based on partid_mask in our partition's AMO */
+ FETCHOP_STORE_OP(TO_AMO((u64) &amo->variable), FETCHOP_AND,
+ ~partid_mask);
+}
+
+
+
+/*
* The following set of macros and inlines are used for the sending and
* receiving of IPIs (also known as IRQs). There are two flavors of IPIs,
* one that is associated with partition activity (SGI_XPC_ACTIVATE) and
@@ -722,13 +995,13 @@ xpc_IPI_send(AMO_t *amo, u64 flag, int nasid, int phys_cpuid, int vector)
* Flag the appropriate AMO variable and send an IPI to the specified node.
*/
static inline void
-xpc_activate_IRQ_send(u64 amos_page, int from_nasid, int to_nasid,
+xpc_activate_IRQ_send(u64 amos_page_pa, int from_nasid, int to_nasid,
int to_phys_cpuid)
{
int w_index = XPC_NASID_W_INDEX(from_nasid);
int b_index = XPC_NASID_B_INDEX(from_nasid);
- AMO_t *amos = (AMO_t *) __va(amos_page +
- (XP_MAX_PARTITIONS * sizeof(AMO_t)));
+ AMO_t *amos = (AMO_t *) __va(amos_page_pa +
+ (XPC_ACTIVATE_IRQ_AMOS * sizeof(AMO_t)));
(void) xpc_IPI_send(&amos[w_index], (1UL << b_index), to_nasid,
@@ -756,6 +1029,13 @@ xpc_IPI_send_reactivate(struct xpc_partition *part)
xpc_vars->act_nasid, xpc_vars->act_phys_cpuid);
}
+static inline void
+xpc_IPI_send_disengage(struct xpc_partition *part)
+{
+ xpc_activate_IRQ_send(part->remote_amos_page_pa, cnodeid_to_nasid(0),
+ part->remote_act_nasid, part->remote_act_phys_cpuid);
+}
+
/*
* IPIs associated with SGI_XPC_NOTIFY IRQ.
@@ -836,6 +1116,7 @@ xpc_notify_IRQ_send_local(struct xpc_channel *ch, u8 ipi_flag,
/* given an AMO variable and a channel#, get its associated IPI flags */
#define XPC_GET_IPI_FLAGS(_amo, _c) ((u8) (((_amo) >> ((_c) * 8)) & 0xff))
+#define XPC_SET_IPI_FLAGS(_amo, _c, _f) (_amo) |= ((u64) (_f) << ((_c) * 8))
#define XPC_ANY_OPENCLOSE_IPI_FLAGS_SET(_amo) ((_amo) & 0x0f0f0f0f0f0f0f0f)
#define XPC_ANY_MSG_IPI_FLAGS_SET(_amo) ((_amo) & 0x1010101010101010)
@@ -903,17 +1184,18 @@ xpc_IPI_send_local_msgrequest(struct xpc_channel *ch)
* cacheable mapping for the entire region. This will prevent speculative
* reading of cached copies of our lines from being issued which will cause
* a PI FSB Protocol error to be generated by the SHUB. For XPC, we need 64
- * (XP_MAX_PARTITIONS) AMO variables for message notification (xpc_main.c)
- * and an additional 16 AMO variables for partition activation (xpc_hb.c).
+ * AMO variables (based on XP_MAX_PARTITIONS) for message notification and an
+ * additional 128 AMO variables (based on XP_NASID_MASK_WORDS) for partition
+ * activation and 2 AMO variables for partition deactivation.
*/
static inline AMO_t *
-xpc_IPI_init(partid_t partid)
+xpc_IPI_init(int index)
{
- AMO_t *part_amo = xpc_vars->amos_page + partid;
+ AMO_t *amo = xpc_vars->amos_page + index;
- xpc_IPI_receive(part_amo);
- return part_amo;
+ (void) xpc_IPI_receive(amo); /* clear AMO variable */
+ return amo;
}
@@ -939,7 +1221,7 @@ xpc_map_bte_errors(bte_result_t error)
static inline void *
-xpc_kmalloc_cacheline_aligned(size_t size, int flags, void **base)
+xpc_kmalloc_cacheline_aligned(size_t size, gfp_t flags, void **base)
{
/* see if kmalloc will give us cachline aligned memory by default */
*base = kmalloc(size, flags);
diff --git a/arch/ia64/sn/kernel/xpc_channel.c b/arch/ia64/sn/kernel/xpc_channel.c
index 94698bea7be0..abf4fc2a87bb 100644
--- a/arch/ia64/sn/kernel/xpc_channel.c
+++ b/arch/ia64/sn/kernel/xpc_channel.c
@@ -57,6 +57,7 @@ xpc_initialize_channels(struct xpc_partition *part, partid_t partid)
spin_lock_init(&ch->lock);
sema_init(&ch->msg_to_pull_sema, 1); /* mutex */
+ sema_init(&ch->wdisconnect_sema, 0); /* event wait */
atomic_set(&ch->n_on_msg_allocate_wq, 0);
init_waitqueue_head(&ch->msg_allocate_wq);
@@ -166,6 +167,7 @@ xpc_setup_infrastructure(struct xpc_partition *part)
xpc_initialize_channels(part, partid);
atomic_set(&part->nchannels_active, 0);
+ atomic_set(&part->nchannels_engaged, 0);
/* local_IPI_amo were set to 0 by an earlier memset() */
@@ -555,8 +557,6 @@ xpc_allocate_msgqueues(struct xpc_channel *ch)
sema_init(&ch->notify_queue[i].sema, 0);
}
- sema_init(&ch->teardown_sema, 0); /* event wait */
-
spin_lock_irqsave(&ch->lock, irq_flags);
ch->flags |= XPC_C_SETUP;
spin_unlock_irqrestore(&ch->lock, irq_flags);
@@ -626,6 +626,55 @@ xpc_process_connect(struct xpc_channel *ch, unsigned long *irq_flags)
/*
+ * Notify those who wanted to be notified upon delivery of their message.
+ */
+static void
+xpc_notify_senders(struct xpc_channel *ch, enum xpc_retval reason, s64 put)
+{
+ struct xpc_notify *notify;
+ u8 notify_type;
+ s64 get = ch->w_remote_GP.get - 1;
+
+
+ while (++get < put && atomic_read(&ch->n_to_notify) > 0) {
+
+ notify = &ch->notify_queue[get % ch->local_nentries];
+
+ /*
+ * See if the notify entry indicates it was associated with
+ * a message who's sender wants to be notified. It is possible
+ * that it is, but someone else is doing or has done the
+ * notification.
+ */
+ notify_type = notify->type;
+ if (notify_type == 0 ||
+ cmpxchg(&notify->type, notify_type, 0) !=
+ notify_type) {
+ continue;
+ }
+
+ DBUG_ON(notify_type != XPC_N_CALL);
+
+ atomic_dec(&ch->n_to_notify);
+
+ if (notify->func != NULL) {
+ dev_dbg(xpc_chan, "notify->func() called, notify=0x%p, "
+ "msg_number=%ld, partid=%d, channel=%d\n",
+ (void *) notify, get, ch->partid, ch->number);
+
+ notify->func(reason, ch->partid, ch->number,
+ notify->key);
+
+ dev_dbg(xpc_chan, "notify->func() returned, "
+ "notify=0x%p, msg_number=%ld, partid=%d, "
+ "channel=%d\n", (void *) notify, get,
+ ch->partid, ch->number);
+ }
+ }
+}
+
+
+/*
* Free up message queues and other stuff that were allocated for the specified
* channel.
*
@@ -669,9 +718,6 @@ xpc_free_msgqueues(struct xpc_channel *ch)
ch->remote_msgqueue = NULL;
kfree(ch->notify_queue);
ch->notify_queue = NULL;
-
- /* in case someone is waiting for the teardown to complete */
- up(&ch->teardown_sema);
}
}
@@ -683,7 +729,7 @@ static void
xpc_process_disconnect(struct xpc_channel *ch, unsigned long *irq_flags)
{
struct xpc_partition *part = &xpc_partitions[ch->partid];
- u32 ch_flags = ch->flags;
+ u32 channel_was_connected = (ch->flags & XPC_C_WASCONNECTED);
DBUG_ON(!spin_is_locked(&ch->lock));
@@ -701,12 +747,13 @@ xpc_process_disconnect(struct xpc_channel *ch, unsigned long *irq_flags)
}
DBUG_ON(atomic_read(&ch->kthreads_assigned) != 0);
- /* it's now safe to free the channel's message queues */
-
- xpc_free_msgqueues(ch);
- DBUG_ON(ch->flags & XPC_C_SETUP);
+ if (part->act_state == XPC_P_DEACTIVATING) {
+ /* can't proceed until the other side disengages from us */
+ if (xpc_partition_engaged(1UL << ch->partid)) {
+ return;
+ }
- if (part->act_state != XPC_P_DEACTIVATING) {
+ } else {
/* as long as the other side is up do the full protocol */
@@ -724,16 +771,42 @@ xpc_process_disconnect(struct xpc_channel *ch, unsigned long *irq_flags)
}
}
+ /* wake those waiting for notify completion */
+ if (atomic_read(&ch->n_to_notify) > 0) {
+ /* >>> we do callout while holding ch->lock */
+ xpc_notify_senders(ch, ch->reason, ch->w_local_GP.put);
+ }
+
/* both sides are disconnected now */
- ch->flags = XPC_C_DISCONNECTED; /* clear all flags, but this one */
+ /* it's now safe to free the channel's message queues */
+ xpc_free_msgqueues(ch);
+
+ /* mark disconnected, clear all other flags except XPC_C_WDISCONNECT */
+ ch->flags = (XPC_C_DISCONNECTED | (ch->flags & XPC_C_WDISCONNECT));
atomic_dec(&part->nchannels_active);
- if (ch_flags & XPC_C_WASCONNECTED) {
+ if (channel_was_connected) {
dev_info(xpc_chan, "channel %d to partition %d disconnected, "
"reason=%d\n", ch->number, ch->partid, ch->reason);
}
+
+ if (ch->flags & XPC_C_WDISCONNECT) {
+ spin_unlock_irqrestore(&ch->lock, *irq_flags);
+ up(&ch->wdisconnect_sema);
+ spin_lock_irqsave(&ch->lock, *irq_flags);
+
+ } else if (ch->delayed_IPI_flags) {
+ if (part->act_state != XPC_P_DEACTIVATING) {
+ /* time to take action on any delayed IPI flags */
+ spin_lock(&part->IPI_lock);
+ XPC_SET_IPI_FLAGS(part->local_IPI_amo, ch->number,
+ ch->delayed_IPI_flags);
+ spin_unlock(&part->IPI_lock);
+ }
+ ch->delayed_IPI_flags = 0;
+ }
}
@@ -754,6 +827,19 @@ xpc_process_openclose_IPI(struct xpc_partition *part, int ch_number,
spin_lock_irqsave(&ch->lock, irq_flags);
+again:
+
+ if ((ch->flags & XPC_C_DISCONNECTED) &&
+ (ch->flags & XPC_C_WDISCONNECT)) {
+ /*
+ * Delay processing IPI flags until thread waiting disconnect
+ * has had a chance to see that the channel is disconnected.
+ */
+ ch->delayed_IPI_flags |= IPI_flags;
+ spin_unlock_irqrestore(&ch->lock, irq_flags);
+ return;
+ }
+
if (IPI_flags & XPC_IPI_CLOSEREQUEST) {
@@ -764,7 +850,7 @@ xpc_process_openclose_IPI(struct xpc_partition *part, int ch_number,
/*
* If RCLOSEREQUEST is set, we're probably waiting for
* RCLOSEREPLY. We should find it and a ROPENREQUEST packed
- * with this RCLOSEQREUQEST in the IPI_flags.
+ * with this RCLOSEREQUEST in the IPI_flags.
*/
if (ch->flags & XPC_C_RCLOSEREQUEST) {
@@ -779,14 +865,22 @@ xpc_process_openclose_IPI(struct xpc_partition *part, int ch_number,
/* both sides have finished disconnecting */
xpc_process_disconnect(ch, &irq_flags);
+ DBUG_ON(!(ch->flags & XPC_C_DISCONNECTED));
+ goto again;
}
if (ch->flags & XPC_C_DISCONNECTED) {
- // >>> explain this section
-
if (!(IPI_flags & XPC_IPI_OPENREQUEST)) {
- DBUG_ON(part->act_state !=
- XPC_P_DEACTIVATING);
+ if ((XPC_GET_IPI_FLAGS(part->local_IPI_amo,
+ ch_number) & XPC_IPI_OPENREQUEST)) {
+
+ DBUG_ON(ch->delayed_IPI_flags != 0);
+ spin_lock(&part->IPI_lock);
+ XPC_SET_IPI_FLAGS(part->local_IPI_amo,
+ ch_number,
+ XPC_IPI_CLOSEREQUEST);
+ spin_unlock(&part->IPI_lock);
+ }
spin_unlock_irqrestore(&ch->lock, irq_flags);
return;
}
@@ -816,9 +910,13 @@ xpc_process_openclose_IPI(struct xpc_partition *part, int ch_number,
}
XPC_DISCONNECT_CHANNEL(ch, reason, &irq_flags);
- } else {
- xpc_process_disconnect(ch, &irq_flags);
+
+ DBUG_ON(IPI_flags & XPC_IPI_CLOSEREPLY);
+ spin_unlock_irqrestore(&ch->lock, irq_flags);
+ return;
}
+
+ xpc_process_disconnect(ch, &irq_flags);
}
@@ -834,7 +932,20 @@ xpc_process_openclose_IPI(struct xpc_partition *part, int ch_number,
}
DBUG_ON(!(ch->flags & XPC_C_CLOSEREQUEST));
- DBUG_ON(!(ch->flags & XPC_C_RCLOSEREQUEST));
+
+ if (!(ch->flags & XPC_C_RCLOSEREQUEST)) {
+ if ((XPC_GET_IPI_FLAGS(part->local_IPI_amo, ch_number)
+ & XPC_IPI_CLOSEREQUEST)) {
+
+ DBUG_ON(ch->delayed_IPI_flags != 0);
+ spin_lock(&part->IPI_lock);
+ XPC_SET_IPI_FLAGS(part->local_IPI_amo,
+ ch_number, XPC_IPI_CLOSEREPLY);
+ spin_unlock(&part->IPI_lock);
+ }
+ spin_unlock_irqrestore(&ch->lock, irq_flags);
+ return;
+ }
ch->flags |= XPC_C_RCLOSEREPLY;
@@ -852,8 +963,14 @@ xpc_process_openclose_IPI(struct xpc_partition *part, int ch_number,
"channel=%d\n", args->msg_size, args->local_nentries,
ch->partid, ch->number);
- if ((ch->flags & XPC_C_DISCONNECTING) ||
- part->act_state == XPC_P_DEACTIVATING) {
+ if (part->act_state == XPC_P_DEACTIVATING ||
+ (ch->flags & XPC_C_ROPENREQUEST)) {
+ spin_unlock_irqrestore(&ch->lock, irq_flags);
+ return;
+ }
+
+ if (ch->flags & (XPC_C_DISCONNECTING | XPC_C_WDISCONNECT)) {
+ ch->delayed_IPI_flags |= XPC_IPI_OPENREQUEST;
spin_unlock_irqrestore(&ch->lock, irq_flags);
return;
}
@@ -867,8 +984,11 @@ xpc_process_openclose_IPI(struct xpc_partition *part, int ch_number,
* msg_size = size of channel's messages in bytes
* local_nentries = remote partition's local_nentries
*/
- DBUG_ON(args->msg_size == 0);
- DBUG_ON(args->local_nentries == 0);
+ if (args->msg_size == 0 || args->local_nentries == 0) {
+ /* assume OPENREQUEST was delayed by mistake */
+ spin_unlock_irqrestore(&ch->lock, irq_flags);
+ return;
+ }
ch->flags |= (XPC_C_ROPENREQUEST | XPC_C_CONNECTING);
ch->remote_nentries = args->local_nentries;
@@ -906,7 +1026,13 @@ xpc_process_openclose_IPI(struct xpc_partition *part, int ch_number,
spin_unlock_irqrestore(&ch->lock, irq_flags);
return;
}
- DBUG_ON(!(ch->flags & XPC_C_OPENREQUEST));
+ if (!(ch->flags & XPC_C_OPENREQUEST)) {
+ XPC_DISCONNECT_CHANNEL(ch, xpcOpenCloseError,
+ &irq_flags);
+ spin_unlock_irqrestore(&ch->lock, irq_flags);
+ return;
+ }
+
DBUG_ON(!(ch->flags & XPC_C_ROPENREQUEST));
DBUG_ON(ch->flags & XPC_C_CONNECTED);
@@ -960,8 +1086,8 @@ xpc_connect_channel(struct xpc_channel *ch)
struct xpc_registration *registration = &xpc_registrations[ch->number];
- if (down_interruptible(&registration->sema) != 0) {
- return xpcInterrupted;
+ if (down_trylock(&registration->sema) != 0) {
+ return xpcRetry;
}
if (!XPC_CHANNEL_REGISTERED(ch->number)) {
@@ -1040,55 +1166,6 @@ xpc_connect_channel(struct xpc_channel *ch)
/*
- * Notify those who wanted to be notified upon delivery of their message.
- */
-static void
-xpc_notify_senders(struct xpc_channel *ch, enum xpc_retval reason, s64 put)
-{
- struct xpc_notify *notify;
- u8 notify_type;
- s64 get = ch->w_remote_GP.get - 1;
-
-
- while (++get < put && atomic_read(&ch->n_to_notify) > 0) {
-
- notify = &ch->notify_queue[get % ch->local_nentries];
-
- /*
- * See if the notify entry indicates it was associated with
- * a message who's sender wants to be notified. It is possible
- * that it is, but someone else is doing or has done the
- * notification.
- */
- notify_type = notify->type;
- if (notify_type == 0 ||
- cmpxchg(&notify->type, notify_type, 0) !=
- notify_type) {
- continue;
- }
-
- DBUG_ON(notify_type != XPC_N_CALL);
-
- atomic_dec(&ch->n_to_notify);
-
- if (notify->func != NULL) {
- dev_dbg(xpc_chan, "notify->func() called, notify=0x%p, "
- "msg_number=%ld, partid=%d, channel=%d\n",
- (void *) notify, get, ch->partid, ch->number);
-
- notify->func(reason, ch->partid, ch->number,
- notify->key);
-
- dev_dbg(xpc_chan, "notify->func() returned, "
- "notify=0x%p, msg_number=%ld, partid=%d, "
- "channel=%d\n", (void *) notify, get,
- ch->partid, ch->number);
- }
- }
-}
-
-
-/*
* Clear some of the msg flags in the local message queue.
*/
static inline void
@@ -1240,6 +1317,7 @@ xpc_process_channel_activity(struct xpc_partition *part)
u64 IPI_amo, IPI_flags;
struct xpc_channel *ch;
int ch_number;
+ u32 ch_flags;
IPI_amo = xpc_get_IPI_flags(part);
@@ -1266,8 +1344,9 @@ xpc_process_channel_activity(struct xpc_partition *part)
xpc_process_openclose_IPI(part, ch_number, IPI_flags);
}
+ ch_flags = ch->flags; /* need an atomic snapshot of flags */
- if (ch->flags & XPC_C_DISCONNECTING) {
+ if (ch_flags & XPC_C_DISCONNECTING) {
spin_lock_irqsave(&ch->lock, irq_flags);
xpc_process_disconnect(ch, &irq_flags);
spin_unlock_irqrestore(&ch->lock, irq_flags);
@@ -1278,9 +1357,9 @@ xpc_process_channel_activity(struct xpc_partition *part)
continue;
}
- if (!(ch->flags & XPC_C_CONNECTED)) {
- if (!(ch->flags & XPC_C_OPENREQUEST)) {
- DBUG_ON(ch->flags & XPC_C_SETUP);
+ if (!(ch_flags & XPC_C_CONNECTED)) {
+ if (!(ch_flags & XPC_C_OPENREQUEST)) {
+ DBUG_ON(ch_flags & XPC_C_SETUP);
(void) xpc_connect_channel(ch);
} else {
spin_lock_irqsave(&ch->lock, irq_flags);
@@ -1305,8 +1384,8 @@ xpc_process_channel_activity(struct xpc_partition *part)
/*
- * XPC's heartbeat code calls this function to inform XPC that a partition has
- * gone down. XPC responds by tearing down the XPartition Communication
+ * XPC's heartbeat code calls this function to inform XPC that a partition is
+ * going down. XPC responds by tearing down the XPartition Communication
* infrastructure used for the just downed partition.
*
* XPC's heartbeat code will never call this function and xpc_partition_up()
@@ -1314,7 +1393,7 @@ xpc_process_channel_activity(struct xpc_partition *part)
* at the same time.
*/
void
-xpc_partition_down(struct xpc_partition *part, enum xpc_retval reason)
+xpc_partition_going_down(struct xpc_partition *part, enum xpc_retval reason)
{
unsigned long irq_flags;
int ch_number;
@@ -1330,12 +1409,11 @@ xpc_partition_down(struct xpc_partition *part, enum xpc_retval reason)
}
- /* disconnect all channels associated with the downed partition */
+ /* disconnect channels associated with the partition going down */
for (ch_number = 0; ch_number < part->nchannels; ch_number++) {
ch = &part->channels[ch_number];
-
xpc_msgqueue_ref(ch);
spin_lock_irqsave(&ch->lock, irq_flags);
@@ -1370,6 +1448,7 @@ xpc_teardown_infrastructure(struct xpc_partition *part)
* this partition.
*/
+ DBUG_ON(atomic_read(&part->nchannels_engaged) != 0);
DBUG_ON(atomic_read(&part->nchannels_active) != 0);
DBUG_ON(part->setup_state != XPC_P_SETUP);
part->setup_state = XPC_P_WTEARDOWN;
@@ -1428,19 +1507,11 @@ xpc_initiate_connect(int ch_number)
if (xpc_part_ref(part)) {
ch = &part->channels[ch_number];
- if (!(ch->flags & XPC_C_DISCONNECTING)) {
- DBUG_ON(ch->flags & XPC_C_OPENREQUEST);
- DBUG_ON(ch->flags & XPC_C_CONNECTED);
- DBUG_ON(ch->flags & XPC_C_SETUP);
-
- /*
- * Initiate the establishment of a connection
- * on the newly registered channel to the
- * remote partition.
- */
- xpc_wakeup_channel_mgr(part);
- }
-
+ /*
+ * Initiate the establishment of a connection on the
+ * newly registered channel to the remote partition.
+ */
+ xpc_wakeup_channel_mgr(part);
xpc_part_deref(part);
}
}
@@ -1450,9 +1521,6 @@ xpc_initiate_connect(int ch_number)
void
xpc_connected_callout(struct xpc_channel *ch)
{
- unsigned long irq_flags;
-
-
/* let the registerer know that a connection has been established */
if (ch->func != NULL) {
@@ -1465,10 +1533,6 @@ xpc_connected_callout(struct xpc_channel *ch)
dev_dbg(xpc_chan, "ch->func() returned, reason=xpcConnected, "
"partid=%d, channel=%d\n", ch->partid, ch->number);
}
-
- spin_lock_irqsave(&ch->lock, irq_flags);
- ch->flags |= XPC_C_CONNECTCALLOUT;
- spin_unlock_irqrestore(&ch->lock, irq_flags);
}
@@ -1506,8 +1570,12 @@ xpc_initiate_disconnect(int ch_number)
spin_lock_irqsave(&ch->lock, irq_flags);
- XPC_DISCONNECT_CHANNEL(ch, xpcUnregistering,
+ if (!(ch->flags & XPC_C_DISCONNECTED)) {
+ ch->flags |= XPC_C_WDISCONNECT;
+
+ XPC_DISCONNECT_CHANNEL(ch, xpcUnregistering,
&irq_flags);
+ }
spin_unlock_irqrestore(&ch->lock, irq_flags);
@@ -1523,8 +1591,9 @@ xpc_initiate_disconnect(int ch_number)
/*
* To disconnect a channel, and reflect it back to all who may be waiting.
*
- * >>> An OPEN is not allowed until XPC_C_DISCONNECTING is cleared by
- * >>> xpc_free_msgqueues().
+ * An OPEN is not allowed until XPC_C_DISCONNECTING is cleared by
+ * xpc_process_disconnect(), and if set, XPC_C_WDISCONNECT is cleared by
+ * xpc_disconnect_wait().
*
* THE CHANNEL IS TO BE LOCKED BY THE CALLER AND WILL REMAIN LOCKED UPON RETURN.
*/
@@ -1532,7 +1601,7 @@ void
xpc_disconnect_channel(const int line, struct xpc_channel *ch,
enum xpc_retval reason, unsigned long *irq_flags)
{
- u32 flags;
+ u32 channel_was_connected = (ch->flags & XPC_C_CONNECTED);
DBUG_ON(!spin_is_locked(&ch->lock));
@@ -1547,61 +1616,53 @@ xpc_disconnect_channel(const int line, struct xpc_channel *ch,
XPC_SET_REASON(ch, reason, line);
- flags = ch->flags;
+ ch->flags |= (XPC_C_CLOSEREQUEST | XPC_C_DISCONNECTING);
/* some of these may not have been set */
ch->flags &= ~(XPC_C_OPENREQUEST | XPC_C_OPENREPLY |
XPC_C_ROPENREQUEST | XPC_C_ROPENREPLY |
XPC_C_CONNECTING | XPC_C_CONNECTED);
- ch->flags |= (XPC_C_CLOSEREQUEST | XPC_C_DISCONNECTING);
xpc_IPI_send_closerequest(ch, irq_flags);
- if (flags & XPC_C_CONNECTED) {
+ if (channel_was_connected) {
ch->flags |= XPC_C_WASCONNECTED;
}
+ spin_unlock_irqrestore(&ch->lock, *irq_flags);
+
+ /* wake all idle kthreads so they can exit */
if (atomic_read(&ch->kthreads_idle) > 0) {
- /* wake all idle kthreads so they can exit */
wake_up_all(&ch->idle_wq);
}
- spin_unlock_irqrestore(&ch->lock, *irq_flags);
-
-
/* wake those waiting to allocate an entry from the local msg queue */
-
if (atomic_read(&ch->n_on_msg_allocate_wq) > 0) {
wake_up(&ch->msg_allocate_wq);
}
- /* wake those waiting for notify completion */
-
- if (atomic_read(&ch->n_to_notify) > 0) {
- xpc_notify_senders(ch, reason, ch->w_local_GP.put);
- }
-
spin_lock_irqsave(&ch->lock, *irq_flags);
}
void
-xpc_disconnected_callout(struct xpc_channel *ch)
+xpc_disconnecting_callout(struct xpc_channel *ch)
{
/*
- * Let the channel's registerer know that the channel is now
+ * Let the channel's registerer know that the channel is being
* disconnected. We don't want to do this if the registerer was never
- * informed of a connection being made, unless the disconnect was for
- * abnormal reasons.
+ * informed of a connection being made.
*/
if (ch->func != NULL) {
- dev_dbg(xpc_chan, "ch->func() called, reason=%d, partid=%d, "
- "channel=%d\n", ch->reason, ch->partid, ch->number);
+ dev_dbg(xpc_chan, "ch->func() called, reason=xpcDisconnecting,"
+ " partid=%d, channel=%d\n", ch->partid, ch->number);
- ch->func(ch->reason, ch->partid, ch->number, NULL, ch->key);
+ ch->func(xpcDisconnecting, ch->partid, ch->number, NULL,
+ ch->key);
- dev_dbg(xpc_chan, "ch->func() returned, reason=%d, partid=%d, "
- "channel=%d\n", ch->reason, ch->partid, ch->number);
+ dev_dbg(xpc_chan, "ch->func() returned, reason="
+ "xpcDisconnecting, partid=%d, channel=%d\n",
+ ch->partid, ch->number);
}
}
@@ -1848,7 +1909,7 @@ xpc_send_msg(struct xpc_channel *ch, struct xpc_msg *msg, u8 notify_type,
xpc_notify_func func, void *key)
{
enum xpc_retval ret = xpcSuccess;
- struct xpc_notify *notify = NULL; // >>> to keep the compiler happy!!
+ struct xpc_notify *notify = notify;
s64 put, msg_number = msg->number;
diff --git a/arch/ia64/sn/kernel/xpc_main.c b/arch/ia64/sn/kernel/xpc_main.c
index ed7c21586e98..b617236524c6 100644
--- a/arch/ia64/sn/kernel/xpc_main.c
+++ b/arch/ia64/sn/kernel/xpc_main.c
@@ -54,8 +54,10 @@
#include <linux/interrupt.h>
#include <linux/slab.h>
#include <linux/delay.h>
+#include <linux/reboot.h>
#include <asm/sn/intr.h>
#include <asm/sn/sn_sal.h>
+#include <asm/kdebug.h>
#include <asm/uaccess.h>
#include "xpc.h"
@@ -82,11 +84,17 @@ struct device *xpc_chan = &xpc_chan_dbg_subname;
/* systune related variables for /proc/sys directories */
-static int xpc_hb_min = 1;
-static int xpc_hb_max = 10;
+static int xpc_hb_interval = XPC_HB_DEFAULT_INTERVAL;
+static int xpc_hb_min_interval = 1;
+static int xpc_hb_max_interval = 10;
-static int xpc_hb_check_min = 10;
-static int xpc_hb_check_max = 120;
+static int xpc_hb_check_interval = XPC_HB_CHECK_DEFAULT_INTERVAL;
+static int xpc_hb_check_min_interval = 10;
+static int xpc_hb_check_max_interval = 120;
+
+int xpc_disengage_request_timelimit = XPC_DISENGAGE_REQUEST_DEFAULT_TIMELIMIT;
+static int xpc_disengage_request_min_timelimit = 0;
+static int xpc_disengage_request_max_timelimit = 120;
static ctl_table xpc_sys_xpc_hb_dir[] = {
{
@@ -99,7 +107,8 @@ static ctl_table xpc_sys_xpc_hb_dir[] = {
&proc_dointvec_minmax,
&sysctl_intvec,
NULL,
- &xpc_hb_min, &xpc_hb_max
+ &xpc_hb_min_interval,
+ &xpc_hb_max_interval
},
{
2,
@@ -111,7 +120,8 @@ static ctl_table xpc_sys_xpc_hb_dir[] = {
&proc_dointvec_minmax,
&sysctl_intvec,
NULL,
- &xpc_hb_check_min, &xpc_hb_check_max
+ &xpc_hb_check_min_interval,
+ &xpc_hb_check_max_interval
},
{0}
};
@@ -124,6 +134,19 @@ static ctl_table xpc_sys_xpc_dir[] = {
0555,
xpc_sys_xpc_hb_dir
},
+ {
+ 2,
+ "disengage_request_timelimit",
+ &xpc_disengage_request_timelimit,
+ sizeof(int),
+ 0644,
+ NULL,
+ &proc_dointvec_minmax,
+ &sysctl_intvec,
+ NULL,
+ &xpc_disengage_request_min_timelimit,
+ &xpc_disengage_request_max_timelimit
+ },
{0}
};
static ctl_table xpc_sys_dir[] = {
@@ -148,10 +171,10 @@ static DECLARE_WAIT_QUEUE_HEAD(xpc_act_IRQ_wq);
static unsigned long xpc_hb_check_timeout;
-/* xpc_hb_checker thread exited notification */
+/* notification that the xpc_hb_checker thread has exited */
static DECLARE_MUTEX_LOCKED(xpc_hb_checker_exited);
-/* xpc_discovery thread exited notification */
+/* notification that the xpc_discovery thread has exited */
static DECLARE_MUTEX_LOCKED(xpc_discovery_exited);
@@ -161,6 +184,35 @@ static struct timer_list xpc_hb_timer;
static void xpc_kthread_waitmsgs(struct xpc_partition *, struct xpc_channel *);
+static int xpc_system_reboot(struct notifier_block *, unsigned long, void *);
+static struct notifier_block xpc_reboot_notifier = {
+ .notifier_call = xpc_system_reboot,
+};
+
+static int xpc_system_die(struct notifier_block *, unsigned long, void *);
+static struct notifier_block xpc_die_notifier = {
+ .notifier_call = xpc_system_die,
+};
+
+
+/*
+ * Timer function to enforce the timelimit on the partition disengage request.
+ */
+static void
+xpc_timeout_partition_disengage_request(unsigned long data)
+{
+ struct xpc_partition *part = (struct xpc_partition *) data;
+
+
+ DBUG_ON(jiffies < part->disengage_request_timeout);
+
+ (void) xpc_partition_disengaged(part);
+
+ DBUG_ON(part->disengage_request_timeout != 0);
+ DBUG_ON(xpc_partition_engaged(1UL << XPC_PARTID(part)) != 0);
+}
+
+
/*
* Notify the heartbeat check thread that an IRQ has been received.
*/
@@ -214,12 +266,6 @@ xpc_hb_checker(void *ignore)
while (!(volatile int) xpc_exiting) {
- /* wait for IRQ or timeout */
- (void) wait_event_interruptible(xpc_act_IRQ_wq,
- (last_IRQ_count < atomic_read(&xpc_act_IRQ_rcvd) ||
- jiffies >= xpc_hb_check_timeout ||
- (volatile int) xpc_exiting));
-
dev_dbg(xpc_part, "woke up with %d ticks rem; %d IRQs have "
"been received\n",
(int) (xpc_hb_check_timeout - jiffies),
@@ -240,6 +286,7 @@ xpc_hb_checker(void *ignore)
}
+ /* check for outstanding IRQs */
new_IRQ_count = atomic_read(&xpc_act_IRQ_rcvd);
if (last_IRQ_count < new_IRQ_count || force_IRQ != 0) {
force_IRQ = 0;
@@ -257,12 +304,18 @@ xpc_hb_checker(void *ignore)
xpc_hb_check_timeout = jiffies +
(xpc_hb_check_interval * HZ);
}
+
+ /* wait for IRQ or timeout */
+ (void) wait_event_interruptible(xpc_act_IRQ_wq,
+ (last_IRQ_count < atomic_read(&xpc_act_IRQ_rcvd) ||
+ jiffies >= xpc_hb_check_timeout ||
+ (volatile int) xpc_exiting));
}
dev_dbg(xpc_part, "heartbeat checker is exiting\n");
- /* mark this thread as inactive */
+ /* mark this thread as having exited */
up(&xpc_hb_checker_exited);
return 0;
}
@@ -282,7 +335,7 @@ xpc_initiate_discovery(void *ignore)
dev_dbg(xpc_part, "discovery thread is exiting\n");
- /* mark this thread as inactive */
+ /* mark this thread as having exited */
up(&xpc_discovery_exited);
return 0;
}
@@ -309,7 +362,7 @@ xpc_make_first_contact(struct xpc_partition *part)
"partition %d\n", XPC_PARTID(part));
/* wait a 1/4 of a second or so */
- msleep_interruptible(250);
+ (void) msleep_interruptible(250);
if (part->act_state == XPC_P_DEACTIVATING) {
return part->reason;
@@ -336,7 +389,8 @@ static void
xpc_channel_mgr(struct xpc_partition *part)
{
while (part->act_state != XPC_P_DEACTIVATING ||
- atomic_read(&part->nchannels_active) > 0) {
+ atomic_read(&part->nchannels_active) > 0 ||
+ !xpc_partition_disengaged(part)) {
xpc_process_channel_activity(part);
@@ -360,7 +414,8 @@ xpc_channel_mgr(struct xpc_partition *part)
(volatile u64) part->local_IPI_amo != 0 ||
((volatile u8) part->act_state ==
XPC_P_DEACTIVATING &&
- atomic_read(&part->nchannels_active) == 0)));
+ atomic_read(&part->nchannels_active) == 0 &&
+ xpc_partition_disengaged(part))));
atomic_set(&part->channel_mgr_requests, 1);
// >>> Does it need to wakeup periodically as well? In case we
@@ -482,7 +537,7 @@ xpc_activating(void *__partid)
return 0;
}
- XPC_ALLOW_HB(partid, xpc_vars);
+ xpc_allow_hb(partid, xpc_vars);
xpc_IPI_send_activated(part);
@@ -492,6 +547,7 @@ xpc_activating(void *__partid)
*/
(void) xpc_partition_up(part);
+ xpc_disallow_hb(partid, xpc_vars);
xpc_mark_partition_inactive(part);
if (part->reason == xpcReactivating) {
@@ -670,6 +726,7 @@ xpc_daemonize_kthread(void *args)
struct xpc_partition *part = &xpc_partitions[partid];
struct xpc_channel *ch;
int n_needed;
+ unsigned long irq_flags;
daemonize("xpc%02dc%d", partid, ch_number);
@@ -680,11 +737,14 @@ xpc_daemonize_kthread(void *args)
ch = &part->channels[ch_number];
if (!(ch->flags & XPC_C_DISCONNECTING)) {
- DBUG_ON(!(ch->flags & XPC_C_CONNECTED));
/* let registerer know that connection has been established */
- if (atomic_read(&ch->kthreads_assigned) == 1) {
+ spin_lock_irqsave(&ch->lock, irq_flags);
+ if (!(ch->flags & XPC_C_CONNECTCALLOUT)) {
+ ch->flags |= XPC_C_CONNECTCALLOUT;
+ spin_unlock_irqrestore(&ch->lock, irq_flags);
+
xpc_connected_callout(ch);
/*
@@ -699,16 +759,28 @@ xpc_daemonize_kthread(void *args)
!(ch->flags & XPC_C_DISCONNECTING)) {
xpc_activate_kthreads(ch, n_needed);
}
+ } else {
+ spin_unlock_irqrestore(&ch->lock, irq_flags);
}
xpc_kthread_waitmsgs(part, ch);
}
- if (atomic_dec_return(&ch->kthreads_assigned) == 0 &&
- ((ch->flags & XPC_C_CONNECTCALLOUT) ||
- (ch->reason != xpcUnregistering &&
- ch->reason != xpcOtherUnregistering))) {
- xpc_disconnected_callout(ch);
+ if (atomic_dec_return(&ch->kthreads_assigned) == 0) {
+ spin_lock_irqsave(&ch->lock, irq_flags);
+ if ((ch->flags & XPC_C_CONNECTCALLOUT) &&
+ !(ch->flags & XPC_C_DISCONNECTCALLOUT)) {
+ ch->flags |= XPC_C_DISCONNECTCALLOUT;
+ spin_unlock_irqrestore(&ch->lock, irq_flags);
+
+ xpc_disconnecting_callout(ch);
+ } else {
+ spin_unlock_irqrestore(&ch->lock, irq_flags);
+ }
+ if (atomic_dec_return(&part->nchannels_engaged) == 0) {
+ xpc_mark_partition_disengaged(part);
+ xpc_IPI_send_disengage(part);
+ }
}
@@ -740,12 +812,33 @@ xpc_create_kthreads(struct xpc_channel *ch, int needed)
unsigned long irq_flags;
pid_t pid;
u64 args = XPC_PACK_ARGS(ch->partid, ch->number);
+ struct xpc_partition *part = &xpc_partitions[ch->partid];
while (needed-- > 0) {
+
+ /*
+ * The following is done on behalf of the newly created
+ * kthread. That kthread is responsible for doing the
+ * counterpart to the following before it exits.
+ */
+ (void) xpc_part_ref(part);
+ xpc_msgqueue_ref(ch);
+ if (atomic_inc_return(&ch->kthreads_assigned) == 1 &&
+ atomic_inc_return(&part->nchannels_engaged) == 1) {
+ xpc_mark_partition_engaged(part);
+ }
+
pid = kernel_thread(xpc_daemonize_kthread, (void *) args, 0);
if (pid < 0) {
/* the fork failed */
+ if (atomic_dec_return(&ch->kthreads_assigned) == 0 &&
+ atomic_dec_return(&part->nchannels_engaged) == 0) {
+ xpc_mark_partition_disengaged(part);
+ xpc_IPI_send_disengage(part);
+ }
+ xpc_msgqueue_deref(ch);
+ xpc_part_deref(part);
if (atomic_read(&ch->kthreads_assigned) <
ch->kthreads_idle_limit) {
@@ -765,14 +858,6 @@ xpc_create_kthreads(struct xpc_channel *ch, int needed)
break;
}
- /*
- * The following is done on behalf of the newly created
- * kthread. That kthread is responsible for doing the
- * counterpart to the following before it exits.
- */
- (void) xpc_part_ref(&xpc_partitions[ch->partid]);
- xpc_msgqueue_ref(ch);
- atomic_inc(&ch->kthreads_assigned);
ch->kthreads_created++; // >>> temporary debug only!!!
}
}
@@ -781,87 +866,145 @@ xpc_create_kthreads(struct xpc_channel *ch, int needed)
void
xpc_disconnect_wait(int ch_number)
{
+ unsigned long irq_flags;
partid_t partid;
struct xpc_partition *part;
struct xpc_channel *ch;
+ int wakeup_channel_mgr;
/* now wait for all callouts to the caller's function to cease */
for (partid = 1; partid < XP_MAX_PARTITIONS; partid++) {
part = &xpc_partitions[partid];
- if (xpc_part_ref(part)) {
- ch = &part->channels[ch_number];
+ if (!xpc_part_ref(part)) {
+ continue;
+ }
-// >>> how do we keep from falling into the window between our check and going
-// >>> down and coming back up where sema is re-inited?
- if (ch->flags & XPC_C_SETUP) {
- (void) down(&ch->teardown_sema);
- }
+ ch = &part->channels[ch_number];
+ if (!(ch->flags & XPC_C_WDISCONNECT)) {
xpc_part_deref(part);
+ continue;
+ }
+
+ (void) down(&ch->wdisconnect_sema);
+
+ spin_lock_irqsave(&ch->lock, irq_flags);
+ DBUG_ON(!(ch->flags & XPC_C_DISCONNECTED));
+ wakeup_channel_mgr = 0;
+
+ if (ch->delayed_IPI_flags) {
+ if (part->act_state != XPC_P_DEACTIVATING) {
+ spin_lock(&part->IPI_lock);
+ XPC_SET_IPI_FLAGS(part->local_IPI_amo,
+ ch->number, ch->delayed_IPI_flags);
+ spin_unlock(&part->IPI_lock);
+ wakeup_channel_mgr = 1;
+ }
+ ch->delayed_IPI_flags = 0;
}
+
+ ch->flags &= ~XPC_C_WDISCONNECT;
+ spin_unlock_irqrestore(&ch->lock, irq_flags);
+
+ if (wakeup_channel_mgr) {
+ xpc_wakeup_channel_mgr(part);
+ }
+
+ xpc_part_deref(part);
}
}
static void
-xpc_do_exit(void)
+xpc_do_exit(enum xpc_retval reason)
{
partid_t partid;
int active_part_count;
struct xpc_partition *part;
+ unsigned long printmsg_time;
- /* now it's time to eliminate our heartbeat */
- del_timer_sync(&xpc_hb_timer);
- xpc_vars->heartbeating_to_mask = 0;
-
- /* indicate to others that our reserved page is uninitialized */
- xpc_rsvd_page->vars_pa = 0;
-
- /*
- * Ignore all incoming interrupts. Without interupts the heartbeat
- * checker won't activate any new partitions that may come up.
- */
- free_irq(SGI_XPC_ACTIVATE, NULL);
+ /* a 'rmmod XPC' and a 'reboot' cannot both end up here together */
+ DBUG_ON(xpc_exiting == 1);
/*
- * Cause the heartbeat checker and the discovery threads to exit.
- * We don't want them attempting to activate new partitions as we
- * try to deactivate the existing ones.
+ * Let the heartbeat checker thread and the discovery thread
+ * (if one is running) know that they should exit. Also wake up
+ * the heartbeat checker thread in case it's sleeping.
*/
xpc_exiting = 1;
wake_up_interruptible(&xpc_act_IRQ_wq);
- /* wait for the heartbeat checker thread to mark itself inactive */
- down(&xpc_hb_checker_exited);
+ /* ignore all incoming interrupts */
+ free_irq(SGI_XPC_ACTIVATE, NULL);
- /* wait for the discovery thread to mark itself inactive */
+ /* wait for the discovery thread to exit */
down(&xpc_discovery_exited);
+ /* wait for the heartbeat checker thread to exit */
+ down(&xpc_hb_checker_exited);
+
- msleep_interruptible(300);
+ /* sleep for a 1/3 of a second or so */
+ (void) msleep_interruptible(300);
/* wait for all partitions to become inactive */
+ printmsg_time = jiffies;
+
do {
active_part_count = 0;
for (partid = 1; partid < XP_MAX_PARTITIONS; partid++) {
part = &xpc_partitions[partid];
- if (part->act_state != XPC_P_INACTIVE) {
- active_part_count++;
- XPC_DEACTIVATE_PARTITION(part, xpcUnloading);
+ if (xpc_partition_disengaged(part) &&
+ part->act_state == XPC_P_INACTIVE) {
+ continue;
}
+
+ active_part_count++;
+
+ XPC_DEACTIVATE_PARTITION(part, reason);
}
- if (active_part_count)
- msleep_interruptible(300);
- } while (active_part_count > 0);
+ if (active_part_count == 0) {
+ break;
+ }
+ if (jiffies >= printmsg_time) {
+ dev_info(xpc_part, "waiting for partitions to "
+ "deactivate/disengage, active count=%d, remote "
+ "engaged=0x%lx\n", active_part_count,
+ xpc_partition_engaged(1UL << partid));
+
+ printmsg_time = jiffies +
+ (XPC_DISENGAGE_PRINTMSG_INTERVAL * HZ);
+ }
+
+ /* sleep for a 1/3 of a second or so */
+ (void) msleep_interruptible(300);
+
+ } while (1);
+
+ DBUG_ON(xpc_partition_engaged(-1UL));
+
+
+ /* indicate to others that our reserved page is uninitialized */
+ xpc_rsvd_page->vars_pa = 0;
+
+ /* now it's time to eliminate our heartbeat */
+ del_timer_sync(&xpc_hb_timer);
+ DBUG_ON(xpc_vars->heartbeating_to_mask != 0);
+
+ /* take ourselves off of the reboot_notifier_list */
+ (void) unregister_reboot_notifier(&xpc_reboot_notifier);
+
+ /* take ourselves off of the die_notifier list */
+ (void) unregister_die_notifier(&xpc_die_notifier);
/* close down protections for IPI operations */
xpc_restrict_IPI_ops();
@@ -876,6 +1019,118 @@ xpc_do_exit(void)
}
+/*
+ * Called when the system is about to be either restarted or halted.
+ */
+static void
+xpc_die_disengage(void)
+{
+ struct xpc_partition *part;
+ partid_t partid;
+ unsigned long engaged;
+ long time, print_time, disengage_request_timeout;
+
+
+ /* keep xpc_hb_checker thread from doing anything (just in case) */
+ xpc_exiting = 1;
+
+ xpc_vars->heartbeating_to_mask = 0; /* indicate we're deactivated */
+
+ for (partid = 1; partid < XP_MAX_PARTITIONS; partid++) {
+ part = &xpc_partitions[partid];
+
+ if (!XPC_SUPPORTS_DISENGAGE_REQUEST(part->
+ remote_vars_version)) {
+
+ /* just in case it was left set by an earlier XPC */
+ xpc_clear_partition_engaged(1UL << partid);
+ continue;
+ }
+
+ if (xpc_partition_engaged(1UL << partid) ||
+ part->act_state != XPC_P_INACTIVE) {
+ xpc_request_partition_disengage(part);
+ xpc_mark_partition_disengaged(part);
+ xpc_IPI_send_disengage(part);
+ }
+ }
+
+ print_time = rtc_time();
+ disengage_request_timeout = print_time +
+ (xpc_disengage_request_timelimit * sn_rtc_cycles_per_second);
+
+ /* wait for all other partitions to disengage from us */
+
+ while ((engaged = xpc_partition_engaged(-1UL)) &&
+ (time = rtc_time()) < disengage_request_timeout) {
+
+ if (time >= print_time) {
+ dev_info(xpc_part, "waiting for remote partitions to "
+ "disengage, engaged=0x%lx\n", engaged);
+ print_time = time + (XPC_DISENGAGE_PRINTMSG_INTERVAL *
+ sn_rtc_cycles_per_second);
+ }
+ }
+ dev_info(xpc_part, "finished waiting for remote partitions to "
+ "disengage, engaged=0x%lx\n", engaged);
+}
+
+
+/*
+ * This function is called when the system is being rebooted.
+ */
+static int
+xpc_system_reboot(struct notifier_block *nb, unsigned long event, void *unused)
+{
+ enum xpc_retval reason;
+
+
+ switch (event) {
+ case SYS_RESTART:
+ reason = xpcSystemReboot;
+ break;
+ case SYS_HALT:
+ reason = xpcSystemHalt;
+ break;
+ case SYS_POWER_OFF:
+ reason = xpcSystemPoweroff;
+ break;
+ default:
+ reason = xpcSystemGoingDown;
+ }
+
+ xpc_do_exit(reason);
+ return NOTIFY_DONE;
+}
+
+
+/*
+ * This function is called when the system is being rebooted.
+ */
+static int
+xpc_system_die(struct notifier_block *nb, unsigned long event, void *unused)
+{
+ switch (event) {
+ case DIE_MACHINE_RESTART:
+ case DIE_MACHINE_HALT:
+ xpc_die_disengage();
+ break;
+ case DIE_MCA_MONARCH_ENTER:
+ case DIE_INIT_MONARCH_ENTER:
+ xpc_vars->heartbeat++;
+ xpc_vars->heartbeat_offline = 1;
+ break;
+ case DIE_MCA_MONARCH_LEAVE:
+ case DIE_INIT_MONARCH_LEAVE:
+ xpc_vars->heartbeat++;
+ xpc_vars->heartbeat_offline = 0;
+ break;
+ }
+
+ return NOTIFY_DONE;
+}
+
+
int __init
xpc_init(void)
{
@@ -891,11 +1146,11 @@ xpc_init(void)
/*
* xpc_remote_copy_buffer is used as a temporary buffer for bte_copy'ng
- * both a partition's reserved page and its XPC variables. Its size was
- * based on the size of a reserved page. So we need to ensure that the
- * XPC variables will fit as well.
+ * various portions of a partition's reserved page. Its size is based
+ * on the size of the reserved page header and part_nasids mask. So we
+ * need to ensure that the other items will fit as well.
*/
- if (XPC_VARS_ALIGNED_SIZE > XPC_RSVD_PAGE_ALIGNED_SIZE) {
+ if (XPC_RP_VARS_SIZE > XPC_RP_HEADER_SIZE + XP_NASID_MASK_BYTES) {
dev_err(xpc_part, "xpc_remote_copy_buffer is not big enough\n");
return -EPERM;
}
@@ -924,6 +1179,12 @@ xpc_init(void)
spin_lock_init(&part->act_lock);
part->act_state = XPC_P_INACTIVE;
XPC_SET_REASON(part, 0, 0);
+
+ init_timer(&part->disengage_request_timer);
+ part->disengage_request_timer.function =
+ xpc_timeout_partition_disengage_request;
+ part->disengage_request_timer.data = (unsigned long) part;
+
part->setup_state = XPC_P_UNSET;
init_waitqueue_head(&part->teardown_wq);
atomic_set(&part->references, 0);
@@ -980,6 +1241,19 @@ xpc_init(void)
}
+ /* add ourselves to the reboot_notifier_list */
+ ret = register_reboot_notifier(&xpc_reboot_notifier);
+ if (ret != 0) {
+ dev_warn(xpc_part, "can't register reboot notifier\n");
+ }
+
+ /* add ourselves to the die_notifier list (i.e., ia64die_chain) */
+ ret = register_die_notifier(&xpc_die_notifier);
+ if (ret != 0) {
+ dev_warn(xpc_part, "can't register die notifier\n");
+ }
+
+
/*
* Set the beating to other partitions into motion. This is
* the last requirement for other partitions' discovery to
@@ -1001,6 +1275,12 @@ xpc_init(void)
/* indicate to others that our reserved page is uninitialized */
xpc_rsvd_page->vars_pa = 0;
+ /* take ourselves off of the reboot_notifier_list */
+ (void) unregister_reboot_notifier(&xpc_reboot_notifier);
+
+ /* take ourselves off of the die_notifier list */
+ (void) unregister_die_notifier(&xpc_die_notifier);
+
del_timer_sync(&xpc_hb_timer);
free_irq(SGI_XPC_ACTIVATE, NULL);
xpc_restrict_IPI_ops();
@@ -1024,7 +1304,7 @@ xpc_init(void)
/* mark this new thread as a non-starter */
up(&xpc_discovery_exited);
- xpc_do_exit();
+ xpc_do_exit(xpcUnloading);
return -EBUSY;
}
@@ -1043,7 +1323,7 @@ module_init(xpc_init);
void __exit
xpc_exit(void)
{
- xpc_do_exit();
+ xpc_do_exit(xpcUnloading);
}
module_exit(xpc_exit);
@@ -1060,3 +1340,7 @@ module_param(xpc_hb_check_interval, int, 0);
MODULE_PARM_DESC(xpc_hb_check_interval, "Number of seconds between "
"heartbeat checks.");
+module_param(xpc_disengage_request_timelimit, int, 0);
+MODULE_PARM_DESC(xpc_disengage_request_timelimit, "Number of seconds to wait "
+ "for disengage request to complete.");
+
diff --git a/arch/ia64/sn/kernel/xpc_partition.c b/arch/ia64/sn/kernel/xpc_partition.c
index 578265ea9e67..cdd6431853a1 100644
--- a/arch/ia64/sn/kernel/xpc_partition.c
+++ b/arch/ia64/sn/kernel/xpc_partition.c
@@ -44,16 +44,19 @@ static u64 xpc_sh2_IPI_access3;
/* original protection values for each node */
-u64 xpc_prot_vec[MAX_COMPACT_NODES];
+u64 xpc_prot_vec[MAX_NUMNODES];
-/* this partition's reserved page */
+/* this partition's reserved page pointers */
struct xpc_rsvd_page *xpc_rsvd_page;
-
-/* this partition's XPC variables (within the reserved page) */
+static u64 *xpc_part_nasids;
+static u64 *xpc_mach_nasids;
struct xpc_vars *xpc_vars;
struct xpc_vars_part *xpc_vars_part;
+static int xp_nasid_mask_bytes; /* actual size in bytes of nasid mask */
+static int xp_nasid_mask_words; /* actual size in words of nasid mask */
+
/*
* For performance reasons, each entry of xpc_partitions[] is cacheline
@@ -65,20 +68,16 @@ struct xpc_partition xpc_partitions[XP_MAX_PARTITIONS + 1];
/*
- * Generic buffer used to store a local copy of the remote partitions
- * reserved page or XPC variables.
+ * Generic buffer used to store a local copy of portions of a remote
+ * partition's reserved page (either its header and part_nasids mask,
+ * or its vars).
*
* xpc_discovery runs only once and is a seperate thread that is
* very likely going to be processing in parallel with receiving
* interrupts.
*/
-char ____cacheline_aligned
- xpc_remote_copy_buffer[XPC_RSVD_PAGE_ALIGNED_SIZE];
-
-
-/* systune related variables */
-int xpc_hb_interval = XPC_HB_DEFAULT_INTERVAL;
-int xpc_hb_check_interval = XPC_HB_CHECK_DEFAULT_TIMEOUT;
+char ____cacheline_aligned xpc_remote_copy_buffer[XPC_RP_HEADER_SIZE +
+ XP_NASID_MASK_BYTES];
/*
@@ -86,13 +85,16 @@ int xpc_hb_check_interval = XPC_HB_CHECK_DEFAULT_TIMEOUT;
* for that nasid. This function returns 0 on any error.
*/
static u64
-xpc_get_rsvd_page_pa(int nasid, u64 buf, u64 buf_size)
+xpc_get_rsvd_page_pa(int nasid)
{
bte_result_t bte_res;
s64 status;
u64 cookie = 0;
u64 rp_pa = nasid; /* seed with nasid */
u64 len = 0;
+ u64 buf = buf;
+ u64 buf_len = 0;
+ void *buf_base = NULL;
while (1) {
@@ -108,13 +110,22 @@ xpc_get_rsvd_page_pa(int nasid, u64 buf, u64 buf_size)
break;
}
- if (len > buf_size) {
- dev_err(xpc_part, "len (=0x%016lx) > buf_size\n", len);
- status = SALRET_ERROR;
- break;
+ if (L1_CACHE_ALIGN(len) > buf_len) {
+ if (buf_base != NULL) {
+ kfree(buf_base);
+ }
+ buf_len = L1_CACHE_ALIGN(len);
+ buf = (u64) xpc_kmalloc_cacheline_aligned(buf_len,
+ GFP_KERNEL, &buf_base);
+ if (buf_base == NULL) {
+ dev_err(xpc_part, "unable to kmalloc "
+ "len=0x%016lx\n", buf_len);
+ status = SALRET_ERROR;
+ break;
+ }
}
- bte_res = xp_bte_copy(rp_pa, ia64_tpa(buf), buf_size,
+ bte_res = xp_bte_copy(rp_pa, ia64_tpa(buf), buf_len,
(BTE_NOTIFY | BTE_WACQUIRE), NULL);
if (bte_res != BTE_SUCCESS) {
dev_dbg(xpc_part, "xp_bte_copy failed %i\n", bte_res);
@@ -123,6 +134,10 @@ xpc_get_rsvd_page_pa(int nasid, u64 buf, u64 buf_size)
}
}
+ if (buf_base != NULL) {
+ kfree(buf_base);
+ }
+
if (status != SALRET_OK) {
rp_pa = 0;
}
@@ -141,15 +156,15 @@ xpc_rsvd_page_init(void)
{
struct xpc_rsvd_page *rp;
AMO_t *amos_page;
- u64 rp_pa, next_cl, nasid_array = 0;
+ u64 rp_pa, nasid_array = 0;
int i, ret;
/* get the local reserved page's address */
- rp_pa = xpc_get_rsvd_page_pa(cnodeid_to_nasid(0),
- (u64) xpc_remote_copy_buffer,
- XPC_RSVD_PAGE_ALIGNED_SIZE);
+ preempt_disable();
+ rp_pa = xpc_get_rsvd_page_pa(cpuid_to_nasid(smp_processor_id()));
+ preempt_enable();
if (rp_pa == 0) {
dev_err(xpc_part, "SAL failed to locate the reserved page\n");
return NULL;
@@ -164,12 +179,19 @@ xpc_rsvd_page_init(void)
rp->version = XPC_RP_VERSION;
- /*
- * Place the XPC variables on the cache line following the
- * reserved page structure.
- */
- next_cl = (u64) rp + XPC_RSVD_PAGE_ALIGNED_SIZE;
- xpc_vars = (struct xpc_vars *) next_cl;
+ /* establish the actual sizes of the nasid masks */
+ if (rp->SAL_version == 1) {
+ /* SAL_version 1 didn't set the nasids_size field */
+ rp->nasids_size = 128;
+ }
+ xp_nasid_mask_bytes = rp->nasids_size;
+ xp_nasid_mask_words = xp_nasid_mask_bytes / 8;
+
+ /* setup the pointers to the various items in the reserved page */
+ xpc_part_nasids = XPC_RP_PART_NASIDS(rp);
+ xpc_mach_nasids = XPC_RP_MACH_NASIDS(rp);
+ xpc_vars = XPC_RP_VARS(rp);
+ xpc_vars_part = XPC_RP_VARS_PART(rp);
/*
* Before clearing xpc_vars, see if a page of AMOs had been previously
@@ -221,33 +243,32 @@ xpc_rsvd_page_init(void)
amos_page = (AMO_t *) TO_AMO((u64) amos_page);
}
+ /* clear xpc_vars */
memset(xpc_vars, 0, sizeof(struct xpc_vars));
- /*
- * Place the XPC per partition specific variables on the cache line
- * following the XPC variables structure.
- */
- next_cl += XPC_VARS_ALIGNED_SIZE;
- memset((u64 *) next_cl, 0, sizeof(struct xpc_vars_part) *
- XP_MAX_PARTITIONS);
- xpc_vars_part = (struct xpc_vars_part *) next_cl;
- xpc_vars->vars_part_pa = __pa(next_cl);
-
xpc_vars->version = XPC_V_VERSION;
xpc_vars->act_nasid = cpuid_to_nasid(0);
xpc_vars->act_phys_cpuid = cpu_physical_id(0);
+ xpc_vars->vars_part_pa = __pa(xpc_vars_part);
+ xpc_vars->amos_page_pa = ia64_tpa((u64) amos_page);
xpc_vars->amos_page = amos_page; /* save for next load of XPC */
- /*
- * Initialize the activation related AMO variables.
- */
- xpc_vars->act_amos = xpc_IPI_init(XP_MAX_PARTITIONS);
- for (i = 1; i < XP_NASID_MASK_WORDS; i++) {
- xpc_IPI_init(i + XP_MAX_PARTITIONS);
+ /* clear xpc_vars_part */
+ memset((u64 *) xpc_vars_part, 0, sizeof(struct xpc_vars_part) *
+ XP_MAX_PARTITIONS);
+
+ /* initialize the activate IRQ related AMO variables */
+ for (i = 0; i < xp_nasid_mask_words; i++) {
+ (void) xpc_IPI_init(XPC_ACTIVATE_IRQ_AMOS + i);
}
- /* export AMO page's physical address to other partitions */
- xpc_vars->amos_page_pa = ia64_tpa((u64) xpc_vars->amos_page);
+
+ /* initialize the engaged remote partitions related AMO variables */
+ (void) xpc_IPI_init(XPC_ENGAGED_PARTITIONS_AMO);
+ (void) xpc_IPI_init(XPC_DISENGAGE_REQUEST_AMO);
+
+ /* timestamp of when reserved page was setup by XPC */
+ rp->stamp = CURRENT_TIME;
/*
* This signifies to the remote partition that our reserved
@@ -387,6 +408,11 @@ xpc_check_remote_hb(void)
remote_vars = (struct xpc_vars *) xpc_remote_copy_buffer;
for (partid = 1; partid < XP_MAX_PARTITIONS; partid++) {
+
+ if (xpc_exiting) {
+ break;
+ }
+
if (partid == sn_partition_id) {
continue;
}
@@ -401,7 +427,7 @@ xpc_check_remote_hb(void)
/* pull the remote_hb cache line */
bres = xp_bte_copy(part->remote_vars_pa,
ia64_tpa((u64) remote_vars),
- XPC_VARS_ALIGNED_SIZE,
+ XPC_RP_VARS_SIZE,
(BTE_NOTIFY | BTE_WACQUIRE), NULL);
if (bres != BTE_SUCCESS) {
XPC_DEACTIVATE_PARTITION(part,
@@ -410,14 +436,14 @@ xpc_check_remote_hb(void)
}
dev_dbg(xpc_part, "partid = %d, heartbeat = %ld, last_heartbeat"
- " = %ld, kdb_status = %ld, HB_mask = 0x%lx\n", partid,
- remote_vars->heartbeat, part->last_heartbeat,
- remote_vars->kdb_status,
+ " = %ld, heartbeat_offline = %ld, HB_mask = 0x%lx\n",
+ partid, remote_vars->heartbeat, part->last_heartbeat,
+ remote_vars->heartbeat_offline,
remote_vars->heartbeating_to_mask);
if (((remote_vars->heartbeat == part->last_heartbeat) &&
- (remote_vars->kdb_status == 0)) ||
- !XPC_HB_ALLOWED(sn_partition_id, remote_vars)) {
+ (remote_vars->heartbeat_offline == 0)) ||
+ !xpc_hb_allowed(sn_partition_id, remote_vars)) {
XPC_DEACTIVATE_PARTITION(part, xpcNoHeartbeat);
continue;
@@ -429,31 +455,31 @@ xpc_check_remote_hb(void)
/*
- * Get a copy of the remote partition's rsvd page.
+ * Get a copy of a portion of the remote partition's rsvd page.
*
* remote_rp points to a buffer that is cacheline aligned for BTE copies and
- * assumed to be of size XPC_RSVD_PAGE_ALIGNED_SIZE.
+ * is large enough to contain a copy of their reserved page header and
+ * part_nasids mask.
*/
static enum xpc_retval
xpc_get_remote_rp(int nasid, u64 *discovered_nasids,
- struct xpc_rsvd_page *remote_rp, u64 *remote_rsvd_page_pa)
+ struct xpc_rsvd_page *remote_rp, u64 *remote_rp_pa)
{
int bres, i;
/* get the reserved page's physical address */
- *remote_rsvd_page_pa = xpc_get_rsvd_page_pa(nasid, (u64) remote_rp,
- XPC_RSVD_PAGE_ALIGNED_SIZE);
- if (*remote_rsvd_page_pa == 0) {
+ *remote_rp_pa = xpc_get_rsvd_page_pa(nasid);
+ if (*remote_rp_pa == 0) {
return xpcNoRsvdPageAddr;
}
- /* pull over the reserved page structure */
+ /* pull over the reserved page header and part_nasids mask */
- bres = xp_bte_copy(*remote_rsvd_page_pa, ia64_tpa((u64) remote_rp),
- XPC_RSVD_PAGE_ALIGNED_SIZE,
+ bres = xp_bte_copy(*remote_rp_pa, ia64_tpa((u64) remote_rp),
+ XPC_RP_HEADER_SIZE + xp_nasid_mask_bytes,
(BTE_NOTIFY | BTE_WACQUIRE), NULL);
if (bres != BTE_SUCCESS) {
return xpc_map_bte_errors(bres);
@@ -461,8 +487,11 @@ xpc_get_remote_rp(int nasid, u64 *discovered_nasids,
if (discovered_nasids != NULL) {
- for (i = 0; i < XP_NASID_MASK_WORDS; i++) {
- discovered_nasids[i] |= remote_rp->part_nasids[i];
+ u64 *remote_part_nasids = XPC_RP_PART_NASIDS(remote_rp);
+
+
+ for (i = 0; i < xp_nasid_mask_words; i++) {
+ discovered_nasids[i] |= remote_part_nasids[i];
}
}
@@ -489,10 +518,10 @@ xpc_get_remote_rp(int nasid, u64 *discovered_nasids,
/*
- * Get a copy of the remote partition's XPC variables.
+ * Get a copy of the remote partition's XPC variables from the reserved page.
*
* remote_vars points to a buffer that is cacheline aligned for BTE copies and
- * assumed to be of size XPC_VARS_ALIGNED_SIZE.
+ * assumed to be of size XPC_RP_VARS_SIZE.
*/
static enum xpc_retval
xpc_get_remote_vars(u64 remote_vars_pa, struct xpc_vars *remote_vars)
@@ -508,7 +537,7 @@ xpc_get_remote_vars(u64 remote_vars_pa, struct xpc_vars *remote_vars)
/* pull over the cross partition variables */
bres = xp_bte_copy(remote_vars_pa, ia64_tpa((u64) remote_vars),
- XPC_VARS_ALIGNED_SIZE,
+ XPC_RP_VARS_SIZE,
(BTE_NOTIFY | BTE_WACQUIRE), NULL);
if (bres != BTE_SUCCESS) {
return xpc_map_bte_errors(bres);
@@ -524,7 +553,56 @@ xpc_get_remote_vars(u64 remote_vars_pa, struct xpc_vars *remote_vars)
/*
- * Prior code has determine the nasid which generated an IPI. Inspect
+ * Update the remote partition's info.
+ */
+static void
+xpc_update_partition_info(struct xpc_partition *part, u8 remote_rp_version,
+ struct timespec *remote_rp_stamp, u64 remote_rp_pa,
+ u64 remote_vars_pa, struct xpc_vars *remote_vars)
+{
+ part->remote_rp_version = remote_rp_version;
+ dev_dbg(xpc_part, " remote_rp_version = 0x%016lx\n",
+ part->remote_rp_version);
+
+ part->remote_rp_stamp = *remote_rp_stamp;
+ dev_dbg(xpc_part, " remote_rp_stamp (tv_sec = 0x%lx tv_nsec = 0x%lx\n",
+ part->remote_rp_stamp.tv_sec, part->remote_rp_stamp.tv_nsec);
+
+ part->remote_rp_pa = remote_rp_pa;
+ dev_dbg(xpc_part, " remote_rp_pa = 0x%016lx\n", part->remote_rp_pa);
+
+ part->remote_vars_pa = remote_vars_pa;
+ dev_dbg(xpc_part, " remote_vars_pa = 0x%016lx\n",
+ part->remote_vars_pa);
+
+ part->last_heartbeat = remote_vars->heartbeat;
+ dev_dbg(xpc_part, " last_heartbeat = 0x%016lx\n",
+ part->last_heartbeat);
+
+ part->remote_vars_part_pa = remote_vars->vars_part_pa;
+ dev_dbg(xpc_part, " remote_vars_part_pa = 0x%016lx\n",
+ part->remote_vars_part_pa);
+
+ part->remote_act_nasid = remote_vars->act_nasid;
+ dev_dbg(xpc_part, " remote_act_nasid = 0x%x\n",
+ part->remote_act_nasid);
+
+ part->remote_act_phys_cpuid = remote_vars->act_phys_cpuid;
+ dev_dbg(xpc_part, " remote_act_phys_cpuid = 0x%x\n",
+ part->remote_act_phys_cpuid);
+
+ part->remote_amos_page_pa = remote_vars->amos_page_pa;
+ dev_dbg(xpc_part, " remote_amos_page_pa = 0x%lx\n",
+ part->remote_amos_page_pa);
+
+ part->remote_vars_version = remote_vars->version;
+ dev_dbg(xpc_part, " remote_vars_version = 0x%x\n",
+ part->remote_vars_version);
+}
+
+
+/*
+ * Prior code has determined the nasid which generated an IPI. Inspect
* that nasid to determine if its partition needs to be activated or
* deactivated.
*
@@ -542,8 +620,12 @@ xpc_identify_act_IRQ_req(int nasid)
{
struct xpc_rsvd_page *remote_rp;
struct xpc_vars *remote_vars;
- u64 remote_rsvd_page_pa;
+ u64 remote_rp_pa;
u64 remote_vars_pa;
+ int remote_rp_version;
+ int reactivate = 0;
+ int stamp_diff;
+ struct timespec remote_rp_stamp = { 0, 0 };
partid_t partid;
struct xpc_partition *part;
enum xpc_retval ret;
@@ -553,7 +635,7 @@ xpc_identify_act_IRQ_req(int nasid)
remote_rp = (struct xpc_rsvd_page *) xpc_remote_copy_buffer;
- ret = xpc_get_remote_rp(nasid, NULL, remote_rp, &remote_rsvd_page_pa);
+ ret = xpc_get_remote_rp(nasid, NULL, remote_rp, &remote_rp_pa);
if (ret != xpcSuccess) {
dev_warn(xpc_part, "unable to get reserved page from nasid %d, "
"which sent interrupt, reason=%d\n", nasid, ret);
@@ -561,6 +643,10 @@ xpc_identify_act_IRQ_req(int nasid)
}
remote_vars_pa = remote_rp->vars_pa;
+ remote_rp_version = remote_rp->version;
+ if (XPC_SUPPORTS_RP_STAMP(remote_rp_version)) {
+ remote_rp_stamp = remote_rp->stamp;
+ }
partid = remote_rp->partid;
part = &xpc_partitions[partid];
@@ -586,44 +672,117 @@ xpc_identify_act_IRQ_req(int nasid)
"%ld:0x%lx\n", (int) nasid, (int) partid, part->act_IRQ_rcvd,
remote_vars->heartbeat, remote_vars->heartbeating_to_mask);
+ if (xpc_partition_disengaged(part) &&
+ part->act_state == XPC_P_INACTIVE) {
- if (part->act_state == XPC_P_INACTIVE) {
+ xpc_update_partition_info(part, remote_rp_version,
+ &remote_rp_stamp, remote_rp_pa,
+ remote_vars_pa, remote_vars);
- part->remote_rp_pa = remote_rsvd_page_pa;
- dev_dbg(xpc_part, " remote_rp_pa = 0x%016lx\n",
- part->remote_rp_pa);
+ if (XPC_SUPPORTS_DISENGAGE_REQUEST(part->remote_vars_version)) {
+ if (xpc_partition_disengage_requested(1UL << partid)) {
+ /*
+ * Other side is waiting on us to disengage,
+ * even though we already have.
+ */
+ return;
+ }
+ } else {
+ /* other side doesn't support disengage requests */
+ xpc_clear_partition_disengage_request(1UL << partid);
+ }
- part->remote_vars_pa = remote_vars_pa;
- dev_dbg(xpc_part, " remote_vars_pa = 0x%016lx\n",
- part->remote_vars_pa);
+ xpc_activate_partition(part);
+ return;
+ }
- part->last_heartbeat = remote_vars->heartbeat;
- dev_dbg(xpc_part, " last_heartbeat = 0x%016lx\n",
- part->last_heartbeat);
+ DBUG_ON(part->remote_rp_version == 0);
+ DBUG_ON(part->remote_vars_version == 0);
+
+ if (!XPC_SUPPORTS_RP_STAMP(part->remote_rp_version)) {
+ DBUG_ON(XPC_SUPPORTS_DISENGAGE_REQUEST(part->
+ remote_vars_version));
+
+ if (!XPC_SUPPORTS_RP_STAMP(remote_rp_version)) {
+ DBUG_ON(XPC_SUPPORTS_DISENGAGE_REQUEST(remote_vars->
+ version));
+ /* see if the other side rebooted */
+ if (part->remote_amos_page_pa ==
+ remote_vars->amos_page_pa &&
+ xpc_hb_allowed(sn_partition_id,
+ remote_vars)) {
+ /* doesn't look that way, so ignore the IPI */
+ return;
+ }
+ }
- part->remote_vars_part_pa = remote_vars->vars_part_pa;
- dev_dbg(xpc_part, " remote_vars_part_pa = 0x%016lx\n",
- part->remote_vars_part_pa);
+ /*
+ * Other side rebooted and previous XPC didn't support the
+ * disengage request, so we don't need to do anything special.
+ */
- part->remote_act_nasid = remote_vars->act_nasid;
- dev_dbg(xpc_part, " remote_act_nasid = 0x%x\n",
- part->remote_act_nasid);
+ xpc_update_partition_info(part, remote_rp_version,
+ &remote_rp_stamp, remote_rp_pa,
+ remote_vars_pa, remote_vars);
+ part->reactivate_nasid = nasid;
+ XPC_DEACTIVATE_PARTITION(part, xpcReactivating);
+ return;
+ }
- part->remote_act_phys_cpuid = remote_vars->act_phys_cpuid;
- dev_dbg(xpc_part, " remote_act_phys_cpuid = 0x%x\n",
- part->remote_act_phys_cpuid);
+ DBUG_ON(!XPC_SUPPORTS_DISENGAGE_REQUEST(part->remote_vars_version));
- part->remote_amos_page_pa = remote_vars->amos_page_pa;
- dev_dbg(xpc_part, " remote_amos_page_pa = 0x%lx\n",
- part->remote_amos_page_pa);
+ if (!XPC_SUPPORTS_RP_STAMP(remote_rp_version)) {
+ DBUG_ON(!XPC_SUPPORTS_DISENGAGE_REQUEST(remote_vars->version));
- xpc_activate_partition(part);
+ /*
+ * Other side rebooted and previous XPC did support the
+ * disengage request, but the new one doesn't.
+ */
+
+ xpc_clear_partition_engaged(1UL << partid);
+ xpc_clear_partition_disengage_request(1UL << partid);
- } else if (part->remote_amos_page_pa != remote_vars->amos_page_pa ||
- !XPC_HB_ALLOWED(sn_partition_id, remote_vars)) {
+ xpc_update_partition_info(part, remote_rp_version,
+ &remote_rp_stamp, remote_rp_pa,
+ remote_vars_pa, remote_vars);
+ reactivate = 1;
+
+ } else {
+ DBUG_ON(!XPC_SUPPORTS_DISENGAGE_REQUEST(remote_vars->version));
+ stamp_diff = xpc_compare_stamps(&part->remote_rp_stamp,
+ &remote_rp_stamp);
+ if (stamp_diff != 0) {
+ DBUG_ON(stamp_diff >= 0);
+
+ /*
+ * Other side rebooted and the previous XPC did support
+ * the disengage request, as does the new one.
+ */
+
+ DBUG_ON(xpc_partition_engaged(1UL << partid));
+ DBUG_ON(xpc_partition_disengage_requested(1UL <<
+ partid));
+
+ xpc_update_partition_info(part, remote_rp_version,
+ &remote_rp_stamp, remote_rp_pa,
+ remote_vars_pa, remote_vars);
+ reactivate = 1;
+ }
+ }
+
+ if (!xpc_partition_disengaged(part)) {
+ /* still waiting on other side to disengage from us */
+ return;
+ }
+
+ if (reactivate) {
part->reactivate_nasid = nasid;
XPC_DEACTIVATE_PARTITION(part, xpcReactivating);
+
+ } else if (XPC_SUPPORTS_DISENGAGE_REQUEST(part->remote_vars_version) &&
+ xpc_partition_disengage_requested(1UL << partid)) {
+ XPC_DEACTIVATE_PARTITION(part, xpcOtherGoingDown);
}
}
@@ -643,14 +802,17 @@ xpc_identify_act_IRQ_sender(void)
u64 nasid; /* remote nasid */
int n_IRQs_detected = 0;
AMO_t *act_amos;
- struct xpc_rsvd_page *rp = (struct xpc_rsvd_page *) xpc_rsvd_page;
- act_amos = xpc_vars->act_amos;
+ act_amos = xpc_vars->amos_page + XPC_ACTIVATE_IRQ_AMOS;
/* scan through act AMO variable looking for non-zero entries */
- for (word = 0; word < XP_NASID_MASK_WORDS; word++) {
+ for (word = 0; word < xp_nasid_mask_words; word++) {
+
+ if (xpc_exiting) {
+ break;
+ }
nasid_mask = xpc_IPI_receive(&act_amos[word]);
if (nasid_mask == 0) {
@@ -668,7 +830,7 @@ xpc_identify_act_IRQ_sender(void)
* remote nasid in our reserved pages machine mask.
* This is used in the event of module reload.
*/
- rp->mach_nasids[word] |= nasid_mask;
+ xpc_mach_nasids[word] |= nasid_mask;
/* locate the nasid(s) which sent interrupts */
@@ -688,6 +850,55 @@ xpc_identify_act_IRQ_sender(void)
/*
+ * See if the other side has responded to a partition disengage request
+ * from us.
+ */
+int
+xpc_partition_disengaged(struct xpc_partition *part)
+{
+ partid_t partid = XPC_PARTID(part);
+ int disengaged;
+
+
+ disengaged = (xpc_partition_engaged(1UL << partid) == 0);
+ if (part->disengage_request_timeout) {
+ if (!disengaged) {
+ if (jiffies < part->disengage_request_timeout) {
+ /* timelimit hasn't been reached yet */
+ return 0;
+ }
+
+ /*
+ * Other side hasn't responded to our disengage
+ * request in a timely fashion, so assume it's dead.
+ */
+
+ xpc_clear_partition_engaged(1UL << partid);
+ disengaged = 1;
+ }
+ part->disengage_request_timeout = 0;
+
+ /* cancel the timer function, provided it's not us */
+ if (!in_interrupt()) {
+ del_singleshot_timer_sync(&part->
+ disengage_request_timer);
+ }
+
+ DBUG_ON(part->act_state != XPC_P_DEACTIVATING &&
+ part->act_state != XPC_P_INACTIVE);
+ if (part->act_state != XPC_P_INACTIVE) {
+ xpc_wakeup_channel_mgr(part);
+ }
+
+ if (XPC_SUPPORTS_DISENGAGE_REQUEST(part->remote_vars_version)) {
+ xpc_cancel_partition_disengage_request(part);
+ }
+ }
+ return disengaged;
+}
+
+
+/*
* Mark specified partition as active.
*/
enum xpc_retval
@@ -721,7 +932,6 @@ xpc_deactivate_partition(const int line, struct xpc_partition *part,
enum xpc_retval reason)
{
unsigned long irq_flags;
- partid_t partid = XPC_PARTID(part);
spin_lock_irqsave(&part->act_lock, irq_flags);
@@ -749,17 +959,27 @@ xpc_deactivate_partition(const int line, struct xpc_partition *part,
spin_unlock_irqrestore(&part->act_lock, irq_flags);
- XPC_DISALLOW_HB(partid, xpc_vars);
+ if (XPC_SUPPORTS_DISENGAGE_REQUEST(part->remote_vars_version)) {
+ xpc_request_partition_disengage(part);
+ xpc_IPI_send_disengage(part);
- dev_dbg(xpc_part, "bringing partition %d down, reason = %d\n", partid,
- reason);
+ /* set a timelimit on the disengage request */
+ part->disengage_request_timeout = jiffies +
+ (xpc_disengage_request_timelimit * HZ);
+ part->disengage_request_timer.expires =
+ part->disengage_request_timeout;
+ add_timer(&part->disengage_request_timer);
+ }
+
+ dev_dbg(xpc_part, "bringing partition %d down, reason = %d\n",
+ XPC_PARTID(part), reason);
- xpc_partition_down(part, reason);
+ xpc_partition_going_down(part, reason);
}
/*
- * Mark specified partition as active.
+ * Mark specified partition as inactive.
*/
void
xpc_mark_partition_inactive(struct xpc_partition *part)
@@ -792,9 +1012,10 @@ xpc_discovery(void)
void *remote_rp_base;
struct xpc_rsvd_page *remote_rp;
struct xpc_vars *remote_vars;
- u64 remote_rsvd_page_pa;
+ u64 remote_rp_pa;
u64 remote_vars_pa;
int region;
+ int region_size;
int max_regions;
int nasid;
struct xpc_rsvd_page *rp;
@@ -804,7 +1025,8 @@ xpc_discovery(void)
enum xpc_retval ret;
- remote_rp = xpc_kmalloc_cacheline_aligned(XPC_RSVD_PAGE_ALIGNED_SIZE,
+ remote_rp = xpc_kmalloc_cacheline_aligned(XPC_RP_HEADER_SIZE +
+ xp_nasid_mask_bytes,
GFP_KERNEL, &remote_rp_base);
if (remote_rp == NULL) {
return;
@@ -812,13 +1034,13 @@ xpc_discovery(void)
remote_vars = (struct xpc_vars *) remote_rp;
- discovered_nasids = kmalloc(sizeof(u64) * XP_NASID_MASK_WORDS,
+ discovered_nasids = kmalloc(sizeof(u64) * xp_nasid_mask_words,
GFP_KERNEL);
if (discovered_nasids == NULL) {
kfree(remote_rp_base);
return;
}
- memset(discovered_nasids, 0, sizeof(u64) * XP_NASID_MASK_WORDS);
+ memset(discovered_nasids, 0, sizeof(u64) * xp_nasid_mask_words);
rp = (struct xpc_rsvd_page *) xpc_rsvd_page;
@@ -827,11 +1049,19 @@ xpc_discovery(void)
* nodes that can comprise an access protection grouping. The access
* protection is in regards to memory, IOI and IPI.
*/
-//>>> move the next two #defines into either include/asm-ia64/sn/arch.h or
-//>>> include/asm-ia64/sn/addrs.h
-#define SH1_MAX_REGIONS 64
-#define SH2_MAX_REGIONS 256
- max_regions = is_shub2() ? SH2_MAX_REGIONS : SH1_MAX_REGIONS;
+ max_regions = 64;
+ region_size = sn_region_size;
+
+ switch (region_size) {
+ case 128:
+ max_regions *= 2;
+ case 64:
+ max_regions *= 2;
+ case 32:
+ max_regions *= 2;
+ region_size = 16;
+ DBUG_ON(!is_shub2());
+ }
for (region = 0; region < max_regions; region++) {
@@ -841,8 +1071,8 @@ xpc_discovery(void)
dev_dbg(xpc_part, "searching region %d\n", region);
- for (nasid = (region * sn_region_size * 2);
- nasid < ((region + 1) * sn_region_size * 2);
+ for (nasid = (region * region_size * 2);
+ nasid < ((region + 1) * region_size * 2);
nasid += 2) {
if ((volatile int) xpc_exiting) {
@@ -852,14 +1082,14 @@ xpc_discovery(void)
dev_dbg(xpc_part, "checking nasid %d\n", nasid);
- if (XPC_NASID_IN_ARRAY(nasid, rp->part_nasids)) {
+ if (XPC_NASID_IN_ARRAY(nasid, xpc_part_nasids)) {
dev_dbg(xpc_part, "PROM indicates Nasid %d is "
"part of the local partition; skipping "
"region\n", nasid);
break;
}
- if (!(XPC_NASID_IN_ARRAY(nasid, rp->mach_nasids))) {
+ if (!(XPC_NASID_IN_ARRAY(nasid, xpc_mach_nasids))) {
dev_dbg(xpc_part, "PROM indicates Nasid %d was "
"not on Numa-Link network at reset\n",
nasid);
@@ -877,7 +1107,7 @@ xpc_discovery(void)
/* pull over the reserved page structure */
ret = xpc_get_remote_rp(nasid, discovered_nasids,
- remote_rp, &remote_rsvd_page_pa);
+ remote_rp, &remote_rp_pa);
if (ret != xpcSuccess) {
dev_dbg(xpc_part, "unable to get reserved page "
"from nasid %d, reason=%d\n", nasid,
@@ -948,6 +1178,13 @@ xpc_discovery(void)
remote_vars->act_nasid,
remote_vars->act_phys_cpuid);
+ if (XPC_SUPPORTS_DISENGAGE_REQUEST(remote_vars->
+ version)) {
+ part->remote_amos_page_pa =
+ remote_vars->amos_page_pa;
+ xpc_mark_partition_disengaged(part);
+ xpc_cancel_partition_disengage_request(part);
+ }
xpc_IPI_send_activate(remote_vars);
}
}
@@ -974,12 +1211,12 @@ xpc_initiate_partid_to_nasids(partid_t partid, void *nasid_mask)
return xpcPartitionDown;
}
- part_nasid_pa = part->remote_rp_pa +
- (u64) &((struct xpc_rsvd_page *) 0)->part_nasids;
+ memset(nasid_mask, 0, XP_NASID_MASK_BYTES);
+
+ part_nasid_pa = (u64) XPC_RP_PART_NASIDS(part->remote_rp_pa);
bte_res = xp_bte_copy(part_nasid_pa, ia64_tpa((u64) nasid_mask),
- L1_CACHE_ALIGN(XP_NASID_MASK_BYTES),
- (BTE_NOTIFY | BTE_WACQUIRE), NULL);
+ xp_nasid_mask_bytes, (BTE_NOTIFY | BTE_WACQUIRE), NULL);
return xpc_map_bte_errors(bte_res);
}
diff --git a/arch/ia64/sn/pci/pci_dma.c b/arch/ia64/sn/pci/pci_dma.c
index 0e4b9ad9ef02..9bf9f23b9a1f 100644
--- a/arch/ia64/sn/pci/pci_dma.c
+++ b/arch/ia64/sn/pci/pci_dma.c
@@ -75,7 +75,7 @@ EXPORT_SYMBOL(sn_dma_set_mask);
* more information.
*/
void *sn_dma_alloc_coherent(struct device *dev, size_t size,
- dma_addr_t * dma_handle, int flags)
+ dma_addr_t * dma_handle, gfp_t flags)
{
void *cpuaddr;
unsigned long phys_addr;
@@ -326,6 +326,29 @@ int sn_pci_legacy_read(struct pci_bus *bus, u16 port, u32 *val, u8 size)
{
unsigned long addr;
int ret;
+ struct ia64_sal_retval isrv;
+
+ /*
+ * First, try the SN_SAL_IOIF_PCI_SAFE SAL call which can work
+ * around hw issues at the pci bus level. SGI proms older than
+ * 4.10 don't implment this.
+ */
+
+ SAL_CALL(isrv, SN_SAL_IOIF_PCI_SAFE,
+ pci_domain_nr(bus), bus->number,
+ 0, /* io */
+ 0, /* read */
+ port, size, __pa(val));
+
+ if (isrv.status == 0)
+ return size;
+
+ /*
+ * If the above failed, retry using the SAL_PROBE call which should
+ * be present in all proms (but which cannot work round PCI chipset
+ * bugs). This code is retained for compatability with old
+ * pre-4.10 proms, and should be removed at some point in the future.
+ */
if (!SN_PCIBUS_BUSSOFT(bus))
return -ENODEV;
@@ -349,6 +372,29 @@ int sn_pci_legacy_write(struct pci_bus *bus, u16 port, u32 val, u8 size)
int ret = size;
unsigned long paddr;
unsigned long *addr;
+ struct ia64_sal_retval isrv;
+
+ /*
+ * First, try the SN_SAL_IOIF_PCI_SAFE SAL call which can work
+ * around hw issues at the pci bus level. SGI proms older than
+ * 4.10 don't implment this.
+ */
+
+ SAL_CALL(isrv, SN_SAL_IOIF_PCI_SAFE,
+ pci_domain_nr(bus), bus->number,
+ 0, /* io */
+ 1, /* write */
+ port, size, __pa(&val));
+
+ if (isrv.status == 0)
+ return size;
+
+ /*
+ * If the above failed, retry using the SAL_PROBE call which should
+ * be present in all proms (but which cannot work round PCI chipset
+ * bugs). This code is retained for compatability with old
+ * pre-4.10 proms, and should be removed at some point in the future.
+ */
if (!SN_PCIBUS_BUSSOFT(bus)) {
ret = -ENODEV;
diff --git a/arch/ia64/sn/pci/pcibr/pcibr_provider.c b/arch/ia64/sn/pci/pcibr/pcibr_provider.c
index 7b03b8084ffc..1f500c81002c 100644
--- a/arch/ia64/sn/pci/pcibr/pcibr_provider.c
+++ b/arch/ia64/sn/pci/pcibr/pcibr_provider.c
@@ -212,13 +212,13 @@ void pcibr_target_interrupt(struct sn_irq_info *sn_irq_info)
pdi_pcibus_info;
/* Disable the device's IRQ */
- pcireg_intr_enable_bit_clr(pcibus_info, bit);
+ pcireg_intr_enable_bit_clr(pcibus_info, (1 << bit));
/* Change the device's IRQ */
pcireg_intr_addr_addr_set(pcibus_info, bit, xtalk_addr);
/* Re-enable the device's IRQ */
- pcireg_intr_enable_bit_set(pcibus_info, bit);
+ pcireg_intr_enable_bit_set(pcibus_info, (1 << bit));
pcibr_force_interrupt(sn_irq_info);
}
diff --git a/arch/ia64/sn/pci/pcibr/pcibr_reg.c b/arch/ia64/sn/pci/pcibr/pcibr_reg.c
index 21426d02fbe6..5d534091262c 100644
--- a/arch/ia64/sn/pci/pcibr/pcibr_reg.c
+++ b/arch/ia64/sn/pci/pcibr/pcibr_reg.c
@@ -8,6 +8,7 @@
#include <linux/interrupt.h>
#include <linux/types.h>
+#include <asm/sn/io.h>
#include <asm/sn/pcibr_provider.h>
#include <asm/sn/pcibus_provider_defs.h>
#include <asm/sn/pcidev.h>
@@ -29,10 +30,10 @@ void pcireg_control_bit_clr(struct pcibus_info *pcibus_info, uint64_t bits)
if (pcibus_info) {
switch (pcibus_info->pbi_bridge_type) {
case PCIBR_BRIDGETYPE_TIOCP:
- ptr->tio.cp_control &= ~bits;
+ __sn_clrq_relaxed(&ptr->tio.cp_control, bits);
break;
case PCIBR_BRIDGETYPE_PIC:
- ptr->pic.p_wid_control &= ~bits;
+ __sn_clrq_relaxed(&ptr->pic.p_wid_control, bits);
break;
default:
panic
@@ -49,10 +50,10 @@ void pcireg_control_bit_set(struct pcibus_info *pcibus_info, uint64_t bits)
if (pcibus_info) {
switch (pcibus_info->pbi_bridge_type) {
case PCIBR_BRIDGETYPE_TIOCP:
- ptr->tio.cp_control |= bits;
+ __sn_setq_relaxed(&ptr->tio.cp_control, bits);
break;
case PCIBR_BRIDGETYPE_PIC:
- ptr->pic.p_wid_control |= bits;
+ __sn_setq_relaxed(&ptr->pic.p_wid_control, bits);
break;
default:
panic
@@ -73,10 +74,10 @@ uint64_t pcireg_tflush_get(struct pcibus_info *pcibus_info)
if (pcibus_info) {
switch (pcibus_info->pbi_bridge_type) {
case PCIBR_BRIDGETYPE_TIOCP:
- ret = ptr->tio.cp_tflush;
+ ret = __sn_readq_relaxed(&ptr->tio.cp_tflush);
break;
case PCIBR_BRIDGETYPE_PIC:
- ret = ptr->pic.p_wid_tflush;
+ ret = __sn_readq_relaxed(&ptr->pic.p_wid_tflush);
break;
default:
panic
@@ -103,10 +104,10 @@ uint64_t pcireg_intr_status_get(struct pcibus_info * pcibus_info)
if (pcibus_info) {
switch (pcibus_info->pbi_bridge_type) {
case PCIBR_BRIDGETYPE_TIOCP:
- ret = ptr->tio.cp_int_status;
+ ret = __sn_readq_relaxed(&ptr->tio.cp_int_status);
break;
case PCIBR_BRIDGETYPE_PIC:
- ret = ptr->pic.p_int_status;
+ ret = __sn_readq_relaxed(&ptr->pic.p_int_status);
break;
default:
panic
@@ -127,10 +128,10 @@ void pcireg_intr_enable_bit_clr(struct pcibus_info *pcibus_info, uint64_t bits)
if (pcibus_info) {
switch (pcibus_info->pbi_bridge_type) {
case PCIBR_BRIDGETYPE_TIOCP:
- ptr->tio.cp_int_enable &= ~bits;
+ __sn_clrq_relaxed(&ptr->tio.cp_int_enable, bits);
break;
case PCIBR_BRIDGETYPE_PIC:
- ptr->pic.p_int_enable &= ~bits;
+ __sn_clrq_relaxed(&ptr->pic.p_int_enable, bits);
break;
default:
panic
@@ -147,10 +148,10 @@ void pcireg_intr_enable_bit_set(struct pcibus_info *pcibus_info, uint64_t bits)
if (pcibus_info) {
switch (pcibus_info->pbi_bridge_type) {
case PCIBR_BRIDGETYPE_TIOCP:
- ptr->tio.cp_int_enable |= bits;
+ __sn_setq_relaxed(&ptr->tio.cp_int_enable, bits);
break;
case PCIBR_BRIDGETYPE_PIC:
- ptr->pic.p_int_enable |= bits;
+ __sn_setq_relaxed(&ptr->pic.p_int_enable, bits);
break;
default:
panic
@@ -171,14 +172,16 @@ void pcireg_intr_addr_addr_set(struct pcibus_info *pcibus_info, int int_n,
if (pcibus_info) {
switch (pcibus_info->pbi_bridge_type) {
case PCIBR_BRIDGETYPE_TIOCP:
- ptr->tio.cp_int_addr[int_n] &= ~TIOCP_HOST_INTR_ADDR;
- ptr->tio.cp_int_addr[int_n] |=
- (addr & TIOCP_HOST_INTR_ADDR);
+ __sn_clrq_relaxed(&ptr->tio.cp_int_addr[int_n],
+ TIOCP_HOST_INTR_ADDR);
+ __sn_setq_relaxed(&ptr->tio.cp_int_addr[int_n],
+ (addr & TIOCP_HOST_INTR_ADDR));
break;
case PCIBR_BRIDGETYPE_PIC:
- ptr->pic.p_int_addr[int_n] &= ~PIC_HOST_INTR_ADDR;
- ptr->pic.p_int_addr[int_n] |=
- (addr & PIC_HOST_INTR_ADDR);
+ __sn_clrq_relaxed(&ptr->pic.p_int_addr[int_n],
+ PIC_HOST_INTR_ADDR);
+ __sn_setq_relaxed(&ptr->pic.p_int_addr[int_n],
+ (addr & PIC_HOST_INTR_ADDR));
break;
default:
panic
@@ -198,10 +201,10 @@ void pcireg_force_intr_set(struct pcibus_info *pcibus_info, int int_n)
if (pcibus_info) {
switch (pcibus_info->pbi_bridge_type) {
case PCIBR_BRIDGETYPE_TIOCP:
- ptr->tio.cp_force_pin[int_n] = 1;
+ writeq(1, &ptr->tio.cp_force_pin[int_n]);
break;
case PCIBR_BRIDGETYPE_PIC:
- ptr->pic.p_force_pin[int_n] = 1;
+ writeq(1, &ptr->pic.p_force_pin[int_n]);
break;
default:
panic
@@ -222,10 +225,12 @@ uint64_t pcireg_wrb_flush_get(struct pcibus_info *pcibus_info, int device)
if (pcibus_info) {
switch (pcibus_info->pbi_bridge_type) {
case PCIBR_BRIDGETYPE_TIOCP:
- ret = ptr->tio.cp_wr_req_buf[device];
+ ret =
+ __sn_readq_relaxed(&ptr->tio.cp_wr_req_buf[device]);
break;
case PCIBR_BRIDGETYPE_PIC:
- ret = ptr->pic.p_wr_req_buf[device];
+ ret =
+ __sn_readq_relaxed(&ptr->pic.p_wr_req_buf[device]);
break;
default:
panic("pcireg_wrb_flush_get: unknown bridgetype bridge 0x%p", (void *)ptr);
@@ -244,10 +249,10 @@ void pcireg_int_ate_set(struct pcibus_info *pcibus_info, int ate_index,
if (pcibus_info) {
switch (pcibus_info->pbi_bridge_type) {
case PCIBR_BRIDGETYPE_TIOCP:
- ptr->tio.cp_int_ate_ram[ate_index] = (uint64_t) val;
+ writeq(val, &ptr->tio.cp_int_ate_ram[ate_index]);
break;
case PCIBR_BRIDGETYPE_PIC:
- ptr->pic.p_int_ate_ram[ate_index] = (uint64_t) val;
+ writeq(val, &ptr->pic.p_int_ate_ram[ate_index]);
break;
default:
panic
@@ -265,12 +270,10 @@ uint64_t *pcireg_int_ate_addr(struct pcibus_info *pcibus_info, int ate_index)
if (pcibus_info) {
switch (pcibus_info->pbi_bridge_type) {
case PCIBR_BRIDGETYPE_TIOCP:
- ret =
- (uint64_t *) & (ptr->tio.cp_int_ate_ram[ate_index]);
+ ret = &ptr->tio.cp_int_ate_ram[ate_index];
break;
case PCIBR_BRIDGETYPE_PIC:
- ret =
- (uint64_t *) & (ptr->pic.p_int_ate_ram[ate_index]);
+ ret = &ptr->pic.p_int_ate_ram[ate_index];
break;
default:
panic
diff --git a/arch/ia64/sn/pci/tioca_provider.c b/arch/ia64/sn/pci/tioca_provider.c
index 19bced34d5f1..46b646a6d345 100644
--- a/arch/ia64/sn/pci/tioca_provider.c
+++ b/arch/ia64/sn/pci/tioca_provider.c
@@ -11,6 +11,7 @@
#include <linux/pci.h>
#include <asm/sn/sn_sal.h>
#include <asm/sn/addrs.h>
+#include <asm/sn/io.h>
#include <asm/sn/pcidev.h>
#include <asm/sn/pcibus_provider_defs.h>
#include <asm/sn/tioca_provider.h>
@@ -37,7 +38,7 @@ tioca_gart_init(struct tioca_kernel *tioca_kern)
uint64_t offset;
struct page *tmp;
struct tioca_common *tioca_common;
- volatile struct tioca *ca_base;
+ struct tioca *ca_base;
tioca_common = tioca_kern->ca_common;
ca_base = (struct tioca *)tioca_common->ca_common.bs_base;
@@ -174,27 +175,29 @@ tioca_gart_init(struct tioca_kernel *tioca_kern)
* DISABLE GART PREFETCHING due to hw bug tracked in SGI PV930029
*/
- ca_base->ca_control1 |= CA_AGPDMA_OP_ENB_COMBDELAY; /* PV895469 ? */
- ca_base->ca_control2 &= ~(CA_GART_MEM_PARAM);
- ca_base->ca_control2 |= (0x2ull << CA_GART_MEM_PARAM_SHFT);
+ __sn_setq_relaxed(&ca_base->ca_control1,
+ CA_AGPDMA_OP_ENB_COMBDELAY); /* PV895469 ? */
+ __sn_clrq_relaxed(&ca_base->ca_control2, CA_GART_MEM_PARAM);
+ __sn_setq_relaxed(&ca_base->ca_control2,
+ (0x2ull << CA_GART_MEM_PARAM_SHFT));
tioca_kern->ca_gart_iscoherent = 1;
- ca_base->ca_control2 &=
- ~(CA_GART_WR_PREFETCH_ENB | CA_GART_RD_PREFETCH_ENB);
+ __sn_clrq_relaxed(&ca_base->ca_control2,
+ (CA_GART_WR_PREFETCH_ENB | CA_GART_RD_PREFETCH_ENB));
/*
* Unmask GART fetch error interrupts. Clear residual errors first.
*/
- ca_base->ca_int_status_alias = CA_GART_FETCH_ERR;
- ca_base->ca_mult_error_alias = CA_GART_FETCH_ERR;
- ca_base->ca_int_mask &= ~CA_GART_FETCH_ERR;
+ writeq(CA_GART_FETCH_ERR, &ca_base->ca_int_status_alias);
+ writeq(CA_GART_FETCH_ERR, &ca_base->ca_mult_error_alias);
+ __sn_clrq_relaxed(&ca_base->ca_int_mask, CA_GART_FETCH_ERR);
/*
* Program the aperature and gart registers in TIOCA
*/
- ca_base->ca_gart_aperature = ap_reg;
- ca_base->ca_gart_ptr_table = tioca_kern->ca_gart_coretalk_addr | 1;
+ writeq(ap_reg, &ca_base->ca_gart_aperature);
+ writeq(tioca_kern->ca_gart_coretalk_addr|1, &ca_base->ca_gart_ptr_table);
return 0;
}
@@ -211,7 +214,6 @@ void
tioca_fastwrite_enable(struct tioca_kernel *tioca_kern)
{
int cap_ptr;
- uint64_t ca_control1;
uint32_t reg;
struct tioca *tioca_base;
struct pci_dev *pdev;
@@ -256,9 +258,7 @@ tioca_fastwrite_enable(struct tioca_kernel *tioca_kern)
*/
tioca_base = (struct tioca *)common->ca_common.bs_base;
- ca_control1 = tioca_base->ca_control1;
- ca_control1 |= CA_AGP_FW_ENABLE;
- tioca_base->ca_control1 = ca_control1;
+ __sn_setq_relaxed(&tioca_base->ca_control1, CA_AGP_FW_ENABLE);
}
EXPORT_SYMBOL(tioca_fastwrite_enable); /* used by agp-sgi */
@@ -345,7 +345,7 @@ tioca_dma_d48(struct pci_dev *pdev, uint64_t paddr)
return 0;
}
- agp_dma_extn = ca_base->ca_agp_dma_addr_extn;
+ agp_dma_extn = __sn_readq_relaxed(&ca_base->ca_agp_dma_addr_extn);
if (node_upper != (agp_dma_extn >> CA_AGP_DMA_NODE_ID_SHFT)) {
printk(KERN_ERR "%s: coretalk upper node (%u) "
"mismatch with ca_agp_dma_addr_extn (%lu)\n",
diff --git a/arch/ia64/sn/pci/tioce_provider.c b/arch/ia64/sn/pci/tioce_provider.c
index 8e75db2b825d..dda196c9e324 100644
--- a/arch/ia64/sn/pci/tioce_provider.c
+++ b/arch/ia64/sn/pci/tioce_provider.c
@@ -11,6 +11,7 @@
#include <linux/pci.h>
#include <asm/sn/sn_sal.h>
#include <asm/sn/addrs.h>
+#include <asm/sn/io.h>
#include <asm/sn/pcidev.h>
#include <asm/sn/pcibus_provider_defs.h>
#include <asm/sn/tioce_provider.h>
@@ -217,7 +218,7 @@ tioce_alloc_map(struct tioce_kernel *ce_kern, int type, int port,
if (i > last)
return 0;
- map = kcalloc(1, sizeof(struct tioce_dmamap), GFP_ATOMIC);
+ map = kzalloc(sizeof(struct tioce_dmamap), GFP_ATOMIC);
if (!map)
return 0;
@@ -227,7 +228,7 @@ tioce_alloc_map(struct tioce_kernel *ce_kern, int type, int port,
ate = ATE_MAKE(addr, pagesize);
ate_shadow[i + j] = ate;
- ate_reg[i + j] = ate;
+ writeq(ate, &ate_reg[i + j]);
addr += pagesize;
}
@@ -268,10 +269,10 @@ tioce_dma_d32(struct pci_dev *pdev, uint64_t ct_addr)
pcidev_to_tioce(pdev, &ce_mmr, &ce_kern, &port);
if (ce_kern->ce_port[port].dirmap_refcnt == 0) {
- volatile uint64_t tmp;
+ uint64_t tmp;
ce_kern->ce_port[port].dirmap_shadow = ct_upper;
- ce_mmr->ce_ure_dir_map[port] = ct_upper;
+ writeq(ct_upper, &ce_mmr->ce_ure_dir_map[port]);
tmp = ce_mmr->ce_ure_dir_map[port];
dma_ok = 1;
} else
@@ -343,7 +344,7 @@ tioce_dma_unmap(struct pci_dev *pdev, dma_addr_t bus_addr, int dir)
if (TIOCE_D32_ADDR(bus_addr)) {
if (--ce_kern->ce_port[port].dirmap_refcnt == 0) {
ce_kern->ce_port[port].dirmap_shadow = 0;
- ce_mmr->ce_ure_dir_map[port] = 0;
+ writeq(0, &ce_mmr->ce_ure_dir_map[port]);
}
} else {
struct tioce_dmamap *map;
@@ -554,7 +555,7 @@ tioce_kern_init(struct tioce_common *tioce_common)
struct tioce *tioce_mmr;
struct tioce_kernel *tioce_kern;
- tioce_kern = kcalloc(1, sizeof(struct tioce_kernel), GFP_KERNEL);
+ tioce_kern = kzalloc(sizeof(struct tioce_kernel), GFP_KERNEL);
if (!tioce_kern) {
return NULL;
}
@@ -582,18 +583,18 @@ tioce_kern_init(struct tioce_common *tioce_common)
*/
tioce_mmr = (struct tioce *)tioce_common->ce_pcibus.bs_base;
- tioce_mmr->ce_ure_page_map &= ~CE_URE_PAGESIZE_MASK;
- tioce_mmr->ce_ure_page_map |= CE_URE_256K_PAGESIZE;
+ __sn_clrq_relaxed(&tioce_mmr->ce_ure_page_map, CE_URE_PAGESIZE_MASK);
+ __sn_setq_relaxed(&tioce_mmr->ce_ure_page_map, CE_URE_256K_PAGESIZE);
tioce_kern->ce_ate3240_pagesize = KB(256);
for (i = 0; i < TIOCE_NUM_M40_ATES; i++) {
tioce_kern->ce_ate40_shadow[i] = 0;
- tioce_mmr->ce_ure_ate40[i] = 0;
+ writeq(0, &tioce_mmr->ce_ure_ate40[i]);
}
for (i = 0; i < TIOCE_NUM_M3240_ATES; i++) {
tioce_kern->ce_ate3240_shadow[i] = 0;
- tioce_mmr->ce_ure_ate3240[i] = 0;
+ writeq(0, &tioce_mmr->ce_ure_ate3240[i]);
}
return tioce_kern;
@@ -665,7 +666,7 @@ tioce_force_interrupt(struct sn_irq_info *sn_irq_info)
default:
return;
}
- ce_mmr->ce_adm_force_int = force_int_val;
+ writeq(force_int_val, &ce_mmr->ce_adm_force_int);
}
/**
@@ -686,6 +687,7 @@ tioce_target_interrupt(struct sn_irq_info *sn_irq_info)
struct tioce_common *ce_common;
struct tioce *ce_mmr;
int bit;
+ uint64_t vector;
pcidev_info = (struct pcidev_info *)sn_irq_info->irq_pciioinfo;
if (!pcidev_info)
@@ -696,11 +698,11 @@ tioce_target_interrupt(struct sn_irq_info *sn_irq_info)
bit = sn_irq_info->irq_int_bit;
- ce_mmr->ce_adm_int_mask |= (1UL << bit);
- ce_mmr->ce_adm_int_dest[bit] =
- ((uint64_t)sn_irq_info->irq_irq << INTR_VECTOR_SHFT) |
- sn_irq_info->irq_xtalkaddr;
- ce_mmr->ce_adm_int_mask &= ~(1UL << bit);
+ __sn_setq_relaxed(&ce_mmr->ce_adm_int_mask, (1UL << bit));
+ vector = (uint64_t)sn_irq_info->irq_irq << INTR_VECTOR_SHFT;
+ vector |= sn_irq_info->irq_xtalkaddr;
+ writeq(vector, &ce_mmr->ce_adm_int_dest[bit]);
+ __sn_clrq_relaxed(&ce_mmr->ce_adm_int_mask, (1UL << bit));
tioce_force_interrupt(sn_irq_info);
}
@@ -725,7 +727,7 @@ tioce_bus_fixup(struct pcibus_bussoft *prom_bussoft, struct pci_controller *cont
* Allocate kernel bus soft and copy from prom.
*/
- tioce_common = kcalloc(1, sizeof(struct tioce_common), GFP_KERNEL);
+ tioce_common = kzalloc(sizeof(struct tioce_common), GFP_KERNEL);
if (!tioce_common)
return NULL;
diff --git a/arch/m32r/kernel/entry.S b/arch/m32r/kernel/entry.S
index 85920fb8d08c..396c94218cc2 100644
--- a/arch/m32r/kernel/entry.S
+++ b/arch/m32r/kernel/entry.S
@@ -653,8 +653,6 @@ ENTRY(rie_handler)
SAVE_ALL
mvfc r0, bpc
ld r1, @r0
- seth r0, #0xa0f0
- st r1, @r0
ldi r1, #0x20 ; error_code
mv r0, sp ; pt_regs
bl do_rie_handler
diff --git a/arch/m32r/kernel/io_m32700ut.c b/arch/m32r/kernel/io_m32700ut.c
index e545b065f7e9..eda9f963c1eb 100644
--- a/arch/m32r/kernel/io_m32700ut.c
+++ b/arch/m32r/kernel/io_m32700ut.c
@@ -64,11 +64,11 @@ static inline void *__port2addr_ata(unsigned long port)
* from 0x10000000 to 0x13ffffff on physical address.
* The base address of LAN controller(LAN91C111) is 0x300.
*/
-#define LAN_IOSTART 0x300
-#define LAN_IOEND 0x320
+#define LAN_IOSTART 0xa0000300
+#define LAN_IOEND 0xa0000320
static inline void *_port2addr_ne(unsigned long port)
{
- return (void *)(port + NONCACHE_OFFSET + 0x10000000);
+ return (void *)(port + 0x10000000);
}
static inline void *_port2addr_usb(unsigned long port)
{
diff --git a/arch/m32r/kernel/io_mappi.c b/arch/m32r/kernel/io_mappi.c
index 78033165fb5c..3c3da042fbd1 100644
--- a/arch/m32r/kernel/io_mappi.c
+++ b/arch/m32r/kernel/io_mappi.c
@@ -31,7 +31,7 @@ extern void pcc_iowrite(int, unsigned long, void *, size_t, size_t, int);
static inline void *_port2addr(unsigned long port)
{
- return (void *)(port + NONCACHE_OFFSET);
+ return (void *)(port | (NONCACHE_OFFSET));
}
static inline void *_port2addr_ne(unsigned long port)
diff --git a/arch/m32r/kernel/io_mappi2.c b/arch/m32r/kernel/io_mappi2.c
index 5c03504bf653..df3c729cb3e0 100644
--- a/arch/m32r/kernel/io_mappi2.c
+++ b/arch/m32r/kernel/io_mappi2.c
@@ -33,12 +33,9 @@ extern void pcc_iowrite_word(int, unsigned long, void *, size_t, size_t, int);
static inline void *_port2addr(unsigned long port)
{
- return (void *)(port + NONCACHE_OFFSET);
+ return (void *)(port | (NONCACHE_OFFSET));
}
-#define LAN_IOSTART 0x300
-#define LAN_IOEND 0x320
-
#if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC)
static inline void *__port2addr_ata(unsigned long port)
{
@@ -59,15 +56,17 @@ static inline void *__port2addr_ata(unsigned long port)
}
#endif
+#define LAN_IOSTART 0xa0000300
+#define LAN_IOEND 0xa0000320
#ifdef CONFIG_CHIP_OPSP
static inline void *_port2addr_ne(unsigned long port)
{
- return (void *)(port + NONCACHE_OFFSET + 0x10000000);
+ return (void *)(port + 0x10000000);
}
#else
static inline void *_port2addr_ne(unsigned long port)
{
- return (void *)(port + NONCACHE_OFFSET + 0x04000000);
+ return (void *)(port + 0x04000000);
}
#endif
static inline void *_port2addr_usb(unsigned long port)
diff --git a/arch/m32r/kernel/io_mappi3.c b/arch/m32r/kernel/io_mappi3.c
index c80bde657854..6716ffea769a 100644
--- a/arch/m32r/kernel/io_mappi3.c
+++ b/arch/m32r/kernel/io_mappi3.c
@@ -36,9 +36,6 @@ static inline void *_port2addr(unsigned long port)
return (void *)(port + NONCACHE_OFFSET);
}
-#define LAN_IOSTART 0x300
-#define LAN_IOEND 0x320
-
#if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC)
static inline void *__port2addr_ata(unsigned long port)
{
@@ -59,9 +56,11 @@ static inline void *__port2addr_ata(unsigned long port)
}
#endif
+#define LAN_IOSTART 0xa0000300
+#define LAN_IOEND 0xa0000320
static inline void *_port2addr_ne(unsigned long port)
{
- return (void *)(port + NONCACHE_OFFSET + 0x10000000);
+ return (void *)(port + 0x10000000);
}
static inline void *_port2addr_usb(unsigned long port)
diff --git a/arch/m32r/kernel/io_oaks32r.c b/arch/m32r/kernel/io_oaks32r.c
index 9997dddd24d7..8be323931e4a 100644
--- a/arch/m32r/kernel/io_oaks32r.c
+++ b/arch/m32r/kernel/io_oaks32r.c
@@ -16,7 +16,7 @@
static inline void *_port2addr(unsigned long port)
{
- return (void *)(port + NONCACHE_OFFSET);
+ return (void *)(port | (NONCACHE_OFFSET));
}
static inline void *_port2addr_ne(unsigned long port)
diff --git a/arch/m32r/kernel/io_opsput.c b/arch/m32r/kernel/io_opsput.c
index e34951e8156f..4793bd18e115 100644
--- a/arch/m32r/kernel/io_opsput.c
+++ b/arch/m32r/kernel/io_opsput.c
@@ -36,7 +36,7 @@ extern void pcc_iowrite_word(int, unsigned long, void *, size_t, size_t, int);
static inline void *_port2addr(unsigned long port)
{
- return (void *)(port + NONCACHE_OFFSET);
+ return (void *)(port | (NONCACHE_OFFSET));
}
/*
@@ -44,11 +44,11 @@ static inline void *_port2addr(unsigned long port)
* from 0x10000000 to 0x13ffffff on physical address.
* The base address of LAN controller(LAN91C111) is 0x300.
*/
-#define LAN_IOSTART 0x300
-#define LAN_IOEND 0x320
+#define LAN_IOSTART 0xa0000300
+#define LAN_IOEND 0xa0000320
static inline void *_port2addr_ne(unsigned long port)
{
- return (void *)(port + NONCACHE_OFFSET + 0x10000000);
+ return (void *)(port + 0x10000000);
}
static inline void *_port2addr_usb(unsigned long port)
{
diff --git a/arch/m32r/kernel/io_usrv.c b/arch/m32r/kernel/io_usrv.c
index 9eb161dcc104..39a379af40bc 100644
--- a/arch/m32r/kernel/io_usrv.c
+++ b/arch/m32r/kernel/io_usrv.c
@@ -47,7 +47,7 @@ static inline void *_port2addr(unsigned long port)
else if (port >= UART1_IOSTART && port <= UART1_IOEND)
port = ((port - UART1_IOSTART) << 1) + UART1_REGSTART;
#endif /* CONFIG_SERIAL_8250 || CONFIG_SERIAL_8250_MODULE */
- return (void *)(port + NONCACHE_OFFSET);
+ return (void *)(port | (NONCACHE_OFFSET));
}
static inline void delay(void)
diff --git a/arch/m32r/kernel/process.c b/arch/m32r/kernel/process.c
index ea13a8f4d8b0..cc4b571e5db7 100644
--- a/arch/m32r/kernel/process.c
+++ b/arch/m32r/kernel/process.c
@@ -104,7 +104,9 @@ void cpu_idle (void)
idle();
}
+ preempt_enable_no_resched();
schedule();
+ preempt_disable();
}
}
diff --git a/arch/m32r/kernel/ptrace.c b/arch/m32r/kernel/ptrace.c
index 124f7c1b775e..078d2a0e71c2 100644
--- a/arch/m32r/kernel/ptrace.c
+++ b/arch/m32r/kernel/ptrace.c
@@ -756,7 +756,7 @@ do_ptrace(long request, struct task_struct *child, long addr, long data)
return ret;
}
-asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
+asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
{
struct task_struct *child;
int ret;
diff --git a/arch/m32r/kernel/setup.c b/arch/m32r/kernel/setup.c
index ec5674727e7f..f722ec8eb021 100644
--- a/arch/m32r/kernel/setup.c
+++ b/arch/m32r/kernel/setup.c
@@ -305,19 +305,19 @@ static int show_cpuinfo(struct seq_file *m, void *v)
seq_printf(m, "processor\t: %ld\n", cpu);
-#ifdef CONFIG_CHIP_VDEC2
+#if defined(CONFIG_CHIP_VDEC2)
seq_printf(m, "cpu family\t: VDEC2\n"
"cache size\t: Unknown\n");
-#elif CONFIG_CHIP_M32700
+#elif defined(CONFIG_CHIP_M32700)
seq_printf(m,"cpu family\t: M32700\n"
"cache size\t: I-8KB/D-8KB\n");
-#elif CONFIG_CHIP_M32102
+#elif defined(CONFIG_CHIP_M32102)
seq_printf(m,"cpu family\t: M32102\n"
"cache size\t: I-8KB\n");
-#elif CONFIG_CHIP_OPSP
+#elif defined(CONFIG_CHIP_OPSP)
seq_printf(m,"cpu family\t: OPSP\n"
"cache size\t: I-8KB/D-8KB\n");
-#elif CONFIG_CHIP_MP
+#elif defined(CONFIG_CHIP_MP)
seq_printf(m, "cpu family\t: M32R-MP\n"
"cache size\t: I-xxKB/D-xxKB\n");
#else
@@ -326,19 +326,19 @@ static int show_cpuinfo(struct seq_file *m, void *v)
seq_printf(m, "bogomips\t: %lu.%02lu\n",
c->loops_per_jiffy/(500000/HZ),
(c->loops_per_jiffy/(5000/HZ)) % 100);
-#ifdef CONFIG_PLAT_MAPPI
+#if defined(CONFIG_PLAT_MAPPI)
seq_printf(m, "Machine\t\t: Mappi Evaluation board\n");
-#elif CONFIG_PLAT_MAPPI2
+#elif defined(CONFIG_PLAT_MAPPI2)
seq_printf(m, "Machine\t\t: Mappi-II Evaluation board\n");
-#elif CONFIG_PLAT_MAPPI3
+#elif defined(CONFIG_PLAT_MAPPI3)
seq_printf(m, "Machine\t\t: Mappi-III Evaluation board\n");
-#elif CONFIG_PLAT_M32700UT
+#elif defined(CONFIG_PLAT_M32700UT)
seq_printf(m, "Machine\t\t: M32700UT Evaluation board\n");
-#elif CONFIG_PLAT_OPSPUT
+#elif defined(CONFIG_PLAT_OPSPUT)
seq_printf(m, "Machine\t\t: OPSPUT Evaluation board\n");
-#elif CONFIG_PLAT_USRV
+#elif defined(CONFIG_PLAT_USRV)
seq_printf(m, "Machine\t\t: uServer\n");
-#elif CONFIG_PLAT_OAKS32R
+#elif defined(CONFIG_PLAT_OAKS32R)
seq_printf(m, "Machine\t\t: OAKS32R\n");
#else
seq_printf(m, "Machine\t\t: Unknown\n");
diff --git a/arch/m32r/kernel/setup_m32700ut.c b/arch/m32r/kernel/setup_m32700ut.c
index 708634b685e4..cb76916b014d 100644
--- a/arch/m32r/kernel/setup_m32700ut.c
+++ b/arch/m32r/kernel/setup_m32700ut.c
@@ -15,7 +15,7 @@
#include <linux/irq.h>
#include <linux/kernel.h>
#include <linux/init.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <asm/system.h>
#include <asm/m32r.h>
diff --git a/arch/m32r/kernel/setup_mappi.c b/arch/m32r/kernel/setup_mappi.c
index 4e709809efc5..501d798cf050 100644
--- a/arch/m32r/kernel/setup_mappi.c
+++ b/arch/m32r/kernel/setup_mappi.c
@@ -11,7 +11,7 @@
#include <linux/irq.h>
#include <linux/kernel.h>
#include <linux/init.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <asm/system.h>
#include <asm/m32r.h>
diff --git a/arch/m32r/kernel/setup_mappi2.c b/arch/m32r/kernel/setup_mappi2.c
index a1d801598aa4..7f2db5bfd626 100644
--- a/arch/m32r/kernel/setup_mappi2.c
+++ b/arch/m32r/kernel/setup_mappi2.c
@@ -11,7 +11,7 @@
#include <linux/irq.h>
#include <linux/kernel.h>
#include <linux/init.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <asm/system.h>
#include <asm/m32r.h>
diff --git a/arch/m32r/kernel/setup_mappi3.c b/arch/m32r/kernel/setup_mappi3.c
index a76412e883e8..9c79341a7b45 100644
--- a/arch/m32r/kernel/setup_mappi3.c
+++ b/arch/m32r/kernel/setup_mappi3.c
@@ -11,7 +11,7 @@
#include <linux/irq.h>
#include <linux/kernel.h>
#include <linux/init.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <asm/system.h>
#include <asm/m32r.h>
diff --git a/arch/m32r/kernel/setup_opsput.c b/arch/m32r/kernel/setup_opsput.c
index d7b7ec6d30f8..1fbb140854e7 100644
--- a/arch/m32r/kernel/setup_opsput.c
+++ b/arch/m32r/kernel/setup_opsput.c
@@ -16,7 +16,7 @@
#include <linux/irq.h>
#include <linux/kernel.h>
#include <linux/init.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <asm/system.h>
#include <asm/m32r.h>
diff --git a/arch/m32r/kernel/smpboot.c b/arch/m32r/kernel/smpboot.c
index 640d592ea072..b90c54169fa5 100644
--- a/arch/m32r/kernel/smpboot.c
+++ b/arch/m32r/kernel/smpboot.c
@@ -426,6 +426,7 @@ void __init smp_cpus_done(unsigned int max_cpus)
int __init start_secondary(void *unused)
{
cpu_init();
+ preempt_disable();
smp_callin();
while (!cpu_isset(smp_processor_id(), smp_commenced_mask))
cpu_relax();
diff --git a/arch/m32r/kernel/time.c b/arch/m32r/kernel/time.c
index 539c562cd54d..2ebce2063fea 100644
--- a/arch/m32r/kernel/time.c
+++ b/arch/m32r/kernel/time.c
@@ -39,10 +39,6 @@ extern void send_IPI_allbutself(int, int);
extern void smp_local_timer_interrupt(struct pt_regs *);
#endif
-u64 jiffies_64 = INITIAL_JIFFIES;
-
-EXPORT_SYMBOL(jiffies_64);
-
extern unsigned long wall_jiffies;
#define TICK_SIZE (tick_nsec / 1000)
diff --git a/arch/m32r/lib/csum_partial_copy.c b/arch/m32r/lib/csum_partial_copy.c
index ddb16a83a8ce..3d5f06145854 100644
--- a/arch/m32r/lib/csum_partial_copy.c
+++ b/arch/m32r/lib/csum_partial_copy.c
@@ -18,10 +18,10 @@
#include <linux/module.h>
#include <linux/types.h>
+#include <linux/string.h>
#include <net/checksum.h>
#include <asm/byteorder.h>
-#include <asm/string.h>
#include <asm/uaccess.h>
/*
diff --git a/arch/m32r/mm/init.c b/arch/m32r/mm/init.c
index d9a40b1fe8ba..6facf15b04f3 100644
--- a/arch/m32r/mm/init.c
+++ b/arch/m32r/mm/init.c
@@ -48,6 +48,8 @@ void show_mem(void)
show_free_areas();
printk("Free swap: %6ldkB\n",nr_swap_pages<<(PAGE_SHIFT-10));
for_each_pgdat(pgdat) {
+ unsigned long flags;
+ pgdat_resize_lock(pgdat, &flags);
for (i = 0; i < pgdat->node_spanned_pages; ++i) {
page = pgdat_page_nr(pgdat, i);
total++;
@@ -60,6 +62,7 @@ void show_mem(void)
else if (page_count(page))
shared += page_count(page) - 1;
}
+ pgdat_resize_unlock(pgdat, &flags);
}
printk("%d pages of RAM\n", total);
printk("%d pages of HIGHMEM\n",highmem);
@@ -150,10 +153,14 @@ int __init reservedpages_count(void)
int reservedpages, nid, i;
reservedpages = 0;
- for_each_online_node(nid)
+ for_each_online_node(nid) {
+ unsigned long flags;
+ pgdat_resize_lock(NODE_DATA(nid), &flags);
for (i = 0 ; i < MAX_LOW_PFN(nid) - START_PFN(nid) ; i++)
if (PageReserved(nid_page_nr(nid, i)))
reservedpages++;
+ pgdat_resize_unlock(NODE_DATA(nid), &flags);
+ }
return reservedpages;
}
diff --git a/arch/m32r/mm/ioremap.c b/arch/m32r/mm/ioremap.c
index 70c59055c19c..a151849a605e 100644
--- a/arch/m32r/mm/ioremap.c
+++ b/arch/m32r/mm/ioremap.c
@@ -67,7 +67,7 @@ remap_area_pmd(pmd_t * pmd, unsigned long address, unsigned long size,
if (address >= end)
BUG();
do {
- pte_t * pte = pte_alloc_kernel(&init_mm, pmd, address);
+ pte_t * pte = pte_alloc_kernel(pmd, address);
if (!pte)
return -ENOMEM;
remap_area_pte(pte, address, end - address, address + phys_addr, flags);
@@ -90,7 +90,6 @@ remap_area_pages(unsigned long address, unsigned long phys_addr,
flush_cache_all();
if (address >= end)
BUG();
- spin_lock(&init_mm.page_table_lock);
do {
pmd_t *pmd;
pmd = pmd_alloc(&init_mm, dir, address);
@@ -104,7 +103,6 @@ remap_area_pages(unsigned long address, unsigned long phys_addr,
address = (address + PGDIR_SIZE) & PGDIR_MASK;
dir++;
} while (address && (address < end));
- spin_unlock(&init_mm.page_table_lock);
flush_tlb_all();
return error;
}
diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig
index ba960bbc8e6d..1dd5d18b2201 100644
--- a/arch/m68k/Kconfig
+++ b/arch/m68k/Kconfig
@@ -388,33 +388,11 @@ config AMIGA_PCMCIA
Include support in the kernel for pcmcia on Amiga 1200 and Amiga
600. If you intend to use pcmcia cards say Y; otherwise say N.
-config STRAM_SWAP
- bool "Support for ST-RAM as swap space"
- depends on ATARI && BROKEN
- ---help---
- Some Atari 68k machines (including the 520STF and 1020STE) divide
- their addressable memory into ST and TT sections. The TT section
- (up to 512MB) is the main memory; the ST section (up to 4MB) is
- accessible to the built-in graphics board, runs slower, and is
- present mainly for backward compatibility with older machines.
-
- This enables support for using (parts of) ST-RAM as swap space,
- instead of as normal system memory. This can first enhance system
- performance if you have lots of alternate RAM (compared to the size
- of ST-RAM), because executable code always will reside in faster
- memory. ST-RAM will remain as ultra-fast swap space. On the other
- hand, it allows much improved dynamic allocations of ST-RAM buffers
- for device driver modules (e.g. floppy, ACSI, SLM printer, DMA
- sound). The probability that such allocations at module load time
- fail is drastically reduced.
-
config STRAM_PROC
bool "ST-RAM statistics in /proc"
depends on ATARI
help
- Say Y here to report ST-RAM usage statistics in /proc/stram. See
- the help for CONFIG_STRAM_SWAP for discussion of ST-RAM and its
- uses.
+ Say Y here to report ST-RAM usage statistics in /proc/stram.
config HEARTBEAT
bool "Use power LED as a heartbeat" if AMIGA || APOLLO || ATARI || MAC ||Q40
diff --git a/arch/m68k/atari/stram.c b/arch/m68k/atari/stram.c
index 5a3c106b40c8..22e0481a5f7b 100644
--- a/arch/m68k/atari/stram.c
+++ b/arch/m68k/atari/stram.c
@@ -15,11 +15,9 @@
#include <linux/kdev_t.h>
#include <linux/major.h>
#include <linux/init.h>
-#include <linux/swap.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/pagemap.h>
-#include <linux/shm.h>
#include <linux/bootmem.h>
#include <linux/mount.h>
#include <linux/blkdev.h>
@@ -33,8 +31,6 @@
#include <asm/io.h>
#include <asm/semaphore.h>
-#include <linux/swapops.h>
-
#undef DEBUG
#ifdef DEBUG
@@ -49,8 +45,7 @@
#include <linux/proc_fs.h>
#endif
-/* Pre-swapping comments:
- *
+/*
* ++roman:
*
* New version of ST-Ram buffer allocation. Instead of using the
@@ -75,76 +70,6 @@
*
*/
-/*
- * New Nov 1997: Use ST-RAM as swap space!
- *
- * In the past, there were often problems with modules that require ST-RAM
- * buffers. Such drivers have to use __get_dma_pages(), which unfortunately
- * often isn't very successful in allocating more than 1 page :-( [1] The net
- * result was that most of the time you couldn't insmod such modules (ataflop,
- * ACSI, SCSI on Falcon, Atari internal framebuffer, not to speak of acsi_slm,
- * which needs a 1 MB buffer... :-).
- *
- * To overcome this limitation, ST-RAM can now be turned into a very
- * high-speed swap space. If a request for an ST-RAM buffer comes, the kernel
- * now tries to unswap some pages on that swap device to make some free (and
- * contiguous) space. This works much better in comparison to
- * __get_dma_pages(), since used swap pages can be selectively freed by either
- * moving them to somewhere else in swap space, or by reading them back into
- * system memory. Ok, there operation of unswapping isn't really cheap (for
- * each page, one has to go through the page tables of all processes), but it
- * doesn't happen that often (only when allocation ST-RAM, i.e. when loading a
- * module that needs ST-RAM). But it at least makes it possible to load such
- * modules!
- *
- * It could also be that overall system performance increases a bit due to
- * ST-RAM swapping, since slow ST-RAM isn't used anymore for holding data or
- * executing code in. It's then just a (very fast, compared to disk) back
- * storage for not-so-often needed data. (But this effect must be compared
- * with the loss of total memory...) Don't know if the effect is already
- * visible on a TT, where the speed difference between ST- and TT-RAM isn't
- * that dramatic, but it should on machines where TT-RAM is really much faster
- * (e.g. Afterburner).
- *
- * [1]: __get_free_pages() does a fine job if you only want one page, but if
- * you want more (contiguous) pages, it can give you such a block only if
- * there's already a free one. The algorithm can't try to free buffers or swap
- * out something in order to make more free space, since all that page-freeing
- * mechanisms work "target-less", i.e. they just free something, but not in a
- * specific place. I.e., __get_free_pages() can't do anything to free
- * *adjacent* pages :-( This situation becomes even worse for DMA memory,
- * since the freeing algorithms are also blind to DMA capability of pages.
- */
-
-/* 1998-10-20: ++andreas
- unswap_by_move disabled because it does not handle swapped shm pages.
-*/
-
-/* 2000-05-01: ++andreas
- Integrated with bootmem. Remove all traces of unswap_by_move.
-*/
-
-#ifdef CONFIG_STRAM_SWAP
-#define ALIGN_IF_SWAP(x) PAGE_ALIGN(x)
-#else
-#define ALIGN_IF_SWAP(x) (x)
-#endif
-
-/* get index of swap page at address 'addr' */
-#define SWAP_NR(addr) (((addr) - swap_start) >> PAGE_SHIFT)
-
-/* get address of swap page #'nr' */
-#define SWAP_ADDR(nr) (swap_start + ((nr) << PAGE_SHIFT))
-
-/* get number of pages for 'n' bytes (already page-aligned) */
-#define N_PAGES(n) ((n) >> PAGE_SHIFT)
-
-/* The following two numbers define the maximum fraction of ST-RAM in total
- * memory, below that the kernel would automatically use ST-RAM as swap
- * space. This decision can be overridden with stram_swap= */
-#define MAX_STRAM_FRACTION_NOM 1
-#define MAX_STRAM_FRACTION_DENOM 3
-
/* Start and end (virtual) of ST-RAM */
static void *stram_start, *stram_end;
@@ -164,10 +89,9 @@ typedef struct stram_block {
} BLOCK;
/* values for flags field */
-#define BLOCK_FREE 0x01 /* free structure in the BLOCKs pool */
+#define BLOCK_FREE 0x01 /* free structure in the BLOCKs pool */
#define BLOCK_KMALLOCED 0x02 /* structure allocated by kmalloc() */
-#define BLOCK_GFP 0x08 /* block allocated with __get_dma_pages() */
-#define BLOCK_INSWAP 0x10 /* block allocated in swap space */
+#define BLOCK_GFP 0x08 /* block allocated with __get_dma_pages() */
/* list of allocated blocks */
static BLOCK *alloc_list;
@@ -179,60 +103,8 @@ static BLOCK *alloc_list;
#define N_STATIC_BLOCKS 20
static BLOCK static_blocks[N_STATIC_BLOCKS];
-#ifdef CONFIG_STRAM_SWAP
-/* max. number of bytes to use for swapping
- * 0 = no ST-RAM swapping
- * -1 = do swapping (to whole ST-RAM) if it's less than MAX_STRAM_FRACTION of
- * total memory
- */
-static int max_swap_size = -1;
-
-/* start and end of swapping area */
-static void *swap_start, *swap_end;
-
-/* The ST-RAM's swap info structure */
-static struct swap_info_struct *stram_swap_info;
-
-/* The ST-RAM's swap type */
-static int stram_swap_type;
-
-/* Semaphore for get_stram_region. */
-static DECLARE_MUTEX(stram_swap_sem);
-
-/* major and minor device number of the ST-RAM device; for the major, we use
- * the same as Amiga z2ram, which is really similar and impossible on Atari,
- * and for the minor a relatively odd number to avoid the user creating and
- * using that device. */
-#define STRAM_MAJOR Z2RAM_MAJOR
-#define STRAM_MINOR 13
-
-/* Some impossible pointer value */
-#define MAGIC_FILE_P (struct file *)0xffffdead
-
-#ifdef DO_PROC
-static unsigned stat_swap_read;
-static unsigned stat_swap_write;
-static unsigned stat_swap_force;
-#endif /* DO_PROC */
-
-#endif /* CONFIG_STRAM_SWAP */
-
/***************************** Prototypes *****************************/
-#ifdef CONFIG_STRAM_SWAP
-static int swap_init(void *start_mem, void *swap_data);
-static void *get_stram_region( unsigned long n_pages );
-static void free_stram_region( unsigned long offset, unsigned long n_pages
- );
-static int in_some_region(void *addr);
-static unsigned long find_free_region( unsigned long n_pages, unsigned long
- *total_free, unsigned long
- *region_free );
-static void do_stram_request(request_queue_t *);
-static int stram_open( struct inode *inode, struct file *filp );
-static int stram_release( struct inode *inode, struct file *filp );
-static void reserve_region(void *start, void *end);
-#endif
static BLOCK *add_region( void *addr, unsigned long size );
static BLOCK *find_region( void *addr );
static int remove_region( BLOCK *block );
@@ -279,84 +151,11 @@ void __init atari_stram_init(void)
*/
void __init atari_stram_reserve_pages(void *start_mem)
{
-#ifdef CONFIG_STRAM_SWAP
- /* if max_swap_size is negative (i.e. no stram_swap= option given),
- * determine at run time whether to use ST-RAM swapping */
- if (max_swap_size < 0)
- /* Use swapping if ST-RAM doesn't make up more than MAX_STRAM_FRACTION
- * of total memory. In that case, the max. size is set to 16 MB,
- * because ST-RAM can never be bigger than that.
- * Also, never use swapping on a Hades, there's no separate ST-RAM in
- * that machine. */
- max_swap_size =
- (!MACH_IS_HADES &&
- (N_PAGES(stram_end-stram_start)*MAX_STRAM_FRACTION_DENOM <=
- ((unsigned long)high_memory>>PAGE_SHIFT)*MAX_STRAM_FRACTION_NOM)) ? 16*1024*1024 : 0;
- DPRINTK( "atari_stram_reserve_pages: max_swap_size = %d\n", max_swap_size );
-#endif
-
/* always reserve first page of ST-RAM, the first 2 kB are
* supervisor-only! */
if (!kernel_in_stram)
reserve_bootmem (0, PAGE_SIZE);
-#ifdef CONFIG_STRAM_SWAP
- {
- void *swap_data;
-
- start_mem = (void *) PAGE_ALIGN ((unsigned long) start_mem);
- /* determine first page to use as swap: if the kernel is
- in TT-RAM, this is the first page of (usable) ST-RAM;
- otherwise just use the end of kernel data (= start_mem) */
- swap_start = !kernel_in_stram ? stram_start + PAGE_SIZE : start_mem;
- /* decrement by one page, rest of kernel assumes that first swap page
- * is always reserved and maybe doesn't handle swp_entry == 0
- * correctly */
- swap_start -= PAGE_SIZE;
- swap_end = stram_end;
- if (swap_end-swap_start > max_swap_size)
- swap_end = swap_start + max_swap_size;
- DPRINTK( "atari_stram_reserve_pages: swapping enabled; "
- "swap=%p-%p\n", swap_start, swap_end);
-
- /* reserve some amount of memory for maintainance of
- * swapping itself: one page for each 2048 (PAGE_SIZE/2)
- * swap pages. (2 bytes for each page) */
- swap_data = start_mem;
- start_mem += ((SWAP_NR(swap_end) + PAGE_SIZE/2 - 1)
- >> (PAGE_SHIFT-1)) << PAGE_SHIFT;
- /* correct swap_start if necessary */
- if (swap_start + PAGE_SIZE == swap_data)
- swap_start = start_mem - PAGE_SIZE;
-
- if (!swap_init( start_mem, swap_data )) {
- printk( KERN_ERR "ST-RAM swap space initialization failed\n" );
- max_swap_size = 0;
- return;
- }
- /* reserve region for swapping meta-data */
- reserve_region(swap_data, start_mem);
- /* reserve swapping area itself */
- reserve_region(swap_start + PAGE_SIZE, swap_end);
-
- /*
- * If the whole ST-RAM is used for swapping, there are no allocatable
- * dma pages left. But unfortunately, some shared parts of the kernel
- * (particularly the SCSI mid-level) call __get_dma_pages()
- * unconditionally :-( These calls then fail, and scsi.c even doesn't
- * check for NULL return values and just crashes. The quick fix for
- * this (instead of doing much clean up work in the SCSI code) is to
- * pretend all pages are DMA-able by setting mach_max_dma_address to
- * ULONG_MAX. This doesn't change any functionality so far, since
- * get_dma_pages() shouldn't be used on Atari anyway anymore (better
- * use atari_stram_alloc()), and the Atari SCSI drivers don't need DMA
- * memory. But unfortunately there's now no kind of warning (even not
- * a NULL return value) if you use get_dma_pages() nevertheless :-(
- * You just will get non-DMA-able memory...
- */
- mach_max_dma_address = 0xffffffff;
- }
-#endif
}
void atari_stram_mem_init_hook (void)
@@ -367,7 +166,6 @@ void atari_stram_mem_init_hook (void)
/*
* This is main public interface: somehow allocate a ST-RAM block
- * There are three strategies:
*
* - If we're before mem_init(), we have to make a static allocation. The
* region is taken in the kernel data area (if the kernel is in ST-RAM) or
@@ -375,14 +173,9 @@ void atari_stram_mem_init_hook (void)
* rsvd_stram_* region. The ST-RAM is somewhere in the middle of kernel
* address space in the latter case.
*
- * - If mem_init() already has been called and ST-RAM swapping is enabled,
- * try to get the memory from the (pseudo) swap-space, either free already
- * or by moving some other pages out of the swap.
- *
- * - If mem_init() already has been called, and ST-RAM swapping is not
- * enabled, the only possibility is to try with __get_dma_pages(). This has
- * the disadvantage that it's very hard to get more than 1 page, and it is
- * likely to fail :-(
+ * - If mem_init() already has been called, try with __get_dma_pages().
+ * This has the disadvantage that it's very hard to get more than 1 page,
+ * and it is likely to fail :-(
*
*/
void *atari_stram_alloc(long size, const char *owner)
@@ -393,27 +186,13 @@ void *atari_stram_alloc(long size, const char *owner)
DPRINTK("atari_stram_alloc(size=%08lx,owner=%s)\n", size, owner);
- size = ALIGN_IF_SWAP(size);
- DPRINTK( "atari_stram_alloc: rounded size = %08lx\n", size );
-#ifdef CONFIG_STRAM_SWAP
- if (max_swap_size) {
- /* If swapping is active: make some free space in the swap
- "device". */
- DPRINTK( "atari_stram_alloc: after mem_init, swapping ok, "
- "calling get_region\n" );
- addr = get_stram_region( N_PAGES(size) );
- flags = BLOCK_INSWAP;
- }
- else
-#endif
if (!mem_init_done)
return alloc_bootmem_low(size);
else {
- /* After mem_init() and no swapping: can only resort to
- * __get_dma_pages() */
+ /* After mem_init(): can only resort to __get_dma_pages() */
addr = (void *)__get_dma_pages(GFP_KERNEL, get_order(size));
flags = BLOCK_GFP;
- DPRINTK( "atari_stram_alloc: after mem_init, swapping off, "
+ DPRINTK( "atari_stram_alloc: after mem_init, "
"get_pages=%p\n", addr );
}
@@ -422,12 +201,7 @@ void *atari_stram_alloc(long size, const char *owner)
/* out of memory for BLOCK structure :-( */
DPRINTK( "atari_stram_alloc: out of mem for BLOCK -- "
"freeing again\n" );
-#ifdef CONFIG_STRAM_SWAP
- if (flags == BLOCK_INSWAP)
- free_stram_region( SWAP_NR(addr), N_PAGES(size) );
- else
-#endif
- free_pages((unsigned long)addr, get_order(size));
+ free_pages((unsigned long)addr, get_order(size));
return( NULL );
}
block->owner = owner;
@@ -451,25 +225,12 @@ void atari_stram_free( void *addr )
DPRINTK( "atari_stram_free: found block (%p): size=%08lx, owner=%s, "
"flags=%02x\n", block, block->size, block->owner, block->flags );
-#ifdef CONFIG_STRAM_SWAP
- if (!max_swap_size) {
-#endif
- if (block->flags & BLOCK_GFP) {
- DPRINTK("atari_stram_free: is kmalloced, order_size=%d\n",
- get_order(block->size));
- free_pages((unsigned long)addr, get_order(block->size));
- }
- else
- goto fail;
-#ifdef CONFIG_STRAM_SWAP
- }
- else if (block->flags & BLOCK_INSWAP) {
- DPRINTK( "atari_stram_free: is swap-alloced\n" );
- free_stram_region( SWAP_NR(block->start), N_PAGES(block->size) );
- }
- else
+ if (!(block->flags & BLOCK_GFP))
goto fail;
-#endif
+
+ DPRINTK("atari_stram_free: is kmalloced, order_size=%d\n",
+ get_order(block->size));
+ free_pages((unsigned long)addr, get_order(block->size));
remove_region( block );
return;
@@ -478,612 +239,6 @@ void atari_stram_free( void *addr )
"(called from %p)\n", addr, __builtin_return_address(0) );
}
-
-#ifdef CONFIG_STRAM_SWAP
-
-
-/* ------------------------------------------------------------------------ */
-/* Main Swapping Functions */
-/* ------------------------------------------------------------------------ */
-
-
-/*
- * Initialize ST-RAM swap device
- * (lots copied and modified from sys_swapon() in mm/swapfile.c)
- */
-static int __init swap_init(void *start_mem, void *swap_data)
-{
- static struct dentry fake_dentry;
- static struct vfsmount fake_vfsmnt;
- struct swap_info_struct *p;
- struct inode swap_inode;
- unsigned int type;
- void *addr;
- int i, j, k, prev;
-
- DPRINTK("swap_init(start_mem=%p, swap_data=%p)\n",
- start_mem, swap_data);
-
- /* need at least one page for swapping to (and this also isn't very
- * much... :-) */
- if (swap_end - swap_start < 2*PAGE_SIZE) {
- printk( KERN_WARNING "stram_swap_init: swap space too small\n" );
- return( 0 );
- }
-
- /* find free slot in swap_info */
- for( p = swap_info, type = 0; type < nr_swapfiles; type++, p++ )
- if (!(p->flags & SWP_USED))
- break;
- if (type >= MAX_SWAPFILES) {
- printk( KERN_WARNING "stram_swap_init: max. number of "
- "swap devices exhausted\n" );
- return( 0 );
- }
- if (type >= nr_swapfiles)
- nr_swapfiles = type+1;
-
- stram_swap_info = p;
- stram_swap_type = type;
-
- /* fake some dir cache entries to give us some name in /dev/swaps */
- fake_dentry.d_parent = &fake_dentry;
- fake_dentry.d_name.name = "stram (internal)";
- fake_dentry.d_name.len = 16;
- fake_vfsmnt.mnt_parent = &fake_vfsmnt;
-
- p->flags = SWP_USED;
- p->swap_file = &fake_dentry;
- p->swap_vfsmnt = &fake_vfsmnt;
- p->swap_map = swap_data;
- p->cluster_nr = 0;
- p->next = -1;
- p->prio = 0x7ff0; /* a rather high priority, but not the higest
- * to give the user a chance to override */
-
- /* call stram_open() directly, avoids at least the overhead in
- * constructing a dummy file structure... */
- swap_inode.i_rdev = MKDEV( STRAM_MAJOR, STRAM_MINOR );
- stram_open( &swap_inode, MAGIC_FILE_P );
- p->max = SWAP_NR(swap_end);
-
- /* initialize swap_map: set regions that are already allocated or belong
- * to kernel data space to SWAP_MAP_BAD, otherwise to free */
- j = 0; /* # of free pages */
- k = 0; /* # of already allocated pages (from pre-mem_init stram_alloc()) */
- p->lowest_bit = 0;
- p->highest_bit = 0;
- for( i = 1, addr = SWAP_ADDR(1); i < p->max;
- i++, addr += PAGE_SIZE ) {
- if (in_some_region( addr )) {
- p->swap_map[i] = SWAP_MAP_BAD;
- ++k;
- }
- else if (kernel_in_stram && addr < start_mem ) {
- p->swap_map[i] = SWAP_MAP_BAD;
- }
- else {
- p->swap_map[i] = 0;
- ++j;
- if (!p->lowest_bit) p->lowest_bit = i;
- p->highest_bit = i;
- }
- }
- /* first page always reserved (and doesn't really belong to swap space) */
- p->swap_map[0] = SWAP_MAP_BAD;
-
- /* now swapping to this device ok */
- p->pages = j + k;
- swap_list_lock();
- nr_swap_pages += j;
- p->flags = SWP_WRITEOK;
-
- /* insert swap space into swap_list */
- prev = -1;
- for (i = swap_list.head; i >= 0; i = swap_info[i].next) {
- if (p->prio >= swap_info[i].prio) {
- break;
- }
- prev = i;
- }
- p->next = i;
- if (prev < 0) {
- swap_list.head = swap_list.next = p - swap_info;
- } else {
- swap_info[prev].next = p - swap_info;
- }
- swap_list_unlock();
-
- printk( KERN_INFO "Using %dk (%d pages) of ST-RAM as swap space.\n",
- p->pages << 2, p->pages );
- return( 1 );
-}
-
-
-/*
- * The swap entry has been read in advance, and we return 1 to indicate
- * that the page has been used or is no longer needed.
- *
- * Always set the resulting pte to be nowrite (the same as COW pages
- * after one process has exited). We don't know just how many PTEs will
- * share this swap entry, so be cautious and let do_wp_page work out
- * what to do if a write is requested later.
- */
-static inline void unswap_pte(struct vm_area_struct * vma, unsigned long
- address, pte_t *dir, swp_entry_t entry,
- struct page *page)
-{
- pte_t pte = *dir;
-
- if (pte_none(pte))
- return;
- if (pte_present(pte)) {
- /* If this entry is swap-cached, then page must already
- hold the right address for any copies in physical
- memory */
- if (pte_page(pte) != page)
- return;
- /* We will be removing the swap cache in a moment, so... */
- set_pte(dir, pte_mkdirty(pte));
- return;
- }
- if (pte_val(pte) != entry.val)
- return;
-
- DPRINTK("unswap_pte: replacing entry %08lx by new page %p",
- entry.val, page);
- set_pte(dir, pte_mkdirty(mk_pte(page, vma->vm_page_prot)));
- swap_free(entry);
- get_page(page);
- inc_mm_counter(vma->vm_mm, rss);
-}
-
-static inline void unswap_pmd(struct vm_area_struct * vma, pmd_t *dir,
- unsigned long address, unsigned long size,
- unsigned long offset, swp_entry_t entry,
- struct page *page)
-{
- pte_t * pte;
- unsigned long end;
-
- if (pmd_none(*dir))
- return;
- if (pmd_bad(*dir)) {
- pmd_ERROR(*dir);
- pmd_clear(dir);
- return;
- }
- pte = pte_offset_kernel(dir, address);
- offset += address & PMD_MASK;
- address &= ~PMD_MASK;
- end = address + size;
- if (end > PMD_SIZE)
- end = PMD_SIZE;
- do {
- unswap_pte(vma, offset+address-vma->vm_start, pte, entry, page);
- address += PAGE_SIZE;
- pte++;
- } while (address < end);
-}
-
-static inline void unswap_pgd(struct vm_area_struct * vma, pgd_t *dir,
- unsigned long address, unsigned long size,
- swp_entry_t entry, struct page *page)
-{
- pmd_t * pmd;
- unsigned long offset, end;
-
- if (pgd_none(*dir))
- return;
- if (pgd_bad(*dir)) {
- pgd_ERROR(*dir);
- pgd_clear(dir);
- return;
- }
- pmd = pmd_offset(dir, address);
- offset = address & PGDIR_MASK;
- address &= ~PGDIR_MASK;
- end = address + size;
- if (end > PGDIR_SIZE)
- end = PGDIR_SIZE;
- do {
- unswap_pmd(vma, pmd, address, end - address, offset, entry,
- page);
- address = (address + PMD_SIZE) & PMD_MASK;
- pmd++;
- } while (address < end);
-}
-
-static void unswap_vma(struct vm_area_struct * vma, pgd_t *pgdir,
- swp_entry_t entry, struct page *page)
-{
- unsigned long start = vma->vm_start, end = vma->vm_end;
-
- do {
- unswap_pgd(vma, pgdir, start, end - start, entry, page);
- start = (start + PGDIR_SIZE) & PGDIR_MASK;
- pgdir++;
- } while (start < end);
-}
-
-static void unswap_process(struct mm_struct * mm, swp_entry_t entry,
- struct page *page)
-{
- struct vm_area_struct* vma;
-
- /*
- * Go through process' page directory.
- */
- if (!mm)
- return;
- for (vma = mm->mmap; vma; vma = vma->vm_next) {
- pgd_t * pgd = pgd_offset(mm, vma->vm_start);
- unswap_vma(vma, pgd, entry, page);
- }
-}
-
-
-static int unswap_by_read(unsigned short *map, unsigned long max,
- unsigned long start, unsigned long n_pages)
-{
- struct task_struct *p;
- struct page *page;
- swp_entry_t entry;
- unsigned long i;
-
- DPRINTK( "unswapping %lu..%lu by reading in\n",
- start, start+n_pages-1 );
-
- for( i = start; i < start+n_pages; ++i ) {
- if (map[i] == SWAP_MAP_BAD) {
- printk( KERN_ERR "get_stram_region: page %lu already "
- "reserved??\n", i );
- continue;
- }
-
- if (map[i]) {
- entry = swp_entry(stram_swap_type, i);
- DPRINTK("unswap: map[i=%lu]=%u nr_swap=%ld\n",
- i, map[i], nr_swap_pages);
-
- swap_device_lock(stram_swap_info);
- map[i]++;
- swap_device_unlock(stram_swap_info);
- /* Get a page for the entry, using the existing
- swap cache page if there is one. Otherwise,
- get a clean page and read the swap into it. */
- page = read_swap_cache_async(entry, NULL, 0);
- if (!page) {
- swap_free(entry);
- return -ENOMEM;
- }
- read_lock(&tasklist_lock);
- for_each_process(p)
- unswap_process(p->mm, entry, page);
- read_unlock(&tasklist_lock);
- shmem_unuse(entry, page);
- /* Now get rid of the extra reference to the
- temporary page we've been using. */
- if (PageSwapCache(page))
- delete_from_swap_cache(page);
- __free_page(page);
- #ifdef DO_PROC
- stat_swap_force++;
- #endif
- }
-
- DPRINTK( "unswap: map[i=%lu]=%u nr_swap=%ld\n",
- i, map[i], nr_swap_pages );
- swap_list_lock();
- swap_device_lock(stram_swap_info);
- map[i] = SWAP_MAP_BAD;
- if (stram_swap_info->lowest_bit == i)
- stram_swap_info->lowest_bit++;
- if (stram_swap_info->highest_bit == i)
- stram_swap_info->highest_bit--;
- --nr_swap_pages;
- swap_device_unlock(stram_swap_info);
- swap_list_unlock();
- }
-
- return 0;
-}
-
-/*
- * reserve a region in ST-RAM swap space for an allocation
- */
-static void *get_stram_region( unsigned long n_pages )
-{
- unsigned short *map = stram_swap_info->swap_map;
- unsigned long max = stram_swap_info->max;
- unsigned long start, total_free, region_free;
- int err;
- void *ret = NULL;
-
- DPRINTK( "get_stram_region(n_pages=%lu)\n", n_pages );
-
- down(&stram_swap_sem);
-
- /* disallow writing to the swap device now */
- stram_swap_info->flags = SWP_USED;
-
- /* find a region of n_pages pages in the swap space including as much free
- * pages as possible (and excluding any already-reserved pages). */
- if (!(start = find_free_region( n_pages, &total_free, &region_free )))
- goto end;
- DPRINTK( "get_stram_region: region starts at %lu, has %lu free pages\n",
- start, region_free );
-
- err = unswap_by_read(map, max, start, n_pages);
- if (err)
- goto end;
-
- ret = SWAP_ADDR(start);
- end:
- /* allow using swap device again */
- stram_swap_info->flags = SWP_WRITEOK;
- up(&stram_swap_sem);
- DPRINTK( "get_stram_region: returning %p\n", ret );
- return( ret );
-}
-
-
-/*
- * free a reserved region in ST-RAM swap space
- */
-static void free_stram_region( unsigned long offset, unsigned long n_pages )
-{
- unsigned short *map = stram_swap_info->swap_map;
-
- DPRINTK( "free_stram_region(offset=%lu,n_pages=%lu)\n", offset, n_pages );
-
- if (offset < 1 || offset + n_pages > stram_swap_info->max) {
- printk( KERN_ERR "free_stram_region: Trying to free non-ST-RAM\n" );
- return;
- }
-
- swap_list_lock();
- swap_device_lock(stram_swap_info);
- /* un-reserve the freed pages */
- for( ; n_pages > 0; ++offset, --n_pages ) {
- if (map[offset] != SWAP_MAP_BAD)
- printk( KERN_ERR "free_stram_region: Swap page %lu was not "
- "reserved\n", offset );
- map[offset] = 0;
- }
-
- /* update swapping meta-data */
- if (offset < stram_swap_info->lowest_bit)
- stram_swap_info->lowest_bit = offset;
- if (offset+n_pages-1 > stram_swap_info->highest_bit)
- stram_swap_info->highest_bit = offset+n_pages-1;
- if (stram_swap_info->prio > swap_info[swap_list.next].prio)
- swap_list.next = swap_list.head;
- nr_swap_pages += n_pages;
- swap_device_unlock(stram_swap_info);
- swap_list_unlock();
-}
-
-
-/* ------------------------------------------------------------------------ */
-/* Utility Functions for Swapping */
-/* ------------------------------------------------------------------------ */
-
-
-/* is addr in some of the allocated regions? */
-static int in_some_region(void *addr)
-{
- BLOCK *p;
-
- for( p = alloc_list; p; p = p->next ) {
- if (p->start <= addr && addr < p->start + p->size)
- return( 1 );
- }
- return( 0 );
-}
-
-
-static unsigned long find_free_region(unsigned long n_pages,
- unsigned long *total_free,
- unsigned long *region_free)
-{
- unsigned short *map = stram_swap_info->swap_map;
- unsigned long max = stram_swap_info->max;
- unsigned long head, tail, max_start;
- long nfree, max_free;
-
- /* first scan the swap space for a suitable place for the allocation */
- head = 1;
- max_start = 0;
- max_free = -1;
- *total_free = 0;
-
- start_over:
- /* increment tail until final window size reached, and count free pages */
- nfree = 0;
- for( tail = head; tail-head < n_pages && tail < max; ++tail ) {
- if (map[tail] == SWAP_MAP_BAD) {
- head = tail+1;
- goto start_over;
- }
- if (!map[tail]) {
- ++nfree;
- ++*total_free;
- }
- }
- if (tail-head < n_pages)
- goto out;
- if (nfree > max_free) {
- max_start = head;
- max_free = nfree;
- if (max_free >= n_pages)
- /* don't need more free pages... :-) */
- goto out;
- }
-
- /* now shift the window and look for the area where as much pages as
- * possible are free */
- while( tail < max ) {
- nfree -= (map[head++] == 0);
- if (map[tail] == SWAP_MAP_BAD) {
- head = tail+1;
- goto start_over;
- }
- if (!map[tail]) {
- ++nfree;
- ++*total_free;
- }
- ++tail;
- if (nfree > max_free) {
- max_start = head;
- max_free = nfree;
- if (max_free >= n_pages)
- /* don't need more free pages... :-) */
- goto out;
- }
- }
-
- out:
- if (max_free < 0) {
- printk( KERN_NOTICE "get_stram_region: ST-RAM too full or fragmented "
- "-- can't allocate %lu pages\n", n_pages );
- return( 0 );
- }
-
- *region_free = max_free;
- return( max_start );
-}
-
-
-/* setup parameters from command line */
-void __init stram_swap_setup(char *str, int *ints)
-{
- if (ints[0] >= 1)
- max_swap_size = ((ints[1] < 0 ? 0 : ints[1]) * 1024) & PAGE_MASK;
-}
-
-
-/* ------------------------------------------------------------------------ */
-/* ST-RAM device */
-/* ------------------------------------------------------------------------ */
-
-static int refcnt;
-
-static void do_stram_request(request_queue_t *q)
-{
- struct request *req;
-
- while ((req = elv_next_request(q)) != NULL) {
- void *start = swap_start + (req->sector << 9);
- unsigned long len = req->current_nr_sectors << 9;
- if ((start + len) > swap_end) {
- printk( KERN_ERR "stram: bad access beyond end of device: "
- "block=%ld, count=%d\n",
- req->sector,
- req->current_nr_sectors );
- end_request(req, 0);
- continue;
- }
-
- if (req->cmd == READ) {
- memcpy(req->buffer, start, len);
-#ifdef DO_PROC
- stat_swap_read += N_PAGES(len);
-#endif
- }
- else {
- memcpy(start, req->buffer, len);
-#ifdef DO_PROC
- stat_swap_write += N_PAGES(len);
-#endif
- }
- end_request(req, 1);
- }
-}
-
-
-static int stram_open( struct inode *inode, struct file *filp )
-{
- if (filp != MAGIC_FILE_P) {
- printk( KERN_NOTICE "Only kernel can open ST-RAM device\n" );
- return( -EPERM );
- }
- if (refcnt)
- return( -EBUSY );
- ++refcnt;
- return( 0 );
-}
-
-static int stram_release( struct inode *inode, struct file *filp )
-{
- if (filp != MAGIC_FILE_P) {
- printk( KERN_NOTICE "Only kernel can close ST-RAM device\n" );
- return( -EPERM );
- }
- if (refcnt > 0)
- --refcnt;
- return( 0 );
-}
-
-
-static struct block_device_operations stram_fops = {
- .open = stram_open,
- .release = stram_release,
-};
-
-static struct gendisk *stram_disk;
-static struct request_queue *stram_queue;
-static DEFINE_SPINLOCK(stram_lock);
-
-int __init stram_device_init(void)
-{
- if (!MACH_IS_ATARI)
- /* no point in initializing this, I hope */
- return -ENXIO;
-
- if (!max_swap_size)
- /* swapping not enabled */
- return -ENXIO;
- stram_disk = alloc_disk(1);
- if (!stram_disk)
- return -ENOMEM;
-
- if (register_blkdev(STRAM_MAJOR, "stram")) {
- put_disk(stram_disk);
- return -ENXIO;
- }
-
- stram_queue = blk_init_queue(do_stram_request, &stram_lock);
- if (!stram_queue) {
- unregister_blkdev(STRAM_MAJOR, "stram");
- put_disk(stram_disk);
- return -ENOMEM;
- }
-
- stram_disk->major = STRAM_MAJOR;
- stram_disk->first_minor = STRAM_MINOR;
- stram_disk->fops = &stram_fops;
- stram_disk->queue = stram_queue;
- sprintf(stram_disk->disk_name, "stram");
- set_capacity(stram_disk, (swap_end - swap_start)/512);
- add_disk(stram_disk);
- return 0;
-}
-
-
-
-/* ------------------------------------------------------------------------ */
-/* Misc Utility Functions */
-/* ------------------------------------------------------------------------ */
-
-/* reserve a range of pages */
-static void reserve_region(void *start, void *end)
-{
- reserve_bootmem (virt_to_phys(start), end - start);
-}
-
-#endif /* CONFIG_STRAM_SWAP */
-
/* ------------------------------------------------------------------------ */
/* Region Management */
@@ -1173,50 +328,9 @@ int get_stram_list( char *buf )
{
int len = 0;
BLOCK *p;
-#ifdef CONFIG_STRAM_SWAP
- int i;
- unsigned short *map = stram_swap_info->swap_map;
- unsigned long max = stram_swap_info->max;
- unsigned free = 0, used = 0, rsvd = 0;
-#endif
-#ifdef CONFIG_STRAM_SWAP
- if (max_swap_size) {
- for( i = 1; i < max; ++i ) {
- if (!map[i])
- ++free;
- else if (map[i] == SWAP_MAP_BAD)
- ++rsvd;
- else
- ++used;
- }
- PRINT_PROC(
- "Total ST-RAM: %8u kB\n"
- "Total ST-RAM swap: %8lu kB\n"
- "Free swap: %8u kB\n"
- "Used swap: %8u kB\n"
- "Allocated swap: %8u kB\n"
- "Swap Reads: %8u\n"
- "Swap Writes: %8u\n"
- "Swap Forced Reads: %8u\n",
- (stram_end - stram_start) >> 10,
- (max-1) << (PAGE_SHIFT-10),
- free << (PAGE_SHIFT-10),
- used << (PAGE_SHIFT-10),
- rsvd << (PAGE_SHIFT-10),
- stat_swap_read,
- stat_swap_write,
- stat_swap_force );
- }
- else {
-#endif
- PRINT_PROC( "ST-RAM swapping disabled\n" );
- PRINT_PROC("Total ST-RAM: %8u kB\n",
+ PRINT_PROC("Total ST-RAM: %8u kB\n",
(stram_end - stram_start) >> 10);
-#ifdef CONFIG_STRAM_SWAP
- }
-#endif
-
PRINT_PROC( "Allocated regions:\n" );
for( p = alloc_list; p; p = p->next ) {
if (len + 50 >= PAGE_SIZE)
@@ -1227,8 +341,6 @@ int get_stram_list( char *buf )
p->owner);
if (p->flags & BLOCK_GFP)
PRINT_PROC( "page-alloced)\n" );
- else if (p->flags & BLOCK_INSWAP)
- PRINT_PROC( "in swap)\n" );
else
PRINT_PROC( "??)\n" );
}
diff --git a/arch/m68k/atari/time.c b/arch/m68k/atari/time.c
index 6df7fb60dfea..e79bbc94216d 100644
--- a/arch/m68k/atari/time.c
+++ b/arch/m68k/atari/time.c
@@ -212,10 +212,8 @@ int atari_tt_hwclk( int op, struct rtc_time *t )
* additionally the RTC_SET bit is set to prevent an update cycle.
*/
- while( RTC_READ(RTC_FREQ_SELECT) & RTC_UIP ) {
- current->state = TASK_INTERRUPTIBLE;
- schedule_timeout(HWCLK_POLL_INTERVAL);
- }
+ while( RTC_READ(RTC_FREQ_SELECT) & RTC_UIP )
+ schedule_timeout_interruptible(HWCLK_POLL_INTERVAL);
local_irq_save(flags);
RTC_WRITE( RTC_CONTROL, ctrl | RTC_SET );
diff --git a/arch/m68k/kernel/process.c b/arch/m68k/kernel/process.c
index 11b1b90ba6ba..13d109328a42 100644
--- a/arch/m68k/kernel/process.c
+++ b/arch/m68k/kernel/process.c
@@ -102,7 +102,9 @@ void cpu_idle(void)
while (1) {
while (!need_resched())
idle();
+ preempt_enable_no_resched();
schedule();
+ preempt_disable();
}
}
diff --git a/arch/m68k/kernel/ptrace.c b/arch/m68k/kernel/ptrace.c
index 8ed1b01a6a87..7e54422685cf 100644
--- a/arch/m68k/kernel/ptrace.c
+++ b/arch/m68k/kernel/ptrace.c
@@ -121,48 +121,11 @@ void ptrace_disable(struct task_struct *child)
child->thread.work.syscall_trace = 0;
}
-asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request, long addr, long data)
{
- struct task_struct *child;
unsigned long tmp;
int i, ret = 0;
- lock_kernel();
- if (request == PTRACE_TRACEME) {
- /* are we already being traced? */
- if (current->ptrace & PT_PTRACED) {
- ret = -EPERM;
- goto out;
- }
- /* set the ptrace bit in the process flags. */
- current->ptrace |= PT_PTRACED;
- goto out;
- }
- read_lock(&tasklist_lock);
- child = find_task_by_pid(pid);
- if (child)
- get_task_struct(child);
- read_unlock(&tasklist_lock);
- if (unlikely(!child)) {
- ret = -ESRCH;
- goto out;
- }
-
- /* you may not mess with init */
- if (unlikely(pid == 1)) {
- ret = -EPERM;
- goto out_tsk;
- }
-
- if (request == PTRACE_ATTACH) {
- ret = ptrace_attach(child);
- goto out_tsk;
- }
-
- ret = ptrace_check_attach(child, request == PTRACE_KILL);
- if (ret)
- goto out_tsk;
-
switch (request) {
/* when I and D space are separate, these will need to be fixed. */
case PTRACE_PEEKTEXT: /* read word at location addr. */
@@ -317,14 +280,10 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
ret = ptrace_request(child, request, addr, data);
break;
}
-out_tsk:
- put_task_struct(child);
-out:
- unlock_kernel();
+
return ret;
out_eio:
- ret = -EIO;
- goto out_tsk;
+ return -EIO;
}
asmlinkage void syscall_trace(void)
diff --git a/arch/m68k/kernel/time.c b/arch/m68k/kernel/time.c
index 4ec95e3cb874..98e4b1adfa29 100644
--- a/arch/m68k/kernel/time.c
+++ b/arch/m68k/kernel/time.c
@@ -27,10 +27,6 @@
#include <linux/timex.h>
#include <linux/profile.h>
-u64 jiffies_64 = INITIAL_JIFFIES;
-
-EXPORT_SYMBOL(jiffies_64);
-
static inline int set_rtc_mmss(unsigned long nowtime)
{
if (mach_set_clock_mmss)
diff --git a/arch/m68k/mm/kmap.c b/arch/m68k/mm/kmap.c
index 5dcb3fa35ea9..fe2383e36b06 100644
--- a/arch/m68k/mm/kmap.c
+++ b/arch/m68k/mm/kmap.c
@@ -201,7 +201,7 @@ void *__ioremap(unsigned long physaddr, unsigned long size, int cacheflag)
virtaddr += PTRTREESIZE;
size -= PTRTREESIZE;
} else {
- pte_dir = pte_alloc_kernel(&init_mm, pmd_dir, virtaddr);
+ pte_dir = pte_alloc_kernel(pmd_dir, virtaddr);
if (!pte_dir) {
printk("ioremap: no mem for pte_dir\n");
return NULL;
diff --git a/arch/m68k/sun3x/dvma.c b/arch/m68k/sun3x/dvma.c
index 32e55adfeb8e..117481e86305 100644
--- a/arch/m68k/sun3x/dvma.c
+++ b/arch/m68k/sun3x/dvma.c
@@ -116,7 +116,7 @@ inline int dvma_map_cpu(unsigned long kaddr,
pte_t *pte;
unsigned long end3;
- if((pte = pte_alloc_kernel(&init_mm, pmd, vaddr)) == NULL) {
+ if((pte = pte_alloc_kernel(pmd, vaddr)) == NULL) {
ret = -ENOMEM;
goto out;
}
diff --git a/arch/m68knommu/Kconfig b/arch/m68knommu/Kconfig
index 8520df9cee6d..b96498120fe9 100644
--- a/arch/m68knommu/Kconfig
+++ b/arch/m68knommu/Kconfig
@@ -71,6 +71,11 @@ config M5206e
help
Motorola ColdFire 5206e processor support.
+config M520x
+ bool "MCF520x"
+ help
+ Freescale Coldfire 5207/5208 processor support.
+
config M523x
bool "MCF523x"
help
@@ -120,7 +125,7 @@ config M527x
config COLDFIRE
bool
- depends on (M5206 || M5206e || M523x || M5249 || M527x || M5272 || M528x || M5307 || M5407)
+ depends on (M5206 || M5206e || M520x || M523x || M5249 || M527x || M5272 || M528x || M5307 || M5407)
default y
choice
@@ -322,6 +327,12 @@ config ELITE
help
Support for the Motorola M5206eLITE board.
+config M5208EVB
+ bool "Freescale M5208EVB board support"
+ depends on M520x
+ help
+ Support for the Freescale Coldfire M5208EVB.
+
config M5235EVB
bool "Freescale M5235EVB support"
depends on M523x
@@ -465,10 +476,10 @@ config ARNEWSH
default y
depends on (ARN5206 || ARN5307)
-config MOTOROLA
+config FREESCALE
bool
default y
- depends on (M5206eC3 || M5235EVB || M5249C3 || M5271EVB || M5272C3 || M5275EVB || M5282EVB || M5307C3 || M5407C3)
+ depends on (M5206eC3 || M5208EVB || M5235EVB || M5249C3 || M5271EVB || M5272C3 || M5275EVB || M5282EVB || M5307C3 || M5407C3)
config HW_FEITH
bool
diff --git a/arch/m68knommu/Makefile b/arch/m68knommu/Makefile
index b8fdf191b8f6..b6b5c14e55fd 100644
--- a/arch/m68knommu/Makefile
+++ b/arch/m68knommu/Makefile
@@ -14,6 +14,7 @@ platform-$(CONFIG_M68VZ328) := 68VZ328
platform-$(CONFIG_M68360) := 68360
platform-$(CONFIG_M5206) := 5206
platform-$(CONFIG_M5206e) := 5206e
+platform-$(CONFIG_M520x) := 520x
platform-$(CONFIG_M523x) := 523x
platform-$(CONFIG_M5249) := 5249
platform-$(CONFIG_M527x) := 527x
@@ -29,7 +30,7 @@ board-$(CONFIG_UCDIMM) := ucdimm
board-$(CONFIG_UCQUICC) := uCquicc
board-$(CONFIG_DRAGEN2) := de2
board-$(CONFIG_ARNEWSH) := ARNEWSH
-board-$(CONFIG_MOTOROLA) := MOTOROLA
+board-$(CONFIG_FREESCALE) := FREESCALE
board-$(CONFIG_M5235EVB) := M5235EVB
board-$(CONFIG_M5271EVB) := M5271EVB
board-$(CONFIG_M5275EVB) := M5275EVB
@@ -41,6 +42,7 @@ board-$(CONFIG_SECUREEDGEMP3) := MP3
board-$(CONFIG_CLEOPATRA) := CLEOPATRA
board-$(CONFIG_senTec) := senTec
board-$(CONFIG_SNEHA) := SNEHA
+board-$(CONFIG_M5208EVB) := M5208EVB
board-$(CONFIG_MOD5272) := MOD5272
BOARD := $(board-y)
@@ -56,6 +58,7 @@ MODEL := $(model-y)
#
cpuclass-$(CONFIG_M5206) := 5307
cpuclass-$(CONFIG_M5206e) := 5307
+cpuclass-$(CONFIG_M520x) := 5307
cpuclass-$(CONFIG_M523x) := 5307
cpuclass-$(CONFIG_M5249) := 5307
cpuclass-$(CONFIG_M527x) := 5307
@@ -80,6 +83,7 @@ export PLATFORM BOARD MODEL CPUCLASS
#
cflags-$(CONFIG_M5206) := -m5200 -Wa,-S -Wa,-m5200
cflags-$(CONFIG_M5206e) := -m5200 -Wa,-S -Wa,-m5200
+cflags-$(CONFIG_M520x) := -m5307 -Wa,-S -Wa,-m5307
cflags-$(CONFIG_M523x) := -m5307 -Wa,-S -Wa,-m5307
cflags-$(CONFIG_M5249) := -m5200 -Wa,-S -Wa,-m5200
cflags-$(CONFIG_M527x) := -m5307 -Wa,-S -Wa,-m5307
@@ -95,7 +99,6 @@ cflags-$(CONFIG_M68360) := -m68332
AFLAGS += $(cflags-y)
CFLAGS += $(cflags-y)
-CFLAGS += -fno-builtin
CFLAGS += -O1 -g
CFLAGS += -D__linux__
CFLAGS += -DUTS_SYSNAME=\"uClinux\"
diff --git a/arch/m68knommu/defconfig b/arch/m68knommu/defconfig
index 87f2d6587c56..2d59ba1a79ba 100644
--- a/arch/m68knommu/defconfig
+++ b/arch/m68knommu/defconfig
@@ -99,7 +99,7 @@ CONFIG_M5272C3=y
# CONFIG_NETtel is not set
# CONFIG_CPU16B is not set
# CONFIG_MOD5272 is not set
-CONFIG_MOTOROLA=y
+CONFIG_FREESCALE=y
# CONFIG_LARGE_ALLOCS is not set
CONFIG_4KSTACKS=y
CONFIG_RAMAUTO=y
@@ -554,7 +554,6 @@ CONFIG_EXT2_FS=y
# CONFIG_XFS_FS is not set
# CONFIG_MINIX_FS is not set
CONFIG_ROMFS_FS=y
-CONFIG_MAGIC_ROM_PTR=y
# CONFIG_INOTIFY is not set
# CONFIG_QUOTA is not set
# CONFIG_DNOTIFY is not set
diff --git a/arch/m68knommu/kernel/asm-offsets.c b/arch/m68knommu/kernel/asm-offsets.c
index cd3ffe12653e..b988c7bdc6e4 100644
--- a/arch/m68knommu/kernel/asm-offsets.c
+++ b/arch/m68knommu/kernel/asm-offsets.c
@@ -15,6 +15,7 @@
#include <linux/hardirq.h>
#include <asm/bootinfo.h>
#include <asm/irq.h>
+#include <asm/irqnode.h>
#include <asm/thread_info.h>
#define DEFINE(sym, val) \
diff --git a/arch/m68knommu/kernel/ptrace.c b/arch/m68knommu/kernel/ptrace.c
index 9724e1cd82e5..262ab8c72e5f 100644
--- a/arch/m68knommu/kernel/ptrace.c
+++ b/arch/m68knommu/kernel/ptrace.c
@@ -101,43 +101,10 @@ void ptrace_disable(struct task_struct *child)
put_reg(child, PT_SR, tmp);
}
-asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
+long arch_ptrace(truct task_struct *child, long request, long addr, long data)
{
- struct task_struct *child;
int ret;
- lock_kernel();
- ret = -EPERM;
- if (request == PTRACE_TRACEME) {
- /* are we already being traced? */
- if (current->ptrace & PT_PTRACED)
- goto out;
- /* set the ptrace bit in the process flags. */
- current->ptrace |= PT_PTRACED;
- ret = 0;
- goto out;
- }
- ret = -ESRCH;
- read_lock(&tasklist_lock);
- child = find_task_by_pid(pid);
- if (child)
- get_task_struct(child);
- read_unlock(&tasklist_lock);
- if (!child)
- goto out;
-
- ret = -EPERM;
- if (pid == 1) /* you may not mess with init */
- goto out_tsk;
-
- if (request == PTRACE_ATTACH) {
- ret = ptrace_attach(child);
- goto out_tsk;
- }
- ret = ptrace_check_attach(child, request == PTRACE_KILL);
- if (ret < 0)
- goto out_tsk;
-
switch (request) {
/* when I and D space are separate, these will need to be fixed. */
case PTRACE_PEEKTEXT: /* read word at location addr. */
@@ -357,10 +324,6 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
ret = -EIO;
break;
}
-out_tsk:
- put_task_struct(child);
-out:
- unlock_kernel();
return ret;
}
diff --git a/arch/m68knommu/kernel/setup.c b/arch/m68knommu/kernel/setup.c
index a220345e9746..abb80fa2b940 100644
--- a/arch/m68knommu/kernel/setup.c
+++ b/arch/m68knommu/kernel/setup.c
@@ -107,6 +107,9 @@ void (*mach_power_off)( void ) = NULL;
#if defined(CONFIG_M5206e)
#define CPU "COLDFIRE(m5206e)"
#endif
+#if defined(CONFIG_M520x)
+ #define CPU "COLDFIRE(m520x)"
+#endif
#if defined(CONFIG_M523x)
#define CPU "COLDFIRE(m523x)"
#endif
@@ -132,7 +135,7 @@ void (*mach_power_off)( void ) = NULL;
#define CPU "COLDFIRE(m5407)"
#endif
#ifndef CPU
- #define CPU "UNKOWN"
+ #define CPU "UNKNOWN"
#endif
/* (es) */
diff --git a/arch/m68knommu/kernel/time.c b/arch/m68knommu/kernel/time.c
index b17c1ecba966..b9d8abb45430 100644
--- a/arch/m68knommu/kernel/time.c
+++ b/arch/m68knommu/kernel/time.c
@@ -27,10 +27,6 @@
#define TICK_SIZE (tick_nsec / 1000)
-u64 jiffies_64 = INITIAL_JIFFIES;
-
-EXPORT_SYMBOL(jiffies_64);
-
extern unsigned long wall_jiffies;
diff --git a/arch/m68knommu/kernel/vmlinux.lds.S b/arch/m68knommu/kernel/vmlinux.lds.S
index 47f06787190d..0eab92ca4b97 100644
--- a/arch/m68knommu/kernel/vmlinux.lds.S
+++ b/arch/m68knommu/kernel/vmlinux.lds.S
@@ -125,6 +125,14 @@
#endif
/*
+ * The Freescale 5208EVB board has 32MB of RAM.
+ */
+#if defined(CONFIG_M5208EVB)
+#define RAM_START 0x40020000
+#define RAM_LENGTH 0x01e00000
+#endif
+
+/*
* The senTec COBRA5272 board has nearly the same memory layout as
* the M5272C3. We assume 16MiB ram.
*/
@@ -275,6 +283,7 @@ SECTIONS {
*(__ksymtab_strings)
/* Built-in module parameters */
+ . = ALIGN(4) ;
__start___param = .;
*(__param)
__stop___param = .;
diff --git a/arch/m68knommu/platform/520x/Makefile b/arch/m68knommu/platform/520x/Makefile
new file mode 100644
index 000000000000..e861b05106bc
--- /dev/null
+++ b/arch/m68knommu/platform/520x/Makefile
@@ -0,0 +1,19 @@
+#
+# Makefile for the M5208 specific file.
+#
+
+#
+# If you want to play with the HW breakpoints then you will
+# need to add define this, which will give you a stack backtrace
+# on the console port whenever a DBG interrupt occurs. You have to
+# set up you HW breakpoints to trigger a DBG interrupt:
+#
+# EXTRA_CFLAGS += -DTRAP_DBG_INTERRUPT
+# EXTRA_AFLAGS += -DTRAP_DBG_INTERRUPT
+#
+
+ifdef CONFIG_FULLDEBUG
+AFLAGS += -DDEBUGGER_COMPATIBLE_CACHE=1
+endif
+
+obj-y := config.o
diff --git a/arch/m68knommu/platform/520x/config.c b/arch/m68knommu/platform/520x/config.c
new file mode 100644
index 000000000000..71dea2e0f452
--- /dev/null
+++ b/arch/m68knommu/platform/520x/config.c
@@ -0,0 +1,65 @@
+/***************************************************************************/
+
+/*
+ * linux/arch/m68knommu/platform/520x/config.c
+ *
+ * Copyright (C) 2005, Freescale (www.freescale.com)
+ * Copyright (C) 2005, Intec Automation (mike@steroidmicros.com)
+ * Copyright (C) 1999-2003, Greg Ungerer (gerg@snapgear.com)
+ * Copyright (C) 2001-2003, SnapGear Inc. (www.snapgear.com)
+ */
+
+/***************************************************************************/
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/param.h>
+#include <asm/machdep.h>
+#include <asm/dma.h>
+
+/***************************************************************************/
+
+/*
+ * DMA channel base address table.
+ */
+unsigned int dma_base_addr[MAX_M68K_DMA_CHANNELS];
+unsigned int dma_device_address[MAX_M68K_DMA_CHANNELS];
+
+/***************************************************************************/
+
+void coldfire_pit_tick(void);
+void coldfire_pit_init(irqreturn_t (*handler)(int, void *, struct pt_regs *));
+unsigned long coldfire_pit_offset(void);
+void coldfire_trap_init(void);
+void coldfire_reset(void);
+
+/***************************************************************************/
+
+/*
+ * Program the vector to be an auto-vectored.
+ */
+
+void mcf_autovector(unsigned int vec)
+{
+ /* Everything is auto-vectored on the 520x devices */
+}
+
+/***************************************************************************/
+
+void config_BSP(char *commandp, int size)
+{
+#ifdef CONFIG_BOOTPARAM
+ strncpy(commandp, CONFIG_BOOTPARAM_STRING, size);
+ commandp[size-1] = 0;
+#else
+ memset(commandp, 0, size);
+#endif
+
+ mach_sched_init = coldfire_pit_init;
+ mach_tick = coldfire_pit_tick;
+ mach_gettimeoffset = coldfire_pit_offset;
+ mach_trap_init = coldfire_trap_init;
+ mach_reset = coldfire_reset;
+}
+
+/***************************************************************************/
diff --git a/arch/m68knommu/platform/5307/Makefile b/arch/m68knommu/platform/5307/Makefile
index 6fe5a2b8fb08..8d1619dc1ea6 100644
--- a/arch/m68knommu/platform/5307/Makefile
+++ b/arch/m68knommu/platform/5307/Makefile
@@ -19,6 +19,7 @@ endif
obj-$(CONFIG_COLDFIRE) += entry.o vectors.o ints.o
obj-$(CONFIG_M5206) += timers.o
obj-$(CONFIG_M5206e) += timers.o
+obj-$(CONFIG_M520x) += pit.o
obj-$(CONFIG_M523x) += pit.o
obj-$(CONFIG_M5249) += timers.o
obj-$(CONFIG_M527x) += pit.o
diff --git a/arch/m68knommu/platform/5307/head.S b/arch/m68knommu/platform/5307/head.S
index 7f4ba837901f..c30c462b99b1 100644
--- a/arch/m68knommu/platform/5307/head.S
+++ b/arch/m68knommu/platform/5307/head.S
@@ -113,6 +113,9 @@
#define MEM_BASE 0x02000000
#define VBR_BASE 0x20000000 /* vectors in SRAM */
#endif
+#if defined(CONFIG_M5208EVB)
+#define MEM_BASE 0x40000000
+#endif
#ifndef MEM_BASE
#define MEM_BASE 0x00000000 /* memory base at address 0 */
diff --git a/arch/m68knommu/platform/5307/ints.c b/arch/m68knommu/platform/5307/ints.c
index 0117754d44f3..a134fb2f0566 100644
--- a/arch/m68knommu/platform/5307/ints.c
+++ b/arch/m68knommu/platform/5307/ints.c
@@ -26,6 +26,7 @@
#include <asm/system.h>
#include <asm/irq.h>
+#include <asm/irqnode.h>
#include <asm/traps.h>
#include <asm/page.h>
#include <asm/machdep.h>
diff --git a/arch/m68knommu/platform/5307/pit.c b/arch/m68knommu/platform/5307/pit.c
index a9b2c2e7e280..323f2677e49d 100644
--- a/arch/m68knommu/platform/5307/pit.c
+++ b/arch/m68knommu/platform/5307/pit.c
@@ -3,7 +3,7 @@
/*
* pit.c -- Motorola ColdFire PIT timer. Currently this type of
* hardware timer only exists in the Motorola ColdFire
- * 5270/5271 and 5282 CPUs.
+ * 5270/5271, 5282 and other CPUs.
*
* Copyright (C) 1999-2004, Greg Ungerer (gerg@snapgear.com)
* Copyright (C) 2001-2004, SnapGear Inc. (www.snapgear.com)
@@ -47,10 +47,10 @@ void coldfire_pit_init(irqreturn_t (*handler)(int, void *, struct pt_regs *))
icrp = (volatile unsigned char *) (MCF_IPSBAR + MCFICM_INTC0 +
MCFINTC_ICR0 + MCFINT_PIT1);
- *icrp = 0x2b; /* PIT1 with level 5, priority 3 */
+ *icrp = ICR_INTRCONF;
- imrp = (volatile unsigned long *) (MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRH);
- *imrp &= ~(1 << (MCFINT_PIT1 - 32));
+ imrp = (volatile unsigned long *) (MCF_IPSBAR + MCFICM_INTC0 + MCFPIT_IMR);
+ *imrp &= ~MCFPIT_IMR_IBIT;
/* Set up PIT timer 1 as poll clock */
tp = (volatile struct mcfpit *) (MCF_IPSBAR + MCFPIT_BASE1);
@@ -70,7 +70,7 @@ unsigned long coldfire_pit_offset(void)
unsigned long pmr, pcntr, offset;
tp = (volatile struct mcfpit *) (MCF_IPSBAR + MCFPIT_BASE1);
- ipr = (volatile unsigned long *) (MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IPRH);
+ ipr = (volatile unsigned long *) (MCF_IPSBAR + MCFICM_INTC0 + MCFPIT_IMR);
pmr = *(&tp->pmr);
pcntr = *(&tp->pcntr);
@@ -80,7 +80,7 @@ unsigned long coldfire_pit_offset(void)
* timer interupt is pending, then add on a ticks worth of time.
*/
offset = ((pmr - pcntr) * (1000000 / HZ)) / pmr;
- if ((offset < (1000000 / HZ / 2)) && (*ipr & (1 << (MCFINT_PIT1 - 32))))
+ if ((offset < (1000000 / HZ / 2)) && (*ipr & MCFPIT_IMR_IBIT))
offset += 1000000 / HZ;
return offset;
}
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 4cd724c05700..e380a8322a94 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -4,216 +4,147 @@ config MIPS
# Horrible source of confusion. Die, die, die ...
select EMBEDDED
-# shouldn't it be per-subarchitecture?
-config ARCH_MAY_HAVE_PC_FDC
- bool
- default y
-
mainmenu "Linux/MIPS Kernel Configuration"
source "init/Kconfig"
-config SYS_SUPPORTS_32BIT_KERNEL
- bool
-config SYS_SUPPORTS_64BIT_KERNEL
- bool
-config CPU_SUPPORTS_32BIT_KERNEL
- bool
-config CPU_SUPPORTS_64BIT_KERNEL
- bool
-
-menu "Kernel type"
-
-choice
-
- prompt "Kernel code model"
- help
- You should only select this option if you have a workload that
- actually benefits from 64-bit processing or if your machine has
- large memory. You will only be presented a single option in this
- menu if your system does not support both 32-bit and 64-bit kernels.
-
-config 32BIT
- bool "32-bit kernel"
- depends on CPU_SUPPORTS_32BIT_KERNEL && SYS_SUPPORTS_32BIT_KERNEL
- select TRAD_SIGNALS
- help
- Select this option if you want to build a 32-bit kernel.
-
-config 64BIT
- bool "64-bit kernel"
- depends on CPU_SUPPORTS_64BIT_KERNEL && SYS_SUPPORTS_64BIT_KERNEL
- help
- Select this option if you want to build a 64-bit kernel.
-
-endchoice
-
-endmenu
-
menu "Machine selection"
-config MACH_JAZZ
- bool "Support for the Jazz family of machines"
- select ARC
- select ARC32
- select GENERIC_ISA_DMA
- select I8259
- select ISA
- select SYS_SUPPORTS_32BIT_KERNEL
- select SYS_SUPPORTS_64BIT_KERNEL if EXPERIMENTAL
- help
- This a family of machines based on the MIPS R4030 chipset which was
- used by several vendors to build RISC/os and Windows NT workstations.
- Members include the Acer PICA, MIPS Magnum 4000, MIPS Millenium and
- Olivetti M700-10 workstations.
+choice
+ prompt "System type"
+ default SGI_IP22
-config ACER_PICA_61
- bool "Support for Acer PICA 1 chipset (EXPERIMENTAL)"
- depends on MACH_JAZZ && EXPERIMENTAL
+config MIPS_MTX1
+ bool "Support for 4G Systems MTX-1 board"
select DMA_NONCOHERENT
- help
- This is a machine with a R4400 133/150 MHz CPU. To compile a Linux
- kernel that runs on these, say Y here. For details about Linux on
- the MIPS architecture, check out the Linux/MIPS FAQ on the WWW at
- <http://www.linux-mips.org/>.
+ select HW_HAS_PCI
+ select SOC_AU1500
+ select SYS_HAS_CPU_MIPS32_R1
+ select SYS_SUPPORTS_LITTLE_ENDIAN
-config MIPS_MAGNUM_4000
- bool "Support for MIPS Magnum 4000"
- depends on MACH_JAZZ
+config MIPS_BOSPORUS
+ bool "AMD Alchemy Bosporus board"
+ select SOC_AU1500
select DMA_NONCOHERENT
- help
- This is a machine with a R4000 100 MHz CPU. To compile a Linux
- kernel that runs on these, say Y here. For details about Linux on
- the MIPS architecture, check out the Linux/MIPS FAQ on the WWW at
- <http://www.linux-mips.org/>.
+ select SYS_HAS_CPU_MIPS32_R1
+ select SYS_SUPPORTS_LITTLE_ENDIAN
-config OLIVETTI_M700
- bool "Support for Olivetti M700-10"
- depends on MACH_JAZZ
+config MIPS_PB1000
+ bool "AMD Alchemy PB1000 board"
+ select SOC_AU1000
select DMA_NONCOHERENT
- help
- This is a machine with a R4000 100 MHz CPU. To compile a Linux
- kernel that runs on these, say Y here. For details about Linux on
- the MIPS architecture, check out the Linux/MIPS FAQ on the WWW at
- <http://www.linux-mips.org/>.
-
-config MACH_VR41XX
- bool "Support for NEC VR4100 series based machines"
- select SYS_SUPPORTS_32BIT_KERNEL
- select SYS_SUPPORTS_64BIT_KERNEL if EXPERIMENTAL
+ select HW_HAS_PCI
+ select SWAP_IO_SPACE
+ select SYS_HAS_CPU_MIPS32_R1
+ select SYS_SUPPORTS_LITTLE_ENDIAN
-config NEC_CMBVR4133
- bool "Support for NEC CMB-VR4133"
- depends on MACH_VR41XX
- select CPU_VR41XX
+config MIPS_PB1100
+ bool "AMD Alchemy PB1100 board"
+ select SOC_AU1100
select DMA_NONCOHERENT
- select IRQ_CPU
select HW_HAS_PCI
+ select SWAP_IO_SPACE
+ select SYS_HAS_CPU_MIPS32_R1
+ select SYS_SUPPORTS_LITTLE_ENDIAN
-config ROCKHOPPER
- bool "Support for Rockhopper baseboard"
- depends on NEC_CMBVR4133
- select I8259
- select HAVE_STD_PC_SERIAL_PORT
+config MIPS_PB1500
+ bool "AMD Alchemy PB1500 board"
+ select SOC_AU1500
+ select DMA_NONCOHERENT
+ select HW_HAS_PCI
+ select SYS_HAS_CPU_MIPS32_R1
+ select SYS_SUPPORTS_LITTLE_ENDIAN
-config CASIO_E55
- bool "Support for CASIO CASSIOPEIA E-10/15/55/65"
- depends on MACH_VR41XX
- select CPU_LITTLE_ENDIAN
+config MIPS_PB1550
+ bool "AMD Alchemy PB1550 board"
+ select SOC_AU1550
select DMA_NONCOHERENT
- select IRQ_CPU
- select ISA
+ select HW_HAS_PCI
+ select MIPS_DISABLE_OBSOLETE_IDE
+ select SYS_HAS_CPU_MIPS32_R1
+ select SYS_SUPPORTS_LITTLE_ENDIAN
-config IBM_WORKPAD
- bool "Support for IBM WorkPad z50"
- depends on MACH_VR41XX
- select CPU_LITTLE_ENDIAN
+config MIPS_PB1200
+ bool "AMD Alchemy PB1200 board"
+ select SOC_AU1200
select DMA_NONCOHERENT
- select IRQ_CPU
- select ISA
+ select MIPS_DISABLE_OBSOLETE_IDE
+ select SYS_HAS_CPU_MIPS32_R1
+ select SYS_SUPPORTS_LITTLE_ENDIAN
-config TANBAC_TB022X
- bool "Support for TANBAC VR4131 multichip module and TANBAC VR4131DIMM"
- depends on MACH_VR41XX
- select CPU_LITTLE_ENDIAN
+config MIPS_DB1000
+ bool "AMD Alchemy DB1000 board"
+ select SOC_AU1000
select DMA_NONCOHERENT
- select IRQ_CPU
select HW_HAS_PCI
- help
- The TANBAC VR4131 multichip module(TB0225) and
- the TANBAC VR4131DIMM(TB0229) are MIPS-based platforms
- manufactured by TANBAC.
- Please refer to <http://www.tanbac.co.jp/>
- about VR4131 multichip module and VR4131DIMM.
+ select SYS_HAS_CPU_MIPS32_R1
+ select SYS_SUPPORTS_LITTLE_ENDIAN
-config TANBAC_TB0226
- bool "Support for TANBAC Mbase(TB0226)"
- depends on TANBAC_TB022X
- select GPIO_VR41XX
- help
- The TANBAC Mbase(TB0226) is a MIPS-based platform manufactured by TANBAC.
- Please refer to <http://www.tanbac.co.jp/> about Mbase.
-
-config TANBAC_TB0287
- bool "Support for TANBAC Mini-ITX DIMM base(TB0287)"
- depends on TANBAC_TB022X
- help
- The TANBAC Mini-ITX DIMM base(TB0287) is a MIPS-based platform manufactured by TANBAC.
- Please refer to <http://www.tanbac.co.jp/> about Mini-ITX DIMM base.
-
-config VICTOR_MPC30X
- bool "Support for Victor MP-C303/304"
- depends on MACH_VR41XX
- select CPU_LITTLE_ENDIAN
+config MIPS_DB1100
+ bool "AMD Alchemy DB1100 board"
+ select SOC_AU1100
select DMA_NONCOHERENT
- select IRQ_CPU
- select HW_HAS_PCI
+ select SYS_HAS_CPU_MIPS32_R1
+ select SYS_SUPPORTS_LITTLE_ENDIAN
-config ZAO_CAPCELLA
- bool "Support for ZAO Networks Capcella"
- depends on MACH_VR41XX
- select CPU_LITTLE_ENDIAN
+config MIPS_DB1500
+ bool "AMD Alchemy DB1500 board"
+ select SOC_AU1500
select DMA_NONCOHERENT
- select IRQ_CPU
select HW_HAS_PCI
+ select MIPS_DISABLE_OBSOLETE_IDE
+ select SYS_HAS_CPU_MIPS32_R1
+ select SYS_SUPPORTS_BIG_ENDIAN
+ select SYS_SUPPORTS_LITTLE_ENDIAN
-config PCI_VR41XX
- bool "Add PCI control unit support of NEC VR4100 series"
- depends on MACH_VR41XX && HW_HAS_PCI
- default y
- select PCI
+config MIPS_DB1550
+ bool "AMD Alchemy DB1550 board"
+ select SOC_AU1550
+ select HW_HAS_PCI
+ select DMA_NONCOHERENT
+ select MIPS_DISABLE_OBSOLETE_IDE
+ select SYS_HAS_CPU_MIPS32_R1
+ select SYS_SUPPORTS_LITTLE_ENDIAN
-config VRC4173
- tristate "Add NEC VRC4173 companion chip support"
- depends on MACH_VR41XX && PCI_VR41XX
- ---help---
- The NEC VRC4173 is a companion chip for NEC VR4122/VR4131.
+config MIPS_DB1200
+ bool "AMD Alchemy DB1200 board"
+ select SOC_AU1200
+ select DMA_COHERENT
+ select MIPS_DISABLE_OBSOLETE_IDE
+ select SYS_HAS_CPU_MIPS32_R1
+ select SYS_SUPPORTS_LITTLE_ENDIAN
-config TOSHIBA_JMR3927
- bool "Support for Toshiba JMR-TX3927 board"
+config MIPS_MIRAGE
+ bool "AMD Alchemy Mirage board"
select DMA_NONCOHERENT
- select HW_HAS_PCI
- select SWAP_IO_SPACE
- select SYS_SUPPORTS_32BIT_KERNEL
+ select SOC_AU1500
+ select SYS_HAS_CPU_MIPS32_R1
+ select SYS_SUPPORTS_LITTLE_ENDIAN
config MIPS_COBALT
bool "Support for Cobalt Server"
- depends on EXPERIMENTAL
select DMA_NONCOHERENT
select HW_HAS_PCI
select I8259
select IRQ_CPU
+ select MIPS_GT64111
+ select SYS_HAS_CPU_NEVADA
select SYS_SUPPORTS_32BIT_KERNEL
select SYS_SUPPORTS_64BIT_KERNEL if EXPERIMENTAL
+ select SYS_SUPPORTS_LITTLE_ENDIAN
config MACH_DECSTATION
bool "Support for DECstations"
select BOOT_ELF32
select DMA_NONCOHERENT
+ select EARLY_PRINTK
select IRQ_CPU
+ select SYS_HAS_CPU_R3000
+ select SYS_HAS_CPU_R4X00
select SYS_SUPPORTS_32BIT_KERNEL
select SYS_SUPPORTS_64BIT_KERNEL if EXPERIMENTAL
- ---help---
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+ help
This enables support for DEC's MIPS based workstations. For details
see the Linux/MIPS FAQ on <http://www.linux-mips.org/> and the
DECstation porting pages on <http://decstation.unix-ag.org/>.
@@ -234,8 +165,10 @@ config MIPS_EV64120
select DMA_NONCOHERENT
select HW_HAS_PCI
select MIPS_GT64120
+ select SYS_HAS_CPU_R5000
select SYS_SUPPORTS_32BIT_KERNEL
select SYS_SUPPORTS_64BIT_KERNEL
+ select SYS_SUPPORTS_BIG_ENDIAN
help
This is an evaluation board based on the Galileo GT-64120
single-chip system controller that contains a MIPS R5000 compatible
@@ -243,10 +176,6 @@ config MIPS_EV64120
<http://www.marvell.com/>. Say Y here if you wish to build a
kernel for this platform.
-config EVB_PCI1
- bool "Enable Second PCI (PCI1)"
- depends on MIPS_EV64120
-
config MIPS_EV96100
bool "Support for Galileo EV96100 Evaluation board (EXPERIMENTAL)"
depends on EXPERIMENTAL
@@ -256,8 +185,11 @@ config MIPS_EV96100
select MIPS_GT96100
select RM7000_CPU_SCACHE
select SWAP_IO_SPACE
+ select SYS_HAS_CPU_R5000
+ select SYS_HAS_CPU_RM7000
select SYS_SUPPORTS_32BIT_KERNEL
- select SYS_SUPPORTS_64BIT_KERNEL
+ select SYS_SUPPORTS_64BIT_KERNEL if EXPERIMENTAL
+ select SYS_SUPPORTS_BIG_ENDIAN
help
This is an evaluation board based on the Galileo GT-96100 LAN/WAN
communications controllers containing a MIPS R5000 compatible core
@@ -268,8 +200,11 @@ config MIPS_IVR
bool "Support for Globespan IVR board"
select DMA_NONCOHERENT
select HW_HAS_PCI
+ select ITE_BOARD_GEN
+ select SYS_HAS_CPU_NEVADA
select SYS_SUPPORTS_32BIT_KERNEL
select SYS_SUPPORTS_64BIT_KERNEL if EXPERIMENTAL
+ select SYS_SUPPORTS_LITTLE_ENDIAN
help
This is an evaluation board built by Globespan to showcase thir
iVR (Internet Video Recorder) design. It utilizes a QED RM5231
@@ -277,37 +212,16 @@ config MIPS_IVR
located at <http://www.globespan.net/>. Say Y here if you wish to
build a kernel for this platform.
-config LASAT
- bool "Support for LASAT Networks platforms"
- select DMA_NONCOHERENT
- select HW_HAS_PCI
- select MIPS_GT64120
- select R5000_CPU_SCACHE
- select SYS_SUPPORTS_32BIT_KERNEL
- select SYS_SUPPORTS_64BIT_KERNEL if EXPERIMENTAL
-
-config PICVUE
- tristate "PICVUE LCD display driver"
- depends on LASAT
-
-config PICVUE_PROC
- tristate "PICVUE LCD display driver /proc interface"
- depends on PICVUE
-
-config DS1603
- bool "DS1603 RTC driver"
- depends on LASAT
-
-config LASAT_SYSCTL
- bool "LASAT sysctl interface"
- depends on LASAT
-
config MIPS_ITE8172
bool "Support for ITE 8172G board"
select DMA_NONCOHERENT
select HW_HAS_PCI
+ select ITE_BOARD_GEN
+ select SYS_HAS_CPU_R5432
+ select SYS_HAS_CPU_NEVADA
select SYS_SUPPORTS_32BIT_KERNEL
select SYS_SUPPORTS_64BIT_KERNEL if EXPERIMENTAL
+ select SYS_SUPPORTS_LITTLE_ENDIAN
help
Ths is an evaluation board made by ITE <http://www.ite.com.tw/>
with ATX form factor that utilizes a MIPS R5000 to work with its
@@ -315,42 +229,86 @@ config MIPS_ITE8172
either a NEC Vr5432 or QED RM5231. Say Y here if you wish to build
a kernel for this platform.
-config IT8172_REVC
- bool "Support for older IT8172 (Rev C)"
- depends on MIPS_ITE8172
+config MACH_JAZZ
+ bool "Support for the Jazz family of machines"
+ select ARC
+ select ARC32
+ select ARCH_MAY_HAVE_PC_FDC
+ select GENERIC_ISA_DMA
+ select I8259
+ select ISA
+ select SYS_HAS_CPU_R4X00
+ select SYS_SUPPORTS_32BIT_KERNEL
+ select SYS_SUPPORTS_64BIT_KERNEL if EXPERIMENTAL
help
- Say Y here to support the older, Revision C version of the Integrated
- Technology Express, Inc. ITE8172 SBC. Vendor page at
- <http://www.ite.com.tw/ia/brief_it8172bsp.htm>; picture of the
- board at <http://www.mvista.com/partners/semiconductor/ite.html>.
+ This a family of machines based on the MIPS R4030 chipset which was
+ used by several vendors to build RISC/os and Windows NT workstations.
+ Members include the Acer PICA, MIPS Magnum 4000, MIPS Millenium and
+ Olivetti M700-10 workstations.
+
+config LASAT
+ bool "Support for LASAT Networks platforms"
+ select DMA_NONCOHERENT
+ select HW_HAS_PCI
+ select MIPS_GT64120
+ select MIPS_NILE4
+ select R5000_CPU_SCACHE
+ select SYS_HAS_CPU_R5000
+ select SYS_SUPPORTS_32BIT_KERNEL
+ select SYS_SUPPORTS_64BIT_KERNEL if EXPERIMENTAL
+ select SYS_SUPPORTS_LITTLE_ENDIAN
config MIPS_ATLAS
bool "Support for MIPS Atlas board"
select BOOT_ELF32
select DMA_NONCOHERENT
+ select IRQ_CPU
select HW_HAS_PCI
+ select MIPS_BOARDS_GEN
+ select MIPS_BONITO64
select MIPS_GT64120
+ select MIPS_MSC
+ select RM7000_CPU_SCACHE
select SWAP_IO_SPACE
+ select SYS_HAS_CPU_MIPS32_R1
+ select SYS_HAS_CPU_MIPS32_R2
+ select SYS_HAS_CPU_MIPS64_R1
+ select SYS_HAS_CPU_NEVADA
+ select SYS_HAS_CPU_RM7000
select SYS_SUPPORTS_32BIT_KERNEL
select SYS_SUPPORTS_64BIT_KERNEL
+ select SYS_SUPPORTS_BIG_ENDIAN
+ select SYS_SUPPORTS_LITTLE_ENDIAN
help
- This enables support for the QED R5231-based MIPS Atlas evaluation
+ This enables support for the MIPS Technologies Atlas evaluation
board.
config MIPS_MALTA
bool "Support for MIPS Malta board"
+ select ARCH_MAY_HAVE_PC_FDC
select BOOT_ELF32
select HAVE_STD_PC_SERIAL_PORT
select DMA_NONCOHERENT
+ select IRQ_CPU
select GENERIC_ISA_DMA
select HW_HAS_PCI
select I8259
+ select MIPS_BOARDS_GEN
+ select MIPS_BONITO64
select MIPS_GT64120
+ select MIPS_MSC
select SWAP_IO_SPACE
+ select SYS_HAS_CPU_MIPS32_R1
+ select SYS_HAS_CPU_MIPS32_R2
+ select SYS_HAS_CPU_MIPS64_R1
+ select SYS_HAS_CPU_NEVADA
+ select SYS_HAS_CPU_RM7000
select SYS_SUPPORTS_32BIT_KERNEL
select SYS_SUPPORTS_64BIT_KERNEL
+ select SYS_SUPPORTS_BIG_ENDIAN
+ select SYS_SUPPORTS_LITTLE_ENDIAN
help
- This enables support for the VR5000-based MIPS Malta evaluation
+ This enables support for the MIPS Technologies Malta evaluation
board.
config MIPS_SEAD
@@ -358,50 +316,64 @@ config MIPS_SEAD
depends on EXPERIMENTAL
select IRQ_CPU
select DMA_NONCOHERENT
+ select MIPS_BOARDS_GEN
+ select SYS_HAS_CPU_MIPS32_R1
+ select SYS_HAS_CPU_MIPS32_R2
+ select SYS_HAS_CPU_MIPS64_R1
select SYS_SUPPORTS_32BIT_KERNEL
- select SYS_SUPPORTS_64BIT_KERNEL
+ select SYS_SUPPORTS_64BIT_KERNEL if EXPERIMENTAL
+ select SYS_SUPPORTS_BIG_ENDIAN
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+ help
+ This enables support for the MIPS Technologies SEAD evaluation
+ board.
-config MOMENCO_OCELOT
- bool "Support for Momentum Ocelot board"
+config MIPS_SIM
+ bool 'Support for MIPS simulator (MIPSsim)'
select DMA_NONCOHERENT
- select HW_HAS_PCI
select IRQ_CPU
- select IRQ_CPU_RM7K
- select MIPS_GT64120
- select RM7000_CPU_SCACHE
- select SWAP_IO_SPACE
+ select SYS_HAS_CPU_MIPS32_R1
+ select SYS_HAS_CPU_MIPS32_R2
select SYS_SUPPORTS_32BIT_KERNEL
- select SYS_SUPPORTS_64BIT_KERNEL
+ select SYS_SUPPORTS_BIG_ENDIAN
+ select SYS_SUPPORTS_LITTLE_ENDIAN
help
- The Ocelot is a MIPS-based Single Board Computer (SBC) made by
- Momentum Computer <http://www.momenco.com/>.
+ This option enables support for MIPS Technologies MIPSsim software
+ emulator.
-config MOMENCO_OCELOT_G
- bool "Support for Momentum Ocelot-G board"
+config MOMENCO_JAGUAR_ATX
+ bool "Support for Momentum Jaguar board"
+ select BOOT_ELF32
select DMA_NONCOHERENT
select HW_HAS_PCI
select IRQ_CPU
select IRQ_CPU_RM7K
+ select IRQ_MV64340
+ select LIMITED_DMA
select PCI_MARVELL
select RM7000_CPU_SCACHE
select SWAP_IO_SPACE
+ select SYS_HAS_CPU_RM9000
select SYS_SUPPORTS_32BIT_KERNEL
select SYS_SUPPORTS_64BIT_KERNEL
+ select SYS_SUPPORTS_BIG_ENDIAN
help
- The Ocelot is a MIPS-based Single Board Computer (SBC) made by
+ The Jaguar ATX is a MIPS-based Single Board Computer (SBC) made by
Momentum Computer <http://www.momenco.com/>.
-config MOMENCO_OCELOT_C
- bool "Support for Momentum Ocelot-C board"
+config MOMENCO_OCELOT
+ bool "Support for Momentum Ocelot board"
select DMA_NONCOHERENT
select HW_HAS_PCI
select IRQ_CPU
- select IRQ_MV64340
- select PCI_MARVELL
+ select IRQ_CPU_RM7K
+ select MIPS_GT64120
select RM7000_CPU_SCACHE
select SWAP_IO_SPACE
+ select SYS_HAS_CPU_RM7000
select SYS_SUPPORTS_32BIT_KERNEL
select SYS_SUPPORTS_64BIT_KERNEL
+ select SYS_SUPPORTS_BIG_ENDIAN
help
The Ocelot is a MIPS-based Single Board Computer (SBC) made by
Momentum Computer <http://www.momenco.com/>.
@@ -417,80 +389,95 @@ config MOMENCO_OCELOT_3
select PCI_MARVELL
select RM7000_CPU_SCACHE
select SWAP_IO_SPACE
+ select SYS_HAS_CPU_RM9000
select SYS_SUPPORTS_32BIT_KERNEL
select SYS_SUPPORTS_64BIT_KERNEL
+ select SYS_SUPPORTS_BIG_ENDIAN
help
The Ocelot-3 is based off Discovery III System Controller and
PMC-Sierra Rm79000 core.
-config MOMENCO_JAGUAR_ATX
- bool "Support for Momentum Jaguar board"
- select BOOT_ELF32
+config MOMENCO_OCELOT_C
+ bool "Support for Momentum Ocelot-C board"
select DMA_NONCOHERENT
select HW_HAS_PCI
select IRQ_CPU
- select IRQ_CPU_RM7K
select IRQ_MV64340
- select LIMITED_DMA
select PCI_MARVELL
select RM7000_CPU_SCACHE
select SWAP_IO_SPACE
+ select SYS_HAS_CPU_RM7000
select SYS_SUPPORTS_32BIT_KERNEL
select SYS_SUPPORTS_64BIT_KERNEL
+ select SYS_SUPPORTS_BIG_ENDIAN
help
- The Jaguar ATX is a MIPS-based Single Board Computer (SBC) made by
+ The Ocelot is a MIPS-based Single Board Computer (SBC) made by
Momentum Computer <http://www.momenco.com/>.
-config JAGUAR_DMALOW
- bool "Low DMA Mode"
- depends on MOMENCO_JAGUAR_ATX
- help
- Select to Y if jump JP5 is set on your board, N otherwise. Normally
- the jumper is set, so if you feel unsafe, just say Y.
-
-config PMC_YOSEMITE
- bool "Support for PMC-Sierra Yosemite eval board"
- select DMA_COHERENT
+config MOMENCO_OCELOT_G
+ bool "Support for Momentum Ocelot-G board"
+ select DMA_NONCOHERENT
select HW_HAS_PCI
select IRQ_CPU
select IRQ_CPU_RM7K
- select IRQ_CPU_RM9K
+ select PCI_MARVELL
+ select RM7000_CPU_SCACHE
select SWAP_IO_SPACE
+ select SYS_HAS_CPU_RM7000
select SYS_SUPPORTS_32BIT_KERNEL
select SYS_SUPPORTS_64BIT_KERNEL
+ select SYS_SUPPORTS_BIG_ENDIAN
help
- Yosemite is an evaluation board for the RM9000x2 processor
- manufactured by PMC-Sierra
+ The Ocelot is a MIPS-based Single Board Computer (SBC) made by
+ Momentum Computer <http://www.momenco.com/>.
-config HYPERTRANSPORT
- bool "Hypertransport Support for PMC-Sierra Yosemite"
- depends on PMC_YOSEMITE
+config MIPS_XXS1500
+ bool "Support for MyCable XXS1500 board"
+ select DMA_NONCOHERENT
+ select SOC_AU1500
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+
+config PNX8550_V2PCI
+ bool "Support for Philips PNX8550 based Viper2-PCI board"
+ select PNX8550
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+
+config PNX8550_JBS
+ bool "Support for Philips PNX8550 based JBS board"
+ select PNX8550
+ select SYS_SUPPORTS_LITTLE_ENDIAN
config DDB5074
bool "Support for NEC DDB Vrc-5074 (EXPERIMENTAL)"
depends on EXPERIMENTAL
+ select DDB5XXX_COMMON
select DMA_NONCOHERENT
select HAVE_STD_PC_SERIAL_PORT
select HW_HAS_PCI
select IRQ_CPU
select I8259
select ISA
+ select SYS_HAS_CPU_R5000
select SYS_SUPPORTS_32BIT_KERNEL
- select SYS_SUPPORTS_64BIT_KERNEL
+ select SYS_SUPPORTS_64BIT_KERNEL if EXPERIMENTAL
+ select SYS_SUPPORTS_LITTLE_ENDIAN
help
This enables support for the VR5000-based NEC DDB Vrc-5074
evaluation board.
config DDB5476
bool "Support for NEC DDB Vrc-5476"
+ select DDB5XXX_COMMON
select DMA_NONCOHERENT
select HAVE_STD_PC_SERIAL_PORT
select HW_HAS_PCI
select IRQ_CPU
select I8259
select ISA
+ select SYS_HAS_CPU_R5432
select SYS_SUPPORTS_32BIT_KERNEL
select SYS_SUPPORTS_64BIT_KERNEL if EXPERIMENTAL
+ select SYS_SUPPORTS_LITTLE_ENDIAN
help
This enables support for the R5432-based NEC DDB Vrc-5476
evaluation board.
@@ -501,12 +488,15 @@ config DDB5476
config DDB5477
bool "Support for NEC DDB Vrc-5477"
+ select DDB5XXX_COMMON
select DMA_NONCOHERENT
select HW_HAS_PCI
select I8259
select IRQ_CPU
+ select SYS_HAS_CPU_R5432
select SYS_SUPPORTS_32BIT_KERNEL
select SYS_SUPPORTS_64BIT_KERNEL if EXPERIMENTAL
+ select SYS_SUPPORTS_LITTLE_ENDIAN
help
This enables support for the R5432-based NEC DDB Vrc-5477,
or Rockhopper/SolutionGear boards with R5432/R5500 CPUs.
@@ -514,10 +504,28 @@ config DDB5477
Features : kernel debugging, serial terminal, NFS root fs, on-board
ether port USB, AC97, PCI, etc.
-config DDB5477_BUS_FREQUENCY
- int "bus frequency (in kHZ, 0 for auto-detect)"
- depends on DDB5477
- default 0
+config MACH_VR41XX
+ bool "Support for NEC VR4100 series based machines"
+ select SYS_HAS_CPU_VR41XX
+ select SYS_SUPPORTS_32BIT_KERNEL
+ select SYS_SUPPORTS_64BIT_KERNEL if EXPERIMENTAL
+
+config PMC_YOSEMITE
+ bool "Support for PMC-Sierra Yosemite eval board"
+ select DMA_COHERENT
+ select HW_HAS_PCI
+ select IRQ_CPU
+ select IRQ_CPU_RM7K
+ select IRQ_CPU_RM9K
+ select SWAP_IO_SPACE
+ select SYS_HAS_CPU_RM9000
+ select SYS_SUPPORTS_32BIT_KERNEL
+ select SYS_SUPPORTS_64BIT_KERNEL
+ select SYS_SUPPORTS_BIG_ENDIAN
+ select SYS_SUPPORTS_HIGHMEM
+ help
+ Yosemite is an evaluation board for the RM9000x2 processor
+ manufactured by PMC-Sierra.
config QEMU
bool "Support for Qemu"
@@ -527,15 +535,16 @@ config QEMU
select I8259
select ISA
select SWAP_IO_SPACE
+ select SYS_HAS_CPU_MIPS32_R1
select SYS_SUPPORTS_32BIT_KERNEL
select SYS_SUPPORTS_BIG_ENDIAN
help
- Qemu is a software emulator which among other architectures also
- can simulate a MIPS32 4Kc system. This patch adds support for the
- system architecture that currently is being simulated by Qemu. It
- will eventually be removed again when Qemu has the capability to
- simulate actual MIPS hardware platforms. More information on Qemu
- can be found at http://www.linux-mips.org/wiki/Qemu.
+ Qemu is a software emulator which among other architectures also
+ can simulate a MIPS32 4Kc system. This patch adds support for the
+ system architecture that currently is being simulated by Qemu. It
+ will eventually be removed again when Qemu has the capability to
+ simulate actual MIPS hardware platforms. More information on Qemu
+ can be found at http://www.linux-mips.org/wiki/Qemu.
config SGI_IP22
bool "Support for SGI IP22 (Indy/Indigo2)"
@@ -543,11 +552,15 @@ config SGI_IP22
select ARC32
select BOOT_ELF32
select DMA_NONCOHERENT
+ select HW_HAS_EISA
select IP22_CPU_SCACHE
select IRQ_CPU
select SWAP_IO_SPACE
+ select SYS_HAS_CPU_R4X00
+ select SYS_HAS_CPU_R5000
select SYS_SUPPORTS_32BIT_KERNEL
select SYS_SUPPORTS_64BIT_KERNEL
+ select SYS_SUPPORTS_BIG_ENDIAN
help
This are the SGI Indy, Challenge S and Indigo2, as well as certain
OEM variants like the Tandem CMN B006S. To compile a Linux kernel
@@ -557,70 +570,18 @@ config SGI_IP27
bool "Support for SGI IP27 (Origin200/2000)"
select ARC
select ARC64
+ select BOOT_ELF64
select DMA_IP27
select HW_HAS_PCI
select PCI_DOMAINS
+ select SYS_HAS_CPU_R10000
select SYS_SUPPORTS_64BIT_KERNEL
+ select SYS_SUPPORTS_BIG_ENDIAN
help
This are the SGI Origin 200, Origin 2000 and Onyx 2 Graphics
workstations. To compile a Linux kernel that runs on these, say Y
here.
-#config SGI_SN0_XXL
-# bool "IP27 XXL"
-# depends on SGI_IP27
-# This options adds support for userspace processes upto 16TB size.
-# Normally the limit is just .5TB.
-
-config SGI_SN0_N_MODE
- bool "IP27 N-Mode"
- depends on SGI_IP27
- help
- The nodes of Origin 200, Origin 2000 and Onyx 2 systems can be
- configured in either N-Modes which allows for more nodes or M-Mode
- which allows for more memory. Your system is most probably
- running in M-Mode, so you should say N here.
-
-config ARCH_DISCONTIGMEM_ENABLE
- bool
- default y if SGI_IP27
- help
- Say Y to upport efficient handling of discontiguous physical memory,
- for architectures which are either NUMA (Non-Uniform Memory Access)
- or have huge holes in the physical address space for other reasons.
- See <file:Documentation/vm/numa> for more.
-
-config NUMA
- bool "NUMA Support"
- depends on SGI_IP27
- help
- Say Y to compile the kernel to support NUMA (Non-Uniform Memory
- Access). This option is for configuring high-end multiprocessor
- server machines. If in doubt, say N.
-
-config MAPPED_KERNEL
- bool "Mapped kernel support"
- depends on SGI_IP27
- help
- Change the way a Linux kernel is loaded into memory on a MIPS64
- machine. This is required in order to support text replication and
- NUMA. If you need to understand it, read the source code.
-
-config REPLICATE_KTEXT
- bool "Kernel text replication support"
- depends on SGI_IP27
- help
- Say Y here to enable replicating the kernel text across multiple
- nodes in a NUMA cluster. This trades memory for speed.
-
-config REPLICATE_EXHANDLERS
- bool "Exception handler replication support"
- depends on SGI_IP27
- help
- Say Y here to enable replicating the kernel exception handlers
- across multiple nodes in a NUMA cluster. This trades memory for
- speed.
-
config SGI_IP32
bool "Support for SGI IP32 (O2) (EXPERIMENTAL)"
depends on EXPERIMENTAL
@@ -633,353 +594,152 @@ config SGI_IP32
select HW_HAS_PCI
select R5000_CPU_SCACHE
select RM7000_CPU_SCACHE
+ select SYS_HAS_CPU_R5000
+ select SYS_HAS_CPU_R10000 if BROKEN
+ select SYS_HAS_CPU_RM7000
select SYS_SUPPORTS_64BIT_KERNEL
+ select SYS_SUPPORTS_BIG_ENDIAN
help
If you want this kernel to run on SGI O2 workstation, say Y here.
-config SOC_AU1X00
- bool "Support for AMD/Alchemy Au1X00 SOCs"
- select SYS_SUPPORTS_32BIT_KERNEL
-
-choice
- prompt "Au1X00 SOC Type"
- depends on SOC_AU1X00
- help
- Say Y here to enable support for one of three AMD/Alchemy
- SOCs. For additional documentation see www.amd.com.
-
-config SOC_AU1000
- bool "SOC_AU1000"
-config SOC_AU1100
- bool "SOC_AU1100"
-config SOC_AU1500
- bool "SOC_AU1500"
-config SOC_AU1550
- bool "SOC_AU1550"
-
-endchoice
-
-choice
- prompt "AMD/Alchemy Au1x00 board support"
- depends on SOC_AU1X00
- help
- These are evaluation boards built by AMD/Alchemy to
- showcase their Au1X00 Internet Edge Processors. The SOC design
- is based on the MIPS32 architecture running at 266/400/500MHz
- with many integrated peripherals. Further information can be
- found at their website, <http://www.amd.com/>. Say Y here if you
- wish to build a kernel for this platform.
-
-config MIPS_PB1000
- bool "PB1000 board"
- depends on SOC_AU1000
- select DMA_NONCOHERENT
- select HW_HAS_PCI
- select SWAP_IO_SPACE
-
-config MIPS_PB1100
- bool "PB1100 board"
- depends on SOC_AU1100
- select DMA_NONCOHERENT
- select HW_HAS_PCI
- select SWAP_IO_SPACE
-
-config MIPS_PB1500
- bool "PB1500 board"
- depends on SOC_AU1500
- select DMA_COHERENT
- select HW_HAS_PCI
-
-config MIPS_PB1550
- bool "PB1550 board"
- depends on SOC_AU1550
- select DMA_COHERENT
- select HW_HAS_PCI
- select MIPS_DISABLE_OBSOLETE_IDE
-
-config MIPS_DB1000
- bool "DB1000 board"
- depends on SOC_AU1000
- select DMA_NONCOHERENT
- select HW_HAS_PCI
-
-config MIPS_DB1100
- bool "DB1100 board"
- depends on SOC_AU1100
- select DMA_NONCOHERENT
-
-config MIPS_DB1500
- bool "DB1500 board"
- depends on SOC_AU1500
- select DMA_COHERENT
- select HW_HAS_PCI
- select MIPS_DISABLE_OBSOLETE_IDE
-
-config MIPS_DB1550
- bool "DB1550 board"
- depends on SOC_AU1550
- select HW_HAS_PCI
- select DMA_COHERENT
- select MIPS_DISABLE_OBSOLETE_IDE
-
-config MIPS_BOSPORUS
- bool "Bosporus board"
- depends on SOC_AU1500
- select DMA_NONCOHERENT
-
-config MIPS_MIRAGE
- bool "Mirage board"
- depends on SOC_AU1500
- select DMA_NONCOHERENT
-
-config MIPS_XXS1500
- bool "MyCable XXS1500 board"
- depends on SOC_AU1500
- select DMA_NONCOHERENT
-
-config MIPS_MTX1
- bool "4G Systems MTX-1 board"
- depends on SOC_AU1500
- select HW_HAS_PCI
- select DMA_NONCOHERENT
-
-endchoice
-
-config SIBYTE_SB1xxx_SOC
- bool "Support for Broadcom BCM1xxx SOCs (EXPERIMENTAL)"
- depends on EXPERIMENTAL
+config SIBYTE_BIGSUR
+ bool "Support for Sibyte BigSur"
select BOOT_ELF32
select DMA_COHERENT
+ select PCI_DOMAINS
+ select SIBYTE_BCM1x80
select SWAP_IO_SPACE
- select SYS_SUPPORTS_32BIT_KERNEL
- select SYS_SUPPORTS_64BIT_KERNEL
-
-choice
- prompt "BCM1xxx SOC-based board"
- depends on SIBYTE_SB1xxx_SOC
- default SIBYTE_SWARM
- help
- Enable support for boards based on the SiByte line of SOCs
- from Broadcom. There are configurations for the known
- evaluation boards, or you can choose "Other" and add your
- own board support code.
+ select SYS_HAS_CPU_SB1
+ select SYS_SUPPORTS_BIG_ENDIAN
+ select SYS_SUPPORTS_LITTLE_ENDIAN
config SIBYTE_SWARM
- bool "BCM91250A-SWARM"
+ bool "Support for Sibyte BCM91250A-SWARM"
+ select BOOT_ELF32
+ select DMA_COHERENT
select SIBYTE_SB1250
+ select SWAP_IO_SPACE
+ select SYS_HAS_CPU_SB1
+ select SYS_SUPPORTS_BIG_ENDIAN
+ select SYS_SUPPORTS_HIGHMEM
+ select SYS_SUPPORTS_LITTLE_ENDIAN
config SIBYTE_SENTOSA
- bool "BCM91250E-Sentosa"
+ bool "Support for Sibyte BCM91250E-Sentosa"
+ depends on EXPERIMENTAL
+ select BOOT_ELF32
+ select DMA_COHERENT
select SIBYTE_SB1250
+ select SWAP_IO_SPACE
+ select SYS_HAS_CPU_SB1
+ select SYS_SUPPORTS_BIG_ENDIAN
+ select SYS_SUPPORTS_LITTLE_ENDIAN
config SIBYTE_RHONE
- bool "BCM91125E-Rhone"
+ bool "Support for Sibyte BCM91125E-Rhone"
+ depends on EXPERIMENTAL
+ select BOOT_ELF32
+ select DMA_COHERENT
select SIBYTE_BCM1125H
+ select SWAP_IO_SPACE
+ select SYS_HAS_CPU_SB1
+ select SYS_SUPPORTS_BIG_ENDIAN
+ select SYS_SUPPORTS_LITTLE_ENDIAN
config SIBYTE_CARMEL
- bool "BCM91120x-Carmel"
+ bool "Support for Sibyte BCM91120x-Carmel"
+ depends on EXPERIMENTAL
+ select BOOT_ELF32
+ select DMA_COHERENT
select SIBYTE_BCM1120
+ select SWAP_IO_SPACE
+ select SYS_HAS_CPU_SB1
+ select SYS_SUPPORTS_BIG_ENDIAN
+ select SYS_SUPPORTS_LITTLE_ENDIAN
config SIBYTE_PTSWARM
- bool "BCM91250PT-PTSWARM"
+ bool "Support for Sibyte BCM91250PT-PTSWARM"
+ depends on EXPERIMENTAL
+ select BOOT_ELF32
+ select DMA_COHERENT
select SIBYTE_SB1250
+ select SWAP_IO_SPACE
+ select SYS_HAS_CPU_SB1
+ select SYS_SUPPORTS_BIG_ENDIAN
+ select SYS_SUPPORTS_HIGHMEM
+ select SYS_SUPPORTS_LITTLE_ENDIAN
config SIBYTE_LITTLESUR
- bool "BCM91250C2-LittleSur"
+ bool "Support for Sibyte BCM91250C2-LittleSur"
+ depends on EXPERIMENTAL
+ select BOOT_ELF32
+ select DMA_COHERENT
select SIBYTE_SB1250
+ select SWAP_IO_SPACE
+ select SYS_HAS_CPU_SB1
+ select SYS_SUPPORTS_BIG_ENDIAN
+ select SYS_SUPPORTS_HIGHMEM
+ select SYS_SUPPORTS_LITTLE_ENDIAN
config SIBYTE_CRHINE
- bool "BCM91120C-CRhine"
+ bool "Support for Sibyte BCM91120C-CRhine"
+ depends on EXPERIMENTAL
+ select BOOT_ELF32
+ select DMA_COHERENT
select SIBYTE_BCM1120
+ select SWAP_IO_SPACE
+ select SYS_HAS_CPU_SB1
+ select SYS_SUPPORTS_BIG_ENDIAN
+ select SYS_SUPPORTS_LITTLE_ENDIAN
config SIBYTE_CRHONE
- bool "BCM91125C-CRhone"
- select SIBYTE_BCM1125
-
-config SIBYTE_UNKNOWN
- bool "Other"
-
-endchoice
-
-config SIBYTE_BOARD
- bool
- depends on SIBYTE_SB1xxx_SOC && !SIBYTE_UNKNOWN
- default y
-
-choice
- prompt "BCM1xxx SOC Type"
- depends on SIBYTE_UNKNOWN
- default SIBYTE_UNK_BCM1250
- help
- Since you haven't chosen a known evaluation board from
- Broadcom, you must explicitly pick the SOC this kernel is
- targetted for.
-
-config SIBYTE_UNK_BCM1250
- bool "BCM1250"
- select SIBYTE_SB1250
-
-config SIBYTE_UNK_BCM1120
- bool "BCM1120"
- select SIBYTE_BCM1120
-
-config SIBYTE_UNK_BCM1125
- bool "BCM1125"
+ bool "Support for Sibyte BCM91125C-CRhone"
+ depends on EXPERIMENTAL
+ select BOOT_ELF32
+ select DMA_COHERENT
select SIBYTE_BCM1125
-
-config SIBYTE_UNK_BCM1125H
- bool "BCM1125H"
- select SIBYTE_BCM1125H
-
-endchoice
-
-config SIBYTE_SB1250
- bool
- select HW_HAS_PCI
-
-config SIBYTE_BCM1120
- bool
- select SIBYTE_BCM112X
-
-config SIBYTE_BCM1125
- bool
- select HW_HAS_PCI
- select SIBYTE_BCM112X
-
-config SIBYTE_BCM1125H
- bool
- select HW_HAS_PCI
- select SIBYTE_BCM112X
-
-config SIBYTE_BCM112X
- bool
-
-choice
- prompt "SiByte SOC Stepping"
- depends on SIBYTE_SB1xxx_SOC
-
-config CPU_SB1_PASS_1
- bool "1250 Pass1"
- depends on SIBYTE_SB1250
- select CPU_HAS_PREFETCH
-
-config CPU_SB1_PASS_2_1250
- bool "1250 An"
- depends on SIBYTE_SB1250
- select CPU_SB1_PASS_2
- help
- Also called BCM1250 Pass 2
-
-config CPU_SB1_PASS_2_2
- bool "1250 Bn"
- depends on SIBYTE_SB1250
- select CPU_HAS_PREFETCH
- help
- Also called BCM1250 Pass 2.2
-
-config CPU_SB1_PASS_4
- bool "1250 Cn"
- depends on SIBYTE_SB1250
- select CPU_HAS_PREFETCH
- help
- Also called BCM1250 Pass 3
-
-config CPU_SB1_PASS_2_112x
- bool "112x Hybrid"
- depends on SIBYTE_BCM112X
- select CPU_SB1_PASS_2
-
-config CPU_SB1_PASS_3
- bool "112x An"
- depends on SIBYTE_BCM112X
- select CPU_HAS_PREFETCH
-
-endchoice
-
-config CPU_SB1_PASS_2
- bool
-
-config SIBYTE_HAS_LDT
- bool
- depends on PCI && (SIBYTE_SB1250 || SIBYTE_BCM1125H)
- default y
-
-config SIMULATION
- bool "Running under simulation"
- depends on SIBYTE_SB1xxx_SOC
- help
- Build a kernel suitable for running under the GDB simulator.
- Primarily adjusts the kernel's notion of time.
-
-config SIBYTE_CFE
- bool "Booting from CFE"
- depends on SIBYTE_SB1xxx_SOC
- help
- Make use of the CFE API for enumerating available memory,
- controlling secondary CPUs, and possibly console output.
-
-config SIBYTE_CFE_CONSOLE
- bool "Use firmware console"
- depends on SIBYTE_CFE
- help
- Use the CFE API's console write routines during boot. Other console
- options (VT console, sb1250 duart console, etc.) should not be
- configured.
-
-config SIBYTE_STANDALONE
- bool
- depends on SIBYTE_SB1xxx_SOC && !SIBYTE_CFE
- default y
-
-config SIBYTE_STANDALONE_RAM_SIZE
- int "Memory size (in megabytes)"
- depends on SIBYTE_STANDALONE
- default "32"
-
-config SIBYTE_BUS_WATCHER
- bool "Support for Bus Watcher statistics"
- depends on SIBYTE_SB1xxx_SOC
- help
- Handle and keep statistics on the bus error interrupts (COR_ECC,
- BAD_ECC, IO_BUS).
-
-config SIBYTE_BW_TRACE
- bool "Capture bus trace before bus error"
- depends on SIBYTE_BUS_WATCHER
- help
- Run a continuous bus trace, dumping the raw data as soon as
- a ZBbus error is detected. Cannot work if ZBbus profiling
- is turned on, and also will interfere with JTAG-based trace
- buffer activity. Raw buffer data is dumped to console, and
- must be processed off-line.
-
-config SIBYTE_SB1250_PROF
- bool "Support for SB1/SOC profiling - SB1/SCD perf counters"
- depends on SIBYTE_SB1xxx_SOC
-
-config SIBYTE_TBPROF
- bool "Support for ZBbus profiling"
- depends on SIBYTE_SB1xxx_SOC
+ select SWAP_IO_SPACE
+ select SYS_HAS_CPU_SB1
+ select SYS_SUPPORTS_BIG_ENDIAN
+ select SYS_SUPPORTS_HIGHMEM
+ select SYS_SUPPORTS_LITTLE_ENDIAN
config SNI_RM200_PCI
bool "Support for SNI RM200 PCI"
select ARC
select ARC32
+ select ARCH_MAY_HAVE_PC_FDC
select BOOT_ELF32
select DMA_NONCOHERENT
select GENERIC_ISA_DMA
select HAVE_STD_PC_SERIAL_PORT
+ select HW_HAS_EISA
select HW_HAS_PCI
select I8259
select ISA
+ select SYS_HAS_CPU_R4X00
select SYS_SUPPORTS_32BIT_KERNEL
select SYS_SUPPORTS_64BIT_KERNEL if EXPERIMENTAL
+ select SYS_SUPPORTS_BIG_ENDIAN if EXPERIMENTAL
+ select SYS_SUPPORTS_HIGHMEM
+ select SYS_SUPPORTS_LITTLE_ENDIAN
help
The SNI RM200 PCI was a MIPS-based platform manufactured by Siemens
Nixdorf Informationssysteme (SNI), parent company of Pyramid
Technology and now in turn merged with Fujitsu. Say Y here to
support this machine type.
+config TOSHIBA_JMR3927
+ bool "Support for Toshiba JMR-TX3927 board"
+ select DMA_NONCOHERENT
+ select HW_HAS_PCI
+ select MIPS_TX3927
+ select SWAP_IO_SPACE
+ select SYS_HAS_CPU_TX39XX
+ select SYS_SUPPORTS_32BIT_KERNEL
+ select SYS_SUPPORTS_BIG_ENDIAN
+ select TOSHIBA_BOARDS
+
config TOSHIBA_RBTX4927
bool "Support for Toshiba TBTX49[23]7 board"
select DMA_NONCOHERENT
@@ -988,15 +748,51 @@ config TOSHIBA_RBTX4927
select I8259
select ISA
select SWAP_IO_SPACE
+ select SYS_HAS_CPU_TX49XX
select SYS_SUPPORTS_32BIT_KERNEL
select SYS_SUPPORTS_64BIT_KERNEL
+ select SYS_SUPPORTS_BIG_ENDIAN
+ select TOSHIBA_BOARDS
help
This Toshiba board is based on the TX4927 processor. Say Y here to
support this machine type
-config TOSHIBA_FPCIB0
- bool "FPCIB0 Backplane Support"
- depends on TOSHIBA_RBTX4927
+config TOSHIBA_RBTX4938
+ bool "Support for Toshiba RBTX4938 board"
+ select HAVE_STD_PC_SERIAL_PORT
+ select DMA_NONCOHERENT
+ select GENERIC_ISA_DMA
+ select HAS_TXX9_SERIAL
+ select HW_HAS_PCI
+ select I8259
+ select ISA
+ select SWAP_IO_SPACE
+ select SYS_HAS_CPU_TX49XX
+ select SYS_SUPPORTS_32BIT_KERNEL
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+ select SYS_SUPPORTS_BIG_ENDIAN
+ select TOSHIBA_BOARDS
+ help
+ This Toshiba board is based on the TX4938 processor. Say Y here to
+ support this machine type
+
+endchoice
+
+source "arch/mips/ddb5xxx/Kconfig"
+source "arch/mips/gt64120/ev64120/Kconfig"
+source "arch/mips/jazz/Kconfig"
+source "arch/mips/ite-boards/Kconfig"
+source "arch/mips/lasat/Kconfig"
+source "arch/mips/momentum/Kconfig"
+source "arch/mips/pmc-sierra/Kconfig"
+source "arch/mips/sgi-ip27/Kconfig"
+source "arch/mips/sibyte/Kconfig"
+source "arch/mips/tx4927/Kconfig"
+source "arch/mips/tx4938/Kconfig"
+source "arch/mips/vr41xx/Kconfig"
+source "arch/mips/philips/pnx8550/common/Kconfig"
+
+endmenu
config RWSEM_GENERIC_SPINLOCK
bool
@@ -1014,8 +810,9 @@ config GENERIC_CALIBRATE_DELAY
#
config ARC
bool
- depends on SNI_RM200_PCI || SGI_IP32 || SGI_IP27 || SGI_IP22 || MIPS_MAGNUM_4000 || OLIVETTI_M700 || ACER_PICA_61
- default y
+
+config ARCH_MAY_HAVE_PC_FDC
+ bool
config DMA_COHERENT
bool
@@ -1034,51 +831,65 @@ config DMA_NONCOHERENT
config DMA_NEED_PCI_MAP_STATE
bool
+config OWN_DMA
+ bool
+
config EARLY_PRINTK
bool
- depends on MACH_DECSTATION
- default y
config GENERIC_ISA_DMA
bool
- depends on SNI_RM200_PCI || MIPS_MAGNUM_4000 || OLIVETTI_M700 || ACER_PICA_61 || MIPS_MALTA
- default y
config I8259
bool
- depends on SNI_RM200_PCI || DDB5477 || DDB5476 || DDB5074 || MACH_JAZZ || MIPS_MALTA || MIPS_COBALT
- default y
config LIMITED_DMA
bool
select HIGHMEM
+ select SYS_SUPPORTS_HIGHMEM
config MIPS_BONITO64
bool
- depends on MIPS_ATLAS || MIPS_MALTA
- default y
config MIPS_MSC
bool
- depends on MIPS_ATLAS || MIPS_MALTA
- default y
config MIPS_NILE4
bool
- depends on LASAT
- default y
config MIPS_DISABLE_OBSOLETE_IDE
bool
-config CPU_LITTLE_ENDIAN
- bool "Generate little endian code"
- default y if ACER_PICA_61 || CASIO_E55 || DDB5074 || DDB5476 || DDB5477 || MACH_DECSTATION || IBM_WORKPAD || LASAT || MIPS_COBALT || MIPS_ITE8172 || MIPS_IVR || SOC_AU1X00 || OLIVETTI_M700 || SNI_RM200_PCI || VICTOR_MPC30X || ZAO_CAPCELLA
- default n if MIPS_EV64120 || MIPS_EV96100 || MOMENCO_OCELOT || MOMENCO_OCELOT_G || SGI_IP22 || SGI_IP27 || SGI_IP32 || TOSHIBA_JMR3927
+#
+# Endianess selection. Suffiently obscure so many users don't know what to
+# answer,so we try hard to limit the available choices. Also the use of a
+# choice statement should be more obvious to the user.
+#
+choice
+ prompt "Endianess selection"
help
Some MIPS machines can be configured for either little or big endian
- byte order. These modes require different kernels. Say Y if your
- machine is little endian, N if it's a big endian machine.
+ byte order. These modes require different kernels and a different
+ Linux distribution. In general there is one prefered byteorder for a
+ particular system but some systems are just as commonly used in the
+ one or the other endianess.
+
+config CPU_BIG_ENDIAN
+ bool "Big endian"
+ depends on SYS_SUPPORTS_BIG_ENDIAN
+
+config CPU_LITTLE_ENDIAN
+ bool "Little endian"
+ depends on SYS_SUPPORTS_LITTLE_ENDIAN
+ help
+
+endchoice
+
+config SYS_SUPPORTS_BIG_ENDIAN
+ bool
+
+config SYS_SUPPORTS_LITTLE_ENDIAN
+ bool
config IRQ_CPU
bool
@@ -1086,42 +897,69 @@ config IRQ_CPU
config IRQ_CPU_RM7K
bool
+config IRQ_CPU_RM9K
+ bool
+
config IRQ_MV64340
bool
config DDB5XXX_COMMON
bool
- depends on DDB5074 || DDB5476 || DDB5477
- default y
config MIPS_BOARDS_GEN
bool
- depends on MIPS_ATLAS || MIPS_MALTA || MIPS_SEAD
- default y
config MIPS_GT64111
bool
- depends on MIPS_COBALT
- default y
config MIPS_GT64120
bool
- depends on MIPS_EV64120 || MIPS_EV96100 || LASAT || MIPS_ATLAS || MIPS_MALTA || MOMENCO_OCELOT
- default y
config MIPS_TX3927
bool
- depends on TOSHIBA_JMR3927
select HAS_TXX9_SERIAL
- default y
config PCI_MARVELL
bool
config ITE_BOARD_GEN
bool
- depends on MIPS_IVR || MIPS_ITE8172
- default y
+
+config SOC_AU1000
+ bool
+ select SOC_AU1X00
+
+config SOC_AU1100
+ bool
+ select SOC_AU1X00
+
+config SOC_AU1500
+ bool
+ select SOC_AU1X00
+
+config SOC_AU1550
+ bool
+ select SOC_AU1X00
+
+config SOC_AU1200
+ bool
+ select SOC_AU1X00
+
+config SOC_AU1X00
+ bool
+ select SYS_HAS_CPU_MIPS32_R1
+ select SYS_SUPPORTS_32BIT_KERNEL
+
+config PNX8550
+ bool
+ select SOC_PNX8550
+
+config SOC_PNX8550
+ bool
+ select DMA_NONCOHERENT
+ select HW_HAS_PCI
+ select SYS_HAS_CPU_MIPS32_R1
+ select SYS_SUPPORTS_32BIT_KERNEL
config SWAP_IO_SPACE
bool
@@ -1148,6 +986,9 @@ config SYSCLK_100
endchoice
+config ARC32
+ bool
+
config AU1X00_USB_DEVICE
bool
depends on MIPS_PB1500 || MIPS_PB1100 || MIPS_PB1000
@@ -1155,11 +996,7 @@ config AU1X00_USB_DEVICE
config MIPS_GT96100
bool
- depends on MIPS_EV96100
- default y
- help
- Say Y here to support the Galileo Technology GT96100 communications
- controller card. There is a web page at <http://www.galileot.com/>.
+ select MIPS_GT64120
config IT8172_CIR
bool
@@ -1173,8 +1010,6 @@ config IT8712
config BOOT_ELF32
bool
- depends on MACH_DECSTATION || MIPS_ATLAS || MIPS_MALTA || MOMENCO_JAGUAR_ATX || MOMENCO_OCELOT_3 || SIBYTE_SB1xxx_SOC || SGI_IP32 || SGI_IP22 || SNI_RM200_PCI
- default y
config MIPS_L1_CACHE_SHIFT
int
@@ -1182,11 +1017,6 @@ config MIPS_L1_CACHE_SHIFT
default "7" if SGI_IP27
default "5"
-config ARC32
- bool
- depends on MACH_JAZZ || SNI_RM200_PCI || SGI_IP22 || SGI_IP32
- default y
-
config HAVE_STD_PC_SERIAL_PORT
bool
@@ -1206,30 +1036,12 @@ config ARC_PROMLIB
config ARC64
bool
- depends on SGI_IP27
- default y
config BOOT_ELF64
bool
- depends on SGI_IP27
- default y
-
-#config MAPPED_PCI_IO y
-# bool
-# depends on SGI_IP27
-# default y
-
-config QL_ISP_A64
- bool
- depends on SGI_IP27
- default y
config TOSHIBA_BOARDS
bool
- depends on TOSHIBA_JMR3927 || TOSHIBA_RBTX4927
- default y
-
-endmenu
menu "CPU selection"
@@ -1237,18 +1049,69 @@ choice
prompt "CPU type"
default CPU_R4X00
-config CPU_MIPS32
- bool "MIPS32"
+config CPU_MIPS32_R1
+ bool "MIPS32 Release 1"
+ depends on SYS_HAS_CPU_MIPS32_R1
+ select CPU_HAS_PREFETCH
select CPU_SUPPORTS_32BIT_KERNEL
+ help
+ Choose this option to build a kernel for release 1 or later of the
+ MIPS32 architecture. Most modern embedded systems with a 32-bit
+ MIPS processor are based on a MIPS32 processor. If you know the
+ specific type of processor in your system, choose those that one
+ otherwise CPU_MIPS32_R1 is a safe bet for any MIPS32 system.
+ Release 2 of the MIPS32 architecture is available since several
+ years so chances are you even have a MIPS32 Release 2 processor
+ in which case you should choose CPU_MIPS32_R2 instead for better
+ performance.
+
+config CPU_MIPS32_R2
+ bool "MIPS32 Release 2"
+ depends on SYS_HAS_CPU_MIPS32_R2
+ select CPU_HAS_PREFETCH
+ select CPU_SUPPORTS_32BIT_KERNEL
+ help
+ Choose this option to build a kernel for release 2 or later of the
+ MIPS32 architecture. Most modern embedded systems with a 32-bit
+ MIPS processor are based on a MIPS32 processor. If you know the
+ specific type of processor in your system, choose those that one
+ otherwise CPU_MIPS32_R1 is a safe bet for any MIPS32 system.
-config CPU_MIPS64
- bool "MIPS64"
+config CPU_MIPS64_R1
+ bool "MIPS64 Release 1"
+ depends on SYS_HAS_CPU_MIPS64_R1
+ select CPU_HAS_PREFETCH
select CPU_SUPPORTS_32BIT_KERNEL
select CPU_SUPPORTS_64BIT_KERNEL
+ help
+ Choose this option to build a kernel for release 1 or later of the
+ MIPS64 architecture. Many modern embedded systems with a 64-bit
+ MIPS processor are based on a MIPS64 processor. If you know the
+ specific type of processor in your system, choose those that one
+ otherwise CPU_MIPS64_R1 is a safe bet for any MIPS64 system.
+ Release 2 of the MIPS64 architecture is available since several
+ years so chances are you even have a MIPS64 Release 2 processor
+ in which case you should choose CPU_MIPS64_R2 instead for better
+ performance.
+
+config CPU_MIPS64_R2
+ bool "MIPS64 Release 2"
+ depends on SYS_HAS_CPU_MIPS64_R2
+ select CPU_HAS_PREFETCH
+ select CPU_SUPPORTS_32BIT_KERNEL
+ select CPU_SUPPORTS_64BIT_KERNEL
+ help
+ Choose this option to build a kernel for release 2 or later of the
+ MIPS64 architecture. Many modern embedded systems with a 64-bit
+ MIPS processor are based on a MIPS64 processor. If you know the
+ specific type of processor in your system, choose those that one
+ otherwise CPU_MIPS64_R1 is a safe bet for any MIPS64 system.
config CPU_R3000
bool "R3000"
+ depends on SYS_HAS_CPU_R3000
select CPU_SUPPORTS_32BIT_KERNEL
+ select CPU_SUPPORTS_HIGHMEM
help
Please make sure to pick the right CPU type. Linux/MIPS is not
designed to be generic, i.e. Kernels compiled for R3000 CPUs will
@@ -1259,20 +1122,23 @@ config CPU_R3000
config CPU_TX39XX
bool "R39XX"
+ depends on SYS_HAS_CPU_TX39XX
select CPU_SUPPORTS_32BIT_KERNEL
config CPU_VR41XX
bool "R41xx"
+ depends on SYS_HAS_CPU_VR41XX
select CPU_SUPPORTS_32BIT_KERNEL
select CPU_SUPPORTS_64BIT_KERNEL
help
- The options selects support for the NEC VR41xx series of processors.
+ The options selects support for the NEC VR4100 series of processors.
Only choose this option if you have one of these processors as a
kernel built with this option will not run on any other type of
processor or vice versa.
config CPU_R4300
bool "R4300"
+ depends on SYS_HAS_CPU_R4300
select CPU_SUPPORTS_32BIT_KERNEL
select CPU_SUPPORTS_64BIT_KERNEL
help
@@ -1280,6 +1146,7 @@ config CPU_R4300
config CPU_R4X00
bool "R4x00"
+ depends on SYS_HAS_CPU_R4X00
select CPU_SUPPORTS_32BIT_KERNEL
select CPU_SUPPORTS_64BIT_KERNEL
help
@@ -1288,11 +1155,13 @@ config CPU_R4X00
config CPU_TX49XX
bool "R49XX"
+ depends on SYS_HAS_CPU_TX49XX
select CPU_SUPPORTS_32BIT_KERNEL
select CPU_SUPPORTS_64BIT_KERNEL
config CPU_R5000
bool "R5000"
+ depends on SYS_HAS_CPU_R5000
select CPU_SUPPORTS_32BIT_KERNEL
select CPU_SUPPORTS_64BIT_KERNEL
help
@@ -1300,10 +1169,14 @@ config CPU_R5000
config CPU_R5432
bool "R5432"
+ depends on SYS_HAS_CPU_R5432
+ select CPU_SUPPORTS_32BIT_KERNEL
+ select CPU_SUPPORTS_64BIT_KERNEL
config CPU_R6000
bool "R6000"
depends on EXPERIMENTAL
+ depends on SYS_HAS_CPU_R6000
select CPU_SUPPORTS_32BIT_KERNEL
help
MIPS Technologies R6000 and R6000A series processors. Note these
@@ -1311,6 +1184,7 @@ config CPU_R6000
config CPU_NEVADA
bool "RM52xx"
+ depends on SYS_HAS_CPU_NEVADA
select CPU_SUPPORTS_32BIT_KERNEL
select CPU_SUPPORTS_64BIT_KERNEL
help
@@ -1319,6 +1193,8 @@ config CPU_NEVADA
config CPU_R8000
bool "R8000"
depends on EXPERIMENTAL
+ depends on SYS_HAS_CPU_R8000
+ select CPU_HAS_PREFETCH
select CPU_SUPPORTS_64BIT_KERNEL
help
MIPS Technologies R8000 processors. Note these processors are
@@ -1326,25 +1202,151 @@ config CPU_R8000
config CPU_R10000
bool "R10000"
+ depends on SYS_HAS_CPU_R10000
+ select CPU_HAS_PREFETCH
select CPU_SUPPORTS_32BIT_KERNEL
select CPU_SUPPORTS_64BIT_KERNEL
+ select CPU_SUPPORTS_HIGHMEM
help
MIPS Technologies R10000-series processors.
config CPU_RM7000
bool "RM7000"
+ depends on SYS_HAS_CPU_RM7000
+ select CPU_HAS_PREFETCH
select CPU_SUPPORTS_32BIT_KERNEL
select CPU_SUPPORTS_64BIT_KERNEL
+ select CPU_SUPPORTS_HIGHMEM
config CPU_RM9000
bool "RM9000"
+ depends on SYS_HAS_CPU_RM9000
+ select CPU_HAS_PREFETCH
select CPU_SUPPORTS_32BIT_KERNEL
select CPU_SUPPORTS_64BIT_KERNEL
+ select CPU_SUPPORTS_HIGHMEM
config CPU_SB1
bool "SB1"
+ depends on SYS_HAS_CPU_SB1
select CPU_SUPPORTS_32BIT_KERNEL
select CPU_SUPPORTS_64BIT_KERNEL
+ select CPU_SUPPORTS_HIGHMEM
+
+endchoice
+
+config SYS_HAS_CPU_MIPS32_R1
+ bool
+
+config SYS_HAS_CPU_MIPS32_R2
+ bool
+
+config SYS_HAS_CPU_MIPS64_R1
+ bool
+
+config SYS_HAS_CPU_MIPS64_R2
+ bool
+
+config SYS_HAS_CPU_R3000
+ bool
+
+config SYS_HAS_CPU_TX39XX
+ bool
+
+config SYS_HAS_CPU_VR41XX
+ bool
+
+config SYS_HAS_CPU_R4300
+ bool
+
+config SYS_HAS_CPU_R4X00
+ bool
+
+config SYS_HAS_CPU_TX49XX
+ bool
+
+config SYS_HAS_CPU_R5000
+ bool
+
+config SYS_HAS_CPU_R5432
+ bool
+
+config SYS_HAS_CPU_R6000
+ bool
+
+config SYS_HAS_CPU_NEVADA
+ bool
+
+config SYS_HAS_CPU_R8000
+ bool
+
+config SYS_HAS_CPU_R10000
+ bool
+
+config SYS_HAS_CPU_RM7000
+ bool
+
+config SYS_HAS_CPU_RM9000
+ bool
+
+config SYS_HAS_CPU_SB1
+ bool
+
+endmenu
+
+#
+# These two indicate any levelof the MIPS32 and MIPS64 architecture
+#
+config CPU_MIPS32
+ bool
+ default y if CPU_MIPS32_R1 || CPU_MIPS32_R2
+
+config CPU_MIPS64
+ bool
+ default y if CPU_MIPS64_R1 || CPU_MIPS64_R2
+
+#
+# These two indicate the revision of the architecture, either 32 bot 64 bit.
+#
+config CPU_MIPSR1
+ bool
+ default y if CPU_MIPS32_R1 || CPU_MIPS64_R1
+
+config CPU_MIPSR2
+ bool
+ default y if CPU_MIPS32_R2 || CPU_MIPS64_R2
+
+config SYS_SUPPORTS_32BIT_KERNEL
+ bool
+config SYS_SUPPORTS_64BIT_KERNEL
+ bool
+config CPU_SUPPORTS_32BIT_KERNEL
+ bool
+config CPU_SUPPORTS_64BIT_KERNEL
+ bool
+
+menu "Kernel type"
+
+choice
+
+ prompt "Kernel code model"
+ help
+ You should only select this option if you have a workload that
+ actually benefits from 64-bit processing or if your machine has
+ large memory. You will only be presented a single option in this
+ menu if your system does not support both 32-bit and 64-bit kernels.
+
+config 32BIT
+ bool "32-bit kernel"
+ depends on CPU_SUPPORTS_32BIT_KERNEL && SYS_SUPPORTS_32BIT_KERNEL
+ select TRAD_SIGNALS
+ help
+ Select this option if you want to build a 32-bit kernel.
+config 64BIT
+ bool "64-bit kernel"
+ depends on CPU_SUPPORTS_64BIT_KERNEL && SYS_SUPPORTS_64BIT_KERNEL
+ help
+ Select this option if you want to build a 64-bit kernel.
endchoice
@@ -1416,12 +1418,43 @@ config SIBYTE_DMA_PAGEOPS
SiByte Linux port. Seems to give a small performance benefit.
config CPU_HAS_PREFETCH
- bool "Enable prefetches" if CPU_SB1 && !CPU_SB1_PASS_2
- default y if CPU_MIPS32 || CPU_MIPS64 || CPU_RM7000 || CPU_RM9000 || CPU_R10000
+ bool
+
+config MIPS_MT
+ bool "Enable MIPS MT"
+
+choice
+ prompt "MIPS MT options"
+ depends on MIPS_MT
-config VTAG_ICACHE
- bool "Support for Virtual Tagged I-cache" if CPU_MIPS64 || CPU_MIPS32
- default y if CPU_SB1
+config MIPS_MT_SMP
+ bool "Use 1 TC on each available VPE for SMP"
+ select SMP
+
+config MIPS_VPE_LOADER
+ bool "VPE loader support."
+ depends on MIPS_MT
+ help
+ Includes a loader for loading an elf relocatable object
+ onto another VPE and running it.
+
+endchoice
+
+config MIPS_VPE_LOADER_TOM
+ bool "Load VPE program into memory hidden from linux"
+ depends on MIPS_VPE_LOADER
+ default y
+ help
+ The loader can use memory that is present but has been hidden from
+ Linux using the kernel command line option "mem=xxMB". It's up to
+ you to ensure the amount you put in the option and the space your
+ program requires is less or equal to the amount physically present.
+
+# this should possibly be in drivers/char, but it is rather cpu related. Hmmm
+config MIPS_VPE_APSP_API
+ bool "Enable support for AP/SP API (RTLX)"
+ depends on MIPS_VPE_LOADER
+ help
config SB1_PASS_1_WORKAROUNDS
bool
@@ -1440,7 +1473,7 @@ config SB1_PASS_2_1_WORKAROUNDS
config 64BIT_PHYS_ADDR
bool "Support for 64-bit physical address space"
- depends on (CPU_R4X00 || CPU_R5000 || CPU_RM7000 || CPU_RM9000 || CPU_R10000 || CPU_SB1 || CPU_MIPS32 || CPU_MIPS64) && 32BIT
+ depends on (CPU_R4X00 || CPU_R5000 || CPU_RM7000 || CPU_RM9000 || CPU_R10000 || CPU_SB1 || CPU_MIPS32_R1 || CPU_MIPS64_R1) && 32BIT
config CPU_ADVANCED
bool "Override CPU Options"
@@ -1463,7 +1496,7 @@ config CPU_HAS_LLSC
config CPU_HAS_LLDSCD
bool "lld/scd Instructions available" if CPU_ADVANCED
- default y if !CPU_ADVANCED && !CPU_R3000 && !CPU_VR41XX && !CPU_TX39XX && !CPU_MIPS32
+ default y if !CPU_ADVANCED && !CPU_R3000 && !CPU_VR41XX && !CPU_TX39XX && !CPU_MIPS32_R1
help
Say Y here if your CPU has the lld and scd instructions, the 64-bit
equivalents of ll and sc. Say Y here for better performance, N if
@@ -1477,12 +1510,52 @@ config CPU_HAS_WB
machines which require flushing of write buffers in software. Saying
Y is the safe option; N may result in kernel malfunction and crashes.
+menu "MIPSR2 Interrupt handling"
+ depends on CPU_MIPSR2 && CPU_ADVANCED
+
+config CPU_MIPSR2_IRQ_VI
+ bool "Vectored interrupt mode"
+ help
+ Vectored interrupt mode allowing faster dispatching of interrupts.
+ The board support code needs to be written to take advantage of this
+ mode. Compatibility code is included to allow the kernel to run on
+ a CPU that does not support vectored interrupts. It's safe to
+ say Y here.
+
+config CPU_MIPSR2_IRQ_EI
+ bool "External interrupt controller mode"
+ help
+ Extended interrupt mode takes advantage of an external interrupt
+ controller to allow fast dispatching from many possible interrupt
+ sources. Say N unless you know that external interrupt support is
+ required.
+
+config CPU_MIPSR2_SRS
+ bool "Make shadow set registers available for interrupt handlers"
+ depends on CPU_MIPSR2_IRQ_VI || CPU_MIPSR2_IRQ_EI
+ help
+ Allow the kernel to use shadow register sets for fast interrupts.
+ Interrupt handlers must be specially written to use shadow sets.
+ Say N unless you know that shadow register set upport is needed.
+endmenu
+
config CPU_HAS_SYNC
bool
depends on !CPU_R3000
default y
#
+# Use the generic interrupt handling code in kernel/irq/:
+#
+config GENERIC_HARDIRQS
+ bool
+ default y
+
+config GENERIC_IRQ_PROBE
+ bool
+ default y
+
+#
# - Highmem only makes sense for the 32-bit kernel.
# - The current highmem code will only work properly on physically indexed
# caches such as R3000, SB1, R7000 or those that look like they're virtually
@@ -1491,14 +1564,19 @@ config CPU_HAS_SYNC
# where it's known to be safe. This will not offer highmem on a few systems
# such as MIPS32 and MIPS64 CPUs which may have virtual and physically
# indexed CPUs but we're playing safe.
-# - We should not offer highmem for system of which we already know that they
-# don't have memory configurations that could gain from highmem support in
-# the kernel because they don't support configurations with RAM at physical
-# addresses > 0x20000000.
+# - We use SYS_SUPPORTS_HIGHMEM to offer highmem only for systems where we
+# know they might have memory configurations that could make use of highmem
+# support.
#
config HIGHMEM
bool "High Memory Support"
- depends on 32BIT && (CPU_R3000 || CPU_SB1 || CPU_R7000 || CPU_RM9000 || CPU_R10000) && !(MACH_DECSTATION || MOMENCO_JAGUAR_ATX)
+ depends on 32BIT && CPU_SUPPORTS_HIGHMEM && SYS_SUPPORTS_HIGHMEM
+
+config CPU_SUPPORTS_HIGHMEM
+ bool
+
+config SYS_SUPPORTS_HIGHMEM
+ bool
config ARCH_FLATMEM_ENABLE
def_bool y
@@ -1508,7 +1586,7 @@ source "mm/Kconfig"
config SMP
bool "Multi-Processing support"
- depends on CPU_RM9000 || (SIBYTE_SB1250 && !SIBYTE_STANDALONE) || SGI_IP27
+ depends on CPU_RM9000 || ((SIBYTE_BCM1x80 || SIBYTE_BCM1x55 || SIBYTE_SB1250) && !SIBYTE_STANDALONE) || SGI_IP27 || MIPS_MT_SMP
---help---
This enables support for systems with more than one CPU. If you have
a system with only one CPU, like most personal computers, say N. If
@@ -1543,14 +1621,7 @@ config NR_CPUS
This is purely to save memory - each supported CPU adds
approximately eight kilobytes to the kernel image.
-config PREEMPT
- bool "Preemptible Kernel"
- help
- This option reduces the latency of the kernel when reacting to
- real-time or interactive events by allowing a low priority process to
- be preempted even if it is in kernel mode executing a system call.
- This allows applications to run more reliably even when the system is
- under load.
+source "kernel/Kconfig.preempt"
config RTC_DS1742
bool "DS1742 BRAM/RTC support"
@@ -1566,14 +1637,16 @@ config MIPS_INSANE_LARGE
This will result in additional memory usage, so it is not
recommended for normal users.
+endmenu
+
config RWSEM_GENERIC_SPINLOCK
bool
default y
-endmenu
-
menu "Bus options (PCI, PCMCIA, EISA, ISA, TC)"
+config HW_HAS_EISA
+ bool
config HW_HAS_PCI
bool
@@ -1607,7 +1680,7 @@ config ISA
config EISA
bool "EISA support"
- depends on SGI_IP22 || SNI_RM200_PCI
+ depends on HW_HAS_EISA
select ISA
---help---
The Extended Industry Standard Architecture (EISA) bus was
@@ -1641,12 +1714,6 @@ config MMU
bool
default y
-config MCA
- bool
-
-config SBUS
- bool
-
source "drivers/pcmcia/Kconfig"
source "drivers/pci/hotplug/Kconfig"
@@ -1659,7 +1726,6 @@ source "fs/Kconfig.binfmt"
config TRAD_SIGNALS
bool
- default y if 32BIT
config BUILD_ELF64
bool "Use 64-bit ELF format for building"
@@ -1678,7 +1744,7 @@ config BUILD_ELF64
config BINFMT_IRIX
bool "Include IRIX binary compatibility"
- depends on !CPU_LITTLE_ENDIAN && 32BIT && BROKEN
+ depends on CPU_BIG_ENDIAN && 32BIT && BROKEN
config MIPS32_COMPAT
bool "Kernel support for Linux/MIPS 32-bit binary compatibility"
@@ -1718,9 +1784,26 @@ config BINFMT_ELF32
bool
default y if MIPS32_O32 || MIPS32_N32
+config SECCOMP
+ bool "Enable seccomp to safely compute untrusted bytecode"
+ depends on PROC_FS && BROKEN
+ 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. Only embedded should say N here.
+
config PM
bool "Power Management support (EXPERIMENTAL)"
- depends on EXPERIMENTAL && MACH_AU1X00
+ depends on EXPERIMENTAL && SOC_AU1X00
endmenu
@@ -1730,6 +1813,8 @@ source "drivers/Kconfig"
source "fs/Kconfig"
+source "arch/mips/oprofile/Kconfig"
+
source "arch/mips/Kconfig.debug"
source "security/Kconfig"
@@ -1737,18 +1822,3 @@ source "security/Kconfig"
source "crypto/Kconfig"
source "lib/Kconfig"
-
-#
-# Use the generic interrupt handling code in kernel/irq/:
-#
-config GENERIC_HARDIRQS
- bool
- default y
-
-config GENERIC_IRQ_PROBE
- bool
- default y
-
-config ISA_DMA_API
- bool
- default y
diff --git a/arch/mips/Makefile b/arch/mips/Makefile
index 346e803f153b..02692027730a 100644
--- a/arch/mips/Makefile
+++ b/arch/mips/Makefile
@@ -52,6 +52,21 @@ ifdef CONFIG_CROSSCOMPILE
CROSS_COMPILE := $(tool-prefix)
endif
+CHECKFLAGS-y += -D__linux__ -D__mips__ \
+ -D_ABIO32=1 \
+ -D_ABIN32=2 \
+ -D_ABI64=3
+CHECKFLAGS-$(CONFIG_32BIT) += -D_MIPS_SIM=_ABIO32 \
+ -D_MIPS_SZLONG=32 \
+ -D__PTRDIFF_TYPE__=int
+CHECKFLAGS-$(CONFIG_64BIT) += -m64 -D_MIPS_SIM=_ABI64 \
+ -D_MIPS_SZLONG=64 \
+ -D__PTRDIFF_TYPE__="long int"
+CHECKFLAGS-$(CONFIG_CPU_BIG_ENDIAN) += -D__MIPSEB__
+CHECKFLAGS-$(CONFIG_CPU_LITTLE_ENDIAN) += -D__MIPSEL__
+
+CHECKFLAGS = $(CHECKFLAGS-y)
+
ifdef CONFIG_BUILD_ELF64
gas-abi = 64
ld-emul = $(64bit-emul)
@@ -79,9 +94,18 @@ endif
cflags-y += -I $(TOPDIR)/include/asm/gcc
cflags-y += -G 0 -mno-abicalls -fno-pic -pipe
cflags-y += $(call cc-option, -finline-limit=100000)
-LDFLAGS_vmlinux += -G 0 -static -n
+LDFLAGS_vmlinux += -G 0 -static -n -nostdlib
MODFLAGS += -mlong-calls
+#
+# We explicitly add the endianness specifier if needed, this allows
+# to compile kernels with a toolchain for the other endianness. We
+# carefully avoid to add it redundantly because gcc 3.3/3.4 complains
+# when fed the toolchain default!
+#
+cflags-$(CONFIG_CPU_BIG_ENDIAN) += $(shell $(CC) -dumpmachine |grep -q 'mips.*el-.*' && echo -EB)
+cflags-$(CONFIG_CPU_LITTLE_ENDIAN) += $(shell $(CC) -dumpmachine |grep -q 'mips.*el-.*' || echo -EL)
+
cflags-$(CONFIG_SB1XXX_CORELIS) += -mno-sched-prolog -fno-omit-frame-pointer
#
@@ -167,14 +191,22 @@ cflags-$(CONFIG_CPU_TX49XX) += \
$(call set_gccflags,r4600,mips3,r4600,mips3,mips2) \
-Wa,--trap
-cflags-$(CONFIG_CPU_MIPS32) += \
+cflags-$(CONFIG_CPU_MIPS32_R1) += \
$(call set_gccflags,mips32,mips32,r4600,mips3,mips2) \
-Wa,--trap
-cflags-$(CONFIG_CPU_MIPS64) += \
+cflags-$(CONFIG_CPU_MIPS32_R2) += \
+ $(call set_gccflags,mips32r2,mips32r2,r4600,mips3,mips2) \
+ -Wa,--trap
+
+cflags-$(CONFIG_CPU_MIPS64_R1) += \
$(call set_gccflags,mips64,mips64,r4600,mips3,mips2) \
-Wa,--trap
+cflags-$(CONFIG_CPU_MIPS64_R2) += \
+ $(call set_gccflags,mips64r2,mips64r2,r4600,mips3,mips2) \
+ -Wa,--trap
+
cflags-$(CONFIG_CPU_R5000) += \
$(call set_gccflags,r5000,mips4,r5000,mips4,mips2) \
-Wa,--trap
@@ -196,6 +228,7 @@ cflags-$(CONFIG_CPU_RM9000) += \
$(call set_gccflags,rm9000,mips4,r5000,mips4,mips2) \
-Wa,--trap
+
cflags-$(CONFIG_CPU_SB1) += \
$(call set_gccflags,sb1,mips64,r5000,mips4,mips2) \
-Wa,--trap
@@ -266,6 +299,13 @@ cflags-$(CONFIG_MIPS_PB1550) += -Iinclude/asm-mips/mach-pb1x00
load-$(CONFIG_MIPS_PB1550) += 0xffffffff80100000
#
+# AMD Alchemy Pb1200 eval board
+#
+libs-$(CONFIG_MIPS_PB1200) += arch/mips/au1000/pb1200/
+cflags-$(CONFIG_MIPS_PB1200) += -Iinclude/asm-mips/mach-pb1x00
+load-$(CONFIG_MIPS_PB1200) += 0xffffffff80100000
+
+#
# AMD Alchemy Db1000 eval board
#
libs-$(CONFIG_MIPS_DB1000) += arch/mips/au1000/db1x00/
@@ -294,6 +334,13 @@ cflags-$(CONFIG_MIPS_DB1550) += -Iinclude/asm-mips/mach-db1x00
load-$(CONFIG_MIPS_DB1550) += 0xffffffff80100000
#
+# AMD Alchemy Db1200 eval board
+#
+libs-$(CONFIG_MIPS_DB1200) += arch/mips/au1000/pb1200/
+cflags-$(CONFIG_MIPS_DB1200) += -Iinclude/asm-mips/mach-db1x00
+load-$(CONFIG_MIPS_DB1200) += 0xffffffff80100000
+
+#
# AMD Alchemy Bosporus eval board
#
libs-$(CONFIG_MIPS_BOSPORUS) += arch/mips/au1000/db1x00/
@@ -323,6 +370,7 @@ load-$(CONFIG_MIPS_XXS1500) += 0xffffffff80100000
# Cobalt Server
#
core-$(CONFIG_MIPS_COBALT) += arch/mips/cobalt/
+cflags-$(CONFIG_MIPS_COBALT) += -Iinclude/asm-mips/cobalt
load-$(CONFIG_MIPS_COBALT) += 0xffffffff80080000
#
@@ -389,6 +437,13 @@ core-$(CONFIG_MIPS_SEAD) += arch/mips/mips-boards/sead/
load-$(CONFIG_MIPS_SEAD) += 0xffffffff80100000
#
+# MIPS SIM
+#
+core-$(CONFIG_MIPS_SIM) += arch/mips/mips-boards/sim/
+cflags-$(CONFIG_MIPS_SIM) += -Iinclude/asm-mips/mach-sim
+load-$(CONFIG_MIPS_SIM) += 0x80100000
+
+#
# Momentum Ocelot board
#
# The Ocelot setup.o must be linked early - it does the ioremap() for the
@@ -514,6 +569,19 @@ load-$(CONFIG_CASIO_E55) += 0xffffffff80004000
load-$(CONFIG_TANBAC_TB022X) += 0xffffffff80000000
#
+# Common Philips PNX8550
+#
+core-$(CONFIG_SOC_PNX8550) += arch/mips/philips/pnx8550/common/
+cflags-$(CONFIG_SOC_PNX8550) += -Iinclude/asm-mips/mach-pnx8550
+
+#
+# Philips PNX8550 JBS board
+#
+libs-$(CONFIG_PNX8550_JBS) += arch/mips/philips/pnx8550/jbs/
+#cflags-$(CONFIG_PNX8550_JBS) += -Iinclude/asm-mips/mach-pnx8550
+load-$(CONFIG_PNX8550_JBS) += 0xffffffff80060000
+
+#
# SGI IP22 (Indy/Indigo2)
#
# Set the load address to >= 0xffffffff88069000 if you want to leave space for
@@ -582,10 +650,20 @@ load-$(CONFIG_SGI_IP32) += 0xffffffff80004000
# removed (as happens, even if they have __initcall/module_init)
#
core-$(CONFIG_SIBYTE_BCM112X) += arch/mips/sibyte/sb1250/
-cflags-$(CONFIG_SIBYTE_BCM112X) += -Iinclude/asm-mips/mach-sibyte
+cflags-$(CONFIG_SIBYTE_BCM112X) += -Iinclude/asm-mips/mach-sibyte \
+ -DSIBYTE_HDR_FEATURES=SIBYTE_HDR_FMASK_1250_112x_ALL
core-$(CONFIG_SIBYTE_SB1250) += arch/mips/sibyte/sb1250/
-cflags-$(CONFIG_SIBYTE_SB1250) += -Iinclude/asm-mips/mach-sibyte
+cflags-$(CONFIG_SIBYTE_SB1250) += -Iinclude/asm-mips/mach-sibyte \
+ -DSIBYTE_HDR_FEATURES=SIBYTE_HDR_FMASK_1250_112x_ALL
+
+core-$(CONFIG_SIBYTE_BCM1x55) += arch/mips/sibyte/bcm1480/
+cflags-$(CONFIG_SIBYTE_BCM1x55) += -Iinclude/asm-mips/mach-sibyte \
+ -DSIBYTE_HDR_FEATURES=SIBYTE_HDR_FMASK_1480_ALL
+
+core-$(CONFIG_SIBYTE_BCM1x80) += arch/mips/sibyte/bcm1480/
+cflags-$(CONFIG_SIBYTE_BCM1x80) += -Iinclude/asm-mips/mach-sibyte \
+ -DSIBYTE_HDR_FEATURES=SIBYTE_HDR_FMASK_1480_ALL
#
# Sibyte BCM91120x (Carmel) board
@@ -593,6 +671,7 @@ cflags-$(CONFIG_SIBYTE_SB1250) += -Iinclude/asm-mips/mach-sibyte
# Sibyte BCM91125C (CRhone) board
# Sibyte BCM91125E (Rhone) board
# Sibyte SWARM board
+# Sibyte BCM91x80 (BigSur) board
#
libs-$(CONFIG_SIBYTE_CARMEL) += arch/mips/sibyte/swarm/
load-$(CONFIG_SIBYTE_CARMEL) := 0xffffffff80100000
@@ -606,6 +685,8 @@ libs-$(CONFIG_SIBYTE_SENTOSA) += arch/mips/sibyte/swarm/
load-$(CONFIG_SIBYTE_SENTOSA) := 0xffffffff80100000
libs-$(CONFIG_SIBYTE_SWARM) += arch/mips/sibyte/swarm/
load-$(CONFIG_SIBYTE_SWARM) := 0xffffffff80100000
+libs-$(CONFIG_SIBYTE_BIGSUR) += arch/mips/sibyte/swarm/
+load-$(CONFIG_SIBYTE_BIGSUR) := 0xffffffff80100000
#
# SNI RM200 PCI
@@ -629,6 +710,13 @@ core-$(CONFIG_TOSHIBA_RBTX4927) += arch/mips/tx4927/toshiba_rbtx4927/
core-$(CONFIG_TOSHIBA_RBTX4927) += arch/mips/tx4927/common/
load-$(CONFIG_TOSHIBA_RBTX4927) += 0xffffffff80020000
+#
+# Toshiba RBTX4938 board
+#
+core-$(CONFIG_TOSHIBA_RBTX4938) += arch/mips/tx4938/toshiba_rbtx4938/
+core-$(CONFIG_TOSHIBA_RBTX4938) += arch/mips/tx4938/common/
+load-$(CONFIG_TOSHIBA_RBTX4938) += 0xffffffff80100000
+
cflags-y += -Iinclude/asm-mips/mach-generic
drivers-$(CONFIG_PCI) += arch/mips/pci/
@@ -701,10 +789,29 @@ ifdef CONFIG_BOOT_ELF64
all: $(vmlinux-64)
endif
+ifdef CONFIG_MIPS_ATLAS
+all: vmlinux.srec
+endif
+
+ifdef CONFIG_MIPS_MALTA
+all: vmlinux.srec
+endif
+
+ifdef CONFIG_MIPS_SEAD
+all: vmlinux.srec
+endif
+
+ifdef CONFIG_QEMU
+all: vmlinux.bin
+endif
+
ifdef CONFIG_SNI_RM200_PCI
all: vmlinux.ecoff
endif
+vmlinux.bin: $(vmlinux-32)
+ +@$(call makeboot,$@)
+
vmlinux.ecoff vmlinux.rm200: $(vmlinux-32)
+@$(call makeboot,$@)
@@ -720,7 +827,6 @@ archclean:
@$(MAKE) $(clean)=arch/mips/boot
@$(MAKE) $(clean)=arch/mips/lasat
-
CLEAN_FILES += vmlinux.32 \
vmlinux.64 \
vmlinux.ecoff
diff --git a/arch/mips/arc/Makefile b/arch/mips/arc/Makefile
index e8424932e1a3..4f349ec1ea2d 100644
--- a/arch/mips/arc/Makefile
+++ b/arch/mips/arc/Makefile
@@ -3,7 +3,7 @@
#
lib-y += cmdline.o env.o file.o identify.o init.o \
- misc.o time.o tree.o
+ misc.o salone.o time.o tree.o
lib-$(CONFIG_ARC_MEMORY) += memory.o
lib-$(CONFIG_ARC_CONSOLE) += arc_con.o
diff --git a/arch/mips/arc/identify.c b/arch/mips/arc/identify.c
index 0dd7a345eb79..1bd6199e174a 100644
--- a/arch/mips/arc/identify.c
+++ b/arch/mips/arc/identify.c
@@ -44,6 +44,11 @@ static struct smatch mach_table[] = {
MACH_GROUP_SGI,
MACH_SGI_IP28,
PROM_FLAG_ARCS
+ }, { "SGI-IP30",
+ "SGI Octane",
+ MACH_GROUP_SGI,
+ MACH_SGI_IP30,
+ PROM_FLAG_ARCS
}, { "SGI-IP32",
"SGI O2",
MACH_GROUP_SGI,
diff --git a/arch/mips/au1000/common/Makefile b/arch/mips/au1000/common/Makefile
index 594b75e5e080..a1edfd1f643c 100644
--- a/arch/mips/au1000/common/Makefile
+++ b/arch/mips/au1000/common/Makefile
@@ -8,7 +8,7 @@
obj-y += prom.o int-handler.o irq.o puts.o time.o reset.o \
au1xxx_irqmap.o clocks.o platform.o power.o setup.o \
- sleeper.o cputable.o dma.o dbdma.o
+ sleeper.o cputable.o dma.o dbdma.o gpio.o
obj-$(CONFIG_AU1X00_USB_DEVICE) += usbdev.o
obj-$(CONFIG_KGDB) += dbg_io.o
diff --git a/arch/mips/au1000/common/au1xxx_irqmap.c b/arch/mips/au1000/common/au1xxx_irqmap.c
index 8a0f39f67c59..0b2c03c52319 100644
--- a/arch/mips/au1000/common/au1xxx_irqmap.c
+++ b/arch/mips/au1000/common/au1xxx_irqmap.c
@@ -173,14 +173,14 @@ au1xxx_irq_map_t au1xxx_ic0_map[] = {
{ AU1550_PSC1_INT, INTC_INT_HIGH_LEVEL, 0},
{ AU1550_PSC2_INT, INTC_INT_HIGH_LEVEL, 0},
{ AU1550_PSC3_INT, INTC_INT_HIGH_LEVEL, 0},
- { AU1550_TOY_INT, INTC_INT_RISE_EDGE, 0 },
- { AU1550_TOY_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
- { AU1550_TOY_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
- { AU1550_TOY_MATCH2_INT, INTC_INT_RISE_EDGE, 1 },
- { AU1550_RTC_INT, INTC_INT_RISE_EDGE, 0 },
- { AU1550_RTC_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
- { AU1550_RTC_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
- { AU1550_RTC_MATCH2_INT, INTC_INT_RISE_EDGE, 0 },
+ { AU1000_TOY_INT, INTC_INT_RISE_EDGE, 0 },
+ { AU1000_TOY_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
+ { AU1000_TOY_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
+ { AU1000_TOY_MATCH2_INT, INTC_INT_RISE_EDGE, 1 },
+ { AU1000_RTC_INT, INTC_INT_RISE_EDGE, 0 },
+ { AU1000_RTC_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
+ { AU1000_RTC_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
+ { AU1000_RTC_MATCH2_INT, INTC_INT_RISE_EDGE, 0 },
{ AU1550_NAND_INT, INTC_INT_RISE_EDGE, 0},
{ AU1550_USB_DEV_REQ_INT, INTC_INT_HIGH_LEVEL, 0 },
{ AU1550_USB_DEV_SUS_INT, INTC_INT_RISE_EDGE, 0 },
@@ -201,14 +201,14 @@ au1xxx_irq_map_t au1xxx_ic0_map[] = {
{ AU1200_PSC1_INT, INTC_INT_HIGH_LEVEL, 0},
{ AU1200_AES_INT, INTC_INT_HIGH_LEVEL, 0},
{ AU1200_CAMERA_INT, INTC_INT_HIGH_LEVEL, 0},
- { AU1200_TOY_INT, INTC_INT_RISE_EDGE, 0 },
- { AU1200_TOY_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
- { AU1200_TOY_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
- { AU1200_TOY_MATCH2_INT, INTC_INT_RISE_EDGE, 1 },
- { AU1200_RTC_INT, INTC_INT_RISE_EDGE, 0 },
- { AU1200_RTC_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
- { AU1200_RTC_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
- { AU1200_RTC_MATCH2_INT, INTC_INT_RISE_EDGE, 0 },
+ { AU1000_TOY_INT, INTC_INT_RISE_EDGE, 0 },
+ { AU1000_TOY_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
+ { AU1000_TOY_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
+ { AU1000_TOY_MATCH2_INT, INTC_INT_RISE_EDGE, 1 },
+ { AU1000_RTC_INT, INTC_INT_RISE_EDGE, 0 },
+ { AU1000_RTC_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
+ { AU1000_RTC_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
+ { AU1000_RTC_MATCH2_INT, INTC_INT_RISE_EDGE, 0 },
{ AU1200_NAND_INT, INTC_INT_RISE_EDGE, 0},
{ AU1200_USB_INT, INTC_INT_HIGH_LEVEL, 0 },
{ AU1200_LCD_INT, INTC_INT_HIGH_LEVEL, 0},
diff --git a/arch/mips/au1000/common/cputable.c b/arch/mips/au1000/common/cputable.c
index f5521dfccfd6..4dbde82c8215 100644
--- a/arch/mips/au1000/common/cputable.c
+++ b/arch/mips/au1000/common/cputable.c
@@ -37,7 +37,8 @@ struct cpu_spec cpu_specs[] = {
{ 0xffffffff, 0x02030203, "Au1100 BD", 0, 1 },
{ 0xffffffff, 0x02030204, "Au1100 BE", 0, 1 },
{ 0xffffffff, 0x03030200, "Au1550 AA", 0, 1 },
- { 0xffffffff, 0x04030200, "Au1200 AA", 0, 1 },
+ { 0xffffffff, 0x04030200, "Au1200 AB", 0, 0 },
+ { 0xffffffff, 0x04030201, "Au1200 AC", 0, 1 },
{ 0x00000000, 0x00000000, "Unknown Au1xxx", 1, 0 },
};
diff --git a/arch/mips/au1000/common/dbdma.c b/arch/mips/au1000/common/dbdma.c
index adfc3172aace..d00e8247d6c2 100644
--- a/arch/mips/au1000/common/dbdma.c
+++ b/arch/mips/au1000/common/dbdma.c
@@ -29,6 +29,7 @@
* 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
+
#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/errno.h>
@@ -38,10 +39,12 @@
#include <linux/string.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
+#include <linux/module.h>
#include <asm/mach-au1x00/au1000.h>
#include <asm/mach-au1x00/au1xxx_dbdma.h>
#include <asm/system.h>
+
#if defined(CONFIG_SOC_AU1550) || defined(CONFIG_SOC_AU1200)
/*
@@ -61,37 +64,10 @@ static DEFINE_SPINLOCK(au1xxx_dbdma_spin_lock);
*/
#define ALIGN_ADDR(x, a) ((((u32)(x)) + (a-1)) & ~(a-1))
-static volatile dbdma_global_t *dbdma_gptr = (dbdma_global_t *)DDMA_GLOBAL_BASE;
-static int dbdma_initialized;
+static dbdma_global_t *dbdma_gptr = (dbdma_global_t *)DDMA_GLOBAL_BASE;
+static int dbdma_initialized=0;
static void au1xxx_dbdma_init(void);
-typedef struct dbdma_device_table {
- u32 dev_id;
- u32 dev_flags;
- u32 dev_tsize;
- u32 dev_devwidth;
- u32 dev_physaddr; /* If FIFO */
- u32 dev_intlevel;
- u32 dev_intpolarity;
-} dbdev_tab_t;
-
-typedef struct dbdma_chan_config {
- u32 chan_flags;
- u32 chan_index;
- dbdev_tab_t *chan_src;
- dbdev_tab_t *chan_dest;
- au1x_dma_chan_t *chan_ptr;
- au1x_ddma_desc_t *chan_desc_base;
- au1x_ddma_desc_t *get_ptr, *put_ptr, *cur_ptr;
- void *chan_callparam;
- void (*chan_callback)(int, void *, struct pt_regs *);
-} chan_tab_t;
-
-#define DEV_FLAGS_INUSE (1 << 0)
-#define DEV_FLAGS_ANYUSE (1 << 1)
-#define DEV_FLAGS_OUT (1 << 2)
-#define DEV_FLAGS_IN (1 << 3)
-
static dbdev_tab_t dbdev_tab[] = {
#ifdef CONFIG_SOC_AU1550
/* UARTS */
@@ -157,25 +133,25 @@ static dbdev_tab_t dbdev_tab[] = {
{ DSCR_CMD0_MAE_BOTH, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 },
{ DSCR_CMD0_LCD, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 },
- { DSCR_CMD0_SDMS_TX0, DEV_FLAGS_OUT, 0, 0, 0x00000000, 0, 0 },
- { DSCR_CMD0_SDMS_RX0, DEV_FLAGS_IN, 0, 0, 0x00000000, 0, 0 },
- { DSCR_CMD0_SDMS_TX1, DEV_FLAGS_OUT, 0, 0, 0x00000000, 0, 0 },
- { DSCR_CMD0_SDMS_RX1, DEV_FLAGS_IN, 0, 0, 0x00000000, 0, 0 },
+ { DSCR_CMD0_SDMS_TX0, DEV_FLAGS_OUT, 4, 8, 0x10600000, 0, 0 },
+ { DSCR_CMD0_SDMS_RX0, DEV_FLAGS_IN, 4, 8, 0x10600004, 0, 0 },
+ { DSCR_CMD0_SDMS_TX1, DEV_FLAGS_OUT, 4, 8, 0x10680000, 0, 0 },
+ { DSCR_CMD0_SDMS_RX1, DEV_FLAGS_IN, 4, 8, 0x10680004, 0, 0 },
- { DSCR_CMD0_AES_TX, DEV_FLAGS_OUT, 0, 0, 0x00000000, 0, 0 },
- { DSCR_CMD0_AES_RX, DEV_FLAGS_IN, 0, 0, 0x00000000, 0, 0 },
+ { DSCR_CMD0_AES_RX, DEV_FLAGS_IN , 4, 32, 0x10300008, 0, 0 },
+ { DSCR_CMD0_AES_TX, DEV_FLAGS_OUT, 4, 32, 0x10300004, 0, 0 },
- { DSCR_CMD0_PSC0_TX, DEV_FLAGS_OUT, 0, 0, 0x11a0001c, 0, 0 },
- { DSCR_CMD0_PSC0_RX, DEV_FLAGS_IN, 0, 0, 0x11a0001c, 0, 0 },
+ { DSCR_CMD0_PSC0_TX, DEV_FLAGS_OUT, 0, 16, 0x11a0001c, 0, 0 },
+ { DSCR_CMD0_PSC0_RX, DEV_FLAGS_IN, 0, 16, 0x11a0001c, 0, 0 },
{ DSCR_CMD0_PSC0_SYNC, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 },
- { DSCR_CMD0_PSC1_TX, DEV_FLAGS_OUT, 0, 0, 0x11b0001c, 0, 0 },
- { DSCR_CMD0_PSC1_RX, DEV_FLAGS_IN, 0, 0, 0x11b0001c, 0, 0 },
+ { DSCR_CMD0_PSC1_TX, DEV_FLAGS_OUT, 0, 16, 0x11b0001c, 0, 0 },
+ { DSCR_CMD0_PSC1_RX, DEV_FLAGS_IN, 0, 16, 0x11b0001c, 0, 0 },
{ DSCR_CMD0_PSC1_SYNC, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 },
- { DSCR_CMD0_CIM_RXA, DEV_FLAGS_IN, 0, 0, 0x00000000, 0, 0 },
- { DSCR_CMD0_CIM_RXB, DEV_FLAGS_IN, 0, 0, 0x00000000, 0, 0 },
- { DSCR_CMD0_CIM_RXC, DEV_FLAGS_IN, 0, 0, 0x00000000, 0, 0 },
+ { DSCR_CMD0_CIM_RXA, DEV_FLAGS_IN, 0, 32, 0x14004020, 0, 0 },
+ { DSCR_CMD0_CIM_RXB, DEV_FLAGS_IN, 0, 32, 0x14004040, 0, 0 },
+ { DSCR_CMD0_CIM_RXC, DEV_FLAGS_IN, 0, 32, 0x14004060, 0, 0 },
{ DSCR_CMD0_CIM_SYNC, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 },
{ DSCR_CMD0_NAND_FLASH, DEV_FLAGS_IN, 0, 0, 0x00000000, 0, 0 },
@@ -184,6 +160,24 @@ static dbdev_tab_t dbdev_tab[] = {
{ DSCR_CMD0_THROTTLE, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 },
{ DSCR_CMD0_ALWAYS, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 },
+
+ /* Provide 16 user definable device types */
+ { 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 },
+ { 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 },
+ { 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 },
};
#define DBDEV_TAB_SIZE (sizeof(dbdev_tab) / sizeof(dbdev_tab_t))
@@ -203,6 +197,36 @@ find_dbdev_id (u32 id)
return NULL;
}
+void * au1xxx_ddma_get_nextptr_virt(au1x_ddma_desc_t *dp)
+{
+ return phys_to_virt(DSCR_GET_NXTPTR(dp->dscr_nxtptr));
+}
+EXPORT_SYMBOL(au1xxx_ddma_get_nextptr_virt);
+
+u32
+au1xxx_ddma_add_device(dbdev_tab_t *dev)
+{
+ u32 ret = 0;
+ dbdev_tab_t *p=NULL;
+ static u16 new_id=0x1000;
+
+ p = find_dbdev_id(0);
+ if ( NULL != p )
+ {
+ memcpy(p, dev, sizeof(dbdev_tab_t));
+ p->dev_id = DSCR_DEV2CUSTOM_ID(new_id,dev->dev_id);
+ ret = p->dev_id;
+ new_id++;
+#if 0
+ printk("add_device: id:%x flags:%x padd:%x\n",
+ p->dev_id, p->dev_flags, p->dev_physaddr );
+#endif
+ }
+
+ return ret;
+}
+EXPORT_SYMBOL(au1xxx_ddma_add_device);
+
/* Allocate a channel and return a non-zero descriptor if successful.
*/
u32
@@ -215,7 +239,7 @@ au1xxx_dbdma_chan_alloc(u32 srcid, u32 destid,
int i;
dbdev_tab_t *stp, *dtp;
chan_tab_t *ctp;
- volatile au1x_dma_chan_t *cp;
+ au1x_dma_chan_t *cp;
/* We do the intialization on the first channel allocation.
* We have to wait because of the interrupt handler initialization
@@ -225,9 +249,6 @@ au1xxx_dbdma_chan_alloc(u32 srcid, u32 destid,
au1xxx_dbdma_init();
dbdma_initialized = 1;
- if ((srcid > DSCR_NDEV_IDS) || (destid > DSCR_NDEV_IDS))
- return 0;
-
if ((stp = find_dbdev_id(srcid)) == NULL) return 0;
if ((dtp = find_dbdev_id(destid)) == NULL) return 0;
@@ -271,7 +292,6 @@ au1xxx_dbdma_chan_alloc(u32 srcid, u32 destid,
*/
ctp = kmalloc(sizeof(chan_tab_t), GFP_KERNEL);
chan_tab_ptr[i] = ctp;
- ctp->chan_index = chan = i;
break;
}
}
@@ -279,10 +299,11 @@ au1xxx_dbdma_chan_alloc(u32 srcid, u32 destid,
if (ctp != NULL) {
memset(ctp, 0, sizeof(chan_tab_t));
+ ctp->chan_index = chan = i;
dcp = DDMA_CHANNEL_BASE;
dcp += (0x0100 * chan);
ctp->chan_ptr = (au1x_dma_chan_t *)dcp;
- cp = (volatile au1x_dma_chan_t *)dcp;
+ cp = (au1x_dma_chan_t *)dcp;
ctp->chan_src = stp;
ctp->chan_dest = dtp;
ctp->chan_callback = callback;
@@ -299,6 +320,9 @@ au1xxx_dbdma_chan_alloc(u32 srcid, u32 destid,
i |= DDMA_CFG_DED;
if (dtp->dev_intpolarity)
i |= DDMA_CFG_DP;
+ if ((stp->dev_flags & DEV_FLAGS_SYNC) ||
+ (dtp->dev_flags & DEV_FLAGS_SYNC))
+ i |= DDMA_CFG_SYNC;
cp->ddma_cfg = i;
au_sync();
@@ -309,14 +333,14 @@ au1xxx_dbdma_chan_alloc(u32 srcid, u32 destid,
rv = (u32)(&chan_tab_ptr[chan]);
}
else {
- /* Release devices.
- */
+ /* Release devices */
stp->dev_flags &= ~DEV_FLAGS_INUSE;
dtp->dev_flags &= ~DEV_FLAGS_INUSE;
}
}
return rv;
}
+EXPORT_SYMBOL(au1xxx_dbdma_chan_alloc);
/* Set the device width if source or destination is a FIFO.
* Should be 8, 16, or 32 bits.
@@ -344,6 +368,7 @@ au1xxx_dbdma_set_devwidth(u32 chanid, int bits)
return rv;
}
+EXPORT_SYMBOL(au1xxx_dbdma_set_devwidth);
/* Allocate a descriptor ring, initializing as much as possible.
*/
@@ -370,7 +395,8 @@ au1xxx_dbdma_ring_alloc(u32 chanid, int entries)
* and if we try that first we are likely to not waste larger
* slabs of memory.
*/
- desc_base = (u32)kmalloc(entries * sizeof(au1x_ddma_desc_t), GFP_KERNEL);
+ desc_base = (u32)kmalloc(entries * sizeof(au1x_ddma_desc_t),
+ GFP_KERNEL|GFP_DMA);
if (desc_base == 0)
return 0;
@@ -381,7 +407,7 @@ au1xxx_dbdma_ring_alloc(u32 chanid, int entries)
kfree((const void *)desc_base);
i = entries * sizeof(au1x_ddma_desc_t);
i += (sizeof(au1x_ddma_desc_t) - 1);
- if ((desc_base = (u32)kmalloc(i, GFP_KERNEL)) == 0)
+ if ((desc_base = (u32)kmalloc(i, GFP_KERNEL|GFP_DMA)) == 0)
return 0;
desc_base = ALIGN_ADDR(desc_base, sizeof(au1x_ddma_desc_t));
@@ -403,7 +429,13 @@ au1xxx_dbdma_ring_alloc(u32 chanid, int entries)
cmd0 |= DSCR_CMD0_SID(srcid);
cmd0 |= DSCR_CMD0_DID(destid);
cmd0 |= DSCR_CMD0_IE | DSCR_CMD0_CV;
- cmd0 |= DSCR_CMD0_ST(DSCR_CMD0_ST_CURRENT);
+ cmd0 |= DSCR_CMD0_ST(DSCR_CMD0_ST_NOCHANGE);
+
+ /* is it mem to mem transfer? */
+ if(((DSCR_CUSTOM2DEV_ID(srcid) == DSCR_CMD0_THROTTLE) || (DSCR_CUSTOM2DEV_ID(srcid) == DSCR_CMD0_ALWAYS)) &&
+ ((DSCR_CUSTOM2DEV_ID(destid) == DSCR_CMD0_THROTTLE) || (DSCR_CUSTOM2DEV_ID(destid) == DSCR_CMD0_ALWAYS))) {
+ cmd0 |= DSCR_CMD0_MEM;
+ }
switch (stp->dev_devwidth) {
case 8:
@@ -461,9 +493,14 @@ au1xxx_dbdma_ring_alloc(u32 chanid, int entries)
/* If source input is fifo, set static address.
*/
if (stp->dev_flags & DEV_FLAGS_IN) {
- src0 = stp->dev_physaddr;
+ if ( stp->dev_flags & DEV_FLAGS_BURSTABLE )
+ src1 |= DSCR_SRC1_SAM(DSCR_xAM_BURST);
+ else
src1 |= DSCR_SRC1_SAM(DSCR_xAM_STATIC);
+
}
+ if (stp->dev_physaddr)
+ src0 = stp->dev_physaddr;
/* Set up dest1. For now, assume no stride and increment.
* A channel attribute update can change this later.
@@ -487,10 +524,18 @@ au1xxx_dbdma_ring_alloc(u32 chanid, int entries)
/* If destination output is fifo, set static address.
*/
if (dtp->dev_flags & DEV_FLAGS_OUT) {
- dest0 = dtp->dev_physaddr;
+ if ( dtp->dev_flags & DEV_FLAGS_BURSTABLE )
+ dest1 |= DSCR_DEST1_DAM(DSCR_xAM_BURST);
+ else
dest1 |= DSCR_DEST1_DAM(DSCR_xAM_STATIC);
}
+ if (dtp->dev_physaddr)
+ dest0 = dtp->dev_physaddr;
+#if 0
+ printk("did:%x sid:%x cmd0:%x cmd1:%x source0:%x source1:%x dest0:%x dest1:%x\n",
+ dtp->dev_id, stp->dev_id, cmd0, cmd1, src0, src1, dest0, dest1 );
+#endif
for (i=0; i<entries; i++) {
dp->dscr_cmd0 = cmd0;
dp->dscr_cmd1 = cmd1;
@@ -499,6 +544,8 @@ au1xxx_dbdma_ring_alloc(u32 chanid, int entries)
dp->dscr_dest0 = dest0;
dp->dscr_dest1 = dest1;
dp->dscr_stat = 0;
+ dp->sw_context = 0;
+ dp->sw_status = 0;
dp->dscr_nxtptr = DSCR_NXTPTR(virt_to_phys(dp + 1));
dp++;
}
@@ -511,13 +558,14 @@ au1xxx_dbdma_ring_alloc(u32 chanid, int entries)
return (u32)(ctp->chan_desc_base);
}
+EXPORT_SYMBOL(au1xxx_dbdma_ring_alloc);
/* Put a source buffer into the DMA ring.
* This updates the source pointer and byte count. Normally used
* for memory to fifo transfers.
*/
u32
-au1xxx_dbdma_put_source(u32 chanid, void *buf, int nbytes)
+_au1xxx_dbdma_put_source(u32 chanid, void *buf, int nbytes, u32 flags)
{
chan_tab_t *ctp;
au1x_ddma_desc_t *dp;
@@ -544,8 +592,24 @@ au1xxx_dbdma_put_source(u32 chanid, void *buf, int nbytes)
*/
dp->dscr_source0 = virt_to_phys(buf);
dp->dscr_cmd1 = nbytes;
- dp->dscr_cmd0 |= DSCR_CMD0_V; /* Let it rip */
- ctp->chan_ptr->ddma_dbell = 0xffffffff; /* Make it go */
+ /* Check flags */
+ if (flags & DDMA_FLAGS_IE)
+ dp->dscr_cmd0 |= DSCR_CMD0_IE;
+ if (flags & DDMA_FLAGS_NOIE)
+ dp->dscr_cmd0 &= ~DSCR_CMD0_IE;
+
+ /*
+ * There is an errata on the Au1200/Au1550 parts that could result
+ * in "stale" data being DMA'd. It has to do with the snoop logic on
+ * the dache eviction buffer. NONCOHERENT_IO is on by default for
+ * these parts. If it is fixedin the future, these dma_cache_inv will
+ * just be nothing more than empty macros. See io.h.
+ * */
+ dma_cache_wback_inv((unsigned long)buf, nbytes);
+ dp->dscr_cmd0 |= DSCR_CMD0_V; /* Let it rip */
+ au_sync();
+ dma_cache_wback_inv((unsigned long)dp, sizeof(dp));
+ ctp->chan_ptr->ddma_dbell = 0;
/* Get next descriptor pointer.
*/
@@ -555,13 +619,14 @@ au1xxx_dbdma_put_source(u32 chanid, void *buf, int nbytes)
*/
return nbytes;
}
+EXPORT_SYMBOL(_au1xxx_dbdma_put_source);
/* Put a destination buffer into the DMA ring.
* This updates the destination pointer and byte count. Normally used
* to place an empty buffer into the ring for fifo to memory transfers.
*/
u32
-au1xxx_dbdma_put_dest(u32 chanid, void *buf, int nbytes)
+_au1xxx_dbdma_put_dest(u32 chanid, void *buf, int nbytes, u32 flags)
{
chan_tab_t *ctp;
au1x_ddma_desc_t *dp;
@@ -583,11 +648,33 @@ au1xxx_dbdma_put_dest(u32 chanid, void *buf, int nbytes)
if (dp->dscr_cmd0 & DSCR_CMD0_V)
return 0;
- /* Load up buffer address and byte count.
- */
+ /* Load up buffer address and byte count */
+
+ /* Check flags */
+ if (flags & DDMA_FLAGS_IE)
+ dp->dscr_cmd0 |= DSCR_CMD0_IE;
+ if (flags & DDMA_FLAGS_NOIE)
+ dp->dscr_cmd0 &= ~DSCR_CMD0_IE;
+
dp->dscr_dest0 = virt_to_phys(buf);
dp->dscr_cmd1 = nbytes;
+#if 0
+ printk("cmd0:%x cmd1:%x source0:%x source1:%x dest0:%x dest1:%x\n",
+ dp->dscr_cmd0, dp->dscr_cmd1, dp->dscr_source0,
+ dp->dscr_source1, dp->dscr_dest0, dp->dscr_dest1 );
+#endif
+ /*
+ * There is an errata on the Au1200/Au1550 parts that could result in
+ * "stale" data being DMA'd. It has to do with the snoop logic on the
+ * dache eviction buffer. NONCOHERENT_IO is on by default for these
+ * parts. If it is fixedin the future, these dma_cache_inv will just
+ * be nothing more than empty macros. See io.h.
+ * */
+ dma_cache_inv((unsigned long)buf,nbytes);
dp->dscr_cmd0 |= DSCR_CMD0_V; /* Let it rip */
+ au_sync();
+ dma_cache_wback_inv((unsigned long)dp, sizeof(dp));
+ ctp->chan_ptr->ddma_dbell = 0;
/* Get next descriptor pointer.
*/
@@ -597,6 +684,7 @@ au1xxx_dbdma_put_dest(u32 chanid, void *buf, int nbytes)
*/
return nbytes;
}
+EXPORT_SYMBOL(_au1xxx_dbdma_put_dest);
/* Get a destination buffer into the DMA ring.
* Normally used to get a full buffer from the ring during fifo
@@ -646,7 +734,7 @@ void
au1xxx_dbdma_stop(u32 chanid)
{
chan_tab_t *ctp;
- volatile au1x_dma_chan_t *cp;
+ au1x_dma_chan_t *cp;
int halt_timeout = 0;
ctp = *((chan_tab_t **)chanid);
@@ -666,6 +754,7 @@ au1xxx_dbdma_stop(u32 chanid)
cp->ddma_stat |= (DDMA_STAT_DB | DDMA_STAT_V);
au_sync();
}
+EXPORT_SYMBOL(au1xxx_dbdma_stop);
/* Start using the current descriptor pointer. If the dbdma encounters
* a not valid descriptor, it will stop. In this case, we can just
@@ -675,17 +764,17 @@ void
au1xxx_dbdma_start(u32 chanid)
{
chan_tab_t *ctp;
- volatile au1x_dma_chan_t *cp;
+ au1x_dma_chan_t *cp;
ctp = *((chan_tab_t **)chanid);
-
cp = ctp->chan_ptr;
cp->ddma_desptr = virt_to_phys(ctp->cur_ptr);
cp->ddma_cfg |= DDMA_CFG_EN; /* Enable channel */
au_sync();
- cp->ddma_dbell = 0xffffffff; /* Make it go */
+ cp->ddma_dbell = 0;
au_sync();
}
+EXPORT_SYMBOL(au1xxx_dbdma_start);
void
au1xxx_dbdma_reset(u32 chanid)
@@ -704,15 +793,21 @@ au1xxx_dbdma_reset(u32 chanid)
do {
dp->dscr_cmd0 &= ~DSCR_CMD0_V;
+ /* reset our SW status -- this is used to determine
+ * if a descriptor is in use by upper level SW. Since
+ * posting can reset 'V' bit.
+ */
+ dp->sw_status = 0;
dp = phys_to_virt(DSCR_GET_NXTPTR(dp->dscr_nxtptr));
} while (dp != ctp->chan_desc_base);
}
+EXPORT_SYMBOL(au1xxx_dbdma_reset);
u32
au1xxx_get_dma_residue(u32 chanid)
{
chan_tab_t *ctp;
- volatile au1x_dma_chan_t *cp;
+ au1x_dma_chan_t *cp;
u32 rv;
ctp = *((chan_tab_t **)chanid);
@@ -738,8 +833,7 @@ au1xxx_dbdma_chan_free(u32 chanid)
au1xxx_dbdma_stop(chanid);
- if (ctp->chan_desc_base != NULL)
- kfree(ctp->chan_desc_base);
+ kfree((void *)ctp->chan_desc_base);
stp->dev_flags &= ~DEV_FLAGS_INUSE;
dtp->dev_flags &= ~DEV_FLAGS_INUSE;
@@ -747,15 +841,16 @@ au1xxx_dbdma_chan_free(u32 chanid)
kfree(ctp);
}
+EXPORT_SYMBOL(au1xxx_dbdma_chan_free);
static irqreturn_t
dbdma_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
- u32 intstat;
- u32 chan_index;
+ u32 intstat;
+ u32 chan_index;
chan_tab_t *ctp;
au1x_ddma_desc_t *dp;
- volatile au1x_dma_chan_t *cp;
+ au1x_dma_chan_t *cp;
intstat = dbdma_gptr->ddma_intstat;
au_sync();
@@ -774,19 +869,27 @@ dbdma_interrupt(int irq, void *dev_id, struct pt_regs *regs)
(ctp->chan_callback)(irq, ctp->chan_callparam, regs);
ctp->cur_ptr = phys_to_virt(DSCR_GET_NXTPTR(dp->dscr_nxtptr));
-
- return IRQ_HANDLED;
+ return IRQ_RETVAL(1);
}
-static void
-au1xxx_dbdma_init(void)
+static void au1xxx_dbdma_init(void)
{
+ int irq_nr;
+
dbdma_gptr->ddma_config = 0;
dbdma_gptr->ddma_throttle = 0;
dbdma_gptr->ddma_inten = 0xffff;
au_sync();
- if (request_irq(AU1550_DDMA_INT, dbdma_interrupt, SA_INTERRUPT,
+#if defined(CONFIG_SOC_AU1550)
+ irq_nr = AU1550_DDMA_INT;
+#elif defined(CONFIG_SOC_AU1200)
+ irq_nr = AU1200_DDMA_INT;
+#else
+ #error Unknown Au1x00 SOC
+#endif
+
+ if (request_irq(irq_nr, dbdma_interrupt, SA_INTERRUPT,
"Au1xxx dbdma", (void *)dbdma_gptr))
printk("Can't get 1550 dbdma irq");
}
@@ -797,7 +900,8 @@ au1xxx_dbdma_dump(u32 chanid)
chan_tab_t *ctp;
au1x_ddma_desc_t *dp;
dbdev_tab_t *stp, *dtp;
- volatile au1x_dma_chan_t *cp;
+ au1x_dma_chan_t *cp;
+ u32 i = 0;
ctp = *((chan_tab_t **)chanid);
stp = ctp->chan_src;
@@ -822,15 +926,64 @@ au1xxx_dbdma_dump(u32 chanid)
dp = ctp->chan_desc_base;
do {
- printk("dp %08x, cmd0 %08x, cmd1 %08x\n",
- (u32)dp, dp->dscr_cmd0, dp->dscr_cmd1);
- printk("src0 %08x, src1 %08x, dest0 %08x\n",
- dp->dscr_source0, dp->dscr_source1, dp->dscr_dest0);
- printk("dest1 %08x, stat %08x, nxtptr %08x\n",
- dp->dscr_dest1, dp->dscr_stat, dp->dscr_nxtptr);
+ printk("Dp[%d]= %08x, cmd0 %08x, cmd1 %08x\n",
+ i++, (u32)dp, dp->dscr_cmd0, dp->dscr_cmd1);
+ printk("src0 %08x, src1 %08x, dest0 %08x, dest1 %08x\n",
+ dp->dscr_source0, dp->dscr_source1, dp->dscr_dest0, dp->dscr_dest1);
+ printk("stat %08x, nxtptr %08x\n",
+ dp->dscr_stat, dp->dscr_nxtptr);
dp = phys_to_virt(DSCR_GET_NXTPTR(dp->dscr_nxtptr));
} while (dp != ctp->chan_desc_base);
}
+/* Put a descriptor into the DMA ring.
+ * This updates the source/destination pointers and byte count.
+ */
+u32
+au1xxx_dbdma_put_dscr(u32 chanid, au1x_ddma_desc_t *dscr )
+{
+ chan_tab_t *ctp;
+ au1x_ddma_desc_t *dp;
+ u32 nbytes=0;
+
+ /* I guess we could check this to be within the
+ * range of the table......
+ */
+ ctp = *((chan_tab_t **)chanid);
+
+ /* We should have multiple callers for a particular channel,
+ * an interrupt doesn't affect this pointer nor the descriptor,
+ * so no locking should be needed.
+ */
+ dp = ctp->put_ptr;
+
+ /* If the descriptor is valid, we are way ahead of the DMA
+ * engine, so just return an error condition.
+ */
+ if (dp->dscr_cmd0 & DSCR_CMD0_V)
+ return 0;
+
+ /* Load up buffer addresses and byte count.
+ */
+ dp->dscr_dest0 = dscr->dscr_dest0;
+ dp->dscr_source0 = dscr->dscr_source0;
+ dp->dscr_dest1 = dscr->dscr_dest1;
+ dp->dscr_source1 = dscr->dscr_source1;
+ dp->dscr_cmd1 = dscr->dscr_cmd1;
+ nbytes = dscr->dscr_cmd1;
+ /* Allow the caller to specifiy if an interrupt is generated */
+ dp->dscr_cmd0 &= ~DSCR_CMD0_IE;
+ dp->dscr_cmd0 |= dscr->dscr_cmd0 | DSCR_CMD0_V;
+ ctp->chan_ptr->ddma_dbell = 0;
+
+ /* Get next descriptor pointer.
+ */
+ ctp->put_ptr = phys_to_virt(DSCR_GET_NXTPTR(dp->dscr_nxtptr));
+
+ /* return something not zero.
+ */
+ return nbytes;
+}
+
#endif /* defined(CONFIG_SOC_AU1550) || defined(CONFIG_SOC_AU1200) */
diff --git a/arch/mips/au1000/common/dma.c b/arch/mips/au1000/common/dma.c
index 372c33f1353d..1905c6b104f2 100644
--- a/arch/mips/au1000/common/dma.c
+++ b/arch/mips/au1000/common/dma.c
@@ -39,7 +39,6 @@
#include <linux/string.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
-#include <linux/module.h>
#include <asm/system.h>
#include <asm/mach-au1x00/au1000.h>
#include <asm/mach-au1x00/au1000_dma.h>
diff --git a/arch/mips/au1000/common/gpio.c b/arch/mips/au1000/common/gpio.c
new file mode 100644
index 000000000000..5f5915b83142
--- /dev/null
+++ b/arch/mips/au1000/common/gpio.c
@@ -0,0 +1,119 @@
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/config.h>
+#include <linux/module.h>
+#include <au1000.h>
+#include <au1xxx_gpio.h>
+
+#define gpio1 sys
+#if !defined(CONFIG_SOC_AU1000)
+static AU1X00_GPIO2 * const gpio2 = (AU1X00_GPIO2 *)GPIO2_BASE;
+
+#define GPIO2_OUTPUT_ENABLE_MASK 0x00010000
+
+int au1xxx_gpio2_read(int signal)
+{
+ signal -= 200;
+/* gpio2->dir &= ~(0x01 << signal); //Set GPIO to input */
+ return ((gpio2->pinstate >> signal) & 0x01);
+}
+
+void au1xxx_gpio2_write(int signal, int value)
+{
+ signal -= 200;
+
+ gpio2->output = (GPIO2_OUTPUT_ENABLE_MASK << signal) |
+ (value << signal);
+}
+
+void au1xxx_gpio2_tristate(int signal)
+{
+ signal -= 200;
+ gpio2->dir &= ~(0x01 << signal); /* Set GPIO to input */
+}
+#endif
+
+int au1xxx_gpio1_read(int signal)
+{
+/* gpio1->trioutclr |= (0x01 << signal); */
+ return ((gpio1->pinstaterd >> signal) & 0x01);
+}
+
+void au1xxx_gpio1_write(int signal, int value)
+{
+ if(value)
+ gpio1->outputset = (0x01 << signal);
+ else
+ gpio1->outputclr = (0x01 << signal); /* Output a Zero */
+}
+
+void au1xxx_gpio1_tristate(int signal)
+{
+ gpio1->trioutclr = (0x01 << signal); /* Tristate signal */
+}
+
+
+int au1xxx_gpio_read(int signal)
+{
+ if(signal >= 200)
+#if defined(CONFIG_SOC_AU1000)
+ return 0;
+#else
+ return au1xxx_gpio2_read(signal);
+#endif
+ else
+ return au1xxx_gpio1_read(signal);
+}
+
+void au1xxx_gpio_write(int signal, int value)
+{
+ if(signal >= 200)
+#if defined(CONFIG_SOC_AU1000)
+ ;
+#else
+ au1xxx_gpio2_write(signal, value);
+#endif
+ else
+ au1xxx_gpio1_write(signal, value);
+}
+
+void au1xxx_gpio_tristate(int signal)
+{
+ if(signal >= 200)
+#if defined(CONFIG_SOC_AU1000)
+ ;
+#else
+ au1xxx_gpio2_tristate(signal);
+#endif
+ else
+ au1xxx_gpio1_tristate(signal);
+}
+
+void au1xxx_gpio1_set_inputs(void)
+{
+ gpio1->pininputen = 0;
+}
+
+EXPORT_SYMBOL(au1xxx_gpio1_set_inputs);
+EXPORT_SYMBOL(au1xxx_gpio_tristate);
+EXPORT_SYMBOL(au1xxx_gpio_write);
+EXPORT_SYMBOL(au1xxx_gpio_read);
diff --git a/arch/mips/au1000/common/irq.c b/arch/mips/au1000/common/irq.c
index d1eb5a4a9a19..1339a0979f66 100644
--- a/arch/mips/au1000/common/irq.c
+++ b/arch/mips/au1000/common/irq.c
@@ -83,7 +83,7 @@ inline void local_disable_irq(unsigned int irq_nr);
void (*board_init_irq)(void);
#ifdef CONFIG_PM
-extern void counter0_irq(int irq, void *dev_id, struct pt_regs *regs);
+extern irqreturn_t counter0_irq(int irq, void *dev_id, struct pt_regs *regs);
#endif
static DEFINE_SPINLOCK(irq_lock);
@@ -253,52 +253,72 @@ void restore_local_and_enable(int controller, unsigned long mask)
static struct hw_interrupt_type rise_edge_irq_type = {
- "Au1000 Rise Edge",
- startup_irq,
- shutdown_irq,
- local_enable_irq,
- local_disable_irq,
- mask_and_ack_rise_edge_irq,
- end_irq,
- NULL
+ .typename = "Au1000 Rise Edge",
+ .startup = startup_irq,
+ .shutdown = shutdown_irq,
+ .enable = local_enable_irq,
+ .disable = local_disable_irq,
+ .ack = mask_and_ack_rise_edge_irq,
+ .end = end_irq,
};
static struct hw_interrupt_type fall_edge_irq_type = {
- "Au1000 Fall Edge",
- startup_irq,
- shutdown_irq,
- local_enable_irq,
- local_disable_irq,
- mask_and_ack_fall_edge_irq,
- end_irq,
- NULL
+ .typename = "Au1000 Fall Edge",
+ .startup = startup_irq,
+ .shutdown = shutdown_irq,
+ .enable = local_enable_irq,
+ .disable = local_disable_irq,
+ .ack = mask_and_ack_fall_edge_irq,
+ .end = end_irq,
};
static struct hw_interrupt_type either_edge_irq_type = {
- "Au1000 Rise or Fall Edge",
- startup_irq,
- shutdown_irq,
- local_enable_irq,
- local_disable_irq,
- mask_and_ack_either_edge_irq,
- end_irq,
- NULL
+ .typename = "Au1000 Rise or Fall Edge",
+ .startup = startup_irq,
+ .shutdown = shutdown_irq,
+ .enable = local_enable_irq,
+ .disable = local_disable_irq,
+ .ack = mask_and_ack_either_edge_irq,
+ .end = end_irq,
};
static struct hw_interrupt_type level_irq_type = {
- "Au1000 Level",
- startup_irq,
- shutdown_irq,
- local_enable_irq,
- local_disable_irq,
- mask_and_ack_level_irq,
- end_irq,
- NULL
+ .typename = "Au1000 Level",
+ .startup = startup_irq,
+ .shutdown = shutdown_irq,
+ .enable = local_enable_irq,
+ .disable = local_disable_irq,
+ .ack = mask_and_ack_level_irq,
+ .end = end_irq,
};
#ifdef CONFIG_PM
-void startup_match20_interrupt(void)
+void startup_match20_interrupt(irqreturn_t (*handler)(int, void *, struct pt_regs *))
{
+ struct irq_desc *desc = &irq_desc[AU1000_TOY_MATCH2_INT];
+
+ static struct irqaction action;
+ memset(&action, 0, sizeof(struct irqaction));
+
+ /* This is a big problem.... since we didn't use request_irq
+ * when kernel/irq.c calls probe_irq_xxx this interrupt will
+ * be probed for usage. This will end up disabling the device :(
+ * Give it a bogus "action" pointer -- this will keep it from
+ * getting auto-probed!
+ *
+ * By setting the status to match that of request_irq() we
+ * can avoid it. --cgray
+ */
+ action.dev_id = handler;
+ action.flags = SA_INTERRUPT;
+ cpus_clear(action.mask);
+ action.name = "Au1xxx TOY";
+ action.handler = handler;
+ action.next = NULL;
+
+ desc->action = &action;
+ desc->status &= ~(IRQ_DISABLED | IRQ_AUTODETECT | IRQ_WAITING | IRQ_INPROGRESS);
+
local_enable_irq(AU1000_TOY_MATCH2_INT);
}
#endif
@@ -426,7 +446,6 @@ void __init arch_init_irq(void)
extern int au1xxx_ic0_nr_irqs;
cp0_status = read_c0_status();
- memset(irq_desc, 0, sizeof(irq_desc));
set_except_vector(0, au1000_IRQ);
/* Initialize interrupt controllers to a safe state.
@@ -492,7 +511,7 @@ void intc0_req0_irqdispatch(struct pt_regs *regs)
intc0_req0 |= au_readl(IC0_REQ0INT);
if (!intc0_req0) return;
-
+#ifdef AU1000_USB_DEV_REQ_INT
/*
* Because of the tight timing of SETUP token to reply
* transactions, the USB devices-side packet complete
@@ -503,7 +522,7 @@ void intc0_req0_irqdispatch(struct pt_regs *regs)
do_IRQ(AU1000_USB_DEV_REQ_INT, regs);
return;
}
-
+#endif
irq = au_ffs(intc0_req0) - 1;
intc0_req0 &= ~(1<<irq);
do_IRQ(irq, regs);
@@ -521,17 +540,7 @@ void intc0_req1_irqdispatch(struct pt_regs *regs)
irq = au_ffs(intc0_req1) - 1;
intc0_req1 &= ~(1<<irq);
-#ifdef CONFIG_PM
- if (irq == AU1000_TOY_MATCH2_INT) {
- mask_and_ack_rise_edge_irq(irq);
- counter0_irq(irq, NULL, regs);
- local_enable_irq(irq);
- }
- else
-#endif
- {
- do_IRQ(irq, regs);
- }
+ do_IRQ(irq, regs);
}
diff --git a/arch/mips/au1000/common/platform.c b/arch/mips/au1000/common/platform.c
index 0776b2db5641..48d3f54f88f8 100644
--- a/arch/mips/au1000/common/platform.c
+++ b/arch/mips/au1000/common/platform.c
@@ -7,13 +7,16 @@
* License version 2. This program is licensed "as is" without any
* warranty of any kind, whether express or implied.
*/
+#include <linux/config.h>
#include <linux/device.h>
+#include <linux/platform_device.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/resource.h>
-#include <asm/mach-au1x00/au1000.h>
+#include <asm/mach-au1x00/au1xxx.h>
+/* OHCI (USB full speed host controller) */
static struct resource au1xxx_usb_ohci_resources[] = {
[0] = {
.start = USB_OHCI_BASE,
@@ -41,8 +44,252 @@ static struct platform_device au1xxx_usb_ohci_device = {
.resource = au1xxx_usb_ohci_resources,
};
+/*** AU1100 LCD controller ***/
+
+#ifdef CONFIG_FB_AU1100
+static struct resource au1100_lcd_resources[] = {
+ [0] = {
+ .start = LCD_PHYS_ADDR,
+ .end = LCD_PHYS_ADDR + 0x800 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AU1100_LCD_INT,
+ .end = AU1100_LCD_INT,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+static u64 au1100_lcd_dmamask = ~(u32)0;
+
+static struct platform_device au1100_lcd_device = {
+ .name = "au1100-lcd",
+ .id = 0,
+ .dev = {
+ .dma_mask = &au1100_lcd_dmamask,
+ .coherent_dma_mask = 0xffffffff,
+ },
+ .num_resources = ARRAY_SIZE(au1100_lcd_resources),
+ .resource = au1100_lcd_resources,
+};
+#endif
+
+#ifdef CONFIG_SOC_AU1200
+/* EHCI (USB high speed host controller) */
+static struct resource au1xxx_usb_ehci_resources[] = {
+ [0] = {
+ .start = USB_EHCI_BASE,
+ .end = USB_EHCI_BASE + USB_EHCI_LEN - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AU1000_USB_HOST_INT,
+ .end = AU1000_USB_HOST_INT,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static u64 ehci_dmamask = ~(u32)0;
+
+static struct platform_device au1xxx_usb_ehci_device = {
+ .name = "au1xxx-ehci",
+ .id = 0,
+ .dev = {
+ .dma_mask = &ehci_dmamask,
+ .coherent_dma_mask = 0xffffffff,
+ },
+ .num_resources = ARRAY_SIZE(au1xxx_usb_ehci_resources),
+ .resource = au1xxx_usb_ehci_resources,
+};
+
+/* Au1200 UDC (USB gadget controller) */
+static struct resource au1xxx_usb_gdt_resources[] = {
+ [0] = {
+ .start = USB_UDC_BASE,
+ .end = USB_UDC_BASE + USB_UDC_LEN - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AU1200_USB_INT,
+ .end = AU1200_USB_INT,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct resource au1xxx_mmc_resources[] = {
+ [0] = {
+ .start = SD0_PHYS_ADDR,
+ .end = SD0_PHYS_ADDR + 0x40,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = SD1_PHYS_ADDR,
+ .end = SD1_PHYS_ADDR + 0x40,
+ .flags = IORESOURCE_MEM,
+ },
+ [2] = {
+ .start = AU1200_SD_INT,
+ .end = AU1200_SD_INT,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+static u64 udc_dmamask = ~(u32)0;
+
+static struct platform_device au1xxx_usb_gdt_device = {
+ .name = "au1xxx-udc",
+ .id = 0,
+ .dev = {
+ .dma_mask = &udc_dmamask,
+ .coherent_dma_mask = 0xffffffff,
+ },
+ .num_resources = ARRAY_SIZE(au1xxx_usb_gdt_resources),
+ .resource = au1xxx_usb_gdt_resources,
+};
+
+/* Au1200 UOC (USB OTG controller) */
+static struct resource au1xxx_usb_otg_resources[] = {
+ [0] = {
+ .start = USB_UOC_BASE,
+ .end = USB_UOC_BASE + USB_UOC_LEN - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AU1200_USB_INT,
+ .end = AU1200_USB_INT,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static u64 uoc_dmamask = ~(u32)0;
+
+static struct platform_device au1xxx_usb_otg_device = {
+ .name = "au1xxx-uoc",
+ .id = 0,
+ .dev = {
+ .dma_mask = &uoc_dmamask,
+ .coherent_dma_mask = 0xffffffff,
+ },
+ .num_resources = ARRAY_SIZE(au1xxx_usb_otg_resources),
+ .resource = au1xxx_usb_otg_resources,
+};
+
+static struct resource au1200_lcd_resources[] = {
+ [0] = {
+ .start = LCD_PHYS_ADDR,
+ .end = LCD_PHYS_ADDR + 0x800 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AU1200_LCD_INT,
+ .end = AU1200_LCD_INT,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+static struct resource au1200_ide0_resources[] = {
+ [0] = {
+ .start = AU1XXX_ATA_PHYS_ADDR,
+ .end = AU1XXX_ATA_PHYS_ADDR + AU1XXX_ATA_PHYS_LEN,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AU1XXX_ATA_INT,
+ .end = AU1XXX_ATA_INT,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+static u64 au1200_lcd_dmamask = ~(u32)0;
+
+static struct platform_device au1200_lcd_device = {
+ .name = "au1200-lcd",
+ .id = 0,
+ .dev = {
+ .dma_mask = &au1200_lcd_dmamask,
+ .coherent_dma_mask = 0xffffffff,
+ },
+ .num_resources = ARRAY_SIZE(au1200_lcd_resources),
+ .resource = au1200_lcd_resources,
+};
+
+
+static u64 ide0_dmamask = ~(u32)0;
+
+static struct platform_device au1200_ide0_device = {
+ .name = "au1200-ide",
+ .id = 0,
+ .dev = {
+ .dma_mask = &ide0_dmamask,
+ .coherent_dma_mask = 0xffffffff,
+ },
+ .num_resources = ARRAY_SIZE(au1200_ide0_resources),
+ .resource = au1200_ide0_resources,
+};
+
+static u64 au1xxx_mmc_dmamask = ~(u32)0;
+
+static struct platform_device au1xxx_mmc_device = {
+ .name = "au1xxx-mmc",
+ .id = 0,
+ .dev = {
+ .dma_mask = &au1xxx_mmc_dmamask,
+ .coherent_dma_mask = 0xffffffff,
+ },
+ .num_resources = ARRAY_SIZE(au1xxx_mmc_resources),
+ .resource = au1xxx_mmc_resources,
+};
+#endif /* #ifdef CONFIG_SOC_AU1200 */
+
+static struct platform_device au1x00_pcmcia_device = {
+ .name = "au1x00-pcmcia",
+ .id = 0,
+};
+
+#ifdef CONFIG_MIPS_DB1200
+
+static struct resource smc91x_resources[] = {
+ [0] = {
+ .name = "smc91x-regs",
+ .start = AU1XXX_SMC91111_PHYS_ADDR,
+ .end = AU1XXX_SMC91111_PHYS_ADDR + 0xfffff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AU1XXX_SMC91111_IRQ,
+ .end = AU1XXX_SMC91111_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device smc91x_device = {
+ .name = "smc91x",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(smc91x_resources),
+ .resource = smc91x_resources,
+};
+
+#endif
+
static struct platform_device *au1xxx_platform_devices[] __initdata = {
&au1xxx_usb_ohci_device,
+ &au1x00_pcmcia_device,
+#ifdef CONFIG_FB_AU1100
+ &au1100_lcd_device,
+#endif
+#ifdef CONFIG_SOC_AU1200
+#if 0 /* fixme */
+ &au1xxx_usb_ehci_device,
+#endif
+ &au1xxx_usb_gdt_device,
+ &au1xxx_usb_otg_device,
+ &au1200_lcd_device,
+ &au1200_ide0_device,
+ &au1xxx_mmc_device,
+#endif
+#ifdef CONFIG_MIPS_DB1200
+ &smc91x_device,
+#endif
};
int au1xxx_platform_init(void)
diff --git a/arch/mips/au1000/common/power.c b/arch/mips/au1000/common/power.c
index c40daccbb5b1..f85093b8d54d 100644
--- a/arch/mips/au1000/common/power.c
+++ b/arch/mips/au1000/common/power.c
@@ -34,11 +34,13 @@
#include <linux/pm.h>
#include <linux/slab.h>
#include <linux/sysctl.h>
+#include <linux/jiffies.h>
#include <asm/string.h>
#include <asm/uaccess.h>
#include <asm/io.h>
#include <asm/system.h>
+#include <asm/cacheflush.h>
#include <asm/mach-au1x00/au1000.h>
#ifdef CONFIG_PM
@@ -50,7 +52,7 @@
# define DPRINTK(fmt, args...)
#endif
-static void calibrate_delay(void);
+static void au1000_calibrate_delay(void);
extern void set_au1x00_speed(unsigned int new_freq);
extern unsigned int get_au1x00_speed(void);
@@ -260,7 +262,7 @@ int au_sleep(void)
}
static int pm_do_sleep(ctl_table * ctl, int write, struct file *file,
- void *buffer, size_t * len)
+ void __user *buffer, size_t * len, loff_t *ppos)
{
int retval = 0;
#ifdef SLEEP_TEST_TIMEOUT
@@ -294,10 +296,9 @@ static int pm_do_sleep(ctl_table * ctl, int write, struct file *file,
}
static int pm_do_suspend(ctl_table * ctl, int write, struct file *file,
- void *buffer, size_t * len)
+ void __user *buffer, size_t * len, loff_t *ppos)
{
int retval = 0;
- void au1k_wait(void);
if (!write) {
*len = 0;
@@ -306,7 +307,7 @@ static int pm_do_suspend(ctl_table * ctl, int write, struct file *file,
if (retval)
return retval;
suspend_mode = 1;
- au1k_wait();
+
retval = pm_send_all(PM_RESUME, (void *) 0);
}
return retval;
@@ -314,7 +315,7 @@ static int pm_do_suspend(ctl_table * ctl, int write, struct file *file,
static int pm_do_freq(ctl_table * ctl, int write, struct file *file,
- void *buffer, size_t * len)
+ void __user *buffer, size_t * len, loff_t *ppos)
{
int retval = 0, i;
unsigned long val, pll;
@@ -409,14 +410,14 @@ static int pm_do_freq(ctl_table * ctl, int write, struct file *file,
/* We don't want _any_ interrupts other than
- * match20. Otherwise our calibrate_delay()
+ * match20. Otherwise our au1000_calibrate_delay()
* calculation will be off, potentially a lot.
*/
intc0_mask = save_local_and_disable(0);
intc1_mask = save_local_and_disable(1);
local_enable_irq(AU1000_TOY_MATCH2_INT);
spin_unlock_irqrestore(&pm_lock, flags);
- calibrate_delay();
+ au1000_calibrate_delay();
restore_local_and_enable(0, intc0_mask);
restore_local_and_enable(1, intc1_mask);
return retval;
@@ -456,7 +457,7 @@ __initcall(pm_init);
better than 1% */
#define LPS_PREC 8
-static void calibrate_delay(void)
+static void au1000_calibrate_delay(void)
{
unsigned long ticks, loopbit;
int lps_precision = LPS_PREC;
diff --git a/arch/mips/au1000/common/prom.c b/arch/mips/au1000/common/prom.c
index 22e5a85af4d5..9c171afd9a53 100644
--- a/arch/mips/au1000/common/prom.c
+++ b/arch/mips/au1000/common/prom.c
@@ -75,7 +75,8 @@ void prom_init_cmdline(void)
}
if (cp != &(arcs_cmdline[0])) /* get rid of trailing space */
--cp;
- *cp = '\0';
+ if (prom_argc > 1)
+ *cp = '\0';
}
diff --git a/arch/mips/au1000/common/puts.c b/arch/mips/au1000/common/puts.c
index c2ae4624b77b..2705829cd466 100644
--- a/arch/mips/au1000/common/puts.c
+++ b/arch/mips/au1000/common/puts.c
@@ -39,7 +39,6 @@
#define TIMEOUT 0xffffff
#define SLOW_DOWN
-static const char digits[16] = "0123456789abcdef";
static volatile unsigned long * const com1 = (unsigned long *)SERIAL_BASE;
@@ -54,7 +53,7 @@ static inline void slow_down(void)
#endif
void
-putch(const unsigned char c)
+prom_putchar(const unsigned char c)
{
unsigned char ch;
int i = 0;
@@ -69,77 +68,3 @@ putch(const unsigned char c)
} while (0 == (ch & TX_BUSY));
com1[SER_DATA] = c;
}
-
-void
-puts(unsigned char *cp)
-{
- unsigned char ch;
- int i = 0;
-
- while (*cp) {
- do {
- ch = com1[SER_CMD];
- slow_down();
- i++;
- if (i>TIMEOUT) {
- break;
- }
- } while (0 == (ch & TX_BUSY));
- com1[SER_DATA] = *cp++;
- }
- putch('\r');
- putch('\n');
-}
-
-void
-fputs(const char *cp)
-{
- unsigned char ch;
- int i = 0;
-
- while (*cp) {
-
- do {
- ch = com1[SER_CMD];
- slow_down();
- i++;
- if (i>TIMEOUT) {
- break;
- }
- } while (0 == (ch & TX_BUSY));
- com1[SER_DATA] = *cp++;
- }
-}
-
-
-void
-put64(uint64_t ul)
-{
- int cnt;
- unsigned ch;
-
- cnt = 16; /* 16 nibbles in a 64 bit long */
- putch('0');
- putch('x');
- do {
- cnt--;
- ch = (unsigned char)(ul >> cnt * 4) & 0x0F;
- putch(digits[ch]);
- } while (cnt > 0);
-}
-
-void
-put32(unsigned u)
-{
- int cnt;
- unsigned ch;
-
- cnt = 8; /* 8 nibbles in a 32 bit long */
- putch('0');
- putch('x');
- do {
- cnt--;
- ch = (unsigned char)(u >> cnt * 4) & 0x0F;
- putch(digits[ch]);
- } while (cnt > 0);
-}
diff --git a/arch/mips/au1000/common/setup.c b/arch/mips/au1000/common/setup.c
index eff89e109ce6..4f21f42d096b 100644
--- a/arch/mips/au1000/common/setup.c
+++ b/arch/mips/au1000/common/setup.c
@@ -32,6 +32,7 @@
#include <linux/mm.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
+#include <linux/module.h>
#include <asm/cpu.h>
#include <asm/bootinfo.h>
@@ -57,7 +58,7 @@ extern void au1xxx_time_init(void);
extern void au1xxx_timer_setup(struct irqaction *irq);
extern void set_cpuspec(void);
-static int __init au1x00_setup(void)
+void __init plat_setup(void)
{
struct cpu_spec *sp;
char *argptr;
@@ -106,23 +107,10 @@ static int __init au1x00_setup(void)
/*strcat(argptr, " video=au1100fb:panel:Sharp_320x240_16");*/
#ifdef CONFIG_MIPS_HYDROGEN3
strcat(argptr, " video=au1100fb:panel:Hydrogen_3_NEC_panel_320x240,nohwcursor");
-#else
- strcat(argptr, " video=au1100fb:panel:s10,nohwcursor");
#endif
}
#endif
-#ifdef CONFIG_FB_E1356
- if ((argptr = strstr(argptr, "video=")) == NULL) {
- argptr = prom_getcmdline();
-#ifdef CONFIG_MIPS_PB1000
- strcat(argptr, " video=e1356fb:system:pb1000,mmunalign:1");
-#else
- strcat(argptr, " video=e1356fb:system:pb1500");
-#endif
- }
-#endif
-
#ifdef CONFIG_FB_XPERT98
if ((argptr = strstr(argptr, "video=")) == NULL) {
argptr = prom_getcmdline();
@@ -153,15 +141,11 @@ static int __init au1x00_setup(void)
au_sync();
while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_T0S);
au_writel(0, SYS_TOYTRIM);
-
- return 0;
}
-early_initcall(au1x00_setup);
-
#if defined(CONFIG_64BIT_PHYS_ADDR)
/* This routine should be valid for all Au1x based boards */
-phys_t fixup_bigphys_addr(phys_t phys_addr, phys_t size)
+phys_t __fixup_bigphys_addr(phys_t phys_addr, phys_t size)
{
u32 start, end;
@@ -192,4 +176,5 @@ phys_t fixup_bigphys_addr(phys_t phys_addr, phys_t size)
/* default nop */
return phys_addr;
}
+EXPORT_SYMBOL(__fixup_bigphys_addr);
#endif
diff --git a/arch/mips/au1000/common/time.c b/arch/mips/au1000/common/time.c
index 57675b41480e..883d3f3d8c53 100644
--- a/arch/mips/au1000/common/time.c
+++ b/arch/mips/au1000/common/time.c
@@ -50,7 +50,6 @@
#include <linux/mc146818rtc.h>
#include <linux/timex.h>
-extern void startup_match20_interrupt(void);
extern void do_softirq(void);
extern volatile unsigned long wall_jiffies;
unsigned long missed_heart_beats = 0;
@@ -58,14 +57,17 @@ unsigned long missed_heart_beats = 0;
static unsigned long r4k_offset; /* Amount to increment compare reg each time */
static unsigned long r4k_cur; /* What counter should be at next timer irq */
int no_au1xxx_32khz;
-void (*au1k_wait_ptr)(void);
+extern int allow_au1k_wait; /* default off for CP0 Counter */
/* Cycle counter value at the previous timer interrupt.. */
static unsigned int timerhi = 0, timerlo = 0;
#ifdef CONFIG_PM
-#define MATCH20_INC 328
-extern void startup_match20_interrupt(void);
+#if HZ < 100 || HZ > 1000
+#error "unsupported HZ value! Must be in [100,1000]"
+#endif
+#define MATCH20_INC (328*100/HZ) /* magic number 328 is for HZ=100... */
+extern void startup_match20_interrupt(irqreturn_t (*handler)(int, void *, struct pt_regs *));
static unsigned long last_pc0, last_match20;
#endif
@@ -117,17 +119,16 @@ null:
}
#ifdef CONFIG_PM
-void counter0_irq(int irq, void *dev_id, struct pt_regs *regs)
+irqreturn_t counter0_irq(int irq, void *dev_id, struct pt_regs *regs)
{
unsigned long pc0;
int time_elapsed;
static int jiffie_drift = 0;
- kstat.irqs[0][irq]++;
if (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20) {
/* should never happen! */
- printk(KERN_WARNING "counter 0 w status eror\n");
- return;
+ printk(KERN_WARNING "counter 0 w status error\n");
+ return IRQ_NONE;
}
pc0 = au_readl(SYS_TOYREAD);
@@ -164,6 +165,8 @@ void counter0_irq(int irq, void *dev_id, struct pt_regs *regs)
update_process_times(user_mode(regs));
#endif
}
+
+ return IRQ_HANDLED;
}
/* When we wakeup from sleep, we have to "catch up" on all of the
@@ -388,7 +391,6 @@ void au1xxx_timer_setup(struct irqaction *irq)
{
unsigned int est_freq;
extern unsigned long (*do_gettimeoffset)(void);
- extern void au1k_wait(void);
printk("calculating r4koff... ");
r4k_offset = cal_r4koff();
@@ -441,18 +443,18 @@ void au1xxx_timer_setup(struct irqaction *irq)
au_sync();
while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20);
- /* setup match20 to interrupt once every 10ms */
+ /* setup match20 to interrupt once every HZ */
last_pc0 = last_match20 = au_readl(SYS_TOYREAD);
au_writel(last_match20 + MATCH20_INC, SYS_TOYMATCH2);
au_sync();
while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20);
- startup_match20_interrupt();
+ startup_match20_interrupt(counter0_irq);
do_gettimeoffset = do_fast_pm_gettimeoffset;
/* We can use the real 'wait' instruction.
*/
- au1k_wait_ptr = au1k_wait;
+ allow_au1k_wait = 1;
}
#else
diff --git a/arch/mips/au1000/common/usbdev.c b/arch/mips/au1000/common/usbdev.c
index 447a9a4612a8..0b21bed7ee55 100644
--- a/arch/mips/au1000/common/usbdev.c
+++ b/arch/mips/au1000/common/usbdev.c
@@ -1005,11 +1005,11 @@ process_ep0_receive (struct usb_dev* dev)
#endif
dev->ep0_stage = SETUP_STAGE;
break;
- }
+ }
spin_unlock(&ep0->lock);
- // we're done processing the packet, free it
- kfree(pkt);
+ // we're done processing the packet, free it
+ kfree(pkt);
}
@@ -1072,8 +1072,7 @@ dma_done_ep0_intr(int irq, void *dev_id, struct pt_regs *regs)
clear_dma_done1(ep0->indma);
pkt = send_packet_complete(ep0);
- if (pkt)
- kfree(pkt);
+ kfree(pkt);
}
/*
@@ -1302,8 +1301,7 @@ usbdev_exit(void)
endpoint_flush(ep);
}
- if (usbdev.full_conf_desc)
- kfree(usbdev.full_conf_desc);
+ kfree(usbdev.full_conf_desc);
}
int
diff --git a/arch/mips/au1000/csb250/init.c b/arch/mips/au1000/csb250/init.c
index bd99733abc0b..a4898b1bc66a 100644
--- a/arch/mips/au1000/csb250/init.c
+++ b/arch/mips/au1000/csb250/init.c
@@ -35,7 +35,6 @@
#include <asm/bootinfo.h>
#include <linux/string.h>
#include <linux/kernel.h>
-#include <linux/sched.h>
int prom_argc;
char **prom_argv, **prom_envp;
diff --git a/arch/mips/au1000/db1x00/irqmap.c b/arch/mips/au1000/db1x00/irqmap.c
index 8f6ef0dbe1f8..f63024a9893a 100644
--- a/arch/mips/au1000/db1x00/irqmap.c
+++ b/arch/mips/au1000/db1x00/irqmap.c
@@ -48,6 +48,38 @@
#include <asm/system.h>
#include <asm/mach-au1x00/au1000.h>
+#ifdef CONFIG_MIPS_DB1500
+char irq_tab_alchemy[][5] __initdata = {
+ [12] = { -1, INTA, INTX, INTX, INTX}, /* IDSEL 12 - HPT371 */
+ [13] = { -1, INTA, INTB, INTC, INTD}, /* IDSEL 13 - PCI slot */
+};
+#endif
+
+#ifdef CONFIG_MIPS_BOSPORUS
+char irq_tab_alchemy[][5] __initdata = {
+ [11] = { -1, INTA, INTB, INTX, INTX}, /* IDSEL 11 - miniPCI */
+ [12] = { -1, INTA, INTX, INTX, INTX}, /* IDSEL 12 - SN1741 */
+ [13] = { -1, INTA, INTB, INTC, INTD}, /* IDSEL 13 - PCI slot */
+};
+#endif
+
+#ifdef CONFIG_MIPS_MIRAGE
+char irq_tab_alchemy[][5] __initdata = {
+ [11] = { -1, INTD, INTX, INTX, INTX}, /* IDSEL 11 - SMI VGX */
+ [12] = { -1, INTX, INTX, INTC, INTX}, /* IDSEL 12 - PNX1300 */
+ [13] = { -1, INTA, INTB, INTX, INTX}, /* IDSEL 13 - miniPCI */
+};
+#endif
+
+#ifdef CONFIG_MIPS_DB1550
+char irq_tab_alchemy[][5] __initdata = {
+ [11] = { -1, INTC, INTX, INTX, INTX}, /* IDSEL 11 - on-board HPT371 */
+ [12] = { -1, INTB, INTC, INTD, INTA}, /* IDSEL 12 - PCI slot 2 (left) */
+ [13] = { -1, INTA, INTB, INTC, INTD}, /* IDSEL 13 - PCI slot 1 (right) */
+};
+#endif
+
+
au1xxx_irq_map_t au1xxx_irq_map[] = {
#ifndef CONFIG_MIPS_MIRAGE
diff --git a/arch/mips/au1000/db1x00/mirage_ts.c b/arch/mips/au1000/db1x00/mirage_ts.c
index ade35e432004..c29852c24b4f 100644
--- a/arch/mips/au1000/db1x00/mirage_ts.c
+++ b/arch/mips/au1000/db1x00/mirage_ts.c
@@ -102,15 +102,15 @@ static struct {
} mirage_ts_cal =
{
#if 0
- xscale: 84,
- xtrans: -157,
- yscale: 66,
- ytrans: -150,
+ .xscale = 84,
+ .xtrans = -157,
+ .yscale = 66,
+ .ytrans = -150,
#else
- xscale: 84,
- xtrans: -150,
- yscale: 66,
- ytrans: -146,
+ .xscale = 84,
+ .xtrans = -150,
+ .yscale = 66,
+ .ytrans = -146,
#endif
};
diff --git a/arch/mips/au1000/hydrogen3/init.c b/arch/mips/au1000/hydrogen3/init.c
index 8cc9879dd582..01ab28483959 100644
--- a/arch/mips/au1000/hydrogen3/init.c
+++ b/arch/mips/au1000/hydrogen3/init.c
@@ -37,7 +37,6 @@
#include <linux/config.h>
#include <linux/string.h>
#include <linux/kernel.h>
-#include <linux/sched.h>
int prom_argc;
char **prom_argv, **prom_envp;
diff --git a/arch/mips/au1000/mtx-1/init.c b/arch/mips/au1000/mtx-1/init.c
index 02e7dbcff727..88f2b6d97281 100644
--- a/arch/mips/au1000/mtx-1/init.c
+++ b/arch/mips/au1000/mtx-1/init.c
@@ -33,7 +33,6 @@
#include <linux/sched.h>
#include <linux/init.h>
#include <linux/mm.h>
-#include <linux/sched.h>
#include <linux/bootmem.h>
#include <asm/addrspace.h>
#include <asm/bootinfo.h>
diff --git a/arch/mips/au1000/mtx-1/irqmap.c b/arch/mips/au1000/mtx-1/irqmap.c
index ddcb9d089dc1..f9a0a8b9def2 100644
--- a/arch/mips/au1000/mtx-1/irqmap.c
+++ b/arch/mips/au1000/mtx-1/irqmap.c
@@ -47,6 +47,17 @@
#include <asm/system.h>
#include <asm/mach-au1x00/au1000.h>
+char irq_tab_alchemy[][5] __initdata = {
+ [0] = { -1, INTA, INTB, INTX, INTX}, /* IDSEL 00 - AdapterA-Slot0 (top) */
+ [1] = { -1, INTB, INTA, INTX, INTX}, /* IDSEL 01 - AdapterA-Slot1 (bottom) */
+ [2] = { -1, INTC, INTD, INTX, INTX}, /* IDSEL 02 - AdapterB-Slot0 (top) */
+ [3] = { -1, INTD, INTC, INTX, INTX}, /* IDSEL 03 - AdapterB-Slot1 (bottom) */
+ [4] = { -1, INTA, INTB, INTX, INTX}, /* IDSEL 04 - AdapterC-Slot0 (top) */
+ [5] = { -1, INTB, INTA, INTX, INTX}, /* IDSEL 05 - AdapterC-Slot1 (bottom) */
+ [6] = { -1, INTC, INTD, INTX, INTX}, /* IDSEL 06 - AdapterD-Slot0 (top) */
+ [7] = { -1, INTD, INTC, INTX, INTX}, /* IDSEL 07 - AdapterD-Slot1 (bottom) */
+};
+
au1xxx_irq_map_t au1xxx_irq_map[] = {
{ AU1500_GPIO_204, INTC_INT_HIGH_LEVEL, 0},
{ AU1500_GPIO_201, INTC_INT_LOW_LEVEL, 0 },
diff --git a/arch/mips/au1000/pb1000/init.c b/arch/mips/au1000/pb1000/init.c
index 34713c5df0d7..e9fa1bab81f3 100644
--- a/arch/mips/au1000/pb1000/init.c
+++ b/arch/mips/au1000/pb1000/init.c
@@ -65,5 +65,4 @@ void __init prom_init(void)
memsize = simple_strtol(memsize_str, NULL, 0);
}
add_memory_region(0, memsize, BOOT_MEM_RAM);
- return 0;
}
diff --git a/arch/mips/au1000/pb1200/Makefile b/arch/mips/au1000/pb1200/Makefile
new file mode 100644
index 000000000000..22b673cf55af
--- /dev/null
+++ b/arch/mips/au1000/pb1200/Makefile
@@ -0,0 +1,5 @@
+#
+# Makefile for the Alchemy Semiconductor PB1200 board.
+#
+
+lib-y := init.o board_setup.o irqmap.o
diff --git a/arch/mips/au1000/pb1200/board_setup.c b/arch/mips/au1000/pb1200/board_setup.c
new file mode 100644
index 000000000000..a45b17538ac9
--- /dev/null
+++ b/arch/mips/au1000/pb1200/board_setup.c
@@ -0,0 +1,193 @@
+/*
+ *
+ * BRIEF MODULE DESCRIPTION
+ * Alchemy Pb1200/Db1200 board setup.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/ioport.h>
+#include <linux/mm.h>
+#include <linux/console.h>
+#include <linux/mc146818rtc.h>
+#include <linux/delay.h>
+
+#if defined(CONFIG_BLK_DEV_IDE_AU1XXX)
+#include <linux/ide.h>
+#endif
+
+#include <asm/cpu.h>
+#include <asm/bootinfo.h>
+#include <asm/irq.h>
+#include <asm/mipsregs.h>
+#include <asm/reboot.h>
+#include <asm/pgtable.h>
+#include <asm/mach-au1x00/au1000.h>
+#include <asm/mach-au1x00/au1xxx_dbdma.h>
+
+#ifdef CONFIG_MIPS_PB1200
+#include <asm/mach-pb1x00/pb1200.h>
+#endif
+
+#ifdef CONFIG_MIPS_DB1200
+#include <asm/mach-db1x00/db1200.h>
+#define PB1200_ETH_INT DB1200_ETH_INT
+#define PB1200_IDE_INT DB1200_IDE_INT
+#endif
+
+extern void _board_init_irq(void);
+extern void (*board_init_irq)(void);
+
+void board_reset (void)
+{
+ bcsr->resets = 0;
+ bcsr->system = 0;
+}
+
+void __init board_setup(void)
+{
+ char *argptr = NULL;
+ u32 pin_func;
+
+#if 0
+ /* Enable PSC1 SYNC for AC97. Normaly done in audio driver,
+ * but it is board specific code, so put it here.
+ */
+ pin_func = au_readl(SYS_PINFUNC);
+ au_sync();
+ pin_func |= SYS_PF_MUST_BE_SET | SYS_PF_PSC1_S1;
+ au_writel(pin_func, SYS_PINFUNC);
+
+ au_writel(0, (u32)bcsr|0x10); /* turn off pcmcia power */
+ au_sync();
+#endif
+
+#if defined(CONFIG_I2C_AU1550)
+ {
+ u32 freq0, clksrc;
+
+ /* Select SMBUS in CPLD */
+ bcsr->resets &= ~(BCSR_RESETS_PCS0MUX);
+
+ pin_func = au_readl(SYS_PINFUNC);
+ au_sync();
+ pin_func &= ~(3<<17 | 1<<4);
+ /* Set GPIOs correctly */
+ pin_func |= 2<<17;
+ au_writel(pin_func, SYS_PINFUNC);
+ au_sync();
+
+ /* The i2c driver depends on 50Mhz clock */
+ freq0 = au_readl(SYS_FREQCTRL0);
+ au_sync();
+ freq0 &= ~(SYS_FC_FRDIV1_MASK | SYS_FC_FS1 | SYS_FC_FE1);
+ freq0 |= (3<<SYS_FC_FRDIV1_BIT);
+ /* 396Mhz / (3+1)*2 == 49.5Mhz */
+ au_writel(freq0, SYS_FREQCTRL0);
+ au_sync();
+ freq0 |= SYS_FC_FE1;
+ au_writel(freq0, SYS_FREQCTRL0);
+ au_sync();
+
+ clksrc = au_readl(SYS_CLKSRC);
+ au_sync();
+ clksrc &= ~0x01f00000;
+ /* bit 22 is EXTCLK0 for PSC0 */
+ clksrc |= (0x3 << 22);
+ au_writel(clksrc, SYS_CLKSRC);
+ au_sync();
+ }
+#endif
+
+#ifdef CONFIG_FB_AU1200
+ argptr = prom_getcmdline();
+#ifdef CONFIG_MIPS_PB1200
+ strcat(argptr, " video=au1200fb:panel:bs");
+#endif
+#ifdef CONFIG_MIPS_DB1200
+ strcat(argptr, " video=au1200fb:panel:bs");
+#endif
+#endif
+
+ /* The Pb1200 development board uses external MUX for PSC0 to
+ support SMB/SPI. bcsr->resets bit 12: 0=SMB 1=SPI
+ */
+#if defined(CONFIG_AU1XXX_PSC_SPI) && defined(CONFIG_I2C_AU1550)
+ #error I2C and SPI are mutually exclusive. Both are physically connected to PSC0.\
+ Refer to Pb1200/Db1200 documentation.
+#elif defined( CONFIG_AU1XXX_PSC_SPI )
+ bcsr->resets |= BCSR_RESETS_PCS0MUX;
+ /*Hard Coding Value to enable Temp Sensors [bit 14] Value for SOC Au1200. Pls refer documentation*/
+ bcsr->resets =0x900f;
+#elif defined( CONFIG_I2C_AU1550 )
+ bcsr->resets &= (~BCSR_RESETS_PCS0MUX);
+#endif
+ au_sync();
+
+#ifdef CONFIG_MIPS_PB1200
+ printk("AMD Alchemy Pb1200 Board\n");
+#endif
+#ifdef CONFIG_MIPS_DB1200
+ printk("AMD Alchemy Db1200 Board\n");
+#endif
+
+ /* Setup Pb1200 External Interrupt Controller */
+ {
+ extern void (*board_init_irq)(void);
+ extern void _board_init_irq(void);
+ board_init_irq = _board_init_irq;
+ }
+}
+
+int
+board_au1200fb_panel (void)
+{
+ BCSR *bcsr = (BCSR *)BCSR_KSEG1_ADDR;
+ int p;
+
+ p = bcsr->switches;
+ p >>= 8;
+ p &= 0x0F;
+ return p;
+}
+
+int
+board_au1200fb_panel_init (void)
+{
+ /* Apply power */
+ BCSR *bcsr = (BCSR *)BCSR_KSEG1_ADDR;
+ bcsr->board |= (BCSR_BOARD_LCDVEE | BCSR_BOARD_LCDVDD | BCSR_BOARD_LCDBL);
+ /*printk("board_au1200fb_panel_init()\n"); */
+ return 0;
+}
+
+int
+board_au1200fb_panel_shutdown (void)
+{
+ /* Remove power */
+ BCSR *bcsr = (BCSR *)BCSR_KSEG1_ADDR;
+ bcsr->board &= ~(BCSR_BOARD_LCDVEE | BCSR_BOARD_LCDVDD | BCSR_BOARD_LCDBL);
+ /*printk("board_au1200fb_panel_shutdown()\n"); */
+ return 0;
+}
+
diff --git a/arch/mips/au1000/pb1200/init.c b/arch/mips/au1000/pb1200/init.c
new file mode 100644
index 000000000000..27f09e374e15
--- /dev/null
+++ b/arch/mips/au1000/pb1200/init.c
@@ -0,0 +1,69 @@
+/*
+ *
+ * BRIEF MODULE DESCRIPTION
+ * PB1200 board setup
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ * ppopov@mvista.com or source@mvista.com
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/bootmem.h>
+#include <asm/addrspace.h>
+#include <asm/bootinfo.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
+
+int prom_argc;
+char **prom_argv, **prom_envp;
+extern void __init prom_init_cmdline(void);
+extern char *prom_getenv(char *envname);
+
+const char *get_system_type(void)
+{
+ return "Alchemy Pb1200";
+}
+
+void __init prom_init(void)
+{
+ unsigned char *memsize_str;
+ unsigned long memsize;
+
+ prom_argc = (int) fw_arg0;
+ prom_argv = (char **) fw_arg1;
+ prom_envp = (char **) fw_arg2;
+
+ mips_machgroup = MACH_GROUP_ALCHEMY;
+ mips_machtype = MACH_PB1200;
+
+ prom_init_cmdline();
+ memsize_str = prom_getenv("memsize");
+ if (!memsize_str) {
+ memsize = 0x08000000;
+ } else {
+ memsize = simple_strtol(memsize_str, NULL, 0);
+ }
+ add_memory_region(0, memsize, BOOT_MEM_RAM);
+}
diff --git a/arch/mips/au1000/pb1200/irqmap.c b/arch/mips/au1000/pb1200/irqmap.c
new file mode 100644
index 000000000000..59e70e5cf325
--- /dev/null
+++ b/arch/mips/au1000/pb1200/irqmap.c
@@ -0,0 +1,182 @@
+/*
+ * BRIEF MODULE DESCRIPTION
+ * Au1xxx irq map table
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/config.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/kernel_stat.h>
+#include <linux/module.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/timex.h>
+#include <linux/slab.h>
+#include <linux/random.h>
+#include <linux/delay.h>
+
+#include <asm/bitops.h>
+#include <asm/bootinfo.h>
+#include <asm/io.h>
+#include <asm/mipsregs.h>
+#include <asm/system.h>
+#include <asm/mach-au1x00/au1000.h>
+
+#ifdef CONFIG_MIPS_PB1200
+#include <asm/mach-pb1x00/pb1200.h>
+#endif
+
+#ifdef CONFIG_MIPS_DB1200
+#include <asm/mach-db1x00/db1200.h>
+#define PB1200_INT_BEGIN DB1200_INT_BEGIN
+#define PB1200_INT_END DB1200_INT_END
+#endif
+
+au1xxx_irq_map_t au1xxx_irq_map[] = {
+ { AU1000_GPIO_7, INTC_INT_LOW_LEVEL, 0 }, // This is exteranl interrupt cascade
+};
+
+int au1xxx_nr_irqs = sizeof(au1xxx_irq_map)/sizeof(au1xxx_irq_map_t);
+
+/*
+ * Support for External interrupts on the PbAu1200 Development platform.
+ */
+static volatile int pb1200_cascade_en=0;
+
+irqreturn_t pb1200_cascade_handler( int irq, void *dev_id, struct pt_regs *regs)
+{
+ unsigned short bisr = bcsr->int_status;
+ int extirq_nr = 0;
+
+ /* Clear all the edge interrupts. This has no effect on level */
+ bcsr->int_status = bisr;
+ for( ; bisr; bisr &= (bisr-1) )
+ {
+ extirq_nr = (PB1200_INT_BEGIN-1) + au_ffs(bisr);
+ /* Ack and dispatch IRQ */
+ do_IRQ(extirq_nr,regs);
+ }
+ return IRQ_RETVAL(1);
+}
+
+inline void pb1200_enable_irq(unsigned int irq_nr)
+{
+ bcsr->intset_mask = 1<<(irq_nr - PB1200_INT_BEGIN);
+ bcsr->intset = 1<<(irq_nr - PB1200_INT_BEGIN);
+}
+
+inline void pb1200_disable_irq(unsigned int irq_nr)
+{
+ bcsr->intclr_mask = 1<<(irq_nr - PB1200_INT_BEGIN);
+ bcsr->intclr = 1<<(irq_nr - PB1200_INT_BEGIN);
+}
+
+static unsigned int pb1200_startup_irq( unsigned int irq_nr )
+{
+ if (++pb1200_cascade_en == 1)
+ {
+ request_irq(AU1000_GPIO_7, &pb1200_cascade_handler,
+ 0, "Pb1200 Cascade", (void *)&pb1200_cascade_handler );
+#ifdef CONFIG_MIPS_PB1200
+ /* We have a problem with CPLD rev3. Enable a workaround */
+ if( ((bcsr->whoami & BCSR_WHOAMI_CPLD)>>4) <= 3)
+ {
+ printk("\nWARNING!!!\n");
+ printk("\nWARNING!!!\n");
+ printk("\nWARNING!!!\n");
+ printk("\nWARNING!!!\n");
+ printk("\nWARNING!!!\n");
+ printk("\nWARNING!!!\n");
+ printk("Pb1200 must be at CPLD rev4. Please have Pb1200\n");
+ printk("updated to latest revision. This software will not\n");
+ printk("work on anything less than CPLD rev4\n");
+ printk("\nWARNING!!!\n");
+ printk("\nWARNING!!!\n");
+ printk("\nWARNING!!!\n");
+ printk("\nWARNING!!!\n");
+ printk("\nWARNING!!!\n");
+ printk("\nWARNING!!!\n");
+ while(1);
+ }
+#endif
+ }
+ pb1200_enable_irq(irq_nr);
+ return 0;
+}
+
+static void pb1200_shutdown_irq( unsigned int irq_nr )
+{
+ pb1200_disable_irq(irq_nr);
+ if (--pb1200_cascade_en == 0)
+ {
+ free_irq(AU1000_GPIO_7,&pb1200_cascade_handler );
+ }
+ return;
+}
+
+static inline void pb1200_mask_and_ack_irq(unsigned int irq_nr)
+{
+ pb1200_disable_irq( irq_nr );
+}
+
+static void pb1200_end_irq(unsigned int irq_nr)
+{
+ if (!(irq_desc[irq_nr].status & (IRQ_DISABLED|IRQ_INPROGRESS))) {
+ pb1200_enable_irq(irq_nr);
+ }
+}
+
+static struct hw_interrupt_type external_irq_type =
+{
+#ifdef CONFIG_MIPS_PB1200
+ "Pb1200 Ext",
+#endif
+#ifdef CONFIG_MIPS_DB1200
+ "Db1200 Ext",
+#endif
+ pb1200_startup_irq,
+ pb1200_shutdown_irq,
+ pb1200_enable_irq,
+ pb1200_disable_irq,
+ pb1200_mask_and_ack_irq,
+ pb1200_end_irq,
+ NULL
+};
+
+void _board_init_irq(void)
+{
+ int irq_nr;
+
+ for (irq_nr = PB1200_INT_BEGIN; irq_nr <= PB1200_INT_END; irq_nr++)
+ {
+ irq_desc[irq_nr].handler = &external_irq_type;
+ pb1200_disable_irq(irq_nr);
+ }
+
+ /* GPIO_7 can not be hooked here, so it is hooked upon first
+ request of any source attached to the cascade */
+}
+
diff --git a/arch/mips/au1000/pb1500/irqmap.c b/arch/mips/au1000/pb1500/irqmap.c
index 476e25001681..8cb76c2edb5e 100644
--- a/arch/mips/au1000/pb1500/irqmap.c
+++ b/arch/mips/au1000/pb1500/irqmap.c
@@ -47,6 +47,11 @@
#include <asm/system.h>
#include <asm/mach-au1x00/au1000.h>
+char irq_tab_alchemy[][5] __initdata = {
+ [12] = { -1, INTA, INTX, INTX, INTX}, /* IDSEL 12 - HPT370 */
+ [13] = { -1, INTA, INTB, INTC, INTD}, /* IDSEL 13 - PCI slot */
+};
+
au1xxx_irq_map_t au1xxx_irq_map[] = {
{ AU1500_GPIO_204, INTC_INT_HIGH_LEVEL, 0},
{ AU1500_GPIO_201, INTC_INT_LOW_LEVEL, 0 },
diff --git a/arch/mips/au1000/pb1550/irqmap.c b/arch/mips/au1000/pb1550/irqmap.c
index 889d4949ee76..47c7a1c19f4b 100644
--- a/arch/mips/au1000/pb1550/irqmap.c
+++ b/arch/mips/au1000/pb1550/irqmap.c
@@ -47,6 +47,11 @@
#include <asm/system.h>
#include <asm/mach-au1x00/au1000.h>
+char irq_tab_alchemy[][5] __initdata = {
+ [12] = { -1, INTB, INTC, INTD, INTA}, /* IDSEL 12 - PCI slot 2 (left) */
+ [13] = { -1, INTA, INTB, INTC, INTD}, /* IDSEL 13 - PCI slot 1 (right) */
+};
+
au1xxx_irq_map_t au1xxx_irq_map[] = {
{ AU1000_GPIO_0, INTC_INT_LOW_LEVEL, 0 },
{ AU1000_GPIO_1, INTC_INT_LOW_LEVEL, 0 },
diff --git a/arch/mips/boot/.gitignore b/arch/mips/boot/.gitignore
new file mode 100644
index 000000000000..ba63401c6e10
--- /dev/null
+++ b/arch/mips/boot/.gitignore
@@ -0,0 +1,4 @@
+mkboot
+elf2ecoff
+zImage
+zImage.tmp
diff --git a/arch/mips/boot/Makefile b/arch/mips/boot/Makefile
index efbeac326815..0dc84417bf49 100644
--- a/arch/mips/boot/Makefile
+++ b/arch/mips/boot/Makefile
@@ -33,6 +33,9 @@ vmlinux.ecoff: $(obj)/elf2ecoff $(VMLINUX)
$(obj)/elf2ecoff: $(obj)/elf2ecoff.c
$(HOSTCC) -o $@ $^
+vmlinux.bin: $(VMLINUX)
+ $(OBJCOPY) -O binary $(strip-flags) $(VMLINUX) $(obj)/vmlinux.bin
+
vmlinux.srec: $(VMLINUX)
$(OBJCOPY) -S -O srec $(strip-flags) $(VMLINUX) $(obj)/vmlinux.srec
@@ -45,5 +48,6 @@ archhelp:
clean-files += addinitrd \
elf2ecoff \
+ vmlinux.bin \
vmlinux.ecoff \
vmlinux.srec
diff --git a/arch/mips/cobalt/Makefile b/arch/mips/cobalt/Makefile
index a5e6554b2326..3b6b7579d1de 100644
--- a/arch/mips/cobalt/Makefile
+++ b/arch/mips/cobalt/Makefile
@@ -2,6 +2,6 @@
# Makefile for the Cobalt micro systems family specific parts of the kernel
#
-obj-y := irq.o int-handler.o reset.o setup.o promcon.o
+obj-y := irq.o int-handler.o reset.o setup.o
EXTRA_AFLAGS := $(CFLAGS)
diff --git a/arch/mips/cobalt/int-handler.S b/arch/mips/cobalt/int-handler.S
index 1a21dec1b3ca..f92608e8d84f 100644
--- a/arch/mips/cobalt/int-handler.S
+++ b/arch/mips/cobalt/int-handler.S
@@ -18,8 +18,8 @@
SAVE_ALL
CLI
- la ra, ret_from_irq
- move a1, sp
+ PTR_LA ra, ret_from_irq
+ move a0, sp
j cobalt_irq
END(cobalt_handle_int)
diff --git a/arch/mips/cobalt/irq.c b/arch/mips/cobalt/irq.c
index 6d2a81581397..0d90851f925e 100644
--- a/arch/mips/cobalt/irq.c
+++ b/arch/mips/cobalt/irq.c
@@ -10,6 +10,8 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/pci.h>
#include <asm/i8259.h>
#include <asm/irq_cpu.h>
@@ -25,8 +27,8 @@ extern void cobalt_handle_int(void);
* the CPU interrupt lines, and ones that come in on the via chip. The CPU
* mappings are:
*
- * 16, - Software interrupt 0 (unused) IE_SW0
- * 17 - Software interrupt 1 (unused) IE_SW0
+ * 16 - Software interrupt 0 (unused) IE_SW0
+ * 17 - Software interrupt 1 (unused) IE_SW1
* 18 - Galileo chip (timer) IE_IRQ0
* 19 - Tulip 0 + NCR SCSI IE_IRQ1
* 20 - Tulip 1 IE_IRQ2
@@ -42,61 +44,94 @@ extern void cobalt_handle_int(void);
* 15 - IDE1
*/
-asmlinkage void cobalt_irq(struct pt_regs *regs)
+static inline void galileo_irq(struct pt_regs *regs)
{
- unsigned int pending = read_c0_status() & read_c0_cause();
-
- if (pending & CAUSEF_IP2) { /* int 18 */
- unsigned long irq_src = GALILEO_INL(GT_INTRCAUSE_OFS);
-
- /* Check for timer irq ... */
- if (irq_src & GALILEO_T0EXP) {
- /* Clear the int line */
- GALILEO_OUTL(0, GT_INTRCAUSE_OFS);
- do_IRQ(COBALT_TIMER_IRQ, regs);
- }
- return;
- }
+ unsigned int mask, pending, devfn;
- if (pending & CAUSEF_IP6) { /* int 22 */
- int irq = i8259_irq();
+ mask = GALILEO_INL(GT_INTRMASK_OFS);
+ pending = GALILEO_INL(GT_INTRCAUSE_OFS) & mask;
- if (irq >= 0)
- do_IRQ(irq, regs);
- return;
- }
+ if (pending & GALILEO_INTR_T0EXP) {
- if (pending & CAUSEF_IP3) { /* int 19 */
- do_IRQ(COBALT_ETH0_IRQ, regs);
- return;
- }
+ GALILEO_OUTL(~GALILEO_INTR_T0EXP, GT_INTRCAUSE_OFS);
+ do_IRQ(COBALT_GALILEO_IRQ, regs);
- if (pending & CAUSEF_IP4) { /* int 20 */
- do_IRQ(COBALT_ETH1_IRQ, regs);
- return;
- }
+ } else if (pending & GALILEO_INTR_RETRY_CTR) {
- if (pending & CAUSEF_IP5) { /* int 21 */
- do_IRQ(COBALT_SERIAL_IRQ, regs);
- return;
- }
+ devfn = GALILEO_INL(GT_PCI0_CFGADDR_OFS) >> 8;
+ GALILEO_OUTL(~GALILEO_INTR_RETRY_CTR, GT_INTRCAUSE_OFS);
+ printk(KERN_WARNING "Galileo: PCI retry count exceeded (%02x.%u)\n",
+ PCI_SLOT(devfn), PCI_FUNC(devfn));
+
+ } else {
- if (pending & CAUSEF_IP7) { /* int 23 */
- do_IRQ(COBALT_QUBE_SLOT_IRQ, regs);
- return;
+ GALILEO_OUTL(mask & ~pending, GT_INTRMASK_OFS);
+ printk(KERN_WARNING "Galileo: masking unexpected interrupt %08x\n", pending);
}
}
+static inline void via_pic_irq(struct pt_regs *regs)
+{
+ int irq;
+
+ irq = i8259_irq();
+ if (irq >= 0)
+ do_IRQ(irq, regs);
+}
+
+asmlinkage void cobalt_irq(struct pt_regs *regs)
+{
+ unsigned pending;
+
+ pending = read_c0_status() & read_c0_cause();
+
+ if (pending & CAUSEF_IP2) /* COBALT_GALILEO_IRQ (18) */
+
+ galileo_irq(regs);
+
+ else if (pending & CAUSEF_IP6) /* COBALT_VIA_IRQ (22) */
+
+ via_pic_irq(regs);
+
+ else if (pending & CAUSEF_IP3) /* COBALT_ETH0_IRQ (19) */
+
+ do_IRQ(COBALT_CPU_IRQ + 3, regs);
+
+ else if (pending & CAUSEF_IP4) /* COBALT_ETH1_IRQ (20) */
+
+ do_IRQ(COBALT_CPU_IRQ + 4, regs);
+
+ else if (pending & CAUSEF_IP5) /* COBALT_SERIAL_IRQ (21) */
+
+ do_IRQ(COBALT_CPU_IRQ + 5, regs);
+
+ else if (pending & CAUSEF_IP7) /* IRQ 23 */
+
+ do_IRQ(COBALT_CPU_IRQ + 7, regs);
+}
+
+static struct irqaction irq_via = {
+ no_action, 0, { { 0, } }, "cascade", NULL, NULL
+};
+
void __init arch_init_irq(void)
{
+ /*
+ * Mask all Galileo interrupts. The Galileo
+ * handler is set in cobalt_timer_setup()
+ */
+ GALILEO_OUTL(0, GT_INTRMASK_OFS);
+
set_except_vector(0, cobalt_handle_int);
init_i8259_irqs(); /* 0 ... 15 */
- mips_cpu_irq_init(16); /* 16 ... 23 */
+ mips_cpu_irq_init(COBALT_CPU_IRQ); /* 16 ... 23 */
/*
* Mask all cpu interrupts
* (except IE4, we already masked those at VIA level)
*/
change_c0_status(ST0_IM, IE_IRQ4);
+
+ setup_irq(COBALT_VIA_IRQ, &irq_via);
}
diff --git a/arch/mips/cobalt/promcon.c b/arch/mips/cobalt/promcon.c
deleted file mode 100644
index f03df761e9f1..000000000000
--- a/arch/mips/cobalt/promcon.c
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * PROM console for Cobalt Raq2
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1995, 1996, 1997 by Ralf Baechle
- * Copyright (C) 2001 by Liam Davies (ldavies@agile.tv)
- *
- */
-
-#include <linux/init.h>
-#include <linux/console.h>
-#include <linux/kdev_t.h>
-#include <linux/serial_reg.h>
-
-#include <asm/delay.h>
-#include <asm/serial.h>
-#include <asm/io.h>
-
-static unsigned long port = 0xc800000;
-
-static __inline__ void ns16550_cons_put_char(char ch, unsigned long ioaddr)
-{
- char lsr;
-
- do {
- lsr = inb(ioaddr + UART_LSR);
- } while ((lsr & (UART_LSR_TEMT | UART_LSR_THRE)) != (UART_LSR_TEMT | UART_LSR_THRE));
- outb(ch, ioaddr + UART_TX);
-}
-
-static __inline__ char ns16550_cons_get_char(unsigned long ioaddr)
-{
- while ((inb(ioaddr + UART_LSR) & UART_LSR_DR) == 0)
- udelay(1);
- return inb(ioaddr + UART_RX);
-}
-
-void ns16550_console_write(struct console *co, const char *s, unsigned count)
-{
- char lsr, ier;
- unsigned i;
-
- ier = inb(port + UART_IER);
- outb(0x00, port + UART_IER);
- for (i=0; i < count; i++, s++) {
-
- if(*s == '\n')
- ns16550_cons_put_char('\r', port);
- ns16550_cons_put_char(*s, port);
- }
-
- do {
- lsr = inb(port + UART_LSR);
- } while ((lsr & (UART_LSR_TEMT | UART_LSR_THRE)) != (UART_LSR_TEMT | UART_LSR_THRE));
-
- outb(ier, port + UART_IER);
-}
-
-char getDebugChar(void)
-{
- return ns16550_cons_get_char(port);
-}
-
-void putDebugChar(char kgdb_char)
-{
- ns16550_cons_put_char(kgdb_char, port);
-}
-
-static struct console ns16550_console = {
- .name = "prom",
- .setup = NULL,
- .write = ns16550_console_write,
- .flags = CON_PRINTBUFFER,
- .index = -1,
-};
-
-static int __init ns16550_setup_console(void)
-{
- register_console(&ns16550_console);
-
- return 0;
-}
-
-console_initcall(ns16550_setup_console);
diff --git a/arch/mips/cobalt/reset.c b/arch/mips/cobalt/reset.c
index 084c8e59f42c..805a0e88507b 100644
--- a/arch/mips/cobalt/reset.c
+++ b/arch/mips/cobalt/reset.c
@@ -16,48 +16,45 @@
#include <asm/reboot.h>
#include <asm/system.h>
#include <asm/mipsregs.h>
+#include <asm/cobalt/cobalt.h>
-void cobalt_machine_restart(char *command)
+void cobalt_machine_halt(void)
{
- *(volatile char *)0xbc000000 = 0x0f;
+ int state, last, diff;
+ unsigned long mark;
/*
- * Ouch, we're still alive ... This time we take the silver bullet ...
- * ... and find that we leave the hardware in a state in which the
- * kernel in the flush locks up somewhen during of after the PCI
- * detection stuff.
+ * turn off bar on Qube, flash power off LED on RaQ (0.5Hz)
+ *
+ * restart if ENTER and SELECT are pressed
*/
- set_c0_status(ST0_BEV | ST0_ERL);
- change_c0_config(CONF_CM_CMASK, CONF_CM_UNCACHED);
- flush_cache_all();
- write_c0_wired(0);
- __asm__ __volatile__(
- "jr\t%0"
- :
- : "r" (0xbfc00000));
-}
-extern int led_state;
-#define kLED 0xBC000000
-#define LEDSet(x) (*(volatile unsigned char *) kLED) = (( unsigned char)x)
+ last = COBALT_KEY_PORT;
-void cobalt_machine_halt(void)
-{
- int mark;
+ for (state = 0;;) {
+
+ state ^= COBALT_LED_POWER_OFF;
+ COBALT_LED_PORT = state;
+
+ diff = COBALT_KEY_PORT ^ last;
+ last ^= diff;
- /* Blink our cute? little LED (number 3)... */
- while (1) {
- led_state = led_state | ( 1 << 3 );
- LEDSet(led_state);
- mark = jiffies;
- while (jiffies<(mark+HZ));
- led_state = led_state & ~( 1 << 3 );
- LEDSet(led_state);
- mark = jiffies;
- while (jiffies<(mark+HZ));
+ if((diff & (COBALT_KEY_ENTER | COBALT_KEY_SELECT)) && !(~last & (COBALT_KEY_ENTER | COBALT_KEY_SELECT)))
+ COBALT_LED_PORT = COBALT_LED_RESET;
+
+ for (mark = jiffies; jiffies - mark < HZ;)
+ ;
}
}
+void cobalt_machine_restart(char *command)
+{
+ COBALT_LED_PORT = COBALT_LED_RESET;
+
+ /* we should never get here */
+ cobalt_machine_halt();
+}
+
/*
* This triggers the luser mode device driver for the power switch ;-)
*/
diff --git a/arch/mips/cobalt/setup.c b/arch/mips/cobalt/setup.c
index 6b4737e425ed..d358a118fa31 100644
--- a/arch/mips/cobalt/setup.c
+++ b/arch/mips/cobalt/setup.c
@@ -13,6 +13,8 @@
#include <linux/interrupt.h>
#include <linux/pci.h>
#include <linux/init.h>
+#include <linux/serial.h>
+#include <linux/serial_core.h>
#include <asm/bootinfo.h>
#include <asm/time.h>
@@ -21,6 +23,7 @@
#include <asm/processor.h>
#include <asm/reboot.h>
#include <asm/gt64120.h>
+#include <asm/serial.h>
#include <asm/cobalt/cobalt.h>
@@ -30,45 +33,44 @@ extern void cobalt_machine_power_off(void);
int cobalt_board_id;
-static char my_cmdline[CL_SIZE] = {
- "console=ttyS0,115200 "
-#ifdef CONFIG_IP_PNP
- "ip=on "
-#endif
-#ifdef CONFIG_ROOT_NFS
- "root=/dev/nfs "
-#else
- "root=/dev/hda1 "
-#endif
- };
-
const char *get_system_type(void)
{
+ switch (cobalt_board_id) {
+ case COBALT_BRD_ID_QUBE1:
+ return "Cobalt Qube";
+ case COBALT_BRD_ID_RAQ1:
+ return "Cobalt RaQ";
+ case COBALT_BRD_ID_QUBE2:
+ return "Cobalt Qube2";
+ case COBALT_BRD_ID_RAQ2:
+ return "Cobalt RaQ2";
+ }
return "MIPS Cobalt";
}
static void __init cobalt_timer_setup(struct irqaction *irq)
{
- /* Load timer value for 150 Hz */
- GALILEO_OUTL(500000, GT_TC0_OFS);
+ /* Load timer value for 1KHz (TCLK is 50MHz) */
+ GALILEO_OUTL(50*1000*1000 / 1000, GT_TC0_OFS);
- /* Register our timer interrupt */
- setup_irq(COBALT_TIMER_IRQ, irq);
+ /* Enable timer */
+ GALILEO_OUTL(GALILEO_ENTC0 | GALILEO_SELTC0, GT_TC_CONTROL_OFS);
- /* Enable timer ints */
- GALILEO_OUTL((GALILEO_ENTC0 | GALILEO_SELTC0), GT_TC_CONTROL_OFS);
- /* Unmask timer int */
- GALILEO_OUTL(0x100, GT_INTRMASK_OFS);
+ /* Register interrupt */
+ setup_irq(COBALT_GALILEO_IRQ, irq);
+
+ /* Enable interrupt */
+ GALILEO_OUTL(GALILEO_INTR_T0EXP | GALILEO_INL(GT_INTRMASK_OFS), GT_INTRMASK_OFS);
}
extern struct pci_ops gt64111_pci_ops;
static struct resource cobalt_mem_resource = {
- "GT64111 PCI MEM", GT64111_IO_BASE, 0xffffffffUL, IORESOURCE_MEM
+ "PCI memory", GT64111_MEM_BASE, GT64111_MEM_END, IORESOURCE_MEM
};
static struct resource cobalt_io_resource = {
- "GT64111 IO MEM", 0x00001000UL, 0x0fffffffUL, IORESOURCE_IO
+ "PCI I/O", 0x1000, 0xffff, IORESOURCE_IO
};
static struct resource cobalt_io_resources[] = {
@@ -86,11 +88,12 @@ static struct pci_controller cobalt_pci_controller = {
.mem_resource = &cobalt_mem_resource,
.mem_offset = 0,
.io_resource = &cobalt_io_resource,
- .io_offset = 0x00001000UL - GT64111_IO_BASE
+ .io_offset = 0 - GT64111_IO_BASE
};
-static void __init cobalt_setup(void)
+void __init plat_setup(void)
{
+ static struct uart_port uart;
unsigned int devfn = PCI_DEVFN(COBALT_PCICONF_VIA, 0);
int i;
@@ -100,7 +103,10 @@ static void __init cobalt_setup(void)
board_timer_setup = cobalt_timer_setup;
- set_io_port_base(KSEG1ADDR(GT64111_IO_BASE));
+ set_io_port_base(CKSEG1ADDR(GT64111_IO_BASE));
+
+ /* I/O port resource must include UART and LCD/buttons */
+ ioport_resource.end = 0x0fffffff;
/*
* This is a prom style console. We just poke at the
@@ -120,27 +126,61 @@ static void __init cobalt_setup(void)
cobalt_board_id >>= ((VIA_COBALT_BRD_ID_REG & 3) * 8);
cobalt_board_id = VIA_COBALT_BRD_REG_to_ID(cobalt_board_id);
+ printk("Cobalt board ID: %d\n", cobalt_board_id);
+
#ifdef CONFIG_PCI
register_pci_controller(&cobalt_pci_controller);
#endif
-}
-early_initcall(cobalt_setup);
+#ifdef CONFIG_SERIAL_8250
+ if (cobalt_board_id > COBALT_BRD_ID_RAQ1) {
+
+ uart.line = 0;
+ uart.type = PORT_UNKNOWN;
+ uart.uartclk = 18432000;
+ uart.irq = COBALT_SERIAL_IRQ;
+ uart.flags = STD_COM_FLAGS;
+ uart.iobase = 0xc800000;
+ uart.iotype = UPIO_PORT;
+
+ early_serial_setup(&uart);
+ }
+#endif
+}
/*
* Prom init. We read our one and only communication with the firmware.
- * Grab the amount of installed memory
+ * Grab the amount of installed memory.
+ * Better boot loaders (CoLo) pass a command line too :-)
*/
void __init prom_init(void)
{
- int argc = fw_arg0;
-
- strcpy(arcs_cmdline, my_cmdline);
+ int narg, indx, posn, nchr;
+ unsigned long memsz;
+ char **argv;
mips_machgroup = MACH_GROUP_COBALT;
- add_memory_region(0x0, argc & 0x7fffffff, BOOT_MEM_RAM);
+ memsz = fw_arg0 & 0x7fff0000;
+ narg = fw_arg0 & 0x0000ffff;
+
+ if (narg) {
+ arcs_cmdline[0] = '\0';
+ argv = (char **) fw_arg1;
+ posn = 0;
+ for (indx = 1; indx < narg; ++indx) {
+ nchr = strlen(argv[indx]);
+ if (posn + 1 + nchr + 1 > sizeof(arcs_cmdline))
+ break;
+ if (posn)
+ arcs_cmdline[posn++] = ' ';
+ strcpy(arcs_cmdline + posn, argv[indx]);
+ posn += nchr;
+ }
+ }
+
+ add_memory_region(0x0, memsz, BOOT_MEM_RAM);
}
unsigned long __init prom_free_prom_memory(void)
diff --git a/arch/mips/configs/atlas_defconfig b/arch/mips/configs/atlas_defconfig
index 3120a02b8670..132ec3dac63f 100644
--- a/arch/mips/configs/atlas_defconfig
+++ b/arch/mips/configs/atlas_defconfig
@@ -1,12 +1,9 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-rc2
-# Wed Jan 26 02:49:00 2005
+# Linux kernel version: 2.6.14-rc2
+# Thu Oct 20 22:25:13 2005
#
CONFIG_MIPS=y
-# CONFIG_64BIT is not set
-# CONFIG_64BIT is not set
-CONFIG_32BIT=y
#
# Code maturity level options
@@ -14,24 +11,29 @@ CONFIG_32BIT=y
CONFIG_EXPERIMENTAL=y
CONFIG_CLEAN_COMPILE=y
CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
#
# General setup
#
CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
# CONFIG_POSIX_MQUEUE is not set
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
CONFIG_HOTPLUG=y
CONFIG_KOBJECT_UEVENT=y
# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
CONFIG_EMBEDDED=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
@@ -41,6 +43,7 @@ CONFIG_CC_ALIGN_LABELS=0
CONFIG_CC_ALIGN_LOOPS=0
CONFIG_CC_ALIGN_JUMPS=0
# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
#
# Loadable module support
@@ -56,42 +59,72 @@ CONFIG_KMOD=y
#
# Machine selection
#
-# CONFIG_MACH_JAZZ is not set
-# CONFIG_MACH_VR41XX is not set
-# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_MIPS_PB1550 is not set
+# CONFIG_MIPS_PB1200 is not set
+# CONFIG_MIPS_DB1000 is not set
+# CONFIG_MIPS_DB1100 is not set
+# CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
+# CONFIG_MIPS_DB1200 is not set
+# CONFIG_MIPS_MIRAGE is not set
# CONFIG_MIPS_COBALT is not set
# CONFIG_MACH_DECSTATION is not set
# CONFIG_MIPS_EV64120 is not set
# CONFIG_MIPS_EV96100 is not set
# CONFIG_MIPS_IVR is not set
-# CONFIG_LASAT is not set
# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_LASAT is not set
CONFIG_MIPS_ATLAS=y
# CONFIG_MIPS_MALTA is not set
# CONFIG_MIPS_SEAD is not set
+# CONFIG_MIPS_SIM is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
# CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_G is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_JAGUAR_ATX is not set
-# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MIPS_XXS1500 is not set
+# CONFIG_PNX8550_V2PCI is not set
+# CONFIG_PNX8550_JBS is not set
# CONFIG_DDB5074 is not set
# CONFIG_DDB5476 is not set
# CONFIG_DDB5477 is not set
-# CONFIG_NEC_OSPREY is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_QEMU is not set
# CONFIG_SGI_IP22 is not set
-# CONFIG_SOC_AU1X00 is not set
-# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_BIGSUR is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_PTSWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CRHONE is not set
# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
# CONFIG_TOSHIBA_RBTX4927 is not set
+# CONFIG_TOSHIBA_RBTX4938 is not set
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_HAVE_DEC_LOCK=y
CONFIG_DMA_NONCOHERENT=y
CONFIG_DMA_NEED_PCI_MAP_STATE=y
CONFIG_MIPS_BONITO64=y
CONFIG_MIPS_MSC=y
-# CONFIG_CPU_LITTLE_ENDIAN is not set
+# CONFIG_CPU_BIG_ENDIAN is not set
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
+CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
+CONFIG_IRQ_CPU=y
CONFIG_MIPS_BOARDS_GEN=y
CONFIG_MIPS_GT64120=y
CONFIG_SWAP_IO_SPACE=y
@@ -101,8 +134,10 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5
#
# CPU selection
#
-CONFIG_CPU_MIPS32=y
-# CONFIG_CPU_MIPS64 is not set
+CONFIG_CPU_MIPS32_R1=y
+# CONFIG_CPU_MIPS32_R2 is not set
+# CONFIG_CPU_MIPS64_R1 is not set
+# CONFIG_CPU_MIPS64_R2 is not set
# CONFIG_CPU_R3000 is not set
# CONFIG_CPU_TX39XX is not set
# CONFIG_CPU_VR41XX is not set
@@ -118,15 +153,46 @@ CONFIG_CPU_MIPS32=y
# CONFIG_CPU_RM7000 is not set
# CONFIG_CPU_RM9000 is not set
# CONFIG_CPU_SB1 is not set
+CONFIG_SYS_HAS_CPU_MIPS32_R1=y
+CONFIG_SYS_HAS_CPU_MIPS32_R2=y
+CONFIG_SYS_HAS_CPU_MIPS64_R1=y
+CONFIG_SYS_HAS_CPU_NEVADA=y
+CONFIG_SYS_HAS_CPU_RM7000=y
+CONFIG_CPU_MIPS32=y
+CONFIG_CPU_MIPSR1=y
+CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
+CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
+
+#
+# Kernel type
+#
+CONFIG_32BIT=y
+# CONFIG_64BIT is not set
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_BOARD_SCACHE=y
+CONFIG_RM7000_CPU_SCACHE=y
CONFIG_CPU_HAS_PREFETCH=y
+# CONFIG_MIPS_MT is not set
# CONFIG_64BIT_PHYS_ADDR is not set
# CONFIG_CPU_ADVANCED is not set
CONFIG_CPU_HAS_LLSC=y
CONFIG_CPU_HAS_SYNC=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_ARCH_FLATMEM_ENABLE=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_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
#
@@ -135,7 +201,6 @@ CONFIG_CPU_HAS_SYNC=y
CONFIG_HW_HAS_PCI=y
CONFIG_PCI=y
CONFIG_PCI_LEGACY_PROC=y
-CONFIG_PCI_NAMES=y
CONFIG_MMU=y
#
@@ -144,10 +209,6 @@ CONFIG_MMU=y
# CONFIG_PCCARD is not set
#
-# PC-card bridges
-#
-
-#
# PCI Hotplug Support
#
# CONFIG_HOTPLUG_PCI is not set
@@ -160,199 +221,7 @@ CONFIG_BINFMT_ELF=y
CONFIG_TRAD_SIGNALS=y
#
-# Device Drivers
-#
-
-#
-# Generic Driver Options
-#
-CONFIG_STANDALONE=y
-CONFIG_PREVENT_FIRMWARE_BUILD=y
-CONFIG_FW_LOADER=y
-
-#
-# Memory Technology Devices (MTD)
-#
-# CONFIG_MTD is not set
-
-#
-# Parallel port support
-#
-# CONFIG_PARPORT is not set
-
-#
-# Plug and Play support
-#
-
-#
-# Block devices
-#
-# CONFIG_BLK_DEV_FD is not set
-# CONFIG_BLK_CPQ_DA is not set
-# CONFIG_BLK_CPQ_CISS_DA is not set
-# CONFIG_BLK_DEV_DAC960 is not set
-CONFIG_BLK_DEV_UMEM=m
-# CONFIG_BLK_DEV_COW_COMMON is not set
-CONFIG_BLK_DEV_LOOP=m
-CONFIG_BLK_DEV_CRYPTOLOOP=m
-CONFIG_BLK_DEV_NBD=m
-# CONFIG_BLK_DEV_SX8 is not set
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_BLK_DEV_RAM_SIZE=4096
-# CONFIG_BLK_DEV_INITRD is not set
-CONFIG_INITRAMFS_SOURCE=""
-# CONFIG_LBD is not set
-CONFIG_CDROM_PKTCDVD=m
-CONFIG_CDROM_PKTCDVD_BUFFERS=8
-# CONFIG_CDROM_PKTCDVD_WCACHE is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-CONFIG_ATA_OVER_ETH=m
-
-#
-# ATA/ATAPI/MFM/RLL support
-#
-CONFIG_IDE=y
-CONFIG_BLK_DEV_IDE=y
-
-#
-# Please see Documentation/ide.txt for help/info on IDE drives
-#
-# CONFIG_BLK_DEV_IDE_SATA is not set
-CONFIG_BLK_DEV_IDEDISK=y
-# CONFIG_IDEDISK_MULTI_MODE is not set
-CONFIG_BLK_DEV_IDECD=y
-# CONFIG_BLK_DEV_IDETAPE is not set
-# CONFIG_BLK_DEV_IDEFLOPPY is not set
-# CONFIG_BLK_DEV_IDESCSI is not set
-# CONFIG_IDE_TASK_IOCTL is not set
-
-#
-# IDE chipset support/bugfixes
-#
-CONFIG_IDE_GENERIC=y
-# CONFIG_BLK_DEV_IDEPCI is not set
-# CONFIG_IDE_ARM is not set
-# CONFIG_BLK_DEV_IDEDMA is not set
-# CONFIG_IDEDMA_AUTO is not set
-# CONFIG_BLK_DEV_HD is not set
-
-#
-# SCSI device support
-#
-CONFIG_SCSI=y
-CONFIG_SCSI_PROC_FS=y
-
-#
-# SCSI support type (disk, tape, CD-ROM)
-#
-CONFIG_BLK_DEV_SD=y
-CONFIG_CHR_DEV_ST=m
-CONFIG_CHR_DEV_OSST=m
-CONFIG_BLK_DEV_SR=m
-CONFIG_BLK_DEV_SR_VENDOR=y
-CONFIG_CHR_DEV_SG=m
-
-#
-# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
-#
-CONFIG_SCSI_MULTI_LUN=y
-CONFIG_SCSI_CONSTANTS=y
-CONFIG_SCSI_LOGGING=y
-
-#
-# SCSI Transport Attributes
-#
-CONFIG_SCSI_SPI_ATTRS=y
-CONFIG_SCSI_FC_ATTRS=m
-CONFIG_SCSI_ISCSI_ATTRS=m
-
-#
-# SCSI low-level drivers
-#
-# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
-# CONFIG_SCSI_3W_9XXX is not set
-# CONFIG_SCSI_ACARD is not set
-# CONFIG_SCSI_AACRAID is not set
-# CONFIG_SCSI_AIC7XXX is not set
-# CONFIG_SCSI_AIC7XXX_OLD is not set
-# CONFIG_SCSI_AIC79XX is not set
-# CONFIG_SCSI_DPT_I2O is not set
-# CONFIG_MEGARAID_NEWGEN is not set
-# CONFIG_MEGARAID_LEGACY is not set
-# CONFIG_SCSI_SATA is not set
-# CONFIG_SCSI_BUSLOGIC is not set
-# CONFIG_SCSI_DMX3191D is not set
-# CONFIG_SCSI_EATA is not set
-# CONFIG_SCSI_EATA_PIO is not set
-# CONFIG_SCSI_FUTURE_DOMAIN is not set
-# CONFIG_SCSI_GDTH is not set
-# CONFIG_SCSI_IPS is not set
-# CONFIG_SCSI_INITIO is not set
-# CONFIG_SCSI_INIA100 is not set
-CONFIG_SCSI_SYM53C8XX_2=y
-CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=0
-CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
-CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
-# CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set
-# CONFIG_SCSI_IPR is not set
-# CONFIG_SCSI_QLOGIC_ISP is not set
-# CONFIG_SCSI_QLOGIC_FC is not set
-# CONFIG_SCSI_QLOGIC_1280 is not set
-CONFIG_SCSI_QLA2XXX=y
-# CONFIG_SCSI_QLA21XX is not set
-# CONFIG_SCSI_QLA22XX is not set
-# CONFIG_SCSI_QLA2300 is not set
-# CONFIG_SCSI_QLA2322 is not set
-# CONFIG_SCSI_QLA6312 is not set
-# CONFIG_SCSI_DC395x is not set
-# CONFIG_SCSI_DC390T is not set
-# CONFIG_SCSI_NSP32 is not set
-# CONFIG_SCSI_DEBUG is not set
-
-#
-# Multi-device support (RAID and LVM)
-#
-CONFIG_MD=y
-CONFIG_BLK_DEV_MD=m
-CONFIG_MD_LINEAR=m
-CONFIG_MD_RAID0=m
-CONFIG_MD_RAID1=m
-CONFIG_MD_RAID10=m
-CONFIG_MD_RAID5=m
-CONFIG_MD_RAID6=m
-CONFIG_MD_MULTIPATH=m
-CONFIG_MD_FAULTY=m
-CONFIG_BLK_DEV_DM=m
-CONFIG_DM_CRYPT=m
-CONFIG_DM_SNAPSHOT=m
-CONFIG_DM_MIRROR=m
-CONFIG_DM_ZERO=m
-
-#
-# Fusion MPT device support
-#
-# CONFIG_FUSION is not set
-
-#
-# IEEE 1394 (FireWire) support
-#
-# CONFIG_IEEE1394 is not set
-
-#
-# I2O device support
-#
-# CONFIG_I2O is not set
-
-#
-# Networking support
+# Networking
#
CONFIG_NET=y
@@ -361,15 +230,20 @@ CONFIG_NET=y
#
CONFIG_PACKET=y
CONFIG_PACKET_MMAP=y
-CONFIG_NETLINK_DEV=y
CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
CONFIG_NET_KEY=y
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_FWMARK=y
CONFIG_IP_ROUTE_MULTIPATH=y
+# CONFIG_IP_ROUTE_MULTIPATH_CACHED is not set
CONFIG_IP_ROUTE_VERBOSE=y
CONFIG_IP_PNP=y
CONFIG_IP_PNP_DHCP=y
@@ -387,8 +261,10 @@ CONFIG_INET_AH=m
CONFIG_INET_ESP=m
CONFIG_INET_IPCOMP=m
CONFIG_INET_TUNNEL=m
-CONFIG_IP_TCPDIAG=m
-CONFIG_IP_TCPDIAG_IPV6=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
#
# IP: Virtual Server Configuration
@@ -433,6 +309,9 @@ CONFIG_IPV6_TUNNEL=m
CONFIG_NETFILTER=y
# CONFIG_NETFILTER_DEBUG is not set
CONFIG_BRIDGE_NETFILTER=y
+CONFIG_NETFILTER_NETLINK=m
+CONFIG_NETFILTER_NETLINK_QUEUE=m
+CONFIG_NETFILTER_NETLINK_LOG=m
#
# IP: Netfilter Configuration
@@ -440,11 +319,15 @@ CONFIG_BRIDGE_NETFILTER=y
CONFIG_IP_NF_CONNTRACK=m
CONFIG_IP_NF_CT_ACCT=y
CONFIG_IP_NF_CONNTRACK_MARK=y
+CONFIG_IP_NF_CONNTRACK_EVENTS=y
+CONFIG_IP_NF_CONNTRACK_NETLINK=m
CONFIG_IP_NF_CT_PROTO_SCTP=m
CONFIG_IP_NF_FTP=m
CONFIG_IP_NF_IRC=m
+# CONFIG_IP_NF_NETBIOS_NS is not set
CONFIG_IP_NF_TFTP=m
CONFIG_IP_NF_AMANDA=m
+CONFIG_IP_NF_PPTP=m
CONFIG_IP_NF_QUEUE=m
CONFIG_IP_NF_IPTABLES=m
CONFIG_IP_NF_MATCH_LIMIT=m
@@ -469,9 +352,12 @@ CONFIG_IP_NF_MATCH_PHYSDEV=m
CONFIG_IP_NF_MATCH_ADDRTYPE=m
CONFIG_IP_NF_MATCH_REALM=m
CONFIG_IP_NF_MATCH_SCTP=m
+CONFIG_IP_NF_MATCH_DCCP=m
CONFIG_IP_NF_MATCH_COMMENT=m
CONFIG_IP_NF_MATCH_CONNMARK=m
+CONFIG_IP_NF_MATCH_CONNBYTES=m
CONFIG_IP_NF_MATCH_HASHLIMIT=m
+CONFIG_IP_NF_MATCH_STRING=m
CONFIG_IP_NF_FILTER=m
CONFIG_IP_NF_TARGET_REJECT=m
CONFIG_IP_NF_TARGET_LOG=m
@@ -488,12 +374,14 @@ CONFIG_IP_NF_NAT_IRC=m
CONFIG_IP_NF_NAT_FTP=m
CONFIG_IP_NF_NAT_TFTP=m
CONFIG_IP_NF_NAT_AMANDA=m
+CONFIG_IP_NF_NAT_PPTP=m
CONFIG_IP_NF_MANGLE=m
CONFIG_IP_NF_TARGET_TOS=m
CONFIG_IP_NF_TARGET_ECN=m
CONFIG_IP_NF_TARGET_DSCP=m
CONFIG_IP_NF_TARGET_MARK=m
CONFIG_IP_NF_TARGET_CLASSIFY=m
+CONFIG_IP_NF_TARGET_TTL=m
CONFIG_IP_NF_TARGET_CONNMARK=m
CONFIG_IP_NF_TARGET_CLUSTERIP=m
CONFIG_IP_NF_RAW=m
@@ -503,7 +391,7 @@ CONFIG_IP_NF_ARPFILTER=m
CONFIG_IP_NF_ARP_MANGLE=m
#
-# IPv6: Netfilter Configuration
+# IPv6: Netfilter Configuration (EXPERIMENTAL)
#
CONFIG_IP6_NF_QUEUE=m
CONFIG_IP6_NF_IPTABLES=m
@@ -523,8 +411,10 @@ CONFIG_IP6_NF_MATCH_EUI64=m
CONFIG_IP6_NF_MATCH_PHYSDEV=m
CONFIG_IP6_NF_FILTER=m
CONFIG_IP6_NF_TARGET_LOG=m
+CONFIG_IP6_NF_TARGET_REJECT=m
CONFIG_IP6_NF_MANGLE=m
CONFIG_IP6_NF_TARGET_MARK=m
+CONFIG_IP6_NF_TARGET_HL=m
CONFIG_IP6_NF_RAW=m
#
@@ -550,8 +440,11 @@ CONFIG_BRIDGE_EBT_REDIRECT=m
CONFIG_BRIDGE_EBT_SNAT=m
CONFIG_BRIDGE_EBT_LOG=m
CONFIG_BRIDGE_EBT_ULOG=m
-CONFIG_XFRM=y
-CONFIG_XFRM_USER=m
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
#
# SCTP Configuration (EXPERIMENTAL)
@@ -579,10 +472,6 @@ CONFIG_IPDDP_DECAP=y
CONFIG_NET_DIVERT=y
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
CONFIG_NET_SCHED=y
CONFIG_NET_SCH_CLK_JIFFIES=y
# CONFIG_NET_SCH_CLK_GETTIMEOFDAY is not set
@@ -602,6 +491,7 @@ CONFIG_NET_SCH_INGRESS=m
CONFIG_NET_QOS=y
CONFIG_NET_ESTIMATOR=y
CONFIG_NET_CLS=y
+CONFIG_NET_CLS_BASIC=m
CONFIG_NET_CLS_TCINDEX=m
CONFIG_NET_CLS_ROUTE4=m
CONFIG_NET_CLS_ROUTE=y
@@ -612,6 +502,7 @@ CONFIG_NET_CLS_IND=y
# CONFIG_CLS_U32_MARK is not set
CONFIG_NET_CLS_RSVP=m
CONFIG_NET_CLS_RSVP6=m
+# CONFIG_NET_EMATCH is not set
# CONFIG_NET_CLS_ACT is not set
CONFIG_NET_CLS_POLICE=y
@@ -619,17 +510,222 @@ CONFIG_NET_CLS_POLICE=y
# Network testing
#
# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
# CONFIG_HAMRADIO is not set
# CONFIG_IRDA is not set
# CONFIG_BT is not set
+CONFIG_IEEE80211=m
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=m
+CONFIG_IEEE80211_CRYPT_CCMP=m
+CONFIG_IEEE80211_CRYPT_TKIP=m
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+CONFIG_CONNECTOR=m
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+
+#
+# Block devices
+#
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+CONFIG_BLK_DEV_UMEM=m
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=m
+CONFIG_BLK_DEV_CRYPTOLOOP=m
+CONFIG_BLK_DEV_NBD=m
+# CONFIG_BLK_DEV_SX8 is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=4096
+# CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_LBD is not set
+CONFIG_CDROM_PKTCDVD=m
+CONFIG_CDROM_PKTCDVD_BUFFERS=8
+# CONFIG_CDROM_PKTCDVD_WCACHE is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_ATA_OVER_ETH=m
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+CONFIG_IDE=y
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_IDE_SATA is not set
+CONFIG_BLK_DEV_IDEDISK=y
+# CONFIG_IDEDISK_MULTI_MODE is not set
+CONFIG_BLK_DEV_IDECD=y
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_BLK_DEV_IDEFLOPPY is not set
+# CONFIG_BLK_DEV_IDESCSI is not set
+# CONFIG_IDE_TASK_IOCTL is not set
+
+#
+# IDE chipset support/bugfixes
+#
+CONFIG_IDE_GENERIC=y
+# CONFIG_BLK_DEV_IDEPCI is not set
+# CONFIG_IDE_ARM is not set
+# CONFIG_BLK_DEV_IDEDMA is not set
+# CONFIG_IDEDMA_AUTO is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI device support
+#
+CONFIG_RAID_ATTRS=m
+CONFIG_SCSI=y
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_ST=m
+CONFIG_CHR_DEV_OSST=m
+CONFIG_BLK_DEV_SR=m
+CONFIG_BLK_DEV_SR_VENDOR=y
+CONFIG_CHR_DEV_SG=m
+CONFIG_CHR_DEV_SCH=m
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+
+#
+# SCSI Transport Attributes
+#
+CONFIG_SCSI_SPI_ATTRS=y
+CONFIG_SCSI_FC_ATTRS=m
+CONFIG_SCSI_ISCSI_ATTRS=m
+CONFIG_SCSI_SAS_ATTRS=m
+
+#
+# SCSI low-level drivers
+#
+# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_ACARD is not set
+# CONFIG_SCSI_AACRAID is not set
+# CONFIG_SCSI_AIC7XXX is not set
+# CONFIG_SCSI_AIC7XXX_OLD is not set
+# CONFIG_SCSI_AIC79XX is not set
+# CONFIG_SCSI_DPT_I2O is not set
+# CONFIG_MEGARAID_NEWGEN is not set
+# CONFIG_MEGARAID_LEGACY is not set
+# CONFIG_SCSI_SATA is not set
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+# CONFIG_SCSI_IPS is not set
+# CONFIG_SCSI_INITIO is not set
+# CONFIG_SCSI_INIA100 is not set
+CONFIG_SCSI_SYM53C8XX_2=y
+CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=0
+CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
+CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
+# CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set
+# CONFIG_SCSI_IPR is not set
+# CONFIG_SCSI_QLOGIC_FC is not set
+# CONFIG_SCSI_QLOGIC_1280 is not set
+CONFIG_SCSI_QLA2XXX=y
+# CONFIG_SCSI_QLA21XX is not set
+# CONFIG_SCSI_QLA22XX is not set
+# CONFIG_SCSI_QLA2300 is not set
+# CONFIG_SCSI_QLA2322 is not set
+# CONFIG_SCSI_QLA6312 is not set
+# CONFIG_SCSI_QLA24XX is not set
+# CONFIG_SCSI_LPFC is not set
+# CONFIG_SCSI_DC395x is not set
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_NSP32 is not set
+# CONFIG_SCSI_DEBUG is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+CONFIG_MD=y
+CONFIG_BLK_DEV_MD=m
+CONFIG_MD_LINEAR=m
+CONFIG_MD_RAID0=m
+CONFIG_MD_RAID1=m
+CONFIG_MD_RAID10=m
+CONFIG_MD_RAID5=m
+CONFIG_MD_RAID6=m
+CONFIG_MD_MULTIPATH=m
+CONFIG_MD_FAULTY=m
+CONFIG_BLK_DEV_DM=m
+CONFIG_DM_CRYPT=m
+CONFIG_DM_SNAPSHOT=m
+CONFIG_DM_MIRROR=m
+CONFIG_DM_ZERO=m
+CONFIG_DM_MULTIPATH=m
+CONFIG_DM_MULTIPATH_EMC=m
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+# CONFIG_FUSION_SPI is not set
+# CONFIG_FUSION_FC is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+
+#
+# Network device support
+#
CONFIG_NETDEVICES=y
CONFIG_DUMMY=m
CONFIG_BONDING=m
CONFIG_EQUALIZER=m
CONFIG_TUN=m
-# CONFIG_ETHERTAP is not set
#
# ARCnet devices
@@ -637,6 +733,21 @@ CONFIG_TUN=m
# CONFIG_ARCNET is not set
#
+# PHY device support
+#
+CONFIG_PHYLIB=m
+CONFIG_PHYCONTROL=y
+
+#
+# MII PHY device drivers
+#
+CONFIG_MARVELL_PHY=m
+CONFIG_DAVICOM_PHY=m
+CONFIG_QSEMI_PHY=m
+CONFIG_LXT_PHY=m
+CONFIG_CICADA_PHY=m
+
+#
# Ethernet (10 or 100Mbit)
#
CONFIG_NET_ETHERNET=y
@@ -681,13 +792,17 @@ CONFIG_LAN_SAA9730=y
# CONFIG_HAMACHI is not set
# CONFIG_YELLOWFIN is not set
# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
# CONFIG_SK98LIN is not set
# CONFIG_VIA_VELOCITY is not set
# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
#
# Ethernet (10000 Mbit)
#
+# CONFIG_CHELSIO_T1 is not set
# CONFIG_IXGB is not set
# CONFIG_S2IO is not set
@@ -700,6 +815,8 @@ CONFIG_LAN_SAA9730=y
# Wireless LAN (non-hamradio)
#
# CONFIG_NET_RADIO is not set
+# CONFIG_IPW_DEBUG is not set
+CONFIG_IPW2200=m
#
# Wan interfaces
@@ -712,6 +829,8 @@ CONFIG_LAN_SAA9730=y
# CONFIG_NET_FC is not set
# CONFIG_SHAPER is not set
# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
#
# ISDN subsystem
@@ -741,19 +860,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
# CONFIG_INPUT_EVBUG is not set
#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=y
-# CONFIG_SERIO_I8042 is not set
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_PCIPS2 is not set
-CONFIG_SERIO_LIBPS2=y
-CONFIG_SERIO_RAW=y
-
-#
# Input Device Drivers
#
# CONFIG_INPUT_KEYBOARD is not set
@@ -766,6 +872,17 @@ CONFIG_MOUSE_SERIAL=m
# CONFIG_INPUT_MISC is not set
#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_PCIPS2 is not set
+CONFIG_SERIO_LIBPS2=y
+CONFIG_SERIO_RAW=y
+# CONFIG_GAMEPORT is not set
+
+#
# Character devices
#
CONFIG_VT=y
@@ -786,6 +903,7 @@ CONFIG_SERIAL_8250_NR_UARTS=4
#
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
CONFIG_UNIX98_PTYS=y
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
@@ -812,6 +930,11 @@ CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_RAW_DRIVER is not set
#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+
+#
# I2C support
#
# CONFIG_I2C is not set
@@ -822,10 +945,20 @@ CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_W1 is not set
#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
+#
# Misc devices
#
#
+# Multimedia Capabilities Port drivers
+#
+
+#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
@@ -845,7 +978,6 @@ CONFIG_LEGACY_PTY_COUNT=256
#
# CONFIG_VGA_CONSOLE is not set
CONFIG_DUMMY_CONSOLE=y
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Sound
@@ -855,13 +987,9 @@ CONFIG_DUMMY_CONSOLE=y
#
# USB support
#
-# CONFIG_USB is not set
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB_ARCH_HAS_OHCI=y
-
-#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
-#
+# CONFIG_USB is not set
#
# USB Gadget Support
@@ -879,10 +1007,15 @@ CONFIG_USB_ARCH_HAS_OHCI=y
# CONFIG_INFINIBAND is not set
#
+# SN Devices
+#
+
+#
# File systems
#
CONFIG_EXT2_FS=y
# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
CONFIG_EXT3_FS=y
CONFIG_EXT3_FS_XATTR=y
# CONFIG_EXT3_FS_POSIX_ACL is not set
@@ -903,12 +1036,14 @@ CONFIG_JFS_SECURITY=y
# CONFIG_JFS_STATISTICS is not set
CONFIG_FS_POSIX_ACL=y
CONFIG_XFS_FS=m
-# CONFIG_XFS_RT is not set
-CONFIG_XFS_QUOTA=y
+CONFIG_XFS_EXPORT=y
+CONFIG_XFS_QUOTA=m
CONFIG_XFS_SECURITY=y
CONFIG_XFS_POSIX_ACL=y
+# CONFIG_XFS_RT is not set
CONFIG_MINIX_FS=m
CONFIG_ROMFS_FS=m
+CONFIG_INOTIFY=y
CONFIG_QUOTA=y
# CONFIG_QFMT_V1 is not set
CONFIG_QFMT_V2=y
@@ -916,6 +1051,7 @@ CONFIG_QUOTACTL=y
CONFIG_DNOTIFY=y
CONFIG_AUTOFS_FS=y
# CONFIG_AUTOFS4_FS is not set
+CONFIG_FUSE_FS=m
#
# CD-ROM/DVD Filesystems
@@ -943,12 +1079,10 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
-CONFIG_DEVPTS_FS_XATTR=y
-CONFIG_DEVPTS_FS_SECURITY=y
# CONFIG_TMPFS is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
+CONFIG_RELAYFS_FS=m
#
# Miscellaneous filesystems
@@ -974,16 +1108,19 @@ CONFIG_UFS_FS=m
#
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
# CONFIG_NFS_V4 is not set
# CONFIG_NFS_DIRECTIO is not set
CONFIG_NFSD=y
CONFIG_NFSD_V3=y
+# CONFIG_NFSD_V3_ACL is not set
# CONFIG_NFSD_V4 is not set
# CONFIG_NFSD_TCP is not set
CONFIG_ROOT_NFS=y
CONFIG_LOCKD=y
CONFIG_LOCKD_V4=y
CONFIG_EXPORTFS=y
+CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
@@ -992,6 +1129,7 @@ CONFIG_SUNRPC=y
# CONFIG_NCP_FS is not set
# CONFIG_CODA_FS is not set
# CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
#
# Partition Types
@@ -1051,7 +1189,9 @@ CONFIG_NLS_UTF8=m
#
# Kernel hacking
#
+# CONFIG_PRINTK_TIME is not set
# CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=14
CONFIG_CROSSCOMPILE=y
CONFIG_CMDLINE=""
@@ -1073,6 +1213,7 @@ CONFIG_CRYPTO_SHA1=m
CONFIG_CRYPTO_SHA256=m
CONFIG_CRYPTO_SHA512=m
CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_TGR192=m
CONFIG_CRYPTO_DES=m
CONFIG_CRYPTO_BLOWFISH=m
CONFIG_CRYPTO_TWOFISH=m
@@ -1097,9 +1238,12 @@ CONFIG_CRYPTO_CRC32C=m
# Library routines
#
# CONFIG_CRC_CCITT is not set
+CONFIG_CRC16=m
CONFIG_CRC32=y
CONFIG_LIBCRC32C=m
CONFIG_ZLIB_INFLATE=m
CONFIG_ZLIB_DEFLATE=m
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_TEXTSEARCH=y
+CONFIG_TEXTSEARCH_KMP=m
+CONFIG_TEXTSEARCH_BM=m
+CONFIG_TEXTSEARCH_FSM=m
diff --git a/arch/mips/configs/bigsur_defconfig b/arch/mips/configs/bigsur_defconfig
new file mode 100644
index 000000000000..25e8a08e68be
--- /dev/null
+++ b/arch/mips/configs/bigsur_defconfig
@@ -0,0 +1,881 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.14-rc2
+# Thu Oct 20 22:25:17 2005
+#
+CONFIG_MIPS=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+# CONFIG_HOTPLUG is not set
+CONFIG_KOBJECT_UEVENT=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+# CONFIG_CPUSETS is not set
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_OBSOLETE_MODPARM=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_KMOD=y
+CONFIG_STOP_MACHINE=y
+
+#
+# Machine selection
+#
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_MIPS_PB1550 is not set
+# CONFIG_MIPS_PB1200 is not set
+# CONFIG_MIPS_DB1000 is not set
+# CONFIG_MIPS_DB1100 is not set
+# CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
+# CONFIG_MIPS_DB1200 is not set
+# CONFIG_MIPS_MIRAGE is not set
+# CONFIG_MIPS_COBALT is not set
+# CONFIG_MACH_DECSTATION is not set
+# CONFIG_MIPS_EV64120 is not set
+# CONFIG_MIPS_EV96100 is not set
+# CONFIG_MIPS_IVR is not set
+# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_LASAT is not set
+# CONFIG_MIPS_ATLAS is not set
+# CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SEAD is not set
+# CONFIG_MIPS_SIM is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_MOMENCO_OCELOT_3 is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MIPS_XXS1500 is not set
+# CONFIG_PNX8550_V2PCI is not set
+# CONFIG_PNX8550_JBS is not set
+# CONFIG_DDB5074 is not set
+# CONFIG_DDB5476 is not set
+# CONFIG_DDB5477 is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_QEMU is not set
+# CONFIG_SGI_IP22 is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+CONFIG_SIBYTE_BIGSUR=y
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_PTSWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CRHONE is not set
+# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_TOSHIBA_RBTX4927 is not set
+# CONFIG_TOSHIBA_RBTX4938 is not set
+CONFIG_SIBYTE_BCM1x80=y
+CONFIG_SIBYTE_SB1xxx_SOC=y
+# CONFIG_CPU_SB1_PASS_1 is not set
+# CONFIG_CPU_SB1_PASS_2_1250 is not set
+# CONFIG_CPU_SB1_PASS_2_2 is not set
+# CONFIG_CPU_SB1_PASS_4 is not set
+# CONFIG_CPU_SB1_PASS_2_112x is not set
+# CONFIG_CPU_SB1_PASS_3 is not set
+# CONFIG_SIMULATION is not set
+# CONFIG_CONFIG_SB1_CEX_ALWAYS_FATAL is not set
+# CONFIG_CONFIG_SB1_CERR_STALL is not set
+CONFIG_SIBYTE_CFE=y
+# CONFIG_SIBYTE_CFE_CONSOLE is not set
+# CONFIG_SIBYTE_BUS_WATCHER is not set
+# CONFIG_SIBYTE_SB1250_PROF is not set
+# CONFIG_SIBYTE_TBPROF is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_DMA_COHERENT=y
+CONFIG_CPU_BIG_ENDIAN=y
+# CONFIG_CPU_LITTLE_ENDIAN is not set
+CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
+CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
+CONFIG_SWAP_IO_SPACE=y
+CONFIG_BOOT_ELF32=y
+CONFIG_MIPS_L1_CACHE_SHIFT=5
+
+#
+# CPU selection
+#
+# CONFIG_CPU_MIPS32_R1 is not set
+# CONFIG_CPU_MIPS32_R2 is not set
+# CONFIG_CPU_MIPS64_R1 is not set
+# CONFIG_CPU_MIPS64_R2 is not set
+# CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_TX39XX is not set
+# CONFIG_CPU_VR41XX is not set
+# CONFIG_CPU_R4300 is not set
+# CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_TX49XX is not set
+# CONFIG_CPU_R5000 is not set
+# CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_R6000 is not set
+# CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
+# CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_RM7000 is not set
+# CONFIG_CPU_RM9000 is not set
+CONFIG_CPU_SB1=y
+CONFIG_SYS_HAS_CPU_SB1=y
+CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
+CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y
+
+#
+# Kernel type
+#
+# CONFIG_32BIT is not set
+CONFIG_64BIT=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_SIBYTE_DMA_PAGEOPS is not set
+# CONFIG_MIPS_MT is not set
+CONFIG_CPU_HAS_LLSC=y
+CONFIG_CPU_HAS_LLDSCD=y
+CONFIG_CPU_HAS_SYNC=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_CPU_SUPPORTS_HIGHMEM=y
+CONFIG_ARCH_FLATMEM_ENABLE=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_SMP=y
+CONFIG_NR_CPUS=4
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+# CONFIG_PREEMPT_BKL is not set
+
+#
+# Bus options (PCI, PCMCIA, EISA, ISA, TC)
+#
+CONFIG_HW_HAS_PCI=y
+CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
+CONFIG_PCI_LEGACY_PROC=y
+CONFIG_PCI_DEBUG=y
+CONFIG_MMU=y
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PCI Hotplug Support
+#
+# CONFIG_HOTPLUG_PCI is not set
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+CONFIG_BUILD_ELF64=y
+CONFIG_MIPS32_COMPAT=y
+CONFIG_COMPAT=y
+CONFIG_MIPS32_O32=y
+# CONFIG_MIPS32_N32 is not set
+CONFIG_BINFMT_ELF32=y
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+CONFIG_NET_KEY=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+CONFIG_INET_TUNNEL=m
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+# CONFIG_IPV6 is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# 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_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+# CONFIG_DEBUG_DRIVER is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+
+#
+# Block devices
+#
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=m
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+CONFIG_BLK_DEV_NBD=m
+# CONFIG_BLK_DEV_SX8 is not set
+# CONFIG_BLK_DEV_RAM is not set
+CONFIG_BLK_DEV_RAM_COUNT=16
+# CONFIG_CDROM_PKTCDVD is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_ATA_OVER_ETH is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+CONFIG_IDE=y
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_IDE_SATA is not set
+CONFIG_BLK_DEV_IDEDISK=y
+# CONFIG_IDEDISK_MULTI_MODE is not set
+CONFIG_BLK_DEV_IDECD=y
+CONFIG_BLK_DEV_IDETAPE=y
+CONFIG_BLK_DEV_IDEFLOPPY=y
+# CONFIG_IDE_TASK_IOCTL is not set
+
+#
+# IDE chipset support/bugfixes
+#
+CONFIG_IDE_GENERIC=y
+# CONFIG_BLK_DEV_IDEPCI is not set
+# CONFIG_BLK_DEV_IDE_SWARM is not set
+# CONFIG_IDE_ARM is not set
+# CONFIG_BLK_DEV_IDEDMA is not set
+# CONFIG_IDEDMA_AUTO is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
+#
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_NET_VENDOR_3COM is not set
+
+#
+# Tulip family network device support
+#
+# CONFIG_NET_TULIP is not set
+# CONFIG_HP100 is not set
+# CONFIG_NET_PCI is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+CONFIG_NET_SB1250_MAC=y
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
+
+#
+# Ethernet (10000 Mbit)
+#
+# CONFIG_CHELSIO_T1 is not set
+# CONFIG_IXGB is not set
+# CONFIG_S2IO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+# CONFIG_INPUT is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_PCIPS2 is not set
+# CONFIG_SERIO_LIBPS2 is not set
+CONFIG_SERIO_RAW=m
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+CONFIG_SERIAL_NONSTANDARD=y
+# CONFIG_ROCKETPORT is not set
+# CONFIG_CYCLADES is not set
+# CONFIG_DIGIEPCA is not set
+# CONFIG_MOXA_SMARTIO is not set
+# CONFIG_ISI is not set
+# CONFIG_SYNCLINKMP is not set
+# CONFIG_N_HDLC is not set
+# CONFIG_SPECIALIX is not set
+# CONFIG_SX is not set
+# CONFIG_STALDRV is not set
+CONFIG_SIBYTE_SB1250_DUART=y
+CONFIG_SIBYTE_SB1250_DUART_CONSOLE=y
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_JSM is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_RTC is not set
+CONFIG_GEN_RTC=y
+# CONFIG_GEN_RTC_X is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_DRM is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+
+#
+# I2C support
+#
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+
+#
+# I2C Algorithms
+#
+# CONFIG_I2C_ALGOBIT is not set
+# CONFIG_I2C_ALGOPCF is not set
+# CONFIG_I2C_ALGOPCA is not set
+CONFIG_I2C_ALGO_SIBYTE=y
+
+#
+# I2C Hardware Bus support
+#
+# 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_PIIX4 is not set
+# CONFIG_I2C_NFORCE2 is not set
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_PROSAVAGE is not set
+# CONFIG_I2C_SAVAGE4 is not set
+CONFIG_I2C_SIBYTE=y
+# CONFIG_SCx200_ACB is not set
+# CONFIG_I2C_SIS5595 is not set
+# CONFIG_I2C_SIS630 is not set
+# CONFIG_I2C_SIS96X is not set
+# CONFIG_I2C_STUB is not set
+# CONFIG_I2C_VIA is not set
+# CONFIG_I2C_VIAPRO is not set
+# CONFIG_I2C_VOODOO3 is not set
+# CONFIG_I2C_PCA_ISA is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+CONFIG_SENSORS_DS1337=y
+CONFIG_SENSORS_DS1374=y
+CONFIG_SENSORS_EEPROM=y
+CONFIG_SENSORS_PCF8574=y
+CONFIG_SENSORS_PCA9539=y
+CONFIG_SENSORS_PCF8591=y
+CONFIG_SENSORS_RTC8564=y
+CONFIG_SENSORS_MAX6875=y
+CONFIG_I2C_DEBUG_CORE=y
+CONFIG_I2C_DEBUG_ALGO=y
+CONFIG_I2C_DEBUG_BUS=y
+CONFIG_I2C_DEBUG_CHIP=y
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
+#
+# Misc devices
+#
+
+#
+# Multimedia Capabilities Port drivers
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+# CONFIG_FB is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+# CONFIG_USB is not set
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
+# SN Devices
+#
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+# CONFIG_EXT2_FS_XIP is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+# CONFIG_XFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_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_KCORE=y
+CONFIG_SYSFS=y
+# CONFIG_TMPFS is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+# CONFIG_RELAYFS_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_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFS_DIRECTIO is not set
+# CONFIG_NFSD is not set
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_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
+# CONFIG_9P_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+
+#
+# Native Language Support
+#
+# CONFIG_NLS is not set
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+CONFIG_PRINTK_TIME=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_LOG_BUF_SHIFT=16
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_FS is not set
+CONFIG_CROSSCOMPILE=y
+CONFIG_CMDLINE=""
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_KGDB is not set
+# CONFIG_SB1XXX_CORELIS is not set
+# CONFIG_RUNTIME_DEBUG is not set
+
+#
+# Security options
+#
+CONFIG_KEYS=y
+CONFIG_KEYS_DEBUG_PROC_KEYS=y
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_NULL=y
+CONFIG_CRYPTO_MD4=y
+CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_SHA1=y
+CONFIG_CRYPTO_SHA256=y
+CONFIG_CRYPTO_SHA512=y
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_DES=y
+CONFIG_CRYPTO_BLOWFISH=y
+CONFIG_CRYPTO_TWOFISH=y
+CONFIG_CRYPTO_SERPENT=y
+CONFIG_CRYPTO_AES=m
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+CONFIG_CRYPTO_TEA=m
+# CONFIG_CRYPTO_ARC4 is not set
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_DEFLATE=y
+CONFIG_CRYPTO_MICHAEL_MIC=y
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Hardware crypto devices
+#
+
+#
+# Library routines
+#
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+CONFIG_CRC32=y
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
diff --git a/arch/mips/configs/capcella_defconfig b/arch/mips/configs/capcella_defconfig
index 158e7165f4e3..bfbaa08c47cb 100644
--- a/arch/mips/configs/capcella_defconfig
+++ b/arch/mips/configs/capcella_defconfig
@@ -1,12 +1,9 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-rc2
-# Wed Jan 26 02:49:00 2005
+# Linux kernel version: 2.6.14-rc2
+# Thu Oct 20 22:25:20 2005
#
CONFIG_MIPS=y
-# CONFIG_64BIT is not set
-# CONFIG_64BIT is not set
-CONFIG_32BIT=y
#
# Code maturity level options
@@ -14,24 +11,29 @@ CONFIG_32BIT=y
CONFIG_EXPERIMENTAL=y
CONFIG_CLEAN_COMPILE=y
CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
#
# General setup
#
CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
# CONFIG_POSIX_MQUEUE is not set
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_HOTPLUG is not set
+CONFIG_HOTPLUG=y
CONFIG_KOBJECT_UEVENT=y
# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
CONFIG_EMBEDDED=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
@@ -41,6 +43,7 @@ CONFIG_CC_ALIGN_LABELS=0
CONFIG_CC_ALIGN_LOOPS=0
CONFIG_CC_ALIGN_JUMPS=0
# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
#
# Loadable module support
@@ -56,57 +59,86 @@ CONFIG_KMOD=y
#
# Machine selection
#
-# CONFIG_MACH_JAZZ is not set
-CONFIG_MACH_VR41XX=y
-# CONFIG_NEC_CMBVR4133 is not set
-# CONFIG_CASIO_E55 is not set
-# CONFIG_IBM_WORKPAD is not set
-# CONFIG_TANBAC_TB0226 is not set
-# CONFIG_TANBAC_TB0229 is not set
-# CONFIG_VICTOR_MPC30X is not set
-CONFIG_ZAO_CAPCELLA=y
-CONFIG_PCI_VR41XX=y
-CONFIG_VRC4173=y
-# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_MIPS_PB1550 is not set
+# CONFIG_MIPS_PB1200 is not set
+# CONFIG_MIPS_DB1000 is not set
+# CONFIG_MIPS_DB1100 is not set
+# CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
+# CONFIG_MIPS_DB1200 is not set
+# CONFIG_MIPS_MIRAGE is not set
# CONFIG_MIPS_COBALT is not set
# CONFIG_MACH_DECSTATION is not set
# CONFIG_MIPS_EV64120 is not set
# CONFIG_MIPS_EV96100 is not set
# CONFIG_MIPS_IVR is not set
-# CONFIG_LASAT is not set
# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_LASAT is not set
# CONFIG_MIPS_ATLAS is not set
# CONFIG_MIPS_MALTA is not set
# CONFIG_MIPS_SEAD is not set
+# CONFIG_MIPS_SIM is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
# CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_G is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_JAGUAR_ATX is not set
-# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MIPS_XXS1500 is not set
+# CONFIG_PNX8550_V2PCI is not set
+# CONFIG_PNX8550_JBS is not set
# CONFIG_DDB5074 is not set
# CONFIG_DDB5476 is not set
# CONFIG_DDB5477 is not set
-# CONFIG_NEC_OSPREY is not set
+CONFIG_MACH_VR41XX=y
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_QEMU is not set
# CONFIG_SGI_IP22 is not set
-# CONFIG_SOC_AU1X00 is not set
-# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_BIGSUR is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_PTSWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CRHONE is not set
# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
# CONFIG_TOSHIBA_RBTX4927 is not set
+# CONFIG_TOSHIBA_RBTX4938 is not set
+# CONFIG_NEC_CMBVR4133 is not set
+# CONFIG_CASIO_E55 is not set
+# CONFIG_IBM_WORKPAD is not set
+# CONFIG_TANBAC_TB022X is not set
+# CONFIG_VICTOR_MPC30X is not set
+CONFIG_ZAO_CAPCELLA=y
+CONFIG_PCI_VR41XX=y
+# CONFIG_VRC4173 is not set
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_HAVE_DEC_LOCK=y
CONFIG_DMA_NONCOHERENT=y
CONFIG_DMA_NEED_PCI_MAP_STATE=y
+# CONFIG_CPU_BIG_ENDIAN is not set
CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
CONFIG_IRQ_CPU=y
CONFIG_MIPS_L1_CACHE_SHIFT=5
#
# CPU selection
#
-# CONFIG_CPU_MIPS32 is not set
-# CONFIG_CPU_MIPS64 is not set
+# CONFIG_CPU_MIPS32_R1 is not set
+# CONFIG_CPU_MIPS32_R2 is not set
+# CONFIG_CPU_MIPS64_R1 is not set
+# CONFIG_CPU_MIPS64_R2 is not set
# CONFIG_CPU_R3000 is not set
# CONFIG_CPU_TX39XX is not set
CONFIG_CPU_VR41XX=y
@@ -122,12 +154,36 @@ CONFIG_CPU_VR41XX=y
# CONFIG_CPU_RM7000 is not set
# CONFIG_CPU_RM9000 is not set
# CONFIG_CPU_SB1 is not set
+CONFIG_SYS_HAS_CPU_VR41XX=y
+CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
+CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y
+
+#
+# Kernel type
+#
+CONFIG_32BIT=y
+# CONFIG_64BIT is not set
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_MIPS_MT is not set
# CONFIG_CPU_ADVANCED is not set
CONFIG_CPU_HAS_SYNC=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_ARCH_FLATMEM_ENABLE=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_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
#
@@ -136,7 +192,6 @@ CONFIG_CPU_HAS_SYNC=y
CONFIG_HW_HAS_PCI=y
CONFIG_PCI=y
CONFIG_PCI_LEGACY_PROC=y
-CONFIG_PCI_NAMES=y
CONFIG_MMU=y
#
@@ -145,10 +200,6 @@ CONFIG_MMU=y
# CONFIG_PCCARD is not set
#
-# PC-card bridges
-#
-
-#
# PCI Hotplug Support
#
# CONFIG_HOTPLUG_PCI is not set
@@ -161,6 +212,81 @@ CONFIG_BINFMT_ELF=y
CONFIG_TRAD_SIGNALS=y
#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+CONFIG_NET_KEY=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+CONFIG_INET_TUNNEL=m
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+# CONFIG_IPV6 is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# 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_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_IEEE80211=m
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=m
+CONFIG_IEEE80211_CRYPT_CCMP=m
+CONFIG_IEEE80211_CRYPT_TKIP=m
+
+#
# Device Drivers
#
@@ -169,7 +295,12 @@ CONFIG_TRAD_SIGNALS=y
#
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
+CONFIG_FW_LOADER=m
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+CONFIG_CONNECTOR=m
#
# Memory Technology Devices (MTD)
@@ -188,7 +319,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
#
# Block devices
#
-# CONFIG_BLK_DEV_FD is not set
# CONFIG_BLK_CPQ_DA is not set
# CONFIG_BLK_CPQ_CISS_DA is not set
# CONFIG_BLK_DEV_DAC960 is not set
@@ -199,11 +329,8 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_BLK_DEV_SX8 is not set
# CONFIG_BLK_DEV_RAM is not set
CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_INITRAMFS_SOURCE=""
# CONFIG_LBD is not set
-CONFIG_CDROM_PKTCDVD=m
-CONFIG_CDROM_PKTCDVD_BUFFERS=8
-# CONFIG_CDROM_PKTCDVD_WCACHE is not set
+# CONFIG_CDROM_PKTCDVD is not set
#
# IO Schedulers
@@ -244,6 +371,7 @@ CONFIG_IDE_GENERIC=y
#
# SCSI device support
#
+# CONFIG_RAID_ATTRS is not set
# CONFIG_SCSI is not set
#
@@ -254,6 +382,7 @@ CONFIG_IDE_GENERIC=y
#
# Fusion MPT device support
#
+# CONFIG_FUSION is not set
#
# IEEE 1394 (FireWire) support
@@ -266,79 +395,13 @@ CONFIG_IDE_GENERIC=y
# CONFIG_I2O is not set
#
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
-CONFIG_NETLINK_DEV=y
-CONFIG_UNIX=y
-CONFIG_NET_KEY=y
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-# CONFIG_IP_ADVANCED_ROUTER is not set
-CONFIG_IP_PNP=y
-# CONFIG_IP_PNP_DHCP is not set
-CONFIG_IP_PNP_BOOTP=y
-# CONFIG_IP_PNP_RARP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_IP_MROUTE is not set
-# CONFIG_ARPD is not set
-# CONFIG_SYN_COOKIES is not set
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-CONFIG_INET_TUNNEL=m
-CONFIG_IP_TCPDIAG=m
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-# CONFIG_IPV6 is not set
-# CONFIG_NETFILTER is not set
-CONFIG_XFRM=y
-CONFIG_XFRM_USER=m
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP 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_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
-
-#
-# Network testing
+# Network device support
#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
CONFIG_NETDEVICES=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_EQUALIZER is not set
# CONFIG_TUN is not set
-# CONFIG_ETHERTAP is not set
#
# ARCnet devices
@@ -346,10 +409,25 @@ CONFIG_NETDEVICES=y
# CONFIG_ARCNET is not set
#
+# PHY device support
+#
+CONFIG_PHYLIB=m
+CONFIG_PHYCONTROL=y
+
+#
+# MII PHY device drivers
+#
+CONFIG_MARVELL_PHY=m
+CONFIG_DAVICOM_PHY=m
+CONFIG_QSEMI_PHY=m
+CONFIG_LXT_PHY=m
+CONFIG_CICADA_PHY=m
+
+#
# Ethernet (10 or 100Mbit)
#
CONFIG_NET_ETHERNET=y
-# CONFIG_MII is not set
+CONFIG_MII=y
# CONFIG_HAPPYMEAL is not set
# CONFIG_SUNGEM is not set
# CONFIG_NET_VENDOR_3COM is not set
@@ -359,7 +437,30 @@ CONFIG_NET_ETHERNET=y
#
# CONFIG_NET_TULIP is not set
# CONFIG_HP100 is not set
-# CONFIG_NET_PCI is not set
+CONFIG_NET_PCI=y
+# CONFIG_PCNET32 is not set
+# CONFIG_AMD8111_ETH is not set
+# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_B44 is not set
+# CONFIG_FORCEDETH is not set
+# CONFIG_DGRS is not set
+# CONFIG_EEPRO100 is not set
+# CONFIG_E100 is not set
+# CONFIG_FEALNX is not set
+# CONFIG_NATSEMI is not set
+# CONFIG_NE2K_PCI is not set
+# CONFIG_8139CP is not set
+CONFIG_8139TOO=y
+CONFIG_8139TOO_PIO=y
+# CONFIG_8139TOO_TUNE_TWISTER is not set
+# CONFIG_8139TOO_8129 is not set
+# CONFIG_8139_OLD_RX_RESET is not set
+# CONFIG_SIS900 is not set
+# CONFIG_EPIC100 is not set
+# CONFIG_SUNDANCE is not set
+# CONFIG_TLAN is not set
+# CONFIG_VIA_RHINE is not set
+# CONFIG_LAN_SAA9730 is not set
#
# Ethernet (1000 Mbit)
@@ -371,12 +472,17 @@ CONFIG_NET_ETHERNET=y
# CONFIG_HAMACHI is not set
# CONFIG_YELLOWFIN is not set
# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
# CONFIG_SK98LIN is not set
+# CONFIG_VIA_VELOCITY is not set
# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
#
# Ethernet (10000 Mbit)
#
+# CONFIG_CHELSIO_T1 is not set
# CONFIG_IXGB is not set
# CONFIG_S2IO is not set
@@ -389,6 +495,8 @@ CONFIG_NET_ETHERNET=y
# Wireless LAN (non-hamradio)
#
# CONFIG_NET_RADIO is not set
+# CONFIG_IPW_DEBUG is not set
+CONFIG_IPW2200=m
#
# Wan interfaces
@@ -400,6 +508,8 @@ CONFIG_NET_ETHERNET=y
# CONFIG_SLIP is not set
# CONFIG_SHAPER is not set
# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
#
# ISDN subsystem
@@ -419,29 +529,13 @@ CONFIG_INPUT=y
#
# Userland interfaces
#
-CONFIG_INPUT_MOUSEDEV=y
-CONFIG_INPUT_MOUSEDEV_PSAUX=y
-CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_MOUSEDEV is not set
# CONFIG_INPUT_JOYDEV is not set
# CONFIG_INPUT_TSDEV is not set
# CONFIG_INPUT_EVDEV is not set
# CONFIG_INPUT_EVBUG is not set
#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=y
-CONFIG_SERIO_I8042=y
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_PCIPS2 is not set
-CONFIG_SERIO_LIBPS2=m
-CONFIG_SERIO_RAW=m
-
-#
# Input Device Drivers
#
# CONFIG_INPUT_KEYBOARD is not set
@@ -451,6 +545,12 @@ CONFIG_SERIO_RAW=m
# CONFIG_INPUT_MISC is not set
#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
# Character devices
#
CONFIG_VT=y
@@ -461,16 +561,16 @@ CONFIG_HW_CONSOLE=y
#
# Serial drivers
#
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_NR_UARTS=4
-# CONFIG_SERIAL_8250_EXTENDED is not set
+# CONFIG_SERIAL_8250 is not set
#
# Non-8250 serial port support
#
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_SERIAL_VR41XX=y
+CONFIG_SERIAL_VR41XX_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
CONFIG_UNIX98_PTYS=y
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
@@ -483,19 +583,7 @@ CONFIG_LEGACY_PTY_COUNT=256
#
# Watchdog Cards
#
-CONFIG_WATCHDOG=y
-# CONFIG_WATCHDOG_NOWAYOUT is not set
-
-#
-# Watchdog Device Drivers
-#
-# CONFIG_SOFT_WATCHDOG is not set
-
-#
-# PCI-based Watchdog Cards
-#
-# CONFIG_PCIPCWATCHDOG is not set
-# CONFIG_WDTPCI is not set
+# CONFIG_WATCHDOG is not set
# CONFIG_RTC is not set
# CONFIG_GEN_RTC is not set
# CONFIG_DTLK is not set
@@ -506,9 +594,15 @@ CONFIG_WATCHDOG=y
# Ftape, the floppy tape device driver
#
# CONFIG_DRM is not set
+CONFIG_GPIO_VR41XX=y
# CONFIG_RAW_DRIVER is not set
#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+
+#
# I2C support
#
# CONFIG_I2C is not set
@@ -519,10 +613,20 @@ CONFIG_WATCHDOG=y
# CONFIG_W1 is not set
#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
+#
# Misc devices
#
#
+# Multimedia Capabilities Port drivers
+#
+
+#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
@@ -542,7 +646,6 @@ CONFIG_WATCHDOG=y
#
# CONFIG_VGA_CONSOLE is not set
CONFIG_DUMMY_CONSOLE=y
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Sound
@@ -552,13 +655,9 @@ CONFIG_DUMMY_CONSOLE=y
#
# USB support
#
-# CONFIG_USB is not set
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB_ARCH_HAS_OHCI=y
-
-#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
-#
+# CONFIG_USB is not set
#
# USB Gadget Support
@@ -576,21 +675,29 @@ CONFIG_USB_ARCH_HAS_OHCI=y
# CONFIG_INFINIBAND is not set
#
+# SN Devices
+#
+
+#
# File systems
#
CONFIG_EXT2_FS=y
# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
# CONFIG_EXT3_FS is not set
# CONFIG_JBD 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_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
# CONFIG_QUOTA is not set
CONFIG_DNOTIFY=y
CONFIG_AUTOFS_FS=y
CONFIG_AUTOFS4_FS=y
+CONFIG_FUSE_FS=m
#
# CD-ROM/DVD Filesystems
@@ -611,12 +718,10 @@ CONFIG_AUTOFS4_FS=y
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
-CONFIG_DEVPTS_FS_XATTR=y
-CONFIG_DEVPTS_FS_SECURITY=y
# CONFIG_TMPFS is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
+CONFIG_RELAYFS_FS=m
#
# Miscellaneous filesystems
@@ -648,6 +753,7 @@ CONFIG_NFSD=y
CONFIG_ROOT_NFS=y
CONFIG_LOCKD=y
CONFIG_EXPORTFS=y
+CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
@@ -656,6 +762,7 @@ CONFIG_SUNRPC=y
# CONFIG_NCP_FS is not set
# CONFIG_CODA_FS is not set
# CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
#
# Partition Types
@@ -676,9 +783,11 @@ CONFIG_MSDOS_PARTITION=y
#
# Kernel hacking
#
+# CONFIG_PRINTK_TIME is not set
# CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=14
CONFIG_CROSSCOMPILE=y
-CONFIG_CMDLINE=""
+CONFIG_CMDLINE="mem=32M console=ttyVR0,38400"
#
# Security options
@@ -690,7 +799,31 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
#
# Cryptographic options
#
-# CONFIG_CRYPTO is not set
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_AES=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_CRC32C=m
+# CONFIG_CRYPTO_TEST is not set
#
# Hardware crypto devices
@@ -700,7 +833,8 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
# Library routines
#
# CONFIG_CRC_CCITT is not set
-# CONFIG_CRC32 is not set
+CONFIG_CRC16=m
+CONFIG_CRC32=y
CONFIG_LIBCRC32C=m
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_ZLIB_INFLATE=m
+CONFIG_ZLIB_DEFLATE=m
diff --git a/arch/mips/configs/cobalt_defconfig b/arch/mips/configs/cobalt_defconfig
index 4302c6f914f5..4b4d1ddb3d42 100644
--- a/arch/mips/configs/cobalt_defconfig
+++ b/arch/mips/configs/cobalt_defconfig
@@ -1,12 +1,9 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-rc2
-# Wed Jan 26 02:49:00 2005
+# Linux kernel version: 2.6.14-rc2
+# Thu Oct 20 22:25:23 2005
#
CONFIG_MIPS=y
-# CONFIG_64BIT is not set
-# CONFIG_64BIT is not set
-CONFIG_32BIT=y
#
# Code maturity level options
@@ -14,24 +11,29 @@ CONFIG_32BIT=y
CONFIG_EXPERIMENTAL=y
CONFIG_CLEAN_COMPILE=y
CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
#
# General setup
#
CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
# CONFIG_POSIX_MQUEUE is not set
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
CONFIG_HOTPLUG=y
CONFIG_KOBJECT_UEVENT=y
# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
CONFIG_EMBEDDED=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
@@ -41,6 +43,7 @@ CONFIG_CC_ALIGN_LABELS=0
CONFIG_CC_ALIGN_LOOPS=0
CONFIG_CC_ALIGN_JUMPS=0
# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
#
# Loadable module support
@@ -50,41 +53,69 @@ CONFIG_CC_ALIGN_JUMPS=0
#
# Machine selection
#
-# CONFIG_MACH_JAZZ is not set
-# CONFIG_MACH_VR41XX is not set
-# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_MIPS_PB1550 is not set
+# CONFIG_MIPS_PB1200 is not set
+# CONFIG_MIPS_DB1000 is not set
+# CONFIG_MIPS_DB1100 is not set
+# CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
+# CONFIG_MIPS_DB1200 is not set
+# CONFIG_MIPS_MIRAGE is not set
CONFIG_MIPS_COBALT=y
# CONFIG_MACH_DECSTATION is not set
# CONFIG_MIPS_EV64120 is not set
# CONFIG_MIPS_EV96100 is not set
# CONFIG_MIPS_IVR is not set
-# CONFIG_LASAT is not set
# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_LASAT is not set
# CONFIG_MIPS_ATLAS is not set
# CONFIG_MIPS_MALTA is not set
# CONFIG_MIPS_SEAD is not set
+# CONFIG_MIPS_SIM is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
# CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_G is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_JAGUAR_ATX is not set
-# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MIPS_XXS1500 is not set
+# CONFIG_PNX8550_V2PCI is not set
+# CONFIG_PNX8550_JBS is not set
# CONFIG_DDB5074 is not set
# CONFIG_DDB5476 is not set
# CONFIG_DDB5477 is not set
-# CONFIG_NEC_OSPREY is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_QEMU is not set
# CONFIG_SGI_IP22 is not set
-# CONFIG_SOC_AU1X00 is not set
-# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_BIGSUR is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_PTSWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CRHONE is not set
# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
# CONFIG_TOSHIBA_RBTX4927 is not set
+# CONFIG_TOSHIBA_RBTX4938 is not set
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_HAVE_DEC_LOCK=y
CONFIG_DMA_NONCOHERENT=y
CONFIG_DMA_NEED_PCI_MAP_STATE=y
CONFIG_I8259=y
+# CONFIG_CPU_BIG_ENDIAN is not set
CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
CONFIG_IRQ_CPU=y
CONFIG_MIPS_GT64111=y
CONFIG_MIPS_L1_CACHE_SHIFT=5
@@ -92,8 +123,10 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5
#
# CPU selection
#
-# CONFIG_CPU_MIPS32 is not set
-# CONFIG_CPU_MIPS64 is not set
+# CONFIG_CPU_MIPS32_R1 is not set
+# CONFIG_CPU_MIPS32_R2 is not set
+# CONFIG_CPU_MIPS64_R1 is not set
+# CONFIG_CPU_MIPS64_R2 is not set
# CONFIG_CPU_R3000 is not set
# CONFIG_CPU_TX39XX is not set
# CONFIG_CPU_VR41XX is not set
@@ -109,14 +142,38 @@ CONFIG_CPU_NEVADA=y
# CONFIG_CPU_RM7000 is not set
# CONFIG_CPU_RM9000 is not set
# CONFIG_CPU_SB1 is not set
+CONFIG_SYS_HAS_CPU_NEVADA=y
+CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
+CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y
+
+#
+# Kernel type
+#
+CONFIG_32BIT=y
+# CONFIG_64BIT is not set
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_MIPS_MT is not set
# CONFIG_CPU_ADVANCED is not set
CONFIG_CPU_HAS_LLSC=y
CONFIG_CPU_HAS_LLDSCD=y
CONFIG_CPU_HAS_SYNC=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_ARCH_FLATMEM_ENABLE=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_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
#
@@ -125,7 +182,6 @@ CONFIG_CPU_HAS_SYNC=y
CONFIG_HW_HAS_PCI=y
CONFIG_PCI=y
CONFIG_PCI_LEGACY_PROC=y
-CONFIG_PCI_NAMES=y
CONFIG_MMU=y
#
@@ -134,10 +190,6 @@ CONFIG_MMU=y
# CONFIG_PCCARD is not set
#
-# PC-card bridges
-#
-
-#
# PCI Hotplug Support
#
# CONFIG_HOTPLUG_PCI is not set
@@ -150,6 +202,77 @@ CONFIG_BINFMT_ELF=y
CONFIG_TRAD_SIGNALS=y
#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=y
+CONFIG_NET_KEY=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+# CONFIG_IP_PNP 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_TUNNEL=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+# CONFIG_IPV6 is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# 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_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_IEEE80211=y
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=y
+CONFIG_IEEE80211_CRYPT_CCMP=y
+CONFIG_IEEE80211_CRYPT_TKIP=y
+
+#
# Device Drivers
#
@@ -161,6 +284,11 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
CONFIG_FW_LOADER=y
#
+# Connector - unified userspace <-> kernelspace linker
+#
+CONFIG_CONNECTOR=y
+
+#
# Memory Technology Devices (MTD)
#
# CONFIG_MTD is not set
@@ -177,7 +305,6 @@ CONFIG_FW_LOADER=y
#
# Block devices
#
-# CONFIG_BLK_DEV_FD is not set
# CONFIG_BLK_CPQ_DA is not set
# CONFIG_BLK_CPQ_CISS_DA is not set
# CONFIG_BLK_DEV_DAC960 is not set
@@ -189,7 +316,6 @@ CONFIG_BLK_DEV_LOOP=y
# CONFIG_BLK_DEV_SX8 is not set
# CONFIG_BLK_DEV_RAM is not set
CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_INITRAMFS_SOURCE=""
# CONFIG_LBD is not set
CONFIG_CDROM_PKTCDVD=y
CONFIG_CDROM_PKTCDVD_BUFFERS=8
@@ -234,6 +360,7 @@ CONFIG_IDE_GENERIC=y
#
# SCSI device support
#
+CONFIG_RAID_ATTRS=y
# CONFIG_SCSI is not set
#
@@ -244,6 +371,7 @@ CONFIG_IDE_GENERIC=y
#
# Fusion MPT device support
#
+# CONFIG_FUSION is not set
#
# IEEE 1394 (FireWire) support
@@ -256,75 +384,13 @@ CONFIG_IDE_GENERIC=y
# CONFIG_I2O is not set
#
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
-CONFIG_NETLINK_DEV=y
-CONFIG_UNIX=y
-CONFIG_NET_KEY=y
-CONFIG_INET=y
-# CONFIG_IP_MULTICAST is not set
-# CONFIG_IP_ADVANCED_ROUTER is not set
-# CONFIG_IP_PNP 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_TUNNEL=y
-CONFIG_IP_TCPDIAG=y
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-# CONFIG_IPV6 is not set
-# CONFIG_NETFILTER is not set
-CONFIG_XFRM=y
-CONFIG_XFRM_USER=y
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP 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_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
-
-#
-# Network testing
+# Network device support
#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
CONFIG_NETDEVICES=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_EQUALIZER is not set
# CONFIG_TUN is not set
-# CONFIG_ETHERTAP is not set
#
# ARCnet devices
@@ -332,6 +398,21 @@ CONFIG_NETDEVICES=y
# CONFIG_ARCNET is not set
#
+# PHY device support
+#
+CONFIG_PHYLIB=y
+CONFIG_PHYCONTROL=y
+
+#
+# MII PHY device drivers
+#
+CONFIG_MARVELL_PHY=y
+CONFIG_DAVICOM_PHY=y
+CONFIG_QSEMI_PHY=y
+CONFIG_LXT_PHY=y
+CONFIG_CICADA_PHY=y
+
+#
# Ethernet (10 or 100Mbit)
#
CONFIG_NET_ETHERNET=y
@@ -357,12 +438,16 @@ CONFIG_NET_ETHERNET=y
# CONFIG_HAMACHI is not set
# CONFIG_YELLOWFIN is not set
# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
# CONFIG_SK98LIN is not set
# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
#
# Ethernet (10000 Mbit)
#
+# CONFIG_CHELSIO_T1 is not set
# CONFIG_IXGB is not set
# CONFIG_S2IO is not set
@@ -375,6 +460,8 @@ CONFIG_NET_ETHERNET=y
# Wireless LAN (non-hamradio)
#
# CONFIG_NET_RADIO is not set
+# CONFIG_IPW_DEBUG is not set
+CONFIG_IPW2200=y
#
# Wan interfaces
@@ -386,6 +473,8 @@ CONFIG_NET_ETHERNET=y
# CONFIG_SLIP is not set
# CONFIG_SHAPER is not set
# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
#
# ISDN subsystem
@@ -415,19 +504,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
# CONFIG_INPUT_EVBUG is not set
#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=y
-# CONFIG_SERIO_I8042 is not set
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_PCIPS2 is not set
-# CONFIG_SERIO_LIBPS2 is not set
-CONFIG_SERIO_RAW=y
-
-#
# Input Device Drivers
#
# CONFIG_INPUT_KEYBOARD is not set
@@ -437,6 +513,17 @@ CONFIG_SERIO_RAW=y
# CONFIG_INPUT_MISC is not set
#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_PCIPS2 is not set
+# CONFIG_SERIO_LIBPS2 is not set
+CONFIG_SERIO_RAW=y
+# CONFIG_GAMEPORT is not set
+
+#
# Character devices
#
CONFIG_VT=y
@@ -457,6 +544,7 @@ CONFIG_SERIAL_8250_NR_UARTS=4
#
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
CONFIG_UNIX98_PTYS=y
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
@@ -483,6 +571,11 @@ CONFIG_COBALT_LCD=y
# CONFIG_RAW_DRIVER is not set
#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+
+#
# I2C support
#
# CONFIG_I2C is not set
@@ -493,10 +586,20 @@ CONFIG_COBALT_LCD=y
# CONFIG_W1 is not set
#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
+#
# Misc devices
#
#
+# Multimedia Capabilities Port drivers
+#
+
+#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
@@ -516,7 +619,6 @@ CONFIG_COBALT_LCD=y
#
# CONFIG_VGA_CONSOLE is not set
CONFIG_DUMMY_CONSOLE=y
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Sound
@@ -526,13 +628,9 @@ CONFIG_DUMMY_CONSOLE=y
#
# USB support
#
-# CONFIG_USB is not set
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB_ARCH_HAS_OHCI=y
-
-#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
-#
+# CONFIG_USB is not set
#
# USB Gadget Support
@@ -550,12 +648,17 @@ CONFIG_USB_ARCH_HAS_OHCI=y
# CONFIG_INFINIBAND is not set
#
+# SN Devices
+#
+
+#
# File systems
#
CONFIG_EXT2_FS=y
CONFIG_EXT2_FS_XATTR=y
CONFIG_EXT2_FS_POSIX_ACL=y
CONFIG_EXT2_FS_SECURITY=y
+# CONFIG_EXT2_FS_XIP is not set
# CONFIG_EXT3_FS is not set
# CONFIG_JBD is not set
CONFIG_FS_MBCACHE=y
@@ -565,10 +668,12 @@ CONFIG_FS_POSIX_ACL=y
# CONFIG_XFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
# CONFIG_QUOTA is not set
CONFIG_DNOTIFY=y
# CONFIG_AUTOFS_FS is not set
# CONFIG_AUTOFS4_FS is not set
+CONFIG_FUSE_FS=y
#
# CD-ROM/DVD Filesystems
@@ -589,12 +694,10 @@ CONFIG_DNOTIFY=y
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
-CONFIG_DEVPTS_FS_XATTR=y
-CONFIG_DEVPTS_FS_SECURITY=y
# CONFIG_TMPFS is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
+CONFIG_RELAYFS_FS=y
#
# Miscellaneous filesystems
@@ -622,7 +725,7 @@ CONFIG_NFS_FS=y
# CONFIG_NFS_DIRECTIO is not set
# CONFIG_NFSD is not set
CONFIG_LOCKD=y
-# CONFIG_EXPORTFS is not set
+CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
@@ -631,6 +734,7 @@ CONFIG_SUNRPC=y
# CONFIG_NCP_FS is not set
# CONFIG_CODA_FS is not set
# CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
#
# Partition Types
@@ -651,7 +755,9 @@ CONFIG_MSDOS_PARTITION=y
#
# Kernel hacking
#
+# CONFIG_PRINTK_TIME is not set
# CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=14
CONFIG_CROSSCOMPILE=y
CONFIG_CMDLINE=""
@@ -665,7 +771,31 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
#
# Cryptographic options
#
-# CONFIG_CRYPTO is not set
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_NULL=y
+CONFIG_CRYPTO_MD4=y
+CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_SHA1=y
+CONFIG_CRYPTO_SHA256=y
+CONFIG_CRYPTO_SHA512=y
+CONFIG_CRYPTO_WP512=y
+CONFIG_CRYPTO_TGR192=y
+CONFIG_CRYPTO_DES=y
+CONFIG_CRYPTO_BLOWFISH=y
+CONFIG_CRYPTO_TWOFISH=y
+CONFIG_CRYPTO_SERPENT=y
+CONFIG_CRYPTO_AES=y
+CONFIG_CRYPTO_CAST5=y
+CONFIG_CRYPTO_CAST6=y
+CONFIG_CRYPTO_TEA=y
+CONFIG_CRYPTO_ARC4=y
+CONFIG_CRYPTO_KHAZAD=y
+CONFIG_CRYPTO_ANUBIS=y
+CONFIG_CRYPTO_DEFLATE=y
+CONFIG_CRYPTO_MICHAEL_MIC=y
+CONFIG_CRYPTO_CRC32C=y
+# CONFIG_CRYPTO_TEST is not set
#
# Hardware crypto devices
@@ -675,7 +805,8 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
# Library routines
#
# CONFIG_CRC_CCITT is not set
-# CONFIG_CRC32 is not set
-# CONFIG_LIBCRC32C is not set
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_CRC16=y
+CONFIG_CRC32=y
+CONFIG_LIBCRC32C=y
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
diff --git a/arch/mips/configs/db1000_defconfig b/arch/mips/configs/db1000_defconfig
index 962fc14b58c2..6501144ec612 100644
--- a/arch/mips/configs/db1000_defconfig
+++ b/arch/mips/configs/db1000_defconfig
@@ -1,12 +1,9 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-rc2
-# Wed Jan 26 02:49:01 2005
+# Linux kernel version: 2.6.14-rc2
+# Thu Oct 20 22:25:26 2005
#
CONFIG_MIPS=y
-# CONFIG_64BIT is not set
-# CONFIG_64BIT is not set
-CONFIG_32BIT=y
#
# Code maturity level options
@@ -14,24 +11,29 @@ CONFIG_32BIT=y
CONFIG_EXPERIMENTAL=y
CONFIG_CLEAN_COMPILE=y
CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
#
# General setup
#
CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
# CONFIG_POSIX_MQUEUE is not set
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
CONFIG_HOTPLUG=y
CONFIG_KOBJECT_UEVENT=y
# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
CONFIG_EMBEDDED=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
@@ -41,6 +43,7 @@ CONFIG_CC_ALIGN_LABELS=0
CONFIG_CC_ALIGN_LOOPS=0
CONFIG_CC_ALIGN_JUMPS=0
# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
#
# Loadable module support
@@ -56,63 +59,79 @@ CONFIG_KMOD=y
#
# Machine selection
#
-# CONFIG_MACH_JAZZ is not set
-# CONFIG_MACH_VR41XX is not set
-# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_MIPS_PB1550 is not set
+# CONFIG_MIPS_PB1200 is not set
+CONFIG_MIPS_DB1000=y
+# CONFIG_MIPS_DB1100 is not set
+# CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
+# CONFIG_MIPS_DB1200 is not set
+# CONFIG_MIPS_MIRAGE is not set
# CONFIG_MIPS_COBALT is not set
# CONFIG_MACH_DECSTATION is not set
# CONFIG_MIPS_EV64120 is not set
# CONFIG_MIPS_EV96100 is not set
# CONFIG_MIPS_IVR is not set
-# CONFIG_LASAT is not set
# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_LASAT is not set
# CONFIG_MIPS_ATLAS is not set
# CONFIG_MIPS_MALTA is not set
# CONFIG_MIPS_SEAD is not set
+# CONFIG_MIPS_SIM is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
# CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_G is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_JAGUAR_ATX is not set
-# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MIPS_XXS1500 is not set
+# CONFIG_PNX8550_V2PCI is not set
+# CONFIG_PNX8550_JBS is not set
# CONFIG_DDB5074 is not set
# CONFIG_DDB5476 is not set
# CONFIG_DDB5477 is not set
-# CONFIG_NEC_OSPREY is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_QEMU is not set
# CONFIG_SGI_IP22 is not set
-CONFIG_SOC_AU1X00=y
-CONFIG_SOC_AU1000=y
-# CONFIG_SOC_AU1100 is not set
-# CONFIG_SOC_AU1500 is not set
-# CONFIG_SOC_AU1550 is not set
-# CONFIG_MIPS_PB1000 is not set
-# CONFIG_MIPS_PB1100 is not set
-# CONFIG_MIPS_PB1500 is not set
-# CONFIG_MIPS_PB1550 is not set
-CONFIG_MIPS_DB1000=y
-# CONFIG_MIPS_DB1100 is not set
-# CONFIG_MIPS_DB1500 is not set
-# CONFIG_MIPS_DB1550 is not set
-# CONFIG_MIPS_BOSPORUS is not set
-# CONFIG_MIPS_MIRAGE is not set
-# CONFIG_MIPS_XXS1500 is not set
-# CONFIG_MIPS_MTX1 is not set
-# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_BIGSUR is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_PTSWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CRHONE is not set
# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
# CONFIG_TOSHIBA_RBTX4927 is not set
+# CONFIG_TOSHIBA_RBTX4938 is not set
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_HAVE_DEC_LOCK=y
CONFIG_DMA_NONCOHERENT=y
CONFIG_DMA_NEED_PCI_MAP_STATE=y
+# CONFIG_CPU_BIG_ENDIAN is not set
CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
+CONFIG_SOC_AU1000=y
+CONFIG_SOC_AU1X00=y
CONFIG_MIPS_L1_CACHE_SHIFT=5
#
# CPU selection
#
-CONFIG_CPU_MIPS32=y
-# CONFIG_CPU_MIPS64 is not set
+CONFIG_CPU_MIPS32_R1=y
+# CONFIG_CPU_MIPS32_R2 is not set
+# CONFIG_CPU_MIPS64_R1 is not set
+# CONFIG_CPU_MIPS64_R2 is not set
# CONFIG_CPU_R3000 is not set
# CONFIG_CPU_TX39XX is not set
# CONFIG_CPU_VR41XX is not set
@@ -128,15 +147,39 @@ CONFIG_CPU_MIPS32=y
# CONFIG_CPU_RM7000 is not set
# CONFIG_CPU_RM9000 is not set
# CONFIG_CPU_SB1 is not set
+CONFIG_SYS_HAS_CPU_MIPS32_R1=y
+CONFIG_CPU_MIPS32=y
+CONFIG_CPU_MIPSR1=y
+CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
+
+#
+# Kernel type
+#
+CONFIG_32BIT=y
+# CONFIG_64BIT is not set
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_CPU_HAS_PREFETCH=y
+# CONFIG_MIPS_MT is not set
CONFIG_64BIT_PHYS_ADDR=y
# CONFIG_CPU_ADVANCED is not set
CONFIG_CPU_HAS_LLSC=y
CONFIG_CPU_HAS_SYNC=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_ARCH_FLATMEM_ENABLE=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_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
#
@@ -152,6 +195,8 @@ CONFIG_MMU=y
CONFIG_PCCARD=m
# CONFIG_PCMCIA_DEBUG is not set
CONFIG_PCMCIA=m
+CONFIG_PCMCIA_LOAD_CIS=y
+CONFIG_PCMCIA_IOCTL=y
#
# PC-card bridges
@@ -169,6 +214,100 @@ CONFIG_PCMCIA=m
CONFIG_BINFMT_ELF=y
# CONFIG_BINFMT_MISC is not set
CONFIG_TRAD_SIGNALS=y
+# CONFIG_PM is not set
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+CONFIG_NET_KEY=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+CONFIG_INET_TUNNEL=m
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+
+#
+# IP: Virtual Server Configuration
+#
+# CONFIG_IP_VS is not set
+# CONFIG_IPV6 is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+CONFIG_NETFILTER_NETLINK=m
+CONFIG_NETFILTER_NETLINK_QUEUE=m
+CONFIG_NETFILTER_NETLINK_LOG=m
+
+#
+# IP: Netfilter Configuration
+#
+# CONFIG_IP_NF_CONNTRACK is not set
+CONFIG_IP_NF_PPTP=m
+# CONFIG_IP_NF_QUEUE is not set
+# CONFIG_IP_NF_IPTABLES is not set
+# CONFIG_IP_NF_ARPTABLES is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP 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_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_IEEE80211=m
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=m
+CONFIG_IEEE80211_CRYPT_CCMP=m
+CONFIG_IEEE80211_CRYPT_TKIP=m
#
# Device Drivers
@@ -179,12 +318,86 @@ CONFIG_TRAD_SIGNALS=y
#
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
+CONFIG_FW_LOADER=m
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+CONFIG_CONNECTOR=m
#
# Memory Technology Devices (MTD)
#
-# CONFIG_MTD is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_CMDLINE_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL 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_AMDSTD_RETRY=0
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PHYSMAP is not set
+CONFIG_MTD_ALCHEMY=y
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLKMTD 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
+
+#
+# NAND Flash Device Drivers
+#
+# CONFIG_MTD_NAND is not set
#
# Parallel port support
@@ -198,14 +411,12 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
#
# Block devices
#
-# CONFIG_BLK_DEV_FD is not set
# CONFIG_BLK_DEV_COW_COMMON is not set
CONFIG_BLK_DEV_LOOP=y
# CONFIG_BLK_DEV_CRYPTOLOOP is not set
# CONFIG_BLK_DEV_NBD is not set
# CONFIG_BLK_DEV_RAM is not set
CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_INITRAMFS_SOURCE=""
# CONFIG_LBD is not set
CONFIG_CDROM_PKTCDVD=m
CONFIG_CDROM_PKTCDVD_BUFFERS=8
@@ -228,6 +439,7 @@ CONFIG_ATA_OVER_ETH=m
#
# SCSI device support
#
+CONFIG_RAID_ATTRS=m
# CONFIG_SCSI is not set
#
@@ -238,6 +450,7 @@ CONFIG_ATA_OVER_ETH=m
#
# Fusion MPT device support
#
+# CONFIG_FUSION is not set
#
# IEEE 1394 (FireWire) support
@@ -248,94 +461,28 @@ CONFIG_ATA_OVER_ETH=m
#
#
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
-CONFIG_NETLINK_DEV=y
-CONFIG_UNIX=y
-CONFIG_NET_KEY=y
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-# CONFIG_IP_ADVANCED_ROUTER is not set
-CONFIG_IP_PNP=y
-# CONFIG_IP_PNP_DHCP is not set
-CONFIG_IP_PNP_BOOTP=y
-# CONFIG_IP_PNP_RARP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_IP_MROUTE is not set
-# CONFIG_ARPD is not set
-# CONFIG_SYN_COOKIES is not set
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-CONFIG_INET_TUNNEL=m
-CONFIG_IP_TCPDIAG=m
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-
-#
-# IP: Virtual Server Configuration
-#
-# CONFIG_IP_VS is not set
-# CONFIG_IPV6 is not set
-CONFIG_NETFILTER=y
-# CONFIG_NETFILTER_DEBUG is not set
-
-#
-# IP: Netfilter Configuration
+# Network device support
#
-# CONFIG_IP_NF_CONNTRACK is not set
-CONFIG_IP_NF_CONNTRACK_MARK=y
-# CONFIG_IP_NF_QUEUE is not set
-# CONFIG_IP_NF_IPTABLES is not set
-# CONFIG_IP_NF_ARPTABLES is not set
-CONFIG_XFRM=y
-CONFIG_XFRM_USER=m
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP 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_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
#
-# QoS and/or fair queueing
+# PHY device support
#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
+CONFIG_PHYLIB=m
+CONFIG_PHYCONTROL=y
#
-# Network testing
+# MII PHY device drivers
#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
-CONFIG_NETDEVICES=y
-# CONFIG_DUMMY is not set
-# CONFIG_BONDING is not set
-# CONFIG_EQUALIZER is not set
-# CONFIG_TUN is not set
-# CONFIG_ETHERTAP is not set
+CONFIG_MARVELL_PHY=m
+CONFIG_DAVICOM_PHY=m
+CONFIG_QSEMI_PHY=m
+CONFIG_LXT_PHY=m
+CONFIG_CICADA_PHY=m
#
# Ethernet (10 or 100Mbit)
@@ -389,6 +536,8 @@ CONFIG_PPPOE=m
# CONFIG_SLIP is not set
# CONFIG_SHAPER is not set
# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
#
# ISDN subsystem
@@ -418,18 +567,6 @@ CONFIG_INPUT_EVDEV=y
# CONFIG_INPUT_EVBUG is not set
#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=y
-# CONFIG_SERIO_I8042 is not set
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_LIBPS2 is not set
-CONFIG_SERIO_RAW=m
-
-#
# Input Device Drivers
#
# CONFIG_INPUT_KEYBOARD is not set
@@ -439,6 +576,16 @@ CONFIG_SERIO_RAW=m
# CONFIG_INPUT_MISC is not set
#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_LIBPS2 is not set
+CONFIG_SERIO_RAW=m
+# CONFIG_GAMEPORT is not set
+
+#
# Character devices
#
CONFIG_VT=y
@@ -473,14 +620,14 @@ CONFIG_LEGACY_PTY_COUNT=256
# Watchdog Cards
#
# CONFIG_WATCHDOG is not set
-CONFIG_RTC=y
+# CONFIG_RTC is not set
+# CONFIG_GEN_RTC is not set
# CONFIG_DTLK is not set
# CONFIG_R3964 is not set
#
# Ftape, the floppy tape device driver
#
-# CONFIG_DRM is not set
#
# PCMCIA character devices
@@ -489,6 +636,10 @@ CONFIG_SYNCLINK_CS=m
# CONFIG_RAW_DRIVER is not set
#
+# TPM devices
+#
+
+#
# I2C support
#
# CONFIG_I2C is not set
@@ -499,10 +650,20 @@ CONFIG_SYNCLINK_CS=m
# CONFIG_W1 is not set
#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
+#
# Misc devices
#
#
+# Multimedia Capabilities Port drivers
+#
+
+#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
@@ -522,7 +683,6 @@ CONFIG_SYNCLINK_CS=m
#
# CONFIG_VGA_CONSOLE is not set
CONFIG_DUMMY_CONSOLE=y
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Sound
@@ -532,12 +692,9 @@ CONFIG_DUMMY_CONSOLE=y
#
# USB support
#
-# CONFIG_USB_ARCH_HAS_HCD is not set
-# CONFIG_USB_ARCH_HAS_OHCI is not set
-
-#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
-#
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+# CONFIG_USB is not set
#
# USB Gadget Support
@@ -552,7 +709,10 @@ CONFIG_DUMMY_CONSOLE=y
#
# InfiniBand support
#
-# CONFIG_INFINIBAND is not set
+
+#
+# SN Devices
+#
#
# File systems
@@ -561,6 +721,7 @@ CONFIG_EXT2_FS=y
CONFIG_EXT2_FS_XATTR=y
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_FS_XATTR=y
CONFIG_EXT3_FS_POSIX_ACL=y
@@ -579,10 +740,12 @@ CONFIG_FS_POSIX_ACL=y
# CONFIG_XFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
# CONFIG_QUOTA is not set
CONFIG_DNOTIFY=y
CONFIG_AUTOFS_FS=m
CONFIG_AUTOFS4_FS=m
+CONFIG_FUSE_FS=m
#
# CD-ROM/DVD Filesystems
@@ -603,13 +766,10 @@ CONFIG_AUTOFS4_FS=m
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
-CONFIG_DEVPTS_FS_XATTR=y
-CONFIG_DEVPTS_FS_SECURITY=y
CONFIG_TMPFS=y
-# CONFIG_TMPFS_XATTR is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
+CONFIG_RELAYFS_FS=m
#
# Miscellaneous filesystems
@@ -621,6 +781,8 @@ CONFIG_RAMFS=y
# CONFIG_BEFS_FS is not set
# CONFIG_BFS_FS is not set
# CONFIG_EFS_FS is not set
+# CONFIG_JFFS_FS is not set
+# CONFIG_JFFS2_FS is not set
CONFIG_CRAMFS=m
# CONFIG_VXFS_FS is not set
# CONFIG_HPFS_FS is not set
@@ -641,6 +803,7 @@ CONFIG_NFSD=m
CONFIG_ROOT_NFS=y
CONFIG_LOCKD=y
CONFIG_EXPORTFS=m
+CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
@@ -650,6 +813,7 @@ CONFIG_SMB_FS=m
# CONFIG_NCP_FS is not set
# CONFIG_CODA_FS is not set
# CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
#
# Partition Types
@@ -709,7 +873,9 @@ CONFIG_NLS_DEFAULT="iso8859-1"
#
# Kernel hacking
#
+# CONFIG_PRINTK_TIME is not set
# CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=14
CONFIG_CROSSCOMPILE=y
CONFIG_CMDLINE=""
@@ -725,26 +891,27 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
#
CONFIG_CRYPTO=y
CONFIG_CRYPTO_HMAC=y
-CONFIG_CRYPTO_NULL=y
-# CONFIG_CRYPTO_MD4 is not set
-# CONFIG_CRYPTO_MD5 is not set
-# CONFIG_CRYPTO_SHA1 is not set
-# CONFIG_CRYPTO_SHA256 is not set
-CONFIG_CRYPTO_SHA512=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
CONFIG_CRYPTO_WP512=m
-# CONFIG_CRYPTO_DES is not set
-# CONFIG_CRYPTO_BLOWFISH is not set
-CONFIG_CRYPTO_TWOFISH=y
-# CONFIG_CRYPTO_SERPENT is not set
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_SERPENT=m
CONFIG_CRYPTO_AES=m
-# CONFIG_CRYPTO_CAST5 is not set
-# CONFIG_CRYPTO_CAST6 is not set
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
CONFIG_CRYPTO_TEA=m
-# CONFIG_CRYPTO_ARC4 is not set
+CONFIG_CRYPTO_ARC4=m
CONFIG_CRYPTO_KHAZAD=m
CONFIG_CRYPTO_ANUBIS=m
-CONFIG_CRYPTO_DEFLATE=y
-CONFIG_CRYPTO_MICHAEL_MIC=y
+CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
CONFIG_CRYPTO_CRC32C=m
# CONFIG_CRYPTO_TEST is not set
@@ -756,9 +923,8 @@ CONFIG_CRYPTO_CRC32C=m
# Library routines
#
CONFIG_CRC_CCITT=m
+CONFIG_CRC16=m
CONFIG_CRC32=y
CONFIG_LIBCRC32C=m
-CONFIG_ZLIB_INFLATE=y
-CONFIG_ZLIB_DEFLATE=y
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_ZLIB_INFLATE=m
+CONFIG_ZLIB_DEFLATE=m
diff --git a/arch/mips/configs/db1100_defconfig b/arch/mips/configs/db1100_defconfig
index 6a528d479d70..b8cd2cd923dd 100644
--- a/arch/mips/configs/db1100_defconfig
+++ b/arch/mips/configs/db1100_defconfig
@@ -1,12 +1,9 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-rc2
-# Wed Jan 26 02:49:01 2005
+# Linux kernel version: 2.6.14-rc2
+# Thu Oct 20 22:25:29 2005
#
CONFIG_MIPS=y
-# CONFIG_64BIT is not set
-# CONFIG_64BIT is not set
-CONFIG_32BIT=y
#
# Code maturity level options
@@ -14,24 +11,29 @@ CONFIG_32BIT=y
CONFIG_EXPERIMENTAL=y
CONFIG_CLEAN_COMPILE=y
CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
#
# General setup
#
CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
# CONFIG_POSIX_MQUEUE is not set
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
CONFIG_HOTPLUG=y
CONFIG_KOBJECT_UEVENT=y
# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
CONFIG_EMBEDDED=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
@@ -41,6 +43,7 @@ CONFIG_CC_ALIGN_LABELS=0
CONFIG_CC_ALIGN_LOOPS=0
CONFIG_CC_ALIGN_JUMPS=0
# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
#
# Loadable module support
@@ -56,63 +59,79 @@ CONFIG_KMOD=y
#
# Machine selection
#
-# CONFIG_MACH_JAZZ is not set
-# CONFIG_MACH_VR41XX is not set
-# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_MIPS_PB1550 is not set
+# CONFIG_MIPS_PB1200 is not set
+# CONFIG_MIPS_DB1000 is not set
+CONFIG_MIPS_DB1100=y
+# CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
+# CONFIG_MIPS_DB1200 is not set
+# CONFIG_MIPS_MIRAGE is not set
# CONFIG_MIPS_COBALT is not set
# CONFIG_MACH_DECSTATION is not set
# CONFIG_MIPS_EV64120 is not set
# CONFIG_MIPS_EV96100 is not set
# CONFIG_MIPS_IVR is not set
-# CONFIG_LASAT is not set
# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_LASAT is not set
# CONFIG_MIPS_ATLAS is not set
# CONFIG_MIPS_MALTA is not set
# CONFIG_MIPS_SEAD is not set
+# CONFIG_MIPS_SIM is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
# CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_G is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_JAGUAR_ATX is not set
-# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MIPS_XXS1500 is not set
+# CONFIG_PNX8550_V2PCI is not set
+# CONFIG_PNX8550_JBS is not set
# CONFIG_DDB5074 is not set
# CONFIG_DDB5476 is not set
# CONFIG_DDB5477 is not set
-# CONFIG_NEC_OSPREY is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_QEMU is not set
# CONFIG_SGI_IP22 is not set
-CONFIG_SOC_AU1X00=y
-# CONFIG_SOC_AU1000 is not set
-CONFIG_SOC_AU1100=y
-# CONFIG_SOC_AU1500 is not set
-# CONFIG_SOC_AU1550 is not set
-# CONFIG_MIPS_PB1000 is not set
-# CONFIG_MIPS_PB1100 is not set
-# CONFIG_MIPS_PB1500 is not set
-# CONFIG_MIPS_PB1550 is not set
-# CONFIG_MIPS_DB1000 is not set
-CONFIG_MIPS_DB1100=y
-# CONFIG_MIPS_DB1500 is not set
-# CONFIG_MIPS_DB1550 is not set
-# CONFIG_MIPS_BOSPORUS is not set
-# CONFIG_MIPS_MIRAGE is not set
-# CONFIG_MIPS_XXS1500 is not set
-# CONFIG_MIPS_MTX1 is not set
-# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_BIGSUR is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_PTSWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CRHONE is not set
# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
# CONFIG_TOSHIBA_RBTX4927 is not set
+# CONFIG_TOSHIBA_RBTX4938 is not set
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_HAVE_DEC_LOCK=y
CONFIG_DMA_NONCOHERENT=y
CONFIG_DMA_NEED_PCI_MAP_STATE=y
+# CONFIG_CPU_BIG_ENDIAN is not set
CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
+CONFIG_SOC_AU1100=y
+CONFIG_SOC_AU1X00=y
CONFIG_MIPS_L1_CACHE_SHIFT=5
#
# CPU selection
#
-CONFIG_CPU_MIPS32=y
-# CONFIG_CPU_MIPS64 is not set
+CONFIG_CPU_MIPS32_R1=y
+# CONFIG_CPU_MIPS32_R2 is not set
+# CONFIG_CPU_MIPS64_R1 is not set
+# CONFIG_CPU_MIPS64_R2 is not set
# CONFIG_CPU_R3000 is not set
# CONFIG_CPU_TX39XX is not set
# CONFIG_CPU_VR41XX is not set
@@ -128,15 +147,39 @@ CONFIG_CPU_MIPS32=y
# CONFIG_CPU_RM7000 is not set
# CONFIG_CPU_RM9000 is not set
# CONFIG_CPU_SB1 is not set
+CONFIG_SYS_HAS_CPU_MIPS32_R1=y
+CONFIG_CPU_MIPS32=y
+CONFIG_CPU_MIPSR1=y
+CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
+
+#
+# Kernel type
+#
+CONFIG_32BIT=y
+# CONFIG_64BIT is not set
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_CPU_HAS_PREFETCH=y
-# CONFIG_64BIT_PHYS_ADDR is not set
+# CONFIG_MIPS_MT is not set
+CONFIG_64BIT_PHYS_ADDR=y
# CONFIG_CPU_ADVANCED is not set
CONFIG_CPU_HAS_LLSC=y
CONFIG_CPU_HAS_SYNC=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_ARCH_FLATMEM_ENABLE=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_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
#
@@ -147,15 +190,7 @@ CONFIG_MMU=y
#
# PCCARD (PCMCIA/CardBus) support
#
-CONFIG_PCCARD=m
-# CONFIG_PCMCIA_DEBUG is not set
-CONFIG_PCMCIA=m
-
-#
-# PC-card bridges
-#
-# CONFIG_TCIC is not set
-# CONFIG_PCMCIA_AU1X00 is not set
+# CONFIG_PCCARD is not set
#
# PCI Hotplug Support
@@ -167,6 +202,100 @@ CONFIG_PCMCIA=m
CONFIG_BINFMT_ELF=y
# CONFIG_BINFMT_MISC is not set
CONFIG_TRAD_SIGNALS=y
+# CONFIG_PM is not set
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+CONFIG_NET_KEY=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+CONFIG_INET_TUNNEL=m
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+
+#
+# IP: Virtual Server Configuration
+#
+# CONFIG_IP_VS is not set
+# CONFIG_IPV6 is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+CONFIG_NETFILTER_NETLINK=m
+CONFIG_NETFILTER_NETLINK_QUEUE=m
+CONFIG_NETFILTER_NETLINK_LOG=m
+
+#
+# IP: Netfilter Configuration
+#
+# CONFIG_IP_NF_CONNTRACK is not set
+CONFIG_IP_NF_PPTP=m
+# CONFIG_IP_NF_QUEUE is not set
+# CONFIG_IP_NF_IPTABLES is not set
+# CONFIG_IP_NF_ARPTABLES is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP 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_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_IEEE80211=m
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=m
+CONFIG_IEEE80211_CRYPT_CCMP=m
+CONFIG_IEEE80211_CRYPT_TKIP=m
#
# Device Drivers
@@ -180,9 +309,83 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_FW_LOADER is not set
#
+# Connector - unified userspace <-> kernelspace linker
+#
+CONFIG_CONNECTOR=m
+
+#
# Memory Technology Devices (MTD)
#
-# CONFIG_MTD is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_CMDLINE_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL 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_AMDSTD_RETRY=0
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PHYSMAP is not set
+CONFIG_MTD_ALCHEMY=y
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLKMTD 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
+
+#
+# NAND Flash Device Drivers
+#
+# CONFIG_MTD_NAND is not set
#
# Parallel port support
@@ -196,14 +399,12 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
#
# Block devices
#
-# CONFIG_BLK_DEV_FD is not set
# CONFIG_BLK_DEV_COW_COMMON is not set
CONFIG_BLK_DEV_LOOP=y
# CONFIG_BLK_DEV_CRYPTOLOOP is not set
# CONFIG_BLK_DEV_NBD is not set
# CONFIG_BLK_DEV_RAM is not set
CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_INITRAMFS_SOURCE=""
# CONFIG_LBD is not set
CONFIG_CDROM_PKTCDVD=m
CONFIG_CDROM_PKTCDVD_BUFFERS=8
@@ -226,6 +427,7 @@ CONFIG_ATA_OVER_ETH=m
#
# SCSI device support
#
+CONFIG_RAID_ATTRS=m
# CONFIG_SCSI is not set
#
@@ -236,6 +438,7 @@ CONFIG_ATA_OVER_ETH=m
#
# Fusion MPT device support
#
+# CONFIG_FUSION is not set
#
# IEEE 1394 (FireWire) support
@@ -246,101 +449,35 @@ CONFIG_ATA_OVER_ETH=m
#
#
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
-CONFIG_NETLINK_DEV=y
-CONFIG_UNIX=y
-CONFIG_NET_KEY=y
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-# CONFIG_IP_ADVANCED_ROUTER is not set
-CONFIG_IP_PNP=y
-# CONFIG_IP_PNP_DHCP is not set
-CONFIG_IP_PNP_BOOTP=y
-# CONFIG_IP_PNP_RARP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_IP_MROUTE is not set
-# CONFIG_ARPD is not set
-# CONFIG_SYN_COOKIES is not set
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-CONFIG_INET_TUNNEL=m
-CONFIG_IP_TCPDIAG=m
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-
-#
-# IP: Virtual Server Configuration
-#
-# CONFIG_IP_VS is not set
-# CONFIG_IPV6 is not set
-CONFIG_NETFILTER=y
-# CONFIG_NETFILTER_DEBUG is not set
-
-#
-# IP: Netfilter Configuration
+# Network device support
#
-# CONFIG_IP_NF_CONNTRACK is not set
-CONFIG_IP_NF_CONNTRACK_MARK=y
-# CONFIG_IP_NF_QUEUE is not set
-# CONFIG_IP_NF_IPTABLES is not set
-# CONFIG_IP_NF_ARPTABLES is not set
-CONFIG_XFRM=y
-CONFIG_XFRM_USER=m
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP 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_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
#
-# QoS and/or fair queueing
+# PHY device support
#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
+CONFIG_PHYLIB=m
+CONFIG_PHYCONTROL=y
#
-# Network testing
+# MII PHY device drivers
#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
-CONFIG_NETDEVICES=y
-# CONFIG_DUMMY is not set
-# CONFIG_BONDING is not set
-# CONFIG_EQUALIZER is not set
-# CONFIG_TUN is not set
-# CONFIG_ETHERTAP is not set
+CONFIG_MARVELL_PHY=m
+CONFIG_DAVICOM_PHY=m
+CONFIG_QSEMI_PHY=m
+CONFIG_LXT_PHY=m
+CONFIG_CICADA_PHY=m
#
# Ethernet (10 or 100Mbit)
#
CONFIG_NET_ETHERNET=y
CONFIG_MII=m
-# CONFIG_MIPS_AU1X00_ENET is not set
+CONFIG_MIPS_AU1X00_ENET=y
#
# Ethernet (1000 Mbit)
@@ -360,19 +497,6 @@ CONFIG_MII=m
# CONFIG_NET_RADIO is not set
#
-# PCMCIA network device support
-#
-CONFIG_NET_PCMCIA=y
-CONFIG_PCMCIA_3C589=m
-CONFIG_PCMCIA_3C574=m
-CONFIG_PCMCIA_FMVJ18X=m
-CONFIG_PCMCIA_PCNET=m
-CONFIG_PCMCIA_NMCLAN=m
-CONFIG_PCMCIA_SMC91C92=m
-CONFIG_PCMCIA_XIRC2PS=m
-CONFIG_PCMCIA_AXNET=m
-
-#
# Wan interfaces
#
# CONFIG_WAN is not set
@@ -387,6 +511,8 @@ CONFIG_PPPOE=m
# CONFIG_SLIP is not set
# CONFIG_SHAPER is not set
# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
#
# ISDN subsystem
@@ -416,18 +542,6 @@ CONFIG_INPUT_EVDEV=y
# CONFIG_INPUT_EVBUG is not set
#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=y
-# CONFIG_SERIO_I8042 is not set
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_CT82C710 is not set
-CONFIG_SERIO_LIBPS2=m
-CONFIG_SERIO_RAW=m
-
-#
# Input Device Drivers
#
# CONFIG_INPUT_KEYBOARD is not set
@@ -437,6 +551,16 @@ CONFIG_SERIO_RAW=m
# CONFIG_INPUT_MISC is not set
#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+CONFIG_SERIO_SERPORT=y
+CONFIG_SERIO_LIBPS2=m
+CONFIG_SERIO_RAW=m
+# CONFIG_GAMEPORT is not set
+
+#
# Character devices
#
CONFIG_VT=y
@@ -454,7 +578,10 @@ CONFIG_HW_CONSOLE=y
#
# Non-8250 serial port support
#
-# CONFIG_SERIAL_AU1X00 is not set
+CONFIG_SERIAL_AU1X00=y
+CONFIG_SERIAL_AU1X00_CONSOLE=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
CONFIG_UNIX98_PTYS=y
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
@@ -468,20 +595,19 @@ CONFIG_LEGACY_PTY_COUNT=256
# Watchdog Cards
#
# CONFIG_WATCHDOG is not set
-CONFIG_RTC=y
+# CONFIG_RTC is not set
+# CONFIG_GEN_RTC is not set
# CONFIG_DTLK is not set
# CONFIG_R3964 is not set
#
# Ftape, the floppy tape device driver
#
-# CONFIG_DRM is not set
+# CONFIG_RAW_DRIVER is not set
#
-# PCMCIA character devices
+# TPM devices
#
-CONFIG_SYNCLINK_CS=m
-# CONFIG_RAW_DRIVER is not set
#
# I2C support
@@ -494,10 +620,20 @@ CONFIG_SYNCLINK_CS=m
# CONFIG_W1 is not set
#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
+#
# Misc devices
#
#
+# Multimedia Capabilities Port drivers
+#
+
+#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
@@ -510,13 +646,43 @@ CONFIG_SYNCLINK_CS=m
#
# Graphics support
#
-# CONFIG_FB is not set
+CONFIG_FB=y
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+CONFIG_FB_SOFT_CURSOR=y
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+CONFIG_FB_AU1100=y
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_VIRTUAL is not set
#
# Console display driver support
#
# CONFIG_VGA_CONSOLE is not set
CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FONTS=y
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+# CONFIG_FONT_6x11 is not set
+# CONFIG_FONT_7x14 is not set
+# CONFIG_FONT_PEARL_8x8 is not set
+# CONFIG_FONT_ACORN_8x8 is not set
+# CONFIG_FONT_MINI_4x6 is not set
+# CONFIG_FONT_SUN8x16 is not set
+# CONFIG_FONT_SUN12x22 is not set
+# CONFIG_FONT_10x18 is not set
+
+#
+# Logo configuration
+#
+CONFIG_LOGO=y
+CONFIG_LOGO_LINUX_MONO=y
+CONFIG_LOGO_LINUX_VGA16=y
+CONFIG_LOGO_LINUX_CLUT224=y
# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
@@ -527,12 +693,9 @@ CONFIG_DUMMY_CONSOLE=y
#
# USB support
#
-# CONFIG_USB_ARCH_HAS_HCD is not set
-# CONFIG_USB_ARCH_HAS_OHCI is not set
-
-#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
-#
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+# CONFIG_USB is not set
#
# USB Gadget Support
@@ -547,7 +710,10 @@ CONFIG_DUMMY_CONSOLE=y
#
# InfiniBand support
#
-# CONFIG_INFINIBAND is not set
+
+#
+# SN Devices
+#
#
# File systems
@@ -556,6 +722,7 @@ CONFIG_EXT2_FS=y
CONFIG_EXT2_FS_XATTR=y
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_FS_XATTR=y
CONFIG_EXT3_FS_POSIX_ACL=y
@@ -574,10 +741,12 @@ CONFIG_FS_POSIX_ACL=y
# CONFIG_XFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
# CONFIG_QUOTA is not set
CONFIG_DNOTIFY=y
CONFIG_AUTOFS_FS=m
CONFIG_AUTOFS4_FS=m
+CONFIG_FUSE_FS=m
#
# CD-ROM/DVD Filesystems
@@ -598,13 +767,10 @@ CONFIG_AUTOFS4_FS=m
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
-CONFIG_DEVPTS_FS_XATTR=y
-CONFIG_DEVPTS_FS_SECURITY=y
CONFIG_TMPFS=y
-# CONFIG_TMPFS_XATTR is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
+CONFIG_RELAYFS_FS=m
#
# Miscellaneous filesystems
@@ -616,6 +782,8 @@ CONFIG_RAMFS=y
# CONFIG_BEFS_FS is not set
# CONFIG_BFS_FS is not set
# CONFIG_EFS_FS is not set
+# CONFIG_JFFS_FS is not set
+# CONFIG_JFFS2_FS is not set
CONFIG_CRAMFS=m
# CONFIG_VXFS_FS is not set
# CONFIG_HPFS_FS is not set
@@ -636,6 +804,7 @@ CONFIG_NFSD=m
CONFIG_ROOT_NFS=y
CONFIG_LOCKD=y
CONFIG_EXPORTFS=m
+CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
@@ -645,6 +814,7 @@ CONFIG_SMB_FS=m
# CONFIG_NCP_FS is not set
# CONFIG_CODA_FS is not set
# CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
#
# Partition Types
@@ -704,7 +874,9 @@ CONFIG_NLS_DEFAULT="iso8859-1"
#
# Kernel hacking
#
+# CONFIG_PRINTK_TIME is not set
# CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=14
CONFIG_CROSSCOMPILE=y
CONFIG_CMDLINE=""
@@ -720,26 +892,27 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
#
CONFIG_CRYPTO=y
CONFIG_CRYPTO_HMAC=y
-CONFIG_CRYPTO_NULL=y
-# CONFIG_CRYPTO_MD4 is not set
-# CONFIG_CRYPTO_MD5 is not set
-# CONFIG_CRYPTO_SHA1 is not set
-# CONFIG_CRYPTO_SHA256 is not set
-CONFIG_CRYPTO_SHA512=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
CONFIG_CRYPTO_WP512=m
-# CONFIG_CRYPTO_DES is not set
-# CONFIG_CRYPTO_BLOWFISH is not set
-CONFIG_CRYPTO_TWOFISH=y
-# CONFIG_CRYPTO_SERPENT is not set
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_SERPENT=m
CONFIG_CRYPTO_AES=m
-# CONFIG_CRYPTO_CAST5 is not set
-# CONFIG_CRYPTO_CAST6 is not set
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
CONFIG_CRYPTO_TEA=m
-# CONFIG_CRYPTO_ARC4 is not set
+CONFIG_CRYPTO_ARC4=m
CONFIG_CRYPTO_KHAZAD=m
CONFIG_CRYPTO_ANUBIS=m
-CONFIG_CRYPTO_DEFLATE=y
-CONFIG_CRYPTO_MICHAEL_MIC=y
+CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
CONFIG_CRYPTO_CRC32C=m
# CONFIG_CRYPTO_TEST is not set
@@ -751,9 +924,8 @@ CONFIG_CRYPTO_CRC32C=m
# Library routines
#
CONFIG_CRC_CCITT=m
+CONFIG_CRC16=m
CONFIG_CRC32=y
CONFIG_LIBCRC32C=m
-CONFIG_ZLIB_INFLATE=y
-CONFIG_ZLIB_DEFLATE=y
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_ZLIB_INFLATE=m
+CONFIG_ZLIB_DEFLATE=m
diff --git a/arch/mips/configs/db1200_defconfig b/arch/mips/configs/db1200_defconfig
new file mode 100644
index 000000000000..530b6c2d99f6
--- /dev/null
+++ b/arch/mips/configs/db1200_defconfig
@@ -0,0 +1,987 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.14-rc2
+# Thu Oct 20 22:25:32 2005
+#
+CONFIG_MIPS=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_HOTPLUG=y
+CONFIG_KOBJECT_UEVENT=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_OBSOLETE_MODPARM=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_KMOD=y
+
+#
+# Machine selection
+#
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_MIPS_PB1550 is not set
+# CONFIG_MIPS_PB1200 is not set
+# CONFIG_MIPS_DB1000 is not set
+# CONFIG_MIPS_DB1100 is not set
+# CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
+CONFIG_MIPS_DB1200=y
+# CONFIG_MIPS_MIRAGE is not set
+# CONFIG_MIPS_COBALT is not set
+# CONFIG_MACH_DECSTATION is not set
+# CONFIG_MIPS_EV64120 is not set
+# CONFIG_MIPS_EV96100 is not set
+# CONFIG_MIPS_IVR is not set
+# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_LASAT is not set
+# CONFIG_MIPS_ATLAS is not set
+# CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SEAD is not set
+# CONFIG_MIPS_SIM is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_MOMENCO_OCELOT_3 is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MIPS_XXS1500 is not set
+# CONFIG_PNX8550_V2PCI is not set
+# CONFIG_PNX8550_JBS is not set
+# CONFIG_DDB5074 is not set
+# CONFIG_DDB5476 is not set
+# CONFIG_DDB5477 is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_QEMU is not set
+# CONFIG_SGI_IP22 is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_BIGSUR is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_PTSWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CRHONE is not set
+# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_TOSHIBA_RBTX4927 is not set
+# CONFIG_TOSHIBA_RBTX4938 is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_DMA_COHERENT=y
+CONFIG_MIPS_DISABLE_OBSOLETE_IDE=y
+# CONFIG_CPU_BIG_ENDIAN is not set
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
+CONFIG_SOC_AU1200=y
+CONFIG_SOC_AU1X00=y
+CONFIG_MIPS_L1_CACHE_SHIFT=5
+
+#
+# CPU selection
+#
+CONFIG_CPU_MIPS32_R1=y
+# CONFIG_CPU_MIPS32_R2 is not set
+# CONFIG_CPU_MIPS64_R1 is not set
+# CONFIG_CPU_MIPS64_R2 is not set
+# CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_TX39XX is not set
+# CONFIG_CPU_VR41XX is not set
+# CONFIG_CPU_R4300 is not set
+# CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_TX49XX is not set
+# CONFIG_CPU_R5000 is not set
+# CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_R6000 is not set
+# CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
+# CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_RM7000 is not set
+# CONFIG_CPU_RM9000 is not set
+# CONFIG_CPU_SB1 is not set
+CONFIG_SYS_HAS_CPU_MIPS32_R1=y
+CONFIG_CPU_MIPS32=y
+CONFIG_CPU_MIPSR1=y
+CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
+
+#
+# Kernel type
+#
+CONFIG_32BIT=y
+# CONFIG_64BIT is not set
+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_CPU_HAS_PREFETCH=y
+# CONFIG_MIPS_MT is not set
+CONFIG_64BIT_PHYS_ADDR=y
+# CONFIG_CPU_ADVANCED is not set
+CONFIG_CPU_HAS_LLSC=y
+CONFIG_CPU_HAS_SYNC=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_ARCH_FLATMEM_ENABLE=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_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+
+#
+# Bus options (PCI, PCMCIA, EISA, ISA, TC)
+#
+CONFIG_MMU=y
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+CONFIG_PCCARD=m
+# CONFIG_PCMCIA_DEBUG is not set
+CONFIG_PCMCIA=m
+CONFIG_PCMCIA_LOAD_CIS=y
+CONFIG_PCMCIA_IOCTL=y
+
+#
+# PC-card bridges
+#
+# CONFIG_TCIC is not set
+CONFIG_PCMCIA_AU1X00=m
+
+#
+# PCI Hotplug Support
+#
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+CONFIG_TRAD_SIGNALS=y
+# CONFIG_PM is not set
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+CONFIG_NET_KEY=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+# CONFIG_IP_PNP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+CONFIG_INET_TUNNEL=m
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+
+#
+# IP: Virtual Server Configuration
+#
+# CONFIG_IP_VS is not set
+# CONFIG_IPV6 is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+# CONFIG_NETFILTER_NETLINK is not set
+
+#
+# IP: Netfilter Configuration
+#
+# CONFIG_IP_NF_CONNTRACK is not set
+CONFIG_IP_NF_PPTP=m
+# CONFIG_IP_NF_QUEUE is not set
+# CONFIG_IP_NF_IPTABLES is not set
+# CONFIG_IP_NF_ARPTABLES is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP 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_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_CMDLINE_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL 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_AMDSTD_RETRY=0
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PHYSMAP is not set
+CONFIG_MTD_ALCHEMY=y
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLKMTD 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
+
+#
+# NAND Flash Device Drivers
+#
+CONFIG_MTD_NAND=y
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+CONFIG_MTD_NAND_IDS=y
+# CONFIG_MTD_NAND_AU1550 is not set
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+# CONFIG_MTD_NAND_NANDSIM is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=4096
+# CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_LBD is not set
+# CONFIG_CDROM_PKTCDVD is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_ATA_OVER_ETH is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+CONFIG_IDE=y
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_IDE_SATA is not set
+CONFIG_BLK_DEV_IDEDISK=y
+CONFIG_IDEDISK_MULTI_MODE=y
+CONFIG_BLK_DEV_IDECS=m
+# CONFIG_BLK_DEV_IDECD is not set
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_BLK_DEV_IDEFLOPPY is not set
+# CONFIG_BLK_DEV_IDESCSI is not set
+# CONFIG_IDE_TASK_IOCTL is not set
+
+#
+# IDE chipset support/bugfixes
+#
+CONFIG_IDE_GENERIC=y
+CONFIG_BLK_DEV_IDE_AU1XXX=y
+CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA=y
+# CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA is not set
+# CONFIG_BLK_DEV_IDE_AU1XXX_BURSTABLE_ON is not set
+CONFIG_BLK_DEV_IDE_AU1XXX_SEQTS_PER_RQ=128
+# CONFIG_IDE_ARM is not set
+# CONFIG_BLK_DEV_IDEDMA is not set
+# CONFIG_IDEDMA_AUTO is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+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=y
+# CONFIG_BLK_DEV_SR_VENDOR 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=y
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+
+#
+# SCSI Transport Attributes
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_ATTRS is not set
+
+#
+# SCSI low-level drivers
+#
+# CONFIG_SCSI_SATA is not set
+# CONFIG_SCSI_DEBUG is not set
+
+#
+# PCMCIA SCSI adapter support
+#
+# CONFIG_PCMCIA_AHA152X is not set
+# CONFIG_PCMCIA_FDOMAIN is not set
+# CONFIG_PCMCIA_NINJA_SCSI is not set
+# CONFIG_PCMCIA_QLOGIC is not set
+# CONFIG_PCMCIA_SYM53C500 is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+
+#
+# I2O device support
+#
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+
+#
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=m
+# CONFIG_MIPS_AU1X00_ENET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+
+#
+# Ethernet (10000 Mbit)
+#
+
+#
+# Token Ring devices
+#
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# PCMCIA network device support
+#
+# CONFIG_NET_PCMCIA is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_LIBPS2 is not set
+CONFIG_SERIO_RAW=y
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_AU1X00_GPIO is not set
+# CONFIG_TS_AU1X00_ADS7846 is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_AU1X00=y
+CONFIG_SERIAL_AU1X00_CONSOLE=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_RTC is not set
+# CONFIG_GEN_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+
+#
+# PCMCIA character devices
+#
+# CONFIG_SYNCLINK_CS is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# TPM devices
+#
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
+#
+# Misc devices
+#
+
+#
+# Multimedia Capabilities Port drivers
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+CONFIG_FB=y
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+CONFIG_FB_SOFT_CURSOR=y
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+CONFIG_FB_AU1200=y
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_VIRTUAL is not set
+
+#
+# Console display driver support
+#
+CONFIG_VGA_CONSOLE=y
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE is not set
+
+#
+# Logo configuration
+#
+CONFIG_LOGO=y
+CONFIG_LOGO_LINUX_MONO=y
+CONFIG_LOGO_LINUX_VGA16=y
+CONFIG_LOGO_LINUX_CLUT224=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+# CONFIG_USB is not set
+
+#
+# USB Gadget Support
+#
+CONFIG_USB_GADGET=m
+# CONFIG_USB_GADGET_DEBUG_FILES is not set
+# CONFIG_USB_GADGET_NET2280 is not set
+# CONFIG_USB_GADGET_PXA2XX is not set
+# CONFIG_USB_GADGET_GOKU is not set
+# CONFIG_USB_GADGET_LH7A40X is not set
+# CONFIG_USB_GADGET_OMAP is not set
+# CONFIG_USB_GADGET_DUMMY_HCD is not set
+# CONFIG_USB_GADGET_DUALSPEED is not set
+
+#
+# MMC/SD Card support
+#
+CONFIG_MMC=y
+# CONFIG_MMC_DEBUG is not set
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_AU1X=y
+
+#
+# InfiniBand support
+#
+
+#
+# SN Devices
+#
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+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_FS_XATTR=y
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+CONFIG_JFS_FS=y
+# CONFIG_JFS_POSIX_ACL is not set
+# CONFIG_JFS_SECURITY is not set
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
+CONFIG_FS_POSIX_ACL=y
+# CONFIG_XFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=m
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_ZISOFS_FS=m
+CONFIG_UDF_FS=m
+CONFIG_UDF_NLS=y
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+# CONFIG_RELAYFS_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_JFFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
+CONFIG_JFFS2_ZLIB=y
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN is not set
+CONFIG_CRAMFS=m
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFS_DIRECTIO is not set
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=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=y
+# CONFIG_SMB_NLS_DEFAULT is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=m
+CONFIG_NLS_CODEPAGE_737=m
+CONFIG_NLS_CODEPAGE_775=m
+CONFIG_NLS_CODEPAGE_850=m
+CONFIG_NLS_CODEPAGE_852=m
+CONFIG_NLS_CODEPAGE_855=m
+CONFIG_NLS_CODEPAGE_857=m
+CONFIG_NLS_CODEPAGE_860=m
+CONFIG_NLS_CODEPAGE_861=m
+CONFIG_NLS_CODEPAGE_862=m
+CONFIG_NLS_CODEPAGE_863=m
+CONFIG_NLS_CODEPAGE_864=m
+CONFIG_NLS_CODEPAGE_865=m
+CONFIG_NLS_CODEPAGE_866=m
+CONFIG_NLS_CODEPAGE_869=m
+CONFIG_NLS_CODEPAGE_936=m
+CONFIG_NLS_CODEPAGE_950=m
+CONFIG_NLS_CODEPAGE_932=m
+CONFIG_NLS_CODEPAGE_949=m
+CONFIG_NLS_CODEPAGE_874=m
+CONFIG_NLS_ISO8859_8=m
+CONFIG_NLS_CODEPAGE_1250=m
+CONFIG_NLS_CODEPAGE_1251=m
+CONFIG_NLS_ASCII=m
+CONFIG_NLS_ISO8859_1=m
+CONFIG_NLS_ISO8859_2=m
+CONFIG_NLS_ISO8859_3=m
+CONFIG_NLS_ISO8859_4=m
+CONFIG_NLS_ISO8859_5=m
+CONFIG_NLS_ISO8859_6=m
+CONFIG_NLS_ISO8859_7=m
+CONFIG_NLS_ISO8859_9=m
+CONFIG_NLS_ISO8859_13=m
+CONFIG_NLS_ISO8859_14=m
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_KOI8_R=m
+CONFIG_NLS_KOI8_U=m
+CONFIG_NLS_UTF8=m
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+# CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_CROSSCOMPILE=y
+CONFIG_CMDLINE="mem=48M"
+
+#
+# Security options
+#
+CONFIG_KEYS=y
+CONFIG_KEYS_DEBUG_PROC_KEYS=y
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
+
+#
+# Hardware crypto devices
+#
+
+#
+# Library routines
+#
+CONFIG_CRC_CCITT=y
+# CONFIG_CRC16 is not set
+CONFIG_CRC32=y
+CONFIG_LIBCRC32C=y
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
diff --git a/arch/mips/configs/db1500_defconfig b/arch/mips/configs/db1500_defconfig
index fed6f2fab48b..1c2784dee697 100644
--- a/arch/mips/configs/db1500_defconfig
+++ b/arch/mips/configs/db1500_defconfig
@@ -1,12 +1,9 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-rc2
-# Wed Jan 26 02:49:01 2005
+# Linux kernel version: 2.6.14-rc2
+# Thu Oct 20 22:25:36 2005
#
CONFIG_MIPS=y
-# CONFIG_64BIT is not set
-# CONFIG_64BIT is not set
-CONFIG_32BIT=y
#
# Code maturity level options
@@ -14,24 +11,29 @@ CONFIG_32BIT=y
CONFIG_EXPERIMENTAL=y
CONFIG_CLEAN_COMPILE=y
CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
#
# General setup
#
CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
# CONFIG_POSIX_MQUEUE is not set
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
CONFIG_HOTPLUG=y
CONFIG_KOBJECT_UEVENT=y
# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
CONFIG_EMBEDDED=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
@@ -41,6 +43,7 @@ CONFIG_CC_ALIGN_LABELS=0
CONFIG_CC_ALIGN_LOOPS=0
CONFIG_CC_ALIGN_JUMPS=0
# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
#
# Loadable module support
@@ -56,63 +59,81 @@ CONFIG_KMOD=y
#
# Machine selection
#
-# CONFIG_MACH_JAZZ is not set
-# CONFIG_MACH_VR41XX is not set
-# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_MIPS_PB1550 is not set
+# CONFIG_MIPS_PB1200 is not set
+# CONFIG_MIPS_DB1000 is not set
+# CONFIG_MIPS_DB1100 is not set
+CONFIG_MIPS_DB1500=y
+# CONFIG_MIPS_DB1550 is not set
+# CONFIG_MIPS_DB1200 is not set
+# CONFIG_MIPS_MIRAGE is not set
# CONFIG_MIPS_COBALT is not set
# CONFIG_MACH_DECSTATION is not set
# CONFIG_MIPS_EV64120 is not set
# CONFIG_MIPS_EV96100 is not set
# CONFIG_MIPS_IVR is not set
-# CONFIG_LASAT is not set
# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_LASAT is not set
# CONFIG_MIPS_ATLAS is not set
# CONFIG_MIPS_MALTA is not set
# CONFIG_MIPS_SEAD is not set
+# CONFIG_MIPS_SIM is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
# CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_G is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_JAGUAR_ATX is not set
-# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MIPS_XXS1500 is not set
+# CONFIG_PNX8550_V2PCI is not set
+# CONFIG_PNX8550_JBS is not set
# CONFIG_DDB5074 is not set
# CONFIG_DDB5476 is not set
# CONFIG_DDB5477 is not set
-# CONFIG_NEC_OSPREY is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_QEMU is not set
# CONFIG_SGI_IP22 is not set
-CONFIG_SOC_AU1X00=y
-# CONFIG_SOC_AU1000 is not set
-# CONFIG_SOC_AU1100 is not set
-CONFIG_SOC_AU1500=y
-# CONFIG_SOC_AU1550 is not set
-# CONFIG_MIPS_PB1000 is not set
-# CONFIG_MIPS_PB1100 is not set
-# CONFIG_MIPS_PB1500 is not set
-# CONFIG_MIPS_PB1550 is not set
-# CONFIG_MIPS_DB1000 is not set
-# CONFIG_MIPS_DB1100 is not set
-CONFIG_MIPS_DB1500=y
-# CONFIG_MIPS_DB1550 is not set
-# CONFIG_MIPS_BOSPORUS is not set
-# CONFIG_MIPS_MIRAGE is not set
-# CONFIG_MIPS_XXS1500 is not set
-# CONFIG_MIPS_MTX1 is not set
-# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_BIGSUR is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_PTSWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CRHONE is not set
# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
# CONFIG_TOSHIBA_RBTX4927 is not set
+# CONFIG_TOSHIBA_RBTX4938 is not set
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_HAVE_DEC_LOCK=y
-CONFIG_DMA_COHERENT=y
+CONFIG_DMA_NONCOHERENT=y
+CONFIG_DMA_NEED_PCI_MAP_STATE=y
CONFIG_MIPS_DISABLE_OBSOLETE_IDE=y
+# CONFIG_CPU_BIG_ENDIAN is not set
CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
+CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
+CONFIG_SOC_AU1500=y
+CONFIG_SOC_AU1X00=y
CONFIG_MIPS_L1_CACHE_SHIFT=5
#
# CPU selection
#
-CONFIG_CPU_MIPS32=y
-# CONFIG_CPU_MIPS64 is not set
+CONFIG_CPU_MIPS32_R1=y
+# CONFIG_CPU_MIPS32_R2 is not set
+# CONFIG_CPU_MIPS64_R1 is not set
+# CONFIG_CPU_MIPS64_R2 is not set
# CONFIG_CPU_R3000 is not set
# CONFIG_CPU_TX39XX is not set
# CONFIG_CPU_VR41XX is not set
@@ -128,15 +149,39 @@ CONFIG_CPU_MIPS32=y
# CONFIG_CPU_RM7000 is not set
# CONFIG_CPU_RM9000 is not set
# CONFIG_CPU_SB1 is not set
+CONFIG_SYS_HAS_CPU_MIPS32_R1=y
+CONFIG_CPU_MIPS32=y
+CONFIG_CPU_MIPSR1=y
+CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
+
+#
+# Kernel type
+#
+CONFIG_32BIT=y
+# CONFIG_64BIT is not set
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_CPU_HAS_PREFETCH=y
+# CONFIG_MIPS_MT is not set
CONFIG_64BIT_PHYS_ADDR=y
# CONFIG_CPU_ADVANCED is not set
CONFIG_CPU_HAS_LLSC=y
CONFIG_CPU_HAS_SYNC=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_ARCH_FLATMEM_ENABLE=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_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
#
@@ -145,7 +190,6 @@ CONFIG_CPU_HAS_SYNC=y
CONFIG_HW_HAS_PCI=y
CONFIG_PCI=y
CONFIG_PCI_LEGACY_PROC=y
-CONFIG_PCI_NAMES=y
CONFIG_MMU=y
#
@@ -154,6 +198,8 @@ CONFIG_MMU=y
CONFIG_PCCARD=m
# CONFIG_PCMCIA_DEBUG is not set
CONFIG_PCMCIA=m
+CONFIG_PCMCIA_LOAD_CIS=y
+CONFIG_PCMCIA_IOCTL=y
CONFIG_CARDBUS=y
#
@@ -176,6 +222,100 @@ CONFIG_PCMCIA_AU1X00=m
CONFIG_BINFMT_ELF=y
# CONFIG_BINFMT_MISC is not set
CONFIG_TRAD_SIGNALS=y
+# CONFIG_PM is not set
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+CONFIG_NET_KEY=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+CONFIG_INET_TUNNEL=m
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+
+#
+# IP: Virtual Server Configuration
+#
+# CONFIG_IP_VS is not set
+# CONFIG_IPV6 is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+CONFIG_NETFILTER_NETLINK=m
+CONFIG_NETFILTER_NETLINK_QUEUE=m
+CONFIG_NETFILTER_NETLINK_LOG=m
+
+#
+# IP: Netfilter Configuration
+#
+# CONFIG_IP_NF_CONNTRACK is not set
+CONFIG_IP_NF_PPTP=m
+# CONFIG_IP_NF_QUEUE is not set
+# CONFIG_IP_NF_IPTABLES is not set
+# CONFIG_IP_NF_ARPTABLES is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP 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_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_IEEE80211=m
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=m
+CONFIG_IEEE80211_CRYPT_CCMP=m
+CONFIG_IEEE80211_CRYPT_TKIP=m
#
# Device Drivers
@@ -186,15 +326,20 @@ CONFIG_TRAD_SIGNALS=y
#
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
+CONFIG_FW_LOADER=m
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+CONFIG_CONNECTOR=m
#
# Memory Technology Devices (MTD)
#
CONFIG_MTD=y
# CONFIG_MTD_DEBUG is not set
-CONFIG_MTD_PARTITIONS=y
# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
# CONFIG_MTD_REDBOOT_PARTS is not set
# CONFIG_MTD_CMDLINE_PARTS is not set
@@ -232,16 +377,14 @@ 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 is not set
-CONFIG_MTD_DB1X00=y
-CONFIG_MTD_DB1X00_BOOT=y
-CONFIG_MTD_DB1X00_USER=y
+CONFIG_MTD_ALCHEMY=y
+# CONFIG_MTD_PLATRAM is not set
#
# Self-contained MTD device drivers
@@ -277,7 +420,6 @@ CONFIG_MTD_DB1X00_USER=y
#
# Block devices
#
-# CONFIG_BLK_DEV_FD is not set
# CONFIG_BLK_CPQ_DA is not set
# CONFIG_BLK_CPQ_CISS_DA is not set
# CONFIG_BLK_DEV_DAC960 is not set
@@ -290,7 +432,6 @@ CONFIG_BLK_DEV_LOOP=y
# CONFIG_BLK_DEV_UB is not set
# CONFIG_BLK_DEV_RAM is not set
CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_INITRAMFS_SOURCE=""
# CONFIG_LBD is not set
CONFIG_CDROM_PKTCDVD=m
CONFIG_CDROM_PKTCDVD_BUFFERS=8
@@ -336,6 +477,7 @@ CONFIG_BLK_DEV_IDECS=m
#
# SCSI device support
#
+CONFIG_RAID_ATTRS=m
# CONFIG_SCSI is not set
#
@@ -346,6 +488,7 @@ CONFIG_BLK_DEV_IDECS=m
#
# Fusion MPT device support
#
+# CONFIG_FUSION is not set
#
# IEEE 1394 (FireWire) support
@@ -358,94 +501,13 @@ CONFIG_BLK_DEV_IDECS=m
# CONFIG_I2O is not set
#
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
-CONFIG_NETLINK_DEV=y
-CONFIG_UNIX=y
-CONFIG_NET_KEY=y
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-# CONFIG_IP_ADVANCED_ROUTER is not set
-CONFIG_IP_PNP=y
-# CONFIG_IP_PNP_DHCP is not set
-CONFIG_IP_PNP_BOOTP=y
-# CONFIG_IP_PNP_RARP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_IP_MROUTE is not set
-# CONFIG_ARPD is not set
-# CONFIG_SYN_COOKIES is not set
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-CONFIG_INET_TUNNEL=m
-CONFIG_IP_TCPDIAG=m
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-
-#
-# IP: Virtual Server Configuration
+# Network device support
#
-# CONFIG_IP_VS is not set
-# CONFIG_IPV6 is not set
-CONFIG_NETFILTER=y
-# CONFIG_NETFILTER_DEBUG is not set
-
-#
-# IP: Netfilter Configuration
-#
-# CONFIG_IP_NF_CONNTRACK is not set
-CONFIG_IP_NF_CONNTRACK_MARK=y
-# CONFIG_IP_NF_QUEUE is not set
-# CONFIG_IP_NF_IPTABLES is not set
-# CONFIG_IP_NF_ARPTABLES is not set
-CONFIG_XFRM=y
-CONFIG_XFRM_USER=m
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP 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_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
CONFIG_NETDEVICES=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_EQUALIZER is not set
# CONFIG_TUN is not set
-# CONFIG_ETHERTAP is not set
#
# ARCnet devices
@@ -453,6 +515,21 @@ CONFIG_NETDEVICES=y
# CONFIG_ARCNET is not set
#
+# PHY device support
+#
+CONFIG_PHYLIB=m
+CONFIG_PHYCONTROL=y
+
+#
+# MII PHY device drivers
+#
+CONFIG_MARVELL_PHY=m
+CONFIG_DAVICOM_PHY=m
+CONFIG_QSEMI_PHY=m
+CONFIG_LXT_PHY=m
+CONFIG_CICADA_PHY=m
+
+#
# Ethernet (10 or 100Mbit)
#
CONFIG_NET_ETHERNET=y
@@ -479,12 +556,16 @@ CONFIG_MIPS_AU1X00_ENET=y
# CONFIG_HAMACHI is not set
# CONFIG_YELLOWFIN is not set
# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
# CONFIG_SK98LIN is not set
# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
#
# Ethernet (10000 Mbit)
#
+# CONFIG_CHELSIO_T1 is not set
# CONFIG_IXGB is not set
# CONFIG_S2IO is not set
@@ -497,6 +578,8 @@ CONFIG_MIPS_AU1X00_ENET=y
# Wireless LAN (non-hamradio)
#
# CONFIG_NET_RADIO is not set
+# CONFIG_IPW_DEBUG is not set
+CONFIG_IPW2200=m
#
# PCMCIA network device support
@@ -520,6 +603,8 @@ CONFIG_PPPOE=m
# CONFIG_SLIP is not set
# CONFIG_SHAPER is not set
# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
#
# ISDN subsystem
@@ -549,19 +634,6 @@ CONFIG_INPUT_EVDEV=y
# CONFIG_INPUT_EVBUG is not set
#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=y
-# CONFIG_SERIO_I8042 is not set
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_PCIPS2 is not set
-# CONFIG_SERIO_LIBPS2 is not set
-CONFIG_SERIO_RAW=m
-
-#
# Input Device Drivers
#
# CONFIG_INPUT_KEYBOARD is not set
@@ -571,6 +643,17 @@ CONFIG_SERIO_RAW=m
# CONFIG_INPUT_MISC is not set
#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_PCIPS2 is not set
+# CONFIG_SERIO_LIBPS2 is not set
+CONFIG_SERIO_RAW=m
+# CONFIG_GAMEPORT is not set
+
+#
# Character devices
#
# CONFIG_VT is not set
@@ -590,6 +673,7 @@ CONFIG_SERIAL_AU1X00=y
CONFIG_SERIAL_AU1X00_CONSOLE=y
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
CONFIG_UNIX98_PTYS=y
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
@@ -603,7 +687,8 @@ CONFIG_LEGACY_PTY_COUNT=256
# Watchdog Cards
#
# CONFIG_WATCHDOG is not set
-CONFIG_RTC=y
+# CONFIG_RTC is not set
+# CONFIG_GEN_RTC is not set
# CONFIG_DTLK is not set
# CONFIG_R3964 is not set
# CONFIG_APPLICOM is not set
@@ -620,6 +705,11 @@ CONFIG_SYNCLINK_CS=m
# CONFIG_RAW_DRIVER is not set
#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+
+#
# I2C support
#
# CONFIG_I2C is not set
@@ -630,10 +720,20 @@ CONFIG_SYNCLINK_CS=m
# CONFIG_W1 is not set
#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
+#
# Misc devices
#
#
+# Multimedia Capabilities Port drivers
+#
+
+#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
@@ -647,7 +747,6 @@ CONFIG_SYNCLINK_CS=m
# Graphics support
#
# CONFIG_FB is not set
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Sound
@@ -680,7 +779,6 @@ CONFIG_SOUND_AU1000=y
# CONFIG_SOUND_MSNDCLAS is not set
# CONFIG_SOUND_MSNDPIN is not set
# CONFIG_SOUND_VIA82CXXX is not set
-# CONFIG_SOUND_OSS is not set
# CONFIG_SOUND_ALI5455 is not set
# CONFIG_SOUND_FORTE is not set
# CONFIG_SOUND_RME96XX is not set
@@ -689,6 +787,8 @@ CONFIG_SOUND_AU1000=y
#
# USB support
#
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
CONFIG_USB=y
# CONFIG_USB_DEBUG is not set
@@ -699,23 +799,23 @@ CONFIG_USB=y
# CONFIG_USB_BANDWIDTH is not set
# CONFIG_USB_DYNAMIC_MINORS is not set
# CONFIG_USB_OTG is not set
-CONFIG_USB_ARCH_HAS_HCD=y
-CONFIG_USB_ARCH_HAS_OHCI=y
#
# USB Host Controller Drivers
#
# CONFIG_USB_EHCI_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
CONFIG_USB_OHCI_HCD=y
+# CONFIG_USB_OHCI_BIG_ENDIAN is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
# CONFIG_USB_UHCI_HCD is not set
# CONFIG_USB_SL811_HCD is not set
#
# USB Device Class drivers
#
-# CONFIG_USB_AUDIO is not set
+# CONFIG_OBSOLETE_OSS_USB_DRIVER is not set
# CONFIG_USB_BLUETOOTH_TTY is not set
-# CONFIG_USB_MIDI is not set
# CONFIG_USB_ACM is not set
# CONFIG_USB_PRINTER is not set
@@ -733,12 +833,17 @@ CONFIG_USB_HIDINPUT=y
# CONFIG_USB_HIDDEV is not set
# CONFIG_USB_AIPTEK is not set
# CONFIG_USB_WACOM is not set
+# CONFIG_USB_ACECAD is not set
# CONFIG_USB_KBTAB is not set
# CONFIG_USB_POWERMATE is not set
# CONFIG_USB_MTOUCH is not set
+# CONFIG_USB_ITMTOUCH is not set
# CONFIG_USB_EGALAX is not set
+CONFIG_USB_YEALINK=m
# CONFIG_USB_XPAD is not set
# CONFIG_USB_ATI_REMOTE is not set
+# CONFIG_USB_KEYSPAN_REMOTE is not set
+# CONFIG_USB_APPLETOUCH is not set
#
# USB Imaging devices
@@ -762,6 +867,7 @@ CONFIG_USB_HIDINPUT=y
# CONFIG_USB_PEGASUS is not set
# CONFIG_USB_RTL8150 is not set
# CONFIG_USB_USBNET is not set
+CONFIG_USB_MON=y
#
# USB port drivers
@@ -786,9 +892,10 @@ CONFIG_USB_HIDINPUT=y
# CONFIG_USB_PHIDGETKIT is not set
# CONFIG_USB_PHIDGETSERVO is not set
# CONFIG_USB_IDMOUSE is not set
+CONFIG_USB_LD=m
#
-# USB ATM/DSL drivers
+# USB DSL modem support
#
#
@@ -807,12 +914,17 @@ CONFIG_USB_HIDINPUT=y
# CONFIG_INFINIBAND is not set
#
+# SN Devices
+#
+
+#
# File systems
#
CONFIG_EXT2_FS=y
CONFIG_EXT2_FS_XATTR=y
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_FS_XATTR=y
CONFIG_EXT3_FS_POSIX_ACL=y
@@ -831,10 +943,12 @@ CONFIG_FS_POSIX_ACL=y
# CONFIG_XFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
# CONFIG_QUOTA is not set
CONFIG_DNOTIFY=y
CONFIG_AUTOFS_FS=m
CONFIG_AUTOFS4_FS=m
+CONFIG_FUSE_FS=m
#
# CD-ROM/DVD Filesystems
@@ -855,13 +969,10 @@ CONFIG_AUTOFS4_FS=m
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
-CONFIG_DEVPTS_FS_XATTR=y
-CONFIG_DEVPTS_FS_SECURITY=y
CONFIG_TMPFS=y
-# CONFIG_TMPFS_XATTR is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
+CONFIG_RELAYFS_FS=m
#
# Miscellaneous filesystems
@@ -895,6 +1006,7 @@ CONFIG_NFSD=m
CONFIG_ROOT_NFS=y
CONFIG_LOCKD=y
CONFIG_EXPORTFS=m
+CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
@@ -904,6 +1016,7 @@ CONFIG_SMB_FS=m
# CONFIG_NCP_FS is not set
# CONFIG_CODA_FS is not set
# CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
#
# Partition Types
@@ -963,7 +1076,9 @@ CONFIG_NLS_DEFAULT="iso8859-1"
#
# Kernel hacking
#
+# CONFIG_PRINTK_TIME is not set
# CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=14
CONFIG_CROSSCOMPILE=y
CONFIG_CMDLINE=""
@@ -979,26 +1094,27 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
#
CONFIG_CRYPTO=y
CONFIG_CRYPTO_HMAC=y
-CONFIG_CRYPTO_NULL=y
-# CONFIG_CRYPTO_MD4 is not set
-# CONFIG_CRYPTO_MD5 is not set
-# CONFIG_CRYPTO_SHA1 is not set
-# CONFIG_CRYPTO_SHA256 is not set
-CONFIG_CRYPTO_SHA512=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
CONFIG_CRYPTO_WP512=m
-# CONFIG_CRYPTO_DES is not set
-# CONFIG_CRYPTO_BLOWFISH is not set
-CONFIG_CRYPTO_TWOFISH=y
-# CONFIG_CRYPTO_SERPENT is not set
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_SERPENT=m
CONFIG_CRYPTO_AES=m
-# CONFIG_CRYPTO_CAST5 is not set
-# CONFIG_CRYPTO_CAST6 is not set
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
CONFIG_CRYPTO_TEA=m
-# CONFIG_CRYPTO_ARC4 is not set
+CONFIG_CRYPTO_ARC4=m
CONFIG_CRYPTO_KHAZAD=m
CONFIG_CRYPTO_ANUBIS=m
-CONFIG_CRYPTO_DEFLATE=y
-CONFIG_CRYPTO_MICHAEL_MIC=y
+CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
CONFIG_CRYPTO_CRC32C=m
# CONFIG_CRYPTO_TEST is not set
@@ -1010,9 +1126,8 @@ CONFIG_CRYPTO_CRC32C=m
# Library routines
#
CONFIG_CRC_CCITT=m
+CONFIG_CRC16=m
CONFIG_CRC32=y
CONFIG_LIBCRC32C=m
-CONFIG_ZLIB_INFLATE=y
-CONFIG_ZLIB_DEFLATE=y
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_ZLIB_INFLATE=m
+CONFIG_ZLIB_DEFLATE=m
diff --git a/arch/mips/configs/db1550_defconfig b/arch/mips/configs/db1550_defconfig
index 178c0ad1af75..64248e2e924a 100644
--- a/arch/mips/configs/db1550_defconfig
+++ b/arch/mips/configs/db1550_defconfig
@@ -1,12 +1,9 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-rc2
-# Wed Jan 26 02:49:02 2005
+# Linux kernel version: 2.6.14-rc2
+# Thu Oct 20 22:25:39 2005
#
CONFIG_MIPS=y
-# CONFIG_64BIT is not set
-# CONFIG_64BIT is not set
-CONFIG_32BIT=y
#
# Code maturity level options
@@ -14,24 +11,29 @@ CONFIG_32BIT=y
CONFIG_EXPERIMENTAL=y
CONFIG_CLEAN_COMPILE=y
CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
#
# General setup
#
CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
# CONFIG_POSIX_MQUEUE is not set
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
CONFIG_HOTPLUG=y
CONFIG_KOBJECT_UEVENT=y
# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
CONFIG_EMBEDDED=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
@@ -41,6 +43,7 @@ CONFIG_CC_ALIGN_LABELS=0
CONFIG_CC_ALIGN_LOOPS=0
CONFIG_CC_ALIGN_JUMPS=0
# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
#
# Loadable module support
@@ -56,63 +59,80 @@ CONFIG_KMOD=y
#
# Machine selection
#
-# CONFIG_MACH_JAZZ is not set
-# CONFIG_MACH_VR41XX is not set
-# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_MIPS_PB1550 is not set
+# CONFIG_MIPS_PB1200 is not set
+# CONFIG_MIPS_DB1000 is not set
+# CONFIG_MIPS_DB1100 is not set
+# CONFIG_MIPS_DB1500 is not set
+CONFIG_MIPS_DB1550=y
+# CONFIG_MIPS_DB1200 is not set
+# CONFIG_MIPS_MIRAGE is not set
# CONFIG_MIPS_COBALT is not set
# CONFIG_MACH_DECSTATION is not set
# CONFIG_MIPS_EV64120 is not set
# CONFIG_MIPS_EV96100 is not set
# CONFIG_MIPS_IVR is not set
-# CONFIG_LASAT is not set
# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_LASAT is not set
# CONFIG_MIPS_ATLAS is not set
# CONFIG_MIPS_MALTA is not set
# CONFIG_MIPS_SEAD is not set
+# CONFIG_MIPS_SIM is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
# CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_G is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_JAGUAR_ATX is not set
-# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MIPS_XXS1500 is not set
+# CONFIG_PNX8550_V2PCI is not set
+# CONFIG_PNX8550_JBS is not set
# CONFIG_DDB5074 is not set
# CONFIG_DDB5476 is not set
# CONFIG_DDB5477 is not set
-# CONFIG_NEC_OSPREY is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_QEMU is not set
# CONFIG_SGI_IP22 is not set
-CONFIG_SOC_AU1X00=y
-# CONFIG_SOC_AU1000 is not set
-# CONFIG_SOC_AU1100 is not set
-# CONFIG_SOC_AU1500 is not set
-CONFIG_SOC_AU1550=y
-# CONFIG_MIPS_PB1000 is not set
-# CONFIG_MIPS_PB1100 is not set
-# CONFIG_MIPS_PB1500 is not set
-# CONFIG_MIPS_PB1550 is not set
-# CONFIG_MIPS_DB1000 is not set
-# CONFIG_MIPS_DB1100 is not set
-# CONFIG_MIPS_DB1500 is not set
-CONFIG_MIPS_DB1550=y
-# CONFIG_MIPS_BOSPORUS is not set
-# CONFIG_MIPS_MIRAGE is not set
-# CONFIG_MIPS_XXS1500 is not set
-# CONFIG_MIPS_MTX1 is not set
-# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_BIGSUR is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_PTSWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CRHONE is not set
# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
# CONFIG_TOSHIBA_RBTX4927 is not set
+# CONFIG_TOSHIBA_RBTX4938 is not set
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_HAVE_DEC_LOCK=y
-CONFIG_DMA_COHERENT=y
+CONFIG_DMA_NONCOHERENT=y
+CONFIG_DMA_NEED_PCI_MAP_STATE=y
CONFIG_MIPS_DISABLE_OBSOLETE_IDE=y
+# CONFIG_CPU_BIG_ENDIAN is not set
CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
+CONFIG_SOC_AU1550=y
+CONFIG_SOC_AU1X00=y
CONFIG_MIPS_L1_CACHE_SHIFT=5
#
# CPU selection
#
-CONFIG_CPU_MIPS32=y
-# CONFIG_CPU_MIPS64 is not set
+CONFIG_CPU_MIPS32_R1=y
+# CONFIG_CPU_MIPS32_R2 is not set
+# CONFIG_CPU_MIPS64_R1 is not set
+# CONFIG_CPU_MIPS64_R2 is not set
# CONFIG_CPU_R3000 is not set
# CONFIG_CPU_TX39XX is not set
# CONFIG_CPU_VR41XX is not set
@@ -128,15 +148,39 @@ CONFIG_CPU_MIPS32=y
# CONFIG_CPU_RM7000 is not set
# CONFIG_CPU_RM9000 is not set
# CONFIG_CPU_SB1 is not set
+CONFIG_SYS_HAS_CPU_MIPS32_R1=y
+CONFIG_CPU_MIPS32=y
+CONFIG_CPU_MIPSR1=y
+CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
+
+#
+# Kernel type
+#
+CONFIG_32BIT=y
+# CONFIG_64BIT is not set
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_CPU_HAS_PREFETCH=y
+# CONFIG_MIPS_MT is not set
CONFIG_64BIT_PHYS_ADDR=y
# CONFIG_CPU_ADVANCED is not set
CONFIG_CPU_HAS_LLSC=y
CONFIG_CPU_HAS_SYNC=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_ARCH_FLATMEM_ENABLE=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_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
#
@@ -145,7 +189,6 @@ CONFIG_CPU_HAS_SYNC=y
CONFIG_HW_HAS_PCI=y
CONFIG_PCI=y
CONFIG_PCI_LEGACY_PROC=y
-CONFIG_PCI_NAMES=y
CONFIG_MMU=y
#
@@ -154,6 +197,8 @@ CONFIG_MMU=y
CONFIG_PCCARD=m
# CONFIG_PCMCIA_DEBUG is not set
CONFIG_PCMCIA=m
+CONFIG_PCMCIA_LOAD_CIS=y
+CONFIG_PCMCIA_IOCTL=y
CONFIG_CARDBUS=y
#
@@ -176,6 +221,100 @@ CONFIG_PCMCIA_AU1X00=m
CONFIG_BINFMT_ELF=y
# CONFIG_BINFMT_MISC is not set
CONFIG_TRAD_SIGNALS=y
+# CONFIG_PM is not set
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+CONFIG_NET_KEY=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+CONFIG_INET_TUNNEL=m
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+
+#
+# IP: Virtual Server Configuration
+#
+# CONFIG_IP_VS is not set
+# CONFIG_IPV6 is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+CONFIG_NETFILTER_NETLINK=m
+CONFIG_NETFILTER_NETLINK_QUEUE=m
+CONFIG_NETFILTER_NETLINK_LOG=m
+
+#
+# IP: Netfilter Configuration
+#
+# CONFIG_IP_NF_CONNTRACK is not set
+CONFIG_IP_NF_PPTP=m
+# CONFIG_IP_NF_QUEUE is not set
+# CONFIG_IP_NF_IPTABLES is not set
+# CONFIG_IP_NF_ARPTABLES is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP 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_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_IEEE80211=m
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=m
+CONFIG_IEEE80211_CRYPT_CCMP=m
+CONFIG_IEEE80211_CRYPT_TKIP=m
#
# Device Drivers
@@ -186,15 +325,20 @@ CONFIG_TRAD_SIGNALS=y
#
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
+CONFIG_FW_LOADER=m
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+CONFIG_CONNECTOR=m
#
# Memory Technology Devices (MTD)
#
CONFIG_MTD=y
# CONFIG_MTD_DEBUG is not set
-CONFIG_MTD_PARTITIONS=y
# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
# CONFIG_MTD_REDBOOT_PARTS is not set
# CONFIG_MTD_CMDLINE_PARTS is not set
@@ -238,9 +382,8 @@ CONFIG_MTD_CFI_UTIL=y
#
# CONFIG_MTD_COMPLEX_MAPPINGS is not set
# CONFIG_MTD_PHYSMAP is not set
-CONFIG_MTD_DB1550=y
-CONFIG_MTD_DB1550_BOOT=y
-CONFIG_MTD_DB1550_USER=y
+CONFIG_MTD_ALCHEMY=y
+# CONFIG_MTD_PLATRAM is not set
#
# Self-contained MTD device drivers
@@ -281,7 +424,6 @@ CONFIG_MTD_NAND_AU1550=m
#
# Block devices
#
-# CONFIG_BLK_DEV_FD is not set
# CONFIG_BLK_CPQ_DA is not set
# CONFIG_BLK_CPQ_CISS_DA is not set
# CONFIG_BLK_DEV_DAC960 is not set
@@ -293,7 +435,6 @@ CONFIG_BLK_DEV_LOOP=y
# CONFIG_BLK_DEV_SX8 is not set
# CONFIG_BLK_DEV_RAM is not set
CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_INITRAMFS_SOURCE=""
# CONFIG_LBD is not set
CONFIG_CDROM_PKTCDVD=m
CONFIG_CDROM_PKTCDVD_BUFFERS=8
@@ -350,6 +491,7 @@ CONFIG_BLK_DEV_IDEDMA_PCI=y
# CONFIG_BLK_DEV_HPT366 is not set
# CONFIG_BLK_DEV_SC1200 is not set
# CONFIG_BLK_DEV_PIIX is not set
+# CONFIG_BLK_DEV_IT821X is not set
# CONFIG_BLK_DEV_NS87415 is not set
# CONFIG_BLK_DEV_PDC202XX_OLD is not set
# CONFIG_BLK_DEV_PDC202XX_NEW is not set
@@ -367,6 +509,7 @@ CONFIG_BLK_DEV_IDEDMA=y
#
# SCSI device support
#
+CONFIG_RAID_ATTRS=m
# CONFIG_SCSI is not set
#
@@ -377,6 +520,7 @@ CONFIG_BLK_DEV_IDEDMA=y
#
# Fusion MPT device support
#
+# CONFIG_FUSION is not set
#
# IEEE 1394 (FireWire) support
@@ -389,94 +533,13 @@ CONFIG_BLK_DEV_IDEDMA=y
# CONFIG_I2O is not set
#
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
-CONFIG_NETLINK_DEV=y
-CONFIG_UNIX=y
-CONFIG_NET_KEY=y
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-# CONFIG_IP_ADVANCED_ROUTER is not set
-CONFIG_IP_PNP=y
-# CONFIG_IP_PNP_DHCP is not set
-CONFIG_IP_PNP_BOOTP=y
-# CONFIG_IP_PNP_RARP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_IP_MROUTE is not set
-# CONFIG_ARPD is not set
-# CONFIG_SYN_COOKIES is not set
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-CONFIG_INET_TUNNEL=m
-CONFIG_IP_TCPDIAG=m
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-
-#
-# IP: Virtual Server Configuration
+# Network device support
#
-# CONFIG_IP_VS is not set
-# CONFIG_IPV6 is not set
-CONFIG_NETFILTER=y
-# CONFIG_NETFILTER_DEBUG is not set
-
-#
-# IP: Netfilter Configuration
-#
-# CONFIG_IP_NF_CONNTRACK is not set
-CONFIG_IP_NF_CONNTRACK_MARK=y
-# CONFIG_IP_NF_QUEUE is not set
-# CONFIG_IP_NF_IPTABLES is not set
-# CONFIG_IP_NF_ARPTABLES is not set
-CONFIG_XFRM=y
-CONFIG_XFRM_USER=m
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP 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_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
CONFIG_NETDEVICES=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_EQUALIZER is not set
# CONFIG_TUN is not set
-# CONFIG_ETHERTAP is not set
#
# ARCnet devices
@@ -484,6 +547,21 @@ CONFIG_NETDEVICES=y
# CONFIG_ARCNET is not set
#
+# PHY device support
+#
+CONFIG_PHYLIB=m
+CONFIG_PHYCONTROL=y
+
+#
+# MII PHY device drivers
+#
+CONFIG_MARVELL_PHY=m
+CONFIG_DAVICOM_PHY=m
+CONFIG_QSEMI_PHY=m
+CONFIG_LXT_PHY=m
+CONFIG_CICADA_PHY=m
+
+#
# Ethernet (10 or 100Mbit)
#
CONFIG_NET_ETHERNET=y
@@ -510,12 +588,16 @@ CONFIG_MIPS_AU1X00_ENET=y
# CONFIG_HAMACHI is not set
# CONFIG_YELLOWFIN is not set
# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
# CONFIG_SK98LIN is not set
# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
#
# Ethernet (10000 Mbit)
#
+# CONFIG_CHELSIO_T1 is not set
# CONFIG_IXGB is not set
# CONFIG_S2IO is not set
@@ -528,6 +610,8 @@ CONFIG_MIPS_AU1X00_ENET=y
# Wireless LAN (non-hamradio)
#
# CONFIG_NET_RADIO is not set
+# CONFIG_IPW_DEBUG is not set
+CONFIG_IPW2200=m
#
# PCMCIA network device support
@@ -559,6 +643,8 @@ CONFIG_PPPOE=m
# CONFIG_SLIP is not set
# CONFIG_SHAPER is not set
# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
#
# ISDN subsystem
@@ -588,19 +674,6 @@ CONFIG_INPUT_EVDEV=y
# CONFIG_INPUT_EVBUG is not set
#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=y
-# CONFIG_SERIO_I8042 is not set
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_PCIPS2 is not set
-# CONFIG_SERIO_LIBPS2 is not set
-CONFIG_SERIO_RAW=m
-
-#
# Input Device Drivers
#
# CONFIG_INPUT_KEYBOARD is not set
@@ -610,6 +683,17 @@ CONFIG_SERIO_RAW=m
# CONFIG_INPUT_MISC is not set
#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_PCIPS2 is not set
+# CONFIG_SERIO_LIBPS2 is not set
+CONFIG_SERIO_RAW=m
+# CONFIG_GAMEPORT is not set
+
+#
# Character devices
#
# CONFIG_VT is not set
@@ -629,6 +713,7 @@ CONFIG_SERIAL_AU1X00=y
CONFIG_SERIAL_AU1X00_CONSOLE=y
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
CONFIG_UNIX98_PTYS=y
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
@@ -660,6 +745,11 @@ CONFIG_SYNCLINK_CS=m
# CONFIG_RAW_DRIVER is not set
#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+
+#
# I2C support
#
# CONFIG_I2C is not set
@@ -670,10 +760,20 @@ CONFIG_SYNCLINK_CS=m
# CONFIG_W1 is not set
#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
+#
# Misc devices
#
#
+# Multimedia Capabilities Port drivers
+#
+
+#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
@@ -687,7 +787,6 @@ CONFIG_SYNCLINK_CS=m
# Graphics support
#
# CONFIG_FB is not set
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Sound
@@ -697,13 +796,9 @@ CONFIG_SYNCLINK_CS=m
#
# USB support
#
-# CONFIG_USB is not set
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB_ARCH_HAS_OHCI=y
-
-#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
-#
+# CONFIG_USB is not set
#
# USB Gadget Support
@@ -721,12 +816,17 @@ CONFIG_USB_ARCH_HAS_OHCI=y
# CONFIG_INFINIBAND is not set
#
+# SN Devices
+#
+
+#
# File systems
#
CONFIG_EXT2_FS=y
CONFIG_EXT2_FS_XATTR=y
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_FS_XATTR=y
CONFIG_EXT3_FS_POSIX_ACL=y
@@ -745,10 +845,12 @@ CONFIG_FS_POSIX_ACL=y
# CONFIG_XFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
# CONFIG_QUOTA is not set
CONFIG_DNOTIFY=y
CONFIG_AUTOFS_FS=m
CONFIG_AUTOFS4_FS=m
+CONFIG_FUSE_FS=m
#
# CD-ROM/DVD Filesystems
@@ -769,13 +871,10 @@ CONFIG_AUTOFS4_FS=m
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
-CONFIG_DEVPTS_FS_XATTR=y
-CONFIG_DEVPTS_FS_SECURITY=y
CONFIG_TMPFS=y
-# CONFIG_TMPFS_XATTR is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
+CONFIG_RELAYFS_FS=m
#
# Miscellaneous filesystems
@@ -809,6 +908,7 @@ CONFIG_NFSD=m
CONFIG_ROOT_NFS=y
CONFIG_LOCKD=y
CONFIG_EXPORTFS=m
+CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
@@ -818,6 +918,7 @@ CONFIG_SMB_FS=m
# CONFIG_NCP_FS is not set
# CONFIG_CODA_FS is not set
# CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
#
# Partition Types
@@ -877,7 +978,9 @@ CONFIG_NLS_DEFAULT="iso8859-1"
#
# Kernel hacking
#
+# CONFIG_PRINTK_TIME is not set
# CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=14
CONFIG_CROSSCOMPILE=y
CONFIG_CMDLINE=""
@@ -893,26 +996,27 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
#
CONFIG_CRYPTO=y
CONFIG_CRYPTO_HMAC=y
-CONFIG_CRYPTO_NULL=y
-# CONFIG_CRYPTO_MD4 is not set
-# CONFIG_CRYPTO_MD5 is not set
-# CONFIG_CRYPTO_SHA1 is not set
-# CONFIG_CRYPTO_SHA256 is not set
-CONFIG_CRYPTO_SHA512=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
CONFIG_CRYPTO_WP512=m
-# CONFIG_CRYPTO_DES is not set
-# CONFIG_CRYPTO_BLOWFISH is not set
-CONFIG_CRYPTO_TWOFISH=y
-# CONFIG_CRYPTO_SERPENT is not set
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_SERPENT=m
CONFIG_CRYPTO_AES=m
-# CONFIG_CRYPTO_CAST5 is not set
-# CONFIG_CRYPTO_CAST6 is not set
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
CONFIG_CRYPTO_TEA=m
-# CONFIG_CRYPTO_ARC4 is not set
+CONFIG_CRYPTO_ARC4=m
CONFIG_CRYPTO_KHAZAD=m
CONFIG_CRYPTO_ANUBIS=m
-CONFIG_CRYPTO_DEFLATE=y
-CONFIG_CRYPTO_MICHAEL_MIC=y
+CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
CONFIG_CRYPTO_CRC32C=m
# CONFIG_CRYPTO_TEST is not set
@@ -924,9 +1028,8 @@ CONFIG_CRYPTO_CRC32C=m
# Library routines
#
CONFIG_CRC_CCITT=m
+CONFIG_CRC16=m
CONFIG_CRC32=y
CONFIG_LIBCRC32C=m
-CONFIG_ZLIB_INFLATE=y
-CONFIG_ZLIB_DEFLATE=y
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_ZLIB_INFLATE=m
+CONFIG_ZLIB_DEFLATE=m
diff --git a/arch/mips/configs/ddb5476_defconfig b/arch/mips/configs/ddb5476_defconfig
index 70addc73f699..326f3aa63741 100644
--- a/arch/mips/configs/ddb5476_defconfig
+++ b/arch/mips/configs/ddb5476_defconfig
@@ -1,12 +1,9 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-rc2
-# Wed Jan 26 02:49:02 2005
+# Linux kernel version: 2.6.14-rc2
+# Thu Oct 20 22:25:42 2005
#
CONFIG_MIPS=y
-# CONFIG_64BIT is not set
-# CONFIG_64BIT is not set
-CONFIG_32BIT=y
#
# Code maturity level options
@@ -14,24 +11,29 @@ CONFIG_32BIT=y
CONFIG_EXPERIMENTAL=y
CONFIG_CLEAN_COMPILE=y
CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
#
# General setup
#
CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
# CONFIG_POSIX_MQUEUE is not set
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_HOTPLUG is not set
+CONFIG_HOTPLUG=y
CONFIG_KOBJECT_UEVENT=y
# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
CONFIG_EMBEDDED=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
@@ -41,6 +43,7 @@ CONFIG_CC_ALIGN_LABELS=0
CONFIG_CC_ALIGN_LOOPS=0
CONFIG_CC_ALIGN_JUMPS=0
# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
#
# Loadable module support
@@ -50,41 +53,69 @@ CONFIG_CC_ALIGN_JUMPS=0
#
# Machine selection
#
-# CONFIG_MACH_JAZZ is not set
-# CONFIG_MACH_VR41XX is not set
-# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_MIPS_PB1550 is not set
+# CONFIG_MIPS_PB1200 is not set
+# CONFIG_MIPS_DB1000 is not set
+# CONFIG_MIPS_DB1100 is not set
+# CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
+# CONFIG_MIPS_DB1200 is not set
+# CONFIG_MIPS_MIRAGE is not set
# CONFIG_MIPS_COBALT is not set
# CONFIG_MACH_DECSTATION is not set
# CONFIG_MIPS_EV64120 is not set
# CONFIG_MIPS_EV96100 is not set
# CONFIG_MIPS_IVR is not set
-# CONFIG_LASAT is not set
# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_LASAT is not set
# CONFIG_MIPS_ATLAS is not set
# CONFIG_MIPS_MALTA is not set
# CONFIG_MIPS_SEAD is not set
+# CONFIG_MIPS_SIM is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
# CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_G is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_JAGUAR_ATX is not set
-# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MIPS_XXS1500 is not set
+# CONFIG_PNX8550_V2PCI is not set
+# CONFIG_PNX8550_JBS is not set
# CONFIG_DDB5074 is not set
CONFIG_DDB5476=y
# CONFIG_DDB5477 is not set
-# CONFIG_NEC_OSPREY is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_QEMU is not set
# CONFIG_SGI_IP22 is not set
-# CONFIG_SOC_AU1X00 is not set
-# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_BIGSUR is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_PTSWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CRHONE is not set
# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
# CONFIG_TOSHIBA_RBTX4927 is not set
+# CONFIG_TOSHIBA_RBTX4938 is not set
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_HAVE_DEC_LOCK=y
CONFIG_DMA_NONCOHERENT=y
CONFIG_DMA_NEED_PCI_MAP_STATE=y
CONFIG_I8259=y
+# CONFIG_CPU_BIG_ENDIAN is not set
CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
CONFIG_IRQ_CPU=y
CONFIG_DDB5XXX_COMMON=y
CONFIG_MIPS_L1_CACHE_SHIFT=5
@@ -93,8 +124,10 @@ CONFIG_HAVE_STD_PC_SERIAL_PORT=y
#
# CPU selection
#
-# CONFIG_CPU_MIPS32 is not set
-# CONFIG_CPU_MIPS64 is not set
+# CONFIG_CPU_MIPS32_R1 is not set
+# CONFIG_CPU_MIPS32_R2 is not set
+# CONFIG_CPU_MIPS64_R1 is not set
+# CONFIG_CPU_MIPS64_R2 is not set
# CONFIG_CPU_R3000 is not set
# CONFIG_CPU_TX39XX is not set
# CONFIG_CPU_VR41XX is not set
@@ -110,14 +143,38 @@ CONFIG_CPU_R5432=y
# CONFIG_CPU_RM7000 is not set
# CONFIG_CPU_RM9000 is not set
# CONFIG_CPU_SB1 is not set
+CONFIG_SYS_HAS_CPU_R5432=y
+CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
+CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y
+
+#
+# Kernel type
+#
+CONFIG_32BIT=y
+# CONFIG_64BIT is not set
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_MIPS_MT is not set
# CONFIG_CPU_ADVANCED is not set
CONFIG_CPU_HAS_LLSC=y
CONFIG_CPU_HAS_LLDSCD=y
CONFIG_CPU_HAS_SYNC=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_ARCH_FLATMEM_ENABLE=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_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
#
@@ -126,7 +183,6 @@ CONFIG_CPU_HAS_SYNC=y
CONFIG_HW_HAS_PCI=y
CONFIG_PCI=y
CONFIG_PCI_LEGACY_PROC=y
-CONFIG_PCI_NAMES=y
CONFIG_ISA=y
CONFIG_MMU=y
@@ -136,11 +192,6 @@ CONFIG_MMU=y
# CONFIG_PCCARD is not set
#
-# PC-card bridges
-#
-CONFIG_PCMCIA_PROBE=y
-
-#
# PCI Hotplug Support
#
# CONFIG_HOTPLUG_PCI is not set
@@ -153,6 +204,80 @@ CONFIG_BINFMT_ELF=y
CONFIG_TRAD_SIGNALS=y
#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=y
+CONFIG_NET_KEY=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+CONFIG_INET_TUNNEL=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+# CONFIG_IPV6 is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# 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_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_IEEE80211=y
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=y
+CONFIG_IEEE80211_CRYPT_CCMP=y
+CONFIG_IEEE80211_CRYPT_TKIP=y
+
+#
# Device Drivers
#
@@ -161,7 +286,12 @@ CONFIG_TRAD_SIGNALS=y
#
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
+CONFIG_FW_LOADER=y
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+CONFIG_CONNECTOR=y
#
# Memory Technology Devices (MTD)
@@ -181,8 +311,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
#
# Block devices
#
-# CONFIG_BLK_DEV_FD is not set
-# CONFIG_BLK_DEV_XD is not set
# CONFIG_BLK_CPQ_DA is not set
# CONFIG_BLK_CPQ_CISS_DA is not set
# CONFIG_BLK_DEV_DAC960 is not set
@@ -193,7 +321,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_BLK_DEV_SX8 is not set
# CONFIG_BLK_DEV_RAM is not set
CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_INITRAMFS_SOURCE=""
# CONFIG_LBD is not set
CONFIG_CDROM_PKTCDVD=y
CONFIG_CDROM_PKTCDVD_BUFFERS=8
@@ -239,6 +366,7 @@ CONFIG_IDE_GENERIC=y
#
# SCSI device support
#
+CONFIG_RAID_ATTRS=y
# CONFIG_SCSI is not set
#
@@ -254,6 +382,7 @@ CONFIG_IDE_GENERIC=y
#
# Fusion MPT device support
#
+# CONFIG_FUSION is not set
#
# IEEE 1394 (FireWire) support
@@ -266,78 +395,13 @@ CONFIG_IDE_GENERIC=y
# CONFIG_I2O is not set
#
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
-CONFIG_NETLINK_DEV=y
-CONFIG_UNIX=y
-CONFIG_NET_KEY=y
-CONFIG_INET=y
-# CONFIG_IP_MULTICAST is not set
-# CONFIG_IP_ADVANCED_ROUTER is not set
-CONFIG_IP_PNP=y
-# CONFIG_IP_PNP_DHCP is not set
-CONFIG_IP_PNP_BOOTP=y
-# CONFIG_IP_PNP_RARP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_ARPD is not set
-# CONFIG_SYN_COOKIES is not set
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-CONFIG_INET_TUNNEL=y
-CONFIG_IP_TCPDIAG=y
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-# CONFIG_IPV6 is not set
-# CONFIG_NETFILTER is not set
-CONFIG_XFRM=y
-CONFIG_XFRM_USER=y
-
-#
-# SCTP Configuration (EXPERIMENTAL)
+# Network device support
#
-# CONFIG_IP_SCTP 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_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
CONFIG_NETDEVICES=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_EQUALIZER is not set
# CONFIG_TUN is not set
-# CONFIG_ETHERTAP is not set
#
# ARCnet devices
@@ -345,6 +409,21 @@ CONFIG_NETDEVICES=y
# CONFIG_ARCNET is not set
#
+# PHY device support
+#
+CONFIG_PHYLIB=y
+CONFIG_PHYCONTROL=y
+
+#
+# MII PHY device drivers
+#
+CONFIG_MARVELL_PHY=y
+CONFIG_DAVICOM_PHY=y
+CONFIG_QSEMI_PHY=y
+CONFIG_LXT_PHY=y
+CONFIG_CICADA_PHY=y
+
+#
# Ethernet (10 or 100Mbit)
#
CONFIG_NET_ETHERNET=y
@@ -352,7 +431,6 @@ CONFIG_NET_ETHERNET=y
# CONFIG_HAPPYMEAL is not set
# CONFIG_SUNGEM is not set
# CONFIG_NET_VENDOR_3COM is not set
-# CONFIG_LANCE is not set
# CONFIG_NET_VENDOR_SMC is not set
# CONFIG_NET_VENDOR_RACAL is not set
@@ -377,12 +455,16 @@ CONFIG_NET_ETHERNET=y
# CONFIG_HAMACHI is not set
# CONFIG_YELLOWFIN is not set
# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
# CONFIG_SK98LIN is not set
# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
#
# Ethernet (10000 Mbit)
#
+# CONFIG_CHELSIO_T1 is not set
# CONFIG_IXGB is not set
# CONFIG_S2IO is not set
@@ -395,6 +477,8 @@ CONFIG_NET_ETHERNET=y
# Wireless LAN (non-hamradio)
#
# CONFIG_NET_RADIO is not set
+# CONFIG_IPW_DEBUG is not set
+CONFIG_IPW2200=y
#
# Wan interfaces
@@ -406,6 +490,8 @@ CONFIG_NET_ETHERNET=y
# CONFIG_SLIP is not set
# CONFIG_SHAPER is not set
# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
#
# ISDN subsystem
@@ -435,19 +521,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
# CONFIG_INPUT_EVBUG is not set
#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=y
-# CONFIG_SERIO_I8042 is not set
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_PCIPS2 is not set
-# CONFIG_SERIO_LIBPS2 is not set
-CONFIG_SERIO_RAW=y
-
-#
# Input Device Drivers
#
# CONFIG_INPUT_KEYBOARD is not set
@@ -457,6 +530,17 @@ CONFIG_SERIO_RAW=y
# CONFIG_INPUT_MISC is not set
#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_PCIPS2 is not set
+# CONFIG_SERIO_LIBPS2 is not set
+CONFIG_SERIO_RAW=y
+# CONFIG_GAMEPORT is not set
+
+#
# Character devices
#
CONFIG_VT=y
@@ -477,6 +561,7 @@ CONFIG_SERIAL_8250_NR_UARTS=4
#
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
CONFIG_UNIX98_PTYS=y
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
@@ -503,6 +588,11 @@ CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_RAW_DRIVER is not set
#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+
+#
# I2C support
#
# CONFIG_I2C is not set
@@ -513,10 +603,20 @@ CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_W1 is not set
#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
+#
# Misc devices
#
#
+# Multimedia Capabilities Port drivers
+#
+
+#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
@@ -530,6 +630,11 @@ CONFIG_LEGACY_PTY_COUNT=256
# Graphics support
#
CONFIG_FB=y
+# CONFIG_FB_CFB_FILLRECT is not set
+# CONFIG_FB_CFB_COPYAREA is not set
+# CONFIG_FB_CFB_IMAGEBLIT is not set
+# CONFIG_FB_SOFT_CURSOR is not set
+# CONFIG_FB_MACMODES is not set
# CONFIG_FB_MODE_HELPERS is not set
# CONFIG_FB_TILEBLITTING is not set
# CONFIG_FB_CIRRUS is not set
@@ -537,6 +642,7 @@ CONFIG_FB=y
# CONFIG_FB_CYBER2000 is not set
# CONFIG_FB_ASILIANT is not set
# CONFIG_FB_IMSTT is not set
+# CONFIG_FB_NVIDIA is not set
# CONFIG_FB_RIVA is not set
# CONFIG_FB_MATROX is not set
# CONFIG_FB_RADEON_OLD is not set
@@ -549,8 +655,10 @@ CONFIG_FB=y
# CONFIG_FB_KYRO is not set
# CONFIG_FB_3DFX is not set
# CONFIG_FB_VOODOO1 is not set
+# CONFIG_FB_SMIVGX is not set
+# CONFIG_FB_CYBLA is not set
# CONFIG_FB_TRIDENT is not set
-# CONFIG_FB_E1356 is not set
+# CONFIG_FB_S1D13XXX is not set
# CONFIG_FB_VIRTUAL is not set
#
@@ -575,13 +683,9 @@ CONFIG_DUMMY_CONSOLE=y
#
# USB support
#
-# CONFIG_USB is not set
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB_ARCH_HAS_OHCI=y
-
-#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
-#
+# CONFIG_USB is not set
#
# USB Gadget Support
@@ -599,21 +703,29 @@ CONFIG_USB_ARCH_HAS_OHCI=y
# CONFIG_INFINIBAND is not set
#
+# SN Devices
+#
+
+#
# File systems
#
CONFIG_EXT2_FS=y
# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
# CONFIG_EXT3_FS is not set
# CONFIG_JBD 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_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
# CONFIG_QUOTA is not set
CONFIG_DNOTIFY=y
# CONFIG_AUTOFS_FS is not set
# CONFIG_AUTOFS4_FS is not set
+CONFIG_FUSE_FS=y
#
# CD-ROM/DVD Filesystems
@@ -634,12 +746,10 @@ CONFIG_DNOTIFY=y
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
-CONFIG_DEVPTS_FS_XATTR=y
-CONFIG_DEVPTS_FS_SECURITY=y
# CONFIG_TMPFS is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
+CONFIG_RELAYFS_FS=y
#
# Miscellaneous filesystems
@@ -668,7 +778,7 @@ CONFIG_NFS_FS=y
# CONFIG_NFSD is not set
CONFIG_ROOT_NFS=y
CONFIG_LOCKD=y
-# CONFIG_EXPORTFS is not set
+CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
@@ -677,6 +787,7 @@ CONFIG_SUNRPC=y
# CONFIG_NCP_FS is not set
# CONFIG_CODA_FS is not set
# CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
#
# Partition Types
@@ -697,7 +808,9 @@ CONFIG_MSDOS_PARTITION=y
#
# Kernel hacking
#
+# CONFIG_PRINTK_TIME is not set
# CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=14
CONFIG_CROSSCOMPILE=y
CONFIG_CMDLINE="ip=any"
@@ -711,7 +824,31 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
#
# Cryptographic options
#
-# CONFIG_CRYPTO is not set
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_NULL=y
+CONFIG_CRYPTO_MD4=y
+CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_SHA1=y
+CONFIG_CRYPTO_SHA256=y
+CONFIG_CRYPTO_SHA512=y
+CONFIG_CRYPTO_WP512=y
+CONFIG_CRYPTO_TGR192=y
+CONFIG_CRYPTO_DES=y
+CONFIG_CRYPTO_BLOWFISH=y
+CONFIG_CRYPTO_TWOFISH=y
+CONFIG_CRYPTO_SERPENT=y
+CONFIG_CRYPTO_AES=y
+CONFIG_CRYPTO_CAST5=y
+CONFIG_CRYPTO_CAST6=y
+CONFIG_CRYPTO_TEA=y
+CONFIG_CRYPTO_ARC4=y
+CONFIG_CRYPTO_KHAZAD=y
+CONFIG_CRYPTO_ANUBIS=y
+CONFIG_CRYPTO_DEFLATE=y
+CONFIG_CRYPTO_MICHAEL_MIC=y
+CONFIG_CRYPTO_CRC32C=y
+# CONFIG_CRYPTO_TEST is not set
#
# Hardware crypto devices
@@ -721,7 +858,8 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
# Library routines
#
# CONFIG_CRC_CCITT is not set
-# CONFIG_CRC32 is not set
-# CONFIG_LIBCRC32C is not set
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_CRC16=y
+CONFIG_CRC32=y
+CONFIG_LIBCRC32C=y
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
diff --git a/arch/mips/configs/ddb5477_defconfig b/arch/mips/configs/ddb5477_defconfig
index 60292808b384..c2a01df3c8df 100644
--- a/arch/mips/configs/ddb5477_defconfig
+++ b/arch/mips/configs/ddb5477_defconfig
@@ -1,12 +1,9 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-rc2
-# Wed Jan 26 02:49:02 2005
+# Linux kernel version: 2.6.14-rc2
+# Thu Oct 20 22:25:45 2005
#
CONFIG_MIPS=y
-# CONFIG_64BIT is not set
-# CONFIG_64BIT is not set
-CONFIG_32BIT=y
#
# Code maturity level options
@@ -14,24 +11,29 @@ CONFIG_32BIT=y
CONFIG_EXPERIMENTAL=y
CONFIG_CLEAN_COMPILE=y
CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
#
# General setup
#
CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
# CONFIG_POSIX_MQUEUE is not set
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_HOTPLUG is not set
+CONFIG_HOTPLUG=y
CONFIG_KOBJECT_UEVENT=y
# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
CONFIG_EMBEDDED=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
@@ -41,6 +43,7 @@ CONFIG_CC_ALIGN_LABELS=0
CONFIG_CC_ALIGN_LOOPS=0
CONFIG_CC_ALIGN_JUMPS=0
# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
#
# Loadable module support
@@ -50,42 +53,70 @@ CONFIG_CC_ALIGN_JUMPS=0
#
# Machine selection
#
-# CONFIG_MACH_JAZZ is not set
-# CONFIG_MACH_VR41XX is not set
-# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_MIPS_PB1550 is not set
+# CONFIG_MIPS_PB1200 is not set
+# CONFIG_MIPS_DB1000 is not set
+# CONFIG_MIPS_DB1100 is not set
+# CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
+# CONFIG_MIPS_DB1200 is not set
+# CONFIG_MIPS_MIRAGE is not set
# CONFIG_MIPS_COBALT is not set
# CONFIG_MACH_DECSTATION is not set
# CONFIG_MIPS_EV64120 is not set
# CONFIG_MIPS_EV96100 is not set
# CONFIG_MIPS_IVR is not set
-# CONFIG_LASAT is not set
# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_LASAT is not set
# CONFIG_MIPS_ATLAS is not set
# CONFIG_MIPS_MALTA is not set
# CONFIG_MIPS_SEAD is not set
+# CONFIG_MIPS_SIM is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
# CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_G is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_JAGUAR_ATX is not set
-# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MIPS_XXS1500 is not set
+# CONFIG_PNX8550_V2PCI is not set
+# CONFIG_PNX8550_JBS is not set
# CONFIG_DDB5074 is not set
# CONFIG_DDB5476 is not set
CONFIG_DDB5477=y
-CONFIG_DDB5477_BUS_FREQUENCY=0
-# CONFIG_NEC_OSPREY is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_QEMU is not set
# CONFIG_SGI_IP22 is not set
-# CONFIG_SOC_AU1X00 is not set
-# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_BIGSUR is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_PTSWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CRHONE is not set
# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
# CONFIG_TOSHIBA_RBTX4927 is not set
+# CONFIG_TOSHIBA_RBTX4938 is not set
+CONFIG_DDB5477_BUS_FREQUENCY=0
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_HAVE_DEC_LOCK=y
CONFIG_DMA_NONCOHERENT=y
CONFIG_DMA_NEED_PCI_MAP_STATE=y
CONFIG_I8259=y
+# CONFIG_CPU_BIG_ENDIAN is not set
CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
CONFIG_IRQ_CPU=y
CONFIG_DDB5XXX_COMMON=y
CONFIG_MIPS_L1_CACHE_SHIFT=5
@@ -93,8 +124,10 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5
#
# CPU selection
#
-# CONFIG_CPU_MIPS32 is not set
-# CONFIG_CPU_MIPS64 is not set
+# CONFIG_CPU_MIPS32_R1 is not set
+# CONFIG_CPU_MIPS32_R2 is not set
+# CONFIG_CPU_MIPS64_R1 is not set
+# CONFIG_CPU_MIPS64_R2 is not set
# CONFIG_CPU_R3000 is not set
# CONFIG_CPU_TX39XX is not set
# CONFIG_CPU_VR41XX is not set
@@ -110,14 +143,38 @@ CONFIG_CPU_R5432=y
# CONFIG_CPU_RM7000 is not set
# CONFIG_CPU_RM9000 is not set
# CONFIG_CPU_SB1 is not set
+CONFIG_SYS_HAS_CPU_R5432=y
+CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
+CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y
+
+#
+# Kernel type
+#
+CONFIG_32BIT=y
+# CONFIG_64BIT is not set
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_MIPS_MT is not set
# CONFIG_CPU_ADVANCED is not set
CONFIG_CPU_HAS_LLSC=y
CONFIG_CPU_HAS_LLDSCD=y
CONFIG_CPU_HAS_SYNC=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_ARCH_FLATMEM_ENABLE=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_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
#
@@ -126,7 +183,6 @@ CONFIG_CPU_HAS_SYNC=y
CONFIG_HW_HAS_PCI=y
CONFIG_PCI=y
CONFIG_PCI_LEGACY_PROC=y
-CONFIG_PCI_NAMES=y
CONFIG_MMU=y
#
@@ -135,10 +191,6 @@ CONFIG_MMU=y
# CONFIG_PCCARD is not set
#
-# PC-card bridges
-#
-
-#
# PCI Hotplug Support
#
# CONFIG_HOTPLUG_PCI is not set
@@ -151,6 +203,80 @@ CONFIG_BINFMT_ELF=y
CONFIG_TRAD_SIGNALS=y
#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=y
+CONFIG_NET_KEY=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+CONFIG_INET_TUNNEL=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+# CONFIG_IPV6 is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# 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_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_IEEE80211=y
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=y
+CONFIG_IEEE80211_CRYPT_CCMP=y
+CONFIG_IEEE80211_CRYPT_TKIP=y
+
+#
# Device Drivers
#
@@ -159,7 +285,12 @@ CONFIG_TRAD_SIGNALS=y
#
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
+CONFIG_FW_LOADER=y
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+CONFIG_CONNECTOR=y
#
# Memory Technology Devices (MTD)
@@ -178,7 +309,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
#
# Block devices
#
-# CONFIG_BLK_DEV_FD is not set
# CONFIG_BLK_CPQ_DA is not set
# CONFIG_BLK_CPQ_CISS_DA is not set
# CONFIG_BLK_DEV_DAC960 is not set
@@ -189,7 +319,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_BLK_DEV_SX8 is not set
# CONFIG_BLK_DEV_RAM is not set
CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_INITRAMFS_SOURCE=""
# CONFIG_LBD is not set
CONFIG_CDROM_PKTCDVD=y
CONFIG_CDROM_PKTCDVD_BUFFERS=8
@@ -212,6 +341,7 @@ CONFIG_ATA_OVER_ETH=y
#
# SCSI device support
#
+CONFIG_RAID_ATTRS=y
# CONFIG_SCSI is not set
#
@@ -222,6 +352,7 @@ CONFIG_ATA_OVER_ETH=y
#
# Fusion MPT device support
#
+# CONFIG_FUSION is not set
#
# IEEE 1394 (FireWire) support
@@ -234,78 +365,13 @@ CONFIG_ATA_OVER_ETH=y
# CONFIG_I2O is not set
#
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
-CONFIG_NETLINK_DEV=y
-CONFIG_UNIX=y
-CONFIG_NET_KEY=y
-CONFIG_INET=y
-# CONFIG_IP_MULTICAST is not set
-# CONFIG_IP_ADVANCED_ROUTER is not set
-CONFIG_IP_PNP=y
-# CONFIG_IP_PNP_DHCP is not set
-CONFIG_IP_PNP_BOOTP=y
-# CONFIG_IP_PNP_RARP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_ARPD is not set
-# CONFIG_SYN_COOKIES is not set
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-CONFIG_INET_TUNNEL=y
-CONFIG_IP_TCPDIAG=y
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-# CONFIG_IPV6 is not set
-# CONFIG_NETFILTER is not set
-CONFIG_XFRM=y
-CONFIG_XFRM_USER=y
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP 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_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
+# Network device support
#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
CONFIG_NETDEVICES=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_EQUALIZER is not set
# CONFIG_TUN is not set
-# CONFIG_ETHERTAP is not set
#
# ARCnet devices
@@ -313,6 +379,21 @@ CONFIG_NETDEVICES=y
# CONFIG_ARCNET is not set
#
+# PHY device support
+#
+CONFIG_PHYLIB=y
+CONFIG_PHYCONTROL=y
+
+#
+# MII PHY device drivers
+#
+CONFIG_MARVELL_PHY=y
+CONFIG_DAVICOM_PHY=y
+CONFIG_QSEMI_PHY=y
+CONFIG_LXT_PHY=y
+CONFIG_CICADA_PHY=y
+
+#
# Ethernet (10 or 100Mbit)
#
CONFIG_NET_ETHERNET=y
@@ -357,13 +438,17 @@ CONFIG_PCNET32=y
# CONFIG_HAMACHI is not set
# CONFIG_YELLOWFIN is not set
# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
# CONFIG_SK98LIN is not set
# CONFIG_VIA_VELOCITY is not set
# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
#
# Ethernet (10000 Mbit)
#
+# CONFIG_CHELSIO_T1 is not set
# CONFIG_IXGB is not set
# CONFIG_S2IO is not set
@@ -376,6 +461,8 @@ CONFIG_PCNET32=y
# Wireless LAN (non-hamradio)
#
# CONFIG_NET_RADIO is not set
+# CONFIG_IPW_DEBUG is not set
+CONFIG_IPW2200=y
#
# Wan interfaces
@@ -387,6 +474,8 @@ CONFIG_PCNET32=y
# CONFIG_SLIP is not set
# CONFIG_SHAPER is not set
# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
#
# ISDN subsystem
@@ -416,19 +505,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
# CONFIG_INPUT_EVBUG is not set
#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=y
-# CONFIG_SERIO_I8042 is not set
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_PCIPS2 is not set
-# CONFIG_SERIO_LIBPS2 is not set
-CONFIG_SERIO_RAW=y
-
-#
# Input Device Drivers
#
# CONFIG_INPUT_KEYBOARD is not set
@@ -438,6 +514,17 @@ CONFIG_SERIO_RAW=y
# CONFIG_INPUT_MISC is not set
#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_PCIPS2 is not set
+# CONFIG_SERIO_LIBPS2 is not set
+CONFIG_SERIO_RAW=y
+# CONFIG_GAMEPORT is not set
+
+#
# Character devices
#
CONFIG_VT=y
@@ -458,6 +545,7 @@ CONFIG_SERIAL_8250_NR_UARTS=4
#
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
CONFIG_UNIX98_PTYS=y
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
@@ -484,6 +572,11 @@ CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_RAW_DRIVER is not set
#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+
+#
# I2C support
#
# CONFIG_I2C is not set
@@ -494,10 +587,20 @@ CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_W1 is not set
#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
+#
# Misc devices
#
#
+# Multimedia Capabilities Port drivers
+#
+
+#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
@@ -517,7 +620,6 @@ CONFIG_LEGACY_PTY_COUNT=256
#
# CONFIG_VGA_CONSOLE is not set
CONFIG_DUMMY_CONSOLE=y
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Sound
@@ -527,13 +629,9 @@ CONFIG_DUMMY_CONSOLE=y
#
# USB support
#
-# CONFIG_USB is not set
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB_ARCH_HAS_OHCI=y
-
-#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
-#
+# CONFIG_USB is not set
#
# USB Gadget Support
@@ -551,21 +649,29 @@ CONFIG_USB_ARCH_HAS_OHCI=y
# CONFIG_INFINIBAND is not set
#
+# SN Devices
+#
+
+#
# File systems
#
CONFIG_EXT2_FS=y
# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
# CONFIG_EXT3_FS is not set
# CONFIG_JBD 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_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
# CONFIG_QUOTA is not set
CONFIG_DNOTIFY=y
CONFIG_AUTOFS_FS=y
CONFIG_AUTOFS4_FS=y
+CONFIG_FUSE_FS=y
#
# CD-ROM/DVD Filesystems
@@ -586,12 +692,10 @@ CONFIG_AUTOFS4_FS=y
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
-CONFIG_DEVPTS_FS_XATTR=y
-CONFIG_DEVPTS_FS_SECURITY=y
# CONFIG_TMPFS is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
+CONFIG_RELAYFS_FS=y
#
# Miscellaneous filesystems
@@ -623,6 +727,7 @@ CONFIG_NFSD=y
CONFIG_ROOT_NFS=y
CONFIG_LOCKD=y
CONFIG_EXPORTFS=y
+CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
@@ -631,6 +736,7 @@ CONFIG_SUNRPC=y
# CONFIG_NCP_FS is not set
# CONFIG_CODA_FS is not set
# CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
#
# Partition Types
@@ -651,7 +757,9 @@ CONFIG_MSDOS_PARTITION=y
#
# Kernel hacking
#
+# CONFIG_PRINTK_TIME is not set
# CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=14
CONFIG_CROSSCOMPILE=y
CONFIG_CMDLINE="ip=any"
@@ -665,7 +773,31 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
#
# Cryptographic options
#
-# CONFIG_CRYPTO is not set
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_NULL=y
+CONFIG_CRYPTO_MD4=y
+CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_SHA1=y
+CONFIG_CRYPTO_SHA256=y
+CONFIG_CRYPTO_SHA512=y
+CONFIG_CRYPTO_WP512=y
+CONFIG_CRYPTO_TGR192=y
+CONFIG_CRYPTO_DES=y
+CONFIG_CRYPTO_BLOWFISH=y
+CONFIG_CRYPTO_TWOFISH=y
+CONFIG_CRYPTO_SERPENT=y
+CONFIG_CRYPTO_AES=y
+CONFIG_CRYPTO_CAST5=y
+CONFIG_CRYPTO_CAST6=y
+CONFIG_CRYPTO_TEA=y
+CONFIG_CRYPTO_ARC4=y
+CONFIG_CRYPTO_KHAZAD=y
+CONFIG_CRYPTO_ANUBIS=y
+CONFIG_CRYPTO_DEFLATE=y
+CONFIG_CRYPTO_MICHAEL_MIC=y
+CONFIG_CRYPTO_CRC32C=y
+# CONFIG_CRYPTO_TEST is not set
#
# Hardware crypto devices
@@ -675,7 +807,8 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
# Library routines
#
# CONFIG_CRC_CCITT is not set
+CONFIG_CRC16=y
CONFIG_CRC32=y
-# CONFIG_LIBCRC32C is not set
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_LIBCRC32C=y
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
diff --git a/arch/mips/configs/decstation_defconfig b/arch/mips/configs/decstation_defconfig
index 66ec1f41d122..5bc885b72d14 100644
--- a/arch/mips/configs/decstation_defconfig
+++ b/arch/mips/configs/decstation_defconfig
@@ -1,12 +1,9 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-rc2
-# Wed Jan 26 02:49:03 2005
+# Linux kernel version: 2.6.14-rc2
+# Thu Oct 20 22:25:48 2005
#
CONFIG_MIPS=y
-# CONFIG_64BIT is not set
-# CONFIG_64BIT is not set
-CONFIG_32BIT=y
#
# Code maturity level options
@@ -14,24 +11,30 @@ CONFIG_32BIT=y
CONFIG_EXPERIMENTAL=y
CONFIG_CLEAN_COMPILE=y
CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
#
# General setup
#
CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
# CONFIG_POSIX_MQUEUE is not set
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
# CONFIG_HOTPLUG is not set
CONFIG_KOBJECT_UEVENT=y
# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
CONFIG_EMBEDDED=y
CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
@@ -41,6 +44,7 @@ CONFIG_CC_ALIGN_LABELS=0
CONFIG_CC_ALIGN_LOOPS=0
CONFIG_CC_ALIGN_JUMPS=0
# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
#
# Loadable module support
@@ -49,48 +53,76 @@ CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
# CONFIG_MODULE_FORCE_UNLOAD is not set
CONFIG_OBSOLETE_MODPARM=y
-CONFIG_MODVERSIONS=y
+# CONFIG_MODVERSIONS is not set
CONFIG_MODULE_SRCVERSION_ALL=y
CONFIG_KMOD=y
#
# Machine selection
#
-# CONFIG_MACH_JAZZ is not set
-# CONFIG_MACH_VR41XX is not set
-# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_MIPS_PB1550 is not set
+# CONFIG_MIPS_PB1200 is not set
+# CONFIG_MIPS_DB1000 is not set
+# CONFIG_MIPS_DB1100 is not set
+# CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
+# CONFIG_MIPS_DB1200 is not set
+# CONFIG_MIPS_MIRAGE is not set
# CONFIG_MIPS_COBALT is not set
CONFIG_MACH_DECSTATION=y
# CONFIG_MIPS_EV64120 is not set
# CONFIG_MIPS_EV96100 is not set
# CONFIG_MIPS_IVR is not set
-# CONFIG_LASAT is not set
# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_LASAT is not set
# CONFIG_MIPS_ATLAS is not set
# CONFIG_MIPS_MALTA is not set
# CONFIG_MIPS_SEAD is not set
+# CONFIG_MIPS_SIM is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
# CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_G is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_JAGUAR_ATX is not set
-# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MIPS_XXS1500 is not set
+# CONFIG_PNX8550_V2PCI is not set
+# CONFIG_PNX8550_JBS is not set
# CONFIG_DDB5074 is not set
# CONFIG_DDB5476 is not set
# CONFIG_DDB5477 is not set
-# CONFIG_NEC_OSPREY is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_QEMU is not set
# CONFIG_SGI_IP22 is not set
-# CONFIG_SOC_AU1X00 is not set
-# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_BIGSUR is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_PTSWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CRHONE is not set
# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
# CONFIG_TOSHIBA_RBTX4927 is not set
+# CONFIG_TOSHIBA_RBTX4938 is not set
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_HAVE_DEC_LOCK=y
CONFIG_DMA_NONCOHERENT=y
CONFIG_DMA_NEED_PCI_MAP_STATE=y
CONFIG_EARLY_PRINTK=y
+# CONFIG_CPU_BIG_ENDIAN is not set
CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
CONFIG_IRQ_CPU=y
CONFIG_BOOT_ELF32=y
CONFIG_MIPS_L1_CACHE_SHIFT=4
@@ -98,8 +130,10 @@ CONFIG_MIPS_L1_CACHE_SHIFT=4
#
# CPU selection
#
-# CONFIG_CPU_MIPS32 is not set
-# CONFIG_CPU_MIPS64 is not set
+# CONFIG_CPU_MIPS32_R1 is not set
+# CONFIG_CPU_MIPS32_R2 is not set
+# CONFIG_CPU_MIPS64_R1 is not set
+# CONFIG_CPU_MIPS64_R2 is not set
CONFIG_CPU_R3000=y
# CONFIG_CPU_TX39XX is not set
# CONFIG_CPU_VR41XX is not set
@@ -115,12 +149,37 @@ CONFIG_CPU_R3000=y
# CONFIG_CPU_RM7000 is not set
# CONFIG_CPU_RM9000 is not set
# CONFIG_CPU_SB1 is not set
+CONFIG_SYS_HAS_CPU_R3000=y
+CONFIG_SYS_HAS_CPU_R4X00=y
+CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
+CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
+
+#
+# Kernel type
+#
+CONFIG_32BIT=y
+# CONFIG_64BIT is not set
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_MIPS_MT is not set
# CONFIG_CPU_ADVANCED is not set
CONFIG_CPU_HAS_WB=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_CPU_SUPPORTS_HIGHMEM=y
+CONFIG_ARCH_FLATMEM_ENABLE=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_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
#
@@ -135,10 +194,6 @@ CONFIG_MMU=y
# CONFIG_PCCARD is not set
#
-# PC-card bridges
-#
-
-#
# PCI Hotplug Support
#
@@ -150,6 +205,80 @@ CONFIG_BINFMT_ELF=y
CONFIG_TRAD_SIGNALS=y
#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+CONFIG_INET_TUNNEL=m
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+# CONFIG_IPV6 is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# 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_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_IEEE80211=m
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=m
+CONFIG_IEEE80211_CRYPT_CCMP=m
+CONFIG_IEEE80211_CRYPT_TKIP=m
+
+#
# Device Drivers
#
@@ -159,6 +288,12 @@ CONFIG_TRAD_SIGNALS=y
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_FW_LOADER is not set
+# CONFIG_DEBUG_DRIVER is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+CONFIG_CONNECTOR=m
#
# Memory Technology Devices (MTD)
@@ -177,17 +312,14 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
#
# Block devices
#
-# CONFIG_BLK_DEV_FD is not set
# CONFIG_BLK_DEV_COW_COMMON is not set
-# CONFIG_BLK_DEV_LOOP is not set
+CONFIG_BLK_DEV_LOOP=m
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
# CONFIG_BLK_DEV_NBD is not set
# CONFIG_BLK_DEV_RAM is not set
CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_INITRAMFS_SOURCE=""
# CONFIG_LBD is not set
-CONFIG_CDROM_PKTCDVD=m
-CONFIG_CDROM_PKTCDVD_BUFFERS=8
-# CONFIG_CDROM_PKTCDVD_WCACHE is not set
+# CONFIG_CDROM_PKTCDVD is not set
#
# IO Schedulers
@@ -196,7 +328,7 @@ CONFIG_IOSCHED_NOOP=y
CONFIG_IOSCHED_AS=y
CONFIG_IOSCHED_DEADLINE=y
CONFIG_IOSCHED_CFQ=y
-CONFIG_ATA_OVER_ETH=m
+# CONFIG_ATA_OVER_ETH is not set
#
# ATA/ATAPI/MFM/RLL support
@@ -206,6 +338,7 @@ CONFIG_ATA_OVER_ETH=m
#
# SCSI device support
#
+CONFIG_RAID_ATTRS=m
CONFIG_SCSI=y
CONFIG_SCSI_PROC_FS=y
@@ -213,10 +346,12 @@ 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_ST=m
# CONFIG_CHR_DEV_OSST is not set
-# CONFIG_BLK_DEV_SR is not set
-# CONFIG_CHR_DEV_SG is not set
+CONFIG_BLK_DEV_SR=m
+# CONFIG_BLK_DEV_SR_VENDOR is not set
+CONFIG_CHR_DEV_SG=m
+# CONFIG_CHR_DEV_SCH is not set
#
# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
@@ -228,9 +363,10 @@ CONFIG_SCSI_CONSTANTS=y
#
# SCSI Transport Attributes
#
-# CONFIG_SCSI_SPI_ATTRS is not set
+CONFIG_SCSI_SPI_ATTRS=m
# CONFIG_SCSI_FC_ATTRS is not set
# CONFIG_SCSI_ISCSI_ATTRS is not set
+CONFIG_SCSI_SAS_ATTRS=m
#
# SCSI low-level drivers
@@ -248,6 +384,7 @@ CONFIG_SCSI_DECNCR=y
#
# Fusion MPT device support
#
+# CONFIG_FUSION is not set
#
# IEEE 1394 (FireWire) support
@@ -258,78 +395,28 @@ CONFIG_SCSI_DECNCR=y
#
#
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
-CONFIG_NETLINK_DEV=y
-CONFIG_UNIX=y
-CONFIG_NET_KEY=y
-CONFIG_INET=y
-# CONFIG_IP_MULTICAST is not set
-# CONFIG_IP_ADVANCED_ROUTER is not set
-CONFIG_IP_PNP=y
-# CONFIG_IP_PNP_DHCP is not set
-CONFIG_IP_PNP_BOOTP=y
-# CONFIG_IP_PNP_RARP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_ARPD is not set
-# CONFIG_SYN_COOKIES is not set
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-CONFIG_INET_TUNNEL=m
-CONFIG_IP_TCPDIAG=m
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-# CONFIG_IPV6 is not set
-# CONFIG_NETFILTER is not set
-CONFIG_XFRM=y
-CONFIG_XFRM_USER=m
-
-#
-# SCTP Configuration (EXPERIMENTAL)
+# Network device support
#
-# CONFIG_IP_SCTP 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_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
#
-# QoS and/or fair queueing
+# PHY device support
#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
+CONFIG_PHYLIB=m
+CONFIG_PHYCONTROL=y
#
-# Network testing
+# MII PHY device drivers
#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
-CONFIG_NETDEVICES=y
-# CONFIG_DUMMY is not set
-# CONFIG_BONDING is not set
-# CONFIG_EQUALIZER is not set
-# CONFIG_TUN is not set
-# CONFIG_ETHERTAP is not set
+CONFIG_MARVELL_PHY=m
+CONFIG_DAVICOM_PHY=m
+CONFIG_QSEMI_PHY=m
+CONFIG_LXT_PHY=m
+CONFIG_CICADA_PHY=m
#
# Ethernet (10 or 100Mbit)
@@ -363,6 +450,8 @@ CONFIG_DECLANCE=y
# CONFIG_SLIP is not set
# CONFIG_SHAPER is not set
# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
#
# ISDN subsystem
@@ -377,48 +466,22 @@ CONFIG_DECLANCE=y
#
# Input device support
#
-CONFIG_INPUT=y
+# CONFIG_INPUT is not set
#
-# Userland interfaces
-#
-CONFIG_INPUT_MOUSEDEV=y
-CONFIG_INPUT_MOUSEDEV_PSAUX=y
-CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
-# CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_TSDEV is not set
-# CONFIG_INPUT_EVDEV is not set
-# CONFIG_INPUT_EVBUG is not set
-
-#
-# Input I/O drivers
+# Hardware I/O ports
#
+# CONFIG_SERIO is not set
# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=y
-# CONFIG_SERIO_I8042 is not set
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_LIBPS2 is not set
-CONFIG_SERIO_RAW=m
-
-#
-# Input Device Drivers
-#
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_INPUT_JOYSTICK is not set
-# CONFIG_INPUT_TOUCHSCREEN is not set
-# CONFIG_INPUT_MISC is not set
#
# Character devices
#
-CONFIG_VT=y
-CONFIG_VT_CONSOLE=y
-CONFIG_HW_CONSOLE=y
+# CONFIG_VT is not set
# CONFIG_SERIAL_NONSTANDARD is not set
+CONFIG_SERIAL_DEC=y
+CONFIG_SERIAL_DEC_CONSOLE=y
+CONFIG_ZS=y
#
# Serial drivers
@@ -445,18 +508,20 @@ CONFIG_LEGACY_PTY_COUNT=256
# Watchdog Cards
#
# CONFIG_WATCHDOG is not set
-# CONFIG_RTC is not set
-# CONFIG_GEN_RTC is not set
+CONFIG_RTC=y
# CONFIG_DTLK is not set
# CONFIG_R3964 is not set
#
# Ftape, the floppy tape device driver
#
-# CONFIG_DRM is not set
# CONFIG_RAW_DRIVER is not set
#
+# TPM devices
+#
+
+#
# I2C support
#
# CONFIG_I2C is not set
@@ -467,10 +532,20 @@ CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_W1 is not set
#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
+#
# Misc devices
#
#
+# Multimedia Capabilities Port drivers
+#
+
+#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
@@ -483,13 +558,29 @@ CONFIG_LEGACY_PTY_COUNT=256
#
# Graphics support
#
-# CONFIG_FB is not set
-
-#
-# Console display driver support
-#
-# CONFIG_VGA_CONSOLE is not set
-CONFIG_DUMMY_CONSOLE=y
+CONFIG_FB=y
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+CONFIG_FB_SOFT_CURSOR=y
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+# CONFIG_FB_PMAG_AA is not set
+CONFIG_FB_PMAG_BA=y
+CONFIG_FB_PMAGB_B=y
+# CONFIG_FB_MAXINE is not set
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_VIRTUAL is not set
+
+#
+# Logo configuration
+#
+CONFIG_LOGO=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+# CONFIG_LOGO_LINUX_CLUT224 is not set
+CONFIG_LOGO_DEC_CLUT224=y
# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
@@ -504,10 +595,6 @@ CONFIG_DUMMY_CONSOLE=y
# CONFIG_USB_ARCH_HAS_OHCI is not set
#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
-#
-
-#
# USB Gadget Support
#
# CONFIG_USB_GADGET is not set
@@ -520,7 +607,10 @@ CONFIG_DUMMY_CONSOLE=y
#
# InfiniBand support
#
-# CONFIG_INFINIBAND is not set
+
+#
+# SN Devices
+#
#
# File systems
@@ -529,6 +619,7 @@ CONFIG_EXT2_FS=y
CONFIG_EXT2_FS_XATTR=y
CONFIG_EXT2_FS_POSIX_ACL=y
CONFIG_EXT2_FS_SECURITY=y
+# CONFIG_EXT2_FS_XIP is not set
# CONFIG_EXT3_FS is not set
# CONFIG_JBD is not set
CONFIG_FS_MBCACHE=y
@@ -538,10 +629,12 @@ CONFIG_FS_POSIX_ACL=y
# CONFIG_XFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
# CONFIG_QUOTA is not set
CONFIG_DNOTIFY=y
# CONFIG_AUTOFS_FS is not set
# CONFIG_AUTOFS4_FS is not set
+CONFIG_FUSE_FS=m
#
# CD-ROM/DVD Filesystems
@@ -562,12 +655,10 @@ CONFIG_DNOTIFY=y
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
-CONFIG_DEVPTS_FS_XATTR=y
-CONFIG_DEVPTS_FS_SECURITY=y
-# CONFIG_TMPFS is not set
+CONFIG_TMPFS=y
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
+CONFIG_RELAYFS_FS=m
#
# Miscellaneous filesystems
@@ -584,19 +675,31 @@ CONFIG_RAMFS=y
# CONFIG_HPFS_FS is not set
# CONFIG_QNX4FS_FS is not set
# CONFIG_SYSV_FS is not set
-# CONFIG_UFS_FS is not set
+CONFIG_UFS_FS=y
+CONFIG_UFS_FS_WRITE=y
#
# Network File Systems
#
-# CONFIG_NFS_FS is not set
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFS_DIRECTIO is not set
# CONFIG_NFSD is not set
-# CONFIG_EXPORTFS is not set
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=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
+# CONFIG_9P_FS is not set
#
# Partition Types
@@ -631,9 +734,24 @@ CONFIG_ULTRIX_PARTITION=y
#
# Kernel hacking
#
-# CONFIG_DEBUG_KERNEL is not set
+# CONFIG_PRINTK_TIME is not set
+CONFIG_DEBUG_KERNEL=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_FS is not set
CONFIG_CROSSCOMPILE=y
CONFIG_CMDLINE=""
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_KGDB is not set
+# CONFIG_RUNTIME_DEBUG is not set
+# CONFIG_MIPS_UNCACHED is not set
#
# Security options
@@ -645,7 +763,31 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
#
# Cryptographic options
#
-# CONFIG_CRYPTO is not set
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_AES=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_CRC32C=m
+# CONFIG_CRYPTO_TEST is not set
#
# Hardware crypto devices
@@ -655,7 +797,8 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
# Library routines
#
# CONFIG_CRC_CCITT is not set
+CONFIG_CRC16=m
CONFIG_CRC32=y
CONFIG_LIBCRC32C=m
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_ZLIB_INFLATE=m
+CONFIG_ZLIB_DEFLATE=m
diff --git a/arch/mips/configs/e55_defconfig b/arch/mips/configs/e55_defconfig
index ba2ec01defb1..c0d06ea5566c 100644
--- a/arch/mips/configs/e55_defconfig
+++ b/arch/mips/configs/e55_defconfig
@@ -1,12 +1,9 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-rc2
-# Wed Jan 26 02:49:03 2005
+# Linux kernel version: 2.6.14-rc2
+# Thu Oct 20 22:25:51 2005
#
CONFIG_MIPS=y
-# CONFIG_64BIT is not set
-# CONFIG_64BIT is not set
-CONFIG_32BIT=y
#
# Code maturity level options
@@ -14,24 +11,29 @@ CONFIG_32BIT=y
CONFIG_EXPERIMENTAL=y
CONFIG_CLEAN_COMPILE=y
CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
#
# General setup
#
CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
# CONFIG_POSIX_MQUEUE is not set
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
# CONFIG_HOTPLUG is not set
CONFIG_KOBJECT_UEVENT=y
# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
CONFIG_EMBEDDED=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
@@ -41,6 +43,7 @@ CONFIG_CC_ALIGN_LABELS=0
CONFIG_CC_ALIGN_LOOPS=0
CONFIG_CC_ALIGN_JUMPS=0
# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
#
# Loadable module support
@@ -56,56 +59,84 @@ CONFIG_KMOD=y
#
# Machine selection
#
-# CONFIG_MACH_JAZZ is not set
-CONFIG_MACH_VR41XX=y
-# CONFIG_NEC_CMBVR4133 is not set
-CONFIG_CASIO_E55=y
-# CONFIG_IBM_WORKPAD is not set
-# CONFIG_TANBAC_TB0226 is not set
-# CONFIG_TANBAC_TB0229 is not set
-# CONFIG_VICTOR_MPC30X is not set
-# CONFIG_ZAO_CAPCELLA is not set
-# CONFIG_VRC4171 is not set
-# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_MIPS_PB1550 is not set
+# CONFIG_MIPS_PB1200 is not set
+# CONFIG_MIPS_DB1000 is not set
+# CONFIG_MIPS_DB1100 is not set
+# CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
+# CONFIG_MIPS_DB1200 is not set
+# CONFIG_MIPS_MIRAGE is not set
# CONFIG_MIPS_COBALT is not set
# CONFIG_MACH_DECSTATION is not set
# CONFIG_MIPS_EV64120 is not set
# CONFIG_MIPS_EV96100 is not set
# CONFIG_MIPS_IVR is not set
-# CONFIG_LASAT is not set
# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_LASAT is not set
# CONFIG_MIPS_ATLAS is not set
# CONFIG_MIPS_MALTA is not set
# CONFIG_MIPS_SEAD is not set
+# CONFIG_MIPS_SIM is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
# CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_G is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_JAGUAR_ATX is not set
-# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MIPS_XXS1500 is not set
+# CONFIG_PNX8550_V2PCI is not set
+# CONFIG_PNX8550_JBS is not set
# CONFIG_DDB5074 is not set
# CONFIG_DDB5476 is not set
# CONFIG_DDB5477 is not set
-# CONFIG_NEC_OSPREY is not set
+CONFIG_MACH_VR41XX=y
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_QEMU is not set
# CONFIG_SGI_IP22 is not set
-# CONFIG_SOC_AU1X00 is not set
-# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_BIGSUR is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_PTSWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CRHONE is not set
# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
# CONFIG_TOSHIBA_RBTX4927 is not set
+# CONFIG_TOSHIBA_RBTX4938 is not set
+# CONFIG_NEC_CMBVR4133 is not set
+CONFIG_CASIO_E55=y
+# CONFIG_IBM_WORKPAD is not set
+# CONFIG_TANBAC_TB022X is not set
+# CONFIG_VICTOR_MPC30X is not set
+# CONFIG_ZAO_CAPCELLA is not set
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_HAVE_DEC_LOCK=y
CONFIG_DMA_NONCOHERENT=y
CONFIG_DMA_NEED_PCI_MAP_STATE=y
+# CONFIG_CPU_BIG_ENDIAN is not set
CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
CONFIG_IRQ_CPU=y
CONFIG_MIPS_L1_CACHE_SHIFT=5
#
# CPU selection
#
-# CONFIG_CPU_MIPS32 is not set
-# CONFIG_CPU_MIPS64 is not set
+# CONFIG_CPU_MIPS32_R1 is not set
+# CONFIG_CPU_MIPS32_R2 is not set
+# CONFIG_CPU_MIPS64_R1 is not set
+# CONFIG_CPU_MIPS64_R2 is not set
# CONFIG_CPU_R3000 is not set
# CONFIG_CPU_TX39XX is not set
CONFIG_CPU_VR41XX=y
@@ -121,12 +152,36 @@ CONFIG_CPU_VR41XX=y
# CONFIG_CPU_RM7000 is not set
# CONFIG_CPU_RM9000 is not set
# CONFIG_CPU_SB1 is not set
+CONFIG_SYS_HAS_CPU_VR41XX=y
+CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
+CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y
+
+#
+# Kernel type
+#
+CONFIG_32BIT=y
+# CONFIG_64BIT is not set
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_MIPS_MT is not set
# CONFIG_CPU_ADVANCED is not set
CONFIG_CPU_HAS_SYNC=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_ARCH_FLATMEM_ENABLE=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_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
#
@@ -141,11 +196,6 @@ CONFIG_MMU=y
# CONFIG_PCCARD is not set
#
-# PC-card bridges
-#
-CONFIG_PCMCIA_PROBE=y
-
-#
# PCI Hotplug Support
#
@@ -157,6 +207,78 @@ CONFIG_BINFMT_ELF=y
CONFIG_TRAD_SIGNALS=y
#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+CONFIG_NET_KEY=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+# CONFIG_IP_PNP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+CONFIG_INET_TUNNEL=m
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+# CONFIG_IPV6 is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# 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_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_IEEE80211=m
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=m
+CONFIG_IEEE80211_CRYPT_CCMP=m
+CONFIG_IEEE80211_CRYPT_TKIP=m
+
+#
# Device Drivers
#
@@ -168,6 +290,11 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_FW_LOADER is not set
#
+# Connector - unified userspace <-> kernelspace linker
+#
+CONFIG_CONNECTOR=m
+
+#
# Memory Technology Devices (MTD)
#
# CONFIG_MTD is not set
@@ -185,18 +312,13 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
#
# Block devices
#
-# CONFIG_BLK_DEV_FD is not set
-# CONFIG_BLK_DEV_XD is not set
# CONFIG_BLK_DEV_COW_COMMON is not set
# CONFIG_BLK_DEV_LOOP is not set
# CONFIG_BLK_DEV_NBD is not set
# CONFIG_BLK_DEV_RAM is not set
CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_INITRAMFS_SOURCE=""
# CONFIG_LBD is not set
-CONFIG_CDROM_PKTCDVD=m
-CONFIG_CDROM_PKTCDVD_BUFFERS=8
-# CONFIG_CDROM_PKTCDVD_WCACHE is not set
+# CONFIG_CDROM_PKTCDVD is not set
#
# IO Schedulers
@@ -205,7 +327,7 @@ CONFIG_IOSCHED_NOOP=y
CONFIG_IOSCHED_AS=y
CONFIG_IOSCHED_DEADLINE=y
CONFIG_IOSCHED_CFQ=y
-CONFIG_ATA_OVER_ETH=m
+# CONFIG_ATA_OVER_ETH is not set
#
# ATA/ATAPI/MFM/RLL support
@@ -237,6 +359,7 @@ CONFIG_IDE_GENERIC=y
#
# SCSI device support
#
+# CONFIG_RAID_ATTRS is not set
# CONFIG_SCSI is not set
#
@@ -252,6 +375,7 @@ CONFIG_IDE_GENERIC=y
#
# Fusion MPT device support
#
+# CONFIG_FUSION is not set
#
# IEEE 1394 (FireWire) support
@@ -262,76 +386,13 @@ CONFIG_IDE_GENERIC=y
#
#
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
-CONFIG_NETLINK_DEV=y
-CONFIG_UNIX=y
-CONFIG_NET_KEY=y
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-# CONFIG_IP_ADVANCED_ROUTER is not set
-# CONFIG_IP_PNP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_IP_MROUTE is not set
-# CONFIG_ARPD is not set
-# CONFIG_SYN_COOKIES is not set
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-CONFIG_INET_TUNNEL=m
-CONFIG_IP_TCPDIAG=m
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-# CONFIG_IPV6 is not set
-# CONFIG_NETFILTER is not set
-CONFIG_XFRM=y
-CONFIG_XFRM_USER=m
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP 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_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
-
-#
-# Network testing
+# Network device support
#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
CONFIG_NETDEVICES=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_EQUALIZER is not set
# CONFIG_TUN is not set
-# CONFIG_ETHERTAP is not set
#
# ARCnet devices
@@ -339,12 +400,26 @@ CONFIG_NETDEVICES=y
# CONFIG_ARCNET is not set
#
+# PHY device support
+#
+CONFIG_PHYLIB=m
+CONFIG_PHYCONTROL=y
+
+#
+# MII PHY device drivers
+#
+CONFIG_MARVELL_PHY=m
+CONFIG_DAVICOM_PHY=m
+CONFIG_QSEMI_PHY=m
+CONFIG_LXT_PHY=m
+CONFIG_CICADA_PHY=m
+
+#
# Ethernet (10 or 100Mbit)
#
CONFIG_NET_ETHERNET=y
# CONFIG_MII is not set
# CONFIG_NET_VENDOR_3COM is not set
-# CONFIG_LANCE is not set
# CONFIG_NET_VENDOR_SMC is not set
# CONFIG_NET_VENDOR_RACAL is not set
# CONFIG_AT1700 is not set
@@ -380,6 +455,8 @@ CONFIG_NET_ETHERNET=y
# CONFIG_SLIP is not set
# CONFIG_SHAPER is not set
# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
#
# ISDN subsystem
@@ -401,26 +478,14 @@ CONFIG_INPUT=y
#
CONFIG_INPUT_MOUSEDEV=y
CONFIG_INPUT_MOUSEDEV_PSAUX=y
-CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=320
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=240
# CONFIG_INPUT_JOYDEV is not set
# CONFIG_INPUT_TSDEV is not set
# CONFIG_INPUT_EVDEV is not set
# CONFIG_INPUT_EVBUG is not set
#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=y
-CONFIG_SERIO_I8042=y
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_LIBPS2 is not set
-CONFIG_SERIO_RAW=m
-
-#
# Input Device Drivers
#
# CONFIG_INPUT_KEYBOARD is not set
@@ -430,6 +495,16 @@ CONFIG_SERIO_RAW=m
# CONFIG_INPUT_MISC is not set
#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_LIBPS2 is not set
+CONFIG_SERIO_RAW=m
+# CONFIG_GAMEPORT is not set
+
+#
# Character devices
#
CONFIG_VT=y
@@ -440,16 +515,15 @@ CONFIG_HW_CONSOLE=y
#
# Serial drivers
#
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_NR_UARTS=4
-# CONFIG_SERIAL_8250_EXTENDED is not set
+# CONFIG_SERIAL_8250 is not set
#
# Non-8250 serial port support
#
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_SERIAL_VR41XX=y
+CONFIG_SERIAL_VR41XX_CONSOLE=y
CONFIG_UNIX98_PTYS=y
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
@@ -484,10 +558,14 @@ CONFIG_WATCHDOG=y
#
# Ftape, the floppy tape device driver
#
-# CONFIG_DRM is not set
+CONFIG_GPIO_VR41XX=y
# CONFIG_RAW_DRIVER is not set
#
+# TPM devices
+#
+
+#
# I2C support
#
# CONFIG_I2C is not set
@@ -498,10 +576,20 @@ CONFIG_WATCHDOG=y
# CONFIG_W1 is not set
#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
+#
# Misc devices
#
#
+# Multimedia Capabilities Port drivers
+#
+
+#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
@@ -522,7 +610,6 @@ CONFIG_WATCHDOG=y
# CONFIG_VGA_CONSOLE is not set
# CONFIG_MDA_CONSOLE is not set
CONFIG_DUMMY_CONSOLE=y
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Sound
@@ -536,10 +623,6 @@ CONFIG_DUMMY_CONSOLE=y
# CONFIG_USB_ARCH_HAS_OHCI is not set
#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
-#
-
-#
# USB Gadget Support
#
# CONFIG_USB_GADGET is not set
@@ -552,24 +635,31 @@ CONFIG_DUMMY_CONSOLE=y
#
# InfiniBand support
#
-# CONFIG_INFINIBAND is not set
+
+#
+# SN Devices
+#
#
# File systems
#
CONFIG_EXT2_FS=y
# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
# CONFIG_EXT3_FS is not set
# CONFIG_JBD 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_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
# CONFIG_QUOTA is not set
CONFIG_DNOTIFY=y
CONFIG_AUTOFS_FS=y
CONFIG_AUTOFS4_FS=y
+CONFIG_FUSE_FS=m
#
# CD-ROM/DVD Filesystems
@@ -590,12 +680,10 @@ CONFIG_AUTOFS4_FS=y
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
-CONFIG_DEVPTS_FS_XATTR=y
-CONFIG_DEVPTS_FS_SECURITY=y
# CONFIG_TMPFS is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
+CONFIG_RELAYFS_FS=m
#
# Miscellaneous filesystems
@@ -617,16 +705,17 @@ CONFIG_RAMFS=y
#
# Network File Systems
#
-CONFIG_NFS_FS=y
+CONFIG_NFS_FS=m
# CONFIG_NFS_V3 is not set
# CONFIG_NFS_V4 is not set
# CONFIG_NFS_DIRECTIO is not set
-CONFIG_NFSD=y
+CONFIG_NFSD=m
# CONFIG_NFSD_V3 is not set
# CONFIG_NFSD_TCP is not set
-CONFIG_LOCKD=y
-CONFIG_EXPORTFS=y
-CONFIG_SUNRPC=y
+CONFIG_LOCKD=m
+CONFIG_EXPORTFS=m
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=m
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
# CONFIG_SMB_FS is not set
@@ -634,6 +723,7 @@ CONFIG_SUNRPC=y
# CONFIG_NCP_FS is not set
# CONFIG_CODA_FS is not set
# CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
#
# Partition Types
@@ -654,9 +744,11 @@ CONFIG_MSDOS_PARTITION=y
#
# Kernel hacking
#
+# CONFIG_PRINTK_TIME is not set
# CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=14
CONFIG_CROSSCOMPILE=y
-CONFIG_CMDLINE=""
+CONFIG_CMDLINE="console=ttyVR0,19200 mem=8M"
#
# Security options
@@ -668,7 +760,31 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
#
# Cryptographic options
#
-# CONFIG_CRYPTO is not set
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_AES=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_CRC32C=m
+# CONFIG_CRYPTO_TEST is not set
#
# Hardware crypto devices
@@ -678,7 +794,8 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
# Library routines
#
# CONFIG_CRC_CCITT is not set
-# CONFIG_CRC32 is not set
+CONFIG_CRC16=m
+CONFIG_CRC32=m
CONFIG_LIBCRC32C=m
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_ZLIB_INFLATE=m
+CONFIG_ZLIB_DEFLATE=m
diff --git a/arch/mips/configs/ev64120_defconfig b/arch/mips/configs/ev64120_defconfig
index 17e87f70f602..f1309d84d2fe 100644
--- a/arch/mips/configs/ev64120_defconfig
+++ b/arch/mips/configs/ev64120_defconfig
@@ -1,12 +1,9 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-rc2
-# Wed Jan 26 02:49:03 2005
+# Linux kernel version: 2.6.14-rc2
+# Thu Oct 20 22:25:54 2005
#
CONFIG_MIPS=y
-# CONFIG_64BIT is not set
-# CONFIG_64BIT is not set
-CONFIG_32BIT=y
#
# Code maturity level options
@@ -14,24 +11,29 @@ CONFIG_32BIT=y
CONFIG_EXPERIMENTAL=y
CONFIG_CLEAN_COMPILE=y
CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
#
# General setup
#
CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
# CONFIG_POSIX_MQUEUE is not set
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_HOTPLUG is not set
+CONFIG_HOTPLUG=y
CONFIG_KOBJECT_UEVENT=y
# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
CONFIG_EMBEDDED=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
@@ -41,6 +43,7 @@ CONFIG_CC_ALIGN_LABELS=0
CONFIG_CC_ALIGN_LOOPS=0
CONFIG_CC_ALIGN_JUMPS=0
# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
#
# Loadable module support
@@ -56,41 +59,69 @@ CONFIG_MODULE_SRCVERSION_ALL=y
#
# Machine selection
#
-# CONFIG_MACH_JAZZ is not set
-# CONFIG_MACH_VR41XX is not set
-# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_MIPS_PB1550 is not set
+# CONFIG_MIPS_PB1200 is not set
+# CONFIG_MIPS_DB1000 is not set
+# CONFIG_MIPS_DB1100 is not set
+# CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
+# CONFIG_MIPS_DB1200 is not set
+# CONFIG_MIPS_MIRAGE is not set
# CONFIG_MIPS_COBALT is not set
# CONFIG_MACH_DECSTATION is not set
CONFIG_MIPS_EV64120=y
-# CONFIG_EVB_PCI1 is not set
# CONFIG_MIPS_EV96100 is not set
# CONFIG_MIPS_IVR is not set
-# CONFIG_LASAT is not set
# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_LASAT is not set
# CONFIG_MIPS_ATLAS is not set
# CONFIG_MIPS_MALTA is not set
# CONFIG_MIPS_SEAD is not set
+# CONFIG_MIPS_SIM is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
# CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_G is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_JAGUAR_ATX is not set
-# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MIPS_XXS1500 is not set
+# CONFIG_PNX8550_V2PCI is not set
+# CONFIG_PNX8550_JBS is not set
# CONFIG_DDB5074 is not set
# CONFIG_DDB5476 is not set
# CONFIG_DDB5477 is not set
-# CONFIG_NEC_OSPREY is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_QEMU is not set
# CONFIG_SGI_IP22 is not set
-# CONFIG_SOC_AU1X00 is not set
-# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_BIGSUR is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_PTSWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CRHONE is not set
# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
# CONFIG_TOSHIBA_RBTX4927 is not set
+# CONFIG_TOSHIBA_RBTX4938 is not set
+# CONFIG_EVB_PCI1 is not set
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_HAVE_DEC_LOCK=y
CONFIG_DMA_NONCOHERENT=y
CONFIG_DMA_NEED_PCI_MAP_STATE=y
+CONFIG_CPU_BIG_ENDIAN=y
# CONFIG_CPU_LITTLE_ENDIAN is not set
+CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
CONFIG_MIPS_GT64120=y
# CONFIG_SYSCLK_75 is not set
# CONFIG_SYSCLK_83 is not set
@@ -100,8 +131,10 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5
#
# CPU selection
#
-# CONFIG_CPU_MIPS32 is not set
-# CONFIG_CPU_MIPS64 is not set
+# CONFIG_CPU_MIPS32_R1 is not set
+# CONFIG_CPU_MIPS32_R2 is not set
+# CONFIG_CPU_MIPS64_R1 is not set
+# CONFIG_CPU_MIPS64_R2 is not set
# CONFIG_CPU_R3000 is not set
# CONFIG_CPU_TX39XX is not set
# CONFIG_CPU_VR41XX is not set
@@ -117,15 +150,39 @@ CONFIG_CPU_R5000=y
# CONFIG_CPU_RM7000 is not set
# CONFIG_CPU_RM9000 is not set
# CONFIG_CPU_SB1 is not set
+CONFIG_SYS_HAS_CPU_R5000=y
+CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
+CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y
+
+#
+# Kernel type
+#
+CONFIG_32BIT=y
+# CONFIG_64BIT is not set
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_MIPS_MT is not set
# CONFIG_64BIT_PHYS_ADDR is not set
# CONFIG_CPU_ADVANCED is not set
CONFIG_CPU_HAS_LLSC=y
CONFIG_CPU_HAS_LLDSCD=y
CONFIG_CPU_HAS_SYNC=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_ARCH_FLATMEM_ENABLE=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_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
#
@@ -134,7 +191,6 @@ CONFIG_CPU_HAS_SYNC=y
CONFIG_HW_HAS_PCI=y
CONFIG_PCI=y
CONFIG_PCI_LEGACY_PROC=y
-CONFIG_PCI_NAMES=y
CONFIG_MMU=y
#
@@ -143,10 +199,6 @@ CONFIG_MMU=y
# CONFIG_PCCARD is not set
#
-# PC-card bridges
-#
-
-#
# PCI Hotplug Support
#
# CONFIG_HOTPLUG_PCI is not set
@@ -159,6 +211,79 @@ CONFIG_BINFMT_ELF=y
CONFIG_TRAD_SIGNALS=y
#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_PACKET is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+CONFIG_NET_KEY=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+# CONFIG_IP_PNP_BOOTP is not set
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+CONFIG_INET_TUNNEL=m
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+# CONFIG_IPV6 is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# 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_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_IEEE80211=m
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=m
+CONFIG_IEEE80211_CRYPT_CCMP=m
+CONFIG_IEEE80211_CRYPT_TKIP=m
+
+#
# Device Drivers
#
@@ -167,7 +292,12 @@ CONFIG_TRAD_SIGNALS=y
#
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
+CONFIG_FW_LOADER=m
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+CONFIG_CONNECTOR=m
#
# Memory Technology Devices (MTD)
@@ -186,7 +316,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
#
# Block devices
#
-# CONFIG_BLK_DEV_FD is not set
# CONFIG_BLK_CPQ_DA is not set
# CONFIG_BLK_CPQ_CISS_DA is not set
# CONFIG_BLK_DEV_DAC960 is not set
@@ -197,7 +326,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_BLK_DEV_SX8 is not set
# CONFIG_BLK_DEV_RAM is not set
CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_INITRAMFS_SOURCE=""
# CONFIG_LBD is not set
CONFIG_CDROM_PKTCDVD=m
CONFIG_CDROM_PKTCDVD_BUFFERS=8
@@ -220,6 +348,7 @@ CONFIG_ATA_OVER_ETH=m
#
# SCSI device support
#
+CONFIG_RAID_ATTRS=m
# CONFIG_SCSI is not set
#
@@ -230,6 +359,7 @@ CONFIG_ATA_OVER_ETH=m
#
# Fusion MPT device support
#
+# CONFIG_FUSION is not set
#
# IEEE 1394 (FireWire) support
@@ -242,77 +372,13 @@ CONFIG_ATA_OVER_ETH=m
# CONFIG_I2O is not set
#
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-# CONFIG_PACKET is not set
-CONFIG_NETLINK_DEV=y
-CONFIG_UNIX=y
-CONFIG_NET_KEY=y
-CONFIG_INET=y
-# CONFIG_IP_MULTICAST is not set
-# CONFIG_IP_ADVANCED_ROUTER is not set
-CONFIG_IP_PNP=y
-# CONFIG_IP_PNP_DHCP is not set
-# CONFIG_IP_PNP_BOOTP is not set
-# CONFIG_IP_PNP_RARP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_ARPD is not set
-# CONFIG_SYN_COOKIES is not set
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-CONFIG_INET_TUNNEL=m
-CONFIG_IP_TCPDIAG=m
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-# CONFIG_IPV6 is not set
-# CONFIG_NETFILTER is not set
-CONFIG_XFRM=y
-CONFIG_XFRM_USER=m
-
-#
-# SCTP Configuration (EXPERIMENTAL)
+# Network device support
#
-# CONFIG_IP_SCTP 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_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
CONFIG_NETDEVICES=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_EQUALIZER is not set
# CONFIG_TUN is not set
-# CONFIG_ETHERTAP is not set
#
# ARCnet devices
@@ -320,6 +386,21 @@ CONFIG_NETDEVICES=y
# CONFIG_ARCNET is not set
#
+# PHY device support
+#
+CONFIG_PHYLIB=m
+CONFIG_PHYCONTROL=y
+
+#
+# MII PHY device drivers
+#
+CONFIG_MARVELL_PHY=m
+CONFIG_DAVICOM_PHY=m
+CONFIG_QSEMI_PHY=m
+CONFIG_LXT_PHY=m
+CONFIG_CICADA_PHY=m
+
+#
# Ethernet (10 or 100Mbit)
#
CONFIG_NET_ETHERNET=y
@@ -345,12 +426,16 @@ CONFIG_NET_ETHERNET=y
# CONFIG_HAMACHI is not set
# CONFIG_YELLOWFIN is not set
# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
# CONFIG_SK98LIN is not set
# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
#
# Ethernet (10000 Mbit)
#
+# CONFIG_CHELSIO_T1 is not set
# CONFIG_IXGB is not set
# CONFIG_S2IO is not set
@@ -363,6 +448,8 @@ CONFIG_NET_ETHERNET=y
# Wireless LAN (non-hamradio)
#
# CONFIG_NET_RADIO is not set
+# CONFIG_IPW_DEBUG is not set
+CONFIG_IPW2200=m
#
# Wan interfaces
@@ -381,6 +468,8 @@ CONFIG_PPP_ASYNC=y
# CONFIG_SLIP is not set
# CONFIG_SHAPER is not set
# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
#
# ISDN subsystem
@@ -410,19 +499,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
# CONFIG_INPUT_EVBUG is not set
#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=y
-# CONFIG_SERIO_I8042 is not set
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_PCIPS2 is not set
-# CONFIG_SERIO_LIBPS2 is not set
-CONFIG_SERIO_RAW=m
-
-#
# Input Device Drivers
#
# CONFIG_INPUT_KEYBOARD is not set
@@ -432,6 +508,17 @@ CONFIG_SERIO_RAW=m
# CONFIG_INPUT_MISC is not set
#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_PCIPS2 is not set
+# CONFIG_SERIO_LIBPS2 is not set
+CONFIG_SERIO_RAW=m
+# CONFIG_GAMEPORT is not set
+
+#
# Character devices
#
CONFIG_VT=y
@@ -452,6 +539,7 @@ CONFIG_SERIAL_8250_NR_UARTS=4
#
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
CONFIG_UNIX98_PTYS=y
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
@@ -478,6 +566,11 @@ CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_RAW_DRIVER is not set
#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+
+#
# I2C support
#
# CONFIG_I2C is not set
@@ -488,10 +581,20 @@ CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_W1 is not set
#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
+#
# Misc devices
#
#
+# Multimedia Capabilities Port drivers
+#
+
+#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
@@ -511,7 +614,6 @@ CONFIG_LEGACY_PTY_COUNT=256
#
# CONFIG_VGA_CONSOLE is not set
CONFIG_DUMMY_CONSOLE=y
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Sound
@@ -521,13 +623,9 @@ CONFIG_DUMMY_CONSOLE=y
#
# USB support
#
-# CONFIG_USB is not set
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB_ARCH_HAS_OHCI=y
-
-#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
-#
+# CONFIG_USB is not set
#
# USB Gadget Support
@@ -545,21 +643,29 @@ CONFIG_USB_ARCH_HAS_OHCI=y
# CONFIG_INFINIBAND is not set
#
+# SN Devices
+#
+
+#
# File systems
#
CONFIG_EXT2_FS=y
# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
# CONFIG_EXT3_FS is not set
# CONFIG_JBD 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_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
# CONFIG_QUOTA is not set
CONFIG_DNOTIFY=y
# CONFIG_AUTOFS_FS is not set
# CONFIG_AUTOFS4_FS is not set
+CONFIG_FUSE_FS=m
#
# CD-ROM/DVD Filesystems
@@ -580,12 +686,10 @@ CONFIG_DNOTIFY=y
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
-CONFIG_DEVPTS_FS_XATTR=y
-CONFIG_DEVPTS_FS_SECURITY=y
# CONFIG_TMPFS is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
+CONFIG_RELAYFS_FS=m
#
# Miscellaneous filesystems
@@ -614,7 +718,7 @@ CONFIG_NFS_FS=y
# CONFIG_NFSD is not set
CONFIG_ROOT_NFS=y
CONFIG_LOCKD=y
-# CONFIG_EXPORTFS is not set
+CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
@@ -623,6 +727,7 @@ CONFIG_SUNRPC=y
# CONFIG_NCP_FS is not set
# CONFIG_CODA_FS is not set
# CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
#
# Partition Types
@@ -643,7 +748,9 @@ CONFIG_MSDOS_PARTITION=y
#
# Kernel hacking
#
+# CONFIG_PRINTK_TIME is not set
# CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=14
CONFIG_CROSSCOMPILE=y
CONFIG_CMDLINE="console=ttyS0,115200 root=/dev/nfs rw nfsroot=192.168.1.1:/mnt/disk2/fs.gal ip=192.168.1.211:192.168.1.1:::gt::"
@@ -657,7 +764,31 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
#
# Cryptographic options
#
-# CONFIG_CRYPTO is not set
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_AES=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_CRC32C=m
+# CONFIG_CRYPTO_TEST is not set
#
# Hardware crypto devices
@@ -667,7 +798,8 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
# Library routines
#
CONFIG_CRC_CCITT=y
-# CONFIG_CRC32 is not set
+CONFIG_CRC16=m
+CONFIG_CRC32=m
CONFIG_LIBCRC32C=m
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_ZLIB_INFLATE=m
+CONFIG_ZLIB_DEFLATE=m
diff --git a/arch/mips/configs/ev96100_defconfig b/arch/mips/configs/ev96100_defconfig
index 9da4140eae00..8ac55b7acc01 100644
--- a/arch/mips/configs/ev96100_defconfig
+++ b/arch/mips/configs/ev96100_defconfig
@@ -1,12 +1,9 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-rc2
-# Wed Jan 26 02:49:03 2005
+# Linux kernel version: 2.6.14-rc2
+# Thu Oct 20 22:25:57 2005
#
CONFIG_MIPS=y
-# CONFIG_64BIT is not set
-# CONFIG_64BIT is not set
-CONFIG_32BIT=y
#
# Code maturity level options
@@ -14,24 +11,29 @@ CONFIG_32BIT=y
CONFIG_EXPERIMENTAL=y
CONFIG_CLEAN_COMPILE=y
CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
#
# General setup
#
CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
# CONFIG_POSIX_MQUEUE is not set
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
# CONFIG_HOTPLUG is not set
CONFIG_KOBJECT_UEVENT=y
# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
CONFIG_EMBEDDED=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
@@ -41,6 +43,7 @@ CONFIG_CC_ALIGN_LABELS=0
CONFIG_CC_ALIGN_LOOPS=0
CONFIG_CC_ALIGN_JUMPS=0
# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
#
# Loadable module support
@@ -56,40 +59,68 @@ CONFIG_MODULE_SRCVERSION_ALL=y
#
# Machine selection
#
-# CONFIG_MACH_JAZZ is not set
-# CONFIG_MACH_VR41XX is not set
-# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_MIPS_PB1550 is not set
+# CONFIG_MIPS_PB1200 is not set
+# CONFIG_MIPS_DB1000 is not set
+# CONFIG_MIPS_DB1100 is not set
+# CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
+# CONFIG_MIPS_DB1200 is not set
+# CONFIG_MIPS_MIRAGE is not set
# CONFIG_MIPS_COBALT is not set
# CONFIG_MACH_DECSTATION is not set
# CONFIG_MIPS_EV64120 is not set
CONFIG_MIPS_EV96100=y
# CONFIG_MIPS_IVR is not set
-# CONFIG_LASAT is not set
# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_LASAT is not set
# CONFIG_MIPS_ATLAS is not set
# CONFIG_MIPS_MALTA is not set
# CONFIG_MIPS_SEAD is not set
+# CONFIG_MIPS_SIM is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
# CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_G is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_JAGUAR_ATX is not set
-# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MIPS_XXS1500 is not set
+# CONFIG_PNX8550_V2PCI is not set
+# CONFIG_PNX8550_JBS is not set
# CONFIG_DDB5074 is not set
# CONFIG_DDB5476 is not set
# CONFIG_DDB5477 is not set
-# CONFIG_NEC_OSPREY is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_QEMU is not set
# CONFIG_SGI_IP22 is not set
-# CONFIG_SOC_AU1X00 is not set
-# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_BIGSUR is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_PTSWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CRHONE is not set
# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
# CONFIG_TOSHIBA_RBTX4927 is not set
+# CONFIG_TOSHIBA_RBTX4938 is not set
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_HAVE_DEC_LOCK=y
CONFIG_DMA_NONCOHERENT=y
CONFIG_DMA_NEED_PCI_MAP_STATE=y
+CONFIG_CPU_BIG_ENDIAN=y
# CONFIG_CPU_LITTLE_ENDIAN is not set
+CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
CONFIG_IRQ_CPU=y
CONFIG_MIPS_GT64120=y
CONFIG_SWAP_IO_SPACE=y
@@ -99,8 +130,10 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5
#
# CPU selection
#
-# CONFIG_CPU_MIPS32 is not set
-# CONFIG_CPU_MIPS64 is not set
+# CONFIG_CPU_MIPS32_R1 is not set
+# CONFIG_CPU_MIPS32_R2 is not set
+# CONFIG_CPU_MIPS64_R1 is not set
+# CONFIG_CPU_MIPS64_R2 is not set
# CONFIG_CPU_R3000 is not set
# CONFIG_CPU_TX39XX is not set
# CONFIG_CPU_VR41XX is not set
@@ -116,6 +149,18 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5
CONFIG_CPU_RM7000=y
# CONFIG_CPU_RM9000 is not set
# CONFIG_CPU_SB1 is not set
+CONFIG_SYS_HAS_CPU_R5000=y
+CONFIG_SYS_HAS_CPU_RM7000=y
+CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
+CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y
+
+#
+# Kernel type
+#
+CONFIG_32BIT=y
+# CONFIG_64BIT is not set
CONFIG_PAGE_SIZE_4KB=y
# CONFIG_PAGE_SIZE_8KB is not set
# CONFIG_PAGE_SIZE_16KB is not set
@@ -123,11 +168,25 @@ CONFIG_PAGE_SIZE_4KB=y
CONFIG_BOARD_SCACHE=y
CONFIG_RM7000_CPU_SCACHE=y
CONFIG_CPU_HAS_PREFETCH=y
+# CONFIG_MIPS_MT is not set
# CONFIG_64BIT_PHYS_ADDR is not set
# CONFIG_CPU_ADVANCED is not set
CONFIG_CPU_HAS_LLSC=y
CONFIG_CPU_HAS_LLDSCD=y
CONFIG_CPU_HAS_SYNC=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_CPU_SUPPORTS_HIGHMEM=y
+CONFIG_ARCH_FLATMEM_ENABLE=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_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
#
@@ -143,10 +202,6 @@ CONFIG_MMU=y
# CONFIG_PCCARD is not set
#
-# PC-card bridges
-#
-
-#
# PCI Hotplug Support
#
@@ -158,6 +213,79 @@ CONFIG_BINFMT_ELF=y
CONFIG_TRAD_SIGNALS=y
#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_PACKET is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+CONFIG_NET_KEY=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+CONFIG_INET_TUNNEL=m
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+# CONFIG_IPV6 is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# 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_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_IEEE80211=m
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=m
+CONFIG_IEEE80211_CRYPT_CCMP=m
+CONFIG_IEEE80211_CRYPT_TKIP=m
+
+#
# Device Drivers
#
@@ -169,6 +297,11 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_FW_LOADER is not set
#
+# Connector - unified userspace <-> kernelspace linker
+#
+CONFIG_CONNECTOR=m
+
+#
# Memory Technology Devices (MTD)
#
# CONFIG_MTD is not set
@@ -185,13 +318,11 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
#
# Block devices
#
-# CONFIG_BLK_DEV_FD is not set
# CONFIG_BLK_DEV_COW_COMMON is not set
# CONFIG_BLK_DEV_LOOP is not set
# CONFIG_BLK_DEV_NBD is not set
# CONFIG_BLK_DEV_RAM is not set
CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_INITRAMFS_SOURCE=""
# CONFIG_LBD is not set
CONFIG_CDROM_PKTCDVD=m
CONFIG_CDROM_PKTCDVD_BUFFERS=8
@@ -214,6 +345,7 @@ CONFIG_ATA_OVER_ETH=m
#
# SCSI device support
#
+CONFIG_RAID_ATTRS=m
# CONFIG_SCSI is not set
#
@@ -224,6 +356,7 @@ CONFIG_ATA_OVER_ETH=m
#
# Fusion MPT device support
#
+# CONFIG_FUSION is not set
#
# IEEE 1394 (FireWire) support
@@ -234,77 +367,28 @@ CONFIG_ATA_OVER_ETH=m
#
#
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
+# Network device support
#
-# CONFIG_PACKET is not set
-CONFIG_NETLINK_DEV=y
-CONFIG_UNIX=y
-CONFIG_NET_KEY=y
-CONFIG_INET=y
-# CONFIG_IP_MULTICAST is not set
-# CONFIG_IP_ADVANCED_ROUTER is not set
-CONFIG_IP_PNP=y
-# CONFIG_IP_PNP_DHCP is not set
-CONFIG_IP_PNP_BOOTP=y
-# CONFIG_IP_PNP_RARP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_ARPD is not set
-# CONFIG_SYN_COOKIES is not set
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-CONFIG_INET_TUNNEL=m
-CONFIG_IP_TCPDIAG=m
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-# CONFIG_IPV6 is not set
-# CONFIG_NETFILTER is not set
-CONFIG_XFRM=y
-CONFIG_XFRM_USER=m
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP 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_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
#
-# QoS and/or fair queueing
+# PHY device support
#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
+CONFIG_PHYLIB=m
+CONFIG_PHYCONTROL=y
#
-# Network testing
+# MII PHY device drivers
#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
-CONFIG_NETDEVICES=y
-# CONFIG_DUMMY is not set
-# CONFIG_BONDING is not set
-# CONFIG_EQUALIZER is not set
-# CONFIG_TUN is not set
-# CONFIG_ETHERTAP is not set
+CONFIG_MARVELL_PHY=m
+CONFIG_DAVICOM_PHY=m
+CONFIG_QSEMI_PHY=m
+CONFIG_LXT_PHY=m
+CONFIG_CICADA_PHY=m
#
# Ethernet (10 or 100Mbit)
@@ -338,6 +422,8 @@ CONFIG_MIPS_GT96100ETH=y
# CONFIG_SLIP is not set
# CONFIG_SHAPER is not set
# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
#
# ISDN subsystem
@@ -367,18 +453,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
# CONFIG_INPUT_EVBUG is not set
#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=y
-# CONFIG_SERIO_I8042 is not set
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_LIBPS2 is not set
-CONFIG_SERIO_RAW=m
-
-#
# Input Device Drivers
#
# CONFIG_INPUT_KEYBOARD is not set
@@ -388,6 +462,16 @@ CONFIG_SERIO_RAW=m
# CONFIG_INPUT_MISC is not set
#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_LIBPS2 is not set
+CONFIG_SERIO_RAW=m
+# CONFIG_GAMEPORT is not set
+
+#
# Character devices
#
CONFIG_VT=y
@@ -429,10 +513,13 @@ CONFIG_LEGACY_PTY_COUNT=256
#
# Ftape, the floppy tape device driver
#
-# CONFIG_DRM is not set
# CONFIG_RAW_DRIVER is not set
#
+# TPM devices
+#
+
+#
# I2C support
#
# CONFIG_I2C is not set
@@ -443,10 +530,20 @@ CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_W1 is not set
#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
+#
# Misc devices
#
#
+# Multimedia Capabilities Port drivers
+#
+
+#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
@@ -466,7 +563,6 @@ CONFIG_LEGACY_PTY_COUNT=256
#
# CONFIG_VGA_CONSOLE is not set
CONFIG_DUMMY_CONSOLE=y
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Sound
@@ -480,10 +576,6 @@ CONFIG_DUMMY_CONSOLE=y
# CONFIG_USB_ARCH_HAS_OHCI is not set
#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
-#
-
-#
# USB Gadget Support
#
# CONFIG_USB_GADGET is not set
@@ -496,24 +588,31 @@ CONFIG_DUMMY_CONSOLE=y
#
# InfiniBand support
#
-# CONFIG_INFINIBAND is not set
+
+#
+# SN Devices
+#
#
# File systems
#
CONFIG_EXT2_FS=y
# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
# CONFIG_EXT3_FS is not set
# CONFIG_JBD 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_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
# CONFIG_QUOTA is not set
CONFIG_DNOTIFY=y
# CONFIG_AUTOFS_FS is not set
# CONFIG_AUTOFS4_FS is not set
+CONFIG_FUSE_FS=m
#
# CD-ROM/DVD Filesystems
@@ -534,12 +633,10 @@ CONFIG_DNOTIFY=y
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
-CONFIG_DEVPTS_FS_XATTR=y
-CONFIG_DEVPTS_FS_SECURITY=y
# CONFIG_TMPFS is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
+CONFIG_RELAYFS_FS=m
#
# Miscellaneous filesystems
@@ -568,7 +665,7 @@ CONFIG_NFS_FS=y
# CONFIG_NFSD is not set
CONFIG_ROOT_NFS=y
CONFIG_LOCKD=y
-# CONFIG_EXPORTFS is not set
+CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
@@ -577,6 +674,7 @@ CONFIG_SUNRPC=y
# CONFIG_NCP_FS is not set
# CONFIG_CODA_FS is not set
# CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
#
# Partition Types
@@ -597,7 +695,9 @@ CONFIG_MSDOS_PARTITION=y
#
# Kernel hacking
#
+# CONFIG_PRINTK_TIME is not set
# CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=14
CONFIG_CROSSCOMPILE=y
CONFIG_CMDLINE=""
@@ -611,7 +711,31 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
#
# Cryptographic options
#
-# CONFIG_CRYPTO is not set
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_AES=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_CRC32C=m
+# CONFIG_CRYPTO_TEST is not set
#
# Hardware crypto devices
@@ -621,7 +745,8 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
# Library routines
#
# CONFIG_CRC_CCITT is not set
-# CONFIG_CRC32 is not set
+CONFIG_CRC16=m
+CONFIG_CRC32=m
CONFIG_LIBCRC32C=m
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_ZLIB_INFLATE=m
+CONFIG_ZLIB_DEFLATE=m
diff --git a/arch/mips/configs/ip22_defconfig b/arch/mips/configs/ip22_defconfig
index 17fa5c4e3ad1..3ae3838f283c 100644
--- a/arch/mips/configs/ip22_defconfig
+++ b/arch/mips/configs/ip22_defconfig
@@ -1,12 +1,9 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-rc2
-# Wed Jan 26 02:49:04 2005
+# Linux kernel version: 2.6.14-rc2
+# Thu Oct 20 22:26:01 2005
#
CONFIG_MIPS=y
-# CONFIG_64BIT is not set
-# CONFIG_64BIT is not set
-CONFIG_32BIT=y
#
# Code maturity level options
@@ -14,25 +11,30 @@ CONFIG_32BIT=y
CONFIG_EXPERIMENTAL=y
CONFIG_CLEAN_COMPILE=y
CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
#
# General setup
#
CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
# CONFIG_POSIX_MQUEUE is not set
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
# CONFIG_HOTPLUG is not set
CONFIG_KOBJECT_UEVENT=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
+CONFIG_INITRAMFS_SOURCE=""
CONFIG_EMBEDDED=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
@@ -42,6 +44,7 @@ CONFIG_CC_ALIGN_LABELS=0
CONFIG_CC_ALIGN_LOOPS=0
CONFIG_CC_ALIGN_JUMPS=0
# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
#
# Loadable module support
@@ -57,41 +60,69 @@ CONFIG_KMOD=y
#
# Machine selection
#
-# CONFIG_MACH_JAZZ is not set
-# CONFIG_MACH_VR41XX is not set
-# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_MIPS_PB1550 is not set
+# CONFIG_MIPS_PB1200 is not set
+# CONFIG_MIPS_DB1000 is not set
+# CONFIG_MIPS_DB1100 is not set
+# CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
+# CONFIG_MIPS_DB1200 is not set
+# CONFIG_MIPS_MIRAGE is not set
# CONFIG_MIPS_COBALT is not set
# CONFIG_MACH_DECSTATION is not set
# CONFIG_MIPS_EV64120 is not set
# CONFIG_MIPS_EV96100 is not set
# CONFIG_MIPS_IVR is not set
-# CONFIG_LASAT is not set
# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_LASAT is not set
# CONFIG_MIPS_ATLAS is not set
# CONFIG_MIPS_MALTA is not set
# CONFIG_MIPS_SEAD is not set
+# CONFIG_MIPS_SIM is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
# CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_G is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_JAGUAR_ATX is not set
-# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MIPS_XXS1500 is not set
+# CONFIG_PNX8550_V2PCI is not set
+# CONFIG_PNX8550_JBS is not set
# CONFIG_DDB5074 is not set
# CONFIG_DDB5476 is not set
# CONFIG_DDB5477 is not set
-# CONFIG_NEC_OSPREY is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_QEMU is not set
CONFIG_SGI_IP22=y
-# CONFIG_SOC_AU1X00 is not set
-# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_BIGSUR is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_PTSWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CRHONE is not set
# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
# CONFIG_TOSHIBA_RBTX4927 is not set
+# CONFIG_TOSHIBA_RBTX4938 is not set
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_HAVE_DEC_LOCK=y
CONFIG_ARC=y
CONFIG_DMA_NONCOHERENT=y
CONFIG_DMA_NEED_PCI_MAP_STATE=y
+CONFIG_CPU_BIG_ENDIAN=y
# CONFIG_CPU_LITTLE_ENDIAN is not set
+CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
CONFIG_IRQ_CPU=y
CONFIG_SWAP_IO_SPACE=y
CONFIG_ARC32=y
@@ -103,8 +134,10 @@ CONFIG_ARC_PROMLIB=y
#
# CPU selection
#
-# CONFIG_CPU_MIPS32 is not set
-# CONFIG_CPU_MIPS64 is not set
+# CONFIG_CPU_MIPS32_R1 is not set
+# CONFIG_CPU_MIPS32_R2 is not set
+# CONFIG_CPU_MIPS64_R1 is not set
+# CONFIG_CPU_MIPS64_R2 is not set
# CONFIG_CPU_R3000 is not set
# CONFIG_CPU_TX39XX is not set
# CONFIG_CPU_VR41XX is not set
@@ -120,22 +153,48 @@ CONFIG_CPU_R5000=y
# CONFIG_CPU_RM7000 is not set
# CONFIG_CPU_RM9000 is not set
# CONFIG_CPU_SB1 is not set
+CONFIG_SYS_HAS_CPU_R4X00=y
+CONFIG_SYS_HAS_CPU_R5000=y
+CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
+CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y
+
+#
+# Kernel type
+#
+CONFIG_32BIT=y
+# CONFIG_64BIT is not set
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_BOARD_SCACHE=y
CONFIG_IP22_CPU_SCACHE=y
+# CONFIG_MIPS_MT is not set
# CONFIG_64BIT_PHYS_ADDR is not set
# CONFIG_CPU_ADVANCED is not set
CONFIG_CPU_HAS_LLSC=y
CONFIG_CPU_HAS_LLDSCD=y
CONFIG_CPU_HAS_SYNC=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_ARCH_FLATMEM_ENABLE=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_PREEMPT_NONE is not set
+CONFIG_PREEMPT_VOLUNTARY=y
# CONFIG_PREEMPT is not set
#
# Bus options (PCI, PCMCIA, EISA, ISA, TC)
#
+CONFIG_HW_HAS_EISA=y
# CONFIG_EISA is not set
CONFIG_MMU=y
@@ -145,10 +204,6 @@ CONFIG_MMU=y
# CONFIG_PCCARD is not set
#
-# PC-card bridges
-#
-
-#
# PCI Hotplug Support
#
@@ -160,115 +215,7 @@ CONFIG_BINFMT_MISC=m
CONFIG_TRAD_SIGNALS=y
#
-# Device Drivers
-#
-
-#
-# Generic Driver Options
-#
-CONFIG_STANDALONE=y
-CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
-
-#
-# Memory Technology Devices (MTD)
-#
-# CONFIG_MTD is not set
-
-#
-# Parallel port support
-#
-# CONFIG_PARPORT is not set
-
-#
-# Plug and Play support
-#
-
-#
-# Block devices
-#
-# CONFIG_BLK_DEV_FD is not set
-# CONFIG_BLK_DEV_COW_COMMON is not set
-# CONFIG_BLK_DEV_LOOP is not set
-# CONFIG_BLK_DEV_NBD is not set
-# CONFIG_BLK_DEV_RAM is not set
-CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_INITRAMFS_SOURCE=""
-# CONFIG_LBD is not set
-CONFIG_CDROM_PKTCDVD=m
-CONFIG_CDROM_PKTCDVD_BUFFERS=8
-# CONFIG_CDROM_PKTCDVD_WCACHE is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-CONFIG_ATA_OVER_ETH=m
-
-#
-# ATA/ATAPI/MFM/RLL support
-#
-# CONFIG_IDE is not set
-
-#
-# SCSI device support
-#
-CONFIG_SCSI=y
-CONFIG_SCSI_PROC_FS=y
-
-#
-# SCSI support type (disk, tape, CD-ROM)
-#
-CONFIG_BLK_DEV_SD=y
-CONFIG_CHR_DEV_ST=y
-# CONFIG_CHR_DEV_OSST is not set
-CONFIG_BLK_DEV_SR=y
-# CONFIG_BLK_DEV_SR_VENDOR is not set
-# CONFIG_CHR_DEV_SG is not set
-
-#
-# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
-#
-# CONFIG_SCSI_MULTI_LUN is not set
-CONFIG_SCSI_CONSTANTS=y
-# CONFIG_SCSI_LOGGING is not set
-
-#
-# SCSI Transport Attributes
-#
-CONFIG_SCSI_SPI_ATTRS=m
-# CONFIG_SCSI_FC_ATTRS is not set
-# CONFIG_SCSI_ISCSI_ATTRS is not set
-
-#
-# SCSI low-level drivers
-#
-CONFIG_SGIWD93_SCSI=y
-# CONFIG_SCSI_SATA is not set
-# CONFIG_SCSI_DEBUG is not set
-
-#
-# Multi-device support (RAID and LVM)
-#
-# CONFIG_MD is not set
-
-#
-# Fusion MPT device support
-#
-
-#
-# IEEE 1394 (FireWire) support
-#
-
-#
-# I2O device support
-#
-
-#
-# Networking support
+# Networking
#
CONFIG_NET=y
@@ -277,12 +224,14 @@ CONFIG_NET=y
#
CONFIG_PACKET=y
CONFIG_PACKET_MMAP=y
-CONFIG_NETLINK_DEV=y
CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
CONFIG_NET_KEY=y
CONFIG_INET=y
CONFIG_IP_MULTICAST=y
# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
CONFIG_IP_PNP=y
# CONFIG_IP_PNP_DHCP is not set
CONFIG_IP_PNP_BOOTP=y
@@ -296,8 +245,10 @@ CONFIG_INET_AH=m
CONFIG_INET_ESP=m
CONFIG_INET_IPCOMP=m
CONFIG_INET_TUNNEL=m
-CONFIG_IP_TCPDIAG=m
-CONFIG_IP_TCPDIAG_IPV6=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
#
# IP: Virtual Server Configuration
@@ -341,6 +292,9 @@ CONFIG_INET6_TUNNEL=m
CONFIG_IPV6_TUNNEL=m
CONFIG_NETFILTER=y
# CONFIG_NETFILTER_DEBUG is not set
+CONFIG_NETFILTER_NETLINK=m
+CONFIG_NETFILTER_NETLINK_QUEUE=m
+CONFIG_NETFILTER_NETLINK_LOG=m
#
# IP: Netfilter Configuration
@@ -348,11 +302,15 @@ CONFIG_NETFILTER=y
CONFIG_IP_NF_CONNTRACK=m
CONFIG_IP_NF_CT_ACCT=y
CONFIG_IP_NF_CONNTRACK_MARK=y
+CONFIG_IP_NF_CONNTRACK_EVENTS=y
+CONFIG_IP_NF_CONNTRACK_NETLINK=m
# CONFIG_IP_NF_CT_PROTO_SCTP is not set
CONFIG_IP_NF_FTP=m
CONFIG_IP_NF_IRC=m
+# CONFIG_IP_NF_NETBIOS_NS is not set
CONFIG_IP_NF_TFTP=m
CONFIG_IP_NF_AMANDA=m
+CONFIG_IP_NF_PPTP=m
CONFIG_IP_NF_QUEUE=m
CONFIG_IP_NF_IPTABLES=m
CONFIG_IP_NF_MATCH_LIMIT=m
@@ -376,9 +334,12 @@ CONFIG_IP_NF_MATCH_OWNER=m
CONFIG_IP_NF_MATCH_ADDRTYPE=m
CONFIG_IP_NF_MATCH_REALM=m
CONFIG_IP_NF_MATCH_SCTP=m
+CONFIG_IP_NF_MATCH_DCCP=m
CONFIG_IP_NF_MATCH_COMMENT=m
CONFIG_IP_NF_MATCH_CONNMARK=m
+CONFIG_IP_NF_MATCH_CONNBYTES=m
CONFIG_IP_NF_MATCH_HASHLIMIT=m
+CONFIG_IP_NF_MATCH_STRING=m
CONFIG_IP_NF_FILTER=m
CONFIG_IP_NF_TARGET_REJECT=m
CONFIG_IP_NF_TARGET_LOG=m
@@ -395,12 +356,14 @@ CONFIG_IP_NF_NAT_IRC=m
CONFIG_IP_NF_NAT_FTP=m
CONFIG_IP_NF_NAT_TFTP=m
CONFIG_IP_NF_NAT_AMANDA=m
+CONFIG_IP_NF_NAT_PPTP=m
CONFIG_IP_NF_MANGLE=m
CONFIG_IP_NF_TARGET_TOS=m
CONFIG_IP_NF_TARGET_ECN=m
CONFIG_IP_NF_TARGET_DSCP=m
CONFIG_IP_NF_TARGET_MARK=m
CONFIG_IP_NF_TARGET_CLASSIFY=m
+CONFIG_IP_NF_TARGET_TTL=m
CONFIG_IP_NF_TARGET_CONNMARK=m
CONFIG_IP_NF_TARGET_CLUSTERIP=m
CONFIG_IP_NF_RAW=m
@@ -410,7 +373,7 @@ CONFIG_IP_NF_ARPFILTER=m
CONFIG_IP_NF_ARP_MANGLE=m
#
-# IPv6: Netfilter Configuration
+# IPv6: Netfilter Configuration (EXPERIMENTAL)
#
CONFIG_IP6_NF_QUEUE=m
CONFIG_IP6_NF_IPTABLES=m
@@ -429,11 +392,16 @@ CONFIG_IP6_NF_MATCH_LENGTH=m
CONFIG_IP6_NF_MATCH_EUI64=m
CONFIG_IP6_NF_FILTER=m
CONFIG_IP6_NF_TARGET_LOG=m
+CONFIG_IP6_NF_TARGET_REJECT=m
CONFIG_IP6_NF_MANGLE=m
CONFIG_IP6_NF_TARGET_MARK=m
+CONFIG_IP6_NF_TARGET_HL=m
CONFIG_IP6_NF_RAW=m
-CONFIG_XFRM=y
-CONFIG_XFRM_USER=m
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
#
# SCTP Configuration (EXPERIMENTAL)
@@ -456,10 +424,6 @@ CONFIG_SCTP_HMAC_MD5=y
CONFIG_NET_DIVERT=y
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
CONFIG_NET_SCHED=y
# CONFIG_NET_SCH_CLK_JIFFIES is not set
CONFIG_NET_SCH_CLK_GETTIMEOFDAY=y
@@ -479,6 +443,7 @@ CONFIG_NET_SCH_INGRESS=m
CONFIG_NET_QOS=y
CONFIG_NET_ESTIMATOR=y
CONFIG_NET_CLS=y
+CONFIG_NET_CLS_BASIC=m
CONFIG_NET_CLS_TCINDEX=m
CONFIG_NET_CLS_ROUTE4=m
CONFIG_NET_CLS_ROUTE=y
@@ -489,6 +454,7 @@ CONFIG_NET_CLS_U32=m
# CONFIG_CLS_U32_MARK is not set
CONFIG_NET_CLS_RSVP=m
CONFIG_NET_CLS_RSVP6=m
+# CONFIG_NET_EMATCH is not set
# CONFIG_NET_CLS_ACT is not set
CONFIG_NET_CLS_POLICE=y
@@ -496,17 +462,153 @@ CONFIG_NET_CLS_POLICE=y
# Network testing
#
# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
# CONFIG_HAMRADIO is not set
# CONFIG_IRDA is not set
# CONFIG_BT is not set
+CONFIG_IEEE80211=m
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=m
+CONFIG_IEEE80211_CRYPT_CCMP=m
+CONFIG_IEEE80211_CRYPT_TKIP=m
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+CONFIG_CONNECTOR=m
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_RAM is not set
+CONFIG_BLK_DEV_RAM_COUNT=16
+# CONFIG_LBD is not set
+CONFIG_CDROM_PKTCDVD=m
+CONFIG_CDROM_PKTCDVD_BUFFERS=8
+# CONFIG_CDROM_PKTCDVD_WCACHE is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_ATA_OVER_ETH=m
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+CONFIG_RAID_ATTRS=m
+CONFIG_SCSI=y
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_ST=y
+# CONFIG_CHR_DEV_OSST is not set
+CONFIG_BLK_DEV_SR=y
+# CONFIG_BLK_DEV_SR_VENDOR is not set
+# CONFIG_CHR_DEV_SG is not set
+CONFIG_CHR_DEV_SCH=m
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# CONFIG_SCSI_MULTI_LUN is not set
+CONFIG_SCSI_CONSTANTS=y
+# CONFIG_SCSI_LOGGING is not set
+
+#
+# SCSI Transport Attributes
+#
+CONFIG_SCSI_SPI_ATTRS=m
+# CONFIG_SCSI_FC_ATTRS is not set
+CONFIG_SCSI_ISCSI_ATTRS=m
+CONFIG_SCSI_SAS_ATTRS=m
+
+#
+# SCSI low-level drivers
+#
+CONFIG_SGIWD93_SCSI=y
+# CONFIG_SCSI_SATA is not set
+# CONFIG_SCSI_DEBUG is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+
+#
+# I2O device support
+#
+
+#
+# Network device support
+#
CONFIG_NETDEVICES=y
CONFIG_DUMMY=m
CONFIG_BONDING=m
CONFIG_EQUALIZER=m
CONFIG_TUN=m
-CONFIG_ETHERTAP=m
+
+#
+# PHY device support
+#
+CONFIG_PHYLIB=m
+CONFIG_PHYCONTROL=y
+
+#
+# MII PHY device drivers
+#
+CONFIG_MARVELL_PHY=m
+CONFIG_DAVICOM_PHY=m
+CONFIG_QSEMI_PHY=m
+CONFIG_LXT_PHY=m
+CONFIG_CICADA_PHY=m
#
# Ethernet (10 or 100Mbit)
@@ -540,6 +642,8 @@ CONFIG_SGISEEQ=y
# CONFIG_SLIP is not set
# CONFIG_SHAPER is not set
# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
#
# ISDN subsystem
@@ -569,18 +673,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
# CONFIG_INPUT_EVBUG is not set
#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=y
-CONFIG_SERIO_I8042=y
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_CT82C710 is not set
-CONFIG_SERIO_LIBPS2=y
-CONFIG_SERIO_RAW=m
-
-#
# Input Device Drivers
#
CONFIG_INPUT_KEYBOARD=y
@@ -598,6 +690,16 @@ CONFIG_MOUSE_SERIAL=m
# CONFIG_INPUT_MISC is not set
#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_I8042=y
+CONFIG_SERIO_SERPORT=y
+CONFIG_SERIO_LIBPS2=y
+CONFIG_SERIO_RAW=m
+# CONFIG_GAMEPORT is not set
+
+#
# Character devices
#
CONFIG_VT=y
@@ -644,11 +746,14 @@ CONFIG_SGI_DS1286=m
#
# Ftape, the floppy tape device driver
#
-# CONFIG_DRM is not set
CONFIG_RAW_DRIVER=m
CONFIG_MAX_RAW_DEVS=256
#
+# TPM devices
+#
+
+#
# I2C support
#
# CONFIG_I2C is not set
@@ -659,10 +764,20 @@ CONFIG_MAX_RAW_DEVS=256
# CONFIG_W1 is not set
#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
+#
# Misc devices
#
#
+# Multimedia Capabilities Port drivers
+#
+
+#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
@@ -693,7 +808,6 @@ CONFIG_LOGO=y
# CONFIG_LOGO_LINUX_VGA16 is not set
# CONFIG_LOGO_LINUX_CLUT224 is not set
CONFIG_LOGO_SGI_CLUT224=y
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Sound
@@ -707,10 +821,6 @@ CONFIG_LOGO_SGI_CLUT224=y
# CONFIG_USB_ARCH_HAS_OHCI is not set
#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
-#
-
-#
# USB Gadget Support
#
# CONFIG_USB_GADGET is not set
@@ -723,13 +833,17 @@ CONFIG_LOGO_SGI_CLUT224=y
#
# InfiniBand support
#
-# CONFIG_INFINIBAND is not set
+
+#
+# SN Devices
+#
#
# File systems
#
CONFIG_EXT2_FS=m
# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
CONFIG_EXT3_FS=y
CONFIG_EXT3_FS_XATTR=y
CONFIG_EXT3_FS_POSIX_ACL=y
@@ -741,12 +855,14 @@ CONFIG_FS_MBCACHE=y
# CONFIG_JFS_FS is not set
CONFIG_FS_POSIX_ACL=y
CONFIG_XFS_FS=m
-# CONFIG_XFS_RT is not set
-CONFIG_XFS_QUOTA=y
+CONFIG_XFS_EXPORT=y
+CONFIG_XFS_QUOTA=m
CONFIG_XFS_SECURITY=y
# CONFIG_XFS_POSIX_ACL is not set
+# CONFIG_XFS_RT is not set
CONFIG_MINIX_FS=m
# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
CONFIG_QUOTA=y
# CONFIG_QFMT_V1 is not set
CONFIG_QFMT_V2=m
@@ -754,6 +870,7 @@ CONFIG_QUOTACTL=y
CONFIG_DNOTIFY=y
CONFIG_AUTOFS_FS=m
CONFIG_AUTOFS4_FS=m
+CONFIG_FUSE_FS=m
#
# CD-ROM/DVD Filesystems
@@ -781,12 +898,10 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
-CONFIG_DEVPTS_FS_XATTR=y
-CONFIG_DEVPTS_FS_SECURITY=y
# CONFIG_TMPFS is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
+CONFIG_RELAYFS_FS=m
#
# Miscellaneous filesystems
@@ -811,15 +926,20 @@ CONFIG_UFS_FS=m
#
CONFIG_NFS_FS=m
CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
# CONFIG_NFS_V4 is not set
# CONFIG_NFS_DIRECTIO is not set
CONFIG_NFSD=m
+CONFIG_NFSD_V2_ACL=y
CONFIG_NFSD_V3=y
+CONFIG_NFSD_V3_ACL=y
# CONFIG_NFSD_V4 is not set
CONFIG_NFSD_TCP=y
CONFIG_LOCKD=m
CONFIG_LOCKD_V4=y
CONFIG_EXPORTFS=m
+CONFIG_NFS_ACL_SUPPORT=m
+CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=m
CONFIG_SUNRPC_GSS=m
CONFIG_RPCSEC_GSS_KRB5=m
@@ -835,6 +955,7 @@ CONFIG_CIFS=m
CONFIG_CODA_FS=m
# CONFIG_CODA_FS_OLD_API is not set
# CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
#
# Partition Types
@@ -908,7 +1029,9 @@ CONFIG_NLS_UTF8=m
#
# Kernel hacking
#
+# CONFIG_PRINTK_TIME is not set
# CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=14
CONFIG_CROSSCOMPILE=y
CONFIG_CMDLINE=""
@@ -931,6 +1054,7 @@ CONFIG_CRYPTO_SHA1=m
CONFIG_CRYPTO_SHA256=m
CONFIG_CRYPTO_SHA512=m
CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_TGR192=m
CONFIG_CRYPTO_DES=m
CONFIG_CRYPTO_BLOWFISH=m
CONFIG_CRYPTO_TWOFISH=m
@@ -942,10 +1066,10 @@ CONFIG_CRYPTO_TEA=m
CONFIG_CRYPTO_ARC4=m
CONFIG_CRYPTO_KHAZAD=m
CONFIG_CRYPTO_ANUBIS=m
-CONFIG_CRYPTO_DEFLATE=y
+CONFIG_CRYPTO_DEFLATE=m
CONFIG_CRYPTO_MICHAEL_MIC=m
CONFIG_CRYPTO_CRC32C=m
-CONFIG_CRYPTO_TEST=m
+# CONFIG_CRYPTO_TEST is not set
#
# Hardware crypto devices
@@ -955,9 +1079,12 @@ CONFIG_CRYPTO_TEST=m
# Library routines
#
# CONFIG_CRC_CCITT is not set
+CONFIG_CRC16=m
CONFIG_CRC32=m
CONFIG_LIBCRC32C=m
-CONFIG_ZLIB_INFLATE=y
-CONFIG_ZLIB_DEFLATE=y
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_ZLIB_INFLATE=m
+CONFIG_ZLIB_DEFLATE=m
+CONFIG_TEXTSEARCH=y
+CONFIG_TEXTSEARCH_KMP=m
+CONFIG_TEXTSEARCH_BM=m
+CONFIG_TEXTSEARCH_FSM=m
diff --git a/arch/mips/configs/ip27_defconfig b/arch/mips/configs/ip27_defconfig
index b2a67da1e031..d962f61d5b98 100644
--- a/arch/mips/configs/ip27_defconfig
+++ b/arch/mips/configs/ip27_defconfig
@@ -1,11 +1,9 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-rc2
-# Wed Jan 26 02:49:04 2005
+# Linux kernel version: 2.6.14-rc2
+# Thu Oct 20 22:26:04 2005
#
CONFIG_MIPS=y
-CONFIG_64BIT=y
-CONFIG_64BIT=y
#
# Code maturity level options
@@ -13,25 +11,31 @@ CONFIG_64BIT=y
CONFIG_EXPERIMENTAL=y
CONFIG_CLEAN_COMPILE=y
CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
#
# General setup
#
CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
CONFIG_POSIX_MQUEUE=y
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=15
-# CONFIG_HOTPLUG is not set
+CONFIG_HOTPLUG=y
CONFIG_KOBJECT_UEVENT=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
+CONFIG_CPUSETS=y
+CONFIG_INITRAMFS_SOURCE=""
CONFIG_EMBEDDED=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
@@ -41,6 +45,7 @@ CONFIG_CC_ALIGN_LABELS=0
CONFIG_CC_ALIGN_LOOPS=0
CONFIG_CC_ALIGN_JUMPS=0
# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
#
# Loadable module support
@@ -57,55 +62,85 @@ CONFIG_STOP_MACHINE=y
#
# Machine selection
#
-# CONFIG_MACH_JAZZ is not set
-# CONFIG_MACH_VR41XX is not set
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_MIPS_PB1550 is not set
+# CONFIG_MIPS_PB1200 is not set
+# CONFIG_MIPS_DB1000 is not set
+# CONFIG_MIPS_DB1100 is not set
+# CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
+# CONFIG_MIPS_DB1200 is not set
+# CONFIG_MIPS_MIRAGE is not set
# CONFIG_MIPS_COBALT is not set
# CONFIG_MACH_DECSTATION is not set
# CONFIG_MIPS_EV64120 is not set
# CONFIG_MIPS_EV96100 is not set
# CONFIG_MIPS_IVR is not set
-# CONFIG_LASAT is not set
# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_LASAT is not set
# CONFIG_MIPS_ATLAS is not set
# CONFIG_MIPS_MALTA is not set
# CONFIG_MIPS_SEAD is not set
+# CONFIG_MIPS_SIM is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
# CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_G is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_JAGUAR_ATX is not set
-# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MIPS_XXS1500 is not set
+# CONFIG_PNX8550_V2PCI is not set
+# CONFIG_PNX8550_JBS is not set
# CONFIG_DDB5074 is not set
# CONFIG_DDB5476 is not set
# CONFIG_DDB5477 is not set
-# CONFIG_NEC_OSPREY is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_QEMU is not set
# CONFIG_SGI_IP22 is not set
CONFIG_SGI_IP27=y
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_BIGSUR is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_PTSWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CRHONE is not set
+# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_TOSHIBA_RBTX4927 is not set
+# CONFIG_TOSHIBA_RBTX4938 is not set
# CONFIG_SGI_SN0_N_MODE is not set
CONFIG_ARCH_DISCONTIGMEM_ENABLE=y
CONFIG_NUMA=y
# CONFIG_MAPPED_KERNEL is not set
# CONFIG_REPLICATE_KTEXT is not set
# CONFIG_REPLICATE_EXHANDLERS is not set
-# CONFIG_SGI_IP32 is not set
-# CONFIG_SIBYTE_SB1xxx_SOC is not set
-# CONFIG_SNI_RM200_PCI is not set
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_HAVE_DEC_LOCK=y
CONFIG_ARC=y
CONFIG_DMA_IP27=y
+CONFIG_CPU_BIG_ENDIAN=y
# CONFIG_CPU_LITTLE_ENDIAN is not set
+CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
CONFIG_MIPS_L1_CACHE_SHIFT=7
CONFIG_ARC64=y
CONFIG_BOOT_ELF64=y
-CONFIG_QL_ISP_A64=y
#
# CPU selection
#
-# CONFIG_CPU_MIPS32 is not set
-# CONFIG_CPU_MIPS64 is not set
+# CONFIG_CPU_MIPS32_R1 is not set
+# CONFIG_CPU_MIPS32_R2 is not set
+# CONFIG_CPU_MIPS64_R1 is not set
+# CONFIG_CPU_MIPS64_R2 is not set
# CONFIG_CPU_R3000 is not set
# CONFIG_CPU_TX39XX is not set
# CONFIG_CPU_VR41XX is not set
@@ -121,17 +156,42 @@ CONFIG_CPU_R10000=y
# CONFIG_CPU_RM7000 is not set
# CONFIG_CPU_RM9000 is not set
# CONFIG_CPU_SB1 is not set
+CONFIG_SYS_HAS_CPU_R10000=y
+CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y
+
+#
+# Kernel type
+#
+# CONFIG_32BIT is not set
+CONFIG_64BIT=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_CPU_HAS_PREFETCH=y
+# CONFIG_MIPS_MT is not set
CONFIG_CPU_HAS_LLSC=y
CONFIG_CPU_HAS_LLDSCD=y
CONFIG_CPU_HAS_SYNC=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_CPU_SUPPORTS_HIGHMEM=y
+CONFIG_SELECT_MEMORY_MODEL=y
+# CONFIG_FLATMEM_MANUAL is not set
+CONFIG_DISCONTIGMEM_MANUAL=y
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_DISCONTIGMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_NEED_MULTIPLE_NODES=y
+# CONFIG_SPARSEMEM_STATIC is not set
CONFIG_SMP=y
CONFIG_NR_CPUS=64
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
+CONFIG_PREEMPT_BKL=y
# CONFIG_MIPS_INSANE_LARGE is not set
#
@@ -141,7 +201,6 @@ CONFIG_HW_HAS_PCI=y
CONFIG_PCI=y
CONFIG_PCI_DOMAINS=y
CONFIG_PCI_LEGACY_PROC=y
-CONFIG_PCI_NAMES=y
CONFIG_MMU=y
#
@@ -150,10 +209,6 @@ CONFIG_MMU=y
# CONFIG_PCCARD is not set
#
-# PC-card bridges
-#
-
-#
# PCI Hotplug Support
#
# CONFIG_HOTPLUG_PCI is not set
@@ -163,7 +218,7 @@ CONFIG_MMU=y
#
CONFIG_BINFMT_ELF=y
# CONFIG_BINFMT_MISC is not set
-# CONFIG_BUILD_ELF64 is not set
+CONFIG_BUILD_ELF64=y
CONFIG_MIPS32_COMPAT=y
CONFIG_COMPAT=y
CONFIG_MIPS32_O32=y
@@ -171,6 +226,111 @@ CONFIG_MIPS32_O32=y
CONFIG_BINFMT_ELF32=y
#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+CONFIG_NET_KEY=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+# CONFIG_IP_PNP_BOOTP is not set
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+CONFIG_INET_TUNNEL=m
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+# CONFIG_IPV6 is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# 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_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+CONFIG_NET_SCHED=y
+# CONFIG_NET_SCH_CLK_JIFFIES is not set
+CONFIG_NET_SCH_CLK_GETTIMEOFDAY=y
+# CONFIG_NET_SCH_CLK_CPU is not set
+CONFIG_NET_SCH_CBQ=m
+CONFIG_NET_SCH_HTB=m
+CONFIG_NET_SCH_HFSC=m
+CONFIG_NET_SCH_PRIO=m
+CONFIG_NET_SCH_RED=m
+CONFIG_NET_SCH_SFQ=m
+CONFIG_NET_SCH_TEQL=m
+CONFIG_NET_SCH_TBF=m
+CONFIG_NET_SCH_GRED=m
+CONFIG_NET_SCH_DSMARK=m
+CONFIG_NET_SCH_NETEM=m
+CONFIG_NET_SCH_INGRESS=m
+CONFIG_NET_QOS=y
+CONFIG_NET_ESTIMATOR=y
+CONFIG_NET_CLS=y
+CONFIG_NET_CLS_BASIC=m
+CONFIG_NET_CLS_TCINDEX=m
+CONFIG_NET_CLS_ROUTE4=m
+CONFIG_NET_CLS_ROUTE=y
+CONFIG_NET_CLS_FW=m
+CONFIG_NET_CLS_U32=m
+# CONFIG_CLS_U32_PERF is not set
+# CONFIG_NET_CLS_IND is not set
+CONFIG_NET_CLS_RSVP=m
+CONFIG_NET_CLS_RSVP6=m
+# CONFIG_NET_EMATCH is not set
+# CONFIG_NET_CLS_ACT is not set
+CONFIG_NET_CLS_POLICE=y
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_IEEE80211=m
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=m
+CONFIG_IEEE80211_CRYPT_CCMP=m
+CONFIG_IEEE80211_CRYPT_TKIP=m
+
+#
# Device Drivers
#
@@ -179,7 +339,12 @@ CONFIG_BINFMT_ELF32=y
#
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
+CONFIG_FW_LOADER=m
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+CONFIG_CONNECTOR=m
#
# Memory Technology Devices (MTD)
@@ -198,7 +363,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
#
# Block devices
#
-# CONFIG_BLK_DEV_FD is not set
# CONFIG_BLK_CPQ_DA is not set
# CONFIG_BLK_CPQ_CISS_DA is not set
# CONFIG_BLK_DEV_DAC960 is not set
@@ -210,7 +374,6 @@ CONFIG_BLK_DEV_CRYPTOLOOP=m
# CONFIG_BLK_DEV_SX8 is not set
# CONFIG_BLK_DEV_RAM is not set
CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_INITRAMFS_SOURCE=""
CONFIG_CDROM_PKTCDVD=m
CONFIG_CDROM_PKTCDVD_BUFFERS=8
# CONFIG_CDROM_PKTCDVD_WCACHE is not set
@@ -232,6 +395,7 @@ CONFIG_ATA_OVER_ETH=m
#
# SCSI device support
#
+CONFIG_RAID_ATTRS=m
CONFIG_SCSI=y
CONFIG_SCSI_PROC_FS=y
@@ -241,8 +405,10 @@ CONFIG_SCSI_PROC_FS=y
CONFIG_BLK_DEV_SD=y
CONFIG_CHR_DEV_ST=y
# CONFIG_CHR_DEV_OSST is not set
-# CONFIG_BLK_DEV_SR is not set
-# CONFIG_CHR_DEV_SG is not set
+CONFIG_BLK_DEV_SR=m
+CONFIG_BLK_DEV_SR_VENDOR=y
+CONFIG_CHR_DEV_SG=m
+CONFIG_CHR_DEV_SCH=m
#
# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
@@ -256,7 +422,8 @@ CONFIG_SCSI_LOGGING=y
#
CONFIG_SCSI_SPI_ATTRS=y
# CONFIG_SCSI_FC_ATTRS is not set
-# CONFIG_SCSI_ISCSI_ATTRS is not set
+CONFIG_SCSI_ISCSI_ATTRS=m
+CONFIG_SCSI_SAS_ATTRS=m
#
# SCSI low-level drivers
@@ -271,26 +438,24 @@ CONFIG_SCSI_SPI_ATTRS=y
# CONFIG_MEGARAID_NEWGEN is not set
# CONFIG_MEGARAID_LEGACY is not set
# CONFIG_SCSI_SATA is not set
-# CONFIG_SCSI_BUSLOGIC is not set
# CONFIG_SCSI_DMX3191D is not set
-# CONFIG_SCSI_EATA is not set
-# CONFIG_SCSI_EATA_PIO is not set
# CONFIG_SCSI_FUTURE_DOMAIN is not set
-# CONFIG_SCSI_GDTH is not set
# CONFIG_SCSI_IPS is not set
# CONFIG_SCSI_INITIO is not set
# CONFIG_SCSI_INIA100 is not set
# CONFIG_SCSI_SYM53C8XX_2 is not set
# CONFIG_SCSI_IPR is not set
-CONFIG_SCSI_QLOGIC_ISP=y
# CONFIG_SCSI_QLOGIC_FC is not set
-# CONFIG_SCSI_QLOGIC_1280 is not set
+CONFIG_SCSI_QLOGIC_1280=y
+CONFIG_SCSI_QLOGIC_1280_1040=y
CONFIG_SCSI_QLA2XXX=y
# CONFIG_SCSI_QLA21XX is not set
# CONFIG_SCSI_QLA22XX is not set
# CONFIG_SCSI_QLA2300 is not set
# CONFIG_SCSI_QLA2322 is not set
# CONFIG_SCSI_QLA6312 is not set
+# CONFIG_SCSI_QLA24XX is not set
+# CONFIG_SCSI_LPFC is not set
# CONFIG_SCSI_DC395x is not set
# CONFIG_SCSI_DC390T is not set
# CONFIG_SCSI_DEBUG is not set
@@ -313,11 +478,15 @@ CONFIG_DM_CRYPT=m
CONFIG_DM_SNAPSHOT=m
CONFIG_DM_MIRROR=m
CONFIG_DM_ZERO=m
+CONFIG_DM_MULTIPATH=m
+CONFIG_DM_MULTIPATH_EMC=m
#
# Fusion MPT device support
#
# CONFIG_FUSION is not set
+# CONFIG_FUSION_SPI is not set
+# CONFIG_FUSION_FC is not set
#
# IEEE 1394 (FireWire) support
@@ -330,107 +499,13 @@ CONFIG_DM_ZERO=m
# CONFIG_I2O is not set
#
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
-CONFIG_NETLINK_DEV=y
-CONFIG_UNIX=y
-CONFIG_NET_KEY=y
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-# CONFIG_IP_ADVANCED_ROUTER is not set
-CONFIG_IP_PNP=y
-# CONFIG_IP_PNP_DHCP is not set
-# CONFIG_IP_PNP_BOOTP is not set
-# CONFIG_IP_PNP_RARP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_IP_MROUTE is not set
-# CONFIG_ARPD is not set
-# CONFIG_SYN_COOKIES is not set
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-CONFIG_INET_TUNNEL=m
-CONFIG_IP_TCPDIAG=m
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-# CONFIG_IPV6 is not set
-# CONFIG_NETFILTER is not set
-CONFIG_XFRM=y
-CONFIG_XFRM_USER=m
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP 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_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
-CONFIG_NET_SCHED=y
-# CONFIG_NET_SCH_CLK_JIFFIES is not set
-CONFIG_NET_SCH_CLK_GETTIMEOFDAY=y
-# CONFIG_NET_SCH_CLK_CPU is not set
-CONFIG_NET_SCH_CBQ=m
-CONFIG_NET_SCH_HTB=m
-CONFIG_NET_SCH_HFSC=m
-CONFIG_NET_SCH_PRIO=m
-CONFIG_NET_SCH_RED=m
-CONFIG_NET_SCH_SFQ=m
-CONFIG_NET_SCH_TEQL=m
-CONFIG_NET_SCH_TBF=m
-CONFIG_NET_SCH_GRED=m
-CONFIG_NET_SCH_DSMARK=m
-CONFIG_NET_SCH_NETEM=m
-CONFIG_NET_SCH_INGRESS=m
-CONFIG_NET_QOS=y
-CONFIG_NET_ESTIMATOR=y
-CONFIG_NET_CLS=y
-CONFIG_NET_CLS_TCINDEX=m
-CONFIG_NET_CLS_ROUTE4=m
-CONFIG_NET_CLS_ROUTE=y
-CONFIG_NET_CLS_FW=m
-CONFIG_NET_CLS_U32=m
-# CONFIG_CLS_U32_PERF is not set
-# CONFIG_NET_CLS_IND is not set
-CONFIG_NET_CLS_RSVP=m
-CONFIG_NET_CLS_RSVP6=m
-# CONFIG_NET_CLS_ACT is not set
-CONFIG_NET_CLS_POLICE=y
-
-#
-# Network testing
+# Network device support
#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
CONFIG_NETDEVICES=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_EQUALIZER is not set
# CONFIG_TUN is not set
-# CONFIG_ETHERTAP is not set
#
# ARCnet devices
@@ -438,13 +513,25 @@ CONFIG_NETDEVICES=y
# CONFIG_ARCNET is not set
#
+# PHY device support
+#
+CONFIG_PHYLIB=m
+CONFIG_PHYCONTROL=y
+
+#
+# MII PHY device drivers
+#
+CONFIG_MARVELL_PHY=m
+CONFIG_DAVICOM_PHY=m
+CONFIG_QSEMI_PHY=m
+CONFIG_LXT_PHY=m
+CONFIG_CICADA_PHY=m
+
+#
# Ethernet (10 or 100Mbit)
#
CONFIG_NET_ETHERNET=y
CONFIG_MII=y
-CONFIG_SGI_IOC3_ETH=y
-CONFIG_SGI_IOC3_ETH_HW_RX_CSUM=y
-CONFIG_SGI_IOC3_ETH_HW_TX_CSUM=y
# CONFIG_HAPPYMEAL is not set
# CONFIG_SUNGEM is not set
# CONFIG_NET_VENDOR_3COM is not set
@@ -466,12 +553,16 @@ CONFIG_SGI_IOC3_ETH_HW_TX_CSUM=y
# CONFIG_HAMACHI is not set
# CONFIG_YELLOWFIN is not set
# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
# CONFIG_SK98LIN is not set
# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
#
# Ethernet (10000 Mbit)
#
+# CONFIG_CHELSIO_T1 is not set
# CONFIG_IXGB is not set
# CONFIG_S2IO is not set
@@ -484,6 +575,8 @@ CONFIG_SGI_IOC3_ETH_HW_TX_CSUM=y
# Wireless LAN (non-hamradio)
#
# CONFIG_NET_RADIO is not set
+# CONFIG_IPW_DEBUG is not set
+CONFIG_IPW2200=m
#
# Wan interfaces
@@ -496,6 +589,8 @@ CONFIG_SGI_IOC3_ETH_HW_TX_CSUM=y
# CONFIG_NET_FC is not set
# CONFIG_SHAPER is not set
# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
#
# ISDN subsystem
@@ -513,25 +608,15 @@ CONFIG_SGI_IOC3_ETH_HW_TX_CSUM=y
# CONFIG_INPUT is not set
#
-# Userland interfaces
-#
-
-#
-# Input I/O drivers
+# Hardware I/O ports
#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
CONFIG_SERIO=y
# CONFIG_SERIO_I8042 is not set
CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_CT82C710 is not set
# CONFIG_SERIO_PCIPS2 is not set
-# CONFIG_SERIO_LIBPS2 is not set
+CONFIG_SERIO_LIBPS2=m
CONFIG_SERIO_RAW=m
-
-#
-# Input Device Drivers
-#
+# CONFIG_GAMEPORT is not set
#
# Character devices
@@ -549,7 +634,6 @@ CONFIG_SERIAL_8250_EXTENDED=y
CONFIG_SERIAL_8250_MANY_PORTS=y
CONFIG_SERIAL_8250_SHARE_IRQ=y
# CONFIG_SERIAL_8250_DETECT_IRQ is not set
-# CONFIG_SERIAL_8250_MULTIPORT is not set
# CONFIG_SERIAL_8250_RSA is not set
#
@@ -557,6 +641,7 @@ CONFIG_SERIAL_8250_SHARE_IRQ=y
#
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
CONFIG_UNIX98_PTYS=y
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
@@ -584,6 +669,11 @@ CONFIG_SGI_IP27_RTC=y
# CONFIG_RAW_DRIVER is not set
#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+
+#
# I2C support
#
# CONFIG_I2C is not set
@@ -594,10 +684,20 @@ CONFIG_SGI_IP27_RTC=y
# CONFIG_W1 is not set
#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
+#
# Misc devices
#
#
+# Multimedia Capabilities Port drivers
+#
+
+#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
@@ -611,7 +711,6 @@ CONFIG_SGI_IP27_RTC=y
# Graphics support
#
# CONFIG_FB is not set
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Sound
@@ -621,13 +720,9 @@ CONFIG_SGI_IP27_RTC=y
#
# USB support
#
-# CONFIG_USB is not set
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB_ARCH_HAS_OHCI=y
-
-#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
-#
+# CONFIG_USB is not set
#
# USB Gadget Support
@@ -645,12 +740,17 @@ CONFIG_USB_ARCH_HAS_OHCI=y
# CONFIG_INFINIBAND is not set
#
+# SN Devices
+#
+
+#
# File systems
#
CONFIG_EXT2_FS=y
CONFIG_EXT2_FS_XATTR=y
CONFIG_EXT2_FS_POSIX_ACL=y
CONFIG_EXT2_FS_SECURITY=y
+# CONFIG_EXT2_FS_XIP is not set
CONFIG_EXT3_FS=y
CONFIG_EXT3_FS_XATTR=y
CONFIG_EXT3_FS_POSIX_ACL=y
@@ -662,17 +762,19 @@ CONFIG_FS_MBCACHE=y
# CONFIG_JFS_FS is not set
CONFIG_FS_POSIX_ACL=y
CONFIG_XFS_FS=m
-# CONFIG_XFS_RT is not set
-CONFIG_XFS_QUOTA=y
+CONFIG_XFS_QUOTA=m
CONFIG_XFS_SECURITY=y
CONFIG_XFS_POSIX_ACL=y
+# CONFIG_XFS_RT is not set
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
# CONFIG_QUOTA is not set
CONFIG_QUOTACTL=y
CONFIG_DNOTIFY=y
CONFIG_AUTOFS_FS=m
# CONFIG_AUTOFS4_FS is not set
+CONFIG_FUSE_FS=m
#
# CD-ROM/DVD Filesystems
@@ -693,12 +795,10 @@ CONFIG_AUTOFS_FS=m
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
-CONFIG_DEVPTS_FS_XATTR=y
-CONFIG_DEVPTS_FS_SECURITY=y
# CONFIG_TMPFS is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
+CONFIG_RELAYFS_FS=m
#
# Miscellaneous filesystems
@@ -722,13 +822,14 @@ CONFIG_RAMFS=y
#
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
# CONFIG_NFS_V4 is not set
# CONFIG_NFS_DIRECTIO is not set
# CONFIG_NFSD is not set
# CONFIG_ROOT_NFS is not set
CONFIG_LOCKD=y
CONFIG_LOCKD_V4=y
-# CONFIG_EXPORTFS is not set
+CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
CONFIG_SUNRPC_GSS=y
CONFIG_RPCSEC_GSS_KRB5=y
@@ -738,6 +839,7 @@ CONFIG_RPCSEC_GSS_KRB5=y
# CONFIG_NCP_FS is not set
# CONFIG_CODA_FS is not set
# CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
#
# Partition Types
@@ -772,7 +874,9 @@ CONFIG_SGI_PARTITION=y
#
# Kernel hacking
#
+# CONFIG_PRINTK_TIME is not set
# CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=15
CONFIG_CROSSCOMPILE=y
CONFIG_CMDLINE=""
@@ -788,28 +892,29 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
#
CONFIG_CRYPTO=y
CONFIG_CRYPTO_HMAC=y
-CONFIG_CRYPTO_NULL=y
-CONFIG_CRYPTO_MD4=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_MD4=m
CONFIG_CRYPTO_MD5=y
-CONFIG_CRYPTO_SHA1=y
-CONFIG_CRYPTO_SHA256=y
-CONFIG_CRYPTO_SHA512=y
+CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_TGR192=m
CONFIG_CRYPTO_DES=y
-CONFIG_CRYPTO_BLOWFISH=y
-CONFIG_CRYPTO_TWOFISH=y
-CONFIG_CRYPTO_SERPENT=y
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_SERPENT=m
CONFIG_CRYPTO_AES=m
-CONFIG_CRYPTO_CAST5=y
-CONFIG_CRYPTO_CAST6=y
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
CONFIG_CRYPTO_TEA=m
-CONFIG_CRYPTO_ARC4=y
+CONFIG_CRYPTO_ARC4=m
CONFIG_CRYPTO_KHAZAD=m
CONFIG_CRYPTO_ANUBIS=m
-CONFIG_CRYPTO_DEFLATE=y
-CONFIG_CRYPTO_MICHAEL_MIC=y
+CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
CONFIG_CRYPTO_CRC32C=m
-CONFIG_CRYPTO_TEST=m
+# CONFIG_CRYPTO_TEST is not set
#
# Hardware crypto devices
@@ -819,9 +924,8 @@ CONFIG_CRYPTO_TEST=m
# Library routines
#
# CONFIG_CRC_CCITT is not set
+CONFIG_CRC16=m
CONFIG_CRC32=y
CONFIG_LIBCRC32C=m
-CONFIG_ZLIB_INFLATE=y
-CONFIG_ZLIB_DEFLATE=y
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_ZLIB_INFLATE=m
+CONFIG_ZLIB_DEFLATE=m
diff --git a/arch/mips/configs/ip32_defconfig b/arch/mips/configs/ip32_defconfig
index b26e1173365d..bf8fb95b21dc 100644
--- a/arch/mips/configs/ip32_defconfig
+++ b/arch/mips/configs/ip32_defconfig
@@ -1,11 +1,9 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-rc2
-# Wed Jan 26 02:49:04 2005
+# Linux kernel version: 2.6.14-rc2
+# Thu Oct 20 22:26:07 2005
#
CONFIG_MIPS=y
-CONFIG_64BIT=y
-CONFIG_64BIT=y
#
# Code maturity level options
@@ -13,11 +11,13 @@ CONFIG_64BIT=y
CONFIG_EXPERIMENTAL=y
CONFIG_CLEAN_COMPILE=y
CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
#
# General setup
#
CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
# CONFIG_POSIX_MQUEUE is not set
@@ -25,13 +25,16 @@ CONFIG_BSD_PROCESS_ACCT=y
# CONFIG_BSD_PROCESS_ACCT_V3 is not set
CONFIG_SYSCTL=y
# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_HOTPLUG is not set
+CONFIG_HOTPLUG=y
CONFIG_KOBJECT_UEVENT=y
# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
CONFIG_EMBEDDED=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
@@ -41,6 +44,7 @@ CONFIG_CC_ALIGN_LABELS=0
CONFIG_CC_ALIGN_LOOPS=0
CONFIG_CC_ALIGN_JUMPS=0
# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
#
# Loadable module support
@@ -50,42 +54,71 @@ CONFIG_CC_ALIGN_JUMPS=0
#
# Machine selection
#
-# CONFIG_MACH_JAZZ is not set
-# CONFIG_MACH_VR41XX is not set
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_MIPS_PB1550 is not set
+# CONFIG_MIPS_PB1200 is not set
+# CONFIG_MIPS_DB1000 is not set
+# CONFIG_MIPS_DB1100 is not set
+# CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
+# CONFIG_MIPS_DB1200 is not set
+# CONFIG_MIPS_MIRAGE is not set
# CONFIG_MIPS_COBALT is not set
# CONFIG_MACH_DECSTATION is not set
# CONFIG_MIPS_EV64120 is not set
# CONFIG_MIPS_EV96100 is not set
# CONFIG_MIPS_IVR is not set
-# CONFIG_LASAT is not set
# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_LASAT is not set
# CONFIG_MIPS_ATLAS is not set
# CONFIG_MIPS_MALTA is not set
# CONFIG_MIPS_SEAD is not set
+# CONFIG_MIPS_SIM is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
# CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_G is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_JAGUAR_ATX is not set
-# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MIPS_XXS1500 is not set
+# CONFIG_PNX8550_V2PCI is not set
+# CONFIG_PNX8550_JBS is not set
# CONFIG_DDB5074 is not set
# CONFIG_DDB5476 is not set
# CONFIG_DDB5477 is not set
-# CONFIG_NEC_OSPREY is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_QEMU is not set
# CONFIG_SGI_IP22 is not set
# CONFIG_SGI_IP27 is not set
CONFIG_SGI_IP32=y
-# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SIBYTE_BIGSUR is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_PTSWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CRHONE is not set
# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_TOSHIBA_RBTX4927 is not set
+# CONFIG_TOSHIBA_RBTX4938 is not set
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_HAVE_DEC_LOCK=y
CONFIG_ARC=y
CONFIG_DMA_IP32=y
-CONFIG_OWN_DMA=y
CONFIG_DMA_NONCOHERENT=y
CONFIG_DMA_NEED_PCI_MAP_STATE=y
+CONFIG_OWN_DMA=y
+CONFIG_CPU_BIG_ENDIAN=y
# CONFIG_CPU_LITTLE_ENDIAN is not set
+CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
CONFIG_ARC32=y
CONFIG_BOOT_ELF32=y
CONFIG_MIPS_L1_CACHE_SHIFT=5
@@ -95,8 +128,10 @@ CONFIG_ARC_PROMLIB=y
#
# CPU selection
#
-# CONFIG_CPU_MIPS32 is not set
-# CONFIG_CPU_MIPS64 is not set
+# CONFIG_CPU_MIPS32_R1 is not set
+# CONFIG_CPU_MIPS32_R2 is not set
+# CONFIG_CPU_MIPS64_R1 is not set
+# CONFIG_CPU_MIPS64_R2 is not set
# CONFIG_CPU_R3000 is not set
# CONFIG_CPU_TX39XX is not set
# CONFIG_CPU_VR41XX is not set
@@ -112,6 +147,17 @@ CONFIG_CPU_R5000=y
# CONFIG_CPU_RM7000 is not set
# CONFIG_CPU_RM9000 is not set
# CONFIG_CPU_SB1 is not set
+CONFIG_SYS_HAS_CPU_R5000=y
+CONFIG_SYS_HAS_CPU_RM7000=y
+CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y
+
+#
+# Kernel type
+#
+# CONFIG_32BIT is not set
+CONFIG_64BIT=y
CONFIG_PAGE_SIZE_4KB=y
# CONFIG_PAGE_SIZE_8KB is not set
# CONFIG_PAGE_SIZE_16KB is not set
@@ -119,9 +165,22 @@ CONFIG_PAGE_SIZE_4KB=y
CONFIG_BOARD_SCACHE=y
CONFIG_R5000_CPU_SCACHE=y
CONFIG_RM7000_CPU_SCACHE=y
+# CONFIG_MIPS_MT is not set
CONFIG_CPU_HAS_LLSC=y
CONFIG_CPU_HAS_LLDSCD=y
CONFIG_CPU_HAS_SYNC=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_ARCH_FLATMEM_ENABLE=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_PREEMPT_NONE is not set
+CONFIG_PREEMPT_VOLUNTARY=y
# CONFIG_PREEMPT is not set
#
@@ -130,7 +189,6 @@ CONFIG_CPU_HAS_SYNC=y
CONFIG_HW_HAS_PCI=y
CONFIG_PCI=y
CONFIG_PCI_LEGACY_PROC=y
-CONFIG_PCI_NAMES=y
CONFIG_MMU=y
#
@@ -139,10 +197,6 @@ CONFIG_MMU=y
# CONFIG_PCCARD is not set
#
-# PC-card bridges
-#
-
-#
# PCI Hotplug Support
#
# CONFIG_HOTPLUG_PCI is not set
@@ -160,6 +214,80 @@ CONFIG_MIPS32_O32=y
CONFIG_BINFMT_ELF32=y
#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=y
+CONFIG_NET_KEY=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+CONFIG_INET_TUNNEL=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+# CONFIG_IPV6 is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# 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_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_IEEE80211=y
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=y
+CONFIG_IEEE80211_CRYPT_CCMP=y
+CONFIG_IEEE80211_CRYPT_TKIP=y
+
+#
# Device Drivers
#
@@ -168,7 +296,12 @@ CONFIG_BINFMT_ELF32=y
#
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
+CONFIG_FW_LOADER=y
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+CONFIG_CONNECTOR=y
#
# Memory Technology Devices (MTD)
@@ -187,7 +320,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
#
# Block devices
#
-# CONFIG_BLK_DEV_FD is not set
# CONFIG_BLK_CPQ_DA is not set
# CONFIG_BLK_CPQ_CISS_DA is not set
# CONFIG_BLK_DEV_DAC960 is not set
@@ -199,7 +331,6 @@ CONFIG_BLK_DEV_LOOP=y
# CONFIG_BLK_DEV_SX8 is not set
# CONFIG_BLK_DEV_RAM is not set
CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_INITRAMFS_SOURCE=""
CONFIG_CDROM_PKTCDVD=y
CONFIG_CDROM_PKTCDVD_BUFFERS=8
# CONFIG_CDROM_PKTCDVD_WCACHE is not set
@@ -221,6 +352,7 @@ CONFIG_ATA_OVER_ETH=y
#
# SCSI device support
#
+CONFIG_RAID_ATTRS=y
CONFIG_SCSI=y
CONFIG_SCSI_PROC_FS=y
@@ -233,6 +365,7 @@ CONFIG_CHR_DEV_OSST=y
CONFIG_BLK_DEV_SR=y
CONFIG_BLK_DEV_SR_VENDOR=y
CONFIG_CHR_DEV_SG=y
+# CONFIG_CHR_DEV_SCH is not set
#
# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
@@ -244,9 +377,10 @@ CONFIG_SCSI_LOGGING=y
#
# SCSI Transport Attributes
#
-# CONFIG_SCSI_SPI_ATTRS is not set
+CONFIG_SCSI_SPI_ATTRS=y
# CONFIG_SCSI_FC_ATTRS is not set
# CONFIG_SCSI_ISCSI_ATTRS is not set
+CONFIG_SCSI_SAS_ATTRS=y
#
# SCSI low-level drivers
@@ -266,18 +400,13 @@ CONFIG_AIC7XXX_REG_PRETTY_PRINT=y
# CONFIG_MEGARAID_NEWGEN is not set
# CONFIG_MEGARAID_LEGACY is not set
# CONFIG_SCSI_SATA is not set
-# CONFIG_SCSI_BUSLOGIC is not set
# CONFIG_SCSI_DMX3191D is not set
-# CONFIG_SCSI_EATA is not set
-# CONFIG_SCSI_EATA_PIO is not set
# CONFIG_SCSI_FUTURE_DOMAIN is not set
-# CONFIG_SCSI_GDTH is not set
# CONFIG_SCSI_IPS is not set
# CONFIG_SCSI_INITIO is not set
# CONFIG_SCSI_INIA100 is not set
# CONFIG_SCSI_SYM53C8XX_2 is not set
# CONFIG_SCSI_IPR is not set
-# CONFIG_SCSI_QLOGIC_ISP is not set
# CONFIG_SCSI_QLOGIC_FC is not set
# CONFIG_SCSI_QLOGIC_1280 is not set
CONFIG_SCSI_QLA2XXX=y
@@ -286,6 +415,8 @@ CONFIG_SCSI_QLA2XXX=y
# CONFIG_SCSI_QLA2300 is not set
# CONFIG_SCSI_QLA2322 is not set
# CONFIG_SCSI_QLA6312 is not set
+# CONFIG_SCSI_QLA24XX is not set
+# CONFIG_SCSI_LPFC is not set
# CONFIG_SCSI_DC395x is not set
# CONFIG_SCSI_DC390T is not set
# CONFIG_SCSI_DEBUG is not set
@@ -299,6 +430,8 @@ CONFIG_SCSI_QLA2XXX=y
# Fusion MPT device support
#
# CONFIG_FUSION is not set
+# CONFIG_FUSION_SPI is not set
+# CONFIG_FUSION_FC is not set
#
# IEEE 1394 (FireWire) support
@@ -311,78 +444,13 @@ CONFIG_SCSI_QLA2XXX=y
# CONFIG_I2O is not set
#
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
-CONFIG_NETLINK_DEV=y
-CONFIG_UNIX=y
-CONFIG_NET_KEY=y
-CONFIG_INET=y
-# CONFIG_IP_MULTICAST is not set
-# CONFIG_IP_ADVANCED_ROUTER is not set
-CONFIG_IP_PNP=y
-# CONFIG_IP_PNP_DHCP is not set
-CONFIG_IP_PNP_BOOTP=y
-# CONFIG_IP_PNP_RARP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_ARPD is not set
-# CONFIG_SYN_COOKIES is not set
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-CONFIG_INET_TUNNEL=y
-CONFIG_IP_TCPDIAG=y
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-# CONFIG_IPV6 is not set
-# CONFIG_NETFILTER is not set
-CONFIG_XFRM=y
-CONFIG_XFRM_USER=y
-
-#
-# SCTP Configuration (EXPERIMENTAL)
+# Network device support
#
-# CONFIG_IP_SCTP 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_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
CONFIG_NETDEVICES=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_EQUALIZER is not set
# CONFIG_TUN is not set
-# CONFIG_ETHERTAP is not set
#
# ARCnet devices
@@ -390,6 +458,21 @@ CONFIG_NETDEVICES=y
# CONFIG_ARCNET is not set
#
+# PHY device support
+#
+CONFIG_PHYLIB=y
+CONFIG_PHYCONTROL=y
+
+#
+# MII PHY device drivers
+#
+CONFIG_MARVELL_PHY=y
+CONFIG_DAVICOM_PHY=y
+CONFIG_QSEMI_PHY=y
+CONFIG_LXT_PHY=y
+CONFIG_CICADA_PHY=y
+
+#
# Ethernet (10 or 100Mbit)
#
CONFIG_NET_ETHERNET=y
@@ -416,12 +499,16 @@ CONFIG_SGI_O2MACE_ETH=y
# CONFIG_HAMACHI is not set
# CONFIG_YELLOWFIN is not set
# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
# CONFIG_SK98LIN is not set
# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
#
# Ethernet (10000 Mbit)
#
+# CONFIG_CHELSIO_T1 is not set
# CONFIG_IXGB is not set
# CONFIG_S2IO is not set
@@ -434,6 +521,8 @@ CONFIG_SGI_O2MACE_ETH=y
# Wireless LAN (non-hamradio)
#
# CONFIG_NET_RADIO is not set
+# CONFIG_IPW_DEBUG is not set
+CONFIG_IPW2200=y
#
# Wan interfaces
@@ -446,6 +535,8 @@ CONFIG_SGI_O2MACE_ETH=y
# CONFIG_NET_FC is not set
# CONFIG_SHAPER is not set
# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
#
# ISDN subsystem
@@ -475,27 +566,25 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
# CONFIG_INPUT_EVBUG is not set
#
-# Input I/O drivers
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
CONFIG_SERIO=y
# CONFIG_SERIO_I8042 is not set
CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_CT82C710 is not set
# CONFIG_SERIO_PCIPS2 is not set
# CONFIG_SERIO_MACEPS2 is not set
# CONFIG_SERIO_LIBPS2 is not set
CONFIG_SERIO_RAW=y
-
-#
-# Input Device Drivers
-#
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_INPUT_JOYSTICK is not set
-# CONFIG_INPUT_TOUCHSCREEN is not set
-# CONFIG_INPUT_MISC is not set
+# CONFIG_GAMEPORT is not set
#
# Character devices
@@ -518,6 +607,7 @@ CONFIG_SERIAL_8250_NR_UARTS=4
#
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
CONFIG_UNIX98_PTYS=y
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
@@ -544,6 +634,11 @@ CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_RAW_DRIVER is not set
#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+
+#
# I2C support
#
# CONFIG_I2C is not set
@@ -554,10 +649,20 @@ CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_W1 is not set
#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
+#
# Misc devices
#
#
+# Multimedia Capabilities Port drivers
+#
+
+#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
@@ -577,7 +682,6 @@ CONFIG_LEGACY_PTY_COUNT=256
#
# CONFIG_VGA_CONSOLE is not set
CONFIG_DUMMY_CONSOLE=y
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Sound
@@ -587,13 +691,9 @@ CONFIG_DUMMY_CONSOLE=y
#
# USB support
#
-# CONFIG_USB is not set
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB_ARCH_HAS_OHCI=y
-
-#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
-#
+# CONFIG_USB is not set
#
# USB Gadget Support
@@ -611,21 +711,29 @@ CONFIG_USB_ARCH_HAS_OHCI=y
# CONFIG_INFINIBAND is not set
#
+# SN Devices
+#
+
+#
# File systems
#
CONFIG_EXT2_FS=y
# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
# CONFIG_EXT3_FS is not set
# CONFIG_JBD 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_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
# CONFIG_QUOTA is not set
CONFIG_DNOTIFY=y
# CONFIG_AUTOFS_FS is not set
# CONFIG_AUTOFS4_FS is not set
+CONFIG_FUSE_FS=y
#
# CD-ROM/DVD Filesystems
@@ -646,13 +754,10 @@ CONFIG_DNOTIFY=y
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
-CONFIG_DEVPTS_FS_XATTR=y
-CONFIG_DEVPTS_FS_SECURITY=y
CONFIG_TMPFS=y
-# CONFIG_TMPFS_XATTR is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
+CONFIG_RELAYFS_FS=y
#
# Miscellaneous filesystems
@@ -676,13 +781,14 @@ CONFIG_RAMFS=y
#
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
# CONFIG_NFS_V4 is not set
# CONFIG_NFS_DIRECTIO is not set
# CONFIG_NFSD is not set
CONFIG_ROOT_NFS=y
CONFIG_LOCKD=y
CONFIG_LOCKD_V4=y
-# CONFIG_EXPORTFS is not set
+CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
@@ -691,6 +797,7 @@ CONFIG_SUNRPC=y
# CONFIG_NCP_FS is not set
# CONFIG_CODA_FS is not set
# CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
#
# Partition Types
@@ -721,7 +828,9 @@ CONFIG_SGI_PARTITION=y
#
# Kernel hacking
#
+# CONFIG_PRINTK_TIME is not set
# CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=14
CONFIG_CROSSCOMPILE=y
CONFIG_CMDLINE=""
@@ -735,7 +844,31 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
#
# Cryptographic options
#
-# CONFIG_CRYPTO is not set
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_NULL=y
+CONFIG_CRYPTO_MD4=y
+CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_SHA1=y
+CONFIG_CRYPTO_SHA256=y
+CONFIG_CRYPTO_SHA512=y
+CONFIG_CRYPTO_WP512=y
+CONFIG_CRYPTO_TGR192=y
+CONFIG_CRYPTO_DES=y
+CONFIG_CRYPTO_BLOWFISH=y
+CONFIG_CRYPTO_TWOFISH=y
+CONFIG_CRYPTO_SERPENT=y
+CONFIG_CRYPTO_AES=y
+CONFIG_CRYPTO_CAST5=y
+CONFIG_CRYPTO_CAST6=y
+CONFIG_CRYPTO_TEA=y
+CONFIG_CRYPTO_ARC4=y
+CONFIG_CRYPTO_KHAZAD=y
+CONFIG_CRYPTO_ANUBIS=y
+CONFIG_CRYPTO_DEFLATE=y
+CONFIG_CRYPTO_MICHAEL_MIC=y
+CONFIG_CRYPTO_CRC32C=y
+# CONFIG_CRYPTO_TEST is not set
#
# Hardware crypto devices
@@ -745,7 +878,8 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
# Library routines
#
# CONFIG_CRC_CCITT is not set
-# CONFIG_CRC32 is not set
-# CONFIG_LIBCRC32C is not set
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_CRC16=y
+CONFIG_CRC32=y
+CONFIG_LIBCRC32C=y
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
diff --git a/arch/mips/configs/it8172_defconfig b/arch/mips/configs/it8172_defconfig
index 08bd3ad64761..0940771bafb1 100644
--- a/arch/mips/configs/it8172_defconfig
+++ b/arch/mips/configs/it8172_defconfig
@@ -1,12 +1,9 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-rc2
-# Wed Jan 26 02:49:05 2005
+# Linux kernel version: 2.6.14-rc2
+# Thu Oct 20 22:26:09 2005
#
CONFIG_MIPS=y
-# CONFIG_64BIT is not set
-# CONFIG_64BIT is not set
-CONFIG_32BIT=y
#
# Code maturity level options
@@ -14,11 +11,13 @@ CONFIG_32BIT=y
CONFIG_EXPERIMENTAL=y
CONFIG_CLEAN_COMPILE=y
CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
#
# General setup
#
CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
# CONFIG_POSIX_MQUEUE is not set
@@ -26,13 +25,16 @@ CONFIG_BSD_PROCESS_ACCT=y
# CONFIG_BSD_PROCESS_ACCT_V3 is not set
CONFIG_SYSCTL=y
# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
# CONFIG_HOTPLUG is not set
CONFIG_KOBJECT_UEVENT=y
# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
CONFIG_EMBEDDED=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
@@ -42,6 +44,7 @@ CONFIG_CC_ALIGN_LABELS=0
CONFIG_CC_ALIGN_LOOPS=0
CONFIG_CC_ALIGN_JUMPS=0
# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
#
# Loadable module support
@@ -57,41 +60,69 @@ CONFIG_KMOD=y
#
# Machine selection
#
-# CONFIG_MACH_JAZZ is not set
-# CONFIG_MACH_VR41XX is not set
-# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_MIPS_PB1550 is not set
+# CONFIG_MIPS_PB1200 is not set
+# CONFIG_MIPS_DB1000 is not set
+# CONFIG_MIPS_DB1100 is not set
+# CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
+# CONFIG_MIPS_DB1200 is not set
+# CONFIG_MIPS_MIRAGE is not set
# CONFIG_MIPS_COBALT is not set
# CONFIG_MACH_DECSTATION is not set
# CONFIG_MIPS_EV64120 is not set
# CONFIG_MIPS_EV96100 is not set
# CONFIG_MIPS_IVR is not set
-# CONFIG_LASAT is not set
CONFIG_MIPS_ITE8172=y
-# CONFIG_IT8172_REVC is not set
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_LASAT is not set
# CONFIG_MIPS_ATLAS is not set
# CONFIG_MIPS_MALTA is not set
# CONFIG_MIPS_SEAD is not set
+# CONFIG_MIPS_SIM is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
# CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_G is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_JAGUAR_ATX is not set
-# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MIPS_XXS1500 is not set
+# CONFIG_PNX8550_V2PCI is not set
+# CONFIG_PNX8550_JBS is not set
# CONFIG_DDB5074 is not set
# CONFIG_DDB5476 is not set
# CONFIG_DDB5477 is not set
-# CONFIG_NEC_OSPREY is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_QEMU is not set
# CONFIG_SGI_IP22 is not set
-# CONFIG_SOC_AU1X00 is not set
-# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_BIGSUR is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_PTSWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CRHONE is not set
# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
# CONFIG_TOSHIBA_RBTX4927 is not set
+# CONFIG_TOSHIBA_RBTX4938 is not set
+# CONFIG_IT8172_REVC is not set
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_HAVE_DEC_LOCK=y
CONFIG_DMA_NONCOHERENT=y
CONFIG_DMA_NEED_PCI_MAP_STATE=y
+# CONFIG_CPU_BIG_ENDIAN is not set
CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
CONFIG_ITE_BOARD_GEN=y
CONFIG_IT8172_CIR=y
CONFIG_IT8712=y
@@ -100,8 +131,10 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5
#
# CPU selection
#
-# CONFIG_CPU_MIPS32 is not set
-# CONFIG_CPU_MIPS64 is not set
+# CONFIG_CPU_MIPS32_R1 is not set
+# CONFIG_CPU_MIPS32_R2 is not set
+# CONFIG_CPU_MIPS64_R1 is not set
+# CONFIG_CPU_MIPS64_R2 is not set
# CONFIG_CPU_R3000 is not set
# CONFIG_CPU_TX39XX is not set
# CONFIG_CPU_VR41XX is not set
@@ -117,14 +150,39 @@ CONFIG_CPU_NEVADA=y
# CONFIG_CPU_RM7000 is not set
# CONFIG_CPU_RM9000 is not set
# CONFIG_CPU_SB1 is not set
+CONFIG_SYS_HAS_CPU_R5432=y
+CONFIG_SYS_HAS_CPU_NEVADA=y
+CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
+CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y
+
+#
+# Kernel type
+#
+CONFIG_32BIT=y
+# CONFIG_64BIT is not set
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_MIPS_MT is not set
# CONFIG_CPU_ADVANCED is not set
CONFIG_CPU_HAS_LLSC=y
CONFIG_CPU_HAS_LLDSCD=y
CONFIG_CPU_HAS_SYNC=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_ARCH_FLATMEM_ENABLE=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_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
#
@@ -140,10 +198,6 @@ CONFIG_MMU=y
# CONFIG_PCCARD is not set
#
-# PC-card bridges
-#
-
-#
# PCI Hotplug Support
#
@@ -155,6 +209,80 @@ CONFIG_BINFMT_ELF=y
CONFIG_TRAD_SIGNALS=y
#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+CONFIG_NET_KEY=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+CONFIG_INET_TUNNEL=m
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+# CONFIG_IPV6 is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# 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_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_IEEE80211=m
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=m
+CONFIG_IEEE80211_CRYPT_CCMP=m
+CONFIG_IEEE80211_CRYPT_TKIP=m
+
+#
# Device Drivers
#
@@ -166,12 +294,17 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_FW_LOADER is not set
#
+# Connector - unified userspace <-> kernelspace linker
+#
+CONFIG_CONNECTOR=m
+
+#
# Memory Technology Devices (MTD)
#
CONFIG_MTD=y
# CONFIG_MTD_DEBUG is not set
-# CONFIG_MTD_PARTITIONS is not set
# CONFIG_MTD_CONCAT is not set
+# CONFIG_MTD_PARTITIONS is not set
#
# User Modules And Translation Layers
@@ -207,7 +340,6 @@ 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
@@ -217,6 +349,7 @@ CONFIG_MTD_PHYSMAP=y
CONFIG_MTD_PHYSMAP_START=0x8000000
CONFIG_MTD_PHYSMAP_LEN=0x2000000
CONFIG_MTD_PHYSMAP_BANKWIDTH=2
+# CONFIG_MTD_PLATRAM is not set
#
# Self-contained MTD device drivers
@@ -251,14 +384,12 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=2
#
# Block devices
#
-# CONFIG_BLK_DEV_FD is not set
# CONFIG_BLK_DEV_COW_COMMON is not set
CONFIG_BLK_DEV_LOOP=y
# CONFIG_BLK_DEV_CRYPTOLOOP is not set
# CONFIG_BLK_DEV_NBD is not set
# CONFIG_BLK_DEV_RAM is not set
CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_INITRAMFS_SOURCE=""
# CONFIG_LBD is not set
CONFIG_CDROM_PKTCDVD=m
CONFIG_CDROM_PKTCDVD_BUFFERS=8
@@ -302,6 +433,7 @@ CONFIG_IDE_GENERIC=y
#
# SCSI device support
#
+CONFIG_RAID_ATTRS=m
# CONFIG_SCSI is not set
#
@@ -312,6 +444,7 @@ CONFIG_IDE_GENERIC=y
#
# Fusion MPT device support
#
+# CONFIG_FUSION is not set
#
# IEEE 1394 (FireWire) support
@@ -322,78 +455,28 @@ CONFIG_IDE_GENERIC=y
#
#
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
+# Network device support
#
-CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
-CONFIG_NETLINK_DEV=y
-CONFIG_UNIX=y
-CONFIG_NET_KEY=y
-CONFIG_INET=y
-# CONFIG_IP_MULTICAST is not set
-# CONFIG_IP_ADVANCED_ROUTER is not set
-CONFIG_IP_PNP=y
-# CONFIG_IP_PNP_DHCP is not set
-CONFIG_IP_PNP_BOOTP=y
-# CONFIG_IP_PNP_RARP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_ARPD is not set
-# CONFIG_SYN_COOKIES is not set
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-CONFIG_INET_TUNNEL=m
-CONFIG_IP_TCPDIAG=m
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-# CONFIG_IPV6 is not set
-# CONFIG_NETFILTER is not set
-CONFIG_XFRM=y
-CONFIG_XFRM_USER=m
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
#
-# SCTP Configuration (EXPERIMENTAL)
+# PHY device support
#
-# CONFIG_IP_SCTP 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_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
+CONFIG_PHYLIB=m
+CONFIG_PHYCONTROL=y
#
-# QoS and/or fair queueing
+# MII PHY device drivers
#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
-CONFIG_NETDEVICES=y
-# CONFIG_DUMMY is not set
-# CONFIG_BONDING is not set
-# CONFIG_EQUALIZER is not set
-# CONFIG_TUN is not set
-# CONFIG_ETHERTAP is not set
+CONFIG_MARVELL_PHY=m
+CONFIG_DAVICOM_PHY=m
+CONFIG_QSEMI_PHY=m
+CONFIG_LXT_PHY=m
+CONFIG_CICADA_PHY=m
#
# Ethernet (10 or 100Mbit)
@@ -426,6 +509,8 @@ CONFIG_NET_ETHERNET=y
# CONFIG_SLIP is not set
# CONFIG_SHAPER is not set
# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
#
# ISDN subsystem
@@ -455,18 +540,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
# CONFIG_INPUT_EVBUG is not set
#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=y
-# CONFIG_SERIO_I8042 is not set
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_LIBPS2 is not set
-CONFIG_SERIO_RAW=m
-
-#
# Input Device Drivers
#
# CONFIG_INPUT_KEYBOARD is not set
@@ -476,6 +549,16 @@ CONFIG_SERIO_RAW=m
# CONFIG_INPUT_MISC is not set
#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_LIBPS2 is not set
+CONFIG_SERIO_RAW=m
+# CONFIG_GAMEPORT is not set
+
+#
# Character devices
#
CONFIG_VT=y
@@ -521,10 +604,13 @@ CONFIG_LEGACY_PTY_COUNT=256
#
# Ftape, the floppy tape device driver
#
-# CONFIG_DRM is not set
# CONFIG_RAW_DRIVER is not set
#
+# TPM devices
+#
+
+#
# I2C support
#
# CONFIG_I2C is not set
@@ -535,10 +621,20 @@ CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_W1 is not set
#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
+#
# Misc devices
#
#
+# Multimedia Capabilities Port drivers
+#
+
+#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
@@ -558,7 +654,6 @@ CONFIG_LEGACY_PTY_COUNT=256
#
# CONFIG_VGA_CONSOLE is not set
CONFIG_DUMMY_CONSOLE=y
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Sound
@@ -574,15 +669,9 @@ CONFIG_SOUND=y
# Open Sound System
#
CONFIG_SOUND_PRIME=y
-# CONFIG_SOUND_BT878 is not set
-# CONFIG_SOUND_FUSION is not set
-# CONFIG_SOUND_CS4281 is not set
-# CONFIG_SOUND_SONICVIBES is not set
CONFIG_SOUND_IT8172=y
-# CONFIG_SOUND_TRIDENT is not set
# CONFIG_SOUND_MSNDCLAS is not set
# CONFIG_SOUND_MSNDPIN is not set
-# CONFIG_SOUND_OSS is not set
# CONFIG_SOUND_AD1980 is not set
#
@@ -592,10 +681,6 @@ CONFIG_SOUND_IT8172=y
# CONFIG_USB_ARCH_HAS_OHCI is not set
#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
-#
-
-#
# USB Gadget Support
#
# CONFIG_USB_GADGET is not set
@@ -608,24 +693,31 @@ CONFIG_SOUND_IT8172=y
#
# InfiniBand support
#
-# CONFIG_INFINIBAND is not set
+
+#
+# SN Devices
+#
#
# File systems
#
CONFIG_EXT2_FS=y
# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
# CONFIG_EXT3_FS is not set
# CONFIG_JBD 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_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
# CONFIG_QUOTA is not set
CONFIG_DNOTIFY=y
# CONFIG_AUTOFS_FS is not set
# CONFIG_AUTOFS4_FS is not set
+CONFIG_FUSE_FS=m
#
# CD-ROM/DVD Filesystems
@@ -646,12 +738,10 @@ CONFIG_DNOTIFY=y
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
-CONFIG_DEVPTS_FS_XATTR=y
-CONFIG_DEVPTS_FS_SECURITY=y
# CONFIG_TMPFS is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
+CONFIG_RELAYFS_FS=m
#
# Miscellaneous filesystems
@@ -682,7 +772,7 @@ CONFIG_NFS_FS=y
# CONFIG_NFSD is not set
CONFIG_ROOT_NFS=y
CONFIG_LOCKD=y
-# CONFIG_EXPORTFS is not set
+CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
@@ -691,6 +781,7 @@ CONFIG_SUNRPC=y
# CONFIG_NCP_FS is not set
# CONFIG_CODA_FS is not set
# CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
#
# Partition Types
@@ -711,7 +802,9 @@ CONFIG_MSDOS_PARTITION=y
#
# Kernel hacking
#
+# CONFIG_PRINTK_TIME is not set
# CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=14
CONFIG_CROSSCOMPILE=y
CONFIG_CMDLINE=""
@@ -725,7 +818,31 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
#
# Cryptographic options
#
-# CONFIG_CRYPTO is not set
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_AES=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_CRC32C=m
+# CONFIG_CRYPTO_TEST is not set
#
# Hardware crypto devices
@@ -735,7 +852,8 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
# Library routines
#
# CONFIG_CRC_CCITT is not set
-# CONFIG_CRC32 is not set
+CONFIG_CRC16=m
+CONFIG_CRC32=m
CONFIG_LIBCRC32C=m
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_ZLIB_INFLATE=m
+CONFIG_ZLIB_DEFLATE=m
diff --git a/arch/mips/configs/ivr_defconfig b/arch/mips/configs/ivr_defconfig
index 583ef5c5b1cd..9ba61dfc490d 100644
--- a/arch/mips/configs/ivr_defconfig
+++ b/arch/mips/configs/ivr_defconfig
@@ -1,12 +1,9 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-rc2
-# Wed Jan 26 02:49:05 2005
+# Linux kernel version: 2.6.14-rc2
+# Thu Oct 20 22:26:12 2005
#
CONFIG_MIPS=y
-# CONFIG_64BIT is not set
-# CONFIG_64BIT is not set
-CONFIG_32BIT=y
#
# Code maturity level options
@@ -14,11 +11,13 @@ CONFIG_32BIT=y
CONFIG_EXPERIMENTAL=y
CONFIG_CLEAN_COMPILE=y
CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
#
# General setup
#
CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
# CONFIG_POSIX_MQUEUE is not set
@@ -26,13 +25,16 @@ CONFIG_BSD_PROCESS_ACCT=y
# CONFIG_BSD_PROCESS_ACCT_V3 is not set
CONFIG_SYSCTL=y
# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_HOTPLUG is not set
+CONFIG_HOTPLUG=y
CONFIG_KOBJECT_UEVENT=y
# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
CONFIG_EMBEDDED=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
@@ -42,6 +44,7 @@ CONFIG_CC_ALIGN_LABELS=0
CONFIG_CC_ALIGN_LOOPS=0
CONFIG_CC_ALIGN_JUMPS=0
# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
#
# Loadable module support
@@ -57,40 +60,68 @@ CONFIG_KMOD=y
#
# Machine selection
#
-# CONFIG_MACH_JAZZ is not set
-# CONFIG_MACH_VR41XX is not set
-# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_MIPS_PB1550 is not set
+# CONFIG_MIPS_PB1200 is not set
+# CONFIG_MIPS_DB1000 is not set
+# CONFIG_MIPS_DB1100 is not set
+# CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
+# CONFIG_MIPS_DB1200 is not set
+# CONFIG_MIPS_MIRAGE is not set
# CONFIG_MIPS_COBALT is not set
# CONFIG_MACH_DECSTATION is not set
# CONFIG_MIPS_EV64120 is not set
# CONFIG_MIPS_EV96100 is not set
CONFIG_MIPS_IVR=y
-# CONFIG_LASAT is not set
# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_LASAT is not set
# CONFIG_MIPS_ATLAS is not set
# CONFIG_MIPS_MALTA is not set
# CONFIG_MIPS_SEAD is not set
+# CONFIG_MIPS_SIM is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
# CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_G is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_JAGUAR_ATX is not set
-# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MIPS_XXS1500 is not set
+# CONFIG_PNX8550_V2PCI is not set
+# CONFIG_PNX8550_JBS is not set
# CONFIG_DDB5074 is not set
# CONFIG_DDB5476 is not set
# CONFIG_DDB5477 is not set
-# CONFIG_NEC_OSPREY is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_QEMU is not set
# CONFIG_SGI_IP22 is not set
-# CONFIG_SOC_AU1X00 is not set
-# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_BIGSUR is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_PTSWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CRHONE is not set
# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
# CONFIG_TOSHIBA_RBTX4927 is not set
+# CONFIG_TOSHIBA_RBTX4938 is not set
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_HAVE_DEC_LOCK=y
CONFIG_DMA_NONCOHERENT=y
CONFIG_DMA_NEED_PCI_MAP_STATE=y
+# CONFIG_CPU_BIG_ENDIAN is not set
CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
CONFIG_ITE_BOARD_GEN=y
CONFIG_IT8172_CIR=y
CONFIG_MIPS_L1_CACHE_SHIFT=5
@@ -98,8 +129,10 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5
#
# CPU selection
#
-# CONFIG_CPU_MIPS32 is not set
-# CONFIG_CPU_MIPS64 is not set
+# CONFIG_CPU_MIPS32_R1 is not set
+# CONFIG_CPU_MIPS32_R2 is not set
+# CONFIG_CPU_MIPS64_R1 is not set
+# CONFIG_CPU_MIPS64_R2 is not set
# CONFIG_CPU_R3000 is not set
# CONFIG_CPU_TX39XX is not set
# CONFIG_CPU_VR41XX is not set
@@ -115,14 +148,38 @@ CONFIG_CPU_NEVADA=y
# CONFIG_CPU_RM7000 is not set
# CONFIG_CPU_RM9000 is not set
# CONFIG_CPU_SB1 is not set
+CONFIG_SYS_HAS_CPU_NEVADA=y
+CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
+CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y
+
+#
+# Kernel type
+#
+CONFIG_32BIT=y
+# CONFIG_64BIT is not set
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_MIPS_MT is not set
# CONFIG_CPU_ADVANCED is not set
CONFIG_CPU_HAS_LLSC=y
CONFIG_CPU_HAS_LLDSCD=y
CONFIG_CPU_HAS_SYNC=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_ARCH_FLATMEM_ENABLE=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_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
#
@@ -131,7 +188,6 @@ CONFIG_CPU_HAS_SYNC=y
CONFIG_HW_HAS_PCI=y
CONFIG_PCI=y
CONFIG_PCI_LEGACY_PROC=y
-CONFIG_PCI_NAMES=y
CONFIG_MMU=y
#
@@ -140,10 +196,6 @@ CONFIG_MMU=y
# CONFIG_PCCARD is not set
#
-# PC-card bridges
-#
-
-#
# PCI Hotplug Support
#
# CONFIG_HOTPLUG_PCI is not set
@@ -156,6 +208,80 @@ CONFIG_BINFMT_ELF=y
CONFIG_TRAD_SIGNALS=y
#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+CONFIG_NET_KEY=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+CONFIG_INET_TUNNEL=m
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+# CONFIG_IPV6 is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# 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_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_IEEE80211=m
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=m
+CONFIG_IEEE80211_CRYPT_CCMP=m
+CONFIG_IEEE80211_CRYPT_TKIP=m
+
+#
# Device Drivers
#
@@ -164,7 +290,12 @@ CONFIG_TRAD_SIGNALS=y
#
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
+CONFIG_FW_LOADER=m
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+CONFIG_CONNECTOR=m
#
# Memory Technology Devices (MTD)
@@ -183,7 +314,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
#
# Block devices
#
-# CONFIG_BLK_DEV_FD is not set
# CONFIG_BLK_CPQ_DA is not set
# CONFIG_BLK_CPQ_CISS_DA is not set
# CONFIG_BLK_DEV_DAC960 is not set
@@ -194,7 +324,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_BLK_DEV_SX8 is not set
# CONFIG_BLK_DEV_RAM is not set
CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_INITRAMFS_SOURCE=""
# CONFIG_LBD is not set
CONFIG_CDROM_PKTCDVD=m
CONFIG_CDROM_PKTCDVD_BUFFERS=8
@@ -239,6 +368,7 @@ CONFIG_IDE_GENERIC=y
#
# SCSI device support
#
+CONFIG_RAID_ATTRS=m
# CONFIG_SCSI is not set
#
@@ -249,6 +379,7 @@ CONFIG_IDE_GENERIC=y
#
# Fusion MPT device support
#
+# CONFIG_FUSION is not set
#
# IEEE 1394 (FireWire) support
@@ -261,78 +392,13 @@ CONFIG_IDE_GENERIC=y
# CONFIG_I2O is not set
#
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
-CONFIG_NETLINK_DEV=y
-CONFIG_UNIX=y
-CONFIG_NET_KEY=y
-CONFIG_INET=y
-# CONFIG_IP_MULTICAST is not set
-# CONFIG_IP_ADVANCED_ROUTER is not set
-CONFIG_IP_PNP=y
-# CONFIG_IP_PNP_DHCP is not set
-CONFIG_IP_PNP_BOOTP=y
-# CONFIG_IP_PNP_RARP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_ARPD is not set
-# CONFIG_SYN_COOKIES is not set
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-CONFIG_INET_TUNNEL=m
-CONFIG_IP_TCPDIAG=m
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-# CONFIG_IPV6 is not set
-# CONFIG_NETFILTER is not set
-CONFIG_XFRM=y
-CONFIG_XFRM_USER=m
-
-#
-# SCTP Configuration (EXPERIMENTAL)
+# Network device support
#
-# CONFIG_IP_SCTP 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_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
CONFIG_NETDEVICES=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_EQUALIZER is not set
# CONFIG_TUN is not set
-# CONFIG_ETHERTAP is not set
#
# ARCnet devices
@@ -340,6 +406,21 @@ CONFIG_NETDEVICES=y
# CONFIG_ARCNET is not set
#
+# PHY device support
+#
+CONFIG_PHYLIB=m
+CONFIG_PHYCONTROL=y
+
+#
+# MII PHY device drivers
+#
+CONFIG_MARVELL_PHY=m
+CONFIG_DAVICOM_PHY=m
+CONFIG_QSEMI_PHY=m
+CONFIG_LXT_PHY=m
+CONFIG_CICADA_PHY=m
+
+#
# Ethernet (10 or 100Mbit)
#
CONFIG_NET_ETHERNET=y
@@ -365,12 +446,16 @@ CONFIG_NET_ETHERNET=y
# CONFIG_HAMACHI is not set
# CONFIG_YELLOWFIN is not set
# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
# CONFIG_SK98LIN is not set
# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
#
# Ethernet (10000 Mbit)
#
+# CONFIG_CHELSIO_T1 is not set
# CONFIG_IXGB is not set
# CONFIG_S2IO is not set
@@ -383,6 +468,8 @@ CONFIG_NET_ETHERNET=y
# Wireless LAN (non-hamradio)
#
# CONFIG_NET_RADIO is not set
+# CONFIG_IPW_DEBUG is not set
+CONFIG_IPW2200=m
#
# Wan interfaces
@@ -394,6 +481,8 @@ CONFIG_NET_ETHERNET=y
# CONFIG_SLIP is not set
# CONFIG_SHAPER is not set
# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
#
# ISDN subsystem
@@ -423,19 +512,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
# CONFIG_INPUT_EVBUG is not set
#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=y
-# CONFIG_SERIO_I8042 is not set
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_PCIPS2 is not set
-# CONFIG_SERIO_LIBPS2 is not set
-CONFIG_SERIO_RAW=m
-
-#
# Input Device Drivers
#
# CONFIG_INPUT_KEYBOARD is not set
@@ -445,6 +521,17 @@ CONFIG_SERIO_RAW=m
# CONFIG_INPUT_MISC is not set
#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_PCIPS2 is not set
+# CONFIG_SERIO_LIBPS2 is not set
+CONFIG_SERIO_RAW=m
+# CONFIG_GAMEPORT is not set
+
+#
# Character devices
#
CONFIG_VT=y
@@ -467,6 +554,7 @@ CONFIG_SERIAL_8250_NR_UARTS=4
#
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
CONFIG_UNIX98_PTYS=y
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
@@ -492,6 +580,11 @@ CONFIG_RTC=y
# CONFIG_RAW_DRIVER is not set
#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+
+#
# I2C support
#
# CONFIG_I2C is not set
@@ -502,10 +595,20 @@ CONFIG_RTC=y
# CONFIG_W1 is not set
#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
+#
# Misc devices
#
#
+# Multimedia Capabilities Port drivers
+#
+
+#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
@@ -525,7 +628,6 @@ CONFIG_RTC=y
#
# CONFIG_VGA_CONSOLE is not set
CONFIG_DUMMY_CONSOLE=y
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Sound
@@ -535,13 +637,9 @@ CONFIG_DUMMY_CONSOLE=y
#
# USB support
#
-# CONFIG_USB is not set
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB_ARCH_HAS_OHCI=y
-
-#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
-#
+# CONFIG_USB is not set
#
# USB Gadget Support
@@ -559,21 +657,29 @@ CONFIG_USB_ARCH_HAS_OHCI=y
# CONFIG_INFINIBAND is not set
#
+# SN Devices
+#
+
+#
# File systems
#
CONFIG_EXT2_FS=y
# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
# CONFIG_EXT3_FS is not set
# CONFIG_JBD 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_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
# CONFIG_QUOTA is not set
CONFIG_DNOTIFY=y
# CONFIG_AUTOFS_FS is not set
# CONFIG_AUTOFS4_FS is not set
+CONFIG_FUSE_FS=m
#
# CD-ROM/DVD Filesystems
@@ -594,12 +700,10 @@ CONFIG_DNOTIFY=y
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
-CONFIG_DEVPTS_FS_XATTR=y
-CONFIG_DEVPTS_FS_SECURITY=y
# CONFIG_TMPFS is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
+CONFIG_RELAYFS_FS=m
#
# Miscellaneous filesystems
@@ -628,7 +732,7 @@ CONFIG_NFS_FS=y
# CONFIG_NFSD is not set
CONFIG_ROOT_NFS=y
CONFIG_LOCKD=y
-# CONFIG_EXPORTFS is not set
+CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
@@ -637,6 +741,7 @@ CONFIG_SUNRPC=y
# CONFIG_NCP_FS is not set
# CONFIG_CODA_FS is not set
# CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
#
# Partition Types
@@ -657,7 +762,9 @@ CONFIG_MSDOS_PARTITION=y
#
# Kernel hacking
#
+# CONFIG_PRINTK_TIME is not set
# CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=14
CONFIG_CROSSCOMPILE=y
CONFIG_CMDLINE=""
@@ -671,7 +778,31 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
#
# Cryptographic options
#
-# CONFIG_CRYPTO is not set
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_AES=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_CRC32C=m
+# CONFIG_CRYPTO_TEST is not set
#
# Hardware crypto devices
@@ -681,7 +812,8 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
# Library routines
#
# CONFIG_CRC_CCITT is not set
-# CONFIG_CRC32 is not set
+CONFIG_CRC16=m
+CONFIG_CRC32=m
CONFIG_LIBCRC32C=m
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_ZLIB_INFLATE=m
+CONFIG_ZLIB_DEFLATE=m
diff --git a/arch/mips/configs/jaguar-atx_defconfig b/arch/mips/configs/jaguar-atx_defconfig
index 8abb5a0c6c12..21b2b8042f91 100644
--- a/arch/mips/configs/jaguar-atx_defconfig
+++ b/arch/mips/configs/jaguar-atx_defconfig
@@ -1,12 +1,9 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-rc2
-# Wed Jan 26 02:49:05 2005
+# Linux kernel version: 2.6.14-rc2
+# Thu Oct 20 22:26:14 2005
#
CONFIG_MIPS=y
-# CONFIG_64BIT is not set
-# CONFIG_64BIT is not set
-CONFIG_32BIT=y
#
# Code maturity level options
@@ -14,24 +11,29 @@ CONFIG_32BIT=y
# CONFIG_EXPERIMENTAL is not set
CONFIG_CLEAN_COMPILE=y
CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
#
# General setup
#
CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_HOTPLUG is not set
+CONFIG_HOTPLUG=y
CONFIG_KOBJECT_UEVENT=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
+CONFIG_INITRAMFS_SOURCE=""
CONFIG_EMBEDDED=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
@@ -41,6 +43,7 @@ CONFIG_CC_ALIGN_LABELS=0
CONFIG_CC_ALIGN_LOOPS=0
CONFIG_CC_ALIGN_JUMPS=0
# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
#
# Loadable module support
@@ -54,36 +57,70 @@ CONFIG_KMOD=y
#
# Machine selection
#
-# CONFIG_MACH_JAZZ is not set
-# CONFIG_MACH_VR41XX is not set
-# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_MIPS_PB1550 is not set
+# CONFIG_MIPS_PB1200 is not set
+# CONFIG_MIPS_DB1000 is not set
+# CONFIG_MIPS_DB1100 is not set
+# CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
+# CONFIG_MIPS_DB1200 is not set
+# CONFIG_MIPS_MIRAGE is not set
+# CONFIG_MIPS_COBALT is not set
# CONFIG_MACH_DECSTATION is not set
+# CONFIG_MIPS_EV64120 is not set
+# CONFIG_MIPS_EV96100 is not set
# CONFIG_MIPS_IVR is not set
-# CONFIG_LASAT is not set
# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_LASAT is not set
# CONFIG_MIPS_ATLAS is not set
# CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SEAD is not set
+# CONFIG_MIPS_SIM is not set
+CONFIG_MOMENCO_JAGUAR_ATX=y
# CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_G is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
# CONFIG_MOMENCO_OCELOT_3 is not set
-CONFIG_MOMENCO_JAGUAR_ATX=y
-CONFIG_JAGUAR_DMALOW=y
-# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MIPS_XXS1500 is not set
+# CONFIG_PNX8550_V2PCI is not set
+# CONFIG_PNX8550_JBS is not set
+# CONFIG_DDB5074 is not set
# CONFIG_DDB5476 is not set
# CONFIG_DDB5477 is not set
-# CONFIG_NEC_OSPREY is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_QEMU is not set
# CONFIG_SGI_IP22 is not set
-# CONFIG_SOC_AU1X00 is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_BIGSUR is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_PTSWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CRHONE is not set
# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
# CONFIG_TOSHIBA_RBTX4927 is not set
+# CONFIG_TOSHIBA_RBTX4938 is not set
+CONFIG_JAGUAR_DMALOW=y
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_HAVE_DEC_LOCK=y
CONFIG_DMA_NONCOHERENT=y
CONFIG_DMA_NEED_PCI_MAP_STATE=y
CONFIG_LIMITED_DMA=y
+CONFIG_CPU_BIG_ENDIAN=y
# CONFIG_CPU_LITTLE_ENDIAN is not set
+CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
CONFIG_IRQ_CPU=y
CONFIG_IRQ_CPU_RM7K=y
CONFIG_IRQ_MV64340=y
@@ -95,8 +132,10 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5
#
# CPU selection
#
-# CONFIG_CPU_MIPS32 is not set
-# CONFIG_CPU_MIPS64 is not set
+# CONFIG_CPU_MIPS32_R1 is not set
+# CONFIG_CPU_MIPS32_R2 is not set
+# CONFIG_CPU_MIPS64_R1 is not set
+# CONFIG_CPU_MIPS64_R2 is not set
# CONFIG_CPU_R3000 is not set
# CONFIG_CPU_TX39XX is not set
# CONFIG_CPU_VR41XX is not set
@@ -112,6 +151,17 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5
# CONFIG_CPU_RM7000 is not set
CONFIG_CPU_RM9000=y
# CONFIG_CPU_SB1 is not set
+CONFIG_SYS_HAS_CPU_RM9000=y
+CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
+CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y
+
+#
+# Kernel type
+#
+CONFIG_32BIT=y
+# CONFIG_64BIT is not set
CONFIG_PAGE_SIZE_4KB=y
# CONFIG_PAGE_SIZE_8KB is not set
# CONFIG_PAGE_SIZE_16KB is not set
@@ -119,13 +169,24 @@ CONFIG_PAGE_SIZE_4KB=y
CONFIG_BOARD_SCACHE=y
CONFIG_RM7000_CPU_SCACHE=y
CONFIG_CPU_HAS_PREFETCH=y
+# CONFIG_MIPS_MT is not set
# CONFIG_64BIT_PHYS_ADDR is not set
# CONFIG_CPU_ADVANCED is not set
CONFIG_CPU_HAS_LLSC=y
CONFIG_CPU_HAS_LLDSCD=y
CONFIG_CPU_HAS_SYNC=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_HIGHMEM=y
+CONFIG_CPU_SUPPORTS_HIGHMEM=y
+CONFIG_SYS_SUPPORTS_HIGHMEM=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
# CONFIG_SMP is not set
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
#
@@ -134,7 +195,6 @@ CONFIG_HIGHMEM=y
CONFIG_HW_HAS_PCI=y
CONFIG_PCI=y
CONFIG_PCI_LEGACY_PROC=y
-CONFIG_PCI_NAMES=y
CONFIG_MMU=y
#
@@ -143,10 +203,6 @@ CONFIG_MMU=y
# CONFIG_PCCARD is not set
#
-# PC-card bridges
-#
-
-#
# PCI Hotplug Support
#
@@ -158,6 +214,68 @@ CONFIG_BINFMT_ELF=y
CONFIG_TRAD_SIGNALS=y
#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_PACKET is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE 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_TUNNEL=m
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+CONFIG_IPV6=m
+CONFIG_IPV6_PRIVACY=y
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+CONFIG_INET6_TUNNEL=m
+CONFIG_IPV6_TUNNEL=m
+# CONFIG_NETFILTER 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_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_IEEE80211=m
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=m
+CONFIG_IEEE80211_CRYPT_CCMP=m
+CONFIG_IEEE80211_CRYPT_TKIP=m
+
+#
# Device Drivers
#
@@ -166,7 +284,12 @@ CONFIG_TRAD_SIGNALS=y
#
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
+CONFIG_FW_LOADER=m
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+CONFIG_CONNECTOR=m
#
# Memory Technology Devices (MTD)
@@ -185,7 +308,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
#
# Block devices
#
-# CONFIG_BLK_DEV_FD is not set
# CONFIG_BLK_CPQ_DA is not set
# CONFIG_BLK_CPQ_CISS_DA is not set
# CONFIG_BLK_DEV_DAC960 is not set
@@ -195,7 +317,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_BLK_DEV_SX8 is not set
# CONFIG_BLK_DEV_RAM is not set
CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_INITRAMFS_SOURCE=""
# CONFIG_LBD is not set
CONFIG_CDROM_PKTCDVD=m
CONFIG_CDROM_PKTCDVD_BUFFERS=8
@@ -218,6 +339,7 @@ CONFIG_ATA_OVER_ETH=m
#
# SCSI device support
#
+CONFIG_RAID_ATTRS=m
# CONFIG_SCSI is not set
#
@@ -228,6 +350,7 @@ CONFIG_ATA_OVER_ETH=m
#
# Fusion MPT device support
#
+# CONFIG_FUSION is not set
#
# IEEE 1394 (FireWire) support
@@ -240,58 +363,8 @@ CONFIG_ATA_OVER_ETH=m
# CONFIG_I2O is not set
#
-# Networking support
+# Network device support
#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-# CONFIG_PACKET is not set
-# CONFIG_NETLINK_DEV 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_PNP=y
-# CONFIG_IP_PNP_DHCP is not set
-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_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_TUNNEL=m
-CONFIG_IP_TCPDIAG=m
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-# CONFIG_NETFILTER is not set
-CONFIG_XFRM=y
-CONFIG_XFRM_USER=m
-# 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
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
CONFIG_NETDEVICES=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
@@ -304,6 +377,21 @@ CONFIG_NETDEVICES=y
# CONFIG_ARCNET is not set
#
+# PHY device support
+#
+CONFIG_PHYLIB=m
+CONFIG_PHYCONTROL=y
+
+#
+# MII PHY device drivers
+#
+CONFIG_MARVELL_PHY=m
+CONFIG_DAVICOM_PHY=m
+CONFIG_QSEMI_PHY=m
+CONFIG_LXT_PHY=m
+CONFIG_CICADA_PHY=m
+
+#
# Ethernet (10 or 100Mbit)
#
CONFIG_NET_ETHERNET=y
@@ -343,9 +431,11 @@ CONFIG_EEPRO100=y
# CONFIG_NS83820 is not set
# CONFIG_HAMACHI is not set
# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
# CONFIG_SK98LIN is not set
# CONFIG_VIA_VELOCITY is not set
# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
CONFIG_MV643XX_ETH=y
CONFIG_MV643XX_ETH_0=y
CONFIG_MV643XX_ETH_1=y
@@ -354,6 +444,7 @@ CONFIG_MV643XX_ETH_2=y
#
# Ethernet (10000 Mbit)
#
+# CONFIG_CHELSIO_T1 is not set
# CONFIG_IXGB is not set
# CONFIG_S2IO is not set
@@ -366,6 +457,8 @@ CONFIG_MV643XX_ETH_2=y
# Wireless LAN (non-hamradio)
#
# CONFIG_NET_RADIO is not set
+# CONFIG_IPW_DEBUG is not set
+CONFIG_IPW2200=m
#
# Wan interfaces
@@ -374,6 +467,8 @@ CONFIG_MV643XX_ETH_2=y
# CONFIG_FDDI is not set
# CONFIG_PPP is not set
# CONFIG_SLIP is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
#
# ISDN subsystem
@@ -391,20 +486,10 @@ CONFIG_MV643XX_ETH_2=y
# CONFIG_INPUT is not set
#
-# Userland interfaces
-#
-
-#
-# Input I/O drivers
+# Hardware I/O ports
#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
# CONFIG_SERIO is not set
-# CONFIG_SERIO_I8042 is not set
-
-#
-# Input Device Drivers
-#
+# CONFIG_GAMEPORT is not set
#
# Character devices
@@ -425,6 +510,7 @@ CONFIG_SERIAL_8250_NR_UARTS=4
#
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
CONFIG_UNIX98_PTYS=y
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
@@ -451,6 +537,10 @@ CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_RAW_DRIVER is not set
#
+# TPM devices
+#
+
+#
# I2C support
#
# CONFIG_I2C is not set
@@ -461,10 +551,20 @@ CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_W1 is not set
#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
+#
# Misc devices
#
#
+# Multimedia Capabilities Port drivers
+#
+
+#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
@@ -478,7 +578,6 @@ CONFIG_LEGACY_PTY_COUNT=256
# Graphics support
#
# CONFIG_FB is not set
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Sound
@@ -488,13 +587,9 @@ CONFIG_LEGACY_PTY_COUNT=256
#
# USB support
#
-# CONFIG_USB is not set
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB_ARCH_HAS_OHCI=y
-
-#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
-#
+# CONFIG_USB is not set
#
# USB Gadget Support
@@ -512,6 +607,10 @@ CONFIG_USB_ARCH_HAS_OHCI=y
# CONFIG_INFINIBAND is not set
#
+# SN Devices
+#
+
+#
# File systems
#
# CONFIG_EXT2_FS is not set
@@ -519,13 +618,16 @@ CONFIG_USB_ARCH_HAS_OHCI=y
# CONFIG_JBD 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_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
# CONFIG_QUOTA is not set
CONFIG_DNOTIFY=y
# CONFIG_AUTOFS_FS is not set
# CONFIG_AUTOFS4_FS is not set
+CONFIG_FUSE_FS=m
#
# CD-ROM/DVD Filesystems
@@ -546,10 +648,10 @@ CONFIG_DNOTIFY=y
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_SYSFS=y
-# CONFIG_DEVPTS_FS_XATTR is not set
# CONFIG_TMPFS is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
+CONFIG_RELAYFS_FS=m
#
# Miscellaneous filesystems
@@ -570,7 +672,7 @@ CONFIG_NFS_FS=y
# CONFIG_NFSD is not set
CONFIG_ROOT_NFS=y
CONFIG_LOCKD=y
-# CONFIG_EXPORTFS is not set
+CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
# CONFIG_SMB_FS is not set
# CONFIG_CIFS is not set
@@ -591,7 +693,9 @@ CONFIG_MSDOS_PARTITION=y
#
# Kernel hacking
#
+# CONFIG_PRINTK_TIME is not set
# CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=14
CONFIG_CROSSCOMPILE=y
CONFIG_CMDLINE=""
@@ -605,7 +709,31 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
#
# Cryptographic options
#
-# CONFIG_CRYPTO is not set
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_AES=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_CRC32C=m
+# CONFIG_CRYPTO_TEST is not set
#
# Hardware crypto devices
@@ -615,7 +743,8 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
# Library routines
#
# CONFIG_CRC_CCITT is not set
-# CONFIG_CRC32 is not set
-# CONFIG_LIBCRC32C is not set
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_CRC16=m
+CONFIG_CRC32=m
+CONFIG_LIBCRC32C=m
+CONFIG_ZLIB_INFLATE=m
+CONFIG_ZLIB_DEFLATE=m
diff --git a/arch/mips/configs/jmr3927_defconfig b/arch/mips/configs/jmr3927_defconfig
index da5d9ee2ecce..6390a753e80b 100644
--- a/arch/mips/configs/jmr3927_defconfig
+++ b/arch/mips/configs/jmr3927_defconfig
@@ -1,12 +1,9 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-rc2
-# Wed Jan 26 02:49:06 2005
+# Linux kernel version: 2.6.14-rc2
+# Thu Oct 20 22:26:17 2005
#
CONFIG_MIPS=y
-# CONFIG_64BIT is not set
-# CONFIG_64BIT is not set
-CONFIG_32BIT=y
#
# Code maturity level options
@@ -14,24 +11,29 @@ CONFIG_32BIT=y
CONFIG_EXPERIMENTAL=y
CONFIG_CLEAN_COMPILE=y
CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
#
# General setup
#
CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
# CONFIG_POSIX_MQUEUE is not set
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_HOTPLUG is not set
+CONFIG_HOTPLUG=y
CONFIG_KOBJECT_UEVENT=y
# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
CONFIG_EMBEDDED=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
@@ -41,6 +43,7 @@ CONFIG_CC_ALIGN_LABELS=0
CONFIG_CC_ALIGN_LOOPS=0
CONFIG_CC_ALIGN_JUMPS=0
# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
#
# Loadable module support
@@ -50,40 +53,68 @@ CONFIG_CC_ALIGN_JUMPS=0
#
# Machine selection
#
-# CONFIG_MACH_JAZZ is not set
-# CONFIG_MACH_VR41XX is not set
-CONFIG_TOSHIBA_JMR3927=y
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_MIPS_PB1550 is not set
+# CONFIG_MIPS_PB1200 is not set
+# CONFIG_MIPS_DB1000 is not set
+# CONFIG_MIPS_DB1100 is not set
+# CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
+# CONFIG_MIPS_DB1200 is not set
+# CONFIG_MIPS_MIRAGE is not set
# CONFIG_MIPS_COBALT is not set
# CONFIG_MACH_DECSTATION is not set
# CONFIG_MIPS_EV64120 is not set
# CONFIG_MIPS_EV96100 is not set
# CONFIG_MIPS_IVR is not set
-# CONFIG_LASAT is not set
# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_LASAT is not set
# CONFIG_MIPS_ATLAS is not set
# CONFIG_MIPS_MALTA is not set
# CONFIG_MIPS_SEAD is not set
+# CONFIG_MIPS_SIM is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
# CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_G is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_JAGUAR_ATX is not set
-# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MIPS_XXS1500 is not set
+# CONFIG_PNX8550_V2PCI is not set
+# CONFIG_PNX8550_JBS is not set
# CONFIG_DDB5074 is not set
# CONFIG_DDB5476 is not set
# CONFIG_DDB5477 is not set
-# CONFIG_NEC_OSPREY is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_QEMU is not set
# CONFIG_SGI_IP22 is not set
-# CONFIG_SOC_AU1X00 is not set
-# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_BIGSUR is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_PTSWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CRHONE is not set
# CONFIG_SNI_RM200_PCI is not set
+CONFIG_TOSHIBA_JMR3927=y
# CONFIG_TOSHIBA_RBTX4927 is not set
+# CONFIG_TOSHIBA_RBTX4938 is not set
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_HAVE_DEC_LOCK=y
CONFIG_DMA_NONCOHERENT=y
CONFIG_DMA_NEED_PCI_MAP_STATE=y
+CONFIG_CPU_BIG_ENDIAN=y
# CONFIG_CPU_LITTLE_ENDIAN is not set
+CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
CONFIG_MIPS_TX3927=y
CONFIG_SWAP_IO_SPACE=y
CONFIG_MIPS_L1_CACHE_SHIFT=5
@@ -92,8 +123,10 @@ CONFIG_TOSHIBA_BOARDS=y
#
# CPU selection
#
-# CONFIG_CPU_MIPS32 is not set
-# CONFIG_CPU_MIPS64 is not set
+# CONFIG_CPU_MIPS32_R1 is not set
+# CONFIG_CPU_MIPS32_R2 is not set
+# CONFIG_CPU_MIPS64_R1 is not set
+# CONFIG_CPU_MIPS64_R2 is not set
# CONFIG_CPU_R3000 is not set
CONFIG_CPU_TX39XX=y
# CONFIG_CPU_VR41XX is not set
@@ -109,12 +142,34 @@ CONFIG_CPU_TX39XX=y
# CONFIG_CPU_RM7000 is not set
# CONFIG_CPU_RM9000 is not set
# CONFIG_CPU_SB1 is not set
+CONFIG_SYS_HAS_CPU_TX39XX=y
+CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
+
+#
+# Kernel type
+#
+CONFIG_32BIT=y
+# CONFIG_64BIT is not set
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_MIPS_MT is not set
# CONFIG_CPU_ADVANCED is not set
CONFIG_CPU_HAS_SYNC=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_ARCH_FLATMEM_ENABLE=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_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
CONFIG_RTC_DS1742=y
@@ -124,7 +179,6 @@ CONFIG_RTC_DS1742=y
CONFIG_HW_HAS_PCI=y
CONFIG_PCI=y
CONFIG_PCI_LEGACY_PROC=y
-CONFIG_PCI_NAMES=y
CONFIG_MMU=y
#
@@ -133,10 +187,6 @@ CONFIG_MMU=y
# CONFIG_PCCARD is not set
#
-# PC-card bridges
-#
-
-#
# PCI Hotplug Support
#
# CONFIG_HOTPLUG_PCI is not set
@@ -149,6 +199,80 @@ CONFIG_BINFMT_ELF=y
CONFIG_TRAD_SIGNALS=y
#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=y
+CONFIG_NET_KEY=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+CONFIG_INET_TUNNEL=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+# CONFIG_IPV6 is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# 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_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_IEEE80211=y
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=y
+CONFIG_IEEE80211_CRYPT_CCMP=y
+CONFIG_IEEE80211_CRYPT_TKIP=y
+
+#
# Device Drivers
#
@@ -157,7 +281,12 @@ CONFIG_TRAD_SIGNALS=y
#
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
+CONFIG_FW_LOADER=y
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+CONFIG_CONNECTOR=y
#
# Memory Technology Devices (MTD)
@@ -176,7 +305,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
#
# Block devices
#
-# CONFIG_BLK_DEV_FD is not set
# CONFIG_BLK_CPQ_DA is not set
# CONFIG_BLK_CPQ_CISS_DA is not set
# CONFIG_BLK_DEV_DAC960 is not set
@@ -187,7 +315,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_BLK_DEV_SX8 is not set
# CONFIG_BLK_DEV_RAM is not set
CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_INITRAMFS_SOURCE=""
# CONFIG_LBD is not set
CONFIG_CDROM_PKTCDVD=y
CONFIG_CDROM_PKTCDVD_BUFFERS=8
@@ -210,6 +337,7 @@ CONFIG_ATA_OVER_ETH=y
#
# SCSI device support
#
+CONFIG_RAID_ATTRS=y
# CONFIG_SCSI is not set
#
@@ -220,6 +348,7 @@ CONFIG_ATA_OVER_ETH=y
#
# Fusion MPT device support
#
+# CONFIG_FUSION is not set
#
# IEEE 1394 (FireWire) support
@@ -232,78 +361,13 @@ CONFIG_ATA_OVER_ETH=y
# CONFIG_I2O is not set
#
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
-CONFIG_NETLINK_DEV=y
-CONFIG_UNIX=y
-CONFIG_NET_KEY=y
-CONFIG_INET=y
-# CONFIG_IP_MULTICAST is not set
-# CONFIG_IP_ADVANCED_ROUTER is not set
-CONFIG_IP_PNP=y
-# CONFIG_IP_PNP_DHCP is not set
-CONFIG_IP_PNP_BOOTP=y
-# CONFIG_IP_PNP_RARP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_ARPD is not set
-# CONFIG_SYN_COOKIES is not set
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-CONFIG_INET_TUNNEL=y
-CONFIG_IP_TCPDIAG=y
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-# CONFIG_IPV6 is not set
-# CONFIG_NETFILTER is not set
-CONFIG_XFRM=y
-CONFIG_XFRM_USER=y
-
-#
-# SCTP Configuration (EXPERIMENTAL)
+# Network device support
#
-# CONFIG_IP_SCTP 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_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
CONFIG_NETDEVICES=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_EQUALIZER is not set
# CONFIG_TUN is not set
-# CONFIG_ETHERTAP is not set
#
# ARCnet devices
@@ -311,6 +375,21 @@ CONFIG_NETDEVICES=y
# CONFIG_ARCNET is not set
#
+# PHY device support
+#
+CONFIG_PHYLIB=y
+CONFIG_PHYCONTROL=y
+
+#
+# MII PHY device drivers
+#
+CONFIG_MARVELL_PHY=y
+CONFIG_DAVICOM_PHY=y
+CONFIG_QSEMI_PHY=y
+CONFIG_LXT_PHY=y
+CONFIG_CICADA_PHY=y
+
+#
# Ethernet (10 or 100Mbit)
#
CONFIG_NET_ETHERNET=y
@@ -336,12 +415,16 @@ CONFIG_NET_ETHERNET=y
# CONFIG_HAMACHI is not set
# CONFIG_YELLOWFIN is not set
# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
# CONFIG_SK98LIN is not set
# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
#
# Ethernet (10000 Mbit)
#
+# CONFIG_CHELSIO_T1 is not set
# CONFIG_IXGB is not set
# CONFIG_S2IO is not set
@@ -354,6 +437,8 @@ CONFIG_NET_ETHERNET=y
# Wireless LAN (non-hamradio)
#
# CONFIG_NET_RADIO is not set
+# CONFIG_IPW_DEBUG is not set
+CONFIG_IPW2200=y
#
# Wan interfaces
@@ -365,6 +450,8 @@ CONFIG_NET_ETHERNET=y
# CONFIG_SLIP is not set
# CONFIG_SHAPER is not set
# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
#
# ISDN subsystem
@@ -394,19 +481,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
# CONFIG_INPUT_EVBUG is not set
#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=y
-# CONFIG_SERIO_I8042 is not set
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_PCIPS2 is not set
-# CONFIG_SERIO_LIBPS2 is not set
-CONFIG_SERIO_RAW=y
-
-#
# Input Device Drivers
#
# CONFIG_INPUT_KEYBOARD is not set
@@ -416,6 +490,17 @@ CONFIG_SERIO_RAW=y
# CONFIG_INPUT_MISC is not set
#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_PCIPS2 is not set
+# CONFIG_SERIO_LIBPS2 is not set
+CONFIG_SERIO_RAW=y
+# CONFIG_GAMEPORT is not set
+
+#
# Character devices
#
CONFIG_VT=y
@@ -426,11 +511,9 @@ CONFIG_SERIAL_NONSTANDARD=y
# CONFIG_ROCKETPORT is not set
# CONFIG_CYCLADES is not set
# CONFIG_DIGIEPCA is not set
-# CONFIG_DIGI is not set
# CONFIG_MOXA_INTELLIO is not set
# CONFIG_MOXA_SMARTIO is not set
# CONFIG_ISI is not set
-# CONFIG_SYNCLINK is not set
# CONFIG_SYNCLINKMP is not set
# CONFIG_N_HDLC is not set
# CONFIG_RISCOM8 is not set
@@ -438,10 +521,6 @@ CONFIG_SERIAL_NONSTANDARD=y
# CONFIG_SX is not set
# CONFIG_RIO is not set
# CONFIG_STALDRV is not set
-# CONFIG_SERIAL_TX3912 is not set
-CONFIG_TXX927_SERIAL=y
-CONFIG_TXX927_SERIAL_CONSOLE=y
-# CONFIG_SERIAL_TXX9 is not set
#
# Serial drivers
@@ -451,6 +530,8 @@ CONFIG_TXX927_SERIAL_CONSOLE=y
#
# Non-8250 serial port support
#
+CONFIG_HAS_TXX9_SERIAL=y
+# CONFIG_SERIAL_JSM is not set
# CONFIG_UNIX98_PTYS is not set
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
@@ -477,6 +558,11 @@ CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_RAW_DRIVER is not set
#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+
+#
# I2C support
#
# CONFIG_I2C is not set
@@ -487,10 +573,20 @@ CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_W1 is not set
#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
+#
# Misc devices
#
#
+# Multimedia Capabilities Port drivers
+#
+
+#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
@@ -504,6 +600,11 @@ CONFIG_LEGACY_PTY_COUNT=256
# Graphics support
#
CONFIG_FB=y
+# CONFIG_FB_CFB_FILLRECT is not set
+# CONFIG_FB_CFB_COPYAREA is not set
+# CONFIG_FB_CFB_IMAGEBLIT is not set
+# CONFIG_FB_SOFT_CURSOR is not set
+# CONFIG_FB_MACMODES is not set
# CONFIG_FB_MODE_HELPERS is not set
# CONFIG_FB_TILEBLITTING is not set
# CONFIG_FB_CIRRUS is not set
@@ -511,6 +612,7 @@ CONFIG_FB=y
# CONFIG_FB_CYBER2000 is not set
# CONFIG_FB_ASILIANT is not set
# CONFIG_FB_IMSTT is not set
+# CONFIG_FB_NVIDIA is not set
# CONFIG_FB_RIVA is not set
# CONFIG_FB_MATROX is not set
# CONFIG_FB_RADEON_OLD is not set
@@ -523,8 +625,10 @@ CONFIG_FB=y
# CONFIG_FB_KYRO is not set
# CONFIG_FB_3DFX is not set
# CONFIG_FB_VOODOO1 is not set
+# CONFIG_FB_SMIVGX is not set
+# CONFIG_FB_CYBLA is not set
# CONFIG_FB_TRIDENT is not set
-# CONFIG_FB_E1356 is not set
+# CONFIG_FB_S1D13XXX is not set
# CONFIG_FB_VIRTUAL is not set
#
@@ -548,13 +652,9 @@ CONFIG_DUMMY_CONSOLE=y
#
# USB support
#
-# CONFIG_USB is not set
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB_ARCH_HAS_OHCI=y
-
-#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
-#
+# CONFIG_USB is not set
#
# USB Gadget Support
@@ -572,6 +672,10 @@ CONFIG_USB_ARCH_HAS_OHCI=y
# CONFIG_INFINIBAND is not set
#
+# SN Devices
+#
+
+#
# File systems
#
# CONFIG_EXT2_FS is not set
@@ -579,13 +683,16 @@ CONFIG_USB_ARCH_HAS_OHCI=y
# CONFIG_JBD 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_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
# CONFIG_QUOTA is not set
CONFIG_DNOTIFY=y
# CONFIG_AUTOFS_FS is not set
# CONFIG_AUTOFS4_FS is not set
+CONFIG_FUSE_FS=y
#
# CD-ROM/DVD Filesystems
@@ -606,10 +713,10 @@ CONFIG_DNOTIFY=y
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
# CONFIG_TMPFS is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
+CONFIG_RELAYFS_FS=y
#
# Miscellaneous filesystems
@@ -638,7 +745,7 @@ CONFIG_NFS_FS=y
# CONFIG_NFSD is not set
CONFIG_ROOT_NFS=y
CONFIG_LOCKD=y
-# CONFIG_EXPORTFS is not set
+CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
@@ -647,6 +754,7 @@ CONFIG_SUNRPC=y
# CONFIG_NCP_FS is not set
# CONFIG_CODA_FS is not set
# CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
#
# Partition Types
@@ -667,7 +775,9 @@ CONFIG_MSDOS_PARTITION=y
#
# Kernel hacking
#
+# CONFIG_PRINTK_TIME is not set
# CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=14
CONFIG_CROSSCOMPILE=y
CONFIG_CMDLINE=""
@@ -681,7 +791,31 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
#
# Cryptographic options
#
-# CONFIG_CRYPTO is not set
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_NULL=y
+CONFIG_CRYPTO_MD4=y
+CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_SHA1=y
+CONFIG_CRYPTO_SHA256=y
+CONFIG_CRYPTO_SHA512=y
+CONFIG_CRYPTO_WP512=y
+CONFIG_CRYPTO_TGR192=y
+CONFIG_CRYPTO_DES=y
+CONFIG_CRYPTO_BLOWFISH=y
+CONFIG_CRYPTO_TWOFISH=y
+CONFIG_CRYPTO_SERPENT=y
+CONFIG_CRYPTO_AES=y
+CONFIG_CRYPTO_CAST5=y
+CONFIG_CRYPTO_CAST6=y
+CONFIG_CRYPTO_TEA=y
+CONFIG_CRYPTO_ARC4=y
+CONFIG_CRYPTO_KHAZAD=y
+CONFIG_CRYPTO_ANUBIS=y
+CONFIG_CRYPTO_DEFLATE=y
+CONFIG_CRYPTO_MICHAEL_MIC=y
+CONFIG_CRYPTO_CRC32C=y
+# CONFIG_CRYPTO_TEST is not set
#
# Hardware crypto devices
@@ -691,7 +825,8 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
# Library routines
#
# CONFIG_CRC_CCITT is not set
-# CONFIG_CRC32 is not set
-# CONFIG_LIBCRC32C is not set
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_CRC16=y
+CONFIG_CRC32=y
+CONFIG_LIBCRC32C=y
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
diff --git a/arch/mips/configs/lasat200_defconfig b/arch/mips/configs/lasat200_defconfig
index 8d600ae890f4..03cd0ca6e639 100644
--- a/arch/mips/configs/lasat200_defconfig
+++ b/arch/mips/configs/lasat200_defconfig
@@ -1,12 +1,9 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-rc2
-# Wed Jan 26 02:49:06 2005
+# Linux kernel version: 2.6.14-rc2
+# Thu Oct 20 22:26:19 2005
#
CONFIG_MIPS=y
-# CONFIG_64BIT is not set
-# CONFIG_64BIT is not set
-CONFIG_32BIT=y
#
# Code maturity level options
@@ -14,24 +11,29 @@ CONFIG_32BIT=y
CONFIG_EXPERIMENTAL=y
CONFIG_CLEAN_COMPILE=y
CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
#
# General setup
#
CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
# CONFIG_POSIX_MQUEUE is not set
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_HOTPLUG is not set
+CONFIG_HOTPLUG=y
CONFIG_KOBJECT_UEVENT=y
# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
CONFIG_EMBEDDED=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
@@ -41,6 +43,7 @@ CONFIG_CC_ALIGN_LABELS=0
CONFIG_CC_ALIGN_LOOPS=0
CONFIG_CC_ALIGN_JUMPS=0
# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
#
# Loadable module support
@@ -56,53 +59,83 @@ CONFIG_KMOD=y
#
# Machine selection
#
-# CONFIG_MACH_JAZZ is not set
-# CONFIG_MACH_VR41XX is not set
-# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_MIPS_PB1550 is not set
+# CONFIG_MIPS_PB1200 is not set
+# CONFIG_MIPS_DB1000 is not set
+# CONFIG_MIPS_DB1100 is not set
+# CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
+# CONFIG_MIPS_DB1200 is not set
+# CONFIG_MIPS_MIRAGE is not set
# CONFIG_MIPS_COBALT is not set
# CONFIG_MACH_DECSTATION is not set
# CONFIG_MIPS_EV64120 is not set
# CONFIG_MIPS_EV96100 is not set
# CONFIG_MIPS_IVR is not set
-CONFIG_LASAT=y
-CONFIG_PICVUE=y
-CONFIG_PICVUE_PROC=y
-CONFIG_DS1603=y
-CONFIG_LASAT_SYSCTL=y
# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MACH_JAZZ is not set
+CONFIG_LASAT=y
# CONFIG_MIPS_ATLAS is not set
# CONFIG_MIPS_MALTA is not set
# CONFIG_MIPS_SEAD is not set
+# CONFIG_MIPS_SIM is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
# CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_G is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_JAGUAR_ATX is not set
-# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MIPS_XXS1500 is not set
+# CONFIG_PNX8550_V2PCI is not set
+# CONFIG_PNX8550_JBS is not set
# CONFIG_DDB5074 is not set
# CONFIG_DDB5476 is not set
# CONFIG_DDB5477 is not set
-# CONFIG_NEC_OSPREY is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_QEMU is not set
# CONFIG_SGI_IP22 is not set
-# CONFIG_SOC_AU1X00 is not set
-# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_BIGSUR is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_PTSWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CRHONE is not set
# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
# CONFIG_TOSHIBA_RBTX4927 is not set
+# CONFIG_TOSHIBA_RBTX4938 is not set
+CONFIG_PICVUE=y
+CONFIG_PICVUE_PROC=y
+CONFIG_DS1603=y
+CONFIG_LASAT_SYSCTL=y
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_HAVE_DEC_LOCK=y
CONFIG_DMA_NONCOHERENT=y
CONFIG_DMA_NEED_PCI_MAP_STATE=y
CONFIG_MIPS_NILE4=y
+# CONFIG_CPU_BIG_ENDIAN is not set
CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
CONFIG_MIPS_GT64120=y
CONFIG_MIPS_L1_CACHE_SHIFT=5
#
# CPU selection
#
-# CONFIG_CPU_MIPS32 is not set
-# CONFIG_CPU_MIPS64 is not set
+# CONFIG_CPU_MIPS32_R1 is not set
+# CONFIG_CPU_MIPS32_R2 is not set
+# CONFIG_CPU_MIPS64_R1 is not set
+# CONFIG_CPU_MIPS64_R2 is not set
# CONFIG_CPU_R3000 is not set
# CONFIG_CPU_TX39XX is not set
# CONFIG_CPU_VR41XX is not set
@@ -118,17 +151,41 @@ CONFIG_CPU_R5000=y
# CONFIG_CPU_RM7000 is not set
# CONFIG_CPU_RM9000 is not set
# CONFIG_CPU_SB1 is not set
+CONFIG_SYS_HAS_CPU_R5000=y
+CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
+CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y
+
+#
+# Kernel type
+#
+CONFIG_32BIT=y
+# CONFIG_64BIT is not set
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_BOARD_SCACHE=y
CONFIG_R5000_CPU_SCACHE=y
+# CONFIG_MIPS_MT is not set
# CONFIG_64BIT_PHYS_ADDR is not set
# CONFIG_CPU_ADVANCED is not set
CONFIG_CPU_HAS_LLSC=y
CONFIG_CPU_HAS_LLDSCD=y
CONFIG_CPU_HAS_SYNC=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_ARCH_FLATMEM_ENABLE=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_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
#
@@ -137,7 +194,6 @@ CONFIG_CPU_HAS_SYNC=y
CONFIG_HW_HAS_PCI=y
CONFIG_PCI=y
CONFIG_PCI_LEGACY_PROC=y
-# CONFIG_PCI_NAMES is not set
CONFIG_MMU=y
#
@@ -146,10 +202,6 @@ CONFIG_MMU=y
# CONFIG_PCCARD is not set
#
-# PC-card bridges
-#
-
-#
# PCI Hotplug Support
#
# CONFIG_HOTPLUG_PCI is not set
@@ -162,6 +214,76 @@ CONFIG_BINFMT_ELF=y
CONFIG_TRAD_SIGNALS=y
#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_PACKET is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+CONFIG_NET_KEY=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+# CONFIG_IP_PNP 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_TUNNEL=m
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+# CONFIG_IPV6 is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# 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_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_IEEE80211=m
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=m
+CONFIG_IEEE80211_CRYPT_CCMP=m
+CONFIG_IEEE80211_CRYPT_TKIP=m
+
+#
# Device Drivers
#
@@ -170,15 +292,20 @@ CONFIG_TRAD_SIGNALS=y
#
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
+CONFIG_FW_LOADER=m
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+CONFIG_CONNECTOR=m
#
# Memory Technology Devices (MTD)
#
CONFIG_MTD=y
# CONFIG_MTD_DEBUG is not set
-CONFIG_MTD_PARTITIONS=y
# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
# CONFIG_MTD_REDBOOT_PARTS is not set
# CONFIG_MTD_CMDLINE_PARTS is not set
@@ -223,6 +350,7 @@ CONFIG_MTD_CFI_UTIL=y
# CONFIG_MTD_COMPLEX_MAPPINGS is not set
# CONFIG_MTD_PHYSMAP is not set
CONFIG_MTD_LASAT=y
+# CONFIG_MTD_PLATRAM is not set
#
# Self-contained MTD device drivers
@@ -258,7 +386,6 @@ CONFIG_MTD_LASAT=y
#
# Block devices
#
-# CONFIG_BLK_DEV_FD is not set
# CONFIG_BLK_CPQ_DA is not set
# CONFIG_BLK_CPQ_CISS_DA is not set
# CONFIG_BLK_DEV_DAC960 is not set
@@ -269,7 +396,6 @@ CONFIG_MTD_LASAT=y
# CONFIG_BLK_DEV_SX8 is not set
# CONFIG_BLK_DEV_RAM is not set
CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_INITRAMFS_SOURCE=""
# CONFIG_LBD is not set
CONFIG_CDROM_PKTCDVD=m
CONFIG_CDROM_PKTCDVD_BUFFERS=8
@@ -326,6 +452,7 @@ CONFIG_BLK_DEV_CMD64X=y
# CONFIG_BLK_DEV_HPT366 is not set
# CONFIG_BLK_DEV_SC1200 is not set
# CONFIG_BLK_DEV_PIIX is not set
+# CONFIG_BLK_DEV_IT821X is not set
# CONFIG_BLK_DEV_NS87415 is not set
# CONFIG_BLK_DEV_PDC202XX_OLD is not set
# CONFIG_BLK_DEV_PDC202XX_NEW is not set
@@ -343,6 +470,7 @@ CONFIG_IDEDMA_AUTO=y
#
# SCSI device support
#
+CONFIG_RAID_ATTRS=m
# CONFIG_SCSI is not set
#
@@ -353,6 +481,7 @@ CONFIG_IDEDMA_AUTO=y
#
# Fusion MPT device support
#
+# CONFIG_FUSION is not set
#
# IEEE 1394 (FireWire) support
@@ -365,68 +494,8 @@ CONFIG_IDEDMA_AUTO=y
# CONFIG_I2O is not set
#
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-# CONFIG_PACKET is not set
-# CONFIG_NETLINK_DEV is not set
-CONFIG_UNIX=y
-CONFIG_NET_KEY=y
-CONFIG_INET=y
-# CONFIG_IP_MULTICAST is not set
-# CONFIG_IP_ADVANCED_ROUTER is not set
-# CONFIG_IP_PNP 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_TUNNEL=m
-CONFIG_IP_TCPDIAG=m
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-# CONFIG_IPV6 is not set
-# CONFIG_NETFILTER is not set
-CONFIG_XFRM=y
-CONFIG_XFRM_USER=m
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP 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_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
+# Network device support
#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
CONFIG_NETDEVICES=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
@@ -439,6 +508,21 @@ CONFIG_NETDEVICES=y
# CONFIG_ARCNET is not set
#
+# PHY device support
+#
+CONFIG_PHYLIB=m
+CONFIG_PHYCONTROL=y
+
+#
+# MII PHY device drivers
+#
+CONFIG_MARVELL_PHY=m
+CONFIG_DAVICOM_PHY=m
+CONFIG_QSEMI_PHY=m
+CONFIG_LXT_PHY=m
+CONFIG_CICADA_PHY=m
+
+#
# Ethernet (10 or 100Mbit)
#
CONFIG_NET_ETHERNET=y
@@ -464,12 +548,16 @@ CONFIG_NET_ETHERNET=y
# CONFIG_HAMACHI is not set
# CONFIG_YELLOWFIN is not set
# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
# CONFIG_SK98LIN is not set
# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
#
# Ethernet (10000 Mbit)
#
+# CONFIG_CHELSIO_T1 is not set
# CONFIG_IXGB is not set
# CONFIG_S2IO is not set
@@ -482,6 +570,8 @@ CONFIG_NET_ETHERNET=y
# Wireless LAN (non-hamradio)
#
# CONFIG_NET_RADIO is not set
+# CONFIG_IPW_DEBUG is not set
+CONFIG_IPW2200=m
#
# Wan interfaces
@@ -493,6 +583,8 @@ CONFIG_NET_ETHERNET=y
# CONFIG_SLIP is not set
# CONFIG_SHAPER is not set
# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
#
# ISDN subsystem
@@ -522,19 +614,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
# CONFIG_INPUT_EVBUG is not set
#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=y
-CONFIG_SERIO_I8042=y
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_PCIPS2 is not set
-# CONFIG_SERIO_LIBPS2 is not set
-CONFIG_SERIO_RAW=m
-
-#
# Input Device Drivers
#
# CONFIG_INPUT_KEYBOARD is not set
@@ -544,6 +623,17 @@ CONFIG_SERIO_RAW=m
# CONFIG_INPUT_MISC is not set
#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_I8042=y
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_PCIPS2 is not set
+# CONFIG_SERIO_LIBPS2 is not set
+CONFIG_SERIO_RAW=m
+# CONFIG_GAMEPORT is not set
+
+#
# Character devices
#
CONFIG_VT=y
@@ -564,6 +654,7 @@ CONFIG_SERIAL_8250_NR_UARTS=4
#
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
CONFIG_UNIX98_PTYS=y
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
@@ -590,6 +681,11 @@ CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_RAW_DRIVER is not set
#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+
+#
# I2C support
#
# CONFIG_I2C is not set
@@ -600,10 +696,20 @@ CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_W1 is not set
#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
+#
# Misc devices
#
#
+# Multimedia Capabilities Port drivers
+#
+
+#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
@@ -623,7 +729,6 @@ CONFIG_LEGACY_PTY_COUNT=256
#
# CONFIG_VGA_CONSOLE is not set
CONFIG_DUMMY_CONSOLE=y
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Sound
@@ -633,13 +738,9 @@ CONFIG_DUMMY_CONSOLE=y
#
# USB support
#
-# CONFIG_USB is not set
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB_ARCH_HAS_OHCI=y
-
-#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
-#
+# CONFIG_USB is not set
#
# USB Gadget Support
@@ -657,10 +758,15 @@ CONFIG_USB_ARCH_HAS_OHCI=y
# CONFIG_INFINIBAND is not set
#
+# SN Devices
+#
+
+#
# File systems
#
CONFIG_EXT2_FS=y
# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
CONFIG_EXT3_FS=y
CONFIG_EXT3_FS_XATTR=y
# CONFIG_EXT3_FS_POSIX_ACL is not set
@@ -670,13 +776,16 @@ CONFIG_JBD=y
CONFIG_FS_MBCACHE=y
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
# CONFIG_XFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
# CONFIG_QUOTA is not set
CONFIG_DNOTIFY=y
# CONFIG_AUTOFS_FS is not set
# CONFIG_AUTOFS4_FS is not set
+CONFIG_FUSE_FS=m
#
# CD-ROM/DVD Filesystems
@@ -697,12 +806,10 @@ CONFIG_DNOTIFY=y
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
-CONFIG_DEVPTS_FS_XATTR=y
-CONFIG_DEVPTS_FS_SECURITY=y
# CONFIG_TMPFS is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
+CONFIG_RELAYFS_FS=m
#
# Miscellaneous filesystems
@@ -728,12 +835,13 @@ CONFIG_RAMFS=y
#
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
# CONFIG_NFS_V4 is not set
# CONFIG_NFS_DIRECTIO is not set
# CONFIG_NFSD is not set
CONFIG_LOCKD=y
CONFIG_LOCKD_V4=y
-# CONFIG_EXPORTFS is not set
+CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
@@ -742,6 +850,7 @@ CONFIG_SUNRPC=y
# CONFIG_NCP_FS is not set
# CONFIG_CODA_FS is not set
# CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
#
# Partition Types
@@ -762,7 +871,9 @@ CONFIG_MSDOS_PARTITION=y
#
# Kernel hacking
#
+# CONFIG_PRINTK_TIME is not set
# CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=14
CONFIG_CROSSCOMPILE=y
CONFIG_CMDLINE=""
@@ -776,7 +887,31 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
#
# Cryptographic options
#
-# CONFIG_CRYPTO is not set
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_AES=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_CRC32C=m
+# CONFIG_CRYPTO_TEST is not set
#
# Hardware crypto devices
@@ -786,7 +921,8 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
# Library routines
#
# CONFIG_CRC_CCITT is not set
+CONFIG_CRC16=m
CONFIG_CRC32=y
CONFIG_LIBCRC32C=m
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_ZLIB_INFLATE=m
+CONFIG_ZLIB_DEFLATE=m
diff --git a/arch/mips/configs/malta_defconfig b/arch/mips/configs/malta_defconfig
index 79519ac5af4a..2acdec959dd0 100644
--- a/arch/mips/configs/malta_defconfig
+++ b/arch/mips/configs/malta_defconfig
@@ -1,12 +1,9 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-rc2
-# Wed Jan 26 02:53:14 2005
+# Linux kernel version: 2.6.14-rc2
+# Thu Oct 20 22:26:22 2005
#
CONFIG_MIPS=y
-# CONFIG_64BIT is not set
-# CONFIG_64BIT is not set
-CONFIG_32BIT=y
#
# Code maturity level options
@@ -14,24 +11,29 @@ CONFIG_32BIT=y
CONFIG_EXPERIMENTAL=y
CONFIG_CLEAN_COMPILE=y
CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
#
# General setup
#
CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
# CONFIG_POSIX_MQUEUE is not set
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
CONFIG_HOTPLUG=y
CONFIG_KOBJECT_UEVENT=y
# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
CONFIG_EMBEDDED=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
@@ -41,6 +43,7 @@ CONFIG_CC_ALIGN_LABELS=0
CONFIG_CC_ALIGN_LOOPS=0
CONFIG_CC_ALIGN_JUMPS=0
# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
#
# Loadable module support
@@ -56,44 +59,75 @@ CONFIG_KMOD=y
#
# Machine selection
#
-# CONFIG_MACH_JAZZ is not set
-# CONFIG_MACH_VR41XX is not set
-# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_MIPS_PB1550 is not set
+# CONFIG_MIPS_PB1200 is not set
+# CONFIG_MIPS_DB1000 is not set
+# CONFIG_MIPS_DB1100 is not set
+# CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
+# CONFIG_MIPS_DB1200 is not set
+# CONFIG_MIPS_MIRAGE is not set
# CONFIG_MIPS_COBALT is not set
# CONFIG_MACH_DECSTATION is not set
# CONFIG_MIPS_EV64120 is not set
# CONFIG_MIPS_EV96100 is not set
# CONFIG_MIPS_IVR is not set
-# CONFIG_LASAT is not set
# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_LASAT is not set
# CONFIG_MIPS_ATLAS is not set
CONFIG_MIPS_MALTA=y
# CONFIG_MIPS_SEAD is not set
+# CONFIG_MIPS_SIM is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
# CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_G is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_JAGUAR_ATX is not set
-# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MIPS_XXS1500 is not set
+# CONFIG_PNX8550_V2PCI is not set
+# CONFIG_PNX8550_JBS is not set
# CONFIG_DDB5074 is not set
# CONFIG_DDB5476 is not set
# CONFIG_DDB5477 is not set
-# CONFIG_NEC_OSPREY is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_QEMU is not set
# CONFIG_SGI_IP22 is not set
-# CONFIG_SOC_AU1X00 is not set
-# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_BIGSUR is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_PTSWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CRHONE is not set
# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
# CONFIG_TOSHIBA_RBTX4927 is not set
+# CONFIG_TOSHIBA_RBTX4938 is not set
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_HAVE_DEC_LOCK=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
CONFIG_DMA_NONCOHERENT=y
CONFIG_DMA_NEED_PCI_MAP_STATE=y
CONFIG_GENERIC_ISA_DMA=y
CONFIG_I8259=y
CONFIG_MIPS_BONITO64=y
CONFIG_MIPS_MSC=y
+# CONFIG_CPU_BIG_ENDIAN is not set
CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
+CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
+CONFIG_IRQ_CPU=y
CONFIG_MIPS_BOARDS_GEN=y
CONFIG_MIPS_GT64120=y
CONFIG_SWAP_IO_SPACE=y
@@ -104,8 +138,10 @@ CONFIG_HAVE_STD_PC_SERIAL_PORT=y
#
# CPU selection
#
-CONFIG_CPU_MIPS32=y
-# CONFIG_CPU_MIPS64 is not set
+CONFIG_CPU_MIPS32_R1=y
+# CONFIG_CPU_MIPS32_R2 is not set
+# CONFIG_CPU_MIPS64_R1 is not set
+# CONFIG_CPU_MIPS64_R2 is not set
# CONFIG_CPU_R3000 is not set
# CONFIG_CPU_TX39XX is not set
# CONFIG_CPU_VR41XX is not set
@@ -121,14 +157,48 @@ CONFIG_CPU_MIPS32=y
# CONFIG_CPU_RM7000 is not set
# CONFIG_CPU_RM9000 is not set
# CONFIG_CPU_SB1 is not set
+CONFIG_SYS_HAS_CPU_MIPS32_R1=y
+CONFIG_SYS_HAS_CPU_MIPS32_R2=y
+CONFIG_SYS_HAS_CPU_MIPS64_R1=y
+CONFIG_SYS_HAS_CPU_NEVADA=y
+CONFIG_SYS_HAS_CPU_RM7000=y
+CONFIG_CPU_MIPS32=y
+CONFIG_CPU_MIPSR1=y
+CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
+CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
+
+#
+# Kernel type
+#
+CONFIG_32BIT=y
+# CONFIG_64BIT is not set
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_CPU_HAS_PREFETCH=y
+CONFIG_MIPS_MT=y
+# CONFIG_MIPS_MT_SMP is not set
+CONFIG_MIPS_VPE_LOADER=y
+CONFIG_MIPS_VPE_LOADER_TOM=y
+CONFIG_MIPS_VPE_APSP_API=y
# CONFIG_64BIT_PHYS_ADDR is not set
# CONFIG_CPU_ADVANCED is not set
CONFIG_CPU_HAS_LLSC=y
CONFIG_CPU_HAS_SYNC=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_ARCH_FLATMEM_ENABLE=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_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
#
@@ -137,7 +207,6 @@ CONFIG_CPU_HAS_SYNC=y
CONFIG_HW_HAS_PCI=y
CONFIG_PCI=y
CONFIG_PCI_LEGACY_PROC=y
-CONFIG_PCI_NAMES=y
CONFIG_MMU=y
#
@@ -146,10 +215,6 @@ CONFIG_MMU=y
# CONFIG_PCCARD is not set
#
-# PC-card bridges
-#
-
-#
# PCI Hotplug Support
#
# CONFIG_HOTPLUG_PCI is not set
@@ -162,229 +227,7 @@ CONFIG_BINFMT_ELF=y
CONFIG_TRAD_SIGNALS=y
#
-# Device Drivers
-#
-
-#
-# Generic Driver Options
-#
-CONFIG_STANDALONE=y
-CONFIG_PREVENT_FIRMWARE_BUILD=y
-CONFIG_FW_LOADER=y
-
-#
-# Memory Technology Devices (MTD)
-#
-# CONFIG_MTD is not set
-
-#
-# Parallel port support
-#
-# CONFIG_PARPORT is not set
-
-#
-# Plug and Play support
-#
-
-#
-# Block devices
-#
-CONFIG_BLK_DEV_FD=m
-# CONFIG_BLK_CPQ_DA is not set
-# CONFIG_BLK_CPQ_CISS_DA is not set
-# CONFIG_BLK_DEV_DAC960 is not set
-CONFIG_BLK_DEV_UMEM=m
-# CONFIG_BLK_DEV_COW_COMMON is not set
-CONFIG_BLK_DEV_LOOP=m
-CONFIG_BLK_DEV_CRYPTOLOOP=m
-CONFIG_BLK_DEV_NBD=m
-# CONFIG_BLK_DEV_SX8 is not set
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_BLK_DEV_RAM_SIZE=4096
-# CONFIG_BLK_DEV_INITRD is not set
-CONFIG_INITRAMFS_SOURCE=""
-# CONFIG_LBD is not set
-CONFIG_CDROM_PKTCDVD=m
-CONFIG_CDROM_PKTCDVD_BUFFERS=8
-# CONFIG_CDROM_PKTCDVD_WCACHE is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-CONFIG_ATA_OVER_ETH=m
-
-#
-# ATA/ATAPI/MFM/RLL support
-#
-CONFIG_IDE=y
-CONFIG_BLK_DEV_IDE=y
-
-#
-# Please see Documentation/ide.txt for help/info on IDE drives
-#
-# CONFIG_BLK_DEV_IDE_SATA is not set
-CONFIG_BLK_DEV_IDEDISK=y
-# CONFIG_IDEDISK_MULTI_MODE is not set
-CONFIG_BLK_DEV_IDECD=y
-# CONFIG_BLK_DEV_IDETAPE is not set
-# CONFIG_BLK_DEV_IDEFLOPPY is not set
-# CONFIG_BLK_DEV_IDESCSI is not set
-# CONFIG_IDE_TASK_IOCTL is not set
-
-#
-# IDE chipset support/bugfixes
-#
-CONFIG_IDE_GENERIC=y
-CONFIG_BLK_DEV_IDEPCI=y
-# CONFIG_IDEPCI_SHARE_IRQ is not set
-# CONFIG_BLK_DEV_OFFBOARD is not set
-CONFIG_BLK_DEV_GENERIC=y
-# CONFIG_BLK_DEV_OPTI621 is not set
-CONFIG_BLK_DEV_IDEDMA_PCI=y
-# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
-CONFIG_IDEDMA_PCI_AUTO=y
-# CONFIG_IDEDMA_ONLYDISK is not set
-# CONFIG_BLK_DEV_AEC62XX is not set
-# CONFIG_BLK_DEV_ALI15X3 is not set
-# CONFIG_BLK_DEV_AMD74XX is not set
-# CONFIG_BLK_DEV_CMD64X is not set
-# CONFIG_BLK_DEV_TRIFLEX is not set
-# CONFIG_BLK_DEV_CY82C693 is not set
-# CONFIG_BLK_DEV_CS5520 is not set
-# CONFIG_BLK_DEV_CS5530 is not set
-# CONFIG_BLK_DEV_HPT34X is not set
-# CONFIG_BLK_DEV_HPT366 is not set
-# CONFIG_BLK_DEV_SC1200 is not set
-CONFIG_BLK_DEV_PIIX=y
-# CONFIG_BLK_DEV_NS87415 is not set
-# CONFIG_BLK_DEV_PDC202XX_OLD is not set
-# CONFIG_BLK_DEV_PDC202XX_NEW is not set
-# CONFIG_BLK_DEV_SVWKS is not set
-# CONFIG_BLK_DEV_SIIMAGE is not set
-# CONFIG_BLK_DEV_SLC90E66 is not set
-# CONFIG_BLK_DEV_TRM290 is not set
-# CONFIG_BLK_DEV_VIA82CXXX is not set
-# CONFIG_IDE_ARM is not set
-CONFIG_BLK_DEV_IDEDMA=y
-# CONFIG_IDEDMA_IVB is not set
-CONFIG_IDEDMA_AUTO=y
-# CONFIG_BLK_DEV_HD is not set
-
-#
-# SCSI device support
-#
-CONFIG_SCSI=m
-CONFIG_SCSI_PROC_FS=y
-
-#
-# SCSI support type (disk, tape, CD-ROM)
-#
-CONFIG_BLK_DEV_SD=m
-CONFIG_CHR_DEV_ST=m
-CONFIG_CHR_DEV_OSST=m
-CONFIG_BLK_DEV_SR=m
-CONFIG_BLK_DEV_SR_VENDOR=y
-CONFIG_CHR_DEV_SG=m
-
-#
-# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
-#
-CONFIG_SCSI_MULTI_LUN=y
-CONFIG_SCSI_CONSTANTS=y
-CONFIG_SCSI_LOGGING=y
-
-#
-# SCSI Transport Attributes
-#
-CONFIG_SCSI_SPI_ATTRS=m
-CONFIG_SCSI_FC_ATTRS=m
-CONFIG_SCSI_ISCSI_ATTRS=m
-
-#
-# SCSI low-level drivers
-#
-CONFIG_BLK_DEV_3W_XXXX_RAID=m
-CONFIG_SCSI_3W_9XXX=m
-CONFIG_SCSI_ACARD=m
-CONFIG_SCSI_AACRAID=m
-CONFIG_SCSI_AIC7XXX=m
-CONFIG_AIC7XXX_CMDS_PER_DEVICE=32
-CONFIG_AIC7XXX_RESET_DELAY_MS=15000
-# CONFIG_AIC7XXX_DEBUG_ENABLE is not set
-CONFIG_AIC7XXX_DEBUG_MASK=0
-CONFIG_AIC7XXX_REG_PRETTY_PRINT=y
-# CONFIG_SCSI_AIC7XXX_OLD is not set
-# CONFIG_SCSI_AIC79XX is not set
-# CONFIG_SCSI_DPT_I2O is not set
-# CONFIG_MEGARAID_NEWGEN is not set
-# CONFIG_MEGARAID_LEGACY is not set
-# CONFIG_SCSI_SATA is not set
-# CONFIG_SCSI_BUSLOGIC is not set
-# CONFIG_SCSI_DMX3191D is not set
-# CONFIG_SCSI_EATA is not set
-# CONFIG_SCSI_EATA_PIO is not set
-# CONFIG_SCSI_FUTURE_DOMAIN is not set
-# CONFIG_SCSI_GDTH is not set
-# CONFIG_SCSI_IPS is not set
-# CONFIG_SCSI_INITIO is not set
-# CONFIG_SCSI_INIA100 is not set
-# CONFIG_SCSI_SYM53C8XX_2 is not set
-# CONFIG_SCSI_IPR is not set
-# CONFIG_SCSI_QLOGIC_ISP is not set
-# CONFIG_SCSI_QLOGIC_FC is not set
-# CONFIG_SCSI_QLOGIC_1280 is not set
-CONFIG_SCSI_QLA2XXX=m
-# CONFIG_SCSI_QLA21XX is not set
-# CONFIG_SCSI_QLA22XX is not set
-# CONFIG_SCSI_QLA2300 is not set
-# CONFIG_SCSI_QLA2322 is not set
-# CONFIG_SCSI_QLA6312 is not set
-# CONFIG_SCSI_DC395x is not set
-# CONFIG_SCSI_DC390T is not set
-# CONFIG_SCSI_NSP32 is not set
-# CONFIG_SCSI_DEBUG is not set
-
-#
-# Multi-device support (RAID and LVM)
-#
-CONFIG_MD=y
-CONFIG_BLK_DEV_MD=m
-CONFIG_MD_LINEAR=m
-CONFIG_MD_RAID0=m
-CONFIG_MD_RAID1=m
-CONFIG_MD_RAID10=m
-CONFIG_MD_RAID5=m
-CONFIG_MD_RAID6=m
-CONFIG_MD_MULTIPATH=m
-CONFIG_MD_FAULTY=m
-CONFIG_BLK_DEV_DM=m
-CONFIG_DM_CRYPT=m
-CONFIG_DM_SNAPSHOT=m
-CONFIG_DM_MIRROR=m
-CONFIG_DM_ZERO=m
-
-#
-# Fusion MPT device support
-#
-# CONFIG_FUSION is not set
-
-#
-# IEEE 1394 (FireWire) support
-#
-# CONFIG_IEEE1394 is not set
-
-#
-# I2O device support
-#
-# CONFIG_I2O is not set
-
-#
-# Networking support
+# Networking
#
CONFIG_NET=y
@@ -393,15 +236,20 @@ CONFIG_NET=y
#
CONFIG_PACKET=y
CONFIG_PACKET_MMAP=y
-CONFIG_NETLINK_DEV=y
CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
CONFIG_NET_KEY=y
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_FWMARK=y
CONFIG_IP_ROUTE_MULTIPATH=y
+# CONFIG_IP_ROUTE_MULTIPATH_CACHED is not set
CONFIG_IP_ROUTE_VERBOSE=y
CONFIG_IP_PNP=y
CONFIG_IP_PNP_DHCP=y
@@ -419,8 +267,10 @@ CONFIG_INET_AH=m
CONFIG_INET_ESP=m
CONFIG_INET_IPCOMP=m
CONFIG_INET_TUNNEL=m
-CONFIG_IP_TCPDIAG=m
-CONFIG_IP_TCPDIAG_IPV6=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
#
# IP: Virtual Server Configuration
@@ -465,6 +315,9 @@ CONFIG_IPV6_TUNNEL=m
CONFIG_NETFILTER=y
# CONFIG_NETFILTER_DEBUG is not set
CONFIG_BRIDGE_NETFILTER=y
+CONFIG_NETFILTER_NETLINK=m
+CONFIG_NETFILTER_NETLINK_QUEUE=m
+CONFIG_NETFILTER_NETLINK_LOG=m
#
# IP: Netfilter Configuration
@@ -472,11 +325,15 @@ CONFIG_BRIDGE_NETFILTER=y
CONFIG_IP_NF_CONNTRACK=m
CONFIG_IP_NF_CT_ACCT=y
CONFIG_IP_NF_CONNTRACK_MARK=y
+CONFIG_IP_NF_CONNTRACK_EVENTS=y
+CONFIG_IP_NF_CONNTRACK_NETLINK=m
CONFIG_IP_NF_CT_PROTO_SCTP=m
CONFIG_IP_NF_FTP=m
CONFIG_IP_NF_IRC=m
+# CONFIG_IP_NF_NETBIOS_NS is not set
CONFIG_IP_NF_TFTP=m
CONFIG_IP_NF_AMANDA=m
+CONFIG_IP_NF_PPTP=m
CONFIG_IP_NF_QUEUE=m
CONFIG_IP_NF_IPTABLES=m
CONFIG_IP_NF_MATCH_LIMIT=m
@@ -501,9 +358,12 @@ CONFIG_IP_NF_MATCH_PHYSDEV=m
CONFIG_IP_NF_MATCH_ADDRTYPE=m
CONFIG_IP_NF_MATCH_REALM=m
CONFIG_IP_NF_MATCH_SCTP=m
+CONFIG_IP_NF_MATCH_DCCP=m
CONFIG_IP_NF_MATCH_COMMENT=m
CONFIG_IP_NF_MATCH_CONNMARK=m
+CONFIG_IP_NF_MATCH_CONNBYTES=m
CONFIG_IP_NF_MATCH_HASHLIMIT=m
+CONFIG_IP_NF_MATCH_STRING=m
CONFIG_IP_NF_FILTER=m
CONFIG_IP_NF_TARGET_REJECT=m
CONFIG_IP_NF_TARGET_LOG=m
@@ -520,12 +380,14 @@ CONFIG_IP_NF_NAT_IRC=m
CONFIG_IP_NF_NAT_FTP=m
CONFIG_IP_NF_NAT_TFTP=m
CONFIG_IP_NF_NAT_AMANDA=m
+CONFIG_IP_NF_NAT_PPTP=m
CONFIG_IP_NF_MANGLE=m
CONFIG_IP_NF_TARGET_TOS=m
CONFIG_IP_NF_TARGET_ECN=m
CONFIG_IP_NF_TARGET_DSCP=m
CONFIG_IP_NF_TARGET_MARK=m
CONFIG_IP_NF_TARGET_CLASSIFY=m
+CONFIG_IP_NF_TARGET_TTL=m
CONFIG_IP_NF_TARGET_CONNMARK=m
CONFIG_IP_NF_TARGET_CLUSTERIP=m
CONFIG_IP_NF_RAW=m
@@ -535,7 +397,7 @@ CONFIG_IP_NF_ARPFILTER=m
CONFIG_IP_NF_ARP_MANGLE=m
#
-# IPv6: Netfilter Configuration
+# IPv6: Netfilter Configuration (EXPERIMENTAL)
#
CONFIG_IP6_NF_QUEUE=m
CONFIG_IP6_NF_IPTABLES=m
@@ -555,8 +417,10 @@ CONFIG_IP6_NF_MATCH_EUI64=m
CONFIG_IP6_NF_MATCH_PHYSDEV=m
CONFIG_IP6_NF_FILTER=m
CONFIG_IP6_NF_TARGET_LOG=m
+CONFIG_IP6_NF_TARGET_REJECT=m
CONFIG_IP6_NF_MANGLE=m
CONFIG_IP6_NF_TARGET_MARK=m
+CONFIG_IP6_NF_TARGET_HL=m
CONFIG_IP6_NF_RAW=m
#
@@ -582,8 +446,11 @@ CONFIG_BRIDGE_EBT_REDIRECT=m
CONFIG_BRIDGE_EBT_SNAT=m
CONFIG_BRIDGE_EBT_LOG=m
CONFIG_BRIDGE_EBT_ULOG=m
-CONFIG_XFRM=y
-CONFIG_XFRM_USER=m
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
#
# SCTP Configuration (EXPERIMENTAL)
@@ -611,10 +478,6 @@ CONFIG_IPDDP_DECAP=y
CONFIG_NET_DIVERT=y
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
CONFIG_NET_SCHED=y
CONFIG_NET_SCH_CLK_JIFFIES=y
# CONFIG_NET_SCH_CLK_GETTIMEOFDAY is not set
@@ -634,6 +497,7 @@ CONFIG_NET_SCH_INGRESS=m
CONFIG_NET_QOS=y
CONFIG_NET_ESTIMATOR=y
CONFIG_NET_CLS=y
+CONFIG_NET_CLS_BASIC=m
CONFIG_NET_CLS_TCINDEX=m
CONFIG_NET_CLS_ROUTE4=m
CONFIG_NET_CLS_ROUTE=y
@@ -644,6 +508,7 @@ CONFIG_NET_CLS_IND=y
# CONFIG_CLS_U32_MARK is not set
CONFIG_NET_CLS_RSVP=m
CONFIG_NET_CLS_RSVP6=m
+# CONFIG_NET_EMATCH is not set
# CONFIG_NET_CLS_ACT is not set
CONFIG_NET_CLS_POLICE=y
@@ -651,17 +516,254 @@ CONFIG_NET_CLS_POLICE=y
# Network testing
#
# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
# CONFIG_HAMRADIO is not set
# CONFIG_IRDA is not set
# CONFIG_BT is not set
+CONFIG_IEEE80211=m
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=m
+CONFIG_IEEE80211_CRYPT_CCMP=m
+CONFIG_IEEE80211_CRYPT_TKIP=m
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+CONFIG_CONNECTOR=m
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+
+#
+# Block devices
+#
+CONFIG_BLK_DEV_FD=m
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+CONFIG_BLK_DEV_UMEM=m
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=m
+CONFIG_BLK_DEV_CRYPTOLOOP=m
+CONFIG_BLK_DEV_NBD=m
+# CONFIG_BLK_DEV_SX8 is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=4096
+# CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_LBD is not set
+CONFIG_CDROM_PKTCDVD=m
+CONFIG_CDROM_PKTCDVD_BUFFERS=8
+# CONFIG_CDROM_PKTCDVD_WCACHE is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_ATA_OVER_ETH=m
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+CONFIG_IDE=y
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_IDE_SATA is not set
+CONFIG_BLK_DEV_IDEDISK=y
+# CONFIG_IDEDISK_MULTI_MODE is not set
+CONFIG_BLK_DEV_IDECD=y
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_BLK_DEV_IDEFLOPPY is not set
+# CONFIG_BLK_DEV_IDESCSI is not set
+# CONFIG_IDE_TASK_IOCTL is not set
+
+#
+# IDE chipset support/bugfixes
+#
+CONFIG_IDE_GENERIC=y
+CONFIG_BLK_DEV_IDEPCI=y
+# CONFIG_IDEPCI_SHARE_IRQ is not set
+# CONFIG_BLK_DEV_OFFBOARD is not set
+CONFIG_BLK_DEV_GENERIC=y
+# CONFIG_BLK_DEV_OPTI621 is not set
+CONFIG_BLK_DEV_IDEDMA_PCI=y
+# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
+CONFIG_IDEDMA_PCI_AUTO=y
+# CONFIG_IDEDMA_ONLYDISK is not set
+# CONFIG_BLK_DEV_AEC62XX is not set
+# CONFIG_BLK_DEV_ALI15X3 is not set
+# CONFIG_BLK_DEV_AMD74XX is not set
+# CONFIG_BLK_DEV_CMD64X is not set
+# CONFIG_BLK_DEV_TRIFLEX is not set
+# CONFIG_BLK_DEV_CY82C693 is not set
+# CONFIG_BLK_DEV_CS5520 is not set
+# CONFIG_BLK_DEV_CS5530 is not set
+# CONFIG_BLK_DEV_HPT34X is not set
+# CONFIG_BLK_DEV_HPT366 is not set
+# CONFIG_BLK_DEV_SC1200 is not set
+CONFIG_BLK_DEV_PIIX=y
+# CONFIG_BLK_DEV_IT821X is not set
+# CONFIG_BLK_DEV_NS87415 is not set
+# CONFIG_BLK_DEV_PDC202XX_OLD is not set
+# CONFIG_BLK_DEV_PDC202XX_NEW is not set
+# CONFIG_BLK_DEV_SVWKS is not set
+# CONFIG_BLK_DEV_SIIMAGE is not set
+# CONFIG_BLK_DEV_SLC90E66 is not set
+# CONFIG_BLK_DEV_TRM290 is not set
+# CONFIG_BLK_DEV_VIA82CXXX is not set
+# CONFIG_IDE_ARM is not set
+CONFIG_BLK_DEV_IDEDMA=y
+# CONFIG_IDEDMA_IVB is not set
+CONFIG_IDEDMA_AUTO=y
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI device support
+#
+CONFIG_RAID_ATTRS=m
+CONFIG_SCSI=m
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=m
+CONFIG_CHR_DEV_ST=m
+CONFIG_CHR_DEV_OSST=m
+CONFIG_BLK_DEV_SR=m
+CONFIG_BLK_DEV_SR_VENDOR=y
+CONFIG_CHR_DEV_SG=m
+# CONFIG_CHR_DEV_SCH is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+
+#
+# SCSI Transport Attributes
+#
+CONFIG_SCSI_SPI_ATTRS=m
+CONFIG_SCSI_FC_ATTRS=m
+CONFIG_SCSI_ISCSI_ATTRS=m
+CONFIG_SCSI_SAS_ATTRS=m
+
+#
+# SCSI low-level drivers
+#
+CONFIG_BLK_DEV_3W_XXXX_RAID=m
+CONFIG_SCSI_3W_9XXX=m
+CONFIG_SCSI_ACARD=m
+CONFIG_SCSI_AACRAID=m
+CONFIG_SCSI_AIC7XXX=m
+CONFIG_AIC7XXX_CMDS_PER_DEVICE=32
+CONFIG_AIC7XXX_RESET_DELAY_MS=15000
+# CONFIG_AIC7XXX_DEBUG_ENABLE is not set
+CONFIG_AIC7XXX_DEBUG_MASK=0
+CONFIG_AIC7XXX_REG_PRETTY_PRINT=y
+# CONFIG_SCSI_AIC7XXX_OLD is not set
+# CONFIG_SCSI_AIC79XX is not set
+# CONFIG_SCSI_DPT_I2O is not set
+# CONFIG_MEGARAID_NEWGEN is not set
+# CONFIG_MEGARAID_LEGACY is not set
+# CONFIG_SCSI_SATA is not set
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+# CONFIG_SCSI_IPS is not set
+# CONFIG_SCSI_INITIO is not set
+# CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_SYM53C8XX_2 is not set
+# CONFIG_SCSI_IPR is not set
+# CONFIG_SCSI_QLOGIC_FC is not set
+# CONFIG_SCSI_QLOGIC_1280 is not set
+CONFIG_SCSI_QLA2XXX=m
+# CONFIG_SCSI_QLA21XX is not set
+# CONFIG_SCSI_QLA22XX is not set
+# CONFIG_SCSI_QLA2300 is not set
+# CONFIG_SCSI_QLA2322 is not set
+# CONFIG_SCSI_QLA6312 is not set
+# CONFIG_SCSI_QLA24XX is not set
+# CONFIG_SCSI_LPFC is not set
+# CONFIG_SCSI_DC395x is not set
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_NSP32 is not set
+# CONFIG_SCSI_DEBUG is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+CONFIG_MD=y
+CONFIG_BLK_DEV_MD=m
+CONFIG_MD_LINEAR=m
+CONFIG_MD_RAID0=m
+CONFIG_MD_RAID1=m
+CONFIG_MD_RAID10=m
+CONFIG_MD_RAID5=m
+CONFIG_MD_RAID6=m
+CONFIG_MD_MULTIPATH=m
+CONFIG_MD_FAULTY=m
+CONFIG_BLK_DEV_DM=m
+CONFIG_DM_CRYPT=m
+CONFIG_DM_SNAPSHOT=m
+CONFIG_DM_MIRROR=m
+CONFIG_DM_ZERO=m
+CONFIG_DM_MULTIPATH=m
+CONFIG_DM_MULTIPATH_EMC=m
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+# CONFIG_FUSION_SPI is not set
+# CONFIG_FUSION_FC is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+
+#
+# Network device support
+#
CONFIG_NETDEVICES=y
CONFIG_DUMMY=m
CONFIG_BONDING=m
CONFIG_EQUALIZER=m
CONFIG_TUN=m
-# CONFIG_ETHERTAP is not set
#
# ARCnet devices
@@ -669,6 +771,21 @@ CONFIG_TUN=m
# CONFIG_ARCNET is not set
#
+# PHY device support
+#
+CONFIG_PHYLIB=m
+CONFIG_PHYCONTROL=y
+
+#
+# MII PHY device drivers
+#
+CONFIG_MARVELL_PHY=m
+CONFIG_DAVICOM_PHY=m
+CONFIG_QSEMI_PHY=m
+CONFIG_LXT_PHY=m
+CONFIG_CICADA_PHY=m
+
+#
# Ethernet (10 or 100Mbit)
#
CONFIG_NET_ETHERNET=y
@@ -713,13 +830,17 @@ CONFIG_PCNET32=y
# CONFIG_HAMACHI is not set
# CONFIG_YELLOWFIN is not set
# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
# CONFIG_SK98LIN is not set
# CONFIG_VIA_VELOCITY is not set
# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
#
# Ethernet (10000 Mbit)
#
+# CONFIG_CHELSIO_T1 is not set
# CONFIG_IXGB is not set
# CONFIG_S2IO is not set
@@ -732,6 +853,8 @@ CONFIG_PCNET32=y
# Wireless LAN (non-hamradio)
#
# CONFIG_NET_RADIO is not set
+# CONFIG_IPW_DEBUG is not set
+CONFIG_IPW2200=m
#
# Wan interfaces
@@ -744,6 +867,8 @@ CONFIG_PCNET32=y
# CONFIG_NET_FC is not set
# CONFIG_SHAPER is not set
# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
#
# ISDN subsystem
@@ -773,19 +898,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
# CONFIG_INPUT_EVBUG is not set
#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=y
-# CONFIG_SERIO_I8042 is not set
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_PCIPS2 is not set
-# CONFIG_SERIO_LIBPS2 is not set
-# CONFIG_SERIO_RAW is not set
-
-#
# Input Device Drivers
#
# CONFIG_INPUT_KEYBOARD is not set
@@ -795,6 +907,17 @@ CONFIG_SERIO_SERPORT=y
# CONFIG_INPUT_MISC is not set
#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_PCIPS2 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
@@ -815,6 +938,7 @@ CONFIG_SERIAL_8250_NR_UARTS=4
#
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
CONFIG_UNIX98_PTYS=y
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
@@ -840,6 +964,11 @@ CONFIG_RTC=y
# CONFIG_RAW_DRIVER is not set
#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+
+#
# I2C support
#
# CONFIG_I2C is not set
@@ -850,10 +979,20 @@ CONFIG_RTC=y
# CONFIG_W1 is not set
#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
+#
# Misc devices
#
#
+# Multimedia Capabilities Port drivers
+#
+
+#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
@@ -873,7 +1012,6 @@ CONFIG_RTC=y
#
# CONFIG_VGA_CONSOLE is not set
CONFIG_DUMMY_CONSOLE=y
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Sound
@@ -883,13 +1021,9 @@ CONFIG_DUMMY_CONSOLE=y
#
# USB support
#
-# CONFIG_USB is not set
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB_ARCH_HAS_OHCI=y
-
-#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
-#
+# CONFIG_USB is not set
#
# USB Gadget Support
@@ -907,10 +1041,15 @@ CONFIG_USB_ARCH_HAS_OHCI=y
# CONFIG_INFINIBAND is not set
#
+# SN Devices
+#
+
+#
# File systems
#
CONFIG_EXT2_FS=y
# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
CONFIG_EXT3_FS=y
CONFIG_EXT3_FS_XATTR=y
# CONFIG_EXT3_FS_POSIX_ACL is not set
@@ -931,12 +1070,14 @@ CONFIG_JFS_SECURITY=y
# CONFIG_JFS_STATISTICS is not set
CONFIG_FS_POSIX_ACL=y
CONFIG_XFS_FS=m
-# CONFIG_XFS_RT is not set
-CONFIG_XFS_QUOTA=y
+CONFIG_XFS_EXPORT=y
+CONFIG_XFS_QUOTA=m
CONFIG_XFS_SECURITY=y
CONFIG_XFS_POSIX_ACL=y
+# CONFIG_XFS_RT is not set
CONFIG_MINIX_FS=m
CONFIG_ROMFS_FS=m
+CONFIG_INOTIFY=y
CONFIG_QUOTA=y
# CONFIG_QFMT_V1 is not set
CONFIG_QFMT_V2=y
@@ -944,6 +1085,7 @@ CONFIG_QUOTACTL=y
CONFIG_DNOTIFY=y
CONFIG_AUTOFS_FS=y
# CONFIG_AUTOFS4_FS is not set
+CONFIG_FUSE_FS=m
#
# CD-ROM/DVD Filesystems
@@ -971,12 +1113,10 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
-CONFIG_DEVPTS_FS_XATTR=y
-CONFIG_DEVPTS_FS_SECURITY=y
# CONFIG_TMPFS is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
+CONFIG_RELAYFS_FS=m
#
# Miscellaneous filesystems
@@ -1002,16 +1142,19 @@ CONFIG_UFS_FS=m
#
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
# CONFIG_NFS_V4 is not set
# CONFIG_NFS_DIRECTIO is not set
CONFIG_NFSD=y
CONFIG_NFSD_V3=y
+# CONFIG_NFSD_V3_ACL is not set
# CONFIG_NFSD_V4 is not set
# CONFIG_NFSD_TCP is not set
CONFIG_ROOT_NFS=y
CONFIG_LOCKD=y
CONFIG_LOCKD_V4=y
CONFIG_EXPORTFS=y
+CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
@@ -1020,6 +1163,7 @@ CONFIG_SUNRPC=y
# CONFIG_NCP_FS is not set
# CONFIG_CODA_FS is not set
# CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
#
# Partition Types
@@ -1079,7 +1223,9 @@ CONFIG_NLS_UTF8=m
#
# Kernel hacking
#
+# CONFIG_PRINTK_TIME is not set
# CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=14
CONFIG_CROSSCOMPILE=y
CONFIG_CMDLINE=""
@@ -1101,6 +1247,7 @@ CONFIG_CRYPTO_SHA1=m
CONFIG_CRYPTO_SHA256=m
CONFIG_CRYPTO_SHA512=m
CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_TGR192=m
CONFIG_CRYPTO_DES=m
CONFIG_CRYPTO_BLOWFISH=m
CONFIG_CRYPTO_TWOFISH=m
@@ -1125,9 +1272,12 @@ CONFIG_CRYPTO_CRC32C=m
# Library routines
#
# CONFIG_CRC_CCITT is not set
+CONFIG_CRC16=m
CONFIG_CRC32=y
CONFIG_LIBCRC32C=m
CONFIG_ZLIB_INFLATE=m
CONFIG_ZLIB_DEFLATE=m
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_TEXTSEARCH=y
+CONFIG_TEXTSEARCH_KMP=m
+CONFIG_TEXTSEARCH_BM=m
+CONFIG_TEXTSEARCH_FSM=m
diff --git a/arch/mips/configs/mipssim_defconfig b/arch/mips/configs/mipssim_defconfig
new file mode 100644
index 000000000000..fb9bdd9e3151
--- /dev/null
+++ b/arch/mips/configs/mipssim_defconfig
@@ -0,0 +1,775 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.14-rc2
+# Thu Oct 20 22:26:25 2005
+#
+CONFIG_MIPS=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_HOTPLUG=y
+CONFIG_KOBJECT_UEVENT=y
+# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_OBSOLETE_MODPARM=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_KMOD=y
+
+#
+# Machine selection
+#
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_MIPS_PB1550 is not set
+# CONFIG_MIPS_PB1200 is not set
+# CONFIG_MIPS_DB1000 is not set
+# CONFIG_MIPS_DB1100 is not set
+# CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
+# CONFIG_MIPS_DB1200 is not set
+# CONFIG_MIPS_MIRAGE is not set
+# CONFIG_MIPS_COBALT is not set
+# CONFIG_MACH_DECSTATION is not set
+# CONFIG_MIPS_EV64120 is not set
+# CONFIG_MIPS_EV96100 is not set
+# CONFIG_MIPS_IVR is not set
+# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_LASAT is not set
+# CONFIG_MIPS_ATLAS is not set
+# CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SEAD is not set
+CONFIG_MIPS_SIM=y
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_MOMENCO_OCELOT_3 is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MIPS_XXS1500 is not set
+# CONFIG_PNX8550_V2PCI is not set
+# CONFIG_PNX8550_JBS is not set
+# CONFIG_DDB5074 is not set
+# CONFIG_DDB5476 is not set
+# CONFIG_DDB5477 is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_QEMU is not set
+# CONFIG_SGI_IP22 is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_BIGSUR is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_PTSWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CRHONE is not set
+# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_TOSHIBA_RBTX4927 is not set
+# CONFIG_TOSHIBA_RBTX4938 is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_DMA_NONCOHERENT=y
+CONFIG_DMA_NEED_PCI_MAP_STATE=y
+# CONFIG_CPU_BIG_ENDIAN is not set
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
+CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
+CONFIG_IRQ_CPU=y
+CONFIG_MIPS_L1_CACHE_SHIFT=5
+
+#
+# CPU selection
+#
+CONFIG_CPU_MIPS32_R1=y
+# CONFIG_CPU_MIPS32_R2 is not set
+# CONFIG_CPU_MIPS64_R1 is not set
+# CONFIG_CPU_MIPS64_R2 is not set
+# CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_TX39XX is not set
+# CONFIG_CPU_VR41XX is not set
+# CONFIG_CPU_R4300 is not set
+# CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_TX49XX is not set
+# CONFIG_CPU_R5000 is not set
+# CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_R6000 is not set
+# CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
+# CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_RM7000 is not set
+# CONFIG_CPU_RM9000 is not set
+# CONFIG_CPU_SB1 is not set
+CONFIG_SYS_HAS_CPU_MIPS32_R1=y
+CONFIG_SYS_HAS_CPU_MIPS32_R2=y
+CONFIG_CPU_MIPS32=y
+CONFIG_CPU_MIPSR1=y
+CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
+
+#
+# Kernel type
+#
+CONFIG_32BIT=y
+# CONFIG_64BIT is not set
+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_CPU_HAS_PREFETCH=y
+CONFIG_MIPS_MT=y
+# CONFIG_MIPS_MT_SMP is not set
+CONFIG_MIPS_VPE_LOADER=y
+CONFIG_MIPS_VPE_LOADER_TOM=y
+CONFIG_MIPS_VPE_APSP_API=y
+# CONFIG_64BIT_PHYS_ADDR is not set
+# CONFIG_CPU_ADVANCED is not set
+CONFIG_CPU_HAS_LLSC=y
+CONFIG_CPU_HAS_SYNC=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_ARCH_FLATMEM_ENABLE=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_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+
+#
+# Bus options (PCI, PCMCIA, EISA, ISA, TC)
+#
+CONFIG_MMU=y
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PCI Hotplug Support
+#
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+CONFIG_TRAD_SIGNALS=y
+
+#
+# Networking
+#
+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_NET_KEY=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_ASK_IP_FIB_HASH=y
+# CONFIG_IP_FIB_TRIE is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IP_ROUTE_MULTIPATH=y
+# CONFIG_IP_ROUTE_MULTIPATH_CACHED is not set
+CONFIG_IP_ROUTE_VERBOSE=y
+CONFIG_IP_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_TUNNEL is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+# CONFIG_IPV6 is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+CONFIG_IP_SCTP=m
+# CONFIG_SCTP_DBG_MSG is not set
+# CONFIG_SCTP_DBG_OBJCNT is not set
+# CONFIG_SCTP_HMAC_NONE is not set
+# CONFIG_SCTP_HMAC_SHA1 is not set
+CONFIG_SCTP_HMAC_MD5=y
+# 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_NET_DIVERT=y
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+CONFIG_NET_SCHED=y
+CONFIG_NET_SCH_CLK_JIFFIES=y
+# CONFIG_NET_SCH_CLK_GETTIMEOFDAY is not set
+# CONFIG_NET_SCH_CLK_CPU is not set
+CONFIG_NET_SCH_CBQ=m
+CONFIG_NET_SCH_HTB=m
+CONFIG_NET_SCH_HFSC=m
+CONFIG_NET_SCH_PRIO=m
+CONFIG_NET_SCH_RED=m
+CONFIG_NET_SCH_SFQ=m
+CONFIG_NET_SCH_TEQL=m
+CONFIG_NET_SCH_TBF=m
+CONFIG_NET_SCH_GRED=m
+CONFIG_NET_SCH_DSMARK=m
+CONFIG_NET_SCH_NETEM=m
+CONFIG_NET_SCH_INGRESS=m
+CONFIG_NET_QOS=y
+CONFIG_NET_ESTIMATOR=y
+CONFIG_NET_CLS=y
+CONFIG_NET_CLS_BASIC=m
+CONFIG_NET_CLS_TCINDEX=m
+CONFIG_NET_CLS_ROUTE4=m
+CONFIG_NET_CLS_ROUTE=y
+# CONFIG_NET_CLS_FW is not set
+# CONFIG_NET_CLS_U32 is not set
+# CONFIG_NET_CLS_RSVP is not set
+# CONFIG_NET_CLS_RSVP6 is not set
+# CONFIG_NET_EMATCH is not set
+# CONFIG_NET_CLS_ACT is not set
+# CONFIG_NET_CLS_POLICE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+# CONFIG_STANDALONE is not set
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+# CONFIG_FW_LOADER is not set
+# CONFIG_DEBUG_DRIVER is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+CONFIG_BLK_DEV_NBD=y
+# CONFIG_BLK_DEV_RAM is not set
+CONFIG_BLK_DEV_RAM_COUNT=16
+# CONFIG_LBD is not set
+# CONFIG_CDROM_PKTCDVD is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_ATA_OVER_ETH is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+
+#
+# I2O device support
+#
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+
+#
+# PHY device support
+#
+
+#
+# Ethernet (10 or 100Mbit)
+#
+# CONFIG_NET_ETHERNET is not set
+# CONFIG_MIPS_SIM_NET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+
+#
+# Ethernet (10000 Mbit)
+#
+
+#
+# Token Ring devices
+#
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+
+#
+# Userland interfaces
+#
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_LIBPS2 is not set
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=1
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_RTC is not set
+# CONFIG_GEN_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_RAW_DRIVER is not set
+
+#
+# TPM devices
+#
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
+#
+# Misc devices
+#
+
+#
+# Multimedia Capabilities Port drivers
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+# CONFIG_FB is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB_ARCH_HAS_HCD is not set
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# InfiniBand support
+#
+
+#
+# SN Devices
+#
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD 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_MINIX_FS is not set
+CONFIG_ROMFS_FS=y
+# CONFIG_INOTIFY is not set
+# CONFIG_QUOTA is not set
+# CONFIG_DNOTIFY is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+# CONFIG_PROC_KCORE is not set
+# CONFIG_SYSFS is not set
+# CONFIG_TMPFS is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+# CONFIG_RELAYFS_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_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFS_DIRECTIO is not set
+# CONFIG_NFSD is not set
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_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
+# CONFIG_9P_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+
+#
+# Native Language Support
+#
+# CONFIG_NLS is not set
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_MAGIC_SYSRQ is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_DETECT_SOFTLOCKUP is not set
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_INFO=y
+CONFIG_CROSSCOMPILE=y
+CONFIG_CMDLINE="nfsroot=192.168.192.169:/u1/mipsel,timeo=20 ip=dhcp"
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_KGDB is not set
+# CONFIG_RUNTIME_DEBUG is not set
+# CONFIG_MIPS_UNCACHED is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+
+#
+# Cryptographic options
+#
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_HMAC=y
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_MD4 is not set
+CONFIG_CRYPTO_MD5=y
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_WP512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_DES is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Hardware crypto devices
+#
+
+#
+# Library routines
+#
+# CONFIG_CRC_CCITT is not set
+CONFIG_CRC16=y
+CONFIG_CRC32=y
+# CONFIG_LIBCRC32C is not set
diff --git a/arch/mips/configs/mpc30x_defconfig b/arch/mips/configs/mpc30x_defconfig
index 0fea57ef18f2..e2c082128532 100644
--- a/arch/mips/configs/mpc30x_defconfig
+++ b/arch/mips/configs/mpc30x_defconfig
@@ -1,12 +1,9 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-rc2
-# Wed Jan 26 02:49:07 2005
+# Linux kernel version: 2.6.14-rc2
+# Thu Oct 20 22:26:28 2005
#
CONFIG_MIPS=y
-# CONFIG_64BIT is not set
-# CONFIG_64BIT is not set
-CONFIG_32BIT=y
#
# Code maturity level options
@@ -14,24 +11,29 @@ CONFIG_32BIT=y
CONFIG_EXPERIMENTAL=y
CONFIG_CLEAN_COMPILE=y
CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
#
# General setup
#
CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
# CONFIG_POSIX_MQUEUE is not set
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_HOTPLUG is not set
+CONFIG_HOTPLUG=y
CONFIG_KOBJECT_UEVENT=y
# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
CONFIG_EMBEDDED=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
@@ -41,6 +43,7 @@ CONFIG_CC_ALIGN_LABELS=0
CONFIG_CC_ALIGN_LOOPS=0
CONFIG_CC_ALIGN_JUMPS=0
# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
#
# Loadable module support
@@ -56,57 +59,86 @@ CONFIG_KMOD=y
#
# Machine selection
#
-# CONFIG_MACH_JAZZ is not set
-CONFIG_MACH_VR41XX=y
-# CONFIG_NEC_CMBVR4133 is not set
-# CONFIG_CASIO_E55 is not set
-# CONFIG_IBM_WORKPAD is not set
-# CONFIG_TANBAC_TB0226 is not set
-# CONFIG_TANBAC_TB0229 is not set
-CONFIG_VICTOR_MPC30X=y
-# CONFIG_ZAO_CAPCELLA is not set
-CONFIG_PCI_VR41XX=y
-CONFIG_VRC4173=y
-# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_MIPS_PB1550 is not set
+# CONFIG_MIPS_PB1200 is not set
+# CONFIG_MIPS_DB1000 is not set
+# CONFIG_MIPS_DB1100 is not set
+# CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
+# CONFIG_MIPS_DB1200 is not set
+# CONFIG_MIPS_MIRAGE is not set
# CONFIG_MIPS_COBALT is not set
# CONFIG_MACH_DECSTATION is not set
# CONFIG_MIPS_EV64120 is not set
# CONFIG_MIPS_EV96100 is not set
# CONFIG_MIPS_IVR is not set
-# CONFIG_LASAT is not set
# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_LASAT is not set
# CONFIG_MIPS_ATLAS is not set
# CONFIG_MIPS_MALTA is not set
# CONFIG_MIPS_SEAD is not set
+# CONFIG_MIPS_SIM is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
# CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_G is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_JAGUAR_ATX is not set
-# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MIPS_XXS1500 is not set
+# CONFIG_PNX8550_V2PCI is not set
+# CONFIG_PNX8550_JBS is not set
# CONFIG_DDB5074 is not set
# CONFIG_DDB5476 is not set
# CONFIG_DDB5477 is not set
-# CONFIG_NEC_OSPREY is not set
+CONFIG_MACH_VR41XX=y
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_QEMU is not set
# CONFIG_SGI_IP22 is not set
-# CONFIG_SOC_AU1X00 is not set
-# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_BIGSUR is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_PTSWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CRHONE is not set
# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
# CONFIG_TOSHIBA_RBTX4927 is not set
+# CONFIG_TOSHIBA_RBTX4938 is not set
+# CONFIG_NEC_CMBVR4133 is not set
+# CONFIG_CASIO_E55 is not set
+# CONFIG_IBM_WORKPAD is not set
+# CONFIG_TANBAC_TB022X is not set
+CONFIG_VICTOR_MPC30X=y
+# CONFIG_ZAO_CAPCELLA is not set
+CONFIG_PCI_VR41XX=y
+CONFIG_VRC4173=y
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_HAVE_DEC_LOCK=y
CONFIG_DMA_NONCOHERENT=y
CONFIG_DMA_NEED_PCI_MAP_STATE=y
+# CONFIG_CPU_BIG_ENDIAN is not set
CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
CONFIG_IRQ_CPU=y
CONFIG_MIPS_L1_CACHE_SHIFT=5
#
# CPU selection
#
-# CONFIG_CPU_MIPS32 is not set
-# CONFIG_CPU_MIPS64 is not set
+# CONFIG_CPU_MIPS32_R1 is not set
+# CONFIG_CPU_MIPS32_R2 is not set
+# CONFIG_CPU_MIPS64_R1 is not set
+# CONFIG_CPU_MIPS64_R2 is not set
# CONFIG_CPU_R3000 is not set
# CONFIG_CPU_TX39XX is not set
CONFIG_CPU_VR41XX=y
@@ -122,12 +154,36 @@ CONFIG_CPU_VR41XX=y
# CONFIG_CPU_RM7000 is not set
# CONFIG_CPU_RM9000 is not set
# CONFIG_CPU_SB1 is not set
+CONFIG_SYS_HAS_CPU_VR41XX=y
+CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
+CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y
+
+#
+# Kernel type
+#
+CONFIG_32BIT=y
+# CONFIG_64BIT is not set
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_MIPS_MT is not set
# CONFIG_CPU_ADVANCED is not set
CONFIG_CPU_HAS_SYNC=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_ARCH_FLATMEM_ENABLE=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_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
#
@@ -136,17 +192,26 @@ CONFIG_CPU_HAS_SYNC=y
CONFIG_HW_HAS_PCI=y
CONFIG_PCI=y
CONFIG_PCI_LEGACY_PROC=y
-CONFIG_PCI_NAMES=y
CONFIG_MMU=y
#
# PCCARD (PCMCIA/CardBus) support
#
-# CONFIG_PCCARD is not set
+CONFIG_PCCARD=y
+# CONFIG_PCMCIA_DEBUG is not set
+CONFIG_PCMCIA=y
+CONFIG_PCMCIA_LOAD_CIS=y
+CONFIG_PCMCIA_IOCTL=y
+# CONFIG_CARDBUS is not set
#
# PC-card bridges
#
+# CONFIG_YENTA is not set
+# CONFIG_PD6729 is not set
+# CONFIG_I82092 is not set
+# CONFIG_TCIC is not set
+CONFIG_PCMCIA_VRC4173=y
#
# PCI Hotplug Support
@@ -161,6 +226,78 @@ CONFIG_BINFMT_ELF=y
CONFIG_TRAD_SIGNALS=y
#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+CONFIG_NET_KEY=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+# CONFIG_IP_PNP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+CONFIG_INET_TUNNEL=m
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+# CONFIG_IPV6 is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# 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_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_IEEE80211=m
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=m
+CONFIG_IEEE80211_CRYPT_CCMP=m
+CONFIG_IEEE80211_CRYPT_TKIP=m
+
+#
# Device Drivers
#
@@ -169,7 +306,12 @@ CONFIG_TRAD_SIGNALS=y
#
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
+CONFIG_FW_LOADER=y
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+CONFIG_CONNECTOR=m
#
# Memory Technology Devices (MTD)
@@ -188,7 +330,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
#
# Block devices
#
-# CONFIG_BLK_DEV_FD is not set
# CONFIG_BLK_CPQ_DA is not set
# CONFIG_BLK_CPQ_CISS_DA is not set
# CONFIG_BLK_DEV_DAC960 is not set
@@ -197,13 +338,11 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_BLK_DEV_LOOP is not set
# CONFIG_BLK_DEV_NBD is not set
# CONFIG_BLK_DEV_SX8 is not set
+# CONFIG_BLK_DEV_UB is not set
# CONFIG_BLK_DEV_RAM is not set
CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_INITRAMFS_SOURCE=""
# CONFIG_LBD is not set
-CONFIG_CDROM_PKTCDVD=m
-CONFIG_CDROM_PKTCDVD_BUFFERS=8
-# CONFIG_CDROM_PKTCDVD_WCACHE is not set
+# CONFIG_CDROM_PKTCDVD is not set
#
# IO Schedulers
@@ -217,11 +356,35 @@ CONFIG_ATA_OVER_ETH=m
#
# ATA/ATAPI/MFM/RLL support
#
-# CONFIG_IDE is not set
+CONFIG_IDE=y
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_IDE_SATA is not set
+CONFIG_BLK_DEV_IDEDISK=y
+# CONFIG_IDEDISK_MULTI_MODE is not set
+CONFIG_BLK_DEV_IDECS=m
+# CONFIG_BLK_DEV_IDECD is not set
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_BLK_DEV_IDEFLOPPY is not set
+# CONFIG_IDE_TASK_IOCTL is not set
+
+#
+# IDE chipset support/bugfixes
+#
+CONFIG_IDE_GENERIC=y
+# CONFIG_BLK_DEV_IDEPCI is not set
+# CONFIG_IDE_ARM is not set
+# CONFIG_BLK_DEV_IDEDMA is not set
+# CONFIG_IDEDMA_AUTO is not set
+# CONFIG_BLK_DEV_HD is not set
#
# SCSI device support
#
+# CONFIG_RAID_ATTRS is not set
# CONFIG_SCSI is not set
#
@@ -232,6 +395,7 @@ CONFIG_ATA_OVER_ETH=m
#
# Fusion MPT device support
#
+# CONFIG_FUSION is not set
#
# IEEE 1394 (FireWire) support
@@ -244,79 +408,13 @@ CONFIG_ATA_OVER_ETH=m
# CONFIG_I2O is not set
#
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
-CONFIG_NETLINK_DEV=y
-CONFIG_UNIX=y
-CONFIG_NET_KEY=y
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-# CONFIG_IP_ADVANCED_ROUTER is not set
-CONFIG_IP_PNP=y
-# CONFIG_IP_PNP_DHCP is not set
-CONFIG_IP_PNP_BOOTP=y
-# CONFIG_IP_PNP_RARP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_IP_MROUTE is not set
-# CONFIG_ARPD is not set
-# CONFIG_SYN_COOKIES is not set
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-CONFIG_INET_TUNNEL=m
-CONFIG_IP_TCPDIAG=m
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-# CONFIG_IPV6 is not set
-# CONFIG_NETFILTER is not set
-CONFIG_XFRM=y
-CONFIG_XFRM_USER=m
-
-#
-# SCTP Configuration (EXPERIMENTAL)
+# Network device support
#
-# CONFIG_IP_SCTP 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_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
CONFIG_NETDEVICES=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_EQUALIZER is not set
# CONFIG_TUN is not set
-# CONFIG_ETHERTAP is not set
#
# ARCnet devices
@@ -324,20 +422,14 @@ CONFIG_NETDEVICES=y
# CONFIG_ARCNET is not set
#
-# Ethernet (10 or 100Mbit)
+# PHY device support
#
-CONFIG_NET_ETHERNET=y
-# CONFIG_MII is not set
-# CONFIG_HAPPYMEAL is not set
-# CONFIG_SUNGEM is not set
-# CONFIG_NET_VENDOR_3COM is not set
#
-# Tulip family network device support
+# Ethernet (10 or 100Mbit)
#
-# CONFIG_NET_TULIP is not set
-# CONFIG_HP100 is not set
-# CONFIG_NET_PCI is not set
+# CONFIG_NET_ETHERNET is not set
+CONFIG_MII=m
#
# Ethernet (1000 Mbit)
@@ -349,12 +441,16 @@ CONFIG_NET_ETHERNET=y
# CONFIG_HAMACHI is not set
# CONFIG_YELLOWFIN is not set
# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
# CONFIG_SK98LIN is not set
# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
#
# Ethernet (10000 Mbit)
#
+# CONFIG_CHELSIO_T1 is not set
# CONFIG_IXGB is not set
# CONFIG_S2IO is not set
@@ -366,7 +462,59 @@ CONFIG_NET_ETHERNET=y
#
# Wireless LAN (non-hamradio)
#
-# CONFIG_NET_RADIO is not set
+CONFIG_NET_RADIO=y
+
+#
+# Obsolete Wireless cards support (pre-802.11)
+#
+# CONFIG_STRIP is not set
+# CONFIG_PCMCIA_WAVELAN is not set
+# CONFIG_PCMCIA_NETWAVE is not set
+
+#
+# Wireless 802.11 Frequency Hopping cards support
+#
+# CONFIG_PCMCIA_RAYCS is not set
+
+#
+# Wireless 802.11b ISA/PCI cards support
+#
+# CONFIG_IPW2100 is not set
+# CONFIG_IPW2200 is not set
+CONFIG_HERMES=m
+# CONFIG_PLX_HERMES is not set
+# CONFIG_TMD_HERMES is not set
+# CONFIG_NORTEL_HERMES is not set
+# CONFIG_PCI_HERMES is not set
+# CONFIG_ATMEL is not set
+
+#
+# Wireless 802.11b Pcmcia/Cardbus cards support
+#
+CONFIG_PCMCIA_HERMES=m
+# CONFIG_PCMCIA_SPECTRUM is not set
+# CONFIG_AIRO_CS is not set
+# CONFIG_PCMCIA_WL3501 is not set
+
+#
+# Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support
+#
+# CONFIG_PRISM54 is not set
+# CONFIG_HOSTAP is not set
+CONFIG_NET_WIRELESS=y
+
+#
+# PCMCIA network device support
+#
+CONFIG_NET_PCMCIA=y
+CONFIG_PCMCIA_3C589=m
+CONFIG_PCMCIA_3C574=m
+CONFIG_PCMCIA_FMVJ18X=m
+CONFIG_PCMCIA_PCNET=m
+CONFIG_PCMCIA_NMCLAN=m
+CONFIG_PCMCIA_SMC91C92=m
+CONFIG_PCMCIA_XIRC2PS=m
+CONFIG_PCMCIA_AXNET=m
#
# Wan interfaces
@@ -378,6 +526,8 @@ CONFIG_NET_ETHERNET=y
# CONFIG_SLIP is not set
# CONFIG_SHAPER is not set
# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
#
# ISDN subsystem
@@ -407,19 +557,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
# CONFIG_INPUT_EVBUG is not set
#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=y
-CONFIG_SERIO_I8042=y
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_PCIPS2 is not set
-# CONFIG_SERIO_LIBPS2 is not set
-CONFIG_SERIO_RAW=m
-
-#
# Input Device Drivers
#
# CONFIG_INPUT_KEYBOARD is not set
@@ -429,6 +566,17 @@ CONFIG_SERIO_RAW=m
# CONFIG_INPUT_MISC is not set
#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_PCIPS2 is not set
+# CONFIG_SERIO_LIBPS2 is not set
+CONFIG_SERIO_RAW=m
+# CONFIG_GAMEPORT is not set
+
+#
# Character devices
#
CONFIG_VT=y
@@ -439,16 +587,16 @@ CONFIG_HW_CONSOLE=y
#
# Serial drivers
#
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_NR_UARTS=4
-# CONFIG_SERIAL_8250_EXTENDED is not set
+# CONFIG_SERIAL_8250 is not set
#
# Non-8250 serial port support
#
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_SERIAL_VR41XX=y
+CONFIG_SERIAL_VR41XX_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
CONFIG_UNIX98_PTYS=y
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
@@ -472,9 +620,20 @@ CONFIG_LEGACY_PTY_COUNT=256
# Ftape, the floppy tape device driver
#
# CONFIG_DRM is not set
+
+#
+# PCMCIA character devices
+#
+# CONFIG_SYNCLINK_CS is not set
+CONFIG_GPIO_VR41XX=y
# CONFIG_RAW_DRIVER is not set
#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+
+#
# I2C support
#
# CONFIG_I2C is not set
@@ -485,10 +644,20 @@ CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_W1 is not set
#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
+#
# Misc devices
#
#
+# Multimedia Capabilities Port drivers
+#
+
+#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
@@ -508,7 +677,6 @@ CONFIG_LEGACY_PTY_COUNT=256
#
# CONFIG_VGA_CONSOLE is not set
CONFIG_DUMMY_CONSOLE=y
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Sound
@@ -518,13 +686,120 @@ CONFIG_DUMMY_CONSOLE=y
#
# USB support
#
-# CONFIG_USB is not set
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB=m
+# CONFIG_USB_DEBUG is not set
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+# CONFIG_USB_BANDWIDTH is not set
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_OTG is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_EHCI_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
+CONFIG_USB_OHCI_HCD=m
+# CONFIG_USB_OHCI_BIG_ENDIAN is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+# CONFIG_USB_UHCI_HCD is not set
+# CONFIG_USB_SL811_HCD is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_BLUETOOTH_TTY is not set
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
#
# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
#
+# CONFIG_USB_STORAGE is not set
+
+#
+# USB Input Devices
+#
+# CONFIG_USB_HID is not set
+
+#
+# USB HID Boot Protocol drivers
+#
+# CONFIG_USB_KBD is not set
+# CONFIG_USB_MOUSE is not set
+# CONFIG_USB_AIPTEK is not set
+# CONFIG_USB_WACOM is not set
+# CONFIG_USB_ACECAD is not set
+# CONFIG_USB_KBTAB is not set
+# CONFIG_USB_POWERMATE is not set
+# CONFIG_USB_MTOUCH is not set
+# CONFIG_USB_ITMTOUCH is not set
+# CONFIG_USB_EGALAX is not set
+# CONFIG_USB_YEALINK is not set
+# CONFIG_USB_XPAD is not set
+# CONFIG_USB_ATI_REMOTE is not set
+# CONFIG_USB_KEYSPAN_REMOTE is not set
+# CONFIG_USB_APPLETOUCH is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+
+#
+# USB Multimedia devices
+#
+# CONFIG_USB_DABUSB is not set
+
+#
+# Video4Linux support is needed for USB Multimedia device support
+#
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+CONFIG_USB_PEGASUS=m
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET is not set
+# CONFIG_USB_ZD1201 is not set
+# CONFIG_USB_MON is not set
+
+#
+# USB port drivers
+#
+
+#
+# USB Serial Converter support
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_AUERSWALD is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_PHIDGETKIT is not set
+# CONFIG_USB_PHIDGETSERVO is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TEST is not set
+
+#
+# USB DSL modem support
+#
#
# USB Gadget Support
@@ -542,21 +817,29 @@ CONFIG_USB_ARCH_HAS_OHCI=y
# CONFIG_INFINIBAND is not set
#
+# SN Devices
+#
+
+#
# File systems
#
CONFIG_EXT2_FS=y
# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
# CONFIG_EXT3_FS is not set
# CONFIG_JBD 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_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
# CONFIG_QUOTA is not set
CONFIG_DNOTIFY=y
CONFIG_AUTOFS_FS=y
CONFIG_AUTOFS4_FS=y
+CONFIG_FUSE_FS=m
#
# CD-ROM/DVD Filesystems
@@ -577,12 +860,10 @@ CONFIG_AUTOFS4_FS=y
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
-CONFIG_DEVPTS_FS_XATTR=y
-CONFIG_DEVPTS_FS_SECURITY=y
# CONFIG_TMPFS is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
+CONFIG_RELAYFS_FS=m
#
# Miscellaneous filesystems
@@ -609,9 +890,8 @@ CONFIG_NFS_FS=y
# CONFIG_NFS_V4 is not set
# CONFIG_NFS_DIRECTIO is not set
# CONFIG_NFSD is not set
-CONFIG_ROOT_NFS=y
CONFIG_LOCKD=y
-# CONFIG_EXPORTFS is not set
+CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
@@ -620,6 +900,7 @@ CONFIG_SUNRPC=y
# CONFIG_NCP_FS is not set
# CONFIG_CODA_FS is not set
# CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
#
# Partition Types
@@ -640,9 +921,11 @@ CONFIG_MSDOS_PARTITION=y
#
# Kernel hacking
#
+# CONFIG_PRINTK_TIME is not set
# CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=14
CONFIG_CROSSCOMPILE=y
-CONFIG_CMDLINE=""
+CONFIG_CMDLINE="mem=32M console=ttyVR0,19200"
#
# Security options
@@ -656,26 +939,27 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
#
CONFIG_CRYPTO=y
CONFIG_CRYPTO_HMAC=y
-CONFIG_CRYPTO_NULL=y
-# CONFIG_CRYPTO_MD4 is not set
-# CONFIG_CRYPTO_MD5 is not set
-# CONFIG_CRYPTO_SHA1 is not set
-# CONFIG_CRYPTO_SHA256 is not set
-CONFIG_CRYPTO_SHA512=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
CONFIG_CRYPTO_WP512=m
-# CONFIG_CRYPTO_DES is not set
-# CONFIG_CRYPTO_BLOWFISH is not set
-CONFIG_CRYPTO_TWOFISH=y
-# CONFIG_CRYPTO_SERPENT is not set
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_SERPENT=m
CONFIG_CRYPTO_AES=m
-# CONFIG_CRYPTO_CAST5 is not set
-# CONFIG_CRYPTO_CAST6 is not set
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
CONFIG_CRYPTO_TEA=m
-# CONFIG_CRYPTO_ARC4 is not set
+CONFIG_CRYPTO_ARC4=m
CONFIG_CRYPTO_KHAZAD=m
CONFIG_CRYPTO_ANUBIS=m
-CONFIG_CRYPTO_DEFLATE=y
-CONFIG_CRYPTO_MICHAEL_MIC=y
+CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
CONFIG_CRYPTO_CRC32C=m
# CONFIG_CRYPTO_TEST is not set
@@ -687,9 +971,8 @@ CONFIG_CRYPTO_CRC32C=m
# Library routines
#
# CONFIG_CRC_CCITT is not set
-# CONFIG_CRC32 is not set
+CONFIG_CRC16=m
+CONFIG_CRC32=y
CONFIG_LIBCRC32C=m
-CONFIG_ZLIB_INFLATE=y
-CONFIG_ZLIB_DEFLATE=y
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_ZLIB_INFLATE=m
+CONFIG_ZLIB_DEFLATE=m
diff --git a/arch/mips/configs/ocelot_3_defconfig b/arch/mips/configs/ocelot_3_defconfig
index b4cf97a732bc..f18d05c2ca77 100644
--- a/arch/mips/configs/ocelot_3_defconfig
+++ b/arch/mips/configs/ocelot_3_defconfig
@@ -1,12 +1,9 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-rc2
-# Wed Jan 26 02:49:07 2005
+# Linux kernel version: 2.6.14-rc2
+# Thu Oct 20 22:26:30 2005
#
CONFIG_MIPS=y
-# CONFIG_64BIT is not set
-# CONFIG_64BIT is not set
-CONFIG_32BIT=y
#
# Code maturity level options
@@ -14,25 +11,30 @@ CONFIG_32BIT=y
CONFIG_EXPERIMENTAL=y
CONFIG_CLEAN_COMPILE=y
CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
#
# General setup
#
CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
# CONFIG_POSIX_MQUEUE is not set
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_HOTPLUG is not set
+CONFIG_HOTPLUG=y
CONFIG_KOBJECT_UEVENT=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
+CONFIG_INITRAMFS_SOURCE=""
CONFIG_EMBEDDED=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
@@ -42,6 +44,7 @@ CONFIG_CC_ALIGN_LABELS=0
CONFIG_CC_ALIGN_LOOPS=0
CONFIG_CC_ALIGN_JUMPS=0
# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
#
# Loadable module support
@@ -57,40 +60,68 @@ CONFIG_KMOD=y
#
# Machine selection
#
-# CONFIG_MACH_JAZZ is not set
-# CONFIG_MACH_VR41XX is not set
-# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_MIPS_PB1550 is not set
+# CONFIG_MIPS_PB1200 is not set
+# CONFIG_MIPS_DB1000 is not set
+# CONFIG_MIPS_DB1100 is not set
+# CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
+# CONFIG_MIPS_DB1200 is not set
+# CONFIG_MIPS_MIRAGE is not set
# CONFIG_MIPS_COBALT is not set
# CONFIG_MACH_DECSTATION is not set
# CONFIG_MIPS_EV64120 is not set
# CONFIG_MIPS_EV96100 is not set
# CONFIG_MIPS_IVR is not set
-# CONFIG_LASAT is not set
# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_LASAT is not set
# CONFIG_MIPS_ATLAS is not set
# CONFIG_MIPS_MALTA is not set
# CONFIG_MIPS_SEAD is not set
+# CONFIG_MIPS_SIM is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
# CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_G is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
CONFIG_MOMENCO_OCELOT_3=y
-# CONFIG_MOMENCO_JAGUAR_ATX is not set
-# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MIPS_XXS1500 is not set
+# CONFIG_PNX8550_V2PCI is not set
+# CONFIG_PNX8550_JBS is not set
# CONFIG_DDB5074 is not set
# CONFIG_DDB5476 is not set
# CONFIG_DDB5477 is not set
-# CONFIG_NEC_OSPREY is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_QEMU is not set
# CONFIG_SGI_IP22 is not set
-# CONFIG_SOC_AU1X00 is not set
-# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_BIGSUR is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_PTSWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CRHONE is not set
# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
# CONFIG_TOSHIBA_RBTX4927 is not set
+# CONFIG_TOSHIBA_RBTX4938 is not set
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_HAVE_DEC_LOCK=y
CONFIG_DMA_NONCOHERENT=y
CONFIG_DMA_NEED_PCI_MAP_STATE=y
+CONFIG_CPU_BIG_ENDIAN=y
# CONFIG_CPU_LITTLE_ENDIAN is not set
+CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
CONFIG_IRQ_CPU=y
CONFIG_IRQ_CPU_RM7K=y
CONFIG_IRQ_MV64340=y
@@ -102,8 +133,10 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5
#
# CPU selection
#
-# CONFIG_CPU_MIPS32 is not set
-# CONFIG_CPU_MIPS64 is not set
+# CONFIG_CPU_MIPS32_R1 is not set
+# CONFIG_CPU_MIPS32_R2 is not set
+# CONFIG_CPU_MIPS64_R1 is not set
+# CONFIG_CPU_MIPS64_R2 is not set
# CONFIG_CPU_R3000 is not set
# CONFIG_CPU_TX39XX is not set
# CONFIG_CPU_VR41XX is not set
@@ -119,6 +152,17 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5
# CONFIG_CPU_RM7000 is not set
CONFIG_CPU_RM9000=y
# CONFIG_CPU_SB1 is not set
+CONFIG_SYS_HAS_CPU_RM9000=y
+CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
+CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y
+
+#
+# Kernel type
+#
+CONFIG_32BIT=y
+# CONFIG_64BIT is not set
CONFIG_PAGE_SIZE_4KB=y
# CONFIG_PAGE_SIZE_8KB is not set
# CONFIG_PAGE_SIZE_16KB is not set
@@ -126,13 +170,26 @@ CONFIG_PAGE_SIZE_4KB=y
CONFIG_BOARD_SCACHE=y
CONFIG_RM7000_CPU_SCACHE=y
CONFIG_CPU_HAS_PREFETCH=y
+# CONFIG_MIPS_MT is not set
# CONFIG_64BIT_PHYS_ADDR is not set
# CONFIG_CPU_ADVANCED is not set
CONFIG_CPU_HAS_LLSC=y
CONFIG_CPU_HAS_LLDSCD=y
CONFIG_CPU_HAS_SYNC=y
-# CONFIG_HIGHMEM is not set
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_CPU_SUPPORTS_HIGHMEM=y
+CONFIG_ARCH_FLATMEM_ENABLE=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_SMP is not set
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
#
@@ -141,7 +198,6 @@ CONFIG_CPU_HAS_SYNC=y
CONFIG_HW_HAS_PCI=y
CONFIG_PCI=y
CONFIG_PCI_LEGACY_PROC=y
-CONFIG_PCI_NAMES=y
CONFIG_MMU=y
#
@@ -150,10 +206,6 @@ CONFIG_MMU=y
# CONFIG_PCCARD is not set
#
-# PC-card bridges
-#
-
-#
# PCI Hotplug Support
#
# CONFIG_HOTPLUG_PCI is not set
@@ -166,6 +218,110 @@ CONFIG_BINFMT_ELF=y
CONFIG_TRAD_SIGNALS=y
#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+CONFIG_NET_KEY=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+
+#
+# IP: Virtual Server Configuration
+#
+# CONFIG_IP_VS is not set
+CONFIG_IPV6=m
+# CONFIG_IPV6_PRIVACY is not set
+# CONFIG_INET6_AH is not set
+# CONFIG_INET6_ESP is not set
+# CONFIG_INET6_IPCOMP is not set
+# CONFIG_INET6_TUNNEL is not set
+# CONFIG_IPV6_TUNNEL is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+CONFIG_NETFILTER_NETLINK=m
+CONFIG_NETFILTER_NETLINK_QUEUE=m
+CONFIG_NETFILTER_NETLINK_LOG=m
+
+#
+# IP: Netfilter Configuration
+#
+# CONFIG_IP_NF_CONNTRACK is not set
+CONFIG_IP_NF_PPTP=m
+# CONFIG_IP_NF_QUEUE is not set
+# CONFIG_IP_NF_IPTABLES is not set
+# CONFIG_IP_NF_ARPTABLES is not set
+
+#
+# IPv6: Netfilter Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP6_NF_QUEUE is not set
+# CONFIG_IP6_NF_IPTABLES is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP 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_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_IEEE80211=m
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=m
+CONFIG_IEEE80211_CRYPT_CCMP=m
+CONFIG_IEEE80211_CRYPT_TKIP=m
+
+#
# Device Drivers
#
@@ -174,7 +330,12 @@ CONFIG_TRAD_SIGNALS=y
#
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
+CONFIG_FW_LOADER=m
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+CONFIG_CONNECTOR=m
#
# Memory Technology Devices (MTD)
@@ -193,7 +354,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
#
# Block devices
#
-# CONFIG_BLK_DEV_FD is not set
# CONFIG_BLK_CPQ_DA is not set
# CONFIG_BLK_CPQ_CISS_DA is not set
# CONFIG_BLK_DEV_DAC960 is not set
@@ -205,7 +365,6 @@ CONFIG_BLK_DEV_LOOP=y
# CONFIG_BLK_DEV_SX8 is not set
# CONFIG_BLK_DEV_RAM is not set
CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_INITRAMFS_SOURCE=""
# CONFIG_LBD is not set
# CONFIG_CDROM_PKTCDVD is not set
@@ -226,6 +385,7 @@ CONFIG_ATA_OVER_ETH=m
#
# SCSI device support
#
+CONFIG_RAID_ATTRS=m
CONFIG_SCSI=m
CONFIG_SCSI_PROC_FS=y
@@ -237,6 +397,7 @@ CONFIG_SCSI_PROC_FS=y
# CONFIG_CHR_DEV_OSST is not set
# CONFIG_BLK_DEV_SR is not set
# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
#
# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
@@ -251,6 +412,7 @@ CONFIG_SCSI_PROC_FS=y
# CONFIG_SCSI_SPI_ATTRS is not set
# CONFIG_SCSI_FC_ATTRS is not set
# CONFIG_SCSI_ISCSI_ATTRS is not set
+CONFIG_SCSI_SAS_ATTRS=m
#
# SCSI low-level drivers
@@ -266,18 +428,13 @@ CONFIG_SCSI_PROC_FS=y
# CONFIG_MEGARAID_NEWGEN is not set
# CONFIG_MEGARAID_LEGACY is not set
# CONFIG_SCSI_SATA is not set
-# CONFIG_SCSI_BUSLOGIC is not set
# CONFIG_SCSI_DMX3191D is not set
-# CONFIG_SCSI_EATA is not set
-# CONFIG_SCSI_EATA_PIO is not set
# CONFIG_SCSI_FUTURE_DOMAIN is not set
-# CONFIG_SCSI_GDTH is not set
# CONFIG_SCSI_IPS is not set
# CONFIG_SCSI_INITIO is not set
# CONFIG_SCSI_INIA100 is not set
# CONFIG_SCSI_SYM53C8XX_2 is not set
# CONFIG_SCSI_IPR is not set
-# CONFIG_SCSI_QLOGIC_ISP is not set
# CONFIG_SCSI_QLOGIC_FC is not set
# CONFIG_SCSI_QLOGIC_1280 is not set
CONFIG_SCSI_QLA2XXX=m
@@ -286,6 +443,8 @@ CONFIG_SCSI_QLA2XXX=m
# CONFIG_SCSI_QLA2300 is not set
# CONFIG_SCSI_QLA2322 is not set
# CONFIG_SCSI_QLA6312 is not set
+# CONFIG_SCSI_QLA24XX is not set
+# CONFIG_SCSI_LPFC is not set
# CONFIG_SCSI_DC395x is not set
# CONFIG_SCSI_DC390T is not set
# CONFIG_SCSI_NSP32 is not set
@@ -300,6 +459,8 @@ CONFIG_SCSI_QLA2XXX=m
# Fusion MPT device support
#
# CONFIG_FUSION is not set
+# CONFIG_FUSION_SPI is not set
+# CONFIG_FUSION_FC is not set
#
# IEEE 1394 (FireWire) support
@@ -312,105 +473,13 @@ CONFIG_SCSI_QLA2XXX=m
# CONFIG_I2O is not set
#
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
-CONFIG_NETLINK_DEV=y
-CONFIG_UNIX=y
-CONFIG_NET_KEY=y
-CONFIG_INET=y
-# CONFIG_IP_MULTICAST is not set
-# CONFIG_IP_ADVANCED_ROUTER is not set
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-CONFIG_IP_PNP_BOOTP=y
-# CONFIG_IP_PNP_RARP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_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_TUNNEL is not set
-CONFIG_IP_TCPDIAG=m
-CONFIG_IP_TCPDIAG_IPV6=y
-
-#
-# IP: Virtual Server Configuration
-#
-# CONFIG_IP_VS is not set
-CONFIG_IPV6=m
-# CONFIG_IPV6_PRIVACY is not set
-# CONFIG_INET6_AH is not set
-# CONFIG_INET6_ESP is not set
-# CONFIG_INET6_IPCOMP is not set
-# CONFIG_INET6_TUNNEL is not set
-# CONFIG_IPV6_TUNNEL is not set
-CONFIG_NETFILTER=y
-# CONFIG_NETFILTER_DEBUG is not set
-
-#
-# IP: Netfilter Configuration
-#
-# CONFIG_IP_NF_CONNTRACK is not set
-# CONFIG_IP_NF_CONNTRACK_MARK is not set
-# CONFIG_IP_NF_QUEUE is not set
-# CONFIG_IP_NF_IPTABLES is not set
-# CONFIG_IP_NF_ARPTABLES is not set
-
-#
-# IPv6: Netfilter Configuration
-#
-# CONFIG_IP6_NF_QUEUE is not set
-# CONFIG_IP6_NF_IPTABLES is not set
-CONFIG_XFRM=y
-# CONFIG_XFRM_USER is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP 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_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
-
-#
-# Network testing
+# Network device support
#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
CONFIG_NETDEVICES=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_EQUALIZER is not set
CONFIG_TUN=m
-# CONFIG_ETHERTAP is not set
#
# ARCnet devices
@@ -418,6 +487,21 @@ CONFIG_TUN=m
# CONFIG_ARCNET is not set
#
+# PHY device support
+#
+CONFIG_PHYLIB=m
+CONFIG_PHYCONTROL=y
+
+#
+# MII PHY device drivers
+#
+CONFIG_MARVELL_PHY=m
+CONFIG_DAVICOM_PHY=m
+CONFIG_QSEMI_PHY=m
+CONFIG_LXT_PHY=m
+CONFIG_CICADA_PHY=m
+
+#
# Ethernet (10 or 100Mbit)
#
CONFIG_NET_ETHERNET=y
@@ -440,7 +524,6 @@ CONFIG_NET_PCI=y
# CONFIG_DGRS is not set
# CONFIG_EEPRO100 is not set
CONFIG_E100=y
-# CONFIG_E100_NAPI is not set
# CONFIG_FEALNX is not set
# CONFIG_NATSEMI is not set
# CONFIG_NE2K_PCI is not set
@@ -463,9 +546,12 @@ CONFIG_E100=y
# CONFIG_HAMACHI is not set
# CONFIG_YELLOWFIN is not set
# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
# CONFIG_SK98LIN is not set
# CONFIG_VIA_VELOCITY is not set
# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
CONFIG_MV643XX_ETH=y
CONFIG_MV643XX_ETH_0=y
CONFIG_MV643XX_ETH_1=y
@@ -474,6 +560,7 @@ CONFIG_MV643XX_ETH_2=y
#
# Ethernet (10000 Mbit)
#
+# CONFIG_CHELSIO_T1 is not set
# CONFIG_IXGB is not set
# CONFIG_S2IO is not set
@@ -486,6 +573,8 @@ CONFIG_MV643XX_ETH_2=y
# Wireless LAN (non-hamradio)
#
# CONFIG_NET_RADIO is not set
+# CONFIG_IPW_DEBUG is not set
+CONFIG_IPW2200=m
#
# Wan interfaces
@@ -505,6 +594,8 @@ CONFIG_PPPOE=m
# CONFIG_NET_FC is not set
# CONFIG_SHAPER is not set
# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
#
# ISDN subsystem
@@ -531,19 +622,6 @@ CONFIG_INPUT=y
# CONFIG_INPUT_EVBUG is not set
#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=y
-# CONFIG_SERIO_I8042 is not set
-# CONFIG_SERIO_SERPORT is not set
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_PCIPS2 is not set
-# CONFIG_SERIO_LIBPS2 is not set
-# CONFIG_SERIO_RAW is not set
-
-#
# Input Device Drivers
#
# CONFIG_INPUT_KEYBOARD is not set
@@ -553,6 +631,17 @@ CONFIG_SERIO=y
# CONFIG_INPUT_MISC is not set
#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+# CONFIG_SERIO_SERPORT is not set
+# CONFIG_SERIO_PCIPS2 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
@@ -573,6 +662,7 @@ CONFIG_SERIAL_8250_NR_UARTS=4
#
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
CONFIG_UNIX98_PTYS=y
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
@@ -598,6 +688,11 @@ CONFIG_RTC=y
# CONFIG_RAW_DRIVER is not set
#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+
+#
# I2C support
#
# CONFIG_I2C is not set
@@ -608,10 +703,20 @@ CONFIG_RTC=y
# CONFIG_W1 is not set
#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
+#
# Misc devices
#
#
+# Multimedia Capabilities Port drivers
+#
+
+#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
@@ -625,6 +730,11 @@ CONFIG_RTC=y
# Graphics support
#
CONFIG_FB=y
+# CONFIG_FB_CFB_FILLRECT is not set
+# CONFIG_FB_CFB_COPYAREA is not set
+# CONFIG_FB_CFB_IMAGEBLIT is not set
+# CONFIG_FB_SOFT_CURSOR is not set
+# CONFIG_FB_MACMODES is not set
CONFIG_FB_MODE_HELPERS=y
# CONFIG_FB_TILEBLITTING is not set
# CONFIG_FB_CIRRUS is not set
@@ -632,6 +742,7 @@ CONFIG_FB_MODE_HELPERS=y
# CONFIG_FB_CYBER2000 is not set
# CONFIG_FB_ASILIANT is not set
# CONFIG_FB_IMSTT is not set
+# CONFIG_FB_NVIDIA is not set
# CONFIG_FB_RIVA is not set
# CONFIG_FB_MATROX is not set
# CONFIG_FB_RADEON_OLD is not set
@@ -644,8 +755,10 @@ CONFIG_FB_MODE_HELPERS=y
# CONFIG_FB_KYRO is not set
# CONFIG_FB_3DFX is not set
# CONFIG_FB_VOODOO1 is not set
+# CONFIG_FB_SMIVGX is not set
+# CONFIG_FB_CYBLA is not set
# CONFIG_FB_TRIDENT is not set
-# CONFIG_FB_E1356 is not set
+# CONFIG_FB_S1D13XXX is not set
# CONFIG_FB_VIRTUAL is not set
#
@@ -675,13 +788,9 @@ CONFIG_LOGO_LINUX_CLUT224=y
#
# USB support
#
-# CONFIG_USB is not set
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB_ARCH_HAS_OHCI=y
-
-#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
-#
+# CONFIG_USB is not set
#
# USB Gadget Support
@@ -699,10 +808,15 @@ CONFIG_USB_ARCH_HAS_OHCI=y
# CONFIG_INFINIBAND is not set
#
+# SN Devices
+#
+
+#
# File systems
#
CONFIG_EXT2_FS=y
# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
CONFIG_EXT3_FS=m
CONFIG_EXT3_FS_XATTR=y
# CONFIG_EXT3_FS_POSIX_ACL is not set
@@ -715,17 +829,21 @@ CONFIG_REISERFS_FS=m
# CONFIG_REISERFS_PROC_INFO is not set
# CONFIG_REISERFS_FS_XATTR is not set
# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
CONFIG_XFS_FS=m
-# CONFIG_XFS_RT is not set
+CONFIG_XFS_EXPORT=y
# CONFIG_XFS_QUOTA is not set
# CONFIG_XFS_SECURITY is not set
# CONFIG_XFS_POSIX_ACL is not set
+# CONFIG_XFS_RT is not set
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
# CONFIG_QUOTA is not set
CONFIG_DNOTIFY=y
CONFIG_AUTOFS_FS=y
CONFIG_AUTOFS4_FS=m
+CONFIG_FUSE_FS=m
#
# CD-ROM/DVD Filesystems
@@ -746,15 +864,10 @@ CONFIG_AUTOFS4_FS=m
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_SYSFS=y
-CONFIG_DEVFS_FS=y
-CONFIG_DEVFS_MOUNT=y
-# CONFIG_DEVFS_DEBUG is not set
-CONFIG_DEVPTS_FS_XATTR=y
-CONFIG_DEVPTS_FS_SECURITY=y
CONFIG_TMPFS=y
-# CONFIG_TMPFS_XATTR is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
+CONFIG_RELAYFS_FS=m
#
# Miscellaneous filesystems
@@ -778,16 +891,19 @@ CONFIG_CRAMFS=y
#
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
# CONFIG_NFS_V4 is not set
# CONFIG_NFS_DIRECTIO is not set
CONFIG_NFSD=y
CONFIG_NFSD_V3=y
+# CONFIG_NFSD_V3_ACL is not set
# CONFIG_NFSD_V4 is not set
# CONFIG_NFSD_TCP is not set
CONFIG_ROOT_NFS=y
CONFIG_LOCKD=y
CONFIG_LOCKD_V4=y
CONFIG_EXPORTFS=y
+CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
@@ -797,6 +913,7 @@ CONFIG_SMB_FS=m
# CONFIG_NCP_FS is not set
# CONFIG_CODA_FS is not set
# CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
#
# Partition Types
@@ -856,7 +973,9 @@ CONFIG_NLS_DEFAULT="iso8859-1"
#
# Kernel hacking
#
+# CONFIG_PRINTK_TIME is not set
# CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=14
CONFIG_CROSSCOMPILE=y
CONFIG_CMDLINE="ip=any root=nfs"
@@ -869,7 +988,31 @@ CONFIG_CMDLINE="ip=any root=nfs"
#
# Cryptographic options
#
-# CONFIG_CRYPTO is not set
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_AES=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_CRC32C=m
+# CONFIG_CRYPTO_TEST is not set
#
# Hardware crypto devices
@@ -879,9 +1022,8 @@ CONFIG_CMDLINE="ip=any root=nfs"
# Library routines
#
CONFIG_CRC_CCITT=m
+CONFIG_CRC16=m
CONFIG_CRC32=y
CONFIG_LIBCRC32C=m
CONFIG_ZLIB_INFLATE=y
CONFIG_ZLIB_DEFLATE=m
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_IRQ_PROBE=y
diff --git a/arch/mips/configs/ocelot_c_defconfig b/arch/mips/configs/ocelot_c_defconfig
index a38903db85a0..d3a5fee02b79 100644
--- a/arch/mips/configs/ocelot_c_defconfig
+++ b/arch/mips/configs/ocelot_c_defconfig
@@ -1,11 +1,9 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-rc2
-# Wed Jan 26 02:49:07 2005
+# Linux kernel version: 2.6.14-rc2
+# Thu Oct 20 22:26:33 2005
#
CONFIG_MIPS=y
-CONFIG_64BIT=y
-CONFIG_64BIT=y
#
# Code maturity level options
@@ -13,24 +11,29 @@ CONFIG_64BIT=y
CONFIG_EXPERIMENTAL=y
CONFIG_CLEAN_COMPILE=y
CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
#
# General setup
#
CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
# CONFIG_POSIX_MQUEUE is not set
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_HOTPLUG is not set
+CONFIG_HOTPLUG=y
CONFIG_KOBJECT_UEVENT=y
# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
CONFIG_EMBEDDED=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
@@ -40,6 +43,7 @@ CONFIG_CC_ALIGN_LABELS=0
CONFIG_CC_ALIGN_LOOPS=0
CONFIG_CC_ALIGN_JUMPS=0
# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
#
# Loadable module support
@@ -49,39 +53,68 @@ CONFIG_CC_ALIGN_JUMPS=0
#
# Machine selection
#
-# CONFIG_MACH_JAZZ is not set
-# CONFIG_MACH_VR41XX is not set
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_MIPS_PB1550 is not set
+# CONFIG_MIPS_PB1200 is not set
+# CONFIG_MIPS_DB1000 is not set
+# CONFIG_MIPS_DB1100 is not set
+# CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
+# CONFIG_MIPS_DB1200 is not set
+# CONFIG_MIPS_MIRAGE is not set
# CONFIG_MIPS_COBALT is not set
# CONFIG_MACH_DECSTATION is not set
# CONFIG_MIPS_EV64120 is not set
# CONFIG_MIPS_EV96100 is not set
# CONFIG_MIPS_IVR is not set
-# CONFIG_LASAT is not set
# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_LASAT is not set
# CONFIG_MIPS_ATLAS is not set
# CONFIG_MIPS_MALTA is not set
# CONFIG_MIPS_SEAD is not set
+# CONFIG_MIPS_SIM is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
# CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_G is not set
-CONFIG_MOMENCO_OCELOT_C=y
# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_JAGUAR_ATX is not set
-# CONFIG_PMC_YOSEMITE is not set
+CONFIG_MOMENCO_OCELOT_C=y
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MIPS_XXS1500 is not set
+# CONFIG_PNX8550_V2PCI is not set
+# CONFIG_PNX8550_JBS is not set
# CONFIG_DDB5074 is not set
# CONFIG_DDB5476 is not set
# CONFIG_DDB5477 is not set
-# CONFIG_NEC_OSPREY is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_QEMU is not set
# CONFIG_SGI_IP22 is not set
# CONFIG_SGI_IP27 is not set
# CONFIG_SGI_IP32 is not set
-# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SIBYTE_BIGSUR is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_PTSWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CRHONE is not set
# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_TOSHIBA_RBTX4927 is not set
+# CONFIG_TOSHIBA_RBTX4938 is not set
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_HAVE_DEC_LOCK=y
CONFIG_DMA_NONCOHERENT=y
CONFIG_DMA_NEED_PCI_MAP_STATE=y
+CONFIG_CPU_BIG_ENDIAN=y
# CONFIG_CPU_LITTLE_ENDIAN is not set
+CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
CONFIG_IRQ_CPU=y
CONFIG_IRQ_MV64340=y
CONFIG_PCI_MARVELL=y
@@ -91,8 +124,10 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5
#
# CPU selection
#
-# CONFIG_CPU_MIPS32 is not set
-# CONFIG_CPU_MIPS64 is not set
+# CONFIG_CPU_MIPS32_R1 is not set
+# CONFIG_CPU_MIPS32_R2 is not set
+# CONFIG_CPU_MIPS64_R1 is not set
+# CONFIG_CPU_MIPS64_R2 is not set
# CONFIG_CPU_R3000 is not set
# CONFIG_CPU_TX39XX is not set
# CONFIG_CPU_VR41XX is not set
@@ -108,6 +143,17 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5
CONFIG_CPU_RM7000=y
# CONFIG_CPU_RM9000 is not set
# CONFIG_CPU_SB1 is not set
+CONFIG_SYS_HAS_CPU_RM7000=y
+CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
+CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y
+
+#
+# Kernel type
+#
+# CONFIG_32BIT is not set
+CONFIG_64BIT=y
CONFIG_PAGE_SIZE_4KB=y
# CONFIG_PAGE_SIZE_8KB is not set
# CONFIG_PAGE_SIZE_16KB is not set
@@ -115,9 +161,23 @@ CONFIG_PAGE_SIZE_4KB=y
CONFIG_BOARD_SCACHE=y
CONFIG_RM7000_CPU_SCACHE=y
CONFIG_CPU_HAS_PREFETCH=y
+# CONFIG_MIPS_MT is not set
CONFIG_CPU_HAS_LLSC=y
CONFIG_CPU_HAS_LLDSCD=y
CONFIG_CPU_HAS_SYNC=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_CPU_SUPPORTS_HIGHMEM=y
+CONFIG_ARCH_FLATMEM_ENABLE=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_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
#
@@ -126,7 +186,6 @@ CONFIG_CPU_HAS_SYNC=y
CONFIG_HW_HAS_PCI=y
CONFIG_PCI=y
CONFIG_PCI_LEGACY_PROC=y
-CONFIG_PCI_NAMES=y
CONFIG_MMU=y
#
@@ -135,10 +194,6 @@ CONFIG_MMU=y
# CONFIG_PCCARD is not set
#
-# PC-card bridges
-#
-
-#
# PCI Hotplug Support
#
# CONFIG_HOTPLUG_PCI is not set
@@ -156,6 +211,79 @@ CONFIG_MIPS32_N32=y
CONFIG_BINFMT_ELF32=y
#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_PACKET is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=y
+CONFIG_NET_KEY=y
+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_TUNNEL=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+# CONFIG_IPV6 is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# 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_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_IEEE80211=y
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=y
+CONFIG_IEEE80211_CRYPT_CCMP=y
+CONFIG_IEEE80211_CRYPT_TKIP=y
+
+#
# Device Drivers
#
@@ -164,7 +292,12 @@ CONFIG_BINFMT_ELF32=y
#
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
+CONFIG_FW_LOADER=y
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+CONFIG_CONNECTOR=y
#
# Memory Technology Devices (MTD)
@@ -183,7 +316,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
#
# Block devices
#
-# CONFIG_BLK_DEV_FD is not set
# CONFIG_BLK_CPQ_DA is not set
# CONFIG_BLK_CPQ_CISS_DA is not set
# CONFIG_BLK_DEV_DAC960 is not set
@@ -194,7 +326,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_BLK_DEV_SX8 is not set
# CONFIG_BLK_DEV_RAM is not set
CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_INITRAMFS_SOURCE=""
CONFIG_CDROM_PKTCDVD=y
CONFIG_CDROM_PKTCDVD_BUFFERS=8
# CONFIG_CDROM_PKTCDVD_WCACHE is not set
@@ -216,6 +347,7 @@ CONFIG_ATA_OVER_ETH=y
#
# SCSI device support
#
+CONFIG_RAID_ATTRS=y
# CONFIG_SCSI is not set
#
@@ -226,6 +358,7 @@ CONFIG_ATA_OVER_ETH=y
#
# Fusion MPT device support
#
+# CONFIG_FUSION is not set
#
# IEEE 1394 (FireWire) support
@@ -238,77 +371,13 @@ CONFIG_ATA_OVER_ETH=y
# CONFIG_I2O is not set
#
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-# CONFIG_PACKET is not set
-CONFIG_NETLINK_DEV=y
-CONFIG_UNIX=y
-CONFIG_NET_KEY=y
-CONFIG_INET=y
-# CONFIG_IP_MULTICAST is not set
-# CONFIG_IP_ADVANCED_ROUTER is not set
-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_TUNNEL=y
-CONFIG_IP_TCPDIAG=y
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-# CONFIG_IPV6 is not set
-# CONFIG_NETFILTER is not set
-CONFIG_XFRM=y
-CONFIG_XFRM_USER=y
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP 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_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
-
-#
-# Network testing
+# Network device support
#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
CONFIG_NETDEVICES=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_EQUALIZER is not set
# CONFIG_TUN is not set
-# CONFIG_ETHERTAP is not set
#
# ARCnet devices
@@ -316,6 +385,21 @@ CONFIG_NETDEVICES=y
# CONFIG_ARCNET is not set
#
+# PHY device support
+#
+CONFIG_PHYLIB=y
+CONFIG_PHYCONTROL=y
+
+#
+# MII PHY device drivers
+#
+CONFIG_MARVELL_PHY=y
+CONFIG_DAVICOM_PHY=y
+CONFIG_QSEMI_PHY=y
+CONFIG_LXT_PHY=y
+CONFIG_CICADA_PHY=y
+
+#
# Ethernet (10 or 100Mbit)
#
CONFIG_NET_ETHERNET=y
@@ -341,13 +425,17 @@ CONFIG_NET_ETHERNET=y
# CONFIG_HAMACHI is not set
# CONFIG_YELLOWFIN is not set
# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
# CONFIG_SK98LIN is not set
# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
# CONFIG_MV643XX_ETH is not set
#
# Ethernet (10000 Mbit)
#
+# CONFIG_CHELSIO_T1 is not set
# CONFIG_IXGB is not set
# CONFIG_S2IO is not set
@@ -360,6 +448,8 @@ CONFIG_NET_ETHERNET=y
# Wireless LAN (non-hamradio)
#
# CONFIG_NET_RADIO is not set
+# CONFIG_IPW_DEBUG is not set
+CONFIG_IPW2200=y
#
# Wan interfaces
@@ -371,6 +461,8 @@ CONFIG_NET_ETHERNET=y
# CONFIG_SLIP is not set
# CONFIG_SHAPER is not set
# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
#
# ISDN subsystem
@@ -400,19 +492,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
# CONFIG_INPUT_EVBUG is not set
#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=y
-# CONFIG_SERIO_I8042 is not set
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_PCIPS2 is not set
-# CONFIG_SERIO_LIBPS2 is not set
-CONFIG_SERIO_RAW=y
-
-#
# Input Device Drivers
#
# CONFIG_INPUT_KEYBOARD is not set
@@ -422,6 +501,17 @@ CONFIG_SERIO_RAW=y
# CONFIG_INPUT_MISC is not set
#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_PCIPS2 is not set
+# CONFIG_SERIO_LIBPS2 is not set
+CONFIG_SERIO_RAW=y
+# CONFIG_GAMEPORT is not set
+
+#
# Character devices
#
CONFIG_VT=y
@@ -442,6 +532,7 @@ CONFIG_SERIAL_8250_NR_UARTS=4
#
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
CONFIG_UNIX98_PTYS=y
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
@@ -468,6 +559,11 @@ CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_RAW_DRIVER is not set
#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+
+#
# I2C support
#
# CONFIG_I2C is not set
@@ -478,10 +574,20 @@ CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_W1 is not set
#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
+#
# Misc devices
#
#
+# Multimedia Capabilities Port drivers
+#
+
+#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
@@ -501,7 +607,6 @@ CONFIG_LEGACY_PTY_COUNT=256
#
# CONFIG_VGA_CONSOLE is not set
CONFIG_DUMMY_CONSOLE=y
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Sound
@@ -511,13 +616,9 @@ CONFIG_DUMMY_CONSOLE=y
#
# USB support
#
-# CONFIG_USB is not set
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB_ARCH_HAS_OHCI=y
-
-#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
-#
+# CONFIG_USB is not set
#
# USB Gadget Support
@@ -535,21 +636,29 @@ CONFIG_USB_ARCH_HAS_OHCI=y
# CONFIG_INFINIBAND is not set
#
+# SN Devices
+#
+
+#
# File systems
#
CONFIG_EXT2_FS=y
# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
# CONFIG_EXT3_FS is not set
# CONFIG_JBD 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_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
# CONFIG_QUOTA is not set
CONFIG_DNOTIFY=y
# CONFIG_AUTOFS_FS is not set
# CONFIG_AUTOFS4_FS is not set
+CONFIG_FUSE_FS=y
#
# CD-ROM/DVD Filesystems
@@ -570,12 +679,10 @@ CONFIG_DNOTIFY=y
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
-CONFIG_DEVPTS_FS_XATTR=y
-CONFIG_DEVPTS_FS_SECURITY=y
# CONFIG_TMPFS is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
+CONFIG_RELAYFS_FS=y
#
# Miscellaneous filesystems
@@ -607,6 +714,7 @@ CONFIG_NFSD=y
CONFIG_ROOT_NFS=y
CONFIG_LOCKD=y
CONFIG_EXPORTFS=y
+CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
@@ -615,6 +723,7 @@ CONFIG_SUNRPC=y
# CONFIG_NCP_FS is not set
# CONFIG_CODA_FS is not set
# CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
#
# Partition Types
@@ -635,7 +744,9 @@ CONFIG_MSDOS_PARTITION=y
#
# Kernel hacking
#
+# CONFIG_PRINTK_TIME is not set
# CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=14
CONFIG_CROSSCOMPILE=y
CONFIG_CMDLINE=""
@@ -649,7 +760,31 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
#
# Cryptographic options
#
-# CONFIG_CRYPTO is not set
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_NULL=y
+CONFIG_CRYPTO_MD4=y
+CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_SHA1=y
+CONFIG_CRYPTO_SHA256=y
+CONFIG_CRYPTO_SHA512=y
+CONFIG_CRYPTO_WP512=y
+CONFIG_CRYPTO_TGR192=y
+CONFIG_CRYPTO_DES=y
+CONFIG_CRYPTO_BLOWFISH=y
+CONFIG_CRYPTO_TWOFISH=y
+CONFIG_CRYPTO_SERPENT=y
+CONFIG_CRYPTO_AES=y
+CONFIG_CRYPTO_CAST5=y
+CONFIG_CRYPTO_CAST6=y
+CONFIG_CRYPTO_TEA=y
+CONFIG_CRYPTO_ARC4=y
+CONFIG_CRYPTO_KHAZAD=y
+CONFIG_CRYPTO_ANUBIS=y
+CONFIG_CRYPTO_DEFLATE=y
+CONFIG_CRYPTO_MICHAEL_MIC=y
+CONFIG_CRYPTO_CRC32C=y
+# CONFIG_CRYPTO_TEST is not set
#
# Hardware crypto devices
@@ -659,7 +794,8 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
# Library routines
#
# CONFIG_CRC_CCITT is not set
-# CONFIG_CRC32 is not set
-# CONFIG_LIBCRC32C is not set
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_CRC16=y
+CONFIG_CRC32=y
+CONFIG_LIBCRC32C=y
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
diff --git a/arch/mips/configs/ocelot_defconfig b/arch/mips/configs/ocelot_defconfig
index 920d59b56a4e..1edde12ebff9 100644
--- a/arch/mips/configs/ocelot_defconfig
+++ b/arch/mips/configs/ocelot_defconfig
@@ -1,12 +1,9 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-rc2
-# Wed Jan 26 02:49:08 2005
+# Linux kernel version: 2.6.14-rc2
+# Thu Oct 20 22:26:35 2005
#
CONFIG_MIPS=y
-# CONFIG_64BIT is not set
-# CONFIG_64BIT is not set
-CONFIG_32BIT=y
#
# Code maturity level options
@@ -14,24 +11,29 @@ CONFIG_32BIT=y
CONFIG_EXPERIMENTAL=y
CONFIG_CLEAN_COMPILE=y
CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
#
# General setup
#
CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
# CONFIG_POSIX_MQUEUE is not set
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
# CONFIG_HOTPLUG is not set
CONFIG_KOBJECT_UEVENT=y
# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
CONFIG_EMBEDDED=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
@@ -41,6 +43,7 @@ CONFIG_CC_ALIGN_LABELS=0
CONFIG_CC_ALIGN_LOOPS=0
CONFIG_CC_ALIGN_JUMPS=0
# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
#
# Loadable module support
@@ -50,40 +53,68 @@ CONFIG_CC_ALIGN_JUMPS=0
#
# Machine selection
#
-# CONFIG_MACH_JAZZ is not set
-# CONFIG_MACH_VR41XX is not set
-# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_MIPS_PB1550 is not set
+# CONFIG_MIPS_PB1200 is not set
+# CONFIG_MIPS_DB1000 is not set
+# CONFIG_MIPS_DB1100 is not set
+# CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
+# CONFIG_MIPS_DB1200 is not set
+# CONFIG_MIPS_MIRAGE is not set
# CONFIG_MIPS_COBALT is not set
# CONFIG_MACH_DECSTATION is not set
# CONFIG_MIPS_EV64120 is not set
# CONFIG_MIPS_EV96100 is not set
# CONFIG_MIPS_IVR is not set
-# CONFIG_LASAT is not set
# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_LASAT is not set
# CONFIG_MIPS_ATLAS is not set
# CONFIG_MIPS_MALTA is not set
# CONFIG_MIPS_SEAD is not set
+# CONFIG_MIPS_SIM is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
CONFIG_MOMENCO_OCELOT=y
-# CONFIG_MOMENCO_OCELOT_G is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_JAGUAR_ATX is not set
-# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MIPS_XXS1500 is not set
+# CONFIG_PNX8550_V2PCI is not set
+# CONFIG_PNX8550_JBS is not set
# CONFIG_DDB5074 is not set
# CONFIG_DDB5476 is not set
# CONFIG_DDB5477 is not set
-# CONFIG_NEC_OSPREY is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_QEMU is not set
# CONFIG_SGI_IP22 is not set
-# CONFIG_SOC_AU1X00 is not set
-# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_BIGSUR is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_PTSWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CRHONE is not set
# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
# CONFIG_TOSHIBA_RBTX4927 is not set
+# CONFIG_TOSHIBA_RBTX4938 is not set
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_HAVE_DEC_LOCK=y
CONFIG_DMA_NONCOHERENT=y
CONFIG_DMA_NEED_PCI_MAP_STATE=y
+CONFIG_CPU_BIG_ENDIAN=y
# CONFIG_CPU_LITTLE_ENDIAN is not set
+CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
CONFIG_IRQ_CPU=y
CONFIG_IRQ_CPU_RM7K=y
CONFIG_MIPS_GT64120=y
@@ -96,8 +127,10 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5
#
# CPU selection
#
-# CONFIG_CPU_MIPS32 is not set
-# CONFIG_CPU_MIPS64 is not set
+# CONFIG_CPU_MIPS32_R1 is not set
+# CONFIG_CPU_MIPS32_R2 is not set
+# CONFIG_CPU_MIPS64_R1 is not set
+# CONFIG_CPU_MIPS64_R2 is not set
# CONFIG_CPU_R3000 is not set
# CONFIG_CPU_TX39XX is not set
# CONFIG_CPU_VR41XX is not set
@@ -113,6 +146,17 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5
CONFIG_CPU_RM7000=y
# CONFIG_CPU_RM9000 is not set
# CONFIG_CPU_SB1 is not set
+CONFIG_SYS_HAS_CPU_RM7000=y
+CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
+CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y
+
+#
+# Kernel type
+#
+CONFIG_32BIT=y
+# CONFIG_64BIT is not set
CONFIG_PAGE_SIZE_4KB=y
# CONFIG_PAGE_SIZE_8KB is not set
# CONFIG_PAGE_SIZE_16KB is not set
@@ -120,11 +164,25 @@ CONFIG_PAGE_SIZE_4KB=y
CONFIG_BOARD_SCACHE=y
CONFIG_RM7000_CPU_SCACHE=y
CONFIG_CPU_HAS_PREFETCH=y
+# CONFIG_MIPS_MT is not set
# CONFIG_64BIT_PHYS_ADDR is not set
# CONFIG_CPU_ADVANCED is not set
CONFIG_CPU_HAS_LLSC=y
CONFIG_CPU_HAS_LLDSCD=y
CONFIG_CPU_HAS_SYNC=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_CPU_SUPPORTS_HIGHMEM=y
+CONFIG_ARCH_FLATMEM_ENABLE=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_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
#
@@ -140,10 +198,6 @@ CONFIG_MMU=y
# CONFIG_PCCARD is not set
#
-# PC-card bridges
-#
-
-#
# PCI Hotplug Support
#
@@ -155,6 +209,79 @@ CONFIG_BINFMT_ELF=y
CONFIG_TRAD_SIGNALS=y
#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_PACKET is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=y
+CONFIG_NET_KEY=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+CONFIG_INET_TUNNEL=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+# CONFIG_IPV6 is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# 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_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_IEEE80211=y
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=y
+CONFIG_IEEE80211_CRYPT_CCMP=y
+CONFIG_IEEE80211_CRYPT_TKIP=y
+
+#
# Device Drivers
#
@@ -166,6 +293,11 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_FW_LOADER is not set
#
+# Connector - unified userspace <-> kernelspace linker
+#
+CONFIG_CONNECTOR=y
+
+#
# Memory Technology Devices (MTD)
#
# CONFIG_MTD is not set
@@ -182,13 +314,11 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
#
# Block devices
#
-# CONFIG_BLK_DEV_FD is not set
# CONFIG_BLK_DEV_COW_COMMON is not set
# CONFIG_BLK_DEV_LOOP is not set
# CONFIG_BLK_DEV_NBD is not set
# CONFIG_BLK_DEV_RAM is not set
CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_INITRAMFS_SOURCE=""
# CONFIG_LBD is not set
CONFIG_CDROM_PKTCDVD=y
CONFIG_CDROM_PKTCDVD_BUFFERS=8
@@ -211,6 +341,7 @@ CONFIG_ATA_OVER_ETH=y
#
# SCSI device support
#
+CONFIG_RAID_ATTRS=y
# CONFIG_SCSI is not set
#
@@ -221,6 +352,7 @@ CONFIG_ATA_OVER_ETH=y
#
# Fusion MPT device support
#
+# CONFIG_FUSION is not set
#
# IEEE 1394 (FireWire) support
@@ -231,77 +363,28 @@ CONFIG_ATA_OVER_ETH=y
#
#
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
+# Network device support
#
-# CONFIG_PACKET is not set
-CONFIG_NETLINK_DEV=y
-CONFIG_UNIX=y
-CONFIG_NET_KEY=y
-CONFIG_INET=y
-# CONFIG_IP_MULTICAST is not set
-# CONFIG_IP_ADVANCED_ROUTER is not set
-CONFIG_IP_PNP=y
-# CONFIG_IP_PNP_DHCP is not set
-CONFIG_IP_PNP_BOOTP=y
-# CONFIG_IP_PNP_RARP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_ARPD is not set
-# CONFIG_SYN_COOKIES is not set
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-CONFIG_INET_TUNNEL=y
-CONFIG_IP_TCPDIAG=y
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-# CONFIG_IPV6 is not set
-# CONFIG_NETFILTER is not set
-CONFIG_XFRM=y
-CONFIG_XFRM_USER=y
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP 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_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
#
-# QoS and/or fair queueing
+# PHY device support
#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
+CONFIG_PHYLIB=y
+CONFIG_PHYCONTROL=y
#
-# Network testing
+# MII PHY device drivers
#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
-CONFIG_NETDEVICES=y
-# CONFIG_DUMMY is not set
-# CONFIG_BONDING is not set
-# CONFIG_EQUALIZER is not set
-# CONFIG_TUN is not set
-# CONFIG_ETHERTAP is not set
+CONFIG_MARVELL_PHY=y
+CONFIG_DAVICOM_PHY=y
+CONFIG_QSEMI_PHY=y
+CONFIG_LXT_PHY=y
+CONFIG_CICADA_PHY=y
#
# Ethernet (10 or 100Mbit)
@@ -334,6 +417,8 @@ CONFIG_NET_ETHERNET=y
# CONFIG_SLIP is not set
# CONFIG_SHAPER is not set
# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
#
# ISDN subsystem
@@ -363,18 +448,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
# CONFIG_INPUT_EVBUG is not set
#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=y
-# CONFIG_SERIO_I8042 is not set
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_LIBPS2 is not set
-CONFIG_SERIO_RAW=y
-
-#
# Input Device Drivers
#
# CONFIG_INPUT_KEYBOARD is not set
@@ -384,6 +457,16 @@ CONFIG_SERIO_RAW=y
# CONFIG_INPUT_MISC is not set
#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_LIBPS2 is not set
+CONFIG_SERIO_RAW=y
+# CONFIG_GAMEPORT is not set
+
+#
# Character devices
#
CONFIG_VT=y
@@ -425,10 +508,13 @@ CONFIG_LEGACY_PTY_COUNT=256
#
# Ftape, the floppy tape device driver
#
-# CONFIG_DRM is not set
# CONFIG_RAW_DRIVER is not set
#
+# TPM devices
+#
+
+#
# I2C support
#
# CONFIG_I2C is not set
@@ -439,10 +525,20 @@ CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_W1 is not set
#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
+#
# Misc devices
#
#
+# Multimedia Capabilities Port drivers
+#
+
+#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
@@ -462,7 +558,6 @@ CONFIG_LEGACY_PTY_COUNT=256
#
# CONFIG_VGA_CONSOLE is not set
CONFIG_DUMMY_CONSOLE=y
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Sound
@@ -476,10 +571,6 @@ CONFIG_DUMMY_CONSOLE=y
# CONFIG_USB_ARCH_HAS_OHCI is not set
#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
-#
-
-#
# USB Gadget Support
#
# CONFIG_USB_GADGET is not set
@@ -492,24 +583,31 @@ CONFIG_DUMMY_CONSOLE=y
#
# InfiniBand support
#
-# CONFIG_INFINIBAND is not set
+
+#
+# SN Devices
+#
#
# File systems
#
CONFIG_EXT2_FS=y
# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
# CONFIG_EXT3_FS is not set
# CONFIG_JBD 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_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
# CONFIG_QUOTA is not set
CONFIG_DNOTIFY=y
# CONFIG_AUTOFS_FS is not set
# CONFIG_AUTOFS4_FS is not set
+CONFIG_FUSE_FS=y
#
# CD-ROM/DVD Filesystems
@@ -530,12 +628,10 @@ CONFIG_DNOTIFY=y
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
-CONFIG_DEVPTS_FS_XATTR=y
-CONFIG_DEVPTS_FS_SECURITY=y
# CONFIG_TMPFS is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
+CONFIG_RELAYFS_FS=y
#
# Miscellaneous filesystems
@@ -567,6 +663,7 @@ CONFIG_NFSD=y
CONFIG_ROOT_NFS=y
CONFIG_LOCKD=y
CONFIG_EXPORTFS=y
+CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
@@ -575,6 +672,7 @@ CONFIG_SUNRPC=y
# CONFIG_NCP_FS is not set
# CONFIG_CODA_FS is not set
# CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
#
# Partition Types
@@ -595,7 +693,9 @@ CONFIG_MSDOS_PARTITION=y
#
# Kernel hacking
#
+# CONFIG_PRINTK_TIME is not set
# CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=14
CONFIG_CROSSCOMPILE=y
CONFIG_CMDLINE=""
@@ -609,7 +709,31 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
#
# Cryptographic options
#
-# CONFIG_CRYPTO is not set
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_NULL=y
+CONFIG_CRYPTO_MD4=y
+CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_SHA1=y
+CONFIG_CRYPTO_SHA256=y
+CONFIG_CRYPTO_SHA512=y
+CONFIG_CRYPTO_WP512=y
+CONFIG_CRYPTO_TGR192=y
+CONFIG_CRYPTO_DES=y
+CONFIG_CRYPTO_BLOWFISH=y
+CONFIG_CRYPTO_TWOFISH=y
+CONFIG_CRYPTO_SERPENT=y
+CONFIG_CRYPTO_AES=y
+CONFIG_CRYPTO_CAST5=y
+CONFIG_CRYPTO_CAST6=y
+CONFIG_CRYPTO_TEA=y
+CONFIG_CRYPTO_ARC4=y
+CONFIG_CRYPTO_KHAZAD=y
+CONFIG_CRYPTO_ANUBIS=y
+CONFIG_CRYPTO_DEFLATE=y
+CONFIG_CRYPTO_MICHAEL_MIC=y
+CONFIG_CRYPTO_CRC32C=y
+# CONFIG_CRYPTO_TEST is not set
#
# Hardware crypto devices
@@ -619,7 +743,8 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
# Library routines
#
# CONFIG_CRC_CCITT is not set
-# CONFIG_CRC32 is not set
-# CONFIG_LIBCRC32C is not set
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_CRC16=y
+CONFIG_CRC32=y
+CONFIG_LIBCRC32C=y
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
diff --git a/arch/mips/configs/ocelot_g_defconfig b/arch/mips/configs/ocelot_g_defconfig
index ef5ea50893d1..e2d5188cdc15 100644
--- a/arch/mips/configs/ocelot_g_defconfig
+++ b/arch/mips/configs/ocelot_g_defconfig
@@ -1,11 +1,9 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-rc2
-# Wed Jan 26 02:49:08 2005
+# Linux kernel version: 2.6.14-rc2
+# Thu Oct 20 22:26:38 2005
#
CONFIG_MIPS=y
-CONFIG_64BIT=y
-CONFIG_64BIT=y
#
# Code maturity level options
@@ -13,24 +11,29 @@ CONFIG_64BIT=y
CONFIG_EXPERIMENTAL=y
CONFIG_CLEAN_COMPILE=y
CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
#
# General setup
#
CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
# CONFIG_POSIX_MQUEUE is not set
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_HOTPLUG is not set
+CONFIG_HOTPLUG=y
CONFIG_KOBJECT_UEVENT=y
# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
CONFIG_EMBEDDED=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
@@ -40,6 +43,7 @@ CONFIG_CC_ALIGN_LABELS=0
CONFIG_CC_ALIGN_LOOPS=0
CONFIG_CC_ALIGN_JUMPS=0
# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
#
# Loadable module support
@@ -49,39 +53,68 @@ CONFIG_CC_ALIGN_JUMPS=0
#
# Machine selection
#
-# CONFIG_MACH_JAZZ is not set
-# CONFIG_MACH_VR41XX is not set
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_MIPS_PB1550 is not set
+# CONFIG_MIPS_PB1200 is not set
+# CONFIG_MIPS_DB1000 is not set
+# CONFIG_MIPS_DB1100 is not set
+# CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
+# CONFIG_MIPS_DB1200 is not set
+# CONFIG_MIPS_MIRAGE is not set
# CONFIG_MIPS_COBALT is not set
# CONFIG_MACH_DECSTATION is not set
# CONFIG_MIPS_EV64120 is not set
# CONFIG_MIPS_EV96100 is not set
# CONFIG_MIPS_IVR is not set
-# CONFIG_LASAT is not set
# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_LASAT is not set
# CONFIG_MIPS_ATLAS is not set
# CONFIG_MIPS_MALTA is not set
# CONFIG_MIPS_SEAD is not set
+# CONFIG_MIPS_SIM is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
# CONFIG_MOMENCO_OCELOT is not set
-CONFIG_MOMENCO_OCELOT_G=y
-# CONFIG_MOMENCO_OCELOT_C is not set
# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_JAGUAR_ATX is not set
-# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+CONFIG_MOMENCO_OCELOT_G=y
+# CONFIG_MIPS_XXS1500 is not set
+# CONFIG_PNX8550_V2PCI is not set
+# CONFIG_PNX8550_JBS is not set
# CONFIG_DDB5074 is not set
# CONFIG_DDB5476 is not set
# CONFIG_DDB5477 is not set
-# CONFIG_NEC_OSPREY is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_QEMU is not set
# CONFIG_SGI_IP22 is not set
# CONFIG_SGI_IP27 is not set
# CONFIG_SGI_IP32 is not set
-# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SIBYTE_BIGSUR is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_PTSWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CRHONE is not set
# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_TOSHIBA_RBTX4927 is not set
+# CONFIG_TOSHIBA_RBTX4938 is not set
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_HAVE_DEC_LOCK=y
CONFIG_DMA_NONCOHERENT=y
CONFIG_DMA_NEED_PCI_MAP_STATE=y
+CONFIG_CPU_BIG_ENDIAN=y
# CONFIG_CPU_LITTLE_ENDIAN is not set
+CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
CONFIG_IRQ_CPU=y
CONFIG_IRQ_CPU_RM7K=y
CONFIG_PCI_MARVELL=y
@@ -94,8 +127,10 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5
#
# CPU selection
#
-# CONFIG_CPU_MIPS32 is not set
-# CONFIG_CPU_MIPS64 is not set
+# CONFIG_CPU_MIPS32_R1 is not set
+# CONFIG_CPU_MIPS32_R2 is not set
+# CONFIG_CPU_MIPS64_R1 is not set
+# CONFIG_CPU_MIPS64_R2 is not set
# CONFIG_CPU_R3000 is not set
# CONFIG_CPU_TX39XX is not set
# CONFIG_CPU_VR41XX is not set
@@ -111,6 +146,17 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5
CONFIG_CPU_RM7000=y
# CONFIG_CPU_RM9000 is not set
# CONFIG_CPU_SB1 is not set
+CONFIG_SYS_HAS_CPU_RM7000=y
+CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
+CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y
+
+#
+# Kernel type
+#
+# CONFIG_32BIT is not set
+CONFIG_64BIT=y
CONFIG_PAGE_SIZE_4KB=y
# CONFIG_PAGE_SIZE_8KB is not set
# CONFIG_PAGE_SIZE_16KB is not set
@@ -118,9 +164,23 @@ CONFIG_PAGE_SIZE_4KB=y
CONFIG_BOARD_SCACHE=y
CONFIG_RM7000_CPU_SCACHE=y
CONFIG_CPU_HAS_PREFETCH=y
+# CONFIG_MIPS_MT is not set
CONFIG_CPU_HAS_LLSC=y
CONFIG_CPU_HAS_LLDSCD=y
CONFIG_CPU_HAS_SYNC=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_CPU_SUPPORTS_HIGHMEM=y
+CONFIG_ARCH_FLATMEM_ENABLE=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_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
#
@@ -129,7 +189,6 @@ CONFIG_CPU_HAS_SYNC=y
CONFIG_HW_HAS_PCI=y
CONFIG_PCI=y
CONFIG_PCI_LEGACY_PROC=y
-CONFIG_PCI_NAMES=y
CONFIG_MMU=y
#
@@ -138,10 +197,6 @@ CONFIG_MMU=y
# CONFIG_PCCARD is not set
#
-# PC-card bridges
-#
-
-#
# PCI Hotplug Support
#
# CONFIG_HOTPLUG_PCI is not set
@@ -159,6 +214,79 @@ CONFIG_MIPS32_N32=y
CONFIG_BINFMT_ELF32=y
#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_PACKET is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=y
+CONFIG_NET_KEY=y
+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_TUNNEL=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+# CONFIG_IPV6 is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# 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_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_IEEE80211=y
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=y
+CONFIG_IEEE80211_CRYPT_CCMP=y
+CONFIG_IEEE80211_CRYPT_TKIP=y
+
+#
# Device Drivers
#
@@ -167,7 +295,12 @@ CONFIG_BINFMT_ELF32=y
#
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
+CONFIG_FW_LOADER=y
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+CONFIG_CONNECTOR=y
#
# Memory Technology Devices (MTD)
@@ -186,7 +319,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
#
# Block devices
#
-# CONFIG_BLK_DEV_FD is not set
# CONFIG_BLK_CPQ_DA is not set
# CONFIG_BLK_CPQ_CISS_DA is not set
# CONFIG_BLK_DEV_DAC960 is not set
@@ -197,7 +329,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_BLK_DEV_SX8 is not set
# CONFIG_BLK_DEV_RAM is not set
CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_INITRAMFS_SOURCE=""
CONFIG_CDROM_PKTCDVD=y
CONFIG_CDROM_PKTCDVD_BUFFERS=8
# CONFIG_CDROM_PKTCDVD_WCACHE is not set
@@ -219,6 +350,7 @@ CONFIG_ATA_OVER_ETH=y
#
# SCSI device support
#
+CONFIG_RAID_ATTRS=y
# CONFIG_SCSI is not set
#
@@ -229,6 +361,7 @@ CONFIG_ATA_OVER_ETH=y
#
# Fusion MPT device support
#
+# CONFIG_FUSION is not set
#
# IEEE 1394 (FireWire) support
@@ -241,77 +374,13 @@ CONFIG_ATA_OVER_ETH=y
# CONFIG_I2O is not set
#
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-# CONFIG_PACKET is not set
-CONFIG_NETLINK_DEV=y
-CONFIG_UNIX=y
-CONFIG_NET_KEY=y
-CONFIG_INET=y
-# CONFIG_IP_MULTICAST is not set
-# CONFIG_IP_ADVANCED_ROUTER is not set
-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_TUNNEL=y
-CONFIG_IP_TCPDIAG=y
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-# CONFIG_IPV6 is not set
-# CONFIG_NETFILTER is not set
-CONFIG_XFRM=y
-CONFIG_XFRM_USER=y
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP 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_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
-
-#
-# Network testing
+# Network device support
#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
CONFIG_NETDEVICES=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_EQUALIZER is not set
# CONFIG_TUN is not set
-# CONFIG_ETHERTAP is not set
#
# ARCnet devices
@@ -319,6 +388,21 @@ CONFIG_NETDEVICES=y
# CONFIG_ARCNET is not set
#
+# PHY device support
+#
+CONFIG_PHYLIB=y
+CONFIG_PHYCONTROL=y
+
+#
+# MII PHY device drivers
+#
+CONFIG_MARVELL_PHY=y
+CONFIG_DAVICOM_PHY=y
+CONFIG_QSEMI_PHY=y
+CONFIG_LXT_PHY=y
+CONFIG_CICADA_PHY=y
+
+#
# Ethernet (10 or 100Mbit)
#
CONFIG_NET_ETHERNET=y
@@ -345,12 +429,16 @@ CONFIG_GALILEO_64240_ETH=y
# CONFIG_HAMACHI is not set
# CONFIG_YELLOWFIN is not set
# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
# CONFIG_SK98LIN is not set
# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
#
# Ethernet (10000 Mbit)
#
+# CONFIG_CHELSIO_T1 is not set
# CONFIG_IXGB is not set
# CONFIG_S2IO is not set
@@ -363,6 +451,8 @@ CONFIG_GALILEO_64240_ETH=y
# Wireless LAN (non-hamradio)
#
# CONFIG_NET_RADIO is not set
+# CONFIG_IPW_DEBUG is not set
+CONFIG_IPW2200=y
#
# Wan interfaces
@@ -374,6 +464,8 @@ CONFIG_GALILEO_64240_ETH=y
# CONFIG_SLIP is not set
# CONFIG_SHAPER is not set
# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
#
# ISDN subsystem
@@ -403,19 +495,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
# CONFIG_INPUT_EVBUG is not set
#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=y
-# CONFIG_SERIO_I8042 is not set
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_PCIPS2 is not set
-# CONFIG_SERIO_LIBPS2 is not set
-CONFIG_SERIO_RAW=y
-
-#
# Input Device Drivers
#
# CONFIG_INPUT_KEYBOARD is not set
@@ -425,6 +504,17 @@ CONFIG_SERIO_RAW=y
# CONFIG_INPUT_MISC is not set
#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_PCIPS2 is not set
+# CONFIG_SERIO_LIBPS2 is not set
+CONFIG_SERIO_RAW=y
+# CONFIG_GAMEPORT is not set
+
+#
# Character devices
#
CONFIG_VT=y
@@ -445,6 +535,7 @@ CONFIG_SERIAL_8250_NR_UARTS=4
#
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
CONFIG_UNIX98_PTYS=y
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
@@ -471,6 +562,11 @@ CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_RAW_DRIVER is not set
#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+
+#
# I2C support
#
# CONFIG_I2C is not set
@@ -481,10 +577,20 @@ CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_W1 is not set
#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
+#
# Misc devices
#
#
+# Multimedia Capabilities Port drivers
+#
+
+#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
@@ -504,7 +610,6 @@ CONFIG_LEGACY_PTY_COUNT=256
#
# CONFIG_VGA_CONSOLE is not set
CONFIG_DUMMY_CONSOLE=y
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Sound
@@ -514,13 +619,9 @@ CONFIG_DUMMY_CONSOLE=y
#
# USB support
#
-# CONFIG_USB is not set
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB_ARCH_HAS_OHCI=y
-
-#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
-#
+# CONFIG_USB is not set
#
# USB Gadget Support
@@ -538,21 +639,29 @@ CONFIG_USB_ARCH_HAS_OHCI=y
# CONFIG_INFINIBAND is not set
#
+# SN Devices
+#
+
+#
# File systems
#
CONFIG_EXT2_FS=y
# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
# CONFIG_EXT3_FS is not set
# CONFIG_JBD 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_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
# CONFIG_QUOTA is not set
CONFIG_DNOTIFY=y
# CONFIG_AUTOFS_FS is not set
# CONFIG_AUTOFS4_FS is not set
+CONFIG_FUSE_FS=y
#
# CD-ROM/DVD Filesystems
@@ -573,12 +682,10 @@ CONFIG_DNOTIFY=y
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
-CONFIG_DEVPTS_FS_XATTR=y
-CONFIG_DEVPTS_FS_SECURITY=y
# CONFIG_TMPFS is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
+CONFIG_RELAYFS_FS=y
#
# Miscellaneous filesystems
@@ -610,6 +717,7 @@ CONFIG_NFSD=y
CONFIG_ROOT_NFS=y
CONFIG_LOCKD=y
CONFIG_EXPORTFS=y
+CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
@@ -618,6 +726,7 @@ CONFIG_SUNRPC=y
# CONFIG_NCP_FS is not set
# CONFIG_CODA_FS is not set
# CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
#
# Partition Types
@@ -638,7 +747,9 @@ CONFIG_MSDOS_PARTITION=y
#
# Kernel hacking
#
+# CONFIG_PRINTK_TIME is not set
# CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=14
CONFIG_CROSSCOMPILE=y
CONFIG_CMDLINE=""
@@ -652,7 +763,31 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
#
# Cryptographic options
#
-# CONFIG_CRYPTO is not set
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_NULL=y
+CONFIG_CRYPTO_MD4=y
+CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_SHA1=y
+CONFIG_CRYPTO_SHA256=y
+CONFIG_CRYPTO_SHA512=y
+CONFIG_CRYPTO_WP512=y
+CONFIG_CRYPTO_TGR192=y
+CONFIG_CRYPTO_DES=y
+CONFIG_CRYPTO_BLOWFISH=y
+CONFIG_CRYPTO_TWOFISH=y
+CONFIG_CRYPTO_SERPENT=y
+CONFIG_CRYPTO_AES=y
+CONFIG_CRYPTO_CAST5=y
+CONFIG_CRYPTO_CAST6=y
+CONFIG_CRYPTO_TEA=y
+CONFIG_CRYPTO_ARC4=y
+CONFIG_CRYPTO_KHAZAD=y
+CONFIG_CRYPTO_ANUBIS=y
+CONFIG_CRYPTO_DEFLATE=y
+CONFIG_CRYPTO_MICHAEL_MIC=y
+CONFIG_CRYPTO_CRC32C=y
+# CONFIG_CRYPTO_TEST is not set
#
# Hardware crypto devices
@@ -662,7 +797,8 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
# Library routines
#
# CONFIG_CRC_CCITT is not set
-# CONFIG_CRC32 is not set
-# CONFIG_LIBCRC32C is not set
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_CRC16=y
+CONFIG_CRC32=y
+CONFIG_LIBCRC32C=y
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
diff --git a/arch/mips/configs/pb1100_defconfig b/arch/mips/configs/pb1100_defconfig
index 813e3a8b480b..47247addee1b 100644
--- a/arch/mips/configs/pb1100_defconfig
+++ b/arch/mips/configs/pb1100_defconfig
@@ -1,12 +1,9 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-rc2
-# Wed Jan 26 02:49:08 2005
+# Linux kernel version: 2.6.14-rc2
+# Thu Oct 20 22:26:41 2005
#
CONFIG_MIPS=y
-# CONFIG_64BIT is not set
-# CONFIG_64BIT is not set
-CONFIG_32BIT=y
#
# Code maturity level options
@@ -14,24 +11,29 @@ CONFIG_32BIT=y
CONFIG_EXPERIMENTAL=y
CONFIG_CLEAN_COMPILE=y
CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
#
# General setup
#
CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
# CONFIG_POSIX_MQUEUE is not set
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
CONFIG_HOTPLUG=y
CONFIG_KOBJECT_UEVENT=y
# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
CONFIG_EMBEDDED=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
@@ -41,6 +43,7 @@ CONFIG_CC_ALIGN_LABELS=0
CONFIG_CC_ALIGN_LOOPS=0
CONFIG_CC_ALIGN_JUMPS=0
# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
#
# Loadable module support
@@ -56,56 +59,70 @@ CONFIG_KMOD=y
#
# Machine selection
#
-# CONFIG_MACH_JAZZ is not set
-# CONFIG_MACH_VR41XX is not set
-# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_PB1000 is not set
+CONFIG_MIPS_PB1100=y
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_MIPS_PB1550 is not set
+# CONFIG_MIPS_PB1200 is not set
+# CONFIG_MIPS_DB1000 is not set
+# CONFIG_MIPS_DB1100 is not set
+# CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
+# CONFIG_MIPS_DB1200 is not set
+# CONFIG_MIPS_MIRAGE is not set
# CONFIG_MIPS_COBALT is not set
# CONFIG_MACH_DECSTATION is not set
# CONFIG_MIPS_EV64120 is not set
# CONFIG_MIPS_EV96100 is not set
# CONFIG_MIPS_IVR is not set
-# CONFIG_LASAT is not set
# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_LASAT is not set
# CONFIG_MIPS_ATLAS is not set
# CONFIG_MIPS_MALTA is not set
# CONFIG_MIPS_SEAD is not set
+# CONFIG_MIPS_SIM is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
# CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_G is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_JAGUAR_ATX is not set
-# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MIPS_XXS1500 is not set
+# CONFIG_PNX8550_V2PCI is not set
+# CONFIG_PNX8550_JBS is not set
# CONFIG_DDB5074 is not set
# CONFIG_DDB5476 is not set
# CONFIG_DDB5477 is not set
-# CONFIG_NEC_OSPREY is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_QEMU is not set
# CONFIG_SGI_IP22 is not set
-CONFIG_SOC_AU1X00=y
-# CONFIG_SOC_AU1000 is not set
-CONFIG_SOC_AU1100=y
-# CONFIG_SOC_AU1500 is not set
-# CONFIG_SOC_AU1550 is not set
-# CONFIG_MIPS_PB1000 is not set
-CONFIG_MIPS_PB1100=y
-# CONFIG_MIPS_PB1500 is not set
-# CONFIG_MIPS_PB1550 is not set
-# CONFIG_MIPS_DB1000 is not set
-# CONFIG_MIPS_DB1100 is not set
-# CONFIG_MIPS_DB1500 is not set
-# CONFIG_MIPS_DB1550 is not set
-# CONFIG_MIPS_BOSPORUS is not set
-# CONFIG_MIPS_MIRAGE is not set
-# CONFIG_MIPS_XXS1500 is not set
-# CONFIG_MIPS_MTX1 is not set
-# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_BIGSUR is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_PTSWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CRHONE is not set
# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
# CONFIG_TOSHIBA_RBTX4927 is not set
+# CONFIG_TOSHIBA_RBTX4938 is not set
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_HAVE_DEC_LOCK=y
CONFIG_DMA_NONCOHERENT=y
CONFIG_DMA_NEED_PCI_MAP_STATE=y
+# CONFIG_CPU_BIG_ENDIAN is not set
CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
+CONFIG_SOC_AU1100=y
+CONFIG_SOC_AU1X00=y
CONFIG_SWAP_IO_SPACE=y
# CONFIG_AU1X00_USB_DEVICE is not set
CONFIG_MIPS_L1_CACHE_SHIFT=5
@@ -113,8 +130,10 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5
#
# CPU selection
#
-CONFIG_CPU_MIPS32=y
-# CONFIG_CPU_MIPS64 is not set
+CONFIG_CPU_MIPS32_R1=y
+# CONFIG_CPU_MIPS32_R2 is not set
+# CONFIG_CPU_MIPS64_R1 is not set
+# CONFIG_CPU_MIPS64_R2 is not set
# CONFIG_CPU_R3000 is not set
# CONFIG_CPU_TX39XX is not set
# CONFIG_CPU_VR41XX is not set
@@ -130,15 +149,39 @@ CONFIG_CPU_MIPS32=y
# CONFIG_CPU_RM7000 is not set
# CONFIG_CPU_RM9000 is not set
# CONFIG_CPU_SB1 is not set
+CONFIG_SYS_HAS_CPU_MIPS32_R1=y
+CONFIG_CPU_MIPS32=y
+CONFIG_CPU_MIPSR1=y
+CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
+
+#
+# Kernel type
+#
+CONFIG_32BIT=y
+# CONFIG_64BIT is not set
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_CPU_HAS_PREFETCH=y
-# CONFIG_64BIT_PHYS_ADDR is not set
+# CONFIG_MIPS_MT is not set
+CONFIG_64BIT_PHYS_ADDR=y
# CONFIG_CPU_ADVANCED is not set
CONFIG_CPU_HAS_LLSC=y
CONFIG_CPU_HAS_SYNC=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_ARCH_FLATMEM_ENABLE=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_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
#
@@ -154,6 +197,8 @@ CONFIG_MMU=y
CONFIG_PCCARD=m
# CONFIG_PCMCIA_DEBUG is not set
CONFIG_PCMCIA=m
+CONFIG_PCMCIA_LOAD_CIS=y
+CONFIG_PCMCIA_IOCTL=y
#
# PC-card bridges
@@ -171,6 +216,100 @@ CONFIG_PCMCIA=m
CONFIG_BINFMT_ELF=y
# CONFIG_BINFMT_MISC is not set
CONFIG_TRAD_SIGNALS=y
+# CONFIG_PM is not set
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+CONFIG_NET_KEY=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+CONFIG_INET_TUNNEL=m
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+
+#
+# IP: Virtual Server Configuration
+#
+# CONFIG_IP_VS is not set
+# CONFIG_IPV6 is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+CONFIG_NETFILTER_NETLINK=m
+CONFIG_NETFILTER_NETLINK_QUEUE=m
+CONFIG_NETFILTER_NETLINK_LOG=m
+
+#
+# IP: Netfilter Configuration
+#
+# CONFIG_IP_NF_CONNTRACK is not set
+CONFIG_IP_NF_PPTP=m
+# CONFIG_IP_NF_QUEUE is not set
+# CONFIG_IP_NF_IPTABLES is not set
+# CONFIG_IP_NF_ARPTABLES is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP 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_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_IEEE80211=m
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=m
+CONFIG_IEEE80211_CRYPT_CCMP=m
+CONFIG_IEEE80211_CRYPT_TKIP=m
#
# Device Drivers
@@ -181,15 +320,20 @@ CONFIG_TRAD_SIGNALS=y
#
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
+CONFIG_FW_LOADER=m
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+CONFIG_CONNECTOR=m
#
# Memory Technology Devices (MTD)
#
CONFIG_MTD=y
# CONFIG_MTD_DEBUG is not set
-CONFIG_MTD_PARTITIONS=y
# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
# CONFIG_MTD_REDBOOT_PARTS is not set
# CONFIG_MTD_CMDLINE_PARTS is not set
@@ -233,9 +377,8 @@ CONFIG_MTD_CFI_UTIL=y
#
# CONFIG_MTD_COMPLEX_MAPPINGS is not set
# CONFIG_MTD_PHYSMAP is not set
-CONFIG_MTD_PB1100=y
-CONFIG_MTD_PB1500_BOOT=y
-CONFIG_MTD_PB1500_USER=y
+CONFIG_MTD_ALCHEMY=y
+# CONFIG_MTD_PLATRAM is not set
#
# Self-contained MTD device drivers
@@ -270,14 +413,12 @@ CONFIG_MTD_PB1500_USER=y
#
# Block devices
#
-# CONFIG_BLK_DEV_FD is not set
# CONFIG_BLK_DEV_COW_COMMON is not set
CONFIG_BLK_DEV_LOOP=y
# CONFIG_BLK_DEV_CRYPTOLOOP is not set
# CONFIG_BLK_DEV_NBD is not set
# CONFIG_BLK_DEV_RAM is not set
CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_INITRAMFS_SOURCE=""
# CONFIG_LBD is not set
CONFIG_CDROM_PKTCDVD=m
CONFIG_CDROM_PKTCDVD_BUFFERS=8
@@ -300,6 +441,7 @@ CONFIG_ATA_OVER_ETH=m
#
# SCSI device support
#
+CONFIG_RAID_ATTRS=m
# CONFIG_SCSI is not set
#
@@ -310,6 +452,7 @@ CONFIG_ATA_OVER_ETH=m
#
# Fusion MPT device support
#
+# CONFIG_FUSION is not set
#
# IEEE 1394 (FireWire) support
@@ -320,94 +463,28 @@ CONFIG_ATA_OVER_ETH=m
#
#
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
-CONFIG_NETLINK_DEV=y
-CONFIG_UNIX=y
-CONFIG_NET_KEY=y
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-# CONFIG_IP_ADVANCED_ROUTER is not set
-CONFIG_IP_PNP=y
-# CONFIG_IP_PNP_DHCP is not set
-CONFIG_IP_PNP_BOOTP=y
-# CONFIG_IP_PNP_RARP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_IP_MROUTE is not set
-# CONFIG_ARPD is not set
-# CONFIG_SYN_COOKIES is not set
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-CONFIG_INET_TUNNEL=m
-CONFIG_IP_TCPDIAG=m
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-
-#
-# IP: Virtual Server Configuration
-#
-# CONFIG_IP_VS is not set
-# CONFIG_IPV6 is not set
-CONFIG_NETFILTER=y
-# CONFIG_NETFILTER_DEBUG is not set
-
-#
-# IP: Netfilter Configuration
-#
-# CONFIG_IP_NF_CONNTRACK is not set
-CONFIG_IP_NF_CONNTRACK_MARK=y
-# CONFIG_IP_NF_QUEUE is not set
-# CONFIG_IP_NF_IPTABLES is not set
-# CONFIG_IP_NF_ARPTABLES is not set
-CONFIG_XFRM=y
-CONFIG_XFRM_USER=m
-
-#
-# SCTP Configuration (EXPERIMENTAL)
+# Network device support
#
-# CONFIG_IP_SCTP 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_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
#
-# QoS and/or fair queueing
+# PHY device support
#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
+CONFIG_PHYLIB=m
+CONFIG_PHYCONTROL=y
#
-# Network testing
+# MII PHY device drivers
#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
-CONFIG_NETDEVICES=y
-# CONFIG_DUMMY is not set
-# CONFIG_BONDING is not set
-# CONFIG_EQUALIZER is not set
-# CONFIG_TUN is not set
-# CONFIG_ETHERTAP is not set
+CONFIG_MARVELL_PHY=m
+CONFIG_DAVICOM_PHY=m
+CONFIG_QSEMI_PHY=m
+CONFIG_LXT_PHY=m
+CONFIG_CICADA_PHY=m
#
# Ethernet (10 or 100Mbit)
@@ -453,6 +530,8 @@ CONFIG_PPPOE=m
# CONFIG_SLIP is not set
# CONFIG_SHAPER is not set
# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
#
# ISDN subsystem
@@ -482,18 +561,6 @@ CONFIG_INPUT_EVDEV=y
# CONFIG_INPUT_EVBUG is not set
#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=y
-# CONFIG_SERIO_I8042 is not set
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_LIBPS2 is not set
-CONFIG_SERIO_RAW=m
-
-#
# Input Device Drivers
#
# CONFIG_INPUT_KEYBOARD is not set
@@ -503,6 +570,16 @@ CONFIG_SERIO_RAW=m
# CONFIG_INPUT_MISC is not set
#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_LIBPS2 is not set
+CONFIG_SERIO_RAW=m
+# CONFIG_GAMEPORT is not set
+
+#
# Character devices
#
CONFIG_VT=y
@@ -534,14 +611,14 @@ CONFIG_LEGACY_PTY_COUNT=256
# Watchdog Cards
#
# CONFIG_WATCHDOG is not set
-CONFIG_RTC=y
+# CONFIG_RTC is not set
+# CONFIG_GEN_RTC is not set
# CONFIG_DTLK is not set
# CONFIG_R3964 is not set
#
# Ftape, the floppy tape device driver
#
-# CONFIG_DRM is not set
#
# PCMCIA character devices
@@ -550,6 +627,10 @@ CONFIG_SYNCLINK_CS=m
# CONFIG_RAW_DRIVER is not set
#
+# TPM devices
+#
+
+#
# I2C support
#
# CONFIG_I2C is not set
@@ -560,10 +641,20 @@ CONFIG_SYNCLINK_CS=m
# CONFIG_W1 is not set
#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
+#
# Misc devices
#
#
+# Multimedia Capabilities Port drivers
+#
+
+#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
@@ -583,7 +674,6 @@ CONFIG_SYNCLINK_CS=m
#
# CONFIG_VGA_CONSOLE is not set
CONFIG_DUMMY_CONSOLE=y
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Sound
@@ -593,12 +683,9 @@ CONFIG_DUMMY_CONSOLE=y
#
# USB support
#
-# CONFIG_USB_ARCH_HAS_HCD is not set
-# CONFIG_USB_ARCH_HAS_OHCI is not set
-
-#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
-#
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+# CONFIG_USB is not set
#
# USB Gadget Support
@@ -613,7 +700,10 @@ CONFIG_DUMMY_CONSOLE=y
#
# InfiniBand support
#
-# CONFIG_INFINIBAND is not set
+
+#
+# SN Devices
+#
#
# File systems
@@ -622,6 +712,7 @@ CONFIG_EXT2_FS=y
CONFIG_EXT2_FS_XATTR=y
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_FS_XATTR=y
CONFIG_EXT3_FS_POSIX_ACL=y
@@ -640,10 +731,12 @@ CONFIG_FS_POSIX_ACL=y
# CONFIG_XFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
# CONFIG_QUOTA is not set
CONFIG_DNOTIFY=y
CONFIG_AUTOFS_FS=m
CONFIG_AUTOFS4_FS=m
+CONFIG_FUSE_FS=m
#
# CD-ROM/DVD Filesystems
@@ -664,13 +757,10 @@ CONFIG_AUTOFS4_FS=m
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
-CONFIG_DEVPTS_FS_XATTR=y
-CONFIG_DEVPTS_FS_SECURITY=y
CONFIG_TMPFS=y
-# CONFIG_TMPFS_XATTR is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
+CONFIG_RELAYFS_FS=m
#
# Miscellaneous filesystems
@@ -704,6 +794,7 @@ CONFIG_NFSD=m
CONFIG_ROOT_NFS=y
CONFIG_LOCKD=y
CONFIG_EXPORTFS=m
+CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
@@ -713,6 +804,7 @@ CONFIG_SMB_FS=m
# CONFIG_NCP_FS is not set
# CONFIG_CODA_FS is not set
# CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
#
# Partition Types
@@ -772,7 +864,9 @@ CONFIG_NLS_DEFAULT="iso8859-1"
#
# Kernel hacking
#
+# CONFIG_PRINTK_TIME is not set
# CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=14
CONFIG_CROSSCOMPILE=y
CONFIG_CMDLINE=""
@@ -788,26 +882,27 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
#
CONFIG_CRYPTO=y
CONFIG_CRYPTO_HMAC=y
-CONFIG_CRYPTO_NULL=y
-# CONFIG_CRYPTO_MD4 is not set
-# CONFIG_CRYPTO_MD5 is not set
-# CONFIG_CRYPTO_SHA1 is not set
-# CONFIG_CRYPTO_SHA256 is not set
-CONFIG_CRYPTO_SHA512=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
CONFIG_CRYPTO_WP512=m
-# CONFIG_CRYPTO_DES is not set
-# CONFIG_CRYPTO_BLOWFISH is not set
-CONFIG_CRYPTO_TWOFISH=y
-# CONFIG_CRYPTO_SERPENT is not set
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_SERPENT=m
CONFIG_CRYPTO_AES=m
-# CONFIG_CRYPTO_CAST5 is not set
-# CONFIG_CRYPTO_CAST6 is not set
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
CONFIG_CRYPTO_TEA=m
-# CONFIG_CRYPTO_ARC4 is not set
+CONFIG_CRYPTO_ARC4=m
CONFIG_CRYPTO_KHAZAD=m
CONFIG_CRYPTO_ANUBIS=m
-CONFIG_CRYPTO_DEFLATE=y
-CONFIG_CRYPTO_MICHAEL_MIC=y
+CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
CONFIG_CRYPTO_CRC32C=m
# CONFIG_CRYPTO_TEST is not set
@@ -819,9 +914,8 @@ CONFIG_CRYPTO_CRC32C=m
# Library routines
#
CONFIG_CRC_CCITT=m
+CONFIG_CRC16=m
CONFIG_CRC32=y
CONFIG_LIBCRC32C=m
-CONFIG_ZLIB_INFLATE=y
-CONFIG_ZLIB_DEFLATE=y
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_ZLIB_INFLATE=m
+CONFIG_ZLIB_DEFLATE=m
diff --git a/arch/mips/configs/pb1500_defconfig b/arch/mips/configs/pb1500_defconfig
index 49e528340a39..f91a4eaae51a 100644
--- a/arch/mips/configs/pb1500_defconfig
+++ b/arch/mips/configs/pb1500_defconfig
@@ -1,12 +1,9 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-rc2
-# Wed Jan 26 02:49:09 2005
+# Linux kernel version: 2.6.14-rc2
+# Thu Oct 20 22:26:44 2005
#
CONFIG_MIPS=y
-# CONFIG_64BIT is not set
-# CONFIG_64BIT is not set
-CONFIG_32BIT=y
#
# Code maturity level options
@@ -14,24 +11,29 @@ CONFIG_32BIT=y
CONFIG_EXPERIMENTAL=y
CONFIG_CLEAN_COMPILE=y
CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
#
# General setup
#
CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
# CONFIG_POSIX_MQUEUE is not set
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
CONFIG_HOTPLUG=y
CONFIG_KOBJECT_UEVENT=y
# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
CONFIG_EMBEDDED=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
@@ -41,6 +43,7 @@ CONFIG_CC_ALIGN_LABELS=0
CONFIG_CC_ALIGN_LOOPS=0
CONFIG_CC_ALIGN_JUMPS=0
# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
#
# Loadable module support
@@ -56,63 +59,80 @@ CONFIG_KMOD=y
#
# Machine selection
#
-# CONFIG_MACH_JAZZ is not set
-# CONFIG_MACH_VR41XX is not set
-# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+CONFIG_MIPS_PB1500=y
+# CONFIG_MIPS_PB1550 is not set
+# CONFIG_MIPS_PB1200 is not set
+# CONFIG_MIPS_DB1000 is not set
+# CONFIG_MIPS_DB1100 is not set
+# CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
+# CONFIG_MIPS_DB1200 is not set
+# CONFIG_MIPS_MIRAGE is not set
# CONFIG_MIPS_COBALT is not set
# CONFIG_MACH_DECSTATION is not set
# CONFIG_MIPS_EV64120 is not set
# CONFIG_MIPS_EV96100 is not set
# CONFIG_MIPS_IVR is not set
-# CONFIG_LASAT is not set
# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_LASAT is not set
# CONFIG_MIPS_ATLAS is not set
# CONFIG_MIPS_MALTA is not set
# CONFIG_MIPS_SEAD is not set
+# CONFIG_MIPS_SIM is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
# CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_G is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_JAGUAR_ATX is not set
-# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MIPS_XXS1500 is not set
+# CONFIG_PNX8550_V2PCI is not set
+# CONFIG_PNX8550_JBS is not set
# CONFIG_DDB5074 is not set
# CONFIG_DDB5476 is not set
# CONFIG_DDB5477 is not set
-# CONFIG_NEC_OSPREY is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_QEMU is not set
# CONFIG_SGI_IP22 is not set
-CONFIG_SOC_AU1X00=y
-# CONFIG_SOC_AU1000 is not set
-# CONFIG_SOC_AU1100 is not set
-CONFIG_SOC_AU1500=y
-# CONFIG_SOC_AU1550 is not set
-# CONFIG_MIPS_PB1000 is not set
-# CONFIG_MIPS_PB1100 is not set
-CONFIG_MIPS_PB1500=y
-# CONFIG_MIPS_PB1550 is not set
-# CONFIG_MIPS_DB1000 is not set
-# CONFIG_MIPS_DB1100 is not set
-# CONFIG_MIPS_DB1500 is not set
-# CONFIG_MIPS_DB1550 is not set
-# CONFIG_MIPS_BOSPORUS is not set
-# CONFIG_MIPS_MIRAGE is not set
-# CONFIG_MIPS_XXS1500 is not set
-# CONFIG_MIPS_MTX1 is not set
-# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_BIGSUR is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_PTSWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CRHONE is not set
# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
# CONFIG_TOSHIBA_RBTX4927 is not set
+# CONFIG_TOSHIBA_RBTX4938 is not set
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_HAVE_DEC_LOCK=y
-CONFIG_DMA_COHERENT=y
+CONFIG_DMA_NONCOHERENT=y
+CONFIG_DMA_NEED_PCI_MAP_STATE=y
+# CONFIG_CPU_BIG_ENDIAN is not set
CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
+CONFIG_SOC_AU1500=y
+CONFIG_SOC_AU1X00=y
# CONFIG_AU1X00_USB_DEVICE is not set
CONFIG_MIPS_L1_CACHE_SHIFT=5
#
# CPU selection
#
-CONFIG_CPU_MIPS32=y
-# CONFIG_CPU_MIPS64 is not set
+CONFIG_CPU_MIPS32_R1=y
+# CONFIG_CPU_MIPS32_R2 is not set
+# CONFIG_CPU_MIPS64_R1 is not set
+# CONFIG_CPU_MIPS64_R2 is not set
# CONFIG_CPU_R3000 is not set
# CONFIG_CPU_TX39XX is not set
# CONFIG_CPU_VR41XX is not set
@@ -128,15 +148,39 @@ CONFIG_CPU_MIPS32=y
# CONFIG_CPU_RM7000 is not set
# CONFIG_CPU_RM9000 is not set
# CONFIG_CPU_SB1 is not set
+CONFIG_SYS_HAS_CPU_MIPS32_R1=y
+CONFIG_CPU_MIPS32=y
+CONFIG_CPU_MIPSR1=y
+CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
+
+#
+# Kernel type
+#
+CONFIG_32BIT=y
+# CONFIG_64BIT is not set
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_CPU_HAS_PREFETCH=y
+# CONFIG_MIPS_MT is not set
CONFIG_64BIT_PHYS_ADDR=y
# CONFIG_CPU_ADVANCED is not set
CONFIG_CPU_HAS_LLSC=y
CONFIG_CPU_HAS_SYNC=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_ARCH_FLATMEM_ENABLE=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_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
#
@@ -145,7 +189,6 @@ CONFIG_CPU_HAS_SYNC=y
CONFIG_HW_HAS_PCI=y
CONFIG_PCI=y
CONFIG_PCI_LEGACY_PROC=y
-CONFIG_PCI_NAMES=y
CONFIG_MMU=y
#
@@ -154,6 +197,8 @@ CONFIG_MMU=y
CONFIG_PCCARD=m
# CONFIG_PCMCIA_DEBUG is not set
CONFIG_PCMCIA=m
+CONFIG_PCMCIA_LOAD_CIS=y
+CONFIG_PCMCIA_IOCTL=y
CONFIG_CARDBUS=y
#
@@ -177,6 +222,100 @@ CONFIG_PCCARD_NONSTATIC=m
CONFIG_BINFMT_ELF=y
# CONFIG_BINFMT_MISC is not set
CONFIG_TRAD_SIGNALS=y
+# CONFIG_PM is not set
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+CONFIG_NET_KEY=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+CONFIG_INET_TUNNEL=m
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+
+#
+# IP: Virtual Server Configuration
+#
+# CONFIG_IP_VS is not set
+# CONFIG_IPV6 is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+CONFIG_NETFILTER_NETLINK=m
+CONFIG_NETFILTER_NETLINK_QUEUE=m
+CONFIG_NETFILTER_NETLINK_LOG=m
+
+#
+# IP: Netfilter Configuration
+#
+# CONFIG_IP_NF_CONNTRACK is not set
+CONFIG_IP_NF_PPTP=m
+# CONFIG_IP_NF_QUEUE is not set
+# CONFIG_IP_NF_IPTABLES is not set
+# CONFIG_IP_NF_ARPTABLES is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP 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_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_IEEE80211=m
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=m
+CONFIG_IEEE80211_CRYPT_CCMP=m
+CONFIG_IEEE80211_CRYPT_TKIP=m
#
# Device Drivers
@@ -187,12 +326,87 @@ CONFIG_TRAD_SIGNALS=y
#
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
+CONFIG_FW_LOADER=m
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+CONFIG_CONNECTOR=m
#
# Memory Technology Devices (MTD)
#
-# CONFIG_MTD is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_CMDLINE_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL 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_AMDSTD_RETRY=0
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PHYSMAP is not set
+CONFIG_MTD_ALCHEMY=y
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLKMTD 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
+
+#
+# NAND Flash Device Drivers
+#
+# CONFIG_MTD_NAND is not set
#
# Parallel port support
@@ -206,7 +420,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
#
# Block devices
#
-# CONFIG_BLK_DEV_FD is not set
# CONFIG_BLK_CPQ_DA is not set
# CONFIG_BLK_CPQ_CISS_DA is not set
# CONFIG_BLK_DEV_DAC960 is not set
@@ -218,7 +431,6 @@ CONFIG_BLK_DEV_LOOP=y
# CONFIG_BLK_DEV_SX8 is not set
# CONFIG_BLK_DEV_RAM is not set
CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_INITRAMFS_SOURCE=""
# CONFIG_LBD is not set
CONFIG_CDROM_PKTCDVD=m
CONFIG_CDROM_PKTCDVD_BUFFERS=8
@@ -275,6 +487,7 @@ CONFIG_BLK_DEV_IDEDMA_PCI=y
CONFIG_BLK_DEV_HPT366=y
# CONFIG_BLK_DEV_SC1200 is not set
# CONFIG_BLK_DEV_PIIX is not set
+# CONFIG_BLK_DEV_IT821X is not set
# CONFIG_BLK_DEV_NS87415 is not set
# CONFIG_BLK_DEV_PDC202XX_OLD is not set
# CONFIG_BLK_DEV_PDC202XX_NEW is not set
@@ -292,6 +505,7 @@ CONFIG_BLK_DEV_IDEDMA=y
#
# SCSI device support
#
+CONFIG_RAID_ATTRS=m
# CONFIG_SCSI is not set
#
@@ -302,6 +516,7 @@ CONFIG_BLK_DEV_IDEDMA=y
#
# Fusion MPT device support
#
+# CONFIG_FUSION is not set
#
# IEEE 1394 (FireWire) support
@@ -314,94 +529,13 @@ CONFIG_BLK_DEV_IDEDMA=y
# CONFIG_I2O is not set
#
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
-CONFIG_NETLINK_DEV=y
-CONFIG_UNIX=y
-CONFIG_NET_KEY=y
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-# CONFIG_IP_ADVANCED_ROUTER is not set
-CONFIG_IP_PNP=y
-# CONFIG_IP_PNP_DHCP is not set
-CONFIG_IP_PNP_BOOTP=y
-# CONFIG_IP_PNP_RARP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_IP_MROUTE is not set
-# CONFIG_ARPD is not set
-# CONFIG_SYN_COOKIES is not set
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-CONFIG_INET_TUNNEL=m
-CONFIG_IP_TCPDIAG=m
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-
-#
-# IP: Virtual Server Configuration
-#
-# CONFIG_IP_VS is not set
-# CONFIG_IPV6 is not set
-CONFIG_NETFILTER=y
-# CONFIG_NETFILTER_DEBUG is not set
-
-#
-# IP: Netfilter Configuration
+# Network device support
#
-# CONFIG_IP_NF_CONNTRACK is not set
-CONFIG_IP_NF_CONNTRACK_MARK=y
-# CONFIG_IP_NF_QUEUE is not set
-# CONFIG_IP_NF_IPTABLES is not set
-# CONFIG_IP_NF_ARPTABLES is not set
-CONFIG_XFRM=y
-CONFIG_XFRM_USER=m
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP 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_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
CONFIG_NETDEVICES=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_EQUALIZER is not set
# CONFIG_TUN is not set
-# CONFIG_ETHERTAP is not set
#
# ARCnet devices
@@ -409,6 +543,21 @@ CONFIG_NETDEVICES=y
# CONFIG_ARCNET is not set
#
+# PHY device support
+#
+CONFIG_PHYLIB=m
+CONFIG_PHYCONTROL=y
+
+#
+# MII PHY device drivers
+#
+CONFIG_MARVELL_PHY=m
+CONFIG_DAVICOM_PHY=m
+CONFIG_QSEMI_PHY=m
+CONFIG_LXT_PHY=m
+CONFIG_CICADA_PHY=m
+
+#
# Ethernet (10 or 100Mbit)
#
CONFIG_NET_ETHERNET=y
@@ -435,12 +584,16 @@ CONFIG_MIPS_AU1X00_ENET=y
# CONFIG_HAMACHI is not set
# CONFIG_YELLOWFIN is not set
# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
# CONFIG_SK98LIN is not set
# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
#
# Ethernet (10000 Mbit)
#
+# CONFIG_CHELSIO_T1 is not set
# CONFIG_IXGB is not set
# CONFIG_S2IO is not set
@@ -453,6 +606,8 @@ CONFIG_MIPS_AU1X00_ENET=y
# Wireless LAN (non-hamradio)
#
# CONFIG_NET_RADIO is not set
+# CONFIG_IPW_DEBUG is not set
+CONFIG_IPW2200=m
#
# PCMCIA network device support
@@ -484,6 +639,8 @@ CONFIG_PPPOE=m
# CONFIG_SLIP is not set
# CONFIG_SHAPER is not set
# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
#
# ISDN subsystem
@@ -513,19 +670,6 @@ CONFIG_INPUT_EVDEV=y
# CONFIG_INPUT_EVBUG is not set
#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=y
-# CONFIG_SERIO_I8042 is not set
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_PCIPS2 is not set
-# CONFIG_SERIO_LIBPS2 is not set
-CONFIG_SERIO_RAW=m
-
-#
# Input Device Drivers
#
# CONFIG_INPUT_KEYBOARD is not set
@@ -535,6 +679,17 @@ CONFIG_SERIO_RAW=m
# CONFIG_INPUT_MISC is not set
#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_PCIPS2 is not set
+# CONFIG_SERIO_LIBPS2 is not set
+CONFIG_SERIO_RAW=m
+# CONFIG_GAMEPORT is not set
+
+#
# Character devices
#
# CONFIG_VT is not set
@@ -554,6 +709,7 @@ CONFIG_SERIAL_AU1X00=y
CONFIG_SERIAL_AU1X00_CONSOLE=y
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
CONFIG_UNIX98_PTYS=y
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
@@ -585,6 +741,11 @@ CONFIG_SYNCLINK_CS=m
# CONFIG_RAW_DRIVER is not set
#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+
+#
# I2C support
#
# CONFIG_I2C is not set
@@ -595,10 +756,20 @@ CONFIG_SYNCLINK_CS=m
# CONFIG_W1 is not set
#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
+#
# Misc devices
#
#
+# Multimedia Capabilities Port drivers
+#
+
+#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
@@ -612,7 +783,6 @@ CONFIG_SYNCLINK_CS=m
# Graphics support
#
# CONFIG_FB is not set
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Sound
@@ -622,13 +792,9 @@ CONFIG_SYNCLINK_CS=m
#
# USB support
#
-# CONFIG_USB is not set
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB_ARCH_HAS_OHCI=y
-
-#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
-#
+# CONFIG_USB is not set
#
# USB Gadget Support
@@ -646,12 +812,17 @@ CONFIG_USB_ARCH_HAS_OHCI=y
# CONFIG_INFINIBAND is not set
#
+# SN Devices
+#
+
+#
# File systems
#
CONFIG_EXT2_FS=y
CONFIG_EXT2_FS_XATTR=y
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_FS_XATTR=y
CONFIG_EXT3_FS_POSIX_ACL=y
@@ -670,10 +841,12 @@ CONFIG_FS_POSIX_ACL=y
# CONFIG_XFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
# CONFIG_QUOTA is not set
CONFIG_DNOTIFY=y
CONFIG_AUTOFS_FS=m
CONFIG_AUTOFS4_FS=m
+CONFIG_FUSE_FS=m
#
# CD-ROM/DVD Filesystems
@@ -694,13 +867,10 @@ CONFIG_AUTOFS4_FS=m
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
-CONFIG_DEVPTS_FS_XATTR=y
-CONFIG_DEVPTS_FS_SECURITY=y
CONFIG_TMPFS=y
-# CONFIG_TMPFS_XATTR is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
+CONFIG_RELAYFS_FS=m
#
# Miscellaneous filesystems
@@ -712,6 +882,8 @@ CONFIG_RAMFS=y
# CONFIG_BEFS_FS is not set
# CONFIG_BFS_FS is not set
# CONFIG_EFS_FS is not set
+# CONFIG_JFFS_FS is not set
+# CONFIG_JFFS2_FS is not set
CONFIG_CRAMFS=m
# CONFIG_VXFS_FS is not set
# CONFIG_HPFS_FS is not set
@@ -732,6 +904,7 @@ CONFIG_NFSD=m
CONFIG_ROOT_NFS=y
CONFIG_LOCKD=y
CONFIG_EXPORTFS=m
+CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
@@ -741,6 +914,7 @@ CONFIG_SMB_FS=m
# CONFIG_NCP_FS is not set
# CONFIG_CODA_FS is not set
# CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
#
# Partition Types
@@ -800,7 +974,9 @@ CONFIG_NLS_DEFAULT="iso8859-1"
#
# Kernel hacking
#
+# CONFIG_PRINTK_TIME is not set
# CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=14
CONFIG_CROSSCOMPILE=y
CONFIG_CMDLINE=""
@@ -816,27 +992,28 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
#
CONFIG_CRYPTO=y
CONFIG_CRYPTO_HMAC=y
-CONFIG_CRYPTO_NULL=y
-# CONFIG_CRYPTO_MD4 is not set
-# CONFIG_CRYPTO_MD5 is not set
-# CONFIG_CRYPTO_SHA1 is not set
-# CONFIG_CRYPTO_SHA256 is not set
-CONFIG_CRYPTO_SHA512=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
CONFIG_CRYPTO_WP512=m
-# CONFIG_CRYPTO_DES is not set
-# CONFIG_CRYPTO_BLOWFISH is not set
-CONFIG_CRYPTO_TWOFISH=y
-# CONFIG_CRYPTO_SERPENT is not set
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_SERPENT=m
CONFIG_CRYPTO_AES=m
-# CONFIG_CRYPTO_CAST5 is not set
-# CONFIG_CRYPTO_CAST6 is not set
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
CONFIG_CRYPTO_TEA=m
-# CONFIG_CRYPTO_ARC4 is not set
+CONFIG_CRYPTO_ARC4=m
CONFIG_CRYPTO_KHAZAD=m
CONFIG_CRYPTO_ANUBIS=m
-CONFIG_CRYPTO_DEFLATE=y
-CONFIG_CRYPTO_MICHAEL_MIC=y
-# CONFIG_CRYPTO_CRC32C is not set
+CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_CRC32C=m
# CONFIG_CRYPTO_TEST is not set
#
@@ -847,9 +1024,8 @@ CONFIG_CRYPTO_MICHAEL_MIC=y
# Library routines
#
CONFIG_CRC_CCITT=m
+CONFIG_CRC16=m
CONFIG_CRC32=y
-# CONFIG_LIBCRC32C is not set
-CONFIG_ZLIB_INFLATE=y
-CONFIG_ZLIB_DEFLATE=y
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_LIBCRC32C=m
+CONFIG_ZLIB_INFLATE=m
+CONFIG_ZLIB_DEFLATE=m
diff --git a/arch/mips/configs/pb1550_defconfig b/arch/mips/configs/pb1550_defconfig
index 8e426776c098..bbad27cb40a2 100644
--- a/arch/mips/configs/pb1550_defconfig
+++ b/arch/mips/configs/pb1550_defconfig
@@ -1,12 +1,9 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-rc2
-# Wed Jan 26 02:49:09 2005
+# Linux kernel version: 2.6.14-rc2
+# Thu Oct 20 22:26:47 2005
#
CONFIG_MIPS=y
-# CONFIG_64BIT is not set
-# CONFIG_64BIT is not set
-CONFIG_32BIT=y
#
# Code maturity level options
@@ -14,24 +11,29 @@ CONFIG_32BIT=y
CONFIG_EXPERIMENTAL=y
CONFIG_CLEAN_COMPILE=y
CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
#
# General setup
#
CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
# CONFIG_POSIX_MQUEUE is not set
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
CONFIG_HOTPLUG=y
CONFIG_KOBJECT_UEVENT=y
# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
CONFIG_EMBEDDED=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
@@ -41,6 +43,7 @@ CONFIG_CC_ALIGN_LABELS=0
CONFIG_CC_ALIGN_LOOPS=0
CONFIG_CC_ALIGN_JUMPS=0
# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
#
# Loadable module support
@@ -56,63 +59,80 @@ CONFIG_KMOD=y
#
# Machine selection
#
-# CONFIG_MACH_JAZZ is not set
-# CONFIG_MACH_VR41XX is not set
-# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1500 is not set
+CONFIG_MIPS_PB1550=y
+# CONFIG_MIPS_PB1200 is not set
+# CONFIG_MIPS_DB1000 is not set
+# CONFIG_MIPS_DB1100 is not set
+# CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
+# CONFIG_MIPS_DB1200 is not set
+# CONFIG_MIPS_MIRAGE is not set
# CONFIG_MIPS_COBALT is not set
# CONFIG_MACH_DECSTATION is not set
# CONFIG_MIPS_EV64120 is not set
# CONFIG_MIPS_EV96100 is not set
# CONFIG_MIPS_IVR is not set
-# CONFIG_LASAT is not set
# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_LASAT is not set
# CONFIG_MIPS_ATLAS is not set
# CONFIG_MIPS_MALTA is not set
# CONFIG_MIPS_SEAD is not set
+# CONFIG_MIPS_SIM is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
# CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_G is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_JAGUAR_ATX is not set
-# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MIPS_XXS1500 is not set
+# CONFIG_PNX8550_V2PCI is not set
+# CONFIG_PNX8550_JBS is not set
# CONFIG_DDB5074 is not set
# CONFIG_DDB5476 is not set
# CONFIG_DDB5477 is not set
-# CONFIG_NEC_OSPREY is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_QEMU is not set
# CONFIG_SGI_IP22 is not set
-CONFIG_SOC_AU1X00=y
-# CONFIG_SOC_AU1000 is not set
-# CONFIG_SOC_AU1100 is not set
-# CONFIG_SOC_AU1500 is not set
-CONFIG_SOC_AU1550=y
-# CONFIG_MIPS_PB1000 is not set
-# CONFIG_MIPS_PB1100 is not set
-# CONFIG_MIPS_PB1500 is not set
-CONFIG_MIPS_PB1550=y
-# CONFIG_MIPS_DB1000 is not set
-# CONFIG_MIPS_DB1100 is not set
-# CONFIG_MIPS_DB1500 is not set
-# CONFIG_MIPS_DB1550 is not set
-# CONFIG_MIPS_BOSPORUS is not set
-# CONFIG_MIPS_MIRAGE is not set
-# CONFIG_MIPS_XXS1500 is not set
-# CONFIG_MIPS_MTX1 is not set
-# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_BIGSUR is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_PTSWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CRHONE is not set
# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
# CONFIG_TOSHIBA_RBTX4927 is not set
+# CONFIG_TOSHIBA_RBTX4938 is not set
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_HAVE_DEC_LOCK=y
-CONFIG_DMA_COHERENT=y
+CONFIG_DMA_NONCOHERENT=y
+CONFIG_DMA_NEED_PCI_MAP_STATE=y
CONFIG_MIPS_DISABLE_OBSOLETE_IDE=y
+# CONFIG_CPU_BIG_ENDIAN is not set
CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
+CONFIG_SOC_AU1550=y
+CONFIG_SOC_AU1X00=y
CONFIG_MIPS_L1_CACHE_SHIFT=5
#
# CPU selection
#
-CONFIG_CPU_MIPS32=y
-# CONFIG_CPU_MIPS64 is not set
+CONFIG_CPU_MIPS32_R1=y
+# CONFIG_CPU_MIPS32_R2 is not set
+# CONFIG_CPU_MIPS64_R1 is not set
+# CONFIG_CPU_MIPS64_R2 is not set
# CONFIG_CPU_R3000 is not set
# CONFIG_CPU_TX39XX is not set
# CONFIG_CPU_VR41XX is not set
@@ -128,15 +148,39 @@ CONFIG_CPU_MIPS32=y
# CONFIG_CPU_RM7000 is not set
# CONFIG_CPU_RM9000 is not set
# CONFIG_CPU_SB1 is not set
+CONFIG_SYS_HAS_CPU_MIPS32_R1=y
+CONFIG_CPU_MIPS32=y
+CONFIG_CPU_MIPSR1=y
+CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
+
+#
+# Kernel type
+#
+CONFIG_32BIT=y
+# CONFIG_64BIT is not set
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_CPU_HAS_PREFETCH=y
+# CONFIG_MIPS_MT is not set
CONFIG_64BIT_PHYS_ADDR=y
# CONFIG_CPU_ADVANCED is not set
CONFIG_CPU_HAS_LLSC=y
CONFIG_CPU_HAS_SYNC=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_ARCH_FLATMEM_ENABLE=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_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
#
@@ -145,7 +189,6 @@ CONFIG_CPU_HAS_SYNC=y
CONFIG_HW_HAS_PCI=y
CONFIG_PCI=y
CONFIG_PCI_LEGACY_PROC=y
-CONFIG_PCI_NAMES=y
CONFIG_MMU=y
#
@@ -154,6 +197,8 @@ CONFIG_MMU=y
CONFIG_PCCARD=m
# CONFIG_PCMCIA_DEBUG is not set
CONFIG_PCMCIA=m
+CONFIG_PCMCIA_LOAD_CIS=y
+CONFIG_PCMCIA_IOCTL=y
CONFIG_CARDBUS=y
#
@@ -177,6 +222,100 @@ CONFIG_PCCARD_NONSTATIC=m
CONFIG_BINFMT_ELF=y
# CONFIG_BINFMT_MISC is not set
CONFIG_TRAD_SIGNALS=y
+# CONFIG_PM is not set
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+CONFIG_NET_KEY=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+CONFIG_INET_TUNNEL=m
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+
+#
+# IP: Virtual Server Configuration
+#
+# CONFIG_IP_VS is not set
+# CONFIG_IPV6 is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+CONFIG_NETFILTER_NETLINK=m
+CONFIG_NETFILTER_NETLINK_QUEUE=m
+CONFIG_NETFILTER_NETLINK_LOG=m
+
+#
+# IP: Netfilter Configuration
+#
+# CONFIG_IP_NF_CONNTRACK is not set
+CONFIG_IP_NF_PPTP=m
+# CONFIG_IP_NF_QUEUE is not set
+# CONFIG_IP_NF_IPTABLES is not set
+# CONFIG_IP_NF_ARPTABLES is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP 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_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_IEEE80211=m
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=m
+CONFIG_IEEE80211_CRYPT_CCMP=m
+CONFIG_IEEE80211_CRYPT_TKIP=m
#
# Device Drivers
@@ -187,12 +326,87 @@ CONFIG_TRAD_SIGNALS=y
#
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
+CONFIG_FW_LOADER=m
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+CONFIG_CONNECTOR=m
#
# Memory Technology Devices (MTD)
#
-# CONFIG_MTD is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_CMDLINE_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL 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_AMDSTD_RETRY=0
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PHYSMAP is not set
+CONFIG_MTD_ALCHEMY=y
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLKMTD 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
+
+#
+# NAND Flash Device Drivers
+#
+# CONFIG_MTD_NAND is not set
#
# Parallel port support
@@ -206,7 +420,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
#
# Block devices
#
-# CONFIG_BLK_DEV_FD is not set
# CONFIG_BLK_CPQ_DA is not set
# CONFIG_BLK_CPQ_CISS_DA is not set
# CONFIG_BLK_DEV_DAC960 is not set
@@ -218,7 +431,6 @@ CONFIG_BLK_DEV_LOOP=y
# CONFIG_BLK_DEV_SX8 is not set
# CONFIG_BLK_DEV_RAM is not set
CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_INITRAMFS_SOURCE=""
# CONFIG_LBD is not set
CONFIG_CDROM_PKTCDVD=m
CONFIG_CDROM_PKTCDVD_BUFFERS=8
@@ -275,6 +487,7 @@ CONFIG_BLK_DEV_IDEDMA_PCI=y
CONFIG_BLK_DEV_HPT366=y
# CONFIG_BLK_DEV_SC1200 is not set
# CONFIG_BLK_DEV_PIIX is not set
+# CONFIG_BLK_DEV_IT821X is not set
# CONFIG_BLK_DEV_NS87415 is not set
# CONFIG_BLK_DEV_PDC202XX_OLD is not set
# CONFIG_BLK_DEV_PDC202XX_NEW is not set
@@ -292,6 +505,7 @@ CONFIG_BLK_DEV_IDEDMA=y
#
# SCSI device support
#
+CONFIG_RAID_ATTRS=m
# CONFIG_SCSI is not set
#
@@ -302,6 +516,7 @@ CONFIG_BLK_DEV_IDEDMA=y
#
# Fusion MPT device support
#
+# CONFIG_FUSION is not set
#
# IEEE 1394 (FireWire) support
@@ -314,94 +529,13 @@ CONFIG_BLK_DEV_IDEDMA=y
# CONFIG_I2O is not set
#
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
-CONFIG_NETLINK_DEV=y
-CONFIG_UNIX=y
-CONFIG_NET_KEY=y
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-# CONFIG_IP_ADVANCED_ROUTER is not set
-CONFIG_IP_PNP=y
-# CONFIG_IP_PNP_DHCP is not set
-CONFIG_IP_PNP_BOOTP=y
-# CONFIG_IP_PNP_RARP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_IP_MROUTE is not set
-# CONFIG_ARPD is not set
-# CONFIG_SYN_COOKIES is not set
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-CONFIG_INET_TUNNEL=m
-CONFIG_IP_TCPDIAG=m
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-
-#
-# IP: Virtual Server Configuration
-#
-# CONFIG_IP_VS is not set
-# CONFIG_IPV6 is not set
-CONFIG_NETFILTER=y
-# CONFIG_NETFILTER_DEBUG is not set
-
-#
-# IP: Netfilter Configuration
+# Network device support
#
-# CONFIG_IP_NF_CONNTRACK is not set
-CONFIG_IP_NF_CONNTRACK_MARK=y
-# CONFIG_IP_NF_QUEUE is not set
-# CONFIG_IP_NF_IPTABLES is not set
-# CONFIG_IP_NF_ARPTABLES is not set
-CONFIG_XFRM=y
-CONFIG_XFRM_USER=m
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP 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_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
CONFIG_NETDEVICES=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_EQUALIZER is not set
# CONFIG_TUN is not set
-# CONFIG_ETHERTAP is not set
#
# ARCnet devices
@@ -409,6 +543,21 @@ CONFIG_NETDEVICES=y
# CONFIG_ARCNET is not set
#
+# PHY device support
+#
+CONFIG_PHYLIB=m
+CONFIG_PHYCONTROL=y
+
+#
+# MII PHY device drivers
+#
+CONFIG_MARVELL_PHY=m
+CONFIG_DAVICOM_PHY=m
+CONFIG_QSEMI_PHY=m
+CONFIG_LXT_PHY=m
+CONFIG_CICADA_PHY=m
+
+#
# Ethernet (10 or 100Mbit)
#
CONFIG_NET_ETHERNET=y
@@ -435,12 +584,16 @@ CONFIG_MIPS_AU1X00_ENET=y
# CONFIG_HAMACHI is not set
# CONFIG_YELLOWFIN is not set
# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
# CONFIG_SK98LIN is not set
# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
#
# Ethernet (10000 Mbit)
#
+# CONFIG_CHELSIO_T1 is not set
# CONFIG_IXGB is not set
# CONFIG_S2IO is not set
@@ -453,6 +606,8 @@ CONFIG_MIPS_AU1X00_ENET=y
# Wireless LAN (non-hamradio)
#
# CONFIG_NET_RADIO is not set
+# CONFIG_IPW_DEBUG is not set
+CONFIG_IPW2200=m
#
# PCMCIA network device support
@@ -476,6 +631,8 @@ CONFIG_PPPOE=m
# CONFIG_SLIP is not set
# CONFIG_SHAPER is not set
# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
#
# ISDN subsystem
@@ -505,19 +662,6 @@ CONFIG_INPUT_EVDEV=y
# CONFIG_INPUT_EVBUG is not set
#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=y
-# CONFIG_SERIO_I8042 is not set
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_PCIPS2 is not set
-# CONFIG_SERIO_LIBPS2 is not set
-CONFIG_SERIO_RAW=m
-
-#
# Input Device Drivers
#
# CONFIG_INPUT_KEYBOARD is not set
@@ -527,6 +671,17 @@ CONFIG_SERIO_RAW=m
# CONFIG_INPUT_MISC is not set
#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_PCIPS2 is not set
+# CONFIG_SERIO_LIBPS2 is not set
+CONFIG_SERIO_RAW=m
+# CONFIG_GAMEPORT is not set
+
+#
# Character devices
#
# CONFIG_VT is not set
@@ -546,6 +701,7 @@ CONFIG_SERIAL_AU1X00=y
CONFIG_SERIAL_AU1X00_CONSOLE=y
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
CONFIG_UNIX98_PTYS=y
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
@@ -577,6 +733,11 @@ CONFIG_SYNCLINK_CS=m
# CONFIG_RAW_DRIVER is not set
#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+
+#
# I2C support
#
# CONFIG_I2C is not set
@@ -587,10 +748,20 @@ CONFIG_SYNCLINK_CS=m
# CONFIG_W1 is not set
#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
+#
# Misc devices
#
#
+# Multimedia Capabilities Port drivers
+#
+
+#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
@@ -604,7 +775,6 @@ CONFIG_SYNCLINK_CS=m
# Graphics support
#
# CONFIG_FB is not set
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Sound
@@ -614,13 +784,9 @@ CONFIG_SYNCLINK_CS=m
#
# USB support
#
-# CONFIG_USB is not set
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB_ARCH_HAS_OHCI=y
-
-#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
-#
+# CONFIG_USB is not set
#
# USB Gadget Support
@@ -638,12 +804,17 @@ CONFIG_USB_ARCH_HAS_OHCI=y
# CONFIG_INFINIBAND is not set
#
+# SN Devices
+#
+
+#
# File systems
#
CONFIG_EXT2_FS=y
CONFIG_EXT2_FS_XATTR=y
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_FS_XATTR=y
CONFIG_EXT3_FS_POSIX_ACL=y
@@ -662,10 +833,12 @@ CONFIG_FS_POSIX_ACL=y
# CONFIG_XFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
# CONFIG_QUOTA is not set
CONFIG_DNOTIFY=y
CONFIG_AUTOFS_FS=m
CONFIG_AUTOFS4_FS=m
+CONFIG_FUSE_FS=m
#
# CD-ROM/DVD Filesystems
@@ -686,13 +859,10 @@ CONFIG_AUTOFS4_FS=m
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
-CONFIG_DEVPTS_FS_XATTR=y
-CONFIG_DEVPTS_FS_SECURITY=y
CONFIG_TMPFS=y
-# CONFIG_TMPFS_XATTR is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
+CONFIG_RELAYFS_FS=m
#
# Miscellaneous filesystems
@@ -704,6 +874,8 @@ CONFIG_RAMFS=y
# CONFIG_BEFS_FS is not set
# CONFIG_BFS_FS is not set
# CONFIG_EFS_FS is not set
+# CONFIG_JFFS_FS is not set
+# CONFIG_JFFS2_FS is not set
CONFIG_CRAMFS=m
# CONFIG_VXFS_FS is not set
# CONFIG_HPFS_FS is not set
@@ -724,6 +896,7 @@ CONFIG_NFSD=m
CONFIG_ROOT_NFS=y
CONFIG_LOCKD=y
CONFIG_EXPORTFS=m
+CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
@@ -733,6 +906,7 @@ CONFIG_SMB_FS=m
# CONFIG_NCP_FS is not set
# CONFIG_CODA_FS is not set
# CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
#
# Partition Types
@@ -792,7 +966,9 @@ CONFIG_NLS_DEFAULT="iso8859-1"
#
# Kernel hacking
#
+# CONFIG_PRINTK_TIME is not set
# CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=14
CONFIG_CROSSCOMPILE=y
CONFIG_CMDLINE=""
@@ -808,26 +984,27 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
#
CONFIG_CRYPTO=y
CONFIG_CRYPTO_HMAC=y
-CONFIG_CRYPTO_NULL=y
-# CONFIG_CRYPTO_MD4 is not set
-# CONFIG_CRYPTO_MD5 is not set
-# CONFIG_CRYPTO_SHA1 is not set
-# CONFIG_CRYPTO_SHA256 is not set
-CONFIG_CRYPTO_SHA512=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
CONFIG_CRYPTO_WP512=m
-# CONFIG_CRYPTO_DES is not set
-# CONFIG_CRYPTO_BLOWFISH is not set
-CONFIG_CRYPTO_TWOFISH=y
-# CONFIG_CRYPTO_SERPENT is not set
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_SERPENT=m
CONFIG_CRYPTO_AES=m
-# CONFIG_CRYPTO_CAST5 is not set
-# CONFIG_CRYPTO_CAST6 is not set
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
CONFIG_CRYPTO_TEA=m
-# CONFIG_CRYPTO_ARC4 is not set
+CONFIG_CRYPTO_ARC4=m
CONFIG_CRYPTO_KHAZAD=m
CONFIG_CRYPTO_ANUBIS=m
-CONFIG_CRYPTO_DEFLATE=y
-CONFIG_CRYPTO_MICHAEL_MIC=y
+CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
CONFIG_CRYPTO_CRC32C=m
# CONFIG_CRYPTO_TEST is not set
@@ -839,9 +1016,8 @@ CONFIG_CRYPTO_CRC32C=m
# Library routines
#
CONFIG_CRC_CCITT=m
+CONFIG_CRC16=m
CONFIG_CRC32=y
CONFIG_LIBCRC32C=m
-CONFIG_ZLIB_INFLATE=y
-CONFIG_ZLIB_DEFLATE=y
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_ZLIB_INFLATE=m
+CONFIG_ZLIB_DEFLATE=m
diff --git a/arch/mips/configs/pnx8550-jbs_defconfig b/arch/mips/configs/pnx8550-jbs_defconfig
new file mode 100644
index 000000000000..555837e4c06f
--- /dev/null
+++ b/arch/mips/configs/pnx8550-jbs_defconfig
@@ -0,0 +1,1070 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.14-rc2
+# Thu Oct 20 22:26:50 2005
+#
+CONFIG_MIPS=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+# CONFIG_HOTPLUG is not set
+CONFIG_KOBJECT_UEVENT=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+# CONFIG_MODULE_UNLOAD is not set
+CONFIG_OBSOLETE_MODPARM=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+
+#
+# Machine selection
+#
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_MIPS_PB1550 is not set
+# CONFIG_MIPS_PB1200 is not set
+# CONFIG_MIPS_DB1000 is not set
+# CONFIG_MIPS_DB1100 is not set
+# CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
+# CONFIG_MIPS_DB1200 is not set
+# CONFIG_MIPS_MIRAGE is not set
+# CONFIG_MIPS_COBALT is not set
+# CONFIG_MACH_DECSTATION is not set
+# CONFIG_MIPS_EV64120 is not set
+# CONFIG_MIPS_EV96100 is not set
+# CONFIG_MIPS_IVR is not set
+# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_LASAT is not set
+# CONFIG_MIPS_ATLAS is not set
+# CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SEAD is not set
+# CONFIG_MIPS_SIM is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_MOMENCO_OCELOT_3 is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MIPS_XXS1500 is not set
+# CONFIG_PNX8550_V2PCI is not set
+CONFIG_PNX8550_JBS=y
+# CONFIG_DDB5074 is not set
+# CONFIG_DDB5476 is not set
+# CONFIG_DDB5477 is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_QEMU is not set
+# CONFIG_SGI_IP22 is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_BIGSUR is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_PTSWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CRHONE is not set
+# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_TOSHIBA_RBTX4927 is not set
+# CONFIG_TOSHIBA_RBTX4938 is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_DMA_NONCOHERENT=y
+CONFIG_DMA_NEED_PCI_MAP_STATE=y
+# CONFIG_CPU_BIG_ENDIAN is not set
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
+CONFIG_PNX8550=y
+CONFIG_SOC_PNX8550=y
+CONFIG_MIPS_L1_CACHE_SHIFT=5
+
+#
+# CPU selection
+#
+CONFIG_CPU_MIPS32_R1=y
+# CONFIG_CPU_MIPS32_R2 is not set
+# CONFIG_CPU_MIPS64_R1 is not set
+# CONFIG_CPU_MIPS64_R2 is not set
+# CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_TX39XX is not set
+# CONFIG_CPU_VR41XX is not set
+# CONFIG_CPU_R4300 is not set
+# CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_TX49XX is not set
+# CONFIG_CPU_R5000 is not set
+# CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_R6000 is not set
+# CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
+# CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_RM7000 is not set
+# CONFIG_CPU_RM9000 is not set
+# CONFIG_CPU_SB1 is not set
+CONFIG_SYS_HAS_CPU_MIPS32_R1=y
+CONFIG_CPU_MIPS32=y
+CONFIG_CPU_MIPSR1=y
+CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
+
+#
+# Kernel type
+#
+CONFIG_32BIT=y
+# CONFIG_64BIT is not set
+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_CPU_HAS_PREFETCH=y
+# CONFIG_MIPS_MT is not set
+# CONFIG_64BIT_PHYS_ADDR is not set
+# CONFIG_CPU_ADVANCED is not set
+CONFIG_CPU_HAS_LLSC=y
+CONFIG_CPU_HAS_SYNC=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_ARCH_FLATMEM_ENABLE=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_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+
+#
+# Bus options (PCI, PCMCIA, EISA, ISA, TC)
+#
+CONFIG_HW_HAS_PCI=y
+CONFIG_PCI=y
+# CONFIG_PCI_LEGACY_PROC is not set
+# CONFIG_PCI_DEBUG is not set
+CONFIG_MMU=y
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PCI Hotplug Support
+#
+# CONFIG_HOTPLUG_PCI is not set
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+CONFIG_TRAD_SIGNALS=y
+
+#
+# Networking
+#
+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=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+# CONFIG_IPV6 is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# 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_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+# CONFIG_DEBUG_DRIVER is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+
+#
+# Block devices
+#
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_SX8 is not set
+# CONFIG_BLK_DEV_UB is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=8192
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_LBD is not set
+# CONFIG_CDROM_PKTCDVD is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_ATA_OVER_ETH is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+CONFIG_IDE=y
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_IDE_SATA is not set
+CONFIG_BLK_DEV_IDEDISK=y
+# CONFIG_IDEDISK_MULTI_MODE is not set
+CONFIG_BLK_DEV_IDECD=m
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_BLK_DEV_IDEFLOPPY is not set
+CONFIG_BLK_DEV_IDESCSI=y
+# CONFIG_IDE_TASK_IOCTL is not set
+
+#
+# IDE chipset support/bugfixes
+#
+CONFIG_IDE_GENERIC=y
+CONFIG_BLK_DEV_IDEPCI=y
+CONFIG_IDEPCI_SHARE_IRQ=y
+CONFIG_BLK_DEV_OFFBOARD=y
+CONFIG_BLK_DEV_GENERIC=y
+# CONFIG_BLK_DEV_OPTI621 is not set
+CONFIG_BLK_DEV_IDEDMA_PCI=y
+# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
+# CONFIG_IDEDMA_PCI_AUTO is not set
+# CONFIG_BLK_DEV_AEC62XX is not set
+# CONFIG_BLK_DEV_ALI15X3 is not set
+# CONFIG_BLK_DEV_AMD74XX is not set
+# CONFIG_BLK_DEV_CMD64X is not set
+# CONFIG_BLK_DEV_TRIFLEX is not set
+# CONFIG_BLK_DEV_CY82C693 is not set
+# CONFIG_BLK_DEV_CS5520 is not set
+# CONFIG_BLK_DEV_CS5530 is not set
+# CONFIG_BLK_DEV_HPT34X is not set
+CONFIG_BLK_DEV_HPT366=y
+# CONFIG_BLK_DEV_SC1200 is not set
+# CONFIG_BLK_DEV_PIIX is not set
+# CONFIG_BLK_DEV_IT821X is not set
+# CONFIG_BLK_DEV_NS87415 is not set
+# CONFIG_BLK_DEV_PDC202XX_OLD is not set
+# CONFIG_BLK_DEV_PDC202XX_NEW is not set
+# CONFIG_BLK_DEV_SVWKS is not set
+# CONFIG_BLK_DEV_SIIMAGE is not set
+# CONFIG_BLK_DEV_SLC90E66 is not set
+# CONFIG_BLK_DEV_TRM290 is not set
+# CONFIG_BLK_DEV_VIA82CXXX is not set
+# CONFIG_IDE_ARM is not set
+CONFIG_BLK_DEV_IDEDMA=y
+# CONFIG_IDEDMA_IVB is not set
+# CONFIG_IDEDMA_AUTO is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+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 is not set
+# CONFIG_CHR_DEV_SCH is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# CONFIG_SCSI_MULTI_LUN is not set
+CONFIG_SCSI_CONSTANTS=y
+# CONFIG_SCSI_LOGGING is not set
+
+#
+# SCSI Transport Attributes
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_ATTRS is not set
+
+#
+# SCSI low-level drivers
+#
+# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_ACARD is not set
+# CONFIG_SCSI_AACRAID is not set
+# CONFIG_SCSI_AIC7XXX is not set
+# CONFIG_SCSI_AIC7XXX_OLD is not set
+# CONFIG_SCSI_AIC79XX is not set
+# CONFIG_SCSI_DPT_I2O is not set
+# CONFIG_MEGARAID_NEWGEN is not set
+# CONFIG_MEGARAID_LEGACY is not set
+# CONFIG_SCSI_SATA is not set
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+# CONFIG_SCSI_IPS is not set
+# CONFIG_SCSI_INITIO is not set
+# CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_SYM53C8XX_2 is not set
+# CONFIG_SCSI_IPR is not set
+# CONFIG_SCSI_QLOGIC_FC is not set
+# CONFIG_SCSI_QLOGIC_1280 is not set
+CONFIG_SCSI_QLA2XXX=y
+# CONFIG_SCSI_QLA21XX is not set
+# CONFIG_SCSI_QLA22XX is not set
+# CONFIG_SCSI_QLA2300 is not set
+# CONFIG_SCSI_QLA2322 is not set
+# CONFIG_SCSI_QLA6312 is not set
+# CONFIG_SCSI_QLA24XX is not set
+# CONFIG_SCSI_LPFC is not set
+# CONFIG_SCSI_DC395x is not set
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_NSP32 is not set
+# CONFIG_SCSI_DEBUG is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+# CONFIG_FUSION_SPI is not set
+# CONFIG_FUSION_FC is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
+#
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_NET_VENDOR_3COM is not set
+
+#
+# Tulip family network device support
+#
+# CONFIG_NET_TULIP is not set
+# CONFIG_HP100 is not set
+CONFIG_NET_PCI=y
+# CONFIG_PCNET32 is not set
+# CONFIG_AMD8111_ETH is not set
+# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_B44 is not set
+# CONFIG_FORCEDETH is not set
+# CONFIG_DGRS is not set
+# CONFIG_EEPRO100 is not set
+# CONFIG_E100 is not set
+# CONFIG_FEALNX is not set
+# CONFIG_NATSEMI is not set
+# CONFIG_NE2K_PCI is not set
+# CONFIG_8139CP is not set
+CONFIG_8139TOO=y
+# CONFIG_8139TOO_PIO is not set
+CONFIG_8139TOO_TUNE_TWISTER=y
+CONFIG_8139TOO_8129=y
+# CONFIG_8139_OLD_RX_RESET is not set
+# CONFIG_SIS900 is not set
+# CONFIG_EPIC100 is not set
+# CONFIG_SUNDANCE is not set
+# CONFIG_TLAN is not set
+# CONFIG_VIA_RHINE is not set
+# CONFIG_LAN_SAA9730 is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_VIA_VELOCITY is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
+
+#
+# Ethernet (10000 Mbit)
+#
+# CONFIG_CHELSIO_T1 is not set
+# CONFIG_IXGB is not set
+# CONFIG_S2IO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NET_FC is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+
+#
+# Userland interfaces
+#
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+# CONFIG_SERIO_SERPORT is not set
+# CONFIG_SERIO_PCIPS2 is not set
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_IP3106 is not set
+# CONFIG_SERIAL_JSM is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_RTC is not set
+# CONFIG_GEN_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_DRM is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Misc devices
+#
+
+#
+# Multimedia Capabilities Port drivers
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+# CONFIG_FB is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+
+#
+# Miscellaneous USB options
+#
+# CONFIG_USB_DEVICEFS is not set
+# CONFIG_USB_BANDWIDTH is not set
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_OTG is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_EHCI_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
+CONFIG_USB_OHCI_HCD=y
+# CONFIG_USB_OHCI_BIG_ENDIAN is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+# CONFIG_USB_UHCI_HCD is not set
+# CONFIG_USB_SL811_HCD is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_BLUETOOTH_TTY is not set
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+#
+CONFIG_USB_STORAGE=y
+# CONFIG_USB_STORAGE_DEBUG is not set
+CONFIG_USB_STORAGE_DATAFAB=y
+CONFIG_USB_STORAGE_FREECOM=y
+CONFIG_USB_STORAGE_ISD200=y
+CONFIG_USB_STORAGE_DPCM=y
+CONFIG_USB_STORAGE_USBAT=y
+CONFIG_USB_STORAGE_SDDR09=y
+CONFIG_USB_STORAGE_SDDR55=y
+CONFIG_USB_STORAGE_JUMPSHOT=y
+
+#
+# USB Input Devices
+#
+# CONFIG_USB_HID is not set
+
+#
+# USB HID Boot Protocol drivers
+#
+# CONFIG_USB_KBD is not set
+# CONFIG_USB_MOUSE is not set
+# CONFIG_USB_AIPTEK is not set
+# CONFIG_USB_WACOM is not set
+# CONFIG_USB_ACECAD is not set
+# CONFIG_USB_KBTAB is not set
+# CONFIG_USB_POWERMATE is not set
+# CONFIG_USB_MTOUCH is not set
+# CONFIG_USB_ITMTOUCH is not set
+# CONFIG_USB_EGALAX is not set
+# CONFIG_USB_YEALINK is not set
+# CONFIG_USB_XPAD is not set
+# CONFIG_USB_ATI_REMOTE is not set
+# CONFIG_USB_KEYSPAN_REMOTE is not set
+# CONFIG_USB_APPLETOUCH is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+
+#
+# USB Multimedia devices
+#
+# CONFIG_USB_DABUSB is not set
+
+#
+# Video4Linux support is needed for USB Multimedia device support
+#
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET is not set
+CONFIG_USB_MON=y
+
+#
+# USB port drivers
+#
+
+#
+# USB Serial Converter support
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_AUERSWALD is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_PHIDGETKIT is not set
+# CONFIG_USB_PHIDGETSERVO is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_LD is not set
+
+#
+# USB DSL modem support
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
+# SN Devices
+#
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD 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_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+# CONFIG_QUOTA is not set
+# CONFIG_DNOTIFY is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+# CONFIG_PROC_KCORE is not set
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+# CONFIG_RELAYFS_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_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFS_DIRECTIO is not set
+CONFIG_NFSD=m
+# CONFIG_NFSD_V3 is not set
+# CONFIG_NFSD_TCP is not set
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=m
+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
+# CONFIG_9P_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+# CONFIG_NLS_CODEPAGE_437 is not set
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+# CONFIG_NLS_ISO8859_1 is not set
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_DEBUG_KERNEL=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_SCHEDSTATS is not set
+CONFIG_DEBUG_SLAB=y
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_FS is not set
+CONFIG_CROSSCOMPILE=y
+CONFIG_CMDLINE="console=ttyS1,38400n8 kgdb=ttyS0 root=/dev/nfs ip=bootp"
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_KGDB is not set
+# CONFIG_RUNTIME_DEBUG is not set
+# CONFIG_MIPS_UNCACHED is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
+
+#
+# Hardware crypto devices
+#
+
+#
+# Library routines
+#
+CONFIG_CRC_CCITT=m
+# CONFIG_CRC16 is not set
+CONFIG_CRC32=y
+# CONFIG_LIBCRC32C is not set
diff --git a/arch/mips/configs/pnx8550-v2pci_defconfig b/arch/mips/configs/pnx8550-v2pci_defconfig
new file mode 100644
index 000000000000..37bd8d5c865d
--- /dev/null
+++ b/arch/mips/configs/pnx8550-v2pci_defconfig
@@ -0,0 +1,1252 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.14-rc2
+# Thu Oct 20 22:26:53 2005
+#
+CONFIG_MIPS=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+# CONFIG_HOTPLUG is not set
+CONFIG_KOBJECT_UEVENT=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+# CONFIG_MODULE_UNLOAD is not set
+CONFIG_OBSOLETE_MODPARM=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+
+#
+# Machine selection
+#
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_MIPS_PB1550 is not set
+# CONFIG_MIPS_PB1200 is not set
+# CONFIG_MIPS_DB1000 is not set
+# CONFIG_MIPS_DB1100 is not set
+# CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
+# CONFIG_MIPS_DB1200 is not set
+# CONFIG_MIPS_MIRAGE is not set
+# CONFIG_MIPS_COBALT is not set
+# CONFIG_MACH_DECSTATION is not set
+# CONFIG_MIPS_EV64120 is not set
+# CONFIG_MIPS_EV96100 is not set
+# CONFIG_MIPS_IVR is not set
+# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_LASAT is not set
+# CONFIG_MIPS_ATLAS is not set
+# CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SEAD is not set
+# CONFIG_MIPS_SIM is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_MOMENCO_OCELOT_3 is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MIPS_XXS1500 is not set
+CONFIG_PNX8550_V2PCI=y
+# CONFIG_PNX8550_JBS is not set
+# CONFIG_DDB5074 is not set
+# CONFIG_DDB5476 is not set
+# CONFIG_DDB5477 is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_QEMU is not set
+# CONFIG_SGI_IP22 is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_BIGSUR is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_PTSWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CRHONE is not set
+# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_TOSHIBA_RBTX4927 is not set
+# CONFIG_TOSHIBA_RBTX4938 is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_DMA_NONCOHERENT=y
+CONFIG_DMA_NEED_PCI_MAP_STATE=y
+# CONFIG_CPU_BIG_ENDIAN is not set
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
+CONFIG_PNX8550=y
+CONFIG_SOC_PNX8550=y
+CONFIG_MIPS_L1_CACHE_SHIFT=5
+
+#
+# CPU selection
+#
+CONFIG_CPU_MIPS32_R1=y
+# CONFIG_CPU_MIPS32_R2 is not set
+# CONFIG_CPU_MIPS64_R1 is not set
+# CONFIG_CPU_MIPS64_R2 is not set
+# CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_TX39XX is not set
+# CONFIG_CPU_VR41XX is not set
+# CONFIG_CPU_R4300 is not set
+# CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_TX49XX is not set
+# CONFIG_CPU_R5000 is not set
+# CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_R6000 is not set
+# CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
+# CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_RM7000 is not set
+# CONFIG_CPU_RM9000 is not set
+# CONFIG_CPU_SB1 is not set
+CONFIG_SYS_HAS_CPU_MIPS32_R1=y
+CONFIG_CPU_MIPS32=y
+CONFIG_CPU_MIPSR1=y
+CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
+
+#
+# Kernel type
+#
+CONFIG_32BIT=y
+# CONFIG_64BIT is not set
+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_CPU_HAS_PREFETCH=y
+# CONFIG_MIPS_MT is not set
+# CONFIG_64BIT_PHYS_ADDR is not set
+CONFIG_CPU_ADVANCED=y
+CONFIG_CPU_HAS_LLSC=y
+# CONFIG_CPU_HAS_LLDSCD is not set
+# CONFIG_CPU_HAS_WB is not set
+CONFIG_CPU_HAS_SYNC=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_ARCH_FLATMEM_ENABLE=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_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+
+#
+# Bus options (PCI, PCMCIA, EISA, ISA, TC)
+#
+CONFIG_HW_HAS_PCI=y
+CONFIG_PCI=y
+# CONFIG_PCI_LEGACY_PROC is not set
+CONFIG_MMU=y
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PCI Hotplug Support
+#
+# CONFIG_HOTPLUG_PCI is not set
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+CONFIG_TRAD_SIGNALS=y
+
+#
+# Networking
+#
+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 is not set
+# CONFIG_IP_PNP_BOOTP is not set
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+
+#
+# IP: Virtual Server Configuration
+#
+# CONFIG_IP_VS is not set
+CONFIG_IPV6=m
+# CONFIG_IPV6_PRIVACY is not set
+# CONFIG_INET6_AH is not set
+# CONFIG_INET6_ESP is not set
+# CONFIG_INET6_IPCOMP is not set
+# CONFIG_INET6_TUNNEL is not set
+# CONFIG_IPV6_TUNNEL is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+# CONFIG_NETFILTER_NETLINK is not set
+
+#
+# IP: Netfilter Configuration
+#
+# CONFIG_IP_NF_CONNTRACK is not set
+CONFIG_IP_NF_PPTP=m
+# CONFIG_IP_NF_QUEUE is not set
+# CONFIG_IP_NF_IPTABLES is not set
+# CONFIG_IP_NF_ARPTABLES is not set
+
+#
+# IPv6: Netfilter Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP6_NF_QUEUE is not set
+# CONFIG_IP6_NF_IPTABLES is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP 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_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+
+#
+# Block devices
+#
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_SX8 is not set
+# CONFIG_BLK_DEV_UB is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=8192
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_LBD is not set
+# CONFIG_CDROM_PKTCDVD is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_ATA_OVER_ETH is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+CONFIG_IDE=y
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_IDE_SATA is not set
+CONFIG_BLK_DEV_IDEDISK=y
+CONFIG_IDEDISK_MULTI_MODE=y
+# CONFIG_BLK_DEV_IDECD is not set
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_BLK_DEV_IDEFLOPPY is not set
+# CONFIG_BLK_DEV_IDESCSI is not set
+# CONFIG_IDE_TASK_IOCTL is not set
+
+#
+# IDE chipset support/bugfixes
+#
+CONFIG_IDE_GENERIC=y
+CONFIG_BLK_DEV_IDEPCI=y
+CONFIG_IDEPCI_SHARE_IRQ=y
+# CONFIG_BLK_DEV_OFFBOARD is not set
+# CONFIG_BLK_DEV_GENERIC is not set
+# CONFIG_BLK_DEV_OPTI621 is not set
+CONFIG_BLK_DEV_IDEDMA_PCI=y
+# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
+CONFIG_IDEDMA_PCI_AUTO=y
+# CONFIG_IDEDMA_ONLYDISK is not set
+# CONFIG_BLK_DEV_AEC62XX is not set
+# CONFIG_BLK_DEV_ALI15X3 is not set
+# CONFIG_BLK_DEV_AMD74XX is not set
+CONFIG_BLK_DEV_CMD64X=y
+# CONFIG_BLK_DEV_TRIFLEX is not set
+# CONFIG_BLK_DEV_CY82C693 is not set
+# CONFIG_BLK_DEV_CS5520 is not set
+# CONFIG_BLK_DEV_CS5530 is not set
+# CONFIG_BLK_DEV_HPT34X is not set
+# CONFIG_BLK_DEV_HPT366 is not set
+# CONFIG_BLK_DEV_SC1200 is not set
+# CONFIG_BLK_DEV_PIIX is not set
+# CONFIG_BLK_DEV_IT821X is not set
+# CONFIG_BLK_DEV_NS87415 is not set
+# CONFIG_BLK_DEV_PDC202XX_OLD is not set
+# CONFIG_BLK_DEV_PDC202XX_NEW is not set
+# CONFIG_BLK_DEV_SVWKS is not set
+# CONFIG_BLK_DEV_SIIMAGE is not set
+# CONFIG_BLK_DEV_SLC90E66 is not set
+# CONFIG_BLK_DEV_TRM290 is not set
+# CONFIG_BLK_DEV_VIA82CXXX is not set
+# CONFIG_IDE_ARM is not set
+CONFIG_BLK_DEV_IDEDMA=y
+# CONFIG_IDEDMA_IVB is not set
+CONFIG_IDEDMA_AUTO=y
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+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 is not set
+# CONFIG_CHR_DEV_SCH is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+
+#
+# SCSI Transport Attributes
+#
+CONFIG_SCSI_SPI_ATTRS=m
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_ATTRS is not set
+
+#
+# SCSI low-level drivers
+#
+# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_ACARD is not set
+# CONFIG_SCSI_AACRAID is not set
+CONFIG_SCSI_AIC7XXX=m
+CONFIG_AIC7XXX_CMDS_PER_DEVICE=32
+CONFIG_AIC7XXX_RESET_DELAY_MS=15000
+# CONFIG_AIC7XXX_DEBUG_ENABLE is not set
+CONFIG_AIC7XXX_DEBUG_MASK=0
+# CONFIG_AIC7XXX_REG_PRETTY_PRINT is not set
+# CONFIG_SCSI_AIC7XXX_OLD is not set
+# CONFIG_SCSI_AIC79XX is not set
+# CONFIG_SCSI_DPT_I2O is not set
+# CONFIG_MEGARAID_NEWGEN is not set
+# CONFIG_MEGARAID_LEGACY is not set
+# CONFIG_SCSI_SATA is not set
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+# CONFIG_SCSI_IPS is not set
+# CONFIG_SCSI_INITIO is not set
+# CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_SYM53C8XX_2 is not set
+# CONFIG_SCSI_IPR is not set
+# CONFIG_SCSI_QLOGIC_FC is not set
+# CONFIG_SCSI_QLOGIC_1280 is not set
+CONFIG_SCSI_QLA2XXX=y
+# CONFIG_SCSI_QLA21XX is not set
+# CONFIG_SCSI_QLA22XX is not set
+# CONFIG_SCSI_QLA2300 is not set
+# CONFIG_SCSI_QLA2322 is not set
+# CONFIG_SCSI_QLA6312 is not set
+# CONFIG_SCSI_QLA24XX is not set
+# CONFIG_SCSI_LPFC is not set
+# CONFIG_SCSI_DC395x is not set
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_NSP32 is not set
+# CONFIG_SCSI_DEBUG is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+# CONFIG_FUSION_SPI is not set
+# CONFIG_FUSION_FC is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+CONFIG_TUN=m
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
+#
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_NET_VENDOR_3COM is not set
+
+#
+# Tulip family network device support
+#
+# CONFIG_NET_TULIP is not set
+# CONFIG_HP100 is not set
+CONFIG_NET_PCI=y
+# CONFIG_PCNET32 is not set
+# CONFIG_AMD8111_ETH is not set
+# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_B44 is not set
+# CONFIG_FORCEDETH is not set
+# CONFIG_DGRS is not set
+# CONFIG_EEPRO100 is not set
+# CONFIG_E100 is not set
+# CONFIG_FEALNX is not set
+CONFIG_NATSEMI=y
+# CONFIG_NE2K_PCI is not set
+# CONFIG_8139CP is not set
+CONFIG_8139TOO=y
+# CONFIG_8139TOO_PIO is not set
+# CONFIG_8139TOO_TUNE_TWISTER is not set
+# CONFIG_8139TOO_8129 is not set
+# CONFIG_8139_OLD_RX_RESET is not set
+# CONFIG_SIS900 is not set
+# CONFIG_EPIC100 is not set
+# CONFIG_SUNDANCE is not set
+# CONFIG_TLAN is not set
+# CONFIG_VIA_RHINE is not set
+# CONFIG_LAN_SAA9730 is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_VIA_VELOCITY is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
+
+#
+# Ethernet (10000 Mbit)
+#
+# CONFIG_CHELSIO_T1 is not set
+# CONFIG_IXGB is not set
+# CONFIG_S2IO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+CONFIG_PPP=m
+# CONFIG_PPP_MULTILINK is not set
+# CONFIG_PPP_FILTER is not set
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
+CONFIG_PPP_DEFLATE=m
+# CONFIG_PPP_BSDCOMP is not set
+# CONFIG_PPPOE is not set
+# CONFIG_SLIP is not set
+# CONFIG_NET_FC is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+CONFIG_INPUT_EVDEV=m
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+CONFIG_KEYBOARD_ATKBD=y
+# 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_INPUT_MOUSE=y
+CONFIG_MOUSE_PS2=y
+# CONFIG_MOUSE_SERIAL is not set
+# CONFIG_MOUSE_VSXXXAA is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_I8042=y
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_PCIPS2 is not set
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+# CONFIG_VT_CONSOLE is not set
+CONFIG_HW_CONSOLE=y
+CONFIG_SERIAL_NONSTANDARD=y
+# CONFIG_COMPUTONE is not set
+# CONFIG_ROCKETPORT is not set
+# CONFIG_CYCLADES is not set
+# CONFIG_DIGIEPCA is not set
+# CONFIG_MOXA_INTELLIO is not set
+# CONFIG_MOXA_SMARTIO is not set
+# CONFIG_ISI is not set
+# CONFIG_SYNCLINKMP is not set
+# CONFIG_N_HDLC is not set
+# CONFIG_RISCOM8 is not set
+# CONFIG_SPECIALIX is not set
+# CONFIG_SX is not set
+# CONFIG_RIO is not set
+# CONFIG_STALDRV is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_IP3106 is not set
+# CONFIG_SERIAL_JSM is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_RTC is not set
+# CONFIG_GEN_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_DRM is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+
+#
+# I2C support
+#
+CONFIG_I2C=m
+CONFIG_I2C_CHARDEV=m
+
+#
+# I2C Algorithms
+#
+CONFIG_I2C_ALGOBIT=m
+# CONFIG_I2C_ALGOPCF is not set
+# CONFIG_I2C_ALGOPCA is not set
+
+#
+# I2C Hardware Bus support
+#
+# 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_PIIX4 is not set
+# CONFIG_I2C_NFORCE2 is not set
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_PROSAVAGE is not set
+# CONFIG_I2C_SAVAGE4 is not set
+# CONFIG_SCx200_ACB is not set
+# CONFIG_I2C_SIS5595 is not set
+# CONFIG_I2C_SIS630 is not set
+# CONFIG_I2C_SIS96X is not set
+# CONFIG_I2C_STUB is not set
+# CONFIG_I2C_VIA is not set
+# CONFIG_I2C_VIAPRO is not set
+# CONFIG_I2C_VOODOO3 is not set
+# CONFIG_I2C_PCA_ISA is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_SENSORS_DS1337 is not set
+# CONFIG_SENSORS_DS1374 is not set
+# CONFIG_SENSORS_EEPROM is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_SENSORS_PCA9539 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_SENSORS_RTC8564 is not set
+# CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_ADM1021 is not set
+# CONFIG_SENSORS_ADM1025 is not set
+# CONFIG_SENSORS_ADM1026 is not set
+# CONFIG_SENSORS_ADM1031 is not set
+# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ASB100 is not set
+# CONFIG_SENSORS_ATXP1 is not set
+# CONFIG_SENSORS_DS1621 is not set
+# CONFIG_SENSORS_FSCHER is not set
+# CONFIG_SENSORS_FSCPOS is not set
+# CONFIG_SENSORS_GL518SM is not set
+# CONFIG_SENSORS_GL520SM is not set
+# CONFIG_SENSORS_IT87 is not set
+# CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM75 is not set
+# CONFIG_SENSORS_LM77 is not set
+# CONFIG_SENSORS_LM78 is not set
+# CONFIG_SENSORS_LM80 is not set
+# CONFIG_SENSORS_LM83 is not set
+# CONFIG_SENSORS_LM85 is not set
+# CONFIG_SENSORS_LM87 is not set
+# CONFIG_SENSORS_LM90 is not set
+# CONFIG_SENSORS_LM92 is not set
+# CONFIG_SENSORS_MAX1619 is not set
+# CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_SIS5595 is not set
+# CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_VIA686A is not set
+# CONFIG_SENSORS_W83781D is not set
+# CONFIG_SENSORS_W83792D is not set
+# CONFIG_SENSORS_W83L785TS is not set
+# CONFIG_SENSORS_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Misc devices
+#
+
+#
+# Multimedia Capabilities Port drivers
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+CONFIG_FB=y
+# CONFIG_FB_CFB_FILLRECT is not set
+# CONFIG_FB_CFB_COPYAREA is not set
+# CONFIG_FB_CFB_IMAGEBLIT is not set
+# CONFIG_FB_SOFT_CURSOR is not set
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+# CONFIG_FB_CIRRUS is not set
+# CONFIG_FB_PM2 is not set
+# CONFIG_FB_CYBER2000 is not set
+# CONFIG_FB_ASILIANT is not set
+# CONFIG_FB_IMSTT is not set
+# CONFIG_FB_NVIDIA is not set
+# CONFIG_FB_RIVA is not set
+# CONFIG_FB_MATROX is not set
+# CONFIG_FB_RADEON_OLD is not set
+# CONFIG_FB_RADEON is not set
+# CONFIG_FB_ATY128 is not set
+# CONFIG_FB_ATY is not set
+# CONFIG_FB_SAVAGE is not set
+# CONFIG_FB_SIS is not set
+# CONFIG_FB_NEOMAGIC is not set
+# CONFIG_FB_KYRO is not set
+# CONFIG_FB_3DFX is not set
+# CONFIG_FB_VOODOO1 is not set
+# CONFIG_FB_SMIVGX is not set
+# CONFIG_FB_CYBLA is not set
+# CONFIG_FB_TRIDENT is not set
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_VIRTUAL is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE is not set
+
+#
+# Logo configuration
+#
+# CONFIG_LOGO is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+# CONFIG_USB_BANDWIDTH is not set
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_OTG is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_EHCI_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_OHCI_HCD is not set
+# CONFIG_USB_UHCI_HCD is not set
+# CONFIG_USB_SL811_HCD is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_BLUETOOTH_TTY is not set
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+#
+CONFIG_USB_STORAGE=y
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ONETOUCH is not set
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=y
+CONFIG_USB_HIDINPUT=y
+# CONFIG_HID_FF is not set
+CONFIG_USB_HIDDEV=y
+# CONFIG_USB_AIPTEK is not set
+# CONFIG_USB_WACOM is not set
+# CONFIG_USB_ACECAD is not set
+# CONFIG_USB_KBTAB is not set
+# CONFIG_USB_POWERMATE is not set
+# CONFIG_USB_MTOUCH is not set
+# CONFIG_USB_ITMTOUCH is not set
+# CONFIG_USB_EGALAX is not set
+# CONFIG_USB_YEALINK is not set
+# CONFIG_USB_XPAD is not set
+# CONFIG_USB_ATI_REMOTE is not set
+# CONFIG_USB_KEYSPAN_REMOTE is not set
+# CONFIG_USB_APPLETOUCH is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+
+#
+# USB Multimedia devices
+#
+# CONFIG_USB_DABUSB is not set
+
+#
+# Video4Linux support is needed for USB Multimedia device support
+#
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET is not set
+CONFIG_USB_MON=y
+
+#
+# USB port drivers
+#
+
+#
+# USB Serial Converter support
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_AUERSWALD is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_PHIDGETKIT is not set
+# CONFIG_USB_PHIDGETSERVO is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TEST is not set
+
+#
+# USB DSL modem support
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
+# SN Devices
+#
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_XATTR=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
+# CONFIG_EXT3_FS_SECURITY is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+CONFIG_XFS_FS=m
+CONFIG_XFS_EXPORT=y
+# CONFIG_XFS_QUOTA is not set
+# CONFIG_XFS_SECURITY is not set
+# CONFIG_XFS_POSIX_ACL is not set
+# CONFIG_XFS_RT is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+CONFIG_AUTOFS_FS=y
+CONFIG_AUTOFS4_FS=y
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+# CONFIG_PROC_KCORE is not set
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+# CONFIG_RELAYFS_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_CRAMFS=y
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFS_DIRECTIO is not set
+CONFIG_NFSD=m
+# CONFIG_NFSD_V3 is not set
+# CONFIG_NFSD_TCP is not set
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=m
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+CONFIG_SMB_FS=m
+# CONFIG_SMB_NLS_DEFAULT is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+# CONFIG_NLS_CODEPAGE_437 is not set
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+# CONFIG_NLS_ISO8859_1 is not set
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+# CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_CROSSCOMPILE=y
+CONFIG_CMDLINE=""
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
+
+#
+# Hardware crypto devices
+#
+
+#
+# Library routines
+#
+CONFIG_CRC_CCITT=m
+# CONFIG_CRC16 is not set
+CONFIG_CRC32=y
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=m
diff --git a/arch/mips/configs/qemu_defconfig b/arch/mips/configs/qemu_defconfig
index b6568e421b99..741a9a971367 100644
--- a/arch/mips/configs/qemu_defconfig
+++ b/arch/mips/configs/qemu_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.13-rc6
-# Mon Aug 8 11:49:54 2005
+# Linux kernel version: 2.6.14-rc2
+# Thu Oct 20 22:26:56 2005
#
CONFIG_MIPS=y
@@ -17,6 +17,7 @@ CONFIG_INIT_ENV_ARG_LIMIT=32
# General setup
#
CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
# CONFIG_SWAP is not set
# CONFIG_SYSVIPC is not set
# CONFIG_BSD_PROCESS_ACCT is not set
@@ -25,6 +26,7 @@ CONFIG_LOCALVERSION=""
# CONFIG_HOTPLUG is not set
CONFIG_KOBJECT_UEVENT=y
# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
CONFIG_EMBEDDED=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
@@ -74,6 +76,7 @@ CONFIG_BASE_SMALL=1
# CONFIG_MIPS_ATLAS is not set
# CONFIG_MIPS_MALTA is not set
# CONFIG_MIPS_SEAD is not set
+# CONFIG_MIPS_SIM is not set
# CONFIG_MOMENCO_JAGUAR_ATX is not set
# CONFIG_MOMENCO_OCELOT is not set
# CONFIG_MOMENCO_OCELOT_3 is not set
@@ -91,6 +94,7 @@ CONFIG_QEMU=y
# CONFIG_SGI_IP22 is not set
# CONFIG_SGI_IP27 is not set
# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_BIGSUR is not set
# CONFIG_SIBYTE_SWARM is not set
# CONFIG_SIBYTE_SENTOSA is not set
# CONFIG_SIBYTE_RHONE is not set
@@ -105,7 +109,6 @@ CONFIG_QEMU=y
# CONFIG_TOSHIBA_RBTX4938 is not set
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_HAVE_DEC_LOCK=y
CONFIG_DMA_COHERENT=y
CONFIG_GENERIC_ISA_DMA=y
CONFIG_I8259=y
@@ -119,7 +122,7 @@ CONFIG_HAVE_STD_PC_SERIAL_PORT=y
#
# CPU selection
#
-# CONFIG_CPU_MIPS32_R1 is not set
+CONFIG_CPU_MIPS32_R1=y
# CONFIG_CPU_MIPS32_R2 is not set
# CONFIG_CPU_MIPS64_R1 is not set
# CONFIG_CPU_MIPS64_R2 is not set
@@ -127,7 +130,7 @@ CONFIG_HAVE_STD_PC_SERIAL_PORT=y
# CONFIG_CPU_TX39XX is not set
# CONFIG_CPU_VR41XX is not set
# CONFIG_CPU_R4300 is not set
-CONFIG_CPU_R4X00=y
+# CONFIG_CPU_R4X00 is not set
# CONFIG_CPU_TX49XX is not set
# CONFIG_CPU_R5000 is not set
# CONFIG_CPU_R5432 is not set
@@ -138,9 +141,11 @@ CONFIG_CPU_R4X00=y
# CONFIG_CPU_RM7000 is not set
# CONFIG_CPU_RM9000 is not set
# CONFIG_CPU_SB1 is not set
+CONFIG_SYS_HAS_CPU_MIPS32_R1=y
+CONFIG_CPU_MIPS32=y
+CONFIG_CPU_MIPSR1=y
CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
-CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y
#
# Kernel type
@@ -151,15 +156,18 @@ 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_CPU_HAS_PREFETCH=y
# CONFIG_MIPS_MT is not set
# CONFIG_64BIT_PHYS_ADDR is not set
# CONFIG_CPU_ADVANCED is not set
CONFIG_CPU_HAS_LLSC=y
-CONFIG_CPU_HAS_LLDSCD=y
CONFIG_CPU_HAS_SYNC=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_ARCH_FLATMEM_ENABLE=y
CONFIG_FLATMEM=y
CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
CONFIG_PREEMPT_NONE=y
# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
@@ -214,8 +222,8 @@ CONFIG_IP_PNP_BOOTP=y
# CONFIG_INET_ESP is not set
# CONFIG_INET_IPCOMP is not set
# CONFIG_INET_TUNNEL is not set
-CONFIG_IP_TCPDIAG=y
-# CONFIG_IP_TCPDIAG_IPV6 is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
# CONFIG_TCP_CONG_ADVANCED is not set
CONFIG_TCP_CONG_BIC=y
# CONFIG_IPV6 is not set
@@ -232,9 +240,15 @@ CONFIG_TCP_CONG_BIC=y
#
# Network testing
#
+# CONFIG_NET_PKTGEN is not set
# CONFIG_HAMRADIO is not set
# CONFIG_IRDA is not set
# CONFIG_BT is not set
+CONFIG_IEEE80211=y
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=y
+CONFIG_IEEE80211_CRYPT_CCMP=y
+CONFIG_IEEE80211_CRYPT_TKIP=y
#
# Device Drivers
@@ -248,6 +262,11 @@ CONFIG_STANDALONE=y
# CONFIG_FW_LOADER is not set
#
+# Connector - unified userspace <-> kernelspace linker
+#
+CONFIG_CONNECTOR=y
+
+#
# Memory Technology Devices (MTD)
#
# CONFIG_MTD is not set
@@ -265,13 +284,12 @@ CONFIG_STANDALONE=y
#
# Block devices
#
-# CONFIG_BLK_DEV_FD is not set
# CONFIG_BLK_DEV_COW_COMMON is not set
# CONFIG_BLK_DEV_LOOP is not set
# CONFIG_BLK_DEV_NBD is not set
# CONFIG_BLK_DEV_RAM is not set
CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_LBD is not set
# CONFIG_CDROM_PKTCDVD is not set
#
@@ -291,6 +309,7 @@ CONFIG_IOSCHED_NOOP=y
#
# SCSI device support
#
+CONFIG_RAID_ATTRS=y
# CONFIG_SCSI is not set
#
@@ -331,6 +350,21 @@ CONFIG_NETDEVICES=y
# CONFIG_ARCNET is not set
#
+# PHY device support
+#
+CONFIG_PHYLIB=y
+CONFIG_PHYCONTROL=y
+
+#
+# MII PHY device drivers
+#
+CONFIG_MARVELL_PHY=y
+CONFIG_DAVICOM_PHY=y
+CONFIG_QSEMI_PHY=y
+CONFIG_LXT_PHY=y
+CONFIG_CICADA_PHY=y
+
+#
# Ethernet (10 or 100Mbit)
#
CONFIG_NET_ETHERNET=y
@@ -470,7 +504,6 @@ CONFIG_SERIAL_CORE_CONSOLE=y
# I2C support
#
# CONFIG_I2C is not set
-# CONFIG_I2C_SENSOR is not set
#
# Dallas's 1-wire bus
@@ -481,12 +514,17 @@ CONFIG_SERIAL_CORE_CONSOLE=y
# Hardware Monitoring support
#
# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
#
# Misc devices
#
#
+# Multimedia Capabilities Port drivers
+#
+
+#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
@@ -532,7 +570,6 @@ CONFIG_DUMMY_CONSOLE=y
#
# InfiniBand support
#
-# CONFIG_INFINIBAND is not set
#
# SN Devices
@@ -547,10 +584,6 @@ CONFIG_DUMMY_CONSOLE=y
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
# CONFIG_FS_POSIX_ACL is not set
-
-#
-# XFS support
-#
# CONFIG_XFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
@@ -559,6 +592,7 @@ CONFIG_INOTIFY=y
# CONFIG_DNOTIFY is not set
# CONFIG_AUTOFS_FS is not set
# CONFIG_AUTOFS4_FS is not set
+CONFIG_FUSE_FS=y
#
# CD-ROM/DVD Filesystems
@@ -576,11 +610,13 @@ CONFIG_INOTIFY=y
#
# Pseudo filesystems
#
-# CONFIG_PROC_FS is not set
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
# CONFIG_SYSFS is not set
# CONFIG_TMPFS is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
+CONFIG_RELAYFS_FS=y
#
# Miscellaneous filesystems
@@ -634,12 +670,35 @@ CONFIG_CMDLINE="console=ttyS0 debug ip=172.20.0.2:172.20.0.1::255.255.0.0"
# Security options
#
# CONFIG_KEYS is not set
-# CONFIG_SECURITY is not set
#
# Cryptographic options
#
-# CONFIG_CRYPTO is not set
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_NULL=y
+CONFIG_CRYPTO_MD4=y
+CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_SHA1=y
+CONFIG_CRYPTO_SHA256=y
+CONFIG_CRYPTO_SHA512=y
+CONFIG_CRYPTO_WP512=y
+CONFIG_CRYPTO_TGR192=y
+CONFIG_CRYPTO_DES=y
+CONFIG_CRYPTO_BLOWFISH=y
+CONFIG_CRYPTO_TWOFISH=y
+CONFIG_CRYPTO_SERPENT=y
+CONFIG_CRYPTO_AES=y
+CONFIG_CRYPTO_CAST5=y
+CONFIG_CRYPTO_CAST6=y
+CONFIG_CRYPTO_TEA=y
+CONFIG_CRYPTO_ARC4=y
+CONFIG_CRYPTO_KHAZAD=y
+CONFIG_CRYPTO_ANUBIS=y
+CONFIG_CRYPTO_DEFLATE=y
+CONFIG_CRYPTO_MICHAEL_MIC=y
+CONFIG_CRYPTO_CRC32C=y
+# CONFIG_CRYPTO_TEST is not set
#
# Hardware crypto devices
@@ -649,7 +708,8 @@ CONFIG_CMDLINE="console=ttyS0 debug ip=172.20.0.2:172.20.0.1::255.255.0.0"
# Library routines
#
# CONFIG_CRC_CCITT is not set
+CONFIG_CRC16=y
CONFIG_CRC32=y
-# CONFIG_LIBCRC32C is not set
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_LIBCRC32C=y
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
diff --git a/arch/mips/configs/rbhma4500_defconfig b/arch/mips/configs/rbhma4500_defconfig
new file mode 100644
index 000000000000..897420d39053
--- /dev/null
+++ b/arch/mips/configs/rbhma4500_defconfig
@@ -0,0 +1,1258 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.14-rc2
+# Thu Oct 20 22:26:59 2005
+#
+CONFIG_MIPS=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_HOTPLUG=y
+# CONFIG_KOBJECT_UEVENT is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
+# CONFIG_FUTEX is not set
+# CONFIG_EPOLL is not set
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+# CONFIG_MODULE_UNLOAD is not set
+CONFIG_OBSOLETE_MODPARM=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+
+#
+# Machine selection
+#
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_MIPS_PB1550 is not set
+# CONFIG_MIPS_PB1200 is not set
+# CONFIG_MIPS_DB1000 is not set
+# CONFIG_MIPS_DB1100 is not set
+# CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
+# CONFIG_MIPS_DB1200 is not set
+# CONFIG_MIPS_MIRAGE is not set
+# CONFIG_MIPS_COBALT is not set
+# CONFIG_MACH_DECSTATION is not set
+# CONFIG_MIPS_EV64120 is not set
+# CONFIG_MIPS_EV96100 is not set
+# CONFIG_MIPS_IVR is not set
+# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_LASAT is not set
+# CONFIG_MIPS_ATLAS is not set
+# CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SEAD is not set
+# CONFIG_MIPS_SIM is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_MOMENCO_OCELOT_3 is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MIPS_XXS1500 is not set
+# CONFIG_PNX8550_V2PCI is not set
+# CONFIG_PNX8550_JBS is not set
+# CONFIG_DDB5074 is not set
+# CONFIG_DDB5476 is not set
+# CONFIG_DDB5477 is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_QEMU is not set
+# CONFIG_SGI_IP22 is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_BIGSUR is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_PTSWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CRHONE is not set
+# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_TOSHIBA_RBTX4927 is not set
+CONFIG_TOSHIBA_RBTX4938=y
+
+#
+# Multiplex Pin Select
+#
+CONFIG_TOSHIBA_RBTX4938_MPLEX_PIO58_61=y
+# CONFIG_TOSHIBA_RBTX4938_MPLEX_NAND is not set
+# CONFIG_TOSHIBA_RBTX4938_MPLEX_ATA is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_DMA_NONCOHERENT=y
+CONFIG_DMA_NEED_PCI_MAP_STATE=y
+CONFIG_GENERIC_ISA_DMA=y
+CONFIG_I8259=y
+# CONFIG_CPU_BIG_ENDIAN is not set
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
+CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
+CONFIG_SWAP_IO_SPACE=y
+CONFIG_MIPS_L1_CACHE_SHIFT=5
+CONFIG_HAVE_STD_PC_SERIAL_PORT=y
+CONFIG_TOSHIBA_BOARDS=y
+
+#
+# CPU selection
+#
+# CONFIG_CPU_MIPS32_R1 is not set
+# CONFIG_CPU_MIPS32_R2 is not set
+# CONFIG_CPU_MIPS64_R1 is not set
+# CONFIG_CPU_MIPS64_R2 is not set
+# CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_TX39XX is not set
+# CONFIG_CPU_VR41XX is not set
+# CONFIG_CPU_R4300 is not set
+# CONFIG_CPU_R4X00 is not set
+CONFIG_CPU_TX49XX=y
+# CONFIG_CPU_R5000 is not set
+# CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_R6000 is not set
+# CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
+# CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_RM7000 is not set
+# CONFIG_CPU_RM9000 is not set
+# CONFIG_CPU_SB1 is not set
+CONFIG_SYS_HAS_CPU_TX49XX=y
+CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y
+
+#
+# Kernel type
+#
+CONFIG_32BIT=y
+# CONFIG_64BIT is not set
+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_MIPS_MT is not set
+CONFIG_CPU_ADVANCED=y
+CONFIG_CPU_HAS_LLSC=y
+CONFIG_CPU_HAS_LLDSCD=y
+CONFIG_CPU_HAS_WB=y
+CONFIG_CPU_HAS_SYNC=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_ARCH_FLATMEM_ENABLE=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_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+
+#
+# Bus options (PCI, PCMCIA, EISA, ISA, TC)
+#
+CONFIG_HW_HAS_PCI=y
+CONFIG_PCI=y
+# CONFIG_PCI_LEGACY_PROC is not set
+CONFIG_ISA=y
+CONFIG_MMU=y
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PCI Hotplug Support
+#
+# CONFIG_HOTPLUG_PCI is not set
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+CONFIG_TRAD_SIGNALS=y
+
+#
+# Networking
+#
+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=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+
+#
+# IP: Virtual Server Configuration
+#
+# CONFIG_IP_VS is not set
+CONFIG_IPV6=m
+# CONFIG_IPV6_PRIVACY is not set
+# CONFIG_INET6_AH is not set
+# CONFIG_INET6_ESP is not set
+# CONFIG_INET6_IPCOMP is not set
+# CONFIG_INET6_TUNNEL is not set
+# CONFIG_IPV6_TUNNEL is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+CONFIG_NETFILTER_NETLINK=m
+CONFIG_NETFILTER_NETLINK_QUEUE=m
+CONFIG_NETFILTER_NETLINK_LOG=m
+
+#
+# IP: Netfilter Configuration
+#
+# CONFIG_IP_NF_CONNTRACK is not set
+CONFIG_IP_NF_PPTP=m
+# CONFIG_IP_NF_QUEUE is not set
+# CONFIG_IP_NF_IPTABLES is not set
+# CONFIG_IP_NF_ARPTABLES is not set
+
+#
+# IPv6: Netfilter Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP6_NF_QUEUE is not set
+# CONFIG_IP6_NF_IPTABLES is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP 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_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_IEEE80211=m
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=m
+CONFIG_IEEE80211_CRYPT_CCMP=m
+CONFIG_IEEE80211_CRYPT_TKIP=m
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=m
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+CONFIG_CONNECTOR=m
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_CMDLINE_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_CFI_AMDSTD_RETRY=0
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PHYSMAP is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLKMTD 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
+
+#
+# NAND Flash Device Drivers
+#
+# CONFIG_MTD_NAND is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+# CONFIG_PNP is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+CONFIG_BLK_DEV_NBD=m
+# CONFIG_BLK_DEV_SX8 is not set
+# CONFIG_BLK_DEV_UB is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=8192
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_LBD is not set
+# CONFIG_CDROM_PKTCDVD is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_ATA_OVER_ETH is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+CONFIG_IDE=y
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_IDE_SATA is not set
+CONFIG_BLK_DEV_IDEDISK=y
+# CONFIG_IDEDISK_MULTI_MODE is not set
+CONFIG_BLK_DEV_IDECD=y
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_BLK_DEV_IDEFLOPPY is not set
+# CONFIG_IDE_TASK_IOCTL is not set
+
+#
+# IDE chipset support/bugfixes
+#
+CONFIG_IDE_GENERIC=y
+CONFIG_BLK_DEV_IDEPCI=y
+CONFIG_IDEPCI_SHARE_IRQ=y
+# CONFIG_BLK_DEV_OFFBOARD is not set
+# CONFIG_BLK_DEV_GENERIC is not set
+# CONFIG_BLK_DEV_OPTI621 is not set
+CONFIG_BLK_DEV_IDEDMA_PCI=y
+# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
+# CONFIG_IDEDMA_PCI_AUTO is not set
+# CONFIG_BLK_DEV_AEC62XX is not set
+# CONFIG_BLK_DEV_ALI15X3 is not set
+# CONFIG_BLK_DEV_AMD74XX is not set
+# CONFIG_BLK_DEV_CMD64X is not set
+# CONFIG_BLK_DEV_TRIFLEX is not set
+# CONFIG_BLK_DEV_CY82C693 is not set
+# CONFIG_BLK_DEV_CS5520 is not set
+# CONFIG_BLK_DEV_CS5530 is not set
+# CONFIG_BLK_DEV_HPT34X is not set
+# CONFIG_BLK_DEV_HPT366 is not set
+# CONFIG_BLK_DEV_SC1200 is not set
+# CONFIG_BLK_DEV_PIIX is not set
+# CONFIG_BLK_DEV_IT821X is not set
+# CONFIG_BLK_DEV_NS87415 is not set
+# CONFIG_BLK_DEV_PDC202XX_OLD is not set
+# CONFIG_BLK_DEV_PDC202XX_NEW is not set
+# CONFIG_BLK_DEV_SVWKS is not set
+# CONFIG_BLK_DEV_SIIMAGE is not set
+# CONFIG_BLK_DEV_SLC90E66 is not set
+# CONFIG_BLK_DEV_TRM290 is not set
+# CONFIG_BLK_DEV_VIA82CXXX is not set
+# CONFIG_IDE_ARM is not set
+# CONFIG_IDE_CHIPSETS is not set
+CONFIG_BLK_DEV_IDEDMA=y
+# CONFIG_IDEDMA_IVB is not set
+# CONFIG_IDEDMA_AUTO is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI device support
+#
+CONFIG_RAID_ATTRS=m
+# CONFIG_SCSI is not set
+
+#
+# Old CD-ROM drivers (not SCSI, not IDE)
+#
+# CONFIG_CD_NO_IDESCSI is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+CONFIG_TUN=m
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
+#
+# PHY device support
+#
+CONFIG_PHYLIB=m
+CONFIG_PHYCONTROL=y
+
+#
+# MII PHY device drivers
+#
+CONFIG_MARVELL_PHY=m
+CONFIG_DAVICOM_PHY=m
+CONFIG_QSEMI_PHY=m
+CONFIG_LXT_PHY=m
+CONFIG_CICADA_PHY=m
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_MII is not set
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_NET_VENDOR_SMC is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+
+#
+# Tulip family network device support
+#
+# CONFIG_NET_TULIP is not set
+# CONFIG_AT1700 is not set
+# CONFIG_DEPCA is not set
+# CONFIG_HP100 is not set
+CONFIG_NET_ISA=y
+# CONFIG_E2100 is not set
+# CONFIG_EWRK3 is not set
+# CONFIG_EEXPRESS is not set
+# CONFIG_EEXPRESS_PRO is not set
+# CONFIG_HPLAN_PLUS is not set
+# CONFIG_HPLAN is not set
+# CONFIG_LP486E is not set
+# CONFIG_ETH16I is not set
+CONFIG_NE2000=y
+# CONFIG_SEEQ8005 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_AC3200 is not set
+# CONFIG_APRICOT is not set
+# CONFIG_B44 is not set
+# CONFIG_FORCEDETH is not set
+# CONFIG_CS89x0 is not set
+# CONFIG_DGRS is not set
+# CONFIG_EEPRO100 is not set
+# CONFIG_E100 is not set
+# CONFIG_FEALNX is not set
+# CONFIG_NATSEMI is not set
+# CONFIG_NE2K_PCI is not set
+# CONFIG_8139CP is not set
+# CONFIG_8139TOO is not set
+# CONFIG_SIS900 is not set
+# CONFIG_EPIC100 is not set
+# CONFIG_SUNDANCE is not set
+# CONFIG_TLAN is not set
+# CONFIG_VIA_RHINE is not set
+# CONFIG_LAN_SAA9730 is not set
+# CONFIG_NET_POCKET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_VIA_VELOCITY is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
+
+#
+# Ethernet (10000 Mbit)
+#
+# CONFIG_CHELSIO_T1 is not set
+# CONFIG_IXGB is not set
+# CONFIG_S2IO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+CONFIG_NET_RADIO=y
+
+#
+# Obsolete Wireless cards support (pre-802.11)
+#
+# CONFIG_STRIP is not set
+# CONFIG_ARLAN is not set
+# CONFIG_WAVELAN is not set
+
+#
+# Wireless 802.11b ISA/PCI cards support
+#
+# CONFIG_IPW2100 is not set
+# CONFIG_IPW_DEBUG is not set
+CONFIG_IPW2200=m
+# CONFIG_AIRO is not set
+# CONFIG_HERMES is not set
+# CONFIG_ATMEL is not set
+
+#
+# Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support
+#
+# CONFIG_PRISM54 is not set
+# CONFIG_HOSTAP is not set
+CONFIG_NET_WIRELESS=y
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+CONFIG_PPP=m
+CONFIG_PPP_MULTILINK=y
+# CONFIG_PPP_FILTER is not set
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
+CONFIG_PPP_DEFLATE=m
+# CONFIG_PPP_BSDCOMP is not set
+CONFIG_PPPOE=m
+# CONFIG_SLIP is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+CONFIG_KEYBOARD_ATKBD=y
+# 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_INPUT_MOUSE=y
+CONFIG_MOUSE_PS2=y
+# CONFIG_MOUSE_SERIAL is not set
+# CONFIG_MOUSE_INPORT is not set
+# CONFIG_MOUSE_LOGIBM is not set
+# CONFIG_MOUSE_PC110PAD is not set
+# CONFIG_MOUSE_VSXXXAA is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_I8042=y
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_PCIPS2 is not set
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_HAS_TXX9_SERIAL=y
+# CONFIG_SERIAL_JSM is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_RTC is not set
+# CONFIG_GEN_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_DRM is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Misc devices
+#
+
+#
+# Multimedia Capabilities Port drivers
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+CONFIG_FB=y
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+CONFIG_FB_SOFT_CURSOR=y
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+# CONFIG_FB_CIRRUS is not set
+# CONFIG_FB_PM2 is not set
+# CONFIG_FB_CYBER2000 is not set
+# CONFIG_FB_ASILIANT is not set
+# CONFIG_FB_IMSTT is not set
+# CONFIG_FB_NVIDIA is not set
+# CONFIG_FB_RIVA is not set
+# CONFIG_FB_MATROX is not set
+# CONFIG_FB_RADEON_OLD is not set
+# CONFIG_FB_RADEON is not set
+# CONFIG_FB_ATY128 is not set
+CONFIG_FB_ATY=y
+CONFIG_FB_ATY_CT=y
+# CONFIG_FB_ATY_GENERIC_LCD is not set
+# CONFIG_FB_ATY_XL_INIT is not set
+# CONFIG_FB_ATY_GX is not set
+# CONFIG_FB_SAVAGE is not set
+# CONFIG_FB_SIS is not set
+# CONFIG_FB_NEOMAGIC is not set
+# CONFIG_FB_KYRO is not set
+# CONFIG_FB_3DFX is not set
+# CONFIG_FB_VOODOO1 is not set
+# CONFIG_FB_SMIVGX is not set
+# CONFIG_FB_CYBLA is not set
+# CONFIG_FB_TRIDENT is not set
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_VIRTUAL is not set
+
+#
+# Console display driver support
+#
+CONFIG_VGA_CONSOLE=y
+# CONFIG_MDA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE is not set
+
+#
+# Logo configuration
+#
+# CONFIG_LOGO is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+
+#
+# Miscellaneous USB options
+#
+# CONFIG_USB_DEVICEFS is not set
+# CONFIG_USB_BANDWIDTH is not set
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_OTG is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_EHCI_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_OHCI_HCD is not set
+# CONFIG_USB_UHCI_HCD is not set
+# CONFIG_USB_SL811_HCD is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_BLUETOOTH_TTY is not set
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+#
+# CONFIG_USB_STORAGE is not set
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=y
+CONFIG_USB_HIDINPUT=y
+# CONFIG_HID_FF is not set
+CONFIG_USB_HIDDEV=y
+# CONFIG_USB_AIPTEK is not set
+# CONFIG_USB_WACOM is not set
+# CONFIG_USB_ACECAD is not set
+# CONFIG_USB_KBTAB is not set
+# CONFIG_USB_POWERMATE is not set
+# CONFIG_USB_MTOUCH is not set
+# CONFIG_USB_ITMTOUCH is not set
+# CONFIG_USB_EGALAX is not set
+CONFIG_USB_YEALINK=m
+# CONFIG_USB_XPAD is not set
+# CONFIG_USB_ATI_REMOTE is not set
+# CONFIG_USB_KEYSPAN_REMOTE is not set
+# CONFIG_USB_APPLETOUCH is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+
+#
+# USB Multimedia devices
+#
+# CONFIG_USB_DABUSB is not set
+
+#
+# Video4Linux support is needed for USB Multimedia device support
+#
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET is not set
+# CONFIG_USB_ZD1201 is not set
+CONFIG_USB_MON=y
+
+#
+# USB port drivers
+#
+
+#
+# USB Serial Converter support
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_AUERSWALD is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_PHIDGETKIT is not set
+# CONFIG_USB_PHIDGETSERVO is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_LD is not set
+
+#
+# USB DSL modem support
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
+# SN Devices
+#
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=m
+CONFIG_EXT3_FS_XATTR=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
+# CONFIG_EXT3_FS_SECURITY is not set
+CONFIG_JBD=m
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+CONFIG_REISERFS_FS=m
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
+# CONFIG_REISERFS_FS_XATTR is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+CONFIG_XFS_FS=m
+CONFIG_XFS_EXPORT=y
+# CONFIG_XFS_QUOTA is not set
+# CONFIG_XFS_SECURITY is not set
+# CONFIG_XFS_POSIX_ACL is not set
+# CONFIG_XFS_RT is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+# CONFIG_QUOTA is not set
+# CONFIG_DNOTIFY is not set
+# CONFIG_AUTOFS_FS is not set
+CONFIG_AUTOFS4_FS=m
+CONFIG_FUSE_FS=m
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=y
+# CONFIG_JOLIET is not set
+# CONFIG_ZISOFS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+# CONFIG_MSDOS_FS is not set
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+# CONFIG_PROC_KCORE is not set
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+CONFIG_RELAYFS_FS=m
+
+#
+# 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_JFFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
+CONFIG_JFFS2_ZLIB=y
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN is not set
+CONFIG_CRAMFS=y
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFS_DIRECTIO is not set
+CONFIG_NFSD=m
+# CONFIG_NFSD_V3 is not set
+# CONFIG_NFSD_TCP is not set
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=m
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+CONFIG_SMB_FS=m
+# CONFIG_SMB_NLS_DEFAULT is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+# CONFIG_NLS_CODEPAGE_437 is not set
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+# CONFIG_NLS_ISO8859_1 is not set
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+# CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_CROSSCOMPILE=y
+CONFIG_CMDLINE=""
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_AES=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_CRC32C=m
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Hardware crypto devices
+#
+
+#
+# Library routines
+#
+CONFIG_CRC_CCITT=m
+CONFIG_CRC16=m
+CONFIG_CRC32=y
+CONFIG_LIBCRC32C=m
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
diff --git a/arch/mips/configs/rm200_defconfig b/arch/mips/configs/rm200_defconfig
index 17d4fce6c4c6..988a05824f01 100644
--- a/arch/mips/configs/rm200_defconfig
+++ b/arch/mips/configs/rm200_defconfig
@@ -1,12 +1,9 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-rc2
-# Wed Jan 26 02:49:09 2005
+# Linux kernel version: 2.6.14-rc2
+# Thu Oct 20 22:27:03 2005
#
CONFIG_MIPS=y
-# CONFIG_64BIT is not set
-# CONFIG_64BIT is not set
-CONFIG_32BIT=y
#
# Code maturity level options
@@ -14,11 +11,13 @@ CONFIG_32BIT=y
CONFIG_EXPERIMENTAL=y
CONFIG_CLEAN_COMPILE=y
CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
#
# General setup
#
CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
CONFIG_POSIX_MQUEUE=y
@@ -26,14 +25,17 @@ CONFIG_BSD_PROCESS_ACCT=y
# CONFIG_BSD_PROCESS_ACCT_V3 is not set
CONFIG_SYSCTL=y
# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_HOTPLUG is not set
+CONFIG_HOTPLUG=y
CONFIG_KOBJECT_UEVENT=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
+CONFIG_INITRAMFS_SOURCE=""
CONFIG_EMBEDDED=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
@@ -43,6 +45,7 @@ CONFIG_CC_ALIGN_LABELS=0
CONFIG_CC_ALIGN_LOOPS=0
CONFIG_CC_ALIGN_JUMPS=0
# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
#
# Loadable module support
@@ -58,43 +61,73 @@ CONFIG_KMOD=y
#
# Machine selection
#
-# CONFIG_MACH_JAZZ is not set
-# CONFIG_MACH_VR41XX is not set
-# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_MIPS_PB1550 is not set
+# CONFIG_MIPS_PB1200 is not set
+# CONFIG_MIPS_DB1000 is not set
+# CONFIG_MIPS_DB1100 is not set
+# CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
+# CONFIG_MIPS_DB1200 is not set
+# CONFIG_MIPS_MIRAGE is not set
# CONFIG_MIPS_COBALT is not set
# CONFIG_MACH_DECSTATION is not set
# CONFIG_MIPS_EV64120 is not set
# CONFIG_MIPS_EV96100 is not set
# CONFIG_MIPS_IVR is not set
-# CONFIG_LASAT is not set
# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_LASAT is not set
# CONFIG_MIPS_ATLAS is not set
# CONFIG_MIPS_MALTA is not set
# CONFIG_MIPS_SEAD is not set
+# CONFIG_MIPS_SIM is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
# CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_G is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_JAGUAR_ATX is not set
-# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MIPS_XXS1500 is not set
+# CONFIG_PNX8550_V2PCI is not set
+# CONFIG_PNX8550_JBS is not set
# CONFIG_DDB5074 is not set
# CONFIG_DDB5476 is not set
# CONFIG_DDB5477 is not set
-# CONFIG_NEC_OSPREY is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_QEMU is not set
# CONFIG_SGI_IP22 is not set
-# CONFIG_SOC_AU1X00 is not set
-# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_BIGSUR is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_PTSWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CRHONE is not set
CONFIG_SNI_RM200_PCI=y
+# CONFIG_TOSHIBA_JMR3927 is not set
# CONFIG_TOSHIBA_RBTX4927 is not set
+# CONFIG_TOSHIBA_RBTX4938 is not set
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_HAVE_DEC_LOCK=y
CONFIG_ARC=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
CONFIG_DMA_NONCOHERENT=y
CONFIG_DMA_NEED_PCI_MAP_STATE=y
CONFIG_GENERIC_ISA_DMA=y
CONFIG_I8259=y
+# CONFIG_CPU_BIG_ENDIAN is not set
CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
+CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
CONFIG_ARC32=y
CONFIG_BOOT_ELF32=y
CONFIG_MIPS_L1_CACHE_SHIFT=5
@@ -106,8 +139,10 @@ CONFIG_ARC_PROMLIB=y
#
# CPU selection
#
-# CONFIG_CPU_MIPS32 is not set
-# CONFIG_CPU_MIPS64 is not set
+# CONFIG_CPU_MIPS32_R1 is not set
+# CONFIG_CPU_MIPS32_R2 is not set
+# CONFIG_CPU_MIPS64_R1 is not set
+# CONFIG_CPU_MIPS64_R2 is not set
# CONFIG_CPU_R3000 is not set
# CONFIG_CPU_TX39XX is not set
# CONFIG_CPU_VR41XX is not set
@@ -123,24 +158,49 @@ CONFIG_CPU_R4X00=y
# CONFIG_CPU_RM7000 is not set
# CONFIG_CPU_RM9000 is not set
# CONFIG_CPU_SB1 is not set
+CONFIG_SYS_HAS_CPU_R4X00=y
+CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
+CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y
+
+#
+# Kernel type
+#
+CONFIG_32BIT=y
+# CONFIG_64BIT is not set
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_MIPS_MT is not set
# CONFIG_64BIT_PHYS_ADDR is not set
# CONFIG_CPU_ADVANCED is not set
CONFIG_CPU_HAS_LLSC=y
CONFIG_CPU_HAS_LLDSCD=y
CONFIG_CPU_HAS_SYNC=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_SYS_SUPPORTS_HIGHMEM=y
+CONFIG_ARCH_FLATMEM_ENABLE=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_PREEMPT_NONE is not set
+CONFIG_PREEMPT_VOLUNTARY=y
# CONFIG_PREEMPT is not set
#
# Bus options (PCI, PCMCIA, EISA, ISA, TC)
#
+CONFIG_HW_HAS_EISA=y
CONFIG_HW_HAS_PCI=y
CONFIG_PCI=y
CONFIG_PCI_LEGACY_PROC=y
-# CONFIG_PCI_NAMES is not set
CONFIG_ISA=y
# CONFIG_EISA is not set
CONFIG_MMU=y
@@ -151,11 +211,6 @@ CONFIG_MMU=y
# CONFIG_PCCARD is not set
#
-# PC-card bridges
-#
-CONFIG_PCMCIA_PROBE=y
-
-#
# PCI Hotplug Support
#
# CONFIG_HOTPLUG_PCI is not set
@@ -168,240 +223,7 @@ CONFIG_BINFMT_MISC=m
CONFIG_TRAD_SIGNALS=y
#
-# Device Drivers
-#
-
-#
-# Generic Driver Options
-#
-CONFIG_STANDALONE=y
-CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
-
-#
-# Memory Technology Devices (MTD)
-#
-# CONFIG_MTD is not set
-
-#
-# Parallel port support
-#
-CONFIG_PARPORT=m
-CONFIG_PARPORT_PC=m
-CONFIG_PARPORT_PC_CML1=m
-CONFIG_PARPORT_SERIAL=m
-# CONFIG_PARPORT_PC_FIFO is not set
-# CONFIG_PARPORT_PC_SUPERIO is not set
-# CONFIG_PARPORT_OTHER is not set
-CONFIG_PARPORT_1284=y
-
-#
-# Plug and Play support
-#
-# CONFIG_PNP is not set
-
-#
-# Block devices
-#
-CONFIG_BLK_DEV_FD=m
-# CONFIG_BLK_DEV_XD is not set
-CONFIG_PARIDE=m
-CONFIG_PARIDE_PARPORT=m
-
-#
-# Parallel IDE high-level drivers
-#
-CONFIG_PARIDE_PD=m
-CONFIG_PARIDE_PCD=m
-CONFIG_PARIDE_PF=m
-CONFIG_PARIDE_PT=m
-CONFIG_PARIDE_PG=m
-
-#
-# Parallel IDE protocol modules
-#
-CONFIG_PARIDE_ATEN=m
-CONFIG_PARIDE_BPCK=m
-CONFIG_PARIDE_BPCK6=m
-CONFIG_PARIDE_COMM=m
-CONFIG_PARIDE_DSTR=m
-CONFIG_PARIDE_FIT2=m
-CONFIG_PARIDE_FIT3=m
-CONFIG_PARIDE_EPAT=m
-# CONFIG_PARIDE_EPATC8 is not set
-CONFIG_PARIDE_EPIA=m
-CONFIG_PARIDE_FRIQ=m
-CONFIG_PARIDE_FRPW=m
-CONFIG_PARIDE_KBIC=m
-CONFIG_PARIDE_KTTI=m
-CONFIG_PARIDE_ON20=m
-CONFIG_PARIDE_ON26=m
-# CONFIG_BLK_CPQ_DA is not set
-# CONFIG_BLK_CPQ_CISS_DA is not set
-# CONFIG_BLK_DEV_DAC960 is not set
-# CONFIG_BLK_DEV_UMEM is not set
-# CONFIG_BLK_DEV_COW_COMMON is not set
-CONFIG_BLK_DEV_LOOP=m
-CONFIG_BLK_DEV_CRYPTOLOOP=m
-CONFIG_BLK_DEV_NBD=m
-CONFIG_BLK_DEV_SX8=m
-CONFIG_BLK_DEV_UB=m
-CONFIG_BLK_DEV_RAM=m
-CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_BLK_DEV_RAM_SIZE=4096
-CONFIG_INITRAMFS_SOURCE=""
-# CONFIG_LBD is not set
-CONFIG_CDROM_PKTCDVD=m
-CONFIG_CDROM_PKTCDVD_BUFFERS=8
-# CONFIG_CDROM_PKTCDVD_WCACHE is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-CONFIG_ATA_OVER_ETH=m
-
-#
-# ATA/ATAPI/MFM/RLL support
-#
-# CONFIG_IDE is not set
-
-#
-# SCSI device support
-#
-CONFIG_SCSI=y
-CONFIG_SCSI_PROC_FS=y
-
-#
-# SCSI support type (disk, tape, CD-ROM)
-#
-CONFIG_BLK_DEV_SD=y
-CONFIG_CHR_DEV_ST=m
-# CONFIG_CHR_DEV_OSST is not set
-CONFIG_BLK_DEV_SR=m
-CONFIG_BLK_DEV_SR_VENDOR=y
-# CONFIG_CHR_DEV_SG is not set
-
-#
-# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
-#
-# CONFIG_SCSI_MULTI_LUN is not set
-CONFIG_SCSI_CONSTANTS=y
-# CONFIG_SCSI_LOGGING is not set
-
-#
-# SCSI Transport Attributes
-#
-CONFIG_SCSI_SPI_ATTRS=y
-# CONFIG_SCSI_FC_ATTRS is not set
-# CONFIG_SCSI_ISCSI_ATTRS is not set
-
-#
-# SCSI low-level drivers
-#
-# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
-# CONFIG_SCSI_3W_9XXX is not set
-# CONFIG_SCSI_7000FASST is not set
-# CONFIG_SCSI_ACARD is not set
-# CONFIG_SCSI_AHA152X is not set
-# CONFIG_SCSI_AHA1542 is not set
-# CONFIG_SCSI_AACRAID is not set
-# CONFIG_SCSI_AIC7XXX is not set
-# CONFIG_SCSI_AIC7XXX_OLD is not set
-# CONFIG_SCSI_AIC79XX is not set
-# CONFIG_SCSI_DPT_I2O is not set
-# CONFIG_SCSI_IN2000 is not set
-CONFIG_MEGARAID_NEWGEN=y
-CONFIG_MEGARAID_MM=m
-CONFIG_MEGARAID_MAILBOX=m
-# CONFIG_SCSI_SATA is not set
-# CONFIG_SCSI_BUSLOGIC is not set
-# CONFIG_SCSI_DMX3191D is not set
-# CONFIG_SCSI_DTC3280 is not set
-# CONFIG_SCSI_EATA is not set
-# CONFIG_SCSI_EATA_PIO is not set
-# CONFIG_SCSI_FUTURE_DOMAIN is not set
-# CONFIG_SCSI_GDTH is not set
-# CONFIG_SCSI_GENERIC_NCR5380 is not set
-# CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set
-# CONFIG_SCSI_IPS is not set
-# CONFIG_SCSI_INITIO is not set
-# CONFIG_SCSI_INIA100 is not set
-CONFIG_SCSI_PPA=m
-CONFIG_SCSI_IMM=m
-# CONFIG_SCSI_IZIP_EPP16 is not set
-# CONFIG_SCSI_IZIP_SLOW_CTR is not set
-# CONFIG_SCSI_NCR53C406A is not set
-CONFIG_SCSI_SYM53C8XX_2=y
-CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1
-CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
-CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
-# CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set
-# CONFIG_SCSI_IPR is not set
-# CONFIG_SCSI_PAS16 is not set
-# CONFIG_SCSI_PSI240I is not set
-# CONFIG_SCSI_QLOGIC_FAS is not set
-# CONFIG_SCSI_QLOGIC_ISP is not set
-# CONFIG_SCSI_QLOGIC_FC is not set
-# CONFIG_SCSI_QLOGIC_1280 is not set
-CONFIG_SCSI_QLA2XXX=y
-# CONFIG_SCSI_QLA21XX is not set
-# CONFIG_SCSI_QLA22XX is not set
-# CONFIG_SCSI_QLA2300 is not set
-# CONFIG_SCSI_QLA2322 is not set
-# CONFIG_SCSI_QLA6312 is not set
-# CONFIG_SCSI_SYM53C416 is not set
-# CONFIG_SCSI_DC395x is not set
-# CONFIG_SCSI_DC390T is not set
-# CONFIG_SCSI_T128 is not set
-# CONFIG_SCSI_U14_34F is not set
-# CONFIG_SCSI_NSP32 is not set
-# CONFIG_SCSI_DEBUG is not set
-
-#
-# Old CD-ROM drivers (not SCSI, not IDE)
-#
-# CONFIG_CD_NO_IDESCSI is not set
-
-#
-# Multi-device support (RAID and LVM)
-#
-CONFIG_MD=y
-CONFIG_BLK_DEV_MD=m
-CONFIG_MD_LINEAR=m
-CONFIG_MD_RAID0=m
-CONFIG_MD_RAID1=m
-CONFIG_MD_RAID10=m
-CONFIG_MD_RAID5=m
-# CONFIG_MD_RAID6 is not set
-CONFIG_MD_MULTIPATH=m
-CONFIG_MD_FAULTY=m
-CONFIG_BLK_DEV_DM=m
-# CONFIG_DM_CRYPT is not set
-CONFIG_DM_SNAPSHOT=m
-CONFIG_DM_MIRROR=m
-CONFIG_DM_ZERO=m
-
-#
-# Fusion MPT device support
-#
-# CONFIG_FUSION is not set
-
-#
-# IEEE 1394 (FireWire) support
-#
-# CONFIG_IEEE1394 is not set
-
-#
-# I2O device support
-#
-# CONFIG_I2O is not set
-
-#
-# Networking support
+# Networking
#
CONFIG_NET=y
@@ -410,12 +232,14 @@ CONFIG_NET=y
#
CONFIG_PACKET=m
CONFIG_PACKET_MMAP=y
-CONFIG_NETLINK_DEV=m
CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
CONFIG_NET_KEY=m
CONFIG_INET=y
CONFIG_IP_MULTICAST=y
# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
# CONFIG_IP_PNP is not set
CONFIG_NET_IPIP=m
CONFIG_NET_IPGRE=m
@@ -429,8 +253,10 @@ CONFIG_IP_PIMSM_V2=y
# CONFIG_INET_ESP is not set
# CONFIG_INET_IPCOMP is not set
CONFIG_INET_TUNNEL=m
-CONFIG_IP_TCPDIAG=m
-CONFIG_IP_TCPDIAG_IPV6=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
#
# IP: Virtual Server Configuration
@@ -446,6 +272,9 @@ CONFIG_IPV6_TUNNEL=m
CONFIG_NETFILTER=y
# CONFIG_NETFILTER_DEBUG is not set
CONFIG_BRIDGE_NETFILTER=y
+CONFIG_NETFILTER_NETLINK=m
+CONFIG_NETFILTER_NETLINK_QUEUE=m
+CONFIG_NETFILTER_NETLINK_LOG=m
#
# IP: Netfilter Configuration
@@ -453,11 +282,15 @@ CONFIG_BRIDGE_NETFILTER=y
CONFIG_IP_NF_CONNTRACK=m
# CONFIG_IP_NF_CT_ACCT is not set
CONFIG_IP_NF_CONNTRACK_MARK=y
+CONFIG_IP_NF_CONNTRACK_EVENTS=y
+CONFIG_IP_NF_CONNTRACK_NETLINK=m
CONFIG_IP_NF_CT_PROTO_SCTP=m
CONFIG_IP_NF_FTP=m
CONFIG_IP_NF_IRC=m
+# CONFIG_IP_NF_NETBIOS_NS is not set
CONFIG_IP_NF_TFTP=m
CONFIG_IP_NF_AMANDA=m
+CONFIG_IP_NF_PPTP=m
CONFIG_IP_NF_QUEUE=m
CONFIG_IP_NF_IPTABLES=m
CONFIG_IP_NF_MATCH_LIMIT=m
@@ -482,9 +315,11 @@ CONFIG_IP_NF_MATCH_PHYSDEV=m
CONFIG_IP_NF_MATCH_ADDRTYPE=m
CONFIG_IP_NF_MATCH_REALM=m
CONFIG_IP_NF_MATCH_SCTP=m
+CONFIG_IP_NF_MATCH_DCCP=m
CONFIG_IP_NF_MATCH_COMMENT=m
CONFIG_IP_NF_MATCH_CONNMARK=m
CONFIG_IP_NF_MATCH_HASHLIMIT=m
+CONFIG_IP_NF_MATCH_STRING=m
CONFIG_IP_NF_FILTER=m
CONFIG_IP_NF_TARGET_REJECT=m
CONFIG_IP_NF_TARGET_LOG=m
@@ -501,12 +336,14 @@ CONFIG_IP_NF_NAT_IRC=m
CONFIG_IP_NF_NAT_FTP=m
CONFIG_IP_NF_NAT_TFTP=m
CONFIG_IP_NF_NAT_AMANDA=m
+CONFIG_IP_NF_NAT_PPTP=m
CONFIG_IP_NF_MANGLE=m
CONFIG_IP_NF_TARGET_TOS=m
CONFIG_IP_NF_TARGET_ECN=m
CONFIG_IP_NF_TARGET_DSCP=m
CONFIG_IP_NF_TARGET_MARK=m
CONFIG_IP_NF_TARGET_CLASSIFY=m
+CONFIG_IP_NF_TARGET_TTL=m
CONFIG_IP_NF_TARGET_CONNMARK=m
CONFIG_IP_NF_TARGET_CLUSTERIP=m
CONFIG_IP_NF_RAW=m
@@ -516,7 +353,7 @@ CONFIG_IP_NF_ARPFILTER=m
CONFIG_IP_NF_ARP_MANGLE=m
#
-# IPv6: Netfilter Configuration
+# IPv6: Netfilter Configuration (EXPERIMENTAL)
#
CONFIG_IP6_NF_QUEUE=m
CONFIG_IP6_NF_IPTABLES=m
@@ -536,8 +373,10 @@ CONFIG_IP6_NF_MATCH_EUI64=m
CONFIG_IP6_NF_MATCH_PHYSDEV=m
CONFIG_IP6_NF_FILTER=m
CONFIG_IP6_NF_TARGET_LOG=m
+CONFIG_IP6_NF_TARGET_REJECT=m
CONFIG_IP6_NF_MANGLE=m
CONFIG_IP6_NF_TARGET_MARK=m
+CONFIG_IP6_NF_TARGET_HL=m
CONFIG_IP6_NF_RAW=m
#
@@ -567,9 +406,12 @@ CONFIG_BRIDGE_EBT_MARK_T=m
CONFIG_BRIDGE_EBT_REDIRECT=m
CONFIG_BRIDGE_EBT_SNAT=m
CONFIG_BRIDGE_EBT_LOG=m
-# CONFIG_BRIDGE_EBT_ULOG is not set
-CONFIG_XFRM=y
-# CONFIG_XFRM_USER is not set
+CONFIG_BRIDGE_EBT_ULOG=m
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
#
# SCTP Configuration (EXPERIMENTAL)
@@ -588,10 +430,6 @@ CONFIG_DECNET=m
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
CONFIG_NET_SCHED=y
CONFIG_NET_SCH_CLK_JIFFIES=y
# CONFIG_NET_SCH_CLK_GETTIMEOFDAY is not set
@@ -611,6 +449,7 @@ CONFIG_NET_SCH_INGRESS=m
CONFIG_NET_QOS=y
CONFIG_NET_ESTIMATOR=y
CONFIG_NET_CLS=y
+CONFIG_NET_CLS_BASIC=m
CONFIG_NET_CLS_TCINDEX=m
CONFIG_NET_CLS_ROUTE4=m
CONFIG_NET_CLS_ROUTE=y
@@ -621,6 +460,7 @@ CONFIG_NET_CLS_U32=m
# CONFIG_CLS_U32_MARK is not set
CONFIG_NET_CLS_RSVP=m
CONFIG_NET_CLS_RSVP6=m
+# CONFIG_NET_EMATCH is not set
# CONFIG_NET_CLS_ACT is not set
CONFIG_NET_CLS_POLICE=y
@@ -628,8 +468,6 @@ CONFIG_NET_CLS_POLICE=y
# Network testing
#
# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
CONFIG_HAMRADIO=y
#
@@ -646,8 +484,6 @@ CONFIG_ROSE=m
CONFIG_MKISS=m
CONFIG_6PACK=m
CONFIG_BPQETHER=m
-# CONFIG_DMASCC is not set
-# CONFIG_SCC is not set
# CONFIG_BAYCOM_SER_FDX is not set
# CONFIG_BAYCOM_SER_HDX is not set
# CONFIG_BAYCOM_PAR is not set
@@ -655,12 +491,257 @@ CONFIG_BPQETHER=m
# CONFIG_YAM is not set
# CONFIG_IRDA is not set
# CONFIG_BT is not set
+CONFIG_IEEE80211=m
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=m
+CONFIG_IEEE80211_CRYPT_CCMP=m
+CONFIG_IEEE80211_CRYPT_TKIP=m
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=m
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+CONFIG_CONNECTOR=m
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+CONFIG_PARPORT=m
+CONFIG_PARPORT_PC=m
+CONFIG_PARPORT_SERIAL=m
+# CONFIG_PARPORT_PC_FIFO is not set
+# CONFIG_PARPORT_PC_SUPERIO is not set
+CONFIG_PARPORT_NOT_PC=y
+# CONFIG_PARPORT_GSC is not set
+CONFIG_PARPORT_1284=y
+
+#
+# Plug and Play support
+#
+# CONFIG_PNP is not set
+
+#
+# Block devices
+#
+CONFIG_BLK_DEV_FD=m
+CONFIG_PARIDE=m
+CONFIG_PARIDE_PARPORT=m
+
+#
+# Parallel IDE high-level drivers
+#
+CONFIG_PARIDE_PD=m
+CONFIG_PARIDE_PCD=m
+CONFIG_PARIDE_PF=m
+CONFIG_PARIDE_PT=m
+CONFIG_PARIDE_PG=m
+
+#
+# Parallel IDE protocol modules
+#
+CONFIG_PARIDE_ATEN=m
+CONFIG_PARIDE_BPCK=m
+CONFIG_PARIDE_BPCK6=m
+CONFIG_PARIDE_COMM=m
+CONFIG_PARIDE_DSTR=m
+CONFIG_PARIDE_FIT2=m
+CONFIG_PARIDE_FIT3=m
+CONFIG_PARIDE_EPAT=m
+# CONFIG_PARIDE_EPATC8 is not set
+CONFIG_PARIDE_EPIA=m
+CONFIG_PARIDE_FRIQ=m
+CONFIG_PARIDE_FRPW=m
+CONFIG_PARIDE_KBIC=m
+CONFIG_PARIDE_KTTI=m
+CONFIG_PARIDE_ON20=m
+CONFIG_PARIDE_ON26=m
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=m
+CONFIG_BLK_DEV_CRYPTOLOOP=m
+CONFIG_BLK_DEV_NBD=m
+CONFIG_BLK_DEV_SX8=m
+CONFIG_BLK_DEV_UB=m
+CONFIG_BLK_DEV_RAM=m
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=4096
+# CONFIG_LBD is not set
+CONFIG_CDROM_PKTCDVD=m
+CONFIG_CDROM_PKTCDVD_BUFFERS=8
+# CONFIG_CDROM_PKTCDVD_WCACHE is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_ATA_OVER_ETH=m
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+CONFIG_RAID_ATTRS=m
+CONFIG_SCSI=y
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_ST=m
+# CONFIG_CHR_DEV_OSST is not set
+CONFIG_BLK_DEV_SR=m
+CONFIG_BLK_DEV_SR_VENDOR=y
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# CONFIG_SCSI_MULTI_LUN is not set
+CONFIG_SCSI_CONSTANTS=y
+# CONFIG_SCSI_LOGGING is not set
+
+#
+# SCSI Transport Attributes
+#
+CONFIG_SCSI_SPI_ATTRS=y
+# CONFIG_SCSI_FC_ATTRS is not set
+CONFIG_SCSI_ISCSI_ATTRS=m
+CONFIG_SCSI_SAS_ATTRS=m
+
+#
+# SCSI low-level drivers
+#
+# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_ACARD is not set
+# CONFIG_SCSI_AHA152X is not set
+# CONFIG_SCSI_AACRAID is not set
+# CONFIG_SCSI_AIC7XXX is not set
+# CONFIG_SCSI_AIC7XXX_OLD is not set
+# CONFIG_SCSI_AIC79XX is not set
+# CONFIG_SCSI_DPT_I2O is not set
+# CONFIG_SCSI_IN2000 is not set
+CONFIG_MEGARAID_NEWGEN=y
+CONFIG_MEGARAID_MM=m
+CONFIG_MEGARAID_MAILBOX=m
+# CONFIG_SCSI_SATA is not set
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_DTC3280 is not set
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+# CONFIG_SCSI_GENERIC_NCR5380 is not set
+# CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set
+# CONFIG_SCSI_IPS is not set
+# CONFIG_SCSI_INITIO is not set
+# CONFIG_SCSI_INIA100 is not set
+CONFIG_SCSI_PPA=m
+CONFIG_SCSI_IMM=m
+# CONFIG_SCSI_IZIP_EPP16 is not set
+# CONFIG_SCSI_IZIP_SLOW_CTR is not set
+# CONFIG_SCSI_NCR53C406A is not set
+CONFIG_SCSI_SYM53C8XX_2=y
+CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1
+CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
+CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
+# CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set
+# CONFIG_SCSI_IPR is not set
+# CONFIG_SCSI_PAS16 is not set
+# CONFIG_SCSI_PSI240I is not set
+# CONFIG_SCSI_QLOGIC_FAS is not set
+# CONFIG_SCSI_QLOGIC_FC is not set
+# CONFIG_SCSI_QLOGIC_1280 is not set
+CONFIG_SCSI_QLA2XXX=y
+# CONFIG_SCSI_QLA21XX is not set
+# CONFIG_SCSI_QLA22XX is not set
+# CONFIG_SCSI_QLA2300 is not set
+# CONFIG_SCSI_QLA2322 is not set
+# CONFIG_SCSI_QLA6312 is not set
+# CONFIG_SCSI_QLA24XX is not set
+# CONFIG_SCSI_LPFC is not set
+# CONFIG_SCSI_SYM53C416 is not set
+# CONFIG_SCSI_DC395x is not set
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_T128 is not set
+# CONFIG_SCSI_NSP32 is not set
+# CONFIG_SCSI_DEBUG is not set
+
+#
+# Old CD-ROM drivers (not SCSI, not IDE)
+#
+# CONFIG_CD_NO_IDESCSI is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+CONFIG_MD=y
+CONFIG_BLK_DEV_MD=m
+CONFIG_MD_LINEAR=m
+CONFIG_MD_RAID0=m
+CONFIG_MD_RAID1=m
+CONFIG_MD_RAID10=m
+CONFIG_MD_RAID5=m
+# CONFIG_MD_RAID6 is not set
+CONFIG_MD_MULTIPATH=m
+CONFIG_MD_FAULTY=m
+CONFIG_BLK_DEV_DM=m
+# CONFIG_DM_CRYPT is not set
+CONFIG_DM_SNAPSHOT=m
+CONFIG_DM_MIRROR=m
+CONFIG_DM_ZERO=m
+CONFIG_DM_MULTIPATH=m
+CONFIG_DM_MULTIPATH_EMC=m
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+# CONFIG_FUSION_SPI is not set
+# CONFIG_FUSION_FC is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+
+#
+# Network device support
+#
CONFIG_NETDEVICES=y
CONFIG_DUMMY=m
CONFIG_BONDING=m
CONFIG_EQUALIZER=m
CONFIG_TUN=m
-CONFIG_ETHERTAP=m
#
# ARCnet devices
@@ -668,6 +749,21 @@ CONFIG_ETHERTAP=m
# CONFIG_ARCNET is not set
#
+# PHY device support
+#
+CONFIG_PHYLIB=m
+CONFIG_PHYCONTROL=y
+
+#
+# MII PHY device drivers
+#
+CONFIG_MARVELL_PHY=m
+CONFIG_DAVICOM_PHY=m
+CONFIG_QSEMI_PHY=m
+CONFIG_LXT_PHY=m
+CONFIG_CICADA_PHY=m
+
+#
# Ethernet (10 or 100Mbit)
#
CONFIG_NET_ETHERNET=y
@@ -675,7 +771,6 @@ CONFIG_MII=y
# CONFIG_HAPPYMEAL is not set
# CONFIG_SUNGEM is not set
# CONFIG_NET_VENDOR_3COM is not set
-# CONFIG_LANCE is not set
# CONFIG_NET_VENDOR_SMC is not set
# CONFIG_NET_VENDOR_RACAL is not set
@@ -696,7 +791,6 @@ CONFIG_NET_ISA=y
# CONFIG_LP486E is not set
# CONFIG_ETH16I is not set
CONFIG_NE2000=m
-# CONFIG_ZNET is not set
# CONFIG_SEEQ8005 is not set
CONFIG_NET_PCI=y
CONFIG_PCNET32=y
@@ -733,13 +827,17 @@ CONFIG_EEPRO100=m
# CONFIG_HAMACHI is not set
# CONFIG_YELLOWFIN is not set
# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
# CONFIG_SK98LIN is not set
CONFIG_VIA_VELOCITY=m
# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
#
# Ethernet (10000 Mbit)
#
+# CONFIG_CHELSIO_T1 is not set
# CONFIG_IXGB is not set
# CONFIG_S2IO is not set
@@ -752,6 +850,8 @@ CONFIG_VIA_VELOCITY=m
# Wireless LAN (non-hamradio)
#
# CONFIG_NET_RADIO is not set
+# CONFIG_IPW_DEBUG is not set
+CONFIG_IPW2200=m
#
# Wan interfaces
@@ -765,6 +865,8 @@ CONFIG_PLIP=m
# CONFIG_NET_FC is not set
# CONFIG_SHAPER is not set
# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
#
# ISDN subsystem
@@ -794,20 +896,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
# CONFIG_INPUT_EVBUG is not set
#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=y
-CONFIG_SERIO_I8042=y
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_CT82C710 is not set
-CONFIG_SERIO_PARKBD=m
-# CONFIG_SERIO_PCIPS2 is not set
-CONFIG_SERIO_LIBPS2=y
-CONFIG_SERIO_RAW=m
-
-#
# Input Device Drivers
#
CONFIG_INPUT_KEYBOARD=y
@@ -828,6 +916,18 @@ CONFIG_MOUSE_PS2=y
# CONFIG_INPUT_MISC is not set
#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_I8042=y
+CONFIG_SERIO_SERPORT=y
+CONFIG_SERIO_PARKBD=m
+# CONFIG_SERIO_PCIPS2 is not set
+CONFIG_SERIO_LIBPS2=y
+CONFIG_SERIO_RAW=m
+# CONFIG_GAMEPORT is not set
+
+#
# Character devices
#
CONFIG_VT=y
@@ -844,13 +944,13 @@ CONFIG_SERIAL_8250_EXTENDED=y
# CONFIG_SERIAL_8250_MANY_PORTS is not set
CONFIG_SERIAL_8250_SHARE_IRQ=y
CONFIG_SERIAL_8250_DETECT_IRQ=y
-CONFIG_SERIAL_8250_MULTIPORT=y
CONFIG_SERIAL_8250_RSA=y
#
# Non-8250 serial port support
#
CONFIG_SERIAL_CORE=m
+# CONFIG_SERIAL_JSM is not set
CONFIG_UNIX98_PTYS=y
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
@@ -881,6 +981,11 @@ CONFIG_RTC=m
# CONFIG_RAW_DRIVER is not set
#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+
+#
# I2C support
#
# CONFIG_I2C is not set
@@ -891,15 +996,26 @@ CONFIG_RTC=m
CONFIG_W1=m
CONFIG_W1_MATROX=m
CONFIG_W1_DS9490=m
-CONFIG_W1_DS9490_BRIDGE=m
+# CONFIG_W1_DS9490_BRIDGE is not set
CONFIG_W1_THERM=m
CONFIG_W1_SMEM=m
+# CONFIG_W1_DS2433 is not set
+
+#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
#
# Misc devices
#
#
+# Multimedia Capabilities Port drivers
+#
+
+#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
@@ -920,7 +1036,6 @@ CONFIG_W1_SMEM=m
CONFIG_VGA_CONSOLE=y
# CONFIG_MDA_CONSOLE is not set
CONFIG_DUMMY_CONSOLE=y
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Sound
@@ -930,6 +1045,8 @@ CONFIG_DUMMY_CONSOLE=y
#
# USB support
#
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
CONFIG_USB=m
# CONFIG_USB_DEBUG is not set
@@ -940,8 +1057,6 @@ CONFIG_USB_DEVICEFS=y
# CONFIG_USB_BANDWIDTH is not set
# CONFIG_USB_DYNAMIC_MINORS is not set
# CONFIG_USB_OTG is not set
-CONFIG_USB_ARCH_HAS_HCD=y
-CONFIG_USB_ARCH_HAS_OHCI=y
#
# USB Host Controller Drivers
@@ -949,7 +1064,10 @@ CONFIG_USB_ARCH_HAS_OHCI=y
CONFIG_USB_EHCI_HCD=m
# CONFIG_USB_EHCI_SPLIT_ISO is not set
# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
+# CONFIG_USB_ISP116X_HCD is not set
CONFIG_USB_OHCI_HCD=m
+# CONFIG_USB_OHCI_BIG_ENDIAN is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
CONFIG_USB_UHCI_HCD=m
# CONFIG_USB_SL811_HCD is not set
@@ -965,11 +1083,10 @@ CONFIG_USB_PRINTER=m
#
CONFIG_USB_STORAGE=m
# CONFIG_USB_STORAGE_DEBUG is not set
-# CONFIG_USB_STORAGE_RW_DETECT is not set
CONFIG_USB_STORAGE_DATAFAB=y
CONFIG_USB_STORAGE_FREECOM=y
CONFIG_USB_STORAGE_DPCM=y
-CONFIG_USB_STORAGE_HP8200e=y
+# CONFIG_USB_STORAGE_USBAT is not set
CONFIG_USB_STORAGE_SDDR09=y
CONFIG_USB_STORAGE_SDDR55=y
CONFIG_USB_STORAGE_JUMPSHOT=y
@@ -992,12 +1109,17 @@ CONFIG_USB_KBD=m
CONFIG_USB_MOUSE=m
CONFIG_USB_AIPTEK=m
CONFIG_USB_WACOM=m
+# CONFIG_USB_ACECAD is not set
CONFIG_USB_KBTAB=m
CONFIG_USB_POWERMATE=m
# CONFIG_USB_MTOUCH is not set
+# CONFIG_USB_ITMTOUCH is not set
CONFIG_USB_EGALAX=m
+CONFIG_USB_YEALINK=m
CONFIG_USB_XPAD=m
# CONFIG_USB_ATI_REMOTE is not set
+# CONFIG_USB_KEYSPAN_REMOTE is not set
+# CONFIG_USB_APPLETOUCH is not set
#
# USB Imaging devices
@@ -1022,30 +1144,15 @@ CONFIG_USB_KAWETH=m
CONFIG_USB_PEGASUS=m
CONFIG_USB_RTL8150=m
CONFIG_USB_USBNET=m
-
-#
-# USB Host-to-Host Cables
-#
-CONFIG_USB_ALI_M5632=y
-CONFIG_USB_AN2720=y
-CONFIG_USB_BELKIN=y
-CONFIG_USB_GENESYS=y
-CONFIG_USB_NET1080=y
-CONFIG_USB_PL2301=y
-CONFIG_USB_KC2190=y
-
-#
-# Intelligent USB Devices/Gadgets
-#
-CONFIG_USB_ARMLINUX=y
-CONFIG_USB_EPSON2888=y
-CONFIG_USB_ZAURUS=y
-CONFIG_USB_CDCETHER=y
-
-#
-# USB Network Adapters
-#
-CONFIG_USB_AX8817X=y
+CONFIG_USB_NET_AX8817X=m
+CONFIG_USB_NET_CDCETHER=m
+# CONFIG_USB_NET_GL620A is not set
+CONFIG_USB_NET_NET1080=m
+# CONFIG_USB_NET_PLUSB is not set
+# CONFIG_USB_NET_RNDIS_HOST is not set
+# CONFIG_USB_NET_CDC_SUBSET is not set
+CONFIG_USB_NET_ZAURUS=m
+CONFIG_USB_MON=y
#
# USB port drivers
@@ -1057,9 +1164,11 @@ CONFIG_USB_USS720=m
#
CONFIG_USB_SERIAL=m
CONFIG_USB_SERIAL_GENERIC=y
+CONFIG_USB_SERIAL_AIRPRIME=m
CONFIG_USB_SERIAL_BELKIN=m
CONFIG_USB_SERIAL_WHITEHEAT=m
CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m
+# CONFIG_USB_SERIAL_CP2101 is not set
CONFIG_USB_SERIAL_CYPRESS_M8=m
CONFIG_USB_SERIAL_EMPEG=m
CONFIG_USB_SERIAL_FTDI_SIO=m
@@ -1088,6 +1197,7 @@ CONFIG_USB_SERIAL_KLSI=m
CONFIG_USB_SERIAL_KOBIL_SCT=m
CONFIG_USB_SERIAL_MCT_U232=m
CONFIG_USB_SERIAL_PL2303=m
+CONFIG_USB_SERIAL_HP4X=m
CONFIG_USB_SERIAL_SAFE=m
CONFIG_USB_SERIAL_SAFE_PADDED=y
# CONFIG_USB_SERIAL_TI is not set
@@ -1110,10 +1220,13 @@ CONFIG_USB_CYTHERM=m
CONFIG_USB_PHIDGETKIT=m
CONFIG_USB_PHIDGETSERVO=m
# CONFIG_USB_IDMOUSE is not set
+CONFIG_USB_SISUSBVGA=m
+# CONFIG_USB_SISUSBVGA_CON is not set
+CONFIG_USB_LD=m
CONFIG_USB_TEST=m
#
-# USB ATM/DSL drivers
+# USB DSL modem support
#
#
@@ -1132,10 +1245,15 @@ CONFIG_USB_TEST=m
# CONFIG_INFINIBAND is not set
#
+# SN Devices
+#
+
+#
# File systems
#
CONFIG_EXT2_FS=m
# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
CONFIG_EXT3_FS=y
CONFIG_EXT3_FS_XATTR=y
# CONFIG_EXT3_FS_POSIX_ACL is not set
@@ -1152,17 +1270,20 @@ CONFIG_REISERFS_FS_SECURITY=y
# CONFIG_JFS_FS is not set
CONFIG_FS_POSIX_ACL=y
CONFIG_XFS_FS=m
-# CONFIG_XFS_RT is not set
-CONFIG_XFS_QUOTA=y
+CONFIG_XFS_EXPORT=y
+CONFIG_XFS_QUOTA=m
CONFIG_XFS_SECURITY=y
# CONFIG_XFS_POSIX_ACL is not set
+# CONFIG_XFS_RT is not set
CONFIG_MINIX_FS=m
CONFIG_ROMFS_FS=m
+CONFIG_INOTIFY=y
# CONFIG_QUOTA is not set
CONFIG_QUOTACTL=y
CONFIG_DNOTIFY=y
CONFIG_AUTOFS_FS=m
CONFIG_AUTOFS4_FS=m
+CONFIG_FUSE_FS=m
#
# CD-ROM/DVD Filesystems
@@ -1192,12 +1313,10 @@ CONFIG_NTFS_FS=m
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
-CONFIG_DEVPTS_FS_XATTR=y
-CONFIG_DEVPTS_FS_SECURITY=y
# CONFIG_TMPFS is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
+CONFIG_RELAYFS_FS=m
#
# Miscellaneous filesystems
@@ -1224,15 +1343,18 @@ CONFIG_UFS_FS=m
#
CONFIG_NFS_FS=m
CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
# CONFIG_NFS_V4 is not set
# CONFIG_NFS_DIRECTIO is not set
CONFIG_NFSD=m
CONFIG_NFSD_V3=y
+# CONFIG_NFSD_V3_ACL is not set
# CONFIG_NFSD_V4 is not set
CONFIG_NFSD_TCP=y
CONFIG_LOCKD=m
CONFIG_LOCKD_V4=y
CONFIG_EXPORTFS=m
+CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=m
CONFIG_SUNRPC_GSS=m
CONFIG_RPCSEC_GSS_KRB5=m
@@ -1256,6 +1378,7 @@ CONFIG_CODA_FS=m
CONFIG_CODA_FS_OLD_API=y
CONFIG_AFS_FS=m
CONFIG_RXRPC=m
+# CONFIG_9P_FS is not set
#
# Partition Types
@@ -1329,7 +1452,9 @@ CONFIG_NLS_UTF8=m
#
# Kernel hacking
#
+# CONFIG_PRINTK_TIME is not set
# CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=14
CONFIG_CROSSCOMPILE=y
CONFIG_CMDLINE=""
@@ -1352,6 +1477,7 @@ CONFIG_CRYPTO_SHA1=m
CONFIG_CRYPTO_SHA256=m
CONFIG_CRYPTO_SHA512=m
CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_TGR192=m
CONFIG_CRYPTO_DES=m
CONFIG_CRYPTO_BLOWFISH=m
CONFIG_CRYPTO_TWOFISH=m
@@ -1360,13 +1486,13 @@ CONFIG_CRYPTO_AES=m
CONFIG_CRYPTO_CAST5=m
CONFIG_CRYPTO_CAST6=m
CONFIG_CRYPTO_TEA=m
-# CONFIG_CRYPTO_ARC4 is not set
+CONFIG_CRYPTO_ARC4=m
CONFIG_CRYPTO_KHAZAD=m
CONFIG_CRYPTO_ANUBIS=m
CONFIG_CRYPTO_DEFLATE=m
CONFIG_CRYPTO_MICHAEL_MIC=m
-# CONFIG_CRYPTO_CRC32C is not set
-CONFIG_CRYPTO_TEST=m
+CONFIG_CRYPTO_CRC32C=m
+# CONFIG_CRYPTO_TEST is not set
#
# Hardware crypto devices
@@ -1376,9 +1502,12 @@ CONFIG_CRYPTO_TEST=m
# Library routines
#
CONFIG_CRC_CCITT=m
+CONFIG_CRC16=m
CONFIG_CRC32=y
-# CONFIG_LIBCRC32C is not set
+CONFIG_LIBCRC32C=m
CONFIG_ZLIB_INFLATE=m
CONFIG_ZLIB_DEFLATE=m
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_TEXTSEARCH=y
+CONFIG_TEXTSEARCH_KMP=m
+CONFIG_TEXTSEARCH_BM=m
+CONFIG_TEXTSEARCH_FSM=m
diff --git a/arch/mips/configs/sb1250-swarm_defconfig b/arch/mips/configs/sb1250-swarm_defconfig
index 1dc935f37582..4365d9c8c42e 100644
--- a/arch/mips/configs/sb1250-swarm_defconfig
+++ b/arch/mips/configs/sb1250-swarm_defconfig
@@ -1,12 +1,9 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-rc2
-# Wed Jan 26 02:49:10 2005
+# Linux kernel version: 2.6.14-rc2
+# Thu Oct 20 22:27:05 2005
#
CONFIG_MIPS=y
-# CONFIG_64BIT is not set
-# CONFIG_64BIT is not set
-CONFIG_32BIT=y
#
# Code maturity level options
@@ -14,24 +11,30 @@ CONFIG_32BIT=y
CONFIG_EXPERIMENTAL=y
CONFIG_CLEAN_COMPILE=y
CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
#
# General setup
#
CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
# CONFIG_POSIX_MQUEUE is not set
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=15
-# CONFIG_HOTPLUG is not set
+CONFIG_HOTPLUG=y
CONFIG_KOBJECT_UEVENT=y
# CONFIG_IKCONFIG is not set
+CONFIG_CPUSETS=y
+CONFIG_INITRAMFS_SOURCE=""
CONFIG_EMBEDDED=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
@@ -41,6 +44,7 @@ CONFIG_CC_ALIGN_LABELS=0
CONFIG_CC_ALIGN_LOOPS=0
CONFIG_CC_ALIGN_JUMPS=0
# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
#
# Loadable module support
@@ -57,32 +61,49 @@ CONFIG_STOP_MACHINE=y
#
# Machine selection
#
-# CONFIG_MACH_JAZZ is not set
-# CONFIG_MACH_VR41XX is not set
-# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_MIPS_PB1550 is not set
+# CONFIG_MIPS_PB1200 is not set
+# CONFIG_MIPS_DB1000 is not set
+# CONFIG_MIPS_DB1100 is not set
+# CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
+# CONFIG_MIPS_DB1200 is not set
+# CONFIG_MIPS_MIRAGE is not set
# CONFIG_MIPS_COBALT is not set
# CONFIG_MACH_DECSTATION is not set
# CONFIG_MIPS_EV64120 is not set
# CONFIG_MIPS_EV96100 is not set
# CONFIG_MIPS_IVR is not set
-# CONFIG_LASAT is not set
# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_LASAT is not set
# CONFIG_MIPS_ATLAS is not set
# CONFIG_MIPS_MALTA is not set
# CONFIG_MIPS_SEAD is not set
+# CONFIG_MIPS_SIM is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
# CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_G is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_JAGUAR_ATX is not set
-# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MIPS_XXS1500 is not set
+# CONFIG_PNX8550_V2PCI is not set
+# CONFIG_PNX8550_JBS is not set
# CONFIG_DDB5074 is not set
# CONFIG_DDB5476 is not set
# CONFIG_DDB5477 is not set
-# CONFIG_NEC_OSPREY is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_QEMU is not set
# CONFIG_SGI_IP22 is not set
-# CONFIG_SOC_AU1X00 is not set
-CONFIG_SIBYTE_SB1xxx_SOC=y
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_BIGSUR is not set
CONFIG_SIBYTE_SWARM=y
# CONFIG_SIBYTE_SENTOSA is not set
# CONFIG_SIBYTE_RHONE is not set
@@ -91,9 +112,12 @@ CONFIG_SIBYTE_SWARM=y
# CONFIG_SIBYTE_LITTLESUR is not set
# CONFIG_SIBYTE_CRHINE is not set
# CONFIG_SIBYTE_CRHONE is not set
-# CONFIG_SIBYTE_UNKNOWN is not set
-CONFIG_SIBYTE_BOARD=y
+# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_TOSHIBA_RBTX4927 is not set
+# CONFIG_TOSHIBA_RBTX4938 is not set
CONFIG_SIBYTE_SB1250=y
+CONFIG_SIBYTE_SB1xxx_SOC=y
CONFIG_CPU_SB1_PASS_1=y
# CONFIG_CPU_SB1_PASS_2_1250 is not set
# CONFIG_CPU_SB1_PASS_2_2 is not set
@@ -102,18 +126,20 @@ CONFIG_CPU_SB1_PASS_1=y
# CONFIG_CPU_SB1_PASS_3 is not set
CONFIG_SIBYTE_HAS_LDT=y
# CONFIG_SIMULATION is not set
+# CONFIG_CONFIG_SB1_CEX_ALWAYS_FATAL is not set
+# CONFIG_CONFIG_SB1_CERR_STALL is not set
CONFIG_SIBYTE_CFE=y
# CONFIG_SIBYTE_CFE_CONSOLE is not set
# CONFIG_SIBYTE_BUS_WATCHER is not set
# CONFIG_SIBYTE_SB1250_PROF is not set
# CONFIG_SIBYTE_TBPROF is not set
-# CONFIG_SNI_RM200_PCI is not set
-# CONFIG_TOSHIBA_RBTX4927 is not set
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_HAVE_DEC_LOCK=y
CONFIG_DMA_COHERENT=y
+CONFIG_CPU_BIG_ENDIAN=y
# CONFIG_CPU_LITTLE_ENDIAN is not set
+CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
+CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
CONFIG_SWAP_IO_SPACE=y
CONFIG_BOOT_ELF32=y
CONFIG_MIPS_L1_CACHE_SHIFT=5
@@ -121,8 +147,10 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5
#
# CPU selection
#
-# CONFIG_CPU_MIPS32 is not set
-# CONFIG_CPU_MIPS64 is not set
+# CONFIG_CPU_MIPS32_R1 is not set
+# CONFIG_CPU_MIPS32_R2 is not set
+# CONFIG_CPU_MIPS64_R1 is not set
+# CONFIG_CPU_MIPS64_R2 is not set
# CONFIG_CPU_R3000 is not set
# CONFIG_CPU_TX39XX is not set
# CONFIG_CPU_VR41XX is not set
@@ -138,22 +166,46 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5
# CONFIG_CPU_RM7000 is not set
# CONFIG_CPU_RM9000 is not set
CONFIG_CPU_SB1=y
+CONFIG_SYS_HAS_CPU_SB1=y
+CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
+CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y
+
+#
+# Kernel type
+#
+# CONFIG_32BIT is not set
+CONFIG_64BIT=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_SIBYTE_DMA_PAGEOPS is not set
CONFIG_CPU_HAS_PREFETCH=y
+# CONFIG_MIPS_MT is not set
CONFIG_SB1_PASS_1_WORKAROUNDS=y
-# CONFIG_64BIT_PHYS_ADDR is not set
-# CONFIG_CPU_ADVANCED is not set
CONFIG_CPU_HAS_LLSC=y
CONFIG_CPU_HAS_LLDSCD=y
CONFIG_CPU_HAS_SYNC=y
-# CONFIG_HIGHMEM is not set
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_CPU_SUPPORTS_HIGHMEM=y
+CONFIG_SYS_SUPPORTS_HIGHMEM=y
+CONFIG_ARCH_FLATMEM_ENABLE=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_SMP=y
CONFIG_NR_CPUS=2
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
+CONFIG_PREEMPT_BKL=y
#
# Bus options (PCI, PCMCIA, EISA, ISA, TC)
@@ -161,7 +213,6 @@ CONFIG_NR_CPUS=2
CONFIG_HW_HAS_PCI=y
CONFIG_PCI=y
CONFIG_PCI_LEGACY_PROC=y
-CONFIG_PCI_NAMES=y
CONFIG_MMU=y
#
@@ -170,10 +221,6 @@ CONFIG_MMU=y
# CONFIG_PCCARD is not set
#
-# PC-card bridges
-#
-
-#
# PCI Hotplug Support
#
# CONFIG_HOTPLUG_PCI is not set
@@ -183,7 +230,86 @@ CONFIG_MMU=y
#
CONFIG_BINFMT_ELF=y
# CONFIG_BINFMT_MISC is not set
-CONFIG_TRAD_SIGNALS=y
+# CONFIG_BUILD_ELF64 is not set
+CONFIG_MIPS32_COMPAT=y
+CONFIG_COMPAT=y
+CONFIG_MIPS32_O32=y
+# CONFIG_MIPS32_N32 is not set
+CONFIG_BINFMT_ELF32=y
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+CONFIG_NET_KEY=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+CONFIG_INET_TUNNEL=m
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+# CONFIG_IPV6 is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# 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_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_IEEE80211=m
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=m
+CONFIG_IEEE80211_CRYPT_CCMP=m
+CONFIG_IEEE80211_CRYPT_TKIP=m
#
# Device Drivers
@@ -194,7 +320,12 @@ CONFIG_TRAD_SIGNALS=y
#
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
+CONFIG_FW_LOADER=m
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+CONFIG_CONNECTOR=m
#
# Memory Technology Devices (MTD)
@@ -213,7 +344,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
#
# Block devices
#
-# CONFIG_BLK_DEV_FD is not set
# CONFIG_BLK_CPQ_DA is not set
# CONFIG_BLK_CPQ_CISS_DA is not set
# CONFIG_BLK_DEV_DAC960 is not set
@@ -226,8 +356,6 @@ CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=9220
CONFIG_BLK_DEV_INITRD=y
-CONFIG_INITRAMFS_SOURCE=""
-# CONFIG_LBD is not set
CONFIG_CDROM_PKTCDVD=m
CONFIG_CDROM_PKTCDVD_BUFFERS=8
# CONFIG_CDROM_PKTCDVD_WCACHE is not set
@@ -263,7 +391,7 @@ CONFIG_BLK_DEV_IDEFLOPPY=y
#
CONFIG_IDE_GENERIC=y
# CONFIG_BLK_DEV_IDEPCI is not set
-CONFIG_BLK_DEV_IDE_SWARM=y
+# CONFIG_BLK_DEV_IDE_SWARM is not set
# CONFIG_IDE_ARM is not set
# CONFIG_BLK_DEV_IDEDMA is not set
# CONFIG_IDEDMA_AUTO is not set
@@ -272,6 +400,7 @@ CONFIG_BLK_DEV_IDE_SWARM=y
#
# SCSI device support
#
+CONFIG_RAID_ATTRS=m
# CONFIG_SCSI is not set
#
@@ -282,6 +411,7 @@ CONFIG_BLK_DEV_IDE_SWARM=y
#
# Fusion MPT device support
#
+# CONFIG_FUSION is not set
#
# IEEE 1394 (FireWire) support
@@ -294,78 +424,13 @@ CONFIG_BLK_DEV_IDE_SWARM=y
# CONFIG_I2O is not set
#
-# Networking support
+# Network device support
#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
-CONFIG_NETLINK_DEV=y
-CONFIG_UNIX=y
-CONFIG_NET_KEY=y
-CONFIG_INET=y
-# CONFIG_IP_MULTICAST is not set
-# CONFIG_IP_ADVANCED_ROUTER is not set
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-CONFIG_IP_PNP_BOOTP=y
-# CONFIG_IP_PNP_RARP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_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_TUNNEL=m
-CONFIG_IP_TCPDIAG=m
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-# CONFIG_IPV6 is not set
-# CONFIG_NETFILTER is not set
-CONFIG_XFRM=y
-CONFIG_XFRM_USER=m
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP 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_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
CONFIG_NETDEVICES=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_EQUALIZER is not set
# CONFIG_TUN is not set
-# CONFIG_ETHERTAP is not set
#
# ARCnet devices
@@ -373,6 +438,21 @@ CONFIG_NETDEVICES=y
# CONFIG_ARCNET is not set
#
+# PHY device support
+#
+CONFIG_PHYLIB=m
+CONFIG_PHYCONTROL=y
+
+#
+# MII PHY device drivers
+#
+CONFIG_MARVELL_PHY=m
+CONFIG_DAVICOM_PHY=m
+CONFIG_QSEMI_PHY=m
+CONFIG_LXT_PHY=m
+CONFIG_CICADA_PHY=m
+
+#
# Ethernet (10 or 100Mbit)
#
CONFIG_NET_ETHERNET=y
@@ -399,12 +479,16 @@ CONFIG_MII=y
# CONFIG_YELLOWFIN is not set
# CONFIG_R8169 is not set
CONFIG_NET_SB1250_MAC=y
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
# CONFIG_SK98LIN is not set
# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
#
# Ethernet (10000 Mbit)
#
+# CONFIG_CHELSIO_T1 is not set
# CONFIG_IXGB is not set
# CONFIG_S2IO is not set
@@ -417,6 +501,8 @@ CONFIG_NET_SB1250_MAC=y
# Wireless LAN (non-hamradio)
#
# CONFIG_NET_RADIO is not set
+# CONFIG_IPW_DEBUG is not set
+CONFIG_IPW2200=m
#
# Wan interfaces
@@ -428,6 +514,8 @@ CONFIG_NET_SB1250_MAC=y
# CONFIG_SLIP is not set
# CONFIG_SHAPER is not set
# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
#
# ISDN subsystem
@@ -445,25 +533,15 @@ CONFIG_NET_SB1250_MAC=y
# CONFIG_INPUT is not set
#
-# Userland interfaces
-#
-
-#
-# Input I/O drivers
+# Hardware I/O ports
#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
CONFIG_SERIO=y
# CONFIG_SERIO_I8042 is not set
CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_CT82C710 is not set
# CONFIG_SERIO_PCIPS2 is not set
# CONFIG_SERIO_LIBPS2 is not set
CONFIG_SERIO_RAW=m
-
-#
-# Input Device Drivers
-#
+# CONFIG_GAMEPORT is not set
#
# Character devices
@@ -472,11 +550,13 @@ CONFIG_SERIO_RAW=m
CONFIG_SERIAL_NONSTANDARD=y
# CONFIG_ROCKETPORT is not set
# CONFIG_CYCLADES is not set
+# CONFIG_DIGIEPCA is not set
# CONFIG_MOXA_SMARTIO is not set
# CONFIG_ISI is not set
-# CONFIG_SYNCLINK is not set
# CONFIG_SYNCLINKMP is not set
# CONFIG_N_HDLC is not set
+# CONFIG_SPECIALIX is not set
+# CONFIG_SX is not set
# CONFIG_STALDRV is not set
CONFIG_SIBYTE_SB1250_DUART=y
CONFIG_SIBYTE_SB1250_DUART_CONSOLE=y
@@ -489,6 +569,7 @@ CONFIG_SIBYTE_SB1250_DUART_CONSOLE=y
#
# Non-8250 serial port support
#
+# CONFIG_SERIAL_JSM is not set
CONFIG_UNIX98_PTYS=y
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
@@ -515,6 +596,11 @@ CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_RAW_DRIVER is not set
#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+
+#
# I2C support
#
# CONFIG_I2C is not set
@@ -525,10 +611,20 @@ CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_W1 is not set
#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
+#
# Misc devices
#
#
+# Multimedia Capabilities Port drivers
+#
+
+#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
@@ -542,7 +638,6 @@ CONFIG_LEGACY_PTY_COUNT=256
# Graphics support
#
# CONFIG_FB is not set
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Sound
@@ -552,13 +647,9 @@ CONFIG_LEGACY_PTY_COUNT=256
#
# USB support
#
-# CONFIG_USB is not set
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB_ARCH_HAS_OHCI=y
-
-#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
-#
+# CONFIG_USB is not set
#
# USB Gadget Support
@@ -576,12 +667,17 @@ CONFIG_USB_ARCH_HAS_OHCI=y
# CONFIG_INFINIBAND is not set
#
+# SN Devices
+#
+
+#
# File systems
#
CONFIG_EXT2_FS=y
CONFIG_EXT2_FS_XATTR=y
CONFIG_EXT2_FS_POSIX_ACL=y
CONFIG_EXT2_FS_SECURITY=y
+# CONFIG_EXT2_FS_XIP is not set
# CONFIG_EXT3_FS is not set
# CONFIG_JBD is not set
CONFIG_FS_MBCACHE=y
@@ -591,10 +687,12 @@ CONFIG_FS_POSIX_ACL=y
# CONFIG_XFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
# CONFIG_QUOTA is not set
CONFIG_DNOTIFY=y
# CONFIG_AUTOFS_FS is not set
# CONFIG_AUTOFS4_FS is not set
+CONFIG_FUSE_FS=m
#
# CD-ROM/DVD Filesystems
@@ -615,11 +713,10 @@ CONFIG_DNOTIFY=y
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
-# CONFIG_DEVPTS_FS_XATTR is not set
# CONFIG_TMPFS is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
+CONFIG_RELAYFS_FS=m
#
# Miscellaneous filesystems
@@ -643,13 +740,14 @@ CONFIG_RAMFS=y
#
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
# CONFIG_NFS_V4 is not set
# CONFIG_NFS_DIRECTIO is not set
# CONFIG_NFSD is not set
CONFIG_ROOT_NFS=y
CONFIG_LOCKD=y
CONFIG_LOCKD_V4=y
-# CONFIG_EXPORTFS is not set
+CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
@@ -658,6 +756,7 @@ CONFIG_SUNRPC=y
# CONFIG_NCP_FS is not set
# CONFIG_CODA_FS is not set
# CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
#
# Partition Types
@@ -678,7 +777,9 @@ CONFIG_MSDOS_PARTITION=y
#
# Kernel hacking
#
+# CONFIG_PRINTK_TIME is not set
# CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=15
CONFIG_CROSSCOMPILE=y
CONFIG_CMDLINE=""
# CONFIG_SB1XXX_CORELIS is not set
@@ -695,27 +796,28 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
#
CONFIG_CRYPTO=y
CONFIG_CRYPTO_HMAC=y
-CONFIG_CRYPTO_NULL=y
-CONFIG_CRYPTO_MD4=y
-CONFIG_CRYPTO_MD5=y
-CONFIG_CRYPTO_SHA1=y
-CONFIG_CRYPTO_SHA256=y
-CONFIG_CRYPTO_SHA512=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
CONFIG_CRYPTO_WP512=m
-CONFIG_CRYPTO_DES=y
-CONFIG_CRYPTO_BLOWFISH=y
-CONFIG_CRYPTO_TWOFISH=y
-CONFIG_CRYPTO_SERPENT=y
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_SERPENT=m
CONFIG_CRYPTO_AES=m
-# CONFIG_CRYPTO_CAST5 is not set
-# CONFIG_CRYPTO_CAST6 is not set
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
CONFIG_CRYPTO_TEA=m
-# CONFIG_CRYPTO_ARC4 is not set
+CONFIG_CRYPTO_ARC4=m
CONFIG_CRYPTO_KHAZAD=m
CONFIG_CRYPTO_ANUBIS=m
-CONFIG_CRYPTO_DEFLATE=y
-CONFIG_CRYPTO_MICHAEL_MIC=y
-# CONFIG_CRYPTO_CRC32C is not set
+CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_CRC32C=m
# CONFIG_CRYPTO_TEST is not set
#
@@ -726,9 +828,8 @@ CONFIG_CRYPTO_MICHAEL_MIC=y
# Library routines
#
# CONFIG_CRC_CCITT is not set
+CONFIG_CRC16=m
CONFIG_CRC32=y
-# CONFIG_LIBCRC32C is not set
-CONFIG_ZLIB_INFLATE=y
-CONFIG_ZLIB_DEFLATE=y
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_LIBCRC32C=m
+CONFIG_ZLIB_INFLATE=m
+CONFIG_ZLIB_DEFLATE=m
diff --git a/arch/mips/configs/sead_defconfig b/arch/mips/configs/sead_defconfig
index dd07e866b128..d835f6db1f41 100644
--- a/arch/mips/configs/sead_defconfig
+++ b/arch/mips/configs/sead_defconfig
@@ -1,12 +1,9 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-rc2
-# Wed Jan 26 02:49:10 2005
+# Linux kernel version: 2.6.14-rc2
+# Thu Oct 20 22:27:07 2005
#
CONFIG_MIPS=y
-# CONFIG_64BIT is not set
-# CONFIG_64BIT is not set
-CONFIG_32BIT=y
#
# Code maturity level options
@@ -14,22 +11,26 @@ CONFIG_32BIT=y
CONFIG_EXPERIMENTAL=y
CONFIG_CLEAN_COMPILE=y
CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
#
# General setup
#
CONFIG_LOCALVERSION=""
-CONFIG_SWAP=y
-# CONFIG_SYSVIPC is not set
+CONFIG_LOCALVERSION_AUTO=y
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
-# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
# CONFIG_HOTPLUG is not set
# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
CONFIG_EMBEDDED=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
@@ -39,6 +40,7 @@ CONFIG_CC_ALIGN_LABELS=0
CONFIG_CC_ALIGN_LOOPS=0
CONFIG_CC_ALIGN_JUMPS=0
# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
#
# Loadable module support
@@ -48,40 +50,69 @@ CONFIG_CC_ALIGN_JUMPS=0
#
# Machine selection
#
-# CONFIG_MACH_JAZZ is not set
-# CONFIG_MACH_VR41XX is not set
-# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_MIPS_PB1550 is not set
+# CONFIG_MIPS_PB1200 is not set
+# CONFIG_MIPS_DB1000 is not set
+# CONFIG_MIPS_DB1100 is not set
+# CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
+# CONFIG_MIPS_DB1200 is not set
+# CONFIG_MIPS_MIRAGE is not set
# CONFIG_MIPS_COBALT is not set
# CONFIG_MACH_DECSTATION is not set
# CONFIG_MIPS_EV64120 is not set
# CONFIG_MIPS_EV96100 is not set
# CONFIG_MIPS_IVR is not set
-# CONFIG_LASAT is not set
# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_LASAT is not set
# CONFIG_MIPS_ATLAS is not set
# CONFIG_MIPS_MALTA is not set
CONFIG_MIPS_SEAD=y
+# CONFIG_MIPS_SIM is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
# CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_G is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_JAGUAR_ATX is not set
-# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MIPS_XXS1500 is not set
+# CONFIG_PNX8550_V2PCI is not set
+# CONFIG_PNX8550_JBS is not set
# CONFIG_DDB5074 is not set
# CONFIG_DDB5476 is not set
# CONFIG_DDB5477 is not set
-# CONFIG_NEC_OSPREY is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_QEMU is not set
# CONFIG_SGI_IP22 is not set
-# CONFIG_SOC_AU1X00 is not set
-# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_BIGSUR is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_PTSWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CRHONE is not set
# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
# CONFIG_TOSHIBA_RBTX4927 is not set
+# CONFIG_TOSHIBA_RBTX4938 is not set
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_HAVE_DEC_LOCK=y
CONFIG_DMA_NONCOHERENT=y
CONFIG_DMA_NEED_PCI_MAP_STATE=y
+# CONFIG_CPU_BIG_ENDIAN is not set
CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
+CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
CONFIG_IRQ_CPU=y
CONFIG_MIPS_BOARDS_GEN=y
CONFIG_MIPS_L1_CACHE_SHIFT=5
@@ -89,8 +120,10 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5
#
# CPU selection
#
-CONFIG_CPU_MIPS32=y
-# CONFIG_CPU_MIPS64 is not set
+CONFIG_CPU_MIPS32_R1=y
+# CONFIG_CPU_MIPS32_R2 is not set
+# CONFIG_CPU_MIPS64_R1 is not set
+# CONFIG_CPU_MIPS64_R2 is not set
# CONFIG_CPU_R3000 is not set
# CONFIG_CPU_TX39XX is not set
# CONFIG_CPU_VR41XX is not set
@@ -106,15 +139,42 @@ CONFIG_CPU_MIPS32=y
# CONFIG_CPU_RM7000 is not set
# CONFIG_CPU_RM9000 is not set
# CONFIG_CPU_SB1 is not set
+CONFIG_SYS_HAS_CPU_MIPS32_R1=y
+CONFIG_SYS_HAS_CPU_MIPS32_R2=y
+CONFIG_SYS_HAS_CPU_MIPS64_R1=y
+CONFIG_CPU_MIPS32=y
+CONFIG_CPU_MIPSR1=y
+CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
+CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
+
+#
+# Kernel type
+#
+CONFIG_32BIT=y
+# CONFIG_64BIT is not set
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_CPU_HAS_PREFETCH=y
+# CONFIG_MIPS_MT is not set
# CONFIG_64BIT_PHYS_ADDR is not set
# CONFIG_CPU_ADVANCED is not set
CONFIG_CPU_HAS_LLSC=y
CONFIG_CPU_HAS_SYNC=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_ARCH_FLATMEM_ENABLE=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_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
#
@@ -128,10 +188,6 @@ CONFIG_MMU=y
# CONFIG_PCCARD is not set
#
-# PC-card bridges
-#
-
-#
# PCI Hotplug Support
#
@@ -143,6 +199,11 @@ CONFIG_BINFMT_ELF=y
CONFIG_TRAD_SIGNALS=y
#
+# Networking
+#
+# CONFIG_NET is not set
+
+#
# Device Drivers
#
@@ -154,6 +215,10 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_FW_LOADER is not set
#
+# Connector - unified userspace <-> kernelspace linker
+#
+
+#
# Memory Technology Devices (MTD)
#
# CONFIG_MTD is not set
@@ -170,7 +235,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
#
# Block devices
#
-# CONFIG_BLK_DEV_FD is not set
# CONFIG_BLK_DEV_COW_COMMON is not set
CONFIG_BLK_DEV_LOOP=y
# CONFIG_BLK_DEV_CRYPTOLOOP is not set
@@ -178,11 +242,8 @@ CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=18432
CONFIG_BLK_DEV_INITRD=y
-CONFIG_INITRAMFS_SOURCE=""
# CONFIG_LBD is not set
-CONFIG_CDROM_PKTCDVD=y
-CONFIG_CDROM_PKTCDVD_BUFFERS=8
-# CONFIG_CDROM_PKTCDVD_WCACHE is not set
+# CONFIG_CDROM_PKTCDVD is not set
#
# IO Schedulers
@@ -200,6 +261,7 @@ CONFIG_IOSCHED_CFQ=y
#
# SCSI device support
#
+CONFIG_RAID_ATTRS=y
# CONFIG_SCSI is not set
#
@@ -210,6 +272,7 @@ CONFIG_IOSCHED_CFQ=y
#
# Fusion MPT device support
#
+# CONFIG_FUSION is not set
#
# IEEE 1394 (FireWire) support
@@ -220,9 +283,8 @@ CONFIG_IOSCHED_CFQ=y
#
#
-# Networking support
+# Network device support
#
-# CONFIG_NET is not set
# CONFIG_NETPOLL is not set
# CONFIG_NET_POLL_CONTROLLER is not set
@@ -238,47 +300,18 @@ CONFIG_IOSCHED_CFQ=y
#
# Input device support
#
-CONFIG_INPUT=y
+# CONFIG_INPUT is not set
#
-# Userland interfaces
-#
-CONFIG_INPUT_MOUSEDEV=y
-CONFIG_INPUT_MOUSEDEV_PSAUX=y
-CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
-# CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_TSDEV is not set
-# CONFIG_INPUT_EVDEV is not set
-# CONFIG_INPUT_EVBUG is not set
-
-#
-# Input I/O drivers
+# Hardware I/O ports
#
+# CONFIG_SERIO is not set
# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=y
-# CONFIG_SERIO_I8042 is not set
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_LIBPS2 is not set
-CONFIG_SERIO_RAW=y
-
-#
-# Input Device Drivers
-#
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_INPUT_JOYSTICK is not set
-# CONFIG_INPUT_TOUCHSCREEN is not set
-# CONFIG_INPUT_MISC is not set
#
# Character devices
#
-CONFIG_VT=y
-CONFIG_VT_CONSOLE=y
-CONFIG_HW_CONSOLE=y
+# CONFIG_VT is not set
# CONFIG_SERIAL_NONSTANDARD is not set
#
@@ -294,7 +327,7 @@ CONFIG_SERIAL_8250_NR_UARTS=4
#
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
-# CONFIG_UNIX98_PTYS is not set
+CONFIG_UNIX98_PTYS=y
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
@@ -315,10 +348,13 @@ CONFIG_LEGACY_PTY_COUNT=256
#
# Ftape, the floppy tape device driver
#
-# CONFIG_DRM is not set
# CONFIG_RAW_DRIVER is not set
#
+# TPM devices
+#
+
+#
# I2C support
#
# CONFIG_I2C is not set
@@ -329,10 +365,20 @@ CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_W1 is not set
#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
+#
# Misc devices
#
#
+# Multimedia Capabilities Port drivers
+#
+
+#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
@@ -347,13 +393,6 @@ CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_FB is not set
#
-# Console display driver support
-#
-# CONFIG_VGA_CONSOLE is not set
-CONFIG_DUMMY_CONSOLE=y
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
-
-#
# Sound
#
# CONFIG_SOUND is not set
@@ -365,10 +404,6 @@ CONFIG_DUMMY_CONSOLE=y
# CONFIG_USB_ARCH_HAS_OHCI is not set
#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
-#
-
-#
# USB Gadget Support
#
# CONFIG_USB_GADGET is not set
@@ -381,28 +416,31 @@ CONFIG_DUMMY_CONSOLE=y
#
# InfiniBand support
#
-# CONFIG_INFINIBAND is not set
+
+#
+# SN Devices
+#
#
# File systems
#
CONFIG_EXT2_FS=y
-CONFIG_EXT2_FS_XATTR=y
-CONFIG_EXT2_FS_POSIX_ACL=y
-CONFIG_EXT2_FS_SECURITY=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
# CONFIG_EXT3_FS is not set
# CONFIG_JBD is not set
-CONFIG_FS_MBCACHE=y
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
-CONFIG_FS_POSIX_ACL=y
+# CONFIG_FS_POSIX_ACL is not set
# CONFIG_XFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
# CONFIG_QUOTA is not set
CONFIG_DNOTIFY=y
# CONFIG_AUTOFS_FS is not set
# CONFIG_AUTOFS4_FS is not set
+CONFIG_FUSE_FS=y
#
# CD-ROM/DVD Filesystems
@@ -423,10 +461,10 @@ CONFIG_DNOTIFY=y
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
# CONFIG_TMPFS is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
+CONFIG_RELAYFS_FS=y
#
# Miscellaneous filesystems
@@ -448,8 +486,18 @@ CONFIG_RAMFS=y
#
# Partition Types
#
-# CONFIG_PARTITION_ADVANCED is not set
-CONFIG_MSDOS_PARTITION=y
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+# CONFIG_MSDOS_PARTITION is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
#
# Native Language Support
@@ -464,15 +512,16 @@ CONFIG_MSDOS_PARTITION=y
#
# Kernel hacking
#
+# CONFIG_PRINTK_TIME is not set
# CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=14
CONFIG_CROSSCOMPILE=y
CONFIG_CMDLINE=""
#
# Security options
#
-CONFIG_KEYS=y
-CONFIG_KEYS_DEBUG_PROC_KEYS=y
+# CONFIG_KEYS is not set
# CONFIG_SECURITY is not set
#
@@ -488,7 +537,6 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
# Library routines
#
# CONFIG_CRC_CCITT is not set
+CONFIG_CRC16=y
# CONFIG_CRC32 is not set
# CONFIG_LIBCRC32C is not set
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_IRQ_PROBE=y
diff --git a/arch/mips/configs/tb0226_defconfig b/arch/mips/configs/tb0226_defconfig
index c9d3f83caf0f..bf60a17de2b0 100644
--- a/arch/mips/configs/tb0226_defconfig
+++ b/arch/mips/configs/tb0226_defconfig
@@ -1,12 +1,9 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-rc2
-# Wed Jan 26 02:49:12 2005
+# Linux kernel version: 2.6.14-rc2
+# Thu Oct 20 22:27:10 2005
#
CONFIG_MIPS=y
-# CONFIG_64BIT is not set
-# CONFIG_64BIT is not set
-CONFIG_32BIT=y
#
# Code maturity level options
@@ -14,24 +11,29 @@ CONFIG_32BIT=y
CONFIG_EXPERIMENTAL=y
CONFIG_CLEAN_COMPILE=y
CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
#
# General setup
#
CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
# CONFIG_POSIX_MQUEUE is not set
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
# CONFIG_HOTPLUG is not set
CONFIG_KOBJECT_UEVENT=y
# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
CONFIG_EMBEDDED=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
@@ -41,6 +43,7 @@ CONFIG_CC_ALIGN_LABELS=0
CONFIG_CC_ALIGN_LOOPS=0
CONFIG_CC_ALIGN_JUMPS=0
# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
#
# Loadable module support
@@ -56,55 +59,87 @@ CONFIG_KMOD=y
#
# Machine selection
#
-# CONFIG_MACH_JAZZ is not set
-CONFIG_MACH_VR41XX=y
-# CONFIG_NEC_CMBVR4133 is not set
-# CONFIG_CASIO_E55 is not set
-# CONFIG_IBM_WORKPAD is not set
-CONFIG_TANBAC_TB0226=y
-# CONFIG_TANBAC_TB0229 is not set
-# CONFIG_VICTOR_MPC30X is not set
-# CONFIG_ZAO_CAPCELLA is not set
-# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_MIPS_PB1550 is not set
+# CONFIG_MIPS_PB1200 is not set
+# CONFIG_MIPS_DB1000 is not set
+# CONFIG_MIPS_DB1100 is not set
+# CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
+# CONFIG_MIPS_DB1200 is not set
+# CONFIG_MIPS_MIRAGE is not set
# CONFIG_MIPS_COBALT is not set
# CONFIG_MACH_DECSTATION is not set
# CONFIG_MIPS_EV64120 is not set
# CONFIG_MIPS_EV96100 is not set
# CONFIG_MIPS_IVR is not set
-# CONFIG_LASAT is not set
# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_LASAT is not set
# CONFIG_MIPS_ATLAS is not set
# CONFIG_MIPS_MALTA is not set
# CONFIG_MIPS_SEAD is not set
+# CONFIG_MIPS_SIM is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
# CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_G is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_JAGUAR_ATX is not set
-# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MIPS_XXS1500 is not set
+# CONFIG_PNX8550_V2PCI is not set
+# CONFIG_PNX8550_JBS is not set
# CONFIG_DDB5074 is not set
# CONFIG_DDB5476 is not set
# CONFIG_DDB5477 is not set
-# CONFIG_NEC_OSPREY is not set
+CONFIG_MACH_VR41XX=y
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_QEMU is not set
# CONFIG_SGI_IP22 is not set
-# CONFIG_SOC_AU1X00 is not set
-# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_BIGSUR is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_PTSWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CRHONE is not set
# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
# CONFIG_TOSHIBA_RBTX4927 is not set
+# CONFIG_TOSHIBA_RBTX4938 is not set
+# CONFIG_NEC_CMBVR4133 is not set
+# CONFIG_CASIO_E55 is not set
+# CONFIG_IBM_WORKPAD is not set
+CONFIG_TANBAC_TB022X=y
+CONFIG_TANBAC_TB0226=y
+# CONFIG_VICTOR_MPC30X is not set
+# CONFIG_ZAO_CAPCELLA is not set
+CONFIG_PCI_VR41XX=y
+# CONFIG_VRC4173 is not set
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_HAVE_DEC_LOCK=y
CONFIG_DMA_NONCOHERENT=y
CONFIG_DMA_NEED_PCI_MAP_STATE=y
+# CONFIG_CPU_BIG_ENDIAN is not set
CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
CONFIG_IRQ_CPU=y
CONFIG_MIPS_L1_CACHE_SHIFT=5
#
# CPU selection
#
-# CONFIG_CPU_MIPS32 is not set
-# CONFIG_CPU_MIPS64 is not set
+# CONFIG_CPU_MIPS32_R1 is not set
+# CONFIG_CPU_MIPS32_R2 is not set
+# CONFIG_CPU_MIPS64_R1 is not set
+# CONFIG_CPU_MIPS64_R2 is not set
# CONFIG_CPU_R3000 is not set
# CONFIG_CPU_TX39XX is not set
CONFIG_CPU_VR41XX=y
@@ -120,19 +155,44 @@ CONFIG_CPU_VR41XX=y
# CONFIG_CPU_RM7000 is not set
# CONFIG_CPU_RM9000 is not set
# CONFIG_CPU_SB1 is not set
+CONFIG_SYS_HAS_CPU_VR41XX=y
+CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
+CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y
+
+#
+# Kernel type
+#
+CONFIG_32BIT=y
+# CONFIG_64BIT is not set
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_MIPS_MT is not set
# CONFIG_CPU_ADVANCED is not set
CONFIG_CPU_HAS_SYNC=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_ARCH_FLATMEM_ENABLE=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_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
#
# Bus options (PCI, PCMCIA, EISA, ISA, TC)
#
CONFIG_HW_HAS_PCI=y
-# CONFIG_PCI is not set
+CONFIG_PCI=y
+# CONFIG_PCI_LEGACY_PROC is not set
CONFIG_MMU=y
#
@@ -141,12 +201,9 @@ CONFIG_MMU=y
# CONFIG_PCCARD is not set
#
-# PC-card bridges
-#
-
-#
# PCI Hotplug Support
#
+# CONFIG_HOTPLUG_PCI is not set
#
# Executable file formats
@@ -156,6 +213,87 @@ CONFIG_BINFMT_ELF=y
CONFIG_TRAD_SIGNALS=y
#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_ASK_IP_FIB_HASH=y
+# CONFIG_IP_FIB_TRIE is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IP_ROUTE_MULTIPATH=y
+# CONFIG_IP_ROUTE_MULTIPATH_CACHED is not set
+CONFIG_IP_ROUTE_VERBOSE=y
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+CONFIG_INET_TUNNEL=m
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+# CONFIG_IPV6 is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# 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_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_IEEE80211=m
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=m
+CONFIG_IEEE80211_CRYPT_CCMP=m
+CONFIG_IEEE80211_CRYPT_TKIP=m
+
+#
# Device Drivers
#
@@ -167,6 +305,11 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_FW_LOADER is not set
#
+# Connector - unified userspace <-> kernelspace linker
+#
+CONFIG_CONNECTOR=m
+
+#
# Memory Technology Devices (MTD)
#
# CONFIG_MTD is not set
@@ -183,19 +326,21 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
#
# Block devices
#
-# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
# CONFIG_BLK_DEV_COW_COMMON is not set
CONFIG_BLK_DEV_LOOP=m
# CONFIG_BLK_DEV_CRYPTOLOOP is not set
CONFIG_BLK_DEV_NBD=m
+# CONFIG_BLK_DEV_SX8 is not set
+# CONFIG_BLK_DEV_UB is not set
CONFIG_BLK_DEV_RAM=m
CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=4096
-CONFIG_INITRAMFS_SOURCE=""
# CONFIG_LBD is not set
-CONFIG_CDROM_PKTCDVD=m
-CONFIG_CDROM_PKTCDVD_BUFFERS=8
-# CONFIG_CDROM_PKTCDVD_WCACHE is not set
+# CONFIG_CDROM_PKTCDVD is not set
#
# IO Schedulers
@@ -209,33 +354,12 @@ CONFIG_ATA_OVER_ETH=m
#
# ATA/ATAPI/MFM/RLL support
#
-CONFIG_IDE=y
-CONFIG_BLK_DEV_IDE=y
-
-#
-# Please see Documentation/ide.txt for help/info on IDE drives
-#
-# CONFIG_BLK_DEV_IDE_SATA is not set
-CONFIG_BLK_DEV_IDEDISK=y
-CONFIG_IDEDISK_MULTI_MODE=y
-# CONFIG_BLK_DEV_IDECD is not set
-# CONFIG_BLK_DEV_IDETAPE is not set
-# CONFIG_BLK_DEV_IDEFLOPPY is not set
-CONFIG_BLK_DEV_IDESCSI=y
-# CONFIG_IDE_TASK_IOCTL is not set
-
-#
-# IDE chipset support/bugfixes
-#
-CONFIG_IDE_GENERIC=y
-# CONFIG_IDE_ARM is not set
-# CONFIG_BLK_DEV_IDEDMA is not set
-# CONFIG_IDEDMA_AUTO is not set
-# CONFIG_BLK_DEV_HD is not set
+# CONFIG_IDE is not set
#
# SCSI device support
#
+# CONFIG_RAID_ATTRS is not set
CONFIG_SCSI=y
CONFIG_SCSI_PROC_FS=y
@@ -245,15 +369,15 @@ CONFIG_SCSI_PROC_FS=y
CONFIG_BLK_DEV_SD=y
# CONFIG_CHR_DEV_ST is not set
# CONFIG_CHR_DEV_OSST is not set
-CONFIG_BLK_DEV_SR=y
-# CONFIG_BLK_DEV_SR_VENDOR is not set
-CONFIG_CHR_DEV_SG=y
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
#
# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
#
CONFIG_SCSI_MULTI_LUN=y
-CONFIG_SCSI_CONSTANTS=y
+# CONFIG_SCSI_CONSTANTS is not set
# CONFIG_SCSI_LOGGING is not set
#
@@ -262,11 +386,42 @@ CONFIG_SCSI_CONSTANTS=y
# CONFIG_SCSI_SPI_ATTRS is not set
# CONFIG_SCSI_FC_ATTRS is not set
# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_ATTRS is not set
#
# SCSI low-level drivers
#
+# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_ACARD is not set
+# CONFIG_SCSI_AACRAID is not set
+# CONFIG_SCSI_AIC7XXX is not set
+# CONFIG_SCSI_AIC7XXX_OLD is not set
+# CONFIG_SCSI_AIC79XX is not set
+# CONFIG_SCSI_DPT_I2O is not set
+# CONFIG_MEGARAID_NEWGEN is not set
+# CONFIG_MEGARAID_LEGACY is not set
# CONFIG_SCSI_SATA is not set
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+# CONFIG_SCSI_IPS is not set
+# CONFIG_SCSI_INITIO is not set
+# CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_SYM53C8XX_2 is not set
+# CONFIG_SCSI_IPR is not set
+# CONFIG_SCSI_QLOGIC_FC is not set
+# CONFIG_SCSI_QLOGIC_1280 is not set
+CONFIG_SCSI_QLA2XXX=y
+# CONFIG_SCSI_QLA21XX is not set
+# CONFIG_SCSI_QLA22XX is not set
+# CONFIG_SCSI_QLA2300 is not set
+# CONFIG_SCSI_QLA2322 is not set
+# CONFIG_SCSI_QLA6312 is not set
+# CONFIG_SCSI_QLA24XX is not set
+# CONFIG_SCSI_LPFC is not set
+# CONFIG_SCSI_DC395x is not set
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_NSP32 is not set
# CONFIG_SCSI_DEBUG is not set
#
@@ -277,131 +432,132 @@ CONFIG_SCSI_CONSTANTS=y
#
# Fusion MPT device support
#
+# CONFIG_FUSION is not set
+# CONFIG_FUSION_SPI is not set
+# CONFIG_FUSION_FC is not set
#
# IEEE 1394 (FireWire) support
#
+# CONFIG_IEEE1394 is not set
#
# I2O device support
#
+# CONFIG_I2O is not set
#
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
+# Network device support
#
-CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
-CONFIG_NETLINK_DEV=m
-CONFIG_UNIX=y
-# CONFIG_NET_KEY is not set
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-CONFIG_IP_ADVANCED_ROUTER=y
-CONFIG_IP_MULTIPLE_TABLES=y
-CONFIG_IP_ROUTE_MULTIPATH=y
-CONFIG_IP_ROUTE_VERBOSE=y
-CONFIG_IP_PNP=y
-# CONFIG_IP_PNP_DHCP is not set
-CONFIG_IP_PNP_BOOTP=y
-# CONFIG_IP_PNP_RARP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_IP_MROUTE is not set
-# CONFIG_ARPD is not set
-CONFIG_SYN_COOKIES=y
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-CONFIG_INET_TUNNEL=m
-CONFIG_IP_TCPDIAG=m
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-# CONFIG_IPV6 is not set
-# CONFIG_NETFILTER is not set
-CONFIG_XFRM=y
-CONFIG_XFRM_USER=m
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
#
-# SCTP Configuration (EXPERIMENTAL)
+# ARCnet devices
#
-# CONFIG_IP_SCTP 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_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
+# CONFIG_ARCNET is not set
#
-# QoS and/or fair queueing
+# PHY device support
#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
+CONFIG_PHYLIB=m
+CONFIG_PHYCONTROL=y
#
-# Network testing
+# MII PHY device drivers
#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
-CONFIG_NETDEVICES=y
-# CONFIG_DUMMY is not set
-# CONFIG_BONDING is not set
-# CONFIG_EQUALIZER is not set
-# CONFIG_TUN is not set
-# CONFIG_ETHERTAP is not set
+CONFIG_MARVELL_PHY=m
+CONFIG_DAVICOM_PHY=m
+CONFIG_QSEMI_PHY=m
+CONFIG_LXT_PHY=m
+CONFIG_CICADA_PHY=m
#
# Ethernet (10 or 100Mbit)
#
CONFIG_NET_ETHERNET=y
-# CONFIG_MII is not set
+CONFIG_MII=y
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_NET_VENDOR_3COM is not set
+
+#
+# Tulip family network device support
+#
+# CONFIG_NET_TULIP is not set
+# CONFIG_HP100 is not set
+CONFIG_NET_PCI=y
+# CONFIG_PCNET32 is not set
+# CONFIG_AMD8111_ETH is not set
+# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_B44 is not set
+# CONFIG_FORCEDETH is not set
+# CONFIG_DGRS is not set
+CONFIG_EEPRO100=y
+# CONFIG_E100 is not set
+# CONFIG_FEALNX is not set
+# CONFIG_NATSEMI is not set
+# CONFIG_NE2K_PCI is not set
+# CONFIG_8139CP is not set
+# CONFIG_8139TOO is not set
+# CONFIG_SIS900 is not set
+# CONFIG_EPIC100 is not set
+# CONFIG_SUNDANCE is not set
+# CONFIG_TLAN is not set
+# CONFIG_VIA_RHINE is not set
+# CONFIG_LAN_SAA9730 is not set
#
# Ethernet (1000 Mbit)
#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_VIA_VELOCITY is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
#
# Ethernet (10000 Mbit)
#
+# CONFIG_CHELSIO_T1 is not set
+# CONFIG_IXGB is not set
+# CONFIG_S2IO is not set
#
# Token Ring devices
#
+# CONFIG_TR is not set
#
# Wireless LAN (non-hamradio)
#
# CONFIG_NET_RADIO is not set
+# CONFIG_IPW2200 is not set
#
# Wan interfaces
#
# CONFIG_WAN is not set
-CONFIG_PPP=m
-CONFIG_PPP_MULTILINK=y
-# CONFIG_PPP_FILTER is not set
-CONFIG_PPP_ASYNC=m
-CONFIG_PPP_SYNC_TTY=m
-CONFIG_PPP_DEFLATE=m
-CONFIG_PPP_BSDCOMP=m
-CONFIG_PPPOE=m
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PPP is not set
# CONFIG_SLIP is not set
+# CONFIG_NET_FC is not set
# CONFIG_SHAPER is not set
# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
#
# ISDN subsystem
@@ -421,28 +577,13 @@ CONFIG_INPUT=y
#
# Userland interfaces
#
-CONFIG_INPUT_MOUSEDEV=y
-CONFIG_INPUT_MOUSEDEV_PSAUX=y
-CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_MOUSEDEV is not set
# CONFIG_INPUT_JOYDEV is not set
# CONFIG_INPUT_TSDEV is not set
# CONFIG_INPUT_EVDEV is not set
# CONFIG_INPUT_EVBUG is not set
#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=y
-CONFIG_SERIO_I8042=y
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_LIBPS2 is not set
-CONFIG_SERIO_RAW=m
-
-#
# Input Device Drivers
#
# CONFIG_INPUT_KEYBOARD is not set
@@ -452,6 +593,12 @@ CONFIG_SERIO_RAW=m
# CONFIG_INPUT_MISC is not set
#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
# Character devices
#
CONFIG_VT=y
@@ -462,16 +609,16 @@ CONFIG_HW_CONSOLE=y
#
# Serial drivers
#
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_NR_UARTS=4
-# CONFIG_SERIAL_8250_EXTENDED is not set
+# CONFIG_SERIAL_8250 is not set
#
# Non-8250 serial port support
#
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_SERIAL_VR41XX=y
+CONFIG_SERIAL_VR41XX_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
CONFIG_UNIX98_PTYS=y
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
@@ -489,14 +636,22 @@ CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_GEN_RTC is not set
# CONFIG_DTLK is not set
# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+# CONFIG_TANBAC_TB0219 is not set
#
# Ftape, the floppy tape device driver
#
# CONFIG_DRM is not set
+CONFIG_GPIO_VR41XX=y
# CONFIG_RAW_DRIVER is not set
#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+
+#
# I2C support
#
# CONFIG_I2C is not set
@@ -507,10 +662,20 @@ CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_W1 is not set
#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
+#
# Misc devices
#
#
+# Multimedia Capabilities Port drivers
+#
+
+#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
@@ -523,48 +688,147 @@ CONFIG_LEGACY_PTY_COUNT=256
#
# Graphics support
#
-CONFIG_FB=y
-# CONFIG_FB_MODE_HELPERS is not set
-# CONFIG_FB_TILEBLITTING is not set
-# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB is not set
#
# Console display driver support
#
# CONFIG_VGA_CONSOLE is not set
CONFIG_DUMMY_CONSOLE=y
-# CONFIG_FRAMEBUFFER_CONSOLE is not set
#
-# Logo configuration
+# Sound
#
-# CONFIG_LOGO is not set
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+# CONFIG_SOUND is not set
#
-# Sound
+# USB support
#
-CONFIG_SOUND=y
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
#
-# Advanced Linux Sound Architecture
+# Miscellaneous USB options
#
-# CONFIG_SND is not set
+CONFIG_USB_DEVICEFS=y
+# CONFIG_USB_BANDWIDTH is not set
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_OTG is not set
#
-# Open Sound System
+# USB Host Controller Drivers
#
-# CONFIG_SOUND_PRIME is not set
+CONFIG_USB_EHCI_HCD=y
+# CONFIG_USB_EHCI_SPLIT_ISO is not set
+# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
+# CONFIG_USB_ISP116X_HCD is not set
+CONFIG_USB_OHCI_HCD=y
+# CONFIG_USB_OHCI_BIG_ENDIAN is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+# CONFIG_USB_UHCI_HCD is not set
+# CONFIG_USB_SL811_HCD is not set
#
-# USB support
+# USB Device Class drivers
#
-# CONFIG_USB_ARCH_HAS_HCD is not set
-# CONFIG_USB_ARCH_HAS_OHCI is not set
+# CONFIG_USB_BLUETOOTH_TTY is not set
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
#
# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
#
+CONFIG_USB_STORAGE=m
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+
+#
+# USB Input Devices
+#
+# CONFIG_USB_HID is not set
+
+#
+# USB HID Boot Protocol drivers
+#
+# CONFIG_USB_KBD is not set
+# CONFIG_USB_MOUSE is not set
+# CONFIG_USB_AIPTEK is not set
+# CONFIG_USB_WACOM is not set
+# CONFIG_USB_ACECAD is not set
+# CONFIG_USB_KBTAB is not set
+# CONFIG_USB_POWERMATE is not set
+# CONFIG_USB_MTOUCH is not set
+# CONFIG_USB_ITMTOUCH is not set
+# CONFIG_USB_EGALAX is not set
+# CONFIG_USB_YEALINK is not set
+# CONFIG_USB_XPAD is not set
+# CONFIG_USB_ATI_REMOTE is not set
+# CONFIG_USB_KEYSPAN_REMOTE is not set
+# CONFIG_USB_APPLETOUCH is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+
+#
+# USB Multimedia devices
+#
+# CONFIG_USB_DABUSB is not set
+
+#
+# Video4Linux support is needed for USB Multimedia device support
+#
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET is not set
+CONFIG_USB_MON=y
+
+#
+# USB port drivers
+#
+
+#
+# USB Serial Converter support
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_AUERSWALD is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_PHIDGETKIT is not set
+# CONFIG_USB_PHIDGETSERVO is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_SISUSBVGA is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TEST is not set
+
+#
+# USB DSL modem support
+#
#
# USB Gadget Support
@@ -582,39 +846,41 @@ CONFIG_SOUND=y
# CONFIG_INFINIBAND is not set
#
+# SN Devices
+#
+
+#
# File systems
#
CONFIG_EXT2_FS=y
# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
# CONFIG_EXT3_FS is not set
# CONFIG_JBD 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_MINIX_FS is not set
CONFIG_ROMFS_FS=m
+CONFIG_INOTIFY=y
# CONFIG_QUOTA is not set
CONFIG_DNOTIFY=y
# CONFIG_AUTOFS_FS is not set
CONFIG_AUTOFS4_FS=y
+CONFIG_FUSE_FS=m
#
# CD-ROM/DVD Filesystems
#
-CONFIG_ISO9660_FS=y
-CONFIG_JOLIET=y
-CONFIG_ZISOFS=y
-CONFIG_ZISOFS_FS=y
+# CONFIG_ISO9660_FS is not set
# CONFIG_UDF_FS is not set
#
# DOS/FAT/NT Filesystems
#
-CONFIG_FAT_FS=m
-CONFIG_MSDOS_FS=m
-CONFIG_VFAT_FS=m
-CONFIG_FAT_DEFAULT_CODEPAGE=437
-CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
# CONFIG_NTFS_FS is not set
#
@@ -623,13 +889,10 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
-CONFIG_DEVPTS_FS_XATTR=y
-CONFIG_DEVPTS_FS_SECURITY=y
CONFIG_TMPFS=y
-# CONFIG_TMPFS_XATTR is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
+CONFIG_RELAYFS_FS=m
#
# Miscellaneous filesystems
@@ -653,16 +916,19 @@ CONFIG_CRAMFS=m
#
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
# CONFIG_NFS_V4 is not set
# CONFIG_NFS_DIRECTIO is not set
CONFIG_NFSD=m
CONFIG_NFSD_V3=y
+# CONFIG_NFSD_V3_ACL is not set
# CONFIG_NFSD_V4 is not set
# CONFIG_NFSD_TCP is not set
CONFIG_ROOT_NFS=y
CONFIG_LOCKD=y
CONFIG_LOCKD_V4=y
CONFIG_EXPORTFS=m
+CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
@@ -673,6 +939,7 @@ CONFIG_SMB_NLS_REMOTE="cp932"
# CONFIG_NCP_FS is not set
# CONFIG_CODA_FS is not set
# CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
#
# Partition Types
@@ -732,9 +999,11 @@ CONFIG_NLS_ISO8859_1=m
#
# Kernel hacking
#
+# CONFIG_PRINTK_TIME is not set
# CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=14
CONFIG_CROSSCOMPILE=y
-CONFIG_CMDLINE=""
+CONFIG_CMDLINE="mem=32M console=ttyVR0,115200"
#
# Security options
@@ -746,7 +1015,31 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
#
# Cryptographic options
#
-# CONFIG_CRYPTO is not set
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_AES=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_CRC32C=m
+# CONFIG_CRYPTO_TEST is not set
#
# Hardware crypto devices
@@ -756,9 +1049,8 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
# Library routines
#
CONFIG_CRC_CCITT=m
-# CONFIG_CRC32 is not set
-# CONFIG_LIBCRC32C is not set
-CONFIG_ZLIB_INFLATE=y
+CONFIG_CRC16=m
+CONFIG_CRC32=m
+CONFIG_LIBCRC32C=m
+CONFIG_ZLIB_INFLATE=m
CONFIG_ZLIB_DEFLATE=m
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_IRQ_PROBE=y
diff --git a/arch/mips/configs/tb0229_defconfig b/arch/mips/configs/tb0229_defconfig
index 2cb669188aa9..ac8b64e87b8a 100644
--- a/arch/mips/configs/tb0229_defconfig
+++ b/arch/mips/configs/tb0229_defconfig
@@ -1,12 +1,9 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-rc2
-# Wed Jan 26 02:49:12 2005
+# Linux kernel version: 2.6.14-rc2
+# Thu Oct 20 22:27:13 2005
#
CONFIG_MIPS=y
-# CONFIG_64BIT is not set
-# CONFIG_64BIT is not set
-CONFIG_32BIT=y
#
# Code maturity level options
@@ -14,24 +11,29 @@ CONFIG_32BIT=y
CONFIG_EXPERIMENTAL=y
CONFIG_CLEAN_COMPILE=y
CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
#
# General setup
#
CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
# CONFIG_POSIX_MQUEUE is not set
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_HOTPLUG is not set
+CONFIG_HOTPLUG=y
CONFIG_KOBJECT_UEVENT=y
# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
CONFIG_EMBEDDED=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
@@ -41,6 +43,7 @@ CONFIG_CC_ALIGN_LABELS=0
CONFIG_CC_ALIGN_LOOPS=0
CONFIG_CC_ALIGN_JUMPS=0
# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
#
# Loadable module support
@@ -56,58 +59,87 @@ CONFIG_KMOD=y
#
# Machine selection
#
-# CONFIG_MACH_JAZZ is not set
-CONFIG_MACH_VR41XX=y
-# CONFIG_NEC_CMBVR4133 is not set
-# CONFIG_CASIO_E55 is not set
-# CONFIG_IBM_WORKPAD is not set
-# CONFIG_TANBAC_TB0226 is not set
-CONFIG_TANBAC_TB0229=y
-CONFIG_TANBAC_TB0219=y
-# CONFIG_VICTOR_MPC30X is not set
-# CONFIG_ZAO_CAPCELLA is not set
-CONFIG_PCI_VR41XX=y
-# CONFIG_VRC4173 is not set
-# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_MIPS_PB1550 is not set
+# CONFIG_MIPS_PB1200 is not set
+# CONFIG_MIPS_DB1000 is not set
+# CONFIG_MIPS_DB1100 is not set
+# CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
+# CONFIG_MIPS_DB1200 is not set
+# CONFIG_MIPS_MIRAGE is not set
# CONFIG_MIPS_COBALT is not set
# CONFIG_MACH_DECSTATION is not set
# CONFIG_MIPS_EV64120 is not set
# CONFIG_MIPS_EV96100 is not set
# CONFIG_MIPS_IVR is not set
-# CONFIG_LASAT is not set
# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_LASAT is not set
# CONFIG_MIPS_ATLAS is not set
# CONFIG_MIPS_MALTA is not set
# CONFIG_MIPS_SEAD is not set
+# CONFIG_MIPS_SIM is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
# CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_G is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_JAGUAR_ATX is not set
-# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MIPS_XXS1500 is not set
+# CONFIG_PNX8550_V2PCI is not set
+# CONFIG_PNX8550_JBS is not set
# CONFIG_DDB5074 is not set
# CONFIG_DDB5476 is not set
# CONFIG_DDB5477 is not set
-# CONFIG_NEC_OSPREY is not set
+CONFIG_MACH_VR41XX=y
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_QEMU is not set
# CONFIG_SGI_IP22 is not set
-# CONFIG_SOC_AU1X00 is not set
-# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_BIGSUR is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_PTSWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CRHONE is not set
# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
# CONFIG_TOSHIBA_RBTX4927 is not set
+# CONFIG_TOSHIBA_RBTX4938 is not set
+# CONFIG_NEC_CMBVR4133 is not set
+# CONFIG_CASIO_E55 is not set
+# CONFIG_IBM_WORKPAD is not set
+CONFIG_TANBAC_TB022X=y
+# CONFIG_TANBAC_TB0226 is not set
+# CONFIG_VICTOR_MPC30X is not set
+# CONFIG_ZAO_CAPCELLA is not set
+CONFIG_PCI_VR41XX=y
+# CONFIG_VRC4173 is not set
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_HAVE_DEC_LOCK=y
CONFIG_DMA_NONCOHERENT=y
CONFIG_DMA_NEED_PCI_MAP_STATE=y
+# CONFIG_CPU_BIG_ENDIAN is not set
CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
CONFIG_IRQ_CPU=y
CONFIG_MIPS_L1_CACHE_SHIFT=5
#
# CPU selection
#
-# CONFIG_CPU_MIPS32 is not set
-# CONFIG_CPU_MIPS64 is not set
+# CONFIG_CPU_MIPS32_R1 is not set
+# CONFIG_CPU_MIPS32_R2 is not set
+# CONFIG_CPU_MIPS64_R1 is not set
+# CONFIG_CPU_MIPS64_R2 is not set
# CONFIG_CPU_R3000 is not set
# CONFIG_CPU_TX39XX is not set
CONFIG_CPU_VR41XX=y
@@ -123,12 +155,36 @@ CONFIG_CPU_VR41XX=y
# CONFIG_CPU_RM7000 is not set
# CONFIG_CPU_RM9000 is not set
# CONFIG_CPU_SB1 is not set
+CONFIG_SYS_HAS_CPU_VR41XX=y
+CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
+CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y
+
+#
+# Kernel type
+#
+CONFIG_32BIT=y
+# CONFIG_64BIT is not set
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_MIPS_MT is not set
# CONFIG_CPU_ADVANCED is not set
CONFIG_CPU_HAS_SYNC=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_ARCH_FLATMEM_ENABLE=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_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
#
@@ -136,8 +192,7 @@ CONFIG_CPU_HAS_SYNC=y
#
CONFIG_HW_HAS_PCI=y
CONFIG_PCI=y
-CONFIG_PCI_LEGACY_PROC=y
-CONFIG_PCI_NAMES=y
+# CONFIG_PCI_LEGACY_PROC is not set
CONFIG_MMU=y
#
@@ -146,10 +201,6 @@ CONFIG_MMU=y
# CONFIG_PCCARD is not set
#
-# PC-card bridges
-#
-
-#
# PCI Hotplug Support
#
# CONFIG_HOTPLUG_PCI is not set
@@ -162,6 +213,88 @@ CONFIG_BINFMT_ELF=y
CONFIG_TRAD_SIGNALS=y
#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_ASK_IP_FIB_HASH=y
+# CONFIG_IP_FIB_TRIE is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IP_ROUTE_MULTIPATH=y
+# CONFIG_IP_ROUTE_MULTIPATH_CACHED is not set
+CONFIG_IP_ROUTE_VERBOSE=y
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+CONFIG_NET_IPIP=m
+CONFIG_NET_IPGRE=m
+# CONFIG_NET_IPGRE_BROADCAST is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+CONFIG_INET_TUNNEL=m
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+# CONFIG_IPV6 is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# 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_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_IEEE80211=m
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=m
+CONFIG_IEEE80211_CRYPT_CCMP=m
+CONFIG_IEEE80211_CRYPT_TKIP=m
+
+#
# Device Drivers
#
@@ -170,7 +303,12 @@ CONFIG_TRAD_SIGNALS=y
#
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
+CONFIG_FW_LOADER=m
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+CONFIG_CONNECTOR=m
#
# Memory Technology Devices (MTD)
@@ -189,7 +327,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
#
# Block devices
#
-# CONFIG_BLK_DEV_FD is not set
# CONFIG_BLK_CPQ_DA is not set
# CONFIG_BLK_CPQ_CISS_DA is not set
# CONFIG_BLK_DEV_DAC960 is not set
@@ -199,11 +336,11 @@ CONFIG_BLK_DEV_LOOP=m
# CONFIG_BLK_DEV_CRYPTOLOOP is not set
CONFIG_BLK_DEV_NBD=m
# CONFIG_BLK_DEV_SX8 is not set
+# CONFIG_BLK_DEV_UB is not set
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=4096
# CONFIG_BLK_DEV_INITRD is not set
-CONFIG_INITRAMFS_SOURCE=""
# CONFIG_LBD is not set
CONFIG_CDROM_PKTCDVD=m
CONFIG_CDROM_PKTCDVD_BUFFERS=8
@@ -226,6 +363,7 @@ CONFIG_ATA_OVER_ETH=m
#
# SCSI device support
#
+# CONFIG_RAID_ATTRS is not set
# CONFIG_SCSI is not set
#
@@ -236,6 +374,7 @@ CONFIG_ATA_OVER_ETH=m
#
# Fusion MPT device support
#
+# CONFIG_FUSION is not set
#
# IEEE 1394 (FireWire) support
@@ -248,83 +387,13 @@ CONFIG_ATA_OVER_ETH=m
# CONFIG_I2O is not set
#
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
-CONFIG_NETLINK_DEV=m
-CONFIG_UNIX=y
-# CONFIG_NET_KEY is not set
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-CONFIG_IP_ADVANCED_ROUTER=y
-CONFIG_IP_MULTIPLE_TABLES=y
-CONFIG_IP_ROUTE_MULTIPATH=y
-CONFIG_IP_ROUTE_VERBOSE=y
-CONFIG_IP_PNP=y
-# CONFIG_IP_PNP_DHCP is not set
-CONFIG_IP_PNP_BOOTP=y
-# CONFIG_IP_PNP_RARP is not set
-CONFIG_NET_IPIP=m
-CONFIG_NET_IPGRE=m
-# CONFIG_NET_IPGRE_BROADCAST is not set
-# CONFIG_IP_MROUTE is not set
-# CONFIG_ARPD is not set
-CONFIG_SYN_COOKIES=y
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-CONFIG_INET_TUNNEL=m
-CONFIG_IP_TCPDIAG=m
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-# CONFIG_IPV6 is not set
-# CONFIG_NETFILTER is not set
-CONFIG_XFRM=y
-CONFIG_XFRM_USER=m
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP 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_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
-
-#
-# Network testing
+# Network device support
#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
CONFIG_NETDEVICES=y
CONFIG_DUMMY=m
# CONFIG_BONDING is not set
# CONFIG_EQUALIZER is not set
# CONFIG_TUN is not set
-# CONFIG_ETHERTAP is not set
#
# ARCnet devices
@@ -332,6 +401,21 @@ CONFIG_DUMMY=m
# CONFIG_ARCNET is not set
#
+# PHY device support
+#
+CONFIG_PHYLIB=m
+CONFIG_PHYCONTROL=y
+
+#
+# MII PHY device drivers
+#
+CONFIG_MARVELL_PHY=m
+CONFIG_DAVICOM_PHY=m
+CONFIG_QSEMI_PHY=m
+CONFIG_LXT_PHY=m
+CONFIG_CICADA_PHY=m
+
+#
# Ethernet (10 or 100Mbit)
#
CONFIG_NET_ETHERNET=y
@@ -346,7 +430,7 @@ CONFIG_MII=y
# CONFIG_NET_TULIP is not set
# CONFIG_HP100 is not set
CONFIG_NET_PCI=y
-CONFIG_PCNET32=y
+# CONFIG_PCNET32 is not set
# CONFIG_AMD8111_ETH is not set
# CONFIG_ADAPTEC_STARFIRE is not set
# CONFIG_B44 is not set
@@ -358,7 +442,11 @@ CONFIG_EEPRO100=y
# CONFIG_NATSEMI is not set
# CONFIG_NE2K_PCI is not set
# CONFIG_8139CP is not set
-# CONFIG_8139TOO is not set
+CONFIG_8139TOO=y
+CONFIG_8139TOO_PIO=y
+# CONFIG_8139TOO_TUNE_TWISTER is not set
+# CONFIG_8139TOO_8129 is not set
+# CONFIG_8139_OLD_RX_RESET is not set
# CONFIG_SIS900 is not set
# CONFIG_EPIC100 is not set
# CONFIG_SUNDANCE is not set
@@ -375,14 +463,19 @@ CONFIG_EEPRO100=y
# CONFIG_NS83820 is not set
# CONFIG_HAMACHI is not set
# CONFIG_YELLOWFIN is not set
-# CONFIG_R8169 is not set
+CONFIG_R8169=y
+# CONFIG_R8169_NAPI is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
# CONFIG_SK98LIN is not set
# CONFIG_VIA_VELOCITY is not set
# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
#
# Ethernet (10000 Mbit)
#
+# CONFIG_CHELSIO_T1 is not set
# CONFIG_IXGB is not set
# CONFIG_S2IO is not set
@@ -395,6 +488,8 @@ CONFIG_EEPRO100=y
# Wireless LAN (non-hamradio)
#
# CONFIG_NET_RADIO is not set
+# CONFIG_IPW_DEBUG is not set
+CONFIG_IPW2200=m
#
# Wan interfaces
@@ -416,6 +511,8 @@ CONFIG_SLIP_SMART=y
CONFIG_SLIP_MODE_SLIP6=y
# CONFIG_SHAPER is not set
# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
#
# ISDN subsystem
@@ -435,29 +532,13 @@ CONFIG_INPUT=y
#
# Userland interfaces
#
-CONFIG_INPUT_MOUSEDEV=y
-CONFIG_INPUT_MOUSEDEV_PSAUX=y
-CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_MOUSEDEV is not set
# CONFIG_INPUT_JOYDEV is not set
# CONFIG_INPUT_TSDEV is not set
# CONFIG_INPUT_EVDEV is not set
# CONFIG_INPUT_EVBUG is not set
#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=y
-CONFIG_SERIO_I8042=y
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_PCIPS2 is not set
-# CONFIG_SERIO_LIBPS2 is not set
-CONFIG_SERIO_RAW=m
-
-#
# Input Device Drivers
#
# CONFIG_INPUT_KEYBOARD is not set
@@ -467,6 +548,12 @@ CONFIG_SERIO_RAW=m
# CONFIG_INPUT_MISC is not set
#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
# Character devices
#
CONFIG_VT=y
@@ -477,16 +564,16 @@ CONFIG_HW_CONSOLE=y
#
# Serial drivers
#
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_NR_UARTS=4
-# CONFIG_SERIAL_8250_EXTENDED is not set
+# CONFIG_SERIAL_8250 is not set
#
# Non-8250 serial port support
#
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_SERIAL_VR41XX=y
+CONFIG_SERIAL_VR41XX_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
CONFIG_UNIX98_PTYS=y
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
@@ -505,14 +592,21 @@ CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_DTLK is not set
# CONFIG_R3964 is not set
# CONFIG_APPLICOM is not set
+CONFIG_TANBAC_TB0219=y
#
# Ftape, the floppy tape device driver
#
# CONFIG_DRM is not set
+CONFIG_GPIO_VR41XX=y
# CONFIG_RAW_DRIVER is not set
#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+
+#
# I2C support
#
# CONFIG_I2C is not set
@@ -523,10 +617,20 @@ CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_W1 is not set
#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
+#
# Misc devices
#
#
+# Multimedia Capabilities Port drivers
+#
+
+#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
@@ -546,7 +650,6 @@ CONFIG_LEGACY_PTY_COUNT=256
#
# CONFIG_VGA_CONSOLE is not set
CONFIG_DUMMY_CONSOLE=y
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Sound
@@ -556,13 +659,122 @@ CONFIG_DUMMY_CONSOLE=y
#
# USB support
#
-# CONFIG_USB is not set
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB=m
+# CONFIG_USB_DEBUG is not set
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+# CONFIG_USB_BANDWIDTH is not set
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_OTG is not set
+
+#
+# USB Host Controller Drivers
+#
+CONFIG_USB_EHCI_HCD=m
+# CONFIG_USB_EHCI_SPLIT_ISO is not set
+# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
+# CONFIG_USB_ISP116X_HCD is not set
+CONFIG_USB_OHCI_HCD=m
+# CONFIG_USB_OHCI_BIG_ENDIAN is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+# CONFIG_USB_UHCI_HCD is not set
+# CONFIG_USB_SL811_HCD is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_BLUETOOTH_TTY is not set
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
#
# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
#
+# CONFIG_USB_STORAGE is not set
+
+#
+# USB Input Devices
+#
+# CONFIG_USB_HID is not set
+
+#
+# USB HID Boot Protocol drivers
+#
+# CONFIG_USB_KBD is not set
+# CONFIG_USB_MOUSE is not set
+# CONFIG_USB_AIPTEK is not set
+# CONFIG_USB_WACOM is not set
+# CONFIG_USB_ACECAD is not set
+# CONFIG_USB_KBTAB is not set
+# CONFIG_USB_POWERMATE is not set
+# CONFIG_USB_MTOUCH is not set
+# CONFIG_USB_ITMTOUCH is not set
+# CONFIG_USB_EGALAX is not set
+# CONFIG_USB_YEALINK is not set
+# CONFIG_USB_XPAD is not set
+# CONFIG_USB_ATI_REMOTE is not set
+# CONFIG_USB_KEYSPAN_REMOTE is not set
+# CONFIG_USB_APPLETOUCH is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+
+#
+# USB Multimedia devices
+#
+# CONFIG_USB_DABUSB is not set
+
+#
+# Video4Linux support is needed for USB Multimedia device support
+#
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET is not set
+CONFIG_USB_MON=y
+
+#
+# USB port drivers
+#
+
+#
+# USB Serial Converter support
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_AUERSWALD is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_PHIDGETKIT is not set
+# CONFIG_USB_PHIDGETSERVO is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_SISUSBVGA is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TEST is not set
+
+#
+# USB DSL modem support
+#
#
# USB Gadget Support
@@ -580,10 +792,15 @@ CONFIG_USB_ARCH_HAS_OHCI=y
# CONFIG_INFINIBAND is not set
#
+# SN Devices
+#
+
+#
# File systems
#
CONFIG_EXT2_FS=y
# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
CONFIG_EXT3_FS=m
CONFIG_EXT3_FS_XATTR=y
# CONFIG_EXT3_FS_POSIX_ACL is not set
@@ -597,18 +814,22 @@ CONFIG_JFS_FS=m
# CONFIG_JFS_SECURITY is not set
# CONFIG_JFS_DEBUG is not set
# CONFIG_JFS_STATISTICS is not set
+# CONFIG_FS_POSIX_ACL is not set
CONFIG_XFS_FS=y
-# CONFIG_XFS_RT is not set
+CONFIG_XFS_EXPORT=y
CONFIG_XFS_QUOTA=y
# CONFIG_XFS_SECURITY is not set
CONFIG_XFS_POSIX_ACL=y
+# CONFIG_XFS_RT is not set
# CONFIG_MINIX_FS is not set
CONFIG_ROMFS_FS=m
+CONFIG_INOTIFY=y
# CONFIG_QUOTA is not set
CONFIG_QUOTACTL=y
CONFIG_DNOTIFY=y
# CONFIG_AUTOFS_FS is not set
CONFIG_AUTOFS4_FS=y
+CONFIG_FUSE_FS=m
#
# CD-ROM/DVD Filesystems
@@ -635,13 +856,10 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
-CONFIG_DEVPTS_FS_XATTR=y
-CONFIG_DEVPTS_FS_SECURITY=y
CONFIG_TMPFS=y
-# CONFIG_TMPFS_XATTR is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
+CONFIG_RELAYFS_FS=m
#
# Miscellaneous filesystems
@@ -665,16 +883,19 @@ CONFIG_CRAMFS=m
#
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
# CONFIG_NFS_V4 is not set
# CONFIG_NFS_DIRECTIO is not set
CONFIG_NFSD=y
CONFIG_NFSD_V3=y
+# CONFIG_NFSD_V3_ACL is not set
# CONFIG_NFSD_V4 is not set
CONFIG_NFSD_TCP=y
CONFIG_ROOT_NFS=y
CONFIG_LOCKD=y
CONFIG_LOCKD_V4=y
CONFIG_EXPORTFS=y
+CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
@@ -685,6 +906,7 @@ CONFIG_SMB_NLS_REMOTE="cp932"
# CONFIG_NCP_FS is not set
# CONFIG_CODA_FS is not set
# CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
#
# Partition Types
@@ -744,9 +966,11 @@ CONFIG_NLS_ISO8859_1=m
#
# Kernel hacking
#
+# CONFIG_PRINTK_TIME is not set
# CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=14
CONFIG_CROSSCOMPILE=y
-CONFIG_CMDLINE="mem=64M console=ttyS0,38400 ip=bootp root=/dev/nfs"
+CONFIG_CMDLINE="mem=64M console=ttyVR0,115200 ip=any root=/dev/nfs"
#
# Security options
@@ -758,7 +982,31 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
#
# Cryptographic options
#
-# CONFIG_CRYPTO is not set
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_AES=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_CRC32C=m
+# CONFIG_CRYPTO_TEST is not set
#
# Hardware crypto devices
@@ -768,9 +1016,8 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
# Library routines
#
CONFIG_CRC_CCITT=m
+CONFIG_CRC16=m
CONFIG_CRC32=y
-# CONFIG_LIBCRC32C is not set
+CONFIG_LIBCRC32C=m
CONFIG_ZLIB_INFLATE=y
CONFIG_ZLIB_DEFLATE=m
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_IRQ_PROBE=y
diff --git a/arch/mips/configs/tb0287_defconfig b/arch/mips/configs/tb0287_defconfig
index 17b9f2f65ba0..95344832d66e 100644
--- a/arch/mips/configs/tb0287_defconfig
+++ b/arch/mips/configs/tb0287_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.13-mm1
-# Thu Sep 1 22:58:34 2005
+# Linux kernel version: 2.6.14-rc5-mm1
+# Tue Oct 25 00:20:22 2005
#
CONFIG_MIPS=y
@@ -19,6 +19,7 @@ CONFIG_INIT_ENV_ARG_LIMIT=32
CONFIG_LOCALVERSION=""
CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
+CONFIG_SWAP_PREFETCH=y
CONFIG_SYSVIPC=y
# CONFIG_POSIX_MQUEUE is not set
# CONFIG_BSD_PROCESS_ACCT is not set
@@ -55,74 +56,91 @@ CONFIG_OBSOLETE_MODPARM=y
CONFIG_MODVERSIONS=y
CONFIG_MODULE_SRCVERSION_ALL=y
CONFIG_KMOD=y
-CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
-CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
-CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
-CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y
-
-#
-# Kernel type
-#
-CONFIG_32BIT=y
-# CONFIG_64BIT is not set
#
# Machine selection
#
-# CONFIG_MACH_JAZZ is not set
-CONFIG_MACH_VR41XX=y
-# CONFIG_NEC_CMBVR4133 is not set
-# CONFIG_CASIO_E55 is not set
-# CONFIG_IBM_WORKPAD is not set
-CONFIG_TANBAC_TB022X=y
-# CONFIG_TANBAC_TB0226 is not set
-CONFIG_TANBAC_TB0287=y
-# CONFIG_VICTOR_MPC30X is not set
-# CONFIG_ZAO_CAPCELLA is not set
-CONFIG_PCI_VR41XX=y
-# CONFIG_VRC4173 is not set
-# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_MIPS_PB1550 is not set
+# CONFIG_MIPS_PB1200 is not set
+# CONFIG_MIPS_DB1000 is not set
+# CONFIG_MIPS_DB1100 is not set
+# CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
+# CONFIG_MIPS_DB1200 is not set
+# CONFIG_MIPS_MIRAGE is not set
# CONFIG_MIPS_COBALT is not set
# CONFIG_MACH_DECSTATION is not set
# CONFIG_MIPS_EV64120 is not set
# CONFIG_MIPS_EV96100 is not set
# CONFIG_MIPS_IVR is not set
-# CONFIG_LASAT is not set
# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_LASAT is not set
# CONFIG_MIPS_ATLAS is not set
# CONFIG_MIPS_MALTA is not set
# CONFIG_MIPS_SEAD is not set
+# CONFIG_MIPS_SIM is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
# CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_G is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_JAGUAR_ATX is not set
-# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MIPS_XXS1500 is not set
+# CONFIG_PNX8550_V2PCI is not set
+# CONFIG_PNX8550_JBS is not set
# CONFIG_DDB5074 is not set
# CONFIG_DDB5476 is not set
# CONFIG_DDB5477 is not set
+CONFIG_MACH_VR41XX=y
+# CONFIG_PMC_YOSEMITE is not set
# CONFIG_QEMU is not set
# CONFIG_SGI_IP22 is not set
# CONFIG_SGI_IP27 is not set
# CONFIG_SGI_IP32 is not set
-# CONFIG_SOC_AU1X00 is not set
-# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_PTSWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CRHONE is not set
# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
# CONFIG_TOSHIBA_RBTX4927 is not set
+# CONFIG_TOSHIBA_RBTX4938 is not set
+# CONFIG_CASIO_E55 is not set
+# CONFIG_IBM_WORKPAD is not set
+# CONFIG_NEC_CMBVR4133 is not set
+CONFIG_TANBAC_TB022X=y
+# CONFIG_TANBAC_TB0226 is not set
+CONFIG_TANBAC_TB0287=y
+# CONFIG_VICTOR_MPC30X is not set
+# CONFIG_ZAO_CAPCELLA is not set
+CONFIG_PCI_VR41XX=y
+# CONFIG_VRC4173 is not set
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_HAVE_DEC_LOCK=y
CONFIG_DMA_NONCOHERENT=y
CONFIG_DMA_NEED_PCI_MAP_STATE=y
+# CONFIG_CPU_BIG_ENDIAN is not set
CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
CONFIG_IRQ_CPU=y
CONFIG_MIPS_L1_CACHE_SHIFT=5
#
# CPU selection
#
-# CONFIG_CPU_MIPS32 is not set
-# CONFIG_CPU_MIPS64 is not set
+# CONFIG_CPU_MIPS32_R1 is not set
+# CONFIG_CPU_MIPS32_R2 is not set
+# CONFIG_CPU_MIPS64_R1 is not set
+# CONFIG_CPU_MIPS64_R2 is not set
# CONFIG_CPU_R3000 is not set
# CONFIG_CPU_TX39XX is not set
CONFIG_CPU_VR41XX=y
@@ -138,12 +156,25 @@ CONFIG_CPU_VR41XX=y
# CONFIG_CPU_RM7000 is not set
# CONFIG_CPU_RM9000 is not set
# CONFIG_CPU_SB1 is not set
+CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
+CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y
+
+#
+# Kernel type
+#
+CONFIG_32BIT=y
+# CONFIG_64BIT is not set
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_MIPS_MT is not set
# CONFIG_CPU_ADVANCED is not set
CONFIG_CPU_HAS_SYNC=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_ARCH_FLATMEM_ENABLE=y
CONFIG_SELECT_MEMORY_MODEL=y
CONFIG_FLATMEM_MANUAL=y
@@ -152,6 +183,9 @@ CONFIG_FLATMEM_MANUAL=y
CONFIG_FLATMEM=y
CONFIG_FLAT_NODE_MEM_MAP=y
# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
#
@@ -262,7 +296,6 @@ CONFIG_TCP_CONG_HTCP=m
# Network testing
#
# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETFILTER_NETLINK is not set
# CONFIG_HAMRADIO is not set
# CONFIG_IRDA is not set
# CONFIG_BT is not set
@@ -280,6 +313,11 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_FW_LOADER is not set
#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+
+#
# Memory Technology Devices (MTD)
#
# CONFIG_MTD is not set
@@ -296,7 +334,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
#
# Block devices
#
-# CONFIG_BLK_DEV_FD is not set
# CONFIG_BLK_CPQ_DA is not set
# CONFIG_BLK_CPQ_CISS_DA is not set
# CONFIG_BLK_DEV_DAC960 is not set
@@ -312,6 +349,7 @@ CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=4096
# CONFIG_BLK_DEV_INITRD is not set
# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
# CONFIG_CDROM_PKTCDVD is not set
#
@@ -321,6 +359,11 @@ 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_ATA_OVER_ETH is not set
#
@@ -410,13 +453,20 @@ CONFIG_BLK_DEV_SD=y
# CONFIG_SCSI_SPI_ATTRS is not set
# CONFIG_SCSI_FC_ATTRS is not set
# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_ATTRS is not set
+
+#
+# SCSI Transport Layers
+#
+# CONFIG_SAS_CLASS is not set
#
# SCSI low-level drivers
#
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_SCSI_ARCMSR is not set
# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
# CONFIG_SCSI_3W_9XXX is not set
-# CONFIG_SCSI_ARCMSR is not set
# CONFIG_SCSI_ACARD is not set
# CONFIG_SCSI_AACRAID is not set
# CONFIG_SCSI_AIC7XXX is not set
@@ -425,12 +475,10 @@ CONFIG_BLK_DEV_SD=y
# CONFIG_SCSI_DPT_I2O is not set
# CONFIG_MEGARAID_NEWGEN is not set
# CONFIG_MEGARAID_LEGACY is not set
+# CONFIG_MEGARAID_SAS is not set
# CONFIG_SCSI_SATA is not set
-# CONFIG_SCSI_BUSLOGIC is not set
# CONFIG_SCSI_DMX3191D is not set
-# CONFIG_SCSI_EATA is not set
# CONFIG_SCSI_FUTURE_DOMAIN is not set
-# CONFIG_SCSI_GDTH is not set
# CONFIG_SCSI_IPS is not set
# CONFIG_SCSI_INITIO is not set
# CONFIG_SCSI_INIA100 is not set
@@ -462,6 +510,7 @@ CONFIG_SCSI_QLA2XXX=y
# CONFIG_FUSION is not set
# CONFIG_FUSION_SPI is not set
# CONFIG_FUSION_FC is not set
+# CONFIG_FUSION_SAS is not set
#
# IEEE 1394 (FireWire) support
@@ -529,6 +578,7 @@ CONFIG_NET_ETHERNET=y
CONFIG_MII=y
# CONFIG_HAPPYMEAL is not set
# CONFIG_SUNGEM is not set
+# CONFIG_CASSINI is not set
# CONFIG_NET_VENDOR_3COM is not set
#
@@ -572,6 +622,7 @@ CONFIG_R8169=y
# Wireless LAN (non-hamradio)
#
# CONFIG_NET_RADIO is not set
+# CONFIG_HOSTAP is not set
#
# Wan interfaces
@@ -682,6 +733,7 @@ CONFIG_GPIO_VR41XX=y
# TPM devices
#
# CONFIG_TCG_TPM is not set
+# CONFIG_TELCLOCK is not set
#
# I2C support
@@ -770,12 +822,15 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y
#
# USB Device Class drivers
#
-# CONFIG_USB_BLUETOOTH_TTY is not set
# CONFIG_USB_ACM is not set
# CONFIG_USB_PRINTER is not set
#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# may also be needed; see USB_STORAGE Help for more information
#
CONFIG_USB_STORAGE=m
# CONFIG_USB_STORAGE_DEBUG is not set
@@ -891,6 +946,11 @@ CONFIG_USB_MON=y
#
#
+# EDAC - error detection and reporting (RAS)
+#
+# CONFIG_EDAC is not set
+
+#
# Distributed Lock Manager
#
# CONFIG_DLM is not set
@@ -901,20 +961,22 @@ CONFIG_USB_MON=y
CONFIG_EXT2_FS=y
# CONFIG_EXT2_FS_XATTR is not set
# CONFIG_EXT2_FS_XIP is not set
-# CONFIG_EXT3_FS is not set
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_XATTR=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
+# CONFIG_EXT3_FS_SECURITY is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
# CONFIG_REISER4_FS is not set
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
# CONFIG_FS_POSIX_ACL is not set
-
-#
-# XFS support
-#
CONFIG_XFS_FS=y
-# CONFIG_XFS_RT is not set
CONFIG_XFS_QUOTA=y
# CONFIG_XFS_SECURITY is not set
CONFIG_XFS_POSIX_ACL=y
+# CONFIG_XFS_RT is not set
# CONFIG_OCFS2_FS is not set
# CONFIG_MINIX_FS is not set
CONFIG_ROMFS_FS=m
@@ -948,8 +1010,8 @@ CONFIG_SYSFS=y
CONFIG_TMPFS=y
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
-# CONFIG_CONFIGFS_FS is not set
# CONFIG_RELAYFS_FS is not set
+# CONFIG_CONFIGFS_FS is not set
#
# Miscellaneous filesystems
@@ -1004,6 +1066,11 @@ CONFIG_MSDOS_PARTITION=y
# CONFIG_NLS is not set
#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
# Kernel hacking
#
# CONFIG_PRINTK_TIME is not set
@@ -1036,6 +1103,3 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
CONFIG_CRC32=y
# CONFIG_LIBCRC32C is not set
CONFIG_ZLIB_INFLATE=m
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_IRQ_PROBE=y
-CONFIG_ISA_DMA_API=y
diff --git a/arch/mips/configs/workpad_defconfig b/arch/mips/configs/workpad_defconfig
index 16e07fca446f..ab13621ef3b9 100644
--- a/arch/mips/configs/workpad_defconfig
+++ b/arch/mips/configs/workpad_defconfig
@@ -1,12 +1,9 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-rc2
-# Wed Jan 26 02:49:12 2005
+# Linux kernel version: 2.6.14-rc2
+# Thu Oct 20 22:27:16 2005
#
CONFIG_MIPS=y
-# CONFIG_64BIT is not set
-# CONFIG_64BIT is not set
-CONFIG_32BIT=y
#
# Code maturity level options
@@ -14,24 +11,29 @@ CONFIG_32BIT=y
CONFIG_EXPERIMENTAL=y
CONFIG_CLEAN_COMPILE=y
CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
#
# General setup
#
CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
# CONFIG_POSIX_MQUEUE is not set
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_HOTPLUG is not set
+CONFIG_HOTPLUG=y
CONFIG_KOBJECT_UEVENT=y
# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
CONFIG_EMBEDDED=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
@@ -41,6 +43,7 @@ CONFIG_CC_ALIGN_LABELS=0
CONFIG_CC_ALIGN_LOOPS=0
CONFIG_CC_ALIGN_JUMPS=0
# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
#
# Loadable module support
@@ -56,56 +59,84 @@ CONFIG_KMOD=y
#
# Machine selection
#
-# CONFIG_MACH_JAZZ is not set
-CONFIG_MACH_VR41XX=y
-# CONFIG_NEC_CMBVR4133 is not set
-# CONFIG_CASIO_E55 is not set
-CONFIG_IBM_WORKPAD=y
-# CONFIG_TANBAC_TB0226 is not set
-# CONFIG_TANBAC_TB0229 is not set
-# CONFIG_VICTOR_MPC30X is not set
-# CONFIG_ZAO_CAPCELLA is not set
-CONFIG_VRC4171=y
-# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_MIPS_PB1550 is not set
+# CONFIG_MIPS_PB1200 is not set
+# CONFIG_MIPS_DB1000 is not set
+# CONFIG_MIPS_DB1100 is not set
+# CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
+# CONFIG_MIPS_DB1200 is not set
+# CONFIG_MIPS_MIRAGE is not set
# CONFIG_MIPS_COBALT is not set
# CONFIG_MACH_DECSTATION is not set
# CONFIG_MIPS_EV64120 is not set
# CONFIG_MIPS_EV96100 is not set
# CONFIG_MIPS_IVR is not set
-# CONFIG_LASAT is not set
# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_LASAT is not set
# CONFIG_MIPS_ATLAS is not set
# CONFIG_MIPS_MALTA is not set
# CONFIG_MIPS_SEAD is not set
+# CONFIG_MIPS_SIM is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
# CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_G is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_JAGUAR_ATX is not set
-# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MIPS_XXS1500 is not set
+# CONFIG_PNX8550_V2PCI is not set
+# CONFIG_PNX8550_JBS is not set
# CONFIG_DDB5074 is not set
# CONFIG_DDB5476 is not set
# CONFIG_DDB5477 is not set
-# CONFIG_NEC_OSPREY is not set
+CONFIG_MACH_VR41XX=y
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_QEMU is not set
# CONFIG_SGI_IP22 is not set
-# CONFIG_SOC_AU1X00 is not set
-# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_BIGSUR is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_PTSWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CRHONE is not set
# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
# CONFIG_TOSHIBA_RBTX4927 is not set
+# CONFIG_TOSHIBA_RBTX4938 is not set
+# CONFIG_NEC_CMBVR4133 is not set
+# CONFIG_CASIO_E55 is not set
+CONFIG_IBM_WORKPAD=y
+# CONFIG_TANBAC_TB022X is not set
+# CONFIG_VICTOR_MPC30X is not set
+# CONFIG_ZAO_CAPCELLA is not set
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_HAVE_DEC_LOCK=y
CONFIG_DMA_NONCOHERENT=y
CONFIG_DMA_NEED_PCI_MAP_STATE=y
+# CONFIG_CPU_BIG_ENDIAN is not set
CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
CONFIG_IRQ_CPU=y
CONFIG_MIPS_L1_CACHE_SHIFT=5
#
# CPU selection
#
-# CONFIG_CPU_MIPS32 is not set
-# CONFIG_CPU_MIPS64 is not set
+# CONFIG_CPU_MIPS32_R1 is not set
+# CONFIG_CPU_MIPS32_R2 is not set
+# CONFIG_CPU_MIPS64_R1 is not set
+# CONFIG_CPU_MIPS64_R2 is not set
# CONFIG_CPU_R3000 is not set
# CONFIG_CPU_TX39XX is not set
CONFIG_CPU_VR41XX=y
@@ -121,12 +152,36 @@ CONFIG_CPU_VR41XX=y
# CONFIG_CPU_RM7000 is not set
# CONFIG_CPU_RM9000 is not set
# CONFIG_CPU_SB1 is not set
+CONFIG_SYS_HAS_CPU_VR41XX=y
+CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
+CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y
+
+#
+# Kernel type
+#
+CONFIG_32BIT=y
+# CONFIG_64BIT is not set
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_MIPS_MT is not set
# CONFIG_CPU_ADVANCED is not set
CONFIG_CPU_HAS_SYNC=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_ARCH_FLATMEM_ENABLE=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_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
#
@@ -138,11 +193,17 @@ CONFIG_MMU=y
#
# PCCARD (PCMCIA/CardBus) support
#
-# CONFIG_PCCARD is not set
+CONFIG_PCCARD=y
+# CONFIG_PCMCIA_DEBUG is not set
+CONFIG_PCMCIA=y
+CONFIG_PCMCIA_LOAD_CIS=y
+CONFIG_PCMCIA_IOCTL=y
#
# PC-card bridges
#
+# CONFIG_I82365 is not set
+# CONFIG_TCIC is not set
CONFIG_PCMCIA_PROBE=y
#
@@ -157,6 +218,78 @@ CONFIG_BINFMT_ELF=y
CONFIG_TRAD_SIGNALS=y
#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+CONFIG_NET_KEY=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+# CONFIG_IP_PNP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+CONFIG_INET_TUNNEL=m
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+# CONFIG_IPV6 is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# 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_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_IEEE80211=m
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=m
+CONFIG_IEEE80211_CRYPT_CCMP=m
+CONFIG_IEEE80211_CRYPT_TKIP=m
+
+#
# Device Drivers
#
@@ -165,7 +298,12 @@ CONFIG_TRAD_SIGNALS=y
#
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
+CONFIG_FW_LOADER=y
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+CONFIG_CONNECTOR=m
#
# Memory Technology Devices (MTD)
@@ -185,18 +323,13 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
#
# Block devices
#
-# CONFIG_BLK_DEV_FD is not set
-# CONFIG_BLK_DEV_XD is not set
# CONFIG_BLK_DEV_COW_COMMON is not set
# CONFIG_BLK_DEV_LOOP is not set
# CONFIG_BLK_DEV_NBD is not set
# CONFIG_BLK_DEV_RAM is not set
CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_INITRAMFS_SOURCE=""
# CONFIG_LBD is not set
-CONFIG_CDROM_PKTCDVD=m
-CONFIG_CDROM_PKTCDVD_BUFFERS=8
-# CONFIG_CDROM_PKTCDVD_WCACHE is not set
+# CONFIG_CDROM_PKTCDVD is not set
#
# IO Schedulers
@@ -219,6 +352,7 @@ CONFIG_BLK_DEV_IDE=y
# CONFIG_BLK_DEV_IDE_SATA is not set
CONFIG_BLK_DEV_IDEDISK=y
# CONFIG_IDEDISK_MULTI_MODE is not set
+CONFIG_BLK_DEV_IDECS=m
# CONFIG_BLK_DEV_IDECD is not set
# CONFIG_BLK_DEV_IDETAPE is not set
# CONFIG_BLK_DEV_IDEFLOPPY is not set
@@ -237,6 +371,7 @@ CONFIG_IDE_GENERIC=y
#
# SCSI device support
#
+# CONFIG_RAID_ATTRS is not set
# CONFIG_SCSI is not set
#
@@ -252,6 +387,7 @@ CONFIG_IDE_GENERIC=y
#
# Fusion MPT device support
#
+# CONFIG_FUSION is not set
#
# IEEE 1394 (FireWire) support
@@ -262,76 +398,13 @@ CONFIG_IDE_GENERIC=y
#
#
-# Networking support
-#
-CONFIG_NET=y
-
+# Network device support
#
-# Networking options
-#
-CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
-CONFIG_NETLINK_DEV=y
-CONFIG_UNIX=y
-CONFIG_NET_KEY=y
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-# CONFIG_IP_ADVANCED_ROUTER is not set
-# CONFIG_IP_PNP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_IP_MROUTE is not set
-# CONFIG_ARPD is not set
-# CONFIG_SYN_COOKIES is not set
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-CONFIG_INET_TUNNEL=m
-CONFIG_IP_TCPDIAG=m
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-# CONFIG_IPV6 is not set
-# CONFIG_NETFILTER is not set
-CONFIG_XFRM=y
-CONFIG_XFRM_USER=m
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP 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_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
CONFIG_NETDEVICES=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_EQUALIZER is not set
# CONFIG_TUN is not set
-# CONFIG_ETHERTAP is not set
#
# ARCnet devices
@@ -339,12 +412,26 @@ CONFIG_NETDEVICES=y
# CONFIG_ARCNET is not set
#
+# PHY device support
+#
+CONFIG_PHYLIB=m
+CONFIG_PHYCONTROL=y
+
+#
+# MII PHY device drivers
+#
+CONFIG_MARVELL_PHY=m
+CONFIG_DAVICOM_PHY=m
+CONFIG_QSEMI_PHY=m
+CONFIG_LXT_PHY=m
+CONFIG_CICADA_PHY=m
+
+#
# Ethernet (10 or 100Mbit)
#
CONFIG_NET_ETHERNET=y
-# CONFIG_MII is not set
+CONFIG_MII=m
# CONFIG_NET_VENDOR_3COM is not set
-# CONFIG_LANCE is not set
# CONFIG_NET_VENDOR_SMC is not set
# CONFIG_NET_VENDOR_RACAL is not set
# CONFIG_AT1700 is not set
@@ -373,6 +460,19 @@ CONFIG_NET_ETHERNET=y
# CONFIG_NET_RADIO is not set
#
+# PCMCIA network device support
+#
+CONFIG_NET_PCMCIA=y
+CONFIG_PCMCIA_3C589=m
+CONFIG_PCMCIA_3C574=m
+CONFIG_PCMCIA_FMVJ18X=m
+CONFIG_PCMCIA_PCNET=m
+CONFIG_PCMCIA_NMCLAN=m
+CONFIG_PCMCIA_SMC91C92=m
+CONFIG_PCMCIA_XIRC2PS=m
+CONFIG_PCMCIA_AXNET=m
+
+#
# Wan interfaces
#
# CONFIG_WAN is not set
@@ -380,6 +480,8 @@ CONFIG_NET_ETHERNET=y
# CONFIG_SLIP is not set
# CONFIG_SHAPER is not set
# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
#
# ISDN subsystem
@@ -409,18 +511,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
# CONFIG_INPUT_EVBUG is not set
#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=y
-CONFIG_SERIO_I8042=y
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_LIBPS2 is not set
-CONFIG_SERIO_RAW=m
-
-#
# Input Device Drivers
#
# CONFIG_INPUT_KEYBOARD is not set
@@ -430,6 +520,16 @@ CONFIG_SERIO_RAW=m
# CONFIG_INPUT_MISC is not set
#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_LIBPS2 is not set
+CONFIG_SERIO_RAW=m
+# CONFIG_GAMEPORT is not set
+
+#
# Character devices
#
CONFIG_VT=y
@@ -440,16 +540,15 @@ CONFIG_HW_CONSOLE=y
#
# Serial drivers
#
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_NR_UARTS=4
-# CONFIG_SERIAL_8250_EXTENDED is not set
+# CONFIG_SERIAL_8250 is not set
#
# Non-8250 serial port support
#
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_SERIAL_VR41XX=y
+CONFIG_SERIAL_VR41XX_CONSOLE=y
CONFIG_UNIX98_PTYS=y
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
@@ -484,10 +583,19 @@ CONFIG_WATCHDOG=y
#
# Ftape, the floppy tape device driver
#
-# CONFIG_DRM is not set
+
+#
+# PCMCIA character devices
+#
+# CONFIG_SYNCLINK_CS is not set
+# CONFIG_GPIO_VR41XX is not set
# CONFIG_RAW_DRIVER is not set
#
+# TPM devices
+#
+
+#
# I2C support
#
# CONFIG_I2C is not set
@@ -498,10 +606,20 @@ CONFIG_WATCHDOG=y
# CONFIG_W1 is not set
#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
+#
# Misc devices
#
#
+# Multimedia Capabilities Port drivers
+#
+
+#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
@@ -522,7 +640,6 @@ CONFIG_WATCHDOG=y
# CONFIG_VGA_CONSOLE is not set
# CONFIG_MDA_CONSOLE is not set
CONFIG_DUMMY_CONSOLE=y
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Sound
@@ -536,10 +653,6 @@ CONFIG_DUMMY_CONSOLE=y
# CONFIG_USB_ARCH_HAS_OHCI is not set
#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
-#
-
-#
# USB Gadget Support
#
# CONFIG_USB_GADGET is not set
@@ -552,7 +665,10 @@ CONFIG_DUMMY_CONSOLE=y
#
# InfiniBand support
#
-# CONFIG_INFINIBAND is not set
+
+#
+# SN Devices
+#
#
# File systems
@@ -561,6 +677,7 @@ CONFIG_EXT2_FS=y
CONFIG_EXT2_FS_XATTR=y
CONFIG_EXT2_FS_POSIX_ACL=y
CONFIG_EXT2_FS_SECURITY=y
+# CONFIG_EXT2_FS_XIP is not set
# CONFIG_EXT3_FS is not set
# CONFIG_JBD is not set
CONFIG_FS_MBCACHE=y
@@ -570,10 +687,12 @@ CONFIG_FS_POSIX_ACL=y
# CONFIG_XFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
# CONFIG_QUOTA is not set
CONFIG_DNOTIFY=y
CONFIG_AUTOFS_FS=y
CONFIG_AUTOFS4_FS=y
+CONFIG_FUSE_FS=m
#
# CD-ROM/DVD Filesystems
@@ -594,12 +713,10 @@ CONFIG_AUTOFS4_FS=y
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
-CONFIG_DEVPTS_FS_XATTR=y
-CONFIG_DEVPTS_FS_SECURITY=y
# CONFIG_TMPFS is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
+CONFIG_RELAYFS_FS=m
#
# Miscellaneous filesystems
@@ -630,6 +747,7 @@ CONFIG_NFSD=y
# CONFIG_NFSD_TCP is not set
CONFIG_LOCKD=y
CONFIG_EXPORTFS=y
+CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
@@ -638,6 +756,7 @@ CONFIG_SUNRPC=y
# CONFIG_NCP_FS is not set
# CONFIG_CODA_FS is not set
# CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
#
# Partition Types
@@ -658,9 +777,11 @@ CONFIG_MSDOS_PARTITION=y
#
# Kernel hacking
#
+# CONFIG_PRINTK_TIME is not set
# CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=14
CONFIG_CROSSCOMPILE=y
-CONFIG_CMDLINE=""
+CONFIG_CMDLINE="console=ttyVR0,19200 mem=16M"
#
# Security options
@@ -672,7 +793,31 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
#
# Cryptographic options
#
-# CONFIG_CRYPTO is not set
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_AES=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_CRC32C=m
+# CONFIG_CRYPTO_TEST is not set
#
# Hardware crypto devices
@@ -682,7 +827,8 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
# Library routines
#
# CONFIG_CRC_CCITT is not set
-# CONFIG_CRC32 is not set
-# CONFIG_LIBCRC32C is not set
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_CRC16=m
+CONFIG_CRC32=y
+CONFIG_LIBCRC32C=m
+CONFIG_ZLIB_INFLATE=m
+CONFIG_ZLIB_DEFLATE=m
diff --git a/arch/mips/configs/yosemite_defconfig b/arch/mips/configs/yosemite_defconfig
index 6d2290777ad7..5b0b7f30e205 100644
--- a/arch/mips/configs/yosemite_defconfig
+++ b/arch/mips/configs/yosemite_defconfig
@@ -1,12 +1,9 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-rc2
-# Wed Jan 26 02:49:13 2005
+# Linux kernel version: 2.6.14-rc2
+# Thu Oct 20 22:27:18 2005
#
CONFIG_MIPS=y
-# CONFIG_64BIT is not set
-# CONFIG_64BIT is not set
-CONFIG_32BIT=y
#
# Code maturity level options
@@ -14,25 +11,31 @@ CONFIG_32BIT=y
# CONFIG_EXPERIMENTAL is not set
CONFIG_CLEAN_COMPILE=y
CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
#
# General setup
#
CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_HOTPLUG is not set
+CONFIG_HOTPLUG=y
CONFIG_KOBJECT_UEVENT=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
+# CONFIG_CPUSETS is not set
+CONFIG_INITRAMFS_SOURCE=""
CONFIG_EMBEDDED=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_ALL is not set
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
@@ -42,6 +45,7 @@ CONFIG_CC_ALIGN_LABELS=0
CONFIG_CC_ALIGN_LOOPS=0
CONFIG_CC_ALIGN_JUMPS=0
# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
#
# Loadable module support
@@ -56,34 +60,68 @@ CONFIG_STOP_MACHINE=y
#
# Machine selection
#
-# CONFIG_MACH_JAZZ is not set
-# CONFIG_MACH_VR41XX is not set
-# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_MIPS_PB1550 is not set
+# CONFIG_MIPS_PB1200 is not set
+# CONFIG_MIPS_DB1000 is not set
+# CONFIG_MIPS_DB1100 is not set
+# CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
+# CONFIG_MIPS_DB1200 is not set
+# CONFIG_MIPS_MIRAGE is not set
+# CONFIG_MIPS_COBALT is not set
# CONFIG_MACH_DECSTATION is not set
+# CONFIG_MIPS_EV64120 is not set
+# CONFIG_MIPS_EV96100 is not set
# CONFIG_MIPS_IVR is not set
-# CONFIG_LASAT is not set
# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_LASAT is not set
# CONFIG_MIPS_ATLAS is not set
# CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SEAD is not set
+# CONFIG_MIPS_SIM is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
# CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_G is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_JAGUAR_ATX is not set
-CONFIG_PMC_YOSEMITE=y
-# CONFIG_HYPERTRANSPORT is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MIPS_XXS1500 is not set
+# CONFIG_PNX8550_V2PCI is not set
+# CONFIG_PNX8550_JBS is not set
+# CONFIG_DDB5074 is not set
# CONFIG_DDB5476 is not set
# CONFIG_DDB5477 is not set
-# CONFIG_NEC_OSPREY is not set
+# CONFIG_MACH_VR41XX is not set
+CONFIG_PMC_YOSEMITE=y
+# CONFIG_QEMU is not set
# CONFIG_SGI_IP22 is not set
-# CONFIG_SOC_AU1X00 is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_BIGSUR is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_PTSWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CRHONE is not set
# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
# CONFIG_TOSHIBA_RBTX4927 is not set
+# CONFIG_TOSHIBA_RBTX4938 is not set
+# CONFIG_HYPERTRANSPORT is not set
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_HAVE_DEC_LOCK=y
CONFIG_DMA_COHERENT=y
+CONFIG_CPU_BIG_ENDIAN=y
# CONFIG_CPU_LITTLE_ENDIAN is not set
+CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
CONFIG_IRQ_CPU=y
CONFIG_IRQ_CPU_RM7K=y
CONFIG_IRQ_CPU_RM9K=y
@@ -93,8 +131,10 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5
#
# CPU selection
#
-# CONFIG_CPU_MIPS32 is not set
-# CONFIG_CPU_MIPS64 is not set
+# CONFIG_CPU_MIPS32_R1 is not set
+# CONFIG_CPU_MIPS32_R2 is not set
+# CONFIG_CPU_MIPS64_R1 is not set
+# CONFIG_CPU_MIPS64_R2 is not set
# CONFIG_CPU_R3000 is not set
# CONFIG_CPU_TX39XX is not set
# CONFIG_CPU_VR41XX is not set
@@ -110,20 +150,43 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5
# CONFIG_CPU_RM7000 is not set
CONFIG_CPU_RM9000=y
# CONFIG_CPU_SB1 is not set
+CONFIG_SYS_HAS_CPU_RM9000=y
+CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
+CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y
+
+#
+# Kernel type
+#
+CONFIG_32BIT=y
+# CONFIG_64BIT is not set
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_CPU_HAS_PREFETCH=y
+# CONFIG_MIPS_MT is not set
# CONFIG_64BIT_PHYS_ADDR is not set
# CONFIG_CPU_ADVANCED is not set
CONFIG_CPU_HAS_LLSC=y
CONFIG_CPU_HAS_LLDSCD=y
CONFIG_CPU_HAS_SYNC=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_HIGHMEM=y
+CONFIG_CPU_SUPPORTS_HIGHMEM=y
+CONFIG_SYS_SUPPORTS_HIGHMEM=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
CONFIG_SMP=y
CONFIG_NR_CPUS=2
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
+CONFIG_PREEMPT_BKL=y
#
# Bus options (PCI, PCMCIA, EISA, ISA, TC)
@@ -131,7 +194,7 @@ CONFIG_NR_CPUS=2
CONFIG_HW_HAS_PCI=y
CONFIG_PCI=y
CONFIG_PCI_LEGACY_PROC=y
-CONFIG_PCI_NAMES=y
+# CONFIG_PCI_DEBUG is not set
CONFIG_MMU=y
#
@@ -140,10 +203,6 @@ CONFIG_MMU=y
# CONFIG_PCCARD is not set
#
-# PC-card bridges
-#
-
-#
# PCI Hotplug Support
#
@@ -155,6 +214,69 @@ CONFIG_BINFMT_ELF=y
CONFIG_TRAD_SIGNALS=y
#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=m
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE 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_TUNNEL=m
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+CONFIG_IPV6=m
+CONFIG_IPV6_PRIVACY=y
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+CONFIG_INET6_TUNNEL=m
+CONFIG_IPV6_TUNNEL=m
+# CONFIG_NETFILTER 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_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_IEEE80211=m
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=m
+CONFIG_IEEE80211_CRYPT_CCMP=m
+CONFIG_IEEE80211_CRYPT_TKIP=m
+
+#
# Device Drivers
#
@@ -163,10 +285,15 @@ CONFIG_TRAD_SIGNALS=y
#
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
+CONFIG_FW_LOADER=m
# CONFIG_DEBUG_DRIVER is not set
#
+# Connector - unified userspace <-> kernelspace linker
+#
+CONFIG_CONNECTOR=m
+
+#
# Memory Technology Devices (MTD)
#
# CONFIG_MTD is not set
@@ -183,7 +310,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
#
# Block devices
#
-# CONFIG_BLK_DEV_FD is not set
# CONFIG_BLK_CPQ_DA is not set
# CONFIG_BLK_CPQ_CISS_DA is not set
# CONFIG_BLK_DEV_DAC960 is not set
@@ -193,7 +319,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_BLK_DEV_SX8 is not set
# CONFIG_BLK_DEV_RAM is not set
CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_INITRAMFS_SOURCE=""
# CONFIG_LBD is not set
CONFIG_CDROM_PKTCDVD=m
CONFIG_CDROM_PKTCDVD_BUFFERS=8
@@ -216,6 +341,7 @@ CONFIG_ATA_OVER_ETH=m
#
# SCSI device support
#
+CONFIG_RAID_ATTRS=m
# CONFIG_SCSI is not set
#
@@ -226,6 +352,7 @@ CONFIG_ATA_OVER_ETH=m
#
# Fusion MPT device support
#
+# CONFIG_FUSION is not set
#
# IEEE 1394 (FireWire) support
@@ -238,59 +365,8 @@ CONFIG_ATA_OVER_ETH=m
# CONFIG_I2O is not set
#
-# Networking support
+# Network device support
#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=m
-CONFIG_PACKET_MMAP=y
-CONFIG_NETLINK_DEV=m
-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_PNP=y
-# CONFIG_IP_PNP_DHCP is not set
-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_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_TUNNEL=m
-CONFIG_IP_TCPDIAG=m
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-# CONFIG_NETFILTER is not set
-CONFIG_XFRM=y
-CONFIG_XFRM_USER=m
-# 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
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
CONFIG_NETDEVICES=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
@@ -303,6 +379,21 @@ CONFIG_NETDEVICES=y
# CONFIG_ARCNET is not set
#
+# PHY device support
+#
+CONFIG_PHYLIB=m
+CONFIG_PHYCONTROL=y
+
+#
+# MII PHY device drivers
+#
+CONFIG_MARVELL_PHY=m
+CONFIG_DAVICOM_PHY=m
+CONFIG_QSEMI_PHY=m
+CONFIG_LXT_PHY=m
+CONFIG_CICADA_PHY=m
+
+#
# Ethernet (10 or 100Mbit)
#
CONFIG_NET_ETHERNET=y
@@ -327,13 +418,16 @@ CONFIG_MII=y
# CONFIG_NS83820 is not set
# CONFIG_HAMACHI is not set
# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
# CONFIG_SK98LIN is not set
# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
CONFIG_TITAN_GE=y
#
# Ethernet (10000 Mbit)
#
+# CONFIG_CHELSIO_T1 is not set
# CONFIG_IXGB is not set
# CONFIG_S2IO is not set
@@ -346,6 +440,8 @@ CONFIG_TITAN_GE=y
# Wireless LAN (non-hamradio)
#
# CONFIG_NET_RADIO is not set
+# CONFIG_IPW_DEBUG is not set
+CONFIG_IPW2200=m
#
# Wan interfaces
@@ -354,6 +450,8 @@ CONFIG_TITAN_GE=y
# CONFIG_FDDI is not set
# CONFIG_PPP is not set
# CONFIG_SLIP is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
#
# ISDN subsystem
@@ -371,20 +469,10 @@ CONFIG_TITAN_GE=y
# CONFIG_INPUT is not set
#
-# Userland interfaces
-#
-
-#
-# Input I/O drivers
+# Hardware I/O ports
#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
# CONFIG_SERIO is not set
-# CONFIG_SERIO_I8042 is not set
-
-#
-# Input Device Drivers
-#
+# CONFIG_GAMEPORT is not set
#
# Character devices
@@ -405,6 +493,7 @@ CONFIG_SERIAL_8250_NR_UARTS=4
#
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
CONFIG_UNIX98_PTYS=y
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
@@ -432,6 +521,10 @@ CONFIG_GEN_RTC_X=y
# CONFIG_RAW_DRIVER is not set
#
+# TPM devices
+#
+
+#
# I2C support
#
# CONFIG_I2C is not set
@@ -442,10 +535,20 @@ CONFIG_GEN_RTC_X=y
# CONFIG_W1 is not set
#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
+#
# Misc devices
#
#
+# Multimedia Capabilities Port drivers
+#
+
+#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
@@ -459,7 +562,6 @@ CONFIG_GEN_RTC_X=y
# Graphics support
#
# CONFIG_FB is not set
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Sound
@@ -469,13 +571,9 @@ CONFIG_GEN_RTC_X=y
#
# USB support
#
-# CONFIG_USB is not set
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB_ARCH_HAS_OHCI=y
-
-#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
-#
+# CONFIG_USB is not set
#
# USB Gadget Support
@@ -493,6 +591,10 @@ CONFIG_USB_ARCH_HAS_OHCI=y
# CONFIG_INFINIBAND is not set
#
+# SN Devices
+#
+
+#
# File systems
#
# CONFIG_EXT2_FS is not set
@@ -500,13 +602,16 @@ CONFIG_USB_ARCH_HAS_OHCI=y
# CONFIG_JBD 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_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
# CONFIG_QUOTA is not set
CONFIG_DNOTIFY=y
# CONFIG_AUTOFS_FS is not set
# CONFIG_AUTOFS4_FS is not set
+CONFIG_FUSE_FS=m
#
# CD-ROM/DVD Filesystems
@@ -527,11 +632,10 @@ CONFIG_DNOTIFY=y
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_SYSFS=y
-# CONFIG_DEVPTS_FS_XATTR is not set
CONFIG_TMPFS=y
-# CONFIG_TMPFS_XATTR is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
+CONFIG_RELAYFS_FS=m
#
# Miscellaneous filesystems
@@ -552,7 +656,7 @@ CONFIG_NFS_FS=y
# CONFIG_NFSD is not set
CONFIG_ROOT_NFS=y
CONFIG_LOCKD=y
-# CONFIG_EXPORTFS is not set
+CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
# CONFIG_SMB_FS is not set
# CONFIG_CIFS is not set
@@ -573,8 +677,11 @@ CONFIG_MSDOS_PARTITION=y
#
# Kernel hacking
#
+# CONFIG_PRINTK_TIME is not set
CONFIG_DEBUG_KERNEL=y
# CONFIG_MAGIC_SYSRQ is not set
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_DETECT_SOFTLOCKUP=y
# CONFIG_SCHEDSTATS is not set
# CONFIG_DEBUG_SLAB is not set
# CONFIG_DEBUG_SPINLOCK is not set
@@ -599,7 +706,31 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
#
# Cryptographic options
#
-# CONFIG_CRYPTO is not set
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_AES=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_CRC32C=m
+# CONFIG_CRYPTO_TEST is not set
#
# Hardware crypto devices
@@ -609,7 +740,8 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
# Library routines
#
# CONFIG_CRC_CCITT is not set
-# CONFIG_CRC32 is not set
-# CONFIG_LIBCRC32C is not set
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_CRC16=m
+CONFIG_CRC32=m
+CONFIG_LIBCRC32C=m
+CONFIG_ZLIB_INFLATE=m
+CONFIG_ZLIB_DEFLATE=m
diff --git a/arch/mips/ddb5xxx/Kconfig b/arch/mips/ddb5xxx/Kconfig
new file mode 100644
index 000000000000..e9b5de49f4c2
--- /dev/null
+++ b/arch/mips/ddb5xxx/Kconfig
@@ -0,0 +1,4 @@
+config DDB5477_BUS_FREQUENCY
+ int "bus frequency (in kHZ, 0 for auto-detect)"
+ depends on DDB5477
+ default 0
diff --git a/arch/mips/ddb5xxx/common/rtc_ds1386.c b/arch/mips/ddb5xxx/common/rtc_ds1386.c
index f5b11508ff2f..995896ac0e39 100644
--- a/arch/mips/ddb5xxx/common/rtc_ds1386.c
+++ b/arch/mips/ddb5xxx/common/rtc_ds1386.c
@@ -41,7 +41,9 @@ rtc_ds1386_get_time(void)
u8 byte;
u8 temp;
unsigned int year, month, day, hour, minute, second;
+ unsigned long flags;
+ spin_lock_irqsave(&rtc_lock, flags);
/* let us freeze external registers */
byte = READ_RTC(0xB);
byte &= 0x3f;
@@ -60,6 +62,7 @@ rtc_ds1386_get_time(void)
/* enable time transfer */
byte |= 0x80;
WRITE_RTC(0xB, byte);
+ spin_unlock_irqrestore(&rtc_lock, flags);
/* calc hour */
if (temp & 0x40) {
@@ -81,7 +84,9 @@ rtc_ds1386_set_time(unsigned long t)
u8 byte;
u8 temp;
u8 year, month, day, hour, minute, second;
+ unsigned long flags;
+ spin_lock_irqsave(&rtc_lock, flags);
/* let us freeze external registers */
byte = READ_RTC(0xB);
byte &= 0x3f;
@@ -133,6 +138,7 @@ rtc_ds1386_set_time(unsigned long t)
if (second != READ_RTC(0x1)) {
WRITE_RTC(0x1, second);
}
+ spin_unlock_irqrestore(&rtc_lock, flags);
return 0;
}
diff --git a/arch/mips/ddb5xxx/ddb5074/nile4_pic.c b/arch/mips/ddb5xxx/ddb5074/nile4_pic.c
index 68c127cd70c9..8743ffce8653 100644
--- a/arch/mips/ddb5xxx/ddb5074/nile4_pic.c
+++ b/arch/mips/ddb5xxx/ddb5074/nile4_pic.c
@@ -209,14 +209,13 @@ static void nile4_irq_end(unsigned int irq) {
#define nile4_irq_shutdown nile4_disable_irq
static hw_irq_controller nile4_irq_controller = {
- "nile4",
- nile4_irq_startup,
- nile4_irq_shutdown,
- nile4_enable_irq,
- nile4_disable_irq,
- nile4_ack_irq,
- nile4_irq_end,
- NULL
+ .typename = "nile4",
+ .startup = nile4_irq_startup,
+ .shutdown = nile4_irq_shutdown,
+ .enable = nile4_enable_irq,
+ .disable = nile4_disable_irq,
+ .ack = nile4_ack_irq,
+ .end = nile4_irq_end,
};
void nile4_irq_setup(u32 base) {
diff --git a/arch/mips/ddb5xxx/ddb5074/setup.c b/arch/mips/ddb5xxx/ddb5074/setup.c
index a73a5978d550..11535be265b9 100644
--- a/arch/mips/ddb5xxx/ddb5074/setup.c
+++ b/arch/mips/ddb5xxx/ddb5074/setup.c
@@ -85,7 +85,7 @@ static void __init ddb_time_init(void)
-static void __init ddb5074_setup(void)
+void __init plat_setup(void)
{
set_io_port_base(NILE4_PCI_IO_BASE);
isa_slot_offset = NILE4_PCI_MEM_BASE;
@@ -106,8 +106,6 @@ static void __init ddb5074_setup(void)
panic_timeout = 180;
}
-early_initcall(ddb5074_setup);
-
#define USE_NILE4_SERIAL 0
#if USE_NILE4_SERIAL
diff --git a/arch/mips/ddb5xxx/ddb5476/setup.c b/arch/mips/ddb5xxx/ddb5476/setup.c
index 71531f8146ea..f4e480a74edf 100644
--- a/arch/mips/ddb5xxx/ddb5476/setup.c
+++ b/arch/mips/ddb5xxx/ddb5476/setup.c
@@ -124,7 +124,7 @@ static struct {
static void ddb5476_board_init(void);
-static void __init ddb5476_setup(void)
+void __init plat_setup(void)
{
set_io_port_base(KSEG1ADDR(DDB_PCI_IO_BASE));
@@ -158,8 +158,6 @@ static void __init ddb5476_setup(void)
ddb5476_board_init();
}
-early_initcall(ddb5476_setup);
-
/*
* We don't trust bios. We essentially does hardware re-initialization
* as complete as possible, as far as we know we can safely do.
diff --git a/arch/mips/ddb5xxx/ddb5476/vrc5476_irq.c b/arch/mips/ddb5xxx/ddb5476/vrc5476_irq.c
index a77682be01ac..f66fe5b58636 100644
--- a/arch/mips/ddb5xxx/ddb5476/vrc5476_irq.c
+++ b/arch/mips/ddb5xxx/ddb5476/vrc5476_irq.c
@@ -53,14 +53,13 @@ static void vrc5476_irq_end(uint irq)
}
static hw_irq_controller vrc5476_irq_controller = {
- "vrc5476",
- vrc5476_irq_startup,
- vrc5476_irq_shutdown,
- vrc5476_irq_enable,
- vrc5476_irq_disable,
- vrc5476_irq_ack,
- vrc5476_irq_end,
- NULL /* no affinity stuff for UP */
+ .typename = "vrc5476",
+ .startup = vrc5476_irq_startup,
+ .shutdown = vrc5476_irq_shutdown,
+ .enable = vrc5476_irq_enable,
+ .disable = vrc5476_irq_disable,
+ .ack = vrc5476_irq_ack,
+ .end = vrc5476_irq_end
};
void __init
diff --git a/arch/mips/ddb5xxx/ddb5477/irq_5477.c b/arch/mips/ddb5xxx/ddb5477/irq_5477.c
index 0d5e706207ec..5fcd5f070cdc 100644
--- a/arch/mips/ddb5xxx/ddb5477/irq_5477.c
+++ b/arch/mips/ddb5xxx/ddb5477/irq_5477.c
@@ -90,14 +90,13 @@ vrc5477_irq_end(unsigned int irq)
}
hw_irq_controller vrc5477_irq_controller = {
- "vrc5477_irq",
- vrc5477_irq_startup,
- vrc5477_irq_shutdown,
- vrc5477_irq_enable,
- vrc5477_irq_disable,
- vrc5477_irq_ack,
- vrc5477_irq_end,
- NULL /* no affinity stuff for UP */
+ .typename = "vrc5477_irq",
+ .startup = vrc5477_irq_startup,
+ .shutdown = vrc5477_irq_shutdown,
+ .enable = vrc5477_irq_enable,
+ .disable = vrc5477_irq_disable,
+ .ack = vrc5477_irq_ack,
+ .end = vrc5477_irq_end
};
void __init vrc5477_irq_init(u32 irq_base)
diff --git a/arch/mips/ddb5xxx/ddb5477/setup.c b/arch/mips/ddb5xxx/ddb5477/setup.c
index d62f5a789b05..81163353c4a8 100644
--- a/arch/mips/ddb5xxx/ddb5477/setup.c
+++ b/arch/mips/ddb5xxx/ddb5477/setup.c
@@ -170,7 +170,7 @@ static void ddb5477_board_init(void);
extern struct pci_controller ddb5477_ext_controller;
extern struct pci_controller ddb5477_io_controller;
-static int ddb5477_setup(void)
+void __init plat_setup(void)
{
/* initialize board - we don't trust the loader */
ddb5477_board_init();
@@ -193,12 +193,8 @@ static int ddb5477_setup(void)
register_pci_controller (&ddb5477_ext_controller);
register_pci_controller (&ddb5477_io_controller);
-
- return 0;
}
-early_initcall(ddb5477_setup);
-
static void __init ddb5477_board_init(void)
{
/* ----------- setup PDARs ------------ */
diff --git a/arch/mips/dec/Makefile b/arch/mips/dec/Makefile
index 688757a97cb8..ed181fdc3ac9 100644
--- a/arch/mips/dec/Makefile
+++ b/arch/mips/dec/Makefile
@@ -2,8 +2,8 @@
# Makefile for the DECstation family specific parts of the kernel
#
-obj-y := ecc-berr.o int-handler.o ioasic-irq.o kn02-irq.o reset.o \
- setup.o time.o
+obj-y := ecc-berr.o int-handler.o ioasic-irq.o kn01-berr.o \
+ kn02-irq.o kn02xa-berr.o reset.o setup.o time.o
obj-$(CONFIG_PROM_CONSOLE) += promcon.o
obj-$(CONFIG_CPU_HAS_WB) += wbflush.o
diff --git a/arch/mips/dec/ecc-berr.c b/arch/mips/dec/ecc-berr.c
index 6dbce92eb068..cc24c5ed0c05 100644
--- a/arch/mips/dec/ecc-berr.c
+++ b/arch/mips/dec/ecc-berr.c
@@ -6,7 +6,7 @@
* 5000/240 (KN03), 5000/260 (KN05) and DECsystem 5900 (KN03),
* 5900/260 (KN05) systems.
*
- * Copyright (c) 2003 Maciej W. Rozycki
+ * Copyright (c) 2003, 2005 Maciej W. Rozycki
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -15,6 +15,7 @@
*/
#include <linux/init.h>
+#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/spinlock.h>
@@ -57,7 +58,7 @@ static int dec_ecc_be_backend(struct pt_regs *regs, int is_fixup, int invoker)
const char *kind, *agent, *cycle, *event;
const char *status = "", *xbit = "", *fmt = "";
- dma_addr_t address;
+ unsigned long address;
u16 syn = 0, sngl;
int i = 0;
@@ -66,7 +67,7 @@ static int dec_ecc_be_backend(struct pt_regs *regs, int is_fixup, int invoker)
u32 chksyn = *kn0x_chksyn;
int action = MIPS_BE_FATAL;
- /* For non-ECC ack ASAP, so any subsequent errors get caught. */
+ /* For non-ECC ack ASAP, so that any subsequent errors get caught. */
if ((erraddr & (KN0X_EAR_VALID | KN0X_EAR_ECCERR)) == KN0X_EAR_VALID)
dec_ecc_be_ack();
@@ -74,7 +75,7 @@ static int dec_ecc_be_backend(struct pt_regs *regs, int is_fixup, int invoker)
if (!(erraddr & KN0X_EAR_VALID)) {
/* No idea what happened. */
- printk(KERN_ALERT "Unidentified bus error %s.\n", kind);
+ printk(KERN_ALERT "Unidentified bus error %s\n", kind);
return action;
}
@@ -126,7 +127,7 @@ static int dec_ecc_be_backend(struct pt_regs *regs, int is_fixup, int invoker)
/* Ack now, no rewrite will happen. */
dec_ecc_be_ack();
- fmt = KERN_ALERT "%s" "invalid.\n";
+ fmt = KERN_ALERT "%s" "invalid\n";
} else {
sngl = syn & KN0X_ESR_SNGLO;
syn &= KN0X_ESR_SYNLO;
@@ -144,7 +145,8 @@ static int dec_ecc_be_backend(struct pt_regs *regs, int is_fixup, int invoker)
} else if (!sngl) {
status = dbestr;
} else {
- volatile u32 *ptr = (void *)KSEG1ADDR(address);
+ volatile u32 *ptr =
+ (void *)CKSEG1ADDR(address);
*ptr = *ptr; /* Rewrite. */
iob();
@@ -160,12 +162,12 @@ static int dec_ecc_be_backend(struct pt_regs *regs, int is_fixup, int invoker)
if (syn == 0x01) {
fmt = KERN_ALERT "%s"
"%#04x -- %s bit error "
- "at check bit C%s.\n";
+ "at check bit C%s\n";
xbit = "X";
} else {
fmt = KERN_ALERT "%s"
"%#04x -- %s bit error "
- "at check bit C%s%u.\n";
+ "at check bit C%s%u\n";
}
i = syn >> 2;
} else {
@@ -175,16 +177,16 @@ static int dec_ecc_be_backend(struct pt_regs *regs, int is_fixup, int invoker)
if (i < 32)
fmt = KERN_ALERT "%s"
"%#04x -- %s bit error "
- "at data bit D%s%u.\n";
+ "at data bit D%s%u\n";
else
fmt = KERN_ALERT "%s"
- "%#04x -- %s bit error.\n";
+ "%#04x -- %s bit error\n";
}
}
}
if (action != MIPS_BE_FIXUP)
- printk(KERN_ALERT "Bus error %s: %s %s %s at %#010lx.\n",
+ printk(KERN_ALERT "Bus error %s: %s %s %s at %#010lx\n",
kind, agent, cycle, event, address);
if (action != MIPS_BE_FIXUP && erraddr & KN0X_EAR_ECCERR)
@@ -203,11 +205,11 @@ irqreturn_t dec_ecc_be_interrupt(int irq, void *dev_id, struct pt_regs *regs)
int action = dec_ecc_be_backend(regs, 0, 1);
if (action == MIPS_BE_DISCARD)
- return IRQ_NONE;
+ return IRQ_HANDLED;
/*
- * FIXME: Find affected processes and kill them, otherwise we
- * must die.
+ * FIXME: Find the affected processes and kill them, otherwise
+ * we must die.
*
* The interrupt is asynchronously delivered thus EPC and RA
* may be irrelevant, but are printed for a reference.
@@ -225,16 +227,16 @@ irqreturn_t dec_ecc_be_interrupt(int irq, void *dev_id, struct pt_regs *regs)
*/
static inline void dec_kn02_be_init(void)
{
- volatile u32 *csr = (void *)KN02_CSR_BASE;
+ volatile u32 *csr = (void *)CKSEG1ADDR(KN02_SLOT_BASE + KN02_CSR);
unsigned long flags;
- kn0x_erraddr = (void *)(KN02_SLOT_BASE + KN02_ERRADDR);
- kn0x_chksyn = (void *)(KN02_SLOT_BASE + KN02_CHKSYN);
+ kn0x_erraddr = (void *)CKSEG1ADDR(KN02_SLOT_BASE + KN02_ERRADDR);
+ kn0x_chksyn = (void *)CKSEG1ADDR(KN02_SLOT_BASE + KN02_CHKSYN);
spin_lock_irqsave(&kn02_lock, flags);
/* Preset write-only bits of the Control Register cache. */
- cached_kn02_csr = *csr | KN03_CSR_LEDS;
+ cached_kn02_csr = *csr | KN02_CSR_LEDS;
/* Set normal ECC detection and generation. */
cached_kn02_csr &= ~(KN02_CSR_DIAGCHK | KN02_CSR_DIAGGEN);
@@ -248,11 +250,11 @@ static inline void dec_kn02_be_init(void)
static inline void dec_kn03_be_init(void)
{
- volatile u32 *mcr = (void *)(KN03_SLOT_BASE + IOASIC_MCR);
- volatile u32 *mbcs = (void *)(KN03_SLOT_BASE + KN05_MB_CSR);
+ volatile u32 *mcr = (void *)CKSEG1ADDR(KN03_SLOT_BASE + IOASIC_MCR);
+ volatile u32 *mbcs = (void *)CKSEG1ADDR(KN4K_SLOT_BASE + KN4K_MB_CSR);
- kn0x_erraddr = (void *)(KN03_SLOT_BASE + IOASIC_ERRADDR);
- kn0x_chksyn = (void *)(KN03_SLOT_BASE + IOASIC_CHKSYN);
+ kn0x_erraddr = (void *)CKSEG1ADDR(KN03_SLOT_BASE + IOASIC_ERRADDR);
+ kn0x_chksyn = (void *)CKSEG1ADDR(KN03_SLOT_BASE + IOASIC_CHKSYN);
/*
* Set normal ECC detection and generation, enable ECC correction.
@@ -264,7 +266,7 @@ static inline void dec_kn03_be_init(void)
*mcr = (*mcr & ~(KN03_MCR_DIAGCHK | KN03_MCR_DIAGGEN)) |
KN03_MCR_CORRECT;
if (current_cpu_data.cputype == CPU_R4400SC)
- *mbcs |= KN05_MB_CSR_EE;
+ *mbcs |= KN4K_MB_CSR_EE;
fast_iob();
}
diff --git a/arch/mips/dec/int-handler.S b/arch/mips/dec/int-handler.S
index c89768d5c4e5..41fa372007bf 100644
--- a/arch/mips/dec/int-handler.S
+++ b/arch/mips/dec/int-handler.S
@@ -2,9 +2,9 @@
* arch/mips/dec/int-handler.S
*
* Copyright (C) 1995, 1996, 1997 Paul M. Antoine and Harald Koerfgen
- * Copyright (C) 2000, 2001, 2002, 2003 Maciej W. Rozycki
+ * Copyright (C) 2000, 2001, 2002, 2003, 2005 Maciej W. Rozycki
*
- * Written by Ralf Baechle and Andreas Busse, modified for DECStation
+ * Written by Ralf Baechle and Andreas Busse, modified for DECstation
* support by Paul Antoine and Harald Koerfgen.
*
* completly rewritten:
@@ -14,11 +14,12 @@
* by Maciej W. Rozycki.
*/
#include <linux/config.h>
+
+#include <asm/addrspace.h>
#include <asm/asm.h>
-#include <asm/regdef.h>
#include <asm/mipsregs.h>
+#include <asm/regdef.h>
#include <asm/stackframe.h>
-#include <asm/addrspace.h>
#include <asm/dec/interrupts.h>
#include <asm/dec/ioasic_addrs.h>
@@ -28,11 +29,14 @@
#include <asm/dec/kn02xa.h>
#include <asm/dec/kn03.h>
+#define KN02_CSR_BASE CKSEG1ADDR(KN02_SLOT_BASE + KN02_CSR)
+#define KN02XA_IOASIC_BASE CKSEG1ADDR(KN02XA_SLOT_BASE + IOASIC_IOCTL)
+#define KN03_IOASIC_BASE CKSEG1ADDR(KN03_SLOT_BASE + IOASIC_IOCTL)
.text
.set noreorder
/*
- * decstation_handle_int: Interrupt handler for DECStations
+ * decstation_handle_int: Interrupt handler for DECstations
*
* We follow the model in the Indy interrupt code by David Miller, where he
* says: a lot of complication here is taken away because:
@@ -48,7 +52,7 @@
* 3) Linux only thinks in terms of all IRQs on or all IRQs
* off, nothing in between like BSD spl() brain-damage.
*
- * Furthermore, the IRQs on the DECStations look basically (barring
+ * Furthermore, the IRQs on the DECstations look basically (barring
* software IRQs which we don't use at all) like...
*
* DS2100/3100's, aka kn01, aka Pmax:
@@ -61,7 +65,7 @@
* 3 Lance Ethernet
* 4 DZ11 serial
* 5 RTC
- * 6 Memory Controller
+ * 6 Memory Controller & Video
* 7 FPU
*
* DS5000/200, aka kn02, aka 3max:
diff --git a/arch/mips/dec/kn01-berr.c b/arch/mips/dec/kn01-berr.c
new file mode 100644
index 000000000000..b9271db9bc76
--- /dev/null
+++ b/arch/mips/dec/kn01-berr.c
@@ -0,0 +1,201 @@
+/*
+ * linux/arch/mips/dec/kn01-berr.c
+ *
+ * Bus error event handling code for DECstation/DECsystem 3100
+ * and 2100 (KN01) systems equipped with parity error detection
+ * logic.
+ *
+ * Copyright (c) 2005 Maciej W. Rozycki
+ *
+ * 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/init.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/spinlock.h>
+#include <linux/types.h>
+
+#include <asm/inst.h>
+#include <asm/mipsregs.h>
+#include <asm/page.h>
+#include <asm/system.h>
+#include <asm/traps.h>
+#include <asm/uaccess.h>
+
+#include <asm/dec/kn01.h>
+
+
+/* CP0 hazard avoidance. */
+#define BARRIER \
+ __asm__ __volatile__( \
+ ".set push\n\t" \
+ ".set noreorder\n\t" \
+ "nop\n\t" \
+ ".set pop\n\t")
+
+/*
+ * Bits 7:0 of the Control Register are write-only -- the
+ * corresponding bits of the Status Register have a different
+ * meaning. Hence we use a cache. It speeds up things a bit
+ * as well.
+ *
+ * There is no default value -- it has to be initialized.
+ */
+u16 cached_kn01_csr;
+DEFINE_SPINLOCK(kn01_lock);
+
+
+static inline void dec_kn01_be_ack(void)
+{
+ volatile u16 *csr = (void *)CKSEG1ADDR(KN01_SLOT_BASE + KN01_CSR);
+ unsigned long flags;
+
+ spin_lock_irqsave(&kn01_lock, flags);
+
+ *csr = cached_kn01_csr | KN01_CSR_MEMERR; /* Clear bus IRQ. */
+ iob();
+
+ spin_unlock_irqrestore(&kn01_lock, flags);
+}
+
+static int dec_kn01_be_backend(struct pt_regs *regs, int is_fixup, int invoker)
+{
+ volatile u32 *kn01_erraddr = (void *)CKSEG1ADDR(KN01_SLOT_BASE +
+ KN01_ERRADDR);
+
+ static const char excstr[] = "exception";
+ static const char intstr[] = "interrupt";
+ static const char cpustr[] = "CPU";
+ static const char mreadstr[] = "memory read";
+ static const char readstr[] = "read";
+ static const char writestr[] = "write";
+ static const char timestr[] = "timeout";
+ static const char paritystr[] = "parity error";
+
+ int data = regs->cp0_cause & 4;
+ unsigned int __user *pc = (unsigned int __user *)regs->cp0_epc +
+ ((regs->cp0_cause & CAUSEF_BD) != 0);
+ union mips_instruction insn;
+ unsigned long entrylo, offset;
+ long asid, entryhi, vaddr;
+
+ const char *kind, *agent, *cycle, *event;
+ unsigned long address;
+
+ u32 erraddr = *kn01_erraddr;
+ int action = MIPS_BE_FATAL;
+
+ /* Ack ASAP, so that any subsequent errors get caught. */
+ dec_kn01_be_ack();
+
+ kind = invoker ? intstr : excstr;
+
+ agent = cpustr;
+
+ if (invoker)
+ address = erraddr;
+ else {
+ /* Bloody hardware doesn't record the address for reads... */
+ if (data) {
+ /* This never faults. */
+ __get_user(insn.word, pc);
+ vaddr = regs->regs[insn.i_format.rs] +
+ insn.i_format.simmediate;
+ } else
+ vaddr = (long)pc;
+ if (KSEGX(vaddr) == CKSEG0 || KSEGX(vaddr) == CKSEG1)
+ address = CPHYSADDR(vaddr);
+ else {
+ /* Peek at what physical address the CPU used. */
+ asid = read_c0_entryhi();
+ entryhi = asid & (PAGE_SIZE - 1);
+ entryhi |= vaddr & ~(PAGE_SIZE - 1);
+ write_c0_entryhi(entryhi);
+ BARRIER;
+ tlb_probe();
+ /* No need to check for presence. */
+ tlb_read();
+ entrylo = read_c0_entrylo0();
+ write_c0_entryhi(asid);
+ offset = vaddr & (PAGE_SIZE - 1);
+ address = (entrylo & ~(PAGE_SIZE - 1)) | offset;
+ }
+ }
+
+ /* Treat low 256MB as memory, high -- as I/O. */
+ if (address < 0x10000000) {
+ cycle = mreadstr;
+ event = paritystr;
+ } else {
+ cycle = invoker ? writestr : readstr;
+ event = timestr;
+ }
+
+ if (is_fixup)
+ action = MIPS_BE_FIXUP;
+
+ if (action != MIPS_BE_FIXUP)
+ printk(KERN_ALERT "Bus error %s: %s %s %s at %#010lx\n",
+ kind, agent, cycle, event, address);
+
+ return action;
+}
+
+int dec_kn01_be_handler(struct pt_regs *regs, int is_fixup)
+{
+ return dec_kn01_be_backend(regs, is_fixup, 0);
+}
+
+irqreturn_t dec_kn01_be_interrupt(int irq, void *dev_id,
+ struct pt_regs *regs)
+{
+ volatile u16 *csr = (void *)CKSEG1ADDR(KN01_SLOT_BASE + KN01_CSR);
+ int action;
+
+ if (!(*csr & KN01_CSR_MEMERR))
+ return IRQ_NONE; /* Must have been video. */
+
+ action = dec_kn01_be_backend(regs, 0, 1);
+
+ if (action == MIPS_BE_DISCARD)
+ return IRQ_HANDLED;
+
+ /*
+ * FIXME: Find the affected processes and kill them, otherwise
+ * we must die.
+ *
+ * The interrupt is asynchronously delivered thus EPC and RA
+ * may be irrelevant, but are printed for a reference.
+ */
+ printk(KERN_ALERT "Fatal bus interrupt, epc == %08lx, ra == %08lx\n",
+ regs->cp0_epc, regs->regs[31]);
+ die("Unrecoverable bus error", regs);
+}
+
+
+void __init dec_kn01_be_init(void)
+{
+ volatile u16 *csr = (void *)CKSEG1ADDR(KN01_SLOT_BASE + KN01_CSR);
+ unsigned long flags;
+
+ spin_lock_irqsave(&kn01_lock, flags);
+
+ /* Preset write-only bits of the Control Register cache. */
+ cached_kn01_csr = *csr;
+ cached_kn01_csr &= KN01_CSR_STATUS | KN01_CSR_PARDIS | KN01_CSR_TXDIS;
+ cached_kn01_csr |= KN01_CSR_LEDS;
+
+ /* Enable parity error detection. */
+ cached_kn01_csr &= ~KN01_CSR_PARDIS;
+ *csr = cached_kn01_csr;
+ iob();
+
+ spin_unlock_irqrestore(&kn01_lock, flags);
+
+ /* Clear any leftover errors from the firmware. */
+ dec_kn01_be_ack();
+}
diff --git a/arch/mips/dec/kn02-irq.c b/arch/mips/dec/kn02-irq.c
index e0bfcd1521e2..898bed502a34 100644
--- a/arch/mips/dec/kn02-irq.c
+++ b/arch/mips/dec/kn02-irq.c
@@ -4,7 +4,7 @@
* DECstation 5000/200 (KN02) Control and Status Register
* interrupts.
*
- * Copyright (c) 2002, 2003 Maciej W. Rozycki
+ * Copyright (c) 2002, 2003, 2005 Maciej W. Rozycki
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -37,7 +37,8 @@ static int kn02_irq_base;
static inline void unmask_kn02_irq(unsigned int irq)
{
- volatile u32 *csr = (volatile u32 *)KN02_CSR_BASE;
+ volatile u32 *csr = (volatile u32 *)CKSEG1ADDR(KN02_SLOT_BASE +
+ KN02_CSR);
cached_kn02_csr |= (1 << (irq - kn02_irq_base + 16));
*csr = cached_kn02_csr;
@@ -45,7 +46,8 @@ static inline void unmask_kn02_irq(unsigned int irq)
static inline void mask_kn02_irq(unsigned int irq)
{
- volatile u32 *csr = (volatile u32 *)KN02_CSR_BASE;
+ volatile u32 *csr = (volatile u32 *)CKSEG1ADDR(KN02_SLOT_BASE +
+ KN02_CSR);
cached_kn02_csr &= ~(1 << (irq - kn02_irq_base + 16));
*csr = cached_kn02_csr;
@@ -105,13 +107,14 @@ static struct hw_interrupt_type kn02_irq_type = {
void __init init_kn02_irqs(int base)
{
- volatile u32 *csr = (volatile u32 *)KN02_CSR_BASE;
+ volatile u32 *csr = (volatile u32 *)CKSEG1ADDR(KN02_SLOT_BASE +
+ KN02_CSR);
unsigned long flags;
int i;
/* Mask interrupts. */
spin_lock_irqsave(&kn02_lock, flags);
- cached_kn02_csr &= ~KN03_CSR_IOINTEN;
+ cached_kn02_csr &= ~KN02_CSR_IOINTEN;
*csr = cached_kn02_csr;
iob();
spin_unlock_irqrestore(&kn02_lock, flags);
diff --git a/arch/mips/dec/kn02xa-berr.c b/arch/mips/dec/kn02xa-berr.c
new file mode 100644
index 000000000000..6cd3f94f79fe
--- /dev/null
+++ b/arch/mips/dec/kn02xa-berr.c
@@ -0,0 +1,139 @@
+/*
+ * linux/arch/mips/dec/kn02xa-berr.c
+ *
+ * Bus error event handling code for 5000-series systems equipped
+ * with parity error detection logic, i.e. DECstation/DECsystem
+ * 5000/120, /125, /133 (KN02-BA), 5000/150 (KN04-BA) and Personal
+ * DECstation/DECsystem 5000/20, /25, /33 (KN02-CA), 5000/50
+ * (KN04-CA) systems.
+ *
+ * Copyright (c) 2005 Maciej W. Rozycki
+ *
+ * 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/init.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+
+#include <asm/addrspace.h>
+#include <asm/system.h>
+#include <asm/traps.h>
+
+#include <asm/dec/kn02ca.h>
+#include <asm/dec/kn02xa.h>
+#include <asm/dec/kn05.h>
+
+static inline void dec_kn02xa_be_ack(void)
+{
+ volatile u32 *mer = (void *)CKSEG1ADDR(KN02XA_MER);
+ volatile u32 *mem_intr = (void *)CKSEG1ADDR(KN02XA_MEM_INTR);
+
+ *mer = KN02CA_MER_INTR; /* Clear errors; keep the ARC IRQ. */
+ *mem_intr = 0; /* Any write clears the bus IRQ. */
+ iob();
+}
+
+static int dec_kn02xa_be_backend(struct pt_regs *regs, int is_fixup,
+ int invoker)
+{
+ volatile u32 *kn02xa_mer = (void *)CKSEG1ADDR(KN02XA_MER);
+ volatile u32 *kn02xa_ear = (void *)CKSEG1ADDR(KN02XA_EAR);
+
+ static const char excstr[] = "exception";
+ static const char intstr[] = "interrupt";
+ static const char cpustr[] = "CPU";
+ static const char mreadstr[] = "memory read";
+ static const char readstr[] = "read";
+ static const char writestr[] = "write";
+ static const char timestr[] = "timeout";
+ static const char paritystr[] = "parity error";
+ static const char lanestat[][4] = { " OK", "BAD" };
+
+ const char *kind, *agent, *cycle, *event;
+ unsigned long address;
+
+ u32 mer = *kn02xa_mer;
+ u32 ear = *kn02xa_ear;
+ int action = MIPS_BE_FATAL;
+
+ /* Ack ASAP, so that any subsequent errors get caught. */
+ dec_kn02xa_be_ack();
+
+ kind = invoker ? intstr : excstr;
+
+ /* No DMA errors? */
+ agent = cpustr;
+
+ address = ear & KN02XA_EAR_ADDRESS;
+
+ /* Low 256MB is decoded as memory, high -- as TC. */
+ if (address < 0x10000000) {
+ cycle = mreadstr;
+ event = paritystr;
+ } else {
+ cycle = invoker ? writestr : readstr;
+ event = timestr;
+ }
+
+ if (is_fixup)
+ action = MIPS_BE_FIXUP;
+
+ if (action != MIPS_BE_FIXUP)
+ printk(KERN_ALERT "Bus error %s: %s %s %s at %#010lx\n",
+ kind, agent, cycle, event, address);
+
+ if (action != MIPS_BE_FIXUP && address < 0x10000000)
+ printk(KERN_ALERT " Byte lane status %#3x -- "
+ "#3: %s, #2: %s, #1: %s, #0: %s\n",
+ (mer & KN02XA_MER_BYTERR) >> 8,
+ lanestat[(mer & KN02XA_MER_BYTERR_3) != 0],
+ lanestat[(mer & KN02XA_MER_BYTERR_2) != 0],
+ lanestat[(mer & KN02XA_MER_BYTERR_1) != 0],
+ lanestat[(mer & KN02XA_MER_BYTERR_0) != 0]);
+
+ return action;
+}
+
+int dec_kn02xa_be_handler(struct pt_regs *regs, int is_fixup)
+{
+ return dec_kn02xa_be_backend(regs, is_fixup, 0);
+}
+
+irqreturn_t dec_kn02xa_be_interrupt(int irq, void *dev_id,
+ struct pt_regs *regs)
+{
+ int action = dec_kn02xa_be_backend(regs, 0, 1);
+
+ if (action == MIPS_BE_DISCARD)
+ return IRQ_HANDLED;
+
+ /*
+ * FIXME: Find the affected processes and kill them, otherwise
+ * we must die.
+ *
+ * The interrupt is asynchronously delivered thus EPC and RA
+ * may be irrelevant, but are printed for a reference.
+ */
+ printk(KERN_ALERT "Fatal bus interrupt, epc == %08lx, ra == %08lx\n",
+ regs->cp0_epc, regs->regs[31]);
+ die("Unrecoverable bus error", regs);
+}
+
+
+void __init dec_kn02xa_be_init(void)
+{
+ volatile u32 *mbcs = (void *)CKSEG1ADDR(KN4K_SLOT_BASE + KN4K_MB_CSR);
+
+ /* For KN04 we need to make sure EE (?) is enabled in the MB. */
+ if (current_cpu_data.cputype == CPU_R4000SC)
+ *mbcs |= KN4K_MB_CSR_EE;
+ fast_iob();
+
+ /* Clear any leftover errors from the firmware. */
+ dec_kn02xa_be_ack();
+}
diff --git a/arch/mips/dec/prom/identify.c b/arch/mips/dec/prom/identify.c
index 9380588cb15c..81d5e878ddce 100644
--- a/arch/mips/dec/prom/identify.c
+++ b/arch/mips/dec/prom/identify.c
@@ -2,7 +2,7 @@
* identify.c: machine identification code.
*
* Copyright (C) 1998 Harald Koerfgen and Paul M. Antoine
- * Copyright (C) 2002, 2003, 2004 Maciej W. Rozycki
+ * Copyright (C) 2002, 2003, 2004, 2005 Maciej W. Rozycki
*/
#include <linux/init.h>
#include <linux/kernel.h>
@@ -12,6 +12,7 @@
#include <linux/types.h>
#include <asm/bootinfo.h>
+
#include <asm/dec/ioasic.h>
#include <asm/dec/ioasic_addrs.h>
#include <asm/dec/kn01.h>
@@ -21,6 +22,7 @@
#include <asm/dec/kn03.h>
#include <asm/dec/kn230.h>
#include <asm/dec/prom.h>
+#include <asm/dec/system.h>
#include "dectypes.h"
@@ -68,34 +70,44 @@ EXPORT_SYMBOL(dec_rtc_base);
static inline void prom_init_kn01(void)
{
- dec_rtc_base = (void *)KN01_RTC_BASE;
+ dec_kn_slot_base = KN01_SLOT_BASE;
dec_kn_slot_size = KN01_SLOT_SIZE;
+
+ dec_rtc_base = (void *)CKSEG1ADDR(dec_kn_slot_base + KN01_RTC);
}
static inline void prom_init_kn230(void)
{
- dec_rtc_base = (void *)KN01_RTC_BASE;
+ dec_kn_slot_base = KN01_SLOT_BASE;
dec_kn_slot_size = KN01_SLOT_SIZE;
+
+ dec_rtc_base = (void *)CKSEG1ADDR(dec_kn_slot_base + KN01_RTC);
}
static inline void prom_init_kn02(void)
{
- dec_rtc_base = (void *)KN02_RTC_BASE;
+ dec_kn_slot_base = KN02_SLOT_BASE;
dec_kn_slot_size = KN02_SLOT_SIZE;
+
+ dec_rtc_base = (void *)CKSEG1ADDR(dec_kn_slot_base + KN02_RTC);
}
static inline void prom_init_kn02xa(void)
{
- ioasic_base = (void *)KN02XA_IOASIC_BASE;
- dec_rtc_base = (void *)KN02XA_RTC_BASE;
+ dec_kn_slot_base = KN02XA_SLOT_BASE;
dec_kn_slot_size = IOASIC_SLOT_SIZE;
+
+ ioasic_base = (void *)CKSEG1ADDR(dec_kn_slot_base + IOASIC_IOCTL);
+ dec_rtc_base = (void *)CKSEG1ADDR(dec_kn_slot_base + IOASIC_TOY);
}
static inline void prom_init_kn03(void)
{
- ioasic_base = (void *)KN03_IOASIC_BASE;
- dec_rtc_base = (void *)KN03_RTC_BASE;
+ dec_kn_slot_base = KN03_SLOT_BASE;
dec_kn_slot_size = IOASIC_SLOT_SIZE;
+
+ ioasic_base = (void *)CKSEG1ADDR(dec_kn_slot_base + IOASIC_IOCTL);
+ dec_rtc_base = (void *)CKSEG1ADDR(dec_kn_slot_base + IOASIC_TOY);
}
diff --git a/arch/mips/dec/prom/init.c b/arch/mips/dec/prom/init.c
index 60f74256e689..32a7cc7e4c65 100644
--- a/arch/mips/dec/prom/init.c
+++ b/arch/mips/dec/prom/init.c
@@ -6,6 +6,8 @@
*/
#include <linux/config.h>
#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/linkage.h>
#include <linux/smp.h>
#include <linux/string.h>
#include <linux/types.h>
@@ -85,17 +87,13 @@ void __init which_prom(s32 magic, s32 *prom_vec)
void __init prom_init(void)
{
- extern void dec_machine_halt(void);
+ extern void ATTRIB_NORET dec_machine_halt(void);
static char cpu_msg[] __initdata =
"Sorry, this kernel is compiled for a wrong CPU type!\n";
- static char r3k_msg[] __initdata =
- "Please recompile with \"CONFIG_CPU_R3000 = y\".\n";
- static char r4k_msg[] __initdata =
- "Please recompile with \"CONFIG_CPU_R4x00 = y\".\n";
s32 argc = fw_arg0;
- s32 argv = fw_arg1;
+ s32 *argv = (void *)fw_arg1;
u32 magic = fw_arg2;
- s32 prom_vec = fw_arg3;
+ s32 *prom_vec = (void *)fw_arg3;
/*
* Determine which PROM we have
@@ -113,6 +111,8 @@ void __init prom_init(void)
#if defined(CONFIG_CPU_R3000)
if ((current_cpu_data.cputype == CPU_R4000SC) ||
(current_cpu_data.cputype == CPU_R4400SC)) {
+ static char r4k_msg[] __initdata =
+ "Please recompile with \"CONFIG_CPU_R4x00 = y\".\n";
printk(cpu_msg);
printk(r4k_msg);
dec_machine_halt();
@@ -122,6 +122,8 @@ void __init prom_init(void)
#if defined(CONFIG_CPU_R4X00)
if ((current_cpu_data.cputype == CPU_R3000) ||
(current_cpu_data.cputype == CPU_R3000A)) {
+ static char r3k_msg[] __initdata =
+ "Please recompile with \"CONFIG_CPU_R3000 = y\".\n";
printk(cpu_msg);
printk(r3k_msg);
dec_machine_halt();
diff --git a/arch/mips/dec/prom/memory.c b/arch/mips/dec/prom/memory.c
index e4f6f26425ea..83d4556c3cb5 100644
--- a/arch/mips/dec/prom/memory.c
+++ b/arch/mips/dec/prom/memory.c
@@ -35,22 +35,22 @@ static inline void pmax_setup_memory_region(void)
extern char genexcept_early;
/* Install exception handler */
- memcpy(&old_handler, (void *)(KSEG0 + 0x80), 0x80);
- memcpy((void *)(KSEG0 + 0x80), &genexcept_early, 0x80);
+ memcpy(&old_handler, (void *)(CKSEG0 + 0x80), 0x80);
+ memcpy((void *)(CKSEG0 + 0x80), &genexcept_early, 0x80);
/* read unmapped and uncached (KSEG1)
* DECstations have at least 4MB RAM
* Assume less than 480MB of RAM, as this is max for 5000/2xx
* FIXME this should be replaced by the first free page!
*/
- for (memory_page = (unsigned char *) KSEG1 + CHUNK_SIZE;
- (mem_err== 0) && (memory_page < ((unsigned char *) KSEG1+0x1E000000));
+ for (memory_page = (unsigned char *)CKSEG1 + CHUNK_SIZE;
+ mem_err == 0 && memory_page < (unsigned char *)CKSEG1 + 0x1e00000;
memory_page += CHUNK_SIZE) {
dummy = *memory_page;
}
- memcpy((void *)(KSEG0 + 0x80), &old_handler, 0x80);
+ memcpy((void *)(CKSEG0 + 0x80), &old_handler, 0x80);
- add_memory_region(0, (unsigned long)memory_page - KSEG1 - CHUNK_SIZE,
+ add_memory_region(0, (unsigned long)memory_page - CKSEG1 - CHUNK_SIZE,
BOOT_MEM_RAM);
}
@@ -65,7 +65,7 @@ static inline void rex_setup_memory_region(void)
memmap *bm;
/* some free 64k */
- bm = (memmap *)KSEG0ADDR(0x28000);
+ bm = (memmap *)CKSEG0ADDR(0x28000);
bitmap_size = rex_getbitmap(bm);
diff --git a/arch/mips/dec/reset.c b/arch/mips/dec/reset.c
index 7e4d34d0573d..f78c6da47921 100644
--- a/arch/mips/dec/reset.c
+++ b/arch/mips/dec/reset.c
@@ -14,7 +14,7 @@ typedef void ATTRIB_NORET (* noret_func_t)(void);
static inline void ATTRIB_NORET back_to_prom(void)
{
- noret_func_t func = (void *) KSEG1ADDR(0x1fc00000);
+ noret_func_t func = (void *)CKSEG1ADDR(0x1fc00000);
func();
}
diff --git a/arch/mips/dec/setup.c b/arch/mips/dec/setup.c
index 6a69309baf40..9ef54fe1feaa 100644
--- a/arch/mips/dec/setup.c
+++ b/arch/mips/dec/setup.c
@@ -1,19 +1,20 @@
/*
- * Setup the interrupt stuff.
+ * System-specific setup, especially interrupts.
*
* 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) 1998 Harald Koerfgen
- * Copyright (C) 2000, 2001, 2002, 2003 Maciej W. Rozycki
+ * Copyright (C) 2000, 2001, 2002, 2003, 2005 Maciej W. Rozycki
*/
-#include <linux/sched.h>
-#include <linux/interrupt.h>
-#include <linux/param.h>
#include <linux/console.h>
#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
#include <linux/module.h>
+#include <linux/param.h>
+#include <linux/sched.h>
#include <linux/spinlock.h>
#include <linux/types.h>
@@ -38,6 +39,7 @@
#include <asm/dec/kn02ca.h>
#include <asm/dec/kn03.h>
#include <asm/dec/kn230.h>
+#include <asm/dec/system.h>
extern void dec_machine_restart(char *command);
@@ -47,10 +49,16 @@ extern irqreturn_t dec_intr_halt(int irq, void *dev_id, struct pt_regs *regs);
extern asmlinkage void decstation_handle_int(void);
+unsigned long dec_kn_slot_base, dec_kn_slot_size;
+
+EXPORT_SYMBOL(dec_kn_slot_base);
+EXPORT_SYMBOL(dec_kn_slot_size);
+
spinlock_t ioasic_ssr_lock;
volatile u32 *ioasic_base;
-unsigned long dec_kn_slot_size;
+
+EXPORT_SYMBOL(ioasic_base);
/*
* IRQ routing and priority tables. Priorites are set as follows:
@@ -77,6 +85,9 @@ unsigned long dec_kn_slot_size;
int dec_interrupt[DEC_NR_INTS] = {
[0 ... DEC_NR_INTS - 1] = -1
};
+
+EXPORT_SYMBOL(dec_interrupt);
+
int_ptr cpu_mask_nr_tbl[DEC_MAX_CPU_INTS][2] = {
{ { .i = ~0 }, { .p = dec_intr_unimplemented } },
};
@@ -108,11 +119,20 @@ static struct irqaction haltirq = {
/*
* Bus error (DBE/IBE exceptions and bus interrupts) handling setup.
*/
-void __init dec_be_init(void)
+static void __init dec_be_init(void)
{
switch (mips_machtype) {
case MACH_DS23100: /* DS2100/DS3100 Pmin/Pmax */
+ board_be_handler = dec_kn01_be_handler;
+ busirq.handler = dec_kn01_be_interrupt;
busirq.flags |= SA_SHIRQ;
+ dec_kn01_be_init();
+ break;
+ case MACH_DS5000_1XX: /* DS5000/1xx 3min */
+ case MACH_DS5000_XX: /* DS5000/xx Maxine */
+ board_be_handler = dec_kn02xa_be_handler;
+ busirq.handler = dec_kn02xa_be_interrupt;
+ dec_kn02xa_be_init();
break;
case MACH_DS5000_200: /* DS5000/200 3max */
case MACH_DS5000_2X0: /* DS5000/240 3max+ */
@@ -128,7 +148,7 @@ void __init dec_be_init(void)
extern void dec_time_init(void);
extern void dec_timer_setup(struct irqaction *);
-static void __init decstation_setup(void)
+void __init plat_setup(void)
{
board_be_init = dec_be_init;
board_time_init = dec_time_init;
@@ -139,9 +159,10 @@ static void __init decstation_setup(void)
_machine_restart = dec_machine_restart;
_machine_halt = dec_machine_halt;
_machine_power_off = dec_machine_power_off;
-}
-early_initcall(decstation_setup);
+ ioport_resource.start = ~0UL;
+ ioport_resource.end = 0UL;
+}
/*
* Machine-specific initialisation for KN01, aka DS2100 (aka Pmin)
@@ -206,7 +227,7 @@ static int_ptr kn01_cpu_mask_nr_tbl[][2] __initdata = {
{ .p = cpu_all_int } },
};
-void __init dec_init_kn01(void)
+static void __init dec_init_kn01(void)
{
/* IRQ routing. */
memcpy(&dec_interrupt, &kn01_interrupt,
@@ -281,7 +302,7 @@ static int_ptr kn230_cpu_mask_nr_tbl[][2] __initdata = {
{ .p = cpu_all_int } },
};
-void __init dec_init_kn230(void)
+static void __init dec_init_kn230(void)
{
/* IRQ routing. */
memcpy(&dec_interrupt, &kn230_interrupt,
@@ -371,7 +392,7 @@ static int_ptr kn02_asic_mask_nr_tbl[][2] __initdata = {
{ .p = kn02_all_int } },
};
-void __init dec_init_kn02(void)
+static void __init dec_init_kn02(void)
{
/* IRQ routing. */
memcpy(&dec_interrupt, &kn02_interrupt,
@@ -472,7 +493,7 @@ static int_ptr kn02ba_asic_mask_nr_tbl[][2] __initdata = {
{ .p = asic_all_int } },
};
-void __init dec_init_kn02ba(void)
+static void __init dec_init_kn02ba(void)
{
/* IRQ routing. */
memcpy(&dec_interrupt, &kn02ba_interrupt,
@@ -569,7 +590,7 @@ static int_ptr kn02ca_asic_mask_nr_tbl[][2] __initdata = {
{ .p = asic_all_int } },
};
-void __init dec_init_kn02ca(void)
+static void __init dec_init_kn02ca(void)
{
/* IRQ routing. */
memcpy(&dec_interrupt, &kn02ca_interrupt,
@@ -670,7 +691,7 @@ static int_ptr kn03_asic_mask_nr_tbl[][2] __initdata = {
{ .p = asic_all_int } },
};
-void __init dec_init_kn03(void)
+static void __init dec_init_kn03(void)
{
/* IRQ routing. */
memcpy(&dec_interrupt, &kn03_interrupt,
@@ -744,7 +765,3 @@ void __init arch_init_irq(void)
if (dec_interrupt[DEC_IRQ_HALT] >= 0)
setup_irq(dec_interrupt[DEC_IRQ_HALT], &haltirq);
}
-
-EXPORT_SYMBOL(ioasic_base);
-EXPORT_SYMBOL(dec_kn_slot_size);
-EXPORT_SYMBOL(dec_interrupt);
diff --git a/arch/mips/dec/time.c b/arch/mips/dec/time.c
index dc7091caa7aa..174822344131 100644
--- a/arch/mips/dec/time.c
+++ b/arch/mips/dec/time.c
@@ -37,10 +37,25 @@
#include <asm/dec/machtype.h>
+/*
+ * Returns true if a clock update is in progress
+ */
+static inline unsigned char dec_rtc_is_updating(void)
+{
+ unsigned char uip;
+ unsigned long flags;
+
+ spin_lock_irqsave(&rtc_lock, flags);
+ uip = (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP);
+ spin_unlock_irqrestore(&rtc_lock, flags);
+ return uip;
+}
+
static unsigned long dec_rtc_get_time(void)
{
unsigned int year, mon, day, hour, min, sec, real_year;
int i;
+ unsigned long flags;
/* The Linux interpretation of the DS1287 clock register contents:
* When the Update-In-Progress (UIP) flag goes from 1 to 0, the
@@ -49,11 +64,12 @@ static unsigned long dec_rtc_get_time(void)
*/
/* read RTC exactly on falling edge of update flag */
for (i = 0; i < 1000000; i++) /* may take up to 1 second... */
- if (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP)
+ if (dec_rtc_is_updating())
break;
for (i = 0; i < 1000000; i++) /* must try at least 2.228 ms */
- if (!(CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP))
+ if (!dec_rtc_is_updating())
break;
+ spin_lock_irqsave(&rtc_lock, flags);
/* Isn't this overkill? UIP above should guarantee consistency */
do {
sec = CMOS_READ(RTC_SECONDS);
@@ -77,6 +93,7 @@ static unsigned long dec_rtc_get_time(void)
* of unused BBU RAM locations.
*/
real_year = CMOS_READ(RTC_DEC_YEAR);
+ spin_unlock_irqrestore(&rtc_lock, flags);
year += real_year - 72 + 2000;
return mktime(year, mon, day, hour, min, sec);
@@ -95,6 +112,8 @@ static int dec_rtc_set_mmss(unsigned long nowtime)
int real_seconds, real_minutes, cmos_minutes;
unsigned char save_control, save_freq_select;
+ /* irq are locally disabled here */
+ spin_lock(&rtc_lock);
/* tell the clock it's being set */
save_control = CMOS_READ(RTC_CONTROL);
CMOS_WRITE((save_control | RTC_SET), RTC_CONTROL);
@@ -141,6 +160,7 @@ static int dec_rtc_set_mmss(unsigned long nowtime)
*/
CMOS_WRITE(save_control, RTC_CONTROL);
CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT);
+ spin_unlock(&rtc_lock);
return retval;
}
diff --git a/arch/mips/defconfig b/arch/mips/defconfig
index 20f84b119b4c..4b585e642c2a 100644
--- a/arch/mips/defconfig
+++ b/arch/mips/defconfig
@@ -1,12 +1,9 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-rc2
-# Wed Jan 26 02:48:59 2005
+# Linux kernel version: 2.6.14-rc2
+# Thu Oct 20 22:25:09 2005
#
CONFIG_MIPS=y
-# CONFIG_64BIT is not set
-# CONFIG_64BIT is not set
-CONFIG_32BIT=y
#
# Code maturity level options
@@ -14,25 +11,30 @@ CONFIG_32BIT=y
CONFIG_EXPERIMENTAL=y
CONFIG_CLEAN_COMPILE=y
CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
#
# General setup
#
CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
# CONFIG_POSIX_MQUEUE is not set
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
# CONFIG_HOTPLUG is not set
CONFIG_KOBJECT_UEVENT=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
+CONFIG_INITRAMFS_SOURCE=""
CONFIG_EMBEDDED=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
@@ -42,6 +44,7 @@ CONFIG_CC_ALIGN_LABELS=0
CONFIG_CC_ALIGN_LOOPS=0
CONFIG_CC_ALIGN_JUMPS=0
# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
#
# Loadable module support
@@ -57,41 +60,69 @@ CONFIG_KMOD=y
#
# Machine selection
#
-# CONFIG_MACH_JAZZ is not set
-# CONFIG_MACH_VR41XX is not set
-# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_MIPS_PB1550 is not set
+# CONFIG_MIPS_PB1200 is not set
+# CONFIG_MIPS_DB1000 is not set
+# CONFIG_MIPS_DB1100 is not set
+# CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
+# CONFIG_MIPS_DB1200 is not set
+# CONFIG_MIPS_MIRAGE is not set
# CONFIG_MIPS_COBALT is not set
# CONFIG_MACH_DECSTATION is not set
# CONFIG_MIPS_EV64120 is not set
# CONFIG_MIPS_EV96100 is not set
# CONFIG_MIPS_IVR is not set
-# CONFIG_LASAT is not set
# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_LASAT is not set
# CONFIG_MIPS_ATLAS is not set
# CONFIG_MIPS_MALTA is not set
# CONFIG_MIPS_SEAD is not set
+# CONFIG_MIPS_SIM is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
# CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_G is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_JAGUAR_ATX is not set
-# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MIPS_XXS1500 is not set
+# CONFIG_PNX8550_V2PCI is not set
+# CONFIG_PNX8550_JBS is not set
# CONFIG_DDB5074 is not set
# CONFIG_DDB5476 is not set
# CONFIG_DDB5477 is not set
-# CONFIG_NEC_OSPREY is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_QEMU is not set
CONFIG_SGI_IP22=y
-# CONFIG_SOC_AU1X00 is not set
-# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_BIGSUR is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_PTSWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CRHONE is not set
# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
# CONFIG_TOSHIBA_RBTX4927 is not set
+# CONFIG_TOSHIBA_RBTX4938 is not set
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_HAVE_DEC_LOCK=y
CONFIG_ARC=y
CONFIG_DMA_NONCOHERENT=y
CONFIG_DMA_NEED_PCI_MAP_STATE=y
+CONFIG_CPU_BIG_ENDIAN=y
# CONFIG_CPU_LITTLE_ENDIAN is not set
+CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
CONFIG_IRQ_CPU=y
CONFIG_SWAP_IO_SPACE=y
CONFIG_ARC32=y
@@ -103,8 +134,10 @@ CONFIG_ARC_PROMLIB=y
#
# CPU selection
#
-# CONFIG_CPU_MIPS32 is not set
-# CONFIG_CPU_MIPS64 is not set
+# CONFIG_CPU_MIPS32_R1 is not set
+# CONFIG_CPU_MIPS32_R2 is not set
+# CONFIG_CPU_MIPS64_R1 is not set
+# CONFIG_CPU_MIPS64_R2 is not set
# CONFIG_CPU_R3000 is not set
# CONFIG_CPU_TX39XX is not set
# CONFIG_CPU_VR41XX is not set
@@ -120,22 +153,48 @@ CONFIG_CPU_R5000=y
# CONFIG_CPU_RM7000 is not set
# CONFIG_CPU_RM9000 is not set
# CONFIG_CPU_SB1 is not set
+CONFIG_SYS_HAS_CPU_R4X00=y
+CONFIG_SYS_HAS_CPU_R5000=y
+CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
+CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y
+
+#
+# Kernel type
+#
+CONFIG_32BIT=y
+# CONFIG_64BIT is not set
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_BOARD_SCACHE=y
CONFIG_IP22_CPU_SCACHE=y
+# CONFIG_MIPS_MT is not set
# CONFIG_64BIT_PHYS_ADDR is not set
# CONFIG_CPU_ADVANCED is not set
CONFIG_CPU_HAS_LLSC=y
CONFIG_CPU_HAS_LLDSCD=y
CONFIG_CPU_HAS_SYNC=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_ARCH_FLATMEM_ENABLE=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_PREEMPT_NONE is not set
+CONFIG_PREEMPT_VOLUNTARY=y
# CONFIG_PREEMPT is not set
#
# Bus options (PCI, PCMCIA, EISA, ISA, TC)
#
+CONFIG_HW_HAS_EISA=y
# CONFIG_EISA is not set
CONFIG_MMU=y
@@ -145,10 +204,6 @@ CONFIG_MMU=y
# CONFIG_PCCARD is not set
#
-# PC-card bridges
-#
-
-#
# PCI Hotplug Support
#
@@ -160,115 +215,7 @@ CONFIG_BINFMT_MISC=m
CONFIG_TRAD_SIGNALS=y
#
-# Device Drivers
-#
-
-#
-# Generic Driver Options
-#
-CONFIG_STANDALONE=y
-CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
-
-#
-# Memory Technology Devices (MTD)
-#
-# CONFIG_MTD is not set
-
-#
-# Parallel port support
-#
-# CONFIG_PARPORT is not set
-
-#
-# Plug and Play support
-#
-
-#
-# Block devices
-#
-# CONFIG_BLK_DEV_FD is not set
-# CONFIG_BLK_DEV_COW_COMMON is not set
-# CONFIG_BLK_DEV_LOOP is not set
-# CONFIG_BLK_DEV_NBD is not set
-# CONFIG_BLK_DEV_RAM is not set
-CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_INITRAMFS_SOURCE=""
-# CONFIG_LBD is not set
-CONFIG_CDROM_PKTCDVD=m
-CONFIG_CDROM_PKTCDVD_BUFFERS=8
-# CONFIG_CDROM_PKTCDVD_WCACHE is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-CONFIG_ATA_OVER_ETH=m
-
-#
-# ATA/ATAPI/MFM/RLL support
-#
-# CONFIG_IDE is not set
-
-#
-# SCSI device support
-#
-CONFIG_SCSI=y
-CONFIG_SCSI_PROC_FS=y
-
-#
-# SCSI support type (disk, tape, CD-ROM)
-#
-CONFIG_BLK_DEV_SD=y
-CONFIG_CHR_DEV_ST=y
-# CONFIG_CHR_DEV_OSST is not set
-CONFIG_BLK_DEV_SR=y
-# CONFIG_BLK_DEV_SR_VENDOR is not set
-# CONFIG_CHR_DEV_SG is not set
-
-#
-# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
-#
-# CONFIG_SCSI_MULTI_LUN is not set
-CONFIG_SCSI_CONSTANTS=y
-# CONFIG_SCSI_LOGGING is not set
-
-#
-# SCSI Transport Attributes
-#
-CONFIG_SCSI_SPI_ATTRS=m
-# CONFIG_SCSI_FC_ATTRS is not set
-CONFIG_SCSI_ISCSI_ATTRS=m
-
-#
-# SCSI low-level drivers
-#
-CONFIG_SGIWD93_SCSI=y
-# CONFIG_SCSI_SATA is not set
-# CONFIG_SCSI_DEBUG is not set
-
-#
-# Multi-device support (RAID and LVM)
-#
-# CONFIG_MD is not set
-
-#
-# Fusion MPT device support
-#
-
-#
-# IEEE 1394 (FireWire) support
-#
-
-#
-# I2O device support
-#
-
-#
-# Networking support
+# Networking
#
CONFIG_NET=y
@@ -277,12 +224,14 @@ CONFIG_NET=y
#
CONFIG_PACKET=y
CONFIG_PACKET_MMAP=y
-CONFIG_NETLINK_DEV=y
CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
CONFIG_NET_KEY=y
CONFIG_INET=y
CONFIG_IP_MULTICAST=y
# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
CONFIG_IP_PNP=y
# CONFIG_IP_PNP_DHCP is not set
CONFIG_IP_PNP_BOOTP=y
@@ -296,8 +245,10 @@ CONFIG_INET_AH=m
CONFIG_INET_ESP=m
CONFIG_INET_IPCOMP=m
CONFIG_INET_TUNNEL=m
-CONFIG_IP_TCPDIAG=m
-CONFIG_IP_TCPDIAG_IPV6=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
#
# IP: Virtual Server Configuration
@@ -341,6 +292,9 @@ CONFIG_INET6_TUNNEL=m
CONFIG_IPV6_TUNNEL=m
CONFIG_NETFILTER=y
# CONFIG_NETFILTER_DEBUG is not set
+CONFIG_NETFILTER_NETLINK=m
+CONFIG_NETFILTER_NETLINK_QUEUE=m
+CONFIG_NETFILTER_NETLINK_LOG=m
#
# IP: Netfilter Configuration
@@ -348,11 +302,15 @@ CONFIG_NETFILTER=y
CONFIG_IP_NF_CONNTRACK=m
CONFIG_IP_NF_CT_ACCT=y
CONFIG_IP_NF_CONNTRACK_MARK=y
+CONFIG_IP_NF_CONNTRACK_EVENTS=y
+CONFIG_IP_NF_CONNTRACK_NETLINK=m
# CONFIG_IP_NF_CT_PROTO_SCTP is not set
CONFIG_IP_NF_FTP=m
CONFIG_IP_NF_IRC=m
+# CONFIG_IP_NF_NETBIOS_NS is not set
CONFIG_IP_NF_TFTP=m
CONFIG_IP_NF_AMANDA=m
+CONFIG_IP_NF_PPTP=m
CONFIG_IP_NF_QUEUE=m
CONFIG_IP_NF_IPTABLES=m
CONFIG_IP_NF_MATCH_LIMIT=m
@@ -376,9 +334,12 @@ CONFIG_IP_NF_MATCH_OWNER=m
CONFIG_IP_NF_MATCH_ADDRTYPE=m
CONFIG_IP_NF_MATCH_REALM=m
CONFIG_IP_NF_MATCH_SCTP=m
+CONFIG_IP_NF_MATCH_DCCP=m
CONFIG_IP_NF_MATCH_COMMENT=m
CONFIG_IP_NF_MATCH_CONNMARK=m
+CONFIG_IP_NF_MATCH_CONNBYTES=m
CONFIG_IP_NF_MATCH_HASHLIMIT=m
+CONFIG_IP_NF_MATCH_STRING=m
CONFIG_IP_NF_FILTER=m
CONFIG_IP_NF_TARGET_REJECT=m
CONFIG_IP_NF_TARGET_LOG=m
@@ -395,12 +356,14 @@ CONFIG_IP_NF_NAT_IRC=m
CONFIG_IP_NF_NAT_FTP=m
CONFIG_IP_NF_NAT_TFTP=m
CONFIG_IP_NF_NAT_AMANDA=m
+CONFIG_IP_NF_NAT_PPTP=m
CONFIG_IP_NF_MANGLE=m
CONFIG_IP_NF_TARGET_TOS=m
CONFIG_IP_NF_TARGET_ECN=m
CONFIG_IP_NF_TARGET_DSCP=m
CONFIG_IP_NF_TARGET_MARK=m
CONFIG_IP_NF_TARGET_CLASSIFY=m
+CONFIG_IP_NF_TARGET_TTL=m
CONFIG_IP_NF_TARGET_CONNMARK=m
CONFIG_IP_NF_TARGET_CLUSTERIP=m
CONFIG_IP_NF_RAW=m
@@ -410,7 +373,7 @@ CONFIG_IP_NF_ARPFILTER=m
CONFIG_IP_NF_ARP_MANGLE=m
#
-# IPv6: Netfilter Configuration
+# IPv6: Netfilter Configuration (EXPERIMENTAL)
#
CONFIG_IP6_NF_QUEUE=m
CONFIG_IP6_NF_IPTABLES=m
@@ -429,11 +392,16 @@ CONFIG_IP6_NF_MATCH_LENGTH=m
CONFIG_IP6_NF_MATCH_EUI64=m
CONFIG_IP6_NF_FILTER=m
CONFIG_IP6_NF_TARGET_LOG=m
+CONFIG_IP6_NF_TARGET_REJECT=m
CONFIG_IP6_NF_MANGLE=m
CONFIG_IP6_NF_TARGET_MARK=m
+CONFIG_IP6_NF_TARGET_HL=m
CONFIG_IP6_NF_RAW=m
-CONFIG_XFRM=y
-CONFIG_XFRM_USER=m
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
#
# SCTP Configuration (EXPERIMENTAL)
@@ -456,10 +424,6 @@ CONFIG_SCTP_HMAC_MD5=y
CONFIG_NET_DIVERT=y
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
CONFIG_NET_SCHED=y
# CONFIG_NET_SCH_CLK_JIFFIES is not set
CONFIG_NET_SCH_CLK_GETTIMEOFDAY=y
@@ -479,6 +443,7 @@ CONFIG_NET_SCH_INGRESS=m
CONFIG_NET_QOS=y
CONFIG_NET_ESTIMATOR=y
CONFIG_NET_CLS=y
+CONFIG_NET_CLS_BASIC=m
CONFIG_NET_CLS_TCINDEX=m
CONFIG_NET_CLS_ROUTE4=m
CONFIG_NET_CLS_ROUTE=y
@@ -489,6 +454,7 @@ CONFIG_NET_CLS_U32=m
# CONFIG_CLS_U32_MARK is not set
CONFIG_NET_CLS_RSVP=m
CONFIG_NET_CLS_RSVP6=m
+# CONFIG_NET_EMATCH is not set
# CONFIG_NET_CLS_ACT is not set
CONFIG_NET_CLS_POLICE=y
@@ -496,17 +462,153 @@ CONFIG_NET_CLS_POLICE=y
# Network testing
#
# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
# CONFIG_HAMRADIO is not set
# CONFIG_IRDA is not set
# CONFIG_BT is not set
+CONFIG_IEEE80211=m
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=m
+CONFIG_IEEE80211_CRYPT_CCMP=m
+CONFIG_IEEE80211_CRYPT_TKIP=m
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+CONFIG_CONNECTOR=m
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_RAM is not set
+CONFIG_BLK_DEV_RAM_COUNT=16
+# CONFIG_LBD is not set
+CONFIG_CDROM_PKTCDVD=m
+CONFIG_CDROM_PKTCDVD_BUFFERS=8
+# CONFIG_CDROM_PKTCDVD_WCACHE is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_ATA_OVER_ETH=m
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+CONFIG_RAID_ATTRS=m
+CONFIG_SCSI=y
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_ST=y
+# CONFIG_CHR_DEV_OSST is not set
+CONFIG_BLK_DEV_SR=y
+# CONFIG_BLK_DEV_SR_VENDOR is not set
+# CONFIG_CHR_DEV_SG is not set
+CONFIG_CHR_DEV_SCH=m
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# CONFIG_SCSI_MULTI_LUN is not set
+CONFIG_SCSI_CONSTANTS=y
+# CONFIG_SCSI_LOGGING is not set
+
+#
+# SCSI Transport Attributes
+#
+CONFIG_SCSI_SPI_ATTRS=m
+# CONFIG_SCSI_FC_ATTRS is not set
+CONFIG_SCSI_ISCSI_ATTRS=m
+CONFIG_SCSI_SAS_ATTRS=m
+
+#
+# SCSI low-level drivers
+#
+CONFIG_SGIWD93_SCSI=y
+# CONFIG_SCSI_SATA is not set
+# CONFIG_SCSI_DEBUG is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+
+#
+# I2O device support
+#
+
+#
+# Network device support
+#
CONFIG_NETDEVICES=y
CONFIG_DUMMY=m
CONFIG_BONDING=m
CONFIG_EQUALIZER=m
CONFIG_TUN=m
-CONFIG_ETHERTAP=m
+
+#
+# PHY device support
+#
+CONFIG_PHYLIB=m
+CONFIG_PHYCONTROL=y
+
+#
+# MII PHY device drivers
+#
+CONFIG_MARVELL_PHY=m
+CONFIG_DAVICOM_PHY=m
+CONFIG_QSEMI_PHY=m
+CONFIG_LXT_PHY=m
+CONFIG_CICADA_PHY=m
#
# Ethernet (10 or 100Mbit)
@@ -540,6 +642,8 @@ CONFIG_SGISEEQ=y
# CONFIG_SLIP is not set
# CONFIG_SHAPER is not set
# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
#
# ISDN subsystem
@@ -569,18 +673,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
# CONFIG_INPUT_EVBUG is not set
#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=y
-CONFIG_SERIO_I8042=y
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_CT82C710 is not set
-CONFIG_SERIO_LIBPS2=y
-CONFIG_SERIO_RAW=m
-
-#
# Input Device Drivers
#
CONFIG_INPUT_KEYBOARD=y
@@ -598,6 +690,16 @@ CONFIG_MOUSE_SERIAL=m
# CONFIG_INPUT_MISC is not set
#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_I8042=y
+CONFIG_SERIO_SERPORT=y
+CONFIG_SERIO_LIBPS2=y
+CONFIG_SERIO_RAW=m
+# CONFIG_GAMEPORT is not set
+
+#
# Character devices
#
CONFIG_VT=y
@@ -644,11 +746,14 @@ CONFIG_SGI_DS1286=m
#
# Ftape, the floppy tape device driver
#
-# CONFIG_DRM is not set
CONFIG_RAW_DRIVER=m
CONFIG_MAX_RAW_DEVS=256
#
+# TPM devices
+#
+
+#
# I2C support
#
# CONFIG_I2C is not set
@@ -659,10 +764,20 @@ CONFIG_MAX_RAW_DEVS=256
# CONFIG_W1 is not set
#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
+#
# Misc devices
#
#
+# Multimedia Capabilities Port drivers
+#
+
+#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
@@ -693,7 +808,6 @@ CONFIG_LOGO=y
# CONFIG_LOGO_LINUX_VGA16 is not set
# CONFIG_LOGO_LINUX_CLUT224 is not set
CONFIG_LOGO_SGI_CLUT224=y
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Sound
@@ -707,10 +821,6 @@ CONFIG_LOGO_SGI_CLUT224=y
# CONFIG_USB_ARCH_HAS_OHCI is not set
#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
-#
-
-#
# USB Gadget Support
#
# CONFIG_USB_GADGET is not set
@@ -723,13 +833,17 @@ CONFIG_LOGO_SGI_CLUT224=y
#
# InfiniBand support
#
-# CONFIG_INFINIBAND is not set
+
+#
+# SN Devices
+#
#
# File systems
#
CONFIG_EXT2_FS=m
# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
CONFIG_EXT3_FS=y
CONFIG_EXT3_FS_XATTR=y
CONFIG_EXT3_FS_POSIX_ACL=y
@@ -741,12 +855,14 @@ CONFIG_FS_MBCACHE=y
# CONFIG_JFS_FS is not set
CONFIG_FS_POSIX_ACL=y
CONFIG_XFS_FS=m
-# CONFIG_XFS_RT is not set
-CONFIG_XFS_QUOTA=y
+CONFIG_XFS_EXPORT=y
+CONFIG_XFS_QUOTA=m
CONFIG_XFS_SECURITY=y
# CONFIG_XFS_POSIX_ACL is not set
+# CONFIG_XFS_RT is not set
CONFIG_MINIX_FS=m
# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
CONFIG_QUOTA=y
# CONFIG_QFMT_V1 is not set
CONFIG_QFMT_V2=m
@@ -754,6 +870,7 @@ CONFIG_QUOTACTL=y
CONFIG_DNOTIFY=y
CONFIG_AUTOFS_FS=m
CONFIG_AUTOFS4_FS=m
+CONFIG_FUSE_FS=m
#
# CD-ROM/DVD Filesystems
@@ -781,12 +898,10 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
-CONFIG_DEVPTS_FS_XATTR=y
-CONFIG_DEVPTS_FS_SECURITY=y
# CONFIG_TMPFS is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
+CONFIG_RELAYFS_FS=m
#
# Miscellaneous filesystems
@@ -811,15 +926,20 @@ CONFIG_UFS_FS=m
#
CONFIG_NFS_FS=m
CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
# CONFIG_NFS_V4 is not set
# CONFIG_NFS_DIRECTIO is not set
CONFIG_NFSD=m
+CONFIG_NFSD_V2_ACL=y
CONFIG_NFSD_V3=y
+CONFIG_NFSD_V3_ACL=y
# CONFIG_NFSD_V4 is not set
CONFIG_NFSD_TCP=y
CONFIG_LOCKD=m
CONFIG_LOCKD_V4=y
CONFIG_EXPORTFS=m
+CONFIG_NFS_ACL_SUPPORT=m
+CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=m
CONFIG_SUNRPC_GSS=m
CONFIG_RPCSEC_GSS_KRB5=m
@@ -835,6 +955,7 @@ CONFIG_CIFS=m
CONFIG_CODA_FS=m
# CONFIG_CODA_FS_OLD_API is not set
# CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
#
# Partition Types
@@ -908,7 +1029,9 @@ CONFIG_NLS_UTF8=m
#
# Kernel hacking
#
+# CONFIG_PRINTK_TIME is not set
# CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=14
CONFIG_CROSSCOMPILE=y
CONFIG_CMDLINE=""
@@ -931,6 +1054,7 @@ CONFIG_CRYPTO_SHA1=m
CONFIG_CRYPTO_SHA256=m
CONFIG_CRYPTO_SHA512=m
CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_TGR192=m
CONFIG_CRYPTO_DES=m
CONFIG_CRYPTO_BLOWFISH=m
CONFIG_CRYPTO_TWOFISH=m
@@ -942,10 +1066,10 @@ CONFIG_CRYPTO_TEA=m
CONFIG_CRYPTO_ARC4=m
CONFIG_CRYPTO_KHAZAD=m
CONFIG_CRYPTO_ANUBIS=m
-CONFIG_CRYPTO_DEFLATE=y
+CONFIG_CRYPTO_DEFLATE=m
CONFIG_CRYPTO_MICHAEL_MIC=m
CONFIG_CRYPTO_CRC32C=m
-CONFIG_CRYPTO_TEST=m
+# CONFIG_CRYPTO_TEST is not set
#
# Hardware crypto devices
@@ -955,9 +1079,12 @@ CONFIG_CRYPTO_TEST=m
# Library routines
#
# CONFIG_CRC_CCITT is not set
+CONFIG_CRC16=m
CONFIG_CRC32=m
CONFIG_LIBCRC32C=m
-CONFIG_ZLIB_INFLATE=y
-CONFIG_ZLIB_DEFLATE=y
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_ZLIB_INFLATE=m
+CONFIG_ZLIB_DEFLATE=m
+CONFIG_TEXTSEARCH=y
+CONFIG_TEXTSEARCH_KMP=m
+CONFIG_TEXTSEARCH_BM=m
+CONFIG_TEXTSEARCH_FSM=m
diff --git a/arch/mips/galileo-boards/ev96100/setup.c b/arch/mips/galileo-boards/ev96100/setup.c
index 28bd908c6d55..78dbb18edeb8 100644
--- a/arch/mips/galileo-boards/ev96100/setup.c
+++ b/arch/mips/galileo-boards/ev96100/setup.c
@@ -55,7 +55,7 @@ extern void mips_reboot_setup(void);
unsigned char mac_0_1[12];
-static void __init ev96100_setup(void)
+void __init plat_setup(void)
{
unsigned int config = read_c0_config();
unsigned int status = read_c0_status();
@@ -142,8 +142,6 @@ static void __init ev96100_setup(void)
tmp = GT_READ(GT_PCI0_CFGDATA_OFS);
}
-early_initcall(ev96100_setup);
-
unsigned short get_gt_devid(void)
{
u32 gt_devid;
diff --git a/arch/mips/gt64120/ev64120/Kconfig b/arch/mips/gt64120/ev64120/Kconfig
new file mode 100644
index 000000000000..d691762cb0f7
--- /dev/null
+++ b/arch/mips/gt64120/ev64120/Kconfig
@@ -0,0 +1,3 @@
+config EVB_PCI1
+ bool "Enable Second PCI (PCI1)"
+ depends on MIPS_EV64120
diff --git a/arch/mips/gt64120/ev64120/setup.c b/arch/mips/gt64120/ev64120/setup.c
index dba0961400cc..98b5a96cc039 100644
--- a/arch/mips/gt64120/ev64120/setup.c
+++ b/arch/mips/gt64120/ev64120/setup.c
@@ -69,7 +69,7 @@ unsigned long __init prom_free_prom_memory(void)
*/
extern void gt64120_time_init(void);
-static void __init ev64120_setup(void)
+void __init plat_setup(void)
{
_machine_restart = galileo_machine_restart;
_machine_halt = galileo_machine_halt;
@@ -79,8 +79,6 @@ static void __init ev64120_setup(void)
set_io_port_base(KSEG1);
}
-early_initcall(ev64120_setup);
-
const char *get_system_type(void)
{
return "Galileo EV64120A";
diff --git a/arch/mips/gt64120/momenco_ocelot/setup.c b/arch/mips/gt64120/momenco_ocelot/setup.c
index d610f8c17c81..0d07c33112d0 100644
--- a/arch/mips/gt64120/momenco_ocelot/setup.c
+++ b/arch/mips/gt64120/momenco_ocelot/setup.c
@@ -150,7 +150,7 @@ void PMON_v2_setup()
gt64120_base = 0xe0000000;
}
-static void __init momenco_ocelot_setup(void)
+void __init plat_setup(void)
{
void (*l3func)(unsigned long)=KSEG1ADDR(&setup_l3cache);
unsigned int tmpword;
@@ -307,8 +307,6 @@ static void __init momenco_ocelot_setup(void)
GT_WRITE(GT_DEV_B3_OFS, 0xfef73);
}
-early_initcall(momenco_ocelot_setup);
-
extern int rm7k_tcache_enabled;
/*
* This runs in KSEG1. See the verbiage in rm7k.c::probe_scache()
diff --git a/arch/mips/ite-boards/Kconfig b/arch/mips/ite-boards/Kconfig
new file mode 100644
index 000000000000..a6d59ad8f846
--- /dev/null
+++ b/arch/mips/ite-boards/Kconfig
@@ -0,0 +1,8 @@
+config IT8172_REVC
+ bool "Support for older IT8172 (Rev C)"
+ depends on MIPS_ITE8172
+ help
+ Say Y here to support the older, Revision C version of the Integrated
+ Technology Express, Inc. ITE8172 SBC. Vendor page at
+ <http://www.ite.com.tw/ia/brief_it8172bsp.htm>; picture of the
+ board at <http://www.mvista.com/partners/semiconductor/ite.html>.
diff --git a/arch/mips/ite-boards/generic/irq.c b/arch/mips/ite-boards/generic/irq.c
index cb71b9024d6f..e67f96129491 100644
--- a/arch/mips/ite-boards/generic/irq.c
+++ b/arch/mips/ite-boards/generic/irq.c
@@ -138,14 +138,13 @@ static void end_ite_irq(unsigned int irq)
}
static struct hw_interrupt_type it8172_irq_type = {
- "ITE8172",
- startup_ite_irq,
- shutdown_ite_irq,
- enable_it8172_irq,
- disable_it8172_irq,
- mask_and_ack_ite_irq,
- end_ite_irq,
- NULL
+ .typename = "ITE8172",
+ .startup = startup_ite_irq,
+ .shutdown = shutdown_ite_irq,
+ .enable = enable_it8172_irq,
+ .disable = disable_it8172_irq,
+ .ack = mask_and_ack_ite_irq,
+ .end = end_ite_irq,
};
@@ -159,13 +158,13 @@ static void ack_none(unsigned int irq) { }
#define end_none enable_none
static struct hw_interrupt_type cp0_irq_type = {
- "CP0 Count",
- startup_none,
- shutdown_none,
- enable_none,
- disable_none,
- ack_none,
- end_none
+ .typename = "CP0 Count",
+ .startup = startup_none,
+ .shutdown = shutdown_none,
+ .enable = enable_none,
+ .disable = disable_none,
+ .ack = ack_none,
+ .end = end_none
};
void enable_cpu_timer(void)
@@ -182,7 +181,6 @@ void __init arch_init_irq(void)
int i;
unsigned long flags;
- memset(irq_desc, 0, sizeof(irq_desc));
set_except_vector(0, it8172_IRQ);
/* mask all interrupts */
diff --git a/arch/mips/ite-boards/generic/it8172_setup.c b/arch/mips/ite-boards/generic/it8172_setup.c
index a5f6d84bc181..062429dd7ca0 100644
--- a/arch/mips/ite-boards/generic/it8172_setup.c
+++ b/arch/mips/ite-boards/generic/it8172_setup.c
@@ -105,7 +105,7 @@ void __init it8172_init_ram_resource(unsigned long memsize)
it8172_resources.ram.end = memsize;
}
-static void __init it8172_setup(void)
+void __init plat_setup(void)
{
unsigned short dsr;
char *argptr;
@@ -251,8 +251,6 @@ static void __init it8172_setup(void)
#endif /* CONFIG_IT8172_SCR1 */
}
-early_initcall(it8172_setup);
-
#ifdef CONFIG_SERIO_I8042
/*
* According to the ITE Special BIOS Note for waking up the
diff --git a/arch/mips/jazz/Kconfig b/arch/mips/jazz/Kconfig
new file mode 100644
index 000000000000..1f372b0d2559
--- /dev/null
+++ b/arch/mips/jazz/Kconfig
@@ -0,0 +1,33 @@
+config ACER_PICA_61
+ bool "Support for Acer PICA 1 chipset (EXPERIMENTAL)"
+ depends on MACH_JAZZ && EXPERIMENTAL
+ select DMA_NONCOHERENT
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+ help
+ This is a machine with a R4400 133/150 MHz CPU. To compile a Linux
+ kernel that runs on these, say Y here. For details about Linux on
+ the MIPS architecture, check out the Linux/MIPS FAQ on the WWW at
+ <http://www.linux-mips.org/>.
+
+config MIPS_MAGNUM_4000
+ bool "Support for MIPS Magnum 4000"
+ depends on MACH_JAZZ
+ select DMA_NONCOHERENT
+ select SYS_SUPPORTS_BIG_ENDIAN if EXPERIMENTAL
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+ help
+ This is a machine with a R4000 100 MHz CPU. To compile a Linux
+ kernel that runs on these, say Y here. For details about Linux on
+ the MIPS architecture, check out the Linux/MIPS FAQ on the WWW at
+ <http://www.linux-mips.org/>.
+
+config OLIVETTI_M700
+ bool "Support for Olivetti M700-10"
+ depends on MACH_JAZZ
+ select DMA_NONCOHERENT
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+ help
+ This is a machine with a R4000 100 MHz CPU. To compile a Linux
+ kernel that runs on these, say Y here. For details about Linux on
+ the MIPS architecture, check out the Linux/MIPS FAQ on the WWW at
+ <http://www.linux-mips.org/>.
diff --git a/arch/mips/jazz/irq.c b/arch/mips/jazz/irq.c
index 0b608fa98d5a..b309b1bcf2e8 100644
--- a/arch/mips/jazz/irq.c
+++ b/arch/mips/jazz/irq.c
@@ -58,14 +58,13 @@ static void end_r4030_irq(unsigned int irq)
}
static struct hw_interrupt_type r4030_irq_type = {
- "R4030",
- startup_r4030_irq,
- shutdown_r4030_irq,
- enable_r4030_irq,
- disable_r4030_irq,
- mask_and_ack_r4030_irq,
- end_r4030_irq,
- NULL
+ .typename = "R4030",
+ .startup = startup_r4030_irq,
+ .shutdown = shutdown_r4030_irq,
+ .enable = enable_r4030_irq,
+ .disable = disable_r4030_irq,
+ .ack = mask_and_ack_r4030_irq,
+ .end = end_r4030_irq,
};
void __init init_r4030_ints(void)
diff --git a/arch/mips/jazz/setup.c b/arch/mips/jazz/setup.c
index fccb06fe209d..044df9d4ab7c 100644
--- a/arch/mips/jazz/setup.c
+++ b/arch/mips/jazz/setup.c
@@ -50,7 +50,7 @@ static struct resource jazz_io_resources[] = {
{ "dma2", 0xc0, 0xdf, IORESOURCE_BUSY },
};
-static void __init jazz_setup(void)
+void __init plat_setup(void)
{
int i;
@@ -97,5 +97,3 @@ static void __init jazz_setup(void)
vdma_init();
}
-
-early_initcall(jazz_setup);
diff --git a/arch/mips/jmr3927/common/rtc_ds1742.c b/arch/mips/jmr3927/common/rtc_ds1742.c
index 1ae4318e1358..8b407d7dc460 100644
--- a/arch/mips/jmr3927/common/rtc_ds1742.c
+++ b/arch/mips/jmr3927/common/rtc_ds1742.c
@@ -57,7 +57,9 @@ rtc_ds1742_get_time(void)
{
unsigned int year, month, day, hour, minute, second;
unsigned int century;
+ unsigned long flags;
+ spin_lock_irqsave(&rtc_lock, flags);
CMOS_WRITE(RTC_READ, RTC_CONTROL);
second = BCD2BIN(CMOS_READ(RTC_SECONDS) & RTC_SECONDS_MASK);
minute = BCD2BIN(CMOS_READ(RTC_MINUTES));
@@ -67,6 +69,7 @@ rtc_ds1742_get_time(void)
year = BCD2BIN(CMOS_READ(RTC_YEAR));
century = BCD2BIN(CMOS_READ(RTC_CENTURY) & RTC_CENTURY_MASK);
CMOS_WRITE(0, RTC_CONTROL);
+ spin_unlock_irqrestore(&rtc_lock, flags);
year += century * 100;
@@ -81,7 +84,9 @@ rtc_ds1742_set_time(unsigned long t)
u8 year, month, day, hour, minute, second;
u8 cmos_year, cmos_month, cmos_day, cmos_hour, cmos_minute, cmos_second;
int cmos_century;
+ unsigned long flags;
+ spin_lock_irqsave(&rtc_lock, flags);
CMOS_WRITE(RTC_READ, RTC_CONTROL);
cmos_second = (u8)(CMOS_READ(RTC_SECONDS) & RTC_SECONDS_MASK);
cmos_minute = (u8)CMOS_READ(RTC_MINUTES);
@@ -139,6 +144,7 @@ rtc_ds1742_set_time(unsigned long t)
/* RTC_CENTURY and RTC_CONTROL share same address... */
CMOS_WRITE(cmos_century, RTC_CONTROL);
+ spin_unlock_irqrestore(&rtc_lock, flags);
return 0;
}
diff --git a/arch/mips/jmr3927/rbhma3100/irq.c b/arch/mips/jmr3927/rbhma3100/irq.c
index b9799b86fc79..7cbe14483f13 100644
--- a/arch/mips/jmr3927/rbhma3100/irq.c
+++ b/arch/mips/jmr3927/rbhma3100/irq.c
@@ -412,13 +412,13 @@ void __init arch_init_irq(void)
}
static hw_irq_controller jmr3927_irq_controller = {
- "jmr3927_irq",
- jmr3927_irq_startup,
- jmr3927_irq_shutdown,
- jmr3927_irq_enable,
- jmr3927_irq_disable,
- jmr3927_irq_ack,
- jmr3927_irq_end,
+ .typename = "jmr3927_irq",
+ .startup = jmr3927_irq_startup,
+ .shutdown = jmr3927_irq_shutdown,
+ .enable = jmr3927_irq_enable,
+ .disable = jmr3927_irq_disable,
+ .ack = jmr3927_irq_ack,
+ .end = jmr3927_irq_end,
};
void jmr3927_irq_init(u32 irq_base)
diff --git a/arch/mips/jmr3927/rbhma3100/setup.c b/arch/mips/jmr3927/rbhma3100/setup.c
index 32039bb2f440..3e2fbdc66097 100644
--- a/arch/mips/jmr3927/rbhma3100/setup.c
+++ b/arch/mips/jmr3927/rbhma3100/setup.c
@@ -44,6 +44,11 @@
#include <linux/ioport.h>
#include <linux/param.h> /* for HZ */
#include <linux/delay.h>
+#ifdef CONFIG_SERIAL_TXX9
+#include <linux/tty.h>
+#include <linux/serial.h>
+#include <linux/serial_core.h>
+#endif
#include <asm/addrspace.h>
#include <asm/time.h>
@@ -193,7 +198,7 @@ static void jmr3927_board_init(void);
extern struct resource pci_io_resource;
extern struct resource pci_mem_resource;
-static void __init jmr3927_setup(void)
+void __init plat_setup(void)
{
char *argptr;
@@ -211,8 +216,8 @@ static void __init jmr3927_setup(void)
*/
ioport_resource.start = pci_io_resource.start;
ioport_resource.end = pci_io_resource.end;
- iomem_resource.start = pci_mem_resource.start;
- iomem_resource.end = pci_mem_resource.end;
+ iomem_resource.start = 0;
+ iomem_resource.end = 0xffffffff;
/* Reboot on panic */
panic_timeout = 180;
@@ -265,18 +270,35 @@ static void __init jmr3927_setup(void)
strcat(argptr, " ip=bootp");
}
-#ifdef CONFIG_TXX927_SERIAL_CONSOLE
+#ifdef CONFIG_SERIAL_TXX9
+ {
+ extern int early_serial_txx9_setup(struct uart_port *port);
+ int i;
+ struct uart_port req;
+ for(i = 0; i < 2; i++) {
+ memset(&req, 0, sizeof(req));
+ req.line = i;
+ req.iotype = UPIO_MEM;
+ req.membase = (char *)TX3927_SIO_REG(i);
+ req.mapbase = TX3927_SIO_REG(i);
+ req.irq = i == 0 ?
+ JMR3927_IRQ_IRC_SIO0 : JMR3927_IRQ_IRC_SIO1;
+ if (i == 0)
+ req.flags |= UPF_BUGGY_UART /*HAVE_CTS_LINE*/;
+ req.uartclk = JMR3927_IMCLK;
+ early_serial_txx9_setup(&req);
+ }
+ }
+#ifdef CONFIG_SERIAL_TXX9_CONSOLE
argptr = prom_getcmdline();
if ((argptr = strstr(argptr, "console=")) == NULL) {
argptr = prom_getcmdline();
strcat(argptr, " console=ttyS1,115200");
}
#endif
+#endif
}
-early_initcall(jmr3927_setup);
-
-
static void tx3927_setup(void);
#ifdef CONFIG_PCI
@@ -335,7 +357,7 @@ static void __init jmr3927_board_init(void)
jmr3927_io_dipsw());
}
-static void __init tx3927_setup(void)
+void __init plat_setup(void)
{
int i;
diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile
index d3303584fbd1..72f2126ad19d 100644
--- a/arch/mips/kernel/Makefile
+++ b/arch/mips/kernel/Makefile
@@ -11,11 +11,7 @@ obj-y += cpu-probe.o branch.o entry.o genex.o irq.o process.o \
binfmt_irix-objs := irixelf.o irixinv.o irixioctl.o irixsig.o \
irix5sys.o sysirix.o
-ifdef CONFIG_MODULES
-obj-y += mips_ksyms.o module.o
-obj-$(CONFIG_32BIT) += module-elf32.o
-obj-$(CONFIG_64BIT) += module-elf64.o
-endif
+obj-$(CONFIG_MODULES) += mips_ksyms.o module.o
obj-$(CONFIG_CPU_R3000) += r2300_fpu.o r2300_switch.o
obj-$(CONFIG_CPU_TX39XX) += r2300_fpu.o r2300_switch.o
@@ -38,12 +34,18 @@ obj-$(CONFIG_CPU_R6000) += r6000_fpu.o r4k_switch.o
obj-$(CONFIG_SMP) += smp.o
+obj-$(CONFIG_MIPS_MT_SMP) += smp_mt.o
+
+obj-$(CONFIG_MIPS_VPE_LOADER) += vpe.o
+obj-$(CONFIG_MIPS_VPE_APSP_API) += rtlx.o
+
obj-$(CONFIG_NO_ISA) += dma-no-isa.o
obj-$(CONFIG_I8259) += i8259.o
obj-$(CONFIG_IRQ_CPU) += irq_cpu.o
obj-$(CONFIG_IRQ_CPU_RM7K) += irq-rm7000.o
obj-$(CONFIG_IRQ_CPU_RM9K) += irq-rm9000.o
obj-$(CONFIG_IRQ_MV64340) += irq-mv6434x.o
+obj-$(CONFIG_MIPS_BOARDS_GEN) += irq-msc01.o
obj-$(CONFIG_32BIT) += scall32-o32.o
obj-$(CONFIG_64BIT) += scall64-64.o
@@ -57,8 +59,6 @@ obj-$(CONFIG_PROC_FS) += proc.o
obj-$(CONFIG_64BIT) += cpu-bugs64.o
-obj-$(CONFIG_GEN_RTC) += genrtc.o
-
CFLAGS_cpu-bugs64.o = $(shell if $(CC) $(CFLAGS) -Wa,-mdaddi -c -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-DHAVE_AS_SET_DADDI"; fi)
CFLAGS_ioctl32.o += -Ifs/
diff --git a/arch/mips/kernel/asm-offsets.c b/arch/mips/kernel/asm-offsets.c
index 2c11abb5a406..ca6b03c773be 100644
--- a/arch/mips/kernel/asm-offsets.c
+++ b/arch/mips/kernel/asm-offsets.c
@@ -95,6 +95,7 @@ void output_thread_info_defines(void)
offset("#define TI_PRE_COUNT ", struct thread_info, preempt_count);
offset("#define TI_ADDR_LIMIT ", struct thread_info, addr_limit);
offset("#define TI_RESTART_BLOCK ", struct thread_info, restart_block);
+ offset("#define TI_TP_VALUE ", struct thread_info, tp_value);
constant("#define _THREAD_SIZE_ORDER ", THREAD_SIZE_ORDER);
constant("#define _THREAD_SIZE ", THREAD_SIZE);
constant("#define _THREAD_MASK ", THREAD_MASK);
@@ -240,6 +241,7 @@ void output_mm_defines(void)
linefeed;
}
+#ifdef CONFIG_32BIT
void output_sc_defines(void)
{
text("/* Linux sigcontext offsets. */");
@@ -251,10 +253,29 @@ void output_sc_defines(void)
offset("#define SC_STATUS ", struct sigcontext, sc_status);
offset("#define SC_FPC_CSR ", struct sigcontext, sc_fpc_csr);
offset("#define SC_FPC_EIR ", struct sigcontext, sc_fpc_eir);
- offset("#define SC_CAUSE ", struct sigcontext, sc_cause);
- offset("#define SC_BADVADDR ", struct sigcontext, sc_badvaddr);
+ offset("#define SC_HI1 ", struct sigcontext, sc_hi1);
+ offset("#define SC_LO1 ", struct sigcontext, sc_lo1);
+ offset("#define SC_HI2 ", struct sigcontext, sc_hi2);
+ offset("#define SC_LO2 ", struct sigcontext, sc_lo2);
+ offset("#define SC_HI3 ", struct sigcontext, sc_hi3);
+ offset("#define SC_LO3 ", struct sigcontext, sc_lo3);
linefeed;
}
+#endif
+
+#ifdef CONFIG_64BIT
+void output_sc_defines(void)
+{
+ text("/* Linux sigcontext offsets. */");
+ offset("#define SC_REGS ", struct sigcontext, sc_regs);
+ offset("#define SC_FPREGS ", struct sigcontext, sc_fpregs);
+ offset("#define SC_MDHI ", struct sigcontext, sc_hi);
+ offset("#define SC_MDLO ", struct sigcontext, sc_lo);
+ offset("#define SC_PC ", struct sigcontext, sc_pc);
+ offset("#define SC_FPC_CSR ", struct sigcontext, sc_fpc_csr);
+ linefeed;
+}
+#endif
#ifdef CONFIG_MIPS32_COMPAT
void output_sc32_defines(void)
diff --git a/arch/mips/kernel/binfmt_elfn32.c b/arch/mips/kernel/binfmt_elfn32.c
index 6b645fbb1ddc..d8e2674a1543 100644
--- a/arch/mips/kernel/binfmt_elfn32.c
+++ b/arch/mips/kernel/binfmt_elfn32.c
@@ -52,7 +52,6 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
#include <asm/processor.h>
#include <linux/module.h>
-#include <linux/config.h>
#include <linux/elfcore.h>
#include <linux/compat.h>
@@ -116,4 +115,7 @@ MODULE_AUTHOR("Ralf Baechle (ralf@linux-mips.org)");
#undef MODULE_DESCRIPTION
#undef MODULE_AUTHOR
+#undef TASK_SIZE
+#define TASK_SIZE TASK_SIZE32
+
#include "../../../fs/binfmt_elf.c"
diff --git a/arch/mips/kernel/binfmt_elfo32.c b/arch/mips/kernel/binfmt_elfo32.c
index b4075e99c452..cec5f327e360 100644
--- a/arch/mips/kernel/binfmt_elfo32.c
+++ b/arch/mips/kernel/binfmt_elfo32.c
@@ -54,7 +54,6 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
#include <asm/processor.h>
#include <linux/module.h>
-#include <linux/config.h>
#include <linux/elfcore.h>
#include <linux/compat.h>
@@ -98,7 +97,7 @@ struct elf_prpsinfo32
#define init_elf_binfmt init_elf32_binfmt
#define jiffies_to_timeval jiffies_to_compat_timeval
-static __inline__ void
+static inline void
jiffies_to_compat_timeval(unsigned long jiffies, struct compat_timeval *value)
{
/*
@@ -113,21 +112,26 @@ jiffies_to_compat_timeval(unsigned long jiffies, struct compat_timeval *value)
#undef ELF_CORE_COPY_REGS
#define ELF_CORE_COPY_REGS(_dest,_regs) elf32_core_copy_regs(_dest,_regs);
-void elf32_core_copy_regs(elf_gregset_t _dest, struct pt_regs *_regs)
+void elf32_core_copy_regs(elf_gregset_t grp, struct pt_regs *regs)
{
int i;
- memset(_dest, 0, sizeof(elf_gregset_t));
-
- /* XXXKW the 6 is from EF_REG0 in gdb/gdb/mips-linux-tdep.c, include/asm-mips/reg.h */
- for (i=6; i<38; i++)
- _dest[i] = (elf_greg_t) _regs->regs[i-6];
- _dest[i++] = (elf_greg_t) _regs->lo;
- _dest[i++] = (elf_greg_t) _regs->hi;
- _dest[i++] = (elf_greg_t) _regs->cp0_epc;
- _dest[i++] = (elf_greg_t) _regs->cp0_badvaddr;
- _dest[i++] = (elf_greg_t) _regs->cp0_status;
- _dest[i++] = (elf_greg_t) _regs->cp0_cause;
+ for (i = 0; i < EF_R0; i++)
+ grp[i] = 0;
+ grp[EF_R0] = 0;
+ for (i = 1; i <= 31; i++)
+ grp[EF_R0 + i] = (elf_greg_t) regs->regs[i];
+ grp[EF_R26] = 0;
+ grp[EF_R27] = 0;
+ grp[EF_LO] = (elf_greg_t) regs->lo;
+ grp[EF_HI] = (elf_greg_t) regs->hi;
+ grp[EF_CP0_EPC] = (elf_greg_t) regs->cp0_epc;
+ grp[EF_CP0_BADVADDR] = (elf_greg_t) regs->cp0_badvaddr;
+ grp[EF_CP0_STATUS] = (elf_greg_t) regs->cp0_status;
+ grp[EF_CP0_CAUSE] = (elf_greg_t) regs->cp0_cause;
+#ifdef EF_UNUSED0
+ grp[EF_UNUSED0] = 0;
+#endif
}
MODULE_DESCRIPTION("Binary format loader for compatibility with o32 Linux/MIPS binaries");
@@ -136,4 +140,7 @@ MODULE_AUTHOR("Ralf Baechle (ralf@linux-mips.org)");
#undef MODULE_DESCRIPTION
#undef MODULE_AUTHOR
+#undef TASK_SIZE
+#define TASK_SIZE TASK_SIZE32
+
#include "../../../fs/binfmt_elf.c"
diff --git a/arch/mips/kernel/branch.c b/arch/mips/kernel/branch.c
index 01117e977a7f..374de839558d 100644
--- a/arch/mips/kernel/branch.c
+++ b/arch/mips/kernel/branch.c
@@ -12,6 +12,7 @@
#include <asm/branch.h>
#include <asm/cpu.h>
#include <asm/cpu-features.h>
+#include <asm/fpu.h>
#include <asm/inst.h>
#include <asm/ptrace.h>
#include <asm/uaccess.h>
@@ -21,7 +22,7 @@
*/
int __compute_return_epc(struct pt_regs *regs)
{
- unsigned int *addr, bit, fcr31;
+ unsigned int *addr, bit, fcr31, dspcontrol;
long epc;
union mips_instruction insn;
@@ -98,6 +99,18 @@ int __compute_return_epc(struct pt_regs *regs)
epc += 8;
regs->cp0_epc = epc;
break;
+ case bposge32_op:
+ if (!cpu_has_dsp)
+ goto sigill;
+
+ dspcontrol = rddsp(0x01);
+
+ if (dspcontrol >= 32) {
+ epc = epc + 4 + (insn.i_format.simmediate << 2);
+ } else
+ epc += 8;
+ regs->cp0_epc = epc;
+ break;
}
break;
@@ -161,10 +174,13 @@ int __compute_return_epc(struct pt_regs *regs)
* And now the FPA/cp1 branch instructions.
*/
case cop1_op:
- if (!cpu_has_fpu)
- fcr31 = current->thread.fpu.soft.fcr31;
- else
+ preempt_disable();
+ if (is_fpu_owner())
asm volatile("cfc1\t%0,$31" : "=r" (fcr31));
+ else
+ fcr31 = current->thread.fpu.hard.fcr31;
+ preempt_enable();
+
bit = (insn.i_format.rt >> 2);
bit += (bit != 0);
bit += 23;
@@ -196,4 +212,9 @@ unaligned:
printk("%s: unaligned epc - sending SIGBUS.\n", current->comm);
force_sig(SIGBUS, current);
return -EFAULT;
+
+sigill:
+ printk("%s: DSP branch but not DSP ASE - sending SIGBUS.\n", current->comm);
+ force_sig(SIGBUS, current);
+ return -EFAULT;
}
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c
index 7685f8baf3f0..a263fb7a3971 100644
--- a/arch/mips/kernel/cpu-probe.c
+++ b/arch/mips/kernel/cpu-probe.c
@@ -2,9 +2,9 @@
* Processor capabilities determination functions.
*
* Copyright (C) xxxx the Anonymous
- * Copyright (C) 2003 Maciej W. Rozycki
+ * Copyright (C) 2003, 2004 Maciej W. Rozycki
* Copyright (C) 1994 - 2003 Ralf Baechle
- * Copyright (C) 2001 MIPS Inc.
+ * Copyright (C) 2001, 2004 MIPS Inc.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -17,7 +17,6 @@
#include <linux/ptrace.h>
#include <linux/stddef.h>
-#include <asm/bugs.h>
#include <asm/cpu.h>
#include <asm/fpu.h>
#include <asm/mipsregs.h>
@@ -51,36 +50,48 @@ static void r4k_wait(void)
".set\tmips0");
}
-/*
- * The Au1xxx wait is available only if we run CONFIG_PM and
- * the timer setup found we had a 32KHz counter available.
- * There are still problems with functions that may call au1k_wait
- * directly, but that will be discovered pretty quickly.
- */
-extern void (*au1k_wait_ptr)(void);
+/* The Au1xxx wait is available only if using 32khz counter or
+ * external timer source, but specifically not CP0 Counter. */
+int allow_au1k_wait;
-void au1k_wait(void)
+static void au1k_wait(void)
{
-#ifdef CONFIG_PM
/* using the wait instruction makes CP0 counter unusable */
- __asm__(".set\tmips3\n\t"
+ __asm__(".set mips3\n\t"
+ "cache 0x14, 0(%0)\n\t"
+ "cache 0x14, 32(%0)\n\t"
+ "sync\n\t"
+ "nop\n\t"
"wait\n\t"
"nop\n\t"
"nop\n\t"
"nop\n\t"
"nop\n\t"
- ".set\tmips0");
-#else
- __asm__("nop\n\t"
- "nop");
-#endif
+ ".set mips0\n\t"
+ : : "r" (au1k_wait));
}
+static int __initdata nowait = 0;
+
+int __init wait_disable(char *s)
+{
+ nowait = 1;
+
+ return 1;
+}
+
+__setup("nowait", wait_disable);
+
static inline void check_wait(void)
{
struct cpuinfo_mips *c = &current_cpu_data;
printk("Checking for 'wait' instruction... ");
+ if (nowait) {
+ printk (" disabled.\n");
+ return;
+ }
+
switch (c->cputype) {
case CPU_R3081:
case CPU_R3081E:
@@ -109,22 +120,22 @@ static inline void check_wait(void)
/* case CPU_20KC:*/
case CPU_24K:
case CPU_25KF:
+ case CPU_34K:
+ case CPU_PR4450:
cpu_wait = r4k_wait;
printk(" available.\n");
break;
-#ifdef CONFIG_PM
case CPU_AU1000:
case CPU_AU1100:
case CPU_AU1500:
- if (au1k_wait_ptr != NULL) {
- cpu_wait = au1k_wait_ptr;
+ case CPU_AU1550:
+ case CPU_AU1200:
+ if (allow_au1k_wait) {
+ cpu_wait = au1k_wait;
printk(" available.\n");
- }
- else {
+ } else
printk(" unavailable.\n");
- }
break;
-#endif
default:
printk(" unavailable.\n");
break;
@@ -180,7 +191,7 @@ static inline int __cpu_has_fpu(void)
return ((cpu_get_fpu_id() & 0xff00) != FPIR_IMP_NONE);
}
-#define R4K_OPTS (MIPS_CPU_TLB | MIPS_CPU_4KEX | MIPS_CPU_4KTLB \
+#define R4K_OPTS (MIPS_CPU_TLB | MIPS_CPU_4KEX | MIPS_CPU_4K_CACHE \
| MIPS_CPU_COUNTER)
static inline void cpu_probe_legacy(struct cpuinfo_mips *c)
@@ -189,7 +200,8 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c)
case PRID_IMP_R2000:
c->cputype = CPU_R2000;
c->isa_level = MIPS_CPU_ISA_I;
- c->options = MIPS_CPU_TLB | MIPS_CPU_NOFPUEX;
+ c->options = MIPS_CPU_TLB | MIPS_CPU_3K_CACHE |
+ MIPS_CPU_NOFPUEX;
if (__cpu_has_fpu())
c->options |= MIPS_CPU_FPU;
c->tlbsize = 64;
@@ -203,7 +215,8 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c)
else
c->cputype = CPU_R3000;
c->isa_level = MIPS_CPU_ISA_I;
- c->options = MIPS_CPU_TLB | MIPS_CPU_NOFPUEX;
+ c->options = MIPS_CPU_TLB | MIPS_CPU_3K_CACHE |
+ MIPS_CPU_NOFPUEX;
if (__cpu_has_fpu())
c->options |= MIPS_CPU_FPU;
c->tlbsize = 64;
@@ -266,7 +279,8 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c)
case PRID_IMP_R4600:
c->cputype = CPU_R4600;
c->isa_level = MIPS_CPU_ISA_III;
- c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_LLSC;
+ c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |
+ MIPS_CPU_LLSC;
c->tlbsize = 48;
break;
#if 0
@@ -285,7 +299,7 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c)
#endif
case PRID_IMP_TX39:
c->isa_level = MIPS_CPU_ISA_I;
- c->options = MIPS_CPU_TLB;
+ c->options = MIPS_CPU_TLB | MIPS_CPU_TX39_CACHE;
if ((c->processor_id & 0xf0) == (PRID_REV_TX3927 & 0xf0)) {
c->cputype = CPU_TX3927;
@@ -421,74 +435,147 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c)
}
}
-static inline void decode_config1(struct cpuinfo_mips *c)
+static inline unsigned int decode_config0(struct cpuinfo_mips *c)
{
- unsigned long config0 = read_c0_config();
- unsigned long config1;
+ unsigned int config0;
+ int isa;
+
+ config0 = read_c0_config();
- if ((config0 & (1 << 31)) == 0)
- return; /* actually wort a panic() */
+ if (((config0 & MIPS_CONF_MT) >> 7) == 1)
+ c->options |= MIPS_CPU_TLB;
+ isa = (config0 & MIPS_CONF_AT) >> 13;
+ switch (isa) {
+ case 0:
+ c->isa_level = MIPS_CPU_ISA_M32;
+ break;
+ case 2:
+ c->isa_level = MIPS_CPU_ISA_M64;
+ break;
+ default:
+ panic("Unsupported ISA type, cp0.config0.at: %d.", isa);
+ }
+
+ return config0 & MIPS_CONF_M;
+}
+
+static inline unsigned int decode_config1(struct cpuinfo_mips *c)
+{
+ unsigned int config1;
- /* MIPS32 or MIPS64 compliant CPU. Read Config 1 register. */
- c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX |
- MIPS_CPU_4KTLB | MIPS_CPU_COUNTER | MIPS_CPU_DIVEC |
- MIPS_CPU_LLSC | MIPS_CPU_MCHECK;
config1 = read_c0_config1();
- if (config1 & (1 << 3))
+
+ if (config1 & MIPS_CONF1_MD)
+ c->ases |= MIPS_ASE_MDMX;
+ if (config1 & MIPS_CONF1_WR)
c->options |= MIPS_CPU_WATCH;
- if (config1 & (1 << 2))
- c->options |= MIPS_CPU_MIPS16;
- if (config1 & (1 << 1))
+ if (config1 & MIPS_CONF1_CA)
+ c->ases |= MIPS_ASE_MIPS16;
+ if (config1 & MIPS_CONF1_EP)
c->options |= MIPS_CPU_EJTAG;
- if (config1 & 1) {
+ if (config1 & MIPS_CONF1_FP) {
c->options |= MIPS_CPU_FPU;
c->options |= MIPS_CPU_32FPR;
}
+ if (cpu_has_tlb)
+ c->tlbsize = ((config1 & MIPS_CONF1_TLBS) >> 25) + 1;
+
+ return config1 & MIPS_CONF_M;
+}
+
+static inline unsigned int decode_config2(struct cpuinfo_mips *c)
+{
+ unsigned int config2;
+
+ config2 = read_c0_config2();
+
+ if (config2 & MIPS_CONF2_SL)
+ c->scache.flags &= ~MIPS_CACHE_NOT_PRESENT;
+
+ return config2 & MIPS_CONF_M;
+}
+
+static inline unsigned int decode_config3(struct cpuinfo_mips *c)
+{
+ unsigned int config3;
+
+ config3 = read_c0_config3();
+
+ if (config3 & MIPS_CONF3_SM)
+ c->ases |= MIPS_ASE_SMARTMIPS;
+ if (config3 & MIPS_CONF3_DSP)
+ c->ases |= MIPS_ASE_DSP;
+ if (config3 & MIPS_CONF3_VINT)
+ c->options |= MIPS_CPU_VINT;
+ if (config3 & MIPS_CONF3_VEIC)
+ c->options |= MIPS_CPU_VEIC;
+ if (config3 & MIPS_CONF3_MT)
+ c->ases |= MIPS_ASE_MIPSMT;
+
+ return config3 & MIPS_CONF_M;
+}
+
+static inline void decode_configs(struct cpuinfo_mips *c)
+{
+ /* MIPS32 or MIPS64 compliant CPU. */
+ c->options = MIPS_CPU_4KEX | MIPS_CPU_4K_CACHE | MIPS_CPU_COUNTER |
+ MIPS_CPU_DIVEC | MIPS_CPU_LLSC | MIPS_CPU_MCHECK;
+
c->scache.flags = MIPS_CACHE_NOT_PRESENT;
- c->tlbsize = ((config1 >> 25) & 0x3f) + 1;
+ /* Read Config registers. */
+ if (!decode_config0(c))
+ return; /* actually worth a panic() */
+ if (!decode_config1(c))
+ return;
+ if (!decode_config2(c))
+ return;
+ if (!decode_config3(c))
+ return;
}
static inline void cpu_probe_mips(struct cpuinfo_mips *c)
{
- decode_config1(c);
+ decode_configs(c);
switch (c->processor_id & 0xff00) {
case PRID_IMP_4KC:
c->cputype = CPU_4KC;
- c->isa_level = MIPS_CPU_ISA_M32;
break;
case PRID_IMP_4KEC:
c->cputype = CPU_4KEC;
- c->isa_level = MIPS_CPU_ISA_M32;
+ break;
+ case PRID_IMP_4KECR2:
+ c->cputype = CPU_4KEC;
break;
case PRID_IMP_4KSC:
+ case PRID_IMP_4KSD:
c->cputype = CPU_4KSC;
- c->isa_level = MIPS_CPU_ISA_M32;
break;
case PRID_IMP_5KC:
c->cputype = CPU_5KC;
- c->isa_level = MIPS_CPU_ISA_M64;
break;
case PRID_IMP_20KC:
c->cputype = CPU_20KC;
- c->isa_level = MIPS_CPU_ISA_M64;
break;
case PRID_IMP_24K:
+ case PRID_IMP_24KE:
c->cputype = CPU_24K;
- c->isa_level = MIPS_CPU_ISA_M32;
break;
case PRID_IMP_25KF:
c->cputype = CPU_25KF;
- c->isa_level = MIPS_CPU_ISA_M64;
/* Probe for L2 cache */
c->scache.flags &= ~MIPS_CACHE_NOT_PRESENT;
break;
+ case PRID_IMP_34K:
+ c->cputype = CPU_34K;
+ c->isa_level = MIPS_CPU_ISA_M32;
+ break;
}
}
static inline void cpu_probe_alchemy(struct cpuinfo_mips *c)
{
- decode_config1(c);
+ decode_configs(c);
switch (c->processor_id & 0xff00) {
case PRID_IMP_AU1_REV1:
case PRID_IMP_AU1_REV2:
@@ -505,50 +592,70 @@ static inline void cpu_probe_alchemy(struct cpuinfo_mips *c)
case 3:
c->cputype = CPU_AU1550;
break;
+ case 4:
+ c->cputype = CPU_AU1200;
+ break;
default:
panic("Unknown Au Core!");
break;
}
- c->isa_level = MIPS_CPU_ISA_M32;
break;
}
}
static inline void cpu_probe_sibyte(struct cpuinfo_mips *c)
{
- decode_config1(c);
+ decode_configs(c);
+
+ /*
+ * For historical reasons the SB1 comes with it's own variant of
+ * cache code which eventually will be folded into c-r4k.c. Until
+ * then we pretend it's got it's own cache architecture.
+ */
+ c->options &= ~MIPS_CPU_4K_CACHE;
+ c->options |= MIPS_CPU_SB1_CACHE;
+
switch (c->processor_id & 0xff00) {
case PRID_IMP_SB1:
c->cputype = CPU_SB1;
- c->isa_level = MIPS_CPU_ISA_M64;
- c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX |
- MIPS_CPU_COUNTER | MIPS_CPU_DIVEC |
- MIPS_CPU_MCHECK | MIPS_CPU_EJTAG |
- MIPS_CPU_WATCH | MIPS_CPU_LLSC;
-#ifndef CONFIG_SB1_PASS_1_WORKAROUNDS
+#ifdef CONFIG_SB1_PASS_1_WORKAROUNDS
/* FPU in pass1 is known to have issues. */
- c->options |= MIPS_CPU_FPU | MIPS_CPU_32FPR;
+ c->options &= ~(MIPS_CPU_FPU | MIPS_CPU_32FPR);
#endif
break;
+ case PRID_IMP_SB1A:
+ c->cputype = CPU_SB1A;
+ break;
}
}
static inline void cpu_probe_sandcraft(struct cpuinfo_mips *c)
{
- decode_config1(c);
+ decode_configs(c);
switch (c->processor_id & 0xff00) {
case PRID_IMP_SR71000:
c->cputype = CPU_SR71000;
- c->isa_level = MIPS_CPU_ISA_M64;
- c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX |
- MIPS_CPU_4KTLB | MIPS_CPU_FPU |
- MIPS_CPU_COUNTER | MIPS_CPU_MCHECK;
c->scache.ways = 8;
c->tlbsize = 64;
break;
}
}
+static inline void cpu_probe_philips(struct cpuinfo_mips *c)
+{
+ decode_configs(c);
+ switch (c->processor_id & 0xff00) {
+ case PRID_IMP_PR4450:
+ c->cputype = CPU_PR4450;
+ c->isa_level = MIPS_CPU_ISA_M32;
+ break;
+ default:
+ panic("Unknown Philips Core!"); /* REVISIT: die? */
+ break;
+ }
+}
+
+
__init void cpu_probe(void)
{
struct cpuinfo_mips *c = &current_cpu_data;
@@ -571,15 +678,24 @@ __init void cpu_probe(void)
case PRID_COMP_SIBYTE:
cpu_probe_sibyte(c);
break;
-
case PRID_COMP_SANDCRAFT:
cpu_probe_sandcraft(c);
break;
+ case PRID_COMP_PHILIPS:
+ cpu_probe_philips(c);
+ break;
default:
c->cputype = CPU_UNKNOWN;
}
- if (c->options & MIPS_CPU_FPU)
+ if (c->options & MIPS_CPU_FPU) {
c->fpu_id = cpu_get_fpu_id();
+
+ if (c->isa_level == MIPS_CPU_ISA_M32 ||
+ c->isa_level == MIPS_CPU_ISA_M64) {
+ if (c->fpu_id & MIPS_FPIR_3D)
+ c->ases |= MIPS_ASE_MIPS3D;
+ }
+ }
}
__init void cpu_report(void)
diff --git a/arch/mips/kernel/dma-no-isa.c b/arch/mips/kernel/dma-no-isa.c
new file mode 100644
index 000000000000..6df8b07741e3
--- /dev/null
+++ b/arch/mips/kernel/dma-no-isa.c
@@ -0,0 +1,28 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2004 by Ralf Baechle
+ *
+ * Dummy ISA DMA functions for systems that don't have ISA but share drivers
+ * with ISA such as legacy free PCI.
+ */
+#include <linux/errno.h>
+#include <linux/module.h>
+#include <linux/spinlock.h>
+
+DEFINE_SPINLOCK(dma_spin_lock);
+
+int request_dma(unsigned int dmanr, const char * device_id)
+{
+ return -EINVAL;
+}
+
+void free_dma(unsigned int dmanr)
+{
+}
+
+EXPORT_SYMBOL(dma_spin_lock);
+EXPORT_SYMBOL(request_dma);
+EXPORT_SYMBOL(free_dma);
diff --git a/arch/mips/kernel/entry.S b/arch/mips/kernel/entry.S
index 5eb429137e06..83c87fe4ee4f 100644
--- a/arch/mips/kernel/entry.S
+++ b/arch/mips/kernel/entry.S
@@ -19,11 +19,11 @@
#include <asm/war.h>
#ifdef CONFIG_PREEMPT
- .macro preempt_stop reg=t0
+ .macro preempt_stop
.endm
#else
- .macro preempt_stop reg=t0
- local_irq_disable \reg
+ .macro preempt_stop
+ local_irq_disable
.endm
#define resume_kernel restore_all
#endif
@@ -37,17 +37,18 @@ FEXPORT(ret_from_irq)
andi t0, t0, KU_USER
beqz t0, resume_kernel
-FEXPORT(resume_userspace)
- local_irq_disable t0 # make sure we dont miss an
+resume_userspace:
+ local_irq_disable # make sure we dont miss an
# interrupt setting need_resched
# between sampling and return
LONG_L a2, TI_FLAGS($28) # current->work
- andi a2, _TIF_WORK_MASK # (ignoring syscall_trace)
- bnez a2, work_pending
+ andi t0, a2, _TIF_WORK_MASK # (ignoring syscall_trace)
+ bnez t0, work_pending
j restore_all
#ifdef CONFIG_PREEMPT
-ENTRY(resume_kernel)
+resume_kernel:
+ local_irq_disable
lw t0, TI_PRE_COUNT($28)
bnez t0, restore_all
need_resched:
@@ -57,12 +58,7 @@ need_resched:
LONG_L t0, PT_STATUS(sp) # Interrupts off?
andi t0, 1
beqz t0, restore_all
- li t0, PREEMPT_ACTIVE
- sw t0, TI_PRE_COUNT($28)
- local_irq_enable t0
- jal schedule
- sw zero, TI_PRE_COUNT($28)
- local_irq_disable t0
+ jal preempt_schedule_irq
b need_resched
#endif
@@ -88,13 +84,13 @@ FEXPORT(restore_partial) # restore partial frame
RESTORE_SP_AND_RET
.set at
-FEXPORT(work_pending)
- andi t0, a2, _TIF_NEED_RESCHED
+work_pending:
+ andi t0, a2, _TIF_NEED_RESCHED # a2 is preloaded with TI_FLAGS
beqz t0, work_notifysig
work_resched:
jal schedule
- local_irq_disable t0 # make sure need_resched and
+ local_irq_disable # make sure need_resched and
# signals dont change between
# sampling and return
LONG_L a2, TI_FLAGS($28)
@@ -109,15 +105,14 @@ work_notifysig: # deal with pending signals and
move a0, sp
li a1, 0
jal do_notify_resume # a2 already loaded
- j restore_all
+ j resume_userspace
FEXPORT(syscall_exit_work_partial)
SAVE_STATIC
-FEXPORT(syscall_exit_work)
- LONG_L t0, TI_FLAGS($28)
- li t1, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT
- and t0, t1
- beqz t0, work_pending # trace bit is set
+syscall_exit_work:
+ li t0, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT
+ and t0, a2 # a2 is preloaded with TI_FLAGS
+ beqz t0, work_pending # trace bit set?
local_irq_enable # could let do_syscall_trace()
# call schedule() instead
move a0, sp
@@ -128,28 +123,25 @@ FEXPORT(syscall_exit_work)
/*
* Common spurious interrupt handler.
*/
- .text
- .align 5
LEAF(spurious_interrupt)
/*
* Someone tried to fool us by sending an interrupt but we
* couldn't find a cause for it.
*/
+ PTR_LA t1, irq_err_count
#ifdef CONFIG_SMP
- lui t1, %hi(irq_err_count)
-1: ll t0, %lo(irq_err_count)(t1)
+1: ll t0, (t1)
addiu t0, 1
- sc t0, %lo(irq_err_count)(t1)
+ sc t0, (t1)
#if R10000_LLSC_WAR
beqzl t0, 1b
#else
beqz t0, 1b
#endif
#else
- lui t1, %hi(irq_err_count)
- lw t0, %lo(irq_err_count)(t1)
+ lw t0, (t1)
addiu t0, 1
- sw t0, %lo(irq_err_count)(t1)
+ sw t0, (t1)
#endif
j ret_from_irq
END(spurious_interrupt)
diff --git a/arch/mips/kernel/gdb-low.S b/arch/mips/kernel/gdb-low.S
index 512bedbfa7b9..83b8986f9401 100644
--- a/arch/mips/kernel/gdb-low.S
+++ b/arch/mips/kernel/gdb-low.S
@@ -52,16 +52,15 @@
/*
* Called from user mode, go somewhere else.
*/
- lui k1, %hi(saved_vectors)
mfc0 k0, CP0_CAUSE
andi k0, k0, 0x7c
add k1, k1, k0
- lw k0, %lo(saved_vectors)(k1)
+ PTR_L k0, saved_vectors(k1)
jr k0
nop
1:
move k0, sp
- subu sp, k1, GDB_FR_SIZE*2 # see comment above
+ PTR_SUBU sp, k1, GDB_FR_SIZE*2 # see comment above
LONG_S k0, GDB_FR_REG29(sp)
LONG_S $2, GDB_FR_REG2(sp)
diff --git a/arch/mips/kernel/gdb-stub.c b/arch/mips/kernel/gdb-stub.c
index d3fd1ab14274..96d18c43dca0 100644
--- a/arch/mips/kernel/gdb-stub.c
+++ b/arch/mips/kernel/gdb-stub.c
@@ -176,8 +176,10 @@ int kgdb_enabled;
/*
* spin locks for smp case
*/
-static spinlock_t kgdb_lock = SPIN_LOCK_UNLOCKED;
-static spinlock_t kgdb_cpulock[NR_CPUS] = { [0 ... NR_CPUS-1] = SPIN_LOCK_UNLOCKED};
+static DEFINE_SPINLOCK(kgdb_lock);
+static raw_spinlock_t kgdb_cpulock[NR_CPUS] = {
+ [0 ... NR_CPUS-1] = __RAW_SPIN_LOCK_UNLOCKED;
+};
/*
* BUFMAX defines the maximum number of characters in inbound/outbound buffers
@@ -637,29 +639,32 @@ static struct gdb_bp_save async_bp;
* and only one can be active at a time.
*/
extern spinlock_t smp_call_lock;
+
void set_async_breakpoint(unsigned long *epc)
{
/* skip breaking into userland */
if ((*epc & 0x80000000) == 0)
return;
+#ifdef CONFIG_SMP
/* avoid deadlock if someone is make IPC */
if (spin_is_locked(&smp_call_lock))
return;
+#endif
async_bp.addr = *epc;
*epc = (unsigned long)async_breakpoint;
}
-void kgdb_wait(void *arg)
+static void kgdb_wait(void *arg)
{
unsigned flags;
int cpu = smp_processor_id();
local_irq_save(flags);
- spin_lock(&kgdb_cpulock[cpu]);
- spin_unlock(&kgdb_cpulock[cpu]);
+ __raw_spin_lock(&kgdb_cpulock[cpu]);
+ __raw_spin_unlock(&kgdb_cpulock[cpu]);
local_irq_restore(flags);
}
@@ -707,7 +712,7 @@ void handle_exception (struct gdb_regs *regs)
* acquire the CPU spinlocks
*/
for (i = num_online_cpus()-1; i >= 0; i--)
- if (spin_trylock(&kgdb_cpulock[i]) == 0)
+ if (__raw_spin_trylock(&kgdb_cpulock[i]) == 0)
panic("kgdb: couldn't get cpulock %d\n", i);
/*
@@ -982,7 +987,7 @@ finish_kgdb:
exit_kgdb_exception:
/* release locks so other CPUs can go */
for (i = num_online_cpus()-1; i >= 0; i--)
- spin_unlock(&kgdb_cpulock[i]);
+ __raw_spin_unlock(&kgdb_cpulock[i]);
spin_unlock(&kgdb_lock);
__flush_cache_all();
@@ -1036,12 +1041,12 @@ void adel(void)
* malloc is needed by gdb client in "call func()", even a private one
* will make gdb happy
*/
-static void *malloc(size_t size)
+static void * __attribute_used__ malloc(size_t size)
{
return kmalloc(size, GFP_ATOMIC);
}
-static void free(void *where)
+static void __attribute_used__ free (void *where)
{
kfree(where);
}
diff --git a/arch/mips/kernel/genex.S b/arch/mips/kernel/genex.S
index e7f6c1b90806..aa18a8b7b380 100644
--- a/arch/mips/kernel/genex.S
+++ b/arch/mips/kernel/genex.S
@@ -82,7 +82,7 @@ NESTED(except_vec3_r4000, 0, sp)
li k0, 14<<2
beq k1, k0, handle_vcei
#ifdef CONFIG_64BIT
- dsll k1, k1, 1
+ dsll k1, k1, 1
#endif
.set pop
PTR_L k0, exception_handlers(k1)
@@ -90,17 +90,17 @@ NESTED(except_vec3_r4000, 0, sp)
/*
* Big shit, we now may have two dirty primary cache lines for the same
- * physical address. We can savely invalidate the line pointed to by
+ * physical address. We can safely invalidate the line pointed to by
* c0_badvaddr because after return from this exception handler the
* load / store will be re-executed.
*/
handle_vced:
- DMFC0 k0, CP0_BADVADDR
+ MFC0 k0, CP0_BADVADDR
li k1, -4 # Is this ...
and k0, k1 # ... really needed?
mtc0 zero, CP0_TAGLO
- cache Index_Store_Tag_D,(k0)
- cache Hit_Writeback_Inv_SD,(k0)
+ cache Index_Store_Tag_D, (k0)
+ cache Hit_Writeback_Inv_SD, (k0)
#ifdef CONFIG_PROC_FS
PTR_LA k0, vced_count
lw k1, (k0)
@@ -148,6 +148,38 @@ NESTED(except_vec_ejtag_debug, 0, sp)
__FINIT
/*
+ * Vectored interrupt handler.
+ * This prototype is copied to ebase + n*IntCtl.VS and patched
+ * to invoke the handler
+ */
+NESTED(except_vec_vi, 0, sp)
+ SAVE_SOME
+ SAVE_AT
+ .set push
+ .set noreorder
+EXPORT(except_vec_vi_lui)
+ lui v0, 0 /* Patched */
+ j except_vec_vi_handler
+EXPORT(except_vec_vi_ori)
+ ori v0, 0 /* Patched */
+ .set pop
+ END(except_vec_vi)
+EXPORT(except_vec_vi_end)
+
+/*
+ * Common Vectored Interrupt code
+ * Complete the register saves and invoke the handler which is passed in $v0
+ */
+NESTED(except_vec_vi_handler, 0, sp)
+ SAVE_TEMP
+ SAVE_STATIC
+ CLI
+ move a0, sp
+ jalr v0
+ j ret_from_irq
+ END(except_vec_vi_handler)
+
+/*
* EJTAG debug exception handler.
*/
NESTED(ejtag_debug_handler, PT_SIZE, sp)
@@ -291,6 +323,8 @@ NESTED(nmi_handler, PT_SIZE, sp)
BUILD_HANDLER mdmx mdmx sti silent /* #22 */
BUILD_HANDLER watch watch sti verbose /* #23 */
BUILD_HANDLER mcheck mcheck cli verbose /* #24 */
+ BUILD_HANDLER mt mt sti verbose /* #25 */
+ BUILD_HANDLER dsp dsp sti silent /* #26 */
BUILD_HANDLER reserved reserved sti verbose /* others */
#ifdef CONFIG_64BIT
diff --git a/arch/mips/kernel/genrtc.c b/arch/mips/kernel/genrtc.c
deleted file mode 100644
index 71416e7bbbaa..000000000000
--- a/arch/mips/kernel/genrtc.c
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * A glue layer that provides RTC read/write to drivers/char/genrtc.c driver
- * based on MIPS internal RTC routines. It does take care locking
- * issues so that we are SMP/Preemption safe.
- *
- * Copyright (C) 2004 MontaVista Software Inc.
- * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
- *
- * Please read the COPYING file for all license details.
- */
-
-#include <linux/spinlock.h>
-
-#include <asm/rtc.h>
-#include <asm/time.h>
-
-static DEFINE_SPINLOCK(mips_rtc_lock);
-
-unsigned int get_rtc_time(struct rtc_time *time)
-{
- unsigned long nowtime;
-
- spin_lock(&mips_rtc_lock);
- nowtime = rtc_get_time();
- to_tm(nowtime, time);
- time->tm_year -= 1900;
- spin_unlock(&mips_rtc_lock);
-
- return RTC_24H;
-}
-
-int set_rtc_time(struct rtc_time *time)
-{
- unsigned long nowtime;
- int ret;
-
- spin_lock(&mips_rtc_lock);
- nowtime = mktime(time->tm_year+1900, time->tm_mon+1,
- time->tm_mday, time->tm_hour, time->tm_min,
- time->tm_sec);
- ret = rtc_set_time(nowtime);
- spin_unlock(&mips_rtc_lock);
-
- return ret;
-}
-
-unsigned int get_rtc_ss(void)
-{
- struct rtc_time h;
-
- get_rtc_time(&h);
- return h.tm_sec;
-}
-
-int get_rtc_pll(struct rtc_pll_info *pll)
-{
- return -EINVAL;
-}
-
-int set_rtc_pll(struct rtc_pll_info *pll)
-{
- return -EINVAL;
-}
-
diff --git a/arch/mips/kernel/head.S b/arch/mips/kernel/head.S
index 2a1b45d66f04..2e9122a4213a 100644
--- a/arch/mips/kernel/head.S
+++ b/arch/mips/kernel/head.S
@@ -22,11 +22,8 @@
#include <asm/page.h>
#include <asm/mipsregs.h>
#include <asm/stackframe.h>
-#ifdef CONFIG_SGI_IP27
-#include <asm/sn/addrs.h>
-#include <asm/sn/sn0/hubni.h>
-#include <asm/sn/klkernvars.h>
-#endif
+
+#include <kernel-entry-init.h>
.macro ARC64_TWIDDLE_PC
#if defined(CONFIG_ARC64) || defined(CONFIG_MAPPED_KERNEL)
@@ -38,18 +35,6 @@
#endif
.endm
-#ifdef CONFIG_SGI_IP27
- /*
- * outputs the local nasid into res. IP27 stuff.
- */
- .macro GET_NASID_ASM res
- dli \res, LOCAL_HUB_ADDR(NI_STATUS_REV_ID)
- ld \res, (\res)
- and \res, NSRI_NODEID_MASK
- dsrl \res, NSRI_NODEID_SHFT
- .endm
-#endif /* CONFIG_SGI_IP27 */
-
/*
* inputs are the text nasid in t1, data nasid in t2.
*/
@@ -131,16 +116,21 @@
EXPORT(stext) # used for profiling
EXPORT(_stext)
+#if defined(CONFIG_QEMU) || defined(CONFIG_MIPS_SIM)
+ /*
+ * Give us a fighting chance of running if execution beings at the
+ * kernel load address. This is needed because this platform does
+ * not have a ELF loader yet.
+ */
+ j kernel_entry
+#endif
__INIT
NESTED(kernel_entry, 16, sp) # kernel entry point
- setup_c0_status_pri
-#ifdef CONFIG_SGI_IP27
- GET_NASID_ASM t1
- move t2, t1 # text and data are here
- MAPPED_KERNEL_SETUP_TLB
-#endif /* IP27 */
+ kernel_entry_setup # cpu specific setup
+
+ setup_c0_status_pri
ARC64_TWIDDLE_PC
@@ -157,6 +147,7 @@ NESTED(kernel_entry, 16, sp) # kernel entry point
LONG_S a2, fw_arg2
LONG_S a3, fw_arg3
+ MTC0 zero, CP0_CONTEXT # clear context register
PTR_LA $28, init_thread_union
PTR_ADDIU sp, $28, _THREAD_SIZE - 32
set_saved_sp sp, t0, t1
@@ -165,6 +156,10 @@ NESTED(kernel_entry, 16, sp) # kernel entry point
j start_kernel
END(kernel_entry)
+#ifdef CONFIG_QEMU
+ __INIT
+#endif
+
#ifdef CONFIG_SMP
/*
* SMP slave cpus entry point. Board specific code for bootstrap calls this
@@ -172,20 +167,7 @@ NESTED(kernel_entry, 16, sp) # kernel entry point
*/
NESTED(smp_bootstrap, 16, sp)
setup_c0_status_sec
-
-#ifdef CONFIG_SGI_IP27
- GET_NASID_ASM t1
- dli t0, KLDIR_OFFSET + (KLI_KERN_VARS * KLDIR_ENT_SIZE) + \
- KLDIR_OFF_POINTER + CAC_BASE
- dsll t1, NASID_SHFT
- or t0, t0, t1
- ld t0, 0(t0) # t0 points to kern_vars struct
- lh t1, KV_RO_NASID_OFFSET(t0)
- lh t2, KV_RW_NASID_OFFSET(t0)
- MAPPED_KERNEL_SETUP_TLB
- ARC64_TWIDDLE_PC
-#endif /* CONFIG_SGI_IP27 */
-
+ smp_slave_setup
j start_secondary
END(smp_bootstrap)
#endif /* CONFIG_SMP */
@@ -200,19 +182,13 @@ NESTED(smp_bootstrap, 16, sp)
.comm fw_arg2, SZREG, SZREG
.comm fw_arg3, SZREG, SZREG
- .macro page name, order=0
- .globl \name
-\name: .size \name, (_PAGE_SIZE << \order)
- .org . + (_PAGE_SIZE << \order)
- .type \name, @object
+ .macro page name, order
+ .comm \name, (_PAGE_SIZE << \order), (_PAGE_SIZE << \order)
.endm
- .data
- .align PAGE_SHIFT
-
/*
- * ... but on 64-bit we've got three-level pagetables with a
- * slightly different layout ...
+ * On 64-bit we've got three-level pagetables with a slightly
+ * different layout ...
*/
page swapper_pg_dir, _PGD_ORDER
#ifdef CONFIG_64BIT
diff --git a/arch/mips/kernel/i8259.c b/arch/mips/kernel/i8259.c
index 447759201d1d..b974ac9057f6 100644
--- a/arch/mips/kernel/i8259.c
+++ b/arch/mips/kernel/i8259.c
@@ -31,7 +31,7 @@ void disable_8259A_irq(unsigned int irq);
* moves to arch independent land
*/
-spinlock_t DEFINE_SPINLOCK(i8259A_lock);
+DEFINE_SPINLOCK(i8259A_lock);
static void end_8259A_irq (unsigned int irq)
{
@@ -52,14 +52,13 @@ static unsigned int startup_8259A_irq(unsigned int irq)
}
static struct hw_interrupt_type i8259A_irq_type = {
- "XT-PIC",
- startup_8259A_irq,
- shutdown_8259A_irq,
- enable_8259A_irq,
- disable_8259A_irq,
- mask_and_ack_8259A,
- end_8259A_irq,
- NULL
+ .typename = "XT-PIC",
+ .startup = startup_8259A_irq,
+ .shutdown = shutdown_8259A_irq,
+ .enable = enable_8259A_irq,
+ .disable = disable_8259A_irq,
+ .ack = mask_and_ack_8259A,
+ .end = end_8259A_irq,
};
/*
@@ -308,7 +307,7 @@ static struct resource pic2_io_resource = {
/*
* On systems with i8259-style interrupt controllers we assume for
- * driver compatibility reasons interrupts 0 - 15 to be the i8295
+ * driver compatibility reasons interrupts 0 - 15 to be the i8259
* interrupts even if the hardware uses a different interrupt numbering.
*/
void __init init_i8259_irqs (void)
@@ -322,7 +321,7 @@ void __init init_i8259_irqs (void)
for (i = 0; i < 16; i++) {
irq_desc[i].status = IRQ_DISABLED;
- irq_desc[i].action = 0;
+ irq_desc[i].action = NULL;
irq_desc[i].depth = 1;
irq_desc[i].handler = &i8259A_irq_type;
}
diff --git a/arch/mips/kernel/ioctl32.c b/arch/mips/kernel/ioctl32.c
index c069719ff0d8..9ea1fc748864 100644
--- a/arch/mips/kernel/ioctl32.c
+++ b/arch/mips/kernel/ioctl32.c
@@ -26,10 +26,8 @@ long sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg);
#define CODE
#include "compat_ioctl.c"
-typedef int (* ioctl32_handler_t)(unsigned int, unsigned int, unsigned long, struct file *);
-
#define COMPATIBLE_IOCTL(cmd) HANDLE_IOCTL((cmd),sys_ioctl)
-#define HANDLE_IOCTL(cmd,handler) { (cmd), (ioctl32_handler_t)(handler), NULL },
+#define HANDLE_IOCTL(cmd,handler) { (cmd), (ioctl_trans_handler_t)(handler), NULL },
#define IOCTL_TABLE_START \
struct ioctl_trans ioctl_start[] = {
#define IOCTL_TABLE_END \
@@ -41,12 +39,6 @@ IOCTL_TABLE_START
#define DECLARES
#include "compat_ioctl.c"
-#ifdef CONFIG_SIBYTE_TBPROF
-COMPATIBLE_IOCTL(SBPROF_ZBSTART)
-COMPATIBLE_IOCTL(SBPROF_ZBSTOP)
-COMPATIBLE_IOCTL(SBPROF_ZBWAITFULL)
-#endif /* CONFIG_SIBYTE_TBPROF */
-
/*HANDLE_IOCTL(RTC_IRQP_READ, w_long)
COMPATIBLE_IOCTL(RTC_IRQP_SET)
HANDLE_IOCTL(RTC_EPOCH_READ, w_long)
diff --git a/arch/mips/kernel/irixelf.c b/arch/mips/kernel/irixelf.c
index 4af20cd91f9f..10d3644e3608 100644
--- a/arch/mips/kernel/irixelf.c
+++ b/arch/mips/kernel/irixelf.c
@@ -8,7 +8,7 @@
*
* Copyright (C) 1993 - 1994 Eric Youngdale <ericy@cais.com>
* Copyright (C) 1996 - 2004 David S. Miller <dm@engr.sgi.com>
- * Copyright (C) 2004 Steven J. Hill <sjhill@realitydiluted.com>
+ * Copyright (C) 2004 - 2005 Steven J. Hill <sjhill@realitydiluted.com>
*/
#include <linux/module.h>
#include <linux/fs.h>
@@ -31,15 +31,16 @@
#include <linux/elfcore.h>
#include <linux/smp_lock.h>
-#include <asm/uaccess.h>
#include <asm/mipsregs.h>
+#include <asm/namei.h>
#include <asm/prctl.h>
+#include <asm/uaccess.h>
#define DLINFO_ITEMS 12
#include <linux/elf.h>
-#undef DEBUG_ELF
+#undef DEBUG
static int load_irix_binary(struct linux_binprm * bprm, struct pt_regs * regs);
static int load_irix_library(struct file *);
@@ -55,7 +56,7 @@ static struct linux_binfmt irix_format = {
#define elf_addr_t unsigned long
#endif
-#ifdef DEBUG_ELF
+#ifdef DEBUG
/* Debugging routines. */
static char *get_elf_p_type(Elf32_Word p_type)
{
@@ -120,7 +121,7 @@ static void dump_phdrs(struct elf_phdr *ep, int pnum)
print_phdr(i, ep);
}
}
-#endif /* (DEBUG_ELF) */
+#endif /* DEBUG */
static void set_brk(unsigned long start, unsigned long end)
{
@@ -146,20 +147,20 @@ static void padzero(unsigned long elf_bss)
nbyte = elf_bss & (PAGE_SIZE-1);
if (nbyte) {
nbyte = PAGE_SIZE - nbyte;
- clear_user((void *) elf_bss, nbyte);
+ clear_user((void __user *) elf_bss, nbyte);
}
}
-unsigned long * create_irix_tables(char * p, int argc, int envc,
- struct elfhdr * exec, unsigned int load_addr,
- unsigned int interp_load_addr,
- struct pt_regs *regs, struct elf_phdr *ephdr)
+static unsigned long * create_irix_tables(char * p, int argc, int envc,
+ struct elfhdr * exec, unsigned int load_addr,
+ unsigned int interp_load_addr, struct pt_regs *regs,
+ struct elf_phdr *ephdr)
{
elf_addr_t *argv;
elf_addr_t *envp;
elf_addr_t *sp, *csp;
-#ifdef DEBUG_ELF
+#ifdef DEBUG
printk("create_irix_tables: p[%p] argc[%d] envc[%d] "
"load_addr[%08x] interp_load_addr[%08x]\n",
p, argc, envc, load_addr, interp_load_addr);
@@ -248,14 +249,13 @@ static unsigned int load_irix_interp(struct elfhdr * interp_elf_ex,
last_bss = 0;
error = load_addr = 0;
-#ifdef DEBUG_ELF
+#ifdef DEBUG
print_elfhdr(interp_elf_ex);
#endif
/* First of all, some simple consistency checks */
if ((interp_elf_ex->e_type != ET_EXEC &&
interp_elf_ex->e_type != ET_DYN) ||
- !irix_elf_check_arch(interp_elf_ex) ||
!interpreter->f_op->mmap) {
printk("IRIX interp has bad e_type %d\n", interp_elf_ex->e_type);
return 0xffffffff;
@@ -290,7 +290,7 @@ static unsigned int load_irix_interp(struct elfhdr * interp_elf_ex,
(char *) elf_phdata,
sizeof(struct elf_phdr) * interp_elf_ex->e_phnum);
-#ifdef DEBUG_ELF
+#ifdef DEBUG
dump_phdrs(elf_phdata, interp_elf_ex->e_phnum);
#endif
@@ -306,13 +306,11 @@ static unsigned int load_irix_interp(struct elfhdr * interp_elf_ex,
elf_type |= MAP_FIXED;
vaddr = eppnt->p_vaddr;
-#ifdef DEBUG_ELF
- printk("INTERP do_mmap(%p, %08lx, %08lx, %08lx, %08lx, %08lx) ",
+ pr_debug("INTERP do_mmap(%p, %08lx, %08lx, %08lx, %08lx, %08lx) ",
interpreter, vaddr,
(unsigned long) (eppnt->p_filesz + (eppnt->p_vaddr & 0xfff)),
(unsigned long) elf_prot, (unsigned long) elf_type,
(unsigned long) (eppnt->p_offset & 0xfffff000));
-#endif
down_write(&current->mm->mmap_sem);
error = do_mmap(interpreter, vaddr,
eppnt->p_filesz + (eppnt->p_vaddr & 0xfff),
@@ -324,14 +322,10 @@ static unsigned int load_irix_interp(struct elfhdr * interp_elf_ex,
printk("Aieee IRIX interp mmap error=%d\n", error);
break; /* Real error */
}
-#ifdef DEBUG_ELF
- printk("error=%08lx ", (unsigned long) error);
-#endif
+ pr_debug("error=%08lx ", (unsigned long) error);
if(!load_addr && interp_elf_ex->e_type == ET_DYN) {
load_addr = error;
-#ifdef DEBUG_ELF
- printk("load_addr = error ");
-#endif
+ pr_debug("load_addr = error ");
}
/* Find the end of the file mapping for this phdr, and keep
@@ -345,17 +339,13 @@ static unsigned int load_irix_interp(struct elfhdr * interp_elf_ex,
*/
k = eppnt->p_memsz + eppnt->p_vaddr;
if(k > last_bss) last_bss = k;
-#ifdef DEBUG_ELF
- printk("\n");
-#endif
+ pr_debug("\n");
}
}
/* Now use mmap to map the library into memory. */
if(error < 0 && error > -1024) {
-#ifdef DEBUG_ELF
- printk("got error %d\n", error);
-#endif
+ pr_debug("got error %d\n", error);
kfree(elf_phdata);
return 0xffffffff;
}
@@ -365,16 +355,12 @@ static unsigned int load_irix_interp(struct elfhdr * interp_elf_ex,
* that there are zero-mapped pages up to and including the
* last bss page.
*/
-#ifdef DEBUG_ELF
- printk("padzero(%08lx) ", (unsigned long) (elf_bss));
-#endif
+ pr_debug("padzero(%08lx) ", (unsigned long) (elf_bss));
padzero(elf_bss);
len = (elf_bss + 0xfff) & 0xfffff000; /* What we have mapped so far */
-#ifdef DEBUG_ELF
- printk("last_bss[%08lx] len[%08lx]\n", (unsigned long) last_bss,
- (unsigned long) len);
-#endif
+ pr_debug("last_bss[%08lx] len[%08lx]\n", (unsigned long) last_bss,
+ (unsigned long) len);
/* Map the last of the bss segment */
if (last_bss > len) {
@@ -396,12 +382,7 @@ static int verify_binary(struct elfhdr *ehp, struct linux_binprm *bprm)
/* First of all, some simple consistency checks */
if((ehp->e_type != ET_EXEC && ehp->e_type != ET_DYN) ||
- !irix_elf_check_arch(ehp) || !bprm->file->f_op->mmap) {
- return -ENOEXEC;
- }
-
- /* Only support MIPS ARCH2 or greater IRIX binaries for now. */
- if(!(ehp->e_flags & EF_MIPS_ARCH) && !(ehp->e_flags & 0x04)) {
+ !bprm->file->f_op->mmap) {
return -ENOEXEC;
}
@@ -411,16 +392,17 @@ static int verify_binary(struct elfhdr *ehp, struct linux_binprm *bprm)
* XXX all registers as 64bits on cpu's capable of this at
* XXX exception time plus frob the XTLB exception vector.
*/
- if((ehp->e_flags & 0x20)) {
+ if((ehp->e_flags & EF_MIPS_ABI2))
return -ENOEXEC;
- }
- return 0; /* It's ok. */
+ return 0;
}
-#define IRIX_INTERP_PREFIX "/usr/gnemul/irix"
-
-/* Look for an IRIX ELF interpreter. */
+/*
+ * This is where the detailed check is performed. Irix binaries
+ * use interpreters with 'libc.so' in the name, so this function
+ * can differentiate between Linux and Irix binaries.
+ */
static inline int look_for_irix_interpreter(char **name,
struct file **interpreter,
struct elfhdr *interp_elf_ex,
@@ -440,12 +422,11 @@ static inline int look_for_irix_interpreter(char **name,
if (*name != NULL)
goto out;
- *name = kmalloc((epp->p_filesz + strlen(IRIX_INTERP_PREFIX)),
- GFP_KERNEL);
+ *name = kmalloc(epp->p_filesz + strlen(IRIX_EMUL), GFP_KERNEL);
if (!*name)
return -ENOMEM;
- strcpy(*name, IRIX_INTERP_PREFIX);
+ strcpy(*name, IRIX_EMUL);
retval = kernel_read(bprm->file, epp->p_offset, (*name + 16),
epp->p_filesz);
if (retval < 0)
@@ -562,7 +543,7 @@ static inline int map_interpreter(struct elf_phdr *epp, struct elfhdr *ihp,
* process and the system, here we map the page and fill the
* structure
*/
-void irix_map_prda_page (void)
+static void irix_map_prda_page(void)
{
unsigned long v;
struct prda *pp;
@@ -601,14 +582,33 @@ static int load_irix_binary(struct linux_binprm * bprm, struct pt_regs * regs)
load_addr = 0;
has_interp = has_ephdr = 0;
- elf_ihdr = elf_ephdr = 0;
+ elf_ihdr = elf_ephdr = NULL;
elf_ex = *((struct elfhdr *) bprm->buf);
retval = -ENOEXEC;
if (verify_binary(&elf_ex, bprm))
goto out;
-#ifdef DEBUG_ELF
+ /*
+ * Telling -o32 static binaries from Linux and Irix apart from each
+ * other is difficult. There are 2 differences to be noted for static
+ * binaries from the 2 operating systems:
+ *
+ * 1) Irix binaries have their .text section before their .init
+ * section. Linux binaries are just the opposite.
+ *
+ * 2) Irix binaries usually have <= 12 sections and Linux
+ * binaries have > 20.
+ *
+ * We will use Method #2 since Method #1 would require us to read in
+ * the section headers which is way too much overhead. This appears
+ * to work for everything we have ran into so far. If anyone has a
+ * better method to tell the binaries apart, I'm listening.
+ */
+ if (elf_ex.e_shnum > 20)
+ goto out;
+
+#ifdef DEBUG
print_elfhdr(&elf_ex);
#endif
@@ -623,11 +623,10 @@ static int load_irix_binary(struct linux_binprm * bprm, struct pt_regs * regs)
}
retval = kernel_read(bprm->file, elf_ex.e_phoff, (char *)elf_phdata, size);
-
if (retval < 0)
goto out_free_ph;
-#ifdef DEBUG_ELF
+#ifdef DEBUG
dump_phdrs(elf_phdata, elf_ex.e_phnum);
#endif
@@ -644,9 +643,8 @@ static int load_irix_binary(struct linux_binprm * bprm, struct pt_regs * regs)
break;
};
}
-#ifdef DEBUG_ELF
- printk("\n");
-#endif
+
+ pr_debug("\n");
elf_bss = 0;
elf_brk = 0;
@@ -657,12 +655,19 @@ static int load_irix_binary(struct linux_binprm * bprm, struct pt_regs * regs)
end_code = 0;
end_data = 0;
- retval = look_for_irix_interpreter(&elf_interpreter,
- &interpreter,
+ /*
+ * If we get a return value, we change the value to be ENOEXEC
+ * so that we can exit gracefully and the main binary format
+ * search loop in 'fs/exec.c' will move onto the next handler
+ * which should be the normal ELF binary handler.
+ */
+ retval = look_for_irix_interpreter(&elf_interpreter, &interpreter,
&interp_elf_ex, elf_phdata, bprm,
elf_ex.e_phnum);
- if (retval)
+ if (retval) {
+ retval = -ENOEXEC;
goto out_free_file;
+ }
if (elf_interpreter) {
retval = verify_irix_interpreter(&interp_elf_ex);
@@ -692,7 +697,6 @@ static int load_irix_binary(struct linux_binprm * bprm, struct pt_regs * regs)
/* Do this so that we can load the interpreter, if need be. We will
* change some of these later.
*/
- set_mm_counter(current->mm, rss, 0);
setup_arg_pages(bprm, STACK_TOP, EXSTACK_DEFAULT);
current->mm->start_stack = bprm->p;
@@ -746,18 +750,16 @@ static int load_irix_binary(struct linux_binprm * bprm, struct pt_regs * regs)
* IRIX maps a page at 0x200000 which holds some system
* information. Programs depend on this.
*/
- irix_map_prda_page ();
+ irix_map_prda_page();
padzero(elf_bss);
-#ifdef DEBUG_ELF
- printk("(start_brk) %lx\n" , (long) current->mm->start_brk);
- printk("(end_code) %lx\n" , (long) current->mm->end_code);
- printk("(start_code) %lx\n" , (long) current->mm->start_code);
- printk("(end_data) %lx\n" , (long) current->mm->end_data);
- printk("(start_stack) %lx\n" , (long) current->mm->start_stack);
- printk("(brk) %lx\n" , (long) current->mm->brk);
-#endif
+ pr_debug("(start_brk) %lx\n" , (long) current->mm->start_brk);
+ pr_debug("(end_code) %lx\n" , (long) current->mm->end_code);
+ pr_debug("(start_code) %lx\n" , (long) current->mm->start_code);
+ pr_debug("(end_data) %lx\n" , (long) current->mm->end_data);
+ pr_debug("(start_stack) %lx\n" , (long) current->mm->start_stack);
+ pr_debug("(brk) %lx\n" , (long) current->mm->brk);
#if 0 /* XXX No fucking way dude... */
/* Why this, you ask??? Well SVr4 maps page 0 as read-only,
@@ -782,8 +784,7 @@ out_free_dentry:
allow_write_access(interpreter);
fput(interpreter);
out_free_interp:
- if (elf_interpreter)
- kfree(elf_interpreter);
+ kfree(elf_interpreter);
out_free_file:
out_free_ph:
kfree (elf_phdata);
@@ -813,7 +814,7 @@ static int load_irix_library(struct file *file)
/* First of all, some simple consistency checks. */
if(elf_ex.e_type != ET_EXEC || elf_ex.e_phnum > 2 ||
- !irix_elf_check_arch(&elf_ex) || !file->f_op->mmap)
+ !file->f_op->mmap)
return -ENOEXEC;
/* Now read in all of the header information. */
@@ -874,35 +875,36 @@ static int load_irix_library(struct file *file)
* phdrs there are in the USER_PHDRP array. We return the vaddr the
* first phdr was successfully mapped to.
*/
-unsigned long irix_mapelf(int fd, struct elf_phdr *user_phdrp, int cnt)
+unsigned long irix_mapelf(int fd, struct elf_phdr __user *user_phdrp, int cnt)
{
- struct elf_phdr *hp;
+ unsigned long type, vaddr, filesz, offset, flags;
+ struct elf_phdr __user *hp;
struct file *filp;
int i, retval;
-#ifdef DEBUG_ELF
- printk("irix_mapelf: fd[%d] user_phdrp[%p] cnt[%d]\n",
- fd, user_phdrp, cnt);
-#endif
+ pr_debug("irix_mapelf: fd[%d] user_phdrp[%p] cnt[%d]\n",
+ fd, user_phdrp, cnt);
/* First get the verification out of the way. */
hp = user_phdrp;
if (!access_ok(VERIFY_READ, hp, (sizeof(struct elf_phdr) * cnt))) {
-#ifdef DEBUG_ELF
- printk("irix_mapelf: access_ok fails!\n");
-#endif
+ pr_debug("irix_mapelf: bad pointer to ELF PHDR!\n");
+
return -EFAULT;
}
-#ifdef DEBUG_ELF
+#ifdef DEBUG
dump_phdrs(user_phdrp, cnt);
#endif
- for(i = 0; i < cnt; i++, hp++)
- if(hp->p_type != PT_LOAD) {
+ for (i = 0; i < cnt; i++, hp++) {
+ if (__get_user(type, &hp->p_type))
+ return -EFAULT;
+ if (type != PT_LOAD) {
printk("irix_mapelf: One section is not PT_LOAD!\n");
return -ENOEXEC;
}
+ }
filp = fget(fd);
if (!filp)
@@ -917,29 +919,40 @@ unsigned long irix_mapelf(int fd, struct elf_phdr *user_phdrp, int cnt)
for(i = 0; i < cnt; i++, hp++) {
int prot;
- prot = (hp->p_flags & PF_R) ? PROT_READ : 0;
- prot |= (hp->p_flags & PF_W) ? PROT_WRITE : 0;
- prot |= (hp->p_flags & PF_X) ? PROT_EXEC : 0;
+ retval = __get_user(vaddr, &hp->p_vaddr);
+ retval |= __get_user(filesz, &hp->p_filesz);
+ retval |= __get_user(offset, &hp->p_offset);
+ retval |= __get_user(flags, &hp->p_flags);
+ if (retval)
+ return retval;
+
+ prot = (flags & PF_R) ? PROT_READ : 0;
+ prot |= (flags & PF_W) ? PROT_WRITE : 0;
+ prot |= (flags & PF_X) ? PROT_EXEC : 0;
+
down_write(&current->mm->mmap_sem);
- retval = do_mmap(filp, (hp->p_vaddr & 0xfffff000),
- (hp->p_filesz + (hp->p_vaddr & 0xfff)),
+ retval = do_mmap(filp, (vaddr & 0xfffff000),
+ (filesz + (vaddr & 0xfff)),
prot, (MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE),
- (hp->p_offset & 0xfffff000));
+ (offset & 0xfffff000));
up_write(&current->mm->mmap_sem);
- if(retval != (hp->p_vaddr & 0xfffff000)) {
+ if (retval != (vaddr & 0xfffff000)) {
printk("irix_mapelf: do_mmap fails with %d!\n", retval);
fput(filp);
return retval;
}
}
-#ifdef DEBUG_ELF
- printk("irix_mapelf: Success, returning %08lx\n",
- (unsigned long) user_phdrp->p_vaddr);
-#endif
+ pr_debug("irix_mapelf: Success, returning %08lx\n",
+ (unsigned long) user_phdrp->p_vaddr);
+
fput(filp);
- return user_phdrp->p_vaddr;
+
+ if (__get_user(vaddr, &user_phdrp->p_vaddr))
+ return -EFAULT;
+
+ return vaddr;
}
/*
@@ -952,9 +965,9 @@ unsigned long irix_mapelf(int fd, struct elf_phdr *user_phdrp, int cnt)
/* These are the only things you should do on a core-file: use only these
* functions to write out all the necessary info.
*/
-static int dump_write(struct file *file, const void *addr, int nr)
+static int dump_write(struct file *file, const void __user *addr, int nr)
{
- return file->f_op->write(file, addr, nr, &file->f_pos) == nr;
+ return file->f_op->write(file, (const char __user *) addr, nr, &file->f_pos) == nr;
}
static int dump_seek(struct file *file, off_t off)
@@ -1064,8 +1077,8 @@ static int irix_core_dump(long signr, struct pt_regs * regs, struct file *file)
struct elfhdr elf;
off_t offset = 0, dataoff;
int limit = current->signal->rlim[RLIMIT_CORE].rlim_cur;
- int numnote = 4;
- struct memelfnote notes[4];
+ int numnote = 3;
+ struct memelfnote notes[3];
struct elf_prstatus prstatus; /* NT_PRSTATUS */
elf_fpregset_t fpu; /* NT_PRFPREG */
struct elf_prpsinfo psinfo; /* NT_PRPSINFO */
@@ -1073,7 +1086,7 @@ static int irix_core_dump(long signr, struct pt_regs * regs, struct file *file)
/* Count what's needed to dump, up to the limit of coredump size. */
segs = 0;
size = 0;
- for(vma = current->mm->mmap; vma != NULL; vma = vma->vm_next) {
+ for (vma = current->mm->mmap; vma != NULL; vma = vma->vm_next) {
if (maydump(vma))
{
int sz = vma->vm_end-vma->vm_start;
@@ -1187,9 +1200,9 @@ static int irix_core_dump(long signr, struct pt_regs * regs, struct file *file)
len = current->mm->arg_end - current->mm->arg_start;
len = len >= ELF_PRARGSZ ? ELF_PRARGSZ : len;
- copy_from_user(&psinfo.pr_psargs,
- (const char *)current->mm->arg_start, len);
- for(i = 0; i < len; i++)
+ (void *) copy_from_user(&psinfo.pr_psargs,
+ (const char __user *)current->mm->arg_start, len);
+ for (i = 0; i < len; i++)
if (psinfo.pr_psargs[i] == 0)
psinfo.pr_psargs[i] = ' ';
psinfo.pr_psargs[len] = 0;
@@ -1198,20 +1211,15 @@ static int irix_core_dump(long signr, struct pt_regs * regs, struct file *file)
}
strlcpy(psinfo.pr_fname, current->comm, sizeof(psinfo.pr_fname));
- notes[2].name = "CORE";
- notes[2].type = NT_TASKSTRUCT;
- notes[2].datasz = sizeof(*current);
- notes[2].data = current;
-
/* Try to dump the FPU. */
prstatus.pr_fpvalid = dump_fpu (regs, &fpu);
if (!prstatus.pr_fpvalid) {
numnote--;
} else {
- notes[3].name = "CORE";
- notes[3].type = NT_PRFPREG;
- notes[3].datasz = sizeof(fpu);
- notes[3].data = &fpu;
+ notes[2].name = "CORE";
+ notes[2].type = NT_PRFPREG;
+ notes[2].datasz = sizeof(fpu);
+ notes[2].data = &fpu;
}
/* Write notes phdr entry. */
@@ -1256,8 +1264,10 @@ static int irix_core_dump(long signr, struct pt_regs * regs, struct file *file)
phdr.p_memsz = sz;
offset += phdr.p_filesz;
phdr.p_flags = vma->vm_flags & VM_READ ? PF_R : 0;
- if (vma->vm_flags & VM_WRITE) phdr.p_flags |= PF_W;
- if (vma->vm_flags & VM_EXEC) phdr.p_flags |= PF_X;
+ if (vma->vm_flags & VM_WRITE)
+ phdr.p_flags |= PF_W;
+ if (vma->vm_flags & VM_EXEC)
+ phdr.p_flags |= PF_X;
phdr.p_align = PAGE_SIZE;
DUMP_WRITE(&phdr, sizeof(phdr));
@@ -1283,7 +1293,7 @@ static int irix_core_dump(long signr, struct pt_regs * regs, struct file *file)
#ifdef DEBUG
printk("elf_core_dump: writing %08lx %lx\n", addr, len);
#endif
- DUMP_WRITE((void *)addr, len);
+ DUMP_WRITE((void __user *)addr, len);
}
if ((off_t) file->f_pos != offset) {
@@ -1299,7 +1309,7 @@ end_coredump:
static int __init init_irix_binfmt(void)
{
- int init_inventory(void);
+ extern int init_inventory(void);
extern asmlinkage unsigned long sys_call_table;
extern asmlinkage unsigned long sys_call_table_irix5;
@@ -1318,7 +1328,9 @@ static int __init init_irix_binfmt(void)
static void __exit exit_irix_binfmt(void)
{
- /* Remove the IRIX ELF loaders. */
+ /*
+ * Remove the Irix ELF loader.
+ */
unregister_binfmt(&irix_format);
}
diff --git a/arch/mips/kernel/irixinv.c b/arch/mips/kernel/irixinv.c
index 60aa98cd1791..de8584f62311 100644
--- a/arch/mips/kernel/irixinv.c
+++ b/arch/mips/kernel/irixinv.c
@@ -30,10 +30,10 @@ void add_to_inventory (int class, int type, int controller, int unit, int state)
inventory_items++;
}
-int dump_inventory_to_user (void *userbuf, int size)
+int dump_inventory_to_user (void __user *userbuf, int size)
{
inventory_t *inv = &inventory [0];
- inventory_t *user = userbuf;
+ inventory_t __user *user = userbuf;
int v;
if (!access_ok(VERIFY_WRITE, userbuf, size))
@@ -41,7 +41,8 @@ int dump_inventory_to_user (void *userbuf, int size)
for (v = 0; v < inventory_items; v++){
inv = &inventory [v];
- copy_to_user (user, inv, sizeof (inventory_t));
+ if (copy_to_user (user, inv, sizeof (inventory_t)))
+ return -EFAULT;
user++;
}
return inventory_items * sizeof (inventory_t);
diff --git a/arch/mips/kernel/irixioctl.c b/arch/mips/kernel/irixioctl.c
index 3cdc22346f4c..e2863821a3dd 100644
--- a/arch/mips/kernel/irixioctl.c
+++ b/arch/mips/kernel/irixioctl.c
@@ -59,7 +59,7 @@ asmlinkage int irix_ioctl(int fd, unsigned long cmd, unsigned long arg)
{
struct tty_struct *tp, *rtp;
mm_segment_t old_fs;
- int error = 0;
+ int i, error = 0;
#ifdef DEBUG_IOCTLS
printk("[%s:%d] irix_ioctl(%d, ", current->comm, current->pid, fd);
@@ -74,12 +74,13 @@ asmlinkage int irix_ioctl(int fd, unsigned long cmd, unsigned long arg)
case 0x0000540d: {
struct termios kt;
- struct irix_termios *it = (struct irix_termios *) arg;
+ struct irix_termios __user *it =
+ (struct irix_termios __user *) arg;
#ifdef DEBUG_IOCTLS
printk("TCGETS, %08lx) ", arg);
#endif
- if(!access_ok(VERIFY_WRITE, it, sizeof(*it))) {
+ if (!access_ok(VERIFY_WRITE, it, sizeof(*it))) {
error = -EFAULT;
break;
}
@@ -88,13 +89,14 @@ asmlinkage int irix_ioctl(int fd, unsigned long cmd, unsigned long arg)
set_fs(old_fs);
if (error)
break;
- __put_user(kt.c_iflag, &it->c_iflag);
- __put_user(kt.c_oflag, &it->c_oflag);
- __put_user(kt.c_cflag, &it->c_cflag);
- __put_user(kt.c_lflag, &it->c_lflag);
- for(error = 0; error < NCCS; error++)
- __put_user(kt.c_cc[error], &it->c_cc[error]);
- error = 0;
+
+ error = __put_user(kt.c_iflag, &it->c_iflag);
+ error |= __put_user(kt.c_oflag, &it->c_oflag);
+ error |= __put_user(kt.c_cflag, &it->c_cflag);
+ error |= __put_user(kt.c_lflag, &it->c_lflag);
+
+ for (i = 0; i < NCCS; i++)
+ error |= __put_user(kt.c_cc[i], &it->c_cc[i]);
break;
}
@@ -112,14 +114,19 @@ asmlinkage int irix_ioctl(int fd, unsigned long cmd, unsigned long arg)
old_fs = get_fs(); set_fs(get_ds());
error = sys_ioctl(fd, TCGETS, (unsigned long) &kt);
set_fs(old_fs);
- if(error)
+ if (error)
+ break;
+
+ error = __get_user(kt.c_iflag, &it->c_iflag);
+ error |= __get_user(kt.c_oflag, &it->c_oflag);
+ error |= __get_user(kt.c_cflag, &it->c_cflag);
+ error |= __get_user(kt.c_lflag, &it->c_lflag);
+
+ for (i = 0; i < NCCS; i++)
+ error |= __get_user(kt.c_cc[i], &it->c_cc[i]);
+
+ if (error)
break;
- __get_user(kt.c_iflag, &it->c_iflag);
- __get_user(kt.c_oflag, &it->c_oflag);
- __get_user(kt.c_cflag, &it->c_cflag);
- __get_user(kt.c_lflag, &it->c_lflag);
- for(error = 0; error < NCCS; error++)
- __get_user(kt.c_cc[error], &it->c_cc[error]);
old_fs = get_fs(); set_fs(get_ds());
error = sys_ioctl(fd, TCSETS, (unsigned long) &kt);
set_fs(old_fs);
@@ -153,7 +160,7 @@ asmlinkage int irix_ioctl(int fd, unsigned long cmd, unsigned long arg)
#ifdef DEBUG_IOCTLS
printk("rtp->session=%d ", rtp->session);
#endif
- error = put_user(rtp->session, (unsigned long *) arg);
+ error = put_user(rtp->session, (unsigned long __user *) arg);
break;
case 0x746e:
@@ -195,50 +202,32 @@ asmlinkage int irix_ioctl(int fd, unsigned long cmd, unsigned long arg)
break;
case 0x8004667e:
-#ifdef DEBUG_IOCTLS
- printk("FIONBIO, %08lx) arg=%d ", arg, *(int *)arg);
-#endif
error = sys_ioctl(fd, FIONBIO, arg);
break;
case 0x80047476:
-#ifdef DEBUG_IOCTLS
- printk("TIOCSPGRP, %08lx) arg=%d ", arg, *(int *)arg);
-#endif
error = sys_ioctl(fd, TIOCSPGRP, arg);
break;
case 0x8020690c:
-#ifdef DEBUG_IOCTLS
- printk("SIOCSIFADDR, %08lx) arg=%d ", arg, *(int *)arg);
-#endif
error = sys_ioctl(fd, SIOCSIFADDR, arg);
break;
case 0x80206910:
-#ifdef DEBUG_IOCTLS
- printk("SIOCSIFFLAGS, %08lx) arg=%d ", arg, *(int *)arg);
-#endif
error = sys_ioctl(fd, SIOCSIFFLAGS, arg);
break;
case 0xc0206911:
-#ifdef DEBUG_IOCTLS
- printk("SIOCGIFFLAGS, %08lx) arg=%d ", arg, *(int *)arg);
-#endif
error = sys_ioctl(fd, SIOCGIFFLAGS, arg);
break;
case 0xc020691b:
-#ifdef DEBUG_IOCTLS
- printk("SIOCGIFMETRIC, %08lx) arg=%d ", arg, *(int *)arg);
-#endif
error = sys_ioctl(fd, SIOCGIFMETRIC, arg);
break;
default: {
#ifdef DEBUG_MISSING_IOCTL
- char *msg = "Unimplemented IOCTL cmd tell linux@engr.sgi.com\n";
+ char *msg = "Unimplemented IOCTL cmd tell linux-mips@linux-mips.org\n";
#ifdef DEBUG_IOCTLS
printk("UNIMP_IOCTL, %08lx)\n", arg);
diff --git a/arch/mips/kernel/irixsig.c b/arch/mips/kernel/irixsig.c
index eff89322ba50..dd118c60bcd0 100644
--- a/arch/mips/kernel/irixsig.c
+++ b/arch/mips/kernel/irixsig.c
@@ -76,36 +76,39 @@ static inline void dump_irix5_sigctx(struct sigctx_irix5 *c)
}
#endif
-static void setup_irix_frame(struct k_sigaction *ka, struct pt_regs *regs,
- int signr, sigset_t *oldmask)
+static int setup_irix_frame(struct k_sigaction *ka, struct pt_regs *regs,
+ int signr, sigset_t *oldmask)
{
+ struct sigctx_irix5 __user *ctx;
unsigned long sp;
- struct sigctx_irix5 *ctx;
- int i;
+ int error, i;
sp = regs->regs[29];
sp -= sizeof(struct sigctx_irix5);
sp &= ~(0xf);
- ctx = (struct sigctx_irix5 *) sp;
+ ctx = (struct sigctx_irix5 __user *) sp;
if (!access_ok(VERIFY_WRITE, ctx, sizeof(*ctx)))
goto segv_and_exit;
- __put_user(0, &ctx->weird_fpu_thing);
- __put_user(~(0x00000001), &ctx->rmask);
- __put_user(0, &ctx->regs[0]);
+ error = __put_user(0, &ctx->weird_fpu_thing);
+ error |= __put_user(~(0x00000001), &ctx->rmask);
+ error |= __put_user(0, &ctx->regs[0]);
for(i = 1; i < 32; i++)
- __put_user((u64) regs->regs[i], &ctx->regs[i]);
+ error |= __put_user((u64) regs->regs[i], &ctx->regs[i]);
+
+ error |= __put_user((u64) regs->hi, &ctx->hi);
+ error |= __put_user((u64) regs->lo, &ctx->lo);
+ error |= __put_user((u64) regs->cp0_epc, &ctx->pc);
+ error |= __put_user(!!used_math(), &ctx->usedfp);
+ error |= __put_user((u64) regs->cp0_cause, &ctx->cp0_cause);
+ error |= __put_user((u64) regs->cp0_badvaddr, &ctx->cp0_badvaddr);
- __put_user((u64) regs->hi, &ctx->hi);
- __put_user((u64) regs->lo, &ctx->lo);
- __put_user((u64) regs->cp0_epc, &ctx->pc);
- __put_user(!!used_math(), &ctx->usedfp);
- __put_user((u64) regs->cp0_cause, &ctx->cp0_cause);
- __put_user((u64) regs->cp0_badvaddr, &ctx->cp0_badvaddr);
+ error |= __put_user(0, &ctx->sstk_flags); /* XXX sigstack unimp... todo... */
- __put_user(0, &ctx->sstk_flags); /* XXX sigstack unimp... todo... */
+ error |= __copy_to_user(&ctx->sigset, oldmask, sizeof(irix_sigset_t)) ? -EFAULT : 0;
- __copy_to_user(&ctx->sigset, oldmask, sizeof(irix_sigset_t));
+ if (error)
+ goto segv_and_exit;
#ifdef DEBUG_SIG
dump_irix5_sigctx(ctx);
@@ -117,13 +120,14 @@ static void setup_irix_frame(struct k_sigaction *ka, struct pt_regs *regs,
regs->regs[7] = (unsigned long) ka->sa.sa_handler;
regs->regs[25] = regs->cp0_epc = (unsigned long) ka->sa_restorer;
- return;
+ return 1;
segv_and_exit:
force_sigsegv(signr, current);
+ return 0;
}
-static void inline
+static int inline
setup_irix_rt_frame(struct k_sigaction * ka, struct pt_regs *regs,
int signr, sigset_t *oldmask, siginfo_t *info)
{
@@ -131,9 +135,11 @@ setup_irix_rt_frame(struct k_sigaction * ka, struct pt_regs *regs,
do_exit(SIGSEGV);
}
-static inline void handle_signal(unsigned long sig, siginfo_t *info,
+static inline int handle_signal(unsigned long sig, siginfo_t *info,
struct k_sigaction *ka, sigset_t *oldset, struct pt_regs * regs)
{
+ int ret;
+
switch(regs->regs[0]) {
case ERESTARTNOHAND:
regs->regs[2] = EINTR;
@@ -151,9 +157,9 @@ static inline void handle_signal(unsigned long sig, siginfo_t *info,
regs->regs[0] = 0; /* Don't deal with this again. */
if (ka->sa.sa_flags & SA_SIGINFO)
- setup_irix_rt_frame(ka, regs, sig, oldset, info);
+ ret = setup_irix_rt_frame(ka, regs, sig, oldset, info);
else
- setup_irix_frame(ka, regs, sig, oldset);
+ ret = setup_irix_frame(ka, regs, sig, oldset);
spin_lock_irq(&current->sighand->siglock);
sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
@@ -161,6 +167,8 @@ static inline void handle_signal(unsigned long sig, siginfo_t *info,
sigaddset(&current->blocked,sig);
recalc_sigpending();
spin_unlock_irq(&current->sighand->siglock);
+
+ return ret;
}
asmlinkage int do_irix_signal(sigset_t *oldset, struct pt_regs *regs)
@@ -184,10 +192,8 @@ asmlinkage int do_irix_signal(sigset_t *oldset, struct pt_regs *regs)
oldset = &current->blocked;
signr = get_signal_to_deliver(&info, &ka, regs, NULL);
- if (signr > 0) {
- handle_signal(signr, &info, &ka, oldset, regs);
- return 1;
- }
+ if (signr > 0)
+ return handle_signal(signr, &info, &ka, oldset, regs);
no_signal:
/*
@@ -208,10 +214,11 @@ no_signal:
asmlinkage void
irix_sigreturn(struct pt_regs *regs)
{
- struct sigctx_irix5 *context, *magic;
+ struct sigctx_irix5 __user *context, *magic;
unsigned long umask, mask;
u64 *fregs;
- int sig, i, base = 0;
+ u32 usedfp;
+ int error, sig, i, base = 0;
sigset_t blocked;
/* Always make any pending restarted system calls return -EINTR */
@@ -220,8 +227,8 @@ irix_sigreturn(struct pt_regs *regs)
if (regs->regs[2] == 1000)
base = 1;
- context = (struct sigctx_irix5 *) regs->regs[base + 4];
- magic = (struct sigctx_irix5 *) regs->regs[base + 5];
+ context = (struct sigctx_irix5 __user *) regs->regs[base + 4];
+ magic = (struct sigctx_irix5 __user *) regs->regs[base + 5];
sig = (int) regs->regs[base + 6];
#ifdef DEBUG_SIG
printk("[%s:%d] IRIX sigreturn(scp[%p],ucp[%p],sig[%d])\n",
@@ -236,25 +243,31 @@ irix_sigreturn(struct pt_regs *regs)
dump_irix5_sigctx(context);
#endif
- __get_user(regs->cp0_epc, &context->pc);
- umask = context->rmask; mask = 2;
+ error = __get_user(regs->cp0_epc, &context->pc);
+ error |= __get_user(umask, &context->rmask);
+
+ mask = 2;
for (i = 1; i < 32; i++, mask <<= 1) {
- if(umask & mask)
- __get_user(regs->regs[i], &context->regs[i]);
+ if (umask & mask)
+ error |= __get_user(regs->regs[i], &context->regs[i]);
}
- __get_user(regs->hi, &context->hi);
- __get_user(regs->lo, &context->lo);
+ error |= __get_user(regs->hi, &context->hi);
+ error |= __get_user(regs->lo, &context->lo);
- if ((umask & 1) && context->usedfp) {
+ error |= __get_user(usedfp, &context->usedfp);
+ if ((umask & 1) && usedfp) {
fregs = (u64 *) &current->thread.fpu;
+
for(i = 0; i < 32; i++)
- fregs[i] = (u64) context->fpregs[i];
- __get_user(current->thread.fpu.hard.fcr31, &context->fpcsr);
+ error |= __get_user(fregs[i], &context->fpregs[i]);
+ error |= __get_user(current->thread.fpu.hard.fcr31, &context->fpcsr);
}
/* XXX do sigstack crapola here... XXX */
- if (__copy_from_user(&blocked, &context->sigset, sizeof(blocked)))
+ error |= __copy_from_user(&blocked, &context->sigset, sizeof(blocked)) ? -EFAULT : 0;
+
+ if (error)
goto badframe;
sigdelsetmask(&blocked, ~_BLOCKABLE);
@@ -296,8 +309,8 @@ static inline void dump_sigact_irix5(struct sigact_irix5 *p)
#endif
asmlinkage int
-irix_sigaction(int sig, const struct sigaction *act,
- struct sigaction *oact, void *trampoline)
+irix_sigaction(int sig, const struct sigaction __user *act,
+ struct sigaction __user *oact, void __user *trampoline)
{
struct k_sigaction new_ka, old_ka;
int ret;
@@ -311,12 +324,16 @@ irix_sigaction(int sig, const struct sigaction *act,
#endif
if (act) {
sigset_t mask;
- if (!access_ok(VERIFY_READ, act, sizeof(*act)) ||
- __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
- __get_user(new_ka.sa.sa_flags, &act->sa_flags))
+ int err;
+
+ if (!access_ok(VERIFY_READ, act, sizeof(*act)))
return -EFAULT;
+ err = __get_user(new_ka.sa.sa_handler, &act->sa_handler);
+ err |= __get_user(new_ka.sa.sa_flags, &act->sa_flags);
- __copy_from_user(&mask, &act->sa_mask, sizeof(sigset_t));
+ err |= __copy_from_user(&mask, &act->sa_mask, sizeof(sigset_t)) ? -EFAULT : 0;
+ if (err)
+ return err;
/*
* Hmmm... methinks IRIX libc always passes a valid trampoline
@@ -330,30 +347,37 @@ irix_sigaction(int sig, const struct sigaction *act,
ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
if (!ret && oact) {
- if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) ||
- __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
- __put_user(old_ka.sa.sa_flags, &oact->sa_flags))
+ int err;
+
+ if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)))
+ return -EFAULT;
+
+ err = __put_user(old_ka.sa.sa_handler, &oact->sa_handler);
+ err |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
+ err |= __copy_to_user(&oact->sa_mask, &old_ka.sa.sa_mask,
+ sizeof(sigset_t)) ? -EFAULT : 0;
+ if (err)
return -EFAULT;
- __copy_to_user(&old_ka.sa.sa_mask, &oact->sa_mask,
- sizeof(sigset_t));
}
return ret;
}
-asmlinkage int irix_sigpending(irix_sigset_t *set)
+asmlinkage int irix_sigpending(irix_sigset_t __user *set)
{
return do_sigpending(set, sizeof(*set));
}
-asmlinkage int irix_sigprocmask(int how, irix_sigset_t *new, irix_sigset_t *old)
+asmlinkage int irix_sigprocmask(int how, irix_sigset_t __user *new,
+ irix_sigset_t __user *old)
{
sigset_t oldbits, newbits;
if (new) {
if (!access_ok(VERIFY_READ, new, sizeof(*new)))
return -EFAULT;
- __copy_from_user(&newbits, new, sizeof(unsigned long)*4);
+ if (__copy_from_user(&newbits, new, sizeof(unsigned long)*4))
+ return -EFAULT;
sigdelsetmask(&newbits, ~_BLOCKABLE);
spin_lock_irq(&current->sighand->siglock);
@@ -381,20 +405,19 @@ asmlinkage int irix_sigprocmask(int how, irix_sigset_t *new, irix_sigset_t *old)
recalc_sigpending();
spin_unlock_irq(&current->sighand->siglock);
}
- if(old) {
- if (!access_ok(VERIFY_WRITE, old, sizeof(*old)))
- return -EFAULT;
- __copy_to_user(old, &current->blocked, sizeof(unsigned long)*4);
- }
+ if (old)
+ return copy_to_user(old, &current->blocked,
+ sizeof(unsigned long)*4) ? -EFAULT : 0;
return 0;
}
asmlinkage int irix_sigsuspend(struct pt_regs *regs)
{
- sigset_t *uset, saveset, newset;
+ sigset_t saveset, newset;
+ sigset_t __user *uset;
- uset = (sigset_t *) regs->regs[4];
+ uset = (sigset_t __user *) regs->regs[4];
if (copy_from_user(&newset, uset, sizeof(sigset_t)))
return -EFAULT;
sigdelsetmask(&newset, ~_BLOCKABLE);
@@ -440,12 +463,13 @@ struct irix5_siginfo {
} stuff;
};
-asmlinkage int irix_sigpoll_sys(unsigned long *set, struct irix5_siginfo *info,
- struct timespec *tp)
+asmlinkage int irix_sigpoll_sys(unsigned long __user *set,
+ struct irix5_siginfo __user *info, struct timespec __user *tp)
{
long expire = MAX_SCHEDULE_TIMEOUT;
sigset_t kset;
int i, sig, error, timeo = 0;
+ struct timespec ktp;
#ifdef DEBUG_SIG
printk("[%s:%d] irix_sigpoll_sys(%p,%p,%p)\n",
@@ -456,14 +480,8 @@ asmlinkage int irix_sigpoll_sys(unsigned long *set, struct irix5_siginfo *info,
if (!set)
return -EINVAL;
- if (!access_ok(VERIFY_READ, set, sizeof(kset))) {
- error = -EFAULT;
- goto out;
- }
-
- __copy_from_user(&kset, set, sizeof(set));
- if (error)
- goto out;
+ if (copy_from_user(&kset, set, sizeof(set)))
+ return -EFAULT;
if (info && clear_user(info, sizeof(*info))) {
error = -EFAULT;
@@ -471,13 +489,14 @@ asmlinkage int irix_sigpoll_sys(unsigned long *set, struct irix5_siginfo *info,
}
if (tp) {
- if (!access_ok(VERIFY_READ, tp, sizeof(*tp)))
+ if (copy_from_user(&ktp, tp, sizeof(*tp)))
return -EFAULT;
- if (!tp->tv_sec && !tp->tv_nsec) {
- error = -EINVAL;
- goto out;
- }
- expire = timespec_to_jiffies(tp) + (tp->tv_sec||tp->tv_nsec);
+
+ if (!ktp.tv_sec && !ktp.tv_nsec)
+ return -EINVAL;
+
+ expire = timespec_to_jiffies(&ktp) +
+ (ktp.tv_sec || ktp.tv_nsec);
}
while(1) {
@@ -500,15 +519,14 @@ asmlinkage int irix_sigpoll_sys(unsigned long *set, struct irix5_siginfo *info,
if (timeo)
return -EAGAIN;
- for(sig = 1; i <= 65 /* IRIX_NSIG */; sig++) {
+ for (sig = 1; i <= 65 /* IRIX_NSIG */; sig++) {
if (sigismember (&kset, sig))
continue;
if (sigismember (&current->pending.signal, sig)) {
/* XXX need more than this... */
if (info)
- info->sig = sig;
- error = 0;
- goto out;
+ return copy_to_user(&info->sig, &sig, sizeof(sig));
+ return 0;
}
}
@@ -534,8 +552,9 @@ extern int getrusage(struct task_struct *, int, struct rusage __user *);
#define W_MASK (W_EXITED | W_TRAPPED | W_STOPPED | W_CONT | W_NOHANG)
-asmlinkage int irix_waitsys(int type, int pid, struct irix5_siginfo *info,
- int options, struct rusage *ru)
+asmlinkage int irix_waitsys(int type, int pid,
+ struct irix5_siginfo __user *info, int options,
+ struct rusage __user *ru)
{
int flag, retval;
DECLARE_WAITQUEUE(wait, current);
@@ -543,28 +562,22 @@ asmlinkage int irix_waitsys(int type, int pid, struct irix5_siginfo *info,
struct task_struct *p;
struct list_head *_p;
- if (!info) {
- retval = -EINVAL;
- goto out;
- }
- if (!access_ok(VERIFY_WRITE, info, sizeof(*info))) {
- retval = -EFAULT;
- goto out;
- }
- if (ru) {
- if (!access_ok(VERIFY_WRITE, ru, sizeof(*ru))) {
- retval = -EFAULT;
- goto out;
- }
- }
- if (options & ~(W_MASK)) {
- retval = -EINVAL;
- goto out;
- }
- if (type != IRIX_P_PID && type != IRIX_P_PGID && type != IRIX_P_ALL) {
- retval = -EINVAL;
- goto out;
- }
+ if (!info)
+ return -EINVAL;
+
+ if (!access_ok(VERIFY_WRITE, info, sizeof(*info)))
+ return -EFAULT;
+
+ if (ru)
+ if (!access_ok(VERIFY_WRITE, ru, sizeof(*ru)))
+ return -EFAULT;
+
+ if (options & ~W_MASK)
+ return -EINVAL;
+
+ if (type != IRIX_P_PID && type != IRIX_P_PGID && type != IRIX_P_ALL)
+ return -EINVAL;
+
add_wait_queue(&current->signal->wait_chldexit, &wait);
repeat:
flag = 0;
@@ -595,18 +608,20 @@ repeat:
add_parent(p, p->parent);
write_unlock_irq(&tasklist_lock);
retval = ru ? getrusage(p, RUSAGE_BOTH, ru) : 0;
- if (!retval && ru) {
- retval |= __put_user(SIGCHLD, &info->sig);
- retval |= __put_user(0, &info->code);
- retval |= __put_user(p->pid, &info->stuff.procinfo.pid);
- retval |= __put_user((p->exit_code >> 8) & 0xff,
- &info->stuff.procinfo.procdata.child.status);
- retval |= __put_user(p->utime, &info->stuff.procinfo.procdata.child.utime);
- retval |= __put_user(p->stime, &info->stuff.procinfo.procdata.child.stime);
- }
- if (!retval) {
- p->exit_code = 0;
- }
+ if (retval)
+ goto end_waitsys;
+
+ retval = __put_user(SIGCHLD, &info->sig);
+ retval |= __put_user(0, &info->code);
+ retval |= __put_user(p->pid, &info->stuff.procinfo.pid);
+ retval |= __put_user((p->exit_code >> 8) & 0xff,
+ &info->stuff.procinfo.procdata.child.status);
+ retval |= __put_user(p->utime, &info->stuff.procinfo.procdata.child.utime);
+ retval |= __put_user(p->stime, &info->stuff.procinfo.procdata.child.stime);
+ if (retval)
+ goto end_waitsys;
+
+ p->exit_code = 0;
goto end_waitsys;
case EXIT_ZOMBIE:
@@ -614,16 +629,18 @@ repeat:
current->signal->cstime += p->stime + p->signal->cstime;
if (ru != NULL)
getrusage(p, RUSAGE_BOTH, ru);
- __put_user(SIGCHLD, &info->sig);
- __put_user(1, &info->code); /* CLD_EXITED */
- __put_user(p->pid, &info->stuff.procinfo.pid);
- __put_user((p->exit_code >> 8) & 0xff,
+ retval = __put_user(SIGCHLD, &info->sig);
+ retval |= __put_user(1, &info->code); /* CLD_EXITED */
+ retval |= __put_user(p->pid, &info->stuff.procinfo.pid);
+ retval |= __put_user((p->exit_code >> 8) & 0xff,
&info->stuff.procinfo.procdata.child.status);
- __put_user(p->utime,
+ retval |= __put_user(p->utime,
&info->stuff.procinfo.procdata.child.utime);
- __put_user(p->stime,
+ retval |= __put_user(p->stime,
&info->stuff.procinfo.procdata.child.stime);
- retval = 0;
+ if (retval)
+ return retval;
+
if (p->real_parent != p->parent) {
write_lock_irq(&tasklist_lock);
remove_parent(p);
@@ -656,7 +673,6 @@ end_waitsys:
current->state = TASK_RUNNING;
remove_wait_queue(&current->signal->wait_chldexit, &wait);
-out:
return retval;
}
@@ -675,39 +691,39 @@ struct irix5_context {
asmlinkage int irix_getcontext(struct pt_regs *regs)
{
- int i, base = 0;
- struct irix5_context *ctx;
+ int error, i, base = 0;
+ struct irix5_context __user *ctx;
unsigned long flags;
if (regs->regs[2] == 1000)
base = 1;
- ctx = (struct irix5_context *) regs->regs[base + 4];
+ ctx = (struct irix5_context __user *) regs->regs[base + 4];
#ifdef DEBUG_SIG
printk("[%s:%d] irix_getcontext(%p)\n",
current->comm, current->pid, ctx);
#endif
- if (!access_ok(VERIFY_WRITE, ctx, sizeof(*ctx)))
+ if (!access_ok(VERIFY_WRITE, ctx, sizeof(*ctx)));
return -EFAULT;
- __put_user(current->thread.irix_oldctx, &ctx->link);
+ error = __put_user(current->thread.irix_oldctx, &ctx->link);
- __copy_to_user(&ctx->sigmask, &current->blocked, sizeof(irix_sigset_t));
+ error |= __copy_to_user(&ctx->sigmask, &current->blocked, sizeof(irix_sigset_t)) ? -EFAULT : 0;
/* XXX Do sigstack stuff someday... */
- __put_user(0, &ctx->stack.sp);
- __put_user(0, &ctx->stack.size);
- __put_user(0, &ctx->stack.flags);
+ error |= __put_user(0, &ctx->stack.sp);
+ error |= __put_user(0, &ctx->stack.size);
+ error |= __put_user(0, &ctx->stack.flags);
- __put_user(0, &ctx->weird_graphics_thing);
- __put_user(0, &ctx->regs[0]);
+ error |= __put_user(0, &ctx->weird_graphics_thing);
+ error |= __put_user(0, &ctx->regs[0]);
for (i = 1; i < 32; i++)
- __put_user(regs->regs[i], &ctx->regs[i]);
- __put_user(regs->lo, &ctx->regs[32]);
- __put_user(regs->hi, &ctx->regs[33]);
- __put_user(regs->cp0_cause, &ctx->regs[34]);
- __put_user(regs->cp0_epc, &ctx->regs[35]);
+ error |= __put_user(regs->regs[i], &ctx->regs[i]);
+ error |= __put_user(regs->lo, &ctx->regs[32]);
+ error |= __put_user(regs->hi, &ctx->regs[33]);
+ error |= __put_user(regs->cp0_cause, &ctx->regs[34]);
+ error |= __put_user(regs->cp0_epc, &ctx->regs[35]);
flags = 0x0f;
if (!used_math()) {
@@ -716,119 +732,124 @@ asmlinkage int irix_getcontext(struct pt_regs *regs)
/* XXX wheee... */
printk("Wheee, no code for saving IRIX FPU context yet.\n");
}
- __put_user(flags, &ctx->flags);
+ error |= __put_user(flags, &ctx->flags);
- return 0;
+ return error;
}
-asmlinkage unsigned long irix_setcontext(struct pt_regs *regs)
+asmlinkage void irix_setcontext(struct pt_regs *regs)
{
- int error, base = 0;
- struct irix5_context *ctx;
+ struct irix5_context __user *ctx;
+ int err, base = 0;
+ u32 flags;
- if(regs->regs[2] == 1000)
+ if (regs->regs[2] == 1000)
base = 1;
- ctx = (struct irix5_context *) regs->regs[base + 4];
+ ctx = (struct irix5_context __user *) regs->regs[base + 4];
#ifdef DEBUG_SIG
printk("[%s:%d] irix_setcontext(%p)\n",
current->comm, current->pid, ctx);
#endif
- if (!access_ok(VERIFY_READ, ctx, sizeof(*ctx))) {
- error = -EFAULT;
- goto out;
- }
+ if (!access_ok(VERIFY_READ, ctx, sizeof(*ctx)))
+ goto segv_and_exit;
- if (ctx->flags & 0x02) {
+ err = __get_user(flags, &ctx->flags);
+ if (flags & 0x02) {
/* XXX sigstack garbage, todo... */
printk("Wheee, cannot do sigstack stuff in setcontext\n");
}
- if (ctx->flags & 0x04) {
+ if (flags & 0x04) {
int i;
/* XXX extra control block stuff... todo... */
- for(i = 1; i < 32; i++)
- regs->regs[i] = ctx->regs[i];
- regs->lo = ctx->regs[32];
- regs->hi = ctx->regs[33];
- regs->cp0_epc = ctx->regs[35];
+ for (i = 1; i < 32; i++)
+ err |= __get_user(regs->regs[i], &ctx->regs[i]);
+ err |= __get_user(regs->lo, &ctx->regs[32]);
+ err |= __get_user(regs->hi, &ctx->regs[33]);
+ err |= __get_user(regs->cp0_epc, &ctx->regs[35]);
}
- if (ctx->flags & 0x08) {
+ if (flags & 0x08)
/* XXX fpu context, blah... */
- printk("Wheee, cannot restore FPU context yet...\n");
- }
- current->thread.irix_oldctx = ctx->link;
- error = regs->regs[2];
+ printk(KERN_ERR "Wheee, cannot restore FPU context yet...\n");
-out:
- return error;
+ err |= __get_user(current->thread.irix_oldctx, &ctx->link);
+ if (err)
+ goto segv_and_exit;
+
+ /*
+ * Don't let your children do this ...
+ */
+ if (current_thread_info()->flags & TIF_SYSCALL_TRACE)
+ do_syscall_trace(regs, 1);
+ __asm__ __volatile__(
+ "move\t$29,%0\n\t"
+ "j\tsyscall_exit"
+ :/* no outputs */
+ :"r" (&regs));
+ /* Unreached */
+
+segv_and_exit:
+ force_sigsegv(SIGSEGV, current);
}
-struct irix_sigstack { unsigned long sp; int status; };
+struct irix_sigstack {
+ unsigned long sp;
+ int status;
+};
-asmlinkage int irix_sigstack(struct irix_sigstack *new, struct irix_sigstack *old)
+asmlinkage int irix_sigstack(struct irix_sigstack __user *new,
+ struct irix_sigstack __user *old)
{
- int error = -EFAULT;
-
#ifdef DEBUG_SIG
printk("[%s:%d] irix_sigstack(%p,%p)\n",
current->comm, current->pid, new, old);
#endif
- if(new) {
+ if (new) {
if (!access_ok(VERIFY_READ, new, sizeof(*new)))
- goto out;
+ return -EFAULT;
}
- if(old) {
+ if (old) {
if (!access_ok(VERIFY_WRITE, old, sizeof(*old)))
- goto out;
+ return -EFAULT;
}
- error = 0;
-out:
- return error;
+ return 0;
}
struct irix_sigaltstack { unsigned long sp; int size; int status; };
-asmlinkage int irix_sigaltstack(struct irix_sigaltstack *new,
- struct irix_sigaltstack *old)
+asmlinkage int irix_sigaltstack(struct irix_sigaltstack __user *new,
+ struct irix_sigaltstack __user *old)
{
- int error = -EFAULT;
-
#ifdef DEBUG_SIG
printk("[%s:%d] irix_sigaltstack(%p,%p)\n",
current->comm, current->pid, new, old);
#endif
- if (new) {
+ if (new)
if (!access_ok(VERIFY_READ, new, sizeof(*new)))
- goto out;
- }
+ return -EFAULT;
if (old) {
if (!access_ok(VERIFY_WRITE, old, sizeof(*old)))
- goto out;
+ return -EFAULT;
}
- error = 0;
-
-out:
- error = 0;
- return error;
+ return 0;
}
struct irix_procset {
int cmd, ltype, lid, rtype, rid;
};
-asmlinkage int irix_sigsendset(struct irix_procset *pset, int sig)
+asmlinkage int irix_sigsendset(struct irix_procset __user *pset, int sig)
{
if (!access_ok(VERIFY_READ, pset, sizeof(*pset)))
return -EFAULT;
-
#ifdef DEBUG_SIG
printk("[%s:%d] irix_sigsendset([%d,%d,%d,%d,%d],%d)\n",
current->comm, current->pid,
diff --git a/arch/mips/kernel/irq-msc01.c b/arch/mips/kernel/irq-msc01.c
index 43c00ac0b88d..3f653c7cfbf3 100644
--- a/arch/mips/kernel/irq-msc01.c
+++ b/arch/mips/kernel/irq-msc01.c
@@ -74,7 +74,7 @@ static void disable_msc_irq(unsigned int irq)
static void level_mask_and_ack_msc_irq(unsigned int irq)
{
mask_msc_irq(irq);
- if (!cpu_has_ei)
+ if (!cpu_has_veic)
MSCIC_WRITE(MSC01_IC_EOI, 0);
}
@@ -84,7 +84,7 @@ static void level_mask_and_ack_msc_irq(unsigned int irq)
static void edge_mask_and_ack_msc_irq(unsigned int irq)
{
mask_msc_irq(irq);
- if (!cpu_has_ei)
+ if (!cpu_has_veic)
MSCIC_WRITE(MSC01_IC_EOI, 0);
else {
u32 r;
@@ -129,25 +129,23 @@ msc_bind_eic_interrupt (unsigned int irq, unsigned int set)
#define shutdown_msc_irq disable_msc_irq
struct hw_interrupt_type msc_levelirq_type = {
- "SOC-it-Level",
- startup_msc_irq,
- shutdown_msc_irq,
- enable_msc_irq,
- disable_msc_irq,
- level_mask_and_ack_msc_irq,
- end_msc_irq,
- NULL
+ .typename = "SOC-it-Level",
+ .startup = startup_msc_irq,
+ .shutdown = shutdown_msc_irq,
+ .enable = enable_msc_irq,
+ .disable = disable_msc_irq,
+ .ack = level_mask_and_ack_msc_irq,
+ .end = end_msc_irq,
};
struct hw_interrupt_type msc_edgeirq_type = {
- "SOC-it-Edge",
- startup_msc_irq,
- shutdown_msc_irq,
- enable_msc_irq,
- disable_msc_irq,
- edge_mask_and_ack_msc_irq,
- end_msc_irq,
- NULL
+ .typename = "SOC-it-Edge",
+ .startup =startup_msc_irq,
+ .shutdown = shutdown_msc_irq,
+ .enable = enable_msc_irq,
+ .disable = disable_msc_irq,
+ .ack = edge_mask_and_ack_msc_irq,
+ .end = end_msc_irq,
};
@@ -168,14 +166,14 @@ void __init init_msc_irqs(unsigned int base, msc_irqmap_t *imp, int nirq)
switch (imp->im_type) {
case MSC01_IRQ_EDGE:
irq_desc[base+n].handler = &msc_edgeirq_type;
- if (cpu_has_ei)
+ if (cpu_has_veic)
MSCIC_WRITE(MSC01_IC_SUP+n*8, MSC01_IC_SUP_EDGE_BIT);
else
MSCIC_WRITE(MSC01_IC_SUP+n*8, MSC01_IC_SUP_EDGE_BIT | imp->im_lvl);
break;
case MSC01_IRQ_LEVEL:
irq_desc[base+n].handler = &msc_levelirq_type;
- if (cpu_has_ei)
+ if (cpu_has_veic)
MSCIC_WRITE(MSC01_IC_SUP+n*8, 0);
else
MSCIC_WRITE(MSC01_IC_SUP+n*8, imp->im_lvl);
diff --git a/arch/mips/kernel/irq-mv6434x.c b/arch/mips/kernel/irq-mv6434x.c
index 088bbbc869e6..0ac067f45cf5 100644
--- a/arch/mips/kernel/irq-mv6434x.c
+++ b/arch/mips/kernel/irq-mv6434x.c
@@ -135,14 +135,13 @@ void ll_mv64340_irq(struct pt_regs *regs)
#define shutdown_mv64340_irq disable_mv64340_irq
struct hw_interrupt_type mv64340_irq_type = {
- "MV-64340",
- startup_mv64340_irq,
- shutdown_mv64340_irq,
- enable_mv64340_irq,
- disable_mv64340_irq,
- mask_and_ack_mv64340_irq,
- end_mv64340_irq,
- NULL
+ .typename = "MV-64340",
+ .startup = startup_mv64340_irq,
+ .shutdown = shutdown_mv64340_irq,
+ .enable = enable_mv64340_irq,
+ .disable = disable_mv64340_irq,
+ .ack = mask_and_ack_mv64340_irq,
+ .end = end_mv64340_irq,
};
void __init mv64340_irq_init(unsigned int base)
diff --git a/arch/mips/kernel/irq-rm7000.c b/arch/mips/kernel/irq-rm7000.c
index f5d779fd0355..0b130c5ac5d9 100644
--- a/arch/mips/kernel/irq-rm7000.c
+++ b/arch/mips/kernel/irq-rm7000.c
@@ -72,13 +72,13 @@ static void rm7k_cpu_irq_end(unsigned int irq)
}
static hw_irq_controller rm7k_irq_controller = {
- "RM7000",
- rm7k_cpu_irq_startup,
- rm7k_cpu_irq_shutdown,
- rm7k_cpu_irq_enable,
- rm7k_cpu_irq_disable,
- rm7k_cpu_irq_ack,
- rm7k_cpu_irq_end,
+ .typename = "RM7000",
+ .startup = rm7k_cpu_irq_startup,
+ .shutdown = rm7k_cpu_irq_shutdown,
+ .enable = rm7k_cpu_irq_enable,
+ .disable = rm7k_cpu_irq_disable,
+ .ack = rm7k_cpu_irq_ack,
+ .end = rm7k_cpu_irq_end,
};
void __init rm7k_cpu_irq_init(int base)
diff --git a/arch/mips/kernel/irq-rm9000.c b/arch/mips/kernel/irq-rm9000.c
index bdd130296256..9b5f20c32acb 100644
--- a/arch/mips/kernel/irq-rm9000.c
+++ b/arch/mips/kernel/irq-rm9000.c
@@ -106,23 +106,23 @@ static void rm9k_cpu_irq_end(unsigned int irq)
}
static hw_irq_controller rm9k_irq_controller = {
- "RM9000",
- rm9k_cpu_irq_startup,
- rm9k_cpu_irq_shutdown,
- rm9k_cpu_irq_enable,
- rm9k_cpu_irq_disable,
- rm9k_cpu_irq_ack,
- rm9k_cpu_irq_end,
+ .typename = "RM9000",
+ .startup = rm9k_cpu_irq_startup,
+ .shutdown = rm9k_cpu_irq_shutdown,
+ .enable = rm9k_cpu_irq_enable,
+ .disable = rm9k_cpu_irq_disable,
+ .ack = rm9k_cpu_irq_ack,
+ .end = rm9k_cpu_irq_end,
};
static hw_irq_controller rm9k_perfcounter_irq = {
- "RM9000",
- rm9k_perfcounter_irq_startup,
- rm9k_perfcounter_irq_shutdown,
- rm9k_cpu_irq_enable,
- rm9k_cpu_irq_disable,
- rm9k_cpu_irq_ack,
- rm9k_cpu_irq_end,
+ .typename = "RM9000",
+ .startup = rm9k_perfcounter_irq_startup,
+ .shutdown = rm9k_perfcounter_irq_shutdown,
+ .enable = rm9k_cpu_irq_enable,
+ .disable = rm9k_cpu_irq_disable,
+ .ack = rm9k_cpu_irq_ack,
+ .end = rm9k_cpu_irq_end,
};
unsigned int rm9000_perfcount_irq;
diff --git a/arch/mips/kernel/irq_cpu.c b/arch/mips/kernel/irq_cpu.c
index 2b936cf1ef70..5db67e31ec1a 100644
--- a/arch/mips/kernel/irq_cpu.c
+++ b/arch/mips/kernel/irq_cpu.c
@@ -3,6 +3,8 @@
* Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
*
* Copyright (C) 2001 Ralf Baechle
+ * Copyright (C) 2005 MIPS Technologies, Inc. All rights reserved.
+ * Author: Maciej W. Rozycki <macro@mips.com>
*
* This file define the irq handler for MIPS CPU interrupts.
*
@@ -31,19 +33,21 @@
#include <asm/irq_cpu.h>
#include <asm/mipsregs.h>
+#include <asm/mipsmtregs.h>
#include <asm/system.h>
static int mips_cpu_irq_base;
static inline void unmask_mips_irq(unsigned int irq)
{
- clear_c0_cause(0x100 << (irq - mips_cpu_irq_base));
set_c0_status(0x100 << (irq - mips_cpu_irq_base));
+ irq_enable_hazard();
}
static inline void mask_mips_irq(unsigned int irq)
{
clear_c0_status(0x100 << (irq - mips_cpu_irq_base));
+ irq_disable_hazard();
}
static inline void mips_cpu_irq_enable(unsigned int irq)
@@ -52,6 +56,7 @@ static inline void mips_cpu_irq_enable(unsigned int irq)
local_irq_save(flags);
unmask_mips_irq(irq);
+ back_to_back_c0_hazard();
local_irq_restore(flags);
}
@@ -61,6 +66,7 @@ static void mips_cpu_irq_disable(unsigned int irq)
local_irq_save(flags);
mask_mips_irq(irq);
+ back_to_back_c0_hazard();
local_irq_restore(flags);
}
@@ -71,7 +77,7 @@ static unsigned int mips_cpu_irq_startup(unsigned int irq)
return 0;
}
-#define mips_cpu_irq_shutdown mips_cpu_irq_disable
+#define mips_cpu_irq_shutdown mips_cpu_irq_disable
/*
* While we ack the interrupt interrupts are disabled and thus we don't need
@@ -79,9 +85,6 @@ static unsigned int mips_cpu_irq_startup(unsigned int irq)
*/
static void mips_cpu_irq_ack(unsigned int irq)
{
- /* Only necessary for soft interrupts */
- clear_c0_cause(0x100 << (irq - mips_cpu_irq_base));
-
mask_mips_irq(irq);
}
@@ -92,22 +95,82 @@ static void mips_cpu_irq_end(unsigned int irq)
}
static hw_irq_controller mips_cpu_irq_controller = {
- "MIPS",
- mips_cpu_irq_startup,
- mips_cpu_irq_shutdown,
- mips_cpu_irq_enable,
- mips_cpu_irq_disable,
- mips_cpu_irq_ack,
- mips_cpu_irq_end,
- NULL /* no affinity stuff for UP */
+ .typename = "MIPS",
+ .startup = mips_cpu_irq_startup,
+ .shutdown = mips_cpu_irq_shutdown,
+ .enable = mips_cpu_irq_enable,
+ .disable = mips_cpu_irq_disable,
+ .ack = mips_cpu_irq_ack,
+ .end = mips_cpu_irq_end,
};
+/*
+ * Basically the same as above but taking care of all the MT stuff
+ */
+
+#define unmask_mips_mt_irq unmask_mips_irq
+#define mask_mips_mt_irq mask_mips_irq
+#define mips_mt_cpu_irq_enable mips_cpu_irq_enable
+#define mips_mt_cpu_irq_disable mips_cpu_irq_disable
+
+static unsigned int mips_mt_cpu_irq_startup(unsigned int irq)
+{
+ unsigned int vpflags = dvpe();
+
+ clear_c0_cause(0x100 << (irq - mips_cpu_irq_base));
+ evpe(vpflags);
+ mips_mt_cpu_irq_enable(irq);
+
+ return 0;
+}
+
+#define mips_mt_cpu_irq_shutdown mips_mt_cpu_irq_disable
+
+/*
+ * While we ack the interrupt interrupts are disabled and thus we don't need
+ * to deal with concurrency issues. Same for mips_cpu_irq_end.
+ */
+static void mips_mt_cpu_irq_ack(unsigned int irq)
+{
+ unsigned int vpflags = dvpe();
+ clear_c0_cause(0x100 << (irq - mips_cpu_irq_base));
+ evpe(vpflags);
+ mask_mips_mt_irq(irq);
+}
+
+#define mips_mt_cpu_irq_end mips_cpu_irq_end
+
+static hw_irq_controller mips_mt_cpu_irq_controller = {
+ .typename = "MIPS",
+ .startup = mips_mt_cpu_irq_startup,
+ .shutdown = mips_mt_cpu_irq_shutdown,
+ .enable = mips_mt_cpu_irq_enable,
+ .disable = mips_mt_cpu_irq_disable,
+ .ack = mips_mt_cpu_irq_ack,
+ .end = mips_mt_cpu_irq_end,
+};
void __init mips_cpu_irq_init(int irq_base)
{
int i;
- for (i = irq_base; i < irq_base + 8; i++) {
+ /* Mask interrupts. */
+ clear_c0_status(ST0_IM);
+ clear_c0_cause(CAUSEF_IP);
+
+ /*
+ * Only MT is using the software interrupts currently, so we just
+ * leave them uninitialized for other processors.
+ */
+ if (cpu_has_mipsmt)
+ for (i = irq_base; i < irq_base + 2; i++) {
+ irq_desc[i].status = IRQ_DISABLED;
+ irq_desc[i].action = NULL;
+ irq_desc[i].depth = 1;
+ irq_desc[i].handler = &mips_mt_cpu_irq_controller;
+ }
+
+ for (i = irq_base + 2; i < irq_base + 8; i++) {
irq_desc[i].status = IRQ_DISABLED;
irq_desc[i].action = NULL;
irq_desc[i].depth = 1;
diff --git a/arch/mips/kernel/linux32.c b/arch/mips/kernel/linux32.c
index ece4564919d8..330cf84d21fe 100644
--- a/arch/mips/kernel/linux32.c
+++ b/arch/mips/kernel/linux32.c
@@ -215,81 +215,32 @@ sys32_readdir(unsigned int fd, void * dirent32, unsigned int count)
return(n);
}
-struct rusage32 {
- struct compat_timeval ru_utime;
- struct compat_timeval ru_stime;
- int ru_maxrss;
- int ru_ixrss;
- int ru_idrss;
- int ru_isrss;
- int ru_minflt;
- int ru_majflt;
- int ru_nswap;
- int ru_inblock;
- int ru_oublock;
- int ru_msgsnd;
- int ru_msgrcv;
- int ru_nsignals;
- int ru_nvcsw;
- int ru_nivcsw;
-};
-
-static int
-put_rusage (struct rusage32 *ru, struct rusage *r)
+asmlinkage int
+sys32_waitpid(compat_pid_t pid, unsigned int *stat_addr, int options)
{
- int err;
-
- if (!access_ok(VERIFY_WRITE, ru, sizeof *ru))
- return -EFAULT;
-
- err = __put_user (r->ru_utime.tv_sec, &ru->ru_utime.tv_sec);
- err |= __put_user (r->ru_utime.tv_usec, &ru->ru_utime.tv_usec);
- err |= __put_user (r->ru_stime.tv_sec, &ru->ru_stime.tv_sec);
- err |= __put_user (r->ru_stime.tv_usec, &ru->ru_stime.tv_usec);
- err |= __put_user (r->ru_maxrss, &ru->ru_maxrss);
- err |= __put_user (r->ru_ixrss, &ru->ru_ixrss);
- err |= __put_user (r->ru_idrss, &ru->ru_idrss);
- err |= __put_user (r->ru_isrss, &ru->ru_isrss);
- err |= __put_user (r->ru_minflt, &ru->ru_minflt);
- err |= __put_user (r->ru_majflt, &ru->ru_majflt);
- err |= __put_user (r->ru_nswap, &ru->ru_nswap);
- err |= __put_user (r->ru_inblock, &ru->ru_inblock);
- err |= __put_user (r->ru_oublock, &ru->ru_oublock);
- err |= __put_user (r->ru_msgsnd, &ru->ru_msgsnd);
- err |= __put_user (r->ru_msgrcv, &ru->ru_msgrcv);
- err |= __put_user (r->ru_nsignals, &ru->ru_nsignals);
- err |= __put_user (r->ru_nvcsw, &ru->ru_nvcsw);
- err |= __put_user (r->ru_nivcsw, &ru->ru_nivcsw);
-
- return err;
+ return compat_sys_wait4(pid, stat_addr, options, NULL);
}
-asmlinkage int
-sys32_wait4(compat_pid_t pid, unsigned int * stat_addr, int options,
- struct rusage32 * ru)
+asmlinkage long
+sysn32_waitid(int which, compat_pid_t pid,
+ siginfo_t __user *uinfo, int options,
+ struct compat_rusage __user *uru)
{
- if (!ru)
- return sys_wait4(pid, stat_addr, options, NULL);
- else {
- struct rusage r;
- int ret;
- unsigned int status;
- mm_segment_t old_fs = get_fs();
+ struct rusage ru;
+ long ret;
+ mm_segment_t old_fs = get_fs();
- set_fs(KERNEL_DS);
- ret = sys_wait4(pid, stat_addr ? &status : NULL, options, &r);
- set_fs(old_fs);
- if (put_rusage (ru, &r)) return -EFAULT;
- if (stat_addr && put_user (status, stat_addr))
- return -EFAULT;
+ set_fs (KERNEL_DS);
+ ret = sys_waitid(which, pid, uinfo, options,
+ uru ? (struct rusage __user *) &ru : NULL);
+ set_fs (old_fs);
+
+ if (ret < 0 || uinfo->si_signo == 0)
return ret;
- }
-}
-asmlinkage int
-sys32_waitpid(compat_pid_t pid, unsigned int *stat_addr, int options)
-{
- return sys32_wait4(pid, stat_addr, options, NULL);
+ if (uru)
+ ret = put_compat_rusage(&ru, uru);
+ return ret;
}
struct sysinfo32 {
@@ -1467,3 +1418,80 @@ asmlinkage long sys32_socketcall(int call, unsigned int *args32)
}
return err;
}
+
+struct sigevent32 {
+ u32 sigev_value;
+ u32 sigev_signo;
+ u32 sigev_notify;
+ u32 payload[(64 / 4) - 3];
+};
+
+extern asmlinkage long
+sys_timer_create(clockid_t which_clock,
+ struct sigevent __user *timer_event_spec,
+ timer_t __user * created_timer_id);
+
+long
+sys32_timer_create(u32 clock, struct sigevent32 __user *se32, timer_t __user *timer_id)
+{
+ struct sigevent __user *p = NULL;
+ if (se32) {
+ struct sigevent se;
+ p = compat_alloc_user_space(sizeof(struct sigevent));
+ memset(&se, 0, sizeof(struct sigevent));
+ if (get_user(se.sigev_value.sival_int, &se32->sigev_value) ||
+ __get_user(se.sigev_signo, &se32->sigev_signo) ||
+ __get_user(se.sigev_notify, &se32->sigev_notify) ||
+ __copy_from_user(&se._sigev_un._pad, &se32->payload,
+ sizeof(se32->payload)) ||
+ copy_to_user(p, &se, sizeof(se)))
+ return -EFAULT;
+ }
+ return sys_timer_create(clock, p, timer_id);
+}
+
+asmlinkage long
+sysn32_rt_sigtimedwait(const sigset_t __user *uthese,
+ siginfo_t __user *uinfo,
+ const struct compat_timespec __user *uts32,
+ size_t sigsetsize)
+{
+ struct timespec __user *uts = NULL;
+
+ if (uts32) {
+ struct timespec ts;
+ uts = compat_alloc_user_space(sizeof(struct timespec));
+ if (get_user(ts.tv_sec, &uts32->tv_sec) ||
+ get_user(ts.tv_nsec, &uts32->tv_nsec) ||
+ copy_to_user (uts, &ts, sizeof (ts)))
+ return -EFAULT;
+ }
+ return sys_rt_sigtimedwait(uthese, uinfo, uts, sigsetsize);
+}
+
+save_static_function(sys32_clone);
+__attribute_used__ noinline static int
+_sys32_clone(nabi_no_regargs struct pt_regs regs)
+{
+ unsigned long clone_flags;
+ unsigned long newsp;
+ int __user *parent_tidptr, *child_tidptr;
+
+ clone_flags = regs.regs[4];
+ newsp = regs.regs[5];
+ if (!newsp)
+ newsp = regs.regs[29];
+ parent_tidptr = (int *) regs.regs[6];
+
+ /* Use __dummy4 instead of getting it off the stack, so that
+ syscall() works. */
+ child_tidptr = (int __user *) __dummy4;
+ return do_fork(clone_flags, newsp, &regs, 0,
+ parent_tidptr, child_tidptr);
+}
+
+extern asmlinkage void sys_set_thread_area(u32 addr);
+asmlinkage void sys32_set_thread_area(u32 addr)
+{
+ sys_set_thread_area(AA(addr));
+}
diff --git a/arch/mips/kernel/module-elf32.c b/arch/mips/kernel/module-elf32.c
deleted file mode 100644
index ffd216d6d6dc..000000000000
--- a/arch/mips/kernel/module-elf32.c
+++ /dev/null
@@ -1,250 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Copyright (C) 2001 Rusty Russell.
- * Copyright (C) 2003, 2004 Ralf Baechle (ralf@linux-mips.org)
- */
-
-#undef DEBUG
-
-#include <linux/moduleloader.h>
-#include <linux/elf.h>
-#include <linux/vmalloc.h>
-#include <linux/slab.h>
-#include <linux/fs.h>
-#include <linux/string.h>
-#include <linux/kernel.h>
-
-struct mips_hi16 {
- struct mips_hi16 *next;
- Elf32_Addr *addr;
- Elf32_Addr value;
-};
-
-static struct mips_hi16 *mips_hi16_list;
-
-void *module_alloc(unsigned long size)
-{
- if (size == 0)
- return NULL;
- return vmalloc(size);
-}
-
-
-/* Free memory returned from module_alloc */
-void module_free(struct module *mod, void *module_region)
-{
- vfree(module_region);
- /* FIXME: If module_region == mod->init_region, trim exception
- table entries. */
-}
-
-int module_frob_arch_sections(Elf_Ehdr *hdr,
- Elf_Shdr *sechdrs,
- char *secstrings,
- struct module *mod)
-{
- return 0;
-}
-
-static int apply_r_mips_none(struct module *me, uint32_t *location,
- Elf32_Addr v)
-{
- return 0;
-}
-
-static int apply_r_mips_32(struct module *me, uint32_t *location,
- Elf32_Addr v)
-{
- *location += v;
-
- return 0;
-}
-
-static int apply_r_mips_26(struct module *me, uint32_t *location,
- Elf32_Addr v)
-{
- if (v % 4) {
- printk(KERN_ERR "module %s: dangerous relocation\n", me->name);
- return -ENOEXEC;
- }
-
- if ((v & 0xf0000000) != (((unsigned long)location + 4) & 0xf0000000)) {
- printk(KERN_ERR
- "module %s: relocation overflow\n",
- me->name);
- return -ENOEXEC;
- }
-
- *location = (*location & ~0x03ffffff) |
- ((*location + (v >> 2)) & 0x03ffffff);
-
- return 0;
-}
-
-static int apply_r_mips_hi16(struct module *me, uint32_t *location,
- Elf32_Addr v)
-{
- struct mips_hi16 *n;
-
- /*
- * We cannot relocate this one now because we don't know the value of
- * the carry we need to add. Save the information, and let LO16 do the
- * actual relocation.
- */
- n = kmalloc(sizeof *n, GFP_KERNEL);
- if (!n)
- return -ENOMEM;
-
- n->addr = location;
- n->value = v;
- n->next = mips_hi16_list;
- mips_hi16_list = n;
-
- return 0;
-}
-
-static int apply_r_mips_lo16(struct module *me, uint32_t *location,
- Elf32_Addr v)
-{
- unsigned long insnlo = *location;
- Elf32_Addr val, vallo;
-
- /* Sign extend the addend we extract from the lo insn. */
- vallo = ((insnlo & 0xffff) ^ 0x8000) - 0x8000;
-
- if (mips_hi16_list != NULL) {
- struct mips_hi16 *l;
-
- l = mips_hi16_list;
- while (l != NULL) {
- struct mips_hi16 *next;
- unsigned long insn;
-
- /*
- * The value for the HI16 had best be the same.
- */
- if (v != l->value)
- goto out_danger;
-
- /*
- * Do the HI16 relocation. Note that we actually don't
- * need to know anything about the LO16 itself, except
- * where to find the low 16 bits of the addend needed
- * by the LO16.
- */
- insn = *l->addr;
- val = ((insn & 0xffff) << 16) + vallo;
- val += v;
-
- /*
- * Account for the sign extension that will happen in
- * the low bits.
- */
- val = ((val >> 16) + ((val & 0x8000) != 0)) & 0xffff;
-
- insn = (insn & ~0xffff) | val;
- *l->addr = insn;
-
- next = l->next;
- kfree(l);
- l = next;
- }
-
- mips_hi16_list = NULL;
- }
-
- /*
- * Ok, we're done with the HI16 relocs. Now deal with the LO16.
- */
- val = v + vallo;
- insnlo = (insnlo & ~0xffff) | (val & 0xffff);
- *location = insnlo;
-
- return 0;
-
-out_danger:
- printk(KERN_ERR "module %s: dangerous " "relocation\n", me->name);
-
- return -ENOEXEC;
-}
-
-static int (*reloc_handlers[]) (struct module *me, uint32_t *location,
- Elf32_Addr v) = {
- [R_MIPS_NONE] = apply_r_mips_none,
- [R_MIPS_32] = apply_r_mips_32,
- [R_MIPS_26] = apply_r_mips_26,
- [R_MIPS_HI16] = apply_r_mips_hi16,
- [R_MIPS_LO16] = apply_r_mips_lo16
-};
-
-int apply_relocate(Elf32_Shdr *sechdrs,
- const char *strtab,
- unsigned int symindex,
- unsigned int relsec,
- struct module *me)
-{
- Elf32_Rel *rel = (void *) sechdrs[relsec].sh_addr;
- Elf32_Sym *sym;
- uint32_t *location;
- unsigned int i;
- Elf32_Addr v;
- int res;
-
- pr_debug("Applying relocate section %u to %u\n", relsec,
- sechdrs[relsec].sh_info);
-
- for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
- Elf32_Word r_info = rel[i].r_info;
-
- /* This is where to make the change */
- location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
- + rel[i].r_offset;
- /* This is the symbol it is referring to */
- sym = (Elf32_Sym *)sechdrs[symindex].sh_addr
- + ELF32_R_SYM(r_info);
- if (!sym->st_value) {
- printk(KERN_WARNING "%s: Unknown symbol %s\n",
- me->name, strtab + sym->st_name);
- return -ENOENT;
- }
-
- v = sym->st_value;
-
- res = reloc_handlers[ELF32_R_TYPE(r_info)](me, location, v);
- if (res)
- return res;
- }
-
- return 0;
-}
-
-int apply_relocate_add(Elf32_Shdr *sechdrs,
- const char *strtab,
- unsigned int symindex,
- unsigned int relsec,
- struct module *me)
-{
- /*
- * Current binutils always generate .rela relocations. Keep smiling
- * if it's empty, abort otherwise.
- */
- if (!sechdrs[relsec].sh_size)
- return 0;
-
- printk(KERN_ERR "module %s: ADD RELOCATION unsupported\n",
- me->name);
- return -ENOEXEC;
-}
diff --git a/arch/mips/kernel/module-elf64.c b/arch/mips/kernel/module-elf64.c
deleted file mode 100644
index e804792ee1ee..000000000000
--- a/arch/mips/kernel/module-elf64.c
+++ /dev/null
@@ -1,274 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Copyright (C) 2001 Rusty Russell.
- * Copyright (C) 2003, 2004 Ralf Baechle (ralf@linux-mips.org)
- */
-
-#undef DEBUG
-
-#include <linux/moduleloader.h>
-#include <linux/elf.h>
-#include <linux/vmalloc.h>
-#include <linux/slab.h>
-#include <linux/fs.h>
-#include <linux/string.h>
-#include <linux/kernel.h>
-
-struct mips_hi16 {
- struct mips_hi16 *next;
- Elf32_Addr *addr;
- Elf64_Addr value;
-};
-
-static struct mips_hi16 *mips_hi16_list;
-
-void *module_alloc(unsigned long size)
-{
- if (size == 0)
- return NULL;
- return vmalloc(size);
-}
-
-
-/* Free memory returned from module_alloc */
-void module_free(struct module *mod, void *module_region)
-{
- vfree(module_region);
- /* FIXME: If module_region == mod->init_region, trim exception
- table entries. */
-}
-
-int module_frob_arch_sections(Elf_Ehdr *hdr,
- Elf_Shdr *sechdrs,
- char *secstrings,
- struct module *mod)
-{
- return 0;
-}
-
-int apply_relocate(Elf64_Shdr *sechdrs,
- const char *strtab,
- unsigned int symindex,
- unsigned int relsec,
- struct module *me)
-{
- /*
- * We don't want to deal with REL relocations - RELA is so much saner.
- */
- if (!sechdrs[relsec].sh_size)
- return 0;
-
- printk(KERN_ERR "module %s: REL relocation unsupported\n",
- me->name);
- return -ENOEXEC;
-}
-
-static int apply_r_mips_none(struct module *me, uint32_t *location,
- Elf64_Addr v)
-{
- return 0;
-}
-
-static int apply_r_mips_32(struct module *me, uint32_t *location,
- Elf64_Addr v)
-{
- *location = v;
-
- return 0;
-}
-
-static int apply_r_mips_26(struct module *me, uint32_t *location,
- Elf64_Addr v)
-{
- if (v % 4) {
- printk(KERN_ERR "module %s: dangerous relocation\n", me->name);
- return -ENOEXEC;
- }
-
- if ((v & 0xf0000000) != (((unsigned long)location + 4) & 0xf0000000)) {
- printk(KERN_ERR
- "module %s: relocation overflow\n",
- me->name);
- return -ENOEXEC;
- }
-
- *location = (*location & ~0x03ffffff) | ((v >> 2) & 0x03ffffff);
-
- return 0;
-}
-
-static int apply_r_mips_hi16(struct module *me, uint32_t *location,
- Elf64_Addr v)
-{
- struct mips_hi16 *n;
-
- /*
- * We cannot relocate this one now because we don't know the value of
- * the carry we need to add. Save the information, and let LO16 do the
- * actual relocation.
- */
- n = kmalloc(sizeof *n, GFP_KERNEL);
- if (!n)
- return -ENOMEM;
-
- n->addr = location;
- n->value = v;
- n->next = mips_hi16_list;
- mips_hi16_list = n;
-
- return 0;
-}
-
-static int apply_r_mips_lo16(struct module *me, uint32_t *location,
- Elf64_Addr v)
-{
- unsigned long insnlo = *location;
- Elf32_Addr val, vallo;
-
- /* Sign extend the addend we extract from the lo insn. */
- vallo = ((insnlo & 0xffff) ^ 0x8000) - 0x8000;
-
- if (mips_hi16_list != NULL) {
- struct mips_hi16 *l;
-
- l = mips_hi16_list;
- while (l != NULL) {
- struct mips_hi16 *next;
- unsigned long insn;
-
- /*
- * The value for the HI16 had best be the same.
- */
- if (v != l->value)
- goto out_danger;
-
- /*
- * Do the HI16 relocation. Note that we actually don't
- * need to know anything about the LO16 itself, except
- * where to find the low 16 bits of the addend needed
- * by the LO16.
- */
- insn = *l->addr;
- val = ((insn & 0xffff) << 16) + vallo;
- val += v;
-
- /*
- * Account for the sign extension that will happen in
- * the low bits.
- */
- val = ((val >> 16) + ((val & 0x8000) != 0)) & 0xffff;
-
- insn = (insn & ~0xffff) | val;
- *l->addr = insn;
-
- next = l->next;
- kfree(l);
- l = next;
- }
-
- mips_hi16_list = NULL;
- }
-
- /*
- * Ok, we're done with the HI16 relocs. Now deal with the LO16.
- */
- insnlo = (insnlo & ~0xffff) | (v & 0xffff);
- *location = insnlo;
-
- return 0;
-
-out_danger:
- printk(KERN_ERR "module %s: dangerous " "relocation\n", me->name);
-
- return -ENOEXEC;
-}
-
-static int apply_r_mips_64(struct module *me, uint32_t *location,
- Elf64_Addr v)
-{
- *(uint64_t *) location = v;
-
- return 0;
-}
-
-
-static int apply_r_mips_higher(struct module *me, uint32_t *location,
- Elf64_Addr v)
-{
- *location = (*location & 0xffff0000) |
- ((((long long) v + 0x80008000LL) >> 32) & 0xffff);
-
- return 0;
-}
-
-static int apply_r_mips_highest(struct module *me, uint32_t *location,
- Elf64_Addr v)
-{
- *location = (*location & 0xffff0000) |
- ((((long long) v + 0x800080008000LL) >> 48) & 0xffff);
-
- return 0;
-}
-
-static int (*reloc_handlers[]) (struct module *me, uint32_t *location,
- Elf64_Addr v) = {
- [R_MIPS_NONE] = apply_r_mips_none,
- [R_MIPS_32] = apply_r_mips_32,
- [R_MIPS_26] = apply_r_mips_26,
- [R_MIPS_HI16] = apply_r_mips_hi16,
- [R_MIPS_LO16] = apply_r_mips_lo16,
- [R_MIPS_64] = apply_r_mips_64,
- [R_MIPS_HIGHER] = apply_r_mips_higher,
- [R_MIPS_HIGHEST] = apply_r_mips_highest
-};
-
-int apply_relocate_add(Elf64_Shdr *sechdrs,
- const char *strtab,
- unsigned int symindex,
- unsigned int relsec,
- struct module *me)
-{
- Elf64_Mips_Rela *rel = (void *) sechdrs[relsec].sh_addr;
- Elf64_Sym *sym;
- uint32_t *location;
- unsigned int i;
- Elf64_Addr v;
- int res;
-
- pr_debug("Applying relocate section %u to %u\n", relsec,
- sechdrs[relsec].sh_info);
-
- for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
- /* This is where to make the change */
- location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
- + rel[i].r_offset;
- /* This is the symbol it is referring to */
- sym = (Elf64_Sym *)sechdrs[symindex].sh_addr + rel[i].r_sym;
- if (!sym->st_value) {
- printk(KERN_WARNING "%s: Unknown symbol %s\n",
- me->name, strtab + sym->st_name);
- return -ENOENT;
- }
-
- v = sym->st_value;
-
- res = reloc_handlers[rel[i].r_type](me, location, v);
- if (res)
- return res;
- }
-
- return 0;
-}
diff --git a/arch/mips/kernel/module.c b/arch/mips/kernel/module.c
index 458af3c7a639..e54a7f442f8a 100644
--- a/arch/mips/kernel/module.c
+++ b/arch/mips/kernel/module.c
@@ -1,9 +1,345 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Copyright (C) 2001 Rusty Russell.
+ * Copyright (C) 2003, 2004 Ralf Baechle (ralf@linux-mips.org)
+ * Copyright (C) 2005 Thiemo Seufer
+ */
+
+#undef DEBUG
+
+#include <linux/moduleloader.h>
+#include <linux/elf.h>
+#include <linux/vmalloc.h>
+#include <linux/slab.h>
+#include <linux/fs.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/spinlock.h>
+struct mips_hi16 {
+ struct mips_hi16 *next;
+ Elf_Addr *addr;
+ Elf_Addr value;
+};
+
+static struct mips_hi16 *mips_hi16_list;
+
static LIST_HEAD(dbe_list);
static DEFINE_SPINLOCK(dbe_lock);
+void *module_alloc(unsigned long size)
+{
+ if (size == 0)
+ return NULL;
+ return vmalloc(size);
+}
+
+/* Free memory returned from module_alloc */
+void module_free(struct module *mod, void *module_region)
+{
+ vfree(module_region);
+ /* FIXME: If module_region == mod->init_region, trim exception
+ table entries. */
+}
+
+int module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs,
+ char *secstrings, struct module *mod)
+{
+ return 0;
+}
+
+static int apply_r_mips_none(struct module *me, u32 *location, Elf_Addr v)
+{
+ return 0;
+}
+
+static int apply_r_mips_32_rel(struct module *me, u32 *location, Elf_Addr v)
+{
+ *location += v;
+
+ return 0;
+}
+
+static int apply_r_mips_32_rela(struct module *me, u32 *location, Elf_Addr v)
+{
+ *location = v;
+
+ return 0;
+}
+
+static int apply_r_mips_26_rel(struct module *me, u32 *location, Elf_Addr v)
+{
+ if (v % 4) {
+ printk(KERN_ERR "module %s: dangerous relocation\n", me->name);
+ return -ENOEXEC;
+ }
+
+ if ((v & 0xf0000000) != (((unsigned long)location + 4) & 0xf0000000)) {
+ printk(KERN_ERR
+ "module %s: relocation overflow\n",
+ me->name);
+ return -ENOEXEC;
+ }
+
+ *location = (*location & ~0x03ffffff) |
+ ((*location + (v >> 2)) & 0x03ffffff);
+
+ return 0;
+}
+
+static int apply_r_mips_26_rela(struct module *me, u32 *location, Elf_Addr v)
+{
+ if (v % 4) {
+ printk(KERN_ERR "module %s: dangerous relocation\n", me->name);
+ return -ENOEXEC;
+ }
+
+ if ((v & 0xf0000000) != (((unsigned long)location + 4) & 0xf0000000)) {
+ printk(KERN_ERR
+ "module %s: relocation overflow\n",
+ me->name);
+ return -ENOEXEC;
+ }
+
+ *location = (*location & ~0x03ffffff) | ((v >> 2) & 0x03ffffff);
+
+ return 0;
+}
+
+static int apply_r_mips_hi16_rel(struct module *me, u32 *location, Elf_Addr v)
+{
+ struct mips_hi16 *n;
+
+ /*
+ * We cannot relocate this one now because we don't know the value of
+ * the carry we need to add. Save the information, and let LO16 do the
+ * actual relocation.
+ */
+ n = kmalloc(sizeof *n, GFP_KERNEL);
+ if (!n)
+ return -ENOMEM;
+
+ n->addr = (Elf_Addr *)location;
+ n->value = v;
+ n->next = mips_hi16_list;
+ mips_hi16_list = n;
+
+ return 0;
+}
+
+static int apply_r_mips_hi16_rela(struct module *me, u32 *location, Elf_Addr v)
+{
+ *location = (*location & 0xffff0000) |
+ ((((long long) v + 0x8000LL) >> 16) & 0xffff);
+
+ return 0;
+}
+
+static int apply_r_mips_lo16_rel(struct module *me, u32 *location, Elf_Addr v)
+{
+ unsigned long insnlo = *location;
+ Elf_Addr val, vallo;
+
+ /* Sign extend the addend we extract from the lo insn. */
+ vallo = ((insnlo & 0xffff) ^ 0x8000) - 0x8000;
+
+ if (mips_hi16_list != NULL) {
+ struct mips_hi16 *l;
+
+ l = mips_hi16_list;
+ while (l != NULL) {
+ struct mips_hi16 *next;
+ unsigned long insn;
+
+ /*
+ * The value for the HI16 had best be the same.
+ */
+ if (v != l->value)
+ goto out_danger;
+
+ /*
+ * Do the HI16 relocation. Note that we actually don't
+ * need to know anything about the LO16 itself, except
+ * where to find the low 16 bits of the addend needed
+ * by the LO16.
+ */
+ insn = *l->addr;
+ val = ((insn & 0xffff) << 16) + vallo;
+ val += v;
+
+ /*
+ * Account for the sign extension that will happen in
+ * the low bits.
+ */
+ val = ((val >> 16) + ((val & 0x8000) != 0)) & 0xffff;
+
+ insn = (insn & ~0xffff) | val;
+ *l->addr = insn;
+
+ next = l->next;
+ kfree(l);
+ l = next;
+ }
+
+ mips_hi16_list = NULL;
+ }
+
+ /*
+ * Ok, we're done with the HI16 relocs. Now deal with the LO16.
+ */
+ val = v + vallo;
+ insnlo = (insnlo & ~0xffff) | (val & 0xffff);
+ *location = insnlo;
+
+ return 0;
+
+out_danger:
+ printk(KERN_ERR "module %s: dangerous " "relocation\n", me->name);
+
+ return -ENOEXEC;
+}
+
+static int apply_r_mips_lo16_rela(struct module *me, u32 *location, Elf_Addr v)
+{
+ *location = (*location & 0xffff0000) | (v & 0xffff);
+
+ return 0;
+}
+
+static int apply_r_mips_64_rela(struct module *me, u32 *location, Elf_Addr v)
+{
+ *(Elf_Addr *)location = v;
+
+ return 0;
+}
+
+static int apply_r_mips_higher_rela(struct module *me, u32 *location,
+ Elf_Addr v)
+{
+ *location = (*location & 0xffff0000) |
+ ((((long long) v + 0x80008000LL) >> 32) & 0xffff);
+
+ return 0;
+}
+
+static int apply_r_mips_highest_rela(struct module *me, u32 *location,
+ Elf_Addr v)
+{
+ *location = (*location & 0xffff0000) |
+ ((((long long) v + 0x800080008000LL) >> 48) & 0xffff);
+
+ return 0;
+}
+
+static int (*reloc_handlers_rel[]) (struct module *me, u32 *location,
+ Elf_Addr v) = {
+ [R_MIPS_NONE] = apply_r_mips_none,
+ [R_MIPS_32] = apply_r_mips_32_rel,
+ [R_MIPS_26] = apply_r_mips_26_rel,
+ [R_MIPS_HI16] = apply_r_mips_hi16_rel,
+ [R_MIPS_LO16] = apply_r_mips_lo16_rel
+};
+
+static int (*reloc_handlers_rela[]) (struct module *me, u32 *location,
+ Elf_Addr v) = {
+ [R_MIPS_NONE] = apply_r_mips_none,
+ [R_MIPS_32] = apply_r_mips_32_rela,
+ [R_MIPS_26] = apply_r_mips_26_rela,
+ [R_MIPS_HI16] = apply_r_mips_hi16_rela,
+ [R_MIPS_LO16] = apply_r_mips_lo16_rela,
+ [R_MIPS_64] = apply_r_mips_64_rela,
+ [R_MIPS_HIGHER] = apply_r_mips_higher_rela,
+ [R_MIPS_HIGHEST] = apply_r_mips_highest_rela
+};
+
+int apply_relocate(Elf_Shdr *sechdrs, const char *strtab,
+ unsigned int symindex, unsigned int relsec,
+ struct module *me)
+{
+ Elf_Mips_Rel *rel = (void *) sechdrs[relsec].sh_addr;
+ Elf_Sym *sym;
+ u32 *location;
+ unsigned int i;
+ Elf_Addr v;
+ int res;
+
+ pr_debug("Applying relocate section %u to %u\n", relsec,
+ sechdrs[relsec].sh_info);
+
+ for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
+ /* This is where to make the change */
+ location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
+ + rel[i].r_offset;
+ /* This is the symbol it is referring to */
+ sym = (Elf_Sym *)sechdrs[symindex].sh_addr
+ + ELF_MIPS_R_SYM(rel[i]);
+ if (!sym->st_value) {
+ printk(KERN_WARNING "%s: Unknown symbol %s\n",
+ me->name, strtab + sym->st_name);
+ return -ENOENT;
+ }
+
+ v = sym->st_value;
+
+ res = reloc_handlers_rel[ELF_MIPS_R_TYPE(rel[i])](me, location, v);
+ if (res)
+ return res;
+ }
+
+ return 0;
+}
+
+int apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab,
+ unsigned int symindex, unsigned int relsec,
+ struct module *me)
+{
+ Elf_Mips_Rela *rel = (void *) sechdrs[relsec].sh_addr;
+ Elf_Sym *sym;
+ u32 *location;
+ unsigned int i;
+ Elf_Addr v;
+ int res;
+
+ pr_debug("Applying relocate section %u to %u\n", relsec,
+ sechdrs[relsec].sh_info);
+
+ for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
+ /* This is where to make the change */
+ location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
+ + rel[i].r_offset;
+ /* This is the symbol it is referring to */
+ sym = (Elf_Sym *)sechdrs[symindex].sh_addr
+ + ELF_MIPS_R_SYM(rel[i]);
+ if (!sym->st_value) {
+ printk(KERN_WARNING "%s: Unknown symbol %s\n",
+ me->name, strtab + sym->st_name);
+ return -ENOENT;
+ }
+
+ v = sym->st_value + rel[i].r_addend;
+
+ res = reloc_handlers_rela[ELF_MIPS_R_TYPE(rel[i])](me, location, v);
+ if (res)
+ return res;
+ }
+
+ return 0;
+}
+
/* Given an address, look for it in the module exception tables. */
const struct exception_table_entry *search_module_dbetables(unsigned long addr)
{
diff --git a/arch/mips/kernel/proc.c b/arch/mips/kernel/proc.c
index 0f159f30e894..86fe15b273cd 100644
--- a/arch/mips/kernel/proc.c
+++ b/arch/mips/kernel/proc.c
@@ -2,7 +2,8 @@
* linux/arch/mips/kernel/proc.c
*
* Copyright (C) 1995, 1996, 2001 Ralf Baechle
- * Copyright (C) 2001 MIPS Technologies, Inc.
+ * Copyright (C) 2001, 2004 MIPS Technologies, Inc.
+ * Copyright (C) 2004 Maciej W. Rozycki
*/
#include <linux/config.h>
#include <linux/delay.h>
@@ -19,63 +20,69 @@
unsigned int vced_count, vcei_count;
static const char *cpu_name[] = {
- [CPU_UNKNOWN] "unknown",
- [CPU_R2000] "R2000",
- [CPU_R3000] "R3000",
- [CPU_R3000A] "R3000A",
- [CPU_R3041] "R3041",
- [CPU_R3051] "R3051",
- [CPU_R3052] "R3052",
- [CPU_R3081] "R3081",
- [CPU_R3081E] "R3081E",
- [CPU_R4000PC] "R4000PC",
- [CPU_R4000SC] "R4000SC",
- [CPU_R4000MC] "R4000MC",
- [CPU_R4200] "R4200",
- [CPU_R4400PC] "R4400PC",
- [CPU_R4400SC] "R4400SC",
- [CPU_R4400MC] "R4400MC",
- [CPU_R4600] "R4600",
- [CPU_R6000] "R6000",
- [CPU_R6000A] "R6000A",
- [CPU_R8000] "R8000",
- [CPU_R10000] "R10000",
- [CPU_R12000] "R12000",
- [CPU_R4300] "R4300",
- [CPU_R4650] "R4650",
- [CPU_R4700] "R4700",
- [CPU_R5000] "R5000",
- [CPU_R5000A] "R5000A",
- [CPU_R4640] "R4640",
- [CPU_NEVADA] "Nevada",
- [CPU_RM7000] "RM7000",
- [CPU_RM9000] "RM9000",
- [CPU_R5432] "R5432",
- [CPU_4KC] "MIPS 4Kc",
- [CPU_5KC] "MIPS 5Kc",
- [CPU_R4310] "R4310",
- [CPU_SB1] "SiByte SB1",
- [CPU_TX3912] "TX3912",
- [CPU_TX3922] "TX3922",
- [CPU_TX3927] "TX3927",
- [CPU_AU1000] "Au1000",
- [CPU_AU1500] "Au1500",
- [CPU_4KEC] "MIPS 4KEc",
- [CPU_4KSC] "MIPS 4KSc",
- [CPU_VR41XX] "NEC Vr41xx",
- [CPU_R5500] "R5500",
- [CPU_TX49XX] "TX49xx",
- [CPU_20KC] "MIPS 20Kc",
- [CPU_24K] "MIPS 24K",
- [CPU_25KF] "MIPS 25Kf",
- [CPU_VR4111] "NEC VR4111",
- [CPU_VR4121] "NEC VR4121",
- [CPU_VR4122] "NEC VR4122",
- [CPU_VR4131] "NEC VR4131",
- [CPU_VR4133] "NEC VR4133",
- [CPU_VR4181] "NEC VR4181",
- [CPU_VR4181A] "NEC VR4181A",
- [CPU_SR71000] "Sandcraft SR71000"
+ [CPU_UNKNOWN] = "unknown",
+ [CPU_R2000] = "R2000",
+ [CPU_R3000] = "R3000",
+ [CPU_R3000A] = "R3000A",
+ [CPU_R3041] = "R3041",
+ [CPU_R3051] = "R3051",
+ [CPU_R3052] = "R3052",
+ [CPU_R3081] = "R3081",
+ [CPU_R3081E] = "R3081E",
+ [CPU_R4000PC] = "R4000PC",
+ [CPU_R4000SC] = "R4000SC",
+ [CPU_R4000MC] = "R4000MC",
+ [CPU_R4200] = "R4200",
+ [CPU_R4400PC] = "R4400PC",
+ [CPU_R4400SC] = "R4400SC",
+ [CPU_R4400MC] = "R4400MC",
+ [CPU_R4600] = "R4600",
+ [CPU_R6000] = "R6000",
+ [CPU_R6000A] = "R6000A",
+ [CPU_R8000] = "R8000",
+ [CPU_R10000] = "R10000",
+ [CPU_R12000] = "R12000",
+ [CPU_R4300] = "R4300",
+ [CPU_R4650] = "R4650",
+ [CPU_R4700] = "R4700",
+ [CPU_R5000] = "R5000",
+ [CPU_R5000A] = "R5000A",
+ [CPU_R4640] = "R4640",
+ [CPU_NEVADA] = "Nevada",
+ [CPU_RM7000] = "RM7000",
+ [CPU_RM9000] = "RM9000",
+ [CPU_R5432] = "R5432",
+ [CPU_4KC] = "MIPS 4Kc",
+ [CPU_5KC] = "MIPS 5Kc",
+ [CPU_R4310] = "R4310",
+ [CPU_SB1] = "SiByte SB1",
+ [CPU_SB1A] = "SiByte SB1A",
+ [CPU_TX3912] = "TX3912",
+ [CPU_TX3922] = "TX3922",
+ [CPU_TX3927] = "TX3927",
+ [CPU_AU1000] = "Au1000",
+ [CPU_AU1500] = "Au1500",
+ [CPU_AU1100] = "Au1100",
+ [CPU_AU1550] = "Au1550",
+ [CPU_AU1200] = "Au1200",
+ [CPU_4KEC] = "MIPS 4KEc",
+ [CPU_4KSC] = "MIPS 4KSc",
+ [CPU_VR41XX] = "NEC Vr41xx",
+ [CPU_R5500] = "R5500",
+ [CPU_TX49XX] = "TX49xx",
+ [CPU_20KC] = "MIPS 20Kc",
+ [CPU_24K] = "MIPS 24K",
+ [CPU_25KF] = "MIPS 25Kf",
+ [CPU_34K] = "MIPS 34K",
+ [CPU_VR4111] = "NEC VR4111",
+ [CPU_VR4121] = "NEC VR4121",
+ [CPU_VR4122] = "NEC VR4122",
+ [CPU_VR4131] = "NEC VR4131",
+ [CPU_VR4133] = "NEC VR4133",
+ [CPU_VR4181] = "NEC VR4181",
+ [CPU_VR4181A] = "NEC VR4181A",
+ [CPU_SR71000] = "Sandcraft SR71000",
+ [CPU_PR4450] = "Philips PR4450",
};
@@ -105,8 +112,8 @@ static int show_cpuinfo(struct seq_file *m, void *v)
(version >> 4) & 0x0f, version & 0x0f,
(fp_vers >> 4) & 0x0f, fp_vers & 0x0f);
seq_printf(m, "BogoMIPS\t\t: %lu.%02lu\n",
- loops_per_jiffy / (500000/HZ),
- (loops_per_jiffy / (5000/HZ)) % 100);
+ cpu_data[n].udelay_val / (500000/HZ),
+ (cpu_data[n].udelay_val / (5000/HZ)) % 100);
seq_printf(m, "wait instruction\t: %s\n", cpu_wait ? "yes" : "no");
seq_printf(m, "microsecond timers\t: %s\n",
cpu_has_counter ? "yes" : "no");
@@ -115,6 +122,14 @@ static int show_cpuinfo(struct seq_file *m, void *v)
cpu_has_divec ? "yes" : "no");
seq_printf(m, "hardware watchpoint\t: %s\n",
cpu_has_watch ? "yes" : "no");
+ seq_printf(m, "ASEs implemented\t:%s%s%s%s%s%s\n",
+ cpu_has_mips16 ? " mips16" : "",
+ cpu_has_mdmx ? " mdmx" : "",
+ cpu_has_mips3d ? " mips3d" : "",
+ cpu_has_smartmips ? " smartmips" : "",
+ cpu_has_dsp ? " dsp" : "",
+ cpu_has_mipsmt ? " mt" : ""
+ );
sprintf(fmt, "VCE%%c exceptions\t\t: %s\n",
cpu_has_vce ? "%u" : "not available");
diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c
index e4f2f8011387..dd725779d91f 100644
--- a/arch/mips/kernel/process.c
+++ b/arch/mips/kernel/process.c
@@ -25,8 +25,10 @@
#include <linux/init.h>
#include <linux/completion.h>
+#include <asm/abi.h>
#include <asm/bootinfo.h>
#include <asm/cpu.h>
+#include <asm/dsp.h>
#include <asm/fpu.h>
#include <asm/pgtable.h>
#include <asm/system.h>
@@ -39,14 +41,6 @@
#include <asm/inst.h>
/*
- * We use this if we don't have any better idle routine..
- * (This to kill: kernel/platform.c.
- */
-void default_idle (void)
-{
-}
-
-/*
* The idle thread. There's no useful work to be done, so just try to conserve
* power and have a low exit latency (ie sit in a loop waiting for somebody to
* say that they'd like to reschedule)
@@ -58,10 +52,60 @@ ATTRIB_NORET void cpu_idle(void)
while (!need_resched())
if (cpu_wait)
(*cpu_wait)();
+ preempt_enable_no_resched();
schedule();
+ preempt_disable();
}
}
+extern int do_signal(sigset_t *oldset, struct pt_regs *regs);
+extern int do_signal32(sigset_t *oldset, struct pt_regs *regs);
+
+/*
+ * Native o32 and N64 ABI without DSP ASE
+ */
+extern int setup_frame(struct k_sigaction * ka, struct pt_regs *regs,
+ int signr, sigset_t *set);
+extern int setup_rt_frame(struct k_sigaction * ka, struct pt_regs *regs,
+ int signr, sigset_t *set, siginfo_t *info);
+
+struct mips_abi mips_abi = {
+ .do_signal = do_signal,
+#ifdef CONFIG_TRAD_SIGNALS
+ .setup_frame = setup_frame,
+#endif
+ .setup_rt_frame = setup_rt_frame
+};
+
+#ifdef CONFIG_MIPS32_O32
+/*
+ * o32 compatibility on 64-bit kernels, without DSP ASE
+ */
+extern int setup_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
+ int signr, sigset_t *set);
+extern int setup_rt_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
+ int signr, sigset_t *set, siginfo_t *info);
+
+struct mips_abi mips_abi_32 = {
+ .do_signal = do_signal32,
+ .setup_frame = setup_frame_32,
+ .setup_rt_frame = setup_rt_frame_32
+};
+#endif /* CONFIG_MIPS32_O32 */
+
+#ifdef CONFIG_MIPS32_N32
+/*
+ * N32 on 64-bit kernels, without DSP ASE
+ */
+extern int setup_rt_frame_n32(struct k_sigaction * ka, struct pt_regs *regs,
+ int signr, sigset_t *set, siginfo_t *info);
+
+struct mips_abi mips_abi_n32 = {
+ .do_signal = do_signal,
+ .setup_rt_frame = setup_rt_frame_n32
+};
+#endif /* CONFIG_MIPS32_N32 */
+
asmlinkage void ret_from_fork(void);
void start_thread(struct pt_regs * regs, unsigned long pc, unsigned long sp)
@@ -78,6 +122,8 @@ void start_thread(struct pt_regs * regs, unsigned long pc, unsigned long sp)
regs->cp0_status = status;
clear_used_math();
lose_fpu();
+ if (cpu_has_dsp)
+ __init_dsp();
regs->cp0_epc = pc;
regs->regs[29] = sp;
current_thread_info()->addr_limit = USER_DS;
@@ -97,14 +143,17 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
struct thread_info *ti = p->thread_info;
struct pt_regs *childregs;
long childksp;
+ p->set_child_tid = p->clear_child_tid = NULL;
childksp = (unsigned long)ti + THREAD_SIZE - 32;
preempt_disable();
- if (is_fpu_owner()) {
+ if (is_fpu_owner())
save_fp(p);
- }
+
+ if (cpu_has_dsp)
+ save_dsp(p);
preempt_enable();
@@ -142,6 +191,9 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
childregs->cp0_status &= ~(ST0_CU2|ST0_CU1);
clear_tsk_thread_flag(p, TIF_USEDFPU);
+ if (clone_flags & CLONE_SETTLS)
+ ti->tp_value = regs->regs[7];
+
return 0;
}
@@ -175,6 +227,14 @@ void dump_regs(elf_greg_t *gp, struct pt_regs *regs)
#endif
}
+int dump_task_regs (struct task_struct *tsk, elf_gregset_t *regs)
+{
+ struct thread_info *ti = tsk->thread_info;
+ long ksp = (unsigned long)ti + THREAD_SIZE - 32;
+ dump_regs(&(*regs)[0], (struct pt_regs *) ksp - 1);
+ return 1;
+}
+
int dump_task_fpu (struct task_struct *t, elf_fpregset_t *fpr)
{
memcpy(fpr, &t->thread.fpu, sizeof(current->thread.fpu));
@@ -211,22 +271,48 @@ long kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, &regs, 0, NULL, NULL);
}
-struct mips_frame_info {
+static struct mips_frame_info {
+ void *func;
+ int omit_fp; /* compiled without fno-omit-frame-pointer */
int frame_offset;
int pc_offset;
+} schedule_frame, mfinfo[] = {
+ { schedule, 0 }, /* must be first */
+ /* arch/mips/kernel/semaphore.c */
+ { __down, 1 },
+ { __down_interruptible, 1 },
+ /* kernel/sched.c */
+#ifdef CONFIG_PREEMPT
+ { preempt_schedule, 0 },
+#endif
+ { wait_for_completion, 0 },
+ { interruptible_sleep_on, 0 },
+ { interruptible_sleep_on_timeout, 0 },
+ { sleep_on, 0 },
+ { sleep_on_timeout, 0 },
+ { yield, 0 },
+ { io_schedule, 0 },
+ { io_schedule_timeout, 0 },
+#if defined(CONFIG_SMP) && defined(CONFIG_PREEMPT)
+ { __preempt_spin_lock, 0 },
+ { __preempt_write_lock, 0 },
+#endif
+ /* kernel/timer.c */
+ { schedule_timeout, 1 },
+/* { nanosleep_restart, 1 }, */
+ /* lib/rwsem-spinlock.c */
+ { __down_read, 1 },
+ { __down_write, 1 },
};
-static struct mips_frame_info schedule_frame;
-static struct mips_frame_info schedule_timeout_frame;
-static struct mips_frame_info sleep_on_frame;
-static struct mips_frame_info sleep_on_timeout_frame;
-static struct mips_frame_info wait_for_completion_frame;
+
static int mips_frame_info_initialized;
-static int __init get_frame_info(struct mips_frame_info *info, void *func)
+static int __init get_frame_info(struct mips_frame_info *info)
{
int i;
+ void *func = info->func;
union mips_instruction *ip = (union mips_instruction *)func;
info->pc_offset = -1;
- info->frame_offset = -1;
+ info->frame_offset = info->omit_fp ? 0 : -1;
for (i = 0; i < 128; i++, ip++) {
/* if jal, jalr, jr, stop. */
if (ip->j_format.opcode == jal_op ||
@@ -247,14 +333,16 @@ static int __init get_frame_info(struct mips_frame_info *info, void *func)
/* sw / sd $ra, offset($sp) */
if (ip->i_format.rt == 31) {
if (info->pc_offset != -1)
- break;
+ continue;
info->pc_offset =
ip->i_format.simmediate / sizeof(long);
}
/* sw / sd $s8, offset($sp) */
if (ip->i_format.rt == 30) {
+//#if 0 /* gcc 3.4 does aggressive optimization... */
if (info->frame_offset != -1)
- break;
+ continue;
+//#endif
info->frame_offset =
ip->i_format.simmediate / sizeof(long);
}
@@ -272,13 +360,25 @@ static int __init get_frame_info(struct mips_frame_info *info, void *func)
static int __init frame_info_init(void)
{
- mips_frame_info_initialized =
- !get_frame_info(&schedule_frame, schedule) &&
- !get_frame_info(&schedule_timeout_frame, schedule_timeout) &&
- !get_frame_info(&sleep_on_frame, sleep_on) &&
- !get_frame_info(&sleep_on_timeout_frame, sleep_on_timeout) &&
- !get_frame_info(&wait_for_completion_frame, wait_for_completion);
-
+ int i, found;
+ for (i = 0; i < ARRAY_SIZE(mfinfo); i++)
+ if (get_frame_info(&mfinfo[i]))
+ return -1;
+ schedule_frame = mfinfo[0];
+ /* bubble sort */
+ do {
+ struct mips_frame_info tmp;
+ found = 0;
+ for (i = 1; i < ARRAY_SIZE(mfinfo); i++) {
+ if (mfinfo[i-1].func > mfinfo[i].func) {
+ tmp = mfinfo[i];
+ mfinfo[i] = mfinfo[i-1];
+ mfinfo[i-1] = tmp;
+ found = 1;
+ }
+ }
+ } while (found);
+ mips_frame_info_initialized = 1;
return 0;
}
@@ -303,60 +403,39 @@ unsigned long thread_saved_pc(struct task_struct *tsk)
/* get_wchan - a maintenance nightmare^W^Wpain in the ass ... */
unsigned long get_wchan(struct task_struct *p)
{
+ unsigned long stack_page;
unsigned long frame, pc;
if (!p || p == current || p->state == TASK_RUNNING)
return 0;
- if (!mips_frame_info_initialized)
+ stack_page = (unsigned long)p->thread_info;
+ if (!stack_page || !mips_frame_info_initialized)
return 0;
+
pc = thread_saved_pc(p);
if (!in_sched_functions(pc))
- goto out;
-
- if (pc >= (unsigned long) sleep_on_timeout)
- goto schedule_timeout_caller;
- if (pc >= (unsigned long) sleep_on)
- goto schedule_caller;
- if (pc >= (unsigned long) interruptible_sleep_on_timeout)
- goto schedule_timeout_caller;
- if (pc >= (unsigned long)interruptible_sleep_on)
- goto schedule_caller;
- if (pc >= (unsigned long)wait_for_completion)
- goto schedule_caller;
- goto schedule_timeout_caller;
-
-schedule_caller:
- frame = ((unsigned long *)p->thread.reg30)[schedule_frame.frame_offset];
- if (pc >= (unsigned long) sleep_on)
- pc = ((unsigned long *)frame)[sleep_on_frame.pc_offset];
- else
- pc = ((unsigned long *)frame)[wait_for_completion_frame.pc_offset];
- goto out;
+ return pc;
-schedule_timeout_caller:
- /*
- * The schedule_timeout frame
- */
frame = ((unsigned long *)p->thread.reg30)[schedule_frame.frame_offset];
+ do {
+ int i;
- /*
- * frame now points to sleep_on_timeout's frame
- */
- pc = ((unsigned long *)frame)[schedule_timeout_frame.pc_offset];
-
- if (in_sched_functions(pc)) {
- /* schedule_timeout called by [interruptible_]sleep_on_timeout */
- frame = ((unsigned long *)frame)[schedule_timeout_frame.frame_offset];
- pc = ((unsigned long *)frame)[sleep_on_timeout_frame.pc_offset];
- }
+ if (frame < stack_page || frame > stack_page + THREAD_SIZE - 32)
+ return 0;
-out:
+ for (i = ARRAY_SIZE(mfinfo) - 1; i >= 0; i--) {
+ if (pc >= (unsigned long) mfinfo[i].func)
+ break;
+ }
+ if (i < 0)
+ break;
-#ifdef CONFIG_64BIT
- if (current->thread.mflags & MF_32BIT_REGS) /* Kludge for 32-bit ps */
- pc &= 0xffffffffUL;
-#endif
+ if (mfinfo[i].omit_fp)
+ break;
+ pc = ((unsigned long *)frame)[mfinfo[i].pc_offset];
+ frame = ((unsigned long *)frame)[mfinfo[i].frame_offset];
+ } while (in_sched_functions(pc));
return pc;
}
diff --git a/arch/mips/kernel/ptrace.c b/arch/mips/kernel/ptrace.c
index 0b571a5b4b83..510da5fda567 100644
--- a/arch/mips/kernel/ptrace.c
+++ b/arch/mips/kernel/ptrace.c
@@ -28,14 +28,18 @@
#include <linux/security.h>
#include <linux/signal.h>
+#include <asm/byteorder.h>
#include <asm/cpu.h>
+#include <asm/dsp.h>
#include <asm/fpu.h>
#include <asm/mipsregs.h>
+#include <asm/mipsmtregs.h>
#include <asm/pgtable.h>
#include <asm/page.h>
#include <asm/system.h>
#include <asm/uaccess.h>
#include <asm/bootinfo.h>
+#include <asm/reg.h>
/*
* Called by kernel/ptrace.c when detaching..
@@ -47,50 +51,132 @@ void ptrace_disable(struct task_struct *child)
/* Nothing to do.. */
}
-asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
+/*
+ * Read a general register set. We always use the 64-bit format, even
+ * for 32-bit kernels and for 32-bit processes on a 64-bit kernel.
+ * Registers are sign extended to fill the available space.
+ */
+int ptrace_getregs (struct task_struct *child, __s64 __user *data)
{
- struct task_struct *child;
- int ret;
+ struct pt_regs *regs;
+ int i;
-#if 0
- printk("ptrace(r=%d,pid=%d,addr=%08lx,data=%08lx)\n",
- (int) request, (int) pid, (unsigned long) addr,
- (unsigned long) data);
-#endif
- lock_kernel();
- ret = -EPERM;
- if (request == PTRACE_TRACEME) {
- /* are we already being traced? */
- if (current->ptrace & PT_PTRACED)
- goto out;
- if ((ret = security_ptrace(current->parent, current)))
- goto out;
- /* set the ptrace bit in the process flags. */
- current->ptrace |= PT_PTRACED;
- ret = 0;
- goto out;
+ if (!access_ok(VERIFY_WRITE, data, 38 * 8))
+ return -EIO;
+
+ regs = (struct pt_regs *) ((unsigned long) child->thread_info +
+ THREAD_SIZE - 32 - sizeof(struct pt_regs));
+
+ for (i = 0; i < 32; i++)
+ __put_user (regs->regs[i], data + i);
+ __put_user (regs->lo, data + EF_LO - EF_R0);
+ __put_user (regs->hi, data + EF_HI - EF_R0);
+ __put_user (regs->cp0_epc, data + EF_CP0_EPC - EF_R0);
+ __put_user (regs->cp0_badvaddr, data + EF_CP0_BADVADDR - EF_R0);
+ __put_user (regs->cp0_status, data + EF_CP0_STATUS - EF_R0);
+ __put_user (regs->cp0_cause, data + EF_CP0_CAUSE - EF_R0);
+
+ return 0;
+}
+
+/*
+ * Write a general register set. As for PTRACE_GETREGS, we always use
+ * the 64-bit format. On a 32-bit kernel only the lower order half
+ * (according to endianness) will be used.
+ */
+int ptrace_setregs (struct task_struct *child, __s64 __user *data)
+{
+ struct pt_regs *regs;
+ int i;
+
+ if (!access_ok(VERIFY_READ, data, 38 * 8))
+ return -EIO;
+
+ regs = (struct pt_regs *) ((unsigned long) child->thread_info +
+ THREAD_SIZE - 32 - sizeof(struct pt_regs));
+
+ for (i = 0; i < 32; i++)
+ __get_user (regs->regs[i], data + i);
+ __get_user (regs->lo, data + EF_LO - EF_R0);
+ __get_user (regs->hi, data + EF_HI - EF_R0);
+ __get_user (regs->cp0_epc, data + EF_CP0_EPC - EF_R0);
+
+ /* badvaddr, status, and cause may not be written. */
+
+ return 0;
+}
+
+int ptrace_getfpregs (struct task_struct *child, __u32 __user *data)
+{
+ int i;
+
+ if (!access_ok(VERIFY_WRITE, data, 33 * 8))
+ return -EIO;
+
+ if (tsk_used_math(child)) {
+ fpureg_t *fregs = get_fpu_regs(child);
+ for (i = 0; i < 32; i++)
+ __put_user (fregs[i], i + (__u64 __user *) data);
+ } else {
+ for (i = 0; i < 32; i++)
+ __put_user ((__u64) -1, i + (__u64 __user *) data);
}
- ret = -ESRCH;
- read_lock(&tasklist_lock);
- child = find_task_by_pid(pid);
- if (child)
- get_task_struct(child);
- read_unlock(&tasklist_lock);
- if (!child)
- goto out;
- ret = -EPERM;
- if (pid == 1) /* you may not mess with init */
- goto out_tsk;
+ if (cpu_has_fpu) {
+ unsigned int flags, tmp;
+
+ __put_user (child->thread.fpu.hard.fcr31, data + 64);
- if (request == PTRACE_ATTACH) {
- ret = ptrace_attach(child);
- goto out_tsk;
+ preempt_disable();
+ if (cpu_has_mipsmt) {
+ unsigned int vpflags = dvpe();
+ flags = read_c0_status();
+ __enable_fpu();
+ __asm__ __volatile__("cfc1\t%0,$0" : "=r" (tmp));
+ write_c0_status(flags);
+ evpe(vpflags);
+ } else {
+ flags = read_c0_status();
+ __enable_fpu();
+ __asm__ __volatile__("cfc1\t%0,$0" : "=r" (tmp));
+ write_c0_status(flags);
+ }
+ preempt_enable();
+ __put_user (tmp, data + 65);
+ } else {
+ __put_user (child->thread.fpu.soft.fcr31, data + 64);
+ __put_user ((__u32) 0, data + 65);
}
- ret = ptrace_check_attach(child, request == PTRACE_KILL);
- if (ret < 0)
- goto out_tsk;
+ return 0;
+}
+
+int ptrace_setfpregs (struct task_struct *child, __u32 __user *data)
+{
+ fpureg_t *fregs;
+ int i;
+
+ if (!access_ok(VERIFY_READ, data, 33 * 8))
+ return -EIO;
+
+ fregs = get_fpu_regs(child);
+
+ for (i = 0; i < 32; i++)
+ __get_user (fregs[i], i + (__u64 __user *) data);
+
+ if (cpu_has_fpu)
+ __get_user (child->thread.fpu.hard.fcr31, data + 64);
+ else
+ __get_user (child->thread.fpu.soft.fcr31, data + 64);
+
+ /* FIR may not be written. */
+
+ return 0;
+}
+
+long arch_ptrace(struct task_struct *child, long request, long addr, long data)
+{
+ int ret;
switch (request) {
/* when I and D space are separate, these will need to be fixed. */
@@ -103,7 +189,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
ret = -EIO;
if (copied != sizeof(tmp))
break;
- ret = put_user(tmp,(unsigned long *) data);
+ ret = put_user(tmp,(unsigned long __user *) data);
break;
}
@@ -169,18 +255,53 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
if (!cpu_has_fpu)
break;
- flags = read_c0_status();
- __enable_fpu();
- __asm__ __volatile__("cfc1\t%0,$0": "=r" (tmp));
- write_c0_status(flags);
+ preempt_disable();
+ if (cpu_has_mipsmt) {
+ unsigned int vpflags = dvpe();
+ flags = read_c0_status();
+ __enable_fpu();
+ __asm__ __volatile__("cfc1\t%0,$0": "=r" (tmp));
+ write_c0_status(flags);
+ evpe(vpflags);
+ } else {
+ flags = read_c0_status();
+ __enable_fpu();
+ __asm__ __volatile__("cfc1\t%0,$0": "=r" (tmp));
+ write_c0_status(flags);
+ }
+ preempt_enable();
break;
}
+ case DSP_BASE ... DSP_BASE + 5: {
+ dspreg_t *dregs;
+
+ if (!cpu_has_dsp) {
+ tmp = 0;
+ ret = -EIO;
+ goto out;
+ }
+ if (child->thread.dsp.used_dsp) {
+ dregs = __get_dsp_regs(child);
+ tmp = (unsigned long) (dregs[addr - DSP_BASE]);
+ } else {
+ tmp = -1; /* DSP registers yet used */
+ }
+ break;
+ }
+ case DSP_CONTROL:
+ if (!cpu_has_dsp) {
+ tmp = 0;
+ ret = -EIO;
+ goto out;
+ }
+ tmp = child->thread.dsp.dspcontrol;
+ break;
default:
tmp = 0;
ret = -EIO;
- goto out_tsk;
+ goto out;
}
- ret = put_user(tmp, (unsigned long *) data);
+ ret = put_user(tmp, (unsigned long __user *) data);
break;
}
@@ -247,6 +368,25 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
else
child->thread.fpu.soft.fcr31 = data;
break;
+ case DSP_BASE ... DSP_BASE + 5: {
+ dspreg_t *dregs;
+
+ if (!cpu_has_dsp) {
+ ret = -EIO;
+ break;
+ }
+
+ dregs = __get_dsp_regs(child);
+ dregs[addr - DSP_BASE] = data;
+ break;
+ }
+ case DSP_CONTROL:
+ if (!cpu_has_dsp) {
+ ret = -EIO;
+ break;
+ }
+ child->thread.dsp.dspcontrol = data;
+ break;
default:
/* The rest are not allowed. */
ret = -EIO;
@@ -255,6 +395,22 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
break;
}
+ case PTRACE_GETREGS:
+ ret = ptrace_getregs (child, (__u64 __user *) data);
+ break;
+
+ case PTRACE_SETREGS:
+ ret = ptrace_setregs (child, (__u64 __user *) data);
+ break;
+
+ case PTRACE_GETFPREGS:
+ ret = ptrace_getfpregs (child, (__u32 __user *) data);
+ break;
+
+ case PTRACE_SETFPREGS:
+ ret = ptrace_setfpregs (child, (__u32 __user *) data);
+ break;
+
case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
case PTRACE_CONT: { /* restart after signal. */
ret = -EIO;
@@ -289,35 +445,29 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
ret = ptrace_detach(child, data);
break;
+ case PTRACE_GET_THREAD_AREA:
+ ret = put_user(child->thread_info->tp_value,
+ (unsigned long __user *) data);
+ break;
+
default:
ret = ptrace_request(child, request, addr, data);
break;
}
-
-out_tsk:
- put_task_struct(child);
-out:
- unlock_kernel();
+ out:
return ret;
}
static inline int audit_arch(void)
{
-#ifdef CONFIG_CPU_LITTLE_ENDIAN
-#ifdef CONFIG_64BIT
- if (!(current->thread.mflags & MF_32BIT_REGS))
- return AUDIT_ARCH_MIPSEL64;
-#endif /* MIPS64 */
- return AUDIT_ARCH_MIPSEL;
-
-#else /* big endian... */
+ int arch = EM_MIPS;
#ifdef CONFIG_64BIT
- if (!(current->thread.mflags & MF_32BIT_REGS))
- return AUDIT_ARCH_MIPS64;
-#endif /* MIPS64 */
- return AUDIT_ARCH_MIPS;
-
-#endif /* endian */
+ arch |= __AUDIT_ARCH_64BIT;
+#endif
+#if defined(__LITTLE_ENDIAN)
+ arch |= __AUDIT_ARCH_LE;
+#endif
+ return arch;
}
/*
@@ -327,12 +477,13 @@ static inline int audit_arch(void)
asmlinkage void do_syscall_trace(struct pt_regs *regs, int entryexit)
{
if (unlikely(current->audit_context) && entryexit)
- audit_syscall_exit(current, AUDITSC_RESULT(regs->regs[2]), regs->regs[2]);
+ audit_syscall_exit(current, AUDITSC_RESULT(regs->regs[2]),
+ regs->regs[2]);
- if (!test_thread_flag(TIF_SYSCALL_TRACE))
- goto out;
if (!(current->ptrace & PT_PTRACED))
goto out;
+ if (!test_thread_flag(TIF_SYSCALL_TRACE))
+ goto out;
/* The 0x80 provides a way for the tracing parent to distinguish
between a syscall stop and SIGTRAP delivery */
diff --git a/arch/mips/kernel/ptrace32.c b/arch/mips/kernel/ptrace32.c
index eee207969c21..9a9b04972132 100644
--- a/arch/mips/kernel/ptrace32.c
+++ b/arch/mips/kernel/ptrace32.c
@@ -24,17 +24,24 @@
#include <linux/smp_lock.h>
#include <linux/user.h>
#include <linux/security.h>
-#include <linux/signal.h>
#include <asm/cpu.h>
+#include <asm/dsp.h>
#include <asm/fpu.h>
#include <asm/mipsregs.h>
+#include <asm/mipsmtregs.h>
#include <asm/pgtable.h>
#include <asm/page.h>
#include <asm/system.h>
#include <asm/uaccess.h>
#include <asm/bootinfo.h>
+int ptrace_getregs (struct task_struct *child, __s64 __user *data);
+int ptrace_setregs (struct task_struct *child, __s64 __user *data);
+
+int ptrace_getfpregs (struct task_struct *child, __u32 __user *data);
+int ptrace_setfpregs (struct task_struct *child, __u32 __user *data);
+
/*
* Tracing a 32-bit process with a 64-bit strace and vice versa will not
* work. I don't know how to fix this.
@@ -99,6 +106,35 @@ asmlinkage int sys32_ptrace(int request, int pid, int addr, int data)
break;
}
+ /*
+ * Read 4 bytes of the other process' storage
+ * data is a pointer specifying where the user wants the
+ * 4 bytes copied into
+ * addr is a pointer in the user's storage that contains an 8 byte
+ * address in the other process of the 4 bytes that is to be read
+ * (this is run in a 32-bit process looking at a 64-bit process)
+ * when I and D space are separate, these will need to be fixed.
+ */
+ case PTRACE_PEEKTEXT_3264:
+ case PTRACE_PEEKDATA_3264: {
+ u32 tmp;
+ int copied;
+ u32 __user * addrOthers;
+
+ ret = -EIO;
+
+ /* Get the addr in the other process that we want to read */
+ if (get_user(addrOthers, (u32 __user * __user *) (unsigned long) addr) != 0)
+ break;
+
+ copied = access_process_vm(child, (u64)addrOthers, &tmp,
+ sizeof(tmp), 0);
+ if (copied != sizeof(tmp))
+ break;
+ ret = put_user(tmp, (u32 __user *) (unsigned long) data);
+ break;
+ }
+
/* Read the word at location addr in the USER area. */
case PTRACE_PEEKUSR: {
struct pt_regs *regs;
@@ -156,12 +192,44 @@ asmlinkage int sys32_ptrace(int request, int pid, int addr, int data)
if (!cpu_has_fpu)
break;
- flags = read_c0_status();
- __enable_fpu();
- __asm__ __volatile__("cfc1\t%0,$0": "=r" (tmp));
- write_c0_status(flags);
+ preempt_disable();
+ if (cpu_has_mipsmt) {
+ unsigned int vpflags = dvpe();
+ flags = read_c0_status();
+ __enable_fpu();
+ __asm__ __volatile__("cfc1\t%0,$0": "=r" (tmp));
+ write_c0_status(flags);
+ evpe(vpflags);
+ } else {
+ flags = read_c0_status();
+ __enable_fpu();
+ __asm__ __volatile__("cfc1\t%0,$0": "=r" (tmp));
+ write_c0_status(flags);
+ }
+ preempt_enable();
break;
}
+ case DSP_BASE ... DSP_BASE + 5:
+ if (!cpu_has_dsp) {
+ tmp = 0;
+ ret = -EIO;
+ goto out_tsk;
+ }
+ if (child->thread.dsp.used_dsp) {
+ dspreg_t *dregs = __get_dsp_regs(child);
+ tmp = (unsigned long) (dregs[addr - DSP_BASE]);
+ } else {
+ tmp = -1; /* DSP registers yet used */
+ }
+ break;
+ case DSP_CONTROL:
+ if (!cpu_has_dsp) {
+ tmp = 0;
+ ret = -EIO;
+ goto out_tsk;
+ }
+ tmp = child->thread.dsp.dspcontrol;
+ break;
default:
tmp = 0;
ret = -EIO;
@@ -181,6 +249,31 @@ asmlinkage int sys32_ptrace(int request, int pid, int addr, int data)
ret = -EIO;
break;
+ /*
+ * Write 4 bytes into the other process' storage
+ * data is the 4 bytes that the user wants written
+ * addr is a pointer in the user's storage that contains an
+ * 8 byte address in the other process where the 4 bytes
+ * that is to be written
+ * (this is run in a 32-bit process looking at a 64-bit process)
+ * when I and D space are separate, these will need to be fixed.
+ */
+ case PTRACE_POKETEXT_3264:
+ case PTRACE_POKEDATA_3264: {
+ u32 __user * addrOthers;
+
+ /* Get the addr in the other process that we want to write into */
+ ret = -EIO;
+ if (get_user(addrOthers, (u32 __user * __user *) (unsigned long) addr) != 0)
+ break;
+ ret = 0;
+ if (access_process_vm(child, (u64)addrOthers, &data,
+ sizeof(data), 1) == sizeof(data))
+ break;
+ ret = -EIO;
+ break;
+ }
+
case PTRACE_POKEUSR: {
struct pt_regs *regs;
ret = 0;
@@ -231,6 +324,22 @@ asmlinkage int sys32_ptrace(int request, int pid, int addr, int data)
else
child->thread.fpu.soft.fcr31 = data;
break;
+ case DSP_BASE ... DSP_BASE + 5:
+ if (!cpu_has_dsp) {
+ ret = -EIO;
+ break;
+ }
+
+ dspreg_t *dregs = __get_dsp_regs(child);
+ dregs[addr - DSP_BASE] = data;
+ break;
+ case DSP_CONTROL:
+ if (!cpu_has_dsp) {
+ ret = -EIO;
+ break;
+ }
+ child->thread.dsp.dspcontrol = data;
+ break;
default:
/* The rest are not allowed. */
ret = -EIO;
@@ -239,6 +348,22 @@ asmlinkage int sys32_ptrace(int request, int pid, int addr, int data)
break;
}
+ case PTRACE_GETREGS:
+ ret = ptrace_getregs (child, (__u64 __user *) (__u64) data);
+ break;
+
+ case PTRACE_SETREGS:
+ ret = ptrace_setregs (child, (__u64 __user *) (__u64) data);
+ break;
+
+ case PTRACE_GETFPREGS:
+ ret = ptrace_getfpregs (child, (__u32 __user *) (__u64) data);
+ break;
+
+ case PTRACE_SETFPREGS:
+ ret = ptrace_setfpregs (child, (__u32 __user *) (__u64) data);
+ break;
+
case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
case PTRACE_CONT: { /* restart after signal. */
ret = -EIO;
@@ -269,10 +394,25 @@ asmlinkage int sys32_ptrace(int request, int pid, int addr, int data)
wake_up_process(child);
break;
+ case PTRACE_GET_THREAD_AREA:
+ ret = put_user(child->thread_info->tp_value,
+ (unsigned int __user *) (unsigned long) data);
+ break;
+
case PTRACE_DETACH: /* detach a process that was attached. */
ret = ptrace_detach(child, data);
break;
+ case PTRACE_GETEVENTMSG:
+ ret = put_user(child->ptrace_message,
+ (unsigned int __user *) (unsigned long) data);
+ break;
+
+ case PTRACE_GET_THREAD_AREA_3264:
+ ret = put_user(child->thread_info->tp_value,
+ (unsigned long __user *) (unsigned long) data);
+ break;
+
default:
ret = ptrace_request(child, request, addr, data);
break;
diff --git a/arch/mips/kernel/r4k_fpu.S b/arch/mips/kernel/r4k_fpu.S
index 1a14c6b18829..283a98508fc8 100644
--- a/arch/mips/kernel/r4k_fpu.S
+++ b/arch/mips/kernel/r4k_fpu.S
@@ -32,7 +32,7 @@
.set noreorder
.set mips3
- /* Save floating point context */
+
LEAF(_save_fp_context)
cfc1 t1, fcr31
@@ -74,9 +74,6 @@ LEAF(_save_fp_context)
EX sdc1 $f28, SC_FPREGS+224(a0)
EX sdc1 $f30, SC_FPREGS+240(a0)
EX sw t1, SC_FPC_CSR(a0)
- cfc1 t0, $0 # implementation/version
- EX sw t0, SC_FPC_EIR(a0)
-
jr ra
li v0, 0 # success
END(_save_fp_context)
diff --git a/arch/mips/kernel/rtlx.c b/arch/mips/kernel/rtlx.c
new file mode 100644
index 000000000000..1d855112bac2
--- /dev/null
+++ b/arch/mips/kernel/rtlx.c
@@ -0,0 +1,330 @@
+/*
+ * Copyright (C) 2005 MIPS Technologies, Inc. All rights reserved.
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/init.h>
+#include <linux/poll.h>
+#include <linux/sched.h>
+#include <linux/wait.h>
+#include <asm/mipsmtregs.h>
+#include <asm/bitops.h>
+#include <asm/cpu.h>
+#include <asm/processor.h>
+#include <asm/rtlx.h>
+#include <asm/uaccess.h>
+
+#define RTLX_TARG_VPE 1
+
+static struct rtlx_info *rtlx;
+static int major;
+static char module_name[] = "rtlx";
+static struct irqaction irq;
+static int irq_num;
+
+static inline int spacefree(int read, int write, int size)
+{
+ if (read == write) {
+ /*
+ * never fill the buffer completely, so indexes are always
+ * equal if empty and only empty, or !equal if data available
+ */
+ return size - 1;
+ }
+
+ return ((read + size - write) % size) - 1;
+}
+
+static struct chan_waitqueues {
+ wait_queue_head_t rt_queue;
+ wait_queue_head_t lx_queue;
+} channel_wqs[RTLX_CHANNELS];
+
+extern void *vpe_get_shared(int index);
+
+static void rtlx_dispatch(struct pt_regs *regs)
+{
+ do_IRQ(MIPSCPU_INT_BASE + MIPS_CPU_RTLX_IRQ, regs);
+}
+
+static irqreturn_t rtlx_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+ int i;
+
+ for (i = 0; i < RTLX_CHANNELS; i++) {
+ struct rtlx_channel *chan = &rtlx->channel[i];
+
+ if (chan->lx_read != chan->lx_write)
+ wake_up_interruptible(&channel_wqs[i].lx_queue);
+ }
+
+ return IRQ_HANDLED;
+}
+
+/* call when we have the address of the shared structure from the SP side. */
+static int rtlx_init(struct rtlx_info *rtlxi)
+{
+ int i;
+
+ if (rtlxi->id != RTLX_ID) {
+ printk(KERN_WARNING "no valid RTLX id at 0x%p\n", rtlxi);
+ return -ENOEXEC;
+ }
+
+ /* initialise the wait queues */
+ for (i = 0; i < RTLX_CHANNELS; i++) {
+ init_waitqueue_head(&channel_wqs[i].rt_queue);
+ init_waitqueue_head(&channel_wqs[i].lx_queue);
+ }
+
+ /* set up for interrupt handling */
+ memset(&irq, 0, sizeof(struct irqaction));
+
+ if (cpu_has_vint)
+ set_vi_handler(MIPS_CPU_RTLX_IRQ, rtlx_dispatch);
+
+ irq_num = MIPSCPU_INT_BASE + MIPS_CPU_RTLX_IRQ;
+ irq.handler = rtlx_interrupt;
+ irq.flags = SA_INTERRUPT;
+ irq.name = "RTLX";
+ irq.dev_id = rtlx;
+ setup_irq(irq_num, &irq);
+
+ rtlx = rtlxi;
+
+ return 0;
+}
+
+/* only allow one open process at a time to open each channel */
+static int rtlx_open(struct inode *inode, struct file *filp)
+{
+ int minor, ret;
+ struct rtlx_channel *chan;
+
+ /* assume only 1 device at the mo. */
+ minor = MINOR(inode->i_rdev);
+
+ if (rtlx == NULL) {
+ struct rtlx_info **p;
+ if( (p = vpe_get_shared(RTLX_TARG_VPE)) == NULL) {
+ printk(KERN_ERR "vpe_get_shared is NULL. "
+ "Has an SP program been loaded?\n");
+ return -EFAULT;
+ }
+
+ if (*p == NULL) {
+ printk(KERN_ERR "vpe_shared %p %p\n", p, *p);
+ return -EFAULT;
+ }
+
+ if ((ret = rtlx_init(*p)) < 0)
+ return ret;
+ }
+
+ chan = &rtlx->channel[minor];
+
+ if (test_and_set_bit(RTLX_STATE_OPENED, &chan->lx_state))
+ return -EBUSY;
+
+ return 0;
+}
+
+static int rtlx_release(struct inode *inode, struct file *filp)
+{
+ int minor = MINOR(inode->i_rdev);
+
+ clear_bit(RTLX_STATE_OPENED, &rtlx->channel[minor].lx_state);
+ smp_mb__after_clear_bit();
+
+ return 0;
+}
+
+static unsigned int rtlx_poll(struct file *file, poll_table * wait)
+{
+ int minor;
+ unsigned int mask = 0;
+ struct rtlx_channel *chan;
+
+ minor = MINOR(file->f_dentry->d_inode->i_rdev);
+ chan = &rtlx->channel[minor];
+
+ poll_wait(file, &channel_wqs[minor].rt_queue, wait);
+ poll_wait(file, &channel_wqs[minor].lx_queue, wait);
+
+ /* data available to read? */
+ if (chan->lx_read != chan->lx_write)
+ mask |= POLLIN | POLLRDNORM;
+
+ /* space to write */
+ if (spacefree(chan->rt_read, chan->rt_write, chan->buffer_size))
+ mask |= POLLOUT | POLLWRNORM;
+
+ return mask;
+}
+
+static ssize_t rtlx_read(struct file *file, char __user * buffer, size_t count,
+ loff_t * ppos)
+{
+ unsigned long failed;
+ size_t fl = 0L;
+ int minor;
+ struct rtlx_channel *lx;
+ DECLARE_WAITQUEUE(wait, current);
+
+ minor = MINOR(file->f_dentry->d_inode->i_rdev);
+ lx = &rtlx->channel[minor];
+
+ /* data available? */
+ if (lx->lx_write == lx->lx_read) {
+ if (file->f_flags & O_NONBLOCK)
+ return 0; /* -EAGAIN makes cat whinge */
+
+ /* go to sleep */
+ add_wait_queue(&channel_wqs[minor].lx_queue, &wait);
+ set_current_state(TASK_INTERRUPTIBLE);
+
+ while (lx->lx_write == lx->lx_read)
+ schedule();
+
+ set_current_state(TASK_RUNNING);
+ remove_wait_queue(&channel_wqs[minor].lx_queue, &wait);
+
+ /* back running */
+ }
+
+ /* find out how much in total */
+ count = min(count,
+ (size_t)(lx->lx_write + lx->buffer_size - lx->lx_read) % lx->buffer_size);
+
+ /* then how much from the read pointer onwards */
+ fl = min(count, (size_t)lx->buffer_size - lx->lx_read);
+
+ failed = copy_to_user (buffer, &lx->lx_buffer[lx->lx_read], fl);
+ if (failed) {
+ count = fl - failed;
+ goto out;
+ }
+
+ /* and if there is anything left at the beginning of the buffer */
+ if (count - fl) {
+ failed = copy_to_user (buffer + fl, lx->lx_buffer, count - fl);
+ if (failed) {
+ count -= failed;
+ goto out;
+ }
+ }
+
+out:
+ /* update the index */
+ lx->lx_read += count;
+ lx->lx_read %= lx->buffer_size;
+
+ return count;
+}
+
+static ssize_t rtlx_write(struct file *file, const char __user * buffer,
+ size_t count, loff_t * ppos)
+{
+ unsigned long failed;
+ int minor;
+ struct rtlx_channel *rt;
+ size_t fl;
+ DECLARE_WAITQUEUE(wait, current);
+
+ minor = MINOR(file->f_dentry->d_inode->i_rdev);
+ rt = &rtlx->channel[minor];
+
+ /* any space left... */
+ if (!spacefree(rt->rt_read, rt->rt_write, rt->buffer_size)) {
+
+ if (file->f_flags & O_NONBLOCK)
+ return -EAGAIN;
+
+ add_wait_queue(&channel_wqs[minor].rt_queue, &wait);
+ set_current_state(TASK_INTERRUPTIBLE);
+
+ while (!spacefree(rt->rt_read, rt->rt_write, rt->buffer_size))
+ schedule();
+
+ set_current_state(TASK_RUNNING);
+ remove_wait_queue(&channel_wqs[minor].rt_queue, &wait);
+ }
+
+ /* total number of bytes to copy */
+ count = min(count, (size_t)spacefree(rt->rt_read, rt->rt_write, rt->buffer_size) );
+
+ /* first bit from write pointer to the end of the buffer, or count */
+ fl = min(count, (size_t) rt->buffer_size - rt->rt_write);
+
+ failed = copy_from_user(&rt->rt_buffer[rt->rt_write], buffer, fl);
+ if (failed) {
+ count = fl - failed;
+ goto out;
+ }
+
+ /* if there's any left copy to the beginning of the buffer */
+ if (count - fl) {
+ failed = copy_from_user(rt->rt_buffer, buffer + fl, count - fl);
+ if (failed) {
+ count -= failed;
+ goto out;
+ }
+ }
+
+out:
+ rt->rt_write += count;
+ rt->rt_write %= rt->buffer_size;
+
+ return count;
+}
+
+static struct file_operations rtlx_fops = {
+ .owner = THIS_MODULE,
+ .open = rtlx_open,
+ .release = rtlx_release,
+ .write = rtlx_write,
+ .read = rtlx_read,
+ .poll = rtlx_poll
+};
+
+static char register_chrdev_failed[] __initdata =
+ KERN_ERR "rtlx_module_init: unable to register device\n";
+
+static int __init rtlx_module_init(void)
+{
+ major = register_chrdev(0, module_name, &rtlx_fops);
+ if (major < 0) {
+ printk(register_chrdev_failed);
+ return major;
+ }
+
+ return 0;
+}
+
+static void __exit rtlx_module_exit(void)
+{
+ unregister_chrdev(major, module_name);
+}
+
+module_init(rtlx_module_init);
+module_exit(rtlx_module_exit);
+
+MODULE_DESCRIPTION("MIPS RTLX");
+MODULE_AUTHOR("Elizabeth Clarke, MIPS Technologies, Inc.");
+MODULE_LICENSE("GPL");
diff --git a/arch/mips/kernel/scall32-o32.S b/arch/mips/kernel/scall32-o32.S
index 17b5030fb6ea..4dd8e8b4fbc2 100644
--- a/arch/mips/kernel/scall32-o32.S
+++ b/arch/mips/kernel/scall32-o32.S
@@ -578,7 +578,7 @@ einval: li v0, -EINVAL
sys sys_fremovexattr 2 /* 4235 */
sys sys_tkill 2
sys sys_sendfile64 5
- sys sys_futex 2
+ sys sys_futex 6
sys sys_sched_setaffinity 3
sys sys_sched_getaffinity 3 /* 4240 */
sys sys_io_setup 2
@@ -587,7 +587,7 @@ einval: li v0, -EINVAL
sys sys_io_submit 3
sys sys_io_cancel 3 /* 4245 */
sys sys_exit_group 1
- sys sys_lookup_dcookie 3
+ sys sys_lookup_dcookie 4
sys sys_epoll_create 1
sys sys_epoll_ctl 4
sys sys_epoll_wait 3 /* 4250 */
@@ -618,12 +618,15 @@ einval: li v0, -EINVAL
sys sys_mq_notify 2 /* 4275 */
sys sys_mq_getsetattr 3
sys sys_ni_syscall 0 /* sys_vserver */
- sys sys_waitid 4
+ sys sys_waitid 5
sys sys_ni_syscall 0 /* available, was setaltroot */
- sys sys_add_key 5
+ sys sys_add_key 5 /* 4280 */
sys sys_request_key 4
sys sys_keyctl 5
-
+ sys sys_set_thread_area 1
+ sys sys_inotify_init 0
+ sys sys_inotify_add_watch 3 /* 4285 */
+ sys sys_inotify_rm_watch 2
.endm
/* We pre-compute the number of _instruction_ bytes needed to
diff --git a/arch/mips/kernel/scall64-64.S b/arch/mips/kernel/scall64-64.S
index ffb22a2068bf..9085838d6ce3 100644
--- a/arch/mips/kernel/scall64-64.S
+++ b/arch/mips/kernel/scall64-64.S
@@ -449,3 +449,7 @@ sys_call_table:
PTR sys_add_key
PTR sys_request_key /* 5240 */
PTR sys_keyctl
+ PTR sys_set_thread_area
+ PTR sys_inotify_init
+ PTR sys_inotify_add_watch
+ PTR sys_inotify_rm_watch /* 5245 */
diff --git a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S
index e52049c87bc3..7e66eb823bf6 100644
--- a/arch/mips/kernel/scall64-n32.S
+++ b/arch/mips/kernel/scall64-n32.S
@@ -176,7 +176,7 @@ EXPORT(sysn32_call_table)
PTR sys_fork
PTR sys32_execve
PTR sys_exit
- PTR sys32_wait4
+ PTR compat_sys_wait4
PTR sys_kill /* 6060 */
PTR sys32_newuname
PTR sys_semget
@@ -216,7 +216,7 @@ EXPORT(sysn32_call_table)
PTR compat_sys_getrusage
PTR sys32_sysinfo
PTR compat_sys_times
- PTR sys_ptrace
+ PTR sys32_ptrace
PTR sys_getuid /* 6100 */
PTR sys_syslog
PTR sys_getgid
@@ -243,14 +243,14 @@ EXPORT(sysn32_call_table)
PTR sys_capget
PTR sys_capset
PTR sys32_rt_sigpending /* 6125 */
- PTR compat_sys_rt_sigtimedwait
- PTR sys32_rt_sigqueueinfo
+ PTR sysn32_rt_sigtimedwait
+ PTR sys_rt_sigqueueinfo
PTR sys32_rt_sigsuspend
PTR sys32_sigaltstack
PTR compat_sys_utime /* 6130 */
PTR sys_mknod
PTR sys32_personality
- PTR sys_ustat
+ PTR sys32_ustat
PTR compat_sys_statfs
PTR compat_sys_fstatfs /* 6135 */
PTR sys_sysfs
@@ -329,7 +329,7 @@ EXPORT(sysn32_call_table)
PTR sys_epoll_wait
PTR sys_remap_file_pages /* 6210 */
PTR sysn32_rt_sigreturn
- PTR sys_fcntl
+ PTR compat_sys_fcntl64
PTR sys_set_tid_address
PTR sys_restart_syscall
PTR sys_semtimedop /* 6215 */
@@ -337,15 +337,15 @@ EXPORT(sysn32_call_table)
PTR compat_sys_statfs64
PTR compat_sys_fstatfs64
PTR sys_sendfile64
- PTR sys_timer_create /* 6220 */
- PTR sys_timer_settime
- PTR sys_timer_gettime
+ PTR sys32_timer_create /* 6220 */
+ PTR compat_sys_timer_settime
+ PTR compat_sys_timer_gettime
PTR sys_timer_getoverrun
PTR sys_timer_delete
- PTR sys_clock_settime /* 6225 */
- PTR sys_clock_gettime
- PTR sys_clock_getres
- PTR sys_clock_nanosleep
+ PTR compat_sys_clock_settime /* 6225 */
+ PTR compat_sys_clock_gettime
+ PTR compat_sys_clock_getres
+ PTR compat_sys_clock_nanosleep
PTR sys_tgkill
PTR compat_sys_utimes /* 6230 */
PTR sys_ni_syscall /* sys_mbind */
@@ -358,8 +358,12 @@ EXPORT(sysn32_call_table)
PTR compat_sys_mq_notify
PTR compat_sys_mq_getsetattr
PTR sys_ni_syscall /* 6240, sys_vserver */
- PTR sys_waitid
+ PTR sysn32_waitid
PTR sys_ni_syscall /* available, was setaltroot */
PTR sys_add_key
PTR sys_request_key
PTR sys_keyctl /* 6245 */
+ PTR sys_set_thread_area
+ PTR sys_inotify_init
+ PTR sys_inotify_add_watch
+ PTR sys_inotify_rm_watch
diff --git a/arch/mips/kernel/scall64-o32.S b/arch/mips/kernel/scall64-o32.S
index 739f3998d76b..5a16401e443a 100644
--- a/arch/mips/kernel/scall64-o32.S
+++ b/arch/mips/kernel/scall64-o32.S
@@ -316,13 +316,13 @@ sys_call_table:
PTR sys_vhangup
PTR sys_ni_syscall /* was sys_idle */
PTR sys_ni_syscall /* sys_vm86 */
- PTR sys32_wait4
+ PTR compat_sys_wait4
PTR sys_swapoff /* 4115 */
PTR sys32_sysinfo
PTR sys32_ipc
PTR sys_fsync
PTR sys32_sigreturn
- PTR sys_clone /* 4120 */
+ PTR sys32_clone /* 4120 */
PTR sys_setdomainname
PTR sys32_newuname
PTR sys_ni_syscall /* sys_modify_ldt */
@@ -391,7 +391,7 @@ sys_call_table:
PTR sys_getresuid
PTR sys_ni_syscall /* was query_module */
PTR sys_poll
- PTR sys_nfsservctl
+ PTR compat_sys_nfsservctl
PTR sys_setresgid /* 4190 */
PTR sys_getresgid
PTR sys_prctl
@@ -459,7 +459,7 @@ sys_call_table:
PTR sys_fadvise64_64
PTR compat_sys_statfs64 /* 4255 */
PTR compat_sys_fstatfs64
- PTR sys_timer_create
+ PTR sys32_timer_create
PTR compat_sys_timer_settime
PTR compat_sys_timer_gettime
PTR sys_timer_getoverrun /* 4260 */
@@ -480,9 +480,13 @@ sys_call_table:
PTR compat_sys_mq_notify /* 4275 */
PTR compat_sys_mq_getsetattr
PTR sys_ni_syscall /* sys_vserver */
- PTR sys_waitid
+ PTR sys32_waitid
PTR sys_ni_syscall /* available, was setaltroot */
PTR sys_add_key /* 4280 */
PTR sys_request_key
PTR sys_keyctl
+ PTR sys_set_thread_area
+ PTR sys_inotify_init
+ PTR sys_inotify_add_watch /* 4285 */
+ PTR sys_inotify_rm_watch
.size sys_call_table,.-sys_call_table
diff --git a/arch/mips/kernel/semaphore.c b/arch/mips/kernel/semaphore.c
index 9c40fe5a8e8d..1265358cdca1 100644
--- a/arch/mips/kernel/semaphore.c
+++ b/arch/mips/kernel/semaphore.c
@@ -42,24 +42,28 @@ static inline int __sem_update_count(struct semaphore *sem, int incr)
if (cpu_has_llsc && R10000_LLSC_WAR) {
__asm__ __volatile__(
- "1: ll %0, %2 \n"
+ " .set mips3 \n"
+ "1: ll %0, %2 # __sem_update_count \n"
" sra %1, %0, 31 \n"
" not %1 \n"
" and %1, %0, %1 \n"
- " add %1, %1, %3 \n"
+ " addu %1, %1, %3 \n"
" sc %1, %2 \n"
" beqzl %1, 1b \n"
+ " .set mips0 \n"
: "=&r" (old_count), "=&r" (tmp), "=m" (sem->count)
: "r" (incr), "m" (sem->count));
} else if (cpu_has_llsc) {
__asm__ __volatile__(
- "1: ll %0, %2 \n"
+ " .set mips3 \n"
+ "1: ll %0, %2 # __sem_update_count \n"
" sra %1, %0, 31 \n"
" not %1 \n"
" and %1, %0, %1 \n"
- " add %1, %1, %3 \n"
+ " addu %1, %1, %3 \n"
" sc %1, %2 \n"
" beqz %1, 1b \n"
+ " .set mips0 \n"
: "=&r" (old_count), "=&r" (tmp), "=m" (sem->count)
: "r" (incr), "m" (sem->count));
} else {
diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
index 12b531c295c4..d86affa21278 100644
--- a/arch/mips/kernel/setup.c
+++ b/arch/mips/kernel/setup.c
@@ -37,12 +37,13 @@
#include <asm/addrspace.h>
#include <asm/bootinfo.h>
+#include <asm/cache.h>
#include <asm/cpu.h>
#include <asm/sections.h>
#include <asm/setup.h>
#include <asm/system.h>
-struct cpuinfo_mips cpu_data[NR_CPUS];
+struct cpuinfo_mips cpu_data[NR_CPUS] __read_mostly;
EXPORT_SYMBOL(cpu_data);
@@ -62,8 +63,8 @@ EXPORT_SYMBOL(PCI_DMA_BUS_IS_PHYS);
*
* These are initialized so they are in the .data section
*/
-unsigned long mips_machtype = MACH_UNKNOWN;
-unsigned long mips_machgroup = MACH_GROUP_UNKNOWN;
+unsigned long mips_machtype __read_mostly = MACH_UNKNOWN;
+unsigned long mips_machgroup __read_mostly = MACH_GROUP_UNKNOWN;
EXPORT_SYMBOL(mips_machtype);
EXPORT_SYMBOL(mips_machgroup);
@@ -77,7 +78,7 @@ static char command_line[CL_SIZE];
* mips_io_port_base is the begin of the address space to which x86 style
* I/O ports are mapped.
*/
-const unsigned long mips_io_port_base = -1;
+const unsigned long mips_io_port_base __read_mostly = -1;
EXPORT_SYMBOL(mips_io_port_base);
/*
@@ -510,31 +511,7 @@ static inline void resource_init(void)
#undef MAXMEM
#undef MAXMEM_PFN
-static int __initdata earlyinit_debug;
-
-static int __init earlyinit_debug_setup(char *str)
-{
- earlyinit_debug = 1;
- return 1;
-}
-__setup("earlyinit_debug", earlyinit_debug_setup);
-
-extern initcall_t __earlyinitcall_start, __earlyinitcall_end;
-
-static void __init do_earlyinitcalls(void)
-{
- initcall_t *call, *start, *end;
-
- start = &__earlyinitcall_start;
- end = &__earlyinitcall_end;
-
- for (call = start; call < end; call++) {
- if (earlyinit_debug)
- printk("calling earlyinitcall 0x%p\n", *call);
-
- (*call)();
- }
-}
+extern void plat_setup(void);
void __init setup_arch(char **cmdline_p)
{
@@ -551,7 +528,7 @@ void __init setup_arch(char **cmdline_p)
#endif
/* call board setup routine */
- do_earlyinitcalls();
+ plat_setup();
strlcpy(command_line, arcs_cmdline, sizeof(command_line));
strlcpy(saved_command_line, command_line, COMMAND_LINE_SIZE);
@@ -573,3 +550,12 @@ int __init fpu_disable(char *s)
}
__setup("nofpu", fpu_disable);
+
+int __init dsp_disable(char *s)
+{
+ cpu_data[0].ases &= ~MIPS_ASE_DSP;
+
+ return 1;
+}
+
+__setup("nodsp", dsp_disable);
diff --git a/arch/mips/kernel/signal-common.h b/arch/mips/kernel/signal-common.h
index f9234df53253..0f66ae5838b9 100644
--- a/arch/mips/kernel/signal-common.h
+++ b/arch/mips/kernel/signal-common.h
@@ -8,13 +8,14 @@
* Copyright (C) 1999, 2000 Silicon Graphics, Inc.
*/
+#include <linux/config.h>
+
static inline int
setup_sigcontext(struct pt_regs *regs, struct sigcontext *sc)
{
int err = 0;
err |= __put_user(regs->cp0_epc, &sc->sc_pc);
- err |= __put_user(regs->cp0_status, &sc->sc_status);
#define save_gp_reg(i) do { \
err |= __put_user(regs->regs[i], &sc->sc_regs[i]); \
@@ -30,10 +31,32 @@ setup_sigcontext(struct pt_regs *regs, struct sigcontext *sc)
save_gp_reg(31);
#undef save_gp_reg
+#ifdef CONFIG_32BIT
err |= __put_user(regs->hi, &sc->sc_mdhi);
err |= __put_user(regs->lo, &sc->sc_mdlo);
- err |= __put_user(regs->cp0_cause, &sc->sc_cause);
- err |= __put_user(regs->cp0_badvaddr, &sc->sc_badvaddr);
+ if (cpu_has_dsp) {
+ err |= __put_user(mfhi1(), &sc->sc_hi1);
+ err |= __put_user(mflo1(), &sc->sc_lo1);
+ err |= __put_user(mfhi2(), &sc->sc_hi2);
+ err |= __put_user(mflo2(), &sc->sc_lo2);
+ err |= __put_user(mfhi3(), &sc->sc_hi3);
+ err |= __put_user(mflo3(), &sc->sc_lo3);
+ err |= __put_user(rddsp(DSP_MASK), &sc->sc_dsp);
+ }
+#endif
+#ifdef CONFIG_64BIT
+ err |= __put_user(regs->hi, &sc->sc_hi[0]);
+ err |= __put_user(regs->lo, &sc->sc_lo[0]);
+ if (cpu_has_dsp) {
+ err |= __put_user(mfhi1(), &sc->sc_hi[1]);
+ err |= __put_user(mflo1(), &sc->sc_lo[1]);
+ err |= __put_user(mfhi2(), &sc->sc_hi[2]);
+ err |= __put_user(mflo2(), &sc->sc_lo[2]);
+ err |= __put_user(mfhi3(), &sc->sc_hi[3]);
+ err |= __put_user(mflo3(), &sc->sc_lo[3]);
+ err |= __put_user(rddsp(DSP_MASK), &sc->sc_dsp);
+ }
+#endif
err |= __put_user(!!used_math(), &sc->sc_used_math);
@@ -61,15 +84,40 @@ out:
static inline int
restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc)
{
- int err = 0;
unsigned int used_math;
+ unsigned long treg;
+ int err = 0;
/* Always make any pending restarted system calls return -EINTR */
current_thread_info()->restart_block.fn = do_no_restart_syscall;
err |= __get_user(regs->cp0_epc, &sc->sc_pc);
+#ifdef CONFIG_32BIT
err |= __get_user(regs->hi, &sc->sc_mdhi);
err |= __get_user(regs->lo, &sc->sc_mdlo);
+ if (cpu_has_dsp) {
+ err |= __get_user(treg, &sc->sc_hi1); mthi1(treg);
+ err |= __get_user(treg, &sc->sc_lo1); mtlo1(treg);
+ err |= __get_user(treg, &sc->sc_hi2); mthi2(treg);
+ err |= __get_user(treg, &sc->sc_lo2); mtlo2(treg);
+ err |= __get_user(treg, &sc->sc_hi3); mthi3(treg);
+ err |= __get_user(treg, &sc->sc_lo3); mtlo3(treg);
+ err |= __get_user(treg, &sc->sc_dsp); wrdsp(treg, DSP_MASK);
+ }
+#endif
+#ifdef CONFIG_64BIT
+ err |= __get_user(regs->hi, &sc->sc_hi[0]);
+ err |= __get_user(regs->lo, &sc->sc_lo[0]);
+ if (cpu_has_dsp) {
+ err |= __get_user(treg, &sc->sc_hi[1]); mthi1(treg);
+ err |= __get_user(treg, &sc->sc_lo[1]); mthi1(treg);
+ err |= __get_user(treg, &sc->sc_hi[2]); mthi2(treg);
+ err |= __get_user(treg, &sc->sc_lo[2]); mthi2(treg);
+ err |= __get_user(treg, &sc->sc_hi[3]); mthi3(treg);
+ err |= __get_user(treg, &sc->sc_lo[3]); mthi3(treg);
+ err |= __get_user(treg, &sc->sc_dsp); wrdsp(treg, DSP_MASK);
+ }
+#endif
#define restore_gp_reg(i) do { \
err |= __get_user(regs->regs[i], &sc->sc_regs[i]); \
@@ -112,7 +160,7 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc)
static inline void *
get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size)
{
- unsigned long sp, almask;
+ unsigned long sp;
/* Default to using normal stack */
sp = regs->regs[29];
@@ -128,10 +176,32 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size)
if ((ka->sa.sa_flags & SA_ONSTACK) && (sas_ss_flags (sp) == 0))
sp = current->sas_ss_sp + current->sas_ss_size;
- if (PLAT_TRAMPOLINE_STUFF_LINE)
- almask = ~(PLAT_TRAMPOLINE_STUFF_LINE - 1);
- else
- almask = ALMASK;
+ return (void *)((sp - frame_size) & (ICACHE_REFILLS_WORKAROUND_WAR ? 32 : ALMASK));
+}
+
+static inline int install_sigtramp(unsigned int __user *tramp,
+ unsigned int syscall)
+{
+ int err;
+
+ /*
+ * Set up the return code ...
+ *
+ * li v0, __NR__foo_sigreturn
+ * syscall
+ */
+
+ err = __put_user(0x24020000 + syscall, tramp + 0);
+ err |= __put_user(0x0000000c , tramp + 1);
+ if (ICACHE_REFILLS_WORKAROUND_WAR) {
+ err |= __put_user(0, tramp + 2);
+ err |= __put_user(0, tramp + 3);
+ err |= __put_user(0, tramp + 4);
+ err |= __put_user(0, tramp + 5);
+ err |= __put_user(0, tramp + 6);
+ err |= __put_user(0, tramp + 7);
+ }
+ flush_cache_sigtramp((unsigned long) tramp);
- return (void *)((sp - frame_size) & almask);
+ return err;
}
diff --git a/arch/mips/kernel/signal.c b/arch/mips/kernel/signal.c
index 0209c1dd1429..05e09eedabff 100644
--- a/arch/mips/kernel/signal.c
+++ b/arch/mips/kernel/signal.c
@@ -8,6 +8,7 @@
* Copyright (C) 1999, 2000 Silicon Graphics, Inc.
*/
#include <linux/config.h>
+#include <linux/cache.h>
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/personality.h>
@@ -21,6 +22,7 @@
#include <linux/unistd.h>
#include <linux/compiler.h>
+#include <asm/abi.h>
#include <asm/asm.h>
#include <linux/bitops.h>
#include <asm/cacheflush.h>
@@ -29,6 +31,7 @@
#include <asm/uaccess.h>
#include <asm/ucontext.h>
#include <asm/cpu-features.h>
+#include <asm/war.h>
#include "signal-common.h"
@@ -36,7 +39,7 @@
#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
-static int do_signal(sigset_t *oldset, struct pt_regs *regs);
+int do_signal(sigset_t *oldset, struct pt_regs *regs);
/*
* Atomically swap in the new signal mask, and wait for a signal.
@@ -47,9 +50,10 @@ save_static_function(sys_sigsuspend);
__attribute_used__ noinline static int
_sys_sigsuspend(nabi_no_regargs struct pt_regs regs)
{
- sigset_t *uset, saveset, newset;
+ sigset_t saveset, newset;
+ sigset_t __user *uset;
- uset = (sigset_t *) regs.regs[4];
+ uset = (sigset_t __user *) regs.regs[4];
if (copy_from_user(&newset, uset, sizeof(sigset_t)))
return -EFAULT;
sigdelsetmask(&newset, ~_BLOCKABLE);
@@ -75,7 +79,8 @@ save_static_function(sys_rt_sigsuspend);
__attribute_used__ noinline static int
_sys_rt_sigsuspend(nabi_no_regargs struct pt_regs regs)
{
- sigset_t *unewset, saveset, newset;
+ sigset_t saveset, newset;
+ sigset_t __user *unewset;
size_t sigsetsize;
/* XXX Don't preclude handling different sized sigset_t's. */
@@ -83,7 +88,7 @@ _sys_rt_sigsuspend(nabi_no_regargs struct pt_regs regs)
if (sigsetsize != sizeof(sigset_t))
return -EINVAL;
- unewset = (sigset_t *) regs.regs[4];
+ unewset = (sigset_t __user *) regs.regs[4];
if (copy_from_user(&newset, unewset, sizeof(newset)))
return -EFAULT;
sigdelsetmask(&newset, ~_BLOCKABLE);
@@ -147,33 +152,46 @@ asmlinkage int sys_sigaction(int sig, const struct sigaction *act,
asmlinkage int sys_sigaltstack(nabi_no_regargs struct pt_regs regs)
{
- const stack_t *uss = (const stack_t *) regs.regs[4];
- stack_t *uoss = (stack_t *) regs.regs[5];
+ const stack_t __user *uss = (const stack_t __user *) regs.regs[4];
+ stack_t __user *uoss = (stack_t __user *) regs.regs[5];
unsigned long usp = regs.regs[29];
return do_sigaltstack(uss, uoss, usp);
}
-#if PLAT_TRAMPOLINE_STUFF_LINE
-#define __tramp __attribute__((aligned(PLAT_TRAMPOLINE_STUFF_LINE)))
-#else
-#define __tramp
-#endif
-
+/*
+ * Horribly complicated - with the bloody RM9000 workarounds enabled
+ * the signal trampolines is moving to the end of the structure so we can
+ * increase the alignment without breaking software compatibility.
+ */
#ifdef CONFIG_TRAD_SIGNALS
struct sigframe {
u32 sf_ass[4]; /* argument save space for o32 */
- u32 sf_code[2] __tramp; /* signal trampoline */
- struct sigcontext sf_sc __tramp;
+#if ICACHE_REFILLS_WORKAROUND_WAR
+ u32 sf_pad[2];
+#else
+ u32 sf_code[2]; /* signal trampoline */
+#endif
+ struct sigcontext sf_sc;
sigset_t sf_mask;
+#if ICACHE_REFILLS_WORKAROUND_WAR
+ u32 sf_code[8] ____cacheline_aligned; /* signal trampoline */
+#endif
};
#endif
struct rt_sigframe {
u32 rs_ass[4]; /* argument save space for o32 */
- u32 rs_code[2] __tramp; /* signal trampoline */
- struct siginfo rs_info __tramp;
+#if ICACHE_REFILLS_WORKAROUND_WAR
+ u32 rs_pad[2];
+#else
+ u32 rs_code[2]; /* signal trampoline */
+#endif
+ struct siginfo rs_info;
struct ucontext rs_uc;
+#if ICACHE_REFILLS_WORKAROUND_WAR
+ u32 rs_code[8] ____cacheline_aligned; /* signal trampoline */
+#endif
};
#ifdef CONFIG_TRAD_SIGNALS
@@ -214,7 +232,7 @@ _sys_sigreturn(nabi_no_regargs struct pt_regs regs)
badframe:
force_sig(SIGSEGV, current);
}
-#endif
+#endif /* CONFIG_TRAD_SIGNALS */
save_static_function(sys_rt_sigreturn);
__attribute_used__ noinline static void
@@ -260,7 +278,7 @@ badframe:
}
#ifdef CONFIG_TRAD_SIGNALS
-static void inline setup_frame(struct k_sigaction * ka, struct pt_regs *regs,
+int setup_frame(struct k_sigaction * ka, struct pt_regs *regs,
int signr, sigset_t *set)
{
struct sigframe *frame;
@@ -270,17 +288,7 @@ static void inline setup_frame(struct k_sigaction * ka, struct pt_regs *regs,
if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
goto give_sigsegv;
- /*
- * Set up the return code ...
- *
- * li v0, __NR_sigreturn
- * syscall
- */
- if (PLAT_TRAMPOLINE_STUFF_LINE)
- __clear_user(frame->sf_code, PLAT_TRAMPOLINE_STUFF_LINE);
- err |= __put_user(0x24020000 + __NR_sigreturn, frame->sf_code + 0);
- err |= __put_user(0x0000000c , frame->sf_code + 1);
- flush_cache_sigtramp((unsigned long) frame->sf_code);
+ install_sigtramp(frame->sf_code, __NR_sigreturn);
err |= setup_sigcontext(regs, &frame->sf_sc);
err |= __copy_to_user(&frame->sf_mask, set, sizeof(*set));
@@ -309,14 +317,15 @@ static void inline setup_frame(struct k_sigaction * ka, struct pt_regs *regs,
current->comm, current->pid,
frame, regs->cp0_epc, frame->regs[31]);
#endif
- return;
+ return 1;
give_sigsegv:
force_sigsegv(signr, current);
+ return 0;
}
#endif
-static void inline setup_rt_frame(struct k_sigaction * ka, struct pt_regs *regs,
+int setup_rt_frame(struct k_sigaction * ka, struct pt_regs *regs,
int signr, sigset_t *set, siginfo_t *info)
{
struct rt_sigframe *frame;
@@ -326,17 +335,7 @@ static void inline setup_rt_frame(struct k_sigaction * ka, struct pt_regs *regs,
if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
goto give_sigsegv;
- /*
- * Set up the return code ...
- *
- * li v0, __NR_rt_sigreturn
- * syscall
- */
- if (PLAT_TRAMPOLINE_STUFF_LINE)
- __clear_user(frame->rs_code, PLAT_TRAMPOLINE_STUFF_LINE);
- err |= __put_user(0x24020000 + __NR_rt_sigreturn, frame->rs_code + 0);
- err |= __put_user(0x0000000c , frame->rs_code + 1);
- flush_cache_sigtramp((unsigned long) frame->rs_code);
+ install_sigtramp(frame->rs_code, __NR_rt_sigreturn);
/* Create siginfo. */
err |= copy_siginfo_to_user(&frame->rs_info, info);
@@ -378,18 +377,18 @@ static void inline setup_rt_frame(struct k_sigaction * ka, struct pt_regs *regs,
current->comm, current->pid,
frame, regs->cp0_epc, regs->regs[31]);
#endif
- return;
+ return 1;
give_sigsegv:
force_sigsegv(signr, current);
+ return 0;
}
-extern void setup_rt_frame_n32(struct k_sigaction * ka,
- struct pt_regs *regs, int signr, sigset_t *set, siginfo_t *info);
-
-static inline void handle_signal(unsigned long sig, siginfo_t *info,
+static inline int handle_signal(unsigned long sig, siginfo_t *info,
struct k_sigaction *ka, sigset_t *oldset, struct pt_regs *regs)
{
+ int ret;
+
switch(regs->regs[0]) {
case ERESTART_RESTARTBLOCK:
case ERESTARTNOHAND:
@@ -408,22 +407,10 @@ static inline void handle_signal(unsigned long sig, siginfo_t *info,
regs->regs[0] = 0; /* Don't deal with this again. */
-#ifdef CONFIG_TRAD_SIGNALS
- if (ka->sa.sa_flags & SA_SIGINFO) {
-#else
- if (1) {
-#endif
-#ifdef CONFIG_MIPS32_N32
- if ((current->thread.mflags & MF_ABI_MASK) == MF_N32)
- setup_rt_frame_n32 (ka, regs, sig, oldset, info);
- else
-#endif
- setup_rt_frame(ka, regs, sig, oldset, info);
- }
-#ifdef CONFIG_TRAD_SIGNALS
+ if (sig_uses_siginfo(ka))
+ ret = current->thread.abi->setup_rt_frame(ka, regs, sig, oldset, info);
else
- setup_frame(ka, regs, sig, oldset);
-#endif
+ ret = current->thread.abi->setup_frame(ka, regs, sig, oldset);
spin_lock_irq(&current->sighand->siglock);
sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
@@ -431,23 +418,16 @@ static inline void handle_signal(unsigned long sig, siginfo_t *info,
sigaddset(&current->blocked,sig);
recalc_sigpending();
spin_unlock_irq(&current->sighand->siglock);
-}
-extern int do_signal32(sigset_t *oldset, struct pt_regs *regs);
-extern int do_irix_signal(sigset_t *oldset, struct pt_regs *regs);
+ return ret;
+}
-static int do_signal(sigset_t *oldset, struct pt_regs *regs)
+int do_signal(sigset_t *oldset, struct pt_regs *regs)
{
struct k_sigaction ka;
siginfo_t info;
int signr;
-#ifdef CONFIG_BINFMT_ELF32
- if ((current->thread.mflags & MF_ABI_MASK) == MF_O32) {
- return do_signal32(oldset, regs);
- }
-#endif
-
/*
* We want the common case to go fast, which is why we may in certain
* cases get here from kernel mode. Just return without doing anything
@@ -463,10 +443,8 @@ static int do_signal(sigset_t *oldset, struct pt_regs *regs)
oldset = &current->blocked;
signr = get_signal_to_deliver(&info, &ka, regs, NULL);
- if (signr > 0) {
- handle_signal(signr, &info, &ka, oldset, regs);
- return 1;
- }
+ if (signr > 0)
+ return handle_signal(signr, &info, &ka, oldset, regs);
no_signal:
/*
@@ -499,18 +477,6 @@ asmlinkage void do_notify_resume(struct pt_regs *regs, sigset_t *oldset,
{
/* deal with pending signal delivery */
if (thread_info_flags & _TIF_SIGPENDING) {
-#ifdef CONFIG_BINFMT_ELF32
- if (likely((current->thread.mflags & MF_ABI_MASK) == MF_O32)) {
- do_signal32(oldset, regs);
- return;
- }
-#endif
-#ifdef CONFIG_BINFMT_IRIX
- if (unlikely(current->personality != PER_LINUX)) {
- do_irix_signal(oldset, regs);
- return;
- }
-#endif
- do_signal(oldset, regs);
+ current->thread.abi->do_signal(oldset, regs);
}
}
diff --git a/arch/mips/kernel/signal32.c b/arch/mips/kernel/signal32.c
index 8ddfbd8d425a..e315d3f6aa6e 100644
--- a/arch/mips/kernel/signal32.c
+++ b/arch/mips/kernel/signal32.c
@@ -7,6 +7,7 @@
* Copyright (C) 1994 - 2000 Ralf Baechle
* Copyright (C) 1999, 2000 Silicon Graphics, Inc.
*/
+#include <linux/cache.h>
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/smp.h>
@@ -21,6 +22,7 @@
#include <linux/suspend.h>
#include <linux/compiler.h>
+#include <asm/abi.h>
#include <asm/asm.h>
#include <linux/bitops.h>
#include <asm/cacheflush.h>
@@ -29,6 +31,7 @@
#include <asm/ucontext.h>
#include <asm/system.h>
#include <asm/fpu.h>
+#include <asm/war.h>
#define SI_PAD_SIZE32 ((SI_MAX_SIZE/sizeof(int)) - 3)
@@ -76,8 +79,10 @@ typedef struct compat_siginfo {
/* POSIX.1b timers */
struct {
- unsigned int _timer1;
- unsigned int _timer2;
+ timer_t _tid; /* timer id */
+ int _overrun; /* overrun count */
+ compat_sigval_t _sigval;/* same as below */
+ int _sys_private; /* not to be passed to user */
} _timer;
/* POSIX.1b signals */
@@ -259,11 +264,12 @@ asmlinkage int sys32_sigaction(int sig, const struct sigaction32 *act,
if (act) {
old_sigset_t mask;
+ s32 handler;
if (!access_ok(VERIFY_READ, act, sizeof(*act)))
return -EFAULT;
- err |= __get_user((u32)(u64)new_ka.sa.sa_handler,
- &act->sa_handler);
+ err |= __get_user(handler, &act->sa_handler);
+ new_ka.sa.sa_handler = (void*)(s64)handler;
err |= __get_user(new_ka.sa.sa_flags, &act->sa_flags);
err |= __get_user(mask, &act->sa_mask.sig[0]);
if (err)
@@ -331,8 +337,9 @@ asmlinkage int sys32_sigaltstack(nabi_no_regargs struct pt_regs regs)
static int restore_sigcontext32(struct pt_regs *regs, struct sigcontext32 *sc)
{
+ u32 used_math;
int err = 0;
- __u32 used_math;
+ s32 treg;
/* Always make any pending restarted system calls return -EINTR */
current_thread_info()->restart_block.fn = do_no_restart_syscall;
@@ -340,6 +347,15 @@ static int restore_sigcontext32(struct pt_regs *regs, struct sigcontext32 *sc)
err |= __get_user(regs->cp0_epc, &sc->sc_pc);
err |= __get_user(regs->hi, &sc->sc_mdhi);
err |= __get_user(regs->lo, &sc->sc_mdlo);
+ if (cpu_has_dsp) {
+ err |= __get_user(treg, &sc->sc_hi1); mthi1(treg);
+ err |= __get_user(treg, &sc->sc_lo1); mtlo1(treg);
+ err |= __get_user(treg, &sc->sc_hi2); mthi2(treg);
+ err |= __get_user(treg, &sc->sc_lo2); mtlo2(treg);
+ err |= __get_user(treg, &sc->sc_hi3); mthi3(treg);
+ err |= __get_user(treg, &sc->sc_lo3); mtlo3(treg);
+ err |= __get_user(treg, &sc->sc_dsp); wrdsp(treg, DSP_MASK);
+ }
#define restore_gp_reg(i) do { \
err |= __get_user(regs->regs[i], &sc->sc_regs[i]); \
@@ -378,16 +394,30 @@ static int restore_sigcontext32(struct pt_regs *regs, struct sigcontext32 *sc)
struct sigframe {
u32 sf_ass[4]; /* argument save space for o32 */
+#if ICACHE_REFILLS_WORKAROUND_WAR
+ u32 sf_pad[2];
+#else
u32 sf_code[2]; /* signal trampoline */
+#endif
struct sigcontext32 sf_sc;
sigset_t sf_mask;
+#if ICACHE_REFILLS_WORKAROUND_WAR
+ u32 sf_code[8] ____cacheline_aligned; /* signal trampoline */
+#endif
};
struct rt_sigframe32 {
u32 rs_ass[4]; /* argument save space for o32 */
+#if ICACHE_REFILLS_WORKAROUND_WAR
+ u32 rs_pad[2];
+#else
u32 rs_code[2]; /* signal trampoline */
+#endif
compat_siginfo_t rs_info;
struct ucontext32 rs_uc;
+#if ICACHE_REFILLS_WORKAROUND_WAR
+ u32 rs_code[8] __attribute__((aligned(32))); /* signal trampoline */
+#endif
};
int copy_siginfo_to_user32(compat_siginfo_t *to, siginfo_t *from)
@@ -411,6 +441,11 @@ int copy_siginfo_to_user32(compat_siginfo_t *to, siginfo_t *from)
err |= __copy_to_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE);
else {
switch (from->si_code >> 16) {
+ case __SI_TIMER >> 16:
+ err |= __put_user(from->si_tid, &to->si_tid);
+ err |= __put_user(from->si_overrun, &to->si_overrun);
+ err |= __put_user(from->si_int, &to->si_int);
+ break;
case __SI_CHLD >> 16:
err |= __put_user(from->si_utime, &to->si_utime);
err |= __put_user(from->si_stime, &to->si_stime);
@@ -480,6 +515,7 @@ __attribute_used__ noinline static void
_sys32_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
{
struct rt_sigframe32 *frame;
+ mm_segment_t old_fs;
sigset_t set;
stack_t st;
s32 sp;
@@ -510,7 +546,10 @@ _sys32_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
/* It is more difficult to avoid calling this function than to
call it and ignore errors. */
+ old_fs = get_fs();
+ set_fs (KERNEL_DS);
do_sigaltstack(&st, NULL, regs.regs[29]);
+ set_fs (old_fs);
/*
* Don't let your children do this ...
@@ -550,8 +589,15 @@ static inline int setup_sigcontext32(struct pt_regs *regs,
err |= __put_user(regs->hi, &sc->sc_mdhi);
err |= __put_user(regs->lo, &sc->sc_mdlo);
- err |= __put_user(regs->cp0_cause, &sc->sc_cause);
- err |= __put_user(regs->cp0_badvaddr, &sc->sc_badvaddr);
+ if (cpu_has_dsp) {
+ err |= __put_user(rddsp(DSP_MASK), &sc->sc_hi1);
+ err |= __put_user(mfhi1(), &sc->sc_hi1);
+ err |= __put_user(mflo1(), &sc->sc_lo1);
+ err |= __put_user(mfhi2(), &sc->sc_hi2);
+ err |= __put_user(mflo2(), &sc->sc_lo2);
+ err |= __put_user(mfhi3(), &sc->sc_hi3);
+ err |= __put_user(mflo3(), &sc->sc_lo3);
+ }
err |= __put_user(!!used_math(), &sc->sc_used_math);
@@ -601,8 +647,8 @@ static inline void *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
return (void *)((sp - frame_size) & ALMASK);
}
-static inline void setup_frame(struct k_sigaction * ka, struct pt_regs *regs,
- int signr, sigset_t *set)
+int setup_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
+ int signr, sigset_t *set)
{
struct sigframe *frame;
int err = 0;
@@ -648,15 +694,15 @@ static inline void setup_frame(struct k_sigaction * ka, struct pt_regs *regs,
current->comm, current->pid,
frame, regs->cp0_epc, frame->sf_code);
#endif
- return;
+ return 1;
give_sigsegv:
force_sigsegv(signr, current);
+ return 0;
}
-static inline void setup_rt_frame(struct k_sigaction * ka,
- struct pt_regs *regs, int signr,
- sigset_t *set, siginfo_t *info)
+int setup_rt_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
+ int signr, sigset_t *set, siginfo_t *info)
{
struct rt_sigframe32 *frame;
int err = 0;
@@ -719,15 +765,18 @@ static inline void setup_rt_frame(struct k_sigaction * ka,
current->comm, current->pid,
frame, regs->cp0_epc, frame->rs_code);
#endif
- return;
+ return 1;
give_sigsegv:
force_sigsegv(signr, current);
+ return 0;
}
-static inline void handle_signal(unsigned long sig, siginfo_t *info,
+static inline int handle_signal(unsigned long sig, siginfo_t *info,
struct k_sigaction *ka, sigset_t *oldset, struct pt_regs * regs)
{
+ int ret;
+
switch (regs->regs[0]) {
case ERESTART_RESTARTBLOCK:
case ERESTARTNOHAND:
@@ -747,9 +796,9 @@ static inline void handle_signal(unsigned long sig, siginfo_t *info,
regs->regs[0] = 0; /* Don't deal with this again. */
if (ka->sa.sa_flags & SA_SIGINFO)
- setup_rt_frame(ka, regs, sig, oldset, info);
+ ret = current->thread.abi->setup_rt_frame(ka, regs, sig, oldset, info);
else
- setup_frame(ka, regs, sig, oldset);
+ ret = current->thread.abi->setup_frame(ka, regs, sig, oldset);
spin_lock_irq(&current->sighand->siglock);
sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
@@ -757,6 +806,8 @@ static inline void handle_signal(unsigned long sig, siginfo_t *info,
sigaddset(&current->blocked,sig);
recalc_sigpending();
spin_unlock_irq(&current->sighand->siglock);
+
+ return ret;
}
int do_signal32(sigset_t *oldset, struct pt_regs *regs)
@@ -780,10 +831,8 @@ int do_signal32(sigset_t *oldset, struct pt_regs *regs)
oldset = &current->blocked;
signr = get_signal_to_deliver(&info, &ka, regs, NULL);
- if (signr > 0) {
- handle_signal(signr, &info, &ka, oldset, regs);
- return 1;
- }
+ if (signr > 0)
+ return handle_signal(signr, &info, &ka, oldset, regs);
no_signal:
/*
@@ -819,12 +868,13 @@ asmlinkage int sys32_rt_sigaction(int sig, const struct sigaction32 *act,
goto out;
if (act) {
+ s32 handler;
int err = 0;
if (!access_ok(VERIFY_READ, act, sizeof(*act)))
return -EFAULT;
- err |= __get_user((u32)(u64)new_sa.sa.sa_handler,
- &act->sa_handler);
+ err |= __get_user(handler, &act->sa_handler);
+ new_sa.sa.sa_handler = (void*)(s64)handler;
err |= __get_user(new_sa.sa.sa_flags, &act->sa_flags);
err |= get_sigset(&new_sa.sa.sa_mask, &act->sa_mask);
if (err)
@@ -902,3 +952,30 @@ asmlinkage int sys32_rt_sigqueueinfo(int pid, int sig, compat_siginfo_t *uinfo)
set_fs (old_fs);
return ret;
}
+
+asmlinkage long
+sys32_waitid(int which, compat_pid_t pid,
+ compat_siginfo_t __user *uinfo, int options,
+ struct compat_rusage __user *uru)
+{
+ siginfo_t info;
+ struct rusage ru;
+ long ret;
+ mm_segment_t old_fs = get_fs();
+
+ info.si_signo = 0;
+ set_fs (KERNEL_DS);
+ ret = sys_waitid(which, pid, (siginfo_t __user *) &info, options,
+ uru ? (struct rusage __user *) &ru : NULL);
+ set_fs (old_fs);
+
+ if (ret < 0 || info.si_signo == 0)
+ return ret;
+
+ if (uru && (ret = put_compat_rusage(&ru, uru)))
+ return ret;
+
+ BUG_ON(info.si_code & __SI_MASK);
+ info.si_code |= __SI_CHLD;
+ return copy_siginfo_to_user32(uinfo, &info);
+}
diff --git a/arch/mips/kernel/signal_n32.c b/arch/mips/kernel/signal_n32.c
index 3544208d4b4b..ec61b2670ba6 100644
--- a/arch/mips/kernel/signal_n32.c
+++ b/arch/mips/kernel/signal_n32.c
@@ -15,6 +15,8 @@
* 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/cache.h>
+#include <linux/sched.h>
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/smp.h>
@@ -36,6 +38,7 @@
#include <asm/system.h>
#include <asm/fpu.h>
#include <asm/cpu-features.h>
+#include <asm/war.h>
#include "signal-common.h"
@@ -62,17 +65,18 @@ struct ucontextn32 {
sigset_t uc_sigmask; /* mask last for extensibility */
};
-#if PLAT_TRAMPOLINE_STUFF_LINE
-#define __tramp __attribute__((aligned(PLAT_TRAMPOLINE_STUFF_LINE)))
-#else
-#define __tramp
-#endif
-
struct rt_sigframe_n32 {
u32 rs_ass[4]; /* argument save space for o32 */
- u32 rs_code[2] __tramp; /* signal trampoline */
- struct siginfo rs_info __tramp;
+#if ICACHE_REFILLS_WORKAROUND_WAR
+ u32 rs_pad[2];
+#else
+ u32 rs_code[2]; /* signal trampoline */
+#endif
+ struct siginfo rs_info;
struct ucontextn32 rs_uc;
+#if ICACHE_REFILLS_WORKAROUND_WAR
+ u32 rs_code[8] ____cacheline_aligned; /* signal trampoline */
+#endif
};
save_static_function(sysn32_rt_sigreturn);
@@ -126,7 +130,7 @@ badframe:
force_sig(SIGSEGV, current);
}
-void setup_rt_frame_n32(struct k_sigaction * ka,
+int setup_rt_frame_n32(struct k_sigaction * ka,
struct pt_regs *regs, int signr, sigset_t *set, siginfo_t *info)
{
struct rt_sigframe_n32 *frame;
@@ -137,17 +141,7 @@ void setup_rt_frame_n32(struct k_sigaction * ka,
if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
goto give_sigsegv;
- /*
- * Set up the return code ...
- *
- * li v0, __NR_rt_sigreturn
- * syscall
- */
- if (PLAT_TRAMPOLINE_STUFF_LINE)
- __clear_user(frame->rs_code, PLAT_TRAMPOLINE_STUFF_LINE);
- err |= __put_user(0x24020000 + __NR_N32_rt_sigreturn, frame->rs_code + 0);
- err |= __put_user(0x0000000c , frame->rs_code + 1);
- flush_cache_sigtramp((unsigned long) frame->rs_code);
+ install_sigtramp(frame->rs_code, __NR_N32_rt_sigreturn);
/* Create siginfo. */
err |= copy_siginfo_to_user(&frame->rs_info, info);
@@ -190,8 +184,9 @@ void setup_rt_frame_n32(struct k_sigaction * ka,
current->comm, current->pid,
frame, regs->cp0_epc, regs->regs[31]);
#endif
- return;
+ return 1;
give_sigsegv:
force_sigsegv(signr, current);
+ return 0;
}
diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c
index af5cd3b8a396..25472fcaf715 100644
--- a/arch/mips/kernel/smp.c
+++ b/arch/mips/kernel/smp.c
@@ -50,7 +50,6 @@ static void smp_tune_scheduling (void)
{
struct cache_desc *cd = &current_cpu_data.scache;
unsigned long cachesize; /* kB */
- unsigned long bandwidth = 350; /* MB/s */
unsigned long cpu_khz;
/*
@@ -83,7 +82,7 @@ extern ATTRIB_NORET void cpu_idle(void);
*/
asmlinkage void start_secondary(void)
{
- unsigned int cpu = smp_processor_id();
+ unsigned int cpu;
cpu_probe();
cpu_report();
@@ -96,6 +95,8 @@ asmlinkage void start_secondary(void)
*/
calibrate_delay();
+ preempt_disable();
+ cpu = smp_processor_id();
cpu_data[cpu].udelay_val = loops_per_jiffy;
prom_smp_finish();
@@ -121,7 +122,19 @@ struct call_data_struct *call_data;
* or are or have executed.
*
* You must not call this function with disabled interrupts or from a
- * hardware interrupt handler or from a bottom half handler.
+ * hardware interrupt handler or from a bottom half handler:
+ *
+ * CPU A CPU B
+ * Disable interrupts
+ * smp_call_function()
+ * Take call_lock
+ * Send IPIs
+ * Wait for all cpus to acknowledge IPI
+ * CPU A has not responded, spin waiting
+ * for cpu A to respond, holding call_lock
+ * smp_call_function()
+ * Spin waiting for call_lock
+ * Deadlock Deadlock
*/
int smp_call_function (void (*func) (void *info), void *info, int retry,
int wait)
@@ -130,6 +143,11 @@ int smp_call_function (void (*func) (void *info), void *info, int retry,
int i, cpus = num_online_cpus() - 1;
int cpu = smp_processor_id();
+ /*
+ * Can die spectacularly if this CPU isn't yet marked online
+ */
+ BUG_ON(!cpu_online(cpu));
+
if (!cpus)
return 0;
@@ -214,7 +232,6 @@ void __init smp_cpus_done(unsigned int max_cpus)
/* called from main before smp_init() */
void __init smp_prepare_cpus(unsigned int max_cpus)
{
- cpu_data[0].udelay_val = loops_per_jiffy;
init_new_context(current, &init_mm);
current_thread_info()->cpu = 0;
smp_tune_scheduling();
@@ -236,23 +253,28 @@ void __devinit smp_prepare_boot_cpu(void)
}
/*
- * Startup the CPU with this logical number
+ * Called once for each "cpu_possible(cpu)". Needs to spin up the cpu
+ * and keep control until "cpu_online(cpu)" is set. Note: cpu is
+ * physical, not logical.
*/
-static int __init do_boot_cpu(int cpu)
+int __devinit __cpu_up(unsigned int cpu)
{
struct task_struct *idle;
/*
+ * Processor goes to start_secondary(), sets online flag
* The following code is purely to make sure
* Linux can schedule processes on this slave.
*/
idle = fork_idle(cpu);
if (IS_ERR(idle))
- panic("failed fork for CPU %d\n", cpu);
+ panic(KERN_ERR "Fork failed for CPU %d", cpu);
prom_boot_secondary(cpu, idle);
- /* XXXKW timeout */
+ /*
+ * Trust is futile. We should really have timeouts ...
+ */
while (!cpu_isset(cpu, cpu_callin_map))
udelay(100);
@@ -261,23 +283,6 @@ static int __init do_boot_cpu(int cpu)
return 0;
}
-/*
- * Called once for each "cpu_possible(cpu)". Needs to spin up the cpu
- * and keep control until "cpu_online(cpu)" is set. Note: cpu is
- * physical, not logical.
- */
-int __devinit __cpu_up(unsigned int cpu)
-{
- int ret;
-
- /* Processor goes to start_secondary(), sets online flag */
- ret = do_boot_cpu(cpu);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
/* Not really SMP stuff ... */
int setup_profiling_timer(unsigned int multiplier)
{
diff --git a/arch/mips/kernel/smp_mt.c b/arch/mips/kernel/smp_mt.c
new file mode 100644
index 000000000000..d429544ba4bc
--- /dev/null
+++ b/arch/mips/kernel/smp_mt.c
@@ -0,0 +1,366 @@
+/*
+ * Copyright (C) 2004, 2005 MIPS Technologies, Inc. All rights reserved.
+ *
+ * Elizabeth Clarke (beth@mips.com)
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/cpumask.h>
+#include <linux/interrupt.h>
+#include <linux/compiler.h>
+
+#include <asm/atomic.h>
+#include <asm/cpu.h>
+#include <asm/processor.h>
+#include <asm/system.h>
+#include <asm/hardirq.h>
+#include <asm/mmu_context.h>
+#include <asm/smp.h>
+#include <asm/time.h>
+#include <asm/mipsregs.h>
+#include <asm/mipsmtregs.h>
+#include <asm/cacheflush.h>
+#include <asm/mips-boards/maltaint.h>
+
+#define MIPS_CPU_IPI_RESCHED_IRQ 0
+#define MIPS_CPU_IPI_CALL_IRQ 1
+
+static int cpu_ipi_resched_irq, cpu_ipi_call_irq;
+
+#if 0
+static void dump_mtregisters(int vpe, int tc)
+{
+ printk("vpe %d tc %d\n", vpe, tc);
+
+ settc(tc);
+
+ printk(" c0 status 0x%lx\n", read_vpe_c0_status());
+ printk(" vpecontrol 0x%lx\n", read_vpe_c0_vpecontrol());
+ printk(" vpeconf0 0x%lx\n", read_vpe_c0_vpeconf0());
+ printk(" tcstatus 0x%lx\n", read_tc_c0_tcstatus());
+ printk(" tcrestart 0x%lx\n", read_tc_c0_tcrestart());
+ printk(" tcbind 0x%lx\n", read_tc_c0_tcbind());
+ printk(" tchalt 0x%lx\n", read_tc_c0_tchalt());
+}
+#endif
+
+void __init sanitize_tlb_entries(void)
+{
+ int i, tlbsiz;
+ unsigned long mvpconf0, ncpu;
+
+ if (!cpu_has_mipsmt)
+ return;
+
+ set_c0_mvpcontrol(MVPCONTROL_VPC);
+
+ /* Disable TLB sharing */
+ clear_c0_mvpcontrol(MVPCONTROL_STLB);
+
+ mvpconf0 = read_c0_mvpconf0();
+
+ printk(KERN_INFO "MVPConf0 0x%lx TLBS %lx PTLBE %ld\n", mvpconf0,
+ (mvpconf0 & MVPCONF0_TLBS) >> MVPCONF0_TLBS_SHIFT,
+ (mvpconf0 & MVPCONF0_PTLBE) >> MVPCONF0_PTLBE_SHIFT);
+
+ tlbsiz = (mvpconf0 & MVPCONF0_PTLBE) >> MVPCONF0_PTLBE_SHIFT;
+ ncpu = ((mvpconf0 & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT) + 1;
+
+ printk(" tlbsiz %d ncpu %ld\n", tlbsiz, ncpu);
+
+ if (tlbsiz > 0) {
+ /* share them out across the vpe's */
+ tlbsiz /= ncpu;
+
+ printk(KERN_INFO "setting Config1.MMU_size to %d\n", tlbsiz);
+
+ for (i = 0; i < ncpu; i++) {
+ settc(i);
+
+ if (i == 0)
+ write_c0_config1((read_c0_config1() & ~(0x3f << 25)) | (tlbsiz << 25));
+ else
+ write_vpe_c0_config1((read_vpe_c0_config1() & ~(0x3f << 25)) |
+ (tlbsiz << 25));
+ }
+ }
+
+ clear_c0_mvpcontrol(MVPCONTROL_VPC);
+}
+
+#if 0
+/*
+ * Use c0_MVPConf0 to find out how many CPUs are available, setting up
+ * phys_cpu_present_map and the logical/physical mappings.
+ */
+void __init prom_build_cpu_map(void)
+{
+ int i, num, ncpus;
+
+ cpus_clear(phys_cpu_present_map);
+
+ /* assume we boot on cpu 0.... */
+ cpu_set(0, phys_cpu_present_map);
+ __cpu_number_map[0] = 0;
+ __cpu_logical_map[0] = 0;
+
+ if (cpu_has_mipsmt) {
+ ncpus = ((read_c0_mvpconf0() & (MVPCONF0_PVPE)) >> MVPCONF0_PVPE_SHIFT) + 1;
+ for (i=1, num=0; i< NR_CPUS && i<ncpus; i++) {
+ cpu_set(i, phys_cpu_present_map);
+ __cpu_number_map[i] = ++num;
+ __cpu_logical_map[num] = i;
+ }
+
+ printk(KERN_INFO "%i available secondary CPU(s)\n", num);
+ }
+}
+#endif
+
+static void ipi_resched_dispatch (struct pt_regs *regs)
+{
+ do_IRQ(MIPS_CPU_IPI_RESCHED_IRQ, regs);
+}
+
+static void ipi_call_dispatch (struct pt_regs *regs)
+{
+ do_IRQ(MIPS_CPU_IPI_CALL_IRQ, regs);
+}
+
+irqreturn_t ipi_resched_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+ return IRQ_HANDLED;
+}
+
+irqreturn_t ipi_call_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+ smp_call_function_interrupt();
+
+ return IRQ_HANDLED;
+}
+
+static struct irqaction irq_resched = {
+ .handler = ipi_resched_interrupt,
+ .flags = SA_INTERRUPT,
+ .name = "IPI_resched"
+};
+
+static struct irqaction irq_call = {
+ .handler = ipi_call_interrupt,
+ .flags = SA_INTERRUPT,
+ .name = "IPI_call"
+};
+
+/*
+ * Common setup before any secondaries are started
+ * Make sure all CPU's are in a sensible state before we boot any of the
+ * secondarys
+ */
+void prom_prepare_cpus(unsigned int max_cpus)
+{
+ unsigned long val;
+ int i, num;
+
+ if (!cpu_has_mipsmt)
+ return;
+
+ /* disable MT so we can configure */
+ dvpe();
+ dmt();
+
+ /* Put MVPE's into 'configuration state' */
+ set_c0_mvpcontrol(MVPCONTROL_VPC);
+
+ val = read_c0_mvpconf0();
+
+ /* we'll always have more TC's than VPE's, so loop setting everything
+ to a sensible state */
+ for (i = 0, num = 0; i <= ((val & MVPCONF0_PTC) >> MVPCONF0_PTC_SHIFT); i++) {
+ settc(i);
+
+ /* VPE's */
+ if (i <= ((val & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT)) {
+
+ /* deactivate all but vpe0 */
+ if (i != 0) {
+ unsigned long tmp = read_vpe_c0_vpeconf0();
+
+ tmp &= ~VPECONF0_VPA;
+
+ /* master VPE */
+ tmp |= VPECONF0_MVP;
+ write_vpe_c0_vpeconf0(tmp);
+
+ /* Record this as available CPU */
+ if (i < max_cpus) {
+ cpu_set(i, phys_cpu_present_map);
+ __cpu_number_map[i] = ++num;
+ __cpu_logical_map[num] = i;
+ }
+ }
+
+ /* disable multi-threading with TC's */
+ write_vpe_c0_vpecontrol(read_vpe_c0_vpecontrol() & ~VPECONTROL_TE);
+
+ if (i != 0) {
+ write_vpe_c0_status((read_c0_status() & ~(ST0_IM | ST0_IE | ST0_KSU)) | ST0_CU0);
+ write_vpe_c0_cause(read_vpe_c0_cause() & ~CAUSEF_IP);
+
+ /* set config to be the same as vpe0, particularly kseg0 coherency alg */
+ write_vpe_c0_config( read_c0_config());
+ }
+
+ }
+
+ /* TC's */
+
+ if (i != 0) {
+ unsigned long tmp;
+
+ /* bind a TC to each VPE, May as well put all excess TC's
+ on the last VPE */
+ if ( i >= (((val & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT)+1) )
+ write_tc_c0_tcbind(read_tc_c0_tcbind() | ((val & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT) );
+ else {
+ write_tc_c0_tcbind( read_tc_c0_tcbind() | i);
+
+ /* and set XTC */
+ write_vpe_c0_vpeconf0( read_vpe_c0_vpeconf0() | (i << VPECONF0_XTC_SHIFT));
+ }
+
+ tmp = read_tc_c0_tcstatus();
+
+ /* mark not allocated and not dynamically allocatable */
+ tmp &= ~(TCSTATUS_A | TCSTATUS_DA);
+ tmp |= TCSTATUS_IXMT; /* interrupt exempt */
+ write_tc_c0_tcstatus(tmp);
+
+ write_tc_c0_tchalt(TCHALT_H);
+ }
+ }
+
+ /* Release config state */
+ clear_c0_mvpcontrol(MVPCONTROL_VPC);
+
+ /* We'll wait until starting the secondaries before starting MVPE */
+
+ printk(KERN_INFO "Detected %i available secondary CPU(s)\n", num);
+
+ /* set up ipi interrupts */
+ if (cpu_has_vint) {
+ set_vi_handler (MIPS_CPU_IPI_RESCHED_IRQ, ipi_resched_dispatch);
+ set_vi_handler (MIPS_CPU_IPI_CALL_IRQ, ipi_call_dispatch);
+ }
+
+ cpu_ipi_resched_irq = MIPSCPU_INT_BASE + MIPS_CPU_IPI_RESCHED_IRQ;
+ cpu_ipi_call_irq = MIPSCPU_INT_BASE + MIPS_CPU_IPI_CALL_IRQ;
+
+ setup_irq(cpu_ipi_resched_irq, &irq_resched);
+ setup_irq(cpu_ipi_call_irq, &irq_call);
+
+ /* need to mark IPI's as IRQ_PER_CPU */
+ irq_desc[cpu_ipi_resched_irq].status |= IRQ_PER_CPU;
+ irq_desc[cpu_ipi_call_irq].status |= IRQ_PER_CPU;
+}
+
+/*
+ * Setup the PC, SP, and GP of a secondary processor and start it
+ * running!
+ * smp_bootstrap is the place to resume from
+ * __KSTK_TOS(idle) is apparently the stack pointer
+ * (unsigned long)idle->thread_info the gp
+ * assumes a 1:1 mapping of TC => VPE
+ */
+void prom_boot_secondary(int cpu, struct task_struct *idle)
+{
+ dvpe();
+ set_c0_mvpcontrol(MVPCONTROL_VPC);
+
+ settc(cpu);
+
+ /* restart */
+ write_tc_c0_tcrestart((unsigned long)&smp_bootstrap);
+
+ /* enable the tc this vpe/cpu will be running */
+ write_tc_c0_tcstatus((read_tc_c0_tcstatus() & ~TCSTATUS_IXMT) | TCSTATUS_A);
+
+ write_tc_c0_tchalt(0);
+
+ /* enable the VPE */
+ write_vpe_c0_vpeconf0(read_vpe_c0_vpeconf0() | VPECONF0_VPA);
+
+ /* stack pointer */
+ write_tc_gpr_sp( __KSTK_TOS(idle));
+
+ /* global pointer */
+ write_tc_gpr_gp((unsigned long)idle->thread_info);
+
+ flush_icache_range((unsigned long)idle->thread_info,
+ (unsigned long)idle->thread_info +
+ sizeof(struct thread_info));
+
+ /* finally out of configuration and into chaos */
+ clear_c0_mvpcontrol(MVPCONTROL_VPC);
+
+ evpe(EVPE_ENABLE);
+}
+
+void prom_init_secondary(void)
+{
+ write_c0_status((read_c0_status() & ~ST0_IM ) |
+ (STATUSF_IP0 | STATUSF_IP1 | STATUSF_IP7));
+}
+
+void prom_smp_finish(void)
+{
+ write_c0_compare(read_c0_count() + (8* mips_hpt_frequency/HZ));
+
+ local_irq_enable();
+}
+
+void prom_cpus_done(void)
+{
+}
+
+void core_send_ipi(int cpu, unsigned int action)
+{
+ int i;
+ unsigned long flags;
+ int vpflags;
+
+ local_irq_save (flags);
+
+ vpflags = dvpe(); /* cant access the other CPU's registers whilst MVPE enabled */
+
+ switch (action) {
+ case SMP_CALL_FUNCTION:
+ i = C_SW1;
+ break;
+
+ case SMP_RESCHEDULE_YOURSELF:
+ default:
+ i = C_SW0;
+ break;
+ }
+
+ /* 1:1 mapping of vpe and tc... */
+ settc(cpu);
+ write_vpe_c0_cause(read_vpe_c0_cause() | i);
+ evpe(vpflags);
+
+ local_irq_restore(flags);
+}
diff --git a/arch/mips/kernel/syscall.c b/arch/mips/kernel/syscall.c
index 21e3e13a4b44..ee98eeb65e85 100644
--- a/arch/mips/kernel/syscall.c
+++ b/arch/mips/kernel/syscall.c
@@ -7,6 +7,7 @@
* Copyright (C) 1999, 2000 Silicon Graphics, Inc.
* Copyright (C) 2001 MIPS Technologies, Inc.
*/
+#include <linux/config.h>
#include <linux/a.out.h>
#include <linux/errno.h>
#include <linux/linkage.h>
@@ -26,6 +27,7 @@
#include <linux/msg.h>
#include <linux/shm.h>
#include <linux/compiler.h>
+#include <linux/module.h>
#include <asm/branch.h>
#include <asm/cachectl.h>
@@ -56,6 +58,8 @@ out:
unsigned long shm_align_mask = PAGE_SIZE - 1; /* Sane caches */
+EXPORT_SYMBOL(shm_align_mask);
+
#define COLOUR_ALIGN(addr,pgoff) \
((((addr) + shm_align_mask) & ~shm_align_mask) + \
(((pgoff) << PAGE_SHIFT) & shm_align_mask))
@@ -173,14 +177,28 @@ _sys_clone(nabi_no_regargs struct pt_regs regs)
{
unsigned long clone_flags;
unsigned long newsp;
- int *parent_tidptr, *child_tidptr;
+ int __user *parent_tidptr, *child_tidptr;
clone_flags = regs.regs[4];
newsp = regs.regs[5];
if (!newsp)
newsp = regs.regs[29];
- parent_tidptr = (int *) regs.regs[6];
- child_tidptr = (int *) regs.regs[7];
+ parent_tidptr = (int __user *) regs.regs[6];
+#ifdef CONFIG_32BIT
+ /* We need to fetch the fifth argument off the stack. */
+ child_tidptr = NULL;
+ if (clone_flags & (CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID)) {
+ int __user *__user *usp = (int __user *__user *) regs.regs[29];
+ if (regs.regs[2] == __NR_syscall) {
+ if (get_user (child_tidptr, &usp[5]))
+ return -EFAULT;
+ }
+ else if (get_user (child_tidptr, &usp[4]))
+ return -EFAULT;
+ }
+#else
+ child_tidptr = (int __user *) regs.regs[8];
+#endif
return do_fork(clone_flags, newsp, &regs, 0,
parent_tidptr, child_tidptr);
}
@@ -242,6 +260,16 @@ asmlinkage int sys_olduname(struct oldold_utsname * name)
return error;
}
+void sys_set_thread_area(unsigned long addr)
+{
+ struct thread_info *ti = current->thread_info;
+
+ ti->tp_value = addr;
+
+ /* If some future MIPS implementation has this register in hardware,
+ * we will need to update it here (and in context switches). */
+}
+
asmlinkage int _sys_sysmips(int cmd, long arg1, int arg2, int arg3)
{
int tmp, len;
diff --git a/arch/mips/kernel/sysirix.c b/arch/mips/kernel/sysirix.c
index 7ae4af476974..52924f8ce23c 100644
--- a/arch/mips/kernel/sysirix.c
+++ b/arch/mips/kernel/sysirix.c
@@ -73,32 +73,30 @@ asmlinkage int irix_sysmp(struct pt_regs *regs)
}
/* The prctl commands. */
-#define PR_MAXPROCS 1 /* Tasks/user. */
-#define PR_ISBLOCKED 2 /* If blocked, return 1. */
-#define PR_SETSTACKSIZE 3 /* Set largest task stack size. */
-#define PR_GETSTACKSIZE 4 /* Get largest task stack size. */
-#define PR_MAXPPROCS 5 /* Num parallel tasks. */
-#define PR_UNBLKONEXEC 6 /* When task exec/exit's, unblock. */
-#define PR_SETEXITSIG 8 /* When task exit's, set signal. */
-#define PR_RESIDENT 9 /* Make task unswappable. */
-#define PR_ATTACHADDR 10 /* (Re-)Connect a vma to a task. */
-#define PR_DETACHADDR 11 /* Disconnect a vma from a task. */
-#define PR_TERMCHILD 12 /* When parent sleeps with fishes, kill child. */
-#define PR_GETSHMASK 13 /* Get the sproc() share mask. */
-#define PR_GETNSHARE 14 /* Number of share group members. */
-#define PR_COREPID 15 /* Add task pid to name when it core. */
-#define PR_ATTACHADDRPERM 16 /* (Re-)Connect vma, with specified prot. */
-#define PR_PTHREADEXIT 17 /* Kill a pthread without prejudice. */
-
-asmlinkage int irix_prctl(struct pt_regs *regs)
-{
- unsigned long cmd;
- int error = 0, base = 0;
+#define PR_MAXPROCS 1 /* Tasks/user. */
+#define PR_ISBLOCKED 2 /* If blocked, return 1. */
+#define PR_SETSTACKSIZE 3 /* Set largest task stack size. */
+#define PR_GETSTACKSIZE 4 /* Get largest task stack size. */
+#define PR_MAXPPROCS 5 /* Num parallel tasks. */
+#define PR_UNBLKONEXEC 6 /* When task exec/exit's, unblock. */
+#define PR_SETEXITSIG 8 /* When task exit's, set signal. */
+#define PR_RESIDENT 9 /* Make task unswappable. */
+#define PR_ATTACHADDR 10 /* (Re-)Connect a vma to a task. */
+#define PR_DETACHADDR 11 /* Disconnect a vma from a task. */
+#define PR_TERMCHILD 12 /* Kill child if the parent dies. */
+#define PR_GETSHMASK 13 /* Get the sproc() share mask. */
+#define PR_GETNSHARE 14 /* Number of share group members. */
+#define PR_COREPID 15 /* Add task pid to name when it core. */
+#define PR_ATTACHADDRPERM 16 /* (Re-)Connect vma, with specified prot. */
+#define PR_PTHREADEXIT 17 /* Kill a pthread, only for IRIX 6.[234] */
+
+asmlinkage int irix_prctl(unsigned option, ...)
+{
+ va_list args;
+ int error = 0;
- if (regs->regs[2] == 1000)
- base = 1;
- cmd = regs->regs[base + 4];
- switch (cmd) {
+ va_start(args, option);
+ switch (option) {
case PR_MAXPROCS:
printk("irix_prctl[%s:%d]: Wants PR_MAXPROCS\n",
current->comm, current->pid);
@@ -111,7 +109,7 @@ asmlinkage int irix_prctl(struct pt_regs *regs)
printk("irix_prctl[%s:%d]: Wants PR_ISBLOCKED\n",
current->comm, current->pid);
read_lock(&tasklist_lock);
- task = find_task_by_pid(regs->regs[base + 5]);
+ task = find_task_by_pid(va_arg(args, pid_t));
error = -ESRCH;
if (error)
error = (task->run_list.next != NULL);
@@ -121,7 +119,7 @@ asmlinkage int irix_prctl(struct pt_regs *regs)
}
case PR_SETSTACKSIZE: {
- long value = regs->regs[base + 5];
+ long value = va_arg(args, long);
printk("irix_prctl[%s:%d]: Wants PR_SETSTACKSIZE<%08lx>\n",
current->comm, current->pid, (unsigned long) value);
@@ -222,24 +220,20 @@ asmlinkage int irix_prctl(struct pt_regs *regs)
error = -EINVAL;
break;
- case PR_PTHREADEXIT:
- printk("irix_prctl[%s:%d]: Wants PR_PTHREADEXIT\n",
- current->comm, current->pid);
- do_exit(regs->regs[base + 5]);
-
default:
printk("irix_prctl[%s:%d]: Non-existant opcode %d\n",
- current->comm, current->pid, (int)cmd);
+ current->comm, current->pid, option);
error = -EINVAL;
break;
}
+ va_end(args);
return error;
}
#undef DEBUG_PROCGRPS
-extern unsigned long irix_mapelf(int fd, struct elf_phdr *user_phdrp, int cnt);
+extern unsigned long irix_mapelf(int fd, struct elf_phdr __user *user_phdrp, int cnt);
extern int getrusage(struct task_struct *p, int who, struct rusage __user *ru);
extern char *prom_getenv(char *name);
extern long prom_setenv(char *name, char *value);
@@ -276,23 +270,19 @@ asmlinkage int irix_syssgi(struct pt_regs *regs)
cmd = regs->regs[base + 4];
switch(cmd) {
case SGI_SYSID: {
- char *buf = (char *) regs->regs[base + 5];
+ char __user *buf = (char __user *) regs->regs[base + 5];
/* XXX Use ethernet addr.... */
- retval = clear_user(buf, 64);
+ retval = clear_user(buf, 64) ? -EFAULT : 0;
break;
}
#if 0
case SGI_RDNAME: {
int pid = (int) regs->regs[base + 5];
- char *buf = (char *) regs->regs[base + 6];
+ char __user *buf = (char __user *) regs->regs[base + 6];
struct task_struct *p;
char tcomm[sizeof(current->comm)];
- if (!access_ok(VERIFY_WRITE, buf, sizeof(tcomm))) {
- retval = -EFAULT;
- break;
- }
read_lock(&tasklist_lock);
p = find_task_by_pid(pid);
if (!p) {
@@ -304,34 +294,28 @@ asmlinkage int irix_syssgi(struct pt_regs *regs)
read_unlock(&tasklist_lock);
/* XXX Need to check sizes. */
- copy_to_user(buf, tcomm, sizeof(tcomm));
- retval = 0;
+ retval = copy_to_user(buf, tcomm, sizeof(tcomm)) ? -EFAULT : 0;
break;
}
case SGI_GETNVRAM: {
- char *name = (char *) regs->regs[base+5];
- char *buf = (char *) regs->regs[base+6];
+ char __user *name = (char __user *) regs->regs[base+5];
+ char __user *buf = (char __user *) regs->regs[base+6];
char *value;
return -EINVAL; /* til I fix it */
- if (!access_ok(VERIFY_WRITE, buf, 128)) {
- retval = -EFAULT;
- break;
- }
value = prom_getenv(name); /* PROM lock? */
if (!value) {
retval = -EINVAL;
break;
}
/* Do I strlen() for the length? */
- copy_to_user(buf, value, 128);
- retval = 0;
+ retval = copy_to_user(buf, value, 128) ? -EFAULT : 0;
break;
}
case SGI_SETNVRAM: {
- char *name = (char *) regs->regs[base+5];
- char *value = (char *) regs->regs[base+6];
+ char __user *name = (char __user *) regs->regs[base+5];
+ char __user *value = (char __user *) regs->regs[base+6];
return -EINVAL; /* til I fix it */
retval = prom_setenv(name, value);
/* XXX make sure retval conforms to syssgi(2) */
@@ -407,16 +391,16 @@ asmlinkage int irix_syssgi(struct pt_regs *regs)
case SGI_SETGROUPS:
retval = sys_setgroups((int) regs->regs[base + 5],
- (gid_t *) regs->regs[base + 6]);
+ (gid_t __user *) regs->regs[base + 6]);
break;
case SGI_GETGROUPS:
retval = sys_getgroups((int) regs->regs[base + 5],
- (gid_t *) regs->regs[base + 6]);
+ (gid_t __user *) regs->regs[base + 6]);
break;
case SGI_RUSAGE: {
- struct rusage *ru = (struct rusage *) regs->regs[base + 6];
+ struct rusage __user *ru = (struct rusage __user *) regs->regs[base + 6];
switch((int) regs->regs[base + 5]) {
case 0:
@@ -453,7 +437,7 @@ asmlinkage int irix_syssgi(struct pt_regs *regs)
case SGI_ELFMAP:
retval = irix_mapelf((int) regs->regs[base + 5],
- (struct elf_phdr *) regs->regs[base + 6],
+ (struct elf_phdr __user *) regs->regs[base + 6],
(int) regs->regs[base + 7]);
break;
@@ -468,24 +452,24 @@ asmlinkage int irix_syssgi(struct pt_regs *regs)
case SGI_PHYSP: {
unsigned long addr = regs->regs[base + 5];
- int *pageno = (int *) (regs->regs[base + 6]);
+ int __user *pageno = (int __user *) (regs->regs[base + 6]);
struct mm_struct *mm = current->mm;
pgd_t *pgdp;
+ pud_t *pudp;
pmd_t *pmdp;
pte_t *ptep;
- if (!access_ok(VERIFY_WRITE, pageno, sizeof(int)))
- return -EFAULT;
-
down_read(&mm->mmap_sem);
pgdp = pgd_offset(mm, addr);
- pmdp = pmd_offset(pgdp, addr);
+ pudp = pud_offset(pgdp, addr);
+ pmdp = pmd_offset(pudp, addr);
ptep = pte_offset(pmdp, addr);
retval = -EINVAL;
if (ptep) {
pte_t pte = *ptep;
if (pte_val(pte) & (_PAGE_VALID | _PAGE_PRESENT)) {
+ /* b0rked on 64-bit */
retval = put_user((pte_val(pte) & PAGE_MASK) >>
PAGE_SHIFT, pageno);
}
@@ -496,7 +480,7 @@ asmlinkage int irix_syssgi(struct pt_regs *regs)
case SGI_INVENT: {
int arg1 = (int) regs->regs [base + 5];
- void *buffer = (void *) regs->regs [base + 6];
+ void __user *buffer = (void __user *) regs->regs [base + 6];
int count = (int) regs->regs [base + 7];
switch (arg1) {
@@ -692,8 +676,8 @@ asmlinkage int irix_pause(void)
}
/* XXX need more than this... */
-asmlinkage int irix_mount(char *dev_name, char *dir_name, unsigned long flags,
- char *type, void *data, int datalen)
+asmlinkage int irix_mount(char __user *dev_name, char __user *dir_name,
+ unsigned long flags, char __user *type, void __user *data, int datalen)
{
printk("[%s:%d] irix_mount(%p,%p,%08lx,%p,%p,%d)\n",
current->comm, current->pid,
@@ -708,8 +692,8 @@ struct irix_statfs {
char f_fname[6], f_fpack[6];
};
-asmlinkage int irix_statfs(const char *path, struct irix_statfs *buf,
- int len, int fs_type)
+asmlinkage int irix_statfs(const char __user *path,
+ struct irix_statfs __user *buf, int len, int fs_type)
{
struct nameidata nd;
struct kstatfs kbuf;
@@ -724,6 +708,7 @@ asmlinkage int irix_statfs(const char *path, struct irix_statfs *buf,
error = -EFAULT;
goto out;
}
+
error = user_path_walk(path, &nd);
if (error)
goto out;
@@ -732,18 +717,17 @@ asmlinkage int irix_statfs(const char *path, struct irix_statfs *buf,
if (error)
goto dput_and_out;
- __put_user(kbuf.f_type, &buf->f_type);
- __put_user(kbuf.f_bsize, &buf->f_bsize);
- __put_user(kbuf.f_frsize, &buf->f_frsize);
- __put_user(kbuf.f_blocks, &buf->f_blocks);
- __put_user(kbuf.f_bfree, &buf->f_bfree);
- __put_user(kbuf.f_files, &buf->f_files);
- __put_user(kbuf.f_ffree, &buf->f_ffree);
+ error = __put_user(kbuf.f_type, &buf->f_type);
+ error |= __put_user(kbuf.f_bsize, &buf->f_bsize);
+ error |= __put_user(kbuf.f_frsize, &buf->f_frsize);
+ error |= __put_user(kbuf.f_blocks, &buf->f_blocks);
+ error |= __put_user(kbuf.f_bfree, &buf->f_bfree);
+ error |= __put_user(kbuf.f_files, &buf->f_files);
+ error |= __put_user(kbuf.f_ffree, &buf->f_ffree);
for (i = 0; i < 6; i++) {
- __put_user(0, &buf->f_fname[i]);
- __put_user(0, &buf->f_fpack[i]);
+ error |= __put_user(0, &buf->f_fname[i]);
+ error |= __put_user(0, &buf->f_fpack[i]);
}
- error = 0;
dput_and_out:
path_release(&nd);
@@ -751,7 +735,7 @@ out:
return error;
}
-asmlinkage int irix_fstatfs(unsigned int fd, struct irix_statfs *buf)
+asmlinkage int irix_fstatfs(unsigned int fd, struct irix_statfs __user *buf)
{
struct kstatfs kbuf;
struct file *file;
@@ -761,6 +745,7 @@ asmlinkage int irix_fstatfs(unsigned int fd, struct irix_statfs *buf)
error = -EFAULT;
goto out;
}
+
if (!(file = fget(fd))) {
error = -EBADF;
goto out;
@@ -770,16 +755,17 @@ asmlinkage int irix_fstatfs(unsigned int fd, struct irix_statfs *buf)
if (error)
goto out_f;
- __put_user(kbuf.f_type, &buf->f_type);
- __put_user(kbuf.f_bsize, &buf->f_bsize);
- __put_user(kbuf.f_frsize, &buf->f_frsize);
- __put_user(kbuf.f_blocks, &buf->f_blocks);
- __put_user(kbuf.f_bfree, &buf->f_bfree);
- __put_user(kbuf.f_files, &buf->f_files);
- __put_user(kbuf.f_ffree, &buf->f_ffree);
- for(i = 0; i < 6; i++) {
- __put_user(0, &buf->f_fname[i]);
- __put_user(0, &buf->f_fpack[i]);
+ error = __put_user(kbuf.f_type, &buf->f_type);
+ error |= __put_user(kbuf.f_bsize, &buf->f_bsize);
+ error |= __put_user(kbuf.f_frsize, &buf->f_frsize);
+ error |= __put_user(kbuf.f_blocks, &buf->f_blocks);
+ error |= __put_user(kbuf.f_bfree, &buf->f_bfree);
+ error |= __put_user(kbuf.f_files, &buf->f_files);
+ error |= __put_user(kbuf.f_ffree, &buf->f_ffree);
+
+ for (i = 0; i < 6; i++) {
+ error |= __put_user(0, &buf->f_fname[i]);
+ error |= __put_user(0, &buf->f_fpack[i]);
}
out_f:
@@ -806,14 +792,15 @@ asmlinkage int irix_setpgrp(int flags)
return error;
}
-asmlinkage int irix_times(struct tms * tbuf)
+asmlinkage int irix_times(struct tms __user *tbuf)
{
int err = 0;
if (tbuf) {
if (!access_ok(VERIFY_WRITE,tbuf,sizeof *tbuf))
return -EFAULT;
- err |= __put_user(current->utime, &tbuf->tms_utime);
+
+ err = __put_user(current->utime, &tbuf->tms_utime);
err |= __put_user(current->stime, &tbuf->tms_stime);
err |= __put_user(current->signal->cutime, &tbuf->tms_cutime);
err |= __put_user(current->signal->cstime, &tbuf->tms_cstime);
@@ -829,13 +816,13 @@ asmlinkage int irix_exec(struct pt_regs *regs)
if(regs->regs[2] == 1000)
base = 1;
- filename = getname((char *) (long)regs->regs[base + 4]);
+ filename = getname((char __user *) (long)regs->regs[base + 4]);
error = PTR_ERR(filename);
if (IS_ERR(filename))
return error;
- error = do_execve(filename, (char **) (long)regs->regs[base + 5],
- (char **) 0, regs);
+ error = do_execve(filename, (char __user * __user *) (long)regs->regs[base + 5],
+ NULL, regs);
putname(filename);
return error;
@@ -848,12 +835,12 @@ asmlinkage int irix_exece(struct pt_regs *regs)
if (regs->regs[2] == 1000)
base = 1;
- filename = getname((char *) (long)regs->regs[base + 4]);
+ filename = getname((char __user *) (long)regs->regs[base + 4]);
error = PTR_ERR(filename);
if (IS_ERR(filename))
return error;
- error = do_execve(filename, (char **) (long)regs->regs[base + 5],
- (char **) (long)regs->regs[base + 6], regs);
+ error = do_execve(filename, (char __user * __user *) (long)regs->regs[base + 5],
+ (char __user * __user *) (long)regs->regs[base + 6], regs);
putname(filename);
return error;
@@ -909,22 +896,17 @@ asmlinkage int irix_socket(int family, int type, int protocol)
return sys_socket(family, type, protocol);
}
-asmlinkage int irix_getdomainname(char *name, int len)
+asmlinkage int irix_getdomainname(char __user *name, int len)
{
- int error;
-
- if (!access_ok(VERIFY_WRITE, name, len))
- return -EFAULT;
+ int err;
down_read(&uts_sem);
if (len > __NEW_UTS_LEN)
len = __NEW_UTS_LEN;
- error = 0;
- if (copy_to_user(name, system_utsname.domainname, len))
- error = -EFAULT;
+ err = copy_to_user(name, system_utsname.domainname, len) ? -EFAULT : 0;
up_read(&uts_sem);
- return error;
+ return err;
}
asmlinkage unsigned long irix_getpagesize(void)
@@ -940,12 +922,13 @@ asmlinkage int irix_msgsys(int opcode, unsigned long arg0, unsigned long arg1,
case 0:
return sys_msgget((key_t) arg0, (int) arg1);
case 1:
- return sys_msgctl((int) arg0, (int) arg1, (struct msqid_ds *)arg2);
+ return sys_msgctl((int) arg0, (int) arg1,
+ (struct msqid_ds __user *)arg2);
case 2:
- return sys_msgrcv((int) arg0, (struct msgbuf *) arg1,
+ return sys_msgrcv((int) arg0, (struct msgbuf __user *) arg1,
(size_t) arg2, (long) arg3, (int) arg4);
case 3:
- return sys_msgsnd((int) arg0, (struct msgbuf *) arg1,
+ return sys_msgsnd((int) arg0, (struct msgbuf __user *) arg1,
(size_t) arg2, (int) arg3);
default:
return -EINVAL;
@@ -957,12 +940,13 @@ asmlinkage int irix_shmsys(int opcode, unsigned long arg0, unsigned long arg1,
{
switch (opcode) {
case 0:
- return do_shmat((int) arg0, (char *)arg1, (int) arg2,
+ return do_shmat((int) arg0, (char __user *) arg1, (int) arg2,
(unsigned long *) arg3);
case 1:
- return sys_shmctl((int)arg0, (int)arg1, (struct shmid_ds *)arg2);
+ return sys_shmctl((int)arg0, (int)arg1,
+ (struct shmid_ds __user *)arg2);
case 2:
- return sys_shmdt((char *)arg0);
+ return sys_shmdt((char __user *)arg0);
case 3:
return sys_shmget((key_t) arg0, (int) arg1, (int) arg2);
default:
@@ -980,7 +964,7 @@ asmlinkage int irix_semsys(int opcode, unsigned long arg0, unsigned long arg1,
case 1:
return sys_semget((key_t) arg0, (int) arg1, (int) arg2);
case 2:
- return sys_semop((int) arg0, (struct sembuf *)arg1,
+ return sys_semop((int) arg0, (struct sembuf __user *)arg1,
(unsigned int) arg2);
default:
return -EINVAL;
@@ -998,15 +982,16 @@ static inline loff_t llseek(struct file *file, loff_t offset, int origin)
lock_kernel();
retval = fn(file, offset, origin);
unlock_kernel();
+
return retval;
}
asmlinkage int irix_lseek64(int fd, int _unused, int offhi, int offlow,
int origin)
{
- int retval;
struct file * file;
loff_t offset;
+ int retval;
retval = -EBADF;
file = fget(fd);
@@ -1031,12 +1016,12 @@ asmlinkage int irix_sginap(int ticks)
return 0;
}
-asmlinkage int irix_sgikopt(char *istring, char *ostring, int len)
+asmlinkage int irix_sgikopt(char __user *istring, char __user *ostring, int len)
{
return -EINVAL;
}
-asmlinkage int irix_gettimeofday(struct timeval *tv)
+asmlinkage int irix_gettimeofday(struct timeval __user *tv)
{
time_t sec;
long nsec, seq;
@@ -1077,7 +1062,7 @@ asmlinkage unsigned long irix_mmap32(unsigned long addr, size_t len, int prot,
if (max_size > file->f_dentry->d_inode->i_size) {
old_pos = sys_lseek (fd, max_size - 1, 0);
- sys_write (fd, "", 1);
+ sys_write (fd, (void __user *) "", 1);
sys_lseek (fd, old_pos, 0);
}
}
@@ -1102,7 +1087,7 @@ asmlinkage int irix_madvise(unsigned long addr, int len, int behavior)
return -EINVAL;
}
-asmlinkage int irix_pagelock(char *addr, int len, int op)
+asmlinkage int irix_pagelock(char __user *addr, int len, int op)
{
printk("[%s:%d] Wheee.. irix_pagelock(%p,%d,%d)\n",
current->comm, current->pid, addr, len, op);
@@ -1142,7 +1127,7 @@ asmlinkage int irix_BSDsetpgrp(int pid, int pgrp)
return error;
}
-asmlinkage int irix_systeminfo(int cmd, char *buf, int cnt)
+asmlinkage int irix_systeminfo(int cmd, char __user *buf, int cnt)
{
printk("[%s:%d] Wheee.. irix_systeminfo(%d,%p,%d)\n",
current->comm, current->pid, cmd, buf, cnt);
@@ -1158,14 +1143,14 @@ struct iuname {
char _unused3[257], _unused4[257], _unused5[257];
};
-asmlinkage int irix_uname(struct iuname *buf)
+asmlinkage int irix_uname(struct iuname __user *buf)
{
down_read(&uts_sem);
- if (copy_to_user(system_utsname.sysname, buf->sysname, 65)
- || copy_to_user(system_utsname.nodename, buf->nodename, 65)
- || copy_to_user(system_utsname.release, buf->release, 65)
- || copy_to_user(system_utsname.version, buf->version, 65)
- || copy_to_user(system_utsname.machine, buf->machine, 65)) {
+ if (copy_from_user(system_utsname.sysname, buf->sysname, 65)
+ || copy_from_user(system_utsname.nodename, buf->nodename, 65)
+ || copy_from_user(system_utsname.release, buf->release, 65)
+ || copy_from_user(system_utsname.version, buf->version, 65)
+ || copy_from_user(system_utsname.machine, buf->machine, 65)) {
return -EFAULT;
}
up_read(&uts_sem);
@@ -1175,7 +1160,7 @@ asmlinkage int irix_uname(struct iuname *buf)
#undef DEBUG_XSTAT
-static int irix_xstat32_xlate(struct kstat *stat, void *ubuf)
+static int irix_xstat32_xlate(struct kstat *stat, void __user *ubuf)
{
struct xstat32 {
u32 st_dev, st_pad1[3], st_ino, st_mode, st_nlink, st_uid, st_gid;
@@ -1215,7 +1200,7 @@ static int irix_xstat32_xlate(struct kstat *stat, void *ubuf)
return copy_to_user(ubuf, &ub, sizeof(ub)) ? -EFAULT : 0;
}
-static int irix_xstat64_xlate(struct kstat *stat, void *ubuf)
+static int irix_xstat64_xlate(struct kstat *stat, void __user *ubuf)
{
struct xstat64 {
u32 st_dev; s32 st_pad1[3];
@@ -1265,7 +1250,7 @@ static int irix_xstat64_xlate(struct kstat *stat, void *ubuf)
return copy_to_user(ubuf, &ks, sizeof(ks)) ? -EFAULT : 0;
}
-asmlinkage int irix_xstat(int version, char *filename, struct stat *statbuf)
+asmlinkage int irix_xstat(int version, char __user *filename, struct stat __user *statbuf)
{
int retval;
struct kstat stat;
@@ -1291,7 +1276,7 @@ asmlinkage int irix_xstat(int version, char *filename, struct stat *statbuf)
return retval;
}
-asmlinkage int irix_lxstat(int version, char *filename, struct stat *statbuf)
+asmlinkage int irix_lxstat(int version, char __user *filename, struct stat __user *statbuf)
{
int error;
struct kstat stat;
@@ -1318,7 +1303,7 @@ asmlinkage int irix_lxstat(int version, char *filename, struct stat *statbuf)
return error;
}
-asmlinkage int irix_fxstat(int version, int fd, struct stat *statbuf)
+asmlinkage int irix_fxstat(int version, int fd, struct stat __user *statbuf)
{
int error;
struct kstat stat;
@@ -1344,7 +1329,7 @@ asmlinkage int irix_fxstat(int version, int fd, struct stat *statbuf)
return error;
}
-asmlinkage int irix_xmknod(int ver, char *filename, int mode, unsigned dev)
+asmlinkage int irix_xmknod(int ver, char __user *filename, int mode, unsigned dev)
{
int retval;
printk("[%s:%d] Wheee.. irix_xmknod(%d,%s,%x,%x)\n",
@@ -1364,7 +1349,7 @@ asmlinkage int irix_xmknod(int ver, char *filename, int mode, unsigned dev)
return retval;
}
-asmlinkage int irix_swapctl(int cmd, char *arg)
+asmlinkage int irix_swapctl(int cmd, char __user *arg)
{
printk("[%s:%d] Wheee.. irix_swapctl(%d,%p)\n",
current->comm, current->pid, cmd, arg);
@@ -1380,7 +1365,7 @@ struct irix_statvfs {
char f_fstr[32]; u32 f_filler[16];
};
-asmlinkage int irix_statvfs(char *fname, struct irix_statvfs *buf)
+asmlinkage int irix_statvfs(char __user *fname, struct irix_statvfs __user *buf)
{
struct nameidata nd;
struct kstatfs kbuf;
@@ -1388,10 +1373,9 @@ asmlinkage int irix_statvfs(char *fname, struct irix_statvfs *buf)
printk("[%s:%d] Wheee.. irix_statvfs(%s,%p)\n",
current->comm, current->pid, fname, buf);
- if (!access_ok(VERIFY_WRITE, buf, sizeof(struct irix_statvfs))) {
- error = -EFAULT;
- goto out;
- }
+ if (!access_ok(VERIFY_WRITE, buf, sizeof(struct irix_statvfs)))
+ return -EFAULT;
+
error = user_path_walk(fname, &nd);
if (error)
goto out;
@@ -1399,27 +1383,25 @@ asmlinkage int irix_statvfs(char *fname, struct irix_statvfs *buf)
if (error)
goto dput_and_out;
- __put_user(kbuf.f_bsize, &buf->f_bsize);
- __put_user(kbuf.f_frsize, &buf->f_frsize);
- __put_user(kbuf.f_blocks, &buf->f_blocks);
- __put_user(kbuf.f_bfree, &buf->f_bfree);
- __put_user(kbuf.f_bfree, &buf->f_bavail); /* XXX hackety hack... */
- __put_user(kbuf.f_files, &buf->f_files);
- __put_user(kbuf.f_ffree, &buf->f_ffree);
- __put_user(kbuf.f_ffree, &buf->f_favail); /* XXX hackety hack... */
+ error |= __put_user(kbuf.f_bsize, &buf->f_bsize);
+ error |= __put_user(kbuf.f_frsize, &buf->f_frsize);
+ error |= __put_user(kbuf.f_blocks, &buf->f_blocks);
+ error |= __put_user(kbuf.f_bfree, &buf->f_bfree);
+ error |= __put_user(kbuf.f_bfree, &buf->f_bavail); /* XXX hackety hack... */
+ error |= __put_user(kbuf.f_files, &buf->f_files);
+ error |= __put_user(kbuf.f_ffree, &buf->f_ffree);
+ error |= __put_user(kbuf.f_ffree, &buf->f_favail); /* XXX hackety hack... */
#ifdef __MIPSEB__
- __put_user(kbuf.f_fsid.val[1], &buf->f_fsid);
+ error |= __put_user(kbuf.f_fsid.val[1], &buf->f_fsid);
#else
- __put_user(kbuf.f_fsid.val[0], &buf->f_fsid);
+ error |= __put_user(kbuf.f_fsid.val[0], &buf->f_fsid);
#endif
for (i = 0; i < 16; i++)
- __put_user(0, &buf->f_basetype[i]);
- __put_user(0, &buf->f_flag);
- __put_user(kbuf.f_namelen, &buf->f_namemax);
+ error |= __put_user(0, &buf->f_basetype[i]);
+ error |= __put_user(0, &buf->f_flag);
+ error |= __put_user(kbuf.f_namelen, &buf->f_namemax);
for (i = 0; i < 32; i++)
- __put_user(0, &buf->f_fstr[i]);
-
- error = 0;
+ error |= __put_user(0, &buf->f_fstr[i]);
dput_and_out:
path_release(&nd);
@@ -1427,7 +1409,7 @@ out:
return error;
}
-asmlinkage int irix_fstatvfs(int fd, struct irix_statvfs *buf)
+asmlinkage int irix_fstatvfs(int fd, struct irix_statvfs __user *buf)
{
struct kstatfs kbuf;
struct file *file;
@@ -1436,10 +1418,9 @@ asmlinkage int irix_fstatvfs(int fd, struct irix_statvfs *buf)
printk("[%s:%d] Wheee.. irix_fstatvfs(%d,%p)\n",
current->comm, current->pid, fd, buf);
- if (!access_ok(VERIFY_WRITE, buf, sizeof(struct irix_statvfs))) {
- error = -EFAULT;
- goto out;
- }
+ if (!access_ok(VERIFY_WRITE, buf, sizeof(struct irix_statvfs)))
+ return -EFAULT;
+
if (!(file = fget(fd))) {
error = -EBADF;
goto out;
@@ -1448,24 +1429,24 @@ asmlinkage int irix_fstatvfs(int fd, struct irix_statvfs *buf)
if (error)
goto out_f;
- __put_user(kbuf.f_bsize, &buf->f_bsize);
- __put_user(kbuf.f_frsize, &buf->f_frsize);
- __put_user(kbuf.f_blocks, &buf->f_blocks);
- __put_user(kbuf.f_bfree, &buf->f_bfree);
- __put_user(kbuf.f_bfree, &buf->f_bavail); /* XXX hackety hack... */
- __put_user(kbuf.f_files, &buf->f_files);
- __put_user(kbuf.f_ffree, &buf->f_ffree);
- __put_user(kbuf.f_ffree, &buf->f_favail); /* XXX hackety hack... */
+ error = __put_user(kbuf.f_bsize, &buf->f_bsize);
+ error |= __put_user(kbuf.f_frsize, &buf->f_frsize);
+ error |= __put_user(kbuf.f_blocks, &buf->f_blocks);
+ error |= __put_user(kbuf.f_bfree, &buf->f_bfree);
+ error |= __put_user(kbuf.f_bfree, &buf->f_bavail); /* XXX hackety hack... */
+ error |= __put_user(kbuf.f_files, &buf->f_files);
+ error |= __put_user(kbuf.f_ffree, &buf->f_ffree);
+ error |= __put_user(kbuf.f_ffree, &buf->f_favail); /* XXX hackety hack... */
#ifdef __MIPSEB__
- __put_user(kbuf.f_fsid.val[1], &buf->f_fsid);
+ error |= __put_user(kbuf.f_fsid.val[1], &buf->f_fsid);
#else
- __put_user(kbuf.f_fsid.val[0], &buf->f_fsid);
+ error |= __put_user(kbuf.f_fsid.val[0], &buf->f_fsid);
#endif
for(i = 0; i < 16; i++)
- __put_user(0, &buf->f_basetype[i]);
- __put_user(0, &buf->f_flag);
- __put_user(kbuf.f_namelen, &buf->f_namemax);
- __clear_user(&buf->f_fstr, sizeof(buf->f_fstr));
+ error |= __put_user(0, &buf->f_basetype[i]);
+ error |= __put_user(0, &buf->f_flag);
+ error |= __put_user(kbuf.f_namelen, &buf->f_namemax);
+ error |= __clear_user(&buf->f_fstr, sizeof(buf->f_fstr)) ? -EFAULT : 0;
out_f:
fput(file);
@@ -1489,7 +1470,7 @@ asmlinkage int irix_sigqueue(int pid, int sig, int code, int val)
return -EINVAL;
}
-asmlinkage int irix_truncate64(char *name, int pad, int size1, int size2)
+asmlinkage int irix_truncate64(char __user *name, int pad, int size1, int size2)
{
int retval;
@@ -1522,6 +1503,7 @@ asmlinkage int irix_mmap64(struct pt_regs *regs)
int len, prot, flags, fd, off1, off2, error, base = 0;
unsigned long addr, pgoff, *sp;
struct file *file = NULL;
+ int err;
if (regs->regs[2] == 1000)
base = 1;
@@ -1531,36 +1513,31 @@ asmlinkage int irix_mmap64(struct pt_regs *regs)
prot = regs->regs[base + 6];
if (!base) {
flags = regs->regs[base + 7];
- if (!access_ok(VERIFY_READ, sp, (4 * sizeof(unsigned long)))) {
- error = -EFAULT;
- goto out;
- }
+ if (!access_ok(VERIFY_READ, sp, (4 * sizeof(unsigned long))))
+ return -EFAULT;
fd = sp[0];
- __get_user(off1, &sp[1]);
- __get_user(off2, &sp[2]);
+ err = __get_user(off1, &sp[1]);
+ err |= __get_user(off2, &sp[2]);
} else {
- if (!access_ok(VERIFY_READ, sp, (5 * sizeof(unsigned long)))) {
- error = -EFAULT;
- goto out;
- }
- __get_user(flags, &sp[0]);
- __get_user(fd, &sp[1]);
- __get_user(off1, &sp[2]);
- __get_user(off2, &sp[3]);
+ if (!access_ok(VERIFY_READ, sp, (5 * sizeof(unsigned long))))
+ return -EFAULT;
+ err = __get_user(flags, &sp[0]);
+ err |= __get_user(fd, &sp[1]);
+ err |= __get_user(off1, &sp[2]);
+ err |= __get_user(off2, &sp[3]);
}
- if (off1 & PAGE_MASK) {
- error = -EOVERFLOW;
- goto out;
- }
+ if (err)
+ return err;
+
+ if (off1 & PAGE_MASK)
+ return -EOVERFLOW;
pgoff = (off1 << (32 - PAGE_SHIFT)) | (off2 >> PAGE_SHIFT);
if (!(flags & MAP_ANONYMOUS)) {
- if (!(file = fget(fd))) {
- error = -EBADF;
- goto out;
- }
+ if (!(file = fget(fd)))
+ return -EBADF;
/* Ok, bad taste hack follows, try to think in something else
when reading this */
@@ -1570,7 +1547,7 @@ asmlinkage int irix_mmap64(struct pt_regs *regs)
if (max_size > file->f_dentry->d_inode->i_size) {
old_pos = sys_lseek (fd, max_size - 1, 0);
- sys_write (fd, "", 1);
+ sys_write (fd, (void __user *) "", 1);
sys_lseek (fd, old_pos, 0);
}
}
@@ -1585,7 +1562,6 @@ asmlinkage int irix_mmap64(struct pt_regs *regs)
if (file)
fput(file);
-out:
return error;
}
@@ -1597,7 +1573,7 @@ asmlinkage int irix_dmi(struct pt_regs *regs)
return -EINVAL;
}
-asmlinkage int irix_pread(int fd, char *buf, int cnt, int off64,
+asmlinkage int irix_pread(int fd, char __user *buf, int cnt, int off64,
int off1, int off2)
{
printk("[%s:%d] Wheee.. irix_pread(%d,%p,%d,%d,%d,%d)\n",
@@ -1606,7 +1582,7 @@ asmlinkage int irix_pread(int fd, char *buf, int cnt, int off64,
return -EINVAL;
}
-asmlinkage int irix_pwrite(int fd, char *buf, int cnt, int off64,
+asmlinkage int irix_pwrite(int fd, char __user *buf, int cnt, int off64,
int off1, int off2)
{
printk("[%s:%d] Wheee.. irix_pwrite(%d,%p,%d,%d,%d,%d)\n",
@@ -1638,7 +1614,7 @@ struct irix_statvfs64 {
u32 f_filler[16];
};
-asmlinkage int irix_statvfs64(char *fname, struct irix_statvfs64 *buf)
+asmlinkage int irix_statvfs64(char __user *fname, struct irix_statvfs64 __user *buf)
{
struct nameidata nd;
struct kstatfs kbuf;
@@ -1650,6 +1626,7 @@ asmlinkage int irix_statvfs64(char *fname, struct irix_statvfs64 *buf)
error = -EFAULT;
goto out;
}
+
error = user_path_walk(fname, &nd);
if (error)
goto out;
@@ -1657,27 +1634,25 @@ asmlinkage int irix_statvfs64(char *fname, struct irix_statvfs64 *buf)
if (error)
goto dput_and_out;
- __put_user(kbuf.f_bsize, &buf->f_bsize);
- __put_user(kbuf.f_frsize, &buf->f_frsize);
- __put_user(kbuf.f_blocks, &buf->f_blocks);
- __put_user(kbuf.f_bfree, &buf->f_bfree);
- __put_user(kbuf.f_bfree, &buf->f_bavail); /* XXX hackety hack... */
- __put_user(kbuf.f_files, &buf->f_files);
- __put_user(kbuf.f_ffree, &buf->f_ffree);
- __put_user(kbuf.f_ffree, &buf->f_favail); /* XXX hackety hack... */
+ error = __put_user(kbuf.f_bsize, &buf->f_bsize);
+ error |= __put_user(kbuf.f_frsize, &buf->f_frsize);
+ error |= __put_user(kbuf.f_blocks, &buf->f_blocks);
+ error |= __put_user(kbuf.f_bfree, &buf->f_bfree);
+ error |= __put_user(kbuf.f_bfree, &buf->f_bavail); /* XXX hackety hack... */
+ error |= __put_user(kbuf.f_files, &buf->f_files);
+ error |= __put_user(kbuf.f_ffree, &buf->f_ffree);
+ error |= __put_user(kbuf.f_ffree, &buf->f_favail); /* XXX hackety hack... */
#ifdef __MIPSEB__
- __put_user(kbuf.f_fsid.val[1], &buf->f_fsid);
+ error |= __put_user(kbuf.f_fsid.val[1], &buf->f_fsid);
#else
- __put_user(kbuf.f_fsid.val[0], &buf->f_fsid);
+ error |= __put_user(kbuf.f_fsid.val[0], &buf->f_fsid);
#endif
for(i = 0; i < 16; i++)
- __put_user(0, &buf->f_basetype[i]);
- __put_user(0, &buf->f_flag);
- __put_user(kbuf.f_namelen, &buf->f_namemax);
+ error |= __put_user(0, &buf->f_basetype[i]);
+ error |= __put_user(0, &buf->f_flag);
+ error |= __put_user(kbuf.f_namelen, &buf->f_namemax);
for(i = 0; i < 32; i++)
- __put_user(0, &buf->f_fstr[i]);
-
- error = 0;
+ error |= __put_user(0, &buf->f_fstr[i]);
dput_and_out:
path_release(&nd);
@@ -1685,7 +1660,7 @@ out:
return error;
}
-asmlinkage int irix_fstatvfs64(int fd, struct irix_statvfs *buf)
+asmlinkage int irix_fstatvfs64(int fd, struct irix_statvfs __user *buf)
{
struct kstatfs kbuf;
struct file *file;
@@ -1706,24 +1681,24 @@ asmlinkage int irix_fstatvfs64(int fd, struct irix_statvfs *buf)
if (error)
goto out_f;
- __put_user(kbuf.f_bsize, &buf->f_bsize);
- __put_user(kbuf.f_frsize, &buf->f_frsize);
- __put_user(kbuf.f_blocks, &buf->f_blocks);
- __put_user(kbuf.f_bfree, &buf->f_bfree);
- __put_user(kbuf.f_bfree, &buf->f_bavail); /* XXX hackety hack... */
- __put_user(kbuf.f_files, &buf->f_files);
- __put_user(kbuf.f_ffree, &buf->f_ffree);
- __put_user(kbuf.f_ffree, &buf->f_favail); /* XXX hackety hack... */
+ error = __put_user(kbuf.f_bsize, &buf->f_bsize);
+ error |= __put_user(kbuf.f_frsize, &buf->f_frsize);
+ error |= __put_user(kbuf.f_blocks, &buf->f_blocks);
+ error |= __put_user(kbuf.f_bfree, &buf->f_bfree);
+ error |= __put_user(kbuf.f_bfree, &buf->f_bavail); /* XXX hackety hack... */
+ error |= __put_user(kbuf.f_files, &buf->f_files);
+ error |= __put_user(kbuf.f_ffree, &buf->f_ffree);
+ error |= __put_user(kbuf.f_ffree, &buf->f_favail); /* XXX hackety hack... */
#ifdef __MIPSEB__
- __put_user(kbuf.f_fsid.val[1], &buf->f_fsid);
+ error |= __put_user(kbuf.f_fsid.val[1], &buf->f_fsid);
#else
- __put_user(kbuf.f_fsid.val[0], &buf->f_fsid);
+ error |= __put_user(kbuf.f_fsid.val[0], &buf->f_fsid);
#endif
for(i = 0; i < 16; i++)
- __put_user(0, &buf->f_basetype[i]);
- __put_user(0, &buf->f_flag);
- __put_user(kbuf.f_namelen, &buf->f_namemax);
- __clear_user(buf->f_fstr, sizeof(buf->f_fstr[i]));
+ error |= __put_user(0, &buf->f_basetype[i]);
+ error |= __put_user(0, &buf->f_flag);
+ error |= __put_user(kbuf.f_namelen, &buf->f_namemax);
+ error |= __clear_user(buf->f_fstr, sizeof(buf->f_fstr[i])) ? -EFAULT : 0;
out_f:
fput(file);
@@ -1731,9 +1706,9 @@ out:
return error;
}
-asmlinkage int irix_getmountid(char *fname, unsigned long *midbuf)
+asmlinkage int irix_getmountid(char __user *fname, unsigned long __user *midbuf)
{
- int err = 0;
+ int err;
printk("[%s:%d] irix_getmountid(%s, %p)\n",
current->comm, current->pid, fname, midbuf);
@@ -1746,7 +1721,7 @@ asmlinkage int irix_getmountid(char *fname, unsigned long *midbuf)
* fsid of the filesystem to try and make the right decision, but
* we don't have this so for now. XXX
*/
- err |= __put_user(0, &midbuf[0]);
+ err = __put_user(0, &midbuf[0]);
err |= __put_user(0, &midbuf[1]);
err |= __put_user(0, &midbuf[2]);
err |= __put_user(0, &midbuf[3]);
@@ -1773,8 +1748,8 @@ struct irix_dirent32 {
};
struct irix_dirent32_callback {
- struct irix_dirent32 *current_dir;
- struct irix_dirent32 *previous;
+ struct irix_dirent32 __user *current_dir;
+ struct irix_dirent32 __user *previous;
int count;
int error;
};
@@ -1782,13 +1757,13 @@ struct irix_dirent32_callback {
#define NAME_OFFSET32(de) ((int) ((de)->d_name - (char *) (de)))
#define ROUND_UP32(x) (((x)+sizeof(u32)-1) & ~(sizeof(u32)-1))
-static int irix_filldir32(void *__buf, const char *name, int namlen,
- loff_t offset, ino_t ino, unsigned int d_type)
+static int irix_filldir32(void *__buf, const char *name,
+ int namlen, loff_t offset, ino_t ino, unsigned int d_type)
{
- struct irix_dirent32 *dirent;
- struct irix_dirent32_callback *buf =
- (struct irix_dirent32_callback *)__buf;
+ struct irix_dirent32 __user *dirent;
+ struct irix_dirent32_callback *buf = __buf;
unsigned short reclen = ROUND_UP32(NAME_OFFSET32(dirent) + namlen + 1);
+ int err = 0;
#ifdef DEBUG_GETDENTS
printk("\nirix_filldir32[reclen<%d>namlen<%d>count<%d>]",
@@ -1799,25 +1774,26 @@ static int irix_filldir32(void *__buf, const char *name, int namlen,
return -EINVAL;
dirent = buf->previous;
if (dirent)
- __put_user(offset, &dirent->d_off);
+ err = __put_user(offset, &dirent->d_off);
dirent = buf->current_dir;
- buf->previous = dirent;
- __put_user(ino, &dirent->d_ino);
- __put_user(reclen, &dirent->d_reclen);
- copy_to_user(dirent->d_name, name, namlen);
- __put_user(0, &dirent->d_name[namlen]);
- ((char *) dirent) += reclen;
+ err |= __put_user(dirent, &buf->previous);
+ err |= __put_user(ino, &dirent->d_ino);
+ err |= __put_user(reclen, &dirent->d_reclen);
+ err |= copy_to_user((char __user *)dirent->d_name, name, namlen) ? -EFAULT : 0;
+ err |= __put_user(0, &dirent->d_name[namlen]);
+ dirent = (struct irix_dirent32 __user *) ((char __user *) dirent + reclen);
+
buf->current_dir = dirent;
buf->count -= reclen;
- return 0;
+ return err;
}
-asmlinkage int irix_ngetdents(unsigned int fd, void * dirent,
- unsigned int count, int *eob)
+asmlinkage int irix_ngetdents(unsigned int fd, void __user * dirent,
+ unsigned int count, int __user *eob)
{
struct file *file;
- struct irix_dirent32 *lastdirent;
+ struct irix_dirent32 __user *lastdirent;
struct irix_dirent32_callback buf;
int error;
@@ -1830,7 +1806,7 @@ asmlinkage int irix_ngetdents(unsigned int fd, void * dirent,
if (!file)
goto out;
- buf.current_dir = (struct irix_dirent32 *) dirent;
+ buf.current_dir = (struct irix_dirent32 __user *) dirent;
buf.previous = NULL;
buf.count = count;
buf.error = 0;
@@ -1870,8 +1846,8 @@ struct irix_dirent64 {
};
struct irix_dirent64_callback {
- struct irix_dirent64 *curr;
- struct irix_dirent64 *previous;
+ struct irix_dirent64 __user *curr;
+ struct irix_dirent64 __user *previous;
int count;
int error;
};
@@ -1879,37 +1855,44 @@ struct irix_dirent64_callback {
#define NAME_OFFSET64(de) ((int) ((de)->d_name - (char *) (de)))
#define ROUND_UP64(x) (((x)+sizeof(u64)-1) & ~(sizeof(u64)-1))
-static int irix_filldir64(void * __buf, const char * name, int namlen,
- loff_t offset, ino_t ino, unsigned int d_type)
+static int irix_filldir64(void *__buf, const char *name,
+ int namlen, loff_t offset, ino_t ino, unsigned int d_type)
{
- struct irix_dirent64 *dirent;
- struct irix_dirent64_callback * buf =
- (struct irix_dirent64_callback *) __buf;
+ struct irix_dirent64 __user *dirent;
+ struct irix_dirent64_callback * buf = __buf;
unsigned short reclen = ROUND_UP64(NAME_OFFSET64(dirent) + namlen + 1);
+ int err = 0;
- buf->error = -EINVAL; /* only used if we fail.. */
+ if (!access_ok(VERIFY_WRITE, buf, sizeof(*buf)))
+ return -EFAULT;
+
+ if (__put_user(-EINVAL, &buf->error)) /* only used if we fail.. */
+ return -EFAULT;
if (reclen > buf->count)
return -EINVAL;
dirent = buf->previous;
if (dirent)
- __put_user(offset, &dirent->d_off);
+ err = __put_user(offset, &dirent->d_off);
dirent = buf->curr;
buf->previous = dirent;
- __put_user(ino, &dirent->d_ino);
- __put_user(reclen, &dirent->d_reclen);
- __copy_to_user(dirent->d_name, name, namlen);
- __put_user(0, &dirent->d_name[namlen]);
- ((char *) dirent) += reclen;
+ err |= __put_user(ino, &dirent->d_ino);
+ err |= __put_user(reclen, &dirent->d_reclen);
+ err |= __copy_to_user((char __user *)dirent->d_name, name, namlen)
+ ? -EFAULT : 0;
+ err |= __put_user(0, &dirent->d_name[namlen]);
+
+ dirent = (struct irix_dirent64 __user *) ((char __user *) dirent + reclen);
+
buf->curr = dirent;
buf->count -= reclen;
- return 0;
+ return err;
}
-asmlinkage int irix_getdents64(int fd, void *dirent, int cnt)
+asmlinkage int irix_getdents64(int fd, void __user *dirent, int cnt)
{
struct file *file;
- struct irix_dirent64 *lastdirent;
+ struct irix_dirent64 __user *lastdirent;
struct irix_dirent64_callback buf;
int error;
@@ -1929,7 +1912,7 @@ asmlinkage int irix_getdents64(int fd, void *dirent, int cnt)
if (cnt < (sizeof(struct irix_dirent64) + 255))
goto out_f;
- buf.curr = (struct irix_dirent64 *) dirent;
+ buf.curr = (struct irix_dirent64 __user *) dirent;
buf.previous = NULL;
buf.count = cnt;
buf.error = 0;
@@ -1941,7 +1924,8 @@ asmlinkage int irix_getdents64(int fd, void *dirent, int cnt)
error = buf.error;
goto out_f;
}
- lastdirent->d_off = (u64) file->f_pos;
+ if (put_user(file->f_pos, &lastdirent->d_off))
+ return -EFAULT;
#ifdef DEBUG_GETDENTS
printk("returning %d\n", cnt - buf.count);
#endif
@@ -1953,10 +1937,10 @@ out:
return error;
}
-asmlinkage int irix_ngetdents64(int fd, void *dirent, int cnt, int *eob)
+asmlinkage int irix_ngetdents64(int fd, void __user *dirent, int cnt, int *eob)
{
struct file *file;
- struct irix_dirent64 *lastdirent;
+ struct irix_dirent64 __user *lastdirent;
struct irix_dirent64_callback buf;
int error;
@@ -1978,7 +1962,7 @@ asmlinkage int irix_ngetdents64(int fd, void *dirent, int cnt, int *eob)
goto out_f;
*eob = 0;
- buf.curr = (struct irix_dirent64 *) dirent;
+ buf.curr = (struct irix_dirent64 __user *) dirent;
buf.previous = NULL;
buf.count = cnt;
buf.error = 0;
@@ -1990,7 +1974,8 @@ asmlinkage int irix_ngetdents64(int fd, void *dirent, int cnt, int *eob)
error = buf.error;
goto out_f;
}
- lastdirent->d_off = (u64) file->f_pos;
+ if (put_user(file->f_pos, &lastdirent->d_off))
+ return -EFAULT;
#ifdef DEBUG_GETDENTS
printk("eob=%d returning %d\n", *eob, cnt - buf.count);
#endif
@@ -2053,14 +2038,14 @@ out:
return retval;
}
-asmlinkage int irix_utssys(char *inbuf, int arg, int type, char *outbuf)
+asmlinkage int irix_utssys(char __user *inbuf, int arg, int type, char __user *outbuf)
{
int retval;
switch(type) {
case 0:
/* uname() */
- retval = irix_uname((struct iuname *)inbuf);
+ retval = irix_uname((struct iuname __user *)inbuf);
goto out;
case 2:
diff --git a/arch/mips/kernel/time.c b/arch/mips/kernel/time.c
index 0dd0df7a3b04..787ed541d442 100644
--- a/arch/mips/kernel/time.c
+++ b/arch/mips/kernel/time.c
@@ -11,6 +11,7 @@
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*/
+#include <linux/config.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/init.h>
@@ -25,6 +26,7 @@
#include <linux/module.h>
#include <asm/bootinfo.h>
+#include <asm/cache.h>
#include <asm/compiler.h>
#include <asm/cpu.h>
#include <asm/cpu-features.h>
@@ -43,10 +45,6 @@
#define TICK_SIZE (tick_nsec / 1000)
-u64 jiffies_64 = INITIAL_JIFFIES;
-
-EXPORT_SYMBOL(jiffies_64);
-
/*
* forward reference
*/
@@ -76,7 +74,7 @@ int (*rtc_set_mmss)(unsigned long);
static unsigned int sll32_usecs_per_cycle;
/* how many counter cycles in a jiffy */
-static unsigned long cycles_per_jiffy;
+static unsigned long cycles_per_jiffy __read_mostly;
/* Cycle counter value at the previous timer interrupt.. */
static unsigned int timerhi, timerlo;
@@ -98,7 +96,10 @@ static unsigned int null_hpt_read(void)
return 0;
}
-static void null_hpt_init(unsigned int count) { /* nothing */ }
+static void null_hpt_init(unsigned int count)
+{
+ /* nothing */
+}
/*
@@ -108,8 +109,10 @@ static void c0_timer_ack(void)
{
unsigned int count;
+#ifndef CONFIG_SOC_PNX8550 /* pnx8550 resets to zero */
/* Ack this timer interrupt and set the next one. */
expirelo += cycles_per_jiffy;
+#endif
write_c0_compare(expirelo);
/* Check to see if we have missed any timer interrupts. */
@@ -224,7 +227,6 @@ int do_settimeofday(struct timespec *tv)
set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec);
ntp_clear();
-
write_sequnlock_irq(&xtime_lock);
clock_was_set();
return 0;
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index a53b1ed7b386..6f3ff9690686 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -9,7 +9,7 @@
* Copyright (C) 1999 Silicon Graphics, Inc.
* Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
* Copyright (C) 2000, 01 MIPS Technologies, Inc.
- * Copyright (C) 2002, 2003, 2004 Maciej W. Rozycki
+ * Copyright (C) 2002, 2003, 2004, 2005 Maciej W. Rozycki
*/
#include <linux/config.h>
#include <linux/init.h>
@@ -20,12 +20,16 @@
#include <linux/smp_lock.h>
#include <linux/spinlock.h>
#include <linux/kallsyms.h>
+#include <linux/bootmem.h>
#include <asm/bootinfo.h>
#include <asm/branch.h>
#include <asm/break.h>
#include <asm/cpu.h>
+#include <asm/dsp.h>
#include <asm/fpu.h>
+#include <asm/mipsregs.h>
+#include <asm/mipsmtregs.h>
#include <asm/module.h>
#include <asm/pgtable.h>
#include <asm/ptrace.h>
@@ -54,14 +58,19 @@ extern asmlinkage void handle_tr(void);
extern asmlinkage void handle_fpe(void);
extern asmlinkage void handle_mdmx(void);
extern asmlinkage void handle_watch(void);
+extern asmlinkage void handle_mt(void);
+extern asmlinkage void handle_dsp(void);
extern asmlinkage void handle_mcheck(void);
extern asmlinkage void handle_reserved(void);
-extern int fpu_emulator_cop1Handler(int xcptno, struct pt_regs *xcp,
+extern int fpu_emulator_cop1Handler(struct pt_regs *xcp,
struct mips_fpu_soft_struct *ctx);
void (*board_be_init)(void);
int (*board_be_handler)(struct pt_regs *regs, int is_fixup);
+void (*board_nmi_handler_setup)(void);
+void (*board_ejtag_handler_setup)(void);
+void (*board_bind_eic_interrupt)(int irq, int regset);
/*
* These constant is for searching for possible module text segments.
@@ -201,32 +210,47 @@ void show_regs(struct pt_regs *regs)
printk("Status: %08x ", (uint32_t) regs->cp0_status);
- if (regs->cp0_status & ST0_KX)
- printk("KX ");
- if (regs->cp0_status & ST0_SX)
- printk("SX ");
- if (regs->cp0_status & ST0_UX)
- printk("UX ");
- switch (regs->cp0_status & ST0_KSU) {
- case KSU_USER:
- printk("USER ");
- break;
- case KSU_SUPERVISOR:
- printk("SUPERVISOR ");
- break;
- case KSU_KERNEL:
- printk("KERNEL ");
- break;
- default:
- printk("BAD_MODE ");
- break;
+ if (current_cpu_data.isa_level == MIPS_CPU_ISA_I) {
+ if (regs->cp0_status & ST0_KUO)
+ printk("KUo ");
+ if (regs->cp0_status & ST0_IEO)
+ printk("IEo ");
+ if (regs->cp0_status & ST0_KUP)
+ printk("KUp ");
+ if (regs->cp0_status & ST0_IEP)
+ printk("IEp ");
+ if (regs->cp0_status & ST0_KUC)
+ printk("KUc ");
+ if (regs->cp0_status & ST0_IEC)
+ printk("IEc ");
+ } else {
+ if (regs->cp0_status & ST0_KX)
+ printk("KX ");
+ if (regs->cp0_status & ST0_SX)
+ printk("SX ");
+ if (regs->cp0_status & ST0_UX)
+ printk("UX ");
+ switch (regs->cp0_status & ST0_KSU) {
+ case KSU_USER:
+ printk("USER ");
+ break;
+ case KSU_SUPERVISOR:
+ printk("SUPERVISOR ");
+ break;
+ case KSU_KERNEL:
+ printk("KERNEL ");
+ break;
+ default:
+ printk("BAD_MODE ");
+ break;
+ }
+ if (regs->cp0_status & ST0_ERL)
+ printk("ERL ");
+ if (regs->cp0_status & ST0_EXL)
+ printk("EXL ");
+ if (regs->cp0_status & ST0_IE)
+ printk("IE ");
}
- if (regs->cp0_status & ST0_ERL)
- printk("ERL ");
- if (regs->cp0_status & ST0_EXL)
- printk("EXL ");
- if (regs->cp0_status & ST0_IE)
- printk("IE ");
printk("\n");
printk("Cause : %08x\n", cause);
@@ -252,29 +276,18 @@ void show_registers(struct pt_regs *regs)
static DEFINE_SPINLOCK(die_lock);
-NORET_TYPE void __die(const char * str, struct pt_regs * regs,
- const char * file, const char * func, unsigned long line)
+NORET_TYPE void ATTRIB_NORET die(const char * str, struct pt_regs * regs)
{
static int die_counter;
console_verbose();
spin_lock_irq(&die_lock);
- printk("%s", str);
- if (file && func)
- printk(" in %s:%s, line %ld", file, func, line);
- printk("[#%d]:\n", ++die_counter);
+ printk("%s[#%d]:\n", str, ++die_counter);
show_registers(regs);
spin_unlock_irq(&die_lock);
do_exit(SIGSEGV);
}
-void __die_if_kernel(const char * str, struct pt_regs * regs,
- const char * file, const char * func, unsigned long line)
-{
- if (!user_mode(regs))
- __die(str, regs, file, func, line);
-}
-
extern const struct exception_table_entry __start___dbe_table[];
extern const struct exception_table_entry __stop___dbe_table[];
@@ -339,9 +352,9 @@ asmlinkage void do_be(struct pt_regs *regs)
static inline int get_insn_opcode(struct pt_regs *regs, unsigned int *opcode)
{
- unsigned int *epc;
+ unsigned int __user *epc;
- epc = (unsigned int *) regs->cp0_epc +
+ epc = (unsigned int __user *) regs->cp0_epc +
((regs->cp0_cause & CAUSEF_BD) != 0);
if (!get_user(*opcode, epc))
return 0;
@@ -360,6 +373,10 @@ static inline int get_insn_opcode(struct pt_regs *regs, unsigned int *opcode)
#define OFFSET 0x0000ffff
#define LL 0xc0000000
#define SC 0xe0000000
+#define SPEC3 0x7c000000
+#define RD 0x0000f800
+#define FUNC 0x0000003f
+#define RDHWR 0x0000003b
/*
* The ll_bit is cleared by r*_switch.S
@@ -371,7 +388,7 @@ static struct task_struct *ll_task = NULL;
static inline void simulate_ll(struct pt_regs *regs, unsigned int opcode)
{
- unsigned long value, *vaddr;
+ unsigned long value, __user *vaddr;
long offset;
int signal = 0;
@@ -385,7 +402,8 @@ static inline void simulate_ll(struct pt_regs *regs, unsigned int opcode)
offset <<= 16;
offset >>= 16;
- vaddr = (unsigned long *)((long)(regs->regs[(opcode & BASE) >> 21]) + offset);
+ vaddr = (unsigned long __user *)
+ ((unsigned long)(regs->regs[(opcode & BASE) >> 21]) + offset);
if ((unsigned long)vaddr & 3) {
signal = SIGBUS;
@@ -407,9 +425,10 @@ static inline void simulate_ll(struct pt_regs *regs, unsigned int opcode)
preempt_enable();
+ compute_return_epc(regs);
+
regs->regs[(opcode & RT) >> 16] = value;
- compute_return_epc(regs);
return;
sig:
@@ -418,7 +437,8 @@ sig:
static inline void simulate_sc(struct pt_regs *regs, unsigned int opcode)
{
- unsigned long *vaddr, reg;
+ unsigned long __user *vaddr;
+ unsigned long reg;
long offset;
int signal = 0;
@@ -432,7 +452,8 @@ static inline void simulate_sc(struct pt_regs *regs, unsigned int opcode)
offset <<= 16;
offset >>= 16;
- vaddr = (unsigned long *)((long)(regs->regs[(opcode & BASE) >> 21]) + offset);
+ vaddr = (unsigned long __user *)
+ ((unsigned long)(regs->regs[(opcode & BASE) >> 21]) + offset);
reg = (opcode & RT) >> 16;
if ((unsigned long)vaddr & 3) {
@@ -443,9 +464,9 @@ static inline void simulate_sc(struct pt_regs *regs, unsigned int opcode)
preempt_disable();
if (ll_bit == 0 || ll_task != current) {
+ compute_return_epc(regs);
regs->regs[reg] = 0;
preempt_enable();
- compute_return_epc(regs);
return;
}
@@ -456,9 +477,9 @@ static inline void simulate_sc(struct pt_regs *regs, unsigned int opcode)
goto sig;
}
+ compute_return_epc(regs);
regs->regs[reg] = 1;
- compute_return_epc(regs);
return;
sig:
@@ -491,6 +512,37 @@ static inline int simulate_llsc(struct pt_regs *regs)
return -EFAULT; /* Strange things going on ... */
}
+/*
+ * Simulate trapping 'rdhwr' instructions to provide user accessible
+ * registers not implemented in hardware. The only current use of this
+ * is the thread area pointer.
+ */
+static inline int simulate_rdhwr(struct pt_regs *regs)
+{
+ struct thread_info *ti = current->thread_info;
+ unsigned int opcode;
+
+ if (unlikely(get_insn_opcode(regs, &opcode)))
+ return -EFAULT;
+
+ if (unlikely(compute_return_epc(regs)))
+ return -EFAULT;
+
+ if ((opcode & OPCODE) == SPEC3 && (opcode & FUNC) == RDHWR) {
+ int rd = (opcode & RD) >> 11;
+ int rt = (opcode & RT) >> 16;
+ switch (rd) {
+ case 29:
+ regs->regs[rt] = ti->tp_value;
+ break;
+ default:
+ return -EFAULT;
+ }
+ }
+
+ return 0;
+}
+
asmlinkage void do_ov(struct pt_regs *regs)
{
siginfo_t info;
@@ -498,7 +550,7 @@ asmlinkage void do_ov(struct pt_regs *regs)
info.si_code = FPE_INTOVF;
info.si_signo = SIGFPE;
info.si_errno = 0;
- info.si_addr = (void *)regs->cp0_epc;
+ info.si_addr = (void __user *) regs->cp0_epc;
force_sig_info(SIGFPE, &info, current);
}
@@ -512,6 +564,14 @@ asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31)
preempt_disable();
+#ifdef CONFIG_PREEMPT
+ if (!is_fpu_owner()) {
+ /* We might lose fpu before disabling preempt... */
+ own_fpu();
+ BUG_ON(!used_math());
+ restore_fp(current);
+ }
+#endif
/*
* Unimplemented operation exception. If we've got the full
* software emulator on-board, let's use it...
@@ -523,11 +583,18 @@ asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31)
* a bit extreme for what should be an infrequent event.
*/
save_fp(current);
+ /* Ensure 'resume' not overwrite saved fp context again. */
+ lose_fpu();
+
+ preempt_enable();
/* Run the emulator */
- sig = fpu_emulator_cop1Handler (0, regs,
+ sig = fpu_emulator_cop1Handler (regs,
&current->thread.fpu.soft);
+ preempt_disable();
+
+ own_fpu(); /* Using the FPU again. */
/*
* We can't allow the emulated instruction to leave any of
* the cause bit set in $fcr31.
@@ -584,7 +651,7 @@ asmlinkage void do_bp(struct pt_regs *regs)
info.si_code = FPE_INTOVF;
info.si_signo = SIGFPE;
info.si_errno = 0;
- info.si_addr = (void *)regs->cp0_epc;
+ info.si_addr = (void __user *) regs->cp0_epc;
force_sig_info(SIGFPE, &info, current);
break;
default:
@@ -621,7 +688,7 @@ asmlinkage void do_tr(struct pt_regs *regs)
info.si_code = FPE_INTOVF;
info.si_signo = SIGFPE;
info.si_errno = 0;
- info.si_addr = (void *)regs->cp0_epc;
+ info.si_addr = (void __user *) regs->cp0_epc;
force_sig_info(SIGFPE, &info, current);
break;
default:
@@ -637,6 +704,9 @@ asmlinkage void do_ri(struct pt_regs *regs)
if (!simulate_llsc(regs))
return;
+ if (!simulate_rdhwr(regs))
+ return;
+
force_sig(SIGILL, current);
}
@@ -650,11 +720,13 @@ asmlinkage void do_cpu(struct pt_regs *regs)
switch (cpid) {
case 0:
- if (cpu_has_llsc)
- break;
+ if (!cpu_has_llsc)
+ if (!simulate_llsc(regs))
+ return;
- if (!simulate_llsc(regs))
+ if (!simulate_rdhwr(regs))
return;
+
break;
case 1:
@@ -668,15 +740,15 @@ asmlinkage void do_cpu(struct pt_regs *regs)
set_used_math();
}
+ preempt_enable();
+
if (!cpu_has_fpu) {
- int sig = fpu_emulator_cop1Handler(0, regs,
+ int sig = fpu_emulator_cop1Handler(regs,
&current->thread.fpu.soft);
if (sig)
force_sig(sig, current);
}
- preempt_enable();
-
return;
case 2:
@@ -716,6 +788,22 @@ asmlinkage void do_mcheck(struct pt_regs *regs)
(regs->cp0_status & ST0_TS) ? "" : "not ");
}
+asmlinkage void do_mt(struct pt_regs *regs)
+{
+ die_if_kernel("MIPS MT Thread exception in kernel", regs);
+
+ force_sig(SIGILL, current);
+}
+
+
+asmlinkage void do_dsp(struct pt_regs *regs)
+{
+ if (cpu_has_dsp)
+ panic("Unexpected DSP exception\n");
+
+ force_sig(SIGILL, current);
+}
+
asmlinkage void do_reserved(struct pt_regs *regs)
{
/*
@@ -728,6 +816,12 @@ asmlinkage void do_reserved(struct pt_regs *regs)
(regs->cp0_cause & 0x7f) >> 2);
}
+asmlinkage void do_default_vi(struct pt_regs *regs)
+{
+ show_regs(regs);
+ panic("Caught unexpected vectored interrupt.");
+}
+
/*
* Some MIPS CPUs can enable/disable for cache parity detection, but do
* it different ways.
@@ -736,16 +830,12 @@ static inline void parity_protection_init(void)
{
switch (current_cpu_data.cputype) {
case CPU_24K:
- /* 24K cache parity not currently implemented in FPGA */
- printk(KERN_INFO "Disable cache parity protection for "
- "MIPS 24K CPU.\n");
- write_c0_ecc(read_c0_ecc() & ~0x80000000);
- break;
case CPU_5KC:
- /* Set the PE bit (bit 31) in the c0_ecc register. */
- printk(KERN_INFO "Enable cache parity protection for "
- "MIPS 5KC/24K CPUs.\n");
- write_c0_ecc(read_c0_ecc() | 0x80000000);
+ write_c0_ecc(0x80000000);
+ back_to_back_c0_hazard();
+ /* Set the PE bit (bit 31) in the c0_errctl register. */
+ printk(KERN_INFO "Cache parity protection %sabled\n",
+ (read_c0_ecc() & 0x80000000) ? "en" : "dis");
break;
case CPU_20KC:
case CPU_25KF:
@@ -783,7 +873,7 @@ asmlinkage void cache_parity_error(void)
reg_val & (1<<22) ? "E0 " : "");
printk("IDX: 0x%08x\n", reg_val & ((1<<22)-1));
-#if defined(CONFIG_CPU_MIPS32) || defined (CONFIG_CPU_MIPS64)
+#if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64)
if (reg_val & (1<<22))
printk("DErrAddr0: 0x%0*lx\n", field, read_c0_derraddr0());
@@ -840,7 +930,11 @@ void nmi_exception_handler(struct pt_regs *regs)
while(1) ;
}
+#define VECTORSPACING 0x100 /* for EI/VI mode */
+
+unsigned long ebase;
unsigned long exception_handlers[32];
+unsigned long vi_handlers[64];
/*
* As a side effect of the way this is implemented we're limited
@@ -854,13 +948,156 @@ void *set_except_vector(int n, void *addr)
exception_handlers[n] = handler;
if (n == 0 && cpu_has_divec) {
- *(volatile u32 *)(CAC_BASE + 0x200) = 0x08000000 |
+ *(volatile u32 *)(ebase + 0x200) = 0x08000000 |
(0x03ffffff & (handler >> 2));
- flush_icache_range(CAC_BASE + 0x200, CAC_BASE + 0x204);
+ flush_icache_range(ebase + 0x200, ebase + 0x204);
}
return (void *)old_handler;
}
+#ifdef CONFIG_CPU_MIPSR2
+/*
+ * Shadow register allocation
+ * FIXME: SMP...
+ */
+
+/* MIPSR2 shadow register sets */
+struct shadow_registers {
+ spinlock_t sr_lock; /* */
+ int sr_supported; /* Number of shadow register sets supported */
+ int sr_allocated; /* Bitmap of allocated shadow registers */
+} shadow_registers;
+
+void mips_srs_init(void)
+{
+#ifdef CONFIG_CPU_MIPSR2_SRS
+ shadow_registers.sr_supported = ((read_c0_srsctl() >> 26) & 0x0f) + 1;
+ printk ("%d MIPSR2 register sets available\n", shadow_registers.sr_supported);
+#else
+ shadow_registers.sr_supported = 1;
+#endif
+ shadow_registers.sr_allocated = 1; /* Set 0 used by kernel */
+ spin_lock_init(&shadow_registers.sr_lock);
+}
+
+int mips_srs_max(void)
+{
+ return shadow_registers.sr_supported;
+}
+
+int mips_srs_alloc (void)
+{
+ struct shadow_registers *sr = &shadow_registers;
+ unsigned long flags;
+ int set;
+
+ spin_lock_irqsave(&sr->sr_lock, flags);
+
+ for (set = 0; set < sr->sr_supported; set++) {
+ if ((sr->sr_allocated & (1 << set)) == 0) {
+ sr->sr_allocated |= 1 << set;
+ spin_unlock_irqrestore(&sr->sr_lock, flags);
+ return set;
+ }
+ }
+
+ /* None available */
+ spin_unlock_irqrestore(&sr->sr_lock, flags);
+ return -1;
+}
+
+void mips_srs_free (int set)
+{
+ struct shadow_registers *sr = &shadow_registers;
+ unsigned long flags;
+
+ spin_lock_irqsave(&sr->sr_lock, flags);
+ sr->sr_allocated &= ~(1 << set);
+ spin_unlock_irqrestore(&sr->sr_lock, flags);
+}
+
+void *set_vi_srs_handler (int n, void *addr, int srs)
+{
+ unsigned long handler;
+ unsigned long old_handler = vi_handlers[n];
+ u32 *w;
+ unsigned char *b;
+
+ if (!cpu_has_veic && !cpu_has_vint)
+ BUG();
+
+ if (addr == NULL) {
+ handler = (unsigned long) do_default_vi;
+ srs = 0;
+ }
+ else
+ handler = (unsigned long) addr;
+ vi_handlers[n] = (unsigned long) addr;
+
+ b = (unsigned char *)(ebase + 0x200 + n*VECTORSPACING);
+
+ if (srs >= mips_srs_max())
+ panic("Shadow register set %d not supported", srs);
+
+ if (cpu_has_veic) {
+ if (board_bind_eic_interrupt)
+ board_bind_eic_interrupt (n, srs);
+ }
+ else if (cpu_has_vint) {
+ /* SRSMap is only defined if shadow sets are implemented */
+ if (mips_srs_max() > 1)
+ change_c0_srsmap (0xf << n*4, srs << n*4);
+ }
+
+ if (srs == 0) {
+ /*
+ * If no shadow set is selected then use the default handler
+ * that does normal register saving and a standard interrupt exit
+ */
+
+ extern char except_vec_vi, except_vec_vi_lui;
+ extern char except_vec_vi_ori, except_vec_vi_end;
+ const int handler_len = &except_vec_vi_end - &except_vec_vi;
+ const int lui_offset = &except_vec_vi_lui - &except_vec_vi;
+ const int ori_offset = &except_vec_vi_ori - &except_vec_vi;
+
+ if (handler_len > VECTORSPACING) {
+ /*
+ * Sigh... panicing won't help as the console
+ * is probably not configured :(
+ */
+ panic ("VECTORSPACING too small");
+ }
+
+ memcpy (b, &except_vec_vi, handler_len);
+ w = (u32 *)(b + lui_offset);
+ *w = (*w & 0xffff0000) | (((u32)handler >> 16) & 0xffff);
+ w = (u32 *)(b + ori_offset);
+ *w = (*w & 0xffff0000) | ((u32)handler & 0xffff);
+ flush_icache_range((unsigned long)b, (unsigned long)(b+handler_len));
+ }
+ else {
+ /*
+ * In other cases jump directly to the interrupt handler
+ *
+ * It is the handlers responsibility to save registers if required
+ * (eg hi/lo) and return from the exception using "eret"
+ */
+ w = (u32 *)b;
+ *w++ = 0x08000000 | (((u32)handler >> 2) & 0x03fffff); /* j handler */
+ *w = 0;
+ flush_icache_range((unsigned long)b, (unsigned long)(b+8));
+ }
+
+ return (void *)old_handler;
+}
+
+void *set_vi_handler (int n, void *addr)
+{
+ return set_vi_srs_handler (n, addr, 0);
+}
+#endif
+
/*
* This is used by native signal handling
*/
@@ -912,6 +1149,7 @@ static inline void signal32_init(void)
extern void cpu_cache_init(void);
extern void tlb_init(void);
+extern void flush_tlb_handlers(void);
void __init per_cpu_trap_init(void)
{
@@ -929,15 +1167,32 @@ void __init per_cpu_trap_init(void)
#endif
if (current_cpu_data.isa_level == MIPS_CPU_ISA_IV)
status_set |= ST0_XX;
- change_c0_status(ST0_CU|ST0_FR|ST0_BEV|ST0_TS|ST0_KX|ST0_SX|ST0_UX,
+ change_c0_status(ST0_CU|ST0_MX|ST0_FR|ST0_BEV|ST0_TS|ST0_KX|ST0_SX|ST0_UX,
status_set);
+ if (cpu_has_dsp)
+ set_c0_status(ST0_MX);
+
+#ifdef CONFIG_CPU_MIPSR2
+ write_c0_hwrena (0x0000000f); /* Allow rdhwr to all registers */
+#endif
+
/*
- * Some MIPS CPUs have a dedicated interrupt vector which reduces the
- * interrupt processing overhead. Use it where available.
+ * Interrupt handling.
*/
- if (cpu_has_divec)
- set_c0_cause(CAUSEF_IV);
+ if (cpu_has_veic || cpu_has_vint) {
+ write_c0_ebase (ebase);
+ /* Setting vector spacing enables EI/VI mode */
+ change_c0_intctl (0x3e0, VECTORSPACING);
+ }
+ if (cpu_has_divec) {
+ if (cpu_has_mipsmt) {
+ unsigned int vpflags = dvpe();
+ set_c0_cause(CAUSEF_IV);
+ evpe(vpflags);
+ } else
+ set_c0_cause(CAUSEF_IV);
+ }
cpu_data[cpu].asid_cache = ASID_FIRST_VERSION;
TLBMISS_HANDLER_SETUP();
@@ -951,13 +1206,41 @@ void __init per_cpu_trap_init(void)
tlb_init();
}
+/* Install CPU exception handler */
+void __init set_handler (unsigned long offset, void *addr, unsigned long size)
+{
+ memcpy((void *)(ebase + offset), addr, size);
+ flush_icache_range(ebase + offset, ebase + offset + size);
+}
+
+/* Install uncached CPU exception handler */
+void __init set_uncached_handler (unsigned long offset, void *addr, unsigned long size)
+{
+#ifdef CONFIG_32BIT
+ unsigned long uncached_ebase = KSEG1ADDR(ebase);
+#endif
+#ifdef CONFIG_64BIT
+ unsigned long uncached_ebase = TO_UNCAC(ebase);
+#endif
+
+ memcpy((void *)(uncached_ebase + offset), addr, size);
+}
+
void __init trap_init(void)
{
extern char except_vec3_generic, except_vec3_r4000;
- extern char except_vec_ejtag_debug;
extern char except_vec4;
unsigned long i;
+ if (cpu_has_veic || cpu_has_vint)
+ ebase = (unsigned long) alloc_bootmem_low_pages (0x200 + VECTORSPACING*64);
+ else
+ ebase = CAC_BASE;
+
+#ifdef CONFIG_CPU_MIPSR2
+ mips_srs_init();
+#endif
+
per_cpu_trap_init();
/*
@@ -965,7 +1248,7 @@ void __init trap_init(void)
* This will be overriden later as suitable for a particular
* configuration.
*/
- memcpy((void *)(CAC_BASE + 0x180), &except_vec3_generic, 0x80);
+ set_handler(0x180, &except_vec3_generic, 0x80);
/*
* Setup default vectors
@@ -977,8 +1260,8 @@ void __init trap_init(void)
* Copy the EJTAG debug exception vector handler code to it's final
* destination.
*/
- if (cpu_has_ejtag)
- memcpy((void *)(CAC_BASE + 0x300), &except_vec_ejtag_debug, 0x80);
+ if (cpu_has_ejtag && board_ejtag_handler_setup)
+ board_ejtag_handler_setup ();
/*
* Only some CPUs have the watch exceptions.
@@ -987,11 +1270,15 @@ void __init trap_init(void)
set_except_vector(23, handle_watch);
/*
- * Some MIPS CPUs have a dedicated interrupt vector which reduces the
- * interrupt processing overhead. Use it where available.
+ * Initialise interrupt handlers
*/
- if (cpu_has_divec)
- memcpy((void *)(CAC_BASE + 0x200), &except_vec4, 0x8);
+ if (cpu_has_veic || cpu_has_vint) {
+ int nvec = cpu_has_veic ? 64 : 8;
+ for (i = 0; i < nvec; i++)
+ set_vi_handler (i, NULL);
+ }
+ else if (cpu_has_divec)
+ set_handler(0x200, &except_vec4, 0x8);
/*
* Some CPUs can enable/disable for cache parity detection, but does
@@ -1023,21 +1310,6 @@ void __init trap_init(void)
set_except_vector(11, handle_cpu);
set_except_vector(12, handle_ov);
set_except_vector(13, handle_tr);
- set_except_vector(22, handle_mdmx);
-
- if (cpu_has_fpu && !cpu_has_nofpuex)
- set_except_vector(15, handle_fpe);
-
- if (cpu_has_mcheck)
- set_except_vector(24, handle_mcheck);
-
- if (cpu_has_vce)
- /* Special exception: R4[04]00 uses also the divec space. */
- memcpy((void *)(CAC_BASE + 0x180), &except_vec3_r4000, 0x100);
- else if (cpu_has_4kex)
- memcpy((void *)(CAC_BASE + 0x180), &except_vec3_generic, 0x80);
- else
- memcpy((void *)(CAC_BASE + 0x080), &except_vec3_generic, 0x80);
if (current_cpu_data.cputype == CPU_R6000 ||
current_cpu_data.cputype == CPU_R6000A) {
@@ -1053,10 +1325,37 @@ void __init trap_init(void)
//set_except_vector(15, handle_ndc);
}
+
+ if (board_nmi_handler_setup)
+ board_nmi_handler_setup();
+
+ if (cpu_has_fpu && !cpu_has_nofpuex)
+ set_except_vector(15, handle_fpe);
+
+ set_except_vector(22, handle_mdmx);
+
+ if (cpu_has_mcheck)
+ set_except_vector(24, handle_mcheck);
+
+ if (cpu_has_mipsmt)
+ set_except_vector(25, handle_mt);
+
+ if (cpu_has_dsp)
+ set_except_vector(26, handle_dsp);
+
+ if (cpu_has_vce)
+ /* Special exception: R4[04]00 uses also the divec space. */
+ memcpy((void *)(CAC_BASE + 0x180), &except_vec3_r4000, 0x100);
+ else if (cpu_has_4kex)
+ memcpy((void *)(CAC_BASE + 0x180), &except_vec3_generic, 0x80);
+ else
+ memcpy((void *)(CAC_BASE + 0x080), &except_vec3_generic, 0x80);
+
signal_init();
#ifdef CONFIG_MIPS32_COMPAT
signal32_init();
#endif
- flush_icache_range(CAC_BASE, CAC_BASE + 0x400);
+ flush_icache_range(ebase, ebase + 0x400);
+ flush_tlb_handlers();
}
diff --git a/arch/mips/kernel/unaligned.c b/arch/mips/kernel/unaligned.c
index 36c5212e0928..5b5a3736cbbc 100644
--- a/arch/mips/kernel/unaligned.c
+++ b/arch/mips/kernel/unaligned.c
@@ -94,7 +94,7 @@ unsigned long unaligned_instructions;
#endif
static inline int emulate_load_store_insn(struct pt_regs *regs,
- void *addr, unsigned long pc,
+ void __user *addr, unsigned int __user *pc,
unsigned long **regptr, unsigned long *newvalue)
{
union mips_instruction insn;
@@ -107,7 +107,7 @@ static inline int emulate_load_store_insn(struct pt_regs *regs,
/*
* This load never faults.
*/
- __get_user(insn.word, (unsigned int *)pc);
+ __get_user(insn.word, pc);
switch (insn.i_format.opcode) {
/*
@@ -494,8 +494,8 @@ asmlinkage void do_ade(struct pt_regs *regs)
{
unsigned long *regptr, newval;
extern int do_dsemulret(struct pt_regs *);
+ unsigned int __user *pc;
mm_segment_t seg;
- unsigned long pc;
/*
* Address errors may be deliberately induced by the FPU emulator to
@@ -515,7 +515,7 @@ asmlinkage void do_ade(struct pt_regs *regs)
if ((regs->cp0_badvaddr == regs->cp0_epc) || (regs->cp0_epc & 0x1))
goto sigbus;
- pc = exception_epc(regs);
+ pc = (unsigned int __user *) exception_epc(regs);
if ((current->thread.mflags & MF_FIXADE) == 0)
goto sigbus;
@@ -526,7 +526,7 @@ asmlinkage void do_ade(struct pt_regs *regs)
seg = get_fs();
if (!user_mode(regs))
set_fs(KERNEL_DS);
- if (!emulate_load_store_insn(regs, (void *)regs->cp0_badvaddr, pc,
+ if (!emulate_load_store_insn(regs, (void __user *)regs->cp0_badvaddr, pc,
&regptr, &newval)) {
compute_return_epc(regs);
/*
diff --git a/arch/mips/kernel/vmlinux.lds.S b/arch/mips/kernel/vmlinux.lds.S
index 482ac310c937..25cc856d8e7e 100644
--- a/arch/mips/kernel/vmlinux.lds.S
+++ b/arch/mips/kernel/vmlinux.lds.S
@@ -54,13 +54,6 @@ SECTIONS
*(.data)
- /* Align the initial ramdisk image (INITRD) on page boundaries. */
- . = ALIGN(4096);
- __rd_start = .;
- *(.initrd)
- . = ALIGN(4096);
- __rd_end = .;
-
CONSTRUCTORS
}
_gp = . + 0x8000;
@@ -96,12 +89,6 @@ SECTIONS
.init.setup : { *(.init.setup) }
__setup_end = .;
- .early_initcall.init : {
- __earlyinitcall_start = .;
- *(.initcall.early1.init)
- }
- __earlyinitcall_end = .;
-
__initcall_start = .;
.initcall.init : {
*(.initcall1.init)
diff --git a/arch/mips/kernel/vpe.c b/arch/mips/kernel/vpe.c
new file mode 100644
index 000000000000..06be405be399
--- /dev/null
+++ b/arch/mips/kernel/vpe.c
@@ -0,0 +1,1284 @@
+/*
+ * Copyright (C) 2004, 2005 MIPS Technologies, Inc. All rights reserved.
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ */
+
+/*
+ * VPE support module
+ *
+ * Provides support for loading a MIPS SP program on VPE1.
+ * The SP enviroment is rather simple, no tlb's. It needs to be relocatable
+ * (or partially linked). You should initialise your stack in the startup
+ * code. This loader looks for the symbol __start and sets up
+ * execution to resume from there. The MIPS SDE kit contains suitable examples.
+ *
+ * To load and run, simply cat a SP 'program file' to /dev/vpe1.
+ * i.e cat spapp >/dev/vpe1.
+ *
+ * You'll need to have the following device files.
+ * mknod /dev/vpe0 c 63 0
+ * mknod /dev/vpe1 c 63 1
+ */
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/init.h>
+#include <asm/uaccess.h>
+#include <linux/slab.h>
+#include <linux/list.h>
+#include <linux/vmalloc.h>
+#include <linux/elf.h>
+#include <linux/seq_file.h>
+#include <linux/syscalls.h>
+#include <linux/moduleloader.h>
+#include <linux/interrupt.h>
+#include <linux/poll.h>
+#include <linux/bootmem.h>
+#include <asm/mipsregs.h>
+#include <asm/mipsmtregs.h>
+#include <asm/cacheflush.h>
+#include <asm/atomic.h>
+#include <asm/cpu.h>
+#include <asm/processor.h>
+#include <asm/system.h>
+
+typedef void *vpe_handle;
+
+#ifndef ARCH_SHF_SMALL
+#define ARCH_SHF_SMALL 0
+#endif
+
+/* If this is set, the section belongs in the init part of the module */
+#define INIT_OFFSET_MASK (1UL << (BITS_PER_LONG-1))
+
+static char module_name[] = "vpe";
+static int major;
+
+/* grab the likely amount of memory we will need. */
+#ifdef CONFIG_MIPS_VPE_LOADER_TOM
+#define P_SIZE (2 * 1024 * 1024)
+#else
+/* add an overhead to the max kmalloc size for non-striped symbols/etc */
+#define P_SIZE (256 * 1024)
+#endif
+
+#define MAX_VPES 16
+
+enum vpe_state {
+ VPE_STATE_UNUSED = 0,
+ VPE_STATE_INUSE,
+ VPE_STATE_RUNNING
+};
+
+enum tc_state {
+ TC_STATE_UNUSED = 0,
+ TC_STATE_INUSE,
+ TC_STATE_RUNNING,
+ TC_STATE_DYNAMIC
+};
+
+struct vpe {
+ enum vpe_state state;
+
+ /* (device) minor associated with this vpe */
+ int minor;
+
+ /* elfloader stuff */
+ void *load_addr;
+ u32 len;
+ char *pbuffer;
+ u32 plen;
+
+ unsigned long __start;
+
+ /* tc's associated with this vpe */
+ struct list_head tc;
+
+ /* The list of vpe's */
+ struct list_head list;
+
+ /* shared symbol address */
+ void *shared_ptr;
+};
+
+struct tc {
+ enum tc_state state;
+ int index;
+
+ /* parent VPE */
+ struct vpe *pvpe;
+
+ /* The list of TC's with this VPE */
+ struct list_head tc;
+
+ /* The global list of tc's */
+ struct list_head list;
+};
+
+struct vpecontrol_ {
+ /* Virtual processing elements */
+ struct list_head vpe_list;
+
+ /* Thread contexts */
+ struct list_head tc_list;
+} vpecontrol;
+
+static void release_progmem(void *ptr);
+static void dump_vpe(struct vpe * v);
+extern void save_gp_address(unsigned int secbase, unsigned int rel);
+
+/* get the vpe associated with this minor */
+struct vpe *get_vpe(int minor)
+{
+ struct vpe *v;
+
+ list_for_each_entry(v, &vpecontrol.vpe_list, list) {
+ if (v->minor == minor)
+ return v;
+ }
+
+ printk(KERN_DEBUG "VPE: get_vpe minor %d not found\n", minor);
+ return NULL;
+}
+
+/* get the vpe associated with this minor */
+struct tc *get_tc(int index)
+{
+ struct tc *t;
+
+ list_for_each_entry(t, &vpecontrol.tc_list, list) {
+ if (t->index == index)
+ return t;
+ }
+
+ printk(KERN_DEBUG "VPE: get_tc index %d not found\n", index);
+
+ return NULL;
+}
+
+struct tc *get_tc_unused(void)
+{
+ struct tc *t;
+
+ list_for_each_entry(t, &vpecontrol.tc_list, list) {
+ if (t->state == TC_STATE_UNUSED)
+ return t;
+ }
+
+ printk(KERN_DEBUG "VPE: All TC's are in use\n");
+
+ return NULL;
+}
+
+/* allocate a vpe and associate it with this minor (or index) */
+struct vpe *alloc_vpe(int minor)
+{
+ struct vpe *v;
+
+ if ((v = kzalloc(sizeof(struct vpe), GFP_KERNEL)) == NULL) {
+ printk(KERN_WARNING "VPE: alloc_vpe no mem\n");
+ return NULL;
+ }
+
+ INIT_LIST_HEAD(&v->tc);
+ list_add_tail(&v->list, &vpecontrol.vpe_list);
+
+ v->minor = minor;
+ return v;
+}
+
+/* allocate a tc. At startup only tc0 is running, all other can be halted. */
+struct tc *alloc_tc(int index)
+{
+ struct tc *t;
+
+ if ((t = kzalloc(sizeof(struct tc), GFP_KERNEL)) == NULL) {
+ printk(KERN_WARNING "VPE: alloc_tc no mem\n");
+ return NULL;
+ }
+
+ INIT_LIST_HEAD(&t->tc);
+ list_add_tail(&t->list, &vpecontrol.tc_list);
+
+ t->index = index;
+
+ return t;
+}
+
+/* clean up and free everything */
+void release_vpe(struct vpe *v)
+{
+ list_del(&v->list);
+ if (v->load_addr)
+ release_progmem(v);
+ kfree(v);
+}
+
+void dump_mtregs(void)
+{
+ unsigned long val;
+
+ val = read_c0_config3();
+ printk("config3 0x%lx MT %ld\n", val,
+ (val & CONFIG3_MT) >> CONFIG3_MT_SHIFT);
+
+ val = read_c0_mvpconf0();
+ printk("mvpconf0 0x%lx, PVPE %ld PTC %ld M %ld\n", val,
+ (val & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT,
+ val & MVPCONF0_PTC, (val & MVPCONF0_M) >> MVPCONF0_M_SHIFT);
+
+ val = read_c0_mvpcontrol();
+ printk("MVPControl 0x%lx, STLB %ld VPC %ld EVP %ld\n", val,
+ (val & MVPCONTROL_STLB) >> MVPCONTROL_STLB_SHIFT,
+ (val & MVPCONTROL_VPC) >> MVPCONTROL_VPC_SHIFT,
+ (val & MVPCONTROL_EVP));
+
+ val = read_c0_vpeconf0();
+ printk("VPEConf0 0x%lx MVP %ld\n", val,
+ (val & VPECONF0_MVP) >> VPECONF0_MVP_SHIFT);
+}
+
+/* Find some VPE program space */
+static void *alloc_progmem(u32 len)
+{
+#ifdef CONFIG_MIPS_VPE_LOADER_TOM
+ /* this means you must tell linux to use less memory than you physically have */
+ return (void *)((max_pfn * PAGE_SIZE) + KSEG0);
+#else
+ // simple grab some mem for now
+ return kmalloc(len, GFP_KERNEL);
+#endif
+}
+
+static void release_progmem(void *ptr)
+{
+#ifndef CONFIG_MIPS_VPE_LOADER_TOM
+ kfree(ptr);
+#endif
+}
+
+/* Update size with this section: return offset. */
+static long get_offset(unsigned long *size, Elf_Shdr * sechdr)
+{
+ long ret;
+
+ ret = ALIGN(*size, sechdr->sh_addralign ? : 1);
+ *size = ret + sechdr->sh_size;
+ return ret;
+}
+
+/* Lay out the SHF_ALLOC sections in a way not dissimilar to how ld
+ might -- code, read-only data, read-write data, small data. Tally
+ sizes, and place the offsets into sh_entsize fields: high bit means it
+ belongs in init. */
+static void layout_sections(struct module *mod, const Elf_Ehdr * hdr,
+ Elf_Shdr * sechdrs, const char *secstrings)
+{
+ static unsigned long const masks[][2] = {
+ /* NOTE: all executable code must be the first section
+ * in this array; otherwise modify the text_size
+ * finder in the two loops below */
+ {SHF_EXECINSTR | SHF_ALLOC, ARCH_SHF_SMALL},
+ {SHF_ALLOC, SHF_WRITE | ARCH_SHF_SMALL},
+ {SHF_WRITE | SHF_ALLOC, ARCH_SHF_SMALL},
+ {ARCH_SHF_SMALL | SHF_ALLOC, 0}
+ };
+ unsigned int m, i;
+
+ for (i = 0; i < hdr->e_shnum; i++)
+ sechdrs[i].sh_entsize = ~0UL;
+
+ for (m = 0; m < ARRAY_SIZE(masks); ++m) {
+ for (i = 0; i < hdr->e_shnum; ++i) {
+ Elf_Shdr *s = &sechdrs[i];
+
+ // || strncmp(secstrings + s->sh_name, ".init", 5) == 0)
+ if ((s->sh_flags & masks[m][0]) != masks[m][0]
+ || (s->sh_flags & masks[m][1])
+ || s->sh_entsize != ~0UL)
+ continue;
+ s->sh_entsize = get_offset(&mod->core_size, s);
+ }
+
+ if (m == 0)
+ mod->core_text_size = mod->core_size;
+
+ }
+}
+
+
+/* from module-elf32.c, but subverted a little */
+
+struct mips_hi16 {
+ struct mips_hi16 *next;
+ Elf32_Addr *addr;
+ Elf32_Addr value;
+};
+
+static struct mips_hi16 *mips_hi16_list;
+static unsigned int gp_offs, gp_addr;
+
+static int apply_r_mips_none(struct module *me, uint32_t *location,
+ Elf32_Addr v)
+{
+ return 0;
+}
+
+static int apply_r_mips_gprel16(struct module *me, uint32_t *location,
+ Elf32_Addr v)
+{
+ int rel;
+
+ if( !(*location & 0xffff) ) {
+ rel = (int)v - gp_addr;
+ }
+ else {
+ /* .sbss + gp(relative) + offset */
+ /* kludge! */
+ rel = (int)(short)((int)v + gp_offs +
+ (int)(short)(*location & 0xffff) - gp_addr);
+ }
+
+ if( (rel > 32768) || (rel < -32768) ) {
+ printk(KERN_ERR
+ "apply_r_mips_gprel16: relative address out of range 0x%x %d\n",
+ rel, rel);
+ return -ENOEXEC;
+ }
+
+ *location = (*location & 0xffff0000) | (rel & 0xffff);
+
+ return 0;
+}
+
+static int apply_r_mips_pc16(struct module *me, uint32_t *location,
+ Elf32_Addr v)
+{
+ int rel;
+ rel = (((unsigned int)v - (unsigned int)location));
+ rel >>= 2; // because the offset is in _instructions_ not bytes.
+ rel -= 1; // and one instruction less due to the branch delay slot.
+
+ if( (rel > 32768) || (rel < -32768) ) {
+ printk(KERN_ERR
+ "apply_r_mips_pc16: relative address out of range 0x%x\n", rel);
+ return -ENOEXEC;
+ }
+
+ *location = (*location & 0xffff0000) | (rel & 0xffff);
+
+ return 0;
+}
+
+static int apply_r_mips_32(struct module *me, uint32_t *location,
+ Elf32_Addr v)
+{
+ *location += v;
+
+ return 0;
+}
+
+static int apply_r_mips_26(struct module *me, uint32_t *location,
+ Elf32_Addr v)
+{
+ if (v % 4) {
+ printk(KERN_ERR "module %s: dangerous relocation mod4\n", me->name);
+ return -ENOEXEC;
+ }
+
+/*
+ * Not desperately convinced this is a good check of an overflow condition
+ * anyway. But it gets in the way of handling undefined weak symbols which
+ * we want to set to zero.
+ * if ((v & 0xf0000000) != (((unsigned long)location + 4) & 0xf0000000)) {
+ * printk(KERN_ERR
+ * "module %s: relocation overflow\n",
+ * me->name);
+ * return -ENOEXEC;
+ * }
+ */
+
+ *location = (*location & ~0x03ffffff) |
+ ((*location + (v >> 2)) & 0x03ffffff);
+ return 0;
+}
+
+static int apply_r_mips_hi16(struct module *me, uint32_t *location,
+ Elf32_Addr v)
+{
+ struct mips_hi16 *n;
+
+ /*
+ * We cannot relocate this one now because we don't know the value of
+ * the carry we need to add. Save the information, and let LO16 do the
+ * actual relocation.
+ */
+ n = kmalloc(sizeof *n, GFP_KERNEL);
+ if (!n)
+ return -ENOMEM;
+
+ n->addr = location;
+ n->value = v;
+ n->next = mips_hi16_list;
+ mips_hi16_list = n;
+
+ return 0;
+}
+
+static int apply_r_mips_lo16(struct module *me, uint32_t *location,
+ Elf32_Addr v)
+{
+ unsigned long insnlo = *location;
+ Elf32_Addr val, vallo;
+
+ /* Sign extend the addend we extract from the lo insn. */
+ vallo = ((insnlo & 0xffff) ^ 0x8000) - 0x8000;
+
+ if (mips_hi16_list != NULL) {
+ struct mips_hi16 *l;
+
+ l = mips_hi16_list;
+ while (l != NULL) {
+ struct mips_hi16 *next;
+ unsigned long insn;
+
+ /*
+ * The value for the HI16 had best be the same.
+ */
+ if (v != l->value) {
+ printk("%d != %d\n", v, l->value);
+ goto out_danger;
+ }
+
+
+ /*
+ * Do the HI16 relocation. Note that we actually don't
+ * need to know anything about the LO16 itself, except
+ * where to find the low 16 bits of the addend needed
+ * by the LO16.
+ */
+ insn = *l->addr;
+ val = ((insn & 0xffff) << 16) + vallo;
+ val += v;
+
+ /*
+ * Account for the sign extension that will happen in
+ * the low bits.
+ */
+ val = ((val >> 16) + ((val & 0x8000) != 0)) & 0xffff;
+
+ insn = (insn & ~0xffff) | val;
+ *l->addr = insn;
+
+ next = l->next;
+ kfree(l);
+ l = next;
+ }
+
+ mips_hi16_list = NULL;
+ }
+
+ /*
+ * Ok, we're done with the HI16 relocs. Now deal with the LO16.
+ */
+ val = v + vallo;
+ insnlo = (insnlo & ~0xffff) | (val & 0xffff);
+ *location = insnlo;
+
+ return 0;
+
+out_danger:
+ printk(KERN_ERR "module %s: dangerous " "relocation\n", me->name);
+
+ return -ENOEXEC;
+}
+
+static int (*reloc_handlers[]) (struct module *me, uint32_t *location,
+ Elf32_Addr v) = {
+ [R_MIPS_NONE] = apply_r_mips_none,
+ [R_MIPS_32] = apply_r_mips_32,
+ [R_MIPS_26] = apply_r_mips_26,
+ [R_MIPS_HI16] = apply_r_mips_hi16,
+ [R_MIPS_LO16] = apply_r_mips_lo16,
+ [R_MIPS_GPREL16] = apply_r_mips_gprel16,
+ [R_MIPS_PC16] = apply_r_mips_pc16
+};
+
+
+int apply_relocations(Elf32_Shdr *sechdrs,
+ const char *strtab,
+ unsigned int symindex,
+ unsigned int relsec,
+ struct module *me)
+{
+ Elf32_Rel *rel = (void *) sechdrs[relsec].sh_addr;
+ Elf32_Sym *sym;
+ uint32_t *location;
+ unsigned int i;
+ Elf32_Addr v;
+ int res;
+
+ for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
+ Elf32_Word r_info = rel[i].r_info;
+
+ /* This is where to make the change */
+ location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
+ + rel[i].r_offset;
+ /* This is the symbol it is referring to */
+ sym = (Elf32_Sym *)sechdrs[symindex].sh_addr
+ + ELF32_R_SYM(r_info);
+
+ if (!sym->st_value) {
+ printk(KERN_DEBUG "%s: undefined weak symbol %s\n",
+ me->name, strtab + sym->st_name);
+ /* just print the warning, dont barf */
+ }
+
+ v = sym->st_value;
+
+ res = reloc_handlers[ELF32_R_TYPE(r_info)](me, location, v);
+ if( res ) {
+ printk(KERN_DEBUG
+ "relocation error 0x%x sym refer <%s> value 0x%x "
+ "type 0x%x r_info 0x%x\n",
+ (unsigned int)location, strtab + sym->st_name, v,
+ r_info, ELF32_R_TYPE(r_info));
+ }
+
+ if (res)
+ return res;
+ }
+
+ return 0;
+}
+
+void save_gp_address(unsigned int secbase, unsigned int rel)
+{
+ gp_addr = secbase + rel;
+ gp_offs = gp_addr - (secbase & 0xffff0000);
+}
+/* end module-elf32.c */
+
+
+
+/* Change all symbols so that sh_value encodes the pointer directly. */
+static int simplify_symbols(Elf_Shdr * sechdrs,
+ unsigned int symindex,
+ const char *strtab,
+ const char *secstrings,
+ unsigned int nsecs, struct module *mod)
+{
+ Elf_Sym *sym = (void *)sechdrs[symindex].sh_addr;
+ unsigned long secbase, bssbase = 0;
+ unsigned int i, n = sechdrs[symindex].sh_size / sizeof(Elf_Sym);
+ int ret = 0, size;
+
+ /* find the .bss section for COMMON symbols */
+ for (i = 0; i < nsecs; i++) {
+ if (strncmp(secstrings + sechdrs[i].sh_name, ".bss", 4) == 0)
+ bssbase = sechdrs[i].sh_addr;
+ }
+
+ for (i = 1; i < n; i++) {
+ switch (sym[i].st_shndx) {
+ case SHN_COMMON:
+ /* Allocate space for the symbol in the .bss section. st_value is currently size.
+ We want it to have the address of the symbol. */
+
+ size = sym[i].st_value;
+ sym[i].st_value = bssbase;
+
+ bssbase += size;
+ break;
+
+ case SHN_ABS:
+ /* Don't need to do anything */
+ break;
+
+ case SHN_UNDEF:
+ /* ret = -ENOENT; */
+ break;
+
+ case SHN_MIPS_SCOMMON:
+
+ printk(KERN_DEBUG
+ "simplify_symbols: ignoring SHN_MIPS_SCOMMON symbol <%s> st_shndx %d\n",
+ strtab + sym[i].st_name, sym[i].st_shndx);
+
+ // .sbss section
+ break;
+
+ default:
+ secbase = sechdrs[sym[i].st_shndx].sh_addr;
+
+ if (strncmp(strtab + sym[i].st_name, "_gp", 3) == 0) {
+ save_gp_address(secbase, sym[i].st_value);
+ }
+
+ sym[i].st_value += secbase;
+ break;
+ }
+
+ }
+
+ return ret;
+}
+
+#ifdef DEBUG_ELFLOADER
+static void dump_elfsymbols(Elf_Shdr * sechdrs, unsigned int symindex,
+ const char *strtab, struct module *mod)
+{
+ Elf_Sym *sym = (void *)sechdrs[symindex].sh_addr;
+ unsigned int i, n = sechdrs[symindex].sh_size / sizeof(Elf_Sym);
+
+ printk(KERN_DEBUG "dump_elfsymbols: n %d\n", n);
+ for (i = 1; i < n; i++) {
+ printk(KERN_DEBUG " i %d name <%s> 0x%x\n", i,
+ strtab + sym[i].st_name, sym[i].st_value);
+ }
+}
+#endif
+
+static void dump_tc(struct tc *t)
+{
+ printk(KERN_WARNING "VPE: TC index %d TCStatus 0x%lx halt 0x%lx\n",
+ t->index, read_tc_c0_tcstatus(), read_tc_c0_tchalt());
+ printk(KERN_WARNING "VPE: tcrestart 0x%lx\n", read_tc_c0_tcrestart());
+}
+
+static void dump_tclist(void)
+{
+ struct tc *t;
+
+ list_for_each_entry(t, &vpecontrol.tc_list, list) {
+ dump_tc(t);
+ }
+}
+
+/* We are prepared so configure and start the VPE... */
+int vpe_run(struct vpe * v)
+{
+ unsigned long val;
+ struct tc *t;
+
+ /* check we are the Master VPE */
+ val = read_c0_vpeconf0();
+ if (!(val & VPECONF0_MVP)) {
+ printk(KERN_WARNING
+ "VPE: only Master VPE's are allowed to configure MT\n");
+ return -1;
+ }
+
+ /* disable MT (using dvpe) */
+ dvpe();
+
+ /* Put MVPE's into 'configuration state' */
+ set_c0_mvpcontrol(MVPCONTROL_VPC);
+
+ if (!list_empty(&v->tc)) {
+ if ((t = list_entry(v->tc.next, struct tc, tc)) == NULL) {
+ printk(KERN_WARNING "VPE: TC %d is already in use.\n",
+ t->index);
+ return -ENOEXEC;
+ }
+ } else {
+ printk(KERN_WARNING "VPE: No TC's associated with VPE %d\n",
+ v->minor);
+ return -ENOEXEC;
+ }
+
+ settc(t->index);
+
+ val = read_vpe_c0_vpeconf0();
+
+ /* should check it is halted, and not activated */
+ if ((read_tc_c0_tcstatus() & TCSTATUS_A) || !(read_tc_c0_tchalt() & TCHALT_H)) {
+ printk(KERN_WARNING "VPE: TC %d is already doing something!\n",
+ t->index);
+
+ dump_tclist();
+ return -ENOEXEC;
+ }
+
+ /* Write the address we want it to start running from in the TCPC register. */
+ write_tc_c0_tcrestart((unsigned long)v->__start);
+
+ /* write the sivc_info address to tccontext */
+ write_tc_c0_tccontext((unsigned long)0);
+
+ /* Set up the XTC bit in vpeconf0 to point at our tc */
+ write_vpe_c0_vpeconf0(read_vpe_c0_vpeconf0() | (t->index << VPECONF0_XTC_SHIFT));
+
+ /* mark the TC as activated, not interrupt exempt and not dynamically allocatable */
+ val = read_tc_c0_tcstatus();
+ val = (val & ~(TCSTATUS_DA | TCSTATUS_IXMT)) | TCSTATUS_A;
+ write_tc_c0_tcstatus(val);
+
+ write_tc_c0_tchalt(read_tc_c0_tchalt() & ~TCHALT_H);
+
+ /* set up VPE1 */
+ write_vpe_c0_vpecontrol(read_vpe_c0_vpecontrol() & ~VPECONTROL_TE); // no multiple TC's
+ write_vpe_c0_vpeconf0(read_vpe_c0_vpeconf0() | VPECONF0_VPA); // enable this VPE
+
+ /*
+ * The sde-kit passes 'memsize' to __start in $a3, so set something
+ * here...
+ * Or set $a3 (register 7) to zero and define DFLT_STACK_SIZE and
+ * DFLT_HEAP_SIZE when you compile your program
+ */
+
+ mttgpr(7, 0);
+
+ /* set config to be the same as vpe0, particularly kseg0 coherency alg */
+ write_vpe_c0_config(read_c0_config());
+
+ /* clear out any left overs from a previous program */
+ write_vpe_c0_cause(0);
+
+ /* take system out of configuration state */
+ clear_c0_mvpcontrol(MVPCONTROL_VPC);
+
+ /* clear interrupts enabled IE, ERL, EXL, and KSU from c0 status */
+ write_vpe_c0_status(read_vpe_c0_status() & ~(ST0_ERL | ST0_KSU | ST0_IE | ST0_EXL));
+
+ /* set it running */
+ evpe(EVPE_ENABLE);
+
+ return 0;
+}
+
+static unsigned long find_vpe_symbols(struct vpe * v, Elf_Shdr * sechdrs,
+ unsigned int symindex, const char *strtab,
+ struct module *mod)
+{
+ Elf_Sym *sym = (void *)sechdrs[symindex].sh_addr;
+ unsigned int i, n = sechdrs[symindex].sh_size / sizeof(Elf_Sym);
+
+ for (i = 1; i < n; i++) {
+ if (strcmp(strtab + sym[i].st_name, "__start") == 0) {
+ v->__start = sym[i].st_value;
+ }
+
+ if (strcmp(strtab + sym[i].st_name, "vpe_shared") == 0) {
+ v->shared_ptr = (void *)sym[i].st_value;
+ }
+ }
+
+ return 0;
+}
+
+/*
+ * Allocates a VPE with some program code space(the load address), copies
+ * the contents of the program (p)buffer performing relocatations/etc,
+ * free's it when finished.
+*/
+int vpe_elfload(struct vpe * v)
+{
+ Elf_Ehdr *hdr;
+ Elf_Shdr *sechdrs;
+ long err = 0;
+ char *secstrings, *strtab = NULL;
+ unsigned int len, i, symindex = 0, strindex = 0;
+
+ struct module mod; // so we can re-use the relocations code
+
+ memset(&mod, 0, sizeof(struct module));
+ strcpy(mod.name, "VPE dummy prog module");
+
+ hdr = (Elf_Ehdr *) v->pbuffer;
+ len = v->plen;
+
+ /* Sanity checks against insmoding binaries or wrong arch,
+ weird elf version */
+ if (memcmp(hdr->e_ident, ELFMAG, 4) != 0
+ || hdr->e_type != ET_REL || !elf_check_arch(hdr)
+ || hdr->e_shentsize != sizeof(*sechdrs)) {
+ printk(KERN_WARNING
+ "VPE program, wrong arch or weird elf version\n");
+
+ return -ENOEXEC;
+ }
+
+ if (len < hdr->e_shoff + hdr->e_shnum * sizeof(Elf_Shdr)) {
+ printk(KERN_ERR "VPE program length %u truncated\n", len);
+ return -ENOEXEC;
+ }
+
+ /* Convenience variables */
+ sechdrs = (void *)hdr + hdr->e_shoff;
+ secstrings = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
+ sechdrs[0].sh_addr = 0;
+
+ /* And these should exist, but gcc whinges if we don't init them */
+ symindex = strindex = 0;
+
+ for (i = 1; i < hdr->e_shnum; i++) {
+
+ if (sechdrs[i].sh_type != SHT_NOBITS
+ && len < sechdrs[i].sh_offset + sechdrs[i].sh_size) {
+ printk(KERN_ERR "VPE program length %u truncated\n",
+ len);
+ return -ENOEXEC;
+ }
+
+ /* Mark all sections sh_addr with their address in the
+ temporary image. */
+ sechdrs[i].sh_addr = (size_t) hdr + sechdrs[i].sh_offset;
+
+ /* Internal symbols and strings. */
+ if (sechdrs[i].sh_type == SHT_SYMTAB) {
+ symindex = i;
+ strindex = sechdrs[i].sh_link;
+ strtab = (char *)hdr + sechdrs[strindex].sh_offset;
+ }
+ }
+
+ layout_sections(&mod, hdr, sechdrs, secstrings);
+
+ v->load_addr = alloc_progmem(mod.core_size);
+ memset(v->load_addr, 0, mod.core_size);
+
+ printk("VPE elf_loader: loading to %p\n", v->load_addr);
+
+ for (i = 0; i < hdr->e_shnum; i++) {
+ void *dest;
+
+ if (!(sechdrs[i].sh_flags & SHF_ALLOC))
+ continue;
+
+ dest = v->load_addr + sechdrs[i].sh_entsize;
+
+ if (sechdrs[i].sh_type != SHT_NOBITS)
+ memcpy(dest, (void *)sechdrs[i].sh_addr,
+ sechdrs[i].sh_size);
+ /* Update sh_addr to point to copy in image. */
+ sechdrs[i].sh_addr = (unsigned long)dest;
+ }
+
+ /* Fix up syms, so that st_value is a pointer to location. */
+ err =
+ simplify_symbols(sechdrs, symindex, strtab, secstrings,
+ hdr->e_shnum, &mod);
+ if (err < 0) {
+ printk(KERN_WARNING "VPE: unable to simplify symbols\n");
+ goto cleanup;
+ }
+
+ /* Now do relocations. */
+ for (i = 1; i < hdr->e_shnum; i++) {
+ const char *strtab = (char *)sechdrs[strindex].sh_addr;
+ unsigned int info = sechdrs[i].sh_info;
+
+ /* Not a valid relocation section? */
+ if (info >= hdr->e_shnum)
+ continue;
+
+ /* Don't bother with non-allocated sections */
+ if (!(sechdrs[info].sh_flags & SHF_ALLOC))
+ continue;
+
+ if (sechdrs[i].sh_type == SHT_REL)
+ err =
+ apply_relocations(sechdrs, strtab, symindex, i, &mod);
+ else if (sechdrs[i].sh_type == SHT_RELA)
+ err = apply_relocate_add(sechdrs, strtab, symindex, i,
+ &mod);
+ if (err < 0) {
+ printk(KERN_WARNING
+ "vpe_elfload: error in relocations err %ld\n",
+ err);
+ goto cleanup;
+ }
+ }
+
+ /* make sure it's physically written out */
+ flush_icache_range((unsigned long)v->load_addr,
+ (unsigned long)v->load_addr + v->len);
+
+ if ((find_vpe_symbols(v, sechdrs, symindex, strtab, &mod)) < 0) {
+
+ printk(KERN_WARNING
+ "VPE: program doesn't contain __start or vpe_shared symbols\n");
+ err = -ENOEXEC;
+ }
+
+ printk(" elf loaded\n");
+
+cleanup:
+ return err;
+}
+
+static void dump_vpe(struct vpe * v)
+{
+ struct tc *t;
+
+ printk(KERN_DEBUG "VPEControl 0x%lx\n", read_vpe_c0_vpecontrol());
+ printk(KERN_DEBUG "VPEConf0 0x%lx\n", read_vpe_c0_vpeconf0());
+
+ list_for_each_entry(t, &vpecontrol.tc_list, list) {
+ dump_tc(t);
+ }
+}
+
+/* checks for VPE is unused and gets ready to load program */
+static int vpe_open(struct inode *inode, struct file *filp)
+{
+ int minor;
+ struct vpe *v;
+
+ /* assume only 1 device at the mo. */
+ if ((minor = MINOR(inode->i_rdev)) != 1) {
+ printk(KERN_WARNING "VPE: only vpe1 is supported\n");
+ return -ENODEV;
+ }
+
+ if ((v = get_vpe(minor)) == NULL) {
+ printk(KERN_WARNING "VPE: unable to get vpe\n");
+ return -ENODEV;
+ }
+
+ if (v->state != VPE_STATE_UNUSED) {
+ unsigned long tmp;
+ struct tc *t;
+
+ printk(KERN_WARNING "VPE: device %d already in use\n", minor);
+
+ dvpe();
+ dump_vpe(v);
+
+ printk(KERN_WARNING "VPE: re-initialising %d\n", minor);
+
+ release_progmem(v->load_addr);
+
+ t = get_tc(minor);
+ settc(minor);
+ tmp = read_tc_c0_tcstatus();
+
+ /* mark not allocated and not dynamically allocatable */
+ tmp &= ~(TCSTATUS_A | TCSTATUS_DA);
+ tmp |= TCSTATUS_IXMT; /* interrupt exempt */
+ write_tc_c0_tcstatus(tmp);
+
+ write_tc_c0_tchalt(TCHALT_H);
+
+ }
+
+ // allocate it so when we get write ops we know it's expected.
+ v->state = VPE_STATE_INUSE;
+
+ /* this of-course trashes what was there before... */
+ v->pbuffer = vmalloc(P_SIZE);
+ v->plen = P_SIZE;
+ v->load_addr = NULL;
+ v->len = 0;
+
+ return 0;
+}
+
+static int vpe_release(struct inode *inode, struct file *filp)
+{
+ int minor, ret = 0;
+ struct vpe *v;
+ Elf_Ehdr *hdr;
+
+ minor = MINOR(inode->i_rdev);
+ if ((v = get_vpe(minor)) == NULL)
+ return -ENODEV;
+
+ // simple case of fire and forget, so tell the VPE to run...
+
+ hdr = (Elf_Ehdr *) v->pbuffer;
+ if (memcmp(hdr->e_ident, ELFMAG, 4) == 0) {
+ if (vpe_elfload(v) >= 0)
+ vpe_run(v);
+ else {
+ printk(KERN_WARNING "VPE: ELF load failed.\n");
+ ret = -ENOEXEC;
+ }
+ } else {
+ printk(KERN_WARNING "VPE: only elf files are supported\n");
+ ret = -ENOEXEC;
+ }
+
+ // cleanup any temp buffers
+ if (v->pbuffer)
+ vfree(v->pbuffer);
+ v->plen = 0;
+ return ret;
+}
+
+static ssize_t vpe_write(struct file *file, const char __user * buffer,
+ size_t count, loff_t * ppos)
+{
+ int minor;
+ size_t ret = count;
+ struct vpe *v;
+
+ minor = MINOR(file->f_dentry->d_inode->i_rdev);
+ if ((v = get_vpe(minor)) == NULL)
+ return -ENODEV;
+
+ if (v->pbuffer == NULL) {
+ printk(KERN_ERR "vpe_write: no pbuffer\n");
+ return -ENOMEM;
+ }
+
+ if ((count + v->len) > v->plen) {
+ printk(KERN_WARNING
+ "VPE Loader: elf size too big. Perhaps strip uneeded symbols\n");
+ return -ENOMEM;
+ }
+
+ count -= copy_from_user(v->pbuffer + v->len, buffer, count);
+ if (!count) {
+ printk("vpe_write: copy_to_user failed\n");
+ return -EFAULT;
+ }
+
+ v->len += count;
+ return ret;
+}
+
+static struct file_operations vpe_fops = {
+ .owner = THIS_MODULE,
+ .open = vpe_open,
+ .release = vpe_release,
+ .write = vpe_write
+};
+
+/* module wrapper entry points */
+/* give me a vpe */
+vpe_handle vpe_alloc(void)
+{
+ int i;
+ struct vpe *v;
+
+ /* find a vpe */
+ for (i = 1; i < MAX_VPES; i++) {
+ if ((v = get_vpe(i)) != NULL) {
+ v->state = VPE_STATE_INUSE;
+ return v;
+ }
+ }
+ return NULL;
+}
+
+EXPORT_SYMBOL(vpe_alloc);
+
+/* start running from here */
+int vpe_start(vpe_handle vpe, unsigned long start)
+{
+ struct vpe *v = vpe;
+
+ v->__start = start;
+ return vpe_run(v);
+}
+
+EXPORT_SYMBOL(vpe_start);
+
+/* halt it for now */
+int vpe_stop(vpe_handle vpe)
+{
+ struct vpe *v = vpe;
+ struct tc *t;
+ unsigned int evpe_flags;
+
+ evpe_flags = dvpe();
+
+ if ((t = list_entry(v->tc.next, struct tc, tc)) != NULL) {
+
+ settc(t->index);
+ write_vpe_c0_vpeconf0(read_vpe_c0_vpeconf0() & ~VPECONF0_VPA);
+ }
+
+ evpe(evpe_flags);
+
+ return 0;
+}
+
+EXPORT_SYMBOL(vpe_stop);
+
+/* I've done with it thank you */
+int vpe_free(vpe_handle vpe)
+{
+ struct vpe *v = vpe;
+ struct tc *t;
+ unsigned int evpe_flags;
+
+ if ((t = list_entry(v->tc.next, struct tc, tc)) == NULL) {
+ return -ENOEXEC;
+ }
+
+ evpe_flags = dvpe();
+
+ /* Put MVPE's into 'configuration state' */
+ set_c0_mvpcontrol(MVPCONTROL_VPC);
+
+ settc(t->index);
+ write_vpe_c0_vpeconf0(read_vpe_c0_vpeconf0() & ~VPECONF0_VPA);
+
+ /* mark the TC unallocated and halt'ed */
+ write_tc_c0_tcstatus(read_tc_c0_tcstatus() & ~TCSTATUS_A);
+ write_tc_c0_tchalt(TCHALT_H);
+
+ v->state = VPE_STATE_UNUSED;
+
+ clear_c0_mvpcontrol(MVPCONTROL_VPC);
+ evpe(evpe_flags);
+
+ return 0;
+}
+
+EXPORT_SYMBOL(vpe_free);
+
+void *vpe_get_shared(int index)
+{
+ struct vpe *v;
+
+ if ((v = get_vpe(index)) == NULL) {
+ printk(KERN_WARNING "vpe: invalid vpe index %d\n", index);
+ return NULL;
+ }
+
+ return v->shared_ptr;
+}
+
+EXPORT_SYMBOL(vpe_get_shared);
+
+static int __init vpe_module_init(void)
+{
+ struct vpe *v = NULL;
+ struct tc *t;
+ unsigned long val;
+ int i;
+
+ if (!cpu_has_mipsmt) {
+ printk("VPE loader: not a MIPS MT capable processor\n");
+ return -ENODEV;
+ }
+
+ if ((major = register_chrdev(0, module_name, &vpe_fops) < 0)) {
+ printk("VPE loader: unable to register character device\n");
+ return major;
+ }
+
+ dmt();
+ dvpe();
+
+ /* Put MVPE's into 'configuration state' */
+ set_c0_mvpcontrol(MVPCONTROL_VPC);
+
+ /* dump_mtregs(); */
+
+ INIT_LIST_HEAD(&vpecontrol.vpe_list);
+ INIT_LIST_HEAD(&vpecontrol.tc_list);
+
+ val = read_c0_mvpconf0();
+ for (i = 0; i < ((val & MVPCONF0_PTC) + 1); i++) {
+ t = alloc_tc(i);
+
+ /* VPE's */
+ if (i < ((val & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT) + 1) {
+ settc(i);
+
+ if ((v = alloc_vpe(i)) == NULL) {
+ printk(KERN_WARNING "VPE: unable to allocate VPE\n");
+ return -ENODEV;
+ }
+
+ list_add(&t->tc, &v->tc); /* add the tc to the list of this vpe's tc's. */
+
+ /* deactivate all but vpe0 */
+ if (i != 0) {
+ unsigned long tmp = read_vpe_c0_vpeconf0();
+
+ tmp &= ~VPECONF0_VPA;
+
+ /* master VPE */
+ tmp |= VPECONF0_MVP;
+ write_vpe_c0_vpeconf0(tmp);
+ }
+
+ /* disable multi-threading with TC's */
+ write_vpe_c0_vpecontrol(read_vpe_c0_vpecontrol() & ~VPECONTROL_TE);
+
+ if (i != 0) {
+ write_vpe_c0_status((read_c0_status() &
+ ~(ST0_IM | ST0_IE | ST0_KSU))
+ | ST0_CU0);
+
+ /* set config to be the same as vpe0, particularly kseg0 coherency alg */
+ write_vpe_c0_config(read_c0_config());
+ }
+
+ }
+
+ /* TC's */
+ t->pvpe = v; /* set the parent vpe */
+
+ if (i != 0) {
+ unsigned long tmp;
+
+ /* tc 0 will of course be running.... */
+ if (i == 0)
+ t->state = TC_STATE_RUNNING;
+
+ settc(i);
+
+ /* bind a TC to each VPE, May as well put all excess TC's
+ on the last VPE */
+ if (i >= (((val & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT) + 1))
+ write_tc_c0_tcbind(read_tc_c0_tcbind() |
+ ((val & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT));
+ else
+ write_tc_c0_tcbind(read_tc_c0_tcbind() | i);
+
+ tmp = read_tc_c0_tcstatus();
+
+ /* mark not allocated and not dynamically allocatable */
+ tmp &= ~(TCSTATUS_A | TCSTATUS_DA);
+ tmp |= TCSTATUS_IXMT; /* interrupt exempt */
+ write_tc_c0_tcstatus(tmp);
+
+ write_tc_c0_tchalt(TCHALT_H);
+ }
+ }
+
+ /* release config state */
+ clear_c0_mvpcontrol(MVPCONTROL_VPC);
+
+ return 0;
+}
+
+static void __exit vpe_module_exit(void)
+{
+ struct vpe *v, *n;
+
+ list_for_each_entry_safe(v, n, &vpecontrol.vpe_list, list) {
+ if (v->state != VPE_STATE_UNUSED) {
+ release_vpe(v);
+ }
+ }
+
+ unregister_chrdev(major, module_name);
+}
+
+module_init(vpe_module_init);
+module_exit(vpe_module_exit);
+MODULE_DESCRIPTION("MIPS VPE Loader");
+MODULE_AUTHOR("Elizabeth Clarke, MIPS Technologies, Inc");
+MODULE_LICENSE("GPL");
diff --git a/arch/mips/lasat/Kconfig b/arch/mips/lasat/Kconfig
new file mode 100644
index 000000000000..1d2ee8a9be13
--- /dev/null
+++ b/arch/mips/lasat/Kconfig
@@ -0,0 +1,15 @@
+config PICVUE
+ tristate "PICVUE LCD display driver"
+ depends on LASAT
+
+config PICVUE_PROC
+ tristate "PICVUE LCD display driver /proc interface"
+ depends on PICVUE
+
+config DS1603
+ bool "DS1603 RTC driver"
+ depends on LASAT
+
+config LASAT_SYSCTL
+ bool "LASAT sysctl interface"
+ depends on LASAT
diff --git a/arch/mips/lasat/ds1603.c b/arch/mips/lasat/ds1603.c
index 9d7812e03dcd..7dced67c55eb 100644
--- a/arch/mips/lasat/ds1603.c
+++ b/arch/mips/lasat/ds1603.c
@@ -8,6 +8,7 @@
#include <asm/lasat/lasat.h>
#include <linux/delay.h>
#include <asm/lasat/ds1603.h>
+#include <asm/time.h>
#include "ds1603.h"
@@ -138,19 +139,27 @@ static void rtc_end_op(void)
unsigned long ds1603_read(void)
{
unsigned long word;
+ unsigned long flags;
+
+ spin_lock_irqsave(&rtc_lock, flags);
rtc_init_op();
rtc_write_byte(READ_TIME_CMD);
word = rtc_read_word();
rtc_end_op();
+ spin_unlock_irqrestore(&rtc_lock, flags);
return word;
}
int ds1603_set(unsigned long time)
{
+ unsigned long flags;
+
+ spin_lock_irqsave(&rtc_lock, flags);
rtc_init_op();
rtc_write_byte(SET_TIME_CMD);
rtc_write_word(time);
rtc_end_op();
+ spin_unlock_irqrestore(&rtc_lock, flags);
return 0;
}
diff --git a/arch/mips/lasat/interrupt.c b/arch/mips/lasat/interrupt.c
index c90da1639440..852a41901a5e 100644
--- a/arch/mips/lasat/interrupt.c
+++ b/arch/mips/lasat/interrupt.c
@@ -71,14 +71,13 @@ static void end_lasat_irq(unsigned int irq)
}
static struct hw_interrupt_type lasat_irq_type = {
- "Lasat",
- startup_lasat_irq,
- shutdown_lasat_irq,
- enable_lasat_irq,
- disable_lasat_irq,
- mask_and_ack_lasat_irq,
- end_lasat_irq,
- NULL
+ .typename = "Lasat",
+ .startup = startup_lasat_irq,
+ .shutdown = shutdown_lasat_irq,
+ .enable = enable_lasat_irq,
+ .disable = disable_lasat_irq,
+ .ack = mask_and_ack_lasat_irq,
+ .end = end_lasat_irq,
};
static inline int ls1bit32(unsigned int x)
diff --git a/arch/mips/lasat/setup.c b/arch/mips/lasat/setup.c
index f2604fab9a99..dcd819d57dae 100644
--- a/arch/mips/lasat/setup.c
+++ b/arch/mips/lasat/setup.c
@@ -155,7 +155,7 @@ void __init serial_init(void)
}
#endif
-static int __init lasat_setup(void)
+void __init plat_setup(void)
{
int i;
lasat_misc = &lasat_misc_info[mips_machtype];
@@ -185,8 +185,4 @@ static int __init lasat_setup(void)
change_c0_status(ST0_BEV,0);
prom_printf("Lasat specific initialization complete\n");
-
- return 0;
}
-
-early_initcall(lasat_setup);
diff --git a/arch/mips/lib-32/dump_tlb.c b/arch/mips/lib-32/dump_tlb.c
index 019ac8f005d7..46519f4331eb 100644
--- a/arch/mips/lib-32/dump_tlb.c
+++ b/arch/mips/lib-32/dump_tlb.c
@@ -20,16 +20,25 @@
static inline const char *msk2str(unsigned int mask)
{
switch (mask) {
- case PM_4K: return "4kb";
- case PM_16K: return "16kb";
- case PM_64K: return "64kb";
- case PM_256K: return "256kb";
+ case PM_4K:
+ return "4kb";
+ case PM_16K:
+ return "16kb";
+ case PM_64K:
+ return "64kb";
+ case PM_256K:
+ return "256kb";
#ifndef CONFIG_CPU_VR41XX
- case PM_1M: return "1Mb";
- case PM_4M: return "4Mb";
- case PM_16M: return "16Mb";
- case PM_64M: return "64Mb";
- case PM_256M: return "256Mb";
+ case PM_1M:
+ return "1Mb";
+ case PM_4M:
+ return "4Mb";
+ case PM_16M:
+ return "16Mb";
+ case PM_64M:
+ return "64Mb";
+ case PM_256M:
+ return "256Mb";
#endif
}
@@ -47,7 +56,7 @@ void dump_tlb(int first, int last)
unsigned int pagemask, c0, c1, asid;
unsigned long long entrylo0, entrylo1;
unsigned long entryhi;
- int i;
+ int i;
asid = read_c0_entryhi() & 0xff;
@@ -58,7 +67,7 @@ void dump_tlb(int first, int last)
tlb_read();
BARRIER();
pagemask = read_c0_pagemask();
- entryhi = read_c0_entryhi();
+ entryhi = read_c0_entryhi();
entrylo0 = read_c0_entrylo0();
entrylo1 = read_c0_entrylo1();
@@ -78,13 +87,11 @@ void dump_tlb(int first, int last)
printk("\t\t\t[pa=%08Lx c=%d d=%d v=%d g=%Ld]\n",
(entrylo0 << 6) & PAGE_MASK, c0,
(entrylo0 & 4) ? 1 : 0,
- (entrylo0 & 2) ? 1 : 0,
- (entrylo0 & 1));
+ (entrylo0 & 2) ? 1 : 0, (entrylo0 & 1));
printk("\t\t\t[pa=%08Lx c=%d d=%d v=%d g=%Ld]\n",
(entrylo1 << 6) & PAGE_MASK, c1,
(entrylo1 & 4) ? 1 : 0,
- (entrylo1 & 2) ? 1 : 0,
- (entrylo1 & 1));
+ (entrylo1 & 2) ? 1 : 0, (entrylo1 & 1));
printk("\n");
}
}
@@ -99,7 +106,7 @@ void dump_tlb_all(void)
void dump_tlb_wired(void)
{
- int wired;
+ int wired;
wired = read_c0_wired();
printk("Wired: %d", wired);
@@ -138,9 +145,10 @@ void dump_tlb_nonwired(void)
void dump_list_process(struct task_struct *t, void *address)
{
- pgd_t *page_dir, *pgd;
- pmd_t *pmd;
- pte_t *pte, page;
+ pgd_t *page_dir, *pgd;
+ pud_t *pud;
+ pmd_t *pmd;
+ pte_t *pte, page;
unsigned long addr, val;
addr = (unsigned long) address;
@@ -152,21 +160,27 @@ void dump_list_process(struct task_struct *t, void *address)
if (addr > KSEG0)
page_dir = pgd_offset_k(0);
- else
+ else if (t->mm) {
page_dir = pgd_offset(t->mm, 0);
- printk("page_dir == %08x\n", (unsigned int) page_dir);
+ printk("page_dir == %08x\n", (unsigned int) page_dir);
+ } else
+ printk("Current thread has no mm\n");
if (addr > KSEG0)
pgd = pgd_offset_k(addr);
- else
+ else if (t->mm) {
pgd = pgd_offset(t->mm, addr);
- printk("pgd == %08x, ", (unsigned int) pgd);
+ printk("pgd == %08x, ", (unsigned int) pgd);
+ pud = pud_offset(pgd, addr);
+ printk("pud == %08x, ", (unsigned int) pud);
- pmd = pmd_offset(pgd, addr);
- printk("pmd == %08x, ", (unsigned int) pmd);
+ pmd = pmd_offset(pud, addr);
+ printk("pmd == %08x, ", (unsigned int) pmd);
- pte = pte_offset(pmd, addr);
- printk("pte == %08x, ", (unsigned int) pte);
+ pte = pte_offset(pmd, addr);
+ printk("pte == %08x, ", (unsigned int) pte);
+ } else
+ printk("Current thread has no mm\n");
page = *pte;
#ifdef CONFIG_64BIT_PHYS_ADDR
@@ -176,14 +190,22 @@ void dump_list_process(struct task_struct *t, void *address)
#endif
val = pte_val(page);
- if (val & _PAGE_PRESENT) printk("present ");
- if (val & _PAGE_READ) printk("read ");
- if (val & _PAGE_WRITE) printk("write ");
- if (val & _PAGE_ACCESSED) printk("accessed ");
- if (val & _PAGE_MODIFIED) printk("modified ");
- if (val & _PAGE_R4KBUG) printk("r4kbug ");
- if (val & _PAGE_GLOBAL) printk("global ");
- if (val & _PAGE_VALID) printk("valid ");
+ if (val & _PAGE_PRESENT)
+ printk("present ");
+ if (val & _PAGE_READ)
+ printk("read ");
+ if (val & _PAGE_WRITE)
+ printk("write ");
+ if (val & _PAGE_ACCESSED)
+ printk("accessed ");
+ if (val & _PAGE_MODIFIED)
+ printk("modified ");
+ if (val & _PAGE_R4KBUG)
+ printk("r4kbug ");
+ if (val & _PAGE_GLOBAL)
+ printk("global ");
+ if (val & _PAGE_VALID)
+ printk("valid ");
printk("\n");
}
@@ -194,14 +216,16 @@ void dump_list_current(void *address)
unsigned int vtop(void *address)
{
- pgd_t *pgd;
- pmd_t *pmd;
- pte_t *pte;
+ pgd_t *pgd;
+ pud_t *pud;
+ pmd_t *pmd;
+ pte_t *pte;
unsigned int addr, paddr;
addr = (unsigned long) address;
pgd = pgd_offset(current->mm, addr);
- pmd = pmd_offset(pgd, addr);
+ pud = pud_offset(pgd, addr);
+ pmd = pmd_offset(pud, addr);
pte = pte_offset(pmd, addr);
paddr = (KSEG1 | (unsigned int) pte_val(*pte)) & PAGE_MASK;
paddr |= (addr & ~PAGE_MASK);
@@ -214,9 +238,9 @@ void dump16(unsigned long *p)
int i;
for (i = 0; i < 8; i++) {
- printk("*%08lx == %08lx, ", (unsigned long)p, *p);
+ printk("*%08lx == %08lx, ", (unsigned long) p, *p);
p++;
- printk("*%08lx == %08lx\n", (unsigned long)p, *p);
+ printk("*%08lx == %08lx\n", (unsigned long) p, *p);
p++;
}
}
diff --git a/arch/mips/lib-32/r3k_dump_tlb.c b/arch/mips/lib-32/r3k_dump_tlb.c
index a878224004e5..4f2cb74f0766 100644
--- a/arch/mips/lib-32/r3k_dump_tlb.c
+++ b/arch/mips/lib-32/r3k_dump_tlb.c
@@ -105,6 +105,7 @@ void dump_tlb_nonwired(void)
void dump_list_process(struct task_struct *t, void *address)
{
pgd_t *page_dir, *pgd;
+ pud_t *pud;
pmd_t *pmd;
pte_t *pte, page;
unsigned int addr;
@@ -121,7 +122,10 @@ void dump_list_process(struct task_struct *t, void *address)
pgd = pgd_offset(t->mm, addr);
printk("pgd == %08x, ", (unsigned int) pgd);
- pmd = pmd_offset(pgd, addr);
+ pud = pud_offset(pgd, addr);
+ printk("pud == %08x, ", (unsigned int) pud);
+
+ pmd = pmd_offset(pud, addr);
printk("pmd == %08x, ", (unsigned int) pmd);
pte = pte_offset(pmd, addr);
@@ -149,13 +153,15 @@ void dump_list_current(void *address)
unsigned int vtop(void *address)
{
pgd_t *pgd;
+ pud_t *pud;
pmd_t *pmd;
pte_t *pte;
unsigned int addr, paddr;
addr = (unsigned long) address;
pgd = pgd_offset(current->mm, addr);
- pmd = pmd_offset(pgd, addr);
+ pud = pud_offset(pgd, addr);
+ pmd = pmd_offset(pud, addr);
pte = pte_offset(pmd, addr);
paddr = (KSEG1 | (unsigned int) pte_val(*pte)) & PAGE_MASK;
paddr |= (addr & ~PAGE_MASK);
diff --git a/arch/mips/lib-64/dump_tlb.c b/arch/mips/lib-64/dump_tlb.c
index 42f88e055b4c..11a5f015f040 100644
--- a/arch/mips/lib-64/dump_tlb.c
+++ b/arch/mips/lib-64/dump_tlb.c
@@ -140,6 +140,7 @@ void dump_tlb_nonwired(void)
void dump_list_process(struct task_struct *t, void *address)
{
pgd_t *page_dir, *pgd;
+ pud_t *pud;
pmd_t *pmd;
pte_t *pte, page;
unsigned long addr, val;
@@ -155,7 +156,10 @@ void dump_list_process(struct task_struct *t, void *address)
pgd = pgd_offset(t->mm, addr);
printk("pgd == %016lx\n", (unsigned long) pgd);
- pmd = pmd_offset(pgd, addr);
+ pud = pud_offset(pgd, addr);
+ printk("pud == %016lx\n", (unsigned long) pud);
+
+ pmd = pmd_offset(pud, addr);
printk("pmd == %016lx\n", (unsigned long) pmd);
pte = pte_offset(pmd, addr);
@@ -184,13 +188,15 @@ void dump_list_current(void *address)
unsigned int vtop(void *address)
{
pgd_t *pgd;
+ pud_t *pud;
pmd_t *pmd;
pte_t *pte;
unsigned int addr, paddr;
addr = (unsigned long) address;
pgd = pgd_offset(current->mm, addr);
- pmd = pmd_offset(pgd, addr);
+ pud = pud_offset(pgd, addr);
+ pmd = pmd_offset(pud, addr);
pte = pte_offset(pmd, addr);
paddr = (CKSEG1 | (unsigned int) pte_val(*pte)) & PAGE_MASK;
paddr |= (addr & ~PAGE_MASK);
diff --git a/arch/mips/lib/Makefile b/arch/mips/lib/Makefile
index 037303412909..cf12caf80774 100644
--- a/arch/mips/lib/Makefile
+++ b/arch/mips/lib/Makefile
@@ -2,8 +2,8 @@
# Makefile for MIPS-specific library files..
#
-lib-y += csum_partial_copy.o memcpy.o promlib.o \
- strlen_user.o strncpy_user.o strnlen_user.o
+lib-y += csum_partial_copy.o memcpy.o promlib.o strlen_user.o strncpy_user.o \
+ strnlen_user.o uncached.o
obj-y += iomap.o
diff --git a/arch/mips/lib/csum_partial_copy.c b/arch/mips/lib/csum_partial_copy.c
index ffed0a6a1c16..6e9f366f961d 100644
--- a/arch/mips/lib/csum_partial_copy.c
+++ b/arch/mips/lib/csum_partial_copy.c
@@ -16,8 +16,8 @@
/*
* copy while checksumming, otherwise like csum_partial
*/
-unsigned int csum_partial_copy_nocheck(const unsigned char *src, unsigned char *dst,
- int len, unsigned int sum)
+unsigned int csum_partial_copy_nocheck(const unsigned char *src,
+ unsigned char *dst, int len, unsigned int sum)
{
/*
* It's 2:30 am and I don't feel like doing it real ...
@@ -33,8 +33,8 @@ unsigned int csum_partial_copy_nocheck(const unsigned char *src, unsigned char *
* Copy from userspace and compute checksum. If we catch an exception
* then zero the rest of the buffer.
*/
-unsigned int csum_partial_copy_from_user (const unsigned char *src, unsigned char *dst,
- int len, unsigned int sum, int *err_ptr)
+unsigned int csum_partial_copy_from_user (const unsigned char __user *src,
+ unsigned char *dst, int len, unsigned int sum, int *err_ptr)
{
int missing;
diff --git a/arch/mips/lib/memcpy.S b/arch/mips/lib/memcpy.S
index a78865f76547..7f9aafa4d80e 100644
--- a/arch/mips/lib/memcpy.S
+++ b/arch/mips/lib/memcpy.S
@@ -13,6 +13,21 @@
* Mnemonic names for arguments to memcpy/__copy_user
*/
#include <linux/config.h>
+
+/*
+ * Hack to resolve longstanding prefetch issue
+ *
+ * Prefetching may be fatal on some systems if we're prefetching beyond the
+ * end of memory on some systems. It's also a seriously bad idea on non
+ * dma-coherent systems.
+ */
+#if !defined(CONFIG_DMA_COHERENT) || !defined(CONFIG_DMA_IP27)
+#undef CONFIG_CPU_HAS_PREFETCH
+#endif
+#ifdef CONFIG_MIPS_MALTA
+#undef CONFIG_CPU_HAS_PREFETCH
+#endif
+
#include <asm/asm.h>
#include <asm/asm-offsets.h>
#include <asm/regdef.h>
diff --git a/arch/mips/lib/uncached.c b/arch/mips/lib/uncached.c
new file mode 100644
index 000000000000..98ce89f8068b
--- /dev/null
+++ b/arch/mips/lib/uncached.c
@@ -0,0 +1,76 @@
+/*
+ * 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 Thiemo Seufer
+ * Copyright (C) 2005 MIPS Technologies, Inc. All rights reserved.
+ * Author: Maciej W. Rozycki <macro@mips.com>
+ */
+
+#include <linux/init.h>
+
+#include <asm/addrspace.h>
+#include <asm/bug.h>
+
+#ifndef CKSEG2
+#define CKSEG2 CKSSEG
+#endif
+#ifndef TO_PHYS_MASK
+#define TO_PHYS_MASK -1
+#endif
+
+/*
+ * FUNC is executed in one of the uncached segments, depending on its
+ * original address as follows:
+ *
+ * 1. If the original address is in CKSEG0 or CKSEG1, then the uncached
+ * segment used is CKSEG1.
+ * 2. If the original address is in XKPHYS, then the uncached segment
+ * used is XKPHYS(2).
+ * 3. Otherwise it's a bug.
+ *
+ * The same remapping is done with the stack pointer. Stack handling
+ * works because we don't handle stack arguments or more complex return
+ * values, so we can avoid sharing the same stack area between a cached
+ * and the uncached mode.
+ */
+unsigned long __init run_uncached(void *func)
+{
+ register long sp __asm__("$sp");
+ register long ret __asm__("$2");
+ long lfunc = (long)func, ufunc;
+ long usp;
+
+ if (sp >= (long)CKSEG0 && sp < (long)CKSEG2)
+ usp = CKSEG1ADDR(sp);
+ else if ((long long)sp >= (long long)PHYS_TO_XKPHYS(0LL, 0) &&
+ (long long)sp < (long long)PHYS_TO_XKPHYS(8LL, 0))
+ usp = PHYS_TO_XKPHYS((long long)K_CALG_UNCACHED,
+ XKPHYS_TO_PHYS((long long)sp));
+ else {
+ BUG();
+ usp = sp;
+ }
+ if (lfunc >= (long)CKSEG0 && lfunc < (long)CKSEG2)
+ ufunc = CKSEG1ADDR(lfunc);
+ else if ((long long)lfunc >= (long long)PHYS_TO_XKPHYS(0LL, 0) &&
+ (long long)lfunc < (long long)PHYS_TO_XKPHYS(8LL, 0))
+ ufunc = PHYS_TO_XKPHYS((long long)K_CALG_UNCACHED,
+ XKPHYS_TO_PHYS((long long)lfunc));
+ else {
+ BUG();
+ ufunc = lfunc;
+ }
+
+ __asm__ __volatile__ (
+ " move $16, $sp\n"
+ " move $sp, %1\n"
+ " jalr %2\n"
+ " move $sp, $16"
+ : "=r" (ret)
+ : "r" (usp), "r" (ufunc)
+ : "$16", "$31");
+
+ return ret;
+}
diff --git a/arch/mips/math-emu/cp1emu.c b/arch/mips/math-emu/cp1emu.c
index 99c550632d44..aa5818a0d884 100644
--- a/arch/mips/math-emu/cp1emu.c
+++ b/arch/mips/math-emu/cp1emu.c
@@ -70,7 +70,7 @@ static int fpux_emu(struct pt_regs *,
/* Further private data for which no space exists in mips_fpu_soft_struct */
-struct mips_fpu_emulator_private fpuemuprivate;
+struct mips_fpu_emulator_stats fpuemustats;
/* Control registers */
@@ -79,7 +79,17 @@ struct mips_fpu_emulator_private fpuemuprivate;
/* Convert Mips rounding mode (0..3) to IEEE library modes. */
static const unsigned char ieee_rm[4] = {
- IEEE754_RN, IEEE754_RZ, IEEE754_RU, IEEE754_RD
+ [FPU_CSR_RN] = IEEE754_RN,
+ [FPU_CSR_RZ] = IEEE754_RZ,
+ [FPU_CSR_RU] = IEEE754_RU,
+ [FPU_CSR_RD] = IEEE754_RD,
+};
+/* Convert IEEE library modes to Mips rounding mode (0..3). */
+static const unsigned char mips_rm[4] = {
+ [IEEE754_RN] = FPU_CSR_RN,
+ [IEEE754_RZ] = FPU_CSR_RZ,
+ [IEEE754_RD] = FPU_CSR_RD,
+ [IEEE754_RU] = FPU_CSR_RU,
};
#if __mips >= 4
@@ -196,11 +206,11 @@ static int isBranchInstr(mips_instruction * i)
static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_soft_struct *ctx)
{
mips_instruction ir;
- vaddr_t emulpc, contpc;
+ void * emulpc, *contpc;
unsigned int cond;
- if (get_user(ir, (mips_instruction *) xcp->cp0_epc)) {
- fpuemuprivate.stats.errors++;
+ if (get_user(ir, (mips_instruction __user *) xcp->cp0_epc)) {
+ fpuemustats.errors++;
return SIGBUS;
}
@@ -221,41 +231,39 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_soft_struct *ctx)
* Linux MIPS branch emulator operates on context, updating the
* cp0_epc.
*/
- emulpc = REG_TO_VA(xcp->cp0_epc + 4); /* Snapshot emulation target */
+ emulpc = (void *) (xcp->cp0_epc + 4); /* Snapshot emulation target */
if (__compute_return_epc(xcp)) {
#ifdef CP1DBG
printk("failed to emulate branch at %p\n",
- REG_TO_VA(xcp->cp0_epc));
+ (void *) (xcp->cp0_epc));
#endif
return SIGILL;
}
- if (get_user(ir, (mips_instruction *) emulpc)) {
- fpuemuprivate.stats.errors++;
+ if (get_user(ir, (mips_instruction __user *) emulpc)) {
+ fpuemustats.errors++;
return SIGBUS;
}
/* __compute_return_epc() will have updated cp0_epc */
- contpc = REG_TO_VA xcp->cp0_epc;
+ contpc = (void *) xcp->cp0_epc;
/* In order not to confuse ptrace() et al, tweak context */
- xcp->cp0_epc = VA_TO_REG emulpc - 4;
- }
- else {
- emulpc = REG_TO_VA xcp->cp0_epc;
- contpc = REG_TO_VA(xcp->cp0_epc + 4);
+ xcp->cp0_epc = (unsigned long) emulpc - 4;
+ } else {
+ emulpc = (void *) xcp->cp0_epc;
+ contpc = (void *) (xcp->cp0_epc + 4);
}
emul:
- fpuemuprivate.stats.emulated++;
+ fpuemustats.emulated++;
switch (MIPSInst_OPCODE(ir)) {
-#ifndef SINGLE_ONLY_FPU
case ldc1_op:{
- u64 *va = REG_TO_VA(xcp->regs[MIPSInst_RS(ir)] +
+ u64 __user *va = (u64 __user *) (xcp->regs[MIPSInst_RS(ir)] +
MIPSInst_SIMM(ir));
u64 val;
- fpuemuprivate.stats.loads++;
+ fpuemustats.loads++;
if (get_user(val, va)) {
- fpuemuprivate.stats.errors++;
+ fpuemustats.errors++;
return SIGBUS;
}
DITOREG(val, MIPSInst_RT(ir));
@@ -263,55 +271,42 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_soft_struct *ctx)
}
case sdc1_op:{
- u64 *va = REG_TO_VA(xcp->regs[MIPSInst_RS(ir)] +
+ u64 __user *va = (u64 __user *) (xcp->regs[MIPSInst_RS(ir)] +
MIPSInst_SIMM(ir));
u64 val;
- fpuemuprivate.stats.stores++;
+ fpuemustats.stores++;
DIFROMREG(val, MIPSInst_RT(ir));
if (put_user(val, va)) {
- fpuemuprivate.stats.errors++;
+ fpuemustats.errors++;
return SIGBUS;
}
break;
}
-#endif
case lwc1_op:{
- u32 *va = REG_TO_VA(xcp->regs[MIPSInst_RS(ir)] +
+ u32 __user *va = (u32 __user *) (xcp->regs[MIPSInst_RS(ir)] +
MIPSInst_SIMM(ir));
u32 val;
- fpuemuprivate.stats.loads++;
+ fpuemustats.loads++;
if (get_user(val, va)) {
- fpuemuprivate.stats.errors++;
+ fpuemustats.errors++;
return SIGBUS;
}
-#ifdef SINGLE_ONLY_FPU
- if (MIPSInst_RT(ir) & 1) {
- /* illegal register in single-float mode */
- return SIGILL;
- }
-#endif
SITOREG(val, MIPSInst_RT(ir));
break;
}
case swc1_op:{
- u32 *va = REG_TO_VA(xcp->regs[MIPSInst_RS(ir)] +
+ u32 __user *va = (u32 __user *) (xcp->regs[MIPSInst_RS(ir)] +
MIPSInst_SIMM(ir));
u32 val;
- fpuemuprivate.stats.stores++;
-#ifdef SINGLE_ONLY_FPU
- if (MIPSInst_RT(ir) & 1) {
- /* illegal register in single-float mode */
- return SIGILL;
- }
-#endif
+ fpuemustats.stores++;
SIFROMREG(val, MIPSInst_RT(ir));
if (put_user(val, va)) {
- fpuemuprivate.stats.errors++;
+ fpuemustats.errors++;
return SIGBUS;
}
break;
@@ -320,7 +315,7 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_soft_struct *ctx)
case cop1_op:
switch (MIPSInst_RS(ir)) {
-#if defined(__mips64) && !defined(SINGLE_ONLY_FPU)
+#if defined(__mips64)
case dmfc_op:
/* copregister fs -> gpr[rt] */
if (MIPSInst_RT(ir) != 0) {
@@ -337,12 +332,6 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_soft_struct *ctx)
case mfc_op:
/* copregister rd -> gpr[rt] */
-#ifdef SINGLE_ONLY_FPU
- if (MIPSInst_RD(ir) & 1) {
- /* illegal register in single-float mode */
- return SIGILL;
- }
-#endif
if (MIPSInst_RT(ir) != 0) {
SIFROMREG(xcp->regs[MIPSInst_RT(ir)],
MIPSInst_RD(ir));
@@ -351,12 +340,6 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_soft_struct *ctx)
case mtc_op:
/* copregister rd <- rt */
-#ifdef SINGLE_ONLY_FPU
- if (MIPSInst_RD(ir) & 1) {
- /* illegal register in single-float mode */
- return SIGILL;
- }
-#endif
SITOREG(xcp->regs[MIPSInst_RT(ir)], MIPSInst_RD(ir));
break;
@@ -369,9 +352,10 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_soft_struct *ctx)
}
if (MIPSInst_RD(ir) == FPCREG_CSR) {
value = ctx->fcr31;
+ value = (value & ~0x3) | mips_rm[value & 0x3];
#ifdef CSRTRACE
printk("%p gpr[%d]<-csr=%08x\n",
- REG_TO_VA(xcp->cp0_epc),
+ (void *) (xcp->cp0_epc),
MIPSInst_RT(ir), value);
#endif
}
@@ -398,14 +382,13 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_soft_struct *ctx)
if (MIPSInst_RD(ir) == FPCREG_CSR) {
#ifdef CSRTRACE
printk("%p gpr[%d]->csr=%08x\n",
- REG_TO_VA(xcp->cp0_epc),
+ (void *) (xcp->cp0_epc),
MIPSInst_RT(ir), value);
#endif
- ctx->fcr31 = value;
- /* copy new rounding mode and
- flush bit to ieee library state! */
- ieee754_csr.nod = (ctx->fcr31 & 0x1000000) != 0;
- ieee754_csr.rm = ieee_rm[value & 0x3];
+ value &= (FPU_CSR_FLUSH | FPU_CSR_ALL_E | FPU_CSR_ALL_S | 0x03);
+ ctx->fcr31 &= ~(FPU_CSR_FLUSH | FPU_CSR_ALL_E | FPU_CSR_ALL_S | 0x03);
+ /* convert to ieee library modes */
+ ctx->fcr31 |= (value & ~0x3) | ieee_rm[value & 0x3];
}
if ((ctx->fcr31 >> 5) & ctx->fcr31 & FPU_CSR_ALL_E) {
return SIGFPE;
@@ -445,20 +428,20 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_soft_struct *ctx)
* instruction
*/
xcp->cp0_epc += 4;
- contpc = REG_TO_VA
+ contpc = (void *)
(xcp->cp0_epc +
(MIPSInst_SIMM(ir) << 2));
- if (get_user(ir, (mips_instruction *)
- REG_TO_VA xcp->cp0_epc)) {
- fpuemuprivate.stats.errors++;
+ if (get_user(ir,
+ (mips_instruction __user *) xcp->cp0_epc)) {
+ fpuemustats.errors++;
return SIGBUS;
}
switch (MIPSInst_OPCODE(ir)) {
case lwc1_op:
case swc1_op:
-#if (__mips >= 2 || __mips64) && !defined(SINGLE_ONLY_FPU)
+#if (__mips >= 2 || defined(__mips64))
case ldc1_op:
case sdc1_op:
#endif
@@ -480,7 +463,7 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_soft_struct *ctx)
* Single step the non-cp1
* instruction in the dslot
*/
- return mips_dsemul(xcp, ir, VA_TO_REG contpc);
+ return mips_dsemul(xcp, ir, (unsigned long) contpc);
}
else {
/* branch not taken */
@@ -539,8 +522,9 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_soft_struct *ctx)
}
/* we did it !! */
- xcp->cp0_epc = VA_TO_REG(contpc);
+ xcp->cp0_epc = (unsigned long) contpc;
xcp->cp0_cause &= ~CAUSEF_BD;
+
return 0;
}
@@ -570,7 +554,7 @@ static const unsigned char cmptab[8] = {
static ieee754##p fpemu_##p##_##name (ieee754##p r, ieee754##p s, \
ieee754##p t) \
{ \
- struct ieee754_csr ieee754_csr_save; \
+ struct _ieee754_csr ieee754_csr_save; \
s = f1 (s, t); \
ieee754_csr_save = ieee754_csr; \
s = f2 (s, r); \
@@ -616,54 +600,38 @@ static int fpux_emu(struct pt_regs *xcp, struct mips_fpu_soft_struct *ctx,
{
unsigned rcsr = 0; /* resulting csr */
- fpuemuprivate.stats.cp1xops++;
+ fpuemustats.cp1xops++;
switch (MIPSInst_FMA_FFMT(ir)) {
case s_fmt:{ /* 0 */
ieee754sp(*handler) (ieee754sp, ieee754sp, ieee754sp);
ieee754sp fd, fr, fs, ft;
- u32 *va;
+ u32 __user *va;
u32 val;
switch (MIPSInst_FUNC(ir)) {
case lwxc1_op:
- va = REG_TO_VA(xcp->regs[MIPSInst_FR(ir)] +
+ va = (void __user *) (xcp->regs[MIPSInst_FR(ir)] +
xcp->regs[MIPSInst_FT(ir)]);
- fpuemuprivate.stats.loads++;
+ fpuemustats.loads++;
if (get_user(val, va)) {
- fpuemuprivate.stats.errors++;
+ fpuemustats.errors++;
return SIGBUS;
}
-#ifdef SINGLE_ONLY_FPU
- if (MIPSInst_FD(ir) & 1) {
- /* illegal register in single-float
- * mode
- */
- return SIGILL;
- }
-#endif
SITOREG(val, MIPSInst_FD(ir));
break;
case swxc1_op:
- va = REG_TO_VA(xcp->regs[MIPSInst_FR(ir)] +
+ va = (void __user *) (xcp->regs[MIPSInst_FR(ir)] +
xcp->regs[MIPSInst_FT(ir)]);
- fpuemuprivate.stats.stores++;
-#ifdef SINGLE_ONLY_FPU
- if (MIPSInst_FS(ir) & 1) {
- /* illegal register in single-float
- * mode
- */
- return SIGILL;
- }
-#endif
+ fpuemustats.stores++;
SIFROMREG(val, MIPSInst_FS(ir));
if (put_user(val, va)) {
- fpuemuprivate.stats.errors++;
+ fpuemustats.errors++;
return SIGBUS;
}
break;
@@ -699,8 +667,6 @@ static int fpux_emu(struct pt_regs *xcp, struct mips_fpu_soft_struct *ctx,
rcsr |= FPU_CSR_INV_X | FPU_CSR_INV_S;
ctx->fcr31 = (ctx->fcr31 & ~FPU_CSR_ALL_X) | rcsr;
- if (ieee754_csr.nod)
- ctx->fcr31 |= 0x1000000;
if ((ctx->fcr31 >> 5) & ctx->fcr31 & FPU_CSR_ALL_E) {
/*printk ("SIGFPE: fpu csr = %08x\n",
ctx->fcr31); */
@@ -715,34 +681,33 @@ static int fpux_emu(struct pt_regs *xcp, struct mips_fpu_soft_struct *ctx,
break;
}
-#ifndef SINGLE_ONLY_FPU
case d_fmt:{ /* 1 */
ieee754dp(*handler) (ieee754dp, ieee754dp, ieee754dp);
ieee754dp fd, fr, fs, ft;
- u64 *va;
+ u64 __user *va;
u64 val;
switch (MIPSInst_FUNC(ir)) {
case ldxc1_op:
- va = REG_TO_VA(xcp->regs[MIPSInst_FR(ir)] +
+ va = (void __user *) (xcp->regs[MIPSInst_FR(ir)] +
xcp->regs[MIPSInst_FT(ir)]);
- fpuemuprivate.stats.loads++;
+ fpuemustats.loads++;
if (get_user(val, va)) {
- fpuemuprivate.stats.errors++;
+ fpuemustats.errors++;
return SIGBUS;
}
DITOREG(val, MIPSInst_FD(ir));
break;
case sdxc1_op:
- va = REG_TO_VA(xcp->regs[MIPSInst_FR(ir)] +
+ va = (void __user *) (xcp->regs[MIPSInst_FR(ir)] +
xcp->regs[MIPSInst_FT(ir)]);
- fpuemuprivate.stats.stores++;
+ fpuemustats.stores++;
DIFROMREG(val, MIPSInst_FS(ir));
if (put_user(val, va)) {
- fpuemuprivate.stats.errors++;
+ fpuemustats.errors++;
return SIGBUS;
}
break;
@@ -773,7 +738,6 @@ static int fpux_emu(struct pt_regs *xcp, struct mips_fpu_soft_struct *ctx,
}
break;
}
-#endif
case 0x7: /* 7 */
if (MIPSInst_FUNC(ir) != pfetch_op) {
@@ -810,7 +774,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_soft_struct *ctx,
#endif
} rv; /* resulting value */
- fpuemuprivate.stats.cp1ops++;
+ fpuemustats.cp1ops++;
switch (rfmt = (MIPSInst_FFMT(ir) & 0xf)) {
case s_fmt:{ /* 0 */
union {
@@ -834,7 +798,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_soft_struct *ctx,
goto scopbop;
/* unary ops */
-#if __mips >= 2 || __mips64
+#if __mips >= 2 || defined(__mips64)
case fsqrt_op:
handler.u = ieee754sp_sqrt;
goto scopuop;
@@ -913,9 +877,6 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_soft_struct *ctx,
case fcvts_op:
return SIGILL; /* not defined */
case fcvtd_op:{
-#ifdef SINGLE_ONLY_FPU
- return SIGILL; /* not defined */
-#else
ieee754sp fs;
SPFROMREG(fs, MIPSInst_FS(ir));
@@ -923,7 +884,6 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_soft_struct *ctx,
rfmt = d_fmt;
goto copcsr;
}
-#endif
case fcvtw_op:{
ieee754sp fs;
@@ -933,7 +893,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_soft_struct *ctx,
goto copcsr;
}
-#if __mips >= 2 || __mips64
+#if __mips >= 2 || defined(__mips64)
case fround_op:
case ftrunc_op:
case fceil_op:
@@ -950,7 +910,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_soft_struct *ctx,
}
#endif /* __mips >= 2 */
-#if defined(__mips64) && !defined(SINGLE_ONLY_FPU)
+#if defined(__mips64)
case fcvtl_op:{
ieee754sp fs;
@@ -974,7 +934,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_soft_struct *ctx,
rfmt = l_fmt;
goto copcsr;
}
-#endif /* __mips64 && !fpu(single) */
+#endif /* defined(__mips64) */
default:
if (MIPSInst_FUNC(ir) >= fcmp_op) {
@@ -1001,7 +961,6 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_soft_struct *ctx,
break;
}
-#ifndef SINGLE_ONLY_FPU
case d_fmt:{
union {
ieee754dp(*b) (ieee754dp, ieee754dp);
@@ -1024,7 +983,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_soft_struct *ctx,
goto dcopbop;
/* unary ops */
-#if __mips >= 2 || __mips64
+#if __mips >= 2 || defined(__mips64)
case fsqrt_op:
handler.u = ieee754dp_sqrt;
goto dcopuop;
@@ -1108,7 +1067,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_soft_struct *ctx,
goto copcsr;
}
-#if __mips >= 2 || __mips64
+#if __mips >= 2 || defined(__mips64)
case fround_op:
case ftrunc_op:
case fceil_op:
@@ -1125,7 +1084,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_soft_struct *ctx,
}
#endif
-#if defined(__mips64) && !defined(SINGLE_ONLY_FPU)
+#if defined(__mips64)
case fcvtl_op:{
ieee754dp fs;
@@ -1149,7 +1108,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_soft_struct *ctx,
rfmt = l_fmt;
goto copcsr;
}
-#endif /* __mips >= 3 && !fpu(single) */
+#endif /* __mips >= 3 */
default:
if (MIPSInst_FUNC(ir) >= fcmp_op) {
@@ -1177,7 +1136,6 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_soft_struct *ctx,
}
break;
}
-#endif /* ifndef SINGLE_ONLY_FPU */
case w_fmt:{
ieee754sp fs;
@@ -1189,21 +1147,19 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_soft_struct *ctx,
rv.s = ieee754sp_fint(fs.bits);
rfmt = s_fmt;
goto copcsr;
-#ifndef SINGLE_ONLY_FPU
case fcvtd_op:
/* convert word to double precision real */
SPFROMREG(fs, MIPSInst_FS(ir));
rv.d = ieee754dp_fint(fs.bits);
rfmt = d_fmt;
goto copcsr;
-#endif
default:
return SIGILL;
}
break;
}
-#if defined(__mips64) && !defined(SINGLE_ONLY_FPU)
+#if defined(__mips64)
case l_fmt:{
switch (MIPSInst_FUNC(ir)) {
case fcvts_op:
@@ -1256,18 +1212,16 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_soft_struct *ctx,
ctx->fcr31 &= ~cond;
break;
}
-#ifndef SINGLE_ONLY_FPU
case d_fmt:
DPTOREG(rv.d, MIPSInst_FD(ir));
break;
-#endif
case s_fmt:
SPTOREG(rv.s, MIPSInst_FD(ir));
break;
case w_fmt:
SITOREG(rv.w, MIPSInst_FD(ir));
break;
-#if defined(__mips64) && !defined(SINGLE_ONLY_FPU)
+#if defined(__mips64)
case l_fmt:
DITOREG(rv.l, MIPSInst_FD(ir));
break;
@@ -1279,10 +1233,10 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_soft_struct *ctx,
return 0;
}
-int fpu_emulator_cop1Handler(int xcptno, struct pt_regs *xcp,
+int fpu_emulator_cop1Handler(struct pt_regs *xcp,
struct mips_fpu_soft_struct *ctx)
{
- gpreg_t oldepc, prevepc;
+ unsigned long oldepc, prevepc;
mips_instruction insn;
int sig = 0;
@@ -1290,19 +1244,24 @@ int fpu_emulator_cop1Handler(int xcptno, struct pt_regs *xcp,
do {
prevepc = xcp->cp0_epc;
- if (get_user(insn, (mips_instruction *) xcp->cp0_epc)) {
- fpuemuprivate.stats.errors++;
+ if (get_user(insn, (mips_instruction __user *) xcp->cp0_epc)) {
+ fpuemustats.errors++;
return SIGBUS;
}
if (insn == 0)
xcp->cp0_epc += 4; /* skip nops */
else {
- /* Update ieee754_csr. Only relevant if we have a
- h/w FPU */
- ieee754_csr.nod = (ctx->fcr31 & 0x1000000) != 0;
- ieee754_csr.rm = ieee_rm[ctx->fcr31 & 0x3];
- ieee754_csr.cx = (ctx->fcr31 >> 12) & 0x1f;
+ /*
+ * The 'ieee754_csr' is an alias of
+ * ctx->fcr31. No need to copy ctx->fcr31 to
+ * ieee754_csr. But ieee754_csr.rm is ieee
+ * library modes. (not mips rounding mode)
+ */
+ /* convert to ieee library modes */
+ ieee754_csr.rm = ieee_rm[ieee754_csr.rm];
sig = cop1Emulate(xcp, ctx);
+ /* revert to mips rounding mode */
+ ieee754_csr.rm = mips_rm[ieee754_csr.rm];
}
if (cpu_has_fpu)
diff --git a/arch/mips/math-emu/dp_sqrt.c b/arch/mips/math-emu/dp_sqrt.c
index c35e871ae975..032328c49888 100644
--- a/arch/mips/math-emu/dp_sqrt.c
+++ b/arch/mips/math-emu/dp_sqrt.c
@@ -37,7 +37,7 @@ static const unsigned table[] = {
ieee754dp ieee754dp_sqrt(ieee754dp x)
{
- struct ieee754_csr oldcsr;
+ struct _ieee754_csr oldcsr;
ieee754dp y, z, t;
unsigned scalx, yh;
COMPXDP;
diff --git a/arch/mips/math-emu/dsemul.c b/arch/mips/math-emu/dsemul.c
index aa989c2246da..8079f3d1eca0 100644
--- a/arch/mips/math-emu/dsemul.c
+++ b/arch/mips/math-emu/dsemul.c
@@ -28,9 +28,6 @@
#endif
#define __mips 4
-extern struct mips_fpu_emulator_private fpuemuprivate;
-
-
/*
* Emulate the arbritrary instruction ir at xcp->cp0_epc. Required when
* we have to emulate the instruction in a COP1 branch delay slot. Do
@@ -52,10 +49,10 @@ struct emuframe {
mips_instruction emul;
mips_instruction badinst;
mips_instruction cookie;
- gpreg_t epc;
+ unsigned long epc;
};
-int mips_dsemul(struct pt_regs *regs, mips_instruction ir, gpreg_t cpc)
+int mips_dsemul(struct pt_regs *regs, mips_instruction ir, unsigned long cpc)
{
extern asmlinkage void handle_dsemulret(void);
mips_instruction *dsemul_insns;
@@ -91,7 +88,7 @@ int mips_dsemul(struct pt_regs *regs, mips_instruction ir, gpreg_t cpc)
*/
/* Ensure that the two instructions are in the same cache line */
- dsemul_insns = (mips_instruction *) REG_TO_VA ((regs->regs[29] - sizeof(struct emuframe)) & ~0x7);
+ dsemul_insns = (mips_instruction *) ((regs->regs[29] - sizeof(struct emuframe)) & ~0x7);
fr = (struct emuframe *) dsemul_insns;
/* Verify that the stack pointer is not competely insane */
@@ -104,11 +101,11 @@ int mips_dsemul(struct pt_regs *regs, mips_instruction ir, gpreg_t cpc)
err |= __put_user(cpc, &fr->epc);
if (unlikely(err)) {
- fpuemuprivate.stats.errors++;
+ fpuemustats.errors++;
return SIGBUS;
}
- regs->cp0_epc = VA_TO_REG & fr->emul;
+ regs->cp0_epc = (unsigned long) &fr->emul;
flush_cache_sigtramp((unsigned long)&fr->badinst);
@@ -118,7 +115,7 @@ int mips_dsemul(struct pt_regs *regs, mips_instruction ir, gpreg_t cpc)
int do_dsemulret(struct pt_regs *xcp)
{
struct emuframe *fr;
- gpreg_t epc;
+ unsigned long epc;
u32 insn, cookie;
int err = 0;
@@ -141,7 +138,7 @@ int do_dsemulret(struct pt_regs *xcp)
err |= __get_user(cookie, &fr->cookie);
if (unlikely(err || (insn != BADINST) || (cookie != BD_COOKIE))) {
- fpuemuprivate.stats.errors++;
+ fpuemustats.errors++;
return 0;
}
diff --git a/arch/mips/math-emu/dsemul.h b/arch/mips/math-emu/dsemul.h
index dbd85f95268d..091f0e76730f 100644
--- a/arch/mips/math-emu/dsemul.h
+++ b/arch/mips/math-emu/dsemul.h
@@ -1,11 +1,5 @@
-typedef long gpreg_t;
-typedef void *vaddr_t;
-
-#define REG_TO_VA (vaddr_t)
-#define VA_TO_REG (gpreg_t)
-
-int mips_dsemul(struct pt_regs *regs, mips_instruction ir, gpreg_t cpc);
-int do_dsemulret(struct pt_regs *xcp);
+extern int mips_dsemul(struct pt_regs *regs, mips_instruction ir, unsigned long cpc);
+extern int do_dsemulret(struct pt_regs *xcp);
/* Instruction which will always cause an address error */
#define AdELOAD 0x8c000001 /* lw $0,1($0) */
diff --git a/arch/mips/math-emu/ieee754.c b/arch/mips/math-emu/ieee754.c
index f0a364adbf34..a93c45dbdefd 100644
--- a/arch/mips/math-emu/ieee754.c
+++ b/arch/mips/math-emu/ieee754.c
@@ -31,6 +31,8 @@
#include "ieee754int.h"
+#include "ieee754sp.h"
+#include "ieee754dp.h"
#define DP_EBIAS 1023
#define DP_EMIN (-1022)
@@ -40,20 +42,6 @@
#define SP_EMIN (-126)
#define SP_EMAX 127
-/* indexed by class */
-const char *const ieee754_cname[] = {
- "Normal",
- "Zero",
- "Denormal",
- "Infinity",
- "QNaN",
- "SNaN",
-};
-
-/* the control status register
-*/
-struct ieee754_csr ieee754_csr;
-
/* special constants
*/
diff --git a/arch/mips/math-emu/ieee754.h b/arch/mips/math-emu/ieee754.h
index b8772f46972d..171f177c0f88 100644
--- a/arch/mips/math-emu/ieee754.h
+++ b/arch/mips/math-emu/ieee754.h
@@ -1,13 +1,8 @@
-/* single and double precision fp ops
- * missing extended precision.
-*/
/*
* MIPS floating point support
* Copyright (C) 1994-2000 Algorithmics Ltd.
* http://www.algor.co.uk
*
- * ########################################################################
- *
* This program is free software; you can distribute it and/or modify it
* under the terms of the GNU General Public License (Version 2) as
* published by the Free Software Foundation.
@@ -21,20 +16,18 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
*
- * ########################################################################
- */
-
-/**************************************************************************
* Nov 7, 2000
* Modification to allow integration with Linux kernel
*
* Kevin D. Kissell, kevink@mips.com and Carsten Langgard, carstenl@mips.com
* Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved.
- *************************************************************************/
+ */
+#ifndef __ARCH_MIPS_MATH_EMU_IEEE754_H
+#define __ARCH_MIPS_MATH_EMU_IEEE754_H
-#ifdef __KERNEL__
-/* Going from Algorithmics to Linux native environment, add this */
+#include <asm/byteorder.h>
#include <linux/types.h>
+#include <linux/sched.h>
/*
* Not very pretty, but the Linux kernel's normal va_list definition
@@ -44,18 +37,7 @@
#include <stdarg.h>
#endif
-#else
-
-/* Note that __KERNEL__ is taken to mean Linux kernel */
-
-#if #system(OpenBSD)
-#include <machine/types.h>
-#endif
-#include <machine/endian.h>
-
-#endif /* __KERNEL__ */
-
-#if (defined(BYTE_ORDER) && BYTE_ORDER == LITTLE_ENDIAN) || defined(__MIPSEL__)
+#ifdef __LITTLE_ENDIAN
struct ieee754dp_konst {
unsigned mantlo:32;
unsigned manthi:20;
@@ -86,13 +68,14 @@ typedef union _ieee754sp {
} ieee754sp;
#endif
-#if (defined(BYTE_ORDER) && BYTE_ORDER == BIG_ENDIAN) || defined(__MIPSEB__)
+#ifdef __BIG_ENDIAN
struct ieee754dp_konst {
unsigned sign:1;
unsigned bexp:11;
unsigned manthi:20;
unsigned mantlo:32;
};
+
typedef union _ieee754dp {
struct ieee754dp_konst oparts;
struct {
@@ -222,7 +205,6 @@ ieee754dp ieee754dp_sqrt(ieee754dp x);
#define IEEE754_CLASS_INF 0x03
#define IEEE754_CLASS_SNAN 0x04
#define IEEE754_CLASS_QNAN 0x05
-extern const char *const ieee754_cname[];
/* exception numbers */
#define IEEE754_INEXACT 0x01
@@ -251,93 +233,109 @@ extern const char *const ieee754_cname[];
/* "normal" comparisons
*/
-static __inline int ieee754sp_eq(ieee754sp x, ieee754sp y)
+static inline int ieee754sp_eq(ieee754sp x, ieee754sp y)
{
return ieee754sp_cmp(x, y, IEEE754_CEQ, 0);
}
-static __inline int ieee754sp_ne(ieee754sp x, ieee754sp y)
+static inline int ieee754sp_ne(ieee754sp x, ieee754sp y)
{
return ieee754sp_cmp(x, y,
IEEE754_CLT | IEEE754_CGT | IEEE754_CUN, 0);
}
-static __inline int ieee754sp_lt(ieee754sp x, ieee754sp y)
+static inline int ieee754sp_lt(ieee754sp x, ieee754sp y)
{
return ieee754sp_cmp(x, y, IEEE754_CLT, 0);
}
-static __inline int ieee754sp_le(ieee754sp x, ieee754sp y)
+static inline int ieee754sp_le(ieee754sp x, ieee754sp y)
{
return ieee754sp_cmp(x, y, IEEE754_CLT | IEEE754_CEQ, 0);
}
-static __inline int ieee754sp_gt(ieee754sp x, ieee754sp y)
+static inline int ieee754sp_gt(ieee754sp x, ieee754sp y)
{
return ieee754sp_cmp(x, y, IEEE754_CGT, 0);
}
-static __inline int ieee754sp_ge(ieee754sp x, ieee754sp y)
+static inline int ieee754sp_ge(ieee754sp x, ieee754sp y)
{
return ieee754sp_cmp(x, y, IEEE754_CGT | IEEE754_CEQ, 0);
}
-static __inline int ieee754dp_eq(ieee754dp x, ieee754dp y)
+static inline int ieee754dp_eq(ieee754dp x, ieee754dp y)
{
return ieee754dp_cmp(x, y, IEEE754_CEQ, 0);
}
-static __inline int ieee754dp_ne(ieee754dp x, ieee754dp y)
+static inline int ieee754dp_ne(ieee754dp x, ieee754dp y)
{
return ieee754dp_cmp(x, y,
IEEE754_CLT | IEEE754_CGT | IEEE754_CUN, 0);
}
-static __inline int ieee754dp_lt(ieee754dp x, ieee754dp y)
+static inline int ieee754dp_lt(ieee754dp x, ieee754dp y)
{
return ieee754dp_cmp(x, y, IEEE754_CLT, 0);
}
-static __inline int ieee754dp_le(ieee754dp x, ieee754dp y)
+static inline int ieee754dp_le(ieee754dp x, ieee754dp y)
{
return ieee754dp_cmp(x, y, IEEE754_CLT | IEEE754_CEQ, 0);
}
-static __inline int ieee754dp_gt(ieee754dp x, ieee754dp y)
+static inline int ieee754dp_gt(ieee754dp x, ieee754dp y)
{
return ieee754dp_cmp(x, y, IEEE754_CGT, 0);
}
-static __inline int ieee754dp_ge(ieee754dp x, ieee754dp y)
+static inline int ieee754dp_ge(ieee754dp x, ieee754dp y)
{
return ieee754dp_cmp(x, y, IEEE754_CGT | IEEE754_CEQ, 0);
}
-/* like strtod
-*/
+/*
+ * Like strtod
+ */
ieee754dp ieee754dp_fstr(const char *s, char **endp);
char *ieee754dp_tstr(ieee754dp x, int prec, int fmt, int af);
-/* the control status register
-*/
-struct ieee754_csr {
- unsigned pad:13;
+/*
+ * The control status register
+ */
+struct _ieee754_csr {
+#ifdef __BIG_ENDIAN
+ unsigned pad0:7;
unsigned nod:1; /* set 1 for no denormalised numbers */
- unsigned cx:5; /* exceptions this operation */
+ unsigned c:1; /* condition */
+ unsigned pad1:5;
+ unsigned cx:6; /* exceptions this operation */
unsigned mx:5; /* exception enable mask */
unsigned sx:5; /* exceptions total */
unsigned rm:2; /* current rounding mode */
+#endif
+#ifdef __LITTLE_ENDIAN
+ unsigned rm:2; /* current rounding mode */
+ unsigned sx:5; /* exceptions total */
+ unsigned mx:5; /* exception enable mask */
+ unsigned cx:6; /* exceptions this operation */
+ unsigned pad1:5;
+ unsigned c:1; /* condition */
+ unsigned nod:1; /* set 1 for no denormalised numbers */
+ unsigned pad0:7;
+#endif
};
-extern struct ieee754_csr ieee754_csr;
+#define ieee754_csr (*(struct _ieee754_csr *)(&current->thread.fpu.soft.fcr31))
-static __inline unsigned ieee754_getrm(void)
+static inline unsigned ieee754_getrm(void)
{
return (ieee754_csr.rm);
}
-static __inline unsigned ieee754_setrm(unsigned rm)
+static inline unsigned ieee754_setrm(unsigned rm)
{
return (ieee754_csr.rm = rm);
}
@@ -345,14 +343,14 @@ static __inline unsigned ieee754_setrm(unsigned rm)
/*
* get current exceptions
*/
-static __inline unsigned ieee754_getcx(void)
+static inline unsigned ieee754_getcx(void)
{
return (ieee754_csr.cx);
}
/* test for current exception condition
*/
-static __inline int ieee754_cxtest(unsigned n)
+static inline int ieee754_cxtest(unsigned n)
{
return (ieee754_csr.cx & n);
}
@@ -360,21 +358,21 @@ static __inline int ieee754_cxtest(unsigned n)
/*
* get sticky exceptions
*/
-static __inline unsigned ieee754_getsx(void)
+static inline unsigned ieee754_getsx(void)
{
return (ieee754_csr.sx);
}
/* clear sticky conditions
*/
-static __inline unsigned ieee754_clrsx(void)
+static inline unsigned ieee754_clrsx(void)
{
return (ieee754_csr.sx = 0);
}
/* test for sticky exception condition
*/
-static __inline int ieee754_sxtest(unsigned n)
+static inline int ieee754_sxtest(unsigned n)
{
return (ieee754_csr.sx & n);
}
@@ -406,52 +404,34 @@ extern const struct ieee754sp_konst __ieee754sp_spcvals[];
#define ieee754dp_spcvals ((const ieee754dp *)__ieee754dp_spcvals)
#define ieee754sp_spcvals ((const ieee754sp *)__ieee754sp_spcvals)
-/* return infinity with given sign
-*/
-#define ieee754dp_inf(sn) \
- (ieee754dp_spcvals[IEEE754_SPCVAL_PINFINITY+(sn)])
-#define ieee754dp_zero(sn) \
- (ieee754dp_spcvals[IEEE754_SPCVAL_PZERO+(sn)])
-#define ieee754dp_one(sn) \
- (ieee754dp_spcvals[IEEE754_SPCVAL_PONE+(sn)])
-#define ieee754dp_ten(sn) \
- (ieee754dp_spcvals[IEEE754_SPCVAL_PTEN+(sn)])
-#define ieee754dp_indef() \
- (ieee754dp_spcvals[IEEE754_SPCVAL_INDEF])
-#define ieee754dp_max(sn) \
- (ieee754dp_spcvals[IEEE754_SPCVAL_PMAX+(sn)])
-#define ieee754dp_min(sn) \
- (ieee754dp_spcvals[IEEE754_SPCVAL_PMIN+(sn)])
-#define ieee754dp_mind(sn) \
- (ieee754dp_spcvals[IEEE754_SPCVAL_PMIND+(sn)])
-#define ieee754dp_1e31() \
- (ieee754dp_spcvals[IEEE754_SPCVAL_P1E31])
-#define ieee754dp_1e63() \
- (ieee754dp_spcvals[IEEE754_SPCVAL_P1E63])
-
-#define ieee754sp_inf(sn) \
- (ieee754sp_spcvals[IEEE754_SPCVAL_PINFINITY+(sn)])
-#define ieee754sp_zero(sn) \
- (ieee754sp_spcvals[IEEE754_SPCVAL_PZERO+(sn)])
-#define ieee754sp_one(sn) \
- (ieee754sp_spcvals[IEEE754_SPCVAL_PONE+(sn)])
-#define ieee754sp_ten(sn) \
- (ieee754sp_spcvals[IEEE754_SPCVAL_PTEN+(sn)])
-#define ieee754sp_indef() \
- (ieee754sp_spcvals[IEEE754_SPCVAL_INDEF])
-#define ieee754sp_max(sn) \
- (ieee754sp_spcvals[IEEE754_SPCVAL_PMAX+(sn)])
-#define ieee754sp_min(sn) \
- (ieee754sp_spcvals[IEEE754_SPCVAL_PMIN+(sn)])
-#define ieee754sp_mind(sn) \
- (ieee754sp_spcvals[IEEE754_SPCVAL_PMIND+(sn)])
-#define ieee754sp_1e31() \
- (ieee754sp_spcvals[IEEE754_SPCVAL_P1E31])
-#define ieee754sp_1e63() \
- (ieee754sp_spcvals[IEEE754_SPCVAL_P1E63])
-
-/* indefinite integer value
-*/
+/*
+ * Return infinity with given sign
+ */
+#define ieee754dp_inf(sn) (ieee754dp_spcvals[IEEE754_SPCVAL_PINFINITY+(sn)])
+#define ieee754dp_zero(sn) (ieee754dp_spcvals[IEEE754_SPCVAL_PZERO+(sn)])
+#define ieee754dp_one(sn) (ieee754dp_spcvals[IEEE754_SPCVAL_PONE+(sn)])
+#define ieee754dp_ten(sn) (ieee754dp_spcvals[IEEE754_SPCVAL_PTEN+(sn)])
+#define ieee754dp_indef() (ieee754dp_spcvals[IEEE754_SPCVAL_INDEF])
+#define ieee754dp_max(sn) (ieee754dp_spcvals[IEEE754_SPCVAL_PMAX+(sn)])
+#define ieee754dp_min(sn) (ieee754dp_spcvals[IEEE754_SPCVAL_PMIN+(sn)])
+#define ieee754dp_mind(sn) (ieee754dp_spcvals[IEEE754_SPCVAL_PMIND+(sn)])
+#define ieee754dp_1e31() (ieee754dp_spcvals[IEEE754_SPCVAL_P1E31])
+#define ieee754dp_1e63() (ieee754dp_spcvals[IEEE754_SPCVAL_P1E63])
+
+#define ieee754sp_inf(sn) (ieee754sp_spcvals[IEEE754_SPCVAL_PINFINITY+(sn)])
+#define ieee754sp_zero(sn) (ieee754sp_spcvals[IEEE754_SPCVAL_PZERO+(sn)])
+#define ieee754sp_one(sn) (ieee754sp_spcvals[IEEE754_SPCVAL_PONE+(sn)])
+#define ieee754sp_ten(sn) (ieee754sp_spcvals[IEEE754_SPCVAL_PTEN+(sn)])
+#define ieee754sp_indef() (ieee754sp_spcvals[IEEE754_SPCVAL_INDEF])
+#define ieee754sp_max(sn) (ieee754sp_spcvals[IEEE754_SPCVAL_PMAX+(sn)])
+#define ieee754sp_min(sn) (ieee754sp_spcvals[IEEE754_SPCVAL_PMIN+(sn)])
+#define ieee754sp_mind(sn) (ieee754sp_spcvals[IEEE754_SPCVAL_PMIND+(sn)])
+#define ieee754sp_1e31() (ieee754sp_spcvals[IEEE754_SPCVAL_P1E31])
+#define ieee754sp_1e63() (ieee754sp_spcvals[IEEE754_SPCVAL_P1E63])
+
+/*
+ * Indefinite integer value
+ */
#define ieee754si_indef() INT_MAX
#ifdef LONG_LONG_MAX
#define ieee754di_indef() LONG_LONG_MAX
@@ -487,3 +467,5 @@ extern void ieee754_xcpt(struct ieee754xctx *xcp);
/* compat */
#define ieee754dp_fix(x) ieee754dp_tint(x)
#define ieee754sp_fix(x) ieee754sp_tint(x)
+
+#endif /* __ARCH_MIPS_MATH_EMU_IEEE754_H */
diff --git a/arch/mips/math-emu/kernel_linkage.c b/arch/mips/math-emu/kernel_linkage.c
index 4002f0cf79f3..d187ab71c2ff 100644
--- a/arch/mips/math-emu/kernel_linkage.c
+++ b/arch/mips/math-emu/kernel_linkage.c
@@ -27,8 +27,6 @@
#include <asm/fpu_emulator.h>
-extern struct mips_fpu_emulator_private fpuemuprivate;
-
#define SIGNALLING_NAN 0x7ff800007ff80000LL
void fpu_emulator_init_fpu(void)
@@ -65,7 +63,6 @@ int fpu_emulator_save_context(struct sigcontext *sc)
&sc->sc_fpregs[i]);
}
err |= __put_user(current->thread.fpu.soft.fcr31, &sc->sc_fpc_csr);
- err |= __put_user(fpuemuprivate.eir, &sc->sc_fpc_eir);
return err;
}
@@ -81,7 +78,6 @@ int fpu_emulator_restore_context(struct sigcontext *sc)
&sc->sc_fpregs[i]);
}
err |= __get_user(current->thread.fpu.soft.fcr31, &sc->sc_fpc_csr);
- err |= __get_user(fpuemuprivate.eir, &sc->sc_fpc_eir);
return err;
}
@@ -102,7 +98,6 @@ int fpu_emulator_save_context32(struct sigcontext32 *sc)
&sc->sc_fpregs[i]);
}
err |= __put_user(current->thread.fpu.soft.fcr31, &sc->sc_fpc_csr);
- err |= __put_user(fpuemuprivate.eir, &sc->sc_fpc_eir);
return err;
}
@@ -118,7 +113,6 @@ int fpu_emulator_restore_context32(struct sigcontext32 *sc)
&sc->sc_fpregs[i]);
}
err |= __get_user(current->thread.fpu.soft.fcr31, &sc->sc_fpc_csr);
- err |= __get_user(fpuemuprivate.eir, &sc->sc_fpc_eir);
return err;
}
diff --git a/arch/mips/mips-boards/atlas/atlas_int.c b/arch/mips/mips-boards/atlas/atlas_int.c
index 19d4b0792460..bc0ebc69bfb3 100644
--- a/arch/mips/mips-boards/atlas/atlas_int.c
+++ b/arch/mips/mips-boards/atlas/atlas_int.c
@@ -76,14 +76,13 @@ static void end_atlas_irq(unsigned int irq)
}
static struct hw_interrupt_type atlas_irq_type = {
- "Atlas",
- startup_atlas_irq,
- shutdown_atlas_irq,
- enable_atlas_irq,
- disable_atlas_irq,
- mask_and_ack_atlas_irq,
- end_atlas_irq,
- NULL
+ .typename = "Atlas",
+ .startup = startup_atlas_irq,
+ .shutdown = shutdown_atlas_irq,
+ .enable = enable_atlas_irq,
+ .disable = disable_atlas_irq,
+ .ack = mask_and_ack_atlas_irq,
+ .end = end_atlas_irq,
};
static inline int ls1bit32(unsigned int x)
diff --git a/arch/mips/mips-boards/atlas/atlas_setup.c b/arch/mips/mips-boards/atlas/atlas_setup.c
index 0a1dd9bbc02e..625843b30bed 100644
--- a/arch/mips/mips-boards/atlas/atlas_setup.c
+++ b/arch/mips/mips-boards/atlas/atlas_setup.c
@@ -50,8 +50,10 @@ const char *get_system_type(void)
return "MIPS Atlas";
}
-static int __init atlas_setup(void)
+void __init plat_setup(void)
{
+ mips_pcibios_init();
+
ioport_resource.end = 0x7fffffff;
serial_init ();
@@ -64,12 +66,8 @@ static int __init atlas_setup(void)
board_time_init = mips_time_init;
board_timer_setup = mips_timer_setup;
rtc_get_time = mips_rtc_get_time;
-
- return 0;
}
-early_initcall(atlas_setup);
-
static void __init serial_init(void)
{
#ifdef CONFIG_SERIAL_8250
diff --git a/arch/mips/mips-boards/generic/init.c b/arch/mips/mips-boards/generic/init.c
index 311155d1d3ed..eab5a705e989 100644
--- a/arch/mips/mips-boards/generic/init.c
+++ b/arch/mips/mips-boards/generic/init.c
@@ -1,6 +1,8 @@
/*
- * Carsten Langgaard, carstenl@mips.com
- * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved.
+ * Copyright (C) 1999, 2000, 2004, 2005 MIPS Technologies, Inc.
+ * All rights reserved.
+ * Authors: Carsten Langgaard <carstenl@mips.com>
+ * Maciej W. Rozycki <macro@mips.com>
*
* This program is free software; you can distribute it and/or modify it
* under the terms of the GNU General Public License (Version 2) as
@@ -22,18 +24,19 @@
#include <linux/string.h>
#include <linux/kernel.h>
-#include <asm/io.h>
#include <asm/bootinfo.h>
+#include <asm/gt64120.h>
+#include <asm/io.h>
+#include <asm/system.h>
+#include <asm/cacheflush.h>
+#include <asm/traps.h>
+
#include <asm/mips-boards/prom.h>
#include <asm/mips-boards/generic.h>
-#ifdef CONFIG_MIPS_GT64120
-#include <asm/gt64120.h>
-#endif
-#include <asm/mips-boards/msc01_pci.h>
#include <asm/mips-boards/bonito64.h>
-#ifdef CONFIG_MIPS_MALTA
+#include <asm/mips-boards/msc01_pci.h>
+
#include <asm/mips-boards/malta.h>
-#endif
#ifdef CONFIG_KGDB
extern int rs_kgdb_hook(int, int);
@@ -223,8 +226,34 @@ void __init kgdb_config (void)
}
#endif
+void __init mips_nmi_setup (void)
+{
+ void *base;
+ extern char except_vec_nmi;
+
+ base = cpu_has_veic ?
+ (void *)(CAC_BASE + 0xa80) :
+ (void *)(CAC_BASE + 0x380);
+ memcpy(base, &except_vec_nmi, 0x80);
+ flush_icache_range((unsigned long)base, (unsigned long)base + 0x80);
+}
+
+void __init mips_ejtag_setup (void)
+{
+ void *base;
+ extern char except_vec_ejtag_debug;
+
+ base = cpu_has_veic ?
+ (void *)(CAC_BASE + 0xa00) :
+ (void *)(CAC_BASE + 0x300);
+ memcpy(base, &except_vec_ejtag_debug, 0x80);
+ flush_icache_range((unsigned long)base, (unsigned long)base + 0x80);
+}
+
void __init prom_init(void)
{
+ u32 start, map, mask, data;
+
prom_argc = fw_arg0;
_prom_argv = (int *) fw_arg1;
_prom_envp = (int *) fw_arg2;
@@ -266,12 +295,15 @@ void __init prom_init(void)
#else
GT_WRITE(GT_PCI0_CMD_OFS, 0);
#endif
+ /* Fix up PCI I/O mapping if necessary (for Atlas). */
+ start = GT_READ(GT_PCI0IOLD_OFS);
+ map = GT_READ(GT_PCI0IOREMAP_OFS);
+ if ((start & map) != 0) {
+ map &= ~start;
+ GT_WRITE(GT_PCI0IOREMAP_OFS, map);
+ }
-#ifdef CONFIG_MIPS_MALTA
set_io_port_base(MALTA_GT_PORT_BASE);
-#else
- set_io_port_base((unsigned long)ioremap(0, 0x20000000));
-#endif
break;
case MIPS_REVISION_CORID_CORE_EMUL_BON:
@@ -300,18 +332,21 @@ void __init prom_init(void)
BONITO_BONGENCFG_BYTESWAP;
#endif
-#ifdef CONFIG_MIPS_MALTA
set_io_port_base(MALTA_BONITO_PORT_BASE);
-#else
- set_io_port_base((unsigned long)ioremap(0, 0x20000000));
-#endif
break;
case MIPS_REVISION_CORID_CORE_MSC:
case MIPS_REVISION_CORID_CORE_FPGA2:
+ case MIPS_REVISION_CORID_CORE_FPGA3:
case MIPS_REVISION_CORID_CORE_EMUL_MSC:
_pcictrl_msc = (unsigned long)ioremap(MIPS_MSC01_PCI_REG_BASE, 0x2000);
+ mb();
+ MSC_READ(MSC01_PCI_CFG, data);
+ MSC_WRITE(MSC01_PCI_CFG, data & ~MSC01_PCI_CFG_EN_BIT);
+ wmb();
+
+ /* Fix up lane swapping. */
#ifdef CONFIG_CPU_LITTLE_ENDIAN
MSC_WRITE(MSC01_PCI_SWAP, MSC01_PCI_SWAP_NOSWAP);
#else
@@ -320,12 +355,23 @@ void __init prom_init(void)
MSC01_PCI_SWAP_BYTESWAP << MSC01_PCI_SWAP_MEM_SHF |
MSC01_PCI_SWAP_BYTESWAP << MSC01_PCI_SWAP_BAR0_SHF);
#endif
+ /* Fix up target memory mapping. */
+ MSC_READ(MSC01_PCI_BAR0, mask);
+ MSC_WRITE(MSC01_PCI_P2SCMSKL, mask & MSC01_PCI_BAR0_SIZE_MSK);
+
+ /* Don't handle target retries indefinitely. */
+ if ((data & MSC01_PCI_CFG_MAXRTRY_MSK) ==
+ MSC01_PCI_CFG_MAXRTRY_MSK)
+ data = (data & ~(MSC01_PCI_CFG_MAXRTRY_MSK <<
+ MSC01_PCI_CFG_MAXRTRY_SHF)) |
+ ((MSC01_PCI_CFG_MAXRTRY_MSK - 1) <<
+ MSC01_PCI_CFG_MAXRTRY_SHF);
+
+ wmb();
+ MSC_WRITE(MSC01_PCI_CFG, data);
+ mb();
-#ifdef CONFIG_MIPS_MALTA
set_io_port_base(MALTA_MSC_PORT_BASE);
-#else
- set_io_port_base((unsigned long)ioremap(0, 0x20000000));
-#endif
break;
default:
@@ -334,6 +380,9 @@ void __init prom_init(void)
while(1); /* We die here... */
}
#endif
+ board_nmi_handler_setup = mips_nmi_setup;
+ board_ejtag_handler_setup = mips_ejtag_setup;
+
prom_printf("\nLINUX started...\n");
prom_init_cmdline();
prom_meminit();
diff --git a/arch/mips/mips-boards/generic/memory.c b/arch/mips/mips-boards/generic/memory.c
index 5ae2b43e4c2e..2c8afd77a20b 100644
--- a/arch/mips/mips-boards/generic/memory.c
+++ b/arch/mips/mips-boards/generic/memory.c
@@ -22,6 +22,7 @@
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/bootmem.h>
+#include <linux/string.h>
#include <asm/bootinfo.h>
#include <asm/page.h>
@@ -55,18 +56,30 @@ struct prom_pmemblock * __init prom_getmdesc(void)
{
char *memsize_str;
unsigned int memsize;
+ char cmdline[CL_SIZE], *ptr;
- memsize_str = prom_getenv("memsize");
- if (!memsize_str) {
- prom_printf("memsize not set in boot prom, set to default (32Mb)\n");
- memsize = 0x02000000;
- } else {
+ /* Check the command line first for a memsize directive */
+ strcpy(cmdline, arcs_cmdline);
+ ptr = strstr(cmdline, "memsize=");
+ if (ptr && (ptr != cmdline) && (*(ptr - 1) != ' '))
+ ptr = strstr(ptr, " memsize=");
+
+ if (ptr) {
+ memsize = memparse(ptr + 8, &ptr);
+ }
+ else {
+ /* otherwise look in the environment */
+ memsize_str = prom_getenv("memsize");
+ if (!memsize_str) {
+ prom_printf("memsize not set in boot prom, set to default (32Mb)\n");
+ memsize = 0x02000000;
+ } else {
#ifdef DEBUG
- prom_printf("prom_memsize = %s\n", memsize_str);
+ prom_printf("prom_memsize = %s\n", memsize_str);
#endif
- memsize = simple_strtol(memsize_str, NULL, 0);
+ memsize = simple_strtol(memsize_str, NULL, 0);
+ }
}
-
memset(mdesc, 0, sizeof(mdesc));
mdesc[0].type = yamon_dontuse;
diff --git a/arch/mips/mips-boards/generic/mipsIRQ.S b/arch/mips/mips-boards/generic/mipsIRQ.S
index 131f49bccb20..a397ecb872d6 100644
--- a/arch/mips/mips-boards/generic/mipsIRQ.S
+++ b/arch/mips/mips-boards/generic/mipsIRQ.S
@@ -29,6 +29,20 @@
#include <asm/regdef.h>
#include <asm/stackframe.h>
+#ifdef CONFIG_MIPS_ATLAS
+#include <asm/mips-boards/atlasint.h>
+#define CASCADE_IRQ MIPSCPU_INT_ATLAS
+#define CASCADE_DISPATCH atlas_hw0_irqdispatch
+#endif
+#ifdef CONFIG_MIPS_MALTA
+#include <asm/mips-boards/maltaint.h>
+#define CASCADE_IRQ MIPSCPU_INT_I8259A
+#define CASCADE_DISPATCH malta_hw0_irqdispatch
+#endif
+#ifdef CONFIG_MIPS_SEAD
+#include <asm/mips-boards/seadint.h>
+#endif
+
/* A lot of complication here is taken away because:
*
* 1) We handle one interrupt and return, sitting in a loop and moving across
@@ -80,74 +94,62 @@
mfc0 s0, CP0_CAUSE # get irq bits
mfc0 s1, CP0_STATUS # get irq mask
+ andi s0, ST0_IM # CAUSE.CE may be non-zero!
and s0, s1
- /* First we check for r4k counter/timer IRQ. */
- andi a0, s0, CAUSEF_IP7
- beq a0, zero, 1f
- andi a0, s0, CAUSEF_IP2 # delay slot, check hw0 interrupt
+#if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64)
+ .set mips32
+ clz a0, s0
+ .set mips0
+ negu a0
+ addu a0, 31-CAUSEB_IP
+ bltz a0, spurious
+#else
+ beqz s0, spurious
+ li a0, 7
- /* Wheee, a timer interrupt. */
- move a0, sp
- jal mips_timer_interrupt
- nop
+ and t0, s0, 0xf000
+ sltiu t0, t0, 1
+ sll t0, 2
+ subu a0, t0
+ sll s0, t0
- j ret_from_irq
- nop
+ and t0, s0, 0xc000
+ sltiu t0, t0, 1
+ sll t0, 1
+ subu a0, t0
+ sll s0, t0
-1:
-#if defined(CONFIG_MIPS_SEAD)
- beq a0, zero, 1f
- andi a0, s0, CAUSEF_IP3 # delay slot, check hw1 interrupt
-#else
- beq a0, zero, 1f # delay slot, check hw3 interrupt
- andi a0, s0, CAUSEF_IP5
+ and t0, s0, 0x8000
+ sltiu t0, t0, 1
+ # sll t0, 0
+ subu a0, t0
+ # sll s0, t0
#endif
- /* Wheee, combined hardware level zero interrupt. */
-#if defined(CONFIG_MIPS_ATLAS)
- jal atlas_hw0_irqdispatch
-#elif defined(CONFIG_MIPS_MALTA)
- jal malta_hw0_irqdispatch
-#elif defined(CONFIG_MIPS_SEAD)
- jal sead_hw0_irqdispatch
-#else
-#error "MIPS board not supported\n"
-#endif
- move a0, sp # delay slot
+#ifdef CASCADE_IRQ
+ li a1, CASCADE_IRQ
+ bne a0, a1, 1f
+ addu a0, MIPSCPU_INT_BASE
- j ret_from_irq
- nop # delay slot
+ jal CASCADE_DISPATCH
+ move a0, sp
-1:
-#if defined(CONFIG_MIPS_SEAD)
- beq a0, zero, 1f
- andi a0, s0, CAUSEF_IP5 # delay slot, check hw3 interrupt
- jal sead_hw1_irqdispatch
- move a0, sp # delay slot
- j ret_from_irq
- nop # delay slot
-1:
-#endif
-#if defined(CONFIG_MIPS_MALTA)
- beq a0, zero, 1f # check hw3 (coreHI) interrupt
- nop
- jal corehi_irqdispatch
- move a0, sp
j ret_from_irq
nop
1:
+#else
+ addu a0, MIPSCPU_INT_BASE
#endif
- /*
- * Here by mistake? This is possible, what can happen is that by the
- * time we take the exception the IRQ pin goes low, so just leave if
- * this is the case.
- */
- move a1,s0
- PRINT("Got interrupt: c0_cause = %08x\n")
- mfc0 a1, CP0_EPC
- PRINT("c0_epc = %08x\n")
+
+ jal do_IRQ
+ move a1, sp
j ret_from_irq
nop
+
+
+spurious:
+ j spurious_interrupt
+ nop
END(mipsIRQ)
diff --git a/arch/mips/mips-boards/generic/pci.c b/arch/mips/mips-boards/generic/pci.c
index 92c34bda02ae..1f6f9df74ab2 100644
--- a/arch/mips/mips-boards/generic/pci.c
+++ b/arch/mips/mips-boards/generic/pci.c
@@ -1,6 +1,8 @@
/*
- * Carsten Langgaard, carstenl@mips.com
- * Copyright (C) 1999, 2000 MIPS Technologies, Inc. All rights reserved.
+ * Copyright (C) 1999, 2000, 2004, 2005 MIPS Technologies, Inc.
+ * All rights reserved.
+ * Authors: Carsten Langgaard <carstenl@mips.com>
+ * Maciej W. Rozycki <macro@mips.com>
*
* Copyright (C) 2004 by Ralf Baechle (ralf@linux-mips.org)
*
@@ -19,65 +21,46 @@
*
* MIPS boards specific PCI support.
*/
-#include <linux/config.h>
#include <linux/types.h>
#include <linux/pci.h>
#include <linux/kernel.h>
#include <linux/init.h>
-#include <asm/mips-boards/generic.h>
#include <asm/gt64120.h>
+
+#include <asm/mips-boards/generic.h>
#include <asm/mips-boards/bonito64.h>
#include <asm/mips-boards/msc01_pci.h>
-#ifdef CONFIG_MIPS_MALTA
-#include <asm/mips-boards/malta.h>
-#endif
static struct resource bonito64_mem_resource = {
.name = "Bonito PCI MEM",
- .start = 0x10000000UL,
- .end = 0x1bffffffUL,
.flags = IORESOURCE_MEM,
};
static struct resource bonito64_io_resource = {
- .name = "Bonito IO MEM",
- .start = 0x00002000UL, /* avoid conflicts with YAMON allocated I/O addresses */
+ .name = "Bonito PCI I/O",
+ .start = 0x00000000UL,
.end = 0x000fffffUL,
.flags = IORESOURCE_IO,
};
static struct resource gt64120_mem_resource = {
- .name = "GT64120 PCI MEM",
- .start = 0x10000000UL,
- .end = 0x1bdfffffUL,
+ .name = "GT-64120 PCI MEM",
.flags = IORESOURCE_MEM,
};
static struct resource gt64120_io_resource = {
- .name = "GT64120 IO MEM",
-#ifdef CONFIG_MIPS_ATLAS
- .start = 0x18000000UL,
- .end = 0x181fffffUL,
-#endif
-#ifdef CONFIG_MIPS_MALTA
- .start = 0x00002000UL,
- .end = 0x001fffffUL,
-#endif
+ .name = "GT-64120 PCI I/O",
.flags = IORESOURCE_IO,
};
static struct resource msc_mem_resource = {
.name = "MSC PCI MEM",
- .start = 0x10000000UL,
- .end = 0x1fffffffUL,
.flags = IORESOURCE_MEM,
};
static struct resource msc_io_resource = {
- .name = "MSC IO MEM",
- .start = 0x00002000UL,
- .end = 0x007fffffUL,
+ .name = "MSC PCI I/O",
.flags = IORESOURCE_IO,
};
@@ -89,7 +72,6 @@ static struct pci_controller bonito64_controller = {
.pci_ops = &bonito64_pci_ops,
.io_resource = &bonito64_io_resource,
.mem_resource = &bonito64_mem_resource,
- .mem_offset = 0x10000000UL,
.io_offset = 0x00000000UL,
};
@@ -97,21 +79,18 @@ static struct pci_controller gt64120_controller = {
.pci_ops = &gt64120_pci_ops,
.io_resource = &gt64120_io_resource,
.mem_resource = &gt64120_mem_resource,
- .mem_offset = 0x00000000UL,
- .io_offset = 0x00000000UL,
};
-static struct pci_controller msc_controller = {
+static struct pci_controller msc_controller = {
.pci_ops = &msc_pci_ops,
.io_resource = &msc_io_resource,
.mem_resource = &msc_mem_resource,
- .mem_offset = 0x10000000UL,
- .io_offset = 0x00000000UL,
};
-static int __init pcibios_init(void)
+void __init mips_pcibios_init(void)
{
struct pci_controller *controller;
+ unsigned long start, end, map, start1, end1, map1, map2, map3, mask;
switch (mips_revision_corid) {
case MIPS_REVISION_CORID_QED_RM5261:
@@ -130,34 +109,140 @@ static int __init pcibios_init(void)
(0 << GT_PCI0_CFGADDR_DEVNUM_SHF) | /* GT64120 dev */
(0 << GT_PCI0_CFGADDR_FUNCTNUM_SHF) | /* Function 0*/
((0x20/4) << GT_PCI0_CFGADDR_REGNUM_SHF) | /* BAR 4*/
- GT_PCI0_CFGADDR_CONFIGEN_BIT );
+ GT_PCI0_CFGADDR_CONFIGEN_BIT);
/* Perform the write */
GT_WRITE(GT_PCI0_CFGDATA_OFS, CPHYSADDR(MIPS_GT_BASE));
+ /* Set up resource ranges from the controller's registers. */
+ start = GT_READ(GT_PCI0M0LD_OFS);
+ end = GT_READ(GT_PCI0M0HD_OFS);
+ map = GT_READ(GT_PCI0M0REMAP_OFS);
+ end = (end & GT_PCI_HD_MSK) | (start & ~GT_PCI_HD_MSK);
+ start1 = GT_READ(GT_PCI0M1LD_OFS);
+ end1 = GT_READ(GT_PCI0M1HD_OFS);
+ map1 = GT_READ(GT_PCI0M1REMAP_OFS);
+ end1 = (end1 & GT_PCI_HD_MSK) | (start1 & ~GT_PCI_HD_MSK);
+ /* Cannot support multiple windows, use the wider. */
+ if (end1 - start1 > end - start) {
+ start = start1;
+ end = end1;
+ map = map1;
+ }
+ mask = ~(start ^ end);
+ /* We don't support remapping with a discontiguous mask. */
+ BUG_ON((start & GT_PCI_HD_MSK) != (map & GT_PCI_HD_MSK) &&
+ mask != ~((mask & -mask) - 1));
+ gt64120_mem_resource.start = start;
+ gt64120_mem_resource.end = end;
+ gt64120_controller.mem_offset = (start & mask) - (map & mask);
+ /* Addresses are 36-bit, so do shifts in the destinations. */
+ gt64120_mem_resource.start <<= GT_PCI_DCRM_SHF;
+ gt64120_mem_resource.end <<= GT_PCI_DCRM_SHF;
+ gt64120_mem_resource.end |= (1 << GT_PCI_DCRM_SHF) - 1;
+ gt64120_controller.mem_offset <<= GT_PCI_DCRM_SHF;
+
+ start = GT_READ(GT_PCI0IOLD_OFS);
+ end = GT_READ(GT_PCI0IOHD_OFS);
+ map = GT_READ(GT_PCI0IOREMAP_OFS);
+ end = (end & GT_PCI_HD_MSK) | (start & ~GT_PCI_HD_MSK);
+ mask = ~(start ^ end);
+ /* We don't support remapping with a discontiguous mask. */
+ BUG_ON((start & GT_PCI_HD_MSK) != (map & GT_PCI_HD_MSK) &&
+ mask != ~((mask & -mask) - 1));
+ gt64120_io_resource.start = map & mask;
+ gt64120_io_resource.end = (map & mask) | ~mask;
+ gt64120_controller.io_offset = 0;
+ /* Addresses are 36-bit, so do shifts in the destinations. */
+ gt64120_io_resource.start <<= GT_PCI_DCRM_SHF;
+ gt64120_io_resource.end <<= GT_PCI_DCRM_SHF;
+ gt64120_io_resource.end |= (1 << GT_PCI_DCRM_SHF) - 1;
+
controller = &gt64120_controller;
break;
case MIPS_REVISION_CORID_BONITO64:
case MIPS_REVISION_CORID_CORE_20K:
case MIPS_REVISION_CORID_CORE_EMUL_BON:
+ /* Set up resource ranges from the controller's registers. */
+ map = BONITO_PCIMAP;
+ map1 = (BONITO_PCIMAP & BONITO_PCIMAP_PCIMAP_LO0) >>
+ BONITO_PCIMAP_PCIMAP_LO0_SHIFT;
+ map2 = (BONITO_PCIMAP & BONITO_PCIMAP_PCIMAP_LO1) >>
+ BONITO_PCIMAP_PCIMAP_LO1_SHIFT;
+ map3 = (BONITO_PCIMAP & BONITO_PCIMAP_PCIMAP_LO2) >>
+ BONITO_PCIMAP_PCIMAP_LO2_SHIFT;
+ /* Combine as many adjacent windows as possible. */
+ map = map1;
+ start = BONITO_PCILO0_BASE;
+ end = 1;
+ if (map3 == map2 + 1) {
+ map = map2;
+ start = BONITO_PCILO1_BASE;
+ end++;
+ }
+ if (map2 == map1 + 1) {
+ map = map1;
+ start = BONITO_PCILO0_BASE;
+ end++;
+ }
+ bonito64_mem_resource.start = start;
+ bonito64_mem_resource.end = start +
+ BONITO_PCIMAP_WINBASE(end) - 1;
+ bonito64_controller.mem_offset = start -
+ BONITO_PCIMAP_WINBASE(map);
+
controller = &bonito64_controller;
break;
case MIPS_REVISION_CORID_CORE_MSC:
case MIPS_REVISION_CORID_CORE_FPGA2:
+ case MIPS_REVISION_CORID_CORE_FPGA3:
case MIPS_REVISION_CORID_CORE_EMUL_MSC:
+ /* Set up resource ranges from the controller's registers. */
+ MSC_READ(MSC01_PCI_SC2PMBASL, start);
+ MSC_READ(MSC01_PCI_SC2PMMSKL, mask);
+ MSC_READ(MSC01_PCI_SC2PMMAPL, map);
+ msc_mem_resource.start = start & mask;
+ msc_mem_resource.end = (start & mask) | ~mask;
+ msc_controller.mem_offset = (start & mask) - (map & mask);
+
+ MSC_READ(MSC01_PCI_SC2PIOBASL, start);
+ MSC_READ(MSC01_PCI_SC2PIOMSKL, mask);
+ MSC_READ(MSC01_PCI_SC2PIOMAPL, map);
+ msc_io_resource.start = map & mask;
+ msc_io_resource.end = (map & mask) | ~mask;
+ msc_controller.io_offset = 0;
+ ioport_resource.end = ~mask;
+
+ /* If ranges overlap I/O takes precedence. */
+ start = start & mask;
+ end = start | ~mask;
+ if ((start >= msc_mem_resource.start &&
+ start <= msc_mem_resource.end) ||
+ (end >= msc_mem_resource.start &&
+ end <= msc_mem_resource.end)) {
+ /* Use the larger space. */
+ start = max(start, msc_mem_resource.start);
+ end = min(end, msc_mem_resource.end);
+ if (start - msc_mem_resource.start >=
+ msc_mem_resource.end - end)
+ msc_mem_resource.end = start - 1;
+ else
+ msc_mem_resource.start = end + 1;
+ }
+
controller = &msc_controller;
break;
default:
- return 1;
+ return;
}
+ if (controller->io_resource->start < 0x00001000UL) /* FIXME */
+ controller->io_resource->start = 0x00001000UL;
+
+ iomem_resource.end &= 0xfffffffffULL; /* 64 GB */
ioport_resource.end = controller->io_resource->end;
register_pci_controller (controller);
-
- return 0;
}
-
-early_initcall(pcibios_init);
diff --git a/arch/mips/mips-boards/generic/time.c b/arch/mips/mips-boards/generic/time.c
index 16315444dd5a..72a12d931cba 100644
--- a/arch/mips/mips-boards/generic/time.c
+++ b/arch/mips/mips-boards/generic/time.c
@@ -31,22 +31,21 @@
#include <asm/mipsregs.h>
#include <asm/ptrace.h>
+#include <asm/hardirq.h>
+#include <asm/irq.h>
#include <asm/div64.h>
#include <asm/cpu.h>
#include <asm/time.h>
#include <asm/mc146818-time.h>
+#include <asm/msc01_ic.h>
#include <asm/mips-boards/generic.h>
#include <asm/mips-boards/prom.h>
+#include <asm/mips-boards/maltaint.h>
+#include <asm/mc146818-time.h>
unsigned long cpu_khz;
-#if defined(CONFIG_MIPS_SEAD)
-#define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ5)
-#else
-#define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5)
-#endif
-
#if defined(CONFIG_MIPS_ATLAS)
static char display_string[] = " LINUX ON ATLAS ";
#endif
@@ -59,20 +58,61 @@ static char display_string[] = " LINUX ON SEAD ";
static unsigned int display_count = 0;
#define MAX_DISPLAY_COUNT (sizeof(display_string) - 8)
-#define MIPS_CPU_TIMER_IRQ (NR_IRQS-1)
-
static unsigned int timer_tick_count=0;
+static int mips_cpu_timer_irq;
-void mips_timer_interrupt(struct pt_regs *regs)
+static inline void scroll_display_message(void)
{
if ((timer_tick_count++ % HZ) == 0) {
mips_display_message(&display_string[display_count++]);
if (display_count == MAX_DISPLAY_COUNT)
- display_count = 0;
+ display_count = 0;
+ }
+}
+
+static void mips_timer_dispatch (struct pt_regs *regs)
+{
+ do_IRQ (mips_cpu_timer_irq, regs);
+}
+irqreturn_t mips_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+#ifdef CONFIG_SMP
+ int cpu = smp_processor_id();
+
+ if (cpu == 0) {
+ /*
+ * CPU 0 handles the global timer interrupt job and process accounting
+ * resets count/compare registers to trigger next timer int.
+ */
+ (void) timer_interrupt(irq, dev_id, regs);
+ scroll_display_message();
+ }
+ else {
+ /* Everyone else needs to reset the timer int here as
+ ll_local_timer_interrupt doesn't */
+ /*
+ * FIXME: need to cope with counter underflow.
+ * More support needs to be added to kernel/time for
+ * counter/timer interrupts on multiple CPU's
+ */
+ write_c0_compare (read_c0_count() + (mips_hpt_frequency/HZ));
+ /*
+ * other CPUs should do profiling and process accounting
+ */
+ local_timer_interrupt (irq, dev_id, regs);
}
- ll_timer_interrupt(MIPS_CPU_TIMER_IRQ, regs);
+ return IRQ_HANDLED;
+#else
+ irqreturn_t r;
+
+ r = timer_interrupt(irq, dev_id, regs);
+
+ scroll_display_message();
+
+ return r;
+#endif
}
/*
@@ -140,10 +180,8 @@ void __init mips_time_init(void)
local_irq_save(flags);
-#if defined(CONFIG_MIPS_ATLAS) || defined(CONFIG_MIPS_MALTA)
/* Set Data mode - binary. */
CMOS_WRITE(CMOS_READ(RTC_CONTROL) | RTC_DM_BINARY, RTC_CONTROL);
-#endif
est_freq = estimate_cpu_frequency ();
@@ -157,11 +195,29 @@ void __init mips_time_init(void)
void __init mips_timer_setup(struct irqaction *irq)
{
+ if (cpu_has_veic) {
+ set_vi_handler (MSC01E_INT_CPUCTR, mips_timer_dispatch);
+ mips_cpu_timer_irq = MSC01E_INT_BASE + MSC01E_INT_CPUCTR;
+ }
+ else {
+ if (cpu_has_vint)
+ set_vi_handler (MIPSCPU_INT_CPUCTR, mips_timer_dispatch);
+ mips_cpu_timer_irq = MIPSCPU_INT_BASE + MIPSCPU_INT_CPUCTR;
+ }
+
+
/* we are using the cpu counter for timer interrupts */
- irq->handler = no_action; /* we use our own handler */
- setup_irq(MIPS_CPU_TIMER_IRQ, irq);
+ irq->handler = mips_timer_interrupt; /* we use our own handler */
+ setup_irq(mips_cpu_timer_irq, irq);
+
+#ifdef CONFIG_SMP
+ /* irq_desc(riptor) is a global resource, when the interrupt overlaps
+ on seperate cpu's the first one tries to handle the second interrupt.
+ The effect is that the int remains disabled on the second cpu.
+ Mark the interrupt with IRQ_PER_CPU to avoid any confusion */
+ irq_desc[mips_cpu_timer_irq].status |= IRQ_PER_CPU;
+#endif
/* to generate the first timer interrupt */
write_c0_compare (read_c0_count() + mips_hpt_frequency/HZ);
- set_c0_status(ALLINTS);
}
diff --git a/arch/mips/mips-boards/malta/malta_int.c b/arch/mips/mips-boards/malta/malta_int.c
index dd2db35966bc..d06dc5ad6c9e 100644
--- a/arch/mips/mips-boards/malta/malta_int.c
+++ b/arch/mips/mips-boards/malta/malta_int.c
@@ -30,6 +30,7 @@
#include <linux/random.h>
#include <asm/i8259.h>
+#include <asm/irq_cpu.h>
#include <asm/io.h>
#include <asm/mips-boards/malta.h>
#include <asm/mips-boards/maltaint.h>
@@ -37,8 +38,10 @@
#include <asm/gt64120.h>
#include <asm/mips-boards/generic.h>
#include <asm/mips-boards/msc01_pci.h>
+#include <asm/msc01_ic.h>
extern asmlinkage void mipsIRQ(void);
+extern void mips_timer_interrupt(void);
static DEFINE_SPINLOCK(mips_irq_lock);
@@ -54,6 +57,7 @@ static inline int mips_pcibios_iack(void)
switch(mips_revision_corid) {
case MIPS_REVISION_CORID_CORE_MSC:
case MIPS_REVISION_CORID_CORE_FPGA2:
+ case MIPS_REVISION_CORID_CORE_FPGA3:
case MIPS_REVISION_CORID_CORE_EMUL_MSC:
MSC_READ(MSC01_PCI_IACK, irq);
irq &= 0xff;
@@ -91,88 +95,86 @@ static inline int mips_pcibios_iack(void)
return irq;
}
-static inline int get_int(int *irq)
+static inline int get_int(void)
{
unsigned long flags;
-
+ int irq;
spin_lock_irqsave(&mips_irq_lock, flags);
- *irq = mips_pcibios_iack();
+ irq = mips_pcibios_iack();
/*
- * IRQ7 is used to detect spurious interrupts.
- * The interrupt acknowledge cycle returns IRQ7, if no
- * interrupts is requested.
- * We can differentiate between this situation and a
- * "Normal" IRQ7 by reading the ISR.
+ * The only way we can decide if an interrupt is spurious
+ * is by checking the 8259 registers. This needs a spinlock
+ * on an SMP system, so leave it up to the generic code...
*/
- if (*irq == 7)
- {
- outb(PIIX4_OCW3_SEL | PIIX4_OCW3_ISR,
- PIIX4_ICTLR1_OCW3);
- if (!(inb(PIIX4_ICTLR1_OCW3) & (1 << 7))) {
- spin_unlock_irqrestore(&mips_irq_lock, flags);
- printk("We got a spurious interrupt from PIIX4.\n");
- atomic_inc(&irq_err_count);
- return -1; /* Spurious interrupt. */
- }
- }
spin_unlock_irqrestore(&mips_irq_lock, flags);
- return 0;
+ return irq;
}
void malta_hw0_irqdispatch(struct pt_regs *regs)
{
int irq;
- if (get_int(&irq))
- return; /* interrupt has already been cleared */
+ irq = get_int();
+ if (irq < 0)
+ return; /* interrupt has already been cleared */
- do_IRQ(irq, regs);
+ do_IRQ(MALTA_INT_BASE+irq, regs);
}
void corehi_irqdispatch(struct pt_regs *regs)
{
- unsigned int data,datahi;
-
- /* Mask out corehi interrupt. */
- clear_c0_status(IE_IRQ3);
+ unsigned int intrcause,datalo,datahi;
+ unsigned int pcimstat, intisr, inten, intpol, intedge, intsteer, pcicmd, pcibadaddr;
printk("CoreHI interrupt, shouldn't happen, so we die here!!!\n");
printk("epc : %08lx\nStatus: %08lx\nCause : %08lx\nbadVaddr : %08lx\n"
, regs->cp0_epc, regs->cp0_status, regs->cp0_cause, regs->cp0_badvaddr);
+
+ /* Read all the registers and then print them as there is a
+ problem with interspersed printk's upsetting the Bonito controller.
+ Do it for the others too.
+ */
+
switch(mips_revision_corid) {
case MIPS_REVISION_CORID_CORE_MSC:
case MIPS_REVISION_CORID_CORE_FPGA2:
- case MIPS_REVISION_CORID_CORE_EMUL_MSC:
+ case MIPS_REVISION_CORID_CORE_FPGA3:
+ case MIPS_REVISION_CORID_CORE_EMUL_MSC:
+ ll_msc_irq(regs);
break;
case MIPS_REVISION_CORID_QED_RM5261:
case MIPS_REVISION_CORID_CORE_LV:
case MIPS_REVISION_CORID_CORE_FPGA:
case MIPS_REVISION_CORID_CORE_FPGAR2:
- data = GT_READ(GT_INTRCAUSE_OFS);
- printk("GT_INTRCAUSE = %08x\n", data);
- data = GT_READ(GT_CPUERR_ADDRLO_OFS);
+ intrcause = GT_READ(GT_INTRCAUSE_OFS);
+ datalo = GT_READ(GT_CPUERR_ADDRLO_OFS);
datahi = GT_READ(GT_CPUERR_ADDRHI_OFS);
- printk("GT_CPUERR_ADDR = %02x%08x\n", datahi, data);
+ printk("GT_INTRCAUSE = %08x\n", intrcause);
+ printk("GT_CPUERR_ADDR = %02x%08x\n", datahi, datalo);
break;
case MIPS_REVISION_CORID_BONITO64:
case MIPS_REVISION_CORID_CORE_20K:
case MIPS_REVISION_CORID_CORE_EMUL_BON:
- data = BONITO_INTISR;
- printk("BONITO_INTISR = %08x\n", data);
- data = BONITO_INTEN;
- printk("BONITO_INTEN = %08x\n", data);
- data = BONITO_INTPOL;
- printk("BONITO_INTPOL = %08x\n", data);
- data = BONITO_INTEDGE;
- printk("BONITO_INTEDGE = %08x\n", data);
- data = BONITO_INTSTEER;
- printk("BONITO_INTSTEER = %08x\n", data);
- data = BONITO_PCICMD;
- printk("BONITO_PCICMD = %08x\n", data);
+ pcibadaddr = BONITO_PCIBADADDR;
+ pcimstat = BONITO_PCIMSTAT;
+ intisr = BONITO_INTISR;
+ inten = BONITO_INTEN;
+ intpol = BONITO_INTPOL;
+ intedge = BONITO_INTEDGE;
+ intsteer = BONITO_INTSTEER;
+ pcicmd = BONITO_PCICMD;
+ printk("BONITO_INTISR = %08x\n", intisr);
+ printk("BONITO_INTEN = %08x\n", inten);
+ printk("BONITO_INTPOL = %08x\n", intpol);
+ printk("BONITO_INTEDGE = %08x\n", intedge);
+ printk("BONITO_INTSTEER = %08x\n", intsteer);
+ printk("BONITO_PCICMD = %08x\n", pcicmd);
+ printk("BONITO_PCIBADADDR = %08x\n", pcibadaddr);
+ printk("BONITO_PCIMSTAT = %08x\n", pcimstat);
break;
}
@@ -180,8 +182,71 @@ void corehi_irqdispatch(struct pt_regs *regs)
die("CoreHi interrupt", regs);
}
+static struct irqaction i8259irq = {
+ .handler = no_action,
+ .name = "XT-PIC cascade"
+};
+
+static struct irqaction corehi_irqaction = {
+ .handler = no_action,
+ .name = "CoreHi"
+};
+
+msc_irqmap_t __initdata msc_irqmap[] = {
+ {MSC01C_INT_TMR, MSC01_IRQ_EDGE, 0},
+ {MSC01C_INT_PCI, MSC01_IRQ_LEVEL, 0},
+};
+int __initdata msc_nr_irqs = sizeof(msc_irqmap)/sizeof(msc_irqmap_t);
+
+msc_irqmap_t __initdata msc_eicirqmap[] = {
+ {MSC01E_INT_SW0, MSC01_IRQ_LEVEL, 0},
+ {MSC01E_INT_SW1, MSC01_IRQ_LEVEL, 0},
+ {MSC01E_INT_I8259A, MSC01_IRQ_LEVEL, 0},
+ {MSC01E_INT_SMI, MSC01_IRQ_LEVEL, 0},
+ {MSC01E_INT_COREHI, MSC01_IRQ_LEVEL, 0},
+ {MSC01E_INT_CORELO, MSC01_IRQ_LEVEL, 0},
+ {MSC01E_INT_TMR, MSC01_IRQ_EDGE, 0},
+ {MSC01E_INT_PCI, MSC01_IRQ_LEVEL, 0},
+ {MSC01E_INT_PERFCTR, MSC01_IRQ_LEVEL, 0},
+ {MSC01E_INT_CPUCTR, MSC01_IRQ_LEVEL, 0}
+};
+int __initdata msc_nr_eicirqs = sizeof(msc_eicirqmap)/sizeof(msc_irqmap_t);
+
void __init arch_init_irq(void)
{
set_except_vector(0, mipsIRQ);
init_i8259_irqs();
+
+ if (!cpu_has_veic)
+ mips_cpu_irq_init (MIPSCPU_INT_BASE);
+
+ switch(mips_revision_corid) {
+ case MIPS_REVISION_CORID_CORE_MSC:
+ case MIPS_REVISION_CORID_CORE_FPGA2:
+ case MIPS_REVISION_CORID_CORE_FPGA3:
+ case MIPS_REVISION_CORID_CORE_EMUL_MSC:
+ if (cpu_has_veic)
+ init_msc_irqs (MSC01E_INT_BASE, msc_eicirqmap, msc_nr_eicirqs);
+ else
+ init_msc_irqs (MSC01C_INT_BASE, msc_irqmap, msc_nr_irqs);
+ }
+
+ if (cpu_has_veic) {
+ set_vi_handler (MSC01E_INT_I8259A, malta_hw0_irqdispatch);
+ set_vi_handler (MSC01E_INT_COREHI, corehi_irqdispatch);
+ setup_irq (MSC01E_INT_BASE+MSC01E_INT_I8259A, &i8259irq);
+ setup_irq (MSC01E_INT_BASE+MSC01E_INT_COREHI, &corehi_irqaction);
+ }
+ else if (cpu_has_vint) {
+ set_vi_handler (MIPSCPU_INT_I8259A, malta_hw0_irqdispatch);
+ set_vi_handler (MIPSCPU_INT_COREHI, corehi_irqdispatch);
+
+ setup_irq (MIPSCPU_INT_BASE+MIPSCPU_INT_I8259A, &i8259irq);
+ setup_irq (MIPSCPU_INT_BASE+MIPSCPU_INT_COREHI, &corehi_irqaction);
+ }
+ else {
+ set_except_vector(0, mipsIRQ);
+ setup_irq (MIPSCPU_INT_BASE+MIPSCPU_INT_I8259A, &i8259irq);
+ setup_irq (MIPSCPU_INT_BASE+MIPSCPU_INT_COREHI, &corehi_irqaction);
+ }
}
diff --git a/arch/mips/mips-boards/malta/malta_setup.c b/arch/mips/mips-boards/malta/malta_setup.c
index df6db6419ae9..2209e8a9de34 100644
--- a/arch/mips/mips-boards/malta/malta_setup.c
+++ b/arch/mips/mips-boards/malta/malta_setup.c
@@ -111,10 +111,12 @@ void __init fd_activate(void)
}
#endif
-static int __init malta_setup(void)
+void __init plat_setup(void)
{
unsigned int i;
+ mips_pcibios_init();
+
/* Request I/O space for devices used on the Malta board. */
for (i = 0; i < ARRAY_SIZE(standard_io_resources); i++)
request_resource(&ioport_resource, standard_io_resources+i);
@@ -224,8 +226,4 @@ static int __init malta_setup(void)
board_time_init = mips_time_init;
board_timer_setup = mips_timer_setup;
rtc_get_time = mips_rtc_get_time;
-
- return 0;
}
-
-early_initcall(malta_setup);
diff --git a/arch/mips/mips-boards/sead/sead_int.c b/arch/mips/mips-boards/sead/sead_int.c
index e5109657ed5a..e1dd7e009750 100644
--- a/arch/mips/mips-boards/sead/sead_int.c
+++ b/arch/mips/mips-boards/sead/sead_int.c
@@ -2,6 +2,7 @@
* Carsten Langgaard, carstenl@mips.com
* Copyright (C) 2002 MIPS Technologies, Inc. All rights reserved.
* Copyright (C) 2003 Ralf Baechle (ralf@linux-mips.org)
+ * Copyright (C) 2004 Maciej W. Rozycki
*
* This program is free software; you can distribute it and/or modify it
* under the terms of the GNU General Public License (Version 2) as
@@ -21,7 +22,9 @@
*/
#include <linux/init.h>
#include <linux/irq.h>
-#include <linux/interrupt.h>
+
+#include <asm/irq_cpu.h>
+#include <asm/system.h>
#include <asm/mips-boards/seadint.h>
@@ -39,13 +42,8 @@ asmlinkage void sead_hw1_irqdispatch(struct pt_regs *regs)
void __init arch_init_irq(void)
{
- /*
- * Mask out all interrupt
- */
- clear_c0_status(0x0000ff00);
+ mips_cpu_irq_init(0);
/* Now safe to set the exception vector. */
set_except_vector(0, mipsIRQ);
-
- mips_cpu_irq_init(0);
}
diff --git a/arch/mips/mips-boards/sead/sead_setup.c b/arch/mips/mips-boards/sead/sead_setup.c
index 29892b88a4fc..de90bec5505e 100644
--- a/arch/mips/mips-boards/sead/sead_setup.c
+++ b/arch/mips/mips-boards/sead/sead_setup.c
@@ -57,8 +57,6 @@ static void __init sead_setup(void)
mips_reboot_setup();
}
-early_initcall(sead_setup);
-
static void __init serial_init(void)
{
#ifdef CONFIG_SERIAL_8250
diff --git a/arch/mips/mips-boards/sim/Makefile b/arch/mips/mips-boards/sim/Makefile
new file mode 100644
index 000000000000..5b977de4ecff
--- /dev/null
+++ b/arch/mips/mips-boards/sim/Makefile
@@ -0,0 +1,20 @@
+#
+# Copyright (C) 2005 MIPS Technologies, Inc. All rights reserved.
+#
+# This program is free software; you can distribute it and/or modify it
+# under the terms of the GNU General Public License (Version 2) as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+#
+
+obj-y := sim_setup.o sim_mem.o sim_time.o sim_printf.o sim_int.o sim_irq.o \
+ sim_cmdline.o
+obj-$(CONFIG_SMP) += sim_smp.o
diff --git a/arch/mips/mips-boards/sim/cmdline.c b/arch/mips/mips-boards/sim/cmdline.c
new file mode 100644
index 000000000000..fef9fbd8e710
--- /dev/null
+++ b/arch/mips/mips-boards/sim/cmdline.c
@@ -0,0 +1,59 @@
+/*
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved.
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Kernel command line creation using the prom monitor (YAMON) argc/argv.
+ */
+#include <linux/init.h>
+#include <linux/string.h>
+
+#include <asm/bootinfo.h>
+
+extern int prom_argc;
+extern int *_prom_argv;
+
+/*
+ * YAMON (32-bit PROM) pass arguments and environment as 32-bit pointer.
+ * This macro take care of sign extension.
+ */
+#define prom_argv(index) ((char *)(((int *)(int)_prom_argv)[(index)]))
+
+char arcs_cmdline[CL_SIZE];
+
+char * __init prom_getcmdline(void)
+{
+ return &(arcs_cmdline[0]);
+}
+
+
+void __init prom_init_cmdline(void)
+{
+ char *cp;
+ int actr;
+
+ actr = 1; /* Always ignore argv[0] */
+
+ cp = &(arcs_cmdline[0]);
+ while(actr < prom_argc) {
+ strcpy(cp, prom_argv(actr));
+ cp += strlen(prom_argv(actr));
+ *cp++ = ' ';
+ actr++;
+ }
+ if (cp != &(arcs_cmdline[0])) /* get rid of trailing space */
+ --cp;
+ *cp = '\0';
+}
diff --git a/arch/mips/mips-boards/sim/sim_IRQ.c b/arch/mips/mips-boards/sim/sim_IRQ.c
new file mode 100644
index 000000000000..9987a85aabeb
--- /dev/null
+++ b/arch/mips/mips-boards/sim/sim_IRQ.c
@@ -0,0 +1,148 @@
+/*
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 1999, 2000 MIPS Technologies, Inc. All rights reserved.
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Interrupt exception dispatch code.
+ */
+#include <linux/config.h>
+
+#include <asm/asm.h>
+#include <asm/mipsregs.h>
+#include <asm/regdef.h>
+#include <asm/stackframe.h>
+
+/* A lot of complication here is taken away because:
+ *
+ * 1) We handle one interrupt and return, sitting in a loop and moving across
+ * all the pending IRQ bits in the cause register is _NOT_ the answer, the
+ * common case is one pending IRQ so optimize in that direction.
+ *
+ * 2) We need not check against bits in the status register IRQ mask, that
+ * would make this routine slow as hell.
+ *
+ * 3) Linux only thinks in terms of all IRQs on or all IRQs off, nothing in
+ * between like BSD spl() brain-damage.
+ *
+ * Furthermore, the IRQs on the MIPS board look basically (barring software
+ * IRQs which we don't use at all and all external interrupt sources are
+ * combined together on hardware interrupt 0 (MIPS IRQ 2)) like:
+ *
+ * MIPS IRQ Source
+ * -------- ------
+ * 0 Software (ignored)
+ * 1 Software (ignored)
+ * 2 Combined hardware interrupt (hw0)
+ * 3 Hardware (ignored)
+ * 4 Hardware (ignored)
+ * 5 Hardware (ignored)
+ * 6 Hardware (ignored)
+ * 7 R4k timer (what we use)
+ *
+ * Note: On the SEAD board thing are a little bit different.
+ * Here IRQ 2 (hw0) is wired to the UART0 and IRQ 3 (hw1) is wired
+ * wired to UART1.
+ *
+ * We handle the IRQ according to _our_ priority which is:
+ *
+ * Highest ---- R4k Timer
+ * Lowest ---- Combined hardware interrupt
+ *
+ * then we just return, if multiple IRQs are pending then we will just take
+ * another exception, big deal.
+ */
+
+ .text
+ .set noreorder
+ .set noat
+ .align 5
+ NESTED(mipsIRQ, PT_SIZE, sp)
+ SAVE_ALL
+ CLI
+ .set at
+
+ mfc0 s0, CP0_CAUSE # get irq bits
+ mfc0 s1, CP0_STATUS # get irq mask
+ and s0, s1
+
+ /* First we check for r4k counter/timer IRQ. */
+ andi a0, s0, CAUSEF_IP7
+ beq a0, zero, 1f
+ andi a0, s0, CAUSEF_IP2 # delay slot, check hw0 interrupt
+
+ /* Wheee, a timer interrupt. */
+ move a0, sp
+ jal mips_timer_interrupt
+ nop
+
+ j ret_from_irq
+ nop
+
+1:
+#if defined(CONFIG_MIPS_SEAD)
+ beq a0, zero, 1f
+ andi a0, s0, CAUSEF_IP3 # delay slot, check hw1 interrupt
+#else
+ beq a0, zero, 1f # delay slot, check hw3 interrupt
+ andi a0, s0, CAUSEF_IP5
+#endif
+
+ /* Wheee, combined hardware level zero interrupt. */
+#if defined(CONFIG_MIPS_ATLAS)
+ jal atlas_hw0_irqdispatch
+#elif defined(CONFIG_MIPS_MALTA)
+ jal malta_hw0_irqdispatch
+#elif defined(CONFIG_MIPS_SEAD)
+ jal sead_hw0_irqdispatch
+#else
+#error "MIPS board not supported\n"
+#endif
+ move a0, sp # delay slot
+
+ j ret_from_irq
+ nop # delay slot
+
+1:
+#if defined(CONFIG_MIPS_SEAD)
+ beq a0, zero, 1f
+ andi a0, s0, CAUSEF_IP5 # delay slot, check hw3 interrupt
+ jal sead_hw1_irqdispatch
+ move a0, sp # delay slot
+ j ret_from_irq
+ nop # delay slot
+1:
+#endif
+#if defined(CONFIG_MIPS_MALTA)
+ beq a0, zero, 1f # check hw3 (coreHI) interrupt
+ nop
+ jal corehi_irqdispatch
+ move a0, sp
+ j ret_from_irq
+ nop
+1:
+#endif
+ /*
+ * Here by mistake? This is possible, what can happen is that by the
+ * time we take the exception the IRQ pin goes low, so just leave if
+ * this is the case.
+ */
+ move a1,s0
+ PRINT("Got interrupt: c0_cause = %08x\n")
+ mfc0 a1, CP0_EPC
+ PRINT("c0_epc = %08x\n")
+
+ j ret_from_irq
+ nop
+ END(mipsIRQ)
diff --git a/arch/mips/mips-boards/sim/sim_cmdline.c b/arch/mips/mips-boards/sim/sim_cmdline.c
new file mode 100644
index 000000000000..9df37c6fca36
--- /dev/null
+++ b/arch/mips/mips-boards/sim/sim_cmdline.c
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2005 MIPS Technologies, Inc. All rights reserved.
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ */
+#include <linux/init.h>
+#include <linux/string.h>
+#include <asm/bootinfo.h>
+
+extern char arcs_cmdline[];
+
+char * __init prom_getcmdline(void)
+{
+ return arcs_cmdline;
+}
+
+
+void __init prom_init_cmdline(void)
+{
+ /* nothing to do */
+}
diff --git a/arch/mips/mips-boards/sim/sim_int.c b/arch/mips/mips-boards/sim/sim_int.c
new file mode 100644
index 000000000000..a4d0a2c05031
--- /dev/null
+++ b/arch/mips/mips-boards/sim/sim_int.c
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 1999, 2005 MIPS Technologies, Inc. All rights reserved.
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ */
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/kernel_stat.h>
+#include <asm/mips-boards/simint.h>
+
+
+extern void mips_cpu_irq_init(int);
+
+extern asmlinkage void simIRQ(void);
+
+asmlinkage void sim_hw0_irqdispatch(struct pt_regs *regs)
+{
+ do_IRQ(2, regs);
+}
+
+void __init arch_init_irq(void)
+{
+ /* Now safe to set the exception vector. */
+ set_except_vector(0, simIRQ);
+
+ mips_cpu_irq_init(MIPSCPU_INT_BASE);
+}
diff --git a/arch/mips/mips-boards/sim/sim_irq.S b/arch/mips/mips-boards/sim/sim_irq.S
new file mode 100644
index 000000000000..835f0387fcd4
--- /dev/null
+++ b/arch/mips/mips-boards/sim/sim_irq.S
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 1999, 2005 MIPS Technologies, Inc. All rights reserved.
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Interrupt exception dispatch code.
+ *
+ */
+#include <linux/config.h>
+
+#include <asm/asm.h>
+#include <asm/mipsregs.h>
+#include <asm/regdef.h>
+#include <asm/stackframe.h>
+
+#include <asm/mips-boards/simint.h>
+
+
+ .text
+ .set noreorder
+ .set noat
+ .align 5
+ NESTED(simIRQ, PT_SIZE, sp)
+ SAVE_ALL
+ CLI
+ .set at
+
+ mfc0 s0, CP0_CAUSE # get irq bits
+ mfc0 s1, CP0_STATUS # get irq mask
+ andi s0, ST0_IM # CAUSE.CE may be non-zero!
+ and s0, s1
+
+#if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64)
+ .set mips32
+ clz a0, s0
+ .set mips0
+ negu a0
+ addu a0, 31-CAUSEB_IP
+ bltz a0, spurious
+#else
+ beqz s0, spurious
+ li a0, 7
+
+ and t0, s0, 0xf000
+ sltiu t0, t0, 1
+ sll t0, 2
+ subu a0, t0
+ sll s0, t0
+
+ and t0, s0, 0xc000
+ sltiu t0, t0, 1
+ sll t0, 1
+ subu a0, t0
+ sll s0, t0
+
+ and t0, s0, 0x8000
+ sltiu t0, t0, 1
+ # sll t0, 0
+ subu a0, t0
+ # sll s0, t0
+#endif
+
+#ifdef CASCADE_IRQ
+ li a1, CASCADE_IRQ
+ bne a0, a1, 1f
+ addu a0, MIPSCPU_INT_BASE
+
+ jal CASCADE_DISPATCH
+ move a0, sp
+
+ j ret_from_irq
+ nop
+1:
+#else
+ addu a0, MIPSCPU_INT_BASE
+#endif
+
+ jal do_IRQ
+ move a1, sp
+
+ j ret_from_irq
+ nop
+
+
+spurious:
+ j spurious_interrupt
+ nop
+ END(simIRQ)
diff --git a/arch/mips/mips-boards/sim/sim_mem.c b/arch/mips/mips-boards/sim/sim_mem.c
new file mode 100644
index 000000000000..0dbd7435bb2a
--- /dev/null
+++ b/arch/mips/mips-boards/sim/sim_mem.c
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2005 MIPS Technologies, Inc. All rights reserved.
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ */
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/bootmem.h>
+
+#include <asm/bootinfo.h>
+#include <asm/page.h>
+
+#include <asm/mips-boards/prom.h>
+
+/*#define DEBUG*/
+
+enum simmem_memtypes {
+ simmem_reserved = 0,
+ simmem_free,
+};
+struct prom_pmemblock mdesc[PROM_MAX_PMEMBLOCKS];
+
+#ifdef DEBUG
+static char *mtypes[3] = {
+ "SIM reserved memory",
+ "SIM free memory",
+};
+#endif
+
+/* References to section boundaries */
+extern char _end;
+
+#define PFN_ALIGN(x) (((unsigned long)(x) + (PAGE_SIZE - 1)) & PAGE_MASK)
+
+
+struct prom_pmemblock * __init prom_getmdesc(void)
+{
+ unsigned int memsize;
+
+ memsize = 0x02000000;
+ prom_printf("Setting default memory size 0x%08x\n", memsize);
+
+ memset(mdesc, 0, sizeof(mdesc));
+
+ mdesc[0].type = simmem_reserved;
+ mdesc[0].base = 0x00000000;
+ mdesc[0].size = 0x00001000;
+
+ mdesc[1].type = simmem_free;
+ mdesc[1].base = 0x00001000;
+ mdesc[1].size = 0x000ff000;
+
+ mdesc[2].type = simmem_reserved;
+ mdesc[2].base = 0x00100000;
+ mdesc[2].size = CPHYSADDR(PFN_ALIGN(&_end)) - mdesc[2].base;
+
+ mdesc[3].type = simmem_free;
+ mdesc[3].base = CPHYSADDR(PFN_ALIGN(&_end));
+ mdesc[3].size = memsize - mdesc[3].base;
+
+ return &mdesc[0];
+}
+
+static int __init prom_memtype_classify (unsigned int type)
+{
+ switch (type) {
+ case simmem_free:
+ return BOOT_MEM_RAM;
+ case simmem_reserved:
+ default:
+ return BOOT_MEM_RESERVED;
+ }
+}
+
+void __init prom_meminit(void)
+{
+ struct prom_pmemblock *p;
+
+ p = prom_getmdesc();
+
+ while (p->size) {
+ long type;
+ unsigned long base, size;
+
+ type = prom_memtype_classify (p->type);
+ base = p->base;
+ size = p->size;
+
+ add_memory_region(base, size, type);
+ p++;
+ }
+}
+
+unsigned long __init prom_free_prom_memory(void)
+{
+ int i;
+ unsigned long freed = 0;
+ unsigned long addr;
+
+ for (i = 0; i < boot_mem_map.nr_map; i++) {
+ if (boot_mem_map.map[i].type != BOOT_MEM_ROM_DATA)
+ continue;
+
+ addr = boot_mem_map.map[i].addr;
+ while (addr < boot_mem_map.map[i].addr
+ + boot_mem_map.map[i].size) {
+ ClearPageReserved(virt_to_page(__va(addr)));
+ set_page_count(virt_to_page(__va(addr)), 1);
+ free_page((unsigned long)__va(addr));
+ addr += PAGE_SIZE;
+ freed += PAGE_SIZE;
+ }
+ }
+ printk("Freeing prom memory: %ldkb freed\n", freed >> 10);
+
+ return freed;
+}
diff --git a/arch/mips/mips-boards/sim/sim_printf.c b/arch/mips/mips-boards/sim/sim_printf.c
new file mode 100644
index 000000000000..3ee5a0b501a6
--- /dev/null
+++ b/arch/mips/mips-boards/sim/sim_printf.c
@@ -0,0 +1,74 @@
+/*
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved.
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Putting things on the screen/serial line using YAMONs facilities.
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/serial_reg.h>
+#include <linux/spinlock.h>
+#include <asm/io.h>
+#include <asm/system.h>
+
+static inline unsigned int serial_in(int offset)
+{
+ return inb(0x3f8 + offset);
+}
+
+static inline void serial_out(int offset, int value)
+{
+ outb(value, 0x3f8 + offset);
+}
+
+int putPromChar(char c)
+{
+ while ((serial_in(UART_LSR) & UART_LSR_THRE) == 0)
+ ;
+
+ serial_out(UART_TX, c);
+
+ return 1;
+}
+
+char getPromChar(void)
+{
+ while (!(serial_in(UART_LSR) & 1))
+ ;
+
+ return serial_in(UART_RX);
+}
+
+void prom_printf(char *fmt, ...)
+{
+ va_list args;
+ int l;
+ char *p, *buf_end;
+ char buf[1024];
+
+ va_start(args, fmt);
+ l = vsprintf(buf, fmt, args); /* hopefully i < sizeof(buf) */
+ va_end(args);
+
+ buf_end = buf + l;
+
+ for (p = buf; p < buf_end; p++) {
+ /* Crude cr/nl handling is better than none */
+ if (*p == '\n')
+ putPromChar('\r');
+ putPromChar(*p);
+ }
+}
diff --git a/arch/mips/mips-boards/sim/sim_setup.c b/arch/mips/mips-boards/sim/sim_setup.c
new file mode 100644
index 000000000000..485d5a58d9cf
--- /dev/null
+++ b/arch/mips/mips-boards/sim/sim_setup.c
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2005 MIPS Technologies, Inc. All rights reserved.
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <linux/ioport.h>
+#include <linux/tty.h>
+#include <linux/serial.h>
+#include <linux/serial_core.h>
+
+#include <asm/cpu.h>
+#include <asm/bootinfo.h>
+#include <asm/irq.h>
+#include <asm/mips-boards/generic.h>
+#include <asm/mips-boards/prom.h>
+#include <asm/serial.h>
+#include <asm/io.h>
+#include <asm/time.h>
+#include <asm/mips-boards/sim.h>
+#include <asm/mips-boards/simint.h>
+
+
+extern void sim_time_init(void);
+extern void sim_timer_setup(struct irqaction *irq);
+static void __init serial_init(void);
+unsigned int _isbonito = 0;
+
+extern void __init sanitize_tlb_entries(void);
+
+
+const char *get_system_type(void)
+{
+ return "MIPSsim";
+}
+
+void __init plat_setup(void)
+{
+ set_io_port_base(0xbfd00000);
+
+ serial_init();
+
+ board_time_init = sim_time_init;
+ board_timer_setup = sim_timer_setup;
+ prom_printf("Linux started...\n");
+
+#ifdef CONFIG_MT_SMP
+ sanitize_tlb_entries();
+#endif
+}
+
+void prom_init(void)
+{
+ set_io_port_base(0xbfd00000);
+
+ prom_printf("\nLINUX started...\n");
+ prom_init_cmdline();
+ prom_meminit();
+}
+
+
+static void __init serial_init(void)
+{
+#ifdef CONFIG_SERIAL_8250
+ struct uart_port s;
+
+ memset(&s, 0, sizeof(s));
+
+ s.iobase = 0x3f8;
+
+ /* hardware int 4 - the serial int, is CPU int 6
+ but poll for now */
+ s.irq = 0;
+ s.uartclk = BASE_BAUD * 16;
+ s.flags = ASYNC_BOOT_AUTOCONF | UPF_SKIP_TEST;
+ s.iotype = SERIAL_IO_PORT | ASYNC_SKIP_TEST;
+ s.regshift = 0;
+ s.timeout = 4;
+
+ if (early_serial_setup(&s) != 0) {
+ prom_printf(KERN_ERR "Serial setup failed!\n");
+ }
+
+#endif
+}
diff --git a/arch/mips/mips-boards/sim/sim_smp.c b/arch/mips/mips-boards/sim/sim_smp.c
new file mode 100644
index 000000000000..19824359f5de
--- /dev/null
+++ b/arch/mips/mips-boards/sim/sim_smp.c
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2005 MIPS Technologies, Inc. All rights reserved.
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ */
+/*
+ * Simulator Platform-specific hooks for SMP operation
+ */
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/cpumask.h>
+#include <linux/interrupt.h>
+#include <asm/atomic.h>
+#include <asm/cpu.h>
+#include <asm/processor.h>
+#include <asm/system.h>
+#include <asm/hardirq.h>
+#include <asm/mmu_context.h>
+#include <asm/smp.h>
+#ifdef CONFIG_MIPS_MT_SMTC
+#include <asm/smtc_ipi.h>
+#endif /* CONFIG_MIPS_MT_SMTC */
+
+/* VPE/SMP Prototype implements platform interfaces directly */
+#if !defined(CONFIG_MIPS_MT_SMP)
+
+/*
+ * Cause the specified action to be performed on a targeted "CPU"
+ */
+
+void core_send_ipi(int cpu, unsigned int action)
+{
+#ifdef CONFIG_MIPS_MT_SMTC
+ void smtc_send_ipi(int, int, unsigned int);
+
+ smtc_send_ipi(cpu, LINUX_SMP_IPI, action);
+#endif /* CONFIG_MIPS_MT_SMTC */
+/* "CPU" may be TC of same VPE, VPE of same CPU, or different CPU */
+
+}
+
+/*
+ * Detect available CPUs/VPEs/TCs and populate phys_cpu_present_map
+ */
+
+void __init prom_build_cpu_map(void)
+{
+#ifdef CONFIG_MIPS_MT_SMTC
+ extern int mipsmt_build_cpu_map(int startslot);
+ int nextslot;
+
+ cpus_clear(phys_cpu_present_map);
+
+ /* Register the boot CPU */
+
+ smp_prepare_boot_cpu();
+
+ /*
+ * As of November, 2004, MIPSsim only simulates one core
+ * at a time. However, that core may be a MIPS MT core
+ * with multiple virtual processors and thread contexts.
+ */
+
+ if (read_c0_config3() & (1<<2)) {
+ nextslot = mipsmt_build_cpu_map(1);
+ }
+#endif /* CONFIG_MIPS_MT_SMTC */
+}
+
+/*
+ * Platform "CPU" startup hook
+ */
+
+void prom_boot_secondary(int cpu, struct task_struct *idle)
+{
+#ifdef CONFIG_MIPS_MT_SMTC
+ extern void smtc_boot_secondary(int cpu, struct task_struct *t);
+
+ smtc_boot_secondary(cpu, idle);
+#endif /* CONFIG_MIPS_MT_SMTC */
+}
+
+/*
+ * Post-config but pre-boot cleanup entry point
+ */
+
+void prom_init_secondary(void)
+{
+#ifdef CONFIG_MIPS_MT_SMTC
+ void smtc_init_secondary(void);
+
+ smtc_init_secondary();
+#endif /* CONFIG_MIPS_MT_SMTC */
+}
+
+/*
+ * Platform SMP pre-initialization
+ */
+
+void prom_prepare_cpus(unsigned int max_cpus)
+{
+#ifdef CONFIG_MIPS_MT_SMTC
+ void mipsmt_prepare_cpus(int c);
+ /*
+ * As noted above, we can assume a single CPU for now
+ * but it may be multithreaded.
+ */
+
+ if (read_c0_config3() & (1<<2)) {
+ mipsmt_prepare_cpus(max_cpus);
+ }
+#endif /* CONFIG_MIPS_MT_SMTC */
+}
+
+/*
+ * SMP initialization finalization entry point
+ */
+
+void prom_smp_finish(void)
+{
+#ifdef CONFIG_MIPS_MT_SMTC
+ void smtc_smp_finish(void);
+
+ smtc_smp_finish();
+#endif /* CONFIG_MIPS_MT_SMTC */
+}
+
+/*
+ * Hook for after all CPUs are online
+ */
+
+void prom_cpus_done(void)
+{
+#ifdef CONFIG_MIPS_MT_SMTC
+
+#endif /* CONFIG_MIPS_MT_SMTC */
+}
+#endif /* CONFIG_MIPS32R2_MT_SMP */
diff --git a/arch/mips/mips-boards/sim/sim_time.c b/arch/mips/mips-boards/sim/sim_time.c
new file mode 100644
index 000000000000..18b968c696d1
--- /dev/null
+++ b/arch/mips/mips-boards/sim/sim_time.c
@@ -0,0 +1,215 @@
+#include <linux/types.h>
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/kernel_stat.h>
+#include <linux/sched.h>
+#include <linux/spinlock.h>
+
+#include <asm/mipsregs.h>
+#include <asm/ptrace.h>
+#include <asm/hardirq.h>
+#include <asm/div64.h>
+#include <asm/cpu.h>
+#include <asm/time.h>
+
+#include <linux/interrupt.h>
+#include <linux/mc146818rtc.h>
+#include <linux/timex.h>
+#include <asm/mipsregs.h>
+#include <asm/ptrace.h>
+#include <asm/hardirq.h>
+#include <asm/irq.h>
+#include <asm/div64.h>
+#include <asm/cpu.h>
+#include <asm/time.h>
+#include <asm/mc146818-time.h>
+#include <asm/msc01_ic.h>
+
+#include <asm/mips-boards/generic.h>
+#include <asm/mips-boards/prom.h>
+#include <asm/mips-boards/simint.h>
+#include <asm/mc146818-time.h>
+#include <asm/smp.h>
+
+
+unsigned long cpu_khz;
+
+extern asmlinkage void ll_local_timer_interrupt(int irq, struct pt_regs *regs);
+
+irqreturn_t sim_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+#ifdef CONFIG_SMP
+ int cpu = smp_processor_id();
+
+ /*
+ * CPU 0 handles the global timer interrupt job
+ * resets count/compare registers to trigger next timer int.
+ */
+#ifndef CONFIG_MIPS_MT_SMTC
+ if (cpu == 0) {
+ timer_interrupt(irq, dev_id, regs);
+ }
+ else {
+ /* Everyone else needs to reset the timer int here as
+ ll_local_timer_interrupt doesn't */
+ /*
+ * FIXME: need to cope with counter underflow.
+ * More support needs to be added to kernel/time for
+ * counter/timer interrupts on multiple CPU's
+ */
+ write_c0_compare (read_c0_count() + ( mips_hpt_frequency/HZ));
+ }
+#else /* SMTC */
+ /*
+ * In SMTC system, one Count/Compare set exists per VPE.
+ * Which TC within a VPE gets the interrupt is essentially
+ * random - we only know that it shouldn't be one with
+ * IXMT set. Whichever TC gets the interrupt needs to
+ * send special interprocessor interrupts to the other
+ * TCs to make sure that they schedule, etc.
+ *
+ * That code is specific to the SMTC kernel, not to
+ * the simulation platform, so it's invoked from
+ * the general MIPS timer_interrupt routine.
+ *
+ * We have a problem in that the interrupt vector code
+ * had to turn off the timer IM bit to avoid redundant
+ * entries, but we may never get to mips_cpu_irq_end
+ * to turn it back on again if the scheduler gets
+ * involved. So we clear the pending timer here,
+ * and re-enable the mask...
+ */
+
+ int vpflags = dvpe();
+ write_c0_compare (read_c0_count() - 1);
+ clear_c0_cause(0x100 << MIPSCPU_INT_CPUCTR);
+ set_c0_status(0x100 << MIPSCPU_INT_CPUCTR);
+ irq_enable_hazard();
+ evpe(vpflags);
+
+ if(cpu_data[cpu].vpe_id == 0) timer_interrupt(irq, dev_id, regs);
+ else write_c0_compare (read_c0_count() + ( mips_hpt_frequency/HZ));
+ smtc_timer_broadcast(cpu_data[cpu].vpe_id);
+
+#endif /* CONFIG_MIPS_MT_SMTC */
+
+ /*
+ * every CPU should do profiling and process accounting
+ */
+ local_timer_interrupt (irq, dev_id, regs);
+ return IRQ_HANDLED;
+#else
+ return timer_interrupt (irq, dev_id, regs);
+#endif
+}
+
+
+
+/*
+ * Estimate CPU frequency. Sets mips_counter_frequency as a side-effect
+ */
+static unsigned int __init estimate_cpu_frequency(void)
+{
+ unsigned int prid = read_c0_prid() & 0xffff00;
+ unsigned int count;
+
+#if 1
+ /*
+ * hardwire the board frequency to 12MHz.
+ */
+
+ if ((prid == (PRID_COMP_MIPS | PRID_IMP_20KC)) ||
+ (prid == (PRID_COMP_MIPS | PRID_IMP_25KF)))
+ count = 12000000;
+ else
+ count = 6000000;
+#else
+ unsigned int flags;
+
+ local_irq_save(flags);
+
+ /* Start counter exactly on falling edge of update flag */
+ while (CMOS_READ(RTC_REG_A) & RTC_UIP);
+ while (!(CMOS_READ(RTC_REG_A) & RTC_UIP));
+
+ /* Start r4k counter. */
+ write_c0_count(0);
+
+ /* Read counter exactly on falling edge of update flag */
+ while (CMOS_READ(RTC_REG_A) & RTC_UIP);
+ while (!(CMOS_READ(RTC_REG_A) & RTC_UIP));
+
+ count = read_c0_count();
+
+ /* restore interrupts */
+ local_irq_restore(flags);
+#endif
+
+ mips_hpt_frequency = count;
+
+ if ((prid != (PRID_COMP_MIPS | PRID_IMP_20KC)) &&
+ (prid != (PRID_COMP_MIPS | PRID_IMP_25KF)))
+ count *= 2;
+
+ count += 5000; /* round */
+ count -= count%10000;
+
+ return count;
+}
+
+void __init sim_time_init(void)
+{
+ unsigned int est_freq, flags;
+
+ local_irq_save(flags);
+
+
+ /* Set Data mode - binary. */
+ CMOS_WRITE(CMOS_READ(RTC_CONTROL) | RTC_DM_BINARY, RTC_CONTROL);
+
+
+ est_freq = estimate_cpu_frequency ();
+
+ printk("CPU frequency %d.%02d MHz\n", est_freq/1000000,
+ (est_freq%1000000)*100/1000000);
+
+ cpu_khz = est_freq / 1000;
+
+ local_irq_restore(flags);
+}
+
+static int mips_cpu_timer_irq;
+
+static void mips_timer_dispatch (struct pt_regs *regs)
+{
+ do_IRQ (mips_cpu_timer_irq, regs);
+}
+
+
+void __init sim_timer_setup(struct irqaction *irq)
+{
+ if (cpu_has_veic) {
+ set_vi_handler(MSC01E_INT_CPUCTR, mips_timer_dispatch);
+ mips_cpu_timer_irq = MSC01E_INT_BASE + MSC01E_INT_CPUCTR;
+ }
+ else {
+ if (cpu_has_vint)
+ set_vi_handler(MIPSCPU_INT_CPUCTR, mips_timer_dispatch);
+ mips_cpu_timer_irq = MIPSCPU_INT_BASE + MIPSCPU_INT_CPUCTR;
+ }
+
+ /* we are using the cpu counter for timer interrupts */
+ irq->handler = sim_timer_interrupt;
+ setup_irq(mips_cpu_timer_irq, irq);
+
+#ifdef CONFIG_SMP
+ /* irq_desc(riptor) is a global resource, when the interrupt overlaps
+ on seperate cpu's the first one tries to handle the second interrupt.
+ The effect is that the int remains disabled on the second cpu.
+ Mark the interrupt with IRQ_PER_CPU to avoid any confusion */
+ irq_desc[mips_cpu_timer_irq].status |= IRQ_PER_CPU;
+#endif
+
+ /* to generate the first timer interrupt */
+ write_c0_compare(read_c0_count() + (mips_hpt_frequency/HZ));
+}
diff --git a/arch/mips/mm/Makefile b/arch/mips/mm/Makefile
index b56a0abdc3d4..b0178da019f0 100644
--- a/arch/mips/mm/Makefile
+++ b/arch/mips/mm/Makefile
@@ -22,7 +22,7 @@ obj-$(CONFIG_CPU_R8000) += c-r4k.o cex-gen.o pg-r4k.o tlb-r8k.o
obj-$(CONFIG_CPU_RM7000) += c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o
obj-$(CONFIG_CPU_RM9000) += c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o
obj-$(CONFIG_CPU_SB1) += c-sb1.o cerr-sb1.o cex-sb1.o pg-sb1.o \
- tlb-sb1.o
+ tlb-r4k.o
obj-$(CONFIG_CPU_TX39XX) += c-tx39.o pg-r4k.o tlb-r3k.o
obj-$(CONFIG_CPU_TX49XX) += c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o
obj-$(CONFIG_CPU_VR41XX) += c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o
diff --git a/arch/mips/mm/c-r3k.c b/arch/mips/mm/c-r3k.c
index c659f99eb39a..27f4fa25e8c9 100644
--- a/arch/mips/mm/c-r3k.c
+++ b/arch/mips/mm/c-r3k.c
@@ -221,12 +221,14 @@ static inline unsigned long get_phys_page (unsigned long addr,
struct mm_struct *mm)
{
pgd_t *pgd;
+ pud_t *pud;
pmd_t *pmd;
pte_t *pte;
unsigned long physpage;
pgd = pgd_offset(mm, addr);
- pmd = pmd_offset(pgd, addr);
+ pud = pud_offset(pgd, addr);
+ pmd = pmd_offset(pud, addr);
pte = pte_offset(pmd, addr);
if ((physpage = pte_val(*pte)) & _PAGE_VALID)
@@ -317,7 +319,7 @@ static void r3k_dma_cache_wback_inv(unsigned long start, unsigned long size)
r3k_flush_dcache_range(start, start + size);
}
-void __init ld_mmu_r23000(void)
+void __init r3k_cache_init(void)
{
extern void build_clear_page(void);
extern void build_copy_page(void);
diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c
index 5ea84bc98c6a..38223b44d962 100644
--- a/arch/mips/mm/c-r4k.c
+++ b/arch/mips/mm/c-r4k.c
@@ -16,6 +16,7 @@
#include <asm/bcache.h>
#include <asm/bootinfo.h>
+#include <asm/cache.h>
#include <asm/cacheops.h>
#include <asm/cpu.h>
#include <asm/cpu-features.h>
@@ -26,8 +27,14 @@
#include <asm/system.h>
#include <asm/mmu_context.h>
#include <asm/war.h>
+#include <asm/cacheflush.h> /* for run_uncached() */
-static unsigned long icache_size, dcache_size, scache_size;
+/*
+ * Must die.
+ */
+static unsigned long icache_size __read_mostly;
+static unsigned long dcache_size __read_mostly;
+static unsigned long scache_size __read_mostly;
/*
* Dummy cache handling routines for machines without boardcaches
@@ -43,8 +50,8 @@ static struct bcache_ops no_sc_ops = {
struct bcache_ops *bcops = &no_sc_ops;
-#define cpu_is_r4600_v1_x() ((read_c0_prid() & 0xfffffff0) == 0x2010)
-#define cpu_is_r4600_v2_x() ((read_c0_prid() & 0xfffffff0) == 0x2020)
+#define cpu_is_r4600_v1_x() ((read_c0_prid() & 0xfffffff0) == 0x00002010)
+#define cpu_is_r4600_v2_x() ((read_c0_prid() & 0xfffffff0) == 0x00002020)
#define R4600_HIT_CACHEOP_WAR_IMPL \
do { \
@@ -190,12 +197,12 @@ static inline void r4k_blast_icache_page_indexed_setup(void)
if (ic_lsize == 16)
r4k_blast_icache_page_indexed = blast_icache16_page_indexed;
else if (ic_lsize == 32) {
- if (TX49XX_ICACHE_INDEX_INV_WAR)
- r4k_blast_icache_page_indexed =
- tx49_blast_icache32_page_indexed;
- else if (R4600_V1_INDEX_ICACHEOP_WAR && cpu_is_r4600_v1_x())
+ if (R4600_V1_INDEX_ICACHEOP_WAR && cpu_is_r4600_v1_x())
r4k_blast_icache_page_indexed =
blast_icache32_r4600_v1_page_indexed;
+ else if (TX49XX_ICACHE_INDEX_INV_WAR)
+ r4k_blast_icache_page_indexed =
+ tx49_blast_icache32_page_indexed;
else
r4k_blast_icache_page_indexed =
blast_icache32_page_indexed;
@@ -361,24 +368,33 @@ static void r4k_flush_cache_mm(struct mm_struct *mm)
struct flush_cache_page_args {
struct vm_area_struct *vma;
- unsigned long page;
+ unsigned long addr;
};
static inline void local_r4k_flush_cache_page(void *args)
{
struct flush_cache_page_args *fcp_args = args;
struct vm_area_struct *vma = fcp_args->vma;
- unsigned long page = fcp_args->page;
+ unsigned long addr = fcp_args->addr;
int exec = vma->vm_flags & VM_EXEC;
struct mm_struct *mm = vma->vm_mm;
pgd_t *pgdp;
+ pud_t *pudp;
pmd_t *pmdp;
pte_t *ptep;
- page &= PAGE_MASK;
- pgdp = pgd_offset(mm, page);
- pmdp = pmd_offset(pgdp, page);
- ptep = pte_offset(pmdp, page);
+ /*
+ * If ownes no valid ASID yet, cannot possibly have gotten
+ * this page into the cache.
+ */
+ if (cpu_context(smp_processor_id(), mm) == 0)
+ return;
+
+ addr &= PAGE_MASK;
+ pgdp = pgd_offset(mm, addr);
+ pudp = pud_offset(pgdp, addr);
+ pmdp = pmd_offset(pudp, addr);
+ ptep = pte_offset(pmdp, addr);
/*
* If the page isn't marked valid, the page cannot possibly be
@@ -395,12 +411,12 @@ static inline void local_r4k_flush_cache_page(void *args)
*/
if ((mm == current->active_mm) && (pte_val(*ptep) & _PAGE_VALID)) {
if (cpu_has_dc_aliases || (exec && !cpu_has_ic_fills_f_dc)) {
- r4k_blast_dcache_page(page);
+ r4k_blast_dcache_page(addr);
if (exec && !cpu_icache_snoops_remote_store)
- r4k_blast_scache_page(page);
+ r4k_blast_scache_page(addr);
}
if (exec)
- r4k_blast_icache_page(page);
+ r4k_blast_icache_page(addr);
return;
}
@@ -409,36 +425,30 @@ static inline void local_r4k_flush_cache_page(void *args)
* Do indexed flush, too much work to get the (possible) TLB refills
* to work correctly.
*/
- page = INDEX_BASE + (page & (dcache_size - 1));
+ addr = INDEX_BASE + (addr & (dcache_size - 1));
if (cpu_has_dc_aliases || (exec && !cpu_has_ic_fills_f_dc)) {
- r4k_blast_dcache_page_indexed(page);
+ r4k_blast_dcache_page_indexed(addr);
if (exec && !cpu_icache_snoops_remote_store)
- r4k_blast_scache_page_indexed(page);
+ r4k_blast_scache_page_indexed(addr);
}
if (exec) {
if (cpu_has_vtag_icache) {
int cpu = smp_processor_id();
- if (cpu_context(cpu, vma->vm_mm) != 0)
- drop_mmu_context(vma->vm_mm, cpu);
+ if (cpu_context(cpu, mm) != 0)
+ drop_mmu_context(mm, cpu);
} else
- r4k_blast_icache_page_indexed(page);
+ r4k_blast_icache_page_indexed(addr);
}
}
-static void r4k_flush_cache_page(struct vm_area_struct *vma, unsigned long page, unsigned long pfn)
+static void r4k_flush_cache_page(struct vm_area_struct *vma,
+ unsigned long addr, unsigned long pfn)
{
struct flush_cache_page_args args;
- /*
- * If ownes no valid ASID yet, cannot possibly have gotten
- * this page into the cache.
- */
- if (cpu_context(smp_processor_id(), vma->vm_mm) == 0)
- return;
-
args.vma = vma;
- args.page = page;
+ args.addr = addr;
on_each_cpu(local_r4k_flush_cache_page, &args, 1, 1);
}
@@ -454,16 +464,16 @@ static void r4k_flush_data_cache_page(unsigned long addr)
}
struct flush_icache_range_args {
- unsigned long start;
- unsigned long end;
+ unsigned long __user start;
+ unsigned long __user end;
};
static inline void local_r4k_flush_icache_range(void *args)
{
struct flush_icache_range_args *fir_args = args;
- unsigned long dc_lsize = current_cpu_data.dcache.linesz;
- unsigned long ic_lsize = current_cpu_data.icache.linesz;
- unsigned long sc_lsize = current_cpu_data.scache.linesz;
+ unsigned long dc_lsize = cpu_dcache_line_size();
+ unsigned long ic_lsize = cpu_icache_line_size();
+ unsigned long sc_lsize = cpu_scache_line_size();
unsigned long start = fir_args->start;
unsigned long end = fir_args->end;
unsigned long addr, aend;
@@ -472,6 +482,7 @@ static inline void local_r4k_flush_icache_range(void *args)
if (end - start > dcache_size) {
r4k_blast_dcache();
} else {
+ R4600_HIT_CACHEOP_WAR_IMPL;
addr = start & ~(dc_lsize - 1);
aend = (end - 1) & ~(dc_lsize - 1);
@@ -492,7 +503,7 @@ static inline void local_r4k_flush_icache_range(void *args)
aend = (end - 1) & ~(sc_lsize - 1);
while (1) {
- /* Hit_Writeback_Inv_D */
+ /* Hit_Writeback_Inv_SD */
protected_writeback_scache_line(addr);
if (addr == aend)
break;
@@ -517,7 +528,8 @@ static inline void local_r4k_flush_icache_range(void *args)
}
}
-static void r4k_flush_icache_range(unsigned long start, unsigned long end)
+static void r4k_flush_icache_range(unsigned long __user start,
+ unsigned long __user end)
{
struct flush_icache_range_args args;
@@ -525,6 +537,7 @@ static void r4k_flush_icache_range(unsigned long start, unsigned long end)
args.end = end;
on_each_cpu(local_r4k_flush_icache_range, &args, 1, 1);
+ instruction_hazard();
}
/*
@@ -613,7 +626,7 @@ static void r4k_dma_cache_wback_inv(unsigned long addr, unsigned long size)
BUG_ON(size == 0);
if (cpu_has_subset_pcaches) {
- unsigned long sc_lsize = current_cpu_data.scache.linesz;
+ unsigned long sc_lsize = cpu_scache_line_size();
if (size >= scache_size) {
r4k_blast_scache();
@@ -639,7 +652,7 @@ static void r4k_dma_cache_wback_inv(unsigned long addr, unsigned long size)
if (size >= dcache_size) {
r4k_blast_dcache();
} else {
- unsigned long dc_lsize = current_cpu_data.dcache.linesz;
+ unsigned long dc_lsize = cpu_dcache_line_size();
R4600_HIT_CACHEOP_WAR_IMPL;
a = addr & ~(dc_lsize - 1);
@@ -663,7 +676,7 @@ static void r4k_dma_cache_inv(unsigned long addr, unsigned long size)
BUG_ON(size == 0);
if (cpu_has_subset_pcaches) {
- unsigned long sc_lsize = current_cpu_data.scache.linesz;
+ unsigned long sc_lsize = cpu_scache_line_size();
if (size >= scache_size) {
r4k_blast_scache();
@@ -684,7 +697,7 @@ static void r4k_dma_cache_inv(unsigned long addr, unsigned long size)
if (size >= dcache_size) {
r4k_blast_dcache();
} else {
- unsigned long dc_lsize = current_cpu_data.dcache.linesz;
+ unsigned long dc_lsize = cpu_dcache_line_size();
R4600_HIT_CACHEOP_WAR_IMPL;
a = addr & ~(dc_lsize - 1);
@@ -708,9 +721,9 @@ static void r4k_dma_cache_inv(unsigned long addr, unsigned long size)
*/
static void local_r4k_flush_cache_sigtramp(void * arg)
{
- unsigned long ic_lsize = current_cpu_data.icache.linesz;
- unsigned long dc_lsize = current_cpu_data.dcache.linesz;
- unsigned long sc_lsize = current_cpu_data.scache.linesz;
+ unsigned long ic_lsize = cpu_icache_line_size();
+ unsigned long dc_lsize = cpu_dcache_line_size();
+ unsigned long sc_lsize = cpu_scache_line_size();
unsigned long addr = (unsigned long) arg;
R4600_HIT_CACHEOP_WAR_IMPL;
@@ -762,6 +775,7 @@ static inline void rm7k_erratum31(void)
for (addr = INDEX_BASE; addr <= INDEX_BASE + 4096; addr += ic_lsize) {
__asm__ __volatile__ (
+ ".set push\n\t"
".set noreorder\n\t"
".set mips3\n\t"
"cache\t%1, 0(%0)\n\t"
@@ -776,8 +790,7 @@ static inline void rm7k_erratum31(void)
"cache\t%1, 0x1000(%0)\n\t"
"cache\t%1, 0x2000(%0)\n\t"
"cache\t%1, 0x3000(%0)\n\t"
- ".set\tmips0\n\t"
- ".set\treorder\n\t"
+ ".set pop\n"
:
: "r" (addr), "i" (Index_Store_Tag_I), "i" (Fill));
}
@@ -1011,9 +1024,19 @@ static void __init probe_pcache(void)
* normally they'd suffer from aliases but magic in the hardware deals
* with that for us so we don't need to take care ourselves.
*/
- if (c->cputype != CPU_R10000 && c->cputype != CPU_R12000)
- if (c->dcache.waysize > PAGE_SIZE)
- c->dcache.flags |= MIPS_CACHE_ALIASES;
+ switch (c->cputype) {
+ case CPU_20KC:
+ case CPU_25KF:
+ case CPU_R10000:
+ case CPU_R12000:
+ case CPU_SB1:
+ break;
+ case CPU_24K:
+ if (!(read_c0_config7() & (1 << 16)))
+ default:
+ if (c->dcache.waysize > PAGE_SIZE)
+ c->dcache.flags |= MIPS_CACHE_ALIASES;
+ }
switch (c->cputype) {
case CPU_20KC:
@@ -1024,7 +1047,11 @@ static void __init probe_pcache(void)
c->icache.flags |= MIPS_CACHE_VTAG;
break;
+ case CPU_AU1000:
case CPU_AU1500:
+ case CPU_AU1100:
+ case CPU_AU1550:
+ case CPU_AU1200:
c->icache.flags |= MIPS_CACHE_IC_F_DC;
break;
}
@@ -1102,7 +1129,6 @@ static int __init probe_scache(void)
return 1;
}
-typedef int (*probe_func_t)(unsigned long);
extern int r5k_sc_init(void);
extern int rm7k_sc_init(void);
@@ -1110,7 +1136,6 @@ static void __init setup_scache(void)
{
struct cpuinfo_mips *c = &current_cpu_data;
unsigned int config = read_c0_config();
- probe_func_t probe_scache_kseg1;
int sc_present = 0;
/*
@@ -1123,8 +1148,7 @@ static void __init setup_scache(void)
case CPU_R4000MC:
case CPU_R4400SC:
case CPU_R4400MC:
- probe_scache_kseg1 = (probe_func_t) (CKSEG1ADDR(&probe_scache));
- sc_present = probe_scache_kseg1(config);
+ sc_present = run_uncached(probe_scache);
if (sc_present)
c->options |= MIPS_CPU_CACHE_CDEX_S;
break;
@@ -1198,7 +1222,7 @@ static inline void coherency_setup(void)
}
}
-void __init ld_mmu_r4xx0(void)
+void __init r4k_cache_init(void)
{
extern void build_clear_page(void);
extern void build_copy_page(void);
@@ -1206,15 +1230,11 @@ void __init ld_mmu_r4xx0(void)
struct cpuinfo_mips *c = &current_cpu_data;
/* Default cache error handler for R4000 and R5000 family */
- memcpy((void *)(CAC_BASE + 0x100), &except_vec2_generic, 0x80);
- memcpy((void *)(UNCAC_BASE + 0x100), &except_vec2_generic, 0x80);
+ set_uncached_handler (0x100, &except_vec2_generic, 0x80);
probe_pcache();
setup_scache();
- if (c->dcache.sets * c->dcache.ways > PAGE_SIZE)
- c->dcache.flags |= MIPS_CACHE_ALIASES;
-
r4k_blast_dcache_page_setup();
r4k_blast_dcache_page_indexed_setup();
r4k_blast_dcache_setup();
@@ -1252,9 +1272,8 @@ void __init ld_mmu_r4xx0(void)
_dma_cache_inv = r4k_dma_cache_inv;
#endif
- __flush_cache_all();
- coherency_setup();
-
build_clear_page();
build_copy_page();
+ local_r4k___flush_cache_all(NULL);
+ coherency_setup();
}
diff --git a/arch/mips/mm/c-sb1.c b/arch/mips/mm/c-sb1.c
index 502f68c664b2..2f08b535f20e 100644
--- a/arch/mips/mm/c-sb1.c
+++ b/arch/mips/mm/c-sb1.c
@@ -235,7 +235,7 @@ static inline void __sb1_flush_icache_range(unsigned long start,
/*
* Invalidate all caches on this CPU
*/
-static void local_sb1___flush_cache_all(void)
+static void __attribute_used__ local_sb1___flush_cache_all(void)
{
__sb1_writeback_inv_dcache_all();
__sb1_flush_icache_all();
@@ -492,19 +492,17 @@ static __init void probe_cache_sizes(void)
}
/*
- * This is called from loadmmu.c. We have to set up all the
+ * This is called from cache.c. We have to set up all the
* memory management function pointers, as well as initialize
* the caches and tlbs
*/
-void ld_mmu_sb1(void)
+void sb1_cache_init(void)
{
extern char except_vec2_sb1;
extern char handle_vec2_sb1;
/* Special cache error handler for SB1 */
- memcpy((void *)(CAC_BASE + 0x100), &except_vec2_sb1, 0x80);
- memcpy((void *)(UNCAC_BASE + 0x100), &except_vec2_sb1, 0x80);
- memcpy((void *)CKSEG1ADDR(&handle_vec2_sb1), &handle_vec2_sb1, 0x80);
+ set_uncached_handler (0x100, &except_vec2_sb1, 0x80);
probe_cache_sizes();
diff --git a/arch/mips/mm/c-tx39.c b/arch/mips/mm/c-tx39.c
index ff5afab64b2f..0a97a9434eba 100644
--- a/arch/mips/mm/c-tx39.c
+++ b/arch/mips/mm/c-tx39.c
@@ -167,15 +167,16 @@ static void tx39_flush_cache_mm(struct mm_struct *mm)
static void tx39_flush_cache_range(struct vm_area_struct *vma,
unsigned long start, unsigned long end)
{
- struct mm_struct *mm = vma->vm_mm;
+ int exec;
- if (!cpu_has_dc_aliases)
+ if (!(cpu_context(smp_processor_id(), vma->vm_mm)))
return;
- if (cpu_context(smp_processor_id(), mm) != 0) {
+ exec = vma->vm_flags & VM_EXEC;
+ if (cpu_has_dc_aliases || exec)
tx39_blast_dcache();
+ if (exec)
tx39_blast_icache();
- }
}
static void tx39_flush_cache_page(struct vm_area_struct *vma, unsigned long page, unsigned long pfn)
@@ -183,6 +184,7 @@ static void tx39_flush_cache_page(struct vm_area_struct *vma, unsigned long page
int exec = vma->vm_flags & VM_EXEC;
struct mm_struct *mm = vma->vm_mm;
pgd_t *pgdp;
+ pud_t *pudp;
pmd_t *pmdp;
pte_t *ptep;
@@ -195,7 +197,8 @@ static void tx39_flush_cache_page(struct vm_area_struct *vma, unsigned long page
page &= PAGE_MASK;
pgdp = pgd_offset(mm, page);
- pmdp = pmd_offset(pgdp, page);
+ pudp = pud_offset(pgdp, page);
+ pmdp = pmd_offset(pudp, page);
ptep = pte_offset(pmdp, page);
/*
@@ -407,7 +410,7 @@ static __init void tx39_probe_cache(void)
}
}
-void __init ld_mmu_tx39(void)
+void __init tx39_cache_init(void)
{
extern void build_clear_page(void);
extern void build_copy_page(void);
@@ -490,4 +493,5 @@ void __init ld_mmu_tx39(void)
build_clear_page();
build_copy_page();
+ tx39h_flush_icache_all();
}
diff --git a/arch/mips/mm/cache.c b/arch/mips/mm/cache.c
index 1d95cdb77bed..314701a66b13 100644
--- a/arch/mips/mm/cache.c
+++ b/arch/mips/mm/cache.c
@@ -23,8 +23,10 @@ void (*__flush_cache_all)(void);
void (*flush_cache_mm)(struct mm_struct *mm);
void (*flush_cache_range)(struct vm_area_struct *vma, unsigned long start,
unsigned long end);
-void (*flush_cache_page)(struct vm_area_struct *vma, unsigned long page, unsigned long pfn);
-void (*flush_icache_range)(unsigned long start, unsigned long end);
+void (*flush_cache_page)(struct vm_area_struct *vma, unsigned long page,
+ unsigned long pfn);
+void (*flush_icache_range)(unsigned long __user start,
+ unsigned long __user end);
void (*flush_icache_page)(struct vm_area_struct *vma, struct page *page);
/* MIPS specific cache operations */
@@ -32,6 +34,8 @@ void (*flush_cache_sigtramp)(unsigned long addr);
void (*flush_data_cache_page)(unsigned long addr);
void (*flush_icache_all)(void);
+EXPORT_SYMBOL(flush_data_cache_page);
+
#ifdef CONFIG_DMA_NONCOHERENT
/* DMA cache operations. */
@@ -49,10 +53,12 @@ EXPORT_SYMBOL(_dma_cache_inv);
* We could optimize the case where the cache argument is not BCACHE but
* that seems very atypical use ...
*/
-asmlinkage int sys_cacheflush(unsigned long addr, unsigned long int bytes,
- unsigned int cache)
+asmlinkage int sys_cacheflush(unsigned long __user addr,
+ unsigned long bytes, unsigned int cache)
{
- if (!access_ok(VERIFY_WRITE, (void *) addr, bytes))
+ if (bytes == 0)
+ return 0;
+ if (!access_ok(VERIFY_WRITE, (void __user *) addr, bytes))
return -EFAULT;
flush_icache_range(addr, addr + bytes);
@@ -100,58 +106,48 @@ void __update_cache(struct vm_area_struct *vma, unsigned long address,
}
}
-extern void ld_mmu_r23000(void);
-extern void ld_mmu_r4xx0(void);
-extern void ld_mmu_tx39(void);
-extern void ld_mmu_r6000(void);
-extern void ld_mmu_tfp(void);
-extern void ld_mmu_andes(void);
-extern void ld_mmu_sb1(void);
+#define __weak __attribute__((weak))
+
+static char cache_panic[] __initdata = "Yeee, unsupported cache architecture.";
void __init cpu_cache_init(void)
{
- if (cpu_has_4ktlb) {
-#if defined(CONFIG_CPU_R4X00) || defined(CONFIG_CPU_VR41XX) || \
- defined(CONFIG_CPU_R4300) || defined(CONFIG_CPU_R5000) || \
- defined(CONFIG_CPU_NEVADA) || defined(CONFIG_CPU_R5432) || \
- defined(CONFIG_CPU_R5500) || defined(CONFIG_CPU_MIPS32) || \
- defined(CONFIG_CPU_MIPS64) || defined(CONFIG_CPU_TX49XX) || \
- defined(CONFIG_CPU_RM7000) || defined(CONFIG_CPU_RM9000)
- ld_mmu_r4xx0();
-#endif
- } else switch (current_cpu_data.cputype) {
-#ifdef CONFIG_CPU_R3000
- case CPU_R2000:
- case CPU_R3000:
- case CPU_R3000A:
- case CPU_R3081E:
- ld_mmu_r23000();
- break;
-#endif
-#ifdef CONFIG_CPU_TX39XX
- case CPU_TX3912:
- case CPU_TX3922:
- case CPU_TX3927:
- ld_mmu_tx39();
- break;
-#endif
-#ifdef CONFIG_CPU_R10000
- case CPU_R10000:
- case CPU_R12000:
- ld_mmu_r4xx0();
- break;
-#endif
-#ifdef CONFIG_CPU_SB1
- case CPU_SB1:
- ld_mmu_sb1();
- break;
-#endif
-
- case CPU_R8000:
- panic("R8000 is unsupported");
- break;
-
- default:
- panic("Yeee, unsupported cache architecture.");
+ if (cpu_has_3k_cache) {
+ extern void __weak r3k_cache_init(void);
+
+ r3k_cache_init();
+ return;
+ }
+ if (cpu_has_6k_cache) {
+ extern void __weak r6k_cache_init(void);
+
+ r6k_cache_init();
+ return;
+ }
+ if (cpu_has_4k_cache) {
+ extern void __weak r4k_cache_init(void);
+
+ r4k_cache_init();
+ return;
}
+ if (cpu_has_8k_cache) {
+ extern void __weak r8k_cache_init(void);
+
+ r8k_cache_init();
+ return;
+ }
+ if (cpu_has_tx39_cache) {
+ extern void __weak tx39_cache_init(void);
+
+ tx39_cache_init();
+ return;
+ }
+ if (cpu_has_sb1_cache) {
+ extern void __weak sb1_cache_init(void);
+
+ sb1_cache_init();
+ return;
+ }
+
+ panic(cache_panic);
}
diff --git a/arch/mips/mm/cerr-sb1.c b/arch/mips/mm/cerr-sb1.c
index 7166ffe63502..1cf3c6006ccd 100644
--- a/arch/mips/mm/cerr-sb1.c
+++ b/arch/mips/mm/cerr-sb1.c
@@ -19,13 +19,19 @@
#include <linux/sched.h>
#include <asm/mipsregs.h>
#include <asm/sibyte/sb1250.h>
+#include <asm/sibyte/sb1250_regs.h>
-#ifndef CONFIG_SIBYTE_BUS_WATCHER
+#if !defined(CONFIG_SIBYTE_BUS_WATCHER) || defined(CONFIG_SIBYTE_BW_TRACE)
#include <asm/io.h>
-#include <asm/sibyte/sb1250_regs.h>
#include <asm/sibyte/sb1250_scd.h>
#endif
+/*
+ * We'd like to dump the L2_ECC_TAG register on errors, but errata make
+ * that unsafe... So for now we don't. (BCM1250/BCM112x erratum SOC-48.)
+ */
+#undef DUMP_L2_ECC_TAG_ON_ERROR
+
/* SB1 definitions */
/* XXX should come from config1 XXX */
@@ -139,12 +145,18 @@ static inline void breakout_cerrd(unsigned int val)
static void check_bus_watcher(void)
{
uint32_t status, l2_err, memio_err;
+#ifdef DUMP_L2_ECC_TAG_ON_ERROR
+ uint64_t l2_tag;
+#endif
/* Destructive read, clears register and interrupt */
status = csr_in32(IOADDR(A_SCD_BUS_ERR_STATUS));
/* Bit 31 is always on, but there's no #define for that */
if (status & ~(1UL << 31)) {
l2_err = csr_in32(IOADDR(A_BUS_L2_ERRORS));
+#ifdef DUMP_L2_ECC_TAG_ON_ERROR
+ l2_tag = in64(IO_SPACE_BASE | A_L2_ECC_TAG);
+#endif
memio_err = csr_in32(IOADDR(A_BUS_MEM_IO_ERRORS));
prom_printf("Bus watcher error counters: %08x %08x\n", l2_err, memio_err);
prom_printf("\nLast recorded signature:\n");
@@ -153,6 +165,9 @@ static void check_bus_watcher(void)
(int)(G_SCD_BERR_TID(status) >> 6),
(int)G_SCD_BERR_RID(status),
(int)G_SCD_BERR_DCODE(status));
+#ifdef DUMP_L2_ECC_TAG_ON_ERROR
+ prom_printf("Last L2 tag w/ bad ECC: %016llx\n", l2_tag);
+#endif
} else {
prom_printf("Bus watcher indicates no error\n");
}
@@ -166,6 +181,16 @@ asmlinkage void sb1_cache_error(void)
uint64_t cerr_dpa;
uint32_t errctl, cerr_i, cerr_d, dpalo, dpahi, eepc, res;
+#ifdef CONFIG_SIBYTE_BW_TRACE
+ /* Freeze the trace buffer now */
+#if defined(CONFIG_SIBYTE_BCM1x55) || defined(CONFIG_SIBYTE_BCM1x80)
+ csr_out32(M_BCM1480_SCD_TRACE_CFG_FREEZE, IO_SPACE_BASE | A_SCD_TRACE_CFG);
+#else
+ csr_out32(M_SCD_TRACE_CFG_FREEZE, IO_SPACE_BASE | A_SCD_TRACE_CFG);
+#endif
+ prom_printf("Trace buffer frozen\n");
+#endif
+
prom_printf("Cache error exception on CPU %x:\n",
(read_c0_prid() >> 25) & 0x7);
@@ -229,11 +254,19 @@ asmlinkage void sb1_cache_error(void)
check_bus_watcher();
- while (1);
/*
- * This tends to make things get really ugly; let's just stall instead.
- * panic("Can't handle the cache error!");
+ * Calling panic() when a fatal cache error occurs scrambles the
+ * state of the system (and the cache), making it difficult to
+ * investigate after the fact. However, if you just stall the CPU,
+ * the other CPU may keep on running, which is typically very
+ * undesirable.
*/
+#ifdef CONFIG_SB1_CERR_STALL
+ while (1)
+ ;
+#else
+ panic("unhandled cache error");
+#endif
}
@@ -434,7 +467,8 @@ static struct dc_state dc_states[] = {
};
#define DC_TAG_VALID(state) \
- (((state) == 0xf) || ((state) == 0x13) || ((state) == 0x19) || ((state == 0x16)) || ((state) == 0x1c))
+ (((state) == 0x0) || ((state) == 0xf) || ((state) == 0x13) || \
+ ((state) == 0x19) || ((state) == 0x16) || ((state) == 0x1c))
static char *dc_state_str(unsigned char state)
{
@@ -505,6 +539,7 @@ static uint32_t extract_dc(unsigned short addr, int data)
uint64_t datalo;
uint32_t datalohi, datalolo, datahi;
int offset;
+ char bad_ecc = 0;
for (offset = 0; offset < 4; offset++) {
/* Index-load-data-D */
@@ -525,8 +560,7 @@ static uint32_t extract_dc(unsigned short addr, int data)
ecc = dc_ecc(datalo);
if (ecc != datahi) {
int bits = 0;
- prom_printf(" ** bad ECC (%02x %02x) ->",
- datahi, ecc);
+ bad_ecc |= 1 << (3-offset);
ecc ^= datahi;
while (ecc) {
if (ecc & 1) bits++;
@@ -537,6 +571,10 @@ static uint32_t extract_dc(unsigned short addr, int data)
prom_printf(" %02X-%016llX", datahi, datalo);
}
prom_printf("\n");
+ if (bad_ecc)
+ prom_printf(" dwords w/ bad ECC: %d %d %d %d\n",
+ !!(bad_ecc & 8), !!(bad_ecc & 4),
+ !!(bad_ecc & 2), !!(bad_ecc & 1));
}
}
return res;
diff --git a/arch/mips/mm/cex-sb1.S b/arch/mips/mm/cex-sb1.S
index 2c3a23aa88c3..0e71580774ff 100644
--- a/arch/mips/mm/cex-sb1.S
+++ b/arch/mips/mm/cex-sb1.S
@@ -64,6 +64,10 @@ LEAF(except_vec2_sb1)
sd k0,0x170($0)
sd k1,0x178($0)
+#if CONFIG_SB1_CEX_ALWAYS_FATAL
+ j handle_vec2_sb1
+ nop
+#else
/*
* M_ERRCTL_RECOVERABLE is bit 31, which makes it easy to tell
* if we can fast-path out of here for a h/w-recovered error.
@@ -134,6 +138,7 @@ unrecoverable:
/* Unrecoverable Icache or Dcache error; log it and/or fail */
j handle_vec2_sb1
nop
+#endif
END(except_vec2_sb1)
diff --git a/arch/mips/mm/dma-coherent.c b/arch/mips/mm/dma-coherent.c
index 97a50d38c98f..f6b3c722230c 100644
--- a/arch/mips/mm/dma-coherent.c
+++ b/arch/mips/mm/dma-coherent.c
@@ -9,16 +9,16 @@
*/
#include <linux/config.h>
#include <linux/types.h>
+#include <linux/dma-mapping.h>
#include <linux/mm.h>
#include <linux/module.h>
#include <linux/string.h>
-#include <linux/pci.h>
#include <asm/cache.h>
#include <asm/io.h>
void *dma_alloc_noncoherent(struct device *dev, size_t size,
- dma_addr_t * dma_handle, int gfp)
+ dma_addr_t * dma_handle, gfp_t gfp)
{
void *ret;
/* ignore region specifiers */
@@ -39,7 +39,7 @@ void *dma_alloc_noncoherent(struct device *dev, size_t size,
EXPORT_SYMBOL(dma_alloc_noncoherent);
void *dma_alloc_coherent(struct device *dev, size_t size,
- dma_addr_t * dma_handle, int gfp)
+ dma_addr_t * dma_handle, gfp_t gfp)
__attribute__((alias("dma_alloc_noncoherent")));
EXPORT_SYMBOL(dma_alloc_coherent);
diff --git a/arch/mips/mm/dma-ip27.c b/arch/mips/mm/dma-ip27.c
index aa7c94b5d781..8da19fd22ac6 100644
--- a/arch/mips/mm/dma-ip27.c
+++ b/arch/mips/mm/dma-ip27.c
@@ -22,7 +22,7 @@
pdev_to_baddr(to_pci_dev(dev), (addr))
void *dma_alloc_noncoherent(struct device *dev, size_t size,
- dma_addr_t * dma_handle, int gfp)
+ dma_addr_t * dma_handle, gfp_t gfp)
{
void *ret;
@@ -44,7 +44,7 @@ void *dma_alloc_noncoherent(struct device *dev, size_t size,
EXPORT_SYMBOL(dma_alloc_noncoherent);
void *dma_alloc_coherent(struct device *dev, size_t size,
- dma_addr_t * dma_handle, int gfp)
+ dma_addr_t * dma_handle, gfp_t gfp)
__attribute__((alias("dma_alloc_noncoherent")));
EXPORT_SYMBOL(dma_alloc_coherent);
diff --git a/arch/mips/mm/dma-ip32.c b/arch/mips/mm/dma-ip32.c
index 2cbe196c35fb..a7e3072ff78d 100644
--- a/arch/mips/mm/dma-ip32.c
+++ b/arch/mips/mm/dma-ip32.c
@@ -37,7 +37,7 @@
#define RAM_OFFSET_MASK 0x3fffffff
void *dma_alloc_noncoherent(struct device *dev, size_t size,
- dma_addr_t * dma_handle, int gfp)
+ dma_addr_t * dma_handle, gfp_t gfp)
{
void *ret;
/* ignore region specifiers */
@@ -61,7 +61,7 @@ void *dma_alloc_noncoherent(struct device *dev, size_t size,
EXPORT_SYMBOL(dma_alloc_noncoherent);
void *dma_alloc_coherent(struct device *dev, size_t size,
- dma_addr_t * dma_handle, int gfp)
+ dma_addr_t * dma_handle, gfp_t gfp)
{
void *ret;
diff --git a/arch/mips/mm/dma-noncoherent.c b/arch/mips/mm/dma-noncoherent.c
index 59e54f12212e..cd4ea8474f89 100644
--- a/arch/mips/mm/dma-noncoherent.c
+++ b/arch/mips/mm/dma-noncoherent.c
@@ -24,7 +24,7 @@
*/
void *dma_alloc_noncoherent(struct device *dev, size_t size,
- dma_addr_t * dma_handle, int gfp)
+ dma_addr_t * dma_handle, gfp_t gfp)
{
void *ret;
/* ignore region specifiers */
@@ -45,7 +45,7 @@ void *dma_alloc_noncoherent(struct device *dev, size_t size,
EXPORT_SYMBOL(dma_alloc_noncoherent);
void *dma_alloc_coherent(struct device *dev, size_t size,
- dma_addr_t * dma_handle, int gfp)
+ dma_addr_t * dma_handle, gfp_t gfp)
{
void *ret;
@@ -105,22 +105,7 @@ dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size,
{
unsigned long addr = (unsigned long) ptr;
- switch (direction) {
- case DMA_TO_DEVICE:
- dma_cache_wback(addr, size);
- break;
-
- case DMA_FROM_DEVICE:
- dma_cache_inv(addr, size);
- break;
-
- case DMA_BIDIRECTIONAL:
- dma_cache_wback_inv(addr, size);
- break;
-
- default:
- BUG();
- }
+ __dma_sync(addr, size, direction);
return virt_to_phys(ptr);
}
@@ -133,22 +118,7 @@ void dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
unsigned long addr;
addr = dma_addr + PAGE_OFFSET;
- switch (direction) {
- case DMA_TO_DEVICE:
- //dma_cache_wback(addr, size);
- break;
-
- case DMA_FROM_DEVICE:
- //dma_cache_inv(addr, size);
- break;
-
- case DMA_BIDIRECTIONAL:
- //dma_cache_wback_inv(addr, size);
- break;
-
- default:
- BUG();
- }
+ //__dma_sync(addr, size, direction);
}
EXPORT_SYMBOL(dma_unmap_single);
@@ -164,10 +134,11 @@ int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
unsigned long addr;
addr = (unsigned long) page_address(sg->page);
- if (addr)
+ if (addr) {
__dma_sync(addr + sg->offset, sg->length, direction);
- sg->dma_address = (dma_addr_t)
- (page_to_phys(sg->page) + sg->offset);
+ sg->dma_address = (dma_addr_t)page_to_phys(sg->page)
+ + sg->offset;
+ }
}
return nents;
@@ -218,9 +189,8 @@ void dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries,
for (i = 0; i < nhwentries; i++, sg++) {
addr = (unsigned long) page_address(sg->page);
- if (!addr)
- continue;
- dma_cache_wback_inv(addr + sg->offset, sg->length);
+ if (addr)
+ __dma_sync(addr + sg->offset, sg->length, direction);
}
}
diff --git a/arch/mips/mm/fault.c b/arch/mips/mm/fault.c
index ec8077c74e9c..2d9624fd10ec 100644
--- a/arch/mips/mm/fault.c
+++ b/arch/mips/mm/fault.c
@@ -25,6 +25,7 @@
#include <asm/system.h>
#include <asm/uaccess.h>
#include <asm/ptrace.h>
+#include <asm/highmem.h> /* For VMALLOC_END */
/*
* This routine handles page faults. It determines the address,
@@ -57,7 +58,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long write,
* only copy the information from the master page table,
* nothing more.
*/
- if (unlikely(address >= VMALLOC_START))
+ if (unlikely(address >= VMALLOC_START && address <= VMALLOC_END))
goto vmalloc_fault;
/*
@@ -140,7 +141,7 @@ bad_area_nosemaphore:
info.si_signo = SIGSEGV;
info.si_errno = 0;
/* info.si_code has been set above */
- info.si_addr = (void *) address;
+ info.si_addr = (void __user *) address;
force_sig_info(SIGSEGV, &info, tsk);
return;
}
@@ -196,7 +197,7 @@ do_sigbus:
info.si_signo = SIGBUS;
info.si_errno = 0;
info.si_code = BUS_ADRERR;
- info.si_addr = (void *) address;
+ info.si_addr = (void __user *) address;
force_sig_info(SIGBUS, &info, tsk);
return;
@@ -212,6 +213,7 @@ vmalloc_fault:
*/
int offset = __pgd_offset(address);
pgd_t *pgd, *pgd_k;
+ pud_t *pud, *pud_k;
pmd_t *pmd, *pmd_k;
pte_t *pte_k;
@@ -222,8 +224,13 @@ vmalloc_fault:
goto no_context;
set_pgd(pgd, *pgd_k);
- pmd = pmd_offset(pgd, address);
- pmd_k = pmd_offset(pgd_k, address);
+ pud = pud_offset(pgd, address);
+ pud_k = pud_offset(pgd_k, address);
+ if (!pud_present(*pud_k))
+ goto no_context;
+
+ pmd = pmd_offset(pud, address);
+ pmd_k = pmd_offset(pud_k, address);
if (!pmd_present(*pmd_k))
goto no_context;
set_pmd(pmd, *pmd_k);
diff --git a/arch/mips/mm/highmem.c b/arch/mips/mm/highmem.c
index dd5e2e31885b..1f7b37b38f5c 100644
--- a/arch/mips/mm/highmem.c
+++ b/arch/mips/mm/highmem.c
@@ -83,6 +83,25 @@ void __kunmap_atomic(void *kvaddr, enum km_type type)
preempt_check_resched();
}
+/*
+ * This is the same as kmap_atomic() but can map memory that doesn't
+ * have a struct page associated with it.
+ */
+void *kmap_atomic_pfn(unsigned long pfn, enum km_type type)
+{
+ enum fixed_addresses idx;
+ unsigned long vaddr;
+
+ inc_preempt_count();
+
+ idx = type + KM_TYPE_NR*smp_processor_id();
+ vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
+ set_pte(kmap_pte-idx, pfn_pte(pfn, kmap_prot));
+ flush_tlb_one(vaddr);
+
+ return (void*) vaddr;
+}
+
struct page *__kmap_atomic_to_page(void *ptr)
{
unsigned long idx, vaddr = (unsigned long)ptr;
diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c
index dc6830b10fab..f75ab748e8cd 100644
--- a/arch/mips/mm/init.c
+++ b/arch/mips/mm/init.c
@@ -83,7 +83,7 @@ pte_t *kmap_pte;
pgprot_t kmap_prot;
#define kmap_get_fixmap_pte(vaddr) \
- pte_offset_kernel(pmd_offset(pgd_offset_k(vaddr), (vaddr)), (vaddr))
+ pte_offset_kernel(pmd_offset(pud_offset(pgd_offset_k(vaddr), (vaddr)), (vaddr)), (vaddr))
static void __init kmap_init(void)
{
@@ -96,36 +96,42 @@ static void __init kmap_init(void)
kmap_prot = PAGE_KERNEL;
}
-#ifdef CONFIG_64BIT
-static void __init fixrange_init(unsigned long start, unsigned long end,
+#ifdef CONFIG_32BIT
+void __init fixrange_init(unsigned long start, unsigned long end,
pgd_t *pgd_base)
{
pgd_t *pgd;
+ pud_t *pud;
pmd_t *pmd;
pte_t *pte;
- int i, j;
+ int i, j, k;
unsigned long vaddr;
vaddr = start;
i = __pgd_offset(vaddr);
- j = __pmd_offset(vaddr);
+ j = __pud_offset(vaddr);
+ k = __pmd_offset(vaddr);
pgd = pgd_base + i;
for ( ; (i < PTRS_PER_PGD) && (vaddr != end); pgd++, i++) {
- pmd = (pmd_t *)pgd;
- for (; (j < PTRS_PER_PMD) && (vaddr != end); pmd++, j++) {
- if (pmd_none(*pmd)) {
- pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE);
- set_pmd(pmd, __pmd(pte));
- if (pte != pte_offset_kernel(pmd, 0))
- BUG();
+ pud = (pud_t *)pgd;
+ for ( ; (j < PTRS_PER_PUD) && (vaddr != end); pud++, j++) {
+ pmd = (pmd_t *)pud;
+ for (; (k < PTRS_PER_PMD) && (vaddr != end); pmd++, k++) {
+ if (pmd_none(*pmd)) {
+ pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE);
+ set_pmd(pmd, __pmd(pte));
+ if (pte != pte_offset_kernel(pmd, 0))
+ BUG();
+ }
+ vaddr += PMD_SIZE;
}
- vaddr += PMD_SIZE;
+ k = 0;
}
j = 0;
}
}
-#endif /* CONFIG_64BIT */
+#endif /* CONFIG_32BIT */
#endif /* CONFIG_HIGHMEM */
#ifndef CONFIG_NEED_MULTIPLE_NODES
diff --git a/arch/mips/mm/ioremap.c b/arch/mips/mm/ioremap.c
index adf352273f63..3101d1db5592 100644
--- a/arch/mips/mm/ioremap.c
+++ b/arch/mips/mm/ioremap.c
@@ -55,7 +55,7 @@ static inline int remap_area_pmd(pmd_t * pmd, unsigned long address,
if (address >= end)
BUG();
do {
- pte_t * pte = pte_alloc_kernel(&init_mm, pmd, address);
+ pte_t * pte = pte_alloc_kernel(pmd, address);
if (!pte)
return -ENOMEM;
remap_area_pte(pte, address, end - address, address + phys_addr, flags);
@@ -77,11 +77,15 @@ static int remap_area_pages(unsigned long address, phys_t phys_addr,
flush_cache_all();
if (address >= end)
BUG();
- spin_lock(&init_mm.page_table_lock);
do {
+ pud_t *pud;
pmd_t *pmd;
- pmd = pmd_alloc(&init_mm, dir, address);
+
error = -ENOMEM;
+ pud = pud_alloc(&init_mm, dir, address);
+ if (!pud)
+ break;
+ pmd = pmd_alloc(&init_mm, pud, address);
if (!pmd)
break;
if (remap_area_pmd(pmd, address, end - address,
@@ -91,21 +95,11 @@ static int remap_area_pages(unsigned long address, phys_t phys_addr,
address = (address + PGDIR_SIZE) & PGDIR_MASK;
dir++;
} while (address && (address < end));
- spin_unlock(&init_mm.page_table_lock);
flush_tlb_all();
return error;
}
/*
- * Allow physical addresses to be fixed up to help 36 bit peripherals.
- */
-phys_t __attribute__ ((weak))
-fixup_bigphys_addr(phys_t phys_addr, phys_t size)
-{
- return phys_addr;
-}
-
-/*
* Generic mapping function (not visible outside):
*/
@@ -121,7 +115,7 @@ fixup_bigphys_addr(phys_t phys_addr, phys_t size)
#define IS_LOW512(addr) (!((phys_t)(addr) & (phys_t) ~0x1fffffffULL))
-void * __ioremap(phys_t phys_addr, phys_t size, unsigned long flags)
+void __iomem * __ioremap(phys_t phys_addr, phys_t size, unsigned long flags)
{
struct vm_struct * area;
unsigned long offset;
@@ -141,7 +135,7 @@ void * __ioremap(phys_t phys_addr, phys_t size, unsigned long flags)
*/
if (IS_LOW512(phys_addr) && IS_LOW512(last_addr) &&
flags == _CACHE_UNCACHED)
- return (void *) KSEG1ADDR(phys_addr);
+ return (void __iomem *) CKSEG1ADDR(phys_addr);
/*
* Don't allow anybody to remap normal RAM that we're using..
@@ -177,10 +171,10 @@ void * __ioremap(phys_t phys_addr, phys_t size, unsigned long flags)
return NULL;
}
- return (void *) (offset + (char *)addr);
+ return (void __iomem *) (offset + (char *)addr);
}
-#define IS_KSEG1(addr) (((unsigned long)(addr) & ~0x1fffffffUL) == KSEG1)
+#define IS_KSEG1(addr) (((unsigned long)(addr) & ~0x1fffffffUL) == CKSEG1)
void __iounmap(volatile void __iomem *addr)
{
@@ -190,10 +184,8 @@ void __iounmap(volatile void __iomem *addr)
return;
p = remove_vm_area((void *) (PAGE_MASK & (unsigned long __force) addr));
- if (!p) {
+ if (!p)
printk(KERN_ERR "iounmap: bad address %p\n", addr);
- return;
- }
kfree(p);
}
diff --git a/arch/mips/mm/pg-r4k.c b/arch/mips/mm/pg-r4k.c
index 9f8b16541577..f51e180072e3 100644
--- a/arch/mips/mm/pg-r4k.c
+++ b/arch/mips/mm/pg-r4k.c
@@ -25,7 +25,10 @@
#include <asm/cpu.h>
#include <asm/war.h>
-#define half_scache_line_size() (cpu_scache_line_size() >> 1)
+#define half_scache_line_size() (cpu_scache_line_size() >> 1)
+#define cpu_is_r4600_v1_x() ((read_c0_prid() & 0xfffffff0) == 0x00002010)
+#define cpu_is_r4600_v2_x() ((read_c0_prid() & 0xfffffff0) == 0x00002020)
+
/*
* Maximum sizes:
@@ -198,15 +201,15 @@ static inline void build_cdex_p(void)
if (store_offset & (cpu_dcache_line_size() - 1))
return;
- if (R4600_V1_HIT_CACHEOP_WAR && ((read_c0_prid() & 0xfff0) == 0x2010)) {
+ if (R4600_V1_HIT_CACHEOP_WAR && cpu_is_r4600_v1_x()) {
build_nop();
build_nop();
build_nop();
build_nop();
}
- if (R4600_V2_HIT_CACHEOP_WAR && ((read_c0_prid() & 0xfff0) == 0x2020))
- build_insn_word(0x8c200000); /* lw $zero, ($at) */
+ if (R4600_V2_HIT_CACHEOP_WAR && cpu_is_r4600_v2_x())
+ build_insn_word(0x3c01a000); /* lui $at, 0xa000 */
mi.c_format.opcode = cache_op;
mi.c_format.rs = 4; /* $a0 */
@@ -361,7 +364,7 @@ void __init build_clear_page(void)
build_addiu_a2_a0(PAGE_SIZE - (cpu_has_prefetch ? pref_offset_clear : 0));
- if (R4600_V2_HIT_CACHEOP_WAR && ((read_c0_prid() & 0xfff0) == 0x2020))
+ if (R4600_V2_HIT_CACHEOP_WAR && cpu_is_r4600_v2_x())
build_insn_word(0x3c01a000); /* lui $at, 0xa000 */
dest = label();
@@ -404,9 +407,6 @@ dest = label();
build_jr_ra();
- flush_icache_range((unsigned long)&clear_page_array,
- (unsigned long) epc);
-
BUG_ON(epc > clear_page_array + ARRAY_SIZE(clear_page_array));
}
@@ -420,7 +420,7 @@ void __init build_copy_page(void)
build_addiu_a2_a0(PAGE_SIZE - (cpu_has_prefetch ? pref_offset_copy : 0));
- if (R4600_V2_HIT_CACHEOP_WAR && ((read_c0_prid() & 0xfff0) == 0x2020))
+ if (R4600_V2_HIT_CACHEOP_WAR && cpu_is_r4600_v2_x())
build_insn_word(0x3c01a000); /* lui $at, 0xa000 */
dest = label();
@@ -482,8 +482,5 @@ dest = label();
build_jr_ra();
- flush_icache_range((unsigned long)&copy_page_array,
- (unsigned long) epc);
-
BUG_ON(epc > copy_page_array + ARRAY_SIZE(copy_page_array));
}
diff --git a/arch/mips/mm/pg-sb1.c b/arch/mips/mm/pg-sb1.c
index 1b6df7133c1e..148c65b9cd8b 100644
--- a/arch/mips/mm/pg-sb1.c
+++ b/arch/mips/mm/pg-sb1.c
@@ -60,7 +60,8 @@ static inline void clear_page_cpu(void *page)
" .set noreorder \n"
#ifdef CONFIG_CPU_HAS_PREFETCH
" daddiu %0, %0, 128 \n"
- " pref " SB1_PREF_STORE_STREAMED_HINT ", -128(%0) \n" /* Prefetch the first 4 lines */
+ " pref " SB1_PREF_STORE_STREAMED_HINT ", -128(%0) \n"
+ /* Prefetch the first 4 lines */
" pref " SB1_PREF_STORE_STREAMED_HINT ", -96(%0) \n"
" pref " SB1_PREF_STORE_STREAMED_HINT ", -64(%0) \n"
" pref " SB1_PREF_STORE_STREAMED_HINT ", -32(%0) \n"
@@ -106,7 +107,8 @@ static inline void copy_page_cpu(void *to, void *from)
#ifdef CONFIG_CPU_HAS_PREFETCH
" daddiu %0, %0, 128 \n"
" daddiu %1, %1, 128 \n"
- " pref " SB1_PREF_LOAD_STREAMED_HINT ", -128(%0)\n" /* Prefetch the first 4 lines */
+ " pref " SB1_PREF_LOAD_STREAMED_HINT ", -128(%0)\n"
+ /* Prefetch the first 4 lines */
" pref " SB1_PREF_STORE_STREAMED_HINT ", -128(%1)\n"
" pref " SB1_PREF_LOAD_STREAMED_HINT ", -96(%0)\n"
" pref " SB1_PREF_STORE_STREAMED_HINT ", -96(%1)\n"
@@ -207,66 +209,73 @@ typedef struct dmadscr_s {
u64 pad_b;
} dmadscr_t;
-static dmadscr_t page_descr[NR_CPUS] __attribute__((aligned(SMP_CACHE_BYTES)));
+static dmadscr_t page_descr[DM_NUM_CHANNELS]
+ __attribute__((aligned(SMP_CACHE_BYTES)));
void sb1_dma_init(void)
{
- int cpu = smp_processor_id();
- u64 base_val = CPHYSADDR(&page_descr[cpu]) | V_DM_DSCR_BASE_RINGSZ(1);
+ int i;
- bus_writeq(base_val,
- (void *)IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE)));
- bus_writeq(base_val | M_DM_DSCR_BASE_RESET,
- (void *)IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE)));
- bus_writeq(base_val | M_DM_DSCR_BASE_ENABL,
- (void *)IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE)));
+ for (i = 0; i < DM_NUM_CHANNELS; i++) {
+ const u64 base_val = CPHYSADDR(&page_descr[i]) |
+ V_DM_DSCR_BASE_RINGSZ(1);
+ volatile void *base_reg =
+ IOADDR(A_DM_REGISTER(i, R_DM_DSCR_BASE));
+
+ __raw_writeq(base_val, base_reg);
+ __raw_writeq(base_val | M_DM_DSCR_BASE_RESET, base_reg);
+ __raw_writeq(base_val | M_DM_DSCR_BASE_ENABL, base_reg);
+ }
}
void clear_page(void *page)
{
- int cpu = smp_processor_id();
+ u64 to_phys = CPHYSADDR(page);
+ unsigned int cpu = smp_processor_id();
- /* if the page is above Kseg0, use old way */
+ /* if the page is not in KSEG0, use old way */
if ((long)KSEGX(page) != (long)CKSEG0)
return clear_page_cpu(page);
- page_descr[cpu].dscr_a = CPHYSADDR(page) | M_DM_DSCRA_ZERO_MEM | M_DM_DSCRA_L2C_DEST | M_DM_DSCRA_INTERRUPT;
+ page_descr[cpu].dscr_a = to_phys | M_DM_DSCRA_ZERO_MEM |
+ M_DM_DSCRA_L2C_DEST | M_DM_DSCRA_INTERRUPT;
page_descr[cpu].dscr_b = V_DM_DSCRB_SRC_LENGTH(PAGE_SIZE);
- bus_writeq(1, (void *)IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_COUNT)));
+ __raw_writeq(1, IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_COUNT)));
/*
* Don't really want to do it this way, but there's no
* reliable way to delay completion detection.
*/
- while (!(bus_readq((void *)(IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE_DEBUG)) &
- M_DM_DSCR_BASE_INTERRUPT))))
+ while (!(__raw_readq(IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE_DEBUG)))
+ & M_DM_DSCR_BASE_INTERRUPT))
;
- bus_readq((void *)IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE)));
+ __raw_readq(IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE)));
}
void copy_page(void *to, void *from)
{
- unsigned long from_phys = CPHYSADDR(from);
- unsigned long to_phys = CPHYSADDR(to);
- int cpu = smp_processor_id();
+ u64 from_phys = CPHYSADDR(from);
+ u64 to_phys = CPHYSADDR(to);
+ unsigned int cpu = smp_processor_id();
- /* if either page is above Kseg0, use old way */
+ /* if any page is not in KSEG0, use old way */
if ((long)KSEGX(to) != (long)CKSEG0
|| (long)KSEGX(from) != (long)CKSEG0)
return copy_page_cpu(to, from);
- page_descr[cpu].dscr_a = CPHYSADDR(to_phys) | M_DM_DSCRA_L2C_DEST | M_DM_DSCRA_INTERRUPT;
- page_descr[cpu].dscr_b = CPHYSADDR(from_phys) | V_DM_DSCRB_SRC_LENGTH(PAGE_SIZE);
- bus_writeq(1, (void *)IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_COUNT)));
+ page_descr[cpu].dscr_a = to_phys | M_DM_DSCRA_L2C_DEST |
+ M_DM_DSCRA_INTERRUPT;
+ page_descr[cpu].dscr_b = from_phys | V_DM_DSCRB_SRC_LENGTH(PAGE_SIZE);
+ __raw_writeq(1, IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_COUNT)));
/*
* Don't really want to do it this way, but there's no
* reliable way to delay completion detection.
*/
- while (!(bus_readq((void *)(IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE_DEBUG)) &
- M_DM_DSCR_BASE_INTERRUPT))))
+ while (!(__raw_readq(IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE_DEBUG)))
+ & M_DM_DSCR_BASE_INTERRUPT))
;
- bus_readq((void *)IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE)));
+ __raw_readq(IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE)));
}
#else /* !CONFIG_SIBYTE_DMA_PAGEOPS */
diff --git a/arch/mips/mm/pgtable-32.c b/arch/mips/mm/pgtable-32.c
index 4f07f81e8500..4a3c4919e314 100644
--- a/arch/mips/mm/pgtable-32.c
+++ b/arch/mips/mm/pgtable-32.c
@@ -10,6 +10,7 @@
#include <linux/mm.h>
#include <linux/bootmem.h>
#include <linux/highmem.h>
+#include <asm/fixmap.h>
#include <asm/pgtable.h>
void pgd_init(unsigned long page)
@@ -29,42 +30,12 @@ void pgd_init(unsigned long page)
}
}
-#ifdef CONFIG_HIGHMEM
-static void __init fixrange_init (unsigned long start, unsigned long end,
- pgd_t *pgd_base)
-{
- pgd_t *pgd;
- pmd_t *pmd;
- pte_t *pte;
- int i, j;
- unsigned long vaddr;
-
- vaddr = start;
- i = __pgd_offset(vaddr);
- j = __pmd_offset(vaddr);
- pgd = pgd_base + i;
-
- for ( ; (i < PTRS_PER_PGD) && (vaddr != end); pgd++, i++) {
- pmd = (pmd_t *)pgd;
- for (; (j < PTRS_PER_PMD) && (vaddr != end); pmd++, j++) {
- if (pmd_none(*pmd)) {
- pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE);
- set_pmd(pmd, __pmd((unsigned long)pte));
- if (pte != pte_offset_kernel(pmd, 0))
- BUG();
- }
- vaddr += PMD_SIZE;
- }
- j = 0;
- }
-}
-#endif
-
void __init pagetable_init(void)
{
#ifdef CONFIG_HIGHMEM
unsigned long vaddr;
pgd_t *pgd, *pgd_base;
+ pud_t *pud;
pmd_t *pmd;
pte_t *pte;
#endif
@@ -90,7 +61,8 @@ void __init pagetable_init(void)
fixrange_init(vaddr, vaddr + PAGE_SIZE*LAST_PKMAP, pgd_base);
pgd = swapper_pg_dir + __pgd_offset(vaddr);
- pmd = pmd_offset(pgd, vaddr);
+ pud = pud_offset(pgd, vaddr);
+ pmd = pmd_offset(pud, vaddr);
pte = pte_offset_kernel(pmd, vaddr);
pkmap_page_table = pte;
#endif
diff --git a/arch/mips/mm/sc-rm7k.c b/arch/mips/mm/sc-rm7k.c
index 4e92f931aaba..9e8ff8badb19 100644
--- a/arch/mips/mm/sc-rm7k.c
+++ b/arch/mips/mm/sc-rm7k.c
@@ -15,6 +15,7 @@
#include <asm/cacheops.h>
#include <asm/mipsregs.h>
#include <asm/processor.h>
+#include <asm/cacheflush.h> /* for run_uncached() */
/* Primary cache parameters. */
#define sc_lsize 32
@@ -96,25 +97,13 @@ static void rm7k_sc_inv(unsigned long addr, unsigned long size)
}
/*
- * This function is executed in the uncached segment CKSEG1.
- * It must not touch the stack, because the stack pointer still points
- * into CKSEG0.
- *
- * Three options:
- * - Write it in assembly and guarantee that we don't use the stack.
- * - Disable caching for CKSEG0 before calling it.
- * - Pray that GCC doesn't randomly start using the stack.
- *
- * This being Linux, we obviously take the least sane of those options -
- * following DaveM's lead in c-r4k.c
- *
- * It seems we get our kicks from relying on unguaranteed behaviour in GCC
+ * This function is executed in uncached address space.
*/
static __init void __rm7k_sc_enable(void)
{
int i;
- set_c0_config(1 << 3); /* CONF_SE */
+ set_c0_config(RM7K_CONF_SE);
write_c0_taglo(0);
write_c0_taghi(0);
@@ -127,24 +116,22 @@ static __init void __rm7k_sc_enable(void)
".set mips0\n\t"
".set reorder"
:
- : "r" (KSEG0ADDR(i)), "i" (Index_Store_Tag_SD));
+ : "r" (CKSEG0ADDR(i)), "i" (Index_Store_Tag_SD));
}
}
static __init void rm7k_sc_enable(void)
{
- void (*func)(void) = (void *) KSEG1ADDR(&__rm7k_sc_enable);
-
- if (read_c0_config() & 0x08) /* CONF_SE */
+ if (read_c0_config() & RM7K_CONF_SE)
return;
- printk(KERN_INFO "Enabling secondary cache...");
- func();
+ printk(KERN_INFO "Enabling secondary cache...\n");
+ run_uncached(__rm7k_sc_enable);
}
static void rm7k_sc_disable(void)
{
- clear_c0_config(1<<3); /* CONF_SE */
+ clear_c0_config(RM7K_CONF_SE);
}
struct bcache_ops rm7k_sc_ops = {
@@ -158,19 +145,19 @@ void __init rm7k_sc_init(void)
{
unsigned int config = read_c0_config();
- if ((config >> 31) & 1) /* Bit 31 set -> no S-Cache */
+ if ((config & RM7K_CONF_SC))
return;
printk(KERN_INFO "Secondary cache size %dK, linesize %d bytes.\n",
(scache_size >> 10), sc_lsize);
- if (!((config >> 3) & 1)) /* CONF_SE */
+ if (!(config & RM7K_CONF_SE))
rm7k_sc_enable();
/*
* While we're at it let's deal with the tertiary cache.
*/
- if (!((config >> 17) & 1)) {
+ if (!(config & RM7K_CONF_TC)) {
/*
* We can't enable the L3 cache yet. There may be board-specific
@@ -183,9 +170,9 @@ void __init rm7k_sc_init(void)
* to probe it.
*/
printk(KERN_INFO "Tertiary cache present, %s enabled\n",
- config&(1<<12) ? "already" : "not (yet)");
+ (config & RM7K_CONF_TE) ? "already" : "not (yet)");
- if ((config >> 12) & 1)
+ if ((config & RM7K_CONF_TE))
rm7k_tcache_enabled = 1;
}
diff --git a/arch/mips/mm/tlb-andes.c b/arch/mips/mm/tlb-andes.c
index 167e08e9661a..3f422a849c41 100644
--- a/arch/mips/mm/tlb-andes.c
+++ b/arch/mips/mm/tlb-andes.c
@@ -195,6 +195,7 @@ void __update_tlb(struct vm_area_struct * vma, unsigned long address, pte_t pte)
{
unsigned long flags;
pgd_t *pgdp;
+ pud_t *pudp;
pmd_t *pmdp;
pte_t *ptep;
int idx, pid;
@@ -220,7 +221,8 @@ void __update_tlb(struct vm_area_struct * vma, unsigned long address, pte_t pte)
write_c0_entryhi(address | (pid));
pgdp = pgd_offset(vma->vm_mm, address);
tlb_probe();
- pmdp = pmd_offset(pgdp, address);
+ pudp = pud_offset(pgdp, address);
+ pmdp = pmd_offset(pudp, address);
idx = read_c0_index();
ptep = pte_offset_map(pmdp, address);
write_c0_entrylo0(pte_val(*ptep++) >> 6);
diff --git a/arch/mips/mm/tlb-r4k.c b/arch/mips/mm/tlb-r4k.c
index 59d38bc05b69..8297970f0bb1 100644
--- a/arch/mips/mm/tlb-r4k.c
+++ b/arch/mips/mm/tlb-r4k.c
@@ -21,6 +21,12 @@
extern void build_tlb_refill_handler(void);
+/*
+ * Make sure all entries differ. If they're not different
+ * MIPS32 will take revenge ...
+ */
+#define UNIQUE_ENTRYHI(idx) (CKSEG0 + ((idx) << (PAGE_SHIFT + 1)))
+
/* CP0 hazard avoidance. */
#define BARRIER __asm__ __volatile__(".set noreorder\n\t" \
"nop; nop; nop; nop; nop; nop;\n\t" \
@@ -42,11 +48,8 @@ void local_flush_tlb_all(void)
/* Blast 'em all away. */
while (entry < current_cpu_data.tlbsize) {
- /*
- * Make sure all entries differ. If they're not different
- * MIPS32 will take revenge ...
- */
- write_c0_entryhi(CKSEG0 + (entry << (PAGE_SHIFT + 1)));
+ /* Make sure all entries differ. */
+ write_c0_entryhi(UNIQUE_ENTRYHI(entry));
write_c0_index(entry);
mtc0_tlbw_hazard();
tlb_write_indexed();
@@ -57,12 +60,21 @@ void local_flush_tlb_all(void)
local_irq_restore(flags);
}
+/* All entries common to a mm share an asid. To effectively flush
+ these entries, we just bump the asid. */
void local_flush_tlb_mm(struct mm_struct *mm)
{
- int cpu = smp_processor_id();
+ int cpu;
+
+ preempt_disable();
- if (cpu_context(cpu, mm) != 0)
- drop_mmu_context(mm,cpu);
+ cpu = smp_processor_id();
+
+ if (cpu_context(cpu, mm) != 0) {
+ drop_mmu_context(mm, cpu);
+ }
+
+ preempt_enable();
}
void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
@@ -75,9 +87,9 @@ void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
unsigned long flags;
int size;
- local_irq_save(flags);
size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
size = (size + 1) >> 1;
+ local_irq_save(flags);
if (size <= current_cpu_data.tlbsize/2) {
int oldpid = read_c0_entryhi();
int newpid = cpu_asid(cpu, mm);
@@ -99,8 +111,7 @@ void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
if (idx < 0)
continue;
/* Make sure all entries differ. */
- write_c0_entryhi(CKSEG0 +
- (idx << (PAGE_SHIFT + 1)));
+ write_c0_entryhi(UNIQUE_ENTRYHI(idx));
mtc0_tlbw_hazard();
tlb_write_indexed();
}
@@ -118,9 +129,9 @@ void local_flush_tlb_kernel_range(unsigned long start, unsigned long end)
unsigned long flags;
int size;
- local_irq_save(flags);
size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
size = (size + 1) >> 1;
+ local_irq_save(flags);
if (size <= current_cpu_data.tlbsize / 2) {
int pid = read_c0_entryhi();
@@ -142,7 +153,7 @@ void local_flush_tlb_kernel_range(unsigned long start, unsigned long end)
if (idx < 0)
continue;
/* Make sure all entries differ. */
- write_c0_entryhi(CKSEG0 + (idx << (PAGE_SHIFT + 1)));
+ write_c0_entryhi(UNIQUE_ENTRYHI(idx));
mtc0_tlbw_hazard();
tlb_write_indexed();
}
@@ -176,7 +187,7 @@ void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
if (idx < 0)
goto finish;
/* Make sure all entries differ. */
- write_c0_entryhi(CKSEG0 + (idx << (PAGE_SHIFT + 1)));
+ write_c0_entryhi(UNIQUE_ENTRYHI(idx));
mtc0_tlbw_hazard();
tlb_write_indexed();
tlbw_use_hazard();
@@ -197,8 +208,8 @@ void local_flush_tlb_one(unsigned long page)
int oldpid, idx;
local_irq_save(flags);
- page &= (PAGE_MASK << 1);
oldpid = read_c0_entryhi();
+ page &= (PAGE_MASK << 1);
write_c0_entryhi(page);
mtc0_tlbw_hazard();
tlb_probe();
@@ -208,7 +219,7 @@ void local_flush_tlb_one(unsigned long page)
write_c0_entrylo1(0);
if (idx >= 0) {
/* Make sure all entries differ. */
- write_c0_entryhi(CKSEG0 + (idx << (PAGE_SHIFT + 1)));
+ write_c0_entryhi(UNIQUE_ENTRYHI(idx));
mtc0_tlbw_hazard();
tlb_write_indexed();
tlbw_use_hazard();
@@ -227,6 +238,7 @@ void __update_tlb(struct vm_area_struct * vma, unsigned long address, pte_t pte)
{
unsigned long flags;
pgd_t *pgdp;
+ pud_t *pudp;
pmd_t *pmdp;
pte_t *ptep;
int idx, pid;
@@ -237,35 +249,34 @@ void __update_tlb(struct vm_area_struct * vma, unsigned long address, pte_t pte)
if (current->active_mm != vma->vm_mm)
return;
- pid = read_c0_entryhi() & ASID_MASK;
-
local_irq_save(flags);
+
+ pid = read_c0_entryhi() & ASID_MASK;
address &= (PAGE_MASK << 1);
write_c0_entryhi(address | pid);
pgdp = pgd_offset(vma->vm_mm, address);
mtc0_tlbw_hazard();
tlb_probe();
BARRIER;
- pmdp = pmd_offset(pgdp, address);
+ pudp = pud_offset(pgdp, address);
+ pmdp = pmd_offset(pudp, address);
idx = read_c0_index();
ptep = pte_offset_map(pmdp, address);
- #if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32)
- write_c0_entrylo0(ptep->pte_high);
- ptep++;
- write_c0_entrylo1(ptep->pte_high);
+#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32_R1)
+ write_c0_entrylo0(ptep->pte_high);
+ ptep++;
+ write_c0_entrylo1(ptep->pte_high);
#else
- write_c0_entrylo0(pte_val(*ptep++) >> 6);
- write_c0_entrylo1(pte_val(*ptep) >> 6);
+ write_c0_entrylo0(pte_val(*ptep++) >> 6);
+ write_c0_entrylo1(pte_val(*ptep) >> 6);
#endif
- write_c0_entryhi(address | pid);
mtc0_tlbw_hazard();
if (idx < 0)
tlb_write_random();
else
tlb_write_indexed();
tlbw_use_hazard();
- write_c0_entryhi(pid);
local_irq_restore(flags);
}
@@ -357,7 +368,8 @@ __init int add_temporary_entry(unsigned long entrylo0, unsigned long entrylo1,
old_pagemask = read_c0_pagemask();
wired = read_c0_wired();
if (--temp_tlb_entry < wired) {
- printk(KERN_WARNING "No TLB space left for add_temporary_entry\n");
+ printk(KERN_WARNING
+ "No TLB space left for add_temporary_entry\n");
ret = -ENOSPC;
goto out;
}
@@ -388,7 +400,7 @@ static void __init probe_tlb(unsigned long config)
* is not supported, we assume R4k style. Cpu probing already figured
* out the number of tlb entries.
*/
- if ((c->processor_id & 0xff0000) == PRID_COMP_LEGACY)
+ if ((c->processor_id & 0xff0000) == PRID_COMP_LEGACY)
return;
reg = read_c0_config1();
diff --git a/arch/mips/mm/tlb-sb1.c b/arch/mips/mm/tlb-sb1.c
deleted file mode 100644
index 6256cafcf3a2..000000000000
--- a/arch/mips/mm/tlb-sb1.c
+++ /dev/null
@@ -1,376 +0,0 @@
-/*
- * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
- * Copyright (C) 1997, 2001 Ralf Baechle (ralf@gnu.org)
- * Copyright (C) 2000, 2001, 2002, 2003 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; 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/init.h>
-#include <asm/mmu_context.h>
-#include <asm/bootinfo.h>
-#include <asm/cpu.h>
-
-extern void build_tlb_refill_handler(void);
-
-#define UNIQUE_ENTRYHI(idx) (CKSEG0 + ((idx) << (PAGE_SHIFT + 1)))
-
-/* Dump the current entry* and pagemask registers */
-static inline void dump_cur_tlb_regs(void)
-{
- unsigned int entryhihi, entryhilo, entrylo0hi, entrylo0lo, entrylo1hi;
- unsigned int entrylo1lo, pagemask;
-
- __asm__ __volatile__ (
- ".set push \n"
- ".set noreorder \n"
- ".set mips64 \n"
- ".set noat \n"
- " tlbr \n"
- " dmfc0 $1, $10 \n"
- " dsrl32 %0, $1, 0 \n"
- " sll %1, $1, 0 \n"
- " dmfc0 $1, $2 \n"
- " dsrl32 %2, $1, 0 \n"
- " sll %3, $1, 0 \n"
- " dmfc0 $1, $3 \n"
- " dsrl32 %4, $1, 0 \n"
- " sll %5, $1, 0 \n"
- " mfc0 %6, $5 \n"
- ".set pop \n"
- : "=r" (entryhihi), "=r" (entryhilo),
- "=r" (entrylo0hi), "=r" (entrylo0lo),
- "=r" (entrylo1hi), "=r" (entrylo1lo),
- "=r" (pagemask));
-
- printk("%08X%08X %08X%08X %08X%08X %08X",
- entryhihi, entryhilo,
- entrylo0hi, entrylo0lo,
- entrylo1hi, entrylo1lo,
- pagemask);
-}
-
-void sb1_dump_tlb(void)
-{
- unsigned long old_ctx;
- unsigned long flags;
- int entry;
- local_irq_save(flags);
- old_ctx = read_c0_entryhi();
- printk("Current TLB registers state:\n"
- " EntryHi EntryLo0 EntryLo1 PageMask Index\n"
- "--------------------------------------------------------------------\n");
- dump_cur_tlb_regs();
- printk(" %08X\n", read_c0_index());
- printk("\n\nFull TLB Dump:\n"
- "Idx EntryHi EntryLo0 EntryLo1 PageMask\n"
- "--------------------------------------------------------------\n");
- for (entry = 0; entry < current_cpu_data.tlbsize; entry++) {
- write_c0_index(entry);
- printk("\n%02i ", entry);
- dump_cur_tlb_regs();
- }
- printk("\n");
- write_c0_entryhi(old_ctx);
- local_irq_restore(flags);
-}
-
-void local_flush_tlb_all(void)
-{
- unsigned long flags;
- unsigned long old_ctx;
- int entry;
-
- local_irq_save(flags);
- /* Save old context and create impossible VPN2 value */
- old_ctx = read_c0_entryhi() & ASID_MASK;
- write_c0_entrylo0(0);
- write_c0_entrylo1(0);
-
- entry = read_c0_wired();
- while (entry < current_cpu_data.tlbsize) {
- write_c0_entryhi(UNIQUE_ENTRYHI(entry));
- write_c0_index(entry);
- tlb_write_indexed();
- entry++;
- }
- write_c0_entryhi(old_ctx);
- local_irq_restore(flags);
-}
-
-
-/*
- * Use a bogus region of memory (starting at 0) to sanitize the TLB's.
- * Use increments of the maximum page size (16MB), and check for duplicate
- * entries before doing a given write. Then, when we're safe from collisions
- * with the firmware, go back and give all the entries invalid addresses with
- * the normal flush routine. Wired entries will be killed as well!
- */
-static void __init sb1_sanitize_tlb(void)
-{
- int entry;
- long addr = 0;
-
- long inc = 1<<24; /* 16MB */
- /* Save old context and create impossible VPN2 value */
- write_c0_entrylo0(0);
- write_c0_entrylo1(0);
- for (entry = 0; entry < current_cpu_data.tlbsize; entry++) {
- do {
- addr += inc;
- write_c0_entryhi(addr);
- tlb_probe();
- } while ((int)(read_c0_index()) >= 0);
- write_c0_index(entry);
- tlb_write_indexed();
- }
- /* Now that we know we're safe from collisions, we can safely flush
- the TLB with the "normal" routine. */
- local_flush_tlb_all();
-}
-
-void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
- unsigned long end)
-{
- struct mm_struct *mm = vma->vm_mm;
- unsigned long flags;
- int cpu;
-
- local_irq_save(flags);
- cpu = smp_processor_id();
- if (cpu_context(cpu, mm) != 0) {
- int size;
- size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
- size = (size + 1) >> 1;
- if (size <= (current_cpu_data.tlbsize/2)) {
- int oldpid = read_c0_entryhi() & ASID_MASK;
- int newpid = cpu_asid(cpu, mm);
-
- start &= (PAGE_MASK << 1);
- end += ((PAGE_SIZE << 1) - 1);
- end &= (PAGE_MASK << 1);
- while (start < end) {
- int idx;
-
- write_c0_entryhi(start | newpid);
- start += (PAGE_SIZE << 1);
- tlb_probe();
- idx = read_c0_index();
- write_c0_entrylo0(0);
- write_c0_entrylo1(0);
- write_c0_entryhi(UNIQUE_ENTRYHI(idx));
- if (idx < 0)
- continue;
- tlb_write_indexed();
- }
- write_c0_entryhi(oldpid);
- } else {
- drop_mmu_context(mm, cpu);
- }
- }
- local_irq_restore(flags);
-}
-
-void local_flush_tlb_kernel_range(unsigned long start, unsigned long end)
-{
- unsigned long flags;
- int size;
-
- size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
- size = (size + 1) >> 1;
-
- local_irq_save(flags);
- if (size <= (current_cpu_data.tlbsize/2)) {
- int pid = read_c0_entryhi();
-
- start &= (PAGE_MASK << 1);
- end += ((PAGE_SIZE << 1) - 1);
- end &= (PAGE_MASK << 1);
-
- while (start < end) {
- int idx;
-
- write_c0_entryhi(start);
- start += (PAGE_SIZE << 1);
- tlb_probe();
- idx = read_c0_index();
- write_c0_entrylo0(0);
- write_c0_entrylo1(0);
- write_c0_entryhi(UNIQUE_ENTRYHI(idx));
- if (idx < 0)
- continue;
- tlb_write_indexed();
- }
- write_c0_entryhi(pid);
- } else {
- local_flush_tlb_all();
- }
- local_irq_restore(flags);
-}
-
-void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
-{
- unsigned long flags;
- int cpu = smp_processor_id();
-
- local_irq_save(flags);
- if (cpu_context(cpu, vma->vm_mm) != 0) {
- int oldpid, newpid, idx;
- newpid = cpu_asid(cpu, vma->vm_mm);
- page &= (PAGE_MASK << 1);
- oldpid = read_c0_entryhi() & ASID_MASK;
- write_c0_entryhi(page | newpid);
- tlb_probe();
- idx = read_c0_index();
- write_c0_entrylo0(0);
- write_c0_entrylo1(0);
- if (idx < 0)
- goto finish;
- /* Make sure all entries differ. */
- write_c0_entryhi(UNIQUE_ENTRYHI(idx));
- tlb_write_indexed();
- finish:
- write_c0_entryhi(oldpid);
- }
- local_irq_restore(flags);
-}
-
-/*
- * Remove one kernel space TLB entry. This entry is assumed to be marked
- * global so we don't do the ASID thing.
- */
-void local_flush_tlb_one(unsigned long page)
-{
- unsigned long flags;
- int oldpid, idx;
-
- page &= (PAGE_MASK << 1);
- oldpid = read_c0_entryhi() & ASID_MASK;
-
- local_irq_save(flags);
- write_c0_entryhi(page);
- tlb_probe();
- idx = read_c0_index();
- if (idx >= 0) {
- /* Make sure all entries differ. */
- write_c0_entryhi(UNIQUE_ENTRYHI(idx));
- write_c0_entrylo0(0);
- write_c0_entrylo1(0);
- tlb_write_indexed();
- }
-
- write_c0_entryhi(oldpid);
- local_irq_restore(flags);
-}
-
-/* All entries common to a mm share an asid. To effectively flush
- these entries, we just bump the asid. */
-void local_flush_tlb_mm(struct mm_struct *mm)
-{
- int cpu;
-
- preempt_disable();
-
- cpu = smp_processor_id();
-
- if (cpu_context(cpu, mm) != 0) {
- drop_mmu_context(mm, cpu);
- }
-
- preempt_enable();
-}
-
-/* Stolen from mips32 routines */
-
-void __update_tlb(struct vm_area_struct *vma, unsigned long address, pte_t pte)
-{
- unsigned long flags;
- pgd_t *pgdp;
- pmd_t *pmdp;
- pte_t *ptep;
- int idx, pid;
-
- /*
- * Handle debugger faulting in for debugee.
- */
- if (current->active_mm != vma->vm_mm)
- return;
-
- local_irq_save(flags);
-
- pid = read_c0_entryhi() & ASID_MASK;
- address &= (PAGE_MASK << 1);
- write_c0_entryhi(address | (pid));
- pgdp = pgd_offset(vma->vm_mm, address);
- tlb_probe();
- pmdp = pmd_offset(pgdp, address);
- idx = read_c0_index();
- ptep = pte_offset_map(pmdp, address);
- write_c0_entrylo0(pte_val(*ptep++) >> 6);
- write_c0_entrylo1(pte_val(*ptep) >> 6);
- if (idx < 0) {
- tlb_write_random();
- } else {
- tlb_write_indexed();
- }
- local_irq_restore(flags);
-}
-
-void __init add_wired_entry(unsigned long entrylo0, unsigned long entrylo1,
- unsigned long entryhi, unsigned long pagemask)
-{
- unsigned long flags;
- unsigned long wired;
- unsigned long old_pagemask;
- unsigned long old_ctx;
-
- local_irq_save(flags);
- old_ctx = read_c0_entryhi() & 0xff;
- old_pagemask = read_c0_pagemask();
- wired = read_c0_wired();
- write_c0_wired(wired + 1);
- write_c0_index(wired);
-
- write_c0_pagemask(pagemask);
- write_c0_entryhi(entryhi);
- write_c0_entrylo0(entrylo0);
- write_c0_entrylo1(entrylo1);
- tlb_write_indexed();
-
- write_c0_entryhi(old_ctx);
- write_c0_pagemask(old_pagemask);
-
- local_flush_tlb_all();
- local_irq_restore(flags);
-}
-
-/*
- * This is called from loadmmu.c. We have to set up all the
- * memory management function pointers, as well as initialize
- * the caches and tlbs
- */
-void tlb_init(void)
-{
- write_c0_pagemask(PM_DEFAULT_MASK);
- write_c0_wired(0);
-
- /*
- * We don't know what state the firmware left the TLB's in, so this is
- * the ultra-conservative way to flush the TLB's and avoid machine
- * check exceptions due to duplicate TLB entries
- */
- sb1_sanitize_tlb();
-
- build_tlb_refill_handler();
-}
diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c
index 6569be3983c7..0f9485806bac 100644
--- a/arch/mips/mm/tlbex.c
+++ b/arch/mips/mm/tlbex.c
@@ -6,6 +6,7 @@
* Synthesize TLB refill handlers at runtime.
*
* Copyright (C) 2004,2005 by Thiemo Seufer
+ * Copyright (C) 2005 Maciej W. Rozycki
*/
#include <stdarg.h>
@@ -91,7 +92,7 @@ enum opcode {
insn_addu, insn_addiu, insn_and, insn_andi, insn_beq,
insn_beql, insn_bgez, insn_bgezl, insn_bltz, insn_bltzl,
insn_bne, insn_daddu, insn_daddiu, insn_dmfc0, insn_dmtc0,
- insn_dsll, insn_dsll32, insn_dsra, insn_dsrl, insn_dsrl32,
+ insn_dsll, insn_dsll32, insn_dsra, insn_dsrl,
insn_dsubu, insn_eret, insn_j, insn_jal, insn_jr, insn_ld,
insn_ll, insn_lld, insn_lui, insn_lw, insn_mfc0, insn_mtc0,
insn_ori, insn_rfe, insn_sc, insn_scd, insn_sd, insn_sll,
@@ -134,7 +135,6 @@ static __initdata struct insn insn_table[] = {
{ insn_dsll32, M(spec_op,0,0,0,0,dsll32_op), RT | RD | RE },
{ insn_dsra, M(spec_op,0,0,0,0,dsra_op), RT | RD | RE },
{ insn_dsrl, M(spec_op,0,0,0,0,dsrl_op), RT | RD | RE },
- { insn_dsrl32, M(spec_op,0,0,0,0,dsrl32_op), RT | RD | RE },
{ insn_dsubu, M(spec_op,0,0,0,0,dsubu_op), RS | RT | RD },
{ insn_eret, M(cop0_op,cop_op,0,0,0,eret_op), 0 },
{ insn_j, M(j_op,0,0,0,0,0), JIMM },
@@ -366,7 +366,6 @@ I_u2u1u3(_dsll);
I_u2u1u3(_dsll32);
I_u2u1u3(_dsra);
I_u2u1u3(_dsrl);
-I_u2u1u3(_dsrl32);
I_u3u1u2(_dsubu);
I_0(_eret);
I_u1(_j);
@@ -412,7 +411,6 @@ enum label_id {
label_nopage_tlbm,
label_smp_pgtable_change,
label_r3000_write_probe_fail,
- label_r3000_write_probe_ok
};
struct label {
@@ -445,7 +443,6 @@ L_LA(_nopage_tlbs)
L_LA(_nopage_tlbm)
L_LA(_smp_pgtable_change)
L_LA(_r3000_write_probe_fail)
-L_LA(_r3000_write_probe_ok)
/* convenience macros for instructions */
#ifdef CONFIG_64BIT
@@ -490,7 +487,7 @@ L_LA(_r3000_write_probe_ok)
static __init int __attribute__((unused)) in_compat_space_p(long addr)
{
/* Is this address in 32bit compat space? */
- return (((addr) & 0xffffffff00000000) == 0xffffffff00000000);
+ return (((addr) & 0xffffffff00000000L) == 0xffffffff00000000L);
}
static __init int __attribute__((unused)) rel_highest(long val)
@@ -734,7 +731,7 @@ static void __init build_r3000_tlb_refill_handler(void)
if (p > tlb_handler + 32)
panic("TLB refill handler space exceeded");
- printk("Synthesized TLB handler (%u instructions).\n",
+ printk("Synthesized TLB refill handler (%u instructions).\n",
(unsigned int)(p - tlb_handler));
#ifdef DEBUG_TLB
{
@@ -746,7 +743,6 @@ static void __init build_r3000_tlb_refill_handler(void)
#endif
memcpy((void *)CAC_BASE, tlb_handler, 0x80);
- flush_icache_range(CAC_BASE, CAC_BASE + 0x80);
}
/*
@@ -783,6 +779,8 @@ static __initdata u32 final_handler[64];
static __init void __attribute__((unused)) build_tlb_probe_entry(u32 **p)
{
switch (current_cpu_data.cputype) {
+ /* Found by experiment: R4600 v2.0 needs this, too. */
+ case CPU_R4600:
case CPU_R5000:
case CPU_R5000A:
case CPU_NEVADA:
@@ -834,12 +832,20 @@ static __init void build_tlb_write_entry(u32 **p, struct label **l,
case CPU_R4700:
case CPU_R5000:
case CPU_R5000A:
+ i_nop(p);
+ tlbw(p);
+ i_nop(p);
+ break;
+
+ case CPU_R4300:
case CPU_5KC:
case CPU_TX49XX:
case CPU_AU1000:
case CPU_AU1100:
case CPU_AU1500:
case CPU_AU1550:
+ case CPU_AU1200:
+ case CPU_PR4450:
i_nop(p);
tlbw(p);
break;
@@ -848,6 +854,7 @@ static __init void build_tlb_write_entry(u32 **p, struct label **l,
case CPU_R12000:
case CPU_4KC:
case CPU_SB1:
+ case CPU_SB1A:
case CPU_4KSC:
case CPU_20KC:
case CPU_25KF:
@@ -875,6 +882,7 @@ static __init void build_tlb_write_entry(u32 **p, struct label **l,
case CPU_4KEC:
case CPU_24K:
+ case CPU_34K:
i_ehb(p);
tlbw(p);
break;
@@ -911,6 +919,7 @@ static __init void build_tlb_write_entry(u32 **p, struct label **l,
case CPU_VR4131:
case CPU_VR4133:
+ case CPU_R5432:
i_nop(p);
i_nop(p);
tlbw(p);
@@ -942,34 +951,29 @@ build_get_pmde64(u32 **p, struct label **l, struct reloc **r,
/* No i_nop needed here, since the next insn doesn't touch TMP. */
#ifdef CONFIG_SMP
+# ifdef CONFIG_BUILD_ELF64
/*
- * 64 bit SMP has the lower part of &pgd_current[smp_processor_id()]
+ * 64 bit SMP running in XKPHYS has smp_processor_id() << 3
* stored in CONTEXT.
*/
- if (in_compat_space_p(pgdc)) {
- i_dmfc0(p, ptr, C0_CONTEXT);
- i_dsra(p, ptr, ptr, 23);
- i_ld(p, ptr, 0, ptr);
- } else {
-#ifdef CONFIG_BUILD_ELF64
- i_dmfc0(p, ptr, C0_CONTEXT);
- i_dsrl(p, ptr, ptr, 23);
- i_dsll(p, ptr, ptr, 3);
- i_LA_mostly(p, tmp, pgdc);
- i_daddu(p, ptr, ptr, tmp);
- i_dmfc0(p, tmp, C0_BADVADDR);
- i_ld(p, ptr, rel_lo(pgdc), ptr);
-#else
- i_dmfc0(p, ptr, C0_CONTEXT);
- i_lui(p, tmp, rel_highest(pgdc));
- i_dsll(p, ptr, ptr, 9);
- i_daddiu(p, tmp, tmp, rel_higher(pgdc));
- i_dsrl32(p, ptr, ptr, 0);
- i_and(p, ptr, ptr, tmp);
- i_dmfc0(p, tmp, C0_BADVADDR);
- i_ld(p, ptr, 0, ptr);
-#endif
- }
+ i_dmfc0(p, ptr, C0_CONTEXT);
+ i_dsrl(p, ptr, ptr, 23);
+ i_LA_mostly(p, tmp, pgdc);
+ i_daddu(p, ptr, ptr, tmp);
+ i_dmfc0(p, tmp, C0_BADVADDR);
+ i_ld(p, ptr, rel_lo(pgdc), ptr);
+# else
+ /*
+ * 64 bit SMP running in compat space has the lower part of
+ * &pgd_current[smp_processor_id()] stored in CONTEXT.
+ */
+ if (!in_compat_space_p(pgdc))
+ panic("Invalid page directory address!");
+
+ i_dmfc0(p, ptr, C0_CONTEXT);
+ i_dsra(p, ptr, ptr, 23);
+ i_ld(p, ptr, 0, ptr);
+# endif
#else
i_LA_mostly(p, ptr, pgdc);
i_ld(p, ptr, rel_lo(pgdc), ptr);
@@ -1026,7 +1030,6 @@ build_get_pgde32(u32 **p, unsigned int tmp, unsigned int ptr)
i_mfc0(p, ptr, C0_CONTEXT);
i_LA_mostly(p, tmp, pgdc);
i_srl(p, ptr, ptr, 23);
- i_sll(p, ptr, ptr, 2);
i_addu(p, ptr, tmp, ptr);
#else
i_LA_mostly(p, ptr, pgdc);
@@ -1245,13 +1248,19 @@ static void __init build_r4000_tlb_refill_handler(void)
{
int i;
- for (i = 0; i < 64; i++)
- printk("%08x\n", final_handler[i]);
+ f = final_handler;
+#ifdef CONFIG_64BIT
+ if (final_len > 32)
+ final_len = 64;
+ else
+ f = final_handler + 32;
+#endif /* CONFIG_64BIT */
+ for (i = 0; i < final_len; i++)
+ printk("%08x\n", f[i]);
}
#endif
memcpy((void *)CAC_BASE, final_handler, 0x100);
- flush_icache_range(CAC_BASE, CAC_BASE + 0x100);
}
/*
@@ -1277,37 +1286,41 @@ u32 __tlb_handler_align handle_tlbs[FASTPATH_SIZE];
u32 __tlb_handler_align handle_tlbm[FASTPATH_SIZE];
static void __init
-iPTE_LW(u32 **p, struct label **l, unsigned int pte, int offset,
- unsigned int ptr)
+iPTE_LW(u32 **p, struct label **l, unsigned int pte, unsigned int ptr)
{
#ifdef CONFIG_SMP
# ifdef CONFIG_64BIT_PHYS_ADDR
if (cpu_has_64bits)
- i_lld(p, pte, offset, ptr);
+ i_lld(p, pte, 0, ptr);
else
# endif
- i_LL(p, pte, offset, ptr);
+ i_LL(p, pte, 0, ptr);
#else
# ifdef CONFIG_64BIT_PHYS_ADDR
if (cpu_has_64bits)
- i_ld(p, pte, offset, ptr);
+ i_ld(p, pte, 0, ptr);
else
# endif
- i_LW(p, pte, offset, ptr);
+ i_LW(p, pte, 0, ptr);
#endif
}
static void __init
-iPTE_SW(u32 **p, struct reloc **r, unsigned int pte, int offset,
- unsigned int ptr)
+iPTE_SW(u32 **p, struct reloc **r, unsigned int pte, unsigned int ptr,
+ unsigned int mode)
{
+#ifdef CONFIG_64BIT_PHYS_ADDR
+ unsigned int hwmode = mode & (_PAGE_VALID | _PAGE_DIRTY);
+#endif
+
+ i_ori(p, pte, pte, mode);
#ifdef CONFIG_SMP
# ifdef CONFIG_64BIT_PHYS_ADDR
if (cpu_has_64bits)
- i_scd(p, pte, offset, ptr);
+ i_scd(p, pte, 0, ptr);
else
# endif
- i_SC(p, pte, offset, ptr);
+ i_SC(p, pte, 0, ptr);
if (r10000_llsc_war())
il_beqzl(p, r, pte, label_smp_pgtable_change);
@@ -1318,7 +1331,7 @@ iPTE_SW(u32 **p, struct reloc **r, unsigned int pte, int offset,
if (!cpu_has_64bits) {
/* no i_nop needed */
i_ll(p, pte, sizeof(pte_t) / 2, ptr);
- i_ori(p, pte, pte, _PAGE_VALID);
+ i_ori(p, pte, pte, hwmode);
i_sc(p, pte, sizeof(pte_t) / 2, ptr);
il_beqz(p, r, pte, label_smp_pgtable_change);
/* no i_nop needed */
@@ -1331,15 +1344,15 @@ iPTE_SW(u32 **p, struct reloc **r, unsigned int pte, int offset,
#else
# ifdef CONFIG_64BIT_PHYS_ADDR
if (cpu_has_64bits)
- i_sd(p, pte, offset, ptr);
+ i_sd(p, pte, 0, ptr);
else
# endif
- i_SW(p, pte, offset, ptr);
+ i_SW(p, pte, 0, ptr);
# ifdef CONFIG_64BIT_PHYS_ADDR
if (!cpu_has_64bits) {
i_lw(p, pte, sizeof(pte_t) / 2, ptr);
- i_ori(p, pte, pte, _PAGE_VALID);
+ i_ori(p, pte, pte, hwmode);
i_sw(p, pte, sizeof(pte_t) / 2, ptr);
i_lw(p, pte, 0, ptr);
}
@@ -1359,7 +1372,7 @@ build_pte_present(u32 **p, struct label **l, struct reloc **r,
i_andi(p, pte, pte, _PAGE_PRESENT | _PAGE_READ);
i_xori(p, pte, pte, _PAGE_PRESENT | _PAGE_READ);
il_bnez(p, r, pte, lid);
- iPTE_LW(p, l, pte, 0, ptr);
+ iPTE_LW(p, l, pte, ptr);
}
/* Make PTE valid, store result in PTR. */
@@ -1367,8 +1380,9 @@ static void __init
build_make_valid(u32 **p, struct reloc **r, unsigned int pte,
unsigned int ptr)
{
- i_ori(p, pte, pte, _PAGE_VALID | _PAGE_ACCESSED);
- iPTE_SW(p, r, pte, 0, ptr);
+ unsigned int mode = _PAGE_VALID | _PAGE_ACCESSED;
+
+ iPTE_SW(p, r, pte, ptr, mode);
}
/*
@@ -1382,7 +1396,7 @@ build_pte_writable(u32 **p, struct label **l, struct reloc **r,
i_andi(p, pte, pte, _PAGE_PRESENT | _PAGE_WRITE);
i_xori(p, pte, pte, _PAGE_PRESENT | _PAGE_WRITE);
il_bnez(p, r, pte, lid);
- iPTE_LW(p, l, pte, 0, ptr);
+ iPTE_LW(p, l, pte, ptr);
}
/* Make PTE writable, update software status bits as well, then store
@@ -1392,9 +1406,10 @@ static void __init
build_make_write(u32 **p, struct reloc **r, unsigned int pte,
unsigned int ptr)
{
- i_ori(p, pte, pte,
- _PAGE_ACCESSED | _PAGE_MODIFIED | _PAGE_VALID | _PAGE_DIRTY);
- iPTE_SW(p, r, pte, 0, ptr);
+ unsigned int mode = (_PAGE_ACCESSED | _PAGE_MODIFIED | _PAGE_VALID
+ | _PAGE_DIRTY);
+
+ iPTE_SW(p, r, pte, ptr, mode);
}
/*
@@ -1407,41 +1422,48 @@ build_pte_modifiable(u32 **p, struct label **l, struct reloc **r,
{
i_andi(p, pte, pte, _PAGE_WRITE);
il_beqz(p, r, pte, lid);
- iPTE_LW(p, l, pte, 0, ptr);
+ iPTE_LW(p, l, pte, ptr);
}
/*
* R3000 style TLB load/store/modify handlers.
*/
-/* This places the pte in the page table at PTR into ENTRYLO0. */
+/*
+ * This places the pte into ENTRYLO0 and writes it with tlbwi.
+ * Then it returns.
+ */
static void __init
-build_r3000_pte_reload(u32 **p, unsigned int ptr)
+build_r3000_pte_reload_tlbwi(u32 **p, unsigned int pte, unsigned int tmp)
{
- i_lw(p, ptr, 0, ptr);
- i_nop(p); /* load delay */
- i_mtc0(p, ptr, C0_ENTRYLO0);
- i_nop(p); /* cp0 delay */
+ i_mtc0(p, pte, C0_ENTRYLO0); /* cp0 delay */
+ i_mfc0(p, tmp, C0_EPC); /* cp0 delay */
+ i_tlbwi(p);
+ i_jr(p, tmp);
+ i_rfe(p); /* branch delay */
}
/*
- * The index register may have the probe fail bit set,
- * because we would trap on access kseg2, i.e. without refill.
+ * This places the pte into ENTRYLO0 and writes it with tlbwi
+ * or tlbwr as appropriate. This is because the index register
+ * may have the probe fail bit set as a result of a trap on a
+ * kseg2 access, i.e. without refill. Then it returns.
*/
static void __init
-build_r3000_tlb_write(u32 **p, struct label **l, struct reloc **r,
- unsigned int tmp)
+build_r3000_tlb_reload_write(u32 **p, struct label **l, struct reloc **r,
+ unsigned int pte, unsigned int tmp)
{
i_mfc0(p, tmp, C0_INDEX);
- i_nop(p); /* cp0 delay */
- il_bltz(p, r, tmp, label_r3000_write_probe_fail);
- i_nop(p); /* branch delay */
- i_tlbwi(p);
- il_b(p, r, label_r3000_write_probe_ok);
- i_nop(p); /* branch delay */
+ i_mtc0(p, pte, C0_ENTRYLO0); /* cp0 delay */
+ il_bltz(p, r, tmp, label_r3000_write_probe_fail); /* cp0 delay */
+ i_mfc0(p, tmp, C0_EPC); /* branch delay */
+ i_tlbwi(p); /* cp0 delay */
+ i_jr(p, tmp);
+ i_rfe(p); /* branch delay */
l_r3000_write_probe_fail(l, *p);
- i_tlbwr(p);
- l_r3000_write_probe_ok(l, *p);
+ i_tlbwr(p); /* cp0 delay */
+ i_jr(p, tmp);
+ i_rfe(p); /* branch delay */
}
static void __init
@@ -1461,17 +1483,7 @@ build_r3000_tlbchange_handler_head(u32 **p, unsigned int pte,
i_andi(p, pte, pte, 0xffc); /* load delay */
i_addu(p, ptr, ptr, pte);
i_lw(p, pte, 0, ptr);
- i_nop(p); /* load delay */
- i_tlbp(p);
-}
-
-static void __init
-build_r3000_tlbchange_handler_tail(u32 **p, unsigned int tmp)
-{
- i_mfc0(p, tmp, C0_EPC);
- i_nop(p); /* cp0 delay */
- i_jr(p, tmp);
- i_rfe(p); /* branch delay */
+ i_tlbp(p); /* load delay */
}
static void __init build_r3000_tlb_load_handler(void)
@@ -1486,10 +1498,9 @@ static void __init build_r3000_tlb_load_handler(void)
build_r3000_tlbchange_handler_head(&p, K0, K1);
build_pte_present(&p, &l, &r, K0, K1, label_nopage_tlbl);
+ i_nop(&p); /* load delay */
build_make_valid(&p, &r, K0, K1);
- build_r3000_pte_reload(&p, K1);
- build_r3000_tlb_write(&p, &l, &r, K0);
- build_r3000_tlbchange_handler_tail(&p, K0);
+ build_r3000_tlb_reload_write(&p, &l, &r, K0, K1);
l_nopage_tlbl(&l, p);
i_j(&p, (unsigned long)tlb_do_page_fault_0 & 0x0fffffff);
@@ -1506,13 +1517,10 @@ static void __init build_r3000_tlb_load_handler(void)
{
int i;
- for (i = 0; i < FASTPATH_SIZE; i++)
+ for (i = 0; i < (p - handle_tlbl); i++)
printk("%08x\n", handle_tlbl[i]);
}
#endif
-
- flush_icache_range((unsigned long)handle_tlbl,
- (unsigned long)handle_tlbl + FASTPATH_SIZE * sizeof(u32));
}
static void __init build_r3000_tlb_store_handler(void)
@@ -1527,10 +1535,9 @@ static void __init build_r3000_tlb_store_handler(void)
build_r3000_tlbchange_handler_head(&p, K0, K1);
build_pte_writable(&p, &l, &r, K0, K1, label_nopage_tlbs);
+ i_nop(&p); /* load delay */
build_make_write(&p, &r, K0, K1);
- build_r3000_pte_reload(&p, K1);
- build_r3000_tlb_write(&p, &l, &r, K0);
- build_r3000_tlbchange_handler_tail(&p, K0);
+ build_r3000_tlb_reload_write(&p, &l, &r, K0, K1);
l_nopage_tlbs(&l, p);
i_j(&p, (unsigned long)tlb_do_page_fault_1 & 0x0fffffff);
@@ -1547,13 +1554,10 @@ static void __init build_r3000_tlb_store_handler(void)
{
int i;
- for (i = 0; i < FASTPATH_SIZE; i++)
+ for (i = 0; i < (p - handle_tlbs); i++)
printk("%08x\n", handle_tlbs[i]);
}
#endif
-
- flush_icache_range((unsigned long)handle_tlbs,
- (unsigned long)handle_tlbs + FASTPATH_SIZE * sizeof(u32));
}
static void __init build_r3000_tlb_modify_handler(void)
@@ -1568,10 +1572,9 @@ static void __init build_r3000_tlb_modify_handler(void)
build_r3000_tlbchange_handler_head(&p, K0, K1);
build_pte_modifiable(&p, &l, &r, K0, K1, label_nopage_tlbm);
+ i_nop(&p); /* load delay */
build_make_write(&p, &r, K0, K1);
- build_r3000_pte_reload(&p, K1);
- i_tlbwi(&p);
- build_r3000_tlbchange_handler_tail(&p, K0);
+ build_r3000_pte_reload_tlbwi(&p, K0, K1);
l_nopage_tlbm(&l, p);
i_j(&p, (unsigned long)tlb_do_page_fault_1 & 0x0fffffff);
@@ -1588,13 +1591,10 @@ static void __init build_r3000_tlb_modify_handler(void)
{
int i;
- for (i = 0; i < FASTPATH_SIZE; i++)
+ for (i = 0; i < (p - handle_tlbm); i++)
printk("%08x\n", handle_tlbm[i]);
}
#endif
-
- flush_icache_range((unsigned long)handle_tlbm,
- (unsigned long)handle_tlbm + FASTPATH_SIZE * sizeof(u32));
}
/*
@@ -1620,7 +1620,7 @@ build_r4000_tlbchange_handler_head(u32 **p, struct label **l,
#ifdef CONFIG_SMP
l_smp_pgtable_change(l, *p);
# endif
- iPTE_LW(p, l, pte, 0, ptr); /* get even pte */
+ iPTE_LW(p, l, pte, ptr); /* get even pte */
build_tlb_probe_entry(p);
}
@@ -1680,13 +1680,10 @@ static void __init build_r4000_tlb_load_handler(void)
{
int i;
- for (i = 0; i < FASTPATH_SIZE; i++)
+ for (i = 0; i < (p - handle_tlbl); i++)
printk("%08x\n", handle_tlbl[i]);
}
#endif
-
- flush_icache_range((unsigned long)handle_tlbl,
- (unsigned long)handle_tlbl + FASTPATH_SIZE * sizeof(u32));
}
static void __init build_r4000_tlb_store_handler(void)
@@ -1719,13 +1716,10 @@ static void __init build_r4000_tlb_store_handler(void)
{
int i;
- for (i = 0; i < FASTPATH_SIZE; i++)
+ for (i = 0; i < (p - handle_tlbs); i++)
printk("%08x\n", handle_tlbs[i]);
}
#endif
-
- flush_icache_range((unsigned long)handle_tlbs,
- (unsigned long)handle_tlbs + FASTPATH_SIZE * sizeof(u32));
}
static void __init build_r4000_tlb_modify_handler(void)
@@ -1759,13 +1753,10 @@ static void __init build_r4000_tlb_modify_handler(void)
{
int i;
- for (i = 0; i < FASTPATH_SIZE; i++)
+ for (i = 0; i < (p - handle_tlbm); i++)
printk("%08x\n", handle_tlbm[i]);
}
#endif
-
- flush_icache_range((unsigned long)handle_tlbm,
- (unsigned long)handle_tlbm + FASTPATH_SIZE * sizeof(u32));
}
void __init build_tlb_refill_handler(void)
@@ -1813,3 +1804,13 @@ void __init build_tlb_refill_handler(void)
}
}
}
+
+void __init flush_tlb_handlers(void)
+{
+ flush_icache_range((unsigned long)handle_tlbl,
+ (unsigned long)handle_tlbl + sizeof(handle_tlbl));
+ flush_icache_range((unsigned long)handle_tlbs,
+ (unsigned long)handle_tlbs + sizeof(handle_tlbs));
+ flush_icache_range((unsigned long)handle_tlbm,
+ (unsigned long)handle_tlbm + sizeof(handle_tlbm));
+}
diff --git a/arch/mips/momentum/Kconfig b/arch/mips/momentum/Kconfig
new file mode 100644
index 000000000000..70a61cf7174d
--- /dev/null
+++ b/arch/mips/momentum/Kconfig
@@ -0,0 +1,6 @@
+config JAGUAR_DMALOW
+ bool "Low DMA Mode"
+ depends on MOMENCO_JAGUAR_ATX
+ help
+ Select to Y if jump JP5 is set on your board, N otherwise. Normally
+ the jumper is set, so if you feel unsafe, just say Y.
diff --git a/arch/mips/momentum/jaguar_atx/prom.c b/arch/mips/momentum/jaguar_atx/prom.c
index 14ae2e713585..aae7a802767a 100644
--- a/arch/mips/momentum/jaguar_atx/prom.c
+++ b/arch/mips/momentum/jaguar_atx/prom.c
@@ -236,8 +236,9 @@ void __init prom_init(void)
#endif
}
-void __init prom_free_prom_memory(void)
+unsigned long __init prom_free_prom_memory(void)
{
+ return 0;
}
void __init prom_fixup_mem_map(unsigned long start, unsigned long end)
diff --git a/arch/mips/momentum/jaguar_atx/setup.c b/arch/mips/momentum/jaguar_atx/setup.c
index 90288cf2b1e0..bab192ddc185 100644
--- a/arch/mips/momentum/jaguar_atx/setup.c
+++ b/arch/mips/momentum/jaguar_atx/setup.c
@@ -149,7 +149,9 @@ arch_initcall(per_cpu_mappings);
unsigned long m48t37y_get_time(void)
{
unsigned int year, month, day, hour, min, sec;
+ unsigned long flags;
+ spin_lock_irqsave(&rtc_lock, flags);
/* stop the update */
rtc_base[0x7ff8] = 0x40;
@@ -166,6 +168,7 @@ unsigned long m48t37y_get_time(void)
/* start the update */
rtc_base[0x7ff8] = 0x00;
+ spin_unlock_irqrestore(&rtc_lock, flags);
return mktime(year, month, day, hour, min, sec);
}
@@ -173,11 +176,13 @@ unsigned long m48t37y_get_time(void)
int m48t37y_set_time(unsigned long sec)
{
struct rtc_time tm;
+ unsigned long flags;
/* convert to a more useful format -- note months count from 0 */
to_tm(sec, &tm);
tm.tm_mon += 1;
+ spin_lock_irqsave(&rtc_lock, flags);
/* enable writing */
rtc_base[0x7ff8] = 0x80;
@@ -201,6 +206,7 @@ int m48t37y_set_time(unsigned long sec)
/* disable writing */
rtc_base[0x7ff8] = 0x00;
+ spin_unlock_irqrestore(&rtc_lock, flags);
return 0;
}
@@ -351,7 +357,7 @@ static __init int __init ja_pci_init(void)
arch_initcall(ja_pci_init);
-static int __init momenco_jaguar_atx_setup(void)
+void __init plat_setup(void)
{
unsigned int tmpword;
@@ -467,8 +473,4 @@ static int __init momenco_jaguar_atx_setup(void)
}
#endif
-
- return 0;
}
-
-early_initcall(momenco_jaguar_atx_setup);
diff --git a/arch/mips/momentum/ocelot_3/prom.c b/arch/mips/momentum/ocelot_3/prom.c
index c4fa9c525faa..9803daa2a792 100644
--- a/arch/mips/momentum/ocelot_3/prom.c
+++ b/arch/mips/momentum/ocelot_3/prom.c
@@ -239,8 +239,9 @@ void __init prom_init(void)
#endif
}
-void __init prom_free_prom_memory(void)
+unsigned long __init prom_free_prom_memory(void)
{
+ return 0;
}
void __init prom_fixup_mem_map(unsigned long start, unsigned long end)
diff --git a/arch/mips/momentum/ocelot_3/setup.c b/arch/mips/momentum/ocelot_3/setup.c
index ce2efcbab7aa..c9b7ff8148ec 100644
--- a/arch/mips/momentum/ocelot_3/setup.c
+++ b/arch/mips/momentum/ocelot_3/setup.c
@@ -135,7 +135,9 @@ void setup_wired_tlb_entries(void)
unsigned long m48t37y_get_time(void)
{
unsigned int year, month, day, hour, min, sec;
+ unsigned long flags;
+ spin_lock_irqsave(&rtc_lock, flags);
/* stop the update */
rtc_base[0x7ff8] = 0x40;
@@ -152,6 +154,7 @@ unsigned long m48t37y_get_time(void)
/* start the update */
rtc_base[0x7ff8] = 0x00;
+ spin_unlock_irqrestore(&rtc_lock, flags);
return mktime(year, month, day, hour, min, sec);
}
@@ -159,11 +162,13 @@ unsigned long m48t37y_get_time(void)
int m48t37y_set_time(unsigned long sec)
{
struct rtc_time tm;
+ unsigned long flags;
/* convert to a more useful format -- note months count from 0 */
to_tm(sec, &tm);
tm.tm_mon += 1;
+ spin_lock_irqsave(&rtc_lock, flags);
/* enable writing */
rtc_base[0x7ff8] = 0x80;
@@ -187,6 +192,7 @@ int m48t37y_set_time(unsigned long sec)
/* disable writing */
rtc_base[0x7ff8] = 0x00;
+ spin_unlock_irqrestore(&rtc_lock, flags);
return 0;
}
@@ -307,7 +313,7 @@ static __init int __init ja_pci_init(void)
arch_initcall(ja_pci_init);
-static int __init momenco_ocelot_3_setup(void)
+void __init plat_setup(void)
{
unsigned int tmpword;
@@ -391,8 +397,4 @@ static int __init momenco_ocelot_3_setup(void)
/* Support for 128 MB memory */
add_memory_region(0x0, 0x08000000, BOOT_MEM_RAM);
-
- return 0;
}
-
-early_initcall(momenco_ocelot_3_setup);
diff --git a/arch/mips/momentum/ocelot_c/cpci-irq.c b/arch/mips/momentum/ocelot_c/cpci-irq.c
index dea48b3ad687..bd885785e2f9 100644
--- a/arch/mips/momentum/ocelot_c/cpci-irq.c
+++ b/arch/mips/momentum/ocelot_c/cpci-irq.c
@@ -129,14 +129,13 @@ void ll_cpci_irq(struct pt_regs *regs)
#define shutdown_cpci_irq disable_cpci_irq
struct hw_interrupt_type cpci_irq_type = {
- "CPCI/FPGA",
- startup_cpci_irq,
- shutdown_cpci_irq,
- enable_cpci_irq,
- disable_cpci_irq,
- mask_and_ack_cpci_irq,
- end_cpci_irq,
- NULL
+ .typename = "CPCI/FPGA",
+ .startup = startup_cpci_irq,
+ .shutdown = shutdown_cpci_irq,
+ .enable = enable_cpci_irq,
+ .disable = disable_cpci_irq,
+ .ack = mask_and_ack_cpci_irq,
+ .end = end_cpci_irq,
};
void cpci_irq_init(void)
diff --git a/arch/mips/momentum/ocelot_c/setup.c b/arch/mips/momentum/ocelot_c/setup.c
index 844ddd06349b..2755c1547473 100644
--- a/arch/mips/momentum/ocelot_c/setup.c
+++ b/arch/mips/momentum/ocelot_c/setup.c
@@ -140,7 +140,9 @@ unsigned long m48t37y_get_time(void)
unsigned char* rtc_base = (unsigned char*)0xfc800000;
#endif
unsigned int year, month, day, hour, min, sec;
+ unsigned long flags;
+ spin_lock_irqsave(&rtc_lock, flags);
/* stop the update */
rtc_base[0x7ff8] = 0x40;
@@ -157,6 +159,7 @@ unsigned long m48t37y_get_time(void)
/* start the update */
rtc_base[0x7ff8] = 0x00;
+ spin_unlock_irqrestore(&rtc_lock, flags);
return mktime(year, month, day, hour, min, sec);
}
@@ -169,11 +172,13 @@ int m48t37y_set_time(unsigned long sec)
unsigned char* rtc_base = (unsigned char*)0xfc800000;
#endif
struct rtc_time tm;
+ unsigned long flags;
/* convert to a more useful format -- note months count from 0 */
to_tm(sec, &tm);
tm.tm_mon += 1;
+ spin_lock_irqsave(&rtc_lock, flags);
/* enable writing */
rtc_base[0x7ff8] = 0x80;
@@ -197,6 +202,7 @@ int m48t37y_set_time(unsigned long sec)
/* disable writing */
rtc_base[0x7ff8] = 0x00;
+ spin_unlock_irqrestore(&rtc_lock, flags);
return 0;
}
@@ -222,7 +228,7 @@ void momenco_time_init(void)
rtc_set_time = m48t37y_set_time;
}
-static void __init momenco_ocelot_c_setup(void)
+void __init plat_setup(void)
{
unsigned int tmpword;
@@ -340,8 +346,6 @@ static void __init momenco_ocelot_c_setup(void)
}
}
-early_initcall(momenco_ocelot_c_setup);
-
#ifndef CONFIG_64BIT
/* This needs to be one of the first initcalls, because no I/O port access
can work before this */
diff --git a/arch/mips/momentum/ocelot_c/uart-irq.c b/arch/mips/momentum/ocelot_c/uart-irq.c
index ebe1507b17df..755bde5146be 100644
--- a/arch/mips/momentum/ocelot_c/uart-irq.c
+++ b/arch/mips/momentum/ocelot_c/uart-irq.c
@@ -122,14 +122,13 @@ void ll_uart_irq(struct pt_regs *regs)
#define shutdown_uart_irq disable_uart_irq
struct hw_interrupt_type uart_irq_type = {
- "UART/FPGA",
- startup_uart_irq,
- shutdown_uart_irq,
- enable_uart_irq,
- disable_uart_irq,
- mask_and_ack_uart_irq,
- end_uart_irq,
- NULL
+ .typename = "UART/FPGA",
+ .startup = startup_uart_irq,
+ .shutdown = shutdown_uart_irq,
+ .enable = enable_uart_irq,
+ .disable = disable_uart_irq,
+ .ack = mask_and_ack_uart_irq,
+ .end = end_uart_irq,
};
void uart_irq_init(void)
diff --git a/arch/mips/momentum/ocelot_g/setup.c b/arch/mips/momentum/ocelot_g/setup.c
index 38a78ab8c830..6336751391c3 100644
--- a/arch/mips/momentum/ocelot_g/setup.c
+++ b/arch/mips/momentum/ocelot_g/setup.c
@@ -160,7 +160,7 @@ static void __init setup_l3cache(unsigned long size)
printk("Done\n");
}
-static int __init momenco_ocelot_g_setup(void)
+void __init plat_setup(void)
{
void (*l3func)(unsigned long) = (void *) KSEG1ADDR(setup_l3cache);
unsigned int tmpword;
@@ -240,12 +240,8 @@ static int __init momenco_ocelot_g_setup(void)
/* FIXME: Fix up the DiskOnChip mapping */
MV_WRITE(0x468, 0xfef73);
-
- return 0;
}
-early_initcall(momenco_ocelot_g_setup);
-
/* This needs to be one of the first initcalls, because no I/O port access
can work before this */
diff --git a/arch/mips/oprofile/Kconfig b/arch/mips/oprofile/Kconfig
index 19d37730b664..55feaf798596 100644
--- a/arch/mips/oprofile/Kconfig
+++ b/arch/mips/oprofile/Kconfig
@@ -11,7 +11,7 @@ config PROFILING
config OPROFILE
tristate "OProfile system profiling (EXPERIMENTAL)"
- depends on PROFILING
+ depends on PROFILING && EXPERIMENTAL
help
OProfile is a profiling system capable of profiling the
whole system, include the kernel, kernel modules, libraries,
diff --git a/arch/mips/oprofile/common.c b/arch/mips/oprofile/common.c
index ab65ce3d471a..dd2cc42f1b6d 100644
--- a/arch/mips/oprofile/common.c
+++ b/arch/mips/oprofile/common.c
@@ -3,7 +3,8 @@
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
- * Copyright (C) 2004 by Ralf Baechle
+ * Copyright (C) 2004, 2005 Ralf Baechle
+ * Copyright (C) 2005 MIPS Technologies, Inc.
*/
#include <linux/errno.h>
#include <linux/init.h>
@@ -45,10 +46,10 @@ static int op_mips_create_files(struct super_block * sb, struct dentry * root)
oprofilefs_create_ulong(sb, dir, "enabled", &ctr[i].enabled);
oprofilefs_create_ulong(sb, dir, "event", &ctr[i].event);
oprofilefs_create_ulong(sb, dir, "count", &ctr[i].count);
- /* Dummies. */
oprofilefs_create_ulong(sb, dir, "kernel", &ctr[i].kernel);
oprofilefs_create_ulong(sb, dir, "user", &ctr[i].user);
oprofilefs_create_ulong(sb, dir, "exl", &ctr[i].exl);
+ /* Dummy. */
oprofilefs_create_ulong(sb, dir, "unit_mask", &ctr[i].unit_mask);
}
@@ -68,9 +69,10 @@ static void op_mips_stop(void)
on_each_cpu(model->cpu_stop, NULL, 0, 1);
}
-void __init oprofile_arch_init(struct oprofile_operations *ops)
+int __init oprofile_arch_init(struct oprofile_operations *ops)
{
struct op_mips_model *lmodel = NULL;
+ int res;
switch (current_cpu_data.cputype) {
case CPU_24K:
@@ -83,21 +85,25 @@ void __init oprofile_arch_init(struct oprofile_operations *ops)
};
if (!lmodel)
- return;
+ return -ENODEV;
- if (lmodel->init())
- return;
+ res = lmodel->init();
+ if (res)
+ return res;
model = lmodel;
- ops->create_files = op_mips_create_files;
- ops->setup = op_mips_setup;
- ops->start = op_mips_start;
- ops->stop = op_mips_stop;
- ops->cpu_type = lmodel->cpu_type;
+ ops->create_files = op_mips_create_files;
+ ops->setup = op_mips_setup;
+ //ops->shutdown = op_mips_shutdown;
+ ops->start = op_mips_start;
+ ops->stop = op_mips_stop;
+ ops->cpu_type = lmodel->cpu_type;
printk(KERN_INFO "oprofile: using %s performance monitoring.\n",
lmodel->cpu_type);
+
+ return 0;
}
void oprofile_arch_exit(void)
diff --git a/arch/mips/oprofile/op_impl.h b/arch/mips/oprofile/op_impl.h
index 9f5cdff041be..f0121557047d 100644
--- a/arch/mips/oprofile/op_impl.h
+++ b/arch/mips/oprofile/op_impl.h
@@ -10,6 +10,11 @@
#ifndef OP_IMPL_H
#define OP_IMPL_H 1
+struct pt_regs;
+
+extern void null_perf_irq(struct pt_regs *regs);
+extern void (*perf_irq)(struct pt_regs *regs);
+
/* Per-counter configuration as set via oprofilefs. */
struct op_counter_config {
unsigned long enabled;
diff --git a/arch/mips/oprofile/op_model_mipsxx.c b/arch/mips/oprofile/op_model_mipsxx.c
new file mode 100644
index 000000000000..d36b64dfcb2f
--- /dev/null
+++ b/arch/mips/oprofile/op_model_mipsxx.c
@@ -0,0 +1,215 @@
+/*
+ * 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) 2004, 2005 by Ralf Baechle
+ * Copyright (C) 2005 by MIPS Technologies, Inc.
+ */
+#include <linux/oprofile.h>
+#include <linux/interrupt.h>
+#include <linux/smp.h>
+
+#include "op_impl.h"
+
+#define M_PERFCTL_EXL (1UL << 0)
+#define M_PERFCTL_KERNEL (1UL << 1)
+#define M_PERFCTL_SUPERVISOR (1UL << 2)
+#define M_PERFCTL_USER (1UL << 3)
+#define M_PERFCTL_INTERRUPT_ENABLE (1UL << 4)
+#define M_PERFCTL_EVENT(event) ((event) << 5)
+#define M_PERFCTL_WIDE (1UL << 30)
+#define M_PERFCTL_MORE (1UL << 31)
+
+#define M_COUNTER_OVERFLOW (1UL << 31)
+
+struct op_mips_model op_model_mipsxx;
+
+static struct mipsxx_register_config {
+ unsigned int control[4];
+ unsigned int counter[4];
+} reg;
+
+/* Compute all of the registers in preparation for enabling profiling. */
+
+static void mipsxx_reg_setup(struct op_counter_config *ctr)
+{
+ unsigned int counters = op_model_mipsxx.num_counters;
+ int i;
+
+ /* Compute the performance counter control word. */
+ /* For now count kernel and user mode */
+ for (i = 0; i < counters; i++) {
+ reg.control[i] = 0;
+ reg.counter[i] = 0;
+
+ if (!ctr[i].enabled)
+ continue;
+
+ reg.control[i] = M_PERFCTL_EVENT(ctr[i].event) |
+ M_PERFCTL_INTERRUPT_ENABLE;
+ if (ctr[i].kernel)
+ reg.control[i] |= M_PERFCTL_KERNEL;
+ if (ctr[i].user)
+ reg.control[i] |= M_PERFCTL_USER;
+ if (ctr[i].exl)
+ reg.control[i] |= M_PERFCTL_EXL;
+ reg.counter[i] = 0x80000000 - ctr[i].count;
+ }
+}
+
+/* Program all of the registers in preparation for enabling profiling. */
+
+static void mipsxx_cpu_setup (void *args)
+{
+ unsigned int counters = op_model_mipsxx.num_counters;
+
+ switch (counters) {
+ case 4:
+ write_c0_perfctrl3(0);
+ write_c0_perfcntr3(reg.counter[3]);
+ case 3:
+ write_c0_perfctrl2(0);
+ write_c0_perfcntr2(reg.counter[2]);
+ case 2:
+ write_c0_perfctrl1(0);
+ write_c0_perfcntr1(reg.counter[1]);
+ case 1:
+ write_c0_perfctrl0(0);
+ write_c0_perfcntr0(reg.counter[0]);
+ }
+}
+
+/* Start all counters on current CPU */
+static void mipsxx_cpu_start(void *args)
+{
+ unsigned int counters = op_model_mipsxx.num_counters;
+
+ switch (counters) {
+ case 4:
+ write_c0_perfctrl3(reg.control[3]);
+ case 3:
+ write_c0_perfctrl2(reg.control[2]);
+ case 2:
+ write_c0_perfctrl1(reg.control[1]);
+ case 1:
+ write_c0_perfctrl0(reg.control[0]);
+ }
+}
+
+/* Stop all counters on current CPU */
+static void mipsxx_cpu_stop(void *args)
+{
+ unsigned int counters = op_model_mipsxx.num_counters;
+
+ switch (counters) {
+ case 4:
+ write_c0_perfctrl3(0);
+ case 3:
+ write_c0_perfctrl2(0);
+ case 2:
+ write_c0_perfctrl1(0);
+ case 1:
+ write_c0_perfctrl0(0);
+ }
+}
+
+static void mipsxx_perfcount_handler(struct pt_regs *regs)
+{
+ unsigned int counters = op_model_mipsxx.num_counters;
+ unsigned int control;
+ unsigned int counter;
+
+ switch (counters) {
+#define HANDLE_COUNTER(n) \
+ case n + 1: \
+ control = read_c0_perfctrl ## n(); \
+ counter = read_c0_perfcntr ## n(); \
+ if ((control & M_PERFCTL_INTERRUPT_ENABLE) && \
+ (counter & M_COUNTER_OVERFLOW)) { \
+ oprofile_add_sample(regs, n); \
+ write_c0_perfcntr ## n(reg.counter[n]); \
+ }
+ HANDLE_COUNTER(3)
+ HANDLE_COUNTER(2)
+ HANDLE_COUNTER(1)
+ HANDLE_COUNTER(0)
+ }
+}
+
+#define M_CONFIG1_PC (1 << 4)
+
+static inline int n_counters(void)
+{
+ if (!(read_c0_config1() & M_CONFIG1_PC))
+ return 0;
+ if (!(read_c0_perfctrl0() & M_PERFCTL_MORE))
+ return 1;
+ if (!(read_c0_perfctrl1() & M_PERFCTL_MORE))
+ return 2;
+ if (!(read_c0_perfctrl2() & M_PERFCTL_MORE))
+ return 3;
+
+ return 4;
+}
+
+static inline void reset_counters(int counters)
+{
+ switch (counters) {
+ case 4:
+ write_c0_perfctrl3(0);
+ write_c0_perfcntr3(0);
+ case 3:
+ write_c0_perfctrl2(0);
+ write_c0_perfcntr2(0);
+ case 2:
+ write_c0_perfctrl1(0);
+ write_c0_perfcntr1(0);
+ case 1:
+ write_c0_perfctrl0(0);
+ write_c0_perfcntr0(0);
+ }
+}
+
+static int __init mipsxx_init(void)
+{
+ int counters;
+
+ counters = n_counters();
+ if (counters == 0)
+ return -ENODEV;
+
+ reset_counters(counters);
+
+ op_model_mipsxx.num_counters = counters;
+ switch (current_cpu_data.cputype) {
+ case CPU_24K:
+ op_model_mipsxx.cpu_type = "mips/24K";
+ break;
+
+ default:
+ printk(KERN_ERR "Profiling unsupported for this CPU\n");
+
+ return -ENODEV;
+ }
+
+ perf_irq = mipsxx_perfcount_handler;
+
+ return 0;
+}
+
+static void mipsxx_exit(void)
+{
+ reset_counters(op_model_mipsxx.num_counters);
+
+ perf_irq = null_perf_irq;
+}
+
+struct op_mips_model op_model_mipsxx = {
+ .reg_setup = mipsxx_reg_setup,
+ .cpu_setup = mipsxx_cpu_setup,
+ .init = mipsxx_init,
+ .exit = mipsxx_exit,
+ .cpu_start = mipsxx_cpu_start,
+ .cpu_stop = mipsxx_cpu_stop,
+};
diff --git a/arch/mips/oprofile/op_model_rm9000.c b/arch/mips/oprofile/op_model_rm9000.c
index bee47793cb1a..9b75e41c78ef 100644
--- a/arch/mips/oprofile/op_model_rm9000.c
+++ b/arch/mips/oprofile/op_model_rm9000.c
@@ -5,6 +5,7 @@
*
* Copyright (C) 2004 by Ralf Baechle
*/
+#include <linux/init.h>
#include <linux/oprofile.h>
#include <linux/interrupt.h>
#include <linux/smp.h>
@@ -114,7 +115,7 @@ static irqreturn_t rm9000_perfcount_handler(int irq, void * dev_id,
return IRQ_HANDLED;
}
-static int rm9000_init(void)
+static int __init rm9000_init(void)
{
return request_irq(rm9000_perfcount_irq, rm9000_perfcount_handler,
0, "Perfcounter", NULL);
diff --git a/arch/mips/pci/Makefile b/arch/mips/pci/Makefile
index 83d81c9cdc2b..7b7468304022 100644
--- a/arch/mips/pci/Makefile
+++ b/arch/mips/pci/Makefile
@@ -34,6 +34,7 @@ obj-$(CONFIG_MIPS_ITE8172) += fixup-ite8172g.o
obj-$(CONFIG_MIPS_IVR) += fixup-ivr.o
obj-$(CONFIG_SOC_AU1500) += fixup-au1000.o ops-au1000.o
obj-$(CONFIG_SOC_AU1550) += fixup-au1000.o ops-au1000.o
+obj-$(CONFIG_SOC_PNX8550) += fixup-pnx8550.o ops-pnx8550.o
obj-$(CONFIG_MIPS_MALTA) += fixup-malta.o
obj-$(CONFIG_MOMENCO_JAGUAR_ATX)+= fixup-jaguar.o
obj-$(CONFIG_MOMENCO_OCELOT) += fixup-ocelot.o pci-ocelot.o
@@ -45,11 +46,13 @@ obj-$(CONFIG_PMC_YOSEMITE) += fixup-yosemite.o ops-titan.o ops-titan-ht.o \
obj-$(CONFIG_SGI_IP27) += pci-ip27.o
obj-$(CONFIG_SGI_IP32) += fixup-ip32.o ops-mace.o pci-ip32.o
obj-$(CONFIG_SIBYTE_SB1250) += fixup-sb1250.o pci-sb1250.o
+obj-$(CONFIG_SIBYTE_BCM1x80) += pci-bcm1480.o pci-bcm1480ht.o
obj-$(CONFIG_SNI_RM200_PCI) += fixup-sni.o ops-sni.o
obj-$(CONFIG_TANBAC_TB0219) += fixup-tb0219.o
obj-$(CONFIG_TANBAC_TB0226) += fixup-tb0226.o
obj-$(CONFIG_TANBAC_TB0287) += fixup-tb0287.o
obj-$(CONFIG_TOSHIBA_JMR3927) += fixup-jmr3927.o pci-jmr3927.o
obj-$(CONFIG_TOSHIBA_RBTX4927) += fixup-rbtx4927.o ops-tx4927.o
+obj-$(CONFIG_TOSHIBA_RBTX4938) += fixup-tx4938.o ops-tx4938.o
obj-$(CONFIG_VICTOR_MPC30X) += fixup-mpc30x.o
obj-$(CONFIG_ZAO_CAPCELLA) += fixup-capcella.o
diff --git a/arch/mips/pci/fixup-atlas.c b/arch/mips/pci/fixup-atlas.c
index 2406835833d6..87920b245931 100644
--- a/arch/mips/pci/fixup-atlas.c
+++ b/arch/mips/pci/fixup-atlas.c
@@ -1,14 +1,37 @@
+/*
+ * Copyright (C) 2003, 2004 Ralf Baechle (ralf@linux-mips.org)
+ * Copyright (C) 2005 MIPS Technologies, Inc. All rights reserved.
+ * Author: Maciej W. Rozycki <macro@mips.com>
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ */
#include <linux/config.h>
#include <linux/init.h>
#include <linux/pci.h>
+
#include <asm/mips-boards/atlasint.h>
-#define INTD ATLASINT_INTD
-#define INTC ATLASINT_INTC
-#define INTB ATLASINT_INTB
+#define PCIA ATLASINT_PCIA
+#define PCIB ATLASINT_PCIB
+#define PCIC ATLASINT_PCIC
+#define PCID ATLASINT_PCID
#define INTA ATLASINT_INTA
-#define SCSI ATLASINT_SCSI
+#define INTB ATLASINT_INTB
#define ETH ATLASINT_ETH
+#define INTC ATLASINT_INTC
+#define SCSI ATLASINT_SCSI
+#define INTD ATLASINT_INTD
static char irq_tab[][5] __initdata = {
/* INTA INTB INTC INTD */
@@ -27,13 +50,13 @@ static char irq_tab[][5] __initdata = {
{0, 0, 0, 0, 0 }, /* 12: Unused */
{0, 0, 0, 0, 0 }, /* 13: Unused */
{0, 0, 0, 0, 0 }, /* 14: Unused */
- {0, 0, 0, 0, 0 }, /* 15: Unused */
+ {0, PCIA, PCIB, PCIC, PCID }, /* 15: cPCI (behind 21150) */
{0, SCSI, 0, 0, 0 }, /* 16: SYM53C810A SCSI */
{0, 0, 0, 0, 0 }, /* 17: Core */
- {0, INTA, INTB, INTC, INTD }, /* 18: PCI Slot 1 */
- {0, ETH, 0, 0, 0 }, /* 19: SAA9730 Ethernet */
- {0, 0, 0, 0, 0 }, /* 20: PCI Slot 3 */
- {0, 0, 0, 0, 0 } /* 21: PCI Slot 4 */
+ {0, INTA, INTB, INTC, INTD }, /* 18: PCI Slot */
+ {0, ETH, 0, 0, 0 }, /* 19: SAA9730 Eth. et al. */
+ {0, 0, 0, 0, 0 }, /* 20: Unused */
+ {0, 0, 0, 0, 0 } /* 21: Unused */
};
int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
diff --git a/arch/mips/pci/fixup-au1000.c b/arch/mips/pci/fixup-au1000.c
index 39fe2b16fcec..c2f8304fe55b 100644
--- a/arch/mips/pci/fixup-au1000.c
+++ b/arch/mips/pci/fixup-au1000.c
@@ -26,7 +26,6 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#include <linux/config.h>
#include <linux/types.h>
#include <linux/pci.h>
#include <linux/kernel.h>
@@ -34,82 +33,7 @@
#include <asm/mach-au1x00/au1000.h>
-/*
- * Shortcut
- */
-#ifdef CONFIG_SOC_AU1500
-#define INTA AU1000_PCI_INTA
-#define INTB AU1000_PCI_INTB
-#define INTC AU1000_PCI_INTC
-#define INTD AU1000_PCI_INTD
-#endif
-
-#ifdef CONFIG_SOC_AU1550
-#define INTA AU1550_PCI_INTA
-#define INTB AU1550_PCI_INTB
-#define INTC AU1550_PCI_INTC
-#define INTD AU1550_PCI_INTD
-#endif
-
-#define INTX 0xFF /* not valid */
-
-#ifdef CONFIG_MIPS_DB1500
-static char irq_tab_alchemy[][5] __initdata = {
- [12] = { -1, INTA, INTX, INTX, INTX}, /* IDSEL 12 - HPT371 */
- [13] = { -1, INTA, INTB, INTC, INTD}, /* IDSEL 13 - PCI slot */
-};
-#endif
-
-#ifdef CONFIG_MIPS_BOSPORUS
-static char irq_tab_alchemy[][5] __initdata = {
- [11] = { -1, INTA, INTB, INTX, INTX}, /* IDSEL 11 - miniPCI */
- [12] = { -1, INTA, INTX, INTX, INTX}, /* IDSEL 12 - SN1741 */
- [13] = { -1, INTA, INTB, INTC, INTD}, /* IDSEL 13 - PCI slot */
-};
-#endif
-
-#ifdef CONFIG_MIPS_MIRAGE
-static char irq_tab_alchemy[][5] __initdata = {
- [11] = { -1, INTD, INTX, INTX, INTX}, /* IDSEL 11 - SMI VGX */
- [12] = { -1, INTX, INTX, INTC, INTX}, /* IDSEL 12 - PNX1300 */
- [13] = { -1, INTA, INTB, INTX, INTX}, /* IDSEL 13 - miniPCI */
-};
-#endif
-
-#ifdef CONFIG_MIPS_DB1550
-static char irq_tab_alchemy[][5] __initdata = {
- [11] = { -1, INTC, INTX, INTX, INTX}, /* IDSEL 11 - on-board HPT371 */
- [12] = { -1, INTB, INTC, INTD, INTA}, /* IDSEL 12 - PCI slot 2 (left) */
- [13] = { -1, INTA, INTB, INTC, INTD}, /* IDSEL 13 - PCI slot 1 (right) */
-};
-#endif
-
-#ifdef CONFIG_MIPS_PB1500
-static char irq_tab_alchemy[][5] __initdata = {
- [12] = { -1, INTA, INTX, INTX, INTX}, /* IDSEL 12 - HPT370 */
- [13] = { -1, INTA, INTB, INTC, INTD}, /* IDSEL 13 - PCI slot */
-};
-#endif
-
-#ifdef CONFIG_MIPS_PB1550
-static char irq_tab_alchemy[][5] __initdata = {
- [12] = { -1, INTB, INTC, INTD, INTA}, /* IDSEL 12 - PCI slot 2 (left) */
- [13] = { -1, INTA, INTB, INTC, INTD}, /* IDSEL 13 - PCI slot 1 (right) */
-};
-#endif
-
-#ifdef CONFIG_MIPS_MTX1
-static char irq_tab_alchemy[][5] __initdata = {
- [0] = { -1, INTA, INTB, INTX, INTX}, /* IDSEL 00 - AdapterA-Slot0 (top) */
- [1] = { -1, INTB, INTA, INTX, INTX}, /* IDSEL 01 - AdapterA-Slot1 (bottom) */
- [2] = { -1, INTC, INTD, INTX, INTX}, /* IDSEL 02 - AdapterB-Slot0 (top) */
- [3] = { -1, INTD, INTC, INTX, INTX}, /* IDSEL 03 - AdapterB-Slot1 (bottom) */
- [4] = { -1, INTA, INTB, INTX, INTX}, /* IDSEL 04 - AdapterC-Slot0 (top) */
- [5] = { -1, INTB, INTA, INTX, INTX}, /* IDSEL 05 - AdapterC-Slot1 (bottom) */
- [6] = { -1, INTC, INTD, INTX, INTX}, /* IDSEL 06 - AdapterD-Slot0 (top) */
- [7] = { -1, INTD, INTC, INTX, INTX}, /* IDSEL 07 - AdapterD-Slot1 (bottom) */
-};
-#endif
+extern char irq_tab_alchemy[][5];
int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
{
diff --git a/arch/mips/pci/fixup-cobalt.c b/arch/mips/pci/fixup-cobalt.c
index 57e1ca2116bb..909292f50d06 100644
--- a/arch/mips/pci/fixup-cobalt.c
+++ b/arch/mips/pci/fixup-cobalt.c
@@ -21,6 +21,20 @@
extern int cobalt_board_id;
+static void qube_raq_galileo_early_fixup(struct pci_dev *dev)
+{
+ if (dev->devfn == PCI_DEVFN(0, 0) &&
+ (dev->class >> 8) == PCI_CLASS_MEMORY_OTHER) {
+
+ dev->class = (PCI_CLASS_BRIDGE_HOST << 8) | (dev->class & 0xff);
+
+ printk(KERN_INFO "Galileo: fixed bridge class\n");
+ }
+}
+
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_MARVELL, PCI_DEVICE_ID_MARVELL_GT64111,
+ qube_raq_galileo_early_fixup);
+
static void qube_raq_via_bmIDE_fixup(struct pci_dev *dev)
{
unsigned short cfgword;
@@ -48,6 +62,9 @@ static void qube_raq_galileo_fixup(struct pci_dev *dev)
{
unsigned short galileo_id;
+ if (dev->devfn != PCI_DEVFN(0, 0))
+ return;
+
/* Fix PCI latency-timer and cache-line-size values in Galileo
* host bridge.
*/
@@ -55,6 +72,13 @@ static void qube_raq_galileo_fixup(struct pci_dev *dev)
pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, 7);
/*
+ * The code described by the comment below has been removed
+ * as it causes bus mastering by the Ethernet controllers
+ * to break under any kind of network load. We always set
+ * the retry timeouts to their maximum.
+ *
+ * --x--x--x--x--x--x--x--x--x--x--x--x--x--x--x--x--x--x--x--x--
+ *
* On all machines prior to Q2, we had the STOP line disconnected
* from Galileo to VIA on PCI. The new Galileo does not function
* correctly unless we have it connected.
@@ -64,21 +88,43 @@ static void qube_raq_galileo_fixup(struct pci_dev *dev)
*/
pci_read_config_word(dev, PCI_REVISION_ID, &galileo_id);
galileo_id &= 0xff; /* mask off class info */
+
+ printk(KERN_INFO "Galileo: revision %u\n", galileo_id);
+
+#if 0
if (galileo_id >= 0x10) {
/* New Galileo, assumes PCI stop line to VIA is connected. */
GALILEO_OUTL(0x4020, GT_PCI0_TOR_OFS);
- } else if (galileo_id == 0x1 || galileo_id == 0x2) {
+ } else if (galileo_id == 0x1 || galileo_id == 0x2)
+#endif
+ {
signed int timeo;
/* XXX WE MUST DO THIS ELSE GALILEO LOCKS UP! -DaveM */
timeo = GALILEO_INL(GT_PCI0_TOR_OFS);
/* Old Galileo, assumes PCI STOP line to VIA is disconnected. */
- GALILEO_OUTL(0xffff, GT_PCI0_TOR_OFS);
+ GALILEO_OUTL(
+ (0xff << 16) | /* retry count */
+ (0xff << 8) | /* timeout 1 */
+ 0xff, /* timeout 0 */
+ GT_PCI0_TOR_OFS);
+
+ /* enable PCI retry exceeded interrupt */
+ GALILEO_OUTL(GALILEO_INTR_RETRY_CTR | GALILEO_INL(GT_INTRMASK_OFS), GT_INTRMASK_OFS);
}
}
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_GALILEO, PCI_ANY_ID,
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL, PCI_DEVICE_ID_MARVELL_GT64111,
qube_raq_galileo_fixup);
+static char irq_tab_qube1[] __initdata = {
+ [COBALT_PCICONF_CPU] = 0,
+ [COBALT_PCICONF_ETH0] = COBALT_QUBE1_ETH0_IRQ,
+ [COBALT_PCICONF_RAQSCSI] = COBALT_SCSI_IRQ,
+ [COBALT_PCICONF_VIA] = 0,
+ [COBALT_PCICONF_PCISLOT] = COBALT_QUBE_SLOT_IRQ,
+ [COBALT_PCICONF_ETH1] = 0
+};
+
static char irq_tab_cobalt[] __initdata = {
[COBALT_PCICONF_CPU] = 0,
[COBALT_PCICONF_ETH0] = COBALT_ETH0_IRQ,
@@ -99,6 +145,9 @@ static char irq_tab_raq2[] __initdata = {
int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
{
+ if (cobalt_board_id < COBALT_BRD_ID_QUBE2)
+ return irq_tab_qube1[slot];
+
if (cobalt_board_id == COBALT_BRD_ID_RAQ2)
return irq_tab_raq2[slot];
diff --git a/arch/mips/pci/fixup-pnx8550.c b/arch/mips/pci/fixup-pnx8550.c
new file mode 100644
index 000000000000..4256b3b30b77
--- /dev/null
+++ b/arch/mips/pci/fixup-pnx8550.c
@@ -0,0 +1,57 @@
+/*
+ * Philips PNX8550 pci fixups.
+ *
+ * Copyright 2005 Embedded Alley Solutions, Inc
+ * source@embeddealley.com
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ */
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include <asm/mach-pnx8550/pci.h>
+#include <asm/mach-pnx8550/int.h>
+
+
+#undef DEBUG
+#ifdef DEBUG
+#define DBG(x...) printk(x)
+#else
+#define DBG(x...)
+#endif
+
+extern char irq_tab_jbs[][5];
+
+void __init pcibios_fixup_resources(struct pci_dev *dev)
+{
+ /* no need to fixup IO resources */
+}
+
+void __init pcibios_fixup(void)
+{
+ /* nothing to do here */
+}
+
+int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+ return irq_tab_jbs[slot][pin];
+}
+
+/* Do platform specific device initialization at pci_enable_device() time */
+int pcibios_plat_dev_init(struct pci_dev *dev)
+{
+ return 0;
+}
diff --git a/arch/mips/pci/fixup-tx4938.c b/arch/mips/pci/fixup-tx4938.c
new file mode 100644
index 000000000000..f455520ada88
--- /dev/null
+++ b/arch/mips/pci/fixup-tx4938.c
@@ -0,0 +1,92 @@
+/*
+ * Toshiba rbtx4938 pci routines
+ * Copyright (C) 2000-2001 Toshiba Corporation
+ *
+ * 2003-2005 (c) MontaVista Software, Inc. This file is licensed under the
+ * terms of the GNU General Public License version 2. This program is
+ * licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ *
+ * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com)
+ */
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include <asm/tx4938/rbtx4938.h>
+
+extern struct pci_controller tx4938_pci_controller[];
+
+int pci_get_irq(struct pci_dev *dev, int pin)
+{
+ int irq = pin;
+ u8 slot = PCI_SLOT(dev->devfn);
+ struct pci_controller *controller = (struct pci_controller *)dev->sysdata;
+
+ if (controller == &tx4938_pci_controller[1]) {
+ /* TX4938 PCIC1 */
+ switch (slot) {
+ case TX4938_PCIC_IDSEL_AD_TO_SLOT(31):
+ if (tx4938_ccfgptr->pcfg & TX4938_PCFG_ETH0_SEL)
+ return RBTX4938_IRQ_IRC + TX4938_IR_ETH0;
+ break;
+ case TX4938_PCIC_IDSEL_AD_TO_SLOT(30):
+ if (tx4938_ccfgptr->pcfg & TX4938_PCFG_ETH1_SEL)
+ return RBTX4938_IRQ_IRC + TX4938_IR_ETH1;
+ break;
+ }
+ return 0;
+ }
+
+ /* IRQ rotation */
+ irq--; /* 0-3 */
+ if (dev->bus->parent == NULL &&
+ (slot == TX4938_PCIC_IDSEL_AD_TO_SLOT(23))) {
+ /* PCI CardSlot (IDSEL=A23) */
+ /* PCIA => PCIA (IDSEL=A23) */
+ irq = (irq + 0 + slot) % 4;
+ } else {
+ /* PCI Backplane */
+ irq = (irq + 33 - slot) % 4;
+ }
+ irq++; /* 1-4 */
+
+ switch (irq) {
+ case 1:
+ irq = RBTX4938_IRQ_IOC_PCIA;
+ break;
+ case 2:
+ irq = RBTX4938_IRQ_IOC_PCIB;
+ break;
+ case 3:
+ irq = RBTX4938_IRQ_IOC_PCIC;
+ break;
+ case 4:
+ irq = RBTX4938_IRQ_IOC_PCID;
+ break;
+ }
+ return irq;
+}
+
+int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+ unsigned char irq = 0;
+
+ irq = pci_get_irq(dev, pin);
+
+ printk(KERN_INFO "PCI: 0x%02x:0x%02x(0x%02x,0x%02x) IRQ=%d\n",
+ dev->bus->number, dev->devfn, PCI_SLOT(dev->devfn),
+ PCI_FUNC(dev->devfn), irq);
+
+ return irq;
+}
+
+/*
+ * Do platform specific device initialization at pci_enable_device() time
+ */
+int pcibios_plat_dev_init(struct pci_dev *dev)
+{
+ return 0;
+}
+
diff --git a/arch/mips/pci/ops-au1000.c b/arch/mips/pci/ops-au1000.c
index c1c91ca0f9c2..be1420126c42 100644
--- a/arch/mips/pci/ops-au1000.c
+++ b/arch/mips/pci/ops-au1000.c
@@ -50,11 +50,6 @@
int (*board_pci_idsel)(unsigned int devsel, int assert);
-/* CP0 hazard avoidance. */
-#define BARRIER __asm__ __volatile__(".set noreorder\n\t" \
- "nop; nop; nop; nop;\t" \
- ".set reorder\n\t")
-
void mod_wired_entry(int entry, unsigned long entrylo0,
unsigned long entrylo1, unsigned long entryhi,
unsigned long pagemask)
@@ -66,16 +61,12 @@ void mod_wired_entry(int entry, unsigned long entrylo0,
old_ctx = read_c0_entryhi() & 0xff;
old_pagemask = read_c0_pagemask();
write_c0_index(entry);
- BARRIER;
write_c0_pagemask(pagemask);
write_c0_entryhi(entryhi);
write_c0_entrylo0(entrylo0);
write_c0_entrylo1(entrylo1);
- BARRIER;
tlb_write_indexed();
- BARRIER;
write_c0_entryhi(old_ctx);
- BARRIER;
write_c0_pagemask(old_pagemask);
}
@@ -128,9 +119,8 @@ static int config_access(unsigned char access_type, struct pci_bus *bus,
last_entryLo0 = last_entryLo1 = 0xffffffff;
}
- /* Since the Au1xxx doesn't do the idsel timing exactly to spec,
- * many board vendors implement their own off-chip idsel, so call
- * it now. If it doesn't succeed, may as well bail out at this point.
+ /* Allow board vendors to implement their own off-chip idsel.
+ * If it doesn't succeed, may as well bail out at this point.
*/
if (board_pci_idsel) {
if (board_pci_idsel(device, 1) == 0) {
diff --git a/arch/mips/pci/ops-bonito64.c b/arch/mips/pci/ops-bonito64.c
index 4b4e086a7eb1..dc35270b65a2 100644
--- a/arch/mips/pci/ops-bonito64.c
+++ b/arch/mips/pci/ops-bonito64.c
@@ -1,6 +1,8 @@
/*
- * Carsten Langgaard, carstenl@mips.com
- * Copyright (C) 1999, 2000 MIPS Technologies, Inc. All rights reserved.
+ * Copyright (C) 1999, 2000, 2004 MIPS Technologies, Inc.
+ * All rights reserved.
+ * Authors: Carsten Langgaard <carstenl@mips.com>
+ * Maciej W. Rozycki <macro@mips.com>
*
* This program is free software; you can distribute it and/or modify it
* under the terms of the GNU General Public License (Version 2) as
@@ -17,7 +19,6 @@
*
* MIPS boards specific PCI support.
*/
-#include <linux/config.h>
#include <linux/types.h>
#include <linux/pci.h>
#include <linux/kernel.h>
@@ -57,13 +58,6 @@ static int bonito64_pcibios_config_access(unsigned char access_type,
return -1;
}
-#ifdef CONFIG_MIPS_BOARDS_GEN
- if ((busnum == 0) && (PCI_SLOT(devfn) == 17)) {
- /* MIPS Core boards have Bonito connected as device 17 */
- return -1;
- }
-#endif
-
/* Clear cause register bits */
BONITO_PCICMD |= (BONITO_PCICMD_MABORT_CLR |
BONITO_PCICMD_MTABORT_CLR);
diff --git a/arch/mips/pci/ops-gt64111.c b/arch/mips/pci/ops-gt64111.c
index c5b0fc184c2a..c1807934768d 100644
--- a/arch/mips/pci/ops-gt64111.c
+++ b/arch/mips/pci/ops-gt64111.c
@@ -18,15 +18,15 @@
#include <asm/cobalt/cobalt.h>
/*
- * Accessing device 31 hangs the GT64120. Not sure if this will also hang
- * the GT64111, let's be paranoid for now.
+ * Device 31 on the GT64111 is used to generate PCI special
+ * cycles, so we shouldn't expected to find a device there ...
*/
static inline int pci_range_ck(struct pci_bus *bus, unsigned int devfn)
{
- if (bus->number == 0 && devfn == PCI_DEVFN(31, 0))
- return -1;
+ if (bus->number == 0 && PCI_SLOT(devfn) < 31)
+ return 0;
- return 0;
+ return -1;
}
static int gt64111_pci_read_config(struct pci_bus *bus, unsigned int devfn,
diff --git a/arch/mips/pci/ops-gt64120.c b/arch/mips/pci/ops-gt64120.c
index 7b99dfa33dfc..6335844d607a 100644
--- a/arch/mips/pci/ops-gt64120.c
+++ b/arch/mips/pci/ops-gt64120.c
@@ -1,6 +1,8 @@
/*
- * Carsten Langgaard, carstenl@mips.com
- * Copyright (C) 1999, 2000 MIPS Technologies, Inc. All rights reserved.
+ * Copyright (C) 1999, 2000, 2004 MIPS Technologies, Inc.
+ * All rights reserved.
+ * Authors: Carsten Langgaard <carstenl@mips.com>
+ * Maciej W. Rozycki <macro@mips.com>
*
* This program is free software; you can distribute it and/or modify it
* under the terms of the GNU General Public License (Version 2) as
@@ -43,10 +45,6 @@ static int gt64120_pcibios_config_access(unsigned char access_type,
unsigned char busnum = bus->number;
u32 intr;
- if ((busnum == 0) && (PCI_SLOT(devfn) == 0))
- /* Galileo itself is devfn 0, don't move it around */
- return -1;
-
if ((busnum == 0) && (devfn >= PCI_DEVFN(31, 0)))
return -1; /* Because of a bug in the galileo (for slot 31). */
diff --git a/arch/mips/pci/ops-msc.c b/arch/mips/pci/ops-msc.c
index 7bc099643a9d..5d9fbb0f4670 100644
--- a/arch/mips/pci/ops-msc.c
+++ b/arch/mips/pci/ops-msc.c
@@ -21,7 +21,6 @@
* MIPS boards specific PCI support.
*
*/
-#include <linux/config.h>
#include <linux/types.h>
#include <linux/pci.h>
#include <linux/kernel.h>
@@ -49,34 +48,17 @@ static int msc_pcibios_config_access(unsigned char access_type,
struct pci_bus *bus, unsigned int devfn, int where, u32 * data)
{
unsigned char busnum = bus->number;
- unsigned char type;
u32 intr;
-#ifdef CONFIG_MIPS_BOARDS_GEN
- if ((busnum == 0) && (PCI_SLOT(devfn) == 17)) {
- /* MIPS Core boards have SOCit connected as device 17 */
- return -1;
- }
-#endif
-
/* Clear status register bits. */
MSC_WRITE(MSC01_PCI_INTSTAT,
(MSC01_PCI_INTCFG_MA_BIT | MSC01_PCI_INTCFG_TA_BIT));
- /* Setup address */
- if (busnum == 0)
- type = 0; /* Type 0 */
- else
- type = 1; /* Type 1 */
-
MSC_WRITE(MSC01_PCI_CFGADDR,
((busnum << MSC01_PCI_CFGADDR_BNUM_SHF) |
- (PCI_SLOT(devfn) << MSC01_PCI_CFGADDR_DNUM_SHF)
- | (PCI_FUNC(devfn) <<
- MSC01_PCI_CFGADDR_FNUM_SHF) | ((where /
- 4) <<
- MSC01_PCI_CFGADDR_RNUM_SHF)
- | (type)));
+ (PCI_SLOT(devfn) << MSC01_PCI_CFGADDR_DNUM_SHF) |
+ (PCI_FUNC(devfn) << MSC01_PCI_CFGADDR_FNUM_SHF) |
+ ((where / 4) << MSC01_PCI_CFGADDR_RNUM_SHF)));
/* Perform access */
if (access_type == PCI_ACCESS_WRITE)
@@ -86,15 +68,12 @@ static int msc_pcibios_config_access(unsigned char access_type,
/* Detect Master/Target abort */
MSC_READ(MSC01_PCI_INTSTAT, intr);
- if (intr & (MSC01_PCI_INTCFG_MA_BIT |
- MSC01_PCI_INTCFG_TA_BIT)) {
+ if (intr & (MSC01_PCI_INTCFG_MA_BIT | MSC01_PCI_INTCFG_TA_BIT)) {
/* Error occurred */
/* Clear bits */
- MSC_READ(MSC01_PCI_INTSTAT, intr);
MSC_WRITE(MSC01_PCI_INTSTAT,
- (MSC01_PCI_INTCFG_MA_BIT |
- MSC01_PCI_INTCFG_TA_BIT));
+ (MSC01_PCI_INTCFG_MA_BIT | MSC01_PCI_INTCFG_TA_BIT));
return -1;
}
diff --git a/arch/mips/pci/ops-nile4.c b/arch/mips/pci/ops-nile4.c
index a7169928b351..a8d38dc8c504 100644
--- a/arch/mips/pci/ops-nile4.c
+++ b/arch/mips/pci/ops-nile4.c
@@ -15,7 +15,7 @@
volatile unsigned long *const vrc_pciregs = (void *) Vrc5074_BASE;
-static spinlock_t nile4_pci_lock;
+static DEFINE_SPINLOCK(nile4_pci_lock);
static int nile4_pcibios_config_access(unsigned char access_type,
struct pci_bus *bus, unsigned int devfn, int where, u32 * val)
diff --git a/arch/mips/pci/ops-pnx8550.c b/arch/mips/pci/ops-pnx8550.c
new file mode 100644
index 000000000000..454b65cc3354
--- /dev/null
+++ b/arch/mips/pci/ops-pnx8550.c
@@ -0,0 +1,284 @@
+/*
+ *
+ * BRIEF MODULE DESCRIPTION
+ *
+ * 2.6 port, Embedded Alley Solutions, Inc
+ *
+ * Based on:
+ * Author: source@mvista.com
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ */
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/vmalloc.h>
+#include <linux/delay.h>
+
+#include <asm/mach-pnx8550/pci.h>
+#include <asm/mach-pnx8550/glb.h>
+#include <asm/debug.h>
+
+
+static inline void clear_status(void)
+{
+ unsigned long pci_stat;
+
+ pci_stat = inl(PCI_BASE | PCI_GPPM_STATUS);
+ outl(pci_stat, PCI_BASE | PCI_GPPM_ICLR);
+}
+
+static inline unsigned int
+calc_cfg_addr(struct pci_bus *bus, unsigned int devfn, int where)
+{
+ unsigned int addr;
+
+ addr = ((bus->number > 0) ? (((bus->number & 0xff) << PCI_CFG_BUS_SHIFT) | 1) : 0);
+ addr |= ((devfn & 0xff) << PCI_CFG_FUNC_SHIFT) | (where & 0xfc);
+
+ return addr;
+}
+
+static int
+config_access(unsigned int pci_cmd, struct pci_bus *bus, unsigned int devfn, int where, unsigned int pci_mode, unsigned int *val)
+{
+ unsigned int flags;
+ unsigned long loops = 0;
+ unsigned long ioaddr = calc_cfg_addr(bus, devfn, where);
+
+ local_irq_save(flags);
+ /*Clear pending interrupt status */
+ if (inl(PCI_BASE | PCI_GPPM_STATUS)) {
+ clear_status();
+ while (!(inl(PCI_BASE | PCI_GPPM_STATUS) == 0)) ;
+ }
+
+ outl(ioaddr, PCI_BASE | PCI_GPPM_ADDR);
+
+ if ((pci_cmd == PCI_CMD_IOW) || (pci_cmd == PCI_CMD_CONFIG_WRITE))
+ outl(*val, PCI_BASE | PCI_GPPM_WDAT);
+
+ outl(INIT_PCI_CYCLE | pci_cmd | (pci_mode & PCI_BYTE_ENABLE_MASK),
+ PCI_BASE | PCI_GPPM_CTRL);
+
+ loops =
+ ((loops_per_jiffy *
+ PCI_IO_JIFFIES_TIMEOUT) >> (PCI_IO_JIFFIES_SHIFT));
+ while (1) {
+ if (inl(PCI_BASE | PCI_GPPM_STATUS) & GPPM_DONE) {
+ if ((pci_cmd == PCI_CMD_IOR) ||
+ (pci_cmd == PCI_CMD_CONFIG_READ))
+ *val = inl(PCI_BASE | PCI_GPPM_RDAT);
+ clear_status();
+ local_irq_restore(flags);
+ return PCIBIOS_SUCCESSFUL;
+ } else if (inl(PCI_BASE | PCI_GPPM_STATUS) & GPPM_R_MABORT) {
+ break;
+ }
+
+ loops--;
+ if (loops == 0) {
+ printk("%s : Arbiter Locked.\n", __FUNCTION__);
+ }
+ }
+
+ clear_status();
+ if ((pci_cmd == PCI_CMD_IOR) || (pci_cmd == PCI_CMD_IOW)) {
+ printk("%s timeout (GPPM_CTRL=%X) ioaddr %lX pci_cmd %X\n",
+ __FUNCTION__, inl(PCI_BASE | PCI_GPPM_CTRL), ioaddr,
+ pci_cmd);
+ }
+
+ if ((pci_cmd == PCI_CMD_IOR) || (pci_cmd == PCI_CMD_CONFIG_READ))
+ *val = 0xffffffff;
+ local_irq_restore(flags);
+ return PCIBIOS_DEVICE_NOT_FOUND;
+}
+
+/*
+ * We can't address 8 and 16 bit words directly. Instead we have to
+ * read/write a 32bit word and mask/modify the data we actually want.
+ */
+static int
+read_config_byte(struct pci_bus *bus, unsigned int devfn, int where, u8 * val)
+{
+ unsigned int data = 0;
+ int err;
+
+ if (bus == 0)
+ return -1;
+
+ err = config_access(PCI_CMD_CONFIG_READ, bus, devfn, where, ~(1 << (where & 3)), &data);
+ switch (where & 0x03) {
+ case 0:
+ *val = (unsigned char)(data & 0x000000ff);
+ break;
+ case 1:
+ *val = (unsigned char)((data & 0x0000ff00) >> 8);
+ break;
+ case 2:
+ *val = (unsigned char)((data & 0x00ff0000) >> 16);
+ break;
+ case 3:
+ *val = (unsigned char)((data & 0xff000000) >> 24);
+ break;
+ }
+
+ return err;
+}
+
+static int
+read_config_word(struct pci_bus *bus, unsigned int devfn, int where, u16 * val)
+{
+ unsigned int data = 0;
+ int err;
+
+ if (bus == 0)
+ return -1;
+
+ if (where & 0x01)
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+
+ err = config_access(PCI_CMD_CONFIG_READ, bus, devfn, where, ~(3 << (where & 3)), &data);
+ switch (where & 0x02) {
+ case 0:
+ *val = (unsigned short)(data & 0x0000ffff);
+ break;
+ case 2:
+ *val = (unsigned short)((data & 0xffff0000) >> 16);
+ break;
+ }
+
+ return err;
+}
+
+static int
+read_config_dword(struct pci_bus *bus, unsigned int devfn, int where, u32 * val)
+{
+ int err;
+ if (bus == 0)
+ return -1;
+
+ if (where & 0x03)
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+
+ err = config_access(PCI_CMD_CONFIG_READ, bus, devfn, where, 0, val);
+
+ return err;
+}
+
+static int
+write_config_byte(struct pci_bus *bus, unsigned int devfn, int where, u8 val)
+{
+ unsigned int data = (unsigned int)val;
+ int err;
+
+ if (bus == 0)
+ return -1;
+
+ switch (where & 0x03) {
+ case 1:
+ data = (data << 8);
+ break;
+ case 2:
+ data = (data << 16);
+ break;
+ case 3:
+ data = (data << 24);
+ break;
+ default:
+ break;
+ }
+
+ err = config_access(PCI_CMD_CONFIG_READ, bus, devfn, where, ~(1 << (where & 3)), &data);
+
+ return err;
+}
+
+static int
+write_config_word(struct pci_bus *bus, unsigned int devfn, int where, u16 val)
+{
+ unsigned int data = (unsigned int)val;
+ int err;
+
+ if (bus == 0)
+ return -1;
+
+ if (where & 0x01)
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+
+ switch (where & 0x02) {
+ case 2:
+ data = (data << 16);
+ break;
+ default:
+ break;
+ }
+ err = config_access(PCI_CMD_CONFIG_WRITE, bus, devfn, where, ~(3 << (where & 3)), &data);
+
+ return err;
+}
+
+static int
+write_config_dword(struct pci_bus *bus, unsigned int devfn, int where, u32 val)
+{
+ int err;
+ if (bus == 0)
+ return -1;
+
+ if (where & 0x03)
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+
+ err = config_access(PCI_CMD_CONFIG_WRITE, bus, devfn, where, 0, &val);
+
+ return err;
+}
+
+static int config_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 * val)
+{
+ switch (size) {
+ case 1: {
+ u8 _val;
+ int rc = read_config_byte(bus, devfn, where, &_val);
+ *val = _val;
+ return rc;
+ }
+ case 2: {
+ u16 _val;
+ int rc = read_config_word(bus, devfn, where, &_val);
+ *val = _val;
+ return rc;
+ }
+ default:
+ return read_config_dword(bus, devfn, where, val);
+ }
+}
+
+static int config_write(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 val)
+{
+ switch (size) {
+ case 1:
+ return write_config_byte(bus, devfn, where, (u8) val);
+ case 2:
+ return write_config_word(bus, devfn, where, (u16) val);
+ default:
+ return write_config_dword(bus, devfn, where, val);
+ }
+}
+
+struct pci_ops pnx8550_pci_ops = {
+ config_read,
+ config_write
+};
diff --git a/arch/mips/pci/ops-tx4938.c b/arch/mips/pci/ops-tx4938.c
new file mode 100644
index 000000000000..4c0dcfce5297
--- /dev/null
+++ b/arch/mips/pci/ops-tx4938.c
@@ -0,0 +1,198 @@
+/*
+ * Define the pci_ops for the Toshiba rbtx4938
+ * Copyright (C) 2000-2001 Toshiba Corporation
+ *
+ * 2003-2005 (c) MontaVista Software, Inc. This file is licensed under the
+ * terms of the GNU General Public License version 2. This program is
+ * licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ *
+ * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com)
+ */
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include <asm/addrspace.h>
+#include <asm/tx4938/rbtx4938.h>
+
+/* initialize in setup */
+struct resource pci_io_resource = {
+ .name = "pci IO space",
+ .start = 0,
+ .end = 0,
+ .flags = IORESOURCE_IO
+};
+
+/* initialize in setup */
+struct resource pci_mem_resource = {
+ .name = "pci memory space",
+ .start = 0,
+ .end = 0,
+ .flags = IORESOURCE_MEM
+};
+
+struct resource tx4938_pcic1_pci_io_resource = {
+ .name = "PCI1 IO",
+ .start = 0,
+ .end = 0,
+ .flags = IORESOURCE_IO
+};
+struct resource tx4938_pcic1_pci_mem_resource = {
+ .name = "PCI1 mem",
+ .start = 0,
+ .end = 0,
+ .flags = IORESOURCE_MEM
+};
+
+static int mkaddr(int bus, int dev_fn, int where, int *flagsp)
+{
+ if (bus > 0) {
+ /* Type 1 configuration */
+ tx4938_pcicptr->g2pcfgadrs = ((bus & 0xff) << 0x10) |
+ ((dev_fn & 0xff) << 0x08) | (where & 0xfc) | 1;
+ } else {
+ if (dev_fn >= PCI_DEVFN(TX4938_PCIC_MAX_DEVNU, 0))
+ return -1;
+
+ /* Type 0 configuration */
+ tx4938_pcicptr->g2pcfgadrs = ((bus & 0xff) << 0x10) |
+ ((dev_fn & 0xff) << 0x08) | (where & 0xfc);
+ }
+ /* clear M_ABORT and Disable M_ABORT Int. */
+ tx4938_pcicptr->pcistatus =
+ (tx4938_pcicptr->pcistatus & 0x0000ffff) |
+ (PCI_STATUS_REC_MASTER_ABORT << 16);
+ tx4938_pcicptr->pcimask &= ~PCI_STATUS_REC_MASTER_ABORT;
+
+ return 0;
+}
+
+static int check_abort(int flags)
+{
+ int code = PCIBIOS_SUCCESSFUL;
+ /* wait write cycle completion before checking error status */
+ while (tx4938_pcicptr->pcicstatus & TX4938_PCIC_PCICSTATUS_IWB)
+ ;
+ if (tx4938_pcicptr->pcistatus & (PCI_STATUS_REC_MASTER_ABORT << 16)) {
+ tx4938_pcicptr->pcistatus =
+ (tx4938_pcicptr->
+ pcistatus & 0x0000ffff) | (PCI_STATUS_REC_MASTER_ABORT
+ << 16);
+ tx4938_pcicptr->pcimask |= PCI_STATUS_REC_MASTER_ABORT;
+ code = PCIBIOS_DEVICE_NOT_FOUND;
+ }
+ return code;
+}
+
+static int tx4938_pcibios_read_config(struct pci_bus *bus, unsigned int devfn,
+ int where, int size, u32 * val)
+{
+ int flags, retval, dev, busno, func;
+
+ dev = PCI_SLOT(devfn);
+ func = PCI_FUNC(devfn);
+
+ /* check if the bus is top-level */
+ if (bus->parent != NULL)
+ busno = bus->number;
+ else {
+ busno = 0;
+ }
+
+ if (mkaddr(busno, devfn, where, &flags))
+ return -1;
+
+ switch (size) {
+ case 1:
+ *val = *(volatile u8 *) ((ulong) & tx4938_pcicptr->g2pcfgdata |
+#ifdef __BIG_ENDIAN
+ ((where & 3) ^ 3));
+#else
+ (where & 3));
+#endif
+ break;
+ case 2:
+ *val = *(volatile u16 *) ((ulong) & tx4938_pcicptr->g2pcfgdata |
+#ifdef __BIG_ENDIAN
+ ((where & 3) ^ 2));
+#else
+ (where & 3));
+#endif
+ break;
+ case 4:
+ *val = tx4938_pcicptr->g2pcfgdata;
+ break;
+ }
+
+ retval = check_abort(flags);
+ if (retval == PCIBIOS_DEVICE_NOT_FOUND)
+ *val = 0xffffffff;
+
+ return retval;
+}
+
+static int tx4938_pcibios_write_config(struct pci_bus *bus, unsigned int devfn, int where,
+ int size, u32 val)
+{
+ int flags, dev, busno, func;
+
+ busno = bus->number;
+ dev = PCI_SLOT(devfn);
+ func = PCI_FUNC(devfn);
+
+ /* check if the bus is top-level */
+ if (bus->parent != NULL) {
+ busno = bus->number;
+ } else {
+ busno = 0;
+ }
+
+ if (mkaddr(busno, devfn, where, &flags))
+ return -1;
+
+ switch (size) {
+ case 1:
+ *(volatile u8 *) ((ulong) & tx4938_pcicptr->g2pcfgdata |
+#ifdef __BIG_ENDIAN
+ ((where & 3) ^ 3)) = val;
+#else
+ (where & 3)) = val;
+#endif
+ break;
+ case 2:
+ *(volatile u16 *) ((ulong) & tx4938_pcicptr->g2pcfgdata |
+#ifdef __BIG_ENDIAN
+ ((where & 0x3) ^ 0x2)) = val;
+#else
+ (where & 3)) = val;
+#endif
+ break;
+ case 4:
+ tx4938_pcicptr->g2pcfgdata = val;
+ break;
+ }
+
+ return check_abort(flags);
+}
+
+struct pci_ops tx4938_pci_ops = {
+ tx4938_pcibios_read_config,
+ tx4938_pcibios_write_config
+};
+
+struct pci_controller tx4938_pci_controller[] = {
+ /* h/w only supports devices 0x00 to 0x14 */
+ {
+ .pci_ops = &tx4938_pci_ops,
+ .io_resource = &pci_io_resource,
+ .mem_resource = &pci_mem_resource,
+ },
+ /* h/w only supports devices 0x00 to 0x14 */
+ {
+ .pci_ops = &tx4938_pci_ops,
+ .io_resource = &tx4938_pcic1_pci_io_resource,
+ .mem_resource = &tx4938_pcic1_pci_mem_resource,
+ }
+};
diff --git a/arch/mips/pci/pci-bcm1480.c b/arch/mips/pci/pci-bcm1480.c
new file mode 100644
index 000000000000..f194b4e4f86a
--- /dev/null
+++ b/arch/mips/pci/pci-bcm1480.c
@@ -0,0 +1,265 @@
+/*
+ * Copyright (C) 2001,2002,2005 Broadcom Corporation
+ * Copyright (C) 2004 by Ralf Baechle (ralf@linux-mips.org)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your 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.
+ */
+
+/*
+ * BCM1x80/1x55-specific PCI support
+ *
+ * This module provides the glue between Linux's PCI subsystem
+ * and the hardware. We basically provide glue for accessing
+ * configuration space, and set up the translation for I/O
+ * space accesses.
+ *
+ * To access configuration space, we use ioremap. In the 32-bit
+ * kernel, this consumes either 4 or 8 page table pages, and 16MB of
+ * kernel mapped memory. Hopefully neither of these should be a huge
+ * problem.
+ *
+ * XXX: AT THIS TIME, ONLY the NATIVE PCI-X INTERFACE IS SUPPORTED.
+ */
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/console.h>
+#include <linux/tty.h>
+
+#include <asm/sibyte/bcm1480_regs.h>
+#include <asm/sibyte/bcm1480_scd.h>
+#include <asm/sibyte/board.h>
+#include <asm/io.h>
+
+/*
+ * Macros for calculating offsets into config space given a device
+ * structure or dev/fun/reg
+ */
+#define CFGOFFSET(bus,devfn,where) (((bus)<<16)+((devfn)<<8)+(where))
+#define CFGADDR(bus,devfn,where) CFGOFFSET((bus)->number,(devfn),where)
+
+static void *cfg_space;
+
+#define PCI_BUS_ENABLED 1
+#define PCI_DEVICE_MODE 2
+
+static int bcm1480_bus_status = 0;
+
+#define PCI_BRIDGE_DEVICE 0
+
+/*
+ * Read/write 32-bit values in config space.
+ */
+static inline u32 READCFG32(u32 addr)
+{
+ return *(u32 *)(cfg_space + (addr&~3));
+}
+
+static inline void WRITECFG32(u32 addr, u32 data)
+{
+ *(u32 *)(cfg_space + (addr & ~3)) = data;
+}
+
+int pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+ return dev->irq;
+}
+
+/* Do platform specific device initialization at pci_enable_device() time */
+int pcibios_plat_dev_init(struct pci_dev *dev)
+{
+ return 0;
+}
+
+/*
+ * Some checks before doing config cycles:
+ * In PCI Device Mode, hide everything on bus 0 except the LDT host
+ * bridge. Otherwise, access is controlled by bridge MasterEn bits.
+ */
+static int bcm1480_pci_can_access(struct pci_bus *bus, int devfn)
+{
+ u32 devno;
+
+ if (!(bcm1480_bus_status & (PCI_BUS_ENABLED | PCI_DEVICE_MODE)))
+ return 0;
+
+ if (bus->number == 0) {
+ devno = PCI_SLOT(devfn);
+ if (bcm1480_bus_status & PCI_DEVICE_MODE)
+ return 0;
+ else
+ return 1;
+ } else
+ return 1;
+}
+
+/*
+ * Read/write access functions for various sizes of values
+ * in config space. Return all 1's for disallowed accesses
+ * for a kludgy but adequate simulation of master aborts.
+ */
+
+static int bcm1480_pcibios_read(struct pci_bus *bus, unsigned int devfn,
+ int where, int size, u32 * val)
+{
+ u32 data = 0;
+
+ if ((size == 2) && (where & 1))
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+ else if ((size == 4) && (where & 3))
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+
+ if (bcm1480_pci_can_access(bus, devfn))
+ data = READCFG32(CFGADDR(bus, devfn, where));
+ else
+ data = 0xFFFFFFFF;
+
+ if (size == 1)
+ *val = (data >> ((where & 3) << 3)) & 0xff;
+ else if (size == 2)
+ *val = (data >> ((where & 3) << 3)) & 0xffff;
+ else
+ *val = data;
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int bcm1480_pcibios_write(struct pci_bus *bus, unsigned int devfn,
+ int where, int size, u32 val)
+{
+ u32 cfgaddr = CFGADDR(bus, devfn, where);
+ u32 data = 0;
+
+ if ((size == 2) && (where & 1))
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+ else if ((size == 4) && (where & 3))
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+
+ if (!bcm1480_pci_can_access(bus, devfn))
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+
+ data = READCFG32(cfgaddr);
+
+ if (size == 1)
+ data = (data & ~(0xff << ((where & 3) << 3))) |
+ (val << ((where & 3) << 3));
+ else if (size == 2)
+ data = (data & ~(0xffff << ((where & 3) << 3))) |
+ (val << ((where & 3) << 3));
+ else
+ data = val;
+
+ WRITECFG32(cfgaddr, data);
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+struct pci_ops bcm1480_pci_ops = {
+ bcm1480_pcibios_read,
+ bcm1480_pcibios_write,
+};
+
+static struct resource bcm1480_mem_resource = {
+ .name = "BCM1480 PCI MEM",
+ .start = 0x30000000UL,
+ .end = 0x3fffffffUL,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct resource bcm1480_io_resource = {
+ .name = "BCM1480 PCI I/O",
+ .start = 0x2c000000UL,
+ .end = 0x2dffffffUL,
+ .flags = IORESOURCE_IO,
+};
+
+struct pci_controller bcm1480_controller = {
+ .pci_ops = &bcm1480_pci_ops,
+ .mem_resource = &bcm1480_mem_resource,
+ .io_resource = &bcm1480_io_resource,
+};
+
+
+static int __init bcm1480_pcibios_init(void)
+{
+ uint32_t cmdreg;
+ uint64_t reg;
+ extern int pci_probe_only;
+
+ /* CFE will assign PCI resources */
+ pci_probe_only = 1;
+
+ /* Avoid ISA compat ranges. */
+ PCIBIOS_MIN_IO = 0x00008000UL;
+ PCIBIOS_MIN_MEM = 0x01000000UL;
+
+ /* Set I/O resource limits. - unlimited for now to accomodate HT */
+ ioport_resource.end = 0xffffffffUL;
+ iomem_resource.end = 0xffffffffUL;
+
+ cfg_space = ioremap(A_BCM1480_PHYS_PCI_CFG_MATCH_BITS, 16*1024*1024);
+
+ /*
+ * See if the PCI bus has been configured by the firmware.
+ */
+ reg = *((volatile uint64_t *) IOADDR(A_SCD_SYSTEM_CFG));
+ if (!(reg & M_BCM1480_SYS_PCI_HOST)) {
+ bcm1480_bus_status |= PCI_DEVICE_MODE;
+ } else {
+ cmdreg = READCFG32(CFGOFFSET(0, PCI_DEVFN(PCI_BRIDGE_DEVICE, 0),
+ PCI_COMMAND));
+ if (!(cmdreg & PCI_COMMAND_MASTER)) {
+ printk
+ ("PCI: Skipping PCI probe. Bus is not initialized.\n");
+ iounmap(cfg_space);
+ return 1; /* XXX */
+ }
+ bcm1480_bus_status |= PCI_BUS_ENABLED;
+ }
+
+ /* turn on ExpMemEn */
+ cmdreg = READCFG32(CFGOFFSET(0, PCI_DEVFN(PCI_BRIDGE_DEVICE, 0), 0x40));
+ printk("PCIFeatureCtrl = %x\n", cmdreg);
+ WRITECFG32(CFGOFFSET(0, PCI_DEVFN(PCI_BRIDGE_DEVICE, 0), 0x40),
+ cmdreg | 0x10);
+ cmdreg = READCFG32(CFGOFFSET(0, PCI_DEVFN(PCI_BRIDGE_DEVICE, 0), 0x40));
+ printk("PCIFeatureCtrl = %x\n", cmdreg);
+
+ /*
+ * Establish mappings in KSEG2 (kernel virtual) to PCI I/O
+ * space. Use "match bytes" policy to make everything look
+ * little-endian. So, you need to also set
+ * CONFIG_SWAP_IO_SPACE, but this is the combination that
+ * works correctly with most of Linux's drivers.
+ * XXX ehs: Should this happen in PCI Device mode?
+ */
+
+ set_io_port_base((unsigned long)
+ ioremap(A_BCM1480_PHYS_PCI_IO_MATCH_BYTES, 65536));
+ isa_slot_offset = (unsigned long)
+ ioremap(A_BCM1480_PHYS_PCI_MEM_MATCH_BYTES, 1024*1024);
+
+ register_pci_controller(&bcm1480_controller);
+
+#ifdef CONFIG_VGA_CONSOLE
+ take_over_console(&vga_con,0,MAX_NR_CONSOLES-1,1);
+#endif
+ return 0;
+}
+
+arch_initcall(bcm1480_pcibios_init);
diff --git a/arch/mips/pci/pci-bcm1480ht.c b/arch/mips/pci/pci-bcm1480ht.c
new file mode 100644
index 000000000000..aca4a2e7a1c6
--- /dev/null
+++ b/arch/mips/pci/pci-bcm1480ht.c
@@ -0,0 +1,224 @@
+/*
+ * Copyright (C) 2001,2002,2005 Broadcom Corporation
+ * Copyright (C) 2004 by Ralf Baechle (ralf@linux-mips.org)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your 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.
+ */
+
+/*
+ * BCM1480/1455-specific HT support (looking like PCI)
+ *
+ * This module provides the glue between Linux's PCI subsystem
+ * and the hardware. We basically provide glue for accessing
+ * configuration space, and set up the translation for I/O
+ * space accesses.
+ *
+ * To access configuration space, we use ioremap. In the 32-bit
+ * kernel, this consumes either 4 or 8 page table pages, and 16MB of
+ * kernel mapped memory. Hopefully neither of these should be a huge
+ * problem.
+ *
+ */
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/console.h>
+#include <linux/tty.h>
+
+#include <asm/sibyte/bcm1480_regs.h>
+#include <asm/sibyte/bcm1480_scd.h>
+#include <asm/sibyte/board.h>
+#include <asm/io.h>
+
+/*
+ * Macros for calculating offsets into config space given a device
+ * structure or dev/fun/reg
+ */
+#define CFGOFFSET(bus,devfn,where) (((bus)<<16)+((devfn)<<8)+(where))
+#define CFGADDR(bus,devfn,where) CFGOFFSET((bus)->number,(devfn),where)
+
+static void *ht_cfg_space;
+
+#define PCI_BUS_ENABLED 1
+#define PCI_DEVICE_MODE 2
+
+static int bcm1480ht_bus_status = 0;
+
+#define PCI_BRIDGE_DEVICE 0
+#define HT_BRIDGE_DEVICE 1
+
+/*
+ * HT's level-sensitive interrupts require EOI, which is generated
+ * through a 4MB memory-mapped region
+ */
+unsigned long ht_eoi_space;
+
+/*
+ * Read/write 32-bit values in config space.
+ */
+static inline u32 READCFG32(u32 addr)
+{
+ return *(u32 *)(ht_cfg_space + (addr&~3));
+}
+
+static inline void WRITECFG32(u32 addr, u32 data)
+{
+ *(u32 *)(ht_cfg_space + (addr & ~3)) = data;
+}
+
+/*
+ * Some checks before doing config cycles:
+ * In PCI Device Mode, hide everything on bus 0 except the LDT host
+ * bridge. Otherwise, access is controlled by bridge MasterEn bits.
+ */
+static int bcm1480ht_can_access(struct pci_bus *bus, int devfn)
+{
+ u32 devno;
+
+ if (!(bcm1480ht_bus_status & (PCI_BUS_ENABLED | PCI_DEVICE_MODE)))
+ return 0;
+
+ if (bus->number == 0) {
+ devno = PCI_SLOT(devfn);
+ if (bcm1480ht_bus_status & PCI_DEVICE_MODE)
+ return 0;
+ }
+ return 1;
+}
+
+/*
+ * Read/write access functions for various sizes of values
+ * in config space. Return all 1's for disallowed accesses
+ * for a kludgy but adequate simulation of master aborts.
+ */
+
+static int bcm1480ht_pcibios_read(struct pci_bus *bus, unsigned int devfn,
+ int where, int size, u32 * val)
+{
+ u32 data = 0;
+
+ if ((size == 2) && (where & 1))
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+ else if ((size == 4) && (where & 3))
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+
+ if (bcm1480ht_can_access(bus, devfn))
+ data = READCFG32(CFGADDR(bus, devfn, where));
+ else
+ data = 0xFFFFFFFF;
+
+ if (size == 1)
+ *val = (data >> ((where & 3) << 3)) & 0xff;
+ else if (size == 2)
+ *val = (data >> ((where & 3) << 3)) & 0xffff;
+ else
+ *val = data;
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int bcm1480ht_pcibios_write(struct pci_bus *bus, unsigned int devfn,
+ int where, int size, u32 val)
+{
+ u32 cfgaddr = CFGADDR(bus, devfn, where);
+ u32 data = 0;
+
+ if ((size == 2) && (where & 1))
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+ else if ((size == 4) && (where & 3))
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+
+ if (!bcm1480ht_can_access(bus, devfn))
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+
+ data = READCFG32(cfgaddr);
+
+ if (size == 1)
+ data = (data & ~(0xff << ((where & 3) << 3))) |
+ (val << ((where & 3) << 3));
+ else if (size == 2)
+ data = (data & ~(0xffff << ((where & 3) << 3))) |
+ (val << ((where & 3) << 3));
+ else
+ data = val;
+
+ WRITECFG32(cfgaddr, data);
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int bcm1480ht_pcibios_get_busno(void)
+{
+ return 0;
+}
+
+struct pci_ops bcm1480ht_pci_ops = {
+ .read = bcm1480ht_pcibios_read,
+ .write = bcm1480ht_pcibios_write,
+};
+
+static struct resource bcm1480ht_mem_resource = {
+ .name = "BCM1480 HT MEM",
+ .start = 0x40000000UL,
+ .end = 0x5fffffffUL,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct resource bcm1480ht_io_resource = {
+ .name = "BCM1480 HT I/O",
+ .start = 0x00000000UL,
+ .end = 0x01ffffffUL,
+ .flags = IORESOURCE_IO,
+};
+
+struct pci_controller bcm1480ht_controller = {
+ .pci_ops = &bcm1480ht_pci_ops,
+ .mem_resource = &bcm1480ht_mem_resource,
+ .io_resource = &bcm1480ht_io_resource,
+ .index = 1,
+ .get_busno = bcm1480ht_pcibios_get_busno,
+};
+
+static int __init bcm1480ht_pcibios_init(void)
+{
+ uint32_t cmdreg;
+
+ ht_cfg_space = ioremap(A_BCM1480_PHYS_HT_CFG_MATCH_BITS, 16*1024*1024);
+
+ /*
+ * See if the PCI bus has been configured by the firmware.
+ */
+ cmdreg = READCFG32(CFGOFFSET(0, PCI_DEVFN(PCI_BRIDGE_DEVICE, 0),
+ PCI_COMMAND));
+ if (!(cmdreg & PCI_COMMAND_MASTER)) {
+ printk("HT: Skipping HT probe. Bus is not initialized.\n");
+ iounmap(ht_cfg_space);
+ return 1; /* XXX */
+ }
+ bcm1480ht_bus_status |= PCI_BUS_ENABLED;
+
+ ht_eoi_space = (unsigned long)
+ ioremap(A_BCM1480_PHYS_HT_SPECIAL_MATCH_BYTES,
+ 4 * 1024 * 1024);
+
+ register_pci_controller(&bcm1480ht_controller);
+
+ return 0;
+}
+
+arch_initcall(bcm1480ht_pcibios_init);
diff --git a/arch/mips/pci/pci-ip27.c b/arch/mips/pci/pci-ip27.c
index 068e0e508e15..efc96ce99eeb 100644
--- a/arch/mips/pci/pci-ip27.c
+++ b/arch/mips/pci/pci-ip27.c
@@ -485,5 +485,12 @@ static void __init pci_fixup_ioc3(struct pci_dev *d)
pci_disable_swapping(d);
}
+int pcibus_to_node(struct pci_bus *bus)
+{
+ struct bridge_controller *bc = BRIDGE_CONTROLLER(bus);
+
+ return bc->nasid;
+}
+
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SGI, PCI_DEVICE_ID_SGI_IOC3,
pci_fixup_ioc3);
diff --git a/arch/mips/pci/pci-ip32.c b/arch/mips/pci/pci-ip32.c
index 000dc6af6cd3..180af89bcb1e 100644
--- a/arch/mips/pci/pci-ip32.c
+++ b/arch/mips/pci/pci-ip32.c
@@ -136,7 +136,9 @@ static int __init mace_init(void)
BUG_ON(request_irq(MACE_PCI_BRIDGE_IRQ, macepci_error, 0,
"MACE PCI error", NULL));
- ioport_resource.end = mace_pci_io_resource.end;
+ iomem_resource = mace_pci_mem_resource;
+ ioport_resource = mace_pci_io_resource;
+
register_pci_controller(&mace_pci_controller);
return 0;
diff --git a/arch/mips/pci/pci-lasat.c b/arch/mips/pci/pci-lasat.c
index ae3cc4b254b5..88fb191ad2eb 100644
--- a/arch/mips/pci/pci-lasat.c
+++ b/arch/mips/pci/pci-lasat.c
@@ -7,12 +7,8 @@
*/
#include <linux/kernel.h>
#include <linux/init.h>
-#include <linux/interrupt.h>
#include <linux/pci.h>
#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/pci.h>
-#include <linux/delay.h>
#include <asm/bootinfo.h>
extern struct pci_ops nile4_pci_ops;
@@ -20,14 +16,14 @@ extern struct pci_ops gt64120_pci_ops;
static struct resource lasat_pci_mem_resource = {
.name = "LASAT PCI MEM",
.start = 0x18000000,
- .end = 0x19FFFFFF,
+ .end = 0x19ffffff,
.flags = IORESOURCE_MEM,
};
static struct resource lasat_pci_io_resource = {
.name = "LASAT PCI IO",
.start = 0x1a000000,
- .end = 0x1bFFFFFF,
+ .end = 0x1bffffff,
.flags = IORESOURCE_IO,
};
@@ -38,23 +34,25 @@ static struct pci_controller lasat_pci_controller = {
static int __init lasat_pci_setup(void)
{
- printk("PCI: starting\n");
+ printk("PCI: starting\n");
- switch (mips_machtype) {
- case MACH_LASAT_100:
+ switch (mips_machtype) {
+ case MACH_LASAT_100:
lasat_pci_controller.pci_ops = &gt64120_pci_ops;
break;
- case MACH_LASAT_200:
+ case MACH_LASAT_200:
lasat_pci_controller.pci_ops = &nile4_pci_ops;
break;
- default:
+ default:
panic("pcibios_init: mips_machtype incorrect");
}
register_pci_controller(&lasat_pci_controller);
- return 0;
+
+ return 0;
}
-early_initcall(lasat_pci_setup);
+
+arch_initcall(lasat_pci_setup);
#define LASATINT_ETH1 0
#define LASATINT_ETH0 1
@@ -68,24 +66,22 @@ early_initcall(lasat_pci_setup);
int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
{
- switch (slot) {
- case 1:
- return LASATINT_PCIA; /* Expansion Module 0 */
- case 2:
- return LASATINT_PCIB; /* Expansion Module 1 */
- case 3:
- return LASATINT_PCIC; /* Expansion Module 2 */
- case 4:
- return LASATINT_ETH1; /* Ethernet 1 (LAN 2) */
- case 5:
- return LASATINT_ETH0; /* Ethernet 0 (LAN 1) */
- case 6:
- return LASATINT_HDC; /* IDE controller */
- default:
- return 0xff; /* Illegal */
- }
+ switch (slot) {
+ case 1:
+ case 2:
+ case 3:
+ return LASATINT_PCIA + (((slot-1) + (pin-1)) % 4);
+ case 4:
+ return LASATINT_ETH1; /* Ethernet 1 (LAN 2) */
+ case 5:
+ return LASATINT_ETH0; /* Ethernet 0 (LAN 1) */
+ case 6:
+ return LASATINT_HDC; /* IDE controller */
+ default:
+ return 0xff; /* Illegal */
+ }
- return -1;
+ return -1;
}
/* Do platform specific device initialization at pci_enable_device() time */
diff --git a/arch/mips/pci/pci.c b/arch/mips/pci/pci.c
index a8d499b0a36f..21402ffd7c98 100644
--- a/arch/mips/pci/pci.c
+++ b/arch/mips/pci/pci.c
@@ -127,15 +127,20 @@ static int __init pcibios_init(void)
if (!hose->iommu)
PCI_DMA_BUS_IS_PHYS = 1;
+ if (hose->get_busno && pci_probe_only)
+ next_busno = (*hose->get_busno)();
+
bus = pci_scan_bus(next_busno, hose->pci_ops, hose);
hose->bus = bus;
hose->need_domain_info = need_domain_info;
- 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;
- need_domain_info = 1;
+ 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;
+ need_domain_info = 1;
+ }
}
continue;
@@ -164,7 +169,7 @@ static int pcibios_enable_resources(struct pci_dev *dev, int mask)
pci_read_config_word(dev, PCI_COMMAND, &cmd);
old_cmd = cmd;
- for(idx=0; idx<6; idx++) {
+ for (idx=0; idx < PCI_NUM_RESOURCES; idx++) {
/* Only set up the requested stuff */
if (!(mask & (1<<idx)))
continue;
diff --git a/arch/mips/philips/pnx8550/common/Kconfig b/arch/mips/philips/pnx8550/common/Kconfig
new file mode 100644
index 000000000000..072572d173cc
--- /dev/null
+++ b/arch/mips/philips/pnx8550/common/Kconfig
@@ -0,0 +1 @@
+# Place holder
diff --git a/arch/mips/philips/pnx8550/common/Makefile b/arch/mips/philips/pnx8550/common/Makefile
new file mode 100644
index 000000000000..6e38f3bc443c
--- /dev/null
+++ b/arch/mips/philips/pnx8550/common/Makefile
@@ -0,0 +1,27 @@
+#
+# Per Hallsmark, per.hallsmark@mvista.com
+#
+# ########################################################################
+#
+# This program is free software; you can distribute it and/or modify it
+# under the terms of the GNU General Public License (Version 2) as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+#
+# #######################################################################
+#
+# Makefile for the PNX8550 specific kernel interface routines
+# under Linux.
+#
+
+obj-y := setup.o prom.o mipsIRQ.o int.o reset.o time.o proc.o platform.o
+obj-$(CONFIG_PCI) += pci.o
+obj-$(CONFIG_KGDB) += gdb_hook.o
diff --git a/arch/mips/philips/pnx8550/common/gdb_hook.c b/arch/mips/philips/pnx8550/common/gdb_hook.c
new file mode 100644
index 000000000000..ad4624f6d9bc
--- /dev/null
+++ b/arch/mips/philips/pnx8550/common/gdb_hook.c
@@ -0,0 +1,109 @@
+/*
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved.
+ *
+ * ########################################################################
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ *
+ * This is the interface to the remote debugger stub.
+ *
+ */
+#include <linux/types.h>
+#include <linux/serial.h>
+#include <linux/serialP.h>
+#include <linux/serial_reg.h>
+#include <linux/serial_ip3106.h>
+
+#include <asm/serial.h>
+#include <asm/io.h>
+
+#include <uart.h>
+
+static struct serial_state rs_table[IP3106_NR_PORTS] = {
+};
+static struct async_struct kdb_port_info = {0};
+
+void rs_kgdb_hook(int tty_no)
+{
+ struct serial_state *ser = &rs_table[tty_no];
+
+ kdb_port_info.state = ser;
+ kdb_port_info.magic = SERIAL_MAGIC;
+ kdb_port_info.port = tty_no;
+ kdb_port_info.flags = ser->flags;
+
+ /*
+ * Clear all interrupts
+ */
+ /* Clear all the transmitter FIFO counters (pointer and status) */
+ ip3106_lcr(UART_BASE, tty_no) |= IP3106_UART_LCR_TX_RST;
+ /* Clear all the receiver FIFO counters (pointer and status) */
+ ip3106_lcr(UART_BASE, tty_no) |= IP3106_UART_LCR_RX_RST;
+ /* Clear all interrupts */
+ ip3106_iclr(UART_BASE, tty_no) = IP3106_UART_INT_ALLRX |
+ IP3106_UART_INT_ALLTX;
+
+ /*
+ * Now, initialize the UART
+ */
+ ip3106_lcr(UART_BASE, tty_no) = IP3106_UART_LCR_8BIT;
+ ip3106_baud(UART_BASE, tty_no) = 5; // 38400 Baud
+}
+
+int putDebugChar(char c)
+{
+ /* Wait until FIFO not full */
+ while (((ip3106_fifo(UART_BASE, kdb_port_info.port) & IP3106_UART_FIFO_TXFIFO) >> 16) >= 16)
+ ;
+ /* Send one char */
+ ip3106_fifo(UART_BASE, kdb_port_info.port) = c;
+
+ return 1;
+}
+
+char getDebugChar(void)
+{
+ char ch;
+
+ /* Wait until there is a char in the FIFO */
+ while (!((ip3106_fifo(UART_BASE, kdb_port_info.port) &
+ IP3106_UART_FIFO_RXFIFO) >> 8))
+ ;
+ /* Read one char */
+ ch = ip3106_fifo(UART_BASE, kdb_port_info.port) &
+ IP3106_UART_FIFO_RBRTHR;
+ /* Advance the RX FIFO read pointer */
+ ip3106_lcr(UART_BASE, kdb_port_info.port) |= IP3106_UART_LCR_RX_NEXT;
+ return (ch);
+}
+
+void rs_disable_debug_interrupts(void)
+{
+ ip3106_ien(UART_BASE, kdb_port_info.port) = 0; /* Disable all interrupts */
+}
+
+void rs_enable_debug_interrupts(void)
+{
+ /* Clear all the transmitter FIFO counters (pointer and status) */
+ ip3106_lcr(UART_BASE, kdb_port_info.port) |= IP3106_UART_LCR_TX_RST;
+ /* Clear all the receiver FIFO counters (pointer and status) */
+ ip3106_lcr(UART_BASE, kdb_port_info.port) |= IP3106_UART_LCR_RX_RST;
+ /* Clear all interrupts */
+ ip3106_iclr(UART_BASE, kdb_port_info.port) = IP3106_UART_INT_ALLRX |
+ IP3106_UART_INT_ALLTX;
+ ip3106_ien(UART_BASE, kdb_port_info.port) = IP3106_UART_INT_ALLRX; /* Enable RX interrupts */
+}
diff --git a/arch/mips/philips/pnx8550/common/int.c b/arch/mips/philips/pnx8550/common/int.c
new file mode 100644
index 000000000000..546144988bf5
--- /dev/null
+++ b/arch/mips/philips/pnx8550/common/int.c
@@ -0,0 +1,293 @@
+/*
+ *
+ * Copyright (C) 2005 Embedded Alley Solutions, Inc
+ * Ported to 2.6.
+ *
+ * Per Hallsmark, per.hallsmark@mvista.com
+ * Copyright (C) 2000, 2001 MIPS Technologies, Inc.
+ * Copyright (C) 2001 Ralf Baechle
+ *
+ * Cleaned up and bug fixing: Pete Popov, ppopov@embeddedalley.com
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/kernel_stat.h>
+#include <linux/random.h>
+#include <linux/module.h>
+
+#include <asm/io.h>
+#include <asm/gdb-stub.h>
+#include <int.h>
+#include <uart.h>
+
+extern asmlinkage void cp0_irqdispatch(void);
+
+static DEFINE_SPINLOCK(irq_lock);
+
+/* default prio for interrupts */
+/* first one is a no-no so therefore always prio 0 (disabled) */
+static char gic_prio[PNX8550_INT_GIC_TOTINT] = {
+ 0, 1, 1, 1, 1, 15, 1, 1, 1, 1, // 0 - 9
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 10 - 19
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 20 - 29
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 30 - 39
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 40 - 49
+ 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, // 50 - 59
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 60 - 69
+ 1 // 70
+};
+
+void hw0_irqdispatch(int irq, struct pt_regs *regs)
+{
+ /* find out which interrupt */
+ irq = PNX8550_GIC_VECTOR_0 >> 3;
+
+ if (irq == 0) {
+ printk("hw0_irqdispatch: irq 0, spurious interrupt?\n");
+ return;
+ }
+ do_IRQ(PNX8550_INT_GIC_MIN + irq, regs);
+}
+
+
+void timer_irqdispatch(int irq, struct pt_regs *regs)
+{
+ irq = (0x01c0 & read_c0_config7()) >> 6;
+
+ if (irq == 0) {
+ printk("timer_irqdispatch: irq 0, spurious interrupt?\n");
+ return;
+ }
+
+ if (irq & 0x1) {
+ do_IRQ(PNX8550_INT_TIMER1, regs);
+ }
+ if (irq & 0x2) {
+ do_IRQ(PNX8550_INT_TIMER2, regs);
+ }
+ if (irq & 0x4) {
+ do_IRQ(PNX8550_INT_TIMER3, regs);
+ }
+}
+
+static inline void modify_cp0_intmask(unsigned clr_mask, unsigned set_mask)
+{
+ unsigned long status = read_c0_status();
+
+ status &= ~((clr_mask & 0xFF) << 8);
+ status |= (set_mask & 0xFF) << 8;
+
+ write_c0_status(status);
+}
+
+static inline void mask_gic_int(unsigned int irq_nr)
+{
+ /* interrupt disabled, bit 26(WE_ENABLE)=1 and bit 16(enable)=0 */
+ PNX8550_GIC_REQ(irq_nr) = 1<<28; /* set priority to 0 */
+}
+
+static inline void unmask_gic_int(unsigned int irq_nr)
+{
+ /* set prio mask to lower four bits and enable interrupt */
+ PNX8550_GIC_REQ(irq_nr) = (1<<26 | 1<<16) | (1<<28) | gic_prio[irq_nr];
+}
+
+static inline void mask_irq(unsigned int irq_nr)
+{
+ if ((PNX8550_INT_CP0_MIN <= irq_nr) && (irq_nr <= PNX8550_INT_CP0_MAX)) {
+ modify_cp0_intmask(1 << irq_nr, 0);
+ } else if ((PNX8550_INT_GIC_MIN <= irq_nr) &&
+ (irq_nr <= PNX8550_INT_GIC_MAX)) {
+ mask_gic_int(irq_nr - PNX8550_INT_GIC_MIN);
+ } else if ((PNX8550_INT_TIMER_MIN <= irq_nr) &&
+ (irq_nr <= PNX8550_INT_TIMER_MAX)) {
+ modify_cp0_intmask(1 << 7, 0);
+ } else {
+ printk("mask_irq: irq %d doesn't exist!\n", irq_nr);
+ }
+}
+
+static inline void unmask_irq(unsigned int irq_nr)
+{
+ if ((PNX8550_INT_CP0_MIN <= irq_nr) && (irq_nr <= PNX8550_INT_CP0_MAX)) {
+ modify_cp0_intmask(0, 1 << irq_nr);
+ } else if ((PNX8550_INT_GIC_MIN <= irq_nr) &&
+ (irq_nr <= PNX8550_INT_GIC_MAX)) {
+ unmask_gic_int(irq_nr - PNX8550_INT_GIC_MIN);
+ } else if ((PNX8550_INT_TIMER_MIN <= irq_nr) &&
+ (irq_nr <= PNX8550_INT_TIMER_MAX)) {
+ modify_cp0_intmask(0, 1 << 7);
+ } else {
+ printk("mask_irq: irq %d doesn't exist!\n", irq_nr);
+ }
+}
+
+#define pnx8550_disable pnx8550_ack
+static void pnx8550_ack(unsigned int irq)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&irq_lock, flags);
+ mask_irq(irq);
+ spin_unlock_irqrestore(&irq_lock, flags);
+}
+
+#define pnx8550_enable pnx8550_unmask
+static void pnx8550_unmask(unsigned int irq)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&irq_lock, flags);
+ unmask_irq(irq);
+ spin_unlock_irqrestore(&irq_lock, flags);
+}
+
+static unsigned int startup_irq(unsigned int irq_nr)
+{
+ pnx8550_unmask(irq_nr);
+ return 0;
+}
+
+static void shutdown_irq(unsigned int irq_nr)
+{
+ pnx8550_ack(irq_nr);
+ return;
+}
+
+int pnx8550_set_gic_priority(int irq, int priority)
+{
+ int gic_irq = irq-PNX8550_INT_GIC_MIN;
+ int prev_priority = PNX8550_GIC_REQ(gic_irq) & 0xf;
+
+ gic_prio[gic_irq] = priority;
+ PNX8550_GIC_REQ(gic_irq) |= (0x10000000 | gic_prio[gic_irq]);
+
+ return prev_priority;
+}
+
+static inline void mask_and_ack_level_irq(unsigned int irq)
+{
+ pnx8550_disable(irq);
+ return;
+}
+
+static void end_irq(unsigned int irq)
+{
+ if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) {
+ pnx8550_enable(irq);
+ }
+}
+
+static struct hw_interrupt_type level_irq_type = {
+ .typename = "PNX Level IRQ",
+ .startup = startup_irq,
+ .shutdown = shutdown_irq,
+ .enable = pnx8550_enable,
+ .disable = pnx8550_disable,
+ .ack = mask_and_ack_level_irq,
+ .end = end_irq,
+};
+
+static struct irqaction gic_action = {
+ .handler = no_action,
+ .flags = SA_INTERRUPT,
+ .name = "GIC",
+};
+
+static struct irqaction timer_action = {
+ .handler = no_action,
+ .flags = SA_INTERRUPT,
+ .name = "Timer",
+};
+
+void __init arch_init_irq(void)
+{
+ int i;
+ int configPR;
+
+ /* init of cp0 interrupts */
+ set_except_vector(0, cp0_irqdispatch);
+
+ for (i = 0; i < PNX8550_INT_CP0_TOTINT; i++) {
+ irq_desc[i].handler = &level_irq_type;
+ pnx8550_ack(i); /* mask the irq just in case */
+ }
+
+ /* init of GIC/IPC interrupts */
+ /* should be done before cp0 since cp0 init enables the GIC int */
+ for (i = PNX8550_INT_GIC_MIN; i <= PNX8550_INT_GIC_MAX; i++) {
+ int gic_int_line = i - PNX8550_INT_GIC_MIN;
+ if (gic_int_line == 0 )
+ continue; // don't fiddle with int 0
+ /*
+ * enable change of TARGET, ENABLE and ACTIVE_LOW bits
+ * set TARGET 0 to route through hw0 interrupt
+ * set ACTIVE_LOW 0 active high (correct?)
+ *
+ * We really should setup an interrupt description table
+ * to do this nicely.
+ * Note, PCI INTA is active low on the bus, but inverted
+ * in the GIC, so to us it's active high.
+ */
+#ifdef CONFIG_PNX8550_V2PCI
+ if (gic_int_line == (PNX8550_INT_GPIO0 - PNX8550_INT_GIC_MIN)) {
+ /* PCI INT through gpio 8, which is setup in
+ * pnx8550_setup.c and routed to GPIO
+ * Interrupt Level 0 (GPIO Connection 58).
+ * Set it active low. */
+
+ PNX8550_GIC_REQ(gic_int_line) = 0x1E020000;
+ } else
+#endif
+ {
+ PNX8550_GIC_REQ(i - PNX8550_INT_GIC_MIN) = 0x1E000000;
+ }
+
+ /* mask/priority is still 0 so we will not get any
+ * interrupts until it is unmasked */
+
+ irq_desc[i].handler = &level_irq_type;
+ }
+
+ /* Priority level 0 */
+ PNX8550_GIC_PRIMASK_0 = PNX8550_GIC_PRIMASK_1 = 0;
+
+ /* Set int vector table address */
+ PNX8550_GIC_VECTOR_0 = PNX8550_GIC_VECTOR_1 = 0;
+
+ irq_desc[MIPS_CPU_GIC_IRQ].handler = &level_irq_type;
+ setup_irq(MIPS_CPU_GIC_IRQ, &gic_action);
+
+ /* init of Timer interrupts */
+ for (i = PNX8550_INT_TIMER_MIN; i <= PNX8550_INT_TIMER_MAX; i++) {
+ irq_desc[i].handler = &level_irq_type;
+ }
+
+ /* Stop Timer 1-3 */
+ configPR = read_c0_config7();
+ configPR |= 0x00000038;
+ write_c0_config7(configPR);
+
+ irq_desc[MIPS_CPU_TIMER_IRQ].handler = &level_irq_type;
+ setup_irq(MIPS_CPU_TIMER_IRQ, &timer_action);
+}
+
+EXPORT_SYMBOL(pnx8550_set_gic_priority);
diff --git a/arch/mips/philips/pnx8550/common/mipsIRQ.S b/arch/mips/philips/pnx8550/common/mipsIRQ.S
new file mode 100644
index 000000000000..338bffda3fab
--- /dev/null
+++ b/arch/mips/philips/pnx8550/common/mipsIRQ.S
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2002 Philips, Inc. All rights.
+ * Copyright (c) 2002 Red Hat, Inc. All rights.
+ *
+ * This software may be freely redistributed under the terms of the
+ * GNU General Public License.
+ *
+ * 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.
+ *
+ * Based upon arch/mips/galileo-boards/ev64240/int-handler.S
+ *
+ */
+#include <asm/asm.h>
+#include <asm/mipsregs.h>
+#include <asm/addrspace.h>
+#include <asm/regdef.h>
+#include <asm/stackframe.h>
+
+/*
+ * cp0_irqdispatch
+ *
+ * Code to handle in-core interrupt exception.
+ */
+
+ .align 5
+ .set reorder
+ .set noat
+ NESTED(cp0_irqdispatch, PT_SIZE, sp)
+ SAVE_ALL
+ CLI
+ .set at
+ mfc0 t0,CP0_CAUSE
+ mfc0 t2,CP0_STATUS
+
+ and t0,t2
+
+ andi t1,t0,STATUSF_IP2 /* int0 hardware line */
+ bnez t1,ll_hw0_irq
+ nop
+
+ andi t1,t0,STATUSF_IP7 /* int5 hardware line */
+ bnez t1,ll_timer_irq
+ nop
+
+ /* wrong alarm or masked ... */
+
+ j spurious_interrupt
+ nop
+ END(cp0_irqdispatch)
+
+ .align 5
+ .set reorder
+ll_hw0_irq:
+ li a0,2
+ move a1,sp
+ jal hw0_irqdispatch
+ nop
+ j ret_from_irq
+ nop
+
+ .align 5
+ .set reorder
+ll_timer_irq:
+ mfc0 t3,CP0_CONFIG,7
+ andi t4,t3,0x01c0
+ beqz t4,ll_timer_out
+ nop
+ li a0,7
+ move a1,sp
+ jal timer_irqdispatch
+ nop
+
+ll_timer_out: j ret_from_irq
+ nop
diff --git a/arch/mips/philips/pnx8550/common/pci.c b/arch/mips/philips/pnx8550/common/pci.c
new file mode 100644
index 000000000000..baa6905f649f
--- /dev/null
+++ b/arch/mips/philips/pnx8550/common/pci.c
@@ -0,0 +1,133 @@
+/*
+ *
+ * BRIEF MODULE DESCRIPTION
+ *
+ * Author: source@mvista.com
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ */
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include <pci.h>
+#include <glb.h>
+#include <nand.h>
+
+static struct resource pci_io_resource = {
+ "pci IO space",
+ (u32)(PNX8550_PCIIO + 0x1000), /* reserve regacy I/O space */
+ (u32)(PNX8550_PCIIO + PNX8550_PCIIO_SIZE),
+ IORESOURCE_IO
+};
+
+static struct resource pci_mem_resource = {
+ "pci memory space",
+ (u32)(PNX8550_PCIMEM),
+ (u32)(PNX8550_PCIMEM + PNX8550_PCIMEM_SIZE - 1),
+ IORESOURCE_MEM
+};
+
+extern struct pci_ops pnx8550_pci_ops;
+
+static struct pci_controller pnx8550_controller = {
+ .pci_ops = &pnx8550_pci_ops,
+ .io_resource = &pci_io_resource,
+ .mem_resource = &pci_mem_resource,
+};
+
+/* Return the total size of DRAM-memory, (RANK0 + RANK1) */
+static inline unsigned long get_system_mem_size(void)
+{
+ /* Read IP2031_RANK0_ADDR_LO */
+ unsigned long dram_r0_lo = inl(PCI_BASE | 0x65010);
+ /* Read IP2031_RANK1_ADDR_HI */
+ unsigned long dram_r1_hi = inl(PCI_BASE | 0x65018);
+
+ return dram_r1_hi - dram_r0_lo + 1;
+}
+
+static int __init pnx8550_pci_setup(void)
+{
+ int pci_mem_code;
+ int mem_size = get_system_mem_size() >> 20;
+
+ /* Clear the Global 2 Register, PCI Inta Output Enable Registers
+ Bit 1:Enable DAC Powerdown
+ -> 0:DACs are enabled and are working normally
+ 1:DACs are powerdown
+ Bit 0:Enable of PCI inta output
+ -> 0 = Disable PCI inta output
+ 1 = Enable PCI inta output
+ */
+ PNX8550_GLB2_ENAB_INTA_O = 0;
+
+ /* Calc the PCI mem size code */
+ if (mem_size >= 128)
+ pci_mem_code = SIZE_128M;
+ else if (mem_size >= 64)
+ pci_mem_code = SIZE_64M;
+ else if (mem_size >= 32)
+ pci_mem_code = SIZE_32M;
+ else
+ pci_mem_code = SIZE_16M;
+
+ /* Set PCI_XIO registers */
+ outl(pci_mem_resource.start, PCI_BASE | PCI_BASE1_LO);
+ outl(pci_mem_resource.end + 1, PCI_BASE | PCI_BASE1_HI);
+ outl(pci_io_resource.start, PCI_BASE | PCI_BASE2_LO);
+ outl(pci_io_resource.end, PCI_BASE | PCI_BASE2_HI);
+
+ /* Send memory transaction via PCI_BASE2 */
+ outl(0x00000001, PCI_BASE | PCI_IO);
+
+ /* Unlock the setup register */
+ outl(0xca, PCI_BASE | PCI_UNLOCKREG);
+
+ /*
+ * BAR0 of PNX8550 (pci base 10) must be zero in order for ide
+ * to work, and in order for bus_to_baddr to work without any
+ * hacks.
+ */
+ outl(0x00000000, PCI_BASE | PCI_BASE10);
+
+ /*
+ *These two bars are set by default or the boot code.
+ * However, it's safer to set them here so we're not boot
+ * code dependent.
+ */
+ outl(0x1be00000, PCI_BASE | PCI_BASE14); /* PNX MMIO */
+ outl(PNX8550_NAND_BASE_ADDR, PCI_BASE | PCI_BASE18); /* XIO */
+
+ outl(PCI_EN_TA |
+ PCI_EN_PCI2MMI |
+ PCI_EN_XIO |
+ PCI_SETUP_BASE18_SIZE(SIZE_32M) |
+ PCI_SETUP_BASE18_EN |
+ PCI_SETUP_BASE14_EN |
+ PCI_SETUP_BASE10_PREF |
+ PCI_SETUP_BASE10_SIZE(pci_mem_code) |
+ PCI_SETUP_CFGMANAGE_EN |
+ PCI_SETUP_PCIARB_EN,
+ PCI_BASE |
+ PCI_SETUP); /* PCI_SETUP */
+ outl(0x00000000, PCI_BASE | PCI_CTRL); /* PCI_CONTROL */
+
+ register_pci_controller(&pnx8550_controller);
+
+ return 0;
+}
+
+arch_initcall(pnx8550_pci_setup);
diff --git a/arch/mips/philips/pnx8550/common/platform.c b/arch/mips/philips/pnx8550/common/platform.c
new file mode 100644
index 000000000000..8aa9bd65b45e
--- /dev/null
+++ b/arch/mips/philips/pnx8550/common/platform.c
@@ -0,0 +1,135 @@
+/*
+ * Platform device support for Philips PNX8550 SoCs
+ *
+ * Copyright 2005, Embedded Alley Solutions, Inc
+ *
+ * Based on arch/mips/au1000/common/platform.c
+ * Platform device support for Au1x00 SoCs.
+ *
+ * Copyright 2004, Matt Porter <mporter@kernel.crashing.org>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/resource.h>
+#include <linux/serial.h>
+#include <linux/serial_ip3106.h>
+
+#include <int.h>
+#include <usb.h>
+#include <uart.h>
+
+extern struct uart_ops ip3106_pops;
+
+static struct resource pnx8550_usb_ohci_resources[] = {
+ [0] = {
+ .start = PNX8550_USB_OHCI_OP_BASE,
+ .end = PNX8550_USB_OHCI_OP_BASE +
+ PNX8550_USB_OHCI_OP_LEN,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = PNX8550_INT_USB,
+ .end = PNX8550_INT_USB,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct resource pnx8550_uart_resources[] = {
+ [0] = {
+ .start = PNX8550_UART_PORT0,
+ .end = PNX8550_UART_PORT0 + 0xfff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = PNX8550_UART_INT(0),
+ .end = PNX8550_UART_INT(0),
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = PNX8550_UART_PORT1,
+ .end = PNX8550_UART_PORT1 + 0xfff,
+ .flags = IORESOURCE_MEM,
+ },
+ [3] = {
+ .start = PNX8550_UART_INT(1),
+ .end = PNX8550_UART_INT(1),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct ip3106_port ip3106_ports[] = {
+ [0] = {
+ .port = {
+ .type = PORT_IP3106,
+ .iotype = SERIAL_IO_MEM,
+ .membase = (void __iomem *)PNX8550_UART_PORT0,
+ .mapbase = PNX8550_UART_PORT0,
+ .irq = PNX8550_UART_INT(0),
+ .uartclk = 3692300,
+ .fifosize = 16,
+ .ops = &ip3106_pops,
+ .flags = ASYNC_BOOT_AUTOCONF,
+ .line = 0,
+ },
+ },
+ [1] = {
+ .port = {
+ .type = PORT_IP3106,
+ .iotype = SERIAL_IO_MEM,
+ .membase = (void __iomem *)PNX8550_UART_PORT1,
+ .mapbase = PNX8550_UART_PORT1,
+ .irq = PNX8550_UART_INT(1),
+ .uartclk = 3692300,
+ .fifosize = 16,
+ .ops = &ip3106_pops,
+ .flags = ASYNC_BOOT_AUTOCONF,
+ .line = 1,
+ },
+ },
+};
+
+/* The dmamask must be set for OHCI to work */
+static u64 ohci_dmamask = ~(u32)0;
+
+static u64 uart_dmamask = ~(u32)0;
+
+static struct platform_device pnx8550_usb_ohci_device = {
+ .name = "pnx8550-ohci",
+ .id = -1,
+ .dev = {
+ .dma_mask = &ohci_dmamask,
+ .coherent_dma_mask = 0xffffffff,
+ },
+ .num_resources = ARRAY_SIZE(pnx8550_usb_ohci_resources),
+ .resource = pnx8550_usb_ohci_resources,
+};
+
+static struct platform_device pnx8550_uart_device = {
+ .name = "ip3106-uart",
+ .id = -1,
+ .dev = {
+ .dma_mask = &uart_dmamask,
+ .coherent_dma_mask = 0xffffffff,
+ .platform_data = ip3106_ports,
+ },
+ .num_resources = ARRAY_SIZE(pnx8550_uart_resources),
+ .resource = pnx8550_uart_resources,
+};
+
+static struct platform_device *pnx8550_platform_devices[] __initdata = {
+ &pnx8550_usb_ohci_device,
+ &pnx8550_uart_device,
+};
+
+int pnx8550_platform_init(void)
+{
+ return platform_add_devices(pnx8550_platform_devices,
+ ARRAY_SIZE(pnx8550_platform_devices));
+}
+
+arch_initcall(pnx8550_platform_init);
diff --git a/arch/mips/philips/pnx8550/common/proc.c b/arch/mips/philips/pnx8550/common/proc.c
new file mode 100644
index 000000000000..72a016767e09
--- /dev/null
+++ b/arch/mips/philips/pnx8550/common/proc.c
@@ -0,0 +1,113 @@
+/*
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ */
+#include <linux/init.h>
+#include <linux/proc_fs.h>
+#include <linux/irq.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/kernel_stat.h>
+#include <linux/random.h>
+
+#include <asm/io.h>
+#include <asm/gdb-stub.h>
+#include <int.h>
+#include <uart.h>
+
+
+static int pnx8550_timers_read (char* page, char** start, off_t offset, int count, int* eof, void* data)
+{
+ int len = 0;
+ int configPR = read_c0_config7();
+
+ if (offset==0) {
+ len += sprintf(&page[len],"Timer: count, compare, tc, status\n");
+ len += sprintf(&page[len]," 1: %11i, %8i, %1i, %s\n",
+ read_c0_count(), read_c0_compare(),
+ (configPR>>6)&0x1, ((configPR>>3)&0x1)? "off":"on");
+ len += sprintf(&page[len]," 2: %11i, %8i, %1i, %s\n",
+ read_c0_count2(), read_c0_compare2(),
+ (configPR>>7)&0x1, ((configPR>>4)&0x1)? "off":"on");
+ len += sprintf(&page[len]," 3: %11i, %8i, %1i, %s\n",
+ read_c0_count3(), read_c0_compare3(),
+ (configPR>>8)&0x1, ((configPR>>5)&0x1)? "off":"on");
+ }
+
+ return len;
+}
+
+static int pnx8550_registers_read (char* page, char** start, off_t offset, int count, int* eof, void* data)
+{
+ int len = 0;
+
+ if (offset==0) {
+ len += sprintf(&page[len],"config1: %#10.8x\n",read_c0_config1());
+ len += sprintf(&page[len],"config2: %#10.8x\n",read_c0_config2());
+ len += sprintf(&page[len],"config3: %#10.8x\n",read_c0_config3());
+ len += sprintf(&page[len],"configPR: %#10.8x\n",read_c0_config7());
+ len += sprintf(&page[len],"status: %#10.8x\n",read_c0_status());
+ len += sprintf(&page[len],"cause: %#10.8x\n",read_c0_cause());
+ len += sprintf(&page[len],"count: %#10.8x\n",read_c0_count());
+ len += sprintf(&page[len],"count_2: %#10.8x\n",read_c0_count2());
+ len += sprintf(&page[len],"count_3: %#10.8x\n",read_c0_count3());
+ len += sprintf(&page[len],"compare: %#10.8x\n",read_c0_compare());
+ len += sprintf(&page[len],"compare_2: %#10.8x\n",read_c0_compare2());
+ len += sprintf(&page[len],"compare_3: %#10.8x\n",read_c0_compare3());
+ }
+
+ return len;
+}
+
+static struct proc_dir_entry* pnx8550_dir = NULL;
+static struct proc_dir_entry* pnx8550_timers = NULL;
+static struct proc_dir_entry* pnx8550_registers = NULL;
+
+static int pnx8550_proc_init( void )
+{
+
+ // Create /proc/pnx8550
+ pnx8550_dir = create_proc_entry("pnx8550", S_IFDIR|S_IRUGO, NULL);
+ if (pnx8550_dir){
+ pnx8550_dir->nlink = 1;
+ }
+ else {
+ printk(KERN_ERR "Can't create pnx8550 proc dir\n");
+ return -1;
+ }
+
+ // Create /proc/pnx8550/timers
+ pnx8550_timers = create_proc_entry("timers", S_IFREG|S_IRUGO, pnx8550_dir );
+ if (pnx8550_timers){
+ pnx8550_timers->nlink = 1;
+ pnx8550_timers->read_proc = pnx8550_timers_read;
+ }
+ else {
+ printk(KERN_ERR "Can't create pnx8550 timers proc file\n");
+ }
+
+ // Create /proc/pnx8550/registers
+ pnx8550_registers = create_proc_entry("registers", S_IFREG|S_IRUGO, pnx8550_dir );
+ if (pnx8550_registers){
+ pnx8550_registers->nlink = 1;
+ pnx8550_registers->read_proc = pnx8550_registers_read;
+ }
+ else {
+ printk(KERN_ERR "Can't create pnx8550 registers proc file\n");
+ }
+
+ return 0;
+}
+
+__initcall(pnx8550_proc_init);
diff --git a/arch/mips/philips/pnx8550/common/prom.c b/arch/mips/philips/pnx8550/common/prom.c
new file mode 100644
index 000000000000..70aac9759412
--- /dev/null
+++ b/arch/mips/philips/pnx8550/common/prom.c
@@ -0,0 +1,138 @@
+/*
+ *
+ * Per Hallsmark, per.hallsmark@mvista.com
+ *
+ * Based on jmr3927/common/prom.c
+ *
+ * 2004 (c) MontaVista Software, Inc. This file is licensed under the
+ * terms of the GNU General Public License version 2. This program is
+ * licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/string.h>
+#include <linux/serial_ip3106.h>
+
+#include <asm/bootinfo.h>
+#include <uart.h>
+
+/* #define DEBUG_CMDLINE */
+
+extern int prom_argc;
+extern char **prom_argv, **prom_envp;
+
+typedef struct
+{
+ char *name;
+/* char *val; */
+}t_env_var;
+
+
+char * prom_getcmdline(void)
+{
+ return &(arcs_cmdline[0]);
+}
+
+void prom_init_cmdline(void)
+{
+ char *cp;
+ int actr;
+
+ actr = 1; /* Always ignore argv[0] */
+
+ cp = &(arcs_cmdline[0]);
+ while(actr < prom_argc) {
+ strcpy(cp, prom_argv[actr]);
+ cp += strlen(prom_argv[actr]);
+ *cp++ = ' ';
+ actr++;
+ }
+ if (cp != &(arcs_cmdline[0])) /* get rid of trailing space */
+ --cp;
+ *cp = '\0';
+}
+
+char *prom_getenv(char *envname)
+{
+ /*
+ * Return a pointer to the given environment variable.
+ * Environment variables are stored in the form of "memsize=64".
+ */
+
+ t_env_var *env = (t_env_var *)prom_envp;
+ int i;
+
+ i = strlen(envname);
+
+ while(env->name) {
+ if(strncmp(envname, env->name, i) == 0) {
+ return(env->name + strlen(envname) + 1);
+ }
+ env++;
+ }
+ return(NULL);
+}
+
+inline unsigned char str2hexnum(unsigned char c)
+{
+ if(c >= '0' && c <= '9')
+ return c - '0';
+ if(c >= 'a' && c <= 'f')
+ return c - 'a' + 10;
+ if(c >= 'A' && c <= 'F')
+ return c - 'A' + 10;
+ return 0; /* foo */
+}
+
+inline void str2eaddr(unsigned char *ea, unsigned char *str)
+{
+ int i;
+
+ for(i = 0; i < 6; i++) {
+ unsigned char num;
+
+ if((*str == '.') || (*str == ':'))
+ str++;
+ num = str2hexnum(*str++) << 4;
+ num |= (str2hexnum(*str++));
+ ea[i] = num;
+ }
+}
+
+int get_ethernet_addr(char *ethernet_addr)
+{
+ char *ethaddr_str;
+
+ ethaddr_str = prom_getenv("ethaddr");
+ if (!ethaddr_str) {
+ printk("ethaddr not set in boot prom\n");
+ return -1;
+ }
+ str2eaddr(ethernet_addr, ethaddr_str);
+ return 0;
+}
+
+unsigned long __init prom_free_prom_memory(void)
+{
+ return 0;
+}
+
+extern int pnx8550_console_port;
+
+/* used by prom_printf */
+void prom_putchar(char c)
+{
+ if (pnx8550_console_port != -1) {
+ /* Wait until FIFO not full */
+ while( ((ip3106_fifo(UART_BASE, pnx8550_console_port) & IP3106_UART_FIFO_TXFIFO) >> 16) >= 16)
+ ;
+ /* Send one char */
+ ip3106_fifo(UART_BASE, pnx8550_console_port) = c;
+ }
+}
+
+EXPORT_SYMBOL(prom_getcmdline);
+EXPORT_SYMBOL(get_ethernet_addr);
+EXPORT_SYMBOL(str2eaddr);
diff --git a/arch/mips/philips/pnx8550/common/reset.c b/arch/mips/philips/pnx8550/common/reset.c
new file mode 100644
index 000000000000..7b2cbc5b2c7c
--- /dev/null
+++ b/arch/mips/philips/pnx8550/common/reset.c
@@ -0,0 +1,49 @@
+/*.
+ *
+ * ########################################################################
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ *
+ * Reset the PNX8550 board.
+ *
+ */
+#include <linux/slab.h>
+#include <asm/reboot.h>
+#include <glb.h>
+
+void pnx8550_machine_restart(char *command)
+{
+ char head[] = "************* Machine restart *************";
+ char foot[] = "*******************************************";
+
+ printk("\n\n");
+ printk("%s\n", head);
+ if (command != NULL)
+ printk("* %s\n", command);
+ printk("%s\n", foot);
+
+ PNX8550_RST_CTL = PNX8550_RST_DO_SW_RST;
+}
+
+void pnx8550_machine_halt(void)
+{
+ printk("*** Machine halt. (Not implemented) ***\n");
+}
+
+void pnx8550_machine_power_off(void)
+{
+ printk("*** Machine power off. (Not implemented) ***\n");
+}
diff --git a/arch/mips/philips/pnx8550/common/setup.c b/arch/mips/philips/pnx8550/common/setup.c
new file mode 100644
index 000000000000..ee6bf72094f6
--- /dev/null
+++ b/arch/mips/philips/pnx8550/common/setup.c
@@ -0,0 +1,149 @@
+/*
+ *
+ * 2.6 port, Embedded Alley Solutions, Inc
+ *
+ * Based on Per Hallsmark, per.hallsmark@mvista.com
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/ioport.h>
+#include <linux/mm.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/serial_ip3106.h>
+
+#include <asm/cpu.h>
+#include <asm/bootinfo.h>
+#include <asm/irq.h>
+#include <asm/mipsregs.h>
+#include <asm/reboot.h>
+#include <asm/pgtable.h>
+#include <asm/time.h>
+
+#include <glb.h>
+#include <int.h>
+#include <pci.h>
+#include <uart.h>
+#include <nand.h>
+
+extern void prom_printf(char *fmt, ...);
+
+extern void __init board_setup(void);
+extern void pnx8550_machine_restart(char *);
+extern void pnx8550_machine_halt(void);
+extern void pnx8550_machine_power_off(void);
+extern struct resource ioport_resource;
+extern struct resource iomem_resource;
+extern void (*board_time_init)(void);
+extern void pnx8550_time_init(void);
+extern void (*board_timer_setup)(struct irqaction *irq);
+extern void pnx8550_timer_setup(struct irqaction *irq);
+extern void rs_kgdb_hook(int tty_no);
+extern void prom_printf(char *fmt, ...);
+extern char *prom_getcmdline(void);
+
+struct resource standard_io_resources[] = {
+ {"dma1", 0x00, 0x1f, IORESOURCE_BUSY},
+ {"timer", 0x40, 0x5f, IORESOURCE_BUSY},
+ {"dma page reg", 0x80, 0x8f, IORESOURCE_BUSY},
+ {"dma2", 0xc0, 0xdf, IORESOURCE_BUSY},
+};
+
+#define STANDARD_IO_RESOURCES (sizeof(standard_io_resources)/sizeof(struct resource))
+
+extern struct resource pci_io_resource;
+extern struct resource pci_mem_resource;
+
+/* Return the total size of DRAM-memory, (RANK0 + RANK1) */
+unsigned long get_system_mem_size(void)
+{
+ /* Read IP2031_RANK0_ADDR_LO */
+ unsigned long dram_r0_lo = inl(PCI_BASE | 0x65010);
+ /* Read IP2031_RANK1_ADDR_HI */
+ unsigned long dram_r1_hi = inl(PCI_BASE | 0x65018);
+
+ return dram_r1_hi - dram_r0_lo + 1;
+}
+
+int pnx8550_console_port = -1;
+
+void __init plat_setup(void)
+{
+ int i;
+ char* argptr;
+
+ board_setup(); /* board specific setup */
+
+ _machine_restart = pnx8550_machine_restart;
+ _machine_halt = pnx8550_machine_halt;
+ _machine_power_off = pnx8550_machine_power_off;
+
+ board_time_init = pnx8550_time_init;
+ board_timer_setup = pnx8550_timer_setup;
+
+ /* Clear the Global 2 Register, PCI Inta Output Enable Registers
+ Bit 1:Enable DAC Powerdown
+ -> 0:DACs are enabled and are working normally
+ 1:DACs are powerdown
+ Bit 0:Enable of PCI inta output
+ -> 0 = Disable PCI inta output
+ 1 = Enable PCI inta output
+ */
+ PNX8550_GLB2_ENAB_INTA_O = 0;
+
+ /* IO/MEM resources. */
+ set_io_port_base(KSEG1);
+ ioport_resource.start = 0;
+ ioport_resource.end = ~0;
+ iomem_resource.start = 0;
+ iomem_resource.end = ~0;
+
+ /* Request I/O space for devices on this board */
+ for (i = 0; i < STANDARD_IO_RESOURCES; i++)
+ request_resource(&ioport_resource, standard_io_resources + i);
+
+ /* Place the Mode Control bit for GPIO pin 16 in primary function */
+ /* Pin 16 is used by UART1, UA1_TX */
+ outl((PNX8550_GPIO_MODE_PRIMOP << PNX8550_GPIO_MC_16_BIT) |
+ (PNX8550_GPIO_MODE_PRIMOP << PNX8550_GPIO_MC_17_BIT),
+ PNX8550_GPIO_MC1);
+
+ argptr = prom_getcmdline();
+ if ((argptr = strstr(argptr, "console=ttyS")) != NULL) {
+ argptr += strlen("console=ttyS");
+ pnx8550_console_port = *argptr == '0' ? 0 : 1;
+
+ /* We must initialize the UART (console) before prom_printf */
+ /* Set LCR to 8-bit and BAUD to 38400 (no 5) */
+ ip3106_lcr(UART_BASE, pnx8550_console_port) =
+ IP3106_UART_LCR_8BIT;
+ ip3106_baud(UART_BASE, pnx8550_console_port) = 5;
+ }
+
+#ifdef CONFIG_KGDB
+ argptr = prom_getcmdline();
+ if ((argptr = strstr(argptr, "kgdb=ttyS")) != NULL) {
+ int line;
+ argptr += strlen("kgdb=ttyS");
+ line = *argptr == '0' ? 0 : 1;
+ rs_kgdb_hook(line);
+ prom_printf("KGDB: Using ttyS%i for session, "
+ "please connect your debugger\n", line ? 1 : 0);
+ }
+#endif
+ return;
+}
diff --git a/arch/mips/philips/pnx8550/common/time.c b/arch/mips/philips/pnx8550/common/time.c
new file mode 100644
index 000000000000..70664ea96b92
--- /dev/null
+++ b/arch/mips/philips/pnx8550/common/time.c
@@ -0,0 +1,105 @@
+/*
+ * Copyright 2001, 2002, 2003 MontaVista Software Inc.
+ * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
+ *
+ * Common time service routines for MIPS machines. See
+ * Documents/MIPS/README.txt.
+ *
+ * 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/types.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/param.h>
+#include <linux/time.h>
+#include <linux/timer.h>
+#include <linux/smp.h>
+#include <linux/kernel_stat.h>
+#include <linux/spinlock.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+
+#include <asm/bootinfo.h>
+#include <asm/cpu.h>
+#include <asm/time.h>
+#include <asm/hardirq.h>
+#include <asm/div64.h>
+#include <asm/debug.h>
+
+#include <int.h>
+#include <cm.h>
+
+extern unsigned int mips_hpt_frequency;
+
+/*
+ * pnx8550_time_init() - it does the following things:
+ *
+ * 1) board_time_init() -
+ * a) (optional) set up RTC routines,
+ * b) (optional) calibrate and set the mips_hpt_frequency
+ * (only needed if you intended to use fixed_rate_gettimeoffset
+ * or use cpu counter as timer interrupt source)
+ */
+
+void pnx8550_time_init(void)
+{
+ unsigned int n;
+ unsigned int m;
+ unsigned int p;
+ unsigned int pow2p;
+
+ /* PLL0 sets MIPS clock (PLL1 <=> TM1, PLL6 <=> TM2, PLL5 <=> mem) */
+ /* (but only if CLK_MIPS_CTL select value [bits 3:1] is 1: FIXME) */
+
+ n = (PNX8550_CM_PLL0_CTL & PNX8550_CM_PLL_N_MASK) >> 16;
+ m = (PNX8550_CM_PLL0_CTL & PNX8550_CM_PLL_M_MASK) >> 8;
+ p = (PNX8550_CM_PLL0_CTL & PNX8550_CM_PLL_P_MASK) >> 2;
+ pow2p = (1 << p);
+
+ db_assert(m != 0 && pow2p != 0);
+
+ /*
+ * Compute the frequency as in the PNX8550 User Manual 1.0, p.186
+ * (a.k.a. 8-10). Divide by HZ for a timer offset that results in
+ * HZ timer interrupts per second.
+ */
+ mips_hpt_frequency = 27UL * ((1000000UL * n)/(m * pow2p));
+}
+
+/*
+ * pnx8550_timer_setup() - it does the following things:
+ *
+ * 5) board_timer_setup() -
+ * a) (optional) over-write any choices made above by time_init().
+ * b) machine specific code should setup the timer irqaction.
+ * c) enable the timer interrupt
+ */
+
+void __init pnx8550_timer_setup(struct irqaction *irq)
+{
+ int configPR;
+
+ setup_irq(PNX8550_INT_TIMER1, irq);
+
+ /* Start timer1 */
+ configPR = read_c0_config7();
+ configPR &= ~0x00000008;
+ write_c0_config7(configPR);
+
+ /* Timer 2 stop */
+ configPR = read_c0_config7();
+ configPR |= 0x00000010;
+ write_c0_config7(configPR);
+
+ write_c0_count2(0);
+ write_c0_compare2(0xffffffff);
+
+ /* Timer 3 stop */
+ configPR = read_c0_config7();
+ configPR |= 0x00000020;
+ write_c0_config7(configPR);
+}
diff --git a/arch/mips/philips/pnx8550/jbs/Makefile b/arch/mips/philips/pnx8550/jbs/Makefile
new file mode 100644
index 000000000000..e8228dbca8f6
--- /dev/null
+++ b/arch/mips/philips/pnx8550/jbs/Makefile
@@ -0,0 +1,4 @@
+
+# Makefile for the Philips JBS Board.
+
+lib-y := init.o board_setup.o irqmap.o
diff --git a/arch/mips/philips/pnx8550/jbs/board_setup.c b/arch/mips/philips/pnx8550/jbs/board_setup.c
new file mode 100644
index 000000000000..f92826e0096d
--- /dev/null
+++ b/arch/mips/philips/pnx8550/jbs/board_setup.c
@@ -0,0 +1,65 @@
+/*
+ * JBS Specific board startup routines.
+ *
+ * Copyright 2005, 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/ioport.h>
+#include <linux/mm.h>
+#include <linux/console.h>
+#include <linux/mc146818rtc.h>
+#include <linux/delay.h>
+
+#include <asm/cpu.h>
+#include <asm/bootinfo.h>
+#include <asm/irq.h>
+#include <asm/mipsregs.h>
+#include <asm/reboot.h>
+#include <asm/pgtable.h>
+
+#include <glb.h>
+
+/* CP0 hazard avoidance. */
+#define BARRIER __asm__ __volatile__(".set noreorder\n\t" \
+ "nop; nop; nop; nop; nop; nop;\n\t" \
+ ".set reorder\n\t")
+
+void __init board_setup(void)
+{
+ unsigned long config0, configpr;
+
+ config0 = read_c0_config();
+
+ /* clear all three cache coherency fields */
+ config0 &= ~(0x7 | (7<<25) | (7<<28));
+ config0 |= (CONF_CM_DEFAULT | (CONF_CM_DEFAULT<<25) |
+ (CONF_CM_DEFAULT<<28));
+ write_c0_config(config0);
+ BARRIER;
+
+ configpr = read_c0_config7();
+ configpr |= (1<<19); /* enable tlb */
+ write_c0_config7(configpr);
+ BARRIER;
+}
diff --git a/arch/mips/philips/pnx8550/jbs/init.c b/arch/mips/philips/pnx8550/jbs/init.c
new file mode 100644
index 000000000000..85f449174bc3
--- /dev/null
+++ b/arch/mips/philips/pnx8550/jbs/init.c
@@ -0,0 +1,57 @@
+/*
+ *
+ * Copyright 2005 Embedded Alley Solutions, Inc
+ * source@embeddedalley.com
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/bootmem.h>
+#include <asm/addrspace.h>
+#include <asm/bootinfo.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
+
+int prom_argc;
+char **prom_argv, **prom_envp;
+extern void __init prom_init_cmdline(void);
+extern char *prom_getenv(char *envname);
+
+const char *get_system_type(void)
+{
+ return "Philips PNX8550/JBS";
+}
+
+void __init prom_init(void)
+{
+
+ unsigned long memsize;
+
+ mips_machgroup = MACH_GROUP_PHILIPS;
+ mips_machtype = MACH_PHILIPS_JBS;
+
+ //memsize = 0x02800000; /* Trimedia uses memory above */
+ memsize = 0x08000000; /* Trimedia uses memory above */
+ add_memory_region(0, memsize, BOOT_MEM_RAM);
+}
diff --git a/arch/mips/philips/pnx8550/jbs/irqmap.c b/arch/mips/philips/pnx8550/jbs/irqmap.c
new file mode 100644
index 000000000000..f78e0423dc98
--- /dev/null
+++ b/arch/mips/philips/pnx8550/jbs/irqmap.c
@@ -0,0 +1,36 @@
+/*
+ * Philips JBS board irqmap.
+ *
+ * Copyright 2005 Embedded Alley Solutions, Inc
+ * source@embeddealley.com
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/init.h>
+#include <int.h>
+
+char irq_tab_jbs[][5] __initdata = {
+ [8] = { -1, PNX8550_INT_PCI_INTA, 0xff, 0xff, 0xff},
+ [9] = { -1, PNX8550_INT_PCI_INTA, 0xff, 0xff, 0xff},
+ [17] = { -1, PNX8550_INT_PCI_INTA, 0xff, 0xff, 0xff},
+};
+
diff --git a/arch/mips/pmc-sierra/Kconfig b/arch/mips/pmc-sierra/Kconfig
new file mode 100644
index 000000000000..24d514c9dff9
--- /dev/null
+++ b/arch/mips/pmc-sierra/Kconfig
@@ -0,0 +1,3 @@
+config HYPERTRANSPORT
+ bool "Hypertransport Support for PMC-Sierra Yosemite"
+ depends on PMC_YOSEMITE
diff --git a/arch/mips/pmc-sierra/yosemite/atmel_read_eeprom.h b/arch/mips/pmc-sierra/yosemite/atmel_read_eeprom.h
index c19f01a32045..a31288335fba 100644
--- a/arch/mips/pmc-sierra/yosemite/atmel_read_eeprom.h
+++ b/arch/mips/pmc-sierra/yosemite/atmel_read_eeprom.h
@@ -34,7 +34,6 @@
#include <linux/pci.h>
#include <linux/kernel.h>
#include <linux/slab.h>
-#include <linux/version.h>
#include <asm/pci.h>
#include <asm/io.h>
#include <linux/init.h>
diff --git a/arch/mips/pmc-sierra/yosemite/ht-irq.c b/arch/mips/pmc-sierra/yosemite/ht-irq.c
index d22c9ffe4914..5aec4057314e 100644
--- a/arch/mips/pmc-sierra/yosemite/ht-irq.c
+++ b/arch/mips/pmc-sierra/yosemite/ht-irq.c
@@ -26,7 +26,6 @@
#include <linux/types.h>
#include <linux/pci.h>
#include <linux/kernel.h>
-#include <linux/version.h>
#include <linux/init.h>
#include <asm/pci.h>
diff --git a/arch/mips/pmc-sierra/yosemite/ht.c b/arch/mips/pmc-sierra/yosemite/ht.c
index dad228d3a220..54b65a80abf5 100644
--- a/arch/mips/pmc-sierra/yosemite/ht.c
+++ b/arch/mips/pmc-sierra/yosemite/ht.c
@@ -28,7 +28,6 @@
#include <linux/pci.h>
#include <linux/kernel.h>
#include <linux/slab.h>
-#include <linux/version.h>
#include <asm/pci.h>
#include <asm/io.h>
diff --git a/arch/mips/pmc-sierra/yosemite/prom.c b/arch/mips/pmc-sierra/yosemite/prom.c
index 1fb3e697948d..555bfacf7647 100644
--- a/arch/mips/pmc-sierra/yosemite/prom.c
+++ b/arch/mips/pmc-sierra/yosemite/prom.c
@@ -132,8 +132,9 @@ void __init prom_init(void)
prom_grab_secondary();
}
-void __init prom_free_prom_memory(void)
+unsigned long __init prom_free_prom_memory(void)
{
+ return 0;
}
void __init prom_fixup_mem_map(unsigned long start, unsigned long end)
diff --git a/arch/mips/pmc-sierra/yosemite/setup.c b/arch/mips/pmc-sierra/yosemite/setup.c
index 7225bbf20ce4..059755b5ed57 100644
--- a/arch/mips/pmc-sierra/yosemite/setup.c
+++ b/arch/mips/pmc-sierra/yosemite/setup.c
@@ -73,7 +73,9 @@ void __init bus_error_init(void)
unsigned long m48t37y_get_time(void)
{
unsigned int year, month, day, hour, min, sec;
+ unsigned long flags;
+ spin_lock_irqsave(&rtc_lock, flags);
/* Stop the update to the time */
m48t37_base->control = 0x40;
@@ -88,6 +90,7 @@ unsigned long m48t37y_get_time(void)
/* Start the update to the time again */
m48t37_base->control = 0x00;
+ spin_unlock_irqrestore(&rtc_lock, flags);
return mktime(year, month, day, hour, min, sec);
}
@@ -95,11 +98,13 @@ unsigned long m48t37y_get_time(void)
int m48t37y_set_time(unsigned long sec)
{
struct rtc_time tm;
+ unsigned long flags;
/* convert to a more useful format -- note months count from 0 */
to_tm(sec, &tm);
tm.tm_mon += 1;
+ spin_lock_irqsave(&rtc_lock, flags);
/* enable writing */
m48t37_base->control = 0x80;
@@ -123,6 +128,7 @@ int m48t37y_set_time(unsigned long sec)
/* disable writing */
m48t37_base->control = 0x00;
+ spin_unlock_irqrestore(&rtc_lock, flags);
return 0;
}
@@ -212,7 +218,7 @@ static void __init py_late_time_init(void)
py_rtc_setup();
}
-static int __init pmc_yosemite_setup(void)
+void __init plat_setup(void)
{
board_time_init = yosemite_time_init;
late_time_init = py_late_time_init;
@@ -228,8 +234,4 @@ static int __init pmc_yosemite_setup(void)
OCD_WRITE(RM9000x2_OCD_HTBAR0, HYPERTRANSPORT_BAR0_ADDR);
OCD_WRITE(RM9000x2_OCD_HTMASK0, HYPERTRANSPORT_SIZE0);
#endif
-
- return 0;
}
-
-early_initcall(pmc_yosemite_setup);
diff --git a/arch/mips/pmc-sierra/yosemite/smp.c b/arch/mips/pmc-sierra/yosemite/smp.c
index 1d3b0734c78c..0527170d6adb 100644
--- a/arch/mips/pmc-sierra/yosemite/smp.c
+++ b/arch/mips/pmc-sierra/yosemite/smp.c
@@ -9,7 +9,7 @@ extern void (*mips_hpt_init)(unsigned int);
#define LAUNCHSTACK_SIZE 256
-static spinlock_t launch_lock __initdata;
+static __initdata DEFINE_SPINLOCK(launch_lock);
static unsigned long secondary_sp __initdata;
static unsigned long secondary_gp __initdata;
diff --git a/arch/mips/qemu/q-setup.c b/arch/mips/qemu/q-setup.c
index 1a80eee8cd35..022eb1af6db1 100644
--- a/arch/mips/qemu/q-setup.c
+++ b/arch/mips/qemu/q-setup.c
@@ -4,6 +4,11 @@
#define QEMU_PORT_BASE 0xb4000000
+const char *get_system_type(void)
+{
+ return "Qemu";
+}
+
static void __init qemu_timer_setup(struct irqaction *irq)
{
/* set the clock to 100 Hz */
diff --git a/arch/mips/sgi-ip22/ip22-eisa.c b/arch/mips/sgi-ip22/ip22-eisa.c
index fa0e719c5bd1..b19820110aa3 100644
--- a/arch/mips/sgi-ip22/ip22-eisa.c
+++ b/arch/mips/sgi-ip22/ip22-eisa.c
@@ -29,6 +29,7 @@
#include <linux/sched.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
+#include <asm/io.h>
#include <asm/irq.h>
#include <asm/mipsregs.h>
#include <asm/addrspace.h>
@@ -37,42 +38,29 @@
#include <asm/sgi/mc.h>
#include <asm/sgi/ip22.h>
-#define EISA_MAX_SLOTS 4
+/* I2 has four EISA slots. */
+#define IP22_EISA_MAX_SLOTS 4
#define EISA_MAX_IRQ 16
-#define EISA_TO_PHYS(x) (0x00080000 | (x))
-#define EISA_TO_KSEG1(x) ((void *) KSEG1ADDR(EISA_TO_PHYS((x))))
-
-#define EIU_MODE_REG 0x0009ffc0
-#define EIU_STAT_REG 0x0009ffc4
-#define EIU_PREMPT_REG 0x0009ffc8
-#define EIU_QUIET_REG 0x0009ffcc
-#define EIU_INTRPT_ACK 0x00090004
-
-#define EISA_DMA1_STATUS 8
-#define EISA_INT1_CTRL 0x20
-#define EISA_INT1_MASK 0x21
-#define EISA_INT2_CTRL 0xA0
-#define EISA_INT2_MASK 0xA1
-#define EISA_DMA2_STATUS 0xD0
-#define EISA_DMA2_WRITE_SINGLE 0xD4
-#define EISA_EXT_NMI_RESET_CTRL 0x461
-#define EISA_INT1_EDGE_LEVEL 0x4D0
-#define EISA_INT2_EDGE_LEVEL 0x4D1
-#define EISA_VENDOR_ID_OFFSET 0xC80
-
-#define EIU_WRITE_32(x,y) { *((u32 *) KSEG1ADDR(x)) = (u32) (y); mb(); }
-#define EIU_READ_8(x) *((u8 *) KSEG1ADDR(x))
-#define EISA_WRITE_8(x,y) { *((u8 *) EISA_TO_KSEG1(x)) = (u8) (y); mb(); }
-#define EISA_READ_8(x) *((u8 *) EISA_TO_KSEG1(x))
-
-static char *decode_eisa_sig(u8 * sig)
+#define EIU_MODE_REG 0x0001ffc0
+#define EIU_STAT_REG 0x0001ffc4
+#define EIU_PREMPT_REG 0x0001ffc8
+#define EIU_QUIET_REG 0x0001ffcc
+#define EIU_INTRPT_ACK 0x00010004
+
+static char __init *decode_eisa_sig(unsigned long addr)
{
- static char sig_str[8];
- u16 rev;
+ static char sig_str[EISA_SIG_LEN];
+ u8 sig[4];
+ u16 rev;
+ int i;
+
+ for (i = 0; i < 4; i++) {
+ sig[i] = inb (addr + i);
- if (sig[0] & 0x80)
- return NULL;
+ if (!i && (sig[0] & 0x80))
+ return NULL;
+ }
sig_str[0] = ((sig[0] >> 2) & 0x1f) + ('A' - 1);
sig_str[1] = (((sig[0] & 3) << 3) | (sig[1] >> 5)) + ('A' - 1);
@@ -83,23 +71,26 @@ static char *decode_eisa_sig(u8 * sig)
return sig_str;
}
-static void ip22_eisa_intr(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t ip22_eisa_intr(int irq, void *dev_id, struct pt_regs *regs)
{
u8 eisa_irq;
u8 dma1, dma2;
- eisa_irq = EIU_READ_8(EIU_INTRPT_ACK);
- dma1 = EISA_READ_8(EISA_DMA1_STATUS);
- dma2 = EISA_READ_8(EISA_DMA2_STATUS);
-
- if (eisa_irq >= EISA_MAX_IRQ) {
- /* Oops, Bad Stuff Happened... */
- printk(KERN_ERR "eisa_irq %d out of bound\n", eisa_irq);
+ eisa_irq = inb(EIU_INTRPT_ACK);
+ dma1 = inb(EISA_DMA1_STATUS);
+ dma2 = inb(EISA_DMA2_STATUS);
- EISA_WRITE_8(EISA_INT2_CTRL, 0x20);
- EISA_WRITE_8(EISA_INT1_CTRL, 0x20);
- } else
+ if (eisa_irq < EISA_MAX_IRQ) {
do_IRQ(eisa_irq, regs);
+ return IRQ_HANDLED;
+ }
+
+ /* Oops, Bad Stuff Happened... */
+ printk(KERN_ERR "eisa_irq %d out of bound\n", eisa_irq);
+
+ outb(0x20, EISA_INT2_CTRL);
+ outb(0x20, EISA_INT1_CTRL);
+ return IRQ_NONE;
}
static void enable_eisa1_irq(unsigned int irq)
@@ -109,9 +100,9 @@ static void enable_eisa1_irq(unsigned int irq)
local_irq_save(flags);
- mask = EISA_READ_8(EISA_INT1_MASK);
+ mask = inb(EISA_INT1_MASK);
mask &= ~((u8) (1 << irq));
- EISA_WRITE_8(EISA_INT1_MASK, mask);
+ outb(mask, EISA_INT1_MASK);
local_irq_restore(flags);
}
@@ -122,9 +113,9 @@ static unsigned int startup_eisa1_irq(unsigned int irq)
/* Only use edge interrupts for EISA */
- edge = EISA_READ_8(EISA_INT1_EDGE_LEVEL);
+ edge = inb(EISA_INT1_EDGE_LEVEL);
edge &= ~((u8) (1 << irq));
- EISA_WRITE_8(EISA_INT1_EDGE_LEVEL, edge);
+ outb(edge, EISA_INT1_EDGE_LEVEL);
enable_eisa1_irq(irq);
return 0;
@@ -134,9 +125,9 @@ static void disable_eisa1_irq(unsigned int irq)
{
u8 mask;
- mask = EISA_READ_8(EISA_INT1_MASK);
+ mask = inb(EISA_INT1_MASK);
mask |= ((u8) (1 << irq));
- EISA_WRITE_8(EISA_INT1_MASK, mask);
+ outb(mask, EISA_INT1_MASK);
}
#define shutdown_eisa1_irq disable_eisa1_irq
@@ -145,7 +136,7 @@ static void mask_and_ack_eisa1_irq(unsigned int irq)
{
disable_eisa1_irq(irq);
- EISA_WRITE_8(EISA_INT1_CTRL, 0x20);
+ outb(0x20, EISA_INT1_CTRL);
}
static void end_eisa1_irq(unsigned int irq)
@@ -171,9 +162,9 @@ static void enable_eisa2_irq(unsigned int irq)
local_irq_save(flags);
- mask = EISA_READ_8(EISA_INT2_MASK);
+ mask = inb(EISA_INT2_MASK);
mask &= ~((u8) (1 << (irq - 8)));
- EISA_WRITE_8(EISA_INT2_MASK, mask);
+ outb(mask, EISA_INT2_MASK);
local_irq_restore(flags);
}
@@ -184,9 +175,9 @@ static unsigned int startup_eisa2_irq(unsigned int irq)
/* Only use edge interrupts for EISA */
- edge = EISA_READ_8(EISA_INT2_EDGE_LEVEL);
+ edge = inb(EISA_INT2_EDGE_LEVEL);
edge &= ~((u8) (1 << (irq - 8)));
- EISA_WRITE_8(EISA_INT2_EDGE_LEVEL, edge);
+ outb(edge, EISA_INT2_EDGE_LEVEL);
enable_eisa2_irq(irq);
return 0;
@@ -196,9 +187,9 @@ static void disable_eisa2_irq(unsigned int irq)
{
u8 mask;
- mask = EISA_READ_8(EISA_INT2_MASK);
+ mask = inb(EISA_INT2_MASK);
mask |= ((u8) (1 << (irq - 8)));
- EISA_WRITE_8(EISA_INT2_MASK, mask);
+ outb(mask, EISA_INT2_MASK);
}
#define shutdown_eisa2_irq disable_eisa2_irq
@@ -207,8 +198,7 @@ static void mask_and_ack_eisa2_irq(unsigned int irq)
{
disable_eisa2_irq(irq);
- EISA_WRITE_8(EISA_INT2_CTRL, 0x20);
- EISA_WRITE_8(EISA_INT1_CTRL, 0x20);
+ outb(0x20, EISA_INT2_CTRL);
}
static void end_eisa2_irq(unsigned int irq)
@@ -241,7 +231,6 @@ int __init ip22_eisa_init(void)
{
int i, c;
char *str;
- u8 *slot_addr;
if (!(sgimc->systemid & SGIMC_SYSID_EPRESENT)) {
printk(KERN_INFO "EISA: bus not present.\n");
@@ -249,11 +238,8 @@ int __init ip22_eisa_init(void)
}
printk(KERN_INFO "EISA: Probing bus...\n");
- for (c = 0, i = 1; i <= EISA_MAX_SLOTS; i++) {
- slot_addr =
- (u8 *) EISA_TO_KSEG1((0x1000 * i) +
- EISA_VENDOR_ID_OFFSET);
- if ((str = decode_eisa_sig(slot_addr))) {
+ for (c = 0, i = 1; i <= IP22_EISA_MAX_SLOTS; i++) {
+ if ((str = decode_eisa_sig(0x1000 * i + EISA_VENDOR_ID_OFFSET))) {
printk(KERN_INFO "EISA: slot %d : %s detected.\n",
i, str);
c++;
@@ -268,25 +254,25 @@ int __init ip22_eisa_init(void)
Please wave your favorite dead chicken over the busses */
/* First say hello to the EIU */
- EIU_WRITE_32(EIU_PREMPT_REG, 0x0000FFFF);
- EIU_WRITE_32(EIU_QUIET_REG, 1);
- EIU_WRITE_32(EIU_MODE_REG, 0x40f3c07F);
+ outl(0x0000FFFF, EIU_PREMPT_REG);
+ outl(1, EIU_QUIET_REG);
+ outl(0x40f3c07F, EIU_MODE_REG);
/* Now be nice to the EISA chipset */
- EISA_WRITE_8(EISA_EXT_NMI_RESET_CTRL, 1);
- for (i = 0; i < 10000; i++); /* Wait long enough for the dust to settle */
- EISA_WRITE_8(EISA_EXT_NMI_RESET_CTRL, 0);
- EISA_WRITE_8(EISA_INT1_CTRL, 0x11);
- EISA_WRITE_8(EISA_INT2_CTRL, 0x11);
- EISA_WRITE_8(EISA_INT1_MASK, 0);
- EISA_WRITE_8(EISA_INT2_MASK, 8);
- EISA_WRITE_8(EISA_INT1_MASK, 4);
- EISA_WRITE_8(EISA_INT2_MASK, 2);
- EISA_WRITE_8(EISA_INT1_MASK, 1);
- EISA_WRITE_8(EISA_INT2_MASK, 1);
- EISA_WRITE_8(EISA_INT1_MASK, 0xfb);
- EISA_WRITE_8(EISA_INT2_MASK, 0xff);
- EISA_WRITE_8(EISA_DMA2_WRITE_SINGLE, 0);
+ outb(1, EISA_EXT_NMI_RESET_CTRL);
+ udelay(50); /* Wait long enough for the dust to settle */
+ outb(0, EISA_EXT_NMI_RESET_CTRL);
+ outb(0x11, EISA_INT1_CTRL);
+ outb(0x11, EISA_INT2_CTRL);
+ outb(0, EISA_INT1_MASK);
+ outb(8, EISA_INT2_MASK);
+ outb(4, EISA_INT1_MASK);
+ outb(2, EISA_INT2_MASK);
+ outb(1, EISA_INT1_MASK);
+ outb(1, EISA_INT2_MASK);
+ outb(0xfb, EISA_INT1_MASK);
+ outb(0xff, EISA_INT2_MASK);
+ outb(0, EISA_DMA2_WRITE_SINGLE);
for (i = SGINT_EISA; i < (SGINT_EISA + EISA_MAX_IRQ); i++) {
irq_desc[i].status = IRQ_DISABLED;
diff --git a/arch/mips/sgi-ip22/ip22-setup.c b/arch/mips/sgi-ip22/ip22-setup.c
index 0e96a5d67993..5e59b4c8876b 100644
--- a/arch/mips/sgi-ip22/ip22-setup.c
+++ b/arch/mips/sgi-ip22/ip22-setup.c
@@ -53,7 +53,7 @@ EXPORT_SYMBOL(ip22_do_break);
extern void ip22_be_init(void) __init;
extern void ip22_time_init(void) __init;
-static int __init ip22_setup(void)
+void __init plat_setup(void)
{
char *ctype;
@@ -137,8 +137,4 @@ static int __init ip22_setup(void)
}
}
#endif
-
- return 0;
}
-
-early_initcall(ip22_setup);
diff --git a/arch/mips/sgi-ip22/ip22-time.c b/arch/mips/sgi-ip22/ip22-time.c
index df9b5694328a..b7300cc5c5ad 100644
--- a/arch/mips/sgi-ip22/ip22-time.c
+++ b/arch/mips/sgi-ip22/ip22-time.c
@@ -35,7 +35,9 @@ static unsigned long indy_rtc_get_time(void)
{
unsigned int yrs, mon, day, hrs, min, sec;
unsigned int save_control;
+ unsigned long flags;
+ spin_lock_irqsave(&rtc_lock, flags);
save_control = hpc3c0->rtcregs[RTC_CMD] & 0xff;
hpc3c0->rtcregs[RTC_CMD] = save_control | RTC_TE;
@@ -47,6 +49,7 @@ static unsigned long indy_rtc_get_time(void)
yrs = BCD2BIN(hpc3c0->rtcregs[RTC_YEAR] & 0xff);
hpc3c0->rtcregs[RTC_CMD] = save_control;
+ spin_unlock_irqrestore(&rtc_lock, flags);
if (yrs < 45)
yrs += 30;
@@ -60,6 +63,7 @@ static int indy_rtc_set_time(unsigned long tim)
{
struct rtc_time tm;
unsigned int save_control;
+ unsigned long flags;
to_tm(tim, &tm);
@@ -68,6 +72,7 @@ static int indy_rtc_set_time(unsigned long tim)
if (tm.tm_year >= 100)
tm.tm_year -= 100;
+ spin_lock_irqsave(&rtc_lock, flags);
save_control = hpc3c0->rtcregs[RTC_CMD] & 0xff;
hpc3c0->rtcregs[RTC_CMD] = save_control | RTC_TE;
@@ -80,6 +85,7 @@ static int indy_rtc_set_time(unsigned long tim)
hpc3c0->rtcregs[RTC_HUNDREDTH_SECOND] = 0;
hpc3c0->rtcregs[RTC_CMD] = save_control;
+ spin_unlock_irqrestore(&rtc_lock, flags);
return 0;
}
diff --git a/arch/mips/sgi-ip27/Kconfig b/arch/mips/sgi-ip27/Kconfig
new file mode 100644
index 000000000000..7b0bc4437243
--- /dev/null
+++ b/arch/mips/sgi-ip27/Kconfig
@@ -0,0 +1,54 @@
+#config SGI_SN0_XXL
+# bool "IP27 XXL"
+# depends on SGI_IP27
+# This options adds support for userspace processes upto 16TB size.
+# Normally the limit is just .5TB.
+
+config SGI_SN0_N_MODE
+ bool "IP27 N-Mode"
+ depends on SGI_IP27
+ help
+ The nodes of Origin 200, Origin 2000 and Onyx 2 systems can be
+ configured in either N-Modes which allows for more nodes or M-Mode
+ which allows for more memory. Your system is most probably
+ running in M-Mode, so you should say N here.
+
+config ARCH_DISCONTIGMEM_ENABLE
+ bool
+ default y if SGI_IP27
+ help
+ Say Y to upport efficient handling of discontiguous physical memory,
+ for architectures which are either NUMA (Non-Uniform Memory Access)
+ or have huge holes in the physical address space for other reasons.
+ See <file:Documentation/vm/numa> for more.
+
+config NUMA
+ bool "NUMA Support"
+ depends on SGI_IP27
+ help
+ Say Y to compile the kernel to support NUMA (Non-Uniform Memory
+ Access). This option is for configuring high-end multiprocessor
+ server machines. If in doubt, say N.
+
+config MAPPED_KERNEL
+ bool "Mapped kernel support"
+ depends on SGI_IP27
+ help
+ Change the way a Linux kernel is loaded into memory on a MIPS64
+ machine. This is required in order to support text replication and
+ NUMA. If you need to understand it, read the source code.
+
+config REPLICATE_KTEXT
+ bool "Kernel text replication support"
+ depends on SGI_IP27
+ help
+ Say Y here to enable replicating the kernel text across multiple
+ nodes in a NUMA cluster. This trades memory for speed.
+
+config REPLICATE_EXHANDLERS
+ bool "Exception handler replication support"
+ depends on SGI_IP27
+ help
+ Say Y here to enable replicating the kernel exception handlers
+ across multiple nodes in a NUMA cluster. This trades memory for
+ speed.
diff --git a/arch/mips/sgi-ip27/ip27-berr.c b/arch/mips/sgi-ip27/ip27-berr.c
index e1829a5d3b19..07631a97670b 100644
--- a/arch/mips/sgi-ip27/ip27-berr.c
+++ b/arch/mips/sgi-ip27/ip27-berr.c
@@ -10,6 +10,7 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/signal.h> /* for SIGBUS */
#include <asm/module.h>
#include <asm/sn/addrs.h>
diff --git a/arch/mips/sgi-ip27/ip27-console.c b/arch/mips/sgi-ip27/ip27-console.c
index d97f5b5ef844..3e1ac299b804 100644
--- a/arch/mips/sgi-ip27/ip27-console.c
+++ b/arch/mips/sgi-ip27/ip27-console.c
@@ -30,8 +30,10 @@
static inline struct ioc3_uartregs *console_uart(void)
{
struct ioc3 *ioc3;
+ nasid_t nasid;
- ioc3 = (struct ioc3 *)KL_CONFIG_CH_CONS_INFO(get_nasid())->memory_base;
+ nasid = (master_nasid == INVALID_NASID) ? get_nasid() : master_nasid;
+ ioc3 = (struct ioc3 *)KL_CONFIG_CH_CONS_INFO(nasid)->memory_base;
return &ioc3->sregs.uarta;
}
diff --git a/arch/mips/sgi-ip27/ip27-init.c b/arch/mips/sgi-ip27/ip27-init.c
index 6dcee5c46c74..8651a0e75404 100644
--- a/arch/mips/sgi-ip27/ip27-init.c
+++ b/arch/mips/sgi-ip27/ip27-init.c
@@ -56,12 +56,12 @@ static void __init per_hub_init(cnodeid_t cnode)
{
struct hub_data *hub = hub_data(cnode);
nasid_t nasid = COMPACT_TO_NASID_NODEID(cnode);
+ int i;
cpu_set(smp_processor_id(), hub->h_cpus);
if (test_and_set_bit(cnode, hub_init_mask))
return;
-
/*
* Set CRB timeout at 5ms, (< PI timeout of 10ms)
*/
@@ -88,6 +88,24 @@ static void __init per_hub_init(cnodeid_t cnode)
__flush_cache_all();
}
#endif
+
+ /*
+ * Some interrupts are reserved by hardware or by software convention.
+ * Mark these as reserved right away so they won't be used accidently
+ * later.
+ */
+ for (i = 0; i <= BASE_PCI_IRQ; i++) {
+ __set_bit(i, hub->irq_alloc_mask);
+ LOCAL_HUB_CLR_INTR(INT_PEND0_BASELVL + i);
+ }
+
+ __set_bit(IP_PEND0_6_63, hub->irq_alloc_mask);
+ LOCAL_HUB_S(PI_INT_PEND_MOD, IP_PEND0_6_63);
+
+ for (i = NI_BRDCAST_ERR_A; i <= MSC_PANIC_INTR; i++) {
+ __set_bit(i, hub->irq_alloc_mask);
+ LOCAL_HUB_CLR_INTR(INT_PEND1_BASELVL + i);
+ }
}
void __init per_cpu_init(void)
@@ -104,30 +122,12 @@ void __init per_cpu_init(void)
clear_c0_status(ST0_IM);
+ per_hub_init(cnode);
+
for (i = 0; i < LEVELS_PER_SLICE; i++)
si->level_to_irq[i] = -1;
/*
- * Some interrupts are reserved by hardware or by software convention.
- * Mark these as reserved right away so they won't be used accidently
- * later.
- */
- for (i = 0; i <= BASE_PCI_IRQ; i++) {
- __set_bit(i, si->irq_alloc_mask);
- LOCAL_HUB_S(PI_INT_PEND_MOD, i);
- }
-
- __set_bit(IP_PEND0_6_63, si->irq_alloc_mask);
- LOCAL_HUB_S(PI_INT_PEND_MOD, IP_PEND0_6_63);
-
- for (i = NI_BRDCAST_ERR_A; i <= MSC_PANIC_INTR; i++) {
- __set_bit(i, si->irq_alloc_mask + 1);
- LOCAL_HUB_S(PI_INT_PEND_MOD, i);
- }
-
- LOCAL_HUB_L(PI_INT_PEND0);
-
- /*
* We use this so we can find the local hub's data as fast as only
* possible.
*/
@@ -140,8 +140,6 @@ void __init per_cpu_init(void)
install_cpu_nmi_handler(cputoslice(cpu));
set_c0_status(SRB_DEV0 | SRB_DEV1);
-
- per_hub_init(cnode);
}
/*
@@ -198,7 +196,7 @@ extern void ip27_setup_console(void);
extern void ip27_time_init(void);
extern void ip27_reboot_setup(void);
-static int __init ip27_setup(void)
+void __init plat_setup(void)
{
hubreg_t p, e, n_mode;
nasid_t nid;
@@ -245,8 +243,4 @@ static int __init ip27_setup(void)
set_io_port_base(IO_BASE);
board_time_init = ip27_time_init;
-
- return 0;
}
-
-early_initcall(ip27_setup);
diff --git a/arch/mips/sgi-ip27/ip27-irq.c b/arch/mips/sgi-ip27/ip27-irq.c
index 61817a18aed2..73e5e52781d8 100644
--- a/arch/mips/sgi-ip27/ip27-irq.c
+++ b/arch/mips/sgi-ip27/ip27-irq.c
@@ -5,6 +5,9 @@
* Copyright (C) 1999, 2000 Silicon Graphics, Inc.
* Copyright (C) 1999 - 2001 Kanoj Sarcar
*/
+
+#undef DEBUG
+
#include <linux/config.h>
#include <linux/init.h>
#include <linux/irq.h>
@@ -14,11 +17,11 @@
#include <linux/types.h>
#include <linux/interrupt.h>
#include <linux/ioport.h>
-#include <linux/irq.h>
#include <linux/timex.h>
#include <linux/slab.h>
#include <linux/random.h>
#include <linux/smp_lock.h>
+#include <linux/kernel.h>
#include <linux/kernel_stat.h>
#include <linux/delay.h>
#include <linux/bitops.h>
@@ -37,13 +40,6 @@
#include <asm/sn/hub.h>
#include <asm/sn/intr.h>
-#undef DEBUG_IRQ
-#ifdef DEBUG_IRQ
-#define DBG(x...) printk(x)
-#else
-#define DBG(x...)
-#endif
-
/*
* Linux has a controller-independent x86 interrupt architecture.
* every controller has a 'controller-template', that is used
@@ -74,14 +70,15 @@ extern int irq_to_slot[];
static inline int alloc_level(int cpu, int irq)
{
+ struct hub_data *hub = hub_data(cpu_to_node(cpu));
struct slice_data *si = cpu_data[cpu].data;
- int level; /* pre-allocated entries */
+ int level;
- level = find_first_zero_bit(si->irq_alloc_mask, LEVELS_PER_SLICE);
+ level = find_first_zero_bit(hub->irq_alloc_mask, LEVELS_PER_SLICE);
if (level >= LEVELS_PER_SLICE)
panic("Cpu %d flooded with devices\n", cpu);
- __set_bit(level, si->irq_alloc_mask);
+ __set_bit(level, hub->irq_alloc_mask);
si->level_to_irq[level] = irq;
return level;
@@ -216,9 +213,11 @@ static int intr_connect_level(int cpu, int bit)
{
nasid_t nasid = COMPACT_TO_NASID_NODEID(cpu_to_node(cpu));
struct slice_data *si = cpu_data[cpu].data;
+ unsigned long flags;
- __set_bit(bit, si->irq_enable_mask);
+ set_bit(bit, si->irq_enable_mask);
+ local_irq_save(flags);
if (!cputoslice(cpu)) {
REMOTE_HUB_S(nasid, PI_INT_MASK0_A, si->irq_enable_mask[0]);
REMOTE_HUB_S(nasid, PI_INT_MASK1_A, si->irq_enable_mask[1]);
@@ -226,6 +225,7 @@ static int intr_connect_level(int cpu, int bit)
REMOTE_HUB_S(nasid, PI_INT_MASK0_B, si->irq_enable_mask[0]);
REMOTE_HUB_S(nasid, PI_INT_MASK1_B, si->irq_enable_mask[1]);
}
+ local_irq_restore(flags);
return 0;
}
@@ -235,7 +235,7 @@ static int intr_disconnect_level(int cpu, int bit)
nasid_t nasid = COMPACT_TO_NASID_NODEID(cpu_to_node(cpu));
struct slice_data *si = cpu_data[cpu].data;
- __clear_bit(bit, si->irq_enable_mask);
+ clear_bit(bit, si->irq_enable_mask);
if (!cputoslice(cpu)) {
REMOTE_HUB_S(nasid, PI_INT_MASK0_A, si->irq_enable_mask[0]);
@@ -261,7 +261,7 @@ static unsigned int startup_bridge_irq(unsigned int irq)
bc = IRQ_TO_BRIDGE(irq);
bridge = bc->base;
- DBG("bridge_startup(): irq= 0x%x pin=%d\n", irq, pin);
+ pr_debug("bridge_startup(): irq= 0x%x pin=%d\n", irq, pin);
/*
* "map" irq to a swlevel greater than 6 since the first 6 bits
* of INT_PEND0 are taken
@@ -298,12 +298,13 @@ static unsigned int startup_bridge_irq(unsigned int irq)
static void shutdown_bridge_irq(unsigned int irq)
{
struct bridge_controller *bc = IRQ_TO_BRIDGE(irq);
+ struct hub_data *hub = hub_data(cpu_to_node(bc->irq_cpu));
bridge_t *bridge = bc->base;
struct slice_data *si = cpu_data[bc->irq_cpu].data;
int pin, swlevel;
cpuid_t cpu;
- DBG("bridge_shutdown: irq 0x%x\n", irq);
+ pr_debug("bridge_shutdown: irq 0x%x\n", irq);
pin = SLOT_FROM_PCI_IRQ(irq);
/*
@@ -313,7 +314,7 @@ static void shutdown_bridge_irq(unsigned int irq)
swlevel = find_level(&cpu, irq);
intr_disconnect_level(cpu, swlevel);
- __clear_bit(swlevel, si->irq_alloc_mask);
+ __clear_bit(swlevel, hub->irq_alloc_mask);
si->level_to_irq[swlevel] = -1;
bridge->b_int_enable &= ~(1 << pin);
@@ -433,25 +434,24 @@ void install_ipi(void)
int slice = LOCAL_HUB_L(PI_CPU_NUM);
int cpu = smp_processor_id();
struct slice_data *si = cpu_data[cpu].data;
- hubreg_t mask, set;
+ struct hub_data *hub = hub_data(cpu_to_node(cpu));
+ int resched, call;
+
+ resched = CPU_RESCHED_A_IRQ + slice;
+ __set_bit(resched, hub->irq_alloc_mask);
+ __set_bit(resched, si->irq_enable_mask);
+ LOCAL_HUB_CLR_INTR(resched);
+
+ call = CPU_CALL_A_IRQ + slice;
+ __set_bit(call, hub->irq_alloc_mask);
+ __set_bit(call, si->irq_enable_mask);
+ LOCAL_HUB_CLR_INTR(call);
if (slice == 0) {
- LOCAL_HUB_CLR_INTR(CPU_RESCHED_A_IRQ);
- LOCAL_HUB_CLR_INTR(CPU_CALL_A_IRQ);
- mask = LOCAL_HUB_L(PI_INT_MASK0_A); /* Slice A */
- set = (1UL << CPU_RESCHED_A_IRQ) | (1UL << CPU_CALL_A_IRQ);
- mask |= set;
- si->irq_enable_mask[0] |= set;
- si->irq_alloc_mask[0] |= set;
- LOCAL_HUB_S(PI_INT_MASK0_A, mask);
+ LOCAL_HUB_S(PI_INT_MASK0_A, si->irq_enable_mask[0]);
+ LOCAL_HUB_S(PI_INT_MASK1_A, si->irq_enable_mask[1]);
} else {
- LOCAL_HUB_CLR_INTR(CPU_RESCHED_B_IRQ);
- LOCAL_HUB_CLR_INTR(CPU_CALL_B_IRQ);
- mask = LOCAL_HUB_L(PI_INT_MASK0_B); /* Slice B */
- set = (1UL << CPU_RESCHED_B_IRQ) | (1UL << CPU_CALL_B_IRQ);
- mask |= set;
- si->irq_enable_mask[1] |= set;
- si->irq_alloc_mask[1] |= set;
- LOCAL_HUB_S(PI_INT_MASK0_B, mask);
+ LOCAL_HUB_S(PI_INT_MASK0_B, si->irq_enable_mask[0]);
+ LOCAL_HUB_S(PI_INT_MASK1_B, si->irq_enable_mask[1]);
}
}
diff --git a/arch/mips/sgi-ip27/ip27-smp.c b/arch/mips/sgi-ip27/ip27-smp.c
index 17f768cba94f..3a8291b7d26d 100644
--- a/arch/mips/sgi-ip27/ip27-smp.c
+++ b/arch/mips/sgi-ip27/ip27-smp.c
@@ -127,37 +127,28 @@ void cpu_node_probe(void)
printk("Discovered %d cpus on %d nodes\n", highest + 1, num_online_nodes());
}
-static void intr_clear_bits(nasid_t nasid, volatile hubreg_t *pend,
- int base_level)
+static __init void intr_clear_all(nasid_t nasid)
{
- volatile hubreg_t bits;
int i;
- /* Check pending interrupts */
- if ((bits = HUB_L(pend)) != 0)
- for (i = 0; i < N_INTPEND_BITS; i++)
- if (bits & (1 << i))
- LOCAL_HUB_CLR_INTR(base_level + i);
-}
-
-static void intr_clear_all(nasid_t nasid)
-{
REMOTE_HUB_S(nasid, PI_INT_MASK0_A, 0);
REMOTE_HUB_S(nasid, PI_INT_MASK0_B, 0);
REMOTE_HUB_S(nasid, PI_INT_MASK1_A, 0);
REMOTE_HUB_S(nasid, PI_INT_MASK1_B, 0);
- intr_clear_bits(nasid, REMOTE_HUB_ADDR(nasid, PI_INT_PEND0),
- INT_PEND0_BASELVL);
- intr_clear_bits(nasid, REMOTE_HUB_ADDR(nasid, PI_INT_PEND1),
- INT_PEND1_BASELVL);
+
+ for (i = 0; i < 128; i++)
+ REMOTE_HUB_CLR_INTR(nasid, i);
}
void __init prom_prepare_cpus(unsigned int max_cpus)
{
cnodeid_t cnode;
- for_each_online_node(cnode)
+ for_each_online_node(cnode) {
+ if (cnode == 0)
+ continue;
intr_clear_all(COMPACT_TO_NASID_NODEID(cnode));
+ }
replicate_kernel_text();
diff --git a/arch/mips/sgi-ip32/ip32-irq.c b/arch/mips/sgi-ip32/ip32-irq.c
index fc3a8e90d763..2eb22d692ed9 100644
--- a/arch/mips/sgi-ip32/ip32-irq.c
+++ b/arch/mips/sgi-ip32/ip32-irq.c
@@ -163,14 +163,13 @@ static void end_cpu_irq(unsigned int irq)
#define mask_and_ack_cpu_irq disable_cpu_irq
static struct hw_interrupt_type ip32_cpu_interrupt = {
- "IP32 CPU",
- startup_cpu_irq,
- shutdown_cpu_irq,
- enable_cpu_irq,
- disable_cpu_irq,
- mask_and_ack_cpu_irq,
- end_cpu_irq,
- NULL
+ .typename = "IP32 CPU",
+ .startup = startup_cpu_irq,
+ .shutdown = shutdown_cpu_irq,
+ .enable = enable_cpu_irq,
+ .disable = disable_cpu_irq,
+ .ack = mask_and_ack_cpu_irq,
+ .end = end_cpu_irq,
};
/*
@@ -234,14 +233,13 @@ static void end_crime_irq(unsigned int irq)
#define shutdown_crime_irq disable_crime_irq
static struct hw_interrupt_type ip32_crime_interrupt = {
- "IP32 CRIME",
- startup_crime_irq,
- shutdown_crime_irq,
- enable_crime_irq,
- disable_crime_irq,
- mask_and_ack_crime_irq,
- end_crime_irq,
- NULL
+ .typename = "IP32 CRIME",
+ .startup = startup_crime_irq,
+ .shutdown = shutdown_crime_irq,
+ .enable = enable_crime_irq,
+ .disable = disable_crime_irq,
+ .ack = mask_and_ack_crime_irq,
+ .end = end_crime_irq,
};
/*
@@ -294,14 +292,13 @@ static void end_macepci_irq(unsigned int irq)
#define mask_and_ack_macepci_irq disable_macepci_irq
static struct hw_interrupt_type ip32_macepci_interrupt = {
- "IP32 MACE PCI",
- startup_macepci_irq,
- shutdown_macepci_irq,
- enable_macepci_irq,
- disable_macepci_irq,
- mask_and_ack_macepci_irq,
- end_macepci_irq,
- NULL
+ .typename = "IP32 MACE PCI",
+ .startup = startup_macepci_irq,
+ .shutdown = shutdown_macepci_irq,
+ .enable = enable_macepci_irq,
+ .disable = disable_macepci_irq,
+ .ack = mask_and_ack_macepci_irq,
+ .end = end_macepci_irq,
};
/* This is used for MACE ISA interrupts. That means bits 4-6 in the
@@ -425,14 +422,13 @@ static void end_maceisa_irq(unsigned irq)
#define shutdown_maceisa_irq disable_maceisa_irq
static struct hw_interrupt_type ip32_maceisa_interrupt = {
- "IP32 MACE ISA",
- startup_maceisa_irq,
- shutdown_maceisa_irq,
- enable_maceisa_irq,
- disable_maceisa_irq,
- mask_and_ack_maceisa_irq,
- end_maceisa_irq,
- NULL
+ .typename = "IP32 MACE ISA",
+ .startup = startup_maceisa_irq,
+ .shutdown = shutdown_maceisa_irq,
+ .enable = enable_maceisa_irq,
+ .disable = disable_maceisa_irq,
+ .ack = mask_and_ack_maceisa_irq,
+ .end = end_maceisa_irq,
};
/* This is used for regular non-ISA, non-PCI MACE interrupts. That means
@@ -476,14 +472,13 @@ static void end_mace_irq(unsigned int irq)
#define mask_and_ack_mace_irq disable_mace_irq
static struct hw_interrupt_type ip32_mace_interrupt = {
- "IP32 MACE",
- startup_mace_irq,
- shutdown_mace_irq,
- enable_mace_irq,
- disable_mace_irq,
- mask_and_ack_mace_irq,
- end_mace_irq,
- NULL
+ .typename = "IP32 MACE",
+ .startup = startup_mace_irq,
+ .shutdown = shutdown_mace_irq,
+ .enable = enable_mace_irq,
+ .disable = disable_mace_irq,
+ .ack = mask_and_ack_mace_irq,
+ .end = end_mace_irq,
};
static void ip32_unknown_interrupt(struct pt_regs *regs)
diff --git a/arch/mips/sgi-ip32/ip32-memory.c b/arch/mips/sgi-ip32/ip32-memory.c
index fc76ca92bab9..d37d40a3cdae 100644
--- a/arch/mips/sgi-ip32/ip32-memory.c
+++ b/arch/mips/sgi-ip32/ip32-memory.c
@@ -36,8 +36,8 @@ void __init prom_meminit (void)
if (base + size > (256 << 20))
base += CRIME_HI_MEM_BASE;
- printk("CRIME MC: bank %u base 0x%016lx size %luMB\n",
- bank, base, size);
+ printk("CRIME MC: bank %u base 0x%016lx size %luMiB\n",
+ bank, base, size >> 20);
add_memory_region (base, size, BOOT_MEM_RAM);
}
}
diff --git a/arch/mips/sgi-ip32/ip32-setup.c b/arch/mips/sgi-ip32/ip32-setup.c
index 8d270be58224..d10a269aeae1 100644
--- a/arch/mips/sgi-ip32/ip32-setup.c
+++ b/arch/mips/sgi-ip32/ip32-setup.c
@@ -92,7 +92,7 @@ void __init ip32_timer_setup(struct irqaction *irq)
setup_irq(IP32_R4K_TIMER_IRQ, irq);
}
-static int __init ip32_setup(void)
+void __init plat_setup(void)
{
board_be_init = ip32_be_init;
@@ -152,8 +152,4 @@ static int __init ip32_setup(void)
}
}
#endif
-
- return 0;
}
-
-early_initcall(ip32_setup);
diff --git a/arch/mips/sibyte/Kconfig b/arch/mips/sibyte/Kconfig
new file mode 100644
index 000000000000..de46f62ac462
--- /dev/null
+++ b/arch/mips/sibyte/Kconfig
@@ -0,0 +1,161 @@
+config SIBYTE_SB1250
+ bool
+ select HW_HAS_PCI
+ select SIBYTE_HAS_LDT
+ select SIBYTE_SB1xxx_SOC
+
+config SIBYTE_BCM1120
+ bool
+ select SIBYTE_BCM112X
+ select SIBYTE_SB1xxx_SOC
+
+config SIBYTE_BCM1125
+ bool
+ select HW_HAS_PCI
+ select SIBYTE_BCM112X
+ select SIBYTE_SB1xxx_SOC
+
+config SIBYTE_BCM1125H
+ bool
+ select HW_HAS_PCI
+ select SIBYTE_BCM112X
+ select SIBYTE_HAS_LDT
+ select SIBYTE_SB1xxx_SOC
+
+config SIBYTE_BCM112X
+ bool
+ select SIBYTE_SB1xxx_SOC
+
+config SIBYTE_BCM1x80
+ bool
+ select HW_HAS_PCI
+ select SIBYTE_SB1xxx_SOC
+
+config SIBYTE_BCM1x55
+ bool
+ select HW_HAS_PCI
+ select SIBYTE_SB1xxx_SOC
+
+config SIBYTE_SB1xxx_SOC
+ bool
+ depends on EXPERIMENTAL
+ select DMA_COHERENT
+ select SIBYTE_CFE
+ select SWAP_IO_SPACE
+ select SYS_SUPPORTS_32BIT_KERNEL
+ select SYS_SUPPORTS_64BIT_KERNEL
+
+choice
+ prompt "SiByte SOC Stepping"
+ depends on SIBYTE_SB1xxx_SOC
+
+config CPU_SB1_PASS_1
+ bool "1250 Pass1"
+ depends on SIBYTE_SB1250
+ select CPU_HAS_PREFETCH
+
+config CPU_SB1_PASS_2_1250
+ bool "1250 An"
+ depends on SIBYTE_SB1250
+ select CPU_SB1_PASS_2
+ help
+ Also called BCM1250 Pass 2
+
+config CPU_SB1_PASS_2_2
+ bool "1250 Bn"
+ depends on SIBYTE_SB1250
+ select CPU_HAS_PREFETCH
+ help
+ Also called BCM1250 Pass 2.2
+
+config CPU_SB1_PASS_4
+ bool "1250 Cn"
+ depends on SIBYTE_SB1250
+ select CPU_HAS_PREFETCH
+ help
+ Also called BCM1250 Pass 3
+
+config CPU_SB1_PASS_2_112x
+ bool "112x Hybrid"
+ depends on SIBYTE_BCM112X
+ select CPU_SB1_PASS_2
+
+config CPU_SB1_PASS_3
+ bool "112x An"
+ depends on SIBYTE_BCM112X
+ select CPU_HAS_PREFETCH
+
+endchoice
+
+config CPU_SB1_PASS_2
+ bool
+
+config SIBYTE_HAS_LDT
+ bool
+ depends on PCI && (SIBYTE_SB1250 || SIBYTE_BCM1125H)
+ default y
+
+config SIMULATION
+ bool "Running under simulation"
+ depends on SIBYTE_SB1xxx_SOC
+ help
+ Build a kernel suitable for running under the GDB simulator.
+ Primarily adjusts the kernel's notion of time.
+
+config CONFIG_SB1_CEX_ALWAYS_FATAL
+ bool "All cache exceptions considered fatal (no recovery attempted)"
+ depends on SIBYTE_SB1xxx_SOC
+
+config CONFIG_SB1_CERR_STALL
+ bool "Stall (rather than panic) on fatal cache error"
+ depends on SIBYTE_SB1xxx_SOC
+
+config SIBYTE_CFE
+ bool "Booting from CFE"
+ depends on SIBYTE_SB1xxx_SOC
+ help
+ Make use of the CFE API for enumerating available memory,
+ controlling secondary CPUs, and possibly console output.
+
+config SIBYTE_CFE_CONSOLE
+ bool "Use firmware console"
+ depends on SIBYTE_CFE
+ help
+ Use the CFE API's console write routines during boot. Other console
+ options (VT console, sb1250 duart console, etc.) should not be
+ configured.
+
+config SIBYTE_STANDALONE
+ bool
+ depends on SIBYTE_SB1xxx_SOC && !SIBYTE_CFE
+ default y
+
+config SIBYTE_STANDALONE_RAM_SIZE
+ int "Memory size (in megabytes)"
+ depends on SIBYTE_STANDALONE
+ default "32"
+
+config SIBYTE_BUS_WATCHER
+ bool "Support for Bus Watcher statistics"
+ depends on SIBYTE_SB1xxx_SOC
+ help
+ Handle and keep statistics on the bus error interrupts (COR_ECC,
+ BAD_ECC, IO_BUS).
+
+config SIBYTE_BW_TRACE
+ bool "Capture bus trace before bus error"
+ depends on SIBYTE_BUS_WATCHER
+ help
+ Run a continuous bus trace, dumping the raw data as soon as
+ a ZBbus error is detected. Cannot work if ZBbus profiling
+ is turned on, and also will interfere with JTAG-based trace
+ buffer activity. Raw buffer data is dumped to console, and
+ must be processed off-line.
+
+config SIBYTE_SB1250_PROF
+ bool "Support for SB1/SOC profiling - SB1/SCD perf counters"
+ depends on SIBYTE_SB1xxx_SOC
+
+config SIBYTE_TBPROF
+ bool "Support for ZBbus profiling"
+ depends on SIBYTE_SB1xxx_SOC
diff --git a/arch/mips/sibyte/bcm1480/Makefile b/arch/mips/sibyte/bcm1480/Makefile
new file mode 100644
index 000000000000..538d5a51ae94
--- /dev/null
+++ b/arch/mips/sibyte/bcm1480/Makefile
@@ -0,0 +1,5 @@
+obj-y := setup.o irq.o irq_handler.o time.o
+
+obj-$(CONFIG_SMP) += smp.o
+
+EXTRA_AFLAGS := $(CFLAGS)
diff --git a/arch/mips/sibyte/bcm1480/irq.c b/arch/mips/sibyte/bcm1480/irq.c
new file mode 100644
index 000000000000..b2a1ba5d23df
--- /dev/null
+++ b/arch/mips/sibyte/bcm1480/irq.c
@@ -0,0 +1,476 @@
+/*
+ * Copyright (C) 2000,2001,2002,2003,2004 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; 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/config.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/linkage.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/kernel_stat.h>
+
+#include <asm/errno.h>
+#include <asm/signal.h>
+#include <asm/system.h>
+#include <asm/ptrace.h>
+#include <asm/io.h>
+
+#include <asm/sibyte/bcm1480_regs.h>
+#include <asm/sibyte/bcm1480_int.h>
+#include <asm/sibyte/bcm1480_scd.h>
+
+#include <asm/sibyte/sb1250_uart.h>
+#include <asm/sibyte/sb1250.h>
+
+/*
+ * These are the routines that handle all the low level interrupt stuff.
+ * Actions handled here are: initialization of the interrupt map, requesting of
+ * interrupt lines by handlers, dispatching if interrupts to handlers, probing
+ * for interrupt lines
+ */
+
+
+#define shutdown_bcm1480_irq disable_bcm1480_irq
+static void end_bcm1480_irq(unsigned int irq);
+static void enable_bcm1480_irq(unsigned int irq);
+static void disable_bcm1480_irq(unsigned int irq);
+static unsigned int startup_bcm1480_irq(unsigned int irq);
+static void ack_bcm1480_irq(unsigned int irq);
+#ifdef CONFIG_SMP
+static void bcm1480_set_affinity(unsigned int irq, cpumask_t mask);
+#endif
+
+#ifdef CONFIG_PCI
+extern unsigned long ht_eoi_space;
+#endif
+
+#ifdef CONFIG_KGDB
+#include <asm/gdb-stub.h>
+extern void breakpoint(void);
+static int kgdb_irq;
+#ifdef CONFIG_GDB_CONSOLE
+extern void register_gdb_console(void);
+#endif
+
+/* kgdb is on when configured. Pass "nokgdb" kernel arg to turn it off */
+static int kgdb_flag = 1;
+static int __init nokgdb(char *str)
+{
+ kgdb_flag = 0;
+ return 1;
+}
+__setup("nokgdb", nokgdb);
+
+/* Default to UART1 */
+int kgdb_port = 1;
+#ifdef CONFIG_SIBYTE_SB1250_DUART
+extern char sb1250_duart_present[];
+#endif
+#endif
+
+static struct hw_interrupt_type bcm1480_irq_type = {
+ .typename = "BCM1480-IMR",
+ .startup = startup_bcm1480_irq,
+ .shutdown = shutdown_bcm1480_irq,
+ .enable = enable_bcm1480_irq,
+ .disable = disable_bcm1480_irq,
+ .ack = ack_bcm1480_irq,
+ .end = end_bcm1480_irq,
+#ifdef CONFIG_SMP
+ .set_affinity = bcm1480_set_affinity
+#endif
+};
+
+/* Store the CPU id (not the logical number) */
+int bcm1480_irq_owner[BCM1480_NR_IRQS];
+
+DEFINE_SPINLOCK(bcm1480_imr_lock);
+
+void bcm1480_mask_irq(int cpu, int irq)
+{
+ unsigned long flags;
+ u64 cur_ints,hl_spacing;
+
+ spin_lock_irqsave(&bcm1480_imr_lock, flags);
+ hl_spacing = 0;
+ if ((irq >= BCM1480_NR_IRQS_HALF) && (irq <= BCM1480_NR_IRQS)) {
+ hl_spacing = BCM1480_IMR_HL_SPACING;
+ irq -= BCM1480_NR_IRQS_HALF;
+ }
+ cur_ints = ____raw_readq(IOADDR(A_BCM1480_IMR_MAPPER(cpu) + R_BCM1480_IMR_INTERRUPT_MASK_H + hl_spacing));
+ cur_ints |= (((u64) 1) << irq);
+ ____raw_writeq(cur_ints, IOADDR(A_BCM1480_IMR_MAPPER(cpu) + R_BCM1480_IMR_INTERRUPT_MASK_H + hl_spacing));
+ spin_unlock_irqrestore(&bcm1480_imr_lock, flags);
+}
+
+void bcm1480_unmask_irq(int cpu, int irq)
+{
+ unsigned long flags;
+ u64 cur_ints,hl_spacing;
+
+ spin_lock_irqsave(&bcm1480_imr_lock, flags);
+ hl_spacing = 0;
+ if ((irq >= BCM1480_NR_IRQS_HALF) && (irq <= BCM1480_NR_IRQS)) {
+ hl_spacing = BCM1480_IMR_HL_SPACING;
+ irq -= BCM1480_NR_IRQS_HALF;
+ }
+ cur_ints = ____raw_readq(IOADDR(A_BCM1480_IMR_MAPPER(cpu) + R_BCM1480_IMR_INTERRUPT_MASK_H + hl_spacing));
+ cur_ints &= ~(((u64) 1) << irq);
+ ____raw_writeq(cur_ints, IOADDR(A_BCM1480_IMR_MAPPER(cpu) + R_BCM1480_IMR_INTERRUPT_MASK_H + hl_spacing));
+ spin_unlock_irqrestore(&bcm1480_imr_lock, flags);
+}
+
+#ifdef CONFIG_SMP
+static void bcm1480_set_affinity(unsigned int irq, cpumask_t mask)
+{
+ int i = 0, old_cpu, cpu, int_on;
+ u64 cur_ints;
+ irq_desc_t *desc = irq_desc + irq;
+ unsigned long flags;
+ unsigned int irq_dirty;
+
+ i = first_cpu(mask);
+ if (next_cpu(i, mask) <= NR_CPUS) {
+ printk("attempted to set irq affinity for irq %d to multiple CPUs\n", irq);
+ return;
+ }
+
+ /* Convert logical CPU to physical CPU */
+ cpu = cpu_logical_map(i);
+
+ /* Protect against other affinity changers and IMR manipulation */
+ spin_lock_irqsave(&desc->lock, flags);
+ spin_lock(&bcm1480_imr_lock);
+
+ /* Swizzle each CPU's IMR (but leave the IP selection alone) */
+ old_cpu = bcm1480_irq_owner[irq];
+ irq_dirty = irq;
+ if ((irq_dirty >= BCM1480_NR_IRQS_HALF) && (irq_dirty <= BCM1480_NR_IRQS)) {
+ irq_dirty -= BCM1480_NR_IRQS_HALF;
+ }
+
+ int k;
+ for (k=0; k<2; k++) { /* Loop through high and low interrupt mask register */
+ cur_ints = ____raw_readq(IOADDR(A_BCM1480_IMR_MAPPER(old_cpu) + R_BCM1480_IMR_INTERRUPT_MASK_H + (k*BCM1480_IMR_HL_SPACING)));
+ int_on = !(cur_ints & (((u64) 1) << irq_dirty));
+ if (int_on) {
+ /* If it was on, mask it */
+ cur_ints |= (((u64) 1) << irq_dirty);
+ ____raw_writeq(cur_ints, IOADDR(A_BCM1480_IMR_MAPPER(old_cpu) + R_BCM1480_IMR_INTERRUPT_MASK_H + (k*BCM1480_IMR_HL_SPACING)));
+ }
+ bcm1480_irq_owner[irq] = cpu;
+ if (int_on) {
+ /* unmask for the new CPU */
+ cur_ints = ____raw_readq(IOADDR(A_BCM1480_IMR_MAPPER(cpu) + R_BCM1480_IMR_INTERRUPT_MASK_H + (k*BCM1480_IMR_HL_SPACING)));
+ cur_ints &= ~(((u64) 1) << irq_dirty);
+ ____raw_writeq(cur_ints, IOADDR(A_BCM1480_IMR_MAPPER(cpu) + R_BCM1480_IMR_INTERRUPT_MASK_H + (k*BCM1480_IMR_HL_SPACING)));
+ }
+ }
+ spin_unlock(&bcm1480_imr_lock);
+ spin_unlock_irqrestore(&desc->lock, flags);
+}
+#endif
+
+
+/* Defined in arch/mips/sibyte/bcm1480/irq_handler.S */
+extern void bcm1480_irq_handler(void);
+
+/*****************************************************************************/
+
+static unsigned int startup_bcm1480_irq(unsigned int irq)
+{
+ bcm1480_unmask_irq(bcm1480_irq_owner[irq], irq);
+
+ return 0; /* never anything pending */
+}
+
+
+static void disable_bcm1480_irq(unsigned int irq)
+{
+ bcm1480_mask_irq(bcm1480_irq_owner[irq], irq);
+}
+
+static void enable_bcm1480_irq(unsigned int irq)
+{
+ bcm1480_unmask_irq(bcm1480_irq_owner[irq], irq);
+}
+
+
+static void ack_bcm1480_irq(unsigned int irq)
+{
+ u64 pending;
+ unsigned int irq_dirty;
+
+ /*
+ * If the interrupt was an HT interrupt, now is the time to
+ * clear it. NOTE: we assume the HT bridge was set up to
+ * deliver the interrupts to all CPUs (which makes affinity
+ * changing easier for us)
+ */
+ irq_dirty = irq;
+ if ((irq_dirty >= BCM1480_NR_IRQS_HALF) && (irq_dirty <= BCM1480_NR_IRQS)) {
+ irq_dirty -= BCM1480_NR_IRQS_HALF;
+ }
+ int k;
+ for (k=0; k<2; k++) { /* Loop through high and low LDT interrupts */
+ pending = __raw_readq(IOADDR(A_BCM1480_IMR_REGISTER(bcm1480_irq_owner[irq],
+ R_BCM1480_IMR_LDT_INTERRUPT_H + (k*BCM1480_IMR_HL_SPACING))));
+ pending &= ((u64)1 << (irq_dirty));
+ if (pending) {
+#ifdef CONFIG_SMP
+ int i;
+ for (i=0; i<NR_CPUS; i++) {
+ /*
+ * Clear for all CPUs so an affinity switch
+ * doesn't find an old status
+ */
+ __raw_writeq(pending, IOADDR(A_BCM1480_IMR_REGISTER(cpu_logical_map(i),
+ R_BCM1480_IMR_LDT_INTERRUPT_CLR_H + (k*BCM1480_IMR_HL_SPACING))));
+ }
+#else
+ __raw_writeq(pending, IOADDR(A_BCM1480_IMR_REGISTER(0, R_BCM1480_IMR_LDT_INTERRUPT_CLR_H + (k*BCM1480_IMR_HL_SPACING))));
+#endif
+
+ /*
+ * Generate EOI. For Pass 1 parts, EOI is a nop. For
+ * Pass 2, the LDT world may be edge-triggered, but
+ * this EOI shouldn't hurt. If they are
+ * level-sensitive, the EOI is required.
+ */
+#ifdef CONFIG_PCI
+ if (ht_eoi_space)
+ *(uint32_t *)(ht_eoi_space+(irq<<16)+(7<<2)) = 0;
+#endif
+ }
+ }
+ bcm1480_mask_irq(bcm1480_irq_owner[irq], irq);
+}
+
+
+static void end_bcm1480_irq(unsigned int irq)
+{
+ if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) {
+ bcm1480_unmask_irq(bcm1480_irq_owner[irq], irq);
+ }
+}
+
+
+void __init init_bcm1480_irqs(void)
+{
+ int i;
+
+ for (i = 0; i < NR_IRQS; i++) {
+ irq_desc[i].status = IRQ_DISABLED;
+ irq_desc[i].action = 0;
+ irq_desc[i].depth = 1;
+ if (i < BCM1480_NR_IRQS) {
+ irq_desc[i].handler = &bcm1480_irq_type;
+ bcm1480_irq_owner[i] = 0;
+ } else {
+ irq_desc[i].handler = &no_irq_type;
+ }
+ }
+}
+
+
+static irqreturn_t bcm1480_dummy_handler(int irq, void *dev_id,
+ struct pt_regs *regs)
+{
+ return IRQ_NONE;
+}
+
+static struct irqaction bcm1480_dummy_action = {
+ .handler = bcm1480_dummy_handler,
+ .flags = 0,
+ .mask = CPU_MASK_NONE,
+ .name = "bcm1480-private",
+ .next = NULL,
+ .dev_id = 0
+};
+
+int bcm1480_steal_irq(int irq)
+{
+ irq_desc_t *desc = irq_desc + irq;
+ unsigned long flags;
+ int retval = 0;
+
+ if (irq >= BCM1480_NR_IRQS)
+ return -EINVAL;
+
+ spin_lock_irqsave(&desc->lock,flags);
+ /* Don't allow sharing at all for these */
+ if (desc->action != NULL)
+ retval = -EBUSY;
+ else {
+ desc->action = &bcm1480_dummy_action;
+ desc->depth = 0;
+ }
+ spin_unlock_irqrestore(&desc->lock,flags);
+ return 0;
+}
+
+/*
+ * init_IRQ is called early in the boot sequence from init/main.c. It
+ * is responsible for setting up the interrupt mapper and installing the
+ * handler that will be responsible for dispatching interrupts to the
+ * "right" place.
+ */
+/*
+ * For now, map all interrupts to IP[2]. We could save
+ * some cycles by parceling out system interrupts to different
+ * IP lines, but keep it simple for bringup. We'll also direct
+ * all interrupts to a single CPU; we should probably route
+ * PCI and LDT to one cpu and everything else to the other
+ * to balance the load a bit.
+ *
+ * On the second cpu, everything is set to IP5, which is
+ * ignored, EXCEPT the mailbox interrupt. That one is
+ * set to IP[2] so it is handled. This is needed so we
+ * can do cross-cpu function calls, as requred by SMP
+ */
+
+#define IMR_IP2_VAL K_BCM1480_INT_MAP_I0
+#define IMR_IP3_VAL K_BCM1480_INT_MAP_I1
+#define IMR_IP4_VAL K_BCM1480_INT_MAP_I2
+#define IMR_IP5_VAL K_BCM1480_INT_MAP_I3
+#define IMR_IP6_VAL K_BCM1480_INT_MAP_I4
+
+void __init arch_init_irq(void)
+{
+
+ unsigned int i, cpu;
+ u64 tmp;
+ unsigned int imask = STATUSF_IP4 | STATUSF_IP3 | STATUSF_IP2 |
+ STATUSF_IP1 | STATUSF_IP0;
+
+ /* Default everything to IP2 */
+ /* Start with _high registers which has no bit 0 interrupt source */
+ for (i = 1; i < BCM1480_NR_IRQS_HALF; i++) { /* was I0 */
+ for (cpu = 0; cpu < 4; cpu++) {
+ __raw_writeq(IMR_IP2_VAL,
+ IOADDR(A_BCM1480_IMR_REGISTER(cpu,
+ R_BCM1480_IMR_INTERRUPT_MAP_BASE_H) + (i << 3)));
+ }
+ }
+
+ /* Now do _low registers */
+ for (i = 0; i < BCM1480_NR_IRQS_HALF; i++) {
+ for (cpu = 0; cpu < 4; cpu++) {
+ __raw_writeq(IMR_IP2_VAL,
+ IOADDR(A_BCM1480_IMR_REGISTER(cpu,
+ R_BCM1480_IMR_INTERRUPT_MAP_BASE_L) + (i << 3)));
+ }
+ }
+
+ init_bcm1480_irqs();
+
+ /*
+ * Map the high 16 bits of mailbox_0 registers to IP[3], for
+ * inter-cpu messages
+ */
+ /* Was I1 */
+ for (cpu = 0; cpu < 4; cpu++) {
+ __raw_writeq(IMR_IP3_VAL, IOADDR(A_BCM1480_IMR_REGISTER(cpu, R_BCM1480_IMR_INTERRUPT_MAP_BASE_H) +
+ (K_BCM1480_INT_MBOX_0_0 << 3)));
+ }
+
+
+ /* Clear the mailboxes. The firmware may leave them dirty */
+ for (cpu = 0; cpu < 4; cpu++) {
+ __raw_writeq(0xffffffffffffffffULL,
+ IOADDR(A_BCM1480_IMR_REGISTER(cpu, R_BCM1480_IMR_MAILBOX_0_CLR_CPU)));
+ __raw_writeq(0xffffffffffffffffULL,
+ IOADDR(A_BCM1480_IMR_REGISTER(cpu, R_BCM1480_IMR_MAILBOX_1_CLR_CPU)));
+ }
+
+
+ /* Mask everything except the high 16 bit of mailbox_0 registers for all cpus */
+ tmp = ~((u64) 0) ^ ( (((u64) 1) << K_BCM1480_INT_MBOX_0_0));
+ for (cpu = 0; cpu < 4; cpu++) {
+ __raw_writeq(tmp, IOADDR(A_BCM1480_IMR_REGISTER(cpu, R_BCM1480_IMR_INTERRUPT_MASK_H)));
+ }
+ tmp = ~((u64) 0);
+ for (cpu = 0; cpu < 4; cpu++) {
+ __raw_writeq(tmp, IOADDR(A_BCM1480_IMR_REGISTER(cpu, R_BCM1480_IMR_INTERRUPT_MASK_L)));
+ }
+
+ bcm1480_steal_irq(K_BCM1480_INT_MBOX_0_0);
+
+ /*
+ * Note that the timer interrupts are also mapped, but this is
+ * done in bcm1480_time_init(). Also, the profiling driver
+ * does its own management of IP7.
+ */
+
+#ifdef CONFIG_KGDB
+ imask |= STATUSF_IP6;
+#endif
+ /* Enable necessary IPs, disable the rest */
+ change_c0_status(ST0_IM, imask);
+ set_except_vector(0, bcm1480_irq_handler);
+
+#ifdef CONFIG_KGDB
+ if (kgdb_flag) {
+ kgdb_irq = K_BCM1480_INT_UART_0 + kgdb_port;
+
+#ifdef CONFIG_SIBYTE_SB1250_DUART
+ sb1250_duart_present[kgdb_port] = 0;
+#endif
+ /* Setup uart 1 settings, mapper */
+ /* QQQ FIXME */
+ __raw_writeq(M_DUART_IMR_BRK, IO_SPACE_BASE + A_DUART_IMRREG(kgdb_port));
+
+ bcm1480_steal_irq(kgdb_irq);
+ __raw_writeq(IMR_IP6_VAL,
+ IO_SPACE_BASE + A_BCM1480_IMR_REGISTER(0, R_BCM1480_IMR_INTERRUPT_MAP_BASE_H) +
+ (kgdb_irq<<3));
+ bcm1480_unmask_irq(0, kgdb_irq);
+
+#ifdef CONFIG_GDB_CONSOLE
+ register_gdb_console();
+#endif
+ prom_printf("Waiting for GDB on UART port %d\n", kgdb_port);
+ set_debug_traps();
+ breakpoint();
+ }
+#endif
+}
+
+#ifdef CONFIG_KGDB
+
+#include <linux/delay.h>
+
+#define duart_out(reg, val) csr_out32(val, IOADDR(A_DUART_CHANREG(kgdb_port,reg)))
+#define duart_in(reg) csr_in32(IOADDR(A_DUART_CHANREG(kgdb_port,reg)))
+
+void bcm1480_kgdb_interrupt(struct pt_regs *regs)
+{
+ /*
+ * Clear break-change status (allow some time for the remote
+ * host to stop the break, since we would see another
+ * interrupt on the end-of-break too)
+ */
+ kstat.irqs[smp_processor_id()][kgdb_irq]++;
+ mdelay(500);
+ duart_out(R_DUART_CMD, V_DUART_MISC_CMD_RESET_BREAK_INT |
+ M_DUART_RX_EN | M_DUART_TX_EN);
+ set_async_breakpoint(&regs->cp0_epc);
+}
+
+#endif /* CONFIG_KGDB */
diff --git a/arch/mips/sibyte/bcm1480/irq_handler.S b/arch/mips/sibyte/bcm1480/irq_handler.S
new file mode 100644
index 000000000000..408db88d050f
--- /dev/null
+++ b/arch/mips/sibyte/bcm1480/irq_handler.S
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2000,2001,2002,2003,2004 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; 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.
+ */
+
+/*
+ * bcm1480_irq_handler() is the routine that is actually called when an
+ * interrupt occurs. It is installed as the exception vector handler in
+ * init_IRQ() in arch/mips/sibyte/bcm1480/irq.c
+ *
+ * In the handle we figure out which interrupts need handling, and use that
+ * to call the dispatcher, which will take care of actually calling
+ * registered handlers
+ *
+ * Note that we take care of all raised interrupts in one go at the handler.
+ * This is more BSDish than the Indy code, and also, IMHO, more sane.
+ */
+#include <linux/config.h>
+
+#include <asm/addrspace.h>
+#include <asm/asm.h>
+#include <asm/mipsregs.h>
+#include <asm/regdef.h>
+#include <asm/stackframe.h>
+#include <asm/sibyte/sb1250_defs.h>
+#include <asm/sibyte/bcm1480_regs.h>
+#include <asm/sibyte/bcm1480_int.h>
+
+/*
+ * What a pain. We have to be really careful saving the upper 32 bits of any
+ * register across function calls if we don't want them trashed--since were
+ * running in -o32, the calling routing never saves the full 64 bits of a
+ * register across a function call. Being the interrupt handler, we're
+ * guaranteed that interrupts are disabled during this code so we don't have
+ * to worry about random interrupts blasting the high 32 bits.
+ */
+
+ .text
+ .set push
+ .set noreorder
+ .set noat
+ .set mips64
+ #.set mips4
+ .align 5
+ NESTED(bcm1480_irq_handler, PT_SIZE, sp)
+ SAVE_ALL
+ CLI
+
+#ifdef CONFIG_SIBYTE_BCM1480_PROF
+ /* Set compare to count to silence count/compare timer interrupts */
+ mfc0 t1, CP0_COUNT
+ mtc0 t1, CP0_COMPARE /* pause to clear IP[7] bit of cause ? */
+#endif
+ /* Read cause */
+ mfc0 s0, CP0_CAUSE
+
+#ifdef CONFIG_SIBYTE_BCM1480_PROF
+ /* Cpu performance counter interrupt is routed to IP[7] */
+ andi t1, s0, CAUSEF_IP7
+ beqz t1, 0f
+ srl t1, s0, (CAUSEB_BD-2) /* Shift BD bit to bit 2 */
+ and t1, t1, 0x4 /* mask to get just BD bit */
+#ifdef CONFIG_MIPS64
+ dmfc0 a0, CP0_EPC
+ daddu a0, a0, t1 /* a0 = EPC + (BD ? 4 : 0) */
+#else
+ mfc0 a0, CP0_EPC
+ addu a0, a0, t1 /* a0 = EPC + (BD ? 4 : 0) */
+#endif
+ jal sbprof_cpu_intr
+ nop
+ j ret_from_irq
+ nop
+0:
+#endif
+
+ /* Timer interrupt is routed to IP[4] */
+ andi t1, s0, CAUSEF_IP4
+ beqz t1, 1f
+ nop
+ jal bcm1480_timer_interrupt
+ move a0, sp /* Pass the registers along */
+ j ret_from_irq
+ nop /* delay slot */
+1:
+
+#ifdef CONFIG_SMP
+ /* Mailbox interrupt is routed to IP[3] */
+ andi t1, s0, CAUSEF_IP3
+ beqz t1, 2f
+ nop
+ jal bcm1480_mailbox_interrupt
+ move a0, sp
+ j ret_from_irq
+ nop /* delay slot */
+2:
+#endif
+
+#ifdef CONFIG_KGDB
+ /* KGDB (uart 1) interrupt is routed to IP[6] */
+ andi t1, s0, CAUSEF_IP6
+ beqz t1, 3f
+ nop /* delay slot */
+ jal bcm1480_kgdb_interrupt
+ move a0, sp
+ j ret_from_irq
+ nop /* delay slot */
+3:
+#endif
+
+ and t1, s0, CAUSEF_IP2
+ beqz t1, 9f
+ nop
+
+ /*
+ * Default...we've hit an IP[2] interrupt, which means we've got
+ * to check the 1480 interrupt registers to figure out what to do
+ * Need to detect which CPU we're on, now that smp_affinity is
+ * supported.
+ */
+ PTR_LA v0, CKSEG1 + A_BCM1480_IMR_CPU0_BASE
+#ifdef CONFIG_SMP
+ lw t1, TI_CPU($28)
+ sll t1, t1, BCM1480_IMR_REGISTER_SPACING_SHIFT
+ addu v0, v0, t1
+#endif
+
+ /* Read IP[2] status (get both high and low halves of status) */
+ ld s0, R_BCM1480_IMR_INTERRUPT_STATUS_BASE_H(v0)
+ ld s1, R_BCM1480_IMR_INTERRUPT_STATUS_BASE_L(v0)
+
+ move s2, zero /* intr number */
+ li s3, 64
+
+ beqz s0, 9f /* No interrupts. Return. */
+ move a1, sp
+
+ xori s4, s0, 1 /* if s0 (_H) == 1, it's a low intr, so... */
+ movz s2, s3, s4 /* start the intr number at 64, and */
+ movz s0, s1, s4 /* look at the low status value. */
+
+ dclz s1, s0 /* Find the next interrupt. */
+ dsubu a0, zero, s1
+ daddiu a0, a0, 63
+ jal do_IRQ
+ daddu a0, a0, s2
+
+9: j ret_from_irq
+ nop
+
+ .set pop
+ END(bcm1480_irq_handler)
diff --git a/arch/mips/sibyte/bcm1480/setup.c b/arch/mips/sibyte/bcm1480/setup.c
new file mode 100644
index 000000000000..d90a0b87874c
--- /dev/null
+++ b/arch/mips/sibyte/bcm1480/setup.c
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2000,2001,2002,2003,2004 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; 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/config.h>
+#include <linux/kernel.h>
+#include <linux/reboot.h>
+#include <linux/string.h>
+
+#include <asm/bootinfo.h>
+#include <asm/mipsregs.h>
+#include <asm/io.h>
+#include <asm/sibyte/sb1250.h>
+
+#include <asm/sibyte/bcm1480_regs.h>
+#include <asm/sibyte/bcm1480_scd.h>
+#include <asm/sibyte/sb1250_scd.h>
+
+unsigned int sb1_pass;
+unsigned int soc_pass;
+unsigned int soc_type;
+unsigned int periph_rev;
+unsigned int zbbus_mhz;
+
+static unsigned int part_type;
+
+static char *soc_str;
+static char *pass_str;
+
+static inline int setup_bcm1x80_bcm1x55(void);
+
+/* Setup code likely to be common to all SiByte platforms */
+
+static inline int sys_rev_decode(void)
+{
+ int ret = 0;
+
+ switch (soc_type) {
+ case K_SYS_SOC_TYPE_BCM1x80:
+ if (part_type == K_SYS_PART_BCM1480)
+ soc_str = "BCM1480";
+ else if (part_type == K_SYS_PART_BCM1280)
+ soc_str = "BCM1280";
+ else
+ soc_str = "BCM1x80";
+ ret = setup_bcm1x80_bcm1x55();
+ break;
+
+ case K_SYS_SOC_TYPE_BCM1x55:
+ if (part_type == K_SYS_PART_BCM1455)
+ soc_str = "BCM1455";
+ else if (part_type == K_SYS_PART_BCM1255)
+ soc_str = "BCM1255";
+ else
+ soc_str = "BCM1x55";
+ ret = setup_bcm1x80_bcm1x55();
+ break;
+
+ default:
+ prom_printf("Unknown part type %x\n", part_type);
+ ret = 1;
+ break;
+ }
+ return ret;
+}
+
+static inline int setup_bcm1x80_bcm1x55(void)
+{
+ int ret = 0;
+
+ switch (soc_pass) {
+ case K_SYS_REVISION_BCM1480_S0:
+ periph_rev = 1;
+ pass_str = "S0 (pass1)";
+ break;
+ case K_SYS_REVISION_BCM1480_A1:
+ periph_rev = 1;
+ pass_str = "A1 (pass1)";
+ break;
+ case K_SYS_REVISION_BCM1480_A2:
+ periph_rev = 1;
+ pass_str = "A2 (pass1)";
+ break;
+ case K_SYS_REVISION_BCM1480_A3:
+ periph_rev = 1;
+ pass_str = "A3 (pass1)";
+ break;
+ case K_SYS_REVISION_BCM1480_B0:
+ periph_rev = 1;
+ pass_str = "B0 (pass2)";
+ break;
+ default:
+ prom_printf("Unknown %s rev %x\n", soc_str, soc_pass);
+ periph_rev = 1;
+ pass_str = "Unknown Revision";
+ break;
+ }
+ return ret;
+}
+
+void bcm1480_setup(void)
+{
+ uint64_t sys_rev;
+ int plldiv;
+
+ sb1_pass = read_c0_prid() & 0xff;
+ sys_rev = __raw_readq(IOADDR(A_SCD_SYSTEM_REVISION));
+ soc_type = SYS_SOC_TYPE(sys_rev);
+ part_type = G_SYS_PART(sys_rev);
+ soc_pass = G_SYS_REVISION(sys_rev);
+
+ if (sys_rev_decode()) {
+ prom_printf("Restart after failure to identify SiByte chip\n");
+ machine_restart(NULL);
+ }
+
+ plldiv = G_BCM1480_SYS_PLL_DIV(__raw_readq(IOADDR(A_SCD_SYSTEM_CFG)));
+ zbbus_mhz = ((plldiv >> 1) * 50) + ((plldiv & 1) * 25);
+
+ prom_printf("Broadcom SiByte %s %s @ %d MHz (SB-1A rev %d)\n",
+ soc_str, pass_str, zbbus_mhz * 2, sb1_pass);
+ prom_printf("Board type: %s\n", get_system_type());
+}
diff --git a/arch/mips/sibyte/bcm1480/smp.c b/arch/mips/sibyte/bcm1480/smp.c
new file mode 100644
index 000000000000..584a4b33faac
--- /dev/null
+++ b/arch/mips/sibyte/bcm1480/smp.c
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2001,2002,2004 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; 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/init.h>
+#include <linux/delay.h>
+#include <linux/smp.h>
+#include <linux/kernel_stat.h>
+
+#include <asm/mmu_context.h>
+#include <asm/io.h>
+#include <asm/sibyte/sb1250.h>
+#include <asm/sibyte/bcm1480_regs.h>
+#include <asm/sibyte/bcm1480_int.h>
+
+extern void smp_call_function_interrupt(void);
+
+/*
+ * These are routines for dealing with the bcm1480 smp capabilities
+ * independent of board/firmware
+ */
+
+static void *mailbox_0_set_regs[] = {
+ IOADDR(A_BCM1480_IMR_CPU0_BASE + R_BCM1480_IMR_MAILBOX_0_SET_CPU),
+ IOADDR(A_BCM1480_IMR_CPU1_BASE + R_BCM1480_IMR_MAILBOX_0_SET_CPU),
+ IOADDR(A_BCM1480_IMR_CPU2_BASE + R_BCM1480_IMR_MAILBOX_0_SET_CPU),
+ IOADDR(A_BCM1480_IMR_CPU3_BASE + R_BCM1480_IMR_MAILBOX_0_SET_CPU),
+};
+
+static void *mailbox_0_clear_regs[] = {
+ IOADDR(A_BCM1480_IMR_CPU0_BASE + R_BCM1480_IMR_MAILBOX_0_CLR_CPU),
+ IOADDR(A_BCM1480_IMR_CPU1_BASE + R_BCM1480_IMR_MAILBOX_0_CLR_CPU),
+ IOADDR(A_BCM1480_IMR_CPU2_BASE + R_BCM1480_IMR_MAILBOX_0_CLR_CPU),
+ IOADDR(A_BCM1480_IMR_CPU3_BASE + R_BCM1480_IMR_MAILBOX_0_CLR_CPU),
+};
+
+static void *mailbox_0_regs[] = {
+ IOADDR(A_BCM1480_IMR_CPU0_BASE + R_BCM1480_IMR_MAILBOX_0_CPU),
+ IOADDR(A_BCM1480_IMR_CPU1_BASE + R_BCM1480_IMR_MAILBOX_0_CPU),
+ IOADDR(A_BCM1480_IMR_CPU2_BASE + R_BCM1480_IMR_MAILBOX_0_CPU),
+ IOADDR(A_BCM1480_IMR_CPU3_BASE + R_BCM1480_IMR_MAILBOX_0_CPU),
+};
+
+/*
+ * SMP init and finish on secondary CPUs
+ */
+void bcm1480_smp_init(void)
+{
+ unsigned int imask = STATUSF_IP4 | STATUSF_IP3 | STATUSF_IP2 |
+ STATUSF_IP1 | STATUSF_IP0;
+
+ /* Set interrupt mask, but don't enable */
+ change_c0_status(ST0_IM, imask);
+}
+
+void bcm1480_smp_finish(void)
+{
+ extern void bcm1480_time_init(void);
+ bcm1480_time_init();
+ local_irq_enable();
+}
+
+/*
+ * These are routines for dealing with the sb1250 smp capabilities
+ * independent of board/firmware
+ */
+
+/*
+ * Simple enough; everything is set up, so just poke the appropriate mailbox
+ * register, and we should be set
+ */
+void core_send_ipi(int cpu, unsigned int action)
+{
+ __raw_writeq((((u64)action)<< 48), mailbox_0_set_regs[cpu]);
+}
+
+void bcm1480_mailbox_interrupt(struct pt_regs *regs)
+{
+ int cpu = smp_processor_id();
+ unsigned int action;
+
+ kstat_this_cpu.irqs[K_BCM1480_INT_MBOX_0_0]++;
+ /* Load the mailbox register to figure out what we're supposed to do */
+ action = (__raw_readq(mailbox_0_regs[cpu]) >> 48) & 0xffff;
+
+ /* Clear the mailbox to clear the interrupt */
+ __raw_writeq(((u64)action)<<48, mailbox_0_clear_regs[cpu]);
+
+ /*
+ * Nothing to do for SMP_RESCHEDULE_YOURSELF; returning from the
+ * interrupt will do the reschedule for us
+ */
+
+ if (action & SMP_CALL_FUNCTION)
+ smp_call_function_interrupt();
+}
diff --git a/arch/mips/sibyte/bcm1480/time.c b/arch/mips/sibyte/bcm1480/time.c
new file mode 100644
index 000000000000..e545752695a1
--- /dev/null
+++ b/arch/mips/sibyte/bcm1480/time.c
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2000,2001,2004 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; 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.
+ */
+
+/*
+ * These are routines to set up and handle interrupts from the
+ * bcm1480 general purpose timer 0. We're using the timer as a
+ * system clock, so we set it up to run at 100 Hz. On every
+ * interrupt, we update our idea of what the time of day is,
+ * then call do_timer() in the architecture-independent kernel
+ * code to do general bookkeeping (e.g. update jiffies, run
+ * bottom halves, etc.)
+ */
+#include <linux/config.h>
+#include <linux/interrupt.h>
+#include <linux/sched.h>
+#include <linux/spinlock.h>
+#include <linux/kernel_stat.h>
+
+#include <asm/irq.h>
+#include <asm/ptrace.h>
+#include <asm/addrspace.h>
+#include <asm/time.h>
+#include <asm/io.h>
+
+#include <asm/sibyte/bcm1480_regs.h>
+#include <asm/sibyte/sb1250_regs.h>
+#include <asm/sibyte/bcm1480_int.h>
+#include <asm/sibyte/bcm1480_scd.h>
+
+#include <asm/sibyte/sb1250.h>
+
+
+#define IMR_IP2_VAL K_BCM1480_INT_MAP_I0
+#define IMR_IP3_VAL K_BCM1480_INT_MAP_I1
+#define IMR_IP4_VAL K_BCM1480_INT_MAP_I2
+
+extern int bcm1480_steal_irq(int irq);
+
+void bcm1480_time_init(void)
+{
+ int cpu = smp_processor_id();
+ int irq = K_BCM1480_INT_TIMER_0+cpu;
+
+ /* Only have 4 general purpose timers */
+ if (cpu > 3) {
+ BUG();
+ }
+
+ if (!cpu) {
+ /* Use our own gettimeoffset() routine */
+ do_gettimeoffset = bcm1480_gettimeoffset;
+ }
+
+ bcm1480_mask_irq(cpu, irq);
+
+ /* Map the timer interrupt to ip[4] of this cpu */
+ __raw_writeq(IMR_IP4_VAL, IOADDR(A_BCM1480_IMR_REGISTER(cpu, R_BCM1480_IMR_INTERRUPT_MAP_BASE_H)
+ + (irq<<3)));
+
+ /* the general purpose timer ticks at 1 Mhz independent of the rest of the system */
+ /* Disable the timer and set up the count */
+ __raw_writeq(0, IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG)));
+ __raw_writeq(
+#ifndef CONFIG_SIMULATION
+ 1000000/HZ
+#else
+ 50000/HZ
+#endif
+ , IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_INIT)));
+
+ /* Set the timer running */
+ __raw_writeq(M_SCD_TIMER_ENABLE|M_SCD_TIMER_MODE_CONTINUOUS,
+ IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG)));
+
+ bcm1480_unmask_irq(cpu, irq);
+ bcm1480_steal_irq(irq);
+ /*
+ * This interrupt is "special" in that it doesn't use the request_irq
+ * way to hook the irq line. The timer interrupt is initialized early
+ * enough to make this a major pain, and it's also firing enough to
+ * warrant a bit of special case code. bcm1480_timer_interrupt is
+ * called directly from irq_handler.S when IP[4] is set during an
+ * interrupt
+ */
+}
+
+#include <asm/sibyte/sb1250.h>
+
+void bcm1480_timer_interrupt(struct pt_regs *regs)
+{
+ int cpu = smp_processor_id();
+ int irq = K_BCM1480_INT_TIMER_0+cpu;
+
+ /* Reset the timer */
+ __raw_writeq(M_SCD_TIMER_ENABLE|M_SCD_TIMER_MODE_CONTINUOUS,
+ IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG)));
+
+ /*
+ * CPU 0 handles the global timer interrupt job
+ */
+ if (cpu == 0) {
+ ll_timer_interrupt(irq, regs);
+ }
+
+ /*
+ * every CPU should do profiling and process accouting
+ */
+ ll_local_timer_interrupt(irq, regs);
+}
+
+/*
+ * We use our own do_gettimeoffset() instead of the generic one,
+ * because the generic one does not work for SMP case.
+ * In addition, since we use general timer 0 for system time,
+ * we can get accurate intra-jiffy offset without calibration.
+ */
+unsigned long bcm1480_gettimeoffset(void)
+{
+ unsigned long count =
+ __raw_readq(IOADDR(A_SCD_TIMER_REGISTER(0, R_SCD_TIMER_CNT)));
+
+ return 1000000/HZ - count;
+}
diff --git a/arch/mips/sibyte/cfe/smp.c b/arch/mips/sibyte/cfe/smp.c
index e44ce1a9eea9..e8485124b8fc 100644
--- a/arch/mips/sibyte/cfe/smp.c
+++ b/arch/mips/sibyte/cfe/smp.c
@@ -70,8 +70,15 @@ void prom_boot_secondary(int cpu, struct task_struct *idle)
*/
void prom_init_secondary(void)
{
+#if defined(CONFIG_SIBYTE_BCM1x55) || defined(CONFIG_SIBYTE_BCM1x80)
+ extern void bcm1480_smp_init(void);
+ bcm1480_smp_init();
+#elif defined(CONFIG_SIBYTE_SB1250)
extern void sb1250_smp_init(void);
sb1250_smp_init();
+#else
+#error invalid SMP configuration
+#endif
}
/*
@@ -80,8 +87,15 @@ void prom_init_secondary(void)
*/
void prom_smp_finish(void)
{
+#if defined(CONFIG_SIBYTE_BCM1x55) || defined(CONFIG_SIBYTE_BCM1x80)
+ extern void bcm1480_smp_finish(void);
+ bcm1480_smp_finish();
+#elif defined(CONFIG_SIBYTE_SB1250)
extern void sb1250_smp_finish(void);
sb1250_smp_finish();
+#else
+#error invalid SMP configuration
+#endif
}
/*
diff --git a/arch/mips/sibyte/sb1250/bcm1250_tbprof.c b/arch/mips/sibyte/sb1250/bcm1250_tbprof.c
index 7f813ae9eaff..992e0d8dbb67 100644
--- a/arch/mips/sibyte/sb1250/bcm1250_tbprof.c
+++ b/arch/mips/sibyte/sb1250/bcm1250_tbprof.c
@@ -28,6 +28,8 @@
#include <linux/fs.h>
#include <linux/errno.h>
#include <linux/reboot.h>
+#include <linux/smp_lock.h>
+#include <linux/wait.h>
#include <asm/uaccess.h>
#include <asm/io.h>
#include <asm/sibyte/sb1250.h>
@@ -64,24 +66,25 @@ static void arm_tb(void)
u_int64_t tb_options = M_SCD_TRACE_CFG_FREEZE_FULL;
/* Generate an SCD_PERFCNT interrupt in TB_PERIOD Zclks to
trigger start of trace. XXX vary sampling period */
- bus_writeq(0, IOADDR(A_SCD_PERF_CNT_1));
- scdperfcnt = bus_readq(IOADDR(A_SCD_PERF_CNT_CFG));
+ __raw_writeq(0, IOADDR(A_SCD_PERF_CNT_1));
+ scdperfcnt = __raw_readq(IOADDR(A_SCD_PERF_CNT_CFG));
/* Unfortunately, in Pass 2 we must clear all counters to knock down
a previous interrupt request. This means that bus profiling
requires ALL of the SCD perf counters. */
- bus_writeq((scdperfcnt & ~M_SPC_CFG_SRC1) | // keep counters 0,2,3 as is
- M_SPC_CFG_ENABLE | // enable counting
- M_SPC_CFG_CLEAR | // clear all counters
- V_SPC_CFG_SRC1(1), // counter 1 counts cycles
- IOADDR(A_SCD_PERF_CNT_CFG));
- bus_writeq(next, IOADDR(A_SCD_PERF_CNT_1));
+ __raw_writeq((scdperfcnt & ~M_SPC_CFG_SRC1) |
+ // keep counters 0,2,3 as is
+ M_SPC_CFG_ENABLE | // enable counting
+ M_SPC_CFG_CLEAR | // clear all counters
+ V_SPC_CFG_SRC1(1), // counter 1 counts cycles
+ IOADDR(A_SCD_PERF_CNT_CFG));
+ __raw_writeq(next, IOADDR(A_SCD_PERF_CNT_1));
/* Reset the trace buffer */
- bus_writeq(M_SCD_TRACE_CFG_RESET, IOADDR(A_SCD_TRACE_CFG));
+ __raw_writeq(M_SCD_TRACE_CFG_RESET, IOADDR(A_SCD_TRACE_CFG));
#if 0 && defined(M_SCD_TRACE_CFG_FORCECNT)
/* XXXKW may want to expose control to the data-collector */
tb_options |= M_SCD_TRACE_CFG_FORCECNT;
#endif
- bus_writeq(tb_options, IOADDR(A_SCD_TRACE_CFG));
+ __raw_writeq(tb_options, IOADDR(A_SCD_TRACE_CFG));
sbp.tb_armed = 1;
}
@@ -93,23 +96,30 @@ static irqreturn_t sbprof_tb_intr(int irq, void *dev_id, struct pt_regs *regs)
/* XXX should use XKPHYS to make writes bypass L2 */
u_int64_t *p = sbp.sbprof_tbbuf[sbp.next_tb_sample++];
/* Read out trace */
- bus_writeq(M_SCD_TRACE_CFG_START_READ, IOADDR(A_SCD_TRACE_CFG));
+ __raw_writeq(M_SCD_TRACE_CFG_START_READ,
+ IOADDR(A_SCD_TRACE_CFG));
__asm__ __volatile__ ("sync" : : : "memory");
/* Loop runs backwards because bundles are read out in reverse order */
for (i = 256 * 6; i > 0; i -= 6) {
// Subscripts decrease to put bundle in the order
// t0 lo, t0 hi, t1 lo, t1 hi, t2 lo, t2 hi
- p[i-1] = bus_readq(IOADDR(A_SCD_TRACE_READ)); // read t2 hi
- p[i-2] = bus_readq(IOADDR(A_SCD_TRACE_READ)); // read t2 lo
- p[i-3] = bus_readq(IOADDR(A_SCD_TRACE_READ)); // read t1 hi
- p[i-4] = bus_readq(IOADDR(A_SCD_TRACE_READ)); // read t1 lo
- p[i-5] = bus_readq(IOADDR(A_SCD_TRACE_READ)); // read t0 hi
- p[i-6] = bus_readq(IOADDR(A_SCD_TRACE_READ)); // read t0 lo
+ p[i - 1] = __raw_readq(IOADDR(A_SCD_TRACE_READ));
+ // read t2 hi
+ p[i - 2] = __raw_readq(IOADDR(A_SCD_TRACE_READ));
+ // read t2 lo
+ p[i - 3] = __raw_readq(IOADDR(A_SCD_TRACE_READ));
+ // read t1 hi
+ p[i - 4] = __raw_readq(IOADDR(A_SCD_TRACE_READ));
+ // read t1 lo
+ p[i - 5] = __raw_readq(IOADDR(A_SCD_TRACE_READ));
+ // read t0 hi
+ p[i - 6] = __raw_readq(IOADDR(A_SCD_TRACE_READ));
+ // read t0 lo
}
if (!sbp.tb_enable) {
DBG(printk(DEVNAME ": tb_intr shutdown\n"));
- bus_writeq(M_SCD_TRACE_CFG_RESET,
- IOADDR(A_SCD_TRACE_CFG));
+ __raw_writeq(M_SCD_TRACE_CFG_RESET,
+ IOADDR(A_SCD_TRACE_CFG));
sbp.tb_armed = 0;
wake_up(&sbp.tb_sync);
} else {
@@ -118,7 +128,7 @@ static irqreturn_t sbprof_tb_intr(int irq, void *dev_id, struct pt_regs *regs)
} else {
/* No more trace buffer samples */
DBG(printk(DEVNAME ": tb_intr full\n"));
- bus_writeq(M_SCD_TRACE_CFG_RESET, IOADDR(A_SCD_TRACE_CFG));
+ __raw_writeq(M_SCD_TRACE_CFG_RESET, IOADDR(A_SCD_TRACE_CFG));
sbp.tb_armed = 0;
if (!sbp.tb_enable) {
wake_up(&sbp.tb_sync);
@@ -152,13 +162,11 @@ int sbprof_zbprof_start(struct file *filp)
return -EBUSY;
}
/* Make sure there isn't a perf-cnt interrupt waiting */
- scdperfcnt = bus_readq(IOADDR(A_SCD_PERF_CNT_CFG));
+ scdperfcnt = __raw_readq(IOADDR(A_SCD_PERF_CNT_CFG));
/* Disable and clear counters, override SRC_1 */
- bus_writeq((scdperfcnt & ~(M_SPC_CFG_SRC1 | M_SPC_CFG_ENABLE)) |
- M_SPC_CFG_ENABLE |
- M_SPC_CFG_CLEAR |
- V_SPC_CFG_SRC1(1),
- IOADDR(A_SCD_PERF_CNT_CFG));
+ __raw_writeq((scdperfcnt & ~(M_SPC_CFG_SRC1 | M_SPC_CFG_ENABLE)) |
+ M_SPC_CFG_ENABLE | M_SPC_CFG_CLEAR | V_SPC_CFG_SRC1(1),
+ IOADDR(A_SCD_PERF_CNT_CFG));
/* We grab this interrupt to prevent others from trying to use
it, even though we don't want to service the interrupts
@@ -172,55 +180,55 @@ int sbprof_zbprof_start(struct file *filp)
/* I need the core to mask these, but the interrupt mapper to
pass them through. I am exploiting my knowledge that
cp0_status masks out IP[5]. krw */
- bus_writeq(K_INT_MAP_I3,
- IOADDR(A_IMR_REGISTER(0, R_IMR_INTERRUPT_MAP_BASE) +
- (K_INT_PERF_CNT << 3)));
+ __raw_writeq(K_INT_MAP_I3,
+ IOADDR(A_IMR_REGISTER(0, R_IMR_INTERRUPT_MAP_BASE) +
+ (K_INT_PERF_CNT << 3)));
/* Initialize address traps */
- bus_writeq(0, IOADDR(A_ADDR_TRAP_UP_0));
- bus_writeq(0, IOADDR(A_ADDR_TRAP_UP_1));
- bus_writeq(0, IOADDR(A_ADDR_TRAP_UP_2));
- bus_writeq(0, IOADDR(A_ADDR_TRAP_UP_3));
+ __raw_writeq(0, IOADDR(A_ADDR_TRAP_UP_0));
+ __raw_writeq(0, IOADDR(A_ADDR_TRAP_UP_1));
+ __raw_writeq(0, IOADDR(A_ADDR_TRAP_UP_2));
+ __raw_writeq(0, IOADDR(A_ADDR_TRAP_UP_3));
- bus_writeq(0, IOADDR(A_ADDR_TRAP_DOWN_0));
- bus_writeq(0, IOADDR(A_ADDR_TRAP_DOWN_1));
- bus_writeq(0, IOADDR(A_ADDR_TRAP_DOWN_2));
- bus_writeq(0, IOADDR(A_ADDR_TRAP_DOWN_3));
+ __raw_writeq(0, IOADDR(A_ADDR_TRAP_DOWN_0));
+ __raw_writeq(0, IOADDR(A_ADDR_TRAP_DOWN_1));
+ __raw_writeq(0, IOADDR(A_ADDR_TRAP_DOWN_2));
+ __raw_writeq(0, IOADDR(A_ADDR_TRAP_DOWN_3));
- bus_writeq(0, IOADDR(A_ADDR_TRAP_CFG_0));
- bus_writeq(0, IOADDR(A_ADDR_TRAP_CFG_1));
- bus_writeq(0, IOADDR(A_ADDR_TRAP_CFG_2));
- bus_writeq(0, IOADDR(A_ADDR_TRAP_CFG_3));
+ __raw_writeq(0, IOADDR(A_ADDR_TRAP_CFG_0));
+ __raw_writeq(0, IOADDR(A_ADDR_TRAP_CFG_1));
+ __raw_writeq(0, IOADDR(A_ADDR_TRAP_CFG_2));
+ __raw_writeq(0, IOADDR(A_ADDR_TRAP_CFG_3));
/* Initialize Trace Event 0-7 */
// when interrupt
- bus_writeq(M_SCD_TREVT_INTERRUPT, IOADDR(A_SCD_TRACE_EVENT_0));
- bus_writeq(0, IOADDR(A_SCD_TRACE_EVENT_1));
- bus_writeq(0, IOADDR(A_SCD_TRACE_EVENT_2));
- bus_writeq(0, IOADDR(A_SCD_TRACE_EVENT_3));
- bus_writeq(0, IOADDR(A_SCD_TRACE_EVENT_4));
- bus_writeq(0, IOADDR(A_SCD_TRACE_EVENT_5));
- bus_writeq(0, IOADDR(A_SCD_TRACE_EVENT_6));
- bus_writeq(0, IOADDR(A_SCD_TRACE_EVENT_7));
+ __raw_writeq(M_SCD_TREVT_INTERRUPT, IOADDR(A_SCD_TRACE_EVENT_0));
+ __raw_writeq(0, IOADDR(A_SCD_TRACE_EVENT_1));
+ __raw_writeq(0, IOADDR(A_SCD_TRACE_EVENT_2));
+ __raw_writeq(0, IOADDR(A_SCD_TRACE_EVENT_3));
+ __raw_writeq(0, IOADDR(A_SCD_TRACE_EVENT_4));
+ __raw_writeq(0, IOADDR(A_SCD_TRACE_EVENT_5));
+ __raw_writeq(0, IOADDR(A_SCD_TRACE_EVENT_6));
+ __raw_writeq(0, IOADDR(A_SCD_TRACE_EVENT_7));
/* Initialize Trace Sequence 0-7 */
// Start on event 0 (interrupt)
- bus_writeq(V_SCD_TRSEQ_FUNC_START | 0x0fff,
- IOADDR(A_SCD_TRACE_SEQUENCE_0));
+ __raw_writeq(V_SCD_TRSEQ_FUNC_START | 0x0fff,
+ IOADDR(A_SCD_TRACE_SEQUENCE_0));
// dsamp when d used | asamp when a used
- bus_writeq(M_SCD_TRSEQ_ASAMPLE | M_SCD_TRSEQ_DSAMPLE |
- K_SCD_TRSEQ_TRIGGER_ALL,
- IOADDR(A_SCD_TRACE_SEQUENCE_1));
- bus_writeq(0, IOADDR(A_SCD_TRACE_SEQUENCE_2));
- bus_writeq(0, IOADDR(A_SCD_TRACE_SEQUENCE_3));
- bus_writeq(0, IOADDR(A_SCD_TRACE_SEQUENCE_4));
- bus_writeq(0, IOADDR(A_SCD_TRACE_SEQUENCE_5));
- bus_writeq(0, IOADDR(A_SCD_TRACE_SEQUENCE_6));
- bus_writeq(0, IOADDR(A_SCD_TRACE_SEQUENCE_7));
+ __raw_writeq(M_SCD_TRSEQ_ASAMPLE | M_SCD_TRSEQ_DSAMPLE |
+ K_SCD_TRSEQ_TRIGGER_ALL,
+ IOADDR(A_SCD_TRACE_SEQUENCE_1));
+ __raw_writeq(0, IOADDR(A_SCD_TRACE_SEQUENCE_2));
+ __raw_writeq(0, IOADDR(A_SCD_TRACE_SEQUENCE_3));
+ __raw_writeq(0, IOADDR(A_SCD_TRACE_SEQUENCE_4));
+ __raw_writeq(0, IOADDR(A_SCD_TRACE_SEQUENCE_5));
+ __raw_writeq(0, IOADDR(A_SCD_TRACE_SEQUENCE_6));
+ __raw_writeq(0, IOADDR(A_SCD_TRACE_SEQUENCE_7));
/* Now indicate the PERF_CNT interrupt as a trace-relevant interrupt */
- bus_writeq((1ULL << K_INT_PERF_CNT),
- IOADDR(A_IMR_REGISTER(0, R_IMR_INTERRUPT_TRACE)));
+ __raw_writeq(1ULL << K_INT_PERF_CNT,
+ IOADDR(A_IMR_REGISTER(0, R_IMR_INTERRUPT_TRACE)));
arm_tb();
@@ -231,6 +239,7 @@ int sbprof_zbprof_start(struct file *filp)
int sbprof_zbprof_stop(void)
{
+ DEFINE_WAIT(wait);
DBG(printk(DEVNAME ": stopping\n"));
if (sbp.tb_enable) {
@@ -240,7 +249,9 @@ int sbprof_zbprof_stop(void)
this sleep happens. */
if (sbp.tb_armed) {
DBG(printk(DEVNAME ": wait for disarm\n"));
- interruptible_sleep_on(&sbp.tb_sync);
+ prepare_to_wait(&sbp.tb_sync, &wait, TASK_INTERRUPTIBLE);
+ schedule();
+ finish_wait(&sbp.tb_sync, &wait);
DBG(printk(DEVNAME ": disarm complete\n"));
}
free_irq(K_INT_TRACE_FREEZE, &sbp);
@@ -333,13 +344,13 @@ static ssize_t sbprof_tb_read(struct file *filp, char *buf,
return count;
}
-static int sbprof_tb_ioctl(struct inode *inode,
- struct file *filp,
- unsigned int command,
- unsigned long arg)
+static long sbprof_tb_ioctl(struct file *filp,
+ unsigned int command,
+ unsigned long arg)
{
int error = 0;
+ lock_kernel();
switch (command) {
case SBPROF_ZBSTART:
error = sbprof_zbprof_start(filp);
@@ -348,13 +359,17 @@ static int sbprof_tb_ioctl(struct inode *inode,
error = sbprof_zbprof_stop();
break;
case SBPROF_ZBWAITFULL:
- interruptible_sleep_on(&sbp.tb_read);
+ DEFINE_WAIT(wait);
+ prepare_to_wait(&sbp.tb_read, &wait, TASK_INTERRUPTIBLE);
+ schedule();
+ finish_wait(&sbp.tb_read, &wait);
/* XXXKW check if interrupted? */
return put_user(TB_FULL, (int *) arg);
default:
error = -EINVAL;
break;
}
+ unlock_kernel();
return error;
}
@@ -364,7 +379,8 @@ static struct file_operations sbprof_tb_fops = {
.open = sbprof_tb_open,
.release = sbprof_tb_release,
.read = sbprof_tb_read,
- .ioctl = sbprof_tb_ioctl,
+ .unlocked_ioctl = sbprof_tb_ioctl,
+ .compat_ioctl = sbprof_tb_ioctl,
.mmap = NULL,
};
diff --git a/arch/mips/sibyte/sb1250/bus_watcher.c b/arch/mips/sibyte/sb1250/bus_watcher.c
index 1a97e3127aeb..482dee054e68 100644
--- a/arch/mips/sibyte/sb1250/bus_watcher.c
+++ b/arch/mips/sibyte/sb1250/bus_watcher.c
@@ -189,7 +189,7 @@ static irqreturn_t sibyte_bw_int(int irq, void *data, struct pt_regs *regs)
for (i=0; i<256*6; i++)
printk("%016llx\n",
- (unsigned long long)bus_readq(IOADDR(A_SCD_TRACE_READ)));
+ (long long)__raw_readq(IOADDR(A_SCD_TRACE_READ)));
csr_out32(M_SCD_TRACE_CFG_RESET, IOADDR(A_SCD_TRACE_CFG));
csr_out32(M_SCD_TRACE_CFG_START, IOADDR(A_SCD_TRACE_CFG));
diff --git a/arch/mips/sibyte/sb1250/irq.c b/arch/mips/sibyte/sb1250/irq.c
index 2725b263cced..589537bfcc3d 100644
--- a/arch/mips/sibyte/sb1250/irq.c
+++ b/arch/mips/sibyte/sb1250/irq.c
@@ -53,7 +53,7 @@ static void disable_sb1250_irq(unsigned int irq);
static unsigned int startup_sb1250_irq(unsigned int irq);
static void ack_sb1250_irq(unsigned int irq);
#ifdef CONFIG_SMP
-static void sb1250_set_affinity(unsigned int irq, unsigned long mask);
+static void sb1250_set_affinity(unsigned int irq, cpumask_t mask);
#endif
#ifdef CONFIG_SIBYTE_HAS_LDT
@@ -71,17 +71,15 @@ extern char sb1250_duart_present[];
#endif
static struct hw_interrupt_type sb1250_irq_type = {
- "SB1250-IMR",
- startup_sb1250_irq,
- shutdown_sb1250_irq,
- enable_sb1250_irq,
- disable_sb1250_irq,
- ack_sb1250_irq,
- end_sb1250_irq,
+ .typename = "SB1250-IMR",
+ .startup = startup_sb1250_irq,
+ .shutdown = shutdown_sb1250_irq,
+ .enable = enable_sb1250_irq,
+ .disable = disable_sb1250_irq,
+ .ack = ack_sb1250_irq,
+ .end = end_sb1250_irq,
#ifdef CONFIG_SMP
- sb1250_set_affinity
-#else
- NULL
+ .set_affinity = sb1250_set_affinity
#endif
};
@@ -96,11 +94,11 @@ void sb1250_mask_irq(int cpu, int irq)
u64 cur_ints;
spin_lock_irqsave(&sb1250_imr_lock, flags);
- cur_ints = __bus_readq(IOADDR(A_IMR_MAPPER(cpu) +
- R_IMR_INTERRUPT_MASK));
+ cur_ints = ____raw_readq(IOADDR(A_IMR_MAPPER(cpu) +
+ R_IMR_INTERRUPT_MASK));
cur_ints |= (((u64) 1) << irq);
- __bus_writeq(cur_ints, IOADDR(A_IMR_MAPPER(cpu) +
- R_IMR_INTERRUPT_MASK));
+ ____raw_writeq(cur_ints, IOADDR(A_IMR_MAPPER(cpu) +
+ R_IMR_INTERRUPT_MASK));
spin_unlock_irqrestore(&sb1250_imr_lock, flags);
}
@@ -110,32 +108,25 @@ void sb1250_unmask_irq(int cpu, int irq)
u64 cur_ints;
spin_lock_irqsave(&sb1250_imr_lock, flags);
- cur_ints = __bus_readq(IOADDR(A_IMR_MAPPER(cpu) +
- R_IMR_INTERRUPT_MASK));
+ cur_ints = ____raw_readq(IOADDR(A_IMR_MAPPER(cpu) +
+ R_IMR_INTERRUPT_MASK));
cur_ints &= ~(((u64) 1) << irq);
- __bus_writeq(cur_ints, IOADDR(A_IMR_MAPPER(cpu) +
- R_IMR_INTERRUPT_MASK));
+ ____raw_writeq(cur_ints, IOADDR(A_IMR_MAPPER(cpu) +
+ R_IMR_INTERRUPT_MASK));
spin_unlock_irqrestore(&sb1250_imr_lock, flags);
}
#ifdef CONFIG_SMP
-static void sb1250_set_affinity(unsigned int irq, unsigned long mask)
+static void sb1250_set_affinity(unsigned int irq, cpumask_t mask)
{
int i = 0, old_cpu, cpu, int_on;
u64 cur_ints;
irq_desc_t *desc = irq_desc + irq;
unsigned long flags;
- while (mask) {
- if (mask & 1) {
- mask >>= 1;
- break;
- }
- mask >>= 1;
- i++;
- }
+ i = first_cpu(mask);
- if (mask) {
+ if (cpus_weight(mask) > 1) {
printk("attempted to set irq affinity for irq %d to multiple CPUs\n", irq);
return;
}
@@ -149,23 +140,23 @@ static void sb1250_set_affinity(unsigned int irq, unsigned long mask)
/* Swizzle each CPU's IMR (but leave the IP selection alone) */
old_cpu = sb1250_irq_owner[irq];
- cur_ints = __bus_readq(IOADDR(A_IMR_MAPPER(old_cpu) +
- R_IMR_INTERRUPT_MASK));
+ cur_ints = ____raw_readq(IOADDR(A_IMR_MAPPER(old_cpu) +
+ R_IMR_INTERRUPT_MASK));
int_on = !(cur_ints & (((u64) 1) << irq));
if (int_on) {
/* If it was on, mask it */
cur_ints |= (((u64) 1) << irq);
- __bus_writeq(cur_ints, IOADDR(A_IMR_MAPPER(old_cpu) +
- R_IMR_INTERRUPT_MASK));
+ ____raw_writeq(cur_ints, IOADDR(A_IMR_MAPPER(old_cpu) +
+ R_IMR_INTERRUPT_MASK));
}
sb1250_irq_owner[irq] = cpu;
if (int_on) {
/* unmask for the new CPU */
- cur_ints = __bus_readq(IOADDR(A_IMR_MAPPER(cpu) +
- R_IMR_INTERRUPT_MASK));
+ cur_ints = ____raw_readq(IOADDR(A_IMR_MAPPER(cpu) +
+ R_IMR_INTERRUPT_MASK));
cur_ints &= ~(((u64) 1) << irq);
- __bus_writeq(cur_ints, IOADDR(A_IMR_MAPPER(cpu) +
- R_IMR_INTERRUPT_MASK));
+ ____raw_writeq(cur_ints, IOADDR(A_IMR_MAPPER(cpu) +
+ R_IMR_INTERRUPT_MASK));
}
spin_unlock(&sb1250_imr_lock);
spin_unlock_irqrestore(&desc->lock, flags);
@@ -208,8 +199,8 @@ static void ack_sb1250_irq(unsigned int irq)
* deliver the interrupts to all CPUs (which makes affinity
* changing easier for us)
*/
- pending = bus_readq(IOADDR(A_IMR_REGISTER(sb1250_irq_owner[irq],
- R_IMR_LDT_INTERRUPT)));
+ pending = __raw_readq(IOADDR(A_IMR_REGISTER(sb1250_irq_owner[irq],
+ R_IMR_LDT_INTERRUPT)));
pending &= ((u64)1 << (irq));
if (pending) {
int i;
@@ -224,8 +215,8 @@ static void ack_sb1250_irq(unsigned int irq)
* Clear for all CPUs so an affinity switch
* doesn't find an old status
*/
- bus_writeq(pending,
- IOADDR(A_IMR_REGISTER(cpu,
+ __raw_writeq(pending,
+ IOADDR(A_IMR_REGISTER(cpu,
R_IMR_LDT_INTERRUPT_CLR)));
}
@@ -340,12 +331,14 @@ void __init arch_init_irq(void)
/* Default everything to IP2 */
for (i = 0; i < SB1250_NR_IRQS; i++) { /* was I0 */
- bus_writeq(IMR_IP2_VAL,
- IOADDR(A_IMR_REGISTER(0, R_IMR_INTERRUPT_MAP_BASE) +
- (i << 3)));
- bus_writeq(IMR_IP2_VAL,
- IOADDR(A_IMR_REGISTER(1, R_IMR_INTERRUPT_MAP_BASE) +
- (i << 3)));
+ __raw_writeq(IMR_IP2_VAL,
+ IOADDR(A_IMR_REGISTER(0,
+ R_IMR_INTERRUPT_MAP_BASE) +
+ (i << 3)));
+ __raw_writeq(IMR_IP2_VAL,
+ IOADDR(A_IMR_REGISTER(1,
+ R_IMR_INTERRUPT_MAP_BASE) +
+ (i << 3)));
}
init_sb1250_irqs();
@@ -355,23 +348,23 @@ void __init arch_init_irq(void)
* inter-cpu messages
*/
/* Was I1 */
- bus_writeq(IMR_IP3_VAL,
- IOADDR(A_IMR_REGISTER(0, R_IMR_INTERRUPT_MAP_BASE) +
- (K_INT_MBOX_0 << 3)));
- bus_writeq(IMR_IP3_VAL,
- IOADDR(A_IMR_REGISTER(1, R_IMR_INTERRUPT_MAP_BASE) +
- (K_INT_MBOX_0 << 3)));
+ __raw_writeq(IMR_IP3_VAL,
+ IOADDR(A_IMR_REGISTER(0, R_IMR_INTERRUPT_MAP_BASE) +
+ (K_INT_MBOX_0 << 3)));
+ __raw_writeq(IMR_IP3_VAL,
+ IOADDR(A_IMR_REGISTER(1, R_IMR_INTERRUPT_MAP_BASE) +
+ (K_INT_MBOX_0 << 3)));
/* Clear the mailboxes. The firmware may leave them dirty */
- bus_writeq(0xffffffffffffffffULL,
- IOADDR(A_IMR_REGISTER(0, R_IMR_MAILBOX_CLR_CPU)));
- bus_writeq(0xffffffffffffffffULL,
- IOADDR(A_IMR_REGISTER(1, R_IMR_MAILBOX_CLR_CPU)));
+ __raw_writeq(0xffffffffffffffffULL,
+ IOADDR(A_IMR_REGISTER(0, R_IMR_MAILBOX_CLR_CPU)));
+ __raw_writeq(0xffffffffffffffffULL,
+ IOADDR(A_IMR_REGISTER(1, R_IMR_MAILBOX_CLR_CPU)));
/* Mask everything except the mailbox registers for both cpus */
tmp = ~((u64) 0) ^ (((u64) 1) << K_INT_MBOX_0);
- bus_writeq(tmp, IOADDR(A_IMR_REGISTER(0, R_IMR_INTERRUPT_MASK)));
- bus_writeq(tmp, IOADDR(A_IMR_REGISTER(1, R_IMR_INTERRUPT_MASK)));
+ __raw_writeq(tmp, IOADDR(A_IMR_REGISTER(0, R_IMR_INTERRUPT_MASK)));
+ __raw_writeq(tmp, IOADDR(A_IMR_REGISTER(1, R_IMR_INTERRUPT_MASK)));
sb1250_steal_irq(K_INT_MBOX_0);
@@ -396,12 +389,14 @@ void __init arch_init_irq(void)
sb1250_duart_present[kgdb_port] = 0;
#endif
/* Setup uart 1 settings, mapper */
- bus_writeq(M_DUART_IMR_BRK, IOADDR(A_DUART_IMRREG(kgdb_port)));
+ __raw_writeq(M_DUART_IMR_BRK,
+ IOADDR(A_DUART_IMRREG(kgdb_port)));
sb1250_steal_irq(kgdb_irq);
- bus_writeq(IMR_IP6_VAL,
- IOADDR(A_IMR_REGISTER(0, R_IMR_INTERRUPT_MAP_BASE) +
- (kgdb_irq<<3)));
+ __raw_writeq(IMR_IP6_VAL,
+ IOADDR(A_IMR_REGISTER(0,
+ R_IMR_INTERRUPT_MAP_BASE) +
+ (kgdb_irq << 3)));
sb1250_unmask_irq(0, kgdb_irq);
}
#endif
diff --git a/arch/mips/sibyte/sb1250/setup.c b/arch/mips/sibyte/sb1250/setup.c
index f8c605be96c7..df2e266c700c 100644
--- a/arch/mips/sibyte/sb1250/setup.c
+++ b/arch/mips/sibyte/sb1250/setup.c
@@ -153,7 +153,7 @@ void sb1250_setup(void)
int bad_config = 0;
sb1_pass = read_c0_prid() & 0xff;
- sys_rev = bus_readq(IOADDR(A_SCD_SYSTEM_REVISION));
+ sys_rev = __raw_readq(IOADDR(A_SCD_SYSTEM_REVISION));
soc_type = SYS_SOC_TYPE(sys_rev);
soc_pass = G_SYS_REVISION(sys_rev);
@@ -162,7 +162,7 @@ void sb1250_setup(void)
machine_restart(NULL);
}
- plldiv = G_SYS_PLL_DIV(bus_readq(IOADDR(A_SCD_SYSTEM_CFG)));
+ plldiv = G_SYS_PLL_DIV(__raw_readq(IOADDR(A_SCD_SYSTEM_CFG)));
zbbus_mhz = ((plldiv >> 1) * 50) + ((plldiv & 1) * 25);
prom_printf("Broadcom SiByte %s %s @ %d MHz (SB1 rev %d)\n",
diff --git a/arch/mips/sibyte/sb1250/smp.c b/arch/mips/sibyte/sb1250/smp.c
index be91b3990952..f859db02d3c9 100644
--- a/arch/mips/sibyte/sb1250/smp.c
+++ b/arch/mips/sibyte/sb1250/smp.c
@@ -29,18 +29,18 @@
#include <asm/sibyte/sb1250_int.h>
static void *mailbox_set_regs[] = {
- (void *)IOADDR(A_IMR_CPU0_BASE + R_IMR_MAILBOX_SET_CPU),
- (void *)IOADDR(A_IMR_CPU1_BASE + R_IMR_MAILBOX_SET_CPU)
+ IOADDR(A_IMR_CPU0_BASE + R_IMR_MAILBOX_SET_CPU),
+ IOADDR(A_IMR_CPU1_BASE + R_IMR_MAILBOX_SET_CPU)
};
static void *mailbox_clear_regs[] = {
- (void *)IOADDR(A_IMR_CPU0_BASE + R_IMR_MAILBOX_CLR_CPU),
- (void *)IOADDR(A_IMR_CPU1_BASE + R_IMR_MAILBOX_CLR_CPU)
+ IOADDR(A_IMR_CPU0_BASE + R_IMR_MAILBOX_CLR_CPU),
+ IOADDR(A_IMR_CPU1_BASE + R_IMR_MAILBOX_CLR_CPU)
};
static void *mailbox_regs[] = {
- (void *)IOADDR(A_IMR_CPU0_BASE + R_IMR_MAILBOX_CPU),
- (void *)IOADDR(A_IMR_CPU1_BASE + R_IMR_MAILBOX_CPU)
+ IOADDR(A_IMR_CPU0_BASE + R_IMR_MAILBOX_CPU),
+ IOADDR(A_IMR_CPU1_BASE + R_IMR_MAILBOX_CPU)
};
/*
@@ -73,7 +73,7 @@ void sb1250_smp_finish(void)
*/
void core_send_ipi(int cpu, unsigned int action)
{
- bus_writeq((((u64)action) << 48), mailbox_set_regs[cpu]);
+ __raw_writeq((((u64)action) << 48), mailbox_set_regs[cpu]);
}
void sb1250_mailbox_interrupt(struct pt_regs *regs)
@@ -83,10 +83,10 @@ void sb1250_mailbox_interrupt(struct pt_regs *regs)
kstat_this_cpu.irqs[K_INT_MBOX_0]++;
/* Load the mailbox register to figure out what we're supposed to do */
- action = (__bus_readq(mailbox_regs[cpu]) >> 48) & 0xffff;
+ action = (____raw_readq(mailbox_regs[cpu]) >> 48) & 0xffff;
/* Clear the mailbox to clear the interrupt */
- __bus_writeq(((u64)action) << 48, mailbox_clear_regs[cpu]);
+ ____raw_writeq(((u64)action) << 48, mailbox_clear_regs[cpu]);
/*
* Nothing to do for SMP_RESCHEDULE_YOURSELF; returning from the
diff --git a/arch/mips/sibyte/sb1250/time.c b/arch/mips/sibyte/sb1250/time.c
index 8b4c848c907b..511c89d65f38 100644
--- a/arch/mips/sibyte/sb1250/time.c
+++ b/arch/mips/sibyte/sb1250/time.c
@@ -67,24 +67,24 @@ void sb1250_time_init(void)
sb1250_mask_irq(cpu, irq);
/* Map the timer interrupt to ip[4] of this cpu */
- bus_writeq(IMR_IP4_VAL,
- IOADDR(A_IMR_REGISTER(cpu, R_IMR_INTERRUPT_MAP_BASE) +
- (irq << 3)));
+ __raw_writeq(IMR_IP4_VAL,
+ IOADDR(A_IMR_REGISTER(cpu, R_IMR_INTERRUPT_MAP_BASE) +
+ (irq << 3)));
/* the general purpose timer ticks at 1 Mhz independent if the rest of the system */
/* Disable the timer and set up the count */
- bus_writeq(0, IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG)));
+ __raw_writeq(0, IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG)));
#ifdef CONFIG_SIMULATION
- bus_writeq(50000 / HZ,
- IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_INIT)));
+ __raw_writeq(50000 / HZ,
+ IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_INIT)));
#else
- bus_writeq(1000000/HZ,
- IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_INIT)));
+ __raw_writeq(1000000 / HZ,
+ IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_INIT)));
#endif
/* Set the timer running */
- bus_writeq(M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS,
- IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG)));
+ __raw_writeq(M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS,
+ IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG)));
sb1250_unmask_irq(cpu, irq);
sb1250_steal_irq(irq);
@@ -100,25 +100,25 @@ void sb1250_time_init(void)
void sb1250_timer_interrupt(struct pt_regs *regs)
{
- extern asmlinkage void ll_local_timer_interrupt(int irq, struct pt_regs *regs);
int cpu = smp_processor_id();
int irq = K_INT_TIMER_0 + cpu;
/* Reset the timer */
- __bus_writeq(M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS,
- IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG)));
+ ____raw_writeq(M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS,
+ IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG)));
- /*
- * CPU 0 handles the global timer interrupt job
- */
if (cpu == 0) {
+ /*
+ * CPU 0 handles the global timer interrupt job
+ */
ll_timer_interrupt(irq, regs);
}
-
- /*
- * every CPU should do profiling and process accouting
- */
- ll_local_timer_interrupt(irq, regs);
+ else {
+ /*
+ * other CPUs should just do profiling and process accounting
+ */
+ ll_local_timer_interrupt(irq, regs);
+ }
}
/*
@@ -130,7 +130,7 @@ void sb1250_timer_interrupt(struct pt_regs *regs)
unsigned long sb1250_gettimeoffset(void)
{
unsigned long count =
- bus_readq(IOADDR(A_SCD_TIMER_REGISTER(0, R_SCD_TIMER_CNT)));
+ __raw_readq(IOADDR(A_SCD_TIMER_REGISTER(0, R_SCD_TIMER_CNT)));
return 1000000/HZ - count;
}
diff --git a/arch/mips/sibyte/swarm/rtc_m41t81.c b/arch/mips/sibyte/swarm/rtc_m41t81.c
index a686bb716ec6..c13914bdda59 100644
--- a/arch/mips/sibyte/swarm/rtc_m41t81.c
+++ b/arch/mips/sibyte/swarm/rtc_m41t81.c
@@ -82,59 +82,60 @@
#define M41T81REG_SQW 0x13 /* square wave register */
#define M41T81_CCR_ADDRESS 0x68
-#define SMB_CSR(reg) ((u8 *) (IOADDR(A_SMB_REGISTER(1, reg))))
+
+#define SMB_CSR(reg) IOADDR(A_SMB_REGISTER(1, reg))
static int m41t81_read(uint8_t addr)
{
- while (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+ while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
;
- bus_writeq(addr & 0xff, SMB_CSR(R_SMB_CMD));
- bus_writeq((V_SMB_ADDR(M41T81_CCR_ADDRESS) | V_SMB_TT_WR1BYTE),
- SMB_CSR(R_SMB_START));
+ __raw_writeq(addr & 0xff, SMB_CSR(R_SMB_CMD));
+ __raw_writeq(V_SMB_ADDR(M41T81_CCR_ADDRESS) | V_SMB_TT_WR1BYTE,
+ SMB_CSR(R_SMB_START));
- while (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+ while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
;
- bus_writeq((V_SMB_ADDR(M41T81_CCR_ADDRESS) | V_SMB_TT_RD1BYTE),
- SMB_CSR(R_SMB_START));
+ __raw_writeq(V_SMB_ADDR(M41T81_CCR_ADDRESS) | V_SMB_TT_RD1BYTE,
+ SMB_CSR(R_SMB_START));
- while (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+ while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
;
- if (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_ERROR) {
+ if (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_ERROR) {
/* Clear error bit by writing a 1 */
- bus_writeq(M_SMB_ERROR, SMB_CSR(R_SMB_STATUS));
+ __raw_writeq(M_SMB_ERROR, SMB_CSR(R_SMB_STATUS));
return -1;
}
- return (bus_readq(SMB_CSR(R_SMB_DATA)) & 0xff);
+ return (__raw_readq(SMB_CSR(R_SMB_DATA)) & 0xff);
}
static int m41t81_write(uint8_t addr, int b)
{
- while (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+ while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
;
- bus_writeq((addr & 0xFF), SMB_CSR(R_SMB_CMD));
- bus_writeq((b & 0xff), SMB_CSR(R_SMB_DATA));
- bus_writeq(V_SMB_ADDR(M41T81_CCR_ADDRESS) | V_SMB_TT_WR2BYTE,
- SMB_CSR(R_SMB_START));
+ __raw_writeq(addr & 0xff, SMB_CSR(R_SMB_CMD));
+ __raw_writeq(b & 0xff, SMB_CSR(R_SMB_DATA));
+ __raw_writeq(V_SMB_ADDR(M41T81_CCR_ADDRESS) | V_SMB_TT_WR2BYTE,
+ SMB_CSR(R_SMB_START));
- while (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+ while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
;
- if (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_ERROR) {
+ if (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_ERROR) {
/* Clear error bit by writing a 1 */
- bus_writeq(M_SMB_ERROR, SMB_CSR(R_SMB_STATUS));
+ __raw_writeq(M_SMB_ERROR, SMB_CSR(R_SMB_STATUS));
return -1;
}
/* read the same byte again to make sure it is written */
- bus_writeq(V_SMB_ADDR(M41T81_CCR_ADDRESS) | V_SMB_TT_RD1BYTE,
- SMB_CSR(R_SMB_START));
+ __raw_writeq(V_SMB_ADDR(M41T81_CCR_ADDRESS) | V_SMB_TT_RD1BYTE,
+ SMB_CSR(R_SMB_START));
- while (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+ while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
;
return 0;
@@ -143,6 +144,7 @@ static int m41t81_write(uint8_t addr, int b)
int m41t81_set_time(unsigned long t)
{
struct rtc_time tm;
+ unsigned long flags;
to_tm(t, &tm);
@@ -152,6 +154,7 @@ int m41t81_set_time(unsigned long t)
* believe we should finish writing min within a second.
*/
+ spin_lock_irqsave(&rtc_lock, flags);
tm.tm_sec = BIN2BCD(tm.tm_sec);
m41t81_write(M41T81REG_SC, tm.tm_sec);
@@ -179,6 +182,7 @@ int m41t81_set_time(unsigned long t)
tm.tm_year %= 100;
tm.tm_year = BIN2BCD(tm.tm_year);
m41t81_write(M41T81REG_YR, tm.tm_year);
+ spin_unlock_irqrestore(&rtc_lock, flags);
return 0;
}
@@ -186,19 +190,23 @@ int m41t81_set_time(unsigned long t)
unsigned long m41t81_get_time(void)
{
unsigned int year, mon, day, hour, min, sec;
+ unsigned long flags;
/*
* min is valid if two reads of sec are the same.
*/
for (;;) {
+ spin_lock_irqsave(&rtc_lock, flags);
sec = m41t81_read(M41T81REG_SC);
min = m41t81_read(M41T81REG_MN);
if (sec == m41t81_read(M41T81REG_SC)) break;
+ spin_unlock_irqrestore(&rtc_lock, flags);
}
hour = m41t81_read(M41T81REG_HR) & 0x3f;
day = m41t81_read(M41T81REG_DT);
mon = m41t81_read(M41T81REG_MO);
year = m41t81_read(M41T81REG_YR);
+ spin_unlock_irqrestore(&rtc_lock, flags);
sec = BCD2BIN(sec);
min = BCD2BIN(min);
diff --git a/arch/mips/sibyte/swarm/rtc_xicor1241.c b/arch/mips/sibyte/swarm/rtc_xicor1241.c
index 981d21f16e64..f4a178836415 100644
--- a/arch/mips/sibyte/swarm/rtc_xicor1241.c
+++ b/arch/mips/sibyte/swarm/rtc_xicor1241.c
@@ -57,52 +57,52 @@
#define X1241_CCR_ADDRESS 0x6F
-#define SMB_CSR(reg) ((u8 *) (IOADDR(A_SMB_REGISTER(1, reg))))
+#define SMB_CSR(reg) IOADDR(A_SMB_REGISTER(1, reg))
static int xicor_read(uint8_t addr)
{
- while (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+ while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
;
- bus_writeq((addr >> 8) & 0x7, SMB_CSR(R_SMB_CMD));
- bus_writeq((addr & 0xff), SMB_CSR(R_SMB_DATA));
- bus_writeq((V_SMB_ADDR(X1241_CCR_ADDRESS) | V_SMB_TT_WR2BYTE),
- SMB_CSR(R_SMB_START));
+ __raw_writeq((addr >> 8) & 0x7, SMB_CSR(R_SMB_CMD));
+ __raw_writeq(addr & 0xff, SMB_CSR(R_SMB_DATA));
+ __raw_writeq(V_SMB_ADDR(X1241_CCR_ADDRESS) | V_SMB_TT_WR2BYTE,
+ SMB_CSR(R_SMB_START));
- while (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+ while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
;
- bus_writeq((V_SMB_ADDR(X1241_CCR_ADDRESS) | V_SMB_TT_RD1BYTE),
- SMB_CSR(R_SMB_START));
+ __raw_writeq(V_SMB_ADDR(X1241_CCR_ADDRESS) | V_SMB_TT_RD1BYTE,
+ SMB_CSR(R_SMB_START));
- while (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+ while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
;
- if (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_ERROR) {
+ if (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_ERROR) {
/* Clear error bit by writing a 1 */
- bus_writeq(M_SMB_ERROR, SMB_CSR(R_SMB_STATUS));
+ __raw_writeq(M_SMB_ERROR, SMB_CSR(R_SMB_STATUS));
return -1;
}
- return (bus_readq(SMB_CSR(R_SMB_DATA)) & 0xff);
+ return (__raw_readq(SMB_CSR(R_SMB_DATA)) & 0xff);
}
static int xicor_write(uint8_t addr, int b)
{
- while (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+ while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
;
- bus_writeq(addr, SMB_CSR(R_SMB_CMD));
- bus_writeq((addr & 0xff) | ((b & 0xff) << 8), SMB_CSR(R_SMB_DATA));
- bus_writeq(V_SMB_ADDR(X1241_CCR_ADDRESS) | V_SMB_TT_WR3BYTE,
- SMB_CSR(R_SMB_START));
+ __raw_writeq(addr, SMB_CSR(R_SMB_CMD));
+ __raw_writeq((addr & 0xff) | ((b & 0xff) << 8), SMB_CSR(R_SMB_DATA));
+ __raw_writeq(V_SMB_ADDR(X1241_CCR_ADDRESS) | V_SMB_TT_WR3BYTE,
+ SMB_CSR(R_SMB_START));
- while (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+ while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
;
- if (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_ERROR) {
+ if (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_ERROR) {
/* Clear error bit by writing a 1 */
- bus_writeq(M_SMB_ERROR, SMB_CSR(R_SMB_STATUS));
+ __raw_writeq(M_SMB_ERROR, SMB_CSR(R_SMB_STATUS));
return -1;
} else {
return 0;
@@ -113,9 +113,11 @@ int xicor_set_time(unsigned long t)
{
struct rtc_time tm;
int tmp;
+ unsigned long flags;
to_tm(t, &tm);
+ spin_lock_irqsave(&rtc_lock, flags);
/* unlock writes to the CCR */
xicor_write(X1241REG_SR, X1241REG_SR_WEL);
xicor_write(X1241REG_SR, X1241REG_SR_WEL | X1241REG_SR_RWEL);
@@ -160,6 +162,7 @@ int xicor_set_time(unsigned long t)
xicor_write(X1241REG_HR, tmp);
xicor_write(X1241REG_SR, 0);
+ spin_unlock_irqrestore(&rtc_lock, flags);
return 0;
}
@@ -167,7 +170,9 @@ int xicor_set_time(unsigned long t)
unsigned long xicor_get_time(void)
{
unsigned int year, mon, day, hour, min, sec, y2k;
+ unsigned long flags;
+ spin_lock_irqsave(&rtc_lock, flags);
sec = xicor_read(X1241REG_SC);
min = xicor_read(X1241REG_MN);
hour = xicor_read(X1241REG_HR);
@@ -183,6 +188,7 @@ unsigned long xicor_get_time(void)
mon = xicor_read(X1241REG_MO);
year = xicor_read(X1241REG_YR);
y2k = xicor_read(X1241REG_Y2K);
+ spin_unlock_irqrestore(&rtc_lock, flags);
sec = BCD2BIN(sec);
min = BCD2BIN(min);
diff --git a/arch/mips/sibyte/swarm/setup.c b/arch/mips/sibyte/swarm/setup.c
index 4daeaa413def..b614ca0ddb69 100644
--- a/arch/mips/sibyte/swarm/setup.c
+++ b/arch/mips/sibyte/swarm/setup.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2000, 2001, 2002, 2003 Broadcom Corporation
+ * Copyright (C) 2000, 2001, 2002, 2003, 2004 Broadcom Corporation
* Copyright (C) 2004 by Ralf Baechle (ralf@linux-mips.org)
*
* This program is free software; you can redistribute it and/or
@@ -39,11 +39,23 @@
#include <asm/time.h>
#include <asm/traps.h>
#include <asm/sibyte/sb1250.h>
+#if defined(CONFIG_SIBYTE_BCM1x55) || defined(CONFIG_SIBYTE_BCM1x80)
+#include <asm/sibyte/bcm1480_regs.h>
+#elif defined(CONFIG_SIBYTE_SB1250) || defined(CONFIG_SIBYTE_BCM112X)
#include <asm/sibyte/sb1250_regs.h>
+#else
+#error invalid SiByte board configuation
+#endif
#include <asm/sibyte/sb1250_genbus.h>
#include <asm/sibyte/board.h>
+#if defined(CONFIG_SIBYTE_BCM1x55) || defined(CONFIG_SIBYTE_BCM1x80)
+extern void bcm1480_setup(void);
+#elif defined(CONFIG_SIBYTE_SB1250) || defined(CONFIG_SIBYTE_BCM112X)
extern void sb1250_setup(void);
+#else
+#error invalid SiByte board configuation
+#endif
extern int xicor_probe(void);
extern int xicor_set_time(unsigned long);
@@ -66,27 +78,34 @@ void __init swarm_timer_setup(struct irqaction *irq)
*/
/* We only need to setup the generic timer */
- sb1250_time_init();
+#if defined(CONFIG_SIBYTE_BCM1x55) || defined(CONFIG_SIBYTE_BCM1x80)
+ bcm1480_time_init();
+#elif defined(CONFIG_SIBYTE_SB1250) || defined(CONFIG_SIBYTE_BCM112X)
+ sb1250_time_init();
+#else
+#error invalid SiByte board configuation
+#endif
}
int swarm_be_handler(struct pt_regs *regs, int is_fixup)
{
if (!is_fixup && (regs->cp0_cause & 4)) {
/* Data bus error - print PA */
-#ifdef CONFIG_64BIT
- printk("DBE physical address: %010lx\n",
+ printk("DBE physical address: %010Lx\n",
__read_64bit_c0_register($26, 1));
-#else
- printk("DBE physical address: %010llx\n",
- __read_64bit_c0_split($26, 1));
-#endif
}
return (is_fixup ? MIPS_BE_FIXUP : MIPS_BE_FATAL);
}
-static int __init swarm_setup(void)
+void __init plat_setup(void)
{
+#if defined(CONFIG_SIBYTE_BCM1x55) || defined(CONFIG_SIBYTE_BCM1x80)
+ bcm1480_setup();
+#elif defined(CONFIG_SIBYTE_SB1250) || defined(CONFIG_SIBYTE_BCM112X)
sb1250_setup();
+#else
+#error invalid SiByte board configuation
+#endif
panic_timeout = 5; /* For debug. */
@@ -133,12 +152,8 @@ static int __init swarm_setup(void)
};
/* XXXKW for CFE, get lines/cols from environment */
#endif
-
- return 0;
}
-early_initcall(swarm_setup);
-
#ifdef LEDS_PHYS
#ifdef CONFIG_SIBYTE_CARMEL
diff --git a/arch/mips/sibyte/swarm/time.c b/arch/mips/sibyte/swarm/time.c
index c1f1a9defeeb..97c73c793c35 100644
--- a/arch/mips/sibyte/swarm/time.c
+++ b/arch/mips/sibyte/swarm/time.c
@@ -79,48 +79,48 @@ static unsigned int usec_bias = 0;
static int xicor_read(uint8_t addr)
{
- while (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+ while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
;
- bus_writeq((addr >> 8) & 0x7, SMB_CSR(R_SMB_CMD));
- bus_writeq((addr & 0xff), SMB_CSR(R_SMB_DATA));
- bus_writeq((V_SMB_ADDR(X1241_CCR_ADDRESS) | V_SMB_TT_WR2BYTE),
- SMB_CSR(R_SMB_START));
+ __raw_writeq((addr >> 8) & 0x7, SMB_CSR(R_SMB_CMD));
+ __raw_writeq(addr & 0xff, SMB_CSR(R_SMB_DATA));
+ __raw_writeq(V_SMB_ADDR(X1241_CCR_ADDRESS) | V_SMB_TT_WR2BYTE,
+ SMB_CSR(R_SMB_START));
- while (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+ while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
;
- bus_writeq((V_SMB_ADDR(X1241_CCR_ADDRESS) | V_SMB_TT_RD1BYTE),
- SMB_CSR(R_SMB_START));
+ __raw_writeq(V_SMB_ADDR(X1241_CCR_ADDRESS) | V_SMB_TT_RD1BYTE,
+ SMB_CSR(R_SMB_START));
- while (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+ while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
;
- if (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_ERROR) {
+ if (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_ERROR) {
/* Clear error bit by writing a 1 */
- bus_writeq(M_SMB_ERROR, SMB_CSR(R_SMB_STATUS));
+ __raw_writeq(M_SMB_ERROR, SMB_CSR(R_SMB_STATUS));
return -1;
}
- return (bus_readq(SMB_CSR(R_SMB_DATA)) & 0xff);
+ return (__raw_readq(SMB_CSR(R_SMB_DATA)) & 0xff);
}
static int xicor_write(uint8_t addr, int b)
{
- while (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+ while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
;
- bus_writeq(addr, SMB_CSR(R_SMB_CMD));
- bus_writeq((addr & 0xff) | ((b & 0xff) << 8), SMB_CSR(R_SMB_DATA));
- bus_writeq(V_SMB_ADDR(X1241_CCR_ADDRESS) | V_SMB_TT_WR3BYTE,
- SMB_CSR(R_SMB_START));
+ __raw_writeq(addr, SMB_CSR(R_SMB_CMD));
+ __raw_writeq((addr & 0xff) | ((b & 0xff) << 8), SMB_CSR(R_SMB_DATA));
+ __raw_writeq(V_SMB_ADDR(X1241_CCR_ADDRESS) | V_SMB_TT_WR3BYTE,
+ SMB_CSR(R_SMB_START));
- while (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+ while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
;
- if (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_ERROR) {
+ if (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_ERROR) {
/* Clear error bit by writing a 1 */
- bus_writeq(M_SMB_ERROR, SMB_CSR(R_SMB_STATUS));
+ __raw_writeq(M_SMB_ERROR, SMB_CSR(R_SMB_STATUS));
return -1;
} else {
return 0;
@@ -228,8 +228,8 @@ void __init swarm_time_init(void)
/* Establish communication with the Xicor 1241 RTC */
/* XXXKW how do I share the SMBus with the I2C subsystem? */
- bus_writeq(K_SMB_FREQ_400KHZ, SMB_CSR(R_SMB_FREQ));
- bus_writeq(0, SMB_CSR(R_SMB_CONTROL));
+ __raw_writeq(K_SMB_FREQ_400KHZ, SMB_CSR(R_SMB_FREQ));
+ __raw_writeq(0, SMB_CSR(R_SMB_CONTROL));
if ((status = xicor_read(X1241REG_SR_RTCF)) < 0) {
printk("x1241: couldn't detect on SWARM SMBus 1\n");
diff --git a/arch/mips/sni/irq.c b/arch/mips/sni/irq.c
index 141a310d74d8..952038aa4b90 100644
--- a/arch/mips/sni/irq.c
+++ b/arch/mips/sni/irq.c
@@ -58,14 +58,13 @@ static void end_pciasic_irq(unsigned int irq)
}
static struct hw_interrupt_type pciasic_irq_type = {
- "ASIC-PCI",
- startup_pciasic_irq,
- shutdown_pciasic_irq,
- enable_pciasic_irq,
- disable_pciasic_irq,
- mask_and_ack_pciasic_irq,
- end_pciasic_irq,
- NULL
+ .typename = "ASIC-PCI",
+ .startup = startup_pciasic_irq,
+ .shutdown = shutdown_pciasic_irq,
+ .enable = enable_pciasic_irq,
+ .disable = disable_pciasic_irq,
+ .ack = mask_and_ack_pciasic_irq,
+ .end = end_pciasic_irq,
};
/*
diff --git a/arch/mips/sni/setup.c b/arch/mips/sni/setup.c
index 1b3f8a0903e1..262c85680709 100644
--- a/arch/mips/sni/setup.c
+++ b/arch/mips/sni/setup.c
@@ -167,7 +167,7 @@ static inline void sni_pcimt_time_init(void)
rtc_set_time = mc146818_set_rtc_mmss;
}
-static int __init sni_rm200_pci_setup(void)
+void __init plat_setup(void)
{
sni_pcimt_detect();
sni_pcimt_sc_init();
@@ -196,8 +196,4 @@ static int __init sni_rm200_pci_setup(void)
#ifdef CONFIG_PCI
register_pci_controller(&sni_controller);
#endif
-
- return 0;
}
-
-early_initcall(sni_rm200_pci_setup);
diff --git a/arch/mips/tx4927/Kconfig b/arch/mips/tx4927/Kconfig
new file mode 100644
index 000000000000..5fbbe12e0fc1
--- /dev/null
+++ b/arch/mips/tx4927/Kconfig
@@ -0,0 +1,3 @@
+config TOSHIBA_FPCIB0
+ bool "FPCIB0 Backplane Support"
+ depends on TOSHIBA_RBTX4927
diff --git a/arch/mips/tx4927/common/tx4927_setup.c b/arch/mips/tx4927/common/tx4927_setup.c
index 26d7c53612a8..77c3b66fb959 100644
--- a/arch/mips/tx4927/common/tx4927_setup.c
+++ b/arch/mips/tx4927/common/tx4927_setup.c
@@ -64,7 +64,7 @@ static void tx4927_write_buffer_flush(void)
}
-static void __init tx4927_setup(void)
+void __init plat_setup(void)
{
board_time_init = tx4927_time_init;
board_timer_setup = tx4927_timer_setup;
@@ -76,12 +76,8 @@ static void __init tx4927_setup(void)
toshiba_rbtx4927_setup();
}
#endif
-
- return;
}
-early_initcall(tx4927_setup);
-
void __init tx4927_time_init(void)
{
diff --git a/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c b/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c
index fc0720599fd9..990fcb294bab 100644
--- a/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c
+++ b/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c
@@ -77,6 +77,11 @@
#include <linux/hdreg.h>
#include <linux/ide.h>
#endif
+#ifdef CONFIG_SERIAL_TXX9
+#include <linux/tty.h>
+#include <linux/serial.h>
+#include <linux/serial_core.h>
+#endif
#undef TOSHIBA_RBTX4927_SETUP_DEBUG
@@ -920,12 +925,30 @@ void __init toshiba_rbtx4927_setup(void)
#endif /* CONFIG_PCI */
+#ifdef CONFIG_SERIAL_TXX9
+ {
+ extern int early_serial_txx9_setup(struct uart_port *port);
+ int i;
+ struct uart_port req;
+ for(i = 0; i < 2; i++) {
+ memset(&req, 0, sizeof(req));
+ req.line = i;
+ req.iotype = UPIO_MEM;
+ req.membase = (char *)(0xff1ff300 + i * 0x100);
+ req.mapbase = 0xff1ff300 + i * 0x100;
+ req.irq = 32 + i;
+ req.flags |= UPF_BUGGY_UART /*HAVE_CTS_LINE*/;
+ req.uartclk = 50000000;
+ early_serial_txx9_setup(&req);
+ }
+ }
#ifdef CONFIG_SERIAL_TXX9_CONSOLE
argptr = prom_getcmdline();
if (strstr(argptr, "console=") == NULL) {
strcat(argptr, " console=ttyS0,38400");
}
#endif
+#endif
#ifdef CONFIG_ROOT_NFS
argptr = prom_getcmdline();
diff --git a/arch/mips/tx4938/Kconfig b/arch/mips/tx4938/Kconfig
new file mode 100644
index 000000000000..d90e9cd85138
--- /dev/null
+++ b/arch/mips/tx4938/Kconfig
@@ -0,0 +1,24 @@
+if TOSHIBA_RBTX4938
+
+comment "Multiplex Pin Select"
+choice
+ prompt "PIO[58:61]"
+ default TOSHIBA_RBTX4938_MPLEX_PIO58_61
+
+config TOSHIBA_RBTX4938_MPLEX_PIO58_61
+ bool "PIO"
+config TOSHIBA_RBTX4938_MPLEX_NAND
+ bool "NAND"
+config TOSHIBA_RBTX4938_MPLEX_ATA
+ bool "ATA"
+
+endchoice
+
+config TX4938_NAND_BOOT
+ depends on EXPERIMENTAL && TOSHIBA_RBTX4938_MPLEX_NAND
+ bool "NAND Boot Support (EXPERIMENTAL)"
+ help
+ This is only for Toshiba RBTX4938 reference board, which has NAND IPL.
+ Select this option if you need to use NAND boot.
+
+endif
diff --git a/arch/mips/tx4938/common/Makefile b/arch/mips/tx4938/common/Makefile
new file mode 100644
index 000000000000..74c95c5bcdbf
--- /dev/null
+++ b/arch/mips/tx4938/common/Makefile
@@ -0,0 +1,11 @@
+#
+# Makefile for common code for Toshiba TX4927 based systems
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+
+obj-y += prom.o setup.o irq.o irq_handler.o rtc_rx5c348.o
+obj-$(CONFIG_KGDB) += dbgio.o
+
diff --git a/arch/mips/tx4938/common/dbgio.c b/arch/mips/tx4938/common/dbgio.c
new file mode 100644
index 000000000000..bea59ff1842a
--- /dev/null
+++ b/arch/mips/tx4938/common/dbgio.c
@@ -0,0 +1,50 @@
+/*
+ * linux/arch/mips/tx4938/common/dbgio.c
+ *
+ * kgdb interface for gdb
+ *
+ * Author: MontaVista Software, Inc.
+ * source@mvista.com
+ *
+ * Copyright 2005 MontaVista Software 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Support for TX4938 in 2.6 - Hiroshi DOYU <Hiroshi_DOYU@montavista.co.jp>
+ */
+
+#include <asm/mipsregs.h>
+#include <asm/system.h>
+#include <asm/tx4938/tx4938_mips.h>
+
+extern u8 txx9_sio_kdbg_rd(void);
+extern int txx9_sio_kdbg_wr( u8 ch );
+
+u8 getDebugChar(void)
+{
+ return (txx9_sio_kdbg_rd());
+}
+
+int putDebugChar(u8 byte)
+{
+ return (txx9_sio_kdbg_wr(byte));
+}
+
diff --git a/arch/mips/tx4938/common/irq.c b/arch/mips/tx4938/common/irq.c
new file mode 100644
index 000000000000..4f90d7faf634
--- /dev/null
+++ b/arch/mips/tx4938/common/irq.c
@@ -0,0 +1,424 @@
+/*
+ * linux/arch/mps/tx4938/common/irq.c
+ *
+ * Common tx4938 irq handler
+ * Copyright (C) 2000-2001 Toshiba Corporation
+ *
+ * 2003-2005 (c) MontaVista Software, Inc. This file is licensed under the
+ * terms of the GNU General Public License version 2. This program is
+ * licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ *
+ * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com)
+ */
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/kernel_stat.h>
+#include <linux/module.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/timex.h>
+#include <linux/slab.h>
+#include <linux/random.h>
+#include <linux/irq.h>
+#include <asm/bitops.h>
+#include <asm/bootinfo.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/mipsregs.h>
+#include <asm/system.h>
+#include <asm/tx4938/rbtx4938.h>
+
+/**********************************************************************************/
+/* Forwad definitions for all pic's */
+/**********************************************************************************/
+
+static unsigned int tx4938_irq_cp0_startup(unsigned int irq);
+static void tx4938_irq_cp0_shutdown(unsigned int irq);
+static void tx4938_irq_cp0_enable(unsigned int irq);
+static void tx4938_irq_cp0_disable(unsigned int irq);
+static void tx4938_irq_cp0_mask_and_ack(unsigned int irq);
+static void tx4938_irq_cp0_end(unsigned int irq);
+
+static unsigned int tx4938_irq_pic_startup(unsigned int irq);
+static void tx4938_irq_pic_shutdown(unsigned int irq);
+static void tx4938_irq_pic_enable(unsigned int irq);
+static void tx4938_irq_pic_disable(unsigned int irq);
+static void tx4938_irq_pic_mask_and_ack(unsigned int irq);
+static void tx4938_irq_pic_end(unsigned int irq);
+
+/**********************************************************************************/
+/* Kernel structs for all pic's */
+/**********************************************************************************/
+DEFINE_SPINLOCK(tx4938_cp0_lock);
+DEFINE_SPINLOCK(tx4938_pic_lock);
+
+#define TX4938_CP0_NAME "TX4938-CP0"
+static struct hw_interrupt_type tx4938_irq_cp0_type = {
+ .typename = TX4938_CP0_NAME,
+ .startup = tx4938_irq_cp0_startup,
+ .shutdown = tx4938_irq_cp0_shutdown,
+ .enable = tx4938_irq_cp0_enable,
+ .disable = tx4938_irq_cp0_disable,
+ .ack = tx4938_irq_cp0_mask_and_ack,
+ .end = tx4938_irq_cp0_end,
+ .set_affinity = NULL
+};
+
+#define TX4938_PIC_NAME "TX4938-PIC"
+static struct hw_interrupt_type tx4938_irq_pic_type = {
+ .typename = TX4938_PIC_NAME,
+ .startup = tx4938_irq_pic_startup,
+ .shutdown = tx4938_irq_pic_shutdown,
+ .enable = tx4938_irq_pic_enable,
+ .disable = tx4938_irq_pic_disable,
+ .ack = tx4938_irq_pic_mask_and_ack,
+ .end = tx4938_irq_pic_end,
+ .set_affinity = NULL
+};
+
+static struct irqaction tx4938_irq_pic_action = {
+ .handler = no_action,
+ .flags = 0,
+ .mask = CPU_MASK_NONE,
+ .name = TX4938_PIC_NAME
+};
+
+/**********************************************************************************/
+/* Functions for cp0 */
+/**********************************************************************************/
+
+#define tx4938_irq_cp0_mask(irq) ( 1 << ( irq-TX4938_IRQ_CP0_BEG+8 ) )
+
+static void __init
+tx4938_irq_cp0_init(void)
+{
+ int i;
+
+ for (i = TX4938_IRQ_CP0_BEG; i <= TX4938_IRQ_CP0_END; i++) {
+ irq_desc[i].status = IRQ_DISABLED;
+ irq_desc[i].action = 0;
+ irq_desc[i].depth = 1;
+ irq_desc[i].handler = &tx4938_irq_cp0_type;
+ }
+
+ return;
+}
+
+static unsigned int
+tx4938_irq_cp0_startup(unsigned int irq)
+{
+ tx4938_irq_cp0_enable(irq);
+
+ return (0);
+}
+
+static void
+tx4938_irq_cp0_shutdown(unsigned int irq)
+{
+ tx4938_irq_cp0_disable(irq);
+}
+
+static void
+tx4938_irq_cp0_enable(unsigned int irq)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&tx4938_cp0_lock, flags);
+
+ set_c0_status(tx4938_irq_cp0_mask(irq));
+
+ spin_unlock_irqrestore(&tx4938_cp0_lock, flags);
+}
+
+static void
+tx4938_irq_cp0_disable(unsigned int irq)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&tx4938_cp0_lock, flags);
+
+ clear_c0_status(tx4938_irq_cp0_mask(irq));
+
+ spin_unlock_irqrestore(&tx4938_cp0_lock, flags);
+
+ return;
+}
+
+static void
+tx4938_irq_cp0_mask_and_ack(unsigned int irq)
+{
+ tx4938_irq_cp0_disable(irq);
+
+ return;
+}
+
+static void
+tx4938_irq_cp0_end(unsigned int irq)
+{
+ if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) {
+ tx4938_irq_cp0_enable(irq);
+ }
+
+ return;
+}
+
+/**********************************************************************************/
+/* Functions for pic */
+/**********************************************************************************/
+
+u32
+tx4938_irq_pic_addr(int irq)
+{
+ /* MVMCP -- need to formulize this */
+ irq -= TX4938_IRQ_PIC_BEG;
+
+ switch (irq) {
+ case 17:
+ case 16:
+ case 1:
+ case 0:{
+ return (TX4938_MKA(TX4938_IRC_IRLVL0));
+ }
+ case 19:
+ case 18:
+ case 3:
+ case 2:{
+ return (TX4938_MKA(TX4938_IRC_IRLVL1));
+ }
+ case 21:
+ case 20:
+ case 5:
+ case 4:{
+ return (TX4938_MKA(TX4938_IRC_IRLVL2));
+ }
+ case 23:
+ case 22:
+ case 7:
+ case 6:{
+ return (TX4938_MKA(TX4938_IRC_IRLVL3));
+ }
+ case 25:
+ case 24:
+ case 9:
+ case 8:{
+ return (TX4938_MKA(TX4938_IRC_IRLVL4));
+ }
+ case 27:
+ case 26:
+ case 11:
+ case 10:{
+ return (TX4938_MKA(TX4938_IRC_IRLVL5));
+ }
+ case 29:
+ case 28:
+ case 13:
+ case 12:{
+ return (TX4938_MKA(TX4938_IRC_IRLVL6));
+ }
+ case 31:
+ case 30:
+ case 15:
+ case 14:{
+ return (TX4938_MKA(TX4938_IRC_IRLVL7));
+ }
+ }
+
+ return (0);
+}
+
+u32
+tx4938_irq_pic_mask(int irq)
+{
+ /* MVMCP -- need to formulize this */
+ irq -= TX4938_IRQ_PIC_BEG;
+
+ switch (irq) {
+ case 31:
+ case 29:
+ case 27:
+ case 25:
+ case 23:
+ case 21:
+ case 19:
+ case 17:{
+ return (0x07000000);
+ }
+ case 30:
+ case 28:
+ case 26:
+ case 24:
+ case 22:
+ case 20:
+ case 18:
+ case 16:{
+ return (0x00070000);
+ }
+ case 15:
+ case 13:
+ case 11:
+ case 9:
+ case 7:
+ case 5:
+ case 3:
+ case 1:{
+ return (0x00000700);
+ }
+ case 14:
+ case 12:
+ case 10:
+ case 8:
+ case 6:
+ case 4:
+ case 2:
+ case 0:{
+ return (0x00000007);
+ }
+ }
+ return (0x00000000);
+}
+
+static void
+tx4938_irq_pic_modify(unsigned pic_reg, unsigned clr_bits, unsigned set_bits)
+{
+ unsigned long val = 0;
+
+ val = TX4938_RD(pic_reg);
+ val &= (~clr_bits);
+ val |= (set_bits);
+ TX4938_WR(pic_reg, val);
+ mmiowb();
+ TX4938_RD(pic_reg);
+
+ return;
+}
+
+static void __init
+tx4938_irq_pic_init(void)
+{
+ unsigned long flags;
+ int i;
+
+ for (i = TX4938_IRQ_PIC_BEG; i <= TX4938_IRQ_PIC_END; i++) {
+ irq_desc[i].status = IRQ_DISABLED;
+ irq_desc[i].action = 0;
+ irq_desc[i].depth = 2;
+ irq_desc[i].handler = &tx4938_irq_pic_type;
+ }
+
+ setup_irq(TX4938_IRQ_NEST_PIC_ON_CP0, &tx4938_irq_pic_action);
+
+ spin_lock_irqsave(&tx4938_pic_lock, flags);
+
+ TX4938_WR(0xff1ff640, 0x6); /* irq level mask -- only accept hightest */
+ TX4938_WR(0xff1ff600, TX4938_RD(0xff1ff600) | 0x1); /* irq enable */
+
+ spin_unlock_irqrestore(&tx4938_pic_lock, flags);
+
+ return;
+}
+
+static unsigned int
+tx4938_irq_pic_startup(unsigned int irq)
+{
+ tx4938_irq_pic_enable(irq);
+
+ return (0);
+}
+
+static void
+tx4938_irq_pic_shutdown(unsigned int irq)
+{
+ tx4938_irq_pic_disable(irq);
+
+ return;
+}
+
+static void
+tx4938_irq_pic_enable(unsigned int irq)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&tx4938_pic_lock, flags);
+
+ tx4938_irq_pic_modify(tx4938_irq_pic_addr(irq), 0,
+ tx4938_irq_pic_mask(irq));
+
+ spin_unlock_irqrestore(&tx4938_pic_lock, flags);
+
+ return;
+}
+
+static void
+tx4938_irq_pic_disable(unsigned int irq)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&tx4938_pic_lock, flags);
+
+ tx4938_irq_pic_modify(tx4938_irq_pic_addr(irq),
+ tx4938_irq_pic_mask(irq), 0);
+
+ spin_unlock_irqrestore(&tx4938_pic_lock, flags);
+
+ return;
+}
+
+static void
+tx4938_irq_pic_mask_and_ack(unsigned int irq)
+{
+ tx4938_irq_pic_disable(irq);
+
+ return;
+}
+
+static void
+tx4938_irq_pic_end(unsigned int irq)
+{
+ if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) {
+ tx4938_irq_pic_enable(irq);
+ }
+
+ return;
+}
+
+/**********************************************************************************/
+/* Main init functions */
+/**********************************************************************************/
+
+void __init
+tx4938_irq_init(void)
+{
+ extern asmlinkage void tx4938_irq_handler(void);
+
+ tx4938_irq_cp0_init();
+ tx4938_irq_pic_init();
+ set_except_vector(0, tx4938_irq_handler);
+
+ return;
+}
+
+int
+tx4938_irq_nested(void)
+{
+ int sw_irq = 0;
+ u32 level2;
+
+ level2 = TX4938_RD(0xff1ff6a0);
+ if ((level2 & 0x10000) == 0) {
+ level2 &= 0x1f;
+ sw_irq = TX4938_IRQ_PIC_BEG + level2;
+ if (sw_irq == 26) {
+ {
+ extern int toshiba_rbtx4938_irq_nested(int sw_irq);
+ sw_irq = toshiba_rbtx4938_irq_nested(sw_irq);
+ }
+ }
+ }
+
+ wbflush();
+ return (sw_irq);
+}
diff --git a/arch/mips/tx4938/common/irq_handler.S b/arch/mips/tx4938/common/irq_handler.S
new file mode 100644
index 000000000000..1b2f72bac42d
--- /dev/null
+++ b/arch/mips/tx4938/common/irq_handler.S
@@ -0,0 +1,84 @@
+/*
+ * linux/arch/mips/tx4938/common/handler.S
+ *
+ * Primary interrupt handler for tx4938 based systems
+ * Copyright (C) 2000-2001 Toshiba Corporation
+ *
+ * 2003-2005 (c) MontaVista Software, Inc. This file is licensed under the
+ * terms of the GNU General Public License version 2. This program is
+ * licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ *
+ * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com)
+ */
+#include <asm/asm.h>
+#include <asm/mipsregs.h>
+#include <asm/addrspace.h>
+#include <asm/regdef.h>
+#include <asm/stackframe.h>
+#include <asm/tx4938/rbtx4938.h>
+
+
+ .align 5
+ NESTED(tx4938_irq_handler, PT_SIZE, sp)
+ SAVE_ALL
+ CLI
+ .set at
+
+ mfc0 t0, CP0_CAUSE
+ mfc0 t1, CP0_STATUS
+ and t0, t1
+
+ andi t1, t0, STATUSF_IP7 /* cpu timer */
+ bnez t1, ll_ip7
+
+ /* IP6..IP3 multiplexed -- do not use */
+
+ andi t1, t0, STATUSF_IP2 /* tx4938 pic */
+ bnez t1, ll_ip2
+
+ andi t1, t0, STATUSF_IP1 /* user line 1 */
+ bnez t1, ll_ip1
+
+ andi t1, t0, STATUSF_IP0 /* user line 0 */
+ bnez t1, ll_ip0
+
+ .set reorder
+
+ nop
+ END(tx4938_irq_handler)
+
+ .align 5
+
+
+ll_ip7:
+ li a0, TX4938_IRQ_CPU_TIMER
+ move a1, sp
+ jal do_IRQ
+ j ret_from_irq
+
+
+ll_ip2:
+ jal tx4938_irq_nested
+ nop
+ beqz v0, goto_spurious_interrupt
+ nop
+ move a0, v0
+ move a1, sp
+ jal do_IRQ
+ j ret_from_irq
+
+goto_spurious_interrupt:
+ j ret_from_irq
+
+ll_ip1:
+ li a0, TX4938_IRQ_USER1
+ move a1, sp
+ jal do_IRQ
+ j ret_from_irq
+
+ll_ip0:
+ li a0, TX4938_IRQ_USER0
+ move a1, sp
+ jal do_IRQ
+ j ret_from_irq
diff --git a/arch/mips/tx4938/common/prom.c b/arch/mips/tx4938/common/prom.c
new file mode 100644
index 000000000000..3189a65f7d7e
--- /dev/null
+++ b/arch/mips/tx4938/common/prom.c
@@ -0,0 +1,129 @@
+/*
+ * linux/arch/mips/tx4938/common/prom.c
+ *
+ * common tx4938 memory interface
+ * Copyright (C) 2000-2001 Toshiba Corporation
+ *
+ * 2003-2005 (c) MontaVista Software, Inc. This file is licensed under the
+ * terms of the GNU General Public License version 2. This program is
+ * licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ *
+ * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com)
+ */
+
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/bootmem.h>
+
+#include <asm/addrspace.h>
+#include <asm/bootinfo.h>
+#include <asm/tx4938/tx4938.h>
+
+static unsigned int __init
+tx4938_process_sdccr(u64 * addr)
+{
+ u64 val;
+ unsigned int sdccr_ce;
+ unsigned int sdccr_rs;
+ unsigned int sdccr_cs;
+ unsigned int sdccr_mw;
+ unsigned int rs = 0;
+ unsigned int cs = 0;
+ unsigned int mw = 0;
+ unsigned int bc = 4;
+ unsigned int msize = 0;
+
+ val = (*((vu64 *) (addr)));
+
+ /* MVMCP -- need #defs for these bits masks */
+ sdccr_ce = ((val & (1 << 10)) >> 10);
+ sdccr_rs = ((val & (3 << 5)) >> 5);
+ sdccr_cs = ((val & (7 << 2)) >> 2);
+ sdccr_mw = ((val & (1 << 0)) >> 0);
+
+ if (sdccr_ce) {
+ switch (sdccr_rs) {
+ case 0:{
+ rs = 2048;
+ break;
+ }
+ case 1:{
+ rs = 4096;
+ break;
+ }
+ case 2:{
+ rs = 8192;
+ break;
+ }
+ default:{
+ rs = 0;
+ break;
+ }
+ }
+ switch (sdccr_cs) {
+ case 0:{
+ cs = 256;
+ break;
+ }
+ case 1:{
+ cs = 512;
+ break;
+ }
+ case 2:{
+ cs = 1024;
+ break;
+ }
+ case 3:{
+ cs = 2048;
+ break;
+ }
+ case 4:{
+ cs = 4096;
+ break;
+ }
+ default:{
+ cs = 0;
+ break;
+ }
+ }
+ switch (sdccr_mw) {
+ case 0:{
+ mw = 8;
+ break;
+ } /* 8 bytes = 64 bits */
+ case 1:{
+ mw = 4;
+ break;
+ } /* 4 bytes = 32 bits */
+ }
+ }
+
+ /* bytes per chip MB per chip bank count */
+ msize = (((rs * cs * mw) / (1024 * 1024)) * (bc));
+
+ /* MVMCP -- bc hard coded to 4 from table 9.3.1 */
+ /* boad supports bc=2 but no way to detect */
+
+ return (msize);
+}
+
+unsigned int __init
+tx4938_get_mem_size(void)
+{
+ unsigned int c0;
+ unsigned int c1;
+ unsigned int c2;
+ unsigned int c3;
+ unsigned int total;
+
+ /* MVMCP -- need #defs for these registers */
+ c0 = tx4938_process_sdccr((u64 *) 0xff1f8000);
+ c1 = tx4938_process_sdccr((u64 *) 0xff1f8008);
+ c2 = tx4938_process_sdccr((u64 *) 0xff1f8010);
+ c3 = tx4938_process_sdccr((u64 *) 0xff1f8018);
+ total = c0 + c1 + c2 + c3;
+
+ return (total);
+}
diff --git a/arch/mips/tx4938/common/rtc_rx5c348.c b/arch/mips/tx4938/common/rtc_rx5c348.c
new file mode 100644
index 000000000000..d249edbb6af4
--- /dev/null
+++ b/arch/mips/tx4938/common/rtc_rx5c348.c
@@ -0,0 +1,202 @@
+/*
+ * RTC routines for RICOH Rx5C348 SPI chip.
+ * Copyright (C) 2000-2001 Toshiba Corporation
+ *
+ * 2003-2005 (c) MontaVista Software, Inc. This file is licensed under the
+ * terms of the GNU General Public License version 2. This program is
+ * licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ *
+ * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com)
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/rtc.h>
+#include <linux/time.h>
+#include <asm/time.h>
+#include <asm/tx4938/spi.h>
+
+#define EPOCH 2000
+
+/* registers */
+#define Rx5C348_REG_SECOND 0
+#define Rx5C348_REG_MINUTE 1
+#define Rx5C348_REG_HOUR 2
+#define Rx5C348_REG_WEEK 3
+#define Rx5C348_REG_DAY 4
+#define Rx5C348_REG_MONTH 5
+#define Rx5C348_REG_YEAR 6
+#define Rx5C348_REG_ADJUST 7
+#define Rx5C348_REG_ALARM_W_MIN 8
+#define Rx5C348_REG_ALARM_W_HOUR 9
+#define Rx5C348_REG_ALARM_W_WEEK 10
+#define Rx5C348_REG_ALARM_D_MIN 11
+#define Rx5C348_REG_ALARM_D_HOUR 12
+#define Rx5C348_REG_CTL1 14
+#define Rx5C348_REG_CTL2 15
+
+/* register bits */
+#define Rx5C348_BIT_PM 0x20 /* REG_HOUR */
+#define Rx5C348_BIT_Y2K 0x80 /* REG_MONTH */
+#define Rx5C348_BIT_24H 0x20 /* REG_CTL1 */
+#define Rx5C348_BIT_XSTP 0x10 /* REG_CTL2 */
+
+/* commands */
+#define Rx5C348_CMD_W(addr) (((addr) << 4) | 0x08) /* single write */
+#define Rx5C348_CMD_R(addr) (((addr) << 4) | 0x0c) /* single read */
+#define Rx5C348_CMD_MW(addr) (((addr) << 4) | 0x00) /* burst write */
+#define Rx5C348_CMD_MR(addr) (((addr) << 4) | 0x04) /* burst read */
+
+static struct spi_dev_desc srtc_dev_desc = {
+ .baud = 1000000, /* 1.0Mbps @ Vdd 2.0V */
+ .tcss = 31,
+ .tcsh = 1,
+ .tcsr = 62,
+ /* 31us for Tcss (62us for Tcsr) is required for carry operation) */
+ .byteorder = 1, /* MSB-First */
+ .polarity = 0, /* High-Active */
+ .phase = 1, /* Shift-Then-Sample */
+
+};
+static int srtc_chipid;
+static int srtc_24h;
+
+static inline int
+spi_rtc_io(unsigned char *inbuf, unsigned char *outbuf, unsigned int count)
+{
+ unsigned char *inbufs[1], *outbufs[1];
+ unsigned int incounts[2], outcounts[2];
+ inbufs[0] = inbuf;
+ incounts[0] = count;
+ incounts[1] = 0;
+ outbufs[0] = outbuf;
+ outcounts[0] = count;
+ outcounts[1] = 0;
+ return txx9_spi_io(srtc_chipid, &srtc_dev_desc,
+ inbufs, incounts, outbufs, outcounts, 0);
+}
+
+/*
+ * Conversion between binary and BCD.
+ */
+#ifndef BCD_TO_BIN
+#define BCD_TO_BIN(val) ((val)=((val)&15) + ((val)>>4)*10)
+#endif
+
+#ifndef BIN_TO_BCD
+#define BIN_TO_BCD(val) ((val)=(((val)/10)<<4) + (val)%10)
+#endif
+
+/* RTC-dependent code for time.c */
+
+static int
+rtc_rx5c348_set_time(unsigned long t)
+{
+ unsigned char inbuf[8];
+ struct rtc_time tm;
+ u8 year, month, day, hour, minute, second, century;
+
+ /* convert */
+ to_tm(t, &tm);
+
+ year = tm.tm_year % 100;
+ month = tm.tm_mon+1; /* tm_mon starts from 0 to 11 */
+ day = tm.tm_mday;
+ hour = tm.tm_hour;
+ minute = tm.tm_min;
+ second = tm.tm_sec;
+ century = tm.tm_year / 100;
+
+ inbuf[0] = Rx5C348_CMD_MW(Rx5C348_REG_SECOND);
+ BIN_TO_BCD(second);
+ inbuf[1] = second;
+ BIN_TO_BCD(minute);
+ inbuf[2] = minute;
+
+ if (srtc_24h) {
+ BIN_TO_BCD(hour);
+ inbuf[3] = hour;
+ } else {
+ /* hour 0 is AM12, noon is PM12 */
+ inbuf[3] = 0;
+ if (hour >= 12)
+ inbuf[3] = Rx5C348_BIT_PM;
+ hour = (hour + 11) % 12 + 1;
+ BIN_TO_BCD(hour);
+ inbuf[3] |= hour;
+ }
+ inbuf[4] = 0; /* ignore week */
+ BIN_TO_BCD(day);
+ inbuf[5] = day;
+ BIN_TO_BCD(month);
+ inbuf[6] = month;
+ if (century >= 20)
+ inbuf[6] |= Rx5C348_BIT_Y2K;
+ BIN_TO_BCD(year);
+ inbuf[7] = year;
+ /* write in one transfer to avoid data inconsistency */
+ return spi_rtc_io(inbuf, NULL, 8);
+}
+
+static unsigned long
+rtc_rx5c348_get_time(void)
+{
+ unsigned char inbuf[8], outbuf[8];
+ unsigned int year, month, day, hour, minute, second;
+
+ inbuf[0] = Rx5C348_CMD_MR(Rx5C348_REG_SECOND);
+ memset(inbuf + 1, 0, 7);
+ /* read in one transfer to avoid data inconsistency */
+ if (spi_rtc_io(inbuf, outbuf, 8))
+ return 0;
+ second = outbuf[1];
+ BCD_TO_BIN(second);
+ minute = outbuf[2];
+ BCD_TO_BIN(minute);
+ if (srtc_24h) {
+ hour = outbuf[3];
+ BCD_TO_BIN(hour);
+ } else {
+ hour = outbuf[3] & ~Rx5C348_BIT_PM;
+ BCD_TO_BIN(hour);
+ hour %= 12;
+ if (outbuf[3] & Rx5C348_BIT_PM)
+ hour += 12;
+ }
+ day = outbuf[5];
+ BCD_TO_BIN(day);
+ month = outbuf[6] & ~Rx5C348_BIT_Y2K;
+ BCD_TO_BIN(month);
+ year = outbuf[7];
+ BCD_TO_BIN(year);
+ year += EPOCH;
+
+ return mktime(year, month, day, hour, minute, second);
+}
+
+void __init
+rtc_rx5c348_init(int chipid)
+{
+ unsigned char inbuf[2], outbuf[2];
+ srtc_chipid = chipid;
+ /* turn on RTC if it is not on */
+ inbuf[0] = Rx5C348_CMD_R(Rx5C348_REG_CTL2);
+ inbuf[1] = 0;
+ spi_rtc_io(inbuf, outbuf, 2);
+ if (outbuf[1] & Rx5C348_BIT_XSTP) {
+ inbuf[0] = Rx5C348_CMD_W(Rx5C348_REG_CTL2);
+ inbuf[1] = 0;
+ spi_rtc_io(inbuf, NULL, 2);
+ }
+
+ inbuf[0] = Rx5C348_CMD_R(Rx5C348_REG_CTL1);
+ inbuf[1] = 0;
+ spi_rtc_io(inbuf, outbuf, 2);
+ if (outbuf[1] & Rx5C348_BIT_24H)
+ srtc_24h = 1;
+
+ /* set the function pointers */
+ rtc_get_time = rtc_rx5c348_get_time;
+ rtc_set_time = rtc_rx5c348_set_time;
+}
diff --git a/arch/mips/tx4938/common/setup.c b/arch/mips/tx4938/common/setup.c
new file mode 100644
index 000000000000..fc992953bf95
--- /dev/null
+++ b/arch/mips/tx4938/common/setup.c
@@ -0,0 +1,91 @@
+/*
+ * linux/arch/mips/tx4938/common/setup.c
+ *
+ * common tx4938 setup routines
+ *
+ * 2003-2005 (c) MontaVista Software, Inc. This file is licensed under the
+ * terms of the GNU General Public License version 2. This program is
+ * licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ *
+ * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com)
+ */
+
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/kernel_stat.h>
+#include <linux/module.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/timex.h>
+#include <linux/slab.h>
+#include <linux/random.h>
+#include <linux/irq.h>
+#include <asm/bitops.h>
+#include <asm/bootinfo.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/mipsregs.h>
+#include <asm/system.h>
+#include <asm/time.h>
+#include <asm/time.h>
+#include <asm/tx4938/rbtx4938.h>
+
+extern void toshiba_rbtx4938_setup(void);
+extern void rbtx4938_time_init(void);
+
+void __init tx4938_setup(void);
+void __init tx4938_time_init(void);
+void __init tx4938_timer_setup(struct irqaction *irq);
+void dump_cp0(char *key);
+
+void (*__wbflush) (void);
+
+static void
+tx4938_write_buffer_flush(void)
+{
+ mmiowb();
+
+ __asm__ __volatile__(
+ ".set push\n\t"
+ ".set noreorder\n\t"
+ "lw $0,%0\n\t"
+ "nop\n\t"
+ ".set pop"
+ : /* no output */
+ : "m" (*(int *)KSEG1)
+ : "memory");
+}
+
+void __init
+plat_setup(void)
+{
+ board_time_init = tx4938_time_init;
+ board_timer_setup = tx4938_timer_setup;
+ __wbflush = tx4938_write_buffer_flush;
+ toshiba_rbtx4938_setup();
+}
+
+void __init
+tx4938_time_init(void)
+{
+ rbtx4938_time_init();
+}
+
+void __init
+tx4938_timer_setup(struct irqaction *irq)
+{
+ u32 count;
+ u32 c1;
+ u32 c2;
+
+ setup_irq(TX4938_IRQ_CPU_TIMER, irq);
+
+ c1 = read_c0_count();
+ count = c1 + (mips_hpt_frequency / HZ);
+ write_c0_compare(count);
+ c2 = read_c0_count();
+}
diff --git a/arch/mips/tx4938/toshiba_rbtx4938/Makefile b/arch/mips/tx4938/toshiba_rbtx4938/Makefile
new file mode 100644
index 000000000000..226941279d75
--- /dev/null
+++ b/arch/mips/tx4938/toshiba_rbtx4938/Makefile
@@ -0,0 +1,9 @@
+#
+# Makefile for common code for Toshiba TX4927 based systems
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+
+obj-y += prom.o setup.o irq.o spi_eeprom.o spi_txx9.o
diff --git a/arch/mips/tx4938/toshiba_rbtx4938/irq.c b/arch/mips/tx4938/toshiba_rbtx4938/irq.c
new file mode 100644
index 000000000000..9cd9c0fe2265
--- /dev/null
+++ b/arch/mips/tx4938/toshiba_rbtx4938/irq.c
@@ -0,0 +1,243 @@
+/*
+ * linux/arch/mips/tx4938/toshiba_rbtx4938/irq.c
+ *
+ * Toshiba RBTX4938 specific interrupt handlers
+ * Copyright (C) 2000-2001 Toshiba Corporation
+ *
+ * 2003-2005 (c) MontaVista Software, Inc. This file is licensed under the
+ * terms of the GNU General Public License version 2. This program is
+ * licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ *
+ * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com)
+ */
+
+/*
+IRQ Device
+
+16 TX4938-CP0/00 Software 0
+17 TX4938-CP0/01 Software 1
+18 TX4938-CP0/02 Cascade TX4938-CP0
+19 TX4938-CP0/03 Multiplexed -- do not use
+20 TX4938-CP0/04 Multiplexed -- do not use
+21 TX4938-CP0/05 Multiplexed -- do not use
+22 TX4938-CP0/06 Multiplexed -- do not use
+23 TX4938-CP0/07 CPU TIMER
+
+24 TX4938-PIC/00
+25 TX4938-PIC/01
+26 TX4938-PIC/02 Cascade RBTX4938-IOC
+27 TX4938-PIC/03 RBTX4938 RTL-8019AS Ethernet
+28 TX4938-PIC/04
+29 TX4938-PIC/05 TX4938 ETH1
+30 TX4938-PIC/06 TX4938 ETH0
+31 TX4938-PIC/07
+32 TX4938-PIC/08 TX4938 SIO 0
+33 TX4938-PIC/09 TX4938 SIO 1
+34 TX4938-PIC/10 TX4938 DMA0
+35 TX4938-PIC/11 TX4938 DMA1
+36 TX4938-PIC/12 TX4938 DMA2
+37 TX4938-PIC/13 TX4938 DMA3
+38 TX4938-PIC/14
+39 TX4938-PIC/15
+40 TX4938-PIC/16 TX4938 PCIC
+41 TX4938-PIC/17 TX4938 TMR0
+42 TX4938-PIC/18 TX4938 TMR1
+43 TX4938-PIC/19 TX4938 TMR2
+44 TX4938-PIC/20
+45 TX4938-PIC/21
+46 TX4938-PIC/22 TX4938 PCIERR
+47 TX4938-PIC/23
+48 TX4938-PIC/24
+49 TX4938-PIC/25
+50 TX4938-PIC/26
+51 TX4938-PIC/27
+52 TX4938-PIC/28
+53 TX4938-PIC/29
+54 TX4938-PIC/30
+55 TX4938-PIC/31 TX4938 SPI
+
+56 RBTX4938-IOC/00 PCI-D
+57 RBTX4938-IOC/01 PCI-C
+58 RBTX4938-IOC/02 PCI-B
+59 RBTX4938-IOC/03 PCI-A
+60 RBTX4938-IOC/04 RTC
+61 RBTX4938-IOC/05 ATA
+62 RBTX4938-IOC/06 MODEM
+63 RBTX4938-IOC/07 SWINT
+*/
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/swap.h>
+#include <linux/ioport.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/pci.h>
+#include <linux/timex.h>
+#include <asm/bootinfo.h>
+#include <asm/page.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/processor.h>
+#include <asm/ptrace.h>
+#include <asm/reboot.h>
+#include <asm/time.h>
+#include <linux/bootmem.h>
+#include <asm/tx4938/rbtx4938.h>
+
+static unsigned int toshiba_rbtx4938_irq_ioc_startup(unsigned int irq);
+static void toshiba_rbtx4938_irq_ioc_shutdown(unsigned int irq);
+static void toshiba_rbtx4938_irq_ioc_enable(unsigned int irq);
+static void toshiba_rbtx4938_irq_ioc_disable(unsigned int irq);
+static void toshiba_rbtx4938_irq_ioc_mask_and_ack(unsigned int irq);
+static void toshiba_rbtx4938_irq_ioc_end(unsigned int irq);
+
+DEFINE_SPINLOCK(toshiba_rbtx4938_ioc_lock);
+
+#define TOSHIBA_RBTX4938_IOC_NAME "RBTX4938-IOC"
+static struct hw_interrupt_type toshiba_rbtx4938_irq_ioc_type = {
+ .typename = TOSHIBA_RBTX4938_IOC_NAME,
+ .startup = toshiba_rbtx4938_irq_ioc_startup,
+ .shutdown = toshiba_rbtx4938_irq_ioc_shutdown,
+ .enable = toshiba_rbtx4938_irq_ioc_enable,
+ .disable = toshiba_rbtx4938_irq_ioc_disable,
+ .ack = toshiba_rbtx4938_irq_ioc_mask_and_ack,
+ .end = toshiba_rbtx4938_irq_ioc_end,
+ .set_affinity = NULL
+};
+
+#define TOSHIBA_RBTX4938_IOC_INTR_ENAB 0xb7f02000
+#define TOSHIBA_RBTX4938_IOC_INTR_STAT 0xb7f0200a
+
+int
+toshiba_rbtx4938_irq_nested(int sw_irq)
+{
+ u8 level3;
+
+ level3 = reg_rd08(TOSHIBA_RBTX4938_IOC_INTR_STAT) & 0xff;
+ if (level3) {
+ /* must use fls so onboard ATA has priority */
+ sw_irq = TOSHIBA_RBTX4938_IRQ_IOC_BEG + fls(level3) - 1;
+ }
+
+ wbflush();
+ return sw_irq;
+}
+
+static struct irqaction toshiba_rbtx4938_irq_ioc_action = {
+ .handler = no_action,
+ .flags = 0,
+ .mask = CPU_MASK_NONE,
+ .name = TOSHIBA_RBTX4938_IOC_NAME,
+};
+
+/**********************************************************************************/
+/* Functions for ioc */
+/**********************************************************************************/
+static void __init
+toshiba_rbtx4938_irq_ioc_init(void)
+{
+ int i;
+
+ for (i = TOSHIBA_RBTX4938_IRQ_IOC_BEG;
+ i <= TOSHIBA_RBTX4938_IRQ_IOC_END; i++) {
+ irq_desc[i].status = IRQ_DISABLED;
+ irq_desc[i].action = 0;
+ irq_desc[i].depth = 3;
+ irq_desc[i].handler = &toshiba_rbtx4938_irq_ioc_type;
+ }
+
+ setup_irq(RBTX4938_IRQ_IOCINT,
+ &toshiba_rbtx4938_irq_ioc_action);
+}
+
+static unsigned int
+toshiba_rbtx4938_irq_ioc_startup(unsigned int irq)
+{
+ toshiba_rbtx4938_irq_ioc_enable(irq);
+
+ return 0;
+}
+
+static void
+toshiba_rbtx4938_irq_ioc_shutdown(unsigned int irq)
+{
+ toshiba_rbtx4938_irq_ioc_disable(irq);
+}
+
+static void
+toshiba_rbtx4938_irq_ioc_enable(unsigned int irq)
+{
+ unsigned long flags;
+ volatile unsigned char v;
+
+ spin_lock_irqsave(&toshiba_rbtx4938_ioc_lock, flags);
+
+ v = TX4938_RD08(TOSHIBA_RBTX4938_IOC_INTR_ENAB);
+ v |= (1 << (irq - TOSHIBA_RBTX4938_IRQ_IOC_BEG));
+ TX4938_WR08(TOSHIBA_RBTX4938_IOC_INTR_ENAB, v);
+ mmiowb();
+ TX4938_RD08(TOSHIBA_RBTX4938_IOC_INTR_ENAB);
+
+ spin_unlock_irqrestore(&toshiba_rbtx4938_ioc_lock, flags);
+}
+
+static void
+toshiba_rbtx4938_irq_ioc_disable(unsigned int irq)
+{
+ unsigned long flags;
+ volatile unsigned char v;
+
+ spin_lock_irqsave(&toshiba_rbtx4938_ioc_lock, flags);
+
+ v = TX4938_RD08(TOSHIBA_RBTX4938_IOC_INTR_ENAB);
+ v &= ~(1 << (irq - TOSHIBA_RBTX4938_IRQ_IOC_BEG));
+ TX4938_WR08(TOSHIBA_RBTX4938_IOC_INTR_ENAB, v);
+ mmiowb();
+ TX4938_RD08(TOSHIBA_RBTX4938_IOC_INTR_ENAB);
+
+ spin_unlock_irqrestore(&toshiba_rbtx4938_ioc_lock, flags);
+}
+
+static void
+toshiba_rbtx4938_irq_ioc_mask_and_ack(unsigned int irq)
+{
+ toshiba_rbtx4938_irq_ioc_disable(irq);
+}
+
+static void
+toshiba_rbtx4938_irq_ioc_end(unsigned int irq)
+{
+ if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) {
+ toshiba_rbtx4938_irq_ioc_enable(irq);
+ }
+}
+
+extern void __init txx9_spi_irqinit(int irc_irq);
+
+void __init arch_init_irq(void)
+{
+ extern void tx4938_irq_init(void);
+
+ /* Now, interrupt control disabled, */
+ /* all IRC interrupts are masked, */
+ /* all IRC interrupt mode are Low Active. */
+
+ /* mask all IOC interrupts */
+ *rbtx4938_imask_ptr = 0;
+
+ /* clear SoftInt interrupts */
+ *rbtx4938_softint_ptr = 0;
+ tx4938_irq_init();
+ toshiba_rbtx4938_irq_ioc_init();
+ /* Onboard 10M Ether: High Active */
+ TX4938_WR(TX4938_MKA(TX4938_IRC_IRDM0), 0x00000040);
+
+ if (tx4938_ccfgptr->pcfg & TX4938_PCFG_SPI_SEL) {
+ txx9_spi_irqinit(RBTX4938_IRQ_IRC_SPI);
+ }
+
+ wbflush();
+}
diff --git a/arch/mips/tx4938/toshiba_rbtx4938/prom.c b/arch/mips/tx4938/toshiba_rbtx4938/prom.c
new file mode 100644
index 000000000000..7df8b32ba265
--- /dev/null
+++ b/arch/mips/tx4938/toshiba_rbtx4938/prom.c
@@ -0,0 +1,78 @@
+/*
+ * linux/arch/mips/tx4938/toshiba_rbtx4938/prom.c
+ *
+ * rbtx4938 specific prom routines
+ * Copyright (C) 2000-2001 Toshiba Corporation
+ *
+ * 2003-2005 (c) MontaVista Software, Inc. This file is licensed under the
+ * terms of the GNU General Public License version 2. This program is
+ * licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ *
+ * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com)
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/bootmem.h>
+
+#include <asm/addrspace.h>
+#include <asm/bootinfo.h>
+#include <asm/tx4938/tx4938.h>
+
+void __init prom_init_cmdline(void)
+{
+ int argc = (int) fw_arg0;
+ char **argv = (char **) fw_arg1;
+ int i;
+
+ /* ignore all built-in args if any f/w args given */
+ if (argc > 1) {
+ *arcs_cmdline = '\0';
+ }
+
+ for (i = 1; i < argc; i++) {
+ if (i != 1) {
+ strcat(arcs_cmdline, " ");
+ }
+ strcat(arcs_cmdline, argv[i]);
+ }
+}
+
+void __init prom_init(void)
+{
+ extern int tx4938_get_mem_size(void);
+ int msize;
+#ifndef CONFIG_TX4938_NAND_BOOT
+ prom_init_cmdline();
+#endif
+ mips_machgroup = MACH_GROUP_TOSHIBA;
+ mips_machtype = MACH_TOSHIBA_RBTX4938;
+
+ msize = tx4938_get_mem_size();
+ add_memory_region(0, msize << 20, BOOT_MEM_RAM);
+
+ return;
+}
+
+unsigned long __init prom_free_prom_memory(void)
+{
+ return 0;
+}
+
+void __init prom_fixup_mem_map(unsigned long start, unsigned long end)
+{
+ return;
+}
+
+const char *get_system_type(void)
+{
+ return "Toshiba RBTX4938";
+}
+
+char * __init prom_getcmdline(void)
+{
+ return &(arcs_cmdline[0]);
+}
diff --git a/arch/mips/tx4938/toshiba_rbtx4938/setup.c b/arch/mips/tx4938/toshiba_rbtx4938/setup.c
new file mode 100644
index 000000000000..9f1dcc8ca5a3
--- /dev/null
+++ b/arch/mips/tx4938/toshiba_rbtx4938/setup.c
@@ -0,0 +1,1035 @@
+/*
+ * linux/arch/mips/tx4938/toshiba_rbtx4938/setup.c
+ *
+ * Setup pointers to hardware-dependent routines.
+ * Copyright (C) 2000-2001 Toshiba Corporation
+ *
+ * 2003-2005 (c) MontaVista Software, Inc. This file is licensed under the
+ * terms of the GNU General Public License version 2. This program is
+ * licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ *
+ * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com)
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/ioport.h>
+#include <linux/proc_fs.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/console.h>
+#include <linux/pci.h>
+#include <asm/wbflush.h>
+#include <asm/reboot.h>
+#include <asm/irq.h>
+#include <asm/time.h>
+#include <asm/uaccess.h>
+#include <asm/io.h>
+#include <asm/bootinfo.h>
+#include <asm/tx4938/rbtx4938.h>
+#ifdef CONFIG_SERIAL_TXX9
+#include <linux/tty.h>
+#include <linux/serial.h>
+#include <linux/serial_core.h>
+#endif
+
+extern void rbtx4938_time_init(void) __init;
+extern char * __init prom_getcmdline(void);
+static inline void tx4938_report_pcic_status1(struct tx4938_pcic_reg *pcicptr);
+
+/* These functions are used for rebooting or halting the machine*/
+extern void rbtx4938_machine_restart(char *command);
+extern void rbtx4938_machine_halt(void);
+extern void rbtx4938_machine_power_off(void);
+
+/* clocks */
+unsigned int txx9_master_clock;
+unsigned int txx9_cpu_clock;
+unsigned int txx9_gbus_clock;
+
+unsigned long rbtx4938_ce_base[8];
+unsigned long rbtx4938_ce_size[8];
+int txboard_pci66_mode;
+static int tx4938_pcic_trdyto; /* default: disabled */
+static int tx4938_pcic_retryto; /* default: disabled */
+static int tx4938_ccfg_toeon = 1;
+
+struct tx4938_pcic_reg *pcicptrs[4] = {
+ tx4938_pcicptr /* default setting for TX4938 */
+};
+
+static struct {
+ unsigned long base;
+ unsigned long size;
+} phys_regions[16] __initdata;
+static int num_phys_regions __initdata;
+
+#define PHYS_REGION_MINSIZE 0x10000
+
+void rbtx4938_machine_halt(void)
+{
+ printk(KERN_NOTICE "System Halted\n");
+ local_irq_disable();
+
+ while (1)
+ __asm__(".set\tmips3\n\t"
+ "wait\n\t"
+ ".set\tmips0");
+}
+
+void rbtx4938_machine_power_off(void)
+{
+ rbtx4938_machine_halt();
+ /* no return */
+}
+
+void rbtx4938_machine_restart(char *command)
+{
+ local_irq_disable();
+
+ printk("Rebooting...");
+ *rbtx4938_softresetlock_ptr = 1;
+ *rbtx4938_sfvol_ptr = 1;
+ *rbtx4938_softreset_ptr = 1;
+ wbflush();
+
+ while(1);
+}
+
+void __init
+txboard_add_phys_region(unsigned long base, unsigned long size)
+{
+ if (num_phys_regions >= ARRAY_SIZE(phys_regions)) {
+ printk("phys_region overflow\n");
+ return;
+ }
+ phys_regions[num_phys_regions].base = base;
+ phys_regions[num_phys_regions].size = size;
+ num_phys_regions++;
+}
+unsigned long __init
+txboard_find_free_phys_region(unsigned long begin, unsigned long end,
+ unsigned long size)
+{
+ unsigned long base;
+ int i;
+
+ for (base = begin / size * size; base < end; base += size) {
+ for (i = 0; i < num_phys_regions; i++) {
+ if (phys_regions[i].size &&
+ base <= phys_regions[i].base + (phys_regions[i].size - 1) &&
+ base + (size - 1) >= phys_regions[i].base)
+ break;
+ }
+ if (i == num_phys_regions)
+ return base;
+ }
+ return 0;
+}
+unsigned long __init
+txboard_find_free_phys_region_shrink(unsigned long begin, unsigned long end,
+ unsigned long *size)
+{
+ unsigned long sz, base;
+ for (sz = *size; sz >= PHYS_REGION_MINSIZE; sz /= 2) {
+ base = txboard_find_free_phys_region(begin, end, sz);
+ if (base) {
+ *size = sz;
+ return base;
+ }
+ }
+ return 0;
+}
+unsigned long __init
+txboard_request_phys_region_range(unsigned long begin, unsigned long end,
+ unsigned long size)
+{
+ unsigned long base;
+ base = txboard_find_free_phys_region(begin, end, size);
+ if (base)
+ txboard_add_phys_region(base, size);
+ return base;
+}
+unsigned long __init
+txboard_request_phys_region(unsigned long size)
+{
+ unsigned long base;
+ unsigned long begin = 0, end = 0x20000000; /* search low 512MB */
+ base = txboard_find_free_phys_region(begin, end, size);
+ if (base)
+ txboard_add_phys_region(base, size);
+ return base;
+}
+unsigned long __init
+txboard_request_phys_region_shrink(unsigned long *size)
+{
+ unsigned long base;
+ unsigned long begin = 0, end = 0x20000000; /* search low 512MB */
+ base = txboard_find_free_phys_region_shrink(begin, end, size);
+ if (base)
+ txboard_add_phys_region(base, *size);
+ return base;
+}
+
+#ifdef CONFIG_PCI
+void __init
+tx4938_pcic_setup(struct tx4938_pcic_reg *pcicptr,
+ struct pci_controller *channel,
+ unsigned long pci_io_base,
+ int extarb)
+{
+ int i;
+
+ /* Disable All Initiator Space */
+ pcicptr->pciccfg &= ~(TX4938_PCIC_PCICCFG_G2PMEN(0)|
+ TX4938_PCIC_PCICCFG_G2PMEN(1)|
+ TX4938_PCIC_PCICCFG_G2PMEN(2)|
+ TX4938_PCIC_PCICCFG_G2PIOEN);
+
+ /* GB->PCI mappings */
+ pcicptr->g2piomask = (channel->io_resource->end - channel->io_resource->start) >> 4;
+ pcicptr->g2piogbase = pci_io_base |
+#ifdef __BIG_ENDIAN
+ TX4938_PCIC_G2PIOGBASE_ECHG
+#else
+ TX4938_PCIC_G2PIOGBASE_BSDIS
+#endif
+ ;
+ pcicptr->g2piopbase = 0;
+ for (i = 0; i < 3; i++) {
+ pcicptr->g2pmmask[i] = 0;
+ pcicptr->g2pmgbase[i] = 0;
+ pcicptr->g2pmpbase[i] = 0;
+ }
+ if (channel->mem_resource->end) {
+ pcicptr->g2pmmask[0] = (channel->mem_resource->end - channel->mem_resource->start) >> 4;
+ pcicptr->g2pmgbase[0] = channel->mem_resource->start |
+#ifdef __BIG_ENDIAN
+ TX4938_PCIC_G2PMnGBASE_ECHG
+#else
+ TX4938_PCIC_G2PMnGBASE_BSDIS
+#endif
+ ;
+ pcicptr->g2pmpbase[0] = channel->mem_resource->start;
+ }
+ /* PCI->GB mappings (I/O 256B) */
+ pcicptr->p2giopbase = 0; /* 256B */
+ pcicptr->p2giogbase = 0;
+ /* PCI->GB mappings (MEM 512MB (64MB on R1.x)) */
+ pcicptr->p2gm0plbase = 0;
+ pcicptr->p2gm0pubase = 0;
+ pcicptr->p2gmgbase[0] = 0 |
+ TX4938_PCIC_P2GMnGBASE_TMEMEN |
+#ifdef __BIG_ENDIAN
+ TX4938_PCIC_P2GMnGBASE_TECHG
+#else
+ TX4938_PCIC_P2GMnGBASE_TBSDIS
+#endif
+ ;
+ /* PCI->GB mappings (MEM 16MB) */
+ pcicptr->p2gm1plbase = 0xffffffff;
+ pcicptr->p2gm1pubase = 0xffffffff;
+ pcicptr->p2gmgbase[1] = 0;
+ /* PCI->GB mappings (MEM 1MB) */
+ pcicptr->p2gm2pbase = 0xffffffff; /* 1MB */
+ pcicptr->p2gmgbase[2] = 0;
+
+ pcicptr->pciccfg &= TX4938_PCIC_PCICCFG_GBWC_MASK;
+ /* Enable Initiator Memory Space */
+ if (channel->mem_resource->end)
+ pcicptr->pciccfg |= TX4938_PCIC_PCICCFG_G2PMEN(0);
+ /* Enable Initiator I/O Space */
+ if (channel->io_resource->end)
+ pcicptr->pciccfg |= TX4938_PCIC_PCICCFG_G2PIOEN;
+ /* Enable Initiator Config */
+ pcicptr->pciccfg |=
+ TX4938_PCIC_PCICCFG_ICAEN |
+ TX4938_PCIC_PCICCFG_TCAR;
+
+ /* Do not use MEMMUL, MEMINF: YMFPCI card causes M_ABORT. */
+ pcicptr->pcicfg1 = 0;
+
+ pcicptr->g2ptocnt &= ~0xffff;
+
+ if (tx4938_pcic_trdyto >= 0) {
+ pcicptr->g2ptocnt &= ~0xff;
+ pcicptr->g2ptocnt |= (tx4938_pcic_trdyto & 0xff);
+ }
+
+ if (tx4938_pcic_retryto >= 0) {
+ pcicptr->g2ptocnt &= ~0xff00;
+ pcicptr->g2ptocnt |= ((tx4938_pcic_retryto<<8) & 0xff00);
+ }
+
+ /* Clear All Local Bus Status */
+ pcicptr->pcicstatus = TX4938_PCIC_PCICSTATUS_ALL;
+ /* Enable All Local Bus Interrupts */
+ pcicptr->pcicmask = TX4938_PCIC_PCICSTATUS_ALL;
+ /* Clear All Initiator Status */
+ pcicptr->g2pstatus = TX4938_PCIC_G2PSTATUS_ALL;
+ /* Enable All Initiator Interrupts */
+ pcicptr->g2pmask = TX4938_PCIC_G2PSTATUS_ALL;
+ /* Clear All PCI Status Error */
+ pcicptr->pcistatus =
+ (pcicptr->pcistatus & 0x0000ffff) |
+ (TX4938_PCIC_PCISTATUS_ALL << 16);
+ /* Enable All PCI Status Error Interrupts */
+ pcicptr->pcimask = TX4938_PCIC_PCISTATUS_ALL;
+
+ if (!extarb) {
+ /* Reset Bus Arbiter */
+ pcicptr->pbacfg = TX4938_PCIC_PBACFG_RPBA;
+ pcicptr->pbabm = 0;
+ /* Enable Bus Arbiter */
+ pcicptr->pbacfg = TX4938_PCIC_PBACFG_PBAEN;
+ }
+
+ /* PCIC Int => IRC IRQ16 */
+ pcicptr->pcicfg2 =
+ (pcicptr->pcicfg2 & 0xffffff00) | TX4938_IR_PCIC;
+
+ pcicptr->pcistatus = PCI_COMMAND_MASTER |
+ PCI_COMMAND_MEMORY |
+ PCI_COMMAND_PARITY | PCI_COMMAND_SERR;
+}
+
+int __init
+tx4938_report_pciclk(void)
+{
+ unsigned long pcode = TX4938_REV_PCODE();
+ int pciclk = 0;
+ printk("TX%lx PCIC --%s PCICLK:",
+ pcode,
+ (tx4938_ccfgptr->ccfg & TX4938_CCFG_PCI66) ? " PCI66" : "");
+ if (tx4938_ccfgptr->pcfg & TX4938_PCFG_PCICLKEN_ALL) {
+
+ switch ((unsigned long)tx4938_ccfgptr->ccfg & TX4938_CCFG_PCIDIVMODE_MASK) {
+ case TX4938_CCFG_PCIDIVMODE_4:
+ pciclk = txx9_cpu_clock / 4; break;
+ case TX4938_CCFG_PCIDIVMODE_4_5:
+ pciclk = txx9_cpu_clock * 2 / 9; break;
+ case TX4938_CCFG_PCIDIVMODE_5:
+ pciclk = txx9_cpu_clock / 5; break;
+ case TX4938_CCFG_PCIDIVMODE_5_5:
+ pciclk = txx9_cpu_clock * 2 / 11; break;
+ case TX4938_CCFG_PCIDIVMODE_8:
+ pciclk = txx9_cpu_clock / 8; break;
+ case TX4938_CCFG_PCIDIVMODE_9:
+ pciclk = txx9_cpu_clock / 9; break;
+ case TX4938_CCFG_PCIDIVMODE_10:
+ pciclk = txx9_cpu_clock / 10; break;
+ case TX4938_CCFG_PCIDIVMODE_11:
+ pciclk = txx9_cpu_clock / 11; break;
+ }
+ printk("Internal(%dMHz)", pciclk / 1000000);
+ } else {
+ printk("External");
+ pciclk = -1;
+ }
+ printk("\n");
+ return pciclk;
+}
+
+void __init set_tx4938_pcicptr(int ch, struct tx4938_pcic_reg *pcicptr)
+{
+ pcicptrs[ch] = pcicptr;
+}
+
+struct tx4938_pcic_reg *get_tx4938_pcicptr(int ch)
+{
+ return pcicptrs[ch];
+}
+
+static struct pci_dev *fake_pci_dev(struct pci_controller *hose,
+ int top_bus, int busnr, int devfn)
+{
+ static struct pci_dev dev;
+ static struct pci_bus bus;
+
+ dev.sysdata = (void *)hose;
+ dev.devfn = devfn;
+ bus.number = busnr;
+ bus.ops = hose->pci_ops;
+ bus.parent = NULL;
+ dev.bus = &bus;
+
+ return &dev;
+}
+
+#define EARLY_PCI_OP(rw, size, type) \
+static int early_##rw##_config_##size(struct pci_controller *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, word, u16 *)
+
+int txboard_pci66_check(struct pci_controller *hose, int top_bus, int current_bus)
+{
+ u32 pci_devfn;
+ unsigned short vid;
+ int devfn_start = 0;
+ int devfn_stop = 0xff;
+ int cap66 = -1;
+ u16 stat;
+
+ printk("PCI: Checking 66MHz capabilities...\n");
+
+ for (pci_devfn=devfn_start; pci_devfn<devfn_stop; pci_devfn++) {
+ early_read_config_word(hose, top_bus, current_bus, pci_devfn,
+ PCI_VENDOR_ID, &vid);
+
+ if (vid == 0xffff) continue;
+
+ /* check 66MHz capability */
+ if (cap66 < 0)
+ cap66 = 1;
+ if (cap66) {
+ early_read_config_word(hose, top_bus, current_bus, pci_devfn,
+ PCI_STATUS, &stat);
+ if (!(stat & PCI_STATUS_66MHZ)) {
+ printk(KERN_DEBUG "PCI: %02x:%02x not 66MHz capable.\n",
+ current_bus, pci_devfn);
+ cap66 = 0;
+ break;
+ }
+ }
+ }
+ return cap66 > 0;
+}
+
+int __init
+tx4938_pciclk66_setup(void)
+{
+ int pciclk;
+
+ /* Assert M66EN */
+ tx4938_ccfgptr->ccfg |= TX4938_CCFG_PCI66;
+ /* Double PCICLK (if possible) */
+ if (tx4938_ccfgptr->pcfg & TX4938_PCFG_PCICLKEN_ALL) {
+ unsigned int pcidivmode =
+ tx4938_ccfgptr->ccfg & TX4938_CCFG_PCIDIVMODE_MASK;
+ switch (pcidivmode) {
+ case TX4938_CCFG_PCIDIVMODE_8:
+ case TX4938_CCFG_PCIDIVMODE_4:
+ pcidivmode = TX4938_CCFG_PCIDIVMODE_4;
+ pciclk = txx9_cpu_clock / 4;
+ break;
+ case TX4938_CCFG_PCIDIVMODE_9:
+ case TX4938_CCFG_PCIDIVMODE_4_5:
+ pcidivmode = TX4938_CCFG_PCIDIVMODE_4_5;
+ pciclk = txx9_cpu_clock * 2 / 9;
+ break;
+ case TX4938_CCFG_PCIDIVMODE_10:
+ case TX4938_CCFG_PCIDIVMODE_5:
+ pcidivmode = TX4938_CCFG_PCIDIVMODE_5;
+ pciclk = txx9_cpu_clock / 5;
+ break;
+ case TX4938_CCFG_PCIDIVMODE_11:
+ case TX4938_CCFG_PCIDIVMODE_5_5:
+ default:
+ pcidivmode = TX4938_CCFG_PCIDIVMODE_5_5;
+ pciclk = txx9_cpu_clock * 2 / 11;
+ break;
+ }
+ tx4938_ccfgptr->ccfg =
+ (tx4938_ccfgptr->ccfg & ~TX4938_CCFG_PCIDIVMODE_MASK)
+ | pcidivmode;
+ printk(KERN_DEBUG "PCICLK: ccfg:%08lx\n",
+ (unsigned long)tx4938_ccfgptr->ccfg);
+ } else {
+ pciclk = -1;
+ }
+ return pciclk;
+}
+
+extern struct pci_controller tx4938_pci_controller[];
+static int __init tx4938_pcibios_init(void)
+{
+ unsigned long mem_base[2];
+ unsigned long mem_size[2] = {TX4938_PCIMEM_SIZE_0,TX4938_PCIMEM_SIZE_1}; /* MAX 128M,64K */
+ unsigned long io_base[2];
+ unsigned long io_size[2] = {TX4938_PCIIO_SIZE_0,TX4938_PCIIO_SIZE_1}; /* MAX 16M,64K */
+ /* TX4938 PCIC1: 64K MEM/IO is enough for ETH0,ETH1 */
+ int extarb = !(tx4938_ccfgptr->ccfg & TX4938_CCFG_PCIXARB);
+
+ PCIBIOS_MIN_IO = 0x00001000UL;
+ PCIBIOS_MIN_MEM = 0x01000000UL;
+
+ mem_base[0] = txboard_request_phys_region_shrink(&mem_size[0]);
+ io_base[0] = txboard_request_phys_region_shrink(&io_size[0]);
+
+ printk("TX4938 PCIC -- DID:%04x VID:%04x RID:%02x Arbiter:%s\n",
+ (unsigned short)(tx4938_pcicptr->pciid >> 16),
+ (unsigned short)(tx4938_pcicptr->pciid & 0xffff),
+ (unsigned short)(tx4938_pcicptr->pciccrev & 0xff),
+ extarb ? "External" : "Internal");
+
+ /* setup PCI area */
+ tx4938_pci_controller[0].io_resource->start = io_base[0];
+ tx4938_pci_controller[0].io_resource->end = (io_base[0] + io_size[0]) - 1;
+ tx4938_pci_controller[0].mem_resource->start = mem_base[0];
+ tx4938_pci_controller[0].mem_resource->end = mem_base[0] + mem_size[0] - 1;
+
+ set_tx4938_pcicptr(0, tx4938_pcicptr);
+
+ register_pci_controller(&tx4938_pci_controller[0]);
+
+ if (tx4938_ccfgptr->ccfg & TX4938_CCFG_PCI66) {
+ printk("TX4938_CCFG_PCI66 already configured\n");
+ txboard_pci66_mode = -1; /* already configured */
+ }
+
+ /* Reset PCI Bus */
+ *rbtx4938_pcireset_ptr = 0;
+ /* Reset PCIC */
+ tx4938_ccfgptr->clkctr |= TX4938_CLKCTR_PCIRST;
+ if (txboard_pci66_mode > 0)
+ tx4938_pciclk66_setup();
+ mdelay(10);
+ /* clear PCIC reset */
+ tx4938_ccfgptr->clkctr &= ~TX4938_CLKCTR_PCIRST;
+ *rbtx4938_pcireset_ptr = 1;
+ wbflush();
+ tx4938_report_pcic_status1(tx4938_pcicptr);
+
+ tx4938_report_pciclk();
+ tx4938_pcic_setup(tx4938_pcicptr, &tx4938_pci_controller[0], io_base[0], extarb);
+ if (txboard_pci66_mode == 0 &&
+ txboard_pci66_check(&tx4938_pci_controller[0], 0, 0)) {
+ /* Reset PCI Bus */
+ *rbtx4938_pcireset_ptr = 0;
+ /* Reset PCIC */
+ tx4938_ccfgptr->clkctr |= TX4938_CLKCTR_PCIRST;
+ tx4938_pciclk66_setup();
+ mdelay(10);
+ /* clear PCIC reset */
+ tx4938_ccfgptr->clkctr &= ~TX4938_CLKCTR_PCIRST;
+ *rbtx4938_pcireset_ptr = 1;
+ wbflush();
+ /* Reinitialize PCIC */
+ tx4938_report_pciclk();
+ tx4938_pcic_setup(tx4938_pcicptr, &tx4938_pci_controller[0], io_base[0], extarb);
+ }
+
+ mem_base[1] = txboard_request_phys_region_shrink(&mem_size[1]);
+ io_base[1] = txboard_request_phys_region_shrink(&io_size[1]);
+ /* Reset PCIC1 */
+ tx4938_ccfgptr->clkctr |= TX4938_CLKCTR_PCIC1RST;
+ /* PCI1DMD==0 => PCI1CLK==GBUSCLK/2 => PCI66 */
+ if (!(tx4938_ccfgptr->ccfg & TX4938_CCFG_PCI1DMD))
+ tx4938_ccfgptr->ccfg |= TX4938_CCFG_PCI1_66;
+ else
+ tx4938_ccfgptr->ccfg &= ~TX4938_CCFG_PCI1_66;
+ mdelay(10);
+ /* clear PCIC1 reset */
+ tx4938_ccfgptr->clkctr &= ~TX4938_CLKCTR_PCIC1RST;
+ tx4938_report_pcic_status1(tx4938_pcic1ptr);
+
+ printk("TX4938 PCIC1 -- DID:%04x VID:%04x RID:%02x",
+ (unsigned short)(tx4938_pcic1ptr->pciid >> 16),
+ (unsigned short)(tx4938_pcic1ptr->pciid & 0xffff),
+ (unsigned short)(tx4938_pcic1ptr->pciccrev & 0xff));
+ printk("%s PCICLK:%dMHz\n",
+ (tx4938_ccfgptr->ccfg & TX4938_CCFG_PCI1_66) ? " PCI66" : "",
+ txx9_gbus_clock /
+ ((tx4938_ccfgptr->ccfg & TX4938_CCFG_PCI1DMD) ? 4 : 2) /
+ 1000000);
+
+ /* assumption: CPHYSADDR(mips_io_port_base) == io_base[0] */
+ tx4938_pci_controller[1].io_resource->start =
+ io_base[1] - io_base[0];
+ tx4938_pci_controller[1].io_resource->end =
+ io_base[1] - io_base[0] + io_size[1] - 1;
+ tx4938_pci_controller[1].mem_resource->start = mem_base[1];
+ tx4938_pci_controller[1].mem_resource->end =
+ mem_base[1] + mem_size[1] - 1;
+ set_tx4938_pcicptr(1, tx4938_pcic1ptr);
+
+ register_pci_controller(&tx4938_pci_controller[1]);
+
+ tx4938_pcic_setup(tx4938_pcic1ptr, &tx4938_pci_controller[1], io_base[1], extarb);
+
+ /* map ioport 0 to PCI I/O space address 0 */
+ set_io_port_base(KSEG1 + io_base[0]);
+
+ return 0;
+}
+
+arch_initcall(tx4938_pcibios_init);
+
+#endif /* CONFIG_PCI */
+
+/* SPI support */
+
+/* chip select for SPI devices */
+#define SEEPROM1_CS 7 /* PIO7 */
+#define SEEPROM2_CS 0 /* IOC */
+#define SEEPROM3_CS 1 /* IOC */
+#define SRTC_CS 2 /* IOC */
+
+static int rbtx4938_spi_cs_func(int chipid, int on)
+{
+ unsigned char bit;
+ switch (chipid) {
+ case RBTX4938_SEEPROM1_CHIPID:
+ if (on)
+ tx4938_pioptr->dout &= ~(1 << SEEPROM1_CS);
+ else
+ tx4938_pioptr->dout |= (1 << SEEPROM1_CS);
+ return 0;
+ break;
+ case RBTX4938_SEEPROM2_CHIPID:
+ bit = (1 << SEEPROM2_CS);
+ break;
+ case RBTX4938_SEEPROM3_CHIPID:
+ bit = (1 << SEEPROM3_CS);
+ break;
+ case RBTX4938_SRTC_CHIPID:
+ bit = (1 << SRTC_CS);
+ break;
+ default:
+ return -ENODEV;
+ }
+ /* bit1,2,4 are low active, bit3 is high active */
+ *rbtx4938_spics_ptr =
+ (*rbtx4938_spics_ptr & ~bit) |
+ ((on ? (bit ^ 0x0b) : ~(bit ^ 0x0b)) & bit);
+ return 0;
+}
+
+#ifdef CONFIG_PCI
+extern int spi_eeprom_read(int chipid, int address, unsigned char *buf, int len);
+
+int rbtx4938_get_tx4938_ethaddr(struct pci_dev *dev, unsigned char *addr)
+{
+ struct pci_controller *channel = (struct pci_controller *)dev->bus->sysdata;
+ static unsigned char dat[17];
+ static int read_dat = 0;
+ int ch = 0;
+
+ if (channel != &tx4938_pci_controller[1])
+ return -ENODEV;
+ /* TX4938 PCIC1 */
+ switch (PCI_SLOT(dev->devfn)) {
+ case TX4938_PCIC_IDSEL_AD_TO_SLOT(31):
+ ch = 0;
+ break;
+ case TX4938_PCIC_IDSEL_AD_TO_SLOT(30):
+ ch = 1;
+ break;
+ default:
+ return -ENODEV;
+ }
+ if (!read_dat) {
+ unsigned char sum;
+ int i;
+ read_dat = 1;
+ /* 0-3: "MAC\0", 4-9:eth0, 10-15:eth1, 16:sum */
+ if (spi_eeprom_read(RBTX4938_SEEPROM1_CHIPID,
+ 0, dat, sizeof(dat))) {
+ printk(KERN_ERR "seeprom: read error.\n");
+ } else {
+ if (strcmp(dat, "MAC") != 0)
+ printk(KERN_WARNING "seeprom: bad signature.\n");
+ for (i = 0, sum = 0; i < sizeof(dat); i++)
+ sum += dat[i];
+ if (sum)
+ printk(KERN_WARNING "seeprom: bad checksum.\n");
+ }
+ }
+ memcpy(addr, &dat[4 + 6 * ch], 6);
+ return 0;
+}
+#endif /* CONFIG_PCI */
+
+extern void __init txx9_spi_init(unsigned long base, int (*cs_func)(int chipid, int on));
+static void __init rbtx4938_spi_setup(void)
+{
+ /* set SPI_SEL */
+ tx4938_ccfgptr->pcfg |= TX4938_PCFG_SPI_SEL;
+ /* chip selects for SPI devices */
+ tx4938_pioptr->dout |= (1 << SEEPROM1_CS);
+ tx4938_pioptr->dir |= (1 << SEEPROM1_CS);
+ txx9_spi_init(TX4938_SPI_REG, rbtx4938_spi_cs_func);
+}
+
+static struct resource rbtx4938_fpga_resource;
+
+static char pcode_str[8];
+static struct resource tx4938_reg_resource = {
+ pcode_str, TX4938_REG_BASE, TX4938_REG_BASE+TX4938_REG_SIZE, IORESOURCE_MEM
+};
+
+void __init tx4938_board_setup(void)
+{
+ int i;
+ unsigned long divmode;
+ int cpuclk = 0;
+ unsigned long pcode = TX4938_REV_PCODE();
+
+ ioport_resource.start = 0x1000;
+ ioport_resource.end = 0xffffffff;
+ iomem_resource.start = 0x1000;
+ iomem_resource.end = 0xffffffff; /* expand to 4GB */
+
+ sprintf(pcode_str, "TX%lx", pcode);
+ /* SDRAMC,EBUSC are configured by PROM */
+ for (i = 0; i < 8; i++) {
+ if (!(tx4938_ebuscptr->cr[i] & 0x8))
+ continue; /* disabled */
+ rbtx4938_ce_base[i] = (unsigned long)TX4938_EBUSC_BA(i);
+ txboard_add_phys_region(rbtx4938_ce_base[i], TX4938_EBUSC_SIZE(i));
+ }
+
+ /* clocks */
+ if (txx9_master_clock) {
+ /* calculate gbus_clock and cpu_clock from master_clock */
+ divmode = (unsigned long)tx4938_ccfgptr->ccfg & TX4938_CCFG_DIVMODE_MASK;
+ switch (divmode) {
+ case TX4938_CCFG_DIVMODE_8:
+ case TX4938_CCFG_DIVMODE_10:
+ case TX4938_CCFG_DIVMODE_12:
+ case TX4938_CCFG_DIVMODE_16:
+ case TX4938_CCFG_DIVMODE_18:
+ txx9_gbus_clock = txx9_master_clock * 4; break;
+ default:
+ txx9_gbus_clock = txx9_master_clock;
+ }
+ switch (divmode) {
+ case TX4938_CCFG_DIVMODE_2:
+ case TX4938_CCFG_DIVMODE_8:
+ cpuclk = txx9_gbus_clock * 2; break;
+ case TX4938_CCFG_DIVMODE_2_5:
+ case TX4938_CCFG_DIVMODE_10:
+ cpuclk = txx9_gbus_clock * 5 / 2; break;
+ case TX4938_CCFG_DIVMODE_3:
+ case TX4938_CCFG_DIVMODE_12:
+ cpuclk = txx9_gbus_clock * 3; break;
+ case TX4938_CCFG_DIVMODE_4:
+ case TX4938_CCFG_DIVMODE_16:
+ cpuclk = txx9_gbus_clock * 4; break;
+ case TX4938_CCFG_DIVMODE_4_5:
+ case TX4938_CCFG_DIVMODE_18:
+ cpuclk = txx9_gbus_clock * 9 / 2; break;
+ }
+ txx9_cpu_clock = cpuclk;
+ } else {
+ if (txx9_cpu_clock == 0) {
+ txx9_cpu_clock = 300000000; /* 300MHz */
+ }
+ /* calculate gbus_clock and master_clock from cpu_clock */
+ cpuclk = txx9_cpu_clock;
+ divmode = (unsigned long)tx4938_ccfgptr->ccfg & TX4938_CCFG_DIVMODE_MASK;
+ switch (divmode) {
+ case TX4938_CCFG_DIVMODE_2:
+ case TX4938_CCFG_DIVMODE_8:
+ txx9_gbus_clock = cpuclk / 2; break;
+ case TX4938_CCFG_DIVMODE_2_5:
+ case TX4938_CCFG_DIVMODE_10:
+ txx9_gbus_clock = cpuclk * 2 / 5; break;
+ case TX4938_CCFG_DIVMODE_3:
+ case TX4938_CCFG_DIVMODE_12:
+ txx9_gbus_clock = cpuclk / 3; break;
+ case TX4938_CCFG_DIVMODE_4:
+ case TX4938_CCFG_DIVMODE_16:
+ txx9_gbus_clock = cpuclk / 4; break;
+ case TX4938_CCFG_DIVMODE_4_5:
+ case TX4938_CCFG_DIVMODE_18:
+ txx9_gbus_clock = cpuclk * 2 / 9; break;
+ }
+ switch (divmode) {
+ case TX4938_CCFG_DIVMODE_8:
+ case TX4938_CCFG_DIVMODE_10:
+ case TX4938_CCFG_DIVMODE_12:
+ case TX4938_CCFG_DIVMODE_16:
+ case TX4938_CCFG_DIVMODE_18:
+ txx9_master_clock = txx9_gbus_clock / 4; break;
+ default:
+ txx9_master_clock = txx9_gbus_clock;
+ }
+ }
+ /* change default value to udelay/mdelay take reasonable time */
+ loops_per_jiffy = txx9_cpu_clock / HZ / 2;
+
+ /* CCFG */
+ /* clear WatchDogReset,BusErrorOnWrite flag (W1C) */
+ tx4938_ccfgptr->ccfg |= TX4938_CCFG_WDRST | TX4938_CCFG_BEOW;
+ /* clear PCIC1 reset */
+ if (tx4938_ccfgptr->clkctr & TX4938_CLKCTR_PCIC1RST)
+ tx4938_ccfgptr->clkctr &= ~TX4938_CLKCTR_PCIC1RST;
+
+ /* enable Timeout BusError */
+ if (tx4938_ccfg_toeon)
+ tx4938_ccfgptr->ccfg |= TX4938_CCFG_TOE;
+
+ /* DMA selection */
+ tx4938_ccfgptr->pcfg &= ~TX4938_PCFG_DMASEL_ALL;
+
+ /* Use external clock for external arbiter */
+ if (!(tx4938_ccfgptr->ccfg & TX4938_CCFG_PCIXARB))
+ tx4938_ccfgptr->pcfg &= ~TX4938_PCFG_PCICLKEN_ALL;
+
+ printk("%s -- %dMHz(M%dMHz) CRIR:%08lx CCFG:%Lx PCFG:%Lx\n",
+ pcode_str,
+ cpuclk / 1000000, txx9_master_clock / 1000000,
+ (unsigned long)tx4938_ccfgptr->crir,
+ tx4938_ccfgptr->ccfg,
+ tx4938_ccfgptr->pcfg);
+
+ printk("%s SDRAMC --", pcode_str);
+ for (i = 0; i < 4; i++) {
+ unsigned long long cr = tx4938_sdramcptr->cr[i];
+ unsigned long ram_base, ram_size;
+ if (!((unsigned long)cr & 0x00000400))
+ continue; /* disabled */
+ ram_base = (unsigned long)(cr >> 49) << 21;
+ ram_size = ((unsigned long)(cr >> 33) + 1) << 21;
+ if (ram_base >= 0x20000000)
+ continue; /* high memory (ignore) */
+ printk(" CR%d:%016Lx", i, cr);
+ txboard_add_phys_region(ram_base, ram_size);
+ }
+ printk(" TR:%09Lx\n", tx4938_sdramcptr->tr);
+
+ /* SRAM */
+ if (pcode == 0x4938 && tx4938_sramcptr->cr & 1) {
+ unsigned int size = 0x800;
+ unsigned long base =
+ (tx4938_sramcptr->cr >> (39-11)) & ~(size - 1);
+ txboard_add_phys_region(base, size);
+ }
+
+ /* IRC */
+ /* disable interrupt control */
+ tx4938_ircptr->cer = 0;
+
+ /* TMR */
+ /* disable all timers */
+ for (i = 0; i < TX4938_NR_TMR; i++) {
+ tx4938_tmrptr(i)->tcr = 0x00000020;
+ tx4938_tmrptr(i)->tisr = 0;
+ tx4938_tmrptr(i)->cpra = 0xffffffff;
+ tx4938_tmrptr(i)->itmr = 0;
+ tx4938_tmrptr(i)->ccdr = 0;
+ tx4938_tmrptr(i)->pgmr = 0;
+ }
+
+ /* enable DMA */
+ TX4938_WR64(0xff1fb150, TX4938_DMA_MCR_MSTEN);
+ TX4938_WR64(0xff1fb950, TX4938_DMA_MCR_MSTEN);
+
+ /* PIO */
+ tx4938_pioptr->maskcpu = 0;
+ tx4938_pioptr->maskext = 0;
+
+ /* TX4938 internal registers */
+ if (request_resource(&iomem_resource, &tx4938_reg_resource))
+ printk("request resource for internal registers failed\n");
+}
+
+#ifdef CONFIG_PCI
+static inline void tx4938_report_pcic_status1(struct tx4938_pcic_reg *pcicptr)
+{
+ unsigned short pcistatus = (unsigned short)(pcicptr->pcistatus >> 16);
+ unsigned long g2pstatus = pcicptr->g2pstatus;
+ unsigned long pcicstatus = pcicptr->pcicstatus;
+ static struct {
+ unsigned long flag;
+ const char *str;
+ } pcistat_tbl[] = {
+ { PCI_STATUS_DETECTED_PARITY, "DetectedParityError" },
+ { PCI_STATUS_SIG_SYSTEM_ERROR, "SignaledSystemError" },
+ { PCI_STATUS_REC_MASTER_ABORT, "ReceivedMasterAbort" },
+ { PCI_STATUS_REC_TARGET_ABORT, "ReceivedTargetAbort" },
+ { PCI_STATUS_SIG_TARGET_ABORT, "SignaledTargetAbort" },
+ { PCI_STATUS_PARITY, "MasterParityError" },
+ }, g2pstat_tbl[] = {
+ { TX4938_PCIC_G2PSTATUS_TTOE, "TIOE" },
+ { TX4938_PCIC_G2PSTATUS_RTOE, "RTOE" },
+ }, pcicstat_tbl[] = {
+ { TX4938_PCIC_PCICSTATUS_PME, "PME" },
+ { TX4938_PCIC_PCICSTATUS_TLB, "TLB" },
+ { TX4938_PCIC_PCICSTATUS_NIB, "NIB" },
+ { TX4938_PCIC_PCICSTATUS_ZIB, "ZIB" },
+ { TX4938_PCIC_PCICSTATUS_PERR, "PERR" },
+ { TX4938_PCIC_PCICSTATUS_SERR, "SERR" },
+ { TX4938_PCIC_PCICSTATUS_GBE, "GBE" },
+ { TX4938_PCIC_PCICSTATUS_IWB, "IWB" },
+ };
+ int i;
+
+ printk("pcistat:%04x(", pcistatus);
+ for (i = 0; i < ARRAY_SIZE(pcistat_tbl); i++)
+ if (pcistatus & pcistat_tbl[i].flag)
+ printk("%s ", pcistat_tbl[i].str);
+ printk("), g2pstatus:%08lx(", g2pstatus);
+ for (i = 0; i < ARRAY_SIZE(g2pstat_tbl); i++)
+ if (g2pstatus & g2pstat_tbl[i].flag)
+ printk("%s ", g2pstat_tbl[i].str);
+ printk("), pcicstatus:%08lx(", pcicstatus);
+ for (i = 0; i < ARRAY_SIZE(pcicstat_tbl); i++)
+ if (pcicstatus & pcicstat_tbl[i].flag)
+ printk("%s ", pcicstat_tbl[i].str);
+ printk(")\n");
+}
+
+void tx4938_report_pcic_status(void)
+{
+ int i;
+ struct tx4938_pcic_reg *pcicptr;
+ for (i = 0; (pcicptr = get_tx4938_pcicptr(i)) != NULL; i++)
+ tx4938_report_pcic_status1(pcicptr);
+}
+
+#endif /* CONFIG_PCI */
+
+/* We use onchip r4k counter or TMR timer as our system wide timer
+ * interrupt running at 100HZ. */
+
+extern void __init rtc_rx5c348_init(int chipid);
+void __init rbtx4938_time_init(void)
+{
+ rtc_rx5c348_init(RBTX4938_SRTC_CHIPID);
+ mips_hpt_frequency = txx9_cpu_clock / 2;
+}
+
+void __init toshiba_rbtx4938_setup(void)
+{
+ unsigned long long pcfg;
+ char *argptr;
+
+ iomem_resource.end = 0xffffffff; /* 4GB */
+
+ if (txx9_master_clock == 0)
+ txx9_master_clock = 25000000; /* 25MHz */
+ tx4938_board_setup();
+ /* setup irq stuff */
+ TX4938_WR(TX4938_MKA(TX4938_IRC_IRDM0), 0x00000000); /* irq trigger */
+ TX4938_WR(TX4938_MKA(TX4938_IRC_IRDM1), 0x00000000); /* irq trigger */
+ /* setup serial stuff */
+ TX4938_WR(0xff1ff314, 0x00000000); /* h/w flow control off */
+ TX4938_WR(0xff1ff414, 0x00000000); /* h/w flow control off */
+
+#ifndef CONFIG_PCI
+ set_io_port_base(RBTX4938_ETHER_BASE);
+#endif
+
+#ifdef CONFIG_SERIAL_TXX9
+ {
+ extern int early_serial_txx9_setup(struct uart_port *port);
+ int i;
+ struct uart_port req;
+ for(i = 0; i < 2; i++) {
+ memset(&req, 0, sizeof(req));
+ req.line = i;
+ req.iotype = UPIO_MEM;
+ req.membase = (char *)(0xff1ff300 + i * 0x100);
+ req.mapbase = 0xff1ff300 + i * 0x100;
+ req.irq = 32 + i;
+ req.flags |= UPF_BUGGY_UART /*HAVE_CTS_LINE*/;
+ req.uartclk = 50000000;
+ early_serial_txx9_setup(&req);
+ }
+ }
+#ifdef CONFIG_SERIAL_TXX9_CONSOLE
+ argptr = prom_getcmdline();
+ if (strstr(argptr, "console=") == NULL) {
+ strcat(argptr, " console=ttyS0,38400");
+ }
+#endif
+#endif
+
+#ifdef CONFIG_TOSHIBA_RBTX4938_MPLEX_PIO58_61
+ printk("PIOSEL: disabling both ata and nand selection\n");
+ local_irq_disable();
+ tx4938_ccfgptr->pcfg &= ~(TX4938_PCFG_NDF_SEL | TX4938_PCFG_ATA_SEL);
+#endif
+
+#ifdef CONFIG_TOSHIBA_RBTX4938_MPLEX_NAND
+ printk("PIOSEL: enabling nand selection\n");
+ tx4938_ccfgptr->pcfg |= TX4938_PCFG_NDF_SEL;
+ tx4938_ccfgptr->pcfg &= ~TX4938_PCFG_ATA_SEL;
+#endif
+
+#ifdef CONFIG_TOSHIBA_RBTX4938_MPLEX_ATA
+ printk("PIOSEL: enabling ata selection\n");
+ tx4938_ccfgptr->pcfg |= TX4938_PCFG_ATA_SEL;
+ tx4938_ccfgptr->pcfg &= ~TX4938_PCFG_NDF_SEL;
+#endif
+
+#ifdef CONFIG_IP_PNP
+ argptr = prom_getcmdline();
+ if (strstr(argptr, "ip=") == NULL) {
+ strcat(argptr, " ip=any");
+ }
+#endif
+
+
+#ifdef CONFIG_FB
+ {
+ conswitchp = &dummy_con;
+ }
+#endif
+
+ rbtx4938_spi_setup();
+ pcfg = tx4938_ccfgptr->pcfg; /* updated */
+ /* fixup piosel */
+ if ((pcfg & (TX4938_PCFG_ATA_SEL | TX4938_PCFG_NDF_SEL)) ==
+ TX4938_PCFG_ATA_SEL) {
+ *rbtx4938_piosel_ptr = (*rbtx4938_piosel_ptr & 0x03) | 0x04;
+ }
+ else if ((pcfg & (TX4938_PCFG_ATA_SEL | TX4938_PCFG_NDF_SEL)) ==
+ TX4938_PCFG_NDF_SEL) {
+ *rbtx4938_piosel_ptr = (*rbtx4938_piosel_ptr & 0x03) | 0x08;
+ }
+ else {
+ *rbtx4938_piosel_ptr &= ~(0x08 | 0x04);
+ }
+
+ rbtx4938_fpga_resource.name = "FPGA Registers";
+ rbtx4938_fpga_resource.start = CPHYSADDR(RBTX4938_FPGA_REG_ADDR);
+ rbtx4938_fpga_resource.end = CPHYSADDR(RBTX4938_FPGA_REG_ADDR) + 0xffff;
+ rbtx4938_fpga_resource.flags = IORESOURCE_MEM | IORESOURCE_BUSY;
+ if (request_resource(&iomem_resource, &rbtx4938_fpga_resource))
+ printk("request resource for fpga failed\n");
+
+ /* disable all OnBoard I/O interrupts */
+ *rbtx4938_imask_ptr = 0;
+
+ _machine_restart = rbtx4938_machine_restart;
+ _machine_halt = rbtx4938_machine_halt;
+ _machine_power_off = rbtx4938_machine_power_off;
+
+ *rbtx4938_led_ptr = 0xff;
+ printk("RBTX4938 --- FPGA(Rev %02x)", *rbtx4938_fpga_rev_ptr);
+ printk(" DIPSW:%02x,%02x\n",
+ *rbtx4938_dipsw_ptr, *rbtx4938_bdipsw_ptr);
+}
+
+#ifdef CONFIG_PROC_FS
+extern void spi_eeprom_proc_create(struct proc_dir_entry *dir, int chipid);
+static int __init tx4938_spi_proc_setup(void)
+{
+ struct proc_dir_entry *tx4938_spi_eeprom_dir;
+
+ tx4938_spi_eeprom_dir = proc_mkdir("spi_eeprom", 0);
+
+ if (!tx4938_spi_eeprom_dir)
+ return -ENOMEM;
+
+ /* don't allow user access to RBTX4938_SEEPROM1_CHIPID
+ * as it contains eth0 and eth1 MAC addresses
+ */
+ spi_eeprom_proc_create(tx4938_spi_eeprom_dir, RBTX4938_SEEPROM2_CHIPID);
+ spi_eeprom_proc_create(tx4938_spi_eeprom_dir, RBTX4938_SEEPROM3_CHIPID);
+
+ return 0;
+}
+
+__initcall(tx4938_spi_proc_setup);
+#endif
diff --git a/arch/mips/tx4938/toshiba_rbtx4938/spi_eeprom.c b/arch/mips/tx4938/toshiba_rbtx4938/spi_eeprom.c
new file mode 100644
index 000000000000..951a208ee9b3
--- /dev/null
+++ b/arch/mips/tx4938/toshiba_rbtx4938/spi_eeprom.c
@@ -0,0 +1,219 @@
+/*
+ * linux/arch/mips/tx4938/toshiba_rbtx4938/spi_eeprom.c
+ * Copyright (C) 2000-2001 Toshiba Corporation
+ *
+ * 2003-2005 (c) MontaVista Software, Inc. This file is licensed under the
+ * terms of the GNU General Public License version 2. This program is
+ * licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ *
+ * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com)
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/proc_fs.h>
+#include <linux/spinlock.h>
+#include <asm/tx4938/spi.h>
+#include <asm/tx4938/tx4938.h>
+
+/* ATMEL 250x0 instructions */
+#define ATMEL_WREN 0x06
+#define ATMEL_WRDI 0x04
+#define ATMEL_RDSR 0x05
+#define ATMEL_WRSR 0x01
+#define ATMEL_READ 0x03
+#define ATMEL_WRITE 0x02
+
+#define ATMEL_SR_BSY 0x01
+#define ATMEL_SR_WEN 0x02
+#define ATMEL_SR_BP0 0x04
+#define ATMEL_SR_BP1 0x08
+
+DEFINE_SPINLOCK(spi_eeprom_lock);
+
+static struct spi_dev_desc seeprom_dev_desc = {
+ .baud = 1500000, /* 1.5Mbps */
+ .tcss = 1,
+ .tcsh = 1,
+ .tcsr = 1,
+ .byteorder = 1, /* MSB-First */
+ .polarity = 0, /* High-Active */
+ .phase = 0, /* Sample-Then-Shift */
+
+};
+static inline int
+spi_eeprom_io(int chipid,
+ unsigned char **inbufs, unsigned int *incounts,
+ unsigned char **outbufs, unsigned int *outcounts)
+{
+ return txx9_spi_io(chipid, &seeprom_dev_desc,
+ inbufs, incounts, outbufs, outcounts, 0);
+}
+
+int spi_eeprom_write_enable(int chipid, int enable)
+{
+ unsigned char inbuf[1];
+ unsigned char *inbufs[1];
+ unsigned int incounts[2];
+ unsigned long flags;
+ int stat;
+ inbuf[0] = enable ? ATMEL_WREN : ATMEL_WRDI;
+ inbufs[0] = inbuf;
+ incounts[0] = sizeof(inbuf);
+ incounts[1] = 0;
+ spin_lock_irqsave(&spi_eeprom_lock, flags);
+ stat = spi_eeprom_io(chipid, inbufs, incounts, NULL, NULL);
+ spin_unlock_irqrestore(&spi_eeprom_lock, flags);
+ return stat;
+}
+
+static int spi_eeprom_read_status_nolock(int chipid)
+{
+ unsigned char inbuf[2], outbuf[2];
+ unsigned char *inbufs[1], *outbufs[1];
+ unsigned int incounts[2], outcounts[2];
+ int stat;
+ inbuf[0] = ATMEL_RDSR;
+ inbuf[1] = 0;
+ inbufs[0] = inbuf;
+ incounts[0] = sizeof(inbuf);
+ incounts[1] = 0;
+ outbufs[0] = outbuf;
+ outcounts[0] = sizeof(outbuf);
+ outcounts[1] = 0;
+ stat = spi_eeprom_io(chipid, inbufs, incounts, outbufs, outcounts);
+ if (stat < 0)
+ return stat;
+ return outbuf[1];
+}
+
+int spi_eeprom_read_status(int chipid)
+{
+ unsigned long flags;
+ int stat;
+ spin_lock_irqsave(&spi_eeprom_lock, flags);
+ stat = spi_eeprom_read_status_nolock(chipid);
+ spin_unlock_irqrestore(&spi_eeprom_lock, flags);
+ return stat;
+}
+
+int spi_eeprom_read(int chipid, int address, unsigned char *buf, int len)
+{
+ unsigned char inbuf[2];
+ unsigned char *inbufs[2], *outbufs[2];
+ unsigned int incounts[2], outcounts[3];
+ unsigned long flags;
+ int stat;
+ inbuf[0] = ATMEL_READ;
+ inbuf[1] = address;
+ inbufs[0] = inbuf;
+ inbufs[1] = NULL;
+ incounts[0] = sizeof(inbuf);
+ incounts[1] = 0;
+ outbufs[0] = NULL;
+ outbufs[1] = buf;
+ outcounts[0] = 2;
+ outcounts[1] = len;
+ outcounts[2] = 0;
+ spin_lock_irqsave(&spi_eeprom_lock, flags);
+ stat = spi_eeprom_io(chipid, inbufs, incounts, outbufs, outcounts);
+ spin_unlock_irqrestore(&spi_eeprom_lock, flags);
+ return stat;
+}
+
+int spi_eeprom_write(int chipid, int address, unsigned char *buf, int len)
+{
+ unsigned char inbuf[2];
+ unsigned char *inbufs[2];
+ unsigned int incounts[3];
+ unsigned long flags;
+ int i, stat;
+
+ if (address / 8 != (address + len - 1) / 8)
+ return -EINVAL;
+ stat = spi_eeprom_write_enable(chipid, 1);
+ if (stat < 0)
+ return stat;
+ stat = spi_eeprom_read_status(chipid);
+ if (stat < 0)
+ return stat;
+ if (!(stat & ATMEL_SR_WEN))
+ return -EPERM;
+
+ inbuf[0] = ATMEL_WRITE;
+ inbuf[1] = address;
+ inbufs[0] = inbuf;
+ inbufs[1] = buf;
+ incounts[0] = sizeof(inbuf);
+ incounts[1] = len;
+ incounts[2] = 0;
+ spin_lock_irqsave(&spi_eeprom_lock, flags);
+ stat = spi_eeprom_io(chipid, inbufs, incounts, NULL, NULL);
+ if (stat < 0)
+ goto unlock_return;
+
+ /* write start. max 10ms */
+ for (i = 10; i > 0; i--) {
+ int stat = spi_eeprom_read_status_nolock(chipid);
+ if (stat < 0)
+ goto unlock_return;
+ if (!(stat & ATMEL_SR_BSY))
+ break;
+ mdelay(1);
+ }
+ spin_unlock_irqrestore(&spi_eeprom_lock, flags);
+ if (i == 0)
+ return -EIO;
+ return len;
+ unlock_return:
+ spin_unlock_irqrestore(&spi_eeprom_lock, flags);
+ return stat;
+}
+
+#ifdef CONFIG_PROC_FS
+#define MAX_SIZE 0x80 /* for ATMEL 25010 */
+static int spi_eeprom_read_proc(char *page, char **start, off_t off,
+ int count, int *eof, void *data)
+{
+ unsigned int size = MAX_SIZE;
+ if (spi_eeprom_read((int)data, 0, (unsigned char *)page, size) < 0)
+ size = 0;
+ return size;
+}
+
+static int spi_eeprom_write_proc(struct file *file, const char *buffer,
+ unsigned long count, void *data)
+{
+ unsigned int size = MAX_SIZE;
+ int i;
+ if (file->f_pos >= size)
+ return -EIO;
+ if (file->f_pos + count > size)
+ count = size - file->f_pos;
+ for (i = 0; i < count; i += 8) {
+ int len = count - i < 8 ? count - i : 8;
+ if (spi_eeprom_write((int)data, file->f_pos,
+ (unsigned char *)buffer, len) < 0) {
+ count = -EIO;
+ break;
+ }
+ buffer += len;
+ file->f_pos += len;
+ }
+ return count;
+}
+
+__init void spi_eeprom_proc_create(struct proc_dir_entry *dir, int chipid)
+{
+ struct proc_dir_entry *entry;
+ char name[128];
+ sprintf(name, "seeprom-%d", chipid);
+ entry = create_proc_entry(name, 0600, dir);
+ if (entry) {
+ entry->read_proc = spi_eeprom_read_proc;
+ entry->write_proc = spi_eeprom_write_proc;
+ entry->data = (void *)chipid;
+ }
+}
+#endif /* CONFIG_PROC_FS */
diff --git a/arch/mips/tx4938/toshiba_rbtx4938/spi_txx9.c b/arch/mips/tx4938/toshiba_rbtx4938/spi_txx9.c
new file mode 100644
index 000000000000..fae3136f462d
--- /dev/null
+++ b/arch/mips/tx4938/toshiba_rbtx4938/spi_txx9.c
@@ -0,0 +1,159 @@
+/*
+ * linux/arch/mips/tx4938/toshiba_rbtx4938/spi_txx9.c
+ * Copyright (C) 2000-2001 Toshiba Corporation
+ *
+ * 2003-2005 (c) MontaVista Software, Inc. This file is licensed under the
+ * terms of the GNU General Public License version 2. This program is
+ * licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ *
+ * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com)
+ */
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/spinlock.h>
+#include <linux/wait.h>
+#include <asm/tx4938/spi.h>
+#include <asm/tx4938/tx4938.h>
+
+static int (*txx9_spi_cs_func)(int chipid, int on);
+static DEFINE_SPINLOCK(txx9_spi_lock);
+
+extern unsigned int txx9_gbus_clock;
+
+#define SPI_FIFO_SIZE 4
+
+void __init txx9_spi_init(unsigned long base, int (*cs_func)(int chipid, int on))
+{
+ txx9_spi_cs_func = cs_func;
+ /* enter config mode */
+ tx4938_spiptr->mcr = TXx9_SPMCR_CONFIG | TXx9_SPMCR_BCLR;
+}
+
+static DECLARE_WAIT_QUEUE_HEAD(txx9_spi_wait);
+static void txx9_spi_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+ /* disable rx intr */
+ tx4938_spiptr->cr0 &= ~TXx9_SPCR0_RBSIE;
+ wake_up(&txx9_spi_wait);
+}
+static struct irqaction txx9_spi_action = {
+ txx9_spi_interrupt, 0, 0, "spi", NULL, NULL,
+};
+
+void __init txx9_spi_irqinit(int irc_irq)
+{
+ setup_irq(irc_irq, &txx9_spi_action);
+}
+
+int txx9_spi_io(int chipid, struct spi_dev_desc *desc,
+ unsigned char **inbufs, unsigned int *incounts,
+ unsigned char **outbufs, unsigned int *outcounts,
+ int cansleep)
+{
+ unsigned int incount, outcount;
+ unsigned char *inp, *outp;
+ int ret;
+ unsigned long flags;
+
+ spin_lock_irqsave(&txx9_spi_lock, flags);
+ if ((tx4938_spiptr->mcr & TXx9_SPMCR_OPMODE) == TXx9_SPMCR_ACTIVE) {
+ spin_unlock_irqrestore(&txx9_spi_lock, flags);
+ return -EBUSY;
+ }
+ /* enter config mode */
+ tx4938_spiptr->mcr = TXx9_SPMCR_CONFIG | TXx9_SPMCR_BCLR;
+ tx4938_spiptr->cr0 =
+ (desc->byteorder ? TXx9_SPCR0_SBOS : 0) |
+ (desc->polarity ? TXx9_SPCR0_SPOL : 0) |
+ (desc->phase ? TXx9_SPCR0_SPHA : 0) |
+ 0x08;
+ tx4938_spiptr->cr1 =
+ (((TXX9_IMCLK + desc->baud) / (2 * desc->baud) - 1) << 8) |
+ 0x08 /* 8 bit only */;
+ /* enter active mode */
+ tx4938_spiptr->mcr = TXx9_SPMCR_ACTIVE;
+ spin_unlock_irqrestore(&txx9_spi_lock, flags);
+
+ /* CS ON */
+ if ((ret = txx9_spi_cs_func(chipid, 1)) < 0) {
+ spin_unlock_irqrestore(&txx9_spi_lock, flags);
+ return ret;
+ }
+ udelay(desc->tcss);
+
+ /* do scatter IO */
+ inp = inbufs ? *inbufs : NULL;
+ outp = outbufs ? *outbufs : NULL;
+ incount = 0;
+ outcount = 0;
+ while (1) {
+ unsigned char data;
+ unsigned int count;
+ int i;
+ if (!incount) {
+ incount = incounts ? *incounts++ : 0;
+ inp = (incount && inbufs) ? *inbufs++ : NULL;
+ }
+ if (!outcount) {
+ outcount = outcounts ? *outcounts++ : 0;
+ outp = (outcount && outbufs) ? *outbufs++ : NULL;
+ }
+ if (!inp && !outp)
+ break;
+ count = SPI_FIFO_SIZE;
+ if (incount)
+ count = min(count, incount);
+ if (outcount)
+ count = min(count, outcount);
+
+ /* now tx must be idle... */
+ while (!(tx4938_spiptr->sr & TXx9_SPSR_SIDLE))
+ ;
+
+ tx4938_spiptr->cr0 =
+ (tx4938_spiptr->cr0 & ~TXx9_SPCR0_RXIFL_MASK) |
+ ((count - 1) << 12);
+ if (cansleep) {
+ /* enable rx intr */
+ tx4938_spiptr->cr0 |= TXx9_SPCR0_RBSIE;
+ }
+ /* send */
+ for (i = 0; i < count; i++)
+ tx4938_spiptr->dr = inp ? *inp++ : 0;
+ /* wait all rx data */
+ if (cansleep) {
+ wait_event(txx9_spi_wait,
+ tx4938_spiptr->sr & TXx9_SPSR_SRRDY);
+ } else {
+ while (!(tx4938_spiptr->sr & TXx9_SPSR_RBSI))
+ ;
+ }
+ /* receive */
+ for (i = 0; i < count; i++) {
+ data = tx4938_spiptr->dr;
+ if (outp)
+ *outp++ = data;
+ }
+ if (incount)
+ incount -= count;
+ if (outcount)
+ outcount -= count;
+ }
+
+ /* CS OFF */
+ udelay(desc->tcsh);
+ txx9_spi_cs_func(chipid, 0);
+ udelay(desc->tcsr);
+
+ spin_lock_irqsave(&txx9_spi_lock, flags);
+ /* enter config mode */
+ tx4938_spiptr->mcr = TXx9_SPMCR_CONFIG | TXx9_SPMCR_BCLR;
+ spin_unlock_irqrestore(&txx9_spi_lock, flags);
+
+ return 0;
+}
diff --git a/arch/mips/vr41xx/Kconfig b/arch/mips/vr41xx/Kconfig
new file mode 100644
index 000000000000..a7add16c9aa4
--- /dev/null
+++ b/arch/mips/vr41xx/Kconfig
@@ -0,0 +1,88 @@
+config CASIO_E55
+ bool "Support for CASIO CASSIOPEIA E-10/15/55/65"
+ depends on MACH_VR41XX
+ select DMA_NONCOHERENT
+ select IRQ_CPU
+ select ISA
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+
+config IBM_WORKPAD
+ bool "Support for IBM WorkPad z50"
+ depends on MACH_VR41XX
+ select DMA_NONCOHERENT
+ select IRQ_CPU
+ select ISA
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+
+config NEC_CMBVR4133
+ bool "Support for NEC CMB-VR4133"
+ depends on MACH_VR41XX
+ select CPU_VR41XX
+ select DMA_NONCOHERENT
+ select IRQ_CPU
+ select HW_HAS_PCI
+
+config ROCKHOPPER
+ bool "Support for Rockhopper baseboard"
+ depends on NEC_CMBVR4133
+ select I8259
+ select HAVE_STD_PC_SERIAL_PORT
+
+config TANBAC_TB022X
+ bool "Support for TANBAC VR4131 multichip module and TANBAC VR4131DIMM"
+ depends on MACH_VR41XX
+ select DMA_NONCOHERENT
+ select HW_HAS_PCI
+ select IRQ_CPU
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+ help
+ The TANBAC VR4131 multichip module(TB0225) and
+ the TANBAC VR4131DIMM(TB0229) are MIPS-based platforms
+ manufactured by TANBAC.
+ Please refer to <http://www.tanbac.co.jp/>
+ about VR4131 multichip module and VR4131DIMM.
+
+config TANBAC_TB0226
+ bool "Support for TANBAC Mbase(TB0226)"
+ depends on TANBAC_TB022X
+ select GPIO_VR41XX
+ help
+ The TANBAC Mbase(TB0226) is a MIPS-based platform
+ manufactured by TANBAC.
+ Please refer to <http://www.tanbac.co.jp/> about Mbase.
+
+config TANBAC_TB0287
+ bool "Support for TANBAC Mini-ITX DIMM base(TB0287)"
+ depends on TANBAC_TB022X
+ help
+ The TANBAC Mini-ITX DIMM base(TB0287) is a MIPS-based platform
+ manufactured by TANBAC.
+ Please refer to <http://www.tanbac.co.jp/> about Mini-ITX DIMM base.
+
+config VICTOR_MPC30X
+ bool "Support for Victor MP-C303/304"
+ depends on MACH_VR41XX
+ select DMA_NONCOHERENT
+ select HW_HAS_PCI
+ select IRQ_CPU
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+
+config ZAO_CAPCELLA
+ bool "Support for ZAO Networks Capcella"
+ depends on MACH_VR41XX
+ select DMA_NONCOHERENT
+ select HW_HAS_PCI
+ select IRQ_CPU
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+
+config PCI_VR41XX
+ bool "Add PCI control unit support of NEC VR4100 series"
+ depends on MACH_VR41XX && HW_HAS_PCI
+ default y
+ select PCI
+
+config VRC4173
+ tristate "Add NEC VRC4173 companion chip support"
+ depends on MACH_VR41XX && PCI_VR41XX
+ help
+ The NEC VRC4173 is a companion chip for NEC VR4122/VR4131.
diff --git a/arch/mips/vr41xx/common/cmu.c b/arch/mips/vr41xx/common/cmu.c
index fcd3cb8cdd9d..d758e432961b 100644
--- a/arch/mips/vr41xx/common/cmu.c
+++ b/arch/mips/vr41xx/common/cmu.c
@@ -69,7 +69,7 @@
static void __iomem *cmu_base;
static uint16_t cmuclkmsk, cmuclkmsk2;
-static spinlock_t cmu_lock;
+static DEFINE_SPINLOCK(cmu_lock);
#define cmu_read(offset) readw(cmu_base + (offset))
#define cmu_write(offset, value) writew((value), cmu_base + (offset))
diff --git a/arch/mips/vr41xx/common/init.c b/arch/mips/vr41xx/common/init.c
index e03be896cbc4..578f6496ffd4 100644
--- a/arch/mips/vr41xx/common/init.c
+++ b/arch/mips/vr41xx/common/init.c
@@ -58,6 +58,14 @@ static void __init timer_init(void)
board_timer_setup = setup_timer_irq;
}
+void __init plat_setup(void)
+{
+ vr41xx_calculate_clock_frequency();
+
+ timer_init();
+ iomem_resource_init();
+}
+
void __init prom_init(void)
{
int argc, i;
@@ -71,12 +79,6 @@ void __init prom_init(void)
if (i < (argc - 1))
strcat(arcs_cmdline, " ");
}
-
- vr41xx_calculate_clock_frequency();
-
- timer_init();
-
- iomem_resource_init();
}
unsigned long __init prom_free_prom_memory (void)
diff --git a/arch/mips/vr41xx/common/vrc4173.c b/arch/mips/vr41xx/common/vrc4173.c
index ba58764ef8ea..462a9af30eef 100644
--- a/arch/mips/vr41xx/common/vrc4173.c
+++ b/arch/mips/vr41xx/common/vrc4173.c
@@ -81,8 +81,8 @@ EXPORT_SYMBOL(vrc4173_io_offset);
static int vrc4173_initialized;
static uint16_t vrc4173_cmuclkmsk;
static uint16_t vrc4173_selectreg;
-static spinlock_t vrc4173_cmu_lock;
-static spinlock_t vrc4173_giu_lock;
+static DEFINE_SPINLOCK(vrc4173_cmu_lock);
+static DEFINE_SPINLOCK(vrc4173_giu_lock);
static inline void set_cmusrst(uint16_t val)
{
diff --git a/arch/mips/vr41xx/nec-cmbvr4133/setup.c b/arch/mips/vr41xx/nec-cmbvr4133/setup.c
index db686ce42e85..53272a5c3cbe 100644
--- a/arch/mips/vr41xx/nec-cmbvr4133/setup.c
+++ b/arch/mips/vr41xx/nec-cmbvr4133/setup.c
@@ -56,7 +56,7 @@ static struct mtd_partition cmbvr4133_mtd_parts[] = {
extern void i8259_init(void);
-static int __init nec_cmbvr4133_setup(void)
+static void __init nec_cmbvr4133_setup(void)
{
#ifdef CONFIG_ROCKHOPPER
extern void disable_pcnet(void);
@@ -90,7 +90,4 @@ static int __init nec_cmbvr4133_setup(void)
#ifdef CONFIG_ROCKHOPPER
i8259_init();
#endif
- return 0;
}
-
-early_initcall(nec_cmbvr4133_setup);
diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig
index 0b07922a2ac6..874a283edb95 100644
--- a/arch/parisc/Kconfig
+++ b/arch/parisc/Kconfig
@@ -47,10 +47,10 @@ config PM
config ISA_DMA_API
bool
- default y
config ARCH_MAY_HAVE_PC_FDC
bool
+ depends on BROKEN
default y
source "init/Kconfig"
@@ -154,13 +154,14 @@ config HOTPLUG_CPU
config ARCH_DISCONTIGMEM_ENABLE
bool "Discontiguous memory support (EXPERIMENTAL)"
- depends on EXPERIMENTAL
+ depends on 64BIT && EXPERIMENTAL
help
Say Y to support efficient handling of discontiguous physical memory,
for architectures which are either NUMA (Non-Uniform Memory Access)
or have huge holes in the physical address space for other reasons.
See <file:Documentation/vm/numa> for more.
+source "kernel/Kconfig.hz"
source "mm/Kconfig"
config PREEMPT
diff --git a/arch/parisc/Makefile b/arch/parisc/Makefile
index 3b339b1cce13..9b7e42490dd1 100644
--- a/arch/parisc/Makefile
+++ b/arch/parisc/Makefile
@@ -20,7 +20,8 @@ NM = sh $(srctree)/arch/parisc/nm
CHECKFLAGS += -D__hppa__=1
ifdef CONFIG_64BIT
-CROSS_COMPILE := hppa64-linux-
+CROSS_COMPILE := $(shell if [ -x /usr/bin/hppa64-linux-gnu-gcc ]; then \
+ echo hppa64-linux-gnu-; else echo hppa64-linux-; fi)
UTS_MACHINE := parisc64
CHECKFLAGS += -D__LP64__=1 -m64
else
@@ -34,6 +35,14 @@ FINAL_LD=$(CROSS_COMPILE)ld --warn-common --warn-section-align
OBJCOPY_FLAGS =-O binary -R .note -R .comment -S
+GCC_VERSION := $(call cc-version)
+ifneq ($(shell if [ -z $(GCC_VERSION) ] ; then echo "bad"; fi ;),)
+$(error Sorry, couldn't find ($(cc-version)).)
+endif
+ifneq ($(shell if [ $(GCC_VERSION) -lt 0303 ] ; then echo "bad"; fi ;),)
+$(error Sorry, your compiler is too old ($(GCC_VERSION)). GCC v3.3 or above is required.)
+endif
+
cflags-y := -pipe
# These flags should be implied by an hppa-linux configuration, but they
@@ -43,7 +52,7 @@ cflags-y += -mno-space-regs -mfast-indirect-calls
# Currently we save and restore fpregs on all kernel entry/interruption paths.
# If that gets optimized, we might need to disable the use of fpregs in the
# kernel.
-#cflags-y += -mdisable-fpregs
+cflags-y += -mdisable-fpregs
# Without this, "ld -r" results in .text sections that are too big
# (> 0x40000) for branches to reach stubs.
diff --git a/arch/parisc/configs/712_defconfig b/arch/parisc/configs/712_defconfig
index 6efaa9293eef..3e013f55df64 100644
--- a/arch/parisc/configs/712_defconfig
+++ b/arch/parisc/configs/712_defconfig
@@ -1,12 +1,16 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.10-pa5
-# Wed Jan 5 13:20:32 2005
+# Linux kernel version: 2.6.14-rc5-pa1
+# Fri Oct 21 23:04:34 2005
#
CONFIG_PARISC=y
CONFIG_MMU=y
CONFIG_STACK_GROWSUP=y
CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
#
# Code maturity level options
@@ -15,35 +19,40 @@ CONFIG_EXPERIMENTAL=y
# CONFIG_CLEAN_COMPILE is not set
CONFIG_BROKEN=y
CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
#
# General setup
#
CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
CONFIG_POSIX_MQUEUE=y
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=16
CONFIG_HOTPLUG=y
CONFIG_KOBJECT_UEVENT=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
+CONFIG_INITRAMFS_SOURCE=""
# CONFIG_EMBEDDED is not set
CONFIG_KALLSYMS=y
CONFIG_KALLSYMS_ALL=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_SHMEM=y
CONFIG_CC_ALIGN_FUNCTIONS=0
CONFIG_CC_ALIGN_LABELS=0
CONFIG_CC_ALIGN_LOOPS=0
CONFIG_CC_ALIGN_JUMPS=0
# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
#
# Loadable module support
@@ -65,9 +74,18 @@ CONFIG_PA7100LC=y
# CONFIG_PA7300LC is not set
# CONFIG_PA8X00 is not set
CONFIG_PA11=y
-# CONFIG_64BIT is not set
# CONFIG_SMP is not set
-# CONFIG_DISCONTIGMEM is not set
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+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_PREEMPT is not set
# CONFIG_HPUX is not set
@@ -81,8 +99,6 @@ CONFIG_GSC_LASI=y
# CONFIG_GSC_WAX is not set
# CONFIG_EISA is not set
# CONFIG_PCI is not set
-CONFIG_CHASSIS_LCD_LED=y
-# CONFIG_PDC_CHASSIS is not set
#
# PCCARD (PCMCIA/CardBus) support
@@ -90,12 +106,15 @@ CONFIG_CHASSIS_LCD_LED=y
# CONFIG_PCCARD is not set
#
-# PC-card bridges
+# PCI Hotplug Support
#
#
-# PCI Hotplug Support
+# PA-RISC specific drivers
#
+CONFIG_CHASSIS_LCD_LED=y
+# CONFIG_PDC_CHASSIS is not set
+CONFIG_PDC_STABLE=y
#
# Executable file formats
@@ -104,137 +123,7 @@ CONFIG_BINFMT_ELF=y
CONFIG_BINFMT_MISC=m
#
-# Device Drivers
-#
-
-#
-# Generic Driver Options
-#
-# CONFIG_STANDALONE is not set
-# CONFIG_PREVENT_FIRMWARE_BUILD is not set
-CONFIG_FW_LOADER=y
-# CONFIG_DEBUG_DRIVER is not set
-
-#
-# Memory Technology Devices (MTD)
-#
-# CONFIG_MTD is not set
-
-#
-# Parallel port support
-#
-CONFIG_PARPORT=y
-CONFIG_PARPORT_PC=m
-CONFIG_PARPORT_PC_CML1=m
-# CONFIG_PARPORT_PC_FIFO is not set
-# CONFIG_PARPORT_PC_SUPERIO is not set
-CONFIG_PARPORT_GSC=y
-# CONFIG_PARPORT_OTHER is not set
-# CONFIG_PARPORT_1284 is not set
-
-#
-# Plug and Play support
-#
-
-#
-# Block devices
-#
-# CONFIG_BLK_DEV_FD is not set
-# CONFIG_PARIDE 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=16
-CONFIG_BLK_DEV_RAM_SIZE=6144
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_INITRAMFS_SOURCE=""
-# CONFIG_CDROM_PKTCDVD is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-
-#
-# ATA/ATAPI/MFM/RLL support
-#
-# CONFIG_IDE is not set
-
-#
-# SCSI device support
-#
-CONFIG_SCSI=y
-CONFIG_SCSI_PROC_FS=y
-
-#
-# SCSI support type (disk, tape, CD-ROM)
-#
-CONFIG_BLK_DEV_SD=y
-CONFIG_CHR_DEV_ST=y
-# CONFIG_CHR_DEV_OSST is not set
-CONFIG_BLK_DEV_SR=y
-# CONFIG_BLK_DEV_SR_VENDOR is not set
-CONFIG_CHR_DEV_SG=y
-
-#
-# 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
-
-#
-# SCSI Transport Attributes
-#
-CONFIG_SCSI_SPI_ATTRS=y
-# CONFIG_SCSI_FC_ATTRS is not set
-
-#
-# SCSI low-level drivers
-#
-# CONFIG_SCSI_SATA is not set
-# CONFIG_SCSI_PPA is not set
-# CONFIG_SCSI_IMM is not set
-CONFIG_SCSI_LASI700=y
-CONFIG_53C700_MEM_MAPPED=y
-CONFIG_53C700_LE_ON_BE=y
-# CONFIG_SCSI_ZALON is not set
-CONFIG_SCSI_DEBUG=m
-
-#
-# Multi-device support (RAID and LVM)
-#
-CONFIG_MD=y
-CONFIG_BLK_DEV_MD=m
-CONFIG_MD_LINEAR=m
-CONFIG_MD_RAID0=m
-CONFIG_MD_RAID1=m
-# CONFIG_MD_RAID10 is not set
-# CONFIG_MD_RAID5 is not set
-# CONFIG_MD_RAID6 is not set
-# CONFIG_MD_MULTIPATH is not set
-# CONFIG_MD_FAULTY is not set
-# CONFIG_BLK_DEV_DM is not set
-
-#
-# Fusion MPT device support
-#
-
-#
-# IEEE 1394 (FireWire) support
-#
-# CONFIG_IEEE1394 is not set
-
-#
-# I2O device support
-#
-
-#
-# Networking support
+# Networking
#
CONFIG_NET=y
@@ -243,12 +132,14 @@ CONFIG_NET=y
#
CONFIG_PACKET=y
CONFIG_PACKET_MMAP=y
-CONFIG_NETLINK_DEV=y
CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
CONFIG_NET_KEY=m
CONFIG_INET=y
CONFIG_IP_MULTICAST=y
# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
CONFIG_IP_PNP=y
CONFIG_IP_PNP_DHCP=y
CONFIG_IP_PNP_BOOTP=y
@@ -262,8 +153,10 @@ CONFIG_INET_AH=m
CONFIG_INET_ESP=m
# CONFIG_INET_IPCOMP is not set
CONFIG_INET_TUNNEL=m
-CONFIG_IP_TCPDIAG=y
-# CONFIG_IP_TCPDIAG_IPV6 is not set
+CONFIG_INET_DIAG=m
+CONFIG_INET_TCP_DIAG=m
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
#
# IP: Virtual Server Configuration
@@ -272,6 +165,7 @@ CONFIG_IP_TCPDIAG=y
# CONFIG_IPV6 is not set
CONFIG_NETFILTER=y
# CONFIG_NETFILTER_DEBUG is not set
+# CONFIG_NETFILTER_NETLINK is not set
#
# IP: Netfilter Configuration
@@ -279,11 +173,14 @@ CONFIG_NETFILTER=y
CONFIG_IP_NF_CONNTRACK=m
# CONFIG_IP_NF_CT_ACCT is not set
CONFIG_IP_NF_CONNTRACK_MARK=y
+# CONFIG_IP_NF_CONNTRACK_EVENTS is not set
CONFIG_IP_NF_CT_PROTO_SCTP=m
CONFIG_IP_NF_FTP=m
CONFIG_IP_NF_IRC=m
+# CONFIG_IP_NF_NETBIOS_NS is not set
CONFIG_IP_NF_TFTP=m
CONFIG_IP_NF_AMANDA=m
+# CONFIG_IP_NF_PPTP is not set
CONFIG_IP_NF_QUEUE=m
CONFIG_IP_NF_IPTABLES=m
CONFIG_IP_NF_MATCH_LIMIT=m
@@ -307,21 +204,23 @@ CONFIG_IP_NF_MATCH_OWNER=m
# CONFIG_IP_NF_MATCH_ADDRTYPE is not set
# CONFIG_IP_NF_MATCH_REALM is not set
CONFIG_IP_NF_MATCH_SCTP=m
+# CONFIG_IP_NF_MATCH_DCCP is not set
CONFIG_IP_NF_MATCH_COMMENT=m
CONFIG_IP_NF_MATCH_CONNMARK=m
CONFIG_IP_NF_MATCH_HASHLIMIT=m
+# CONFIG_IP_NF_MATCH_STRING is not set
CONFIG_IP_NF_FILTER=m
CONFIG_IP_NF_TARGET_REJECT=m
CONFIG_IP_NF_TARGET_LOG=m
CONFIG_IP_NF_TARGET_ULOG=m
CONFIG_IP_NF_TARGET_TCPMSS=m
+# CONFIG_IP_NF_TARGET_NFQUEUE is not set
CONFIG_IP_NF_NAT=m
CONFIG_IP_NF_NAT_NEEDED=y
CONFIG_IP_NF_TARGET_MASQUERADE=m
CONFIG_IP_NF_TARGET_REDIRECT=m
CONFIG_IP_NF_TARGET_NETMAP=m
CONFIG_IP_NF_TARGET_SAME=m
-# CONFIG_IP_NF_NAT_LOCAL is not set
CONFIG_IP_NF_NAT_SNMP_BASIC=m
CONFIG_IP_NF_NAT_IRC=m
CONFIG_IP_NF_NAT_FTP=m
@@ -333,6 +232,7 @@ CONFIG_IP_NF_TARGET_ECN=m
CONFIG_IP_NF_TARGET_DSCP=m
CONFIG_IP_NF_TARGET_MARK=m
CONFIG_IP_NF_TARGET_CLASSIFY=m
+# CONFIG_IP_NF_TARGET_TTL is not set
CONFIG_IP_NF_TARGET_CONNMARK=m
CONFIG_IP_NF_TARGET_CLUSTERIP=m
CONFIG_IP_NF_RAW=m
@@ -340,10 +240,11 @@ CONFIG_IP_NF_TARGET_NOTRACK=m
CONFIG_IP_NF_ARPTABLES=m
CONFIG_IP_NF_ARPFILTER=m
CONFIG_IP_NF_ARP_MANGLE=m
-# CONFIG_IP_NF_COMPAT_IPCHAINS is not set
-# CONFIG_IP_NF_COMPAT_IPFWADM is not set
-CONFIG_XFRM=y
-CONFIG_XFRM_USER=m
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
#
# SCTP Configuration (EXPERIMENTAL)
@@ -362,10 +263,6 @@ CONFIG_LLC2=m
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
# CONFIG_NET_SCHED is not set
# CONFIG_NET_CLS_ROUTE is not set
@@ -373,17 +270,162 @@ CONFIG_LLC2=m
# Network testing
#
CONFIG_NET_PKTGEN=m
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
# CONFIG_HAMRADIO is not set
# CONFIG_IRDA is not set
# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+# CONFIG_STANDALONE is not set
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+CONFIG_FW_LOADER=y
+# CONFIG_DEBUG_DRIVER is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+CONFIG_PARPORT=y
+CONFIG_PARPORT_PC=m
+# CONFIG_PARPORT_PC_FIFO is not set
+# CONFIG_PARPORT_PC_SUPERIO is not set
+CONFIG_PARPORT_GSC=y
+# CONFIG_PARPORT_1284 is not set
+
+#
+# Plug and Play support
+#
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_PARIDE is not set
+# 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=16
+CONFIG_BLK_DEV_RAM_SIZE=6144
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_CDROM_PKTCDVD is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_ATA_OVER_ETH=m
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_ST=y
+# CONFIG_CHR_DEV_OSST is not set
+CONFIG_BLK_DEV_SR=y
+# CONFIG_BLK_DEV_SR_VENDOR 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
+
+#
+# SCSI Transport Attributes
+#
+CONFIG_SCSI_SPI_ATTRS=y
+# CONFIG_SCSI_FC_ATTRS is not set
+CONFIG_SCSI_ISCSI_ATTRS=m
+# CONFIG_SCSI_SAS_ATTRS is not set
+
+#
+# SCSI low-level drivers
+#
+# CONFIG_SCSI_SATA is not set
+# CONFIG_SCSI_PPA is not set
+# CONFIG_SCSI_IMM is not set
+CONFIG_SCSI_LASI700=y
+CONFIG_53C700_LE_ON_BE=y
+# CONFIG_SCSI_ZALON is not set
+CONFIG_SCSI_DEBUG=m
+
+#
+# Multi-device support (RAID and LVM)
+#
+CONFIG_MD=y
+CONFIG_BLK_DEV_MD=m
+CONFIG_MD_LINEAR=m
+CONFIG_MD_RAID0=m
+CONFIG_MD_RAID1=m
+# CONFIG_MD_RAID10 is not set
+# CONFIG_MD_RAID5 is not set
+# CONFIG_MD_RAID6 is not set
+# CONFIG_MD_MULTIPATH is not set
+# CONFIG_MD_FAULTY is not set
+# CONFIG_BLK_DEV_DM is not set
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+
+#
+# Network device support
+#
CONFIG_NETDEVICES=y
CONFIG_DUMMY=m
CONFIG_BONDING=m
# CONFIG_EQUALIZER is not set
CONFIG_TUN=m
-# CONFIG_ETHERTAP is not set
+
+#
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
#
# Ethernet (10 or 100Mbit)
@@ -391,6 +433,7 @@ CONFIG_TUN=m
CONFIG_NET_ETHERNET=y
CONFIG_MII=m
CONFIG_LASI_82596=y
+# CONFIG_NET_POCKET is not set
#
# Ethernet (1000 Mbit)
@@ -414,6 +457,7 @@ CONFIG_NET_RADIO=y
#
# CONFIG_STRIP is not set
# CONFIG_ATMEL is not set
+# CONFIG_HOSTAP is not set
#
# Wan interfaces
@@ -431,6 +475,8 @@ CONFIG_PPPOE=m
# CONFIG_SLIP is not set
# CONFIG_SHAPER is not set
# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
#
# ISDN subsystem
@@ -460,19 +506,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
# CONFIG_INPUT_EVBUG is not set
#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=y
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_PARKBD is not set
-CONFIG_SERIO_GSCPS2=y
-CONFIG_HP_SDC=y
-CONFIG_HIL_MLC=y
-# CONFIG_SERIO_RAW is not set
-
-#
# Input Device Drivers
#
CONFIG_INPUT_KEYBOARD=y
@@ -483,6 +516,7 @@ CONFIG_KEYBOARD_ATKBD_HP_KEYCODES=y
# CONFIG_KEYBOARD_LKKBD is not set
# CONFIG_KEYBOARD_XTKBD is not set
# CONFIG_KEYBOARD_NEWTON is not set
+CONFIG_KEYBOARD_HIL_OLD=y
# CONFIG_KEYBOARD_HIL is not set
CONFIG_INPUT_MOUSE=y
CONFIG_MOUSE_PS2=y
@@ -494,6 +528,19 @@ CONFIG_MOUSE_HIL=m
# CONFIG_INPUT_MISC is not set
#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_PARKBD is not set
+CONFIG_SERIO_GSCPS2=y
+CONFIG_HP_SDC=y
+CONFIG_HIL_MLC=y
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+
+#
# Character devices
#
CONFIG_VT=y
@@ -511,7 +558,6 @@ CONFIG_SERIAL_8250_EXTENDED=y
CONFIG_SERIAL_8250_MANY_PORTS=y
CONFIG_SERIAL_8250_SHARE_IRQ=y
# CONFIG_SERIAL_8250_DETECT_IRQ is not set
-# CONFIG_SERIAL_8250_MULTIPORT is not set
# CONFIG_SERIAL_8250_RSA is not set
#
@@ -546,12 +592,14 @@ CONFIG_GEN_RTC_X=y
#
# Ftape, the floppy tape device driver
#
-# CONFIG_AGP is not set
-# CONFIG_DRM is not set
CONFIG_RAW_DRIVER=y
CONFIG_MAX_RAW_DEVS=256
#
+# TPM devices
+#
+
+#
# I2C support
#
# CONFIG_I2C is not set
@@ -562,10 +610,20 @@ CONFIG_MAX_RAW_DEVS=256
# CONFIG_W1 is not set
#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
+#
# Misc devices
#
#
+# Multimedia Capabilities Port drivers
+#
+
+#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
@@ -579,28 +637,36 @@ CONFIG_MAX_RAW_DEVS=256
# Graphics support
#
CONFIG_FB=y
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+CONFIG_FB_SOFT_CURSOR=y
+# CONFIG_FB_MACMODES is not set
CONFIG_FB_MODE_HELPERS=y
CONFIG_FB_TILEBLITTING=y
CONFIG_FB_STI=y
+# CONFIG_FB_S1D13XXX is not set
# CONFIG_FB_VIRTUAL is not set
#
# Console display driver support
#
-CONFIG_STI_CONSOLE=y
+CONFIG_DUMMY_CONSOLE=y
CONFIG_DUMMY_CONSOLE_COLUMNS=128
CONFIG_DUMMY_CONSOLE_ROWS=48
-CONFIG_DUMMY_CONSOLE=y
CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_STI_CONSOLE=y
CONFIG_FONTS=y
CONFIG_FONT_8x8=y
CONFIG_FONT_8x16=y
# CONFIG_FONT_6x11 is not set
+# CONFIG_FONT_7x14 is not set
# CONFIG_FONT_PEARL_8x8 is not set
# CONFIG_FONT_ACORN_8x8 is not set
# CONFIG_FONT_MINI_4x6 is not set
# CONFIG_FONT_SUN8x16 is not set
# CONFIG_FONT_SUN12x22 is not set
+# CONFIG_FONT_10x18 is not set
#
# Logo configuration
@@ -610,6 +676,7 @@ CONFIG_LOGO=y
# CONFIG_LOGO_LINUX_VGA16 is not set
# CONFIG_LOGO_LINUX_CLUT224 is not set
CONFIG_LOGO_PARISC_CLUT224=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Sound
@@ -657,10 +724,6 @@ CONFIG_SND_HARMONY=y
# CONFIG_USB_ARCH_HAS_OHCI is not set
#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
-#
-
-#
# USB Gadget Support
#
# CONFIG_USB_GADGET is not set
@@ -671,10 +734,20 @@ CONFIG_SND_HARMONY=y
# CONFIG_MMC is not set
#
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
+# SN Devices
+#
+
+#
# File systems
#
CONFIG_EXT2_FS=y
# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
CONFIG_EXT3_FS=y
# CONFIG_EXT3_FS_XATTR is not set
CONFIG_JBD=y
@@ -682,20 +755,24 @@ CONFIG_JBD=y
# CONFIG_REISERFS_FS is not set
CONFIG_JFS_FS=m
# CONFIG_JFS_POSIX_ACL is not set
+# CONFIG_JFS_SECURITY is not set
# CONFIG_JFS_DEBUG is not set
# CONFIG_JFS_STATISTICS is not set
CONFIG_FS_POSIX_ACL=y
CONFIG_XFS_FS=m
-# CONFIG_XFS_RT is not set
+CONFIG_XFS_EXPORT=y
# CONFIG_XFS_QUOTA is not set
# CONFIG_XFS_SECURITY is not set
# CONFIG_XFS_POSIX_ACL is not set
+# CONFIG_XFS_RT is not set
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
# CONFIG_QUOTA is not set
CONFIG_DNOTIFY=y
# CONFIG_AUTOFS_FS is not set
CONFIG_AUTOFS4_FS=y
+# CONFIG_FUSE_FS is not set
#
# CD-ROM/DVD Filesystems
@@ -722,14 +799,11 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
-# CONFIG_DEVPTS_FS_XATTR is not set
CONFIG_TMPFS=y
-CONFIG_TMPFS_XATTR=y
-# CONFIG_TMPFS_SECURITY is not set
# CONFIG_HUGETLBFS is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
+# CONFIG_RELAYFS_FS is not set
#
# Miscellaneous filesystems
@@ -754,16 +828,19 @@ CONFIG_UFS_FS=m
#
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
CONFIG_NFS_V4=y
CONFIG_NFS_DIRECTIO=y
CONFIG_NFSD=m
CONFIG_NFSD_V3=y
+# CONFIG_NFSD_V3_ACL is not set
CONFIG_NFSD_V4=y
CONFIG_NFSD_TCP=y
CONFIG_ROOT_NFS=y
CONFIG_LOCKD=y
CONFIG_LOCKD_V4=y
CONFIG_EXPORTFS=m
+CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
CONFIG_SUNRPC_GSS=y
CONFIG_RPCSEC_GSS_KRB5=y
@@ -778,6 +855,7 @@ CONFIG_CIFS=m
# CONFIG_NCP_FS is not set
# CONFIG_CODA_FS is not set
# CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
#
# Partition Types
@@ -838,13 +916,19 @@ CONFIG_OPROFILE=m
#
# Kernel hacking
#
+# CONFIG_PRINTK_TIME is not set
CONFIG_DEBUG_KERNEL=y
CONFIG_MAGIC_SYSRQ=y
+CONFIG_LOG_BUF_SHIFT=16
+CONFIG_DETECT_SOFTLOCKUP=y
# CONFIG_SCHEDSTATS is not set
# CONFIG_DEBUG_SLAB is not set
# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
# CONFIG_DEBUG_KOBJECT is not set
# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_IOREMAP is not set
+# CONFIG_DEBUG_FS is not set
#
# Security options
@@ -865,6 +949,7 @@ CONFIG_CRYPTO_SHA1=m
CONFIG_CRYPTO_SHA256=m
CONFIG_CRYPTO_SHA512=m
CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_TGR192=m
CONFIG_CRYPTO_DES=y
CONFIG_CRYPTO_BLOWFISH=m
CONFIG_CRYPTO_TWOFISH=m
@@ -882,9 +967,14 @@ CONFIG_CRYPTO_CRC32C=m
CONFIG_CRYPTO_TEST=m
#
+# Hardware crypto devices
+#
+
+#
# Library routines
#
CONFIG_CRC_CCITT=m
+# CONFIG_CRC16 is not set
CONFIG_CRC32=y
CONFIG_LIBCRC32C=m
CONFIG_ZLIB_INFLATE=m
diff --git a/arch/parisc/configs/a500_defconfig b/arch/parisc/configs/a500_defconfig
index 30fc03ed0cfb..955ef5084f3e 100644
--- a/arch/parisc/configs/a500_defconfig
+++ b/arch/parisc/configs/a500_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-rc4-pa1
-# Wed Feb 16 11:32:49 2005
+# Linux kernel version: 2.6.14-rc5-pa1
+# Fri Oct 21 23:04:54 2005
#
CONFIG_PARISC=y
CONFIG_MMU=y
@@ -10,6 +10,7 @@ CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
#
# Code maturity level options
@@ -19,26 +20,32 @@ CONFIG_EXPERIMENTAL=y
CONFIG_BROKEN=y
CONFIG_BROKEN_ON_SMP=y
CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
#
# General setup
#
CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
CONFIG_POSIX_MQUEUE=y
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=16
CONFIG_HOTPLUG=y
CONFIG_KOBJECT_UEVENT=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
+# CONFIG_CPUSETS is not set
+CONFIG_INITRAMFS_SOURCE=""
CONFIG_EMBEDDED=y
CONFIG_KALLSYMS=y
CONFIG_KALLSYMS_ALL=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
@@ -48,6 +55,7 @@ CONFIG_CC_ALIGN_LABELS=0
CONFIG_CC_ALIGN_LOOPS=0
CONFIG_CC_ALIGN_JUMPS=0
# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
#
# Loadable module support
@@ -74,7 +82,19 @@ CONFIG_PREFETCH=y
CONFIG_64BIT=y
CONFIG_SMP=y
CONFIG_HOTPLUG_CPU=y
+CONFIG_ARCH_DISCONTIGMEM_ENABLE=y
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+CONFIG_SELECT_MEMORY_MODEL=y
+# CONFIG_FLATMEM_MANUAL is not set
+CONFIG_DISCONTIGMEM_MANUAL=y
+# CONFIG_SPARSEMEM_MANUAL is not set
CONFIG_DISCONTIGMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_NEED_MULTIPLE_NODES=y
+# CONFIG_SPARSEMEM_STATIC is not set
# CONFIG_PREEMPT is not set
CONFIG_COMPAT=y
CONFIG_NR_CPUS=8
@@ -85,7 +105,7 @@ CONFIG_NR_CPUS=8
# CONFIG_GSC is not set
CONFIG_PCI=y
CONFIG_PCI_LEGACY_PROC=y
-CONFIG_PCI_NAMES=y
+# CONFIG_PCI_DEBUG is not set
CONFIG_PCI_LBA=y
CONFIG_IOSAPIC=y
CONFIG_IOMMU_SBA=y
@@ -96,6 +116,8 @@ CONFIG_IOMMU_SBA=y
CONFIG_PCCARD=m
# CONFIG_PCMCIA_DEBUG is not set
CONFIG_PCMCIA=m
+# CONFIG_PCMCIA_LOAD_CIS is not set
+CONFIG_PCMCIA_IOCTL=y
CONFIG_CARDBUS=y
#
@@ -104,7 +126,6 @@ CONFIG_CARDBUS=y
CONFIG_YENTA=m
CONFIG_PD6729=m
CONFIG_I82092=m
-CONFIG_TCIC=m
CONFIG_PCCARD_NONSTATIC=m
#
@@ -127,6 +148,203 @@ CONFIG_BINFMT_ELF=y
# CONFIG_BINFMT_MISC is not set
#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+CONFIG_NET_KEY=m
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+CONFIG_INET_AH=m
+CONFIG_INET_ESP=m
+# CONFIG_INET_IPCOMP is not set
+CONFIG_INET_TUNNEL=m
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+
+#
+# IP: Virtual Server Configuration
+#
+# CONFIG_IP_VS is not set
+CONFIG_IPV6=m
+# CONFIG_IPV6_PRIVACY is not set
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+CONFIG_INET6_TUNNEL=m
+CONFIG_IPV6_TUNNEL=m
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+# CONFIG_NETFILTER_NETLINK is not set
+
+#
+# IP: Netfilter Configuration
+#
+CONFIG_IP_NF_CONNTRACK=m
+# CONFIG_IP_NF_CT_ACCT is not set
+CONFIG_IP_NF_CONNTRACK_MARK=y
+# CONFIG_IP_NF_CONNTRACK_EVENTS is not set
+CONFIG_IP_NF_CT_PROTO_SCTP=m
+CONFIG_IP_NF_FTP=m
+CONFIG_IP_NF_IRC=m
+# CONFIG_IP_NF_NETBIOS_NS is not set
+CONFIG_IP_NF_TFTP=m
+CONFIG_IP_NF_AMANDA=m
+# CONFIG_IP_NF_PPTP is not set
+CONFIG_IP_NF_QUEUE=m
+CONFIG_IP_NF_IPTABLES=m
+CONFIG_IP_NF_MATCH_LIMIT=m
+CONFIG_IP_NF_MATCH_IPRANGE=m
+CONFIG_IP_NF_MATCH_MAC=m
+CONFIG_IP_NF_MATCH_PKTTYPE=m
+CONFIG_IP_NF_MATCH_MARK=m
+CONFIG_IP_NF_MATCH_MULTIPORT=m
+CONFIG_IP_NF_MATCH_TOS=m
+CONFIG_IP_NF_MATCH_RECENT=m
+CONFIG_IP_NF_MATCH_ECN=m
+CONFIG_IP_NF_MATCH_DSCP=m
+CONFIG_IP_NF_MATCH_AH_ESP=m
+CONFIG_IP_NF_MATCH_LENGTH=m
+CONFIG_IP_NF_MATCH_TTL=m
+CONFIG_IP_NF_MATCH_TCPMSS=m
+CONFIG_IP_NF_MATCH_HELPER=m
+CONFIG_IP_NF_MATCH_STATE=m
+CONFIG_IP_NF_MATCH_CONNTRACK=m
+CONFIG_IP_NF_MATCH_OWNER=m
+# CONFIG_IP_NF_MATCH_ADDRTYPE is not set
+# CONFIG_IP_NF_MATCH_REALM is not set
+CONFIG_IP_NF_MATCH_SCTP=m
+# CONFIG_IP_NF_MATCH_DCCP is not set
+CONFIG_IP_NF_MATCH_COMMENT=m
+CONFIG_IP_NF_MATCH_CONNMARK=m
+CONFIG_IP_NF_MATCH_HASHLIMIT=m
+# CONFIG_IP_NF_MATCH_STRING is not set
+CONFIG_IP_NF_FILTER=m
+CONFIG_IP_NF_TARGET_REJECT=m
+CONFIG_IP_NF_TARGET_LOG=m
+CONFIG_IP_NF_TARGET_ULOG=m
+CONFIG_IP_NF_TARGET_TCPMSS=m
+# CONFIG_IP_NF_TARGET_NFQUEUE is not set
+CONFIG_IP_NF_NAT=m
+CONFIG_IP_NF_NAT_NEEDED=y
+CONFIG_IP_NF_TARGET_MASQUERADE=m
+CONFIG_IP_NF_TARGET_REDIRECT=m
+CONFIG_IP_NF_TARGET_NETMAP=m
+CONFIG_IP_NF_TARGET_SAME=m
+CONFIG_IP_NF_NAT_SNMP_BASIC=m
+CONFIG_IP_NF_NAT_IRC=m
+CONFIG_IP_NF_NAT_FTP=m
+CONFIG_IP_NF_NAT_TFTP=m
+CONFIG_IP_NF_NAT_AMANDA=m
+CONFIG_IP_NF_MANGLE=m
+CONFIG_IP_NF_TARGET_TOS=m
+CONFIG_IP_NF_TARGET_ECN=m
+CONFIG_IP_NF_TARGET_DSCP=m
+CONFIG_IP_NF_TARGET_MARK=m
+CONFIG_IP_NF_TARGET_CLASSIFY=m
+# CONFIG_IP_NF_TARGET_TTL is not set
+CONFIG_IP_NF_TARGET_CONNMARK=m
+CONFIG_IP_NF_TARGET_CLUSTERIP=m
+CONFIG_IP_NF_RAW=m
+CONFIG_IP_NF_TARGET_NOTRACK=m
+CONFIG_IP_NF_ARPTABLES=m
+CONFIG_IP_NF_ARPFILTER=m
+CONFIG_IP_NF_ARP_MANGLE=m
+
+#
+# IPv6: Netfilter Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP6_NF_QUEUE is not set
+CONFIG_IP6_NF_IPTABLES=m
+# CONFIG_IP6_NF_MATCH_LIMIT is not set
+CONFIG_IP6_NF_MATCH_MAC=m
+CONFIG_IP6_NF_MATCH_RT=m
+CONFIG_IP6_NF_MATCH_OPTS=m
+CONFIG_IP6_NF_MATCH_FRAG=m
+CONFIG_IP6_NF_MATCH_HL=m
+# CONFIG_IP6_NF_MATCH_MULTIPORT is not set
+# CONFIG_IP6_NF_MATCH_OWNER is not set
+# CONFIG_IP6_NF_MATCH_MARK is not set
+CONFIG_IP6_NF_MATCH_IPV6HEADER=m
+# CONFIG_IP6_NF_MATCH_AHESP is not set
+# CONFIG_IP6_NF_MATCH_LENGTH is not set
+# CONFIG_IP6_NF_MATCH_EUI64 is not set
+CONFIG_IP6_NF_FILTER=m
+CONFIG_IP6_NF_TARGET_LOG=m
+CONFIG_IP6_NF_TARGET_REJECT=m
+# CONFIG_IP6_NF_TARGET_NFQUEUE is not set
+CONFIG_IP6_NF_MANGLE=m
+# CONFIG_IP6_NF_TARGET_MARK is not set
+# CONFIG_IP6_NF_TARGET_HL is not set
+CONFIG_IP6_NF_RAW=m
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+CONFIG_IP_DCCP=m
+CONFIG_INET_DCCP_DIAG=m
+
+#
+# DCCP CCIDs Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP_CCID3 is not set
+
+#
+# DCCP Kernel Hacking
+#
+# CONFIG_IP_DCCP_DEBUG is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+CONFIG_LLC=m
+CONFIG_LLC2=m
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+CONFIG_NET_PKTGEN=m
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
+
+#
# Device Drivers
#
@@ -139,6 +357,11 @@ CONFIG_FW_LOADER=y
# CONFIG_DEBUG_DRIVER is not set
#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+
+#
# Memory Technology Devices (MTD)
#
# CONFIG_MTD is not set
@@ -169,7 +392,6 @@ CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=6144
CONFIG_BLK_DEV_INITRD=y
-CONFIG_INITRAMFS_SOURCE=""
# CONFIG_CDROM_PKTCDVD is not set
#
@@ -189,6 +411,7 @@ CONFIG_IOSCHED_CFQ=y
#
# SCSI device support
#
+CONFIG_RAID_ATTRS=m
CONFIG_SCSI=y
CONFIG_SCSI_PROC_FS=y
@@ -201,6 +424,7 @@ CONFIG_CHR_DEV_ST=y
CONFIG_BLK_DEV_SR=y
# CONFIG_BLK_DEV_SR_VENDOR 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
@@ -215,6 +439,7 @@ CONFIG_SCSI_MULTI_LUN=y
CONFIG_SCSI_SPI_ATTRS=y
CONFIG_SCSI_FC_ATTRS=m
CONFIG_SCSI_ISCSI_ATTRS=m
+CONFIG_SCSI_SAS_ATTRS=m
#
# SCSI low-level drivers
@@ -229,14 +454,12 @@ CONFIG_SCSI_ISCSI_ATTRS=m
# CONFIG_SCSI_ADVANSYS is not set
# CONFIG_MEGARAID_NEWGEN is not set
# CONFIG_MEGARAID_LEGACY is not set
+# CONFIG_MEGARAID_SAS is not set
# CONFIG_SCSI_SATA is not set
-# CONFIG_SCSI_BUSLOGIC is not set
# CONFIG_SCSI_CPQFCTS is not set
# CONFIG_SCSI_DMX3191D is not set
-# CONFIG_SCSI_EATA is not set
# CONFIG_SCSI_EATA_PIO is not set
# CONFIG_SCSI_FUTURE_DOMAIN is not set
-# CONFIG_SCSI_GDTH is not set
# CONFIG_SCSI_IPS is not set
# CONFIG_SCSI_INITIO is not set
# CONFIG_SCSI_INIA100 is not set
@@ -246,8 +469,6 @@ CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
# CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set
# CONFIG_SCSI_IPR is not set
-# CONFIG_SCSI_PCI2000 is not set
-# CONFIG_SCSI_PCI2220I is not set
# CONFIG_SCSI_QLOGIC_ISP is not set
CONFIG_SCSI_QLOGIC_FC=m
# CONFIG_SCSI_QLOGIC_FC_FIRMWARE is not set
@@ -258,7 +479,9 @@ CONFIG_SCSI_QLA2XXX=y
# CONFIG_SCSI_QLA22XX is not set
CONFIG_SCSI_QLA2300=m
CONFIG_SCSI_QLA2322=m
-CONFIG_SCSI_QLA6312=m
+# CONFIG_SCSI_QLA6312 is not set
+# CONFIG_SCSI_QLA24XX is not set
+# CONFIG_SCSI_LPFC is not set
# CONFIG_SCSI_DC395x is not set
# CONFIG_SCSI_DC390T is not set
CONFIG_SCSI_DEBUG=m
@@ -288,8 +511,11 @@ CONFIG_MD_RAID1=y
#
# Fusion MPT device support
#
-CONFIG_FUSION=m
-CONFIG_FUSION_MAX_SGE=40
+CONFIG_FUSION=y
+CONFIG_FUSION_SPI=m
+CONFIG_FUSION_FC=m
+# CONFIG_FUSION_SAS is not set
+CONFIG_FUSION_MAX_SGE=128
CONFIG_FUSION_CTL=m
#
@@ -303,153 +529,13 @@ CONFIG_FUSION_CTL=m
# CONFIG_I2O is not set
#
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
-CONFIG_NETLINK_DEV=y
-CONFIG_UNIX=y
-CONFIG_NET_KEY=m
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-# CONFIG_IP_ADVANCED_ROUTER is not set
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-CONFIG_IP_PNP_BOOTP=y
-# CONFIG_IP_PNP_RARP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_IP_MROUTE is not set
-# CONFIG_ARPD is not set
-# CONFIG_SYN_COOKIES is not set
-CONFIG_INET_AH=m
-CONFIG_INET_ESP=m
-# CONFIG_INET_IPCOMP is not set
-CONFIG_INET_TUNNEL=m
-CONFIG_IP_TCPDIAG=y
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-
-#
-# IP: Virtual Server Configuration
+# Network device support
#
-# CONFIG_IP_VS is not set
-# CONFIG_IPV6 is not set
-CONFIG_NETFILTER=y
-# CONFIG_NETFILTER_DEBUG is not set
-
-#
-# IP: Netfilter Configuration
-#
-CONFIG_IP_NF_CONNTRACK=m
-# CONFIG_IP_NF_CT_ACCT is not set
-CONFIG_IP_NF_CONNTRACK_MARK=y
-CONFIG_IP_NF_CT_PROTO_SCTP=m
-CONFIG_IP_NF_FTP=m
-CONFIG_IP_NF_IRC=m
-CONFIG_IP_NF_TFTP=m
-CONFIG_IP_NF_AMANDA=m
-CONFIG_IP_NF_QUEUE=m
-CONFIG_IP_NF_IPTABLES=m
-CONFIG_IP_NF_MATCH_LIMIT=m
-CONFIG_IP_NF_MATCH_IPRANGE=m
-CONFIG_IP_NF_MATCH_MAC=m
-CONFIG_IP_NF_MATCH_PKTTYPE=m
-CONFIG_IP_NF_MATCH_MARK=m
-CONFIG_IP_NF_MATCH_MULTIPORT=m
-CONFIG_IP_NF_MATCH_TOS=m
-CONFIG_IP_NF_MATCH_RECENT=m
-CONFIG_IP_NF_MATCH_ECN=m
-CONFIG_IP_NF_MATCH_DSCP=m
-CONFIG_IP_NF_MATCH_AH_ESP=m
-CONFIG_IP_NF_MATCH_LENGTH=m
-CONFIG_IP_NF_MATCH_TTL=m
-CONFIG_IP_NF_MATCH_TCPMSS=m
-CONFIG_IP_NF_MATCH_HELPER=m
-CONFIG_IP_NF_MATCH_STATE=m
-CONFIG_IP_NF_MATCH_CONNTRACK=m
-CONFIG_IP_NF_MATCH_OWNER=m
-# CONFIG_IP_NF_MATCH_ADDRTYPE is not set
-# CONFIG_IP_NF_MATCH_REALM is not set
-CONFIG_IP_NF_MATCH_SCTP=m
-CONFIG_IP_NF_MATCH_COMMENT=m
-CONFIG_IP_NF_MATCH_CONNMARK=m
-CONFIG_IP_NF_MATCH_HASHLIMIT=m
-CONFIG_IP_NF_FILTER=m
-CONFIG_IP_NF_TARGET_REJECT=m
-CONFIG_IP_NF_TARGET_LOG=m
-CONFIG_IP_NF_TARGET_ULOG=m
-CONFIG_IP_NF_TARGET_TCPMSS=m
-CONFIG_IP_NF_NAT=m
-CONFIG_IP_NF_NAT_NEEDED=y
-CONFIG_IP_NF_TARGET_MASQUERADE=m
-CONFIG_IP_NF_TARGET_REDIRECT=m
-CONFIG_IP_NF_TARGET_NETMAP=m
-CONFIG_IP_NF_TARGET_SAME=m
-CONFIG_IP_NF_NAT_SNMP_BASIC=m
-CONFIG_IP_NF_NAT_IRC=m
-CONFIG_IP_NF_NAT_FTP=m
-CONFIG_IP_NF_NAT_TFTP=m
-CONFIG_IP_NF_NAT_AMANDA=m
-CONFIG_IP_NF_MANGLE=m
-CONFIG_IP_NF_TARGET_TOS=m
-CONFIG_IP_NF_TARGET_ECN=m
-CONFIG_IP_NF_TARGET_DSCP=m
-CONFIG_IP_NF_TARGET_MARK=m
-CONFIG_IP_NF_TARGET_CLASSIFY=m
-CONFIG_IP_NF_TARGET_CONNMARK=m
-CONFIG_IP_NF_TARGET_CLUSTERIP=m
-CONFIG_IP_NF_RAW=m
-CONFIG_IP_NF_TARGET_NOTRACK=m
-CONFIG_IP_NF_ARPTABLES=m
-CONFIG_IP_NF_ARPFILTER=m
-CONFIG_IP_NF_ARP_MANGLE=m
-CONFIG_XFRM=y
-CONFIG_XFRM_USER=m
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP 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_LLC=m
-CONFIG_LLC2=m
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
-
-#
-# Network testing
-#
-CONFIG_NET_PKTGEN=m
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
CONFIG_NETDEVICES=y
CONFIG_DUMMY=m
CONFIG_BONDING=m
# CONFIG_EQUALIZER is not set
CONFIG_TUN=m
-# CONFIG_ETHERTAP is not set
#
# ARCnet devices
@@ -457,12 +543,18 @@ CONFIG_TUN=m
# CONFIG_ARCNET is not set
#
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
+#
# Ethernet (10 or 100Mbit)
#
CONFIG_NET_ETHERNET=y
CONFIG_MII=m
# CONFIG_HAPPYMEAL is not set
# CONFIG_SUNGEM is not set
+# CONFIG_CASSINI is not set
CONFIG_NET_VENDOR_3COM=y
CONFIG_VORTEX=m
CONFIG_TYPHOON=m
@@ -479,6 +571,7 @@ CONFIG_TULIP_MMIO=y
# CONFIG_DE4X5 is not set
# CONFIG_WINBOND_840 is not set
# CONFIG_DM9102 is not set
+# CONFIG_ULI526X is not set
CONFIG_PCMCIA_XIRCOM=m
# CONFIG_PCMCIA_XIRTULIP is not set
CONFIG_HP100=m
@@ -489,48 +582,43 @@ CONFIG_PCNET32=m
# CONFIG_B44 is not set
# CONFIG_FORCEDETH is not set
# CONFIG_DGRS is not set
-CONFIG_EEPRO100=m
+# CONFIG_EEPRO100 is not set
CONFIG_E100=m
-CONFIG_E100_NAPI=y
# CONFIG_FEALNX is not set
-CONFIG_NATSEMI=m
+# CONFIG_NATSEMI is not set
# CONFIG_NE2K_PCI is not set
# CONFIG_8139CP is not set
-CONFIG_8139TOO=m
-# CONFIG_8139TOO_PIO is not set
-# CONFIG_8139TOO_TUNE_TWISTER is not set
-# CONFIG_8139TOO_8129 is not set
-# CONFIG_8139_OLD_RX_RESET is not set
+# CONFIG_8139TOO is not set
# CONFIG_SIS900 is not set
-CONFIG_EPIC100=m
+# CONFIG_EPIC100 is not set
# CONFIG_SUNDANCE is not set
-CONFIG_VIA_RHINE=m
-CONFIG_VIA_RHINE_MMIO=y
+# CONFIG_VIA_RHINE is not set
#
# Ethernet (1000 Mbit)
#
CONFIG_ACENIC=m
CONFIG_ACENIC_OMIT_TIGON_I=y
-CONFIG_DL2K=m
+# CONFIG_DL2K is not set
CONFIG_E1000=m
CONFIG_E1000_NAPI=y
# CONFIG_NS83820 is not set
# CONFIG_HAMACHI is not set
# CONFIG_YELLOWFIN is not set
# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
# CONFIG_SK98LIN is not set
# CONFIG_VIA_VELOCITY is not set
CONFIG_TIGON3=m
+# CONFIG_BNX2 is not set
#
# Ethernet (10000 Mbit)
#
-CONFIG_IXGB=m
-CONFIG_IXGB_NAPI=y
-CONFIG_S2IO=m
-CONFIG_S2IO_NAPI=y
-# CONFIG_2BUFF_MODE is not set
+# CONFIG_CHELSIO_T1 is not set
+# CONFIG_IXGB is not set
+# CONFIG_S2IO is not set
#
# Token Ring devices
@@ -560,6 +648,7 @@ CONFIG_PCMCIA_RAYCS=m
CONFIG_HERMES=m
CONFIG_PLX_HERMES=m
CONFIG_TMD_HERMES=m
+# CONFIG_NORTEL_HERMES is not set
CONFIG_PCI_HERMES=m
# CONFIG_ATMEL is not set
@@ -567,6 +656,7 @@ CONFIG_PCI_HERMES=m
# Wireless 802.11b Pcmcia/Cardbus cards support
#
CONFIG_PCMCIA_HERMES=m
+# CONFIG_PCMCIA_SPECTRUM is not set
CONFIG_AIRO_CS=m
CONFIG_PCMCIA_WL3501=m
@@ -574,6 +664,7 @@ CONFIG_PCMCIA_WL3501=m
# Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support
#
# CONFIG_PRISM54 is not set
+# CONFIG_HOSTAP is not set
CONFIG_NET_WIRELESS=y
#
@@ -607,6 +698,8 @@ CONFIG_PPP_BSDCOMP=m
# CONFIG_NET_FC is not set
# CONFIG_SHAPER is not set
# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
#
# ISDN subsystem
@@ -633,13 +726,6 @@ CONFIG_INPUT=y
# CONFIG_INPUT_EVBUG is not set
#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-# CONFIG_SERIO is not set
-
-#
# Input Device Drivers
#
# CONFIG_INPUT_KEYBOARD is not set
@@ -649,6 +735,12 @@ CONFIG_SOUND_GAMEPORT=y
# CONFIG_INPUT_MISC is not set
#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
# Character devices
#
CONFIG_VT=y
@@ -667,7 +759,6 @@ CONFIG_SERIAL_8250_EXTENDED=y
CONFIG_SERIAL_8250_MANY_PORTS=y
CONFIG_SERIAL_8250_SHARE_IRQ=y
# CONFIG_SERIAL_8250_DETECT_IRQ is not set
-# CONFIG_SERIAL_8250_MULTIPORT is not set
# CONFIG_SERIAL_8250_RSA is not set
#
@@ -677,6 +768,7 @@ CONFIG_SERIAL_8250_SHARE_IRQ=y
CONFIG_PDC_CONSOLE=y
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
CONFIG_UNIX98_PTYS=y
# CONFIG_LEGACY_PTYS is not set
@@ -708,6 +800,11 @@ CONFIG_RAW_DRIVER=y
CONFIG_MAX_RAW_DEVS=256
#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+
+#
# I2C support
#
# CONFIG_I2C is not set
@@ -718,10 +815,20 @@ CONFIG_MAX_RAW_DEVS=256
# CONFIG_W1 is not set
#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
+#
# Misc devices
#
#
+# Multimedia Capabilities Port drivers
+#
+
+#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
@@ -742,6 +849,7 @@ CONFIG_MAX_RAW_DEVS=256
CONFIG_DUMMY_CONSOLE=y
CONFIG_DUMMY_CONSOLE_COLUMNS=160
CONFIG_DUMMY_CONSOLE_ROWS=64
+# CONFIG_STI_CONSOLE is not set
#
# Sound
@@ -751,13 +859,9 @@ CONFIG_DUMMY_CONSOLE_ROWS=64
#
# USB support
#
-# CONFIG_USB is not set
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB_ARCH_HAS_OHCI=y
-
-#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
-#
+# CONFIG_USB is not set
#
# USB Gadget Support
@@ -772,17 +876,18 @@ CONFIG_USB_ARCH_HAS_OHCI=y
#
# InfiniBand support
#
-CONFIG_INFINIBAND=m
-CONFIG_INFINIBAND_MTHCA=m
-# CONFIG_INFINIBAND_MTHCA_DEBUG is not set
-CONFIG_INFINIBAND_IPOIB=m
-# CONFIG_INFINIBAND_IPOIB_DEBUG is not set
+# CONFIG_INFINIBAND is not set
+
+#
+# SN Devices
+#
#
# File systems
#
CONFIG_EXT2_FS=y
# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
CONFIG_EXT3_FS=y
# CONFIG_EXT3_FS_XATTR is not set
CONFIG_JBD=y
@@ -794,22 +899,20 @@ CONFIG_JFS_FS=m
# CONFIG_JFS_DEBUG is not set
# CONFIG_JFS_STATISTICS is not set
CONFIG_FS_POSIX_ACL=y
-
-#
-# XFS support
-#
CONFIG_XFS_FS=m
CONFIG_XFS_EXPORT=y
-# CONFIG_XFS_RT is not set
# CONFIG_XFS_QUOTA is not set
# CONFIG_XFS_SECURITY is not set
# CONFIG_XFS_POSIX_ACL is not set
+# CONFIG_XFS_RT is not set
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
# CONFIG_QUOTA is not set
CONFIG_DNOTIFY=y
# CONFIG_AUTOFS_FS is not set
CONFIG_AUTOFS4_FS=y
+# CONFIG_FUSE_FS is not set
#
# CD-ROM/DVD Filesystems
@@ -836,13 +939,11 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
-# CONFIG_DEVPTS_FS_XATTR is not set
CONFIG_TMPFS=y
-# CONFIG_TMPFS_XATTR is not set
# CONFIG_HUGETLBFS is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
+# CONFIG_RELAYFS_FS is not set
#
# Miscellaneous filesystems
@@ -867,15 +968,18 @@ CONFIG_UFS_FS=m
#
CONFIG_NFS_FS=m
CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
CONFIG_NFS_V4=y
CONFIG_NFS_DIRECTIO=y
CONFIG_NFSD=m
CONFIG_NFSD_V3=y
+# CONFIG_NFSD_V3_ACL is not set
CONFIG_NFSD_V4=y
CONFIG_NFSD_TCP=y
CONFIG_LOCKD=m
CONFIG_LOCKD_V4=y
CONFIG_EXPORTFS=m
+CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=m
CONFIG_SUNRPC_GSS=m
CONFIG_RPCSEC_GSS_KRB5=m
@@ -890,6 +994,7 @@ CONFIG_CIFS=m
# CONFIG_NCP_FS is not set
# CONFIG_CODA_FS is not set
# CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
#
# Partition Types
@@ -906,15 +1011,15 @@ CONFIG_NLS_CODEPAGE_437=m
# CONFIG_NLS_CODEPAGE_737 is not set
# CONFIG_NLS_CODEPAGE_775 is not set
CONFIG_NLS_CODEPAGE_850=m
-CONFIG_NLS_CODEPAGE_852=m
+# CONFIG_NLS_CODEPAGE_852 is not set
# CONFIG_NLS_CODEPAGE_855 is not set
# CONFIG_NLS_CODEPAGE_857 is not set
# CONFIG_NLS_CODEPAGE_860 is not set
# CONFIG_NLS_CODEPAGE_861 is not set
# CONFIG_NLS_CODEPAGE_862 is not set
-CONFIG_NLS_CODEPAGE_863=m
+# CONFIG_NLS_CODEPAGE_863 is not set
# CONFIG_NLS_CODEPAGE_864 is not set
-CONFIG_NLS_CODEPAGE_865=m
+# CONFIG_NLS_CODEPAGE_865 is not set
# CONFIG_NLS_CODEPAGE_866 is not set
# CONFIG_NLS_CODEPAGE_869 is not set
# CONFIG_NLS_CODEPAGE_936 is not set
@@ -926,10 +1031,10 @@ CONFIG_NLS_CODEPAGE_865=m
# CONFIG_NLS_CODEPAGE_1250 is not set
# CONFIG_NLS_CODEPAGE_1251 is not set
# CONFIG_NLS_ASCII is not set
-CONFIG_NLS_ISO8859_1=m
-CONFIG_NLS_ISO8859_2=m
-CONFIG_NLS_ISO8859_3=m
-CONFIG_NLS_ISO8859_4=m
+# CONFIG_NLS_ISO8859_1 is not set
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
# CONFIG_NLS_ISO8859_5 is not set
# CONFIG_NLS_ISO8859_6 is not set
# CONFIG_NLS_ISO8859_7 is not set
@@ -950,11 +1055,15 @@ CONFIG_OPROFILE=m
#
# Kernel hacking
#
+# CONFIG_PRINTK_TIME is not set
CONFIG_DEBUG_KERNEL=y
CONFIG_MAGIC_SYSRQ=y
+CONFIG_LOG_BUF_SHIFT=16
+CONFIG_DETECT_SOFTLOCKUP=y
# CONFIG_SCHEDSTATS is not set
# CONFIG_DEBUG_SLAB is not set
# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
# CONFIG_DEBUG_KOBJECT is not set
# CONFIG_DEBUG_INFO is not set
# CONFIG_DEBUG_IOREMAP is not set
@@ -974,25 +1083,26 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
CONFIG_CRYPTO=y
CONFIG_CRYPTO_HMAC=y
CONFIG_CRYPTO_NULL=m
-CONFIG_CRYPTO_MD4=m
-CONFIG_CRYPTO_MD5=m
+# CONFIG_CRYPTO_MD4 is not set
+CONFIG_CRYPTO_MD5=y
CONFIG_CRYPTO_SHA1=m
-CONFIG_CRYPTO_SHA256=m
-CONFIG_CRYPTO_SHA512=m
-CONFIG_CRYPTO_WP512=m
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_WP512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
CONFIG_CRYPTO_DES=m
CONFIG_CRYPTO_BLOWFISH=m
-CONFIG_CRYPTO_TWOFISH=m
-CONFIG_CRYPTO_SERPENT=m
-CONFIG_CRYPTO_AES=m
-CONFIG_CRYPTO_CAST5=m
-CONFIG_CRYPTO_CAST6=m
-CONFIG_CRYPTO_TEA=m
-CONFIG_CRYPTO_ARC4=m
-CONFIG_CRYPTO_KHAZAD=m
-CONFIG_CRYPTO_ANUBIS=m
+# CONFIG_CRYPTO_TWOFISH is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_ANUBIS is not set
CONFIG_CRYPTO_DEFLATE=m
-CONFIG_CRYPTO_MICHAEL_MIC=m
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
CONFIG_CRYPTO_CRC32C=m
CONFIG_CRYPTO_TEST=m
@@ -1004,6 +1114,7 @@ CONFIG_CRYPTO_TEST=m
# Library routines
#
CONFIG_CRC_CCITT=m
+# CONFIG_CRC16 is not set
CONFIG_CRC32=y
CONFIG_LIBCRC32C=m
CONFIG_ZLIB_INFLATE=m
diff --git a/arch/parisc/configs/b180_defconfig b/arch/parisc/configs/b180_defconfig
index 46c9511f3229..8819e7e6ae3f 100644
--- a/arch/parisc/configs/b180_defconfig
+++ b/arch/parisc/configs/b180_defconfig
@@ -1,12 +1,15 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.10-pa5
-# Wed Jan 5 13:35:54 2005
+# Linux kernel version: 2.6.14-rc5-pa1
+# Fri Oct 21 23:06:10 2005
#
CONFIG_PARISC=y
CONFIG_MMU=y
CONFIG_STACK_GROWSUP=y
CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
#
# Code maturity level options
@@ -14,33 +17,39 @@ CONFIG_RWSEM_GENERIC_SPINLOCK=y
# CONFIG_EXPERIMENTAL is not set
CONFIG_CLEAN_COMPILE=y
CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
#
# General setup
#
CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=16
# CONFIG_HOTPLUG is not set
CONFIG_KOBJECT_UEVENT=y
-# CONFIG_IKCONFIG is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_INITRAMFS_SOURCE=""
# CONFIG_EMBEDDED is not set
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_ALL is not set
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_SHMEM=y
CONFIG_CC_ALIGN_FUNCTIONS=0
CONFIG_CC_ALIGN_LABELS=0
CONFIG_CC_ALIGN_LOOPS=0
CONFIG_CC_ALIGN_JUMPS=0
# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
#
# Loadable module support
@@ -60,8 +69,14 @@ CONFIG_PA7100LC=y
# CONFIG_PA7300LC is not set
# CONFIG_PA8X00 is not set
CONFIG_PA11=y
-# CONFIG_64BIT is not set
# CONFIG_SMP is not set
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
# CONFIG_PREEMPT is not set
# CONFIG_HPUX is not set
@@ -78,11 +93,25 @@ CONFIG_EISA_NAMES=y
CONFIG_ISA=y
CONFIG_PCI=y
CONFIG_PCI_LEGACY_PROC=y
-CONFIG_PCI_NAMES=y
+# CONFIG_PCI_DEBUG is not set
CONFIG_GSC_DINO=y
# CONFIG_PCI_LBA is not set
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PCI Hotplug Support
+#
+
+#
+# PA-RISC specific drivers
+#
CONFIG_CHASSIS_LCD_LED=y
# CONFIG_PDC_CHASSIS is not set
+CONFIG_PDC_STABLE=y
#
# Executable file formats
@@ -91,6 +120,64 @@ CONFIG_BINFMT_ELF=y
# CONFIG_BINFMT_MISC is not set
#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_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_TUNNEL is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+CONFIG_IPV6=y
+# CONFIG_IPV6_PRIVACY is not set
+# CONFIG_INET6_AH is not set
+# CONFIG_INET6_ESP is not set
+# CONFIG_INET6_IPCOMP is not set
+# CONFIG_INET6_TUNNEL is not set
+# CONFIG_IPV6_TUNNEL is not set
+# CONFIG_NETFILTER 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_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
+
+#
# Device Drivers
#
@@ -99,9 +186,15 @@ CONFIG_BINFMT_ELF=y
#
CONFIG_STANDALONE=y
# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+# CONFIG_FW_LOADER is not set
# CONFIG_DEBUG_DRIVER is not set
#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+
+#
# Memory Technology Devices (MTD)
#
# CONFIG_MTD is not set
@@ -111,10 +204,8 @@ CONFIG_STANDALONE=y
#
CONFIG_PARPORT=y
CONFIG_PARPORT_PC=y
-CONFIG_PARPORT_PC_CML1=y
# CONFIG_PARPORT_SERIAL is not set
CONFIG_PARPORT_GSC=y
-# CONFIG_PARPORT_OTHER is not set
# CONFIG_PARPORT_1284 is not set
#
@@ -125,19 +216,17 @@ CONFIG_PARPORT_GSC=y
#
# Block devices
#
-# CONFIG_BLK_DEV_FD is not set
-# CONFIG_BLK_DEV_XD is not set
# CONFIG_PARIDE is not set
# CONFIG_BLK_CPQ_DA is not set
# CONFIG_BLK_CPQ_CISS_DA is not set
# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_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_SX8 is not set
# CONFIG_BLK_DEV_RAM is not set
CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_INITRAMFS_SOURCE=""
CONFIG_CDROM_PKTCDVD=m
CONFIG_CDROM_PKTCDVD_BUFFERS=8
# CONFIG_CDROM_PKTCDVD_WCACHE is not set
@@ -149,6 +238,7 @@ CONFIG_IOSCHED_NOOP=y
CONFIG_IOSCHED_AS=y
CONFIG_IOSCHED_DEADLINE=y
CONFIG_IOSCHED_CFQ=y
+CONFIG_ATA_OVER_ETH=y
#
# ATA/ATAPI/MFM/RLL support
@@ -158,6 +248,7 @@ CONFIG_IOSCHED_CFQ=y
#
# SCSI device support
#
+# CONFIG_RAID_ATTRS is not set
CONFIG_SCSI=y
CONFIG_SCSI_PROC_FS=y
@@ -170,6 +261,7 @@ CONFIG_CHR_DEV_ST=y
CONFIG_BLK_DEV_SR=y
# CONFIG_BLK_DEV_SR_VENDOR 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
@@ -183,16 +275,16 @@ CONFIG_CHR_DEV_SG=y
#
CONFIG_SCSI_SPI_ATTRS=y
# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_ATTRS is not set
#
# SCSI low-level drivers
#
# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
# CONFIG_SCSI_3W_9XXX is not set
-# CONFIG_SCSI_7000FASST is not set
# CONFIG_SCSI_ACARD is not set
# CONFIG_SCSI_AHA152X is not set
-# CONFIG_SCSI_AHA1542 is not set
# CONFIG_SCSI_AHA1740 is not set
# CONFIG_SCSI_AACRAID is not set
# CONFIG_SCSI_AIC7XXX is not set
@@ -202,14 +294,11 @@ CONFIG_SCSI_SPI_ATTRS=y
# CONFIG_SCSI_IN2000 is not set
# CONFIG_MEGARAID_NEWGEN is not set
# CONFIG_MEGARAID_LEGACY is not set
+# CONFIG_MEGARAID_SAS is not set
# CONFIG_SCSI_SATA is not set
-# CONFIG_SCSI_BUSLOGIC is not set
# CONFIG_SCSI_DMX3191D is not set
# CONFIG_SCSI_DTC3280 is not set
-# CONFIG_SCSI_EATA is not set
-# CONFIG_SCSI_EATA_PIO is not set
# CONFIG_SCSI_FUTURE_DOMAIN is not set
-# CONFIG_SCSI_GDTH is not set
# CONFIG_SCSI_GENERIC_NCR5380 is not set
# CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set
# CONFIG_SCSI_IPS is not set
@@ -219,7 +308,6 @@ CONFIG_SCSI_SPI_ATTRS=y
# CONFIG_SCSI_IMM is not set
# CONFIG_SCSI_NCR53C406A is not set
CONFIG_SCSI_LASI700=y
-CONFIG_53C700_MEM_MAPPED=y
CONFIG_53C700_LE_ON_BE=y
CONFIG_SCSI_SYM53C8XX_2=y
CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=0
@@ -231,7 +319,6 @@ CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
# CONFIG_SCSI_PAS16 is not set
# CONFIG_SCSI_PSI240I is not set
# CONFIG_SCSI_QLOGIC_FAS is not set
-# CONFIG_SCSI_QLOGIC_ISP is not set
# CONFIG_SCSI_QLOGIC_FC is not set
# CONFIG_SCSI_QLOGIC_1280 is not set
CONFIG_SCSI_QLA2XXX=y
@@ -240,12 +327,12 @@ CONFIG_SCSI_QLA2XXX=y
# CONFIG_SCSI_QLA2300 is not set
# CONFIG_SCSI_QLA2322 is not set
# CONFIG_SCSI_QLA6312 is not set
-# CONFIG_SCSI_QLA6322 is not set
+# CONFIG_SCSI_QLA24XX is not set
+# CONFIG_SCSI_LPFC is not set
# CONFIG_SCSI_SIM710 is not set
# CONFIG_SCSI_SYM53C416 is not set
# CONFIG_SCSI_DC390T is not set
# CONFIG_SCSI_T128 is not set
-# CONFIG_SCSI_U14_34F is not set
# CONFIG_SCSI_NSP32 is not set
# CONFIG_SCSI_DEBUG is not set
@@ -263,6 +350,7 @@ CONFIG_MD_LINEAR=y
CONFIG_MD_RAID0=y
CONFIG_MD_RAID1=y
CONFIG_MD_RAID5=y
+CONFIG_MD_RAID6=y
# CONFIG_MD_MULTIPATH is not set
# CONFIG_MD_FAULTY is not set
# CONFIG_BLK_DEV_DM is not set
@@ -271,6 +359,9 @@ CONFIG_MD_RAID5=y
# Fusion MPT device support
#
# CONFIG_FUSION is not set
+# CONFIG_FUSION_SPI is not set
+# CONFIG_FUSION_FC is not set
+# CONFIG_FUSION_SAS is not set
#
# IEEE 1394 (FireWire) support
@@ -283,58 +374,8 @@ CONFIG_MD_RAID5=y
# CONFIG_I2O is not set
#
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
-CONFIG_NETLINK_DEV=y
-CONFIG_UNIX=y
-# CONFIG_NET_KEY is not set
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-# CONFIG_IP_ADVANCED_ROUTER is not set
-CONFIG_IP_PNP=y
-# CONFIG_IP_PNP_DHCP is not set
-CONFIG_IP_PNP_BOOTP=y
-# CONFIG_IP_PNP_RARP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_IP_MROUTE is not set
-# CONFIG_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_TUNNEL is not set
-CONFIG_IP_TCPDIAG=y
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-# CONFIG_NETFILTER 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
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
-
-#
-# Network testing
+# Network device support
#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
CONFIG_NETDEVICES=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
@@ -347,6 +388,11 @@ CONFIG_NETDEVICES=y
# CONFIG_ARCNET is not set
#
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
+#
# Ethernet (10 or 100Mbit)
#
CONFIG_NET_ETHERNET=y
@@ -354,8 +400,8 @@ CONFIG_NET_ETHERNET=y
# CONFIG_LASI_82596 is not set
# CONFIG_HAPPYMEAL is not set
# CONFIG_SUNGEM is not set
+# CONFIG_CASSINI is not set
# CONFIG_NET_VENDOR_3COM is not set
-# CONFIG_LANCE is not set
# CONFIG_NET_VENDOR_SMC is not set
# CONFIG_NET_VENDOR_RACAL is not set
@@ -369,6 +415,7 @@ CONFIG_TULIP=y
# CONFIG_DE4X5 is not set
# CONFIG_WINBOND_840 is not set
# CONFIG_DM9102 is not set
+# CONFIG_ULI526X is not set
# CONFIG_DEPCA is not set
# CONFIG_HP100 is not set
# CONFIG_NET_ISA is not set
@@ -384,12 +431,15 @@ CONFIG_TULIP=y
# CONFIG_NS83820 is not set
# CONFIG_HAMACHI is not set
# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
# CONFIG_SK98LIN is not set
# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
#
# Ethernet (10000 Mbit)
#
+# CONFIG_CHELSIO_T1 is not set
# CONFIG_IXGB is not set
# CONFIG_S2IO is not set
@@ -413,12 +463,12 @@ CONFIG_NET_RADIO=y
#
# Wireless 802.11b ISA/PCI cards support
#
-# CONFIG_AIRO is not set
# CONFIG_HERMES is not set
#
# Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support
#
+# CONFIG_HOSTAP is not set
CONFIG_NET_WIRELESS=y
#
@@ -435,6 +485,8 @@ CONFIG_PPP=y
# CONFIG_PPP_BSDCOMP is not set
# CONFIG_SLIP is not set
# CONFIG_NET_FC is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
#
# ISDN subsystem
@@ -464,23 +516,12 @@ CONFIG_INPUT_EVDEV=y
# CONFIG_INPUT_EVBUG is not set
#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=y
-# CONFIG_SERIO_SERPORT is not set
-# CONFIG_SERIO_PARKBD is not set
-CONFIG_SERIO_GSCPS2=y
-# CONFIG_HP_SDC is not set
-# CONFIG_SERIO_PCIPS2 is not set
-# CONFIG_SERIO_RAW is not set
-
-#
# Input Device Drivers
#
CONFIG_INPUT_KEYBOARD=y
-# CONFIG_KEYBOARD_ATKBD is not set
+CONFIG_KEYBOARD_ATKBD=y
+CONFIG_KEYBOARD_ATKBD_HP_KEYCODES=y
+# CONFIG_KEYBOARD_ATKBD_RDI_KEYCODES is not set
# CONFIG_KEYBOARD_SUNKBD is not set
# CONFIG_KEYBOARD_LKKBD is not set
# CONFIG_KEYBOARD_XTKBD is not set
@@ -488,7 +529,7 @@ CONFIG_INPUT_KEYBOARD=y
# CONFIG_KEYBOARD_HIL_OLD is not set
# CONFIG_KEYBOARD_HIL is not set
CONFIG_INPUT_MOUSE=y
-# CONFIG_MOUSE_PS2 is not set
+CONFIG_MOUSE_PS2=y
# CONFIG_MOUSE_SERIAL is not set
# CONFIG_MOUSE_INPORT is not set
# CONFIG_MOUSE_LOGIBM is not set
@@ -502,6 +543,19 @@ CONFIG_INPUT_MISC=y
# CONFIG_HP_SDC_RTC is not set
#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_SERPORT is not set
+# CONFIG_SERIO_PARKBD is not set
+CONFIG_SERIO_GSCPS2=y
+# CONFIG_HP_SDC is not set
+# CONFIG_SERIO_PCIPS2 is not set
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+
+#
# Character devices
#
CONFIG_VT=y
@@ -519,8 +573,11 @@ CONFIG_SERIAL_8250_EXTENDED=y
CONFIG_SERIAL_8250_MANY_PORTS=y
CONFIG_SERIAL_8250_SHARE_IRQ=y
# CONFIG_SERIAL_8250_DETECT_IRQ is not set
-# CONFIG_SERIAL_8250_MULTIPORT is not set
# CONFIG_SERIAL_8250_RSA is not set
+# CONFIG_SERIAL_8250_FOURPORT is not set
+# CONFIG_SERIAL_8250_ACCENT is not set
+# CONFIG_SERIAL_8250_BOCA is not set
+# CONFIG_SERIAL_8250_HUB6 is not set
#
# Non-8250 serial port support
@@ -529,6 +586,7 @@ CONFIG_SERIAL_8250_SHARE_IRQ=y
# CONFIG_PDC_CONSOLE is not set
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
CONFIG_UNIX98_PTYS=y
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
@@ -555,11 +613,14 @@ CONFIG_GEN_RTC=y
#
# Ftape, the floppy tape device driver
#
-# CONFIG_AGP is not set
# CONFIG_DRM is not set
# CONFIG_RAW_DRIVER is not set
#
+# TPM devices
+#
+
+#
# I2C support
#
# CONFIG_I2C is not set
@@ -570,10 +631,20 @@ CONFIG_GEN_RTC=y
# CONFIG_W1 is not set
#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
+#
# Misc devices
#
#
+# Multimedia Capabilities Port drivers
+#
+
+#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
@@ -587,6 +658,11 @@ CONFIG_GEN_RTC=y
# Graphics support
#
CONFIG_FB=y
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+CONFIG_FB_SOFT_CURSOR=y
+# CONFIG_FB_MACMODES is not set
# CONFIG_FB_MODE_HELPERS is not set
# CONFIG_FB_TILEBLITTING is not set
# CONFIG_FB_CIRRUS is not set
@@ -595,6 +671,7 @@ CONFIG_FB=y
# CONFIG_FB_ASILIANT is not set
# CONFIG_FB_IMSTT is not set
CONFIG_FB_STI=y
+# CONFIG_FB_NVIDIA is not set
# CONFIG_FB_RIVA is not set
# CONFIG_FB_MATROX is not set
# CONFIG_FB_RADEON_OLD is not set
@@ -606,18 +683,19 @@ CONFIG_FB_STI=y
# CONFIG_FB_KYRO is not set
# CONFIG_FB_3DFX is not set
# CONFIG_FB_VOODOO1 is not set
+# CONFIG_FB_CYBLA is not set
# CONFIG_FB_TRIDENT is not set
+# CONFIG_FB_S1D13XXX is not set
# CONFIG_FB_VIRTUAL is not set
#
# Console display driver support
#
-# CONFIG_MDA_CONSOLE is not set
-CONFIG_STI_CONSOLE=y
+CONFIG_DUMMY_CONSOLE=y
CONFIG_DUMMY_CONSOLE_COLUMNS=160
CONFIG_DUMMY_CONSOLE_ROWS=64
-CONFIG_DUMMY_CONSOLE=y
CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_STI_CONSOLE=y
# CONFIG_FONTS is not set
CONFIG_FONT_8x8=y
CONFIG_FONT_8x16=y
@@ -630,6 +708,7 @@ CONFIG_LOGO_LINUX_MONO=y
CONFIG_LOGO_LINUX_VGA16=y
CONFIG_LOGO_LINUX_CLUT224=y
CONFIG_LOGO_PARISC_CLUT224=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Sound
@@ -639,13 +718,9 @@ CONFIG_LOGO_PARISC_CLUT224=y
#
# USB support
#
-# CONFIG_USB is not set
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB_ARCH_HAS_OHCI=y
-
-#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
-#
+# CONFIG_USB is not set
#
# USB Gadget Support
@@ -658,23 +733,36 @@ CONFIG_USB_ARCH_HAS_OHCI=y
# CONFIG_MMC is not set
#
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
+# SN Devices
+#
+
+#
# File systems
#
CONFIG_EXT2_FS=y
# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
CONFIG_EXT3_FS=y
# CONFIG_EXT3_FS_XATTR is not set
CONFIG_JBD=y
# CONFIG_JBD_DEBUG is not set
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
# CONFIG_XFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
# CONFIG_QUOTA is not set
CONFIG_DNOTIFY=y
# CONFIG_AUTOFS_FS is not set
CONFIG_AUTOFS4_FS=y
+# CONFIG_FUSE_FS is not set
#
# CD-ROM/DVD Filesystems
@@ -697,11 +785,10 @@ CONFIG_JOLIET=y
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_SYSFS=y
-# CONFIG_DEVPTS_FS_XATTR is not set
CONFIG_TMPFS=y
-# CONFIG_TMPFS_XATTR is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
+# CONFIG_RELAYFS_FS is not set
#
# Miscellaneous filesystems
@@ -719,15 +806,19 @@ CONFIG_RAMFS=y
#
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
CONFIG_NFSD=y
CONFIG_NFSD_V3=y
+# CONFIG_NFSD_V3_ACL is not set
CONFIG_NFSD_TCP=y
CONFIG_ROOT_NFS=y
CONFIG_LOCKD=y
CONFIG_LOCKD_V4=y
CONFIG_EXPORTFS=y
+CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
-# CONFIG_SMB_FS is not set
+CONFIG_SMB_FS=y
+# CONFIG_SMB_NLS_DEFAULT is not set
# CONFIG_CIFS is not set
# CONFIG_NCP_FS is not set
# CONFIG_CODA_FS is not set
@@ -785,13 +876,19 @@ CONFIG_NLS_DEFAULT="iso8859-1"
#
# Kernel hacking
#
+# CONFIG_PRINTK_TIME is not set
CONFIG_DEBUG_KERNEL=y
CONFIG_MAGIC_SYSRQ=y
+CONFIG_LOG_BUF_SHIFT=16
+CONFIG_DETECT_SOFTLOCKUP=y
# CONFIG_SCHEDSTATS is not set
# CONFIG_DEBUG_SLAB is not set
# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
# CONFIG_DEBUG_KOBJECT is not set
# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_IOREMAP is not set
+# CONFIG_DEBUG_FS is not set
#
# Security options
@@ -815,6 +912,7 @@ CONFIG_CRYPTO=y
# CONFIG_CRYPTO_SHA256 is not set
# CONFIG_CRYPTO_SHA512 is not set
# CONFIG_CRYPTO_WP512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
# CONFIG_CRYPTO_DES is not set
# CONFIG_CRYPTO_BLOWFISH is not set
# CONFIG_CRYPTO_TWOFISH is not set
@@ -832,8 +930,13 @@ CONFIG_CRYPTO=y
# CONFIG_CRYPTO_TEST is not set
#
+# Hardware crypto devices
+#
+
+#
# Library routines
#
# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
CONFIG_CRC32=y
# CONFIG_LIBCRC32C is not set
diff --git a/arch/parisc/configs/c3000_defconfig b/arch/parisc/configs/c3000_defconfig
index 67aca6ccc9b0..9d86b6b1ebd1 100644
--- a/arch/parisc/configs/c3000_defconfig
+++ b/arch/parisc/configs/c3000_defconfig
@@ -1,12 +1,16 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.10-pa5
-# Wed Jan 5 13:26:49 2005
+# Linux kernel version: 2.6.14-rc5-pa1
+# Fri Oct 21 23:06:31 2005
#
CONFIG_PARISC=y
CONFIG_MMU=y
CONFIG_STACK_GROWSUP=y
CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
#
# Code maturity level options
@@ -15,26 +19,31 @@ CONFIG_EXPERIMENTAL=y
# CONFIG_CLEAN_COMPILE is not set
CONFIG_BROKEN=y
CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
#
# General setup
#
CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
# CONFIG_POSIX_MQUEUE is not set
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=16
CONFIG_HOTPLUG=y
CONFIG_KOBJECT_UEVENT=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
+CONFIG_INITRAMFS_SOURCE=""
CONFIG_EMBEDDED=y
CONFIG_KALLSYMS=y
CONFIG_KALLSYMS_ALL=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
@@ -44,6 +53,7 @@ CONFIG_CC_ALIGN_LABELS=0
CONFIG_CC_ALIGN_LOOPS=0
CONFIG_CC_ALIGN_JUMPS=0
# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
#
# Loadable module support
@@ -66,10 +76,19 @@ CONFIG_KMOD=y
CONFIG_PA8X00=y
CONFIG_PA20=y
CONFIG_PREFETCH=y
-# CONFIG_PARISC64 is not set
# CONFIG_64BIT is not set
# CONFIG_SMP is not set
-# CONFIG_DISCONTIGMEM is not set
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+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_PREEMPT is not set
# CONFIG_HPUX is not set
@@ -79,13 +98,10 @@ CONFIG_PREFETCH=y
# CONFIG_GSC is not set
CONFIG_PCI=y
CONFIG_PCI_LEGACY_PROC=y
-CONFIG_PCI_NAMES=y
+# CONFIG_PCI_DEBUG is not set
CONFIG_PCI_LBA=y
CONFIG_IOSAPIC=y
CONFIG_IOMMU_SBA=y
-CONFIG_SUPERIO=y
-CONFIG_CHASSIS_LCD_LED=y
-# CONFIG_PDC_CHASSIS is not set
#
# PCCARD (PCMCIA/CardBus) support
@@ -93,13 +109,17 @@ CONFIG_CHASSIS_LCD_LED=y
# CONFIG_PCCARD is not set
#
-# PC-card bridges
+# PCI Hotplug Support
#
+# CONFIG_HOTPLUG_PCI is not set
#
-# PCI Hotplug Support
+# PA-RISC specific drivers
#
-# CONFIG_HOTPLUG_PCI is not set
+CONFIG_SUPERIO=y
+CONFIG_CHASSIS_LCD_LED=y
+# CONFIG_PDC_CHASSIS is not set
+CONFIG_PDC_STABLE=y
#
# Executable file formats
@@ -108,6 +128,186 @@ CONFIG_BINFMT_ELF=y
# CONFIG_BINFMT_MISC is not set
#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+CONFIG_NET_KEY=m
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_TUNNEL is not set
+# CONFIG_INET_DIAG is not set
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+
+#
+# IP: Virtual Server Configuration
+#
+# CONFIG_IP_VS is not set
+CONFIG_IPV6=m
+# CONFIG_IPV6_PRIVACY is not set
+# CONFIG_INET6_AH is not set
+# CONFIG_INET6_ESP is not set
+CONFIG_INET6_IPCOMP=m
+CONFIG_INET6_TUNNEL=m
+CONFIG_IPV6_TUNNEL=m
+CONFIG_NETFILTER=y
+CONFIG_NETFILTER_DEBUG=y
+# CONFIG_NETFILTER_NETLINK is not set
+
+#
+# IP: Netfilter Configuration
+#
+CONFIG_IP_NF_CONNTRACK=m
+# CONFIG_IP_NF_CT_ACCT is not set
+# CONFIG_IP_NF_CONNTRACK_MARK is not set
+# CONFIG_IP_NF_CONNTRACK_EVENTS is not set
+# CONFIG_IP_NF_CT_PROTO_SCTP is not set
+CONFIG_IP_NF_FTP=m
+CONFIG_IP_NF_IRC=m
+# CONFIG_IP_NF_NETBIOS_NS is not set
+CONFIG_IP_NF_TFTP=m
+CONFIG_IP_NF_AMANDA=m
+# CONFIG_IP_NF_PPTP is not set
+CONFIG_IP_NF_QUEUE=m
+CONFIG_IP_NF_IPTABLES=m
+CONFIG_IP_NF_MATCH_LIMIT=m
+CONFIG_IP_NF_MATCH_IPRANGE=m
+CONFIG_IP_NF_MATCH_MAC=m
+CONFIG_IP_NF_MATCH_PKTTYPE=m
+CONFIG_IP_NF_MATCH_MARK=m
+CONFIG_IP_NF_MATCH_MULTIPORT=m
+CONFIG_IP_NF_MATCH_TOS=m
+CONFIG_IP_NF_MATCH_RECENT=m
+CONFIG_IP_NF_MATCH_ECN=m
+CONFIG_IP_NF_MATCH_DSCP=m
+CONFIG_IP_NF_MATCH_AH_ESP=m
+CONFIG_IP_NF_MATCH_LENGTH=m
+CONFIG_IP_NF_MATCH_TTL=m
+CONFIG_IP_NF_MATCH_TCPMSS=m
+CONFIG_IP_NF_MATCH_HELPER=m
+CONFIG_IP_NF_MATCH_STATE=m
+CONFIG_IP_NF_MATCH_CONNTRACK=m
+CONFIG_IP_NF_MATCH_OWNER=m
+# CONFIG_IP_NF_MATCH_ADDRTYPE is not set
+# CONFIG_IP_NF_MATCH_REALM is not set
+# CONFIG_IP_NF_MATCH_SCTP is not set
+# CONFIG_IP_NF_MATCH_DCCP is not set
+# CONFIG_IP_NF_MATCH_COMMENT is not set
+# CONFIG_IP_NF_MATCH_HASHLIMIT is not set
+# CONFIG_IP_NF_MATCH_STRING is not set
+CONFIG_IP_NF_FILTER=m
+CONFIG_IP_NF_TARGET_REJECT=m
+CONFIG_IP_NF_TARGET_LOG=m
+CONFIG_IP_NF_TARGET_ULOG=m
+CONFIG_IP_NF_TARGET_TCPMSS=m
+# CONFIG_IP_NF_TARGET_NFQUEUE is not set
+CONFIG_IP_NF_NAT=m
+CONFIG_IP_NF_NAT_NEEDED=y
+CONFIG_IP_NF_TARGET_MASQUERADE=m
+CONFIG_IP_NF_TARGET_REDIRECT=m
+CONFIG_IP_NF_TARGET_NETMAP=m
+CONFIG_IP_NF_TARGET_SAME=m
+CONFIG_IP_NF_NAT_SNMP_BASIC=m
+CONFIG_IP_NF_NAT_IRC=m
+CONFIG_IP_NF_NAT_FTP=m
+CONFIG_IP_NF_NAT_TFTP=m
+CONFIG_IP_NF_NAT_AMANDA=m
+CONFIG_IP_NF_MANGLE=m
+CONFIG_IP_NF_TARGET_TOS=m
+CONFIG_IP_NF_TARGET_ECN=m
+CONFIG_IP_NF_TARGET_DSCP=m
+CONFIG_IP_NF_TARGET_MARK=m
+CONFIG_IP_NF_TARGET_CLASSIFY=m
+# CONFIG_IP_NF_TARGET_TTL is not set
+# CONFIG_IP_NF_RAW is not set
+CONFIG_IP_NF_ARPTABLES=m
+CONFIG_IP_NF_ARPFILTER=m
+CONFIG_IP_NF_ARP_MANGLE=m
+
+#
+# IPv6: Netfilter Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP6_NF_QUEUE is not set
+CONFIG_IP6_NF_IPTABLES=m
+# CONFIG_IP6_NF_MATCH_LIMIT is not set
+CONFIG_IP6_NF_MATCH_MAC=m
+CONFIG_IP6_NF_MATCH_RT=m
+# CONFIG_IP6_NF_MATCH_OPTS is not set
+# CONFIG_IP6_NF_MATCH_FRAG is not set
+# CONFIG_IP6_NF_MATCH_HL is not set
+# CONFIG_IP6_NF_MATCH_MULTIPORT is not set
+CONFIG_IP6_NF_MATCH_OWNER=m
+# CONFIG_IP6_NF_MATCH_MARK is not set
+CONFIG_IP6_NF_MATCH_IPV6HEADER=m
+# CONFIG_IP6_NF_MATCH_AHESP is not set
+CONFIG_IP6_NF_MATCH_LENGTH=m
+# CONFIG_IP6_NF_MATCH_EUI64 is not set
+CONFIG_IP6_NF_FILTER=m
+CONFIG_IP6_NF_TARGET_LOG=m
+CONFIG_IP6_NF_TARGET_REJECT=m
+# CONFIG_IP6_NF_TARGET_NFQUEUE is not set
+CONFIG_IP6_NF_MANGLE=m
+# CONFIG_IP6_NF_TARGET_MARK is not set
+# CONFIG_IP6_NF_TARGET_HL is not set
+# CONFIG_IP6_NF_RAW is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP 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_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+CONFIG_NET_PKTGEN=m
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
+
+#
# Device Drivers
#
@@ -120,6 +320,11 @@ CONFIG_FW_LOADER=y
# CONFIG_DEBUG_DRIVER is not set
#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+
+#
# Memory Technology Devices (MTD)
#
# CONFIG_MTD is not set
@@ -141,14 +346,14 @@ CONFIG_FW_LOADER=y
# CONFIG_BLK_CPQ_CISS_DA is not set
# CONFIG_BLK_DEV_DAC960 is not set
CONFIG_BLK_DEV_UMEM=m
+# CONFIG_BLK_DEV_COW_COMMON is not set
CONFIG_BLK_DEV_LOOP=y
-# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+CONFIG_BLK_DEV_CRYPTOLOOP=m
# CONFIG_BLK_DEV_NBD is not set
# CONFIG_BLK_DEV_SX8 is not set
# CONFIG_BLK_DEV_UB is not set
# CONFIG_BLK_DEV_RAM is not set
CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_INITRAMFS_SOURCE=""
# CONFIG_CDROM_PKTCDVD is not set
#
@@ -158,6 +363,7 @@ CONFIG_IOSCHED_NOOP=y
CONFIG_IOSCHED_AS=y
CONFIG_IOSCHED_DEADLINE=y
CONFIG_IOSCHED_CFQ=y
+# CONFIG_ATA_OVER_ETH is not set
#
# ATA/ATAPI/MFM/RLL support
@@ -201,6 +407,7 @@ CONFIG_BLK_DEV_IDEDMA_PCI=y
# CONFIG_BLK_DEV_HPT366 is not set
# CONFIG_BLK_DEV_SC1200 is not set
# CONFIG_BLK_DEV_PIIX is not set
+# CONFIG_BLK_DEV_IT821X is not set
CONFIG_BLK_DEV_NS87415=y
# CONFIG_BLK_DEV_PDC202XX_OLD is not set
# CONFIG_BLK_DEV_PDC202XX_NEW is not set
@@ -218,6 +425,7 @@ CONFIG_BLK_DEV_IDEDMA=y
#
# SCSI device support
#
+# CONFIG_RAID_ATTRS is not set
CONFIG_SCSI=y
CONFIG_SCSI_PROC_FS=y
@@ -230,6 +438,7 @@ CONFIG_CHR_DEV_ST=y
CONFIG_BLK_DEV_SR=y
# CONFIG_BLK_DEV_SR_VENDOR 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
@@ -242,7 +451,9 @@ CONFIG_SCSI_MULTI_LUN=y
# SCSI Transport Attributes
#
CONFIG_SCSI_SPI_ATTRS=y
-CONFIG_SCSI_FC_ATTRS=m
+# CONFIG_SCSI_FC_ATTRS is not set
+CONFIG_SCSI_ISCSI_ATTRS=m
+# CONFIG_SCSI_SAS_ATTRS is not set
#
# SCSI low-level drivers
@@ -258,25 +469,26 @@ CONFIG_SCSI_FC_ATTRS=m
# CONFIG_SCSI_ADVANSYS is not set
# CONFIG_MEGARAID_NEWGEN is not set
# CONFIG_MEGARAID_LEGACY is not set
+# CONFIG_MEGARAID_SAS is not set
CONFIG_SCSI_SATA=y
# CONFIG_SCSI_SATA_AHCI is not set
# CONFIG_SCSI_SATA_SVW is not set
CONFIG_SCSI_ATA_PIIX=m
+# CONFIG_SCSI_SATA_MV is not set
# CONFIG_SCSI_SATA_NV is not set
CONFIG_SCSI_SATA_PROMISE=m
+# CONFIG_SCSI_SATA_QSTOR is not set
# CONFIG_SCSI_SATA_SX4 is not set
CONFIG_SCSI_SATA_SIL=m
# CONFIG_SCSI_SATA_SIS is not set
# CONFIG_SCSI_SATA_ULI is not set
CONFIG_SCSI_SATA_VIA=m
# CONFIG_SCSI_SATA_VITESSE is not set
-# CONFIG_SCSI_BUSLOGIC is not set
+CONFIG_SCSI_SATA_INTEL_COMBINED=y
# CONFIG_SCSI_CPQFCTS is not set
# CONFIG_SCSI_DMX3191D is not set
-# CONFIG_SCSI_EATA is not set
# CONFIG_SCSI_EATA_PIO is not set
# CONFIG_SCSI_FUTURE_DOMAIN is not set
-# CONFIG_SCSI_GDTH is not set
# CONFIG_SCSI_IPS is not set
# CONFIG_SCSI_INITIO is not set
# CONFIG_SCSI_INIA100 is not set
@@ -286,20 +498,17 @@ CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
# CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set
# CONFIG_SCSI_IPR is not set
-# CONFIG_SCSI_PCI2000 is not set
-# CONFIG_SCSI_PCI2220I is not set
# CONFIG_SCSI_QLOGIC_ISP is not set
-CONFIG_SCSI_QLOGIC_FC=m
-# CONFIG_SCSI_QLOGIC_FC_FIRMWARE is not set
-CONFIG_SCSI_QLOGIC_1280=m
-# CONFIG_SCSI_QLOGIC_1280_1040 is not set
+# CONFIG_SCSI_QLOGIC_FC is not set
+# CONFIG_SCSI_QLOGIC_1280 is not set
CONFIG_SCSI_QLA2XXX=y
# CONFIG_SCSI_QLA21XX is not set
# CONFIG_SCSI_QLA22XX is not set
-CONFIG_SCSI_QLA2300=m
-CONFIG_SCSI_QLA2322=m
-CONFIG_SCSI_QLA6312=m
-CONFIG_SCSI_QLA6322=m
+# CONFIG_SCSI_QLA2300 is not set
+# CONFIG_SCSI_QLA2322 is not set
+# CONFIG_SCSI_QLA6312 is not set
+# CONFIG_SCSI_QLA24XX is not set
+# CONFIG_SCSI_LPFC is not set
# CONFIG_SCSI_DC395x is not set
# CONFIG_SCSI_DC390T is not set
# CONFIG_SCSI_NSP32 is not set
@@ -316,19 +525,24 @@ CONFIG_MD_RAID1=y
# CONFIG_MD_RAID10 is not set
# CONFIG_MD_RAID5 is not set
# CONFIG_MD_RAID6 is not set
-CONFIG_MD_MULTIPATH=y
+# CONFIG_MD_MULTIPATH is not set
# CONFIG_MD_FAULTY is not set
-CONFIG_BLK_DEV_DM=y
-# CONFIG_DM_CRYPT is not set
-# CONFIG_DM_SNAPSHOT is not set
-# CONFIG_DM_MIRROR is not set
-# CONFIG_DM_ZERO is not set
+CONFIG_BLK_DEV_DM=m
+CONFIG_DM_CRYPT=m
+CONFIG_DM_SNAPSHOT=m
+CONFIG_DM_MIRROR=m
+CONFIG_DM_ZERO=m
+CONFIG_DM_MULTIPATH=m
+# CONFIG_DM_MULTIPATH_EMC is not set
#
# Fusion MPT device support
#
-CONFIG_FUSION=m
-CONFIG_FUSION_MAX_SGE=40
+CONFIG_FUSION=y
+CONFIG_FUSION_SPI=m
+# CONFIG_FUSION_FC is not set
+# CONFIG_FUSION_SAS is not set
+CONFIG_FUSION_MAX_SGE=128
CONFIG_FUSION_CTL=m
#
@@ -342,151 +556,13 @@ CONFIG_FUSION_CTL=m
# CONFIG_I2O is not set
#
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
-CONFIG_NETLINK_DEV=y
-CONFIG_UNIX=y
-CONFIG_NET_KEY=m
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-# CONFIG_IP_ADVANCED_ROUTER is not set
-CONFIG_IP_PNP=y
-# CONFIG_IP_PNP_DHCP is not set
-CONFIG_IP_PNP_BOOTP=y
-# CONFIG_IP_PNP_RARP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_IP_MROUTE is not set
-# CONFIG_ARPD is not set
-# CONFIG_SYN_COOKIES is not set
-CONFIG_INET_AH=m
-CONFIG_INET_ESP=m
-# CONFIG_INET_IPCOMP is not set
-# CONFIG_INET_TUNNEL is not set
-CONFIG_IP_TCPDIAG=y
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-
-#
-# IP: Virtual Server Configuration
-#
-# CONFIG_IP_VS is not set
-# CONFIG_IPV6 is not set
-CONFIG_NETFILTER=y
-CONFIG_NETFILTER_DEBUG=y
-
-#
-# IP: Netfilter Configuration
-#
-CONFIG_IP_NF_CONNTRACK=m
-# CONFIG_IP_NF_CT_ACCT is not set
-# CONFIG_IP_NF_CONNTRACK_MARK is not set
-# CONFIG_IP_NF_CT_PROTO_SCTP is not set
-CONFIG_IP_NF_FTP=m
-CONFIG_IP_NF_IRC=m
-CONFIG_IP_NF_TFTP=m
-CONFIG_IP_NF_AMANDA=m
-CONFIG_IP_NF_QUEUE=m
-CONFIG_IP_NF_IPTABLES=m
-CONFIG_IP_NF_MATCH_LIMIT=m
-CONFIG_IP_NF_MATCH_IPRANGE=m
-CONFIG_IP_NF_MATCH_MAC=m
-CONFIG_IP_NF_MATCH_PKTTYPE=m
-CONFIG_IP_NF_MATCH_MARK=m
-CONFIG_IP_NF_MATCH_MULTIPORT=m
-CONFIG_IP_NF_MATCH_TOS=m
-CONFIG_IP_NF_MATCH_RECENT=m
-CONFIG_IP_NF_MATCH_ECN=m
-CONFIG_IP_NF_MATCH_DSCP=m
-CONFIG_IP_NF_MATCH_AH_ESP=m
-CONFIG_IP_NF_MATCH_LENGTH=m
-CONFIG_IP_NF_MATCH_TTL=m
-CONFIG_IP_NF_MATCH_TCPMSS=m
-CONFIG_IP_NF_MATCH_HELPER=m
-CONFIG_IP_NF_MATCH_STATE=m
-CONFIG_IP_NF_MATCH_CONNTRACK=m
-CONFIG_IP_NF_MATCH_OWNER=m
-# CONFIG_IP_NF_MATCH_ADDRTYPE is not set
-# CONFIG_IP_NF_MATCH_REALM is not set
-# CONFIG_IP_NF_MATCH_SCTP is not set
-# CONFIG_IP_NF_MATCH_COMMENT is not set
-# CONFIG_IP_NF_MATCH_HASHLIMIT is not set
-CONFIG_IP_NF_FILTER=m
-CONFIG_IP_NF_TARGET_REJECT=m
-CONFIG_IP_NF_TARGET_LOG=m
-CONFIG_IP_NF_TARGET_ULOG=m
-CONFIG_IP_NF_TARGET_TCPMSS=m
-CONFIG_IP_NF_NAT=m
-CONFIG_IP_NF_NAT_NEEDED=y
-CONFIG_IP_NF_TARGET_MASQUERADE=m
-CONFIG_IP_NF_TARGET_REDIRECT=m
-CONFIG_IP_NF_TARGET_NETMAP=m
-CONFIG_IP_NF_TARGET_SAME=m
-CONFIG_IP_NF_NAT_SNMP_BASIC=m
-CONFIG_IP_NF_NAT_IRC=m
-CONFIG_IP_NF_NAT_FTP=m
-CONFIG_IP_NF_NAT_TFTP=m
-CONFIG_IP_NF_NAT_AMANDA=m
-CONFIG_IP_NF_MANGLE=m
-CONFIG_IP_NF_TARGET_TOS=m
-CONFIG_IP_NF_TARGET_ECN=m
-CONFIG_IP_NF_TARGET_DSCP=m
-CONFIG_IP_NF_TARGET_MARK=m
-CONFIG_IP_NF_TARGET_CLASSIFY=m
-# CONFIG_IP_NF_RAW is not set
-CONFIG_IP_NF_ARPTABLES=m
-CONFIG_IP_NF_ARPFILTER=m
-CONFIG_IP_NF_ARP_MANGLE=m
-CONFIG_IP_NF_COMPAT_IPCHAINS=m
-CONFIG_IP_NF_COMPAT_IPFWADM=m
-CONFIG_XFRM=y
-CONFIG_XFRM_USER=m
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP 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_LLC=m
-CONFIG_LLC2=m
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
-
-#
-# Network testing
+# Network device support
#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
CONFIG_NETDEVICES=y
CONFIG_DUMMY=m
CONFIG_BONDING=m
# CONFIG_EQUALIZER is not set
CONFIG_TUN=m
-# CONFIG_ETHERTAP is not set
#
# ARCnet devices
@@ -494,12 +570,18 @@ CONFIG_TUN=m
# CONFIG_ARCNET is not set
#
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
+#
# Ethernet (10 or 100Mbit)
#
CONFIG_NET_ETHERNET=y
CONFIG_MII=m
-CONFIG_HAPPYMEAL=m
+# CONFIG_HAPPYMEAL is not set
# CONFIG_SUNGEM is not set
+# CONFIG_CASSINI is not set
# CONFIG_NET_VENDOR_3COM is not set
#
@@ -514,28 +596,22 @@ CONFIG_TULIP_MMIO=y
# CONFIG_DE4X5 is not set
# CONFIG_WINBOND_840 is not set
# CONFIG_DM9102 is not set
+# CONFIG_ULI526X is not set
# CONFIG_HP100 is not set
CONFIG_NET_PCI=y
-CONFIG_PCNET32=m
+# CONFIG_PCNET32 is not set
# CONFIG_AMD8111_ETH is not set
-CONFIG_ADAPTEC_STARFIRE=m
-# CONFIG_ADAPTEC_STARFIRE_NAPI is not set
-CONFIG_B44=m
+# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_B44 is not set
# CONFIG_FORCEDETH is not set
# CONFIG_DGRS is not set
-CONFIG_EEPRO100=m
-# CONFIG_EEPRO100_PIO is not set
+# CONFIG_EEPRO100 is not set
CONFIG_E100=m
-# CONFIG_E100_NAPI is not set
# CONFIG_FEALNX is not set
-CONFIG_NATSEMI=m
+# CONFIG_NATSEMI is not set
# CONFIG_NE2K_PCI is not set
# CONFIG_8139CP is not set
-CONFIG_8139TOO=m
-# CONFIG_8139TOO_PIO is not set
-# CONFIG_8139TOO_TUNE_TWISTER is not set
-# CONFIG_8139TOO_8129 is not set
-# CONFIG_8139_OLD_RX_RESET is not set
+# CONFIG_8139TOO is not set
# CONFIG_SIS900 is not set
# CONFIG_EPIC100 is not set
# CONFIG_SUNDANCE is not set
@@ -554,15 +630,18 @@ CONFIG_E1000=m
# CONFIG_HAMACHI is not set
# CONFIG_YELLOWFIN is not set
# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
# CONFIG_SK98LIN is not set
# CONFIG_VIA_VELOCITY is not set
CONFIG_TIGON3=m
+# CONFIG_BNX2 is not set
#
# Ethernet (10000 Mbit)
#
-CONFIG_IXGB=y
-CONFIG_IXGB_NAPI=y
+# CONFIG_CHELSIO_T1 is not set
+# CONFIG_IXGB is not set
# CONFIG_S2IO is not set
#
@@ -593,6 +672,8 @@ CONFIG_PPPOE=m
# CONFIG_NET_FC is not set
# CONFIG_SHAPER is not set
# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
#
# ISDN subsystem
@@ -622,16 +703,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=1200
# CONFIG_INPUT_EVBUG is not set
#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=m
-CONFIG_SERIO_SERPORT=m
-# CONFIG_SERIO_PCIPS2 is not set
-# CONFIG_SERIO_RAW is not set
-
-#
# Input Device Drivers
#
CONFIG_INPUT_KEYBOARD=y
@@ -649,6 +720,16 @@ CONFIG_INPUT_MOUSE=y
# CONFIG_INPUT_MISC is not set
#
+# Hardware I/O ports
+#
+CONFIG_SERIO=m
+CONFIG_SERIO_SERPORT=m
+# CONFIG_SERIO_PCIPS2 is not set
+CONFIG_SERIO_LIBPS2=m
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+
+#
# Character devices
#
CONFIG_VT=y
@@ -666,7 +747,6 @@ CONFIG_SERIAL_8250_EXTENDED=y
CONFIG_SERIAL_8250_MANY_PORTS=y
CONFIG_SERIAL_8250_SHARE_IRQ=y
# CONFIG_SERIAL_8250_DETECT_IRQ is not set
-# CONFIG_SERIAL_8250_MULTIPORT is not set
# CONFIG_SERIAL_8250_RSA is not set
#
@@ -676,6 +756,7 @@ CONFIG_SERIAL_8250_SHARE_IRQ=y
# CONFIG_PDC_CONSOLE is not set
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
CONFIG_UNIX98_PTYS=y
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
@@ -698,12 +779,16 @@ CONFIG_GEN_RTC_X=y
#
# Ftape, the floppy tape device driver
#
-# CONFIG_AGP is not set
# CONFIG_DRM is not set
CONFIG_RAW_DRIVER=y
CONFIG_MAX_RAW_DEVS=256
#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+
+#
# I2C support
#
# CONFIG_I2C is not set
@@ -714,10 +799,20 @@ CONFIG_MAX_RAW_DEVS=256
# CONFIG_W1 is not set
#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
+#
# Misc devices
#
#
+# Multimedia Capabilities Port drivers
+#
+
+#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
@@ -731,6 +826,11 @@ CONFIG_MAX_RAW_DEVS=256
# Graphics support
#
CONFIG_FB=y
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+CONFIG_FB_SOFT_CURSOR=y
+# CONFIG_FB_MACMODES is not set
# CONFIG_FB_MODE_HELPERS is not set
# CONFIG_FB_TILEBLITTING is not set
# CONFIG_FB_CIRRUS is not set
@@ -739,6 +839,7 @@ CONFIG_FB=y
# CONFIG_FB_ASILIANT is not set
# CONFIG_FB_IMSTT is not set
CONFIG_FB_STI=y
+# CONFIG_FB_NVIDIA is not set
# CONFIG_FB_RIVA is not set
# CONFIG_FB_MATROX is not set
# CONFIG_FB_RADEON_OLD is not set
@@ -751,18 +852,20 @@ CONFIG_FB_STI=y
# CONFIG_FB_KYRO is not set
# CONFIG_FB_3DFX is not set
# CONFIG_FB_VOODOO1 is not set
+# CONFIG_FB_CYBLA is not set
# CONFIG_FB_TRIDENT is not set
# CONFIG_FB_PM3 is not set
+# CONFIG_FB_S1D13XXX is not set
# CONFIG_FB_VIRTUAL is not set
#
# Console display driver support
#
-CONFIG_STI_CONSOLE=y
+CONFIG_DUMMY_CONSOLE=y
CONFIG_DUMMY_CONSOLE_COLUMNS=160
CONFIG_DUMMY_CONSOLE_ROWS=64
-CONFIG_DUMMY_CONSOLE=y
CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_STI_CONSOLE=y
# CONFIG_FONTS is not set
CONFIG_FONT_8x8=y
CONFIG_FONT_8x16=y
@@ -775,6 +878,7 @@ CONFIG_LOGO=y
# CONFIG_LOGO_LINUX_VGA16 is not set
# CONFIG_LOGO_LINUX_CLUT224 is not set
CONFIG_LOGO_PARISC_CLUT224=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Sound
@@ -784,7 +888,78 @@ CONFIG_SOUND=y
#
# Advanced Linux Sound Architecture
#
-# CONFIG_SND is not set
+CONFIG_SND=y
+CONFIG_SND_TIMER=y
+CONFIG_SND_PCM=y
+CONFIG_SND_SEQUENCER=y
+# CONFIG_SND_SEQ_DUMMY is not set
+CONFIG_SND_OSSEMUL=y
+CONFIG_SND_MIXER_OSS=y
+CONFIG_SND_PCM_OSS=y
+CONFIG_SND_SEQUENCER_OSS=y
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+
+#
+# Generic devices
+#
+# CONFIG_SND_DUMMY is not set
+# CONFIG_SND_VIRMIDI is not set
+# CONFIG_SND_MTPAV is not set
+# CONFIG_SND_SERIAL_U16550 is not set
+# CONFIG_SND_MPU401 is not set
+CONFIG_SND_AC97_CODEC=y
+CONFIG_SND_AC97_BUS=y
+
+#
+# PCI devices
+#
+# CONFIG_SND_ALI5451 is not set
+# CONFIG_SND_ATIIXP is not set
+# CONFIG_SND_ATIIXP_MODEM is not set
+# CONFIG_SND_AU8810 is not set
+# CONFIG_SND_AU8820 is not set
+# CONFIG_SND_AU8830 is not set
+# CONFIG_SND_AZT3328 is not set
+# CONFIG_SND_BT87X is not set
+# CONFIG_SND_CS46XX is not set
+# CONFIG_SND_CS4281 is not set
+# CONFIG_SND_EMU10K1 is not set
+# CONFIG_SND_EMU10K1X is not set
+# CONFIG_SND_CA0106 is not set
+# CONFIG_SND_KORG1212 is not set
+# CONFIG_SND_MIXART is not set
+# CONFIG_SND_NM256 is not set
+# CONFIG_SND_RME32 is not set
+# CONFIG_SND_RME96 is not set
+# CONFIG_SND_RME9652 is not set
+# CONFIG_SND_HDSP is not set
+# CONFIG_SND_HDSPM is not set
+# CONFIG_SND_TRIDENT is not set
+# CONFIG_SND_YMFPCI is not set
+CONFIG_SND_AD1889=y
+# CONFIG_SND_AD1889_OPL3 is not set
+# CONFIG_SND_CMIPCI is not set
+# CONFIG_SND_ENS1370 is not set
+# CONFIG_SND_ENS1371 is not set
+# CONFIG_SND_ES1938 is not set
+# CONFIG_SND_ES1968 is not set
+# CONFIG_SND_MAESTRO3 is not set
+# CONFIG_SND_FM801 is not set
+# CONFIG_SND_ICE1712 is not set
+# CONFIG_SND_ICE1724 is not set
+# CONFIG_SND_INTEL8X0 is not set
+# CONFIG_SND_INTEL8X0M is not set
+# CONFIG_SND_SONICVIBES is not set
+# CONFIG_SND_VIA82XX is not set
+# CONFIG_SND_VIA82XX_MODEM is not set
+# CONFIG_SND_VX222 is not set
+# CONFIG_SND_HDA_INTEL is not set
+
+#
+# USB devices
+#
+# CONFIG_SND_USB_AUDIO is not set
#
# Open Sound System
@@ -794,6 +969,8 @@ CONFIG_SOUND=y
#
# USB support
#
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
CONFIG_USB=y
CONFIG_USB_DEBUG=y
@@ -804,23 +981,23 @@ CONFIG_USB_DEVICEFS=y
# CONFIG_USB_BANDWIDTH is not set
# CONFIG_USB_DYNAMIC_MINORS is not set
# CONFIG_USB_OTG is not set
-CONFIG_USB_ARCH_HAS_HCD=y
-CONFIG_USB_ARCH_HAS_OHCI=y
#
# USB Host Controller Drivers
#
# CONFIG_USB_EHCI_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
CONFIG_USB_OHCI_HCD=y
+# CONFIG_USB_OHCI_BIG_ENDIAN is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
# CONFIG_USB_UHCI_HCD is not set
# CONFIG_USB_SL811_HCD is not set
#
# USB Device Class drivers
#
-# CONFIG_USB_AUDIO is not set
+# CONFIG_OBSOLETE_OSS_USB_DRIVER is not set
# CONFIG_USB_BLUETOOTH_TTY is not set
-# CONFIG_USB_MIDI is not set
# CONFIG_USB_ACM is not set
CONFIG_USB_PRINTER=m
@@ -829,12 +1006,11 @@ CONFIG_USB_PRINTER=m
#
CONFIG_USB_STORAGE=m
# CONFIG_USB_STORAGE_DEBUG is not set
-# CONFIG_USB_STORAGE_RW_DETECT is not set
-CONFIG_USB_STORAGE_DATAFAB=y
-CONFIG_USB_STORAGE_FREECOM=y
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
# CONFIG_USB_STORAGE_ISD200 is not set
CONFIG_USB_STORAGE_DPCM=y
-CONFIG_USB_STORAGE_HP8200e=y
+CONFIG_USB_STORAGE_USBAT=y
CONFIG_USB_STORAGE_SDDR09=y
CONFIG_USB_STORAGE_SDDR55=y
CONFIG_USB_STORAGE_JUMPSHOT=y
@@ -846,21 +1022,25 @@ CONFIG_USB_HID=y
CONFIG_USB_HIDINPUT=y
# CONFIG_HID_FF is not set
CONFIG_USB_HIDDEV=y
-CONFIG_USB_AIPTEK=m
-CONFIG_USB_WACOM=m
-CONFIG_USB_KBTAB=m
+# CONFIG_USB_AIPTEK is not set
+# CONFIG_USB_WACOM is not set
+# CONFIG_USB_ACECAD is not set
+# CONFIG_USB_KBTAB is not set
# CONFIG_USB_POWERMATE is not set
# CONFIG_USB_MTOUCH is not set
+# CONFIG_USB_ITMTOUCH is not set
# CONFIG_USB_EGALAX is not set
+# CONFIG_USB_YEALINK is not set
# CONFIG_USB_XPAD is not set
# CONFIG_USB_ATI_REMOTE is not set
+# CONFIG_USB_KEYSPAN_REMOTE is not set
+# CONFIG_USB_APPLETOUCH is not set
#
# USB Imaging devices
#
CONFIG_USB_MDC800=m
CONFIG_USB_MICROTEK=m
-CONFIG_USB_HPUSBSCSI=m
#
# USB Multimedia devices
@@ -879,6 +1059,7 @@ CONFIG_USB_HPUSBSCSI=m
# CONFIG_USB_PEGASUS is not set
# CONFIG_USB_RTL8150 is not set
# CONFIG_USB_USBNET is not set
+# CONFIG_USB_MON is not set
#
# USB port drivers
@@ -894,7 +1075,6 @@ CONFIG_USB_HPUSBSCSI=m
#
# CONFIG_USB_EMI62 is not set
# CONFIG_USB_EMI26 is not set
-# CONFIG_USB_TIGL is not set
# CONFIG_USB_AUERSWALD is not set
# CONFIG_USB_RIO500 is not set
CONFIG_USB_LEGOTOWER=m
@@ -903,10 +1083,12 @@ CONFIG_USB_LEGOTOWER=m
# CONFIG_USB_CYTHERM is not set
# CONFIG_USB_PHIDGETKIT is not set
# CONFIG_USB_PHIDGETSERVO is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_LD is not set
# CONFIG_USB_TEST is not set
#
-# USB ATM/DSL drivers
+# USB DSL modem support
#
#
@@ -920,27 +1102,41 @@ CONFIG_USB_LEGOTOWER=m
# CONFIG_MMC is not set
#
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
+# SN Devices
+#
+
+#
# File systems
#
CONFIG_EXT2_FS=y
# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
CONFIG_EXT3_FS=y
# CONFIG_EXT3_FS_XATTR is not set
CONFIG_JBD=y
# CONFIG_JBD_DEBUG is not set
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
CONFIG_XFS_FS=m
-# CONFIG_XFS_RT is not set
+CONFIG_XFS_EXPORT=y
# CONFIG_XFS_QUOTA is not set
# CONFIG_XFS_SECURITY is not set
# CONFIG_XFS_POSIX_ACL is not set
+# CONFIG_XFS_RT is not set
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
# CONFIG_QUOTA is not set
CONFIG_DNOTIFY=y
# CONFIG_AUTOFS_FS is not set
CONFIG_AUTOFS4_FS=y
+# CONFIG_FUSE_FS is not set
#
# CD-ROM/DVD Filesystems
@@ -966,13 +1162,11 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
-# CONFIG_DEVPTS_FS_XATTR is not set
CONFIG_TMPFS=y
-# CONFIG_TMPFS_XATTR is not set
# CONFIG_HUGETLBFS is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
+# CONFIG_RELAYFS_FS is not set
#
# Miscellaneous filesystems
@@ -996,16 +1190,19 @@ CONFIG_RAMFS=y
#
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
# CONFIG_NFS_V4 is not set
# CONFIG_NFS_DIRECTIO is not set
CONFIG_NFSD=y
CONFIG_NFSD_V3=y
+# CONFIG_NFSD_V3_ACL is not set
# CONFIG_NFSD_V4 is not set
# CONFIG_NFSD_TCP is not set
CONFIG_ROOT_NFS=y
CONFIG_LOCKD=y
CONFIG_LOCKD_V4=y
CONFIG_EXPORTFS=y
+CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
@@ -1014,6 +1211,7 @@ CONFIG_SUNRPC=y
# CONFIG_NCP_FS is not set
# CONFIG_CODA_FS is not set
# CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
#
# Partition Types
@@ -1074,13 +1272,19 @@ CONFIG_OPROFILE=m
#
# Kernel hacking
#
+# CONFIG_PRINTK_TIME is not set
CONFIG_DEBUG_KERNEL=y
CONFIG_MAGIC_SYSRQ=y
+CONFIG_LOG_BUF_SHIFT=16
+CONFIG_DETECT_SOFTLOCKUP=y
# CONFIG_SCHEDSTATS is not set
# CONFIG_DEBUG_SLAB is not set
# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
# CONFIG_DEBUG_KOBJECT is not set
# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_IOREMAP is not set
+# CONFIG_DEBUG_FS is not set
#
# Security options
@@ -1092,21 +1296,22 @@ CONFIG_MAGIC_SYSRQ=y
# Cryptographic options
#
CONFIG_CRYPTO=y
-CONFIG_CRYPTO_HMAC=y
+# CONFIG_CRYPTO_HMAC is not set
CONFIG_CRYPTO_NULL=m
-CONFIG_CRYPTO_MD4=m
+# CONFIG_CRYPTO_MD4 is not set
CONFIG_CRYPTO_MD5=m
-CONFIG_CRYPTO_SHA1=m
-CONFIG_CRYPTO_SHA256=m
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
# CONFIG_CRYPTO_SHA512 is not set
# CONFIG_CRYPTO_WP512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
CONFIG_CRYPTO_DES=m
CONFIG_CRYPTO_BLOWFISH=m
-CONFIG_CRYPTO_TWOFISH=m
-CONFIG_CRYPTO_SERPENT=m
-CONFIG_CRYPTO_AES=m
-CONFIG_CRYPTO_CAST5=m
-CONFIG_CRYPTO_CAST6=m
+# CONFIG_CRYPTO_TWOFISH is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
# CONFIG_CRYPTO_TEA is not set
# CONFIG_CRYPTO_ARC4 is not set
# CONFIG_CRYPTO_KHAZAD is not set
@@ -1117,9 +1322,14 @@ CONFIG_CRYPTO_CRC32C=m
CONFIG_CRYPTO_TEST=m
#
+# Hardware crypto devices
+#
+
+#
# Library routines
#
CONFIG_CRC_CCITT=m
+# CONFIG_CRC16 is not set
CONFIG_CRC32=y
CONFIG_LIBCRC32C=m
CONFIG_ZLIB_INFLATE=m
diff --git a/arch/parisc/defconfig b/arch/parisc/defconfig
index fdae21c503d7..f38a4620d24f 100644
--- a/arch/parisc/defconfig
+++ b/arch/parisc/defconfig
@@ -1,38 +1,56 @@
#
# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.14-rc5-pa1
+# Fri Oct 21 23:01:33 2005
#
CONFIG_PARISC=y
CONFIG_MMU=y
CONFIG_STACK_GROWSUP=y
CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
#
# Code maturity level options
#
CONFIG_EXPERIMENTAL=y
CONFIG_CLEAN_COMPILE=y
-CONFIG_STANDALONE=y
CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
#
# General setup
#
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
-CONFIG_LOG_BUF_SHIFT=15
+# CONFIG_AUDIT is not set
# CONFIG_HOTPLUG is not set
+CONFIG_KOBJECT_UEVENT=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
+CONFIG_INITRAMFS_SOURCE=""
# CONFIG_EMBEDDED is not set
CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
#
# Loadable module support
@@ -45,10 +63,21 @@ CONFIG_IOSCHED_DEADLINE=y
CONFIG_PA7000=y
# CONFIG_PA7100LC is not set
# CONFIG_PA7200 is not set
+# CONFIG_PA7300LC is not set
# CONFIG_PA8X00 is not set
CONFIG_PA11=y
-# CONFIG_64BIT is not set
# CONFIG_SMP is not set
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+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_PREEMPT is not set
# CONFIG_HPUX is not set
@@ -65,14 +94,29 @@ CONFIG_EISA_NAMES=y
# CONFIG_ISA is not set
CONFIG_PCI=y
CONFIG_PCI_LEGACY_PROC=y
-CONFIG_PCI_NAMES=y
+# CONFIG_PCI_DEBUG is not set
CONFIG_GSC_DINO=y
CONFIG_PCI_LBA=y
CONFIG_IOSAPIC=y
CONFIG_IOMMU_SBA=y
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PCI Hotplug Support
+#
+# CONFIG_HOTPLUG_PCI is not set
+
+#
+# PA-RISC specific drivers
+#
CONFIG_SUPERIO=y
CONFIG_CHASSIS_LCD_LED=y
CONFIG_PDC_CHASSIS=y
+CONFIG_PDC_STABLE=y
#
# Executable file formats
@@ -81,15 +125,97 @@ CONFIG_BINFMT_ELF=y
# CONFIG_BINFMT_MISC is not set
#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_TUNNEL is not set
+# CONFIG_INET_DIAG is not set
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+CONFIG_IPV6=y
+# CONFIG_IPV6_PRIVACY is not set
+# CONFIG_INET6_AH is not set
+# CONFIG_INET6_ESP is not set
+# CONFIG_INET6_IPCOMP is not set
+# CONFIG_INET6_TUNNEL is not set
+# CONFIG_IPV6_TUNNEL is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# 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_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
+
+#
# Device Drivers
#
#
# Generic Driver Options
#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
# CONFIG_DEBUG_DRIVER is not set
#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+
+#
# Memory Technology Devices (MTD)
#
# CONFIG_MTD is not set
@@ -99,12 +225,10 @@ CONFIG_BINFMT_ELF=y
#
CONFIG_PARPORT=y
CONFIG_PARPORT_PC=y
-CONFIG_PARPORT_PC_CML1=y
# CONFIG_PARPORT_SERIAL is not set
# CONFIG_PARPORT_PC_FIFO is not set
# CONFIG_PARPORT_PC_SUPERIO is not set
CONFIG_PARPORT_GSC=y
-# CONFIG_PARPORT_OTHER is not set
# CONFIG_PARPORT_1284 is not set
#
@@ -114,18 +238,31 @@ CONFIG_PARPORT_GSC=y
#
# Block devices
#
-# CONFIG_BLK_DEV_FD is not set
# CONFIG_PARIDE is not set
# CONFIG_BLK_CPQ_DA is not set
# CONFIG_BLK_CPQ_CISS_DA is not set
# CONFIG_BLK_DEV_DAC960 is not set
# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_CRYPTOLOOP=y
# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_SX8 is not set
+# CONFIG_BLK_DEV_UB is not set
CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=4096
CONFIG_BLK_DEV_INITRD=y
+# CONFIG_CDROM_PKTCDVD is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_ATA_OVER_ETH is not set
#
# ATA/ATAPI/MFM/RLL support
@@ -135,6 +272,7 @@ CONFIG_BLK_DEV_INITRD=y
#
# SCSI device support
#
+# CONFIG_RAID_ATTRS is not set
CONFIG_SCSI=y
CONFIG_SCSI_PROC_FS=y
@@ -147,53 +285,59 @@ CONFIG_CHR_DEV_ST=y
CONFIG_BLK_DEV_SR=y
# CONFIG_BLK_DEV_SR_VENDOR 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_REPORT_LUNS is not set
# CONFIG_SCSI_CONSTANTS is not set
# CONFIG_SCSI_LOGGING is not set
#
+# SCSI Transport Attributes
+#
+CONFIG_SCSI_SPI_ATTRS=y
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_ATTRS is not set
+
+#
# SCSI low-level drivers
#
# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_3W_9XXX is not set
# CONFIG_SCSI_ACARD is not set
# CONFIG_SCSI_AHA1740 is not set
# CONFIG_SCSI_AACRAID is not set
# CONFIG_SCSI_AIC7XXX is not set
# CONFIG_SCSI_AIC7XXX_OLD is not set
# CONFIG_SCSI_AIC79XX is not set
-# CONFIG_SCSI_ADVANSYS is not set
-# CONFIG_SCSI_MEGARAID is not set
+# CONFIG_SCSI_DPT_I2O is not set
+# CONFIG_MEGARAID_NEWGEN is not set
+# CONFIG_MEGARAID_LEGACY is not set
+# CONFIG_MEGARAID_SAS is not set
# CONFIG_SCSI_SATA is not set
-# CONFIG_SCSI_BUSLOGIC is not set
-# CONFIG_SCSI_CPQFCTS is not set
# CONFIG_SCSI_DMX3191D is not set
-# CONFIG_SCSI_EATA is not set
-# CONFIG_SCSI_EATA_PIO is not set
# CONFIG_SCSI_FUTURE_DOMAIN is not set
-# CONFIG_SCSI_GDTH is not set
# CONFIG_SCSI_IPS is not set
+# CONFIG_SCSI_INITIO is not set
# CONFIG_SCSI_INIA100 is not set
# CONFIG_SCSI_PPA is not set
# CONFIG_SCSI_IMM is not set
CONFIG_SCSI_LASI700=y
-CONFIG_53C700_MEM_MAPPED=y
CONFIG_53C700_LE_ON_BE=y
CONFIG_SCSI_SYM53C8XX_2=y
CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1
CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
# CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set
+# CONFIG_SCSI_IPR is not set
CONFIG_SCSI_ZALON=y
CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS=8
CONFIG_SCSI_NCR53C8XX_MAX_TAGS=32
CONFIG_SCSI_NCR53C8XX_SYNC=20
# CONFIG_SCSI_NCR53C8XX_PROFILE is not set
-# CONFIG_SCSI_QLOGIC_ISP is not set
# CONFIG_SCSI_QLOGIC_FC is not set
# CONFIG_SCSI_QLOGIC_1280 is not set
CONFIG_SCSI_QLA2XXX=y
@@ -202,7 +346,8 @@ CONFIG_SCSI_QLA2XXX=y
# CONFIG_SCSI_QLA2300 is not set
# CONFIG_SCSI_QLA2322 is not set
# CONFIG_SCSI_QLA6312 is not set
-# CONFIG_SCSI_QLA6322 is not set
+# CONFIG_SCSI_QLA24XX is not set
+# CONFIG_SCSI_LPFC is not set
# CONFIG_SCSI_SIM710 is not set
# CONFIG_SCSI_DC395x is not set
# CONFIG_SCSI_DC390T is not set
@@ -217,15 +362,20 @@ CONFIG_BLK_DEV_MD=y
CONFIG_MD_LINEAR=y
CONFIG_MD_RAID0=y
CONFIG_MD_RAID1=y
+# CONFIG_MD_RAID10 is not set
CONFIG_MD_RAID5=y
# CONFIG_MD_RAID6 is not set
# CONFIG_MD_MULTIPATH is not set
+# CONFIG_MD_FAULTY is not set
# CONFIG_BLK_DEV_DM is not set
#
# Fusion MPT device support
#
# CONFIG_FUSION is not set
+# CONFIG_FUSION_SPI is not set
+# CONFIG_FUSION_FC is not set
+# CONFIG_FUSION_SAS is not set
#
# IEEE 1394 (FireWire) support
@@ -238,80 +388,23 @@ CONFIG_MD_RAID5=y
# CONFIG_I2O is not set
#
-# Macintosh device drivers
-#
-
-#
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
-CONFIG_NETLINK_DEV=y
-CONFIG_UNIX=y
-# CONFIG_NET_KEY is not set
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-# CONFIG_IP_ADVANCED_ROUTER is not set
-CONFIG_IP_PNP=y
-# CONFIG_IP_PNP_DHCP is not set
-CONFIG_IP_PNP_BOOTP=y
-# CONFIG_IP_PNP_RARP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_IP_MROUTE is not set
-# CONFIG_ARPD is not set
-# CONFIG_INET_ECN 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_IPV6 is not set
-# CONFIG_DECNET is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_NETFILTER is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-CONFIG_IPV6_SCTP__=y
-# CONFIG_IP_SCTP is not set
-# CONFIG_ATM is not set
-# CONFIG_VLAN_8021Q 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_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_HW_FLOWCONTROL is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-
-#
-# Network testing
+# Network device support
#
-# CONFIG_NET_PKTGEN is not set
CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
#
# ARCnet devices
#
# CONFIG_ARCNET is not set
-# CONFIG_DUMMY is not set
-# CONFIG_BONDING is not set
-# CONFIG_EQUALIZER is not set
-# CONFIG_TUN is not set
-# CONFIG_ETHERTAP is not set
+
+#
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
#
# Ethernet (10 or 100Mbit)
@@ -321,6 +414,7 @@ CONFIG_NET_ETHERNET=y
CONFIG_LASI_82596=y
# CONFIG_HAPPYMEAL is not set
# CONFIG_SUNGEM is not set
+# CONFIG_CASSINI is not set
# CONFIG_NET_VENDOR_3COM is not set
# CONFIG_NET_VENDOR_SMC is not set
@@ -336,6 +430,7 @@ CONFIG_TULIP=y
# CONFIG_DE4X5 is not set
# CONFIG_WINBOND_840 is not set
# CONFIG_DM9102 is not set
+# CONFIG_ULI526X is not set
# CONFIG_DEPCA is not set
# CONFIG_HP100 is not set
CONFIG_NET_PCI=y
@@ -361,30 +456,37 @@ CONFIG_NET_PCI=y
# CONFIG_SUNDANCE is not set
# CONFIG_TLAN is not set
# CONFIG_VIA_RHINE is not set
+# CONFIG_NET_POCKET is not set
#
# Ethernet (1000 Mbit)
#
-# CONFIG_ACENIC is not set
-CONFIG_DL2K=y
+CONFIG_ACENIC=y
+# CONFIG_ACENIC_OMIT_TIGON_I is not set
+# CONFIG_DL2K is not set
# CONFIG_E1000 is not set
# CONFIG_NS83820 is not set
# CONFIG_HAMACHI is not set
# CONFIG_YELLOWFIN is not set
# CONFIG_R8169 is not set
# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
# CONFIG_SK98LIN is not set
-# CONFIG_TIGON3 is not set
+# CONFIG_VIA_VELOCITY is not set
+CONFIG_TIGON3=y
+# CONFIG_BNX2 is not set
#
# Ethernet (10000 Mbit)
#
+# CONFIG_CHELSIO_T1 is not set
# CONFIG_IXGB is not set
-# CONFIG_FDDI is not set
-# CONFIG_HIPPI is not set
-# CONFIG_PLIP is not set
-# CONFIG_PPP is not set
-# CONFIG_SLIP is not set
+# CONFIG_S2IO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
#
# Wireless LAN (non-hamradio)
@@ -399,38 +501,30 @@ CONFIG_NET_RADIO=y
#
# Wireless 802.11b ISA/PCI cards support
#
-CONFIG_AIRO=y
# CONFIG_HERMES is not set
# CONFIG_ATMEL is not set
-CONFIG_NET_WIRELESS=y
#
-# Token Ring devices
+# Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support
#
-# CONFIG_TR is not set
-# CONFIG_NET_FC is not set
-# CONFIG_RCPCI is not set
-# CONFIG_SHAPER is not set
+# CONFIG_PRISM54 is not set
+# CONFIG_HOSTAP is not set
+CONFIG_NET_WIRELESS=y
#
# Wan interfaces
#
# CONFIG_WAN is not set
-
-#
-# Amateur Radio support
-#
-# CONFIG_HAMRADIO is not set
-
-#
-# IrDA (infrared) support
-#
-# CONFIG_IRDA is not set
-
-#
-# Bluetooth support
-#
-# CONFIG_BT is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PLIP is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NET_FC is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
#
# ISDN subsystem
@@ -460,51 +554,67 @@ CONFIG_INPUT_EVDEV=y
# CONFIG_INPUT_EVBUG is not set
#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=y
-# CONFIG_SERIO_SERPORT is not set
-# CONFIG_SERIO_PARKBD is not set
-CONFIG_SERIO_GSCPS2=y
-CONFIG_HP_SDC=y
-CONFIG_HIL_MLC=y
-# CONFIG_SERIO_PCIPS2 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_HIL_OLD=y
CONFIG_KEYBOARD_HIL=y
CONFIG_INPUT_MOUSE=y
# CONFIG_MOUSE_PS2 is not set
# CONFIG_MOUSE_SERIAL is not set
+# CONFIG_MOUSE_VSXXXAA is not set
# CONFIG_MOUSE_HIL is not set
CONFIG_INPUT_JOYSTICK=y
+# CONFIG_JOYSTICK_ANALOG is not set
+# CONFIG_JOYSTICK_A3D is not set
+# CONFIG_JOYSTICK_ADI is not set
+# CONFIG_JOYSTICK_COBRA is not set
+# CONFIG_JOYSTICK_GF2K is not set
+# CONFIG_JOYSTICK_GRIP is not set
+# CONFIG_JOYSTICK_GRIP_MP is not set
+# CONFIG_JOYSTICK_GUILLEMOT is not set
+# CONFIG_JOYSTICK_INTERACT is not set
+# CONFIG_JOYSTICK_SIDEWINDER is not set
+# CONFIG_JOYSTICK_TMDC is not set
# CONFIG_JOYSTICK_IFORCE is not set
# CONFIG_JOYSTICK_WARRIOR is not set
# CONFIG_JOYSTICK_MAGELLAN is not set
# CONFIG_JOYSTICK_SPACEORB is not set
# CONFIG_JOYSTICK_SPACEBALL is not set
# CONFIG_JOYSTICK_STINGER is not set
-# CONFIG_JOYSTICK_TWIDDLER is not set
+# CONFIG_JOYSTICK_TWIDJOY is not set
# CONFIG_JOYSTICK_DB9 is not set
# CONFIG_JOYSTICK_GAMECON is not set
# CONFIG_JOYSTICK_TURBOGRAFX is not set
-# CONFIG_INPUT_JOYDUMP is not set
+# CONFIG_JOYSTICK_JOYDUMP is not set
CONFIG_INPUT_TOUCHSCREEN=y
# CONFIG_TOUCHSCREEN_GUNZE is not set
+# CONFIG_TOUCHSCREEN_ELO is not set
+# CONFIG_TOUCHSCREEN_MTOUCH is not set
+# CONFIG_TOUCHSCREEN_MK712 is not set
CONFIG_INPUT_MISC=y
-# CONFIG_INPUT_PCSPKR is not set
# CONFIG_INPUT_UINPUT is not set
CONFIG_HP_SDC_RTC=y
#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_SERPORT is not set
+# CONFIG_SERIO_PARKBD is not set
+CONFIG_SERIO_GSCPS2=y
+CONFIG_HP_SDC=y
+CONFIG_HIL_MLC=y
+# CONFIG_SERIO_PCIPS2 is not set
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+
+#
# Character devices
#
CONFIG_VT=y
@@ -522,16 +632,16 @@ CONFIG_SERIAL_8250_EXTENDED=y
CONFIG_SERIAL_8250_MANY_PORTS=y
CONFIG_SERIAL_8250_SHARE_IRQ=y
# CONFIG_SERIAL_8250_DETECT_IRQ is not set
-# CONFIG_SERIAL_8250_MULTIPORT is not set
# CONFIG_SERIAL_8250_RSA is not set
#
# Non-8250 serial port support
#
-# CONFIG_SERIAL_MUX is not set
-# CONFIG_PDC_CONSOLE is not set
+CONFIG_SERIAL_MUX=y
+CONFIG_SERIAL_MUX_CONSOLE=y
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
CONFIG_UNIX98_PTYS=y
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
@@ -541,12 +651,6 @@ CONFIG_PRINTER=y
# CONFIG_TIPAR is not set
#
-# Mice
-#
-# CONFIG_BUSMOUSE is not set
-# CONFIG_QIC02_TAPE is not set
-
-#
# IPMI
#
# CONFIG_IPMI_HANDLER is not set
@@ -555,7 +659,6 @@ CONFIG_PRINTER=y
# Watchdog Cards
#
# CONFIG_WATCHDOG is not set
-# CONFIG_NVRAM is not set
CONFIG_GEN_RTC=y
# CONFIG_GEN_RTC_X is not set
# CONFIG_DTLK is not set
@@ -565,21 +668,40 @@ CONFIG_GEN_RTC=y
#
# Ftape, the floppy tape device driver
#
-# CONFIG_FTAPE is not set
-# CONFIG_AGP is not set
# CONFIG_DRM is not set
# CONFIG_RAW_DRIVER is not set
#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+
+#
# I2C support
#
# CONFIG_I2C is not set
#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
# Misc devices
#
#
+# Multimedia Capabilities Port drivers
+#
+
+#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
@@ -593,34 +715,45 @@ CONFIG_GEN_RTC=y
# Graphics support
#
CONFIG_FB=y
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+CONFIG_FB_SOFT_CURSOR=y
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+# CONFIG_FB_CIRRUS is not set
# CONFIG_FB_PM2 is not set
# CONFIG_FB_CYBER2000 is not set
+# CONFIG_FB_ASILIANT is not set
# CONFIG_FB_IMSTT is not set
CONFIG_FB_STI=y
+# CONFIG_FB_NVIDIA is not set
# CONFIG_FB_RIVA is not set
# CONFIG_FB_MATROX is not set
# CONFIG_FB_RADEON_OLD is not set
# CONFIG_FB_RADEON is not set
# CONFIG_FB_ATY128 is not set
# CONFIG_FB_ATY is not set
+# CONFIG_FB_SAVAGE is not set
# CONFIG_FB_SIS is not set
# CONFIG_FB_NEOMAGIC is not set
# CONFIG_FB_KYRO is not set
# CONFIG_FB_3DFX is not set
# CONFIG_FB_VOODOO1 is not set
+# CONFIG_FB_CYBLA is not set
# CONFIG_FB_TRIDENT is not set
+# CONFIG_FB_S1D13XXX is not set
# CONFIG_FB_VIRTUAL is not set
#
# Console display driver support
#
-# CONFIG_MDA_CONSOLE is not set
-CONFIG_STI_CONSOLE=y
+CONFIG_DUMMY_CONSOLE=y
CONFIG_DUMMY_CONSOLE_COLUMNS=160
CONFIG_DUMMY_CONSOLE_ROWS=64
-CONFIG_DUMMY_CONSOLE=y
CONFIG_FRAMEBUFFER_CONSOLE=y
-CONFIG_PCI_CONSOLE=y
+CONFIG_STI_CONSOLE=y
# CONFIG_FONTS is not set
CONFIG_FONT_8x8=y
CONFIG_FONT_8x16=y
@@ -629,6 +762,7 @@ CONFIG_FONT_8x16=y
# Logo configuration
#
# CONFIG_LOGO is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Sound
@@ -638,17 +772,94 @@ CONFIG_SOUND=y
#
# Advanced Linux Sound Architecture
#
-# CONFIG_SND is not set
+CONFIG_SND=y
+CONFIG_SND_TIMER=y
+CONFIG_SND_PCM=y
+CONFIG_SND_SEQUENCER=y
+# CONFIG_SND_SEQ_DUMMY is not set
+CONFIG_SND_OSSEMUL=y
+CONFIG_SND_MIXER_OSS=y
+CONFIG_SND_PCM_OSS=y
+CONFIG_SND_SEQUENCER_OSS=y
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+
+#
+# Generic devices
+#
+# CONFIG_SND_DUMMY is not set
+# CONFIG_SND_VIRMIDI is not set
+# CONFIG_SND_MTPAV is not set
+# CONFIG_SND_SERIAL_U16550 is not set
+# CONFIG_SND_MPU401 is not set
+CONFIG_SND_AC97_CODEC=y
+CONFIG_SND_AC97_BUS=y
+
+#
+# PCI devices
+#
+# CONFIG_SND_ALI5451 is not set
+# CONFIG_SND_ATIIXP is not set
+# CONFIG_SND_ATIIXP_MODEM is not set
+# CONFIG_SND_AU8810 is not set
+# CONFIG_SND_AU8820 is not set
+# CONFIG_SND_AU8830 is not set
+# CONFIG_SND_AZT3328 is not set
+# CONFIG_SND_BT87X is not set
+# CONFIG_SND_CS46XX is not set
+# CONFIG_SND_CS4281 is not set
+# CONFIG_SND_EMU10K1 is not set
+# CONFIG_SND_EMU10K1X is not set
+# CONFIG_SND_CA0106 is not set
+# CONFIG_SND_KORG1212 is not set
+# CONFIG_SND_MIXART is not set
+# CONFIG_SND_NM256 is not set
+# CONFIG_SND_RME32 is not set
+# CONFIG_SND_RME96 is not set
+# CONFIG_SND_RME9652 is not set
+# CONFIG_SND_HDSP is not set
+# CONFIG_SND_HDSPM is not set
+# CONFIG_SND_TRIDENT is not set
+# CONFIG_SND_YMFPCI is not set
+CONFIG_SND_AD1889=y
+# CONFIG_SND_AD1889_OPL3 is not set
+# CONFIG_SND_CMIPCI is not set
+# CONFIG_SND_ENS1370 is not set
+# CONFIG_SND_ENS1371 is not set
+# CONFIG_SND_ES1938 is not set
+# CONFIG_SND_ES1968 is not set
+# CONFIG_SND_MAESTRO3 is not set
+# CONFIG_SND_FM801 is not set
+# CONFIG_SND_ICE1712 is not set
+# CONFIG_SND_ICE1724 is not set
+# CONFIG_SND_INTEL8X0 is not set
+# CONFIG_SND_INTEL8X0M is not set
+# CONFIG_SND_SONICVIBES is not set
+# CONFIG_SND_VIA82XX is not set
+# CONFIG_SND_VIA82XX_MODEM is not set
+# CONFIG_SND_VX222 is not set
+# CONFIG_SND_HDA_INTEL is not set
+
+#
+# USB devices
+#
+# CONFIG_SND_USB_AUDIO is not set
+
+#
+# GSC devices
+#
+CONFIG_SND_HARMONY=y
#
# Open Sound System
#
# CONFIG_SOUND_PRIME is not set
-# CONFIG_SOUND_HARMONY is not set
#
# USB support
#
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
CONFIG_USB=y
CONFIG_USB_DEBUG=y
@@ -658,26 +869,36 @@ CONFIG_USB_DEBUG=y
# CONFIG_USB_DEVICEFS is not set
# CONFIG_USB_BANDWIDTH is not set
# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_OTG is not set
#
# USB Host Controller Drivers
#
CONFIG_USB_EHCI_HCD=y
+# CONFIG_USB_EHCI_SPLIT_ISO is not set
+# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
+# CONFIG_USB_ISP116X_HCD is not set
CONFIG_USB_OHCI_HCD=y
+# CONFIG_USB_OHCI_BIG_ENDIAN is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
# CONFIG_USB_UHCI_HCD is not set
+# CONFIG_USB_SL811_HCD is not set
#
# USB Device Class drivers
#
-# CONFIG_USB_AUDIO is not set
+# CONFIG_OBSOLETE_OSS_USB_DRIVER is not set
# CONFIG_USB_BLUETOOTH_TTY is not set
-# CONFIG_USB_MIDI is not set
# CONFIG_USB_ACM is not set
# CONFIG_USB_PRINTER is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+#
# CONFIG_USB_STORAGE is not set
#
-# USB Human Interface Devices (HID)
+# USB Input Devices
#
# CONFIG_USB_HID is not set
@@ -688,16 +909,23 @@ CONFIG_USB_OHCI_HCD=y
# CONFIG_USB_MOUSE is not set
# CONFIG_USB_AIPTEK is not set
# CONFIG_USB_WACOM is not set
+# CONFIG_USB_ACECAD is not set
# CONFIG_USB_KBTAB is not set
# CONFIG_USB_POWERMATE is not set
+# CONFIG_USB_MTOUCH is not set
+# CONFIG_USB_ITMTOUCH is not set
+# CONFIG_USB_EGALAX is not set
+# CONFIG_USB_YEALINK is not set
# CONFIG_USB_XPAD is not set
+# CONFIG_USB_ATI_REMOTE is not set
+# CONFIG_USB_KEYSPAN_REMOTE is not set
+# CONFIG_USB_APPLETOUCH is not set
#
# USB Imaging devices
#
# CONFIG_USB_MDC800 is not set
# CONFIG_USB_MICROTEK is not set
-# CONFIG_USB_HPUSBSCSI is not set
#
# USB Multimedia devices
@@ -709,13 +937,15 @@ CONFIG_USB_OHCI_HCD=y
#
#
-# USB Network adaptors
+# USB Network Adapters
#
# CONFIG_USB_CATC is not set
# CONFIG_USB_KAWETH is not set
# CONFIG_USB_PEGASUS is not set
# CONFIG_USB_RTL8150 is not set
# CONFIG_USB_USBNET is not set
+# CONFIG_USB_ZD1201 is not set
+CONFIG_USB_MON=y
#
# USB port drivers
@@ -732,12 +962,21 @@ CONFIG_USB_OHCI_HCD=y
#
# CONFIG_USB_EMI62 is not set
# CONFIG_USB_EMI26 is not set
-# CONFIG_USB_TIGL is not set
# CONFIG_USB_AUERSWALD is not set
# CONFIG_USB_RIO500 is not set
# CONFIG_USB_LEGOTOWER is not set
# CONFIG_USB_LCD is not set
# CONFIG_USB_LED is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_PHIDGETKIT is not set
+# CONFIG_USB_PHIDGETSERVO is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_SISUSBVGA is not set
+# CONFIG_USB_LD is not set
+
+#
+# USB DSL modem support
+#
#
# USB Gadget Support
@@ -745,22 +984,41 @@ CONFIG_USB_OHCI_HCD=y
# CONFIG_USB_GADGET is not set
#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
+# SN Devices
+#
+
+#
# File systems
#
CONFIG_EXT2_FS=y
# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
CONFIG_EXT3_FS=y
# CONFIG_EXT3_FS_XATTR is not set
CONFIG_JBD=y
# CONFIG_JBD_DEBUG is not set
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
# CONFIG_XFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
# CONFIG_AUTOFS_FS is not set
# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
#
# CD-ROM/DVD Filesystems
@@ -773,7 +1031,8 @@ CONFIG_JOLIET=y
#
# DOS/FAT/NT Filesystems
#
-# CONFIG_FAT_FS is not set
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
# CONFIG_NTFS_FS is not set
#
@@ -781,11 +1040,11 @@ CONFIG_JOLIET=y
#
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
-# CONFIG_DEVFS_FS is not set
-# CONFIG_DEVPTS_FS_XATTR is not set
+CONFIG_SYSFS=y
CONFIG_TMPFS=y
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
+# CONFIG_RELAYFS_FS is not set
#
# Miscellaneous filesystems
@@ -809,23 +1068,28 @@ CONFIG_RAMFS=y
#
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
# CONFIG_NFS_V4 is not set
# CONFIG_NFS_DIRECTIO is not set
CONFIG_NFSD=y
CONFIG_NFSD_V3=y
+# CONFIG_NFSD_V3_ACL is not set
# CONFIG_NFSD_V4 is not set
CONFIG_NFSD_TCP=y
CONFIG_ROOT_NFS=y
CONFIG_LOCKD=y
CONFIG_LOCKD_V4=y
CONFIG_EXPORTFS=y
+CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
-# CONFIG_SUNRPC_GSS is not set
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
# CONFIG_SMB_FS is not set
# CONFIG_CIFS is not set
# CONFIG_NCP_FS is not set
# CONFIG_CODA_FS is not set
# CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
#
# Partition Types
@@ -861,6 +1125,7 @@ CONFIG_NLS_DEFAULT="iso8859-1"
# CONFIG_NLS_ISO8859_8 is not set
# CONFIG_NLS_CODEPAGE_1250 is not set
# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
# CONFIG_NLS_ISO8859_1 is not set
# CONFIG_NLS_ISO8859_2 is not set
# CONFIG_NLS_ISO8859_3 is not set
@@ -885,17 +1150,24 @@ CONFIG_OPROFILE=y
#
# Kernel hacking
#
+# CONFIG_PRINTK_TIME is not set
CONFIG_DEBUG_KERNEL=y
-# CONFIG_DEBUG_SLAB is not set
CONFIG_MAGIC_SYSRQ=y
+CONFIG_LOG_BUF_SHIFT=15
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_DEBUG_SLAB is not set
# CONFIG_DEBUG_SPINLOCK is not set
-# CONFIG_DEBUG_RWLOCK is not set
-CONFIG_FRAME_POINTER=y
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_KOBJECT is not set
# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_IOREMAP is not set
+# CONFIG_DEBUG_FS is not set
#
# Security options
#
+# CONFIG_KEYS is not set
# CONFIG_SECURITY is not set
#
@@ -909,6 +1181,8 @@ CONFIG_CRYPTO=y
# CONFIG_CRYPTO_SHA1 is not set
# CONFIG_CRYPTO_SHA256 is not set
# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_WP512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
# CONFIG_CRYPTO_DES is not set
# CONFIG_CRYPTO_BLOWFISH is not set
# CONFIG_CRYPTO_TWOFISH is not set
@@ -916,11 +1190,23 @@ CONFIG_CRYPTO=y
# CONFIG_CRYPTO_AES is not set
# CONFIG_CRYPTO_CAST5 is not set
# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_TEA is not set
# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_ANUBIS is not set
# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_CRC32C is not set
# CONFIG_CRYPTO_TEST is not set
#
+# Hardware crypto devices
+#
+
+#
# Library routines
#
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
CONFIG_CRC32=y
+# CONFIG_LIBCRC32C is not set
diff --git a/arch/parisc/kernel/asm-offsets.c b/arch/parisc/kernel/asm-offsets.c
index 1ad44f92d6e4..e23c4e1e3a25 100644
--- a/arch/parisc/kernel/asm-offsets.c
+++ b/arch/parisc/kernel/asm-offsets.c
@@ -30,7 +30,6 @@
#include <linux/types.h>
#include <linux/sched.h>
#include <linux/thread_info.h>
-#include <linux/version.h>
#include <linux/ptrace.h>
#include <linux/hardirq.h>
diff --git a/arch/parisc/kernel/cache.c b/arch/parisc/kernel/cache.c
index f46a07a79218..a065349aee37 100644
--- a/arch/parisc/kernel/cache.c
+++ b/arch/parisc/kernel/cache.c
@@ -27,6 +27,7 @@
#include <asm/page.h>
#include <asm/pgalloc.h>
#include <asm/processor.h>
+#include <asm/sections.h>
int split_tlb;
int dcache_stride;
@@ -207,6 +208,9 @@ parisc_cache_init(void)
/* "New and Improved" version from Jim Hull
* (1 << (cc_block-1)) * (cc_line << (4 + cnf.cc_shift))
+ * The following CAFL_STRIDE is an optimized version, see
+ * http://lists.parisc-linux.org/pipermail/parisc-linux/2004-June/023625.html
+ * http://lists.parisc-linux.org/pipermail/parisc-linux/2004-June/023671.html
*/
#define CAFL_STRIDE(cnf) (cnf.cc_line << (3 + cnf.cc_block + cnf.cc_shift))
dcache_stride = CAFL_STRIDE(cache_info.dc_conf);
@@ -266,7 +270,6 @@ void flush_dcache_page(struct page *page)
unsigned long offset;
unsigned long addr;
pgoff_t pgoff;
- pte_t *pte;
unsigned long pfn = page_to_pfn(page);
@@ -297,21 +300,16 @@ void flush_dcache_page(struct page *page)
* taking a page fault if the pte doesn't exist.
* This is just for speed. If the page translation
* isn't there, there's no point exciting the
- * nadtlb handler into a nullification frenzy */
-
-
- if(!(pte = translation_exists(mpnt, addr)))
- continue;
-
- /* make sure we really have this page: the private
+ * nadtlb handler into a nullification frenzy.
+ *
+ * Make sure we really have this page: the private
* mappings may cover this area but have COW'd this
- * particular page */
- if(pte_pfn(*pte) != pfn)
- continue;
-
- __flush_cache_page(mpnt, addr);
-
- break;
+ * particular page.
+ */
+ if (translation_exists(mpnt, addr, pfn)) {
+ __flush_cache_page(mpnt, addr);
+ break;
+ }
}
flush_dcache_mmap_unlock(mapping);
}
@@ -339,17 +337,15 @@ int parisc_cache_flush_threshold = FLUSH_THRESHOLD;
void parisc_setup_cache_timing(void)
{
unsigned long rangetime, alltime;
- extern char _text; /* start of kernel code, defined by linker */
- extern char _end; /* end of BSS, defined by linker */
unsigned long size;
alltime = mfctl(16);
flush_data_cache();
alltime = mfctl(16) - alltime;
- size = (unsigned long)(&_end - _text);
+ size = (unsigned long)(_end - _text);
rangetime = mfctl(16);
- flush_kernel_dcache_range((unsigned long)&_text, size);
+ flush_kernel_dcache_range((unsigned long)_text, size);
rangetime = mfctl(16) - rangetime;
printk(KERN_DEBUG "Whole cache flush %lu cycles, flushing %lu bytes %lu cycles\n",
diff --git a/arch/parisc/kernel/drivers.c b/arch/parisc/kernel/drivers.c
index d34bbe7ae0e3..988844a169e6 100644
--- a/arch/parisc/kernel/drivers.c
+++ b/arch/parisc/kernel/drivers.c
@@ -46,36 +46,51 @@ static struct device root = {
.bus_id = "parisc",
};
-#define for_each_padev(padev) \
- for (padev = next_dev(&root); padev != NULL; \
- padev = next_dev(&padev->dev))
+static inline int check_dev(struct device *dev)
+{
+ if (dev->bus == &parisc_bus_type) {
+ struct parisc_device *pdev;
+ pdev = to_parisc_device(dev);
+ return pdev->id.hw_type != HPHW_FAULTY;
+ }
+ return 1;
+}
+
+static struct device *
+parse_tree_node(struct device *parent, int index, struct hardware_path *modpath);
-#define check_dev(padev) \
- (padev->id.hw_type != HPHW_FAULTY) ? padev : next_dev(&padev->dev)
+struct recurse_struct {
+ void * obj;
+ int (*fn)(struct device *, void *);
+};
+
+static int descend_children(struct device * dev, void * data)
+{
+ struct recurse_struct * recurse_data = (struct recurse_struct *)data;
+
+ if (recurse_data->fn(dev, recurse_data->obj))
+ return 1;
+ else
+ return device_for_each_child(dev, recurse_data, descend_children);
+}
/**
- * next_dev - enumerates registered devices
- * @dev: the previous device returned from next_dev
+ * for_each_padev - Iterate over all devices in the tree
+ * @fn: Function to call for each device.
+ * @data: Data to pass to the called function.
*
- * next_dev does a depth-first search of the tree, returning parents
- * before children. Returns NULL when there are no more devices.
+ * This performs a depth-first traversal of the tree, calling the
+ * function passed for each node. It calls the function for parents
+ * before children.
*/
-static struct parisc_device *next_dev(struct device *dev)
-{
- if (!list_empty(&dev->children)) {
- dev = list_to_dev(dev->children.next);
- return check_dev(to_parisc_device(dev));
- }
- while (dev != &root) {
- if (dev->node.next != &dev->parent->children) {
- dev = list_to_dev(dev->node.next);
- return to_parisc_device(dev);
- }
- dev = dev->parent;
- }
-
- return NULL;
+static int for_each_padev(int (*fn)(struct device *, void *), void * data)
+{
+ struct recurse_struct recurse_data = {
+ .obj = data,
+ .fn = fn,
+ };
+ return device_for_each_child(&root, &recurse_data, descend_children);
}
/**
@@ -105,12 +120,6 @@ static int match_device(struct parisc_driver *driver, struct parisc_device *dev)
return 0;
}
-static void claim_device(struct parisc_driver *driver, struct parisc_device *dev)
-{
- dev->driver = driver;
- request_mem_region(dev->hpa, 0x1000, driver->name);
-}
-
static int parisc_driver_probe(struct device *dev)
{
int rc;
@@ -119,8 +128,8 @@ static int parisc_driver_probe(struct device *dev)
rc = pa_drv->probe(pa_dev);
- if(!rc)
- claim_device(pa_drv, pa_dev);
+ if (!rc)
+ pa_dev->driver = pa_drv;
return rc;
}
@@ -131,7 +140,6 @@ static int parisc_driver_remove(struct device *dev)
struct parisc_driver *pa_drv = to_parisc_driver(dev->driver);
if (pa_drv->remove)
pa_drv->remove(pa_dev);
- release_mem_region(pa_dev->hpa, 0x1000);
return 0;
}
@@ -173,6 +181,24 @@ int register_parisc_driver(struct parisc_driver *driver)
}
EXPORT_SYMBOL(register_parisc_driver);
+
+struct match_count {
+ struct parisc_driver * driver;
+ int count;
+};
+
+static int match_and_count(struct device * dev, void * data)
+{
+ struct match_count * m = data;
+ struct parisc_device * pdev = to_parisc_device(dev);
+
+ if (check_dev(dev)) {
+ if (match_device(m->driver, pdev))
+ m->count++;
+ }
+ return 0;
+}
+
/**
* count_parisc_driver - count # of devices this driver would match
* @driver: the PA-RISC driver to try
@@ -182,15 +208,14 @@ EXPORT_SYMBOL(register_parisc_driver);
*/
int count_parisc_driver(struct parisc_driver *driver)
{
- struct parisc_device *device;
- int cnt = 0;
+ struct match_count m = {
+ .driver = driver,
+ .count = 0,
+ };
- for_each_padev(device) {
- if (match_device(driver, device))
- cnt++;
- }
+ for_each_padev(match_and_count, &m);
- return cnt;
+ return m.count;
}
@@ -206,14 +231,34 @@ int unregister_parisc_driver(struct parisc_driver *driver)
}
EXPORT_SYMBOL(unregister_parisc_driver);
-static struct parisc_device *find_device_by_addr(unsigned long hpa)
+struct find_data {
+ unsigned long hpa;
+ struct parisc_device * dev;
+};
+
+static int find_device(struct device * dev, void * data)
{
- struct parisc_device *dev;
- for_each_padev(dev) {
- if (dev->hpa == hpa)
- return dev;
+ struct parisc_device * pdev = to_parisc_device(dev);
+ struct find_data * d = (struct find_data*)data;
+
+ if (check_dev(dev)) {
+ if (pdev->hpa.start == d->hpa) {
+ d->dev = pdev;
+ return 1;
+ }
}
- return NULL;
+ return 0;
+}
+
+static struct parisc_device *find_device_by_addr(unsigned long hpa)
+{
+ struct find_data d = {
+ .hpa = hpa,
+ };
+ int ret;
+
+ ret = for_each_padev(find_device, &d);
+ return ret ? d.dev : NULL;
}
/**
@@ -387,6 +432,23 @@ struct parisc_device * create_tree_node(char id, struct device *parent)
return dev;
}
+struct match_id_data {
+ char id;
+ struct parisc_device * dev;
+};
+
+static int match_by_id(struct device * dev, void * data)
+{
+ struct parisc_device * pdev = to_parisc_device(dev);
+ struct match_id_data * d = data;
+
+ if (pdev->hw_path == d->id) {
+ d->dev = pdev;
+ return 1;
+ }
+ return 0;
+}
+
/**
* alloc_tree_node - returns a device entry in the iotree
* @parent: the parent node in the tree
@@ -397,15 +459,13 @@ struct parisc_device * create_tree_node(char id, struct device *parent)
*/
static struct parisc_device * alloc_tree_node(struct device *parent, char id)
{
- struct device *dev;
-
- list_for_each_entry(dev, &parent->children, node) {
- struct parisc_device *padev = to_parisc_device(dev);
- if (padev->hw_path == id)
- return padev;
- }
-
- return create_tree_node(id, parent);
+ struct match_id_data d = {
+ .id = id,
+ };
+ if (device_for_each_child(parent, &d, match_by_id))
+ return d.dev;
+ else
+ return create_tree_node(id, parent);
}
static struct parisc_device *create_parisc_device(struct hardware_path *modpath)
@@ -439,10 +499,8 @@ alloc_pa_dev(unsigned long hpa, struct hardware_path *mod_path)
dev = create_parisc_device(mod_path);
if (dev->id.hw_type != HPHW_FAULTY) {
- char p[64];
- print_pa_hwpath(dev, p);
printk("Two devices have hardware path %s. Please file a bug with HP.\n"
- "In the meantime, you could try rearranging your cards.\n", p);
+ "In the meantime, you could try rearranging your cards.\n", parisc_pathname(dev));
return NULL;
}
@@ -451,12 +509,27 @@ alloc_pa_dev(unsigned long hpa, struct hardware_path *mod_path)
dev->id.hversion_rev = iodc_data[1] & 0x0f;
dev->id.sversion = ((iodc_data[4] & 0x0f) << 16) |
(iodc_data[5] << 8) | iodc_data[6];
- dev->hpa = hpa;
+ dev->hpa.name = parisc_pathname(dev);
+ dev->hpa.start = hpa;
+ if (hpa == 0xf4000000 || hpa == 0xf6000000 ||
+ hpa == 0xf8000000 || hpa == 0xfa000000) {
+ dev->hpa.end = hpa + 0x01ffffff;
+ } else {
+ dev->hpa.end = hpa + 0xfff;
+ }
+ dev->hpa.flags = IORESOURCE_MEM;
name = parisc_hardware_description(&dev->id);
if (name) {
strlcpy(dev->name, name, sizeof(dev->name));
}
+ /* Silently fail things like mouse ports which are subsumed within
+ * the keyboard controller
+ */
+ if ((hpa & 0xfff) == 0 && insert_resource(&iomem_resource, &dev->hpa))
+ printk("Unable to claim HPA %lx for device %s\n",
+ hpa, name);
+
return dev;
}
@@ -555,6 +628,33 @@ static int match_parisc_device(struct device *dev, int index,
return (curr->hw_path == id);
}
+struct parse_tree_data {
+ int index;
+ struct hardware_path * modpath;
+ struct device * dev;
+};
+
+static int check_parent(struct device * dev, void * data)
+{
+ struct parse_tree_data * d = data;
+
+ if (check_dev(dev)) {
+ if (dev->bus == &parisc_bus_type) {
+ if (match_parisc_device(dev, d->index, d->modpath))
+ d->dev = dev;
+ } else if (is_pci_dev(dev)) {
+ if (match_pci_device(dev, d->index, d->modpath))
+ d->dev = dev;
+ } else if (dev->bus == NULL) {
+ /* we are on a bus bridge */
+ struct device *new = parse_tree_node(dev, d->index, d->modpath);
+ if (new)
+ d->dev = new;
+ }
+ }
+ return d->dev != NULL;
+}
+
/**
* parse_tree_node - returns a device entry in the iotree
* @parent: the parent node in the tree
@@ -568,24 +668,18 @@ static int match_parisc_device(struct device *dev, int index,
static struct device *
parse_tree_node(struct device *parent, int index, struct hardware_path *modpath)
{
- struct device *device;
-
- list_for_each_entry(device, &parent->children, node) {
- if (device->bus == &parisc_bus_type) {
- if (match_parisc_device(device, index, modpath))
- return device;
- } else if (is_pci_dev(device)) {
- if (match_pci_device(device, index, modpath))
- return device;
- } else if (device->bus == NULL) {
- /* we are on a bus bridge */
- struct device *new = parse_tree_node(device, index, modpath);
- if (new)
- return new;
- }
- }
+ struct parse_tree_data d = {
+ .index = index,
+ .modpath = modpath,
+ };
- return NULL;
+ struct recurse_struct recurse_data = {
+ .obj = &d,
+ .fn = check_parent,
+ };
+
+ device_for_each_child(parent, &recurse_data, descend_children);
+ return d.dev;
}
/**
@@ -636,7 +730,7 @@ EXPORT_SYMBOL(device_to_hwpath);
((dev->id.hw_type == HPHW_IOA) || (dev->id.hw_type == HPHW_BCPORT))
#define IS_LOWER_PORT(dev) \
- ((gsc_readl(dev->hpa + offsetof(struct bc_module, io_status)) \
+ ((gsc_readl(dev->hpa.start + offsetof(struct bc_module, io_status)) \
& BC_PORT_MASK) == BC_LOWER_PORT)
#define MAX_NATIVE_DEVICES 64
@@ -645,8 +739,8 @@ EXPORT_SYMBOL(device_to_hwpath);
#define FLEX_MASK F_EXTEND(0xfffc0000)
#define IO_IO_LOW offsetof(struct bc_module, io_io_low)
#define IO_IO_HIGH offsetof(struct bc_module, io_io_high)
-#define READ_IO_IO_LOW(dev) (unsigned long)(signed int)gsc_readl(dev->hpa + IO_IO_LOW)
-#define READ_IO_IO_HIGH(dev) (unsigned long)(signed int)gsc_readl(dev->hpa + IO_IO_HIGH)
+#define READ_IO_IO_LOW(dev) (unsigned long)(signed int)gsc_readl(dev->hpa.start + IO_IO_LOW)
+#define READ_IO_IO_HIGH(dev) (unsigned long)(signed int)gsc_readl(dev->hpa.start + IO_IO_HIGH)
static void walk_native_bus(unsigned long io_io_low, unsigned long io_io_high,
struct device *parent);
@@ -655,10 +749,10 @@ void walk_lower_bus(struct parisc_device *dev)
{
unsigned long io_io_low, io_io_high;
- if(!BUS_CONVERTER(dev) || IS_LOWER_PORT(dev))
+ if (!BUS_CONVERTER(dev) || IS_LOWER_PORT(dev))
return;
- if(dev->id.hw_type == HPHW_IOA) {
+ if (dev->id.hw_type == HPHW_IOA) {
io_io_low = (unsigned long)(signed int)(READ_IO_IO_LOW(dev) << 16);
io_io_high = io_io_low + MAX_NATIVE_DEVICES * NATIVE_DEVICE_OFFSET;
} else {
@@ -731,7 +825,7 @@ static void print_parisc_device(struct parisc_device *dev)
print_pa_hwpath(dev, hw_path);
printk(KERN_INFO "%d. %s at 0x%lx [%s] { %d, 0x%x, 0x%.3x, 0x%.5x }",
- ++count, dev->name, dev->hpa, hw_path, dev->id.hw_type,
+ ++count, dev->name, dev->hpa.start, hw_path, dev->id.hw_type,
dev->id.hversion_rev, dev->id.hversion, dev->id.sversion);
if (dev->num_addrs) {
@@ -753,13 +847,20 @@ void init_parisc_bus(void)
get_device(&root);
}
+
+static int print_one_device(struct device * dev, void * data)
+{
+ struct parisc_device * pdev = to_parisc_device(dev);
+
+ if (check_dev(dev))
+ print_parisc_device(pdev);
+ return 0;
+}
+
/**
* print_parisc_devices - Print out a list of devices found in this system
*/
void print_parisc_devices(void)
{
- struct parisc_device *dev;
- for_each_padev(dev) {
- print_parisc_device(dev);
- }
+ for_each_padev(print_one_device, NULL);
}
diff --git a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S
index be0f07f2fa58..c7e66ee5b083 100644
--- a/arch/parisc/kernel/entry.S
+++ b/arch/parisc/kernel/entry.S
@@ -30,14 +30,14 @@
* - save registers to kernel stack and handle in assembly or C */
+#include <asm/psw.h>
#include <asm/assembly.h> /* for LDREG/STREG defines */
#include <asm/pgtable.h>
-#include <asm/psw.h>
#include <asm/signal.h>
#include <asm/unistd.h>
#include <asm/thread_info.h>
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
#define CMPIB cmpib,*
#define CMPB cmpb,*
#define COND(x) *x
@@ -67,19 +67,22 @@
/* Switch to virtual mapping, trashing only %r1 */
.macro virt_map
- rsm PSW_SM_Q,%r0
- tovirt_r1 %r29
- mfsp %sr7, %r1
- or,= %r0,%r1,%r0 /* Only save sr7 in sr3 if sr7 != 0 */
- mtsp %r1, %sr3
+ /* pcxt_ssm_bug */
+ rsm PSW_SM_I, %r0 /* barrier for "Relied upon Translation */
mtsp %r0, %sr4
mtsp %r0, %sr5
+ mfsp %sr7, %r1
+ or,= %r0,%r1,%r0 /* Only save sr7 in sr3 if sr7 != 0 */
+ mtsp %r1, %sr3
+ tovirt_r1 %r29
+ load32 KERNEL_PSW, %r1
+
+ rsm PSW_SM_QUIET,%r0 /* second "heavy weight" ctl op */
mtsp %r0, %sr6
mtsp %r0, %sr7
- load32 KERNEL_PSW, %r1
- mtctl %r1, %cr22
mtctl %r0, %cr17 /* Clear IIASQ tail */
mtctl %r0, %cr17 /* Clear IIASQ head */
+ mtctl %r1, %ipsw
load32 4f, %r1
mtctl %r1, %cr18 /* Set IIAOQ tail */
ldo 4(%r1), %r1
@@ -214,7 +217,7 @@
va = r8 /* virtual address for which the trap occured */
spc = r24 /* space for which the trap occured */
-#ifndef __LP64__
+#ifndef CONFIG_64BIT
/*
* itlb miss interruption handler (parisc 1.1 - 32 bit)
@@ -236,7 +239,7 @@
.macro itlb_20 code
mfctl %pcsq, spc
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
b itlb_miss_20w
#else
b itlb_miss_20
@@ -246,7 +249,7 @@
.align 32
.endm
-#ifndef __LP64__
+#ifndef CONFIG_64BIT
/*
* naitlb miss interruption handler (parisc 1.1 - 32 bit)
*
@@ -283,7 +286,7 @@
.macro naitlb_20 code
mfctl %isr,spc
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
b itlb_miss_20w
#else
b itlb_miss_20
@@ -296,7 +299,7 @@
.align 32
.endm
-#ifndef __LP64__
+#ifndef CONFIG_64BIT
/*
* dtlb miss interruption handler (parisc 1.1 - 32 bit)
*/
@@ -318,7 +321,7 @@
.macro dtlb_20 code
mfctl %isr, spc
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
b dtlb_miss_20w
#else
b dtlb_miss_20
@@ -328,7 +331,7 @@
.align 32
.endm
-#ifndef __LP64__
+#ifndef CONFIG_64BIT
/* nadtlb miss interruption handler (parisc 1.1 - 32 bit) */
.macro nadtlb_11 code
@@ -346,7 +349,7 @@
.macro nadtlb_20 code
mfctl %isr,spc
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
b nadtlb_miss_20w
#else
b nadtlb_miss_20
@@ -356,7 +359,7 @@
.align 32
.endm
-#ifndef __LP64__
+#ifndef CONFIG_64BIT
/*
* dirty bit trap interruption handler (parisc 1.1 - 32 bit)
*/
@@ -378,7 +381,7 @@
.macro dbit_20 code
mfctl %isr,spc
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
b dbit_trap_20w
#else
b dbit_trap_20
@@ -391,7 +394,7 @@
/* The following are simple 32 vs 64 bit instruction
* abstractions for the macros */
.macro EXTR reg1,start,length,reg2
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
extrd,u \reg1,32+\start,\length,\reg2
#else
extrw,u \reg1,\start,\length,\reg2
@@ -399,7 +402,7 @@
.endm
.macro DEP reg1,start,length,reg2
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
depd \reg1,32+\start,\length,\reg2
#else
depw \reg1,\start,\length,\reg2
@@ -407,7 +410,7 @@
.endm
.macro DEPI val,start,length,reg
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
depdi \val,32+\start,\length,\reg
#else
depwi \val,\start,\length,\reg
@@ -418,7 +421,7 @@
* fault. We have to extract this and place it in the va,
* zeroing the corresponding bits in the space register */
.macro space_adjust spc,va,tmp
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
extrd,u \spc,63,SPACEID_SHIFT,\tmp
depd %r0,63,SPACEID_SHIFT,\spc
depd \tmp,31,SPACEID_SHIFT,\va
@@ -476,7 +479,7 @@
bb,>=,n \pmd,_PxD_PRESENT_BIT,\fault
DEP %r0,31,PxD_FLAG_SHIFT,\pmd /* clear flags */
copy \pmd,%r9
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
shld %r9,PxD_VALUE_SHIFT,\pmd
#else
shlw %r9,PxD_VALUE_SHIFT,\pmd
@@ -607,7 +610,7 @@
.macro do_alias spc,tmp,tmp1,va,pte,prot,fault
cmpib,COND(<>),n 0,\spc,\fault
ldil L%(TMPALIAS_MAP_START),\tmp
-#if defined(__LP64__) && (TMPALIAS_MAP_START >= 0x80000000)
+#if defined(CONFIG_64BIT) && (TMPALIAS_MAP_START >= 0x80000000)
/* on LP64, ldi will sign extend into the upper 32 bits,
* which is behaviour we don't want */
depdi 0,31,32,\tmp
@@ -621,7 +624,7 @@
* OK, it is in the temp alias region, check whether "from" or "to".
* Check "subtle" note in pacache.S re: r23/r26.
*/
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
extrd,u,*= \va,41,1,%r0
#else
extrw,u,= \va,9,1,%r0
@@ -688,7 +691,7 @@ fault_vector_20:
def 30
def 31
-#ifndef __LP64__
+#ifndef CONFIG_64BIT
.export fault_vector_11
@@ -761,7 +764,7 @@ __kernel_thread:
copy %r30, %r1
ldo PT_SZ_ALGN(%r30),%r30
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
/* Yo, function pointers in wide mode are little structs... -PB */
ldd 24(%r26), %r2
STREG %r2, PT_GR27(%r1) /* Store childs %dp */
@@ -777,7 +780,7 @@ __kernel_thread:
or %r26, %r24, %r26 /* will have kernel mappings. */
ldi 1, %r25 /* stack_start, signals kernel thread */
stw %r0, -52(%r30) /* user_tid */
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
ldo -16(%r30),%r29 /* Reference param save area */
#endif
BL do_fork, %r2
@@ -806,7 +809,7 @@ ret_from_kernel_thread:
LDREG TI_TASK-THREAD_SZ_ALGN(%r30), %r1
LDREG TASK_PT_GR25(%r1), %r26
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
LDREG TASK_PT_GR27(%r1), %r27
LDREG TASK_PT_GR22(%r1), %r22
#endif
@@ -814,11 +817,16 @@ ret_from_kernel_thread:
ble 0(%sr7, %r1)
copy %r31, %r2
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
ldo -16(%r30),%r29 /* Reference param save area */
loadgp /* Thread could have been in a module */
#endif
+#ifndef CONFIG_64BIT
b sys_exit
+#else
+ load32 sys_exit, %r1
+ bv %r0(%r1)
+#endif
ldi 0, %r26
.import sys_execve, code
@@ -830,7 +838,7 @@ __execve:
STREG %r26, PT_GR26(%r16)
STREG %r25, PT_GR25(%r16)
STREG %r24, PT_GR24(%r16)
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
ldo -16(%r30),%r29 /* Reference param save area */
#endif
BL sys_execve, %r2
@@ -855,6 +863,7 @@ __execve:
_switch_to:
STREG %r2, -RP_OFFSET(%r30)
+ callee_save_float
callee_save
load32 _switch_to_ret, %r2
@@ -871,6 +880,7 @@ _switch_to:
_switch_to_ret:
mtctl %r0, %cr0 /* Needed for single stepping */
callee_rest
+ callee_rest_float
LDREG -RP_OFFSET(%r30), %r2
bv %r0(%r2)
@@ -888,9 +898,6 @@ _switch_to_ret:
* this way, then we will need to copy %sr3 in to PT_SR[3..7], and
* adjust IASQ[0..1].
*
- * Note that the following code uses a "relied upon translation".
- * See the parisc ACD for details. The ssm is necessary due to a
- * PCXT bug.
*/
.align 4096
@@ -911,7 +918,7 @@ syscall_exit_rfi:
STREG %r19,PT_IAOQ1(%r16)
LDREG PT_PSW(%r16),%r19
load32 USER_PSW_MASK,%r1
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
load32 USER_PSW_HI_MASK,%r20
depd %r20,31,32,%r1
#endif
@@ -955,7 +962,7 @@ intr_return:
/* shift left ____cacheline_aligned (aka L1_CACHE_BYTES) amount
** irq_stat[] is defined using ____cacheline_aligned.
*/
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
shld %r1, 6, %r20
#else
shlw %r1, 5, %r20
@@ -963,9 +970,6 @@ intr_return:
add %r19,%r20,%r19 /* now have &irq_stat[smp_processor_id()] */
#endif /* CONFIG_SMP */
- LDREG IRQSTAT_SIRQ_PEND(%r19),%r20 /* hardirq.h: unsigned long */
- cmpib,<>,n 0,%r20,intr_do_softirq /* forward */
-
intr_check_resched:
/* check for reschedule */
@@ -985,24 +989,19 @@ intr_restore:
rest_fp %r1
rest_general %r29
- /* Create a "relied upon translation" PA 2.0 Arch. F-5 */
- ssm 0,%r0
- nop
- nop
- nop
- nop
- nop
- nop
- nop
+ /* inverse of virt_map */
+ pcxt_ssm_bug
+ rsm PSW_SM_QUIET,%r0 /* prepare for rfi */
tophys_r1 %r29
- rsm (PSW_SM_Q|PSW_SM_P|PSW_SM_D|PSW_SM_I),%r0
/* Restore space id's and special cr's from PT_REGS
- * structure pointed to by r29 */
+ * structure pointed to by r29
+ */
rest_specials %r29
- /* Important: Note that rest_stack restores r29
- * last (we are using it)! It also restores r1 and r30. */
+ /* IMPORTANT: rest_stack restores r29 last (we are using it)!
+ * It also restores r1 and r30.
+ */
rest_stack
rfi
@@ -1015,17 +1014,6 @@ intr_restore:
nop
nop
- .import do_softirq,code
-intr_do_softirq:
- bl do_softirq,%r2
-#ifdef __LP64__
- ldo -16(%r30),%r29 /* Reference param save area */
-#else
- nop
-#endif
- b intr_check_resched
- nop
-
.import schedule,code
intr_do_resched:
/* Only do reschedule if we are returning to user space */
@@ -1036,12 +1024,17 @@ intr_do_resched:
CMPIB= 0,%r20,intr_restore /* backward */
nop
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
ldo -16(%r30),%r29 /* Reference param save area */
#endif
ldil L%intr_check_sig, %r2
+#ifndef CONFIG_64BIT
b schedule
+#else
+ load32 schedule, %r20
+ bv %r0(%r20)
+#endif
ldo R%intr_check_sig(%r2), %r2
@@ -1064,7 +1057,7 @@ intr_do_signal:
copy %r0, %r24 /* unsigned long in_syscall */
copy %r16, %r25 /* struct pt_regs *regs */
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
ldo -16(%r30),%r29 /* Reference param save area */
#endif
@@ -1088,7 +1081,7 @@ intr_extint:
mfctl %cr31,%r1
copy %r30,%r17
/* FIXME! depi below has hardcoded idea of interrupt stack size (32k)*/
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
depdi 0,63,15,%r17
#else
depi 0,31,15,%r17
@@ -1115,7 +1108,7 @@ intr_extint:
ldil L%intr_return, %r2
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
ldo -16(%r30),%r29 /* Reference param save area */
#endif
@@ -1153,15 +1146,17 @@ intr_save:
CMPIB=,n 6,%r26,skip_save_ior
- /* save_specials left ipsw value in r8 for us to test */
mfctl %cr20, %r16 /* isr */
+ nop /* serialize mfctl on PA 2.0 to avoid 4 cycle penalty */
mfctl %cr21, %r17 /* ior */
-#ifdef __LP64__
+
+#ifdef CONFIG_64BIT
/*
* If the interrupted code was running with W bit off (32 bit),
* clear the b bits (bits 0 & 1) in the ior.
+ * save_specials left ipsw value in r8 for us to test.
*/
extrd,u,*<> %r8,PSW_W_BIT,1,%r0
depdi 0,1,2,%r17
@@ -1192,7 +1187,7 @@ skip_save_ior:
loadgp
copy %r29, %r25 /* arg1 is pt_regs */
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
ldo -16(%r30),%r29 /* Reference param save area */
#endif
@@ -1230,7 +1225,7 @@ skip_save_ior:
spc = r24 /* space for which the trap occured */
ptp = r25 /* page directory/page table pointer */
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
dtlb_miss_20w:
space_adjust spc,va,t0
@@ -1487,10 +1482,10 @@ nadtlb_emulate:
add,l %r1,%r24,%r1 /* doesn't affect c/b bits */
nadtlb_nullify:
- mfctl %cr22,%r8 /* Get ipsw */
+ mfctl %ipsw,%r8
ldil L%PSW_N,%r9
or %r8,%r9,%r8 /* Set PSW_N */
- mtctl %r8,%cr22
+ mtctl %r8,%ipsw
rfir
nop
@@ -1521,7 +1516,7 @@ nadtlb_probe_check:
nop
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
itlb_miss_20w:
/*
@@ -1588,7 +1583,7 @@ itlb_miss_20:
#endif
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
dbit_trap_20w:
space_adjust spc,va,t0
@@ -1797,7 +1792,7 @@ sys_fork_wrapper:
STREG %r2,-RP_OFFSET(%r30)
ldo FRAME_SIZE(%r30),%r30
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
ldo -16(%r30),%r29 /* Reference param save area */
#endif
@@ -1847,7 +1842,7 @@ sys_clone_wrapper:
STREG %r2,-RP_OFFSET(%r30)
ldo FRAME_SIZE(%r30),%r30
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
ldo -16(%r30),%r29 /* Reference param save area */
#endif
@@ -1869,7 +1864,7 @@ sys_vfork_wrapper:
STREG %r2,-RP_OFFSET(%r30)
ldo FRAME_SIZE(%r30),%r30
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
ldo -16(%r30),%r29 /* Reference param save area */
#endif
@@ -1897,10 +1892,10 @@ sys_vfork_wrapper:
STREG %r2,-RP_OFFSET(%r30)
ldo FRAME_SIZE(%r30),%r30
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
ldo -16(%r30),%r29 /* Reference param save area */
#endif
- bl \execve,%r2
+ BL \execve,%r2
copy %r1,%arg0
ldo -FRAME_SIZE(%r30),%r30
@@ -1923,7 +1918,7 @@ error_\execve:
sys_execve_wrapper:
execve_wrapper sys_execve
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
.export sys32_execve_wrapper
.import sys32_execve
@@ -1937,7 +1932,7 @@ sys_rt_sigreturn_wrapper:
ldo TASK_REGS(%r26),%r26 /* get pt regs */
/* Don't save regs, we are going to restore them from sigcontext. */
STREG %r2, -RP_OFFSET(%r30)
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
ldo FRAME_SIZE(%r30), %r30
BL sys_rt_sigreturn,%r2
ldo -16(%r30),%r29 /* Reference param save area */
@@ -1968,7 +1963,7 @@ sys_sigaltstack_wrapper:
ldo TASK_REGS(%r1),%r24 /* get pt regs */
LDREG TASK_PT_GR30(%r24),%r24
STREG %r2, -RP_OFFSET(%r30)
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
ldo FRAME_SIZE(%r30), %r30
b,l do_sigaltstack,%r2
ldo -16(%r30),%r29 /* Reference param save area */
@@ -1982,7 +1977,7 @@ sys_sigaltstack_wrapper:
bv %r0(%r2)
nop
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
.export sys32_sigaltstack_wrapper
sys32_sigaltstack_wrapper:
/* Get the user stack pointer */
@@ -2006,7 +2001,7 @@ sys_rt_sigsuspend_wrapper:
reg_save %r24
STREG %r2, -RP_OFFSET(%r30)
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
ldo FRAME_SIZE(%r30), %r30
b,l sys_rt_sigsuspend,%r2
ldo -16(%r30),%r29 /* Reference param save area */
@@ -2079,7 +2074,7 @@ syscall_check_bh:
ldw TI_CPU-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r26 /* cpu # */
/* shift left ____cacheline_aligned (aka L1_CACHE_BYTES) bits */
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
shld %r26, 6, %r20
#else
shlw %r26, 5, %r20
@@ -2087,9 +2082,6 @@ syscall_check_bh:
add %r19,%r20,%r19 /* now have &irq_stat[smp_processor_id()] */
#endif /* CONFIG_SMP */
- LDREG IRQSTAT_SIRQ_PEND(%r19),%r20 /* hardirq.h: unsigned long */
- cmpib,<>,n 0,%r20,syscall_do_softirq /* forward */
-
syscall_check_resched:
/* check for reschedule */
@@ -2144,7 +2136,7 @@ syscall_restore:
depi 3,31,2,%r31 /* ensure return to user mode. */
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
/* decide whether to reset the wide mode bit
*
* For a syscall, the W bit is stored in the lowest bit
@@ -2227,20 +2219,10 @@ pt_regs_ok:
b intr_restore
nop
- .import do_softirq,code
-syscall_do_softirq:
- bl do_softirq,%r2
- nop
- /* NOTE: We enable I-bit incase we schedule later,
- * and we might be going back to userspace if we were
- * traced. */
- b syscall_check_resched
- ssm PSW_SM_I, %r0 /* do_softirq returns with I bit off */
-
.import schedule,code
syscall_do_resched:
BL schedule,%r2
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
ldo -16(%r30),%r29 /* Reference param save area */
#else
nop
@@ -2260,7 +2242,7 @@ syscall_do_signal:
ldi 1, %r24 /* unsigned long in_syscall */
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
ldo -16(%r30),%r29 /* Reference param save area */
#endif
BL do_signal,%r2
diff --git a/arch/parisc/kernel/firmware.c b/arch/parisc/kernel/firmware.c
index f244fb200db1..553f8fe03224 100644
--- a/arch/parisc/kernel/firmware.c
+++ b/arch/parisc/kernel/firmware.c
@@ -83,15 +83,15 @@ static unsigned long pdc_result2[32] __attribute__ ((aligned (8)));
int parisc_narrow_firmware = 1;
#endif
-/* on all currently-supported platforms, IODC I/O calls are always
- * 32-bit calls, and MEM_PDC calls are always the same width as the OS.
- * This means Cxxx boxes can't run wide kernels right now. -PB
+/* On most currently-supported platforms, IODC I/O calls are 32-bit calls
+ * and MEM_PDC calls are always the same width as the OS.
+ * Some PAT boxes may have 64-bit IODC I/O.
*
- * CONFIG_PDC_NARROW has been added to allow 64-bit kernels to run on
- * systems with 32-bit MEM_PDC calls. This will allow wide kernels to
- * run on Cxxx boxes now. -RB
- *
- * Note that some PAT boxes may have 64-bit IODC I/O...
+ * Ryan Bradetich added the now obsolete CONFIG_PDC_NARROW to allow
+ * 64-bit kernels to run on systems with 32-bit MEM_PDC calls.
+ * This allowed wide kernels to run on Cxxx boxes.
+ * We now detect 32-bit-only PDC and dynamically switch to 32-bit mode
+ * when running a 64-bit kernel on such boxes (e.g. C200 or C360).
*/
#ifdef __LP64__
diff --git a/arch/parisc/kernel/head.S b/arch/parisc/kernel/head.S
index 28405edf8448..0b47afc20690 100644
--- a/arch/parisc/kernel/head.S
+++ b/arch/parisc/kernel/head.S
@@ -12,7 +12,7 @@
* Initial Version 04-23-1999 by Helge Deller <deller@gmx.de>
*/
-#include <linux/autoconf.h> /* for CONFIG_SMP */
+#include <linux/config.h> /* for CONFIG_SMP */
#include <asm/asm-offsets.h>
#include <asm/psw.h>
@@ -36,10 +36,10 @@ boot_args:
.align 4
.import init_thread_union,data
.import fault_vector_20,code /* IVA parisc 2.0 32 bit */
-#ifndef __LP64__
+#ifndef CONFIG_64BIT
.import fault_vector_11,code /* IVA parisc 1.1 32 bit */
.import $global$ /* forward declaration */
-#endif /*!LP64*/
+#endif /*!CONFIG_64BIT*/
.export stext
.export _stext,data /* Kernel want it this way! */
_stext:
@@ -76,7 +76,7 @@ $bss_loop:
mtctl %r4,%cr24 /* Initialize kernel root pointer */
mtctl %r4,%cr25 /* Initialize user root pointer */
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
/* Set pmd in pgd */
load32 PA(pmd0),%r5
shrd %r5,PxD_VALUE_SHIFT,%r3
@@ -99,7 +99,7 @@ $bss_loop:
stw %r3,0(%r4)
ldo (ASM_PAGE_SIZE >> PxD_VALUE_SHIFT)(%r3),%r3
addib,> -1,%r1,1b
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
ldo ASM_PMD_ENTRY_SIZE(%r4),%r4
#else
ldo ASM_PGD_ENTRY_SIZE(%r4),%r4
@@ -170,7 +170,7 @@ common_stext:
stw %r0,0x28(%r0) /* MEM_RENDEZ_HI */
#endif /*CONFIG_SMP*/
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
tophys_r1 %sp
/* Save the rfi target address */
@@ -224,8 +224,6 @@ stext_pdc_ret:
mtctl %r0,%cr12
mtctl %r0,%cr13
- /* Prepare to RFI! Man all the cannons! */
-
/* Initialize the global data pointer */
loadgp
@@ -235,7 +233,7 @@ stext_pdc_ret:
* following short sequence of instructions can determine this
* (without being illegal on a PA1.1 machine).
*/
-#ifndef __LP64__
+#ifndef CONFIG_64BIT
ldi 32,%r10
mtctl %r10,%cr11
.level 2.0
@@ -248,52 +246,22 @@ stext_pdc_ret:
$is_pa20:
.level LEVEL /* restore 1.1 || 2.0w */
-#endif /*!LP64*/
+#endif /*!CONFIG_64BIT*/
load32 PA(fault_vector_20),%r10
$install_iva:
mtctl %r10,%cr14
-#ifdef __LP64__
- b aligned_rfi
+ b aligned_rfi /* Prepare to RFI! Man all the cannons! */
nop
- .align 256
+ .align 128
aligned_rfi:
- ssm 0,0
- nop /* 1 */
- nop /* 2 */
- nop /* 3 */
- nop /* 4 */
- nop /* 5 */
- nop /* 6 */
- nop /* 7 */
- nop /* 8 */
-#endif
+ pcxt_ssm_bug
-#ifdef __LP64__ /* move to psw.h? */
-#define PSW_BITS PSW_Q+PSW_I+PSW_D+PSW_P+PSW_R
-#else
-#define PSW_BITS PSW_SM_Q
-#endif
+ rsm PSW_SM_QUIET,%r0 /* off troublesome PSW bits */
+ /* Don't need NOPs, have 8 compliant insn before rfi */
-$rfi:
- /* turn off troublesome PSW bits */
- rsm PSW_BITS,%r0
-
- /* kernel PSW:
- * - no interruptions except HPMC and TOC (which are handled by PDC)
- * - Q bit set (IODC / PDC interruptions)
- * - big-endian
- * - virtually mapped
- */
- load32 KERNEL_PSW,%r10
- mtctl %r10,%ipsw
-
- /* Set the space pointers for the post-RFI world
- ** Clear the two-level IIA Space Queue, effectively setting
- ** Kernel space.
- */
mtctl %r0,%cr17 /* Clear IIASQ tail */
mtctl %r0,%cr17 /* Clear IIASQ head */
@@ -301,8 +269,11 @@ $rfi:
mtctl %r11,%cr18 /* IIAOQ head */
ldo 4(%r11),%r11
mtctl %r11,%cr18 /* IIAOQ tail */
+
+ load32 KERNEL_PSW,%r10
+ mtctl %r10,%ipsw
- /* Jump to hyperspace */
+ /* Jump through hyperspace to Virt Mode */
rfi
nop
@@ -313,7 +284,7 @@ $rfi:
.import smp_init_current_idle_task,data
.import smp_callin,code
-#ifndef __LP64__
+#ifndef CONFIG_64BIT
smp_callin_rtn:
.proc
.callinfo
@@ -321,7 +292,7 @@ smp_callin_rtn:
nop
nop
.procend
-#endif /*!LP64*/
+#endif /*!CONFIG_64BIT*/
/***************************************************************************
* smp_slave_stext is executed by all non-monarch Processors when the Monarch
@@ -356,7 +327,7 @@ smp_slave_stext:
mtctl %r4,%cr24 /* Initialize kernel root pointer */
mtctl %r4,%cr25 /* Initialize user root pointer */
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
/* Setup PDCE_PROC entry */
copy %arg0,%r3
#else
@@ -373,7 +344,7 @@ smp_slave_stext:
.procend
#endif /* CONFIG_SMP */
-#ifndef __LP64__
+#ifndef CONFIG_64BIT
.data
.align 4
@@ -383,4 +354,4 @@ smp_slave_stext:
.size $global$,4
$global$:
.word 0
-#endif /*!LP64*/
+#endif /*!CONFIG_64BIT*/
diff --git a/arch/parisc/kernel/ioctl32.c b/arch/parisc/kernel/ioctl32.c
index 1d3824b670d1..0a331104ad56 100644
--- a/arch/parisc/kernel/ioctl32.c
+++ b/arch/parisc/kernel/ioctl32.c
@@ -104,12 +104,9 @@ static int drm32_version(unsigned int fd, unsigned int cmd, unsigned long arg)
}
out:
- if (kversion.name)
- kfree(kversion.name);
- if (kversion.date)
- kfree(kversion.date);
- if (kversion.desc)
- kfree(kversion.desc);
+ kfree(kversion.name);
+ kfree(kversion.date);
+ kfree(kversion.desc);
return ret;
}
@@ -166,9 +163,7 @@ static int drm32_getsetunique(unsigned int fd, unsigned int cmd, unsigned long a
ret = -EFAULT;
}
- if (karg.unique != NULL)
- kfree(karg.unique);
-
+ kfree(karg.unique);
return ret;
}
@@ -265,7 +260,6 @@ static int drm32_info_bufs(unsigned int fd, unsigned int cmd, unsigned long arg)
}
kfree(karg.list);
-
return ret;
}
@@ -305,7 +299,6 @@ static int drm32_free_bufs(unsigned int fd, unsigned int cmd, unsigned long arg)
out:
kfree(karg.list);
-
return ret;
}
@@ -494,15 +487,10 @@ static int drm32_dma(unsigned int fd, unsigned int cmd, unsigned long arg)
}
out:
- if (karg.send_indices)
- kfree(karg.send_indices);
- if (karg.send_sizes)
- kfree(karg.send_sizes);
- if (karg.request_indices)
- kfree(karg.request_indices);
- if (karg.request_sizes)
- kfree(karg.request_sizes);
-
+ kfree(karg.send_indices);
+ kfree(karg.send_sizes);
+ kfree(karg.request_indices);
+ kfree(karg.request_sizes);
return ret;
}
@@ -555,9 +543,7 @@ static int drm32_res_ctx(unsigned int fd, unsigned int cmd, unsigned long arg)
ret = -EFAULT;
}
- if (karg.contexts)
- kfree(karg.contexts);
-
+ kfree(karg.contexts);
return ret;
}
@@ -575,11 +561,6 @@ IOCTL_TABLE_START
#define DECLARES
#include "compat_ioctl.c"
-/* Might be moved to compat_ioctl.h with some ifdefs... */
-COMPATIBLE_IOCTL(TIOCSTART)
-COMPATIBLE_IOCTL(TIOCSTOP)
-COMPATIBLE_IOCTL(TIOCSLTC)
-
/* PA-specific ioctls */
COMPATIBLE_IOCTL(PA_PERF_ON)
COMPATIBLE_IOCTL(PA_PERF_OFF)
diff --git a/arch/parisc/kernel/pacache.S b/arch/parisc/kernel/pacache.S
index 77e03bc0f935..9534ee17b9be 100644
--- a/arch/parisc/kernel/pacache.S
+++ b/arch/parisc/kernel/pacache.S
@@ -26,7 +26,7 @@
* can be used.
*/
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
#define ADDIB addib,*
#define CMPB cmpb,*
#define ANDCM andcm,*
@@ -40,8 +40,10 @@
.level 2.0
#endif
-#include <asm/assembly.h>
+#include <linux/config.h>
+
#include <asm/psw.h>
+#include <asm/assembly.h>
#include <asm/pgtable.h>
#include <asm/cache.h>
@@ -62,32 +64,23 @@ flush_tlb_all_local:
* to happen in real mode with all interruptions disabled.
*/
- /*
- * Once again, we do the rfi dance ... some day we need examine
- * all of our uses of this type of code and see what can be
- * consolidated.
- */
-
- rsm PSW_SM_I, %r19 /* relied upon translation! PA 2.0 Arch. F-5 */
+ /* pcxt_ssm_bug - relied upon translation! PA 2.0 Arch. F-4 and F-5 */
+ rsm PSW_SM_I, %r19 /* save I-bit state */
+ load32 PA(1f), %r1
nop
nop
nop
nop
nop
- nop
- nop
-
- rsm PSW_SM_Q, %r0 /* Turn off Q bit to load iia queue */
- ldil L%REAL_MODE_PSW, %r1
- ldo R%REAL_MODE_PSW(%r1), %r1
- mtctl %r1, %cr22
+
+ rsm PSW_SM_Q, %r0 /* prep to load iia queue */
mtctl %r0, %cr17 /* Clear IIASQ tail */
mtctl %r0, %cr17 /* Clear IIASQ head */
- ldil L%PA(1f), %r1
- ldo R%PA(1f)(%r1), %r1
mtctl %r1, %cr18 /* IIAOQ head */
ldo 4(%r1), %r1
mtctl %r1, %cr18 /* IIAOQ tail */
+ load32 REAL_MODE_PSW, %r1
+ mtctl %r1, %ipsw
rfi
nop
@@ -178,29 +171,36 @@ fdtonemiddle: /* Loop if LOOP = 1 */
ADDIB> -1, %r22, fdtoneloop /* Outer loop count decr */
add %r21, %r20, %r20 /* increment space */
-fdtdone:
- /* Switch back to virtual mode */
+fdtdone:
+ /*
+ * Switch back to virtual mode
+ */
+ /* pcxt_ssm_bug */
+ rsm PSW_SM_I, %r0
+ load32 2f, %r1
+ nop
+ nop
+ nop
+ nop
+ nop
- rsm PSW_SM_Q, %r0 /* clear Q bit to load iia queue */
- ldil L%KERNEL_PSW, %r1
- ldo R%KERNEL_PSW(%r1), %r1
- or %r1, %r19, %r1 /* Set I bit if set on entry */
- mtctl %r1, %cr22
+ rsm PSW_SM_Q, %r0 /* prep to load iia queue */
mtctl %r0, %cr17 /* Clear IIASQ tail */
mtctl %r0, %cr17 /* Clear IIASQ head */
- ldil L%(2f), %r1
- ldo R%(2f)(%r1), %r1
mtctl %r1, %cr18 /* IIAOQ head */
ldo 4(%r1), %r1
mtctl %r1, %cr18 /* IIAOQ tail */
+ load32 KERNEL_PSW, %r1
+ or %r1, %r19, %r1 /* I-bit to state on entry */
+ mtctl %r1, %ipsw /* restore I-bit (entire PSW) */
rfi
nop
2: bv %r0(%r2)
nop
- .exit
+ .exit
.procend
.export flush_instruction_cache_local,code
@@ -227,7 +227,7 @@ flush_instruction_cache_local:
fimanyloop: /* Loop if LOOP >= 2 */
ADDIB> -1, %r31, fimanyloop /* Adjusted inner loop decr */
- fice 0(%sr1, %arg0)
+ fice %r0(%sr1, %arg0)
fice,m %arg1(%sr1, %arg0) /* Last fice and addr adjust */
movb,tr %arg3, %r31, fimanyloop /* Re-init inner loop count */
ADDIB<=,n -1, %arg2, fisync /* Outer loop decr */
@@ -238,7 +238,7 @@ fioneloop: /* Loop if LOOP = 1 */
fisync:
sync
- mtsm %r22
+ mtsm %r22 /* restore I-bit */
bv %r0(%r2)
nop
.exit
@@ -269,7 +269,7 @@ flush_data_cache_local:
fdmanyloop: /* Loop if LOOP >= 2 */
ADDIB> -1, %r31, fdmanyloop /* Adjusted inner loop decr */
- fdce 0(%sr1, %arg0)
+ fdce %r0(%sr1, %arg0)
fdce,m %arg1(%sr1, %arg0) /* Last fdce and addr adjust */
movb,tr %arg3, %r31, fdmanyloop /* Re-init inner loop count */
ADDIB<=,n -1, %arg2, fdsync /* Outer loop decr */
@@ -281,7 +281,7 @@ fdoneloop: /* Loop if LOOP = 1 */
fdsync:
syncdma
sync
- mtsm %r22
+ mtsm %r22 /* restore I-bit */
bv %r0(%r2)
nop
.exit
@@ -296,7 +296,7 @@ copy_user_page_asm:
.callinfo NO_CALLS
.entry
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
/* PA8x00 CPUs can consume 2 loads or 1 store per cycle.
* Unroll the loop by hand and arrange insn appropriately.
* GCC probably can do this just as well.
@@ -351,7 +351,11 @@ copy_user_page_asm:
std %r22, 120(%r26)
ldo 128(%r26), %r26
- ADDIB> -1, %r1, 1b /* bundle 10 */
+ /* conditional branches nullify on forward taken branch, and on
+ * non-taken backward branch. Note that .+4 is a backwards branch.
+ * The ldd should only get executed if the branch is taken.
+ */
+ ADDIB>,n -1, %r1, 1b /* bundle 10 */
ldd 0(%r25), %r19 /* start next loads */
#else
@@ -363,10 +367,10 @@ copy_user_page_asm:
* the full 64 bit register values on interrupt, we can't
* use ldd/std on a 32 bit kernel.
*/
+ ldw 0(%r25), %r19
ldi 64, %r1 /* PAGE_SIZE/64 == 64 */
1:
- ldw 0(%r25), %r19
ldw 4(%r25), %r20
ldw 8(%r25), %r21
ldw 12(%r25), %r22
@@ -396,11 +400,12 @@ copy_user_page_asm:
ldw 60(%r25), %r22
stw %r19, 48(%r26)
stw %r20, 52(%r26)
+ ldo 64(%r25), %r25
stw %r21, 56(%r26)
stw %r22, 60(%r26)
ldo 64(%r26), %r26
- ADDIB> -1, %r1, 1b
- ldo 64(%r25), %r25
+ ADDIB>,n -1, %r1, 1b
+ ldw 0(%r25), %r19
#endif
bv %r0(%r2)
nop
@@ -456,7 +461,7 @@ copy_user_page_asm:
sub %r25, %r1, %r23 /* move physical addr into non shadowed reg */
ldil L%(TMPALIAS_MAP_START), %r28
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
extrd,u %r26,56,32, %r26 /* convert phys addr to tlb insert format */
extrd,u %r23,56,32, %r23 /* convert phys addr to tlb insert format */
depd %r24,63,22, %r28 /* Form aliased virtual address 'to' */
@@ -543,7 +548,7 @@ __clear_user_page_asm:
tophys_r1 %r26
ldil L%(TMPALIAS_MAP_START), %r28
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
#if (TMPALIAS_MAP_START >= 0x80000000)
depdi 0, 31,32, %r28 /* clear any sign extension */
#endif
@@ -560,7 +565,7 @@ __clear_user_page_asm:
pdtlb 0(%r28)
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
ldi 32, %r1 /* PAGE_SIZE/128 == 32 */
/* PREFETCH (Write) has not (yet) been proven to help here */
@@ -585,7 +590,7 @@ __clear_user_page_asm:
ADDIB> -1, %r1, 1b
ldo 128(%r28), %r28
-#else /* ! __LP64 */
+#else /* ! CONFIG_64BIT */
ldi 64, %r1 /* PAGE_SIZE/64 == 64 */
@@ -608,7 +613,7 @@ __clear_user_page_asm:
stw %r0, 60(%r28)
ADDIB> -1, %r1, 1b
ldo 64(%r28), %r28
-#endif /* __LP64 */
+#endif /* CONFIG_64BIT */
bv %r0(%r2)
nop
@@ -626,7 +631,7 @@ flush_kernel_dcache_page:
ldil L%dcache_stride, %r1
ldw R%dcache_stride(%r1), %r23
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
depdi,z 1, 63-PAGE_SHIFT,1, %r25
#else
depwi,z 1, 31-PAGE_SHIFT,1, %r25
@@ -670,7 +675,7 @@ flush_user_dcache_page:
ldil L%dcache_stride, %r1
ldw R%dcache_stride(%r1), %r23
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
depdi,z 1,63-PAGE_SHIFT,1, %r25
#else
depwi,z 1,31-PAGE_SHIFT,1, %r25
@@ -714,7 +719,7 @@ flush_user_icache_page:
ldil L%dcache_stride, %r1
ldw R%dcache_stride(%r1), %r23
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
depdi,z 1, 63-PAGE_SHIFT,1, %r25
#else
depwi,z 1, 31-PAGE_SHIFT,1, %r25
@@ -759,7 +764,7 @@ purge_kernel_dcache_page:
ldil L%dcache_stride, %r1
ldw R%dcache_stride(%r1), %r23
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
depdi,z 1, 63-PAGE_SHIFT,1, %r25
#else
depwi,z 1, 31-PAGE_SHIFT,1, %r25
@@ -807,7 +812,7 @@ flush_alias_page:
tophys_r1 %r26
ldil L%(TMPALIAS_MAP_START), %r28
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
extrd,u %r26, 56,32, %r26 /* convert phys addr to tlb insert format */
depd %r25, 63,22, %r28 /* Form aliased virtual address 'to' */
depdi 0, 63,12, %r28 /* Clear any offset bits */
@@ -824,7 +829,7 @@ flush_alias_page:
ldil L%dcache_stride, %r1
ldw R%dcache_stride(%r1), %r23
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
depdi,z 1, 63-PAGE_SHIFT,1, %r29
#else
depwi,z 1, 31-PAGE_SHIFT,1, %r29
@@ -935,7 +940,7 @@ flush_kernel_icache_page:
ldil L%icache_stride, %r1
ldw R%icache_stride(%r1), %r23
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
depdi,z 1, 63-PAGE_SHIFT,1, %r25
#else
depwi,z 1, 31-PAGE_SHIFT,1, %r25
@@ -944,23 +949,23 @@ flush_kernel_icache_page:
sub %r25, %r23, %r25
-1: fic,m %r23(%r26)
- fic,m %r23(%r26)
- fic,m %r23(%r26)
- fic,m %r23(%r26)
- fic,m %r23(%r26)
- fic,m %r23(%r26)
- fic,m %r23(%r26)
- fic,m %r23(%r26)
- fic,m %r23(%r26)
- fic,m %r23(%r26)
- fic,m %r23(%r26)
- fic,m %r23(%r26)
- fic,m %r23(%r26)
- fic,m %r23(%r26)
- fic,m %r23(%r26)
+1: fic,m %r23(%sr4, %r26)
+ fic,m %r23(%sr4, %r26)
+ fic,m %r23(%sr4, %r26)
+ fic,m %r23(%sr4, %r26)
+ fic,m %r23(%sr4, %r26)
+ fic,m %r23(%sr4, %r26)
+ fic,m %r23(%sr4, %r26)
+ fic,m %r23(%sr4, %r26)
+ fic,m %r23(%sr4, %r26)
+ fic,m %r23(%sr4, %r26)
+ fic,m %r23(%sr4, %r26)
+ fic,m %r23(%sr4, %r26)
+ fic,m %r23(%sr4, %r26)
+ fic,m %r23(%sr4, %r26)
+ fic,m %r23(%sr4, %r26)
CMPB<< %r26, %r25, 1b
- fic,m %r23(%r26)
+ fic,m %r23(%sr4, %r26)
sync
bv %r0(%r2)
@@ -982,17 +987,18 @@ flush_kernel_icache_range_asm:
ANDCM %r26, %r21, %r26
1: CMPB<<,n %r26, %r25, 1b
- fic,m %r23(%r26)
+ fic,m %r23(%sr4, %r26)
sync
bv %r0(%r2)
nop
.exit
-
.procend
- .align 128
-
+ /* align should cover use of rfi in disable_sr_hashing_asm and
+ * srdis_done.
+ */
+ .align 256
.export disable_sr_hashing_asm,code
disable_sr_hashing_asm:
@@ -1000,28 +1006,26 @@ disable_sr_hashing_asm:
.callinfo NO_CALLS
.entry
- /* Switch to real mode */
-
- ssm 0, %r0 /* relied upon translation! */
- nop
- nop
+ /*
+ * Switch to real mode
+ */
+ /* pcxt_ssm_bug */
+ rsm PSW_SM_I, %r0
+ load32 PA(1f), %r1
nop
nop
nop
nop
nop
-
- rsm (PSW_SM_Q|PSW_SM_I), %r0 /* disable Q&I to load the iia queue */
- ldil L%REAL_MODE_PSW, %r1
- ldo R%REAL_MODE_PSW(%r1), %r1
- mtctl %r1, %cr22
+
+ rsm PSW_SM_Q, %r0 /* prep to load iia queue */
mtctl %r0, %cr17 /* Clear IIASQ tail */
mtctl %r0, %cr17 /* Clear IIASQ head */
- ldil L%PA(1f), %r1
- ldo R%PA(1f)(%r1), %r1
mtctl %r1, %cr18 /* IIAOQ head */
ldo 4(%r1), %r1
mtctl %r1, %cr18 /* IIAOQ tail */
+ load32 REAL_MODE_PSW, %r1
+ mtctl %r1, %ipsw
rfi
nop
@@ -1053,27 +1057,31 @@ srdis_pcxl:
srdis_pa20:
- /* Disable Space Register Hashing for PCXU,PCXU+,PCXW,PCXW+ */
+ /* Disable Space Register Hashing for PCXU,PCXU+,PCXW,PCXW+,PCXW2 */
.word 0x144008bc /* mfdiag %dr2, %r28 */
depdi 0, 54,1, %r28 /* clear DIAG_SPHASH_ENAB (bit 54) */
.word 0x145c1840 /* mtdiag %r28, %dr2 */
-srdis_done:
+srdis_done:
/* Switch back to virtual mode */
+ rsm PSW_SM_I, %r0 /* prep to load iia queue */
+ load32 2f, %r1
+ nop
+ nop
+ nop
+ nop
+ nop
- rsm PSW_SM_Q, %r0 /* clear Q bit to load iia queue */
- ldil L%KERNEL_PSW, %r1
- ldo R%KERNEL_PSW(%r1), %r1
- mtctl %r1, %cr22
+ rsm PSW_SM_Q, %r0 /* prep to load iia queue */
mtctl %r0, %cr17 /* Clear IIASQ tail */
mtctl %r0, %cr17 /* Clear IIASQ head */
- ldil L%(2f), %r1
- ldo R%(2f)(%r1), %r1
mtctl %r1, %cr18 /* IIAOQ head */
ldo 4(%r1), %r1
mtctl %r1, %cr18 /* IIAOQ tail */
+ load32 KERNEL_PSW, %r1
+ mtctl %r1, %ipsw
rfi
nop
diff --git a/arch/parisc/kernel/pci-dma.c b/arch/parisc/kernel/pci-dma.c
index 368cc095c99f..f94a02ef3d95 100644
--- a/arch/parisc/kernel/pci-dma.c
+++ b/arch/parisc/kernel/pci-dma.c
@@ -31,7 +31,7 @@
#include <asm/page.h> /* get_order */
#include <asm/pgalloc.h>
#include <asm/uaccess.h>
-
+#include <asm/tlbflush.h> /* for purge_tlb_*() macros */
static struct proc_dir_entry * proc_gsc_root = NULL;
static int pcxl_proc_info(char *buffer, char **start, off_t offset, int length);
@@ -114,7 +114,7 @@ static inline int map_pmd_uncached(pmd_t * pmd, unsigned long vaddr,
if (end > PGDIR_SIZE)
end = PGDIR_SIZE;
do {
- pte_t * pte = pte_alloc_kernel(&init_mm, pmd, vaddr);
+ pte_t * pte = pte_alloc_kernel(pmd, vaddr);
if (!pte)
return -ENOMEM;
if (map_pte_uncached(pte, orig_vaddr, end - vaddr, paddr_ptr))
@@ -333,23 +333,33 @@ pcxl_free_range(unsigned long vaddr, size_t size)
static int __init
pcxl_dma_init(void)
{
- if (pcxl_dma_start == 0)
- return 0;
+ if (pcxl_dma_start == 0)
+ return 0;
- spin_lock_init(&pcxl_res_lock);
- pcxl_res_size = PCXL_DMA_MAP_SIZE >> (PAGE_SHIFT + 3);
- pcxl_res_hint = 0;
- pcxl_res_map = (char *)__get_free_pages(GFP_KERNEL,
+ spin_lock_init(&pcxl_res_lock);
+ pcxl_res_size = PCXL_DMA_MAP_SIZE >> (PAGE_SHIFT + 3);
+ pcxl_res_hint = 0;
+ pcxl_res_map = (char *)__get_free_pages(GFP_KERNEL,
get_order(pcxl_res_size));
- memset(pcxl_res_map, 0, pcxl_res_size);
- proc_gsc_root = proc_mkdir("gsc", 0);
- create_proc_info_entry("dino", 0, proc_gsc_root, pcxl_proc_info);
- return 0;
+ memset(pcxl_res_map, 0, pcxl_res_size);
+ proc_gsc_root = proc_mkdir("gsc", 0);
+ if (!proc_gsc_root)
+ printk(KERN_WARNING
+ "pcxl_dma_init: Unable to create gsc /proc dir entry\n");
+ else {
+ struct proc_dir_entry* ent;
+ ent = create_proc_info_entry("pcxl_dma", 0,
+ proc_gsc_root, pcxl_proc_info);
+ if (!ent)
+ printk(KERN_WARNING
+ "pci-dma.c: Unable to create pcxl_dma /proc entry.\n");
+ }
+ return 0;
}
__initcall(pcxl_dma_init);
-static void * pa11_dma_alloc_consistent (struct device *dev, size_t size, dma_addr_t *dma_handle, int flag)
+static void * pa11_dma_alloc_consistent (struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t flag)
{
unsigned long vaddr;
unsigned long paddr;
@@ -502,13 +512,13 @@ struct hppa_dma_ops pcxl_dma_ops = {
};
static void *fail_alloc_consistent(struct device *dev, size_t size,
- dma_addr_t *dma_handle, int flag)
+ dma_addr_t *dma_handle, gfp_t flag)
{
return NULL;
}
static void *pa11_dma_alloc_noncoherent(struct device *dev, size_t size,
- dma_addr_t *dma_handle, int flag)
+ dma_addr_t *dma_handle, gfp_t flag)
{
void *addr = NULL;
@@ -545,16 +555,16 @@ struct hppa_dma_ops pcx_dma_ops = {
static int pcxl_proc_info(char *buf, char **start, off_t offset, int len)
{
+#if 0
u_long i = 0;
unsigned long *res_ptr = (u_long *)pcxl_res_map;
- unsigned long total_pages = pcxl_res_size << 3; /* 8 bits per byte */
+#endif
+ unsigned long total_pages = pcxl_res_size << 3; /* 8 bits per byte */
- sprintf(buf, "\nDMA Mapping Area size : %d bytes (%d pages)\n",
- PCXL_DMA_MAP_SIZE,
- (pcxl_res_size << 3) ); /* 1 bit per page */
+ sprintf(buf, "\nDMA Mapping Area size : %d bytes (%ld pages)\n",
+ PCXL_DMA_MAP_SIZE, total_pages);
- sprintf(buf, "%sResource bitmap : %d bytes (%d pages)\n",
- buf, pcxl_res_size, pcxl_res_size << 3); /* 8 bits per byte */
+ sprintf(buf, "%sResource bitmap : %d bytes\n", buf, pcxl_res_size);
strcat(buf, " total: free: used: % used:\n");
sprintf(buf, "%sblocks %8d %8ld %8ld %8ld%%\n", buf, pcxl_res_size,
@@ -564,7 +574,8 @@ static int pcxl_proc_info(char *buf, char **start, off_t offset, int len)
sprintf(buf, "%spages %8ld %8ld %8ld %8ld%%\n", buf, total_pages,
total_pages - pcxl_used_pages, pcxl_used_pages,
(pcxl_used_pages * 100 / total_pages));
-
+
+#if 0
strcat(buf, "\nResource bitmap:");
for(; i < (pcxl_res_size / sizeof(u_long)); ++i, ++res_ptr) {
@@ -572,6 +583,7 @@ static int pcxl_proc_info(char *buf, char **start, off_t offset, int len)
strcat(buf,"\n ");
sprintf(buf, "%s %08lx", buf, *res_ptr);
}
+#endif
strcat(buf, "\n");
return strlen(buf);
}
diff --git a/arch/parisc/kernel/pci.c b/arch/parisc/kernel/pci.c
index e6a891a0cad0..88cba49c5301 100644
--- a/arch/parisc/kernel/pci.c
+++ b/arch/parisc/kernel/pci.c
@@ -202,7 +202,8 @@ static void
pcibios_link_hba_resources( struct resource *hba_res, struct resource *r)
{
if (!r->parent) {
- printk(KERN_EMERG "PCI: Tell willy he's wrong\n");
+ printk(KERN_EMERG "PCI: resource not parented! [%lx-%lx]\n",
+ r->start, r->end);
r->parent = hba_res;
/* reverse link is harder *sigh* */
diff --git a/arch/parisc/kernel/pdc_cons.c b/arch/parisc/kernel/pdc_cons.c
index 01f676d1673b..215d78c87bc5 100644
--- a/arch/parisc/kernel/pdc_cons.c
+++ b/arch/parisc/kernel/pdc_cons.c
@@ -41,7 +41,7 @@
/* Define EARLY_BOOTUP_DEBUG to debug kernel related boot problems.
* On production kernels EARLY_BOOTUP_DEBUG should be undefined. */
-#undef EARLY_BOOTUP_DEBUG
+#define EARLY_BOOTUP_DEBUG
#include <linux/config.h>
@@ -49,14 +49,8 @@
#include <linux/console.h>
#include <linux/string.h>
#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/sched.h>
-#include <linux/interrupt.h>
#include <linux/major.h>
#include <linux/tty.h>
-#include <asm/page.h>
-#include <asm/types.h>
-#include <asm/system.h>
#include <asm/pdc.h> /* for iodc_call() proto and friends */
@@ -96,7 +90,6 @@ static int pdc_console_setup(struct console *co, char *options)
}
#if defined(CONFIG_PDC_CONSOLE)
-#define PDC_CONSOLE_DEVICE pdc_console_device
static struct tty_driver * pdc_console_device (struct console *c, int *index)
{
extern struct tty_driver console_driver;
@@ -104,22 +97,19 @@ static struct tty_driver * pdc_console_device (struct console *c, int *index)
return &console_driver;
}
#else
-#define PDC_CONSOLE_DEVICE NULL
+#define pdc_console_device NULL
#endif
static struct console pdc_cons = {
.name = "ttyB",
.write = pdc_console_write,
- .device = PDC_CONSOLE_DEVICE,
+ .device = pdc_console_device,
.setup = pdc_console_setup,
- .flags = CON_BOOT|CON_PRINTBUFFER|CON_ENABLED,
+ .flags = CON_BOOT | CON_PRINTBUFFER | CON_ENABLED,
.index = -1,
};
static int pdc_console_initialized;
-extern unsigned long con_start; /* kernel/printk.c */
-extern unsigned long log_end; /* kernel/printk.c */
-
static void pdc_console_init_force(void)
{
@@ -146,27 +136,11 @@ void __init pdc_console_init(void)
}
-/* Unregister the pdc console with the printk console layer */
-void pdc_console_die(void)
-{
- if (!pdc_console_initialized)
- return;
- --pdc_console_initialized;
-
- printk(KERN_INFO "Switching from PDC console\n");
-
- /* Don't repeat what we've already printed */
- con_start = log_end;
-
- unregister_console(&pdc_cons);
-}
-
-
/*
* Used for emergencies. Currently only used if an HPMC occurs. If an
* HPMC occurs, it is possible that the current console may not be
- * properly initialed after the PDC IO reset. This routine unregisters all
- * of the current consoles, reinitializes the pdc console and
+ * properly initialised after the PDC IO reset. This routine unregisters
+ * all of the current consoles, reinitializes the pdc console and
* registers it.
*/
@@ -177,13 +151,13 @@ void pdc_console_restart(void)
if (pdc_console_initialized)
return;
+ /* If we've already seen the output, don't bother to print it again */
+ if (console_drivers != NULL)
+ pdc_cons.flags &= ~CON_PRINTBUFFER;
+
while ((console = console_drivers) != NULL)
unregister_console(console_drivers);
- /* Don't repeat what we've already printed */
- con_start = log_end;
-
/* force registering the pdc console */
pdc_console_init_force();
}
-
diff --git a/arch/parisc/kernel/perf.c b/arch/parisc/kernel/perf.c
index b3ad0a505b87..44670d6e06f4 100644
--- a/arch/parisc/kernel/perf.c
+++ b/arch/parisc/kernel/perf.c
@@ -746,7 +746,8 @@ static int perf_write_image(uint64_t *memaddr)
uint64_t *bptr;
uint32_t dwords;
uint32_t *intrigue_rdr;
- uint64_t *intrigue_bitmask, tmp64, proc_hpa;
+ uint64_t *intrigue_bitmask, tmp64;
+ void __iomem *runway;
struct rdr_tbl_ent *tentry;
int i;
@@ -798,15 +799,16 @@ static int perf_write_image(uint64_t *memaddr)
return -1;
}
- proc_hpa = cpu_device->hpa;
+ runway = ioremap(cpu_device->hpa.start, 4096);
/* Merge intrigue bits into Runway STATUS 0 */
- tmp64 = __raw_readq(proc_hpa + RUNWAY_STATUS) & 0xffecfffffffffffful;
- __raw_writeq(tmp64 | (*memaddr++ & 0x0013000000000000ul), proc_hpa + RUNWAY_STATUS);
+ tmp64 = __raw_readq(runway + RUNWAY_STATUS) & 0xffecfffffffffffful;
+ __raw_writeq(tmp64 | (*memaddr++ & 0x0013000000000000ul),
+ runway + RUNWAY_STATUS);
/* Write RUNWAY DEBUG registers */
for (i = 0; i < 8; i++) {
- __raw_writeq(*memaddr++, proc_hpa + RUNWAY_DEBUG + i);
+ __raw_writeq(*memaddr++, runway + RUNWAY_DEBUG);
}
return 0;
diff --git a/arch/parisc/kernel/process.c b/arch/parisc/kernel/process.c
index 46b759385115..fee4f1f09adc 100644
--- a/arch/parisc/kernel/process.c
+++ b/arch/parisc/kernel/process.c
@@ -9,7 +9,7 @@
* Copyright (C) 2000-2003 Paul Bame <bame at parisc-linux.org>
* Copyright (C) 2000 Philipp Rumpf <prumpf with tux.org>
* Copyright (C) 2000 David Kennedy <dkennedy with linuxcare.com>
- * Copyright (C) 2000 Richard Hirst <rhirst with parisc-lixux.org>
+ * Copyright (C) 2000 Richard Hirst <rhirst with parisc-linux.org>
* Copyright (C) 2000 Grant Grundler <grundler with parisc-linux.org>
* Copyright (C) 2001 Alan Modra <amodra at parisc-linux.org>
* Copyright (C) 2001-2002 Ryan Bradetich <rbrad at parisc-linux.org>
@@ -88,11 +88,15 @@ void default_idle(void)
*/
void cpu_idle(void)
{
+ set_thread_flag(TIF_POLLING_NRFLAG);
+
/* endless idle loop with no priority at all */
while (1) {
while (!need_resched())
barrier();
+ preempt_enable_no_resched();
schedule();
+ preempt_disable();
check_pgt_cache();
}
}
@@ -245,7 +249,17 @@ int
sys_clone(unsigned long clone_flags, unsigned long usp,
struct pt_regs *regs)
{
- int __user *user_tid = (int __user *)regs->gr[26];
+ /* Arugments from userspace are:
+ r26 = Clone flags.
+ r25 = Child stack.
+ r24 = parent_tidptr.
+ r23 = Is the TLS storage descriptor
+ r22 = child_tidptr
+
+ However, these last 3 args are only examined
+ if the proper flags are set. */
+ int __user *child_tidptr;
+ int __user *parent_tidptr;
/* usp must be word aligned. This also prevents users from
* passing in the value 1 (which is the signal for a special
@@ -253,10 +267,20 @@ sys_clone(unsigned long clone_flags, unsigned long usp,
usp = ALIGN(usp, 4);
/* A zero value for usp means use the current stack */
- if(usp == 0)
- usp = regs->gr[30];
+ if (usp == 0)
+ usp = regs->gr[30];
+
+ if (clone_flags & CLONE_PARENT_SETTID)
+ parent_tidptr = (int __user *)regs->gr[24];
+ else
+ parent_tidptr = NULL;
+
+ if (clone_flags & (CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID))
+ child_tidptr = (int __user *)regs->gr[22];
+ else
+ child_tidptr = NULL;
- return do_fork(clone_flags, usp, regs, 0, user_tid, NULL);
+ return do_fork(clone_flags, usp, regs, 0, parent_tidptr, child_tidptr);
}
int
@@ -332,6 +356,10 @@ copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
} else {
cregs->kpc = (unsigned long) &child_return;
}
+ /* Setup thread TLS area from the 4th parameter in clone */
+ if (clone_flags & CLONE_SETTLS)
+ cregs->cr27 = pregs->gr[23];
+
}
return 0;
diff --git a/arch/parisc/kernel/processor.c b/arch/parisc/kernel/processor.c
index 13b721cb9f55..4f5bbcf1f5a4 100644
--- a/arch/parisc/kernel/processor.c
+++ b/arch/parisc/kernel/processor.c
@@ -92,7 +92,7 @@ static int __init processor_probe(struct parisc_device *dev)
* May get overwritten by PAT code.
*/
cpuid = boot_cpu_data.cpu_count;
- txn_addr = dev->hpa; /* for legacy PDC */
+ txn_addr = dev->hpa.start; /* for legacy PDC */
#ifdef __LP64__
if (is_pdc_pat()) {
@@ -122,7 +122,7 @@ static int __init processor_probe(struct parisc_device *dev)
* boot time (ie shutdown a CPU from an OS perspective).
*/
/* get the cpu number */
- status = pdc_pat_cpu_get_number(&cpu_info, dev->hpa);
+ status = pdc_pat_cpu_get_number(&cpu_info, dev->hpa.start);
BUG_ON(PDC_OK != status);
@@ -130,7 +130,7 @@ static int __init processor_probe(struct parisc_device *dev)
printk(KERN_WARNING "IGNORING CPU at 0x%x,"
" cpu_slot_id > NR_CPUS"
" (%ld > %d)\n",
- dev->hpa, cpu_info.cpu_num, NR_CPUS);
+ dev->hpa.start, cpu_info.cpu_num, NR_CPUS);
/* Ignore CPU since it will only crash */
boot_cpu_data.cpu_count--;
return 1;
@@ -149,7 +149,7 @@ static int __init processor_probe(struct parisc_device *dev)
p->loops_per_jiffy = loops_per_jiffy;
p->dev = dev; /* Save IODC data in case we need it */
- p->hpa = dev->hpa; /* save CPU hpa */
+ p->hpa = dev->hpa.start; /* save CPU hpa */
p->cpuid = cpuid; /* save CPU id */
p->txn_addr = txn_addr; /* save CPU IRQ address */
#ifdef CONFIG_SMP
diff --git a/arch/parisc/kernel/ptrace.c b/arch/parisc/kernel/ptrace.c
index f3428e5e86fb..b6fe202a620d 100644
--- a/arch/parisc/kernel/ptrace.c
+++ b/arch/parisc/kernel/ptrace.c
@@ -78,52 +78,13 @@ void ptrace_disable(struct task_struct *child)
pa_psw(child)->l = 0;
}
-long sys_ptrace(long request, pid_t pid, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request, long addr, long data)
{
- struct task_struct *child;
long ret;
#ifdef DEBUG_PTRACE
long oaddr=addr, odata=data;
#endif
- lock_kernel();
- ret = -EPERM;
- if (request == PTRACE_TRACEME) {
- /* are we already being traced? */
- if (current->ptrace & PT_PTRACED)
- goto out;
-
- ret = security_ptrace(current->parent, current);
- if (ret)
- goto out;
-
- /* set the ptrace bit in the process flags. */
- current->ptrace |= PT_PTRACED;
- ret = 0;
- goto out;
- }
-
- ret = -ESRCH;
- read_lock(&tasklist_lock);
- child = find_task_by_pid(pid);
- if (child)
- get_task_struct(child);
- read_unlock(&tasklist_lock);
- if (!child)
- goto out;
- ret = -EPERM;
- if (pid == 1) /* no messing around with init! */
- goto out_tsk;
-
- if (request == PTRACE_ATTACH) {
- ret = ptrace_attach(child);
- goto out_tsk;
- }
-
- ret = ptrace_check_attach(child, request == PTRACE_KILL);
- if (ret < 0)
- goto out_tsk;
-
switch (request) {
case PTRACE_PEEKTEXT: /* read word at location addr. */
case PTRACE_PEEKDATA: {
@@ -383,11 +344,11 @@ long sys_ptrace(long request, pid_t pid, long addr, long data)
case PTRACE_GETEVENTMSG:
ret = put_user(child->ptrace_message, (unsigned int __user *) data);
- goto out_tsk;
+ goto out;
default:
ret = ptrace_request(child, request, addr, data);
- goto out_tsk;
+ goto out;
}
out_wake_notrap:
@@ -396,10 +357,7 @@ out_wake:
wake_up_process(child);
ret = 0;
out_tsk:
- put_task_struct(child);
-out:
- unlock_kernel();
- DBG("sys_ptrace(%ld, %d, %lx, %lx) returning %ld\n",
+ DBG("arch_ptrace(%ld, %d, %lx, %lx) returning %ld\n",
request, pid, oaddr, odata, ret);
return ret;
}
diff --git a/arch/parisc/kernel/real2.S b/arch/parisc/kernel/real2.S
index 8dd5defb7316..8c2859cca77e 100644
--- a/arch/parisc/kernel/real2.S
+++ b/arch/parisc/kernel/real2.S
@@ -7,8 +7,10 @@
* Copyright (C) 2000 Hewlett Packard (Paul Bame bame@puffin.external.hp.com)
*
*/
-#include <asm/assembly.h>
+#include <linux/config.h>
+
#include <asm/psw.h>
+#include <asm/assembly.h>
.section .bss
.export real_stack
@@ -20,7 +22,7 @@ real32_stack:
real64_stack:
.block 8192
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
# define REG_SZ 8
#else
# define REG_SZ 4
@@ -50,7 +52,7 @@ save_cr_end:
real32_call_asm:
STREG %rp, -RP_OFFSET(%sp) /* save RP */
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
callee_save
ldo 2*REG_SZ(%sp), %sp /* room for a couple more saves */
STREG %r27, -1*REG_SZ(%sp)
@@ -77,7 +79,7 @@ real32_call_asm:
b,l save_control_regs,%r2 /* modifies r1, r2, r28 */
nop
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
rsm PSW_SM_W, %r0 /* go narrow */
#endif
@@ -85,7 +87,7 @@ real32_call_asm:
bv 0(%r31)
nop
ric_ret:
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
ssm PSW_SM_W, %r0 /* go wide */
#endif
/* restore CRs before going virtual in case we page fault */
@@ -97,7 +99,7 @@ ric_ret:
tovirt_r1 %sp
LDREG -REG_SZ(%sp), %sp /* restore SP */
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
LDREG -1*REG_SZ(%sp), %r27
LDREG -2*REG_SZ(%sp), %r29
ldo -2*REG_SZ(%sp), %sp
@@ -143,24 +145,21 @@ restore_control_regs:
/* rfi_virt2real() and rfi_real2virt() could perhaps be adapted for
* more general-purpose use by the several places which need RFIs
*/
- .align 128
.text
+ .align 128
rfi_virt2real:
/* switch to real mode... */
- ssm 0,0 /* See "relied upon translation" */
- nop /* PA 2.0 Arch. F-5 */
- nop
- nop
+ rsm PSW_SM_I,%r0
+ load32 PA(rfi_v2r_1), %r1
nop
nop
nop
nop
nop
- rsm (PSW_SM_Q|PSW_SM_I),%r0 /* disable Q & I bits to load iia queue */
+ rsm PSW_SM_Q,%r0 /* disable Q & I bits to load iia queue */
mtctl %r0, %cr17 /* Clear IIASQ tail */
mtctl %r0, %cr17 /* Clear IIASQ head */
- load32 PA(rfi_v2r_1), %r1
mtctl %r1, %cr18 /* IIAOQ head */
ldo 4(%r1), %r1
mtctl %r1, %cr18 /* IIAOQ tail */
@@ -184,10 +183,8 @@ rfi_v2r_1:
.text
.align 128
rfi_real2virt:
- ssm 0,0 /* See "relied upon translation" */
- nop /* PA 2.0 Arch. F-5 */
- nop
- nop
+ rsm PSW_SM_I,%r0
+ load32 (rfi_r2v_1), %r1
nop
nop
nop
@@ -197,7 +194,6 @@ rfi_real2virt:
rsm PSW_SM_Q,%r0 /* disable Q bit to load iia queue */
mtctl %r0, %cr17 /* Clear IIASQ tail */
mtctl %r0, %cr17 /* Clear IIASQ head */
- load32 (rfi_r2v_1), %r1
mtctl %r1, %cr18 /* IIAOQ head */
ldo 4(%r1), %r1
mtctl %r1, %cr18 /* IIAOQ tail */
@@ -218,7 +214,7 @@ rfi_r2v_1:
bv 0(%r2)
nop
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
/************************ 64-bit real-mode calls ***********************/
/* This is only usable in wide kernels right now and will probably stay so */
@@ -296,7 +292,7 @@ pc_in_user_space:
** comparing function pointers.
*/
__canonicalize_funcptr_for_compare:
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
bve (%r2)
#else
bv %r0(%r2)
diff --git a/arch/parisc/kernel/signal.c b/arch/parisc/kernel/signal.c
index 0224651fd8f1..82c24e62ab63 100644
--- a/arch/parisc/kernel/signal.c
+++ b/arch/parisc/kernel/signal.c
@@ -490,15 +490,7 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
give_sigsegv:
DBG(1,"setup_rt_frame: sending SIGSEGV\n");
- if (sig == SIGSEGV)
- ka->sa.sa_handler = SIG_DFL;
- si.si_signo = SIGSEGV;
- si.si_errno = 0;
- si.si_code = SI_KERNEL;
- si.si_pid = current->pid;
- si.si_uid = current->uid;
- si.si_addr = frame;
- force_sig_info(SIGSEGV, &si, current);
+ force_sigsegv(sig, current);
return 0;
}
@@ -633,10 +625,14 @@ do_signal(sigset_t *oldset, struct pt_regs *regs, int in_syscall)
put_user(0xe0008200, &usp[3]);
put_user(0x34140000, &usp[4]);
- /* Stack is 64-byte aligned, and we only
- * need to flush 1 cache line */
- asm("fdc 0(%%sr3, %0)\n"
- "fic 0(%%sr3, %0)\n"
+ /* Stack is 64-byte aligned, and we only need
+ * to flush 1 cache line.
+ * Flushing one cacheline is cheap.
+ * "sync" on bigger (> 4 way) boxes is not.
+ */
+ asm("fdc %%r0(%%sr3, %0)\n"
+ "sync\n"
+ "fic %%r0(%%sr3, %0)\n"
"sync\n"
: : "r"(regs->gr[30]));
diff --git a/arch/parisc/kernel/smp.c b/arch/parisc/kernel/smp.c
index bcc7e83f5142..a9ecf6465784 100644
--- a/arch/parisc/kernel/smp.c
+++ b/arch/parisc/kernel/smp.c
@@ -18,7 +18,7 @@
*/
#undef ENTRY_SYS_CPUS /* syscall support for iCOD-like functionality */
-#include <linux/autoconf.h>
+#include <linux/config.h>
#include <linux/types.h>
#include <linux/spinlock.h>
@@ -463,6 +463,7 @@ void __init smp_callin(void)
#endif
smp_cpu_init(slave_id);
+ preempt_disable();
#if 0 /* NOT WORKING YET - see entry.S */
istack = (void *)__get_free_pages(GFP_KERNEL,ISTACK_ORDER);
diff --git a/arch/parisc/kernel/syscall.S b/arch/parisc/kernel/syscall.S
index 8c7a7185cd3b..b29b76b42bb7 100644
--- a/arch/parisc/kernel/syscall.S
+++ b/arch/parisc/kernel/syscall.S
@@ -6,6 +6,7 @@
* thanks to Philipp Rumpf, Mike Shaver and various others
* sorry about the wall, puffin..
*/
+#include <linux/config.h> /* for CONFIG_SMP */
#include <asm/asm-offsets.h>
#include <asm/unistd.h>
@@ -22,15 +23,13 @@
*/
#define KILL_INSN break 0,0
-#include <linux/config.h> /* for CONFIG_SMP */
-
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
.level 2.0w
#else
.level 1.1
#endif
-#ifndef __LP64__
+#ifndef CONFIG_64BIT
.macro fixup_branch,lbl
b \lbl
.endm
@@ -103,7 +102,7 @@ linux_gateway_entry:
mfsp %sr7,%r1 /* save user sr7 */
mtsp %r1,%sr3 /* and store it in sr3 */
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
/* for now we can *always* set the W bit on entry to the syscall
* since we don't support wide userland processes. We could
* also save the current SM other than in r0 and restore it on
@@ -155,7 +154,7 @@ linux_gateway_entry:
STREG %r19, TASK_PT_GR19(%r1)
LDREGM -FRAME_SIZE(%r30), %r2 /* get users sp back */
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
extrd,u %r2,63,1,%r19 /* W hidden in bottom bit */
#if 0
xor %r19,%r2,%r2 /* clear bottom bit */
@@ -186,7 +185,7 @@ linux_gateway_entry:
loadgp
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
ldo -16(%r30),%r29 /* Reference param save area */
copy %r19,%r2 /* W bit back to r2 */
#else
@@ -205,7 +204,7 @@ linux_gateway_entry:
/* Note! We cannot use the syscall table that is mapped
nearby since the gateway page is mapped execute-only. */
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
ldil L%sys_call_table, %r1
or,= %r2,%r2,%r2
addil L%(sys_call_table64-sys_call_table), %r1
@@ -321,7 +320,7 @@ tracesys_next:
LDREG TASK_PT_GR25(%r1), %r25
LDREG TASK_PT_GR24(%r1), %r24
LDREG TASK_PT_GR23(%r1), %r23
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
LDREG TASK_PT_GR22(%r1), %r22
LDREG TASK_PT_GR21(%r1), %r21
ldo -16(%r30),%r29 /* Reference param save area */
@@ -350,7 +349,7 @@ tracesys_next:
tracesys_exit:
ldo -THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1 /* get task ptr */
LDREG TI_TASK(%r1), %r1
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
ldo -16(%r30),%r29 /* Reference param save area */
#endif
bl syscall_trace, %r2
@@ -371,7 +370,7 @@ tracesys_exit:
tracesys_sigexit:
ldo -THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1 /* get task ptr */
LDREG 0(%r1), %r1
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
ldo -16(%r30),%r29 /* Reference param save area */
#endif
bl syscall_trace, %r2
@@ -404,7 +403,7 @@ lws_start:
gate .+8, %r0
depi 3, 31, 2, %r31 /* Ensure we return to userspace */
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
/* FIXME: If we are a 64-bit kernel just
* turn this on unconditionally.
*/
@@ -440,7 +439,7 @@ lws_exit_nosys:
/* Fall through: Return to userspace */
lws_exit:
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
/* decide whether to reset the wide mode bit
*
* For a syscall, the W bit is stored in the lowest bit
@@ -486,7 +485,7 @@ lws_exit:
/* ELF64 Process entry path */
lws_compare_and_swap64:
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
b,n lws_compare_and_swap
#else
/* If we are not a 64-bit kernel, then we don't
@@ -497,7 +496,7 @@ lws_compare_and_swap64:
/* ELF32 Process entry path */
lws_compare_and_swap32:
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
/* Clip all the input registers */
depdi 0, 31, 32, %r26
depdi 0, 31, 32, %r25
@@ -608,7 +607,7 @@ cas_action:
the other for the store. Either return -EFAULT.
Each of the entries must be relocated. */
.section __ex_table,"aw"
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
/* Pad the address calculation */
.word 0,(2b - linux_gateway_page)
.word 0,(3b - linux_gateway_page)
@@ -619,7 +618,7 @@ cas_action:
.previous
.section __ex_table,"aw"
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
/* Pad the address calculation */
.word 0,(1b - linux_gateway_page)
.word 0,(3b - linux_gateway_page)
@@ -638,7 +637,7 @@ end_linux_gateway_page:
/* Relocate symbols assuming linux_gateway_page is mapped
to virtual address 0x0 */
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
/* FIXME: The code will always be on the gateay page
and thus it will be on the first 4k, the
assembler seems to think that the final
@@ -666,7 +665,7 @@ lws_table:
sys_call_table:
#include "syscall_table.S"
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
.align 4096
.export sys_call_table64
.Lsys_call_table64:
diff --git a/arch/parisc/kernel/syscall_table.S b/arch/parisc/kernel/syscall_table.S
index dcfa4d3d0e7d..32cbc0489324 100644
--- a/arch/parisc/kernel/syscall_table.S
+++ b/arch/parisc/kernel/syscall_table.S
@@ -35,7 +35,7 @@
#undef ENTRY_UHOH
#undef ENTRY_COMP
#undef ENTRY_OURS
-#if defined(__LP64__) && !defined(SYSCALL_TABLE_64BIT)
+#if defined(CONFIG_64BIT) && !defined(SYSCALL_TABLE_64BIT)
/* Use ENTRY_SAME for 32-bit syscalls which are the same on wide and
* narrow palinux. Use ENTRY_DIFF for those where a 32-bit specific
* implementation is required on wide palinux. Use ENTRY_COMP where
@@ -46,7 +46,7 @@
#define ENTRY_UHOH(_name_) .dword sys32_##unimplemented
#define ENTRY_OURS(_name_) .dword parisc_##_name_
#define ENTRY_COMP(_name_) .dword compat_sys_##_name_
-#elif defined(__LP64__) && defined(SYSCALL_TABLE_64BIT)
+#elif defined(CONFIG_64BIT) && defined(SYSCALL_TABLE_64BIT)
#define ENTRY_SAME(_name_) .dword sys_##_name_
#define ENTRY_DIFF(_name_) .dword sys_##_name_
#define ENTRY_UHOH(_name_) .dword sys_##_name_
@@ -368,5 +368,11 @@
ENTRY_COMP(mbind) /* 260 */
ENTRY_COMP(get_mempolicy)
ENTRY_COMP(set_mempolicy)
+ ENTRY_SAME(ni_syscall) /* 263: reserved for vserver */
+ ENTRY_SAME(add_key)
+ ENTRY_SAME(request_key) /* 265 */
+ ENTRY_SAME(keyctl)
+ ENTRY_SAME(ioprio_set)
+ ENTRY_SAME(ioprio_get)
/* Nothing yet */
diff --git a/arch/parisc/kernel/time.c b/arch/parisc/kernel/time.c
index 7ff67f8e9f8c..cded25680787 100644
--- a/arch/parisc/kernel/time.c
+++ b/arch/parisc/kernel/time.c
@@ -33,10 +33,6 @@
#include <linux/timex.h>
-u64 jiffies_64 = INITIAL_JIFFIES;
-
-EXPORT_SYMBOL(jiffies_64);
-
/* xtime and wall_jiffies keep wall-clock time */
extern unsigned long wall_jiffies;
@@ -89,14 +85,6 @@ irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
}
}
-#ifdef CONFIG_CHASSIS_LCD_LED
- /* Only schedule the led tasklet on cpu 0, and only if it
- * is enabled.
- */
- if (cpu == 0 && !atomic_read(&led_tasklet.count))
- tasklet_schedule(&led_tasklet);
-#endif
-
/* check soft power switch status */
if (cpu == 0 && !atomic_read(&power_tasklet.count))
tasklet_schedule(&power_tasklet);
@@ -104,6 +92,24 @@ irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
return IRQ_HANDLED;
}
+
+unsigned long profile_pc(struct pt_regs *regs)
+{
+ unsigned long pc = instruction_pointer(regs);
+
+ if (regs->gr[0] & PSW_N)
+ pc -= 4;
+
+#ifdef CONFIG_SMP
+ if (in_lock_functions(pc))
+ pc = regs->gr[2];
+#endif
+
+ return pc;
+}
+EXPORT_SYMBOL(profile_pc);
+
+
/*** converted from ia64 ***/
/*
* Return the number of micro-seconds that elapsed since the last
diff --git a/arch/parisc/kernel/traps.c b/arch/parisc/kernel/traps.c
index d2e5b229a2f4..15914f0235a0 100644
--- a/arch/parisc/kernel/traps.c
+++ b/arch/parisc/kernel/traps.c
@@ -74,7 +74,10 @@ void show_regs(struct pt_regs *regs)
char *level;
unsigned long cr30;
unsigned long cr31;
-
+ /* carlos says that gcc understands better memory in a struct,
+ * and it makes our life easier with fpregs -- T-Bone */
+ struct { u32 sw[2]; } s;
+
level = user_mode(regs) ? KERN_DEBUG : KERN_CRIT;
printk("%s\n", level); /* don't want to have that pretty register dump messed up */
@@ -103,11 +106,33 @@ void show_regs(struct pt_regs *regs)
printk("%s\n", buf);
}
-#if RIDICULOUSLY_VERBOSE
- for (i = 0; i < 32; i += 2)
- printk("%sFR%02d : %016lx FR%2d : %016lx", level, i,
- regs->fr[i], i+1, regs->fr[i+1]);
-#endif
+ /* FR are 64bit everywhere. Need to use asm to get the content
+ * of fpsr/fper1, and we assume that we won't have a FP Identify
+ * in our way, otherwise we're screwed.
+ * The fldd is used to restore the T-bit if there was one, as the
+ * store clears it anyway.
+ * BTW, PA2.0 book says "thou shall not use fstw on FPSR/FPERs". */
+ __asm__ (
+ "fstd %%fr0,0(%1) \n\t"
+ "fldd 0(%1),%%fr0 \n\t"
+ : "=m" (s) : "r" (&s) : "%r0"
+ );
+
+ printk("%s\n", level);
+ printk("%s VZOUICununcqcqcqcqcqcrmunTDVZOUI\n", level);
+ printbinary(buf, s.sw[0], 32);
+ printk("%sFPSR: %s\n", level, buf);
+ printk("%sFPER1: %08x\n", level, s.sw[1]);
+
+ /* here we'll print fr0 again, tho it'll be meaningless */
+ for (i = 0; i < 32; i += 4) {
+ int j;
+ p = buf;
+ p += sprintf(p, "%sfr%02d-%02d ", level, i, i + 3);
+ for (j = 0; j < 4; j++)
+ p += sprintf(p, " %016llx", (i+j) == 0 ? 0 : regs->fr[i+j]);
+ printk("%s\n", buf);
+ }
cr30 = mfctl(30);
cr31 = mfctl(31);
diff --git a/arch/parisc/kernel/unaligned.c b/arch/parisc/kernel/unaligned.c
index 62eea35bcd69..eaae8a021f9f 100644
--- a/arch/parisc/kernel/unaligned.c
+++ b/arch/parisc/kernel/unaligned.c
@@ -513,15 +513,18 @@ void handle_unaligned(struct pt_regs *regs)
register int flop=0; /* true if this is a flop */
/* log a message with pacing */
- if (user_mode(regs))
- {
- if (unaligned_count > 5 && jiffies - last_time > 5*HZ)
- {
+ if (user_mode(regs)) {
+ if (current->thread.flags & PARISC_UAC_SIGBUS) {
+ goto force_sigbus;
+ }
+
+ if (unaligned_count > 5 && jiffies - last_time > 5*HZ) {
unaligned_count = 0;
last_time = jiffies;
}
- if (++unaligned_count < 5)
- {
+
+ if (!(current->thread.flags & PARISC_UAC_NOPRINT)
+ && ++unaligned_count < 5) {
char buf[256];
sprintf(buf, "%s(%d): unaligned access to 0x" RFMT " at ip=0x" RFMT "\n",
current->comm, current->pid, regs->ior, regs->iaoq[0]);
@@ -530,6 +533,7 @@ void handle_unaligned(struct pt_regs *regs)
show_regs(regs);
#endif
}
+
if (!unaligned_enabled)
goto force_sigbus;
}
diff --git a/arch/parisc/lib/fixup.S b/arch/parisc/lib/fixup.S
index 1b91612ed964..e0661c2978ed 100644
--- a/arch/parisc/lib/fixup.S
+++ b/arch/parisc/lib/fixup.S
@@ -35,7 +35,7 @@
extrd,u \t2,63,32,\t2
#endif
/* t2 = &__per_cpu_offset[smp_processor_id()]; */
- LDREG,s \t2(\t1),\t2
+ LDREGX \t2(\t1),\t2
addil LT%per_cpu__exception_data,%r27
LDREG RT%per_cpu__exception_data(%r1),\t1
/* t1 = &__get_cpu_var(exception_data) */
@@ -53,6 +53,8 @@
.endm
#endif
+ .level LEVEL
+
.text
.section .fixup, "ax"
diff --git a/arch/parisc/lib/memcpy.c b/arch/parisc/lib/memcpy.c
index feb1b9f42c2b..b7098035321f 100644
--- a/arch/parisc/lib/memcpy.c
+++ b/arch/parisc/lib/memcpy.c
@@ -339,6 +339,7 @@ unsigned long pa_memcpy(void *dstp, const void *srcp, unsigned long len)
pds = (double *)pcs;
pdd = (double *)pcd;
+#if 0
/* Copy 8 doubles at a time */
while (len >= 8*sizeof(double)) {
register double r1, r2, r3, r4, r5, r6, r7, r8;
@@ -366,6 +367,7 @@ unsigned long pa_memcpy(void *dstp, const void *srcp, unsigned long len)
fstdma(d_space, r8, pdd, pmc_store_exc);
len -= 8*sizeof(double);
}
+#endif
pws = (unsigned int *)pds;
pwd = (unsigned int *)pdd;
diff --git a/arch/parisc/mm/init.c b/arch/parisc/mm/init.c
index 2886ad70db48..29b998e430e6 100644
--- a/arch/parisc/mm/init.c
+++ b/arch/parisc/mm/init.c
@@ -505,7 +505,9 @@ void show_mem(void)
for (j = node_start_pfn(i); j < node_end_pfn(i); j++) {
struct page *p;
+ unsigned long flags;
+ pgdat_resize_lock(NODE_DATA(i), &flags);
p = nid_page_nr(i, j) - node_start_pfn(i);
total++;
@@ -517,6 +519,7 @@ void show_mem(void)
free++;
else
shared += page_count(p) - 1;
+ pgdat_resize_unlock(NODE_DATA(i), &flags);
}
}
#endif
diff --git a/arch/parisc/mm/ioremap.c b/arch/parisc/mm/ioremap.c
index f2df502cdae3..5c7a1b3b9326 100644
--- a/arch/parisc/mm/ioremap.c
+++ b/arch/parisc/mm/ioremap.c
@@ -52,7 +52,7 @@ static inline int remap_area_pmd(pmd_t * pmd, unsigned long address, unsigned lo
if (address >= end)
BUG();
do {
- pte_t * pte = pte_alloc_kernel(NULL, pmd, address);
+ pte_t * pte = pte_alloc_kernel(pmd, address);
if (!pte)
return -ENOMEM;
remap_area_pte(pte, address, end - address, address + phys_addr, flags);
@@ -75,10 +75,9 @@ static int remap_area_pages(unsigned long address, unsigned long phys_addr,
flush_cache_all();
if (address >= end)
BUG();
- spin_lock(&init_mm.page_table_lock);
do {
pmd_t *pmd;
- pmd = pmd_alloc(dir, address);
+ pmd = pmd_alloc(&init_mm, dir, address);
error = -ENOMEM;
if (!pmd)
break;
@@ -89,7 +88,6 @@ static int remap_area_pages(unsigned long address, unsigned long phys_addr,
address = (address + PGDIR_SIZE) & PGDIR_MASK;
dir++;
} while (address && (address < end));
- spin_unlock(&init_mm.page_table_lock);
flush_tlb_all();
return error;
}
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
new file mode 100644
index 000000000000..ed31062029f7
--- /dev/null
+++ b/arch/powerpc/Kconfig
@@ -0,0 +1,957 @@
+# For a description of the syntax of this configuration file,
+# see Documentation/kbuild/kconfig-language.txt.
+#
+
+mainmenu "Linux/PowerPC Kernel Configuration"
+
+config PPC64
+ bool "64-bit kernel"
+ default n
+ help
+ This option selects whether a 32-bit or a 64-bit kernel
+ will be built.
+
+config PPC32
+ bool
+ default y if !PPC64
+
+config 64BIT
+ bool
+ default y if PPC64
+
+config PPC_MERGE
+ def_bool y
+
+config MMU
+ bool
+ default y
+
+config UID16
+ bool
+
+config GENERIC_HARDIRQS
+ bool
+ default y
+
+config RWSEM_GENERIC_SPINLOCK
+ bool
+
+config RWSEM_XCHGADD_ALGORITHM
+ bool
+ default y
+
+config GENERIC_CALIBRATE_DELAY
+ bool
+ default y
+
+config PPC
+ bool
+ default y
+
+config EARLY_PRINTK
+ bool
+ default y if PPC64
+
+config COMPAT
+ bool
+ default y if PPC64
+
+config SYSVIPC_COMPAT
+ bool
+ depends on COMPAT && SYSVIPC
+ default y
+
+# All PPC32s use generic nvram driver through ppc_md
+config GENERIC_NVRAM
+ bool
+ default y if PPC32
+
+config SCHED_NO_NO_OMIT_FRAME_POINTER
+ bool
+ default y
+
+config ARCH_MAY_HAVE_PC_FDC
+ bool
+ default y
+
+menu "Processor support"
+choice
+ prompt "Processor Type"
+ depends on PPC32
+ default 6xx
+
+config 6xx
+ bool "6xx/7xx/74xx"
+ select PPC_FPU
+ help
+ There are four families of PowerPC chips supported. The more common
+ types (601, 603, 604, 740, 750, 7400), the Motorola embedded
+ versions (821, 823, 850, 855, 860, 52xx, 82xx, 83xx), the AMCC
+ embedded versions (403 and 405) and the high end 64 bit Power
+ processors (POWER 3, POWER4, and IBM PPC970 also known as G5).
+
+ Unless you are building a kernel for one of the embedded processor
+ systems, 64 bit IBM RS/6000 or an Apple G5, choose 6xx.
+ Note that the kernel runs in 32-bit mode even on 64-bit chips.
+
+config PPC_52xx
+ bool "Freescale 52xx"
+
+config PPC_82xx
+ bool "Freescale 82xx"
+
+config PPC_83xx
+ bool "Freescale 83xx"
+
+config 40x
+ bool "AMCC 40x"
+
+config 44x
+ bool "AMCC 44x"
+
+config 8xx
+ bool "Freescale 8xx"
+
+config E200
+ bool "Freescale e200"
+
+config E500
+ bool "Freescale e500"
+endchoice
+
+config POWER4_ONLY
+ bool "Optimize for POWER4"
+ depends on PPC64
+ default n
+ ---help---
+ Cause the compiler to optimize for POWER4/POWER5/PPC970 processors.
+ The resulting binary will not work on POWER3 or RS64 processors
+ when compiled with binutils 2.15 or later.
+
+config POWER3
+ bool
+ depends on PPC64
+ default y if !POWER4_ONLY
+
+config POWER4
+ depends on PPC64
+ def_bool y
+
+config PPC_FPU
+ bool
+ default y if PPC64
+
+config BOOKE
+ bool
+ depends on E200 || E500
+ default y
+
+config FSL_BOOKE
+ bool
+ depends on E200 || E500
+ default y
+
+config PTE_64BIT
+ bool
+ depends on 44x || E500
+ default y if 44x
+ default y if E500 && PHYS_64BIT
+
+config PHYS_64BIT
+ bool 'Large physical address support' if E500
+ depends on 44x || E500
+ default y if 44x
+ ---help---
+ This option enables kernel support for larger than 32-bit physical
+ addresses. This features is not be available on all e500 cores.
+
+ If in doubt, say N here.
+
+config ALTIVEC
+ bool "AltiVec Support"
+ depends on 6xx || POWER4
+ ---help---
+ This option enables kernel support for the Altivec extensions to the
+ PowerPC processor. The kernel currently supports saving and restoring
+ altivec registers, and turning on the 'altivec enable' bit so user
+ processes can execute altivec instructions.
+
+ This option is only usefully if you have a processor that supports
+ altivec (G4, otherwise known as 74xx series), but does not have
+ any affect on a non-altivec cpu (it does, however add code to the
+ kernel).
+
+ If in doubt, say Y here.
+
+config SPE
+ bool "SPE Support"
+ depends on E200 || E500
+ ---help---
+ This option enables kernel support for the Signal Processing
+ Extensions (SPE) to the PowerPC processor. The kernel currently
+ supports saving and restoring SPE registers, and turning on the
+ 'spe enable' bit so user processes can execute SPE instructions.
+
+ This option is only useful if you have a processor that supports
+ SPE (e500, otherwise known as 85xx series), but does not have any
+ effect on a non-spe cpu (it does, however add code to the kernel).
+
+ If in doubt, say Y here.
+
+config PPC_STD_MMU
+ bool
+ depends on 6xx || POWER3 || POWER4 || PPC64
+ default y
+
+config PPC_STD_MMU_32
+ def_bool y
+ depends on PPC_STD_MMU && PPC32
+
+config SMP
+ depends on PPC_STD_MMU
+ bool "Symmetric multi-processing support"
+ ---help---
+ This enables support for systems with more than one CPU. If you have
+ a system with only one CPU, say N. If you have a system with more
+ than one CPU, say Y. Note that the kernel does not currently
+ support SMP machines with 603/603e/603ev or PPC750 ("G3") processors
+ since they have inadequate hardware support for multiprocessor
+ operation.
+
+ If you say N here, the kernel will run on single and multiprocessor
+ machines, but will use only one CPU of a multiprocessor machine. If
+ you say Y here, the kernel will run on single-processor machines.
+ On a single-processor machine, the kernel will run faster if you say
+ N here.
+
+ If you don't know what to do here, say N.
+
+config NR_CPUS
+ int "Maximum number of CPUs (2-32)"
+ range 2 128
+ depends on SMP
+ default "32" if PPC64
+ default "4"
+
+config NOT_COHERENT_CACHE
+ bool
+ depends on 4xx || 8xx || E200
+ default y
+endmenu
+
+source "init/Kconfig"
+
+menu "Platform support"
+ depends on PPC64 || 6xx
+
+choice
+ prompt "Machine type"
+ default PPC_MULTIPLATFORM
+
+config PPC_MULTIPLATFORM
+ bool "Generic desktop/server/laptop"
+ help
+ Select this option if configuring for an IBM pSeries or
+ RS/6000 machine, an Apple machine, or a PReP, CHRP,
+ Maple or Cell-based machine.
+
+config PPC_ISERIES
+ bool "IBM Legacy iSeries"
+ depends on PPC64
+
+config EMBEDDED6xx
+ bool "Embedded 6xx/7xx/7xxx-based board"
+ depends on PPC32
+
+config APUS
+ bool "Amiga-APUS"
+ depends on PPC32 && BROKEN
+ help
+ Select APUS if configuring for a PowerUP Amiga.
+ More information is available at:
+ <http://linux-apus.sourceforge.net/>.
+endchoice
+
+config PPC_PSERIES
+ depends on PPC_MULTIPLATFORM && PPC64
+ bool " IBM pSeries & new (POWER5-based) iSeries"
+ select PPC_I8259
+ select PPC_RTAS
+ select RTAS_ERROR_LOGGING
+ default y
+
+config PPC_CHRP
+ bool " Common Hardware Reference Platform (CHRP) based machines"
+ depends on PPC_MULTIPLATFORM && PPC32
+ select PPC_I8259
+ select PPC_INDIRECT_PCI
+ select PPC_RTAS
+ select PPC_MPC106
+ default y
+
+config PPC_PMAC
+ bool " Apple PowerMac based machines"
+ depends on PPC_MULTIPLATFORM
+ select PPC_INDIRECT_PCI if PPC32
+ select PPC_MPC106 if PPC32
+ default y
+
+config PPC_PMAC64
+ bool
+ depends on PPC_PMAC && POWER4
+ select U3_DART
+ select GENERIC_TBSYNC
+ default y
+
+config PPC_PREP
+ bool " PowerPC Reference Platform (PReP) based machines"
+ depends on PPC_MULTIPLATFORM && PPC32
+ select PPC_I8259
+ select PPC_INDIRECT_PCI
+ default y
+
+config PPC_MAPLE
+ depends on PPC_MULTIPLATFORM && PPC64
+ bool " Maple 970FX Evaluation Board"
+ select U3_DART
+ select MPIC_BROKEN_U3
+ select GENERIC_TBSYNC
+ default n
+ help
+ This option enables support for the Maple 970FX Evaluation Board.
+ For more informations, refer to <http://www.970eval.com>
+
+config PPC_CELL
+ bool " Cell Broadband Processor Architecture"
+ depends on PPC_MULTIPLATFORM && PPC64
+ select PPC_RTAS
+ select MMIO_NVRAM
+
+config PPC_OF
+ bool
+ depends on PPC_MULTIPLATFORM # for now
+ default y
+
+config XICS
+ depends on PPC_PSERIES
+ bool
+ default y
+
+config U3_DART
+ bool
+ depends on PPC_MULTIPLATFORM && PPC64
+ default n
+
+config MPIC
+ depends on PPC_PSERIES || PPC_PMAC || PPC_MAPLE || PPC_CHRP
+ bool
+ default y
+
+config PPC_RTAS
+ bool
+ default n
+
+config RTAS_ERROR_LOGGING
+ bool
+ depends on PPC_RTAS
+ default n
+
+config RTAS_PROC
+ bool "Proc interface to RTAS"
+ depends on PPC_RTAS
+ default y
+
+config RTAS_FLASH
+ tristate "Firmware flash interface"
+ depends on PPC64 && RTAS_PROC
+
+config MMIO_NVRAM
+ bool
+ default n
+
+config MPIC_BROKEN_U3
+ bool
+ depends on PPC_MAPLE
+ default y
+
+config CELL_IIC
+ depends on PPC_CELL
+ bool
+ default y
+
+config IBMVIO
+ depends on PPC_PSERIES || PPC_ISERIES
+ bool
+ default y
+
+config PPC_MPC106
+ bool
+ default n
+
+config GENERIC_TBSYNC
+ bool
+ default y if CONFIG_PPC32 && CONFIG_SMP
+ default n
+
+source "drivers/cpufreq/Kconfig"
+
+config CPU_FREQ_PMAC
+ bool "Support for Apple PowerBooks"
+ depends on CPU_FREQ && ADB_PMU && PPC32
+ select CPU_FREQ_TABLE
+ help
+ This adds support for frequency switching on Apple PowerBooks,
+ this currently includes some models of iBook & Titanium
+ PowerBook.
+
+config CPU_FREQ_PMAC64
+ bool "Support for some Apple G5s"
+ depends on CPU_FREQ && PMAC_SMU && PPC64
+ select CPU_FREQ_TABLE
+ help
+ This adds support for frequency switching on Apple iMac G5,
+ and some of the more recent desktop G5 machines as well.
+
+config PPC601_SYNC_FIX
+ bool "Workarounds for PPC601 bugs"
+ depends on 6xx && (PPC_PREP || PPC_PMAC)
+ help
+ Some versions of the PPC601 (the first PowerPC chip) have bugs which
+ mean that extra synchronization instructions are required near
+ certain instructions, typically those that make major changes to the
+ CPU state. These extra instructions reduce performance slightly.
+ If you say N here, these extra instructions will not be included,
+ resulting in a kernel which will run faster but may not run at all
+ on some systems with the PPC601 chip.
+
+ If in doubt, say Y here.
+
+config TAU
+ bool "Thermal Management Support"
+ depends on 6xx
+ help
+ G3 and G4 processors have an on-chip temperature sensor called the
+ 'Thermal Assist Unit (TAU)', which, in theory, can measure the on-die
+ temperature within 2-4 degrees Celsius. This option shows the current
+ on-die temperature in /proc/cpuinfo if the cpu supports it.
+
+ Unfortunately, on some chip revisions, this sensor is very inaccurate
+ and in some cases, does not work at all, so don't assume the cpu
+ temp is actually what /proc/cpuinfo says it is.
+
+config TAU_INT
+ bool "Interrupt driven TAU driver (DANGEROUS)"
+ depends on TAU
+ ---help---
+ The TAU supports an interrupt driven mode which causes an interrupt
+ whenever the temperature goes out of range. This is the fastest way
+ to get notified the temp has exceeded a range. With this option off,
+ a timer is used to re-check the temperature periodically.
+
+ However, on some cpus it appears that the TAU interrupt hardware
+ is buggy and can cause a situation which would lead unexplained hard
+ lockups.
+
+ Unless you are extending the TAU driver, or enjoy kernel/hardware
+ debugging, leave this option off.
+
+config TAU_AVERAGE
+ bool "Average high and low temp"
+ depends on TAU
+ ---help---
+ The TAU hardware can compare the temperature to an upper and lower
+ bound. The default behavior is to show both the upper and lower
+ bound in /proc/cpuinfo. If the range is large, the temperature is
+ either changing a lot, or the TAU hardware is broken (likely on some
+ G4's). If the range is small (around 4 degrees), the temperature is
+ relatively stable. If you say Y here, a single temperature value,
+ halfway between the upper and lower bounds, will be reported in
+ /proc/cpuinfo.
+
+ If in doubt, say N here.
+endmenu
+
+source arch/powerpc/platforms/embedded6xx/Kconfig
+source arch/powerpc/platforms/4xx/Kconfig
+source arch/powerpc/platforms/85xx/Kconfig
+source arch/powerpc/platforms/8xx/Kconfig
+
+menu "Kernel options"
+
+config HIGHMEM
+ bool "High memory support"
+ depends on PPC32
+
+source kernel/Kconfig.hz
+source kernel/Kconfig.preempt
+source "fs/Kconfig.binfmt"
+
+# We optimistically allocate largepages from the VM, so make the limit
+# large enough (16MB). This badly named config option is actually
+# max order + 1
+config FORCE_MAX_ZONEORDER
+ int
+ depends on PPC64
+ default "9" if PPC_64K_PAGES
+ default "13"
+
+config MATH_EMULATION
+ bool "Math emulation"
+ depends on 4xx || 8xx || E200 || E500
+ ---help---
+ Some PowerPC chips designed for embedded applications do not have
+ a floating-point unit and therefore do not implement the
+ floating-point instructions in the PowerPC instruction set. If you
+ say Y here, the kernel will include code to emulate a floating-point
+ unit, which will allow programs that use floating-point
+ instructions to run.
+
+config IOMMU_VMERGE
+ bool "Enable IOMMU virtual merging (EXPERIMENTAL)"
+ depends on EXPERIMENTAL && PPC64
+ default n
+ help
+ Cause IO segments sent to a device for DMA to be merged virtually
+ by the IOMMU when they happen to have been allocated contiguously.
+ This doesn't add pressure to the IOMMU allocator. However, some
+ drivers don't support getting large merged segments coming back
+ from *_map_sg(). Say Y if you know the drivers you are using are
+ properly handling this case.
+
+config HOTPLUG_CPU
+ bool "Support for enabling/disabling CPUs"
+ depends on SMP && HOTPLUG && EXPERIMENTAL && (PPC_PSERIES || PPC_PMAC)
+ ---help---
+ Say Y here to be able to disable and re-enable individual
+ CPUs at runtime on SMP machines.
+
+ Say N if you are unsure.
+
+config KEXEC
+ bool "kexec system call (EXPERIMENTAL)"
+ depends on PPC_MULTIPLATFORM && EXPERIMENTAL
+ help
+ kexec is a system call that implements the ability to shutdown your
+ current kernel, and to start another kernel. It is like a reboot
+ but it is indepedent of the system firmware. And like a reboot
+ you can start any kernel with it, not just Linux.
+
+ The name comes from the similiarity to the exec system call.
+
+ It is an ongoing process to be certain the hardware in a machine
+ is properly shutdown, so do not be surprised if this code does not
+ initially work for you. It may help to enable device hotplugging
+ support. As of this writing the exact hardware interface is
+ strongly in flux, so no good recommendation can be made.
+
+config EMBEDDEDBOOT
+ bool
+ depends on 8xx || 8260
+ default y
+
+config PC_KEYBOARD
+ bool "PC PS/2 style Keyboard"
+ depends on 4xx || CPM2
+
+config PPCBUG_NVRAM
+ bool "Enable reading PPCBUG NVRAM during boot" if PPLUS || LOPEC
+ default y if PPC_PREP
+
+config IRQ_ALL_CPUS
+ bool "Distribute interrupts on all CPUs by default"
+ depends on SMP && !MV64360
+ help
+ This option gives the kernel permission to distribute IRQs across
+ multiple CPUs. Saying N here will route all IRQs to the first
+ CPU. Generally saying Y is safe, although some problems have been
+ reported with SMP Power Macintoshes with this option enabled.
+
+source "arch/powerpc/platforms/pseries/Kconfig"
+
+config NUMA
+ bool "NUMA support"
+ depends on PPC64
+ default y if SMP && PPC_PSERIES
+
+config ARCH_SELECT_MEMORY_MODEL
+ def_bool y
+ depends on PPC64
+
+config ARCH_FLATMEM_ENABLE
+ def_bool y
+ depends on PPC64 && !NUMA
+
+config ARCH_DISCONTIGMEM_ENABLE
+ def_bool y
+ depends on SMP && PPC_PSERIES
+
+config ARCH_DISCONTIGMEM_DEFAULT
+ def_bool y
+ depends on ARCH_DISCONTIGMEM_ENABLE
+
+config ARCH_SPARSEMEM_ENABLE
+ def_bool y
+ depends on ARCH_DISCONTIGMEM_ENABLE
+
+source "mm/Kconfig"
+
+config HAVE_ARCH_EARLY_PFN_TO_NID
+ def_bool y
+ depends on NEED_MULTIPLE_NODES
+
+config ARCH_MEMORY_PROBE
+ def_bool y
+ depends on MEMORY_HOTPLUG
+
+# Some NUMA nodes have memory ranges that span
+# other nodes. Even though a pfn is valid and
+# between a node's start and end pfns, it may not
+# reside on that node.
+#
+# This is a relatively temporary hack that should
+# be able to go away when sparsemem is fully in
+# place
+
+config NODES_SPAN_OTHER_NODES
+ def_bool y
+ depends on NEED_MULTIPLE_NODES
+
+config PPC_64K_PAGES
+ bool "64k page size"
+ depends on PPC64
+ help
+ This option changes the kernel logical page size to 64k. On machines
+ without processor support for 64k pages, the kernel will simulate
+ them by loading each individual 4k page on demand transparently,
+ while on hardware with such support, it will be used to map
+ normal application pages.
+
+config SCHED_SMT
+ bool "SMT (Hyperthreading) scheduler support"
+ depends on PPC64 && SMP
+ default off
+ help
+ SMT scheduler support improves the CPU scheduler's decision making
+ when dealing with POWER5 cpus at a cost of slightly increased
+ overhead in some places. If unsure say N here.
+
+config PROC_DEVICETREE
+ bool "Support for device tree in /proc"
+ depends on PROC_FS
+ help
+ This option adds a device-tree directory under /proc which contains
+ an image of the device tree that the kernel copies from Open
+ Firmware or other boot firmware. If unsure, say Y here.
+
+source "arch/powerpc/platforms/prep/Kconfig"
+
+config CMDLINE_BOOL
+ bool "Default bootloader kernel arguments"
+ depends on !PPC_ISERIES
+
+config CMDLINE
+ string "Initial kernel command string"
+ depends on CMDLINE_BOOL
+ default "console=ttyS0,9600 console=tty0 root=/dev/sda2"
+ help
+ On some platforms, there is currently no way for the boot loader to
+ pass arguments to the kernel. For these platforms, you can supply
+ some command-line options at build time by entering them here. In
+ most cases you will need to specify the root device here.
+
+if !44x || BROKEN
+source kernel/power/Kconfig
+endif
+
+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. Only embedded should say N here.
+
+endmenu
+
+config ISA_DMA_API
+ bool
+ default y
+
+menu "Bus options"
+
+config ISA
+ bool "Support for ISA-bus hardware"
+ depends on PPC_PREP || PPC_CHRP
+ select PPC_I8259
+ help
+ Find out whether you have ISA slots on your motherboard. ISA is the
+ name of a bus system, i.e. the way the CPU talks to the other stuff
+ inside your box. If you have an Apple machine, say N here; if you
+ have an IBM RS/6000 or pSeries machine or a PReP machine, say Y. If
+ you have an embedded board, consult your board documentation.
+
+config GENERIC_ISA_DMA
+ bool
+ depends on PPC64 || POWER4 || 6xx && !CPM2
+ default y
+
+config PPC_I8259
+ bool
+ default y if 85xx
+ default n
+
+config PPC_INDIRECT_PCI
+ bool
+ depends on PCI
+ default y if 40x || 44x || 85xx || 83xx
+ default n
+
+config EISA
+ bool
+
+config SBUS
+ bool
+
+# Yes MCA RS/6000s exist but Linux-PPC does not currently support any
+config MCA
+ bool
+
+config PCI
+ bool "PCI support" if 40x || CPM2 || 83xx || 85xx || PPC_MPC52xx || (EMBEDDED && PPC_ISERIES)
+ default y if !40x && !CPM2 && !8xx && !APUS && !83xx && !85xx
+ default PCI_PERMEDIA if !4xx && !CPM2 && !8xx && APUS
+ default PCI_QSPAN if !4xx && !CPM2 && 8xx
+ help
+ Find out whether your system includes a PCI bus. PCI is the name of
+ a bus system, i.e. the way the CPU talks to the other stuff inside
+ your box. If you say Y here, the kernel will include drivers and
+ infrastructure code to support PCI bus devices.
+
+config PCI_DOMAINS
+ bool
+ default PCI
+
+config MPC83xx_PCI2
+ bool " Supprt for 2nd PCI host controller"
+ depends on PCI && MPC834x
+ default y if MPC834x_SYS
+
+config PCI_QSPAN
+ bool "QSpan PCI"
+ depends on !4xx && !CPM2 && 8xx
+ select PPC_I8259
+ help
+ Say Y here if you have a system based on a Motorola 8xx-series
+ embedded processor with a QSPAN PCI interface, otherwise say N.
+
+config PCI_8260
+ bool
+ depends on PCI && 8260
+ select PPC_INDIRECT_PCI
+ default y
+
+config 8260_PCI9
+ bool " Enable workaround for MPC826x erratum PCI 9"
+ depends on PCI_8260 && !ADS8272
+ default y
+
+choice
+ prompt " IDMA channel for PCI 9 workaround"
+ depends on 8260_PCI9
+
+config 8260_PCI9_IDMA1
+ bool "IDMA1"
+
+config 8260_PCI9_IDMA2
+ bool "IDMA2"
+
+config 8260_PCI9_IDMA3
+ bool "IDMA3"
+
+config 8260_PCI9_IDMA4
+ bool "IDMA4"
+
+endchoice
+
+source "drivers/pci/Kconfig"
+
+source "drivers/pcmcia/Kconfig"
+
+source "drivers/pci/hotplug/Kconfig"
+
+endmenu
+
+menu "Advanced setup"
+ depends on PPC32
+
+config ADVANCED_OPTIONS
+ bool "Prompt for advanced kernel configuration options"
+ help
+ This option will enable prompting for a variety of advanced kernel
+ configuration options. These options can cause the kernel to not
+ work if they are set incorrectly, but can be used to optimize certain
+ aspects of kernel memory management.
+
+ Unless you know what you are doing, say N here.
+
+comment "Default settings for advanced configuration options are used"
+ depends on !ADVANCED_OPTIONS
+
+config HIGHMEM_START_BOOL
+ bool "Set high memory pool address"
+ depends on ADVANCED_OPTIONS && HIGHMEM
+ help
+ This option allows you to set the base address of the kernel virtual
+ area used to map high memory pages. This can be useful in
+ optimizing the layout of kernel virtual memory.
+
+ Say N here unless you know what you are doing.
+
+config HIGHMEM_START
+ hex "Virtual start address of high memory pool" if HIGHMEM_START_BOOL
+ default "0xfe000000"
+
+config LOWMEM_SIZE_BOOL
+ bool "Set maximum low memory"
+ depends on ADVANCED_OPTIONS
+ help
+ This option allows you to set the maximum amount of memory which
+ will be used as "low memory", that is, memory which the kernel can
+ access directly, without having to set up a kernel virtual mapping.
+ This can be useful in optimizing the layout of kernel virtual
+ memory.
+
+ Say N here unless you know what you are doing.
+
+config LOWMEM_SIZE
+ hex "Maximum low memory size (in bytes)" if LOWMEM_SIZE_BOOL
+ default "0x30000000"
+
+config KERNEL_START_BOOL
+ bool "Set custom kernel base address"
+ depends on ADVANCED_OPTIONS
+ help
+ This option allows you to set the kernel virtual address at which
+ the kernel will map low memory (the kernel image will be linked at
+ this address). This can be useful in optimizing the virtual memory
+ layout of the system.
+
+ Say N here unless you know what you are doing.
+
+config KERNEL_START
+ hex "Virtual address of kernel base" if KERNEL_START_BOOL
+ default "0xc0000000"
+
+config TASK_SIZE_BOOL
+ bool "Set custom user task size"
+ depends on ADVANCED_OPTIONS
+ help
+ This option allows you to set the amount of virtual address space
+ allocated to user tasks. This can be useful in optimizing the
+ virtual memory layout of the system.
+
+ Say N here unless you know what you are doing.
+
+config TASK_SIZE
+ hex "Size of user task space" if TASK_SIZE_BOOL
+ default "0x80000000"
+
+config CONSISTENT_START_BOOL
+ bool "Set custom consistent memory pool address"
+ depends on ADVANCED_OPTIONS && NOT_COHERENT_CACHE
+ help
+ This option allows you to set the base virtual address
+ of the the consistent memory pool. This pool of virtual
+ memory is used to make consistent memory allocations.
+
+config CONSISTENT_START
+ hex "Base virtual address of consistent memory pool" if CONSISTENT_START_BOOL
+ default "0xff100000" if NOT_COHERENT_CACHE
+
+config CONSISTENT_SIZE_BOOL
+ bool "Set custom consistent memory pool size"
+ depends on ADVANCED_OPTIONS && NOT_COHERENT_CACHE
+ help
+ This option allows you to set the size of the the
+ consistent memory pool. This pool of virtual memory
+ is used to make consistent memory allocations.
+
+config CONSISTENT_SIZE
+ hex "Size of consistent memory pool" if CONSISTENT_SIZE_BOOL
+ default "0x00200000" if NOT_COHERENT_CACHE
+
+config BOOT_LOAD_BOOL
+ bool "Set the boot link/load address"
+ depends on ADVANCED_OPTIONS && !PPC_MULTIPLATFORM
+ help
+ This option allows you to set the initial load address of the zImage
+ or zImage.initrd file. This can be useful if you are on a board
+ which has a small amount of memory.
+
+ Say N here unless you know what you are doing.
+
+config BOOT_LOAD
+ hex "Link/load address for booting" if BOOT_LOAD_BOOL
+ default "0x00400000" if 40x || 8xx || 8260
+ default "0x01000000" if 44x
+ default "0x00800000"
+
+config PIN_TLB
+ bool "Pinned Kernel TLBs (860 ONLY)"
+ depends on ADVANCED_OPTIONS && 8xx
+endmenu
+
+if PPC64
+config KERNEL_START
+ hex
+ default "0xc000000000000000"
+endif
+
+source "net/Kconfig"
+
+source "drivers/Kconfig"
+
+source "fs/Kconfig"
+
+# XXX source "arch/ppc/8xx_io/Kconfig"
+
+# XXX source "arch/ppc/8260_io/Kconfig"
+
+source "arch/powerpc/platforms/iseries/Kconfig"
+
+source "lib/Kconfig"
+
+menu "Instrumentation Support"
+ depends on EXPERIMENTAL
+
+source "arch/powerpc/oprofile/Kconfig"
+
+config KPROBES
+ bool "Kprobes (EXPERIMENTAL)"
+ help
+ Kprobes allows you to trap at almost any kernel address and
+ execute a callback function. register_kprobe() establishes
+ a probepoint and specifies the callback. Kprobes is useful
+ for kernel debugging, non-intrusive instrumentation and testing.
+ If in doubt, say "N".
+endmenu
+
+source "arch/powerpc/Kconfig.debug"
+
+source "security/Kconfig"
+
+config KEYS_COMPAT
+ bool
+ depends on COMPAT && KEYS
+ default y
+
+source "crypto/Kconfig"
diff --git a/arch/powerpc/Kconfig.debug b/arch/powerpc/Kconfig.debug
new file mode 100644
index 000000000000..30a30bf559ea
--- /dev/null
+++ b/arch/powerpc/Kconfig.debug
@@ -0,0 +1,118 @@
+menu "Kernel hacking"
+
+source "lib/Kconfig.debug"
+
+config DEBUG_STACKOVERFLOW
+ bool "Check for stack overflows"
+ depends on DEBUG_KERNEL && PPC64
+ help
+ This option will cause messages to be printed if free stack space
+ drops below a certain limit.
+
+config DEBUG_STACK_USAGE
+ bool "Stack utilization instrumentation"
+ depends on DEBUG_KERNEL && PPC64
+ help
+ Enables the display of the minimum amount of free stack which each
+ task has ever had available in the sysrq-T and sysrq-P debug output.
+
+ This option will slow down process creation somewhat.
+
+config DEBUGGER
+ bool "Enable debugger hooks"
+ depends on DEBUG_KERNEL
+ help
+ Include in-kernel hooks for kernel debuggers. Unless you are
+ intending to debug the kernel, say N here.
+
+config KGDB
+ bool "Include kgdb kernel debugger"
+ depends on DEBUGGER && (BROKEN || PPC_GEN550 || 4xx)
+ select DEBUG_INFO
+ help
+ Include in-kernel hooks for kgdb, the Linux kernel source level
+ debugger. See <http://kgdb.sourceforge.net/> for more information.
+ Unless you are intending to debug the kernel, say N here.
+
+choice
+ prompt "Serial Port"
+ depends on KGDB
+ default KGDB_TTYS1
+
+config KGDB_TTYS0
+ bool "ttyS0"
+
+config KGDB_TTYS1
+ bool "ttyS1"
+
+config KGDB_TTYS2
+ bool "ttyS2"
+
+config KGDB_TTYS3
+ bool "ttyS3"
+
+endchoice
+
+config KGDB_CONSOLE
+ bool "Enable serial console thru kgdb port"
+ depends on KGDB && 8xx || CPM2
+ help
+ If you enable this, all serial console messages will be sent
+ over the gdb stub.
+ If unsure, say N.
+
+config XMON
+ bool "Include xmon kernel debugger"
+ depends on DEBUGGER && !PPC_ISERIES
+ help
+ Include in-kernel hooks for the xmon kernel monitor/debugger.
+ Unless you are intending to debug the kernel, say N here.
+ Make sure to enable also CONFIG_BOOTX_TEXT on Macs. Otherwise
+ nothing will appear on the screen (xmon writes directly to the
+ framebuffer memory).
+ The cmdline option 'xmon' or 'xmon=early' will drop into xmon
+ very early during boot. 'xmon=on' will just enable the xmon
+ debugger hooks. 'xmon=off' will disable the debugger hooks
+ if CONFIG_XMON_DEFAULT is set.
+
+config XMON_DEFAULT
+ bool "Enable xmon by default"
+ depends on XMON
+ help
+ xmon is normally disabled unless booted with 'xmon=on'.
+ Use 'xmon=off' to disable xmon init during runtime.
+
+config IRQSTACKS
+ bool "Use separate kernel stacks when processing interrupts"
+ depends on PPC64
+ help
+ If you say Y here the kernel will use separate kernel stacks
+ for handling hard and soft interrupts. This can help avoid
+ overflowing the process kernel stacks.
+
+config BDI_SWITCH
+ bool "Include BDI-2000 user context switcher"
+ depends on DEBUG_KERNEL && PPC32
+ help
+ Include in-kernel support for the Abatron BDI2000 debugger.
+ Unless you are intending to debug the kernel with one of these
+ machines, say N here.
+
+config BOOTX_TEXT
+ bool "Support for early boot text console (BootX or OpenFirmware only)"
+ depends PPC_OF && !PPC_ISERIES
+ help
+ Say Y here to see progress messages from the boot firmware in text
+ mode. Requires either BootX or Open Firmware.
+
+config SERIAL_TEXT_DEBUG
+ bool "Support for early boot texts over serial port"
+ depends on 4xx || LOPEC || MV64X60 || PPLUS || PRPMC800 || \
+ PPC_GEN550 || PPC_MPC52xx
+
+config PPC_OCP
+ bool
+ depends on IBM_OCP || XILINX_OCP
+ default y
+
+endmenu
diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile
new file mode 100644
index 000000000000..5bc11bd36c1f
--- /dev/null
+++ b/arch/powerpc/Makefile
@@ -0,0 +1,219 @@
+# This file is included by the global makefile so that you can add your own
+# architecture-specific flags and dependencies. Remember to do have actions
+# for "archclean" and "archdep" for cleaning up and making dependencies for
+# this architecture.
+#
+# 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) 1994 by Linus Torvalds
+# Changes for PPC by Gary Thomas
+# Rewritten by Cort Dougan and Paul Mackerras
+#
+
+HAS_BIARCH := $(call cc-option-yn, -m32)
+
+ifeq ($(CONFIG_PPC64),y)
+OLDARCH := ppc64
+SZ := 64
+
+# Set default 32 bits cross compilers for vdso and boot wrapper
+CROSS32_COMPILE ?=
+
+CROSS32CC := $(CROSS32_COMPILE)gcc
+CROSS32AS := $(CROSS32_COMPILE)as
+CROSS32LD := $(CROSS32_COMPILE)ld
+CROSS32OBJCOPY := $(CROSS32_COMPILE)objcopy
+
+ifeq ($(HAS_BIARCH),y)
+ifeq ($(CROSS32_COMPILE),)
+CROSS32CC := $(CC) -m32
+CROSS32AS := $(AS) -a32
+CROSS32LD := $(LD) -m elf32ppc
+CROSS32OBJCOPY := $(OBJCOPY)
+endif
+endif
+
+export CROSS32CC CROSS32AS CROSS32LD CROSS32OBJCOPY
+
+new_nm := $(shell if $(NM) --help 2>&1 | grep -- '--synthetic' > /dev/null; then echo y; else echo n; fi)
+
+ifeq ($(new_nm),y)
+NM := $(NM) --synthetic
+endif
+
+else
+OLDARCH := ppc
+SZ := 32
+endif
+
+UTS_MACHINE := $(OLDARCH)
+
+ifeq ($(HAS_BIARCH),y)
+override AS += -a$(SZ)
+override LD += -m elf$(SZ)ppc
+override CC += -m$(SZ)
+endif
+
+LDFLAGS_vmlinux := -Bstatic
+
+# The -Iarch/$(ARCH)/include is temporary while we are merging
+CPPFLAGS += -Iarch/$(ARCH) -Iarch/$(ARCH)/include
+AFLAGS += -Iarch/$(ARCH)
+CFLAGS += -Iarch/$(ARCH) -msoft-float -pipe
+CFLAGS-$(CONFIG_PPC64) := -mminimal-toc -mtraceback=none -mcall-aixdesc
+CFLAGS-$(CONFIG_PPC32) := -ffixed-r2 -mmultiple
+CFLAGS += $(CFLAGS-y)
+CPP = $(CC) -E $(CFLAGS)
+# Temporary hack until we have migrated to asm-powerpc
+LINUXINCLUDE += -Iarch/$(ARCH)/include
+
+CHECKFLAGS += -m$(SZ) -D__powerpc__ -D__powerpc$(SZ)__
+
+ifeq ($(CONFIG_PPC64),y)
+GCC_VERSION := $(call cc-version)
+GCC_BROKEN_VEC := $(shell if [ $(GCC_VERSION) -lt 0400 ] ; then echo "y"; fi)
+
+ifeq ($(CONFIG_POWER4_ONLY),y)
+ifeq ($(CONFIG_ALTIVEC),y)
+ifeq ($(GCC_BROKEN_VEC),y)
+ CFLAGS += $(call cc-option,-mcpu=970)
+else
+ CFLAGS += $(call cc-option,-mcpu=power4)
+endif
+else
+ CFLAGS += $(call cc-option,-mcpu=power4)
+endif
+else
+ CFLAGS += $(call cc-option,-mtune=power4)
+endif
+endif
+
+# No AltiVec instruction when building kernel
+CFLAGS += $(call cc-option,-mno-altivec)
+
+# Enable unit-at-a-time mode when possible. It shrinks the
+# kernel considerably.
+CFLAGS += $(call cc-option,-funit-at-a-time)
+
+ifndef CONFIG_FSL_BOOKE
+CFLAGS += -mstring
+endif
+
+cpu-as-$(CONFIG_PPC64BRIDGE) += -Wa,-mppc64bridge
+cpu-as-$(CONFIG_4xx) += -Wa,-m405
+cpu-as-$(CONFIG_6xx) += -Wa,-maltivec
+cpu-as-$(CONFIG_POWER4) += -Wa,-maltivec
+cpu-as-$(CONFIG_E500) += -Wa,-me500
+cpu-as-$(CONFIG_E200) += -Wa,-me200
+
+AFLAGS += $(cpu-as-y)
+CFLAGS += $(cpu-as-y)
+
+# Default to the common case.
+KBUILD_DEFCONFIG := common_defconfig
+
+head-y := arch/powerpc/kernel/head_32.o
+head-$(CONFIG_PPC64) := arch/powerpc/kernel/head_64.o
+head-$(CONFIG_8xx) := arch/powerpc/kernel/head_8xx.o
+head-$(CONFIG_4xx) := arch/powerpc/kernel/head_4xx.o
+head-$(CONFIG_44x) := arch/powerpc/kernel/head_44x.o
+head-$(CONFIG_FSL_BOOKE) := arch/powerpc/kernel/head_fsl_booke.o
+
+head-$(CONFIG_PPC64) += arch/powerpc/kernel/entry_64.o
+head-$(CONFIG_PPC_FPU) += arch/powerpc/kernel/fpu.o
+
+core-y += arch/powerpc/kernel/ \
+ arch/$(OLDARCH)/kernel/ \
+ arch/powerpc/mm/ \
+ arch/powerpc/lib/ \
+ arch/powerpc/sysdev/ \
+ arch/powerpc/platforms/
+core-$(CONFIG_MATH_EMULATION) += arch/ppc/math-emu/
+core-$(CONFIG_XMON) += arch/powerpc/xmon/
+core-$(CONFIG_APUS) += arch/ppc/amiga/
+drivers-$(CONFIG_8xx) += arch/ppc/8xx_io/
+drivers-$(CONFIG_4xx) += arch/ppc/4xx_io/
+drivers-$(CONFIG_CPM2) += arch/ppc/8260_io/
+
+drivers-$(CONFIG_OPROFILE) += arch/powerpc/oprofile/
+
+defaultimage-$(CONFIG_PPC32) := uImage zImage
+defaultimage-$(CONFIG_PPC_ISERIES) := vmlinux
+defaultimage-$(CONFIG_PPC_PSERIES) := zImage
+KBUILD_IMAGE := $(defaultimage-y)
+all: $(KBUILD_IMAGE)
+
+CPPFLAGS_vmlinux.lds := -Upowerpc
+
+# All the instructions talk about "make bzImage".
+bzImage: zImage
+
+BOOT_TARGETS = zImage zImage.initrd znetboot znetboot.initrd vmlinux.sm
+
+.PHONY: $(BOOT_TARGETS)
+
+boot := arch/$(OLDARCH)/boot
+
+# urk
+ifeq ($(CONFIG_PPC64),y)
+$(BOOT_TARGETS): vmlinux
+ $(Q)$(MAKE) ARCH=ppc64 $(build)=$(boot) $(patsubst %,$(boot)/%,$@)
+else
+$(BOOT_TARGETS): vmlinux
+ $(Q)$(MAKE) ARCH=ppc $(build)=$(boot) $@
+endif
+
+uImage: vmlinux
+ $(Q)$(MAKE) ARCH=$(OLDARCH) $(build)=$(boot)/images $(boot)/images/$@
+
+define archhelp
+ @echo '* zImage - Compressed kernel image (arch/$(ARCH)/boot/images/zImage.*)'
+ @echo ' uImage - Create a bootable image for U-Boot / PPCBoot'
+ @echo ' install - Install kernel using'
+ @echo ' (your) ~/bin/installkernel or'
+ @echo ' (distribution) /sbin/installkernel or'
+ @echo ' install to $$(INSTALL_PATH) and run lilo'
+ @echo ' *_defconfig - Select default config from arch/$(ARCH)/ppc/configs'
+endef
+
+archclean:
+ $(Q)$(MAKE) $(clean)=$(boot)
+ # Temporary hack until we have migrated to asm-powerpc
+ $(Q)rm -rf arch/$(ARCH)/include
+
+archprepare: checkbin
+
+# Temporary hack until we have migrated to asm-powerpc
+include/asm: arch/$(ARCH)/include/asm
+arch/$(ARCH)/include/asm:
+ $(Q)if [ ! -d arch/$(ARCH)/include ]; then mkdir -p arch/$(ARCH)/include; fi
+ $(Q)ln -fsn $(srctree)/include/asm-$(OLDARCH) arch/$(ARCH)/include/asm
+
+# Use the file '.tmp_gas_check' for binutils tests, as gas won't output
+# to stdout and these checks are run even on install targets.
+TOUT := .tmp_gas_check
+# Ensure this is binutils 2.12.1 (or 2.12.90.0.7) or later for altivec
+# instructions.
+# gcc-3.4 and binutils-2.14 are a fatal combination.
+GCC_VERSION := $(call cc-version)
+
+checkbin:
+ @if test "$(GCC_VERSION)" = "0304" ; then \
+ if ! /bin/echo mftb 5 | $(AS) -v -mppc -many -o $(TOUT) >/dev/null 2>&1 ; then \
+ echo -n '*** ${VERSION}.${PATCHLEVEL} kernels no longer build '; \
+ echo 'correctly with gcc-3.4 and your version of binutils.'; \
+ echo '*** Please upgrade your binutils or downgrade your gcc'; \
+ false; \
+ fi ; \
+ fi
+ @if ! /bin/echo dssall | $(AS) -many -o $(TOUT) >/dev/null 2>&1 ; then \
+ echo -n '*** ${VERSION}.${PATCHLEVEL} kernels no longer build ' ; \
+ echo 'correctly with old versions of binutils.' ; \
+ echo '*** Please upgrade your binutils to 2.12.1 or newer' ; \
+ false ; \
+ fi
+
+CLEAN_FILES += $(TOUT)
+
diff --git a/arch/powerpc/configs/cell_defconfig b/arch/powerpc/configs/cell_defconfig
new file mode 100644
index 000000000000..67ffecbc05cb
--- /dev/null
+++ b/arch/powerpc/configs/cell_defconfig
@@ -0,0 +1,1024 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.14-rc4
+# Thu Oct 20 08:29:10 2005
+#
+CONFIG_64BIT=y
+CONFIG_MMU=y
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_ISA_DMA=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_COMPAT=y
+CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
+CONFIG_FORCE_MAX_ZONEORDER=13
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_HOTPLUG=y
+CONFIG_KOBJECT_UEVENT=y
+# CONFIG_IKCONFIG is not set
+# CONFIG_CPUSETS is not set
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_EMBEDDED is not set
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_OBSOLETE_MODPARM=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+# CONFIG_KMOD is not set
+CONFIG_STOP_MACHINE=y
+CONFIG_SYSVIPC_COMPAT=y
+
+#
+# Platform support
+#
+# CONFIG_PPC_ISERIES is not set
+CONFIG_PPC_MULTIPLATFORM=y
+# CONFIG_PPC_PSERIES is not set
+CONFIG_PPC_BPA=y
+# CONFIG_PPC_PMAC is not set
+# CONFIG_PPC_MAPLE is not set
+CONFIG_PPC=y
+CONFIG_PPC64=y
+CONFIG_PPC_OF=y
+CONFIG_BPA_IIC=y
+CONFIG_ALTIVEC=y
+CONFIG_KEXEC=y
+# CONFIG_U3_DART is not set
+# CONFIG_BOOTX_TEXT is not set
+# CONFIG_POWER4_ONLY is not set
+# CONFIG_IOMMU_VMERGE is not set
+CONFIG_SMP=y
+CONFIG_NR_CPUS=4
+CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_ARCH_FLATMEM_ENABLE=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_NUMA is not set
+CONFIG_SCHED_SMT=y
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_PREEMPT_BKL=y
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_PPC_RTAS=y
+CONFIG_RTAS_PROC=y
+CONFIG_RTAS_FLASH=y
+CONFIG_SECCOMP=y
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+CONFIG_PROC_DEVICETREE=y
+# CONFIG_CMDLINE_BOOL is not set
+CONFIG_ISA_DMA_API=y
+
+#
+# Bus Options
+#
+CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
+CONFIG_PCI_LEGACY_PROC=y
+# CONFIG_PCI_DEBUG is not set
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PCI Hotplug Support
+#
+# CONFIG_HOTPLUG_PCI is not set
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+# CONFIG_IP_PNP is not set
+CONFIG_NET_IPIP=y
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+CONFIG_INET_TUNNEL=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+
+#
+# IP: Virtual Server Configuration
+#
+# CONFIG_IP_VS is not set
+CONFIG_IPV6=y
+# CONFIG_IPV6_PRIVACY is not set
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+CONFIG_INET6_TUNNEL=m
+CONFIG_IPV6_TUNNEL=m
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+# CONFIG_NETFILTER_NETLINK is not set
+
+#
+# IP: Netfilter Configuration
+#
+CONFIG_IP_NF_CONNTRACK=y
+# CONFIG_IP_NF_CT_ACCT is not set
+# CONFIG_IP_NF_CONNTRACK_MARK is not set
+# CONFIG_IP_NF_CONNTRACK_EVENTS is not set
+CONFIG_IP_NF_CT_PROTO_SCTP=y
+CONFIG_IP_NF_FTP=m
+CONFIG_IP_NF_IRC=m
+# CONFIG_IP_NF_NETBIOS_NS is not set
+CONFIG_IP_NF_TFTP=m
+CONFIG_IP_NF_AMANDA=m
+# CONFIG_IP_NF_PPTP is not set
+CONFIG_IP_NF_QUEUE=m
+CONFIG_IP_NF_IPTABLES=m
+CONFIG_IP_NF_MATCH_LIMIT=m
+CONFIG_IP_NF_MATCH_IPRANGE=m
+CONFIG_IP_NF_MATCH_MAC=m
+CONFIG_IP_NF_MATCH_PKTTYPE=m
+CONFIG_IP_NF_MATCH_MARK=m
+CONFIG_IP_NF_MATCH_MULTIPORT=m
+CONFIG_IP_NF_MATCH_TOS=m
+CONFIG_IP_NF_MATCH_RECENT=m
+CONFIG_IP_NF_MATCH_ECN=m
+CONFIG_IP_NF_MATCH_DSCP=m
+CONFIG_IP_NF_MATCH_AH_ESP=m
+CONFIG_IP_NF_MATCH_LENGTH=m
+CONFIG_IP_NF_MATCH_TTL=m
+CONFIG_IP_NF_MATCH_TCPMSS=m
+CONFIG_IP_NF_MATCH_HELPER=m
+CONFIG_IP_NF_MATCH_STATE=m
+CONFIG_IP_NF_MATCH_CONNTRACK=m
+CONFIG_IP_NF_MATCH_OWNER=m
+CONFIG_IP_NF_MATCH_ADDRTYPE=m
+CONFIG_IP_NF_MATCH_REALM=m
+CONFIG_IP_NF_MATCH_SCTP=m
+# CONFIG_IP_NF_MATCH_DCCP is not set
+CONFIG_IP_NF_MATCH_COMMENT=m
+CONFIG_IP_NF_MATCH_HASHLIMIT=m
+CONFIG_IP_NF_MATCH_STRING=m
+CONFIG_IP_NF_FILTER=m
+CONFIG_IP_NF_TARGET_REJECT=m
+CONFIG_IP_NF_TARGET_LOG=m
+CONFIG_IP_NF_TARGET_ULOG=m
+CONFIG_IP_NF_TARGET_TCPMSS=m
+CONFIG_IP_NF_TARGET_NFQUEUE=m
+CONFIG_IP_NF_NAT=m
+CONFIG_IP_NF_NAT_NEEDED=y
+CONFIG_IP_NF_TARGET_MASQUERADE=m
+CONFIG_IP_NF_TARGET_REDIRECT=m
+CONFIG_IP_NF_TARGET_NETMAP=m
+CONFIG_IP_NF_TARGET_SAME=m
+CONFIG_IP_NF_NAT_SNMP_BASIC=m
+CONFIG_IP_NF_NAT_IRC=m
+CONFIG_IP_NF_NAT_FTP=m
+CONFIG_IP_NF_NAT_TFTP=m
+CONFIG_IP_NF_NAT_AMANDA=m
+CONFIG_IP_NF_MANGLE=m
+CONFIG_IP_NF_TARGET_TOS=m
+CONFIG_IP_NF_TARGET_ECN=m
+CONFIG_IP_NF_TARGET_DSCP=m
+CONFIG_IP_NF_TARGET_MARK=m
+CONFIG_IP_NF_TARGET_CLASSIFY=m
+CONFIG_IP_NF_TARGET_TTL=m
+CONFIG_IP_NF_RAW=m
+CONFIG_IP_NF_TARGET_NOTRACK=m
+CONFIG_IP_NF_ARPTABLES=m
+CONFIG_IP_NF_ARPFILTER=m
+CONFIG_IP_NF_ARP_MANGLE=m
+
+#
+# IPv6: Netfilter Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP6_NF_QUEUE is not set
+# CONFIG_IP6_NF_IPTABLES is not set
+# CONFIG_IP6_NF_TARGET_NFQUEUE is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP 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_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+CONFIG_NET_CLS_ROUTE=y
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+# CONFIG_DEBUG_DRIVER is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+CONFIG_BLK_DEV_NBD=y
+# CONFIG_BLK_DEV_SX8 is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=131072
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_CDROM_PKTCDVD is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_ATA_OVER_ETH is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+CONFIG_IDE=y
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_IDE_SATA is not set
+CONFIG_BLK_DEV_IDEDISK=y
+CONFIG_IDEDISK_MULTI_MODE=y
+# CONFIG_BLK_DEV_IDECD is not set
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_BLK_DEV_IDEFLOPPY is not set
+# CONFIG_IDE_TASK_IOCTL is not set
+
+#
+# IDE chipset support/bugfixes
+#
+CONFIG_IDE_GENERIC=y
+CONFIG_BLK_DEV_IDEPCI=y
+CONFIG_IDEPCI_SHARE_IRQ=y
+# CONFIG_BLK_DEV_OFFBOARD is not set
+CONFIG_BLK_DEV_GENERIC=y
+# CONFIG_BLK_DEV_OPTI621 is not set
+# CONFIG_BLK_DEV_SL82C105 is not set
+CONFIG_BLK_DEV_IDEDMA_PCI=y
+# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
+CONFIG_IDEDMA_PCI_AUTO=y
+# CONFIG_IDEDMA_ONLYDISK is not set
+CONFIG_BLK_DEV_AEC62XX=y
+# CONFIG_BLK_DEV_ALI15X3 is not set
+# CONFIG_BLK_DEV_AMD74XX is not set
+# CONFIG_BLK_DEV_CMD64X is not set
+# CONFIG_BLK_DEV_TRIFLEX is not set
+# CONFIG_BLK_DEV_CY82C693 is not set
+# CONFIG_BLK_DEV_CS5520 is not set
+# CONFIG_BLK_DEV_CS5530 is not set
+# CONFIG_BLK_DEV_HPT34X is not set
+# CONFIG_BLK_DEV_HPT366 is not set
+# CONFIG_BLK_DEV_SC1200 is not set
+# CONFIG_BLK_DEV_PIIX is not set
+# CONFIG_BLK_DEV_IT821X is not set
+# CONFIG_BLK_DEV_NS87415 is not set
+# CONFIG_BLK_DEV_PDC202XX_OLD is not set
+# CONFIG_BLK_DEV_PDC202XX_NEW is not set
+# CONFIG_BLK_DEV_SVWKS is not set
+CONFIG_BLK_DEV_SIIMAGE=y
+# CONFIG_BLK_DEV_SLC90E66 is not set
+# CONFIG_BLK_DEV_TRM290 is not set
+# CONFIG_BLK_DEV_VIA82CXXX is not set
+# CONFIG_IDE_ARM is not set
+CONFIG_BLK_DEV_IDEDMA=y
+# CONFIG_IDEDMA_IVB is not set
+CONFIG_IDEDMA_AUTO=y
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+
+#
+# Macintosh device drivers
+#
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
+#
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_CASSINI is not set
+# CONFIG_NET_VENDOR_3COM is not set
+
+#
+# Tulip family network device support
+#
+# CONFIG_NET_TULIP is not set
+# CONFIG_HP100 is not set
+# CONFIG_NET_PCI is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+CONFIG_E1000=m
+# CONFIG_E1000_NAPI is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
+CONFIG_SKGE=m
+# CONFIG_SK98LIN is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
+# CONFIG_SPIDER_NET is not set
+# CONFIG_MV643XX_ETH is not set
+
+#
+# Ethernet (10000 Mbit)
+#
+# CONFIG_CHELSIO_T1 is not set
+# CONFIG_IXGB is not set
+# CONFIG_S2IO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_PCIPS2 is not set
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+CONFIG_SERIAL_NONSTANDARD=y
+# CONFIG_ROCKETPORT is not set
+# CONFIG_CYCLADES is not set
+# CONFIG_DIGIEPCA is not set
+# CONFIG_MOXA_SMARTIO is not set
+# CONFIG_ISI is not set
+# CONFIG_SYNCLINK is not set
+# CONFIG_SYNCLINKMP is not set
+# CONFIG_N_HDLC is not set
+# CONFIG_SPECIALIX is not set
+# CONFIG_SX is not set
+# CONFIG_STALDRV is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=4
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
+CONFIG_UNIX98_PTYS=y
+# CONFIG_LEGACY_PTYS is not set
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+CONFIG_WATCHDOG_RTAS=y
+
+#
+# PCI-based Watchdog Cards
+#
+# CONFIG_PCIPCWATCHDOG is not set
+# CONFIG_WDTPCI is not set
+# CONFIG_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_HANGCHECK_TIMER is not set
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+
+#
+# I2C support
+#
+CONFIG_I2C=y
+# CONFIG_I2C_CHARDEV is not set
+
+#
+# I2C Algorithms
+#
+CONFIG_I2C_ALGOBIT=y
+# CONFIG_I2C_ALGOPCF is not set
+# CONFIG_I2C_ALGOPCA is not set
+
+#
+# I2C Hardware Bus support
+#
+# 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_PIIX4 is not set
+# CONFIG_I2C_NFORCE2 is not set
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_PROSAVAGE is not set
+# CONFIG_I2C_SAVAGE4 is not set
+# CONFIG_SCx200_ACB is not set
+# CONFIG_I2C_SIS5595 is not set
+# CONFIG_I2C_SIS630 is not set
+# CONFIG_I2C_SIS96X is not set
+# CONFIG_I2C_STUB is not set
+# CONFIG_I2C_VIA is not set
+# CONFIG_I2C_VIAPRO is not set
+# CONFIG_I2C_VOODOO3 is not set
+# CONFIG_I2C_PCA_ISA is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_SENSORS_DS1337 is not set
+# CONFIG_SENSORS_DS1374 is not set
+# CONFIG_SENSORS_EEPROM is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_SENSORS_PCA9539 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_SENSORS_RTC8564 is not set
+# CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
+#
+# Misc devices
+#
+
+#
+# Multimedia Capabilities Port drivers
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+# CONFIG_FB is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+# CONFIG_USB is not set
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
+# SN Devices
+#
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_XATTR=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
+# CONFIG_EXT3_FS_SECURITY is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+# CONFIG_XFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=m
+CONFIG_JOLIET=y
+# CONFIG_ZISOFS is not set
+CONFIG_UDF_FS=m
+CONFIG_UDF_NLS=y
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+CONFIG_HUGETLBFS=y
+CONFIG_HUGETLB_PAGE=y
+CONFIG_RAMFS=y
+# CONFIG_RELAYFS_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_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=m
+CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFS_DIRECTIO is not set
+CONFIG_NFSD=m
+CONFIG_NFSD_V2_ACL=y
+CONFIG_NFSD_V3=y
+CONFIG_NFSD_V3_ACL=y
+# CONFIG_NFSD_V4 is not set
+CONFIG_NFSD_TCP=y
+CONFIG_LOCKD=m
+CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=m
+CONFIG_NFS_ACL_SUPPORT=m
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=m
+# 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
+# CONFIG_9P_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+CONFIG_EFI_PARTITION=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS=m
+CONFIG_NLS_DEFAULT="iso8859-1"
+# CONFIG_NLS_CODEPAGE_437 is not set
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+CONFIG_NLS_ISO8859_1=m
+CONFIG_NLS_ISO8859_2=m
+CONFIG_NLS_ISO8859_3=m
+CONFIG_NLS_ISO8859_4=m
+CONFIG_NLS_ISO8859_5=m
+CONFIG_NLS_ISO8859_6=m
+CONFIG_NLS_ISO8859_7=m
+CONFIG_NLS_ISO8859_9=m
+CONFIG_NLS_ISO8859_13=m
+CONFIG_NLS_ISO8859_14=m
+CONFIG_NLS_ISO8859_15=m
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_DEBUG_KERNEL=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_LOG_BUF_SHIFT=15
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+CONFIG_DEBUG_SPINLOCK_SLEEP=y
+# CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_INFO is not set
+CONFIG_DEBUG_FS=y
+# CONFIG_DEBUG_STACKOVERFLOW is not set
+# CONFIG_KPROBES is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+CONFIG_DEBUGGER=y
+# CONFIG_XMON is not set
+# CONFIG_PPCDBG is not set
+CONFIG_IRQSTACKS=y
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_HMAC=y
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_MD4 is not set
+CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_SHA1=m
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_WP512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+CONFIG_CRYPTO_DES=m
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+CONFIG_CRYPTO_DEFLATE=m
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Hardware crypto devices
+#
+
+#
+# Library routines
+#
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+CONFIG_CRC32=y
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=m
+CONFIG_ZLIB_DEFLATE=m
+CONFIG_TEXTSEARCH=y
+CONFIG_TEXTSEARCH_KMP=m
+CONFIG_TEXTSEARCH_BM=m
+CONFIG_TEXTSEARCH_FSM=m
diff --git a/arch/powerpc/configs/g5_defconfig b/arch/powerpc/configs/g5_defconfig
new file mode 100644
index 000000000000..e76854f8c121
--- /dev/null
+++ b/arch/powerpc/configs/g5_defconfig
@@ -0,0 +1,1543 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.14
+# Mon Nov 7 13:37:59 2005
+#
+CONFIG_PPC64=y
+CONFIG_64BIT=y
+CONFIG_PPC_MERGE=y
+CONFIG_MMU=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_PPC=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_COMPAT=y
+CONFIG_SYSVIPC_COMPAT=y
+CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
+
+#
+# Processor support
+#
+CONFIG_POWER4_ONLY=y
+CONFIG_POWER4=y
+CONFIG_PPC_FPU=y
+CONFIG_ALTIVEC=y
+CONFIG_PPC_STD_MMU=y
+CONFIG_SMP=y
+CONFIG_NR_CPUS=2
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_HOTPLUG=y
+CONFIG_KOBJECT_UEVENT=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+# CONFIG_CPUSETS is not set
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_EMBEDDED is not set
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_OBSOLETE_MODPARM=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_KMOD=y
+CONFIG_STOP_MACHINE=y
+
+#
+# Platform support
+#
+CONFIG_PPC_MULTIPLATFORM=y
+# CONFIG_PPC_ISERIES is not set
+# CONFIG_EMBEDDED6xx is not set
+# CONFIG_APUS is not set
+# CONFIG_PPC_PSERIES is not set
+CONFIG_PPC_PMAC=y
+CONFIG_PPC_PMAC64=y
+# CONFIG_PPC_MAPLE is not set
+# CONFIG_PPC_CELL is not set
+CONFIG_PPC_OF=y
+CONFIG_U3_DART=y
+CONFIG_MPIC=y
+# CONFIG_PPC_RTAS is not set
+# CONFIG_MMIO_NVRAM is not set
+# CONFIG_PPC_MPC106 is not set
+CONFIG_GENERIC_TBSYNC=y
+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_USERSPACE is not set
+CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
+CONFIG_CPU_FREQ_GOV_POWERSAVE=y
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+# CONFIG_CPU_FREQ_GOV_ONDEMAND is not set
+# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set
+CONFIG_CPU_FREQ_PMAC64=y
+# CONFIG_WANT_EARLY_SERIAL is not set
+
+#
+# Kernel options
+#
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+# CONFIG_PREEMPT_BKL is not set
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+CONFIG_FORCE_MAX_ZONEORDER=13
+CONFIG_IOMMU_VMERGE=y
+# CONFIG_HOTPLUG_CPU is not set
+CONFIG_KEXEC=y
+CONFIG_IRQ_ALL_CPUS=y
+# CONFIG_NUMA is not set
+CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_ARCH_FLATMEM_ENABLE=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_SPLIT_PTLOCK_CPUS=4
+# CONFIG_PPC_64K_PAGES is not set
+# CONFIG_SCHED_SMT is not set
+CONFIG_PROC_DEVICETREE=y
+# CONFIG_CMDLINE_BOOL is not set
+# CONFIG_PM is not set
+CONFIG_SECCOMP=y
+CONFIG_ISA_DMA_API=y
+
+#
+# Bus options
+#
+CONFIG_GENERIC_ISA_DMA=y
+# CONFIG_PPC_I8259 is not set
+# CONFIG_PPC_INDIRECT_PCI is not set
+CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
+CONFIG_PCI_LEGACY_PROC=y
+# CONFIG_PCI_DEBUG is not set
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PCI Hotplug Support
+#
+# CONFIG_HOTPLUG_PCI is not set
+CONFIG_KERNEL_START=0xc000000000000000
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+CONFIG_NET_KEY=m
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+# CONFIG_IP_PNP is not set
+CONFIG_NET_IPIP=y
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+CONFIG_INET_AH=m
+CONFIG_INET_ESP=m
+CONFIG_INET_IPCOMP=m
+CONFIG_INET_TUNNEL=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+
+#
+# IP: Virtual Server Configuration
+#
+# CONFIG_IP_VS is not set
+# CONFIG_IPV6 is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+# CONFIG_NETFILTER_NETLINK is not set
+
+#
+# IP: Netfilter Configuration
+#
+CONFIG_IP_NF_CONNTRACK=m
+CONFIG_IP_NF_CT_ACCT=y
+CONFIG_IP_NF_CONNTRACK_MARK=y
+CONFIG_IP_NF_CONNTRACK_EVENTS=y
+CONFIG_IP_NF_CT_PROTO_SCTP=m
+CONFIG_IP_NF_FTP=m
+CONFIG_IP_NF_IRC=m
+# CONFIG_IP_NF_NETBIOS_NS is not set
+CONFIG_IP_NF_TFTP=m
+CONFIG_IP_NF_AMANDA=m
+# CONFIG_IP_NF_PPTP is not set
+CONFIG_IP_NF_QUEUE=m
+CONFIG_IP_NF_IPTABLES=m
+CONFIG_IP_NF_MATCH_LIMIT=m
+CONFIG_IP_NF_MATCH_IPRANGE=m
+CONFIG_IP_NF_MATCH_MAC=m
+CONFIG_IP_NF_MATCH_PKTTYPE=m
+CONFIG_IP_NF_MATCH_MARK=m
+CONFIG_IP_NF_MATCH_MULTIPORT=m
+CONFIG_IP_NF_MATCH_TOS=m
+CONFIG_IP_NF_MATCH_RECENT=m
+CONFIG_IP_NF_MATCH_ECN=m
+CONFIG_IP_NF_MATCH_DSCP=m
+CONFIG_IP_NF_MATCH_AH_ESP=m
+CONFIG_IP_NF_MATCH_LENGTH=m
+CONFIG_IP_NF_MATCH_TTL=m
+CONFIG_IP_NF_MATCH_TCPMSS=m
+CONFIG_IP_NF_MATCH_HELPER=m
+CONFIG_IP_NF_MATCH_STATE=m
+CONFIG_IP_NF_MATCH_CONNTRACK=m
+CONFIG_IP_NF_MATCH_OWNER=m
+CONFIG_IP_NF_MATCH_ADDRTYPE=m
+CONFIG_IP_NF_MATCH_REALM=m
+CONFIG_IP_NF_MATCH_SCTP=m
+# CONFIG_IP_NF_MATCH_DCCP is not set
+CONFIG_IP_NF_MATCH_COMMENT=m
+CONFIG_IP_NF_MATCH_CONNMARK=m
+CONFIG_IP_NF_MATCH_CONNBYTES=m
+CONFIG_IP_NF_MATCH_HASHLIMIT=m
+CONFIG_IP_NF_MATCH_STRING=m
+CONFIG_IP_NF_FILTER=m
+CONFIG_IP_NF_TARGET_REJECT=m
+CONFIG_IP_NF_TARGET_LOG=m
+CONFIG_IP_NF_TARGET_ULOG=m
+CONFIG_IP_NF_TARGET_TCPMSS=m
+CONFIG_IP_NF_TARGET_NFQUEUE=m
+CONFIG_IP_NF_NAT=m
+CONFIG_IP_NF_NAT_NEEDED=y
+CONFIG_IP_NF_TARGET_MASQUERADE=m
+CONFIG_IP_NF_TARGET_REDIRECT=m
+CONFIG_IP_NF_TARGET_NETMAP=m
+CONFIG_IP_NF_TARGET_SAME=m
+CONFIG_IP_NF_NAT_SNMP_BASIC=m
+CONFIG_IP_NF_NAT_IRC=m
+CONFIG_IP_NF_NAT_FTP=m
+CONFIG_IP_NF_NAT_TFTP=m
+CONFIG_IP_NF_NAT_AMANDA=m
+CONFIG_IP_NF_MANGLE=m
+CONFIG_IP_NF_TARGET_TOS=m
+CONFIG_IP_NF_TARGET_ECN=m
+CONFIG_IP_NF_TARGET_DSCP=m
+CONFIG_IP_NF_TARGET_MARK=m
+CONFIG_IP_NF_TARGET_CLASSIFY=m
+CONFIG_IP_NF_TARGET_TTL=m
+CONFIG_IP_NF_TARGET_CONNMARK=m
+CONFIG_IP_NF_TARGET_CLUSTERIP=m
+CONFIG_IP_NF_RAW=m
+CONFIG_IP_NF_TARGET_NOTRACK=m
+CONFIG_IP_NF_ARPTABLES=m
+CONFIG_IP_NF_ARPFILTER=m
+CONFIG_IP_NF_ARP_MANGLE=m
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP 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_LLC=y
+# 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_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+CONFIG_NET_CLS_ROUTE=y
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+# CONFIG_DEBUG_DRIVER is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+CONFIG_BLK_DEV_NBD=m
+# CONFIG_BLK_DEV_SX8 is not set
+# CONFIG_BLK_DEV_UB is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=65536
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_CDROM_PKTCDVD=m
+CONFIG_CDROM_PKTCDVD_BUFFERS=8
+# CONFIG_CDROM_PKTCDVD_WCACHE 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_ATA_OVER_ETH is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+CONFIG_IDE=y
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_IDE_SATA is not set
+CONFIG_BLK_DEV_IDEDISK=y
+# CONFIG_IDEDISK_MULTI_MODE is not set
+CONFIG_BLK_DEV_IDECD=y
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_BLK_DEV_IDEFLOPPY is not set
+# CONFIG_BLK_DEV_IDESCSI is not set
+# CONFIG_IDE_TASK_IOCTL is not set
+
+#
+# IDE chipset support/bugfixes
+#
+CONFIG_IDE_GENERIC=y
+CONFIG_BLK_DEV_IDEPCI=y
+# CONFIG_IDEPCI_SHARE_IRQ is not set
+# CONFIG_BLK_DEV_OFFBOARD is not set
+# CONFIG_BLK_DEV_GENERIC is not set
+# CONFIG_BLK_DEV_OPTI621 is not set
+# CONFIG_BLK_DEV_SL82C105 is not set
+CONFIG_BLK_DEV_IDEDMA_PCI=y
+# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
+CONFIG_IDEDMA_PCI_AUTO=y
+# CONFIG_IDEDMA_ONLYDISK is not set
+# CONFIG_BLK_DEV_AEC62XX is not set
+# CONFIG_BLK_DEV_ALI15X3 is not set
+# CONFIG_BLK_DEV_AMD74XX is not set
+# CONFIG_BLK_DEV_CMD64X is not set
+# CONFIG_BLK_DEV_TRIFLEX is not set
+# CONFIG_BLK_DEV_CY82C693 is not set
+# CONFIG_BLK_DEV_CS5520 is not set
+# CONFIG_BLK_DEV_CS5530 is not set
+# CONFIG_BLK_DEV_HPT34X is not set
+# CONFIG_BLK_DEV_HPT366 is not set
+# CONFIG_BLK_DEV_SC1200 is not set
+# CONFIG_BLK_DEV_PIIX is not set
+# CONFIG_BLK_DEV_IT821X is not set
+# CONFIG_BLK_DEV_NS87415 is not set
+# CONFIG_BLK_DEV_PDC202XX_OLD is not set
+# CONFIG_BLK_DEV_PDC202XX_NEW is not set
+# CONFIG_BLK_DEV_SVWKS is not set
+# CONFIG_BLK_DEV_SIIMAGE is not set
+# CONFIG_BLK_DEV_SLC90E66 is not set
+# CONFIG_BLK_DEV_TRM290 is not set
+# CONFIG_BLK_DEV_VIA82CXXX is not set
+CONFIG_BLK_DEV_IDE_PMAC=y
+CONFIG_BLK_DEV_IDE_PMAC_ATA100FIRST=y
+CONFIG_BLK_DEV_IDEDMA_PMAC=y
+# CONFIG_BLK_DEV_IDE_PMAC_BLINK is not set
+# CONFIG_IDE_ARM is not set
+CONFIG_BLK_DEV_IDEDMA=y
+# CONFIG_IDEDMA_IVB is not set
+CONFIG_IDEDMA_AUTO=y
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_ST=y
+# CONFIG_CHR_DEV_OSST is not set
+CONFIG_BLK_DEV_SR=y
+CONFIG_BLK_DEV_SR_VENDOR=y
+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=y
+CONFIG_SCSI_CONSTANTS=y
+# CONFIG_SCSI_LOGGING is not set
+
+#
+# SCSI Transport Attributes
+#
+CONFIG_SCSI_SPI_ATTRS=y
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_ATTRS is not set
+
+#
+# SCSI low-level drivers
+#
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_ACARD is not set
+# CONFIG_SCSI_AACRAID is not set
+# CONFIG_SCSI_AIC7XXX is not set
+# CONFIG_SCSI_AIC7XXX_OLD is not set
+# CONFIG_SCSI_AIC79XX is not set
+# CONFIG_MEGARAID_NEWGEN is not set
+# CONFIG_MEGARAID_LEGACY is not set
+# CONFIG_MEGARAID_SAS is not set
+CONFIG_SCSI_SATA=y
+# CONFIG_SCSI_SATA_AHCI is not set
+CONFIG_SCSI_SATA_SVW=y
+# CONFIG_SCSI_ATA_PIIX is not set
+# CONFIG_SCSI_SATA_MV is not set
+# CONFIG_SCSI_SATA_NV is not set
+# CONFIG_SCSI_PDC_ADMA is not set
+# CONFIG_SCSI_SATA_QSTOR is not set
+# CONFIG_SCSI_SATA_PROMISE is not set
+# CONFIG_SCSI_SATA_SX4 is not set
+# CONFIG_SCSI_SATA_SIL is not set
+# CONFIG_SCSI_SATA_SIL24 is not set
+# CONFIG_SCSI_SATA_SIS is not set
+# CONFIG_SCSI_SATA_ULI is not set
+# CONFIG_SCSI_SATA_VIA is not set
+# CONFIG_SCSI_SATA_VITESSE is not set
+# CONFIG_SCSI_BUSLOGIC is not set
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_EATA is not set
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+# CONFIG_SCSI_GDTH is not set
+# CONFIG_SCSI_IPS is not set
+# CONFIG_SCSI_INITIO is not set
+# CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_SYM53C8XX_2 is not set
+# CONFIG_SCSI_IPR is not set
+# CONFIG_SCSI_QLOGIC_FC is not set
+# CONFIG_SCSI_QLOGIC_1280 is not set
+CONFIG_SCSI_QLA2XXX=y
+# CONFIG_SCSI_QLA21XX is not set
+# CONFIG_SCSI_QLA22XX is not set
+# CONFIG_SCSI_QLA2300 is not set
+# CONFIG_SCSI_QLA2322 is not set
+# CONFIG_SCSI_QLA6312 is not set
+# CONFIG_SCSI_QLA24XX is not set
+# CONFIG_SCSI_LPFC is not set
+# CONFIG_SCSI_DC395x is not set
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_DEBUG is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+CONFIG_MD=y
+CONFIG_BLK_DEV_MD=y
+CONFIG_MD_LINEAR=y
+CONFIG_MD_RAID0=y
+CONFIG_MD_RAID1=y
+CONFIG_MD_RAID10=m
+CONFIG_MD_RAID5=y
+CONFIG_MD_RAID6=m
+CONFIG_MD_MULTIPATH=m
+CONFIG_MD_FAULTY=m
+CONFIG_BLK_DEV_DM=y
+CONFIG_DM_CRYPT=m
+CONFIG_DM_SNAPSHOT=m
+CONFIG_DM_MIRROR=m
+CONFIG_DM_ZERO=m
+# CONFIG_DM_MULTIPATH is not set
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+# CONFIG_FUSION_SPI is not set
+# CONFIG_FUSION_FC is not set
+# CONFIG_FUSION_SAS is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+CONFIG_IEEE1394=y
+
+#
+# Subsystem Options
+#
+# CONFIG_IEEE1394_VERBOSEDEBUG is not set
+CONFIG_IEEE1394_OUI_DB=y
+CONFIG_IEEE1394_EXTRA_CONFIG_ROMS=y
+CONFIG_IEEE1394_CONFIG_ROM_IP1394=y
+# CONFIG_IEEE1394_EXPORT_FULL_API is not set
+
+#
+# Device Drivers
+#
+# CONFIG_IEEE1394_PCILYNX is not set
+CONFIG_IEEE1394_OHCI1394=y
+
+#
+# Protocol Drivers
+#
+CONFIG_IEEE1394_VIDEO1394=m
+CONFIG_IEEE1394_SBP2=m
+# CONFIG_IEEE1394_SBP2_PHYS_DMA is not set
+CONFIG_IEEE1394_ETH1394=m
+CONFIG_IEEE1394_DV1394=m
+CONFIG_IEEE1394_RAWIO=y
+# CONFIG_IEEE1394_CMP is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+
+#
+# Macintosh device drivers
+#
+CONFIG_ADB_PMU=y
+CONFIG_PMAC_SMU=y
+CONFIG_THERM_PM72=y
+CONFIG_WINDFARM=y
+CONFIG_WINDFARM_PM81=y
+CONFIG_WINDFARM_PM91=y
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+CONFIG_DUMMY=m
+CONFIG_BONDING=m
+# CONFIG_EQUALIZER is not set
+CONFIG_TUN=m
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
+#
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_HAPPYMEAL is not set
+CONFIG_SUNGEM=y
+# CONFIG_CASSINI is not set
+# CONFIG_NET_VENDOR_3COM is not set
+
+#
+# Tulip family network device support
+#
+# CONFIG_NET_TULIP is not set
+# CONFIG_HP100 is not set
+# CONFIG_NET_PCI is not set
+# CONFIG_FEC_8XX is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+CONFIG_ACENIC=y
+CONFIG_ACENIC_OMIT_TIGON_I=y
+# CONFIG_DL2K is not set
+CONFIG_E1000=y
+# CONFIG_E1000_NAPI is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
+# CONFIG_SK98LIN is not set
+CONFIG_TIGON3=m
+# CONFIG_BNX2 is not set
+# CONFIG_MV643XX_ETH is not set
+
+#
+# Ethernet (10000 Mbit)
+#
+# CONFIG_CHELSIO_T1 is not set
+# CONFIG_IXGB is not set
+# CONFIG_S2IO is not set
+
+#
+# Token Ring devices
+#
+CONFIG_TR=y
+CONFIG_IBMOL=y
+# CONFIG_3C359 is not set
+# CONFIG_TMS380TR is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+CONFIG_PPP=m
+# CONFIG_PPP_MULTILINK is not set
+# CONFIG_PPP_FILTER is not set
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_BSDCOMP=m
+CONFIG_PPPOE=m
+# CONFIG_SLIP is not set
+# CONFIG_NET_FC is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+CONFIG_INPUT_JOYDEV=m
+# CONFIG_INPUT_TSDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+# CONFIG_KEYBOARD_ATKBD is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+CONFIG_INPUT_MOUSE=y
+# CONFIG_MOUSE_PS2 is not set
+# CONFIG_MOUSE_SERIAL is not set
+# CONFIG_MOUSE_VSXXXAA is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+# CONFIG_SERIO_SERPORT is not set
+# CONFIG_SERIO_PCIPS2 is not set
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_PMACZILOG is not set
+# CONFIG_SERIAL_JSM is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+CONFIG_AGP=m
+CONFIG_AGP_UNINORTH=m
+# CONFIG_DRM is not set
+CONFIG_RAW_DRIVER=y
+CONFIG_MAX_RAW_DEVS=256
+# CONFIG_HANGCHECK_TIMER is not set
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+# CONFIG_TELCLOCK is not set
+
+#
+# I2C support
+#
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+
+#
+# I2C Algorithms
+#
+CONFIG_I2C_ALGOBIT=y
+# CONFIG_I2C_ALGOPCF is not set
+# CONFIG_I2C_ALGOPCA is not set
+
+#
+# I2C Hardware Bus support
+#
+# 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_PIIX4 is not set
+CONFIG_I2C_KEYWEST=y
+CONFIG_I2C_PMAC_SMU=y
+# CONFIG_I2C_NFORCE2 is not set
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_PROSAVAGE is not set
+# CONFIG_I2C_SAVAGE4 is not set
+# CONFIG_SCx200_ACB is not set
+# CONFIG_I2C_SIS5595 is not set
+# CONFIG_I2C_SIS630 is not set
+# CONFIG_I2C_SIS96X is not set
+# CONFIG_I2C_STUB is not set
+# CONFIG_I2C_VIA is not set
+# CONFIG_I2C_VIAPRO is not set
+# CONFIG_I2C_VOODOO3 is not set
+# CONFIG_I2C_PCA_ISA is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_SENSORS_DS1337 is not set
+# CONFIG_SENSORS_DS1374 is not set
+# CONFIG_SENSORS_EEPROM is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_SENSORS_PCA9539 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_SENSORS_RTC8564 is not set
+# CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_RTC_X1205_I2C 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
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
+#
+# Misc devices
+#
+
+#
+# Multimedia Capabilities Port drivers
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+CONFIG_FB=y
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+CONFIG_FB_SOFT_CURSOR=y
+CONFIG_FB_MACMODES=y
+CONFIG_FB_MODE_HELPERS=y
+CONFIG_FB_TILEBLITTING=y
+# CONFIG_FB_CIRRUS is not set
+# CONFIG_FB_PM2 is not set
+# CONFIG_FB_CYBER2000 is not set
+CONFIG_FB_OF=y
+# CONFIG_FB_CONTROL is not set
+# CONFIG_FB_PLATINUM is not set
+# CONFIG_FB_VALKYRIE is not set
+# CONFIG_FB_CT65550 is not set
+# CONFIG_FB_ASILIANT is not set
+# CONFIG_FB_IMSTT is not set
+# CONFIG_FB_VGA16 is not set
+CONFIG_FB_NVIDIA=y
+CONFIG_FB_NVIDIA_I2C=y
+# CONFIG_FB_RIVA is not set
+# CONFIG_FB_MATROX is not set
+# CONFIG_FB_RADEON_OLD is not set
+CONFIG_FB_RADEON=y
+CONFIG_FB_RADEON_I2C=y
+# CONFIG_FB_RADEON_DEBUG is not set
+# CONFIG_FB_ATY128 is not set
+# CONFIG_FB_ATY is not set
+# CONFIG_FB_SAVAGE is not set
+# CONFIG_FB_SIS is not set
+# CONFIG_FB_NEOMAGIC is not set
+# CONFIG_FB_KYRO is not set
+# CONFIG_FB_3DFX is not set
+# CONFIG_FB_VOODOO1 is not set
+# CONFIG_FB_CYBLA is not set
+# CONFIG_FB_TRIDENT is not set
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_VIRTUAL is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FONTS is not set
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+
+#
+# Logo configuration
+#
+CONFIG_LOGO=y
+CONFIG_LOGO_LINUX_MONO=y
+CONFIG_LOGO_LINUX_VGA16=y
+CONFIG_LOGO_LINUX_CLUT224=y
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_BACKLIGHT_CLASS_DEVICE=m
+CONFIG_BACKLIGHT_DEVICE=y
+CONFIG_LCD_CLASS_DEVICE=m
+CONFIG_LCD_DEVICE=y
+
+#
+# Sound
+#
+CONFIG_SOUND=m
+
+#
+# Advanced Linux Sound Architecture
+#
+CONFIG_SND=m
+CONFIG_SND_TIMER=m
+CONFIG_SND_PCM=m
+CONFIG_SND_HWDEP=m
+CONFIG_SND_RAWMIDI=m
+CONFIG_SND_SEQUENCER=m
+# CONFIG_SND_SEQ_DUMMY is not set
+CONFIG_SND_OSSEMUL=y
+CONFIG_SND_MIXER_OSS=m
+CONFIG_SND_PCM_OSS=m
+CONFIG_SND_SEQUENCER_OSS=y
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+CONFIG_SND_GENERIC_DRIVER=y
+
+#
+# Generic devices
+#
+# CONFIG_SND_DUMMY is not set
+# CONFIG_SND_VIRMIDI is not set
+# CONFIG_SND_MTPAV is not set
+# CONFIG_SND_SERIAL_U16550 is not set
+# CONFIG_SND_MPU401 is not set
+
+#
+# PCI devices
+#
+# CONFIG_SND_ALI5451 is not set
+# CONFIG_SND_ATIIXP is not set
+# CONFIG_SND_ATIIXP_MODEM is not set
+# CONFIG_SND_AU8810 is not set
+# CONFIG_SND_AU8820 is not set
+# CONFIG_SND_AU8830 is not set
+# CONFIG_SND_AZT3328 is not set
+# CONFIG_SND_BT87X is not set
+# CONFIG_SND_CS46XX is not set
+# CONFIG_SND_CS4281 is not set
+# CONFIG_SND_EMU10K1 is not set
+# CONFIG_SND_EMU10K1X is not set
+# CONFIG_SND_CA0106 is not set
+# CONFIG_SND_KORG1212 is not set
+# CONFIG_SND_MIXART is not set
+# CONFIG_SND_NM256 is not set
+# CONFIG_SND_RME32 is not set
+# CONFIG_SND_RME96 is not set
+# CONFIG_SND_RME9652 is not set
+# CONFIG_SND_HDSP is not set
+# CONFIG_SND_HDSPM is not set
+# CONFIG_SND_TRIDENT is not set
+# CONFIG_SND_YMFPCI is not set
+# CONFIG_SND_AD1889 is not set
+# CONFIG_SND_ALS4000 is not set
+# CONFIG_SND_CMIPCI is not set
+# CONFIG_SND_ENS1370 is not set
+# CONFIG_SND_ENS1371 is not set
+# CONFIG_SND_ES1938 is not set
+# CONFIG_SND_ES1968 is not set
+# CONFIG_SND_MAESTRO3 is not set
+# CONFIG_SND_FM801 is not set
+# CONFIG_SND_ICE1712 is not set
+# CONFIG_SND_ICE1724 is not set
+# CONFIG_SND_INTEL8X0 is not set
+# CONFIG_SND_INTEL8X0M is not set
+# CONFIG_SND_SONICVIBES is not set
+# CONFIG_SND_VIA82XX is not set
+# CONFIG_SND_VIA82XX_MODEM is not set
+# CONFIG_SND_VX222 is not set
+# CONFIG_SND_HDA_INTEL is not set
+
+#
+# ALSA PowerMac devices
+#
+CONFIG_SND_POWERMAC=m
+CONFIG_SND_POWERMAC_AUTO_DRC=y
+
+#
+# USB devices
+#
+CONFIG_SND_USB_AUDIO=m
+# CONFIG_SND_USB_USX2Y is not set
+
+#
+# Open Sound System
+#
+# CONFIG_SOUND_PRIME is not set
+
+#
+# USB support
+#
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+# CONFIG_USB_BANDWIDTH is not set
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_OTG is not set
+
+#
+# USB Host Controller Drivers
+#
+CONFIG_USB_EHCI_HCD=y
+# CONFIG_USB_EHCI_SPLIT_ISO is not set
+# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
+# CONFIG_USB_ISP116X_HCD is not set
+CONFIG_USB_OHCI_HCD=y
+# CONFIG_USB_OHCI_BIG_ENDIAN is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+# CONFIG_USB_UHCI_HCD is not set
+# CONFIG_USB_SL811_HCD is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_OBSOLETE_OSS_USB_DRIVER is not set
+CONFIG_USB_ACM=m
+CONFIG_USB_PRINTER=y
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# may also be needed; see USB_STORAGE Help for more information
+#
+CONFIG_USB_STORAGE=y
+# CONFIG_USB_STORAGE_DEBUG is not set
+CONFIG_USB_STORAGE_DATAFAB=y
+CONFIG_USB_STORAGE_FREECOM=y
+CONFIG_USB_STORAGE_ISD200=y
+CONFIG_USB_STORAGE_DPCM=y
+# CONFIG_USB_STORAGE_USBAT is not set
+CONFIG_USB_STORAGE_SDDR09=y
+CONFIG_USB_STORAGE_SDDR55=y
+CONFIG_USB_STORAGE_JUMPSHOT=y
+# CONFIG_USB_STORAGE_ONETOUCH is not set
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=y
+CONFIG_USB_HIDINPUT=y
+CONFIG_HID_FF=y
+CONFIG_HID_PID=y
+CONFIG_LOGITECH_FF=y
+CONFIG_THRUSTMASTER_FF=y
+CONFIG_USB_HIDDEV=y
+# CONFIG_USB_AIPTEK is not set
+# CONFIG_USB_WACOM is not set
+# CONFIG_USB_ACECAD is not set
+# CONFIG_USB_KBTAB is not set
+# CONFIG_USB_POWERMATE is not set
+# CONFIG_USB_MTOUCH is not set
+# CONFIG_USB_ITMTOUCH is not set
+# CONFIG_USB_EGALAX is not set
+# CONFIG_USB_YEALINK is not set
+# CONFIG_USB_XPAD is not set
+# CONFIG_USB_ATI_REMOTE is not set
+# CONFIG_USB_KEYSPAN_REMOTE is not set
+# CONFIG_USB_APPLETOUCH is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+
+#
+# USB Multimedia devices
+#
+# CONFIG_USB_DABUSB is not set
+
+#
+# Video4Linux support is needed for USB Multimedia device support
+#
+
+#
+# USB Network Adapters
+#
+CONFIG_USB_CATC=m
+CONFIG_USB_KAWETH=m
+CONFIG_USB_PEGASUS=m
+CONFIG_USB_RTL8150=m
+CONFIG_USB_USBNET=m
+# CONFIG_USB_NET_AX8817X is not set
+CONFIG_USB_NET_CDCETHER=m
+# CONFIG_USB_NET_GL620A is not set
+# CONFIG_USB_NET_NET1080 is not set
+# CONFIG_USB_NET_PLUSB is not set
+# CONFIG_USB_NET_RNDIS_HOST is not set
+# CONFIG_USB_NET_CDC_SUBSET is not set
+# CONFIG_USB_NET_ZAURUS is not set
+CONFIG_USB_MON=y
+
+#
+# USB port drivers
+#
+
+#
+# USB Serial Converter support
+#
+CONFIG_USB_SERIAL=m
+CONFIG_USB_SERIAL_GENERIC=y
+# CONFIG_USB_SERIAL_AIRPRIME is not set
+CONFIG_USB_SERIAL_BELKIN=m
+CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m
+# CONFIG_USB_SERIAL_CP2101 is not set
+CONFIG_USB_SERIAL_CYPRESS_M8=m
+CONFIG_USB_SERIAL_EMPEG=m
+CONFIG_USB_SERIAL_FTDI_SIO=m
+CONFIG_USB_SERIAL_VISOR=m
+CONFIG_USB_SERIAL_IPAQ=m
+CONFIG_USB_SERIAL_IR=m
+CONFIG_USB_SERIAL_EDGEPORT=m
+CONFIG_USB_SERIAL_EDGEPORT_TI=m
+CONFIG_USB_SERIAL_GARMIN=m
+CONFIG_USB_SERIAL_IPW=m
+CONFIG_USB_SERIAL_KEYSPAN_PDA=m
+CONFIG_USB_SERIAL_KEYSPAN=m
+CONFIG_USB_SERIAL_KEYSPAN_MPR=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28X=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28XA=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28XB=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19=y
+CONFIG_USB_SERIAL_KEYSPAN_USA18X=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19W=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19QW=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19QI=y
+CONFIG_USB_SERIAL_KEYSPAN_USA49W=y
+CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y
+CONFIG_USB_SERIAL_KLSI=m
+CONFIG_USB_SERIAL_KOBIL_SCT=m
+CONFIG_USB_SERIAL_MCT_U232=m
+# CONFIG_USB_SERIAL_NOKIA_DKU2 is not set
+CONFIG_USB_SERIAL_PL2303=m
+# CONFIG_USB_SERIAL_HP4X is not set
+CONFIG_USB_SERIAL_SAFE=m
+CONFIG_USB_SERIAL_SAFE_PADDED=y
+CONFIG_USB_SERIAL_TI=m
+CONFIG_USB_SERIAL_CYBERJACK=m
+CONFIG_USB_SERIAL_XIRCOM=m
+CONFIG_USB_SERIAL_OMNINET=m
+CONFIG_USB_EZUSB=y
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_AUERSWALD is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_PHIDGETKIT is not set
+# CONFIG_USB_PHIDGETSERVO is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_SISUSBVGA is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TEST is not set
+
+#
+# USB DSL modem support
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
+# SN Devices
+#
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+CONFIG_EXT2_FS_XIP=y
+CONFIG_FS_XIP=y
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_XATTR=y
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+CONFIG_REISERFS_FS=y
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
+CONFIG_REISERFS_FS_XATTR=y
+CONFIG_REISERFS_FS_POSIX_ACL=y
+CONFIG_REISERFS_FS_SECURITY=y
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+CONFIG_XFS_FS=m
+CONFIG_XFS_EXPORT=y
+# CONFIG_XFS_QUOTA is not set
+CONFIG_XFS_SECURITY=y
+CONFIG_XFS_POSIX_ACL=y
+# CONFIG_XFS_RT is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+CONFIG_AUTOFS_FS=m
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=y
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_ZISOFS_FS=y
+CONFIG_UDF_FS=m
+CONFIG_UDF_NLS=y
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+CONFIG_HUGETLBFS=y
+CONFIG_HUGETLB_PAGE=y
+CONFIG_RAMFS=y
+# CONFIG_RELAYFS_FS is not set
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+CONFIG_HFS_FS=m
+CONFIG_HFSPLUS_FS=m
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_CRAMFS=y
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+# CONFIG_NFS_DIRECTIO is not set
+CONFIG_NFSD=y
+CONFIG_NFSD_V2_ACL=y
+CONFIG_NFSD_V3=y
+CONFIG_NFSD_V3_ACL=y
+CONFIG_NFSD_V4=y
+CONFIG_NFSD_TCP=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=y
+CONFIG_NFS_ACL_SUPPORT=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+CONFIG_SUNRPC_GSS=y
+CONFIG_RPCSEC_GSS_KRB5=y
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+CONFIG_CIFS=m
+# CONFIG_CIFS_STATS is not set
+# CONFIG_CIFS_XATTR is not set
+# CONFIG_CIFS_EXPERIMENTAL is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+CONFIG_MAC_PARTITION=y
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+
+#
+# Native Language Support
+#
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+CONFIG_NLS_CODEPAGE_1250=y
+CONFIG_NLS_CODEPAGE_1251=y
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+CONFIG_NLS_ISO8859_15=y
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+CONFIG_NLS_UTF8=y
+
+#
+# Library routines
+#
+CONFIG_CRC_CCITT=m
+# CONFIG_CRC16 is not set
+CONFIG_CRC32=y
+CONFIG_LIBCRC32C=m
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=m
+CONFIG_TEXTSEARCH=y
+CONFIG_TEXTSEARCH_KMP=m
+CONFIG_TEXTSEARCH_BM=m
+CONFIG_TEXTSEARCH_FSM=m
+
+#
+# Profiling support
+#
+CONFIG_PROFILING=y
+CONFIG_OPROFILE=y
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_DEBUG_KERNEL=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_LOG_BUF_SHIFT=17
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_INFO is not set
+CONFIG_DEBUG_FS=y
+# CONFIG_DEBUG_VM is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_DEBUG_STACKOVERFLOW is not set
+# CONFIG_KPROBES is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_DEBUGGER is not set
+CONFIG_IRQSTACKS=y
+CONFIG_BOOTX_TEXT=y
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_WP512=m
+# CONFIG_CRYPTO_TGR192 is not set
+CONFIG_CRYPTO_DES=y
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_AES=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_CRC32C=m
+CONFIG_CRYPTO_TEST=m
+
+#
+# Hardware crypto devices
+#
diff --git a/arch/powerpc/configs/iseries_defconfig b/arch/powerpc/configs/iseries_defconfig
new file mode 100644
index 000000000000..62e92c7e9e27
--- /dev/null
+++ b/arch/powerpc/configs/iseries_defconfig
@@ -0,0 +1,998 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.14-rc4
+# Thu Oct 20 08:30:56 2005
+#
+CONFIG_64BIT=y
+CONFIG_MMU=y
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_ISA_DMA=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_COMPAT=y
+CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
+CONFIG_FORCE_MAX_ZONEORDER=13
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+CONFIG_AUDIT=y
+CONFIG_AUDITSYSCALL=y
+CONFIG_HOTPLUG=y
+CONFIG_KOBJECT_UEVENT=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+# CONFIG_CPUSETS is not set
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_EMBEDDED is not set
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_OBSOLETE_MODPARM=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_KMOD=y
+CONFIG_STOP_MACHINE=y
+CONFIG_SYSVIPC_COMPAT=y
+
+#
+# Platform support
+#
+CONFIG_PPC_ISERIES=y
+# CONFIG_PPC_MULTIPLATFORM is not set
+CONFIG_PPC=y
+CONFIG_PPC64=y
+CONFIG_IBMVIO=y
+# CONFIG_POWER4_ONLY is not set
+CONFIG_IOMMU_VMERGE=y
+CONFIG_SMP=y
+CONFIG_NR_CPUS=32
+CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_ARCH_FLATMEM_ENABLE=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_NUMA is not set
+# CONFIG_SCHED_SMT is not set
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+# CONFIG_PREEMPT_BKL is not set
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_LPARCFG=y
+CONFIG_SECCOMP=y
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+CONFIG_ISA_DMA_API=y
+
+#
+# Bus Options
+#
+CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
+CONFIG_PCI_LEGACY_PROC=y
+# CONFIG_PCI_DEBUG is not set
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PCI Hotplug Support
+#
+# CONFIG_HOTPLUG_PCI is not set
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+CONFIG_NET_KEY=m
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+# CONFIG_IP_PNP is not set
+CONFIG_NET_IPIP=y
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+CONFIG_INET_AH=m
+CONFIG_INET_ESP=m
+CONFIG_INET_IPCOMP=m
+CONFIG_INET_TUNNEL=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+
+#
+# IP: Virtual Server Configuration
+#
+# CONFIG_IP_VS is not set
+# CONFIG_IPV6 is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+# CONFIG_NETFILTER_NETLINK is not set
+
+#
+# IP: Netfilter Configuration
+#
+CONFIG_IP_NF_CONNTRACK=m
+CONFIG_IP_NF_CT_ACCT=y
+CONFIG_IP_NF_CONNTRACK_MARK=y
+CONFIG_IP_NF_CONNTRACK_EVENTS=y
+CONFIG_IP_NF_CT_PROTO_SCTP=m
+CONFIG_IP_NF_FTP=m
+CONFIG_IP_NF_IRC=m
+# CONFIG_IP_NF_NETBIOS_NS is not set
+CONFIG_IP_NF_TFTP=m
+CONFIG_IP_NF_AMANDA=m
+# CONFIG_IP_NF_PPTP is not set
+CONFIG_IP_NF_QUEUE=m
+CONFIG_IP_NF_IPTABLES=m
+CONFIG_IP_NF_MATCH_LIMIT=m
+CONFIG_IP_NF_MATCH_IPRANGE=m
+CONFIG_IP_NF_MATCH_MAC=m
+CONFIG_IP_NF_MATCH_PKTTYPE=m
+CONFIG_IP_NF_MATCH_MARK=m
+CONFIG_IP_NF_MATCH_MULTIPORT=m
+CONFIG_IP_NF_MATCH_TOS=m
+CONFIG_IP_NF_MATCH_RECENT=m
+CONFIG_IP_NF_MATCH_ECN=m
+CONFIG_IP_NF_MATCH_DSCP=m
+CONFIG_IP_NF_MATCH_AH_ESP=m
+CONFIG_IP_NF_MATCH_LENGTH=m
+CONFIG_IP_NF_MATCH_TTL=m
+CONFIG_IP_NF_MATCH_TCPMSS=m
+CONFIG_IP_NF_MATCH_HELPER=m
+CONFIG_IP_NF_MATCH_STATE=m
+CONFIG_IP_NF_MATCH_CONNTRACK=m
+CONFIG_IP_NF_MATCH_OWNER=m
+CONFIG_IP_NF_MATCH_ADDRTYPE=m
+CONFIG_IP_NF_MATCH_REALM=m
+CONFIG_IP_NF_MATCH_SCTP=m
+# CONFIG_IP_NF_MATCH_DCCP is not set
+CONFIG_IP_NF_MATCH_COMMENT=m
+CONFIG_IP_NF_MATCH_CONNMARK=m
+CONFIG_IP_NF_MATCH_CONNBYTES=m
+CONFIG_IP_NF_MATCH_HASHLIMIT=m
+CONFIG_IP_NF_MATCH_STRING=m
+CONFIG_IP_NF_FILTER=m
+CONFIG_IP_NF_TARGET_REJECT=m
+CONFIG_IP_NF_TARGET_LOG=m
+CONFIG_IP_NF_TARGET_ULOG=m
+CONFIG_IP_NF_TARGET_TCPMSS=m
+CONFIG_IP_NF_TARGET_NFQUEUE=m
+CONFIG_IP_NF_NAT=m
+CONFIG_IP_NF_NAT_NEEDED=y
+CONFIG_IP_NF_TARGET_MASQUERADE=m
+CONFIG_IP_NF_TARGET_REDIRECT=m
+CONFIG_IP_NF_TARGET_NETMAP=m
+CONFIG_IP_NF_TARGET_SAME=m
+CONFIG_IP_NF_NAT_SNMP_BASIC=m
+CONFIG_IP_NF_NAT_IRC=m
+CONFIG_IP_NF_NAT_FTP=m
+CONFIG_IP_NF_NAT_TFTP=m
+CONFIG_IP_NF_NAT_AMANDA=m
+CONFIG_IP_NF_MANGLE=m
+CONFIG_IP_NF_TARGET_TOS=m
+CONFIG_IP_NF_TARGET_ECN=m
+CONFIG_IP_NF_TARGET_DSCP=m
+CONFIG_IP_NF_TARGET_MARK=m
+CONFIG_IP_NF_TARGET_CLASSIFY=m
+CONFIG_IP_NF_TARGET_TTL=m
+CONFIG_IP_NF_TARGET_CONNMARK=m
+CONFIG_IP_NF_TARGET_CLUSTERIP=m
+CONFIG_IP_NF_RAW=m
+CONFIG_IP_NF_TARGET_NOTRACK=m
+CONFIG_IP_NF_ARPTABLES=m
+CONFIG_IP_NF_ARPFILTER=m
+CONFIG_IP_NF_ARP_MANGLE=m
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP 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_LLC=y
+# 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_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+CONFIG_NET_CLS_ROUTE=y
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=m
+# CONFIG_DEBUG_DRIVER is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+CONFIG_BLK_DEV_NBD=m
+# CONFIG_BLK_DEV_SX8 is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=65536
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_CDROM_PKTCDVD is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_ATA_OVER_ETH is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_ST=y
+# CONFIG_CHR_DEV_OSST is not set
+CONFIG_BLK_DEV_SR=y
+CONFIG_BLK_DEV_SR_VENDOR=y
+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=y
+CONFIG_SCSI_CONSTANTS=y
+# CONFIG_SCSI_LOGGING is not set
+
+#
+# SCSI Transport Attributes
+#
+CONFIG_SCSI_SPI_ATTRS=y
+CONFIG_SCSI_FC_ATTRS=y
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_ATTRS is not set
+
+#
+# SCSI low-level drivers
+#
+# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_ACARD is not set
+# CONFIG_SCSI_AACRAID is not set
+# CONFIG_SCSI_AIC7XXX is not set
+# CONFIG_SCSI_AIC7XXX_OLD is not set
+# CONFIG_SCSI_AIC79XX is not set
+# CONFIG_MEGARAID_NEWGEN is not set
+# CONFIG_MEGARAID_LEGACY is not set
+# CONFIG_MEGARAID_SAS is not set
+# CONFIG_SCSI_SATA is not set
+# CONFIG_SCSI_BUSLOGIC is not set
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_EATA is not set
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+# CONFIG_SCSI_GDTH is not set
+# CONFIG_SCSI_IPS is not set
+CONFIG_SCSI_IBMVSCSI=m
+# CONFIG_SCSI_INITIO is not set
+# CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_SYM53C8XX_2 is not set
+# CONFIG_SCSI_IPR is not set
+# CONFIG_SCSI_QLOGIC_FC is not set
+# CONFIG_SCSI_QLOGIC_1280 is not set
+CONFIG_SCSI_QLA2XXX=y
+# CONFIG_SCSI_QLA21XX is not set
+# CONFIG_SCSI_QLA22XX is not set
+# CONFIG_SCSI_QLA2300 is not set
+# CONFIG_SCSI_QLA2322 is not set
+# CONFIG_SCSI_QLA6312 is not set
+# CONFIG_SCSI_QLA24XX is not set
+# CONFIG_SCSI_LPFC is not set
+# CONFIG_SCSI_DC395x is not set
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_DEBUG is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+CONFIG_MD=y
+CONFIG_BLK_DEV_MD=y
+CONFIG_MD_LINEAR=y
+CONFIG_MD_RAID0=y
+CONFIG_MD_RAID1=y
+CONFIG_MD_RAID10=m
+CONFIG_MD_RAID5=y
+CONFIG_MD_RAID6=m
+CONFIG_MD_MULTIPATH=m
+CONFIG_MD_FAULTY=m
+CONFIG_BLK_DEV_DM=y
+CONFIG_DM_CRYPT=m
+CONFIG_DM_SNAPSHOT=m
+CONFIG_DM_MIRROR=m
+CONFIG_DM_ZERO=m
+# CONFIG_DM_MULTIPATH is not set
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+# CONFIG_FUSION_SPI is not set
+# CONFIG_FUSION_FC is not set
+# CONFIG_FUSION_SAS is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+
+#
+# Macintosh device drivers
+#
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+CONFIG_DUMMY=m
+CONFIG_BONDING=m
+# CONFIG_EQUALIZER is not set
+CONFIG_TUN=m
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
+#
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_CASSINI is not set
+# CONFIG_NET_VENDOR_3COM is not set
+
+#
+# Tulip family network device support
+#
+# CONFIG_NET_TULIP is not set
+# CONFIG_HP100 is not set
+CONFIG_NET_PCI=y
+CONFIG_PCNET32=y
+# CONFIG_AMD8111_ETH is not set
+# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_B44 is not set
+# CONFIG_FORCEDETH is not set
+# CONFIG_DGRS is not set
+# CONFIG_EEPRO100 is not set
+CONFIG_E100=y
+# CONFIG_FEALNX is not set
+# CONFIG_NATSEMI is not set
+# CONFIG_NE2K_PCI is not set
+# CONFIG_8139CP is not set
+# CONFIG_8139TOO is not set
+# CONFIG_SIS900 is not set
+# CONFIG_EPIC100 is not set
+# CONFIG_SUNDANCE is not set
+# CONFIG_VIA_RHINE is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+CONFIG_ACENIC=m
+# CONFIG_ACENIC_OMIT_TIGON_I is not set
+# CONFIG_DL2K is not set
+CONFIG_E1000=m
+# CONFIG_E1000_NAPI is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_VIA_VELOCITY is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
+
+#
+# Ethernet (10000 Mbit)
+#
+# CONFIG_CHELSIO_T1 is not set
+# CONFIG_IXGB is not set
+# CONFIG_S2IO is not set
+
+#
+# Token Ring devices
+#
+CONFIG_TR=y
+CONFIG_IBMOL=y
+# CONFIG_3C359 is not set
+# CONFIG_TMS380TR is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+CONFIG_ISERIES_VETH=y
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+CONFIG_PPP=m
+# CONFIG_PPP_MULTILINK is not set
+# CONFIG_PPP_FILTER is not set
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_BSDCOMP=m
+CONFIG_PPPOE=m
+# CONFIG_SLIP is not set
+# CONFIG_NET_FC is not set
+# CONFIG_SHAPER is not set
+CONFIG_NETCONSOLE=y
+CONFIG_NETPOLL=y
+CONFIG_NETPOLL_RX=y
+CONFIG_NETPOLL_TRAP=y
+CONFIG_NET_POLL_CONTROLLER=y
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=m
+CONFIG_SERIAL_ICOM=m
+# CONFIG_SERIAL_JSM is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+CONFIG_RAW_DRIVER=y
+CONFIG_MAX_RAW_DEVS=256
+# CONFIG_HANGCHECK_TIMER is not set
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
+#
+# Misc devices
+#
+
+#
+# Multimedia Capabilities Port drivers
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+# CONFIG_FB is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+# CONFIG_USB is not set
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
+# SN Devices
+#
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+CONFIG_EXT2_FS_XIP=y
+CONFIG_FS_XIP=y
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_XATTR=y
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+CONFIG_REISERFS_FS=y
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
+CONFIG_REISERFS_FS_XATTR=y
+CONFIG_REISERFS_FS_POSIX_ACL=y
+CONFIG_REISERFS_FS_SECURITY=y
+CONFIG_JFS_FS=m
+CONFIG_JFS_POSIX_ACL=y
+CONFIG_JFS_SECURITY=y
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
+CONFIG_FS_POSIX_ACL=y
+CONFIG_XFS_FS=m
+CONFIG_XFS_EXPORT=y
+# CONFIG_XFS_QUOTA is not set
+CONFIG_XFS_SECURITY=y
+CONFIG_XFS_POSIX_ACL=y
+# CONFIG_XFS_RT is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+CONFIG_AUTOFS_FS=m
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=y
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_ZISOFS_FS=y
+CONFIG_UDF_FS=m
+CONFIG_UDF_NLS=y
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_HUGETLBFS is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+# CONFIG_RELAYFS_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_CRAMFS=y
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+# CONFIG_NFS_DIRECTIO is not set
+CONFIG_NFSD=m
+CONFIG_NFSD_V2_ACL=y
+CONFIG_NFSD_V3=y
+CONFIG_NFSD_V3_ACL=y
+CONFIG_NFSD_V4=y
+CONFIG_NFSD_TCP=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=m
+CONFIG_NFS_ACL_SUPPORT=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+CONFIG_SUNRPC_GSS=y
+CONFIG_RPCSEC_GSS_KRB5=y
+CONFIG_RPCSEC_GSS_SPKM3=m
+# CONFIG_SMB_FS is not set
+CONFIG_CIFS=m
+# CONFIG_CIFS_STATS is not set
+CONFIG_CIFS_XATTR=y
+CONFIG_CIFS_POSIX=y
+# CONFIG_CIFS_EXPERIMENTAL is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+
+#
+# iSeries device drivers
+#
+CONFIG_VIOCONS=y
+CONFIG_VIODASD=y
+CONFIG_VIOCD=m
+CONFIG_VIOTAPE=m
+CONFIG_VIOPATH=y
+
+#
+# Profiling support
+#
+CONFIG_PROFILING=y
+CONFIG_OPROFILE=y
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_DEBUG_KERNEL=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_LOG_BUF_SHIFT=17
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_INFO is not set
+CONFIG_DEBUG_FS=y
+CONFIG_DEBUG_STACKOVERFLOW=y
+# CONFIG_KPROBES is not set
+CONFIG_DEBUG_STACK_USAGE=y
+# CONFIG_DEBUGGER is not set
+# CONFIG_PPCDBG is not set
+CONFIG_IRQSTACKS=y
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_DES=y
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_AES=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_CRC32C=m
+CONFIG_CRYPTO_TEST=m
+
+#
+# Hardware crypto devices
+#
+
+#
+# Library routines
+#
+CONFIG_CRC_CCITT=m
+# CONFIG_CRC16 is not set
+CONFIG_CRC32=y
+CONFIG_LIBCRC32C=m
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=m
+CONFIG_TEXTSEARCH=y
+CONFIG_TEXTSEARCH_KMP=m
+CONFIG_TEXTSEARCH_BM=m
+CONFIG_TEXTSEARCH_FSM=m
diff --git a/arch/powerpc/configs/maple_defconfig b/arch/powerpc/configs/maple_defconfig
new file mode 100644
index 000000000000..7b480f3d1406
--- /dev/null
+++ b/arch/powerpc/configs/maple_defconfig
@@ -0,0 +1,1062 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.14-rc4
+# Thu Oct 20 08:31:24 2005
+#
+CONFIG_64BIT=y
+CONFIG_MMU=y
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_ISA_DMA=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_COMPAT=y
+CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
+CONFIG_FORCE_MAX_ZONEORDER=13
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+# CONFIG_HOTPLUG is not set
+CONFIG_KOBJECT_UEVENT=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+# CONFIG_CPUSETS is not set
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_EMBEDDED is not set
+CONFIG_KALLSYMS=y
+CONFIG_KALLSYMS_ALL=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_OBSOLETE_MODPARM=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_KMOD=y
+CONFIG_STOP_MACHINE=y
+CONFIG_SYSVIPC_COMPAT=y
+
+#
+# Platform support
+#
+# CONFIG_PPC_ISERIES is not set
+CONFIG_PPC_MULTIPLATFORM=y
+# CONFIG_PPC_PSERIES is not set
+# CONFIG_PPC_BPA is not set
+# CONFIG_PPC_PMAC is not set
+CONFIG_PPC_MAPLE=y
+CONFIG_PPC=y
+CONFIG_PPC64=y
+CONFIG_PPC_OF=y
+CONFIG_MPIC=y
+# CONFIG_ALTIVEC is not set
+CONFIG_KEXEC=y
+CONFIG_U3_DART=y
+CONFIG_MPIC_BROKEN_U3=y
+CONFIG_BOOTX_TEXT=y
+CONFIG_POWER4_ONLY=y
+CONFIG_IOMMU_VMERGE=y
+CONFIG_SMP=y
+CONFIG_NR_CPUS=2
+CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_ARCH_FLATMEM_ENABLE=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_NUMA is not set
+# CONFIG_SCHED_SMT is not set
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+# CONFIG_PREEMPT_BKL is not set
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_SECCOMP=y
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+CONFIG_PROC_DEVICETREE=y
+# CONFIG_CMDLINE_BOOL is not set
+CONFIG_ISA_DMA_API=y
+
+#
+# Bus Options
+#
+CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
+CONFIG_PCI_LEGACY_PROC=y
+# CONFIG_PCI_DEBUG is not set
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PCI Hotplug Support
+#
+# CONFIG_HOTPLUG_PCI is not set
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+# CONFIG_IP_PNP_BOOTP is not set
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+# CONFIG_IPV6 is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# 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_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+# CONFIG_DEBUG_DRIVER is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_SX8 is not set
+# CONFIG_BLK_DEV_UB is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=8192
+# CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_CDROM_PKTCDVD is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_ATA_OVER_ETH is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+CONFIG_IDE=y
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_IDE_SATA is not set
+CONFIG_BLK_DEV_IDEDISK=y
+# CONFIG_IDEDISK_MULTI_MODE is not set
+CONFIG_BLK_DEV_IDECD=y
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_BLK_DEV_IDEFLOPPY is not set
+CONFIG_IDE_TASK_IOCTL=y
+
+#
+# IDE chipset support/bugfixes
+#
+CONFIG_IDE_GENERIC=y
+CONFIG_BLK_DEV_IDEPCI=y
+CONFIG_IDEPCI_SHARE_IRQ=y
+# CONFIG_BLK_DEV_OFFBOARD is not set
+CONFIG_BLK_DEV_GENERIC=y
+# CONFIG_BLK_DEV_OPTI621 is not set
+# CONFIG_BLK_DEV_SL82C105 is not set
+CONFIG_BLK_DEV_IDEDMA_PCI=y
+# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
+CONFIG_IDEDMA_PCI_AUTO=y
+# CONFIG_IDEDMA_ONLYDISK is not set
+# CONFIG_BLK_DEV_AEC62XX is not set
+# CONFIG_BLK_DEV_ALI15X3 is not set
+CONFIG_BLK_DEV_AMD74XX=y
+# CONFIG_BLK_DEV_CMD64X is not set
+# CONFIG_BLK_DEV_TRIFLEX is not set
+# CONFIG_BLK_DEV_CY82C693 is not set
+# CONFIG_BLK_DEV_CS5520 is not set
+# CONFIG_BLK_DEV_CS5530 is not set
+# CONFIG_BLK_DEV_HPT34X is not set
+# CONFIG_BLK_DEV_HPT366 is not set
+# CONFIG_BLK_DEV_SC1200 is not set
+# CONFIG_BLK_DEV_PIIX is not set
+# CONFIG_BLK_DEV_IT821X is not set
+# CONFIG_BLK_DEV_NS87415 is not set
+# CONFIG_BLK_DEV_PDC202XX_OLD is not set
+# CONFIG_BLK_DEV_PDC202XX_NEW is not set
+# CONFIG_BLK_DEV_SVWKS is not set
+# CONFIG_BLK_DEV_SIIMAGE is not set
+# CONFIG_BLK_DEV_SLC90E66 is not set
+# CONFIG_BLK_DEV_TRM290 is not set
+# CONFIG_BLK_DEV_VIA82CXXX is not set
+# CONFIG_IDE_ARM is not set
+CONFIG_BLK_DEV_IDEDMA=y
+# CONFIG_IDEDMA_IVB is not set
+CONFIG_IDEDMA_AUTO=y
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+
+#
+# Macintosh device drivers
+#
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
+#
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_CASSINI is not set
+# CONFIG_NET_VENDOR_3COM is not set
+
+#
+# Tulip family network device support
+#
+# CONFIG_NET_TULIP is not set
+# CONFIG_HP100 is not set
+CONFIG_NET_PCI=y
+# CONFIG_PCNET32 is not set
+CONFIG_AMD8111_ETH=y
+# CONFIG_AMD8111E_NAPI is not set
+# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_B44 is not set
+# CONFIG_FORCEDETH is not set
+# CONFIG_DGRS is not set
+# CONFIG_EEPRO100 is not set
+# CONFIG_E100 is not set
+# CONFIG_FEALNX is not set
+# CONFIG_NATSEMI is not set
+# CONFIG_NE2K_PCI is not set
+# CONFIG_8139CP is not set
+# CONFIG_8139TOO is not set
+# CONFIG_SIS900 is not set
+# CONFIG_EPIC100 is not set
+# CONFIG_SUNDANCE is not set
+# CONFIG_VIA_RHINE is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+CONFIG_E1000=y
+# CONFIG_E1000_NAPI is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_VIA_VELOCITY is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
+# CONFIG_MV643XX_ETH is not set
+
+#
+# Ethernet (10000 Mbit)
+#
+# CONFIG_CHELSIO_T1 is not set
+# CONFIG_IXGB is not set
+# CONFIG_S2IO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1600
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=1200
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=4
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_HANGCHECK_TIMER is not set
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+
+#
+# I2C support
+#
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+
+#
+# I2C Algorithms
+#
+CONFIG_I2C_ALGOBIT=y
+# CONFIG_I2C_ALGOPCF is not set
+# CONFIG_I2C_ALGOPCA is not set
+
+#
+# I2C Hardware Bus support
+#
+# 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=y
+# CONFIG_I2C_I801 is not set
+# CONFIG_I2C_I810 is not set
+# CONFIG_I2C_PIIX4 is not set
+# CONFIG_I2C_NFORCE2 is not set
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_PROSAVAGE is not set
+# CONFIG_I2C_SAVAGE4 is not set
+# CONFIG_SCx200_ACB is not set
+# CONFIG_I2C_SIS5595 is not set
+# CONFIG_I2C_SIS630 is not set
+# CONFIG_I2C_SIS96X is not set
+# CONFIG_I2C_STUB is not set
+# CONFIG_I2C_VIA is not set
+# CONFIG_I2C_VIAPRO is not set
+# CONFIG_I2C_VOODOO3 is not set
+# CONFIG_I2C_PCA_ISA is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_SENSORS_DS1337 is not set
+# CONFIG_SENSORS_DS1374 is not set
+# CONFIG_SENSORS_EEPROM is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_SENSORS_PCA9539 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_SENSORS_RTC8564 is not set
+# CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
+#
+# Misc devices
+#
+
+#
+# Multimedia Capabilities Port drivers
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+# CONFIG_FB is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+# CONFIG_USB_BANDWIDTH is not set
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_OTG is not set
+
+#
+# USB Host Controller Drivers
+#
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_SPLIT_ISO=y
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+# CONFIG_USB_ISP116X_HCD is not set
+CONFIG_USB_OHCI_HCD=y
+# CONFIG_USB_OHCI_BIG_ENDIAN is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+CONFIG_USB_UHCI_HCD=y
+# CONFIG_USB_SL811_HCD is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_BLUETOOTH_TTY is not set
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+#
+# CONFIG_USB_STORAGE is not set
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=y
+CONFIG_USB_HIDINPUT=y
+# CONFIG_HID_FF is not set
+# CONFIG_USB_HIDDEV is not set
+# CONFIG_USB_AIPTEK is not set
+# CONFIG_USB_WACOM is not set
+# CONFIG_USB_ACECAD is not set
+# CONFIG_USB_KBTAB is not set
+# CONFIG_USB_POWERMATE is not set
+# CONFIG_USB_MTOUCH is not set
+# CONFIG_USB_ITMTOUCH is not set
+# CONFIG_USB_EGALAX is not set
+# CONFIG_USB_YEALINK is not set
+# CONFIG_USB_XPAD is not set
+# CONFIG_USB_ATI_REMOTE is not set
+# CONFIG_USB_KEYSPAN_REMOTE is not set
+# CONFIG_USB_APPLETOUCH is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+
+#
+# USB Multimedia devices
+#
+# CONFIG_USB_DABUSB is not set
+
+#
+# Video4Linux support is needed for USB Multimedia device support
+#
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+CONFIG_USB_PEGASUS=y
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET is not set
+CONFIG_USB_MON=y
+
+#
+# USB port drivers
+#
+
+#
+# USB Serial Converter support
+#
+CONFIG_USB_SERIAL=y
+# CONFIG_USB_SERIAL_CONSOLE is not set
+CONFIG_USB_SERIAL_GENERIC=y
+# CONFIG_USB_SERIAL_AIRPRIME is not set
+# CONFIG_USB_SERIAL_BELKIN is not set
+# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
+# CONFIG_USB_SERIAL_CP2101 is not set
+CONFIG_USB_SERIAL_CYPRESS_M8=m
+# CONFIG_USB_SERIAL_EMPEG is not set
+# CONFIG_USB_SERIAL_FTDI_SIO is not set
+# CONFIG_USB_SERIAL_VISOR is not set
+# CONFIG_USB_SERIAL_IPAQ is not set
+# CONFIG_USB_SERIAL_IR is not set
+# CONFIG_USB_SERIAL_EDGEPORT is not set
+# CONFIG_USB_SERIAL_EDGEPORT_TI is not set
+CONFIG_USB_SERIAL_GARMIN=m
+CONFIG_USB_SERIAL_IPW=m
+# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
+CONFIG_USB_SERIAL_KEYSPAN=y
+CONFIG_USB_SERIAL_KEYSPAN_MPR=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28X=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28XA=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28XB=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19=y
+CONFIG_USB_SERIAL_KEYSPAN_USA18X=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19W=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19QW=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19QI=y
+CONFIG_USB_SERIAL_KEYSPAN_USA49W=y
+CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y
+# CONFIG_USB_SERIAL_KLSI is not set
+# CONFIG_USB_SERIAL_KOBIL_SCT is not set
+# CONFIG_USB_SERIAL_MCT_U232 is not set
+# CONFIG_USB_SERIAL_PL2303 is not set
+# CONFIG_USB_SERIAL_HP4X is not set
+# CONFIG_USB_SERIAL_SAFE is not set
+CONFIG_USB_SERIAL_TI=m
+# CONFIG_USB_SERIAL_CYBERJACK is not set
+# CONFIG_USB_SERIAL_XIRCOM is not set
+# CONFIG_USB_SERIAL_OMNINET is not set
+CONFIG_USB_EZUSB=y
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_AUERSWALD is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_PHIDGETKIT is not set
+# CONFIG_USB_PHIDGETSERVO is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_SISUSBVGA is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TEST is not set
+
+#
+# USB DSL modem support
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
+# SN Devices
+#
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+CONFIG_EXT2_FS_XIP=y
+CONFIG_FS_XIP=y
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_FS_XATTR is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+# CONFIG_XFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+CONFIG_HUGETLBFS=y
+CONFIG_HUGETLB_PAGE=y
+CONFIG_RAMFS=y
+# CONFIG_RELAYFS_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_CRAMFS=y
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+# CONFIG_NFS_DIRECTIO is not set
+# CONFIG_NFSD is not set
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_ACL_SUPPORT=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+CONFIG_SUNRPC_GSS=y
+CONFIG_RPCSEC_GSS_KRB5=y
+# 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
+# CONFIG_9P_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+CONFIG_MAC_PARTITION=y
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+
+#
+# Native Language Support
+#
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="utf-8"
+# CONFIG_NLS_CODEPAGE_437 is not set
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+# CONFIG_NLS_ISO8859_1 is not set
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+CONFIG_NLS_UTF8=y
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_DEBUG_KERNEL=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_LOG_BUF_SHIFT=17
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_SCHEDSTATS is not set
+CONFIG_DEBUG_SLAB=y
+# CONFIG_DEBUG_SPINLOCK is not set
+CONFIG_DEBUG_SPINLOCK_SLEEP=y
+# CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_INFO is not set
+CONFIG_DEBUG_FS=y
+CONFIG_DEBUG_STACKOVERFLOW=y
+# CONFIG_KPROBES is not set
+CONFIG_DEBUG_STACK_USAGE=y
+CONFIG_DEBUGGER=y
+CONFIG_XMON=y
+CONFIG_XMON_DEFAULT=y
+# CONFIG_PPCDBG is not set
+# CONFIG_IRQSTACKS is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+CONFIG_CRYPTO=y
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_MD4 is not set
+CONFIG_CRYPTO_MD5=y
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_WP512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Hardware crypto devices
+#
+
+#
+# Library routines
+#
+CONFIG_CRC_CCITT=y
+# CONFIG_CRC16 is not set
+CONFIG_CRC32=y
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
diff --git a/arch/powerpc/configs/pseries_defconfig b/arch/powerpc/configs/pseries_defconfig
new file mode 100644
index 000000000000..9f09dff9e11a
--- /dev/null
+++ b/arch/powerpc/configs/pseries_defconfig
@@ -0,0 +1,1371 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.14-rc4
+# Thu Oct 20 08:32:17 2005
+#
+CONFIG_64BIT=y
+CONFIG_MMU=y
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_ISA_DMA=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_COMPAT=y
+CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
+CONFIG_FORCE_MAX_ZONEORDER=13
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+CONFIG_AUDIT=y
+CONFIG_AUDITSYSCALL=y
+CONFIG_HOTPLUG=y
+CONFIG_KOBJECT_UEVENT=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_CPUSETS=y
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_EMBEDDED is not set
+CONFIG_KALLSYMS=y
+CONFIG_KALLSYMS_ALL=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_OBSOLETE_MODPARM=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_KMOD=y
+CONFIG_STOP_MACHINE=y
+CONFIG_SYSVIPC_COMPAT=y
+
+#
+# Platform support
+#
+# CONFIG_PPC_ISERIES is not set
+CONFIG_PPC_MULTIPLATFORM=y
+CONFIG_PPC_PSERIES=y
+# CONFIG_PPC_BPA is not set
+# CONFIG_PPC_PMAC is not set
+# CONFIG_PPC_MAPLE is not set
+CONFIG_PPC=y
+CONFIG_PPC64=y
+CONFIG_PPC_OF=y
+CONFIG_XICS=y
+CONFIG_MPIC=y
+CONFIG_ALTIVEC=y
+CONFIG_PPC_SPLPAR=y
+CONFIG_KEXEC=y
+CONFIG_IBMVIO=y
+# CONFIG_U3_DART is not set
+# CONFIG_BOOTX_TEXT is not set
+# CONFIG_POWER4_ONLY is not set
+CONFIG_IOMMU_VMERGE=y
+CONFIG_SMP=y
+CONFIG_NR_CPUS=128
+CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_DISCONTIGMEM_ENABLE=y
+CONFIG_ARCH_DISCONTIGMEM_DEFAULT=y
+CONFIG_ARCH_SPARSEMEM_ENABLE=y
+CONFIG_SELECT_MEMORY_MODEL=y
+# CONFIG_FLATMEM_MANUAL is not set
+CONFIG_DISCONTIGMEM_MANUAL=y
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_DISCONTIGMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_NEED_MULTIPLE_NODES=y
+# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID=y
+CONFIG_NODES_SPAN_OTHER_NODES=y
+CONFIG_NUMA=y
+CONFIG_SCHED_SMT=y
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+# CONFIG_PREEMPT_BKL is not set
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+CONFIG_EEH=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_PPC_RTAS=y
+CONFIG_RTAS_PROC=y
+CONFIG_RTAS_FLASH=m
+CONFIG_SCANLOG=m
+CONFIG_LPARCFG=y
+CONFIG_SECCOMP=y
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+CONFIG_HOTPLUG_CPU=y
+CONFIG_PROC_DEVICETREE=y
+# CONFIG_CMDLINE_BOOL is not set
+CONFIG_ISA_DMA_API=y
+
+#
+# Bus Options
+#
+CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
+CONFIG_PCI_LEGACY_PROC=y
+# CONFIG_PCI_DEBUG is not set
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PCI Hotplug Support
+#
+CONFIG_HOTPLUG_PCI=m
+# CONFIG_HOTPLUG_PCI_FAKE is not set
+# CONFIG_HOTPLUG_PCI_CPCI is not set
+# CONFIG_HOTPLUG_PCI_SHPC is not set
+CONFIG_HOTPLUG_PCI_RPA=m
+CONFIG_HOTPLUG_PCI_RPA_DLPAR=m
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+CONFIG_NET_KEY=m
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+# CONFIG_IP_PNP is not set
+CONFIG_NET_IPIP=y
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+CONFIG_INET_AH=m
+CONFIG_INET_ESP=m
+CONFIG_INET_IPCOMP=m
+CONFIG_INET_TUNNEL=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+
+#
+# IP: Virtual Server Configuration
+#
+# CONFIG_IP_VS is not set
+# CONFIG_IPV6 is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+CONFIG_NETFILTER_NETLINK=y
+CONFIG_NETFILTER_NETLINK_QUEUE=m
+CONFIG_NETFILTER_NETLINK_LOG=m
+
+#
+# IP: Netfilter Configuration
+#
+CONFIG_IP_NF_CONNTRACK=m
+CONFIG_IP_NF_CT_ACCT=y
+CONFIG_IP_NF_CONNTRACK_MARK=y
+CONFIG_IP_NF_CONNTRACK_EVENTS=y
+CONFIG_IP_NF_CONNTRACK_NETLINK=m
+CONFIG_IP_NF_CT_PROTO_SCTP=m
+CONFIG_IP_NF_FTP=m
+CONFIG_IP_NF_IRC=m
+# CONFIG_IP_NF_NETBIOS_NS is not set
+CONFIG_IP_NF_TFTP=m
+CONFIG_IP_NF_AMANDA=m
+# CONFIG_IP_NF_PPTP is not set
+CONFIG_IP_NF_QUEUE=m
+CONFIG_IP_NF_IPTABLES=m
+CONFIG_IP_NF_MATCH_LIMIT=m
+CONFIG_IP_NF_MATCH_IPRANGE=m
+CONFIG_IP_NF_MATCH_MAC=m
+CONFIG_IP_NF_MATCH_PKTTYPE=m
+CONFIG_IP_NF_MATCH_MARK=m
+CONFIG_IP_NF_MATCH_MULTIPORT=m
+CONFIG_IP_NF_MATCH_TOS=m
+CONFIG_IP_NF_MATCH_RECENT=m
+CONFIG_IP_NF_MATCH_ECN=m
+CONFIG_IP_NF_MATCH_DSCP=m
+CONFIG_IP_NF_MATCH_AH_ESP=m
+CONFIG_IP_NF_MATCH_LENGTH=m
+CONFIG_IP_NF_MATCH_TTL=m
+CONFIG_IP_NF_MATCH_TCPMSS=m
+CONFIG_IP_NF_MATCH_HELPER=m
+CONFIG_IP_NF_MATCH_STATE=m
+CONFIG_IP_NF_MATCH_CONNTRACK=m
+CONFIG_IP_NF_MATCH_OWNER=m
+CONFIG_IP_NF_MATCH_ADDRTYPE=m
+CONFIG_IP_NF_MATCH_REALM=m
+CONFIG_IP_NF_MATCH_SCTP=m
+# CONFIG_IP_NF_MATCH_DCCP is not set
+CONFIG_IP_NF_MATCH_COMMENT=m
+CONFIG_IP_NF_MATCH_CONNMARK=m
+CONFIG_IP_NF_MATCH_CONNBYTES=m
+CONFIG_IP_NF_MATCH_HASHLIMIT=m
+CONFIG_IP_NF_MATCH_STRING=m
+CONFIG_IP_NF_FILTER=m
+CONFIG_IP_NF_TARGET_REJECT=m
+CONFIG_IP_NF_TARGET_LOG=m
+CONFIG_IP_NF_TARGET_ULOG=m
+CONFIG_IP_NF_TARGET_TCPMSS=m
+CONFIG_IP_NF_TARGET_NFQUEUE=m
+CONFIG_IP_NF_NAT=m
+CONFIG_IP_NF_NAT_NEEDED=y
+CONFIG_IP_NF_TARGET_MASQUERADE=m
+CONFIG_IP_NF_TARGET_REDIRECT=m
+CONFIG_IP_NF_TARGET_NETMAP=m
+CONFIG_IP_NF_TARGET_SAME=m
+CONFIG_IP_NF_NAT_SNMP_BASIC=m
+CONFIG_IP_NF_NAT_IRC=m
+CONFIG_IP_NF_NAT_FTP=m
+CONFIG_IP_NF_NAT_TFTP=m
+CONFIG_IP_NF_NAT_AMANDA=m
+CONFIG_IP_NF_MANGLE=m
+CONFIG_IP_NF_TARGET_TOS=m
+CONFIG_IP_NF_TARGET_ECN=m
+CONFIG_IP_NF_TARGET_DSCP=m
+CONFIG_IP_NF_TARGET_MARK=m
+CONFIG_IP_NF_TARGET_CLASSIFY=m
+CONFIG_IP_NF_TARGET_TTL=m
+CONFIG_IP_NF_TARGET_CONNMARK=m
+CONFIG_IP_NF_TARGET_CLUSTERIP=m
+CONFIG_IP_NF_RAW=m
+CONFIG_IP_NF_TARGET_NOTRACK=m
+CONFIG_IP_NF_ARPTABLES=m
+CONFIG_IP_NF_ARPFILTER=m
+CONFIG_IP_NF_ARP_MANGLE=m
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP 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_LLC=y
+# 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_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+CONFIG_NET_CLS_ROUTE=y
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+# CONFIG_DEBUG_DRIVER is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+CONFIG_PARPORT=m
+CONFIG_PARPORT_PC=m
+# CONFIG_PARPORT_SERIAL is not set
+# CONFIG_PARPORT_PC_FIFO is not set
+# CONFIG_PARPORT_PC_SUPERIO is not set
+# CONFIG_PARPORT_GSC is not set
+# CONFIG_PARPORT_1284 is not set
+
+#
+# Plug and Play support
+#
+
+#
+# Block devices
+#
+CONFIG_BLK_DEV_FD=m
+# CONFIG_PARIDE is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+CONFIG_BLK_DEV_NBD=m
+# CONFIG_BLK_DEV_SX8 is not set
+# CONFIG_BLK_DEV_UB is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=65536
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_CDROM_PKTCDVD is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_ATA_OVER_ETH is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+CONFIG_IDE=y
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_IDE_SATA is not set
+CONFIG_BLK_DEV_IDEDISK=y
+# CONFIG_IDEDISK_MULTI_MODE is not set
+CONFIG_BLK_DEV_IDECD=y
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_BLK_DEV_IDEFLOPPY is not set
+# CONFIG_BLK_DEV_IDESCSI is not set
+# CONFIG_IDE_TASK_IOCTL is not set
+
+#
+# IDE chipset support/bugfixes
+#
+CONFIG_IDE_GENERIC=y
+CONFIG_BLK_DEV_IDEPCI=y
+CONFIG_IDEPCI_SHARE_IRQ=y
+# CONFIG_BLK_DEV_OFFBOARD is not set
+CONFIG_BLK_DEV_GENERIC=y
+# CONFIG_BLK_DEV_OPTI621 is not set
+CONFIG_BLK_DEV_SL82C105=y
+CONFIG_BLK_DEV_IDEDMA_PCI=y
+# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
+CONFIG_IDEDMA_PCI_AUTO=y
+# CONFIG_IDEDMA_ONLYDISK is not set
+# CONFIG_BLK_DEV_AEC62XX is not set
+# CONFIG_BLK_DEV_ALI15X3 is not set
+CONFIG_BLK_DEV_AMD74XX=y
+# CONFIG_BLK_DEV_CMD64X is not set
+# CONFIG_BLK_DEV_TRIFLEX is not set
+# CONFIG_BLK_DEV_CY82C693 is not set
+# CONFIG_BLK_DEV_CS5520 is not set
+# CONFIG_BLK_DEV_CS5530 is not set
+# CONFIG_BLK_DEV_HPT34X is not set
+# CONFIG_BLK_DEV_HPT366 is not set
+# CONFIG_BLK_DEV_SC1200 is not set
+# CONFIG_BLK_DEV_PIIX is not set
+# CONFIG_BLK_DEV_IT821X is not set
+# CONFIG_BLK_DEV_NS87415 is not set
+# CONFIG_BLK_DEV_PDC202XX_OLD is not set
+# CONFIG_BLK_DEV_PDC202XX_NEW is not set
+# CONFIG_BLK_DEV_SVWKS is not set
+# CONFIG_BLK_DEV_SIIMAGE is not set
+# CONFIG_BLK_DEV_SLC90E66 is not set
+# CONFIG_BLK_DEV_TRM290 is not set
+# CONFIG_BLK_DEV_VIA82CXXX is not set
+# CONFIG_IDE_ARM is not set
+CONFIG_BLK_DEV_IDEDMA=y
+# CONFIG_IDEDMA_IVB is not set
+CONFIG_IDEDMA_AUTO=y
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_ST=y
+# CONFIG_CHR_DEV_OSST is not set
+CONFIG_BLK_DEV_SR=y
+CONFIG_BLK_DEV_SR_VENDOR=y
+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=y
+CONFIG_SCSI_CONSTANTS=y
+# CONFIG_SCSI_LOGGING is not set
+
+#
+# SCSI Transport Attributes
+#
+CONFIG_SCSI_SPI_ATTRS=y
+CONFIG_SCSI_FC_ATTRS=y
+CONFIG_SCSI_ISCSI_ATTRS=m
+# CONFIG_SCSI_SAS_ATTRS is not set
+
+#
+# SCSI low-level drivers
+#
+# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_ACARD is not set
+# CONFIG_SCSI_AACRAID is not set
+# CONFIG_SCSI_AIC7XXX is not set
+# CONFIG_SCSI_AIC7XXX_OLD is not set
+# CONFIG_SCSI_AIC79XX is not set
+# CONFIG_MEGARAID_NEWGEN is not set
+# CONFIG_MEGARAID_LEGACY is not set
+# CONFIG_MEGARAID_SAS is not set
+# CONFIG_SCSI_SATA is not set
+# CONFIG_SCSI_BUSLOGIC is not set
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_EATA is not set
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+# CONFIG_SCSI_GDTH is not set
+# CONFIG_SCSI_IPS is not set
+CONFIG_SCSI_IBMVSCSI=y
+# CONFIG_SCSI_INITIO is not set
+# CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_PPA is not set
+# CONFIG_SCSI_IMM is not set
+CONFIG_SCSI_SYM53C8XX_2=y
+CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=0
+CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
+CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
+# CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set
+CONFIG_SCSI_IPR=y
+CONFIG_SCSI_IPR_TRACE=y
+CONFIG_SCSI_IPR_DUMP=y
+# CONFIG_SCSI_QLOGIC_FC is not set
+# CONFIG_SCSI_QLOGIC_1280 is not set
+CONFIG_SCSI_QLA2XXX=y
+CONFIG_SCSI_QLA21XX=m
+CONFIG_SCSI_QLA22XX=m
+CONFIG_SCSI_QLA2300=m
+CONFIG_SCSI_QLA2322=m
+CONFIG_SCSI_QLA6312=m
+CONFIG_SCSI_QLA24XX=m
+CONFIG_SCSI_LPFC=m
+# CONFIG_SCSI_DC395x is not set
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_DEBUG is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+CONFIG_MD=y
+CONFIG_BLK_DEV_MD=y
+CONFIG_MD_LINEAR=y
+CONFIG_MD_RAID0=y
+CONFIG_MD_RAID1=y
+CONFIG_MD_RAID10=m
+CONFIG_MD_RAID5=y
+CONFIG_MD_RAID6=m
+CONFIG_MD_MULTIPATH=m
+CONFIG_MD_FAULTY=m
+CONFIG_BLK_DEV_DM=y
+CONFIG_DM_CRYPT=m
+CONFIG_DM_SNAPSHOT=m
+CONFIG_DM_MIRROR=m
+CONFIG_DM_ZERO=m
+CONFIG_DM_MULTIPATH=m
+CONFIG_DM_MULTIPATH_EMC=m
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+# CONFIG_FUSION_SPI is not set
+# CONFIG_FUSION_FC is not set
+# CONFIG_FUSION_SAS is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+
+#
+# Macintosh device drivers
+#
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+CONFIG_DUMMY=m
+CONFIG_BONDING=m
+# CONFIG_EQUALIZER is not set
+CONFIG_TUN=m
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
+#
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_CASSINI is not set
+CONFIG_NET_VENDOR_3COM=y
+CONFIG_VORTEX=y
+# CONFIG_TYPHOON is not set
+
+#
+# Tulip family network device support
+#
+# CONFIG_NET_TULIP is not set
+# CONFIG_HP100 is not set
+CONFIG_IBMVETH=y
+CONFIG_NET_PCI=y
+CONFIG_PCNET32=y
+# CONFIG_AMD8111_ETH is not set
+# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_B44 is not set
+# CONFIG_FORCEDETH is not set
+# CONFIG_DGRS is not set
+# CONFIG_EEPRO100 is not set
+CONFIG_E100=y
+# CONFIG_FEALNX is not set
+# CONFIG_NATSEMI is not set
+# CONFIG_NE2K_PCI is not set
+# CONFIG_8139CP is not set
+# CONFIG_8139TOO is not set
+# CONFIG_SIS900 is not set
+# CONFIG_EPIC100 is not set
+# CONFIG_SUNDANCE is not set
+# CONFIG_VIA_RHINE is not set
+# CONFIG_NET_POCKET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+CONFIG_ACENIC=y
+CONFIG_ACENIC_OMIT_TIGON_I=y
+# CONFIG_DL2K is not set
+CONFIG_E1000=y
+# CONFIG_E1000_NAPI is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_VIA_VELOCITY is not set
+CONFIG_TIGON3=y
+# CONFIG_BNX2 is not set
+# CONFIG_MV643XX_ETH is not set
+
+#
+# Ethernet (10000 Mbit)
+#
+# CONFIG_CHELSIO_T1 is not set
+CONFIG_IXGB=m
+# CONFIG_IXGB_NAPI is not set
+CONFIG_S2IO=m
+# CONFIG_S2IO_NAPI is not set
+# CONFIG_2BUFF_MODE is not set
+
+#
+# Token Ring devices
+#
+CONFIG_TR=y
+CONFIG_IBMOL=y
+# CONFIG_3C359 is not set
+# CONFIG_TMS380TR is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PLIP is not set
+CONFIG_PPP=m
+# CONFIG_PPP_MULTILINK is not set
+# CONFIG_PPP_FILTER is not set
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_BSDCOMP=m
+CONFIG_PPPOE=m
+# CONFIG_SLIP is not set
+# CONFIG_NET_FC is not set
+# CONFIG_SHAPER is not set
+CONFIG_NETCONSOLE=y
+CONFIG_NETPOLL=y
+CONFIG_NETPOLL_RX=y
+CONFIG_NETPOLL_TRAP=y
+CONFIG_NET_POLL_CONTROLLER=y
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+CONFIG_KEYBOARD_ATKBD=y
+# 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_INPUT_MOUSE=y
+CONFIG_MOUSE_PS2=y
+# CONFIG_MOUSE_SERIAL is not set
+# CONFIG_MOUSE_VSXXXAA is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_PCSPKR=m
+# CONFIG_INPUT_UINPUT is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_I8042=y
+# CONFIG_SERIO_SERPORT is not set
+# CONFIG_SERIO_PARKBD is not set
+# CONFIG_SERIO_PCIPS2 is not set
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=4
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_SERIAL_ICOM=m
+# CONFIG_SERIAL_JSM is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+# CONFIG_PRINTER is not set
+# CONFIG_PPDEV is not set
+# CONFIG_TIPAR is not set
+CONFIG_HVC_CONSOLE=y
+CONFIG_HVCS=m
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+CONFIG_RAW_DRIVER=y
+CONFIG_MAX_RAW_DEVS=1024
+# CONFIG_HANGCHECK_TIMER is not set
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+
+#
+# I2C support
+#
+CONFIG_I2C=y
+# CONFIG_I2C_CHARDEV is not set
+
+#
+# I2C Algorithms
+#
+CONFIG_I2C_ALGOBIT=y
+# CONFIG_I2C_ALGOPCF is not set
+# CONFIG_I2C_ALGOPCA is not set
+
+#
+# I2C Hardware Bus support
+#
+# 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_PIIX4 is not set
+# CONFIG_I2C_NFORCE2 is not set
+# CONFIG_I2C_PARPORT is not set
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_PROSAVAGE is not set
+# CONFIG_I2C_SAVAGE4 is not set
+# CONFIG_SCx200_ACB is not set
+# CONFIG_I2C_SIS5595 is not set
+# CONFIG_I2C_SIS630 is not set
+# CONFIG_I2C_SIS96X is not set
+# CONFIG_I2C_STUB is not set
+# CONFIG_I2C_VIA is not set
+# CONFIG_I2C_VIAPRO is not set
+# CONFIG_I2C_VOODOO3 is not set
+# CONFIG_I2C_PCA_ISA is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_SENSORS_DS1337 is not set
+# CONFIG_SENSORS_DS1374 is not set
+# CONFIG_SENSORS_EEPROM is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_SENSORS_PCA9539 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_SENSORS_RTC8564 is not set
+# CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
+#
+# Misc devices
+#
+
+#
+# Multimedia Capabilities Port drivers
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+CONFIG_FB=y
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+CONFIG_FB_SOFT_CURSOR=y
+CONFIG_FB_MACMODES=y
+CONFIG_FB_MODE_HELPERS=y
+CONFIG_FB_TILEBLITTING=y
+# CONFIG_FB_CIRRUS is not set
+# CONFIG_FB_PM2 is not set
+# CONFIG_FB_CYBER2000 is not set
+CONFIG_FB_OF=y
+# CONFIG_FB_CT65550 is not set
+# CONFIG_FB_ASILIANT is not set
+# CONFIG_FB_IMSTT is not set
+# CONFIG_FB_VGA16 is not set
+# CONFIG_FB_NVIDIA is not set
+# CONFIG_FB_RIVA is not set
+CONFIG_FB_MATROX=y
+CONFIG_FB_MATROX_MILLENIUM=y
+CONFIG_FB_MATROX_MYSTIQUE=y
+CONFIG_FB_MATROX_G=y
+# CONFIG_FB_MATROX_I2C is not set
+CONFIG_FB_MATROX_MULTIHEAD=y
+# CONFIG_FB_RADEON_OLD is not set
+CONFIG_FB_RADEON=y
+CONFIG_FB_RADEON_I2C=y
+# CONFIG_FB_RADEON_DEBUG is not set
+# CONFIG_FB_ATY128 is not set
+# CONFIG_FB_ATY is not set
+# CONFIG_FB_SAVAGE is not set
+# CONFIG_FB_SIS is not set
+# CONFIG_FB_NEOMAGIC is not set
+# CONFIG_FB_KYRO is not set
+# CONFIG_FB_3DFX is not set
+# CONFIG_FB_VOODOO1 is not set
+# CONFIG_FB_CYBLA is not set
+# CONFIG_FB_TRIDENT is not set
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_VIRTUAL is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FONTS is not set
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+
+#
+# Logo configuration
+#
+CONFIG_LOGO=y
+CONFIG_LOGO_LINUX_MONO=y
+CONFIG_LOGO_LINUX_VGA16=y
+CONFIG_LOGO_LINUX_CLUT224=y
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_BACKLIGHT_CLASS_DEVICE=m
+CONFIG_BACKLIGHT_DEVICE=y
+CONFIG_LCD_CLASS_DEVICE=m
+CONFIG_LCD_DEVICE=y
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+# CONFIG_USB_BANDWIDTH is not set
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_OTG is not set
+
+#
+# USB Host Controller Drivers
+#
+CONFIG_USB_EHCI_HCD=y
+# CONFIG_USB_EHCI_SPLIT_ISO is not set
+# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
+# CONFIG_USB_ISP116X_HCD is not set
+CONFIG_USB_OHCI_HCD=y
+# CONFIG_USB_OHCI_BIG_ENDIAN is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+# CONFIG_USB_UHCI_HCD is not set
+# CONFIG_USB_SL811_HCD is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_BLUETOOTH_TTY is not set
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+#
+CONFIG_USB_STORAGE=y
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=y
+CONFIG_USB_HIDINPUT=y
+# CONFIG_HID_FF is not set
+CONFIG_USB_HIDDEV=y
+# CONFIG_USB_AIPTEK is not set
+# CONFIG_USB_WACOM is not set
+# CONFIG_USB_ACECAD is not set
+# CONFIG_USB_KBTAB is not set
+# CONFIG_USB_POWERMATE is not set
+# CONFIG_USB_MTOUCH is not set
+# CONFIG_USB_ITMTOUCH is not set
+# CONFIG_USB_EGALAX is not set
+# CONFIG_USB_YEALINK is not set
+# CONFIG_USB_XPAD is not set
+# CONFIG_USB_ATI_REMOTE is not set
+# CONFIG_USB_KEYSPAN_REMOTE is not set
+# CONFIG_USB_APPLETOUCH is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+
+#
+# USB Multimedia devices
+#
+# CONFIG_USB_DABUSB is not set
+
+#
+# Video4Linux support is needed for USB Multimedia device support
+#
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET is not set
+CONFIG_USB_MON=y
+
+#
+# USB port drivers
+#
+# CONFIG_USB_USS720 is not set
+
+#
+# USB Serial Converter support
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_AUERSWALD is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_PHIDGETKIT is not set
+# CONFIG_USB_PHIDGETSERVO is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_SISUSBVGA is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TEST is not set
+
+#
+# USB DSL modem support
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# InfiniBand support
+#
+CONFIG_INFINIBAND=m
+# CONFIG_INFINIBAND_USER_MAD is not set
+# CONFIG_INFINIBAND_USER_ACCESS is not set
+CONFIG_INFINIBAND_MTHCA=m
+# CONFIG_INFINIBAND_MTHCA_DEBUG is not set
+CONFIG_INFINIBAND_IPOIB=m
+# CONFIG_INFINIBAND_IPOIB_DEBUG is not set
+
+#
+# SN Devices
+#
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+CONFIG_EXT2_FS_XIP=y
+CONFIG_FS_XIP=y
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_XATTR=y
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+CONFIG_REISERFS_FS=y
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
+CONFIG_REISERFS_FS_XATTR=y
+CONFIG_REISERFS_FS_POSIX_ACL=y
+CONFIG_REISERFS_FS_SECURITY=y
+CONFIG_JFS_FS=m
+CONFIG_JFS_POSIX_ACL=y
+CONFIG_JFS_SECURITY=y
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
+CONFIG_FS_POSIX_ACL=y
+CONFIG_XFS_FS=m
+CONFIG_XFS_EXPORT=y
+# CONFIG_XFS_QUOTA is not set
+CONFIG_XFS_SECURITY=y
+CONFIG_XFS_POSIX_ACL=y
+# CONFIG_XFS_RT is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+CONFIG_AUTOFS_FS=m
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=y
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_ZISOFS_FS=y
+CONFIG_UDF_FS=m
+CONFIG_UDF_NLS=y
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+CONFIG_HUGETLBFS=y
+CONFIG_HUGETLB_PAGE=y
+CONFIG_RAMFS=y
+# CONFIG_RELAYFS_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_CRAMFS=y
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+# CONFIG_NFS_DIRECTIO is not set
+CONFIG_NFSD=y
+CONFIG_NFSD_V2_ACL=y
+CONFIG_NFSD_V3=y
+CONFIG_NFSD_V3_ACL=y
+CONFIG_NFSD_V4=y
+CONFIG_NFSD_TCP=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=y
+CONFIG_NFS_ACL_SUPPORT=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+CONFIG_SUNRPC_GSS=y
+CONFIG_RPCSEC_GSS_KRB5=y
+CONFIG_RPCSEC_GSS_SPKM3=m
+# CONFIG_SMB_FS is not set
+CONFIG_CIFS=m
+# CONFIG_CIFS_STATS is not set
+CONFIG_CIFS_XATTR=y
+CONFIG_CIFS_POSIX=y
+# CONFIG_CIFS_EXPERIMENTAL is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+
+#
+# Profiling support
+#
+CONFIG_PROFILING=y
+CONFIG_OPROFILE=y
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_DEBUG_KERNEL=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_LOG_BUF_SHIFT=17
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_INFO is not set
+CONFIG_DEBUG_FS=y
+CONFIG_DEBUG_STACKOVERFLOW=y
+# CONFIG_KPROBES is not set
+CONFIG_DEBUG_STACK_USAGE=y
+CONFIG_DEBUGGER=y
+CONFIG_XMON=y
+CONFIG_XMON_DEFAULT=y
+# CONFIG_PPCDBG is not set
+CONFIG_IRQSTACKS=y
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_DES=y
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_AES=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_CRC32C=m
+CONFIG_CRYPTO_TEST=m
+
+#
+# Hardware crypto devices
+#
+
+#
+# Library routines
+#
+CONFIG_CRC_CCITT=m
+# CONFIG_CRC16 is not set
+CONFIG_CRC32=y
+CONFIG_LIBCRC32C=m
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=m
+CONFIG_TEXTSEARCH=y
+CONFIG_TEXTSEARCH_KMP=m
+CONFIG_TEXTSEARCH_BM=m
+CONFIG_TEXTSEARCH_FSM=m
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
new file mode 100644
index 000000000000..c04bbd320594
--- /dev/null
+++ b/arch/powerpc/kernel/Makefile
@@ -0,0 +1,68 @@
+#
+# Makefile for the linux kernel.
+#
+
+ifeq ($(CONFIG_PPC64),y)
+EXTRA_CFLAGS += -mno-minimal-toc
+CFLAGS_ioctl32.o += -Ifs/
+endif
+ifeq ($(CONFIG_PPC32),y)
+CFLAGS_prom_init.o += -fPIC
+CFLAGS_btext.o += -fPIC
+endif
+
+obj-y := semaphore.o cputable.o ptrace.o syscalls.o \
+ irq.o signal_32.o pmc.o
+obj-$(CONFIG_PPC64) += setup_64.o binfmt_elf32.o sys_ppc32.o \
+ signal_64.o ptrace32.o systbl.o \
+ paca.o ioctl32.o cpu_setup_power4.o \
+ firmware.o sysfs.o
+obj-$(CONFIG_ALTIVEC) += vecemu.o vector.o
+obj-$(CONFIG_POWER4) += idle_power4.o
+obj-$(CONFIG_PPC_OF) += of_device.o
+procfs-$(CONFIG_PPC64) := proc_ppc64.o
+obj-$(CONFIG_PROC_FS) += $(procfs-y)
+rtaspci-$(CONFIG_PPC64) := rtas_pci.o
+obj-$(CONFIG_PPC_RTAS) += rtas.o $(rtaspci-y)
+obj-$(CONFIG_RTAS_FLASH) += rtas_flash.o
+obj-$(CONFIG_RTAS_PROC) += rtas-proc.o
+obj-$(CONFIG_LPARCFG) += lparcfg.o
+obj-$(CONFIG_IBMVIO) += vio.o
+obj-$(CONFIG_GENERIC_TBSYNC) += smp-tbsync.o
+
+ifeq ($(CONFIG_PPC_MERGE),y)
+
+extra-$(CONFIG_PPC_STD_MMU) := head_32.o
+extra-$(CONFIG_PPC64) := head_64.o
+extra-$(CONFIG_40x) := head_4xx.o
+extra-$(CONFIG_44x) := head_44x.o
+extra-$(CONFIG_FSL_BOOKE) := head_fsl_booke.o
+extra-$(CONFIG_8xx) := head_8xx.o
+extra-y += vmlinux.lds
+
+obj-y += process.o init_task.o time.o \
+ prom.o traps.o setup-common.o
+obj-$(CONFIG_PPC32) += entry_32.o setup_32.o misc_32.o systbl.o
+obj-$(CONFIG_PPC64) += misc_64.o
+obj-$(CONFIG_PPC_OF) += prom_init.o
+obj-$(CONFIG_MODULES) += ppc_ksyms.o
+obj-$(CONFIG_BOOTX_TEXT) += btext.o
+obj-$(CONFIG_6xx) += idle_6xx.o
+obj-$(CONFIG_SMP) += smp.o
+
+ifeq ($(CONFIG_PPC_ISERIES),y)
+$(obj)/head_64.o: $(obj)/lparmap.s
+AFLAGS_head_64.o += -I$(obj)
+endif
+
+else
+# stuff used from here for ARCH=ppc or ARCH=ppc64
+smpobj-$(CONFIG_SMP) += smp.o
+obj-$(CONFIG_PPC64) += traps.o process.o init_task.o time.o \
+ setup-common.o $(smpobj-y)
+
+
+endif
+
+extra-$(CONFIG_PPC_FPU) += fpu.o
+extra-$(CONFIG_PPC64) += entry_64.o
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c
new file mode 100644
index 000000000000..8793102711a8
--- /dev/null
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -0,0 +1,275 @@
+/*
+ * This program is used to generate definitions needed by
+ * assembly language modules.
+ *
+ * We use the technique used in the OSF Mach kernel code:
+ * generate asm statements containing #defines,
+ * compile this file to assembler, and then extract the
+ * #defines from the assembly-language output.
+ *
+ * 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/config.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/mman.h>
+#include <linux/mm.h>
+#ifdef CONFIG_PPC64
+#include <linux/time.h>
+#include <linux/hardirq.h>
+#else
+#include <linux/ptrace.h>
+#include <linux/suspend.h>
+#endif
+
+#include <asm/io.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/processor.h>
+#include <asm/cputable.h>
+#include <asm/thread_info.h>
+#include <asm/rtas.h>
+#ifdef CONFIG_PPC64
+#include <asm/paca.h>
+#include <asm/lppaca.h>
+#include <asm/iseries/hv_lp_event.h>
+#include <asm/cache.h>
+#include <asm/systemcfg.h>
+#include <asm/compat.h>
+#endif
+
+#define DEFINE(sym, val) \
+ asm volatile("\n->" #sym " %0 " #val : : "i" (val))
+
+#define BLANK() asm volatile("\n->" : : )
+
+int main(void)
+{
+ DEFINE(THREAD, offsetof(struct task_struct, thread));
+ DEFINE(MM, offsetof(struct task_struct, mm));
+#ifdef CONFIG_PPC64
+ DEFINE(AUDITCONTEXT, offsetof(struct task_struct, audit_context));
+#else
+ DEFINE(THREAD_INFO, offsetof(struct task_struct, thread_info));
+ DEFINE(PTRACE, offsetof(struct task_struct, ptrace));
+#endif /* CONFIG_PPC64 */
+
+ DEFINE(KSP, offsetof(struct thread_struct, ksp));
+ DEFINE(PT_REGS, offsetof(struct thread_struct, regs));
+ DEFINE(THREAD_FPEXC_MODE, offsetof(struct thread_struct, fpexc_mode));
+ DEFINE(THREAD_FPR0, offsetof(struct thread_struct, fpr[0]));
+ DEFINE(THREAD_FPSCR, offsetof(struct thread_struct, fpscr));
+#ifdef CONFIG_ALTIVEC
+ DEFINE(THREAD_VR0, offsetof(struct thread_struct, vr[0]));
+ DEFINE(THREAD_VRSAVE, offsetof(struct thread_struct, vrsave));
+ DEFINE(THREAD_VSCR, offsetof(struct thread_struct, vscr));
+ DEFINE(THREAD_USED_VR, offsetof(struct thread_struct, used_vr));
+#endif /* CONFIG_ALTIVEC */
+#ifdef CONFIG_PPC64
+ DEFINE(KSP_VSID, offsetof(struct thread_struct, ksp_vsid));
+#else /* CONFIG_PPC64 */
+ DEFINE(PGDIR, offsetof(struct thread_struct, pgdir));
+ DEFINE(LAST_SYSCALL, offsetof(struct thread_struct, last_syscall));
+#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
+ DEFINE(THREAD_DBCR0, offsetof(struct thread_struct, dbcr0));
+ DEFINE(PT_PTRACED, PT_PTRACED);
+#endif
+#ifdef CONFIG_SPE
+ DEFINE(THREAD_EVR0, offsetof(struct thread_struct, evr[0]));
+ DEFINE(THREAD_ACC, offsetof(struct thread_struct, acc));
+ DEFINE(THREAD_SPEFSCR, offsetof(struct thread_struct, spefscr));
+ DEFINE(THREAD_USED_SPE, offsetof(struct thread_struct, used_spe));
+#endif /* CONFIG_SPE */
+#endif /* CONFIG_PPC64 */
+
+ DEFINE(TI_FLAGS, offsetof(struct thread_info, flags));
+ DEFINE(TI_PREEMPT, offsetof(struct thread_info, preempt_count));
+ DEFINE(TI_SC_NOERR, offsetof(struct thread_info, syscall_noerror));
+#ifdef CONFIG_PPC32
+ DEFINE(TI_TASK, offsetof(struct thread_info, task));
+ DEFINE(TI_EXECDOMAIN, offsetof(struct thread_info, exec_domain));
+ DEFINE(TI_CPU, offsetof(struct thread_info, cpu));
+#endif /* CONFIG_PPC32 */
+
+#ifdef CONFIG_PPC64
+ DEFINE(DCACHEL1LINESIZE, offsetof(struct ppc64_caches, dline_size));
+ DEFINE(DCACHEL1LOGLINESIZE, offsetof(struct ppc64_caches, log_dline_size));
+ DEFINE(DCACHEL1LINESPERPAGE, offsetof(struct ppc64_caches, dlines_per_page));
+ DEFINE(ICACHEL1LINESIZE, offsetof(struct ppc64_caches, iline_size));
+ DEFINE(ICACHEL1LOGLINESIZE, offsetof(struct ppc64_caches, log_iline_size));
+ DEFINE(ICACHEL1LINESPERPAGE, offsetof(struct ppc64_caches, ilines_per_page));
+ DEFINE(PLATFORM_LPAR, PLATFORM_LPAR);
+
+ /* paca */
+ DEFINE(PACA_SIZE, sizeof(struct paca_struct));
+ DEFINE(PACAPACAINDEX, offsetof(struct paca_struct, paca_index));
+ DEFINE(PACAPROCSTART, offsetof(struct paca_struct, cpu_start));
+ DEFINE(PACAKSAVE, offsetof(struct paca_struct, kstack));
+ DEFINE(PACACURRENT, offsetof(struct paca_struct, __current));
+ DEFINE(PACASAVEDMSR, offsetof(struct paca_struct, saved_msr));
+ DEFINE(PACASTABREAL, offsetof(struct paca_struct, stab_real));
+ DEFINE(PACASTABVIRT, offsetof(struct paca_struct, stab_addr));
+ DEFINE(PACASTABRR, offsetof(struct paca_struct, stab_rr));
+ DEFINE(PACAR1, offsetof(struct paca_struct, saved_r1));
+ DEFINE(PACATOC, offsetof(struct paca_struct, kernel_toc));
+ DEFINE(PACAPROCENABLED, offsetof(struct paca_struct, proc_enabled));
+ DEFINE(PACASLBCACHE, offsetof(struct paca_struct, slb_cache));
+ DEFINE(PACASLBCACHEPTR, offsetof(struct paca_struct, slb_cache_ptr));
+ DEFINE(PACACONTEXTID, offsetof(struct paca_struct, context.id));
+#ifdef CONFIG_PPC_64K_PAGES
+ DEFINE(PACAPGDIR, offsetof(struct paca_struct, pgdir));
+#endif
+#ifdef CONFIG_HUGETLB_PAGE
+ DEFINE(PACALOWHTLBAREAS, offsetof(struct paca_struct, context.low_htlb_areas));
+ DEFINE(PACAHIGHHTLBAREAS, offsetof(struct paca_struct, context.high_htlb_areas));
+#endif /* CONFIG_HUGETLB_PAGE */
+ DEFINE(PACADEFAULTDECR, offsetof(struct paca_struct, default_decr));
+ DEFINE(PACA_EXGEN, offsetof(struct paca_struct, exgen));
+ DEFINE(PACA_EXMC, offsetof(struct paca_struct, exmc));
+ DEFINE(PACA_EXSLB, offsetof(struct paca_struct, exslb));
+ DEFINE(PACA_EXDSI, offsetof(struct paca_struct, exdsi));
+ DEFINE(PACAEMERGSP, offsetof(struct paca_struct, emergency_sp));
+ DEFINE(PACALPPACA, offsetof(struct paca_struct, lppaca));
+ DEFINE(PACAHWCPUID, offsetof(struct paca_struct, hw_cpu_id));
+
+ DEFINE(LPPACASRR0, offsetof(struct lppaca, saved_srr0));
+ DEFINE(LPPACASRR1, offsetof(struct lppaca, saved_srr1));
+ DEFINE(LPPACAANYINT, offsetof(struct lppaca, int_dword.any_int));
+ DEFINE(LPPACADECRINT, offsetof(struct lppaca, int_dword.fields.decr_int));
+#endif /* CONFIG_PPC64 */
+
+ /* RTAS */
+ DEFINE(RTASBASE, offsetof(struct rtas_t, base));
+ DEFINE(RTASENTRY, offsetof(struct rtas_t, entry));
+
+ /* Interrupt register frame */
+ DEFINE(STACK_FRAME_OVERHEAD, STACK_FRAME_OVERHEAD);
+#ifndef CONFIG_PPC64
+ DEFINE(INT_FRAME_SIZE, STACK_FRAME_OVERHEAD + sizeof(struct pt_regs));
+#else /* CONFIG_PPC64 */
+ DEFINE(SWITCH_FRAME_SIZE, STACK_FRAME_OVERHEAD + sizeof(struct pt_regs));
+ /* 288 = # of volatile regs, int & fp, for leaf routines */
+ /* which do not stack a frame. See the PPC64 ABI. */
+ DEFINE(INT_FRAME_SIZE, STACK_FRAME_OVERHEAD + sizeof(struct pt_regs) + 288);
+ /* Create extra stack space for SRR0 and SRR1 when calling prom/rtas. */
+ DEFINE(PROM_FRAME_SIZE, STACK_FRAME_OVERHEAD + sizeof(struct pt_regs) + 16);
+ DEFINE(RTAS_FRAME_SIZE, STACK_FRAME_OVERHEAD + sizeof(struct pt_regs) + 16);
+#endif /* CONFIG_PPC64 */
+ DEFINE(GPR0, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[0]));
+ DEFINE(GPR1, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[1]));
+ DEFINE(GPR2, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[2]));
+ DEFINE(GPR3, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[3]));
+ DEFINE(GPR4, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[4]));
+ DEFINE(GPR5, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[5]));
+ DEFINE(GPR6, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[6]));
+ DEFINE(GPR7, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[7]));
+ DEFINE(GPR8, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[8]));
+ DEFINE(GPR9, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[9]));
+ DEFINE(GPR10, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[10]));
+ DEFINE(GPR11, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[11]));
+ DEFINE(GPR12, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[12]));
+ DEFINE(GPR13, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[13]));
+#ifndef CONFIG_PPC64
+ DEFINE(GPR14, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[14]));
+ DEFINE(GPR15, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[15]));
+ DEFINE(GPR16, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[16]));
+ DEFINE(GPR17, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[17]));
+ DEFINE(GPR18, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[18]));
+ DEFINE(GPR19, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[19]));
+ DEFINE(GPR20, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[20]));
+ DEFINE(GPR21, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[21]));
+ DEFINE(GPR22, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[22]));
+ DEFINE(GPR23, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[23]));
+ DEFINE(GPR24, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[24]));
+ DEFINE(GPR25, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[25]));
+ DEFINE(GPR26, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[26]));
+ DEFINE(GPR27, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[27]));
+ DEFINE(GPR28, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[28]));
+ DEFINE(GPR29, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[29]));
+ DEFINE(GPR30, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[30]));
+ DEFINE(GPR31, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[31]));
+#endif /* CONFIG_PPC64 */
+ /*
+ * Note: these symbols include _ because they overlap with special
+ * register names
+ */
+ DEFINE(_NIP, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, nip));
+ DEFINE(_MSR, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, msr));
+ DEFINE(_CTR, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, ctr));
+ DEFINE(_LINK, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, link));
+ DEFINE(_CCR, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, ccr));
+ DEFINE(_XER, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, xer));
+ DEFINE(_DAR, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, dar));
+ DEFINE(_DSISR, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, dsisr));
+ DEFINE(ORIG_GPR3, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, orig_gpr3));
+ DEFINE(RESULT, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, result));
+ DEFINE(_TRAP, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, trap));
+#ifndef CONFIG_PPC64
+ DEFINE(_MQ, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, mq));
+ /*
+ * The PowerPC 400-class & Book-E processors have neither the DAR
+ * nor the DSISR SPRs. Hence, we overload them to hold the similar
+ * DEAR and ESR SPRs for such processors. For critical interrupts
+ * we use them to hold SRR0 and SRR1.
+ */
+ DEFINE(_DEAR, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, dar));
+ DEFINE(_ESR, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, dsisr));
+#else /* CONFIG_PPC64 */
+ DEFINE(SOFTE, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, softe));
+
+ /* These _only_ to be used with {PROM,RTAS}_FRAME_SIZE!!! */
+ DEFINE(_SRR0, STACK_FRAME_OVERHEAD+sizeof(struct pt_regs));
+ DEFINE(_SRR1, STACK_FRAME_OVERHEAD+sizeof(struct pt_regs)+8);
+#endif /* CONFIG_PPC64 */
+
+ DEFINE(CLONE_VM, CLONE_VM);
+ DEFINE(CLONE_UNTRACED, CLONE_UNTRACED);
+
+#ifndef CONFIG_PPC64
+ DEFINE(MM_PGD, offsetof(struct mm_struct, pgd));
+#endif /* ! CONFIG_PPC64 */
+
+ /* About the CPU features table */
+ DEFINE(CPU_SPEC_ENTRY_SIZE, sizeof(struct cpu_spec));
+ DEFINE(CPU_SPEC_PVR_MASK, offsetof(struct cpu_spec, pvr_mask));
+ DEFINE(CPU_SPEC_PVR_VALUE, offsetof(struct cpu_spec, pvr_value));
+ DEFINE(CPU_SPEC_FEATURES, offsetof(struct cpu_spec, cpu_features));
+ DEFINE(CPU_SPEC_SETUP, offsetof(struct cpu_spec, cpu_setup));
+
+#ifndef CONFIG_PPC64
+ DEFINE(pbe_address, offsetof(struct pbe, address));
+ DEFINE(pbe_orig_address, offsetof(struct pbe, orig_address));
+ DEFINE(pbe_next, offsetof(struct pbe, next));
+
+ DEFINE(TASK_SIZE, TASK_SIZE);
+ DEFINE(NUM_USER_SEGMENTS, TASK_SIZE>>28);
+#else /* CONFIG_PPC64 */
+ /* systemcfg offsets for use by vdso */
+ DEFINE(CFG_TB_ORIG_STAMP, offsetof(struct systemcfg, tb_orig_stamp));
+ DEFINE(CFG_TB_TICKS_PER_SEC, offsetof(struct systemcfg, tb_ticks_per_sec));
+ DEFINE(CFG_TB_TO_XS, offsetof(struct systemcfg, tb_to_xs));
+ DEFINE(CFG_STAMP_XSEC, offsetof(struct systemcfg, stamp_xsec));
+ DEFINE(CFG_TB_UPDATE_COUNT, offsetof(struct systemcfg, tb_update_count));
+ DEFINE(CFG_TZ_MINUTEWEST, offsetof(struct systemcfg, tz_minuteswest));
+ DEFINE(CFG_TZ_DSTTIME, offsetof(struct systemcfg, tz_dsttime));
+ DEFINE(CFG_SYSCALL_MAP32, offsetof(struct systemcfg, syscall_map_32));
+ DEFINE(CFG_SYSCALL_MAP64, offsetof(struct systemcfg, syscall_map_64));
+
+ /* timeval/timezone offsets for use by vdso */
+ DEFINE(TVAL64_TV_SEC, offsetof(struct timeval, tv_sec));
+ DEFINE(TVAL64_TV_USEC, offsetof(struct timeval, tv_usec));
+ DEFINE(TVAL32_TV_SEC, offsetof(struct compat_timeval, tv_sec));
+ DEFINE(TVAL32_TV_USEC, offsetof(struct compat_timeval, tv_usec));
+ DEFINE(TZONE_TZ_MINWEST, offsetof(struct timezone, tz_minuteswest));
+ DEFINE(TZONE_TZ_DSTTIME, offsetof(struct timezone, tz_dsttime));
+#endif /* CONFIG_PPC64 */
+ return 0;
+}
diff --git a/arch/ppc64/kernel/binfmt_elf32.c b/arch/powerpc/kernel/binfmt_elf32.c
index fadc699a0497..8ad6b0f33651 100644
--- a/arch/ppc64/kernel/binfmt_elf32.c
+++ b/arch/powerpc/kernel/binfmt_elf32.c
@@ -70,9 +70,6 @@ cputime_to_compat_timeval(const cputime_t cputime, struct compat_timeval *value)
value->tv_sec = jiffies / HZ;
}
-extern void start_thread32(struct pt_regs *, unsigned long, unsigned long);
-#undef start_thread
-#define start_thread start_thread32
#define init_elf_binfmt init_elf32_binfmt
#include "../../../fs/binfmt_elf.c"
diff --git a/arch/powerpc/kernel/btext.c b/arch/powerpc/kernel/btext.c
new file mode 100644
index 000000000000..bdfba92b2b38
--- /dev/null
+++ b/arch/powerpc/kernel/btext.c
@@ -0,0 +1,853 @@
+/*
+ * Procedures for drawing on the screen early on in the boot process.
+ *
+ * Benjamin Herrenschmidt <benh@kernel.crashing.org>
+ */
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/init.h>
+#include <linux/module.h>
+
+#include <asm/sections.h>
+#include <asm/prom.h>
+#include <asm/btext.h>
+#include <asm/prom.h>
+#include <asm/page.h>
+#include <asm/mmu.h>
+#include <asm/pgtable.h>
+#include <asm/io.h>
+#include <asm/lmb.h>
+#include <asm/processor.h>
+
+#define NO_SCROLL
+
+#ifndef NO_SCROLL
+static void scrollscreen(void);
+#endif
+
+static void draw_byte(unsigned char c, long locX, long locY);
+static void draw_byte_32(unsigned char *bits, unsigned int *base, int rb);
+static void draw_byte_16(unsigned char *bits, unsigned int *base, int rb);
+static void draw_byte_8(unsigned char *bits, unsigned int *base, int rb);
+
+static int g_loc_X;
+static int g_loc_Y;
+static int g_max_loc_X;
+static int g_max_loc_Y;
+
+static int dispDeviceRowBytes;
+static int dispDeviceDepth;
+static int dispDeviceRect[4];
+static unsigned char *dispDeviceBase, *logicalDisplayBase;
+
+unsigned long disp_BAT[2] __initdata = {0, 0};
+
+#define cmapsz (16*256)
+
+static unsigned char vga_font[cmapsz];
+
+int boot_text_mapped;
+int force_printk_to_btext = 0;
+
+#ifdef CONFIG_PPC32
+/* Calc BAT values for mapping the display and store them
+ * in disp_BAT. Those values are then used from head.S to map
+ * the display during identify_machine() and MMU_Init()
+ *
+ * The display is mapped to virtual address 0xD0000000, rather
+ * than 1:1, because some some CHRP machines put the frame buffer
+ * in the region starting at 0xC0000000 (KERNELBASE).
+ * This mapping is temporary and will disappear as soon as the
+ * setup done by MMU_Init() is applied.
+ *
+ * For now, we align the BAT and then map 8Mb on 601 and 16Mb
+ * on other PPCs. This may cause trouble if the framebuffer
+ * is really badly aligned, but I didn't encounter this case
+ * yet.
+ */
+void __init
+btext_prepare_BAT(void)
+{
+ unsigned long vaddr = KERNELBASE + 0x10000000;
+ unsigned long addr;
+ unsigned long lowbits;
+
+ addr = (unsigned long)dispDeviceBase;
+ if (!addr) {
+ boot_text_mapped = 0;
+ return;
+ }
+ if (PVR_VER(mfspr(SPRN_PVR)) != 1) {
+ /* 603, 604, G3, G4, ... */
+ lowbits = addr & ~0xFF000000UL;
+ addr &= 0xFF000000UL;
+ disp_BAT[0] = vaddr | (BL_16M<<2) | 2;
+ disp_BAT[1] = addr | (_PAGE_NO_CACHE | _PAGE_GUARDED | BPP_RW);
+ } else {
+ /* 601 */
+ lowbits = addr & ~0xFF800000UL;
+ addr &= 0xFF800000UL;
+ disp_BAT[0] = vaddr | (_PAGE_NO_CACHE | PP_RWXX) | 4;
+ disp_BAT[1] = addr | BL_8M | 0x40;
+ }
+ logicalDisplayBase = (void *) (vaddr + lowbits);
+}
+#endif
+
+/* This function will enable the early boot text when doing OF booting. This
+ * way, xmon output should work too
+ */
+void __init
+btext_setup_display(int width, int height, int depth, int pitch,
+ unsigned long address)
+{
+ g_loc_X = 0;
+ g_loc_Y = 0;
+ g_max_loc_X = width / 8;
+ g_max_loc_Y = height / 16;
+ logicalDisplayBase = (unsigned char *)address;
+ dispDeviceBase = (unsigned char *)address;
+ dispDeviceRowBytes = pitch;
+ dispDeviceDepth = depth;
+ dispDeviceRect[0] = dispDeviceRect[1] = 0;
+ dispDeviceRect[2] = width;
+ dispDeviceRect[3] = height;
+ boot_text_mapped = 1;
+}
+
+/* Here's a small text engine to use during early boot
+ * or for debugging purposes
+ *
+ * todo:
+ *
+ * - build some kind of vgacon with it to enable early printk
+ * - move to a separate file
+ * - add a few video driver hooks to keep in sync with display
+ * changes.
+ */
+
+void map_boot_text(void)
+{
+ unsigned long base, offset, size;
+ unsigned char *vbase;
+
+ /* By default, we are no longer mapped */
+ boot_text_mapped = 0;
+ if (dispDeviceBase == 0)
+ return;
+ base = ((unsigned long) dispDeviceBase) & 0xFFFFF000UL;
+ offset = ((unsigned long) dispDeviceBase) - base;
+ size = dispDeviceRowBytes * dispDeviceRect[3] + offset
+ + dispDeviceRect[0];
+ vbase = __ioremap(base, size, _PAGE_NO_CACHE);
+ if (vbase == 0)
+ return;
+ logicalDisplayBase = vbase + offset;
+ boot_text_mapped = 1;
+}
+
+int btext_initialize(struct device_node *np)
+{
+ unsigned int width, height, depth, pitch;
+ unsigned long address = 0;
+ u32 *prop;
+
+ prop = (u32 *)get_property(np, "width", NULL);
+ if (prop == NULL)
+ return -EINVAL;
+ width = *prop;
+ prop = (u32 *)get_property(np, "height", NULL);
+ if (prop == NULL)
+ return -EINVAL;
+ height = *prop;
+ prop = (u32 *)get_property(np, "depth", NULL);
+ if (prop == NULL)
+ return -EINVAL;
+ depth = *prop;
+ pitch = width * ((depth + 7) / 8);
+ prop = (u32 *)get_property(np, "linebytes", NULL);
+ if (prop)
+ pitch = *prop;
+ if (pitch == 1)
+ pitch = 0x1000;
+ prop = (u32 *)get_property(np, "address", NULL);
+ if (prop)
+ address = *prop;
+
+ /* FIXME: Add support for PCI reg properties */
+
+ if (address == 0)
+ return -EINVAL;
+
+ g_loc_X = 0;
+ g_loc_Y = 0;
+ g_max_loc_X = width / 8;
+ g_max_loc_Y = height / 16;
+ logicalDisplayBase = (unsigned char *)address;
+ dispDeviceBase = (unsigned char *)address;
+ dispDeviceRowBytes = pitch;
+ dispDeviceDepth = depth;
+ dispDeviceRect[0] = dispDeviceRect[1] = 0;
+ dispDeviceRect[2] = width;
+ dispDeviceRect[3] = height;
+
+ map_boot_text();
+
+ return 0;
+}
+
+void __init init_boot_display(void)
+{
+ char *name;
+ struct device_node *np = NULL;
+ int rc = -ENODEV;
+
+ printk("trying to initialize btext ...\n");
+
+ name = (char *)get_property(of_chosen, "linux,stdout-path", NULL);
+ if (name != NULL) {
+ np = of_find_node_by_path(name);
+ if (np != NULL) {
+ if (strcmp(np->type, "display") != 0) {
+ printk("boot stdout isn't a display !\n");
+ of_node_put(np);
+ np = NULL;
+ }
+ }
+ }
+ if (np)
+ rc = btext_initialize(np);
+ if (rc == 0)
+ return;
+
+ for (np = NULL; (np = of_find_node_by_type(np, "display"));) {
+ if (get_property(np, "linux,opened", NULL)) {
+ printk("trying %s ...\n", np->full_name);
+ rc = btext_initialize(np);
+ printk("result: %d\n", rc);
+ }
+ if (rc == 0)
+ return;
+ }
+}
+
+/* Calc the base address of a given point (x,y) */
+static unsigned char * calc_base(int x, int y)
+{
+ unsigned char *base;
+
+ base = logicalDisplayBase;
+ if (base == 0)
+ base = dispDeviceBase;
+ base += (x + dispDeviceRect[0]) * (dispDeviceDepth >> 3);
+ base += (y + dispDeviceRect[1]) * dispDeviceRowBytes;
+ return base;
+}
+
+/* Adjust the display to a new resolution */
+void btext_update_display(unsigned long phys, int width, int height,
+ int depth, int pitch)
+{
+ if (dispDeviceBase == 0)
+ return;
+
+ /* check it's the same frame buffer (within 256MB) */
+ if ((phys ^ (unsigned long)dispDeviceBase) & 0xf0000000)
+ return;
+
+ dispDeviceBase = (__u8 *) phys;
+ dispDeviceRect[0] = 0;
+ dispDeviceRect[1] = 0;
+ dispDeviceRect[2] = width;
+ dispDeviceRect[3] = height;
+ dispDeviceDepth = depth;
+ dispDeviceRowBytes = pitch;
+ if (boot_text_mapped) {
+ iounmap(logicalDisplayBase);
+ boot_text_mapped = 0;
+ }
+ map_boot_text();
+ g_loc_X = 0;
+ g_loc_Y = 0;
+ g_max_loc_X = width / 8;
+ g_max_loc_Y = height / 16;
+}
+EXPORT_SYMBOL(btext_update_display);
+
+void btext_clearscreen(void)
+{
+ unsigned long *base = (unsigned long *)calc_base(0, 0);
+ unsigned long width = ((dispDeviceRect[2] - dispDeviceRect[0]) *
+ (dispDeviceDepth >> 3)) >> 3;
+ int i,j;
+
+ for (i=0; i<(dispDeviceRect[3] - dispDeviceRect[1]); i++)
+ {
+ unsigned long *ptr = base;
+ for(j=width; j; --j)
+ *(ptr++) = 0;
+ base += (dispDeviceRowBytes >> 3);
+ }
+}
+
+#ifndef NO_SCROLL
+static void scrollscreen(void)
+{
+ unsigned long *src = (unsigned long *)calc_base(0,16);
+ unsigned long *dst = (unsigned long *)calc_base(0,0);
+ unsigned long width = ((dispDeviceRect[2] - dispDeviceRect[0]) *
+ (dispDeviceDepth >> 3)) >> 3;
+ int i,j;
+
+ for (i=0; i<(dispDeviceRect[3] - dispDeviceRect[1] - 16); i++)
+ {
+ unsigned long *src_ptr = src;
+ unsigned long *dst_ptr = dst;
+ for(j=width; j; --j)
+ *(dst_ptr++) = *(src_ptr++);
+ src += (dispDeviceRowBytes >> 3);
+ dst += (dispDeviceRowBytes >> 3);
+ }
+ for (i=0; i<16; i++)
+ {
+ unsigned long *dst_ptr = dst;
+ for(j=width; j; --j)
+ *(dst_ptr++) = 0;
+ dst += (dispDeviceRowBytes >> 3);
+ }
+}
+#endif /* ndef NO_SCROLL */
+
+void btext_drawchar(char c)
+{
+ int cline = 0;
+#ifdef NO_SCROLL
+ int x;
+#endif
+ if (!boot_text_mapped)
+ return;
+
+ switch (c) {
+ case '\b':
+ if (g_loc_X > 0)
+ --g_loc_X;
+ break;
+ case '\t':
+ g_loc_X = (g_loc_X & -8) + 8;
+ break;
+ case '\r':
+ g_loc_X = 0;
+ break;
+ case '\n':
+ g_loc_X = 0;
+ g_loc_Y++;
+ cline = 1;
+ break;
+ default:
+ draw_byte(c, g_loc_X++, g_loc_Y);
+ }
+ if (g_loc_X >= g_max_loc_X) {
+ g_loc_X = 0;
+ g_loc_Y++;
+ cline = 1;
+ }
+#ifndef NO_SCROLL
+ while (g_loc_Y >= g_max_loc_Y) {
+ scrollscreen();
+ g_loc_Y--;
+ }
+#else
+ /* wrap around from bottom to top of screen so we don't
+ waste time scrolling each line. -- paulus. */
+ if (g_loc_Y >= g_max_loc_Y)
+ g_loc_Y = 0;
+ if (cline) {
+ for (x = 0; x < g_max_loc_X; ++x)
+ draw_byte(' ', x, g_loc_Y);
+ }
+#endif
+}
+
+void btext_drawstring(const char *c)
+{
+ if (!boot_text_mapped)
+ return;
+ while (*c)
+ btext_drawchar(*c++);
+}
+
+void btext_drawhex(unsigned long v)
+{
+ char *hex_table = "0123456789abcdef";
+
+ if (!boot_text_mapped)
+ return;
+#ifdef CONFIG_PPC64
+ btext_drawchar(hex_table[(v >> 60) & 0x0000000FUL]);
+ btext_drawchar(hex_table[(v >> 56) & 0x0000000FUL]);
+ btext_drawchar(hex_table[(v >> 52) & 0x0000000FUL]);
+ btext_drawchar(hex_table[(v >> 48) & 0x0000000FUL]);
+ btext_drawchar(hex_table[(v >> 44) & 0x0000000FUL]);
+ btext_drawchar(hex_table[(v >> 40) & 0x0000000FUL]);
+ btext_drawchar(hex_table[(v >> 36) & 0x0000000FUL]);
+ btext_drawchar(hex_table[(v >> 32) & 0x0000000FUL]);
+#endif
+ btext_drawchar(hex_table[(v >> 28) & 0x0000000FUL]);
+ btext_drawchar(hex_table[(v >> 24) & 0x0000000FUL]);
+ btext_drawchar(hex_table[(v >> 20) & 0x0000000FUL]);
+ btext_drawchar(hex_table[(v >> 16) & 0x0000000FUL]);
+ btext_drawchar(hex_table[(v >> 12) & 0x0000000FUL]);
+ btext_drawchar(hex_table[(v >> 8) & 0x0000000FUL]);
+ btext_drawchar(hex_table[(v >> 4) & 0x0000000FUL]);
+ btext_drawchar(hex_table[(v >> 0) & 0x0000000FUL]);
+ btext_drawchar(' ');
+}
+
+static void draw_byte(unsigned char c, long locX, long locY)
+{
+ unsigned char *base = calc_base(locX << 3, locY << 4);
+ unsigned char *font = &vga_font[((unsigned int)c) * 16];
+ int rb = dispDeviceRowBytes;
+
+ switch(dispDeviceDepth) {
+ case 24:
+ case 32:
+ draw_byte_32(font, (unsigned int *)base, rb);
+ break;
+ case 15:
+ case 16:
+ draw_byte_16(font, (unsigned int *)base, rb);
+ break;
+ case 8:
+ draw_byte_8(font, (unsigned int *)base, rb);
+ break;
+ }
+}
+
+static unsigned int expand_bits_8[16] = {
+ 0x00000000,
+ 0x000000ff,
+ 0x0000ff00,
+ 0x0000ffff,
+ 0x00ff0000,
+ 0x00ff00ff,
+ 0x00ffff00,
+ 0x00ffffff,
+ 0xff000000,
+ 0xff0000ff,
+ 0xff00ff00,
+ 0xff00ffff,
+ 0xffff0000,
+ 0xffff00ff,
+ 0xffffff00,
+ 0xffffffff
+};
+
+static unsigned int expand_bits_16[4] = {
+ 0x00000000,
+ 0x0000ffff,
+ 0xffff0000,
+ 0xffffffff
+};
+
+
+static void draw_byte_32(unsigned char *font, unsigned int *base, int rb)
+{
+ int l, bits;
+ int fg = 0xFFFFFFFFUL;
+ int bg = 0x00000000UL;
+
+ for (l = 0; l < 16; ++l)
+ {
+ bits = *font++;
+ base[0] = (-(bits >> 7) & fg) ^ bg;
+ base[1] = (-((bits >> 6) & 1) & fg) ^ bg;
+ base[2] = (-((bits >> 5) & 1) & fg) ^ bg;
+ base[3] = (-((bits >> 4) & 1) & fg) ^ bg;
+ base[4] = (-((bits >> 3) & 1) & fg) ^ bg;
+ base[5] = (-((bits >> 2) & 1) & fg) ^ bg;
+ base[6] = (-((bits >> 1) & 1) & fg) ^ bg;
+ base[7] = (-(bits & 1) & fg) ^ bg;
+ base = (unsigned int *) ((char *)base + rb);
+ }
+}
+
+static void draw_byte_16(unsigned char *font, unsigned int *base, int rb)
+{
+ int l, bits;
+ int fg = 0xFFFFFFFFUL;
+ int bg = 0x00000000UL;
+ unsigned int *eb = (int *)expand_bits_16;
+
+ for (l = 0; l < 16; ++l)
+ {
+ bits = *font++;
+ base[0] = (eb[bits >> 6] & fg) ^ bg;
+ base[1] = (eb[(bits >> 4) & 3] & fg) ^ bg;
+ base[2] = (eb[(bits >> 2) & 3] & fg) ^ bg;
+ base[3] = (eb[bits & 3] & fg) ^ bg;
+ base = (unsigned int *) ((char *)base + rb);
+ }
+}
+
+static void draw_byte_8(unsigned char *font, unsigned int *base, int rb)
+{
+ int l, bits;
+ int fg = 0x0F0F0F0FUL;
+ int bg = 0x00000000UL;
+ unsigned int *eb = (int *)expand_bits_8;
+
+ for (l = 0; l < 16; ++l)
+ {
+ bits = *font++;
+ base[0] = (eb[bits >> 4] & fg) ^ bg;
+ base[1] = (eb[bits & 0xf] & fg) ^ bg;
+ base = (unsigned int *) ((char *)base + rb);
+ }
+}
+
+static unsigned char vga_font[cmapsz] = {
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x81, 0xa5, 0x81, 0x81, 0xbd,
+0x99, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xff,
+0xdb, 0xff, 0xff, 0xc3, 0xe7, 0xff, 0xff, 0x7e, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x6c, 0xfe, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x7c, 0xfe,
+0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
+0x3c, 0x3c, 0xe7, 0xe7, 0xe7, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x7e, 0x18, 0x18, 0x3c,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c,
+0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, 0x00,
+0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, 0x99, 0xbd,
+0xbd, 0x99, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x1e, 0x0e,
+0x1a, 0x32, 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x18,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x33, 0x3f, 0x30, 0x30, 0x30,
+0x30, 0x70, 0xf0, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x63,
+0x7f, 0x63, 0x63, 0x63, 0x63, 0x67, 0xe7, 0xe6, 0xc0, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x18, 0x18, 0xdb, 0x3c, 0xe7, 0x3c, 0xdb, 0x18, 0x18,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfe, 0xf8,
+0xf0, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x06, 0x0e,
+0x1e, 0x3e, 0xfe, 0x3e, 0x1e, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
+0x66, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xdb,
+0xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x7c, 0xc6, 0x60, 0x38, 0x6c, 0xc6, 0xc6, 0x6c, 0x38, 0x0c, 0xc6,
+0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0xfe, 0xfe, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c,
+0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0,
+0xc0, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x24, 0x66, 0xff, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x38, 0x7c, 0x7c, 0xfe, 0xfe, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x7c, 0x7c,
+0x38, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x24, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c,
+0x6c, 0xfe, 0x6c, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00,
+0x18, 0x18, 0x7c, 0xc6, 0xc2, 0xc0, 0x7c, 0x06, 0x06, 0x86, 0xc6, 0x7c,
+0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc2, 0xc6, 0x0c, 0x18,
+0x30, 0x60, 0xc6, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c,
+0x6c, 0x38, 0x76, 0xdc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x30, 0x30, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30,
+0x30, 0x30, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x18,
+0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e,
+0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x02, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xce, 0xde, 0xf6, 0xe6, 0xc6, 0xc6, 0x7c,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x38, 0x78, 0x18, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6,
+0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x7c, 0xc6, 0x06, 0x06, 0x3c, 0x06, 0x06, 0x06, 0xc6, 0x7c,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x1c, 0x3c, 0x6c, 0xcc, 0xfe,
+0x0c, 0x0c, 0x0c, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0,
+0xc0, 0xc0, 0xfc, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x38, 0x60, 0xc0, 0xc0, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc6, 0x06, 0x06, 0x0c, 0x18,
+0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6,
+0xc6, 0xc6, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x06, 0x0c, 0x78,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00,
+0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x06,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00,
+0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60,
+0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x0c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xde, 0xde,
+0xde, 0xdc, 0xc0, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38,
+0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x66, 0x66, 0x66, 0x66, 0xfc,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0,
+0xc0, 0xc2, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x6c,
+0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x62, 0x66, 0xfe,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68,
+0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66,
+0xc2, 0xc0, 0xc0, 0xde, 0xc6, 0xc6, 0x66, 0x3a, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x0c,
+0x0c, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0xe6, 0x66, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0x66, 0xe6,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x60, 0x60,
+0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xe7,
+0xff, 0xff, 0xdb, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0xc6,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
+0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x66,
+0x66, 0x66, 0x7c, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xde, 0x7c,
+0x0c, 0x0e, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x6c,
+0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6,
+0xc6, 0x60, 0x38, 0x0c, 0x06, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0xff, 0xdb, 0x99, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
+0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3,
+0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xdb, 0xdb, 0xff, 0x66, 0x66,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x18,
+0x3c, 0x66, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3,
+0xc3, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0xff, 0xc3, 0x86, 0x0c, 0x18, 0x30, 0x60, 0xc1, 0xc3, 0xff,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x30, 0x30, 0x30, 0x30, 0x30,
+0x30, 0x30, 0x30, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+0xc0, 0xe0, 0x70, 0x38, 0x1c, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x3c,
+0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
+0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0c, 0x7c,
+0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x60,
+0x60, 0x78, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x0c, 0x0c, 0x3c, 0x6c, 0xcc,
+0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xf0,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc,
+0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xcc, 0x78, 0x00, 0x00, 0x00, 0xe0, 0x60,
+0x60, 0x6c, 0x76, 0x66, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x18, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x00, 0x0e, 0x06, 0x06,
+0x06, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0xe0, 0x60,
+0x60, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0xff, 0xdb,
+0xdb, 0xdb, 0xdb, 0xdb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66,
+0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0x0c, 0x1e, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x76, 0x66, 0x60, 0x60, 0x60, 0xf0,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x60,
+0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x30,
+0x30, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 0xc3,
+0xc3, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0xc3, 0xc3, 0xc3, 0xdb, 0xdb, 0xff, 0x66, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x66, 0x3c, 0x18, 0x3c, 0x66, 0xc3,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6,
+0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0xfe, 0xcc, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x0e, 0x18, 0x18, 0x18, 0x70, 0x18, 0x18, 0x18, 0x18, 0x0e,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18,
+0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x18,
+0x18, 0x18, 0x0e, 0x18, 0x18, 0x18, 0x18, 0x70, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6,
+0xc6, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66,
+0xc2, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x0c, 0x06, 0x7c, 0x00, 0x00,
+0x00, 0x00, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x00, 0x7c, 0xc6, 0xfe,
+0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c,
+0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0xcc, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x00, 0x78, 0x0c, 0x7c,
+0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x38,
+0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x60, 0x60, 0x66, 0x3c, 0x0c, 0x06,
+0x3c, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xfe,
+0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00,
+0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00, 0x38, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x66,
+0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x60, 0x30, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c,
+0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6,
+0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x38, 0x00,
+0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
+0x18, 0x30, 0x60, 0x00, 0xfe, 0x66, 0x60, 0x7c, 0x60, 0x60, 0x66, 0xfe,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, 0x3b, 0x1b,
+0x7e, 0xd8, 0xdc, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x6c,
+0xcc, 0xcc, 0xfe, 0xcc, 0xcc, 0xcc, 0xcc, 0xce, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x00, 0x7c, 0xc6, 0xc6,
+0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18,
+0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x30, 0x78, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x00, 0xcc, 0xcc, 0xcc,
+0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00,
+0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0x78, 0x00,
+0x00, 0xc6, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c,
+0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
+0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e,
+0xc3, 0xc0, 0xc0, 0xc0, 0xc3, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xe6, 0xfc,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x66, 0x3c, 0x18, 0xff, 0x18,
+0xff, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x66, 0x66,
+0x7c, 0x62, 0x66, 0x6f, 0x66, 0x66, 0x66, 0xf3, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x0e, 0x1b, 0x18, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18,
+0xd8, 0x70, 0x00, 0x00, 0x00, 0x18, 0x30, 0x60, 0x00, 0x78, 0x0c, 0x7c,
+0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30,
+0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x18, 0x30, 0x60, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x30, 0x60, 0x00, 0xcc, 0xcc, 0xcc,
+0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc,
+0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00,
+0x76, 0xdc, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x6c, 0x6c, 0x3e, 0x00, 0x7e, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x6c,
+0x38, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x30, 0x30, 0x00, 0x30, 0x30, 0x60, 0xc0, 0xc6, 0xc6, 0x7c,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0,
+0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0xfe, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, 0x60, 0xce, 0x9b, 0x06,
+0x0c, 0x1f, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30,
+0x66, 0xce, 0x96, 0x3e, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18,
+0x00, 0x18, 0x18, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x6c, 0xd8, 0x6c, 0x36, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x6c, 0x36,
+0x6c, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x44, 0x11, 0x44,
+0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44,
+0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa,
+0x55, 0xaa, 0x55, 0xaa, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77,
+0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8,
+0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36,
+0x36, 0x36, 0x36, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x36, 0x36, 0x36, 0x36,
+0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0xf8,
+0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36,
+0x36, 0xf6, 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0xf6,
+0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+0x36, 0xf6, 0x06, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xfe, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x18, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37,
+0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+0x36, 0x37, 0x30, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36,
+0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xff,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0xff, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36,
+0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36,
+0x36, 0xf7, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0xff, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x36, 0x36, 0x36, 0x36,
+0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x3f,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x1f, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f,
+0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+0x36, 0x36, 0x36, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xf0, 0xf0, 0xf0,
+0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0,
+0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
+0x0f, 0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x76, 0xdc, 0xd8, 0xd8, 0xd8, 0xdc, 0x76, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0xd8, 0xcc, 0xc6, 0xc6, 0xc6, 0xcc,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc6, 0xc6, 0xc0, 0xc0, 0xc0,
+0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0xfe, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0xfe, 0xc6, 0x60, 0x30, 0x18, 0x30, 0x60, 0xc6, 0xfe,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xd8, 0xd8,
+0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x66, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xc0, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x18, 0x3c, 0x66, 0x66,
+0x66, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38,
+0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0x6c, 0x6c, 0x6c, 0x6c, 0xee,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x30, 0x18, 0x0c, 0x3e, 0x66,
+0x66, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x7e, 0xdb, 0xdb, 0xdb, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x03, 0x06, 0x7e, 0xdb, 0xdb, 0xf3, 0x7e, 0x60, 0xc0,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x30, 0x60, 0x60, 0x7c, 0x60,
+0x60, 0x60, 0x30, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c,
+0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18,
+0x18, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30,
+0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x00, 0x7e,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x1b, 0x1b, 0x1b, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x18, 0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x7e, 0x00, 0x18, 0x18, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00,
+0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x6c,
+0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x0c, 0x0c,
+0x0c, 0x0c, 0x0c, 0xec, 0x6c, 0x6c, 0x3c, 0x1c, 0x00, 0x00, 0x00, 0x00,
+0x00, 0xd8, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0xd8, 0x30, 0x60, 0xc8, 0xf8, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00,
+};
diff --git a/arch/ppc64/kernel/cpu_setup_power4.S b/arch/powerpc/kernel/cpu_setup_power4.S
index 1fb673c511ff..cca942fe6115 100644
--- a/arch/ppc64/kernel/cpu_setup_power4.S
+++ b/arch/powerpc/kernel/cpu_setup_power4.S
@@ -114,11 +114,11 @@ _GLOBAL(__setup_cpu_ppc970)
.data
.balign L1_CACHE_BYTES,0
-cpu_state_storage:
+cpu_state_storage:
.space CS_SIZE
.balign L1_CACHE_BYTES,0
.text
-
+
/* Called in normal context to backup CPU 0 state. This
* does not include cache settings. This function is also
* called for machine sleep. This does not include the MMU
@@ -151,7 +151,7 @@ _GLOBAL(__save_cpu_setup)
std r3,CS_HID4(r5)
mfspr r3,SPRN_HID5
std r3,CS_HID5(r5)
-
+
2:
mtcr r7
blr
@@ -213,7 +213,7 @@ _GLOBAL(__restore_cpu_setup)
mtspr SPRN_HID1,r3
sync
isync
-
+
/* Restore HID4 */
ld r3,CS_HID4(r5)
sync
diff --git a/arch/ppc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c
index 6b76cf58d9e0..1d85cedbbb7b 100644
--- a/arch/ppc/kernel/cputable.c
+++ b/arch/powerpc/kernel/cputable.c
@@ -1,8 +1,9 @@
/*
- * arch/ppc/kernel/cputable.c
- *
* Copyright (C) 2001 Ben. Herrenschmidt (benh@kernel.crashing.org)
*
+ * Modifications for ppc64:
+ * Copyright (C) 2003 Dave Engebretsen <engebret@us.ibm.com>
+ *
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
@@ -14,96 +15,305 @@
#include <linux/sched.h>
#include <linux/threads.h>
#include <linux/init.h>
-#include <asm/cputable.h>
+#include <linux/module.h>
-struct cpu_spec* cur_cpu_spec[NR_CPUS];
+#include <asm/oprofile_impl.h>
+#include <asm/cputable.h>
-extern void __setup_cpu_601(unsigned long offset, int cpu_nr, struct cpu_spec* spec);
-extern void __setup_cpu_603(unsigned long offset, int cpu_nr, struct cpu_spec* spec);
-extern void __setup_cpu_604(unsigned long offset, int cpu_nr, struct cpu_spec* spec);
-extern void __setup_cpu_750(unsigned long offset, int cpu_nr, struct cpu_spec* spec);
-extern void __setup_cpu_750cx(unsigned long offset, int cpu_nr, struct cpu_spec* spec);
-extern void __setup_cpu_750fx(unsigned long offset, int cpu_nr, struct cpu_spec* spec);
-extern void __setup_cpu_7400(unsigned long offset, int cpu_nr, struct cpu_spec* spec);
-extern void __setup_cpu_7410(unsigned long offset, int cpu_nr, struct cpu_spec* spec);
-extern void __setup_cpu_745x(unsigned long offset, int cpu_nr, struct cpu_spec* spec);
-extern void __setup_cpu_power3(unsigned long offset, int cpu_nr, struct cpu_spec* spec);
-extern void __setup_cpu_power4(unsigned long offset, int cpu_nr, struct cpu_spec* spec);
-extern void __setup_cpu_ppc970(unsigned long offset, int cpu_nr, struct cpu_spec* spec);
-extern void __setup_cpu_generic(unsigned long offset, int cpu_nr, struct cpu_spec* spec);
+struct cpu_spec* cur_cpu_spec = NULL;
+EXPORT_SYMBOL(cur_cpu_spec);
-#define CLASSIC_PPC (!defined(CONFIG_8xx) && !defined(CONFIG_4xx) && \
- !defined(CONFIG_POWER3) && !defined(CONFIG_POWER4) && \
- !defined(CONFIG_BOOKE))
+/* NOTE:
+ * Unlike ppc32, ppc64 will only call this once for the boot CPU, it's
+ * the responsibility of the appropriate CPU save/restore functions to
+ * eventually copy these settings over. Those save/restore aren't yet
+ * part of the cputable though. That has to be fixed for both ppc32
+ * and ppc64
+ */
+#ifdef CONFIG_PPC64
+extern void __setup_cpu_power3(unsigned long offset, struct cpu_spec* spec);
+extern void __setup_cpu_power4(unsigned long offset, struct cpu_spec* spec);
+extern void __setup_cpu_be(unsigned long offset, struct cpu_spec* spec);
+#else
+extern void __setup_cpu_603(unsigned long offset, struct cpu_spec* spec);
+extern void __setup_cpu_604(unsigned long offset, struct cpu_spec* spec);
+extern void __setup_cpu_750(unsigned long offset, struct cpu_spec* spec);
+extern void __setup_cpu_750cx(unsigned long offset, struct cpu_spec* spec);
+extern void __setup_cpu_750fx(unsigned long offset, struct cpu_spec* spec);
+extern void __setup_cpu_7400(unsigned long offset, struct cpu_spec* spec);
+extern void __setup_cpu_7410(unsigned long offset, struct cpu_spec* spec);
+extern void __setup_cpu_745x(unsigned long offset, struct cpu_spec* spec);
+#endif /* CONFIG_PPC32 */
+extern void __setup_cpu_ppc970(unsigned long offset, struct cpu_spec* spec);
/* This table only contains "desktop" CPUs, it need to be filled with embedded
* ones as well...
*/
-#define COMMON_PPC (PPC_FEATURE_32 | PPC_FEATURE_HAS_FPU | \
- PPC_FEATURE_HAS_MMU)
+#define COMMON_USER (PPC_FEATURE_32 | PPC_FEATURE_HAS_FPU | \
+ PPC_FEATURE_HAS_MMU)
+#define COMMON_USER_PPC64 (COMMON_USER | PPC_FEATURE_64)
+#define COMMON_USER_POWER4 (COMMON_USER_PPC64 | PPC_FEATURE_POWER4)
+#define COMMON_USER_POWER5 (COMMON_USER_PPC64 | PPC_FEATURE_POWER5)
+#define COMMON_USER_POWER5_PLUS (COMMON_USER_PPC64 | PPC_FEATURE_POWER5_PLUS)
-/* We only set the altivec features if the kernel was compiled with altivec
- * support
- */
-#ifdef CONFIG_ALTIVEC
-#define CPU_FTR_ALTIVEC_COMP CPU_FTR_ALTIVEC
-#define PPC_FEATURE_ALTIVEC_COMP PPC_FEATURE_HAS_ALTIVEC
-#else
-#define CPU_FTR_ALTIVEC_COMP 0
-#define PPC_FEATURE_ALTIVEC_COMP 0
-#endif
/* We only set the spe features if the kernel was compiled with
* spe support
*/
#ifdef CONFIG_SPE
-#define PPC_FEATURE_SPE_COMP PPC_FEATURE_HAS_SPE
+#define PPC_FEATURE_SPE_COMP PPC_FEATURE_HAS_SPE
#else
-#define PPC_FEATURE_SPE_COMP 0
+#define PPC_FEATURE_SPE_COMP 0
#endif
-/* We need to mark all pages as being coherent if we're SMP or we
- * have a 74[45]x and an MPC107 host bridge.
- */
-#if defined(CONFIG_SMP) || defined(CONFIG_MPC10X_BRIDGE)
-#define CPU_FTR_COMMON CPU_FTR_NEED_COHERENT
-#else
-#define CPU_FTR_COMMON 0
+struct cpu_spec cpu_specs[] = {
+#ifdef CONFIG_PPC64
+ { /* Power3 */
+ .pvr_mask = 0xffff0000,
+ .pvr_value = 0x00400000,
+ .cpu_name = "POWER3 (630)",
+ .cpu_features = CPU_FTRS_POWER3,
+ .cpu_user_features = COMMON_USER_PPC64,
+ .icache_bsize = 128,
+ .dcache_bsize = 128,
+ .num_pmcs = 8,
+ .cpu_setup = __setup_cpu_power3,
+#ifdef CONFIG_OPROFILE
+ .oprofile_cpu_type = "ppc64/power3",
+ .oprofile_model = &op_model_rs64,
#endif
-
-/* The powersave features NAP & DOZE seems to confuse BDI when
- debugging. So if a BDI is used, disable theses
- */
-#ifndef CONFIG_BDI_SWITCH
-#define CPU_FTR_MAYBE_CAN_DOZE CPU_FTR_CAN_DOZE
-#define CPU_FTR_MAYBE_CAN_NAP CPU_FTR_CAN_NAP
+ },
+ { /* Power3+ */
+ .pvr_mask = 0xffff0000,
+ .pvr_value = 0x00410000,
+ .cpu_name = "POWER3 (630+)",
+ .cpu_features = CPU_FTRS_POWER3,
+ .cpu_user_features = COMMON_USER_PPC64,
+ .icache_bsize = 128,
+ .dcache_bsize = 128,
+ .num_pmcs = 8,
+ .cpu_setup = __setup_cpu_power3,
+#ifdef CONFIG_OPROFILE
+ .oprofile_cpu_type = "ppc64/power3",
+ .oprofile_model = &op_model_rs64,
+#endif
+ },
+ { /* Northstar */
+ .pvr_mask = 0xffff0000,
+ .pvr_value = 0x00330000,
+ .cpu_name = "RS64-II (northstar)",
+ .cpu_features = CPU_FTRS_RS64,
+ .cpu_user_features = COMMON_USER_PPC64,
+ .icache_bsize = 128,
+ .dcache_bsize = 128,
+ .num_pmcs = 8,
+ .cpu_setup = __setup_cpu_power3,
+#ifdef CONFIG_OPROFILE
+ .oprofile_cpu_type = "ppc64/rs64",
+ .oprofile_model = &op_model_rs64,
+#endif
+ },
+ { /* Pulsar */
+ .pvr_mask = 0xffff0000,
+ .pvr_value = 0x00340000,
+ .cpu_name = "RS64-III (pulsar)",
+ .cpu_features = CPU_FTRS_RS64,
+ .cpu_user_features = COMMON_USER_PPC64,
+ .icache_bsize = 128,
+ .dcache_bsize = 128,
+ .num_pmcs = 8,
+ .cpu_setup = __setup_cpu_power3,
+#ifdef CONFIG_OPROFILE
+ .oprofile_cpu_type = "ppc64/rs64",
+ .oprofile_model = &op_model_rs64,
+#endif
+ },
+ { /* I-star */
+ .pvr_mask = 0xffff0000,
+ .pvr_value = 0x00360000,
+ .cpu_name = "RS64-III (icestar)",
+ .cpu_features = CPU_FTRS_RS64,
+ .cpu_user_features = COMMON_USER_PPC64,
+ .icache_bsize = 128,
+ .dcache_bsize = 128,
+ .num_pmcs = 8,
+ .cpu_setup = __setup_cpu_power3,
+#ifdef CONFIG_OPROFILE
+ .oprofile_cpu_type = "ppc64/rs64",
+ .oprofile_model = &op_model_rs64,
+#endif
+ },
+ { /* S-star */
+ .pvr_mask = 0xffff0000,
+ .pvr_value = 0x00370000,
+ .cpu_name = "RS64-IV (sstar)",
+ .cpu_features = CPU_FTRS_RS64,
+ .cpu_user_features = COMMON_USER_PPC64,
+ .icache_bsize = 128,
+ .dcache_bsize = 128,
+ .num_pmcs = 8,
+ .cpu_setup = __setup_cpu_power3,
+#ifdef CONFIG_OPROFILE
+ .oprofile_cpu_type = "ppc64/rs64",
+ .oprofile_model = &op_model_rs64,
+#endif
+ },
+ { /* Power4 */
+ .pvr_mask = 0xffff0000,
+ .pvr_value = 0x00350000,
+ .cpu_name = "POWER4 (gp)",
+ .cpu_features = CPU_FTRS_POWER4,
+ .cpu_user_features = COMMON_USER_POWER4,
+ .icache_bsize = 128,
+ .dcache_bsize = 128,
+ .num_pmcs = 8,
+ .cpu_setup = __setup_cpu_power4,
+#ifdef CONFIG_OPROFILE
+ .oprofile_cpu_type = "ppc64/power4",
+ .oprofile_model = &op_model_rs64,
+#endif
+ },
+ { /* Power4+ */
+ .pvr_mask = 0xffff0000,
+ .pvr_value = 0x00380000,
+ .cpu_name = "POWER4+ (gq)",
+ .cpu_features = CPU_FTRS_POWER4,
+ .cpu_user_features = COMMON_USER_POWER4,
+ .icache_bsize = 128,
+ .dcache_bsize = 128,
+ .num_pmcs = 8,
+ .cpu_setup = __setup_cpu_power4,
+#ifdef CONFIG_OPROFILE
+ .oprofile_cpu_type = "ppc64/power4",
+ .oprofile_model = &op_model_power4,
+#endif
+ },
+ { /* PPC970 */
+ .pvr_mask = 0xffff0000,
+ .pvr_value = 0x00390000,
+ .cpu_name = "PPC970",
+ .cpu_features = CPU_FTRS_PPC970,
+ .cpu_user_features = COMMON_USER_POWER4 |
+ PPC_FEATURE_HAS_ALTIVEC_COMP,
+ .icache_bsize = 128,
+ .dcache_bsize = 128,
+ .num_pmcs = 8,
+ .cpu_setup = __setup_cpu_ppc970,
+#ifdef CONFIG_OPROFILE
+ .oprofile_cpu_type = "ppc64/970",
+ .oprofile_model = &op_model_power4,
+#endif
+ },
+#endif /* CONFIG_PPC64 */
+#if defined(CONFIG_PPC64) || defined(CONFIG_POWER4)
+ { /* PPC970FX */
+ .pvr_mask = 0xffff0000,
+ .pvr_value = 0x003c0000,
+ .cpu_name = "PPC970FX",
+#ifdef CONFIG_PPC32
+ .cpu_features = CPU_FTRS_970_32,
#else
-#define CPU_FTR_MAYBE_CAN_DOZE 0
-#define CPU_FTR_MAYBE_CAN_NAP 0
+ .cpu_features = CPU_FTRS_PPC970,
#endif
-
-struct cpu_spec cpu_specs[] = {
+ .cpu_user_features = COMMON_USER_POWER4 |
+ PPC_FEATURE_HAS_ALTIVEC_COMP,
+ .icache_bsize = 128,
+ .dcache_bsize = 128,
+ .num_pmcs = 8,
+ .cpu_setup = __setup_cpu_ppc970,
+#ifdef CONFIG_OPROFILE
+ .oprofile_cpu_type = "ppc64/970",
+ .oprofile_model = &op_model_power4,
+#endif
+ },
+#endif /* defined(CONFIG_PPC64) || defined(CONFIG_POWER4) */
+#ifdef CONFIG_PPC64
+ { /* PPC970MP */
+ .pvr_mask = 0xffff0000,
+ .pvr_value = 0x00440000,
+ .cpu_name = "PPC970MP",
+ .cpu_features = CPU_FTRS_PPC970,
+ .cpu_user_features = COMMON_USER_POWER4 |
+ PPC_FEATURE_HAS_ALTIVEC_COMP,
+ .icache_bsize = 128,
+ .dcache_bsize = 128,
+ .cpu_setup = __setup_cpu_ppc970,
+#ifdef CONFIG_OPROFILE
+ .oprofile_cpu_type = "ppc64/970",
+ .oprofile_model = &op_model_power4,
+#endif
+ },
+ { /* Power5 GR */
+ .pvr_mask = 0xffff0000,
+ .pvr_value = 0x003a0000,
+ .cpu_name = "POWER5 (gr)",
+ .cpu_features = CPU_FTRS_POWER5,
+ .cpu_user_features = COMMON_USER_POWER5,
+ .icache_bsize = 128,
+ .dcache_bsize = 128,
+ .num_pmcs = 6,
+ .cpu_setup = __setup_cpu_power4,
+#ifdef CONFIG_OPROFILE
+ .oprofile_cpu_type = "ppc64/power5",
+ .oprofile_model = &op_model_power4,
+#endif
+ },
+ { /* Power5 GS */
+ .pvr_mask = 0xffff0000,
+ .pvr_value = 0x003b0000,
+ .cpu_name = "POWER5 (gs)",
+ .cpu_features = CPU_FTRS_POWER5,
+ .cpu_user_features = COMMON_USER_POWER5_PLUS,
+ .icache_bsize = 128,
+ .dcache_bsize = 128,
+ .num_pmcs = 6,
+ .cpu_setup = __setup_cpu_power4,
+#ifdef CONFIG_OPROFILE
+ .oprofile_cpu_type = "ppc64/power5",
+ .oprofile_model = &op_model_power4,
+#endif
+ },
+ { /* BE DD1.x */
+ .pvr_mask = 0xffff0000,
+ .pvr_value = 0x00700000,
+ .cpu_name = "Cell Broadband Engine",
+ .cpu_features = CPU_FTRS_CELL,
+ .cpu_user_features = COMMON_USER_PPC64 |
+ PPC_FEATURE_CELL | PPC_FEATURE_HAS_ALTIVEC_COMP,
+ .icache_bsize = 128,
+ .dcache_bsize = 128,
+ .cpu_setup = __setup_cpu_be,
+ },
+ { /* default match */
+ .pvr_mask = 0x00000000,
+ .pvr_value = 0x00000000,
+ .cpu_name = "POWER4 (compatible)",
+ .cpu_features = CPU_FTRS_COMPATIBLE,
+ .cpu_user_features = COMMON_USER_PPC64,
+ .icache_bsize = 128,
+ .dcache_bsize = 128,
+ .num_pmcs = 6,
+ .cpu_setup = __setup_cpu_power4,
+ }
+#endif /* CONFIG_PPC64 */
+#ifdef CONFIG_PPC32
#if CLASSIC_PPC
- { /* 601 */
+ { /* 601 */
.pvr_mask = 0xffff0000,
.pvr_value = 0x00010000,
.cpu_name = "601",
- .cpu_features = CPU_FTR_COMMON | CPU_FTR_601 |
- CPU_FTR_HPTE_TABLE,
- .cpu_user_features = COMMON_PPC | PPC_FEATURE_601_INSTR |
+ .cpu_features = CPU_FTRS_PPC601,
+ .cpu_user_features = COMMON_USER | PPC_FEATURE_601_INSTR |
PPC_FEATURE_UNIFIED_CACHE | PPC_FEATURE_NO_TB,
.icache_bsize = 32,
.dcache_bsize = 32,
- .cpu_setup = __setup_cpu_601
},
{ /* 603 */
.pvr_mask = 0xffff0000,
.pvr_value = 0x00030000,
.cpu_name = "603",
- .cpu_features = CPU_FTR_COMMON |
- CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_MAYBE_CAN_DOZE |
- CPU_FTR_USE_TB | CPU_FTR_MAYBE_CAN_NAP,
- .cpu_user_features = COMMON_PPC,
+ .cpu_features = CPU_FTRS_603,
+ .cpu_user_features = COMMON_USER,
.icache_bsize = 32,
.dcache_bsize = 32,
.cpu_setup = __setup_cpu_603
@@ -112,10 +322,8 @@ struct cpu_spec cpu_specs[] = {
.pvr_mask = 0xffff0000,
.pvr_value = 0x00060000,
.cpu_name = "603e",
- .cpu_features = CPU_FTR_COMMON |
- CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_MAYBE_CAN_DOZE |
- CPU_FTR_USE_TB | CPU_FTR_MAYBE_CAN_NAP,
- .cpu_user_features = COMMON_PPC,
+ .cpu_features = CPU_FTRS_603,
+ .cpu_user_features = COMMON_USER,
.icache_bsize = 32,
.dcache_bsize = 32,
.cpu_setup = __setup_cpu_603
@@ -124,10 +332,8 @@ struct cpu_spec cpu_specs[] = {
.pvr_mask = 0xffff0000,
.pvr_value = 0x00070000,
.cpu_name = "603ev",
- .cpu_features = CPU_FTR_COMMON |
- CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_MAYBE_CAN_DOZE |
- CPU_FTR_USE_TB | CPU_FTR_MAYBE_CAN_NAP,
- .cpu_user_features = COMMON_PPC,
+ .cpu_features = CPU_FTRS_603,
+ .cpu_user_features = COMMON_USER,
.icache_bsize = 32,
.dcache_bsize = 32,
.cpu_setup = __setup_cpu_603
@@ -136,10 +342,8 @@ struct cpu_spec cpu_specs[] = {
.pvr_mask = 0xffff0000,
.pvr_value = 0x00040000,
.cpu_name = "604",
- .cpu_features = CPU_FTR_COMMON |
- CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB |
- CPU_FTR_604_PERF_MON | CPU_FTR_HPTE_TABLE,
- .cpu_user_features = COMMON_PPC,
+ .cpu_features = CPU_FTRS_604,
+ .cpu_user_features = COMMON_USER,
.icache_bsize = 32,
.dcache_bsize = 32,
.num_pmcs = 2,
@@ -149,10 +353,8 @@ struct cpu_spec cpu_specs[] = {
.pvr_mask = 0xfffff000,
.pvr_value = 0x00090000,
.cpu_name = "604e",
- .cpu_features = CPU_FTR_COMMON |
- CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB |
- CPU_FTR_604_PERF_MON | CPU_FTR_HPTE_TABLE,
- .cpu_user_features = COMMON_PPC,
+ .cpu_features = CPU_FTRS_604,
+ .cpu_user_features = COMMON_USER,
.icache_bsize = 32,
.dcache_bsize = 32,
.num_pmcs = 4,
@@ -162,10 +364,8 @@ struct cpu_spec cpu_specs[] = {
.pvr_mask = 0xffff0000,
.pvr_value = 0x00090000,
.cpu_name = "604r",
- .cpu_features = CPU_FTR_COMMON |
- CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB |
- CPU_FTR_604_PERF_MON | CPU_FTR_HPTE_TABLE,
- .cpu_user_features = COMMON_PPC,
+ .cpu_features = CPU_FTRS_604,
+ .cpu_user_features = COMMON_USER,
.icache_bsize = 32,
.dcache_bsize = 32,
.num_pmcs = 4,
@@ -175,10 +375,8 @@ struct cpu_spec cpu_specs[] = {
.pvr_mask = 0xffff0000,
.pvr_value = 0x000a0000,
.cpu_name = "604ev",
- .cpu_features = CPU_FTR_COMMON |
- CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB |
- CPU_FTR_604_PERF_MON | CPU_FTR_HPTE_TABLE,
- .cpu_user_features = COMMON_PPC,
+ .cpu_features = CPU_FTRS_604,
+ .cpu_user_features = COMMON_USER,
.icache_bsize = 32,
.dcache_bsize = 32,
.num_pmcs = 4,
@@ -188,11 +386,8 @@ struct cpu_spec cpu_specs[] = {
.pvr_mask = 0xffffffff,
.pvr_value = 0x00084202,
.cpu_name = "740/750",
- .cpu_features = CPU_FTR_COMMON |
- CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_MAYBE_CAN_DOZE |
- CPU_FTR_USE_TB | CPU_FTR_L2CR | CPU_FTR_HPTE_TABLE |
- CPU_FTR_MAYBE_CAN_NAP,
- .cpu_user_features = COMMON_PPC,
+ .cpu_features = CPU_FTRS_740_NOTAU,
+ .cpu_user_features = COMMON_USER,
.icache_bsize = 32,
.dcache_bsize = 32,
.num_pmcs = 4,
@@ -202,11 +397,8 @@ struct cpu_spec cpu_specs[] = {
.pvr_mask = 0xfffffff0,
.pvr_value = 0x00080100,
.cpu_name = "750CX",
- .cpu_features = CPU_FTR_COMMON |
- CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_MAYBE_CAN_DOZE |
- CPU_FTR_USE_TB | CPU_FTR_L2CR | CPU_FTR_TAU |
- CPU_FTR_HPTE_TABLE | CPU_FTR_MAYBE_CAN_NAP,
- .cpu_user_features = COMMON_PPC,
+ .cpu_features = CPU_FTRS_750,
+ .cpu_user_features = COMMON_USER,
.icache_bsize = 32,
.dcache_bsize = 32,
.num_pmcs = 4,
@@ -216,11 +408,8 @@ struct cpu_spec cpu_specs[] = {
.pvr_mask = 0xfffffff0,
.pvr_value = 0x00082200,
.cpu_name = "750CX",
- .cpu_features = CPU_FTR_COMMON |
- CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_MAYBE_CAN_DOZE |
- CPU_FTR_USE_TB | CPU_FTR_L2CR | CPU_FTR_TAU |
- CPU_FTR_HPTE_TABLE | CPU_FTR_MAYBE_CAN_NAP,
- .cpu_user_features = COMMON_PPC,
+ .cpu_features = CPU_FTRS_750,
+ .cpu_user_features = COMMON_USER,
.icache_bsize = 32,
.dcache_bsize = 32,
.num_pmcs = 4,
@@ -230,11 +419,8 @@ struct cpu_spec cpu_specs[] = {
.pvr_mask = 0xfffffff0,
.pvr_value = 0x00082210,
.cpu_name = "750CXe",
- .cpu_features = CPU_FTR_COMMON |
- CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_MAYBE_CAN_DOZE |
- CPU_FTR_USE_TB | CPU_FTR_L2CR | CPU_FTR_TAU |
- CPU_FTR_HPTE_TABLE | CPU_FTR_MAYBE_CAN_NAP,
- .cpu_user_features = COMMON_PPC,
+ .cpu_features = CPU_FTRS_750,
+ .cpu_user_features = COMMON_USER,
.icache_bsize = 32,
.dcache_bsize = 32,
.num_pmcs = 4,
@@ -244,11 +430,8 @@ struct cpu_spec cpu_specs[] = {
.pvr_mask = 0xffffffff,
.pvr_value = 0x00083214,
.cpu_name = "750CXe",
- .cpu_features = CPU_FTR_COMMON |
- CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_MAYBE_CAN_DOZE |
- CPU_FTR_USE_TB | CPU_FTR_L2CR | CPU_FTR_TAU |
- CPU_FTR_HPTE_TABLE | CPU_FTR_MAYBE_CAN_NAP,
- .cpu_user_features = COMMON_PPC,
+ .cpu_features = CPU_FTRS_750,
+ .cpu_user_features = COMMON_USER,
.icache_bsize = 32,
.dcache_bsize = 32,
.num_pmcs = 4,
@@ -258,11 +441,8 @@ struct cpu_spec cpu_specs[] = {
.pvr_mask = 0xfffff000,
.pvr_value = 0x00083000,
.cpu_name = "745/755",
- .cpu_features = CPU_FTR_COMMON |
- CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_MAYBE_CAN_DOZE |
- CPU_FTR_USE_TB | CPU_FTR_L2CR | CPU_FTR_TAU |
- CPU_FTR_HPTE_TABLE | CPU_FTR_MAYBE_CAN_NAP,
- .cpu_user_features = COMMON_PPC,
+ .cpu_features = CPU_FTRS_750,
+ .cpu_user_features = COMMON_USER,
.icache_bsize = 32,
.dcache_bsize = 32,
.num_pmcs = 4,
@@ -272,12 +452,8 @@ struct cpu_spec cpu_specs[] = {
.pvr_mask = 0xffffff00,
.pvr_value = 0x70000100,
.cpu_name = "750FX",
- .cpu_features = CPU_FTR_COMMON |
- CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_MAYBE_CAN_DOZE |
- CPU_FTR_USE_TB | CPU_FTR_L2CR | CPU_FTR_TAU |
- CPU_FTR_HPTE_TABLE | CPU_FTR_MAYBE_CAN_NAP |
- CPU_FTR_DUAL_PLL_750FX | CPU_FTR_NO_DPM,
- .cpu_user_features = COMMON_PPC,
+ .cpu_features = CPU_FTRS_750FX1,
+ .cpu_user_features = COMMON_USER,
.icache_bsize = 32,
.dcache_bsize = 32,
.num_pmcs = 4,
@@ -287,12 +463,8 @@ struct cpu_spec cpu_specs[] = {
.pvr_mask = 0xffffffff,
.pvr_value = 0x70000200,
.cpu_name = "750FX",
- .cpu_features = CPU_FTR_COMMON |
- CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_MAYBE_CAN_DOZE |
- CPU_FTR_USE_TB | CPU_FTR_L2CR | CPU_FTR_TAU |
- CPU_FTR_HPTE_TABLE | CPU_FTR_MAYBE_CAN_NAP |
- CPU_FTR_NO_DPM,
- .cpu_user_features = COMMON_PPC,
+ .cpu_features = CPU_FTRS_750FX2,
+ .cpu_user_features = COMMON_USER,
.icache_bsize = 32,
.dcache_bsize = 32,
.num_pmcs = 4,
@@ -302,12 +474,8 @@ struct cpu_spec cpu_specs[] = {
.pvr_mask = 0xffff0000,
.pvr_value = 0x70000000,
.cpu_name = "750FX",
- .cpu_features = CPU_FTR_COMMON |
- CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_MAYBE_CAN_DOZE |
- CPU_FTR_USE_TB | CPU_FTR_L2CR | CPU_FTR_TAU |
- CPU_FTR_HPTE_TABLE | CPU_FTR_MAYBE_CAN_NAP |
- CPU_FTR_DUAL_PLL_750FX | CPU_FTR_HAS_HIGH_BATS,
- .cpu_user_features = COMMON_PPC,
+ .cpu_features = CPU_FTRS_750FX,
+ .cpu_user_features = COMMON_USER,
.icache_bsize = 32,
.dcache_bsize = 32,
.num_pmcs = 4,
@@ -317,12 +485,8 @@ struct cpu_spec cpu_specs[] = {
.pvr_mask = 0xffff0000,
.pvr_value = 0x70020000,
.cpu_name = "750GX",
- .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
- CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB |
- CPU_FTR_L2CR | CPU_FTR_TAU | CPU_FTR_HPTE_TABLE |
- CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_DUAL_PLL_750FX |
- CPU_FTR_HAS_HIGH_BATS,
- .cpu_user_features = COMMON_PPC,
+ .cpu_features = CPU_FTRS_750GX,
+ .cpu_user_features = COMMON_USER,
.icache_bsize = 32,
.dcache_bsize = 32,
.num_pmcs = 4,
@@ -332,11 +496,8 @@ struct cpu_spec cpu_specs[] = {
.pvr_mask = 0xffff0000,
.pvr_value = 0x00080000,
.cpu_name = "740/750",
- .cpu_features = CPU_FTR_COMMON |
- CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_MAYBE_CAN_DOZE |
- CPU_FTR_USE_TB | CPU_FTR_L2CR | CPU_FTR_TAU |
- CPU_FTR_HPTE_TABLE | CPU_FTR_MAYBE_CAN_NAP,
- .cpu_user_features = COMMON_PPC,
+ .cpu_features = CPU_FTRS_740,
+ .cpu_user_features = COMMON_USER,
.icache_bsize = 32,
.dcache_bsize = 32,
.num_pmcs = 4,
@@ -346,11 +507,8 @@ struct cpu_spec cpu_specs[] = {
.pvr_mask = 0xffffffff,
.pvr_value = 0x000c1101,
.cpu_name = "7400 (1.1)",
- .cpu_features = CPU_FTR_COMMON |
- CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_MAYBE_CAN_DOZE |
- CPU_FTR_USE_TB | CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP |
- CPU_FTR_HPTE_TABLE | CPU_FTR_MAYBE_CAN_NAP,
- .cpu_user_features = COMMON_PPC | PPC_FEATURE_ALTIVEC_COMP,
+ .cpu_features = CPU_FTRS_7400_NOTAU,
+ .cpu_user_features = COMMON_USER | PPC_FEATURE_HAS_ALTIVEC_COMP,
.icache_bsize = 32,
.dcache_bsize = 32,
.num_pmcs = 4,
@@ -360,12 +518,8 @@ struct cpu_spec cpu_specs[] = {
.pvr_mask = 0xffff0000,
.pvr_value = 0x000c0000,
.cpu_name = "7400",
- .cpu_features = CPU_FTR_COMMON |
- CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_MAYBE_CAN_DOZE |
- CPU_FTR_USE_TB | CPU_FTR_L2CR | CPU_FTR_TAU |
- CPU_FTR_ALTIVEC_COMP | CPU_FTR_HPTE_TABLE |
- CPU_FTR_MAYBE_CAN_NAP,
- .cpu_user_features = COMMON_PPC | PPC_FEATURE_ALTIVEC_COMP,
+ .cpu_features = CPU_FTRS_7400,
+ .cpu_user_features = COMMON_USER | PPC_FEATURE_HAS_ALTIVEC_COMP,
.icache_bsize = 32,
.dcache_bsize = 32,
.num_pmcs = 4,
@@ -375,12 +529,8 @@ struct cpu_spec cpu_specs[] = {
.pvr_mask = 0xffff0000,
.pvr_value = 0x800c0000,
.cpu_name = "7410",
- .cpu_features = CPU_FTR_COMMON |
- CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_MAYBE_CAN_DOZE |
- CPU_FTR_USE_TB | CPU_FTR_L2CR | CPU_FTR_TAU |
- CPU_FTR_ALTIVEC_COMP | CPU_FTR_HPTE_TABLE |
- CPU_FTR_MAYBE_CAN_NAP,
- .cpu_user_features = COMMON_PPC | PPC_FEATURE_ALTIVEC_COMP,
+ .cpu_features = CPU_FTRS_7400,
+ .cpu_user_features = COMMON_USER | PPC_FEATURE_HAS_ALTIVEC_COMP,
.icache_bsize = 32,
.dcache_bsize = 32,
.num_pmcs = 4,
@@ -390,12 +540,8 @@ struct cpu_spec cpu_specs[] = {
.pvr_mask = 0xffffffff,
.pvr_value = 0x80000200,
.cpu_name = "7450",
- .cpu_features = CPU_FTR_COMMON |
- CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB |
- CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | CPU_FTR_L3CR |
- CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 |
- CPU_FTR_NEED_COHERENT,
- .cpu_user_features = COMMON_PPC | PPC_FEATURE_ALTIVEC_COMP,
+ .cpu_features = CPU_FTRS_7450_20,
+ .cpu_user_features = COMMON_USER | PPC_FEATURE_HAS_ALTIVEC_COMP,
.icache_bsize = 32,
.dcache_bsize = 32,
.num_pmcs = 6,
@@ -405,14 +551,8 @@ struct cpu_spec cpu_specs[] = {
.pvr_mask = 0xffffffff,
.pvr_value = 0x80000201,
.cpu_name = "7450",
- .cpu_features = CPU_FTR_COMMON |
- CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB |
- CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR |
- CPU_FTR_ALTIVEC_COMP | CPU_FTR_L3CR |
- CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 |
- CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_L3_DISABLE_NAP |
- CPU_FTR_NEED_COHERENT,
- .cpu_user_features = COMMON_PPC | PPC_FEATURE_ALTIVEC_COMP,
+ .cpu_features = CPU_FTRS_7450_21,
+ .cpu_user_features = COMMON_USER | PPC_FEATURE_HAS_ALTIVEC_COMP,
.icache_bsize = 32,
.dcache_bsize = 32,
.num_pmcs = 6,
@@ -422,13 +562,8 @@ struct cpu_spec cpu_specs[] = {
.pvr_mask = 0xffff0000,
.pvr_value = 0x80000000,
.cpu_name = "7450",
- .cpu_features = CPU_FTR_COMMON |
- CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB |
- CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR |
- CPU_FTR_ALTIVEC_COMP | CPU_FTR_L3CR |
- CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 |
- CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_NEED_COHERENT,
- .cpu_user_features = COMMON_PPC | PPC_FEATURE_ALTIVEC_COMP,
+ .cpu_features = CPU_FTRS_7450_23,
+ .cpu_user_features = COMMON_USER | PPC_FEATURE_HAS_ALTIVEC_COMP,
.icache_bsize = 32,
.dcache_bsize = 32,
.num_pmcs = 6,
@@ -438,12 +573,8 @@ struct cpu_spec cpu_specs[] = {
.pvr_mask = 0xffffff00,
.pvr_value = 0x80010100,
.cpu_name = "7455",
- .cpu_features = CPU_FTR_COMMON |
- CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB |
- CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | CPU_FTR_L3CR |
- CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 |
- CPU_FTR_HAS_HIGH_BATS | CPU_FTR_NEED_COHERENT,
- .cpu_user_features = COMMON_PPC | PPC_FEATURE_ALTIVEC_COMP,
+ .cpu_features = CPU_FTRS_7455_1,
+ .cpu_user_features = COMMON_USER | PPC_FEATURE_HAS_ALTIVEC_COMP,
.icache_bsize = 32,
.dcache_bsize = 32,
.num_pmcs = 6,
@@ -453,14 +584,8 @@ struct cpu_spec cpu_specs[] = {
.pvr_mask = 0xffffffff,
.pvr_value = 0x80010200,
.cpu_name = "7455",
- .cpu_features = CPU_FTR_COMMON |
- CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB |
- CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR |
- CPU_FTR_ALTIVEC_COMP | CPU_FTR_L3CR |
- CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 |
- CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_L3_DISABLE_NAP |
- CPU_FTR_NEED_COHERENT | CPU_FTR_HAS_HIGH_BATS,
- .cpu_user_features = COMMON_PPC | PPC_FEATURE_ALTIVEC_COMP,
+ .cpu_features = CPU_FTRS_7455_20,
+ .cpu_user_features = COMMON_USER | PPC_FEATURE_HAS_ALTIVEC_COMP,
.icache_bsize = 32,
.dcache_bsize = 32,
.num_pmcs = 6,
@@ -470,14 +595,8 @@ struct cpu_spec cpu_specs[] = {
.pvr_mask = 0xffff0000,
.pvr_value = 0x80010000,
.cpu_name = "7455",
- .cpu_features = CPU_FTR_COMMON |
- CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB |
- CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR |
- CPU_FTR_ALTIVEC_COMP | CPU_FTR_L3CR |
- CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 |
- CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_HAS_HIGH_BATS |
- CPU_FTR_NEED_COHERENT,
- .cpu_user_features = COMMON_PPC | PPC_FEATURE_ALTIVEC_COMP,
+ .cpu_features = CPU_FTRS_7455,
+ .cpu_user_features = COMMON_USER | PPC_FEATURE_HAS_ALTIVEC_COMP,
.icache_bsize = 32,
.dcache_bsize = 32,
.num_pmcs = 6,
@@ -487,14 +606,8 @@ struct cpu_spec cpu_specs[] = {
.pvr_mask = 0xffffffff,
.pvr_value = 0x80020100,
.cpu_name = "7447/7457",
- .cpu_features = CPU_FTR_COMMON |
- CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB |
- CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR |
- CPU_FTR_ALTIVEC_COMP | CPU_FTR_L3CR |
- CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 |
- CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_HAS_HIGH_BATS |
- CPU_FTR_NEED_COHERENT | CPU_FTR_NO_BTIC,
- .cpu_user_features = COMMON_PPC | PPC_FEATURE_ALTIVEC_COMP,
+ .cpu_features = CPU_FTRS_7447_10,
+ .cpu_user_features = COMMON_USER | PPC_FEATURE_HAS_ALTIVEC_COMP,
.icache_bsize = 32,
.dcache_bsize = 32,
.num_pmcs = 6,
@@ -504,14 +617,8 @@ struct cpu_spec cpu_specs[] = {
.pvr_mask = 0xffffffff,
.pvr_value = 0x80020101,
.cpu_name = "7447/7457",
- .cpu_features = CPU_FTR_COMMON |
- CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB |
- CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR |
- CPU_FTR_ALTIVEC_COMP | CPU_FTR_L3CR |
- CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 |
- CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_HAS_HIGH_BATS |
- CPU_FTR_NEED_COHERENT | CPU_FTR_NO_BTIC,
- .cpu_user_features = COMMON_PPC | PPC_FEATURE_ALTIVEC_COMP,
+ .cpu_features = CPU_FTRS_7447_10,
+ .cpu_user_features = COMMON_USER | PPC_FEATURE_HAS_ALTIVEC_COMP,
.icache_bsize = 32,
.dcache_bsize = 32,
.num_pmcs = 6,
@@ -521,14 +628,8 @@ struct cpu_spec cpu_specs[] = {
.pvr_mask = 0xffff0000,
.pvr_value = 0x80020000,
.cpu_name = "7447/7457",
- .cpu_features = CPU_FTR_COMMON |
- CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB |
- CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR |
- CPU_FTR_ALTIVEC_COMP | CPU_FTR_L3CR |
- CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 |
- CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_HAS_HIGH_BATS |
- CPU_FTR_NEED_COHERENT,
- .cpu_user_features = COMMON_PPC | PPC_FEATURE_ALTIVEC_COMP,
+ .cpu_features = CPU_FTRS_7447,
+ .cpu_user_features = COMMON_USER | PPC_FEATURE_HAS_ALTIVEC_COMP,
.icache_bsize = 32,
.dcache_bsize = 32,
.num_pmcs = 6,
@@ -538,13 +639,8 @@ struct cpu_spec cpu_specs[] = {
.pvr_mask = 0xffff0000,
.pvr_value = 0x80030000,
.cpu_name = "7447A",
- .cpu_features = CPU_FTR_COMMON |
- CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB |
- CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR |
- CPU_FTR_ALTIVEC_COMP | CPU_FTR_HPTE_TABLE |
- CPU_FTR_SPEC7450 | CPU_FTR_NAP_DISABLE_L2_PR |
- CPU_FTR_HAS_HIGH_BATS | CPU_FTR_NEED_COHERENT,
- .cpu_user_features = COMMON_PPC | PPC_FEATURE_ALTIVEC_COMP,
+ .cpu_features = CPU_FTRS_7447A,
+ .cpu_user_features = COMMON_USER | PPC_FEATURE_HAS_ALTIVEC_COMP,
.icache_bsize = 32,
.dcache_bsize = 32,
.num_pmcs = 6,
@@ -554,13 +650,8 @@ struct cpu_spec cpu_specs[] = {
.pvr_mask = 0xffff0000,
.pvr_value = 0x80040000,
.cpu_name = "7448",
- .cpu_features = CPU_FTR_COMMON |
- CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB |
- CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR |
- CPU_FTR_ALTIVEC_COMP | CPU_FTR_HPTE_TABLE |
- CPU_FTR_SPEC7450 | CPU_FTR_NAP_DISABLE_L2_PR |
- CPU_FTR_HAS_HIGH_BATS | CPU_FTR_NEED_COHERENT,
- .cpu_user_features = COMMON_PPC | PPC_FEATURE_ALTIVEC_COMP,
+ .cpu_features = CPU_FTRS_7447A,
+ .cpu_user_features = COMMON_USER | PPC_FEATURE_HAS_ALTIVEC_COMP,
.icache_bsize = 32,
.dcache_bsize = 32,
.num_pmcs = 6,
@@ -570,10 +661,8 @@ struct cpu_spec cpu_specs[] = {
.pvr_mask = 0x7fff0000,
.pvr_value = 0x00810000,
.cpu_name = "82xx",
- .cpu_features = CPU_FTR_COMMON |
- CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_MAYBE_CAN_DOZE |
- CPU_FTR_USE_TB,
- .cpu_user_features = COMMON_PPC,
+ .cpu_features = CPU_FTRS_82XX,
+ .cpu_user_features = COMMON_USER,
.icache_bsize = 32,
.dcache_bsize = 32,
.cpu_setup = __setup_cpu_603
@@ -582,10 +671,8 @@ struct cpu_spec cpu_specs[] = {
.pvr_mask = 0x7fff0000,
.pvr_value = 0x00820000,
.cpu_name = "G2_LE",
- .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
- CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB |
- CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_HAS_HIGH_BATS,
- .cpu_user_features = COMMON_PPC,
+ .cpu_features = CPU_FTRS_G2_LE,
+ .cpu_user_features = COMMON_USER,
.icache_bsize = 32,
.dcache_bsize = 32,
.cpu_setup = __setup_cpu_603
@@ -594,10 +681,8 @@ struct cpu_spec cpu_specs[] = {
.pvr_mask = 0x7fff0000,
.pvr_value = 0x00830000,
.cpu_name = "e300",
- .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
- CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB |
- CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_HAS_HIGH_BATS,
- .cpu_user_features = COMMON_PPC,
+ .cpu_features = CPU_FTRS_E300,
+ .cpu_user_features = COMMON_USER,
.icache_bsize = 32,
.dcache_bsize = 32,
.cpu_setup = __setup_cpu_603
@@ -606,114 +691,12 @@ struct cpu_spec cpu_specs[] = {
.pvr_mask = 0x00000000,
.pvr_value = 0x00000000,
.cpu_name = "(generic PPC)",
- .cpu_features = CPU_FTR_COMMON |
- CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB |
- CPU_FTR_HPTE_TABLE,
- .cpu_user_features = COMMON_PPC,
+ .cpu_features = CPU_FTRS_CLASSIC32,
+ .cpu_user_features = COMMON_USER,
.icache_bsize = 32,
.dcache_bsize = 32,
- .cpu_setup = __setup_cpu_generic
},
#endif /* CLASSIC_PPC */
-#ifdef CONFIG_PPC64BRIDGE
- { /* Power3 */
- .pvr_mask = 0xffff0000,
- .pvr_value = 0x00400000,
- .cpu_name = "Power3 (630)",
- .cpu_features = CPU_FTR_COMMON |
- CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB |
- CPU_FTR_HPTE_TABLE,
- .cpu_user_features = COMMON_PPC | PPC_FEATURE_64,
- .icache_bsize = 128,
- .dcache_bsize = 128,
- .num_pmcs = 8,
- .cpu_setup = __setup_cpu_power3
- },
- { /* Power3+ */
- .pvr_mask = 0xffff0000,
- .pvr_value = 0x00410000,
- .cpu_name = "Power3 (630+)",
- .cpu_features = CPU_FTR_COMMON |
- CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB |
- CPU_FTR_HPTE_TABLE,
- .cpu_user_features = COMMON_PPC | PPC_FEATURE_64,
- .icache_bsize = 128,
- .dcache_bsize = 128,
- .num_pmcs = 8,
- .cpu_setup = __setup_cpu_power3
- },
- { /* I-star */
- .pvr_mask = 0xffff0000,
- .pvr_value = 0x00360000,
- .cpu_name = "I-star",
- .cpu_features = CPU_FTR_COMMON |
- CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB |
- CPU_FTR_HPTE_TABLE,
- .cpu_user_features = COMMON_PPC | PPC_FEATURE_64,
- .icache_bsize = 128,
- .dcache_bsize = 128,
- .num_pmcs = 8,
- .cpu_setup = __setup_cpu_power3
- },
- { /* S-star */
- .pvr_mask = 0xffff0000,
- .pvr_value = 0x00370000,
- .cpu_name = "S-star",
- .cpu_features = CPU_FTR_COMMON |
- CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB |
- CPU_FTR_HPTE_TABLE,
- .cpu_user_features = COMMON_PPC | PPC_FEATURE_64,
- .icache_bsize = 128,
- .dcache_bsize = 128,
- .num_pmcs = 8,
- .cpu_setup = __setup_cpu_power3
- },
-#endif /* CONFIG_PPC64BRIDGE */
-#ifdef CONFIG_POWER4
- { /* Power4 */
- .pvr_mask = 0xffff0000,
- .pvr_value = 0x00350000,
- .cpu_name = "Power4",
- .cpu_features = CPU_FTR_COMMON |
- CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB |
- CPU_FTR_HPTE_TABLE,
- .cpu_user_features = COMMON_PPC | PPC_FEATURE_64,
- .icache_bsize = 128,
- .dcache_bsize = 128,
- .num_pmcs = 8,
- .cpu_setup = __setup_cpu_power4
- },
- { /* PPC970 */
- .pvr_mask = 0xffff0000,
- .pvr_value = 0x00390000,
- .cpu_name = "PPC970",
- .cpu_features = CPU_FTR_COMMON |
- CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB |
- CPU_FTR_HPTE_TABLE |
- CPU_FTR_ALTIVEC_COMP | CPU_FTR_MAYBE_CAN_NAP,
- .cpu_user_features = COMMON_PPC | PPC_FEATURE_64 |
- PPC_FEATURE_ALTIVEC_COMP,
- .icache_bsize = 128,
- .dcache_bsize = 128,
- .num_pmcs = 8,
- .cpu_setup = __setup_cpu_ppc970
- },
- { /* PPC970FX */
- .pvr_mask = 0xffff0000,
- .pvr_value = 0x003c0000,
- .cpu_name = "PPC970FX",
- .cpu_features = CPU_FTR_COMMON |
- CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB |
- CPU_FTR_HPTE_TABLE |
- CPU_FTR_ALTIVEC_COMP | CPU_FTR_MAYBE_CAN_NAP,
- .cpu_user_features = COMMON_PPC | PPC_FEATURE_64 |
- PPC_FEATURE_ALTIVEC_COMP,
- .icache_bsize = 128,
- .dcache_bsize = 128,
- .num_pmcs = 8,
- .cpu_setup = __setup_cpu_ppc970
- },
-#endif /* CONFIG_POWER4 */
#ifdef CONFIG_8xx
{ /* 8xx */
.pvr_mask = 0xffff0000,
@@ -721,8 +704,7 @@ struct cpu_spec cpu_specs[] = {
.cpu_name = "8xx",
/* CPU_FTR_MAYBE_CAN_DOZE is possible,
* if the 8xx code is there.... */
- .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
- CPU_FTR_USE_TB,
+ .cpu_features = CPU_FTRS_8XX,
.cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU,
.icache_bsize = 16,
.dcache_bsize = 16,
@@ -733,8 +715,7 @@ struct cpu_spec cpu_specs[] = {
.pvr_mask = 0xffffff00,
.pvr_value = 0x00200200,
.cpu_name = "403GC",
- .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
- CPU_FTR_USE_TB,
+ .cpu_features = CPU_FTRS_40X,
.cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU,
.icache_bsize = 16,
.dcache_bsize = 16,
@@ -743,8 +724,7 @@ struct cpu_spec cpu_specs[] = {
.pvr_mask = 0xffffff00,
.pvr_value = 0x00201400,
.cpu_name = "403GCX",
- .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
- CPU_FTR_USE_TB,
+ .cpu_features = CPU_FTRS_40X,
.cpu_user_features = PPC_FEATURE_32 |
PPC_FEATURE_HAS_MMU | PPC_FEATURE_NO_TB,
.icache_bsize = 16,
@@ -754,8 +734,7 @@ struct cpu_spec cpu_specs[] = {
.pvr_mask = 0xffff0000,
.pvr_value = 0x00200000,
.cpu_name = "403G ??",
- .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
- CPU_FTR_USE_TB,
+ .cpu_features = CPU_FTRS_40X,
.cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU,
.icache_bsize = 16,
.dcache_bsize = 16,
@@ -764,8 +743,7 @@ struct cpu_spec cpu_specs[] = {
.pvr_mask = 0xffff0000,
.pvr_value = 0x40110000,
.cpu_name = "405GP",
- .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
- CPU_FTR_USE_TB,
+ .cpu_features = CPU_FTRS_40X,
.cpu_user_features = PPC_FEATURE_32 |
PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
.icache_bsize = 32,
@@ -775,8 +753,7 @@ struct cpu_spec cpu_specs[] = {
.pvr_mask = 0xffff0000,
.pvr_value = 0x40130000,
.cpu_name = "STB03xxx",
- .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
- CPU_FTR_USE_TB,
+ .cpu_features = CPU_FTRS_40X,
.cpu_user_features = PPC_FEATURE_32 |
PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
.icache_bsize = 32,
@@ -786,8 +763,7 @@ struct cpu_spec cpu_specs[] = {
.pvr_mask = 0xffff0000,
.pvr_value = 0x41810000,
.cpu_name = "STB04xxx",
- .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
- CPU_FTR_USE_TB,
+ .cpu_features = CPU_FTRS_40X,
.cpu_user_features = PPC_FEATURE_32 |
PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
.icache_bsize = 32,
@@ -797,8 +773,7 @@ struct cpu_spec cpu_specs[] = {
.pvr_mask = 0xffff0000,
.pvr_value = 0x41610000,
.cpu_name = "NP405L",
- .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
- CPU_FTR_USE_TB,
+ .cpu_features = CPU_FTRS_40X,
.cpu_user_features = PPC_FEATURE_32 |
PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
.icache_bsize = 32,
@@ -808,8 +783,7 @@ struct cpu_spec cpu_specs[] = {
.pvr_mask = 0xffff0000,
.pvr_value = 0x40B10000,
.cpu_name = "NP4GS3",
- .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
- CPU_FTR_USE_TB,
+ .cpu_features = CPU_FTRS_40X,
.cpu_user_features = PPC_FEATURE_32 |
PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
.icache_bsize = 32,
@@ -819,8 +793,7 @@ struct cpu_spec cpu_specs[] = {
.pvr_mask = 0xffff0000,
.pvr_value = 0x41410000,
.cpu_name = "NP405H",
- .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
- CPU_FTR_USE_TB,
+ .cpu_features = CPU_FTRS_40X,
.cpu_user_features = PPC_FEATURE_32 |
PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
.icache_bsize = 32,
@@ -830,8 +803,7 @@ struct cpu_spec cpu_specs[] = {
.pvr_mask = 0xffff0000,
.pvr_value = 0x50910000,
.cpu_name = "405GPr",
- .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
- CPU_FTR_USE_TB,
+ .cpu_features = CPU_FTRS_40X,
.cpu_user_features = PPC_FEATURE_32 |
PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
.icache_bsize = 32,
@@ -841,8 +813,7 @@ struct cpu_spec cpu_specs[] = {
.pvr_mask = 0xffff0000,
.pvr_value = 0x51510000,
.cpu_name = "STBx25xx",
- .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
- CPU_FTR_USE_TB,
+ .cpu_features = CPU_FTRS_40X,
.cpu_user_features = PPC_FEATURE_32 |
PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
.icache_bsize = 32,
@@ -852,8 +823,7 @@ struct cpu_spec cpu_specs[] = {
.pvr_mask = 0xffff0000,
.pvr_value = 0x41F10000,
.cpu_name = "405LP",
- .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
- CPU_FTR_USE_TB,
+ .cpu_features = CPU_FTRS_40X,
.cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU,
.icache_bsize = 32,
.dcache_bsize = 32,
@@ -862,8 +832,7 @@ struct cpu_spec cpu_specs[] = {
.pvr_mask = 0xffff0000,
.pvr_value = 0x20010000,
.cpu_name = "Virtex-II Pro",
- .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
- CPU_FTR_USE_TB,
+ .cpu_features = CPU_FTRS_40X,
.cpu_user_features = PPC_FEATURE_32 |
PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
.icache_bsize = 32,
@@ -873,8 +842,7 @@ struct cpu_spec cpu_specs[] = {
.pvr_mask = 0xffff0000,
.pvr_value = 0x51210000,
.cpu_name = "405EP",
- .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
- CPU_FTR_USE_TB,
+ .cpu_features = CPU_FTRS_40X,
.cpu_user_features = PPC_FEATURE_32 |
PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
.icache_bsize = 32,
@@ -887,9 +855,8 @@ struct cpu_spec cpu_specs[] = {
.pvr_mask = 0xf0000fff,
.pvr_value = 0x40000850,
.cpu_name = "440EP Rev. A",
- .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
- CPU_FTR_USE_TB,
- .cpu_user_features = COMMON_PPC, /* 440EP has an FPU */
+ .cpu_features = CPU_FTRS_44X,
+ .cpu_user_features = COMMON_USER, /* 440EP has an FPU */
.icache_bsize = 32,
.dcache_bsize = 32,
},
@@ -897,28 +864,25 @@ struct cpu_spec cpu_specs[] = {
.pvr_mask = 0xf0000fff,
.pvr_value = 0x400008d3,
.cpu_name = "440EP Rev. B",
- .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
- CPU_FTR_USE_TB,
- .cpu_user_features = COMMON_PPC, /* 440EP has an FPU */
+ .cpu_features = CPU_FTRS_44X,
+ .cpu_user_features = COMMON_USER, /* 440EP has an FPU */
.icache_bsize = 32,
.dcache_bsize = 32,
},
- { /* 440GP Rev. B */
+ { /* 440GP Rev. B */
.pvr_mask = 0xf0000fff,
.pvr_value = 0x40000440,
.cpu_name = "440GP Rev. B",
- .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
- CPU_FTR_USE_TB,
+ .cpu_features = CPU_FTRS_44X,
.cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU,
.icache_bsize = 32,
.dcache_bsize = 32,
},
- { /* 440GP Rev. C */
+ { /* 440GP Rev. C */
.pvr_mask = 0xf0000fff,
.pvr_value = 0x40000481,
.cpu_name = "440GP Rev. C",
- .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
- CPU_FTR_USE_TB,
+ .cpu_features = CPU_FTRS_44X,
.cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU,
.icache_bsize = 32,
.dcache_bsize = 32,
@@ -927,8 +891,7 @@ struct cpu_spec cpu_specs[] = {
.pvr_mask = 0xf0000fff,
.pvr_value = 0x50000850,
.cpu_name = "440GX Rev. A",
- .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
- CPU_FTR_USE_TB,
+ .cpu_features = CPU_FTRS_44X,
.cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU,
.icache_bsize = 32,
.dcache_bsize = 32,
@@ -937,8 +900,7 @@ struct cpu_spec cpu_specs[] = {
.pvr_mask = 0xf0000fff,
.pvr_value = 0x50000851,
.cpu_name = "440GX Rev. B",
- .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
- CPU_FTR_USE_TB,
+ .cpu_features = CPU_FTRS_44X,
.cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU,
.icache_bsize = 32,
.dcache_bsize = 32,
@@ -947,8 +909,7 @@ struct cpu_spec cpu_specs[] = {
.pvr_mask = 0xf0000fff,
.pvr_value = 0x50000892,
.cpu_name = "440GX Rev. C",
- .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
- CPU_FTR_USE_TB,
+ .cpu_features = CPU_FTRS_44X,
.cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU,
.icache_bsize = 32,
.dcache_bsize = 32,
@@ -957,8 +918,7 @@ struct cpu_spec cpu_specs[] = {
.pvr_mask = 0xf0000fff,
.pvr_value = 0x50000894,
.cpu_name = "440GX Rev. F",
- .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
- CPU_FTR_USE_TB,
+ .cpu_features = CPU_FTRS_44X,
.cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU,
.icache_bsize = 32,
.dcache_bsize = 32,
@@ -967,6 +927,15 @@ struct cpu_spec cpu_specs[] = {
.pvr_mask = 0xff000fff,
.pvr_value = 0x53000891,
.cpu_name = "440SP Rev. A",
+ .cpu_features = CPU_FTRS_44X,
+ .cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU,
+ .icache_bsize = 32,
+ .dcache_bsize = 32,
+ },
+ { /* 440SPe Rev. A */
+ .pvr_mask = 0xff000fff,
+ .pvr_value = 0x53000890,
+ .cpu_name = "440SPe Rev. A",
.cpu_features = CPU_FTR_SPLIT_ID_CACHE |
CPU_FTR_USE_TB,
.cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU,
@@ -975,36 +944,35 @@ struct cpu_spec cpu_specs[] = {
},
#endif /* CONFIG_44x */
#ifdef CONFIG_FSL_BOOKE
- { /* e200z5 */
+ { /* e200z5 */
.pvr_mask = 0xfff00000,
.pvr_value = 0x81000000,
.cpu_name = "e200z5",
/* xxx - galak: add CPU_FTR_MAYBE_CAN_DOZE */
- .cpu_features = CPU_FTR_USE_TB,
+ .cpu_features = CPU_FTRS_E200,
.cpu_user_features = PPC_FEATURE_32 |
PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_EFP_SINGLE |
PPC_FEATURE_UNIFIED_CACHE,
.dcache_bsize = 32,
},
- { /* e200z6 */
+ { /* e200z6 */
.pvr_mask = 0xfff00000,
.pvr_value = 0x81100000,
.cpu_name = "e200z6",
/* xxx - galak: add CPU_FTR_MAYBE_CAN_DOZE */
- .cpu_features = CPU_FTR_USE_TB,
+ .cpu_features = CPU_FTRS_E200,
.cpu_user_features = PPC_FEATURE_32 |
PPC_FEATURE_HAS_MMU | PPC_FEATURE_SPE_COMP |
PPC_FEATURE_HAS_EFP_SINGLE |
PPC_FEATURE_UNIFIED_CACHE,
.dcache_bsize = 32,
},
- { /* e500 */
+ { /* e500 */
.pvr_mask = 0xffff0000,
.pvr_value = 0x80200000,
.cpu_name = "e500",
/* xxx - galak: add CPU_FTR_MAYBE_CAN_DOZE */
- .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
- CPU_FTR_USE_TB,
+ .cpu_features = CPU_FTRS_E500,
.cpu_user_features = PPC_FEATURE_32 |
PPC_FEATURE_HAS_MMU | PPC_FEATURE_SPE_COMP |
PPC_FEATURE_HAS_EFP_SINGLE,
@@ -1012,13 +980,12 @@ struct cpu_spec cpu_specs[] = {
.dcache_bsize = 32,
.num_pmcs = 4,
},
- { /* e500v2 */
+ { /* e500v2 */
.pvr_mask = 0xffff0000,
.pvr_value = 0x80210000,
.cpu_name = "e500v2",
/* xxx - galak: add CPU_FTR_MAYBE_CAN_DOZE */
- .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
- CPU_FTR_USE_TB | CPU_FTR_BIG_PHYS,
+ .cpu_features = CPU_FTRS_E500_2,
.cpu_user_features = PPC_FEATURE_32 |
PPC_FEATURE_HAS_MMU | PPC_FEATURE_SPE_COMP |
PPC_FEATURE_HAS_EFP_SINGLE | PPC_FEATURE_HAS_EFP_DOUBLE,
@@ -1032,10 +999,11 @@ struct cpu_spec cpu_specs[] = {
.pvr_mask = 0x00000000,
.pvr_value = 0x00000000,
.cpu_name = "(generic PPC)",
- .cpu_features = CPU_FTR_COMMON,
+ .cpu_features = CPU_FTRS_GENERIC_32,
.cpu_user_features = PPC_FEATURE_32,
.icache_bsize = 32,
.dcache_bsize = 32,
}
#endif /* !CLASSIC_PPC */
+#endif /* CONFIG_PPC32 */
};
diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S
new file mode 100644
index 000000000000..2e99ae41723c
--- /dev/null
+++ b/arch/powerpc/kernel/entry_32.S
@@ -0,0 +1,1000 @@
+/*
+ * PowerPC version
+ * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
+ * Rewritten by Cort Dougan (cort@fsmlabs.com) for PReP
+ * Copyright (C) 1996 Cort Dougan <cort@fsmlabs.com>
+ * Adapted for Power Macintosh by Paul Mackerras.
+ * Low-level exception handlers and MMU support
+ * rewritten by Paul Mackerras.
+ * Copyright (C) 1996 Paul Mackerras.
+ * MPC8xx modifications Copyright (C) 1997 Dan Malek (dmalek@jlc.net).
+ *
+ * This file contains the system call entry code, context switch
+ * code, and exception/interrupt return code for PowerPC.
+ *
+ * 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/config.h>
+#include <linux/errno.h>
+#include <linux/sys.h>
+#include <linux/threads.h>
+#include <asm/reg.h>
+#include <asm/page.h>
+#include <asm/mmu.h>
+#include <asm/cputable.h>
+#include <asm/thread_info.h>
+#include <asm/ppc_asm.h>
+#include <asm/asm-offsets.h>
+#include <asm/unistd.h>
+
+#undef SHOW_SYSCALLS
+#undef SHOW_SYSCALLS_TASK
+
+/*
+ * MSR_KERNEL is > 0x10000 on 4xx/Book-E since it include MSR_CE.
+ */
+#if MSR_KERNEL >= 0x10000
+#define LOAD_MSR_KERNEL(r, x) lis r,(x)@h; ori r,r,(x)@l
+#else
+#define LOAD_MSR_KERNEL(r, x) li r,(x)
+#endif
+
+#ifdef CONFIG_BOOKE
+#include "head_booke.h"
+#define TRANSFER_TO_HANDLER_EXC_LEVEL(exc_level) \
+ mtspr exc_level##_SPRG,r8; \
+ BOOKE_LOAD_EXC_LEVEL_STACK(exc_level); \
+ lwz r0,GPR10-INT_FRAME_SIZE(r8); \
+ stw r0,GPR10(r11); \
+ lwz r0,GPR11-INT_FRAME_SIZE(r8); \
+ stw r0,GPR11(r11); \
+ mfspr r8,exc_level##_SPRG
+
+ .globl mcheck_transfer_to_handler
+mcheck_transfer_to_handler:
+ TRANSFER_TO_HANDLER_EXC_LEVEL(MCHECK)
+ b transfer_to_handler_full
+
+ .globl debug_transfer_to_handler
+debug_transfer_to_handler:
+ TRANSFER_TO_HANDLER_EXC_LEVEL(DEBUG)
+ b transfer_to_handler_full
+
+ .globl crit_transfer_to_handler
+crit_transfer_to_handler:
+ TRANSFER_TO_HANDLER_EXC_LEVEL(CRIT)
+ /* fall through */
+#endif
+
+#ifdef CONFIG_40x
+ .globl crit_transfer_to_handler
+crit_transfer_to_handler:
+ lwz r0,crit_r10@l(0)
+ stw r0,GPR10(r11)
+ lwz r0,crit_r11@l(0)
+ stw r0,GPR11(r11)
+ /* fall through */
+#endif
+
+/*
+ * This code finishes saving the registers to the exception frame
+ * and jumps to the appropriate handler for the exception, turning
+ * on address translation.
+ * Note that we rely on the caller having set cr0.eq iff the exception
+ * occurred in kernel mode (i.e. MSR:PR = 0).
+ */
+ .globl transfer_to_handler_full
+transfer_to_handler_full:
+ SAVE_NVGPRS(r11)
+ /* fall through */
+
+ .globl transfer_to_handler
+transfer_to_handler:
+ stw r2,GPR2(r11)
+ stw r12,_NIP(r11)
+ stw r9,_MSR(r11)
+ andi. r2,r9,MSR_PR
+ mfctr r12
+ mfspr r2,SPRN_XER
+ stw r12,_CTR(r11)
+ stw r2,_XER(r11)
+ mfspr r12,SPRN_SPRG3
+ addi r2,r12,-THREAD
+ tovirt(r2,r2) /* set r2 to current */
+ beq 2f /* if from user, fix up THREAD.regs */
+ addi r11,r1,STACK_FRAME_OVERHEAD
+ stw r11,PT_REGS(r12)
+#if defined(CONFIG_40x) || defined(CONFIG_BOOKE)
+ /* Check to see if the dbcr0 register is set up to debug. Use the
+ single-step bit to do this. */
+ lwz r12,THREAD_DBCR0(r12)
+ andis. r12,r12,DBCR0_IC@h
+ beq+ 3f
+ /* From user and task is ptraced - load up global dbcr0 */
+ li r12,-1 /* clear all pending debug events */
+ mtspr SPRN_DBSR,r12
+ lis r11,global_dbcr0@ha
+ tophys(r11,r11)
+ addi r11,r11,global_dbcr0@l
+ lwz r12,0(r11)
+ mtspr SPRN_DBCR0,r12
+ lwz r12,4(r11)
+ addi r12,r12,-1
+ stw r12,4(r11)
+#endif
+ b 3f
+2: /* if from kernel, check interrupted DOZE/NAP mode and
+ * check for stack overflow
+ */
+#ifdef CONFIG_6xx
+ mfspr r11,SPRN_HID0
+ mtcr r11
+BEGIN_FTR_SECTION
+ bt- 8,power_save_6xx_restore /* Check DOZE */
+END_FTR_SECTION_IFSET(CPU_FTR_CAN_DOZE)
+BEGIN_FTR_SECTION
+ bt- 9,power_save_6xx_restore /* Check NAP */
+END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP)
+#endif /* CONFIG_6xx */
+ .globl transfer_to_handler_cont
+transfer_to_handler_cont:
+ lwz r11,THREAD_INFO-THREAD(r12)
+ cmplw r1,r11 /* if r1 <= current->thread_info */
+ ble- stack_ovf /* then the kernel stack overflowed */
+3:
+ mflr r9
+ lwz r11,0(r9) /* virtual address of handler */
+ lwz r9,4(r9) /* where to go when done */
+ FIX_SRR1(r10,r12)
+ mtspr SPRN_SRR0,r11
+ mtspr SPRN_SRR1,r10
+ mtlr r9
+ SYNC
+ RFI /* jump to handler, enable MMU */
+
+/*
+ * On kernel stack overflow, load up an initial stack pointer
+ * and call StackOverflow(regs), which should not return.
+ */
+stack_ovf:
+ /* sometimes we use a statically-allocated stack, which is OK. */
+ lis r11,_end@h
+ ori r11,r11,_end@l
+ cmplw r1,r11
+ ble 3b /* r1 <= &_end is OK */
+ SAVE_NVGPRS(r11)
+ addi r3,r1,STACK_FRAME_OVERHEAD
+ lis r1,init_thread_union@ha
+ addi r1,r1,init_thread_union@l
+ addi r1,r1,THREAD_SIZE-STACK_FRAME_OVERHEAD
+ lis r9,StackOverflow@ha
+ addi r9,r9,StackOverflow@l
+ LOAD_MSR_KERNEL(r10,MSR_KERNEL)
+ FIX_SRR1(r10,r12)
+ mtspr SPRN_SRR0,r9
+ mtspr SPRN_SRR1,r10
+ SYNC
+ RFI
+
+/*
+ * Handle a system call.
+ */
+ .stabs "arch/powerpc/kernel/",N_SO,0,0,0f
+ .stabs "entry_32.S",N_SO,0,0,0f
+0:
+
+_GLOBAL(DoSyscall)
+ stw r0,THREAD+LAST_SYSCALL(r2)
+ stw r3,ORIG_GPR3(r1)
+ li r12,0
+ stw r12,RESULT(r1)
+ lwz r11,_CCR(r1) /* Clear SO bit in CR */
+ rlwinm r11,r11,0,4,2
+ stw r11,_CCR(r1)
+#ifdef SHOW_SYSCALLS
+ bl do_show_syscall
+#endif /* SHOW_SYSCALLS */
+ rlwinm r10,r1,0,0,(31-THREAD_SHIFT) /* current_thread_info() */
+ li r11,0
+ stb r11,TI_SC_NOERR(r10)
+ lwz r11,TI_FLAGS(r10)
+ andi. r11,r11,_TIF_SYSCALL_T_OR_A
+ bne- syscall_dotrace
+syscall_dotrace_cont:
+ cmplwi 0,r0,NR_syscalls
+ lis r10,sys_call_table@h
+ ori r10,r10,sys_call_table@l
+ slwi r0,r0,2
+ bge- 66f
+ lwzx r10,r10,r0 /* Fetch system call handler [ptr] */
+ mtlr r10
+ addi r9,r1,STACK_FRAME_OVERHEAD
+ PPC440EP_ERR42
+ blrl /* Call handler */
+ .globl ret_from_syscall
+ret_from_syscall:
+#ifdef SHOW_SYSCALLS
+ bl do_show_syscall_exit
+#endif
+ mr r6,r3
+ li r11,-_LAST_ERRNO
+ cmplw 0,r3,r11
+ rlwinm r12,r1,0,0,(31-THREAD_SHIFT) /* current_thread_info() */
+ blt+ 30f
+ lbz r11,TI_SC_NOERR(r12)
+ cmpwi r11,0
+ bne 30f
+ neg r3,r3
+ lwz r10,_CCR(r1) /* Set SO bit in CR */
+ oris r10,r10,0x1000
+ stw r10,_CCR(r1)
+
+ /* disable interrupts so current_thread_info()->flags can't change */
+30: LOAD_MSR_KERNEL(r10,MSR_KERNEL) /* doesn't include MSR_EE */
+ SYNC
+ MTMSRD(r10)
+ lwz r9,TI_FLAGS(r12)
+ andi. r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SIGPENDING|_TIF_NEED_RESCHED)
+ bne- syscall_exit_work
+syscall_exit_cont:
+#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
+ /* If the process has its own DBCR0 value, load it up. The single
+ step bit tells us that dbcr0 should be loaded. */
+ lwz r0,THREAD+THREAD_DBCR0(r2)
+ andis. r10,r0,DBCR0_IC@h
+ bnel- load_dbcr0
+#endif
+ stwcx. r0,0,r1 /* to clear the reservation */
+ lwz r4,_LINK(r1)
+ lwz r5,_CCR(r1)
+ mtlr r4
+ mtcr r5
+ lwz r7,_NIP(r1)
+ lwz r8,_MSR(r1)
+ FIX_SRR1(r8, r0)
+ lwz r2,GPR2(r1)
+ lwz r1,GPR1(r1)
+ mtspr SPRN_SRR0,r7
+ mtspr SPRN_SRR1,r8
+ SYNC
+ RFI
+
+66: li r3,-ENOSYS
+ b ret_from_syscall
+
+ .globl ret_from_fork
+ret_from_fork:
+ REST_NVGPRS(r1)
+ bl schedule_tail
+ li r3,0
+ b ret_from_syscall
+
+/* Traced system call support */
+syscall_dotrace:
+ SAVE_NVGPRS(r1)
+ li r0,0xc00
+ stw r0,_TRAP(r1)
+ addi r3,r1,STACK_FRAME_OVERHEAD
+ bl do_syscall_trace_enter
+ lwz r0,GPR0(r1) /* Restore original registers */
+ lwz r3,GPR3(r1)
+ lwz r4,GPR4(r1)
+ lwz r5,GPR5(r1)
+ lwz r6,GPR6(r1)
+ lwz r7,GPR7(r1)
+ lwz r8,GPR8(r1)
+ REST_NVGPRS(r1)
+ b syscall_dotrace_cont
+
+syscall_exit_work:
+ stw r6,RESULT(r1) /* Save result */
+ stw r3,GPR3(r1) /* Update return value */
+ andi. r0,r9,_TIF_SYSCALL_T_OR_A
+ beq 5f
+ ori r10,r10,MSR_EE
+ SYNC
+ MTMSRD(r10) /* re-enable interrupts */
+ lwz r4,_TRAP(r1)
+ andi. r4,r4,1
+ beq 4f
+ SAVE_NVGPRS(r1)
+ li r4,0xc00
+ stw r4,_TRAP(r1)
+4:
+ addi r3,r1,STACK_FRAME_OVERHEAD
+ bl do_syscall_trace_leave
+ REST_NVGPRS(r1)
+2:
+ lwz r3,GPR3(r1)
+ LOAD_MSR_KERNEL(r10,MSR_KERNEL) /* doesn't include MSR_EE */
+ SYNC
+ MTMSRD(r10) /* disable interrupts again */
+ rlwinm r12,r1,0,0,(31-THREAD_SHIFT) /* current_thread_info() */
+ lwz r9,TI_FLAGS(r12)
+5:
+ andi. r0,r9,_TIF_NEED_RESCHED
+ bne 1f
+ lwz r5,_MSR(r1)
+ andi. r5,r5,MSR_PR
+ beq syscall_exit_cont
+ andi. r0,r9,_TIF_SIGPENDING
+ beq syscall_exit_cont
+ b do_user_signal
+1:
+ ori r10,r10,MSR_EE
+ SYNC
+ MTMSRD(r10) /* re-enable interrupts */
+ bl schedule
+ b 2b
+
+#ifdef SHOW_SYSCALLS
+do_show_syscall:
+#ifdef SHOW_SYSCALLS_TASK
+ lis r11,show_syscalls_task@ha
+ lwz r11,show_syscalls_task@l(r11)
+ cmp 0,r2,r11
+ bnelr
+#endif
+ stw r31,GPR31(r1)
+ mflr r31
+ lis r3,7f@ha
+ addi r3,r3,7f@l
+ lwz r4,GPR0(r1)
+ lwz r5,GPR3(r1)
+ lwz r6,GPR4(r1)
+ lwz r7,GPR5(r1)
+ lwz r8,GPR6(r1)
+ lwz r9,GPR7(r1)
+ bl printk
+ lis r3,77f@ha
+ addi r3,r3,77f@l
+ lwz r4,GPR8(r1)
+ mr r5,r2
+ bl printk
+ lwz r0,GPR0(r1)
+ lwz r3,GPR3(r1)
+ lwz r4,GPR4(r1)
+ lwz r5,GPR5(r1)
+ lwz r6,GPR6(r1)
+ lwz r7,GPR7(r1)
+ lwz r8,GPR8(r1)
+ mtlr r31
+ lwz r31,GPR31(r1)
+ blr
+
+do_show_syscall_exit:
+#ifdef SHOW_SYSCALLS_TASK
+ lis r11,show_syscalls_task@ha
+ lwz r11,show_syscalls_task@l(r11)
+ cmp 0,r2,r11
+ bnelr
+#endif
+ stw r31,GPR31(r1)
+ mflr r31
+ stw r3,RESULT(r1) /* Save result */
+ mr r4,r3
+ lis r3,79f@ha
+ addi r3,r3,79f@l
+ bl printk
+ lwz r3,RESULT(r1)
+ mtlr r31
+ lwz r31,GPR31(r1)
+ blr
+
+7: .string "syscall %d(%x, %x, %x, %x, %x, "
+77: .string "%x), current=%p\n"
+79: .string " -> %x\n"
+ .align 2,0
+
+#ifdef SHOW_SYSCALLS_TASK
+ .data
+ .globl show_syscalls_task
+show_syscalls_task:
+ .long -1
+ .text
+#endif
+#endif /* SHOW_SYSCALLS */
+
+/*
+ * The sigsuspend and rt_sigsuspend system calls can call do_signal
+ * and thus put the process into the stopped state where we might
+ * want to examine its user state with ptrace. Therefore we need
+ * to save all the nonvolatile registers (r13 - r31) before calling
+ * the C code.
+ */
+ .globl ppc_sigsuspend
+ppc_sigsuspend:
+ SAVE_NVGPRS(r1)
+ lwz r0,_TRAP(r1)
+ rlwinm r0,r0,0,0,30 /* clear LSB to indicate full */
+ stw r0,_TRAP(r1) /* register set saved */
+ b sys_sigsuspend
+
+ .globl ppc_rt_sigsuspend
+ppc_rt_sigsuspend:
+ SAVE_NVGPRS(r1)
+ lwz r0,_TRAP(r1)
+ rlwinm r0,r0,0,0,30
+ stw r0,_TRAP(r1)
+ b sys_rt_sigsuspend
+
+ .globl ppc_fork
+ppc_fork:
+ SAVE_NVGPRS(r1)
+ lwz r0,_TRAP(r1)
+ rlwinm r0,r0,0,0,30 /* clear LSB to indicate full */
+ stw r0,_TRAP(r1) /* register set saved */
+ b sys_fork
+
+ .globl ppc_vfork
+ppc_vfork:
+ SAVE_NVGPRS(r1)
+ lwz r0,_TRAP(r1)
+ rlwinm r0,r0,0,0,30 /* clear LSB to indicate full */
+ stw r0,_TRAP(r1) /* register set saved */
+ b sys_vfork
+
+ .globl ppc_clone
+ppc_clone:
+ SAVE_NVGPRS(r1)
+ lwz r0,_TRAP(r1)
+ rlwinm r0,r0,0,0,30 /* clear LSB to indicate full */
+ stw r0,_TRAP(r1) /* register set saved */
+ b sys_clone
+
+ .globl ppc_swapcontext
+ppc_swapcontext:
+ SAVE_NVGPRS(r1)
+ lwz r0,_TRAP(r1)
+ rlwinm r0,r0,0,0,30 /* clear LSB to indicate full */
+ stw r0,_TRAP(r1) /* register set saved */
+ b sys_swapcontext
+
+/*
+ * Top-level page fault handling.
+ * This is in assembler because if do_page_fault tells us that
+ * it is a bad kernel page fault, we want to save the non-volatile
+ * registers before calling bad_page_fault.
+ */
+ .globl handle_page_fault
+handle_page_fault:
+ stw r4,_DAR(r1)
+ addi r3,r1,STACK_FRAME_OVERHEAD
+ bl do_page_fault
+ cmpwi r3,0
+ beq+ ret_from_except
+ SAVE_NVGPRS(r1)
+ lwz r0,_TRAP(r1)
+ clrrwi r0,r0,1
+ stw r0,_TRAP(r1)
+ mr r5,r3
+ addi r3,r1,STACK_FRAME_OVERHEAD
+ lwz r4,_DAR(r1)
+ bl bad_page_fault
+ b ret_from_except_full
+
+/*
+ * This routine switches between two different tasks. The process
+ * state of one is saved on its kernel stack. Then the state
+ * of the other is restored from its kernel stack. The memory
+ * management hardware is updated to the second process's state.
+ * Finally, we can return to the second process.
+ * On entry, r3 points to the THREAD for the current task, r4
+ * points to the THREAD for the new task.
+ *
+ * This routine is always called with interrupts disabled.
+ *
+ * Note: there are two ways to get to the "going out" portion
+ * of this code; either by coming in via the entry (_switch)
+ * or via "fork" which must set up an environment equivalent
+ * to the "_switch" path. If you change this , you'll have to
+ * change the fork code also.
+ *
+ * The code which creates the new task context is in 'copy_thread'
+ * in arch/ppc/kernel/process.c
+ */
+_GLOBAL(_switch)
+ stwu r1,-INT_FRAME_SIZE(r1)
+ mflr r0
+ stw r0,INT_FRAME_SIZE+4(r1)
+ /* r3-r12 are caller saved -- Cort */
+ SAVE_NVGPRS(r1)
+ stw r0,_NIP(r1) /* Return to switch caller */
+ mfmsr r11
+ li r0,MSR_FP /* Disable floating-point */
+#ifdef CONFIG_ALTIVEC
+BEGIN_FTR_SECTION
+ oris r0,r0,MSR_VEC@h /* Disable altivec */
+ mfspr r12,SPRN_VRSAVE /* save vrsave register value */
+ stw r12,THREAD+THREAD_VRSAVE(r2)
+END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
+#endif /* CONFIG_ALTIVEC */
+#ifdef CONFIG_SPE
+ oris r0,r0,MSR_SPE@h /* Disable SPE */
+ mfspr r12,SPRN_SPEFSCR /* save spefscr register value */
+ stw r12,THREAD+THREAD_SPEFSCR(r2)
+#endif /* CONFIG_SPE */
+ and. r0,r0,r11 /* FP or altivec or SPE enabled? */
+ beq+ 1f
+ andc r11,r11,r0
+ MTMSRD(r11)
+ isync
+1: stw r11,_MSR(r1)
+ mfcr r10
+ stw r10,_CCR(r1)
+ stw r1,KSP(r3) /* Set old stack pointer */
+
+#ifdef CONFIG_SMP
+ /* We need a sync somewhere here to make sure that if the
+ * previous task gets rescheduled on another CPU, it sees all
+ * stores it has performed on this one.
+ */
+ sync
+#endif /* CONFIG_SMP */
+
+ tophys(r0,r4)
+ CLR_TOP32(r0)
+ mtspr SPRN_SPRG3,r0 /* Update current THREAD phys addr */
+ lwz r1,KSP(r4) /* Load new stack pointer */
+
+ /* save the old current 'last' for return value */
+ mr r3,r2
+ addi r2,r4,-THREAD /* Update current */
+
+#ifdef CONFIG_ALTIVEC
+BEGIN_FTR_SECTION
+ lwz r0,THREAD+THREAD_VRSAVE(r2)
+ mtspr SPRN_VRSAVE,r0 /* if G4, restore VRSAVE reg */
+END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
+#endif /* CONFIG_ALTIVEC */
+#ifdef CONFIG_SPE
+ lwz r0,THREAD+THREAD_SPEFSCR(r2)
+ mtspr SPRN_SPEFSCR,r0 /* restore SPEFSCR reg */
+#endif /* CONFIG_SPE */
+
+ lwz r0,_CCR(r1)
+ mtcrf 0xFF,r0
+ /* r3-r12 are destroyed -- Cort */
+ REST_NVGPRS(r1)
+
+ lwz r4,_NIP(r1) /* Return to _switch caller in new task */
+ mtlr r4
+ addi r1,r1,INT_FRAME_SIZE
+ blr
+
+ .globl fast_exception_return
+fast_exception_return:
+#if !(defined(CONFIG_4xx) || defined(CONFIG_BOOKE))
+ andi. r10,r9,MSR_RI /* check for recoverable interrupt */
+ beq 1f /* if not, we've got problems */
+#endif
+
+2: REST_4GPRS(3, r11)
+ lwz r10,_CCR(r11)
+ REST_GPR(1, r11)
+ mtcr r10
+ lwz r10,_LINK(r11)
+ mtlr r10
+ REST_GPR(10, r11)
+ mtspr SPRN_SRR1,r9
+ mtspr SPRN_SRR0,r12
+ REST_GPR(9, r11)
+ REST_GPR(12, r11)
+ lwz r11,GPR11(r11)
+ SYNC
+ RFI
+
+#if !(defined(CONFIG_4xx) || defined(CONFIG_BOOKE))
+/* check if the exception happened in a restartable section */
+1: lis r3,exc_exit_restart_end@ha
+ addi r3,r3,exc_exit_restart_end@l
+ cmplw r12,r3
+ bge 3f
+ lis r4,exc_exit_restart@ha
+ addi r4,r4,exc_exit_restart@l
+ cmplw r12,r4
+ blt 3f
+ lis r3,fee_restarts@ha
+ tophys(r3,r3)
+ lwz r5,fee_restarts@l(r3)
+ addi r5,r5,1
+ stw r5,fee_restarts@l(r3)
+ mr r12,r4 /* restart at exc_exit_restart */
+ b 2b
+
+ .comm fee_restarts,4
+
+/* aargh, a nonrecoverable interrupt, panic */
+/* aargh, we don't know which trap this is */
+/* but the 601 doesn't implement the RI bit, so assume it's OK */
+3:
+BEGIN_FTR_SECTION
+ b 2b
+END_FTR_SECTION_IFSET(CPU_FTR_601)
+ li r10,-1
+ stw r10,_TRAP(r11)
+ addi r3,r1,STACK_FRAME_OVERHEAD
+ lis r10,MSR_KERNEL@h
+ ori r10,r10,MSR_KERNEL@l
+ bl transfer_to_handler_full
+ .long nonrecoverable_exception
+ .long ret_from_except
+#endif
+
+ .globl sigreturn_exit
+sigreturn_exit:
+ subi r1,r3,STACK_FRAME_OVERHEAD
+ rlwinm r12,r1,0,0,(31-THREAD_SHIFT) /* current_thread_info() */
+ lwz r9,TI_FLAGS(r12)
+ andi. r0,r9,_TIF_SYSCALL_T_OR_A
+ beq+ ret_from_except_full
+ bl do_syscall_trace_leave
+ /* fall through */
+
+ .globl ret_from_except_full
+ret_from_except_full:
+ REST_NVGPRS(r1)
+ /* fall through */
+
+ .globl ret_from_except
+ret_from_except:
+ /* Hard-disable interrupts so that current_thread_info()->flags
+ * can't change between when we test it and when we return
+ * from the interrupt. */
+ LOAD_MSR_KERNEL(r10,MSR_KERNEL)
+ SYNC /* Some chip revs have problems here... */
+ MTMSRD(r10) /* disable interrupts */
+
+ lwz r3,_MSR(r1) /* Returning to user mode? */
+ andi. r0,r3,MSR_PR
+ beq resume_kernel
+
+user_exc_return: /* r10 contains MSR_KERNEL here */
+ /* Check current_thread_info()->flags */
+ rlwinm r9,r1,0,0,(31-THREAD_SHIFT)
+ lwz r9,TI_FLAGS(r9)
+ andi. r0,r9,(_TIF_SIGPENDING|_TIF_NEED_RESCHED)
+ bne do_work
+
+restore_user:
+#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
+ /* Check whether this process has its own DBCR0 value. The single
+ step bit tells us that dbcr0 should be loaded. */
+ lwz r0,THREAD+THREAD_DBCR0(r2)
+ andis. r10,r0,DBCR0_IC@h
+ bnel- load_dbcr0
+#endif
+
+#ifdef CONFIG_PREEMPT
+ b restore
+
+/* N.B. the only way to get here is from the beq following ret_from_except. */
+resume_kernel:
+ /* check current_thread_info->preempt_count */
+ rlwinm r9,r1,0,0,(31-THREAD_SHIFT)
+ lwz r0,TI_PREEMPT(r9)
+ cmpwi 0,r0,0 /* if non-zero, just restore regs and return */
+ bne restore
+ lwz r0,TI_FLAGS(r9)
+ andi. r0,r0,_TIF_NEED_RESCHED
+ beq+ restore
+ andi. r0,r3,MSR_EE /* interrupts off? */
+ beq restore /* don't schedule if so */
+1: bl preempt_schedule_irq
+ rlwinm r9,r1,0,0,(31-THREAD_SHIFT)
+ lwz r3,TI_FLAGS(r9)
+ andi. r0,r3,_TIF_NEED_RESCHED
+ bne- 1b
+#else
+resume_kernel:
+#endif /* CONFIG_PREEMPT */
+
+ /* interrupts are hard-disabled at this point */
+restore:
+ lwz r0,GPR0(r1)
+ lwz r2,GPR2(r1)
+ REST_4GPRS(3, r1)
+ REST_2GPRS(7, r1)
+
+ lwz r10,_XER(r1)
+ lwz r11,_CTR(r1)
+ mtspr SPRN_XER,r10
+ mtctr r11
+
+ PPC405_ERR77(0,r1)
+ stwcx. r0,0,r1 /* to clear the reservation */
+
+#if !(defined(CONFIG_4xx) || defined(CONFIG_BOOKE))
+ lwz r9,_MSR(r1)
+ andi. r10,r9,MSR_RI /* check if this exception occurred */
+ beql nonrecoverable /* at a bad place (MSR:RI = 0) */
+
+ lwz r10,_CCR(r1)
+ lwz r11,_LINK(r1)
+ mtcrf 0xFF,r10
+ mtlr r11
+
+ /*
+ * Once we put values in SRR0 and SRR1, we are in a state
+ * where exceptions are not recoverable, since taking an
+ * exception will trash SRR0 and SRR1. Therefore we clear the
+ * MSR:RI bit to indicate this. If we do take an exception,
+ * we can't return to the point of the exception but we
+ * can restart the exception exit path at the label
+ * exc_exit_restart below. -- paulus
+ */
+ LOAD_MSR_KERNEL(r10,MSR_KERNEL & ~MSR_RI)
+ SYNC
+ MTMSRD(r10) /* clear the RI bit */
+ .globl exc_exit_restart
+exc_exit_restart:
+ lwz r9,_MSR(r1)
+ lwz r12,_NIP(r1)
+ FIX_SRR1(r9,r10)
+ mtspr SPRN_SRR0,r12
+ mtspr SPRN_SRR1,r9
+ REST_4GPRS(9, r1)
+ lwz r1,GPR1(r1)
+ .globl exc_exit_restart_end
+exc_exit_restart_end:
+ SYNC
+ RFI
+
+#else /* !(CONFIG_4xx || CONFIG_BOOKE) */
+ /*
+ * This is a bit different on 4xx/Book-E because it doesn't have
+ * the RI bit in the MSR.
+ * The TLB miss handler checks if we have interrupted
+ * the exception exit path and restarts it if so
+ * (well maybe one day it will... :).
+ */
+ lwz r11,_LINK(r1)
+ mtlr r11
+ lwz r10,_CCR(r1)
+ mtcrf 0xff,r10
+ REST_2GPRS(9, r1)
+ .globl exc_exit_restart
+exc_exit_restart:
+ lwz r11,_NIP(r1)
+ lwz r12,_MSR(r1)
+exc_exit_start:
+ mtspr SPRN_SRR0,r11
+ mtspr SPRN_SRR1,r12
+ REST_2GPRS(11, r1)
+ lwz r1,GPR1(r1)
+ .globl exc_exit_restart_end
+exc_exit_restart_end:
+ PPC405_ERR77_SYNC
+ rfi
+ b . /* prevent prefetch past rfi */
+
+/*
+ * Returning from a critical interrupt in user mode doesn't need
+ * to be any different from a normal exception. For a critical
+ * interrupt in the kernel, we just return (without checking for
+ * preemption) since the interrupt may have happened at some crucial
+ * place (e.g. inside the TLB miss handler), and because we will be
+ * running with r1 pointing into critical_stack, not the current
+ * process's kernel stack (and therefore current_thread_info() will
+ * give the wrong answer).
+ * We have to restore various SPRs that may have been in use at the
+ * time of the critical interrupt.
+ *
+ */
+#ifdef CONFIG_40x
+#define PPC_40x_TURN_OFF_MSR_DR \
+ /* avoid any possible TLB misses here by turning off MSR.DR, we \
+ * assume the instructions here are mapped by a pinned TLB entry */ \
+ li r10,MSR_IR; \
+ mtmsr r10; \
+ isync; \
+ tophys(r1, r1);
+#else
+#define PPC_40x_TURN_OFF_MSR_DR
+#endif
+
+#define RET_FROM_EXC_LEVEL(exc_lvl_srr0, exc_lvl_srr1, exc_lvl_rfi) \
+ REST_NVGPRS(r1); \
+ lwz r3,_MSR(r1); \
+ andi. r3,r3,MSR_PR; \
+ LOAD_MSR_KERNEL(r10,MSR_KERNEL); \
+ bne user_exc_return; \
+ lwz r0,GPR0(r1); \
+ lwz r2,GPR2(r1); \
+ REST_4GPRS(3, r1); \
+ REST_2GPRS(7, r1); \
+ lwz r10,_XER(r1); \
+ lwz r11,_CTR(r1); \
+ mtspr SPRN_XER,r10; \
+ mtctr r11; \
+ PPC405_ERR77(0,r1); \
+ stwcx. r0,0,r1; /* to clear the reservation */ \
+ lwz r11,_LINK(r1); \
+ mtlr r11; \
+ lwz r10,_CCR(r1); \
+ mtcrf 0xff,r10; \
+ PPC_40x_TURN_OFF_MSR_DR; \
+ lwz r9,_DEAR(r1); \
+ lwz r10,_ESR(r1); \
+ mtspr SPRN_DEAR,r9; \
+ mtspr SPRN_ESR,r10; \
+ lwz r11,_NIP(r1); \
+ lwz r12,_MSR(r1); \
+ mtspr exc_lvl_srr0,r11; \
+ mtspr exc_lvl_srr1,r12; \
+ lwz r9,GPR9(r1); \
+ lwz r12,GPR12(r1); \
+ lwz r10,GPR10(r1); \
+ lwz r11,GPR11(r1); \
+ lwz r1,GPR1(r1); \
+ PPC405_ERR77_SYNC; \
+ exc_lvl_rfi; \
+ b .; /* prevent prefetch past exc_lvl_rfi */
+
+ .globl ret_from_crit_exc
+ret_from_crit_exc:
+ RET_FROM_EXC_LEVEL(SPRN_CSRR0, SPRN_CSRR1, RFCI)
+
+#ifdef CONFIG_BOOKE
+ .globl ret_from_debug_exc
+ret_from_debug_exc:
+ RET_FROM_EXC_LEVEL(SPRN_DSRR0, SPRN_DSRR1, RFDI)
+
+ .globl ret_from_mcheck_exc
+ret_from_mcheck_exc:
+ RET_FROM_EXC_LEVEL(SPRN_MCSRR0, SPRN_MCSRR1, RFMCI)
+#endif /* CONFIG_BOOKE */
+
+/*
+ * Load the DBCR0 value for a task that is being ptraced,
+ * having first saved away the global DBCR0. Note that r0
+ * has the dbcr0 value to set upon entry to this.
+ */
+load_dbcr0:
+ mfmsr r10 /* first disable debug exceptions */
+ rlwinm r10,r10,0,~MSR_DE
+ mtmsr r10
+ isync
+ mfspr r10,SPRN_DBCR0
+ lis r11,global_dbcr0@ha
+ addi r11,r11,global_dbcr0@l
+ stw r10,0(r11)
+ mtspr SPRN_DBCR0,r0
+ lwz r10,4(r11)
+ addi r10,r10,1
+ stw r10,4(r11)
+ li r11,-1
+ mtspr SPRN_DBSR,r11 /* clear all pending debug events */
+ blr
+
+ .comm global_dbcr0,8
+#endif /* !(CONFIG_4xx || CONFIG_BOOKE) */
+
+do_work: /* r10 contains MSR_KERNEL here */
+ andi. r0,r9,_TIF_NEED_RESCHED
+ beq do_user_signal
+
+do_resched: /* r10 contains MSR_KERNEL here */
+ ori r10,r10,MSR_EE
+ SYNC
+ MTMSRD(r10) /* hard-enable interrupts */
+ bl schedule
+recheck:
+ LOAD_MSR_KERNEL(r10,MSR_KERNEL)
+ SYNC
+ MTMSRD(r10) /* disable interrupts */
+ rlwinm r9,r1,0,0,(31-THREAD_SHIFT)
+ lwz r9,TI_FLAGS(r9)
+ andi. r0,r9,_TIF_NEED_RESCHED
+ bne- do_resched
+ andi. r0,r9,_TIF_SIGPENDING
+ beq restore_user
+do_user_signal: /* r10 contains MSR_KERNEL here */
+ ori r10,r10,MSR_EE
+ SYNC
+ MTMSRD(r10) /* hard-enable interrupts */
+ /* save r13-r31 in the exception frame, if not already done */
+ lwz r3,_TRAP(r1)
+ andi. r0,r3,1
+ beq 2f
+ SAVE_NVGPRS(r1)
+ rlwinm r3,r3,0,0,30
+ stw r3,_TRAP(r1)
+2: li r3,0
+ addi r4,r1,STACK_FRAME_OVERHEAD
+ bl do_signal
+ REST_NVGPRS(r1)
+ b recheck
+
+/*
+ * We come here when we are at the end of handling an exception
+ * that occurred at a place where taking an exception will lose
+ * state information, such as the contents of SRR0 and SRR1.
+ */
+nonrecoverable:
+ lis r10,exc_exit_restart_end@ha
+ addi r10,r10,exc_exit_restart_end@l
+ cmplw r12,r10
+ bge 3f
+ lis r11,exc_exit_restart@ha
+ addi r11,r11,exc_exit_restart@l
+ cmplw r12,r11
+ blt 3f
+ lis r10,ee_restarts@ha
+ lwz r12,ee_restarts@l(r10)
+ addi r12,r12,1
+ stw r12,ee_restarts@l(r10)
+ mr r12,r11 /* restart at exc_exit_restart */
+ blr
+3: /* OK, we can't recover, kill this process */
+ /* but the 601 doesn't implement the RI bit, so assume it's OK */
+BEGIN_FTR_SECTION
+ blr
+END_FTR_SECTION_IFSET(CPU_FTR_601)
+ lwz r3,_TRAP(r1)
+ andi. r0,r3,1
+ beq 4f
+ SAVE_NVGPRS(r1)
+ rlwinm r3,r3,0,0,30
+ stw r3,_TRAP(r1)
+4: addi r3,r1,STACK_FRAME_OVERHEAD
+ bl nonrecoverable_exception
+ /* shouldn't return */
+ b 4b
+
+ .comm ee_restarts,4
+
+/*
+ * PROM code for specific machines follows. Put it
+ * here so it's easy to add arch-specific sections later.
+ * -- Cort
+ */
+#ifdef CONFIG_PPC_RTAS
+/*
+ * On CHRP, the Run-Time Abstraction Services (RTAS) have to be
+ * called with the MMU off.
+ */
+_GLOBAL(enter_rtas)
+ stwu r1,-INT_FRAME_SIZE(r1)
+ mflr r0
+ stw r0,INT_FRAME_SIZE+4(r1)
+ LOADADDR(r4, rtas)
+ lis r6,1f@ha /* physical return address for rtas */
+ addi r6,r6,1f@l
+ tophys(r6,r6)
+ tophys(r7,r1)
+ lwz r8,RTASENTRY(r4)
+ lwz r4,RTASBASE(r4)
+ mfmsr r9
+ stw r9,8(r1)
+ LOAD_MSR_KERNEL(r0,MSR_KERNEL)
+ SYNC /* disable interrupts so SRR0/1 */
+ MTMSRD(r0) /* don't get trashed */
+ li r9,MSR_KERNEL & ~(MSR_IR|MSR_DR)
+ mtlr r6
+ mtspr SPRN_SPRG2,r7
+ mtspr SPRN_SRR0,r8
+ mtspr SPRN_SRR1,r9
+ RFI
+1: tophys(r9,r1)
+ lwz r8,INT_FRAME_SIZE+4(r9) /* get return address */
+ lwz r9,8(r9) /* original msr value */
+ FIX_SRR1(r9,r0)
+ addi r1,r1,INT_FRAME_SIZE
+ li r0,0
+ mtspr SPRN_SPRG2,r0
+ mtspr SPRN_SRR0,r8
+ mtspr SPRN_SRR1,r9
+ RFI /* return to caller */
+
+ .globl machine_check_in_rtas
+machine_check_in_rtas:
+ twi 31,0,0
+ /* XXX load up BATs and panic */
+
+#endif /* CONFIG_PPC_RTAS */
diff --git a/arch/ppc64/kernel/entry.S b/arch/powerpc/kernel/entry_64.S
index e8c0bbf4d000..2d22bf03484e 100644
--- a/arch/ppc64/kernel/entry.S
+++ b/arch/powerpc/kernel/entry_64.S
@@ -42,9 +42,6 @@
.SYS_CALL_TABLE:
.tc .sys_call_table[TC],.sys_call_table
-.SYS_CALL_TABLE32:
- .tc .sys_call_table32[TC],.sys_call_table32
-
/* This value is used to mark exception frames on the stack. */
exception_marker:
.tc ID_72656773_68657265[TC],0x7265677368657265
@@ -133,7 +130,7 @@ system_call: /* label this so stack traces look sane */
ld r11,.SYS_CALL_TABLE@toc(2)
andi. r10,r10,_TIF_32BIT
beq 15f
- ld r11,.SYS_CALL_TABLE32@toc(2)
+ addi r11,r11,8 /* use 32-bit syscall entries */
clrldi r3,r3,32
clrldi r4,r4,32
clrldi r5,r5,32
@@ -141,7 +138,7 @@ system_call: /* label this so stack traces look sane */
clrldi r7,r7,32
clrldi r8,r8,32
15:
- slwi r0,r0,3
+ slwi r0,r0,4
ldx r10,r11,r0 /* Fetch system call handler [ptr] */
mtctr r10
bctrl /* Call handler */
@@ -191,8 +188,8 @@ syscall_exit_trace_cont:
ld r1,GPR1(r1)
mtlr r4
mtcr r5
- mtspr SRR0,r7
- mtspr SRR1,r8
+ mtspr SPRN_SRR0,r7
+ mtspr SPRN_SRR1,r8
rfid
b . /* prevent speculative execution */
@@ -265,7 +262,7 @@ _GLOBAL(save_nvgprs)
*/
_GLOBAL(ppc32_sigsuspend)
bl .save_nvgprs
- bl .sys32_sigsuspend
+ bl .compat_sys_sigsuspend
b 70f
_GLOBAL(ppc64_rt_sigsuspend)
@@ -275,14 +272,14 @@ _GLOBAL(ppc64_rt_sigsuspend)
_GLOBAL(ppc32_rt_sigsuspend)
bl .save_nvgprs
- bl .sys32_rt_sigsuspend
+ bl .compat_sys_rt_sigsuspend
70: cmpdi 0,r3,0
/* If it returned an error, we need to return via syscall_exit to set
the SO bit in cr0 and potentially stop for ptrace. */
bne syscall_exit
/* If sigsuspend() returns zero, we are going into a signal handler. We
may need to call audit_syscall_exit() to mark the exit from sigsuspend() */
-#ifdef CONFIG_AUDIT
+#ifdef CONFIG_AUDITSYSCALL
ld r3,PACACURRENT(r13)
ld r4,AUDITCONTEXT(r3)
cmpdi 0,r4,0
@@ -310,7 +307,7 @@ _GLOBAL(ppc_clone)
_GLOBAL(ppc32_swapcontext)
bl .save_nvgprs
- bl .sys32_swapcontext
+ bl .compat_sys_swapcontext
b 80f
_GLOBAL(ppc64_swapcontext)
@@ -319,11 +316,11 @@ _GLOBAL(ppc64_swapcontext)
b 80f
_GLOBAL(ppc32_sigreturn)
- bl .sys32_sigreturn
+ bl .compat_sys_sigreturn
b 80f
_GLOBAL(ppc32_rt_sigreturn)
- bl .sys32_rt_sigreturn
+ bl .compat_sys_rt_sigreturn
b 80f
_GLOBAL(ppc64_rt_sigreturn)
@@ -531,7 +528,7 @@ restore:
mtctr r3
mtlr r0
ld r3,_XER(r1)
- mtspr XER,r3
+ mtspr SPRN_XER,r3
REST_8GPRS(5, r1)
@@ -543,12 +540,12 @@ restore:
mtmsrd r0,1
ld r0,_MSR(r1)
- mtspr SRR1,r0
+ mtspr SPRN_SRR1,r0
ld r2,_CCR(r1)
mtcrf 0xFF,r2
ld r2,_NIP(r1)
- mtspr SRR0,r2
+ mtspr SPRN_SRR0,r2
ld r0,GPR0(r1)
ld r2,GPR2(r1)
@@ -643,7 +640,7 @@ _GLOBAL(enter_rtas)
std r4,_CCR(r1)
mfctr r5
std r5,_CTR(r1)
- mfspr r6,XER
+ mfspr r6,SPRN_XER
std r6,_XER(r1)
mfdar r7
std r7,_DAR(r1)
@@ -697,14 +694,14 @@ _GLOBAL(enter_rtas)
ld r5,RTASENTRY(r4) /* get the rtas->entry value */
ld r4,RTASBASE(r4) /* get the rtas->base value */
- mtspr SRR0,r5
- mtspr SRR1,r6
+ mtspr SPRN_SRR0,r5
+ mtspr SPRN_SRR1,r6
rfid
b . /* prevent speculative execution */
_STATIC(rtas_return_loc)
/* relocation is off at this point */
- mfspr r4,SPRG3 /* Get PACA */
+ mfspr r4,SPRN_SPRG3 /* Get PACA */
SET_REG_TO_CONST(r5, KERNELBASE)
sub r4,r4,r5 /* RELOC the PACA base pointer */
@@ -718,8 +715,8 @@ _STATIC(rtas_return_loc)
LOADADDR(r3,.rtas_restore_regs)
ld r4,PACASAVEDMSR(r4) /* Restore our MSR */
- mtspr SRR0,r3
- mtspr SRR1,r4
+ mtspr SPRN_SRR0,r3
+ mtspr SPRN_SRR1,r4
rfid
b . /* prevent speculative execution */
@@ -730,14 +727,14 @@ _STATIC(rtas_restore_regs)
REST_8GPRS(14, r1) /* Restore the non-volatiles */
REST_10GPRS(22, r1) /* ditto */
- mfspr r13,SPRG3
+ mfspr r13,SPRN_SPRG3
ld r4,_CCR(r1)
mtcr r4
ld r5,_CTR(r1)
mtctr r5
ld r6,_XER(r1)
- mtspr XER,r6
+ mtspr SPRN_XER,r6
ld r7,_DAR(r1)
mtdar r7
ld r8,_DSISR(r1)
@@ -774,7 +771,7 @@ _GLOBAL(enter_prom)
std r4,_CCR(r1)
mfctr r5
std r5,_CTR(r1)
- mfspr r6,XER
+ mfspr r6,SPRN_XER
std r6,_XER(r1)
mfdar r7
std r7,_DAR(r1)
@@ -827,7 +824,7 @@ _GLOBAL(enter_prom)
ld r5,_CTR(r1)
mtctr r5
ld r6,_XER(r1)
- mtspr XER,r6
+ mtspr SPRN_XER,r6
ld r7,_DAR(r1)
mtdar r7
ld r8,_DSISR(r1)
diff --git a/arch/ppc64/kernel/firmware.c b/arch/powerpc/kernel/firmware.c
index d8432c0fb27d..65eae752a527 100644
--- a/arch/ppc64/kernel/firmware.c
+++ b/arch/powerpc/kernel/firmware.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc64/kernel/firmware.c
- *
* Extracted from cputable.c
*
* Copyright (C) 2001 Ben. Herrenschmidt (benh@kernel.crashing.org)
diff --git a/arch/ppc/kernel/fpu.S b/arch/powerpc/kernel/fpu.S
index 665d7d34304c..b780b42c95fc 100644
--- a/arch/ppc/kernel/fpu.S
+++ b/arch/powerpc/kernel/fpu.S
@@ -10,7 +10,7 @@
*/
#include <linux/config.h>
-#include <asm/processor.h>
+#include <asm/reg.h>
#include <asm/page.h>
#include <asm/mmu.h>
#include <asm/pgtable.h>
@@ -27,13 +27,9 @@
* Load up this task's FP registers from its thread_struct,
* enable the FPU for the current task and return to the task.
*/
- .globl load_up_fpu
-load_up_fpu:
+_GLOBAL(load_up_fpu)
mfmsr r5
ori r5,r5,MSR_FP
-#ifdef CONFIG_PPC64BRIDGE
- clrldi r5,r5,1 /* turn off 64-bit mode */
-#endif /* CONFIG_PPC64BRIDGE */
SYNC
MTMSRD(r5) /* enable use of fpu now */
isync
@@ -43,67 +39,57 @@ load_up_fpu:
* to another. Instead we call giveup_fpu in switch_to.
*/
#ifndef CONFIG_SMP
- tophys(r6,0) /* get __pa constant */
- addis r3,r6,last_task_used_math@ha
- lwz r4,last_task_used_math@l(r3)
- cmpwi 0,r4,0
+ LOADBASE(r3, last_task_used_math)
+ toreal(r3)
+ PPC_LL r4,OFF(last_task_used_math)(r3)
+ PPC_LCMPI 0,r4,0
beq 1f
- add r4,r4,r6
+ toreal(r4)
addi r4,r4,THREAD /* want last_task_used_math->thread */
SAVE_32FPRS(0, r4)
mffs fr0
- stfd fr0,THREAD_FPSCR-4(r4)
- lwz r5,PT_REGS(r4)
- add r5,r5,r6
- lwz r4,_MSR-STACK_FRAME_OVERHEAD(r5)
+ stfd fr0,THREAD_FPSCR(r4)
+ PPC_LL r5,PT_REGS(r4)
+ toreal(r5)
+ PPC_LL r4,_MSR-STACK_FRAME_OVERHEAD(r5)
li r10,MSR_FP|MSR_FE0|MSR_FE1
andc r4,r4,r10 /* disable FP for previous task */
- stw r4,_MSR-STACK_FRAME_OVERHEAD(r5)
+ PPC_STL r4,_MSR-STACK_FRAME_OVERHEAD(r5)
1:
#endif /* CONFIG_SMP */
/* enable use of FP after return */
+#ifdef CONFIG_PPC32
mfspr r5,SPRN_SPRG3 /* current task's THREAD (phys) */
lwz r4,THREAD_FPEXC_MODE(r5)
ori r9,r9,MSR_FP /* enable FP for current */
or r9,r9,r4
- lfd fr0,THREAD_FPSCR-4(r5)
+#else
+ ld r4,PACACURRENT(r13)
+ addi r5,r4,THREAD /* Get THREAD */
+ ld r4,THREAD_FPEXC_MODE(r5)
+ ori r12,r12,MSR_FP
+ or r12,r12,r4
+ std r12,_MSR(r1)
+#endif
+ lfd fr0,THREAD_FPSCR(r5)
mtfsf 0xff,fr0
REST_32FPRS(0, r5)
#ifndef CONFIG_SMP
subi r4,r5,THREAD
- sub r4,r4,r6
- stw r4,last_task_used_math@l(r3)
+ fromreal(r4)
+ PPC_STL r4,OFF(last_task_used_math)(r3)
#endif /* CONFIG_SMP */
/* restore registers and return */
/* we haven't used ctr or xer or lr */
b fast_exception_return
/*
- * FP unavailable trap from kernel - print a message, but let
- * the task use FP in the kernel until it returns to user mode.
- */
- .globl KernelFP
-KernelFP:
- lwz r3,_MSR(r1)
- ori r3,r3,MSR_FP
- stw r3,_MSR(r1) /* enable use of FP after return */
- lis r3,86f@h
- ori r3,r3,86f@l
- mr r4,r2 /* current */
- lwz r5,_NIP(r1)
- bl printk
- b ret_from_except
-86: .string "floating point used in kernel (task=%p, pc=%x)\n"
- .align 4,0
-
-/*
* giveup_fpu(tsk)
* Disable FP for the task given as the argument,
* and save the floating-point registers in its thread_struct.
* Enables the FPU for use in the kernel on return.
*/
- .globl giveup_fpu
-giveup_fpu:
+_GLOBAL(giveup_fpu)
mfmsr r5
ori r5,r5,MSR_FP
SYNC_601
@@ -111,23 +97,48 @@ giveup_fpu:
MTMSRD(r5) /* enable use of fpu now */
SYNC_601
isync
- cmpwi 0,r3,0
+ PPC_LCMPI 0,r3,0
beqlr- /* if no previous owner, done */
addi r3,r3,THREAD /* want THREAD of task */
- lwz r5,PT_REGS(r3)
- cmpwi 0,r5,0
+ PPC_LL r5,PT_REGS(r3)
+ PPC_LCMPI 0,r5,0
SAVE_32FPRS(0, r3)
mffs fr0
- stfd fr0,THREAD_FPSCR-4(r3)
+ stfd fr0,THREAD_FPSCR(r3)
beq 1f
- lwz r4,_MSR-STACK_FRAME_OVERHEAD(r5)
+ PPC_LL r4,_MSR-STACK_FRAME_OVERHEAD(r5)
li r3,MSR_FP|MSR_FE0|MSR_FE1
andc r4,r4,r3 /* disable FP for previous task */
- stw r4,_MSR-STACK_FRAME_OVERHEAD(r5)
+ PPC_STL r4,_MSR-STACK_FRAME_OVERHEAD(r5)
1:
#ifndef CONFIG_SMP
li r5,0
- lis r4,last_task_used_math@ha
- stw r5,last_task_used_math@l(r4)
+ LOADBASE(r4,last_task_used_math)
+ PPC_STL r5,OFF(last_task_used_math)(r4)
#endif /* CONFIG_SMP */
blr
+
+/*
+ * These are used in the alignment trap handler when emulating
+ * single-precision loads and stores.
+ * We restore and save the fpscr so the task gets the same result
+ * and exceptions as if the cpu had performed the load or store.
+ */
+
+_GLOBAL(cvt_fd)
+ lfd 0,THREAD_FPSCR(r5) /* load up fpscr value */
+ mtfsf 0xff,0
+ lfs 0,0(r3)
+ stfd 0,0(r4)
+ mffs 0
+ stfd 0,THREAD_FPSCR(r5) /* save new fpscr value */
+ blr
+
+_GLOBAL(cvt_df)
+ lfd 0,THREAD_FPSCR(r5) /* load up fpscr value */
+ mtfsf 0xff,0
+ lfd 0,0(r3)
+ stfs 0,0(r4)
+ mffs 0
+ stfd 0,THREAD_FPSCR(r5) /* save new fpscr value */
+ blr
diff --git a/arch/powerpc/kernel/head_32.S b/arch/powerpc/kernel/head_32.S
new file mode 100644
index 000000000000..b102e3a2415e
--- /dev/null
+++ b/arch/powerpc/kernel/head_32.S
@@ -0,0 +1,1381 @@
+/*
+ * PowerPC version
+ * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
+ *
+ * Rewritten by Cort Dougan (cort@cs.nmt.edu) for PReP
+ * Copyright (C) 1996 Cort Dougan <cort@cs.nmt.edu>
+ * Adapted for Power Macintosh by Paul Mackerras.
+ * Low-level exception handlers and MMU support
+ * rewritten by Paul Mackerras.
+ * Copyright (C) 1996 Paul Mackerras.
+ * MPC8xx modifications Copyright (C) 1997 Dan Malek (dmalek@jlc.net).
+ * Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk).
+ *
+ * This file contains the low-level support and setup for the
+ * PowerPC platform, including trap and interrupt dispatch.
+ * (The PPC 8xx embedded CPUs use head_8xx.S instead.)
+ *
+ * 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/config.h>
+#include <asm/reg.h>
+#include <asm/page.h>
+#include <asm/mmu.h>
+#include <asm/pgtable.h>
+#include <asm/cputable.h>
+#include <asm/cache.h>
+#include <asm/thread_info.h>
+#include <asm/ppc_asm.h>
+#include <asm/asm-offsets.h>
+
+#ifdef CONFIG_APUS
+#include <asm/amigappc.h>
+#endif
+
+/* 601 only have IBAT; cr0.eq is set on 601 when using this macro */
+#define LOAD_BAT(n, reg, RA, RB) \
+ /* see the comment for clear_bats() -- Cort */ \
+ li RA,0; \
+ mtspr SPRN_IBAT##n##U,RA; \
+ mtspr SPRN_DBAT##n##U,RA; \
+ lwz RA,(n*16)+0(reg); \
+ lwz RB,(n*16)+4(reg); \
+ mtspr SPRN_IBAT##n##U,RA; \
+ mtspr SPRN_IBAT##n##L,RB; \
+ beq 1f; \
+ lwz RA,(n*16)+8(reg); \
+ lwz RB,(n*16)+12(reg); \
+ mtspr SPRN_DBAT##n##U,RA; \
+ mtspr SPRN_DBAT##n##L,RB; \
+1:
+
+ .text
+ .stabs "arch/powerpc/kernel/",N_SO,0,0,0f
+ .stabs "head_32.S",N_SO,0,0,0f
+0:
+ .globl _stext
+_stext:
+
+/*
+ * _start is defined this way because the XCOFF loader in the OpenFirmware
+ * on the powermac expects the entry point to be a procedure descriptor.
+ */
+ .text
+ .globl _start
+_start:
+ /*
+ * These are here for legacy reasons, the kernel used to
+ * need to look like a coff function entry for the pmac
+ * but we're always started by some kind of bootloader now.
+ * -- Cort
+ */
+ nop /* used by __secondary_hold on prep (mtx) and chrp smp */
+ nop /* used by __secondary_hold on prep (mtx) and chrp smp */
+ nop
+
+/* PMAC
+ * Enter here with the kernel text, data and bss loaded starting at
+ * 0, running with virtual == physical mapping.
+ * r5 points to the prom entry point (the client interface handler
+ * address). Address translation is turned on, with the prom
+ * managing the hash table. Interrupts are disabled. The stack
+ * pointer (r1) points to just below the end of the half-meg region
+ * from 0x380000 - 0x400000, which is mapped in already.
+ *
+ * If we are booted from MacOS via BootX, we enter with the kernel
+ * image loaded somewhere, and the following values in registers:
+ * r3: 'BooX' (0x426f6f58)
+ * r4: virtual address of boot_infos_t
+ * r5: 0
+ *
+ * APUS
+ * r3: 'APUS'
+ * r4: physical address of memory base
+ * Linux/m68k style BootInfo structure at &_end.
+ *
+ * PREP
+ * This is jumped to on prep systems right after the kernel is relocated
+ * to its proper place in memory by the boot loader. The expected layout
+ * of the regs is:
+ * r3: ptr to residual data
+ * r4: initrd_start or if no initrd then 0
+ * r5: initrd_end - unused if r4 is 0
+ * r6: Start of command line string
+ * r7: End of command line string
+ *
+ * This just gets a minimal mmu environment setup so we can call
+ * start_here() to do the real work.
+ * -- Cort
+ */
+
+ .globl __start
+__start:
+/*
+ * We have to do any OF calls before we map ourselves to KERNELBASE,
+ * because OF may have I/O devices mapped into that area
+ * (particularly on CHRP).
+ */
+ cmpwi 0,r5,0
+ beq 1f
+ bl prom_init
+ trap
+
+1: mr r31,r3 /* save parameters */
+ mr r30,r4
+ li r24,0 /* cpu # */
+
+/*
+ * early_init() does the early machine identification and does
+ * the necessary low-level setup and clears the BSS
+ * -- Cort <cort@fsmlabs.com>
+ */
+ bl early_init
+
+#ifdef CONFIG_APUS
+/* On APUS the __va/__pa constants need to be set to the correct
+ * values before continuing.
+ */
+ mr r4,r30
+ bl fix_mem_constants
+#endif /* CONFIG_APUS */
+
+/* Switch MMU off, clear BATs and flush TLB. At this point, r3 contains
+ * the physical address we are running at, returned by early_init()
+ */
+ bl mmu_off
+__after_mmu_off:
+ bl clear_bats
+ bl flush_tlbs
+
+ bl initial_bats
+
+/*
+ * Call setup_cpu for CPU 0 and initialize 6xx Idle
+ */
+ bl reloc_offset
+ li r24,0 /* cpu# */
+ bl call_setup_cpu /* Call setup_cpu for this CPU */
+#ifdef CONFIG_6xx
+ bl reloc_offset
+ bl init_idle_6xx
+#endif /* CONFIG_6xx */
+
+
+#ifndef CONFIG_APUS
+/*
+ * We need to run with _start at physical address 0.
+ * On CHRP, we are loaded at 0x10000 since OF on CHRP uses
+ * the exception vectors at 0 (and therefore this copy
+ * overwrites OF's exception vectors with our own).
+ * The MMU is off at this point.
+ */
+ bl reloc_offset
+ mr r26,r3
+ addis r4,r3,KERNELBASE@h /* current address of _start */
+ cmpwi 0,r4,0 /* are we already running at 0? */
+ bne relocate_kernel
+#endif /* CONFIG_APUS */
+/*
+ * we now have the 1st 16M of ram mapped with the bats.
+ * prep needs the mmu to be turned on here, but pmac already has it on.
+ * this shouldn't bother the pmac since it just gets turned on again
+ * as we jump to our code at KERNELBASE. -- Cort
+ * Actually no, pmac doesn't have it on any more. BootX enters with MMU
+ * off, and in other cases, we now turn it off before changing BATs above.
+ */
+turn_on_mmu:
+ mfmsr r0
+ ori r0,r0,MSR_DR|MSR_IR
+ mtspr SPRN_SRR1,r0
+ lis r0,start_here@h
+ ori r0,r0,start_here@l
+ mtspr SPRN_SRR0,r0
+ SYNC
+ RFI /* enables MMU */
+
+/*
+ * We need __secondary_hold as a place to hold the other cpus on
+ * an SMP machine, even when we are running a UP kernel.
+ */
+ . = 0xc0 /* for prep bootloader */
+ li r3,1 /* MTX only has 1 cpu */
+ .globl __secondary_hold
+__secondary_hold:
+ /* tell the master we're here */
+ stw r3,__secondary_hold_acknowledge@l(0)
+#ifdef CONFIG_SMP
+100: lwz r4,0(0)
+ /* wait until we're told to start */
+ cmpw 0,r4,r3
+ bne 100b
+ /* our cpu # was at addr 0 - go */
+ mr r24,r3 /* cpu # */
+ b __secondary_start
+#else
+ b .
+#endif /* CONFIG_SMP */
+
+ .globl __secondary_hold_spinloop
+__secondary_hold_spinloop:
+ .long 0
+ .globl __secondary_hold_acknowledge
+__secondary_hold_acknowledge:
+ .long -1
+
+/*
+ * Exception entry code. This code runs with address translation
+ * turned off, i.e. using physical addresses.
+ * We assume sprg3 has the physical address of the current
+ * task's thread_struct.
+ */
+#define EXCEPTION_PROLOG \
+ mtspr SPRN_SPRG0,r10; \
+ mtspr SPRN_SPRG1,r11; \
+ mfcr r10; \
+ EXCEPTION_PROLOG_1; \
+ EXCEPTION_PROLOG_2
+
+#define EXCEPTION_PROLOG_1 \
+ mfspr r11,SPRN_SRR1; /* check whether user or kernel */ \
+ andi. r11,r11,MSR_PR; \
+ tophys(r11,r1); /* use tophys(r1) if kernel */ \
+ beq 1f; \
+ mfspr r11,SPRN_SPRG3; \
+ lwz r11,THREAD_INFO-THREAD(r11); \
+ addi r11,r11,THREAD_SIZE; \
+ tophys(r11,r11); \
+1: subi r11,r11,INT_FRAME_SIZE /* alloc exc. frame */
+
+
+#define EXCEPTION_PROLOG_2 \
+ CLR_TOP32(r11); \
+ stw r10,_CCR(r11); /* save registers */ \
+ stw r12,GPR12(r11); \
+ stw r9,GPR9(r11); \
+ mfspr r10,SPRN_SPRG0; \
+ stw r10,GPR10(r11); \
+ mfspr r12,SPRN_SPRG1; \
+ stw r12,GPR11(r11); \
+ mflr r10; \
+ stw r10,_LINK(r11); \
+ mfspr r12,SPRN_SRR0; \
+ mfspr r9,SPRN_SRR1; \
+ stw r1,GPR1(r11); \
+ stw r1,0(r11); \
+ tovirt(r1,r11); /* set new kernel sp */ \
+ li r10,MSR_KERNEL & ~(MSR_IR|MSR_DR); /* can take exceptions */ \
+ MTMSRD(r10); /* (except for mach check in rtas) */ \
+ stw r0,GPR0(r11); \
+ lis r10,0x7265; /* put exception frame marker */ \
+ addi r10,r10,0x6773; \
+ stw r10,8(r11); \
+ SAVE_4GPRS(3, r11); \
+ SAVE_2GPRS(7, r11)
+
+/*
+ * Note: code which follows this uses cr0.eq (set if from kernel),
+ * r11, r12 (SRR0), and r9 (SRR1).
+ *
+ * Note2: once we have set r1 we are in a position to take exceptions
+ * again, and we could thus set MSR:RI at that point.
+ */
+
+/*
+ * Exception vectors.
+ */
+#define EXCEPTION(n, label, hdlr, xfer) \
+ . = n; \
+label: \
+ EXCEPTION_PROLOG; \
+ addi r3,r1,STACK_FRAME_OVERHEAD; \
+ xfer(n, hdlr)
+
+#define EXC_XFER_TEMPLATE(n, hdlr, trap, copyee, tfer, ret) \
+ li r10,trap; \
+ stw r10,_TRAP(r11); \
+ li r10,MSR_KERNEL; \
+ copyee(r10, r9); \
+ bl tfer; \
+i##n: \
+ .long hdlr; \
+ .long ret
+
+#define COPY_EE(d, s) rlwimi d,s,0,16,16
+#define NOCOPY(d, s)
+
+#define EXC_XFER_STD(n, hdlr) \
+ EXC_XFER_TEMPLATE(n, hdlr, n, NOCOPY, transfer_to_handler_full, \
+ ret_from_except_full)
+
+#define EXC_XFER_LITE(n, hdlr) \
+ EXC_XFER_TEMPLATE(n, hdlr, n+1, NOCOPY, transfer_to_handler, \
+ ret_from_except)
+
+#define EXC_XFER_EE(n, hdlr) \
+ EXC_XFER_TEMPLATE(n, hdlr, n, COPY_EE, transfer_to_handler_full, \
+ ret_from_except_full)
+
+#define EXC_XFER_EE_LITE(n, hdlr) \
+ EXC_XFER_TEMPLATE(n, hdlr, n+1, COPY_EE, transfer_to_handler, \
+ ret_from_except)
+
+/* System reset */
+/* core99 pmac starts the seconary here by changing the vector, and
+ putting it back to what it was (unknown_exception) when done. */
+#if defined(CONFIG_GEMINI) && defined(CONFIG_SMP)
+ . = 0x100
+ b __secondary_start_gemini
+#else
+ EXCEPTION(0x100, Reset, unknown_exception, EXC_XFER_STD)
+#endif
+
+/* Machine check */
+/*
+ * On CHRP, this is complicated by the fact that we could get a
+ * machine check inside RTAS, and we have no guarantee that certain
+ * critical registers will have the values we expect. The set of
+ * registers that might have bad values includes all the GPRs
+ * and all the BATs. We indicate that we are in RTAS by putting
+ * a non-zero value, the address of the exception frame to use,
+ * in SPRG2. The machine check handler checks SPRG2 and uses its
+ * value if it is non-zero. If we ever needed to free up SPRG2,
+ * we could use a field in the thread_info or thread_struct instead.
+ * (Other exception handlers assume that r1 is a valid kernel stack
+ * pointer when we take an exception from supervisor mode.)
+ * -- paulus.
+ */
+ . = 0x200
+ mtspr SPRN_SPRG0,r10
+ mtspr SPRN_SPRG1,r11
+ mfcr r10
+#ifdef CONFIG_PPC_CHRP
+ mfspr r11,SPRN_SPRG2
+ cmpwi 0,r11,0
+ bne 7f
+#endif /* CONFIG_PPC_CHRP */
+ EXCEPTION_PROLOG_1
+7: EXCEPTION_PROLOG_2
+ addi r3,r1,STACK_FRAME_OVERHEAD
+#ifdef CONFIG_PPC_CHRP
+ mfspr r4,SPRN_SPRG2
+ cmpwi cr1,r4,0
+ bne cr1,1f
+#endif
+ EXC_XFER_STD(0x200, machine_check_exception)
+#ifdef CONFIG_PPC_CHRP
+1: b machine_check_in_rtas
+#endif
+
+/* Data access exception. */
+ . = 0x300
+DataAccess:
+ EXCEPTION_PROLOG
+ mfspr r10,SPRN_DSISR
+ andis. r0,r10,0xa470 /* weird error? */
+ bne 1f /* if not, try to put a PTE */
+ mfspr r4,SPRN_DAR /* into the hash table */
+ rlwinm r3,r10,32-15,21,21 /* DSISR_STORE -> _PAGE_RW */
+ bl hash_page
+1: stw r10,_DSISR(r11)
+ mr r5,r10
+ mfspr r4,SPRN_DAR
+ EXC_XFER_EE_LITE(0x300, handle_page_fault)
+
+
+/* Instruction access exception. */
+ . = 0x400
+InstructionAccess:
+ EXCEPTION_PROLOG
+ andis. r0,r9,0x4000 /* no pte found? */
+ beq 1f /* if so, try to put a PTE */
+ li r3,0 /* into the hash table */
+ mr r4,r12 /* SRR0 is fault address */
+ bl hash_page
+1: mr r4,r12
+ mr r5,r9
+ EXC_XFER_EE_LITE(0x400, handle_page_fault)
+
+/* External interrupt */
+ EXCEPTION(0x500, HardwareInterrupt, do_IRQ, EXC_XFER_LITE)
+
+/* Alignment exception */
+ . = 0x600
+Alignment:
+ EXCEPTION_PROLOG
+ mfspr r4,SPRN_DAR
+ stw r4,_DAR(r11)
+ mfspr r5,SPRN_DSISR
+ stw r5,_DSISR(r11)
+ addi r3,r1,STACK_FRAME_OVERHEAD
+ EXC_XFER_EE(0x600, alignment_exception)
+
+/* Program check exception */
+ EXCEPTION(0x700, ProgramCheck, program_check_exception, EXC_XFER_STD)
+
+/* Floating-point unavailable */
+ . = 0x800
+FPUnavailable:
+ EXCEPTION_PROLOG
+ bne load_up_fpu /* if from user, just load it up */
+ addi r3,r1,STACK_FRAME_OVERHEAD
+ EXC_XFER_EE_LITE(0x800, kernel_fp_unavailable_exception)
+
+/* Decrementer */
+ EXCEPTION(0x900, Decrementer, timer_interrupt, EXC_XFER_LITE)
+
+ EXCEPTION(0xa00, Trap_0a, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0xb00, Trap_0b, unknown_exception, EXC_XFER_EE)
+
+/* System call */
+ . = 0xc00
+SystemCall:
+ EXCEPTION_PROLOG
+ EXC_XFER_EE_LITE(0xc00, DoSyscall)
+
+/* Single step - not used on 601 */
+ EXCEPTION(0xd00, SingleStep, single_step_exception, EXC_XFER_STD)
+ EXCEPTION(0xe00, Trap_0e, unknown_exception, EXC_XFER_EE)
+
+/*
+ * The Altivec unavailable trap is at 0x0f20. Foo.
+ * We effectively remap it to 0x3000.
+ * We include an altivec unavailable exception vector even if
+ * not configured for Altivec, so that you can't panic a
+ * non-altivec kernel running on a machine with altivec just
+ * by executing an altivec instruction.
+ */
+ . = 0xf00
+ b Trap_0f
+
+ . = 0xf20
+ b AltiVecUnavailable
+
+Trap_0f:
+ EXCEPTION_PROLOG
+ addi r3,r1,STACK_FRAME_OVERHEAD
+ EXC_XFER_EE(0xf00, unknown_exception)
+
+/*
+ * Handle TLB miss for instruction on 603/603e.
+ * Note: we get an alternate set of r0 - r3 to use automatically.
+ */
+ . = 0x1000
+InstructionTLBMiss:
+/*
+ * r0: stored ctr
+ * r1: linux style pte ( later becomes ppc hardware pte )
+ * r2: ptr to linux-style pte
+ * r3: scratch
+ */
+ mfctr r0
+ /* Get PTE (linux-style) and check access */
+ mfspr r3,SPRN_IMISS
+ lis r1,KERNELBASE@h /* check if kernel address */
+ cmplw 0,r3,r1
+ mfspr r2,SPRN_SPRG3
+ li r1,_PAGE_USER|_PAGE_PRESENT /* low addresses tested as user */
+ lwz r2,PGDIR(r2)
+ blt+ 112f
+ lis r2,swapper_pg_dir@ha /* if kernel address, use */
+ addi r2,r2,swapper_pg_dir@l /* kernel page table */
+ mfspr r1,SPRN_SRR1 /* and MSR_PR bit from SRR1 */
+ rlwinm r1,r1,32-12,29,29 /* shift MSR_PR to _PAGE_USER posn */
+112: tophys(r2,r2)
+ rlwimi r2,r3,12,20,29 /* insert top 10 bits of address */
+ lwz r2,0(r2) /* get pmd entry */
+ rlwinm. r2,r2,0,0,19 /* extract address of pte page */
+ beq- InstructionAddressInvalid /* return if no mapping */
+ rlwimi r2,r3,22,20,29 /* insert next 10 bits of address */
+ lwz r3,0(r2) /* get linux-style pte */
+ andc. r1,r1,r3 /* check access & ~permission */
+ bne- InstructionAddressInvalid /* return if access not permitted */
+ ori r3,r3,_PAGE_ACCESSED /* set _PAGE_ACCESSED in pte */
+ /*
+ * NOTE! We are assuming this is not an SMP system, otherwise
+ * we would need to update the pte atomically with lwarx/stwcx.
+ */
+ stw r3,0(r2) /* update PTE (accessed bit) */
+ /* Convert linux-style PTE to low word of PPC-style PTE */
+ rlwinm r1,r3,32-10,31,31 /* _PAGE_RW -> PP lsb */
+ rlwinm r2,r3,32-7,31,31 /* _PAGE_DIRTY -> PP lsb */
+ and r1,r1,r2 /* writable if _RW and _DIRTY */
+ rlwimi r3,r3,32-1,30,30 /* _PAGE_USER -> PP msb */
+ rlwimi r3,r3,32-1,31,31 /* _PAGE_USER -> PP lsb */
+ ori r1,r1,0xe14 /* clear out reserved bits and M */
+ andc r1,r3,r1 /* PP = user? (rw&dirty? 2: 3): 0 */
+ mtspr SPRN_RPA,r1
+ mfspr r3,SPRN_IMISS
+ tlbli r3
+ mfspr r3,SPRN_SRR1 /* Need to restore CR0 */
+ mtcrf 0x80,r3
+ rfi
+InstructionAddressInvalid:
+ mfspr r3,SPRN_SRR1
+ rlwinm r1,r3,9,6,6 /* Get load/store bit */
+
+ addis r1,r1,0x2000
+ mtspr SPRN_DSISR,r1 /* (shouldn't be needed) */
+ mtctr r0 /* Restore CTR */
+ andi. r2,r3,0xFFFF /* Clear upper bits of SRR1 */
+ or r2,r2,r1
+ mtspr SPRN_SRR1,r2
+ mfspr r1,SPRN_IMISS /* Get failing address */
+ rlwinm. r2,r2,0,31,31 /* Check for little endian access */
+ rlwimi r2,r2,1,30,30 /* change 1 -> 3 */
+ xor r1,r1,r2
+ mtspr SPRN_DAR,r1 /* Set fault address */
+ mfmsr r0 /* Restore "normal" registers */
+ xoris r0,r0,MSR_TGPR>>16
+ mtcrf 0x80,r3 /* Restore CR0 */
+ mtmsr r0
+ b InstructionAccess
+
+/*
+ * Handle TLB miss for DATA Load operation on 603/603e
+ */
+ . = 0x1100
+DataLoadTLBMiss:
+/*
+ * r0: stored ctr
+ * r1: linux style pte ( later becomes ppc hardware pte )
+ * r2: ptr to linux-style pte
+ * r3: scratch
+ */
+ mfctr r0
+ /* Get PTE (linux-style) and check access */
+ mfspr r3,SPRN_DMISS
+ lis r1,KERNELBASE@h /* check if kernel address */
+ cmplw 0,r3,r1
+ mfspr r2,SPRN_SPRG3
+ li r1,_PAGE_USER|_PAGE_PRESENT /* low addresses tested as user */
+ lwz r2,PGDIR(r2)
+ blt+ 112f
+ lis r2,swapper_pg_dir@ha /* if kernel address, use */
+ addi r2,r2,swapper_pg_dir@l /* kernel page table */
+ mfspr r1,SPRN_SRR1 /* and MSR_PR bit from SRR1 */
+ rlwinm r1,r1,32-12,29,29 /* shift MSR_PR to _PAGE_USER posn */
+112: tophys(r2,r2)
+ rlwimi r2,r3,12,20,29 /* insert top 10 bits of address */
+ lwz r2,0(r2) /* get pmd entry */
+ rlwinm. r2,r2,0,0,19 /* extract address of pte page */
+ beq- DataAddressInvalid /* return if no mapping */
+ rlwimi r2,r3,22,20,29 /* insert next 10 bits of address */
+ lwz r3,0(r2) /* get linux-style pte */
+ andc. r1,r1,r3 /* check access & ~permission */
+ bne- DataAddressInvalid /* return if access not permitted */
+ ori r3,r3,_PAGE_ACCESSED /* set _PAGE_ACCESSED in pte */
+ /*
+ * NOTE! We are assuming this is not an SMP system, otherwise
+ * we would need to update the pte atomically with lwarx/stwcx.
+ */
+ stw r3,0(r2) /* update PTE (accessed bit) */
+ /* Convert linux-style PTE to low word of PPC-style PTE */
+ rlwinm r1,r3,32-10,31,31 /* _PAGE_RW -> PP lsb */
+ rlwinm r2,r3,32-7,31,31 /* _PAGE_DIRTY -> PP lsb */
+ and r1,r1,r2 /* writable if _RW and _DIRTY */
+ rlwimi r3,r3,32-1,30,30 /* _PAGE_USER -> PP msb */
+ rlwimi r3,r3,32-1,31,31 /* _PAGE_USER -> PP lsb */
+ ori r1,r1,0xe14 /* clear out reserved bits and M */
+ andc r1,r3,r1 /* PP = user? (rw&dirty? 2: 3): 0 */
+ mtspr SPRN_RPA,r1
+ mfspr r3,SPRN_DMISS
+ tlbld r3
+ mfspr r3,SPRN_SRR1 /* Need to restore CR0 */
+ mtcrf 0x80,r3
+ rfi
+DataAddressInvalid:
+ mfspr r3,SPRN_SRR1
+ rlwinm r1,r3,9,6,6 /* Get load/store bit */
+ addis r1,r1,0x2000
+ mtspr SPRN_DSISR,r1
+ mtctr r0 /* Restore CTR */
+ andi. r2,r3,0xFFFF /* Clear upper bits of SRR1 */
+ mtspr SPRN_SRR1,r2
+ mfspr r1,SPRN_DMISS /* Get failing address */
+ rlwinm. r2,r2,0,31,31 /* Check for little endian access */
+ beq 20f /* Jump if big endian */
+ xori r1,r1,3
+20: mtspr SPRN_DAR,r1 /* Set fault address */
+ mfmsr r0 /* Restore "normal" registers */
+ xoris r0,r0,MSR_TGPR>>16
+ mtcrf 0x80,r3 /* Restore CR0 */
+ mtmsr r0
+ b DataAccess
+
+/*
+ * Handle TLB miss for DATA Store on 603/603e
+ */
+ . = 0x1200
+DataStoreTLBMiss:
+/*
+ * r0: stored ctr
+ * r1: linux style pte ( later becomes ppc hardware pte )
+ * r2: ptr to linux-style pte
+ * r3: scratch
+ */
+ mfctr r0
+ /* Get PTE (linux-style) and check access */
+ mfspr r3,SPRN_DMISS
+ lis r1,KERNELBASE@h /* check if kernel address */
+ cmplw 0,r3,r1
+ mfspr r2,SPRN_SPRG3
+ li r1,_PAGE_RW|_PAGE_USER|_PAGE_PRESENT /* access flags */
+ lwz r2,PGDIR(r2)
+ blt+ 112f
+ lis r2,swapper_pg_dir@ha /* if kernel address, use */
+ addi r2,r2,swapper_pg_dir@l /* kernel page table */
+ mfspr r1,SPRN_SRR1 /* and MSR_PR bit from SRR1 */
+ rlwinm r1,r1,32-12,29,29 /* shift MSR_PR to _PAGE_USER posn */
+112: tophys(r2,r2)
+ rlwimi r2,r3,12,20,29 /* insert top 10 bits of address */
+ lwz r2,0(r2) /* get pmd entry */
+ rlwinm. r2,r2,0,0,19 /* extract address of pte page */
+ beq- DataAddressInvalid /* return if no mapping */
+ rlwimi r2,r3,22,20,29 /* insert next 10 bits of address */
+ lwz r3,0(r2) /* get linux-style pte */
+ andc. r1,r1,r3 /* check access & ~permission */
+ bne- DataAddressInvalid /* return if access not permitted */
+ ori r3,r3,_PAGE_ACCESSED|_PAGE_DIRTY
+ /*
+ * NOTE! We are assuming this is not an SMP system, otherwise
+ * we would need to update the pte atomically with lwarx/stwcx.
+ */
+ stw r3,0(r2) /* update PTE (accessed/dirty bits) */
+ /* Convert linux-style PTE to low word of PPC-style PTE */
+ rlwimi r3,r3,32-1,30,30 /* _PAGE_USER -> PP msb */
+ li r1,0xe15 /* clear out reserved bits and M */
+ andc r1,r3,r1 /* PP = user? 2: 0 */
+ mtspr SPRN_RPA,r1
+ mfspr r3,SPRN_DMISS
+ tlbld r3
+ mfspr r3,SPRN_SRR1 /* Need to restore CR0 */
+ mtcrf 0x80,r3
+ rfi
+
+#ifndef CONFIG_ALTIVEC
+#define altivec_assist_exception unknown_exception
+#endif
+
+ EXCEPTION(0x1300, Trap_13, instruction_breakpoint_exception, EXC_XFER_EE)
+ EXCEPTION(0x1400, SMI, SMIException, EXC_XFER_EE)
+ EXCEPTION(0x1500, Trap_15, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x1600, Trap_16, altivec_assist_exception, EXC_XFER_EE)
+ EXCEPTION(0x1700, Trap_17, TAUException, EXC_XFER_STD)
+ EXCEPTION(0x1800, Trap_18, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x1900, Trap_19, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x1a00, Trap_1a, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x1b00, Trap_1b, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x1c00, Trap_1c, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x1d00, Trap_1d, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x1e00, Trap_1e, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x1f00, Trap_1f, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x2000, RunMode, RunModeException, EXC_XFER_EE)
+ EXCEPTION(0x2100, Trap_21, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x2200, Trap_22, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x2300, Trap_23, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x2400, Trap_24, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x2500, Trap_25, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x2600, Trap_26, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x2700, Trap_27, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x2800, Trap_28, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x2900, Trap_29, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x2a00, Trap_2a, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x2b00, Trap_2b, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x2c00, Trap_2c, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x2d00, Trap_2d, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x2e00, Trap_2e, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x2f00, MOLTrampoline, unknown_exception, EXC_XFER_EE_LITE)
+
+ .globl mol_trampoline
+ .set mol_trampoline, i0x2f00
+
+ . = 0x3000
+
+AltiVecUnavailable:
+ EXCEPTION_PROLOG
+#ifdef CONFIG_ALTIVEC
+ bne load_up_altivec /* if from user, just load it up */
+#endif /* CONFIG_ALTIVEC */
+ EXC_XFER_EE_LITE(0xf20, altivec_unavailable_exception)
+
+#ifdef CONFIG_ALTIVEC
+/* Note that the AltiVec support is closely modeled after the FP
+ * support. Changes to one are likely to be applicable to the
+ * other! */
+load_up_altivec:
+/*
+ * Disable AltiVec for the task which had AltiVec previously,
+ * and save its AltiVec registers in its thread_struct.
+ * Enables AltiVec for use in the kernel on return.
+ * On SMP we know the AltiVec units are free, since we give it up every
+ * switch. -- Kumar
+ */
+ mfmsr r5
+ oris r5,r5,MSR_VEC@h
+ MTMSRD(r5) /* enable use of AltiVec now */
+ isync
+/*
+ * For SMP, we don't do lazy AltiVec switching because it just gets too
+ * horrendously complex, especially when a task switches from one CPU
+ * to another. Instead we call giveup_altivec in switch_to.
+ */
+#ifndef CONFIG_SMP
+ tophys(r6,0)
+ addis r3,r6,last_task_used_altivec@ha
+ lwz r4,last_task_used_altivec@l(r3)
+ cmpwi 0,r4,0
+ beq 1f
+ add r4,r4,r6
+ addi r4,r4,THREAD /* want THREAD of last_task_used_altivec */
+ SAVE_32VRS(0,r10,r4)
+ mfvscr vr0
+ li r10,THREAD_VSCR
+ stvx vr0,r10,r4
+ lwz r5,PT_REGS(r4)
+ add r5,r5,r6
+ lwz r4,_MSR-STACK_FRAME_OVERHEAD(r5)
+ lis r10,MSR_VEC@h
+ andc r4,r4,r10 /* disable altivec for previous task */
+ stw r4,_MSR-STACK_FRAME_OVERHEAD(r5)
+1:
+#endif /* CONFIG_SMP */
+ /* enable use of AltiVec after return */
+ oris r9,r9,MSR_VEC@h
+ mfspr r5,SPRN_SPRG3 /* current task's THREAD (phys) */
+ li r4,1
+ li r10,THREAD_VSCR
+ stw r4,THREAD_USED_VR(r5)
+ lvx vr0,r10,r5
+ mtvscr vr0
+ REST_32VRS(0,r10,r5)
+#ifndef CONFIG_SMP
+ subi r4,r5,THREAD
+ sub r4,r4,r6
+ stw r4,last_task_used_altivec@l(r3)
+#endif /* CONFIG_SMP */
+ /* restore registers and return */
+ /* we haven't used ctr or xer or lr */
+ b fast_exception_return
+
+/*
+ * AltiVec unavailable trap from kernel - print a message, but let
+ * the task use AltiVec in the kernel until it returns to user mode.
+ */
+KernelAltiVec:
+ lwz r3,_MSR(r1)
+ oris r3,r3,MSR_VEC@h
+ stw r3,_MSR(r1) /* enable use of AltiVec after return */
+ lis r3,87f@h
+ ori r3,r3,87f@l
+ mr r4,r2 /* current */
+ lwz r5,_NIP(r1)
+ bl printk
+ b ret_from_except
+87: .string "AltiVec used in kernel (task=%p, pc=%x) \n"
+ .align 4,0
+
+/*
+ * giveup_altivec(tsk)
+ * Disable AltiVec for the task given as the argument,
+ * and save the AltiVec registers in its thread_struct.
+ * Enables AltiVec for use in the kernel on return.
+ */
+
+ .globl giveup_altivec
+giveup_altivec:
+ mfmsr r5
+ oris r5,r5,MSR_VEC@h
+ SYNC
+ MTMSRD(r5) /* enable use of AltiVec now */
+ isync
+ cmpwi 0,r3,0
+ beqlr- /* if no previous owner, done */
+ addi r3,r3,THREAD /* want THREAD of task */
+ lwz r5,PT_REGS(r3)
+ cmpwi 0,r5,0
+ SAVE_32VRS(0, r4, r3)
+ mfvscr vr0
+ li r4,THREAD_VSCR
+ stvx vr0,r4,r3
+ beq 1f
+ lwz r4,_MSR-STACK_FRAME_OVERHEAD(r5)
+ lis r3,MSR_VEC@h
+ andc r4,r4,r3 /* disable AltiVec for previous task */
+ stw r4,_MSR-STACK_FRAME_OVERHEAD(r5)
+1:
+#ifndef CONFIG_SMP
+ li r5,0
+ lis r4,last_task_used_altivec@ha
+ stw r5,last_task_used_altivec@l(r4)
+#endif /* CONFIG_SMP */
+ blr
+#endif /* CONFIG_ALTIVEC */
+
+/*
+ * This code is jumped to from the startup code to copy
+ * the kernel image to physical address 0.
+ */
+relocate_kernel:
+ addis r9,r26,klimit@ha /* fetch klimit */
+ lwz r25,klimit@l(r9)
+ addis r25,r25,-KERNELBASE@h
+ li r3,0 /* Destination base address */
+ li r6,0 /* Destination offset */
+ li r5,0x4000 /* # bytes of memory to copy */
+ bl copy_and_flush /* copy the first 0x4000 bytes */
+ addi r0,r3,4f@l /* jump to the address of 4f */
+ mtctr r0 /* in copy and do the rest. */
+ bctr /* jump to the copy */
+4: mr r5,r25
+ bl copy_and_flush /* copy the rest */
+ b turn_on_mmu
+
+/*
+ * Copy routine used to copy the kernel to start at physical address 0
+ * and flush and invalidate the caches as needed.
+ * r3 = dest addr, r4 = source addr, r5 = copy limit, r6 = start offset
+ * on exit, r3, r4, r5 are unchanged, r6 is updated to be >= r5.
+ */
+_GLOBAL(copy_and_flush)
+ addi r5,r5,-4
+ addi r6,r6,-4
+4: li r0,L1_CACHE_BYTES/4
+ mtctr r0
+3: addi r6,r6,4 /* copy a cache line */
+ lwzx r0,r6,r4
+ stwx r0,r6,r3
+ bdnz 3b
+ dcbst r6,r3 /* write it to memory */
+ sync
+ icbi r6,r3 /* flush the icache line */
+ cmplw 0,r6,r5
+ blt 4b
+ sync /* additional sync needed on g4 */
+ isync
+ addi r5,r5,4
+ addi r6,r6,4
+ blr
+
+#ifdef CONFIG_APUS
+/*
+ * On APUS the physical base address of the kernel is not known at compile
+ * time, which means the __pa/__va constants used are incorrect. In the
+ * __init section is recorded the virtual addresses of instructions using
+ * these constants, so all that has to be done is fix these before
+ * continuing the kernel boot.
+ *
+ * r4 = The physical address of the kernel base.
+ */
+fix_mem_constants:
+ mr r10,r4
+ addis r10,r10,-KERNELBASE@h /* virt_to_phys constant */
+ neg r11,r10 /* phys_to_virt constant */
+
+ lis r12,__vtop_table_begin@h
+ ori r12,r12,__vtop_table_begin@l
+ add r12,r12,r10 /* table begin phys address */
+ lis r13,__vtop_table_end@h
+ ori r13,r13,__vtop_table_end@l
+ add r13,r13,r10 /* table end phys address */
+ subi r12,r12,4
+ subi r13,r13,4
+1: lwzu r14,4(r12) /* virt address of instruction */
+ add r14,r14,r10 /* phys address of instruction */
+ lwz r15,0(r14) /* instruction, now insert top */
+ rlwimi r15,r10,16,16,31 /* half of vp const in low half */
+ stw r15,0(r14) /* of instruction and restore. */
+ dcbst r0,r14 /* write it to memory */
+ sync
+ icbi r0,r14 /* flush the icache line */
+ cmpw r12,r13
+ bne 1b
+ sync /* additional sync needed on g4 */
+ isync
+
+/*
+ * Map the memory where the exception handlers will
+ * be copied to when hash constants have been patched.
+ */
+#ifdef CONFIG_APUS_FAST_EXCEPT
+ lis r8,0xfff0
+#else
+ lis r8,0
+#endif
+ ori r8,r8,0x2 /* 128KB, supervisor */
+ mtspr SPRN_DBAT3U,r8
+ mtspr SPRN_DBAT3L,r8
+
+ lis r12,__ptov_table_begin@h
+ ori r12,r12,__ptov_table_begin@l
+ add r12,r12,r10 /* table begin phys address */
+ lis r13,__ptov_table_end@h
+ ori r13,r13,__ptov_table_end@l
+ add r13,r13,r10 /* table end phys address */
+ subi r12,r12,4
+ subi r13,r13,4
+1: lwzu r14,4(r12) /* virt address of instruction */
+ add r14,r14,r10 /* phys address of instruction */
+ lwz r15,0(r14) /* instruction, now insert top */
+ rlwimi r15,r11,16,16,31 /* half of pv const in low half*/
+ stw r15,0(r14) /* of instruction and restore. */
+ dcbst r0,r14 /* write it to memory */
+ sync
+ icbi r0,r14 /* flush the icache line */
+ cmpw r12,r13
+ bne 1b
+
+ sync /* additional sync needed on g4 */
+ isync /* No speculative loading until now */
+ blr
+
+/***********************************************************************
+ * Please note that on APUS the exception handlers are located at the
+ * physical address 0xfff0000. For this reason, the exception handlers
+ * cannot use relative branches to access the code below.
+ ***********************************************************************/
+#endif /* CONFIG_APUS */
+
+#ifdef CONFIG_SMP
+#ifdef CONFIG_GEMINI
+ .globl __secondary_start_gemini
+__secondary_start_gemini:
+ mfspr r4,SPRN_HID0
+ ori r4,r4,HID0_ICFI
+ li r3,0
+ ori r3,r3,HID0_ICE
+ andc r4,r4,r3
+ mtspr SPRN_HID0,r4
+ sync
+ b __secondary_start
+#endif /* CONFIG_GEMINI */
+
+ .globl __secondary_start_pmac_0
+__secondary_start_pmac_0:
+ /* NB the entries for cpus 0, 1, 2 must each occupy 8 bytes. */
+ li r24,0
+ b 1f
+ li r24,1
+ b 1f
+ li r24,2
+ b 1f
+ li r24,3
+1:
+ /* on powersurge, we come in here with IR=0 and DR=1, and DBAT 0
+ set to map the 0xf0000000 - 0xffffffff region */
+ mfmsr r0
+ rlwinm r0,r0,0,28,26 /* clear DR (0x10) */
+ SYNC
+ mtmsr r0
+ isync
+
+ .globl __secondary_start
+__secondary_start:
+ /* Copy some CPU settings from CPU 0 */
+ bl __restore_cpu_setup
+
+ lis r3,-KERNELBASE@h
+ mr r4,r24
+ bl call_setup_cpu /* Call setup_cpu for this CPU */
+#ifdef CONFIG_6xx
+ lis r3,-KERNELBASE@h
+ bl init_idle_6xx
+#endif /* CONFIG_6xx */
+
+ /* get current_thread_info and current */
+ lis r1,secondary_ti@ha
+ tophys(r1,r1)
+ lwz r1,secondary_ti@l(r1)
+ tophys(r2,r1)
+ lwz r2,TI_TASK(r2)
+
+ /* stack */
+ addi r1,r1,THREAD_SIZE-STACK_FRAME_OVERHEAD
+ li r0,0
+ tophys(r3,r1)
+ stw r0,0(r3)
+
+ /* load up the MMU */
+ bl load_up_mmu
+
+ /* ptr to phys current thread */
+ tophys(r4,r2)
+ addi r4,r4,THREAD /* phys address of our thread_struct */
+ CLR_TOP32(r4)
+ mtspr SPRN_SPRG3,r4
+ li r3,0
+ mtspr SPRN_SPRG2,r3 /* 0 => not in RTAS */
+
+ /* enable MMU and jump to start_secondary */
+ li r4,MSR_KERNEL
+ FIX_SRR1(r4,r5)
+ lis r3,start_secondary@h
+ ori r3,r3,start_secondary@l
+ mtspr SPRN_SRR0,r3
+ mtspr SPRN_SRR1,r4
+ SYNC
+ RFI
+#endif /* CONFIG_SMP */
+
+/*
+ * Those generic dummy functions are kept for CPUs not
+ * included in CONFIG_6xx
+ */
+#if !defined(CONFIG_6xx)
+_GLOBAL(__save_cpu_setup)
+ blr
+_GLOBAL(__restore_cpu_setup)
+ blr
+#endif /* !defined(CONFIG_6xx) */
+
+
+/*
+ * Load stuff into the MMU. Intended to be called with
+ * IR=0 and DR=0.
+ */
+load_up_mmu:
+ sync /* Force all PTE updates to finish */
+ isync
+ tlbia /* Clear all TLB entries */
+ sync /* wait for tlbia/tlbie to finish */
+ TLBSYNC /* ... on all CPUs */
+ /* Load the SDR1 register (hash table base & size) */
+ lis r6,_SDR1@ha
+ tophys(r6,r6)
+ lwz r6,_SDR1@l(r6)
+ mtspr SPRN_SDR1,r6
+ li r0,16 /* load up segment register values */
+ mtctr r0 /* for context 0 */
+ lis r3,0x2000 /* Ku = 1, VSID = 0 */
+ li r4,0
+3: mtsrin r3,r4
+ addi r3,r3,0x111 /* increment VSID */
+ addis r4,r4,0x1000 /* address of next segment */
+ bdnz 3b
+
+/* Load the BAT registers with the values set up by MMU_init.
+ MMU_init takes care of whether we're on a 601 or not. */
+ mfpvr r3
+ srwi r3,r3,16
+ cmpwi r3,1
+ lis r3,BATS@ha
+ addi r3,r3,BATS@l
+ tophys(r3,r3)
+ LOAD_BAT(0,r3,r4,r5)
+ LOAD_BAT(1,r3,r4,r5)
+ LOAD_BAT(2,r3,r4,r5)
+ LOAD_BAT(3,r3,r4,r5)
+
+ blr
+
+/*
+ * This is where the main kernel code starts.
+ */
+start_here:
+ /* ptr to current */
+ lis r2,init_task@h
+ ori r2,r2,init_task@l
+ /* Set up for using our exception vectors */
+ /* ptr to phys current thread */
+ tophys(r4,r2)
+ addi r4,r4,THREAD /* init task's THREAD */
+ CLR_TOP32(r4)
+ mtspr SPRN_SPRG3,r4
+ li r3,0
+ mtspr SPRN_SPRG2,r3 /* 0 => not in RTAS */
+
+ /* stack */
+ lis r1,init_thread_union@ha
+ addi r1,r1,init_thread_union@l
+ li r0,0
+ stwu r0,THREAD_SIZE-STACK_FRAME_OVERHEAD(r1)
+/*
+ * Do early platform-specific initialization,
+ * and set up the MMU.
+ */
+ mr r3,r31
+ mr r4,r30
+ bl machine_init
+ bl MMU_init
+
+#ifdef CONFIG_APUS
+ /* Copy exception code to exception vector base on APUS. */
+ lis r4,KERNELBASE@h
+#ifdef CONFIG_APUS_FAST_EXCEPT
+ lis r3,0xfff0 /* Copy to 0xfff00000 */
+#else
+ lis r3,0 /* Copy to 0x00000000 */
+#endif
+ li r5,0x4000 /* # bytes of memory to copy */
+ li r6,0
+ bl copy_and_flush /* copy the first 0x4000 bytes */
+#endif /* CONFIG_APUS */
+
+/*
+ * Go back to running unmapped so we can load up new values
+ * for SDR1 (hash table pointer) and the segment registers
+ * and change to using our exception vectors.
+ */
+ lis r4,2f@h
+ ori r4,r4,2f@l
+ tophys(r4,r4)
+ li r3,MSR_KERNEL & ~(MSR_IR|MSR_DR)
+ FIX_SRR1(r3,r5)
+ mtspr SPRN_SRR0,r4
+ mtspr SPRN_SRR1,r3
+ SYNC
+ RFI
+/* Load up the kernel context */
+2: bl load_up_mmu
+
+#ifdef CONFIG_BDI_SWITCH
+ /* Add helper information for the Abatron bdiGDB debugger.
+ * We do this here because we know the mmu is disabled, and
+ * will be enabled for real in just a few instructions.
+ */
+ lis r5, abatron_pteptrs@h
+ ori r5, r5, abatron_pteptrs@l
+ stw r5, 0xf0(r0) /* This much match your Abatron config */
+ lis r6, swapper_pg_dir@h
+ ori r6, r6, swapper_pg_dir@l
+ tophys(r5, r5)
+ stw r6, 0(r5)
+#endif /* CONFIG_BDI_SWITCH */
+
+/* Now turn on the MMU for real! */
+ li r4,MSR_KERNEL
+ FIX_SRR1(r4,r5)
+ lis r3,start_kernel@h
+ ori r3,r3,start_kernel@l
+ mtspr SPRN_SRR0,r3
+ mtspr SPRN_SRR1,r4
+ SYNC
+ RFI
+
+/*
+ * Set up the segment registers for a new context.
+ */
+_GLOBAL(set_context)
+ mulli r3,r3,897 /* multiply context by skew factor */
+ rlwinm r3,r3,4,8,27 /* VSID = (context & 0xfffff) << 4 */
+ addis r3,r3,0x6000 /* Set Ks, Ku bits */
+ li r0,NUM_USER_SEGMENTS
+ mtctr r0
+
+#ifdef CONFIG_BDI_SWITCH
+ /* Context switch the PTE pointer for the Abatron BDI2000.
+ * The PGDIR is passed as second argument.
+ */
+ lis r5, KERNELBASE@h
+ lwz r5, 0xf0(r5)
+ stw r4, 0x4(r5)
+#endif
+ li r4,0
+ isync
+3:
+ mtsrin r3,r4
+ addi r3,r3,0x111 /* next VSID */
+ rlwinm r3,r3,0,8,3 /* clear out any overflow from VSID field */
+ addis r4,r4,0x1000 /* address of next segment */
+ bdnz 3b
+ sync
+ isync
+ blr
+
+/*
+ * An undocumented "feature" of 604e requires that the v bit
+ * be cleared before changing BAT values.
+ *
+ * Also, newer IBM firmware does not clear bat3 and 4 so
+ * this makes sure it's done.
+ * -- Cort
+ */
+clear_bats:
+ li r10,0
+ mfspr r9,SPRN_PVR
+ rlwinm r9,r9,16,16,31 /* r9 = 1 for 601, 4 for 604 */
+ cmpwi r9, 1
+ beq 1f
+
+ mtspr SPRN_DBAT0U,r10
+ mtspr SPRN_DBAT0L,r10
+ mtspr SPRN_DBAT1U,r10
+ mtspr SPRN_DBAT1L,r10
+ mtspr SPRN_DBAT2U,r10
+ mtspr SPRN_DBAT2L,r10
+ mtspr SPRN_DBAT3U,r10
+ mtspr SPRN_DBAT3L,r10
+1:
+ mtspr SPRN_IBAT0U,r10
+ mtspr SPRN_IBAT0L,r10
+ mtspr SPRN_IBAT1U,r10
+ mtspr SPRN_IBAT1L,r10
+ mtspr SPRN_IBAT2U,r10
+ mtspr SPRN_IBAT2L,r10
+ mtspr SPRN_IBAT3U,r10
+ mtspr SPRN_IBAT3L,r10
+BEGIN_FTR_SECTION
+ /* Here's a tweak: at this point, CPU setup have
+ * not been called yet, so HIGH_BAT_EN may not be
+ * set in HID0 for the 745x processors. However, it
+ * seems that doesn't affect our ability to actually
+ * write to these SPRs.
+ */
+ mtspr SPRN_DBAT4U,r10
+ mtspr SPRN_DBAT4L,r10
+ mtspr SPRN_DBAT5U,r10
+ mtspr SPRN_DBAT5L,r10
+ mtspr SPRN_DBAT6U,r10
+ mtspr SPRN_DBAT6L,r10
+ mtspr SPRN_DBAT7U,r10
+ mtspr SPRN_DBAT7L,r10
+ mtspr SPRN_IBAT4U,r10
+ mtspr SPRN_IBAT4L,r10
+ mtspr SPRN_IBAT5U,r10
+ mtspr SPRN_IBAT5L,r10
+ mtspr SPRN_IBAT6U,r10
+ mtspr SPRN_IBAT6L,r10
+ mtspr SPRN_IBAT7U,r10
+ mtspr SPRN_IBAT7L,r10
+END_FTR_SECTION_IFSET(CPU_FTR_HAS_HIGH_BATS)
+ blr
+
+flush_tlbs:
+ lis r10, 0x40
+1: addic. r10, r10, -0x1000
+ tlbie r10
+ blt 1b
+ sync
+ blr
+
+mmu_off:
+ addi r4, r3, __after_mmu_off - _start
+ mfmsr r3
+ andi. r0,r3,MSR_DR|MSR_IR /* MMU enabled? */
+ beqlr
+ andc r3,r3,r0
+ mtspr SPRN_SRR0,r4
+ mtspr SPRN_SRR1,r3
+ sync
+ RFI
+
+/*
+ * Use the first pair of BAT registers to map the 1st 16MB
+ * of RAM to KERNELBASE. From this point on we can't safely
+ * call OF any more.
+ */
+initial_bats:
+ lis r11,KERNELBASE@h
+ mfspr r9,SPRN_PVR
+ rlwinm r9,r9,16,16,31 /* r9 = 1 for 601, 4 for 604 */
+ cmpwi 0,r9,1
+ bne 4f
+ ori r11,r11,4 /* set up BAT registers for 601 */
+ li r8,0x7f /* valid, block length = 8MB */
+ oris r9,r11,0x800000@h /* set up BAT reg for 2nd 8M */
+ oris r10,r8,0x800000@h /* set up BAT reg for 2nd 8M */
+ mtspr SPRN_IBAT0U,r11 /* N.B. 601 has valid bit in */
+ mtspr SPRN_IBAT0L,r8 /* lower BAT register */
+ mtspr SPRN_IBAT1U,r9
+ mtspr SPRN_IBAT1L,r10
+ isync
+ blr
+
+4: tophys(r8,r11)
+#ifdef CONFIG_SMP
+ ori r8,r8,0x12 /* R/W access, M=1 */
+#else
+ ori r8,r8,2 /* R/W access */
+#endif /* CONFIG_SMP */
+#ifdef CONFIG_APUS
+ ori r11,r11,BL_8M<<2|0x2 /* set up 8MB BAT registers for 604 */
+#else
+ ori r11,r11,BL_256M<<2|0x2 /* set up BAT registers for 604 */
+#endif /* CONFIG_APUS */
+
+ mtspr SPRN_DBAT0L,r8 /* N.B. 6xx (not 601) have valid */
+ mtspr SPRN_DBAT0U,r11 /* bit in upper BAT register */
+ mtspr SPRN_IBAT0L,r8
+ mtspr SPRN_IBAT0U,r11
+ isync
+ blr
+
+
+#ifdef CONFIG_8260
+/* Jump into the system reset for the rom.
+ * We first disable the MMU, and then jump to the ROM reset address.
+ *
+ * r3 is the board info structure, r4 is the location for starting.
+ * I use this for building a small kernel that can load other kernels,
+ * rather than trying to write or rely on a rom monitor that can tftp load.
+ */
+ .globl m8260_gorom
+m8260_gorom:
+ mfmsr r0
+ rlwinm r0,r0,0,17,15 /* clear MSR_EE in r0 */
+ sync
+ mtmsr r0
+ sync
+ mfspr r11, SPRN_HID0
+ lis r10, 0
+ ori r10,r10,HID0_ICE|HID0_DCE
+ andc r11, r11, r10
+ mtspr SPRN_HID0, r11
+ isync
+ li r5, MSR_ME|MSR_RI
+ lis r6,2f@h
+ addis r6,r6,-KERNELBASE@h
+ ori r6,r6,2f@l
+ mtspr SPRN_SRR0,r6
+ mtspr SPRN_SRR1,r5
+ isync
+ sync
+ rfi
+2:
+ mtlr r4
+ blr
+#endif
+
+
+/*
+ * We put a few things here that have to be page-aligned.
+ * This stuff goes at the beginning of the data segment,
+ * which is page-aligned.
+ */
+ .data
+ .globl sdata
+sdata:
+ .globl empty_zero_page
+empty_zero_page:
+ .space 4096
+
+ .globl swapper_pg_dir
+swapper_pg_dir:
+ .space 4096
+
+/*
+ * This space gets a copy of optional info passed to us by the bootstrap
+ * Used to pass parameters into the kernel like root=/dev/sda1, etc.
+ */
+ .globl cmd_line
+cmd_line:
+ .space 512
+
+ .globl intercept_table
+intercept_table:
+ .long 0, 0, i0x200, i0x300, i0x400, 0, i0x600, i0x700
+ .long i0x800, 0, 0, 0, 0, i0xd00, 0, 0
+ .long 0, 0, 0, i0x1300, 0, 0, 0, 0
+ .long 0, 0, 0, 0, 0, 0, 0, 0
+ .long 0, 0, 0, 0, 0, 0, 0, 0
+ .long 0, 0, 0, 0, 0, 0, 0, 0
+
+/* Room for two PTE pointers, usually the kernel and current user pointers
+ * to their respective root page table.
+ */
+abatron_pteptrs:
+ .space 8
diff --git a/arch/powerpc/kernel/head_44x.S b/arch/powerpc/kernel/head_44x.S
new file mode 100644
index 000000000000..8b49679fad54
--- /dev/null
+++ b/arch/powerpc/kernel/head_44x.S
@@ -0,0 +1,782 @@
+/*
+ * arch/ppc/kernel/head_44x.S
+ *
+ * Kernel execution entry point code.
+ *
+ * Copyright (c) 1995-1996 Gary Thomas <gdt@linuxppc.org>
+ * Initial PowerPC version.
+ * Copyright (c) 1996 Cort Dougan <cort@cs.nmt.edu>
+ * Rewritten for PReP
+ * Copyright (c) 1996 Paul Mackerras <paulus@cs.anu.edu.au>
+ * Low-level exception handers, MMU support, and rewrite.
+ * Copyright (c) 1997 Dan Malek <dmalek@jlc.net>
+ * PowerPC 8xx modifications.
+ * Copyright (c) 1998-1999 TiVo, Inc.
+ * PowerPC 403GCX modifications.
+ * Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu>
+ * PowerPC 403GCX/405GP modifications.
+ * Copyright 2000 MontaVista Software Inc.
+ * PPC405 modifications
+ * PowerPC 403GCX/405GP modifications.
+ * Author: MontaVista Software, Inc.
+ * frank_rowand@mvista.com or source@mvista.com
+ * debbie_chu@mvista.com
+ * Copyright 2002-2005 MontaVista Software, Inc.
+ * PowerPC 44x support, Matt Porter <mporter@kernel.crashing.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/config.h>
+#include <asm/processor.h>
+#include <asm/page.h>
+#include <asm/mmu.h>
+#include <asm/pgtable.h>
+#include <asm/ibm4xx.h>
+#include <asm/ibm44x.h>
+#include <asm/cputable.h>
+#include <asm/thread_info.h>
+#include <asm/ppc_asm.h>
+#include <asm/asm-offsets.h>
+#include "head_booke.h"
+
+
+/* As with the other PowerPC ports, it is expected that when code
+ * execution begins here, the following registers contain valid, yet
+ * optional, information:
+ *
+ * r3 - Board info structure pointer (DRAM, frequency, MAC address, etc.)
+ * r4 - Starting address of the init RAM disk
+ * r5 - Ending address of the init RAM disk
+ * r6 - Start of kernel command line string (e.g. "mem=128")
+ * r7 - End of kernel command line string
+ *
+ */
+ .text
+_GLOBAL(_stext)
+_GLOBAL(_start)
+ /*
+ * Reserve a word at a fixed location to store the address
+ * of abatron_pteptrs
+ */
+ nop
+/*
+ * Save parameters we are passed
+ */
+ mr r31,r3
+ mr r30,r4
+ mr r29,r5
+ mr r28,r6
+ mr r27,r7
+ li r24,0 /* CPU number */
+
+/*
+ * Set up the initial MMU state
+ *
+ * We are still executing code at the virtual address
+ * mappings set by the firmware for the base of RAM.
+ *
+ * We first invalidate all TLB entries but the one
+ * we are running from. We then load the KERNELBASE
+ * mappings so we can begin to use kernel addresses
+ * natively and so the interrupt vector locations are
+ * permanently pinned (necessary since Book E
+ * implementations always have translation enabled).
+ *
+ * TODO: Use the known TLB entry we are running from to
+ * determine which physical region we are located
+ * in. This can be used to determine where in RAM
+ * (on a shared CPU system) or PCI memory space
+ * (on a DRAMless system) we are located.
+ * For now, we assume a perfect world which means
+ * we are located at the base of DRAM (physical 0).
+ */
+
+/*
+ * Search TLB for entry that we are currently using.
+ * Invalidate all entries but the one we are using.
+ */
+ /* Load our current PID->MMUCR TID and MSR IS->MMUCR STS */
+ mfspr r3,SPRN_PID /* Get PID */
+ mfmsr r4 /* Get MSR */
+ andi. r4,r4,MSR_IS@l /* TS=1? */
+ beq wmmucr /* If not, leave STS=0 */
+ oris r3,r3,PPC44x_MMUCR_STS@h /* Set STS=1 */
+wmmucr: mtspr SPRN_MMUCR,r3 /* Put MMUCR */
+ sync
+
+ bl invstr /* Find our address */
+invstr: mflr r5 /* Make it accessible */
+ tlbsx r23,0,r5 /* Find entry we are in */
+ li r4,0 /* Start at TLB entry 0 */
+ li r3,0 /* Set PAGEID inval value */
+1: cmpw r23,r4 /* Is this our entry? */
+ beq skpinv /* If so, skip the inval */
+ tlbwe r3,r4,PPC44x_TLB_PAGEID /* If not, inval the entry */
+skpinv: addi r4,r4,1 /* Increment */
+ cmpwi r4,64 /* Are we done? */
+ bne 1b /* If not, repeat */
+ isync /* If so, context change */
+
+/*
+ * Configure and load pinned entry into TLB slot 63.
+ */
+
+ lis r3,KERNELBASE@h /* Load the kernel virtual address */
+ ori r3,r3,KERNELBASE@l
+
+ /* Kernel is at the base of RAM */
+ li r4, 0 /* Load the kernel physical address */
+
+ /* Load the kernel PID = 0 */
+ li r0,0
+ mtspr SPRN_PID,r0
+ sync
+
+ /* Initialize MMUCR */
+ li r5,0
+ mtspr SPRN_MMUCR,r5
+ sync
+
+ /* pageid fields */
+ clrrwi r3,r3,10 /* Mask off the effective page number */
+ ori r3,r3,PPC44x_TLB_VALID | PPC44x_TLB_256M
+
+ /* xlat fields */
+ clrrwi r4,r4,10 /* Mask off the real page number */
+ /* ERPN is 0 for first 4GB page */
+
+ /* attrib fields */
+ /* Added guarded bit to protect against speculative loads/stores */
+ li r5,0
+ ori r5,r5,(PPC44x_TLB_SW | PPC44x_TLB_SR | PPC44x_TLB_SX | PPC44x_TLB_G)
+
+ li r0,63 /* TLB slot 63 */
+
+ tlbwe r3,r0,PPC44x_TLB_PAGEID /* Load the pageid fields */
+ tlbwe r4,r0,PPC44x_TLB_XLAT /* Load the translation fields */
+ tlbwe r5,r0,PPC44x_TLB_ATTRIB /* Load the attrib/access fields */
+
+ /* Force context change */
+ mfmsr r0
+ mtspr SPRN_SRR1, r0
+ lis r0,3f@h
+ ori r0,r0,3f@l
+ mtspr SPRN_SRR0,r0
+ sync
+ rfi
+
+ /* If necessary, invalidate original entry we used */
+3: cmpwi r23,63
+ beq 4f
+ li r6,0
+ tlbwe r6,r23,PPC44x_TLB_PAGEID
+ isync
+
+4:
+#ifdef CONFIG_SERIAL_TEXT_DEBUG
+ /*
+ * Add temporary UART mapping for early debug.
+ * We can map UART registers wherever we want as long as they don't
+ * interfere with other system mappings (e.g. with pinned entries).
+ * For an example of how we handle this - see ocotea.h. --ebs
+ */
+ /* pageid fields */
+ lis r3,UART0_IO_BASE@h
+ ori r3,r3,PPC44x_TLB_VALID | PPC44x_TLB_4K
+
+ /* xlat fields */
+ lis r4,UART0_PHYS_IO_BASE@h /* RPN depends on SoC */
+#ifndef CONFIG_440EP
+ ori r4,r4,0x0001 /* ERPN is 1 for second 4GB page */
+#endif
+
+ /* attrib fields */
+ li r5,0
+ ori r5,r5,(PPC44x_TLB_SW | PPC44x_TLB_SR | PPC44x_TLB_I | PPC44x_TLB_G)
+
+ li r0,0 /* TLB slot 0 */
+
+ tlbwe r3,r0,PPC44x_TLB_PAGEID /* Load the pageid fields */
+ tlbwe r4,r0,PPC44x_TLB_XLAT /* Load the translation fields */
+ tlbwe r5,r0,PPC44x_TLB_ATTRIB /* Load the attrib/access fields */
+
+ /* Force context change */
+ isync
+#endif /* CONFIG_SERIAL_TEXT_DEBUG */
+
+ /* Establish the interrupt vector offsets */
+ SET_IVOR(0, CriticalInput);
+ SET_IVOR(1, MachineCheck);
+ SET_IVOR(2, DataStorage);
+ SET_IVOR(3, InstructionStorage);
+ SET_IVOR(4, ExternalInput);
+ SET_IVOR(5, Alignment);
+ SET_IVOR(6, Program);
+ SET_IVOR(7, FloatingPointUnavailable);
+ SET_IVOR(8, SystemCall);
+ SET_IVOR(9, AuxillaryProcessorUnavailable);
+ SET_IVOR(10, Decrementer);
+ SET_IVOR(11, FixedIntervalTimer);
+ SET_IVOR(12, WatchdogTimer);
+ SET_IVOR(13, DataTLBError);
+ SET_IVOR(14, InstructionTLBError);
+ SET_IVOR(15, Debug);
+
+ /* Establish the interrupt vector base */
+ lis r4,interrupt_base@h /* IVPR only uses the high 16-bits */
+ mtspr SPRN_IVPR,r4
+
+#ifdef CONFIG_440EP
+ /* Clear DAPUIB flag in CCR0 (enable APU between CPU and FPU) */
+ mfspr r2,SPRN_CCR0
+ lis r3,0xffef
+ ori r3,r3,0xffff
+ and r2,r2,r3
+ mtspr SPRN_CCR0,r2
+ isync
+#endif
+
+ /*
+ * This is where the main kernel code starts.
+ */
+
+ /* ptr to current */
+ lis r2,init_task@h
+ ori r2,r2,init_task@l
+
+ /* ptr to current thread */
+ addi r4,r2,THREAD /* init task's THREAD */
+ mtspr SPRN_SPRG3,r4
+
+ /* stack */
+ lis r1,init_thread_union@h
+ ori r1,r1,init_thread_union@l
+ li r0,0
+ stwu r0,THREAD_SIZE-STACK_FRAME_OVERHEAD(r1)
+
+ bl early_init
+
+/*
+ * Decide what sort of machine this is and initialize the MMU.
+ */
+ mr r3,r31
+ mr r4,r30
+ mr r5,r29
+ mr r6,r28
+ mr r7,r27
+ bl machine_init
+ bl MMU_init
+
+ /* Setup PTE pointers for the Abatron bdiGDB */
+ lis r6, swapper_pg_dir@h
+ ori r6, r6, swapper_pg_dir@l
+ lis r5, abatron_pteptrs@h
+ ori r5, r5, abatron_pteptrs@l
+ lis r4, KERNELBASE@h
+ ori r4, r4, KERNELBASE@l
+ stw r5, 0(r4) /* Save abatron_pteptrs at a fixed location */
+ stw r6, 0(r5)
+
+ /* Let's move on */
+ lis r4,start_kernel@h
+ ori r4,r4,start_kernel@l
+ lis r3,MSR_KERNEL@h
+ ori r3,r3,MSR_KERNEL@l
+ mtspr SPRN_SRR0,r4
+ mtspr SPRN_SRR1,r3
+ rfi /* change context and jump to start_kernel */
+
+/*
+ * Interrupt vector entry code
+ *
+ * The Book E MMUs are always on so we don't need to handle
+ * interrupts in real mode as with previous PPC processors. In
+ * this case we handle interrupts in the kernel virtual address
+ * space.
+ *
+ * Interrupt vectors are dynamically placed relative to the
+ * interrupt prefix as determined by the address of interrupt_base.
+ * The interrupt vectors offsets are programmed using the labels
+ * for each interrupt vector entry.
+ *
+ * Interrupt vectors must be aligned on a 16 byte boundary.
+ * We align on a 32 byte cache line boundary for good measure.
+ */
+
+interrupt_base:
+ /* Critical Input Interrupt */
+ CRITICAL_EXCEPTION(0x0100, CriticalInput, unknown_exception)
+
+ /* Machine Check Interrupt */
+#ifdef CONFIG_440A
+ MCHECK_EXCEPTION(0x0200, MachineCheck, machine_check_exception)
+#else
+ CRITICAL_EXCEPTION(0x0200, MachineCheck, machine_check_exception)
+#endif
+
+ /* Data Storage Interrupt */
+ START_EXCEPTION(DataStorage)
+ mtspr SPRN_SPRG0, r10 /* Save some working registers */
+ mtspr SPRN_SPRG1, r11
+ mtspr SPRN_SPRG4W, r12
+ mtspr SPRN_SPRG5W, r13
+ mfcr r11
+ mtspr SPRN_SPRG7W, r11
+
+ /*
+ * Check if it was a store fault, if not then bail
+ * because a user tried to access a kernel or
+ * read-protected page. Otherwise, get the
+ * offending address and handle it.
+ */
+ mfspr r10, SPRN_ESR
+ andis. r10, r10, ESR_ST@h
+ beq 2f
+
+ mfspr r10, SPRN_DEAR /* Get faulting address */
+
+ /* If we are faulting a kernel address, we have to use the
+ * kernel page tables.
+ */
+ lis r11, TASK_SIZE@h
+ cmplw r10, r11
+ blt+ 3f
+ lis r11, swapper_pg_dir@h
+ ori r11, r11, swapper_pg_dir@l
+
+ mfspr r12,SPRN_MMUCR
+ rlwinm r12,r12,0,0,23 /* Clear TID */
+
+ b 4f
+
+ /* Get the PGD for the current thread */
+3:
+ mfspr r11,SPRN_SPRG3
+ lwz r11,PGDIR(r11)
+
+ /* Load PID into MMUCR TID */
+ mfspr r12,SPRN_MMUCR /* Get MMUCR */
+ mfspr r13,SPRN_PID /* Get PID */
+ rlwimi r12,r13,0,24,31 /* Set TID */
+
+4:
+ mtspr SPRN_MMUCR,r12
+
+ rlwinm r12, r10, 13, 19, 29 /* Compute pgdir/pmd offset */
+ lwzx r11, r12, r11 /* Get pgd/pmd entry */
+ rlwinm. r12, r11, 0, 0, 20 /* Extract pt base address */
+ beq 2f /* Bail if no table */
+
+ rlwimi r12, r10, 23, 20, 28 /* Compute pte address */
+ lwz r11, 4(r12) /* Get pte entry */
+
+ andi. r13, r11, _PAGE_RW /* Is it writeable? */
+ beq 2f /* Bail if not */
+
+ /* Update 'changed'.
+ */
+ ori r11, r11, _PAGE_DIRTY|_PAGE_ACCESSED|_PAGE_HWWRITE
+ stw r11, 4(r12) /* Update Linux page table */
+
+ li r13, PPC44x_TLB_SR@l /* Set SR */
+ rlwimi r13, r11, 29, 29, 29 /* SX = _PAGE_HWEXEC */
+ rlwimi r13, r11, 0, 30, 30 /* SW = _PAGE_RW */
+ rlwimi r13, r11, 29, 28, 28 /* UR = _PAGE_USER */
+ rlwimi r12, r11, 31, 26, 26 /* (_PAGE_USER>>1)->r12 */
+ rlwimi r12, r11, 29, 30, 30 /* (_PAGE_USER>>3)->r12 */
+ and r12, r12, r11 /* HWEXEC/RW & USER */
+ rlwimi r13, r12, 0, 26, 26 /* UX = HWEXEC & USER */
+ rlwimi r13, r12, 3, 27, 27 /* UW = RW & USER */
+
+ rlwimi r11,r13,0,26,31 /* Insert static perms */
+
+ rlwinm r11,r11,0,20,15 /* Clear U0-U3 */
+
+ /* find the TLB index that caused the fault. It has to be here. */
+ tlbsx r10, 0, r10
+
+ tlbwe r11, r10, PPC44x_TLB_ATTRIB /* Write ATTRIB */
+
+ /* Done...restore registers and get out of here.
+ */
+ mfspr r11, SPRN_SPRG7R
+ mtcr r11
+ mfspr r13, SPRN_SPRG5R
+ mfspr r12, SPRN_SPRG4R
+
+ mfspr r11, SPRN_SPRG1
+ mfspr r10, SPRN_SPRG0
+ rfi /* Force context change */
+
+2:
+ /*
+ * The bailout. Restore registers to pre-exception conditions
+ * and call the heavyweights to help us out.
+ */
+ mfspr r11, SPRN_SPRG7R
+ mtcr r11
+ mfspr r13, SPRN_SPRG5R
+ mfspr r12, SPRN_SPRG4R
+
+ mfspr r11, SPRN_SPRG1
+ mfspr r10, SPRN_SPRG0
+ b data_access
+
+ /* Instruction Storage Interrupt */
+ INSTRUCTION_STORAGE_EXCEPTION
+
+ /* External Input Interrupt */
+ EXCEPTION(0x0500, ExternalInput, do_IRQ, EXC_XFER_LITE)
+
+ /* Alignment Interrupt */
+ ALIGNMENT_EXCEPTION
+
+ /* Program Interrupt */
+ PROGRAM_EXCEPTION
+
+ /* Floating Point Unavailable Interrupt */
+#ifdef CONFIG_PPC_FPU
+ FP_UNAVAILABLE_EXCEPTION
+#else
+ EXCEPTION(0x2010, FloatingPointUnavailable, unknown_exception, EXC_XFER_EE)
+#endif
+
+ /* System Call Interrupt */
+ START_EXCEPTION(SystemCall)
+ NORMAL_EXCEPTION_PROLOG
+ EXC_XFER_EE_LITE(0x0c00, DoSyscall)
+
+ /* Auxillary Processor Unavailable Interrupt */
+ EXCEPTION(0x2020, AuxillaryProcessorUnavailable, unknown_exception, EXC_XFER_EE)
+
+ /* Decrementer Interrupt */
+ DECREMENTER_EXCEPTION
+
+ /* Fixed Internal Timer Interrupt */
+ /* TODO: Add FIT support */
+ EXCEPTION(0x1010, FixedIntervalTimer, unknown_exception, EXC_XFER_EE)
+
+ /* Watchdog Timer Interrupt */
+ /* TODO: Add watchdog support */
+#ifdef CONFIG_BOOKE_WDT
+ CRITICAL_EXCEPTION(0x1020, WatchdogTimer, WatchdogException)
+#else
+ CRITICAL_EXCEPTION(0x1020, WatchdogTimer, unknown_exception)
+#endif
+
+ /* Data TLB Error Interrupt */
+ START_EXCEPTION(DataTLBError)
+ mtspr SPRN_SPRG0, r10 /* Save some working registers */
+ mtspr SPRN_SPRG1, r11
+ mtspr SPRN_SPRG4W, r12
+ mtspr SPRN_SPRG5W, r13
+ mfcr r11
+ mtspr SPRN_SPRG7W, r11
+ mfspr r10, SPRN_DEAR /* Get faulting address */
+
+ /* If we are faulting a kernel address, we have to use the
+ * kernel page tables.
+ */
+ lis r11, TASK_SIZE@h
+ cmplw r10, r11
+ blt+ 3f
+ lis r11, swapper_pg_dir@h
+ ori r11, r11, swapper_pg_dir@l
+
+ mfspr r12,SPRN_MMUCR
+ rlwinm r12,r12,0,0,23 /* Clear TID */
+
+ b 4f
+
+ /* Get the PGD for the current thread */
+3:
+ mfspr r11,SPRN_SPRG3
+ lwz r11,PGDIR(r11)
+
+ /* Load PID into MMUCR TID */
+ mfspr r12,SPRN_MMUCR
+ mfspr r13,SPRN_PID /* Get PID */
+ rlwimi r12,r13,0,24,31 /* Set TID */
+
+4:
+ mtspr SPRN_MMUCR,r12
+
+ rlwinm r12, r10, 13, 19, 29 /* Compute pgdir/pmd offset */
+ lwzx r11, r12, r11 /* Get pgd/pmd entry */
+ rlwinm. r12, r11, 0, 0, 20 /* Extract pt base address */
+ beq 2f /* Bail if no table */
+
+ rlwimi r12, r10, 23, 20, 28 /* Compute pte address */
+ lwz r11, 4(r12) /* Get pte entry */
+ andi. r13, r11, _PAGE_PRESENT /* Is the page present? */
+ beq 2f /* Bail if not present */
+
+ ori r11, r11, _PAGE_ACCESSED
+ stw r11, 4(r12)
+
+ /* Jump to common tlb load */
+ b finish_tlb_load
+
+2:
+ /* The bailout. Restore registers to pre-exception conditions
+ * and call the heavyweights to help us out.
+ */
+ mfspr r11, SPRN_SPRG7R
+ mtcr r11
+ mfspr r13, SPRN_SPRG5R
+ mfspr r12, SPRN_SPRG4R
+ mfspr r11, SPRN_SPRG1
+ mfspr r10, SPRN_SPRG0
+ b data_access
+
+ /* Instruction TLB Error Interrupt */
+ /*
+ * Nearly the same as above, except we get our
+ * information from different registers and bailout
+ * to a different point.
+ */
+ START_EXCEPTION(InstructionTLBError)
+ mtspr SPRN_SPRG0, r10 /* Save some working registers */
+ mtspr SPRN_SPRG1, r11
+ mtspr SPRN_SPRG4W, r12
+ mtspr SPRN_SPRG5W, r13
+ mfcr r11
+ mtspr SPRN_SPRG7W, r11
+ mfspr r10, SPRN_SRR0 /* Get faulting address */
+
+ /* If we are faulting a kernel address, we have to use the
+ * kernel page tables.
+ */
+ lis r11, TASK_SIZE@h
+ cmplw r10, r11
+ blt+ 3f
+ lis r11, swapper_pg_dir@h
+ ori r11, r11, swapper_pg_dir@l
+
+ mfspr r12,SPRN_MMUCR
+ rlwinm r12,r12,0,0,23 /* Clear TID */
+
+ b 4f
+
+ /* Get the PGD for the current thread */
+3:
+ mfspr r11,SPRN_SPRG3
+ lwz r11,PGDIR(r11)
+
+ /* Load PID into MMUCR TID */
+ mfspr r12,SPRN_MMUCR
+ mfspr r13,SPRN_PID /* Get PID */
+ rlwimi r12,r13,0,24,31 /* Set TID */
+
+4:
+ mtspr SPRN_MMUCR,r12
+
+ rlwinm r12, r10, 13, 19, 29 /* Compute pgdir/pmd offset */
+ lwzx r11, r12, r11 /* Get pgd/pmd entry */
+ rlwinm. r12, r11, 0, 0, 20 /* Extract pt base address */
+ beq 2f /* Bail if no table */
+
+ rlwimi r12, r10, 23, 20, 28 /* Compute pte address */
+ lwz r11, 4(r12) /* Get pte entry */
+ andi. r13, r11, _PAGE_PRESENT /* Is the page present? */
+ beq 2f /* Bail if not present */
+
+ ori r11, r11, _PAGE_ACCESSED
+ stw r11, 4(r12)
+
+ /* Jump to common TLB load point */
+ b finish_tlb_load
+
+2:
+ /* The bailout. Restore registers to pre-exception conditions
+ * and call the heavyweights to help us out.
+ */
+ mfspr r11, SPRN_SPRG7R
+ mtcr r11
+ mfspr r13, SPRN_SPRG5R
+ mfspr r12, SPRN_SPRG4R
+ mfspr r11, SPRN_SPRG1
+ mfspr r10, SPRN_SPRG0
+ b InstructionStorage
+
+ /* Debug Interrupt */
+ DEBUG_EXCEPTION
+
+/*
+ * Local functions
+ */
+ /*
+ * Data TLB exceptions will bail out to this point
+ * if they can't resolve the lightweight TLB fault.
+ */
+data_access:
+ NORMAL_EXCEPTION_PROLOG
+ mfspr r5,SPRN_ESR /* Grab the ESR, save it, pass arg3 */
+ stw r5,_ESR(r11)
+ mfspr r4,SPRN_DEAR /* Grab the DEAR, save it, pass arg2 */
+ EXC_XFER_EE_LITE(0x0300, handle_page_fault)
+
+/*
+
+ * Both the instruction and data TLB miss get to this
+ * point to load the TLB.
+ * r10 - EA of fault
+ * r11 - available to use
+ * r12 - Pointer to the 64-bit PTE
+ * r13 - available to use
+ * MMUCR - loaded with proper value when we get here
+ * Upon exit, we reload everything and RFI.
+ */
+finish_tlb_load:
+ /*
+ * We set execute, because we don't have the granularity to
+ * properly set this at the page level (Linux problem).
+ * If shared is set, we cause a zero PID->TID load.
+ * Many of these bits are software only. Bits we don't set
+ * here we (properly should) assume have the appropriate value.
+ */
+
+ /* Load the next available TLB index */
+ lis r13, tlb_44x_index@ha
+ lwz r13, tlb_44x_index@l(r13)
+ /* Load the TLB high watermark */
+ lis r11, tlb_44x_hwater@ha
+ lwz r11, tlb_44x_hwater@l(r11)
+
+ /* Increment, rollover, and store TLB index */
+ addi r13, r13, 1
+ cmpw 0, r13, r11 /* reserve entries */
+ ble 7f
+ li r13, 0
+7:
+ /* Store the next available TLB index */
+ lis r11, tlb_44x_index@ha
+ stw r13, tlb_44x_index@l(r11)
+
+ lwz r11, 0(r12) /* Get MS word of PTE */
+ lwz r12, 4(r12) /* Get LS word of PTE */
+ rlwimi r11, r12, 0, 0 , 19 /* Insert RPN */
+ tlbwe r11, r13, PPC44x_TLB_XLAT /* Write XLAT */
+
+ /*
+ * Create PAGEID. This is the faulting address,
+ * page size, and valid flag.
+ */
+ li r11, PPC44x_TLB_VALID | PPC44x_TLB_4K
+ rlwimi r10, r11, 0, 20, 31 /* Insert valid and page size */
+ tlbwe r10, r13, PPC44x_TLB_PAGEID /* Write PAGEID */
+
+ li r10, PPC44x_TLB_SR@l /* Set SR */
+ rlwimi r10, r12, 0, 30, 30 /* Set SW = _PAGE_RW */
+ rlwimi r10, r12, 29, 29, 29 /* SX = _PAGE_HWEXEC */
+ rlwimi r10, r12, 29, 28, 28 /* UR = _PAGE_USER */
+ rlwimi r11, r12, 31, 26, 26 /* (_PAGE_USER>>1)->r12 */
+ and r11, r12, r11 /* HWEXEC & USER */
+ rlwimi r10, r11, 0, 26, 26 /* UX = HWEXEC & USER */
+
+ rlwimi r12, r10, 0, 26, 31 /* Insert static perms */
+ rlwinm r12, r12, 0, 20, 15 /* Clear U0-U3 */
+ tlbwe r12, r13, PPC44x_TLB_ATTRIB /* Write ATTRIB */
+
+ /* Done...restore registers and get out of here.
+ */
+ mfspr r11, SPRN_SPRG7R
+ mtcr r11
+ mfspr r13, SPRN_SPRG5R
+ mfspr r12, SPRN_SPRG4R
+ mfspr r11, SPRN_SPRG1
+ mfspr r10, SPRN_SPRG0
+ rfi /* Force context change */
+
+/*
+ * Global functions
+ */
+
+/*
+ * extern void giveup_altivec(struct task_struct *prev)
+ *
+ * The 44x core does not have an AltiVec unit.
+ */
+_GLOBAL(giveup_altivec)
+ blr
+
+/*
+ * extern void giveup_fpu(struct task_struct *prev)
+ *
+ * The 44x core does not have an FPU.
+ */
+#ifndef CONFIG_PPC_FPU
+_GLOBAL(giveup_fpu)
+ blr
+#endif
+
+/*
+ * extern void abort(void)
+ *
+ * At present, this routine just applies a system reset.
+ */
+_GLOBAL(abort)
+ mfspr r13,SPRN_DBCR0
+ oris r13,r13,DBCR0_RST_SYSTEM@h
+ mtspr SPRN_DBCR0,r13
+
+_GLOBAL(set_context)
+
+#ifdef CONFIG_BDI_SWITCH
+ /* Context switch the PTE pointer for the Abatron BDI2000.
+ * The PGDIR is the second parameter.
+ */
+ lis r5, abatron_pteptrs@h
+ ori r5, r5, abatron_pteptrs@l
+ stw r4, 0x4(r5)
+#endif
+ mtspr SPRN_PID,r3
+ isync /* Force context change */
+ blr
+
+/*
+ * We put a few things here that have to be page-aligned. This stuff
+ * goes at the beginning of the data segment, which is page-aligned.
+ */
+ .data
+ .align 12
+ .globl sdata
+sdata:
+ .globl empty_zero_page
+empty_zero_page:
+ .space 4096
+
+/*
+ * To support >32-bit physical addresses, we use an 8KB pgdir.
+ */
+ .globl swapper_pg_dir
+swapper_pg_dir:
+ .space 8192
+
+/* Reserved 4k for the critical exception stack & 4k for the machine
+ * check stack per CPU for kernel mode exceptions */
+ .section .bss
+ .align 12
+exception_stack_bottom:
+ .space BOOKE_EXCEPTION_STACK_SIZE
+ .globl exception_stack_top
+exception_stack_top:
+
+/*
+ * This space gets a copy of optional info passed to us by the bootstrap
+ * which is used to pass parameters into the kernel like root=/dev/sda1, etc.
+ */
+ .globl cmd_line
+cmd_line:
+ .space 512
+
+/*
+ * Room for two PTE pointers, usually the kernel and current user pointers
+ * to their respective root page table.
+ */
+abatron_pteptrs:
+ .space 8
diff --git a/arch/powerpc/kernel/head_4xx.S b/arch/powerpc/kernel/head_4xx.S
new file mode 100644
index 000000000000..2590e97f5539
--- /dev/null
+++ b/arch/powerpc/kernel/head_4xx.S
@@ -0,0 +1,1022 @@
+/*
+ * Copyright (c) 1995-1996 Gary Thomas <gdt@linuxppc.org>
+ * Initial PowerPC version.
+ * Copyright (c) 1996 Cort Dougan <cort@cs.nmt.edu>
+ * Rewritten for PReP
+ * Copyright (c) 1996 Paul Mackerras <paulus@cs.anu.edu.au>
+ * Low-level exception handers, MMU support, and rewrite.
+ * Copyright (c) 1997 Dan Malek <dmalek@jlc.net>
+ * PowerPC 8xx modifications.
+ * Copyright (c) 1998-1999 TiVo, Inc.
+ * PowerPC 403GCX modifications.
+ * Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu>
+ * PowerPC 403GCX/405GP modifications.
+ * Copyright 2000 MontaVista Software Inc.
+ * PPC405 modifications
+ * PowerPC 403GCX/405GP modifications.
+ * Author: MontaVista Software, Inc.
+ * frank_rowand@mvista.com or source@mvista.com
+ * debbie_chu@mvista.com
+ *
+ *
+ * Module name: head_4xx.S
+ *
+ * Description:
+ * Kernel execution entry point code.
+ *
+ * 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/config.h>
+#include <asm/processor.h>
+#include <asm/page.h>
+#include <asm/mmu.h>
+#include <asm/pgtable.h>
+#include <asm/ibm4xx.h>
+#include <asm/cputable.h>
+#include <asm/thread_info.h>
+#include <asm/ppc_asm.h>
+#include <asm/asm-offsets.h>
+
+/* As with the other PowerPC ports, it is expected that when code
+ * execution begins here, the following registers contain valid, yet
+ * optional, information:
+ *
+ * r3 - Board info structure pointer (DRAM, frequency, MAC address, etc.)
+ * r4 - Starting address of the init RAM disk
+ * r5 - Ending address of the init RAM disk
+ * r6 - Start of kernel command line string (e.g. "mem=96m")
+ * r7 - End of kernel command line string
+ *
+ * This is all going to change RSN when we add bi_recs....... -- Dan
+ */
+ .text
+_GLOBAL(_stext)
+_GLOBAL(_start)
+
+ /* Save parameters we are passed.
+ */
+ mr r31,r3
+ mr r30,r4
+ mr r29,r5
+ mr r28,r6
+ mr r27,r7
+
+ /* We have to turn on the MMU right away so we get cache modes
+ * set correctly.
+ */
+ bl initial_mmu
+
+/* We now have the lower 16 Meg mapped into TLB entries, and the caches
+ * ready to work.
+ */
+turn_on_mmu:
+ lis r0,MSR_KERNEL@h
+ ori r0,r0,MSR_KERNEL@l
+ mtspr SPRN_SRR1,r0
+ lis r0,start_here@h
+ ori r0,r0,start_here@l
+ mtspr SPRN_SRR0,r0
+ SYNC
+ rfi /* enables MMU */
+ b . /* prevent prefetch past rfi */
+
+/*
+ * This area is used for temporarily saving registers during the
+ * critical exception prolog.
+ */
+ . = 0xc0
+crit_save:
+_GLOBAL(crit_r10)
+ .space 4
+_GLOBAL(crit_r11)
+ .space 4
+
+/*
+ * Exception vector entry code. This code runs with address translation
+ * turned off (i.e. using physical addresses). We assume SPRG3 has the
+ * physical address of the current task thread_struct.
+ * Note that we have to have decremented r1 before we write to any fields
+ * of the exception frame, since a critical interrupt could occur at any
+ * time, and it will write to the area immediately below the current r1.
+ */
+#define NORMAL_EXCEPTION_PROLOG \
+ mtspr SPRN_SPRG0,r10; /* save two registers to work with */\
+ mtspr SPRN_SPRG1,r11; \
+ mtspr SPRN_SPRG2,r1; \
+ mfcr r10; /* save CR in r10 for now */\
+ mfspr r11,SPRN_SRR1; /* check whether user or kernel */\
+ andi. r11,r11,MSR_PR; \
+ beq 1f; \
+ mfspr r1,SPRN_SPRG3; /* if from user, start at top of */\
+ lwz r1,THREAD_INFO-THREAD(r1); /* this thread's kernel stack */\
+ addi r1,r1,THREAD_SIZE; \
+1: subi r1,r1,INT_FRAME_SIZE; /* Allocate an exception frame */\
+ tophys(r11,r1); \
+ stw r10,_CCR(r11); /* save various registers */\
+ stw r12,GPR12(r11); \
+ stw r9,GPR9(r11); \
+ mfspr r10,SPRN_SPRG0; \
+ stw r10,GPR10(r11); \
+ mfspr r12,SPRN_SPRG1; \
+ stw r12,GPR11(r11); \
+ mflr r10; \
+ stw r10,_LINK(r11); \
+ mfspr r10,SPRN_SPRG2; \
+ mfspr r12,SPRN_SRR0; \
+ stw r10,GPR1(r11); \
+ mfspr r9,SPRN_SRR1; \
+ stw r10,0(r11); \
+ rlwinm r9,r9,0,14,12; /* clear MSR_WE (necessary?) */\
+ stw r0,GPR0(r11); \
+ SAVE_4GPRS(3, r11); \
+ SAVE_2GPRS(7, r11)
+
+/*
+ * Exception prolog for critical exceptions. This is a little different
+ * from the normal exception prolog above since a critical exception
+ * can potentially occur at any point during normal exception processing.
+ * Thus we cannot use the same SPRG registers as the normal prolog above.
+ * Instead we use a couple of words of memory at low physical addresses.
+ * This is OK since we don't support SMP on these processors.
+ */
+#define CRITICAL_EXCEPTION_PROLOG \
+ stw r10,crit_r10@l(0); /* save two registers to work with */\
+ stw r11,crit_r11@l(0); \
+ mfcr r10; /* save CR in r10 for now */\
+ mfspr r11,SPRN_SRR3; /* check whether user or kernel */\
+ andi. r11,r11,MSR_PR; \
+ lis r11,critical_stack_top@h; \
+ ori r11,r11,critical_stack_top@l; \
+ beq 1f; \
+ /* COMING FROM USER MODE */ \
+ mfspr r11,SPRN_SPRG3; /* if from user, start at top of */\
+ lwz r11,THREAD_INFO-THREAD(r11); /* this thread's kernel stack */\
+ addi r11,r11,THREAD_SIZE; \
+1: subi r11,r11,INT_FRAME_SIZE; /* Allocate an exception frame */\
+ tophys(r11,r11); \
+ stw r10,_CCR(r11); /* save various registers */\
+ stw r12,GPR12(r11); \
+ stw r9,GPR9(r11); \
+ mflr r10; \
+ stw r10,_LINK(r11); \
+ mfspr r12,SPRN_DEAR; /* save DEAR and ESR in the frame */\
+ stw r12,_DEAR(r11); /* since they may have had stuff */\
+ mfspr r9,SPRN_ESR; /* in them at the point where the */\
+ stw r9,_ESR(r11); /* exception was taken */\
+ mfspr r12,SPRN_SRR2; \
+ stw r1,GPR1(r11); \
+ mfspr r9,SPRN_SRR3; \
+ stw r1,0(r11); \
+ tovirt(r1,r11); \
+ rlwinm r9,r9,0,14,12; /* clear MSR_WE (necessary?) */\
+ stw r0,GPR0(r11); \
+ SAVE_4GPRS(3, r11); \
+ SAVE_2GPRS(7, r11)
+
+ /*
+ * State at this point:
+ * r9 saved in stack frame, now saved SRR3 & ~MSR_WE
+ * r10 saved in crit_r10 and in stack frame, trashed
+ * r11 saved in crit_r11 and in stack frame,
+ * now phys stack/exception frame pointer
+ * r12 saved in stack frame, now saved SRR2
+ * CR saved in stack frame, CR0.EQ = !SRR3.PR
+ * LR, DEAR, ESR in stack frame
+ * r1 saved in stack frame, now virt stack/excframe pointer
+ * r0, r3-r8 saved in stack frame
+ */
+
+/*
+ * Exception vectors.
+ */
+#define START_EXCEPTION(n, label) \
+ . = n; \
+label:
+
+#define EXCEPTION(n, label, hdlr, xfer) \
+ START_EXCEPTION(n, label); \
+ NORMAL_EXCEPTION_PROLOG; \
+ addi r3,r1,STACK_FRAME_OVERHEAD; \
+ xfer(n, hdlr)
+
+#define CRITICAL_EXCEPTION(n, label, hdlr) \
+ START_EXCEPTION(n, label); \
+ CRITICAL_EXCEPTION_PROLOG; \
+ addi r3,r1,STACK_FRAME_OVERHEAD; \
+ EXC_XFER_TEMPLATE(hdlr, n+2, (MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)), \
+ NOCOPY, crit_transfer_to_handler, \
+ ret_from_crit_exc)
+
+#define EXC_XFER_TEMPLATE(hdlr, trap, msr, copyee, tfer, ret) \
+ li r10,trap; \
+ stw r10,_TRAP(r11); \
+ lis r10,msr@h; \
+ ori r10,r10,msr@l; \
+ copyee(r10, r9); \
+ bl tfer; \
+ .long hdlr; \
+ .long ret
+
+#define COPY_EE(d, s) rlwimi d,s,0,16,16
+#define NOCOPY(d, s)
+
+#define EXC_XFER_STD(n, hdlr) \
+ EXC_XFER_TEMPLATE(hdlr, n, MSR_KERNEL, NOCOPY, transfer_to_handler_full, \
+ ret_from_except_full)
+
+#define EXC_XFER_LITE(n, hdlr) \
+ EXC_XFER_TEMPLATE(hdlr, n+1, MSR_KERNEL, NOCOPY, transfer_to_handler, \
+ ret_from_except)
+
+#define EXC_XFER_EE(n, hdlr) \
+ EXC_XFER_TEMPLATE(hdlr, n, MSR_KERNEL, COPY_EE, transfer_to_handler_full, \
+ ret_from_except_full)
+
+#define EXC_XFER_EE_LITE(n, hdlr) \
+ EXC_XFER_TEMPLATE(hdlr, n+1, MSR_KERNEL, COPY_EE, transfer_to_handler, \
+ ret_from_except)
+
+
+/*
+ * 0x0100 - Critical Interrupt Exception
+ */
+ CRITICAL_EXCEPTION(0x0100, CriticalInterrupt, unknown_exception)
+
+/*
+ * 0x0200 - Machine Check Exception
+ */
+ CRITICAL_EXCEPTION(0x0200, MachineCheck, machine_check_exception)
+
+/*
+ * 0x0300 - Data Storage Exception
+ * This happens for just a few reasons. U0 set (but we don't do that),
+ * or zone protection fault (user violation, write to protected page).
+ * If this is just an update of modified status, we do that quickly
+ * and exit. Otherwise, we call heavywight functions to do the work.
+ */
+ START_EXCEPTION(0x0300, DataStorage)
+ mtspr SPRN_SPRG0, r10 /* Save some working registers */
+ mtspr SPRN_SPRG1, r11
+#ifdef CONFIG_403GCX
+ stw r12, 0(r0)
+ stw r9, 4(r0)
+ mfcr r11
+ mfspr r12, SPRN_PID
+ stw r11, 8(r0)
+ stw r12, 12(r0)
+#else
+ mtspr SPRN_SPRG4, r12
+ mtspr SPRN_SPRG5, r9
+ mfcr r11
+ mfspr r12, SPRN_PID
+ mtspr SPRN_SPRG7, r11
+ mtspr SPRN_SPRG6, r12
+#endif
+
+ /* First, check if it was a zone fault (which means a user
+ * tried to access a kernel or read-protected page - always
+ * a SEGV). All other faults here must be stores, so no
+ * need to check ESR_DST as well. */
+ mfspr r10, SPRN_ESR
+ andis. r10, r10, ESR_DIZ@h
+ bne 2f
+
+ mfspr r10, SPRN_DEAR /* Get faulting address */
+
+ /* If we are faulting a kernel address, we have to use the
+ * kernel page tables.
+ */
+ lis r11, TASK_SIZE@h
+ cmplw r10, r11
+ blt+ 3f
+ lis r11, swapper_pg_dir@h
+ ori r11, r11, swapper_pg_dir@l
+ li r9, 0
+ mtspr SPRN_PID, r9 /* TLB will have 0 TID */
+ b 4f
+
+ /* Get the PGD for the current thread.
+ */
+3:
+ mfspr r11,SPRN_SPRG3
+ lwz r11,PGDIR(r11)
+4:
+ tophys(r11, r11)
+ rlwimi r11, r10, 12, 20, 29 /* Create L1 (pgdir/pmd) address */
+ lwz r11, 0(r11) /* Get L1 entry */
+ rlwinm. r12, r11, 0, 0, 19 /* Extract L2 (pte) base address */
+ beq 2f /* Bail if no table */
+
+ rlwimi r12, r10, 22, 20, 29 /* Compute PTE address */
+ lwz r11, 0(r12) /* Get Linux PTE */
+
+ andi. r9, r11, _PAGE_RW /* Is it writeable? */
+ beq 2f /* Bail if not */
+
+ /* Update 'changed'.
+ */
+ ori r11, r11, _PAGE_DIRTY|_PAGE_ACCESSED|_PAGE_HWWRITE
+ stw r11, 0(r12) /* Update Linux page table */
+
+ /* Most of the Linux PTE is ready to load into the TLB LO.
+ * We set ZSEL, where only the LS-bit determines user access.
+ * We set execute, because we don't have the granularity to
+ * properly set this at the page level (Linux problem).
+ * If shared is set, we cause a zero PID->TID load.
+ * Many of these bits are software only. Bits we don't set
+ * here we (properly should) assume have the appropriate value.
+ */
+ li r12, 0x0ce2
+ andc r11, r11, r12 /* Make sure 20, 21 are zero */
+
+ /* find the TLB index that caused the fault. It has to be here.
+ */
+ tlbsx r9, 0, r10
+
+ tlbwe r11, r9, TLB_DATA /* Load TLB LO */
+
+ /* Done...restore registers and get out of here.
+ */
+#ifdef CONFIG_403GCX
+ lwz r12, 12(r0)
+ lwz r11, 8(r0)
+ mtspr SPRN_PID, r12
+ mtcr r11
+ lwz r9, 4(r0)
+ lwz r12, 0(r0)
+#else
+ mfspr r12, SPRN_SPRG6
+ mfspr r11, SPRN_SPRG7
+ mtspr SPRN_PID, r12
+ mtcr r11
+ mfspr r9, SPRN_SPRG5
+ mfspr r12, SPRN_SPRG4
+#endif
+ mfspr r11, SPRN_SPRG1
+ mfspr r10, SPRN_SPRG0
+ PPC405_ERR77_SYNC
+ rfi /* Should sync shadow TLBs */
+ b . /* prevent prefetch past rfi */
+
+2:
+ /* The bailout. Restore registers to pre-exception conditions
+ * and call the heavyweights to help us out.
+ */
+#ifdef CONFIG_403GCX
+ lwz r12, 12(r0)
+ lwz r11, 8(r0)
+ mtspr SPRN_PID, r12
+ mtcr r11
+ lwz r9, 4(r0)
+ lwz r12, 0(r0)
+#else
+ mfspr r12, SPRN_SPRG6
+ mfspr r11, SPRN_SPRG7
+ mtspr SPRN_PID, r12
+ mtcr r11
+ mfspr r9, SPRN_SPRG5
+ mfspr r12, SPRN_SPRG4
+#endif
+ mfspr r11, SPRN_SPRG1
+ mfspr r10, SPRN_SPRG0
+ b DataAccess
+
+/*
+ * 0x0400 - Instruction Storage Exception
+ * This is caused by a fetch from non-execute or guarded pages.
+ */
+ START_EXCEPTION(0x0400, InstructionAccess)
+ NORMAL_EXCEPTION_PROLOG
+ mr r4,r12 /* Pass SRR0 as arg2 */
+ li r5,0 /* Pass zero as arg3 */
+ EXC_XFER_EE_LITE(0x400, handle_page_fault)
+
+/* 0x0500 - External Interrupt Exception */
+ EXCEPTION(0x0500, HardwareInterrupt, do_IRQ, EXC_XFER_LITE)
+
+/* 0x0600 - Alignment Exception */
+ START_EXCEPTION(0x0600, Alignment)
+ NORMAL_EXCEPTION_PROLOG
+ mfspr r4,SPRN_DEAR /* Grab the DEAR and save it */
+ stw r4,_DEAR(r11)
+ addi r3,r1,STACK_FRAME_OVERHEAD
+ EXC_XFER_EE(0x600, alignment_exception)
+
+/* 0x0700 - Program Exception */
+ START_EXCEPTION(0x0700, ProgramCheck)
+ NORMAL_EXCEPTION_PROLOG
+ mfspr r4,SPRN_ESR /* Grab the ESR and save it */
+ stw r4,_ESR(r11)
+ addi r3,r1,STACK_FRAME_OVERHEAD
+ EXC_XFER_STD(0x700, program_check_exception)
+
+ EXCEPTION(0x0800, Trap_08, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x0900, Trap_09, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x0A00, Trap_0A, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x0B00, Trap_0B, unknown_exception, EXC_XFER_EE)
+
+/* 0x0C00 - System Call Exception */
+ START_EXCEPTION(0x0C00, SystemCall)
+ NORMAL_EXCEPTION_PROLOG
+ EXC_XFER_EE_LITE(0xc00, DoSyscall)
+
+ EXCEPTION(0x0D00, Trap_0D, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x0E00, Trap_0E, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x0F00, Trap_0F, unknown_exception, EXC_XFER_EE)
+
+/* 0x1000 - Programmable Interval Timer (PIT) Exception */
+ START_EXCEPTION(0x1000, Decrementer)
+ NORMAL_EXCEPTION_PROLOG
+ lis r0,TSR_PIS@h
+ mtspr SPRN_TSR,r0 /* Clear the PIT exception */
+ addi r3,r1,STACK_FRAME_OVERHEAD
+ EXC_XFER_LITE(0x1000, timer_interrupt)
+
+#if 0
+/* NOTE:
+ * FIT and WDT handlers are not implemented yet.
+ */
+
+/* 0x1010 - Fixed Interval Timer (FIT) Exception
+*/
+ STND_EXCEPTION(0x1010, FITException, unknown_exception)
+
+/* 0x1020 - Watchdog Timer (WDT) Exception
+*/
+#ifdef CONFIG_BOOKE_WDT
+ CRITICAL_EXCEPTION(0x1020, WDTException, WatchdogException)
+#else
+ CRITICAL_EXCEPTION(0x1020, WDTException, unknown_exception)
+#endif
+#endif
+
+/* 0x1100 - Data TLB Miss Exception
+ * As the name implies, translation is not in the MMU, so search the
+ * page tables and fix it. The only purpose of this function is to
+ * load TLB entries from the page table if they exist.
+ */
+ START_EXCEPTION(0x1100, DTLBMiss)
+ mtspr SPRN_SPRG0, r10 /* Save some working registers */
+ mtspr SPRN_SPRG1, r11
+#ifdef CONFIG_403GCX
+ stw r12, 0(r0)
+ stw r9, 4(r0)
+ mfcr r11
+ mfspr r12, SPRN_PID
+ stw r11, 8(r0)
+ stw r12, 12(r0)
+#else
+ mtspr SPRN_SPRG4, r12
+ mtspr SPRN_SPRG5, r9
+ mfcr r11
+ mfspr r12, SPRN_PID
+ mtspr SPRN_SPRG7, r11
+ mtspr SPRN_SPRG6, r12
+#endif
+ mfspr r10, SPRN_DEAR /* Get faulting address */
+
+ /* If we are faulting a kernel address, we have to use the
+ * kernel page tables.
+ */
+ lis r11, TASK_SIZE@h
+ cmplw r10, r11
+ blt+ 3f
+ lis r11, swapper_pg_dir@h
+ ori r11, r11, swapper_pg_dir@l
+ li r9, 0
+ mtspr SPRN_PID, r9 /* TLB will have 0 TID */
+ b 4f
+
+ /* Get the PGD for the current thread.
+ */
+3:
+ mfspr r11,SPRN_SPRG3
+ lwz r11,PGDIR(r11)
+4:
+ tophys(r11, r11)
+ rlwimi r11, r10, 12, 20, 29 /* Create L1 (pgdir/pmd) address */
+ lwz r12, 0(r11) /* Get L1 entry */
+ andi. r9, r12, _PMD_PRESENT /* Check if it points to a PTE page */
+ beq 2f /* Bail if no table */
+
+ rlwimi r12, r10, 22, 20, 29 /* Compute PTE address */
+ lwz r11, 0(r12) /* Get Linux PTE */
+ andi. r9, r11, _PAGE_PRESENT
+ beq 5f
+
+ ori r11, r11, _PAGE_ACCESSED
+ stw r11, 0(r12)
+
+ /* Create TLB tag. This is the faulting address plus a static
+ * set of bits. These are size, valid, E, U0.
+ */
+ li r12, 0x00c0
+ rlwimi r10, r12, 0, 20, 31
+
+ b finish_tlb_load
+
+2: /* Check for possible large-page pmd entry */
+ rlwinm. r9, r12, 2, 22, 24
+ beq 5f
+
+ /* Create TLB tag. This is the faulting address, plus a static
+ * set of bits (valid, E, U0) plus the size from the PMD.
+ */
+ ori r9, r9, 0x40
+ rlwimi r10, r9, 0, 20, 31
+ mr r11, r12
+
+ b finish_tlb_load
+
+5:
+ /* The bailout. Restore registers to pre-exception conditions
+ * and call the heavyweights to help us out.
+ */
+#ifdef CONFIG_403GCX
+ lwz r12, 12(r0)
+ lwz r11, 8(r0)
+ mtspr SPRN_PID, r12
+ mtcr r11
+ lwz r9, 4(r0)
+ lwz r12, 0(r0)
+#else
+ mfspr r12, SPRN_SPRG6
+ mfspr r11, SPRN_SPRG7
+ mtspr SPRN_PID, r12
+ mtcr r11
+ mfspr r9, SPRN_SPRG5
+ mfspr r12, SPRN_SPRG4
+#endif
+ mfspr r11, SPRN_SPRG1
+ mfspr r10, SPRN_SPRG0
+ b DataAccess
+
+/* 0x1200 - Instruction TLB Miss Exception
+ * Nearly the same as above, except we get our information from different
+ * registers and bailout to a different point.
+ */
+ START_EXCEPTION(0x1200, ITLBMiss)
+ mtspr SPRN_SPRG0, r10 /* Save some working registers */
+ mtspr SPRN_SPRG1, r11
+#ifdef CONFIG_403GCX
+ stw r12, 0(r0)
+ stw r9, 4(r0)
+ mfcr r11
+ mfspr r12, SPRN_PID
+ stw r11, 8(r0)
+ stw r12, 12(r0)
+#else
+ mtspr SPRN_SPRG4, r12
+ mtspr SPRN_SPRG5, r9
+ mfcr r11
+ mfspr r12, SPRN_PID
+ mtspr SPRN_SPRG7, r11
+ mtspr SPRN_SPRG6, r12
+#endif
+ mfspr r10, SPRN_SRR0 /* Get faulting address */
+
+ /* If we are faulting a kernel address, we have to use the
+ * kernel page tables.
+ */
+ lis r11, TASK_SIZE@h
+ cmplw r10, r11
+ blt+ 3f
+ lis r11, swapper_pg_dir@h
+ ori r11, r11, swapper_pg_dir@l
+ li r9, 0
+ mtspr SPRN_PID, r9 /* TLB will have 0 TID */
+ b 4f
+
+ /* Get the PGD for the current thread.
+ */
+3:
+ mfspr r11,SPRN_SPRG3
+ lwz r11,PGDIR(r11)
+4:
+ tophys(r11, r11)
+ rlwimi r11, r10, 12, 20, 29 /* Create L1 (pgdir/pmd) address */
+ lwz r12, 0(r11) /* Get L1 entry */
+ andi. r9, r12, _PMD_PRESENT /* Check if it points to a PTE page */
+ beq 2f /* Bail if no table */
+
+ rlwimi r12, r10, 22, 20, 29 /* Compute PTE address */
+ lwz r11, 0(r12) /* Get Linux PTE */
+ andi. r9, r11, _PAGE_PRESENT
+ beq 5f
+
+ ori r11, r11, _PAGE_ACCESSED
+ stw r11, 0(r12)
+
+ /* Create TLB tag. This is the faulting address plus a static
+ * set of bits. These are size, valid, E, U0.
+ */
+ li r12, 0x00c0
+ rlwimi r10, r12, 0, 20, 31
+
+ b finish_tlb_load
+
+2: /* Check for possible large-page pmd entry */
+ rlwinm. r9, r12, 2, 22, 24
+ beq 5f
+
+ /* Create TLB tag. This is the faulting address, plus a static
+ * set of bits (valid, E, U0) plus the size from the PMD.
+ */
+ ori r9, r9, 0x40
+ rlwimi r10, r9, 0, 20, 31
+ mr r11, r12
+
+ b finish_tlb_load
+
+5:
+ /* The bailout. Restore registers to pre-exception conditions
+ * and call the heavyweights to help us out.
+ */
+#ifdef CONFIG_403GCX
+ lwz r12, 12(r0)
+ lwz r11, 8(r0)
+ mtspr SPRN_PID, r12
+ mtcr r11
+ lwz r9, 4(r0)
+ lwz r12, 0(r0)
+#else
+ mfspr r12, SPRN_SPRG6
+ mfspr r11, SPRN_SPRG7
+ mtspr SPRN_PID, r12
+ mtcr r11
+ mfspr r9, SPRN_SPRG5
+ mfspr r12, SPRN_SPRG4
+#endif
+ mfspr r11, SPRN_SPRG1
+ mfspr r10, SPRN_SPRG0
+ b InstructionAccess
+
+ EXCEPTION(0x1300, Trap_13, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x1400, Trap_14, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x1500, Trap_15, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x1600, Trap_16, unknown_exception, EXC_XFER_EE)
+#ifdef CONFIG_IBM405_ERR51
+ /* 405GP errata 51 */
+ START_EXCEPTION(0x1700, Trap_17)
+ b DTLBMiss
+#else
+ EXCEPTION(0x1700, Trap_17, unknown_exception, EXC_XFER_EE)
+#endif
+ EXCEPTION(0x1800, Trap_18, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x1900, Trap_19, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x1A00, Trap_1A, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x1B00, Trap_1B, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x1C00, Trap_1C, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x1D00, Trap_1D, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x1E00, Trap_1E, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x1F00, Trap_1F, unknown_exception, EXC_XFER_EE)
+
+/* Check for a single step debug exception while in an exception
+ * handler before state has been saved. This is to catch the case
+ * where an instruction that we are trying to single step causes
+ * an exception (eg ITLB/DTLB miss) and thus the first instruction of
+ * the exception handler generates a single step debug exception.
+ *
+ * If we get a debug trap on the first instruction of an exception handler,
+ * we reset the MSR_DE in the _exception handler's_ MSR (the debug trap is
+ * a critical exception, so we are using SPRN_CSRR1 to manipulate the MSR).
+ * The exception handler was handling a non-critical interrupt, so it will
+ * save (and later restore) the MSR via SPRN_SRR1, which will still have
+ * the MSR_DE bit set.
+ */
+ /* 0x2000 - Debug Exception */
+ START_EXCEPTION(0x2000, DebugTrap)
+ CRITICAL_EXCEPTION_PROLOG
+
+ /*
+ * If this is a single step or branch-taken exception in an
+ * exception entry sequence, it was probably meant to apply to
+ * the code where the exception occurred (since exception entry
+ * doesn't turn off DE automatically). We simulate the effect
+ * of turning off DE on entry to an exception handler by turning
+ * off DE in the SRR3 value and clearing the debug status.
+ */
+ mfspr r10,SPRN_DBSR /* check single-step/branch taken */
+ andis. r10,r10,DBSR_IC@h
+ beq+ 2f
+
+ andi. r10,r9,MSR_IR|MSR_PR /* check supervisor + MMU off */
+ beq 1f /* branch and fix it up */
+
+ mfspr r10,SPRN_SRR2 /* Faulting instruction address */
+ cmplwi r10,0x2100
+ bgt+ 2f /* address above exception vectors */
+
+ /* here it looks like we got an inappropriate debug exception. */
+1: rlwinm r9,r9,0,~MSR_DE /* clear DE in the SRR3 value */
+ lis r10,DBSR_IC@h /* clear the IC event */
+ mtspr SPRN_DBSR,r10
+ /* restore state and get out */
+ lwz r10,_CCR(r11)
+ lwz r0,GPR0(r11)
+ lwz r1,GPR1(r11)
+ mtcrf 0x80,r10
+ mtspr SPRN_SRR2,r12
+ mtspr SPRN_SRR3,r9
+ lwz r9,GPR9(r11)
+ lwz r12,GPR12(r11)
+ lwz r10,crit_r10@l(0)
+ lwz r11,crit_r11@l(0)
+ PPC405_ERR77_SYNC
+ rfci
+ b .
+
+ /* continue normal handling for a critical exception... */
+2: mfspr r4,SPRN_DBSR
+ addi r3,r1,STACK_FRAME_OVERHEAD
+ EXC_XFER_TEMPLATE(DebugException, 0x2002, \
+ (MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)), \
+ NOCOPY, crit_transfer_to_handler, ret_from_crit_exc)
+
+/*
+ * The other Data TLB exceptions bail out to this point
+ * if they can't resolve the lightweight TLB fault.
+ */
+DataAccess:
+ NORMAL_EXCEPTION_PROLOG
+ mfspr r5,SPRN_ESR /* Grab the ESR, save it, pass arg3 */
+ stw r5,_ESR(r11)
+ mfspr r4,SPRN_DEAR /* Grab the DEAR, save it, pass arg2 */
+ EXC_XFER_EE_LITE(0x300, handle_page_fault)
+
+/* Other PowerPC processors, namely those derived from the 6xx-series
+ * have vectors from 0x2100 through 0x2F00 defined, but marked as reserved.
+ * However, for the 4xx-series processors these are neither defined nor
+ * reserved.
+ */
+
+ /* Damn, I came up one instruction too many to fit into the
+ * exception space :-). Both the instruction and data TLB
+ * miss get to this point to load the TLB.
+ * r10 - TLB_TAG value
+ * r11 - Linux PTE
+ * r12, r9 - avilable to use
+ * PID - loaded with proper value when we get here
+ * Upon exit, we reload everything and RFI.
+ * Actually, it will fit now, but oh well.....a common place
+ * to load the TLB.
+ */
+tlb_4xx_index:
+ .long 0
+finish_tlb_load:
+ /* load the next available TLB index.
+ */
+ lwz r9, tlb_4xx_index@l(0)
+ addi r9, r9, 1
+ andi. r9, r9, (PPC4XX_TLB_SIZE-1)
+ stw r9, tlb_4xx_index@l(0)
+
+6:
+ /*
+ * Clear out the software-only bits in the PTE to generate the
+ * TLB_DATA value. These are the bottom 2 bits of the RPM, the
+ * top 3 bits of the zone field, and M.
+ */
+ li r12, 0x0ce2
+ andc r11, r11, r12
+
+ tlbwe r11, r9, TLB_DATA /* Load TLB LO */
+ tlbwe r10, r9, TLB_TAG /* Load TLB HI */
+
+ /* Done...restore registers and get out of here.
+ */
+#ifdef CONFIG_403GCX
+ lwz r12, 12(r0)
+ lwz r11, 8(r0)
+ mtspr SPRN_PID, r12
+ mtcr r11
+ lwz r9, 4(r0)
+ lwz r12, 0(r0)
+#else
+ mfspr r12, SPRN_SPRG6
+ mfspr r11, SPRN_SPRG7
+ mtspr SPRN_PID, r12
+ mtcr r11
+ mfspr r9, SPRN_SPRG5
+ mfspr r12, SPRN_SPRG4
+#endif
+ mfspr r11, SPRN_SPRG1
+ mfspr r10, SPRN_SPRG0
+ PPC405_ERR77_SYNC
+ rfi /* Should sync shadow TLBs */
+ b . /* prevent prefetch past rfi */
+
+/* extern void giveup_fpu(struct task_struct *prev)
+ *
+ * The PowerPC 4xx family of processors do not have an FPU, so this just
+ * returns.
+ */
+_GLOBAL(giveup_fpu)
+ blr
+
+/* This is where the main kernel code starts.
+ */
+start_here:
+
+ /* ptr to current */
+ lis r2,init_task@h
+ ori r2,r2,init_task@l
+
+ /* ptr to phys current thread */
+ tophys(r4,r2)
+ addi r4,r4,THREAD /* init task's THREAD */
+ mtspr SPRN_SPRG3,r4
+
+ /* stack */
+ lis r1,init_thread_union@ha
+ addi r1,r1,init_thread_union@l
+ li r0,0
+ stwu r0,THREAD_SIZE-STACK_FRAME_OVERHEAD(r1)
+
+ bl early_init /* We have to do this with MMU on */
+
+/*
+ * Decide what sort of machine this is and initialize the MMU.
+ */
+ mr r3,r31
+ mr r4,r30
+ mr r5,r29
+ mr r6,r28
+ mr r7,r27
+ bl machine_init
+ bl MMU_init
+
+/* Go back to running unmapped so we can load up new values
+ * and change to using our exception vectors.
+ * On the 4xx, all we have to do is invalidate the TLB to clear
+ * the old 16M byte TLB mappings.
+ */
+ lis r4,2f@h
+ ori r4,r4,2f@l
+ tophys(r4,r4)
+ lis r3,(MSR_KERNEL & ~(MSR_IR|MSR_DR))@h
+ ori r3,r3,(MSR_KERNEL & ~(MSR_IR|MSR_DR))@l
+ mtspr SPRN_SRR0,r4
+ mtspr SPRN_SRR1,r3
+ rfi
+ b . /* prevent prefetch past rfi */
+
+/* Load up the kernel context */
+2:
+ sync /* Flush to memory before changing TLB */
+ tlbia
+ isync /* Flush shadow TLBs */
+
+ /* set up the PTE pointers for the Abatron bdiGDB.
+ */
+ lis r6, swapper_pg_dir@h
+ ori r6, r6, swapper_pg_dir@l
+ lis r5, abatron_pteptrs@h
+ ori r5, r5, abatron_pteptrs@l
+ stw r5, 0xf0(r0) /* Must match your Abatron config file */
+ tophys(r5,r5)
+ stw r6, 0(r5)
+
+/* Now turn on the MMU for real! */
+ lis r4,MSR_KERNEL@h
+ ori r4,r4,MSR_KERNEL@l
+ lis r3,start_kernel@h
+ ori r3,r3,start_kernel@l
+ mtspr SPRN_SRR0,r3
+ mtspr SPRN_SRR1,r4
+ rfi /* enable MMU and jump to start_kernel */
+ b . /* prevent prefetch past rfi */
+
+/* Set up the initial MMU state so we can do the first level of
+ * kernel initialization. This maps the first 16 MBytes of memory 1:1
+ * virtual to physical and more importantly sets the cache mode.
+ */
+initial_mmu:
+ tlbia /* Invalidate all TLB entries */
+ isync
+
+ /* We should still be executing code at physical address 0x0000xxxx
+ * at this point. However, start_here is at virtual address
+ * 0xC000xxxx. So, set up a TLB mapping to cover this once
+ * translation is enabled.
+ */
+
+ lis r3,KERNELBASE@h /* Load the kernel virtual address */
+ ori r3,r3,KERNELBASE@l
+ tophys(r4,r3) /* Load the kernel physical address */
+
+ iccci r0,r3 /* Invalidate the i-cache before use */
+
+ /* Load the kernel PID.
+ */
+ li r0,0
+ mtspr SPRN_PID,r0
+ sync
+
+ /* Configure and load two entries into TLB slots 62 and 63.
+ * In case we are pinning TLBs, these are reserved in by the
+ * other TLB functions. If not reserving, then it doesn't
+ * matter where they are loaded.
+ */
+ clrrwi r4,r4,10 /* Mask off the real page number */
+ ori r4,r4,(TLB_WR | TLB_EX) /* Set the write and execute bits */
+
+ clrrwi r3,r3,10 /* Mask off the effective page number */
+ ori r3,r3,(TLB_VALID | TLB_PAGESZ(PAGESZ_16M))
+
+ li r0,63 /* TLB slot 63 */
+
+ tlbwe r4,r0,TLB_DATA /* Load the data portion of the entry */
+ tlbwe r3,r0,TLB_TAG /* Load the tag portion of the entry */
+
+#if defined(CONFIG_SERIAL_TEXT_DEBUG) && defined(SERIAL_DEBUG_IO_BASE)
+
+ /* Load a TLB entry for the UART, so that ppc4xx_progress() can use
+ * the UARTs nice and early. We use a 4k real==virtual mapping. */
+
+ lis r3,SERIAL_DEBUG_IO_BASE@h
+ ori r3,r3,SERIAL_DEBUG_IO_BASE@l
+ mr r4,r3
+ clrrwi r4,r4,12
+ ori r4,r4,(TLB_WR|TLB_I|TLB_M|TLB_G)
+
+ clrrwi r3,r3,12
+ ori r3,r3,(TLB_VALID | TLB_PAGESZ(PAGESZ_4K))
+
+ li r0,0 /* TLB slot 0 */
+ tlbwe r4,r0,TLB_DATA
+ tlbwe r3,r0,TLB_TAG
+#endif /* CONFIG_SERIAL_DEBUG_TEXT && SERIAL_DEBUG_IO_BASE */
+
+ isync
+
+ /* Establish the exception vector base
+ */
+ lis r4,KERNELBASE@h /* EVPR only uses the high 16-bits */
+ tophys(r0,r4) /* Use the physical address */
+ mtspr SPRN_EVPR,r0
+
+ blr
+
+_GLOBAL(abort)
+ mfspr r13,SPRN_DBCR0
+ oris r13,r13,DBCR0_RST_SYSTEM@h
+ mtspr SPRN_DBCR0,r13
+
+_GLOBAL(set_context)
+
+#ifdef CONFIG_BDI_SWITCH
+ /* Context switch the PTE pointer for the Abatron BDI2000.
+ * The PGDIR is the second parameter.
+ */
+ lis r5, KERNELBASE@h
+ lwz r5, 0xf0(r5)
+ stw r4, 0x4(r5)
+#endif
+ sync
+ mtspr SPRN_PID,r3
+ isync /* Need an isync to flush shadow */
+ /* TLBs after changing PID */
+ blr
+
+/* We put a few things here that have to be page-aligned. This stuff
+ * goes at the beginning of the data segment, which is page-aligned.
+ */
+ .data
+ .align 12
+ .globl sdata
+sdata:
+ .globl empty_zero_page
+empty_zero_page:
+ .space 4096
+ .globl swapper_pg_dir
+swapper_pg_dir:
+ .space 4096
+
+
+/* Stack for handling critical exceptions from kernel mode */
+ .section .bss
+ .align 12
+exception_stack_bottom:
+ .space 4096
+critical_stack_top:
+ .globl exception_stack_top
+exception_stack_top:
+
+/* This space gets a copy of optional info passed to us by the bootstrap
+ * which is used to pass parameters into the kernel like root=/dev/sda1, etc.
+ */
+ .globl cmd_line
+cmd_line:
+ .space 512
+
+/* Room for two PTE pointers, usually the kernel and current user pointers
+ * to their respective root page table.
+ */
+abatron_pteptrs:
+ .space 8
diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S
new file mode 100644
index 000000000000..8a8bf79ef044
--- /dev/null
+++ b/arch/powerpc/kernel/head_64.S
@@ -0,0 +1,2010 @@
+/*
+ * arch/ppc64/kernel/head.S
+ *
+ * PowerPC version
+ * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
+ *
+ * Rewritten by Cort Dougan (cort@cs.nmt.edu) for PReP
+ * Copyright (C) 1996 Cort Dougan <cort@cs.nmt.edu>
+ * Adapted for Power Macintosh by Paul Mackerras.
+ * Low-level exception handlers and MMU support
+ * rewritten by Paul Mackerras.
+ * Copyright (C) 1996 Paul Mackerras.
+ *
+ * Adapted for 64bit PowerPC by Dave Engebretsen, Peter Bergner, and
+ * Mike Corrigan {engebret|bergner|mikejc}@us.ibm.com
+ *
+ * This file contains the low-level support and setup for the
+ * PowerPC-64 platform, including trap and interrupt dispatch.
+ *
+ * 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/config.h>
+#include <linux/threads.h>
+#include <asm/reg.h>
+#include <asm/page.h>
+#include <asm/mmu.h>
+#include <asm/ppc_asm.h>
+#include <asm/asm-offsets.h>
+#include <asm/bug.h>
+#include <asm/cputable.h>
+#include <asm/setup.h>
+#include <asm/hvcall.h>
+#include <asm/iseries/lpar_map.h>
+#include <asm/thread_info.h>
+
+#ifdef CONFIG_PPC_ISERIES
+#define DO_SOFT_DISABLE
+#endif
+
+/*
+ * We layout physical memory as follows:
+ * 0x0000 - 0x00ff : Secondary processor spin code
+ * 0x0100 - 0x2fff : pSeries Interrupt prologs
+ * 0x3000 - 0x5fff : interrupt support, iSeries and common interrupt prologs
+ * 0x6000 - 0x6fff : Initial (CPU0) segment table
+ * 0x7000 - 0x7fff : FWNMI data area
+ * 0x8000 - : Early init and support code
+ */
+
+/*
+ * SPRG Usage
+ *
+ * Register Definition
+ *
+ * SPRG0 reserved for hypervisor
+ * SPRG1 temp - used to save gpr
+ * SPRG2 temp - used to save gpr
+ * SPRG3 virt addr of paca
+ */
+
+/*
+ * Entering into this code we make the following assumptions:
+ * For pSeries:
+ * 1. The MMU is off & open firmware is running in real mode.
+ * 2. The kernel is entered at __start
+ *
+ * For iSeries:
+ * 1. The MMU is on (as it always is for iSeries)
+ * 2. The kernel is entered at system_reset_iSeries
+ */
+
+ .text
+ .globl _stext
+_stext:
+#ifdef CONFIG_PPC_MULTIPLATFORM
+_GLOBAL(__start)
+ /* NOP this out unconditionally */
+BEGIN_FTR_SECTION
+ b .__start_initialization_multiplatform
+END_FTR_SECTION(0, 1)
+#endif /* CONFIG_PPC_MULTIPLATFORM */
+
+ /* Catch branch to 0 in real mode */
+ trap
+
+#ifdef CONFIG_PPC_ISERIES
+ /*
+ * At offset 0x20, there is a pointer to iSeries LPAR data.
+ * This is required by the hypervisor
+ */
+ . = 0x20
+ .llong hvReleaseData-KERNELBASE
+
+ /*
+ * At offset 0x28 and 0x30 are offsets to the mschunks_map
+ * array (used by the iSeries LPAR debugger to do translation
+ * between physical addresses and absolute addresses) and
+ * to the pidhash table (also used by the debugger)
+ */
+ .llong mschunks_map-KERNELBASE
+ .llong 0 /* pidhash-KERNELBASE SFRXXX */
+
+ /* Offset 0x38 - Pointer to start of embedded System.map */
+ .globl embedded_sysmap_start
+embedded_sysmap_start:
+ .llong 0
+ /* Offset 0x40 - Pointer to end of embedded System.map */
+ .globl embedded_sysmap_end
+embedded_sysmap_end:
+ .llong 0
+
+#endif /* CONFIG_PPC_ISERIES */
+
+ /* Secondary processors spin on this value until it goes to 1. */
+ .globl __secondary_hold_spinloop
+__secondary_hold_spinloop:
+ .llong 0x0
+
+ /* Secondary processors write this value with their cpu # */
+ /* after they enter the spin loop immediately below. */
+ .globl __secondary_hold_acknowledge
+__secondary_hold_acknowledge:
+ .llong 0x0
+
+ . = 0x60
+/*
+ * The following code is used on pSeries to hold secondary processors
+ * in a spin loop after they have been freed from OpenFirmware, but
+ * before the bulk of the kernel has been relocated. This code
+ * is relocated to physical address 0x60 before prom_init is run.
+ * All of it must fit below the first exception vector at 0x100.
+ */
+_GLOBAL(__secondary_hold)
+ mfmsr r24
+ ori r24,r24,MSR_RI
+ mtmsrd r24 /* RI on */
+
+ /* Grab our linux cpu number */
+ mr r24,r3
+
+ /* Tell the master cpu we're here */
+ /* Relocation is off & we are located at an address less */
+ /* than 0x100, so only need to grab low order offset. */
+ std r24,__secondary_hold_acknowledge@l(0)
+ sync
+
+ /* All secondary cpus wait here until told to start. */
+100: ld r4,__secondary_hold_spinloop@l(0)
+ cmpdi 0,r4,1
+ bne 100b
+
+#ifdef CONFIG_HMT
+ b .hmt_init
+#else
+#ifdef CONFIG_SMP
+ mr r3,r24
+ b .pSeries_secondary_smp_init
+#else
+ BUG_OPCODE
+#endif
+#endif
+
+/* This value is used to mark exception frames on the stack. */
+ .section ".toc","aw"
+exception_marker:
+ .tc ID_72656773_68657265[TC],0x7265677368657265
+ .text
+
+/*
+ * The following macros define the code that appears as
+ * the prologue to each of the exception handlers. They
+ * are split into two parts to allow a single kernel binary
+ * to be used for pSeries and iSeries.
+ * LOL. One day... - paulus
+ */
+
+/*
+ * We make as much of the exception code common between native
+ * exception handlers (including pSeries LPAR) and iSeries LPAR
+ * implementations as possible.
+ */
+
+/*
+ * This is the start of the interrupt handlers for pSeries
+ * This code runs with relocation off.
+ */
+#define EX_R9 0
+#define EX_R10 8
+#define EX_R11 16
+#define EX_R12 24
+#define EX_R13 32
+#define EX_SRR0 40
+#define EX_DAR 48
+#define EX_DSISR 56
+#define EX_CCR 60
+#define EX_R3 64
+#define EX_LR 72
+
+#define EXCEPTION_PROLOG_PSERIES(area, label) \
+ mfspr r13,SPRN_SPRG3; /* get paca address into r13 */ \
+ std r9,area+EX_R9(r13); /* save r9 - r12 */ \
+ std r10,area+EX_R10(r13); \
+ std r11,area+EX_R11(r13); \
+ std r12,area+EX_R12(r13); \
+ mfspr r9,SPRN_SPRG1; \
+ std r9,area+EX_R13(r13); \
+ mfcr r9; \
+ clrrdi r12,r13,32; /* get high part of &label */ \
+ mfmsr r10; \
+ mfspr r11,SPRN_SRR0; /* save SRR0 */ \
+ ori r12,r12,(label)@l; /* virt addr of handler */ \
+ ori r10,r10,MSR_IR|MSR_DR|MSR_RI; \
+ mtspr SPRN_SRR0,r12; \
+ mfspr r12,SPRN_SRR1; /* and SRR1 */ \
+ mtspr SPRN_SRR1,r10; \
+ rfid; \
+ b . /* prevent speculative execution */
+
+/*
+ * This is the start of the interrupt handlers for iSeries
+ * This code runs with relocation on.
+ */
+#define EXCEPTION_PROLOG_ISERIES_1(area) \
+ mfspr r13,SPRN_SPRG3; /* get paca address into r13 */ \
+ std r9,area+EX_R9(r13); /* save r9 - r12 */ \
+ std r10,area+EX_R10(r13); \
+ std r11,area+EX_R11(r13); \
+ std r12,area+EX_R12(r13); \
+ mfspr r9,SPRN_SPRG1; \
+ std r9,area+EX_R13(r13); \
+ mfcr r9
+
+#define EXCEPTION_PROLOG_ISERIES_2 \
+ mfmsr r10; \
+ ld r11,PACALPPACA+LPPACASRR0(r13); \
+ ld r12,PACALPPACA+LPPACASRR1(r13); \
+ ori r10,r10,MSR_RI; \
+ mtmsrd r10,1
+
+/*
+ * The common exception prolog is used for all except a few exceptions
+ * such as a segment miss on a kernel address. We have to be prepared
+ * to take another exception from the point where we first touch the
+ * kernel stack onwards.
+ *
+ * On entry r13 points to the paca, r9-r13 are saved in the paca,
+ * r9 contains the saved CR, r11 and r12 contain the saved SRR0 and
+ * SRR1, and relocation is on.
+ */
+#define EXCEPTION_PROLOG_COMMON(n, area) \
+ andi. r10,r12,MSR_PR; /* See if coming from user */ \
+ mr r10,r1; /* Save r1 */ \
+ subi r1,r1,INT_FRAME_SIZE; /* alloc frame on kernel stack */ \
+ beq- 1f; \
+ ld r1,PACAKSAVE(r13); /* kernel stack to use */ \
+1: cmpdi cr1,r1,0; /* check if r1 is in userspace */ \
+ bge- cr1,bad_stack; /* abort if it is */ \
+ std r9,_CCR(r1); /* save CR in stackframe */ \
+ std r11,_NIP(r1); /* save SRR0 in stackframe */ \
+ std r12,_MSR(r1); /* save SRR1 in stackframe */ \
+ std r10,0(r1); /* make stack chain pointer */ \
+ std r0,GPR0(r1); /* save r0 in stackframe */ \
+ std r10,GPR1(r1); /* save r1 in stackframe */ \
+ std r2,GPR2(r1); /* save r2 in stackframe */ \
+ SAVE_4GPRS(3, r1); /* save r3 - r6 in stackframe */ \
+ SAVE_2GPRS(7, r1); /* save r7, r8 in stackframe */ \
+ ld r9,area+EX_R9(r13); /* move r9, r10 to stackframe */ \
+ ld r10,area+EX_R10(r13); \
+ std r9,GPR9(r1); \
+ std r10,GPR10(r1); \
+ ld r9,area+EX_R11(r13); /* move r11 - r13 to stackframe */ \
+ ld r10,area+EX_R12(r13); \
+ ld r11,area+EX_R13(r13); \
+ std r9,GPR11(r1); \
+ std r10,GPR12(r1); \
+ std r11,GPR13(r1); \
+ ld r2,PACATOC(r13); /* get kernel TOC into r2 */ \
+ mflr r9; /* save LR in stackframe */ \
+ std r9,_LINK(r1); \
+ mfctr r10; /* save CTR in stackframe */ \
+ std r10,_CTR(r1); \
+ mfspr r11,SPRN_XER; /* save XER in stackframe */ \
+ std r11,_XER(r1); \
+ li r9,(n)+1; \
+ std r9,_TRAP(r1); /* set trap number */ \
+ li r10,0; \
+ ld r11,exception_marker@toc(r2); \
+ std r10,RESULT(r1); /* clear regs->result */ \
+ std r11,STACK_FRAME_OVERHEAD-16(r1); /* mark the frame */
+
+/*
+ * Exception vectors.
+ */
+#define STD_EXCEPTION_PSERIES(n, label) \
+ . = n; \
+ .globl label##_pSeries; \
+label##_pSeries: \
+ HMT_MEDIUM; \
+ mtspr SPRN_SPRG1,r13; /* save r13 */ \
+ RUNLATCH_ON(r13); \
+ EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common)
+
+#define STD_EXCEPTION_ISERIES(n, label, area) \
+ .globl label##_iSeries; \
+label##_iSeries: \
+ HMT_MEDIUM; \
+ mtspr SPRN_SPRG1,r13; /* save r13 */ \
+ RUNLATCH_ON(r13); \
+ EXCEPTION_PROLOG_ISERIES_1(area); \
+ EXCEPTION_PROLOG_ISERIES_2; \
+ b label##_common
+
+#define MASKABLE_EXCEPTION_ISERIES(n, label) \
+ .globl label##_iSeries; \
+label##_iSeries: \
+ HMT_MEDIUM; \
+ mtspr SPRN_SPRG1,r13; /* save r13 */ \
+ RUNLATCH_ON(r13); \
+ EXCEPTION_PROLOG_ISERIES_1(PACA_EXGEN); \
+ lbz r10,PACAPROCENABLED(r13); \
+ cmpwi 0,r10,0; \
+ beq- label##_iSeries_masked; \
+ EXCEPTION_PROLOG_ISERIES_2; \
+ b label##_common; \
+
+#ifdef DO_SOFT_DISABLE
+#define DISABLE_INTS \
+ lbz r10,PACAPROCENABLED(r13); \
+ li r11,0; \
+ std r10,SOFTE(r1); \
+ mfmsr r10; \
+ stb r11,PACAPROCENABLED(r13); \
+ ori r10,r10,MSR_EE; \
+ mtmsrd r10,1
+
+#define ENABLE_INTS \
+ lbz r10,PACAPROCENABLED(r13); \
+ mfmsr r11; \
+ std r10,SOFTE(r1); \
+ ori r11,r11,MSR_EE; \
+ mtmsrd r11,1
+
+#else /* hard enable/disable interrupts */
+#define DISABLE_INTS
+
+#define ENABLE_INTS \
+ ld r12,_MSR(r1); \
+ mfmsr r11; \
+ rlwimi r11,r12,0,MSR_EE; \
+ mtmsrd r11,1
+
+#endif
+
+#define STD_EXCEPTION_COMMON(trap, label, hdlr) \
+ .align 7; \
+ .globl label##_common; \
+label##_common: \
+ EXCEPTION_PROLOG_COMMON(trap, PACA_EXGEN); \
+ DISABLE_INTS; \
+ bl .save_nvgprs; \
+ addi r3,r1,STACK_FRAME_OVERHEAD; \
+ bl hdlr; \
+ b .ret_from_except
+
+#define STD_EXCEPTION_COMMON_LITE(trap, label, hdlr) \
+ .align 7; \
+ .globl label##_common; \
+label##_common: \
+ EXCEPTION_PROLOG_COMMON(trap, PACA_EXGEN); \
+ DISABLE_INTS; \
+ addi r3,r1,STACK_FRAME_OVERHEAD; \
+ bl hdlr; \
+ b .ret_from_except_lite
+
+/*
+ * Start of pSeries system interrupt routines
+ */
+ . = 0x100
+ .globl __start_interrupts
+__start_interrupts:
+
+ STD_EXCEPTION_PSERIES(0x100, system_reset)
+
+ . = 0x200
+_machine_check_pSeries:
+ HMT_MEDIUM
+ mtspr SPRN_SPRG1,r13 /* save r13 */
+ RUNLATCH_ON(r13)
+ EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common)
+
+ . = 0x300
+ .globl data_access_pSeries
+data_access_pSeries:
+ HMT_MEDIUM
+ mtspr SPRN_SPRG1,r13
+BEGIN_FTR_SECTION
+ mtspr SPRN_SPRG2,r12
+ mfspr r13,SPRN_DAR
+ mfspr r12,SPRN_DSISR
+ srdi r13,r13,60
+ rlwimi r13,r12,16,0x20
+ mfcr r12
+ cmpwi r13,0x2c
+ beq .do_stab_bolted_pSeries
+ mtcrf 0x80,r12
+ mfspr r12,SPRN_SPRG2
+END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
+ EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, data_access_common)
+
+ . = 0x380
+ .globl data_access_slb_pSeries
+data_access_slb_pSeries:
+ HMT_MEDIUM
+ mtspr SPRN_SPRG1,r13
+ RUNLATCH_ON(r13)
+ mfspr r13,SPRN_SPRG3 /* get paca address into r13 */
+ std r3,PACA_EXSLB+EX_R3(r13)
+ mfspr r3,SPRN_DAR
+ std r9,PACA_EXSLB+EX_R9(r13) /* save r9 - r12 */
+ mfcr r9
+#ifdef __DISABLED__
+ /* Keep that around for when we re-implement dynamic VSIDs */
+ cmpdi r3,0
+ bge slb_miss_user_pseries
+#endif /* __DISABLED__ */
+ std r10,PACA_EXSLB+EX_R10(r13)
+ std r11,PACA_EXSLB+EX_R11(r13)
+ std r12,PACA_EXSLB+EX_R12(r13)
+ mfspr r10,SPRN_SPRG1
+ std r10,PACA_EXSLB+EX_R13(r13)
+ mfspr r12,SPRN_SRR1 /* and SRR1 */
+ b .slb_miss_realmode /* Rel. branch works in real mode */
+
+ STD_EXCEPTION_PSERIES(0x400, instruction_access)
+
+ . = 0x480
+ .globl instruction_access_slb_pSeries
+instruction_access_slb_pSeries:
+ HMT_MEDIUM
+ mtspr SPRN_SPRG1,r13
+ RUNLATCH_ON(r13)
+ mfspr r13,SPRN_SPRG3 /* get paca address into r13 */
+ std r3,PACA_EXSLB+EX_R3(r13)
+ mfspr r3,SPRN_SRR0 /* SRR0 is faulting address */
+ std r9,PACA_EXSLB+EX_R9(r13) /* save r9 - r12 */
+ mfcr r9
+#ifdef __DISABLED__
+ /* Keep that around for when we re-implement dynamic VSIDs */
+ cmpdi r3,0
+ bge slb_miss_user_pseries
+#endif /* __DISABLED__ */
+ std r10,PACA_EXSLB+EX_R10(r13)
+ std r11,PACA_EXSLB+EX_R11(r13)
+ std r12,PACA_EXSLB+EX_R12(r13)
+ mfspr r10,SPRN_SPRG1
+ std r10,PACA_EXSLB+EX_R13(r13)
+ mfspr r12,SPRN_SRR1 /* and SRR1 */
+ b .slb_miss_realmode /* Rel. branch works in real mode */
+
+ STD_EXCEPTION_PSERIES(0x500, hardware_interrupt)
+ STD_EXCEPTION_PSERIES(0x600, alignment)
+ STD_EXCEPTION_PSERIES(0x700, program_check)
+ STD_EXCEPTION_PSERIES(0x800, fp_unavailable)
+ STD_EXCEPTION_PSERIES(0x900, decrementer)
+ STD_EXCEPTION_PSERIES(0xa00, trap_0a)
+ STD_EXCEPTION_PSERIES(0xb00, trap_0b)
+
+ . = 0xc00
+ .globl system_call_pSeries
+system_call_pSeries:
+ HMT_MEDIUM
+ RUNLATCH_ON(r9)
+ mr r9,r13
+ mfmsr r10
+ mfspr r13,SPRN_SPRG3
+ mfspr r11,SPRN_SRR0
+ clrrdi r12,r13,32
+ oris r12,r12,system_call_common@h
+ ori r12,r12,system_call_common@l
+ mtspr SPRN_SRR0,r12
+ ori r10,r10,MSR_IR|MSR_DR|MSR_RI
+ mfspr r12,SPRN_SRR1
+ mtspr SPRN_SRR1,r10
+ rfid
+ b . /* prevent speculative execution */
+
+ STD_EXCEPTION_PSERIES(0xd00, single_step)
+ STD_EXCEPTION_PSERIES(0xe00, trap_0e)
+
+ /* We need to deal with the Altivec unavailable exception
+ * here which is at 0xf20, thus in the middle of the
+ * prolog code of the PerformanceMonitor one. A little
+ * trickery is thus necessary
+ */
+ . = 0xf00
+ b performance_monitor_pSeries
+
+ STD_EXCEPTION_PSERIES(0xf20, altivec_unavailable)
+
+ STD_EXCEPTION_PSERIES(0x1300, instruction_breakpoint)
+ STD_EXCEPTION_PSERIES(0x1700, altivec_assist)
+
+ . = 0x3000
+
+/*** pSeries interrupt support ***/
+
+ /* moved from 0xf00 */
+ STD_EXCEPTION_PSERIES(., performance_monitor)
+
+ .align 7
+_GLOBAL(do_stab_bolted_pSeries)
+ mtcrf 0x80,r12
+ mfspr r12,SPRN_SPRG2
+ EXCEPTION_PROLOG_PSERIES(PACA_EXSLB, .do_stab_bolted)
+
+/*
+ * We have some room here we use that to put
+ * the peries slb miss user trampoline code so it's reasonably
+ * away from slb_miss_user_common to avoid problems with rfid
+ *
+ * This is used for when the SLB miss handler has to go virtual,
+ * which doesn't happen for now anymore but will once we re-implement
+ * dynamic VSIDs for shared page tables
+ */
+#ifdef __DISABLED__
+slb_miss_user_pseries:
+ std r10,PACA_EXGEN+EX_R10(r13)
+ std r11,PACA_EXGEN+EX_R11(r13)
+ std r12,PACA_EXGEN+EX_R12(r13)
+ mfspr r10,SPRG1
+ ld r11,PACA_EXSLB+EX_R9(r13)
+ ld r12,PACA_EXSLB+EX_R3(r13)
+ std r10,PACA_EXGEN+EX_R13(r13)
+ std r11,PACA_EXGEN+EX_R9(r13)
+ std r12,PACA_EXGEN+EX_R3(r13)
+ clrrdi r12,r13,32
+ mfmsr r10
+ mfspr r11,SRR0 /* save SRR0 */
+ ori r12,r12,slb_miss_user_common@l /* virt addr of handler */
+ ori r10,r10,MSR_IR|MSR_DR|MSR_RI
+ mtspr SRR0,r12
+ mfspr r12,SRR1 /* and SRR1 */
+ mtspr SRR1,r10
+ rfid
+ b . /* prevent spec. execution */
+#endif /* __DISABLED__ */
+
+/*
+ * Vectors for the FWNMI option. Share common code.
+ */
+ .globl system_reset_fwnmi
+system_reset_fwnmi:
+ HMT_MEDIUM
+ mtspr SPRN_SPRG1,r13 /* save r13 */
+ RUNLATCH_ON(r13)
+ EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, system_reset_common)
+
+ .globl machine_check_fwnmi
+machine_check_fwnmi:
+ HMT_MEDIUM
+ mtspr SPRN_SPRG1,r13 /* save r13 */
+ RUNLATCH_ON(r13)
+ EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common)
+
+#ifdef CONFIG_PPC_ISERIES
+/*** ISeries-LPAR interrupt handlers ***/
+
+ STD_EXCEPTION_ISERIES(0x200, machine_check, PACA_EXMC)
+
+ .globl data_access_iSeries
+data_access_iSeries:
+ mtspr SPRN_SPRG1,r13
+BEGIN_FTR_SECTION
+ mtspr SPRN_SPRG2,r12
+ mfspr r13,SPRN_DAR
+ mfspr r12,SPRN_DSISR
+ srdi r13,r13,60
+ rlwimi r13,r12,16,0x20
+ mfcr r12
+ cmpwi r13,0x2c
+ beq .do_stab_bolted_iSeries
+ mtcrf 0x80,r12
+ mfspr r12,SPRN_SPRG2
+END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
+ EXCEPTION_PROLOG_ISERIES_1(PACA_EXGEN)
+ EXCEPTION_PROLOG_ISERIES_2
+ b data_access_common
+
+.do_stab_bolted_iSeries:
+ mtcrf 0x80,r12
+ mfspr r12,SPRN_SPRG2
+ EXCEPTION_PROLOG_ISERIES_1(PACA_EXSLB)
+ EXCEPTION_PROLOG_ISERIES_2
+ b .do_stab_bolted
+
+ .globl data_access_slb_iSeries
+data_access_slb_iSeries:
+ mtspr SPRN_SPRG1,r13 /* save r13 */
+ mfspr r13,SPRN_SPRG3 /* get paca address into r13 */
+ std r3,PACA_EXSLB+EX_R3(r13)
+ mfspr r3,SPRN_DAR
+ std r9,PACA_EXSLB+EX_R9(r13)
+ mfcr r9
+#ifdef __DISABLED__
+ cmpdi r3,0
+ bge slb_miss_user_iseries
+#endif
+ std r10,PACA_EXSLB+EX_R10(r13)
+ std r11,PACA_EXSLB+EX_R11(r13)
+ std r12,PACA_EXSLB+EX_R12(r13)
+ mfspr r10,SPRN_SPRG1
+ std r10,PACA_EXSLB+EX_R13(r13)
+ ld r12,PACALPPACA+LPPACASRR1(r13);
+ b .slb_miss_realmode
+
+ STD_EXCEPTION_ISERIES(0x400, instruction_access, PACA_EXGEN)
+
+ .globl instruction_access_slb_iSeries
+instruction_access_slb_iSeries:
+ mtspr SPRN_SPRG1,r13 /* save r13 */
+ mfspr r13,SPRN_SPRG3 /* get paca address into r13 */
+ std r3,PACA_EXSLB+EX_R3(r13)
+ ld r3,PACALPPACA+LPPACASRR0(r13) /* get SRR0 value */
+ std r9,PACA_EXSLB+EX_R9(r13)
+ mfcr r9
+#ifdef __DISABLED__
+ cmpdi r3,0
+ bge .slb_miss_user_iseries
+#endif
+ std r10,PACA_EXSLB+EX_R10(r13)
+ std r11,PACA_EXSLB+EX_R11(r13)
+ std r12,PACA_EXSLB+EX_R12(r13)
+ mfspr r10,SPRN_SPRG1
+ std r10,PACA_EXSLB+EX_R13(r13)
+ ld r12,PACALPPACA+LPPACASRR1(r13);
+ b .slb_miss_realmode
+
+#ifdef __DISABLED__
+slb_miss_user_iseries:
+ std r10,PACA_EXGEN+EX_R10(r13)
+ std r11,PACA_EXGEN+EX_R11(r13)
+ std r12,PACA_EXGEN+EX_R12(r13)
+ mfspr r10,SPRG1
+ ld r11,PACA_EXSLB+EX_R9(r13)
+ ld r12,PACA_EXSLB+EX_R3(r13)
+ std r10,PACA_EXGEN+EX_R13(r13)
+ std r11,PACA_EXGEN+EX_R9(r13)
+ std r12,PACA_EXGEN+EX_R3(r13)
+ EXCEPTION_PROLOG_ISERIES_2
+ b slb_miss_user_common
+#endif
+
+ MASKABLE_EXCEPTION_ISERIES(0x500, hardware_interrupt)
+ STD_EXCEPTION_ISERIES(0x600, alignment, PACA_EXGEN)
+ STD_EXCEPTION_ISERIES(0x700, program_check, PACA_EXGEN)
+ STD_EXCEPTION_ISERIES(0x800, fp_unavailable, PACA_EXGEN)
+ MASKABLE_EXCEPTION_ISERIES(0x900, decrementer)
+ STD_EXCEPTION_ISERIES(0xa00, trap_0a, PACA_EXGEN)
+ STD_EXCEPTION_ISERIES(0xb00, trap_0b, PACA_EXGEN)
+
+ .globl system_call_iSeries
+system_call_iSeries:
+ mr r9,r13
+ mfspr r13,SPRN_SPRG3
+ EXCEPTION_PROLOG_ISERIES_2
+ b system_call_common
+
+ STD_EXCEPTION_ISERIES( 0xd00, single_step, PACA_EXGEN)
+ STD_EXCEPTION_ISERIES( 0xe00, trap_0e, PACA_EXGEN)
+ STD_EXCEPTION_ISERIES( 0xf00, performance_monitor, PACA_EXGEN)
+
+ .globl system_reset_iSeries
+system_reset_iSeries:
+ mfspr r13,SPRN_SPRG3 /* Get paca address */
+ mfmsr r24
+ ori r24,r24,MSR_RI
+ mtmsrd r24 /* RI on */
+ lhz r24,PACAPACAINDEX(r13) /* Get processor # */
+ cmpwi 0,r24,0 /* Are we processor 0? */
+ beq .__start_initialization_iSeries /* Start up the first processor */
+ mfspr r4,SPRN_CTRLF
+ li r5,CTRL_RUNLATCH /* Turn off the run light */
+ andc r4,r4,r5
+ mtspr SPRN_CTRLT,r4
+
+1:
+ HMT_LOW
+#ifdef CONFIG_SMP
+ lbz r23,PACAPROCSTART(r13) /* Test if this processor
+ * should start */
+ sync
+ LOADADDR(r3,current_set)
+ sldi r28,r24,3 /* get current_set[cpu#] */
+ ldx r3,r3,r28
+ addi r1,r3,THREAD_SIZE
+ subi r1,r1,STACK_FRAME_OVERHEAD
+
+ cmpwi 0,r23,0
+ beq iSeries_secondary_smp_loop /* Loop until told to go */
+ bne .__secondary_start /* Loop until told to go */
+iSeries_secondary_smp_loop:
+ /* Let the Hypervisor know we are alive */
+ /* 8002 is a call to HvCallCfg::getLps, a harmless Hypervisor function */
+ lis r3,0x8002
+ rldicr r3,r3,32,15 /* r0 = (r3 << 32) & 0xffff000000000000 */
+#else /* CONFIG_SMP */
+ /* Yield the processor. This is required for non-SMP kernels
+ which are running on multi-threaded machines. */
+ lis r3,0x8000
+ rldicr r3,r3,32,15 /* r3 = (r3 << 32) & 0xffff000000000000 */
+ addi r3,r3,18 /* r3 = 0x8000000000000012 which is "yield" */
+ li r4,0 /* "yield timed" */
+ li r5,-1 /* "yield forever" */
+#endif /* CONFIG_SMP */
+ li r0,-1 /* r0=-1 indicates a Hypervisor call */
+ sc /* Invoke the hypervisor via a system call */
+ mfspr r13,SPRN_SPRG3 /* Put r13 back ???? */
+ b 1b /* If SMP not configured, secondaries
+ * loop forever */
+
+ .globl decrementer_iSeries_masked
+decrementer_iSeries_masked:
+ li r11,1
+ stb r11,PACALPPACA+LPPACADECRINT(r13)
+ lwz r12,PACADEFAULTDECR(r13)
+ mtspr SPRN_DEC,r12
+ /* fall through */
+
+ .globl hardware_interrupt_iSeries_masked
+hardware_interrupt_iSeries_masked:
+ mtcrf 0x80,r9 /* Restore regs */
+ ld r11,PACALPPACA+LPPACASRR0(r13)
+ ld r12,PACALPPACA+LPPACASRR1(r13)
+ mtspr SPRN_SRR0,r11
+ mtspr SPRN_SRR1,r12
+ ld r9,PACA_EXGEN+EX_R9(r13)
+ ld r10,PACA_EXGEN+EX_R10(r13)
+ ld r11,PACA_EXGEN+EX_R11(r13)
+ ld r12,PACA_EXGEN+EX_R12(r13)
+ ld r13,PACA_EXGEN+EX_R13(r13)
+ rfid
+ b . /* prevent speculative execution */
+#endif /* CONFIG_PPC_ISERIES */
+
+/*** Common interrupt handlers ***/
+
+ STD_EXCEPTION_COMMON(0x100, system_reset, .system_reset_exception)
+
+ /*
+ * Machine check is different because we use a different
+ * save area: PACA_EXMC instead of PACA_EXGEN.
+ */
+ .align 7
+ .globl machine_check_common
+machine_check_common:
+ EXCEPTION_PROLOG_COMMON(0x200, PACA_EXMC)
+ DISABLE_INTS
+ bl .save_nvgprs
+ addi r3,r1,STACK_FRAME_OVERHEAD
+ bl .machine_check_exception
+ b .ret_from_except
+
+ STD_EXCEPTION_COMMON_LITE(0x900, decrementer, .timer_interrupt)
+ STD_EXCEPTION_COMMON(0xa00, trap_0a, .unknown_exception)
+ STD_EXCEPTION_COMMON(0xb00, trap_0b, .unknown_exception)
+ STD_EXCEPTION_COMMON(0xd00, single_step, .single_step_exception)
+ STD_EXCEPTION_COMMON(0xe00, trap_0e, .unknown_exception)
+ STD_EXCEPTION_COMMON(0xf00, performance_monitor, .performance_monitor_exception)
+ STD_EXCEPTION_COMMON(0x1300, instruction_breakpoint, .instruction_breakpoint_exception)
+#ifdef CONFIG_ALTIVEC
+ STD_EXCEPTION_COMMON(0x1700, altivec_assist, .altivec_assist_exception)
+#else
+ STD_EXCEPTION_COMMON(0x1700, altivec_assist, .unknown_exception)
+#endif
+
+/*
+ * Here we have detected that the kernel stack pointer is bad.
+ * R9 contains the saved CR, r13 points to the paca,
+ * r10 contains the (bad) kernel stack pointer,
+ * r11 and r12 contain the saved SRR0 and SRR1.
+ * We switch to using an emergency stack, save the registers there,
+ * and call kernel_bad_stack(), which panics.
+ */
+bad_stack:
+ ld r1,PACAEMERGSP(r13)
+ subi r1,r1,64+INT_FRAME_SIZE
+ std r9,_CCR(r1)
+ std r10,GPR1(r1)
+ std r11,_NIP(r1)
+ std r12,_MSR(r1)
+ mfspr r11,SPRN_DAR
+ mfspr r12,SPRN_DSISR
+ std r11,_DAR(r1)
+ std r12,_DSISR(r1)
+ mflr r10
+ mfctr r11
+ mfxer r12
+ std r10,_LINK(r1)
+ std r11,_CTR(r1)
+ std r12,_XER(r1)
+ SAVE_GPR(0,r1)
+ SAVE_GPR(2,r1)
+ SAVE_4GPRS(3,r1)
+ SAVE_2GPRS(7,r1)
+ SAVE_10GPRS(12,r1)
+ SAVE_10GPRS(22,r1)
+ addi r11,r1,INT_FRAME_SIZE
+ std r11,0(r1)
+ li r12,0
+ std r12,0(r11)
+ ld r2,PACATOC(r13)
+1: addi r3,r1,STACK_FRAME_OVERHEAD
+ bl .kernel_bad_stack
+ b 1b
+
+/*
+ * Return from an exception with minimal checks.
+ * The caller is assumed to have done EXCEPTION_PROLOG_COMMON.
+ * If interrupts have been enabled, or anything has been
+ * done that might have changed the scheduling status of
+ * any task or sent any task a signal, you should use
+ * ret_from_except or ret_from_except_lite instead of this.
+ */
+ .globl fast_exception_return
+fast_exception_return:
+ ld r12,_MSR(r1)
+ ld r11,_NIP(r1)
+ andi. r3,r12,MSR_RI /* check if RI is set */
+ beq- unrecov_fer
+ ld r3,_CCR(r1)
+ ld r4,_LINK(r1)
+ ld r5,_CTR(r1)
+ ld r6,_XER(r1)
+ mtcr r3
+ mtlr r4
+ mtctr r5
+ mtxer r6
+ REST_GPR(0, r1)
+ REST_8GPRS(2, r1)
+
+ mfmsr r10
+ clrrdi r10,r10,2 /* clear RI (LE is 0 already) */
+ mtmsrd r10,1
+
+ mtspr SPRN_SRR1,r12
+ mtspr SPRN_SRR0,r11
+ REST_4GPRS(10, r1)
+ ld r1,GPR1(r1)
+ rfid
+ b . /* prevent speculative execution */
+
+unrecov_fer:
+ bl .save_nvgprs
+1: addi r3,r1,STACK_FRAME_OVERHEAD
+ bl .unrecoverable_exception
+ b 1b
+
+/*
+ * Here r13 points to the paca, r9 contains the saved CR,
+ * SRR0 and SRR1 are saved in r11 and r12,
+ * r9 - r13 are saved in paca->exgen.
+ */
+ .align 7
+ .globl data_access_common
+data_access_common:
+ RUNLATCH_ON(r10) /* It wont fit in the 0x300 handler */
+ mfspr r10,SPRN_DAR
+ std r10,PACA_EXGEN+EX_DAR(r13)
+ mfspr r10,SPRN_DSISR
+ stw r10,PACA_EXGEN+EX_DSISR(r13)
+ EXCEPTION_PROLOG_COMMON(0x300, PACA_EXGEN)
+ ld r3,PACA_EXGEN+EX_DAR(r13)
+ lwz r4,PACA_EXGEN+EX_DSISR(r13)
+ li r5,0x300
+ b .do_hash_page /* Try to handle as hpte fault */
+
+ .align 7
+ .globl instruction_access_common
+instruction_access_common:
+ EXCEPTION_PROLOG_COMMON(0x400, PACA_EXGEN)
+ ld r3,_NIP(r1)
+ andis. r4,r12,0x5820
+ li r5,0x400
+ b .do_hash_page /* Try to handle as hpte fault */
+
+/*
+ * Here is the common SLB miss user that is used when going to virtual
+ * mode for SLB misses, that is currently not used
+ */
+#ifdef __DISABLED__
+ .align 7
+ .globl slb_miss_user_common
+slb_miss_user_common:
+ mflr r10
+ std r3,PACA_EXGEN+EX_DAR(r13)
+ stw r9,PACA_EXGEN+EX_CCR(r13)
+ std r10,PACA_EXGEN+EX_LR(r13)
+ std r11,PACA_EXGEN+EX_SRR0(r13)
+ bl .slb_allocate_user
+
+ ld r10,PACA_EXGEN+EX_LR(r13)
+ ld r3,PACA_EXGEN+EX_R3(r13)
+ lwz r9,PACA_EXGEN+EX_CCR(r13)
+ ld r11,PACA_EXGEN+EX_SRR0(r13)
+ mtlr r10
+ beq- slb_miss_fault
+
+ andi. r10,r12,MSR_RI /* check for unrecoverable exception */
+ beq- unrecov_user_slb
+ mfmsr r10
+
+.machine push
+.machine "power4"
+ mtcrf 0x80,r9
+.machine pop
+
+ clrrdi r10,r10,2 /* clear RI before setting SRR0/1 */
+ mtmsrd r10,1
+
+ mtspr SRR0,r11
+ mtspr SRR1,r12
+
+ ld r9,PACA_EXGEN+EX_R9(r13)
+ ld r10,PACA_EXGEN+EX_R10(r13)
+ ld r11,PACA_EXGEN+EX_R11(r13)
+ ld r12,PACA_EXGEN+EX_R12(r13)
+ ld r13,PACA_EXGEN+EX_R13(r13)
+ rfid
+ b .
+
+slb_miss_fault:
+ EXCEPTION_PROLOG_COMMON(0x380, PACA_EXGEN)
+ ld r4,PACA_EXGEN+EX_DAR(r13)
+ li r5,0
+ std r4,_DAR(r1)
+ std r5,_DSISR(r1)
+ b .handle_page_fault
+
+unrecov_user_slb:
+ EXCEPTION_PROLOG_COMMON(0x4200, PACA_EXGEN)
+ DISABLE_INTS
+ bl .save_nvgprs
+1: addi r3,r1,STACK_FRAME_OVERHEAD
+ bl .unrecoverable_exception
+ b 1b
+
+#endif /* __DISABLED__ */
+
+
+/*
+ * r13 points to the PACA, r9 contains the saved CR,
+ * r12 contain the saved SRR1, SRR0 is still ready for return
+ * r3 has the faulting address
+ * r9 - r13 are saved in paca->exslb.
+ * r3 is saved in paca->slb_r3
+ * We assume we aren't going to take any exceptions during this procedure.
+ */
+_GLOBAL(slb_miss_realmode)
+ mflr r10
+
+ stw r9,PACA_EXSLB+EX_CCR(r13) /* save CR in exc. frame */
+ std r10,PACA_EXSLB+EX_LR(r13) /* save LR */
+
+ bl .slb_allocate_realmode
+
+ /* All done -- return from exception. */
+
+ ld r10,PACA_EXSLB+EX_LR(r13)
+ ld r3,PACA_EXSLB+EX_R3(r13)
+ lwz r9,PACA_EXSLB+EX_CCR(r13) /* get saved CR */
+#ifdef CONFIG_PPC_ISERIES
+ ld r11,PACALPPACA+LPPACASRR0(r13) /* get SRR0 value */
+#endif /* CONFIG_PPC_ISERIES */
+
+ mtlr r10
+
+ andi. r10,r12,MSR_RI /* check for unrecoverable exception */
+ beq- unrecov_slb
+
+.machine push
+.machine "power4"
+ mtcrf 0x80,r9
+ mtcrf 0x01,r9 /* slb_allocate uses cr0 and cr7 */
+.machine pop
+
+#ifdef CONFIG_PPC_ISERIES
+ mtspr SPRN_SRR0,r11
+ mtspr SPRN_SRR1,r12
+#endif /* CONFIG_PPC_ISERIES */
+ ld r9,PACA_EXSLB+EX_R9(r13)
+ ld r10,PACA_EXSLB+EX_R10(r13)
+ ld r11,PACA_EXSLB+EX_R11(r13)
+ ld r12,PACA_EXSLB+EX_R12(r13)
+ ld r13,PACA_EXSLB+EX_R13(r13)
+ rfid
+ b . /* prevent speculative execution */
+
+unrecov_slb:
+ EXCEPTION_PROLOG_COMMON(0x4100, PACA_EXSLB)
+ DISABLE_INTS
+ bl .save_nvgprs
+1: addi r3,r1,STACK_FRAME_OVERHEAD
+ bl .unrecoverable_exception
+ b 1b
+
+ .align 7
+ .globl hardware_interrupt_common
+ .globl hardware_interrupt_entry
+hardware_interrupt_common:
+ EXCEPTION_PROLOG_COMMON(0x500, PACA_EXGEN)
+hardware_interrupt_entry:
+ DISABLE_INTS
+ addi r3,r1,STACK_FRAME_OVERHEAD
+ bl .do_IRQ
+ b .ret_from_except_lite
+
+ .align 7
+ .globl alignment_common
+alignment_common:
+ mfspr r10,SPRN_DAR
+ std r10,PACA_EXGEN+EX_DAR(r13)
+ mfspr r10,SPRN_DSISR
+ stw r10,PACA_EXGEN+EX_DSISR(r13)
+ EXCEPTION_PROLOG_COMMON(0x600, PACA_EXGEN)
+ ld r3,PACA_EXGEN+EX_DAR(r13)
+ lwz r4,PACA_EXGEN+EX_DSISR(r13)
+ std r3,_DAR(r1)
+ std r4,_DSISR(r1)
+ bl .save_nvgprs
+ addi r3,r1,STACK_FRAME_OVERHEAD
+ ENABLE_INTS
+ bl .alignment_exception
+ b .ret_from_except
+
+ .align 7
+ .globl program_check_common
+program_check_common:
+ EXCEPTION_PROLOG_COMMON(0x700, PACA_EXGEN)
+ bl .save_nvgprs
+ addi r3,r1,STACK_FRAME_OVERHEAD
+ ENABLE_INTS
+ bl .program_check_exception
+ b .ret_from_except
+
+ .align 7
+ .globl fp_unavailable_common
+fp_unavailable_common:
+ EXCEPTION_PROLOG_COMMON(0x800, PACA_EXGEN)
+ bne .load_up_fpu /* if from user, just load it up */
+ bl .save_nvgprs
+ addi r3,r1,STACK_FRAME_OVERHEAD
+ ENABLE_INTS
+ bl .kernel_fp_unavailable_exception
+ BUG_OPCODE
+
+ .align 7
+ .globl altivec_unavailable_common
+altivec_unavailable_common:
+ EXCEPTION_PROLOG_COMMON(0xf20, PACA_EXGEN)
+#ifdef CONFIG_ALTIVEC
+BEGIN_FTR_SECTION
+ bne .load_up_altivec /* if from user, just load it up */
+END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
+#endif
+ bl .save_nvgprs
+ addi r3,r1,STACK_FRAME_OVERHEAD
+ ENABLE_INTS
+ bl .altivec_unavailable_exception
+ b .ret_from_except
+
+#ifdef CONFIG_ALTIVEC
+/*
+ * load_up_altivec(unused, unused, tsk)
+ * Disable VMX for the task which had it previously,
+ * and save its vector registers in its thread_struct.
+ * Enables the VMX for use in the kernel on return.
+ * On SMP we know the VMX is free, since we give it up every
+ * switch (ie, no lazy save of the vector registers).
+ * On entry: r13 == 'current' && last_task_used_altivec != 'current'
+ */
+_STATIC(load_up_altivec)
+ mfmsr r5 /* grab the current MSR */
+ oris r5,r5,MSR_VEC@h
+ mtmsrd r5 /* enable use of VMX now */
+ isync
+
+/*
+ * For SMP, we don't do lazy VMX switching because it just gets too
+ * horrendously complex, especially when a task switches from one CPU
+ * to another. Instead we call giveup_altvec in switch_to.
+ * VRSAVE isn't dealt with here, that is done in the normal context
+ * switch code. Note that we could rely on vrsave value to eventually
+ * avoid saving all of the VREGs here...
+ */
+#ifndef CONFIG_SMP
+ ld r3,last_task_used_altivec@got(r2)
+ ld r4,0(r3)
+ cmpdi 0,r4,0
+ beq 1f
+ /* Save VMX state to last_task_used_altivec's THREAD struct */
+ addi r4,r4,THREAD
+ SAVE_32VRS(0,r5,r4)
+ mfvscr vr0
+ li r10,THREAD_VSCR
+ stvx vr0,r10,r4
+ /* Disable VMX for last_task_used_altivec */
+ ld r5,PT_REGS(r4)
+ ld r4,_MSR-STACK_FRAME_OVERHEAD(r5)
+ lis r6,MSR_VEC@h
+ andc r4,r4,r6
+ std r4,_MSR-STACK_FRAME_OVERHEAD(r5)
+1:
+#endif /* CONFIG_SMP */
+ /* Hack: if we get an altivec unavailable trap with VRSAVE
+ * set to all zeros, we assume this is a broken application
+ * that fails to set it properly, and thus we switch it to
+ * all 1's
+ */
+ mfspr r4,SPRN_VRSAVE
+ cmpdi 0,r4,0
+ bne+ 1f
+ li r4,-1
+ mtspr SPRN_VRSAVE,r4
+1:
+ /* enable use of VMX after return */
+ ld r4,PACACURRENT(r13)
+ addi r5,r4,THREAD /* Get THREAD */
+ oris r12,r12,MSR_VEC@h
+ std r12,_MSR(r1)
+ li r4,1
+ li r10,THREAD_VSCR
+ stw r4,THREAD_USED_VR(r5)
+ lvx vr0,r10,r5
+ mtvscr vr0
+ REST_32VRS(0,r4,r5)
+#ifndef CONFIG_SMP
+ /* Update last_task_used_math to 'current' */
+ subi r4,r5,THREAD /* Back to 'current' */
+ std r4,0(r3)
+#endif /* CONFIG_SMP */
+ /* restore registers and return */
+ b fast_exception_return
+#endif /* CONFIG_ALTIVEC */
+
+/*
+ * Hash table stuff
+ */
+ .align 7
+_GLOBAL(do_hash_page)
+ std r3,_DAR(r1)
+ std r4,_DSISR(r1)
+
+ andis. r0,r4,0xa450 /* weird error? */
+ bne- .handle_page_fault /* if not, try to insert a HPTE */
+BEGIN_FTR_SECTION
+ andis. r0,r4,0x0020 /* Is it a segment table fault? */
+ bne- .do_ste_alloc /* If so handle it */
+END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
+
+ /*
+ * We need to set the _PAGE_USER bit if MSR_PR is set or if we are
+ * accessing a userspace segment (even from the kernel). We assume
+ * kernel addresses always have the high bit set.
+ */
+ rlwinm r4,r4,32-25+9,31-9,31-9 /* DSISR_STORE -> _PAGE_RW */
+ rotldi r0,r3,15 /* Move high bit into MSR_PR posn */
+ orc r0,r12,r0 /* MSR_PR | ~high_bit */
+ rlwimi r4,r0,32-13,30,30 /* becomes _PAGE_USER access bit */
+ ori r4,r4,1 /* add _PAGE_PRESENT */
+ rlwimi r4,r5,22+2,31-2,31-2 /* Set _PAGE_EXEC if trap is 0x400 */
+
+ /*
+ * On iSeries, we soft-disable interrupts here, then
+ * hard-enable interrupts so that the hash_page code can spin on
+ * the hash_table_lock without problems on a shared processor.
+ */
+ DISABLE_INTS
+
+ /*
+ * r3 contains the faulting address
+ * r4 contains the required access permissions
+ * r5 contains the trap number
+ *
+ * at return r3 = 0 for success
+ */
+ bl .hash_page /* build HPTE if possible */
+ cmpdi r3,0 /* see if hash_page succeeded */
+
+#ifdef DO_SOFT_DISABLE
+ /*
+ * If we had interrupts soft-enabled at the point where the
+ * DSI/ISI occurred, and an interrupt came in during hash_page,
+ * handle it now.
+ * We jump to ret_from_except_lite rather than fast_exception_return
+ * because ret_from_except_lite will check for and handle pending
+ * interrupts if necessary.
+ */
+ beq .ret_from_except_lite
+ /* For a hash failure, we don't bother re-enabling interrupts */
+ ble- 12f
+
+ /*
+ * hash_page couldn't handle it, set soft interrupt enable back
+ * to what it was before the trap. Note that .local_irq_restore
+ * handles any interrupts pending at this point.
+ */
+ ld r3,SOFTE(r1)
+ bl .local_irq_restore
+ b 11f
+#else
+ beq fast_exception_return /* Return from exception on success */
+ ble- 12f /* Failure return from hash_page */
+
+ /* fall through */
+#endif
+
+/* Here we have a page fault that hash_page can't handle. */
+_GLOBAL(handle_page_fault)
+ ENABLE_INTS
+11: ld r4,_DAR(r1)
+ ld r5,_DSISR(r1)
+ addi r3,r1,STACK_FRAME_OVERHEAD
+ bl .do_page_fault
+ cmpdi r3,0
+ beq+ .ret_from_except_lite
+ bl .save_nvgprs
+ mr r5,r3
+ addi r3,r1,STACK_FRAME_OVERHEAD
+ lwz r4,_DAR(r1)
+ bl .bad_page_fault
+ b .ret_from_except
+
+/* We have a page fault that hash_page could handle but HV refused
+ * the PTE insertion
+ */
+12: bl .save_nvgprs
+ addi r3,r1,STACK_FRAME_OVERHEAD
+ lwz r4,_DAR(r1)
+ bl .low_hash_fault
+ b .ret_from_except
+
+ /* here we have a segment miss */
+_GLOBAL(do_ste_alloc)
+ bl .ste_allocate /* try to insert stab entry */
+ cmpdi r3,0
+ beq+ fast_exception_return
+ b .handle_page_fault
+
+/*
+ * r13 points to the PACA, r9 contains the saved CR,
+ * r11 and r12 contain the saved SRR0 and SRR1.
+ * r9 - r13 are saved in paca->exslb.
+ * We assume we aren't going to take any exceptions during this procedure.
+ * We assume (DAR >> 60) == 0xc.
+ */
+ .align 7
+_GLOBAL(do_stab_bolted)
+ stw r9,PACA_EXSLB+EX_CCR(r13) /* save CR in exc. frame */
+ std r11,PACA_EXSLB+EX_SRR0(r13) /* save SRR0 in exc. frame */
+
+ /* Hash to the primary group */
+ ld r10,PACASTABVIRT(r13)
+ mfspr r11,SPRN_DAR
+ srdi r11,r11,28
+ rldimi r10,r11,7,52 /* r10 = first ste of the group */
+
+ /* Calculate VSID */
+ /* This is a kernel address, so protovsid = ESID */
+ ASM_VSID_SCRAMBLE(r11, r9)
+ rldic r9,r11,12,16 /* r9 = vsid << 12 */
+
+ /* Search the primary group for a free entry */
+1: ld r11,0(r10) /* Test valid bit of the current ste */
+ andi. r11,r11,0x80
+ beq 2f
+ addi r10,r10,16
+ andi. r11,r10,0x70
+ bne 1b
+
+ /* Stick for only searching the primary group for now. */
+ /* At least for now, we use a very simple random castout scheme */
+ /* Use the TB as a random number ; OR in 1 to avoid entry 0 */
+ mftb r11
+ rldic r11,r11,4,57 /* r11 = (r11 << 4) & 0x70 */
+ ori r11,r11,0x10
+
+ /* r10 currently points to an ste one past the group of interest */
+ /* make it point to the randomly selected entry */
+ subi r10,r10,128
+ or r10,r10,r11 /* r10 is the entry to invalidate */
+
+ isync /* mark the entry invalid */
+ ld r11,0(r10)
+ rldicl r11,r11,56,1 /* clear the valid bit */
+ rotldi r11,r11,8
+ std r11,0(r10)
+ sync
+
+ clrrdi r11,r11,28 /* Get the esid part of the ste */
+ slbie r11
+
+2: std r9,8(r10) /* Store the vsid part of the ste */
+ eieio
+
+ mfspr r11,SPRN_DAR /* Get the new esid */
+ clrrdi r11,r11,28 /* Permits a full 32b of ESID */
+ ori r11,r11,0x90 /* Turn on valid and kp */
+ std r11,0(r10) /* Put new entry back into the stab */
+
+ sync
+
+ /* All done -- return from exception. */
+ lwz r9,PACA_EXSLB+EX_CCR(r13) /* get saved CR */
+ ld r11,PACA_EXSLB+EX_SRR0(r13) /* get saved SRR0 */
+
+ andi. r10,r12,MSR_RI
+ beq- unrecov_slb
+
+ mtcrf 0x80,r9 /* restore CR */
+
+ mfmsr r10
+ clrrdi r10,r10,2
+ mtmsrd r10,1
+
+ mtspr SPRN_SRR0,r11
+ mtspr SPRN_SRR1,r12
+ ld r9,PACA_EXSLB+EX_R9(r13)
+ ld r10,PACA_EXSLB+EX_R10(r13)
+ ld r11,PACA_EXSLB+EX_R11(r13)
+ ld r12,PACA_EXSLB+EX_R12(r13)
+ ld r13,PACA_EXSLB+EX_R13(r13)
+ rfid
+ b . /* prevent speculative execution */
+
+/*
+ * Space for CPU0's segment table.
+ *
+ * On iSeries, the hypervisor must fill in at least one entry before
+ * we get control (with relocate on). The address is give to the hv
+ * as a page number (see xLparMap in lpardata.c), so this must be at a
+ * fixed address (the linker can't compute (u64)&initial_stab >>
+ * PAGE_SHIFT).
+ */
+ . = STAB0_PHYS_ADDR /* 0x6000 */
+ .globl initial_stab
+initial_stab:
+ .space 4096
+
+/*
+ * Data area reserved for FWNMI option.
+ * This address (0x7000) is fixed by the RPA.
+ */
+ .= 0x7000
+ .globl fwnmi_data_area
+fwnmi_data_area:
+
+ /* iSeries does not use the FWNMI stuff, so it is safe to put
+ * this here, even if we later allow kernels that will boot on
+ * both pSeries and iSeries */
+#ifdef CONFIG_PPC_ISERIES
+ . = LPARMAP_PHYS
+#include "lparmap.s"
+/*
+ * This ".text" is here for old compilers that generate a trailing
+ * .note section when compiling .c files to .s
+ */
+ .text
+#endif /* CONFIG_PPC_ISERIES */
+
+ . = 0x8000
+
+/*
+ * On pSeries, secondary processors spin in the following code.
+ * At entry, r3 = this processor's number (physical cpu id)
+ */
+_GLOBAL(pSeries_secondary_smp_init)
+ mr r24,r3
+
+ /* turn on 64-bit mode */
+ bl .enable_64b_mode
+ isync
+
+ /* Copy some CPU settings from CPU 0 */
+ bl .__restore_cpu_setup
+
+ /* Set up a paca value for this processor. Since we have the
+ * physical cpu id in r24, we need to search the pacas to find
+ * which logical id maps to our physical one.
+ */
+ LOADADDR(r13, paca) /* Get base vaddr of paca array */
+ li r5,0 /* logical cpu id */
+1: lhz r6,PACAHWCPUID(r13) /* Load HW procid from paca */
+ cmpw r6,r24 /* Compare to our id */
+ beq 2f
+ addi r13,r13,PACA_SIZE /* Loop to next PACA on miss */
+ addi r5,r5,1
+ cmpwi r5,NR_CPUS
+ blt 1b
+
+ mr r3,r24 /* not found, copy phys to r3 */
+ b .kexec_wait /* next kernel might do better */
+
+2: mtspr SPRN_SPRG3,r13 /* Save vaddr of paca in SPRG3 */
+ /* From now on, r24 is expected to be logical cpuid */
+ mr r24,r5
+3: HMT_LOW
+ lbz r23,PACAPROCSTART(r13) /* Test if this processor should */
+ /* start. */
+ sync
+
+ /* Create a temp kernel stack for use before relocation is on. */
+ ld r1,PACAEMERGSP(r13)
+ subi r1,r1,STACK_FRAME_OVERHEAD
+
+ cmpwi 0,r23,0
+#ifdef CONFIG_SMP
+ bne .__secondary_start
+#endif
+ b 3b /* Loop until told to go */
+
+#ifdef CONFIG_PPC_ISERIES
+_STATIC(__start_initialization_iSeries)
+ /* Clear out the BSS */
+ LOADADDR(r11,__bss_stop)
+ LOADADDR(r8,__bss_start)
+ sub r11,r11,r8 /* bss size */
+ addi r11,r11,7 /* round up to an even double word */
+ rldicl. r11,r11,61,3 /* shift right by 3 */
+ beq 4f
+ addi r8,r8,-8
+ li r0,0
+ mtctr r11 /* zero this many doublewords */
+3: stdu r0,8(r8)
+ bdnz 3b
+4:
+ LOADADDR(r1,init_thread_union)
+ addi r1,r1,THREAD_SIZE
+ li r0,0
+ stdu r0,-STACK_FRAME_OVERHEAD(r1)
+
+ LOADADDR(r3,cpu_specs)
+ LOADADDR(r4,cur_cpu_spec)
+ li r5,0
+ bl .identify_cpu
+
+ LOADADDR(r2,__toc_start)
+ addi r2,r2,0x4000
+ addi r2,r2,0x4000
+
+ bl .iSeries_early_setup
+ bl .early_setup
+
+ /* relocation is on at this point */
+
+ b .start_here_common
+#endif /* CONFIG_PPC_ISERIES */
+
+#ifdef CONFIG_PPC_MULTIPLATFORM
+
+_STATIC(__mmu_off)
+ mfmsr r3
+ andi. r0,r3,MSR_IR|MSR_DR
+ beqlr
+ andc r3,r3,r0
+ mtspr SPRN_SRR0,r4
+ mtspr SPRN_SRR1,r3
+ sync
+ rfid
+ b . /* prevent speculative execution */
+
+
+/*
+ * Here is our main kernel entry point. We support currently 2 kind of entries
+ * depending on the value of r5.
+ *
+ * r5 != NULL -> OF entry, we go to prom_init, "legacy" parameter content
+ * in r3...r7
+ *
+ * r5 == NULL -> kexec style entry. r3 is a physical pointer to the
+ * DT block, r4 is a physical pointer to the kernel itself
+ *
+ */
+_GLOBAL(__start_initialization_multiplatform)
+ /*
+ * Are we booted from a PROM Of-type client-interface ?
+ */
+ cmpldi cr0,r5,0
+ bne .__boot_from_prom /* yes -> prom */
+
+ /* Save parameters */
+ mr r31,r3
+ mr r30,r4
+
+ /* Make sure we are running in 64 bits mode */
+ bl .enable_64b_mode
+
+ /* Setup some critical 970 SPRs before switching MMU off */
+ bl .__970_cpu_preinit
+
+ /* cpu # */
+ li r24,0
+
+ /* Switch off MMU if not already */
+ LOADADDR(r4, .__after_prom_start - KERNELBASE)
+ add r4,r4,r30
+ bl .__mmu_off
+ b .__after_prom_start
+
+_STATIC(__boot_from_prom)
+ /* Save parameters */
+ mr r31,r3
+ mr r30,r4
+ mr r29,r5
+ mr r28,r6
+ mr r27,r7
+
+ /* Make sure we are running in 64 bits mode */
+ bl .enable_64b_mode
+
+ /* put a relocation offset into r3 */
+ bl .reloc_offset
+
+ LOADADDR(r2,__toc_start)
+ addi r2,r2,0x4000
+ addi r2,r2,0x4000
+
+ /* Relocate the TOC from a virt addr to a real addr */
+ add r2,r2,r3
+
+ /* Restore parameters */
+ mr r3,r31
+ mr r4,r30
+ mr r5,r29
+ mr r6,r28
+ mr r7,r27
+
+ /* Do all of the interaction with OF client interface */
+ bl .prom_init
+ /* We never return */
+ trap
+
+/*
+ * At this point, r3 contains the physical address we are running at,
+ * returned by prom_init()
+ */
+_STATIC(__after_prom_start)
+
+/*
+ * We need to run with __start at physical address 0.
+ * This will leave some code in the first 256B of
+ * real memory, which are reserved for software use.
+ * The remainder of the first page is loaded with the fixed
+ * interrupt vectors. The next two pages are filled with
+ * unknown exception placeholders.
+ *
+ * Note: This process overwrites the OF exception vectors.
+ * r26 == relocation offset
+ * r27 == KERNELBASE
+ */
+ bl .reloc_offset
+ mr r26,r3
+ SET_REG_TO_CONST(r27,KERNELBASE)
+
+ li r3,0 /* target addr */
+
+ // XXX FIXME: Use phys returned by OF (r30)
+ add r4,r27,r26 /* source addr */
+ /* current address of _start */
+ /* i.e. where we are running */
+ /* the source addr */
+
+ LOADADDR(r5,copy_to_here) /* # bytes of memory to copy */
+ sub r5,r5,r27
+
+ li r6,0x100 /* Start offset, the first 0x100 */
+ /* bytes were copied earlier. */
+
+ bl .copy_and_flush /* copy the first n bytes */
+ /* this includes the code being */
+ /* executed here. */
+
+ LOADADDR(r0, 4f) /* Jump to the copy of this code */
+ mtctr r0 /* that we just made/relocated */
+ bctr
+
+4: LOADADDR(r5,klimit)
+ add r5,r5,r26
+ ld r5,0(r5) /* get the value of klimit */
+ sub r5,r5,r27
+ bl .copy_and_flush /* copy the rest */
+ b .start_here_multiplatform
+
+#endif /* CONFIG_PPC_MULTIPLATFORM */
+
+/*
+ * Copy routine used to copy the kernel to start at physical address 0
+ * and flush and invalidate the caches as needed.
+ * r3 = dest addr, r4 = source addr, r5 = copy limit, r6 = start offset
+ * on exit, r3, r4, r5 are unchanged, r6 is updated to be >= r5.
+ *
+ * Note: this routine *only* clobbers r0, r6 and lr
+ */
+_GLOBAL(copy_and_flush)
+ addi r5,r5,-8
+ addi r6,r6,-8
+4: li r0,16 /* Use the least common */
+ /* denominator cache line */
+ /* size. This results in */
+ /* extra cache line flushes */
+ /* but operation is correct. */
+ /* Can't get cache line size */
+ /* from NACA as it is being */
+ /* moved too. */
+
+ mtctr r0 /* put # words/line in ctr */
+3: addi r6,r6,8 /* copy a cache line */
+ ldx r0,r6,r4
+ stdx r0,r6,r3
+ bdnz 3b
+ dcbst r6,r3 /* write it to memory */
+ sync
+ icbi r6,r3 /* flush the icache line */
+ cmpld 0,r6,r5
+ blt 4b
+ sync
+ addi r5,r5,8
+ addi r6,r6,8
+ blr
+
+.align 8
+copy_to_here:
+
+#ifdef CONFIG_SMP
+#ifdef CONFIG_PPC_PMAC
+/*
+ * On PowerMac, secondary processors starts from the reset vector, which
+ * is temporarily turned into a call to one of the functions below.
+ */
+ .section ".text";
+ .align 2 ;
+
+ .globl __secondary_start_pmac_0
+__secondary_start_pmac_0:
+ /* NB the entries for cpus 0, 1, 2 must each occupy 8 bytes. */
+ li r24,0
+ b 1f
+ li r24,1
+ b 1f
+ li r24,2
+ b 1f
+ li r24,3
+1:
+
+_GLOBAL(pmac_secondary_start)
+ /* turn on 64-bit mode */
+ bl .enable_64b_mode
+ isync
+
+ /* Copy some CPU settings from CPU 0 */
+ bl .__restore_cpu_setup
+
+ /* pSeries do that early though I don't think we really need it */
+ mfmsr r3
+ ori r3,r3,MSR_RI
+ mtmsrd r3 /* RI on */
+
+ /* Set up a paca value for this processor. */
+ LOADADDR(r4, paca) /* Get base vaddr of paca array */
+ mulli r13,r24,PACA_SIZE /* Calculate vaddr of right paca */
+ add r13,r13,r4 /* for this processor. */
+ mtspr SPRN_SPRG3,r13 /* Save vaddr of paca in SPRG3 */
+
+ /* Create a temp kernel stack for use before relocation is on. */
+ ld r1,PACAEMERGSP(r13)
+ subi r1,r1,STACK_FRAME_OVERHEAD
+
+ b .__secondary_start
+
+#endif /* CONFIG_PPC_PMAC */
+
+/*
+ * This function is called after the master CPU has released the
+ * secondary processors. The execution environment is relocation off.
+ * The paca for this processor has the following fields initialized at
+ * this point:
+ * 1. Processor number
+ * 2. Segment table pointer (virtual address)
+ * On entry the following are set:
+ * r1 = stack pointer. vaddr for iSeries, raddr (temp stack) for pSeries
+ * r24 = cpu# (in Linux terms)
+ * r13 = paca virtual address
+ * SPRG3 = paca virtual address
+ */
+_GLOBAL(__secondary_start)
+ /* Set thread priority to MEDIUM */
+ HMT_MEDIUM
+
+ /* Load TOC */
+ ld r2,PACATOC(r13)
+
+ /* Do early setup for that CPU (stab, slb, hash table pointer) */
+ bl .early_setup_secondary
+
+ /* Initialize the kernel stack. Just a repeat for iSeries. */
+ LOADADDR(r3,current_set)
+ sldi r28,r24,3 /* get current_set[cpu#] */
+ ldx r1,r3,r28
+ addi r1,r1,THREAD_SIZE-STACK_FRAME_OVERHEAD
+ std r1,PACAKSAVE(r13)
+
+ /* Clear backchain so we get nice backtraces */
+ li r7,0
+ mtlr r7
+
+ /* enable MMU and jump to start_secondary */
+ LOADADDR(r3,.start_secondary_prolog)
+ SET_REG_TO_CONST(r4, MSR_KERNEL)
+#ifdef DO_SOFT_DISABLE
+ ori r4,r4,MSR_EE
+#endif
+ mtspr SPRN_SRR0,r3
+ mtspr SPRN_SRR1,r4
+ rfid
+ b . /* prevent speculative execution */
+
+/*
+ * Running with relocation on at this point. All we want to do is
+ * zero the stack back-chain pointer before going into C code.
+ */
+_GLOBAL(start_secondary_prolog)
+ li r3,0
+ std r3,0(r1) /* Zero the stack frame pointer */
+ bl .start_secondary
+ b .
+#endif
+
+/*
+ * This subroutine clobbers r11 and r12
+ */
+_GLOBAL(enable_64b_mode)
+ mfmsr r11 /* grab the current MSR */
+ li r12,1
+ rldicr r12,r12,MSR_SF_LG,(63-MSR_SF_LG)
+ or r11,r11,r12
+ li r12,1
+ rldicr r12,r12,MSR_ISF_LG,(63-MSR_ISF_LG)
+ or r11,r11,r12
+ mtmsrd r11
+ isync
+ blr
+
+#ifdef CONFIG_PPC_MULTIPLATFORM
+/*
+ * This is where the main kernel code starts.
+ */
+_STATIC(start_here_multiplatform)
+ /* get a new offset, now that the kernel has moved. */
+ bl .reloc_offset
+ mr r26,r3
+
+ /* Clear out the BSS. It may have been done in prom_init,
+ * already but that's irrelevant since prom_init will soon
+ * be detached from the kernel completely. Besides, we need
+ * to clear it now for kexec-style entry.
+ */
+ LOADADDR(r11,__bss_stop)
+ LOADADDR(r8,__bss_start)
+ sub r11,r11,r8 /* bss size */
+ addi r11,r11,7 /* round up to an even double word */
+ rldicl. r11,r11,61,3 /* shift right by 3 */
+ beq 4f
+ addi r8,r8,-8
+ li r0,0
+ mtctr r11 /* zero this many doublewords */
+3: stdu r0,8(r8)
+ bdnz 3b
+4:
+
+ mfmsr r6
+ ori r6,r6,MSR_RI
+ mtmsrd r6 /* RI on */
+
+#ifdef CONFIG_HMT
+ /* Start up the second thread on cpu 0 */
+ mfspr r3,SPRN_PVR
+ srwi r3,r3,16
+ cmpwi r3,0x34 /* Pulsar */
+ beq 90f
+ cmpwi r3,0x36 /* Icestar */
+ beq 90f
+ cmpwi r3,0x37 /* SStar */
+ beq 90f
+ b 91f /* HMT not supported */
+90: li r3,0
+ bl .hmt_start_secondary
+91:
+#endif
+
+ /* The following gets the stack and TOC set up with the regs */
+ /* pointing to the real addr of the kernel stack. This is */
+ /* all done to support the C function call below which sets */
+ /* up the htab. This is done because we have relocated the */
+ /* kernel but are still running in real mode. */
+
+ LOADADDR(r3,init_thread_union)
+ add r3,r3,r26
+
+ /* set up a stack pointer (physical address) */
+ addi r1,r3,THREAD_SIZE
+ li r0,0
+ stdu r0,-STACK_FRAME_OVERHEAD(r1)
+
+ /* set up the TOC (physical address) */
+ LOADADDR(r2,__toc_start)
+ addi r2,r2,0x4000
+ addi r2,r2,0x4000
+ add r2,r2,r26
+
+ LOADADDR(r3,cpu_specs)
+ add r3,r3,r26
+ LOADADDR(r4,cur_cpu_spec)
+ add r4,r4,r26
+ mr r5,r26
+ bl .identify_cpu
+
+ /* Save some low level config HIDs of CPU0 to be copied to
+ * other CPUs later on, or used for suspend/resume
+ */
+ bl .__save_cpu_setup
+ sync
+
+ /* Setup a valid physical PACA pointer in SPRG3 for early_setup
+ * note that boot_cpuid can always be 0 nowadays since there is
+ * nowhere it can be initialized differently before we reach this
+ * code
+ */
+ LOADADDR(r27, boot_cpuid)
+ add r27,r27,r26
+ lwz r27,0(r27)
+
+ LOADADDR(r24, paca) /* Get base vaddr of paca array */
+ mulli r13,r27,PACA_SIZE /* Calculate vaddr of right paca */
+ add r13,r13,r24 /* for this processor. */
+ add r13,r13,r26 /* convert to physical addr */
+ mtspr SPRN_SPRG3,r13 /* PPPBBB: Temp... -Peter */
+
+ /* Do very early kernel initializations, including initial hash table,
+ * stab and slb setup before we turn on relocation. */
+
+ /* Restore parameters passed from prom_init/kexec */
+ mr r3,r31
+ bl .early_setup
+
+ LOADADDR(r3,.start_here_common)
+ SET_REG_TO_CONST(r4, MSR_KERNEL)
+ mtspr SPRN_SRR0,r3
+ mtspr SPRN_SRR1,r4
+ rfid
+ b . /* prevent speculative execution */
+#endif /* CONFIG_PPC_MULTIPLATFORM */
+
+ /* This is where all platforms converge execution */
+_STATIC(start_here_common)
+ /* relocation is on at this point */
+
+ /* The following code sets up the SP and TOC now that we are */
+ /* running with translation enabled. */
+
+ LOADADDR(r3,init_thread_union)
+
+ /* set up the stack */
+ addi r1,r3,THREAD_SIZE
+ li r0,0
+ stdu r0,-STACK_FRAME_OVERHEAD(r1)
+
+ /* Apply the CPUs-specific fixups (nop out sections not relevant
+ * to this CPU
+ */
+ li r3,0
+ bl .do_cpu_ftr_fixups
+
+ LOADADDR(r26, boot_cpuid)
+ lwz r26,0(r26)
+
+ LOADADDR(r24, paca) /* Get base vaddr of paca array */
+ mulli r13,r26,PACA_SIZE /* Calculate vaddr of right paca */
+ add r13,r13,r24 /* for this processor. */
+ mtspr SPRN_SPRG3,r13
+
+ /* ptr to current */
+ LOADADDR(r4,init_task)
+ std r4,PACACURRENT(r13)
+
+ /* Load the TOC */
+ ld r2,PACATOC(r13)
+ std r1,PACAKSAVE(r13)
+
+ bl .setup_system
+
+ /* Load up the kernel context */
+5:
+#ifdef DO_SOFT_DISABLE
+ li r5,0
+ stb r5,PACAPROCENABLED(r13) /* Soft Disabled */
+ mfmsr r5
+ ori r5,r5,MSR_EE /* Hard Enabled */
+ mtmsrd r5
+#endif
+
+ bl .start_kernel
+
+_GLOBAL(hmt_init)
+#ifdef CONFIG_HMT
+ LOADADDR(r5, hmt_thread_data)
+ mfspr r7,SPRN_PVR
+ srwi r7,r7,16
+ cmpwi r7,0x34 /* Pulsar */
+ beq 90f
+ cmpwi r7,0x36 /* Icestar */
+ beq 91f
+ cmpwi r7,0x37 /* SStar */
+ beq 91f
+ b 101f
+90: mfspr r6,SPRN_PIR
+ andi. r6,r6,0x1f
+ b 92f
+91: mfspr r6,SPRN_PIR
+ andi. r6,r6,0x3ff
+92: sldi r4,r24,3
+ stwx r6,r5,r4
+ bl .hmt_start_secondary
+ b 101f
+
+__hmt_secondary_hold:
+ LOADADDR(r5, hmt_thread_data)
+ clrldi r5,r5,4
+ li r7,0
+ mfspr r6,SPRN_PIR
+ mfspr r8,SPRN_PVR
+ srwi r8,r8,16
+ cmpwi r8,0x34
+ bne 93f
+ andi. r6,r6,0x1f
+ b 103f
+93: andi. r6,r6,0x3f
+
+103: lwzx r8,r5,r7
+ cmpw r8,r6
+ beq 104f
+ addi r7,r7,8
+ b 103b
+
+104: addi r7,r7,4
+ lwzx r9,r5,r7
+ mr r24,r9
+101:
+#endif
+ mr r3,r24
+ b .pSeries_secondary_smp_init
+
+#ifdef CONFIG_HMT
+_GLOBAL(hmt_start_secondary)
+ LOADADDR(r4,__hmt_secondary_hold)
+ clrldi r4,r4,4
+ mtspr SPRN_NIADORM, r4
+ mfspr r4, SPRN_MSRDORM
+ li r5, -65
+ and r4, r4, r5
+ mtspr SPRN_MSRDORM, r4
+ lis r4,0xffef
+ ori r4,r4,0x7403
+ mtspr SPRN_TSC, r4
+ li r4,0x1f4
+ mtspr SPRN_TST, r4
+ mfspr r4, SPRN_HID0
+ ori r4, r4, 0x1
+ mtspr SPRN_HID0, r4
+ mfspr r4, SPRN_CTRLF
+ oris r4, r4, 0x40
+ mtspr SPRN_CTRLT, r4
+ blr
+#endif
+
+/*
+ * We put a few things here that have to be page-aligned.
+ * This stuff goes at the beginning of the bss, which is page-aligned.
+ */
+ .section ".bss"
+
+ .align PAGE_SHIFT
+
+ .globl empty_zero_page
+empty_zero_page:
+ .space PAGE_SIZE
+
+ .globl swapper_pg_dir
+swapper_pg_dir:
+ .space PAGE_SIZE
+
+/*
+ * This space gets a copy of optional info passed to us by the bootstrap
+ * Used to pass parameters into the kernel like root=/dev/sda1, etc.
+ */
+ .globl cmd_line
+cmd_line:
+ .space COMMAND_LINE_SIZE
diff --git a/arch/powerpc/kernel/head_8xx.S b/arch/powerpc/kernel/head_8xx.S
new file mode 100644
index 000000000000..bc6d1ac55235
--- /dev/null
+++ b/arch/powerpc/kernel/head_8xx.S
@@ -0,0 +1,860 @@
+/*
+ * arch/ppc/kernel/except_8xx.S
+ *
+ * PowerPC version
+ * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
+ * Rewritten by Cort Dougan (cort@cs.nmt.edu) for PReP
+ * Copyright (C) 1996 Cort Dougan <cort@cs.nmt.edu>
+ * Low-level exception handlers and MMU support
+ * rewritten by Paul Mackerras.
+ * Copyright (C) 1996 Paul Mackerras.
+ * MPC8xx modifications by Dan Malek
+ * Copyright (C) 1997 Dan Malek (dmalek@jlc.net).
+ *
+ * This file contains low-level support and setup for PowerPC 8xx
+ * embedded processors, including trap and interrupt dispatch.
+ *
+ * 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/config.h>
+#include <asm/processor.h>
+#include <asm/page.h>
+#include <asm/mmu.h>
+#include <asm/cache.h>
+#include <asm/pgtable.h>
+#include <asm/cputable.h>
+#include <asm/thread_info.h>
+#include <asm/ppc_asm.h>
+#include <asm/asm-offsets.h>
+
+/* Macro to make the code more readable. */
+#ifdef CONFIG_8xx_CPU6
+#define DO_8xx_CPU6(val, reg) \
+ li reg, val; \
+ stw reg, 12(r0); \
+ lwz reg, 12(r0);
+#else
+#define DO_8xx_CPU6(val, reg)
+#endif
+ .text
+ .globl _stext
+_stext:
+ .text
+ .globl _start
+_start:
+
+/* MPC8xx
+ * This port was done on an MBX board with an 860. Right now I only
+ * support an ELF compressed (zImage) boot from EPPC-Bug because the
+ * code there loads up some registers before calling us:
+ * r3: ptr to board info data
+ * r4: initrd_start or if no initrd then 0
+ * r5: initrd_end - unused if r4 is 0
+ * r6: Start of command line string
+ * r7: End of command line string
+ *
+ * I decided to use conditional compilation instead of checking PVR and
+ * adding more processor specific branches around code I don't need.
+ * Since this is an embedded processor, I also appreciate any memory
+ * savings I can get.
+ *
+ * The MPC8xx does not have any BATs, but it supports large page sizes.
+ * We first initialize the MMU to support 8M byte pages, then load one
+ * entry into each of the instruction and data TLBs to map the first
+ * 8M 1:1. I also mapped an additional I/O space 1:1 so we can get to
+ * the "internal" processor registers before MMU_init is called.
+ *
+ * The TLB code currently contains a major hack. Since I use the condition
+ * code register, I have to save and restore it. I am out of registers, so
+ * I just store it in memory location 0 (the TLB handlers are not reentrant).
+ * To avoid making any decisions, I need to use the "segment" valid bit
+ * in the first level table, but that would require many changes to the
+ * Linux page directory/table functions that I don't want to do right now.
+ *
+ * I used to use SPRG2 for a temporary register in the TLB handler, but it
+ * has since been put to other uses. I now use a hack to save a register
+ * and the CCR at memory location 0.....Someday I'll fix this.....
+ * -- Dan
+ */
+ .globl __start
+__start:
+ mr r31,r3 /* save parameters */
+ mr r30,r4
+ mr r29,r5
+ mr r28,r6
+ mr r27,r7
+
+ /* We have to turn on the MMU right away so we get cache modes
+ * set correctly.
+ */
+ bl initial_mmu
+
+/* We now have the lower 8 Meg mapped into TLB entries, and the caches
+ * ready to work.
+ */
+
+turn_on_mmu:
+ mfmsr r0
+ ori r0,r0,MSR_DR|MSR_IR
+ mtspr SPRN_SRR1,r0
+ lis r0,start_here@h
+ ori r0,r0,start_here@l
+ mtspr SPRN_SRR0,r0
+ SYNC
+ rfi /* enables MMU */
+
+/*
+ * Exception entry code. This code runs with address translation
+ * turned off, i.e. using physical addresses.
+ * We assume sprg3 has the physical address of the current
+ * task's thread_struct.
+ */
+#define EXCEPTION_PROLOG \
+ mtspr SPRN_SPRG0,r10; \
+ mtspr SPRN_SPRG1,r11; \
+ mfcr r10; \
+ EXCEPTION_PROLOG_1; \
+ EXCEPTION_PROLOG_2
+
+#define EXCEPTION_PROLOG_1 \
+ mfspr r11,SPRN_SRR1; /* check whether user or kernel */ \
+ andi. r11,r11,MSR_PR; \
+ tophys(r11,r1); /* use tophys(r1) if kernel */ \
+ beq 1f; \
+ mfspr r11,SPRN_SPRG3; \
+ lwz r11,THREAD_INFO-THREAD(r11); \
+ addi r11,r11,THREAD_SIZE; \
+ tophys(r11,r11); \
+1: subi r11,r11,INT_FRAME_SIZE /* alloc exc. frame */
+
+
+#define EXCEPTION_PROLOG_2 \
+ CLR_TOP32(r11); \
+ stw r10,_CCR(r11); /* save registers */ \
+ stw r12,GPR12(r11); \
+ stw r9,GPR9(r11); \
+ mfspr r10,SPRN_SPRG0; \
+ stw r10,GPR10(r11); \
+ mfspr r12,SPRN_SPRG1; \
+ stw r12,GPR11(r11); \
+ mflr r10; \
+ stw r10,_LINK(r11); \
+ mfspr r12,SPRN_SRR0; \
+ mfspr r9,SPRN_SRR1; \
+ stw r1,GPR1(r11); \
+ stw r1,0(r11); \
+ tovirt(r1,r11); /* set new kernel sp */ \
+ li r10,MSR_KERNEL & ~(MSR_IR|MSR_DR); /* can take exceptions */ \
+ MTMSRD(r10); /* (except for mach check in rtas) */ \
+ stw r0,GPR0(r11); \
+ SAVE_4GPRS(3, r11); \
+ SAVE_2GPRS(7, r11)
+
+/*
+ * Note: code which follows this uses cr0.eq (set if from kernel),
+ * r11, r12 (SRR0), and r9 (SRR1).
+ *
+ * Note2: once we have set r1 we are in a position to take exceptions
+ * again, and we could thus set MSR:RI at that point.
+ */
+
+/*
+ * Exception vectors.
+ */
+#define EXCEPTION(n, label, hdlr, xfer) \
+ . = n; \
+label: \
+ EXCEPTION_PROLOG; \
+ addi r3,r1,STACK_FRAME_OVERHEAD; \
+ xfer(n, hdlr)
+
+#define EXC_XFER_TEMPLATE(n, hdlr, trap, copyee, tfer, ret) \
+ li r10,trap; \
+ stw r10,_TRAP(r11); \
+ li r10,MSR_KERNEL; \
+ copyee(r10, r9); \
+ bl tfer; \
+i##n: \
+ .long hdlr; \
+ .long ret
+
+#define COPY_EE(d, s) rlwimi d,s,0,16,16
+#define NOCOPY(d, s)
+
+#define EXC_XFER_STD(n, hdlr) \
+ EXC_XFER_TEMPLATE(n, hdlr, n, NOCOPY, transfer_to_handler_full, \
+ ret_from_except_full)
+
+#define EXC_XFER_LITE(n, hdlr) \
+ EXC_XFER_TEMPLATE(n, hdlr, n+1, NOCOPY, transfer_to_handler, \
+ ret_from_except)
+
+#define EXC_XFER_EE(n, hdlr) \
+ EXC_XFER_TEMPLATE(n, hdlr, n, COPY_EE, transfer_to_handler_full, \
+ ret_from_except_full)
+
+#define EXC_XFER_EE_LITE(n, hdlr) \
+ EXC_XFER_TEMPLATE(n, hdlr, n+1, COPY_EE, transfer_to_handler, \
+ ret_from_except)
+
+/* System reset */
+ EXCEPTION(0x100, Reset, unknown_exception, EXC_XFER_STD)
+
+/* Machine check */
+ . = 0x200
+MachineCheck:
+ EXCEPTION_PROLOG
+ mfspr r4,SPRN_DAR
+ stw r4,_DAR(r11)
+ mfspr r5,SPRN_DSISR
+ stw r5,_DSISR(r11)
+ addi r3,r1,STACK_FRAME_OVERHEAD
+ EXC_XFER_STD(0x200, machine_check_exception)
+
+/* Data access exception.
+ * This is "never generated" by the MPC8xx. We jump to it for other
+ * translation errors.
+ */
+ . = 0x300
+DataAccess:
+ EXCEPTION_PROLOG
+ mfspr r10,SPRN_DSISR
+ stw r10,_DSISR(r11)
+ mr r5,r10
+ mfspr r4,SPRN_DAR
+ EXC_XFER_EE_LITE(0x300, handle_page_fault)
+
+/* Instruction access exception.
+ * This is "never generated" by the MPC8xx. We jump to it for other
+ * translation errors.
+ */
+ . = 0x400
+InstructionAccess:
+ EXCEPTION_PROLOG
+ mr r4,r12
+ mr r5,r9
+ EXC_XFER_EE_LITE(0x400, handle_page_fault)
+
+/* External interrupt */
+ EXCEPTION(0x500, HardwareInterrupt, do_IRQ, EXC_XFER_LITE)
+
+/* Alignment exception */
+ . = 0x600
+Alignment:
+ EXCEPTION_PROLOG
+ mfspr r4,SPRN_DAR
+ stw r4,_DAR(r11)
+ mfspr r5,SPRN_DSISR
+ stw r5,_DSISR(r11)
+ addi r3,r1,STACK_FRAME_OVERHEAD
+ EXC_XFER_EE(0x600, alignment_exception)
+
+/* Program check exception */
+ EXCEPTION(0x700, ProgramCheck, program_check_exception, EXC_XFER_STD)
+
+/* No FPU on MPC8xx. This exception is not supposed to happen.
+*/
+ EXCEPTION(0x800, FPUnavailable, unknown_exception, EXC_XFER_STD)
+
+/* Decrementer */
+ EXCEPTION(0x900, Decrementer, timer_interrupt, EXC_XFER_LITE)
+
+ EXCEPTION(0xa00, Trap_0a, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0xb00, Trap_0b, unknown_exception, EXC_XFER_EE)
+
+/* System call */
+ . = 0xc00
+SystemCall:
+ EXCEPTION_PROLOG
+ EXC_XFER_EE_LITE(0xc00, DoSyscall)
+
+/* Single step - not used on 601 */
+ EXCEPTION(0xd00, SingleStep, single_step_exception, EXC_XFER_STD)
+ EXCEPTION(0xe00, Trap_0e, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0xf00, Trap_0f, unknown_exception, EXC_XFER_EE)
+
+/* On the MPC8xx, this is a software emulation interrupt. It occurs
+ * for all unimplemented and illegal instructions.
+ */
+ EXCEPTION(0x1000, SoftEmu, SoftwareEmulation, EXC_XFER_STD)
+
+ . = 0x1100
+/*
+ * For the MPC8xx, this is a software tablewalk to load the instruction
+ * TLB. It is modelled after the example in the Motorola manual. The task
+ * switch loads the M_TWB register with the pointer to the first level table.
+ * If we discover there is no second level table (value is zero) or if there
+ * is an invalid pte, we load that into the TLB, which causes another fault
+ * into the TLB Error interrupt where we can handle such problems.
+ * We have to use the MD_xxx registers for the tablewalk because the
+ * equivalent MI_xxx registers only perform the attribute functions.
+ */
+InstructionTLBMiss:
+#ifdef CONFIG_8xx_CPU6
+ stw r3, 8(r0)
+#endif
+ DO_8xx_CPU6(0x3f80, r3)
+ mtspr SPRN_M_TW, r10 /* Save a couple of working registers */
+ mfcr r10
+ stw r10, 0(r0)
+ stw r11, 4(r0)
+ mfspr r10, SPRN_SRR0 /* Get effective address of fault */
+ DO_8xx_CPU6(0x3780, r3)
+ mtspr SPRN_MD_EPN, r10 /* Have to use MD_EPN for walk, MI_EPN can't */
+ mfspr r10, SPRN_M_TWB /* Get level 1 table entry address */
+
+ /* If we are faulting a kernel address, we have to use the
+ * kernel page tables.
+ */
+ andi. r11, r10, 0x0800 /* Address >= 0x80000000 */
+ beq 3f
+ lis r11, swapper_pg_dir@h
+ ori r11, r11, swapper_pg_dir@l
+ rlwimi r10, r11, 0, 2, 19
+3:
+ lwz r11, 0(r10) /* Get the level 1 entry */
+ rlwinm. r10, r11,0,0,19 /* Extract page descriptor page address */
+ beq 2f /* If zero, don't try to find a pte */
+
+ /* We have a pte table, so load the MI_TWC with the attributes
+ * for this "segment."
+ */
+ ori r11,r11,1 /* Set valid bit */
+ DO_8xx_CPU6(0x2b80, r3)
+ mtspr SPRN_MI_TWC, r11 /* Set segment attributes */
+ DO_8xx_CPU6(0x3b80, r3)
+ mtspr SPRN_MD_TWC, r11 /* Load pte table base address */
+ mfspr r11, SPRN_MD_TWC /* ....and get the pte address */
+ lwz r10, 0(r11) /* Get the pte */
+
+ ori r10, r10, _PAGE_ACCESSED
+ stw r10, 0(r11)
+
+ /* The Linux PTE won't go exactly into the MMU TLB.
+ * Software indicator bits 21, 22 and 28 must be clear.
+ * Software indicator bits 24, 25, 26, and 27 must be
+ * set. All other Linux PTE bits control the behavior
+ * of the MMU.
+ */
+2: li r11, 0x00f0
+ rlwimi r10, r11, 0, 24, 28 /* Set 24-27, clear 28 */
+ DO_8xx_CPU6(0x2d80, r3)
+ mtspr SPRN_MI_RPN, r10 /* Update TLB entry */
+
+ mfspr r10, SPRN_M_TW /* Restore registers */
+ lwz r11, 0(r0)
+ mtcr r11
+ lwz r11, 4(r0)
+#ifdef CONFIG_8xx_CPU6
+ lwz r3, 8(r0)
+#endif
+ rfi
+
+ . = 0x1200
+DataStoreTLBMiss:
+#ifdef CONFIG_8xx_CPU6
+ stw r3, 8(r0)
+#endif
+ DO_8xx_CPU6(0x3f80, r3)
+ mtspr SPRN_M_TW, r10 /* Save a couple of working registers */
+ mfcr r10
+ stw r10, 0(r0)
+ stw r11, 4(r0)
+ mfspr r10, SPRN_M_TWB /* Get level 1 table entry address */
+
+ /* If we are faulting a kernel address, we have to use the
+ * kernel page tables.
+ */
+ andi. r11, r10, 0x0800
+ beq 3f
+ lis r11, swapper_pg_dir@h
+ ori r11, r11, swapper_pg_dir@l
+ rlwimi r10, r11, 0, 2, 19
+3:
+ lwz r11, 0(r10) /* Get the level 1 entry */
+ rlwinm. r10, r11,0,0,19 /* Extract page descriptor page address */
+ beq 2f /* If zero, don't try to find a pte */
+
+ /* We have a pte table, so load fetch the pte from the table.
+ */
+ ori r11, r11, 1 /* Set valid bit in physical L2 page */
+ DO_8xx_CPU6(0x3b80, r3)
+ mtspr SPRN_MD_TWC, r11 /* Load pte table base address */
+ mfspr r10, SPRN_MD_TWC /* ....and get the pte address */
+ lwz r10, 0(r10) /* Get the pte */
+
+ /* Insert the Guarded flag into the TWC from the Linux PTE.
+ * It is bit 27 of both the Linux PTE and the TWC (at least
+ * I got that right :-). It will be better when we can put
+ * this into the Linux pgd/pmd and load it in the operation
+ * above.
+ */
+ rlwimi r11, r10, 0, 27, 27
+ DO_8xx_CPU6(0x3b80, r3)
+ mtspr SPRN_MD_TWC, r11
+
+ mfspr r11, SPRN_MD_TWC /* get the pte address again */
+ ori r10, r10, _PAGE_ACCESSED
+ stw r10, 0(r11)
+
+ /* The Linux PTE won't go exactly into the MMU TLB.
+ * Software indicator bits 21, 22 and 28 must be clear.
+ * Software indicator bits 24, 25, 26, and 27 must be
+ * set. All other Linux PTE bits control the behavior
+ * of the MMU.
+ */
+2: li r11, 0x00f0
+ rlwimi r10, r11, 0, 24, 28 /* Set 24-27, clear 28 */
+ DO_8xx_CPU6(0x3d80, r3)
+ mtspr SPRN_MD_RPN, r10 /* Update TLB entry */
+
+ mfspr r10, SPRN_M_TW /* Restore registers */
+ lwz r11, 0(r0)
+ mtcr r11
+ lwz r11, 4(r0)
+#ifdef CONFIG_8xx_CPU6
+ lwz r3, 8(r0)
+#endif
+ rfi
+
+/* This is an instruction TLB error on the MPC8xx. This could be due
+ * to many reasons, such as executing guarded memory or illegal instruction
+ * addresses. There is nothing to do but handle a big time error fault.
+ */
+ . = 0x1300
+InstructionTLBError:
+ b InstructionAccess
+
+/* This is the data TLB error on the MPC8xx. This could be due to
+ * many reasons, including a dirty update to a pte. We can catch that
+ * one here, but anything else is an error. First, we track down the
+ * Linux pte. If it is valid, write access is allowed, but the
+ * page dirty bit is not set, we will set it and reload the TLB. For
+ * any other case, we bail out to a higher level function that can
+ * handle it.
+ */
+ . = 0x1400
+DataTLBError:
+#ifdef CONFIG_8xx_CPU6
+ stw r3, 8(r0)
+#endif
+ DO_8xx_CPU6(0x3f80, r3)
+ mtspr SPRN_M_TW, r10 /* Save a couple of working registers */
+ mfcr r10
+ stw r10, 0(r0)
+ stw r11, 4(r0)
+
+ /* First, make sure this was a store operation.
+ */
+ mfspr r10, SPRN_DSISR
+ andis. r11, r10, 0x0200 /* If set, indicates store op */
+ beq 2f
+
+ /* The EA of a data TLB miss is automatically stored in the MD_EPN
+ * register. The EA of a data TLB error is automatically stored in
+ * the DAR, but not the MD_EPN register. We must copy the 20 most
+ * significant bits of the EA from the DAR to MD_EPN before we
+ * start walking the page tables. We also need to copy the CASID
+ * value from the M_CASID register.
+ * Addendum: The EA of a data TLB error is _supposed_ to be stored
+ * in DAR, but it seems that this doesn't happen in some cases, such
+ * as when the error is due to a dcbi instruction to a page with a
+ * TLB that doesn't have the changed bit set. In such cases, there
+ * does not appear to be any way to recover the EA of the error
+ * since it is neither in DAR nor MD_EPN. As a workaround, the
+ * _PAGE_HWWRITE bit is set for all kernel data pages when the PTEs
+ * are initialized in mapin_ram(). This will avoid the problem,
+ * assuming we only use the dcbi instruction on kernel addresses.
+ */
+ mfspr r10, SPRN_DAR
+ rlwinm r11, r10, 0, 0, 19
+ ori r11, r11, MD_EVALID
+ mfspr r10, SPRN_M_CASID
+ rlwimi r11, r10, 0, 28, 31
+ DO_8xx_CPU6(0x3780, r3)
+ mtspr SPRN_MD_EPN, r11
+
+ mfspr r10, SPRN_M_TWB /* Get level 1 table entry address */
+
+ /* If we are faulting a kernel address, we have to use the
+ * kernel page tables.
+ */
+ andi. r11, r10, 0x0800
+ beq 3f
+ lis r11, swapper_pg_dir@h
+ ori r11, r11, swapper_pg_dir@l
+ rlwimi r10, r11, 0, 2, 19
+3:
+ lwz r11, 0(r10) /* Get the level 1 entry */
+ rlwinm. r10, r11,0,0,19 /* Extract page descriptor page address */
+ beq 2f /* If zero, bail */
+
+ /* We have a pte table, so fetch the pte from the table.
+ */
+ ori r11, r11, 1 /* Set valid bit in physical L2 page */
+ DO_8xx_CPU6(0x3b80, r3)
+ mtspr SPRN_MD_TWC, r11 /* Load pte table base address */
+ mfspr r11, SPRN_MD_TWC /* ....and get the pte address */
+ lwz r10, 0(r11) /* Get the pte */
+
+ andi. r11, r10, _PAGE_RW /* Is it writeable? */
+ beq 2f /* Bail out if not */
+
+ /* Update 'changed', among others.
+ */
+ ori r10, r10, _PAGE_DIRTY|_PAGE_ACCESSED|_PAGE_HWWRITE
+ mfspr r11, SPRN_MD_TWC /* Get pte address again */
+ stw r10, 0(r11) /* and update pte in table */
+
+ /* The Linux PTE won't go exactly into the MMU TLB.
+ * Software indicator bits 21, 22 and 28 must be clear.
+ * Software indicator bits 24, 25, 26, and 27 must be
+ * set. All other Linux PTE bits control the behavior
+ * of the MMU.
+ */
+ li r11, 0x00f0
+ rlwimi r10, r11, 0, 24, 28 /* Set 24-27, clear 28 */
+ DO_8xx_CPU6(0x3d80, r3)
+ mtspr SPRN_MD_RPN, r10 /* Update TLB entry */
+
+ mfspr r10, SPRN_M_TW /* Restore registers */
+ lwz r11, 0(r0)
+ mtcr r11
+ lwz r11, 4(r0)
+#ifdef CONFIG_8xx_CPU6
+ lwz r3, 8(r0)
+#endif
+ rfi
+2:
+ mfspr r10, SPRN_M_TW /* Restore registers */
+ lwz r11, 0(r0)
+ mtcr r11
+ lwz r11, 4(r0)
+#ifdef CONFIG_8xx_CPU6
+ lwz r3, 8(r0)
+#endif
+ b DataAccess
+
+ EXCEPTION(0x1500, Trap_15, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x1600, Trap_16, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x1700, Trap_17, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x1800, Trap_18, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x1900, Trap_19, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x1a00, Trap_1a, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x1b00, Trap_1b, unknown_exception, EXC_XFER_EE)
+
+/* On the MPC8xx, these next four traps are used for development
+ * support of breakpoints and such. Someday I will get around to
+ * using them.
+ */
+ EXCEPTION(0x1c00, Trap_1c, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x1d00, Trap_1d, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x1e00, Trap_1e, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x1f00, Trap_1f, unknown_exception, EXC_XFER_EE)
+
+ . = 0x2000
+
+ .globl giveup_fpu
+giveup_fpu:
+ blr
+
+/*
+ * This is where the main kernel code starts.
+ */
+start_here:
+ /* ptr to current */
+ lis r2,init_task@h
+ ori r2,r2,init_task@l
+
+ /* ptr to phys current thread */
+ tophys(r4,r2)
+ addi r4,r4,THREAD /* init task's THREAD */
+ mtspr SPRN_SPRG3,r4
+ li r3,0
+ mtspr SPRN_SPRG2,r3 /* 0 => r1 has kernel sp */
+
+ /* stack */
+ lis r1,init_thread_union@ha
+ addi r1,r1,init_thread_union@l
+ li r0,0
+ stwu r0,THREAD_SIZE-STACK_FRAME_OVERHEAD(r1)
+
+ bl early_init /* We have to do this with MMU on */
+
+/*
+ * Decide what sort of machine this is and initialize the MMU.
+ */
+ mr r3,r31
+ mr r4,r30
+ mr r5,r29
+ mr r6,r28
+ mr r7,r27
+ bl machine_init
+ bl MMU_init
+
+/*
+ * Go back to running unmapped so we can load up new values
+ * and change to using our exception vectors.
+ * On the 8xx, all we have to do is invalidate the TLB to clear
+ * the old 8M byte TLB mappings and load the page table base register.
+ */
+ /* The right way to do this would be to track it down through
+ * init's THREAD like the context switch code does, but this is
+ * easier......until someone changes init's static structures.
+ */
+ lis r6, swapper_pg_dir@h
+ ori r6, r6, swapper_pg_dir@l
+ tophys(r6,r6)
+#ifdef CONFIG_8xx_CPU6
+ lis r4, cpu6_errata_word@h
+ ori r4, r4, cpu6_errata_word@l
+ li r3, 0x3980
+ stw r3, 12(r4)
+ lwz r3, 12(r4)
+#endif
+ mtspr SPRN_M_TWB, r6
+ lis r4,2f@h
+ ori r4,r4,2f@l
+ tophys(r4,r4)
+ li r3,MSR_KERNEL & ~(MSR_IR|MSR_DR)
+ mtspr SPRN_SRR0,r4
+ mtspr SPRN_SRR1,r3
+ rfi
+/* Load up the kernel context */
+2:
+ SYNC /* Force all PTE updates to finish */
+ tlbia /* Clear all TLB entries */
+ sync /* wait for tlbia/tlbie to finish */
+ TLBSYNC /* ... on all CPUs */
+
+ /* set up the PTE pointers for the Abatron bdiGDB.
+ */
+ tovirt(r6,r6)
+ lis r5, abatron_pteptrs@h
+ ori r5, r5, abatron_pteptrs@l
+ stw r5, 0xf0(r0) /* Must match your Abatron config file */
+ tophys(r5,r5)
+ stw r6, 0(r5)
+
+/* Now turn on the MMU for real! */
+ li r4,MSR_KERNEL
+ lis r3,start_kernel@h
+ ori r3,r3,start_kernel@l
+ mtspr SPRN_SRR0,r3
+ mtspr SPRN_SRR1,r4
+ rfi /* enable MMU and jump to start_kernel */
+
+/* Set up the initial MMU state so we can do the first level of
+ * kernel initialization. This maps the first 8 MBytes of memory 1:1
+ * virtual to physical. Also, set the cache mode since that is defined
+ * by TLB entries and perform any additional mapping (like of the IMMR).
+ * If configured to pin some TLBs, we pin the first 8 Mbytes of kernel,
+ * 24 Mbytes of data, and the 8M IMMR space. Anything not covered by
+ * these mappings is mapped by page tables.
+ */
+initial_mmu:
+ tlbia /* Invalidate all TLB entries */
+#ifdef CONFIG_PIN_TLB
+ lis r8, MI_RSV4I@h
+ ori r8, r8, 0x1c00
+#else
+ li r8, 0
+#endif
+ mtspr SPRN_MI_CTR, r8 /* Set instruction MMU control */
+
+#ifdef CONFIG_PIN_TLB
+ lis r10, (MD_RSV4I | MD_RESETVAL)@h
+ ori r10, r10, 0x1c00
+ mr r8, r10
+#else
+ lis r10, MD_RESETVAL@h
+#endif
+#ifndef CONFIG_8xx_COPYBACK
+ oris r10, r10, MD_WTDEF@h
+#endif
+ mtspr SPRN_MD_CTR, r10 /* Set data TLB control */
+
+ /* Now map the lower 8 Meg into the TLBs. For this quick hack,
+ * we can load the instruction and data TLB registers with the
+ * same values.
+ */
+ lis r8, KERNELBASE@h /* Create vaddr for TLB */
+ ori r8, r8, MI_EVALID /* Mark it valid */
+ mtspr SPRN_MI_EPN, r8
+ mtspr SPRN_MD_EPN, r8
+ li r8, MI_PS8MEG /* Set 8M byte page */
+ ori r8, r8, MI_SVALID /* Make it valid */
+ mtspr SPRN_MI_TWC, r8
+ mtspr SPRN_MD_TWC, r8
+ li r8, MI_BOOTINIT /* Create RPN for address 0 */
+ mtspr SPRN_MI_RPN, r8 /* Store TLB entry */
+ mtspr SPRN_MD_RPN, r8
+ lis r8, MI_Kp@h /* Set the protection mode */
+ mtspr SPRN_MI_AP, r8
+ mtspr SPRN_MD_AP, r8
+
+ /* Map another 8 MByte at the IMMR to get the processor
+ * internal registers (among other things).
+ */
+#ifdef CONFIG_PIN_TLB
+ addi r10, r10, 0x0100
+ mtspr SPRN_MD_CTR, r10
+#endif
+ mfspr r9, 638 /* Get current IMMR */
+ andis. r9, r9, 0xff80 /* Get 8Mbyte boundary */
+
+ mr r8, r9 /* Create vaddr for TLB */
+ ori r8, r8, MD_EVALID /* Mark it valid */
+ mtspr SPRN_MD_EPN, r8
+ li r8, MD_PS8MEG /* Set 8M byte page */
+ ori r8, r8, MD_SVALID /* Make it valid */
+ mtspr SPRN_MD_TWC, r8
+ mr r8, r9 /* Create paddr for TLB */
+ ori r8, r8, MI_BOOTINIT|0x2 /* Inhibit cache -- Cort */
+ mtspr SPRN_MD_RPN, r8
+
+#ifdef CONFIG_PIN_TLB
+ /* Map two more 8M kernel data pages.
+ */
+ addi r10, r10, 0x0100
+ mtspr SPRN_MD_CTR, r10
+
+ lis r8, KERNELBASE@h /* Create vaddr for TLB */
+ addis r8, r8, 0x0080 /* Add 8M */
+ ori r8, r8, MI_EVALID /* Mark it valid */
+ mtspr SPRN_MD_EPN, r8
+ li r9, MI_PS8MEG /* Set 8M byte page */
+ ori r9, r9, MI_SVALID /* Make it valid */
+ mtspr SPRN_MD_TWC, r9
+ li r11, MI_BOOTINIT /* Create RPN for address 0 */
+ addis r11, r11, 0x0080 /* Add 8M */
+ mtspr SPRN_MD_RPN, r8
+
+ addis r8, r8, 0x0080 /* Add 8M */
+ mtspr SPRN_MD_EPN, r8
+ mtspr SPRN_MD_TWC, r9
+ addis r11, r11, 0x0080 /* Add 8M */
+ mtspr SPRN_MD_RPN, r8
+#endif
+
+ /* Since the cache is enabled according to the information we
+ * just loaded into the TLB, invalidate and enable the caches here.
+ * We should probably check/set other modes....later.
+ */
+ lis r8, IDC_INVALL@h
+ mtspr SPRN_IC_CST, r8
+ mtspr SPRN_DC_CST, r8
+ lis r8, IDC_ENABLE@h
+ mtspr SPRN_IC_CST, r8
+#ifdef CONFIG_8xx_COPYBACK
+ mtspr SPRN_DC_CST, r8
+#else
+ /* For a debug option, I left this here to easily enable
+ * the write through cache mode
+ */
+ lis r8, DC_SFWT@h
+ mtspr SPRN_DC_CST, r8
+ lis r8, IDC_ENABLE@h
+ mtspr SPRN_DC_CST, r8
+#endif
+ blr
+
+
+/*
+ * Set up to use a given MMU context.
+ * r3 is context number, r4 is PGD pointer.
+ *
+ * We place the physical address of the new task page directory loaded
+ * into the MMU base register, and set the ASID compare register with
+ * the new "context."
+ */
+_GLOBAL(set_context)
+
+#ifdef CONFIG_BDI_SWITCH
+ /* Context switch the PTE pointer for the Abatron BDI2000.
+ * The PGDIR is passed as second argument.
+ */
+ lis r5, KERNELBASE@h
+ lwz r5, 0xf0(r5)
+ stw r4, 0x4(r5)
+#endif
+
+#ifdef CONFIG_8xx_CPU6
+ lis r6, cpu6_errata_word@h
+ ori r6, r6, cpu6_errata_word@l
+ tophys (r4, r4)
+ li r7, 0x3980
+ stw r7, 12(r6)
+ lwz r7, 12(r6)
+ mtspr SPRN_M_TWB, r4 /* Update MMU base address */
+ li r7, 0x3380
+ stw r7, 12(r6)
+ lwz r7, 12(r6)
+ mtspr SPRN_M_CASID, r3 /* Update context */
+#else
+ mtspr SPRN_M_CASID,r3 /* Update context */
+ tophys (r4, r4)
+ mtspr SPRN_M_TWB, r4 /* and pgd */
+#endif
+ SYNC
+ blr
+
+#ifdef CONFIG_8xx_CPU6
+/* It's here because it is unique to the 8xx.
+ * It is important we get called with interrupts disabled. I used to
+ * do that, but it appears that all code that calls this already had
+ * interrupt disabled.
+ */
+ .globl set_dec_cpu6
+set_dec_cpu6:
+ lis r7, cpu6_errata_word@h
+ ori r7, r7, cpu6_errata_word@l
+ li r4, 0x2c00
+ stw r4, 8(r7)
+ lwz r4, 8(r7)
+ mtspr 22, r3 /* Update Decrementer */
+ SYNC
+ blr
+#endif
+
+/*
+ * We put a few things here that have to be page-aligned.
+ * This stuff goes at the beginning of the data segment,
+ * which is page-aligned.
+ */
+ .data
+ .globl sdata
+sdata:
+ .globl empty_zero_page
+empty_zero_page:
+ .space 4096
+
+ .globl swapper_pg_dir
+swapper_pg_dir:
+ .space 4096
+
+/*
+ * This space gets a copy of optional info passed to us by the bootstrap
+ * Used to pass parameters into the kernel like root=/dev/sda1, etc.
+ */
+ .globl cmd_line
+cmd_line:
+ .space 512
+
+/* Room for two PTE table poiners, usually the kernel and current user
+ * pointer to their respective root page table (pgdir).
+ */
+abatron_pteptrs:
+ .space 8
+
+#ifdef CONFIG_8xx_CPU6
+ .globl cpu6_errata_word
+cpu6_errata_word:
+ .space 16
+#endif
+
diff --git a/arch/powerpc/kernel/head_fsl_booke.S b/arch/powerpc/kernel/head_fsl_booke.S
new file mode 100644
index 000000000000..5063c603fad4
--- /dev/null
+++ b/arch/powerpc/kernel/head_fsl_booke.S
@@ -0,0 +1,1063 @@
+/*
+ * arch/ppc/kernel/head_fsl_booke.S
+ *
+ * Kernel execution entry point code.
+ *
+ * Copyright (c) 1995-1996 Gary Thomas <gdt@linuxppc.org>
+ * Initial PowerPC version.
+ * Copyright (c) 1996 Cort Dougan <cort@cs.nmt.edu>
+ * Rewritten for PReP
+ * Copyright (c) 1996 Paul Mackerras <paulus@cs.anu.edu.au>
+ * Low-level exception handers, MMU support, and rewrite.
+ * Copyright (c) 1997 Dan Malek <dmalek@jlc.net>
+ * PowerPC 8xx modifications.
+ * Copyright (c) 1998-1999 TiVo, Inc.
+ * PowerPC 403GCX modifications.
+ * Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu>
+ * PowerPC 403GCX/405GP modifications.
+ * Copyright 2000 MontaVista Software Inc.
+ * PPC405 modifications
+ * PowerPC 403GCX/405GP modifications.
+ * Author: MontaVista Software, Inc.
+ * frank_rowand@mvista.com or source@mvista.com
+ * debbie_chu@mvista.com
+ * Copyright 2002-2004 MontaVista Software, Inc.
+ * PowerPC 44x support, Matt Porter <mporter@kernel.crashing.org>
+ * Copyright 2004 Freescale Semiconductor, Inc
+ * PowerPC e500 modifications, Kumar Gala <kumar.gala@freescale.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/config.h>
+#include <linux/threads.h>
+#include <asm/processor.h>
+#include <asm/page.h>
+#include <asm/mmu.h>
+#include <asm/pgtable.h>
+#include <asm/cputable.h>
+#include <asm/thread_info.h>
+#include <asm/ppc_asm.h>
+#include <asm/asm-offsets.h>
+#include "head_booke.h"
+
+/* As with the other PowerPC ports, it is expected that when code
+ * execution begins here, the following registers contain valid, yet
+ * optional, information:
+ *
+ * r3 - Board info structure pointer (DRAM, frequency, MAC address, etc.)
+ * r4 - Starting address of the init RAM disk
+ * r5 - Ending address of the init RAM disk
+ * r6 - Start of kernel command line string (e.g. "mem=128")
+ * r7 - End of kernel command line string
+ *
+ */
+ .text
+_GLOBAL(_stext)
+_GLOBAL(_start)
+ /*
+ * Reserve a word at a fixed location to store the address
+ * of abatron_pteptrs
+ */
+ nop
+/*
+ * Save parameters we are passed
+ */
+ mr r31,r3
+ mr r30,r4
+ mr r29,r5
+ mr r28,r6
+ mr r27,r7
+ li r24,0 /* CPU number */
+
+/* We try to not make any assumptions about how the boot loader
+ * setup or used the TLBs. We invalidate all mappings from the
+ * boot loader and load a single entry in TLB1[0] to map the
+ * first 16M of kernel memory. Any boot info passed from the
+ * bootloader needs to live in this first 16M.
+ *
+ * Requirement on bootloader:
+ * - The page we're executing in needs to reside in TLB1 and
+ * have IPROT=1. If not an invalidate broadcast could
+ * evict the entry we're currently executing in.
+ *
+ * r3 = Index of TLB1 were executing in
+ * r4 = Current MSR[IS]
+ * r5 = Index of TLB1 temp mapping
+ *
+ * Later in mapin_ram we will correctly map lowmem, and resize TLB1[0]
+ * if needed
+ */
+
+/* 1. Find the index of the entry we're executing in */
+ bl invstr /* Find our address */
+invstr: mflr r6 /* Make it accessible */
+ mfmsr r7
+ rlwinm r4,r7,27,31,31 /* extract MSR[IS] */
+ mfspr r7, SPRN_PID0
+ slwi r7,r7,16
+ or r7,r7,r4
+ mtspr SPRN_MAS6,r7
+ tlbsx 0,r6 /* search MSR[IS], SPID=PID0 */
+#ifndef CONFIG_E200
+ mfspr r7,SPRN_MAS1
+ andis. r7,r7,MAS1_VALID@h
+ bne match_TLB
+ mfspr r7,SPRN_PID1
+ slwi r7,r7,16
+ or r7,r7,r4
+ mtspr SPRN_MAS6,r7
+ tlbsx 0,r6 /* search MSR[IS], SPID=PID1 */
+ mfspr r7,SPRN_MAS1
+ andis. r7,r7,MAS1_VALID@h
+ bne match_TLB
+ mfspr r7, SPRN_PID2
+ slwi r7,r7,16
+ or r7,r7,r4
+ mtspr SPRN_MAS6,r7
+ tlbsx 0,r6 /* Fall through, we had to match */
+#endif
+match_TLB:
+ mfspr r7,SPRN_MAS0
+ rlwinm r3,r7,16,20,31 /* Extract MAS0(Entry) */
+
+ mfspr r7,SPRN_MAS1 /* Insure IPROT set */
+ oris r7,r7,MAS1_IPROT@h
+ mtspr SPRN_MAS1,r7
+ tlbwe
+
+/* 2. Invalidate all entries except the entry we're executing in */
+ mfspr r9,SPRN_TLB1CFG
+ andi. r9,r9,0xfff
+ li r6,0 /* Set Entry counter to 0 */
+1: lis r7,0x1000 /* Set MAS0(TLBSEL) = 1 */
+ rlwimi r7,r6,16,4,15 /* Setup MAS0 = TLBSEL | ESEL(r6) */
+ mtspr SPRN_MAS0,r7
+ tlbre
+ mfspr r7,SPRN_MAS1
+ rlwinm r7,r7,0,2,31 /* Clear MAS1 Valid and IPROT */
+ cmpw r3,r6
+ beq skpinv /* Dont update the current execution TLB */
+ mtspr SPRN_MAS1,r7
+ tlbwe
+ isync
+skpinv: addi r6,r6,1 /* Increment */
+ cmpw r6,r9 /* Are we done? */
+ bne 1b /* If not, repeat */
+
+ /* Invalidate TLB0 */
+ li r6,0x04
+ tlbivax 0,r6
+#ifdef CONFIG_SMP
+ tlbsync
+#endif
+ /* Invalidate TLB1 */
+ li r6,0x0c
+ tlbivax 0,r6
+#ifdef CONFIG_SMP
+ tlbsync
+#endif
+ msync
+
+/* 3. Setup a temp mapping and jump to it */
+ andi. r5, r3, 0x1 /* Find an entry not used and is non-zero */
+ addi r5, r5, 0x1
+ lis r7,0x1000 /* Set MAS0(TLBSEL) = 1 */
+ rlwimi r7,r3,16,4,15 /* Setup MAS0 = TLBSEL | ESEL(r3) */
+ mtspr SPRN_MAS0,r7
+ tlbre
+
+ /* Just modify the entry ID and EPN for the temp mapping */
+ lis r7,0x1000 /* Set MAS0(TLBSEL) = 1 */
+ rlwimi r7,r5,16,4,15 /* Setup MAS0 = TLBSEL | ESEL(r5) */
+ mtspr SPRN_MAS0,r7
+ xori r6,r4,1 /* Setup TMP mapping in the other Address space */
+ slwi r6,r6,12
+ oris r6,r6,(MAS1_VALID|MAS1_IPROT)@h
+ ori r6,r6,(MAS1_TSIZE(BOOKE_PAGESZ_4K))@l
+ mtspr SPRN_MAS1,r6
+ mfspr r6,SPRN_MAS2
+ li r7,0 /* temp EPN = 0 */
+ rlwimi r7,r6,0,20,31
+ mtspr SPRN_MAS2,r7
+ tlbwe
+
+ xori r6,r4,1
+ slwi r6,r6,5 /* setup new context with other address space */
+ bl 1f /* Find our address */
+1: mflr r9
+ rlwimi r7,r9,0,20,31
+ addi r7,r7,24
+ mtspr SPRN_SRR0,r7
+ mtspr SPRN_SRR1,r6
+ rfi
+
+/* 4. Clear out PIDs & Search info */
+ li r6,0
+ mtspr SPRN_PID0,r6
+#ifndef CONFIG_E200
+ mtspr SPRN_PID1,r6
+ mtspr SPRN_PID2,r6
+#endif
+ mtspr SPRN_MAS6,r6
+
+/* 5. Invalidate mapping we started in */
+ lis r7,0x1000 /* Set MAS0(TLBSEL) = 1 */
+ rlwimi r7,r3,16,4,15 /* Setup MAS0 = TLBSEL | ESEL(r3) */
+ mtspr SPRN_MAS0,r7
+ tlbre
+ li r6,0
+ mtspr SPRN_MAS1,r6
+ tlbwe
+ /* Invalidate TLB1 */
+ li r9,0x0c
+ tlbivax 0,r9
+#ifdef CONFIG_SMP
+ tlbsync
+#endif
+ msync
+
+/* 6. Setup KERNELBASE mapping in TLB1[0] */
+ lis r6,0x1000 /* Set MAS0(TLBSEL) = TLB1(1), ESEL = 0 */
+ mtspr SPRN_MAS0,r6
+ lis r6,(MAS1_VALID|MAS1_IPROT)@h
+ ori r6,r6,(MAS1_TSIZE(BOOKE_PAGESZ_16M))@l
+ mtspr SPRN_MAS1,r6
+ li r7,0
+ lis r6,KERNELBASE@h
+ ori r6,r6,KERNELBASE@l
+ rlwimi r6,r7,0,20,31
+ mtspr SPRN_MAS2,r6
+ li r7,(MAS3_SX|MAS3_SW|MAS3_SR)
+ mtspr SPRN_MAS3,r7
+ tlbwe
+
+/* 7. Jump to KERNELBASE mapping */
+ lis r7,MSR_KERNEL@h
+ ori r7,r7,MSR_KERNEL@l
+ bl 1f /* Find our address */
+1: mflr r9
+ rlwimi r6,r9,0,20,31
+ addi r6,r6,24
+ mtspr SPRN_SRR0,r6
+ mtspr SPRN_SRR1,r7
+ rfi /* start execution out of TLB1[0] entry */
+
+/* 8. Clear out the temp mapping */
+ lis r7,0x1000 /* Set MAS0(TLBSEL) = 1 */
+ rlwimi r7,r5,16,4,15 /* Setup MAS0 = TLBSEL | ESEL(r5) */
+ mtspr SPRN_MAS0,r7
+ tlbre
+ mtspr SPRN_MAS1,r8
+ tlbwe
+ /* Invalidate TLB1 */
+ li r9,0x0c
+ tlbivax 0,r9
+#ifdef CONFIG_SMP
+ tlbsync
+#endif
+ msync
+
+ /* Establish the interrupt vector offsets */
+ SET_IVOR(0, CriticalInput);
+ SET_IVOR(1, MachineCheck);
+ SET_IVOR(2, DataStorage);
+ SET_IVOR(3, InstructionStorage);
+ SET_IVOR(4, ExternalInput);
+ SET_IVOR(5, Alignment);
+ SET_IVOR(6, Program);
+ SET_IVOR(7, FloatingPointUnavailable);
+ SET_IVOR(8, SystemCall);
+ SET_IVOR(9, AuxillaryProcessorUnavailable);
+ SET_IVOR(10, Decrementer);
+ SET_IVOR(11, FixedIntervalTimer);
+ SET_IVOR(12, WatchdogTimer);
+ SET_IVOR(13, DataTLBError);
+ SET_IVOR(14, InstructionTLBError);
+ SET_IVOR(15, Debug);
+ SET_IVOR(32, SPEUnavailable);
+ SET_IVOR(33, SPEFloatingPointData);
+ SET_IVOR(34, SPEFloatingPointRound);
+#ifndef CONFIG_E200
+ SET_IVOR(35, PerformanceMonitor);
+#endif
+
+ /* Establish the interrupt vector base */
+ lis r4,interrupt_base@h /* IVPR only uses the high 16-bits */
+ mtspr SPRN_IVPR,r4
+
+ /* Setup the defaults for TLB entries */
+ li r2,(MAS4_TSIZED(BOOKE_PAGESZ_4K))@l
+#ifdef CONFIG_E200
+ oris r2,r2,MAS4_TLBSELD(1)@h
+#endif
+ mtspr SPRN_MAS4, r2
+
+#if 0
+ /* Enable DOZE */
+ mfspr r2,SPRN_HID0
+ oris r2,r2,HID0_DOZE@h
+ mtspr SPRN_HID0, r2
+#endif
+#ifdef CONFIG_E200
+ /* enable dedicated debug exception handling resources (Debug APU) */
+ mfspr r2,SPRN_HID0
+ ori r2,r2,HID0_DAPUEN@l
+ mtspr SPRN_HID0,r2
+#endif
+
+#if !defined(CONFIG_BDI_SWITCH)
+ /*
+ * The Abatron BDI JTAG debugger does not tolerate others
+ * mucking with the debug registers.
+ */
+ lis r2,DBCR0_IDM@h
+ mtspr SPRN_DBCR0,r2
+ /* clear any residual debug events */
+ li r2,-1
+ mtspr SPRN_DBSR,r2
+#endif
+
+ /*
+ * This is where the main kernel code starts.
+ */
+
+ /* ptr to current */
+ lis r2,init_task@h
+ ori r2,r2,init_task@l
+
+ /* ptr to current thread */
+ addi r4,r2,THREAD /* init task's THREAD */
+ mtspr SPRN_SPRG3,r4
+
+ /* stack */
+ lis r1,init_thread_union@h
+ ori r1,r1,init_thread_union@l
+ li r0,0
+ stwu r0,THREAD_SIZE-STACK_FRAME_OVERHEAD(r1)
+
+ bl early_init
+
+ mfspr r3,SPRN_TLB1CFG
+ andi. r3,r3,0xfff
+ lis r4,num_tlbcam_entries@ha
+ stw r3,num_tlbcam_entries@l(r4)
+/*
+ * Decide what sort of machine this is and initialize the MMU.
+ */
+ mr r3,r31
+ mr r4,r30
+ mr r5,r29
+ mr r6,r28
+ mr r7,r27
+ bl machine_init
+ bl MMU_init
+
+ /* Setup PTE pointers for the Abatron bdiGDB */
+ lis r6, swapper_pg_dir@h
+ ori r6, r6, swapper_pg_dir@l
+ lis r5, abatron_pteptrs@h
+ ori r5, r5, abatron_pteptrs@l
+ lis r4, KERNELBASE@h
+ ori r4, r4, KERNELBASE@l
+ stw r5, 0(r4) /* Save abatron_pteptrs at a fixed location */
+ stw r6, 0(r5)
+
+ /* Let's move on */
+ lis r4,start_kernel@h
+ ori r4,r4,start_kernel@l
+ lis r3,MSR_KERNEL@h
+ ori r3,r3,MSR_KERNEL@l
+ mtspr SPRN_SRR0,r4
+ mtspr SPRN_SRR1,r3
+ rfi /* change context and jump to start_kernel */
+
+/* Macros to hide the PTE size differences
+ *
+ * FIND_PTE -- walks the page tables given EA & pgdir pointer
+ * r10 -- EA of fault
+ * r11 -- PGDIR pointer
+ * r12 -- free
+ * label 2: is the bailout case
+ *
+ * if we find the pte (fall through):
+ * r11 is low pte word
+ * r12 is pointer to the pte
+ */
+#ifdef CONFIG_PTE_64BIT
+#define PTE_FLAGS_OFFSET 4
+#define FIND_PTE \
+ rlwinm r12, r10, 13, 19, 29; /* Compute pgdir/pmd offset */ \
+ lwzx r11, r12, r11; /* Get pgd/pmd entry */ \
+ rlwinm. r12, r11, 0, 0, 20; /* Extract pt base address */ \
+ beq 2f; /* Bail if no table */ \
+ rlwimi r12, r10, 23, 20, 28; /* Compute pte address */ \
+ lwz r11, 4(r12); /* Get pte entry */
+#else
+#define PTE_FLAGS_OFFSET 0
+#define FIND_PTE \
+ rlwimi r11, r10, 12, 20, 29; /* Create L1 (pgdir/pmd) address */ \
+ lwz r11, 0(r11); /* Get L1 entry */ \
+ rlwinm. r12, r11, 0, 0, 19; /* Extract L2 (pte) base address */ \
+ beq 2f; /* Bail if no table */ \
+ rlwimi r12, r10, 22, 20, 29; /* Compute PTE address */ \
+ lwz r11, 0(r12); /* Get Linux PTE */
+#endif
+
+/*
+ * Interrupt vector entry code
+ *
+ * The Book E MMUs are always on so we don't need to handle
+ * interrupts in real mode as with previous PPC processors. In
+ * this case we handle interrupts in the kernel virtual address
+ * space.
+ *
+ * Interrupt vectors are dynamically placed relative to the
+ * interrupt prefix as determined by the address of interrupt_base.
+ * The interrupt vectors offsets are programmed using the labels
+ * for each interrupt vector entry.
+ *
+ * Interrupt vectors must be aligned on a 16 byte boundary.
+ * We align on a 32 byte cache line boundary for good measure.
+ */
+
+interrupt_base:
+ /* Critical Input Interrupt */
+ CRITICAL_EXCEPTION(0x0100, CriticalInput, unknown_exception)
+
+ /* Machine Check Interrupt */
+#ifdef CONFIG_E200
+ /* no RFMCI, MCSRRs on E200 */
+ CRITICAL_EXCEPTION(0x0200, MachineCheck, machine_check_exception)
+#else
+ MCHECK_EXCEPTION(0x0200, MachineCheck, machine_check_exception)
+#endif
+
+ /* Data Storage Interrupt */
+ START_EXCEPTION(DataStorage)
+ mtspr SPRN_SPRG0, r10 /* Save some working registers */
+ mtspr SPRN_SPRG1, r11
+ mtspr SPRN_SPRG4W, r12
+ mtspr SPRN_SPRG5W, r13
+ mfcr r11
+ mtspr SPRN_SPRG7W, r11
+
+ /*
+ * Check if it was a store fault, if not then bail
+ * because a user tried to access a kernel or
+ * read-protected page. Otherwise, get the
+ * offending address and handle it.
+ */
+ mfspr r10, SPRN_ESR
+ andis. r10, r10, ESR_ST@h
+ beq 2f
+
+ mfspr r10, SPRN_DEAR /* Get faulting address */
+
+ /* If we are faulting a kernel address, we have to use the
+ * kernel page tables.
+ */
+ lis r11, TASK_SIZE@h
+ ori r11, r11, TASK_SIZE@l
+ cmplw 0, r10, r11
+ bge 2f
+
+ /* Get the PGD for the current thread */
+3:
+ mfspr r11,SPRN_SPRG3
+ lwz r11,PGDIR(r11)
+4:
+ FIND_PTE
+
+ /* Are _PAGE_USER & _PAGE_RW set & _PAGE_HWWRITE not? */
+ andi. r13, r11, _PAGE_RW|_PAGE_USER|_PAGE_HWWRITE
+ cmpwi 0, r13, _PAGE_RW|_PAGE_USER
+ bne 2f /* Bail if not */
+
+ /* Update 'changed'. */
+ ori r11, r11, _PAGE_DIRTY|_PAGE_ACCESSED|_PAGE_HWWRITE
+ stw r11, PTE_FLAGS_OFFSET(r12) /* Update Linux page table */
+
+ /* MAS2 not updated as the entry does exist in the tlb, this
+ fault taken to detect state transition (eg: COW -> DIRTY)
+ */
+ andi. r11, r11, _PAGE_HWEXEC
+ rlwimi r11, r11, 31, 27, 27 /* SX <- _PAGE_HWEXEC */
+ ori r11, r11, (MAS3_UW|MAS3_SW|MAS3_UR|MAS3_SR)@l /* set static perms */
+
+ /* update search PID in MAS6, AS = 0 */
+ mfspr r12, SPRN_PID0
+ slwi r12, r12, 16
+ mtspr SPRN_MAS6, r12
+
+ /* find the TLB index that caused the fault. It has to be here. */
+ tlbsx 0, r10
+
+ /* only update the perm bits, assume the RPN is fine */
+ mfspr r12, SPRN_MAS3
+ rlwimi r12, r11, 0, 20, 31
+ mtspr SPRN_MAS3,r12
+ tlbwe
+
+ /* Done...restore registers and get out of here. */
+ mfspr r11, SPRN_SPRG7R
+ mtcr r11
+ mfspr r13, SPRN_SPRG5R
+ mfspr r12, SPRN_SPRG4R
+ mfspr r11, SPRN_SPRG1
+ mfspr r10, SPRN_SPRG0
+ rfi /* Force context change */
+
+2:
+ /*
+ * The bailout. Restore registers to pre-exception conditions
+ * and call the heavyweights to help us out.
+ */
+ mfspr r11, SPRN_SPRG7R
+ mtcr r11
+ mfspr r13, SPRN_SPRG5R
+ mfspr r12, SPRN_SPRG4R
+ mfspr r11, SPRN_SPRG1
+ mfspr r10, SPRN_SPRG0
+ b data_access
+
+ /* Instruction Storage Interrupt */
+ INSTRUCTION_STORAGE_EXCEPTION
+
+ /* External Input Interrupt */
+ EXCEPTION(0x0500, ExternalInput, do_IRQ, EXC_XFER_LITE)
+
+ /* Alignment Interrupt */
+ ALIGNMENT_EXCEPTION
+
+ /* Program Interrupt */
+ PROGRAM_EXCEPTION
+
+ /* Floating Point Unavailable Interrupt */
+#ifdef CONFIG_PPC_FPU
+ FP_UNAVAILABLE_EXCEPTION
+#else
+#ifdef CONFIG_E200
+ /* E200 treats 'normal' floating point instructions as FP Unavail exception */
+ EXCEPTION(0x0800, FloatingPointUnavailable, program_check_exception, EXC_XFER_EE)
+#else
+ EXCEPTION(0x0800, FloatingPointUnavailable, unknown_exception, EXC_XFER_EE)
+#endif
+#endif
+
+ /* System Call Interrupt */
+ START_EXCEPTION(SystemCall)
+ NORMAL_EXCEPTION_PROLOG
+ EXC_XFER_EE_LITE(0x0c00, DoSyscall)
+
+ /* Auxillary Processor Unavailable Interrupt */
+ EXCEPTION(0x2900, AuxillaryProcessorUnavailable, unknown_exception, EXC_XFER_EE)
+
+ /* Decrementer Interrupt */
+ DECREMENTER_EXCEPTION
+
+ /* Fixed Internal Timer Interrupt */
+ /* TODO: Add FIT support */
+ EXCEPTION(0x3100, FixedIntervalTimer, unknown_exception, EXC_XFER_EE)
+
+ /* Watchdog Timer Interrupt */
+#ifdef CONFIG_BOOKE_WDT
+ CRITICAL_EXCEPTION(0x3200, WatchdogTimer, WatchdogException)
+#else
+ CRITICAL_EXCEPTION(0x3200, WatchdogTimer, unknown_exception)
+#endif
+
+ /* Data TLB Error Interrupt */
+ START_EXCEPTION(DataTLBError)
+ mtspr SPRN_SPRG0, r10 /* Save some working registers */
+ mtspr SPRN_SPRG1, r11
+ mtspr SPRN_SPRG4W, r12
+ mtspr SPRN_SPRG5W, r13
+ mfcr r11
+ mtspr SPRN_SPRG7W, r11
+ mfspr r10, SPRN_DEAR /* Get faulting address */
+
+ /* If we are faulting a kernel address, we have to use the
+ * kernel page tables.
+ */
+ lis r11, TASK_SIZE@h
+ ori r11, r11, TASK_SIZE@l
+ cmplw 5, r10, r11
+ blt 5, 3f
+ lis r11, swapper_pg_dir@h
+ ori r11, r11, swapper_pg_dir@l
+
+ mfspr r12,SPRN_MAS1 /* Set TID to 0 */
+ rlwinm r12,r12,0,16,1
+ mtspr SPRN_MAS1,r12
+
+ b 4f
+
+ /* Get the PGD for the current thread */
+3:
+ mfspr r11,SPRN_SPRG3
+ lwz r11,PGDIR(r11)
+
+4:
+ FIND_PTE
+ andi. r13, r11, _PAGE_PRESENT /* Is the page present? */
+ beq 2f /* Bail if not present */
+
+#ifdef CONFIG_PTE_64BIT
+ lwz r13, 0(r12)
+#endif
+ ori r11, r11, _PAGE_ACCESSED
+ stw r11, PTE_FLAGS_OFFSET(r12)
+
+ /* Jump to common tlb load */
+ b finish_tlb_load
+2:
+ /* The bailout. Restore registers to pre-exception conditions
+ * and call the heavyweights to help us out.
+ */
+ mfspr r11, SPRN_SPRG7R
+ mtcr r11
+ mfspr r13, SPRN_SPRG5R
+ mfspr r12, SPRN_SPRG4R
+ mfspr r11, SPRN_SPRG1
+ mfspr r10, SPRN_SPRG0
+ b data_access
+
+ /* Instruction TLB Error Interrupt */
+ /*
+ * Nearly the same as above, except we get our
+ * information from different registers and bailout
+ * to a different point.
+ */
+ START_EXCEPTION(InstructionTLBError)
+ mtspr SPRN_SPRG0, r10 /* Save some working registers */
+ mtspr SPRN_SPRG1, r11
+ mtspr SPRN_SPRG4W, r12
+ mtspr SPRN_SPRG5W, r13
+ mfcr r11
+ mtspr SPRN_SPRG7W, r11
+ mfspr r10, SPRN_SRR0 /* Get faulting address */
+
+ /* If we are faulting a kernel address, we have to use the
+ * kernel page tables.
+ */
+ lis r11, TASK_SIZE@h
+ ori r11, r11, TASK_SIZE@l
+ cmplw 5, r10, r11
+ blt 5, 3f
+ lis r11, swapper_pg_dir@h
+ ori r11, r11, swapper_pg_dir@l
+
+ mfspr r12,SPRN_MAS1 /* Set TID to 0 */
+ rlwinm r12,r12,0,16,1
+ mtspr SPRN_MAS1,r12
+
+ b 4f
+
+ /* Get the PGD for the current thread */
+3:
+ mfspr r11,SPRN_SPRG3
+ lwz r11,PGDIR(r11)
+
+4:
+ FIND_PTE
+ andi. r13, r11, _PAGE_PRESENT /* Is the page present? */
+ beq 2f /* Bail if not present */
+
+#ifdef CONFIG_PTE_64BIT
+ lwz r13, 0(r12)
+#endif
+ ori r11, r11, _PAGE_ACCESSED
+ stw r11, PTE_FLAGS_OFFSET(r12)
+
+ /* Jump to common TLB load point */
+ b finish_tlb_load
+
+2:
+ /* The bailout. Restore registers to pre-exception conditions
+ * and call the heavyweights to help us out.
+ */
+ mfspr r11, SPRN_SPRG7R
+ mtcr r11
+ mfspr r13, SPRN_SPRG5R
+ mfspr r12, SPRN_SPRG4R
+ mfspr r11, SPRN_SPRG1
+ mfspr r10, SPRN_SPRG0
+ b InstructionStorage
+
+#ifdef CONFIG_SPE
+ /* SPE Unavailable */
+ START_EXCEPTION(SPEUnavailable)
+ NORMAL_EXCEPTION_PROLOG
+ bne load_up_spe
+ addi r3,r1,STACK_FRAME_OVERHEAD
+ EXC_XFER_EE_LITE(0x2010, KernelSPE)
+#else
+ EXCEPTION(0x2020, SPEUnavailable, unknown_exception, EXC_XFER_EE)
+#endif /* CONFIG_SPE */
+
+ /* SPE Floating Point Data */
+#ifdef CONFIG_SPE
+ EXCEPTION(0x2030, SPEFloatingPointData, SPEFloatingPointException, EXC_XFER_EE);
+#else
+ EXCEPTION(0x2040, SPEFloatingPointData, unknown_exception, EXC_XFER_EE)
+#endif /* CONFIG_SPE */
+
+ /* SPE Floating Point Round */
+ EXCEPTION(0x2050, SPEFloatingPointRound, unknown_exception, EXC_XFER_EE)
+
+ /* Performance Monitor */
+ EXCEPTION(0x2060, PerformanceMonitor, performance_monitor_exception, EXC_XFER_STD)
+
+
+ /* Debug Interrupt */
+ DEBUG_EXCEPTION
+
+/*
+ * Local functions
+ */
+
+ /*
+ * Data TLB exceptions will bail out to this point
+ * if they can't resolve the lightweight TLB fault.
+ */
+data_access:
+ NORMAL_EXCEPTION_PROLOG
+ mfspr r5,SPRN_ESR /* Grab the ESR, save it, pass arg3 */
+ stw r5,_ESR(r11)
+ mfspr r4,SPRN_DEAR /* Grab the DEAR, save it, pass arg2 */
+ andis. r10,r5,(ESR_ILK|ESR_DLK)@h
+ bne 1f
+ EXC_XFER_EE_LITE(0x0300, handle_page_fault)
+1:
+ addi r3,r1,STACK_FRAME_OVERHEAD
+ EXC_XFER_EE_LITE(0x0300, CacheLockingException)
+
+/*
+
+ * Both the instruction and data TLB miss get to this
+ * point to load the TLB.
+ * r10 - EA of fault
+ * r11 - TLB (info from Linux PTE)
+ * r12, r13 - available to use
+ * CR5 - results of addr < TASK_SIZE
+ * MAS0, MAS1 - loaded with proper value when we get here
+ * MAS2, MAS3 - will need additional info from Linux PTE
+ * Upon exit, we reload everything and RFI.
+ */
+finish_tlb_load:
+ /*
+ * We set execute, because we don't have the granularity to
+ * properly set this at the page level (Linux problem).
+ * Many of these bits are software only. Bits we don't set
+ * here we (properly should) assume have the appropriate value.
+ */
+
+ mfspr r12, SPRN_MAS2
+#ifdef CONFIG_PTE_64BIT
+ rlwimi r12, r11, 26, 24, 31 /* extract ...WIMGE from pte */
+#else
+ rlwimi r12, r11, 26, 27, 31 /* extract WIMGE from pte */
+#endif
+ mtspr SPRN_MAS2, r12
+
+ bge 5, 1f
+
+ /* is user addr */
+ andi. r12, r11, (_PAGE_USER | _PAGE_HWWRITE | _PAGE_HWEXEC)
+ andi. r10, r11, _PAGE_USER /* Test for _PAGE_USER */
+ srwi r10, r12, 1
+ or r12, r12, r10 /* Copy user perms into supervisor */
+ iseleq r12, 0, r12
+ b 2f
+
+ /* is kernel addr */
+1: rlwinm r12, r11, 31, 29, 29 /* Extract _PAGE_HWWRITE into SW */
+ ori r12, r12, (MAS3_SX | MAS3_SR)
+
+#ifdef CONFIG_PTE_64BIT
+2: rlwimi r12, r13, 24, 0, 7 /* grab RPN[32:39] */
+ rlwimi r12, r11, 24, 8, 19 /* grab RPN[40:51] */
+ mtspr SPRN_MAS3, r12
+BEGIN_FTR_SECTION
+ srwi r10, r13, 8 /* grab RPN[8:31] */
+ mtspr SPRN_MAS7, r10
+END_FTR_SECTION_IFSET(CPU_FTR_BIG_PHYS)
+#else
+2: rlwimi r11, r12, 0, 20, 31 /* Extract RPN from PTE and merge with perms */
+ mtspr SPRN_MAS3, r11
+#endif
+#ifdef CONFIG_E200
+ /* Round robin TLB1 entries assignment */
+ mfspr r12, SPRN_MAS0
+
+ /* Extract TLB1CFG(NENTRY) */
+ mfspr r11, SPRN_TLB1CFG
+ andi. r11, r11, 0xfff
+
+ /* Extract MAS0(NV) */
+ andi. r13, r12, 0xfff
+ addi r13, r13, 1
+ cmpw 0, r13, r11
+ addi r12, r12, 1
+
+ /* check if we need to wrap */
+ blt 7f
+
+ /* wrap back to first free tlbcam entry */
+ lis r13, tlbcam_index@ha
+ lwz r13, tlbcam_index@l(r13)
+ rlwimi r12, r13, 0, 20, 31
+7:
+ mtspr SPRN_MAS0,r12
+#endif /* CONFIG_E200 */
+
+ tlbwe
+
+ /* Done...restore registers and get out of here. */
+ mfspr r11, SPRN_SPRG7R
+ mtcr r11
+ mfspr r13, SPRN_SPRG5R
+ mfspr r12, SPRN_SPRG4R
+ mfspr r11, SPRN_SPRG1
+ mfspr r10, SPRN_SPRG0
+ rfi /* Force context change */
+
+#ifdef CONFIG_SPE
+/* Note that the SPE support is closely modeled after the AltiVec
+ * support. Changes to one are likely to be applicable to the
+ * other! */
+load_up_spe:
+/*
+ * Disable SPE for the task which had SPE previously,
+ * and save its SPE registers in its thread_struct.
+ * Enables SPE for use in the kernel on return.
+ * On SMP we know the SPE units are free, since we give it up every
+ * switch. -- Kumar
+ */
+ mfmsr r5
+ oris r5,r5,MSR_SPE@h
+ mtmsr r5 /* enable use of SPE now */
+ isync
+/*
+ * For SMP, we don't do lazy SPE switching because it just gets too
+ * horrendously complex, especially when a task switches from one CPU
+ * to another. Instead we call giveup_spe in switch_to.
+ */
+#ifndef CONFIG_SMP
+ lis r3,last_task_used_spe@ha
+ lwz r4,last_task_used_spe@l(r3)
+ cmpi 0,r4,0
+ beq 1f
+ addi r4,r4,THREAD /* want THREAD of last_task_used_spe */
+ SAVE_32EVRS(0,r10,r4)
+ evxor evr10, evr10, evr10 /* clear out evr10 */
+ evmwumiaa evr10, evr10, evr10 /* evr10 <- ACC = 0 * 0 + ACC */
+ li r5,THREAD_ACC
+ evstddx evr10, r4, r5 /* save off accumulator */
+ lwz r5,PT_REGS(r4)
+ lwz r4,_MSR-STACK_FRAME_OVERHEAD(r5)
+ lis r10,MSR_SPE@h
+ andc r4,r4,r10 /* disable SPE for previous task */
+ stw r4,_MSR-STACK_FRAME_OVERHEAD(r5)
+1:
+#endif /* CONFIG_SMP */
+ /* enable use of SPE after return */
+ oris r9,r9,MSR_SPE@h
+ mfspr r5,SPRN_SPRG3 /* current task's THREAD (phys) */
+ li r4,1
+ li r10,THREAD_ACC
+ stw r4,THREAD_USED_SPE(r5)
+ evlddx evr4,r10,r5
+ evmra evr4,evr4
+ REST_32EVRS(0,r10,r5)
+#ifndef CONFIG_SMP
+ subi r4,r5,THREAD
+ stw r4,last_task_used_spe@l(r3)
+#endif /* CONFIG_SMP */
+ /* restore registers and return */
+2: REST_4GPRS(3, r11)
+ lwz r10,_CCR(r11)
+ REST_GPR(1, r11)
+ mtcr r10
+ lwz r10,_LINK(r11)
+ mtlr r10
+ REST_GPR(10, r11)
+ mtspr SPRN_SRR1,r9
+ mtspr SPRN_SRR0,r12
+ REST_GPR(9, r11)
+ REST_GPR(12, r11)
+ lwz r11,GPR11(r11)
+ SYNC
+ rfi
+
+/*
+ * SPE unavailable trap from kernel - print a message, but let
+ * the task use SPE in the kernel until it returns to user mode.
+ */
+KernelSPE:
+ lwz r3,_MSR(r1)
+ oris r3,r3,MSR_SPE@h
+ stw r3,_MSR(r1) /* enable use of SPE after return */
+ lis r3,87f@h
+ ori r3,r3,87f@l
+ mr r4,r2 /* current */
+ lwz r5,_NIP(r1)
+ bl printk
+ b ret_from_except
+87: .string "SPE used in kernel (task=%p, pc=%x) \n"
+ .align 4,0
+
+#endif /* CONFIG_SPE */
+
+/*
+ * Global functions
+ */
+
+/*
+ * extern void loadcam_entry(unsigned int index)
+ *
+ * Load TLBCAM[index] entry in to the L2 CAM MMU
+ */
+_GLOBAL(loadcam_entry)
+ lis r4,TLBCAM@ha
+ addi r4,r4,TLBCAM@l
+ mulli r5,r3,20
+ add r3,r5,r4
+ lwz r4,0(r3)
+ mtspr SPRN_MAS0,r4
+ lwz r4,4(r3)
+ mtspr SPRN_MAS1,r4
+ lwz r4,8(r3)
+ mtspr SPRN_MAS2,r4
+ lwz r4,12(r3)
+ mtspr SPRN_MAS3,r4
+ tlbwe
+ isync
+ blr
+
+/*
+ * extern void giveup_altivec(struct task_struct *prev)
+ *
+ * The e500 core does not have an AltiVec unit.
+ */
+_GLOBAL(giveup_altivec)
+ blr
+
+#ifdef CONFIG_SPE
+/*
+ * extern void giveup_spe(struct task_struct *prev)
+ *
+ */
+_GLOBAL(giveup_spe)
+ mfmsr r5
+ oris r5,r5,MSR_SPE@h
+ SYNC
+ mtmsr r5 /* enable use of SPE now */
+ isync
+ cmpi 0,r3,0
+ beqlr- /* if no previous owner, done */
+ addi r3,r3,THREAD /* want THREAD of task */
+ lwz r5,PT_REGS(r3)
+ cmpi 0,r5,0
+ SAVE_32EVRS(0, r4, r3)
+ evxor evr6, evr6, evr6 /* clear out evr6 */
+ evmwumiaa evr6, evr6, evr6 /* evr6 <- ACC = 0 * 0 + ACC */
+ li r4,THREAD_ACC
+ evstddx evr6, r4, r3 /* save off accumulator */
+ mfspr r6,SPRN_SPEFSCR
+ stw r6,THREAD_SPEFSCR(r3) /* save spefscr register value */
+ beq 1f
+ lwz r4,_MSR-STACK_FRAME_OVERHEAD(r5)
+ lis r3,MSR_SPE@h
+ andc r4,r4,r3 /* disable SPE for previous task */
+ stw r4,_MSR-STACK_FRAME_OVERHEAD(r5)
+1:
+#ifndef CONFIG_SMP
+ li r5,0
+ lis r4,last_task_used_spe@ha
+ stw r5,last_task_used_spe@l(r4)
+#endif /* CONFIG_SMP */
+ blr
+#endif /* CONFIG_SPE */
+
+/*
+ * extern void giveup_fpu(struct task_struct *prev)
+ *
+ * Not all FSL Book-E cores have an FPU
+ */
+#ifndef CONFIG_PPC_FPU
+_GLOBAL(giveup_fpu)
+ blr
+#endif
+
+/*
+ * extern void abort(void)
+ *
+ * At present, this routine just applies a system reset.
+ */
+_GLOBAL(abort)
+ li r13,0
+ mtspr SPRN_DBCR0,r13 /* disable all debug events */
+ mfmsr r13
+ ori r13,r13,MSR_DE@l /* Enable Debug Events */
+ mtmsr r13
+ mfspr r13,SPRN_DBCR0
+ lis r13,(DBCR0_IDM|DBCR0_RST_CHIP)@h
+ mtspr SPRN_DBCR0,r13
+
+_GLOBAL(set_context)
+
+#ifdef CONFIG_BDI_SWITCH
+ /* Context switch the PTE pointer for the Abatron BDI2000.
+ * The PGDIR is the second parameter.
+ */
+ lis r5, abatron_pteptrs@h
+ ori r5, r5, abatron_pteptrs@l
+ stw r4, 0x4(r5)
+#endif
+ mtspr SPRN_PID,r3
+ isync /* Force context change */
+ blr
+
+/*
+ * We put a few things here that have to be page-aligned. This stuff
+ * goes at the beginning of the data segment, which is page-aligned.
+ */
+ .data
+ .align 12
+ .globl sdata
+sdata:
+ .globl empty_zero_page
+empty_zero_page:
+ .space 4096
+ .globl swapper_pg_dir
+swapper_pg_dir:
+ .space 4096
+
+/* Reserved 4k for the critical exception stack & 4k for the machine
+ * check stack per CPU for kernel mode exceptions */
+ .section .bss
+ .align 12
+exception_stack_bottom:
+ .space BOOKE_EXCEPTION_STACK_SIZE * NR_CPUS
+ .globl exception_stack_top
+exception_stack_top:
+
+/*
+ * This space gets a copy of optional info passed to us by the bootstrap
+ * which is used to pass parameters into the kernel like root=/dev/sda1, etc.
+ */
+ .globl cmd_line
+cmd_line:
+ .space 512
+
+/*
+ * Room for two PTE pointers, usually the kernel and current user pointers
+ * to their respective root page table.
+ */
+abatron_pteptrs:
+ .space 8
diff --git a/arch/powerpc/kernel/idle_6xx.S b/arch/powerpc/kernel/idle_6xx.S
new file mode 100644
index 000000000000..444fdcc769f1
--- /dev/null
+++ b/arch/powerpc/kernel/idle_6xx.S
@@ -0,0 +1,233 @@
+/*
+ * This file contains the power_save function for 6xx & 7xxx CPUs
+ * rewritten in assembler
+ *
+ * Warning ! This code assumes that if your machine has a 750fx
+ * it will have PLL 1 set to low speed mode (used during NAP/DOZE).
+ * if this is not the case some additional changes will have to
+ * be done to check a runtime var (a bit like powersave-nap)
+ *
+ * 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/config.h>
+#include <linux/threads.h>
+#include <asm/reg.h>
+#include <asm/page.h>
+#include <asm/cputable.h>
+#include <asm/thread_info.h>
+#include <asm/ppc_asm.h>
+#include <asm/asm-offsets.h>
+
+#undef DEBUG
+
+ .text
+
+/*
+ * Init idle, called at early CPU setup time from head.S for each CPU
+ * Make sure no rest of NAP mode remains in HID0, save default
+ * values for some CPU specific registers. Called with r24
+ * containing CPU number and r3 reloc offset
+ */
+_GLOBAL(init_idle_6xx)
+BEGIN_FTR_SECTION
+ mfspr r4,SPRN_HID0
+ rlwinm r4,r4,0,10,8 /* Clear NAP */
+ mtspr SPRN_HID0, r4
+ b 1f
+END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP)
+ blr
+1:
+ slwi r5,r24,2
+ add r5,r5,r3
+BEGIN_FTR_SECTION
+ mfspr r4,SPRN_MSSCR0
+ addis r6,r5, nap_save_msscr0@ha
+ stw r4,nap_save_msscr0@l(r6)
+END_FTR_SECTION_IFSET(CPU_FTR_NAP_DISABLE_L2_PR)
+BEGIN_FTR_SECTION
+ mfspr r4,SPRN_HID1
+ addis r6,r5,nap_save_hid1@ha
+ stw r4,nap_save_hid1@l(r6)
+END_FTR_SECTION_IFSET(CPU_FTR_DUAL_PLL_750FX)
+ blr
+
+/*
+ * Here is the power_save_6xx function. This could eventually be
+ * split into several functions & changing the function pointer
+ * depending on the various features.
+ */
+_GLOBAL(ppc6xx_idle)
+ /* Check if we can nap or doze, put HID0 mask in r3
+ */
+ lis r3, 0
+BEGIN_FTR_SECTION
+ lis r3,HID0_DOZE@h
+END_FTR_SECTION_IFSET(CPU_FTR_CAN_DOZE)
+BEGIN_FTR_SECTION
+ /* We must dynamically check for the NAP feature as it
+ * can be cleared by CPU init after the fixups are done
+ */
+ lis r4,cur_cpu_spec@ha
+ lwz r4,cur_cpu_spec@l(r4)
+ lwz r4,CPU_SPEC_FEATURES(r4)
+ andi. r0,r4,CPU_FTR_CAN_NAP
+ beq 1f
+ /* Now check if user or arch enabled NAP mode */
+ lis r4,powersave_nap@ha
+ lwz r4,powersave_nap@l(r4)
+ cmpwi 0,r4,0
+ beq 1f
+ lis r3,HID0_NAP@h
+1:
+END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP)
+ cmpwi 0,r3,0
+ beqlr
+
+ /* Clear MSR:EE */
+ mfmsr r7
+ rlwinm r0,r7,0,17,15
+ mtmsr r0
+
+ /* Check current_thread_info()->flags */
+ rlwinm r4,r1,0,0,18
+ lwz r4,TI_FLAGS(r4)
+ andi. r0,r4,_TIF_NEED_RESCHED
+ beq 1f
+ mtmsr r7 /* out of line this ? */
+ blr
+1:
+ /* Some pre-nap cleanups needed on some CPUs */
+ andis. r0,r3,HID0_NAP@h
+ beq 2f
+BEGIN_FTR_SECTION
+ /* Disable L2 prefetch on some 745x and try to ensure
+ * L2 prefetch engines are idle. As explained by errata
+ * text, we can't be sure they are, we just hope very hard
+ * that well be enough (sic !). At least I noticed Apple
+ * doesn't even bother doing the dcbf's here...
+ */
+ mfspr r4,SPRN_MSSCR0
+ rlwinm r4,r4,0,0,29
+ sync
+ mtspr SPRN_MSSCR0,r4
+ sync
+ isync
+ lis r4,KERNELBASE@h
+ dcbf 0,r4
+ dcbf 0,r4
+ dcbf 0,r4
+ dcbf 0,r4
+END_FTR_SECTION_IFSET(CPU_FTR_NAP_DISABLE_L2_PR)
+#ifdef DEBUG
+ lis r6,nap_enter_count@ha
+ lwz r4,nap_enter_count@l(r6)
+ addi r4,r4,1
+ stw r4,nap_enter_count@l(r6)
+#endif
+2:
+BEGIN_FTR_SECTION
+ /* Go to low speed mode on some 750FX */
+ lis r4,powersave_lowspeed@ha
+ lwz r4,powersave_lowspeed@l(r4)
+ cmpwi 0,r4,0
+ beq 1f
+ mfspr r4,SPRN_HID1
+ oris r4,r4,0x0001
+ mtspr SPRN_HID1,r4
+1:
+END_FTR_SECTION_IFSET(CPU_FTR_DUAL_PLL_750FX)
+
+ /* Go to NAP or DOZE now */
+ mfspr r4,SPRN_HID0
+ lis r5,(HID0_NAP|HID0_SLEEP)@h
+BEGIN_FTR_SECTION
+ oris r5,r5,HID0_DOZE@h
+END_FTR_SECTION_IFSET(CPU_FTR_CAN_DOZE)
+ andc r4,r4,r5
+ or r4,r4,r3
+BEGIN_FTR_SECTION
+ oris r4,r4,HID0_DPM@h /* that should be done once for all */
+END_FTR_SECTION_IFCLR(CPU_FTR_NO_DPM)
+ mtspr SPRN_HID0,r4
+BEGIN_FTR_SECTION
+ DSSALL
+ sync
+END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
+ ori r7,r7,MSR_EE /* Could be ommited (already set) */
+ oris r7,r7,MSR_POW@h
+ sync
+ isync
+ mtmsr r7
+ isync
+ sync
+ blr
+
+/*
+ * Return from NAP/DOZE mode, restore some CPU specific registers,
+ * we are called with DR/IR still off and r2 containing physical
+ * address of current.
+ */
+_GLOBAL(power_save_6xx_restore)
+ mfspr r11,SPRN_HID0
+ rlwinm. r11,r11,0,10,8 /* Clear NAP & copy NAP bit !state to cr1 EQ */
+ cror 4*cr1+eq,4*cr0+eq,4*cr0+eq
+BEGIN_FTR_SECTION
+ rlwinm r11,r11,0,9,7 /* Clear DOZE */
+END_FTR_SECTION_IFSET(CPU_FTR_CAN_DOZE)
+ mtspr SPRN_HID0, r11
+
+#ifdef DEBUG
+ beq cr1,1f
+ lis r11,(nap_return_count-KERNELBASE)@ha
+ lwz r9,nap_return_count@l(r11)
+ addi r9,r9,1
+ stw r9,nap_return_count@l(r11)
+1:
+#endif
+
+ rlwinm r9,r1,0,0,18
+ tophys(r9,r9)
+ lwz r11,TI_CPU(r9)
+ slwi r11,r11,2
+ /* Todo make sure all these are in the same page
+ * and load r22 (@ha part + CPU offset) only once
+ */
+BEGIN_FTR_SECTION
+ beq cr1,1f
+ addis r9,r11,(nap_save_msscr0-KERNELBASE)@ha
+ lwz r9,nap_save_msscr0@l(r9)
+ mtspr SPRN_MSSCR0, r9
+ sync
+ isync
+1:
+END_FTR_SECTION_IFSET(CPU_FTR_NAP_DISABLE_L2_PR)
+BEGIN_FTR_SECTION
+ addis r9,r11,(nap_save_hid1-KERNELBASE)@ha
+ lwz r9,nap_save_hid1@l(r9)
+ mtspr SPRN_HID1, r9
+END_FTR_SECTION_IFSET(CPU_FTR_DUAL_PLL_750FX)
+ b transfer_to_handler_cont
+
+ .data
+
+_GLOBAL(nap_save_msscr0)
+ .space 4*NR_CPUS
+
+_GLOBAL(nap_save_hid1)
+ .space 4*NR_CPUS
+
+_GLOBAL(powersave_nap)
+ .long 0
+_GLOBAL(powersave_lowspeed)
+ .long 0
+
+#ifdef DEBUG
+_GLOBAL(nap_enter_count)
+ .space 4
+_GLOBAL(nap_return_count)
+ .space 4
+#endif
diff --git a/arch/ppc64/kernel/idle_power4.S b/arch/powerpc/kernel/idle_power4.S
index ca02afe2a795..1494e2f177f7 100644
--- a/arch/ppc64/kernel/idle_power4.S
+++ b/arch/powerpc/kernel/idle_power4.S
@@ -39,13 +39,13 @@ END_FTR_SECTION_IFCLR(CPU_FTR_CAN_NAP)
* can be cleared by CPU init after the fixups are done
*/
LOADBASE(r3,cur_cpu_spec)
- ld r4,cur_cpu_spec@l(r3)
+ ld r4,OFF(cur_cpu_spec)(r3)
ld r4,CPU_SPEC_FEATURES(r4)
andi. r0,r4,CPU_FTR_CAN_NAP
beqlr
/* Now check if user or arch enabled NAP mode */
LOADBASE(r3,powersave_nap)
- lwz r4,powersave_nap@l(r3)
+ lwz r4,OFF(powersave_nap)(r3)
cmpwi 0,r4,0
beqlr
@@ -63,8 +63,8 @@ END_FTR_SECTION_IFCLR(CPU_FTR_CAN_NAP)
beq 1f
mtmsrd r7 /* out of line this ? */
blr
-1:
- /* Go to NAP now */
+1:
+ /* Go to NAP now */
BEGIN_FTR_SECTION
DSSALL
sync
@@ -76,4 +76,3 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
isync
sync
blr
-
diff --git a/arch/ppc64/kernel/init_task.c b/arch/powerpc/kernel/init_task.c
index 941043ae040f..941043ae040f 100644
--- a/arch/ppc64/kernel/init_task.c
+++ b/arch/powerpc/kernel/init_task.c
diff --git a/arch/ppc64/kernel/ioctl32.c b/arch/powerpc/kernel/ioctl32.c
index a8005db23ec5..3fa6a93adbd0 100644
--- a/arch/ppc64/kernel/ioctl32.c
+++ b/arch/powerpc/kernel/ioctl32.c
@@ -1,6 +1,6 @@
-/*
+/*
* ioctl32.c: Conversion between 32bit and 64bit native ioctls.
- *
+ *
* Based on sparc64 ioctl32.c by:
*
* Copyright (C) 1997-2000 Jakub Jelinek (jakub@redhat.com)
@@ -39,9 +39,7 @@ IOCTL_TABLE_START
#include <linux/compat_ioctl.h>
#define DECLARES
#include "compat_ioctl.c"
-COMPATIBLE_IOCTL(TIOCSTART)
-COMPATIBLE_IOCTL(TIOCSTOP)
-COMPATIBLE_IOCTL(TIOCSLTC)
+
/* Little p (/dev/rtc, /dev/envctrl, etc.) */
COMPATIBLE_IOCTL(_IOR('p', 20, int[7])) /* RTCGET */
COMPATIBLE_IOCTL(_IOW('p', 21, int[7])) /* RTCSET */
diff --git a/arch/ppc64/kernel/irq.c b/arch/powerpc/kernel/irq.c
index f41afe545045..4b7940693f3d 100644
--- a/arch/ppc64/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -5,12 +5,12 @@
* Copyright (C) 1992 Linus Torvalds
* Adapted from arch/i386 by Gary Thomas
* Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
- * Updated and modified by Cort Dougan (cort@cs.nmt.edu)
- * Copyright (C) 1996 Cort Dougan
+ * Updated and modified by Cort Dougan <cort@fsmlabs.com>
+ * Copyright (C) 1996-2001 Cort Dougan
* Adapted for Power Macintosh by Paul Mackerras
* Copyright (C) 1996 Paul Mackerras (paulus@cs.anu.edu.au)
* Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk).
- *
+ *
* 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
@@ -21,6 +21,14 @@
* instead of just grabbing them. Thus setups with different IRQ numbers
* shouldn't result in any weird surprises, and installing new handlers
* should be easier.
+ *
+ * The MPC8xx has an interrupt mask in the SIU. If a bit is set, the
+ * interrupt is _enabled_. As expected, IRQ0 is bit 0 in the 32-bit
+ * mask register (of which only 16 are defined), hence the weird shifting
+ * and complement of the cached_irq_mask. I want to be able to stuff
+ * this right into the SIU SMASK register.
+ * Many of the prep/chrp functions are conditional compiled on CONFIG_8xx
+ * to reduce code space and undefined function references.
*/
#include <linux/errno.h>
@@ -29,6 +37,7 @@
#include <linux/kernel_stat.h>
#include <linux/signal.h>
#include <linux/sched.h>
+#include <linux/ptrace.h>
#include <linux/ioport.h>
#include <linux/interrupt.h>
#include <linux/timex.h>
@@ -40,9 +49,13 @@
#include <linux/irq.h>
#include <linux/proc_fs.h>
#include <linux/random.h>
-#include <linux/kallsyms.h>
+#include <linux/seq_file.h>
+#include <linux/cpumask.h>
#include <linux/profile.h>
#include <linux/bitops.h>
+#ifdef CONFIG_PPC64
+#include <linux/kallsyms.h>
+#endif
#include <asm/uaccess.h>
#include <asm/system.h>
@@ -52,35 +65,54 @@
#include <asm/cache.h>
#include <asm/prom.h>
#include <asm/ptrace.h>
-#include <asm/iSeries/ItLpQueue.h>
#include <asm/machdep.h>
+#ifdef CONFIG_PPC64
+#include <asm/iseries/it_lp_queue.h>
#include <asm/paca.h>
+#endif
-#ifdef CONFIG_SMP
-extern void iSeries_smp_message_recv( struct pt_regs * );
+static int ppc_spurious_interrupts;
+
+#if defined(CONFIG_PPC_ISERIES) && defined(CONFIG_SMP)
+extern void iSeries_smp_message_recv(struct pt_regs *);
+#endif
+
+#ifdef CONFIG_PPC32
+#define NR_MASK_WORDS ((NR_IRQS + 31) / 32)
+
+unsigned long ppc_cached_irq_mask[NR_MASK_WORDS];
+atomic_t ppc_n_lost_interrupts;
+
+#ifdef CONFIG_TAU_INT
+extern int tau_initialized;
+extern int tau_interrupts(int);
#endif
-extern irq_desc_t irq_desc[NR_IRQS];
+#if defined(CONFIG_SMP) && !defined(CONFIG_PPC_MERGE)
+extern atomic_t ipi_recv;
+extern atomic_t ipi_sent;
+#endif
+#endif /* CONFIG_PPC32 */
+
+#ifdef CONFIG_PPC64
EXPORT_SYMBOL(irq_desc);
int distribute_irqs = 1;
int __irq_offset_value;
-int ppc_spurious_interrupts;
u64 ppc64_interrupt_controller;
+#endif /* CONFIG_PPC64 */
int show_interrupts(struct seq_file *p, void *v)
{
- int i = *(loff_t *) v, j;
- struct irqaction * action;
+ int i = *(loff_t *)v, j;
+ struct irqaction *action;
irq_desc_t *desc;
unsigned long flags;
if (i == 0) {
- seq_printf(p, " ");
- for (j=0; j<NR_CPUS; j++) {
- if (cpu_online(j))
- seq_printf(p, "CPU%d ",j);
- }
+ seq_puts(p, " ");
+ for_each_online_cpu(j)
+ seq_printf(p, "CPU%d ", j);
seq_putc(p, '\n');
}
@@ -92,26 +124,41 @@ int show_interrupts(struct seq_file *p, void *v)
goto skip;
seq_printf(p, "%3d: ", i);
#ifdef CONFIG_SMP
- for (j = 0; j < NR_CPUS; j++) {
- if (cpu_online(j))
- seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
- }
+ for_each_online_cpu(j)
+ seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
#else
seq_printf(p, "%10u ", kstat_irqs(i));
#endif /* CONFIG_SMP */
if (desc->handler)
- seq_printf(p, " %s ", desc->handler->typename );
+ seq_printf(p, " %s ", desc->handler->typename);
else
- seq_printf(p, " None ");
+ seq_puts(p, " None ");
seq_printf(p, "%s", (desc->status & IRQ_LEVEL) ? "Level " : "Edge ");
- seq_printf(p, " %s",action->name);
- for (action=action->next; action; action = action->next)
+ seq_printf(p, " %s", action->name);
+ for (action = action->next; action; action = action->next)
seq_printf(p, ", %s", action->name);
seq_putc(p, '\n');
skip:
spin_unlock_irqrestore(&desc->lock, flags);
- } else if (i == NR_IRQS)
+ } else if (i == NR_IRQS) {
+#ifdef CONFIG_PPC32
+#ifdef CONFIG_TAU_INT
+ if (tau_initialized){
+ seq_puts(p, "TAU: ");
+ for (j = 0; j < NR_CPUS; j++)
+ if (cpu_online(j))
+ seq_printf(p, "%10u ", tau_interrupts(j));
+ seq_puts(p, " PowerPC Thermal Assist (cpu temp)\n");
+ }
+#endif
+#if defined(CONFIG_SMP) && !defined(CONFIG_PPC_MERGE)
+ /* should this be per processor send/receive? */
+ seq_printf(p, "IPI (recv/sent): %10u/%u\n",
+ atomic_read(&ipi_recv), atomic_read(&ipi_sent));
+#endif
+#endif /* CONFIG_PPC32 */
seq_printf(p, "BAD: %10u\n", ppc_spurious_interrupts);
+ }
return 0;
}
@@ -144,126 +191,6 @@ void fixup_irqs(cpumask_t map)
}
#endif
-extern int noirqdebug;
-
-/*
- * Eventually, this should take an array of interrupts and an array size
- * so it can dispatch multiple interrupts.
- */
-void ppc_irq_dispatch_handler(struct pt_regs *regs, int irq)
-{
- int status;
- struct irqaction *action;
- int cpu = smp_processor_id();
- irq_desc_t *desc = get_irq_desc(irq);
- irqreturn_t action_ret;
-#ifdef CONFIG_IRQSTACKS
- struct thread_info *curtp, *irqtp;
-#endif
-
- kstat_cpu(cpu).irqs[irq]++;
-
- if (desc->status & IRQ_PER_CPU) {
- /* no locking required for CPU-local interrupts: */
- ack_irq(irq);
- action_ret = handle_IRQ_event(irq, regs, desc->action);
- desc->handler->end(irq);
- return;
- }
-
- spin_lock(&desc->lock);
- ack_irq(irq);
- /*
- REPLAY is when Linux resends an IRQ that was dropped earlier
- WAITING is used by probe to mark irqs that are being tested
- */
- status = desc->status & ~(IRQ_REPLAY | IRQ_WAITING);
- status |= IRQ_PENDING; /* we _want_ to handle it */
-
- /*
- * If the IRQ is disabled for whatever reason, we cannot
- * use the action we have.
- */
- action = NULL;
- if (likely(!(status & (IRQ_DISABLED | IRQ_INPROGRESS)))) {
- action = desc->action;
- if (!action || !action->handler) {
- ppc_spurious_interrupts++;
- printk(KERN_DEBUG "Unhandled interrupt %x, disabled\n", irq);
- /* We can't call disable_irq here, it would deadlock */
- if (!desc->depth)
- desc->depth = 1;
- desc->status |= IRQ_DISABLED;
- /* This is not a real spurrious interrupt, we
- * have to eoi it, so we jump to out
- */
- mask_irq(irq);
- goto out;
- }
- status &= ~IRQ_PENDING; /* we commit to handling */
- status |= IRQ_INPROGRESS; /* we are handling it */
- }
- desc->status = status;
-
- /*
- * If there is no IRQ handler or it was disabled, exit early.
- Since we set PENDING, if another processor is handling
- a different instance of this same irq, the other processor
- will take care of it.
- */
- if (unlikely(!action))
- goto out;
-
- /*
- * Edge triggered interrupts need to remember
- * pending events.
- * This applies to any hw interrupts that allow a second
- * instance of the same irq to arrive while we are in do_IRQ
- * or in the handler. But the code here only handles the _second_
- * instance of the irq, not the third or fourth. So it is mostly
- * useful for irq hardware that does not mask cleanly in an
- * SMP environment.
- */
- for (;;) {
- spin_unlock(&desc->lock);
-
-#ifdef CONFIG_IRQSTACKS
- /* Switch to the irq stack to handle this */
- curtp = current_thread_info();
- irqtp = hardirq_ctx[smp_processor_id()];
- if (curtp != irqtp) {
- irqtp->task = curtp->task;
- irqtp->flags = 0;
- action_ret = call_handle_IRQ_event(irq, regs, action, irqtp);
- irqtp->task = NULL;
- if (irqtp->flags)
- set_bits(irqtp->flags, &curtp->flags);
- } else
-#endif
- action_ret = handle_IRQ_event(irq, regs, action);
-
- spin_lock(&desc->lock);
- if (!noirqdebug)
- note_interrupt(irq, desc, action_ret, regs);
- if (likely(!(desc->status & IRQ_PENDING)))
- break;
- desc->status &= ~IRQ_PENDING;
- }
-out:
- desc->status &= ~IRQ_INPROGRESS;
- /*
- * The ->end() handler has to deal with interrupts which got
- * disabled while the handler was running.
- */
- if (desc->handler) {
- if (desc->handler->end)
- desc->handler->end(irq);
- else if (desc->handler->enable)
- desc->handler->enable(irq);
- }
- spin_unlock(&desc->lock);
-}
-
#ifdef CONFIG_PPC_ISERIES
void do_IRQ(struct pt_regs *regs)
{
@@ -310,8 +237,11 @@ void do_IRQ(struct pt_regs *regs)
void do_IRQ(struct pt_regs *regs)
{
int irq;
+#ifdef CONFIG_IRQSTACKS
+ struct thread_info *curtp, *irqtp;
+#endif
- irq_enter();
+ irq_enter();
#ifdef CONFIG_DEBUG_STACKOVERFLOW
/* Debugging check for stack overflow: is there less than 2KB free? */
@@ -328,20 +258,44 @@ void do_IRQ(struct pt_regs *regs)
}
#endif
+ /*
+ * Every platform is required to implement ppc_md.get_irq.
+ * This function will either return an irq number or -1 to
+ * indicate there are no more pending.
+ * The value -2 is for buggy hardware and means that this IRQ
+ * has already been handled. -- Tom
+ */
irq = ppc_md.get_irq(regs);
- if (irq >= 0)
- ppc_irq_dispatch_handler(regs, irq);
- else
- /* That's not SMP safe ... but who cares ? */
- ppc_spurious_interrupts++;
-
- irq_exit();
+ if (irq >= 0) {
+#ifdef CONFIG_IRQSTACKS
+ /* Switch to the irq stack to handle this */
+ curtp = current_thread_info();
+ irqtp = hardirq_ctx[smp_processor_id()];
+ if (curtp != irqtp) {
+ irqtp->task = curtp->task;
+ irqtp->flags = 0;
+ call___do_IRQ(irq, regs, irqtp);
+ irqtp->task = NULL;
+ if (irqtp->flags)
+ set_bits(irqtp->flags, &curtp->flags);
+ } else
+#endif
+ __do_IRQ(irq, regs);
+ } else
+#ifdef CONFIG_PPC32
+ if (irq != -2)
+#endif
+ /* That's not SMP safe ... but who cares ? */
+ ppc_spurious_interrupts++;
+ irq_exit();
}
+
#endif /* CONFIG_PPC_ISERIES */
void __init init_IRQ(void)
{
+#ifdef CONFIG_PPC64
static int once = 0;
if (once)
@@ -349,10 +303,14 @@ void __init init_IRQ(void)
once++;
+#endif
ppc_md.init_IRQ();
+#ifdef CONFIG_PPC64
irq_ctx_init();
+#endif
}
+#ifdef CONFIG_PPC64
#ifndef CONFIG_PPC_ISERIES
/*
* Virtual IRQ mapping code, used on systems with XICS interrupt controllers.
@@ -392,7 +350,7 @@ int virt_irq_create_mapping(unsigned int real_irq)
if (ppc64_interrupt_controller == IC_OPEN_PIC)
return real_irq; /* no mapping for openpic (for now) */
- if (ppc64_interrupt_controller == IC_BPA_IIC)
+ if (ppc64_interrupt_controller == IC_CELL_PIC)
return real_irq; /* no mapping for iic either */
/* don't map interrupts < MIN_VIRT_IRQ */
@@ -517,3 +475,4 @@ static int __init setup_noirqdistrib(char *str)
}
__setup("noirqdistrib", setup_noirqdistrib);
+#endif /* CONFIG_PPC64 */
diff --git a/arch/ppc64/kernel/lparcfg.c b/arch/powerpc/kernel/lparcfg.c
index cae19bbd5acd..5e954fae031f 100644
--- a/arch/ppc64/kernel/lparcfg.c
+++ b/arch/powerpc/kernel/lparcfg.c
@@ -26,15 +26,16 @@
#include <linux/init.h>
#include <linux/seq_file.h>
#include <asm/uaccess.h>
-#include <asm/iSeries/HvLpConfig.h>
+#include <asm/iseries/hv_lp_config.h>
#include <asm/lppaca.h>
#include <asm/hvcall.h>
#include <asm/firmware.h>
#include <asm/rtas.h>
#include <asm/system.h>
#include <asm/time.h>
-#include <asm/iSeries/ItExtVpdPanel.h>
+#include <asm/iseries/it_exp_vpd_panel.h>
#include <asm/prom.h>
+#include <asm/systemcfg.h>
#define MODULE_VERS "1.6"
#define MODULE_NAME "lparcfg"
@@ -96,7 +97,7 @@ static unsigned long get_purr(void)
#define lparcfg_write NULL
-/*
+/*
* Methods used to fetch LPAR data when running on an iSeries platform.
*/
static int lparcfg_data(struct seq_file *m, void *v)
@@ -168,7 +169,7 @@ static int lparcfg_data(struct seq_file *m, void *v)
#endif /* CONFIG_PPC_ISERIES */
#ifdef CONFIG_PPC_PSERIES
-/*
+/*
* Methods used to fetch LPAR data when running on a pSeries platform.
*/
@@ -177,7 +178,7 @@ static int lparcfg_data(struct seq_file *m, void *v)
* entitled_capacity,unallocated_capacity,
* aggregation, resource_capability).
*
- * R4 = Entitled Processor Capacity Percentage.
+ * R4 = Entitled Processor Capacity Percentage.
* R5 = Unallocated Processor Capacity Percentage.
* R6 (AABBCCDDEEFFGGHH).
* XXXX - reserved (0)
@@ -190,7 +191,7 @@ static int lparcfg_data(struct seq_file *m, void *v)
* XX - variable processor Capacity Weight
* XX - Unallocated Variable Processor Capacity Weight.
* XXXX - Active processors in Physical Processor Pool.
- * XXXX - Processors active on platform.
+ * XXXX - Processors active on platform.
*/
static unsigned int h_get_ppp(unsigned long *entitled,
unsigned long *unallocated,
@@ -273,7 +274,7 @@ static void parse_system_parameter_string(struct seq_file *m)
if (!workbuffer) {
printk(KERN_ERR "%s %s kmalloc failure at line %d \n",
__FILE__, __FUNCTION__, __LINE__);
- kfree(local_buffer);
+ kfree(local_buffer);
return;
}
#ifdef LPARCFG_DEBUG
@@ -371,7 +372,7 @@ static int lparcfg_data(struct seq_file *m, void *v)
lrdrp = (int *)get_property(rtas_node, "ibm,lrdr-capacity", NULL);
if (lrdrp == NULL) {
- partition_potential_processors = systemcfg->processorCount;
+ partition_potential_processors = _systemcfg->processorCount;
} else {
partition_potential_processors = *(lrdrp + 4);
}
@@ -599,9 +600,7 @@ int __init lparcfg_init(void)
void __exit lparcfg_cleanup(void)
{
if (proc_ppc64_lparcfg) {
- if (proc_ppc64_lparcfg->data) {
- kfree(proc_ppc64_lparcfg->data);
- }
+ kfree(proc_ppc64_lparcfg->data);
remove_proc_entry("lparcfg", proc_ppc64_lparcfg->parent);
}
}
diff --git a/arch/ppc64/kernel/lparmap.c b/arch/powerpc/kernel/lparmap.c
index b81de286df5e..5a05a797485f 100644
--- a/arch/ppc64/kernel/lparmap.c
+++ b/arch/powerpc/kernel/lparmap.c
@@ -8,7 +8,7 @@
*/
#include <asm/mmu.h>
#include <asm/page.h>
-#include <asm/iSeries/LparMap.h>
+#include <asm/iseries/lpar_map.h>
const struct LparMap __attribute__((__section__(".text"))) xLparMap = {
.xNumberEsids = HvEsidsToMap,
@@ -25,7 +25,7 @@ const struct LparMap __attribute__((__section__(".text"))) xLparMap = {
.xRanges = {
{ .xPages = HvPagesToMap,
.xOffset = 0,
- .xVPN = KERNEL_VSID(KERNELBASE) << (SID_SHIFT - PAGE_SHIFT),
+ .xVPN = KERNEL_VSID(KERNELBASE) << (SID_SHIFT - HW_PAGE_SHIFT),
},
},
};
diff --git a/arch/powerpc/kernel/misc_32.S b/arch/powerpc/kernel/misc_32.S
new file mode 100644
index 000000000000..f6d84a75ed26
--- /dev/null
+++ b/arch/powerpc/kernel/misc_32.S
@@ -0,0 +1,1016 @@
+/*
+ * This file contains miscellaneous low-level functions.
+ * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
+ *
+ * Largely rewritten by Cort Dougan (cort@cs.nmt.edu)
+ * and Paul Mackerras.
+ *
+ * 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/config.h>
+#include <linux/sys.h>
+#include <asm/unistd.h>
+#include <asm/errno.h>
+#include <asm/reg.h>
+#include <asm/page.h>
+#include <asm/cache.h>
+#include <asm/cputable.h>
+#include <asm/mmu.h>
+#include <asm/ppc_asm.h>
+#include <asm/thread_info.h>
+#include <asm/asm-offsets.h>
+
+ .text
+
+ .align 5
+_GLOBAL(__delay)
+ cmpwi 0,r3,0
+ mtctr r3
+ beqlr
+1: bdnz 1b
+ blr
+
+/*
+ * This returns the high 64 bits of the product of two 64-bit numbers.
+ */
+_GLOBAL(mulhdu)
+ cmpwi r6,0
+ cmpwi cr1,r3,0
+ mr r10,r4
+ mulhwu r4,r4,r5
+ beq 1f
+ mulhwu r0,r10,r6
+ mullw r7,r10,r5
+ addc r7,r0,r7
+ addze r4,r4
+1: beqlr cr1 /* all done if high part of A is 0 */
+ mr r10,r3
+ mullw r9,r3,r5
+ mulhwu r3,r3,r5
+ beq 2f
+ mullw r0,r10,r6
+ mulhwu r8,r10,r6
+ addc r7,r0,r7
+ adde r4,r4,r8
+ addze r3,r3
+2: addc r4,r4,r9
+ addze r3,r3
+ blr
+
+/*
+ * Returns (address we're running at) - (address we were linked at)
+ * for use before the text and data are mapped to KERNELBASE.
+ */
+_GLOBAL(reloc_offset)
+ mflr r0
+ bl 1f
+1: mflr r3
+ LOADADDR(r4,1b)
+ subf r3,r4,r3
+ mtlr r0
+ blr
+
+/*
+ * add_reloc_offset(x) returns x + reloc_offset().
+ */
+_GLOBAL(add_reloc_offset)
+ mflr r0
+ bl 1f
+1: mflr r5
+ LOADADDR(r4,1b)
+ subf r5,r4,r5
+ add r3,r3,r5
+ mtlr r0
+ blr
+
+/*
+ * sub_reloc_offset(x) returns x - reloc_offset().
+ */
+_GLOBAL(sub_reloc_offset)
+ mflr r0
+ bl 1f
+1: mflr r5
+ lis r4,1b@ha
+ addi r4,r4,1b@l
+ subf r5,r4,r5
+ subf r3,r5,r3
+ mtlr r0
+ blr
+
+/*
+ * reloc_got2 runs through the .got2 section adding an offset
+ * to each entry.
+ */
+_GLOBAL(reloc_got2)
+ mflr r11
+ lis r7,__got2_start@ha
+ addi r7,r7,__got2_start@l
+ lis r8,__got2_end@ha
+ addi r8,r8,__got2_end@l
+ subf r8,r7,r8
+ srwi. r8,r8,2
+ beqlr
+ mtctr r8
+ bl 1f
+1: mflr r0
+ lis r4,1b@ha
+ addi r4,r4,1b@l
+ subf r0,r4,r0
+ add r7,r0,r7
+2: lwz r0,0(r7)
+ add r0,r0,r3
+ stw r0,0(r7)
+ addi r7,r7,4
+ bdnz 2b
+ mtlr r11
+ blr
+
+/*
+ * identify_cpu,
+ * called with r3 = data offset and r4 = CPU number
+ * doesn't change r3
+ */
+_GLOBAL(identify_cpu)
+ addis r8,r3,cpu_specs@ha
+ addi r8,r8,cpu_specs@l
+ mfpvr r7
+1:
+ lwz r5,CPU_SPEC_PVR_MASK(r8)
+ and r5,r5,r7
+ lwz r6,CPU_SPEC_PVR_VALUE(r8)
+ cmplw 0,r6,r5
+ beq 1f
+ addi r8,r8,CPU_SPEC_ENTRY_SIZE
+ b 1b
+1:
+ addis r6,r3,cur_cpu_spec@ha
+ addi r6,r6,cur_cpu_spec@l
+ sub r8,r8,r3
+ stw r8,0(r6)
+ blr
+
+/*
+ * do_cpu_ftr_fixups - goes through the list of CPU feature fixups
+ * and writes nop's over sections of code that don't apply for this cpu.
+ * r3 = data offset (not changed)
+ */
+_GLOBAL(do_cpu_ftr_fixups)
+ /* Get CPU 0 features */
+ addis r6,r3,cur_cpu_spec@ha
+ addi r6,r6,cur_cpu_spec@l
+ lwz r4,0(r6)
+ add r4,r4,r3
+ lwz r4,CPU_SPEC_FEATURES(r4)
+
+ /* Get the fixup table */
+ addis r6,r3,__start___ftr_fixup@ha
+ addi r6,r6,__start___ftr_fixup@l
+ addis r7,r3,__stop___ftr_fixup@ha
+ addi r7,r7,__stop___ftr_fixup@l
+
+ /* Do the fixup */
+1: cmplw 0,r6,r7
+ bgelr
+ addi r6,r6,16
+ lwz r8,-16(r6) /* mask */
+ and r8,r8,r4
+ lwz r9,-12(r6) /* value */
+ cmplw 0,r8,r9
+ beq 1b
+ lwz r8,-8(r6) /* section begin */
+ lwz r9,-4(r6) /* section end */
+ subf. r9,r8,r9
+ beq 1b
+ /* write nops over the section of code */
+ /* todo: if large section, add a branch at the start of it */
+ srwi r9,r9,2
+ mtctr r9
+ add r8,r8,r3
+ lis r0,0x60000000@h /* nop */
+3: stw r0,0(r8)
+ andi. r10,r4,CPU_FTR_SPLIT_ID_CACHE@l
+ beq 2f
+ dcbst 0,r8 /* suboptimal, but simpler */
+ sync
+ icbi 0,r8
+2: addi r8,r8,4
+ bdnz 3b
+ sync /* additional sync needed on g4 */
+ isync
+ b 1b
+
+/*
+ * call_setup_cpu - call the setup_cpu function for this cpu
+ * r3 = data offset, r24 = cpu number
+ *
+ * Setup function is called with:
+ * r3 = data offset
+ * r4 = ptr to CPU spec (relocated)
+ */
+_GLOBAL(call_setup_cpu)
+ addis r4,r3,cur_cpu_spec@ha
+ addi r4,r4,cur_cpu_spec@l
+ lwz r4,0(r4)
+ add r4,r4,r3
+ lwz r5,CPU_SPEC_SETUP(r4)
+ cmpi 0,r5,0
+ add r5,r5,r3
+ beqlr
+ mtctr r5
+ bctr
+
+#if defined(CONFIG_CPU_FREQ_PMAC) && defined(CONFIG_6xx)
+
+/* This gets called by via-pmu.c to switch the PLL selection
+ * on 750fx CPU. This function should really be moved to some
+ * other place (as most of the cpufreq code in via-pmu
+ */
+_GLOBAL(low_choose_750fx_pll)
+ /* Clear MSR:EE */
+ mfmsr r7
+ rlwinm r0,r7,0,17,15
+ mtmsr r0
+
+ /* If switching to PLL1, disable HID0:BTIC */
+ cmplwi cr0,r3,0
+ beq 1f
+ mfspr r5,SPRN_HID0
+ rlwinm r5,r5,0,27,25
+ sync
+ mtspr SPRN_HID0,r5
+ isync
+ sync
+
+1:
+ /* Calc new HID1 value */
+ mfspr r4,SPRN_HID1 /* Build a HID1:PS bit from parameter */
+ rlwinm r5,r3,16,15,15 /* Clear out HID1:PS from value read */
+ rlwinm r4,r4,0,16,14 /* Could have I used rlwimi here ? */
+ or r4,r4,r5
+ mtspr SPRN_HID1,r4
+
+ /* Store new HID1 image */
+ rlwinm r6,r1,0,0,18
+ lwz r6,TI_CPU(r6)
+ slwi r6,r6,2
+ addis r6,r6,nap_save_hid1@ha
+ stw r4,nap_save_hid1@l(r6)
+
+ /* If switching to PLL0, enable HID0:BTIC */
+ cmplwi cr0,r3,0
+ bne 1f
+ mfspr r5,SPRN_HID0
+ ori r5,r5,HID0_BTIC
+ sync
+ mtspr SPRN_HID0,r5
+ isync
+ sync
+
+1:
+ /* Return */
+ mtmsr r7
+ blr
+
+_GLOBAL(low_choose_7447a_dfs)
+ /* Clear MSR:EE */
+ mfmsr r7
+ rlwinm r0,r7,0,17,15
+ mtmsr r0
+
+ /* Calc new HID1 value */
+ mfspr r4,SPRN_HID1
+ insrwi r4,r3,1,9 /* insert parameter into bit 9 */
+ sync
+ mtspr SPRN_HID1,r4
+ sync
+ isync
+
+ /* Return */
+ mtmsr r7
+ blr
+
+#endif /* CONFIG_CPU_FREQ_PMAC && CONFIG_6xx */
+
+/*
+ * complement mask on the msr then "or" some values on.
+ * _nmask_and_or_msr(nmask, value_to_or)
+ */
+_GLOBAL(_nmask_and_or_msr)
+ mfmsr r0 /* Get current msr */
+ andc r0,r0,r3 /* And off the bits set in r3 (first parm) */
+ or r0,r0,r4 /* Or on the bits in r4 (second parm) */
+ SYNC /* Some chip revs have problems here... */
+ mtmsr r0 /* Update machine state */
+ isync
+ blr /* Done */
+
+
+/*
+ * Flush MMU TLB
+ */
+_GLOBAL(_tlbia)
+#if defined(CONFIG_40x)
+ sync /* Flush to memory before changing mapping */
+ tlbia
+ isync /* Flush shadow TLB */
+#elif defined(CONFIG_44x)
+ li r3,0
+ sync
+
+ /* Load high watermark */
+ lis r4,tlb_44x_hwater@ha
+ lwz r5,tlb_44x_hwater@l(r4)
+
+1: tlbwe r3,r3,PPC44x_TLB_PAGEID
+ addi r3,r3,1
+ cmpw 0,r3,r5
+ ble 1b
+
+ isync
+#elif defined(CONFIG_FSL_BOOKE)
+ /* Invalidate all entries in TLB0 */
+ li r3, 0x04
+ tlbivax 0,3
+ /* Invalidate all entries in TLB1 */
+ li r3, 0x0c
+ tlbivax 0,3
+ /* Invalidate all entries in TLB2 */
+ li r3, 0x14
+ tlbivax 0,3
+ /* Invalidate all entries in TLB3 */
+ li r3, 0x1c
+ tlbivax 0,3
+ msync
+#ifdef CONFIG_SMP
+ tlbsync
+#endif /* CONFIG_SMP */
+#else /* !(CONFIG_40x || CONFIG_44x || CONFIG_FSL_BOOKE) */
+#if defined(CONFIG_SMP)
+ rlwinm r8,r1,0,0,18
+ lwz r8,TI_CPU(r8)
+ oris r8,r8,10
+ mfmsr r10
+ SYNC
+ rlwinm r0,r10,0,17,15 /* clear bit 16 (MSR_EE) */
+ rlwinm r0,r0,0,28,26 /* clear DR */
+ mtmsr r0
+ SYNC_601
+ isync
+ lis r9,mmu_hash_lock@h
+ ori r9,r9,mmu_hash_lock@l
+ tophys(r9,r9)
+10: lwarx r7,0,r9
+ cmpwi 0,r7,0
+ bne- 10b
+ stwcx. r8,0,r9
+ bne- 10b
+ sync
+ tlbia
+ sync
+ TLBSYNC
+ li r0,0
+ stw r0,0(r9) /* clear mmu_hash_lock */
+ mtmsr r10
+ SYNC_601
+ isync
+#else /* CONFIG_SMP */
+ sync
+ tlbia
+ sync
+#endif /* CONFIG_SMP */
+#endif /* ! defined(CONFIG_40x) */
+ blr
+
+/*
+ * Flush MMU TLB for a particular address
+ */
+_GLOBAL(_tlbie)
+#if defined(CONFIG_40x)
+ tlbsx. r3, 0, r3
+ bne 10f
+ sync
+ /* There are only 64 TLB entries, so r3 < 64, which means bit 25 is clear.
+ * Since 25 is the V bit in the TLB_TAG, loading this value will invalidate
+ * the TLB entry. */
+ tlbwe r3, r3, TLB_TAG
+ isync
+10:
+#elif defined(CONFIG_44x)
+ mfspr r4,SPRN_MMUCR
+ mfspr r5,SPRN_PID /* Get PID */
+ rlwimi r4,r5,0,24,31 /* Set TID */
+ mtspr SPRN_MMUCR,r4
+
+ tlbsx. r3, 0, r3
+ bne 10f
+ sync
+ /* There are only 64 TLB entries, so r3 < 64,
+ * which means bit 22, is clear. Since 22 is
+ * the V bit in the TLB_PAGEID, loading this
+ * value will invalidate the TLB entry.
+ */
+ tlbwe r3, r3, PPC44x_TLB_PAGEID
+ isync
+10:
+#elif defined(CONFIG_FSL_BOOKE)
+ rlwinm r4, r3, 0, 0, 19
+ ori r5, r4, 0x08 /* TLBSEL = 1 */
+ ori r6, r4, 0x10 /* TLBSEL = 2 */
+ ori r7, r4, 0x18 /* TLBSEL = 3 */
+ tlbivax 0, r4
+ tlbivax 0, r5
+ tlbivax 0, r6
+ tlbivax 0, r7
+ msync
+#if defined(CONFIG_SMP)
+ tlbsync
+#endif /* CONFIG_SMP */
+#else /* !(CONFIG_40x || CONFIG_44x || CONFIG_FSL_BOOKE) */
+#if defined(CONFIG_SMP)
+ rlwinm r8,r1,0,0,18
+ lwz r8,TI_CPU(r8)
+ oris r8,r8,11
+ mfmsr r10
+ SYNC
+ rlwinm r0,r10,0,17,15 /* clear bit 16 (MSR_EE) */
+ rlwinm r0,r0,0,28,26 /* clear DR */
+ mtmsr r0
+ SYNC_601
+ isync
+ lis r9,mmu_hash_lock@h
+ ori r9,r9,mmu_hash_lock@l
+ tophys(r9,r9)
+10: lwarx r7,0,r9
+ cmpwi 0,r7,0
+ bne- 10b
+ stwcx. r8,0,r9
+ bne- 10b
+ eieio
+ tlbie r3
+ sync
+ TLBSYNC
+ li r0,0
+ stw r0,0(r9) /* clear mmu_hash_lock */
+ mtmsr r10
+ SYNC_601
+ isync
+#else /* CONFIG_SMP */
+ tlbie r3
+ sync
+#endif /* CONFIG_SMP */
+#endif /* ! CONFIG_40x */
+ blr
+
+/*
+ * Flush instruction cache.
+ * This is a no-op on the 601.
+ */
+_GLOBAL(flush_instruction_cache)
+#if defined(CONFIG_8xx)
+ isync
+ lis r5, IDC_INVALL@h
+ mtspr SPRN_IC_CST, r5
+#elif defined(CONFIG_4xx)
+#ifdef CONFIG_403GCX
+ li r3, 512
+ mtctr r3
+ lis r4, KERNELBASE@h
+1: iccci 0, r4
+ addi r4, r4, 16
+ bdnz 1b
+#else
+ lis r3, KERNELBASE@h
+ iccci 0,r3
+#endif
+#elif CONFIG_FSL_BOOKE
+BEGIN_FTR_SECTION
+ mfspr r3,SPRN_L1CSR0
+ ori r3,r3,L1CSR0_CFI|L1CSR0_CLFC
+ /* msync; isync recommended here */
+ mtspr SPRN_L1CSR0,r3
+ isync
+ blr
+END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE)
+ mfspr r3,SPRN_L1CSR1
+ ori r3,r3,L1CSR1_ICFI|L1CSR1_ICLFR
+ mtspr SPRN_L1CSR1,r3
+#else
+ mfspr r3,SPRN_PVR
+ rlwinm r3,r3,16,16,31
+ cmpwi 0,r3,1
+ beqlr /* for 601, do nothing */
+ /* 603/604 processor - use invalidate-all bit in HID0 */
+ mfspr r3,SPRN_HID0
+ ori r3,r3,HID0_ICFI
+ mtspr SPRN_HID0,r3
+#endif /* CONFIG_8xx/4xx */
+ isync
+ blr
+
+/*
+ * Write any modified data cache blocks out to memory
+ * and invalidate the corresponding instruction cache blocks.
+ * This is a no-op on the 601.
+ *
+ * flush_icache_range(unsigned long start, unsigned long stop)
+ */
+_GLOBAL(__flush_icache_range)
+BEGIN_FTR_SECTION
+ blr /* for 601, do nothing */
+END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE)
+ li r5,L1_CACHE_BYTES-1
+ andc r3,r3,r5
+ subf r4,r3,r4
+ add r4,r4,r5
+ srwi. r4,r4,L1_CACHE_SHIFT
+ beqlr
+ mtctr r4
+ mr r6,r3
+1: dcbst 0,r3
+ addi r3,r3,L1_CACHE_BYTES
+ bdnz 1b
+ sync /* wait for dcbst's to get to ram */
+ mtctr r4
+2: icbi 0,r6
+ addi r6,r6,L1_CACHE_BYTES
+ bdnz 2b
+ sync /* additional sync needed on g4 */
+ isync
+ blr
+/*
+ * Write any modified data cache blocks out to memory.
+ * Does not invalidate the corresponding cache lines (especially for
+ * any corresponding instruction cache).
+ *
+ * clean_dcache_range(unsigned long start, unsigned long stop)
+ */
+_GLOBAL(clean_dcache_range)
+ li r5,L1_CACHE_BYTES-1
+ andc r3,r3,r5
+ subf r4,r3,r4
+ add r4,r4,r5
+ srwi. r4,r4,L1_CACHE_SHIFT
+ beqlr
+ mtctr r4
+
+1: dcbst 0,r3
+ addi r3,r3,L1_CACHE_BYTES
+ bdnz 1b
+ sync /* wait for dcbst's to get to ram */
+ blr
+
+/*
+ * Write any modified data cache blocks out to memory and invalidate them.
+ * Does not invalidate the corresponding instruction cache blocks.
+ *
+ * flush_dcache_range(unsigned long start, unsigned long stop)
+ */
+_GLOBAL(flush_dcache_range)
+ li r5,L1_CACHE_BYTES-1
+ andc r3,r3,r5
+ subf r4,r3,r4
+ add r4,r4,r5
+ srwi. r4,r4,L1_CACHE_SHIFT
+ beqlr
+ mtctr r4
+
+1: dcbf 0,r3
+ addi r3,r3,L1_CACHE_BYTES
+ bdnz 1b
+ sync /* wait for dcbst's to get to ram */
+ blr
+
+/*
+ * Like above, but invalidate the D-cache. This is used by the 8xx
+ * to invalidate the cache so the PPC core doesn't get stale data
+ * from the CPM (no cache snooping here :-).
+ *
+ * invalidate_dcache_range(unsigned long start, unsigned long stop)
+ */
+_GLOBAL(invalidate_dcache_range)
+ li r5,L1_CACHE_BYTES-1
+ andc r3,r3,r5
+ subf r4,r3,r4
+ add r4,r4,r5
+ srwi. r4,r4,L1_CACHE_SHIFT
+ beqlr
+ mtctr r4
+
+1: dcbi 0,r3
+ addi r3,r3,L1_CACHE_BYTES
+ bdnz 1b
+ sync /* wait for dcbi's to get to ram */
+ blr
+
+/*
+ * Flush a particular page from the data cache to RAM.
+ * Note: this is necessary because the instruction cache does *not*
+ * snoop from the data cache.
+ * This is a no-op on the 601 which has a unified cache.
+ *
+ * void __flush_dcache_icache(void *page)
+ */
+_GLOBAL(__flush_dcache_icache)
+BEGIN_FTR_SECTION
+ blr /* for 601, do nothing */
+END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE)
+ rlwinm r3,r3,0,0,19 /* Get page base address */
+ li r4,4096/L1_CACHE_BYTES /* Number of lines in a page */
+ mtctr r4
+ mr r6,r3
+0: dcbst 0,r3 /* Write line to ram */
+ addi r3,r3,L1_CACHE_BYTES
+ bdnz 0b
+ sync
+ mtctr r4
+1: icbi 0,r6
+ addi r6,r6,L1_CACHE_BYTES
+ bdnz 1b
+ sync
+ isync
+ blr
+
+/*
+ * Flush a particular page from the data cache to RAM, identified
+ * by its physical address. We turn off the MMU so we can just use
+ * the physical address (this may be a highmem page without a kernel
+ * mapping).
+ *
+ * void __flush_dcache_icache_phys(unsigned long physaddr)
+ */
+_GLOBAL(__flush_dcache_icache_phys)
+BEGIN_FTR_SECTION
+ blr /* for 601, do nothing */
+END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE)
+ mfmsr r10
+ rlwinm r0,r10,0,28,26 /* clear DR */
+ mtmsr r0
+ isync
+ rlwinm r3,r3,0,0,19 /* Get page base address */
+ li r4,4096/L1_CACHE_BYTES /* Number of lines in a page */
+ mtctr r4
+ mr r6,r3
+0: dcbst 0,r3 /* Write line to ram */
+ addi r3,r3,L1_CACHE_BYTES
+ bdnz 0b
+ sync
+ mtctr r4
+1: icbi 0,r6
+ addi r6,r6,L1_CACHE_BYTES
+ bdnz 1b
+ sync
+ mtmsr r10 /* restore DR */
+ isync
+ blr
+
+/*
+ * Clear pages using the dcbz instruction, which doesn't cause any
+ * memory traffic (except to write out any cache lines which get
+ * displaced). This only works on cacheable memory.
+ *
+ * void clear_pages(void *page, int order) ;
+ */
+_GLOBAL(clear_pages)
+ li r0,4096/L1_CACHE_BYTES
+ slw r0,r0,r4
+ mtctr r0
+#ifdef CONFIG_8xx
+ li r4, 0
+1: stw r4, 0(r3)
+ stw r4, 4(r3)
+ stw r4, 8(r3)
+ stw r4, 12(r3)
+#else
+1: dcbz 0,r3
+#endif
+ addi r3,r3,L1_CACHE_BYTES
+ bdnz 1b
+ blr
+
+/*
+ * Copy a whole page. We use the dcbz instruction on the destination
+ * to reduce memory traffic (it eliminates the unnecessary reads of
+ * the destination into cache). This requires that the destination
+ * is cacheable.
+ */
+#define COPY_16_BYTES \
+ lwz r6,4(r4); \
+ lwz r7,8(r4); \
+ lwz r8,12(r4); \
+ lwzu r9,16(r4); \
+ stw r6,4(r3); \
+ stw r7,8(r3); \
+ stw r8,12(r3); \
+ stwu r9,16(r3)
+
+_GLOBAL(copy_page)
+ addi r3,r3,-4
+ addi r4,r4,-4
+
+#ifdef CONFIG_8xx
+ /* don't use prefetch on 8xx */
+ li r0,4096/L1_CACHE_BYTES
+ mtctr r0
+1: COPY_16_BYTES
+ bdnz 1b
+ blr
+
+#else /* not 8xx, we can prefetch */
+ li r5,4
+
+#if MAX_COPY_PREFETCH > 1
+ li r0,MAX_COPY_PREFETCH
+ li r11,4
+ mtctr r0
+11: dcbt r11,r4
+ addi r11,r11,L1_CACHE_BYTES
+ bdnz 11b
+#else /* MAX_COPY_PREFETCH == 1 */
+ dcbt r5,r4
+ li r11,L1_CACHE_BYTES+4
+#endif /* MAX_COPY_PREFETCH */
+ li r0,4096/L1_CACHE_BYTES - MAX_COPY_PREFETCH
+ crclr 4*cr0+eq
+2:
+ mtctr r0
+1:
+ dcbt r11,r4
+ dcbz r5,r3
+ COPY_16_BYTES
+#if L1_CACHE_BYTES >= 32
+ COPY_16_BYTES
+#if L1_CACHE_BYTES >= 64
+ COPY_16_BYTES
+ COPY_16_BYTES
+#if L1_CACHE_BYTES >= 128
+ COPY_16_BYTES
+ COPY_16_BYTES
+ COPY_16_BYTES
+ COPY_16_BYTES
+#endif
+#endif
+#endif
+ bdnz 1b
+ beqlr
+ crnot 4*cr0+eq,4*cr0+eq
+ li r0,MAX_COPY_PREFETCH
+ li r11,4
+ b 2b
+#endif /* CONFIG_8xx */
+
+/*
+ * void atomic_clear_mask(atomic_t mask, atomic_t *addr)
+ * void atomic_set_mask(atomic_t mask, atomic_t *addr);
+ */
+_GLOBAL(atomic_clear_mask)
+10: lwarx r5,0,r4
+ andc r5,r5,r3
+ PPC405_ERR77(0,r4)
+ stwcx. r5,0,r4
+ bne- 10b
+ blr
+_GLOBAL(atomic_set_mask)
+10: lwarx r5,0,r4
+ or r5,r5,r3
+ PPC405_ERR77(0,r4)
+ stwcx. r5,0,r4
+ bne- 10b
+ blr
+
+/*
+ * I/O string operations
+ *
+ * insb(port, buf, len)
+ * outsb(port, buf, len)
+ * insw(port, buf, len)
+ * outsw(port, buf, len)
+ * insl(port, buf, len)
+ * outsl(port, buf, len)
+ * insw_ns(port, buf, len)
+ * outsw_ns(port, buf, len)
+ * insl_ns(port, buf, len)
+ * outsl_ns(port, buf, len)
+ *
+ * The *_ns versions don't do byte-swapping.
+ */
+_GLOBAL(_insb)
+ cmpwi 0,r5,0
+ mtctr r5
+ subi r4,r4,1
+ blelr-
+00: lbz r5,0(r3)
+ eieio
+ stbu r5,1(r4)
+ bdnz 00b
+ blr
+
+_GLOBAL(_outsb)
+ cmpwi 0,r5,0
+ mtctr r5
+ subi r4,r4,1
+ blelr-
+00: lbzu r5,1(r4)
+ stb r5,0(r3)
+ eieio
+ bdnz 00b
+ blr
+
+_GLOBAL(_insw)
+ cmpwi 0,r5,0
+ mtctr r5
+ subi r4,r4,2
+ blelr-
+00: lhbrx r5,0,r3
+ eieio
+ sthu r5,2(r4)
+ bdnz 00b
+ blr
+
+_GLOBAL(_outsw)
+ cmpwi 0,r5,0
+ mtctr r5
+ subi r4,r4,2
+ blelr-
+00: lhzu r5,2(r4)
+ eieio
+ sthbrx r5,0,r3
+ bdnz 00b
+ blr
+
+_GLOBAL(_insl)
+ cmpwi 0,r5,0
+ mtctr r5
+ subi r4,r4,4
+ blelr-
+00: lwbrx r5,0,r3
+ eieio
+ stwu r5,4(r4)
+ bdnz 00b
+ blr
+
+_GLOBAL(_outsl)
+ cmpwi 0,r5,0
+ mtctr r5
+ subi r4,r4,4
+ blelr-
+00: lwzu r5,4(r4)
+ stwbrx r5,0,r3
+ eieio
+ bdnz 00b
+ blr
+
+_GLOBAL(__ide_mm_insw)
+_GLOBAL(_insw_ns)
+ cmpwi 0,r5,0
+ mtctr r5
+ subi r4,r4,2
+ blelr-
+00: lhz r5,0(r3)
+ eieio
+ sthu r5,2(r4)
+ bdnz 00b
+ blr
+
+_GLOBAL(__ide_mm_outsw)
+_GLOBAL(_outsw_ns)
+ cmpwi 0,r5,0
+ mtctr r5
+ subi r4,r4,2
+ blelr-
+00: lhzu r5,2(r4)
+ sth r5,0(r3)
+ eieio
+ bdnz 00b
+ blr
+
+_GLOBAL(__ide_mm_insl)
+_GLOBAL(_insl_ns)
+ cmpwi 0,r5,0
+ mtctr r5
+ subi r4,r4,4
+ blelr-
+00: lwz r5,0(r3)
+ eieio
+ stwu r5,4(r4)
+ bdnz 00b
+ blr
+
+_GLOBAL(__ide_mm_outsl)
+_GLOBAL(_outsl_ns)
+ cmpwi 0,r5,0
+ mtctr r5
+ subi r4,r4,4
+ blelr-
+00: lwzu r5,4(r4)
+ stw r5,0(r3)
+ eieio
+ bdnz 00b
+ blr
+
+/*
+ * Extended precision shifts.
+ *
+ * Updated to be valid for shift counts from 0 to 63 inclusive.
+ * -- Gabriel
+ *
+ * R3/R4 has 64 bit value
+ * R5 has shift count
+ * result in R3/R4
+ *
+ * ashrdi3: arithmetic right shift (sign propagation)
+ * lshrdi3: logical right shift
+ * ashldi3: left shift
+ */
+_GLOBAL(__ashrdi3)
+ subfic r6,r5,32
+ srw r4,r4,r5 # LSW = count > 31 ? 0 : LSW >> count
+ addi r7,r5,32 # could be xori, or addi with -32
+ slw r6,r3,r6 # t1 = count > 31 ? 0 : MSW << (32-count)
+ rlwinm r8,r7,0,32 # t3 = (count < 32) ? 32 : 0
+ sraw r7,r3,r7 # t2 = MSW >> (count-32)
+ or r4,r4,r6 # LSW |= t1
+ slw r7,r7,r8 # t2 = (count < 32) ? 0 : t2
+ sraw r3,r3,r5 # MSW = MSW >> count
+ or r4,r4,r7 # LSW |= t2
+ blr
+
+_GLOBAL(__ashldi3)
+ subfic r6,r5,32
+ slw r3,r3,r5 # MSW = count > 31 ? 0 : MSW << count
+ addi r7,r5,32 # could be xori, or addi with -32
+ srw r6,r4,r6 # t1 = count > 31 ? 0 : LSW >> (32-count)
+ slw r7,r4,r7 # t2 = count < 32 ? 0 : LSW << (count-32)
+ or r3,r3,r6 # MSW |= t1
+ slw r4,r4,r5 # LSW = LSW << count
+ or r3,r3,r7 # MSW |= t2
+ blr
+
+_GLOBAL(__lshrdi3)
+ subfic r6,r5,32
+ srw r4,r4,r5 # LSW = count > 31 ? 0 : LSW >> count
+ addi r7,r5,32 # could be xori, or addi with -32
+ slw r6,r3,r6 # t1 = count > 31 ? 0 : MSW << (32-count)
+ srw r7,r3,r7 # t2 = count < 32 ? 0 : MSW >> (count-32)
+ or r4,r4,r6 # LSW |= t1
+ srw r3,r3,r5 # MSW = MSW >> count
+ or r4,r4,r7 # LSW |= t2
+ blr
+
+_GLOBAL(abs)
+ srawi r4,r3,31
+ xor r3,r3,r4
+ sub r3,r3,r4
+ blr
+
+_GLOBAL(_get_SP)
+ mr r3,r1 /* Close enough */
+ blr
+
+/*
+ * Create a kernel thread
+ * kernel_thread(fn, arg, flags)
+ */
+_GLOBAL(kernel_thread)
+ stwu r1,-16(r1)
+ stw r30,8(r1)
+ stw r31,12(r1)
+ mr r30,r3 /* function */
+ mr r31,r4 /* argument */
+ ori r3,r5,CLONE_VM /* flags */
+ oris r3,r3,CLONE_UNTRACED>>16
+ li r4,0 /* new sp (unused) */
+ li r0,__NR_clone
+ sc
+ cmpwi 0,r3,0 /* parent or child? */
+ bne 1f /* return if parent */
+ li r0,0 /* make top-level stack frame */
+ stwu r0,-16(r1)
+ mtlr r30 /* fn addr in lr */
+ mr r3,r31 /* load arg and call fn */
+ PPC440EP_ERR42
+ blrl
+ li r0,__NR_exit /* exit if function returns */
+ li r3,0
+ sc
+1: lwz r30,8(r1)
+ lwz r31,12(r1)
+ addi r1,r1,16
+ blr
+
+_GLOBAL(execve)
+ li r0,__NR_execve
+ sc
+ bnslr
+ neg r3,r3
+ blr
+
+/*
+ * This routine is just here to keep GCC happy - sigh...
+ */
+_GLOBAL(__main)
+ blr
diff --git a/arch/powerpc/kernel/misc_64.S b/arch/powerpc/kernel/misc_64.S
new file mode 100644
index 000000000000..ae48a002f81a
--- /dev/null
+++ b/arch/powerpc/kernel/misc_64.S
@@ -0,0 +1,950 @@
+/*
+ * arch/powerpc/kernel/misc64.S
+ *
+ * This file contains miscellaneous low-level functions.
+ * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
+ *
+ * Largely rewritten by Cort Dougan (cort@cs.nmt.edu)
+ * and Paul Mackerras.
+ * Adapted for iSeries by Mike Corrigan (mikejc@us.ibm.com)
+ * PPC64 updates by Dave Engebretsen (engebret@us.ibm.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/sys.h>
+#include <asm/unistd.h>
+#include <asm/errno.h>
+#include <asm/processor.h>
+#include <asm/page.h>
+#include <asm/cache.h>
+#include <asm/ppc_asm.h>
+#include <asm/asm-offsets.h>
+#include <asm/cputable.h>
+#include <asm/thread_info.h>
+
+ .text
+
+/*
+ * Returns (address we are running at) - (address we were linked at)
+ * for use before the text and data are mapped to KERNELBASE.
+ */
+
+_GLOBAL(reloc_offset)
+ mflr r0
+ bl 1f
+1: mflr r3
+ LOADADDR(r4,1b)
+ subf r3,r4,r3
+ mtlr r0
+ blr
+
+/*
+ * add_reloc_offset(x) returns x + reloc_offset().
+ */
+_GLOBAL(add_reloc_offset)
+ mflr r0
+ bl 1f
+1: mflr r5
+ LOADADDR(r4,1b)
+ subf r5,r4,r5
+ add r3,r3,r5
+ mtlr r0
+ blr
+
+_GLOBAL(get_msr)
+ mfmsr r3
+ blr
+
+_GLOBAL(get_dar)
+ mfdar r3
+ blr
+
+_GLOBAL(get_srr0)
+ mfsrr0 r3
+ blr
+
+_GLOBAL(get_srr1)
+ mfsrr1 r3
+ blr
+
+_GLOBAL(get_sp)
+ mr r3,r1
+ blr
+
+#ifdef CONFIG_IRQSTACKS
+_GLOBAL(call_do_softirq)
+ mflr r0
+ std r0,16(r1)
+ stdu r1,THREAD_SIZE-112(r3)
+ mr r1,r3
+ bl .__do_softirq
+ ld r1,0(r1)
+ ld r0,16(r1)
+ mtlr r0
+ blr
+
+_GLOBAL(call___do_IRQ)
+ mflr r0
+ std r0,16(r1)
+ stdu r1,THREAD_SIZE-112(r5)
+ mr r1,r5
+ bl .__do_IRQ
+ ld r1,0(r1)
+ ld r0,16(r1)
+ mtlr r0
+ blr
+#endif /* CONFIG_IRQSTACKS */
+
+ /*
+ * To be called by C code which needs to do some operations with MMU
+ * disabled. Note that interrupts have to be disabled by the caller
+ * prior to calling us. The code called _MUST_ be in the RMO of course
+ * and part of the linear mapping as we don't attempt to translate the
+ * stack pointer at all. The function is called with the stack switched
+ * to this CPU emergency stack
+ *
+ * prototype is void *call_with_mmu_off(void *func, void *data);
+ *
+ * the called function is expected to be of the form
+ *
+ * void *called(void *data);
+ */
+_GLOBAL(call_with_mmu_off)
+ mflr r0 /* get link, save it on stackframe */
+ std r0,16(r1)
+ mr r1,r5 /* save old stack ptr */
+ ld r1,PACAEMERGSP(r13) /* get emerg. stack */
+ subi r1,r1,STACK_FRAME_OVERHEAD
+ std r0,16(r1) /* save link on emerg. stack */
+ std r5,0(r1) /* save old stack ptr in backchain */
+ ld r3,0(r3) /* get to real function ptr (assume same TOC) */
+ bl 2f /* we need LR to return, continue at label 2 */
+
+ ld r0,16(r1) /* we return here from the call, get LR and */
+ ld r1,0(r1) /* .. old stack ptr */
+ mtspr SPRN_SRR0,r0 /* and get back to virtual mode with these */
+ mfmsr r4
+ ori r4,r4,MSR_IR|MSR_DR
+ mtspr SPRN_SRR1,r4
+ rfid
+
+2: mtspr SPRN_SRR0,r3 /* coming from above, enter real mode */
+ mr r3,r4 /* get parameter */
+ mfmsr r0
+ ori r0,r0,MSR_IR|MSR_DR
+ xori r0,r0,MSR_IR|MSR_DR
+ mtspr SPRN_SRR1,r0
+ rfid
+
+
+ .section ".toc","aw"
+PPC64_CACHES:
+ .tc ppc64_caches[TC],ppc64_caches
+ .section ".text"
+
+/*
+ * Write any modified data cache blocks out to memory
+ * and invalidate the corresponding instruction cache blocks.
+ *
+ * flush_icache_range(unsigned long start, unsigned long stop)
+ *
+ * flush all bytes from start through stop-1 inclusive
+ */
+
+_KPROBE(__flush_icache_range)
+
+/*
+ * Flush the data cache to memory
+ *
+ * Different systems have different cache line sizes
+ * and in some cases i-cache and d-cache line sizes differ from
+ * each other.
+ */
+ ld r10,PPC64_CACHES@toc(r2)
+ lwz r7,DCACHEL1LINESIZE(r10)/* Get cache line size */
+ addi r5,r7,-1
+ andc r6,r3,r5 /* round low to line bdy */
+ subf r8,r6,r4 /* compute length */
+ add r8,r8,r5 /* ensure we get enough */
+ lwz r9,DCACHEL1LOGLINESIZE(r10) /* Get log-2 of cache line size */
+ srw. r8,r8,r9 /* compute line count */
+ beqlr /* nothing to do? */
+ mtctr r8
+1: dcbst 0,r6
+ add r6,r6,r7
+ bdnz 1b
+ sync
+
+/* Now invalidate the instruction cache */
+
+ lwz r7,ICACHEL1LINESIZE(r10) /* Get Icache line size */
+ addi r5,r7,-1
+ andc r6,r3,r5 /* round low to line bdy */
+ subf r8,r6,r4 /* compute length */
+ add r8,r8,r5
+ lwz r9,ICACHEL1LOGLINESIZE(r10) /* Get log-2 of Icache line size */
+ srw. r8,r8,r9 /* compute line count */
+ beqlr /* nothing to do? */
+ mtctr r8
+2: icbi 0,r6
+ add r6,r6,r7
+ bdnz 2b
+ isync
+ blr
+ .previous .text
+/*
+ * Like above, but only do the D-cache.
+ *
+ * flush_dcache_range(unsigned long start, unsigned long stop)
+ *
+ * flush all bytes from start to stop-1 inclusive
+ */
+_GLOBAL(flush_dcache_range)
+
+/*
+ * Flush the data cache to memory
+ *
+ * Different systems have different cache line sizes
+ */
+ ld r10,PPC64_CACHES@toc(r2)
+ lwz r7,DCACHEL1LINESIZE(r10) /* Get dcache line size */
+ addi r5,r7,-1
+ andc r6,r3,r5 /* round low to line bdy */
+ subf r8,r6,r4 /* compute length */
+ add r8,r8,r5 /* ensure we get enough */
+ lwz r9,DCACHEL1LOGLINESIZE(r10) /* Get log-2 of dcache line size */
+ srw. r8,r8,r9 /* compute line count */
+ beqlr /* nothing to do? */
+ mtctr r8
+0: dcbst 0,r6
+ add r6,r6,r7
+ bdnz 0b
+ sync
+ blr
+
+/*
+ * Like above, but works on non-mapped physical addresses.
+ * Use only for non-LPAR setups ! It also assumes real mode
+ * is cacheable. Used for flushing out the DART before using
+ * it as uncacheable memory
+ *
+ * flush_dcache_phys_range(unsigned long start, unsigned long stop)
+ *
+ * flush all bytes from start to stop-1 inclusive
+ */
+_GLOBAL(flush_dcache_phys_range)
+ ld r10,PPC64_CACHES@toc(r2)
+ lwz r7,DCACHEL1LINESIZE(r10) /* Get dcache line size */
+ addi r5,r7,-1
+ andc r6,r3,r5 /* round low to line bdy */
+ subf r8,r6,r4 /* compute length */
+ add r8,r8,r5 /* ensure we get enough */
+ lwz r9,DCACHEL1LOGLINESIZE(r10) /* Get log-2 of dcache line size */
+ srw. r8,r8,r9 /* compute line count */
+ beqlr /* nothing to do? */
+ mfmsr r5 /* Disable MMU Data Relocation */
+ ori r0,r5,MSR_DR
+ xori r0,r0,MSR_DR
+ sync
+ mtmsr r0
+ sync
+ isync
+ mtctr r8
+0: dcbst 0,r6
+ add r6,r6,r7
+ bdnz 0b
+ sync
+ isync
+ mtmsr r5 /* Re-enable MMU Data Relocation */
+ sync
+ isync
+ blr
+
+_GLOBAL(flush_inval_dcache_range)
+ ld r10,PPC64_CACHES@toc(r2)
+ lwz r7,DCACHEL1LINESIZE(r10) /* Get dcache line size */
+ addi r5,r7,-1
+ andc r6,r3,r5 /* round low to line bdy */
+ subf r8,r6,r4 /* compute length */
+ add r8,r8,r5 /* ensure we get enough */
+ lwz r9,DCACHEL1LOGLINESIZE(r10)/* Get log-2 of dcache line size */
+ srw. r8,r8,r9 /* compute line count */
+ beqlr /* nothing to do? */
+ sync
+ isync
+ mtctr r8
+0: dcbf 0,r6
+ add r6,r6,r7
+ bdnz 0b
+ sync
+ isync
+ blr
+
+
+/*
+ * Flush a particular page from the data cache to RAM.
+ * Note: this is necessary because the instruction cache does *not*
+ * snoop from the data cache.
+ *
+ * void __flush_dcache_icache(void *page)
+ */
+_GLOBAL(__flush_dcache_icache)
+/*
+ * Flush the data cache to memory
+ *
+ * Different systems have different cache line sizes
+ */
+
+/* Flush the dcache */
+ ld r7,PPC64_CACHES@toc(r2)
+ clrrdi r3,r3,PAGE_SHIFT /* Page align */
+ lwz r4,DCACHEL1LINESPERPAGE(r7) /* Get # dcache lines per page */
+ lwz r5,DCACHEL1LINESIZE(r7) /* Get dcache line size */
+ mr r6,r3
+ mtctr r4
+0: dcbst 0,r6
+ add r6,r6,r5
+ bdnz 0b
+ sync
+
+/* Now invalidate the icache */
+
+ lwz r4,ICACHEL1LINESPERPAGE(r7) /* Get # icache lines per page */
+ lwz r5,ICACHEL1LINESIZE(r7) /* Get icache line size */
+ mtctr r4
+1: icbi 0,r3
+ add r3,r3,r5
+ bdnz 1b
+ isync
+ blr
+
+/*
+ * I/O string operations
+ *
+ * insb(port, buf, len)
+ * outsb(port, buf, len)
+ * insw(port, buf, len)
+ * outsw(port, buf, len)
+ * insl(port, buf, len)
+ * outsl(port, buf, len)
+ * insw_ns(port, buf, len)
+ * outsw_ns(port, buf, len)
+ * insl_ns(port, buf, len)
+ * outsl_ns(port, buf, len)
+ *
+ * The *_ns versions don't do byte-swapping.
+ */
+_GLOBAL(_insb)
+ cmpwi 0,r5,0
+ mtctr r5
+ subi r4,r4,1
+ blelr-
+00: lbz r5,0(r3)
+ eieio
+ stbu r5,1(r4)
+ bdnz 00b
+ twi 0,r5,0
+ isync
+ blr
+
+_GLOBAL(_outsb)
+ cmpwi 0,r5,0
+ mtctr r5
+ subi r4,r4,1
+ blelr-
+00: lbzu r5,1(r4)
+ stb r5,0(r3)
+ bdnz 00b
+ sync
+ blr
+
+_GLOBAL(_insw)
+ cmpwi 0,r5,0
+ mtctr r5
+ subi r4,r4,2
+ blelr-
+00: lhbrx r5,0,r3
+ eieio
+ sthu r5,2(r4)
+ bdnz 00b
+ twi 0,r5,0
+ isync
+ blr
+
+_GLOBAL(_outsw)
+ cmpwi 0,r5,0
+ mtctr r5
+ subi r4,r4,2
+ blelr-
+00: lhzu r5,2(r4)
+ sthbrx r5,0,r3
+ bdnz 00b
+ sync
+ blr
+
+_GLOBAL(_insl)
+ cmpwi 0,r5,0
+ mtctr r5
+ subi r4,r4,4
+ blelr-
+00: lwbrx r5,0,r3
+ eieio
+ stwu r5,4(r4)
+ bdnz 00b
+ twi 0,r5,0
+ isync
+ blr
+
+_GLOBAL(_outsl)
+ cmpwi 0,r5,0
+ mtctr r5
+ subi r4,r4,4
+ blelr-
+00: lwzu r5,4(r4)
+ stwbrx r5,0,r3
+ bdnz 00b
+ sync
+ blr
+
+/* _GLOBAL(ide_insw) now in drivers/ide/ide-iops.c */
+_GLOBAL(_insw_ns)
+ cmpwi 0,r5,0
+ mtctr r5
+ subi r4,r4,2
+ blelr-
+00: lhz r5,0(r3)
+ eieio
+ sthu r5,2(r4)
+ bdnz 00b
+ twi 0,r5,0
+ isync
+ blr
+
+/* _GLOBAL(ide_outsw) now in drivers/ide/ide-iops.c */
+_GLOBAL(_outsw_ns)
+ cmpwi 0,r5,0
+ mtctr r5
+ subi r4,r4,2
+ blelr-
+00: lhzu r5,2(r4)
+ sth r5,0(r3)
+ bdnz 00b
+ sync
+ blr
+
+_GLOBAL(_insl_ns)
+ cmpwi 0,r5,0
+ mtctr r5
+ subi r4,r4,4
+ blelr-
+00: lwz r5,0(r3)
+ eieio
+ stwu r5,4(r4)
+ bdnz 00b
+ twi 0,r5,0
+ isync
+ blr
+
+_GLOBAL(_outsl_ns)
+ cmpwi 0,r5,0
+ mtctr r5
+ subi r4,r4,4
+ blelr-
+00: lwzu r5,4(r4)
+ stw r5,0(r3)
+ bdnz 00b
+ sync
+ blr
+
+/*
+ * identify_cpu and calls setup_cpu
+ * In: r3 = base of the cpu_specs array
+ * r4 = address of cur_cpu_spec
+ * r5 = relocation offset
+ */
+_GLOBAL(identify_cpu)
+ mfpvr r7
+1:
+ lwz r8,CPU_SPEC_PVR_MASK(r3)
+ and r8,r8,r7
+ lwz r9,CPU_SPEC_PVR_VALUE(r3)
+ cmplw 0,r9,r8
+ beq 1f
+ addi r3,r3,CPU_SPEC_ENTRY_SIZE
+ b 1b
+1:
+ sub r0,r3,r5
+ std r0,0(r4)
+ ld r4,CPU_SPEC_SETUP(r3)
+ add r4,r4,r5
+ ld r4,0(r4)
+ add r4,r4,r5
+ mtctr r4
+ /* Calling convention for cpu setup is r3=offset, r4=cur_cpu_spec */
+ mr r4,r3
+ mr r3,r5
+ bctr
+
+/*
+ * do_cpu_ftr_fixups - goes through the list of CPU feature fixups
+ * and writes nop's over sections of code that don't apply for this cpu.
+ * r3 = data offset (not changed)
+ */
+_GLOBAL(do_cpu_ftr_fixups)
+ /* Get CPU 0 features */
+ LOADADDR(r6,cur_cpu_spec)
+ sub r6,r6,r3
+ ld r4,0(r6)
+ sub r4,r4,r3
+ ld r4,CPU_SPEC_FEATURES(r4)
+ /* Get the fixup table */
+ LOADADDR(r6,__start___ftr_fixup)
+ sub r6,r6,r3
+ LOADADDR(r7,__stop___ftr_fixup)
+ sub r7,r7,r3
+ /* Do the fixup */
+1: cmpld r6,r7
+ bgelr
+ addi r6,r6,32
+ ld r8,-32(r6) /* mask */
+ and r8,r8,r4
+ ld r9,-24(r6) /* value */
+ cmpld r8,r9
+ beq 1b
+ ld r8,-16(r6) /* section begin */
+ ld r9,-8(r6) /* section end */
+ subf. r9,r8,r9
+ beq 1b
+ /* write nops over the section of code */
+ /* todo: if large section, add a branch at the start of it */
+ srwi r9,r9,2
+ mtctr r9
+ sub r8,r8,r3
+ lis r0,0x60000000@h /* nop */
+3: stw r0,0(r8)
+ andi. r10,r4,CPU_FTR_SPLIT_ID_CACHE@l
+ beq 2f
+ dcbst 0,r8 /* suboptimal, but simpler */
+ sync
+ icbi 0,r8
+2: addi r8,r8,4
+ bdnz 3b
+ sync /* additional sync needed on g4 */
+ isync
+ b 1b
+
+#if defined(CONFIG_PPC_PMAC) || defined(CONFIG_PPC_MAPLE)
+/*
+ * Do an IO access in real mode
+ */
+_GLOBAL(real_readb)
+ mfmsr r7
+ ori r0,r7,MSR_DR
+ xori r0,r0,MSR_DR
+ sync
+ mtmsrd r0
+ sync
+ isync
+ mfspr r6,SPRN_HID4
+ rldicl r5,r6,32,0
+ ori r5,r5,0x100
+ rldicl r5,r5,32,0
+ sync
+ mtspr SPRN_HID4,r5
+ isync
+ slbia
+ isync
+ lbz r3,0(r3)
+ sync
+ mtspr SPRN_HID4,r6
+ isync
+ slbia
+ isync
+ mtmsrd r7
+ sync
+ isync
+ blr
+
+ /*
+ * Do an IO access in real mode
+ */
+_GLOBAL(real_writeb)
+ mfmsr r7
+ ori r0,r7,MSR_DR
+ xori r0,r0,MSR_DR
+ sync
+ mtmsrd r0
+ sync
+ isync
+ mfspr r6,SPRN_HID4
+ rldicl r5,r6,32,0
+ ori r5,r5,0x100
+ rldicl r5,r5,32,0
+ sync
+ mtspr SPRN_HID4,r5
+ isync
+ slbia
+ isync
+ stb r3,0(r4)
+ sync
+ mtspr SPRN_HID4,r6
+ isync
+ slbia
+ isync
+ mtmsrd r7
+ sync
+ isync
+ blr
+#endif /* defined(CONFIG_PPC_PMAC) || defined(CONFIG_PPC_MAPLE) */
+
+/*
+ * SCOM access functions for 970 (FX only for now)
+ *
+ * unsigned long scom970_read(unsigned int address);
+ * void scom970_write(unsigned int address, unsigned long value);
+ *
+ * The address passed in is the 24 bits register address. This code
+ * is 970 specific and will not check the status bits, so you should
+ * know what you are doing.
+ */
+_GLOBAL(scom970_read)
+ /* interrupts off */
+ mfmsr r4
+ ori r0,r4,MSR_EE
+ xori r0,r0,MSR_EE
+ mtmsrd r0,1
+
+ /* rotate 24 bits SCOM address 8 bits left and mask out it's low 8 bits
+ * (including parity). On current CPUs they must be 0'd,
+ * and finally or in RW bit
+ */
+ rlwinm r3,r3,8,0,15
+ ori r3,r3,0x8000
+
+ /* do the actual scom read */
+ sync
+ mtspr SPRN_SCOMC,r3
+ isync
+ mfspr r3,SPRN_SCOMD
+ isync
+ mfspr r0,SPRN_SCOMC
+ isync
+
+ /* XXX: fixup result on some buggy 970's (ouch ! we lost a bit, bah
+ * that's the best we can do). Not implemented yet as we don't use
+ * the scom on any of the bogus CPUs yet, but may have to be done
+ * ultimately
+ */
+
+ /* restore interrupts */
+ mtmsrd r4,1
+ blr
+
+
+_GLOBAL(scom970_write)
+ /* interrupts off */
+ mfmsr r5
+ ori r0,r5,MSR_EE
+ xori r0,r0,MSR_EE
+ mtmsrd r0,1
+
+ /* rotate 24 bits SCOM address 8 bits left and mask out it's low 8 bits
+ * (including parity). On current CPUs they must be 0'd.
+ */
+
+ rlwinm r3,r3,8,0,15
+
+ sync
+ mtspr SPRN_SCOMD,r4 /* write data */
+ isync
+ mtspr SPRN_SCOMC,r3 /* write command */
+ isync
+ mfspr 3,SPRN_SCOMC
+ isync
+
+ /* restore interrupts */
+ mtmsrd r5,1
+ blr
+
+
+/*
+ * Create a kernel thread
+ * kernel_thread(fn, arg, flags)
+ */
+_GLOBAL(kernel_thread)
+ std r29,-24(r1)
+ std r30,-16(r1)
+ stdu r1,-STACK_FRAME_OVERHEAD(r1)
+ mr r29,r3
+ mr r30,r4
+ ori r3,r5,CLONE_VM /* flags */
+ oris r3,r3,(CLONE_UNTRACED>>16)
+ li r4,0 /* new sp (unused) */
+ li r0,__NR_clone
+ sc
+ cmpdi 0,r3,0 /* parent or child? */
+ bne 1f /* return if parent */
+ li r0,0
+ stdu r0,-STACK_FRAME_OVERHEAD(r1)
+ ld r2,8(r29)
+ ld r29,0(r29)
+ mtlr r29 /* fn addr in lr */
+ mr r3,r30 /* load arg and call fn */
+ blrl
+ li r0,__NR_exit /* exit after child exits */
+ li r3,0
+ sc
+1: addi r1,r1,STACK_FRAME_OVERHEAD
+ ld r29,-24(r1)
+ ld r30,-16(r1)
+ blr
+
+/*
+ * disable_kernel_fp()
+ * Disable the FPU.
+ */
+_GLOBAL(disable_kernel_fp)
+ mfmsr r3
+ rldicl r0,r3,(63-MSR_FP_LG),1
+ rldicl r3,r0,(MSR_FP_LG+1),0
+ mtmsrd r3 /* disable use of fpu now */
+ isync
+ blr
+
+#ifdef CONFIG_ALTIVEC
+
+#if 0 /* this has no callers for now */
+/*
+ * disable_kernel_altivec()
+ * Disable the VMX.
+ */
+_GLOBAL(disable_kernel_altivec)
+ mfmsr r3
+ rldicl r0,r3,(63-MSR_VEC_LG),1
+ rldicl r3,r0,(MSR_VEC_LG+1),0
+ mtmsrd r3 /* disable use of VMX now */
+ isync
+ blr
+#endif /* 0 */
+
+/*
+ * giveup_altivec(tsk)
+ * Disable VMX for the task given as the argument,
+ * and save the vector registers in its thread_struct.
+ * Enables the VMX for use in the kernel on return.
+ */
+_GLOBAL(giveup_altivec)
+ mfmsr r5
+ oris r5,r5,MSR_VEC@h
+ mtmsrd r5 /* enable use of VMX now */
+ isync
+ cmpdi 0,r3,0
+ beqlr- /* if no previous owner, done */
+ addi r3,r3,THREAD /* want THREAD of task */
+ ld r5,PT_REGS(r3)
+ cmpdi 0,r5,0
+ SAVE_32VRS(0,r4,r3)
+ mfvscr vr0
+ li r4,THREAD_VSCR
+ stvx vr0,r4,r3
+ beq 1f
+ ld r4,_MSR-STACK_FRAME_OVERHEAD(r5)
+ lis r3,MSR_VEC@h
+ andc r4,r4,r3 /* disable FP for previous task */
+ std r4,_MSR-STACK_FRAME_OVERHEAD(r5)
+1:
+#ifndef CONFIG_SMP
+ li r5,0
+ ld r4,last_task_used_altivec@got(r2)
+ std r5,0(r4)
+#endif /* CONFIG_SMP */
+ blr
+
+#endif /* CONFIG_ALTIVEC */
+
+_GLOBAL(__setup_cpu_power3)
+ blr
+
+_GLOBAL(execve)
+ li r0,__NR_execve
+ sc
+ bnslr
+ neg r3,r3
+ blr
+
+/* kexec_wait(phys_cpu)
+ *
+ * wait for the flag to change, indicating this kernel is going away but
+ * the slave code for the next one is at addresses 0 to 100.
+ *
+ * This is used by all slaves.
+ *
+ * Physical (hardware) cpu id should be in r3.
+ */
+_GLOBAL(kexec_wait)
+ bl 1f
+1: mflr r5
+ addi r5,r5,kexec_flag-1b
+
+99: HMT_LOW
+#ifdef CONFIG_KEXEC /* use no memory without kexec */
+ lwz r4,0(r5)
+ cmpwi 0,r4,0
+ bnea 0x60
+#endif
+ b 99b
+
+/* this can be in text because we won't change it until we are
+ * running in real anyways
+ */
+kexec_flag:
+ .long 0
+
+
+#ifdef CONFIG_KEXEC
+
+/* kexec_smp_wait(void)
+ *
+ * call with interrupts off
+ * note: this is a terminal routine, it does not save lr
+ *
+ * get phys id from paca
+ * set paca id to -1 to say we got here
+ * switch to real mode
+ * join other cpus in kexec_wait(phys_id)
+ */
+_GLOBAL(kexec_smp_wait)
+ lhz r3,PACAHWCPUID(r13)
+ li r4,-1
+ sth r4,PACAHWCPUID(r13) /* let others know we left */
+ bl real_mode
+ b .kexec_wait
+
+/*
+ * switch to real mode (turn mmu off)
+ * we use the early kernel trick that the hardware ignores bits
+ * 0 and 1 (big endian) of the effective address in real mode
+ *
+ * don't overwrite r3 here, it is live for kexec_wait above.
+ */
+real_mode: /* assume normal blr return */
+1: li r9,MSR_RI
+ li r10,MSR_DR|MSR_IR
+ mflr r11 /* return address to SRR0 */
+ mfmsr r12
+ andc r9,r12,r9
+ andc r10,r12,r10
+
+ mtmsrd r9,1
+ mtspr SPRN_SRR1,r10
+ mtspr SPRN_SRR0,r11
+ rfid
+
+
+/*
+ * kexec_sequence(newstack, start, image, control, clear_all())
+ *
+ * does the grungy work with stack switching and real mode switches
+ * also does simple calls to other code
+ */
+
+_GLOBAL(kexec_sequence)
+ mflr r0
+ std r0,16(r1)
+
+ /* switch stacks to newstack -- &kexec_stack.stack */
+ stdu r1,THREAD_SIZE-112(r3)
+ mr r1,r3
+
+ li r0,0
+ std r0,16(r1)
+
+ /* save regs for local vars on new stack.
+ * yes, we won't go back, but ...
+ */
+ std r31,-8(r1)
+ std r30,-16(r1)
+ std r29,-24(r1)
+ std r28,-32(r1)
+ std r27,-40(r1)
+ std r26,-48(r1)
+ std r25,-56(r1)
+
+ stdu r1,-112-64(r1)
+
+ /* save args into preserved regs */
+ mr r31,r3 /* newstack (both) */
+ mr r30,r4 /* start (real) */
+ mr r29,r5 /* image (virt) */
+ mr r28,r6 /* control, unused */
+ mr r27,r7 /* clear_all() fn desc */
+ mr r26,r8 /* spare */
+ lhz r25,PACAHWCPUID(r13) /* get our phys cpu from paca */
+
+ /* disable interrupts, we are overwriting kernel data next */
+ mfmsr r3
+ rlwinm r3,r3,0,17,15
+ mtmsrd r3,1
+
+ /* copy dest pages, flush whole dest image */
+ mr r3,r29
+ bl .kexec_copy_flush /* (image) */
+
+ /* turn off mmu */
+ bl real_mode
+
+ /* clear out hardware hash page table and tlb */
+ ld r5,0(r27) /* deref function descriptor */
+ mtctr r5
+ bctrl /* ppc_md.hash_clear_all(void); */
+
+/*
+ * kexec image calling is:
+ * the first 0x100 bytes of the entry point are copied to 0
+ *
+ * all slaves branch to slave = 0x60 (absolute)
+ * slave(phys_cpu_id);
+ *
+ * master goes to start = entry point
+ * start(phys_cpu_id, start, 0);
+ *
+ *
+ * a wrapper is needed to call existing kernels, here is an approximate
+ * description of one method:
+ *
+ * v2: (2.6.10)
+ * start will be near the boot_block (maybe 0x100 bytes before it?)
+ * it will have a 0x60, which will b to boot_block, where it will wait
+ * and 0 will store phys into struct boot-block and load r3 from there,
+ * copy kernel 0-0x100 and tell slaves to back down to 0x60 again
+ *
+ * v1: (2.6.9)
+ * boot block will have all cpus scanning device tree to see if they
+ * are the boot cpu ?????
+ * other device tree differences (prop sizes, va vs pa, etc)...
+ */
+
+ /* copy 0x100 bytes starting at start to 0 */
+ li r3,0
+ mr r4,r30
+ li r5,0x100
+ li r6,0
+ bl .copy_and_flush /* (dest, src, copy limit, start offset) */
+1: /* assume normal blr return */
+
+ /* release other cpus to the new kernel secondary start at 0x60 */
+ mflr r5
+ li r6,1
+ stw r6,kexec_flag-1b(5)
+ mr r3,r25 # my phys cpu
+ mr r4,r30 # start, aka phys mem offset
+ mtlr 4
+ li r5,0
+ blr /* image->start(physid, image->start, 0); */
+#endif /* CONFIG_KEXEC */
diff --git a/arch/ppc64/kernel/of_device.c b/arch/powerpc/kernel/of_device.c
index 9f200f0f2ad5..7065e40e2f42 100644
--- a/arch/ppc64/kernel/of_device.c
+++ b/arch/powerpc/kernel/of_device.c
@@ -4,6 +4,8 @@
#include <linux/init.h>
#include <linux/module.h>
#include <linux/mod_devicetable.h>
+#include <linux/slab.h>
+
#include <asm/errno.h>
#include <asm/of_device.h>
@@ -184,6 +186,7 @@ void of_release_dev(struct device *dev)
struct of_device *ofdev;
ofdev = to_of_device(dev);
+ of_node_put(ofdev->node);
kfree(ofdev);
}
@@ -244,7 +247,7 @@ struct of_device* of_platform_device_create(struct device_node *np,
return NULL;
memset(dev, 0, sizeof(*dev));
- dev->node = np;
+ dev->node = of_node_get(np);
dev->dma_mask = 0xffffffffUL;
dev->dev.dma_mask = &dev->dma_mask;
dev->dev.parent = parent;
@@ -261,7 +264,6 @@ struct of_device* of_platform_device_create(struct device_node *np,
return dev;
}
-
EXPORT_SYMBOL(of_match_device);
EXPORT_SYMBOL(of_platform_bus_type);
EXPORT_SYMBOL(of_register_driver);
diff --git a/arch/ppc64/kernel/pacaData.c b/arch/powerpc/kernel/paca.c
index 33a2d8db3f21..3cf2517c5f91 100644
--- a/arch/ppc64/kernel/pacaData.c
+++ b/arch/powerpc/kernel/paca.c
@@ -15,24 +15,23 @@
#include <asm/processor.h>
#include <asm/ptrace.h>
#include <asm/page.h>
-
+#include <asm/systemcfg.h>
#include <asm/lppaca.h>
-#include <asm/iSeries/ItLpQueue.h>
+#include <asm/iseries/it_lp_queue.h>
#include <asm/paca.h>
static union {
struct systemcfg data;
u8 page[PAGE_SIZE];
-} systemcfg_store __page_aligned;
-struct systemcfg *systemcfg = &systemcfg_store.data;
-EXPORT_SYMBOL(systemcfg);
+} systemcfg_store __attribute__((__section__(".data.page.aligned")));
+struct systemcfg *_systemcfg = &systemcfg_store.data;
/* This symbol is provided by the linker - let it fill in the paca
* field correctly */
extern unsigned long __toc_start;
-/* The Paca is an array with one entry per processor. Each contains an
+/* The Paca is an array with one entry per processor. Each contains an
* lppaca, which contains the information shared between the
* hypervisor and Linux. Each also contains an ItLpRegSave area which
* is used by the hypervisor to save registers.
diff --git a/arch/ppc64/kernel/pmc.c b/arch/powerpc/kernel/pmc.c
index 63d9481c3ec2..2d333cc84082 100644
--- a/arch/ppc64/kernel/pmc.c
+++ b/arch/powerpc/kernel/pmc.c
@@ -1,7 +1,10 @@
/*
- * linux/arch/ppc64/kernel/pmc.c
+ * arch/powerpc/kernel/pmc.c
*
* Copyright (C) 2004 David Gibson, IBM Corporation.
+ * Includes code formerly from arch/ppc/kernel/perfmon.c:
+ * Author: Andy Fleming
+ * Copyright (c) 2004 Freescale Semiconductor, Inc
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -17,6 +20,20 @@
#include <asm/processor.h>
#include <asm/pmc.h>
+#if defined(CONFIG_FSL_BOOKE) && !defined(CONFIG_E200)
+static void dummy_perf(struct pt_regs *regs)
+{
+ unsigned int pmgc0 = mfpmr(PMRN_PMGC0);
+
+ pmgc0 &= ~PMGC0_PMIE;
+ mtpmr(PMRN_PMGC0, pmgc0);
+}
+#elif defined(CONFIG_PPC64) || defined(CONFIG_6xx)
+
+#ifndef MMCR0_PMAO
+#define MMCR0_PMAO 0
+#endif
+
/* Ensure exceptions are disabled */
static void dummy_perf(struct pt_regs *regs)
{
@@ -25,6 +42,11 @@ static void dummy_perf(struct pt_regs *regs)
mmcr0 &= ~(MMCR0_PMXE|MMCR0_PMAO);
mtspr(SPRN_MMCR0, mmcr0);
}
+#else
+static void dummy_perf(struct pt_regs *regs)
+{
+}
+#endif
static DEFINE_SPINLOCK(pmc_owner_lock);
static void *pmc_owner_caller; /* mostly for debugging */
@@ -66,11 +88,12 @@ void release_pmc_hardware(void)
}
EXPORT_SYMBOL_GPL(release_pmc_hardware);
+#ifdef CONFIG_PPC64
void power4_enable_pmcs(void)
{
unsigned long hid0;
- hid0 = mfspr(HID0);
+ hid0 = mfspr(SPRN_HID0);
hid0 |= 1UL << (63 - 20);
/* POWER4 requires the following sequence */
@@ -83,6 +106,7 @@ void power4_enable_pmcs(void)
"mfspr %0, %1\n"
"mfspr %0, %1\n"
"mfspr %0, %1\n"
- "isync" : "=&r" (hid0) : "i" (HID0), "0" (hid0):
+ "isync" : "=&r" (hid0) : "i" (SPRN_HID0), "0" (hid0):
"memory");
}
+#endif /* CONFIG_PPC64 */
diff --git a/include/asm-ppc64/ppc32.h b/arch/powerpc/kernel/ppc32.h
index 6b44a8caf395..90e562771791 100644
--- a/include/asm-ppc64/ppc32.h
+++ b/arch/powerpc/kernel/ppc32.h
@@ -70,18 +70,18 @@ typedef struct compat_siginfo {
#define __old_sigaction32 old_sigaction32
struct __old_sigaction32 {
- unsigned sa_handler;
+ compat_uptr_t sa_handler;
compat_old_sigset_t sa_mask;
unsigned int sa_flags;
- unsigned sa_restorer; /* not used by Linux/SPARC yet */
+ compat_uptr_t sa_restorer; /* not used by Linux/SPARC yet */
};
struct sigaction32 {
- unsigned int sa_handler; /* Really a pointer, but need to deal with 32 bits */
+ compat_uptr_t sa_handler; /* Really a pointer, but need to deal with 32 bits */
unsigned int sa_flags;
- unsigned int sa_restorer; /* Another 32 bit pointer */
+ compat_uptr_t sa_restorer; /* Another 32 bit pointer */
compat_sigset_t sa_mask; /* A 32 bit mask */
};
@@ -91,12 +91,28 @@ typedef struct sigaltstack_32 {
compat_size_t ss_size;
} stack_32_t;
+struct pt_regs32 {
+ unsigned int gpr[32];
+ unsigned int nip;
+ unsigned int msr;
+ unsigned int orig_gpr3; /* Used for restarting system calls */
+ unsigned int ctr;
+ unsigned int link;
+ unsigned int xer;
+ unsigned int ccr;
+ unsigned int mq; /* 601 only (not used at present) */
+ unsigned int trap; /* Reason for being here */
+ unsigned int dar; /* Fault registers */
+ unsigned int dsisr;
+ unsigned int result; /* Result of a system call */
+};
+
struct sigcontext32 {
unsigned int _unused[4];
int signal;
- unsigned int handler;
+ compat_uptr_t handler;
unsigned int oldmask;
- u32 regs; /* 4 byte pointer to the pt_regs32 structure. */
+ compat_uptr_t regs; /* 4 byte pointer to the pt_regs32 structure. */
};
struct mcontext32 {
@@ -111,7 +127,7 @@ struct ucontext32 {
unsigned int uc_link;
stack_32_t uc_stack;
int uc_pad[7];
- u32 uc_regs; /* points to uc_mcontext field */
+ compat_uptr_t uc_regs; /* points to uc_mcontext field */
compat_sigset_t uc_sigmask; /* mask last for extensibility */
/* glibc has 1024-bit signal masks, ours are 64-bit */
int uc_maskext[30];
diff --git a/arch/powerpc/kernel/ppc_ksyms.c b/arch/powerpc/kernel/ppc_ksyms.c
new file mode 100644
index 000000000000..5dcf4ba05ee8
--- /dev/null
+++ b/arch/powerpc/kernel/ppc_ksyms.c
@@ -0,0 +1,261 @@
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/threads.h>
+#include <linux/smp.h>
+#include <linux/sched.h>
+#include <linux/elfcore.h>
+#include <linux/string.h>
+#include <linux/interrupt.h>
+#include <linux/tty.h>
+#include <linux/vt_kern.h>
+#include <linux/nvram.h>
+#include <linux/console.h>
+#include <linux/irq.h>
+#include <linux/pci.h>
+#include <linux/delay.h>
+#include <linux/ide.h>
+#include <linux/bitops.h>
+
+#include <asm/page.h>
+#include <asm/semaphore.h>
+#include <asm/processor.h>
+#include <asm/uaccess.h>
+#include <asm/io.h>
+#include <asm/ide.h>
+#include <asm/atomic.h>
+#include <asm/checksum.h>
+#include <asm/pgtable.h>
+#include <asm/tlbflush.h>
+#include <linux/adb.h>
+#include <linux/cuda.h>
+#include <linux/pmu.h>
+#include <asm/prom.h>
+#include <asm/system.h>
+#include <asm/pci-bridge.h>
+#include <asm/irq.h>
+#include <asm/pmac_feature.h>
+#include <asm/dma.h>
+#include <asm/machdep.h>
+#include <asm/hw_irq.h>
+#include <asm/nvram.h>
+#include <asm/mmu_context.h>
+#include <asm/backlight.h>
+#include <asm/time.h>
+#include <asm/cputable.h>
+#include <asm/btext.h>
+#include <asm/div64.h>
+#include <asm/signal.h>
+
+#ifdef CONFIG_8xx
+#include <asm/commproc.h>
+#endif
+
+#ifdef CONFIG_PPC32
+extern void transfer_to_handler(void);
+extern void do_IRQ(struct pt_regs *regs);
+extern void machine_check_exception(struct pt_regs *regs);
+extern void alignment_exception(struct pt_regs *regs);
+extern void program_check_exception(struct pt_regs *regs);
+extern void single_step_exception(struct pt_regs *regs);
+extern int pmac_newworld;
+extern int sys_sigreturn(struct pt_regs *regs);
+
+EXPORT_SYMBOL(clear_pages);
+EXPORT_SYMBOL(ISA_DMA_THRESHOLD);
+EXPORT_SYMBOL(DMA_MODE_READ);
+EXPORT_SYMBOL(DMA_MODE_WRITE);
+EXPORT_SYMBOL(__div64_32);
+
+EXPORT_SYMBOL(do_signal);
+EXPORT_SYMBOL(transfer_to_handler);
+EXPORT_SYMBOL(do_IRQ);
+EXPORT_SYMBOL(machine_check_exception);
+EXPORT_SYMBOL(alignment_exception);
+EXPORT_SYMBOL(program_check_exception);
+EXPORT_SYMBOL(single_step_exception);
+EXPORT_SYMBOL(sys_sigreturn);
+#endif
+
+#if defined(CONFIG_PPC_PREP)
+EXPORT_SYMBOL(_prep_type);
+EXPORT_SYMBOL(ucSystemType);
+#endif
+
+EXPORT_SYMBOL(strcpy);
+EXPORT_SYMBOL(strncpy);
+EXPORT_SYMBOL(strcat);
+EXPORT_SYMBOL(strncat);
+EXPORT_SYMBOL(strchr);
+EXPORT_SYMBOL(strrchr);
+EXPORT_SYMBOL(strpbrk);
+EXPORT_SYMBOL(strstr);
+EXPORT_SYMBOL(strlen);
+EXPORT_SYMBOL(strnlen);
+EXPORT_SYMBOL(strcmp);
+EXPORT_SYMBOL(strncmp);
+EXPORT_SYMBOL(strcasecmp);
+
+EXPORT_SYMBOL(csum_partial);
+EXPORT_SYMBOL(csum_partial_copy_generic);
+EXPORT_SYMBOL(ip_fast_csum);
+EXPORT_SYMBOL(csum_tcpudp_magic);
+
+EXPORT_SYMBOL(__copy_tofrom_user);
+EXPORT_SYMBOL(__clear_user);
+EXPORT_SYMBOL(__strncpy_from_user);
+EXPORT_SYMBOL(__strnlen_user);
+
+EXPORT_SYMBOL(_insb);
+EXPORT_SYMBOL(_outsb);
+EXPORT_SYMBOL(_insw);
+EXPORT_SYMBOL(_outsw);
+EXPORT_SYMBOL(_insl);
+EXPORT_SYMBOL(_outsl);
+EXPORT_SYMBOL(_insw_ns);
+EXPORT_SYMBOL(_outsw_ns);
+EXPORT_SYMBOL(_insl_ns);
+EXPORT_SYMBOL(_outsl_ns);
+EXPORT_SYMBOL(ioremap);
+#ifdef CONFIG_44x
+EXPORT_SYMBOL(ioremap64);
+#endif
+EXPORT_SYMBOL(__ioremap);
+EXPORT_SYMBOL(iounmap);
+#ifdef CONFIG_PPC32
+EXPORT_SYMBOL(ioremap_bot); /* aka VMALLOC_END */
+#endif
+
+#if defined(CONFIG_PPC32) && (defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE))
+EXPORT_SYMBOL(ppc_ide_md);
+#endif
+
+#if defined(CONFIG_PCI) && defined(CONFIG_PPC32)
+EXPORT_SYMBOL(isa_io_base);
+EXPORT_SYMBOL(isa_mem_base);
+EXPORT_SYMBOL(pci_dram_offset);
+EXPORT_SYMBOL(pci_alloc_consistent);
+EXPORT_SYMBOL(pci_free_consistent);
+EXPORT_SYMBOL(pci_bus_io_base);
+EXPORT_SYMBOL(pci_bus_io_base_phys);
+EXPORT_SYMBOL(pci_bus_mem_base_phys);
+EXPORT_SYMBOL(pci_bus_to_hose);
+EXPORT_SYMBOL(pci_resource_to_bus);
+EXPORT_SYMBOL(pci_phys_to_bus);
+EXPORT_SYMBOL(pci_bus_to_phys);
+#endif /* CONFIG_PCI */
+
+#ifdef CONFIG_NOT_COHERENT_CACHE
+EXPORT_SYMBOL(flush_dcache_all);
+#endif
+
+EXPORT_SYMBOL(start_thread);
+EXPORT_SYMBOL(kernel_thread);
+
+EXPORT_SYMBOL(giveup_fpu);
+#ifdef CONFIG_ALTIVEC
+EXPORT_SYMBOL(giveup_altivec);
+#endif /* CONFIG_ALTIVEC */
+#ifdef CONFIG_SPE
+EXPORT_SYMBOL(giveup_spe);
+#endif /* CONFIG_SPE */
+
+#ifdef CONFIG_PPC64
+EXPORT_SYMBOL(__flush_icache_range);
+#else
+EXPORT_SYMBOL(flush_instruction_cache);
+EXPORT_SYMBOL(flush_icache_range);
+EXPORT_SYMBOL(flush_tlb_kernel_range);
+EXPORT_SYMBOL(flush_tlb_page);
+EXPORT_SYMBOL(_tlbie);
+#endif
+EXPORT_SYMBOL(flush_dcache_range);
+
+#ifdef CONFIG_SMP
+EXPORT_SYMBOL(smp_call_function);
+#ifdef CONFIG_PPC32
+EXPORT_SYMBOL(smp_hw_index);
+#endif
+#endif
+
+#ifdef CONFIG_ADB
+EXPORT_SYMBOL(adb_request);
+EXPORT_SYMBOL(adb_register);
+EXPORT_SYMBOL(adb_unregister);
+EXPORT_SYMBOL(adb_poll);
+EXPORT_SYMBOL(adb_try_handler_change);
+#endif /* CONFIG_ADB */
+#ifdef CONFIG_ADB_CUDA
+EXPORT_SYMBOL(cuda_request);
+EXPORT_SYMBOL(cuda_poll);
+#endif /* CONFIG_ADB_CUDA */
+#ifdef CONFIG_PPC_PMAC
+EXPORT_SYMBOL(sys_ctrler);
+#endif
+#ifdef CONFIG_VT
+EXPORT_SYMBOL(kd_mksound);
+#endif
+EXPORT_SYMBOL(to_tm);
+
+#ifdef CONFIG_PPC32
+long long __ashrdi3(long long, int);
+long long __ashldi3(long long, int);
+long long __lshrdi3(long long, int);
+EXPORT_SYMBOL(__ashrdi3);
+EXPORT_SYMBOL(__ashldi3);
+EXPORT_SYMBOL(__lshrdi3);
+#endif
+
+EXPORT_SYMBOL(memcpy);
+EXPORT_SYMBOL(memset);
+EXPORT_SYMBOL(memmove);
+EXPORT_SYMBOL(memscan);
+EXPORT_SYMBOL(memcmp);
+EXPORT_SYMBOL(memchr);
+
+#if defined(CONFIG_FB_VGA16_MODULE)
+EXPORT_SYMBOL(screen_info);
+#endif
+
+#ifdef CONFIG_PPC32
+EXPORT_SYMBOL(__delay);
+EXPORT_SYMBOL(timer_interrupt);
+EXPORT_SYMBOL(irq_desc);
+EXPORT_SYMBOL(tb_ticks_per_jiffy);
+EXPORT_SYMBOL(console_drivers);
+EXPORT_SYMBOL(cacheable_memcpy);
+#endif
+
+EXPORT_SYMBOL(__up);
+EXPORT_SYMBOL(__down);
+EXPORT_SYMBOL(__down_interruptible);
+
+#ifdef CONFIG_8xx
+EXPORT_SYMBOL(cpm_install_handler);
+EXPORT_SYMBOL(cpm_free_handler);
+#endif /* CONFIG_8xx */
+#if defined(CONFIG_8xx) || defined(CONFIG_40x) || defined(CONFIG_85xx) ||\
+ defined(CONFIG_83xx)
+EXPORT_SYMBOL(__res);
+#endif
+
+#ifdef CONFIG_PPC32
+EXPORT_SYMBOL(next_mmu_context);
+EXPORT_SYMBOL(set_context);
+#endif
+
+#ifdef CONFIG_PPC_STD_MMU_32
+extern long mol_trampoline;
+EXPORT_SYMBOL(mol_trampoline); /* For MOL */
+EXPORT_SYMBOL(flush_hash_pages); /* For MOL */
+EXPORT_SYMBOL_GPL(__handle_mm_fault); /* For MOL */
+#ifdef CONFIG_SMP
+extern int mmu_hash_lock;
+EXPORT_SYMBOL(mmu_hash_lock); /* For MOL */
+#endif /* CONFIG_SMP */
+extern long *intercept_table;
+EXPORT_SYMBOL(intercept_table);
+#endif /* CONFIG_PPC_STD_MMU_32 */
+#if defined(CONFIG_40x) || defined(CONFIG_BOOKE)
+EXPORT_SYMBOL(__mtdcr);
+EXPORT_SYMBOL(__mfdcr);
+#endif
diff --git a/arch/ppc64/kernel/proc_ppc64.c b/arch/powerpc/kernel/proc_ppc64.c
index a87c66a9652a..a1c19502fe8b 100644
--- a/arch/ppc64/kernel/proc_ppc64.c
+++ b/arch/powerpc/kernel/proc_ppc64.c
@@ -1,18 +1,16 @@
/*
- * arch/ppc64/kernel/proc_ppc64.c
- *
* Copyright (C) 2001 Mike Corrigan & Dave Engebretsen IBM 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
@@ -53,7 +51,7 @@ static int __init proc_ppc64_create(void)
if (!root)
return 1;
- if (!(systemcfg->platform & (PLATFORM_PSERIES | PLATFORM_BPA)))
+ if (!(platform_is_pseries() || _machine == PLATFORM_CELL))
return 0;
if (!proc_mkdir("rtas", root))
@@ -74,7 +72,7 @@ static int __init proc_ppc64_init(void)
if (!pde)
return 1;
pde->nlink = 1;
- pde->data = systemcfg;
+ pde->data = _systemcfg;
pde->size = PAGE_SIZE;
pde->proc_fops = &page_map_fops;
diff --git a/arch/ppc64/kernel/process.c b/arch/powerpc/kernel/process.c
index 887005358eb1..de69fb37c731 100644
--- a/arch/ppc64/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -1,5 +1,5 @@
/*
- * linux/arch/ppc64/kernel/process.c
+ * arch/ppc/kernel/process.c
*
* Derived from "arch/i386/kernel/process.c"
* Copyright (C) 1995 Linus Torvalds
@@ -7,7 +7,7 @@
* Updated and modified by Cort Dougan (cort@cs.nmt.edu) and
* Paul Mackerras (paulus@cs.anu.edu.au)
*
- * PowerPC version
+ * PowerPC version
* Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
*
* This program is free software; you can redistribute it and/or
@@ -17,7 +17,6 @@
*/
#include <linux/config.h>
-#include <linux/module.h>
#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/kernel.h>
@@ -26,15 +25,17 @@
#include <linux/smp_lock.h>
#include <linux/stddef.h>
#include <linux/unistd.h>
+#include <linux/ptrace.h>
#include <linux/slab.h>
#include <linux/user.h>
#include <linux/elf.h>
#include <linux/init.h>
-#include <linux/init_task.h>
#include <linux/prctl.h>
-#include <linux/ptrace.h>
+#include <linux/init_task.h>
+#include <linux/module.h>
#include <linux/kallsyms.h>
-#include <linux/interrupt.h>
+#include <linux/mqueue.h>
+#include <linux/hardirq.h>
#include <linux/utsname.h>
#include <linux/kprobes.h>
@@ -44,21 +45,19 @@
#include <asm/io.h>
#include <asm/processor.h>
#include <asm/mmu.h>
-#include <asm/mmu_context.h>
#include <asm/prom.h>
-#include <asm/ppcdebug.h>
#include <asm/machdep.h>
-#include <asm/iSeries/HvCallHpt.h>
-#include <asm/cputable.h>
+#ifdef CONFIG_PPC64
#include <asm/firmware.h>
-#include <asm/sections.h>
-#include <asm/tlbflush.h>
#include <asm/time.h>
-#include <asm/plpar_wrappers.h>
+#endif
+
+extern unsigned long _get_SP(void);
#ifndef CONFIG_SMP
struct task_struct *last_task_used_math = NULL;
struct task_struct *last_task_used_altivec = NULL;
+struct task_struct *last_task_used_spe = NULL;
#endif
/*
@@ -121,7 +120,6 @@ int dump_task_fpu(struct task_struct *tsk, elf_fpregset_t *fpregs)
}
#ifdef CONFIG_ALTIVEC
-
void enable_kernel_altivec(void)
{
WARN_ON(preemptible());
@@ -130,7 +128,7 @@ void enable_kernel_altivec(void)
if (current->thread.regs && (current->thread.regs->msr & MSR_VEC))
giveup_altivec(current);
else
- giveup_altivec(NULL); /* just enables FP for kernel */
+ giveup_altivec(NULL); /* just enable AltiVec for kernel - force */
#else
giveup_altivec(last_task_used_altivec);
#endif /* CONFIG_SMP */
@@ -161,36 +159,64 @@ int dump_task_altivec(struct pt_regs *regs, elf_vrregset_t *vrregs)
memcpy(vrregs, &current->thread.vr[0], sizeof(*vrregs));
return 1;
}
-
#endif /* CONFIG_ALTIVEC */
-static void set_dabr_spr(unsigned long val)
+#ifdef CONFIG_SPE
+
+void enable_kernel_spe(void)
{
- mtspr(SPRN_DABR, val);
+ WARN_ON(preemptible());
+
+#ifdef CONFIG_SMP
+ if (current->thread.regs && (current->thread.regs->msr & MSR_SPE))
+ giveup_spe(current);
+ else
+ giveup_spe(NULL); /* just enable SPE for kernel - force */
+#else
+ giveup_spe(last_task_used_spe);
+#endif /* __SMP __ */
}
+EXPORT_SYMBOL(enable_kernel_spe);
-int set_dabr(unsigned long dabr)
+void flush_spe_to_thread(struct task_struct *tsk)
{
- int ret = 0;
-
- if (firmware_has_feature(FW_FEATURE_XDABR)) {
- /* We want to catch accesses from kernel and userspace */
- unsigned long flags = H_DABRX_KERNEL|H_DABRX_USER;
- ret = plpar_set_xdabr(dabr, flags);
- } else if (firmware_has_feature(FW_FEATURE_DABR)) {
- ret = plpar_set_dabr(dabr);
- } else {
- set_dabr_spr(dabr);
+ if (tsk->thread.regs) {
+ preempt_disable();
+ if (tsk->thread.regs->msr & MSR_SPE) {
+#ifdef CONFIG_SMP
+ BUG_ON(tsk != current);
+#endif
+ giveup_spe(current);
+ }
+ preempt_enable();
}
+}
- return ret;
+int dump_spe(struct pt_regs *regs, elf_vrregset_t *evrregs)
+{
+ flush_spe_to_thread(current);
+ /* We copy u32 evr[32] + u64 acc + u32 spefscr -> 35 */
+ memcpy(evrregs, &current->thread.evr[0], sizeof(u32) * 35);
+ return 1;
+}
+#endif /* CONFIG_SPE */
+
+int set_dabr(unsigned long dabr)
+{
+ if (ppc_md.set_dabr)
+ return ppc_md.set_dabr(dabr);
+
+ mtspr(SPRN_DABR, dabr);
+ return 0;
}
+#ifdef CONFIG_PPC64
DEFINE_PER_CPU(struct cpu_usage, cpu_usage_array);
static DEFINE_PER_CPU(unsigned long, current_dabr);
+#endif
struct task_struct *__switch_to(struct task_struct *prev,
- struct task_struct *new)
+ struct task_struct *new)
{
struct thread_struct *new_thread, *old_thread;
unsigned long flags;
@@ -200,7 +226,7 @@ struct task_struct *__switch_to(struct task_struct *prev,
/* avoid complexity of lazy save/restore of fpu
* by just saving it every time we switch out if
* this task used the fpu during the last quantum.
- *
+ *
* If it tries to use the fpu again, it'll trap and
* reload its fp regs. So we don't have to do a restore
* every switch, just a save.
@@ -209,31 +235,65 @@ struct task_struct *__switch_to(struct task_struct *prev,
if (prev->thread.regs && (prev->thread.regs->msr & MSR_FP))
giveup_fpu(prev);
#ifdef CONFIG_ALTIVEC
+ /*
+ * If the previous thread used altivec in the last quantum
+ * (thus changing altivec regs) then save them.
+ * We used to check the VRSAVE register but not all apps
+ * set it, so we don't rely on it now (and in fact we need
+ * to save & restore VSCR even if VRSAVE == 0). -- paulus
+ *
+ * On SMP we always save/restore altivec regs just to avoid the
+ * complexity of changing processors.
+ * -- Cort
+ */
if (prev->thread.regs && (prev->thread.regs->msr & MSR_VEC))
giveup_altivec(prev);
#endif /* CONFIG_ALTIVEC */
-#endif /* CONFIG_SMP */
+#ifdef CONFIG_SPE
+ /*
+ * If the previous thread used spe in the last quantum
+ * (thus changing spe regs) then save them.
+ *
+ * On SMP we always save/restore spe regs just to avoid the
+ * complexity of changing processors.
+ */
+ if ((prev->thread.regs && (prev->thread.regs->msr & MSR_SPE)))
+ giveup_spe(prev);
+#endif /* CONFIG_SPE */
-#if defined(CONFIG_ALTIVEC) && !defined(CONFIG_SMP)
+#else /* CONFIG_SMP */
+#ifdef CONFIG_ALTIVEC
/* Avoid the trap. On smp this this never happens since
* we don't set last_task_used_altivec -- Cort
*/
if (new->thread.regs && last_task_used_altivec == new)
new->thread.regs->msr |= MSR_VEC;
#endif /* CONFIG_ALTIVEC */
+#ifdef CONFIG_SPE
+ /* Avoid the trap. On smp this this never happens since
+ * we don't set last_task_used_spe
+ */
+ if (new->thread.regs && last_task_used_spe == new)
+ new->thread.regs->msr |= MSR_SPE;
+#endif /* CONFIG_SPE */
+
+#endif /* CONFIG_SMP */
+#ifdef CONFIG_PPC64 /* for now */
if (unlikely(__get_cpu_var(current_dabr) != new->thread.dabr)) {
set_dabr(new->thread.dabr);
__get_cpu_var(current_dabr) = new->thread.dabr;
}
flush_tlb_pending();
+#endif
new_thread = &new->thread;
old_thread = &current->thread;
- /* Collect purr utilization data per process and per processor
- * wise purr is nothing but processor time base
+#ifdef CONFIG_PPC64
+ /*
+ * Collect processor utilization data per process
*/
if (firmware_has_feature(FW_FEATURE_SPLPAR)) {
struct cpu_usage *cu = &__get_cpu_var(cpu_usage_array);
@@ -243,6 +303,7 @@ struct task_struct *__switch_to(struct task_struct *prev,
old_thread->accum_tb += (current_tb - start_tb);
new_thread->start_tb = current_tb;
}
+#endif
local_irq_save(flags);
last = _switch(old_thread, new_thread);
@@ -254,6 +315,13 @@ struct task_struct *__switch_to(struct task_struct *prev,
static int instructions_to_print = 16;
+#ifdef CONFIG_PPC64
+#define BAD_PC(pc) ((REGION_ID(pc) != KERNEL_REGION_ID) && \
+ (REGION_ID(pc) != VMALLOC_REGION_ID))
+#else
+#define BAD_PC(pc) ((pc) < KERNELBASE)
+#endif
+
static void show_instructions(struct pt_regs *regs)
{
int i;
@@ -268,9 +336,7 @@ static void show_instructions(struct pt_regs *regs)
if (!(i % 8))
printk("\n");
- if (((REGION_ID(pc) != KERNEL_REGION_ID) &&
- (REGION_ID(pc) != VMALLOC_REGION_ID)) ||
- __get_user(instr, (unsigned int *)pc)) {
+ if (BAD_PC(pc) || __get_user(instr, (unsigned int *)pc)) {
printk("XXXXXXXX ");
} else {
if (regs->nip == pc)
@@ -285,50 +351,82 @@ static void show_instructions(struct pt_regs *regs)
printk("\n");
}
+static struct regbit {
+ unsigned long bit;
+ const char *name;
+} msr_bits[] = {
+ {MSR_EE, "EE"},
+ {MSR_PR, "PR"},
+ {MSR_FP, "FP"},
+ {MSR_ME, "ME"},
+ {MSR_IR, "IR"},
+ {MSR_DR, "DR"},
+ {0, NULL}
+};
+
+static void printbits(unsigned long val, struct regbit *bits)
+{
+ const char *sep = "";
+
+ printk("<");
+ for (; bits->bit; ++bits)
+ if (val & bits->bit) {
+ printk("%s%s", sep, bits->name);
+ sep = ",";
+ }
+ printk(">");
+}
+
+#ifdef CONFIG_PPC64
+#define REG "%016lX"
+#define REGS_PER_LINE 4
+#define LAST_VOLATILE 13
+#else
+#define REG "%08lX"
+#define REGS_PER_LINE 8
+#define LAST_VOLATILE 12
+#endif
+
void show_regs(struct pt_regs * regs)
{
- int i;
- unsigned long trap;
+ int i, trap;
- printk("NIP: %016lX XER: %08X LR: %016lX CTR: %016lX\n",
- regs->nip, (unsigned int)regs->xer, regs->link, regs->ctr);
+ printk("NIP: "REG" LR: "REG" CTR: "REG"\n",
+ regs->nip, regs->link, regs->ctr);
printk("REGS: %p TRAP: %04lx %s (%s)\n",
regs, regs->trap, print_tainted(), system_utsname.release);
- printk("MSR: %016lx EE: %01x PR: %01x FP: %01x ME: %01x "
- "IR/DR: %01x%01x CR: %08X\n",
- regs->msr, regs->msr&MSR_EE ? 1 : 0, regs->msr&MSR_PR ? 1 : 0,
- regs->msr & MSR_FP ? 1 : 0,regs->msr&MSR_ME ? 1 : 0,
- regs->msr&MSR_IR ? 1 : 0,
- regs->msr&MSR_DR ? 1 : 0,
- (unsigned int)regs->ccr);
+ printk("MSR: "REG" ", regs->msr);
+ printbits(regs->msr, msr_bits);
+ printk(" CR: %08lX XER: %08lX\n", regs->ccr, regs->xer);
trap = TRAP(regs);
- printk("DAR: %016lx DSISR: %016lx\n", regs->dar, regs->dsisr);
- printk("TASK: %p[%d] '%s' THREAD: %p",
+ if (trap == 0x300 || trap == 0x600)
+ printk("DAR: "REG", DSISR: "REG"\n", regs->dar, regs->dsisr);
+ printk("TASK = %p[%d] '%s' THREAD: %p",
current, current->pid, current->comm, current->thread_info);
#ifdef CONFIG_SMP
printk(" CPU: %d", smp_processor_id());
#endif /* CONFIG_SMP */
- for (i = 0; i < 32; i++) {
- if ((i % 4) == 0) {
+ for (i = 0; i < 32; i++) {
+ if ((i % REGS_PER_LINE) == 0)
printk("\n" KERN_INFO "GPR%02d: ", i);
- }
-
- printk("%016lX ", regs->gpr[i]);
- if (i == 13 && !FULL_REGS(regs))
+ printk(REG " ", regs->gpr[i]);
+ if (i == LAST_VOLATILE && !FULL_REGS(regs))
break;
}
printk("\n");
+#ifdef CONFIG_KALLSYMS
/*
* Lookup NIP late so we have the best change of getting the
* above info out without failing
*/
- printk("NIP [%016lx] ", regs->nip);
+ printk("NIP ["REG"] ", regs->nip);
print_symbol("%s\n", regs->nip);
- printk("LR [%016lx] ", regs->link);
+ printk("LR ["REG"] ", regs->link);
print_symbol("%s\n", regs->link);
- show_stack(current, (unsigned long *)regs->gpr[1]);
+#endif
+ show_stack(current, (unsigned long *) regs->gpr[1]);
if (!user_mode(regs))
show_instructions(regs);
}
@@ -344,16 +442,22 @@ void exit_thread(void)
if (last_task_used_altivec == current)
last_task_used_altivec = NULL;
#endif /* CONFIG_ALTIVEC */
+#ifdef CONFIG_SPE
+ if (last_task_used_spe == current)
+ last_task_used_spe = NULL;
+#endif
#endif /* CONFIG_SMP */
}
void flush_thread(void)
{
+#ifdef CONFIG_PPC64
struct thread_info *t = current_thread_info();
- kprobe_flush_task(current);
if (t->flags & _TIF_ABI_PENDING)
t->flags ^= (_TIF_ABI_PENDING | _TIF_32BIT);
+#endif
+ kprobe_flush_task(current);
#ifndef CONFIG_SMP
if (last_task_used_math == current)
@@ -362,12 +466,18 @@ void flush_thread(void)
if (last_task_used_altivec == current)
last_task_used_altivec = NULL;
#endif /* CONFIG_ALTIVEC */
+#ifdef CONFIG_SPE
+ if (last_task_used_spe == current)
+ last_task_used_spe = NULL;
+#endif
#endif /* CONFIG_SMP */
+#ifdef CONFIG_PPC64 /* for now */
if (current->thread.dabr) {
current->thread.dabr = 0;
set_dabr(0);
}
+#endif
}
void
@@ -375,7 +485,6 @@ release_thread(struct task_struct *t)
{
}
-
/*
* This gets called before we allocate a new thread and copy
* the current task into it.
@@ -384,36 +493,44 @@ void prepare_to_copy(struct task_struct *tsk)
{
flush_fp_to_thread(current);
flush_altivec_to_thread(current);
+ flush_spe_to_thread(current);
}
/*
* Copy a thread..
*/
-int
-copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
- unsigned long unused, struct task_struct *p, struct pt_regs *regs)
+int copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
+ unsigned long unused, struct task_struct *p,
+ struct pt_regs *regs)
{
struct pt_regs *childregs, *kregs;
extern void ret_from_fork(void);
unsigned long sp = (unsigned long)p->thread_info + THREAD_SIZE;
+ CHECK_FULL_REGS(regs);
/* Copy registers */
sp -= sizeof(struct pt_regs);
childregs = (struct pt_regs *) sp;
*childregs = *regs;
if ((childregs->msr & MSR_PR) == 0) {
- /* for kernel thread, set stackptr in new task */
+ /* for kernel thread, set `current' and stackptr in new task */
childregs->gpr[1] = sp + sizeof(struct pt_regs);
- p->thread.regs = NULL; /* no user register state */
+#ifdef CONFIG_PPC32
+ childregs->gpr[2] = (unsigned long) p;
+#else
clear_ti_thread_flag(p->thread_info, TIF_32BIT);
+#endif
+ p->thread.regs = NULL; /* no user register state */
} else {
childregs->gpr[1] = usp;
p->thread.regs = childregs;
if (clone_flags & CLONE_SETTLS) {
- if (test_thread_flag(TIF_32BIT))
- childregs->gpr[2] = childregs->gpr[6];
- else
+#ifdef CONFIG_PPC64
+ if (!test_thread_flag(TIF_32BIT))
childregs->gpr[13] = childregs->gpr[6];
+ else
+#endif
+ childregs->gpr[2] = childregs->gpr[6];
}
}
childregs->gpr[3] = 0; /* Result from fork() */
@@ -431,14 +548,14 @@ copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
kregs = (struct pt_regs *) sp;
sp -= STACK_FRAME_OVERHEAD;
p->thread.ksp = sp;
+
+#ifdef CONFIG_PPC64
if (cpu_has_feature(CPU_FTR_SLB)) {
unsigned long sp_vsid = get_kernel_vsid(sp);
+ unsigned long llp = mmu_psize_defs[mmu_linear_psize].sllp;
sp_vsid <<= SLB_VSID_SHIFT;
- sp_vsid |= SLB_VSID_KERNEL;
- if (cpu_has_feature(CPU_FTR_16M_PAGE))
- sp_vsid |= SLB_VSID_L;
-
+ sp_vsid |= SLB_VSID_KERNEL | llp;
p->thread.ksp_vsid = sp_vsid;
}
@@ -449,6 +566,10 @@ copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
* function.
*/
kregs->nip = *((unsigned long *)ret_from_fork);
+#else
+ kregs->nip = (unsigned long)ret_from_fork;
+ p->thread.last_syscall = -1;
+#endif
return 0;
}
@@ -456,30 +577,17 @@ copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
/*
* Set up a thread for executing a new program
*/
-void start_thread(struct pt_regs *regs, unsigned long fdptr, unsigned long sp)
+void start_thread(struct pt_regs *regs, unsigned long start, unsigned long sp)
{
- unsigned long entry, toc, load_addr = regs->gpr[2];
+#ifdef CONFIG_PPC64
+ unsigned long load_addr = regs->gpr[2]; /* saved by ELF_PLAT_INIT */
+#endif
- /* fdptr is a relocated pointer to the function descriptor for
- * the elf _start routine. The first entry in the function
- * descriptor is the entry address of _start and the second
- * entry is the TOC value we need to use.
- */
set_fs(USER_DS);
- __get_user(entry, (unsigned long __user *)fdptr);
- __get_user(toc, (unsigned long __user *)fdptr+1);
-
- /* Check whether the e_entry function descriptor entries
- * need to be relocated before we can use them.
- */
- if (load_addr != 0) {
- entry += load_addr;
- toc += load_addr;
- }
/*
* If we exec out of a kernel thread then thread.regs will not be
- * set. Do it now.
+ * set. Do it now.
*/
if (!current->thread.regs) {
unsigned long childregs = (unsigned long)current->thread_info +
@@ -488,36 +596,101 @@ void start_thread(struct pt_regs *regs, unsigned long fdptr, unsigned long sp)
current->thread.regs = (struct pt_regs *)childregs;
}
- regs->nip = entry;
+ memset(regs->gpr, 0, sizeof(regs->gpr));
+ regs->ctr = 0;
+ regs->link = 0;
+ regs->xer = 0;
+ regs->ccr = 0;
regs->gpr[1] = sp;
- regs->gpr[2] = toc;
- regs->msr = MSR_USER64;
+
+#ifdef CONFIG_PPC32
+ regs->mq = 0;
+ regs->nip = start;
+ regs->msr = MSR_USER;
+#else
+ if (!test_thread_flag(TIF_32BIT)) {
+ unsigned long entry, toc;
+
+ /* start is a relocated pointer to the function descriptor for
+ * the elf _start routine. The first entry in the function
+ * descriptor is the entry address of _start and the second
+ * entry is the TOC value we need to use.
+ */
+ __get_user(entry, (unsigned long __user *)start);
+ __get_user(toc, (unsigned long __user *)start+1);
+
+ /* Check whether the e_entry function descriptor entries
+ * need to be relocated before we can use them.
+ */
+ if (load_addr != 0) {
+ entry += load_addr;
+ toc += load_addr;
+ }
+ regs->nip = entry;
+ regs->gpr[2] = toc;
+ regs->msr = MSR_USER64;
+ } else {
+ regs->nip = start;
+ regs->gpr[2] = 0;
+ regs->msr = MSR_USER32;
+ }
+#endif
+
#ifndef CONFIG_SMP
if (last_task_used_math == current)
- last_task_used_math = 0;
-#endif /* CONFIG_SMP */
- memset(current->thread.fpr, 0, sizeof(current->thread.fpr));
- current->thread.fpscr = 0;
+ last_task_used_math = NULL;
#ifdef CONFIG_ALTIVEC
-#ifndef CONFIG_SMP
if (last_task_used_altivec == current)
- last_task_used_altivec = 0;
+ last_task_used_altivec = NULL;
+#endif
+#ifdef CONFIG_SPE
+ if (last_task_used_spe == current)
+ last_task_used_spe = NULL;
+#endif
#endif /* CONFIG_SMP */
+ memset(current->thread.fpr, 0, sizeof(current->thread.fpr));
+ current->thread.fpscr.val = 0;
+#ifdef CONFIG_ALTIVEC
memset(current->thread.vr, 0, sizeof(current->thread.vr));
- current->thread.vscr.u[0] = 0;
- current->thread.vscr.u[1] = 0;
- current->thread.vscr.u[2] = 0;
+ memset(&current->thread.vscr, 0, sizeof(current->thread.vscr));
current->thread.vscr.u[3] = 0x00010000; /* Java mode disabled */
current->thread.vrsave = 0;
current->thread.used_vr = 0;
#endif /* CONFIG_ALTIVEC */
+#ifdef CONFIG_SPE
+ memset(current->thread.evr, 0, sizeof(current->thread.evr));
+ current->thread.acc = 0;
+ current->thread.spefscr = 0;
+ current->thread.used_spe = 0;
+#endif /* CONFIG_SPE */
}
-EXPORT_SYMBOL(start_thread);
+
+#define PR_FP_ALL_EXCEPT (PR_FP_EXC_DIV | PR_FP_EXC_OVF | PR_FP_EXC_UND \
+ | PR_FP_EXC_RES | PR_FP_EXC_INV)
int set_fpexc_mode(struct task_struct *tsk, unsigned int val)
{
struct pt_regs *regs = tsk->thread.regs;
+ /* This is a bit hairy. If we are an SPE enabled processor
+ * (have embedded fp) we store the IEEE exception enable flags in
+ * fpexc_mode. fpexc_mode is also used for setting FP exception
+ * mode (asyn, precise, disabled) for 'Classic' FP. */
+ if (val & PR_FP_EXC_SW_ENABLE) {
+#ifdef CONFIG_SPE
+ tsk->thread.fpexc_mode = val &
+ (PR_FP_EXC_SW_ENABLE | PR_FP_ALL_EXCEPT);
+ return 0;
+#else
+ return -EINVAL;
+#endif
+ }
+
+ /* on a CONFIG_SPE this does not hurt us. The bits that
+ * __pack_fe01 use do not overlap with bits used for
+ * PR_FP_EXC_SW_ENABLE. Additionally, the MSR[FE0,FE1] bits
+ * on CONFIG_SPE implementations are reserved so writing to
+ * them does not change anything */
if (val > PR_FP_EXC_PRECISE)
return -EINVAL;
tsk->thread.fpexc_mode = __pack_fe01(val);
@@ -531,38 +704,41 @@ int get_fpexc_mode(struct task_struct *tsk, unsigned long adr)
{
unsigned int val;
- val = __unpack_fe01(tsk->thread.fpexc_mode);
+ if (tsk->thread.fpexc_mode & PR_FP_EXC_SW_ENABLE)
+#ifdef CONFIG_SPE
+ val = tsk->thread.fpexc_mode;
+#else
+ return -EINVAL;
+#endif
+ else
+ val = __unpack_fe01(tsk->thread.fpexc_mode);
return put_user(val, (unsigned int __user *) adr);
}
-int sys_clone(unsigned long clone_flags, unsigned long p2, unsigned long p3,
- unsigned long p4, unsigned long p5, unsigned long p6,
+#define TRUNC_PTR(x) ((typeof(x))(((unsigned long)(x)) & 0xffffffff))
+
+int sys_clone(unsigned long clone_flags, unsigned long usp,
+ int __user *parent_tidp, void __user *child_threadptr,
+ int __user *child_tidp, int p6,
struct pt_regs *regs)
{
- unsigned long parent_tidptr = 0;
- unsigned long child_tidptr = 0;
-
- if (p2 == 0)
- p2 = regs->gpr[1]; /* stack pointer for child */
-
- if (clone_flags & (CLONE_PARENT_SETTID | CLONE_CHILD_SETTID |
- CLONE_CHILD_CLEARTID)) {
- parent_tidptr = p3;
- child_tidptr = p5;
- if (test_thread_flag(TIF_32BIT)) {
- parent_tidptr &= 0xffffffff;
- child_tidptr &= 0xffffffff;
- }
+ CHECK_FULL_REGS(regs);
+ if (usp == 0)
+ usp = regs->gpr[1]; /* stack pointer for child */
+#ifdef CONFIG_PPC64
+ if (test_thread_flag(TIF_32BIT)) {
+ parent_tidp = TRUNC_PTR(parent_tidp);
+ child_tidp = TRUNC_PTR(child_tidp);
}
-
- return do_fork(clone_flags, p2, regs, 0,
- (int __user *)parent_tidptr, (int __user *)child_tidptr);
+#endif
+ return do_fork(clone_flags, usp, regs, 0, parent_tidp, child_tidp);
}
int sys_fork(unsigned long p1, unsigned long p2, unsigned long p3,
unsigned long p4, unsigned long p5, unsigned long p6,
struct pt_regs *regs)
{
+ CHECK_FULL_REGS(regs);
return do_fork(SIGCHLD, regs->gpr[1], regs, 0, NULL, NULL);
}
@@ -570,8 +746,9 @@ int sys_vfork(unsigned long p1, unsigned long p2, unsigned long p3,
unsigned long p4, unsigned long p5, unsigned long p6,
struct pt_regs *regs)
{
- return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->gpr[1], regs, 0,
- NULL, NULL);
+ CHECK_FULL_REGS(regs);
+ return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->gpr[1],
+ regs, 0, NULL, NULL);
}
int sys_execve(unsigned long a0, unsigned long a1, unsigned long a2,
@@ -579,30 +756,27 @@ int sys_execve(unsigned long a0, unsigned long a1, unsigned long a2,
struct pt_regs *regs)
{
int error;
- char * filename;
-
+ char *filename;
+
filename = getname((char __user *) a0);
error = PTR_ERR(filename);
if (IS_ERR(filename))
goto out;
flush_fp_to_thread(current);
flush_altivec_to_thread(current);
+ flush_spe_to_thread(current);
error = do_execve(filename, (char __user * __user *) a1,
- (char __user * __user *) a2, regs);
-
+ (char __user * __user *) a2, regs);
if (error == 0) {
task_lock(current);
current->ptrace &= ~PT_DTRACE;
task_unlock(current);
}
putname(filename);
-
out:
return error;
}
-static int kstack_depth_to_print = 64;
-
static int validate_sp(unsigned long sp, struct task_struct *p,
unsigned long nbytes)
{
@@ -627,6 +801,20 @@ static int validate_sp(unsigned long sp, struct task_struct *p,
return 0;
}
+#ifdef CONFIG_PPC64
+#define MIN_STACK_FRAME 112 /* same as STACK_FRAME_OVERHEAD, in fact */
+#define FRAME_LR_SAVE 2
+#define INT_FRAME_SIZE (sizeof(struct pt_regs) + STACK_FRAME_OVERHEAD + 288)
+#define REGS_MARKER 0x7265677368657265ul
+#define FRAME_MARKER 12
+#else
+#define MIN_STACK_FRAME 16
+#define FRAME_LR_SAVE 1
+#define INT_FRAME_SIZE (sizeof(struct pt_regs) + STACK_FRAME_OVERHEAD)
+#define REGS_MARKER 0x72656773ul
+#define FRAME_MARKER 2
+#endif
+
unsigned long get_wchan(struct task_struct *p)
{
unsigned long ip, sp;
@@ -636,15 +824,15 @@ unsigned long get_wchan(struct task_struct *p)
return 0;
sp = p->thread.ksp;
- if (!validate_sp(sp, p, 112))
+ if (!validate_sp(sp, p, MIN_STACK_FRAME))
return 0;
do {
sp = *(unsigned long *)sp;
- if (!validate_sp(sp, p, 112))
+ if (!validate_sp(sp, p, MIN_STACK_FRAME))
return 0;
if (count > 0) {
- ip = *(unsigned long *)(sp + 16);
+ ip = ((unsigned long *)sp)[FRAME_LR_SAVE];
if (!in_sched_functions(ip))
return ip;
}
@@ -653,33 +841,35 @@ unsigned long get_wchan(struct task_struct *p)
}
EXPORT_SYMBOL(get_wchan);
-void show_stack(struct task_struct *p, unsigned long *_sp)
+static int kstack_depth_to_print = 64;
+
+void show_stack(struct task_struct *tsk, unsigned long *stack)
{
- unsigned long ip, newsp, lr;
+ unsigned long sp, ip, lr, newsp;
int count = 0;
- unsigned long sp = (unsigned long)_sp;
int firstframe = 1;
+ sp = (unsigned long) stack;
+ if (tsk == NULL)
+ tsk = current;
if (sp == 0) {
- if (p) {
- sp = p->thread.ksp;
- } else {
- sp = __get_SP();
- p = current;
- }
+ if (tsk == current)
+ asm("mr %0,1" : "=r" (sp));
+ else
+ sp = tsk->thread.ksp;
}
lr = 0;
printk("Call Trace:\n");
do {
- if (!validate_sp(sp, p, 112))
+ if (!validate_sp(sp, tsk, MIN_STACK_FRAME))
return;
- _sp = (unsigned long *) sp;
- newsp = _sp[0];
- ip = _sp[2];
+ stack = (unsigned long *) sp;
+ newsp = stack[0];
+ ip = stack[FRAME_LR_SAVE];
if (!firstframe || ip != lr) {
- printk("[%016lx] [%016lx] ", sp, ip);
+ printk("["REG"] ["REG"] ", sp, ip);
print_symbol("%s", ip);
if (firstframe)
printk(" (unreliable)");
@@ -691,8 +881,8 @@ void show_stack(struct task_struct *p, unsigned long *_sp)
* See if this is an exception frame.
* We look for the "regshere" marker in the current frame.
*/
- if (validate_sp(sp, p, sizeof(struct pt_regs) + 400)
- && _sp[12] == 0x7265677368657265ul) {
+ if (validate_sp(sp, tsk, INT_FRAME_SIZE)
+ && stack[FRAME_MARKER] == REGS_MARKER) {
struct pt_regs *regs = (struct pt_regs *)
(sp + STACK_FRAME_OVERHEAD);
printk("--- Exception: %lx", regs->trap);
@@ -708,6 +898,6 @@ void show_stack(struct task_struct *p, unsigned long *_sp)
void dump_stack(void)
{
- show_stack(current, (unsigned long *)__get_SP());
+ show_stack(current, NULL);
}
EXPORT_SYMBOL(dump_stack);
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
new file mode 100644
index 000000000000..6a5b468edb4d
--- /dev/null
+++ b/arch/powerpc/kernel/prom.c
@@ -0,0 +1,2168 @@
+/*
+ * Procedures for creating, accessing and interpreting the device tree.
+ *
+ * Paul Mackerras August 1996.
+ * Copyright (C) 1996-2005 Paul Mackerras.
+ *
+ * Adapted for 64bit PowerPC by Dave Engebretsen and Peter Bergner.
+ * {engebret|bergner}@us.ibm.com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#undef DEBUG
+
+#include <stdarg.h>
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/init.h>
+#include <linux/threads.h>
+#include <linux/spinlock.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/stringify.h>
+#include <linux/delay.h>
+#include <linux/initrd.h>
+#include <linux/bitops.h>
+#include <linux/module.h>
+
+#include <asm/prom.h>
+#include <asm/rtas.h>
+#include <asm/lmb.h>
+#include <asm/page.h>
+#include <asm/processor.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+#include <asm/smp.h>
+#include <asm/system.h>
+#include <asm/mmu.h>
+#include <asm/pgtable.h>
+#include <asm/pci.h>
+#include <asm/iommu.h>
+#include <asm/btext.h>
+#include <asm/sections.h>
+#include <asm/machdep.h>
+#include <asm/pSeries_reconfig.h>
+#include <asm/pci-bridge.h>
+
+#ifdef DEBUG
+#define DBG(fmt...) printk(KERN_ERR fmt)
+#else
+#define DBG(fmt...)
+#endif
+
+struct pci_reg_property {
+ struct pci_address addr;
+ u32 size_hi;
+ u32 size_lo;
+};
+
+struct isa_reg_property {
+ u32 space;
+ u32 address;
+ u32 size;
+};
+
+
+typedef int interpret_func(struct device_node *, unsigned long *,
+ int, int, int);
+
+static int __initdata dt_root_addr_cells;
+static int __initdata dt_root_size_cells;
+
+#ifdef CONFIG_PPC64
+static int __initdata iommu_is_off;
+int __initdata iommu_force_on;
+unsigned long tce_alloc_start, tce_alloc_end;
+#endif
+
+typedef u32 cell_t;
+
+#if 0
+static struct boot_param_header *initial_boot_params __initdata;
+#else
+struct boot_param_header *initial_boot_params;
+#endif
+
+static struct device_node *allnodes = NULL;
+
+/* use when traversing tree through the allnext, child, sibling,
+ * or parent members of struct device_node.
+ */
+static DEFINE_RWLOCK(devtree_lock);
+
+/* export that to outside world */
+struct device_node *of_chosen;
+
+struct device_node *dflt_interrupt_controller;
+int num_interrupt_controllers;
+
+/*
+ * Wrapper for allocating memory for various data that needs to be
+ * attached to device nodes as they are processed at boot or when
+ * added to the device tree later (e.g. DLPAR). At boot there is
+ * already a region reserved so we just increment *mem_start by size;
+ * otherwise we call kmalloc.
+ */
+static void * prom_alloc(unsigned long size, unsigned long *mem_start)
+{
+ unsigned long tmp;
+
+ if (!mem_start)
+ return kmalloc(size, GFP_KERNEL);
+
+ tmp = *mem_start;
+ *mem_start += size;
+ return (void *)tmp;
+}
+
+/*
+ * Find the device_node with a given phandle.
+ */
+static struct device_node * find_phandle(phandle ph)
+{
+ struct device_node *np;
+
+ for (np = allnodes; np != 0; np = np->allnext)
+ if (np->linux_phandle == ph)
+ return np;
+ return NULL;
+}
+
+/*
+ * Find the interrupt parent of a node.
+ */
+static struct device_node * __devinit intr_parent(struct device_node *p)
+{
+ phandle *parp;
+
+ parp = (phandle *) get_property(p, "interrupt-parent", NULL);
+ if (parp == NULL)
+ return p->parent;
+ p = find_phandle(*parp);
+ if (p != NULL)
+ return p;
+ /*
+ * On a powermac booted with BootX, we don't get to know the
+ * phandles for any nodes, so find_phandle will return NULL.
+ * Fortunately these machines only have one interrupt controller
+ * so there isn't in fact any ambiguity. -- paulus
+ */
+ if (num_interrupt_controllers == 1)
+ p = dflt_interrupt_controller;
+ return p;
+}
+
+/*
+ * Find out the size of each entry of the interrupts property
+ * for a node.
+ */
+int __devinit prom_n_intr_cells(struct device_node *np)
+{
+ struct device_node *p;
+ unsigned int *icp;
+
+ for (p = np; (p = intr_parent(p)) != NULL; ) {
+ icp = (unsigned int *)
+ get_property(p, "#interrupt-cells", NULL);
+ if (icp != NULL)
+ return *icp;
+ if (get_property(p, "interrupt-controller", NULL) != NULL
+ || get_property(p, "interrupt-map", NULL) != NULL) {
+ printk("oops, node %s doesn't have #interrupt-cells\n",
+ p->full_name);
+ return 1;
+ }
+ }
+#ifdef DEBUG_IRQ
+ printk("prom_n_intr_cells failed for %s\n", np->full_name);
+#endif
+ return 1;
+}
+
+/*
+ * Map an interrupt from a device up to the platform interrupt
+ * descriptor.
+ */
+static int __devinit map_interrupt(unsigned int **irq, struct device_node **ictrler,
+ struct device_node *np, unsigned int *ints,
+ int nintrc)
+{
+ struct device_node *p, *ipar;
+ unsigned int *imap, *imask, *ip;
+ int i, imaplen, match;
+ int newintrc = 0, newaddrc = 0;
+ unsigned int *reg;
+ int naddrc;
+
+ reg = (unsigned int *) get_property(np, "reg", NULL);
+ naddrc = prom_n_addr_cells(np);
+ p = intr_parent(np);
+ while (p != NULL) {
+ if (get_property(p, "interrupt-controller", NULL) != NULL)
+ /* this node is an interrupt controller, stop here */
+ break;
+ imap = (unsigned int *)
+ get_property(p, "interrupt-map", &imaplen);
+ if (imap == NULL) {
+ p = intr_parent(p);
+ continue;
+ }
+ imask = (unsigned int *)
+ get_property(p, "interrupt-map-mask", NULL);
+ if (imask == NULL) {
+ printk("oops, %s has interrupt-map but no mask\n",
+ p->full_name);
+ return 0;
+ }
+ imaplen /= sizeof(unsigned int);
+ match = 0;
+ ipar = NULL;
+ while (imaplen > 0 && !match) {
+ /* check the child-interrupt field */
+ match = 1;
+ for (i = 0; i < naddrc && match; ++i)
+ match = ((reg[i] ^ imap[i]) & imask[i]) == 0;
+ for (; i < naddrc + nintrc && match; ++i)
+ match = ((ints[i-naddrc] ^ imap[i]) & imask[i]) == 0;
+ imap += naddrc + nintrc;
+ imaplen -= naddrc + nintrc;
+ /* grab the interrupt parent */
+ ipar = find_phandle((phandle) *imap++);
+ --imaplen;
+ if (ipar == NULL && num_interrupt_controllers == 1)
+ /* cope with BootX not giving us phandles */
+ ipar = dflt_interrupt_controller;
+ if (ipar == NULL) {
+ printk("oops, no int parent %x in map of %s\n",
+ imap[-1], p->full_name);
+ return 0;
+ }
+ /* find the parent's # addr and intr cells */
+ ip = (unsigned int *)
+ get_property(ipar, "#interrupt-cells", NULL);
+ if (ip == NULL) {
+ printk("oops, no #interrupt-cells on %s\n",
+ ipar->full_name);
+ return 0;
+ }
+ newintrc = *ip;
+ ip = (unsigned int *)
+ get_property(ipar, "#address-cells", NULL);
+ newaddrc = (ip == NULL)? 0: *ip;
+ imap += newaddrc + newintrc;
+ imaplen -= newaddrc + newintrc;
+ }
+ if (imaplen < 0) {
+ printk("oops, error decoding int-map on %s, len=%d\n",
+ p->full_name, imaplen);
+ return 0;
+ }
+ if (!match) {
+#ifdef DEBUG_IRQ
+ printk("oops, no match in %s int-map for %s\n",
+ p->full_name, np->full_name);
+#endif
+ return 0;
+ }
+ p = ipar;
+ naddrc = newaddrc;
+ nintrc = newintrc;
+ ints = imap - nintrc;
+ reg = ints - naddrc;
+ }
+ if (p == NULL) {
+#ifdef DEBUG_IRQ
+ printk("hmmm, int tree for %s doesn't have ctrler\n",
+ np->full_name);
+#endif
+ return 0;
+ }
+ *irq = ints;
+ *ictrler = p;
+ return nintrc;
+}
+
+static unsigned char map_isa_senses[4] = {
+ IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE,
+ IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE,
+ IRQ_SENSE_EDGE | IRQ_POLARITY_NEGATIVE,
+ IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE
+};
+
+static unsigned char map_mpic_senses[4] = {
+ IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE,
+ IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE,
+ /* 2 seems to be used for the 8259 cascade... */
+ IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE,
+ IRQ_SENSE_EDGE | IRQ_POLARITY_NEGATIVE,
+};
+
+static int __devinit finish_node_interrupts(struct device_node *np,
+ unsigned long *mem_start,
+ int measure_only)
+{
+ unsigned int *ints;
+ int intlen, intrcells, intrcount;
+ int i, j, n, sense;
+ unsigned int *irq, virq;
+ struct device_node *ic;
+
+ if (num_interrupt_controllers == 0) {
+ /*
+ * Old machines just have a list of interrupt numbers
+ * and no interrupt-controller nodes.
+ */
+ ints = (unsigned int *) get_property(np, "AAPL,interrupts",
+ &intlen);
+ /* XXX old interpret_pci_props looked in parent too */
+ /* XXX old interpret_macio_props looked for interrupts
+ before AAPL,interrupts */
+ if (ints == NULL)
+ ints = (unsigned int *) get_property(np, "interrupts",
+ &intlen);
+ if (ints == NULL)
+ return 0;
+
+ np->n_intrs = intlen / sizeof(unsigned int);
+ np->intrs = prom_alloc(np->n_intrs * sizeof(np->intrs[0]),
+ mem_start);
+ if (!np->intrs)
+ return -ENOMEM;
+ if (measure_only)
+ return 0;
+
+ for (i = 0; i < np->n_intrs; ++i) {
+ np->intrs[i].line = *ints++;
+ np->intrs[i].sense = IRQ_SENSE_LEVEL
+ | IRQ_POLARITY_NEGATIVE;
+ }
+ return 0;
+ }
+
+ ints = (unsigned int *) get_property(np, "interrupts", &intlen);
+ if (ints == NULL)
+ return 0;
+ intrcells = prom_n_intr_cells(np);
+ intlen /= intrcells * sizeof(unsigned int);
+
+ np->intrs = prom_alloc(intlen * sizeof(*(np->intrs)), mem_start);
+ if (!np->intrs)
+ return -ENOMEM;
+
+ if (measure_only)
+ return 0;
+
+ intrcount = 0;
+ for (i = 0; i < intlen; ++i, ints += intrcells) {
+ n = map_interrupt(&irq, &ic, np, ints, intrcells);
+ if (n <= 0)
+ continue;
+
+ /* don't map IRQ numbers under a cascaded 8259 controller */
+ if (ic && device_is_compatible(ic, "chrp,iic")) {
+ np->intrs[intrcount].line = irq[0];
+ sense = (n > 1)? (irq[1] & 3): 3;
+ np->intrs[intrcount].sense = map_isa_senses[sense];
+ } else {
+ virq = virt_irq_create_mapping(irq[0]);
+#ifdef CONFIG_PPC64
+ if (virq == NO_IRQ) {
+ printk(KERN_CRIT "Could not allocate interrupt"
+ " number for %s\n", np->full_name);
+ continue;
+ }
+#endif
+ np->intrs[intrcount].line = irq_offset_up(virq);
+ sense = (n > 1)? (irq[1] & 3): 1;
+ np->intrs[intrcount].sense = map_mpic_senses[sense];
+ }
+
+#ifdef CONFIG_PPC64
+ /* We offset irq numbers for the u3 MPIC by 128 in PowerMac */
+ if (_machine == PLATFORM_POWERMAC && ic && ic->parent) {
+ char *name = get_property(ic->parent, "name", NULL);
+ if (name && !strcmp(name, "u3"))
+ np->intrs[intrcount].line += 128;
+ else if (!(name && !strcmp(name, "mac-io")))
+ /* ignore other cascaded controllers, such as
+ the k2-sata-root */
+ break;
+ }
+#endif
+ if (n > 2) {
+ printk("hmmm, got %d intr cells for %s:", n,
+ np->full_name);
+ for (j = 0; j < n; ++j)
+ printk(" %d", irq[j]);
+ printk("\n");
+ }
+ ++intrcount;
+ }
+ np->n_intrs = intrcount;
+
+ return 0;
+}
+
+static int __devinit interpret_pci_props(struct device_node *np,
+ unsigned long *mem_start,
+ int naddrc, int nsizec,
+ int measure_only)
+{
+ struct address_range *adr;
+ struct pci_reg_property *pci_addrs;
+ int i, l, n_addrs;
+
+ pci_addrs = (struct pci_reg_property *)
+ get_property(np, "assigned-addresses", &l);
+ if (!pci_addrs)
+ return 0;
+
+ n_addrs = l / sizeof(*pci_addrs);
+
+ adr = prom_alloc(n_addrs * sizeof(*adr), mem_start);
+ if (!adr)
+ return -ENOMEM;
+
+ if (measure_only)
+ return 0;
+
+ np->addrs = adr;
+ np->n_addrs = n_addrs;
+
+ for (i = 0; i < n_addrs; i++) {
+ adr[i].space = pci_addrs[i].addr.a_hi;
+ adr[i].address = pci_addrs[i].addr.a_lo |
+ ((u64)pci_addrs[i].addr.a_mid << 32);
+ adr[i].size = pci_addrs[i].size_lo;
+ }
+
+ return 0;
+}
+
+static int __init interpret_dbdma_props(struct device_node *np,
+ unsigned long *mem_start,
+ int naddrc, int nsizec,
+ int measure_only)
+{
+ struct reg_property32 *rp;
+ struct address_range *adr;
+ unsigned long base_address;
+ int i, l;
+ struct device_node *db;
+
+ base_address = 0;
+ if (!measure_only) {
+ for (db = np->parent; db != NULL; db = db->parent) {
+ if (!strcmp(db->type, "dbdma") && db->n_addrs != 0) {
+ base_address = db->addrs[0].address;
+ break;
+ }
+ }
+ }
+
+ rp = (struct reg_property32 *) get_property(np, "reg", &l);
+ if (rp != 0 && l >= sizeof(struct reg_property32)) {
+ i = 0;
+ adr = (struct address_range *) (*mem_start);
+ while ((l -= sizeof(struct reg_property32)) >= 0) {
+ if (!measure_only) {
+ adr[i].space = 2;
+ adr[i].address = rp[i].address + base_address;
+ adr[i].size = rp[i].size;
+ }
+ ++i;
+ }
+ np->addrs = adr;
+ np->n_addrs = i;
+ (*mem_start) += i * sizeof(struct address_range);
+ }
+
+ return 0;
+}
+
+static int __init interpret_macio_props(struct device_node *np,
+ unsigned long *mem_start,
+ int naddrc, int nsizec,
+ int measure_only)
+{
+ struct reg_property32 *rp;
+ struct address_range *adr;
+ unsigned long base_address;
+ int i, l;
+ struct device_node *db;
+
+ base_address = 0;
+ if (!measure_only) {
+ for (db = np->parent; db != NULL; db = db->parent) {
+ if (!strcmp(db->type, "mac-io") && db->n_addrs != 0) {
+ base_address = db->addrs[0].address;
+ break;
+ }
+ }
+ }
+
+ rp = (struct reg_property32 *) get_property(np, "reg", &l);
+ if (rp != 0 && l >= sizeof(struct reg_property32)) {
+ i = 0;
+ adr = (struct address_range *) (*mem_start);
+ while ((l -= sizeof(struct reg_property32)) >= 0) {
+ if (!measure_only) {
+ adr[i].space = 2;
+ adr[i].address = rp[i].address + base_address;
+ adr[i].size = rp[i].size;
+ }
+ ++i;
+ }
+ np->addrs = adr;
+ np->n_addrs = i;
+ (*mem_start) += i * sizeof(struct address_range);
+ }
+
+ return 0;
+}
+
+static int __init interpret_isa_props(struct device_node *np,
+ unsigned long *mem_start,
+ int naddrc, int nsizec,
+ int measure_only)
+{
+ struct isa_reg_property *rp;
+ struct address_range *adr;
+ int i, l;
+
+ rp = (struct isa_reg_property *) get_property(np, "reg", &l);
+ if (rp != 0 && l >= sizeof(struct isa_reg_property)) {
+ i = 0;
+ adr = (struct address_range *) (*mem_start);
+ while ((l -= sizeof(struct isa_reg_property)) >= 0) {
+ if (!measure_only) {
+ adr[i].space = rp[i].space;
+ adr[i].address = rp[i].address;
+ adr[i].size = rp[i].size;
+ }
+ ++i;
+ }
+ np->addrs = adr;
+ np->n_addrs = i;
+ (*mem_start) += i * sizeof(struct address_range);
+ }
+
+ return 0;
+}
+
+static int __init interpret_root_props(struct device_node *np,
+ unsigned long *mem_start,
+ int naddrc, int nsizec,
+ int measure_only)
+{
+ struct address_range *adr;
+ int i, l;
+ unsigned int *rp;
+ int rpsize = (naddrc + nsizec) * sizeof(unsigned int);
+
+ rp = (unsigned int *) get_property(np, "reg", &l);
+ if (rp != 0 && l >= rpsize) {
+ i = 0;
+ adr = (struct address_range *) (*mem_start);
+ while ((l -= rpsize) >= 0) {
+ if (!measure_only) {
+ adr[i].space = 0;
+ adr[i].address = rp[naddrc - 1];
+ adr[i].size = rp[naddrc + nsizec - 1];
+ }
+ ++i;
+ rp += naddrc + nsizec;
+ }
+ np->addrs = adr;
+ np->n_addrs = i;
+ (*mem_start) += i * sizeof(struct address_range);
+ }
+
+ return 0;
+}
+
+static int __devinit finish_node(struct device_node *np,
+ unsigned long *mem_start,
+ interpret_func *ifunc,
+ int naddrc, int nsizec,
+ int measure_only)
+{
+ struct device_node *child;
+ int *ip, rc = 0;
+
+ /* get the device addresses and interrupts */
+ if (ifunc != NULL)
+ rc = ifunc(np, mem_start, naddrc, nsizec, measure_only);
+ if (rc)
+ goto out;
+
+ rc = finish_node_interrupts(np, mem_start, measure_only);
+ if (rc)
+ goto out;
+
+ /* Look for #address-cells and #size-cells properties. */
+ ip = (int *) get_property(np, "#address-cells", NULL);
+ if (ip != NULL)
+ naddrc = *ip;
+ ip = (int *) get_property(np, "#size-cells", NULL);
+ if (ip != NULL)
+ nsizec = *ip;
+
+ if (!strcmp(np->name, "device-tree") || np->parent == NULL)
+ ifunc = interpret_root_props;
+ else if (np->type == 0)
+ ifunc = NULL;
+ else if (!strcmp(np->type, "pci") || !strcmp(np->type, "vci"))
+ ifunc = interpret_pci_props;
+ else if (!strcmp(np->type, "dbdma"))
+ ifunc = interpret_dbdma_props;
+ else if (!strcmp(np->type, "mac-io") || ifunc == interpret_macio_props)
+ ifunc = interpret_macio_props;
+ else if (!strcmp(np->type, "isa"))
+ ifunc = interpret_isa_props;
+ else if (!strcmp(np->name, "uni-n") || !strcmp(np->name, "u3"))
+ ifunc = interpret_root_props;
+ else if (!((ifunc == interpret_dbdma_props
+ || ifunc == interpret_macio_props)
+ && (!strcmp(np->type, "escc")
+ || !strcmp(np->type, "media-bay"))))
+ ifunc = NULL;
+
+ for (child = np->child; child != NULL; child = child->sibling) {
+ rc = finish_node(child, mem_start, ifunc,
+ naddrc, nsizec, measure_only);
+ if (rc)
+ goto out;
+ }
+out:
+ return rc;
+}
+
+static void __init scan_interrupt_controllers(void)
+{
+ struct device_node *np;
+ int n = 0;
+ char *name, *ic;
+ int iclen;
+
+ for (np = allnodes; np != NULL; np = np->allnext) {
+ ic = get_property(np, "interrupt-controller", &iclen);
+ name = get_property(np, "name", NULL);
+ /* checking iclen makes sure we don't get a false
+ match on /chosen.interrupt_controller */
+ if ((name != NULL
+ && strcmp(name, "interrupt-controller") == 0)
+ || (ic != NULL && iclen == 0
+ && strcmp(name, "AppleKiwi"))) {
+ if (n == 0)
+ dflt_interrupt_controller = np;
+ ++n;
+ }
+ }
+ num_interrupt_controllers = n;
+}
+
+/**
+ * finish_device_tree is called once things are running normally
+ * (i.e. with text and data mapped to the address they were linked at).
+ * It traverses the device tree and fills in some of the additional,
+ * fields in each node like {n_}addrs and {n_}intrs, the virt interrupt
+ * mapping is also initialized at this point.
+ */
+void __init finish_device_tree(void)
+{
+ unsigned long start, end, size = 0;
+
+ DBG(" -> finish_device_tree\n");
+
+#ifdef CONFIG_PPC64
+ /* Initialize virtual IRQ map */
+ virt_irq_init();
+#endif
+ scan_interrupt_controllers();
+
+ /*
+ * Finish device-tree (pre-parsing some properties etc...)
+ * We do this in 2 passes. One with "measure_only" set, which
+ * will only measure the amount of memory needed, then we can
+ * allocate that memory, and call finish_node again. However,
+ * we must be careful as most routines will fail nowadays when
+ * prom_alloc() returns 0, so we must make sure our first pass
+ * doesn't start at 0. We pre-initialize size to 16 for that
+ * reason and then remove those additional 16 bytes
+ */
+ size = 16;
+ finish_node(allnodes, &size, NULL, 0, 0, 1);
+ size -= 16;
+ end = start = (unsigned long) __va(lmb_alloc(size, 128));
+ finish_node(allnodes, &end, NULL, 0, 0, 0);
+ BUG_ON(end != start + size);
+
+ DBG(" <- finish_device_tree\n");
+}
+
+static inline char *find_flat_dt_string(u32 offset)
+{
+ return ((char *)initial_boot_params) +
+ initial_boot_params->off_dt_strings + offset;
+}
+
+/**
+ * This function is used to scan the flattened device-tree, it is
+ * used to extract the memory informations at boot before we can
+ * unflatten the tree
+ */
+int __init of_scan_flat_dt(int (*it)(unsigned long node,
+ const char *uname, int depth,
+ void *data),
+ void *data)
+{
+ unsigned long p = ((unsigned long)initial_boot_params) +
+ initial_boot_params->off_dt_struct;
+ int rc = 0;
+ int depth = -1;
+
+ do {
+ u32 tag = *((u32 *)p);
+ char *pathp;
+
+ p += 4;
+ if (tag == OF_DT_END_NODE) {
+ depth --;
+ continue;
+ }
+ if (tag == OF_DT_NOP)
+ continue;
+ if (tag == OF_DT_END)
+ break;
+ if (tag == OF_DT_PROP) {
+ u32 sz = *((u32 *)p);
+ p += 8;
+ if (initial_boot_params->version < 0x10)
+ p = _ALIGN(p, sz >= 8 ? 8 : 4);
+ p += sz;
+ p = _ALIGN(p, 4);
+ continue;
+ }
+ if (tag != OF_DT_BEGIN_NODE) {
+ printk(KERN_WARNING "Invalid tag %x scanning flattened"
+ " device tree !\n", tag);
+ return -EINVAL;
+ }
+ depth++;
+ pathp = (char *)p;
+ p = _ALIGN(p + strlen(pathp) + 1, 4);
+ if ((*pathp) == '/') {
+ char *lp, *np;
+ for (lp = NULL, np = pathp; *np; np++)
+ if ((*np) == '/')
+ lp = np+1;
+ if (lp != NULL)
+ pathp = lp;
+ }
+ rc = it(p, pathp, depth, data);
+ if (rc != 0)
+ break;
+ } while(1);
+
+ return rc;
+}
+
+/**
+ * This function can be used within scan_flattened_dt callback to get
+ * access to properties
+ */
+void* __init of_get_flat_dt_prop(unsigned long node, const char *name,
+ unsigned long *size)
+{
+ unsigned long p = node;
+
+ do {
+ u32 tag = *((u32 *)p);
+ u32 sz, noff;
+ const char *nstr;
+
+ p += 4;
+ if (tag == OF_DT_NOP)
+ continue;
+ if (tag != OF_DT_PROP)
+ return NULL;
+
+ sz = *((u32 *)p);
+ noff = *((u32 *)(p + 4));
+ p += 8;
+ if (initial_boot_params->version < 0x10)
+ p = _ALIGN(p, sz >= 8 ? 8 : 4);
+
+ nstr = find_flat_dt_string(noff);
+ if (nstr == NULL) {
+ printk(KERN_WARNING "Can't find property index"
+ " name !\n");
+ return NULL;
+ }
+ if (strcmp(name, nstr) == 0) {
+ if (size)
+ *size = sz;
+ return (void *)p;
+ }
+ p += sz;
+ p = _ALIGN(p, 4);
+ } while(1);
+}
+
+static void *__init unflatten_dt_alloc(unsigned long *mem, unsigned long size,
+ unsigned long align)
+{
+ void *res;
+
+ *mem = _ALIGN(*mem, align);
+ res = (void *)*mem;
+ *mem += size;
+
+ return res;
+}
+
+static unsigned long __init unflatten_dt_node(unsigned long mem,
+ unsigned long *p,
+ struct device_node *dad,
+ struct device_node ***allnextpp,
+ unsigned long fpsize)
+{
+ struct device_node *np;
+ struct property *pp, **prev_pp = NULL;
+ char *pathp;
+ u32 tag;
+ unsigned int l, allocl;
+ int has_name = 0;
+ int new_format = 0;
+
+ tag = *((u32 *)(*p));
+ if (tag != OF_DT_BEGIN_NODE) {
+ printk("Weird tag at start of node: %x\n", tag);
+ return mem;
+ }
+ *p += 4;
+ pathp = (char *)*p;
+ l = allocl = strlen(pathp) + 1;
+ *p = _ALIGN(*p + l, 4);
+
+ /* version 0x10 has a more compact unit name here instead of the full
+ * path. we accumulate the full path size using "fpsize", we'll rebuild
+ * it later. We detect this because the first character of the name is
+ * not '/'.
+ */
+ if ((*pathp) != '/') {
+ new_format = 1;
+ if (fpsize == 0) {
+ /* root node: special case. fpsize accounts for path
+ * plus terminating zero. root node only has '/', so
+ * fpsize should be 2, but we want to avoid the first
+ * level nodes to have two '/' so we use fpsize 1 here
+ */
+ fpsize = 1;
+ allocl = 2;
+ } else {
+ /* account for '/' and path size minus terminal 0
+ * already in 'l'
+ */
+ fpsize += l;
+ allocl = fpsize;
+ }
+ }
+
+
+ np = unflatten_dt_alloc(&mem, sizeof(struct device_node) + allocl,
+ __alignof__(struct device_node));
+ if (allnextpp) {
+ memset(np, 0, sizeof(*np));
+ np->full_name = ((char*)np) + sizeof(struct device_node);
+ if (new_format) {
+ char *p = np->full_name;
+ /* rebuild full path for new format */
+ if (dad && dad->parent) {
+ strcpy(p, dad->full_name);
+#ifdef DEBUG
+ if ((strlen(p) + l + 1) != allocl) {
+ DBG("%s: p: %d, l: %d, a: %d\n",
+ pathp, strlen(p), l, allocl);
+ }
+#endif
+ p += strlen(p);
+ }
+ *(p++) = '/';
+ memcpy(p, pathp, l);
+ } else
+ memcpy(np->full_name, pathp, l);
+ prev_pp = &np->properties;
+ **allnextpp = np;
+ *allnextpp = &np->allnext;
+ if (dad != NULL) {
+ np->parent = dad;
+ /* we temporarily use the next field as `last_child'*/
+ if (dad->next == 0)
+ dad->child = np;
+ else
+ dad->next->sibling = np;
+ dad->next = np;
+ }
+ kref_init(&np->kref);
+ }
+ while(1) {
+ u32 sz, noff;
+ char *pname;
+
+ tag = *((u32 *)(*p));
+ if (tag == OF_DT_NOP) {
+ *p += 4;
+ continue;
+ }
+ if (tag != OF_DT_PROP)
+ break;
+ *p += 4;
+ sz = *((u32 *)(*p));
+ noff = *((u32 *)((*p) + 4));
+ *p += 8;
+ if (initial_boot_params->version < 0x10)
+ *p = _ALIGN(*p, sz >= 8 ? 8 : 4);
+
+ pname = find_flat_dt_string(noff);
+ if (pname == NULL) {
+ printk("Can't find property name in list !\n");
+ break;
+ }
+ if (strcmp(pname, "name") == 0)
+ has_name = 1;
+ l = strlen(pname) + 1;
+ pp = unflatten_dt_alloc(&mem, sizeof(struct property),
+ __alignof__(struct property));
+ if (allnextpp) {
+ if (strcmp(pname, "linux,phandle") == 0) {
+ np->node = *((u32 *)*p);
+ if (np->linux_phandle == 0)
+ np->linux_phandle = np->node;
+ }
+ if (strcmp(pname, "ibm,phandle") == 0)
+ np->linux_phandle = *((u32 *)*p);
+ pp->name = pname;
+ pp->length = sz;
+ pp->value = (void *)*p;
+ *prev_pp = pp;
+ prev_pp = &pp->next;
+ }
+ *p = _ALIGN((*p) + sz, 4);
+ }
+ /* with version 0x10 we may not have the name property, recreate
+ * it here from the unit name if absent
+ */
+ if (!has_name) {
+ char *p = pathp, *ps = pathp, *pa = NULL;
+ int sz;
+
+ while (*p) {
+ if ((*p) == '@')
+ pa = p;
+ if ((*p) == '/')
+ ps = p + 1;
+ p++;
+ }
+ if (pa < ps)
+ pa = p;
+ sz = (pa - ps) + 1;
+ pp = unflatten_dt_alloc(&mem, sizeof(struct property) + sz,
+ __alignof__(struct property));
+ if (allnextpp) {
+ pp->name = "name";
+ pp->length = sz;
+ pp->value = (unsigned char *)(pp + 1);
+ *prev_pp = pp;
+ prev_pp = &pp->next;
+ memcpy(pp->value, ps, sz - 1);
+ ((char *)pp->value)[sz - 1] = 0;
+ DBG("fixed up name for %s -> %s\n", pathp, pp->value);
+ }
+ }
+ if (allnextpp) {
+ *prev_pp = NULL;
+ np->name = get_property(np, "name", NULL);
+ np->type = get_property(np, "device_type", NULL);
+
+ if (!np->name)
+ np->name = "<NULL>";
+ if (!np->type)
+ np->type = "<NULL>";
+ }
+ while (tag == OF_DT_BEGIN_NODE) {
+ mem = unflatten_dt_node(mem, p, np, allnextpp, fpsize);
+ tag = *((u32 *)(*p));
+ }
+ if (tag != OF_DT_END_NODE) {
+ printk("Weird tag at end of node: %x\n", tag);
+ return mem;
+ }
+ *p += 4;
+ return mem;
+}
+
+
+/**
+ * unflattens the device-tree passed by the firmware, creating the
+ * tree of struct device_node. It also fills the "name" and "type"
+ * pointers of the nodes so the normal device-tree walking functions
+ * can be used (this used to be done by finish_device_tree)
+ */
+void __init unflatten_device_tree(void)
+{
+ unsigned long start, mem, size;
+ struct device_node **allnextp = &allnodes;
+ char *p = NULL;
+ int l = 0;
+
+ DBG(" -> unflatten_device_tree()\n");
+
+ /* First pass, scan for size */
+ start = ((unsigned long)initial_boot_params) +
+ initial_boot_params->off_dt_struct;
+ size = unflatten_dt_node(0, &start, NULL, NULL, 0);
+ size = (size | 3) + 1;
+
+ DBG(" size is %lx, allocating...\n", size);
+
+ /* Allocate memory for the expanded device tree */
+ mem = lmb_alloc(size + 4, __alignof__(struct device_node));
+ if (!mem) {
+ DBG("Couldn't allocate memory with lmb_alloc()!\n");
+ panic("Couldn't allocate memory with lmb_alloc()!\n");
+ }
+ mem = (unsigned long) __va(mem);
+
+ ((u32 *)mem)[size / 4] = 0xdeadbeef;
+
+ DBG(" unflattening %lx...\n", mem);
+
+ /* Second pass, do actual unflattening */
+ start = ((unsigned long)initial_boot_params) +
+ initial_boot_params->off_dt_struct;
+ unflatten_dt_node(mem, &start, NULL, &allnextp, 0);
+ if (*((u32 *)start) != OF_DT_END)
+ printk(KERN_WARNING "Weird tag at end of tree: %08x\n", *((u32 *)start));
+ if (((u32 *)mem)[size / 4] != 0xdeadbeef)
+ printk(KERN_WARNING "End of tree marker overwritten: %08x\n",
+ ((u32 *)mem)[size / 4] );
+ *allnextp = NULL;
+
+ /* Get pointer to OF "/chosen" node for use everywhere */
+ of_chosen = of_find_node_by_path("/chosen");
+ if (of_chosen == NULL)
+ of_chosen = of_find_node_by_path("/chosen@0");
+
+ /* Retreive command line */
+ if (of_chosen != NULL) {
+ p = (char *)get_property(of_chosen, "bootargs", &l);
+ if (p != NULL && l > 0)
+ strlcpy(cmd_line, p, min(l, COMMAND_LINE_SIZE));
+ }
+#ifdef CONFIG_CMDLINE
+ if (l == 0 || (l == 1 && (*p) == 0))
+ strlcpy(cmd_line, CONFIG_CMDLINE, COMMAND_LINE_SIZE);
+#endif /* CONFIG_CMDLINE */
+
+ DBG("Command line is: %s\n", cmd_line);
+
+ DBG(" <- unflatten_device_tree()\n");
+}
+
+
+static int __init early_init_dt_scan_cpus(unsigned long node,
+ const char *uname, int depth, void *data)
+{
+ u32 *prop;
+ unsigned long size;
+ char *type = of_get_flat_dt_prop(node, "device_type", &size);
+
+ /* We are scanning "cpu" nodes only */
+ if (type == NULL || strcmp(type, "cpu") != 0)
+ return 0;
+
+ boot_cpuid = 0;
+ boot_cpuid_phys = 0;
+ if (initial_boot_params && initial_boot_params->version >= 2) {
+ /* version 2 of the kexec param format adds the phys cpuid
+ * of booted proc.
+ */
+ boot_cpuid_phys = initial_boot_params->boot_cpuid_phys;
+ } else {
+ /* Check if it's the boot-cpu, set it's hw index now */
+ if (of_get_flat_dt_prop(node,
+ "linux,boot-cpu", NULL) != NULL) {
+ prop = of_get_flat_dt_prop(node, "reg", NULL);
+ if (prop != NULL)
+ boot_cpuid_phys = *prop;
+ }
+ }
+ set_hard_smp_processor_id(0, boot_cpuid_phys);
+
+#ifdef CONFIG_ALTIVEC
+ /* Check if we have a VMX and eventually update CPU features */
+ prop = (u32 *)of_get_flat_dt_prop(node, "ibm,vmx", NULL);
+ if (prop && (*prop) > 0) {
+ cur_cpu_spec->cpu_features |= CPU_FTR_ALTIVEC;
+ cur_cpu_spec->cpu_user_features |= PPC_FEATURE_HAS_ALTIVEC;
+ }
+
+ /* Same goes for Apple's "altivec" property */
+ prop = (u32 *)of_get_flat_dt_prop(node, "altivec", NULL);
+ if (prop) {
+ cur_cpu_spec->cpu_features |= CPU_FTR_ALTIVEC;
+ cur_cpu_spec->cpu_user_features |= PPC_FEATURE_HAS_ALTIVEC;
+ }
+#endif /* CONFIG_ALTIVEC */
+
+#ifdef CONFIG_PPC_PSERIES
+ /*
+ * Check for an SMT capable CPU and set the CPU feature. We do
+ * this by looking at the size of the ibm,ppc-interrupt-server#s
+ * property
+ */
+ prop = (u32 *)of_get_flat_dt_prop(node, "ibm,ppc-interrupt-server#s",
+ &size);
+ cur_cpu_spec->cpu_features &= ~CPU_FTR_SMT;
+ if (prop && ((size / sizeof(u32)) > 1))
+ cur_cpu_spec->cpu_features |= CPU_FTR_SMT;
+#endif
+
+ return 0;
+}
+
+static int __init early_init_dt_scan_chosen(unsigned long node,
+ const char *uname, int depth, void *data)
+{
+ u32 *prop;
+ unsigned long *lprop;
+
+ DBG("search \"chosen\", depth: %d, uname: %s\n", depth, uname);
+
+ if (depth != 1 ||
+ (strcmp(uname, "chosen") != 0 && strcmp(uname, "chosen@0") != 0))
+ return 0;
+
+ /* get platform type */
+ prop = (u32 *)of_get_flat_dt_prop(node, "linux,platform", NULL);
+ if (prop == NULL)
+ return 0;
+#ifdef CONFIG_PPC_MULTIPLATFORM
+ _machine = *prop;
+#endif
+
+#ifdef CONFIG_PPC64
+ /* check if iommu is forced on or off */
+ if (of_get_flat_dt_prop(node, "linux,iommu-off", NULL) != NULL)
+ iommu_is_off = 1;
+ if (of_get_flat_dt_prop(node, "linux,iommu-force-on", NULL) != NULL)
+ iommu_force_on = 1;
+#endif
+
+ lprop = of_get_flat_dt_prop(node, "linux,memory-limit", NULL);
+ if (lprop)
+ memory_limit = *lprop;
+
+#ifdef CONFIG_PPC64
+ lprop = of_get_flat_dt_prop(node, "linux,tce-alloc-start", NULL);
+ if (lprop)
+ tce_alloc_start = *lprop;
+ lprop = of_get_flat_dt_prop(node, "linux,tce-alloc-end", NULL);
+ if (lprop)
+ tce_alloc_end = *lprop;
+#endif
+
+#ifdef CONFIG_PPC_RTAS
+ /* To help early debugging via the front panel, we retreive a minimal
+ * set of RTAS infos now if available
+ */
+ {
+ u64 *basep, *entryp;
+
+ basep = of_get_flat_dt_prop(node, "linux,rtas-base", NULL);
+ entryp = of_get_flat_dt_prop(node, "linux,rtas-entry", NULL);
+ prop = of_get_flat_dt_prop(node, "linux,rtas-size", NULL);
+ if (basep && entryp && prop) {
+ rtas.base = *basep;
+ rtas.entry = *entryp;
+ rtas.size = *prop;
+ }
+ }
+#endif /* CONFIG_PPC_RTAS */
+
+ /* break now */
+ return 1;
+}
+
+static int __init early_init_dt_scan_root(unsigned long node,
+ const char *uname, int depth, void *data)
+{
+ u32 *prop;
+
+ if (depth != 0)
+ return 0;
+
+ prop = of_get_flat_dt_prop(node, "#size-cells", NULL);
+ dt_root_size_cells = (prop == NULL) ? 1 : *prop;
+ DBG("dt_root_size_cells = %x\n", dt_root_size_cells);
+
+ prop = of_get_flat_dt_prop(node, "#address-cells", NULL);
+ dt_root_addr_cells = (prop == NULL) ? 2 : *prop;
+ DBG("dt_root_addr_cells = %x\n", dt_root_addr_cells);
+
+ /* break now */
+ return 1;
+}
+
+static unsigned long __init dt_mem_next_cell(int s, cell_t **cellp)
+{
+ cell_t *p = *cellp;
+ unsigned long r;
+
+ /* Ignore more than 2 cells */
+ while (s > sizeof(unsigned long) / 4) {
+ p++;
+ s--;
+ }
+ r = *p++;
+#ifdef CONFIG_PPC64
+ if (s > 1) {
+ r <<= 32;
+ r |= *(p++);
+ s--;
+ }
+#endif
+
+ *cellp = p;
+ return r;
+}
+
+
+static int __init early_init_dt_scan_memory(unsigned long node,
+ const char *uname, int depth, void *data)
+{
+ char *type = of_get_flat_dt_prop(node, "device_type", NULL);
+ cell_t *reg, *endp;
+ unsigned long l;
+
+ /* We are scanning "memory" nodes only */
+ if (type == NULL) {
+ /*
+ * The longtrail doesn't have a device_type on the
+ * /memory node, so look for the node called /memory@0.
+ */
+ if (depth != 1 || strcmp(uname, "memory@0") != 0)
+ return 0;
+ } else if (strcmp(type, "memory") != 0)
+ return 0;
+
+ reg = (cell_t *)of_get_flat_dt_prop(node, "reg", &l);
+ if (reg == NULL)
+ return 0;
+
+ endp = reg + (l / sizeof(cell_t));
+
+ DBG("memory scan node %s, reg size %ld, data: %x %x %x %x,\n",
+ uname, l, reg[0], reg[1], reg[2], reg[3]);
+
+ while ((endp - reg) >= (dt_root_addr_cells + dt_root_size_cells)) {
+ unsigned long base, size;
+
+ base = dt_mem_next_cell(dt_root_addr_cells, &reg);
+ size = dt_mem_next_cell(dt_root_size_cells, &reg);
+
+ if (size == 0)
+ continue;
+ DBG(" - %lx , %lx\n", base, size);
+#ifdef CONFIG_PPC64
+ if (iommu_is_off) {
+ if (base >= 0x80000000ul)
+ continue;
+ if ((base + size) > 0x80000000ul)
+ size = 0x80000000ul - base;
+ }
+#endif
+ lmb_add(base, size);
+ }
+ return 0;
+}
+
+static void __init early_reserve_mem(void)
+{
+ unsigned long base, size;
+ unsigned long *reserve_map;
+
+ reserve_map = (unsigned long *)(((unsigned long)initial_boot_params) +
+ initial_boot_params->off_mem_rsvmap);
+ while (1) {
+ base = *(reserve_map++);
+ size = *(reserve_map++);
+ if (size == 0)
+ break;
+ DBG("reserving: %lx -> %lx\n", base, size);
+ lmb_reserve(base, size);
+ }
+
+#if 0
+ DBG("memory reserved, lmbs :\n");
+ lmb_dump_all();
+#endif
+}
+
+void __init early_init_devtree(void *params)
+{
+ DBG(" -> early_init_devtree()\n");
+
+ /* Setup flat device-tree pointer */
+ initial_boot_params = params;
+
+ /* Retrieve various informations from the /chosen node of the
+ * device-tree, including the platform type, initrd location and
+ * size, TCE reserve, and more ...
+ */
+ of_scan_flat_dt(early_init_dt_scan_chosen, NULL);
+
+ /* Scan memory nodes and rebuild LMBs */
+ lmb_init();
+ of_scan_flat_dt(early_init_dt_scan_root, NULL);
+ of_scan_flat_dt(early_init_dt_scan_memory, NULL);
+ lmb_enforce_memory_limit(memory_limit);
+ lmb_analyze();
+ lmb_reserve(0, __pa(klimit));
+
+ DBG("Phys. mem: %lx\n", lmb_phys_mem_size());
+
+ /* Reserve LMB regions used by kernel, initrd, dt, etc... */
+ early_reserve_mem();
+
+ DBG("Scanning CPUs ...\n");
+
+ /* Retreive CPU related informations from the flat tree
+ * (altivec support, boot CPU ID, ...)
+ */
+ of_scan_flat_dt(early_init_dt_scan_cpus, NULL);
+
+ DBG(" <- early_init_devtree()\n");
+}
+
+#undef printk
+
+int
+prom_n_addr_cells(struct device_node* np)
+{
+ int* ip;
+ do {
+ if (np->parent)
+ np = np->parent;
+ ip = (int *) get_property(np, "#address-cells", NULL);
+ if (ip != NULL)
+ return *ip;
+ } while (np->parent);
+ /* No #address-cells property for the root node, default to 1 */
+ return 1;
+}
+
+int
+prom_n_size_cells(struct device_node* np)
+{
+ int* ip;
+ do {
+ if (np->parent)
+ np = np->parent;
+ ip = (int *) get_property(np, "#size-cells", NULL);
+ if (ip != NULL)
+ return *ip;
+ } while (np->parent);
+ /* No #size-cells property for the root node, default to 1 */
+ return 1;
+}
+
+/**
+ * Work out the sense (active-low level / active-high edge)
+ * of each interrupt from the device tree.
+ */
+void __init prom_get_irq_senses(unsigned char *senses, int off, int max)
+{
+ struct device_node *np;
+ int i, j;
+
+ /* default to level-triggered */
+ memset(senses, IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE, max - off);
+
+ for (np = allnodes; np != 0; np = np->allnext) {
+ for (j = 0; j < np->n_intrs; j++) {
+ i = np->intrs[j].line;
+ if (i >= off && i < max)
+ senses[i-off] = np->intrs[j].sense;
+ }
+ }
+}
+
+/**
+ * Construct and return a list of the device_nodes with a given name.
+ */
+struct device_node *find_devices(const char *name)
+{
+ struct device_node *head, **prevp, *np;
+
+ prevp = &head;
+ for (np = allnodes; np != 0; np = np->allnext) {
+ if (np->name != 0 && strcasecmp(np->name, name) == 0) {
+ *prevp = np;
+ prevp = &np->next;
+ }
+ }
+ *prevp = NULL;
+ return head;
+}
+EXPORT_SYMBOL(find_devices);
+
+/**
+ * Construct and return a list of the device_nodes with a given type.
+ */
+struct device_node *find_type_devices(const char *type)
+{
+ struct device_node *head, **prevp, *np;
+
+ prevp = &head;
+ for (np = allnodes; np != 0; np = np->allnext) {
+ if (np->type != 0 && strcasecmp(np->type, type) == 0) {
+ *prevp = np;
+ prevp = &np->next;
+ }
+ }
+ *prevp = NULL;
+ return head;
+}
+EXPORT_SYMBOL(find_type_devices);
+
+/**
+ * Returns all nodes linked together
+ */
+struct device_node *find_all_nodes(void)
+{
+ struct device_node *head, **prevp, *np;
+
+ prevp = &head;
+ for (np = allnodes; np != 0; np = np->allnext) {
+ *prevp = np;
+ prevp = &np->next;
+ }
+ *prevp = NULL;
+ return head;
+}
+EXPORT_SYMBOL(find_all_nodes);
+
+/** Checks if the given "compat" string matches one of the strings in
+ * the device's "compatible" property
+ */
+int device_is_compatible(struct device_node *device, const char *compat)
+{
+ const char* cp;
+ int cplen, l;
+
+ cp = (char *) get_property(device, "compatible", &cplen);
+ if (cp == NULL)
+ return 0;
+ while (cplen > 0) {
+ if (strncasecmp(cp, compat, strlen(compat)) == 0)
+ return 1;
+ l = strlen(cp) + 1;
+ cp += l;
+ cplen -= l;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(device_is_compatible);
+
+
+/**
+ * Indicates whether the root node has a given value in its
+ * compatible property.
+ */
+int machine_is_compatible(const char *compat)
+{
+ struct device_node *root;
+ int rc = 0;
+
+ root = of_find_node_by_path("/");
+ if (root) {
+ rc = device_is_compatible(root, compat);
+ of_node_put(root);
+ }
+ return rc;
+}
+EXPORT_SYMBOL(machine_is_compatible);
+
+/**
+ * Construct and return a list of the device_nodes with a given type
+ * and compatible property.
+ */
+struct device_node *find_compatible_devices(const char *type,
+ const char *compat)
+{
+ struct device_node *head, **prevp, *np;
+
+ prevp = &head;
+ for (np = allnodes; np != 0; np = np->allnext) {
+ if (type != NULL
+ && !(np->type != 0 && strcasecmp(np->type, type) == 0))
+ continue;
+ if (device_is_compatible(np, compat)) {
+ *prevp = np;
+ prevp = &np->next;
+ }
+ }
+ *prevp = NULL;
+ return head;
+}
+EXPORT_SYMBOL(find_compatible_devices);
+
+/**
+ * Find the device_node with a given full_name.
+ */
+struct device_node *find_path_device(const char *path)
+{
+ struct device_node *np;
+
+ for (np = allnodes; np != 0; np = np->allnext)
+ if (np->full_name != 0 && strcasecmp(np->full_name, path) == 0)
+ return np;
+ return NULL;
+}
+EXPORT_SYMBOL(find_path_device);
+
+/*******
+ *
+ * New implementation of the OF "find" APIs, return a refcounted
+ * object, call of_node_put() when done. The device tree and list
+ * are protected by a rw_lock.
+ *
+ * Note that property management will need some locking as well,
+ * this isn't dealt with yet.
+ *
+ *******/
+
+/**
+ * of_find_node_by_name - Find a node by its "name" property
+ * @from: The node to start searching from or NULL, the node
+ * you pass will not be searched, only the next one
+ * will; typically, you pass what the previous call
+ * returned. of_node_put() will be called on it
+ * @name: The name string to match against
+ *
+ * Returns a node pointer with refcount incremented, use
+ * of_node_put() on it when done.
+ */
+struct device_node *of_find_node_by_name(struct device_node *from,
+ const char *name)
+{
+ struct device_node *np;
+
+ read_lock(&devtree_lock);
+ np = from ? from->allnext : allnodes;
+ for (; np != 0; np = np->allnext)
+ if (np->name != 0 && strcasecmp(np->name, name) == 0
+ && of_node_get(np))
+ break;
+ if (from)
+ of_node_put(from);
+ read_unlock(&devtree_lock);
+ return np;
+}
+EXPORT_SYMBOL(of_find_node_by_name);
+
+/**
+ * of_find_node_by_type - Find a node by its "device_type" property
+ * @from: The node to start searching from or NULL, the node
+ * you pass will not be searched, only the next one
+ * will; typically, you pass what the previous call
+ * returned. of_node_put() will be called on it
+ * @name: The type string to match against
+ *
+ * Returns a node pointer with refcount incremented, use
+ * of_node_put() on it when done.
+ */
+struct device_node *of_find_node_by_type(struct device_node *from,
+ const char *type)
+{
+ struct device_node *np;
+
+ read_lock(&devtree_lock);
+ np = from ? from->allnext : allnodes;
+ for (; np != 0; np = np->allnext)
+ if (np->type != 0 && strcasecmp(np->type, type) == 0
+ && of_node_get(np))
+ break;
+ if (from)
+ of_node_put(from);
+ read_unlock(&devtree_lock);
+ return np;
+}
+EXPORT_SYMBOL(of_find_node_by_type);
+
+/**
+ * of_find_compatible_node - Find a node based on type and one of the
+ * tokens in its "compatible" property
+ * @from: The node to start searching from or NULL, the node
+ * you pass will not be searched, only the next one
+ * will; typically, you pass what the previous call
+ * returned. of_node_put() will be called on it
+ * @type: The type string to match "device_type" or NULL to ignore
+ * @compatible: The string to match to one of the tokens in the device
+ * "compatible" list.
+ *
+ * Returns a node pointer with refcount incremented, use
+ * of_node_put() on it when done.
+ */
+struct device_node *of_find_compatible_node(struct device_node *from,
+ const char *type, const char *compatible)
+{
+ struct device_node *np;
+
+ read_lock(&devtree_lock);
+ np = from ? from->allnext : allnodes;
+ for (; np != 0; np = np->allnext) {
+ if (type != NULL
+ && !(np->type != 0 && strcasecmp(np->type, type) == 0))
+ continue;
+ if (device_is_compatible(np, compatible) && of_node_get(np))
+ break;
+ }
+ if (from)
+ of_node_put(from);
+ read_unlock(&devtree_lock);
+ return np;
+}
+EXPORT_SYMBOL(of_find_compatible_node);
+
+/**
+ * of_find_node_by_path - Find a node matching a full OF path
+ * @path: The full path to match
+ *
+ * Returns a node pointer with refcount incremented, use
+ * of_node_put() on it when done.
+ */
+struct device_node *of_find_node_by_path(const char *path)
+{
+ struct device_node *np = allnodes;
+
+ read_lock(&devtree_lock);
+ for (; np != 0; np = np->allnext) {
+ if (np->full_name != 0 && strcasecmp(np->full_name, path) == 0
+ && of_node_get(np))
+ break;
+ }
+ read_unlock(&devtree_lock);
+ return np;
+}
+EXPORT_SYMBOL(of_find_node_by_path);
+
+/**
+ * of_find_node_by_phandle - Find a node given a phandle
+ * @handle: phandle of the node to find
+ *
+ * Returns a node pointer with refcount incremented, use
+ * of_node_put() on it when done.
+ */
+struct device_node *of_find_node_by_phandle(phandle handle)
+{
+ struct device_node *np;
+
+ read_lock(&devtree_lock);
+ for (np = allnodes; np != 0; np = np->allnext)
+ if (np->linux_phandle == handle)
+ break;
+ if (np)
+ of_node_get(np);
+ read_unlock(&devtree_lock);
+ return np;
+}
+EXPORT_SYMBOL(of_find_node_by_phandle);
+
+/**
+ * of_find_all_nodes - Get next node in global list
+ * @prev: Previous node or NULL to start iteration
+ * of_node_put() will be called on it
+ *
+ * Returns a node pointer with refcount incremented, use
+ * of_node_put() on it when done.
+ */
+struct device_node *of_find_all_nodes(struct device_node *prev)
+{
+ struct device_node *np;
+
+ read_lock(&devtree_lock);
+ np = prev ? prev->allnext : allnodes;
+ for (; np != 0; np = np->allnext)
+ if (of_node_get(np))
+ break;
+ if (prev)
+ of_node_put(prev);
+ read_unlock(&devtree_lock);
+ return np;
+}
+EXPORT_SYMBOL(of_find_all_nodes);
+
+/**
+ * of_get_parent - Get a node's parent if any
+ * @node: Node to get parent
+ *
+ * Returns a node pointer with refcount incremented, use
+ * of_node_put() on it when done.
+ */
+struct device_node *of_get_parent(const struct device_node *node)
+{
+ struct device_node *np;
+
+ if (!node)
+ return NULL;
+
+ read_lock(&devtree_lock);
+ np = of_node_get(node->parent);
+ read_unlock(&devtree_lock);
+ return np;
+}
+EXPORT_SYMBOL(of_get_parent);
+
+/**
+ * of_get_next_child - Iterate a node childs
+ * @node: parent node
+ * @prev: previous child of the parent node, or NULL to get first
+ *
+ * Returns a node pointer with refcount incremented, use
+ * of_node_put() on it when done.
+ */
+struct device_node *of_get_next_child(const struct device_node *node,
+ struct device_node *prev)
+{
+ struct device_node *next;
+
+ read_lock(&devtree_lock);
+ next = prev ? prev->sibling : node->child;
+ for (; next != 0; next = next->sibling)
+ if (of_node_get(next))
+ break;
+ if (prev)
+ of_node_put(prev);
+ read_unlock(&devtree_lock);
+ return next;
+}
+EXPORT_SYMBOL(of_get_next_child);
+
+/**
+ * of_node_get - Increment refcount of a node
+ * @node: Node to inc refcount, NULL is supported to
+ * simplify writing of callers
+ *
+ * Returns node.
+ */
+struct device_node *of_node_get(struct device_node *node)
+{
+ if (node)
+ kref_get(&node->kref);
+ return node;
+}
+EXPORT_SYMBOL(of_node_get);
+
+static inline struct device_node * kref_to_device_node(struct kref *kref)
+{
+ return container_of(kref, struct device_node, kref);
+}
+
+/**
+ * of_node_release - release a dynamically allocated node
+ * @kref: kref element of the node to be released
+ *
+ * In of_node_put() this function is passed to kref_put()
+ * as the destructor.
+ */
+static void of_node_release(struct kref *kref)
+{
+ struct device_node *node = kref_to_device_node(kref);
+ struct property *prop = node->properties;
+
+ if (!OF_IS_DYNAMIC(node))
+ return;
+ while (prop) {
+ struct property *next = prop->next;
+ kfree(prop->name);
+ kfree(prop->value);
+ kfree(prop);
+ prop = next;
+ }
+ kfree(node->intrs);
+ kfree(node->addrs);
+ kfree(node->full_name);
+ kfree(node->data);
+ kfree(node);
+}
+
+/**
+ * of_node_put - Decrement refcount of a node
+ * @node: Node to dec refcount, NULL is supported to
+ * simplify writing of callers
+ *
+ */
+void of_node_put(struct device_node *node)
+{
+ if (node)
+ kref_put(&node->kref, of_node_release);
+}
+EXPORT_SYMBOL(of_node_put);
+
+/*
+ * Plug a device node into the tree and global list.
+ */
+void of_attach_node(struct device_node *np)
+{
+ write_lock(&devtree_lock);
+ np->sibling = np->parent->child;
+ np->allnext = allnodes;
+ np->parent->child = np;
+ allnodes = np;
+ write_unlock(&devtree_lock);
+}
+
+/*
+ * "Unplug" a node from the device tree. The caller must hold
+ * a reference to the node. The memory associated with the node
+ * is not freed until its refcount goes to zero.
+ */
+void of_detach_node(const struct device_node *np)
+{
+ struct device_node *parent;
+
+ write_lock(&devtree_lock);
+
+ parent = np->parent;
+
+ if (allnodes == np)
+ allnodes = np->allnext;
+ else {
+ struct device_node *prev;
+ for (prev = allnodes;
+ prev->allnext != np;
+ prev = prev->allnext)
+ ;
+ prev->allnext = np->allnext;
+ }
+
+ if (parent->child == np)
+ parent->child = np->sibling;
+ else {
+ struct device_node *prevsib;
+ for (prevsib = np->parent->child;
+ prevsib->sibling != np;
+ prevsib = prevsib->sibling)
+ ;
+ prevsib->sibling = np->sibling;
+ }
+
+ write_unlock(&devtree_lock);
+}
+
+#ifdef CONFIG_PPC_PSERIES
+/*
+ * Fix up the uninitialized fields in a new device node:
+ * name, type, n_addrs, addrs, n_intrs, intrs, and pci-specific fields
+ *
+ * A lot of boot-time code is duplicated here, because functions such
+ * as finish_node_interrupts, interpret_pci_props, etc. cannot use the
+ * slab allocator.
+ *
+ * This should probably be split up into smaller chunks.
+ */
+
+static int of_finish_dynamic_node(struct device_node *node,
+ unsigned long *unused1, int unused2,
+ int unused3, int unused4)
+{
+ struct device_node *parent = of_get_parent(node);
+ int err = 0;
+ phandle *ibm_phandle;
+
+ node->name = get_property(node, "name", NULL);
+ node->type = get_property(node, "device_type", NULL);
+
+ if (!parent) {
+ err = -ENODEV;
+ goto out;
+ }
+
+ /* We don't support that function on PowerMac, at least
+ * not yet
+ */
+ if (_machine == PLATFORM_POWERMAC)
+ return -ENODEV;
+
+ /* fix up new node's linux_phandle field */
+ if ((ibm_phandle = (unsigned int *)get_property(node, "ibm,phandle", NULL)))
+ node->linux_phandle = *ibm_phandle;
+
+out:
+ of_node_put(parent);
+ return err;
+}
+
+static int prom_reconfig_notifier(struct notifier_block *nb,
+ unsigned long action, void *node)
+{
+ int err;
+
+ switch (action) {
+ case PSERIES_RECONFIG_ADD:
+ err = finish_node(node, NULL, of_finish_dynamic_node, 0, 0, 0);
+ if (err < 0) {
+ printk(KERN_ERR "finish_node returned %d\n", err);
+ err = NOTIFY_BAD;
+ }
+ break;
+ default:
+ err = NOTIFY_DONE;
+ break;
+ }
+ return err;
+}
+
+static struct notifier_block prom_reconfig_nb = {
+ .notifier_call = prom_reconfig_notifier,
+ .priority = 10, /* This one needs to run first */
+};
+
+static int __init prom_reconfig_setup(void)
+{
+ return pSeries_reconfig_notifier_register(&prom_reconfig_nb);
+}
+__initcall(prom_reconfig_setup);
+#endif
+
+/*
+ * Find a property with a given name for a given node
+ * and return the value.
+ */
+unsigned char *get_property(struct device_node *np, const char *name,
+ int *lenp)
+{
+ struct property *pp;
+
+ for (pp = np->properties; pp != 0; pp = pp->next)
+ if (strcmp(pp->name, name) == 0) {
+ if (lenp != 0)
+ *lenp = pp->length;
+ return pp->value;
+ }
+ return NULL;
+}
+EXPORT_SYMBOL(get_property);
+
+/*
+ * Add a property to a node
+ */
+int prom_add_property(struct device_node* np, struct property* prop)
+{
+ struct property **next;
+
+ prop->next = NULL;
+ write_lock(&devtree_lock);
+ next = &np->properties;
+ while (*next) {
+ if (strcmp(prop->name, (*next)->name) == 0) {
+ /* duplicate ! don't insert it */
+ write_unlock(&devtree_lock);
+ return -1;
+ }
+ next = &(*next)->next;
+ }
+ *next = prop;
+ write_unlock(&devtree_lock);
+
+#ifdef CONFIG_PROC_DEVICETREE
+ /* try to add to proc as well if it was initialized */
+ if (np->pde)
+ proc_device_tree_add_prop(np->pde, prop);
+#endif /* CONFIG_PROC_DEVICETREE */
+
+ return 0;
+}
+
+/* I quickly hacked that one, check against spec ! */
+static inline unsigned long
+bus_space_to_resource_flags(unsigned int bus_space)
+{
+ u8 space = (bus_space >> 24) & 0xf;
+ if (space == 0)
+ space = 0x02;
+ if (space == 0x02)
+ return IORESOURCE_MEM;
+ else if (space == 0x01)
+ return IORESOURCE_IO;
+ else {
+ printk(KERN_WARNING "prom.c: bus_space_to_resource_flags(), space: %x\n",
+ bus_space);
+ return 0;
+ }
+}
+
+#ifdef CONFIG_PCI
+static struct resource *find_parent_pci_resource(struct pci_dev* pdev,
+ struct address_range *range)
+{
+ unsigned long mask;
+ int i;
+
+ /* Check this one */
+ mask = bus_space_to_resource_flags(range->space);
+ for (i=0; i<DEVICE_COUNT_RESOURCE; i++) {
+ if ((pdev->resource[i].flags & mask) == mask &&
+ pdev->resource[i].start <= range->address &&
+ pdev->resource[i].end > range->address) {
+ if ((range->address + range->size - 1) > pdev->resource[i].end) {
+ /* Add better message */
+ printk(KERN_WARNING "PCI/OF resource overlap !\n");
+ return NULL;
+ }
+ break;
+ }
+ }
+ if (i == DEVICE_COUNT_RESOURCE)
+ return NULL;
+ return &pdev->resource[i];
+}
+
+/*
+ * Request an OF device resource. Currently handles child of PCI devices,
+ * or other nodes attached to the root node. Ultimately, put some
+ * link to resources in the OF node.
+ */
+struct resource *request_OF_resource(struct device_node* node, int index,
+ const char* name_postfix)
+{
+ struct pci_dev* pcidev;
+ u8 pci_bus, pci_devfn;
+ unsigned long iomask;
+ struct device_node* nd;
+ struct resource* parent;
+ struct resource *res = NULL;
+ int nlen, plen;
+
+ if (index >= node->n_addrs)
+ goto fail;
+
+ /* Sanity check on bus space */
+ iomask = bus_space_to_resource_flags(node->addrs[index].space);
+ if (iomask & IORESOURCE_MEM)
+ parent = &iomem_resource;
+ else if (iomask & IORESOURCE_IO)
+ parent = &ioport_resource;
+ else
+ goto fail;
+
+ /* Find a PCI parent if any */
+ nd = node;
+ pcidev = NULL;
+ while (nd) {
+ if (!pci_device_from_OF_node(nd, &pci_bus, &pci_devfn))
+ pcidev = pci_find_slot(pci_bus, pci_devfn);
+ if (pcidev) break;
+ nd = nd->parent;
+ }
+ if (pcidev)
+ parent = find_parent_pci_resource(pcidev, &node->addrs[index]);
+ if (!parent) {
+ printk(KERN_WARNING "request_OF_resource(%s), parent not found\n",
+ node->name);
+ goto fail;
+ }
+
+ res = __request_region(parent, node->addrs[index].address,
+ node->addrs[index].size, NULL);
+ if (!res)
+ goto fail;
+ nlen = strlen(node->name);
+ plen = name_postfix ? strlen(name_postfix) : 0;
+ res->name = (const char *)kmalloc(nlen+plen+1, GFP_KERNEL);
+ if (res->name) {
+ strcpy((char *)res->name, node->name);
+ if (plen)
+ strcpy((char *)res->name+nlen, name_postfix);
+ }
+ return res;
+fail:
+ return NULL;
+}
+EXPORT_SYMBOL(request_OF_resource);
+
+int release_OF_resource(struct device_node *node, int index)
+{
+ struct pci_dev* pcidev;
+ u8 pci_bus, pci_devfn;
+ unsigned long iomask, start, end;
+ struct device_node* nd;
+ struct resource* parent;
+ struct resource *res = NULL;
+
+ if (index >= node->n_addrs)
+ return -EINVAL;
+
+ /* Sanity check on bus space */
+ iomask = bus_space_to_resource_flags(node->addrs[index].space);
+ if (iomask & IORESOURCE_MEM)
+ parent = &iomem_resource;
+ else if (iomask & IORESOURCE_IO)
+ parent = &ioport_resource;
+ else
+ return -EINVAL;
+
+ /* Find a PCI parent if any */
+ nd = node;
+ pcidev = NULL;
+ while(nd) {
+ if (!pci_device_from_OF_node(nd, &pci_bus, &pci_devfn))
+ pcidev = pci_find_slot(pci_bus, pci_devfn);
+ if (pcidev) break;
+ nd = nd->parent;
+ }
+ if (pcidev)
+ parent = find_parent_pci_resource(pcidev, &node->addrs[index]);
+ if (!parent) {
+ printk(KERN_WARNING "release_OF_resource(%s), parent not found\n",
+ node->name);
+ return -ENODEV;
+ }
+
+ /* Find us in the parent and its childs */
+ res = parent->child;
+ start = node->addrs[index].address;
+ end = start + node->addrs[index].size - 1;
+ while (res) {
+ if (res->start == start && res->end == end &&
+ (res->flags & IORESOURCE_BUSY))
+ break;
+ if (res->start <= start && res->end >= end)
+ res = res->child;
+ else
+ res = res->sibling;
+ }
+ if (!res)
+ return -ENODEV;
+
+ if (res->name) {
+ kfree(res->name);
+ res->name = NULL;
+ }
+ release_resource(res);
+ kfree(res);
+
+ return 0;
+}
+EXPORT_SYMBOL(release_OF_resource);
+#endif /* CONFIG_PCI */
diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c
new file mode 100644
index 000000000000..4ce0105c308e
--- /dev/null
+++ b/arch/powerpc/kernel/prom_init.c
@@ -0,0 +1,2195 @@
+/*
+ * Procedures for interfacing to Open Firmware.
+ *
+ * Paul Mackerras August 1996.
+ * Copyright (C) 1996-2005 Paul Mackerras.
+ *
+ * Adapted for 64bit PowerPC by Dave Engebretsen and Peter Bergner.
+ * {engebret|bergner}@us.ibm.com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#undef DEBUG_PROM
+
+#include <stdarg.h>
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/init.h>
+#include <linux/threads.h>
+#include <linux/spinlock.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/proc_fs.h>
+#include <linux/stringify.h>
+#include <linux/delay.h>
+#include <linux/initrd.h>
+#include <linux/bitops.h>
+#include <asm/prom.h>
+#include <asm/rtas.h>
+#include <asm/page.h>
+#include <asm/processor.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+#include <asm/smp.h>
+#include <asm/system.h>
+#include <asm/mmu.h>
+#include <asm/pgtable.h>
+#include <asm/pci.h>
+#include <asm/iommu.h>
+#include <asm/btext.h>
+#include <asm/sections.h>
+#include <asm/machdep.h>
+
+#ifdef CONFIG_LOGO_LINUX_CLUT224
+#include <linux/linux_logo.h>
+extern const struct linux_logo logo_linux_clut224;
+#endif
+
+/*
+ * Properties whose value is longer than this get excluded from our
+ * copy of the device tree. This value does need to be big enough to
+ * ensure that we don't lose things like the interrupt-map property
+ * on a PCI-PCI bridge.
+ */
+#define MAX_PROPERTY_LENGTH (1UL * 1024 * 1024)
+
+/*
+ * Eventually bump that one up
+ */
+#define DEVTREE_CHUNK_SIZE 0x100000
+
+/*
+ * This is the size of the local memory reserve map that gets copied
+ * into the boot params passed to the kernel. That size is totally
+ * flexible as the kernel just reads the list until it encounters an
+ * entry with size 0, so it can be changed without breaking binary
+ * compatibility
+ */
+#define MEM_RESERVE_MAP_SIZE 8
+
+/*
+ * prom_init() is called very early on, before the kernel text
+ * and data have been mapped to KERNELBASE. At this point the code
+ * is running at whatever address it has been loaded at.
+ * On ppc32 we compile with -mrelocatable, which means that references
+ * to extern and static variables get relocated automatically.
+ * On ppc64 we have to relocate the references explicitly with
+ * RELOC. (Note that strings count as static variables.)
+ *
+ * Because OF may have mapped I/O devices into the area starting at
+ * KERNELBASE, particularly on CHRP machines, we can't safely call
+ * OF once the kernel has been mapped to KERNELBASE. Therefore all
+ * OF calls must be done within prom_init().
+ *
+ * ADDR is used in calls to call_prom. The 4th and following
+ * arguments to call_prom should be 32-bit values.
+ * On ppc64, 64 bit values are truncated to 32 bits (and
+ * fortunately don't get interpreted as two arguments).
+ */
+#ifdef CONFIG_PPC64
+#define RELOC(x) (*PTRRELOC(&(x)))
+#define ADDR(x) (u32) add_reloc_offset((unsigned long)(x))
+#define OF_WORKAROUNDS 0
+#else
+#define RELOC(x) (x)
+#define ADDR(x) (u32) (x)
+#define OF_WORKAROUNDS of_workarounds
+int of_workarounds;
+#endif
+
+#define OF_WA_CLAIM 1 /* do phys/virt claim separately, then map */
+#define OF_WA_LONGTRAIL 2 /* work around longtrail bugs */
+
+#define PROM_BUG() do { \
+ prom_printf("kernel BUG at %s line 0x%x!\n", \
+ RELOC(__FILE__), __LINE__); \
+ __asm__ __volatile__(".long " BUG_ILLEGAL_INSTR); \
+} while (0)
+
+#ifdef DEBUG_PROM
+#define prom_debug(x...) prom_printf(x)
+#else
+#define prom_debug(x...)
+#endif
+
+
+typedef u32 prom_arg_t;
+
+struct prom_args {
+ u32 service;
+ u32 nargs;
+ u32 nret;
+ prom_arg_t args[10];
+};
+
+struct prom_t {
+ ihandle root;
+ phandle chosen;
+ int cpu;
+ ihandle stdout;
+ ihandle mmumap;
+ ihandle memory;
+};
+
+struct mem_map_entry {
+ unsigned long base;
+ unsigned long size;
+};
+
+typedef u32 cell_t;
+
+extern void __start(unsigned long r3, unsigned long r4, unsigned long r5);
+
+#ifdef CONFIG_PPC64
+extern int enter_prom(struct prom_args *args, unsigned long entry);
+#else
+static inline int enter_prom(struct prom_args *args, unsigned long entry)
+{
+ return ((int (*)(struct prom_args *))entry)(args);
+}
+#endif
+
+extern void copy_and_flush(unsigned long dest, unsigned long src,
+ unsigned long size, unsigned long offset);
+
+/* prom structure */
+static struct prom_t __initdata prom;
+
+static unsigned long prom_entry __initdata;
+
+#define PROM_SCRATCH_SIZE 256
+
+static char __initdata of_stdout_device[256];
+static char __initdata prom_scratch[PROM_SCRATCH_SIZE];
+
+static unsigned long __initdata dt_header_start;
+static unsigned long __initdata dt_struct_start, dt_struct_end;
+static unsigned long __initdata dt_string_start, dt_string_end;
+
+static unsigned long __initdata prom_initrd_start, prom_initrd_end;
+
+#ifdef CONFIG_PPC64
+static int __initdata iommu_force_on;
+static int __initdata ppc64_iommu_off;
+static unsigned long __initdata prom_tce_alloc_start;
+static unsigned long __initdata prom_tce_alloc_end;
+#endif
+
+static int __initdata of_platform;
+
+static char __initdata prom_cmd_line[COMMAND_LINE_SIZE];
+
+static unsigned long __initdata prom_memory_limit;
+
+static unsigned long __initdata alloc_top;
+static unsigned long __initdata alloc_top_high;
+static unsigned long __initdata alloc_bottom;
+static unsigned long __initdata rmo_top;
+static unsigned long __initdata ram_top;
+
+static struct mem_map_entry __initdata mem_reserve_map[MEM_RESERVE_MAP_SIZE];
+static int __initdata mem_reserve_cnt;
+
+static cell_t __initdata regbuf[1024];
+
+
+#define MAX_CPU_THREADS 2
+
+/* TO GO */
+#ifdef CONFIG_HMT
+struct {
+ unsigned int pir;
+ unsigned int threadid;
+} hmt_thread_data[NR_CPUS];
+#endif /* CONFIG_HMT */
+
+/*
+ * Error results ... some OF calls will return "-1" on error, some
+ * will return 0, some will return either. To simplify, here are
+ * macros to use with any ihandle or phandle return value to check if
+ * it is valid
+ */
+
+#define PROM_ERROR (-1u)
+#define PHANDLE_VALID(p) ((p) != 0 && (p) != PROM_ERROR)
+#define IHANDLE_VALID(i) ((i) != 0 && (i) != PROM_ERROR)
+
+
+/* This is the one and *ONLY* place where we actually call open
+ * firmware.
+ */
+
+static int __init call_prom(const char *service, int nargs, int nret, ...)
+{
+ int i;
+ struct prom_args args;
+ va_list list;
+
+ args.service = ADDR(service);
+ args.nargs = nargs;
+ args.nret = nret;
+
+ va_start(list, nret);
+ for (i = 0; i < nargs; i++)
+ args.args[i] = va_arg(list, prom_arg_t);
+ va_end(list);
+
+ for (i = 0; i < nret; i++)
+ args.args[nargs+i] = 0;
+
+ if (enter_prom(&args, RELOC(prom_entry)) < 0)
+ return PROM_ERROR;
+
+ return (nret > 0) ? args.args[nargs] : 0;
+}
+
+static int __init call_prom_ret(const char *service, int nargs, int nret,
+ prom_arg_t *rets, ...)
+{
+ int i;
+ struct prom_args args;
+ va_list list;
+
+ args.service = ADDR(service);
+ args.nargs = nargs;
+ args.nret = nret;
+
+ va_start(list, rets);
+ for (i = 0; i < nargs; i++)
+ args.args[i] = va_arg(list, prom_arg_t);
+ va_end(list);
+
+ for (i = 0; i < nret; i++)
+ rets[nargs+i] = 0;
+
+ if (enter_prom(&args, RELOC(prom_entry)) < 0)
+ return PROM_ERROR;
+
+ if (rets != NULL)
+ for (i = 1; i < nret; ++i)
+ rets[i-1] = args.args[nargs+i];
+
+ return (nret > 0) ? args.args[nargs] : 0;
+}
+
+
+static void __init prom_print(const char *msg)
+{
+ const char *p, *q;
+ struct prom_t *_prom = &RELOC(prom);
+
+ if (_prom->stdout == 0)
+ return;
+
+ for (p = msg; *p != 0; p = q) {
+ for (q = p; *q != 0 && *q != '\n'; ++q)
+ ;
+ if (q > p)
+ call_prom("write", 3, 1, _prom->stdout, p, q - p);
+ if (*q == 0)
+ break;
+ ++q;
+ call_prom("write", 3, 1, _prom->stdout, ADDR("\r\n"), 2);
+ }
+}
+
+
+static void __init prom_print_hex(unsigned long val)
+{
+ int i, nibbles = sizeof(val)*2;
+ char buf[sizeof(val)*2+1];
+ struct prom_t *_prom = &RELOC(prom);
+
+ for (i = nibbles-1; i >= 0; i--) {
+ buf[i] = (val & 0xf) + '0';
+ if (buf[i] > '9')
+ buf[i] += ('a'-'0'-10);
+ val >>= 4;
+ }
+ buf[nibbles] = '\0';
+ call_prom("write", 3, 1, _prom->stdout, buf, nibbles);
+}
+
+
+static void __init prom_printf(const char *format, ...)
+{
+ const char *p, *q, *s;
+ va_list args;
+ unsigned long v;
+ struct prom_t *_prom = &RELOC(prom);
+
+ va_start(args, format);
+#ifdef CONFIG_PPC64
+ format = PTRRELOC(format);
+#endif
+ for (p = format; *p != 0; p = q) {
+ for (q = p; *q != 0 && *q != '\n' && *q != '%'; ++q)
+ ;
+ if (q > p)
+ call_prom("write", 3, 1, _prom->stdout, p, q - p);
+ if (*q == 0)
+ break;
+ if (*q == '\n') {
+ ++q;
+ call_prom("write", 3, 1, _prom->stdout,
+ ADDR("\r\n"), 2);
+ continue;
+ }
+ ++q;
+ if (*q == 0)
+ break;
+ switch (*q) {
+ case 's':
+ ++q;
+ s = va_arg(args, const char *);
+ prom_print(s);
+ break;
+ case 'x':
+ ++q;
+ v = va_arg(args, unsigned long);
+ prom_print_hex(v);
+ break;
+ }
+ }
+}
+
+
+static unsigned int __init prom_claim(unsigned long virt, unsigned long size,
+ unsigned long align)
+{
+ struct prom_t *_prom = &RELOC(prom);
+
+ if (align == 0 && (OF_WORKAROUNDS & OF_WA_CLAIM)) {
+ /*
+ * Old OF requires we claim physical and virtual separately
+ * and then map explicitly (assuming virtual mode)
+ */
+ int ret;
+ prom_arg_t result;
+
+ ret = call_prom_ret("call-method", 5, 2, &result,
+ ADDR("claim"), _prom->memory,
+ align, size, virt);
+ if (ret != 0 || result == -1)
+ return -1;
+ ret = call_prom_ret("call-method", 5, 2, &result,
+ ADDR("claim"), _prom->mmumap,
+ align, size, virt);
+ if (ret != 0) {
+ call_prom("call-method", 4, 1, ADDR("release"),
+ _prom->memory, size, virt);
+ return -1;
+ }
+ /* the 0x12 is M (coherence) + PP == read/write */
+ call_prom("call-method", 6, 1,
+ ADDR("map"), _prom->mmumap, 0x12, size, virt, virt);
+ return virt;
+ }
+ return call_prom("claim", 3, 1, (prom_arg_t)virt, (prom_arg_t)size,
+ (prom_arg_t)align);
+}
+
+static void __init __attribute__((noreturn)) prom_panic(const char *reason)
+{
+#ifdef CONFIG_PPC64
+ reason = PTRRELOC(reason);
+#endif
+ prom_print(reason);
+ /* ToDo: should put up an SRC here on p/iSeries */
+ call_prom("exit", 0, 0);
+
+ for (;;) /* should never get here */
+ ;
+}
+
+
+static int __init prom_next_node(phandle *nodep)
+{
+ phandle node;
+
+ if ((node = *nodep) != 0
+ && (*nodep = call_prom("child", 1, 1, node)) != 0)
+ return 1;
+ if ((*nodep = call_prom("peer", 1, 1, node)) != 0)
+ return 1;
+ for (;;) {
+ if ((node = call_prom("parent", 1, 1, node)) == 0)
+ return 0;
+ if ((*nodep = call_prom("peer", 1, 1, node)) != 0)
+ return 1;
+ }
+}
+
+static int inline prom_getprop(phandle node, const char *pname,
+ void *value, size_t valuelen)
+{
+ return call_prom("getprop", 4, 1, node, ADDR(pname),
+ (u32)(unsigned long) value, (u32) valuelen);
+}
+
+static int inline prom_getproplen(phandle node, const char *pname)
+{
+ return call_prom("getproplen", 2, 1, node, ADDR(pname));
+}
+
+static void add_string(char **str, const char *q)
+{
+ char *p = *str;
+
+ while (*q)
+ *p++ = *q++;
+ *p++ = ' ';
+ *str = p;
+}
+
+static char *tohex(unsigned int x)
+{
+ static char digits[] = "0123456789abcdef";
+ static char result[9];
+ int i;
+
+ result[8] = 0;
+ i = 8;
+ do {
+ --i;
+ result[i] = digits[x & 0xf];
+ x >>= 4;
+ } while (x != 0 && i > 0);
+ return &result[i];
+}
+
+static int __init prom_setprop(phandle node, const char *nodename,
+ const char *pname, void *value, size_t valuelen)
+{
+ char cmd[256], *p;
+
+ if (!(OF_WORKAROUNDS & OF_WA_LONGTRAIL))
+ return call_prom("setprop", 4, 1, node, ADDR(pname),
+ (u32)(unsigned long) value, (u32) valuelen);
+
+ /* gah... setprop doesn't work on longtrail, have to use interpret */
+ p = cmd;
+ add_string(&p, "dev");
+ add_string(&p, nodename);
+ add_string(&p, tohex((u32)(unsigned long) value));
+ add_string(&p, tohex(valuelen));
+ add_string(&p, tohex(ADDR(pname)));
+ add_string(&p, tohex(strlen(RELOC(pname))));
+ add_string(&p, "property");
+ *p = 0;
+ return call_prom("interpret", 1, 1, (u32)(unsigned long) cmd);
+}
+
+/* We can't use the standard versions because of RELOC headaches. */
+#define isxdigit(c) (('0' <= (c) && (c) <= '9') \
+ || ('a' <= (c) && (c) <= 'f') \
+ || ('A' <= (c) && (c) <= 'F'))
+
+#define isdigit(c) ('0' <= (c) && (c) <= '9')
+#define islower(c) ('a' <= (c) && (c) <= 'z')
+#define toupper(c) (islower(c) ? ((c) - 'a' + 'A') : (c))
+
+unsigned long prom_strtoul(const char *cp, const char **endp)
+{
+ unsigned long result = 0, base = 10, value;
+
+ if (*cp == '0') {
+ base = 8;
+ cp++;
+ if (toupper(*cp) == 'X') {
+ cp++;
+ base = 16;
+ }
+ }
+
+ while (isxdigit(*cp) &&
+ (value = isdigit(*cp) ? *cp - '0' : toupper(*cp) - 'A' + 10) < base) {
+ result = result * base + value;
+ cp++;
+ }
+
+ if (endp)
+ *endp = cp;
+
+ return result;
+}
+
+unsigned long prom_memparse(const char *ptr, const char **retptr)
+{
+ unsigned long ret = prom_strtoul(ptr, retptr);
+ int shift = 0;
+
+ /*
+ * We can't use a switch here because GCC *may* generate a
+ * jump table which won't work, because we're not running at
+ * the address we're linked at.
+ */
+ if ('G' == **retptr || 'g' == **retptr)
+ shift = 30;
+
+ if ('M' == **retptr || 'm' == **retptr)
+ shift = 20;
+
+ if ('K' == **retptr || 'k' == **retptr)
+ shift = 10;
+
+ if (shift) {
+ ret <<= shift;
+ (*retptr)++;
+ }
+
+ return ret;
+}
+
+/*
+ * Early parsing of the command line passed to the kernel, used for
+ * "mem=x" and the options that affect the iommu
+ */
+static void __init early_cmdline_parse(void)
+{
+ struct prom_t *_prom = &RELOC(prom);
+ char *opt, *p;
+ int l = 0;
+
+ RELOC(prom_cmd_line[0]) = 0;
+ p = RELOC(prom_cmd_line);
+ if ((long)_prom->chosen > 0)
+ l = prom_getprop(_prom->chosen, "bootargs", p, COMMAND_LINE_SIZE-1);
+#ifdef CONFIG_CMDLINE
+ if (l == 0) /* dbl check */
+ strlcpy(RELOC(prom_cmd_line),
+ RELOC(CONFIG_CMDLINE), sizeof(prom_cmd_line));
+#endif /* CONFIG_CMDLINE */
+ prom_printf("command line: %s\n", RELOC(prom_cmd_line));
+
+#ifdef CONFIG_PPC64
+ opt = strstr(RELOC(prom_cmd_line), RELOC("iommu="));
+ if (opt) {
+ prom_printf("iommu opt is: %s\n", opt);
+ opt += 6;
+ while (*opt && *opt == ' ')
+ opt++;
+ if (!strncmp(opt, RELOC("off"), 3))
+ RELOC(ppc64_iommu_off) = 1;
+ else if (!strncmp(opt, RELOC("force"), 5))
+ RELOC(iommu_force_on) = 1;
+ }
+#endif
+
+ opt = strstr(RELOC(prom_cmd_line), RELOC("mem="));
+ if (opt) {
+ opt += 4;
+ RELOC(prom_memory_limit) = prom_memparse(opt, (const char **)&opt);
+#ifdef CONFIG_PPC64
+ /* Align to 16 MB == size of ppc64 large page */
+ RELOC(prom_memory_limit) = ALIGN(RELOC(prom_memory_limit), 0x1000000);
+#endif
+ }
+}
+
+#ifdef CONFIG_PPC_PSERIES
+/*
+ * To tell the firmware what our capabilities are, we have to pass
+ * it a fake 32-bit ELF header containing a couple of PT_NOTE sections
+ * that contain structures that contain the actual values.
+ */
+static struct fake_elf {
+ Elf32_Ehdr elfhdr;
+ Elf32_Phdr phdr[2];
+ struct chrpnote {
+ u32 namesz;
+ u32 descsz;
+ u32 type;
+ char name[8]; /* "PowerPC" */
+ struct chrpdesc {
+ u32 real_mode;
+ u32 real_base;
+ u32 real_size;
+ u32 virt_base;
+ u32 virt_size;
+ u32 load_base;
+ } chrpdesc;
+ } chrpnote;
+ struct rpanote {
+ u32 namesz;
+ u32 descsz;
+ u32 type;
+ char name[24]; /* "IBM,RPA-Client-Config" */
+ struct rpadesc {
+ u32 lpar_affinity;
+ u32 min_rmo_size;
+ u32 min_rmo_percent;
+ u32 max_pft_size;
+ u32 splpar;
+ u32 min_load;
+ u32 new_mem_def;
+ u32 ignore_me;
+ } rpadesc;
+ } rpanote;
+} fake_elf = {
+ .elfhdr = {
+ .e_ident = { 0x7f, 'E', 'L', 'F',
+ ELFCLASS32, ELFDATA2MSB, EV_CURRENT },
+ .e_type = ET_EXEC, /* yeah right */
+ .e_machine = EM_PPC,
+ .e_version = EV_CURRENT,
+ .e_phoff = offsetof(struct fake_elf, phdr),
+ .e_phentsize = sizeof(Elf32_Phdr),
+ .e_phnum = 2
+ },
+ .phdr = {
+ [0] = {
+ .p_type = PT_NOTE,
+ .p_offset = offsetof(struct fake_elf, chrpnote),
+ .p_filesz = sizeof(struct chrpnote)
+ }, [1] = {
+ .p_type = PT_NOTE,
+ .p_offset = offsetof(struct fake_elf, rpanote),
+ .p_filesz = sizeof(struct rpanote)
+ }
+ },
+ .chrpnote = {
+ .namesz = sizeof("PowerPC"),
+ .descsz = sizeof(struct chrpdesc),
+ .type = 0x1275,
+ .name = "PowerPC",
+ .chrpdesc = {
+ .real_mode = ~0U, /* ~0 means "don't care" */
+ .real_base = ~0U,
+ .real_size = ~0U,
+ .virt_base = ~0U,
+ .virt_size = ~0U,
+ .load_base = ~0U
+ },
+ },
+ .rpanote = {
+ .namesz = sizeof("IBM,RPA-Client-Config"),
+ .descsz = sizeof(struct rpadesc),
+ .type = 0x12759999,
+ .name = "IBM,RPA-Client-Config",
+ .rpadesc = {
+ .lpar_affinity = 0,
+ .min_rmo_size = 64, /* in megabytes */
+ .min_rmo_percent = 0,
+ .max_pft_size = 48, /* 2^48 bytes max PFT size */
+ .splpar = 1,
+ .min_load = ~0U,
+ .new_mem_def = 0
+ }
+ }
+};
+
+static void __init prom_send_capabilities(void)
+{
+ ihandle elfloader;
+
+ elfloader = call_prom("open", 1, 1, ADDR("/packages/elf-loader"));
+ if (elfloader == 0) {
+ prom_printf("couldn't open /packages/elf-loader\n");
+ return;
+ }
+ call_prom("call-method", 3, 1, ADDR("process-elf-header"),
+ elfloader, ADDR(&fake_elf));
+ call_prom("close", 1, 0, elfloader);
+}
+#endif
+
+/*
+ * Memory allocation strategy... our layout is normally:
+ *
+ * at 14Mb or more we have vmlinux, then a gap and initrd. In some
+ * rare cases, initrd might end up being before the kernel though.
+ * We assume this won't override the final kernel at 0, we have no
+ * provision to handle that in this version, but it should hopefully
+ * never happen.
+ *
+ * alloc_top is set to the top of RMO, eventually shrink down if the
+ * TCEs overlap
+ *
+ * alloc_bottom is set to the top of kernel/initrd
+ *
+ * from there, allocations are done this way : rtas is allocated
+ * topmost, and the device-tree is allocated from the bottom. We try
+ * to grow the device-tree allocation as we progress. If we can't,
+ * then we fail, we don't currently have a facility to restart
+ * elsewhere, but that shouldn't be necessary.
+ *
+ * Note that calls to reserve_mem have to be done explicitly, memory
+ * allocated with either alloc_up or alloc_down isn't automatically
+ * reserved.
+ */
+
+
+/*
+ * Allocates memory in the RMO upward from the kernel/initrd
+ *
+ * When align is 0, this is a special case, it means to allocate in place
+ * at the current location of alloc_bottom or fail (that is basically
+ * extending the previous allocation). Used for the device-tree flattening
+ */
+static unsigned long __init alloc_up(unsigned long size, unsigned long align)
+{
+ unsigned long base = RELOC(alloc_bottom);
+ unsigned long addr = 0;
+
+ if (align)
+ base = _ALIGN_UP(base, align);
+ prom_debug("alloc_up(%x, %x)\n", size, align);
+ if (RELOC(ram_top) == 0)
+ prom_panic("alloc_up() called with mem not initialized\n");
+
+ if (align)
+ base = _ALIGN_UP(RELOC(alloc_bottom), align);
+ else
+ base = RELOC(alloc_bottom);
+
+ for(; (base + size) <= RELOC(alloc_top);
+ base = _ALIGN_UP(base + 0x100000, align)) {
+ prom_debug(" trying: 0x%x\n\r", base);
+ addr = (unsigned long)prom_claim(base, size, 0);
+ if (addr != PROM_ERROR && addr != 0)
+ break;
+ addr = 0;
+ if (align == 0)
+ break;
+ }
+ if (addr == 0)
+ return 0;
+ RELOC(alloc_bottom) = addr;
+
+ prom_debug(" -> %x\n", addr);
+ prom_debug(" alloc_bottom : %x\n", RELOC(alloc_bottom));
+ prom_debug(" alloc_top : %x\n", RELOC(alloc_top));
+ prom_debug(" alloc_top_hi : %x\n", RELOC(alloc_top_high));
+ prom_debug(" rmo_top : %x\n", RELOC(rmo_top));
+ prom_debug(" ram_top : %x\n", RELOC(ram_top));
+
+ return addr;
+}
+
+/*
+ * Allocates memory downward, either from top of RMO, or if highmem
+ * is set, from the top of RAM. Note that this one doesn't handle
+ * failures. It does claim memory if highmem is not set.
+ */
+static unsigned long __init alloc_down(unsigned long size, unsigned long align,
+ int highmem)
+{
+ unsigned long base, addr = 0;
+
+ prom_debug("alloc_down(%x, %x, %s)\n", size, align,
+ highmem ? RELOC("(high)") : RELOC("(low)"));
+ if (RELOC(ram_top) == 0)
+ prom_panic("alloc_down() called with mem not initialized\n");
+
+ if (highmem) {
+ /* Carve out storage for the TCE table. */
+ addr = _ALIGN_DOWN(RELOC(alloc_top_high) - size, align);
+ if (addr <= RELOC(alloc_bottom))
+ return 0;
+ /* Will we bump into the RMO ? If yes, check out that we
+ * didn't overlap existing allocations there, if we did,
+ * we are dead, we must be the first in town !
+ */
+ if (addr < RELOC(rmo_top)) {
+ /* Good, we are first */
+ if (RELOC(alloc_top) == RELOC(rmo_top))
+ RELOC(alloc_top) = RELOC(rmo_top) = addr;
+ else
+ return 0;
+ }
+ RELOC(alloc_top_high) = addr;
+ goto bail;
+ }
+
+ base = _ALIGN_DOWN(RELOC(alloc_top) - size, align);
+ for (; base > RELOC(alloc_bottom);
+ base = _ALIGN_DOWN(base - 0x100000, align)) {
+ prom_debug(" trying: 0x%x\n\r", base);
+ addr = (unsigned long)prom_claim(base, size, 0);
+ if (addr != PROM_ERROR && addr != 0)
+ break;
+ addr = 0;
+ }
+ if (addr == 0)
+ return 0;
+ RELOC(alloc_top) = addr;
+
+ bail:
+ prom_debug(" -> %x\n", addr);
+ prom_debug(" alloc_bottom : %x\n", RELOC(alloc_bottom));
+ prom_debug(" alloc_top : %x\n", RELOC(alloc_top));
+ prom_debug(" alloc_top_hi : %x\n", RELOC(alloc_top_high));
+ prom_debug(" rmo_top : %x\n", RELOC(rmo_top));
+ prom_debug(" ram_top : %x\n", RELOC(ram_top));
+
+ return addr;
+}
+
+/*
+ * Parse a "reg" cell
+ */
+static unsigned long __init prom_next_cell(int s, cell_t **cellp)
+{
+ cell_t *p = *cellp;
+ unsigned long r = 0;
+
+ /* Ignore more than 2 cells */
+ while (s > sizeof(unsigned long) / 4) {
+ p++;
+ s--;
+ }
+ r = *p++;
+#ifdef CONFIG_PPC64
+ if (s > 1) {
+ r <<= 32;
+ r |= *(p++);
+ }
+#endif
+ *cellp = p;
+ return r;
+}
+
+/*
+ * Very dumb function for adding to the memory reserve list, but
+ * we don't need anything smarter at this point
+ *
+ * XXX Eventually check for collisions. They should NEVER happen.
+ * If problems seem to show up, it would be a good start to track
+ * them down.
+ */
+static void reserve_mem(unsigned long base, unsigned long size)
+{
+ unsigned long top = base + size;
+ unsigned long cnt = RELOC(mem_reserve_cnt);
+
+ if (size == 0)
+ return;
+
+ /* We need to always keep one empty entry so that we
+ * have our terminator with "size" set to 0 since we are
+ * dumb and just copy this entire array to the boot params
+ */
+ base = _ALIGN_DOWN(base, PAGE_SIZE);
+ top = _ALIGN_UP(top, PAGE_SIZE);
+ size = top - base;
+
+ if (cnt >= (MEM_RESERVE_MAP_SIZE - 1))
+ prom_panic("Memory reserve map exhausted !\n");
+ RELOC(mem_reserve_map)[cnt].base = base;
+ RELOC(mem_reserve_map)[cnt].size = size;
+ RELOC(mem_reserve_cnt) = cnt + 1;
+}
+
+/*
+ * Initialize memory allocation mecanism, parse "memory" nodes and
+ * obtain that way the top of memory and RMO to setup out local allocator
+ */
+static void __init prom_init_mem(void)
+{
+ phandle node;
+ char *path, type[64];
+ unsigned int plen;
+ cell_t *p, *endp;
+ struct prom_t *_prom = &RELOC(prom);
+ u32 rac, rsc;
+
+ /*
+ * We iterate the memory nodes to find
+ * 1) top of RMO (first node)
+ * 2) top of memory
+ */
+ rac = 2;
+ prom_getprop(_prom->root, "#address-cells", &rac, sizeof(rac));
+ rsc = 1;
+ prom_getprop(_prom->root, "#size-cells", &rsc, sizeof(rsc));
+ prom_debug("root_addr_cells: %x\n", (unsigned long) rac);
+ prom_debug("root_size_cells: %x\n", (unsigned long) rsc);
+
+ prom_debug("scanning memory:\n");
+ path = RELOC(prom_scratch);
+
+ for (node = 0; prom_next_node(&node); ) {
+ type[0] = 0;
+ prom_getprop(node, "device_type", type, sizeof(type));
+
+ if (type[0] == 0) {
+ /*
+ * CHRP Longtrail machines have no device_type
+ * on the memory node, so check the name instead...
+ */
+ prom_getprop(node, "name", type, sizeof(type));
+ }
+ if (strcmp(type, RELOC("memory")))
+ continue;
+
+ plen = prom_getprop(node, "reg", RELOC(regbuf), sizeof(regbuf));
+ if (plen > sizeof(regbuf)) {
+ prom_printf("memory node too large for buffer !\n");
+ plen = sizeof(regbuf);
+ }
+ p = RELOC(regbuf);
+ endp = p + (plen / sizeof(cell_t));
+
+#ifdef DEBUG_PROM
+ memset(path, 0, PROM_SCRATCH_SIZE);
+ call_prom("package-to-path", 3, 1, node, path, PROM_SCRATCH_SIZE-1);
+ prom_debug(" node %s :\n", path);
+#endif /* DEBUG_PROM */
+
+ while ((endp - p) >= (rac + rsc)) {
+ unsigned long base, size;
+
+ base = prom_next_cell(rac, &p);
+ size = prom_next_cell(rsc, &p);
+
+ if (size == 0)
+ continue;
+ prom_debug(" %x %x\n", base, size);
+ if (base == 0)
+ RELOC(rmo_top) = size;
+ if ((base + size) > RELOC(ram_top))
+ RELOC(ram_top) = base + size;
+ }
+ }
+
+ RELOC(alloc_bottom) = PAGE_ALIGN((unsigned long)&RELOC(_end) + 0x4000);
+
+ /* Check if we have an initrd after the kernel, if we do move our bottom
+ * point to after it
+ */
+ if (RELOC(prom_initrd_start)) {
+ if (RELOC(prom_initrd_end) > RELOC(alloc_bottom))
+ RELOC(alloc_bottom) = PAGE_ALIGN(RELOC(prom_initrd_end));
+ }
+
+ /*
+ * If prom_memory_limit is set we reduce the upper limits *except* for
+ * alloc_top_high. This must be the real top of RAM so we can put
+ * TCE's up there.
+ */
+
+ RELOC(alloc_top_high) = RELOC(ram_top);
+
+ if (RELOC(prom_memory_limit)) {
+ if (RELOC(prom_memory_limit) <= RELOC(alloc_bottom)) {
+ prom_printf("Ignoring mem=%x <= alloc_bottom.\n",
+ RELOC(prom_memory_limit));
+ RELOC(prom_memory_limit) = 0;
+ } else if (RELOC(prom_memory_limit) >= RELOC(ram_top)) {
+ prom_printf("Ignoring mem=%x >= ram_top.\n",
+ RELOC(prom_memory_limit));
+ RELOC(prom_memory_limit) = 0;
+ } else {
+ RELOC(ram_top) = RELOC(prom_memory_limit);
+ RELOC(rmo_top) = min(RELOC(rmo_top), RELOC(prom_memory_limit));
+ }
+ }
+
+ /*
+ * Setup our top alloc point, that is top of RMO or top of
+ * segment 0 when running non-LPAR.
+ * Some RS64 machines have buggy firmware where claims up at
+ * 1GB fail. Cap at 768MB as a workaround.
+ * Since 768MB is plenty of room, and we need to cap to something
+ * reasonable on 32-bit, cap at 768MB on all machines.
+ */
+ if (!RELOC(rmo_top))
+ RELOC(rmo_top) = RELOC(ram_top);
+ RELOC(rmo_top) = min(0x30000000ul, RELOC(rmo_top));
+ RELOC(alloc_top) = RELOC(rmo_top);
+
+ prom_printf("memory layout at init:\n");
+ prom_printf(" memory_limit : %x (16 MB aligned)\n", RELOC(prom_memory_limit));
+ prom_printf(" alloc_bottom : %x\n", RELOC(alloc_bottom));
+ prom_printf(" alloc_top : %x\n", RELOC(alloc_top));
+ prom_printf(" alloc_top_hi : %x\n", RELOC(alloc_top_high));
+ prom_printf(" rmo_top : %x\n", RELOC(rmo_top));
+ prom_printf(" ram_top : %x\n", RELOC(ram_top));
+}
+
+
+/*
+ * Allocate room for and instantiate RTAS
+ */
+static void __init prom_instantiate_rtas(void)
+{
+ phandle rtas_node;
+ ihandle rtas_inst;
+ u32 base, entry = 0;
+ u32 size = 0;
+
+ prom_debug("prom_instantiate_rtas: start...\n");
+
+ rtas_node = call_prom("finddevice", 1, 1, ADDR("/rtas"));
+ prom_debug("rtas_node: %x\n", rtas_node);
+ if (!PHANDLE_VALID(rtas_node))
+ return;
+
+ prom_getprop(rtas_node, "rtas-size", &size, sizeof(size));
+ if (size == 0)
+ return;
+
+ base = alloc_down(size, PAGE_SIZE, 0);
+ if (base == 0) {
+ prom_printf("RTAS allocation failed !\n");
+ return;
+ }
+
+ rtas_inst = call_prom("open", 1, 1, ADDR("/rtas"));
+ if (!IHANDLE_VALID(rtas_inst)) {
+ prom_printf("opening rtas package failed (%x)\n", rtas_inst);
+ return;
+ }
+
+ prom_printf("instantiating rtas at 0x%x ...", base);
+
+ if (call_prom_ret("call-method", 3, 2, &entry,
+ ADDR("instantiate-rtas"),
+ rtas_inst, base) != 0
+ || entry == 0) {
+ prom_printf(" failed\n");
+ return;
+ }
+ prom_printf(" done\n");
+
+ reserve_mem(base, size);
+
+ prom_setprop(rtas_node, "/rtas", "linux,rtas-base",
+ &base, sizeof(base));
+ prom_setprop(rtas_node, "/rtas", "linux,rtas-entry",
+ &entry, sizeof(entry));
+
+ prom_debug("rtas base = 0x%x\n", base);
+ prom_debug("rtas entry = 0x%x\n", entry);
+ prom_debug("rtas size = 0x%x\n", (long)size);
+
+ prom_debug("prom_instantiate_rtas: end...\n");
+}
+
+#ifdef CONFIG_PPC64
+/*
+ * Allocate room for and initialize TCE tables
+ */
+static void __init prom_initialize_tce_table(void)
+{
+ phandle node;
+ ihandle phb_node;
+ char compatible[64], type[64], model[64];
+ char *path = RELOC(prom_scratch);
+ u64 base, align;
+ u32 minalign, minsize;
+ u64 tce_entry, *tce_entryp;
+ u64 local_alloc_top, local_alloc_bottom;
+ u64 i;
+
+ if (RELOC(ppc64_iommu_off))
+ return;
+
+ prom_debug("starting prom_initialize_tce_table\n");
+
+ /* Cache current top of allocs so we reserve a single block */
+ local_alloc_top = RELOC(alloc_top_high);
+ local_alloc_bottom = local_alloc_top;
+
+ /* Search all nodes looking for PHBs. */
+ for (node = 0; prom_next_node(&node); ) {
+ compatible[0] = 0;
+ type[0] = 0;
+ model[0] = 0;
+ prom_getprop(node, "compatible",
+ compatible, sizeof(compatible));
+ prom_getprop(node, "device_type", type, sizeof(type));
+ prom_getprop(node, "model", model, sizeof(model));
+
+ if ((type[0] == 0) || (strstr(type, RELOC("pci")) == NULL))
+ continue;
+
+ /* Keep the old logic in tack to avoid regression. */
+ if (compatible[0] != 0) {
+ if ((strstr(compatible, RELOC("python")) == NULL) &&
+ (strstr(compatible, RELOC("Speedwagon")) == NULL) &&
+ (strstr(compatible, RELOC("Winnipeg")) == NULL))
+ continue;
+ } else if (model[0] != 0) {
+ if ((strstr(model, RELOC("ython")) == NULL) &&
+ (strstr(model, RELOC("peedwagon")) == NULL) &&
+ (strstr(model, RELOC("innipeg")) == NULL))
+ continue;
+ }
+
+ if (prom_getprop(node, "tce-table-minalign", &minalign,
+ sizeof(minalign)) == PROM_ERROR)
+ minalign = 0;
+ if (prom_getprop(node, "tce-table-minsize", &minsize,
+ sizeof(minsize)) == PROM_ERROR)
+ minsize = 4UL << 20;
+
+ /*
+ * Even though we read what OF wants, we just set the table
+ * size to 4 MB. This is enough to map 2GB of PCI DMA space.
+ * By doing this, we avoid the pitfalls of trying to DMA to
+ * MMIO space and the DMA alias hole.
+ *
+ * On POWER4, firmware sets the TCE region by assuming
+ * each TCE table is 8MB. Using this memory for anything
+ * else will impact performance, so we always allocate 8MB.
+ * Anton
+ */
+ if (__is_processor(PV_POWER4) || __is_processor(PV_POWER4p))
+ minsize = 8UL << 20;
+ else
+ minsize = 4UL << 20;
+
+ /* Align to the greater of the align or size */
+ align = max(minalign, minsize);
+ base = alloc_down(minsize, align, 1);
+ if (base == 0)
+ prom_panic("ERROR, cannot find space for TCE table.\n");
+ if (base < local_alloc_bottom)
+ local_alloc_bottom = base;
+
+ /* It seems OF doesn't null-terminate the path :-( */
+ memset(path, 0, sizeof(path));
+ /* Call OF to setup the TCE hardware */
+ if (call_prom("package-to-path", 3, 1, node,
+ path, PROM_SCRATCH_SIZE-1) == PROM_ERROR) {
+ prom_printf("package-to-path failed\n");
+ }
+
+ /* Save away the TCE table attributes for later use. */
+ prom_setprop(node, path, "linux,tce-base", &base, sizeof(base));
+ prom_setprop(node, path, "linux,tce-size", &minsize, sizeof(minsize));
+
+ prom_debug("TCE table: %s\n", path);
+ prom_debug("\tnode = 0x%x\n", node);
+ prom_debug("\tbase = 0x%x\n", base);
+ prom_debug("\tsize = 0x%x\n", minsize);
+
+ /* Initialize the table to have a one-to-one mapping
+ * over the allocated size.
+ */
+ tce_entryp = (unsigned long *)base;
+ for (i = 0; i < (minsize >> 3) ;tce_entryp++, i++) {
+ tce_entry = (i << PAGE_SHIFT);
+ tce_entry |= 0x3;
+ *tce_entryp = tce_entry;
+ }
+
+ prom_printf("opening PHB %s", path);
+ phb_node = call_prom("open", 1, 1, path);
+ if (phb_node == 0)
+ prom_printf("... failed\n");
+ else
+ prom_printf("... done\n");
+
+ call_prom("call-method", 6, 0, ADDR("set-64-bit-addressing"),
+ phb_node, -1, minsize,
+ (u32) base, (u32) (base >> 32));
+ call_prom("close", 1, 0, phb_node);
+ }
+
+ reserve_mem(local_alloc_bottom, local_alloc_top - local_alloc_bottom);
+
+ if (RELOC(prom_memory_limit)) {
+ /*
+ * We align the start to a 16MB boundary so we can map
+ * the TCE area using large pages if possible.
+ * The end should be the top of RAM so no need to align it.
+ */
+ RELOC(prom_tce_alloc_start) = _ALIGN_DOWN(local_alloc_bottom,
+ 0x1000000);
+ RELOC(prom_tce_alloc_end) = local_alloc_top;
+ }
+
+ /* Flag the first invalid entry */
+ prom_debug("ending prom_initialize_tce_table\n");
+}
+#endif
+
+/*
+ * With CHRP SMP we need to use the OF to start the other processors.
+ * We can't wait until smp_boot_cpus (the OF is trashed by then)
+ * so we have to put the processors into a holding pattern controlled
+ * by the kernel (not OF) before we destroy the OF.
+ *
+ * This uses a chunk of low memory, puts some holding pattern
+ * code there and sends the other processors off to there until
+ * smp_boot_cpus tells them to do something. The holding pattern
+ * checks that address until its cpu # is there, when it is that
+ * cpu jumps to __secondary_start(). smp_boot_cpus() takes care
+ * of setting those values.
+ *
+ * We also use physical address 0x4 here to tell when a cpu
+ * is in its holding pattern code.
+ *
+ * -- Cort
+ */
+extern void __secondary_hold(void);
+extern unsigned long __secondary_hold_spinloop;
+extern unsigned long __secondary_hold_acknowledge;
+
+/*
+ * We want to reference the copy of __secondary_hold_* in the
+ * 0 - 0x100 address range
+ */
+#define LOW_ADDR(x) (((unsigned long) &(x)) & 0xff)
+
+static void __init prom_hold_cpus(void)
+{
+ unsigned long i;
+ unsigned int reg;
+ phandle node;
+ char type[64];
+ int cpuid = 0;
+ unsigned int interrupt_server[MAX_CPU_THREADS];
+ unsigned int cpu_threads, hw_cpu_num;
+ int propsize;
+ struct prom_t *_prom = &RELOC(prom);
+ unsigned long *spinloop
+ = (void *) LOW_ADDR(__secondary_hold_spinloop);
+ unsigned long *acknowledge
+ = (void *) LOW_ADDR(__secondary_hold_acknowledge);
+#ifdef CONFIG_PPC64
+ /* __secondary_hold is actually a descriptor, not the text address */
+ unsigned long secondary_hold
+ = __pa(*PTRRELOC((unsigned long *)__secondary_hold));
+#else
+ unsigned long secondary_hold = LOW_ADDR(__secondary_hold);
+#endif
+
+ prom_debug("prom_hold_cpus: start...\n");
+ prom_debug(" 1) spinloop = 0x%x\n", (unsigned long)spinloop);
+ prom_debug(" 1) *spinloop = 0x%x\n", *spinloop);
+ prom_debug(" 1) acknowledge = 0x%x\n",
+ (unsigned long)acknowledge);
+ prom_debug(" 1) *acknowledge = 0x%x\n", *acknowledge);
+ prom_debug(" 1) secondary_hold = 0x%x\n", secondary_hold);
+
+ /* Set the common spinloop variable, so all of the secondary cpus
+ * will block when they are awakened from their OF spinloop.
+ * This must occur for both SMP and non SMP kernels, since OF will
+ * be trashed when we move the kernel.
+ */
+ *spinloop = 0;
+
+#ifdef CONFIG_HMT
+ for (i = 0; i < NR_CPUS; i++)
+ RELOC(hmt_thread_data)[i].pir = 0xdeadbeef;
+#endif
+ /* look for cpus */
+ for (node = 0; prom_next_node(&node); ) {
+ type[0] = 0;
+ prom_getprop(node, "device_type", type, sizeof(type));
+ if (strcmp(type, RELOC("cpu")) != 0)
+ continue;
+
+ /* Skip non-configured cpus. */
+ if (prom_getprop(node, "status", type, sizeof(type)) > 0)
+ if (strcmp(type, RELOC("okay")) != 0)
+ continue;
+
+ reg = -1;
+ prom_getprop(node, "reg", &reg, sizeof(reg));
+
+ prom_debug("\ncpuid = 0x%x\n", cpuid);
+ prom_debug("cpu hw idx = 0x%x\n", reg);
+
+ /* Init the acknowledge var which will be reset by
+ * the secondary cpu when it awakens from its OF
+ * spinloop.
+ */
+ *acknowledge = (unsigned long)-1;
+
+ propsize = prom_getprop(node, "ibm,ppc-interrupt-server#s",
+ &interrupt_server,
+ sizeof(interrupt_server));
+ if (propsize < 0) {
+ /* no property. old hardware has no SMT */
+ cpu_threads = 1;
+ interrupt_server[0] = reg; /* fake it with phys id */
+ } else {
+ /* We have a threaded processor */
+ cpu_threads = propsize / sizeof(u32);
+ if (cpu_threads > MAX_CPU_THREADS) {
+ prom_printf("SMT: too many threads!\n"
+ "SMT: found %x, max is %x\n",
+ cpu_threads, MAX_CPU_THREADS);
+ cpu_threads = 1; /* ToDo: panic? */
+ }
+ }
+
+ hw_cpu_num = interrupt_server[0];
+ if (hw_cpu_num != _prom->cpu) {
+ /* Primary Thread of non-boot cpu */
+ prom_printf("%x : starting cpu hw idx %x... ", cpuid, reg);
+ call_prom("start-cpu", 3, 0, node,
+ secondary_hold, reg);
+
+ for (i = 0; (i < 100000000) &&
+ (*acknowledge == ((unsigned long)-1)); i++ )
+ mb();
+
+ if (*acknowledge == reg)
+ prom_printf("done\n");
+ else
+ prom_printf("failed: %x\n", *acknowledge);
+ }
+#ifdef CONFIG_SMP
+ else
+ prom_printf("%x : boot cpu %x\n", cpuid, reg);
+#endif /* CONFIG_SMP */
+
+ /* Reserve cpu #s for secondary threads. They start later. */
+ cpuid += cpu_threads;
+ }
+#ifdef CONFIG_HMT
+ /* Only enable HMT on processors that provide support. */
+ if (__is_processor(PV_PULSAR) ||
+ __is_processor(PV_ICESTAR) ||
+ __is_processor(PV_SSTAR)) {
+ prom_printf(" starting secondary threads\n");
+
+ for (i = 0; i < NR_CPUS; i += 2) {
+ if (!cpu_online(i))
+ continue;
+
+ if (i == 0) {
+ unsigned long pir = mfspr(SPRN_PIR);
+ if (__is_processor(PV_PULSAR)) {
+ RELOC(hmt_thread_data)[i].pir =
+ pir & 0x1f;
+ } else {
+ RELOC(hmt_thread_data)[i].pir =
+ pir & 0x3ff;
+ }
+ }
+ }
+ } else {
+ prom_printf("Processor is not HMT capable\n");
+ }
+#endif
+
+ if (cpuid > NR_CPUS)
+ prom_printf("WARNING: maximum CPUs (" __stringify(NR_CPUS)
+ ") exceeded: ignoring extras\n");
+
+ prom_debug("prom_hold_cpus: end...\n");
+}
+
+
+static void __init prom_init_client_services(unsigned long pp)
+{
+ struct prom_t *_prom = &RELOC(prom);
+
+ /* Get a handle to the prom entry point before anything else */
+ RELOC(prom_entry) = pp;
+
+ /* get a handle for the stdout device */
+ _prom->chosen = call_prom("finddevice", 1, 1, ADDR("/chosen"));
+ if (!PHANDLE_VALID(_prom->chosen))
+ prom_panic("cannot find chosen"); /* msg won't be printed :( */
+
+ /* get device tree root */
+ _prom->root = call_prom("finddevice", 1, 1, ADDR("/"));
+ if (!PHANDLE_VALID(_prom->root))
+ prom_panic("cannot find device tree root"); /* msg won't be printed :( */
+
+ _prom->mmumap = 0;
+}
+
+#ifdef CONFIG_PPC32
+/*
+ * For really old powermacs, we need to map things we claim.
+ * For that, we need the ihandle of the mmu.
+ * Also, on the longtrail, we need to work around other bugs.
+ */
+static void __init prom_find_mmu(void)
+{
+ struct prom_t *_prom = &RELOC(prom);
+ phandle oprom;
+ char version[64];
+
+ oprom = call_prom("finddevice", 1, 1, ADDR("/openprom"));
+ if (!PHANDLE_VALID(oprom))
+ return;
+ if (prom_getprop(oprom, "model", version, sizeof(version)) <= 0)
+ return;
+ version[sizeof(version) - 1] = 0;
+ /* XXX might need to add other versions here */
+ if (strcmp(version, "Open Firmware, 1.0.5") == 0)
+ of_workarounds = OF_WA_CLAIM;
+ else if (strncmp(version, "FirmWorks,3.", 12) == 0) {
+ of_workarounds = OF_WA_CLAIM | OF_WA_LONGTRAIL;
+ call_prom("interpret", 1, 1, "dev /memory 0 to allow-reclaim");
+ } else
+ return;
+ _prom->memory = call_prom("open", 1, 1, ADDR("/memory"));
+ prom_getprop(_prom->chosen, "mmu", &_prom->mmumap,
+ sizeof(_prom->mmumap));
+ if (!IHANDLE_VALID(_prom->memory) || !IHANDLE_VALID(_prom->mmumap))
+ of_workarounds &= ~OF_WA_CLAIM; /* hmmm */
+}
+#else
+#define prom_find_mmu()
+#endif
+
+static void __init prom_init_stdout(void)
+{
+ struct prom_t *_prom = &RELOC(prom);
+ char *path = RELOC(of_stdout_device);
+ char type[16];
+ u32 val;
+
+ if (prom_getprop(_prom->chosen, "stdout", &val, sizeof(val)) <= 0)
+ prom_panic("cannot find stdout");
+
+ _prom->stdout = val;
+
+ /* Get the full OF pathname of the stdout device */
+ memset(path, 0, 256);
+ call_prom("instance-to-path", 3, 1, _prom->stdout, path, 255);
+ val = call_prom("instance-to-package", 1, 1, _prom->stdout);
+ prom_setprop(_prom->chosen, "/chosen", "linux,stdout-package",
+ &val, sizeof(val));
+ prom_printf("OF stdout device is: %s\n", RELOC(of_stdout_device));
+ prom_setprop(_prom->chosen, "/chosen", "linux,stdout-path",
+ path, strlen(path) + 1);
+
+ /* If it's a display, note it */
+ memset(type, 0, sizeof(type));
+ prom_getprop(val, "device_type", type, sizeof(type));
+ if (strcmp(type, RELOC("display")) == 0)
+ prom_setprop(val, path, "linux,boot-display", NULL, 0);
+}
+
+static void __init prom_close_stdin(void)
+{
+ struct prom_t *_prom = &RELOC(prom);
+ ihandle val;
+
+ if (prom_getprop(_prom->chosen, "stdin", &val, sizeof(val)) > 0)
+ call_prom("close", 1, 0, val);
+}
+
+static int __init prom_find_machine_type(void)
+{
+ struct prom_t *_prom = &RELOC(prom);
+ char compat[256];
+ int len, i = 0;
+#ifdef CONFIG_PPC64
+ phandle rtas;
+#endif
+ len = prom_getprop(_prom->root, "compatible",
+ compat, sizeof(compat)-1);
+ if (len > 0) {
+ compat[len] = 0;
+ while (i < len) {
+ char *p = &compat[i];
+ int sl = strlen(p);
+ if (sl == 0)
+ break;
+ if (strstr(p, RELOC("Power Macintosh")) ||
+ strstr(p, RELOC("MacRISC")))
+ return PLATFORM_POWERMAC;
+#ifdef CONFIG_PPC64
+ if (strstr(p, RELOC("Momentum,Maple")))
+ return PLATFORM_MAPLE;
+#endif
+ i += sl + 1;
+ }
+ }
+#ifdef CONFIG_PPC64
+ /* Default to pSeries. We need to know if we are running LPAR */
+ rtas = call_prom("finddevice", 1, 1, ADDR("/rtas"));
+ if (PHANDLE_VALID(rtas)) {
+ int x = prom_getproplen(rtas, "ibm,hypertas-functions");
+ if (x != PROM_ERROR) {
+ prom_printf("Hypertas detected, assuming LPAR !\n");
+ return PLATFORM_PSERIES_LPAR;
+ }
+ }
+ return PLATFORM_PSERIES;
+#else
+ return PLATFORM_CHRP;
+#endif
+}
+
+static int __init prom_set_color(ihandle ih, int i, int r, int g, int b)
+{
+ return call_prom("call-method", 6, 1, ADDR("color!"), ih, i, b, g, r);
+}
+
+/*
+ * If we have a display that we don't know how to drive,
+ * we will want to try to execute OF's open method for it
+ * later. However, OF will probably fall over if we do that
+ * we've taken over the MMU.
+ * So we check whether we will need to open the display,
+ * and if so, open it now.
+ */
+static void __init prom_check_displays(void)
+{
+ char type[16], *path;
+ phandle node;
+ ihandle ih;
+ int i;
+
+ static unsigned char default_colors[] = {
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xaa,
+ 0x00, 0xaa, 0x00,
+ 0x00, 0xaa, 0xaa,
+ 0xaa, 0x00, 0x00,
+ 0xaa, 0x00, 0xaa,
+ 0xaa, 0xaa, 0x00,
+ 0xaa, 0xaa, 0xaa,
+ 0x55, 0x55, 0x55,
+ 0x55, 0x55, 0xff,
+ 0x55, 0xff, 0x55,
+ 0x55, 0xff, 0xff,
+ 0xff, 0x55, 0x55,
+ 0xff, 0x55, 0xff,
+ 0xff, 0xff, 0x55,
+ 0xff, 0xff, 0xff
+ };
+ const unsigned char *clut;
+
+ prom_printf("Looking for displays\n");
+ for (node = 0; prom_next_node(&node); ) {
+ memset(type, 0, sizeof(type));
+ prom_getprop(node, "device_type", type, sizeof(type));
+ if (strcmp(type, RELOC("display")) != 0)
+ continue;
+
+ /* It seems OF doesn't null-terminate the path :-( */
+ path = RELOC(prom_scratch);
+ memset(path, 0, PROM_SCRATCH_SIZE);
+
+ /*
+ * leave some room at the end of the path for appending extra
+ * arguments
+ */
+ if (call_prom("package-to-path", 3, 1, node, path,
+ PROM_SCRATCH_SIZE-10) == PROM_ERROR)
+ continue;
+ prom_printf("found display : %s, opening ... ", path);
+
+ ih = call_prom("open", 1, 1, path);
+ if (ih == 0) {
+ prom_printf("failed\n");
+ continue;
+ }
+
+ /* Success */
+ prom_printf("done\n");
+ prom_setprop(node, path, "linux,opened", NULL, 0);
+
+ /* Setup a usable color table when the appropriate
+ * method is available. Should update this to set-colors */
+ clut = RELOC(default_colors);
+ for (i = 0; i < 32; i++, clut += 3)
+ if (prom_set_color(ih, i, clut[0], clut[1],
+ clut[2]) != 0)
+ break;
+
+#ifdef CONFIG_LOGO_LINUX_CLUT224
+ clut = PTRRELOC(RELOC(logo_linux_clut224.clut));
+ for (i = 0; i < RELOC(logo_linux_clut224.clutsize); i++, clut += 3)
+ if (prom_set_color(ih, i + 32, clut[0], clut[1],
+ clut[2]) != 0)
+ break;
+#endif /* CONFIG_LOGO_LINUX_CLUT224 */
+ }
+}
+
+
+/* Return (relocated) pointer to this much memory: moves initrd if reqd. */
+static void __init *make_room(unsigned long *mem_start, unsigned long *mem_end,
+ unsigned long needed, unsigned long align)
+{
+ void *ret;
+
+ *mem_start = _ALIGN(*mem_start, align);
+ while ((*mem_start + needed) > *mem_end) {
+ unsigned long room, chunk;
+
+ prom_debug("Chunk exhausted, claiming more at %x...\n",
+ RELOC(alloc_bottom));
+ room = RELOC(alloc_top) - RELOC(alloc_bottom);
+ if (room > DEVTREE_CHUNK_SIZE)
+ room = DEVTREE_CHUNK_SIZE;
+ if (room < PAGE_SIZE)
+ prom_panic("No memory for flatten_device_tree (no room)");
+ chunk = alloc_up(room, 0);
+ if (chunk == 0)
+ prom_panic("No memory for flatten_device_tree (claim failed)");
+ *mem_end = RELOC(alloc_top);
+ }
+
+ ret = (void *)*mem_start;
+ *mem_start += needed;
+
+ return ret;
+}
+
+#define dt_push_token(token, mem_start, mem_end) \
+ do { *((u32 *)make_room(mem_start, mem_end, 4, 4)) = token; } while(0)
+
+static unsigned long __init dt_find_string(char *str)
+{
+ char *s, *os;
+
+ s = os = (char *)RELOC(dt_string_start);
+ s += 4;
+ while (s < (char *)RELOC(dt_string_end)) {
+ if (strcmp(s, str) == 0)
+ return s - os;
+ s += strlen(s) + 1;
+ }
+ return 0;
+}
+
+/*
+ * The Open Firmware 1275 specification states properties must be 31 bytes or
+ * less, however not all firmwares obey this. Make it 64 bytes to be safe.
+ */
+#define MAX_PROPERTY_NAME 64
+
+static void __init scan_dt_build_strings(phandle node,
+ unsigned long *mem_start,
+ unsigned long *mem_end)
+{
+ char *prev_name, *namep, *sstart;
+ unsigned long soff;
+ phandle child;
+
+ sstart = (char *)RELOC(dt_string_start);
+
+ /* get and store all property names */
+ prev_name = RELOC("");
+ for (;;) {
+ /* 64 is max len of name including nul. */
+ namep = make_room(mem_start, mem_end, MAX_PROPERTY_NAME, 1);
+ if (call_prom("nextprop", 3, 1, node, prev_name, namep) != 1) {
+ /* No more nodes: unwind alloc */
+ *mem_start = (unsigned long)namep;
+ break;
+ }
+
+ /* skip "name" */
+ if (strcmp(namep, RELOC("name")) == 0) {
+ *mem_start = (unsigned long)namep;
+ prev_name = RELOC("name");
+ continue;
+ }
+ /* get/create string entry */
+ soff = dt_find_string(namep);
+ if (soff != 0) {
+ *mem_start = (unsigned long)namep;
+ namep = sstart + soff;
+ } else {
+ /* Trim off some if we can */
+ *mem_start = (unsigned long)namep + strlen(namep) + 1;
+ RELOC(dt_string_end) = *mem_start;
+ }
+ prev_name = namep;
+ }
+
+ /* do all our children */
+ child = call_prom("child", 1, 1, node);
+ while (child != 0) {
+ scan_dt_build_strings(child, mem_start, mem_end);
+ child = call_prom("peer", 1, 1, child);
+ }
+}
+
+static void __init scan_dt_build_struct(phandle node, unsigned long *mem_start,
+ unsigned long *mem_end)
+{
+ phandle child;
+ char *namep, *prev_name, *sstart, *p, *ep, *lp, *path;
+ unsigned long soff;
+ unsigned char *valp;
+ static char pname[MAX_PROPERTY_NAME];
+ int l, room;
+
+ dt_push_token(OF_DT_BEGIN_NODE, mem_start, mem_end);
+
+ /* get the node's full name */
+ namep = (char *)*mem_start;
+ room = *mem_end - *mem_start;
+ if (room > 255)
+ room = 255;
+ l = call_prom("package-to-path", 3, 1, node, namep, room);
+ if (l >= 0) {
+ /* Didn't fit? Get more room. */
+ if (l >= room) {
+ if (l >= *mem_end - *mem_start)
+ namep = make_room(mem_start, mem_end, l+1, 1);
+ call_prom("package-to-path", 3, 1, node, namep, l);
+ }
+ namep[l] = '\0';
+
+ /* Fixup an Apple bug where they have bogus \0 chars in the
+ * middle of the path in some properties, and extract
+ * the unit name (everything after the last '/').
+ */
+ for (lp = p = namep, ep = namep + l; p < ep; p++) {
+ if (*p == '/')
+ lp = namep;
+ else if (*p != 0)
+ *lp++ = *p;
+ }
+ *lp = 0;
+ *mem_start = _ALIGN((unsigned long)lp + 1, 4);
+ }
+
+ /* get it again for debugging */
+ path = RELOC(prom_scratch);
+ memset(path, 0, PROM_SCRATCH_SIZE);
+ call_prom("package-to-path", 3, 1, node, path, PROM_SCRATCH_SIZE-1);
+
+ /* get and store all properties */
+ prev_name = RELOC("");
+ sstart = (char *)RELOC(dt_string_start);
+ for (;;) {
+ if (call_prom("nextprop", 3, 1, node, prev_name,
+ RELOC(pname)) != 1)
+ break;
+
+ /* skip "name" */
+ if (strcmp(RELOC(pname), RELOC("name")) == 0) {
+ prev_name = RELOC("name");
+ continue;
+ }
+
+ /* find string offset */
+ soff = dt_find_string(RELOC(pname));
+ if (soff == 0) {
+ prom_printf("WARNING: Can't find string index for"
+ " <%s>, node %s\n", RELOC(pname), path);
+ break;
+ }
+ prev_name = sstart + soff;
+
+ /* get length */
+ l = call_prom("getproplen", 2, 1, node, RELOC(pname));
+
+ /* sanity checks */
+ if (l == PROM_ERROR)
+ continue;
+ if (l > MAX_PROPERTY_LENGTH) {
+ prom_printf("WARNING: ignoring large property ");
+ /* It seems OF doesn't null-terminate the path :-( */
+ prom_printf("[%s] ", path);
+ prom_printf("%s length 0x%x\n", RELOC(pname), l);
+ continue;
+ }
+
+ /* push property head */
+ dt_push_token(OF_DT_PROP, mem_start, mem_end);
+ dt_push_token(l, mem_start, mem_end);
+ dt_push_token(soff, mem_start, mem_end);
+
+ /* push property content */
+ valp = make_room(mem_start, mem_end, l, 4);
+ call_prom("getprop", 4, 1, node, RELOC(pname), valp, l);
+ *mem_start = _ALIGN(*mem_start, 4);
+ }
+
+ /* Add a "linux,phandle" property. */
+ soff = dt_find_string(RELOC("linux,phandle"));
+ if (soff == 0)
+ prom_printf("WARNING: Can't find string index for"
+ " <linux-phandle> node %s\n", path);
+ else {
+ dt_push_token(OF_DT_PROP, mem_start, mem_end);
+ dt_push_token(4, mem_start, mem_end);
+ dt_push_token(soff, mem_start, mem_end);
+ valp = make_room(mem_start, mem_end, 4, 4);
+ *(u32 *)valp = node;
+ }
+
+ /* do all our children */
+ child = call_prom("child", 1, 1, node);
+ while (child != 0) {
+ scan_dt_build_struct(child, mem_start, mem_end);
+ child = call_prom("peer", 1, 1, child);
+ }
+
+ dt_push_token(OF_DT_END_NODE, mem_start, mem_end);
+}
+
+static void __init flatten_device_tree(void)
+{
+ phandle root;
+ unsigned long mem_start, mem_end, room;
+ struct boot_param_header *hdr;
+ struct prom_t *_prom = &RELOC(prom);
+ char *namep;
+ u64 *rsvmap;
+
+ /*
+ * Check how much room we have between alloc top & bottom (+/- a
+ * few pages), crop to 4Mb, as this is our "chuck" size
+ */
+ room = RELOC(alloc_top) - RELOC(alloc_bottom) - 0x4000;
+ if (room > DEVTREE_CHUNK_SIZE)
+ room = DEVTREE_CHUNK_SIZE;
+ prom_debug("starting device tree allocs at %x\n", RELOC(alloc_bottom));
+
+ /* Now try to claim that */
+ mem_start = (unsigned long)alloc_up(room, PAGE_SIZE);
+ if (mem_start == 0)
+ prom_panic("Can't allocate initial device-tree chunk\n");
+ mem_end = RELOC(alloc_top);
+
+ /* Get root of tree */
+ root = call_prom("peer", 1, 1, (phandle)0);
+ if (root == (phandle)0)
+ prom_panic ("couldn't get device tree root\n");
+
+ /* Build header and make room for mem rsv map */
+ mem_start = _ALIGN(mem_start, 4);
+ hdr = make_room(&mem_start, &mem_end,
+ sizeof(struct boot_param_header), 4);
+ RELOC(dt_header_start) = (unsigned long)hdr;
+ rsvmap = make_room(&mem_start, &mem_end, sizeof(mem_reserve_map), 8);
+
+ /* Start of strings */
+ mem_start = PAGE_ALIGN(mem_start);
+ RELOC(dt_string_start) = mem_start;
+ mem_start += 4; /* hole */
+
+ /* Add "linux,phandle" in there, we'll need it */
+ namep = make_room(&mem_start, &mem_end, 16, 1);
+ strcpy(namep, RELOC("linux,phandle"));
+ mem_start = (unsigned long)namep + strlen(namep) + 1;
+
+ /* Build string array */
+ prom_printf("Building dt strings...\n");
+ scan_dt_build_strings(root, &mem_start, &mem_end);
+ RELOC(dt_string_end) = mem_start;
+
+ /* Build structure */
+ mem_start = PAGE_ALIGN(mem_start);
+ RELOC(dt_struct_start) = mem_start;
+ prom_printf("Building dt structure...\n");
+ scan_dt_build_struct(root, &mem_start, &mem_end);
+ dt_push_token(OF_DT_END, &mem_start, &mem_end);
+ RELOC(dt_struct_end) = PAGE_ALIGN(mem_start);
+
+ /* Finish header */
+ hdr->boot_cpuid_phys = _prom->cpu;
+ hdr->magic = OF_DT_HEADER;
+ hdr->totalsize = RELOC(dt_struct_end) - RELOC(dt_header_start);
+ hdr->off_dt_struct = RELOC(dt_struct_start) - RELOC(dt_header_start);
+ hdr->off_dt_strings = RELOC(dt_string_start) - RELOC(dt_header_start);
+ hdr->dt_strings_size = RELOC(dt_string_end) - RELOC(dt_string_start);
+ hdr->off_mem_rsvmap = ((unsigned long)rsvmap) - RELOC(dt_header_start);
+ hdr->version = OF_DT_VERSION;
+ /* Version 16 is not backward compatible */
+ hdr->last_comp_version = 0x10;
+
+ /* Reserve the whole thing and copy the reserve map in, we
+ * also bump mem_reserve_cnt to cause further reservations to
+ * fail since it's too late.
+ */
+ reserve_mem(RELOC(dt_header_start), hdr->totalsize);
+ memcpy(rsvmap, RELOC(mem_reserve_map), sizeof(mem_reserve_map));
+
+#ifdef DEBUG_PROM
+ {
+ int i;
+ prom_printf("reserved memory map:\n");
+ for (i = 0; i < RELOC(mem_reserve_cnt); i++)
+ prom_printf(" %x - %x\n",
+ RELOC(mem_reserve_map)[i].base,
+ RELOC(mem_reserve_map)[i].size);
+ }
+#endif
+ RELOC(mem_reserve_cnt) = MEM_RESERVE_MAP_SIZE;
+
+ prom_printf("Device tree strings 0x%x -> 0x%x\n",
+ RELOC(dt_string_start), RELOC(dt_string_end));
+ prom_printf("Device tree struct 0x%x -> 0x%x\n",
+ RELOC(dt_struct_start), RELOC(dt_struct_end));
+
+}
+
+
+static void __init fixup_device_tree(void)
+{
+#if defined(CONFIG_PPC64) && defined(CONFIG_PPC_PMAC)
+ phandle u3, i2c, mpic;
+ u32 u3_rev;
+ u32 interrupts[2];
+ u32 parent;
+
+ /* Some G5s have a missing interrupt definition, fix it up here */
+ u3 = call_prom("finddevice", 1, 1, ADDR("/u3@0,f8000000"));
+ if (!PHANDLE_VALID(u3))
+ return;
+ i2c = call_prom("finddevice", 1, 1, ADDR("/u3@0,f8000000/i2c@f8001000"));
+ if (!PHANDLE_VALID(i2c))
+ return;
+ mpic = call_prom("finddevice", 1, 1, ADDR("/u3@0,f8000000/mpic@f8040000"));
+ if (!PHANDLE_VALID(mpic))
+ return;
+
+ /* check if proper rev of u3 */
+ if (prom_getprop(u3, "device-rev", &u3_rev, sizeof(u3_rev))
+ == PROM_ERROR)
+ return;
+ if (u3_rev < 0x35 || u3_rev > 0x39)
+ return;
+ /* does it need fixup ? */
+ if (prom_getproplen(i2c, "interrupts") > 0)
+ return;
+
+ prom_printf("fixing up bogus interrupts for u3 i2c...\n");
+
+ /* interrupt on this revision of u3 is number 0 and level */
+ interrupts[0] = 0;
+ interrupts[1] = 1;
+ prom_setprop(i2c, "/u3@0,f8000000/i2c@f8001000", "interrupts",
+ &interrupts, sizeof(interrupts));
+ parent = (u32)mpic;
+ prom_setprop(i2c, "/u3@0,f8000000/i2c@f8001000", "interrupt-parent",
+ &parent, sizeof(parent));
+#endif
+}
+
+
+static void __init prom_find_boot_cpu(void)
+{
+ struct prom_t *_prom = &RELOC(prom);
+ u32 getprop_rval;
+ ihandle prom_cpu;
+ phandle cpu_pkg;
+
+ _prom->cpu = 0;
+ if (prom_getprop(_prom->chosen, "cpu", &prom_cpu, sizeof(prom_cpu)) <= 0)
+ return;
+
+ cpu_pkg = call_prom("instance-to-package", 1, 1, prom_cpu);
+
+ prom_getprop(cpu_pkg, "reg", &getprop_rval, sizeof(getprop_rval));
+ _prom->cpu = getprop_rval;
+
+ prom_debug("Booting CPU hw index = 0x%x\n", _prom->cpu);
+}
+
+static void __init prom_check_initrd(unsigned long r3, unsigned long r4)
+{
+#ifdef CONFIG_BLK_DEV_INITRD
+ struct prom_t *_prom = &RELOC(prom);
+
+ if (r3 && r4 && r4 != 0xdeadbeef) {
+ unsigned long val;
+
+ RELOC(prom_initrd_start) = (r3 >= KERNELBASE) ? __pa(r3) : r3;
+ RELOC(prom_initrd_end) = RELOC(prom_initrd_start) + r4;
+
+ val = RELOC(prom_initrd_start);
+ prom_setprop(_prom->chosen, "/chosen", "linux,initrd-start",
+ &val, sizeof(val));
+ val = RELOC(prom_initrd_end);
+ prom_setprop(_prom->chosen, "/chosen", "linux,initrd-end",
+ &val, sizeof(val));
+
+ reserve_mem(RELOC(prom_initrd_start),
+ RELOC(prom_initrd_end) - RELOC(prom_initrd_start));
+
+ prom_debug("initrd_start=0x%x\n", RELOC(prom_initrd_start));
+ prom_debug("initrd_end=0x%x\n", RELOC(prom_initrd_end));
+ }
+#endif /* CONFIG_BLK_DEV_INITRD */
+}
+
+/*
+ * We enter here early on, when the Open Firmware prom is still
+ * handling exceptions and the MMU hash table for us.
+ */
+
+unsigned long __init prom_init(unsigned long r3, unsigned long r4,
+ unsigned long pp,
+ unsigned long r6, unsigned long r7)
+{
+ struct prom_t *_prom;
+ unsigned long hdr;
+ u32 getprop_rval;
+ unsigned long offset = reloc_offset();
+
+#ifdef CONFIG_PPC32
+ reloc_got2(offset);
+#endif
+
+ _prom = &RELOC(prom);
+
+ /*
+ * First zero the BSS
+ */
+ memset(&RELOC(__bss_start), 0, __bss_stop - __bss_start);
+
+ /*
+ * Init interface to Open Firmware, get some node references,
+ * like /chosen
+ */
+ prom_init_client_services(pp);
+
+ /*
+ * See if this OF is old enough that we need to do explicit maps
+ * and other workarounds
+ */
+ prom_find_mmu();
+
+ /*
+ * Init prom stdout device
+ */
+ prom_init_stdout();
+
+ /*
+ * Check for an initrd
+ */
+ prom_check_initrd(r3, r4);
+
+ /*
+ * Get default machine type. At this point, we do not differentiate
+ * between pSeries SMP and pSeries LPAR
+ */
+ RELOC(of_platform) = prom_find_machine_type();
+ getprop_rval = RELOC(of_platform);
+ prom_setprop(_prom->chosen, "/chosen", "linux,platform",
+ &getprop_rval, sizeof(getprop_rval));
+
+#ifdef CONFIG_PPC_PSERIES
+ /*
+ * On pSeries, inform the firmware about our capabilities
+ */
+ if (RELOC(of_platform) == PLATFORM_PSERIES ||
+ RELOC(of_platform) == PLATFORM_PSERIES_LPAR)
+ prom_send_capabilities();
+#endif
+
+ /*
+ * Copy the CPU hold code
+ */
+ if (RELOC(of_platform) != PLATFORM_POWERMAC)
+ copy_and_flush(0, KERNELBASE + offset, 0x100, 0);
+
+ /*
+ * Do early parsing of command line
+ */
+ early_cmdline_parse();
+
+ /*
+ * Initialize memory management within prom_init
+ */
+ prom_init_mem();
+
+ /*
+ * Determine which cpu is actually running right _now_
+ */
+ prom_find_boot_cpu();
+
+ /*
+ * Initialize display devices
+ */
+ prom_check_displays();
+
+#ifdef CONFIG_PPC64
+ /*
+ * Initialize IOMMU (TCE tables) on pSeries. Do that before anything else
+ * that uses the allocator, we need to make sure we get the top of memory
+ * available for us here...
+ */
+ if (RELOC(of_platform) == PLATFORM_PSERIES)
+ prom_initialize_tce_table();
+#endif
+
+ /*
+ * On non-powermacs, try to instantiate RTAS and puts all CPUs
+ * in spin-loops. PowerMacs don't have a working RTAS and use
+ * a different way to spin CPUs
+ */
+ if (RELOC(of_platform) != PLATFORM_POWERMAC) {
+ prom_instantiate_rtas();
+ prom_hold_cpus();
+ }
+
+ /*
+ * Fill in some infos for use by the kernel later on
+ */
+ if (RELOC(prom_memory_limit))
+ prom_setprop(_prom->chosen, "/chosen", "linux,memory-limit",
+ &RELOC(prom_memory_limit),
+ sizeof(prom_memory_limit));
+#ifdef CONFIG_PPC64
+ if (RELOC(ppc64_iommu_off))
+ prom_setprop(_prom->chosen, "/chosen", "linux,iommu-off",
+ NULL, 0);
+
+ if (RELOC(iommu_force_on))
+ prom_setprop(_prom->chosen, "/chosen", "linux,iommu-force-on",
+ NULL, 0);
+
+ if (RELOC(prom_tce_alloc_start)) {
+ prom_setprop(_prom->chosen, "/chosen", "linux,tce-alloc-start",
+ &RELOC(prom_tce_alloc_start),
+ sizeof(prom_tce_alloc_start));
+ prom_setprop(_prom->chosen, "/chosen", "linux,tce-alloc-end",
+ &RELOC(prom_tce_alloc_end),
+ sizeof(prom_tce_alloc_end));
+ }
+#endif
+
+ /*
+ * Fixup any known bugs in the device-tree
+ */
+ fixup_device_tree();
+
+ /*
+ * Now finally create the flattened device-tree
+ */
+ prom_printf("copying OF device tree ...\n");
+ flatten_device_tree();
+
+ /*
+ * in case stdin is USB and still active on IBM machines...
+ * Unfortunately quiesce crashes on some powermacs if we have
+ * closed stdin already (in particular the powerbook 101).
+ */
+ if (RELOC(of_platform) != PLATFORM_POWERMAC)
+ prom_close_stdin();
+
+ /*
+ * Call OF "quiesce" method to shut down pending DMA's from
+ * devices etc...
+ */
+ prom_printf("Calling quiesce ...\n");
+ call_prom("quiesce", 0, 0);
+
+ /*
+ * And finally, call the kernel passing it the flattened device
+ * tree and NULL as r5, thus triggering the new entry point which
+ * is common to us and kexec
+ */
+ hdr = RELOC(dt_header_start);
+ prom_printf("returning from prom_init\n");
+ prom_debug("->dt_header_start=0x%x\n", hdr);
+
+#ifdef CONFIG_PPC32
+ reloc_got2(-offset);
+#endif
+
+ __start(hdr, KERNELBASE + offset, 0);
+
+ return 0;
+}
diff --git a/arch/ppc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
index e7aee4108dea..3d2abd95c7ae 100644
--- a/arch/ppc/kernel/ptrace.c
+++ b/arch/powerpc/kernel/ptrace.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/kernel/ptrace.c
- *
* PowerPC version
* Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
*
@@ -10,13 +8,14 @@
* linux/kernel/ptrace.c is by Ross Biro 1/23/92, edited by Linus Torvalds
*
* Modified by Cort Dougan (cort@hq.fsmlabs.com)
- * and Paul Mackerras (paulus@linuxcare.com.au).
+ * and Paul Mackerras (paulus@samba.org).
*
* This file is subject to the terms and conditions of the GNU General
* Public License. See the file README.legal in the main directory of
* this archive for more details.
*/
+#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/mm.h>
@@ -29,13 +28,19 @@
#include <linux/signal.h>
#include <linux/seccomp.h>
#include <linux/audit.h>
+#ifdef CONFIG_PPC32
#include <linux/module.h>
+#endif
#include <asm/uaccess.h>
#include <asm/page.h>
#include <asm/pgtable.h>
#include <asm/system.h>
+#ifdef CONFIG_PPC64
+#include <asm/ptrace-common.h>
+#endif
+#ifdef CONFIG_PPC32
/*
* Set of msr bits that gdb can change on behalf of a process.
*/
@@ -44,12 +49,14 @@
#else
#define MSR_DEBUGCHANGE (MSR_SE | MSR_BE)
#endif
+#endif /* CONFIG_PPC32 */
/*
* does not yet catch signals sent when the child dies.
* in exit.c or in signal.c.
*/
+#ifdef CONFIG_PPC32
/*
* Get contents of register REGNO in task TASK.
*/
@@ -228,6 +235,7 @@ clear_single_step(struct task_struct *task)
#endif
}
}
+#endif /* CONFIG_PPC32 */
/*
* Called by kernel/ptrace.c when detaching..
@@ -240,46 +248,10 @@ void ptrace_disable(struct task_struct *child)
clear_single_step(child);
}
-int sys_ptrace(long request, long pid, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request, long addr, long data)
{
- struct task_struct *child;
int ret = -EPERM;
- lock_kernel();
- if (request == PTRACE_TRACEME) {
- /* are we already being traced? */
- if (current->ptrace & PT_PTRACED)
- goto out;
- ret = security_ptrace(current->parent, current);
- if (ret)
- goto out;
- /* set the ptrace bit in the process flags. */
- current->ptrace |= PT_PTRACED;
- ret = 0;
- goto out;
- }
- ret = -ESRCH;
- read_lock(&tasklist_lock);
- child = find_task_by_pid(pid);
- if (child)
- get_task_struct(child);
- read_unlock(&tasklist_lock);
- if (!child)
- goto out;
-
- ret = -EPERM;
- if (pid == 1) /* you may not mess with init */
- goto out_tsk;
-
- if (request == PTRACE_ATTACH) {
- ret = ptrace_attach(child);
- goto out_tsk;
- }
-
- ret = ptrace_check_attach(child, request == PTRACE_KILL);
- if (ret < 0)
- goto out_tsk;
-
switch (request) {
/* when I and D space are separate, these will need to be fixed. */
case PTRACE_PEEKTEXT: /* read word at location addr. */
@@ -296,25 +268,28 @@ int sys_ptrace(long request, long pid, long addr, long data)
}
/* read the word at location addr in the USER area. */
- /* XXX this will need fixing for 64-bit */
case PTRACE_PEEKUSR: {
unsigned long index, tmp;
ret = -EIO;
/* convert to index and check */
+#ifdef CONFIG_PPC32
index = (unsigned long) addr >> 2;
- if ((addr & 3) || index > PT_FPSCR
- || child->thread.regs == NULL)
+ if ((addr & 3) || (index > PT_FPSCR)
+ || (child->thread.regs == NULL))
+#else
+ index = (unsigned long) addr >> 3;
+ if ((addr & 7) || (index > PT_FPSCR))
+#endif
break;
+#ifdef CONFIG_PPC32
CHECK_FULL_REGS(child->thread.regs);
+#endif
if (index < PT_FPR0) {
tmp = get_reg(child, (int) index);
} else {
- preempt_disable();
- if (child->thread.regs->msr & MSR_FP)
- giveup_fpu(child);
- preempt_enable();
+ flush_fp_to_thread(child);
tmp = ((unsigned long *)child->thread.fpr)[index - PT_FPR0];
}
ret = put_user(tmp,(unsigned long __user *) data);
@@ -325,7 +300,8 @@ int sys_ptrace(long request, long pid, long addr, long data)
case PTRACE_POKETEXT: /* write the word at location addr. */
case PTRACE_POKEDATA:
ret = 0;
- if (access_process_vm(child, addr, &data, sizeof(data), 1) == sizeof(data))
+ if (access_process_vm(child, addr, &data, sizeof(data), 1)
+ == sizeof(data))
break;
ret = -EIO;
break;
@@ -336,21 +312,25 @@ int sys_ptrace(long request, long pid, long addr, long data)
ret = -EIO;
/* convert to index and check */
+#ifdef CONFIG_PPC32
index = (unsigned long) addr >> 2;
- if ((addr & 3) || index > PT_FPSCR
- || child->thread.regs == NULL)
+ if ((addr & 3) || (index > PT_FPSCR)
+ || (child->thread.regs == NULL))
+#else
+ index = (unsigned long) addr >> 3;
+ if ((addr & 7) || (index > PT_FPSCR))
+#endif
break;
+#ifdef CONFIG_PPC32
CHECK_FULL_REGS(child->thread.regs);
+#endif
if (index == PT_ORIG_R3)
break;
if (index < PT_FPR0) {
ret = put_reg(child, index, data);
} else {
- preempt_disable();
- if (child->thread.regs->msr & MSR_FP)
- giveup_fpu(child);
- preempt_enable();
+ flush_fp_to_thread(child);
((unsigned long *)child->thread.fpr)[index - PT_FPR0] = data;
ret = 0;
}
@@ -362,11 +342,10 @@ int sys_ptrace(long request, long pid, long addr, long data)
ret = -EIO;
if (!valid_signal(data))
break;
- if (request == PTRACE_SYSCALL) {
+ if (request == PTRACE_SYSCALL)
set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
- } else {
+ else
clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
- }
child->exit_code = data;
/* make sure the single step bit is not set. */
clear_single_step(child);
@@ -404,28 +383,102 @@ int sys_ptrace(long request, long pid, long addr, long data)
break;
}
+#ifdef CONFIG_PPC64
+ case PTRACE_GET_DEBUGREG: {
+ ret = -EINVAL;
+ /* We only support one DABR and no IABRS at the moment */
+ if (addr > 0)
+ break;
+ ret = put_user(child->thread.dabr,
+ (unsigned long __user *)data);
+ break;
+ }
+
+ case PTRACE_SET_DEBUGREG:
+ ret = ptrace_set_debugreg(child, addr, data);
+ break;
+#endif
+
case PTRACE_DETACH:
ret = ptrace_detach(child, data);
break;
+#ifdef CONFIG_PPC64
+ case PPC_PTRACE_GETREGS: { /* Get GPRs 0 - 31. */
+ int i;
+ unsigned long *reg = &((unsigned long *)child->thread.regs)[0];
+ unsigned long __user *tmp = (unsigned long __user *)addr;
+
+ for (i = 0; i < 32; i++) {
+ ret = put_user(*reg, tmp);
+ if (ret)
+ break;
+ reg++;
+ tmp++;
+ }
+ break;
+ }
+
+ case PPC_PTRACE_SETREGS: { /* Set GPRs 0 - 31. */
+ int i;
+ unsigned long *reg = &((unsigned long *)child->thread.regs)[0];
+ unsigned long __user *tmp = (unsigned long __user *)addr;
+
+ for (i = 0; i < 32; i++) {
+ ret = get_user(*reg, tmp);
+ if (ret)
+ break;
+ reg++;
+ tmp++;
+ }
+ break;
+ }
+
+ case PPC_PTRACE_GETFPREGS: { /* Get FPRs 0 - 31. */
+ int i;
+ unsigned long *reg = &((unsigned long *)child->thread.fpr)[0];
+ unsigned long __user *tmp = (unsigned long __user *)addr;
+
+ flush_fp_to_thread(child);
+
+ for (i = 0; i < 32; i++) {
+ ret = put_user(*reg, tmp);
+ if (ret)
+ break;
+ reg++;
+ tmp++;
+ }
+ break;
+ }
+
+ case PPC_PTRACE_SETFPREGS: { /* Get FPRs 0 - 31. */
+ int i;
+ unsigned long *reg = &((unsigned long *)child->thread.fpr)[0];
+ unsigned long __user *tmp = (unsigned long __user *)addr;
+
+ flush_fp_to_thread(child);
+
+ for (i = 0; i < 32; i++) {
+ ret = get_user(*reg, tmp);
+ if (ret)
+ break;
+ reg++;
+ tmp++;
+ }
+ break;
+ }
+#endif /* CONFIG_PPC64 */
+
#ifdef CONFIG_ALTIVEC
case PTRACE_GETVRREGS:
/* Get the child altivec register state. */
- preempt_disable();
- if (child->thread.regs->msr & MSR_VEC)
- giveup_altivec(child);
- preempt_enable();
+ flush_altivec_to_thread(child);
ret = get_vrregs((unsigned long __user *)data, child);
break;
case PTRACE_SETVRREGS:
/* Set the child altivec register state. */
- /* this is to clear the MSR_VEC bit to force a reload
- * of register state from memory */
- preempt_disable();
- if (child->thread.regs->msr & MSR_VEC)
- giveup_altivec(child);
- preempt_enable();
+ flush_altivec_to_thread(child);
ret = set_vrregs(child, (unsigned long __user *)data);
break;
#endif
@@ -451,10 +504,7 @@ int sys_ptrace(long request, long pid, long addr, long data)
ret = ptrace_request(child, request, addr, data);
break;
}
-out_tsk:
- put_task_struct(child);
-out:
- unlock_kernel();
+
return ret;
}
@@ -478,12 +528,21 @@ static void do_syscall_trace(void)
void do_syscall_trace_enter(struct pt_regs *regs)
{
+#ifdef CONFIG_PPC64
+ secure_computing(regs->gpr[0]);
+#endif
+
if (test_thread_flag(TIF_SYSCALL_TRACE)
&& (current->ptrace & PT_PTRACED))
do_syscall_trace();
if (unlikely(current->audit_context))
- audit_syscall_entry(current, AUDIT_ARCH_PPC,
+ audit_syscall_entry(current,
+#ifdef CONFIG_PPC32
+ AUDIT_ARCH_PPC,
+#else
+ test_thread_flag(TIF_32BIT)?AUDIT_ARCH_PPC:AUDIT_ARCH_PPC64,
+#endif
regs->gpr[0],
regs->gpr[3], regs->gpr[4],
regs->gpr[5], regs->gpr[6]);
@@ -491,17 +550,25 @@ void do_syscall_trace_enter(struct pt_regs *regs)
void do_syscall_trace_leave(struct pt_regs *regs)
{
+#ifdef CONFIG_PPC32
secure_computing(regs->gpr[0]);
+#endif
if (unlikely(current->audit_context))
audit_syscall_exit(current,
(regs->ccr&0x1000)?AUDITSC_FAILURE:AUDITSC_SUCCESS,
regs->result);
- if ((test_thread_flag(TIF_SYSCALL_TRACE))
+ if ((test_thread_flag(TIF_SYSCALL_TRACE)
+#ifdef CONFIG_PPC64
+ || test_thread_flag(TIF_SINGLESTEP)
+#endif
+ )
&& (current->ptrace & PT_PTRACED))
do_syscall_trace();
}
+#ifdef CONFIG_PPC32
EXPORT_SYMBOL(do_syscall_trace_enter);
EXPORT_SYMBOL(do_syscall_trace_leave);
+#endif
diff --git a/arch/ppc64/kernel/ptrace32.c b/arch/powerpc/kernel/ptrace32.c
index fb8c22d6084a..91eb952e0293 100644
--- a/arch/ppc64/kernel/ptrace32.c
+++ b/arch/powerpc/kernel/ptrace32.c
@@ -1,5 +1,5 @@
/*
- * linux/arch/ppc64/kernel/ptrace32.c
+ * ptrace for 32-bit processes running on a 64-bit kernel.
*
* PowerPC version
* Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
@@ -10,10 +10,10 @@
* linux/kernel/ptrace.c is by Ross Biro 1/23/92, edited by Linus Torvalds
*
* Modified by Cort Dougan (cort@hq.fsmlabs.com)
- * and Paul Mackerras (paulus@linuxcare.com.au).
+ * and Paul Mackerras (paulus@samba.org).
*
* This file is subject to the terms and conditions of the GNU General
- * Public License. See the file README.legal in the main directory of
+ * Public License. See the file COPYING in the main directory of
* this archive for more details.
*/
@@ -40,7 +40,8 @@
* in exit.c or in signal.c.
*/
-int sys32_ptrace(long request, long pid, unsigned long addr, unsigned long data)
+long compat_sys_ptrace(int request, int pid, unsigned long addr,
+ unsigned long data)
{
struct task_struct *child;
int ret = -EPERM;
diff --git a/arch/ppc64/kernel/rtas-proc.c b/arch/powerpc/kernel/rtas-proc.c
index 1f3ff860fdf0..ae1a36449ccd 100644
--- a/arch/ppc64/kernel/rtas-proc.c
+++ b/arch/powerpc/kernel/rtas-proc.c
@@ -23,6 +23,7 @@
#include <linux/init.h>
#include <linux/seq_file.h>
#include <linux/bitops.h>
+#include <linux/rtc.h>
#include <asm/uaccess.h>
#include <asm/processor.h>
@@ -258,7 +259,7 @@ static int __init proc_rtas_init(void)
{
struct proc_dir_entry *entry;
- if (!(systemcfg->platform & PLATFORM_PSERIES))
+ if (_machine != PLATFORM_PSERIES && _machine != PLATFORM_PSERIES_LPAR)
return 1;
rtas_node = of_find_node_by_name(NULL, "rtas");
diff --git a/arch/ppc64/kernel/rtas.c b/arch/powerpc/kernel/rtas.c
index 5e8eb33b8e54..4283fa33f784 100644
--- a/arch/ppc64/kernel/rtas.c
+++ b/arch/powerpc/kernel/rtas.c
@@ -17,6 +17,7 @@
#include <linux/spinlock.h>
#include <linux/module.h>
#include <linux/init.h>
+#include <linux/delay.h>
#include <asm/prom.h>
#include <asm/rtas.h>
@@ -25,28 +26,33 @@
#include <asm/page.h>
#include <asm/param.h>
#include <asm/system.h>
-#include <asm/abs_addr.h>
-#include <asm/udbg.h>
#include <asm/delay.h>
#include <asm/uaccess.h>
-#include <asm/systemcfg.h>
+#include <asm/lmb.h>
-struct flash_block_list_header rtas_firmware_flash_list = {0, NULL};
-
-struct rtas_t rtas = {
+struct rtas_t rtas = {
.lock = SPIN_LOCK_UNLOCKED
};
EXPORT_SYMBOL(rtas);
-char rtas_err_buf[RTAS_ERROR_LOG_MAX];
-
DEFINE_SPINLOCK(rtas_data_buf_lock);
-char rtas_data_buf[RTAS_DATA_BUF_SIZE]__page_aligned;
+char rtas_data_buf[RTAS_DATA_BUF_SIZE] __cacheline_aligned;
unsigned long rtas_rmo_buf;
-void
-call_rtas_display_status(unsigned char c)
+/*
+ * If non-NULL, this gets called when the kernel terminates.
+ * This is done like this so rtas_flash can be a module.
+ */
+void (*rtas_flash_term_hook)(int);
+EXPORT_SYMBOL(rtas_flash_term_hook);
+
+/*
+ * call_rtas_display_status and call_rtas_display_status_delay
+ * are designed only for very early low-level debugging, which
+ * is why the token is hard-coded to 10.
+ */
+void call_rtas_display_status(unsigned char c)
{
struct rtas_args *args = &rtas.args;
unsigned long s;
@@ -66,8 +72,7 @@ call_rtas_display_status(unsigned char c)
spin_unlock_irqrestore(&rtas.lock, s);
}
-void
-call_rtas_display_status_delay(unsigned char c)
+void call_rtas_display_status_delay(unsigned char c)
{
static int pending_newline = 0; /* did last write end with unprinted newline? */
static int width = 16;
@@ -76,7 +81,7 @@ call_rtas_display_status_delay(unsigned char c)
while (width-- > 0)
call_rtas_display_status(' ');
width = 16;
- udelay(500000);
+ mdelay(500);
pending_newline = 1;
} else {
if (pending_newline) {
@@ -91,8 +96,7 @@ call_rtas_display_status_delay(unsigned char c)
}
}
-void
-rtas_progress(char *s, unsigned short hex)
+void rtas_progress(char *s, unsigned short hex)
{
struct device_node *root;
int width, *p;
@@ -207,19 +211,18 @@ rtas_progress(char *s, unsigned short hex)
spin_unlock(&progress_lock);
}
+EXPORT_SYMBOL(rtas_progress); /* needed by rtas_flash module */
-int
-rtas_token(const char *service)
+int rtas_token(const char *service)
{
int *tokp;
- if (rtas.dev == NULL) {
- PPCDBG(PPCDBG_RTAS,"\tNo rtas device in device-tree...\n");
+ if (rtas.dev == NULL)
return RTAS_UNKNOWN_SERVICE;
- }
tokp = (int *) get_property(rtas.dev, service, NULL);
return tokp ? *tokp : RTAS_UNKNOWN_SERVICE;
}
+#ifdef CONFIG_RTAS_ERROR_LOGGING
/*
* Return the firmware-specified size of the error log buffer
* for all rtas calls that require an error buffer argument.
@@ -234,31 +237,38 @@ int rtas_get_error_log_max(void)
rtas_error_log_max = rtas_token ("rtas-error-log-max");
if ((rtas_error_log_max == RTAS_UNKNOWN_SERVICE) ||
(rtas_error_log_max > RTAS_ERROR_LOG_MAX)) {
- printk (KERN_WARNING "RTAS: bad log buffer size %d\n", rtas_error_log_max);
+ printk (KERN_WARNING "RTAS: bad log buffer size %d\n",
+ rtas_error_log_max);
rtas_error_log_max = RTAS_ERROR_LOG_MAX;
}
return rtas_error_log_max;
}
+EXPORT_SYMBOL(rtas_get_error_log_max);
+char rtas_err_buf[RTAS_ERROR_LOG_MAX];
+int rtas_last_error_token;
+
/** Return a copy of the detailed error text associated with the
* most recent failed call to rtas. Because the error text
* might go stale if there are any other intervening rtas calls,
* this routine must be called atomically with whatever produced
* the error (i.e. with rtas.lock still held from the previous call).
*/
-static int
-__fetch_rtas_last_error(void)
+static char *__fetch_rtas_last_error(char *altbuf)
{
struct rtas_args err_args, save_args;
u32 bufsz;
+ char *buf = NULL;
+
+ if (rtas_last_error_token == -1)
+ return NULL;
bufsz = rtas_get_error_log_max();
- err_args.token = rtas_token("rtas-last-error");
+ err_args.token = rtas_last_error_token;
err_args.nargs = 2;
err_args.nret = 1;
-
err_args.args[0] = (rtas_arg_t)__pa(rtas_err_buf);
err_args.args[1] = bufsz;
err_args.args[2] = 0;
@@ -271,23 +281,38 @@ __fetch_rtas_last_error(void)
err_args = rtas.args;
rtas.args = save_args;
- return err_args.args[2];
+ /* Log the error in the unlikely case that there was one. */
+ if (unlikely(err_args.args[2] == 0)) {
+ if (altbuf) {
+ buf = altbuf;
+ } else {
+ buf = rtas_err_buf;
+ if (mem_init_done)
+ buf = kmalloc(RTAS_ERROR_LOG_MAX, GFP_ATOMIC);
+ }
+ if (buf)
+ memcpy(buf, rtas_err_buf, RTAS_ERROR_LOG_MAX);
+ }
+
+ return buf;
}
+#define get_errorlog_buffer() kmalloc(RTAS_ERROR_LOG_MAX, GFP_KERNEL)
+
+#else /* CONFIG_RTAS_ERROR_LOGGING */
+#define __fetch_rtas_last_error(x) NULL
+#define get_errorlog_buffer() NULL
+#endif
+
int rtas_call(int token, int nargs, int nret, int *outputs, ...)
{
va_list list;
- int i, logit = 0;
+ int i;
unsigned long s;
struct rtas_args *rtas_args;
- char * buff_copy = NULL;
+ char *buff_copy = NULL;
int ret;
- PPCDBG(PPCDBG_RTAS, "Entering rtas_call\n");
- PPCDBG(PPCDBG_RTAS, "\ttoken = 0x%x\n", token);
- PPCDBG(PPCDBG_RTAS, "\tnargs = %d\n", nargs);
- PPCDBG(PPCDBG_RTAS, "\tnret = %d\n", nret);
- PPCDBG(PPCDBG_RTAS, "\t&outputs = 0x%lx\n", outputs);
if (token == RTAS_UNKNOWN_SERVICE)
return -1;
@@ -300,46 +325,25 @@ int rtas_call(int token, int nargs, int nret, int *outputs, ...)
rtas_args->nret = nret;
rtas_args->rets = (rtas_arg_t *)&(rtas_args->args[nargs]);
va_start(list, outputs);
- for (i = 0; i < nargs; ++i) {
+ for (i = 0; i < nargs; ++i)
rtas_args->args[i] = va_arg(list, rtas_arg_t);
- PPCDBG(PPCDBG_RTAS, "\tnarg[%d] = 0x%x\n", i, rtas_args->args[i]);
- }
va_end(list);
for (i = 0; i < nret; ++i)
rtas_args->rets[i] = 0;
- PPCDBG(PPCDBG_RTAS, "\tentering rtas with 0x%lx\n",
- __pa(rtas_args));
enter_rtas(__pa(rtas_args));
- PPCDBG(PPCDBG_RTAS, "\treturned from rtas ...\n");
/* A -1 return code indicates that the last command couldn't
be completed due to a hardware error. */
if (rtas_args->rets[0] == -1)
- logit = (__fetch_rtas_last_error() == 0);
-
- ifppcdebug(PPCDBG_RTAS) {
- for(i=0; i < nret ;i++)
- udbg_printf("\tnret[%d] = 0x%lx\n", i, (ulong)rtas_args->rets[i]);
- }
+ buff_copy = __fetch_rtas_last_error(NULL);
if (nret > 1 && outputs != NULL)
for (i = 0; i < nret-1; ++i)
outputs[i] = rtas_args->rets[i+1];
ret = (nret > 0)? rtas_args->rets[0]: 0;
- /* Log the error in the unlikely case that there was one. */
- if (unlikely(logit)) {
- buff_copy = rtas_err_buf;
- if (mem_init_done) {
- buff_copy = kmalloc(RTAS_ERROR_LOG_MAX, GFP_ATOMIC);
- if (buff_copy)
- memcpy(buff_copy, rtas_err_buf,
- RTAS_ERROR_LOG_MAX);
- }
- }
-
/* Gotta do something different here, use global lock for now... */
spin_unlock_irqrestore(&rtas.lock, s);
@@ -354,8 +358,7 @@ int rtas_call(int token, int nargs, int nret, int *outputs, ...)
/* Given an RTAS status code of 990n compute the hinted delay of 10^n
* (last digit) milliseconds. For now we bound at n=5 (100 sec).
*/
-unsigned int
-rtas_extended_busy_delay_time(int status)
+unsigned int rtas_extended_busy_delay_time(int status)
{
int order = status - 9900;
unsigned long ms;
@@ -366,7 +369,7 @@ rtas_extended_busy_delay_time(int status)
order = 5; /* bound */
/* Use microseconds for reasonable accuracy */
- for (ms=1; order > 0; order--)
+ for (ms = 1; order > 0; order--)
ms *= 10;
return ms;
@@ -493,113 +496,33 @@ int rtas_set_indicator(int indicator, int index, int new_value)
return rc;
}
-#define FLASH_BLOCK_LIST_VERSION (1UL)
-static void
-rtas_flash_firmware(void)
+void rtas_restart(char *cmd)
{
- unsigned long image_size;
- struct flash_block_list *f, *next, *flist;
- unsigned long rtas_block_list;
- int i, status, update_token;
-
- update_token = rtas_token("ibm,update-flash-64-and-reboot");
- if (update_token == RTAS_UNKNOWN_SERVICE) {
- printk(KERN_ALERT "FLASH: ibm,update-flash-64-and-reboot is not available -- not a service partition?\n");
- printk(KERN_ALERT "FLASH: firmware will not be flashed\n");
- return;
- }
-
- /* NOTE: the "first" block list is a global var with no data
- * blocks in the kernel data segment. We do this because
- * we want to ensure this block_list addr is under 4GB.
- */
- rtas_firmware_flash_list.num_blocks = 0;
- flist = (struct flash_block_list *)&rtas_firmware_flash_list;
- rtas_block_list = virt_to_abs(flist);
- if (rtas_block_list >= 4UL*1024*1024*1024) {
- printk(KERN_ALERT "FLASH: kernel bug...flash list header addr above 4GB\n");
- return;
- }
-
- printk(KERN_ALERT "FLASH: preparing saved firmware image for flash\n");
- /* Update the block_list in place. */
- image_size = 0;
- for (f = flist; f; f = next) {
- /* Translate data addrs to absolute */
- for (i = 0; i < f->num_blocks; i++) {
- f->blocks[i].data = (char *)virt_to_abs(f->blocks[i].data);
- image_size += f->blocks[i].length;
- }
- next = f->next;
- /* Don't translate NULL pointer for last entry */
- if (f->next)
- f->next = (struct flash_block_list *)virt_to_abs(f->next);
- else
- f->next = NULL;
- /* make num_blocks into the version/length field */
- f->num_blocks = (FLASH_BLOCK_LIST_VERSION << 56) | ((f->num_blocks+1)*16);
- }
-
- printk(KERN_ALERT "FLASH: flash image is %ld bytes\n", image_size);
- printk(KERN_ALERT "FLASH: performing flash and reboot\n");
- rtas_progress("Flashing \n", 0x0);
- rtas_progress("Please Wait... ", 0x0);
- printk(KERN_ALERT "FLASH: this will take several minutes. Do not power off!\n");
- status = rtas_call(update_token, 1, 1, NULL, rtas_block_list);
- switch (status) { /* should only get "bad" status */
- case 0:
- printk(KERN_ALERT "FLASH: success\n");
- break;
- case -1:
- printk(KERN_ALERT "FLASH: hardware error. Firmware may not be not flashed\n");
- break;
- case -3:
- printk(KERN_ALERT "FLASH: image is corrupt or not correct for this platform. Firmware not flashed\n");
- break;
- case -4:
- printk(KERN_ALERT "FLASH: flash failed when partially complete. System may not reboot\n");
- break;
- default:
- printk(KERN_ALERT "FLASH: unknown flash return code %d\n", status);
- break;
- }
-}
-
-void rtas_flash_bypass_warning(void)
-{
- printk(KERN_ALERT "FLASH: firmware flash requires a reboot\n");
- printk(KERN_ALERT "FLASH: the firmware image will NOT be flashed\n");
-}
-
-
-void
-rtas_restart(char *cmd)
-{
- if (rtas_firmware_flash_list.next)
- rtas_flash_firmware();
-
+ if (rtas_flash_term_hook)
+ rtas_flash_term_hook(SYS_RESTART);
printk("RTAS system-reboot returned %d\n",
rtas_call(rtas_token("system-reboot"), 0, 1, NULL));
for (;;);
}
-void
-rtas_power_off(void)
+void rtas_power_off(void)
{
- if (rtas_firmware_flash_list.next)
- rtas_flash_bypass_warning();
+ if (rtas_flash_term_hook)
+ rtas_flash_term_hook(SYS_POWER_OFF);
/* allow power on only with power button press */
printk("RTAS power-off returned %d\n",
rtas_call(rtas_token("power-off"), 2, 1, NULL, -1, -1));
for (;;);
}
-void
-rtas_halt(void)
+void rtas_halt(void)
{
- if (rtas_firmware_flash_list.next)
- rtas_flash_bypass_warning();
- rtas_power_off();
+ if (rtas_flash_term_hook)
+ rtas_flash_term_hook(SYS_HALT);
+ /* allow power on only with power button press */
+ printk("RTAS power-off returned %d\n",
+ rtas_call(rtas_token("power-off"), 2, 1, NULL, -1, -1));
+ for (;;);
}
/* Must be in the RMO region, so we place it here */
@@ -631,9 +554,8 @@ asmlinkage int ppc_rtas(struct rtas_args __user *uargs)
{
struct rtas_args args;
unsigned long flags;
- char * buff_copy;
+ char *buff_copy, *errbuf = NULL;
int nargs;
- int err_rc = 0;
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
@@ -652,7 +574,7 @@ asmlinkage int ppc_rtas(struct rtas_args __user *uargs)
nargs * sizeof(rtas_arg_t)) != 0)
return -EFAULT;
- buff_copy = kmalloc(RTAS_ERROR_LOG_MAX, GFP_KERNEL);
+ buff_copy = get_errorlog_buffer();
spin_lock_irqsave(&rtas.lock, flags);
@@ -664,19 +586,14 @@ asmlinkage int ppc_rtas(struct rtas_args __user *uargs)
/* A -1 return code indicates that the last command couldn't
be completed due to a hardware error. */
- if (args.rets[0] == -1) {
- err_rc = __fetch_rtas_last_error();
- if ((err_rc == 0) && buff_copy) {
- memcpy(buff_copy, rtas_err_buf, RTAS_ERROR_LOG_MAX);
- }
- }
+ if (args.rets[0] == -1)
+ errbuf = __fetch_rtas_last_error(buff_copy);
spin_unlock_irqrestore(&rtas.lock, flags);
if (buff_copy) {
- if ((args.rets[0] == -1) && (err_rc == 0)) {
- log_error(buff_copy, ERR_TYPE_RTAS_LOG, 0);
- }
+ if (errbuf)
+ log_error(errbuf, ERR_TYPE_RTAS_LOG, 0);
kfree(buff_copy);
}
@@ -721,6 +638,8 @@ void rtas_stop_self(void)
*/
void __init rtas_initialize(void)
{
+ unsigned long rtas_region = RTAS_INSTANTIATE_MAX;
+
/* Get RTAS dev node and fill up our "rtas" structure with infos
* about it.
*/
@@ -742,26 +661,27 @@ void __init rtas_initialize(void)
} else
rtas.dev = NULL;
}
+ if (!rtas.dev)
+ return;
+
/* If RTAS was found, allocate the RMO buffer for it and look for
* the stop-self token if any
*/
- if (rtas.dev) {
- unsigned long rtas_region = RTAS_INSTANTIATE_MAX;
- if (systemcfg->platform == PLATFORM_PSERIES_LPAR)
- rtas_region = min(lmb.rmo_size, RTAS_INSTANTIATE_MAX);
-
- rtas_rmo_buf = lmb_alloc_base(RTAS_RMOBUF_MAX, PAGE_SIZE,
- rtas_region);
+#ifdef CONFIG_PPC64
+ if (_machine == PLATFORM_PSERIES_LPAR)
+ rtas_region = min(lmb.rmo_size, RTAS_INSTANTIATE_MAX);
+#endif
+ rtas_rmo_buf = lmb_alloc_base(RTAS_RMOBUF_MAX, PAGE_SIZE, rtas_region);
#ifdef CONFIG_HOTPLUG_CPU
- rtas_stop_self_args.token = rtas_token("stop-self");
+ rtas_stop_self_args.token = rtas_token("stop-self");
#endif /* CONFIG_HOTPLUG_CPU */
- }
-
+#ifdef CONFIG_RTAS_ERROR_LOGGING
+ rtas_last_error_token = rtas_token("rtas-last-error");
+#endif
}
-EXPORT_SYMBOL(rtas_firmware_flash_list);
EXPORT_SYMBOL(rtas_token);
EXPORT_SYMBOL(rtas_call);
EXPORT_SYMBOL(rtas_data_buf);
@@ -771,4 +691,3 @@ EXPORT_SYMBOL(rtas_get_sensor);
EXPORT_SYMBOL(rtas_get_power_level);
EXPORT_SYMBOL(rtas_set_power_level);
EXPORT_SYMBOL(rtas_set_indicator);
-EXPORT_SYMBOL(rtas_get_error_log_max);
diff --git a/arch/ppc64/kernel/rtas_flash.c b/arch/powerpc/kernel/rtas_flash.c
index 923e2e201a70..50500093c97f 100644
--- a/arch/ppc64/kernel/rtas_flash.c
+++ b/arch/powerpc/kernel/rtas_flash.c
@@ -19,6 +19,7 @@
#include <asm/delay.h>
#include <asm/uaccess.h>
#include <asm/rtas.h>
+#include <asm/abs_addr.h>
#define MODULE_VERS "1.0"
#define MODULE_NAME "rtas_flash"
@@ -71,10 +72,36 @@
#define VALIDATE_BUF_SIZE 4096
#define RTAS_MSG_MAXLEN 64
+struct flash_block {
+ char *data;
+ unsigned long length;
+};
+
+/* This struct is very similar but not identical to
+ * that needed by the rtas flash update.
+ * All we need to do for rtas is rewrite num_blocks
+ * into a version/length and translate the pointers
+ * to absolute.
+ */
+#define FLASH_BLOCKS_PER_NODE ((PAGE_SIZE - 16) / sizeof(struct flash_block))
+struct flash_block_list {
+ unsigned long num_blocks;
+ struct flash_block_list *next;
+ struct flash_block blocks[FLASH_BLOCKS_PER_NODE];
+};
+struct flash_block_list_header { /* just the header of flash_block_list */
+ unsigned long num_blocks;
+ struct flash_block_list *next;
+};
+
+static struct flash_block_list_header rtas_firmware_flash_list = {0, NULL};
+
+#define FLASH_BLOCK_LIST_VERSION (1UL)
+
/* Local copy of the flash block list.
* We only allow one open of the flash proc file and create this
- * list as we go. This list will be put in the kernel's
- * rtas_firmware_flash_list global var once it is fully read.
+ * list as we go. This list will be put in the
+ * rtas_firmware_flash_list var once it is fully read.
*
* For convenience as we build the list we use virtual addrs,
* we do not fill in the version number, and the length field
@@ -562,6 +589,86 @@ static int validate_flash_release(struct inode *inode, struct file *file)
return 0;
}
+static void rtas_flash_firmware(int reboot_type)
+{
+ unsigned long image_size;
+ struct flash_block_list *f, *next, *flist;
+ unsigned long rtas_block_list;
+ int i, status, update_token;
+
+ if (rtas_firmware_flash_list.next == NULL)
+ return; /* nothing to do */
+
+ if (reboot_type != SYS_RESTART) {
+ printk(KERN_ALERT "FLASH: firmware flash requires a reboot\n");
+ printk(KERN_ALERT "FLASH: the firmware image will NOT be flashed\n");
+ return;
+ }
+
+ update_token = rtas_token("ibm,update-flash-64-and-reboot");
+ if (update_token == RTAS_UNKNOWN_SERVICE) {
+ printk(KERN_ALERT "FLASH: ibm,update-flash-64-and-reboot "
+ "is not available -- not a service partition?\n");
+ printk(KERN_ALERT "FLASH: firmware will not be flashed\n");
+ return;
+ }
+
+ /* NOTE: the "first" block list is a global var with no data
+ * blocks in the kernel data segment. We do this because
+ * we want to ensure this block_list addr is under 4GB.
+ */
+ rtas_firmware_flash_list.num_blocks = 0;
+ flist = (struct flash_block_list *)&rtas_firmware_flash_list;
+ rtas_block_list = virt_to_abs(flist);
+ if (rtas_block_list >= 4UL*1024*1024*1024) {
+ printk(KERN_ALERT "FLASH: kernel bug...flash list header addr above 4GB\n");
+ return;
+ }
+
+ printk(KERN_ALERT "FLASH: preparing saved firmware image for flash\n");
+ /* Update the block_list in place. */
+ image_size = 0;
+ for (f = flist; f; f = next) {
+ /* Translate data addrs to absolute */
+ for (i = 0; i < f->num_blocks; i++) {
+ f->blocks[i].data = (char *)virt_to_abs(f->blocks[i].data);
+ image_size += f->blocks[i].length;
+ }
+ next = f->next;
+ /* Don't translate NULL pointer for last entry */
+ if (f->next)
+ f->next = (struct flash_block_list *)virt_to_abs(f->next);
+ else
+ f->next = NULL;
+ /* make num_blocks into the version/length field */
+ f->num_blocks = (FLASH_BLOCK_LIST_VERSION << 56) | ((f->num_blocks+1)*16);
+ }
+
+ printk(KERN_ALERT "FLASH: flash image is %ld bytes\n", image_size);
+ printk(KERN_ALERT "FLASH: performing flash and reboot\n");
+ rtas_progress("Flashing \n", 0x0);
+ rtas_progress("Please Wait... ", 0x0);
+ printk(KERN_ALERT "FLASH: this will take several minutes. Do not power off!\n");
+ status = rtas_call(update_token, 1, 1, NULL, rtas_block_list);
+ switch (status) { /* should only get "bad" status */
+ case 0:
+ printk(KERN_ALERT "FLASH: success\n");
+ break;
+ case -1:
+ printk(KERN_ALERT "FLASH: hardware error. Firmware may not be not flashed\n");
+ break;
+ case -3:
+ printk(KERN_ALERT "FLASH: image is corrupt or not correct for this platform. Firmware not flashed\n");
+ break;
+ case -4:
+ printk(KERN_ALERT "FLASH: flash failed when partially complete. System may not reboot\n");
+ break;
+ default:
+ printk(KERN_ALERT "FLASH: unknown flash return code %d\n", status);
+ break;
+ }
+}
+
static void remove_flash_pde(struct proc_dir_entry *dp)
{
if (dp) {
@@ -701,6 +808,7 @@ int __init rtas_flash_init(void)
if (rc != 0)
goto cleanup;
+ rtas_flash_term_hook = rtas_flash_firmware;
return 0;
cleanup:
@@ -714,6 +822,7 @@ cleanup:
void __exit rtas_flash_cleanup(void)
{
+ rtas_flash_term_hook = NULL;
remove_flash_pde(firmware_flash_pde);
remove_flash_pde(firmware_update_pde);
remove_flash_pde(validate_pde);
diff --git a/arch/ppc64/kernel/rtas_pci.c b/arch/powerpc/kernel/rtas_pci.c
index 4a9719b48abe..0e5a8e116653 100644
--- a/arch/ppc64/kernel/rtas_pci.c
+++ b/arch/powerpc/kernel/rtas_pci.c
@@ -5,19 +5,19 @@
* Copyright (C) 2003 Anton Blanchard <anton@au.ibm.com>, IBM
*
* RTAS specific routines for PCI.
- *
+ *
* Based on code from pci.c, chrp_pci.c and pSeries_pci.c
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
- *
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
@@ -38,9 +38,8 @@
#include <asm/pci-bridge.h>
#include <asm/iommu.h>
#include <asm/rtas.h>
-
-#include "mpic.h"
-#include "pci.h"
+#include <asm/mpic.h>
+#include <asm/ppc-pci.h>
/* RTAS tokens */
static int read_pci_config;
@@ -48,7 +47,7 @@ static int write_pci_config;
static int ibm_read_pci_config;
static int ibm_write_pci_config;
-static int config_access_valid(struct pci_dn *dn, int where)
+static inline int config_access_valid(struct pci_dn *dn, int where)
{
if (where < 256)
return 1;
@@ -73,16 +72,14 @@ static int of_device_available(struct device_node * dn)
return 0;
}
-static int rtas_read_config(struct device_node *dn, int where, int size, u32 *val)
+static int rtas_read_config(struct pci_dn *pdn, int where, int size, u32 *val)
{
int returnval = -1;
unsigned long buid, addr;
int ret;
- struct pci_dn *pdn;
- if (!dn || !dn->data)
+ if (!pdn)
return PCIBIOS_DEVICE_NOT_FOUND;
- pdn = dn->data;
if (!config_access_valid(pdn, where))
return PCIBIOS_BAD_REGISTER_NUMBER;
@@ -91,7 +88,7 @@ static int rtas_read_config(struct device_node *dn, int where, int size, u32 *va
buid = pdn->phb->buid;
if (buid) {
ret = rtas_call(ibm_read_pci_config, 4, 2, &returnval,
- addr, buid >> 32, buid & 0xffffffff, size);
+ addr, BUID_HI(buid), BUID_LO(buid), size);
} else {
ret = rtas_call(read_pci_config, 2, 2, &returnval, addr, size);
}
@@ -101,7 +98,7 @@ static int rtas_read_config(struct device_node *dn, int where, int size, u32 *va
return PCIBIOS_DEVICE_NOT_FOUND;
if (returnval == EEH_IO_ERROR_VALUE(size) &&
- eeh_dn_check_failure (dn, NULL))
+ eeh_dn_check_failure (pdn->node, NULL))
return PCIBIOS_DEVICE_NOT_FOUND;
return PCIBIOS_SUCCESSFUL;
@@ -119,23 +116,23 @@ static int rtas_pci_read_config(struct pci_bus *bus,
busdn = bus->sysdata; /* must be a phb */
/* Search only direct children of the bus */
- for (dn = busdn->child; dn; dn = dn->sibling)
- if (dn->data && PCI_DN(dn)->devfn == devfn
+ for (dn = busdn->child; dn; dn = dn->sibling) {
+ struct pci_dn *pdn = PCI_DN(dn);
+ if (pdn && pdn->devfn == devfn
&& of_device_available(dn))
- return rtas_read_config(dn, where, size, val);
+ return rtas_read_config(pdn, where, size, val);
+ }
return PCIBIOS_DEVICE_NOT_FOUND;
}
-int rtas_write_config(struct device_node *dn, int where, int size, u32 val)
+int rtas_write_config(struct pci_dn *pdn, int where, int size, u32 val)
{
unsigned long buid, addr;
int ret;
- struct pci_dn *pdn;
- if (!dn || !dn->data)
+ if (!pdn)
return PCIBIOS_DEVICE_NOT_FOUND;
- pdn = dn->data;
if (!config_access_valid(pdn, where))
return PCIBIOS_BAD_REGISTER_NUMBER;
@@ -143,7 +140,8 @@ int rtas_write_config(struct device_node *dn, int where, int size, u32 val)
(pdn->devfn << 8) | (where & 0xff);
buid = pdn->phb->buid;
if (buid) {
- ret = rtas_call(ibm_write_pci_config, 5, 1, NULL, addr, buid >> 32, buid & 0xffffffff, size, (ulong) val);
+ ret = rtas_call(ibm_write_pci_config, 5, 1, NULL, addr,
+ BUID_HI(buid), BUID_LO(buid), size, (ulong) val);
} else {
ret = rtas_call(write_pci_config, 3, 1, NULL, addr, size, (ulong)val);
}
@@ -166,10 +164,12 @@ static int rtas_pci_write_config(struct pci_bus *bus,
busdn = bus->sysdata; /* must be a phb */
/* Search only direct children of the bus */
- for (dn = busdn->child; dn; dn = dn->sibling)
- if (dn->data && PCI_DN(dn)->devfn == devfn
+ for (dn = busdn->child; dn; dn = dn->sibling) {
+ struct pci_dn *pdn = PCI_DN(dn);
+ if (pdn && pdn->devfn == devfn
&& of_device_available(dn))
- return rtas_write_config(dn, where, size, val);
+ return rtas_write_config(pdn, where, size, val);
+ }
return PCIBIOS_DEVICE_NOT_FOUND;
}
@@ -222,7 +222,7 @@ static void python_countermeasures(struct device_node *dev,
/* Python's register file is 1 MB in size. */
chip_regs = ioremap(reg_struct.address & ~(0xfffffUL), 0x100000);
- /*
+ /*
* Firmware doesn't always clear this bit which is critical
* for good performance - Anton
*/
@@ -293,7 +293,7 @@ static int phb_set_bus_ranges(struct device_node *dev,
if (bus_range == NULL || len < 2 * sizeof(int)) {
return 1;
}
-
+
phb->first_busno = bus_range[0];
phb->last_busno = bus_range[1];
@@ -401,7 +401,7 @@ unsigned long __init find_and_init_phbs(void)
if (!phb)
continue;
- pci_process_bridge_OF_ranges(phb, node);
+ pci_process_bridge_OF_ranges(phb, node, 0);
pci_setup_phb_io(phb, index == 0);
#ifdef CONFIG_PPC_PSERIES
if (ppc64_interrupt_controller == IC_OPEN_PIC && pSeries_mpic) {
@@ -441,7 +441,6 @@ struct pci_controller * __devinit init_phb_dynamic(struct device_node *dn)
struct device_node *root = of_find_node_by_path("/");
unsigned int root_size_cells = 0;
struct pci_controller *phb;
- struct pci_bus *bus;
int primary;
root_size_cells = prom_n_size_cells(root);
@@ -451,16 +450,13 @@ struct pci_controller * __devinit init_phb_dynamic(struct device_node *dn)
if (!phb)
return NULL;
- pci_process_bridge_OF_ranges(phb, dn);
+ pci_process_bridge_OF_ranges(phb, dn, primary);
pci_setup_phb_io_dynamic(phb, primary);
of_node_put(root);
pci_devs_phb_init_dynamic(phb);
- phb->last_busno = 0xff;
- bus = pci_scan_bus(phb->first_busno, phb->ops, phb->arch_data);
- phb->bus = bus;
- phb->last_busno = bus->subordinate;
+ scan_phb(phb);
return phb;
}
diff --git a/arch/powerpc/kernel/semaphore.c b/arch/powerpc/kernel/semaphore.c
new file mode 100644
index 000000000000..2f8c3c951394
--- /dev/null
+++ b/arch/powerpc/kernel/semaphore.c
@@ -0,0 +1,135 @@
+/*
+ * PowerPC-specific semaphore code.
+ *
+ * Copyright (C) 1999 Cort Dougan <cort@cs.nmt.edu>
+ *
+ * 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.
+ *
+ * April 2001 - Reworked by Paul Mackerras <paulus@samba.org>
+ * to eliminate the SMP races in the old version between the updates
+ * of `count' and `waking'. Now we use negative `count' values to
+ * indicate that some process(es) are waiting for the semaphore.
+ */
+
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/module.h>
+
+#include <asm/atomic.h>
+#include <asm/semaphore.h>
+#include <asm/errno.h>
+
+/*
+ * Atomically update sem->count.
+ * This does the equivalent of the following:
+ *
+ * old_count = sem->count;
+ * tmp = MAX(old_count, 0) + incr;
+ * sem->count = tmp;
+ * return old_count;
+ */
+static inline int __sem_update_count(struct semaphore *sem, int incr)
+{
+ int old_count, tmp;
+
+ __asm__ __volatile__("\n"
+"1: lwarx %0,0,%3\n"
+" srawi %1,%0,31\n"
+" andc %1,%0,%1\n"
+" add %1,%1,%4\n"
+ PPC405_ERR77(0,%3)
+" stwcx. %1,0,%3\n"
+" bne 1b"
+ : "=&r" (old_count), "=&r" (tmp), "=m" (sem->count)
+ : "r" (&sem->count), "r" (incr), "m" (sem->count)
+ : "cc");
+
+ return old_count;
+}
+
+void __up(struct semaphore *sem)
+{
+ /*
+ * Note that we incremented count in up() before we came here,
+ * but that was ineffective since the result was <= 0, and
+ * any negative value of count is equivalent to 0.
+ * This ends up setting count to 1, unless count is now > 0
+ * (i.e. because some other cpu has called up() in the meantime),
+ * in which case we just increment count.
+ */
+ __sem_update_count(sem, 1);
+ wake_up(&sem->wait);
+}
+EXPORT_SYMBOL(__up);
+
+/*
+ * Note that when we come in to __down or __down_interruptible,
+ * we have already decremented count, but that decrement was
+ * ineffective since the result was < 0, and any negative value
+ * of count is equivalent to 0.
+ * Thus it is only when we decrement count from some value > 0
+ * that we have actually got the semaphore.
+ */
+void __sched __down(struct semaphore *sem)
+{
+ struct task_struct *tsk = current;
+ DECLARE_WAITQUEUE(wait, tsk);
+
+ __set_task_state(tsk, TASK_UNINTERRUPTIBLE);
+ add_wait_queue_exclusive(&sem->wait, &wait);
+
+ /*
+ * Try to get the semaphore. If the count is > 0, then we've
+ * got the semaphore; we decrement count and exit the loop.
+ * If the count is 0 or negative, we set it to -1, indicating
+ * that we are asleep, and then sleep.
+ */
+ while (__sem_update_count(sem, -1) <= 0) {
+ schedule();
+ set_task_state(tsk, TASK_UNINTERRUPTIBLE);
+ }
+ remove_wait_queue(&sem->wait, &wait);
+ __set_task_state(tsk, TASK_RUNNING);
+
+ /*
+ * If there are any more sleepers, wake one of them up so
+ * that it can either get the semaphore, or set count to -1
+ * indicating that there are still processes sleeping.
+ */
+ wake_up(&sem->wait);
+}
+EXPORT_SYMBOL(__down);
+
+int __sched __down_interruptible(struct semaphore * sem)
+{
+ int retval = 0;
+ struct task_struct *tsk = current;
+ DECLARE_WAITQUEUE(wait, tsk);
+
+ __set_task_state(tsk, TASK_INTERRUPTIBLE);
+ add_wait_queue_exclusive(&sem->wait, &wait);
+
+ while (__sem_update_count(sem, -1) <= 0) {
+ if (signal_pending(current)) {
+ /*
+ * A signal is pending - give up trying.
+ * Set sem->count to 0 if it is negative,
+ * since we are no longer sleeping.
+ */
+ __sem_update_count(sem, 0);
+ retval = -EINTR;
+ break;
+ }
+ schedule();
+ set_task_state(tsk, TASK_INTERRUPTIBLE);
+ }
+ remove_wait_queue(&sem->wait, &wait);
+ __set_task_state(tsk, TASK_RUNNING);
+
+ wake_up(&sem->wait);
+ return retval;
+}
+EXPORT_SYMBOL(__down_interruptible);
diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c
new file mode 100644
index 000000000000..bae4bff138f1
--- /dev/null
+++ b/arch/powerpc/kernel/setup-common.c
@@ -0,0 +1,592 @@
+/*
+ * Common boot and setup code for both 32-bit and 64-bit.
+ * Extracted from arch/powerpc/kernel/setup_64.c.
+ *
+ * Copyright (C) 2001 PPC64 Team, IBM Corp
+ *
+ * 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/config.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/reboot.h>
+#include <linux/delay.h>
+#include <linux/initrd.h>
+#include <linux/ide.h>
+#include <linux/seq_file.h>
+#include <linux/ioport.h>
+#include <linux/console.h>
+#include <linux/utsname.h>
+#include <linux/tty.h>
+#include <linux/root_dev.h>
+#include <linux/notifier.h>
+#include <linux/cpu.h>
+#include <linux/unistd.h>
+#include <linux/serial.h>
+#include <linux/serial_8250.h>
+#include <asm/io.h>
+#include <asm/prom.h>
+#include <asm/processor.h>
+#include <asm/systemcfg.h>
+#include <asm/pgtable.h>
+#include <asm/smp.h>
+#include <asm/elf.h>
+#include <asm/machdep.h>
+#include <asm/time.h>
+#include <asm/cputable.h>
+#include <asm/sections.h>
+#include <asm/btext.h>
+#include <asm/nvram.h>
+#include <asm/setup.h>
+#include <asm/system.h>
+#include <asm/rtas.h>
+#include <asm/iommu.h>
+#include <asm/serial.h>
+#include <asm/cache.h>
+#include <asm/page.h>
+#include <asm/mmu.h>
+#include <asm/lmb.h>
+#include <asm/xmon.h>
+
+#include "setup.h"
+
+#undef DEBUG
+
+#ifdef DEBUG
+#define DBG(fmt...) udbg_printf(fmt)
+#else
+#define DBG(fmt...)
+#endif
+
+#ifdef CONFIG_PPC_MULTIPLATFORM
+int _machine = 0;
+EXPORT_SYMBOL(_machine);
+#endif
+
+unsigned long klimit = (unsigned long) _end;
+
+/*
+ * This still seems to be needed... -- paulus
+ */
+struct screen_info screen_info = {
+ .orig_x = 0,
+ .orig_y = 25,
+ .orig_video_cols = 80,
+ .orig_video_lines = 25,
+ .orig_video_isVGA = 1,
+ .orig_video_points = 16
+};
+
+#ifdef __DO_IRQ_CANON
+/* XXX should go elsewhere eventually */
+int ppc_do_canonicalize_irqs;
+EXPORT_SYMBOL(ppc_do_canonicalize_irqs);
+#endif
+
+/* also used by kexec */
+void machine_shutdown(void)
+{
+ if (ppc_md.nvram_sync)
+ ppc_md.nvram_sync();
+}
+
+void machine_restart(char *cmd)
+{
+ machine_shutdown();
+ ppc_md.restart(cmd);
+#ifdef CONFIG_SMP
+ smp_send_stop();
+#endif
+ printk(KERN_EMERG "System Halted, OK to turn off power\n");
+ local_irq_disable();
+ while (1) ;
+}
+
+void machine_power_off(void)
+{
+ machine_shutdown();
+ ppc_md.power_off();
+#ifdef CONFIG_SMP
+ smp_send_stop();
+#endif
+ printk(KERN_EMERG "System Halted, OK to turn off power\n");
+ local_irq_disable();
+ while (1) ;
+}
+/* Used by the G5 thermal driver */
+EXPORT_SYMBOL_GPL(machine_power_off);
+
+void (*pm_power_off)(void) = machine_power_off;
+EXPORT_SYMBOL_GPL(pm_power_off);
+
+void machine_halt(void)
+{
+ machine_shutdown();
+ ppc_md.halt();
+#ifdef CONFIG_SMP
+ smp_send_stop();
+#endif
+ printk(KERN_EMERG "System Halted, OK to turn off power\n");
+ local_irq_disable();
+ while (1) ;
+}
+
+
+#ifdef CONFIG_TAU
+extern u32 cpu_temp(unsigned long cpu);
+extern u32 cpu_temp_both(unsigned long cpu);
+#endif /* CONFIG_TAU */
+
+#ifdef CONFIG_SMP
+DEFINE_PER_CPU(unsigned int, pvr);
+#endif
+
+static int show_cpuinfo(struct seq_file *m, void *v)
+{
+ unsigned long cpu_id = (unsigned long)v - 1;
+ unsigned int pvr;
+ unsigned short maj;
+ unsigned short min;
+
+ if (cpu_id == NR_CPUS) {
+#if defined(CONFIG_SMP) && defined(CONFIG_PPC32)
+ unsigned long bogosum = 0;
+ int i;
+ for (i = 0; i < NR_CPUS; ++i)
+ if (cpu_online(i))
+ bogosum += loops_per_jiffy;
+ seq_printf(m, "total bogomips\t: %lu.%02lu\n",
+ bogosum/(500000/HZ), bogosum/(5000/HZ) % 100);
+#endif /* CONFIG_SMP && CONFIG_PPC32 */
+ seq_printf(m, "timebase\t: %lu\n", ppc_tb_freq);
+
+ if (ppc_md.show_cpuinfo != NULL)
+ ppc_md.show_cpuinfo(m);
+
+ return 0;
+ }
+
+ /* We only show online cpus: disable preempt (overzealous, I
+ * knew) to prevent cpu going down. */
+ preempt_disable();
+ if (!cpu_online(cpu_id)) {
+ preempt_enable();
+ return 0;
+ }
+
+#ifdef CONFIG_SMP
+ pvr = per_cpu(pvr, cpu_id);
+#else
+ pvr = mfspr(SPRN_PVR);
+#endif
+ maj = (pvr >> 8) & 0xFF;
+ min = pvr & 0xFF;
+
+ seq_printf(m, "processor\t: %lu\n", cpu_id);
+ seq_printf(m, "cpu\t\t: ");
+
+ if (cur_cpu_spec->pvr_mask)
+ seq_printf(m, "%s", cur_cpu_spec->cpu_name);
+ else
+ seq_printf(m, "unknown (%08x)", pvr);
+
+#ifdef CONFIG_ALTIVEC
+ if (cpu_has_feature(CPU_FTR_ALTIVEC))
+ seq_printf(m, ", altivec supported");
+#endif /* CONFIG_ALTIVEC */
+
+ seq_printf(m, "\n");
+
+#ifdef CONFIG_TAU
+ if (cur_cpu_spec->cpu_features & CPU_FTR_TAU) {
+#ifdef CONFIG_TAU_AVERAGE
+ /* more straightforward, but potentially misleading */
+ seq_printf(m, "temperature \t: %u C (uncalibrated)\n",
+ cpu_temp(cpu_id));
+#else
+ /* show the actual temp sensor range */
+ u32 temp;
+ temp = cpu_temp_both(cpu_id);
+ seq_printf(m, "temperature \t: %u-%u C (uncalibrated)\n",
+ temp & 0xff, temp >> 16);
+#endif
+ }
+#endif /* CONFIG_TAU */
+
+ /*
+ * Assume here that all clock rates are the same in a
+ * smp system. -- Cort
+ */
+ if (ppc_proc_freq)
+ seq_printf(m, "clock\t\t: %lu.%06luMHz\n",
+ ppc_proc_freq / 1000000, ppc_proc_freq % 1000000);
+
+ if (ppc_md.show_percpuinfo != NULL)
+ ppc_md.show_percpuinfo(m, cpu_id);
+
+ /* If we are a Freescale core do a simple check so
+ * we dont have to keep adding cases in the future */
+ if (PVR_VER(pvr) & 0x8000) {
+ maj = PVR_MAJ(pvr);
+ min = PVR_MIN(pvr);
+ } else {
+ switch (PVR_VER(pvr)) {
+ case 0x0020: /* 403 family */
+ maj = PVR_MAJ(pvr) + 1;
+ min = PVR_MIN(pvr);
+ break;
+ case 0x1008: /* 740P/750P ?? */
+ maj = ((pvr >> 8) & 0xFF) - 1;
+ min = pvr & 0xFF;
+ break;
+ default:
+ maj = (pvr >> 8) & 0xFF;
+ min = pvr & 0xFF;
+ break;
+ }
+ }
+
+ seq_printf(m, "revision\t: %hd.%hd (pvr %04x %04x)\n",
+ maj, min, PVR_VER(pvr), PVR_REV(pvr));
+
+#ifdef CONFIG_PPC32
+ seq_printf(m, "bogomips\t: %lu.%02lu\n",
+ loops_per_jiffy / (500000/HZ),
+ (loops_per_jiffy / (5000/HZ)) % 100);
+#endif
+
+#ifdef CONFIG_SMP
+ seq_printf(m, "\n");
+#endif
+
+ preempt_enable();
+ return 0;
+}
+
+static void *c_start(struct seq_file *m, loff_t *pos)
+{
+ unsigned long i = *pos;
+
+ return i <= NR_CPUS ? (void *)(i + 1) : NULL;
+}
+
+static void *c_next(struct seq_file *m, void *v, loff_t *pos)
+{
+ ++*pos;
+ return c_start(m, pos);
+}
+
+static void c_stop(struct seq_file *m, void *v)
+{
+}
+
+struct seq_operations cpuinfo_op = {
+ .start =c_start,
+ .next = c_next,
+ .stop = c_stop,
+ .show = show_cpuinfo,
+};
+
+#ifdef CONFIG_PPC_MULTIPLATFORM
+static int __init set_preferred_console(void)
+{
+ struct device_node *prom_stdout = NULL;
+ char *name;
+ u32 *spd;
+ int offset = 0;
+
+ DBG(" -> set_preferred_console()\n");
+
+ /* The user has requested a console so this is already set up. */
+ if (strstr(saved_command_line, "console=")) {
+ DBG(" console was specified !\n");
+ return -EBUSY;
+ }
+
+ if (!of_chosen) {
+ DBG(" of_chosen is NULL !\n");
+ return -ENODEV;
+ }
+ /* We are getting a weird phandle from OF ... */
+ /* ... So use the full path instead */
+ name = (char *)get_property(of_chosen, "linux,stdout-path", NULL);
+ if (name == NULL) {
+ DBG(" no linux,stdout-path !\n");
+ return -ENODEV;
+ }
+ prom_stdout = of_find_node_by_path(name);
+ if (!prom_stdout) {
+ DBG(" can't find stdout package %s !\n", name);
+ return -ENODEV;
+ }
+ DBG("stdout is %s\n", prom_stdout->full_name);
+
+ name = (char *)get_property(prom_stdout, "name", NULL);
+ if (!name) {
+ DBG(" stdout package has no name !\n");
+ goto not_found;
+ }
+ spd = (u32 *)get_property(prom_stdout, "current-speed", NULL);
+
+ if (0)
+ ;
+#ifdef CONFIG_SERIAL_8250_CONSOLE
+ else if (strcmp(name, "serial") == 0) {
+ int i;
+ u32 *reg = (u32 *)get_property(prom_stdout, "reg", &i);
+ if (i > 8) {
+ switch (reg[1]) {
+ case 0x3f8:
+ offset = 0;
+ break;
+ case 0x2f8:
+ offset = 1;
+ break;
+ case 0x898:
+ offset = 2;
+ break;
+ case 0x890:
+ offset = 3;
+ break;
+ default:
+ /* We dont recognise the serial port */
+ goto not_found;
+ }
+ }
+ }
+#endif /* CONFIG_SERIAL_8250_CONSOLE */
+#ifdef CONFIG_PPC_PSERIES
+ else if (strcmp(name, "vty") == 0) {
+ u32 *reg = (u32 *)get_property(prom_stdout, "reg", NULL);
+ char *compat = (char *)get_property(prom_stdout, "compatible", NULL);
+
+ if (reg && compat && (strcmp(compat, "hvterm-protocol") == 0)) {
+ /* Host Virtual Serial Interface */
+ switch (reg[0]) {
+ case 0x30000000:
+ offset = 0;
+ break;
+ case 0x30000001:
+ offset = 1;
+ break;
+ default:
+ goto not_found;
+ }
+ of_node_put(prom_stdout);
+ DBG("Found hvsi console at offset %d\n", offset);
+ return add_preferred_console("hvsi", offset, NULL);
+ } else {
+ /* pSeries LPAR virtual console */
+ of_node_put(prom_stdout);
+ DBG("Found hvc console\n");
+ return add_preferred_console("hvc", 0, NULL);
+ }
+ }
+#endif /* CONFIG_PPC_PSERIES */
+#ifdef CONFIG_SERIAL_PMACZILOG_CONSOLE
+ else if (strcmp(name, "ch-a") == 0)
+ offset = 0;
+ else if (strcmp(name, "ch-b") == 0)
+ offset = 1;
+#endif /* CONFIG_SERIAL_PMACZILOG_CONSOLE */
+ else
+ goto not_found;
+ of_node_put(prom_stdout);
+
+ DBG("Found serial console at ttyS%d\n", offset);
+
+ if (spd) {
+ static char __initdata opt[16];
+ sprintf(opt, "%d", *spd);
+ return add_preferred_console("ttyS", offset, opt);
+ } else
+ return add_preferred_console("ttyS", offset, NULL);
+
+ not_found:
+ DBG("No preferred console found !\n");
+ of_node_put(prom_stdout);
+ return -ENODEV;
+}
+console_initcall(set_preferred_console);
+#endif /* CONFIG_PPC_MULTIPLATFORM */
+
+void __init check_for_initrd(void)
+{
+#ifdef CONFIG_BLK_DEV_INITRD
+ unsigned long *prop;
+
+ DBG(" -> check_for_initrd()\n");
+
+ if (of_chosen) {
+ prop = (unsigned long *)get_property(of_chosen,
+ "linux,initrd-start", NULL);
+ if (prop != NULL) {
+ initrd_start = (unsigned long)__va(*prop);
+ prop = (unsigned long *)get_property(of_chosen,
+ "linux,initrd-end", NULL);
+ if (prop != NULL) {
+ initrd_end = (unsigned long)__va(*prop);
+ initrd_below_start_ok = 1;
+ } else
+ initrd_start = 0;
+ }
+ }
+
+ /* If we were passed an initrd, set the ROOT_DEV properly if the values
+ * look sensible. If not, clear initrd reference.
+ */
+ if (initrd_start >= KERNELBASE && initrd_end >= KERNELBASE &&
+ initrd_end > initrd_start)
+ ROOT_DEV = Root_RAM0;
+ else {
+ printk("Bogus initrd %08lx %08lx\n", initrd_start, initrd_end);
+ initrd_start = initrd_end = 0;
+ }
+
+ if (initrd_start)
+ printk("Found initrd at 0x%lx:0x%lx\n", initrd_start, initrd_end);
+
+ DBG(" <- check_for_initrd()\n");
+#endif /* CONFIG_BLK_DEV_INITRD */
+}
+
+#ifdef CONFIG_SMP
+
+/**
+ * setup_cpu_maps - initialize the following cpu maps:
+ * cpu_possible_map
+ * cpu_present_map
+ * cpu_sibling_map
+ *
+ * Having the possible map set up early allows us to restrict allocations
+ * of things like irqstacks to num_possible_cpus() rather than NR_CPUS.
+ *
+ * We do not initialize the online map here; cpus set their own bits in
+ * cpu_online_map as they come up.
+ *
+ * This function is valid only for Open Firmware systems. finish_device_tree
+ * must be called before using this.
+ *
+ * While we're here, we may as well set the "physical" cpu ids in the paca.
+ */
+void __init smp_setup_cpu_maps(void)
+{
+ struct device_node *dn = NULL;
+ int cpu = 0;
+ int swap_cpuid = 0;
+
+ while ((dn = of_find_node_by_type(dn, "cpu")) && cpu < NR_CPUS) {
+ int *intserv;
+ int j, len = sizeof(u32), nthreads = 1;
+
+ intserv = (int *)get_property(dn, "ibm,ppc-interrupt-server#s",
+ &len);
+ if (intserv)
+ nthreads = len / sizeof(int);
+ else {
+ intserv = (int *) get_property(dn, "reg", NULL);
+ if (!intserv)
+ intserv = &cpu; /* assume logical == phys */
+ }
+
+ for (j = 0; j < nthreads && cpu < NR_CPUS; j++) {
+ cpu_set(cpu, cpu_present_map);
+ set_hard_smp_processor_id(cpu, intserv[j]);
+
+ if (intserv[j] == boot_cpuid_phys)
+ swap_cpuid = cpu;
+ cpu_set(cpu, cpu_possible_map);
+ cpu++;
+ }
+ }
+
+ /* Swap CPU id 0 with boot_cpuid_phys, so we can always assume that
+ * boot cpu is logical 0.
+ */
+ if (boot_cpuid_phys != get_hard_smp_processor_id(0)) {
+ u32 tmp;
+ tmp = get_hard_smp_processor_id(0);
+ set_hard_smp_processor_id(0, boot_cpuid_phys);
+ set_hard_smp_processor_id(swap_cpuid, tmp);
+ }
+
+#ifdef CONFIG_PPC64
+ /*
+ * On pSeries LPAR, we need to know how many cpus
+ * could possibly be added to this partition.
+ */
+ if (_machine == PLATFORM_PSERIES_LPAR &&
+ (dn = of_find_node_by_path("/rtas"))) {
+ int num_addr_cell, num_size_cell, maxcpus;
+ unsigned int *ireg;
+
+ num_addr_cell = prom_n_addr_cells(dn);
+ num_size_cell = prom_n_size_cells(dn);
+
+ ireg = (unsigned int *)
+ get_property(dn, "ibm,lrdr-capacity", NULL);
+
+ if (!ireg)
+ goto out;
+
+ maxcpus = ireg[num_addr_cell + num_size_cell];
+
+ /* Double maxcpus for processors which have SMT capability */
+ if (cpu_has_feature(CPU_FTR_SMT))
+ maxcpus *= 2;
+
+ if (maxcpus > NR_CPUS) {
+ printk(KERN_WARNING
+ "Partition configured for %d cpus, "
+ "operating system maximum is %d.\n",
+ maxcpus, NR_CPUS);
+ maxcpus = NR_CPUS;
+ } else
+ printk(KERN_INFO "Partition configured for %d cpus.\n",
+ maxcpus);
+
+ for (cpu = 0; cpu < maxcpus; cpu++)
+ cpu_set(cpu, cpu_possible_map);
+ out:
+ of_node_put(dn);
+ }
+
+ /*
+ * Do the sibling map; assume only two threads per processor.
+ */
+ for_each_cpu(cpu) {
+ cpu_set(cpu, cpu_sibling_map[cpu]);
+ if (cpu_has_feature(CPU_FTR_SMT))
+ cpu_set(cpu ^ 0x1, cpu_sibling_map[cpu]);
+ }
+
+ _systemcfg->processorCount = num_present_cpus();
+#endif /* CONFIG_PPC64 */
+}
+#endif /* CONFIG_SMP */
+
+#ifdef CONFIG_XMON
+static int __init early_xmon(char *p)
+{
+ /* ensure xmon is enabled */
+ if (p) {
+ if (strncmp(p, "on", 2) == 0)
+ xmon_init(1);
+ if (strncmp(p, "off", 3) == 0)
+ xmon_init(0);
+ if (strncmp(p, "early", 5) != 0)
+ return 0;
+ }
+ xmon_init(1);
+ debugger(NULL);
+
+ return 0;
+}
+early_param("xmon", early_xmon);
+#endif
diff --git a/arch/powerpc/kernel/setup.h b/arch/powerpc/kernel/setup.h
new file mode 100644
index 000000000000..2ebba755272e
--- /dev/null
+++ b/arch/powerpc/kernel/setup.h
@@ -0,0 +1,6 @@
+#ifndef _POWERPC_KERNEL_SETUP_H
+#define _POWERPC_KERNEL_SETUP_H
+
+void check_for_initrd(void);
+
+#endif /* _POWERPC_KERNEL_SETUP_H */
diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c
new file mode 100644
index 000000000000..c98cfcc9cd9a
--- /dev/null
+++ b/arch/powerpc/kernel/setup_32.c
@@ -0,0 +1,369 @@
+/*
+ * Common prep/pmac/chrp boot and setup code.
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/reboot.h>
+#include <linux/delay.h>
+#include <linux/initrd.h>
+#include <linux/ide.h>
+#include <linux/tty.h>
+#include <linux/bootmem.h>
+#include <linux/seq_file.h>
+#include <linux/root_dev.h>
+#include <linux/cpu.h>
+#include <linux/console.h>
+
+#include <asm/residual.h>
+#include <asm/io.h>
+#include <asm/prom.h>
+#include <asm/processor.h>
+#include <asm/pgtable.h>
+#include <asm/setup.h>
+#include <asm/amigappc.h>
+#include <asm/smp.h>
+#include <asm/elf.h>
+#include <asm/cputable.h>
+#include <asm/bootx.h>
+#include <asm/btext.h>
+#include <asm/machdep.h>
+#include <asm/uaccess.h>
+#include <asm/system.h>
+#include <asm/pmac_feature.h>
+#include <asm/sections.h>
+#include <asm/nvram.h>
+#include <asm/xmon.h>
+#include <asm/time.h>
+
+#include "setup.h"
+
+#define DBG(fmt...)
+
+#if defined CONFIG_KGDB
+#include <asm/kgdb.h>
+#endif
+
+extern void platform_init(void);
+extern void bootx_init(unsigned long r4, unsigned long phys);
+
+extern void ppc6xx_idle(void);
+extern void power4_idle(void);
+
+boot_infos_t *boot_infos;
+struct ide_machdep_calls ppc_ide_md;
+
+/* XXX should go elsewhere */
+int __irq_offset_value;
+EXPORT_SYMBOL(__irq_offset_value);
+
+int boot_cpuid;
+EXPORT_SYMBOL_GPL(boot_cpuid);
+int boot_cpuid_phys;
+
+unsigned long ISA_DMA_THRESHOLD;
+unsigned int DMA_MODE_READ;
+unsigned int DMA_MODE_WRITE;
+
+int have_of = 1;
+
+#ifdef CONFIG_PPC_MULTIPLATFORM
+extern void prep_init(void);
+extern void pmac_init(void);
+extern void chrp_init(void);
+
+dev_t boot_dev;
+#endif /* CONFIG_PPC_MULTIPLATFORM */
+
+#ifdef CONFIG_MAGIC_SYSRQ
+unsigned long SYSRQ_KEY = 0x54;
+#endif /* CONFIG_MAGIC_SYSRQ */
+
+#ifdef CONFIG_VGA_CONSOLE
+unsigned long vgacon_remap_base;
+#endif
+
+struct machdep_calls ppc_md;
+EXPORT_SYMBOL(ppc_md);
+
+/*
+ * These are used in binfmt_elf.c to put aux entries on the stack
+ * for each elf executable being started.
+ */
+int dcache_bsize;
+int icache_bsize;
+int ucache_bsize;
+
+/*
+ * We're called here very early in the boot. We determine the machine
+ * type and call the appropriate low-level setup functions.
+ * -- Cort <cort@fsmlabs.com>
+ *
+ * Note that the kernel may be running at an address which is different
+ * from the address that it was linked at, so we must use RELOC/PTRRELOC
+ * to access static data (including strings). -- paulus
+ */
+unsigned long __init early_init(unsigned long dt_ptr)
+{
+ unsigned long offset = reloc_offset();
+
+ /* First zero the BSS -- use memset_io, some platforms don't have
+ * caches on yet */
+ memset_io(PTRRELOC(&__bss_start), 0, _end - __bss_start);
+
+ /*
+ * Identify the CPU type and fix up code sections
+ * that depend on which cpu we have.
+ */
+ identify_cpu(offset, 0);
+ do_cpu_ftr_fixups(offset);
+
+ return KERNELBASE + offset;
+}
+
+#ifdef CONFIG_PPC_MULTIPLATFORM
+/*
+ * The PPC_MULTIPLATFORM version of platform_init...
+ */
+void __init platform_init(void)
+{
+ /* if we didn't get any bootinfo telling us what we are... */
+ if (_machine == 0) {
+ /* prep boot loader tells us if we're prep or not */
+ if ( *(unsigned long *)(KERNELBASE) == (0xdeadc0de) )
+ _machine = _MACH_prep;
+ }
+
+#ifdef CONFIG_PPC_PREP
+ /* not much more to do here, if prep */
+ if (_machine == _MACH_prep) {
+ prep_init();
+ return;
+ }
+#endif
+
+#ifdef CONFIG_ADB
+ if (strstr(cmd_line, "adb_sync")) {
+ extern int __adb_probe_sync;
+ __adb_probe_sync = 1;
+ }
+#endif /* CONFIG_ADB */
+
+ switch (_machine) {
+#ifdef CONFIG_PPC_PMAC
+ case _MACH_Pmac:
+ pmac_init();
+ break;
+#endif
+#ifdef CONFIG_PPC_CHRP
+ case _MACH_chrp:
+ chrp_init();
+ break;
+#endif
+ }
+}
+#endif
+
+/*
+ * Find out what kind of machine we're on and save any data we need
+ * from the early boot process (devtree is copied on pmac by prom_init()).
+ * This is called very early on the boot process, after a minimal
+ * MMU environment has been set up but before MMU_init is called.
+ */
+void __init machine_init(unsigned long dt_ptr, unsigned long phys)
+{
+ early_init_devtree(__va(dt_ptr));
+
+#ifdef CONFIG_CMDLINE
+ strlcpy(cmd_line, CONFIG_CMDLINE, sizeof(cmd_line));
+#endif /* CONFIG_CMDLINE */
+
+ platform_init();
+
+#ifdef CONFIG_6xx
+ ppc_md.power_save = ppc6xx_idle;
+#endif
+
+ if (ppc_md.progress)
+ ppc_md.progress("id mach(): done", 0x200);
+}
+
+#ifdef CONFIG_BOOKE_WDT
+/* Checks wdt=x and wdt_period=xx command-line option */
+int __init early_parse_wdt(char *p)
+{
+ if (p && strncmp(p, "0", 1) != 0)
+ booke_wdt_enabled = 1;
+
+ return 0;
+}
+early_param("wdt", early_parse_wdt);
+
+int __init early_parse_wdt_period (char *p)
+{
+ if (p)
+ booke_wdt_period = simple_strtoul(p, NULL, 0);
+
+ return 0;
+}
+early_param("wdt_period", early_parse_wdt_period);
+#endif /* CONFIG_BOOKE_WDT */
+
+/* Checks "l2cr=xxxx" command-line option */
+int __init ppc_setup_l2cr(char *str)
+{
+ if (cpu_has_feature(CPU_FTR_L2CR)) {
+ unsigned long val = simple_strtoul(str, NULL, 0);
+ printk(KERN_INFO "l2cr set to %lx\n", val);
+ _set_L2CR(0); /* force invalidate by disable cache */
+ _set_L2CR(val); /* and enable it */
+ }
+ return 1;
+}
+__setup("l2cr=", ppc_setup_l2cr);
+
+#ifdef CONFIG_GENERIC_NVRAM
+
+/* Generic nvram hooks used by drivers/char/gen_nvram.c */
+unsigned char nvram_read_byte(int addr)
+{
+ if (ppc_md.nvram_read_val)
+ return ppc_md.nvram_read_val(addr);
+ return 0xff;
+}
+EXPORT_SYMBOL(nvram_read_byte);
+
+void nvram_write_byte(unsigned char val, int addr)
+{
+ if (ppc_md.nvram_write_val)
+ ppc_md.nvram_write_val(addr, val);
+}
+EXPORT_SYMBOL(nvram_write_byte);
+
+void nvram_sync(void)
+{
+ if (ppc_md.nvram_sync)
+ ppc_md.nvram_sync();
+}
+EXPORT_SYMBOL(nvram_sync);
+
+#endif /* CONFIG_NVRAM */
+
+static struct cpu cpu_devices[NR_CPUS];
+
+int __init ppc_init(void)
+{
+ int i;
+
+ /* clear the progress line */
+ if ( ppc_md.progress ) ppc_md.progress(" ", 0xffff);
+
+ /* register CPU devices */
+ for (i = 0; i < NR_CPUS; i++)
+ if (cpu_possible(i))
+ register_cpu(&cpu_devices[i], i, NULL);
+
+ /* call platform init */
+ if (ppc_md.init != NULL) {
+ ppc_md.init();
+ }
+ return 0;
+}
+
+arch_initcall(ppc_init);
+
+/* Warning, IO base is not yet inited */
+void __init setup_arch(char **cmdline_p)
+{
+ extern void do_init_bootmem(void);
+
+ /* so udelay does something sensible, assume <= 1000 bogomips */
+ loops_per_jiffy = 500000000 / HZ;
+
+ unflatten_device_tree();
+ check_for_initrd();
+ finish_device_tree();
+
+ smp_setup_cpu_maps();
+
+#ifdef CONFIG_BOOTX_TEXT
+ init_boot_display();
+#endif
+
+#ifdef CONFIG_PPC_PMAC
+ /* This could be called "early setup arch", it must be done
+ * now because xmon need it
+ */
+ if (_machine == _MACH_Pmac)
+ pmac_feature_init(); /* New cool way */
+#endif
+
+#ifdef CONFIG_XMON_DEFAULT
+ xmon_init(1);
+#endif
+
+#if defined(CONFIG_KGDB)
+ if (ppc_md.kgdb_map_scc)
+ ppc_md.kgdb_map_scc();
+ set_debug_traps();
+ if (strstr(cmd_line, "gdb")) {
+ if (ppc_md.progress)
+ ppc_md.progress("setup_arch: kgdb breakpoint", 0x4000);
+ printk("kgdb breakpoint activated\n");
+ breakpoint();
+ }
+#endif
+
+ /*
+ * Set cache line size based on type of cpu as a default.
+ * Systems with OF can look in the properties on the cpu node(s)
+ * for a possibly more accurate value.
+ */
+ if (cpu_has_feature(CPU_FTR_SPLIT_ID_CACHE)) {
+ dcache_bsize = cur_cpu_spec->dcache_bsize;
+ icache_bsize = cur_cpu_spec->icache_bsize;
+ ucache_bsize = 0;
+ } else
+ ucache_bsize = dcache_bsize = icache_bsize
+ = cur_cpu_spec->dcache_bsize;
+
+ /* reboot on panic */
+ panic_timeout = 180;
+
+ init_mm.start_code = PAGE_OFFSET;
+ init_mm.end_code = (unsigned long) _etext;
+ init_mm.end_data = (unsigned long) _edata;
+ init_mm.brk = klimit;
+
+ /* Save unparsed command line copy for /proc/cmdline */
+ strlcpy(saved_command_line, cmd_line, COMMAND_LINE_SIZE);
+ *cmdline_p = cmd_line;
+
+ parse_early_param();
+
+ /* set up the bootmem stuff with available memory */
+ do_init_bootmem();
+ if ( ppc_md.progress ) ppc_md.progress("setup_arch: bootmem", 0x3eab);
+
+#ifdef CONFIG_PPC_OCP
+ /* Initialize OCP device list */
+ ocp_early_init();
+ if ( ppc_md.progress ) ppc_md.progress("ocp: exit", 0x3eab);
+#endif
+
+#ifdef CONFIG_DUMMY_CONSOLE
+ conswitchp = &dummy_con;
+#endif
+
+ ppc_md.setup_arch();
+ if ( ppc_md.progress ) ppc_md.progress("arch: exit", 0x3eab);
+
+ paging_init();
+
+ /* this is for modules since _machine can be a define -- Cort */
+ ppc_md.ppc_machine = _machine;
+}
diff --git a/arch/ppc64/kernel/setup.c b/arch/powerpc/kernel/setup_64.c
index 5ac48bd64891..6791668213e7 100644
--- a/arch/ppc64/kernel/setup.c
+++ b/arch/powerpc/kernel/setup_64.c
@@ -37,12 +37,10 @@
#include <asm/prom.h>
#include <asm/processor.h>
#include <asm/pgtable.h>
-#include <asm/bootinfo.h>
#include <asm/smp.h>
#include <asm/elf.h>
#include <asm/machdep.h>
#include <asm/paca.h>
-#include <asm/ppcdebug.h>
#include <asm/time.h>
#include <asm/cputable.h>
#include <asm/sections.h>
@@ -57,7 +55,13 @@
#include <asm/page.h>
#include <asm/mmu.h>
#include <asm/lmb.h>
-#include <asm/iSeries/ItLpNaca.h>
+#include <asm/iseries/it_lp_naca.h>
+#include <asm/firmware.h>
+#include <asm/systemcfg.h>
+#include <asm/xmon.h>
+#include <asm/udbg.h>
+
+#include "setup.h"
#ifdef DEBUG
#define DBG(fmt...) udbg_printf(fmt)
@@ -92,17 +96,6 @@ extern void udbg_init_maple_realmode(void);
do { udbg_putc = call_rtas_display_status_delay; } while(0)
#endif
-/* extern void *stab; */
-extern unsigned long klimit;
-
-extern void mm_init_ppc64(void);
-extern void stab_initialize(unsigned long stab);
-extern void htab_initialize(void);
-extern void early_init_devtree(void *flat_dt);
-extern void unflatten_device_tree(void);
-
-extern void smp_release_cpus(void);
-
int have_of = 1;
int boot_cpuid = 0;
int boot_cpuid_phys = 0;
@@ -136,24 +129,7 @@ static struct notifier_block ppc64_panic_block = {
.priority = INT_MIN /* may not return; must be done last */
};
-/*
- * Perhaps we can put the pmac screen_info[] here
- * on pmac as well so we don't need the ifdef's.
- * Until we get multiple-console support in here
- * that is. -- Cort
- * Maybe tie it to serial consoles, since this is really what
- * these processors use on existing boards. -- Dan
- */
-struct screen_info screen_info = {
- .orig_x = 0,
- .orig_y = 25,
- .orig_video_cols = 80,
- .orig_video_lines = 25,
- .orig_video_isVGA = 1,
- .orig_video_points = 16
-};
-
-#if defined(CONFIG_PPC_MULTIPLATFORM) && defined(CONFIG_SMP)
+#ifdef CONFIG_SMP
static int smt_enabled_cmdline;
@@ -198,123 +174,15 @@ static int __init early_smt_enabled(char *p)
}
early_param("smt-enabled", early_smt_enabled);
-/**
- * setup_cpu_maps - initialize the following cpu maps:
- * cpu_possible_map
- * cpu_present_map
- * cpu_sibling_map
- *
- * Having the possible map set up early allows us to restrict allocations
- * of things like irqstacks to num_possible_cpus() rather than NR_CPUS.
- *
- * We do not initialize the online map here; cpus set their own bits in
- * cpu_online_map as they come up.
- *
- * This function is valid only for Open Firmware systems. finish_device_tree
- * must be called before using this.
- *
- * While we're here, we may as well set the "physical" cpu ids in the paca.
- */
-static void __init setup_cpu_maps(void)
-{
- struct device_node *dn = NULL;
- int cpu = 0;
- int swap_cpuid = 0;
-
- check_smt_enabled();
-
- while ((dn = of_find_node_by_type(dn, "cpu")) && cpu < NR_CPUS) {
- u32 *intserv;
- int j, len = sizeof(u32), nthreads;
-
- intserv = (u32 *)get_property(dn, "ibm,ppc-interrupt-server#s",
- &len);
- if (!intserv)
- intserv = (u32 *)get_property(dn, "reg", NULL);
-
- nthreads = len / sizeof(u32);
-
- for (j = 0; j < nthreads && cpu < NR_CPUS; j++) {
- cpu_set(cpu, cpu_present_map);
- set_hard_smp_processor_id(cpu, intserv[j]);
-
- if (intserv[j] == boot_cpuid_phys)
- swap_cpuid = cpu;
- cpu_set(cpu, cpu_possible_map);
- cpu++;
- }
- }
-
- /* Swap CPU id 0 with boot_cpuid_phys, so we can always assume that
- * boot cpu is logical 0.
- */
- if (boot_cpuid_phys != get_hard_smp_processor_id(0)) {
- u32 tmp;
- tmp = get_hard_smp_processor_id(0);
- set_hard_smp_processor_id(0, boot_cpuid_phys);
- set_hard_smp_processor_id(swap_cpuid, tmp);
- }
-
- /*
- * On pSeries LPAR, we need to know how many cpus
- * could possibly be added to this partition.
- */
- if (systemcfg->platform == PLATFORM_PSERIES_LPAR &&
- (dn = of_find_node_by_path("/rtas"))) {
- int num_addr_cell, num_size_cell, maxcpus;
- unsigned int *ireg;
-
- num_addr_cell = prom_n_addr_cells(dn);
- num_size_cell = prom_n_size_cells(dn);
-
- ireg = (unsigned int *)
- get_property(dn, "ibm,lrdr-capacity", NULL);
-
- if (!ireg)
- goto out;
-
- maxcpus = ireg[num_addr_cell + num_size_cell];
-
- /* Double maxcpus for processors which have SMT capability */
- if (cpu_has_feature(CPU_FTR_SMT))
- maxcpus *= 2;
-
- if (maxcpus > NR_CPUS) {
- printk(KERN_WARNING
- "Partition configured for %d cpus, "
- "operating system maximum is %d.\n",
- maxcpus, NR_CPUS);
- maxcpus = NR_CPUS;
- } else
- printk(KERN_INFO "Partition configured for %d cpus.\n",
- maxcpus);
-
- for (cpu = 0; cpu < maxcpus; cpu++)
- cpu_set(cpu, cpu_possible_map);
- out:
- of_node_put(dn);
- }
-
- /*
- * Do the sibling map; assume only two threads per processor.
- */
- for_each_cpu(cpu) {
- cpu_set(cpu, cpu_sibling_map[cpu]);
- if (cpu_has_feature(CPU_FTR_SMT))
- cpu_set(cpu ^ 0x1, cpu_sibling_map[cpu]);
- }
-
- systemcfg->processorCount = num_present_cpus();
-}
-#endif /* defined(CONFIG_PPC_MULTIPLATFORM) && defined(CONFIG_SMP) */
-
-
-#ifdef CONFIG_PPC_MULTIPLATFORM
+#else
+#define check_smt_enabled()
+#endif /* CONFIG_SMP */
extern struct machdep_calls pSeries_md;
extern struct machdep_calls pmac_md;
extern struct machdep_calls maple_md;
-extern struct machdep_calls bpa_md;
+extern struct machdep_calls cell_md;
+extern struct machdep_calls iseries_md;
/* Ultimately, stuff them in an elf section like initcalls... */
static struct machdep_calls __initdata *machines[] = {
@@ -327,8 +195,11 @@ static struct machdep_calls __initdata *machines[] = {
#ifdef CONFIG_PPC_MAPLE
&maple_md,
#endif /* CONFIG_PPC_MAPLE */
-#ifdef CONFIG_PPC_BPA
- &bpa_md,
+#ifdef CONFIG_PPC_CELL
+ &cell_md,
+#endif
+#ifdef CONFIG_PPC_ISERIES
+ &iseries_md,
#endif
NULL
};
@@ -366,12 +237,6 @@ void __init early_setup(unsigned long dt_ptr)
DBG(" -> early_setup()\n");
/*
- * Fill the default DBG level (do we want to keep
- * that old mecanism around forever ?)
- */
- ppcdbg_initialize();
-
- /*
* Do early initializations using the flattened device
* tree, like retreiving the physical memory map or
* calculating/retreiving the hash table size
@@ -382,11 +247,10 @@ void __init early_setup(unsigned long dt_ptr)
* Iterate all ppc_md structures until we find the proper
* one for the current machine type
*/
- DBG("Probing machine type for platform %x...\n",
- systemcfg->platform);
+ DBG("Probing machine type for platform %x...\n", _machine);
for (mach = machines; *mach; mach++) {
- if ((*mach)->probe(systemcfg->platform))
+ if ((*mach)->probe(_machine))
break;
}
/* What can we do if we didn't find ? */
@@ -399,22 +263,74 @@ void __init early_setup(unsigned long dt_ptr)
DBG("Found, Initializing memory management...\n");
/*
- * Initialize stab / SLB management
+ * Initialize the MMU Hash table and create the linear mapping
+ * of memory. Has to be done before stab/slb initialization as
+ * this is currently where the page size encoding is obtained
*/
- stab_initialize(lpaca->stab_real);
+ htab_initialize();
/*
- * Initialize the MMU Hash table and create the linear mapping
- * of memory
+ * Initialize stab / SLB management except on iSeries
*/
- htab_initialize();
+ if (!firmware_has_feature(FW_FEATURE_ISERIES)) {
+ if (cpu_has_feature(CPU_FTR_SLB))
+ slb_initialize();
+ else
+ stab_initialize(lpaca->stab_real);
+ }
DBG(" <- early_setup()\n");
}
+#ifdef CONFIG_SMP
+void early_setup_secondary(void)
+{
+ struct paca_struct *lpaca = get_paca();
+
+ /* Mark enabled in PACA */
+ lpaca->proc_enabled = 0;
+
+ /* Initialize hash table for that CPU */
+ htab_initialize_secondary();
+
+ /* Initialize STAB/SLB. We use a virtual address as it works
+ * in real mode on pSeries and we want a virutal address on
+ * iSeries anyway
+ */
+ if (cpu_has_feature(CPU_FTR_SLB))
+ slb_initialize();
+ else
+ stab_initialize(lpaca->stab_addr);
+}
+
+#endif /* CONFIG_SMP */
+
+#if defined(CONFIG_SMP) || defined(CONFIG_KEXEC)
+void smp_release_cpus(void)
+{
+ extern unsigned long __secondary_hold_spinloop;
+
+ DBG(" -> smp_release_cpus()\n");
+
+ /* All secondary cpus are spinning on a common spinloop, release them
+ * all now so they can start to spin on their individual paca
+ * spinloops. For non SMP kernels, the secondary cpus never get out
+ * of the common spinloop.
+ * This is useless but harmless on iSeries, secondaries are already
+ * waiting on their paca spinloops. */
+
+ __secondary_hold_spinloop = 1;
+ mb();
+
+ DBG(" <- smp_release_cpus()\n");
+}
+#else
+#define smp_release_cpus()
+#endif /* CONFIG_SMP || CONFIG_KEXEC */
/*
- * Initialize some remaining members of the ppc64_caches and systemcfg structures
+ * Initialize some remaining members of the ppc64_caches and systemcfg
+ * structures
* (at least until we get rid of them completely). This is mostly some
* cache informations about the CPU that will be used by cache flush
* routines and/or provided to userland
@@ -439,7 +355,7 @@ static void __init initialize_cache_info(void)
const char *dc, *ic;
/* Then read cache informations */
- if (systemcfg->platform == PLATFORM_POWERMAC) {
+ if (_machine == PLATFORM_POWERMAC) {
dc = "d-cache-block-size";
ic = "i-cache-block-size";
} else {
@@ -459,8 +375,8 @@ static void __init initialize_cache_info(void)
DBG("Argh, can't find dcache properties ! "
"sizep: %p, lsizep: %p\n", sizep, lsizep);
- systemcfg->dcache_size = ppc64_caches.dsize = size;
- systemcfg->dcache_line_size =
+ _systemcfg->dcache_size = ppc64_caches.dsize = size;
+ _systemcfg->dcache_line_size =
ppc64_caches.dline_size = lsize;
ppc64_caches.log_dline_size = __ilog2(lsize);
ppc64_caches.dlines_per_page = PAGE_SIZE / lsize;
@@ -477,8 +393,8 @@ static void __init initialize_cache_info(void)
DBG("Argh, can't find icache properties ! "
"sizep: %p, lsizep: %p\n", sizep, lsizep);
- systemcfg->icache_size = ppc64_caches.isize = size;
- systemcfg->icache_line_size =
+ _systemcfg->icache_size = ppc64_caches.isize = size;
+ _systemcfg->icache_line_size =
ppc64_caches.iline_size = lsize;
ppc64_caches.log_iline_size = __ilog2(lsize);
ppc64_caches.ilines_per_page = PAGE_SIZE / lsize;
@@ -486,53 +402,16 @@ static void __init initialize_cache_info(void)
}
/* Add an eye catcher and the systemcfg layout version number */
- strcpy(systemcfg->eye_catcher, "SYSTEMCFG:PPC64");
- systemcfg->version.major = SYSTEMCFG_MAJOR;
- systemcfg->version.minor = SYSTEMCFG_MINOR;
- systemcfg->processor = mfspr(SPRN_PVR);
+ strcpy(_systemcfg->eye_catcher, "SYSTEMCFG:PPC64");
+ _systemcfg->version.major = SYSTEMCFG_MAJOR;
+ _systemcfg->version.minor = SYSTEMCFG_MINOR;
+ _systemcfg->processor = mfspr(SPRN_PVR);
+ _systemcfg->platform = _machine;
+ _systemcfg->physicalMemorySize = lmb_phys_mem_size();
DBG(" <- initialize_cache_info()\n");
}
-static void __init check_for_initrd(void)
-{
-#ifdef CONFIG_BLK_DEV_INITRD
- u64 *prop;
-
- DBG(" -> check_for_initrd()\n");
-
- if (of_chosen) {
- prop = (u64 *)get_property(of_chosen,
- "linux,initrd-start", NULL);
- if (prop != NULL) {
- initrd_start = (unsigned long)__va(*prop);
- prop = (u64 *)get_property(of_chosen,
- "linux,initrd-end", NULL);
- if (prop != NULL) {
- initrd_end = (unsigned long)__va(*prop);
- initrd_below_start_ok = 1;
- } else
- initrd_start = 0;
- }
- }
-
- /* If we were passed an initrd, set the ROOT_DEV properly if the values
- * look sensible. If not, clear initrd reference.
- */
- if (initrd_start >= KERNELBASE && initrd_end >= KERNELBASE &&
- initrd_end > initrd_start)
- ROOT_DEV = Root_RAM0;
- else
- initrd_start = initrd_end = 0;
-
- if (initrd_start)
- printk("Found initrd at 0x%lx:0x%lx\n", initrd_start, initrd_end);
-
- DBG(" <- check_for_initrd()\n");
-#endif /* CONFIG_BLK_DEV_INITRD */
-}
-
-#endif /* CONFIG_PPC_MULTIPLATFORM */
/*
* Do some initial setup of the system. The parameters are those which
@@ -542,14 +421,6 @@ void __init setup_system(void)
{
DBG(" -> setup_system()\n");
-#ifdef CONFIG_PPC_ISERIES
- /* pSeries systems are identified in prom.c via OF. */
- if (itLpNaca.xLparInstalled == 1)
- systemcfg->platform = PLATFORM_ISERIES_LPAR;
-
- ppc_md.init_early();
-#else /* CONFIG_PPC_ISERIES */
-
/*
* Unflatten the device-tree passed by prom_init or kexec
*/
@@ -592,6 +463,10 @@ void __init setup_system(void)
*/
finish_device_tree();
+#ifdef CONFIG_BOOTX_TEXT
+ init_boot_display();
+#endif
+
/*
* Initialize xmon
*/
@@ -607,30 +482,24 @@ void __init setup_system(void)
strlcpy(saved_command_line, cmd_line, COMMAND_LINE_SIZE);
parse_early_param();
-#endif /* !CONFIG_PPC_ISERIES */
-#if defined(CONFIG_SMP) && !defined(CONFIG_PPC_ISERIES)
- /*
- * iSeries has already initialized the cpu maps at this point.
- */
- setup_cpu_maps();
+ check_smt_enabled();
+ smp_setup_cpu_maps();
/* Release secondary cpus out of their spinloops at 0x60 now that
* we can map physical -> logical CPU ids
*/
smp_release_cpus();
-#endif /* defined(CONFIG_SMP) && !defined(CONFIG_PPC_ISERIES) */
printk("Starting Linux PPC64 %s\n", system_utsname.version);
printk("-----------------------------------------------------\n");
printk("ppc64_pft_size = 0x%lx\n", ppc64_pft_size);
- printk("ppc64_debug_switch = 0x%lx\n", ppc64_debug_switch);
printk("ppc64_interrupt_controller = 0x%ld\n", ppc64_interrupt_controller);
- printk("systemcfg = 0x%p\n", systemcfg);
- printk("systemcfg->platform = 0x%x\n", systemcfg->platform);
- printk("systemcfg->processorCount = 0x%lx\n", systemcfg->processorCount);
- printk("systemcfg->physicalMemorySize = 0x%lx\n", systemcfg->physicalMemorySize);
+ printk("systemcfg = 0x%p\n", _systemcfg);
+ printk("systemcfg->platform = 0x%x\n", _systemcfg->platform);
+ printk("systemcfg->processorCount = 0x%lx\n", _systemcfg->processorCount);
+ printk("systemcfg->physicalMemorySize = 0x%lx\n", _systemcfg->physicalMemorySize);
printk("ppc64_caches.dcache_line_size = 0x%x\n",
ppc64_caches.dline_size);
printk("ppc64_caches.icache_line_size = 0x%x\n",
@@ -644,51 +513,6 @@ void __init setup_system(void)
DBG(" <- setup_system()\n");
}
-/* also used by kexec */
-void machine_shutdown(void)
-{
- if (ppc_md.nvram_sync)
- ppc_md.nvram_sync();
-}
-
-void machine_restart(char *cmd)
-{
- machine_shutdown();
- ppc_md.restart(cmd);
-#ifdef CONFIG_SMP
- smp_send_stop();
-#endif
- printk(KERN_EMERG "System Halted, OK to turn off power\n");
- local_irq_disable();
- while (1) ;
-}
-
-void machine_power_off(void)
-{
- machine_shutdown();
- ppc_md.power_off();
-#ifdef CONFIG_SMP
- smp_send_stop();
-#endif
- printk(KERN_EMERG "System Halted, OK to turn off power\n");
- local_irq_disable();
- while (1) ;
-}
-/* Used by the G5 thermal driver */
-EXPORT_SYMBOL_GPL(machine_power_off);
-
-void machine_halt(void)
-{
- machine_shutdown();
- ppc_md.halt();
-#ifdef CONFIG_SMP
- smp_send_stop();
-#endif
- printk(KERN_EMERG "System Halted, OK to turn off power\n");
- local_irq_disable();
- while (1) ;
-}
-
static int ppc64_panic_event(struct notifier_block *this,
unsigned long event, void *ptr)
{
@@ -696,240 +520,6 @@ static int ppc64_panic_event(struct notifier_block *this,
return NOTIFY_DONE;
}
-
-#ifdef CONFIG_SMP
-DEFINE_PER_CPU(unsigned int, pvr);
-#endif
-
-static int show_cpuinfo(struct seq_file *m, void *v)
-{
- unsigned long cpu_id = (unsigned long)v - 1;
- unsigned int pvr;
- unsigned short maj;
- unsigned short min;
-
- if (cpu_id == NR_CPUS) {
- seq_printf(m, "timebase\t: %lu\n", ppc_tb_freq);
-
- if (ppc_md.get_cpuinfo != NULL)
- ppc_md.get_cpuinfo(m);
-
- return 0;
- }
-
- /* We only show online cpus: disable preempt (overzealous, I
- * knew) to prevent cpu going down. */
- preempt_disable();
- if (!cpu_online(cpu_id)) {
- preempt_enable();
- return 0;
- }
-
-#ifdef CONFIG_SMP
- pvr = per_cpu(pvr, cpu_id);
-#else
- pvr = mfspr(SPRN_PVR);
-#endif
- maj = (pvr >> 8) & 0xFF;
- min = pvr & 0xFF;
-
- seq_printf(m, "processor\t: %lu\n", cpu_id);
- seq_printf(m, "cpu\t\t: ");
-
- if (cur_cpu_spec->pvr_mask)
- seq_printf(m, "%s", cur_cpu_spec->cpu_name);
- else
- seq_printf(m, "unknown (%08x)", pvr);
-
-#ifdef CONFIG_ALTIVEC
- if (cpu_has_feature(CPU_FTR_ALTIVEC))
- seq_printf(m, ", altivec supported");
-#endif /* CONFIG_ALTIVEC */
-
- seq_printf(m, "\n");
-
- /*
- * Assume here that all clock rates are the same in a
- * smp system. -- Cort
- */
- seq_printf(m, "clock\t\t: %lu.%06luMHz\n", ppc_proc_freq / 1000000,
- ppc_proc_freq % 1000000);
-
- seq_printf(m, "revision\t: %hd.%hd\n\n", maj, min);
-
- preempt_enable();
- return 0;
-}
-
-static void *c_start(struct seq_file *m, loff_t *pos)
-{
- return *pos <= NR_CPUS ? (void *)((*pos)+1) : NULL;
-}
-static void *c_next(struct seq_file *m, void *v, loff_t *pos)
-{
- ++*pos;
- return c_start(m, pos);
-}
-static void c_stop(struct seq_file *m, void *v)
-{
-}
-struct seq_operations cpuinfo_op = {
- .start =c_start,
- .next = c_next,
- .stop = c_stop,
- .show = show_cpuinfo,
-};
-
-/*
- * These three variables are used to save values passed to us by prom_init()
- * via the device tree. The TCE variables are needed because with a memory_limit
- * in force we may need to explicitly map the TCE are at the top of RAM.
- */
-unsigned long memory_limit;
-unsigned long tce_alloc_start;
-unsigned long tce_alloc_end;
-
-#ifdef CONFIG_PPC_ISERIES
-/*
- * On iSeries we just parse the mem=X option from the command line.
- * On pSeries it's a bit more complicated, see prom_init_mem()
- */
-static int __init early_parsemem(char *p)
-{
- if (!p)
- return 0;
-
- memory_limit = ALIGN(memparse(p, &p), PAGE_SIZE);
-
- return 0;
-}
-early_param("mem", early_parsemem);
-#endif /* CONFIG_PPC_ISERIES */
-
-#ifdef CONFIG_PPC_MULTIPLATFORM
-static int __init set_preferred_console(void)
-{
- struct device_node *prom_stdout = NULL;
- char *name;
- u32 *spd;
- int offset = 0;
-
- DBG(" -> set_preferred_console()\n");
-
- /* The user has requested a console so this is already set up. */
- if (strstr(saved_command_line, "console=")) {
- DBG(" console was specified !\n");
- return -EBUSY;
- }
-
- if (!of_chosen) {
- DBG(" of_chosen is NULL !\n");
- return -ENODEV;
- }
- /* We are getting a weird phandle from OF ... */
- /* ... So use the full path instead */
- name = (char *)get_property(of_chosen, "linux,stdout-path", NULL);
- if (name == NULL) {
- DBG(" no linux,stdout-path !\n");
- return -ENODEV;
- }
- prom_stdout = of_find_node_by_path(name);
- if (!prom_stdout) {
- DBG(" can't find stdout package %s !\n", name);
- return -ENODEV;
- }
- DBG("stdout is %s\n", prom_stdout->full_name);
-
- name = (char *)get_property(prom_stdout, "name", NULL);
- if (!name) {
- DBG(" stdout package has no name !\n");
- goto not_found;
- }
- spd = (u32 *)get_property(prom_stdout, "current-speed", NULL);
-
- if (0)
- ;
-#ifdef CONFIG_SERIAL_8250_CONSOLE
- else if (strcmp(name, "serial") == 0) {
- int i;
- u32 *reg = (u32 *)get_property(prom_stdout, "reg", &i);
- if (i > 8) {
- switch (reg[1]) {
- case 0x3f8:
- offset = 0;
- break;
- case 0x2f8:
- offset = 1;
- break;
- case 0x898:
- offset = 2;
- break;
- case 0x890:
- offset = 3;
- break;
- default:
- /* We dont recognise the serial port */
- goto not_found;
- }
- }
- }
-#endif /* CONFIG_SERIAL_8250_CONSOLE */
-#ifdef CONFIG_PPC_PSERIES
- else if (strcmp(name, "vty") == 0) {
- u32 *reg = (u32 *)get_property(prom_stdout, "reg", NULL);
- char *compat = (char *)get_property(prom_stdout, "compatible", NULL);
-
- if (reg && compat && (strcmp(compat, "hvterm-protocol") == 0)) {
- /* Host Virtual Serial Interface */
- int offset;
- switch (reg[0]) {
- case 0x30000000:
- offset = 0;
- break;
- case 0x30000001:
- offset = 1;
- break;
- default:
- goto not_found;
- }
- of_node_put(prom_stdout);
- DBG("Found hvsi console at offset %d\n", offset);
- return add_preferred_console("hvsi", offset, NULL);
- } else {
- /* pSeries LPAR virtual console */
- of_node_put(prom_stdout);
- DBG("Found hvc console\n");
- return add_preferred_console("hvc", 0, NULL);
- }
- }
-#endif /* CONFIG_PPC_PSERIES */
-#ifdef CONFIG_SERIAL_PMACZILOG_CONSOLE
- else if (strcmp(name, "ch-a") == 0)
- offset = 0;
- else if (strcmp(name, "ch-b") == 0)
- offset = 1;
-#endif /* CONFIG_SERIAL_PMACZILOG_CONSOLE */
- else
- goto not_found;
- of_node_put(prom_stdout);
-
- DBG("Found serial console at ttyS%d\n", offset);
-
- if (spd) {
- static char __initdata opt[16];
- sprintf(opt, "%d", *spd);
- return add_preferred_console("ttyS", offset, opt);
- } else
- return add_preferred_console("ttyS", offset, NULL);
-
- not_found:
- DBG("No preferred console found !\n");
- of_node_put(prom_stdout);
- return -ENODEV;
-}
-console_initcall(set_preferred_console);
-#endif /* CONFIG_PPC_MULTIPLATFORM */
-
#ifdef CONFIG_IRQSTACKS
static void __init irqstack_early_init(void)
{
@@ -940,10 +530,12 @@ static void __init irqstack_early_init(void)
* SLB misses on them.
*/
for_each_cpu(i) {
- softirq_ctx[i] = (struct thread_info *)__va(lmb_alloc_base(THREAD_SIZE,
- THREAD_SIZE, 0x10000000));
- hardirq_ctx[i] = (struct thread_info *)__va(lmb_alloc_base(THREAD_SIZE,
- THREAD_SIZE, 0x10000000));
+ softirq_ctx[i] = (struct thread_info *)
+ __va(lmb_alloc_base(THREAD_SIZE,
+ THREAD_SIZE, 0x10000000));
+ hardirq_ctx[i] = (struct thread_info *)
+ __va(lmb_alloc_base(THREAD_SIZE,
+ THREAD_SIZE, 0x10000000));
}
}
#else
@@ -971,8 +563,8 @@ static void __init emergency_stack_init(void)
limit = min(0x10000000UL, lmb.rmo_size);
for_each_cpu(i)
- paca[i].emergency_sp = __va(lmb_alloc_base(PAGE_SIZE, 128,
- limit)) + PAGE_SIZE;
+ paca[i].emergency_sp =
+ __va(lmb_alloc_base(HW_PAGE_SIZE, 128, limit)) + HW_PAGE_SIZE;
}
/*
@@ -983,23 +575,22 @@ void __init setup_syscall_map(void)
{
unsigned int i, count64 = 0, count32 = 0;
extern unsigned long *sys_call_table;
- extern unsigned long *sys_call_table32;
extern unsigned long sys_ni_syscall;
for (i = 0; i < __NR_syscalls; i++) {
- if (sys_call_table[i] == sys_ni_syscall)
- continue;
- count64++;
- systemcfg->syscall_map_64[i >> 5] |= 0x80000000UL >> (i & 0x1f);
- }
- for (i = 0; i < __NR_syscalls; i++) {
- if (sys_call_table32[i] == sys_ni_syscall)
- continue;
- count32++;
- systemcfg->syscall_map_32[i >> 5] |= 0x80000000UL >> (i & 0x1f);
+ if (sys_call_table[i*2] != sys_ni_syscall) {
+ count64++;
+ _systemcfg->syscall_map_64[i >> 5] |=
+ 0x80000000UL >> (i & 0x1f);
+ }
+ if (sys_call_table[i*2+1] != sys_ni_syscall) {
+ count32++;
+ _systemcfg->syscall_map_32[i >> 5] |=
+ 0x80000000UL >> (i & 0x1f);
+ }
}
- printk(KERN_INFO "Syscall map setup, %d 32 bits and %d 64 bits syscalls\n",
+ printk(KERN_INFO "Syscall map setup, %d 32-bit and %d 64-bit syscalls\n",
count32, count64);
}
@@ -1047,6 +638,10 @@ void __init setup_arch(char **cmdline_p)
/* initialize the syscall map in systemcfg */
setup_syscall_map();
+#ifdef CONFIG_DUMMY_CONSOLE
+ conswitchp = &dummy_con;
+#endif
+
ppc_md.setup_arch();
/* Use the default idle loop if the platform hasn't provided one. */
@@ -1091,15 +686,6 @@ void ppc64_terminate_msg(unsigned int src, const char *msg)
printk("[terminate]%04x %s\n", src, msg);
}
-/* This should only be called on processor 0 during calibrate decr */
-void __init setup_default_decr(void)
-{
- struct paca_struct *lpaca = get_paca();
-
- lpaca->default_decr = tb_ticks_per_jiffy;
- lpaca->next_jiffy_update_tb = get_tb() + tb_ticks_per_jiffy;
-}
-
#ifndef CONFIG_PPC_ISERIES
/*
* This function can be used by platforms to "find" legacy serial ports.
@@ -1289,26 +875,6 @@ int check_legacy_ioport(unsigned long base_port)
}
EXPORT_SYMBOL(check_legacy_ioport);
-#ifdef CONFIG_XMON
-static int __init early_xmon(char *p)
-{
- /* ensure xmon is enabled */
- if (p) {
- if (strncmp(p, "on", 2) == 0)
- xmon_init(1);
- if (strncmp(p, "off", 3) == 0)
- xmon_init(0);
- if (strncmp(p, "early", 5) != 0)
- return 0;
- }
- xmon_init(1);
- debugger(NULL);
-
- return 0;
-}
-early_param("xmon", early_xmon);
-#endif
-
void cpu_die(void)
{
if (ppc_md.cpu_die)
diff --git a/arch/ppc64/kernel/signal32.c b/arch/powerpc/kernel/signal_32.c
index a8b7a5a56bb4..a7c4515f320f 100644
--- a/arch/ppc64/kernel/signal32.c
+++ b/arch/powerpc/kernel/signal_32.c
@@ -1,56 +1,353 @@
/*
- * signal32.c: Support 32bit signal syscalls.
+ * Signal handling for 32bit PPC and 32bit tasks on 64bit PPC
*
+ * PowerPC version
+ * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
* Copyright (C) 2001 IBM
* Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
* Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
*
- * These routines maintain argument size conversion between 32bit and 64bit
- * environment.
+ * Derived from "arch/i386/kernel/signal.c"
+ * Copyright (C) 1991, 1992 Linus Torvalds
+ * 1997-11-28 Modified for POSIX.1b signals by Richard Henderson
*
- * 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 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/config.h>
#include <linux/sched.h>
-#include <linux/mm.h>
+#include <linux/mm.h>
#include <linux/smp.h>
#include <linux/smp_lock.h>
#include <linux/kernel.h>
#include <linux/signal.h>
-#include <linux/syscalls.h>
#include <linux/errno.h>
#include <linux/elf.h>
+#ifdef CONFIG_PPC64
+#include <linux/syscalls.h>
#include <linux/compat.h>
#include <linux/ptrace.h>
-#include <asm/ppc32.h>
+#else
+#include <linux/wait.h>
+#include <linux/ptrace.h>
+#include <linux/unistd.h>
+#include <linux/stddef.h>
+#include <linux/tty.h>
+#include <linux/binfmts.h>
+#include <linux/suspend.h>
+#endif
+
#include <asm/uaccess.h>
-#include <asm/ppcdebug.h>
-#include <asm/unistd.h>
#include <asm/cacheflush.h>
+#include <asm/sigcontext.h>
+#ifdef CONFIG_PPC64
+#include "ppc32.h"
+#include <asm/unistd.h>
#include <asm/vdso.h>
+#else
+#include <asm/ucontext.h>
+#include <asm/pgtable.h>
+#endif
-#define DEBUG_SIG 0
+#undef DEBUG_SIG
#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
-#define GP_REGS_SIZE32 min(sizeof(elf_gregset_t32), sizeof(struct pt_regs32))
+#ifdef CONFIG_PPC64
+#define do_signal do_signal32
+#define sys_sigsuspend compat_sys_sigsuspend
+#define sys_rt_sigsuspend compat_sys_rt_sigsuspend
+#define sys_rt_sigreturn compat_sys_rt_sigreturn
+#define sys_sigaction compat_sys_sigaction
+#define sys_swapcontext compat_sys_swapcontext
+#define sys_sigreturn compat_sys_sigreturn
+
+#define old_sigaction old_sigaction32
+#define sigcontext sigcontext32
+#define mcontext mcontext32
+#define ucontext ucontext32
+
+/*
+ * Returning 0 means we return to userspace via
+ * ret_from_except and thus restore all user
+ * registers from *regs. This is what we need
+ * to do when a signal has been delivered.
+ */
+#define sigreturn_exit(regs) return 0
+
+#define GP_REGS_SIZE min(sizeof(elf_gregset_t32), sizeof(struct pt_regs32))
+#undef __SIGNAL_FRAMESIZE
+#define __SIGNAL_FRAMESIZE __SIGNAL_FRAMESIZE32
+#undef ELF_NVRREG
+#define ELF_NVRREG ELF_NVRREG32
+
+/*
+ * Functions for flipping sigsets (thanks to brain dead generic
+ * implementation that makes things simple for little endian only)
+ */
+static inline int put_sigset_t(compat_sigset_t __user *uset, sigset_t *set)
+{
+ compat_sigset_t cset;
+
+ switch (_NSIG_WORDS) {
+ case 4: cset.sig[5] = set->sig[3] & 0xffffffffull;
+ cset.sig[7] = set->sig[3] >> 32;
+ case 3: cset.sig[4] = set->sig[2] & 0xffffffffull;
+ cset.sig[5] = set->sig[2] >> 32;
+ case 2: cset.sig[2] = set->sig[1] & 0xffffffffull;
+ cset.sig[3] = set->sig[1] >> 32;
+ case 1: cset.sig[0] = set->sig[0] & 0xffffffffull;
+ cset.sig[1] = set->sig[0] >> 32;
+ }
+ return copy_to_user(uset, &cset, sizeof(*uset));
+}
+
+static inline int get_sigset_t(sigset_t *set,
+ const compat_sigset_t __user *uset)
+{
+ compat_sigset_t s32;
+
+ if (copy_from_user(&s32, uset, sizeof(*uset)))
+ return -EFAULT;
+
+ /*
+ * Swap the 2 words of the 64-bit sigset_t (they are stored
+ * in the "wrong" endian in 32-bit user storage).
+ */
+ switch (_NSIG_WORDS) {
+ case 4: set->sig[3] = s32.sig[6] | (((long)s32.sig[7]) << 32);
+ case 3: set->sig[2] = s32.sig[4] | (((long)s32.sig[5]) << 32);
+ case 2: set->sig[1] = s32.sig[2] | (((long)s32.sig[3]) << 32);
+ case 1: set->sig[0] = s32.sig[0] | (((long)s32.sig[1]) << 32);
+ }
+ return 0;
+}
+
+static inline int get_old_sigaction(struct k_sigaction *new_ka,
+ struct old_sigaction __user *act)
+{
+ compat_old_sigset_t mask;
+ compat_uptr_t handler, restorer;
+
+ if (get_user(handler, &act->sa_handler) ||
+ __get_user(restorer, &act->sa_restorer) ||
+ __get_user(new_ka->sa.sa_flags, &act->sa_flags) ||
+ __get_user(mask, &act->sa_mask))
+ return -EFAULT;
+ new_ka->sa.sa_handler = compat_ptr(handler);
+ new_ka->sa.sa_restorer = compat_ptr(restorer);
+ siginitset(&new_ka->sa.sa_mask, mask);
+ return 0;
+}
+
+static inline compat_uptr_t to_user_ptr(void *kp)
+{
+ return (compat_uptr_t)(u64)kp;
+}
+
+#define from_user_ptr(p) compat_ptr(p)
+
+static inline int save_general_regs(struct pt_regs *regs,
+ struct mcontext __user *frame)
+{
+ elf_greg_t64 *gregs = (elf_greg_t64 *)regs;
+ int i;
+
+ for (i = 0; i <= PT_RESULT; i ++)
+ if (__put_user((unsigned int)gregs[i], &frame->mc_gregs[i]))
+ return -EFAULT;
+ return 0;
+}
+
+static inline int restore_general_regs(struct pt_regs *regs,
+ struct mcontext __user *sr)
+{
+ elf_greg_t64 *gregs = (elf_greg_t64 *)regs;
+ int i;
+
+ for (i = 0; i <= PT_RESULT; i++) {
+ if ((i == PT_MSR) || (i == PT_SOFTE))
+ continue;
+ if (__get_user(gregs[i], &sr->mc_gregs[i]))
+ return -EFAULT;
+ }
+ return 0;
+}
+
+#else /* CONFIG_PPC64 */
+
+extern void sigreturn_exit(struct pt_regs *);
+
+#define GP_REGS_SIZE min(sizeof(elf_gregset_t), sizeof(struct pt_regs))
+
+static inline int put_sigset_t(sigset_t __user *uset, sigset_t *set)
+{
+ return copy_to_user(uset, set, sizeof(*uset));
+}
+
+static inline int get_sigset_t(sigset_t *set, const sigset_t __user *uset)
+{
+ return copy_from_user(set, uset, sizeof(*uset));
+}
+
+static inline int get_old_sigaction(struct k_sigaction *new_ka,
+ struct old_sigaction __user *act)
+{
+ old_sigset_t mask;
+
+ if (!access_ok(VERIFY_READ, act, sizeof(*act)) ||
+ __get_user(new_ka->sa.sa_handler, &act->sa_handler) ||
+ __get_user(new_ka->sa.sa_restorer, &act->sa_restorer))
+ return -EFAULT;
+ __get_user(new_ka->sa.sa_flags, &act->sa_flags);
+ __get_user(mask, &act->sa_mask);
+ siginitset(&new_ka->sa.sa_mask, mask);
+ return 0;
+}
+
+#define to_user_ptr(p) (p)
+#define from_user_ptr(p) (p)
+
+static inline int save_general_regs(struct pt_regs *regs,
+ struct mcontext __user *frame)
+{
+ return __copy_to_user(&frame->mc_gregs, regs, GP_REGS_SIZE);
+}
+
+static inline int restore_general_regs(struct pt_regs *regs,
+ struct mcontext __user *sr)
+{
+ /* copy up to but not including MSR */
+ if (__copy_from_user(regs, &sr->mc_gregs,
+ PT_MSR * sizeof(elf_greg_t)))
+ return -EFAULT;
+ /* copy from orig_r3 (the word after the MSR) up to the end */
+ if (__copy_from_user(&regs->orig_gpr3, &sr->mc_gregs[PT_ORIG_R3],
+ GP_REGS_SIZE - PT_ORIG_R3 * sizeof(elf_greg_t)))
+ return -EFAULT;
+ return 0;
+}
+
+#endif /* CONFIG_PPC64 */
+
+int do_signal(sigset_t *oldset, struct pt_regs *regs);
+
+/*
+ * Atomically swap in the new signal mask, and wait for a signal.
+ */
+long sys_sigsuspend(old_sigset_t mask, int p2, int p3, int p4, int p6, int p7,
+ struct pt_regs *regs)
+{
+ sigset_t saveset;
+
+ mask &= _BLOCKABLE;
+ spin_lock_irq(&current->sighand->siglock);
+ saveset = current->blocked;
+ siginitset(&current->blocked, mask);
+ recalc_sigpending();
+ spin_unlock_irq(&current->sighand->siglock);
+
+ regs->result = -EINTR;
+ regs->gpr[3] = EINTR;
+ regs->ccr |= 0x10000000;
+ while (1) {
+ current->state = TASK_INTERRUPTIBLE;
+ schedule();
+ if (do_signal(&saveset, regs))
+ sigreturn_exit(regs);
+ }
+}
+
+long sys_rt_sigsuspend(
+#ifdef CONFIG_PPC64
+ compat_sigset_t __user *unewset,
+#else
+ sigset_t __user *unewset,
+#endif
+ size_t sigsetsize, int p3, int p4,
+ int p6, int p7, struct pt_regs *regs)
+{
+ sigset_t saveset, newset;
+
+ /* XXX: Don't preclude handling different sized sigset_t's. */
+ if (sigsetsize != sizeof(sigset_t))
+ return -EINVAL;
+
+ if (get_sigset_t(&newset, unewset))
+ return -EFAULT;
+ sigdelsetmask(&newset, ~_BLOCKABLE);
+
+ spin_lock_irq(&current->sighand->siglock);
+ saveset = current->blocked;
+ current->blocked = newset;
+ recalc_sigpending();
+ spin_unlock_irq(&current->sighand->siglock);
+
+ regs->result = -EINTR;
+ regs->gpr[3] = EINTR;
+ regs->ccr |= 0x10000000;
+ while (1) {
+ current->state = TASK_INTERRUPTIBLE;
+ schedule();
+ if (do_signal(&saveset, regs))
+ sigreturn_exit(regs);
+ }
+}
+
+#ifdef CONFIG_PPC32
+long sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss, int r5,
+ int r6, int r7, int r8, struct pt_regs *regs)
+{
+ return do_sigaltstack(uss, uoss, regs->gpr[1]);
+}
+#endif
+
+long sys_sigaction(int sig, struct old_sigaction __user *act,
+ struct old_sigaction __user *oact)
+{
+ struct k_sigaction new_ka, old_ka;
+ int ret;
+
+#ifdef CONFIG_PPC64
+ if (sig < 0)
+ sig = -sig;
+#endif
+
+ if (act) {
+ if (get_old_sigaction(&new_ka, act))
+ return -EFAULT;
+ }
+
+ ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
+ if (!ret && oact) {
+ if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) ||
+ __put_user(to_user_ptr(old_ka.sa.sa_handler),
+ &oact->sa_handler) ||
+ __put_user(to_user_ptr(old_ka.sa.sa_restorer),
+ &oact->sa_restorer) ||
+ __put_user(old_ka.sa.sa_flags, &oact->sa_flags) ||
+ __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask))
+ return -EFAULT;
+ }
+
+ return ret;
+}
/*
* When we have signals to deliver, we set up on the
* user stack, going down from the original stack pointer:
- * a sigregs32 struct
- * a sigcontext32 struct
- * a gap of __SIGNAL_FRAMESIZE32 bytes
+ * a sigregs struct
+ * a sigcontext struct
+ * a gap of __SIGNAL_FRAMESIZE bytes
*
* Each of these things must be a multiple of 16 bytes in size.
*
*/
-struct sigregs32 {
- struct mcontext32 mctx; /* all the register values */
+struct sigregs {
+ struct mcontext mctx; /* all the register values */
/*
* Programs using the rs6000/xcoff abi can save up to 19 gp
* regs and 18 fp regs below sp before decrementing it.
@@ -64,17 +361,21 @@ struct sigregs32 {
/*
* When we have rt signals to deliver, we set up on the
* user stack, going down from the original stack pointer:
- * one rt_sigframe32 struct (siginfo + ucontext + ABI gap)
- * a gap of __SIGNAL_FRAMESIZE32+16 bytes
- * (the +16 is to get the siginfo and ucontext32 in the same
+ * one rt_sigframe struct (siginfo + ucontext + ABI gap)
+ * a gap of __SIGNAL_FRAMESIZE+16 bytes
+ * (the +16 is to get the siginfo and ucontext in the same
* positions as in older kernels).
*
* Each of these things must be a multiple of 16 bytes in size.
*
*/
-struct rt_sigframe32 {
- compat_siginfo_t info;
- struct ucontext32 uc;
+struct rt_sigframe {
+#ifdef CONFIG_PPC64
+ compat_siginfo_t info;
+#else
+ struct siginfo info;
+#endif
+ struct ucontext uc;
/*
* Programs using the rs6000/xcoff abi can save up to 19 gp
* regs and 18 fp regs below sp before decrementing it.
@@ -82,76 +383,34 @@ struct rt_sigframe32 {
int abigap[56];
};
-
-/*
- * Common utility functions used by signal and context support
- *
- */
-
-/*
- * Restore the user process's signal mask
- * (implemented in signal.c)
- */
-extern void restore_sigmask(sigset_t *set);
-
-/*
- * Functions for flipping sigsets (thanks to brain dead generic
- * implementation that makes things simple for little endian only
- */
-static inline void compat_from_sigset(compat_sigset_t *compat, sigset_t *set)
-{
- switch (_NSIG_WORDS) {
- case 4: compat->sig[5] = set->sig[3] & 0xffffffffull ;
- compat->sig[7] = set->sig[3] >> 32;
- case 3: compat->sig[4] = set->sig[2] & 0xffffffffull ;
- compat->sig[5] = set->sig[2] >> 32;
- case 2: compat->sig[2] = set->sig[1] & 0xffffffffull ;
- compat->sig[3] = set->sig[1] >> 32;
- case 1: compat->sig[0] = set->sig[0] & 0xffffffffull ;
- compat->sig[1] = set->sig[0] >> 32;
- }
-}
-
-static inline void sigset_from_compat(sigset_t *set, compat_sigset_t *compat)
-{
- switch (_NSIG_WORDS) {
- case 4: set->sig[3] = compat->sig[6] | (((long)compat->sig[7]) << 32);
- case 3: set->sig[2] = compat->sig[4] | (((long)compat->sig[5]) << 32);
- case 2: set->sig[1] = compat->sig[2] | (((long)compat->sig[3]) << 32);
- case 1: set->sig[0] = compat->sig[0] | (((long)compat->sig[1]) << 32);
- }
-}
-
-
/*
* Save the current user registers on the user stack.
- * We only save the altivec registers if the process has used
- * altivec instructions at some point.
+ * We only save the altivec/spe registers if the process has used
+ * altivec/spe instructions at some point.
*/
-static int save_user_regs(struct pt_regs *regs, struct mcontext32 __user *frame, int sigret)
+static int save_user_regs(struct pt_regs *regs, struct mcontext __user *frame,
+ int sigret)
{
- elf_greg_t64 *gregs = (elf_greg_t64 *)regs;
- int i, err = 0;
-
+#ifdef CONFIG_PPC32
+ CHECK_FULL_REGS(regs);
+#endif
/* Make sure floating point registers are stored in regs */
flush_fp_to_thread(current);
/* save general and floating-point registers */
- for (i = 0; i <= PT_RESULT; i ++)
- err |= __put_user((unsigned int)gregs[i], &frame->mc_gregs[i]);
- err |= __copy_to_user(&frame->mc_fregs, current->thread.fpr,
- ELF_NFPREG * sizeof(double));
- if (err)
+ if (save_general_regs(regs, frame) ||
+ __copy_to_user(&frame->mc_fregs, current->thread.fpr,
+ ELF_NFPREG * sizeof(double)))
return 1;
- current->thread.fpscr = 0; /* turn off all fp exceptions */
+ current->thread.fpscr.val = 0; /* turn off all fp exceptions */
#ifdef CONFIG_ALTIVEC
/* save altivec registers */
if (current->thread.used_vr) {
flush_altivec_to_thread(current);
if (__copy_to_user(&frame->mc_vregs, current->thread.vr,
- ELF_NVRREG32 * sizeof(vector128)))
+ ELF_NVRREG * sizeof(vector128)))
return 1;
/* set MSR_VEC in the saved MSR value to indicate that
frame->mc_vregs contains valid data */
@@ -169,6 +428,25 @@ static int save_user_regs(struct pt_regs *regs, struct mcontext32 __user *frame,
return 1;
#endif /* CONFIG_ALTIVEC */
+#ifdef CONFIG_SPE
+ /* save spe registers */
+ if (current->thread.used_spe) {
+ flush_spe_to_thread(current);
+ if (__copy_to_user(&frame->mc_vregs, current->thread.evr,
+ ELF_NEVRREG * sizeof(u32)))
+ return 1;
+ /* set MSR_SPE in the saved MSR value to indicate that
+ frame->mc_vregs contains valid data */
+ if (__put_user(regs->msr | MSR_SPE, &frame->mc_gregs[PT_MSR]))
+ return 1;
+ }
+ /* else assert((regs->msr & MSR_SPE) == 0) */
+
+ /* We always copy to/from spefscr */
+ if (__put_user(current->thread.spefscr, (u32 __user *)&frame->mc_vregs + ELF_NEVRREG))
+ return 1;
+#endif /* CONFIG_SPE */
+
if (sigret) {
/* Set up the sigreturn trampoline: li r0,sigret; sc */
if (__put_user(0x38000000UL + sigret, &frame->tramp[0])
@@ -186,13 +464,11 @@ static int save_user_regs(struct pt_regs *regs, struct mcontext32 __user *frame,
* (except for MSR).
*/
static long restore_user_regs(struct pt_regs *regs,
- struct mcontext32 __user *sr, int sig)
+ struct mcontext __user *sr, int sig)
{
- elf_greg_t64 *gregs = (elf_greg_t64 *)regs;
- int i;
- long err = 0;
+ long err;
unsigned int save_r2 = 0;
-#ifdef CONFIG_ALTIVEC
+#if defined(CONFIG_ALTIVEC) || defined(CONFIG_SPE)
unsigned long msr;
#endif
@@ -202,11 +478,7 @@ static long restore_user_regs(struct pt_regs *regs,
*/
if (!sig)
save_r2 = (unsigned int)regs->gpr[2];
- for (i = 0; i <= PT_RESULT; i++) {
- if ((i == PT_MSR) || (i == PT_SOFTE))
- continue;
- err |= __get_user(gregs[i], &sr->mc_gregs[i]);
- }
+ err = restore_general_regs(regs, sr);
if (!sig)
regs->gpr[2] = (unsigned long) save_r2;
if (err)
@@ -229,135 +501,51 @@ static long restore_user_regs(struct pt_regs *regs,
sizeof(sr->mc_vregs)))
return 1;
} else if (current->thread.used_vr)
- memset(current->thread.vr, 0, ELF_NVRREG32 * sizeof(vector128));
+ memset(current->thread.vr, 0, ELF_NVRREG * sizeof(vector128));
/* Always get VRSAVE back */
if (__get_user(current->thread.vrsave, (u32 __user *)&sr->mc_vregs[32]))
return 1;
#endif /* CONFIG_ALTIVEC */
+#ifdef CONFIG_SPE
+ /* force the process to reload the spe registers from
+ current->thread when it next does spe instructions */
+ regs->msr &= ~MSR_SPE;
+ if (!__get_user(msr, &sr->mc_gregs[PT_MSR]) && (msr & MSR_SPE) != 0) {
+ /* restore spe registers from the stack */
+ if (__copy_from_user(current->thread.evr, &sr->mc_vregs,
+ ELF_NEVRREG * sizeof(u32)))
+ return 1;
+ } else if (current->thread.used_spe)
+ memset(current->thread.evr, 0, ELF_NEVRREG * sizeof(u32));
+
+ /* Always get SPEFSCR back */
+ if (__get_user(current->thread.spefscr, (u32 __user *)&sr->mc_vregs + ELF_NEVRREG))
+ return 1;
+#endif /* CONFIG_SPE */
+
#ifndef CONFIG_SMP
preempt_disable();
if (last_task_used_math == current)
last_task_used_math = NULL;
if (last_task_used_altivec == current)
last_task_used_altivec = NULL;
+#ifdef CONFIG_SPE
+ if (last_task_used_spe == current)
+ last_task_used_spe = NULL;
+#endif
preempt_enable();
#endif
return 0;
}
-
-/*
- * Start of nonRT signal support
- *
- * sigset_t is 32 bits for non-rt signals
- *
- * System Calls
- * sigaction sys32_sigaction
- * sigreturn sys32_sigreturn
- *
- * Note sigsuspend has no special 32 bit routine - uses the 64 bit routine
- *
- * Other routines
- * setup_frame32
- */
-
-/*
- * Atomically swap in the new signal mask, and wait for a signal.
- */
-long sys32_sigsuspend(old_sigset_t mask, int p2, int p3, int p4, int p6, int p7,
- struct pt_regs *regs)
-{
- sigset_t saveset;
-
- mask &= _BLOCKABLE;
- spin_lock_irq(&current->sighand->siglock);
- saveset = current->blocked;
- siginitset(&current->blocked, mask);
- recalc_sigpending();
- spin_unlock_irq(&current->sighand->siglock);
-
- regs->result = -EINTR;
- regs->gpr[3] = EINTR;
- regs->ccr |= 0x10000000;
- while (1) {
- current->state = TASK_INTERRUPTIBLE;
- schedule();
- if (do_signal32(&saveset, regs))
- /*
- * Returning 0 means we return to userspace via
- * ret_from_except and thus restore all user
- * registers from *regs. This is what we need
- * to do when a signal has been delivered.
- */
- return 0;
- }
-}
-
-long sys32_sigaction(int sig, struct old_sigaction32 __user *act,
- struct old_sigaction32 __user *oact)
-{
- struct k_sigaction new_ka, old_ka;
- int ret;
-
- if (sig < 0)
- sig = -sig;
-
- if (act) {
- compat_old_sigset_t mask;
- compat_uptr_t handler, restorer;
-
- if (get_user(handler, &act->sa_handler) ||
- __get_user(restorer, &act->sa_restorer) ||
- __get_user(new_ka.sa.sa_flags, &act->sa_flags) ||
- __get_user(mask, &act->sa_mask))
- return -EFAULT;
- new_ka.sa.sa_handler = compat_ptr(handler);
- new_ka.sa.sa_restorer = compat_ptr(restorer);
- siginitset(&new_ka.sa.sa_mask, mask);
- }
-
- ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
- if (!ret && oact) {
- if (put_user((long)old_ka.sa.sa_handler, &oact->sa_handler) ||
- __put_user((long)old_ka.sa.sa_restorer, &oact->sa_restorer) ||
- __put_user(old_ka.sa.sa_flags, &oact->sa_flags) ||
- __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask))
- return -EFAULT;
- }
-
- return ret;
-}
-
-
-
-/*
- * Start of RT signal support
- *
- * sigset_t is 64 bits for rt signals
- *
- * System Calls
- * sigaction sys32_rt_sigaction
- * sigpending sys32_rt_sigpending
- * sigprocmask sys32_rt_sigprocmask
- * sigreturn sys32_rt_sigreturn
- * sigqueueinfo sys32_rt_sigqueueinfo
- * sigsuspend sys32_rt_sigsuspend
- *
- * Other routines
- * setup_rt_frame32
- * copy_siginfo_to_user32
- * siginfo32to64
- */
-
-
-long sys32_rt_sigaction(int sig, const struct sigaction32 __user *act,
+#ifdef CONFIG_PPC64
+long compat_sys_rt_sigaction(int sig, const struct sigaction32 __user *act,
struct sigaction32 __user *oact, size_t sigsetsize)
{
struct k_sigaction new_ka, old_ka;
int ret;
- compat_sigset_t set32;
/* XXX: Don't preclude handling different sized sigset_t's. */
if (sigsetsize != sizeof(compat_sigset_t))
@@ -368,9 +556,7 @@ long sys32_rt_sigaction(int sig, const struct sigaction32 __user *act,
ret = get_user(handler, &act->sa_handler);
new_ka.sa.sa_handler = compat_ptr(handler);
- ret |= __copy_from_user(&set32, &act->sa_mask,
- sizeof(compat_sigset_t));
- sigset_from_compat(&new_ka.sa.sa_mask, &set32);
+ ret |= get_sigset_t(&new_ka.sa.sa_mask, &act->sa_mask);
ret |= __get_user(new_ka.sa.sa_flags, &act->sa_flags);
if (ret)
return -EFAULT;
@@ -378,10 +564,8 @@ long sys32_rt_sigaction(int sig, const struct sigaction32 __user *act,
ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
if (!ret && oact) {
- compat_from_sigset(&set32, &old_ka.sa.sa_mask);
ret = put_user((long)old_ka.sa.sa_handler, &oact->sa_handler);
- ret |= __copy_to_user(&oact->sa_mask, &set32,
- sizeof(compat_sigset_t));
+ ret |= put_sigset_t(&oact->sa_mask, &old_ka.sa.sa_mask);
ret |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
}
return ret;
@@ -394,41 +578,37 @@ long sys32_rt_sigaction(int sig, const struct sigaction32 __user *act,
* of a signed int (msr in 32-bit mode) and the register representation
* of a signed int (msr in 64-bit mode) is performed.
*/
-long sys32_rt_sigprocmask(u32 how, compat_sigset_t __user *set,
+long compat_sys_rt_sigprocmask(u32 how, compat_sigset_t __user *set,
compat_sigset_t __user *oset, size_t sigsetsize)
{
sigset_t s;
sigset_t __user *up;
- compat_sigset_t s32;
int ret;
mm_segment_t old_fs = get_fs();
if (set) {
- if (copy_from_user (&s32, set, sizeof(compat_sigset_t)))
- return -EFAULT;
- sigset_from_compat(&s, &s32);
+ if (get_sigset_t(&s, set))
+ return -EFAULT;
}
-
+
set_fs(KERNEL_DS);
/* This is valid because of the set_fs() */
up = (sigset_t __user *) &s;
ret = sys_rt_sigprocmask((int)how, set ? up : NULL, oset ? up : NULL,
- sigsetsize);
+ sigsetsize);
set_fs(old_fs);
if (ret)
return ret;
if (oset) {
- compat_from_sigset(&s32, &s);
- if (copy_to_user (oset, &s32, sizeof(compat_sigset_t)))
+ if (put_sigset_t(oset, &s))
return -EFAULT;
}
return 0;
}
-long sys32_rt_sigpending(compat_sigset_t __user *set, compat_size_t sigsetsize)
+long compat_sys_rt_sigpending(compat_sigset_t __user *set, compat_size_t sigsetsize)
{
sigset_t s;
- compat_sigset_t s32;
int ret;
mm_segment_t old_fs = get_fs();
@@ -437,8 +617,7 @@ long sys32_rt_sigpending(compat_sigset_t __user *set, compat_size_t sigsetsize)
ret = sys_rt_sigpending((sigset_t __user *) &s, sigsetsize);
set_fs(old_fs);
if (!ret) {
- compat_from_sigset(&s32, &s);
- if (copy_to_user (set, &s32, sizeof(compat_sigset_t)))
+ if (put_sigset_t(set, &s))
return -EFAULT;
}
return ret;
@@ -500,6 +679,8 @@ int copy_siginfo_to_user32(struct compat_siginfo __user *d, siginfo_t *s)
return err;
}
+#define copy_siginfo_to_user copy_siginfo_to_user32
+
/*
* Note: it is necessary to treat pid and sig as unsigned ints, with the
* corresponding cast to a signed int to insure that the proper conversion
@@ -507,12 +688,12 @@ int copy_siginfo_to_user32(struct compat_siginfo __user *d, siginfo_t *s)
* (msr in 32-bit mode) and the register representation of a signed int
* (msr in 64-bit mode) is performed.
*/
-long sys32_rt_sigqueueinfo(u32 pid, u32 sig, compat_siginfo_t __user *uinfo)
+long compat_sys_rt_sigqueueinfo(u32 pid, u32 sig, compat_siginfo_t __user *uinfo)
{
siginfo_t info;
int ret;
mm_segment_t old_fs = get_fs();
-
+
if (copy_from_user (&info, uinfo, 3*sizeof(int)) ||
copy_from_user (info._sifields._pad, uinfo->_sifields._pad, SI_PAD_SIZE32))
return -EFAULT;
@@ -522,58 +703,14 @@ long sys32_rt_sigqueueinfo(u32 pid, u32 sig, compat_siginfo_t __user *uinfo)
set_fs (old_fs);
return ret;
}
-
-int sys32_rt_sigsuspend(compat_sigset_t __user * unewset, size_t sigsetsize, int p3,
- int p4, int p6, int p7, struct pt_regs *regs)
-{
- sigset_t saveset, newset;
- compat_sigset_t s32;
-
- /* XXX: Don't preclude handling different sized sigset_t's. */
- if (sigsetsize != sizeof(sigset_t))
- return -EINVAL;
-
- if (copy_from_user(&s32, unewset, sizeof(s32)))
- return -EFAULT;
-
- /*
- * Swap the 2 words of the 64-bit sigset_t (they are stored
- * in the "wrong" endian in 32-bit user storage).
- */
- sigset_from_compat(&newset, &s32);
-
- sigdelsetmask(&newset, ~_BLOCKABLE);
- spin_lock_irq(&current->sighand->siglock);
- saveset = current->blocked;
- current->blocked = newset;
- recalc_sigpending();
- spin_unlock_irq(&current->sighand->siglock);
-
- regs->result = -EINTR;
- regs->gpr[3] = EINTR;
- regs->ccr |= 0x10000000;
- while (1) {
- current->state = TASK_INTERRUPTIBLE;
- schedule();
- if (do_signal32(&saveset, regs))
- /*
- * Returning 0 means we return to userspace via
- * ret_from_except and thus restore all user
- * registers from *regs. This is what we need
- * to do when a signal has been delivered.
- */
- return 0;
- }
-}
-
/*
* Start Alternate signal stack support
*
* System Calls
- * sigaltatck sys32_sigaltstack
+ * sigaltatck compat_sys_sigaltstack
*/
-int sys32_sigaltstack(u32 __new, u32 __old, int r5,
+int compat_sys_sigaltstack(u32 __new, u32 __old, int r5,
int r6, int r7, int r8, struct pt_regs *regs)
{
stack_32_t __user * newstack = (stack_32_t __user *)(long) __new;
@@ -615,76 +752,94 @@ int sys32_sigaltstack(u32 __new, u32 __old, int r5,
return -EFAULT;
return ret;
}
+#endif /* CONFIG_PPC64 */
/*
+ * Restore the user process's signal mask
+ */
+#ifdef CONFIG_PPC64
+extern void restore_sigmask(sigset_t *set);
+#else /* CONFIG_PPC64 */
+static void restore_sigmask(sigset_t *set)
+{
+ sigdelsetmask(set, ~_BLOCKABLE);
+ spin_lock_irq(&current->sighand->siglock);
+ current->blocked = *set;
+ recalc_sigpending();
+ spin_unlock_irq(&current->sighand->siglock);
+}
+#endif
+
+/*
* Set up a signal frame for a "real-time" signal handler
* (one which gets siginfo).
*/
-static int handle_rt_signal32(unsigned long sig, struct k_sigaction *ka,
- siginfo_t *info, sigset_t *oldset,
- struct pt_regs * regs, unsigned long newsp)
+static int handle_rt_signal(unsigned long sig, struct k_sigaction *ka,
+ siginfo_t *info, sigset_t *oldset,
+ struct pt_regs *regs, unsigned long newsp)
{
- struct rt_sigframe32 __user *rt_sf;
- struct mcontext32 __user *frame;
+ struct rt_sigframe __user *rt_sf;
+ struct mcontext __user *frame;
unsigned long origsp = newsp;
- compat_sigset_t c_oldset;
/* Set up Signal Frame */
/* Put a Real Time Context onto stack */
newsp -= sizeof(*rt_sf);
- rt_sf = (struct rt_sigframe32 __user *)newsp;
+ rt_sf = (struct rt_sigframe __user *)newsp;
/* create a stack frame for the caller of the handler */
- newsp -= __SIGNAL_FRAMESIZE32 + 16;
+ newsp -= __SIGNAL_FRAMESIZE + 16;
if (!access_ok(VERIFY_WRITE, (void __user *)newsp, origsp - newsp))
goto badframe;
- compat_from_sigset(&c_oldset, oldset);
-
/* Put the siginfo & fill in most of the ucontext */
- if (copy_siginfo_to_user32(&rt_sf->info, info)
+ if (copy_siginfo_to_user(&rt_sf->info, info)
|| __put_user(0, &rt_sf->uc.uc_flags)
|| __put_user(0, &rt_sf->uc.uc_link)
|| __put_user(current->sas_ss_sp, &rt_sf->uc.uc_stack.ss_sp)
|| __put_user(sas_ss_flags(regs->gpr[1]),
&rt_sf->uc.uc_stack.ss_flags)
|| __put_user(current->sas_ss_size, &rt_sf->uc.uc_stack.ss_size)
- || __put_user((u32)(u64)&rt_sf->uc.uc_mcontext, &rt_sf->uc.uc_regs)
- || __copy_to_user(&rt_sf->uc.uc_sigmask, &c_oldset, sizeof(c_oldset)))
+ || __put_user(to_user_ptr(&rt_sf->uc.uc_mcontext),
+ &rt_sf->uc.uc_regs)
+ || put_sigset_t(&rt_sf->uc.uc_sigmask, oldset))
goto badframe;
/* Save user registers on the stack */
frame = &rt_sf->uc.uc_mcontext;
- if (put_user(regs->gpr[1], (u32 __user *)newsp))
- goto badframe;
-
+#ifdef CONFIG_PPC64
if (vdso32_rt_sigtramp && current->thread.vdso_base) {
if (save_user_regs(regs, frame, 0))
goto badframe;
regs->link = current->thread.vdso_base + vdso32_rt_sigtramp;
- } else {
+ } else
+#endif
+ {
if (save_user_regs(regs, frame, __NR_rt_sigreturn))
goto badframe;
regs->link = (unsigned long) frame->tramp;
}
- regs->gpr[1] = (unsigned long) newsp;
+ if (put_user(regs->gpr[1], (u32 __user *)newsp))
+ goto badframe;
+ regs->gpr[1] = newsp;
regs->gpr[3] = sig;
regs->gpr[4] = (unsigned long) &rt_sf->info;
regs->gpr[5] = (unsigned long) &rt_sf->uc;
regs->gpr[6] = (unsigned long) rt_sf;
regs->nip = (unsigned long) ka->sa.sa_handler;
regs->trap = 0;
+#ifdef CONFIG_PPC64
regs->result = 0;
if (test_thread_flag(TIF_SINGLESTEP))
ptrace_notify(SIGTRAP);
-
+#endif
return 1;
badframe:
-#if DEBUG_SIG
+#ifdef DEBUG_SIG
printk("badframe in handle_rt_signal, regs=%p frame=%p newsp=%lx\n",
regs, frame, newsp);
#endif
@@ -692,46 +847,50 @@ badframe:
return 0;
}
-static long do_setcontext32(struct ucontext32 __user *ucp, struct pt_regs *regs, int sig)
+static int do_setcontext(struct ucontext __user *ucp, struct pt_regs *regs, int sig)
{
- compat_sigset_t c_set;
sigset_t set;
- u32 mcp;
+ struct mcontext __user *mcp;
+
+ if (get_sigset_t(&set, &ucp->uc_sigmask))
+ return -EFAULT;
+#ifdef CONFIG_PPC64
+ {
+ u32 cmcp;
- if (__copy_from_user(&c_set, &ucp->uc_sigmask, sizeof(c_set))
- || __get_user(mcp, &ucp->uc_regs))
+ if (__get_user(cmcp, &ucp->uc_regs))
+ return -EFAULT;
+ mcp = (struct mcontext __user *)(u64)cmcp;
+ }
+#else
+ if (__get_user(mcp, &ucp->uc_regs))
return -EFAULT;
- sigset_from_compat(&set, &c_set);
+#endif
restore_sigmask(&set);
- if (restore_user_regs(regs, (struct mcontext32 __user *)(u64)mcp, sig))
+ if (restore_user_regs(regs, mcp, sig))
return -EFAULT;
return 0;
}
-/*
- * Handle {get,set,swap}_context operations for 32 bits processes
- */
-
-long sys32_swapcontext(struct ucontext32 __user *old_ctx,
- struct ucontext32 __user *new_ctx,
+long sys_swapcontext(struct ucontext __user *old_ctx,
+ struct ucontext __user *new_ctx,
int ctx_size, int r6, int r7, int r8, struct pt_regs *regs)
{
unsigned char tmp;
- compat_sigset_t c_set;
/* Context size is for future use. Right now, we only make sure
* we are passed something we understand
*/
- if (ctx_size < sizeof(struct ucontext32))
+ if (ctx_size < sizeof(struct ucontext))
return -EINVAL;
if (old_ctx != NULL) {
- compat_from_sigset(&c_set, &current->blocked);
if (!access_ok(VERIFY_WRITE, old_ctx, sizeof(*old_ctx))
|| save_user_regs(regs, &old_ctx->uc_mcontext, 0)
- || __copy_to_user(&old_ctx->uc_sigmask, &c_set, sizeof(c_set))
- || __put_user((u32)(u64)&old_ctx->uc_mcontext, &old_ctx->uc_regs))
+ || put_sigset_t(&old_ctx->uc_sigmask, &current->blocked)
+ || __put_user(to_user_ptr(&old_ctx->uc_mcontext),
+ &old_ctx->uc_regs))
return -EFAULT;
}
if (new_ctx == NULL)
@@ -752,27 +911,26 @@ long sys32_swapcontext(struct ucontext32 __user *old_ctx,
* or if another thread unmaps the region containing the context.
* We kill the task with a SIGSEGV in this situation.
*/
- if (do_setcontext32(new_ctx, regs, 0))
+ if (do_setcontext(new_ctx, regs, 0))
do_exit(SIGSEGV);
-
+ sigreturn_exit(regs);
+ /* doesn't actually return back to here */
return 0;
}
-long sys32_rt_sigreturn(int r3, int r4, int r5, int r6, int r7, int r8,
+long sys_rt_sigreturn(int r3, int r4, int r5, int r6, int r7, int r8,
struct pt_regs *regs)
{
- struct rt_sigframe32 __user *rt_sf;
- int ret;
-
+ struct rt_sigframe __user *rt_sf;
/* Always make any pending restarted system calls return -EINTR */
current_thread_info()->restart_block.fn = do_no_restart_syscall;
- rt_sf = (struct rt_sigframe32 __user *)
- (regs->gpr[1] + __SIGNAL_FRAMESIZE32 + 16);
+ rt_sf = (struct rt_sigframe __user *)
+ (regs->gpr[1] + __SIGNAL_FRAMESIZE + 16);
if (!access_ok(VERIFY_READ, rt_sf, sizeof(*rt_sf)))
goto bad;
- if (do_setcontext32(&rt_sf->uc, regs, 1))
+ if (do_setcontext(&rt_sf->uc, regs, 1))
goto bad;
/*
@@ -781,62 +939,165 @@ long sys32_rt_sigreturn(int r3, int r4, int r5, int r6, int r7, int r8,
* signal return. But other architectures do this and we have
* always done it up until now so it is probably better not to
* change it. -- paulus
- * We use the sys32_ version that does the 32/64 bits conversion
+ */
+#ifdef CONFIG_PPC64
+ /*
+ * We use the compat_sys_ version that does the 32/64 bits conversion
* and takes userland pointer directly. What about error checking ?
* nobody does any...
*/
- sys32_sigaltstack((u32)(u64)&rt_sf->uc.uc_stack, 0, 0, 0, 0, 0, regs);
-
- ret = regs->result;
-
- return ret;
+ compat_sys_sigaltstack((u32)(u64)&rt_sf->uc.uc_stack, 0, 0, 0, 0, 0, regs);
+ return (int)regs->result;
+#else
+ do_sigaltstack(&rt_sf->uc.uc_stack, NULL, regs->gpr[1]);
+ sigreturn_exit(regs); /* doesn't return here */
+ return 0;
+#endif
bad:
force_sig(SIGSEGV, current);
return 0;
}
+#ifdef CONFIG_PPC32
+int sys_debug_setcontext(struct ucontext __user *ctx,
+ int ndbg, struct sig_dbg_op __user *dbg,
+ int r6, int r7, int r8,
+ struct pt_regs *regs)
+{
+ struct sig_dbg_op op;
+ int i;
+ unsigned long new_msr = regs->msr;
+#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
+ unsigned long new_dbcr0 = current->thread.dbcr0;
+#endif
+
+ for (i=0; i<ndbg; i++) {
+ if (__copy_from_user(&op, dbg, sizeof(op)))
+ return -EFAULT;
+ switch (op.dbg_type) {
+ case SIG_DBG_SINGLE_STEPPING:
+#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
+ if (op.dbg_value) {
+ new_msr |= MSR_DE;
+ new_dbcr0 |= (DBCR0_IDM | DBCR0_IC);
+ } else {
+ new_msr &= ~MSR_DE;
+ new_dbcr0 &= ~(DBCR0_IDM | DBCR0_IC);
+ }
+#else
+ if (op.dbg_value)
+ new_msr |= MSR_SE;
+ else
+ new_msr &= ~MSR_SE;
+#endif
+ break;
+ case SIG_DBG_BRANCH_TRACING:
+#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
+ return -EINVAL;
+#else
+ if (op.dbg_value)
+ new_msr |= MSR_BE;
+ else
+ new_msr &= ~MSR_BE;
+#endif
+ break;
+
+ default:
+ return -EINVAL;
+ }
+ }
+
+ /* We wait until here to actually install the values in the
+ registers so if we fail in the above loop, it will not
+ affect the contents of these registers. After this point,
+ failure is a problem, anyway, and it's very unlikely unless
+ the user is really doing something wrong. */
+ regs->msr = new_msr;
+#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
+ current->thread.dbcr0 = new_dbcr0;
+#endif
+
+ /*
+ * If we get a fault copying the context into the kernel's
+ * image of the user's registers, we can't just return -EFAULT
+ * because the user's registers will be corrupted. For instance
+ * the NIP value may have been updated but not some of the
+ * other registers. Given that we have done the access_ok
+ * and successfully read the first and last bytes of the region
+ * above, this should only happen in an out-of-memory situation
+ * or if another thread unmaps the region containing the context.
+ * We kill the task with a SIGSEGV in this situation.
+ */
+ if (do_setcontext(ctx, regs, 1)) {
+ force_sig(SIGSEGV, current);
+ goto out;
+ }
+
+ /*
+ * It's not clear whether or why it is desirable to save the
+ * sigaltstack setting on signal delivery and restore it on
+ * signal return. But other architectures do this and we have
+ * always done it up until now so it is probably better not to
+ * change it. -- paulus
+ */
+ do_sigaltstack(&ctx->uc_stack, NULL, regs->gpr[1]);
+
+ sigreturn_exit(regs);
+ /* doesn't actually return back to here */
+
+ out:
+ return 0;
+}
+#endif
/*
* OK, we're invoking a handler
*/
-static int handle_signal32(unsigned long sig, struct k_sigaction *ka,
- siginfo_t *info, sigset_t *oldset,
- struct pt_regs * regs, unsigned long newsp)
+static int handle_signal(unsigned long sig, struct k_sigaction *ka,
+ siginfo_t *info, sigset_t *oldset, struct pt_regs *regs,
+ unsigned long newsp)
{
- struct sigcontext32 __user *sc;
- struct sigregs32 __user *frame;
+ struct sigcontext __user *sc;
+ struct sigregs __user *frame;
unsigned long origsp = newsp;
/* Set up Signal Frame */
- newsp -= sizeof(struct sigregs32);
- frame = (struct sigregs32 __user *) newsp;
+ newsp -= sizeof(struct sigregs);
+ frame = (struct sigregs __user *) newsp;
/* Put a sigcontext on the stack */
newsp -= sizeof(*sc);
- sc = (struct sigcontext32 __user *) newsp;
+ sc = (struct sigcontext __user *) newsp;
/* create a stack frame for the caller of the handler */
- newsp -= __SIGNAL_FRAMESIZE32;
+ newsp -= __SIGNAL_FRAMESIZE;
if (!access_ok(VERIFY_WRITE, (void __user *) newsp, origsp - newsp))
goto badframe;
#if _NSIG != 64
-#error "Please adjust handle_signal32()"
+#error "Please adjust handle_signal()"
#endif
- if (__put_user((u32)(u64)ka->sa.sa_handler, &sc->handler)
+ if (__put_user(to_user_ptr(ka->sa.sa_handler), &sc->handler)
|| __put_user(oldset->sig[0], &sc->oldmask)
+#ifdef CONFIG_PPC64
|| __put_user((oldset->sig[0] >> 32), &sc->_unused[3])
- || __put_user((u32)(u64)frame, &sc->regs)
+#else
+ || __put_user(oldset->sig[1], &sc->_unused[3])
+#endif
+ || __put_user(to_user_ptr(frame), &sc->regs)
|| __put_user(sig, &sc->signal))
goto badframe;
+#ifdef CONFIG_PPC64
if (vdso32_sigtramp && current->thread.vdso_base) {
if (save_user_regs(regs, &frame->mctx, 0))
goto badframe;
regs->link = current->thread.vdso_base + vdso32_sigtramp;
- } else {
+ } else
+#endif
+ {
if (save_user_regs(regs, &frame->mctx, __NR_sigreturn))
goto badframe;
regs->link = (unsigned long) frame->mctx.tramp;
@@ -844,22 +1105,24 @@ static int handle_signal32(unsigned long sig, struct k_sigaction *ka,
if (put_user(regs->gpr[1], (u32 __user *)newsp))
goto badframe;
- regs->gpr[1] = (unsigned long) newsp;
+ regs->gpr[1] = newsp;
regs->gpr[3] = sig;
regs->gpr[4] = (unsigned long) sc;
regs->nip = (unsigned long) ka->sa.sa_handler;
regs->trap = 0;
+#ifdef CONFIG_PPC64
regs->result = 0;
if (test_thread_flag(TIF_SINGLESTEP))
ptrace_notify(SIGTRAP);
+#endif
return 1;
badframe:
-#if DEBUG_SIG
- printk("badframe in handle_signal, regs=%p frame=%x newsp=%x\n",
- regs, frame, *newspp);
+#ifdef DEBUG_SIG
+ printk("badframe in handle_signal, regs=%p frame=%p newsp=%lx\n",
+ regs, frame, newsp);
#endif
force_sigsegv(sig, current);
return 0;
@@ -868,65 +1131,69 @@ badframe:
/*
* Do a signal return; undo the signal stack.
*/
-long sys32_sigreturn(int r3, int r4, int r5, int r6, int r7, int r8,
+long sys_sigreturn(int r3, int r4, int r5, int r6, int r7, int r8,
struct pt_regs *regs)
{
- struct sigcontext32 __user *sc;
- struct sigcontext32 sigctx;
- struct mcontext32 __user *sr;
+ struct sigcontext __user *sc;
+ struct sigcontext sigctx;
+ struct mcontext __user *sr;
sigset_t set;
- int ret;
/* Always make any pending restarted system calls return -EINTR */
current_thread_info()->restart_block.fn = do_no_restart_syscall;
- sc = (struct sigcontext32 __user *)(regs->gpr[1] + __SIGNAL_FRAMESIZE32);
+ sc = (struct sigcontext __user *)(regs->gpr[1] + __SIGNAL_FRAMESIZE);
if (copy_from_user(&sigctx, sc, sizeof(sigctx)))
goto badframe;
+#ifdef CONFIG_PPC64
/*
* Note that PPC32 puts the upper 32 bits of the sigmask in the
* unused part of the signal stackframe
*/
set.sig[0] = sigctx.oldmask + ((long)(sigctx._unused[3]) << 32);
+#else
+ set.sig[0] = sigctx.oldmask;
+ set.sig[1] = sigctx._unused[3];
+#endif
restore_sigmask(&set);
- sr = (struct mcontext32 __user *)(u64)sigctx.regs;
+ sr = (struct mcontext __user *)from_user_ptr(sigctx.regs);
if (!access_ok(VERIFY_READ, sr, sizeof(*sr))
|| restore_user_regs(regs, sr, 1))
goto badframe;
- ret = regs->result;
- return ret;
+#ifdef CONFIG_PPC64
+ return (int)regs->result;
+#else
+ sigreturn_exit(regs); /* doesn't return */
+ return 0;
+#endif
badframe:
force_sig(SIGSEGV, current);
return 0;
}
-
-
-/*
- * Start of do_signal32 routine
- *
- * This routine gets control when a pending signal needs to be processed
- * in the 32 bit target thread -
- *
- * It handles both rt and non-rt signals
- */
-
/*
* Note that 'init' is a special process: it doesn't get signals it doesn't
* want to handle. Thus you cannot kill init even with a SIGKILL even by
* mistake.
*/
-
-int do_signal32(sigset_t *oldset, struct pt_regs *regs)
+int do_signal(sigset_t *oldset, struct pt_regs *regs)
{
siginfo_t info;
+ struct k_sigaction ka;
unsigned int frame, newsp;
int signr, ret;
- struct k_sigaction ka;
+
+#ifdef CONFIG_PPC32
+ if (try_to_freeze()) {
+ signr = 0;
+ if (!signal_pending(current))
+ goto no_signal;
+ }
+#endif
if (!oldset)
oldset = &current->blocked;
@@ -934,7 +1201,9 @@ int do_signal32(sigset_t *oldset, struct pt_regs *regs)
newsp = frame = 0;
signr = get_signal_to_deliver(&info, &ka, regs, NULL);
-
+#ifdef CONFIG_PPC32
+no_signal:
+#endif
if (TRAP(regs) == 0x0C00 /* System Call! */
&& regs->ccr & 0x10000000 /* error signalled */
&& ((ret = regs->gpr[3]) == ERESTARTSYS
@@ -964,12 +1233,13 @@ int do_signal32(sigset_t *oldset, struct pt_regs *regs)
return 0; /* no signals delivered */
if ((ka.sa.sa_flags & SA_ONSTACK) && current->sas_ss_size
- && (!on_sig_stack(regs->gpr[1])))
- newsp = (current->sas_ss_sp + current->sas_ss_size);
+ && !on_sig_stack(regs->gpr[1]))
+ newsp = current->sas_ss_sp + current->sas_ss_size;
else
newsp = regs->gpr[1];
newsp &= ~0xfUL;
+#ifdef CONFIG_PPC64
/*
* Reenable the DABR before delivering the signal to
* user space. The DABR will have been cleared if it
@@ -977,12 +1247,13 @@ int do_signal32(sigset_t *oldset, struct pt_regs *regs)
*/
if (current->thread.dabr)
set_dabr(current->thread.dabr);
+#endif
/* Whee! Actually deliver the signal. */
if (ka.sa.sa_flags & SA_SIGINFO)
- ret = handle_rt_signal32(signr, &ka, &info, oldset, regs, newsp);
+ ret = handle_rt_signal(signr, &ka, &info, oldset, regs, newsp);
else
- ret = handle_signal32(signr, &ka, &info, oldset, regs, newsp);
+ ret = handle_signal(signr, &ka, &info, oldset, regs, newsp);
if (ret) {
spin_lock_irq(&current->sighand->siglock);
diff --git a/arch/ppc64/kernel/signal.c b/arch/powerpc/kernel/signal_64.c
index 347112cca3c0..58194e150711 100644
--- a/arch/ppc64/kernel/signal.c
+++ b/arch/powerpc/kernel/signal_64.c
@@ -33,7 +33,6 @@
#include <asm/ucontext.h>
#include <asm/uaccess.h>
#include <asm/pgtable.h>
-#include <asm/ppcdebug.h>
#include <asm/unistd.h>
#include <asm/cacheflush.h>
#include <asm/vdso.h>
@@ -133,7 +132,7 @@ static long setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs,
flush_fp_to_thread(current);
/* Make sure signal doesn't get spurrious FP exceptions */
- current->thread.fpscr = 0;
+ current->thread.fpscr.val = 0;
#ifdef CONFIG_ALTIVEC
err |= __put_user(v_regs, &sc->v_regs);
diff --git a/arch/ppc64/kernel/smp-tbsync.c b/arch/powerpc/kernel/smp-tbsync.c
index 7d8ec9996b3e..9adef3bddad4 100644
--- a/arch/ppc64/kernel/smp-tbsync.c
+++ b/arch/powerpc/kernel/smp-tbsync.c
@@ -22,11 +22,11 @@ enum {
};
static struct {
- volatile long tb;
- volatile long mark;
+ volatile u64 tb;
+ volatile u64 mark;
volatile int cmd;
volatile int handshake;
- int filler[3];
+ int filler[2];
volatile int ack;
int filler2[7];
@@ -36,89 +36,80 @@ static struct {
static volatile int running;
-static void __devinit
-enter_contest( long mark, long add )
+static void __devinit enter_contest(u64 mark, long add)
{
- while( (long)(mftb() - mark) < 0 )
+ while (get_tb() < mark)
tbsync->race_result = add;
}
-void __devinit
-smp_generic_take_timebase( void )
+void __devinit smp_generic_take_timebase(void)
{
int cmd;
- long tb;
+ u64 tb;
local_irq_disable();
- while( !running )
- ;
+ while (!running)
+ barrier();
rmb();
- for( ;; ) {
+ for (;;) {
tbsync->ack = 1;
- while( !tbsync->handshake )
- ;
+ while (!tbsync->handshake)
+ barrier();
rmb();
cmd = tbsync->cmd;
tb = tbsync->tb;
+ mb();
tbsync->ack = 0;
- if( cmd == kExit )
- return;
-
- if( cmd == kSetAndTest ) {
- while( tbsync->handshake )
- ;
- asm volatile ("mttbl %0" :: "r" (tb & 0xfffffffful) );
- asm volatile ("mttbu %0" :: "r" (tb >> 32) );
- } else {
- while( tbsync->handshake )
- ;
- }
- enter_contest( tbsync->mark, -1 );
+ if (cmd == kExit)
+ break;
+
+ while (tbsync->handshake)
+ barrier();
+ if (cmd == kSetAndTest)
+ set_tb(tb >> 32, tb & 0xfffffffful);
+ enter_contest(tbsync->mark, -1);
}
local_irq_enable();
}
-static int __devinit
-start_contest( int cmd, long offset, long num )
+static int __devinit start_contest(int cmd, long offset, int num)
{
int i, score=0;
- long tb, mark;
+ u64 tb;
+ long mark;
tbsync->cmd = cmd;
local_irq_disable();
- for( i=-3; i<num; ) {
- tb = (long)mftb() + 400;
+ for (i = -3; i < num; ) {
+ tb = get_tb() + 400;
tbsync->tb = tb + offset;
tbsync->mark = mark = tb + 400;
wmb();
tbsync->handshake = 1;
- while( tbsync->ack )
- ;
+ while (tbsync->ack)
+ barrier();
- while( (long)(mftb() - tb) <= 0 )
- ;
+ while (get_tb() <= tb)
+ barrier();
tbsync->handshake = 0;
- enter_contest( mark, 1 );
+ enter_contest(mark, 1);
- while( !tbsync->ack )
- ;
+ while (!tbsync->ack)
+ barrier();
- if ((tbsync->tb ^ (long)mftb()) & 0x8000000000000000ul)
- continue;
- if( i++ > 0 )
+ if (i++ > 0)
score += tbsync->race_result;
}
local_irq_enable();
return score;
}
-void __devinit
-smp_generic_give_timebase( void )
+void __devinit smp_generic_give_timebase(void)
{
int i, score, score2, old, min=0, max=5000, offset=1000;
@@ -130,14 +121,14 @@ smp_generic_give_timebase( void )
mb();
running = 1;
- while( !tbsync->ack )
- ;
+ while (!tbsync->ack)
+ barrier();
printk("Got ack\n");
/* binary search */
- for( old=-1 ; old != offset ; offset=(min+max)/2 ) {
- score = start_contest( kSetAndTest, offset, NUM_ITER );
+ for (old = -1; old != offset ; offset = (min+max) / 2) {
+ score = start_contest(kSetAndTest, offset, NUM_ITER);
printk("score %d, offset %d\n", score, offset );
@@ -147,21 +138,22 @@ smp_generic_give_timebase( void )
min = offset;
old = offset;
}
- score = start_contest( kSetAndTest, min, NUM_ITER );
- score2 = start_contest( kSetAndTest, max, NUM_ITER );
+ score = start_contest(kSetAndTest, min, NUM_ITER);
+ score2 = start_contest(kSetAndTest, max, NUM_ITER);
- printk( "Min %d (score %d), Max %d (score %d)\n", min, score, max, score2 );
- score = abs( score );
- score2 = abs( score2 );
+ printk("Min %d (score %d), Max %d (score %d)\n",
+ min, score, max, score2);
+ score = abs(score);
+ score2 = abs(score2);
offset = (score < score2) ? min : max;
/* guard against inaccurate mttb */
- for( i=0; i<10; i++ ) {
- start_contest( kSetAndTest, offset, NUM_ITER/10 );
+ for (i = 0; i < 10; i++) {
+ start_contest(kSetAndTest, offset, NUM_ITER/10);
- if( (score2=start_contest(kTest, offset, NUM_ITER)) < 0 )
+ if ((score2 = start_contest(kTest, offset, NUM_ITER)) < 0)
score2 = -score2;
- if( score2 <= score || score2 < 20 )
+ if (score2 <= score || score2 < 20)
break;
}
printk("Final offset: %d (%d/%d)\n", offset, score2, NUM_ITER );
@@ -170,10 +162,10 @@ smp_generic_give_timebase( void )
tbsync->cmd = kExit;
wmb();
tbsync->handshake = 1;
- while( tbsync->ack )
- ;
+ while (tbsync->ack)
+ barrier();
tbsync->handshake = 0;
- kfree( tbsync );
+ kfree(tbsync);
tbsync = NULL;
running = 0;
}
diff --git a/arch/ppc64/kernel/smp.c b/arch/powerpc/kernel/smp.c
index 793b562da653..e28a139c29d0 100644
--- a/arch/ppc64/kernel/smp.c
+++ b/arch/powerpc/kernel/smp.c
@@ -39,14 +39,18 @@
#include <asm/pgtable.h>
#include <asm/prom.h>
#include <asm/smp.h>
-#include <asm/paca.h>
#include <asm/time.h>
#include <asm/machdep.h>
#include <asm/cputable.h>
#include <asm/system.h>
-#include <asm/abs_addr.h>
+#include <asm/mpic.h>
+#include <asm/systemcfg.h>
+#ifdef CONFIG_PPC64
+#include <asm/paca.h>
+#endif
-#include "mpic.h"
+int smp_hw_index[NR_CPUS];
+struct thread_info *secondary_ti;
#ifdef DEBUG
#define DBG(fmt...) udbg_printf(fmt)
@@ -61,6 +65,7 @@ cpumask_t cpu_sibling_map[NR_CPUS] = { [0 ... NR_CPUS-1] = CPU_MASK_NONE };
EXPORT_SYMBOL(cpu_online_map);
EXPORT_SYMBOL(cpu_possible_map);
+/* SMP operations for this machine */
struct smp_ops_t *smp_ops;
static volatile unsigned int cpu_callin_map[NR_CPUS];
@@ -70,28 +75,6 @@ void smp_call_function_interrupt(void);
int smt_enabled_at_boot = 1;
#ifdef CONFIG_MPIC
-void smp_mpic_message_pass(int target, int msg)
-{
- /* make sure we're sending something that translates to an IPI */
- if ( msg > 0x3 ){
- printk("SMP %d: smp_message_pass: unknown msg %d\n",
- smp_processor_id(), msg);
- return;
- }
- switch ( target )
- {
- case MSG_ALL:
- mpic_send_ipi(msg, 0xffffffff);
- break;
- case MSG_ALL_BUT_SELF:
- mpic_send_ipi(msg, 0xffffffff & ~(1 << smp_processor_id()));
- break;
- default:
- mpic_send_ipi(msg, 1 << target);
- break;
- }
-}
-
int __init smp_mpic_probe(void)
{
int nr_cpus;
@@ -112,7 +95,9 @@ void __devinit smp_mpic_setup_cpu(int cpu)
{
mpic_setup_this_cpu();
}
+#endif /* CONFIG_MPIC */
+#ifdef CONFIG_PPC64
void __devinit smp_generic_kick_cpu(int nr)
{
BUG_ON(nr < 0 || nr >= NR_CPUS);
@@ -125,23 +110,7 @@ void __devinit smp_generic_kick_cpu(int nr)
paca[nr].cpu_start = 1;
smp_mb();
}
-
-#endif /* CONFIG_MPIC */
-
-static void __init smp_space_timers(unsigned int max_cpus)
-{
- int i;
- unsigned long offset = tb_ticks_per_jiffy / max_cpus;
- unsigned long previous_tb = paca[boot_cpuid].next_jiffy_update_tb;
-
- for_each_cpu(i) {
- if (i != boot_cpuid) {
- paca[i].next_jiffy_update_tb =
- previous_tb + offset;
- previous_tb = paca[i].next_jiffy_update_tb;
- }
- }
-}
+#endif
void smp_message_recv(int msg, struct pt_regs *regs)
{
@@ -149,15 +118,10 @@ void smp_message_recv(int msg, struct pt_regs *regs)
case PPC_MSG_CALL_FUNCTION:
smp_call_function_interrupt();
break;
- case PPC_MSG_RESCHEDULE:
+ case PPC_MSG_RESCHEDULE:
/* XXX Do we have to do this? */
set_need_resched();
break;
-#if 0
- case PPC_MSG_MIGRATE_TASK:
- /* spare */
- break;
-#endif
#ifdef CONFIG_DEBUGGER
case PPC_MSG_DEBUGGER_BREAK:
debugger_ipi(regs);
@@ -209,8 +173,8 @@ static struct call_data_struct {
int wait;
} *call_data;
-/* delay of at least 8 seconds on 1GHz cpu */
-#define SMP_CALL_TIMEOUT (1UL << (30 + 3))
+/* delay of at least 8 seconds */
+#define SMP_CALL_TIMEOUT 8
/*
* This function sends a 'generic call function' IPI to all other CPUs
@@ -232,7 +196,7 @@ int smp_call_function (void (*func) (void *info), void *info, int nonatomic,
{
struct call_data_struct data;
int ret = -1, cpus;
- unsigned long timeout;
+ u64 timeout;
/* Can deadlock when called with interrupts disabled */
WARN_ON(irqs_disabled());
@@ -258,11 +222,12 @@ int smp_call_function (void (*func) (void *info), void *info, int nonatomic,
/* Send a message to all other CPUs and wait for them to respond */
smp_ops->message_pass(MSG_ALL_BUT_SELF, PPC_MSG_CALL_FUNCTION);
+ timeout = get_tb() + (u64) SMP_CALL_TIMEOUT * tb_ticks_per_sec;
+
/* Wait for response */
- timeout = SMP_CALL_TIMEOUT;
while (atomic_read(&data.started) != cpus) {
HMT_low();
- if (--timeout == 0) {
+ if (get_tb() >= timeout) {
printk("smp_call_function on cpu %d: other cpus not "
"responding (%d)\n", smp_processor_id(),
atomic_read(&data.started));
@@ -272,10 +237,9 @@ int smp_call_function (void (*func) (void *info), void *info, int nonatomic,
}
if (wait) {
- timeout = SMP_CALL_TIMEOUT;
while (atomic_read(&data.finished) != cpus) {
HMT_low();
- if (--timeout == 0) {
+ if (get_tb() >= timeout) {
printk("smp_call_function on cpu %d: other "
"cpus not finishing (%d/%d)\n",
smp_processor_id(),
@@ -289,7 +253,7 @@ int smp_call_function (void (*func) (void *info), void *info, int nonatomic,
ret = 0;
-out:
+ out:
call_data = NULL;
HMT_medium();
spin_unlock(&call_lock);
@@ -351,8 +315,11 @@ static void __init smp_create_idle(unsigned int cpu)
p = fork_idle(cpu);
if (IS_ERR(p))
panic("failed fork for CPU %u: %li", cpu, PTR_ERR(p));
+#ifdef CONFIG_PPC64
paca[cpu].__current = p;
+#endif
current_set[cpu] = p->thread_info;
+ p->thread_info->cpu = cpu;
}
void __init smp_prepare_cpus(unsigned int max_cpus)
@@ -371,18 +338,6 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
smp_store_cpu_info(boot_cpuid);
cpu_callin_map[boot_cpuid] = 1;
-#ifndef CONFIG_PPC_ISERIES
- paca[boot_cpuid].next_jiffy_update_tb = tb_last_stamp = get_tb();
-
- /*
- * Should update do_gtod.stamp_xsec.
- * For now we leave it which means the time can be some
- * number of msecs off until someone does a settimeofday()
- */
- do_gtod.varp->tb_orig_stamp = tb_last_stamp;
- systemcfg->tb_orig_stamp = tb_last_stamp;
-#endif
-
max_cpus = smp_ops->probe();
smp_space_timers(max_cpus);
@@ -397,8 +352,9 @@ void __devinit smp_prepare_boot_cpu(void)
BUG_ON(smp_processor_id() != boot_cpuid);
cpu_set(boot_cpuid, cpu_online_map);
-
+#ifdef CONFIG_PPC64
paca[boot_cpuid].__current = current;
+#endif
current_set[boot_cpuid] = current->thread_info;
}
@@ -413,9 +369,11 @@ int generic_cpu_disable(void)
if (cpu == boot_cpuid)
return -EBUSY;
- systemcfg->processorCount--;
cpu_clear(cpu, cpu_online_map);
+#ifdef CONFIG_PPC64
+ _systemcfg->processorCount--;
fixup_irqs(cpu_online_map);
+#endif
return 0;
}
@@ -433,9 +391,11 @@ int generic_cpu_enable(unsigned int cpu)
while (!cpu_online(cpu))
cpu_relax();
+#ifdef CONFIG_PPC64
fixup_irqs(cpu_online_map);
/* counter the irq disable in fixup_irqs */
local_irq_enable();
+#endif
return 0;
}
@@ -464,7 +424,9 @@ void generic_mach_cpu_die(void)
while (__get_cpu_var(cpu_state) != CPU_UP_PREPARE)
cpu_relax();
+#ifdef CONFIG_PPC64
flush_tlb_pending();
+#endif
cpu_set(cpu, cpu_online_map);
local_irq_enable();
}
@@ -482,13 +444,16 @@ int __devinit __cpu_up(unsigned int cpu)
{
int c;
+ secondary_ti = current_set[cpu];
if (!cpu_enable(cpu))
return 0;
if (smp_ops->cpu_bootable && !smp_ops->cpu_bootable(cpu))
return -EINVAL;
+#ifdef CONFIG_PPC64
paca[cpu].default_decr = tb_ticks_per_jiffy;
+#endif
/* Make sure callin-map entry is 0 (can be leftover a CPU
* hotplug
@@ -551,7 +516,8 @@ int __devinit start_secondary(void *unused)
current->active_mm = &init_mm;
smp_store_cpu_info(cpu);
- set_dec(paca[cpu].default_decr);
+ set_dec(tb_ticks_per_jiffy);
+ preempt_disable();
cpu_callin_map[cpu] = 1;
smp_ops->setup_cpu(cpu);
diff --git a/arch/ppc64/kernel/sys_ppc32.c b/arch/powerpc/kernel/sys_ppc32.c
index e93c13458910..9c921d1c4084 100644
--- a/arch/ppc64/kernel/sys_ppc32.c
+++ b/arch/powerpc/kernel/sys_ppc32.c
@@ -52,9 +52,7 @@
#include <asm/semaphore.h>
#include <asm/time.h>
#include <asm/mmu_context.h>
-#include <asm/systemcfg.h>
-
-#include "pci.h"
+#include <asm/ppc-pci.h>
/* readdir & getdents */
#define NAME_OFFSET(de) ((int) ((de)->d_name - (char __user *) (de)))
@@ -114,96 +112,6 @@ out:
return error;
}
-struct linux_dirent32 {
- u32 d_ino;
- u32 d_off;
- unsigned short d_reclen;
- char d_name[1];
-};
-
-struct getdents_callback32 {
- struct linux_dirent32 __user * current_dir;
- struct linux_dirent32 __user * previous;
- int count;
- int error;
-};
-
-static int filldir(void * __buf, const char * name, int namlen, off_t offset,
- ino_t ino, unsigned int d_type)
-{
- struct linux_dirent32 __user * dirent;
- struct getdents_callback32 * buf = (struct getdents_callback32 *) __buf;
- int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 2);
-
- buf->error = -EINVAL; /* only used if we fail.. */
- if (reclen > buf->count)
- return -EINVAL;
- dirent = buf->previous;
- if (dirent) {
- if (__put_user(offset, &dirent->d_off))
- goto efault;
- }
- dirent = buf->current_dir;
- if (__put_user(ino, &dirent->d_ino))
- goto efault;
- if (__put_user(reclen, &dirent->d_reclen))
- goto efault;
- if (copy_to_user(dirent->d_name, name, namlen))
- goto efault;
- if (__put_user(0, dirent->d_name + namlen))
- goto efault;
- if (__put_user(d_type, (char __user *) dirent + reclen - 1))
- goto efault;
- buf->previous = dirent;
- dirent = (void __user *)dirent + reclen;
- buf->current_dir = dirent;
- buf->count -= reclen;
- return 0;
-efault:
- buf->error = -EFAULT;
- return -EFAULT;
-}
-
-asmlinkage long sys32_getdents(unsigned int fd, struct linux_dirent32 __user *dirent,
- unsigned int count)
-{
- struct file * file;
- struct linux_dirent32 __user * lastdirent;
- struct getdents_callback32 buf;
- int error;
-
- error = -EFAULT;
- if (!access_ok(VERIFY_WRITE, dirent, count))
- goto out;
-
- error = -EBADF;
- file = fget(fd);
- if (!file)
- goto out;
-
- buf.current_dir = dirent;
- buf.previous = NULL;
- buf.count = count;
- buf.error = 0;
-
- error = vfs_readdir(file, (filldir_t)filldir, &buf);
- if (error < 0)
- goto out_putf;
- error = buf.error;
- lastdirent = buf.previous;
- if (lastdirent) {
- if (put_user(file->f_pos, &lastdirent->d_off))
- error = -EFAULT;
- else
- error = count - buf.count;
- }
-
-out_putf:
- fput(file);
-out:
- return error;
-}
-
asmlinkage long ppc32_select(u32 n, compat_ulong_t __user *inp,
compat_ulong_t __user *outp, compat_ulong_t __user *exp,
compat_uptr_t tvp_x)
@@ -248,7 +156,7 @@ int cp_compat_stat(struct kstat *stat, struct compat_stat __user *statbuf)
* proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
* and the register representation of a signed int (msr in 64-bit mode) is performed.
*/
-asmlinkage long sys32_sysfs(u32 option, u32 arg1, u32 arg2)
+asmlinkage long compat_sys_sysfs(u32 option, u32 arg1, u32 arg2)
{
return sys_sysfs((int)option, arg1, arg2);
}
@@ -270,7 +178,7 @@ struct timex32 {
extern int do_adjtimex(struct timex *);
extern void ppc_adjtimex(void);
-asmlinkage long sys32_adjtimex(struct timex32 __user *utp)
+asmlinkage long compat_sys_adjtimex(struct timex32 __user *utp)
{
struct timex txc;
int ret;
@@ -329,7 +237,7 @@ asmlinkage long sys32_adjtimex(struct timex32 __user *utp)
return ret;
}
-asmlinkage long sys32_pause(void)
+asmlinkage long compat_sys_pause(void)
{
current->state = TASK_INTERRUPTIBLE;
schedule();
@@ -375,7 +283,7 @@ struct sysinfo32 {
char _f[20-2*sizeof(int)-sizeof(int)];
};
-asmlinkage long sys32_sysinfo(struct sysinfo32 __user *info)
+asmlinkage long compat_sys_sysinfo(struct sysinfo32 __user *info)
{
struct sysinfo s;
int ret, err;
@@ -432,7 +340,7 @@ asmlinkage long sys32_sysinfo(struct sysinfo32 __user *info)
sorts of things, like timeval and itimerval. */
extern struct timezone sys_tz;
-asmlinkage long sys32_gettimeofday(struct compat_timeval __user *tv, struct timezone __user *tz)
+asmlinkage long compat_sys_gettimeofday(struct compat_timeval __user *tv, struct timezone __user *tz)
{
if (tv) {
struct timeval ktv;
@@ -450,7 +358,7 @@ asmlinkage long sys32_gettimeofday(struct compat_timeval __user *tv, struct time
-asmlinkage long sys32_settimeofday(struct compat_timeval __user *tv, struct timezone __user *tz)
+asmlinkage long compat_sys_settimeofday(struct compat_timeval __user *tv, struct timezone __user *tz)
{
struct timespec kts;
struct timezone ktz;
@@ -468,7 +376,7 @@ asmlinkage long sys32_settimeofday(struct compat_timeval __user *tv, struct time
}
#ifdef CONFIG_SYSVIPC
-long sys32_ipc(u32 call, u32 first, u32 second, u32 third, compat_uptr_t ptr,
+long compat_sys_ipc(u32 call, u32 first, u32 second, u32 third, compat_uptr_t ptr,
u32 fifth)
{
int version;
@@ -539,7 +447,7 @@ long sys32_ipc(u32 call, u32 first, u32 second, u32 third, compat_uptr_t ptr,
* proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
* and the register representation of a signed int (msr in 64-bit mode) is performed.
*/
-asmlinkage long sys32_sendfile(u32 out_fd, u32 in_fd, compat_off_t __user * offset, u32 count)
+asmlinkage long compat_sys_sendfile(u32 out_fd, u32 in_fd, compat_off_t __user * offset, u32 count)
{
mm_segment_t old_fs = get_fs();
int ret;
@@ -561,7 +469,7 @@ asmlinkage long sys32_sendfile(u32 out_fd, u32 in_fd, compat_off_t __user * offs
return ret;
}
-asmlinkage int sys32_sendfile64(int out_fd, int in_fd, compat_loff_t __user *offset, s32 count)
+asmlinkage int compat_sys_sendfile64(int out_fd, int in_fd, compat_loff_t __user *offset, s32 count)
{
mm_segment_t old_fs = get_fs();
int ret;
@@ -583,7 +491,7 @@ asmlinkage int sys32_sendfile64(int out_fd, int in_fd, compat_loff_t __user *off
return ret;
}
-long sys32_execve(unsigned long a0, unsigned long a1, unsigned long a2,
+long compat_sys_execve(unsigned long a0, unsigned long a1, unsigned long a2,
unsigned long a3, unsigned long a4, unsigned long a5,
struct pt_regs *regs)
{
@@ -610,58 +518,12 @@ out:
return error;
}
-/* Set up a thread for executing a new program. */
-void start_thread32(struct pt_regs* regs, unsigned long nip, unsigned long sp)
-{
- set_fs(USER_DS);
-
- /*
- * If we exec out of a kernel thread then thread.regs will not be
- * set. Do it now.
- */
- if (!current->thread.regs) {
- unsigned long childregs = (unsigned long)current->thread_info +
- THREAD_SIZE;
- childregs -= sizeof(struct pt_regs);
- current->thread.regs = (struct pt_regs *)childregs;
- }
-
- /*
- * ELF_PLAT_INIT already clears all registers but it also sets r2.
- * So just clear r2 here.
- */
- regs->gpr[2] = 0;
-
- regs->nip = nip;
- regs->gpr[1] = sp;
- regs->msr = MSR_USER32;
-#ifndef CONFIG_SMP
- if (last_task_used_math == current)
- last_task_used_math = 0;
-#endif /* CONFIG_SMP */
- current->thread.fpscr = 0;
- memset(current->thread.fpr, 0, sizeof(current->thread.fpr));
-#ifdef CONFIG_ALTIVEC
-#ifndef CONFIG_SMP
- if (last_task_used_altivec == current)
- last_task_used_altivec = 0;
-#endif /* CONFIG_SMP */
- memset(current->thread.vr, 0, sizeof(current->thread.vr));
- current->thread.vscr.u[0] = 0;
- current->thread.vscr.u[1] = 0;
- current->thread.vscr.u[2] = 0;
- current->thread.vscr.u[3] = 0x00010000; /* Java mode disabled */
- current->thread.vrsave = 0;
- current->thread.used_vr = 0;
-#endif /* CONFIG_ALTIVEC */
-}
-
/* Note: it is necessary to treat option as an unsigned int,
* with the corresponding cast to a signed int to insure that the
* proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
* and the register representation of a signed int (msr in 64-bit mode) is performed.
*/
-asmlinkage long sys32_prctl(u32 option, u32 arg2, u32 arg3, u32 arg4, u32 arg5)
+asmlinkage long compat_sys_prctl(u32 option, u32 arg2, u32 arg3, u32 arg4, u32 arg5)
{
return sys_prctl((int)option,
(unsigned long) arg2,
@@ -675,7 +537,7 @@ asmlinkage long sys32_prctl(u32 option, u32 arg2, u32 arg3, u32 arg4, u32 arg5)
* proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
* and the register representation of a signed int (msr in 64-bit mode) is performed.
*/
-asmlinkage long sys32_sched_rr_get_interval(u32 pid, struct compat_timespec __user *interval)
+asmlinkage long compat_sys_sched_rr_get_interval(u32 pid, struct compat_timespec __user *interval)
{
struct timespec t;
int ret;
@@ -690,7 +552,7 @@ asmlinkage long sys32_sched_rr_get_interval(u32 pid, struct compat_timespec __us
return ret;
}
-asmlinkage int sys32_pciconfig_read(u32 bus, u32 dfn, u32 off, u32 len, u32 ubuf)
+asmlinkage int compat_sys_pciconfig_read(u32 bus, u32 dfn, u32 off, u32 len, u32 ubuf)
{
return sys_pciconfig_read((unsigned long) bus,
(unsigned long) dfn,
@@ -699,7 +561,7 @@ asmlinkage int sys32_pciconfig_read(u32 bus, u32 dfn, u32 off, u32 len, u32 ubuf
compat_ptr(ubuf));
}
-asmlinkage int sys32_pciconfig_write(u32 bus, u32 dfn, u32 off, u32 len, u32 ubuf)
+asmlinkage int compat_sys_pciconfig_write(u32 bus, u32 dfn, u32 off, u32 len, u32 ubuf)
{
return sys_pciconfig_write((unsigned long) bus,
(unsigned long) dfn,
@@ -708,7 +570,7 @@ asmlinkage int sys32_pciconfig_write(u32 bus, u32 dfn, u32 off, u32 len, u32 ubu
compat_ptr(ubuf));
}
-asmlinkage int sys32_pciconfig_iobase(u32 which, u32 in_bus, u32 in_devfn)
+asmlinkage int compat_sys_pciconfig_iobase(u32 which, u32 in_bus, u32 in_devfn)
{
return sys_pciconfig_iobase(which, in_bus, in_devfn);
}
@@ -719,7 +581,7 @@ asmlinkage int sys32_pciconfig_iobase(u32 which, u32 in_bus, u32 in_devfn)
* proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
* and the register representation of a signed int (msr in 64-bit mode) is performed.
*/
-asmlinkage long sys32_access(const char __user * filename, u32 mode)
+asmlinkage long compat_sys_access(const char __user * filename, u32 mode)
{
return sys_access(filename, (int)mode);
}
@@ -730,7 +592,7 @@ asmlinkage long sys32_access(const char __user * filename, u32 mode)
* proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
* and the register representation of a signed int (msr in 64-bit mode) is performed.
*/
-asmlinkage long sys32_creat(const char __user * pathname, u32 mode)
+asmlinkage long compat_sys_creat(const char __user * pathname, u32 mode)
{
return sys_creat(pathname, (int)mode);
}
@@ -741,7 +603,7 @@ asmlinkage long sys32_creat(const char __user * pathname, u32 mode)
* proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
* and the register representation of a signed int (msr in 64-bit mode) is performed.
*/
-asmlinkage long sys32_waitpid(u32 pid, unsigned int __user * stat_addr, u32 options)
+asmlinkage long compat_sys_waitpid(u32 pid, unsigned int __user * stat_addr, u32 options)
{
return sys_waitpid((int)pid, stat_addr, (int)options);
}
@@ -752,7 +614,7 @@ asmlinkage long sys32_waitpid(u32 pid, unsigned int __user * stat_addr, u32 opti
* proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
* and the register representation of a signed int (msr in 64-bit mode) is performed.
*/
-asmlinkage long sys32_getgroups(u32 gidsetsize, gid_t __user *grouplist)
+asmlinkage long compat_sys_getgroups(u32 gidsetsize, gid_t __user *grouplist)
{
return sys_getgroups((int)gidsetsize, grouplist);
}
@@ -763,7 +625,7 @@ asmlinkage long sys32_getgroups(u32 gidsetsize, gid_t __user *grouplist)
* proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
* and the register representation of a signed int (msr in 64-bit mode) is performed.
*/
-asmlinkage long sys32_getpgid(u32 pid)
+asmlinkage long compat_sys_getpgid(u32 pid)
{
return sys_getpgid((int)pid);
}
@@ -775,7 +637,7 @@ asmlinkage long sys32_getpgid(u32 pid)
* proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
* and the register representation of a signed int (msr in 64-bit mode) is performed.
*/
-asmlinkage long sys32_getsid(u32 pid)
+asmlinkage long compat_sys_getsid(u32 pid)
{
return sys_getsid((int)pid);
}
@@ -786,7 +648,7 @@ asmlinkage long sys32_getsid(u32 pid)
* proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
* and the register representation of a signed int (msr in 64-bit mode) is performed.
*/
-asmlinkage long sys32_kill(u32 pid, u32 sig)
+asmlinkage long compat_sys_kill(u32 pid, u32 sig)
{
return sys_kill((int)pid, (int)sig);
}
@@ -797,12 +659,12 @@ asmlinkage long sys32_kill(u32 pid, u32 sig)
* proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
* and the register representation of a signed int (msr in 64-bit mode) is performed.
*/
-asmlinkage long sys32_mkdir(const char __user * pathname, u32 mode)
+asmlinkage long compat_sys_mkdir(const char __user * pathname, u32 mode)
{
return sys_mkdir(pathname, (int)mode);
}
-long sys32_nice(u32 increment)
+long compat_sys_nice(u32 increment)
{
/* sign extend increment */
return sys_nice((int)increment);
@@ -819,7 +681,7 @@ off_t ppc32_lseek(unsigned int fd, u32 offset, unsigned int origin)
* proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
* and the register representation of a signed int (msr in 64-bit mode) is performed.
*/
-asmlinkage long sys32_readlink(const char __user * path, char __user * buf, u32 bufsiz)
+asmlinkage long compat_sys_readlink(const char __user * path, char __user * buf, u32 bufsiz)
{
return sys_readlink(path, buf, (int)bufsiz);
}
@@ -829,7 +691,7 @@ asmlinkage long sys32_readlink(const char __user * path, char __user * buf, u32
* proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
* and the register representation of a signed int (msr in 64-bit mode) is performed.
*/
-asmlinkage long sys32_sched_get_priority_max(u32 policy)
+asmlinkage long compat_sys_sched_get_priority_max(u32 policy)
{
return sys_sched_get_priority_max((int)policy);
}
@@ -840,7 +702,7 @@ asmlinkage long sys32_sched_get_priority_max(u32 policy)
* proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
* and the register representation of a signed int (msr in 64-bit mode) is performed.
*/
-asmlinkage long sys32_sched_get_priority_min(u32 policy)
+asmlinkage long compat_sys_sched_get_priority_min(u32 policy)
{
return sys_sched_get_priority_min((int)policy);
}
@@ -851,7 +713,7 @@ asmlinkage long sys32_sched_get_priority_min(u32 policy)
* proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
* and the register representation of a signed int (msr in 64-bit mode) is performed.
*/
-asmlinkage long sys32_sched_getparam(u32 pid, struct sched_param __user *param)
+asmlinkage long compat_sys_sched_getparam(u32 pid, struct sched_param __user *param)
{
return sys_sched_getparam((int)pid, param);
}
@@ -862,7 +724,7 @@ asmlinkage long sys32_sched_getparam(u32 pid, struct sched_param __user *param)
* proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
* and the register representation of a signed int (msr in 64-bit mode) is performed.
*/
-asmlinkage long sys32_sched_getscheduler(u32 pid)
+asmlinkage long compat_sys_sched_getscheduler(u32 pid)
{
return sys_sched_getscheduler((int)pid);
}
@@ -873,7 +735,7 @@ asmlinkage long sys32_sched_getscheduler(u32 pid)
* proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
* and the register representation of a signed int (msr in 64-bit mode) is performed.
*/
-asmlinkage long sys32_sched_setparam(u32 pid, struct sched_param __user *param)
+asmlinkage long compat_sys_sched_setparam(u32 pid, struct sched_param __user *param)
{
return sys_sched_setparam((int)pid, param);
}
@@ -884,7 +746,7 @@ asmlinkage long sys32_sched_setparam(u32 pid, struct sched_param __user *param)
* proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
* and the register representation of a signed int (msr in 64-bit mode) is performed.
*/
-asmlinkage long sys32_sched_setscheduler(u32 pid, u32 policy, struct sched_param __user *param)
+asmlinkage long compat_sys_sched_setscheduler(u32 pid, u32 policy, struct sched_param __user *param)
{
return sys_sched_setscheduler((int)pid, (int)policy, param);
}
@@ -895,7 +757,7 @@ asmlinkage long sys32_sched_setscheduler(u32 pid, u32 policy, struct sched_param
* proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
* and the register representation of a signed int (msr in 64-bit mode) is performed.
*/
-asmlinkage long sys32_setdomainname(char __user *name, u32 len)
+asmlinkage long compat_sys_setdomainname(char __user *name, u32 len)
{
return sys_setdomainname(name, (int)len);
}
@@ -906,13 +768,13 @@ asmlinkage long sys32_setdomainname(char __user *name, u32 len)
* proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
* and the register representation of a signed int (msr in 64-bit mode) is performed.
*/
-asmlinkage long sys32_setgroups(u32 gidsetsize, gid_t __user *grouplist)
+asmlinkage long compat_sys_setgroups(u32 gidsetsize, gid_t __user *grouplist)
{
return sys_setgroups((int)gidsetsize, grouplist);
}
-asmlinkage long sys32_sethostname(char __user *name, u32 len)
+asmlinkage long compat_sys_sethostname(char __user *name, u32 len)
{
/* sign extend len */
return sys_sethostname(name, (int)len);
@@ -924,30 +786,30 @@ asmlinkage long sys32_sethostname(char __user *name, u32 len)
* proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
* and the register representation of a signed int (msr in 64-bit mode) is performed.
*/
-asmlinkage long sys32_setpgid(u32 pid, u32 pgid)
+asmlinkage long compat_sys_setpgid(u32 pid, u32 pgid)
{
return sys_setpgid((int)pid, (int)pgid);
}
-long sys32_getpriority(u32 which, u32 who)
+long compat_sys_getpriority(u32 which, u32 who)
{
/* sign extend which and who */
return sys_getpriority((int)which, (int)who);
}
-long sys32_setpriority(u32 which, u32 who, u32 niceval)
+long compat_sys_setpriority(u32 which, u32 who, u32 niceval)
{
/* sign extend which, who and niceval */
return sys_setpriority((int)which, (int)who, (int)niceval);
}
-long sys32_ioprio_get(u32 which, u32 who)
+long compat_sys_ioprio_get(u32 which, u32 who)
{
/* sign extend which and who */
return sys_ioprio_get((int)which, (int)who);
}
-long sys32_ioprio_set(u32 which, u32 who, u32 ioprio)
+long compat_sys_ioprio_set(u32 which, u32 who, u32 ioprio)
{
/* sign extend which, who and ioprio */
return sys_ioprio_set((int)which, (int)who, (int)ioprio);
@@ -958,12 +820,12 @@ long sys32_ioprio_set(u32 which, u32 who, u32 ioprio)
* proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
* and the register representation of a signed int (msr in 64-bit mode) is performed.
*/
-asmlinkage long sys32_ssetmask(u32 newmask)
+asmlinkage long compat_sys_ssetmask(u32 newmask)
{
return sys_ssetmask((int) newmask);
}
-asmlinkage long sys32_syslog(u32 type, char __user * buf, u32 len)
+asmlinkage long compat_sys_syslog(u32 type, char __user * buf, u32 len)
{
/* sign extend len */
return sys_syslog(type, buf, (int)len);
@@ -975,7 +837,7 @@ asmlinkage long sys32_syslog(u32 type, char __user * buf, u32 len)
* proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
* and the register representation of a signed int (msr in 64-bit mode) is performed.
*/
-asmlinkage long sys32_umask(u32 mask)
+asmlinkage long compat_sys_umask(u32 mask)
{
return sys_umask((int)mask);
}
@@ -991,7 +853,7 @@ struct __sysctl_args32 {
u32 __unused[4];
};
-asmlinkage long sys32_sysctl(struct __sysctl_args32 __user *args)
+asmlinkage long compat_sys_sysctl(struct __sysctl_args32 __user *args)
{
struct __sysctl_args32 tmp;
int error;
@@ -1032,55 +894,7 @@ asmlinkage long sys32_sysctl(struct __sysctl_args32 __user *args)
}
#endif
-asmlinkage int sys32_uname(struct old_utsname __user * name)
-{
- int err = 0;
-
- down_read(&uts_sem);
- if (copy_to_user(name, &system_utsname, sizeof(*name)))
- err = -EFAULT;
- up_read(&uts_sem);
- if (!err && personality(current->personality) == PER_LINUX32) {
- /* change "ppc64" to "ppc" */
- if (__put_user(0, name->machine + 3)
- || __put_user(0, name->machine + 4))
- err = -EFAULT;
- }
- return err;
-}
-
-asmlinkage int sys32_olduname(struct oldold_utsname __user * name)
-{
- int error;
-
- if (!access_ok(VERIFY_WRITE,name,sizeof(struct oldold_utsname)))
- return -EFAULT;
-
- down_read(&uts_sem);
- error = __copy_to_user(&name->sysname,&system_utsname.sysname,__OLD_UTS_LEN);
- error |= __put_user(0,name->sysname+__OLD_UTS_LEN);
- error |= __copy_to_user(&name->nodename,&system_utsname.nodename,__OLD_UTS_LEN);
- error |= __put_user(0,name->nodename+__OLD_UTS_LEN);
- error |= __copy_to_user(&name->release,&system_utsname.release,__OLD_UTS_LEN);
- error |= __put_user(0,name->release+__OLD_UTS_LEN);
- error |= __copy_to_user(&name->version,&system_utsname.version,__OLD_UTS_LEN);
- error |= __put_user(0,name->version+__OLD_UTS_LEN);
- error |= __copy_to_user(&name->machine,&system_utsname.machine,__OLD_UTS_LEN);
- error |= __put_user(0,name->machine+__OLD_UTS_LEN);
- if (personality(current->personality) == PER_LINUX32) {
- /* change "ppc64" to "ppc" */
- error |= __put_user(0, name->machine + 3);
- error |= __put_user(0, name->machine + 4);
- }
-
- up_read(&uts_sem);
-
- error = error ? -EFAULT : 0;
-
- return error;
-}
-
-unsigned long sys32_mmap2(unsigned long addr, size_t len,
+unsigned long compat_sys_mmap2(unsigned long addr, size_t len,
unsigned long prot, unsigned long flags,
unsigned long fd, unsigned long pgoff)
{
@@ -1088,29 +902,7 @@ unsigned long sys32_mmap2(unsigned long addr, size_t len,
return sys_mmap(addr, len, prot, flags, fd, pgoff << 12);
}
-int get_compat_timeval(struct timeval *tv, struct compat_timeval __user *ctv)
-{
- return (!access_ok(VERIFY_READ, ctv, sizeof(*ctv)) ||
- __get_user(tv->tv_sec, &ctv->tv_sec) ||
- __get_user(tv->tv_usec, &ctv->tv_usec)) ? -EFAULT : 0;
-}
-
-asmlinkage long sys32_utimes(char __user *filename, struct compat_timeval __user *tvs)
-{
- struct timeval ktvs[2], *ptr;
-
- ptr = NULL;
- if (tvs) {
- if (get_compat_timeval(&ktvs[0], &tvs[0]) ||
- get_compat_timeval(&ktvs[1], &tvs[1]))
- return -EFAULT;
- ptr = ktvs;
- }
-
- return do_utimes(filename, ptr);
-}
-
-long sys32_tgkill(u32 tgid, u32 pid, int sig)
+long compat_sys_tgkill(u32 tgid, u32 pid, int sig)
{
/* sign extend tgid, pid */
return sys_tgkill((int)tgid, (int)pid, sig);
@@ -1121,30 +913,30 @@ long sys32_tgkill(u32 tgid, u32 pid, int sig)
* The 32 bit ABI passes long longs in an odd even register pair.
*/
-compat_ssize_t sys32_pread64(unsigned int fd, char __user *ubuf, compat_size_t count,
+compat_ssize_t compat_sys_pread64(unsigned int fd, char __user *ubuf, compat_size_t count,
u32 reg6, u32 poshi, u32 poslo)
{
return sys_pread64(fd, ubuf, count, ((loff_t)poshi << 32) | poslo);
}
-compat_ssize_t sys32_pwrite64(unsigned int fd, char __user *ubuf, compat_size_t count,
+compat_ssize_t compat_sys_pwrite64(unsigned int fd, char __user *ubuf, compat_size_t count,
u32 reg6, u32 poshi, u32 poslo)
{
return sys_pwrite64(fd, ubuf, count, ((loff_t)poshi << 32) | poslo);
}
-compat_ssize_t sys32_readahead(int fd, u32 r4, u32 offhi, u32 offlo, u32 count)
+compat_ssize_t compat_sys_readahead(int fd, u32 r4, u32 offhi, u32 offlo, u32 count)
{
return sys_readahead(fd, ((loff_t)offhi << 32) | offlo, count);
}
-asmlinkage int sys32_truncate64(const char __user * path, u32 reg4,
+asmlinkage int compat_sys_truncate64(const char __user * path, u32 reg4,
unsigned long high, unsigned long low)
{
return sys_truncate(path, (high << 32) | low);
}
-asmlinkage int sys32_ftruncate64(unsigned int fd, u32 reg4, unsigned long high,
+asmlinkage int compat_sys_ftruncate64(unsigned int fd, u32 reg4, unsigned long high,
unsigned long low)
{
return sys_ftruncate(fd, (high << 32) | low);
@@ -1164,13 +956,6 @@ long ppc32_fadvise64(int fd, u32 unused, u32 offset_high, u32 offset_low,
advice);
}
-long ppc32_fadvise64_64(int fd, int advice, u32 offset_high, u32 offset_low,
- u32 len_high, u32 len_low)
-{
- return sys_fadvise64(fd, (u64)offset_high << 32 | offset_low,
- (u64)len_high << 32 | len_low, advice);
-}
-
long ppc32_timer_create(clockid_t clock,
struct compat_sigevent __user *ev32,
timer_t __user *timer_id)
@@ -1203,7 +988,7 @@ long ppc32_timer_create(clockid_t clock,
return err;
}
-asmlinkage long sys32_add_key(const char __user *_type,
+asmlinkage long compat_sys_add_key(const char __user *_type,
const char __user *_description,
const void __user *_payload,
u32 plen,
@@ -1212,7 +997,7 @@ asmlinkage long sys32_add_key(const char __user *_type,
return sys_add_key(_type, _description, _payload, plen, ringid);
}
-asmlinkage long sys32_request_key(const char __user *_type,
+asmlinkage long compat_sys_request_key(const char __user *_type,
const char __user *_description,
const char __user *_callout_info,
u32 destringid)
diff --git a/arch/ppc64/kernel/syscalls.c b/arch/powerpc/kernel/syscalls.c
index 05f16633bd2c..f72ced11212d 100644
--- a/arch/ppc64/kernel/syscalls.c
+++ b/arch/powerpc/kernel/syscalls.c
@@ -1,7 +1,6 @@
/*
- * linux/arch/ppc64/kernel/sys_ppc.c
+ * Implementation of various system calls for Linux/PowerPC
*
- * PowerPC version
* Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
*
* Derived from "arch/i386/kernel/sys_i386.c"
@@ -52,9 +51,8 @@ extern unsigned long wall_jiffies;
*
* This is really horribly ugly.
*/
-asmlinkage int
-sys_ipc (uint call, int first, unsigned long second, long third,
- void __user *ptr, long fifth)
+int sys_ipc(uint call, int first, unsigned long second, long third,
+ void __user *ptr, long fifth)
{
int version, ret;
@@ -88,7 +86,7 @@ sys_ipc (uint call, int first, unsigned long second, long third,
}
case MSGSND:
ret = sys_msgsnd(first, (struct msgbuf __user *)ptr,
- (size_t)second, third);
+ (size_t)second, third);
break;
case MSGRCV:
switch (version) {
@@ -113,41 +111,29 @@ sys_ipc (uint call, int first, unsigned long second, long third,
}
break;
case MSGGET:
- ret = sys_msgget ((key_t)first, (int)second);
+ ret = sys_msgget((key_t)first, (int)second);
break;
case MSGCTL:
ret = sys_msgctl(first, (int)second,
(struct msqid_ds __user *)ptr);
break;
- case SHMAT:
- switch (version) {
- default: {
- ulong raddr;
- ret = do_shmat(first, (char __user *) ptr,
- (int)second, &raddr);
- if (ret)
- break;
- ret = put_user (raddr, (ulong __user *) third);
- break;
- }
- case 1: /* iBCS2 emulator entry point */
- ret = -EINVAL;
- if (!segment_eq(get_fs(), get_ds()))
- break;
- ret = do_shmat(first, (char __user *)ptr,
- (int)second, (ulong *)third);
+ case SHMAT: {
+ ulong raddr;
+ ret = do_shmat(first, (char __user *)ptr, (int)second, &raddr);
+ if (ret)
break;
- }
+ ret = put_user(raddr, (ulong __user *) third);
break;
- case SHMDT:
- ret = sys_shmdt ((char __user *)ptr);
+ }
+ case SHMDT:
+ ret = sys_shmdt((char __user *)ptr);
break;
case SHMGET:
- ret = sys_shmget (first, (size_t)second, third);
+ ret = sys_shmget(first, (size_t)second, third);
break;
case SHMCTL:
ret = sys_shmctl(first, (int)second,
- (struct shmid_ds __user *)ptr);
+ (struct shmid_ds __user *)ptr);
break;
}
@@ -158,43 +144,89 @@ sys_ipc (uint call, int first, unsigned long second, long third,
* sys_pipe() is the normal C calling standard for creating
* a pipe. It's not the way unix traditionally does this, though.
*/
-asmlinkage int sys_pipe(int __user *fildes)
+int sys_pipe(int __user *fildes)
{
int fd[2];
int error;
-
+
error = do_pipe(fd);
if (!error) {
if (copy_to_user(fildes, fd, 2*sizeof(int)))
error = -EFAULT;
}
-
return error;
}
-unsigned long sys_mmap(unsigned long addr, size_t len,
- unsigned long prot, unsigned long flags,
- unsigned long fd, off_t offset)
+static inline unsigned long do_mmap2(unsigned long addr, size_t len,
+ unsigned long prot, unsigned long flags,
+ unsigned long fd, unsigned long off, int shift)
{
struct file * file = NULL;
- unsigned long ret = -EBADF;
+ unsigned long ret = -EINVAL;
+ if (shift) {
+ if (off & ((1 << shift) - 1))
+ goto out;
+ off >>= shift;
+ }
+
+ ret = -EBADF;
if (!(flags & MAP_ANONYMOUS)) {
if (!(file = fget(fd)))
goto out;
}
flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+
down_write(&current->mm->mmap_sem);
- ret = do_mmap(file, addr, len, prot, flags, offset);
+ ret = do_mmap_pgoff(file, addr, len, prot, flags, off);
up_write(&current->mm->mmap_sem);
if (file)
fput(file);
-
out:
return ret;
}
+unsigned long sys_mmap2(unsigned long addr, size_t len,
+ unsigned long prot, unsigned long flags,
+ unsigned long fd, unsigned long pgoff)
+{
+ return do_mmap2(addr, len, prot, flags, fd, pgoff, PAGE_SHIFT-12);
+}
+
+unsigned long sys_mmap(unsigned long addr, size_t len,
+ unsigned long prot, unsigned long flags,
+ unsigned long fd, off_t offset)
+{
+ return do_mmap2(addr, len, prot, flags, fd, offset, PAGE_SHIFT);
+}
+
+#ifdef CONFIG_PPC32
+/*
+ * Due to some executables calling the wrong select we sometimes
+ * get wrong args. This determines how the args are being passed
+ * (a single ptr to them all args passed) then calls
+ * sys_select() with the appropriate args. -- Cort
+ */
+int
+ppc_select(int n, fd_set __user *inp, fd_set __user *outp, fd_set __user *exp, struct timeval __user *tvp)
+{
+ if ( (unsigned long)n >= 4096 )
+ {
+ unsigned long __user *buffer = (unsigned long __user *)n;
+ if (!access_ok(VERIFY_READ, buffer, 5*sizeof(unsigned long))
+ || __get_user(n, buffer)
+ || __get_user(inp, ((fd_set __user * __user *)(buffer+1)))
+ || __get_user(outp, ((fd_set __user * __user *)(buffer+2)))
+ || __get_user(exp, ((fd_set __user * __user *)(buffer+3)))
+ || __get_user(tvp, ((struct timeval __user * __user *)(buffer+4))))
+ return -EFAULT;
+ }
+ return sys_select(n, inp, outp, exp, tvp);
+}
+#endif
+
+#ifdef CONFIG_PPC64
long ppc64_personality(unsigned long personality)
{
long ret;
@@ -207,8 +239,25 @@ long ppc64_personality(unsigned long personality)
ret = PER_LINUX;
return ret;
}
+#endif
+
+#ifdef CONFIG_PPC64
+#define OVERRIDE_MACHINE (personality(current->personality) == PER_LINUX32)
+#else
+#define OVERRIDE_MACHINE 0
+#endif
+
+static inline int override_machine(char *mach)
+{
+ if (OVERRIDE_MACHINE) {
+ /* change ppc64 to ppc */
+ if (__put_user(0, mach+3) || __put_user(0, mach+4))
+ return -EFAULT;
+ }
+ return 0;
+}
-long ppc64_newuname(struct new_utsname __user * name)
+long ppc_newuname(struct new_utsname __user * name)
{
int err = 0;
@@ -216,16 +265,54 @@ long ppc64_newuname(struct new_utsname __user * name)
if (copy_to_user(name, &system_utsname, sizeof(*name)))
err = -EFAULT;
up_read(&uts_sem);
- if (!err && personality(current->personality) == PER_LINUX32) {
- /* change ppc64 to ppc */
- if (__put_user(0, name->machine + 3)
- || __put_user(0, name->machine + 4))
- err = -EFAULT;
- }
+ if (!err)
+ err = override_machine(name->machine);
return err;
}
-asmlinkage time_t sys64_time(time_t __user * tloc)
+int sys_uname(struct old_utsname __user *name)
+{
+ int err = 0;
+
+ down_read(&uts_sem);
+ if (copy_to_user(name, &system_utsname, sizeof(*name)))
+ err = -EFAULT;
+ up_read(&uts_sem);
+ if (!err)
+ err = override_machine(name->machine);
+ return err;
+}
+
+int sys_olduname(struct oldold_utsname __user *name)
+{
+ int error;
+
+ if (!access_ok(VERIFY_WRITE, name, sizeof(struct oldold_utsname)))
+ return -EFAULT;
+
+ down_read(&uts_sem);
+ error = __copy_to_user(&name->sysname, &system_utsname.sysname,
+ __OLD_UTS_LEN);
+ error |= __put_user(0, name->sysname + __OLD_UTS_LEN);
+ error |= __copy_to_user(&name->nodename, &system_utsname.nodename,
+ __OLD_UTS_LEN);
+ error |= __put_user(0, name->nodename + __OLD_UTS_LEN);
+ error |= __copy_to_user(&name->release, &system_utsname.release,
+ __OLD_UTS_LEN);
+ error |= __put_user(0, name->release + __OLD_UTS_LEN);
+ error |= __copy_to_user(&name->version, &system_utsname.version,
+ __OLD_UTS_LEN);
+ error |= __put_user(0, name->version + __OLD_UTS_LEN);
+ error |= __copy_to_user(&name->machine, &system_utsname.machine,
+ __OLD_UTS_LEN);
+ error |= override_machine(name->machine);
+ up_read(&uts_sem);
+
+ return error? -EFAULT: 0;
+}
+
+#ifdef CONFIG_PPC64
+time_t sys64_time(time_t __user * tloc)
{
time_t secs;
time_t usecs;
@@ -247,6 +334,14 @@ asmlinkage time_t sys64_time(time_t __user * tloc)
return secs;
}
+#endif
+
+long ppc_fadvise64_64(int fd, int advice, u32 offset_high, u32 offset_low,
+ u32 len_high, u32 len_low)
+{
+ return sys_fadvise64(fd, (u64)offset_high << 32 | offset_low,
+ (u64)len_high << 32 | len_low, advice);
+}
void do_show_syscall(unsigned long r3, unsigned long r4, unsigned long r5,
unsigned long r6, unsigned long r7, unsigned long r8,
diff --git a/arch/ppc64/kernel/sysfs.c b/arch/powerpc/kernel/sysfs.c
index 6654b350979c..850af198fb5f 100644
--- a/arch/ppc64/kernel/sysfs.c
+++ b/arch/powerpc/kernel/sysfs.c
@@ -20,6 +20,7 @@
#include <asm/paca.h>
#include <asm/lppaca.h>
#include <asm/machdep.h>
+#include <asm/smp.h>
static DEFINE_PER_CPU(struct cpu, cpu_devices);
@@ -231,7 +232,7 @@ static void register_cpu_online(unsigned int cpu)
sysdev_create_file(s, &attr_pmc7);
if (cur_cpu_spec->num_pmcs >= 8)
sysdev_create_file(s, &attr_pmc8);
-
+
if (cpu_has_feature(CPU_FTR_SMT))
sysdev_create_file(s, &attr_purr);
}
diff --git a/arch/powerpc/kernel/systbl.S b/arch/powerpc/kernel/systbl.S
new file mode 100644
index 000000000000..65eaea91b499
--- /dev/null
+++ b/arch/powerpc/kernel/systbl.S
@@ -0,0 +1,321 @@
+/*
+ * This file contains the table of syscall-handling functions.
+ * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
+ *
+ * Largely rewritten by Cort Dougan (cort@cs.nmt.edu)
+ * and Paul Mackerras.
+ *
+ * Adapted for iSeries by Mike Corrigan (mikejc@us.ibm.com)
+ * PPC64 updates by Dave Engebretsen (engebret@us.ibm.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/config.h>
+#include <asm/ppc_asm.h>
+
+#ifdef CONFIG_PPC64
+#define SYSCALL(func) .llong .sys_##func,.sys_##func
+#define COMPAT_SYS(func) .llong .sys_##func,.compat_sys_##func
+#define PPC_SYS(func) .llong .ppc_##func,.ppc_##func
+#define OLDSYS(func) .llong .sys_ni_syscall,.sys_ni_syscall
+#define SYS32ONLY(func) .llong .sys_ni_syscall,.compat_sys_##func
+#define SYSX(f, f3264, f32) .llong .f,.f3264
+#else
+#define SYSCALL(func) .long sys_##func
+#define COMPAT_SYS(func) .long sys_##func
+#define PPC_SYS(func) .long ppc_##func
+#define OLDSYS(func) .long sys_##func
+#define SYS32ONLY(func) .long sys_##func
+#define SYSX(f, f3264, f32) .long f32
+#endif
+
+#ifdef CONFIG_PPC64
+#define sys_sigpending sys_ni_syscall
+#define sys_old_getrlimit sys_ni_syscall
+#else
+#define ppc_rtas sys_ni_syscall
+#endif
+
+_GLOBAL(sys_call_table)
+SYSCALL(restart_syscall)
+SYSCALL(exit)
+PPC_SYS(fork)
+SYSCALL(read)
+SYSCALL(write)
+COMPAT_SYS(open)
+SYSCALL(close)
+COMPAT_SYS(waitpid)
+COMPAT_SYS(creat)
+SYSCALL(link)
+SYSCALL(unlink)
+COMPAT_SYS(execve)
+SYSCALL(chdir)
+SYSX(sys64_time,compat_sys_time,sys_time)
+SYSCALL(mknod)
+SYSCALL(chmod)
+SYSCALL(lchown)
+SYSCALL(ni_syscall)
+OLDSYS(stat)
+SYSX(sys_lseek,ppc32_lseek,sys_lseek)
+SYSCALL(getpid)
+COMPAT_SYS(mount)
+SYSX(sys_ni_syscall,sys_oldumount,sys_oldumount)
+SYSCALL(setuid)
+SYSCALL(getuid)
+COMPAT_SYS(stime)
+COMPAT_SYS(ptrace)
+SYSCALL(alarm)
+OLDSYS(fstat)
+COMPAT_SYS(pause)
+COMPAT_SYS(utime)
+SYSCALL(ni_syscall)
+SYSCALL(ni_syscall)
+COMPAT_SYS(access)
+COMPAT_SYS(nice)
+SYSCALL(ni_syscall)
+SYSCALL(sync)
+COMPAT_SYS(kill)
+SYSCALL(rename)
+COMPAT_SYS(mkdir)
+SYSCALL(rmdir)
+SYSCALL(dup)
+SYSCALL(pipe)
+COMPAT_SYS(times)
+SYSCALL(ni_syscall)
+SYSCALL(brk)
+SYSCALL(setgid)
+SYSCALL(getgid)
+SYSCALL(signal)
+SYSCALL(geteuid)
+SYSCALL(getegid)
+SYSCALL(acct)
+SYSCALL(umount)
+SYSCALL(ni_syscall)
+COMPAT_SYS(ioctl)
+COMPAT_SYS(fcntl)
+SYSCALL(ni_syscall)
+COMPAT_SYS(setpgid)
+SYSCALL(ni_syscall)
+SYSX(sys_ni_syscall,sys_olduname, sys_olduname)
+COMPAT_SYS(umask)
+SYSCALL(chroot)
+SYSCALL(ustat)
+SYSCALL(dup2)
+SYSCALL(getppid)
+SYSCALL(getpgrp)
+SYSCALL(setsid)
+SYS32ONLY(sigaction)
+SYSCALL(sgetmask)
+COMPAT_SYS(ssetmask)
+SYSCALL(setreuid)
+SYSCALL(setregid)
+SYSX(sys_ni_syscall,ppc32_sigsuspend,ppc_sigsuspend)
+COMPAT_SYS(sigpending)
+COMPAT_SYS(sethostname)
+COMPAT_SYS(setrlimit)
+COMPAT_SYS(old_getrlimit)
+COMPAT_SYS(getrusage)
+COMPAT_SYS(gettimeofday)
+COMPAT_SYS(settimeofday)
+COMPAT_SYS(getgroups)
+COMPAT_SYS(setgroups)
+SYSX(sys_ni_syscall,sys_ni_syscall,ppc_select)
+SYSCALL(symlink)
+OLDSYS(lstat)
+COMPAT_SYS(readlink)
+SYSCALL(uselib)
+SYSCALL(swapon)
+SYSCALL(reboot)
+SYSX(sys_ni_syscall,old32_readdir,old_readdir)
+SYSCALL(mmap)
+SYSCALL(munmap)
+SYSCALL(truncate)
+SYSCALL(ftruncate)
+SYSCALL(fchmod)
+SYSCALL(fchown)
+COMPAT_SYS(getpriority)
+COMPAT_SYS(setpriority)
+SYSCALL(ni_syscall)
+COMPAT_SYS(statfs)
+COMPAT_SYS(fstatfs)
+SYSCALL(ni_syscall)
+COMPAT_SYS(socketcall)
+COMPAT_SYS(syslog)
+COMPAT_SYS(setitimer)
+COMPAT_SYS(getitimer)
+COMPAT_SYS(newstat)
+COMPAT_SYS(newlstat)
+COMPAT_SYS(newfstat)
+SYSX(sys_ni_syscall,sys_uname,sys_uname)
+SYSCALL(ni_syscall)
+SYSCALL(vhangup)
+SYSCALL(ni_syscall)
+SYSCALL(ni_syscall)
+COMPAT_SYS(wait4)
+SYSCALL(swapoff)
+COMPAT_SYS(sysinfo)
+COMPAT_SYS(ipc)
+SYSCALL(fsync)
+SYSX(sys_ni_syscall,ppc32_sigreturn,sys_sigreturn)
+PPC_SYS(clone)
+COMPAT_SYS(setdomainname)
+PPC_SYS(newuname)
+SYSCALL(ni_syscall)
+COMPAT_SYS(adjtimex)
+SYSCALL(mprotect)
+SYSX(sys_ni_syscall,compat_sys_sigprocmask,sys_sigprocmask)
+SYSCALL(ni_syscall)
+SYSCALL(init_module)
+SYSCALL(delete_module)
+SYSCALL(ni_syscall)
+SYSCALL(quotactl)
+COMPAT_SYS(getpgid)
+SYSCALL(fchdir)
+SYSCALL(bdflush)
+COMPAT_SYS(sysfs)
+SYSX(ppc64_personality,ppc64_personality,sys_personality)
+SYSCALL(ni_syscall)
+SYSCALL(setfsuid)
+SYSCALL(setfsgid)
+SYSCALL(llseek)
+COMPAT_SYS(getdents)
+SYSX(sys_select,ppc32_select,ppc_select)
+SYSCALL(flock)
+SYSCALL(msync)
+COMPAT_SYS(readv)
+COMPAT_SYS(writev)
+COMPAT_SYS(getsid)
+SYSCALL(fdatasync)
+COMPAT_SYS(sysctl)
+SYSCALL(mlock)
+SYSCALL(munlock)
+SYSCALL(mlockall)
+SYSCALL(munlockall)
+COMPAT_SYS(sched_setparam)
+COMPAT_SYS(sched_getparam)
+COMPAT_SYS(sched_setscheduler)
+COMPAT_SYS(sched_getscheduler)
+SYSCALL(sched_yield)
+COMPAT_SYS(sched_get_priority_max)
+COMPAT_SYS(sched_get_priority_min)
+COMPAT_SYS(sched_rr_get_interval)
+COMPAT_SYS(nanosleep)
+SYSCALL(mremap)
+SYSCALL(setresuid)
+SYSCALL(getresuid)
+SYSCALL(ni_syscall)
+SYSCALL(poll)
+COMPAT_SYS(nfsservctl)
+SYSCALL(setresgid)
+SYSCALL(getresgid)
+COMPAT_SYS(prctl)
+SYSX(ppc64_rt_sigreturn,ppc32_rt_sigreturn,sys_rt_sigreturn)
+COMPAT_SYS(rt_sigaction)
+COMPAT_SYS(rt_sigprocmask)
+COMPAT_SYS(rt_sigpending)
+COMPAT_SYS(rt_sigtimedwait)
+COMPAT_SYS(rt_sigqueueinfo)
+SYSX(ppc64_rt_sigsuspend,ppc32_rt_sigsuspend,ppc_rt_sigsuspend)
+COMPAT_SYS(pread64)
+COMPAT_SYS(pwrite64)
+SYSCALL(chown)
+SYSCALL(getcwd)
+SYSCALL(capget)
+SYSCALL(capset)
+COMPAT_SYS(sigaltstack)
+SYSX(sys_sendfile64,compat_sys_sendfile,sys_sendfile)
+SYSCALL(ni_syscall)
+SYSCALL(ni_syscall)
+PPC_SYS(vfork)
+COMPAT_SYS(getrlimit)
+COMPAT_SYS(readahead)
+SYS32ONLY(mmap2)
+SYS32ONLY(truncate64)
+SYS32ONLY(ftruncate64)
+SYSX(sys_ni_syscall,sys_stat64,sys_stat64)
+SYSX(sys_ni_syscall,sys_lstat64,sys_lstat64)
+SYSX(sys_ni_syscall,sys_fstat64,sys_fstat64)
+COMPAT_SYS(pciconfig_read)
+COMPAT_SYS(pciconfig_write)
+COMPAT_SYS(pciconfig_iobase)
+SYSCALL(ni_syscall)
+SYSCALL(getdents64)
+SYSCALL(pivot_root)
+SYSX(sys_ni_syscall,compat_sys_fcntl64,sys_fcntl64)
+SYSCALL(madvise)
+SYSCALL(mincore)
+SYSCALL(gettid)
+SYSCALL(tkill)
+SYSCALL(setxattr)
+SYSCALL(lsetxattr)
+SYSCALL(fsetxattr)
+SYSCALL(getxattr)
+SYSCALL(lgetxattr)
+SYSCALL(fgetxattr)
+SYSCALL(listxattr)
+SYSCALL(llistxattr)
+SYSCALL(flistxattr)
+SYSCALL(removexattr)
+SYSCALL(lremovexattr)
+SYSCALL(fremovexattr)
+COMPAT_SYS(futex)
+COMPAT_SYS(sched_setaffinity)
+COMPAT_SYS(sched_getaffinity)
+SYSCALL(ni_syscall)
+SYSCALL(ni_syscall)
+SYS32ONLY(sendfile64)
+COMPAT_SYS(io_setup)
+SYSCALL(io_destroy)
+COMPAT_SYS(io_getevents)
+COMPAT_SYS(io_submit)
+SYSCALL(io_cancel)
+SYSCALL(set_tid_address)
+SYSX(sys_fadvise64,ppc32_fadvise64,sys_fadvise64)
+SYSCALL(exit_group)
+SYSX(sys_lookup_dcookie,ppc32_lookup_dcookie,sys_lookup_dcookie)
+SYSCALL(epoll_create)
+SYSCALL(epoll_ctl)
+SYSCALL(epoll_wait)
+SYSCALL(remap_file_pages)
+SYSX(sys_timer_create,ppc32_timer_create,sys_timer_create)
+COMPAT_SYS(timer_settime)
+COMPAT_SYS(timer_gettime)
+SYSCALL(timer_getoverrun)
+SYSCALL(timer_delete)
+COMPAT_SYS(clock_settime)
+COMPAT_SYS(clock_gettime)
+COMPAT_SYS(clock_getres)
+COMPAT_SYS(clock_nanosleep)
+SYSX(ppc64_swapcontext,ppc32_swapcontext,ppc_swapcontext)
+COMPAT_SYS(tgkill)
+COMPAT_SYS(utimes)
+COMPAT_SYS(statfs64)
+COMPAT_SYS(fstatfs64)
+SYSX(sys_ni_syscall, ppc_fadvise64_64, ppc_fadvise64_64)
+PPC_SYS(rtas)
+OLDSYS(debug_setcontext)
+SYSCALL(ni_syscall)
+SYSCALL(ni_syscall)
+COMPAT_SYS(mbind)
+COMPAT_SYS(get_mempolicy)
+COMPAT_SYS(set_mempolicy)
+COMPAT_SYS(mq_open)
+SYSCALL(mq_unlink)
+COMPAT_SYS(mq_timedsend)
+COMPAT_SYS(mq_timedreceive)
+COMPAT_SYS(mq_notify)
+COMPAT_SYS(mq_getsetattr)
+COMPAT_SYS(kexec_load)
+COMPAT_SYS(add_key)
+COMPAT_SYS(request_key)
+COMPAT_SYS(keyctl)
+COMPAT_SYS(waitid)
+COMPAT_SYS(ioprio_set)
+COMPAT_SYS(ioprio_get)
+SYSCALL(inotify_init)
+SYSCALL(inotify_add_watch)
+SYSCALL(inotify_rm_watch)
diff --git a/arch/ppc64/kernel/time.c b/arch/powerpc/kernel/time.c
index b56c6a324e17..260b6ecd26a9 100644
--- a/arch/ppc64/kernel/time.c
+++ b/arch/powerpc/kernel/time.c
@@ -1,5 +1,4 @@
/*
- *
* Common time routines among all ppc machines.
*
* Written by Cort Dougan (cort@cs.nmt.edu) to merge
@@ -44,33 +43,34 @@
#include <linux/interrupt.h>
#include <linux/timex.h>
#include <linux/kernel_stat.h>
-#include <linux/mc146818rtc.h>
#include <linux/time.h>
#include <linux/init.h>
#include <linux/profile.h>
#include <linux/cpu.h>
#include <linux/security.h>
+#include <linux/percpu.h>
+#include <linux/rtc.h>
#include <asm/io.h>
#include <asm/processor.h>
#include <asm/nvram.h>
#include <asm/cache.h>
#include <asm/machdep.h>
-#ifdef CONFIG_PPC_ISERIES
-#include <asm/iSeries/ItLpQueue.h>
-#include <asm/iSeries/HvCallXm.h>
-#endif
#include <asm/uaccess.h>
#include <asm/time.h>
-#include <asm/ppcdebug.h>
#include <asm/prom.h>
-#include <asm/sections.h>
+#include <asm/irq.h>
+#include <asm/div64.h>
+#include <asm/smp.h>
+#ifdef CONFIG_PPC64
#include <asm/systemcfg.h>
#include <asm/firmware.h>
-
-u64 jiffies_64 __cacheline_aligned_in_smp = INITIAL_JIFFIES;
-
-EXPORT_SYMBOL(jiffies_64);
+#endif
+#ifdef CONFIG_PPC_ISERIES
+#include <asm/iseries/it_lp_queue.h>
+#include <asm/iseries/hv_call_xm.h>
+#endif
+#include <asm/smp.h>
/* keep track of when we need to update the rtc */
time_t last_rtc_update;
@@ -81,27 +81,37 @@ unsigned long iSeries_recal_tb = 0;
static unsigned long first_settimeofday = 1;
#endif
+/* The decrementer counts down by 128 every 128ns on a 601. */
+#define DECREMENTER_COUNT_601 (1000000000 / HZ)
+
#define XSEC_PER_SEC (1024*1024)
+#ifdef CONFIG_PPC64
+#define SCALE_XSEC(xsec, max) (((xsec) * max) / XSEC_PER_SEC)
+#else
+/* compute ((xsec << 12) * max) >> 32 */
+#define SCALE_XSEC(xsec, max) mulhwu((xsec) << 12, max)
+#endif
+
unsigned long tb_ticks_per_jiffy;
unsigned long tb_ticks_per_usec = 100; /* sane default */
EXPORT_SYMBOL(tb_ticks_per_usec);
unsigned long tb_ticks_per_sec;
-unsigned long tb_to_xs;
-unsigned tb_to_us;
+u64 tb_to_xs;
+unsigned tb_to_us;
unsigned long processor_freq;
DEFINE_SPINLOCK(rtc_lock);
EXPORT_SYMBOL_GPL(rtc_lock);
-unsigned long tb_to_ns_scale;
-unsigned long tb_to_ns_shift;
+u64 tb_to_ns_scale;
+unsigned tb_to_ns_shift;
struct gettimeofday_struct do_gtod;
extern unsigned long wall_jiffies;
-extern int smp_tb_synchronized;
extern struct timezone sys_tz;
+static long timezone_offset;
void ppc_adjtimex(void);
@@ -110,6 +120,16 @@ static unsigned adjusting_time = 0;
unsigned long ppc_proc_freq;
unsigned long ppc_tb_freq;
+u64 tb_last_jiffy __cacheline_aligned_in_smp;
+unsigned long tb_last_stamp;
+
+/*
+ * Note that on ppc32 this only stores the bottom 32 bits of
+ * the timebase value, but that's enough to tell when a jiffy
+ * has passed.
+ */
+DEFINE_PER_CPU(unsigned long, last_jiffy);
+
static __inline__ void timer_check_rtc(void)
{
/*
@@ -128,31 +148,31 @@ static __inline__ void timer_check_rtc(void)
* We should have an rtc call that only sets the minutes and
* seconds like on Intel to avoid problems with non UTC clocks.
*/
- if (ntp_synced() &&
- xtime.tv_sec - last_rtc_update >= 659 &&
- abs((xtime.tv_nsec/1000) - (1000000-1000000/HZ)) < 500000/HZ &&
- jiffies - wall_jiffies == 1) {
- struct rtc_time tm;
- to_tm(xtime.tv_sec+1, &tm);
- tm.tm_year -= 1900;
- tm.tm_mon -= 1;
- if (ppc_md.set_rtc_time(&tm) == 0)
- last_rtc_update = xtime.tv_sec+1;
- else
- /* Try again one minute later */
- last_rtc_update += 60;
+ if (ppc_md.set_rtc_time && ntp_synced() &&
+ xtime.tv_sec - last_rtc_update >= 659 &&
+ abs((xtime.tv_nsec/1000) - (1000000-1000000/HZ)) < 500000/HZ &&
+ jiffies - wall_jiffies == 1) {
+ struct rtc_time tm;
+ to_tm(xtime.tv_sec + 1 + timezone_offset, &tm);
+ tm.tm_year -= 1900;
+ tm.tm_mon -= 1;
+ if (ppc_md.set_rtc_time(&tm) == 0)
+ last_rtc_update = xtime.tv_sec + 1;
+ else
+ /* Try again one minute later */
+ last_rtc_update += 60;
}
}
/*
* This version of gettimeofday has microsecond resolution.
*/
-static inline void __do_gettimeofday(struct timeval *tv, unsigned long tb_val)
+static inline void __do_gettimeofday(struct timeval *tv, u64 tb_val)
{
- unsigned long sec, usec, tb_ticks;
- unsigned long xsec, tb_xsec;
- struct gettimeofday_vars * temp_varp;
- unsigned long temp_tb_to_xs, temp_stamp_xsec;
+ unsigned long sec, usec;
+ u64 tb_ticks, xsec;
+ struct gettimeofday_vars *temp_varp;
+ u64 temp_tb_to_xs, temp_stamp_xsec;
/*
* These calculations are faster (gets rid of divides)
@@ -164,11 +184,10 @@ static inline void __do_gettimeofday(struct timeval *tv, unsigned long tb_val)
tb_ticks = tb_val - temp_varp->tb_orig_stamp;
temp_tb_to_xs = temp_varp->tb_to_xs;
temp_stamp_xsec = temp_varp->stamp_xsec;
- tb_xsec = mulhdu( tb_ticks, temp_tb_to_xs );
- xsec = temp_stamp_xsec + tb_xsec;
+ xsec = temp_stamp_xsec + mulhdu(tb_ticks, temp_tb_to_xs);
sec = xsec / XSEC_PER_SEC;
- xsec -= sec * XSEC_PER_SEC;
- usec = (xsec * USEC_PER_SEC)/XSEC_PER_SEC;
+ usec = (unsigned long)xsec & (XSEC_PER_SEC - 1);
+ usec = SCALE_XSEC(usec, 1000000);
tv->tv_sec = sec;
tv->tv_usec = usec;
@@ -176,6 +195,26 @@ static inline void __do_gettimeofday(struct timeval *tv, unsigned long tb_val)
void do_gettimeofday(struct timeval *tv)
{
+ if (__USE_RTC()) {
+ /* do this the old way */
+ unsigned long flags, seq;
+ unsigned int sec, nsec, usec, lost;
+
+ do {
+ seq = read_seqbegin_irqsave(&xtime_lock, flags);
+ sec = xtime.tv_sec;
+ nsec = xtime.tv_nsec + tb_ticks_since(tb_last_stamp);
+ lost = jiffies - wall_jiffies;
+ } while (read_seqretry_irqrestore(&xtime_lock, seq, flags));
+ usec = nsec / 1000 + lost * (1000000 / HZ);
+ while (usec >= 1000000) {
+ usec -= 1000000;
+ ++sec;
+ }
+ tv->tv_sec = sec;
+ tv->tv_usec = usec;
+ return;
+ }
__do_gettimeofday(tv, get_tb());
}
@@ -185,6 +224,8 @@ EXPORT_SYMBOL(do_gettimeofday);
static inline void timer_sync_xtime(unsigned long cur_tb)
{
+#ifdef CONFIG_PPC64
+ /* why do we do this? */
struct timeval my_tv;
__do_gettimeofday(&my_tv, cur_tb);
@@ -193,47 +234,76 @@ static inline void timer_sync_xtime(unsigned long cur_tb)
xtime.tv_sec = my_tv.tv_sec;
xtime.tv_nsec = my_tv.tv_usec * 1000;
}
+#endif
}
/*
- * When the timebase - tb_orig_stamp gets too big, we do a manipulation
- * between tb_orig_stamp and stamp_xsec. The goal here is to keep the
- * difference tb - tb_orig_stamp small enough to always fit inside a
- * 32 bits number. This is a requirement of our fast 32 bits userland
- * implementation in the vdso. If we "miss" a call to this function
- * (interrupt latency, CPU locked in a spinlock, ...) and we end up
- * with a too big difference, then the vdso will fallback to calling
- * the syscall
+ * There are two copies of tb_to_xs and stamp_xsec so that no
+ * lock is needed to access and use these values in
+ * do_gettimeofday. We alternate the copies and as long as a
+ * reasonable time elapses between changes, there will never
+ * be inconsistent values. ntpd has a minimum of one minute
+ * between updates.
*/
-static __inline__ void timer_recalc_offset(unsigned long cur_tb)
+static inline void update_gtod(u64 new_tb_stamp, u64 new_stamp_xsec,
+ u64 new_tb_to_xs)
{
- struct gettimeofday_vars * temp_varp;
unsigned temp_idx;
- unsigned long offset, new_stamp_xsec, new_tb_orig_stamp;
-
- if (((cur_tb - do_gtod.varp->tb_orig_stamp) & 0x80000000u) == 0)
- return;
+ struct gettimeofday_vars *temp_varp;
temp_idx = (do_gtod.var_idx == 0);
temp_varp = &do_gtod.vars[temp_idx];
- new_tb_orig_stamp = cur_tb;
- offset = new_tb_orig_stamp - do_gtod.varp->tb_orig_stamp;
- new_stamp_xsec = do_gtod.varp->stamp_xsec + mulhdu(offset, do_gtod.varp->tb_to_xs);
-
- temp_varp->tb_to_xs = do_gtod.varp->tb_to_xs;
- temp_varp->tb_orig_stamp = new_tb_orig_stamp;
+ temp_varp->tb_to_xs = new_tb_to_xs;
+ temp_varp->tb_orig_stamp = new_tb_stamp;
temp_varp->stamp_xsec = new_stamp_xsec;
smp_mb();
do_gtod.varp = temp_varp;
do_gtod.var_idx = temp_idx;
- ++(systemcfg->tb_update_count);
+#ifdef CONFIG_PPC64
+ /*
+ * tb_update_count is used to allow the userspace gettimeofday code
+ * to assure itself that it sees a consistent view of the tb_to_xs and
+ * stamp_xsec variables. It reads the tb_update_count, then reads
+ * tb_to_xs and stamp_xsec and then reads tb_update_count again. If
+ * the two values of tb_update_count match and are even then the
+ * tb_to_xs and stamp_xsec values are consistent. If not, then it
+ * loops back and reads them again until this criteria is met.
+ */
+ ++(_systemcfg->tb_update_count);
smp_wmb();
- systemcfg->tb_orig_stamp = new_tb_orig_stamp;
- systemcfg->stamp_xsec = new_stamp_xsec;
+ _systemcfg->tb_orig_stamp = new_tb_stamp;
+ _systemcfg->stamp_xsec = new_stamp_xsec;
+ _systemcfg->tb_to_xs = new_tb_to_xs;
smp_wmb();
- ++(systemcfg->tb_update_count);
+ ++(_systemcfg->tb_update_count);
+#endif
+}
+
+/*
+ * When the timebase - tb_orig_stamp gets too big, we do a manipulation
+ * between tb_orig_stamp and stamp_xsec. The goal here is to keep the
+ * difference tb - tb_orig_stamp small enough to always fit inside a
+ * 32 bits number. This is a requirement of our fast 32 bits userland
+ * implementation in the vdso. If we "miss" a call to this function
+ * (interrupt latency, CPU locked in a spinlock, ...) and we end up
+ * with a too big difference, then the vdso will fallback to calling
+ * the syscall
+ */
+static __inline__ void timer_recalc_offset(u64 cur_tb)
+{
+ unsigned long offset;
+ u64 new_stamp_xsec;
+
+ if (__USE_RTC())
+ return;
+ offset = cur_tb - do_gtod.varp->tb_orig_stamp;
+ if ((offset & 0x80000000u) == 0)
+ return;
+ new_stamp_xsec = do_gtod.varp->stamp_xsec
+ + mulhdu(offset, do_gtod.varp->tb_to_xs);
+ update_gtod(cur_tb, new_stamp_xsec, do_gtod.varp->tb_to_xs);
}
#ifdef CONFIG_SMP
@@ -287,8 +357,9 @@ static void iSeries_tb_recal(void)
do_gtod.tb_ticks_per_sec = tb_ticks_per_sec;
tb_to_xs = divres.result_low;
do_gtod.varp->tb_to_xs = tb_to_xs;
- systemcfg->tb_ticks_per_sec = tb_ticks_per_sec;
- systemcfg->tb_to_xs = tb_to_xs;
+ _systemcfg->tb_ticks_per_sec =
+ tb_ticks_per_sec;
+ _systemcfg->tb_to_xs = tb_to_xs;
}
else {
printk( "Titan recalibrate: FAILED (difference > 4 percent)\n"
@@ -313,26 +384,37 @@ static void iSeries_tb_recal(void)
* call will not be needed)
*/
-unsigned long tb_last_stamp __cacheline_aligned_in_smp;
-
/*
* timer_interrupt - gets called when the decrementer overflows,
* with interrupts disabled.
*/
-int timer_interrupt(struct pt_regs * regs)
+void timer_interrupt(struct pt_regs * regs)
{
int next_dec;
- unsigned long cur_tb;
- struct paca_struct *lpaca = get_paca();
- unsigned long cpu = smp_processor_id();
+ int cpu = smp_processor_id();
+ unsigned long ticks;
+
+#ifdef CONFIG_PPC32
+ if (atomic_read(&ppc_n_lost_interrupts) != 0)
+ do_IRQ(regs);
+#endif
irq_enter();
profile_tick(CPU_PROFILING, regs);
- lpaca->lppaca.int_dword.fields.decr_int = 0;
+#ifdef CONFIG_PPC_ISERIES
+ get_paca()->lppaca.int_dword.fields.decr_int = 0;
+#endif
+
+ while ((ticks = tb_ticks_since(per_cpu(last_jiffy, cpu)))
+ >= tb_ticks_per_jiffy) {
+ /* Update last_jiffy */
+ per_cpu(last_jiffy, cpu) += tb_ticks_per_jiffy;
+ /* Handle RTCL overflow on 601 */
+ if (__USE_RTC() && per_cpu(last_jiffy, cpu) >= 1000000000)
+ per_cpu(last_jiffy, cpu) -= 1000000000;
- while (lpaca->next_jiffy_update_tb <= (cur_tb = get_tb())) {
/*
* We cannot disable the decrementer, so in the period
* between this cpu's being marked offline in cpu_online_map
@@ -342,27 +424,27 @@ int timer_interrupt(struct pt_regs * regs)
*/
if (!cpu_is_offline(cpu))
update_process_times(user_mode(regs));
+
/*
* No need to check whether cpu is offline here; boot_cpuid
* should have been fixed up by now.
*/
- if (cpu == boot_cpuid) {
- write_seqlock(&xtime_lock);
- tb_last_stamp = lpaca->next_jiffy_update_tb;
- timer_recalc_offset(lpaca->next_jiffy_update_tb);
- do_timer(regs);
- timer_sync_xtime(lpaca->next_jiffy_update_tb);
- timer_check_rtc();
- write_sequnlock(&xtime_lock);
- if ( adjusting_time && (time_adjust == 0) )
- ppc_adjtimex();
- }
- lpaca->next_jiffy_update_tb += tb_ticks_per_jiffy;
+ if (cpu != boot_cpuid)
+ continue;
+
+ write_seqlock(&xtime_lock);
+ tb_last_jiffy += tb_ticks_per_jiffy;
+ tb_last_stamp = per_cpu(last_jiffy, cpu);
+ timer_recalc_offset(tb_last_jiffy);
+ do_timer(regs);
+ timer_sync_xtime(tb_last_jiffy);
+ timer_check_rtc();
+ write_sequnlock(&xtime_lock);
+ if (adjusting_time && (time_adjust == 0))
+ ppc_adjtimex();
}
- next_dec = lpaca->next_jiffy_update_tb - cur_tb;
- if (next_dec > lpaca->default_decr)
- next_dec = lpaca->default_decr;
+ next_dec = tb_ticks_per_jiffy - ticks;
set_dec(next_dec);
#ifdef CONFIG_PPC_ISERIES
@@ -370,16 +452,48 @@ int timer_interrupt(struct pt_regs * regs)
process_hvlpevents(regs);
#endif
+#ifdef CONFIG_PPC64
/* collect purr register values often, for accurate calculations */
if (firmware_has_feature(FW_FEATURE_SPLPAR)) {
struct cpu_usage *cu = &__get_cpu_var(cpu_usage_array);
cu->current_tb = mfspr(SPRN_PURR);
}
+#endif
irq_exit();
+}
- return 1;
+void wakeup_decrementer(void)
+{
+ int i;
+
+ set_dec(tb_ticks_per_jiffy);
+ /*
+ * We don't expect this to be called on a machine with a 601,
+ * so using get_tbl is fine.
+ */
+ tb_last_stamp = tb_last_jiffy = get_tb();
+ for_each_cpu(i)
+ per_cpu(last_jiffy, i) = tb_last_stamp;
+}
+
+#ifdef CONFIG_SMP
+void __init smp_space_timers(unsigned int max_cpus)
+{
+ int i;
+ unsigned long offset = tb_ticks_per_jiffy / max_cpus;
+ unsigned long previous_tb = per_cpu(last_jiffy, boot_cpuid);
+
+ /* make sure tb > per_cpu(last_jiffy, cpu) for all cpus always */
+ previous_tb -= tb_ticks_per_jiffy;
+ for_each_cpu(i) {
+ if (i != boot_cpuid) {
+ previous_tb += offset;
+ per_cpu(last_jiffy, i) = previous_tb;
+ }
+ }
}
+#endif
/*
* Scheduler clock - returns current time in nanosec units.
@@ -390,6 +504,8 @@ int timer_interrupt(struct pt_regs * regs)
*/
unsigned long long sched_clock(void)
{
+ if (__USE_RTC())
+ return get_rtc();
return mulhdu(get_tb(), tb_to_ns_scale) << tb_to_ns_shift;
}
@@ -398,31 +514,31 @@ int do_settimeofday(struct timespec *tv)
time_t wtm_sec, new_sec = tv->tv_sec;
long wtm_nsec, new_nsec = tv->tv_nsec;
unsigned long flags;
- unsigned long delta_xsec;
long int tb_delta;
- unsigned long new_xsec;
+ u64 new_xsec, tb_delta_xs;
if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC)
return -EINVAL;
write_seqlock_irqsave(&xtime_lock, flags);
- /* Updating the RTC is not the job of this code. If the time is
- * stepped under NTP, the RTC will be update after STA_UNSYNC
- * is cleared. Tool like clock/hwclock either copy the RTC
+
+ /*
+ * Updating the RTC is not the job of this code. If the time is
+ * stepped under NTP, the RTC will be updated after STA_UNSYNC
+ * is cleared. Tools like clock/hwclock either copy the RTC
* to the system time, in which case there is no point in writing
* to the RTC again, or write to the RTC but then they don't call
* settimeofday to perform this operation.
*/
#ifdef CONFIG_PPC_ISERIES
- if ( first_settimeofday ) {
+ if (first_settimeofday) {
iSeries_tb_recal();
first_settimeofday = 0;
}
#endif
tb_delta = tb_ticks_since(tb_last_stamp);
tb_delta += (jiffies - wall_jiffies) * tb_ticks_per_jiffy;
-
- new_nsec -= tb_delta / tb_ticks_per_usec / 1000;
+ tb_delta_xs = mulhdu(tb_delta, do_gtod.varp->tb_to_xs);
wtm_sec = wall_to_monotonic.tv_sec + (xtime.tv_sec - new_sec);
wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - new_nsec);
@@ -437,28 +553,18 @@ int do_settimeofday(struct timespec *tv)
ntp_clear();
- delta_xsec = mulhdu( (tb_last_stamp-do_gtod.varp->tb_orig_stamp),
- do_gtod.varp->tb_to_xs );
-
- new_xsec = (new_nsec * XSEC_PER_SEC) / NSEC_PER_SEC;
- new_xsec += new_sec * XSEC_PER_SEC;
- if ( new_xsec > delta_xsec ) {
- do_gtod.varp->stamp_xsec = new_xsec - delta_xsec;
- systemcfg->stamp_xsec = new_xsec - delta_xsec;
- }
- else {
- /* This is only for the case where the user is setting the time
- * way back to a time such that the boot time would have been
- * before 1970 ... eg. we booted ten days ago, and we are setting
- * the time to Jan 5, 1970 */
- do_gtod.varp->stamp_xsec = new_xsec;
- do_gtod.varp->tb_orig_stamp = tb_last_stamp;
- systemcfg->stamp_xsec = new_xsec;
- systemcfg->tb_orig_stamp = tb_last_stamp;
+ new_xsec = 0;
+ if (new_nsec != 0) {
+ new_xsec = (u64)new_nsec * XSEC_PER_SEC;
+ do_div(new_xsec, NSEC_PER_SEC);
}
+ new_xsec += (u64)new_sec * XSEC_PER_SEC - tb_delta_xs;
+ update_gtod(tb_last_jiffy, new_xsec, do_gtod.varp->tb_to_xs);
- systemcfg->tz_minuteswest = sys_tz.tz_minuteswest;
- systemcfg->tz_dsttime = sys_tz.tz_dsttime;
+#ifdef CONFIG_PPC64
+ _systemcfg->tz_minuteswest = sys_tz.tz_minuteswest;
+ _systemcfg->tz_dsttime = sys_tz.tz_dsttime;
+#endif
write_sequnlock_irqrestore(&xtime_lock, flags);
clock_was_set();
@@ -467,11 +573,9 @@ int do_settimeofday(struct timespec *tv)
EXPORT_SYMBOL(do_settimeofday);
-#if defined(CONFIG_PPC_PSERIES) || defined(CONFIG_PPC_MAPLE) || defined(CONFIG_PPC_BPA)
void __init generic_calibrate_decr(void)
{
struct device_node *cpu;
- struct div_result divres;
unsigned int *fp;
int node_found;
@@ -505,37 +609,74 @@ void __init generic_calibrate_decr(void)
ppc_proc_freq = *fp;
}
}
+#ifdef CONFIG_BOOKE
+ /* Set the time base to zero */
+ mtspr(SPRN_TBWL, 0);
+ mtspr(SPRN_TBWU, 0);
+
+ /* Clear any pending timer interrupts */
+ mtspr(SPRN_TSR, TSR_ENW | TSR_WIS | TSR_DIS | TSR_FIS);
+
+ /* Enable decrementer interrupt */
+ mtspr(SPRN_TCR, TCR_DIE);
+#endif
if (!node_found)
printk(KERN_ERR "WARNING: Estimating processor frequency "
"(not found)\n");
of_node_put(cpu);
+}
- printk(KERN_INFO "time_init: decrementer frequency = %lu.%.6lu MHz\n",
- ppc_tb_freq/1000000, ppc_tb_freq%1000000);
- printk(KERN_INFO "time_init: processor frequency = %lu.%.6lu MHz\n",
- ppc_proc_freq/1000000, ppc_proc_freq%1000000);
-
- tb_ticks_per_jiffy = ppc_tb_freq / HZ;
- tb_ticks_per_sec = tb_ticks_per_jiffy * HZ;
- tb_ticks_per_usec = ppc_tb_freq / 1000000;
- tb_to_us = mulhwu_scale_factor(ppc_tb_freq, 1000000);
- div128_by_32(1024*1024, 0, tb_ticks_per_sec, &divres);
- tb_to_xs = divres.result_low;
+unsigned long get_boot_time(void)
+{
+ struct rtc_time tm;
- setup_default_decr();
+ if (ppc_md.get_boot_time)
+ return ppc_md.get_boot_time();
+ if (!ppc_md.get_rtc_time)
+ return 0;
+ ppc_md.get_rtc_time(&tm);
+ return mktime(tm.tm_year+1900, tm.tm_mon+1, tm.tm_mday,
+ tm.tm_hour, tm.tm_min, tm.tm_sec);
}
-#endif
+/* This function is only called on the boot processor */
void __init time_init(void)
{
- /* This function is only called on the boot processor */
unsigned long flags;
- struct rtc_time tm;
+ unsigned long tm = 0;
struct div_result res;
- unsigned long scale, shift;
+ u64 scale;
+ unsigned shift;
+
+ if (ppc_md.time_init != NULL)
+ timezone_offset = ppc_md.time_init();
+
+ if (__USE_RTC()) {
+ /* 601 processor: dec counts down by 128 every 128ns */
+ ppc_tb_freq = 1000000000;
+ tb_last_stamp = get_rtcl();
+ tb_last_jiffy = tb_last_stamp;
+ } else {
+ /* Normal PowerPC with timebase register */
+ ppc_md.calibrate_decr();
+ printk(KERN_INFO "time_init: decrementer frequency = %lu.%.6lu MHz\n",
+ ppc_tb_freq / 1000000, ppc_tb_freq % 1000000);
+ printk(KERN_INFO "time_init: processor frequency = %lu.%.6lu MHz\n",
+ ppc_proc_freq / 1000000, ppc_proc_freq % 1000000);
+ tb_last_stamp = tb_last_jiffy = get_tb();
+ }
- ppc_md.calibrate_decr();
+ tb_ticks_per_jiffy = ppc_tb_freq / HZ;
+ tb_ticks_per_sec = tb_ticks_per_jiffy * HZ;
+ tb_ticks_per_usec = ppc_tb_freq / 1000000;
+ tb_to_us = mulhwu_scale_factor(ppc_tb_freq, 1000000);
+ div128_by_32(1024*1024, 0, tb_ticks_per_sec, &res);
+ tb_to_xs = res.result_low;
+
+#ifdef CONFIG_PPC64
+ get_paca()->default_decr = tb_ticks_per_jiffy;
+#endif
/*
* Compute scale factor for sched_clock.
@@ -559,29 +700,36 @@ void __init time_init(void)
#ifdef CONFIG_PPC_ISERIES
if (!piranha_simulator)
#endif
- ppc_md.get_boot_time(&tm);
+ tm = get_boot_time();
write_seqlock_irqsave(&xtime_lock, flags);
- xtime.tv_sec = mktime(tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
- tm.tm_hour, tm.tm_min, tm.tm_sec);
- tb_last_stamp = get_tb();
+ xtime.tv_sec = tm;
+ xtime.tv_nsec = 0;
do_gtod.varp = &do_gtod.vars[0];
do_gtod.var_idx = 0;
- do_gtod.varp->tb_orig_stamp = tb_last_stamp;
- get_paca()->next_jiffy_update_tb = tb_last_stamp + tb_ticks_per_jiffy;
- do_gtod.varp->stamp_xsec = xtime.tv_sec * XSEC_PER_SEC;
+ do_gtod.varp->tb_orig_stamp = tb_last_jiffy;
+ __get_cpu_var(last_jiffy) = tb_last_stamp;
+ do_gtod.varp->stamp_xsec = (u64) xtime.tv_sec * XSEC_PER_SEC;
do_gtod.tb_ticks_per_sec = tb_ticks_per_sec;
do_gtod.varp->tb_to_xs = tb_to_xs;
do_gtod.tb_to_us = tb_to_us;
- systemcfg->tb_orig_stamp = tb_last_stamp;
- systemcfg->tb_update_count = 0;
- systemcfg->tb_ticks_per_sec = tb_ticks_per_sec;
- systemcfg->stamp_xsec = xtime.tv_sec * XSEC_PER_SEC;
- systemcfg->tb_to_xs = tb_to_xs;
+#ifdef CONFIG_PPC64
+ _systemcfg->tb_orig_stamp = tb_last_jiffy;
+ _systemcfg->tb_update_count = 0;
+ _systemcfg->tb_ticks_per_sec = tb_ticks_per_sec;
+ _systemcfg->stamp_xsec = xtime.tv_sec * XSEC_PER_SEC;
+ _systemcfg->tb_to_xs = tb_to_xs;
+#endif
time_freq = 0;
- xtime.tv_nsec = 0;
+ /* If platform provided a timezone (pmac), we correct the time */
+ if (timezone_offset) {
+ sys_tz.tz_minuteswest = -timezone_offset / 60;
+ sys_tz.tz_dsttime = 0;
+ xtime.tv_sec -= timezone_offset;
+ }
+
last_rtc_update = xtime.tv_sec;
set_normalized_timespec(&wall_to_monotonic,
-xtime.tv_sec, -xtime.tv_nsec);
@@ -604,25 +752,28 @@ void __init time_init(void)
void ppc_adjtimex(void)
{
- unsigned long den, new_tb_ticks_per_sec, tb_ticks, old_xsec, new_tb_to_xs, new_xsec, new_stamp_xsec;
+#ifdef CONFIG_PPC64
+ unsigned long den, new_tb_ticks_per_sec, tb_ticks, old_xsec,
+ new_tb_to_xs, new_xsec, new_stamp_xsec;
unsigned long tb_ticks_per_sec_delta;
long delta_freq, ltemp;
struct div_result divres;
unsigned long flags;
- struct gettimeofday_vars * temp_varp;
- unsigned temp_idx;
long singleshot_ppm = 0;
- /* Compute parts per million frequency adjustment to accomplish the time adjustment
- implied by time_offset to be applied over the elapsed time indicated by time_constant.
- Use SHIFT_USEC to get it into the same units as time_freq. */
+ /*
+ * Compute parts per million frequency adjustment to
+ * accomplish the time adjustment implied by time_offset to be
+ * applied over the elapsed time indicated by time_constant.
+ * Use SHIFT_USEC to get it into the same units as
+ * time_freq.
+ */
if ( time_offset < 0 ) {
ltemp = -time_offset;
ltemp <<= SHIFT_USEC - SHIFT_UPDATE;
ltemp >>= SHIFT_KG + time_constant;
ltemp = -ltemp;
- }
- else {
+ } else {
ltemp = time_offset;
ltemp <<= SHIFT_USEC - SHIFT_UPDATE;
ltemp >>= SHIFT_KG + time_constant;
@@ -639,7 +790,10 @@ void ppc_adjtimex(void)
adjusting_time = 1;
- /* Compute parts per million frequency adjustment to match time_adjust */
+ /*
+ * Compute parts per million frequency adjustment
+ * to match time_adjust
+ */
singleshot_ppm = tickadj * HZ;
/*
* The adjustment should be tickadj*HZ to match the code in
@@ -647,7 +801,7 @@ void ppc_adjtimex(void)
* large. 3/4 of tickadj*HZ seems about right
*/
singleshot_ppm -= singleshot_ppm / 4;
- /* Use SHIFT_USEC to get it into the same units as time_freq */
+ /* Use SHIFT_USEC to get it into the same units as time_freq */
singleshot_ppm <<= SHIFT_USEC;
if ( time_adjust < 0 )
singleshot_ppm = -singleshot_ppm;
@@ -663,7 +817,10 @@ void ppc_adjtimex(void)
/* Add up all of the frequency adjustments */
delta_freq = time_freq + ltemp + singleshot_ppm;
- /* Compute a new value for tb_ticks_per_sec based on the frequency adjustment */
+ /*
+ * Compute a new value for tb_ticks_per_sec based on
+ * the frequency adjustment
+ */
den = 1000000 * (1 << (SHIFT_USEC - 8));
if ( delta_freq < 0 ) {
tb_ticks_per_sec_delta = ( tb_ticks_per_sec * ( (-delta_freq) >> (SHIFT_USEC - 8))) / den;
@@ -678,61 +835,37 @@ void ppc_adjtimex(void)
printk("ppc_adjtimex: ltemp = %ld, time_freq = %ld, singleshot_ppm = %ld\n", ltemp, time_freq, singleshot_ppm);
printk("ppc_adjtimex: tb_ticks_per_sec - base = %ld new = %ld\n", tb_ticks_per_sec, new_tb_ticks_per_sec);
#endif
-
- /* Compute a new value of tb_to_xs (used to convert tb to microseconds and a new value of
- stamp_xsec which is the time (in 1/2^20 second units) corresponding to tb_orig_stamp. This
- new value of stamp_xsec compensates for the change in frequency (implied by the new tb_to_xs)
- which guarantees that the current time remains the same */
+
+ /*
+ * Compute a new value of tb_to_xs (used to convert tb to
+ * microseconds) and a new value of stamp_xsec which is the
+ * time (in 1/2^20 second units) corresponding to
+ * tb_orig_stamp. This new value of stamp_xsec compensates
+ * for the change in frequency (implied by the new tb_to_xs)
+ * which guarantees that the current time remains the same.
+ */
write_seqlock_irqsave( &xtime_lock, flags );
tb_ticks = get_tb() - do_gtod.varp->tb_orig_stamp;
- div128_by_32( 1024*1024, 0, new_tb_ticks_per_sec, &divres );
+ div128_by_32(1024*1024, 0, new_tb_ticks_per_sec, &divres);
new_tb_to_xs = divres.result_low;
- new_xsec = mulhdu( tb_ticks, new_tb_to_xs );
+ new_xsec = mulhdu(tb_ticks, new_tb_to_xs);
- old_xsec = mulhdu( tb_ticks, do_gtod.varp->tb_to_xs );
+ old_xsec = mulhdu(tb_ticks, do_gtod.varp->tb_to_xs);
new_stamp_xsec = do_gtod.varp->stamp_xsec + old_xsec - new_xsec;
- /* There are two copies of tb_to_xs and stamp_xsec so that no lock is needed to access and use these
- values in do_gettimeofday. We alternate the copies and as long as a reasonable time elapses between
- changes, there will never be inconsistent values. ntpd has a minimum of one minute between updates */
-
- temp_idx = (do_gtod.var_idx == 0);
- temp_varp = &do_gtod.vars[temp_idx];
-
- temp_varp->tb_to_xs = new_tb_to_xs;
- temp_varp->stamp_xsec = new_stamp_xsec;
- temp_varp->tb_orig_stamp = do_gtod.varp->tb_orig_stamp;
- smp_mb();
- do_gtod.varp = temp_varp;
- do_gtod.var_idx = temp_idx;
-
- /*
- * tb_update_count is used to allow the problem state gettimeofday code
- * to assure itself that it sees a consistent view of the tb_to_xs and
- * stamp_xsec variables. It reads the tb_update_count, then reads
- * tb_to_xs and stamp_xsec and then reads tb_update_count again. If
- * the two values of tb_update_count match and are even then the
- * tb_to_xs and stamp_xsec values are consistent. If not, then it
- * loops back and reads them again until this criteria is met.
- */
- ++(systemcfg->tb_update_count);
- smp_wmb();
- systemcfg->tb_to_xs = new_tb_to_xs;
- systemcfg->stamp_xsec = new_stamp_xsec;
- smp_wmb();
- ++(systemcfg->tb_update_count);
+ update_gtod(do_gtod.varp->tb_orig_stamp, new_stamp_xsec, new_tb_to_xs);
write_sequnlock_irqrestore( &xtime_lock, flags );
-
+#endif /* CONFIG_PPC64 */
}
-#define TICK_SIZE tick
#define FEBRUARY 2
#define STARTOFTIME 1970
#define SECDAY 86400L
#define SECYR (SECDAY * 365)
-#define leapyear(year) ((year) % 4 == 0)
+#define leapyear(year) ((year) % 4 == 0 && \
+ ((year) % 100 != 0 || (year) % 400 == 0))
#define days_in_year(a) (leapyear(a) ? 366 : 365)
#define days_in_month(a) (month_days[(a) - 1])
@@ -750,37 +883,25 @@ void GregorianDay(struct rtc_time * tm)
int day;
int MonthOffset[] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
- lastYear=tm->tm_year-1;
+ lastYear = tm->tm_year - 1;
/*
* Number of leap corrections to apply up to end of last year
*/
- leapsToDate = lastYear/4 - lastYear/100 + lastYear/400;
+ leapsToDate = lastYear / 4 - lastYear / 100 + lastYear / 400;
/*
* This year is a leap year if it is divisible by 4 except when it is
* divisible by 100 unless it is divisible by 400
*
- * e.g. 1904 was a leap year, 1900 was not, 1996 is, and 2000 will be
+ * e.g. 1904 was a leap year, 1900 was not, 1996 is, and 2000 was
*/
- if((tm->tm_year%4==0) &&
- ((tm->tm_year%100!=0) || (tm->tm_year%400==0)) &&
- (tm->tm_mon>2))
- {
- /*
- * We are past Feb. 29 in a leap year
- */
- day=1;
- }
- else
- {
- day=0;
- }
+ day = tm->tm_mon > 2 && leapyear(tm->tm_year);
day += lastYear*365 + leapsToDate + MonthOffset[tm->tm_mon-1] +
tm->tm_mday;
- tm->tm_wday=day%7;
+ tm->tm_wday = day % 7;
}
void to_tm(int tim, struct rtc_time * tm)
@@ -826,14 +947,16 @@ void to_tm(int tim, struct rtc_time * tm)
* oscillators and the precision with which the timebase frequency
* is measured but does not harm.
*/
-unsigned mulhwu_scale_factor(unsigned inscale, unsigned outscale) {
+unsigned mulhwu_scale_factor(unsigned inscale, unsigned outscale)
+{
unsigned mlt=0, tmp, err;
/* No concern for performance, it's done once: use a stupid
* but safe and compact method to find the multiplier.
*/
for (tmp = 1U<<31; tmp != 0; tmp >>= 1) {
- if (mulhwu(inscale, mlt|tmp) < outscale) mlt|=tmp;
+ if (mulhwu(inscale, mlt|tmp) < outscale)
+ mlt |= tmp;
}
/* We might still be off by 1 for the best approximation.
@@ -843,39 +966,41 @@ unsigned mulhwu_scale_factor(unsigned inscale, unsigned outscale) {
* some might have been forgotten in the test however.
*/
- err = inscale*(mlt+1);
- if (err <= inscale/2) mlt++;
+ err = inscale * (mlt+1);
+ if (err <= inscale/2)
+ mlt++;
return mlt;
- }
+}
/*
* Divide a 128-bit dividend by a 32-bit divisor, leaving a 128 bit
* result.
*/
-
-void div128_by_32( unsigned long dividend_high, unsigned long dividend_low,
- unsigned divisor, struct div_result *dr )
+void div128_by_32(u64 dividend_high, u64 dividend_low,
+ unsigned divisor, struct div_result *dr)
{
- unsigned long a,b,c,d, w,x,y,z, ra,rb,rc;
+ unsigned long a, b, c, d;
+ unsigned long w, x, y, z;
+ u64 ra, rb, rc;
a = dividend_high >> 32;
b = dividend_high & 0xffffffff;
c = dividend_low >> 32;
d = dividend_low & 0xffffffff;
- w = a/divisor;
- ra = (a - (w * divisor)) << 32;
+ w = a / divisor;
+ ra = ((u64)(a - (w * divisor)) << 32) + b;
- x = (ra + b)/divisor;
- rb = ((ra + b) - (x * divisor)) << 32;
+ rb = ((u64) do_div(ra, divisor) << 32) + c;
+ x = ra;
- y = (rb + c)/divisor;
- rc = ((rb + c) - (y * divisor)) << 32;
+ rc = ((u64) do_div(rb, divisor) << 32) + d;
+ y = rb;
- z = (rc + d)/divisor;
+ do_div(rc, divisor);
+ z = rc;
- dr->result_high = (w << 32) + x;
- dr->result_low = (y << 32) + z;
+ dr->result_high = ((u64)w << 32) + x;
+ dr->result_low = ((u64)y << 32) + z;
}
-
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
new file mode 100644
index 000000000000..2020bb7648fb
--- /dev/null
+++ b/arch/powerpc/kernel/traps.c
@@ -0,0 +1,1086 @@
+/*
+ * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.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 by Cort Dougan (cort@cs.nmt.edu)
+ * and Paul Mackerras (paulus@samba.org)
+ */
+
+/*
+ * This file handles the architecture-dependent parts of hardware exceptions
+ */
+
+#include <linux/config.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/stddef.h>
+#include <linux/unistd.h>
+#include <linux/ptrace.h>
+#include <linux/slab.h>
+#include <linux/user.h>
+#include <linux/a.out.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/prctl.h>
+#include <linux/delay.h>
+#include <linux/kprobes.h>
+
+#include <asm/kdebug.h>
+#include <asm/pgtable.h>
+#include <asm/uaccess.h>
+#include <asm/system.h>
+#include <asm/io.h>
+#include <asm/machdep.h>
+#include <asm/rtas.h>
+#include <asm/pmc.h>
+#ifdef CONFIG_PPC32
+#include <asm/reg.h>
+#endif
+#ifdef CONFIG_PMAC_BACKLIGHT
+#include <asm/backlight.h>
+#endif
+#ifdef CONFIG_PPC64
+#include <asm/firmware.h>
+#include <asm/processor.h>
+#include <asm/systemcfg.h>
+#endif
+
+#ifdef CONFIG_PPC64 /* XXX */
+#define _IO_BASE pci_io_base
+#endif
+
+#ifdef CONFIG_DEBUGGER
+int (*__debugger)(struct pt_regs *regs);
+int (*__debugger_ipi)(struct pt_regs *regs);
+int (*__debugger_bpt)(struct pt_regs *regs);
+int (*__debugger_sstep)(struct pt_regs *regs);
+int (*__debugger_iabr_match)(struct pt_regs *regs);
+int (*__debugger_dabr_match)(struct pt_regs *regs);
+int (*__debugger_fault_handler)(struct pt_regs *regs);
+
+EXPORT_SYMBOL(__debugger);
+EXPORT_SYMBOL(__debugger_ipi);
+EXPORT_SYMBOL(__debugger_bpt);
+EXPORT_SYMBOL(__debugger_sstep);
+EXPORT_SYMBOL(__debugger_iabr_match);
+EXPORT_SYMBOL(__debugger_dabr_match);
+EXPORT_SYMBOL(__debugger_fault_handler);
+#endif
+
+struct notifier_block *powerpc_die_chain;
+static DEFINE_SPINLOCK(die_notifier_lock);
+
+int register_die_notifier(struct notifier_block *nb)
+{
+ int err = 0;
+ unsigned long flags;
+
+ spin_lock_irqsave(&die_notifier_lock, flags);
+ err = notifier_chain_register(&powerpc_die_chain, nb);
+ spin_unlock_irqrestore(&die_notifier_lock, flags);
+ return err;
+}
+
+/*
+ * Trap & Exception support
+ */
+
+static DEFINE_SPINLOCK(die_lock);
+
+int die(const char *str, struct pt_regs *regs, long err)
+{
+ static int die_counter;
+ int nl = 0;
+
+ if (debugger(regs))
+ return 1;
+
+ console_verbose();
+ spin_lock_irq(&die_lock);
+ bust_spinlocks(1);
+#ifdef CONFIG_PMAC_BACKLIGHT
+ if (_machine == _MACH_Pmac) {
+ set_backlight_enable(1);
+ set_backlight_level(BACKLIGHT_MAX);
+ }
+#endif
+ printk("Oops: %s, sig: %ld [#%d]\n", str, err, ++die_counter);
+#ifdef CONFIG_PREEMPT
+ printk("PREEMPT ");
+ nl = 1;
+#endif
+#ifdef CONFIG_SMP
+ printk("SMP NR_CPUS=%d ", NR_CPUS);
+ nl = 1;
+#endif
+#ifdef CONFIG_DEBUG_PAGEALLOC
+ printk("DEBUG_PAGEALLOC ");
+ nl = 1;
+#endif
+#ifdef CONFIG_NUMA
+ printk("NUMA ");
+ nl = 1;
+#endif
+#ifdef CONFIG_PPC64
+ switch (_machine) {
+ case PLATFORM_PSERIES:
+ printk("PSERIES ");
+ nl = 1;
+ break;
+ case PLATFORM_PSERIES_LPAR:
+ printk("PSERIES LPAR ");
+ nl = 1;
+ break;
+ case PLATFORM_ISERIES_LPAR:
+ printk("ISERIES LPAR ");
+ nl = 1;
+ break;
+ case PLATFORM_POWERMAC:
+ printk("POWERMAC ");
+ nl = 1;
+ break;
+ case PLATFORM_CELL:
+ printk("CELL ");
+ nl = 1;
+ break;
+ }
+#endif
+ if (nl)
+ printk("\n");
+ print_modules();
+ show_regs(regs);
+ bust_spinlocks(0);
+ spin_unlock_irq(&die_lock);
+
+ if (in_interrupt())
+ panic("Fatal exception in interrupt");
+
+ if (panic_on_oops) {
+#ifdef CONFIG_PPC64
+ printk(KERN_EMERG "Fatal exception: panic in 5 seconds\n");
+ ssleep(5);
+#endif
+ panic("Fatal exception");
+ }
+ do_exit(err);
+
+ return 0;
+}
+
+void _exception(int signr, struct pt_regs *regs, int code, unsigned long addr)
+{
+ siginfo_t info;
+
+ if (!user_mode(regs)) {
+ if (die("Exception in kernel mode", regs, signr))
+ return;
+ }
+
+ memset(&info, 0, sizeof(info));
+ info.si_signo = signr;
+ info.si_code = code;
+ info.si_addr = (void __user *) addr;
+ force_sig_info(signr, &info, current);
+
+ /*
+ * Init gets no signals that it doesn't have a handler for.
+ * That's all very well, but if it has caused a synchronous
+ * exception and we ignore the resulting signal, it will just
+ * generate the same exception over and over again and we get
+ * nowhere. Better to kill it and let the kernel panic.
+ */
+ if (current->pid == 1) {
+ __sighandler_t handler;
+
+ spin_lock_irq(&current->sighand->siglock);
+ handler = current->sighand->action[signr-1].sa.sa_handler;
+ spin_unlock_irq(&current->sighand->siglock);
+ if (handler == SIG_DFL) {
+ /* init has generated a synchronous exception
+ and it doesn't have a handler for the signal */
+ printk(KERN_CRIT "init has generated signal %d "
+ "but has no handler for it\n", signr);
+ do_exit(signr);
+ }
+ }
+}
+
+#ifdef CONFIG_PPC64
+void system_reset_exception(struct pt_regs *regs)
+{
+ /* See if any machine dependent calls */
+ if (ppc_md.system_reset_exception)
+ ppc_md.system_reset_exception(regs);
+
+ die("System Reset", regs, SIGABRT);
+
+ /* Must die if the interrupt is not recoverable */
+ if (!(regs->msr & MSR_RI))
+ panic("Unrecoverable System Reset");
+
+ /* What should we do here? We could issue a shutdown or hard reset. */
+}
+#endif
+
+/*
+ * I/O accesses can cause machine checks on powermacs.
+ * Check if the NIP corresponds to the address of a sync
+ * instruction for which there is an entry in the exception
+ * table.
+ * Note that the 601 only takes a machine check on TEA
+ * (transfer error ack) signal assertion, and does not
+ * set any of the top 16 bits of SRR1.
+ * -- paulus.
+ */
+static inline int check_io_access(struct pt_regs *regs)
+{
+#ifdef CONFIG_PPC_PMAC
+ unsigned long msr = regs->msr;
+ const struct exception_table_entry *entry;
+ unsigned int *nip = (unsigned int *)regs->nip;
+
+ if (((msr & 0xffff0000) == 0 || (msr & (0x80000 | 0x40000)))
+ && (entry = search_exception_tables(regs->nip)) != NULL) {
+ /*
+ * Check that it's a sync instruction, or somewhere
+ * in the twi; isync; nop sequence that inb/inw/inl uses.
+ * As the address is in the exception table
+ * we should be able to read the instr there.
+ * For the debug message, we look at the preceding
+ * load or store.
+ */
+ if (*nip == 0x60000000) /* nop */
+ nip -= 2;
+ else if (*nip == 0x4c00012c) /* isync */
+ --nip;
+ if (*nip == 0x7c0004ac || (*nip >> 26) == 3) {
+ /* sync or twi */
+ unsigned int rb;
+
+ --nip;
+ rb = (*nip >> 11) & 0x1f;
+ printk(KERN_DEBUG "%s bad port %lx at %p\n",
+ (*nip & 0x100)? "OUT to": "IN from",
+ regs->gpr[rb] - _IO_BASE, nip);
+ regs->msr |= MSR_RI;
+ regs->nip = entry->fixup;
+ return 1;
+ }
+ }
+#endif /* CONFIG_PPC_PMAC */
+ return 0;
+}
+
+#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
+/* On 4xx, the reason for the machine check or program exception
+ is in the ESR. */
+#define get_reason(regs) ((regs)->dsisr)
+#ifndef CONFIG_FSL_BOOKE
+#define get_mc_reason(regs) ((regs)->dsisr)
+#else
+#define get_mc_reason(regs) (mfspr(SPRN_MCSR))
+#endif
+#define REASON_FP ESR_FP
+#define REASON_ILLEGAL (ESR_PIL | ESR_PUO)
+#define REASON_PRIVILEGED ESR_PPR
+#define REASON_TRAP ESR_PTR
+
+/* single-step stuff */
+#define single_stepping(regs) (current->thread.dbcr0 & DBCR0_IC)
+#define clear_single_step(regs) (current->thread.dbcr0 &= ~DBCR0_IC)
+
+#else
+/* On non-4xx, the reason for the machine check or program
+ exception is in the MSR. */
+#define get_reason(regs) ((regs)->msr)
+#define get_mc_reason(regs) ((regs)->msr)
+#define REASON_FP 0x100000
+#define REASON_ILLEGAL 0x80000
+#define REASON_PRIVILEGED 0x40000
+#define REASON_TRAP 0x20000
+
+#define single_stepping(regs) ((regs)->msr & MSR_SE)
+#define clear_single_step(regs) ((regs)->msr &= ~MSR_SE)
+#endif
+
+/*
+ * This is "fall-back" implementation for configurations
+ * which don't provide platform-specific machine check info
+ */
+void __attribute__ ((weak))
+platform_machine_check(struct pt_regs *regs)
+{
+}
+
+void machine_check_exception(struct pt_regs *regs)
+{
+#ifdef CONFIG_PPC64
+ int recover = 0;
+
+ /* See if any machine dependent calls */
+ if (ppc_md.machine_check_exception)
+ recover = ppc_md.machine_check_exception(regs);
+
+ if (recover)
+ return;
+#else
+ unsigned long reason = get_mc_reason(regs);
+
+ if (user_mode(regs)) {
+ regs->msr |= MSR_RI;
+ _exception(SIGBUS, regs, BUS_ADRERR, regs->nip);
+ return;
+ }
+
+#if defined(CONFIG_8xx) && defined(CONFIG_PCI)
+ /* the qspan pci read routines can cause machine checks -- Cort */
+ bad_page_fault(regs, regs->dar, SIGBUS);
+ return;
+#endif
+
+ if (debugger_fault_handler(regs)) {
+ regs->msr |= MSR_RI;
+ return;
+ }
+
+ if (check_io_access(regs))
+ return;
+
+#if defined(CONFIG_4xx) && !defined(CONFIG_440A)
+ if (reason & ESR_IMCP) {
+ printk("Instruction");
+ mtspr(SPRN_ESR, reason & ~ESR_IMCP);
+ } else
+ printk("Data");
+ printk(" machine check in kernel mode.\n");
+#elif defined(CONFIG_440A)
+ printk("Machine check in kernel mode.\n");
+ if (reason & ESR_IMCP){
+ printk("Instruction Synchronous Machine Check exception\n");
+ mtspr(SPRN_ESR, reason & ~ESR_IMCP);
+ }
+ else {
+ u32 mcsr = mfspr(SPRN_MCSR);
+ if (mcsr & MCSR_IB)
+ printk("Instruction Read PLB Error\n");
+ if (mcsr & MCSR_DRB)
+ printk("Data Read PLB Error\n");
+ if (mcsr & MCSR_DWB)
+ printk("Data Write PLB Error\n");
+ if (mcsr & MCSR_TLBP)
+ printk("TLB Parity Error\n");
+ if (mcsr & MCSR_ICP){
+ flush_instruction_cache();
+ printk("I-Cache Parity Error\n");
+ }
+ if (mcsr & MCSR_DCSP)
+ printk("D-Cache Search Parity Error\n");
+ if (mcsr & MCSR_DCFP)
+ printk("D-Cache Flush Parity Error\n");
+ if (mcsr & MCSR_IMPE)
+ printk("Machine Check exception is imprecise\n");
+
+ /* Clear MCSR */
+ mtspr(SPRN_MCSR, mcsr);
+ }
+#elif defined (CONFIG_E500)
+ printk("Machine check in kernel mode.\n");
+ printk("Caused by (from MCSR=%lx): ", reason);
+
+ if (reason & MCSR_MCP)
+ printk("Machine Check Signal\n");
+ if (reason & MCSR_ICPERR)
+ printk("Instruction Cache Parity Error\n");
+ if (reason & MCSR_DCP_PERR)
+ printk("Data Cache Push Parity Error\n");
+ if (reason & MCSR_DCPERR)
+ printk("Data Cache Parity Error\n");
+ if (reason & MCSR_GL_CI)
+ printk("Guarded Load or Cache-Inhibited stwcx.\n");
+ if (reason & MCSR_BUS_IAERR)
+ printk("Bus - Instruction Address Error\n");
+ if (reason & MCSR_BUS_RAERR)
+ printk("Bus - Read Address Error\n");
+ if (reason & MCSR_BUS_WAERR)
+ printk("Bus - Write Address Error\n");
+ if (reason & MCSR_BUS_IBERR)
+ printk("Bus - Instruction Data Error\n");
+ if (reason & MCSR_BUS_RBERR)
+ printk("Bus - Read Data Bus Error\n");
+ if (reason & MCSR_BUS_WBERR)
+ printk("Bus - Read Data Bus Error\n");
+ if (reason & MCSR_BUS_IPERR)
+ printk("Bus - Instruction Parity Error\n");
+ if (reason & MCSR_BUS_RPERR)
+ printk("Bus - Read Parity Error\n");
+#elif defined (CONFIG_E200)
+ printk("Machine check in kernel mode.\n");
+ printk("Caused by (from MCSR=%lx): ", reason);
+
+ if (reason & MCSR_MCP)
+ printk("Machine Check Signal\n");
+ if (reason & MCSR_CP_PERR)
+ printk("Cache Push Parity Error\n");
+ if (reason & MCSR_CPERR)
+ printk("Cache Parity Error\n");
+ if (reason & MCSR_EXCP_ERR)
+ printk("ISI, ITLB, or Bus Error on first instruction fetch for an exception handler\n");
+ if (reason & MCSR_BUS_IRERR)
+ printk("Bus - Read Bus Error on instruction fetch\n");
+ if (reason & MCSR_BUS_DRERR)
+ printk("Bus - Read Bus Error on data load\n");
+ if (reason & MCSR_BUS_WRERR)
+ printk("Bus - Write Bus Error on buffered store or cache line push\n");
+#else /* !CONFIG_4xx && !CONFIG_E500 && !CONFIG_E200 */
+ printk("Machine check in kernel mode.\n");
+ printk("Caused by (from SRR1=%lx): ", reason);
+ switch (reason & 0x601F0000) {
+ case 0x80000:
+ printk("Machine check signal\n");
+ break;
+ case 0: /* for 601 */
+ case 0x40000:
+ case 0x140000: /* 7450 MSS error and TEA */
+ printk("Transfer error ack signal\n");
+ break;
+ case 0x20000:
+ printk("Data parity error signal\n");
+ break;
+ case 0x10000:
+ printk("Address parity error signal\n");
+ break;
+ case 0x20000000:
+ printk("L1 Data Cache error\n");
+ break;
+ case 0x40000000:
+ printk("L1 Instruction Cache error\n");
+ break;
+ case 0x00100000:
+ printk("L2 data cache parity error\n");
+ break;
+ default:
+ printk("Unknown values in msr\n");
+ }
+#endif /* CONFIG_4xx */
+
+ /*
+ * Optional platform-provided routine to print out
+ * additional info, e.g. bus error registers.
+ */
+ platform_machine_check(regs);
+#endif /* CONFIG_PPC64 */
+
+ if (debugger_fault_handler(regs))
+ return;
+ die("Machine check", regs, SIGBUS);
+
+ /* Must die if the interrupt is not recoverable */
+ if (!(regs->msr & MSR_RI))
+ panic("Unrecoverable Machine check");
+}
+
+void SMIException(struct pt_regs *regs)
+{
+ die("System Management Interrupt", regs, SIGABRT);
+}
+
+void unknown_exception(struct pt_regs *regs)
+{
+ printk("Bad trap at PC: %lx, SR: %lx, vector=%lx\n",
+ regs->nip, regs->msr, regs->trap);
+
+ _exception(SIGTRAP, regs, 0, 0);
+}
+
+void instruction_breakpoint_exception(struct pt_regs *regs)
+{
+ if (notify_die(DIE_IABR_MATCH, "iabr_match", regs, 5,
+ 5, SIGTRAP) == NOTIFY_STOP)
+ return;
+ if (debugger_iabr_match(regs))
+ return;
+ _exception(SIGTRAP, regs, TRAP_BRKPT, regs->nip);
+}
+
+void RunModeException(struct pt_regs *regs)
+{
+ _exception(SIGTRAP, regs, 0, 0);
+}
+
+void __kprobes single_step_exception(struct pt_regs *regs)
+{
+ regs->msr &= ~(MSR_SE | MSR_BE); /* Turn off 'trace' bits */
+
+ if (notify_die(DIE_SSTEP, "single_step", regs, 5,
+ 5, SIGTRAP) == NOTIFY_STOP)
+ return;
+ if (debugger_sstep(regs))
+ return;
+
+ _exception(SIGTRAP, regs, TRAP_TRACE, regs->nip);
+}
+
+/*
+ * After we have successfully emulated an instruction, we have to
+ * check if the instruction was being single-stepped, and if so,
+ * pretend we got a single-step exception. This was pointed out
+ * by Kumar Gala. -- paulus
+ */
+static void emulate_single_step(struct pt_regs *regs)
+{
+ if (single_stepping(regs)) {
+ clear_single_step(regs);
+ _exception(SIGTRAP, regs, TRAP_TRACE, 0);
+ }
+}
+
+static void parse_fpe(struct pt_regs *regs)
+{
+ int code = 0;
+ unsigned long fpscr;
+
+ flush_fp_to_thread(current);
+
+ fpscr = current->thread.fpscr.val;
+
+ /* Invalid operation */
+ if ((fpscr & FPSCR_VE) && (fpscr & FPSCR_VX))
+ code = FPE_FLTINV;
+
+ /* Overflow */
+ else if ((fpscr & FPSCR_OE) && (fpscr & FPSCR_OX))
+ code = FPE_FLTOVF;
+
+ /* Underflow */
+ else if ((fpscr & FPSCR_UE) && (fpscr & FPSCR_UX))
+ code = FPE_FLTUND;
+
+ /* Divide by zero */
+ else if ((fpscr & FPSCR_ZE) && (fpscr & FPSCR_ZX))
+ code = FPE_FLTDIV;
+
+ /* Inexact result */
+ else if ((fpscr & FPSCR_XE) && (fpscr & FPSCR_XX))
+ code = FPE_FLTRES;
+
+ _exception(SIGFPE, regs, code, regs->nip);
+}
+
+/*
+ * Illegal instruction emulation support. Originally written to
+ * provide the PVR to user applications using the mfspr rd, PVR.
+ * Return non-zero if we can't emulate, or -EFAULT if the associated
+ * memory access caused an access fault. Return zero on success.
+ *
+ * There are a couple of ways to do this, either "decode" the instruction
+ * or directly match lots of bits. In this case, matching lots of
+ * bits is faster and easier.
+ *
+ */
+#define INST_MFSPR_PVR 0x7c1f42a6
+#define INST_MFSPR_PVR_MASK 0xfc1fffff
+
+#define INST_DCBA 0x7c0005ec
+#define INST_DCBA_MASK 0x7c0007fe
+
+#define INST_MCRXR 0x7c000400
+#define INST_MCRXR_MASK 0x7c0007fe
+
+#define INST_STRING 0x7c00042a
+#define INST_STRING_MASK 0x7c0007fe
+#define INST_STRING_GEN_MASK 0x7c00067e
+#define INST_LSWI 0x7c0004aa
+#define INST_LSWX 0x7c00042a
+#define INST_STSWI 0x7c0005aa
+#define INST_STSWX 0x7c00052a
+
+static int emulate_string_inst(struct pt_regs *regs, u32 instword)
+{
+ u8 rT = (instword >> 21) & 0x1f;
+ u8 rA = (instword >> 16) & 0x1f;
+ u8 NB_RB = (instword >> 11) & 0x1f;
+ u32 num_bytes;
+ unsigned long EA;
+ int pos = 0;
+
+ /* Early out if we are an invalid form of lswx */
+ if ((instword & INST_STRING_MASK) == INST_LSWX)
+ if ((rT == rA) || (rT == NB_RB))
+ return -EINVAL;
+
+ EA = (rA == 0) ? 0 : regs->gpr[rA];
+
+ switch (instword & INST_STRING_MASK) {
+ case INST_LSWX:
+ case INST_STSWX:
+ EA += NB_RB;
+ num_bytes = regs->xer & 0x7f;
+ break;
+ case INST_LSWI:
+ case INST_STSWI:
+ num_bytes = (NB_RB == 0) ? 32 : NB_RB;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ while (num_bytes != 0)
+ {
+ u8 val;
+ u32 shift = 8 * (3 - (pos & 0x3));
+
+ switch ((instword & INST_STRING_MASK)) {
+ case INST_LSWX:
+ case INST_LSWI:
+ if (get_user(val, (u8 __user *)EA))
+ return -EFAULT;
+ /* first time updating this reg,
+ * zero it out */
+ if (pos == 0)
+ regs->gpr[rT] = 0;
+ regs->gpr[rT] |= val << shift;
+ break;
+ case INST_STSWI:
+ case INST_STSWX:
+ val = regs->gpr[rT] >> shift;
+ if (put_user(val, (u8 __user *)EA))
+ return -EFAULT;
+ break;
+ }
+ /* move EA to next address */
+ EA += 1;
+ num_bytes--;
+
+ /* manage our position within the register */
+ if (++pos == 4) {
+ pos = 0;
+ if (++rT == 32)
+ rT = 0;
+ }
+ }
+
+ return 0;
+}
+
+static int emulate_instruction(struct pt_regs *regs)
+{
+ u32 instword;
+ u32 rd;
+
+ if (!user_mode(regs))
+ return -EINVAL;
+ CHECK_FULL_REGS(regs);
+
+ if (get_user(instword, (u32 __user *)(regs->nip)))
+ return -EFAULT;
+
+ /* Emulate the mfspr rD, PVR. */
+ if ((instword & INST_MFSPR_PVR_MASK) == INST_MFSPR_PVR) {
+ rd = (instword >> 21) & 0x1f;
+ regs->gpr[rd] = mfspr(SPRN_PVR);
+ return 0;
+ }
+
+ /* Emulating the dcba insn is just a no-op. */
+ if ((instword & INST_DCBA_MASK) == INST_DCBA)
+ return 0;
+
+ /* Emulate the mcrxr insn. */
+ if ((instword & INST_MCRXR_MASK) == INST_MCRXR) {
+ int shift = (instword >> 21) & 0x1c;
+ unsigned long msk = 0xf0000000UL >> shift;
+
+ regs->ccr = (regs->ccr & ~msk) | ((regs->xer >> shift) & msk);
+ regs->xer &= ~0xf0000000UL;
+ return 0;
+ }
+
+ /* Emulate load/store string insn. */
+ if ((instword & INST_STRING_GEN_MASK) == INST_STRING)
+ return emulate_string_inst(regs, instword);
+
+ return -EINVAL;
+}
+
+/*
+ * Look through the list of trap instructions that are used for BUG(),
+ * BUG_ON() and WARN_ON() and see if we hit one. At this point we know
+ * that the exception was caused by a trap instruction of some kind.
+ * Returns 1 if we should continue (i.e. it was a WARN_ON) or 0
+ * otherwise.
+ */
+extern struct bug_entry __start___bug_table[], __stop___bug_table[];
+
+#ifndef CONFIG_MODULES
+#define module_find_bug(x) NULL
+#endif
+
+struct bug_entry *find_bug(unsigned long bugaddr)
+{
+ struct bug_entry *bug;
+
+ for (bug = __start___bug_table; bug < __stop___bug_table; ++bug)
+ if (bugaddr == bug->bug_addr)
+ return bug;
+ return module_find_bug(bugaddr);
+}
+
+static int check_bug_trap(struct pt_regs *regs)
+{
+ struct bug_entry *bug;
+ unsigned long addr;
+
+ if (regs->msr & MSR_PR)
+ return 0; /* not in kernel */
+ addr = regs->nip; /* address of trap instruction */
+ if (addr < PAGE_OFFSET)
+ return 0;
+ bug = find_bug(regs->nip);
+ if (bug == NULL)
+ return 0;
+ if (bug->line & BUG_WARNING_TRAP) {
+ /* this is a WARN_ON rather than BUG/BUG_ON */
+ printk(KERN_ERR "Badness in %s at %s:%ld\n",
+ bug->function, bug->file,
+ bug->line & ~BUG_WARNING_TRAP);
+ dump_stack();
+ return 1;
+ }
+ printk(KERN_CRIT "kernel BUG in %s at %s:%ld!\n",
+ bug->function, bug->file, bug->line);
+
+ return 0;
+}
+
+void __kprobes program_check_exception(struct pt_regs *regs)
+{
+ unsigned int reason = get_reason(regs);
+ extern int do_mathemu(struct pt_regs *regs);
+
+#ifdef CONFIG_MATH_EMULATION
+ /* (reason & REASON_ILLEGAL) would be the obvious thing here,
+ * but there seems to be a hardware bug on the 405GP (RevD)
+ * that means ESR is sometimes set incorrectly - either to
+ * ESR_DST (!?) or 0. In the process of chasing this with the
+ * hardware people - not sure if it can happen on any illegal
+ * instruction or only on FP instructions, whether there is a
+ * pattern to occurences etc. -dgibson 31/Mar/2003 */
+ if (!(reason & REASON_TRAP) && do_mathemu(regs) == 0) {
+ emulate_single_step(regs);
+ return;
+ }
+#endif /* CONFIG_MATH_EMULATION */
+
+ if (reason & REASON_FP) {
+ /* IEEE FP exception */
+ parse_fpe(regs);
+ return;
+ }
+ if (reason & REASON_TRAP) {
+ /* trap exception */
+ if (notify_die(DIE_BPT, "breakpoint", regs, 5, 5, SIGTRAP)
+ == NOTIFY_STOP)
+ return;
+ if (debugger_bpt(regs))
+ return;
+ if (check_bug_trap(regs)) {
+ regs->nip += 4;
+ return;
+ }
+ _exception(SIGTRAP, regs, TRAP_BRKPT, regs->nip);
+ return;
+ }
+
+ /* Try to emulate it if we should. */
+ if (reason & (REASON_ILLEGAL | REASON_PRIVILEGED)) {
+ switch (emulate_instruction(regs)) {
+ case 0:
+ regs->nip += 4;
+ emulate_single_step(regs);
+ return;
+ case -EFAULT:
+ _exception(SIGSEGV, regs, SEGV_MAPERR, regs->nip);
+ return;
+ }
+ }
+
+ if (reason & REASON_PRIVILEGED)
+ _exception(SIGILL, regs, ILL_PRVOPC, regs->nip);
+ else
+ _exception(SIGILL, regs, ILL_ILLOPC, regs->nip);
+}
+
+void alignment_exception(struct pt_regs *regs)
+{
+ int fixed;
+
+ fixed = fix_alignment(regs);
+
+ if (fixed == 1) {
+ regs->nip += 4; /* skip over emulated instruction */
+ emulate_single_step(regs);
+ return;
+ }
+
+ /* Operand address was bad */
+ if (fixed == -EFAULT) {
+ if (user_mode(regs))
+ _exception(SIGSEGV, regs, SEGV_ACCERR, regs->dar);
+ else
+ /* Search exception table */
+ bad_page_fault(regs, regs->dar, SIGSEGV);
+ return;
+ }
+ _exception(SIGBUS, regs, BUS_ADRALN, regs->dar);
+}
+
+void StackOverflow(struct pt_regs *regs)
+{
+ printk(KERN_CRIT "Kernel stack overflow in process %p, r1=%lx\n",
+ current, regs->gpr[1]);
+ debugger(regs);
+ show_regs(regs);
+ panic("kernel stack overflow");
+}
+
+void nonrecoverable_exception(struct pt_regs *regs)
+{
+ printk(KERN_ERR "Non-recoverable exception at PC=%lx MSR=%lx\n",
+ regs->nip, regs->msr);
+ debugger(regs);
+ die("nonrecoverable exception", regs, SIGKILL);
+}
+
+void trace_syscall(struct pt_regs *regs)
+{
+ printk("Task: %p(%d), PC: %08lX/%08lX, Syscall: %3ld, Result: %s%ld %s\n",
+ current, current->pid, regs->nip, regs->link, regs->gpr[0],
+ regs->ccr&0x10000000?"Error=":"", regs->gpr[3], print_tainted());
+}
+
+void kernel_fp_unavailable_exception(struct pt_regs *regs)
+{
+ printk(KERN_EMERG "Unrecoverable FP Unavailable Exception "
+ "%lx at %lx\n", regs->trap, regs->nip);
+ die("Unrecoverable FP Unavailable Exception", regs, SIGABRT);
+}
+
+void altivec_unavailable_exception(struct pt_regs *regs)
+{
+#if !defined(CONFIG_ALTIVEC)
+ if (user_mode(regs)) {
+ /* A user program has executed an altivec instruction,
+ but this kernel doesn't support altivec. */
+ _exception(SIGILL, regs, ILL_ILLOPC, regs->nip);
+ return;
+ }
+#endif
+ printk(KERN_EMERG "Unrecoverable VMX/Altivec Unavailable Exception "
+ "%lx at %lx\n", regs->trap, regs->nip);
+ die("Unrecoverable VMX/Altivec Unavailable Exception", regs, SIGABRT);
+}
+
+#if defined(CONFIG_PPC64) || defined(CONFIG_E500)
+void performance_monitor_exception(struct pt_regs *regs)
+{
+ perf_irq(regs);
+}
+#endif
+
+#ifdef CONFIG_8xx
+void SoftwareEmulation(struct pt_regs *regs)
+{
+ extern int do_mathemu(struct pt_regs *);
+ extern int Soft_emulate_8xx(struct pt_regs *);
+ int errcode;
+
+ CHECK_FULL_REGS(regs);
+
+ if (!user_mode(regs)) {
+ debugger(regs);
+ die("Kernel Mode Software FPU Emulation", regs, SIGFPE);
+ }
+
+#ifdef CONFIG_MATH_EMULATION
+ errcode = do_mathemu(regs);
+#else
+ errcode = Soft_emulate_8xx(regs);
+#endif
+ if (errcode) {
+ if (errcode > 0)
+ _exception(SIGFPE, regs, 0, 0);
+ else if (errcode == -EFAULT)
+ _exception(SIGSEGV, regs, 0, 0);
+ else
+ _exception(SIGILL, regs, ILL_ILLOPC, regs->nip);
+ } else
+ emulate_single_step(regs);
+}
+#endif /* CONFIG_8xx */
+
+#if defined(CONFIG_40x) || defined(CONFIG_BOOKE)
+
+void DebugException(struct pt_regs *regs, unsigned long debug_status)
+{
+ if (debug_status & DBSR_IC) { /* instruction completion */
+ regs->msr &= ~MSR_DE;
+ if (user_mode(regs)) {
+ current->thread.dbcr0 &= ~DBCR0_IC;
+ } else {
+ /* Disable instruction completion */
+ mtspr(SPRN_DBCR0, mfspr(SPRN_DBCR0) & ~DBCR0_IC);
+ /* Clear the instruction completion event */
+ mtspr(SPRN_DBSR, DBSR_IC);
+ if (debugger_sstep(regs))
+ return;
+ }
+ _exception(SIGTRAP, regs, TRAP_TRACE, 0);
+ }
+}
+#endif /* CONFIG_4xx || CONFIG_BOOKE */
+
+#if !defined(CONFIG_TAU_INT)
+void TAUException(struct pt_regs *regs)
+{
+ printk("TAU trap at PC: %lx, MSR: %lx, vector=%lx %s\n",
+ regs->nip, regs->msr, regs->trap, print_tainted());
+}
+#endif /* CONFIG_INT_TAU */
+
+#ifdef CONFIG_ALTIVEC
+void altivec_assist_exception(struct pt_regs *regs)
+{
+ int err;
+
+ if (!user_mode(regs)) {
+ printk(KERN_EMERG "VMX/Altivec assist exception in kernel mode"
+ " at %lx\n", regs->nip);
+ die("Kernel VMX/Altivec assist exception", regs, SIGILL);
+ }
+
+ flush_altivec_to_thread(current);
+
+ err = emulate_altivec(regs);
+ if (err == 0) {
+ regs->nip += 4; /* skip emulated instruction */
+ emulate_single_step(regs);
+ return;
+ }
+
+ if (err == -EFAULT) {
+ /* got an error reading the instruction */
+ _exception(SIGSEGV, regs, SEGV_ACCERR, regs->nip);
+ } else {
+ /* didn't recognize the instruction */
+ /* XXX quick hack for now: set the non-Java bit in the VSCR */
+ if (printk_ratelimit())
+ printk(KERN_ERR "Unrecognized altivec instruction "
+ "in %s at %lx\n", current->comm, regs->nip);
+ current->thread.vscr.u[3] |= 0x10000;
+ }
+}
+#endif /* CONFIG_ALTIVEC */
+
+#ifdef CONFIG_FSL_BOOKE
+void CacheLockingException(struct pt_regs *regs, unsigned long address,
+ unsigned long error_code)
+{
+ /* We treat cache locking instructions from the user
+ * as priv ops, in the future we could try to do
+ * something smarter
+ */
+ if (error_code & (ESR_DLK|ESR_ILK))
+ _exception(SIGILL, regs, ILL_PRVOPC, regs->nip);
+ return;
+}
+#endif /* CONFIG_FSL_BOOKE */
+
+#ifdef CONFIG_SPE
+void SPEFloatingPointException(struct pt_regs *regs)
+{
+ unsigned long spefscr;
+ int fpexc_mode;
+ int code = 0;
+
+ spefscr = current->thread.spefscr;
+ fpexc_mode = current->thread.fpexc_mode;
+
+ /* Hardware does not neccessarily set sticky
+ * underflow/overflow/invalid flags */
+ if ((spefscr & SPEFSCR_FOVF) && (fpexc_mode & PR_FP_EXC_OVF)) {
+ code = FPE_FLTOVF;
+ spefscr |= SPEFSCR_FOVFS;
+ }
+ else if ((spefscr & SPEFSCR_FUNF) && (fpexc_mode & PR_FP_EXC_UND)) {
+ code = FPE_FLTUND;
+ spefscr |= SPEFSCR_FUNFS;
+ }
+ else if ((spefscr & SPEFSCR_FDBZ) && (fpexc_mode & PR_FP_EXC_DIV))
+ code = FPE_FLTDIV;
+ else if ((spefscr & SPEFSCR_FINV) && (fpexc_mode & PR_FP_EXC_INV)) {
+ code = FPE_FLTINV;
+ spefscr |= SPEFSCR_FINVS;
+ }
+ else if ((spefscr & (SPEFSCR_FG | SPEFSCR_FX)) && (fpexc_mode & PR_FP_EXC_RES))
+ code = FPE_FLTRES;
+
+ current->thread.spefscr = spefscr;
+
+ _exception(SIGFPE, regs, code, regs->nip);
+ return;
+}
+#endif
+
+/*
+ * We enter here if we get an unrecoverable exception, that is, one
+ * that happened at a point where the RI (recoverable interrupt) bit
+ * in the MSR is 0. This indicates that SRR0/1 are live, and that
+ * we therefore lost state by taking this exception.
+ */
+void unrecoverable_exception(struct pt_regs *regs)
+{
+ printk(KERN_EMERG "Unrecoverable exception %lx at %lx\n",
+ regs->trap, regs->nip);
+ die("Unrecoverable exception", regs, SIGABRT);
+}
+
+#ifdef CONFIG_BOOKE_WDT
+/*
+ * Default handler for a Watchdog exception,
+ * spins until a reboot occurs
+ */
+void __attribute__ ((weak)) WatchdogHandler(struct pt_regs *regs)
+{
+ /* Generic WatchdogHandler, implement your own */
+ mtspr(SPRN_TCR, mfspr(SPRN_TCR)&(~TCR_WIE));
+ return;
+}
+
+void WatchdogException(struct pt_regs *regs)
+{
+ printk (KERN_EMERG "PowerPC Book-E Watchdog Exception\n");
+ WatchdogHandler(regs);
+}
+#endif
+
+/*
+ * We enter here if we discover during exception entry that we are
+ * running in supervisor mode with a userspace value in the stack pointer.
+ */
+void kernel_bad_stack(struct pt_regs *regs)
+{
+ printk(KERN_EMERG "Bad kernel stack pointer %lx at %lx\n",
+ regs->gpr[1], regs->nip);
+ die("Bad kernel stack pointer", regs, SIGABRT);
+}
+
+void __init trap_init(void)
+{
+}
diff --git a/arch/ppc/kernel/vecemu.c b/arch/powerpc/kernel/vecemu.c
index 604d0947cb20..604d0947cb20 100644
--- a/arch/ppc/kernel/vecemu.c
+++ b/arch/powerpc/kernel/vecemu.c
diff --git a/arch/ppc64/kernel/vector.S b/arch/powerpc/kernel/vector.S
index b79d33e4001e..66b3d03c5fa5 100644
--- a/arch/ppc64/kernel/vector.S
+++ b/arch/powerpc/kernel/vector.S
@@ -1,11 +1,26 @@
+#include <linux/config.h>
#include <asm/ppc_asm.h>
-#include <asm/processor.h>
+#include <asm/reg.h>
/*
* The routines below are in assembler so we can closely control the
* usage of floating-point registers. These routines must be called
* with preempt disabled.
*/
+#ifdef CONFIG_PPC32
+ .data
+fpzero:
+ .long 0
+fpone:
+ .long 0x3f800000 /* 1.0 in single-precision FP */
+fphalf:
+ .long 0x3f000000 /* 0.5 in single-precision FP */
+
+#define LDCONST(fr, name) \
+ lis r11,name@ha; \
+ lfs fr,name@l(r11)
+#else
+
.section ".toc","aw"
fpzero:
.tc FD_0_0[TC],0
@@ -14,32 +29,42 @@ fpone:
fphalf:
.tc FD_3fe00000_0[TC],0x3fe0000000000000 /* 0.5 */
+#define LDCONST(fr, name) \
+ lfd fr,name@toc(r2)
+#endif
+
.text
/*
* Internal routine to enable floating point and set FPSCR to 0.
* Don't call it from C; it doesn't use the normal calling convention.
*/
fpenable:
+#ifdef CONFIG_PPC32
+ stwu r1,-64(r1)
+#else
+ stdu r1,-64(r1)
+#endif
mfmsr r10
ori r11,r10,MSR_FP
mtmsr r11
isync
- stfd fr31,-8(r1)
- stfd fr0,-16(r1)
- stfd fr1,-24(r1)
+ stfd fr0,24(r1)
+ stfd fr1,16(r1)
+ stfd fr31,8(r1)
+ LDCONST(fr1, fpzero)
mffs fr31
- lfd fr1,fpzero@toc(r2)
mtfsf 0xff,fr1
blr
fpdisable:
mtlr r12
mtfsf 0xff,fr31
- lfd fr1,-24(r1)
- lfd fr0,-16(r1)
- lfd fr31,-8(r1)
+ lfd fr31,8(r1)
+ lfd fr1,16(r1)
+ lfd fr0,24(r1)
mtmsr r10
isync
+ addi r1,r1,64
blr
/*
@@ -82,7 +107,7 @@ _GLOBAL(vsubfp)
_GLOBAL(vmaddfp)
mflr r12
bl fpenable
- stfd fr2,-32(r1)
+ stfd fr2,32(r1)
li r0,4
mtctr r0
li r7,0
@@ -93,7 +118,7 @@ _GLOBAL(vmaddfp)
stfsx fr0,r3,r7
addi r7,r7,4
bdnz 1b
- lfd fr2,-32(r1)
+ lfd fr2,32(r1)
b fpdisable
/*
@@ -102,7 +127,7 @@ _GLOBAL(vmaddfp)
_GLOBAL(vnmsubfp)
mflr r12
bl fpenable
- stfd fr2,-32(r1)
+ stfd fr2,32(r1)
li r0,4
mtctr r0
li r7,0
@@ -113,7 +138,7 @@ _GLOBAL(vnmsubfp)
stfsx fr0,r3,r7
addi r7,r7,4
bdnz 1b
- lfd fr2,-32(r1)
+ lfd fr2,32(r1)
b fpdisable
/*
@@ -124,7 +149,7 @@ _GLOBAL(vrefp)
mflr r12
bl fpenable
li r0,4
- lfd fr1,fpone@toc(r2)
+ LDCONST(fr1, fpone)
mtctr r0
li r6,0
1: lfsx fr0,r4,r6
@@ -143,13 +168,13 @@ _GLOBAL(vrefp)
_GLOBAL(vrsqrtefp)
mflr r12
bl fpenable
- stfd fr2,-32(r1)
- stfd fr3,-40(r1)
- stfd fr4,-48(r1)
- stfd fr5,-56(r1)
+ stfd fr2,32(r1)
+ stfd fr3,40(r1)
+ stfd fr4,48(r1)
+ stfd fr5,56(r1)
li r0,4
- lfd fr4,fpone@toc(r2)
- lfd fr5,fphalf@toc(r2)
+ LDCONST(fr4, fpone)
+ LDCONST(fr5, fphalf)
mtctr r0
li r6,0
1: lfsx fr0,r4,r6
@@ -165,8 +190,8 @@ _GLOBAL(vrsqrtefp)
stfsx fr1,r3,r6
addi r6,r6,4
bdnz 1b
- lfd fr5,-56(r1)
- lfd fr4,-48(r1)
- lfd fr3,-40(r1)
- lfd fr2,-32(r1)
+ lfd fr5,56(r1)
+ lfd fr4,48(r1)
+ lfd fr3,40(r1)
+ lfd fr2,32(r1)
b fpdisable
diff --git a/arch/ppc64/kernel/vio.c b/arch/powerpc/kernel/vio.c
index 0e555b7a6587..71a6addf9f7f 100644
--- a/arch/ppc64/kernel/vio.c
+++ b/arch/powerpc/kernel/vio.c
@@ -21,6 +21,7 @@
#include <asm/iommu.h>
#include <asm/dma.h>
#include <asm/vio.h>
+#include <asm/prom.h>
static const struct vio_device_id *vio_match_device(
const struct vio_device_id *, const struct vio_dev *);
@@ -69,6 +70,16 @@ static int vio_bus_remove(struct device *dev)
return 1;
}
+/* convert from struct device to struct vio_dev and pass to driver. */
+static void vio_bus_shutdown(struct device *dev)
+{
+ struct vio_dev *viodev = to_vio_dev(dev);
+ struct vio_driver *viodrv = to_vio_driver(dev->driver);
+
+ if (viodrv->shutdown)
+ viodrv->shutdown(viodev);
+}
+
/**
* vio_register_driver: - Register a new vio driver
* @drv: The vio_driver structure to be registered.
@@ -76,13 +87,13 @@ static int vio_bus_remove(struct device *dev)
int vio_register_driver(struct vio_driver *viodrv)
{
printk(KERN_DEBUG "%s: driver %s registering\n", __FUNCTION__,
- viodrv->name);
+ viodrv->driver.name);
/* fill in 'struct driver' fields */
- viodrv->driver.name = viodrv->name;
viodrv->driver.bus = &vio_bus_type;
viodrv->driver.probe = vio_bus_probe;
viodrv->driver.remove = vio_bus_remove;
+ viodrv->driver.shutdown = vio_bus_shutdown;
return driver_register(&viodrv->driver);
}
@@ -255,7 +266,33 @@ static int vio_bus_match(struct device *dev, struct device_driver *drv)
return (ids != NULL) && (vio_match_device(ids, vio_dev) != NULL);
}
+static int vio_hotplug(struct device *dev, char **envp, int num_envp,
+ char *buffer, int buffer_size)
+{
+ const struct vio_dev *vio_dev = to_vio_dev(dev);
+ char *cp;
+ int length;
+
+ if (!num_envp)
+ return -ENOMEM;
+
+ if (!vio_dev->dev.platform_data)
+ return -ENODEV;
+ cp = (char *)get_property(vio_dev->dev.platform_data, "compatible", &length);
+ if (!cp)
+ return -ENODEV;
+
+ envp[0] = buffer;
+ length = scnprintf(buffer, buffer_size, "MODALIAS=vio:T%sS%s",
+ vio_dev->type, cp);
+ if (buffer_size - length <= 0)
+ return -ENOMEM;
+ envp[1] = NULL;
+ return 0;
+}
+
struct bus_type vio_bus_type = {
.name = "vio",
+ .hotplug = vio_hotplug,
.match = vio_bus_match,
};
diff --git a/arch/powerpc/kernel/vmlinux.lds.S b/arch/powerpc/kernel/vmlinux.lds.S
new file mode 100644
index 000000000000..7fa7b15fd8e6
--- /dev/null
+++ b/arch/powerpc/kernel/vmlinux.lds.S
@@ -0,0 +1,258 @@
+#include <linux/config.h>
+#ifdef CONFIG_PPC64
+#include <asm/page.h>
+#else
+#define PAGE_SIZE 4096
+#define KERNELBASE CONFIG_KERNEL_START
+#endif
+#include <asm-generic/vmlinux.lds.h>
+
+ENTRY(_stext)
+
+#ifdef CONFIG_PPC64
+OUTPUT_ARCH(powerpc:common64)
+jiffies = jiffies_64;
+#else
+OUTPUT_ARCH(powerpc:common)
+jiffies = jiffies_64 + 4;
+#endif
+SECTIONS
+{
+ /* Sections to be discarded. */
+ /DISCARD/ : {
+ *(.exitcall.exit)
+ *(.exit.data)
+ }
+
+ . = KERNELBASE;
+
+ /* Read-only sections, merged into text segment: */
+ .text : {
+ *(.text .text.*)
+ SCHED_TEXT
+ LOCK_TEXT
+ KPROBES_TEXT
+ *(.fixup)
+#ifdef CONFIG_PPC32
+ *(.got1)
+ __got2_start = .;
+ *(.got2)
+ __got2_end = .;
+#else
+ . = ALIGN(PAGE_SIZE);
+ _etext = .;
+#endif
+ }
+#ifdef CONFIG_PPC32
+ _etext = .;
+ PROVIDE (etext = .);
+
+ RODATA
+ .fini : { *(.fini) } =0
+ .ctors : { *(.ctors) }
+ .dtors : { *(.dtors) }
+
+ .fixup : { *(.fixup) }
+#endif
+
+ __ex_table : {
+ __start___ex_table = .;
+ *(__ex_table)
+ __stop___ex_table = .;
+ }
+
+ __bug_table : {
+ __start___bug_table = .;
+ *(__bug_table)
+ __stop___bug_table = .;
+ }
+
+#ifdef CONFIG_PPC64
+ __ftr_fixup : {
+ __start___ftr_fixup = .;
+ *(__ftr_fixup)
+ __stop___ftr_fixup = .;
+ }
+
+ RODATA
+#endif
+
+#ifdef CONFIG_PPC32
+ /* Read-write section, merged into data segment: */
+ . = ALIGN(PAGE_SIZE);
+ _sdata = .;
+ .data :
+ {
+ *(.data)
+ *(.data1)
+ *(.sdata)
+ *(.sdata2)
+ *(.got.plt) *(.got)
+ *(.dynamic)
+ CONSTRUCTORS
+ }
+
+ . = ALIGN(PAGE_SIZE);
+ __nosave_begin = .;
+ .data_nosave : { *(.data.nosave) }
+ . = ALIGN(PAGE_SIZE);
+ __nosave_end = .;
+
+ . = ALIGN(32);
+ .data.cacheline_aligned : { *(.data.cacheline_aligned) }
+
+ _edata = .;
+ PROVIDE (edata = .);
+
+ . = ALIGN(8192);
+ .data.init_task : { *(.data.init_task) }
+#endif
+
+ /* will be freed after init */
+ . = ALIGN(PAGE_SIZE);
+ __init_begin = .;
+ .init.text : {
+ _sinittext = .;
+ *(.init.text)
+ _einittext = .;
+ }
+#ifdef CONFIG_PPC32
+ /* .exit.text is discarded at runtime, not link time,
+ to deal with references from __bug_table */
+ .exit.text : { *(.exit.text) }
+#endif
+ .init.data : {
+ *(.init.data);
+ __vtop_table_begin = .;
+ *(.vtop_fixup);
+ __vtop_table_end = .;
+ __ptov_table_begin = .;
+ *(.ptov_fixup);
+ __ptov_table_end = .;
+ }
+
+ . = ALIGN(16);
+ .init.setup : {
+ __setup_start = .;
+ *(.init.setup)
+ __setup_end = .;
+ }
+
+ .initcall.init : {
+ __initcall_start = .;
+ *(.initcall1.init)
+ *(.initcall2.init)
+ *(.initcall3.init)
+ *(.initcall4.init)
+ *(.initcall5.init)
+ *(.initcall6.init)
+ *(.initcall7.init)
+ __initcall_end = .;
+ }
+
+ .con_initcall.init : {
+ __con_initcall_start = .;
+ *(.con_initcall.init)
+ __con_initcall_end = .;
+ }
+
+ SECURITY_INIT
+
+#ifdef CONFIG_PPC32
+ __start___ftr_fixup = .;
+ __ftr_fixup : { *(__ftr_fixup) }
+ __stop___ftr_fixup = .;
+#else
+ . = ALIGN(PAGE_SIZE);
+ .init.ramfs : {
+ __initramfs_start = .;
+ *(.init.ramfs)
+ __initramfs_end = .;
+ }
+#endif
+
+#ifdef CONFIG_PPC32
+ . = ALIGN(32);
+#endif
+ .data.percpu : {
+ __per_cpu_start = .;
+ *(.data.percpu)
+ __per_cpu_end = .;
+ }
+
+ . = ALIGN(PAGE_SIZE);
+#ifdef CONFIG_PPC64
+ . = ALIGN(16384);
+ __init_end = .;
+ /* freed after init ends here */
+
+ /* Read/write sections */
+ . = ALIGN(PAGE_SIZE);
+ . = ALIGN(16384);
+ _sdata = .;
+ /* The initial task and kernel stack */
+ .data.init_task : {
+ *(.data.init_task)
+ }
+
+ . = ALIGN(PAGE_SIZE);
+ .data.page_aligned : {
+ *(.data.page_aligned)
+ }
+
+ .data.cacheline_aligned : {
+ *(.data.cacheline_aligned)
+ }
+
+ .data : {
+ *(.data .data.rel* .toc1)
+ *(.branch_lt)
+ }
+
+ .opd : {
+ *(.opd)
+ }
+
+ .got : {
+ __toc_start = .;
+ *(.got)
+ *(.toc)
+ . = ALIGN(PAGE_SIZE);
+ _edata = .;
+ }
+
+ . = ALIGN(PAGE_SIZE);
+#else
+ __initramfs_start = .;
+ .init.ramfs : {
+ *(.init.ramfs)
+ }
+ __initramfs_end = .;
+
+ . = ALIGN(4096);
+ __init_end = .;
+
+ . = ALIGN(4096);
+ _sextratext = .;
+ _eextratext = .;
+
+ __bss_start = .;
+#endif
+
+ .bss : {
+ __bss_start = .;
+ *(.sbss) *(.scommon)
+ *(.dynbss)
+ *(.bss)
+ *(COMMON)
+ __bss_stop = .;
+ }
+
+#ifdef CONFIG_PPC64
+ . = ALIGN(PAGE_SIZE);
+#endif
+ _end = . ;
+#ifdef CONFIG_PPC32
+ PROVIDE (end = .);
+#endif
+}
diff --git a/arch/powerpc/lib/Makefile b/arch/powerpc/lib/Makefile
new file mode 100644
index 000000000000..34f5c2e074c9
--- /dev/null
+++ b/arch/powerpc/lib/Makefile
@@ -0,0 +1,20 @@
+#
+# Makefile for ppc-specific library files..
+#
+
+ifeq ($(CONFIG_PPC_MERGE),y)
+obj-y := string.o strcase.o
+obj-$(CONFIG_PPC32) += div64.o copy_32.o checksum_32.o
+endif
+
+obj-y += bitops.o
+obj-$(CONFIG_PPC64) += checksum_64.o copypage_64.o copyuser_64.o \
+ memcpy_64.o usercopy_64.o mem_64.o string.o \
+ strcase.o
+obj-$(CONFIG_PPC_ISERIES) += e2a.o
+obj-$(CONFIG_XMON) += sstep.o
+
+ifeq ($(CONFIG_PPC64),y)
+obj-$(CONFIG_SMP) += locks.o
+obj-$(CONFIG_DEBUG_KERNEL) += sstep.o
+endif
diff --git a/arch/ppc64/kernel/bitops.c b/arch/powerpc/lib/bitops.c
index ae329e8b4acb..f68ad71a0187 100644
--- a/arch/ppc64/kernel/bitops.c
+++ b/arch/powerpc/lib/bitops.c
@@ -1,93 +1,97 @@
-/*
- * These are too big to be inlined.
- */
-
-#include <linux/kernel.h>
+#include <linux/types.h>
#include <linux/module.h>
-#include <linux/bitops.h>
#include <asm/byteorder.h>
+#include <asm/bitops.h>
-unsigned long find_next_zero_bit(const unsigned long *addr, unsigned long size,
- unsigned long offset)
+/**
+ * find_next_bit - find the next set bit in a memory region
+ * @addr: The address to base the search on
+ * @offset: The bitnumber to start searching at
+ * @size: The maximum size to search
+ */
+unsigned long find_next_bit(const unsigned long *addr, unsigned long size,
+ unsigned long offset)
{
- const unsigned long *p = addr + (offset >> 6);
- unsigned long result = offset & ~63UL;
+ const unsigned long *p = addr + BITOP_WORD(offset);
+ unsigned long result = offset & ~(BITS_PER_LONG-1);
unsigned long tmp;
if (offset >= size)
return size;
size -= result;
- offset &= 63UL;
+ offset %= BITS_PER_LONG;
if (offset) {
tmp = *(p++);
- tmp |= ~0UL >> (64 - offset);
- if (size < 64)
+ tmp &= (~0UL << offset);
+ if (size < BITS_PER_LONG)
goto found_first;
- if (~tmp)
+ if (tmp)
goto found_middle;
- size -= 64;
- result += 64;
+ size -= BITS_PER_LONG;
+ result += BITS_PER_LONG;
}
- while (size & ~63UL) {
- if (~(tmp = *(p++)))
+ while (size & ~(BITS_PER_LONG-1)) {
+ if ((tmp = *(p++)))
goto found_middle;
- result += 64;
- size -= 64;
+ result += BITS_PER_LONG;
+ size -= BITS_PER_LONG;
}
if (!size)
return result;
tmp = *p;
found_first:
- tmp |= ~0UL << size;
- if (tmp == ~0UL) /* Are any bits zero? */
+ tmp &= (~0UL >> (BITS_PER_LONG - size));
+ if (tmp == 0UL) /* Are any bits set? */
return result + size; /* Nope. */
found_middle:
- return result + ffz(tmp);
+ return result + __ffs(tmp);
}
+EXPORT_SYMBOL(find_next_bit);
-EXPORT_SYMBOL(find_next_zero_bit);
-
-unsigned long find_next_bit(const unsigned long *addr, unsigned long size,
- unsigned long offset)
+/*
+ * This implementation of find_{first,next}_zero_bit was stolen from
+ * Linus' asm-alpha/bitops.h.
+ */
+unsigned long find_next_zero_bit(const unsigned long *addr, unsigned long size,
+ unsigned long offset)
{
- const unsigned long *p = addr + (offset >> 6);
- unsigned long result = offset & ~63UL;
+ const unsigned long *p = addr + BITOP_WORD(offset);
+ unsigned long result = offset & ~(BITS_PER_LONG-1);
unsigned long tmp;
if (offset >= size)
return size;
size -= result;
- offset &= 63UL;
+ offset %= BITS_PER_LONG;
if (offset) {
tmp = *(p++);
- tmp &= (~0UL << offset);
- if (size < 64)
+ tmp |= ~0UL >> (BITS_PER_LONG - offset);
+ if (size < BITS_PER_LONG)
goto found_first;
- if (tmp)
+ if (~tmp)
goto found_middle;
- size -= 64;
- result += 64;
+ size -= BITS_PER_LONG;
+ result += BITS_PER_LONG;
}
- while (size & ~63UL) {
- if ((tmp = *(p++)))
+ while (size & ~(BITS_PER_LONG-1)) {
+ if (~(tmp = *(p++)))
goto found_middle;
- result += 64;
- size -= 64;
+ result += BITS_PER_LONG;
+ size -= BITS_PER_LONG;
}
if (!size)
return result;
tmp = *p;
found_first:
- tmp &= (~0UL >> (64 - size));
- if (tmp == 0UL) /* Are any bits set? */
+ tmp |= ~0UL << size;
+ if (tmp == ~0UL) /* Are any bits zero? */
return result + size; /* Nope. */
found_middle:
- return result + __ffs(tmp);
+ return result + ffz(tmp);
}
-
-EXPORT_SYMBOL(find_next_bit);
+EXPORT_SYMBOL(find_next_zero_bit);
static inline unsigned int ext2_ilog2(unsigned int x)
{
@@ -106,8 +110,8 @@ static inline unsigned int ext2_ffz(unsigned int x)
return rc;
}
-unsigned long find_next_zero_le_bit(const unsigned long *addr, unsigned long size,
- unsigned long offset)
+unsigned long find_next_zero_le_bit(const unsigned long *addr,
+ unsigned long size, unsigned long offset)
{
const unsigned int *p = ((const unsigned int *)addr) + (offset >> 5);
unsigned int result = offset & ~31;
@@ -143,5 +147,4 @@ found_first:
found_middle:
return result + ext2_ffz(tmp);
}
-
EXPORT_SYMBOL(find_next_zero_le_bit);
diff --git a/arch/powerpc/lib/checksum_32.S b/arch/powerpc/lib/checksum_32.S
new file mode 100644
index 000000000000..7874e8a80455
--- /dev/null
+++ b/arch/powerpc/lib/checksum_32.S
@@ -0,0 +1,225 @@
+/*
+ * This file contains assembly-language implementations
+ * of IP-style 1's complement checksum routines.
+ *
+ * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.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.
+ *
+ * Severely hacked about by Paul Mackerras (paulus@cs.anu.edu.au).
+ */
+
+#include <linux/sys.h>
+#include <asm/processor.h>
+#include <asm/errno.h>
+#include <asm/ppc_asm.h>
+
+ .text
+
+/*
+ * ip_fast_csum(buf, len) -- Optimized for IP header
+ * len is in words and is always >= 5.
+ */
+_GLOBAL(ip_fast_csum)
+ lwz r0,0(r3)
+ lwzu r5,4(r3)
+ addic. r4,r4,-2
+ addc r0,r0,r5
+ mtctr r4
+ blelr-
+1: lwzu r4,4(r3)
+ adde r0,r0,r4
+ bdnz 1b
+ addze r0,r0 /* add in final carry */
+ rlwinm r3,r0,16,0,31 /* fold two halves together */
+ add r3,r0,r3
+ not r3,r3
+ srwi r3,r3,16
+ blr
+
+/*
+ * Compute checksum of TCP or UDP pseudo-header:
+ * csum_tcpudp_magic(saddr, daddr, len, proto, sum)
+ */
+_GLOBAL(csum_tcpudp_magic)
+ rlwimi r5,r6,16,0,15 /* put proto in upper half of len */
+ addc r0,r3,r4 /* add 4 32-bit words together */
+ adde r0,r0,r5
+ adde r0,r0,r7
+ addze r0,r0 /* add in final carry */
+ rlwinm r3,r0,16,0,31 /* fold two halves together */
+ add r3,r0,r3
+ not r3,r3
+ srwi r3,r3,16
+ blr
+
+/*
+ * computes the checksum of a memory block at buff, length len,
+ * and adds in "sum" (32-bit)
+ *
+ * csum_partial(buff, len, sum)
+ */
+_GLOBAL(csum_partial)
+ addic r0,r5,0
+ subi r3,r3,4
+ srwi. r6,r4,2
+ beq 3f /* if we're doing < 4 bytes */
+ andi. r5,r3,2 /* Align buffer to longword boundary */
+ beq+ 1f
+ lhz r5,4(r3) /* do 2 bytes to get aligned */
+ addi r3,r3,2
+ subi r4,r4,2
+ addc r0,r0,r5
+ srwi. r6,r4,2 /* # words to do */
+ beq 3f
+1: mtctr r6
+2: lwzu r5,4(r3) /* the bdnz has zero overhead, so it should */
+ adde r0,r0,r5 /* be unnecessary to unroll this loop */
+ bdnz 2b
+ andi. r4,r4,3
+3: cmpwi 0,r4,2
+ blt+ 4f
+ lhz r5,4(r3)
+ addi r3,r3,2
+ subi r4,r4,2
+ adde r0,r0,r5
+4: cmpwi 0,r4,1
+ bne+ 5f
+ lbz r5,4(r3)
+ slwi r5,r5,8 /* Upper byte of word */
+ adde r0,r0,r5
+5: addze r3,r0 /* add in final carry */
+ blr
+
+/*
+ * Computes the checksum of a memory block at src, length len,
+ * and adds in "sum" (32-bit), while copying the block to dst.
+ * If an access exception occurs on src or dst, it stores -EFAULT
+ * to *src_err or *dst_err respectively, and (for an error on
+ * src) zeroes the rest of dst.
+ *
+ * csum_partial_copy_generic(src, dst, len, sum, src_err, dst_err)
+ */
+_GLOBAL(csum_partial_copy_generic)
+ addic r0,r6,0
+ subi r3,r3,4
+ subi r4,r4,4
+ srwi. r6,r5,2
+ beq 3f /* if we're doing < 4 bytes */
+ andi. r9,r4,2 /* Align dst to longword boundary */
+ beq+ 1f
+81: lhz r6,4(r3) /* do 2 bytes to get aligned */
+ addi r3,r3,2
+ subi r5,r5,2
+91: sth r6,4(r4)
+ addi r4,r4,2
+ addc r0,r0,r6
+ srwi. r6,r5,2 /* # words to do */
+ beq 3f
+1: srwi. r6,r5,4 /* # groups of 4 words to do */
+ beq 10f
+ mtctr r6
+71: lwz r6,4(r3)
+72: lwz r9,8(r3)
+73: lwz r10,12(r3)
+74: lwzu r11,16(r3)
+ adde r0,r0,r6
+75: stw r6,4(r4)
+ adde r0,r0,r9
+76: stw r9,8(r4)
+ adde r0,r0,r10
+77: stw r10,12(r4)
+ adde r0,r0,r11
+78: stwu r11,16(r4)
+ bdnz 71b
+10: rlwinm. r6,r5,30,30,31 /* # words left to do */
+ beq 13f
+ mtctr r6
+82: lwzu r9,4(r3)
+92: stwu r9,4(r4)
+ adde r0,r0,r9
+ bdnz 82b
+13: andi. r5,r5,3
+3: cmpwi 0,r5,2
+ blt+ 4f
+83: lhz r6,4(r3)
+ addi r3,r3,2
+ subi r5,r5,2
+93: sth r6,4(r4)
+ addi r4,r4,2
+ adde r0,r0,r6
+4: cmpwi 0,r5,1
+ bne+ 5f
+84: lbz r6,4(r3)
+94: stb r6,4(r4)
+ slwi r6,r6,8 /* Upper byte of word */
+ adde r0,r0,r6
+5: addze r3,r0 /* add in final carry */
+ blr
+
+/* These shouldn't go in the fixup section, since that would
+ cause the ex_table addresses to get out of order. */
+
+src_error_4:
+ mfctr r6 /* update # bytes remaining from ctr */
+ rlwimi r5,r6,4,0,27
+ b 79f
+src_error_1:
+ li r6,0
+ subi r5,r5,2
+95: sth r6,4(r4)
+ addi r4,r4,2
+79: srwi. r6,r5,2
+ beq 3f
+ mtctr r6
+src_error_2:
+ li r6,0
+96: stwu r6,4(r4)
+ bdnz 96b
+3: andi. r5,r5,3
+ beq src_error
+src_error_3:
+ li r6,0
+ mtctr r5
+ addi r4,r4,3
+97: stbu r6,1(r4)
+ bdnz 97b
+src_error:
+ cmpwi 0,r7,0
+ beq 1f
+ li r6,-EFAULT
+ stw r6,0(r7)
+1: addze r3,r0
+ blr
+
+dst_error:
+ cmpwi 0,r8,0
+ beq 1f
+ li r6,-EFAULT
+ stw r6,0(r8)
+1: addze r3,r0
+ blr
+
+.section __ex_table,"a"
+ .long 81b,src_error_1
+ .long 91b,dst_error
+ .long 71b,src_error_4
+ .long 72b,src_error_4
+ .long 73b,src_error_4
+ .long 74b,src_error_4
+ .long 75b,dst_error
+ .long 76b,dst_error
+ .long 77b,dst_error
+ .long 78b,dst_error
+ .long 82b,src_error_2
+ .long 92b,dst_error
+ .long 83b,src_error_3
+ .long 93b,dst_error
+ .long 84b,src_error_3
+ .long 94b,dst_error
+ .long 95b,dst_error
+ .long 96b,dst_error
+ .long 97b,dst_error
diff --git a/arch/ppc64/lib/checksum.S b/arch/powerpc/lib/checksum_64.S
index ef96c6c58efc..ef96c6c58efc 100644
--- a/arch/ppc64/lib/checksum.S
+++ b/arch/powerpc/lib/checksum_64.S
diff --git a/arch/powerpc/lib/copy_32.S b/arch/powerpc/lib/copy_32.S
new file mode 100644
index 000000000000..bee51414812e
--- /dev/null
+++ b/arch/powerpc/lib/copy_32.S
@@ -0,0 +1,543 @@
+/*
+ * Memory copy functions for 32-bit PowerPC.
+ *
+ * Copyright (C) 1996-2005 Paul Mackerras.
+ *
+ * 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/config.h>
+#include <asm/processor.h>
+#include <asm/cache.h>
+#include <asm/errno.h>
+#include <asm/ppc_asm.h>
+
+#define COPY_16_BYTES \
+ lwz r7,4(r4); \
+ lwz r8,8(r4); \
+ lwz r9,12(r4); \
+ lwzu r10,16(r4); \
+ stw r7,4(r6); \
+ stw r8,8(r6); \
+ stw r9,12(r6); \
+ stwu r10,16(r6)
+
+#define COPY_16_BYTES_WITHEX(n) \
+8 ## n ## 0: \
+ lwz r7,4(r4); \
+8 ## n ## 1: \
+ lwz r8,8(r4); \
+8 ## n ## 2: \
+ lwz r9,12(r4); \
+8 ## n ## 3: \
+ lwzu r10,16(r4); \
+8 ## n ## 4: \
+ stw r7,4(r6); \
+8 ## n ## 5: \
+ stw r8,8(r6); \
+8 ## n ## 6: \
+ stw r9,12(r6); \
+8 ## n ## 7: \
+ stwu r10,16(r6)
+
+#define COPY_16_BYTES_EXCODE(n) \
+9 ## n ## 0: \
+ addi r5,r5,-(16 * n); \
+ b 104f; \
+9 ## n ## 1: \
+ addi r5,r5,-(16 * n); \
+ b 105f; \
+.section __ex_table,"a"; \
+ .align 2; \
+ .long 8 ## n ## 0b,9 ## n ## 0b; \
+ .long 8 ## n ## 1b,9 ## n ## 0b; \
+ .long 8 ## n ## 2b,9 ## n ## 0b; \
+ .long 8 ## n ## 3b,9 ## n ## 0b; \
+ .long 8 ## n ## 4b,9 ## n ## 1b; \
+ .long 8 ## n ## 5b,9 ## n ## 1b; \
+ .long 8 ## n ## 6b,9 ## n ## 1b; \
+ .long 8 ## n ## 7b,9 ## n ## 1b; \
+ .text
+
+ .text
+ .stabs "arch/powerpc/lib/",N_SO,0,0,0f
+ .stabs "copy32.S",N_SO,0,0,0f
+0:
+
+CACHELINE_BYTES = L1_CACHE_BYTES
+LG_CACHELINE_BYTES = L1_CACHE_SHIFT
+CACHELINE_MASK = (L1_CACHE_BYTES-1)
+
+/*
+ * Use dcbz on the complete cache lines in the destination
+ * to set them to zero. This requires that the destination
+ * area is cacheable. -- paulus
+ */
+_GLOBAL(cacheable_memzero)
+ mr r5,r4
+ li r4,0
+ addi r6,r3,-4
+ cmplwi 0,r5,4
+ blt 7f
+ stwu r4,4(r6)
+ beqlr
+ andi. r0,r6,3
+ add r5,r0,r5
+ subf r6,r0,r6
+ clrlwi r7,r6,32-LG_CACHELINE_BYTES
+ add r8,r7,r5
+ srwi r9,r8,LG_CACHELINE_BYTES
+ addic. r9,r9,-1 /* total number of complete cachelines */
+ ble 2f
+ xori r0,r7,CACHELINE_MASK & ~3
+ srwi. r0,r0,2
+ beq 3f
+ mtctr r0
+4: stwu r4,4(r6)
+ bdnz 4b
+3: mtctr r9
+ li r7,4
+#if !defined(CONFIG_8xx)
+10: dcbz r7,r6
+#else
+10: stw r4, 4(r6)
+ stw r4, 8(r6)
+ stw r4, 12(r6)
+ stw r4, 16(r6)
+#if CACHE_LINE_SIZE >= 32
+ stw r4, 20(r6)
+ stw r4, 24(r6)
+ stw r4, 28(r6)
+ stw r4, 32(r6)
+#endif /* CACHE_LINE_SIZE */
+#endif
+ addi r6,r6,CACHELINE_BYTES
+ bdnz 10b
+ clrlwi r5,r8,32-LG_CACHELINE_BYTES
+ addi r5,r5,4
+2: srwi r0,r5,2
+ mtctr r0
+ bdz 6f
+1: stwu r4,4(r6)
+ bdnz 1b
+6: andi. r5,r5,3
+7: cmpwi 0,r5,0
+ beqlr
+ mtctr r5
+ addi r6,r6,3
+8: stbu r4,1(r6)
+ bdnz 8b
+ blr
+
+_GLOBAL(memset)
+ rlwimi r4,r4,8,16,23
+ rlwimi r4,r4,16,0,15
+ addi r6,r3,-4
+ cmplwi 0,r5,4
+ blt 7f
+ stwu r4,4(r6)
+ beqlr
+ andi. r0,r6,3
+ add r5,r0,r5
+ subf r6,r0,r6
+ srwi r0,r5,2
+ mtctr r0
+ bdz 6f
+1: stwu r4,4(r6)
+ bdnz 1b
+6: andi. r5,r5,3
+7: cmpwi 0,r5,0
+ beqlr
+ mtctr r5
+ addi r6,r6,3
+8: stbu r4,1(r6)
+ bdnz 8b
+ blr
+
+/*
+ * This version uses dcbz on the complete cache lines in the
+ * destination area to reduce memory traffic. This requires that
+ * the destination area is cacheable.
+ * We only use this version if the source and dest don't overlap.
+ * -- paulus.
+ */
+_GLOBAL(cacheable_memcpy)
+ add r7,r3,r5 /* test if the src & dst overlap */
+ add r8,r4,r5
+ cmplw 0,r4,r7
+ cmplw 1,r3,r8
+ crand 0,0,4 /* cr0.lt &= cr1.lt */
+ blt memcpy /* if regions overlap */
+
+ addi r4,r4,-4
+ addi r6,r3,-4
+ neg r0,r3
+ andi. r0,r0,CACHELINE_MASK /* # bytes to start of cache line */
+ beq 58f
+
+ cmplw 0,r5,r0 /* is this more than total to do? */
+ blt 63f /* if not much to do */
+ andi. r8,r0,3 /* get it word-aligned first */
+ subf r5,r0,r5
+ mtctr r8
+ beq+ 61f
+70: lbz r9,4(r4) /* do some bytes */
+ stb r9,4(r6)
+ addi r4,r4,1
+ addi r6,r6,1
+ bdnz 70b
+61: srwi. r0,r0,2
+ mtctr r0
+ beq 58f
+72: lwzu r9,4(r4) /* do some words */
+ stwu r9,4(r6)
+ bdnz 72b
+
+58: srwi. r0,r5,LG_CACHELINE_BYTES /* # complete cachelines */
+ clrlwi r5,r5,32-LG_CACHELINE_BYTES
+ li r11,4
+ mtctr r0
+ beq 63f
+53:
+#if !defined(CONFIG_8xx)
+ dcbz r11,r6
+#endif
+ COPY_16_BYTES
+#if L1_CACHE_BYTES >= 32
+ COPY_16_BYTES
+#if L1_CACHE_BYTES >= 64
+ COPY_16_BYTES
+ COPY_16_BYTES
+#if L1_CACHE_BYTES >= 128
+ COPY_16_BYTES
+ COPY_16_BYTES
+ COPY_16_BYTES
+ COPY_16_BYTES
+#endif
+#endif
+#endif
+ bdnz 53b
+
+63: srwi. r0,r5,2
+ mtctr r0
+ beq 64f
+30: lwzu r0,4(r4)
+ stwu r0,4(r6)
+ bdnz 30b
+
+64: andi. r0,r5,3
+ mtctr r0
+ beq+ 65f
+40: lbz r0,4(r4)
+ stb r0,4(r6)
+ addi r4,r4,1
+ addi r6,r6,1
+ bdnz 40b
+65: blr
+
+_GLOBAL(memmove)
+ cmplw 0,r3,r4
+ bgt backwards_memcpy
+ /* fall through */
+
+_GLOBAL(memcpy)
+ srwi. r7,r5,3
+ addi r6,r3,-4
+ addi r4,r4,-4
+ beq 2f /* if less than 8 bytes to do */
+ andi. r0,r6,3 /* get dest word aligned */
+ mtctr r7
+ bne 5f
+1: lwz r7,4(r4)
+ lwzu r8,8(r4)
+ stw r7,4(r6)
+ stwu r8,8(r6)
+ bdnz 1b
+ andi. r5,r5,7
+2: cmplwi 0,r5,4
+ blt 3f
+ lwzu r0,4(r4)
+ addi r5,r5,-4
+ stwu r0,4(r6)
+3: cmpwi 0,r5,0
+ beqlr
+ mtctr r5
+ addi r4,r4,3
+ addi r6,r6,3
+4: lbzu r0,1(r4)
+ stbu r0,1(r6)
+ bdnz 4b
+ blr
+5: subfic r0,r0,4
+ mtctr r0
+6: lbz r7,4(r4)
+ addi r4,r4,1
+ stb r7,4(r6)
+ addi r6,r6,1
+ bdnz 6b
+ subf r5,r0,r5
+ rlwinm. r7,r5,32-3,3,31
+ beq 2b
+ mtctr r7
+ b 1b
+
+_GLOBAL(backwards_memcpy)
+ rlwinm. r7,r5,32-3,3,31 /* r0 = r5 >> 3 */
+ add r6,r3,r5
+ add r4,r4,r5
+ beq 2f
+ andi. r0,r6,3
+ mtctr r7
+ bne 5f
+1: lwz r7,-4(r4)
+ lwzu r8,-8(r4)
+ stw r7,-4(r6)
+ stwu r8,-8(r6)
+ bdnz 1b
+ andi. r5,r5,7
+2: cmplwi 0,r5,4
+ blt 3f
+ lwzu r0,-4(r4)
+ subi r5,r5,4
+ stwu r0,-4(r6)
+3: cmpwi 0,r5,0
+ beqlr
+ mtctr r5
+4: lbzu r0,-1(r4)
+ stbu r0,-1(r6)
+ bdnz 4b
+ blr
+5: mtctr r0
+6: lbzu r7,-1(r4)
+ stbu r7,-1(r6)
+ bdnz 6b
+ subf r5,r0,r5
+ rlwinm. r7,r5,32-3,3,31
+ beq 2b
+ mtctr r7
+ b 1b
+
+_GLOBAL(__copy_tofrom_user)
+ addi r4,r4,-4
+ addi r6,r3,-4
+ neg r0,r3
+ andi. r0,r0,CACHELINE_MASK /* # bytes to start of cache line */
+ beq 58f
+
+ cmplw 0,r5,r0 /* is this more than total to do? */
+ blt 63f /* if not much to do */
+ andi. r8,r0,3 /* get it word-aligned first */
+ mtctr r8
+ beq+ 61f
+70: lbz r9,4(r4) /* do some bytes */
+71: stb r9,4(r6)
+ addi r4,r4,1
+ addi r6,r6,1
+ bdnz 70b
+61: subf r5,r0,r5
+ srwi. r0,r0,2
+ mtctr r0
+ beq 58f
+72: lwzu r9,4(r4) /* do some words */
+73: stwu r9,4(r6)
+ bdnz 72b
+
+ .section __ex_table,"a"
+ .align 2
+ .long 70b,100f
+ .long 71b,101f
+ .long 72b,102f
+ .long 73b,103f
+ .text
+
+58: srwi. r0,r5,LG_CACHELINE_BYTES /* # complete cachelines */
+ clrlwi r5,r5,32-LG_CACHELINE_BYTES
+ li r11,4
+ beq 63f
+
+#ifdef CONFIG_8xx
+ /* Don't use prefetch on 8xx */
+ mtctr r0
+ li r0,0
+53: COPY_16_BYTES_WITHEX(0)
+ bdnz 53b
+
+#else /* not CONFIG_8xx */
+ /* Here we decide how far ahead to prefetch the source */
+ li r3,4
+ cmpwi r0,1
+ li r7,0
+ ble 114f
+ li r7,1
+#if MAX_COPY_PREFETCH > 1
+ /* Heuristically, for large transfers we prefetch
+ MAX_COPY_PREFETCH cachelines ahead. For small transfers
+ we prefetch 1 cacheline ahead. */
+ cmpwi r0,MAX_COPY_PREFETCH
+ ble 112f
+ li r7,MAX_COPY_PREFETCH
+112: mtctr r7
+111: dcbt r3,r4
+ addi r3,r3,CACHELINE_BYTES
+ bdnz 111b
+#else
+ dcbt r3,r4
+ addi r3,r3,CACHELINE_BYTES
+#endif /* MAX_COPY_PREFETCH > 1 */
+
+114: subf r8,r7,r0
+ mr r0,r7
+ mtctr r8
+
+53: dcbt r3,r4
+54: dcbz r11,r6
+ .section __ex_table,"a"
+ .align 2
+ .long 54b,105f
+ .text
+/* the main body of the cacheline loop */
+ COPY_16_BYTES_WITHEX(0)
+#if L1_CACHE_BYTES >= 32
+ COPY_16_BYTES_WITHEX(1)
+#if L1_CACHE_BYTES >= 64
+ COPY_16_BYTES_WITHEX(2)
+ COPY_16_BYTES_WITHEX(3)
+#if L1_CACHE_BYTES >= 128
+ COPY_16_BYTES_WITHEX(4)
+ COPY_16_BYTES_WITHEX(5)
+ COPY_16_BYTES_WITHEX(6)
+ COPY_16_BYTES_WITHEX(7)
+#endif
+#endif
+#endif
+ bdnz 53b
+ cmpwi r0,0
+ li r3,4
+ li r7,0
+ bne 114b
+#endif /* CONFIG_8xx */
+
+63: srwi. r0,r5,2
+ mtctr r0
+ beq 64f
+30: lwzu r0,4(r4)
+31: stwu r0,4(r6)
+ bdnz 30b
+
+64: andi. r0,r5,3
+ mtctr r0
+ beq+ 65f
+40: lbz r0,4(r4)
+41: stb r0,4(r6)
+ addi r4,r4,1
+ addi r6,r6,1
+ bdnz 40b
+65: li r3,0
+ blr
+
+/* read fault, initial single-byte copy */
+100: li r9,0
+ b 90f
+/* write fault, initial single-byte copy */
+101: li r9,1
+90: subf r5,r8,r5
+ li r3,0
+ b 99f
+/* read fault, initial word copy */
+102: li r9,0
+ b 91f
+/* write fault, initial word copy */
+103: li r9,1
+91: li r3,2
+ b 99f
+
+/*
+ * this stuff handles faults in the cacheline loop and branches to either
+ * 104f (if in read part) or 105f (if in write part), after updating r5
+ */
+ COPY_16_BYTES_EXCODE(0)
+#if L1_CACHE_BYTES >= 32
+ COPY_16_BYTES_EXCODE(1)
+#if L1_CACHE_BYTES >= 64
+ COPY_16_BYTES_EXCODE(2)
+ COPY_16_BYTES_EXCODE(3)
+#if L1_CACHE_BYTES >= 128
+ COPY_16_BYTES_EXCODE(4)
+ COPY_16_BYTES_EXCODE(5)
+ COPY_16_BYTES_EXCODE(6)
+ COPY_16_BYTES_EXCODE(7)
+#endif
+#endif
+#endif
+
+/* read fault in cacheline loop */
+104: li r9,0
+ b 92f
+/* fault on dcbz (effectively a write fault) */
+/* or write fault in cacheline loop */
+105: li r9,1
+92: li r3,LG_CACHELINE_BYTES
+ mfctr r8
+ add r0,r0,r8
+ b 106f
+/* read fault in final word loop */
+108: li r9,0
+ b 93f
+/* write fault in final word loop */
+109: li r9,1
+93: andi. r5,r5,3
+ li r3,2
+ b 99f
+/* read fault in final byte loop */
+110: li r9,0
+ b 94f
+/* write fault in final byte loop */
+111: li r9,1
+94: li r5,0
+ li r3,0
+/*
+ * At this stage the number of bytes not copied is
+ * r5 + (ctr << r3), and r9 is 0 for read or 1 for write.
+ */
+99: mfctr r0
+106: slw r3,r0,r3
+ add. r3,r3,r5
+ beq 120f /* shouldn't happen */
+ cmpwi 0,r9,0
+ bne 120f
+/* for a read fault, first try to continue the copy one byte at a time */
+ mtctr r3
+130: lbz r0,4(r4)
+131: stb r0,4(r6)
+ addi r4,r4,1
+ addi r6,r6,1
+ bdnz 130b
+/* then clear out the destination: r3 bytes starting at 4(r6) */
+132: mfctr r3
+ srwi. r0,r3,2
+ li r9,0
+ mtctr r0
+ beq 113f
+112: stwu r9,4(r6)
+ bdnz 112b
+113: andi. r0,r3,3
+ mtctr r0
+ beq 120f
+114: stb r9,4(r6)
+ addi r6,r6,1
+ bdnz 114b
+120: blr
+
+ .section __ex_table,"a"
+ .align 2
+ .long 30b,108b
+ .long 31b,109b
+ .long 40b,110b
+ .long 41b,111b
+ .long 130b,132b
+ .long 131b,120b
+ .long 112b,120b
+ .long 114b,120b
+ .text
diff --git a/arch/ppc64/lib/copypage.S b/arch/powerpc/lib/copypage_64.S
index 733d61618bbf..40523b140109 100644
--- a/arch/ppc64/lib/copypage.S
+++ b/arch/powerpc/lib/copypage_64.S
@@ -11,7 +11,7 @@
#include <asm/processor.h>
#include <asm/ppc_asm.h>
-_GLOBAL(copy_page)
+_GLOBAL(copy_4K_page)
std r31,-8(1)
std r30,-16(1)
std r29,-24(1)
diff --git a/arch/ppc64/lib/copyuser.S b/arch/powerpc/lib/copyuser_64.S
index a0b3fbbd6fb1..6d69ef39b7df 100644
--- a/arch/ppc64/lib/copyuser.S
+++ b/arch/powerpc/lib/copyuser_64.S
@@ -24,7 +24,7 @@ _GLOBAL(__copy_tofrom_user)
std r4,-16(r1)
std r5,-8(r1)
dcbt 0,r4
- beq .Lcopy_page
+ beq .Lcopy_page_4K
andi. r6,r6,7
mtcrf 0x01,r5
blt cr1,.Lshort_copy
@@ -366,7 +366,7 @@ _GLOBAL(__copy_tofrom_user)
* above (following the .Ldst_aligned label) but it runs slightly
* slower on POWER3.
*/
-.Lcopy_page:
+.Lcopy_page_4K:
std r31,-32(1)
std r30,-40(1)
std r29,-48(1)
diff --git a/arch/powerpc/lib/div64.S b/arch/powerpc/lib/div64.S
new file mode 100644
index 000000000000..83d9832fd919
--- /dev/null
+++ b/arch/powerpc/lib/div64.S
@@ -0,0 +1,59 @@
+/*
+ * Divide a 64-bit unsigned number by a 32-bit unsigned number.
+ * This routine assumes that the top 32 bits of the dividend are
+ * non-zero to start with.
+ * On entry, r3 points to the dividend, which get overwritten with
+ * the 64-bit quotient, and r4 contains the divisor.
+ * On exit, r3 contains the remainder.
+ *
+ * Copyright (C) 2002 Paul Mackerras, IBM Corp.
+ *
+ * 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 <asm/ppc_asm.h>
+#include <asm/processor.h>
+
+_GLOBAL(__div64_32)
+ lwz r5,0(r3) # get the dividend into r5/r6
+ lwz r6,4(r3)
+ cmplw r5,r4
+ li r7,0
+ li r8,0
+ blt 1f
+ divwu r7,r5,r4 # if dividend.hi >= divisor,
+ mullw r0,r7,r4 # quotient.hi = dividend.hi / divisor
+ subf. r5,r0,r5 # dividend.hi %= divisor
+ beq 3f
+1: mr r11,r5 # here dividend.hi != 0
+ andis. r0,r5,0xc000
+ bne 2f
+ cntlzw r0,r5 # we are shifting the dividend right
+ li r10,-1 # to make it < 2^32, and shifting
+ srw r10,r10,r0 # the divisor right the same amount,
+ addc r9,r4,r10 # rounding up (so the estimate cannot
+ andc r11,r6,r10 # ever be too large, only too small)
+ andc r9,r9,r10
+ addze r9,r9
+ or r11,r5,r11
+ rotlw r9,r9,r0
+ rotlw r11,r11,r0
+ divwu r11,r11,r9 # then we divide the shifted quantities
+2: mullw r10,r11,r4 # to get an estimate of the quotient,
+ mulhwu r9,r11,r4 # multiply the estimate by the divisor,
+ subfc r6,r10,r6 # take the product from the divisor,
+ add r8,r8,r11 # and add the estimate to the accumulated
+ subfe. r5,r9,r5 # quotient
+ bne 1b
+3: cmplw r6,r4
+ blt 4f
+ divwu r0,r6,r4 # perform the remaining 32-bit division
+ mullw r10,r0,r4 # and get the remainder
+ add r8,r8,r0
+ subf r6,r10,r6
+4: stw r7,0(r3) # return the quotient in *r3
+ stw r8,4(r3)
+ mr r3,r6 # return the remainder in r3
+ blr
diff --git a/arch/ppc64/lib/e2a.c b/arch/powerpc/lib/e2a.c
index d2b834887920..d2b834887920 100644
--- a/arch/ppc64/lib/e2a.c
+++ b/arch/powerpc/lib/e2a.c
diff --git a/arch/ppc64/lib/locks.c b/arch/powerpc/lib/locks.c
index 033643ab69e0..35bd03c41dd1 100644
--- a/arch/ppc64/lib/locks.c
+++ b/arch/powerpc/lib/locks.c
@@ -17,11 +17,13 @@
#include <linux/spinlock.h>
#include <linux/module.h>
#include <linux/stringify.h>
-#include <asm/hvcall.h>
-#include <asm/iSeries/HvCall.h>
+#include <linux/smp.h>
/* waiting for a spinlock... */
#if defined(CONFIG_PPC_SPLPAR) || defined(CONFIG_PPC_ISERIES)
+#include <asm/hvcall.h>
+#include <asm/iseries/hv_call.h>
+#include <asm/smp.h>
void __spin_yield(raw_spinlock_t *lock)
{
diff --git a/arch/powerpc/lib/mem_64.S b/arch/powerpc/lib/mem_64.S
new file mode 100644
index 000000000000..68df20283ff5
--- /dev/null
+++ b/arch/powerpc/lib/mem_64.S
@@ -0,0 +1,119 @@
+/*
+ * String handling functions for PowerPC.
+ *
+ * Copyright (C) 1996 Paul Mackerras.
+ *
+ * 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 <asm/processor.h>
+#include <asm/errno.h>
+#include <asm/ppc_asm.h>
+
+_GLOBAL(memset)
+ neg r0,r3
+ rlwimi r4,r4,8,16,23
+ andi. r0,r0,7 /* # bytes to be 8-byte aligned */
+ rlwimi r4,r4,16,0,15
+ cmplw cr1,r5,r0 /* do we get that far? */
+ rldimi r4,r4,32,0
+ mtcrf 1,r0
+ mr r6,r3
+ blt cr1,8f
+ beq+ 3f /* if already 8-byte aligned */
+ subf r5,r0,r5
+ bf 31,1f
+ stb r4,0(r6)
+ addi r6,r6,1
+1: bf 30,2f
+ sth r4,0(r6)
+ addi r6,r6,2
+2: bf 29,3f
+ stw r4,0(r6)
+ addi r6,r6,4
+3: srdi. r0,r5,6
+ clrldi r5,r5,58
+ mtctr r0
+ beq 5f
+4: std r4,0(r6)
+ std r4,8(r6)
+ std r4,16(r6)
+ std r4,24(r6)
+ std r4,32(r6)
+ std r4,40(r6)
+ std r4,48(r6)
+ std r4,56(r6)
+ addi r6,r6,64
+ bdnz 4b
+5: srwi. r0,r5,3
+ clrlwi r5,r5,29
+ mtcrf 1,r0
+ beq 8f
+ bf 29,6f
+ std r4,0(r6)
+ std r4,8(r6)
+ std r4,16(r6)
+ std r4,24(r6)
+ addi r6,r6,32
+6: bf 30,7f
+ std r4,0(r6)
+ std r4,8(r6)
+ addi r6,r6,16
+7: bf 31,8f
+ std r4,0(r6)
+ addi r6,r6,8
+8: cmpwi r5,0
+ mtcrf 1,r5
+ beqlr+
+ bf 29,9f
+ stw r4,0(r6)
+ addi r6,r6,4
+9: bf 30,10f
+ sth r4,0(r6)
+ addi r6,r6,2
+10: bflr 31
+ stb r4,0(r6)
+ blr
+
+_GLOBAL(memmove)
+ cmplw 0,r3,r4
+ bgt .backwards_memcpy
+ b .memcpy
+
+_GLOBAL(backwards_memcpy)
+ rlwinm. r7,r5,32-3,3,31 /* r0 = r5 >> 3 */
+ add r6,r3,r5
+ add r4,r4,r5
+ beq 2f
+ andi. r0,r6,3
+ mtctr r7
+ bne 5f
+1: lwz r7,-4(r4)
+ lwzu r8,-8(r4)
+ stw r7,-4(r6)
+ stwu r8,-8(r6)
+ bdnz 1b
+ andi. r5,r5,7
+2: cmplwi 0,r5,4
+ blt 3f
+ lwzu r0,-4(r4)
+ subi r5,r5,4
+ stwu r0,-4(r6)
+3: cmpwi 0,r5,0
+ beqlr
+ mtctr r5
+4: lbzu r0,-1(r4)
+ stbu r0,-1(r6)
+ bdnz 4b
+ blr
+5: mtctr r0
+6: lbzu r7,-1(r4)
+ stbu r7,-1(r6)
+ bdnz 6b
+ subf r5,r0,r5
+ rlwinm. r7,r5,32-3,3,31
+ beq 2b
+ mtctr r7
+ b 1b
diff --git a/arch/ppc64/lib/memcpy.S b/arch/powerpc/lib/memcpy_64.S
index 9ccacdf5bcb9..9ccacdf5bcb9 100644
--- a/arch/ppc64/lib/memcpy.S
+++ b/arch/powerpc/lib/memcpy_64.S
diff --git a/arch/powerpc/lib/rheap.c b/arch/powerpc/lib/rheap.c
new file mode 100644
index 000000000000..42c5de2c898f
--- /dev/null
+++ b/arch/powerpc/lib/rheap.c
@@ -0,0 +1,693 @@
+/*
+ * arch/ppc/syslib/rheap.c
+ *
+ * A Remote Heap. Remote means that we don't touch the memory that the
+ * heap points to. Normal heap implementations use the memory they manage
+ * to place their list. We cannot do that because the memory we manage may
+ * have special properties, for example it is uncachable or of different
+ * endianess.
+ *
+ * Author: Pantelis Antoniou <panto@intracom.gr>
+ *
+ * 2004 (c) INTRACOM S.A. Greece. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+
+#include <asm/rheap.h>
+
+/*
+ * Fixup a list_head, needed when copying lists. If the pointers fall
+ * between s and e, apply the delta. This assumes that
+ * sizeof(struct list_head *) == sizeof(unsigned long *).
+ */
+static inline void fixup(unsigned long s, unsigned long e, int d,
+ struct list_head *l)
+{
+ unsigned long *pp;
+
+ pp = (unsigned long *)&l->next;
+ if (*pp >= s && *pp < e)
+ *pp += d;
+
+ pp = (unsigned long *)&l->prev;
+ if (*pp >= s && *pp < e)
+ *pp += d;
+}
+
+/* Grow the allocated blocks */
+static int grow(rh_info_t * info, int max_blocks)
+{
+ rh_block_t *block, *blk;
+ int i, new_blocks;
+ int delta;
+ unsigned long blks, blke;
+
+ if (max_blocks <= info->max_blocks)
+ return -EINVAL;
+
+ new_blocks = max_blocks - info->max_blocks;
+
+ block = kmalloc(sizeof(rh_block_t) * max_blocks, GFP_KERNEL);
+ if (block == NULL)
+ return -ENOMEM;
+
+ if (info->max_blocks > 0) {
+
+ /* copy old block area */
+ memcpy(block, info->block,
+ sizeof(rh_block_t) * info->max_blocks);
+
+ delta = (char *)block - (char *)info->block;
+
+ /* and fixup list pointers */
+ blks = (unsigned long)info->block;
+ blke = (unsigned long)(info->block + info->max_blocks);
+
+ for (i = 0, blk = block; i < info->max_blocks; i++, blk++)
+ fixup(blks, blke, delta, &blk->list);
+
+ fixup(blks, blke, delta, &info->empty_list);
+ fixup(blks, blke, delta, &info->free_list);
+ fixup(blks, blke, delta, &info->taken_list);
+
+ /* free the old allocated memory */
+ if ((info->flags & RHIF_STATIC_BLOCK) == 0)
+ kfree(info->block);
+ }
+
+ info->block = block;
+ info->empty_slots += new_blocks;
+ info->max_blocks = max_blocks;
+ info->flags &= ~RHIF_STATIC_BLOCK;
+
+ /* add all new blocks to the free list */
+ for (i = 0, blk = block + info->max_blocks; i < new_blocks; i++, blk++)
+ list_add(&blk->list, &info->empty_list);
+
+ return 0;
+}
+
+/*
+ * Assure at least the required amount of empty slots. If this function
+ * causes a grow in the block area then all pointers kept to the block
+ * area are invalid!
+ */
+static int assure_empty(rh_info_t * info, int slots)
+{
+ int max_blocks;
+
+ /* This function is not meant to be used to grow uncontrollably */
+ if (slots >= 4)
+ return -EINVAL;
+
+ /* Enough space */
+ if (info->empty_slots >= slots)
+ return 0;
+
+ /* Next 16 sized block */
+ max_blocks = ((info->max_blocks + slots) + 15) & ~15;
+
+ return grow(info, max_blocks);
+}
+
+static rh_block_t *get_slot(rh_info_t * info)
+{
+ rh_block_t *blk;
+
+ /* If no more free slots, and failure to extend. */
+ /* XXX: You should have called assure_empty before */
+ if (info->empty_slots == 0) {
+ printk(KERN_ERR "rh: out of slots; crash is imminent.\n");
+ return NULL;
+ }
+
+ /* Get empty slot to use */
+ blk = list_entry(info->empty_list.next, rh_block_t, list);
+ list_del_init(&blk->list);
+ info->empty_slots--;
+
+ /* Initialize */
+ blk->start = NULL;
+ blk->size = 0;
+ blk->owner = NULL;
+
+ return blk;
+}
+
+static inline void release_slot(rh_info_t * info, rh_block_t * blk)
+{
+ list_add(&blk->list, &info->empty_list);
+ info->empty_slots++;
+}
+
+static void attach_free_block(rh_info_t * info, rh_block_t * blkn)
+{
+ rh_block_t *blk;
+ rh_block_t *before;
+ rh_block_t *after;
+ rh_block_t *next;
+ int size;
+ unsigned long s, e, bs, be;
+ struct list_head *l;
+
+ /* We assume that they are aligned properly */
+ size = blkn->size;
+ s = (unsigned long)blkn->start;
+ e = s + size;
+
+ /* Find the blocks immediately before and after the given one
+ * (if any) */
+ before = NULL;
+ after = NULL;
+ next = NULL;
+
+ list_for_each(l, &info->free_list) {
+ blk = list_entry(l, rh_block_t, list);
+
+ bs = (unsigned long)blk->start;
+ be = bs + blk->size;
+
+ if (next == NULL && s >= bs)
+ next = blk;
+
+ if (be == s)
+ before = blk;
+
+ if (e == bs)
+ after = blk;
+
+ /* If both are not null, break now */
+ if (before != NULL && after != NULL)
+ break;
+ }
+
+ /* Now check if they are really adjacent */
+ if (before != NULL && s != (unsigned long)before->start + before->size)
+ before = NULL;
+
+ if (after != NULL && e != (unsigned long)after->start)
+ after = NULL;
+
+ /* No coalescing; list insert and return */
+ if (before == NULL && after == NULL) {
+
+ if (next != NULL)
+ list_add(&blkn->list, &next->list);
+ else
+ list_add(&blkn->list, &info->free_list);
+
+ return;
+ }
+
+ /* We don't need it anymore */
+ release_slot(info, blkn);
+
+ /* Grow the before block */
+ if (before != NULL && after == NULL) {
+ before->size += size;
+ return;
+ }
+
+ /* Grow the after block backwards */
+ if (before == NULL && after != NULL) {
+ after->start = (int8_t *)after->start - size;
+ after->size += size;
+ return;
+ }
+
+ /* Grow the before block, and release the after block */
+ before->size += size + after->size;
+ list_del(&after->list);
+ release_slot(info, after);
+}
+
+static void attach_taken_block(rh_info_t * info, rh_block_t * blkn)
+{
+ rh_block_t *blk;
+ struct list_head *l;
+
+ /* Find the block immediately before the given one (if any) */
+ list_for_each(l, &info->taken_list) {
+ blk = list_entry(l, rh_block_t, list);
+ if (blk->start > blkn->start) {
+ list_add_tail(&blkn->list, &blk->list);
+ return;
+ }
+ }
+
+ list_add_tail(&blkn->list, &info->taken_list);
+}
+
+/*
+ * Create a remote heap dynamically. Note that no memory for the blocks
+ * are allocated. It will upon the first allocation
+ */
+rh_info_t *rh_create(unsigned int alignment)
+{
+ rh_info_t *info;
+
+ /* Alignment must be a power of two */
+ if ((alignment & (alignment - 1)) != 0)
+ return ERR_PTR(-EINVAL);
+
+ info = kmalloc(sizeof(*info), GFP_KERNEL);
+ if (info == NULL)
+ return ERR_PTR(-ENOMEM);
+
+ info->alignment = alignment;
+
+ /* Initially everything as empty */
+ info->block = NULL;
+ info->max_blocks = 0;
+ info->empty_slots = 0;
+ info->flags = 0;
+
+ INIT_LIST_HEAD(&info->empty_list);
+ INIT_LIST_HEAD(&info->free_list);
+ INIT_LIST_HEAD(&info->taken_list);
+
+ return info;
+}
+
+/*
+ * Destroy a dynamically created remote heap. Deallocate only if the areas
+ * are not static
+ */
+void rh_destroy(rh_info_t * info)
+{
+ if ((info->flags & RHIF_STATIC_BLOCK) == 0 && info->block != NULL)
+ kfree(info->block);
+
+ if ((info->flags & RHIF_STATIC_INFO) == 0)
+ kfree(info);
+}
+
+/*
+ * Initialize in place a remote heap info block. This is needed to support
+ * operation very early in the startup of the kernel, when it is not yet safe
+ * to call kmalloc.
+ */
+void rh_init(rh_info_t * info, unsigned int alignment, int max_blocks,
+ rh_block_t * block)
+{
+ int i;
+ rh_block_t *blk;
+
+ /* Alignment must be a power of two */
+ if ((alignment & (alignment - 1)) != 0)
+ return;
+
+ info->alignment = alignment;
+
+ /* Initially everything as empty */
+ info->block = block;
+ info->max_blocks = max_blocks;
+ info->empty_slots = max_blocks;
+ info->flags = RHIF_STATIC_INFO | RHIF_STATIC_BLOCK;
+
+ INIT_LIST_HEAD(&info->empty_list);
+ INIT_LIST_HEAD(&info->free_list);
+ INIT_LIST_HEAD(&info->taken_list);
+
+ /* Add all new blocks to the free list */
+ for (i = 0, blk = block; i < max_blocks; i++, blk++)
+ list_add(&blk->list, &info->empty_list);
+}
+
+/* Attach a free memory region, coalesces regions if adjuscent */
+int rh_attach_region(rh_info_t * info, void *start, int size)
+{
+ rh_block_t *blk;
+ unsigned long s, e, m;
+ int r;
+
+ /* The region must be aligned */
+ s = (unsigned long)start;
+ e = s + size;
+ m = info->alignment - 1;
+
+ /* Round start up */
+ s = (s + m) & ~m;
+
+ /* Round end down */
+ e = e & ~m;
+
+ /* Take final values */
+ start = (void *)s;
+ size = (int)(e - s);
+
+ /* Grow the blocks, if needed */
+ r = assure_empty(info, 1);
+ if (r < 0)
+ return r;
+
+ blk = get_slot(info);
+ blk->start = start;
+ blk->size = size;
+ blk->owner = NULL;
+
+ attach_free_block(info, blk);
+
+ return 0;
+}
+
+/* Detatch given address range, splits free block if needed. */
+void *rh_detach_region(rh_info_t * info, void *start, int size)
+{
+ struct list_head *l;
+ rh_block_t *blk, *newblk;
+ unsigned long s, e, m, bs, be;
+
+ /* Validate size */
+ if (size <= 0)
+ return ERR_PTR(-EINVAL);
+
+ /* The region must be aligned */
+ s = (unsigned long)start;
+ e = s + size;
+ m = info->alignment - 1;
+
+ /* Round start up */
+ s = (s + m) & ~m;
+
+ /* Round end down */
+ e = e & ~m;
+
+ if (assure_empty(info, 1) < 0)
+ return ERR_PTR(-ENOMEM);
+
+ blk = NULL;
+ list_for_each(l, &info->free_list) {
+ blk = list_entry(l, rh_block_t, list);
+ /* The range must lie entirely inside one free block */
+ bs = (unsigned long)blk->start;
+ be = (unsigned long)blk->start + blk->size;
+ if (s >= bs && e <= be)
+ break;
+ blk = NULL;
+ }
+
+ if (blk == NULL)
+ return ERR_PTR(-ENOMEM);
+
+ /* Perfect fit */
+ if (bs == s && be == e) {
+ /* Delete from free list, release slot */
+ list_del(&blk->list);
+ release_slot(info, blk);
+ return (void *)s;
+ }
+
+ /* blk still in free list, with updated start and/or size */
+ if (bs == s || be == e) {
+ if (bs == s)
+ blk->start = (int8_t *)blk->start + size;
+ blk->size -= size;
+
+ } else {
+ /* The front free fragment */
+ blk->size = s - bs;
+
+ /* the back free fragment */
+ newblk = get_slot(info);
+ newblk->start = (void *)e;
+ newblk->size = be - e;
+
+ list_add(&newblk->list, &blk->list);
+ }
+
+ return (void *)s;
+}
+
+void *rh_alloc(rh_info_t * info, int size, const char *owner)
+{
+ struct list_head *l;
+ rh_block_t *blk;
+ rh_block_t *newblk;
+ void *start;
+
+ /* Validate size */
+ if (size <= 0)
+ return ERR_PTR(-EINVAL);
+
+ /* Align to configured alignment */
+ size = (size + (info->alignment - 1)) & ~(info->alignment - 1);
+
+ if (assure_empty(info, 1) < 0)
+ return ERR_PTR(-ENOMEM);
+
+ blk = NULL;
+ list_for_each(l, &info->free_list) {
+ blk = list_entry(l, rh_block_t, list);
+ if (size <= blk->size)
+ break;
+ blk = NULL;
+ }
+
+ if (blk == NULL)
+ return ERR_PTR(-ENOMEM);
+
+ /* Just fits */
+ if (blk->size == size) {
+ /* Move from free list to taken list */
+ list_del(&blk->list);
+ blk->owner = owner;
+ start = blk->start;
+
+ attach_taken_block(info, blk);
+
+ return start;
+ }
+
+ newblk = get_slot(info);
+ newblk->start = blk->start;
+ newblk->size = size;
+ newblk->owner = owner;
+
+ /* blk still in free list, with updated start, size */
+ blk->start = (int8_t *)blk->start + size;
+ blk->size -= size;
+
+ start = newblk->start;
+
+ attach_taken_block(info, newblk);
+
+ return start;
+}
+
+/* allocate at precisely the given address */
+void *rh_alloc_fixed(rh_info_t * info, void *start, int size, const char *owner)
+{
+ struct list_head *l;
+ rh_block_t *blk, *newblk1, *newblk2;
+ unsigned long s, e, m, bs, be;
+
+ /* Validate size */
+ if (size <= 0)
+ return ERR_PTR(-EINVAL);
+
+ /* The region must be aligned */
+ s = (unsigned long)start;
+ e = s + size;
+ m = info->alignment - 1;
+
+ /* Round start up */
+ s = (s + m) & ~m;
+
+ /* Round end down */
+ e = e & ~m;
+
+ if (assure_empty(info, 2) < 0)
+ return ERR_PTR(-ENOMEM);
+
+ blk = NULL;
+ list_for_each(l, &info->free_list) {
+ blk = list_entry(l, rh_block_t, list);
+ /* The range must lie entirely inside one free block */
+ bs = (unsigned long)blk->start;
+ be = (unsigned long)blk->start + blk->size;
+ if (s >= bs && e <= be)
+ break;
+ }
+
+ if (blk == NULL)
+ return ERR_PTR(-ENOMEM);
+
+ /* Perfect fit */
+ if (bs == s && be == e) {
+ /* Move from free list to taken list */
+ list_del(&blk->list);
+ blk->owner = owner;
+
+ start = blk->start;
+ attach_taken_block(info, blk);
+
+ return start;
+
+ }
+
+ /* blk still in free list, with updated start and/or size */
+ if (bs == s || be == e) {
+ if (bs == s)
+ blk->start = (int8_t *)blk->start + size;
+ blk->size -= size;
+
+ } else {
+ /* The front free fragment */
+ blk->size = s - bs;
+
+ /* The back free fragment */
+ newblk2 = get_slot(info);
+ newblk2->start = (void *)e;
+ newblk2->size = be - e;
+
+ list_add(&newblk2->list, &blk->list);
+ }
+
+ newblk1 = get_slot(info);
+ newblk1->start = (void *)s;
+ newblk1->size = e - s;
+ newblk1->owner = owner;
+
+ start = newblk1->start;
+ attach_taken_block(info, newblk1);
+
+ return start;
+}
+
+int rh_free(rh_info_t * info, void *start)
+{
+ rh_block_t *blk, *blk2;
+ struct list_head *l;
+ int size;
+
+ /* Linear search for block */
+ blk = NULL;
+ list_for_each(l, &info->taken_list) {
+ blk2 = list_entry(l, rh_block_t, list);
+ if (start < blk2->start)
+ break;
+ blk = blk2;
+ }
+
+ if (blk == NULL || start > (blk->start + blk->size))
+ return -EINVAL;
+
+ /* Remove from taken list */
+ list_del(&blk->list);
+
+ /* Get size of freed block */
+ size = blk->size;
+ attach_free_block(info, blk);
+
+ return size;
+}
+
+int rh_get_stats(rh_info_t * info, int what, int max_stats, rh_stats_t * stats)
+{
+ rh_block_t *blk;
+ struct list_head *l;
+ struct list_head *h;
+ int nr;
+
+ switch (what) {
+
+ case RHGS_FREE:
+ h = &info->free_list;
+ break;
+
+ case RHGS_TAKEN:
+ h = &info->taken_list;
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ /* Linear search for block */
+ nr = 0;
+ list_for_each(l, h) {
+ blk = list_entry(l, rh_block_t, list);
+ if (stats != NULL && nr < max_stats) {
+ stats->start = blk->start;
+ stats->size = blk->size;
+ stats->owner = blk->owner;
+ stats++;
+ }
+ nr++;
+ }
+
+ return nr;
+}
+
+int rh_set_owner(rh_info_t * info, void *start, const char *owner)
+{
+ rh_block_t *blk, *blk2;
+ struct list_head *l;
+ int size;
+
+ /* Linear search for block */
+ blk = NULL;
+ list_for_each(l, &info->taken_list) {
+ blk2 = list_entry(l, rh_block_t, list);
+ if (start < blk2->start)
+ break;
+ blk = blk2;
+ }
+
+ if (blk == NULL || start > (blk->start + blk->size))
+ return -EINVAL;
+
+ blk->owner = owner;
+ size = blk->size;
+
+ return size;
+}
+
+void rh_dump(rh_info_t * info)
+{
+ static rh_stats_t st[32]; /* XXX maximum 32 blocks */
+ int maxnr;
+ int i, nr;
+
+ maxnr = sizeof(st) / sizeof(st[0]);
+
+ printk(KERN_INFO
+ "info @0x%p (%d slots empty / %d max)\n",
+ info, info->empty_slots, info->max_blocks);
+
+ printk(KERN_INFO " Free:\n");
+ nr = rh_get_stats(info, RHGS_FREE, maxnr, st);
+ if (nr > maxnr)
+ nr = maxnr;
+ for (i = 0; i < nr; i++)
+ printk(KERN_INFO
+ " 0x%p-0x%p (%u)\n",
+ st[i].start, (int8_t *) st[i].start + st[i].size,
+ st[i].size);
+ printk(KERN_INFO "\n");
+
+ printk(KERN_INFO " Taken:\n");
+ nr = rh_get_stats(info, RHGS_TAKEN, maxnr, st);
+ if (nr > maxnr)
+ nr = maxnr;
+ for (i = 0; i < nr; i++)
+ printk(KERN_INFO
+ " 0x%p-0x%p (%u) %s\n",
+ st[i].start, (int8_t *) st[i].start + st[i].size,
+ st[i].size, st[i].owner != NULL ? st[i].owner : "");
+ printk(KERN_INFO "\n");
+}
+
+void rh_dump_blk(rh_info_t * info, rh_block_t * blk)
+{
+ printk(KERN_INFO
+ "blk @0x%p: 0x%p-0x%p (%u)\n",
+ blk, blk->start, (int8_t *) blk->start + blk->size, blk->size);
+}
diff --git a/arch/ppc64/lib/sstep.c b/arch/powerpc/lib/sstep.c
index e79123d1485c..666c2aa55016 100644
--- a/arch/ppc64/lib/sstep.c
+++ b/arch/powerpc/lib/sstep.c
@@ -10,13 +10,18 @@
*/
#include <linux/kernel.h>
#include <linux/ptrace.h>
+#include <linux/config.h>
#include <asm/sstep.h>
#include <asm/processor.h>
extern char system_call_common[];
+#ifdef CONFIG_PPC64
/* Bits in SRR1 that are copied from MSR */
#define MSR_MASK 0xffffffff87c0ffff
+#else
+#define MSR_MASK 0x87c0ffff
+#endif
/*
* Determine whether a conditional branch instruction would branch.
@@ -66,6 +71,7 @@ int emulate_step(struct pt_regs *regs, unsigned int instr)
if (branch_taken(instr, regs))
regs->nip = imm;
return 1;
+#ifdef CONFIG_PPC64
case 17: /* sc */
/*
* N.B. this uses knowledge about how the syscall
@@ -79,6 +85,7 @@ int emulate_step(struct pt_regs *regs, unsigned int instr)
regs->nip = (unsigned long) &system_call_common;
regs->msr = MSR_KERNEL;
return 1;
+#endif
case 18: /* b */
imm = instr & 0x03fffffc;
if (imm & 0x02000000)
@@ -121,6 +128,15 @@ int emulate_step(struct pt_regs *regs, unsigned int instr)
if ((regs->msr & MSR_SF) == 0)
regs->nip &= 0xffffffffUL;
return 1;
+ case 0x124: /* mtmsr */
+ imm = regs->gpr[rd];
+ if ((imm & MSR_RI) == 0)
+ /* can't step mtmsr that would clear MSR_RI */
+ return -1;
+ regs->msr = imm;
+ regs->nip += 4;
+ return 1;
+#ifdef CONFIG_PPC64
case 0x164: /* mtmsrd */
/* only MSR_EE and MSR_RI get changed if bit 15 set */
/* mtmsrd doesn't change MSR_HV and MSR_ME */
@@ -135,6 +151,7 @@ int emulate_step(struct pt_regs *regs, unsigned int instr)
if ((imm & MSR_SF) == 0)
regs->nip &= 0xffffffffUL;
return 1;
+#endif
}
}
return 0;
diff --git a/arch/ppc64/lib/strcase.c b/arch/powerpc/lib/strcase.c
index e84f243368c0..36b521091bbc 100644
--- a/arch/ppc64/lib/strcase.c
+++ b/arch/powerpc/lib/strcase.c
@@ -1,11 +1,3 @@
-/*
- * c 2001 PPC 64 Team, IBM Corp
- *
- * 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/ctype.h>
int strcasecmp(const char *s1, const char *s2)
diff --git a/arch/ppc64/lib/string.S b/arch/powerpc/lib/string.S
index 813587e5c2ec..b9ca84ed8927 100644
--- a/arch/ppc64/lib/string.S
+++ b/arch/powerpc/lib/string.S
@@ -8,10 +8,21 @@
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
+#include <linux/config.h>
#include <asm/processor.h>
#include <asm/errno.h>
#include <asm/ppc_asm.h>
+ .section __ex_table,"a"
+#ifdef CONFIG_PPC64
+ .align 3
+#define EXTBL .llong
+#else
+ .align 2
+#define EXTBL .long
+#endif
+ .text
+
_GLOBAL(strcpy)
addi r5,r3,-1
addi r4,r4,-1
@@ -21,6 +32,8 @@ _GLOBAL(strcpy)
bne 1b
blr
+/* This clears out any unused part of the destination buffer,
+ just as the libc version does. -- paulus */
_GLOBAL(strncpy)
cmpwi 0,r5,0
beqlr
@@ -31,6 +44,12 @@ _GLOBAL(strncpy)
cmpwi 0,r0,0
stbu r0,1(r6)
bdnzf 2,1b /* dec ctr, branch if ctr != 0 && !cr0.eq */
+ bnelr /* if we didn't hit a null char, we're done */
+ mfctr r5
+ cmpwi 0,r5,0 /* any space left in destination buffer? */
+ beqlr /* we know r0 == 0 here */
+2: stbu r0,1(r6) /* clear it out if so */
+ bdnz 2b
blr
_GLOBAL(strcat)
@@ -65,112 +84,6 @@ _GLOBAL(strlen)
subf r3,r3,r4
blr
-_GLOBAL(memset)
- neg r0,r3
- rlwimi r4,r4,8,16,23
- andi. r0,r0,7 /* # bytes to be 8-byte aligned */
- rlwimi r4,r4,16,0,15
- cmplw cr1,r5,r0 /* do we get that far? */
- rldimi r4,r4,32,0
- mtcrf 1,r0
- mr r6,r3
- blt cr1,8f
- beq+ 3f /* if already 8-byte aligned */
- subf r5,r0,r5
- bf 31,1f
- stb r4,0(r6)
- addi r6,r6,1
-1: bf 30,2f
- sth r4,0(r6)
- addi r6,r6,2
-2: bf 29,3f
- stw r4,0(r6)
- addi r6,r6,4
-3: srdi. r0,r5,6
- clrldi r5,r5,58
- mtctr r0
- beq 5f
-4: std r4,0(r6)
- std r4,8(r6)
- std r4,16(r6)
- std r4,24(r6)
- std r4,32(r6)
- std r4,40(r6)
- std r4,48(r6)
- std r4,56(r6)
- addi r6,r6,64
- bdnz 4b
-5: srwi. r0,r5,3
- clrlwi r5,r5,29
- mtcrf 1,r0
- beq 8f
- bf 29,6f
- std r4,0(r6)
- std r4,8(r6)
- std r4,16(r6)
- std r4,24(r6)
- addi r6,r6,32
-6: bf 30,7f
- std r4,0(r6)
- std r4,8(r6)
- addi r6,r6,16
-7: bf 31,8f
- std r4,0(r6)
- addi r6,r6,8
-8: cmpwi r5,0
- mtcrf 1,r5
- beqlr+
- bf 29,9f
- stw r4,0(r6)
- addi r6,r6,4
-9: bf 30,10f
- sth r4,0(r6)
- addi r6,r6,2
-10: bflr 31
- stb r4,0(r6)
- blr
-
-_GLOBAL(memmove)
- cmplw 0,r3,r4
- bgt .backwards_memcpy
- b .memcpy
-
-_GLOBAL(backwards_memcpy)
- rlwinm. r7,r5,32-3,3,31 /* r0 = r5 >> 3 */
- add r6,r3,r5
- add r4,r4,r5
- beq 2f
- andi. r0,r6,3
- mtctr r7
- bne 5f
-1: lwz r7,-4(r4)
- lwzu r8,-8(r4)
- stw r7,-4(r6)
- stwu r8,-8(r6)
- bdnz 1b
- andi. r5,r5,7
-2: cmplwi 0,r5,4
- blt 3f
- lwzu r0,-4(r4)
- subi r5,r5,4
- stwu r0,-4(r6)
-3: cmpwi 0,r5,0
- beqlr
- mtctr r5
-4: lbzu r0,-1(r4)
- stbu r0,-1(r6)
- bdnz 4b
- blr
-5: mtctr r0
-6: lbzu r7,-1(r4)
- stbu r7,-1(r6)
- bdnz 6b
- subf r5,r0,r5
- rlwinm. r7,r5,32-3,3,31
- beq 2b
- mtctr r7
- b 1b
-
_GLOBAL(memcmp)
cmpwi 0,r5,0
ble- 2f
@@ -234,13 +147,11 @@ _GLOBAL(__clear_user)
blr
.section __ex_table,"a"
- .align 3
- .llong 11b,90b
- .llong 1b,91b
- .llong 8b,92b
+ EXTBL 11b,90b
+ EXTBL 1b,91b
+ EXTBL 8b,92b
.text
-/* r3 = dst, r4 = src, r5 = count */
_GLOBAL(__strncpy_from_user)
addi r6,r3,-1
addi r4,r4,-1
@@ -259,14 +170,17 @@ _GLOBAL(__strncpy_from_user)
blr
.section __ex_table,"a"
- .align 3
- .llong 1b,99b
+ EXTBL 1b,99b
.text
-/* r3 = str, r4 = len (> 0) */
+/* r3 = str, r4 = len (> 0), r5 = top (highest addr) */
_GLOBAL(__strnlen_user)
addi r7,r3,-1
- mtctr r4 /* ctr = len */
+ subf r6,r7,r5 /* top+1 - str */
+ cmplw 0,r4,r6
+ bge 0f
+ mr r6,r4
+0: mtctr r6 /* ctr = min(len, top - str) */
1: lbzu r0,1(r7) /* get next byte */
cmpwi 0,r0,0
bdnzf 2,1b /* loop if --ctr != 0 && byte != 0 */
@@ -281,5 +195,4 @@ _GLOBAL(__strnlen_user)
blr
.section __ex_table,"a"
- .align 3
- .llong 1b,99b
+ EXTBL 1b,99b
diff --git a/arch/ppc64/lib/usercopy.c b/arch/powerpc/lib/usercopy_64.c
index 5eea6f3c1e03..5eea6f3c1e03 100644
--- a/arch/ppc64/lib/usercopy.c
+++ b/arch/powerpc/lib/usercopy_64.c
diff --git a/arch/powerpc/mm/44x_mmu.c b/arch/powerpc/mm/44x_mmu.c
new file mode 100644
index 000000000000..3d79ce281b67
--- /dev/null
+++ b/arch/powerpc/mm/44x_mmu.c
@@ -0,0 +1,120 @@
+/*
+ * Modifications by Matt Porter (mporter@mvista.com) to support
+ * PPC44x Book E processors.
+ *
+ * This file contains the routines for initializing the MMU
+ * on the 4xx series of chips.
+ * -- paulus
+ *
+ * Derived from arch/ppc/mm/init.c:
+ * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
+ *
+ * Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au)
+ * and Cort Dougan (PReP) (cort@cs.nmt.edu)
+ * Copyright (C) 1996 Paul Mackerras
+ * Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk).
+ *
+ * Derived from "arch/i386/mm/init.c"
+ * Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds
+ *
+ * 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/config.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/ptrace.h>
+#include <linux/mman.h>
+#include <linux/mm.h>
+#include <linux/swap.h>
+#include <linux/stddef.h>
+#include <linux/vmalloc.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/highmem.h>
+
+#include <asm/pgalloc.h>
+#include <asm/prom.h>
+#include <asm/io.h>
+#include <asm/mmu_context.h>
+#include <asm/pgtable.h>
+#include <asm/mmu.h>
+#include <asm/uaccess.h>
+#include <asm/smp.h>
+#include <asm/bootx.h>
+#include <asm/machdep.h>
+#include <asm/setup.h>
+
+#include "mmu_decl.h"
+
+extern char etext[], _stext[];
+
+/* Used by the 44x TLB replacement exception handler.
+ * Just needed it declared someplace.
+ */
+unsigned int tlb_44x_index = 0;
+unsigned int tlb_44x_hwater = 62;
+
+/*
+ * "Pins" a 256MB TLB entry in AS0 for kernel lowmem
+ */
+static void __init
+ppc44x_pin_tlb(int slot, unsigned int virt, unsigned int phys)
+{
+ unsigned long attrib = 0;
+
+ __asm__ __volatile__("\
+ clrrwi %2,%2,10\n\
+ ori %2,%2,%4\n\
+ clrrwi %1,%1,10\n\
+ li %0,0\n\
+ ori %0,%0,%5\n\
+ tlbwe %2,%3,%6\n\
+ tlbwe %1,%3,%7\n\
+ tlbwe %0,%3,%8"
+ :
+ : "r" (attrib), "r" (phys), "r" (virt), "r" (slot),
+ "i" (PPC44x_TLB_VALID | PPC44x_TLB_256M),
+ "i" (PPC44x_TLB_SW | PPC44x_TLB_SR | PPC44x_TLB_SX | PPC44x_TLB_G),
+ "i" (PPC44x_TLB_PAGEID),
+ "i" (PPC44x_TLB_XLAT),
+ "i" (PPC44x_TLB_ATTRIB));
+}
+
+/*
+ * MMU_init_hw does the chip-specific initialization of the MMU hardware.
+ */
+void __init MMU_init_hw(void)
+{
+ flush_instruction_cache();
+}
+
+unsigned long __init mmu_mapin_ram(void)
+{
+ unsigned int pinned_tlbs = 1;
+ int i;
+
+ /* Determine number of entries necessary to cover lowmem */
+ pinned_tlbs = (unsigned int)
+ (_ALIGN(total_lowmem, PPC44x_PIN_SIZE) >> PPC44x_PIN_SHIFT);
+
+ /* Write upper watermark to save location */
+ tlb_44x_hwater = PPC44x_LOW_SLOT - pinned_tlbs;
+
+ /* If necessary, set additional pinned TLBs */
+ if (pinned_tlbs > 1)
+ for (i = (PPC44x_LOW_SLOT-(pinned_tlbs-1)); i < PPC44x_LOW_SLOT; i++) {
+ unsigned int phys_addr = (PPC44x_LOW_SLOT-i) * PPC44x_PIN_SIZE;
+ ppc44x_pin_tlb(i, phys_addr+PAGE_OFFSET, phys_addr);
+ }
+
+ return total_lowmem;
+}
diff --git a/arch/powerpc/mm/4xx_mmu.c b/arch/powerpc/mm/4xx_mmu.c
new file mode 100644
index 000000000000..b7bcbc232f39
--- /dev/null
+++ b/arch/powerpc/mm/4xx_mmu.c
@@ -0,0 +1,141 @@
+/*
+ * This file contains the routines for initializing the MMU
+ * on the 4xx series of chips.
+ * -- paulus
+ *
+ * Derived from arch/ppc/mm/init.c:
+ * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
+ *
+ * Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au)
+ * and Cort Dougan (PReP) (cort@cs.nmt.edu)
+ * Copyright (C) 1996 Paul Mackerras
+ * Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk).
+ *
+ * Derived from "arch/i386/mm/init.c"
+ * Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds
+ *
+ * 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/config.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/ptrace.h>
+#include <linux/mman.h>
+#include <linux/mm.h>
+#include <linux/swap.h>
+#include <linux/stddef.h>
+#include <linux/vmalloc.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/highmem.h>
+
+#include <asm/pgalloc.h>
+#include <asm/prom.h>
+#include <asm/io.h>
+#include <asm/mmu_context.h>
+#include <asm/pgtable.h>
+#include <asm/mmu.h>
+#include <asm/uaccess.h>
+#include <asm/smp.h>
+#include <asm/bootx.h>
+#include <asm/machdep.h>
+#include <asm/setup.h>
+#include "mmu_decl.h"
+
+extern int __map_without_ltlbs;
+/*
+ * MMU_init_hw does the chip-specific initialization of the MMU hardware.
+ */
+void __init MMU_init_hw(void)
+{
+ /*
+ * The Zone Protection Register (ZPR) defines how protection will
+ * be applied to every page which is a member of a given zone. At
+ * present, we utilize only two of the 4xx's zones.
+ * The zone index bits (of ZSEL) in the PTE are used for software
+ * indicators, except the LSB. For user access, zone 1 is used,
+ * for kernel access, zone 0 is used. We set all but zone 1
+ * to zero, allowing only kernel access as indicated in the PTE.
+ * For zone 1, we set a 01 binary (a value of 10 will not work)
+ * to allow user access as indicated in the PTE. This also allows
+ * kernel access as indicated in the PTE.
+ */
+
+ mtspr(SPRN_ZPR, 0x10000000);
+
+ flush_instruction_cache();
+
+ /*
+ * Set up the real-mode cache parameters for the exception vector
+ * handlers (which are run in real-mode).
+ */
+
+ mtspr(SPRN_DCWR, 0x00000000); /* All caching is write-back */
+
+ /*
+ * Cache instruction and data space where the exception
+ * vectors and the kernel live in real-mode.
+ */
+
+ mtspr(SPRN_DCCR, 0xF0000000); /* 512 MB of data space at 0x0. */
+ mtspr(SPRN_ICCR, 0xF0000000); /* 512 MB of instr. space at 0x0. */
+}
+
+#define LARGE_PAGE_SIZE_16M (1<<24)
+#define LARGE_PAGE_SIZE_4M (1<<22)
+
+unsigned long __init mmu_mapin_ram(void)
+{
+ unsigned long v, s;
+ phys_addr_t p;
+
+ v = KERNELBASE;
+ p = PPC_MEMSTART;
+ s = 0;
+
+ if (__map_without_ltlbs) {
+ return s;
+ }
+
+ while (s <= (total_lowmem - LARGE_PAGE_SIZE_16M)) {
+ pmd_t *pmdp;
+ unsigned long val = p | _PMD_SIZE_16M | _PAGE_HWEXEC | _PAGE_HWWRITE;
+
+ spin_lock(&init_mm.page_table_lock);
+ pmdp = pmd_offset(pgd_offset_k(v), v);
+ pmd_val(*pmdp++) = val;
+ pmd_val(*pmdp++) = val;
+ pmd_val(*pmdp++) = val;
+ pmd_val(*pmdp++) = val;
+ spin_unlock(&init_mm.page_table_lock);
+
+ v += LARGE_PAGE_SIZE_16M;
+ p += LARGE_PAGE_SIZE_16M;
+ s += LARGE_PAGE_SIZE_16M;
+ }
+
+ while (s <= (total_lowmem - LARGE_PAGE_SIZE_4M)) {
+ pmd_t *pmdp;
+ unsigned long val = p | _PMD_SIZE_4M | _PAGE_HWEXEC | _PAGE_HWWRITE;
+
+ spin_lock(&init_mm.page_table_lock);
+ pmdp = pmd_offset(pgd_offset_k(v), v);
+ pmd_val(*pmdp) = val;
+ spin_unlock(&init_mm.page_table_lock);
+
+ v += LARGE_PAGE_SIZE_4M;
+ p += LARGE_PAGE_SIZE_4M;
+ s += LARGE_PAGE_SIZE_4M;
+ }
+
+ return s;
+}
diff --git a/arch/powerpc/mm/Makefile b/arch/powerpc/mm/Makefile
new file mode 100644
index 000000000000..93441e7a2921
--- /dev/null
+++ b/arch/powerpc/mm/Makefile
@@ -0,0 +1,21 @@
+#
+# Makefile for the linux ppc-specific parts of the memory manager.
+#
+
+ifeq ($(CONFIG_PPC64),y)
+EXTRA_CFLAGS += -mno-minimal-toc
+endif
+
+obj-y := fault.o mem.o lmb.o
+obj-$(CONFIG_PPC32) += init_32.o pgtable_32.o mmu_context_32.o
+hash-$(CONFIG_PPC_MULTIPLATFORM) := hash_native_64.o
+obj-$(CONFIG_PPC64) += init_64.o pgtable_64.o mmu_context_64.o \
+ hash_utils_64.o hash_low_64.o tlb_64.o \
+ slb_low.o slb.o stab.o mmap.o imalloc.o \
+ $(hash-y)
+obj-$(CONFIG_PPC_STD_MMU_32) += ppc_mmu_32.o hash_low_32.o tlb_32.o
+obj-$(CONFIG_40x) += 4xx_mmu.o
+obj-$(CONFIG_44x) += 44x_mmu.o
+obj-$(CONFIG_FSL_BOOKE) += fsl_booke_mmu.o
+obj-$(CONFIG_NEED_MULTIPLE_NODES) += numa.o
+obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
diff --git a/arch/ppc64/mm/fault.c b/arch/powerpc/mm/fault.c
index be3f25cf3e9f..93d4fbfdb724 100644
--- a/arch/ppc64/mm/fault.c
+++ b/arch/powerpc/mm/fault.c
@@ -1,7 +1,7 @@
/*
* arch/ppc/mm/fault.c
*
- * PowerPC version
+ * PowerPC version
* Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
*
* Derived from "arch/i386/mm/fault.c"
@@ -24,10 +24,11 @@
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/types.h>
+#include <linux/ptrace.h>
#include <linux/mman.h>
#include <linux/mm.h>
#include <linux/interrupt.h>
-#include <linux/smp_lock.h>
+#include <linux/highmem.h>
#include <linux/module.h>
#include <linux/kprobes.h>
@@ -37,6 +38,7 @@
#include <asm/mmu_context.h>
#include <asm/system.h>
#include <asm/uaccess.h>
+#include <asm/tlbflush.h>
#include <asm/kdebug.h>
#include <asm/siginfo.h>
@@ -78,6 +80,7 @@ static int store_updates_sp(struct pt_regs *regs)
return 0;
}
+#if !(defined(CONFIG_4xx) || defined(CONFIG_BOOKE))
static void do_dabr(struct pt_regs *regs, unsigned long error_code)
{
siginfo_t info;
@@ -99,12 +102,18 @@ static void do_dabr(struct pt_regs *regs, unsigned long error_code)
info.si_addr = (void __user *)regs->nip;
force_sig_info(SIGTRAP, &info, current);
}
+#endif /* !(CONFIG_4xx || CONFIG_BOOKE)*/
/*
- * The error_code parameter is
+ * For 600- and 800-family processors, the error_code parameter is DSISR
+ * for a data fault, SRR1 for an instruction fault. For 400-family processors
+ * the error_code parameter is ESR for a data fault, 0 for an instruction
+ * fault.
+ * For 64-bit processors, the error_code parameter is
* - DSISR for a non-SLB data access fault,
* - SRR1 & 0x08000000 for a non-SLB instruction access fault
* - 0 any SLB fault.
+ *
* The return value is 0 if the fault was handled, or the signal
* number if this is a kernel fault that can't be handled here.
*/
@@ -114,12 +123,25 @@ int __kprobes do_page_fault(struct pt_regs *regs, unsigned long address,
struct vm_area_struct * vma;
struct mm_struct *mm = current->mm;
siginfo_t info;
- unsigned long code = SEGV_MAPERR;
- unsigned long is_write = error_code & DSISR_ISSTORE;
- unsigned long trap = TRAP(regs);
- unsigned long is_exec = trap == 0x400;
+ int code = SEGV_MAPERR;
+ int is_write = 0;
+ int trap = TRAP(regs);
+ int is_exec = trap == 0x400;
- BUG_ON((trap == 0x380) || (trap == 0x480));
+#if !(defined(CONFIG_4xx) || defined(CONFIG_BOOKE))
+ /*
+ * Fortunately the bit assignments in SRR1 for an instruction
+ * fault and DSISR for a data fault are mostly the same for the
+ * bits we are interested in. But there are some bits which
+ * indicate errors in DSISR but can validly be set in SRR1.
+ */
+ if (trap == 0x400)
+ error_code &= 0x48200000;
+ else
+ is_write = error_code & DSISR_ISSTORE;
+#else
+ is_write = error_code & ESR_DST;
+#endif /* CONFIG_4xx || CONFIG_BOOKE */
if (notify_die(DIE_PAGE_FAULT, "page_fault", regs, error_code,
11, SIGSEGV) == NOTIFY_STOP)
@@ -134,10 +156,13 @@ int __kprobes do_page_fault(struct pt_regs *regs, unsigned long address,
if (!user_mode(regs) && (address >= TASK_SIZE))
return SIGSEGV;
+#if !(defined(CONFIG_4xx) || defined(CONFIG_BOOKE))
if (error_code & DSISR_DABRMATCH) {
+ /* DABR match */
do_dabr(regs, error_code);
return 0;
}
+#endif /* !(CONFIG_4xx || CONFIG_BOOKE)*/
if (in_atomic() || mm == NULL) {
if (!user_mode(regs))
@@ -176,10 +201,8 @@ int __kprobes do_page_fault(struct pt_regs *regs, unsigned long address,
vma = find_vma(mm, address);
if (!vma)
goto bad_area;
-
- if (vma->vm_start <= address) {
+ if (vma->vm_start <= address)
goto good_area;
- }
if (!(vma->vm_flags & VM_GROWSDOWN))
goto bad_area;
@@ -214,35 +237,76 @@ int __kprobes do_page_fault(struct pt_regs *regs, unsigned long address,
&& (!user_mode(regs) || !store_updates_sp(regs)))
goto bad_area;
}
-
if (expand_stack(vma, address))
goto bad_area;
good_area:
code = SEGV_ACCERR;
+#if defined(CONFIG_6xx)
+ if (error_code & 0x95700000)
+ /* an error such as lwarx to I/O controller space,
+ address matching DABR, eciwx, etc. */
+ goto bad_area;
+#endif /* CONFIG_6xx */
+#if defined(CONFIG_8xx)
+ /* The MPC8xx seems to always set 0x80000000, which is
+ * "undefined". Of those that can be set, this is the only
+ * one which seems bad.
+ */
+ if (error_code & 0x10000000)
+ /* Guarded storage error. */
+ goto bad_area;
+#endif /* CONFIG_8xx */
if (is_exec) {
+#ifdef CONFIG_PPC64
/* protection fault */
if (error_code & DSISR_PROTFAULT)
goto bad_area;
if (!(vma->vm_flags & VM_EXEC))
goto bad_area;
+#endif
+#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
+ pte_t *ptep;
+
+ /* Since 4xx/Book-E supports per-page execute permission,
+ * we lazily flush dcache to icache. */
+ ptep = NULL;
+ if (get_pteptr(mm, address, &ptep) && pte_present(*ptep)) {
+ struct page *page = pte_page(*ptep);
+
+ if (! test_bit(PG_arch_1, &page->flags)) {
+ flush_dcache_icache_page(page);
+ set_bit(PG_arch_1, &page->flags);
+ }
+ pte_update(ptep, 0, _PAGE_HWEXEC);
+ _tlbie(address);
+ pte_unmap(ptep);
+ up_read(&mm->mmap_sem);
+ return 0;
+ }
+ if (ptep != NULL)
+ pte_unmap(ptep);
+#endif
/* a write */
} else if (is_write) {
if (!(vma->vm_flags & VM_WRITE))
goto bad_area;
/* a read */
} else {
- if (!(vma->vm_flags & VM_READ))
+ /* protection fault */
+ if (error_code & 0x08000000)
+ goto bad_area;
+ if (!(vma->vm_flags & (VM_READ | VM_EXEC)))
goto bad_area;
}
- survive:
/*
* If for any reason at all we couldn't handle the fault,
* make sure we exit gracefully rather than endlessly redo
* the fault.
*/
+ survive:
switch (handle_mm_fault(mm, vma, address, is_write)) {
case VM_FAULT_MINOR:
@@ -268,15 +332,11 @@ bad_area:
bad_area_nosemaphore:
/* User mode accesses cause a SIGSEGV */
if (user_mode(regs)) {
- info.si_signo = SIGSEGV;
- info.si_errno = 0;
- info.si_code = code;
- info.si_addr = (void __user *) address;
- force_sig_info(SIGSEGV, &info, current);
+ _exception(SIGSEGV, regs, code, address);
return 0;
}
- if (trap == 0x400 && (error_code & DSISR_PROTFAULT)
+ if (is_exec && (error_code & DSISR_PROTFAULT)
&& printk_ratelimit())
printk(KERN_CRIT "kernel tried to execute NX-protected"
" page (%lx) - exploit attempt? (uid: %d)\n",
@@ -315,8 +375,8 @@ do_sigbus:
/*
* bad_page_fault is called when we have a bad access from the kernel.
- * It is called from do_page_fault above and from some of the procedures
- * in traps.c.
+ * It is called from the DSI and ISI handlers in head.S and from some
+ * of the procedures in traps.c.
*/
void bad_page_fault(struct pt_regs *regs, unsigned long address, int sig)
{
@@ -329,5 +389,22 @@ void bad_page_fault(struct pt_regs *regs, unsigned long address, int sig)
}
/* kernel has accessed a bad area */
+
+ printk(KERN_ALERT "Unable to handle kernel paging request for ");
+ switch (regs->trap) {
+ case 0x300:
+ case 0x380:
+ printk("data at address 0x%08lx\n", regs->dar);
+ break;
+ case 0x400:
+ case 0x480:
+ printk("instruction fetch\n");
+ break;
+ default:
+ printk("unknown fault\n");
+ }
+ printk(KERN_ALERT "Faulting instruction address: 0x%08lx\n",
+ regs->nip);
+
die("Kernel access of bad area", regs, sig);
}
diff --git a/arch/powerpc/mm/fsl_booke_mmu.c b/arch/powerpc/mm/fsl_booke_mmu.c
new file mode 100644
index 000000000000..af9ca0eb6d55
--- /dev/null
+++ b/arch/powerpc/mm/fsl_booke_mmu.c
@@ -0,0 +1,237 @@
+/*
+ * Modifications by Kumar Gala (kumar.gala@freescale.com) to support
+ * E500 Book E processors.
+ *
+ * Copyright 2004 Freescale Semiconductor, Inc
+ *
+ * This file contains the routines for initializing the MMU
+ * on the 4xx series of chips.
+ * -- paulus
+ *
+ * Derived from arch/ppc/mm/init.c:
+ * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
+ *
+ * Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au)
+ * and Cort Dougan (PReP) (cort@cs.nmt.edu)
+ * Copyright (C) 1996 Paul Mackerras
+ * Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk).
+ *
+ * Derived from "arch/i386/mm/init.c"
+ * Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds
+ *
+ * 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/config.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/ptrace.h>
+#include <linux/mman.h>
+#include <linux/mm.h>
+#include <linux/swap.h>
+#include <linux/stddef.h>
+#include <linux/vmalloc.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/highmem.h>
+
+#include <asm/pgalloc.h>
+#include <asm/prom.h>
+#include <asm/io.h>
+#include <asm/mmu_context.h>
+#include <asm/pgtable.h>
+#include <asm/mmu.h>
+#include <asm/uaccess.h>
+#include <asm/smp.h>
+#include <asm/bootx.h>
+#include <asm/machdep.h>
+#include <asm/setup.h>
+
+extern void loadcam_entry(unsigned int index);
+unsigned int tlbcam_index;
+unsigned int num_tlbcam_entries;
+static unsigned long __cam0, __cam1, __cam2;
+extern unsigned long total_lowmem;
+extern unsigned long __max_low_memory;
+#define MAX_LOW_MEM CONFIG_LOWMEM_SIZE
+
+#define NUM_TLBCAMS (16)
+
+struct tlbcam {
+ u32 MAS0;
+ u32 MAS1;
+ u32 MAS2;
+ u32 MAS3;
+ u32 MAS7;
+} TLBCAM[NUM_TLBCAMS];
+
+struct tlbcamrange {
+ unsigned long start;
+ unsigned long limit;
+ phys_addr_t phys;
+} tlbcam_addrs[NUM_TLBCAMS];
+
+extern unsigned int tlbcam_index;
+
+/*
+ * Return PA for this VA if it is mapped by a CAM, or 0
+ */
+unsigned long v_mapped_by_tlbcam(unsigned long va)
+{
+ int b;
+ for (b = 0; b < tlbcam_index; ++b)
+ if (va >= tlbcam_addrs[b].start && va < tlbcam_addrs[b].limit)
+ return tlbcam_addrs[b].phys + (va - tlbcam_addrs[b].start);
+ return 0;
+}
+
+/*
+ * Return VA for a given PA or 0 if not mapped
+ */
+unsigned long p_mapped_by_tlbcam(unsigned long pa)
+{
+ int b;
+ for (b = 0; b < tlbcam_index; ++b)
+ if (pa >= tlbcam_addrs[b].phys
+ && pa < (tlbcam_addrs[b].limit-tlbcam_addrs[b].start)
+ +tlbcam_addrs[b].phys)
+ return tlbcam_addrs[b].start+(pa-tlbcam_addrs[b].phys);
+ return 0;
+}
+
+/*
+ * Set up one of the I/D BAT (block address translation) register pairs.
+ * The parameters are not checked; in particular size must be a power
+ * of 4 between 4k and 256M.
+ */
+void settlbcam(int index, unsigned long virt, phys_addr_t phys,
+ unsigned int size, int flags, unsigned int pid)
+{
+ unsigned int tsize, lz;
+
+ asm ("cntlzw %0,%1" : "=r" (lz) : "r" (size));
+ tsize = (21 - lz) / 2;
+
+#ifdef CONFIG_SMP
+ if ((flags & _PAGE_NO_CACHE) == 0)
+ flags |= _PAGE_COHERENT;
+#endif
+
+ TLBCAM[index].MAS0 = MAS0_TLBSEL(1) | MAS0_ESEL(index) | MAS0_NV(index+1);
+ TLBCAM[index].MAS1 = MAS1_VALID | MAS1_IPROT | MAS1_TSIZE(tsize) | MAS1_TID(pid);
+ TLBCAM[index].MAS2 = virt & PAGE_MASK;
+
+ TLBCAM[index].MAS2 |= (flags & _PAGE_WRITETHRU) ? MAS2_W : 0;
+ TLBCAM[index].MAS2 |= (flags & _PAGE_NO_CACHE) ? MAS2_I : 0;
+ TLBCAM[index].MAS2 |= (flags & _PAGE_COHERENT) ? MAS2_M : 0;
+ TLBCAM[index].MAS2 |= (flags & _PAGE_GUARDED) ? MAS2_G : 0;
+ TLBCAM[index].MAS2 |= (flags & _PAGE_ENDIAN) ? MAS2_E : 0;
+
+ TLBCAM[index].MAS3 = (phys & PAGE_MASK) | MAS3_SX | MAS3_SR;
+ TLBCAM[index].MAS3 |= ((flags & _PAGE_RW) ? MAS3_SW : 0);
+
+#ifndef CONFIG_KGDB /* want user access for breakpoints */
+ if (flags & _PAGE_USER) {
+ TLBCAM[index].MAS3 |= MAS3_UX | MAS3_UR;
+ TLBCAM[index].MAS3 |= ((flags & _PAGE_RW) ? MAS3_UW : 0);
+ }
+#else
+ TLBCAM[index].MAS3 |= MAS3_UX | MAS3_UR;
+ TLBCAM[index].MAS3 |= ((flags & _PAGE_RW) ? MAS3_UW : 0);
+#endif
+
+ tlbcam_addrs[index].start = virt;
+ tlbcam_addrs[index].limit = virt + size - 1;
+ tlbcam_addrs[index].phys = phys;
+
+ loadcam_entry(index);
+}
+
+void invalidate_tlbcam_entry(int index)
+{
+ TLBCAM[index].MAS0 = MAS0_TLBSEL(1) | MAS0_ESEL(index);
+ TLBCAM[index].MAS1 = ~MAS1_VALID;
+
+ loadcam_entry(index);
+}
+
+void __init cam_mapin_ram(unsigned long cam0, unsigned long cam1,
+ unsigned long cam2)
+{
+ settlbcam(0, KERNELBASE, PPC_MEMSTART, cam0, _PAGE_KERNEL, 0);
+ tlbcam_index++;
+ if (cam1) {
+ tlbcam_index++;
+ settlbcam(1, KERNELBASE+cam0, PPC_MEMSTART+cam0, cam1, _PAGE_KERNEL, 0);
+ }
+ if (cam2) {
+ tlbcam_index++;
+ settlbcam(2, KERNELBASE+cam0+cam1, PPC_MEMSTART+cam0+cam1, cam2, _PAGE_KERNEL, 0);
+ }
+}
+
+/*
+ * MMU_init_hw does the chip-specific initialization of the MMU hardware.
+ */
+void __init MMU_init_hw(void)
+{
+ flush_instruction_cache();
+}
+
+unsigned long __init mmu_mapin_ram(void)
+{
+ cam_mapin_ram(__cam0, __cam1, __cam2);
+
+ return __cam0 + __cam1 + __cam2;
+}
+
+
+void __init
+adjust_total_lowmem(void)
+{
+ unsigned long max_low_mem = MAX_LOW_MEM;
+ unsigned long cam_max = 0x10000000;
+ unsigned long ram;
+
+ /* adjust CAM size to max_low_mem */
+ if (max_low_mem < cam_max)
+ cam_max = max_low_mem;
+
+ /* adjust lowmem size to max_low_mem */
+ if (max_low_mem < total_lowmem)
+ ram = max_low_mem;
+ else
+ ram = total_lowmem;
+
+ /* Calculate CAM values */
+ __cam0 = 1UL << 2 * (__ilog2(ram) / 2);
+ if (__cam0 > cam_max)
+ __cam0 = cam_max;
+ ram -= __cam0;
+ if (ram) {
+ __cam1 = 1UL << 2 * (__ilog2(ram) / 2);
+ if (__cam1 > cam_max)
+ __cam1 = cam_max;
+ ram -= __cam1;
+ }
+ if (ram) {
+ __cam2 = 1UL << 2 * (__ilog2(ram) / 2);
+ if (__cam2 > cam_max)
+ __cam2 = cam_max;
+ ram -= __cam2;
+ }
+
+ printk(KERN_INFO "Memory CAM mapping: CAM0=%ldMb, CAM1=%ldMb,"
+ " CAM2=%ldMb residual: %ldMb\n",
+ __cam0 >> 20, __cam1 >> 20, __cam2 >> 20,
+ (total_lowmem - __cam0 - __cam1 - __cam2) >> 20);
+ __max_low_memory = max_low_mem = __cam0 + __cam1 + __cam2;
+}
diff --git a/arch/powerpc/mm/hash_low_32.S b/arch/powerpc/mm/hash_low_32.S
new file mode 100644
index 000000000000..12ccd7155bac
--- /dev/null
+++ b/arch/powerpc/mm/hash_low_32.S
@@ -0,0 +1,618 @@
+/*
+ * arch/ppc/kernel/hashtable.S
+ *
+ * $Id: hashtable.S,v 1.6 1999/10/08 01:56:15 paulus Exp $
+ *
+ * PowerPC version
+ * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
+ * Rewritten by Cort Dougan (cort@cs.nmt.edu) for PReP
+ * Copyright (C) 1996 Cort Dougan <cort@cs.nmt.edu>
+ * Adapted for Power Macintosh by Paul Mackerras.
+ * Low-level exception handlers and MMU support
+ * rewritten by Paul Mackerras.
+ * Copyright (C) 1996 Paul Mackerras.
+ *
+ * This file contains low-level assembler routines for managing
+ * the PowerPC MMU hash table. (PPC 8xx processors don't use a
+ * hash table, so this file is not used on them.)
+ *
+ * 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/config.h>
+#include <asm/reg.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/cputable.h>
+#include <asm/ppc_asm.h>
+#include <asm/thread_info.h>
+#include <asm/asm-offsets.h>
+
+#ifdef CONFIG_SMP
+ .comm mmu_hash_lock,4
+#endif /* CONFIG_SMP */
+
+/*
+ * Sync CPUs with hash_page taking & releasing the hash
+ * table lock
+ */
+#ifdef CONFIG_SMP
+ .text
+_GLOBAL(hash_page_sync)
+ lis r8,mmu_hash_lock@h
+ ori r8,r8,mmu_hash_lock@l
+ lis r0,0x0fff
+ b 10f
+11: lwz r6,0(r8)
+ cmpwi 0,r6,0
+ bne 11b
+10: lwarx r6,0,r8
+ cmpwi 0,r6,0
+ bne- 11b
+ stwcx. r0,0,r8
+ bne- 10b
+ isync
+ eieio
+ li r0,0
+ stw r0,0(r8)
+ blr
+#endif
+
+/*
+ * Load a PTE into the hash table, if possible.
+ * The address is in r4, and r3 contains an access flag:
+ * _PAGE_RW (0x400) if a write.
+ * r9 contains the SRR1 value, from which we use the MSR_PR bit.
+ * SPRG3 contains the physical address of the current task's thread.
+ *
+ * Returns to the caller if the access is illegal or there is no
+ * mapping for the address. Otherwise it places an appropriate PTE
+ * in the hash table and returns from the exception.
+ * Uses r0, r3 - r8, ctr, lr.
+ */
+ .text
+_GLOBAL(hash_page)
+#ifdef CONFIG_PPC64BRIDGE
+ mfmsr r0
+ clrldi r0,r0,1 /* make sure it's in 32-bit mode */
+ MTMSRD(r0)
+ isync
+#endif
+ tophys(r7,0) /* gets -KERNELBASE into r7 */
+#ifdef CONFIG_SMP
+ addis r8,r7,mmu_hash_lock@h
+ ori r8,r8,mmu_hash_lock@l
+ lis r0,0x0fff
+ b 10f
+11: lwz r6,0(r8)
+ cmpwi 0,r6,0
+ bne 11b
+10: lwarx r6,0,r8
+ cmpwi 0,r6,0
+ bne- 11b
+ stwcx. r0,0,r8
+ bne- 10b
+ isync
+#endif
+ /* Get PTE (linux-style) and check access */
+ lis r0,KERNELBASE@h /* check if kernel address */
+ cmplw 0,r4,r0
+ mfspr r8,SPRN_SPRG3 /* current task's THREAD (phys) */
+ ori r3,r3,_PAGE_USER|_PAGE_PRESENT /* test low addresses as user */
+ lwz r5,PGDIR(r8) /* virt page-table root */
+ blt+ 112f /* assume user more likely */
+ lis r5,swapper_pg_dir@ha /* if kernel address, use */
+ addi r5,r5,swapper_pg_dir@l /* kernel page table */
+ rlwimi r3,r9,32-12,29,29 /* MSR_PR -> _PAGE_USER */
+112: add r5,r5,r7 /* convert to phys addr */
+ rlwimi r5,r4,12,20,29 /* insert top 10 bits of address */
+ lwz r8,0(r5) /* get pmd entry */
+ rlwinm. r8,r8,0,0,19 /* extract address of pte page */
+#ifdef CONFIG_SMP
+ beq- hash_page_out /* return if no mapping */
+#else
+ /* XXX it seems like the 601 will give a machine fault on the
+ rfi if its alignment is wrong (bottom 4 bits of address are
+ 8 or 0xc) and we have had a not-taken conditional branch
+ to the address following the rfi. */
+ beqlr-
+#endif
+ rlwimi r8,r4,22,20,29 /* insert next 10 bits of address */
+ rlwinm r0,r3,32-3,24,24 /* _PAGE_RW access -> _PAGE_DIRTY */
+ ori r0,r0,_PAGE_ACCESSED|_PAGE_HASHPTE
+
+ /*
+ * Update the linux PTE atomically. We do the lwarx up-front
+ * because almost always, there won't be a permission violation
+ * and there won't already be an HPTE, and thus we will have
+ * to update the PTE to set _PAGE_HASHPTE. -- paulus.
+ */
+retry:
+ lwarx r6,0,r8 /* get linux-style pte */
+ andc. r5,r3,r6 /* check access & ~permission */
+#ifdef CONFIG_SMP
+ bne- hash_page_out /* return if access not permitted */
+#else
+ bnelr-
+#endif
+ or r5,r0,r6 /* set accessed/dirty bits */
+ stwcx. r5,0,r8 /* attempt to update PTE */
+ bne- retry /* retry if someone got there first */
+
+ mfsrin r3,r4 /* get segment reg for segment */
+ mfctr r0
+ stw r0,_CTR(r11)
+ bl create_hpte /* add the hash table entry */
+
+#ifdef CONFIG_SMP
+ eieio
+ addis r8,r7,mmu_hash_lock@ha
+ li r0,0
+ stw r0,mmu_hash_lock@l(r8)
+#endif
+
+ /* Return from the exception */
+ lwz r5,_CTR(r11)
+ mtctr r5
+ lwz r0,GPR0(r11)
+ lwz r7,GPR7(r11)
+ lwz r8,GPR8(r11)
+ b fast_exception_return
+
+#ifdef CONFIG_SMP
+hash_page_out:
+ eieio
+ addis r8,r7,mmu_hash_lock@ha
+ li r0,0
+ stw r0,mmu_hash_lock@l(r8)
+ blr
+#endif /* CONFIG_SMP */
+
+/*
+ * Add an entry for a particular page to the hash table.
+ *
+ * add_hash_page(unsigned context, unsigned long va, unsigned long pmdval)
+ *
+ * We assume any necessary modifications to the pte (e.g. setting
+ * the accessed bit) have already been done and that there is actually
+ * a hash table in use (i.e. we're not on a 603).
+ */
+_GLOBAL(add_hash_page)
+ mflr r0
+ stw r0,4(r1)
+
+ /* Convert context and va to VSID */
+ mulli r3,r3,897*16 /* multiply context by context skew */
+ rlwinm r0,r4,4,28,31 /* get ESID (top 4 bits of va) */
+ mulli r0,r0,0x111 /* multiply by ESID skew */
+ add r3,r3,r0 /* note create_hpte trims to 24 bits */
+
+#ifdef CONFIG_SMP
+ rlwinm r8,r1,0,0,18 /* use cpu number to make tag */
+ lwz r8,TI_CPU(r8) /* to go in mmu_hash_lock */
+ oris r8,r8,12
+#endif /* CONFIG_SMP */
+
+ /*
+ * We disable interrupts here, even on UP, because we don't
+ * want to race with hash_page, and because we want the
+ * _PAGE_HASHPTE bit to be a reliable indication of whether
+ * the HPTE exists (or at least whether one did once).
+ * We also turn off the MMU for data accesses so that we
+ * we can't take a hash table miss (assuming the code is
+ * covered by a BAT). -- paulus
+ */
+ mfmsr r10
+ SYNC
+ rlwinm r0,r10,0,17,15 /* clear bit 16 (MSR_EE) */
+ rlwinm r0,r0,0,28,26 /* clear MSR_DR */
+ mtmsr r0
+ SYNC_601
+ isync
+
+ tophys(r7,0)
+
+#ifdef CONFIG_SMP
+ addis r9,r7,mmu_hash_lock@ha
+ addi r9,r9,mmu_hash_lock@l
+10: lwarx r0,0,r9 /* take the mmu_hash_lock */
+ cmpi 0,r0,0
+ bne- 11f
+ stwcx. r8,0,r9
+ beq+ 12f
+11: lwz r0,0(r9)
+ cmpi 0,r0,0
+ beq 10b
+ b 11b
+12: isync
+#endif
+
+ /*
+ * Fetch the linux pte and test and set _PAGE_HASHPTE atomically.
+ * If _PAGE_HASHPTE was already set, we don't replace the existing
+ * HPTE, so we just unlock and return.
+ */
+ mr r8,r5
+ rlwimi r8,r4,22,20,29
+1: lwarx r6,0,r8
+ andi. r0,r6,_PAGE_HASHPTE
+ bne 9f /* if HASHPTE already set, done */
+ ori r5,r6,_PAGE_HASHPTE
+ stwcx. r5,0,r8
+ bne- 1b
+
+ bl create_hpte
+
+9:
+#ifdef CONFIG_SMP
+ eieio
+ li r0,0
+ stw r0,0(r9) /* clear mmu_hash_lock */
+#endif
+
+ /* reenable interrupts and DR */
+ mtmsr r10
+ SYNC_601
+ isync
+
+ lwz r0,4(r1)
+ mtlr r0
+ blr
+
+/*
+ * This routine adds a hardware PTE to the hash table.
+ * It is designed to be called with the MMU either on or off.
+ * r3 contains the VSID, r4 contains the virtual address,
+ * r5 contains the linux PTE, r6 contains the old value of the
+ * linux PTE (before setting _PAGE_HASHPTE) and r7 contains the
+ * offset to be added to addresses (0 if the MMU is on,
+ * -KERNELBASE if it is off).
+ * On SMP, the caller should have the mmu_hash_lock held.
+ * We assume that the caller has (or will) set the _PAGE_HASHPTE
+ * bit in the linux PTE in memory. The value passed in r6 should
+ * be the old linux PTE value; if it doesn't have _PAGE_HASHPTE set
+ * this routine will skip the search for an existing HPTE.
+ * This procedure modifies r0, r3 - r6, r8, cr0.
+ * -- paulus.
+ *
+ * For speed, 4 of the instructions get patched once the size and
+ * physical address of the hash table are known. These definitions
+ * of Hash_base and Hash_bits below are just an example.
+ */
+Hash_base = 0xc0180000
+Hash_bits = 12 /* e.g. 256kB hash table */
+Hash_msk = (((1 << Hash_bits) - 1) * 64)
+
+#ifndef CONFIG_PPC64BRIDGE
+/* defines for the PTE format for 32-bit PPCs */
+#define PTE_SIZE 8
+#define PTEG_SIZE 64
+#define LG_PTEG_SIZE 6
+#define LDPTEu lwzu
+#define STPTE stw
+#define CMPPTE cmpw
+#define PTE_H 0x40
+#define PTE_V 0x80000000
+#define TST_V(r) rlwinm. r,r,0,0,0
+#define SET_V(r) oris r,r,PTE_V@h
+#define CLR_V(r,t) rlwinm r,r,0,1,31
+
+#else
+/* defines for the PTE format for 64-bit PPCs */
+#define PTE_SIZE 16
+#define PTEG_SIZE 128
+#define LG_PTEG_SIZE 7
+#define LDPTEu ldu
+#define STPTE std
+#define CMPPTE cmpd
+#define PTE_H 2
+#define PTE_V 1
+#define TST_V(r) andi. r,r,PTE_V
+#define SET_V(r) ori r,r,PTE_V
+#define CLR_V(r,t) li t,PTE_V; andc r,r,t
+#endif /* CONFIG_PPC64BRIDGE */
+
+#define HASH_LEFT 31-(LG_PTEG_SIZE+Hash_bits-1)
+#define HASH_RIGHT 31-LG_PTEG_SIZE
+
+_GLOBAL(create_hpte)
+ /* Convert linux-style PTE (r5) to low word of PPC-style PTE (r8) */
+ rlwinm r8,r5,32-10,31,31 /* _PAGE_RW -> PP lsb */
+ rlwinm r0,r5,32-7,31,31 /* _PAGE_DIRTY -> PP lsb */
+ and r8,r8,r0 /* writable if _RW & _DIRTY */
+ rlwimi r5,r5,32-1,30,30 /* _PAGE_USER -> PP msb */
+ rlwimi r5,r5,32-2,31,31 /* _PAGE_USER -> PP lsb */
+ ori r8,r8,0xe14 /* clear out reserved bits and M */
+ andc r8,r5,r8 /* PP = user? (rw&dirty? 2: 3): 0 */
+BEGIN_FTR_SECTION
+ ori r8,r8,_PAGE_COHERENT /* set M (coherence required) */
+END_FTR_SECTION_IFSET(CPU_FTR_NEED_COHERENT)
+
+ /* Construct the high word of the PPC-style PTE (r5) */
+#ifndef CONFIG_PPC64BRIDGE
+ rlwinm r5,r3,7,1,24 /* put VSID in 0x7fffff80 bits */
+ rlwimi r5,r4,10,26,31 /* put in API (abbrev page index) */
+#else /* CONFIG_PPC64BRIDGE */
+ clrlwi r3,r3,8 /* reduce vsid to 24 bits */
+ sldi r5,r3,12 /* shift vsid into position */
+ rlwimi r5,r4,16,20,24 /* put in API (abbrev page index) */
+#endif /* CONFIG_PPC64BRIDGE */
+ SET_V(r5) /* set V (valid) bit */
+
+ /* Get the address of the primary PTE group in the hash table (r3) */
+_GLOBAL(hash_page_patch_A)
+ addis r0,r7,Hash_base@h /* base address of hash table */
+ rlwimi r0,r3,LG_PTEG_SIZE,HASH_LEFT,HASH_RIGHT /* VSID -> hash */
+ rlwinm r3,r4,20+LG_PTEG_SIZE,HASH_LEFT,HASH_RIGHT /* PI -> hash */
+ xor r3,r3,r0 /* make primary hash */
+ li r0,8 /* PTEs/group */
+
+ /*
+ * Test the _PAGE_HASHPTE bit in the old linux PTE, and skip the search
+ * if it is clear, meaning that the HPTE isn't there already...
+ */
+ andi. r6,r6,_PAGE_HASHPTE
+ beq+ 10f /* no PTE: go look for an empty slot */
+ tlbie r4
+
+ addis r4,r7,htab_hash_searches@ha
+ lwz r6,htab_hash_searches@l(r4)
+ addi r6,r6,1 /* count how many searches we do */
+ stw r6,htab_hash_searches@l(r4)
+
+ /* Search the primary PTEG for a PTE whose 1st (d)word matches r5 */
+ mtctr r0
+ addi r4,r3,-PTE_SIZE
+1: LDPTEu r6,PTE_SIZE(r4) /* get next PTE */
+ CMPPTE 0,r6,r5
+ bdnzf 2,1b /* loop while ctr != 0 && !cr0.eq */
+ beq+ found_slot
+
+ /* Search the secondary PTEG for a matching PTE */
+ ori r5,r5,PTE_H /* set H (secondary hash) bit */
+_GLOBAL(hash_page_patch_B)
+ xoris r4,r3,Hash_msk>>16 /* compute secondary hash */
+ xori r4,r4,(-PTEG_SIZE & 0xffff)
+ addi r4,r4,-PTE_SIZE
+ mtctr r0
+2: LDPTEu r6,PTE_SIZE(r4)
+ CMPPTE 0,r6,r5
+ bdnzf 2,2b
+ beq+ found_slot
+ xori r5,r5,PTE_H /* clear H bit again */
+
+ /* Search the primary PTEG for an empty slot */
+10: mtctr r0
+ addi r4,r3,-PTE_SIZE /* search primary PTEG */
+1: LDPTEu r6,PTE_SIZE(r4) /* get next PTE */
+ TST_V(r6) /* test valid bit */
+ bdnzf 2,1b /* loop while ctr != 0 && !cr0.eq */
+ beq+ found_empty
+
+ /* update counter of times that the primary PTEG is full */
+ addis r4,r7,primary_pteg_full@ha
+ lwz r6,primary_pteg_full@l(r4)
+ addi r6,r6,1
+ stw r6,primary_pteg_full@l(r4)
+
+ /* Search the secondary PTEG for an empty slot */
+ ori r5,r5,PTE_H /* set H (secondary hash) bit */
+_GLOBAL(hash_page_patch_C)
+ xoris r4,r3,Hash_msk>>16 /* compute secondary hash */
+ xori r4,r4,(-PTEG_SIZE & 0xffff)
+ addi r4,r4,-PTE_SIZE
+ mtctr r0
+2: LDPTEu r6,PTE_SIZE(r4)
+ TST_V(r6)
+ bdnzf 2,2b
+ beq+ found_empty
+ xori r5,r5,PTE_H /* clear H bit again */
+
+ /*
+ * Choose an arbitrary slot in the primary PTEG to overwrite.
+ * Since both the primary and secondary PTEGs are full, and we
+ * have no information that the PTEs in the primary PTEG are
+ * more important or useful than those in the secondary PTEG,
+ * and we know there is a definite (although small) speed
+ * advantage to putting the PTE in the primary PTEG, we always
+ * put the PTE in the primary PTEG.
+ */
+ addis r4,r7,next_slot@ha
+ lwz r6,next_slot@l(r4)
+ addi r6,r6,PTE_SIZE
+ andi. r6,r6,7*PTE_SIZE
+ stw r6,next_slot@l(r4)
+ add r4,r3,r6
+
+#ifndef CONFIG_SMP
+ /* Store PTE in PTEG */
+found_empty:
+ STPTE r5,0(r4)
+found_slot:
+ STPTE r8,PTE_SIZE/2(r4)
+
+#else /* CONFIG_SMP */
+/*
+ * Between the tlbie above and updating the hash table entry below,
+ * another CPU could read the hash table entry and put it in its TLB.
+ * There are 3 cases:
+ * 1. using an empty slot
+ * 2. updating an earlier entry to change permissions (i.e. enable write)
+ * 3. taking over the PTE for an unrelated address
+ *
+ * In each case it doesn't really matter if the other CPUs have the old
+ * PTE in their TLB. So we don't need to bother with another tlbie here,
+ * which is convenient as we've overwritten the register that had the
+ * address. :-) The tlbie above is mainly to make sure that this CPU comes
+ * and gets the new PTE from the hash table.
+ *
+ * We do however have to make sure that the PTE is never in an invalid
+ * state with the V bit set.
+ */
+found_empty:
+found_slot:
+ CLR_V(r5,r0) /* clear V (valid) bit in PTE */
+ STPTE r5,0(r4)
+ sync
+ TLBSYNC
+ STPTE r8,PTE_SIZE/2(r4) /* put in correct RPN, WIMG, PP bits */
+ sync
+ SET_V(r5)
+ STPTE r5,0(r4) /* finally set V bit in PTE */
+#endif /* CONFIG_SMP */
+
+ sync /* make sure pte updates get to memory */
+ blr
+
+ .comm next_slot,4
+ .comm primary_pteg_full,4
+ .comm htab_hash_searches,4
+
+/*
+ * Flush the entry for a particular page from the hash table.
+ *
+ * flush_hash_pages(unsigned context, unsigned long va, unsigned long pmdval,
+ * int count)
+ *
+ * We assume that there is a hash table in use (Hash != 0).
+ */
+_GLOBAL(flush_hash_pages)
+ tophys(r7,0)
+
+ /*
+ * We disable interrupts here, even on UP, because we want
+ * the _PAGE_HASHPTE bit to be a reliable indication of
+ * whether the HPTE exists (or at least whether one did once).
+ * We also turn off the MMU for data accesses so that we
+ * we can't take a hash table miss (assuming the code is
+ * covered by a BAT). -- paulus
+ */
+ mfmsr r10
+ SYNC
+ rlwinm r0,r10,0,17,15 /* clear bit 16 (MSR_EE) */
+ rlwinm r0,r0,0,28,26 /* clear MSR_DR */
+ mtmsr r0
+ SYNC_601
+ isync
+
+ /* First find a PTE in the range that has _PAGE_HASHPTE set */
+ rlwimi r5,r4,22,20,29
+1: lwz r0,0(r5)
+ cmpwi cr1,r6,1
+ andi. r0,r0,_PAGE_HASHPTE
+ bne 2f
+ ble cr1,19f
+ addi r4,r4,0x1000
+ addi r5,r5,4
+ addi r6,r6,-1
+ b 1b
+
+ /* Convert context and va to VSID */
+2: mulli r3,r3,897*16 /* multiply context by context skew */
+ rlwinm r0,r4,4,28,31 /* get ESID (top 4 bits of va) */
+ mulli r0,r0,0x111 /* multiply by ESID skew */
+ add r3,r3,r0 /* note code below trims to 24 bits */
+
+ /* Construct the high word of the PPC-style PTE (r11) */
+#ifndef CONFIG_PPC64BRIDGE
+ rlwinm r11,r3,7,1,24 /* put VSID in 0x7fffff80 bits */
+ rlwimi r11,r4,10,26,31 /* put in API (abbrev page index) */
+#else /* CONFIG_PPC64BRIDGE */
+ clrlwi r3,r3,8 /* reduce vsid to 24 bits */
+ sldi r11,r3,12 /* shift vsid into position */
+ rlwimi r11,r4,16,20,24 /* put in API (abbrev page index) */
+#endif /* CONFIG_PPC64BRIDGE */
+ SET_V(r11) /* set V (valid) bit */
+
+#ifdef CONFIG_SMP
+ addis r9,r7,mmu_hash_lock@ha
+ addi r9,r9,mmu_hash_lock@l
+ rlwinm r8,r1,0,0,18
+ add r8,r8,r7
+ lwz r8,TI_CPU(r8)
+ oris r8,r8,9
+10: lwarx r0,0,r9
+ cmpi 0,r0,0
+ bne- 11f
+ stwcx. r8,0,r9
+ beq+ 12f
+11: lwz r0,0(r9)
+ cmpi 0,r0,0
+ beq 10b
+ b 11b
+12: isync
+#endif
+
+ /*
+ * Check the _PAGE_HASHPTE bit in the linux PTE. If it is
+ * already clear, we're done (for this pte). If not,
+ * clear it (atomically) and proceed. -- paulus.
+ */
+33: lwarx r8,0,r5 /* fetch the pte */
+ andi. r0,r8,_PAGE_HASHPTE
+ beq 8f /* done if HASHPTE is already clear */
+ rlwinm r8,r8,0,31,29 /* clear HASHPTE bit */
+ stwcx. r8,0,r5 /* update the pte */
+ bne- 33b
+
+ /* Get the address of the primary PTE group in the hash table (r3) */
+_GLOBAL(flush_hash_patch_A)
+ addis r8,r7,Hash_base@h /* base address of hash table */
+ rlwimi r8,r3,LG_PTEG_SIZE,HASH_LEFT,HASH_RIGHT /* VSID -> hash */
+ rlwinm r0,r4,20+LG_PTEG_SIZE,HASH_LEFT,HASH_RIGHT /* PI -> hash */
+ xor r8,r0,r8 /* make primary hash */
+
+ /* Search the primary PTEG for a PTE whose 1st (d)word matches r5 */
+ li r0,8 /* PTEs/group */
+ mtctr r0
+ addi r12,r8,-PTE_SIZE
+1: LDPTEu r0,PTE_SIZE(r12) /* get next PTE */
+ CMPPTE 0,r0,r11
+ bdnzf 2,1b /* loop while ctr != 0 && !cr0.eq */
+ beq+ 3f
+
+ /* Search the secondary PTEG for a matching PTE */
+ ori r11,r11,PTE_H /* set H (secondary hash) bit */
+ li r0,8 /* PTEs/group */
+_GLOBAL(flush_hash_patch_B)
+ xoris r12,r8,Hash_msk>>16 /* compute secondary hash */
+ xori r12,r12,(-PTEG_SIZE & 0xffff)
+ addi r12,r12,-PTE_SIZE
+ mtctr r0
+2: LDPTEu r0,PTE_SIZE(r12)
+ CMPPTE 0,r0,r11
+ bdnzf 2,2b
+ xori r11,r11,PTE_H /* clear H again */
+ bne- 4f /* should rarely fail to find it */
+
+3: li r0,0
+ STPTE r0,0(r12) /* invalidate entry */
+4: sync
+ tlbie r4 /* in hw tlb too */
+ sync
+
+8: ble cr1,9f /* if all ptes checked */
+81: addi r6,r6,-1
+ addi r5,r5,4 /* advance to next pte */
+ addi r4,r4,0x1000
+ lwz r0,0(r5) /* check next pte */
+ cmpwi cr1,r6,1
+ andi. r0,r0,_PAGE_HASHPTE
+ bne 33b
+ bgt cr1,81b
+
+9:
+#ifdef CONFIG_SMP
+ TLBSYNC
+ li r0,0
+ stw r0,0(r9) /* clear mmu_hash_lock */
+#endif
+
+19: mtmsr r10
+ SYNC_601
+ isync
+ blr
diff --git a/arch/powerpc/mm/hash_low_64.S b/arch/powerpc/mm/hash_low_64.S
new file mode 100644
index 000000000000..e0d02c4a2615
--- /dev/null
+++ b/arch/powerpc/mm/hash_low_64.S
@@ -0,0 +1,847 @@
+/*
+ * ppc64 MMU hashtable management routines
+ *
+ * (c) Copyright IBM Corp. 2003, 2005
+ *
+ * Maintained by: Benjamin Herrenschmidt
+ * <benh@kernel.crashing.org>
+ *
+ * This file is covered by the GNU Public Licence v2 as
+ * described in the kernel's COPYING file.
+ */
+
+#include <linux/config.h>
+#include <asm/reg.h>
+#include <asm/pgtable.h>
+#include <asm/mmu.h>
+#include <asm/page.h>
+#include <asm/types.h>
+#include <asm/ppc_asm.h>
+#include <asm/asm-offsets.h>
+#include <asm/cputable.h>
+
+ .text
+
+/*
+ * Stackframe:
+ *
+ * +-> Back chain (SP + 256)
+ * | General register save area (SP + 112)
+ * | Parameter save area (SP + 48)
+ * | TOC save area (SP + 40)
+ * | link editor doubleword (SP + 32)
+ * | compiler doubleword (SP + 24)
+ * | LR save area (SP + 16)
+ * | CR save area (SP + 8)
+ * SP ---> +-- Back chain (SP + 0)
+ */
+#define STACKFRAMESIZE 256
+
+/* Save parameters offsets */
+#define STK_PARM(i) (STACKFRAMESIZE + 48 + ((i)-3)*8)
+
+/* Save non-volatile offsets */
+#define STK_REG(i) (112 + ((i)-14)*8)
+
+
+#ifndef CONFIG_PPC_64K_PAGES
+
+/*****************************************************************************
+ * *
+ * 4K SW & 4K HW pages implementation *
+ * *
+ *****************************************************************************/
+
+
+/*
+ * _hash_page_4K(unsigned long ea, unsigned long access, unsigned long vsid,
+ * pte_t *ptep, unsigned long trap, int local)
+ *
+ * Adds a 4K page to the hash table in a segment of 4K pages only
+ */
+
+_GLOBAL(__hash_page_4K)
+ mflr r0
+ std r0,16(r1)
+ stdu r1,-STACKFRAMESIZE(r1)
+ /* Save all params that we need after a function call */
+ std r6,STK_PARM(r6)(r1)
+ std r8,STK_PARM(r8)(r1)
+
+ /* Add _PAGE_PRESENT to access */
+ ori r4,r4,_PAGE_PRESENT
+
+ /* Save non-volatile registers.
+ * r31 will hold "old PTE"
+ * r30 is "new PTE"
+ * r29 is "va"
+ * r28 is a hash value
+ * r27 is hashtab mask (maybe dynamic patched instead ?)
+ */
+ std r27,STK_REG(r27)(r1)
+ std r28,STK_REG(r28)(r1)
+ std r29,STK_REG(r29)(r1)
+ std r30,STK_REG(r30)(r1)
+ std r31,STK_REG(r31)(r1)
+
+ /* Step 1:
+ *
+ * Check permissions, atomically mark the linux PTE busy
+ * and hashed.
+ */
+1:
+ ldarx r31,0,r6
+ /* Check access rights (access & ~(pte_val(*ptep))) */
+ andc. r0,r4,r31
+ bne- htab_wrong_access
+ /* Check if PTE is busy */
+ andi. r0,r31,_PAGE_BUSY
+ /* If so, just bail out and refault if needed. Someone else
+ * is changing this PTE anyway and might hash it.
+ */
+ bne- htab_bail_ok
+
+ /* Prepare new PTE value (turn access RW into DIRTY, then
+ * add BUSY,HASHPTE and ACCESSED)
+ */
+ rlwinm r30,r4,32-9+7,31-7,31-7 /* _PAGE_RW -> _PAGE_DIRTY */
+ or r30,r30,r31
+ ori r30,r30,_PAGE_BUSY | _PAGE_ACCESSED | _PAGE_HASHPTE
+ /* Write the linux PTE atomically (setting busy) */
+ stdcx. r30,0,r6
+ bne- 1b
+ isync
+
+ /* Step 2:
+ *
+ * Insert/Update the HPTE in the hash table. At this point,
+ * r4 (access) is re-useable, we use it for the new HPTE flags
+ */
+
+ /* Calc va and put it in r29 */
+ rldicr r29,r5,28,63-28
+ rldicl r3,r3,0,36
+ or r29,r3,r29
+
+ /* Calculate hash value for primary slot and store it in r28 */
+ rldicl r5,r5,0,25 /* vsid & 0x0000007fffffffff */
+ rldicl r0,r3,64-12,48 /* (ea >> 12) & 0xffff */
+ xor r28,r5,r0
+
+ /* Convert linux PTE bits into HW equivalents */
+ andi. r3,r30,0x1fe /* Get basic set of flags */
+ xori r3,r3,HPTE_R_N /* _PAGE_EXEC -> NOEXEC */
+ rlwinm r0,r30,32-9+1,30,30 /* _PAGE_RW -> _PAGE_USER (r0) */
+ rlwinm r4,r30,32-7+1,30,30 /* _PAGE_DIRTY -> _PAGE_USER (r4) */
+ and r0,r0,r4 /* _PAGE_RW & _PAGE_DIRTY ->r0 bit 30*/
+ andc r0,r30,r0 /* r0 = pte & ~r0 */
+ rlwimi r3,r0,32-1,31,31 /* Insert result into PP lsb */
+
+ /* We eventually do the icache sync here (maybe inline that
+ * code rather than call a C function...)
+ */
+BEGIN_FTR_SECTION
+ mr r4,r30
+ mr r5,r7
+ bl .hash_page_do_lazy_icache
+END_FTR_SECTION(CPU_FTR_NOEXECUTE|CPU_FTR_COHERENT_ICACHE, CPU_FTR_NOEXECUTE)
+
+ /* At this point, r3 contains new PP bits, save them in
+ * place of "access" in the param area (sic)
+ */
+ std r3,STK_PARM(r4)(r1)
+
+ /* Get htab_hash_mask */
+ ld r4,htab_hash_mask@got(2)
+ ld r27,0(r4) /* htab_hash_mask -> r27 */
+
+ /* Check if we may already be in the hashtable, in this case, we
+ * go to out-of-line code to try to modify the HPTE
+ */
+ andi. r0,r31,_PAGE_HASHPTE
+ bne htab_modify_pte
+
+htab_insert_pte:
+ /* Clear hpte bits in new pte (we also clear BUSY btw) and
+ * add _PAGE_HASHPTE
+ */
+ lis r0,_PAGE_HPTEFLAGS@h
+ ori r0,r0,_PAGE_HPTEFLAGS@l
+ andc r30,r30,r0
+ ori r30,r30,_PAGE_HASHPTE
+
+ /* physical address r5 */
+ rldicl r5,r31,64-PTE_RPN_SHIFT,PTE_RPN_SHIFT
+ sldi r5,r5,PAGE_SHIFT
+
+ /* Calculate primary group hash */
+ and r0,r28,r27
+ rldicr r3,r0,3,63-3 /* r3 = (hash & mask) << 3 */
+
+ /* Call ppc_md.hpte_insert */
+ ld r6,STK_PARM(r4)(r1) /* Retreive new pp bits */
+ mr r4,r29 /* Retreive va */
+ li r7,0 /* !bolted, !secondary */
+ li r8,MMU_PAGE_4K /* page size */
+_GLOBAL(htab_call_hpte_insert1)
+ bl . /* Patched by htab_finish_init() */
+ cmpdi 0,r3,0
+ bge htab_pte_insert_ok /* Insertion successful */
+ cmpdi 0,r3,-2 /* Critical failure */
+ beq- htab_pte_insert_failure
+
+ /* Now try secondary slot */
+
+ /* physical address r5 */
+ rldicl r5,r31,64-PTE_RPN_SHIFT,PTE_RPN_SHIFT
+ sldi r5,r5,PAGE_SHIFT
+
+ /* Calculate secondary group hash */
+ andc r0,r27,r28
+ rldicr r3,r0,3,63-3 /* r0 = (~hash & mask) << 3 */
+
+ /* Call ppc_md.hpte_insert */
+ ld r6,STK_PARM(r4)(r1) /* Retreive new pp bits */
+ mr r4,r29 /* Retreive va */
+ li r7,HPTE_V_SECONDARY /* !bolted, secondary */
+ li r8,MMU_PAGE_4K /* page size */
+_GLOBAL(htab_call_hpte_insert2)
+ bl . /* Patched by htab_finish_init() */
+ cmpdi 0,r3,0
+ bge+ htab_pte_insert_ok /* Insertion successful */
+ cmpdi 0,r3,-2 /* Critical failure */
+ beq- htab_pte_insert_failure
+
+ /* Both are full, we need to evict something */
+ mftb r0
+ /* Pick a random group based on TB */
+ andi. r0,r0,1
+ mr r5,r28
+ bne 2f
+ not r5,r5
+2: and r0,r5,r27
+ rldicr r3,r0,3,63-3 /* r0 = (hash & mask) << 3 */
+ /* Call ppc_md.hpte_remove */
+_GLOBAL(htab_call_hpte_remove)
+ bl . /* Patched by htab_finish_init() */
+
+ /* Try all again */
+ b htab_insert_pte
+
+htab_bail_ok:
+ li r3,0
+ b htab_bail
+
+htab_pte_insert_ok:
+ /* Insert slot number & secondary bit in PTE */
+ rldimi r30,r3,12,63-15
+
+ /* Write out the PTE with a normal write
+ * (maybe add eieio may be good still ?)
+ */
+htab_write_out_pte:
+ ld r6,STK_PARM(r6)(r1)
+ std r30,0(r6)
+ li r3, 0
+htab_bail:
+ ld r27,STK_REG(r27)(r1)
+ ld r28,STK_REG(r28)(r1)
+ ld r29,STK_REG(r29)(r1)
+ ld r30,STK_REG(r30)(r1)
+ ld r31,STK_REG(r31)(r1)
+ addi r1,r1,STACKFRAMESIZE
+ ld r0,16(r1)
+ mtlr r0
+ blr
+
+htab_modify_pte:
+ /* Keep PP bits in r4 and slot idx from the PTE around in r3 */
+ mr r4,r3
+ rlwinm r3,r31,32-12,29,31
+
+ /* Secondary group ? if yes, get a inverted hash value */
+ mr r5,r28
+ andi. r0,r31,_PAGE_SECONDARY
+ beq 1f
+ not r5,r5
+1:
+ /* Calculate proper slot value for ppc_md.hpte_updatepp */
+ and r0,r5,r27
+ rldicr r0,r0,3,63-3 /* r0 = (hash & mask) << 3 */
+ add r3,r0,r3 /* add slot idx */
+
+ /* Call ppc_md.hpte_updatepp */
+ mr r5,r29 /* va */
+ li r6,MMU_PAGE_4K /* page size */
+ ld r7,STK_PARM(r8)(r1) /* get "local" param */
+_GLOBAL(htab_call_hpte_updatepp)
+ bl . /* Patched by htab_finish_init() */
+
+ /* if we failed because typically the HPTE wasn't really here
+ * we try an insertion.
+ */
+ cmpdi 0,r3,-1
+ beq- htab_insert_pte
+
+ /* Clear the BUSY bit and Write out the PTE */
+ li r0,_PAGE_BUSY
+ andc r30,r30,r0
+ b htab_write_out_pte
+
+htab_wrong_access:
+ /* Bail out clearing reservation */
+ stdcx. r31,0,r6
+ li r3,1
+ b htab_bail
+
+htab_pte_insert_failure:
+ /* Bail out restoring old PTE */
+ ld r6,STK_PARM(r6)(r1)
+ std r31,0(r6)
+ li r3,-1
+ b htab_bail
+
+
+#else /* CONFIG_PPC_64K_PAGES */
+
+
+/*****************************************************************************
+ * *
+ * 64K SW & 4K or 64K HW in a 4K segment pages implementation *
+ * *
+ *****************************************************************************/
+
+/* _hash_page_4K(unsigned long ea, unsigned long access, unsigned long vsid,
+ * pte_t *ptep, unsigned long trap, int local)
+ */
+
+/*
+ * For now, we do NOT implement Admixed pages
+ */
+_GLOBAL(__hash_page_4K)
+ mflr r0
+ std r0,16(r1)
+ stdu r1,-STACKFRAMESIZE(r1)
+ /* Save all params that we need after a function call */
+ std r6,STK_PARM(r6)(r1)
+ std r8,STK_PARM(r8)(r1)
+
+ /* Add _PAGE_PRESENT to access */
+ ori r4,r4,_PAGE_PRESENT
+
+ /* Save non-volatile registers.
+ * r31 will hold "old PTE"
+ * r30 is "new PTE"
+ * r29 is "va"
+ * r28 is a hash value
+ * r27 is hashtab mask (maybe dynamic patched instead ?)
+ * r26 is the hidx mask
+ * r25 is the index in combo page
+ */
+ std r25,STK_REG(r25)(r1)
+ std r26,STK_REG(r26)(r1)
+ std r27,STK_REG(r27)(r1)
+ std r28,STK_REG(r28)(r1)
+ std r29,STK_REG(r29)(r1)
+ std r30,STK_REG(r30)(r1)
+ std r31,STK_REG(r31)(r1)
+
+ /* Step 1:
+ *
+ * Check permissions, atomically mark the linux PTE busy
+ * and hashed.
+ */
+1:
+ ldarx r31,0,r6
+ /* Check access rights (access & ~(pte_val(*ptep))) */
+ andc. r0,r4,r31
+ bne- htab_wrong_access
+ /* Check if PTE is busy */
+ andi. r0,r31,_PAGE_BUSY
+ /* If so, just bail out and refault if needed. Someone else
+ * is changing this PTE anyway and might hash it.
+ */
+ bne- htab_bail_ok
+ /* Prepare new PTE value (turn access RW into DIRTY, then
+ * add BUSY and ACCESSED)
+ */
+ rlwinm r30,r4,32-9+7,31-7,31-7 /* _PAGE_RW -> _PAGE_DIRTY */
+ or r30,r30,r31
+ ori r30,r30,_PAGE_BUSY | _PAGE_ACCESSED | _PAGE_HASHPTE
+ /* Write the linux PTE atomically (setting busy) */
+ stdcx. r30,0,r6
+ bne- 1b
+ isync
+
+ /* Step 2:
+ *
+ * Insert/Update the HPTE in the hash table. At this point,
+ * r4 (access) is re-useable, we use it for the new HPTE flags
+ */
+
+ /* Load the hidx index */
+ rldicl r25,r3,64-12,60
+
+ /* Calc va and put it in r29 */
+ rldicr r29,r5,28,63-28 /* r29 = (vsid << 28) */
+ rldicl r3,r3,0,36 /* r3 = (ea & 0x0fffffff) */
+ or r29,r3,r29 /* r29 = va
+
+ /* Calculate hash value for primary slot and store it in r28 */
+ rldicl r5,r5,0,25 /* vsid & 0x0000007fffffffff */
+ rldicl r0,r3,64-12,48 /* (ea >> 12) & 0xffff */
+ xor r28,r5,r0
+
+ /* Convert linux PTE bits into HW equivalents */
+ andi. r3,r30,0x1fe /* Get basic set of flags */
+ xori r3,r3,HPTE_R_N /* _PAGE_EXEC -> NOEXEC */
+ rlwinm r0,r30,32-9+1,30,30 /* _PAGE_RW -> _PAGE_USER (r0) */
+ rlwinm r4,r30,32-7+1,30,30 /* _PAGE_DIRTY -> _PAGE_USER (r4) */
+ and r0,r0,r4 /* _PAGE_RW & _PAGE_DIRTY ->r0 bit 30*/
+ andc r0,r30,r0 /* r0 = pte & ~r0 */
+ rlwimi r3,r0,32-1,31,31 /* Insert result into PP lsb */
+
+ /* We eventually do the icache sync here (maybe inline that
+ * code rather than call a C function...)
+ */
+BEGIN_FTR_SECTION
+ mr r4,r30
+ mr r5,r7
+ bl .hash_page_do_lazy_icache
+END_FTR_SECTION(CPU_FTR_NOEXECUTE|CPU_FTR_COHERENT_ICACHE, CPU_FTR_NOEXECUTE)
+
+ /* At this point, r3 contains new PP bits, save them in
+ * place of "access" in the param area (sic)
+ */
+ std r3,STK_PARM(r4)(r1)
+
+ /* Get htab_hash_mask */
+ ld r4,htab_hash_mask@got(2)
+ ld r27,0(r4) /* htab_hash_mask -> r27 */
+
+ /* Check if we may already be in the hashtable, in this case, we
+ * go to out-of-line code to try to modify the HPTE. We look for
+ * the bit at (1 >> (index + 32))
+ */
+ andi. r0,r31,_PAGE_HASHPTE
+ li r26,0 /* Default hidx */
+ beq htab_insert_pte
+ ld r6,STK_PARM(r6)(r1)
+ ori r26,r6,0x8000 /* Load the hidx mask */
+ ld r26,0(r26)
+ addi r5,r25,36 /* Check actual HPTE_SUB bit, this */
+ rldcr. r0,r31,r5,0 /* must match pgtable.h definition */
+ bne htab_modify_pte
+
+htab_insert_pte:
+ /* real page number in r5, PTE RPN value + index */
+ rldicl r5,r31,64-PTE_RPN_SHIFT,PTE_RPN_SHIFT
+ sldi r5,r5,PAGE_SHIFT-HW_PAGE_SHIFT
+ add r5,r5,r25
+ sldi r5,r5,HW_PAGE_SHIFT
+
+ /* Calculate primary group hash */
+ and r0,r28,r27
+ rldicr r3,r0,3,63-3 /* r0 = (hash & mask) << 3 */
+
+ /* Call ppc_md.hpte_insert */
+ ld r6,STK_PARM(r4)(r1) /* Retreive new pp bits */
+ mr r4,r29 /* Retreive va */
+ li r7,0 /* !bolted, !secondary */
+ li r8,MMU_PAGE_4K /* page size */
+_GLOBAL(htab_call_hpte_insert1)
+ bl . /* patched by htab_finish_init() */
+ cmpdi 0,r3,0
+ bge htab_pte_insert_ok /* Insertion successful */
+ cmpdi 0,r3,-2 /* Critical failure */
+ beq- htab_pte_insert_failure
+
+ /* Now try secondary slot */
+
+ /* real page number in r5, PTE RPN value + index */
+ rldicl r5,r31,64-PTE_RPN_SHIFT,PTE_RPN_SHIFT
+ sldi r5,r5,PAGE_SHIFT-HW_PAGE_SHIFT
+ add r5,r5,r25
+ sldi r5,r5,HW_PAGE_SHIFT
+
+ /* Calculate secondary group hash */
+ andc r0,r27,r28
+ rldicr r3,r0,3,63-3 /* r0 = (~hash & mask) << 3 */
+
+ /* Call ppc_md.hpte_insert */
+ ld r6,STK_PARM(r4)(r1) /* Retreive new pp bits */
+ mr r4,r29 /* Retreive va */
+ li r7,HPTE_V_SECONDARY /* !bolted, secondary */
+ li r8,MMU_PAGE_4K /* page size */
+_GLOBAL(htab_call_hpte_insert2)
+ bl . /* patched by htab_finish_init() */
+ cmpdi 0,r3,0
+ bge+ htab_pte_insert_ok /* Insertion successful */
+ cmpdi 0,r3,-2 /* Critical failure */
+ beq- htab_pte_insert_failure
+
+ /* Both are full, we need to evict something */
+ mftb r0
+ /* Pick a random group based on TB */
+ andi. r0,r0,1
+ mr r5,r28
+ bne 2f
+ not r5,r5
+2: and r0,r5,r27
+ rldicr r3,r0,3,63-3 /* r0 = (hash & mask) << 3 */
+ /* Call ppc_md.hpte_remove */
+_GLOBAL(htab_call_hpte_remove)
+ bl . /* patched by htab_finish_init() */
+
+ /* Try all again */
+ b htab_insert_pte
+
+htab_bail_ok:
+ li r3,0
+ b htab_bail
+
+htab_pte_insert_ok:
+ /* Insert slot number & secondary bit in PTE second half,
+ * clear _PAGE_BUSY and set approriate HPTE slot bit
+ */
+ ld r6,STK_PARM(r6)(r1)
+ li r0,_PAGE_BUSY
+ andc r30,r30,r0
+ /* HPTE SUB bit */
+ li r0,1
+ subfic r5,r25,27 /* Must match bit position in */
+ sld r0,r0,r5 /* pgtable.h */
+ or r30,r30,r0
+ /* hindx */
+ sldi r5,r25,2
+ sld r3,r3,r5
+ li r4,0xf
+ sld r4,r4,r5
+ andc r26,r26,r4
+ or r26,r26,r3
+ ori r5,r6,0x8000
+ std r26,0(r5)
+ lwsync
+ std r30,0(r6)
+ li r3, 0
+htab_bail:
+ ld r25,STK_REG(r25)(r1)
+ ld r26,STK_REG(r26)(r1)
+ ld r27,STK_REG(r27)(r1)
+ ld r28,STK_REG(r28)(r1)
+ ld r29,STK_REG(r29)(r1)
+ ld r30,STK_REG(r30)(r1)
+ ld r31,STK_REG(r31)(r1)
+ addi r1,r1,STACKFRAMESIZE
+ ld r0,16(r1)
+ mtlr r0
+ blr
+
+htab_modify_pte:
+ /* Keep PP bits in r4 and slot idx from the PTE around in r3 */
+ mr r4,r3
+ sldi r5,r25,2
+ srd r3,r26,r5
+
+ /* Secondary group ? if yes, get a inverted hash value */
+ mr r5,r28
+ andi. r0,r3,0x8 /* page secondary ? */
+ beq 1f
+ not r5,r5
+1: andi. r3,r3,0x7 /* extract idx alone */
+
+ /* Calculate proper slot value for ppc_md.hpte_updatepp */
+ and r0,r5,r27
+ rldicr r0,r0,3,63-3 /* r0 = (hash & mask) << 3 */
+ add r3,r0,r3 /* add slot idx */
+
+ /* Call ppc_md.hpte_updatepp */
+ mr r5,r29 /* va */
+ li r6,MMU_PAGE_4K /* page size */
+ ld r7,STK_PARM(r8)(r1) /* get "local" param */
+_GLOBAL(htab_call_hpte_updatepp)
+ bl . /* patched by htab_finish_init() */
+
+ /* if we failed because typically the HPTE wasn't really here
+ * we try an insertion.
+ */
+ cmpdi 0,r3,-1
+ beq- htab_insert_pte
+
+ /* Clear the BUSY bit and Write out the PTE */
+ li r0,_PAGE_BUSY
+ andc r30,r30,r0
+ ld r6,STK_PARM(r6)(r1)
+ std r30,0(r6)
+ li r3,0
+ b htab_bail
+
+htab_wrong_access:
+ /* Bail out clearing reservation */
+ stdcx. r31,0,r6
+ li r3,1
+ b htab_bail
+
+htab_pte_insert_failure:
+ /* Bail out restoring old PTE */
+ ld r6,STK_PARM(r6)(r1)
+ std r31,0(r6)
+ li r3,-1
+ b htab_bail
+
+
+/*****************************************************************************
+ * *
+ * 64K SW & 64K HW in a 64K segment pages implementation *
+ * *
+ *****************************************************************************/
+
+_GLOBAL(__hash_page_64K)
+ mflr r0
+ std r0,16(r1)
+ stdu r1,-STACKFRAMESIZE(r1)
+ /* Save all params that we need after a function call */
+ std r6,STK_PARM(r6)(r1)
+ std r8,STK_PARM(r8)(r1)
+
+ /* Add _PAGE_PRESENT to access */
+ ori r4,r4,_PAGE_PRESENT
+
+ /* Save non-volatile registers.
+ * r31 will hold "old PTE"
+ * r30 is "new PTE"
+ * r29 is "va"
+ * r28 is a hash value
+ * r27 is hashtab mask (maybe dynamic patched instead ?)
+ */
+ std r27,STK_REG(r27)(r1)
+ std r28,STK_REG(r28)(r1)
+ std r29,STK_REG(r29)(r1)
+ std r30,STK_REG(r30)(r1)
+ std r31,STK_REG(r31)(r1)
+
+ /* Step 1:
+ *
+ * Check permissions, atomically mark the linux PTE busy
+ * and hashed.
+ */
+1:
+ ldarx r31,0,r6
+ /* Check access rights (access & ~(pte_val(*ptep))) */
+ andc. r0,r4,r31
+ bne- ht64_wrong_access
+ /* Check if PTE is busy */
+ andi. r0,r31,_PAGE_BUSY
+ /* If so, just bail out and refault if needed. Someone else
+ * is changing this PTE anyway and might hash it.
+ */
+ bne- ht64_bail_ok
+ /* Prepare new PTE value (turn access RW into DIRTY, then
+ * add BUSY,HASHPTE and ACCESSED)
+ */
+ rlwinm r30,r4,32-9+7,31-7,31-7 /* _PAGE_RW -> _PAGE_DIRTY */
+ or r30,r30,r31
+ ori r30,r30,_PAGE_BUSY | _PAGE_ACCESSED | _PAGE_HASHPTE
+ /* Write the linux PTE atomically (setting busy) */
+ stdcx. r30,0,r6
+ bne- 1b
+ isync
+
+ /* Step 2:
+ *
+ * Insert/Update the HPTE in the hash table. At this point,
+ * r4 (access) is re-useable, we use it for the new HPTE flags
+ */
+
+ /* Calc va and put it in r29 */
+ rldicr r29,r5,28,63-28
+ rldicl r3,r3,0,36
+ or r29,r3,r29
+
+ /* Calculate hash value for primary slot and store it in r28 */
+ rldicl r5,r5,0,25 /* vsid & 0x0000007fffffffff */
+ rldicl r0,r3,64-16,52 /* (ea >> 16) & 0xfff */
+ xor r28,r5,r0
+
+ /* Convert linux PTE bits into HW equivalents */
+ andi. r3,r30,0x1fe /* Get basic set of flags */
+ xori r3,r3,HPTE_R_N /* _PAGE_EXEC -> NOEXEC */
+ rlwinm r0,r30,32-9+1,30,30 /* _PAGE_RW -> _PAGE_USER (r0) */
+ rlwinm r4,r30,32-7+1,30,30 /* _PAGE_DIRTY -> _PAGE_USER (r4) */
+ and r0,r0,r4 /* _PAGE_RW & _PAGE_DIRTY ->r0 bit 30*/
+ andc r0,r30,r0 /* r0 = pte & ~r0 */
+ rlwimi r3,r0,32-1,31,31 /* Insert result into PP lsb */
+
+ /* We eventually do the icache sync here (maybe inline that
+ * code rather than call a C function...)
+ */
+BEGIN_FTR_SECTION
+ mr r4,r30
+ mr r5,r7
+ bl .hash_page_do_lazy_icache
+END_FTR_SECTION(CPU_FTR_NOEXECUTE|CPU_FTR_COHERENT_ICACHE, CPU_FTR_NOEXECUTE)
+
+ /* At this point, r3 contains new PP bits, save them in
+ * place of "access" in the param area (sic)
+ */
+ std r3,STK_PARM(r4)(r1)
+
+ /* Get htab_hash_mask */
+ ld r4,htab_hash_mask@got(2)
+ ld r27,0(r4) /* htab_hash_mask -> r27 */
+
+ /* Check if we may already be in the hashtable, in this case, we
+ * go to out-of-line code to try to modify the HPTE
+ */
+ andi. r0,r31,_PAGE_HASHPTE
+ bne ht64_modify_pte
+
+ht64_insert_pte:
+ /* Clear hpte bits in new pte (we also clear BUSY btw) and
+ * add _PAGE_HASHPTE
+ */
+ lis r0,_PAGE_HPTEFLAGS@h
+ ori r0,r0,_PAGE_HPTEFLAGS@l
+ andc r30,r30,r0
+ ori r30,r30,_PAGE_HASHPTE
+
+ /* Phyical address in r5 */
+ rldicl r5,r31,64-PTE_RPN_SHIFT,PTE_RPN_SHIFT
+ sldi r5,r5,PAGE_SHIFT
+
+ /* Calculate primary group hash */
+ and r0,r28,r27
+ rldicr r3,r0,3,63-3 /* r0 = (hash & mask) << 3 */
+
+ /* Call ppc_md.hpte_insert */
+ ld r6,STK_PARM(r4)(r1) /* Retreive new pp bits */
+ mr r4,r29 /* Retreive va */
+ li r7,0 /* !bolted, !secondary */
+ li r8,MMU_PAGE_64K
+_GLOBAL(ht64_call_hpte_insert1)
+ bl . /* patched by htab_finish_init() */
+ cmpdi 0,r3,0
+ bge ht64_pte_insert_ok /* Insertion successful */
+ cmpdi 0,r3,-2 /* Critical failure */
+ beq- ht64_pte_insert_failure
+
+ /* Now try secondary slot */
+
+ /* Phyical address in r5 */
+ rldicl r5,r31,64-PTE_RPN_SHIFT,PTE_RPN_SHIFT
+ sldi r5,r5,PAGE_SHIFT
+
+ /* Calculate secondary group hash */
+ andc r0,r27,r28
+ rldicr r3,r0,3,63-3 /* r0 = (~hash & mask) << 3 */
+
+ /* Call ppc_md.hpte_insert */
+ ld r6,STK_PARM(r4)(r1) /* Retreive new pp bits */
+ mr r4,r29 /* Retreive va */
+ li r7,HPTE_V_SECONDARY /* !bolted, secondary */
+ li r8,MMU_PAGE_64K
+_GLOBAL(ht64_call_hpte_insert2)
+ bl . /* patched by htab_finish_init() */
+ cmpdi 0,r3,0
+ bge+ ht64_pte_insert_ok /* Insertion successful */
+ cmpdi 0,r3,-2 /* Critical failure */
+ beq- ht64_pte_insert_failure
+
+ /* Both are full, we need to evict something */
+ mftb r0
+ /* Pick a random group based on TB */
+ andi. r0,r0,1
+ mr r5,r28
+ bne 2f
+ not r5,r5
+2: and r0,r5,r27
+ rldicr r3,r0,3,63-3 /* r0 = (hash & mask) << 3 */
+ /* Call ppc_md.hpte_remove */
+_GLOBAL(ht64_call_hpte_remove)
+ bl . /* patched by htab_finish_init() */
+
+ /* Try all again */
+ b ht64_insert_pte
+
+ht64_bail_ok:
+ li r3,0
+ b ht64_bail
+
+ht64_pte_insert_ok:
+ /* Insert slot number & secondary bit in PTE */
+ rldimi r30,r3,12,63-15
+
+ /* Write out the PTE with a normal write
+ * (maybe add eieio may be good still ?)
+ */
+ht64_write_out_pte:
+ ld r6,STK_PARM(r6)(r1)
+ std r30,0(r6)
+ li r3, 0
+ht64_bail:
+ ld r27,STK_REG(r27)(r1)
+ ld r28,STK_REG(r28)(r1)
+ ld r29,STK_REG(r29)(r1)
+ ld r30,STK_REG(r30)(r1)
+ ld r31,STK_REG(r31)(r1)
+ addi r1,r1,STACKFRAMESIZE
+ ld r0,16(r1)
+ mtlr r0
+ blr
+
+ht64_modify_pte:
+ /* Keep PP bits in r4 and slot idx from the PTE around in r3 */
+ mr r4,r3
+ rlwinm r3,r31,32-12,29,31
+
+ /* Secondary group ? if yes, get a inverted hash value */
+ mr r5,r28
+ andi. r0,r31,_PAGE_F_SECOND
+ beq 1f
+ not r5,r5
+1:
+ /* Calculate proper slot value for ppc_md.hpte_updatepp */
+ and r0,r5,r27
+ rldicr r0,r0,3,63-3 /* r0 = (hash & mask) << 3 */
+ add r3,r0,r3 /* add slot idx */
+
+ /* Call ppc_md.hpte_updatepp */
+ mr r5,r29 /* va */
+ li r6,MMU_PAGE_64K
+ ld r7,STK_PARM(r8)(r1) /* get "local" param */
+_GLOBAL(ht64_call_hpte_updatepp)
+ bl . /* patched by htab_finish_init() */
+
+ /* if we failed because typically the HPTE wasn't really here
+ * we try an insertion.
+ */
+ cmpdi 0,r3,-1
+ beq- ht64_insert_pte
+
+ /* Clear the BUSY bit and Write out the PTE */
+ li r0,_PAGE_BUSY
+ andc r30,r30,r0
+ b ht64_write_out_pte
+
+ht64_wrong_access:
+ /* Bail out clearing reservation */
+ stdcx. r31,0,r6
+ li r3,1
+ b ht64_bail
+
+ht64_pte_insert_failure:
+ /* Bail out restoring old PTE */
+ ld r6,STK_PARM(r6)(r1)
+ std r31,0(r6)
+ li r3,-1
+ b ht64_bail
+
+
+#endif /* CONFIG_PPC_64K_PAGES */
+
+
+/*****************************************************************************
+ * *
+ * Huge pages implementation is in hugetlbpage.c *
+ * *
+ *****************************************************************************/
diff --git a/arch/ppc64/mm/hash_native.c b/arch/powerpc/mm/hash_native_64.c
index bfd385b7713c..d96bcfe4c6f6 100644
--- a/arch/ppc64/mm/hash_native.c
+++ b/arch/powerpc/mm/hash_native_64.c
@@ -9,6 +9,9 @@
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
+
+#undef DEBUG_LOW
+
#include <linux/spinlock.h>
#include <linux/bitops.h>
#include <linux/threads.h>
@@ -22,11 +25,84 @@
#include <asm/tlbflush.h>
#include <asm/tlb.h>
#include <asm/cputable.h>
+#include <asm/udbg.h>
+
+#ifdef DEBUG_LOW
+#define DBG_LOW(fmt...) udbg_printf(fmt)
+#else
+#define DBG_LOW(fmt...)
+#endif
#define HPTE_LOCK_BIT 3
static DEFINE_SPINLOCK(native_tlbie_lock);
+static inline void __tlbie(unsigned long va, unsigned int psize)
+{
+ unsigned int penc;
+
+ /* clear top 16 bits, non SLS segment */
+ va &= ~(0xffffULL << 48);
+
+ switch (psize) {
+ case MMU_PAGE_4K:
+ va &= ~0xffful;
+ asm volatile("tlbie %0,0" : : "r" (va) : "memory");
+ break;
+ default:
+ penc = mmu_psize_defs[psize].penc;
+ va &= ~((1ul << mmu_psize_defs[psize].shift) - 1);
+ va |= (0x7f >> (8 - penc)) << 12;
+ asm volatile("tlbie %0,1" : : "r" (va) : "memory");
+ break;
+ }
+}
+
+static inline void __tlbiel(unsigned long va, unsigned int psize)
+{
+ unsigned int penc;
+
+ /* clear top 16 bits, non SLS segment */
+ va &= ~(0xffffULL << 48);
+
+ switch (psize) {
+ case MMU_PAGE_4K:
+ va &= ~0xffful;
+ asm volatile(".long 0x7c000224 | (%0 << 11) | (0 << 21)"
+ : : "r"(va) : "memory");
+ break;
+ default:
+ penc = mmu_psize_defs[psize].penc;
+ va &= ~((1ul << mmu_psize_defs[psize].shift) - 1);
+ va |= (0x7f >> (8 - penc)) << 12;
+ asm volatile(".long 0x7c000224 | (%0 << 11) | (1 << 21)"
+ : : "r"(va) : "memory");
+ break;
+ }
+
+}
+
+static inline void tlbie(unsigned long va, int psize, int local)
+{
+ unsigned int use_local = local && cpu_has_feature(CPU_FTR_TLBIEL);
+ int lock_tlbie = !cpu_has_feature(CPU_FTR_LOCKLESS_TLBIE);
+
+ if (use_local)
+ use_local = mmu_psize_defs[psize].tlbiel;
+ if (lock_tlbie && !use_local)
+ spin_lock(&native_tlbie_lock);
+ asm volatile("ptesync": : :"memory");
+ if (use_local) {
+ __tlbiel(va, psize);
+ asm volatile("ptesync": : :"memory");
+ } else {
+ __tlbie(va, psize);
+ asm volatile("eieio; tlbsync; ptesync": : :"memory");
+ }
+ if (lock_tlbie && !use_local)
+ spin_unlock(&native_tlbie_lock);
+}
+
static inline void native_lock_hpte(hpte_t *hptep)
{
unsigned long *word = &hptep->v;
@@ -48,13 +124,19 @@ static inline void native_unlock_hpte(hpte_t *hptep)
}
long native_hpte_insert(unsigned long hpte_group, unsigned long va,
- unsigned long prpn, unsigned long vflags,
- unsigned long rflags)
+ unsigned long pa, unsigned long rflags,
+ unsigned long vflags, int psize)
{
hpte_t *hptep = htab_address + hpte_group;
unsigned long hpte_v, hpte_r;
int i;
+ if (!(vflags & HPTE_V_BOLTED)) {
+ DBG_LOW(" insert(group=%lx, va=%016lx, pa=%016lx,"
+ " rflags=%lx, vflags=%lx, psize=%d)\n",
+ hpte_group, va, pa, rflags, vflags, psize);
+ }
+
for (i = 0; i < HPTES_PER_GROUP; i++) {
if (! (hptep->v & HPTE_V_VALID)) {
/* retry with lock held */
@@ -70,10 +152,13 @@ long native_hpte_insert(unsigned long hpte_group, unsigned long va,
if (i == HPTES_PER_GROUP)
return -1;
- hpte_v = (va >> 23) << HPTE_V_AVPN_SHIFT | vflags | HPTE_V_VALID;
- if (vflags & HPTE_V_LARGE)
- va &= ~(1UL << HPTE_V_AVPN_SHIFT);
- hpte_r = (prpn << HPTE_R_RPN_SHIFT) | rflags;
+ hpte_v = hpte_encode_v(va, psize) | vflags | HPTE_V_VALID;
+ hpte_r = hpte_encode_r(pa, psize) | rflags;
+
+ if (!(vflags & HPTE_V_BOLTED)) {
+ DBG_LOW(" i=%x hpte_v=%016lx, hpte_r=%016lx\n",
+ i, hpte_v, hpte_r);
+ }
hptep->r = hpte_r;
/* Guarantee the second dword is visible before the valid bit */
@@ -96,6 +181,8 @@ static long native_hpte_remove(unsigned long hpte_group)
int slot_offset;
unsigned long hpte_v;
+ DBG_LOW(" remove(group=%lx)\n", hpte_group);
+
/* pick a random entry to start at */
slot_offset = mftb() & 0x7;
@@ -126,34 +213,51 @@ static long native_hpte_remove(unsigned long hpte_group)
return i;
}
-static inline void set_pp_bit(unsigned long pp, hpte_t *addr)
+static long native_hpte_updatepp(unsigned long slot, unsigned long newpp,
+ unsigned long va, int psize, int local)
{
- unsigned long old;
- unsigned long *p = &addr->r;
-
- __asm__ __volatile__(
- "1: ldarx %0,0,%3\n\
- rldimi %0,%2,0,61\n\
- stdcx. %0,0,%3\n\
- bne 1b"
- : "=&r" (old), "=m" (*p)
- : "r" (pp), "r" (p), "m" (*p)
- : "cc");
+ hpte_t *hptep = htab_address + slot;
+ unsigned long hpte_v, want_v;
+ int ret = 0;
+
+ want_v = hpte_encode_v(va, psize);
+
+ DBG_LOW(" update(va=%016lx, avpnv=%016lx, hash=%016lx, newpp=%x)",
+ va, want_v & HPTE_V_AVPN, slot, newpp);
+
+ native_lock_hpte(hptep);
+
+ hpte_v = hptep->v;
+
+ /* Even if we miss, we need to invalidate the TLB */
+ if (!HPTE_V_COMPARE(hpte_v, want_v) || !(hpte_v & HPTE_V_VALID)) {
+ DBG_LOW(" -> miss\n");
+ native_unlock_hpte(hptep);
+ ret = -1;
+ } else {
+ DBG_LOW(" -> hit\n");
+ /* Update the HPTE */
+ hptep->r = (hptep->r & ~(HPTE_R_PP | HPTE_R_N)) |
+ (newpp & (HPTE_R_PP | HPTE_R_N));
+ native_unlock_hpte(hptep);
+ }
+
+ /* Ensure it is out of the tlb too. */
+ tlbie(va, psize, local);
+
+ return ret;
}
-/*
- * Only works on small pages. Yes its ugly to have to check each slot in
- * the group but we only use this during bootup.
- */
-static long native_hpte_find(unsigned long vpn)
+static long native_hpte_find(unsigned long va, int psize)
{
hpte_t *hptep;
unsigned long hash;
unsigned long i, j;
long slot;
- unsigned long hpte_v;
+ unsigned long want_v, hpte_v;
- hash = hpt_hash(vpn, 0);
+ hash = hpt_hash(va, mmu_psize_defs[psize].shift);
+ want_v = hpte_encode_v(va, psize);
for (j = 0; j < 2; j++) {
slot = (hash & htab_hash_mask) * HPTES_PER_GROUP;
@@ -161,7 +265,7 @@ static long native_hpte_find(unsigned long vpn)
hptep = htab_address + slot;
hpte_v = hptep->v;
- if ((HPTE_V_AVPN_VAL(hpte_v) == (vpn >> 11))
+ if (HPTE_V_COMPARE(hpte_v, want_v)
&& (hpte_v & HPTE_V_VALID)
&& ( !!(hpte_v & HPTE_V_SECONDARY) == j)) {
/* HPTE matches */
@@ -177,127 +281,101 @@ static long native_hpte_find(unsigned long vpn)
return -1;
}
-static long native_hpte_updatepp(unsigned long slot, unsigned long newpp,
- unsigned long va, int large, int local)
-{
- hpte_t *hptep = htab_address + slot;
- unsigned long hpte_v;
- unsigned long avpn = va >> 23;
- int ret = 0;
-
- if (large)
- avpn &= ~1;
-
- native_lock_hpte(hptep);
-
- hpte_v = hptep->v;
-
- /* Even if we miss, we need to invalidate the TLB */
- if ((HPTE_V_AVPN_VAL(hpte_v) != avpn)
- || !(hpte_v & HPTE_V_VALID)) {
- native_unlock_hpte(hptep);
- ret = -1;
- } else {
- set_pp_bit(newpp, hptep);
- native_unlock_hpte(hptep);
- }
-
- /* Ensure it is out of the tlb too */
- if (cpu_has_feature(CPU_FTR_TLBIEL) && !large && local) {
- tlbiel(va);
- } else {
- int lock_tlbie = !cpu_has_feature(CPU_FTR_LOCKLESS_TLBIE);
-
- if (lock_tlbie)
- spin_lock(&native_tlbie_lock);
- tlbie(va, large);
- if (lock_tlbie)
- spin_unlock(&native_tlbie_lock);
- }
-
- return ret;
-}
-
/*
* Update the page protection bits. Intended to be used to create
* guard pages for kernel data structures on pages which are bolted
* in the HPT. Assumes pages being operated on will not be stolen.
- * Does not work on large pages.
*
* No need to lock here because we should be the only user.
*/
-static void native_hpte_updateboltedpp(unsigned long newpp, unsigned long ea)
+static void native_hpte_updateboltedpp(unsigned long newpp, unsigned long ea,
+ int psize)
{
- unsigned long vsid, va, vpn, flags = 0;
+ unsigned long vsid, va;
long slot;
hpte_t *hptep;
- int lock_tlbie = !cpu_has_feature(CPU_FTR_LOCKLESS_TLBIE);
vsid = get_kernel_vsid(ea);
va = (vsid << 28) | (ea & 0x0fffffff);
- vpn = va >> PAGE_SHIFT;
- slot = native_hpte_find(vpn);
+ slot = native_hpte_find(va, psize);
if (slot == -1)
panic("could not find page to bolt\n");
hptep = htab_address + slot;
- set_pp_bit(newpp, hptep);
+ /* Update the HPTE */
+ hptep->r = (hptep->r & ~(HPTE_R_PP | HPTE_R_N)) |
+ (newpp & (HPTE_R_PP | HPTE_R_N));
- /* Ensure it is out of the tlb too */
- if (lock_tlbie)
- spin_lock_irqsave(&native_tlbie_lock, flags);
- tlbie(va, 0);
- if (lock_tlbie)
- spin_unlock_irqrestore(&native_tlbie_lock, flags);
+ /* Ensure it is out of the tlb too. */
+ tlbie(va, psize, 0);
}
static void native_hpte_invalidate(unsigned long slot, unsigned long va,
- int large, int local)
+ int psize, int local)
{
hpte_t *hptep = htab_address + slot;
unsigned long hpte_v;
- unsigned long avpn = va >> 23;
+ unsigned long want_v;
unsigned long flags;
- int lock_tlbie = !cpu_has_feature(CPU_FTR_LOCKLESS_TLBIE);
-
- if (large)
- avpn &= ~1;
local_irq_save(flags);
- native_lock_hpte(hptep);
+ DBG_LOW(" invalidate(va=%016lx, hash: %x)\n", va, slot);
+
+ want_v = hpte_encode_v(va, psize);
+ native_lock_hpte(hptep);
hpte_v = hptep->v;
/* Even if we miss, we need to invalidate the TLB */
- if ((HPTE_V_AVPN_VAL(hpte_v) != avpn)
- || !(hpte_v & HPTE_V_VALID)) {
+ if (!HPTE_V_COMPARE(hpte_v, want_v) || !(hpte_v & HPTE_V_VALID))
native_unlock_hpte(hptep);
- } else {
+ else
/* Invalidate the hpte. NOTE: this also unlocks it */
hptep->v = 0;
- }
- /* Invalidate the tlb */
- if (cpu_has_feature(CPU_FTR_TLBIEL) && !large && local) {
- tlbiel(va);
- } else {
- if (lock_tlbie)
- spin_lock(&native_tlbie_lock);
- tlbie(va, large);
- if (lock_tlbie)
- spin_unlock(&native_tlbie_lock);
- }
+ /* Invalidate the TLB */
+ tlbie(va, psize, local);
+
local_irq_restore(flags);
}
/*
+ * XXX This need fixing based on page size. It's only used by
+ * native_hpte_clear() for now which needs fixing too so they
+ * make a good pair...
+ */
+static unsigned long slot2va(unsigned long hpte_v, unsigned long slot)
+{
+ unsigned long avpn = HPTE_V_AVPN_VAL(hpte_v);
+ unsigned long va;
+
+ va = avpn << 23;
+
+ if (! (hpte_v & HPTE_V_LARGE)) {
+ unsigned long vpi, pteg;
+
+ pteg = slot / HPTES_PER_GROUP;
+ if (hpte_v & HPTE_V_SECONDARY)
+ pteg = ~pteg;
+
+ vpi = ((va >> 28) ^ pteg) & htab_hash_mask;
+
+ va |= vpi << PAGE_SHIFT;
+ }
+
+ return va;
+}
+
+/*
* clear all mappings on kexec. All cpus are in real mode (or they will
* be when they isi), and we are the only one left. We rely on our kernel
* mapping being 0xC0's and the hardware ignoring those two real bits.
*
* TODO: add batching support when enabled. remember, no dynamic memory here,
* athough there is the control page available...
+ *
+ * XXX FIXME: 4k only for now !
*/
static void native_hpte_clear(void)
{
@@ -327,7 +405,7 @@ static void native_hpte_clear(void)
if (hpte_v & HPTE_V_VALID) {
hptep->v = 0;
- tlbie(slot2va(hpte_v, slot), hpte_v & HPTE_V_LARGE);
+ tlbie(slot2va(hpte_v, slot), MMU_PAGE_4K, 0);
}
}
@@ -335,66 +413,59 @@ static void native_hpte_clear(void)
local_irq_restore(flags);
}
-static void native_flush_hash_range(unsigned long context,
- unsigned long number, int local)
+/*
+ * Batched hash table flush, we batch the tlbie's to avoid taking/releasing
+ * the lock all the time
+ */
+static void native_flush_hash_range(unsigned long number, int local)
{
- unsigned long vsid, vpn, va, hash, secondary, slot, flags, avpn;
- int i, j;
+ unsigned long va, hash, index, hidx, shift, slot;
hpte_t *hptep;
unsigned long hpte_v;
+ unsigned long want_v;
+ unsigned long flags;
+ real_pte_t pte;
struct ppc64_tlb_batch *batch = &__get_cpu_var(ppc64_tlb_batch);
- unsigned long large = batch->large;
+ unsigned long psize = batch->psize;
+ int i;
local_irq_save(flags);
- j = 0;
for (i = 0; i < number; i++) {
- if (batch->addr[i] < KERNELBASE)
- vsid = get_vsid(context, batch->addr[i]);
- else
- vsid = get_kernel_vsid(batch->addr[i]);
-
- va = (vsid << 28) | (batch->addr[i] & 0x0fffffff);
- batch->vaddr[j] = va;
- if (large)
- vpn = va >> HPAGE_SHIFT;
- else
- vpn = va >> PAGE_SHIFT;
- hash = hpt_hash(vpn, large);
- secondary = (pte_val(batch->pte[i]) & _PAGE_SECONDARY) >> 15;
- if (secondary)
- hash = ~hash;
- slot = (hash & htab_hash_mask) * HPTES_PER_GROUP;
- slot += (pte_val(batch->pte[i]) & _PAGE_GROUP_IX) >> 12;
-
- hptep = htab_address + slot;
-
- avpn = va >> 23;
- if (large)
- avpn &= ~0x1UL;
-
- native_lock_hpte(hptep);
-
- hpte_v = hptep->v;
-
- /* Even if we miss, we need to invalidate the TLB */
- if ((HPTE_V_AVPN_VAL(hpte_v) != avpn)
- || !(hpte_v & HPTE_V_VALID)) {
- native_unlock_hpte(hptep);
- } else {
- /* Invalidate the hpte. NOTE: this also unlocks it */
- hptep->v = 0;
- }
-
- j++;
+ va = batch->vaddr[i];
+ pte = batch->pte[i];
+
+ pte_iterate_hashed_subpages(pte, psize, va, index, shift) {
+ hash = hpt_hash(va, shift);
+ hidx = __rpte_to_hidx(pte, index);
+ if (hidx & _PTEIDX_SECONDARY)
+ hash = ~hash;
+ slot = (hash & htab_hash_mask) * HPTES_PER_GROUP;
+ slot += hidx & _PTEIDX_GROUP_IX;
+ hptep = htab_address + slot;
+ want_v = hpte_encode_v(va, psize);
+ native_lock_hpte(hptep);
+ hpte_v = hptep->v;
+ if (!HPTE_V_COMPARE(hpte_v, want_v) ||
+ !(hpte_v & HPTE_V_VALID))
+ native_unlock_hpte(hptep);
+ else
+ hptep->v = 0;
+ } pte_iterate_hashed_end();
}
- if (cpu_has_feature(CPU_FTR_TLBIEL) && !large && local) {
+ if (cpu_has_feature(CPU_FTR_TLBIEL) &&
+ mmu_psize_defs[psize].tlbiel && local) {
asm volatile("ptesync":::"memory");
-
- for (i = 0; i < j; i++)
- __tlbiel(batch->vaddr[i]);
-
+ for (i = 0; i < number; i++) {
+ va = batch->vaddr[i];
+ pte = batch->pte[i];
+
+ pte_iterate_hashed_subpages(pte, psize, va, index,
+ shift) {
+ __tlbiel(va, psize);
+ } pte_iterate_hashed_end();
+ }
asm volatile("ptesync":::"memory");
} else {
int lock_tlbie = !cpu_has_feature(CPU_FTR_LOCKLESS_TLBIE);
@@ -403,10 +474,15 @@ static void native_flush_hash_range(unsigned long context,
spin_lock(&native_tlbie_lock);
asm volatile("ptesync":::"memory");
-
- for (i = 0; i < j; i++)
- __tlbie(batch->vaddr[i], large);
-
+ for (i = 0; i < number; i++) {
+ va = batch->vaddr[i];
+ pte = batch->pte[i];
+
+ pte_iterate_hashed_subpages(pte, psize, va, index,
+ shift) {
+ __tlbie(va, psize);
+ } pte_iterate_hashed_end();
+ }
asm volatile("eieio; tlbsync; ptesync":::"memory");
if (lock_tlbie)
diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c
new file mode 100644
index 000000000000..706e8a63ced9
--- /dev/null
+++ b/arch/powerpc/mm/hash_utils_64.c
@@ -0,0 +1,775 @@
+/*
+ * PowerPC64 port by Mike Corrigan and Dave Engebretsen
+ * {mikejc|engebret}@us.ibm.com
+ *
+ * Copyright (c) 2000 Mike Corrigan <mikejc@us.ibm.com>
+ *
+ * SMP scalability work:
+ * Copyright (C) 2001 Anton Blanchard <anton@au.ibm.com>, IBM
+ *
+ * Module name: htab.c
+ *
+ * Description:
+ * PowerPC Hashed Page Table functions
+ *
+ * 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.
+ */
+
+#undef DEBUG
+#undef DEBUG_LOW
+
+#include <linux/config.h>
+#include <linux/spinlock.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/proc_fs.h>
+#include <linux/stat.h>
+#include <linux/sysctl.h>
+#include <linux/ctype.h>
+#include <linux/cache.h>
+#include <linux/init.h>
+#include <linux/signal.h>
+
+#include <asm/processor.h>
+#include <asm/pgtable.h>
+#include <asm/mmu.h>
+#include <asm/mmu_context.h>
+#include <asm/page.h>
+#include <asm/types.h>
+#include <asm/system.h>
+#include <asm/uaccess.h>
+#include <asm/machdep.h>
+#include <asm/lmb.h>
+#include <asm/abs_addr.h>
+#include <asm/tlbflush.h>
+#include <asm/io.h>
+#include <asm/eeh.h>
+#include <asm/tlb.h>
+#include <asm/cacheflush.h>
+#include <asm/cputable.h>
+#include <asm/abs_addr.h>
+#include <asm/sections.h>
+
+#ifdef DEBUG
+#define DBG(fmt...) udbg_printf(fmt)
+#else
+#define DBG(fmt...)
+#endif
+
+#ifdef DEBUG_LOW
+#define DBG_LOW(fmt...) udbg_printf(fmt)
+#else
+#define DBG_LOW(fmt...)
+#endif
+
+#define KB (1024)
+#define MB (1024*KB)
+
+/*
+ * Note: pte --> Linux PTE
+ * HPTE --> PowerPC Hashed Page Table Entry
+ *
+ * Execution context:
+ * htab_initialize is called with the MMU off (of course), but
+ * the kernel has been copied down to zero so it can directly
+ * reference global data. At this point it is very difficult
+ * to print debug info.
+ *
+ */
+
+#ifdef CONFIG_U3_DART
+extern unsigned long dart_tablebase;
+#endif /* CONFIG_U3_DART */
+
+static unsigned long _SDR1;
+struct mmu_psize_def mmu_psize_defs[MMU_PAGE_COUNT];
+
+hpte_t *htab_address;
+unsigned long htab_hash_mask;
+int mmu_linear_psize = MMU_PAGE_4K;
+int mmu_virtual_psize = MMU_PAGE_4K;
+#ifdef CONFIG_HUGETLB_PAGE
+int mmu_huge_psize = MMU_PAGE_16M;
+unsigned int HPAGE_SHIFT;
+#endif
+
+/* There are definitions of page sizes arrays to be used when none
+ * is provided by the firmware.
+ */
+
+/* Pre-POWER4 CPUs (4k pages only)
+ */
+struct mmu_psize_def mmu_psize_defaults_old[] = {
+ [MMU_PAGE_4K] = {
+ .shift = 12,
+ .sllp = 0,
+ .penc = 0,
+ .avpnm = 0,
+ .tlbiel = 0,
+ },
+};
+
+/* POWER4, GPUL, POWER5
+ *
+ * Support for 16Mb large pages
+ */
+struct mmu_psize_def mmu_psize_defaults_gp[] = {
+ [MMU_PAGE_4K] = {
+ .shift = 12,
+ .sllp = 0,
+ .penc = 0,
+ .avpnm = 0,
+ .tlbiel = 1,
+ },
+ [MMU_PAGE_16M] = {
+ .shift = 24,
+ .sllp = SLB_VSID_L,
+ .penc = 0,
+ .avpnm = 0x1UL,
+ .tlbiel = 0,
+ },
+};
+
+
+int htab_bolt_mapping(unsigned long vstart, unsigned long vend,
+ unsigned long pstart, unsigned long mode, int psize)
+{
+ unsigned long vaddr, paddr;
+ unsigned int step, shift;
+ unsigned long tmp_mode;
+ int ret = 0;
+
+ shift = mmu_psize_defs[psize].shift;
+ step = 1 << shift;
+
+ for (vaddr = vstart, paddr = pstart; vaddr < vend;
+ vaddr += step, paddr += step) {
+ unsigned long vpn, hash, hpteg;
+ unsigned long vsid = get_kernel_vsid(vaddr);
+ unsigned long va = (vsid << 28) | (vaddr & 0x0fffffff);
+
+ vpn = va >> shift;
+ tmp_mode = mode;
+
+ /* Make non-kernel text non-executable */
+ if (!in_kernel_text(vaddr))
+ tmp_mode = mode | HPTE_R_N;
+
+ hash = hpt_hash(va, shift);
+ hpteg = ((hash & htab_hash_mask) * HPTES_PER_GROUP);
+
+ /* The crap below can be cleaned once ppd_md.probe() can
+ * set up the hash callbacks, thus we can just used the
+ * normal insert callback here.
+ */
+#ifdef CONFIG_PPC_ISERIES
+ if (_machine == PLATFORM_ISERIES_LPAR)
+ ret = iSeries_hpte_insert(hpteg, va,
+ virt_to_abs(paddr),
+ tmp_mode,
+ HPTE_V_BOLTED,
+ psize);
+ else
+#endif
+#ifdef CONFIG_PPC_PSERIES
+ if (_machine & PLATFORM_LPAR)
+ ret = pSeries_lpar_hpte_insert(hpteg, va,
+ virt_to_abs(paddr),
+ tmp_mode,
+ HPTE_V_BOLTED,
+ psize);
+ else
+#endif
+#ifdef CONFIG_PPC_MULTIPLATFORM
+ ret = native_hpte_insert(hpteg, va,
+ virt_to_abs(paddr),
+ tmp_mode, HPTE_V_BOLTED,
+ psize);
+#endif
+ if (ret < 0)
+ break;
+ }
+ return ret < 0 ? ret : 0;
+}
+
+static int __init htab_dt_scan_page_sizes(unsigned long node,
+ const char *uname, int depth,
+ void *data)
+{
+ char *type = of_get_flat_dt_prop(node, "device_type", NULL);
+ u32 *prop;
+ unsigned long size = 0;
+
+ /* We are scanning "cpu" nodes only */
+ if (type == NULL || strcmp(type, "cpu") != 0)
+ return 0;
+
+ prop = (u32 *)of_get_flat_dt_prop(node,
+ "ibm,segment-page-sizes", &size);
+ if (prop != NULL) {
+ DBG("Page sizes from device-tree:\n");
+ size /= 4;
+ cur_cpu_spec->cpu_features &= ~(CPU_FTR_16M_PAGE);
+ while(size > 0) {
+ unsigned int shift = prop[0];
+ unsigned int slbenc = prop[1];
+ unsigned int lpnum = prop[2];
+ unsigned int lpenc = 0;
+ struct mmu_psize_def *def;
+ int idx = -1;
+
+ size -= 3; prop += 3;
+ while(size > 0 && lpnum) {
+ if (prop[0] == shift)
+ lpenc = prop[1];
+ prop += 2; size -= 2;
+ lpnum--;
+ }
+ switch(shift) {
+ case 0xc:
+ idx = MMU_PAGE_4K;
+ break;
+ case 0x10:
+ idx = MMU_PAGE_64K;
+ break;
+ case 0x14:
+ idx = MMU_PAGE_1M;
+ break;
+ case 0x18:
+ idx = MMU_PAGE_16M;
+ cur_cpu_spec->cpu_features |= CPU_FTR_16M_PAGE;
+ break;
+ case 0x22:
+ idx = MMU_PAGE_16G;
+ break;
+ }
+ if (idx < 0)
+ continue;
+ def = &mmu_psize_defs[idx];
+ def->shift = shift;
+ if (shift <= 23)
+ def->avpnm = 0;
+ else
+ def->avpnm = (1 << (shift - 23)) - 1;
+ def->sllp = slbenc;
+ def->penc = lpenc;
+ /* We don't know for sure what's up with tlbiel, so
+ * for now we only set it for 4K and 64K pages
+ */
+ if (idx == MMU_PAGE_4K || idx == MMU_PAGE_64K)
+ def->tlbiel = 1;
+ else
+ def->tlbiel = 0;
+
+ DBG(" %d: shift=%02x, sllp=%04x, avpnm=%08x, "
+ "tlbiel=%d, penc=%d\n",
+ idx, shift, def->sllp, def->avpnm, def->tlbiel,
+ def->penc);
+ }
+ return 1;
+ }
+ return 0;
+}
+
+
+static void __init htab_init_page_sizes(void)
+{
+ int rc;
+
+ /* Default to 4K pages only */
+ memcpy(mmu_psize_defs, mmu_psize_defaults_old,
+ sizeof(mmu_psize_defaults_old));
+
+ /*
+ * Try to find the available page sizes in the device-tree
+ */
+ rc = of_scan_flat_dt(htab_dt_scan_page_sizes, NULL);
+ if (rc != 0) /* Found */
+ goto found;
+
+ /*
+ * Not in the device-tree, let's fallback on known size
+ * list for 16M capable GP & GR
+ */
+ if ((_machine != PLATFORM_ISERIES_LPAR) &&
+ cpu_has_feature(CPU_FTR_16M_PAGE))
+ memcpy(mmu_psize_defs, mmu_psize_defaults_gp,
+ sizeof(mmu_psize_defaults_gp));
+ found:
+ /*
+ * Pick a size for the linear mapping. Currently, we only support
+ * 16M, 1M and 4K which is the default
+ */
+ if (mmu_psize_defs[MMU_PAGE_16M].shift)
+ mmu_linear_psize = MMU_PAGE_16M;
+ else if (mmu_psize_defs[MMU_PAGE_1M].shift)
+ mmu_linear_psize = MMU_PAGE_1M;
+
+ /*
+ * Pick a size for the ordinary pages. Default is 4K, we support
+ * 64K if cache inhibited large pages are supported by the
+ * processor
+ */
+#ifdef CONFIG_PPC_64K_PAGES
+ if (mmu_psize_defs[MMU_PAGE_64K].shift &&
+ cpu_has_feature(CPU_FTR_CI_LARGE_PAGE))
+ mmu_virtual_psize = MMU_PAGE_64K;
+#endif
+
+ printk(KERN_INFO "Page orders: linear mapping = %d, others = %d\n",
+ mmu_psize_defs[mmu_linear_psize].shift,
+ mmu_psize_defs[mmu_virtual_psize].shift);
+
+#ifdef CONFIG_HUGETLB_PAGE
+ /* Init large page size. Currently, we pick 16M or 1M depending
+ * on what is available
+ */
+ if (mmu_psize_defs[MMU_PAGE_16M].shift)
+ mmu_huge_psize = MMU_PAGE_16M;
+ /* With 4k/4level pagetables, we can't (for now) cope with a
+ * huge page size < PMD_SIZE */
+ else if (mmu_psize_defs[MMU_PAGE_1M].shift)
+ mmu_huge_psize = MMU_PAGE_1M;
+
+ /* Calculate HPAGE_SHIFT and sanity check it */
+ if (mmu_psize_defs[mmu_huge_psize].shift > MIN_HUGEPTE_SHIFT &&
+ mmu_psize_defs[mmu_huge_psize].shift < SID_SHIFT)
+ HPAGE_SHIFT = mmu_psize_defs[mmu_huge_psize].shift;
+ else
+ HPAGE_SHIFT = 0; /* No huge pages dude ! */
+#endif /* CONFIG_HUGETLB_PAGE */
+}
+
+static int __init htab_dt_scan_pftsize(unsigned long node,
+ const char *uname, int depth,
+ void *data)
+{
+ char *type = of_get_flat_dt_prop(node, "device_type", NULL);
+ u32 *prop;
+
+ /* We are scanning "cpu" nodes only */
+ if (type == NULL || strcmp(type, "cpu") != 0)
+ return 0;
+
+ prop = (u32 *)of_get_flat_dt_prop(node, "ibm,pft-size", NULL);
+ if (prop != NULL) {
+ /* pft_size[0] is the NUMA CEC cookie */
+ ppc64_pft_size = prop[1];
+ return 1;
+ }
+ return 0;
+}
+
+static unsigned long __init htab_get_table_size(void)
+{
+ unsigned long mem_size, rnd_mem_size, pteg_count;
+
+ /* If hash size isn't already provided by the platform, we try to
+ * retreive it from the device-tree. If it's not there neither, we
+ * calculate it now based on the total RAM size
+ */
+ if (ppc64_pft_size == 0)
+ of_scan_flat_dt(htab_dt_scan_pftsize, NULL);
+ if (ppc64_pft_size)
+ return 1UL << ppc64_pft_size;
+
+ /* round mem_size up to next power of 2 */
+ mem_size = lmb_phys_mem_size();
+ rnd_mem_size = 1UL << __ilog2(mem_size);
+ if (rnd_mem_size < mem_size)
+ rnd_mem_size <<= 1;
+
+ /* # pages / 2 */
+ pteg_count = max(rnd_mem_size >> (12 + 1), 1UL << 11);
+
+ return pteg_count << 7;
+}
+
+#ifdef CONFIG_MEMORY_HOTPLUG
+void create_section_mapping(unsigned long start, unsigned long end)
+{
+ BUG_ON(htab_bolt_mapping(start, end, start,
+ _PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_COHERENT | PP_RWXX,
+ mmu_linear_psize));
+}
+#endif /* CONFIG_MEMORY_HOTPLUG */
+
+void __init htab_initialize(void)
+{
+ unsigned long table, htab_size_bytes;
+ unsigned long pteg_count;
+ unsigned long mode_rw;
+ unsigned long base = 0, size = 0;
+ int i;
+
+ extern unsigned long tce_alloc_start, tce_alloc_end;
+
+ DBG(" -> htab_initialize()\n");
+
+ /* Initialize page sizes */
+ htab_init_page_sizes();
+
+ /*
+ * Calculate the required size of the htab. We want the number of
+ * PTEGs to equal one half the number of real pages.
+ */
+ htab_size_bytes = htab_get_table_size();
+ pteg_count = htab_size_bytes >> 7;
+
+ htab_hash_mask = pteg_count - 1;
+
+ if (platform_is_lpar()) {
+ /* Using a hypervisor which owns the htab */
+ htab_address = NULL;
+ _SDR1 = 0;
+ } else {
+ /* Find storage for the HPT. Must be contiguous in
+ * the absolute address space.
+ */
+ table = lmb_alloc(htab_size_bytes, htab_size_bytes);
+ BUG_ON(table == 0);
+
+ DBG("Hash table allocated at %lx, size: %lx\n", table,
+ htab_size_bytes);
+
+ htab_address = abs_to_virt(table);
+
+ /* htab absolute addr + encoded htabsize */
+ _SDR1 = table + __ilog2(pteg_count) - 11;
+
+ /* Initialize the HPT with no entries */
+ memset((void *)table, 0, htab_size_bytes);
+
+ /* Set SDR1 */
+ mtspr(SPRN_SDR1, _SDR1);
+ }
+
+ mode_rw = _PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_COHERENT | PP_RWXX;
+
+ /* On U3 based machines, we need to reserve the DART area and
+ * _NOT_ map it to avoid cache paradoxes as it's remapped non
+ * cacheable later on
+ */
+
+ /* create bolted the linear mapping in the hash table */
+ for (i=0; i < lmb.memory.cnt; i++) {
+ base = lmb.memory.region[i].base + KERNELBASE;
+ size = lmb.memory.region[i].size;
+
+ DBG("creating mapping for region: %lx : %lx\n", base, size);
+
+#ifdef CONFIG_U3_DART
+ /* Do not map the DART space. Fortunately, it will be aligned
+ * in such a way that it will not cross two lmb regions and
+ * will fit within a single 16Mb page.
+ * The DART space is assumed to be a full 16Mb region even if
+ * we only use 2Mb of that space. We will use more of it later
+ * for AGP GART. We have to use a full 16Mb large page.
+ */
+ DBG("DART base: %lx\n", dart_tablebase);
+
+ if (dart_tablebase != 0 && dart_tablebase >= base
+ && dart_tablebase < (base + size)) {
+ if (base != dart_tablebase)
+ BUG_ON(htab_bolt_mapping(base, dart_tablebase,
+ base, mode_rw,
+ mmu_linear_psize));
+ if ((base + size) > (dart_tablebase + 16*MB))
+ BUG_ON(htab_bolt_mapping(dart_tablebase+16*MB,
+ base + size,
+ dart_tablebase+16*MB,
+ mode_rw,
+ mmu_linear_psize));
+ continue;
+ }
+#endif /* CONFIG_U3_DART */
+ BUG_ON(htab_bolt_mapping(base, base + size, base,
+ mode_rw, mmu_linear_psize));
+ }
+
+ /*
+ * If we have a memory_limit and we've allocated TCEs then we need to
+ * explicitly map the TCE area at the top of RAM. We also cope with the
+ * case that the TCEs start below memory_limit.
+ * tce_alloc_start/end are 16MB aligned so the mapping should work
+ * for either 4K or 16MB pages.
+ */
+ if (tce_alloc_start) {
+ tce_alloc_start += KERNELBASE;
+ tce_alloc_end += KERNELBASE;
+
+ if (base + size >= tce_alloc_start)
+ tce_alloc_start = base + size + 1;
+
+ BUG_ON(htab_bolt_mapping(tce_alloc_start, tce_alloc_end,
+ tce_alloc_start, mode_rw,
+ mmu_linear_psize));
+ }
+
+ DBG(" <- htab_initialize()\n");
+}
+#undef KB
+#undef MB
+
+void __init htab_initialize_secondary(void)
+{
+ if (!platform_is_lpar())
+ mtspr(SPRN_SDR1, _SDR1);
+}
+
+/*
+ * Called by asm hashtable.S for doing lazy icache flush
+ */
+unsigned int hash_page_do_lazy_icache(unsigned int pp, pte_t pte, int trap)
+{
+ struct page *page;
+
+ if (!pfn_valid(pte_pfn(pte)))
+ return pp;
+
+ page = pte_page(pte);
+
+ /* page is dirty */
+ if (!test_bit(PG_arch_1, &page->flags) && !PageReserved(page)) {
+ if (trap == 0x400) {
+ __flush_dcache_icache(page_address(page));
+ set_bit(PG_arch_1, &page->flags);
+ } else
+ pp |= HPTE_R_N;
+ }
+ return pp;
+}
+
+/* Result code is:
+ * 0 - handled
+ * 1 - normal page fault
+ * -1 - critical hash insertion error
+ */
+int hash_page(unsigned long ea, unsigned long access, unsigned long trap)
+{
+ void *pgdir;
+ unsigned long vsid;
+ struct mm_struct *mm;
+ pte_t *ptep;
+ cpumask_t tmp;
+ int rc, user_region = 0, local = 0;
+
+ DBG_LOW("hash_page(ea=%016lx, access=%lx, trap=%lx\n",
+ ea, access, trap);
+
+ if ((ea & ~REGION_MASK) >= PGTABLE_RANGE) {
+ DBG_LOW(" out of pgtable range !\n");
+ return 1;
+ }
+
+ /* Get region & vsid */
+ switch (REGION_ID(ea)) {
+ case USER_REGION_ID:
+ user_region = 1;
+ mm = current->mm;
+ if (! mm) {
+ DBG_LOW(" user region with no mm !\n");
+ return 1;
+ }
+ vsid = get_vsid(mm->context.id, ea);
+ break;
+ case VMALLOC_REGION_ID:
+ mm = &init_mm;
+ vsid = get_kernel_vsid(ea);
+ break;
+ default:
+ /* Not a valid range
+ * Send the problem up to do_page_fault
+ */
+ return 1;
+ }
+ DBG_LOW(" mm=%p, mm->pgdir=%p, vsid=%016lx\n", mm, mm->pgd, vsid);
+
+ /* Get pgdir */
+ pgdir = mm->pgd;
+ if (pgdir == NULL)
+ return 1;
+
+ /* Check CPU locality */
+ tmp = cpumask_of_cpu(smp_processor_id());
+ if (user_region && cpus_equal(mm->cpu_vm_mask, tmp))
+ local = 1;
+
+ /* Handle hugepage regions */
+ if (unlikely(in_hugepage_area(mm->context, ea))) {
+ DBG_LOW(" -> huge page !\n");
+ return hash_huge_page(mm, access, ea, vsid, local);
+ }
+
+ /* Get PTE and page size from page tables */
+ ptep = find_linux_pte(pgdir, ea);
+ if (ptep == NULL || !pte_present(*ptep)) {
+ DBG_LOW(" no PTE !\n");
+ return 1;
+ }
+
+#ifndef CONFIG_PPC_64K_PAGES
+ DBG_LOW(" i-pte: %016lx\n", pte_val(*ptep));
+#else
+ DBG_LOW(" i-pte: %016lx %016lx\n", pte_val(*ptep),
+ pte_val(*(ptep + PTRS_PER_PTE)));
+#endif
+ /* Pre-check access permissions (will be re-checked atomically
+ * in __hash_page_XX but this pre-check is a fast path
+ */
+ if (access & ~pte_val(*ptep)) {
+ DBG_LOW(" no access !\n");
+ return 1;
+ }
+
+ /* Do actual hashing */
+#ifndef CONFIG_PPC_64K_PAGES
+ rc = __hash_page_4K(ea, access, vsid, ptep, trap, local);
+#else
+ if (mmu_virtual_psize == MMU_PAGE_64K)
+ rc = __hash_page_64K(ea, access, vsid, ptep, trap, local);
+ else
+ rc = __hash_page_4K(ea, access, vsid, ptep, trap, local);
+#endif /* CONFIG_PPC_64K_PAGES */
+
+#ifndef CONFIG_PPC_64K_PAGES
+ DBG_LOW(" o-pte: %016lx\n", pte_val(*ptep));
+#else
+ DBG_LOW(" o-pte: %016lx %016lx\n", pte_val(*ptep),
+ pte_val(*(ptep + PTRS_PER_PTE)));
+#endif
+ DBG_LOW(" -> rc=%d\n", rc);
+ return rc;
+}
+
+void hash_preload(struct mm_struct *mm, unsigned long ea,
+ unsigned long access, unsigned long trap)
+{
+ unsigned long vsid;
+ void *pgdir;
+ pte_t *ptep;
+ cpumask_t mask;
+ unsigned long flags;
+ int local = 0;
+
+ /* We don't want huge pages prefaulted for now
+ */
+ if (unlikely(in_hugepage_area(mm->context, ea)))
+ return;
+
+ DBG_LOW("hash_preload(mm=%p, mm->pgdir=%p, ea=%016lx, access=%lx,"
+ " trap=%lx\n", mm, mm->pgd, ea, access, trap);
+
+ /* Get PTE, VSID, access mask */
+ pgdir = mm->pgd;
+ if (pgdir == NULL)
+ return;
+ ptep = find_linux_pte(pgdir, ea);
+ if (!ptep)
+ return;
+ vsid = get_vsid(mm->context.id, ea);
+
+ /* Hash it in */
+ local_irq_save(flags);
+ mask = cpumask_of_cpu(smp_processor_id());
+ if (cpus_equal(mm->cpu_vm_mask, mask))
+ local = 1;
+#ifndef CONFIG_PPC_64K_PAGES
+ __hash_page_4K(ea, access, vsid, ptep, trap, local);
+#else
+ if (mmu_virtual_psize == MMU_PAGE_64K)
+ __hash_page_64K(ea, access, vsid, ptep, trap, local);
+ else
+ __hash_page_4K(ea, access, vsid, ptep, trap, local);
+#endif /* CONFIG_PPC_64K_PAGES */
+ local_irq_restore(flags);
+}
+
+void flush_hash_page(unsigned long va, real_pte_t pte, int psize, int local)
+{
+ unsigned long hash, index, shift, hidx, slot;
+
+ DBG_LOW("flush_hash_page(va=%016x)\n", va);
+ pte_iterate_hashed_subpages(pte, psize, va, index, shift) {
+ hash = hpt_hash(va, shift);
+ hidx = __rpte_to_hidx(pte, index);
+ if (hidx & _PTEIDX_SECONDARY)
+ hash = ~hash;
+ slot = (hash & htab_hash_mask) * HPTES_PER_GROUP;
+ slot += hidx & _PTEIDX_GROUP_IX;
+ DBG_LOW(" sub %d: hash=%x, hidx=%x\n", index, slot, hidx);
+ ppc_md.hpte_invalidate(slot, va, psize, local);
+ } pte_iterate_hashed_end();
+}
+
+void flush_hash_range(unsigned long number, int local)
+{
+ if (ppc_md.flush_hash_range)
+ ppc_md.flush_hash_range(number, local);
+ else {
+ int i;
+ struct ppc64_tlb_batch *batch =
+ &__get_cpu_var(ppc64_tlb_batch);
+
+ for (i = 0; i < number; i++)
+ flush_hash_page(batch->vaddr[i], batch->pte[i],
+ batch->psize, local);
+ }
+}
+
+static inline void make_bl(unsigned int *insn_addr, void *func)
+{
+ unsigned long funcp = *((unsigned long *)func);
+ int offset = funcp - (unsigned long)insn_addr;
+
+ *insn_addr = (unsigned int)(0x48000001 | (offset & 0x03fffffc));
+ flush_icache_range((unsigned long)insn_addr, 4+
+ (unsigned long)insn_addr);
+}
+
+/*
+ * low_hash_fault is called when we the low level hash code failed
+ * to instert a PTE due to an hypervisor error
+ */
+void low_hash_fault(struct pt_regs *regs, unsigned long address)
+{
+ if (user_mode(regs)) {
+ siginfo_t info;
+
+ info.si_signo = SIGBUS;
+ info.si_errno = 0;
+ info.si_code = BUS_ADRERR;
+ info.si_addr = (void __user *)address;
+ force_sig_info(SIGBUS, &info, current);
+ return;
+ }
+ bad_page_fault(regs, address, SIGBUS);
+}
+
+void __init htab_finish_init(void)
+{
+ extern unsigned int *htab_call_hpte_insert1;
+ extern unsigned int *htab_call_hpte_insert2;
+ extern unsigned int *htab_call_hpte_remove;
+ extern unsigned int *htab_call_hpte_updatepp;
+
+#ifdef CONFIG_PPC_64K_PAGES
+ extern unsigned int *ht64_call_hpte_insert1;
+ extern unsigned int *ht64_call_hpte_insert2;
+ extern unsigned int *ht64_call_hpte_remove;
+ extern unsigned int *ht64_call_hpte_updatepp;
+
+ make_bl(ht64_call_hpte_insert1, ppc_md.hpte_insert);
+ make_bl(ht64_call_hpte_insert2, ppc_md.hpte_insert);
+ make_bl(ht64_call_hpte_remove, ppc_md.hpte_remove);
+ make_bl(ht64_call_hpte_updatepp, ppc_md.hpte_updatepp);
+#endif /* CONFIG_PPC_64K_PAGES */
+
+ make_bl(htab_call_hpte_insert1, ppc_md.hpte_insert);
+ make_bl(htab_call_hpte_insert2, ppc_md.hpte_insert);
+ make_bl(htab_call_hpte_remove, ppc_md.hpte_remove);
+ make_bl(htab_call_hpte_updatepp, ppc_md.hpte_updatepp);
+}
diff --git a/arch/ppc64/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c
index 0ea0994ed974..426c269e552e 100644
--- a/arch/ppc64/mm/hugetlbpage.c
+++ b/arch/powerpc/mm/hugetlbpage.c
@@ -47,10 +47,25 @@ pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr)
pu = pud_offset(pg, addr);
if (!pud_none(*pu)) {
pm = pmd_offset(pu, addr);
+#ifdef CONFIG_PPC_64K_PAGES
+ /* Currently, we use the normal PTE offset within full
+ * size PTE pages, thus our huge PTEs are scattered in
+ * the PTE page and we do waste some. We may change
+ * that in the future, but the current mecanism keeps
+ * things much simpler
+ */
+ if (!pmd_none(*pm)) {
+ /* Note: pte_offset_* are all equivalent on
+ * ppc64 as we don't have HIGHMEM
+ */
+ pt = pte_offset_kernel(pm, addr);
+ return pt;
+ }
+#else /* CONFIG_PPC_64K_PAGES */
+ /* On 4k pages, we put huge PTEs in the PMD page */
pt = (pte_t *)pm;
- BUG_ON(!pmd_none(*pm)
- && !(pte_present(*pt) && pte_huge(*pt)));
return pt;
+#endif /* CONFIG_PPC_64K_PAGES */
}
}
@@ -74,9 +89,16 @@ pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr)
if (pu) {
pm = pmd_alloc(mm, pu, addr);
if (pm) {
+#ifdef CONFIG_PPC_64K_PAGES
+ /* See comment in huge_pte_offset. Note that if we ever
+ * want to put the page size in the PMD, we would have
+ * to open code our own pte_alloc* function in order
+ * to populate and set the size atomically
+ */
+ pt = pte_alloc_map(mm, pm, addr);
+#else /* CONFIG_PPC_64K_PAGES */
pt = (pte_t *)pm;
- BUG_ON(!pmd_none(*pm)
- && !(pte_present(*pt) && pte_huge(*pt)));
+#endif /* CONFIG_PPC_64K_PAGES */
return pt;
}
}
@@ -84,35 +106,29 @@ pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr)
return NULL;
}
-#define HUGEPTE_BATCH_SIZE (HPAGE_SIZE / PMD_SIZE)
-
void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
pte_t *ptep, pte_t pte)
{
- int i;
-
if (pte_present(*ptep)) {
- pte_clear(mm, addr, ptep);
+ /* We open-code pte_clear because we need to pass the right
+ * argument to hpte_update (huge / !huge)
+ */
+ unsigned long old = pte_update(ptep, ~0UL);
+ if (old & _PAGE_HASHPTE)
+ hpte_update(mm, addr & HPAGE_MASK, ptep, old, 1);
flush_tlb_pending();
}
-
- for (i = 0; i < HUGEPTE_BATCH_SIZE; i++) {
- *ptep = __pte(pte_val(pte) & ~_PAGE_HPTEFLAGS);
- ptep++;
- }
+ *ptep = __pte(pte_val(pte) & ~_PAGE_HPTEFLAGS);
}
pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr,
pte_t *ptep)
{
unsigned long old = pte_update(ptep, ~0UL);
- int i;
if (old & _PAGE_HASHPTE)
- hpte_update(mm, addr, old, 0);
-
- for (i = 1; i < HUGEPTE_BATCH_SIZE; i++)
- ptep[i] = __pte(0);
+ hpte_update(mm, addr & HPAGE_MASK, ptep, old, 1);
+ *ptep = __pte(0);
return __pte(old);
}
@@ -196,6 +212,12 @@ static int prepare_high_area_for_htlb(struct mm_struct *mm, unsigned long area)
BUG_ON(area >= NUM_HIGH_AREAS);
+ /* Hack, so that each addresses is controlled by exactly one
+ * of the high or low area bitmaps, the first high area starts
+ * at 4GB, not 0 */
+ if (start == 0)
+ start = 0x100000000UL;
+
/* Check no VMAs are in the region */
vma = find_vma(mm, start);
if (vma && (vma->vm_start < end))
@@ -563,6 +585,8 @@ unsigned long hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
int lastshift;
u16 areamask, curareas;
+ if (HPAGE_SHIFT == 0)
+ return -EINVAL;
if (len & ~HPAGE_MASK)
return -EINVAL;
@@ -619,19 +643,15 @@ int hash_huge_page(struct mm_struct *mm, unsigned long access,
unsigned long ea, unsigned long vsid, int local)
{
pte_t *ptep;
- unsigned long va, vpn;
- pte_t old_pte, new_pte;
- unsigned long rflags, prpn;
+ unsigned long old_pte, new_pte;
+ unsigned long va, rflags, pa;
long slot;
int err = 1;
- spin_lock(&mm->page_table_lock);
-
ptep = huge_pte_offset(mm, ea);
/* Search the Linux page table for a match with va */
va = (vsid << 28) | (ea & 0x0fffffff);
- vpn = va >> HPAGE_SHIFT;
/*
* If no pte found or not present, send the problem up to
@@ -640,8 +660,6 @@ int hash_huge_page(struct mm_struct *mm, unsigned long access,
if (unlikely(!ptep || pte_none(*ptep)))
goto out;
-/* BUG_ON(pte_bad(*ptep)); */
-
/*
* Check the user's access rights to the page. If access should be
* prevented then send the problem up to do_page_fault.
@@ -661,58 +679,64 @@ int hash_huge_page(struct mm_struct *mm, unsigned long access,
*/
- old_pte = *ptep;
- new_pte = old_pte;
-
- rflags = 0x2 | (! (pte_val(new_pte) & _PAGE_RW));
+ do {
+ old_pte = pte_val(*ptep);
+ if (old_pte & _PAGE_BUSY)
+ goto out;
+ new_pte = old_pte | _PAGE_BUSY |
+ _PAGE_ACCESSED | _PAGE_HASHPTE;
+ } while(old_pte != __cmpxchg_u64((unsigned long *)ptep,
+ old_pte, new_pte));
+
+ rflags = 0x2 | (!(new_pte & _PAGE_RW));
/* _PAGE_EXEC -> HW_NO_EXEC since it's inverted */
- rflags |= ((pte_val(new_pte) & _PAGE_EXEC) ? 0 : HW_NO_EXEC);
+ rflags |= ((new_pte & _PAGE_EXEC) ? 0 : HPTE_R_N);
/* Check if pte already has an hpte (case 2) */
- if (unlikely(pte_val(old_pte) & _PAGE_HASHPTE)) {
+ if (unlikely(old_pte & _PAGE_HASHPTE)) {
/* There MIGHT be an HPTE for this pte */
unsigned long hash, slot;
- hash = hpt_hash(vpn, 1);
- if (pte_val(old_pte) & _PAGE_SECONDARY)
+ hash = hpt_hash(va, HPAGE_SHIFT);
+ if (old_pte & _PAGE_F_SECOND)
hash = ~hash;
slot = (hash & htab_hash_mask) * HPTES_PER_GROUP;
- slot += (pte_val(old_pte) & _PAGE_GROUP_IX) >> 12;
+ slot += (old_pte & _PAGE_F_GIX) >> 12;
if (ppc_md.hpte_updatepp(slot, rflags, va, 1, local) == -1)
- pte_val(old_pte) &= ~_PAGE_HPTEFLAGS;
+ old_pte &= ~_PAGE_HPTEFLAGS;
}
- if (likely(!(pte_val(old_pte) & _PAGE_HASHPTE))) {
- unsigned long hash = hpt_hash(vpn, 1);
+ if (likely(!(old_pte & _PAGE_HASHPTE))) {
+ unsigned long hash = hpt_hash(va, HPAGE_SHIFT);
unsigned long hpte_group;
- prpn = pte_pfn(old_pte);
+ pa = pte_pfn(__pte(old_pte)) << PAGE_SHIFT;
repeat:
hpte_group = ((hash & htab_hash_mask) *
HPTES_PER_GROUP) & ~0x7UL;
- /* Update the linux pte with the HPTE slot */
- pte_val(new_pte) &= ~_PAGE_HPTEFLAGS;
- pte_val(new_pte) |= _PAGE_HASHPTE;
+ /* clear HPTE slot informations in new PTE */
+ new_pte = (new_pte & ~_PAGE_HPTEFLAGS) | _PAGE_HASHPTE;
/* Add in WIMG bits */
/* XXX We should store these in the pte */
+ /* --BenH: I think they are ... */
rflags |= _PAGE_COHERENT;
- slot = ppc_md.hpte_insert(hpte_group, va, prpn,
- HPTE_V_LARGE, rflags);
+ /* Insert into the hash table, primary slot */
+ slot = ppc_md.hpte_insert(hpte_group, va, pa, rflags, 0,
+ mmu_huge_psize);
/* Primary is full, try the secondary */
if (unlikely(slot == -1)) {
- pte_val(new_pte) |= _PAGE_SECONDARY;
+ new_pte |= _PAGE_F_SECOND;
hpte_group = ((~hash & htab_hash_mask) *
HPTES_PER_GROUP) & ~0x7UL;
- slot = ppc_md.hpte_insert(hpte_group, va, prpn,
- HPTE_V_LARGE |
+ slot = ppc_md.hpte_insert(hpte_group, va, pa, rflags,
HPTE_V_SECONDARY,
- rflags);
+ mmu_huge_psize);
if (slot == -1) {
if (mftb() & 0x1)
hpte_group = ((hash & htab_hash_mask) *
@@ -726,20 +750,18 @@ repeat:
if (unlikely(slot == -2))
panic("hash_huge_page: pte_insert failed\n");
- pte_val(new_pte) |= (slot<<12) & _PAGE_GROUP_IX;
-
- /*
- * No need to use ldarx/stdcx here because all who
- * might be updating the pte will hold the
- * page_table_lock
- */
- *ptep = new_pte;
+ new_pte |= (slot << 12) & _PAGE_F_GIX;
}
+ /*
+ * No need to use ldarx/stdcx here because all who
+ * might be updating the pte will hold the
+ * page_table_lock
+ */
+ *ptep = __pte(new_pte & ~_PAGE_BUSY);
+
err = 0;
out:
- spin_unlock(&mm->page_table_lock);
-
return err;
}
diff --git a/arch/ppc64/mm/imalloc.c b/arch/powerpc/mm/imalloc.c
index c65b87b92756..f4ca29cf5364 100644
--- a/arch/ppc64/mm/imalloc.c
+++ b/arch/powerpc/mm/imalloc.c
@@ -300,12 +300,7 @@ void im_free(void * addr)
for (p = &imlist ; (tmp = *p) ; p = &tmp->next) {
if (tmp->addr == addr) {
*p = tmp->next;
-
- /* XXX: do we need the lock? */
- spin_lock(&init_mm.page_table_lock);
unmap_vm_area(tmp);
- spin_unlock(&init_mm.page_table_lock);
-
kfree(tmp);
up(&imlist_sem);
return;
diff --git a/arch/powerpc/mm/init_32.c b/arch/powerpc/mm/init_32.c
new file mode 100644
index 000000000000..7d4b8b5f0606
--- /dev/null
+++ b/arch/powerpc/mm/init_32.c
@@ -0,0 +1,251 @@
+/*
+ * PowerPC version
+ * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
+ *
+ * Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au)
+ * and Cort Dougan (PReP) (cort@cs.nmt.edu)
+ * Copyright (C) 1996 Paul Mackerras
+ * Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk).
+ * PPC44x/36-bit changes by Matt Porter (mporter@mvista.com)
+ *
+ * Derived from "arch/i386/mm/init.c"
+ * Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds
+ *
+ * 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/config.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/stddef.h>
+#include <linux/init.h>
+#include <linux/bootmem.h>
+#include <linux/highmem.h>
+#include <linux/initrd.h>
+#include <linux/pagemap.h>
+
+#include <asm/pgalloc.h>
+#include <asm/prom.h>
+#include <asm/io.h>
+#include <asm/mmu_context.h>
+#include <asm/pgtable.h>
+#include <asm/mmu.h>
+#include <asm/smp.h>
+#include <asm/machdep.h>
+#include <asm/btext.h>
+#include <asm/tlb.h>
+#include <asm/prom.h>
+#include <asm/lmb.h>
+#include <asm/sections.h>
+
+#include "mmu_decl.h"
+
+#if defined(CONFIG_KERNEL_START_BOOL) || defined(CONFIG_LOWMEM_SIZE_BOOL)
+/* The ammount of lowmem must be within 0xF0000000 - KERNELBASE. */
+#if (CONFIG_LOWMEM_SIZE > (0xF0000000 - KERNELBASE))
+#error "You must adjust CONFIG_LOWMEM_SIZE or CONFIG_START_KERNEL"
+#endif
+#endif
+#define MAX_LOW_MEM CONFIG_LOWMEM_SIZE
+
+DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
+
+unsigned long total_memory;
+unsigned long total_lowmem;
+
+unsigned long ppc_memstart;
+unsigned long ppc_memoffset = PAGE_OFFSET;
+
+int boot_mapsize;
+#ifdef CONFIG_PPC_PMAC
+unsigned long agp_special_page;
+EXPORT_SYMBOL(agp_special_page);
+#endif
+
+#ifdef CONFIG_HIGHMEM
+pte_t *kmap_pte;
+pgprot_t kmap_prot;
+
+EXPORT_SYMBOL(kmap_prot);
+EXPORT_SYMBOL(kmap_pte);
+#endif
+
+void MMU_init(void);
+
+/* XXX should be in current.h -- paulus */
+extern struct task_struct *current_set[NR_CPUS];
+
+extern int init_bootmem_done;
+
+/*
+ * this tells the system to map all of ram with the segregs
+ * (i.e. page tables) instead of the bats.
+ * -- Cort
+ */
+int __map_without_bats;
+int __map_without_ltlbs;
+
+/* max amount of low RAM to map in */
+unsigned long __max_low_memory = MAX_LOW_MEM;
+
+/*
+ * limit of what is accessible with initial MMU setup -
+ * 256MB usually, but only 16MB on 601.
+ */
+unsigned long __initial_memory_limit = 0x10000000;
+
+/*
+ * Check for command-line options that affect what MMU_init will do.
+ */
+void MMU_setup(void)
+{
+ /* Check for nobats option (used in mapin_ram). */
+ if (strstr(cmd_line, "nobats")) {
+ __map_without_bats = 1;
+ }
+
+ if (strstr(cmd_line, "noltlbs")) {
+ __map_without_ltlbs = 1;
+ }
+}
+
+/*
+ * MMU_init sets up the basic memory mappings for the kernel,
+ * including both RAM and possibly some I/O regions,
+ * and sets up the page tables and the MMU hardware ready to go.
+ */
+void __init MMU_init(void)
+{
+ if (ppc_md.progress)
+ ppc_md.progress("MMU:enter", 0x111);
+
+ /* 601 can only access 16MB at the moment */
+ if (PVR_VER(mfspr(SPRN_PVR)) == 1)
+ __initial_memory_limit = 0x01000000;
+
+ /* parse args from command line */
+ MMU_setup();
+
+ if (lmb.memory.cnt > 1) {
+ lmb.memory.cnt = 1;
+ lmb_analyze();
+ printk(KERN_WARNING "Only using first contiguous memory region");
+ }
+
+ total_memory = lmb_end_of_DRAM();
+ total_lowmem = total_memory;
+
+#ifdef CONFIG_FSL_BOOKE
+ /* Freescale Book-E parts expect lowmem to be mapped by fixed TLB
+ * entries, so we need to adjust lowmem to match the amount we can map
+ * in the fixed entries */
+ adjust_total_lowmem();
+#endif /* CONFIG_FSL_BOOKE */
+
+ if (total_lowmem > __max_low_memory) {
+ total_lowmem = __max_low_memory;
+#ifndef CONFIG_HIGHMEM
+ total_memory = total_lowmem;
+ lmb_enforce_memory_limit(total_lowmem);
+ lmb_analyze();
+#endif /* CONFIG_HIGHMEM */
+ }
+
+ /* Initialize the MMU hardware */
+ if (ppc_md.progress)
+ ppc_md.progress("MMU:hw init", 0x300);
+ MMU_init_hw();
+
+ /* Map in all of RAM starting at KERNELBASE */
+ if (ppc_md.progress)
+ ppc_md.progress("MMU:mapin", 0x301);
+ mapin_ram();
+
+#ifdef CONFIG_HIGHMEM
+ ioremap_base = PKMAP_BASE;
+#else
+ ioremap_base = 0xfe000000UL; /* for now, could be 0xfffff000 */
+#endif /* CONFIG_HIGHMEM */
+ ioremap_bot = ioremap_base;
+
+ /* Map in I/O resources */
+ if (ppc_md.progress)
+ ppc_md.progress("MMU:setio", 0x302);
+ if (ppc_md.setup_io_mappings)
+ ppc_md.setup_io_mappings();
+
+ /* Initialize the context management stuff */
+ mmu_context_init();
+
+ if (ppc_md.progress)
+ ppc_md.progress("MMU:exit", 0x211);
+}
+
+/* This is only called until mem_init is done. */
+void __init *early_get_page(void)
+{
+ void *p;
+
+ if (init_bootmem_done) {
+ p = alloc_bootmem_pages(PAGE_SIZE);
+ } else {
+ p = __va(lmb_alloc_base(PAGE_SIZE, PAGE_SIZE,
+ __initial_memory_limit));
+ }
+ return p;
+}
+
+/* Free up now-unused memory */
+static void free_sec(unsigned long start, unsigned long end, const char *name)
+{
+ unsigned long cnt = 0;
+
+ while (start < end) {
+ ClearPageReserved(virt_to_page(start));
+ set_page_count(virt_to_page(start), 1);
+ free_page(start);
+ cnt++;
+ start += PAGE_SIZE;
+ }
+ if (cnt) {
+ printk(" %ldk %s", cnt << (PAGE_SHIFT - 10), name);
+ totalram_pages += cnt;
+ }
+}
+
+void free_initmem(void)
+{
+#define FREESEC(TYPE) \
+ free_sec((unsigned long)(&__ ## TYPE ## _begin), \
+ (unsigned long)(&__ ## TYPE ## _end), \
+ #TYPE);
+
+ printk ("Freeing unused kernel memory:");
+ FREESEC(init);
+ printk("\n");
+ ppc_md.progress = NULL;
+#undef FREESEC
+}
+
+#ifdef CONFIG_BLK_DEV_INITRD
+void free_initrd_mem(unsigned long start, unsigned long end)
+{
+ if (start < end)
+ printk ("Freeing initrd memory: %ldk freed\n", (end - start) >> 10);
+ for (; start < end; start += PAGE_SIZE) {
+ ClearPageReserved(virt_to_page(start));
+ set_page_count(virt_to_page(start), 1);
+ free_page(start);
+ totalram_pages++;
+ }
+}
+#endif
diff --git a/arch/powerpc/mm/init_64.c b/arch/powerpc/mm/init_64.c
new file mode 100644
index 000000000000..1134f70f231d
--- /dev/null
+++ b/arch/powerpc/mm/init_64.c
@@ -0,0 +1,234 @@
+/*
+ * PowerPC version
+ * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
+ *
+ * Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au)
+ * and Cort Dougan (PReP) (cort@cs.nmt.edu)
+ * Copyright (C) 1996 Paul Mackerras
+ * Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk).
+ *
+ * Derived from "arch/i386/mm/init.c"
+ * Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds
+ *
+ * Dave Engebretsen <engebret@us.ibm.com>
+ * Rework for PPC64 port.
+ *
+ * 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.
+ *
+ */
+
+#undef DEBUG
+
+#include <linux/config.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/mman.h>
+#include <linux/mm.h>
+#include <linux/swap.h>
+#include <linux/stddef.h>
+#include <linux/vmalloc.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/bootmem.h>
+#include <linux/highmem.h>
+#include <linux/idr.h>
+#include <linux/nodemask.h>
+#include <linux/module.h>
+
+#include <asm/pgalloc.h>
+#include <asm/page.h>
+#include <asm/prom.h>
+#include <asm/lmb.h>
+#include <asm/rtas.h>
+#include <asm/io.h>
+#include <asm/mmu_context.h>
+#include <asm/pgtable.h>
+#include <asm/mmu.h>
+#include <asm/uaccess.h>
+#include <asm/smp.h>
+#include <asm/machdep.h>
+#include <asm/tlb.h>
+#include <asm/eeh.h>
+#include <asm/processor.h>
+#include <asm/mmzone.h>
+#include <asm/cputable.h>
+#include <asm/sections.h>
+#include <asm/system.h>
+#include <asm/iommu.h>
+#include <asm/abs_addr.h>
+#include <asm/vdso.h>
+#include <asm/imalloc.h>
+
+#ifdef DEBUG
+#define DBG(fmt...) printk(fmt)
+#else
+#define DBG(fmt...)
+#endif
+
+#if PGTABLE_RANGE > USER_VSID_RANGE
+#warning Limited user VSID range means pagetable space is wasted
+#endif
+
+#if (TASK_SIZE_USER64 < PGTABLE_RANGE) && (TASK_SIZE_USER64 < USER_VSID_RANGE)
+#warning TASK_SIZE is smaller than it needs to be.
+#endif
+
+/* max amount of RAM to use */
+unsigned long __max_memory;
+
+/* info on what we think the IO hole is */
+unsigned long io_hole_start;
+unsigned long io_hole_size;
+
+/*
+ * Do very early mm setup.
+ */
+void __init mm_init_ppc64(void)
+{
+#ifndef CONFIG_PPC_ISERIES
+ unsigned long i;
+#endif
+
+ ppc64_boot_msg(0x100, "MM Init");
+
+ /* This is the story of the IO hole... please, keep seated,
+ * unfortunately, we are out of oxygen masks at the moment.
+ * So we need some rough way to tell where your big IO hole
+ * is. On pmac, it's between 2G and 4G, on POWER3, it's around
+ * that area as well, on POWER4 we don't have one, etc...
+ * We need that as a "hint" when sizing the TCE table on POWER3
+ * So far, the simplest way that seem work well enough for us it
+ * to just assume that the first discontinuity in our physical
+ * RAM layout is the IO hole. That may not be correct in the future
+ * (and isn't on iSeries but then we don't care ;)
+ */
+
+#ifndef CONFIG_PPC_ISERIES
+ for (i = 1; i < lmb.memory.cnt; i++) {
+ unsigned long base, prevbase, prevsize;
+
+ prevbase = lmb.memory.region[i-1].base;
+ prevsize = lmb.memory.region[i-1].size;
+ base = lmb.memory.region[i].base;
+ if (base > (prevbase + prevsize)) {
+ io_hole_start = prevbase + prevsize;
+ io_hole_size = base - (prevbase + prevsize);
+ break;
+ }
+ }
+#endif /* CONFIG_PPC_ISERIES */
+ if (io_hole_start)
+ printk("IO Hole assumed to be %lx -> %lx\n",
+ io_hole_start, io_hole_start + io_hole_size - 1);
+
+ ppc64_boot_msg(0x100, "MM Init Done");
+}
+
+void free_initmem(void)
+{
+ unsigned long addr;
+
+ addr = (unsigned long)__init_begin;
+ for (; addr < (unsigned long)__init_end; addr += PAGE_SIZE) {
+ memset((void *)addr, 0xcc, PAGE_SIZE);
+ ClearPageReserved(virt_to_page(addr));
+ set_page_count(virt_to_page(addr), 1);
+ free_page(addr);
+ totalram_pages++;
+ }
+ printk ("Freeing unused kernel memory: %luk freed\n",
+ ((unsigned long)__init_end - (unsigned long)__init_begin) >> 10);
+}
+
+#ifdef CONFIG_BLK_DEV_INITRD
+void free_initrd_mem(unsigned long start, unsigned long end)
+{
+ if (start < end)
+ printk ("Freeing initrd memory: %ldk freed\n", (end - start) >> 10);
+ for (; start < end; start += PAGE_SIZE) {
+ ClearPageReserved(virt_to_page(start));
+ set_page_count(virt_to_page(start), 1);
+ free_page(start);
+ totalram_pages++;
+ }
+}
+#endif
+
+static struct kcore_list kcore_vmem;
+
+static int __init setup_kcore(void)
+{
+ int i;
+
+ for (i=0; i < lmb.memory.cnt; i++) {
+ unsigned long base, size;
+ struct kcore_list *kcore_mem;
+
+ base = lmb.memory.region[i].base;
+ size = lmb.memory.region[i].size;
+
+ /* GFP_ATOMIC to avoid might_sleep warnings during boot */
+ kcore_mem = kmalloc(sizeof(struct kcore_list), GFP_ATOMIC);
+ if (!kcore_mem)
+ panic("mem_init: kmalloc failed\n");
+
+ kclist_add(kcore_mem, __va(base), size);
+ }
+
+ kclist_add(&kcore_vmem, (void *)VMALLOC_START, VMALLOC_END-VMALLOC_START);
+
+ return 0;
+}
+module_init(setup_kcore);
+
+static void zero_ctor(void *addr, kmem_cache_t *cache, unsigned long flags)
+{
+ memset(addr, 0, kmem_cache_size(cache));
+}
+
+#ifdef CONFIG_PPC_64K_PAGES
+static const unsigned int pgtable_cache_size[3] = {
+ PTE_TABLE_SIZE, PMD_TABLE_SIZE, PGD_TABLE_SIZE
+};
+static const char *pgtable_cache_name[ARRAY_SIZE(pgtable_cache_size)] = {
+ "pte_pmd_cache", "pmd_cache", "pgd_cache",
+};
+#else
+static const unsigned int pgtable_cache_size[2] = {
+ PTE_TABLE_SIZE, PMD_TABLE_SIZE
+};
+static const char *pgtable_cache_name[ARRAY_SIZE(pgtable_cache_size)] = {
+ "pgd_pte_cache", "pud_pmd_cache",
+};
+#endif /* CONFIG_PPC_64K_PAGES */
+
+kmem_cache_t *pgtable_cache[ARRAY_SIZE(pgtable_cache_size)];
+
+void pgtable_cache_init(void)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(pgtable_cache_size); i++) {
+ int size = pgtable_cache_size[i];
+ const char *name = pgtable_cache_name[i];
+
+ DBG("Allocating page table cache %s (#%d) "
+ "for size: %08x...\n", name, i, size);
+ pgtable_cache[i] = kmem_cache_create(name,
+ size, size,
+ SLAB_HWCACHE_ALIGN |
+ SLAB_MUST_HWCACHE_ALIGN,
+ zero_ctor,
+ NULL);
+ if (! pgtable_cache[i])
+ panic("pgtable_cache_init(): could not create %s!\n",
+ name);
+ }
+}
diff --git a/arch/ppc64/kernel/lmb.c b/arch/powerpc/mm/lmb.c
index 5adaca2ddc9d..9b5aa6808eb8 100644
--- a/arch/ppc64/kernel/lmb.c
+++ b/arch/powerpc/mm/lmb.c
@@ -1,5 +1,5 @@
/*
- * Procedures for interfacing to Open Firmware.
+ * Procedures for maintaining information about logical memory blocks.
*
* Peter Bergner, IBM Corp. June 2001.
* Copyright (C) 2001 Peter Bergner.
@@ -18,7 +18,9 @@
#include <asm/page.h>
#include <asm/prom.h>
#include <asm/lmb.h>
-#include <asm/abs_addr.h>
+#ifdef CONFIG_PPC32
+#include "mmu_decl.h" /* for __max_low_memory */
+#endif
struct lmb lmb;
@@ -54,16 +56,14 @@ void lmb_dump_all(void)
#endif /* DEBUG */
}
-static unsigned long __init
-lmb_addrs_overlap(unsigned long base1, unsigned long size1,
- unsigned long base2, unsigned long size2)
+static unsigned long __init lmb_addrs_overlap(unsigned long base1,
+ unsigned long size1, unsigned long base2, unsigned long size2)
{
return ((base1 < (base2+size2)) && (base2 < (base1+size1)));
}
-static long __init
-lmb_addrs_adjacent(unsigned long base1, unsigned long size1,
- unsigned long base2, unsigned long size2)
+static long __init lmb_addrs_adjacent(unsigned long base1, unsigned long size1,
+ unsigned long base2, unsigned long size2)
{
if (base2 == base1 + size1)
return 1;
@@ -73,8 +73,8 @@ lmb_addrs_adjacent(unsigned long base1, unsigned long size1,
return 0;
}
-static long __init
-lmb_regions_adjacent(struct lmb_region *rgn, unsigned long r1, unsigned long r2)
+static long __init lmb_regions_adjacent(struct lmb_region *rgn,
+ unsigned long r1, unsigned long r2)
{
unsigned long base1 = rgn->region[r1].base;
unsigned long size1 = rgn->region[r1].size;
@@ -85,8 +85,8 @@ lmb_regions_adjacent(struct lmb_region *rgn, unsigned long r1, unsigned long r2)
}
/* Assumption: base addr of region 1 < base addr of region 2 */
-static void __init
-lmb_coalesce_regions(struct lmb_region *rgn, unsigned long r1, unsigned long r2)
+static void __init lmb_coalesce_regions(struct lmb_region *rgn,
+ unsigned long r1, unsigned long r2)
{
unsigned long i;
@@ -99,8 +99,7 @@ lmb_coalesce_regions(struct lmb_region *rgn, unsigned long r1, unsigned long r2)
}
/* This routine called with relocation disabled. */
-void __init
-lmb_init(void)
+void __init lmb_init(void)
{
/* Create a dummy zero size LMB which will get coalesced away later.
* This simplifies the lmb_add() code below...
@@ -115,9 +114,8 @@ lmb_init(void)
lmb.reserved.cnt = 1;
}
-/* This routine called with relocation disabled. */
-void __init
-lmb_analyze(void)
+/* This routine may be called with relocation disabled. */
+void __init lmb_analyze(void)
{
int i;
@@ -128,8 +126,8 @@ lmb_analyze(void)
}
/* This routine called with relocation disabled. */
-static long __init
-lmb_add_region(struct lmb_region *rgn, unsigned long base, unsigned long size)
+static long __init lmb_add_region(struct lmb_region *rgn, unsigned long base,
+ unsigned long size)
{
unsigned long i, coalesced = 0;
long adjacent;
@@ -158,18 +156,17 @@ lmb_add_region(struct lmb_region *rgn, unsigned long base, unsigned long size)
coalesced++;
}
- if ( coalesced ) {
+ if (coalesced)
return coalesced;
- } else if ( rgn->cnt >= MAX_LMB_REGIONS ) {
+ if (rgn->cnt >= MAX_LMB_REGIONS)
return -1;
- }
/* Couldn't coalesce the LMB, so add it to the sorted table. */
- for (i=rgn->cnt-1; i >= 0; i--) {
+ for (i = rgn->cnt-1; i >= 0; i--) {
if (base < rgn->region[i].base) {
rgn->region[i+1].base = rgn->region[i].base;
rgn->region[i+1].size = rgn->region[i].size;
- } else {
+ } else {
rgn->region[i+1].base = base;
rgn->region[i+1].size = size;
break;
@@ -180,30 +177,28 @@ lmb_add_region(struct lmb_region *rgn, unsigned long base, unsigned long size)
return 0;
}
-/* This routine called with relocation disabled. */
-long __init
-lmb_add(unsigned long base, unsigned long size)
+/* This routine may be called with relocation disabled. */
+long __init lmb_add(unsigned long base, unsigned long size)
{
struct lmb_region *_rgn = &(lmb.memory);
/* On pSeries LPAR systems, the first LMB is our RMO region. */
- if ( base == 0 )
+ if (base == 0)
lmb.rmo_size = size;
return lmb_add_region(_rgn, base, size);
}
-long __init
-lmb_reserve(unsigned long base, unsigned long size)
+long __init lmb_reserve(unsigned long base, unsigned long size)
{
struct lmb_region *_rgn = &(lmb.reserved);
return lmb_add_region(_rgn, base, size);
}
-long __init
-lmb_overlaps_region(struct lmb_region *rgn, unsigned long base, unsigned long size)
+long __init lmb_overlaps_region(struct lmb_region *rgn, unsigned long base,
+ unsigned long size)
{
unsigned long i;
@@ -218,39 +213,44 @@ lmb_overlaps_region(struct lmb_region *rgn, unsigned long base, unsigned long si
return (i < rgn->cnt) ? i : -1;
}
-unsigned long __init
-lmb_alloc(unsigned long size, unsigned long align)
+unsigned long __init lmb_alloc(unsigned long size, unsigned long align)
{
return lmb_alloc_base(size, align, LMB_ALLOC_ANYWHERE);
}
-unsigned long __init
-lmb_alloc_base(unsigned long size, unsigned long align, unsigned long max_addr)
+unsigned long __init lmb_alloc_base(unsigned long size, unsigned long align,
+ unsigned long max_addr)
{
long i, j;
unsigned long base = 0;
- for (i=lmb.memory.cnt-1; i >= 0; i--) {
+#ifdef CONFIG_PPC32
+ /* On 32-bit, make sure we allocate lowmem */
+ if (max_addr == LMB_ALLOC_ANYWHERE)
+ max_addr = __max_low_memory;
+#endif
+ for (i = lmb.memory.cnt-1; i >= 0; i--) {
unsigned long lmbbase = lmb.memory.region[i].base;
unsigned long lmbsize = lmb.memory.region[i].size;
- if ( max_addr == LMB_ALLOC_ANYWHERE )
- base = _ALIGN_DOWN(lmbbase+lmbsize-size, align);
- else if ( lmbbase < max_addr )
- base = _ALIGN_DOWN(min(lmbbase+lmbsize,max_addr)-size, align);
- else
+ if (max_addr == LMB_ALLOC_ANYWHERE)
+ base = _ALIGN_DOWN(lmbbase + lmbsize - size, align);
+ else if (lmbbase < max_addr) {
+ base = min(lmbbase + lmbsize, max_addr);
+ base = _ALIGN_DOWN(base - size, align);
+ } else
continue;
- while ( (lmbbase <= base) &&
- ((j = lmb_overlaps_region(&lmb.reserved,base,size)) >= 0) ) {
- base = _ALIGN_DOWN(lmb.reserved.region[j].base-size, align);
- }
+ while ((lmbbase <= base) &&
+ ((j = lmb_overlaps_region(&lmb.reserved, base, size)) >= 0) )
+ base = _ALIGN_DOWN(lmb.reserved.region[j].base - size,
+ align);
- if ( (base != 0) && (lmbbase <= base) )
+ if ((base != 0) && (lmbbase <= base))
break;
}
- if ( i < 0 )
+ if (i < 0)
return 0;
lmb_add_region(&lmb.reserved, base, size);
@@ -259,14 +259,12 @@ lmb_alloc_base(unsigned long size, unsigned long align, unsigned long max_addr)
}
/* You must call lmb_analyze() before this. */
-unsigned long __init
-lmb_phys_mem_size(void)
+unsigned long __init lmb_phys_mem_size(void)
{
return lmb.memory.size;
}
-unsigned long __init
-lmb_end_of_DRAM(void)
+unsigned long __init lmb_end_of_DRAM(void)
{
int idx = lmb.memory.cnt - 1;
@@ -277,9 +275,8 @@ lmb_end_of_DRAM(void)
* Truncate the lmb list to memory_limit if it's set
* You must call lmb_analyze() after this.
*/
-void __init lmb_enforce_memory_limit(void)
+void __init lmb_enforce_memory_limit(unsigned long memory_limit)
{
- extern unsigned long memory_limit;
unsigned long i, limit;
if (! memory_limit)
diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c
new file mode 100644
index 000000000000..1dd3cc69a490
--- /dev/null
+++ b/arch/powerpc/mm/mem.c
@@ -0,0 +1,554 @@
+/*
+ * PowerPC version
+ * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
+ *
+ * Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au)
+ * and Cort Dougan (PReP) (cort@cs.nmt.edu)
+ * Copyright (C) 1996 Paul Mackerras
+ * Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk).
+ * PPC44x/36-bit changes by Matt Porter (mporter@mvista.com)
+ *
+ * Derived from "arch/i386/mm/init.c"
+ * Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds
+ *
+ * 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/config.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/stddef.h>
+#include <linux/init.h>
+#include <linux/bootmem.h>
+#include <linux/highmem.h>
+#include <linux/initrd.h>
+#include <linux/pagemap.h>
+
+#include <asm/pgalloc.h>
+#include <asm/prom.h>
+#include <asm/io.h>
+#include <asm/mmu_context.h>
+#include <asm/pgtable.h>
+#include <asm/mmu.h>
+#include <asm/smp.h>
+#include <asm/machdep.h>
+#include <asm/btext.h>
+#include <asm/tlb.h>
+#include <asm/prom.h>
+#include <asm/lmb.h>
+#include <asm/sections.h>
+#ifdef CONFIG_PPC64
+#include <asm/vdso.h>
+#endif
+
+#include "mmu_decl.h"
+
+#ifndef CPU_FTR_COHERENT_ICACHE
+#define CPU_FTR_COHERENT_ICACHE 0 /* XXX for now */
+#define CPU_FTR_NOEXECUTE 0
+#endif
+
+int init_bootmem_done;
+int mem_init_done;
+unsigned long memory_limit;
+
+extern void hash_preload(struct mm_struct *mm, unsigned long ea,
+ unsigned long access, unsigned long trap);
+
+/*
+ * This is called by /dev/mem to know if a given address has to
+ * be mapped non-cacheable or not
+ */
+int page_is_ram(unsigned long pfn)
+{
+ unsigned long paddr = (pfn << PAGE_SHIFT);
+
+#ifndef CONFIG_PPC64 /* XXX for now */
+ return paddr < __pa(high_memory);
+#else
+ int i;
+ for (i=0; i < lmb.memory.cnt; i++) {
+ unsigned long base;
+
+ base = lmb.memory.region[i].base;
+
+ if ((paddr >= base) &&
+ (paddr < (base + lmb.memory.region[i].size))) {
+ return 1;
+ }
+ }
+
+ return 0;
+#endif
+}
+EXPORT_SYMBOL(page_is_ram);
+
+pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
+ unsigned long size, pgprot_t vma_prot)
+{
+ if (ppc_md.phys_mem_access_prot)
+ return ppc_md.phys_mem_access_prot(file, pfn, size, vma_prot);
+
+ if (!page_is_ram(pfn))
+ vma_prot = __pgprot(pgprot_val(vma_prot)
+ | _PAGE_GUARDED | _PAGE_NO_CACHE);
+ return vma_prot;
+}
+EXPORT_SYMBOL(phys_mem_access_prot);
+
+#ifdef CONFIG_MEMORY_HOTPLUG
+
+void online_page(struct page *page)
+{
+ ClearPageReserved(page);
+ set_page_count(page, 0);
+ free_cold_page(page);
+ totalram_pages++;
+ num_physpages++;
+}
+
+/*
+ * This works only for the non-NUMA case. Later, we'll need a lookup
+ * to convert from real physical addresses to nid, that doesn't use
+ * pfn_to_nid().
+ */
+int __devinit add_memory(u64 start, u64 size)
+{
+ struct pglist_data *pgdata = NODE_DATA(0);
+ struct zone *zone;
+ unsigned long start_pfn = start >> PAGE_SHIFT;
+ unsigned long nr_pages = size >> PAGE_SHIFT;
+
+ start += KERNELBASE;
+ create_section_mapping(start, start + size);
+
+ /* this should work for most non-highmem platforms */
+ zone = pgdata->node_zones;
+
+ return __add_pages(zone, start_pfn, nr_pages);
+
+ return 0;
+}
+
+/*
+ * First pass at this code will check to determine if the remove
+ * request is within the RMO. Do not allow removal within the RMO.
+ */
+int __devinit remove_memory(u64 start, u64 size)
+{
+ struct zone *zone;
+ unsigned long start_pfn, end_pfn, nr_pages;
+
+ start_pfn = start >> PAGE_SHIFT;
+ nr_pages = size >> PAGE_SHIFT;
+ end_pfn = start_pfn + nr_pages;
+
+ printk("%s(): Attempting to remove memoy in range "
+ "%lx to %lx\n", __func__, start, start+size);
+ /*
+ * check for range within RMO
+ */
+ zone = page_zone(pfn_to_page(start_pfn));
+
+ printk("%s(): memory will be removed from "
+ "the %s zone\n", __func__, zone->name);
+
+ /*
+ * not handling removing memory ranges that
+ * overlap multiple zones yet
+ */
+ if (end_pfn > (zone->zone_start_pfn + zone->spanned_pages))
+ goto overlap;
+
+ /* make sure it is NOT in RMO */
+ if ((start < lmb.rmo_size) || ((start+size) < lmb.rmo_size)) {
+ printk("%s(): range to be removed must NOT be in RMO!\n",
+ __func__);
+ goto in_rmo;
+ }
+
+ return __remove_pages(zone, start_pfn, nr_pages);
+
+overlap:
+ printk("%s(): memory range to be removed overlaps "
+ "multiple zones!!!\n", __func__);
+in_rmo:
+ return -1;
+}
+#endif /* CONFIG_MEMORY_HOTPLUG */
+
+void show_mem(void)
+{
+ unsigned long total = 0, reserved = 0;
+ unsigned long shared = 0, cached = 0;
+ unsigned long highmem = 0;
+ struct page *page;
+ pg_data_t *pgdat;
+ unsigned long i;
+
+ printk("Mem-info:\n");
+ show_free_areas();
+ printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10));
+ for_each_pgdat(pgdat) {
+ unsigned long flags;
+ pgdat_resize_lock(pgdat, &flags);
+ for (i = 0; i < pgdat->node_spanned_pages; i++) {
+ page = pgdat_page_nr(pgdat, i);
+ total++;
+ if (PageHighMem(page))
+ highmem++;
+ if (PageReserved(page))
+ reserved++;
+ else if (PageSwapCache(page))
+ cached++;
+ else if (page_count(page))
+ shared += page_count(page) - 1;
+ }
+ pgdat_resize_unlock(pgdat, &flags);
+ }
+ printk("%ld pages of RAM\n", total);
+#ifdef CONFIG_HIGHMEM
+ printk("%ld pages of HIGHMEM\n", highmem);
+#endif
+ printk("%ld reserved pages\n", reserved);
+ printk("%ld pages shared\n", shared);
+ printk("%ld pages swap cached\n", cached);
+}
+
+/*
+ * Initialize the bootmem system and give it all the memory we
+ * have available. If we are using highmem, we only put the
+ * lowmem into the bootmem system.
+ */
+#ifndef CONFIG_NEED_MULTIPLE_NODES
+void __init do_init_bootmem(void)
+{
+ unsigned long i;
+ unsigned long start, bootmap_pages;
+ unsigned long total_pages;
+ int boot_mapsize;
+
+ max_pfn = total_pages = lmb_end_of_DRAM() >> PAGE_SHIFT;
+#ifdef CONFIG_HIGHMEM
+ total_pages = total_lowmem >> PAGE_SHIFT;
+#endif
+
+ /*
+ * Find an area to use for the bootmem bitmap. Calculate the size of
+ * bitmap required as (Total Memory) / PAGE_SIZE / BITS_PER_BYTE.
+ * Add 1 additional page in case the address isn't page-aligned.
+ */
+ bootmap_pages = bootmem_bootmap_pages(total_pages);
+
+ start = lmb_alloc(bootmap_pages << PAGE_SHIFT, PAGE_SIZE);
+ BUG_ON(!start);
+
+ boot_mapsize = init_bootmem(start >> PAGE_SHIFT, total_pages);
+
+ /* Add all physical memory to the bootmem map, mark each area
+ * present.
+ */
+ for (i = 0; i < lmb.memory.cnt; i++) {
+ unsigned long base = lmb.memory.region[i].base;
+ unsigned long size = lmb_size_bytes(&lmb.memory, i);
+#ifdef CONFIG_HIGHMEM
+ if (base >= total_lowmem)
+ continue;
+ if (base + size > total_lowmem)
+ size = total_lowmem - base;
+#endif
+ free_bootmem(base, size);
+ }
+
+ /* reserve the sections we're already using */
+ for (i = 0; i < lmb.reserved.cnt; i++)
+ reserve_bootmem(lmb.reserved.region[i].base,
+ lmb_size_bytes(&lmb.reserved, i));
+
+ /* XXX need to clip this if using highmem? */
+ for (i = 0; i < lmb.memory.cnt; i++)
+ memory_present(0, lmb_start_pfn(&lmb.memory, i),
+ lmb_end_pfn(&lmb.memory, i));
+ init_bootmem_done = 1;
+}
+
+/*
+ * paging_init() sets up the page tables - in fact we've already done this.
+ */
+void __init paging_init(void)
+{
+ unsigned long zones_size[MAX_NR_ZONES];
+ unsigned long zholes_size[MAX_NR_ZONES];
+ unsigned long total_ram = lmb_phys_mem_size();
+ unsigned long top_of_ram = lmb_end_of_DRAM();
+
+#ifdef CONFIG_HIGHMEM
+ map_page(PKMAP_BASE, 0, 0); /* XXX gross */
+ pkmap_page_table = pte_offset_kernel(pmd_offset(pgd_offset_k
+ (PKMAP_BASE), PKMAP_BASE), PKMAP_BASE);
+ map_page(KMAP_FIX_BEGIN, 0, 0); /* XXX gross */
+ kmap_pte = pte_offset_kernel(pmd_offset(pgd_offset_k
+ (KMAP_FIX_BEGIN), KMAP_FIX_BEGIN), KMAP_FIX_BEGIN);
+ kmap_prot = PAGE_KERNEL;
+#endif /* CONFIG_HIGHMEM */
+
+ printk(KERN_INFO "Top of RAM: 0x%lx, Total RAM: 0x%lx\n",
+ top_of_ram, total_ram);
+ printk(KERN_INFO "Memory hole size: %ldMB\n",
+ (top_of_ram - total_ram) >> 20);
+ /*
+ * All pages are DMA-able so we put them all in the DMA zone.
+ */
+ memset(zones_size, 0, sizeof(zones_size));
+ memset(zholes_size, 0, sizeof(zholes_size));
+
+ zones_size[ZONE_DMA] = top_of_ram >> PAGE_SHIFT;
+ zholes_size[ZONE_DMA] = (top_of_ram - total_ram) >> PAGE_SHIFT;
+
+#ifdef CONFIG_HIGHMEM
+ zones_size[ZONE_DMA] = total_lowmem >> PAGE_SHIFT;
+ zones_size[ZONE_HIGHMEM] = (total_memory - total_lowmem) >> PAGE_SHIFT;
+ zholes_size[ZONE_HIGHMEM] = (top_of_ram - total_ram) >> PAGE_SHIFT;
+#else
+ zones_size[ZONE_DMA] = top_of_ram >> PAGE_SHIFT;
+ zholes_size[ZONE_DMA] = (top_of_ram - total_ram) >> PAGE_SHIFT;
+#endif /* CONFIG_HIGHMEM */
+
+ free_area_init_node(0, NODE_DATA(0), zones_size,
+ __pa(PAGE_OFFSET) >> PAGE_SHIFT, zholes_size);
+}
+#endif /* ! CONFIG_NEED_MULTIPLE_NODES */
+
+void __init mem_init(void)
+{
+#ifdef CONFIG_NEED_MULTIPLE_NODES
+ int nid;
+#endif
+ pg_data_t *pgdat;
+ unsigned long i;
+ struct page *page;
+ unsigned long reservedpages = 0, codesize, initsize, datasize, bsssize;
+
+ num_physpages = max_pfn; /* RAM is assumed contiguous */
+ high_memory = (void *) __va(max_low_pfn * PAGE_SIZE);
+
+#ifdef CONFIG_NEED_MULTIPLE_NODES
+ for_each_online_node(nid) {
+ if (NODE_DATA(nid)->node_spanned_pages != 0) {
+ printk("freeing bootmem node %x\n", nid);
+ totalram_pages +=
+ free_all_bootmem_node(NODE_DATA(nid));
+ }
+ }
+#else
+ max_mapnr = num_physpages;
+ totalram_pages += free_all_bootmem();
+#endif
+ for_each_pgdat(pgdat) {
+ for (i = 0; i < pgdat->node_spanned_pages; i++) {
+ page = pgdat_page_nr(pgdat, i);
+ if (PageReserved(page))
+ reservedpages++;
+ }
+ }
+
+ codesize = (unsigned long)&_sdata - (unsigned long)&_stext;
+ datasize = (unsigned long)&_edata - (unsigned long)&_sdata;
+ initsize = (unsigned long)&__init_end - (unsigned long)&__init_begin;
+ bsssize = (unsigned long)&__bss_stop - (unsigned long)&__bss_start;
+
+#ifdef CONFIG_HIGHMEM
+ {
+ unsigned long pfn, highmem_mapnr;
+
+ highmem_mapnr = total_lowmem >> PAGE_SHIFT;
+ for (pfn = highmem_mapnr; pfn < max_mapnr; ++pfn) {
+ struct page *page = pfn_to_page(pfn);
+
+ ClearPageReserved(page);
+ set_page_count(page, 1);
+ __free_page(page);
+ totalhigh_pages++;
+ }
+ totalram_pages += totalhigh_pages;
+ printk(KERN_INFO "High memory: %luk\n",
+ totalhigh_pages << (PAGE_SHIFT-10));
+ }
+#endif /* CONFIG_HIGHMEM */
+
+ printk(KERN_INFO "Memory: %luk/%luk available (%luk kernel code, "
+ "%luk reserved, %luk data, %luk bss, %luk init)\n",
+ (unsigned long)nr_free_pages() << (PAGE_SHIFT-10),
+ num_physpages << (PAGE_SHIFT-10),
+ codesize >> 10,
+ reservedpages << (PAGE_SHIFT-10),
+ datasize >> 10,
+ bsssize >> 10,
+ initsize >> 10);
+
+ mem_init_done = 1;
+
+#ifdef CONFIG_PPC64
+ /* Initialize the vDSO */
+ vdso_init();
+#endif
+}
+
+/*
+ * This is called when a page has been modified by the kernel.
+ * It just marks the page as not i-cache clean. We do the i-cache
+ * flush later when the page is given to a user process, if necessary.
+ */
+void flush_dcache_page(struct page *page)
+{
+ if (cpu_has_feature(CPU_FTR_COHERENT_ICACHE))
+ return;
+ /* avoid an atomic op if possible */
+ if (test_bit(PG_arch_1, &page->flags))
+ clear_bit(PG_arch_1, &page->flags);
+}
+EXPORT_SYMBOL(flush_dcache_page);
+
+void flush_dcache_icache_page(struct page *page)
+{
+#ifdef CONFIG_BOOKE
+ void *start = kmap_atomic(page, KM_PPC_SYNC_ICACHE);
+ __flush_dcache_icache(start);
+ kunmap_atomic(start, KM_PPC_SYNC_ICACHE);
+#elif defined(CONFIG_8xx) || defined(CONFIG_PPC64)
+ /* On 8xx there is no need to kmap since highmem is not supported */
+ __flush_dcache_icache(page_address(page));
+#else
+ __flush_dcache_icache_phys(page_to_pfn(page) << PAGE_SHIFT);
+#endif
+
+}
+void clear_user_page(void *page, unsigned long vaddr, struct page *pg)
+{
+ clear_page(page);
+
+ if (cpu_has_feature(CPU_FTR_COHERENT_ICACHE))
+ return;
+ /*
+ * We shouldnt have to do this, but some versions of glibc
+ * require it (ld.so assumes zero filled pages are icache clean)
+ * - Anton
+ */
+
+ /* avoid an atomic op if possible */
+ if (test_bit(PG_arch_1, &pg->flags))
+ clear_bit(PG_arch_1, &pg->flags);
+}
+EXPORT_SYMBOL(clear_user_page);
+
+void copy_user_page(void *vto, void *vfrom, unsigned long vaddr,
+ struct page *pg)
+{
+ copy_page(vto, vfrom);
+
+ /*
+ * We should be able to use the following optimisation, however
+ * there are two problems.
+ * Firstly a bug in some versions of binutils meant PLT sections
+ * were not marked executable.
+ * Secondly the first word in the GOT section is blrl, used
+ * to establish the GOT address. Until recently the GOT was
+ * not marked executable.
+ * - Anton
+ */
+#if 0
+ if (!vma->vm_file && ((vma->vm_flags & VM_EXEC) == 0))
+ return;
+#endif
+
+ if (cpu_has_feature(CPU_FTR_COHERENT_ICACHE))
+ return;
+
+ /* avoid an atomic op if possible */
+ if (test_bit(PG_arch_1, &pg->flags))
+ clear_bit(PG_arch_1, &pg->flags);
+}
+
+void flush_icache_user_range(struct vm_area_struct *vma, struct page *page,
+ unsigned long addr, int len)
+{
+ unsigned long maddr;
+
+ maddr = (unsigned long) kmap(page) + (addr & ~PAGE_MASK);
+ flush_icache_range(maddr, maddr + len);
+ kunmap(page);
+}
+EXPORT_SYMBOL(flush_icache_user_range);
+
+/*
+ * This is called at the end of handling a user page fault, when the
+ * fault has been handled by updating a PTE in the linux page tables.
+ * We use it to preload an HPTE into the hash table corresponding to
+ * the updated linux PTE.
+ *
+ * This must always be called with the mm->page_table_lock held
+ */
+void update_mmu_cache(struct vm_area_struct *vma, unsigned long address,
+ pte_t pte)
+{
+#ifdef CONFIG_PPC_STD_MMU
+ unsigned long access = 0, trap;
+#endif
+ unsigned long pfn = pte_pfn(pte);
+
+ /* handle i-cache coherency */
+ if (!cpu_has_feature(CPU_FTR_COHERENT_ICACHE) &&
+ !cpu_has_feature(CPU_FTR_NOEXECUTE) &&
+ pfn_valid(pfn)) {
+ struct page *page = pfn_to_page(pfn);
+ if (!PageReserved(page)
+ && !test_bit(PG_arch_1, &page->flags)) {
+ if (vma->vm_mm == current->active_mm) {
+#ifdef CONFIG_8xx
+ /* On 8xx, cache control instructions (particularly
+ * "dcbst" from flush_dcache_icache) fault as write
+ * operation if there is an unpopulated TLB entry
+ * for the address in question. To workaround that,
+ * we invalidate the TLB here, thus avoiding dcbst
+ * misbehaviour.
+ */
+ _tlbie(address);
+#endif
+ __flush_dcache_icache((void *) address);
+ } else
+ flush_dcache_icache_page(page);
+ set_bit(PG_arch_1, &page->flags);
+ }
+ }
+
+#ifdef CONFIG_PPC_STD_MMU
+ /* We only want HPTEs for linux PTEs that have _PAGE_ACCESSED set */
+ if (!pte_young(pte) || address >= TASK_SIZE)
+ return;
+
+ /* We try to figure out if we are coming from an instruction
+ * access fault and pass that down to __hash_page so we avoid
+ * double-faulting on execution of fresh text. We have to test
+ * for regs NULL since init will get here first thing at boot
+ *
+ * We also avoid filling the hash if not coming from a fault
+ */
+ if (current->thread.regs == NULL)
+ return;
+ trap = TRAP(current->thread.regs);
+ if (trap == 0x400)
+ access |= _PAGE_EXEC;
+ else if (trap != 0x300)
+ return;
+ hash_preload(vma->vm_mm, address, access, trap);
+#endif /* CONFIG_PPC_STD_MMU */
+}
diff --git a/arch/ppc64/mm/mmap.c b/arch/powerpc/mm/mmap.c
index fe65f522aff3..fe65f522aff3 100644
--- a/arch/ppc64/mm/mmap.c
+++ b/arch/powerpc/mm/mmap.c
diff --git a/arch/powerpc/mm/mmu_context_32.c b/arch/powerpc/mm/mmu_context_32.c
new file mode 100644
index 000000000000..a8816e0f6a86
--- /dev/null
+++ b/arch/powerpc/mm/mmu_context_32.c
@@ -0,0 +1,86 @@
+/*
+ * This file contains the routines for handling the MMU on those
+ * PowerPC implementations where the MMU substantially follows the
+ * architecture specification. This includes the 6xx, 7xx, 7xxx,
+ * 8260, and POWER3 implementations but excludes the 8xx and 4xx.
+ * -- paulus
+ *
+ * Derived from arch/ppc/mm/init.c:
+ * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
+ *
+ * Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au)
+ * and Cort Dougan (PReP) (cort@cs.nmt.edu)
+ * Copyright (C) 1996 Paul Mackerras
+ * Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk).
+ *
+ * Derived from "arch/i386/mm/init.c"
+ * Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds
+ *
+ * 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/config.h>
+#include <linux/mm.h>
+#include <linux/init.h>
+
+#include <asm/mmu_context.h>
+#include <asm/tlbflush.h>
+
+mm_context_t next_mmu_context;
+unsigned long context_map[LAST_CONTEXT / BITS_PER_LONG + 1];
+#ifdef FEW_CONTEXTS
+atomic_t nr_free_contexts;
+struct mm_struct *context_mm[LAST_CONTEXT+1];
+void steal_context(void);
+#endif /* FEW_CONTEXTS */
+
+/*
+ * Initialize the context management stuff.
+ */
+void __init
+mmu_context_init(void)
+{
+ /*
+ * Some processors have too few contexts to reserve one for
+ * init_mm, and require using context 0 for a normal task.
+ * Other processors reserve the use of context zero for the kernel.
+ * This code assumes FIRST_CONTEXT < 32.
+ */
+ context_map[0] = (1 << FIRST_CONTEXT) - 1;
+ next_mmu_context = FIRST_CONTEXT;
+#ifdef FEW_CONTEXTS
+ atomic_set(&nr_free_contexts, LAST_CONTEXT - FIRST_CONTEXT + 1);
+#endif /* FEW_CONTEXTS */
+}
+
+#ifdef FEW_CONTEXTS
+/*
+ * Steal a context from a task that has one at the moment.
+ * This is only used on 8xx and 4xx and we presently assume that
+ * they don't do SMP. If they do then this will have to check
+ * whether the MM we steal is in use.
+ * We also assume that this is only used on systems that don't
+ * use an MMU hash table - this is true for 8xx and 4xx.
+ * This isn't an LRU system, it just frees up each context in
+ * turn (sort-of pseudo-random replacement :). This would be the
+ * place to implement an LRU scheme if anyone was motivated to do it.
+ * -- paulus
+ */
+void
+steal_context(void)
+{
+ struct mm_struct *mm;
+
+ /* free up context `next_mmu_context' */
+ /* if we shouldn't free context 0, don't... */
+ if (next_mmu_context < FIRST_CONTEXT)
+ next_mmu_context = FIRST_CONTEXT;
+ mm = context_mm[next_mmu_context];
+ flush_tlb_mm(mm);
+ destroy_context(mm);
+}
+#endif /* FEW_CONTEXTS */
diff --git a/arch/powerpc/mm/mmu_context_64.c b/arch/powerpc/mm/mmu_context_64.c
new file mode 100644
index 000000000000..714a84dd8d5d
--- /dev/null
+++ b/arch/powerpc/mm/mmu_context_64.c
@@ -0,0 +1,63 @@
+/*
+ * MMU context allocation for 64-bit kernels.
+ *
+ * Copyright (C) 2004 Anton Blanchard, IBM Corp. <anton@samba.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/config.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/spinlock.h>
+#include <linux/idr.h>
+
+#include <asm/mmu_context.h>
+
+static DEFINE_SPINLOCK(mmu_context_lock);
+static DEFINE_IDR(mmu_context_idr);
+
+int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
+{
+ int index;
+ int err;
+
+again:
+ if (!idr_pre_get(&mmu_context_idr, GFP_KERNEL))
+ return -ENOMEM;
+
+ spin_lock(&mmu_context_lock);
+ err = idr_get_new_above(&mmu_context_idr, NULL, 1, &index);
+ spin_unlock(&mmu_context_lock);
+
+ if (err == -EAGAIN)
+ goto again;
+ else if (err)
+ return err;
+
+ if (index > MAX_CONTEXT) {
+ idr_remove(&mmu_context_idr, index);
+ return -ENOMEM;
+ }
+
+ mm->context.id = index;
+
+ return 0;
+}
+
+void destroy_context(struct mm_struct *mm)
+{
+ spin_lock(&mmu_context_lock);
+ idr_remove(&mmu_context_idr, mm->context.id);
+ spin_unlock(&mmu_context_lock);
+
+ mm->context.id = NO_CONTEXT;
+}
diff --git a/arch/powerpc/mm/mmu_decl.h b/arch/powerpc/mm/mmu_decl.h
new file mode 100644
index 000000000000..a4d7a327c0e5
--- /dev/null
+++ b/arch/powerpc/mm/mmu_decl.h
@@ -0,0 +1,87 @@
+/*
+ * Declarations of procedures and variables shared between files
+ * in arch/ppc/mm/.
+ *
+ * Derived from arch/ppc/mm/init.c:
+ * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
+ *
+ * Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au)
+ * and Cort Dougan (PReP) (cort@cs.nmt.edu)
+ * Copyright (C) 1996 Paul Mackerras
+ * Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk).
+ *
+ * Derived from "arch/i386/mm/init.c"
+ * Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds
+ *
+ * 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 <asm/tlbflush.h>
+#include <asm/mmu.h>
+
+#ifdef CONFIG_PPC32
+extern void mapin_ram(void);
+extern int map_page(unsigned long va, phys_addr_t pa, int flags);
+extern void setbat(int index, unsigned long virt, unsigned long phys,
+ unsigned int size, int flags);
+extern void settlbcam(int index, unsigned long virt, phys_addr_t phys,
+ unsigned int size, int flags, unsigned int pid);
+extern void invalidate_tlbcam_entry(int index);
+
+extern int __map_without_bats;
+extern unsigned long ioremap_base;
+extern unsigned long ioremap_bot;
+extern unsigned int rtas_data, rtas_size;
+
+extern PTE *Hash, *Hash_end;
+extern unsigned long Hash_size, Hash_mask;
+
+extern unsigned int num_tlbcam_entries;
+#endif
+
+extern unsigned long __max_low_memory;
+extern unsigned long __initial_memory_limit;
+extern unsigned long total_memory;
+extern unsigned long total_lowmem;
+
+/* ...and now those things that may be slightly different between processor
+ * architectures. -- Dan
+ */
+#if defined(CONFIG_8xx)
+#define flush_HPTE(X, va, pg) _tlbie(va)
+#define MMU_init_hw() do { } while(0)
+#define mmu_mapin_ram() (0UL)
+
+#elif defined(CONFIG_4xx)
+#define flush_HPTE(X, va, pg) _tlbie(va)
+extern void MMU_init_hw(void);
+extern unsigned long mmu_mapin_ram(void);
+
+#elif defined(CONFIG_FSL_BOOKE)
+#define flush_HPTE(X, va, pg) _tlbie(va)
+extern void MMU_init_hw(void);
+extern unsigned long mmu_mapin_ram(void);
+extern void adjust_total_lowmem(void);
+
+#elif defined(CONFIG_PPC32)
+/* anything 32-bit except 4xx or 8xx */
+extern void MMU_init_hw(void);
+extern unsigned long mmu_mapin_ram(void);
+
+/* Be careful....this needs to be updated if we ever encounter 603 SMPs,
+ * which includes all new 82xx processors. We need tlbie/tlbsync here
+ * in that case (I think). -- Dan.
+ */
+static inline void flush_HPTE(unsigned context, unsigned long va,
+ unsigned long pdval)
+{
+ if ((Hash != 0) &&
+ cpu_has_feature(CPU_FTR_HPTE_TABLE))
+ flush_hash_pages(0, va, pdval, 1);
+ else
+ _tlbie(va);
+}
+#endif
diff --git a/arch/ppc64/mm/numa.c b/arch/powerpc/mm/numa.c
index cb864b8f2750..da09ba03c424 100644
--- a/arch/ppc64/mm/numa.c
+++ b/arch/powerpc/mm/numa.c
@@ -20,6 +20,8 @@
#include <asm/lmb.h>
#include <asm/machdep.h>
#include <asm/abs_addr.h>
+#include <asm/system.h>
+#include <asm/smp.h>
static int numa_enabled = 1;
@@ -300,7 +302,6 @@ static unsigned long __init numa_enforce_memory_limit(unsigned long start, unsig
* we've already adjusted it for the limit and it takes care of
* having memory holes below the limit.
*/
- extern unsigned long memory_limit;
if (! memory_limit)
return size;
diff --git a/arch/powerpc/mm/pgtable_32.c b/arch/powerpc/mm/pgtable_32.c
new file mode 100644
index 000000000000..f4e5ac122615
--- /dev/null
+++ b/arch/powerpc/mm/pgtable_32.c
@@ -0,0 +1,467 @@
+/*
+ * This file contains the routines setting up the linux page tables.
+ * -- paulus
+ *
+ * Derived from arch/ppc/mm/init.c:
+ * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
+ *
+ * Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au)
+ * and Cort Dougan (PReP) (cort@cs.nmt.edu)
+ * Copyright (C) 1996 Paul Mackerras
+ * Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk).
+ *
+ * Derived from "arch/i386/mm/init.c"
+ * Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds
+ *
+ * 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/config.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/vmalloc.h>
+#include <linux/init.h>
+#include <linux/highmem.h>
+
+#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
+#include <asm/io.h>
+
+#include "mmu_decl.h"
+
+unsigned long ioremap_base;
+unsigned long ioremap_bot;
+int io_bat_index;
+
+#if defined(CONFIG_6xx) || defined(CONFIG_POWER3)
+#define HAVE_BATS 1
+#endif
+
+#if defined(CONFIG_FSL_BOOKE)
+#define HAVE_TLBCAM 1
+#endif
+
+extern char etext[], _stext[];
+
+#ifdef CONFIG_SMP
+extern void hash_page_sync(void);
+#endif
+
+#ifdef HAVE_BATS
+extern unsigned long v_mapped_by_bats(unsigned long va);
+extern unsigned long p_mapped_by_bats(unsigned long pa);
+void setbat(int index, unsigned long virt, unsigned long phys,
+ unsigned int size, int flags);
+
+#else /* !HAVE_BATS */
+#define v_mapped_by_bats(x) (0UL)
+#define p_mapped_by_bats(x) (0UL)
+#endif /* HAVE_BATS */
+
+#ifdef HAVE_TLBCAM
+extern unsigned int tlbcam_index;
+extern unsigned long v_mapped_by_tlbcam(unsigned long va);
+extern unsigned long p_mapped_by_tlbcam(unsigned long pa);
+#else /* !HAVE_TLBCAM */
+#define v_mapped_by_tlbcam(x) (0UL)
+#define p_mapped_by_tlbcam(x) (0UL)
+#endif /* HAVE_TLBCAM */
+
+#ifdef CONFIG_PTE_64BIT
+/* 44x uses an 8kB pgdir because it has 8-byte Linux PTEs. */
+#define PGDIR_ORDER 1
+#else
+#define PGDIR_ORDER 0
+#endif
+
+pgd_t *pgd_alloc(struct mm_struct *mm)
+{
+ pgd_t *ret;
+
+ ret = (pgd_t *)__get_free_pages(GFP_KERNEL|__GFP_ZERO, PGDIR_ORDER);
+ return ret;
+}
+
+void pgd_free(pgd_t *pgd)
+{
+ free_pages((unsigned long)pgd, PGDIR_ORDER);
+}
+
+pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address)
+{
+ pte_t *pte;
+ extern int mem_init_done;
+ extern void *early_get_page(void);
+
+ if (mem_init_done) {
+ pte = (pte_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO);
+ } else {
+ pte = (pte_t *)early_get_page();
+ if (pte)
+ clear_page(pte);
+ }
+ return pte;
+}
+
+struct page *pte_alloc_one(struct mm_struct *mm, unsigned long address)
+{
+ struct page *ptepage;
+
+#ifdef CONFIG_HIGHPTE
+ gfp_t flags = GFP_KERNEL | __GFP_HIGHMEM | __GFP_REPEAT;
+#else
+ gfp_t flags = GFP_KERNEL | __GFP_REPEAT;
+#endif
+
+ ptepage = alloc_pages(flags, 0);
+ if (ptepage)
+ clear_highpage(ptepage);
+ return ptepage;
+}
+
+void pte_free_kernel(pte_t *pte)
+{
+#ifdef CONFIG_SMP
+ hash_page_sync();
+#endif
+ free_page((unsigned long)pte);
+}
+
+void pte_free(struct page *ptepage)
+{
+#ifdef CONFIG_SMP
+ hash_page_sync();
+#endif
+ __free_page(ptepage);
+}
+
+#ifndef CONFIG_PHYS_64BIT
+void __iomem *
+ioremap(phys_addr_t addr, unsigned long size)
+{
+ return __ioremap(addr, size, _PAGE_NO_CACHE);
+}
+#else /* CONFIG_PHYS_64BIT */
+void __iomem *
+ioremap64(unsigned long long addr, unsigned long size)
+{
+ return __ioremap(addr, size, _PAGE_NO_CACHE);
+}
+
+void __iomem *
+ioremap(phys_addr_t addr, unsigned long size)
+{
+ phys_addr_t addr64 = fixup_bigphys_addr(addr, size);
+
+ return ioremap64(addr64, size);
+}
+#endif /* CONFIG_PHYS_64BIT */
+
+void __iomem *
+__ioremap(phys_addr_t addr, unsigned long size, unsigned long flags)
+{
+ unsigned long v, i;
+ phys_addr_t p;
+ int err;
+
+ /*
+ * Choose an address to map it to.
+ * Once the vmalloc system is running, we use it.
+ * Before then, we use space going down from ioremap_base
+ * (ioremap_bot records where we're up to).
+ */
+ p = addr & PAGE_MASK;
+ size = PAGE_ALIGN(addr + size) - p;
+
+ /*
+ * If the address lies within the first 16 MB, assume it's in ISA
+ * memory space
+ */
+ if (p < 16*1024*1024)
+ p += _ISA_MEM_BASE;
+
+ /*
+ * Don't allow anybody to remap normal RAM that we're using.
+ * mem_init() sets high_memory so only do the check after that.
+ */
+ if (mem_init_done && (p < virt_to_phys(high_memory))) {
+ printk("__ioremap(): phys addr "PHYS_FMT" is RAM lr %p\n", p,
+ __builtin_return_address(0));
+ return NULL;
+ }
+
+ if (size == 0)
+ return NULL;
+
+ /*
+ * Is it already mapped? Perhaps overlapped by a previous
+ * BAT mapping. If the whole area is mapped then we're done,
+ * otherwise remap it since we want to keep the virt addrs for
+ * each request contiguous.
+ *
+ * We make the assumption here that if the bottom and top
+ * of the range we want are mapped then it's mapped to the
+ * same virt address (and this is contiguous).
+ * -- Cort
+ */
+ if ((v = p_mapped_by_bats(p)) /*&& p_mapped_by_bats(p+size-1)*/ )
+ goto out;
+
+ if ((v = p_mapped_by_tlbcam(p)))
+ goto out;
+
+ if (mem_init_done) {
+ struct vm_struct *area;
+ area = get_vm_area(size, VM_IOREMAP);
+ if (area == 0)
+ return NULL;
+ v = (unsigned long) area->addr;
+ } else {
+ v = (ioremap_bot -= size);
+ }
+
+ if ((flags & _PAGE_PRESENT) == 0)
+ flags |= _PAGE_KERNEL;
+ if (flags & _PAGE_NO_CACHE)
+ flags |= _PAGE_GUARDED;
+
+ /*
+ * Should check if it is a candidate for a BAT mapping
+ */
+
+ err = 0;
+ for (i = 0; i < size && err == 0; i += PAGE_SIZE)
+ err = map_page(v+i, p+i, flags);
+ if (err) {
+ if (mem_init_done)
+ vunmap((void *)v);
+ return NULL;
+ }
+
+out:
+ return (void __iomem *) (v + ((unsigned long)addr & ~PAGE_MASK));
+}
+
+void iounmap(volatile void __iomem *addr)
+{
+ /*
+ * If mapped by BATs then there is nothing to do.
+ * Calling vfree() generates a benign warning.
+ */
+ if (v_mapped_by_bats((unsigned long)addr)) return;
+
+ if (addr > high_memory && (unsigned long) addr < ioremap_bot)
+ vunmap((void *) (PAGE_MASK & (unsigned long)addr));
+}
+
+void __iomem *ioport_map(unsigned long port, unsigned int len)
+{
+ return (void __iomem *) (port + _IO_BASE);
+}
+
+void ioport_unmap(void __iomem *addr)
+{
+ /* Nothing to do */
+}
+EXPORT_SYMBOL(ioport_map);
+EXPORT_SYMBOL(ioport_unmap);
+
+int
+map_page(unsigned long va, phys_addr_t pa, int flags)
+{
+ pmd_t *pd;
+ pte_t *pg;
+ int err = -ENOMEM;
+
+ /* Use upper 10 bits of VA to index the first level map */
+ pd = pmd_offset(pgd_offset_k(va), va);
+ /* Use middle 10 bits of VA to index the second-level map */
+ pg = pte_alloc_kernel(pd, va);
+ if (pg != 0) {
+ err = 0;
+ set_pte_at(&init_mm, va, pg, pfn_pte(pa >> PAGE_SHIFT, __pgprot(flags)));
+ if (mem_init_done)
+ flush_HPTE(0, va, pmd_val(*pd));
+ }
+ return err;
+}
+
+/*
+ * Map in all of physical memory starting at KERNELBASE.
+ */
+void __init mapin_ram(void)
+{
+ unsigned long v, p, s, f;
+
+ s = mmu_mapin_ram();
+ v = KERNELBASE + s;
+ p = PPC_MEMSTART + s;
+ for (; s < total_lowmem; s += PAGE_SIZE) {
+ if ((char *) v >= _stext && (char *) v < etext)
+ f = _PAGE_RAM_TEXT;
+ else
+ f = _PAGE_RAM;
+ map_page(v, p, f);
+ v += PAGE_SIZE;
+ p += PAGE_SIZE;
+ }
+}
+
+/* is x a power of 2? */
+#define is_power_of_2(x) ((x) != 0 && (((x) & ((x) - 1)) == 0))
+
+/* is x a power of 4? */
+#define is_power_of_4(x) ((x) != 0 && (((x) & (x-1)) == 0) && (ffs(x) & 1))
+
+/*
+ * Set up a mapping for a block of I/O.
+ * virt, phys, size must all be page-aligned.
+ * This should only be called before ioremap is called.
+ */
+void __init io_block_mapping(unsigned long virt, phys_addr_t phys,
+ unsigned int size, int flags)
+{
+ int i;
+
+ if (virt > KERNELBASE && virt < ioremap_bot)
+ ioremap_bot = ioremap_base = virt;
+
+#ifdef HAVE_BATS
+ /*
+ * Use a BAT for this if possible...
+ */
+ if (io_bat_index < 2 && is_power_of_2(size)
+ && (virt & (size - 1)) == 0 && (phys & (size - 1)) == 0) {
+ setbat(io_bat_index, virt, phys, size, flags);
+ ++io_bat_index;
+ return;
+ }
+#endif /* HAVE_BATS */
+
+#ifdef HAVE_TLBCAM
+ /*
+ * Use a CAM for this if possible...
+ */
+ if (tlbcam_index < num_tlbcam_entries && is_power_of_4(size)
+ && (virt & (size - 1)) == 0 && (phys & (size - 1)) == 0) {
+ settlbcam(tlbcam_index, virt, phys, size, flags, 0);
+ ++tlbcam_index;
+ return;
+ }
+#endif /* HAVE_TLBCAM */
+
+ /* No BATs available, put it in the page tables. */
+ for (i = 0; i < size; i += PAGE_SIZE)
+ map_page(virt + i, phys + i, flags);
+}
+
+/* Scan the real Linux page tables and return a PTE pointer for
+ * a virtual address in a context.
+ * Returns true (1) if PTE was found, zero otherwise. The pointer to
+ * the PTE pointer is unmodified if PTE is not found.
+ */
+int
+get_pteptr(struct mm_struct *mm, unsigned long addr, pte_t **ptep)
+{
+ pgd_t *pgd;
+ pmd_t *pmd;
+ pte_t *pte;
+ int retval = 0;
+
+ pgd = pgd_offset(mm, addr & PAGE_MASK);
+ if (pgd) {
+ pmd = pmd_offset(pgd, addr & PAGE_MASK);
+ if (pmd_present(*pmd)) {
+ pte = pte_offset_map(pmd, addr & PAGE_MASK);
+ if (pte) {
+ retval = 1;
+ *ptep = pte;
+ /* XXX caller needs to do pte_unmap, yuck */
+ }
+ }
+ }
+ return(retval);
+}
+
+/* Find physical address for this virtual address. Normally used by
+ * I/O functions, but anyone can call it.
+ */
+unsigned long iopa(unsigned long addr)
+{
+ unsigned long pa;
+
+ /* I don't know why this won't work on PMacs or CHRP. It
+ * appears there is some bug, or there is some implicit
+ * mapping done not properly represented by BATs or in page
+ * tables.......I am actively working on resolving this, but
+ * can't hold up other stuff. -- Dan
+ */
+ pte_t *pte;
+ struct mm_struct *mm;
+
+ /* Check the BATs */
+ pa = v_mapped_by_bats(addr);
+ if (pa)
+ return pa;
+
+ /* Allow mapping of user addresses (within the thread)
+ * for DMA if necessary.
+ */
+ if (addr < TASK_SIZE)
+ mm = current->mm;
+ else
+ mm = &init_mm;
+
+ pa = 0;
+ if (get_pteptr(mm, addr, &pte)) {
+ pa = (pte_val(*pte) & PAGE_MASK) | (addr & ~PAGE_MASK);
+ pte_unmap(pte);
+ }
+
+ return(pa);
+}
+
+/* This is will find the virtual address for a physical one....
+ * Swiped from APUS, could be dangerous :-).
+ * This is only a placeholder until I really find a way to make this
+ * work. -- Dan
+ */
+unsigned long
+mm_ptov (unsigned long paddr)
+{
+ unsigned long ret;
+#if 0
+ if (paddr < 16*1024*1024)
+ ret = ZTWO_VADDR(paddr);
+ else {
+ int i;
+
+ for (i = 0; i < kmap_chunk_count;){
+ unsigned long phys = kmap_chunks[i++];
+ unsigned long size = kmap_chunks[i++];
+ unsigned long virt = kmap_chunks[i++];
+ if (paddr >= phys
+ && paddr < (phys + size)){
+ ret = virt + paddr - phys;
+ goto exit;
+ }
+ }
+
+ ret = (unsigned long) __va(paddr);
+ }
+exit:
+#ifdef DEBUGPV
+ printk ("PTOV(%lx)=%lx\n", paddr, ret);
+#endif
+#else
+ ret = (unsigned long)paddr + KERNELBASE;
+#endif
+ return ret;
+}
+
diff --git a/arch/powerpc/mm/pgtable_64.c b/arch/powerpc/mm/pgtable_64.c
new file mode 100644
index 000000000000..c7f7bb6f30b3
--- /dev/null
+++ b/arch/powerpc/mm/pgtable_64.c
@@ -0,0 +1,335 @@
+/*
+ * This file contains ioremap and related functions for 64-bit machines.
+ *
+ * Derived from arch/ppc64/mm/init.c
+ * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
+ *
+ * Modifications by Paul Mackerras (PowerMac) (paulus@samba.org)
+ * and Cort Dougan (PReP) (cort@cs.nmt.edu)
+ * Copyright (C) 1996 Paul Mackerras
+ * Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk).
+ *
+ * Derived from "arch/i386/mm/init.c"
+ * Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds
+ *
+ * Dave Engebretsen <engebret@us.ibm.com>
+ * Rework for PPC64 port.
+ *
+ * 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/config.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/mman.h>
+#include <linux/mm.h>
+#include <linux/swap.h>
+#include <linux/stddef.h>
+#include <linux/vmalloc.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/bootmem.h>
+#include <linux/highmem.h>
+#include <linux/idr.h>
+#include <linux/nodemask.h>
+#include <linux/module.h>
+
+#include <asm/pgalloc.h>
+#include <asm/page.h>
+#include <asm/prom.h>
+#include <asm/lmb.h>
+#include <asm/rtas.h>
+#include <asm/io.h>
+#include <asm/mmu_context.h>
+#include <asm/pgtable.h>
+#include <asm/mmu.h>
+#include <asm/uaccess.h>
+#include <asm/smp.h>
+#include <asm/machdep.h>
+#include <asm/tlb.h>
+#include <asm/eeh.h>
+#include <asm/processor.h>
+#include <asm/mmzone.h>
+#include <asm/cputable.h>
+#include <asm/sections.h>
+#include <asm/system.h>
+#include <asm/iommu.h>
+#include <asm/abs_addr.h>
+#include <asm/vdso.h>
+#include <asm/imalloc.h>
+
+unsigned long ioremap_bot = IMALLOC_BASE;
+static unsigned long phbs_io_bot = PHBS_IO_BASE;
+
+#ifdef CONFIG_PPC_ISERIES
+
+void __iomem *ioremap(unsigned long addr, unsigned long size)
+{
+ return (void __iomem *)addr;
+}
+
+extern void __iomem *__ioremap(unsigned long addr, unsigned long size,
+ unsigned long flags)
+{
+ return (void __iomem *)addr;
+}
+
+void iounmap(volatile void __iomem *addr)
+{
+ return;
+}
+
+#else
+
+/*
+ * map_io_page currently only called by __ioremap
+ * map_io_page adds an entry to the ioremap page table
+ * and adds an entry to the HPT, possibly bolting it
+ */
+static int map_io_page(unsigned long ea, unsigned long pa, int flags)
+{
+ pgd_t *pgdp;
+ pud_t *pudp;
+ pmd_t *pmdp;
+ pte_t *ptep;
+
+ if (mem_init_done) {
+ pgdp = pgd_offset_k(ea);
+ pudp = pud_alloc(&init_mm, pgdp, ea);
+ if (!pudp)
+ return -ENOMEM;
+ pmdp = pmd_alloc(&init_mm, pudp, ea);
+ if (!pmdp)
+ return -ENOMEM;
+ ptep = pte_alloc_kernel(pmdp, ea);
+ if (!ptep)
+ return -ENOMEM;
+ set_pte_at(&init_mm, ea, ptep, pfn_pte(pa >> PAGE_SHIFT,
+ __pgprot(flags)));
+ } else {
+ /*
+ * If the mm subsystem is not fully up, we cannot create a
+ * linux page table entry for this mapping. Simply bolt an
+ * entry in the hardware page table.
+ *
+ */
+ if (htab_bolt_mapping(ea, ea + PAGE_SIZE, pa, flags,
+ mmu_virtual_psize)) {
+ printk(KERN_ERR "Failed to do bolted mapping IO "
+ "memory at %016lx !\n", pa);
+ return -ENOMEM;
+ }
+ }
+ return 0;
+}
+
+
+static void __iomem * __ioremap_com(unsigned long addr, unsigned long pa,
+ unsigned long ea, unsigned long size,
+ unsigned long flags)
+{
+ unsigned long i;
+
+ if ((flags & _PAGE_PRESENT) == 0)
+ flags |= pgprot_val(PAGE_KERNEL);
+
+ for (i = 0; i < size; i += PAGE_SIZE)
+ if (map_io_page(ea+i, pa+i, flags))
+ return NULL;
+
+ return (void __iomem *) (ea + (addr & ~PAGE_MASK));
+}
+
+
+void __iomem *
+ioremap(unsigned long addr, unsigned long size)
+{
+ return __ioremap(addr, size, _PAGE_NO_CACHE | _PAGE_GUARDED);
+}
+
+void __iomem * __ioremap(unsigned long addr, unsigned long size,
+ unsigned long flags)
+{
+ unsigned long pa, ea;
+ void __iomem *ret;
+
+ /*
+ * Choose an address to map it to.
+ * Once the imalloc system is running, we use it.
+ * Before that, we map using addresses going
+ * up from ioremap_bot. imalloc will use
+ * the addresses from ioremap_bot through
+ * IMALLOC_END
+ *
+ */
+ pa = addr & PAGE_MASK;
+ size = PAGE_ALIGN(addr + size) - pa;
+
+ if (size == 0)
+ return NULL;
+
+ if (mem_init_done) {
+ struct vm_struct *area;
+ area = im_get_free_area(size);
+ if (area == NULL)
+ return NULL;
+ ea = (unsigned long)(area->addr);
+ ret = __ioremap_com(addr, pa, ea, size, flags);
+ if (!ret)
+ im_free(area->addr);
+ } else {
+ ea = ioremap_bot;
+ ret = __ioremap_com(addr, pa, ea, size, flags);
+ if (ret)
+ ioremap_bot += size;
+ }
+ return ret;
+}
+
+#define IS_PAGE_ALIGNED(_val) ((_val) == ((_val) & PAGE_MASK))
+
+int __ioremap_explicit(unsigned long pa, unsigned long ea,
+ unsigned long size, unsigned long flags)
+{
+ struct vm_struct *area;
+ void __iomem *ret;
+
+ /* For now, require page-aligned values for pa, ea, and size */
+ if (!IS_PAGE_ALIGNED(pa) || !IS_PAGE_ALIGNED(ea) ||
+ !IS_PAGE_ALIGNED(size)) {
+ printk(KERN_ERR "unaligned value in %s\n", __FUNCTION__);
+ return 1;
+ }
+
+ if (!mem_init_done) {
+ /* Two things to consider in this case:
+ * 1) No records will be kept (imalloc, etc) that the region
+ * has been remapped
+ * 2) It won't be easy to iounmap() the region later (because
+ * of 1)
+ */
+ ;
+ } else {
+ area = im_get_area(ea, size,
+ IM_REGION_UNUSED|IM_REGION_SUBSET|IM_REGION_EXISTS);
+ if (area == NULL) {
+ /* Expected when PHB-dlpar is in play */
+ return 1;
+ }
+ if (ea != (unsigned long) area->addr) {
+ printk(KERN_ERR "unexpected addr return from "
+ "im_get_area\n");
+ return 1;
+ }
+ }
+
+ ret = __ioremap_com(pa, pa, ea, size, flags);
+ if (ret == NULL) {
+ printk(KERN_ERR "ioremap_explicit() allocation failure !\n");
+ return 1;
+ }
+ if (ret != (void *) ea) {
+ printk(KERN_ERR "__ioremap_com() returned unexpected addr\n");
+ return 1;
+ }
+
+ return 0;
+}
+
+/*
+ * Unmap an IO region and remove it from imalloc'd list.
+ * Access to IO memory should be serialized by driver.
+ * This code is modeled after vmalloc code - unmap_vm_area()
+ *
+ * XXX what about calls before mem_init_done (ie python_countermeasures())
+ */
+void iounmap(volatile void __iomem *token)
+{
+ void *addr;
+
+ if (!mem_init_done)
+ return;
+
+ addr = (void *) ((unsigned long __force) token & PAGE_MASK);
+
+ im_free(addr);
+}
+
+static int iounmap_subset_regions(unsigned long addr, unsigned long size)
+{
+ struct vm_struct *area;
+
+ /* Check whether subsets of this region exist */
+ area = im_get_area(addr, size, IM_REGION_SUPERSET);
+ if (area == NULL)
+ return 1;
+
+ while (area) {
+ iounmap((void __iomem *) area->addr);
+ area = im_get_area(addr, size,
+ IM_REGION_SUPERSET);
+ }
+
+ return 0;
+}
+
+int iounmap_explicit(volatile void __iomem *start, unsigned long size)
+{
+ struct vm_struct *area;
+ unsigned long addr;
+ int rc;
+
+ addr = (unsigned long __force) start & PAGE_MASK;
+
+ /* Verify that the region either exists or is a subset of an existing
+ * region. In the latter case, split the parent region to create
+ * the exact region
+ */
+ area = im_get_area(addr, size,
+ IM_REGION_EXISTS | IM_REGION_SUBSET);
+ if (area == NULL) {
+ /* Determine whether subset regions exist. If so, unmap */
+ rc = iounmap_subset_regions(addr, size);
+ if (rc) {
+ printk(KERN_ERR
+ "%s() cannot unmap nonexistent range 0x%lx\n",
+ __FUNCTION__, addr);
+ return 1;
+ }
+ } else {
+ iounmap((void __iomem *) area->addr);
+ }
+ /*
+ * FIXME! This can't be right:
+ iounmap(area->addr);
+ * Maybe it should be "iounmap(area);"
+ */
+ return 0;
+}
+
+#endif
+
+EXPORT_SYMBOL(ioremap);
+EXPORT_SYMBOL(__ioremap);
+EXPORT_SYMBOL(iounmap);
+
+void __iomem * reserve_phb_iospace(unsigned long size)
+{
+ void __iomem *virt_addr;
+
+ if (phbs_io_bot >= IMALLOC_BASE)
+ panic("reserve_phb_iospace(): phb io space overflow\n");
+
+ virt_addr = (void __iomem *) phbs_io_bot;
+ phbs_io_bot += size;
+
+ return virt_addr;
+}
diff --git a/arch/powerpc/mm/ppc_mmu_32.c b/arch/powerpc/mm/ppc_mmu_32.c
new file mode 100644
index 000000000000..ed7fcfe5fd37
--- /dev/null
+++ b/arch/powerpc/mm/ppc_mmu_32.c
@@ -0,0 +1,300 @@
+/*
+ * This file contains the routines for handling the MMU on those
+ * PowerPC implementations where the MMU substantially follows the
+ * architecture specification. This includes the 6xx, 7xx, 7xxx,
+ * 8260, and POWER3 implementations but excludes the 8xx and 4xx.
+ * -- paulus
+ *
+ * Derived from arch/ppc/mm/init.c:
+ * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
+ *
+ * Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au)
+ * and Cort Dougan (PReP) (cort@cs.nmt.edu)
+ * Copyright (C) 1996 Paul Mackerras
+ * Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk).
+ *
+ * Derived from "arch/i386/mm/init.c"
+ * Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds
+ *
+ * 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/config.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <linux/highmem.h>
+
+#include <asm/prom.h>
+#include <asm/mmu.h>
+#include <asm/machdep.h>
+#include <asm/lmb.h>
+
+#include "mmu_decl.h"
+
+PTE *Hash, *Hash_end;
+unsigned long Hash_size, Hash_mask;
+unsigned long _SDR1;
+
+union ubat { /* BAT register values to be loaded */
+ BAT bat;
+#ifdef CONFIG_PPC64BRIDGE
+ u64 word[2];
+#else
+ u32 word[2];
+#endif
+} BATS[4][2]; /* 4 pairs of IBAT, DBAT */
+
+struct batrange { /* stores address ranges mapped by BATs */
+ unsigned long start;
+ unsigned long limit;
+ unsigned long phys;
+} bat_addrs[4];
+
+/*
+ * Return PA for this VA if it is mapped by a BAT, or 0
+ */
+unsigned long v_mapped_by_bats(unsigned long va)
+{
+ int b;
+ for (b = 0; b < 4; ++b)
+ if (va >= bat_addrs[b].start && va < bat_addrs[b].limit)
+ return bat_addrs[b].phys + (va - bat_addrs[b].start);
+ return 0;
+}
+
+/*
+ * Return VA for a given PA or 0 if not mapped
+ */
+unsigned long p_mapped_by_bats(unsigned long pa)
+{
+ int b;
+ for (b = 0; b < 4; ++b)
+ if (pa >= bat_addrs[b].phys
+ && pa < (bat_addrs[b].limit-bat_addrs[b].start)
+ +bat_addrs[b].phys)
+ return bat_addrs[b].start+(pa-bat_addrs[b].phys);
+ return 0;
+}
+
+unsigned long __init mmu_mapin_ram(void)
+{
+#ifdef CONFIG_POWER4
+ return 0;
+#else
+ unsigned long tot, bl, done;
+ unsigned long max_size = (256<<20);
+ unsigned long align;
+
+ if (__map_without_bats)
+ return 0;
+
+ /* Set up BAT2 and if necessary BAT3 to cover RAM. */
+
+ /* Make sure we don't map a block larger than the
+ smallest alignment of the physical address. */
+ /* alignment of PPC_MEMSTART */
+ align = ~(PPC_MEMSTART-1) & PPC_MEMSTART;
+ /* set BAT block size to MIN(max_size, align) */
+ if (align && align < max_size)
+ max_size = align;
+
+ tot = total_lowmem;
+ for (bl = 128<<10; bl < max_size; bl <<= 1) {
+ if (bl * 2 > tot)
+ break;
+ }
+
+ setbat(2, KERNELBASE, PPC_MEMSTART, bl, _PAGE_RAM);
+ done = (unsigned long)bat_addrs[2].limit - KERNELBASE + 1;
+ if ((done < tot) && !bat_addrs[3].limit) {
+ /* use BAT3 to cover a bit more */
+ tot -= done;
+ for (bl = 128<<10; bl < max_size; bl <<= 1)
+ if (bl * 2 > tot)
+ break;
+ setbat(3, KERNELBASE+done, PPC_MEMSTART+done, bl, _PAGE_RAM);
+ done = (unsigned long)bat_addrs[3].limit - KERNELBASE + 1;
+ }
+
+ return done;
+#endif
+}
+
+/*
+ * Set up one of the I/D BAT (block address translation) register pairs.
+ * The parameters are not checked; in particular size must be a power
+ * of 2 between 128k and 256M.
+ */
+void __init setbat(int index, unsigned long virt, unsigned long phys,
+ unsigned int size, int flags)
+{
+ unsigned int bl;
+ int wimgxpp;
+ union ubat *bat = BATS[index];
+
+ if (((flags & _PAGE_NO_CACHE) == 0) &&
+ cpu_has_feature(CPU_FTR_NEED_COHERENT))
+ flags |= _PAGE_COHERENT;
+
+ bl = (size >> 17) - 1;
+ if (PVR_VER(mfspr(SPRN_PVR)) != 1) {
+ /* 603, 604, etc. */
+ /* Do DBAT first */
+ wimgxpp = flags & (_PAGE_WRITETHRU | _PAGE_NO_CACHE
+ | _PAGE_COHERENT | _PAGE_GUARDED);
+ wimgxpp |= (flags & _PAGE_RW)? BPP_RW: BPP_RX;
+ bat[1].word[0] = virt | (bl << 2) | 2; /* Vs=1, Vp=0 */
+ bat[1].word[1] = phys | wimgxpp;
+#ifndef CONFIG_KGDB /* want user access for breakpoints */
+ if (flags & _PAGE_USER)
+#endif
+ bat[1].bat.batu.vp = 1;
+ if (flags & _PAGE_GUARDED) {
+ /* G bit must be zero in IBATs */
+ bat[0].word[0] = bat[0].word[1] = 0;
+ } else {
+ /* make IBAT same as DBAT */
+ bat[0] = bat[1];
+ }
+ } else {
+ /* 601 cpu */
+ if (bl > BL_8M)
+ bl = BL_8M;
+ wimgxpp = flags & (_PAGE_WRITETHRU | _PAGE_NO_CACHE
+ | _PAGE_COHERENT);
+ wimgxpp |= (flags & _PAGE_RW)?
+ ((flags & _PAGE_USER)? PP_RWRW: PP_RWXX): PP_RXRX;
+ bat->word[0] = virt | wimgxpp | 4; /* Ks=0, Ku=1 */
+ bat->word[1] = phys | bl | 0x40; /* V=1 */
+ }
+
+ bat_addrs[index].start = virt;
+ bat_addrs[index].limit = virt + ((bl + 1) << 17) - 1;
+ bat_addrs[index].phys = phys;
+}
+
+/*
+ * Preload a translation in the hash table
+ */
+void hash_preload(struct mm_struct *mm, unsigned long ea,
+ unsigned long access, unsigned long trap)
+{
+ pmd_t *pmd;
+
+ if (Hash == 0)
+ return;
+ pmd = pmd_offset(pgd_offset(mm, ea), ea);
+ if (!pmd_none(*pmd))
+ add_hash_page(mm->context, ea, pmd_val(*pmd));
+}
+
+/*
+ * Initialize the hash table and patch the instructions in hashtable.S.
+ */
+void __init MMU_init_hw(void)
+{
+ unsigned int hmask, mb, mb2;
+ unsigned int n_hpteg, lg_n_hpteg;
+
+ extern unsigned int hash_page_patch_A[];
+ extern unsigned int hash_page_patch_B[], hash_page_patch_C[];
+ extern unsigned int hash_page[];
+ extern unsigned int flush_hash_patch_A[], flush_hash_patch_B[];
+
+ if (!cpu_has_feature(CPU_FTR_HPTE_TABLE)) {
+ /*
+ * Put a blr (procedure return) instruction at the
+ * start of hash_page, since we can still get DSI
+ * exceptions on a 603.
+ */
+ hash_page[0] = 0x4e800020;
+ flush_icache_range((unsigned long) &hash_page[0],
+ (unsigned long) &hash_page[1]);
+ return;
+ }
+
+ if ( ppc_md.progress ) ppc_md.progress("hash:enter", 0x105);
+
+#ifdef CONFIG_PPC64BRIDGE
+#define LG_HPTEG_SIZE 7 /* 128 bytes per HPTEG */
+#define SDR1_LOW_BITS (lg_n_hpteg - 11)
+#define MIN_N_HPTEG 2048 /* min 256kB hash table */
+#else
+#define LG_HPTEG_SIZE 6 /* 64 bytes per HPTEG */
+#define SDR1_LOW_BITS ((n_hpteg - 1) >> 10)
+#define MIN_N_HPTEG 1024 /* min 64kB hash table */
+#endif
+
+ /*
+ * Allow 1 HPTE (1/8 HPTEG) for each page of memory.
+ * This is less than the recommended amount, but then
+ * Linux ain't AIX.
+ */
+ n_hpteg = total_memory / (PAGE_SIZE * 8);
+ if (n_hpteg < MIN_N_HPTEG)
+ n_hpteg = MIN_N_HPTEG;
+ lg_n_hpteg = __ilog2(n_hpteg);
+ if (n_hpteg & (n_hpteg - 1)) {
+ ++lg_n_hpteg; /* round up if not power of 2 */
+ n_hpteg = 1 << lg_n_hpteg;
+ }
+ Hash_size = n_hpteg << LG_HPTEG_SIZE;
+
+ /*
+ * Find some memory for the hash table.
+ */
+ if ( ppc_md.progress ) ppc_md.progress("hash:find piece", 0x322);
+ Hash = __va(lmb_alloc_base(Hash_size, Hash_size,
+ __initial_memory_limit));
+ cacheable_memzero(Hash, Hash_size);
+ _SDR1 = __pa(Hash) | SDR1_LOW_BITS;
+
+ Hash_end = (PTE *) ((unsigned long)Hash + Hash_size);
+
+ printk("Total memory = %ldMB; using %ldkB for hash table (at %p)\n",
+ total_memory >> 20, Hash_size >> 10, Hash);
+
+
+ /*
+ * Patch up the instructions in hashtable.S:create_hpte
+ */
+ if ( ppc_md.progress ) ppc_md.progress("hash:patch", 0x345);
+ Hash_mask = n_hpteg - 1;
+ hmask = Hash_mask >> (16 - LG_HPTEG_SIZE);
+ mb2 = mb = 32 - LG_HPTEG_SIZE - lg_n_hpteg;
+ if (lg_n_hpteg > 16)
+ mb2 = 16 - LG_HPTEG_SIZE;
+
+ hash_page_patch_A[0] = (hash_page_patch_A[0] & ~0xffff)
+ | ((unsigned int)(Hash) >> 16);
+ hash_page_patch_A[1] = (hash_page_patch_A[1] & ~0x7c0) | (mb << 6);
+ hash_page_patch_A[2] = (hash_page_patch_A[2] & ~0x7c0) | (mb2 << 6);
+ hash_page_patch_B[0] = (hash_page_patch_B[0] & ~0xffff) | hmask;
+ hash_page_patch_C[0] = (hash_page_patch_C[0] & ~0xffff) | hmask;
+
+ /*
+ * Ensure that the locations we've patched have been written
+ * out from the data cache and invalidated in the instruction
+ * cache, on those machines with split caches.
+ */
+ flush_icache_range((unsigned long) &hash_page_patch_A[0],
+ (unsigned long) &hash_page_patch_C[1]);
+
+ /*
+ * Patch up the instructions in hashtable.S:flush_hash_page
+ */
+ flush_hash_patch_A[0] = (flush_hash_patch_A[0] & ~0xffff)
+ | ((unsigned int)(Hash) >> 16);
+ flush_hash_patch_A[1] = (flush_hash_patch_A[1] & ~0x7c0) | (mb << 6);
+ flush_hash_patch_A[2] = (flush_hash_patch_A[2] & ~0x7c0) | (mb2 << 6);
+ flush_hash_patch_B[0] = (flush_hash_patch_B[0] & ~0xffff) | hmask;
+ flush_icache_range((unsigned long) &flush_hash_patch_A[0],
+ (unsigned long) &flush_hash_patch_B[1]);
+
+ if ( ppc_md.progress ) ppc_md.progress("hash:done", 0x205);
+}
diff --git a/arch/ppc64/mm/slb.c b/arch/powerpc/mm/slb.c
index 0473953f6a37..60e852f2f8e5 100644
--- a/arch/ppc64/mm/slb.c
+++ b/arch/powerpc/mm/slb.c
@@ -14,14 +14,32 @@
* 2 of the License, or (at your option) any later version.
*/
+#undef DEBUG
+
#include <linux/config.h>
#include <asm/pgtable.h>
#include <asm/mmu.h>
#include <asm/mmu_context.h>
#include <asm/paca.h>
#include <asm/cputable.h>
+#include <asm/cacheflush.h>
+
+#ifdef DEBUG
+#define DBG(fmt...) udbg_printf(fmt)
+#else
+#define DBG(fmt...)
+#endif
-extern void slb_allocate(unsigned long ea);
+extern void slb_allocate_realmode(unsigned long ea);
+extern void slb_allocate_user(unsigned long ea);
+
+static void slb_allocate(unsigned long ea)
+{
+ /* Currently, we do real mode for all SLBs including user, but
+ * that will change if we bring back dynamic VSIDs
+ */
+ slb_allocate_realmode(ea);
+}
static inline unsigned long mk_esid_data(unsigned long ea, unsigned long slot)
{
@@ -46,13 +64,15 @@ static void slb_flush_and_rebolt(void)
{
/* If you change this make sure you change SLB_NUM_BOLTED
* appropriately too. */
- unsigned long ksp_flags = SLB_VSID_KERNEL;
+ unsigned long linear_llp, virtual_llp, lflags, vflags;
unsigned long ksp_esid_data;
WARN_ON(!irqs_disabled());
- if (cpu_has_feature(CPU_FTR_16M_PAGE))
- ksp_flags |= SLB_VSID_L;
+ linear_llp = mmu_psize_defs[mmu_linear_psize].sllp;
+ virtual_llp = mmu_psize_defs[mmu_virtual_psize].sllp;
+ lflags = SLB_VSID_KERNEL | linear_llp;
+ vflags = SLB_VSID_KERNEL | virtual_llp;
ksp_esid_data = mk_esid_data(get_paca()->kstack, 2);
if ((ksp_esid_data & ESID_MASK) == KERNELBASE)
@@ -67,9 +87,9 @@ static void slb_flush_and_rebolt(void)
/* Slot 2 - kernel stack */
"slbmte %2,%3\n"
"isync"
- :: "r"(mk_vsid_data(VMALLOCBASE, SLB_VSID_KERNEL)),
+ :: "r"(mk_vsid_data(VMALLOCBASE, vflags)),
"r"(mk_esid_data(VMALLOCBASE, 1)),
- "r"(mk_vsid_data(ksp_esid_data, ksp_flags)),
+ "r"(mk_vsid_data(ksp_esid_data, lflags)),
"r"(ksp_esid_data)
: "memory");
}
@@ -102,6 +122,9 @@ void switch_slb(struct task_struct *tsk, struct mm_struct *mm)
get_paca()->slb_cache_ptr = 0;
get_paca()->context = mm->context;
+#ifdef CONFIG_PPC_64K_PAGES
+ get_paca()->pgdir = mm->pgd;
+#endif /* CONFIG_PPC_64K_PAGES */
/*
* preload some userspace segments into the SLB.
@@ -131,28 +154,77 @@ void switch_slb(struct task_struct *tsk, struct mm_struct *mm)
slb_allocate(unmapped_base);
}
+static inline void patch_slb_encoding(unsigned int *insn_addr,
+ unsigned int immed)
+{
+ /* Assume the instruction had a "0" immediate value, just
+ * "or" in the new value
+ */
+ *insn_addr |= immed;
+ flush_icache_range((unsigned long)insn_addr, 4+
+ (unsigned long)insn_addr);
+}
+
void slb_initialize(void)
{
+ unsigned long linear_llp, virtual_llp;
+ static int slb_encoding_inited;
+ extern unsigned int *slb_miss_kernel_load_linear;
+ extern unsigned int *slb_miss_kernel_load_virtual;
+ extern unsigned int *slb_miss_user_load_normal;
+#ifdef CONFIG_HUGETLB_PAGE
+ extern unsigned int *slb_miss_user_load_huge;
+ unsigned long huge_llp;
+
+ huge_llp = mmu_psize_defs[mmu_huge_psize].sllp;
+#endif
+
+ /* Prepare our SLB miss handler based on our page size */
+ linear_llp = mmu_psize_defs[mmu_linear_psize].sllp;
+ virtual_llp = mmu_psize_defs[mmu_virtual_psize].sllp;
+ if (!slb_encoding_inited) {
+ slb_encoding_inited = 1;
+ patch_slb_encoding(slb_miss_kernel_load_linear,
+ SLB_VSID_KERNEL | linear_llp);
+ patch_slb_encoding(slb_miss_kernel_load_virtual,
+ SLB_VSID_KERNEL | virtual_llp);
+ patch_slb_encoding(slb_miss_user_load_normal,
+ SLB_VSID_USER | virtual_llp);
+
+ DBG("SLB: linear LLP = %04x\n", linear_llp);
+ DBG("SLB: virtual LLP = %04x\n", virtual_llp);
+#ifdef CONFIG_HUGETLB_PAGE
+ patch_slb_encoding(slb_miss_user_load_huge,
+ SLB_VSID_USER | huge_llp);
+ DBG("SLB: huge LLP = %04x\n", huge_llp);
+#endif
+ }
+
/* On iSeries the bolted entries have already been set up by
* the hypervisor from the lparMap data in head.S */
#ifndef CONFIG_PPC_ISERIES
- unsigned long flags = SLB_VSID_KERNEL;
+ {
+ unsigned long lflags, vflags;
- /* Invalidate the entire SLB (even slot 0) & all the ERATS */
- if (cpu_has_feature(CPU_FTR_16M_PAGE))
- flags |= SLB_VSID_L;
+ lflags = SLB_VSID_KERNEL | linear_llp;
+ vflags = SLB_VSID_KERNEL | virtual_llp;
- asm volatile("isync":::"memory");
- asm volatile("slbmte %0,%0"::"r" (0) : "memory");
+ /* Invalidate the entire SLB (even slot 0) & all the ERATS */
+ asm volatile("isync":::"memory");
+ asm volatile("slbmte %0,%0"::"r" (0) : "memory");
asm volatile("isync; slbia; isync":::"memory");
- create_slbe(KERNELBASE, flags, 0);
- create_slbe(VMALLOCBASE, SLB_VSID_KERNEL, 1);
+ create_slbe(KERNELBASE, lflags, 0);
+
+ /* VMALLOC space has 4K pages always for now */
+ create_slbe(VMALLOCBASE, vflags, 1);
+
/* We don't bolt the stack for the time being - we're in boot,
* so the stack is in the bolted segment. By the time it goes
* elsewhere, we'll call _switch() which will bolt in the new
* one. */
asm volatile("isync":::"memory");
-#endif
+ }
+#endif /* CONFIG_PPC_ISERIES */
get_paca()->stab_rr = SLB_NUM_BOLTED;
}
diff --git a/arch/powerpc/mm/slb_low.S b/arch/powerpc/mm/slb_low.S
new file mode 100644
index 000000000000..950ffc5848c7
--- /dev/null
+++ b/arch/powerpc/mm/slb_low.S
@@ -0,0 +1,240 @@
+/*
+ * arch/ppc64/mm/slb_low.S
+ *
+ * Low-level SLB routines
+ *
+ * Copyright (C) 2004 David Gibson <dwg@au.ibm.com>, IBM
+ *
+ * Based on earlier C version:
+ * Dave Engebretsen and Mike Corrigan {engebret|mikejc}@us.ibm.com
+ * Copyright (c) 2001 Dave Engebretsen
+ * Copyright (C) 2002 Anton Blanchard <anton@au.ibm.com>, IBM
+ *
+ * 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/config.h>
+#include <asm/processor.h>
+#include <asm/ppc_asm.h>
+#include <asm/asm-offsets.h>
+#include <asm/cputable.h>
+#include <asm/page.h>
+#include <asm/mmu.h>
+#include <asm/pgtable.h>
+
+/* void slb_allocate_realmode(unsigned long ea);
+ *
+ * Create an SLB entry for the given EA (user or kernel).
+ * r3 = faulting address, r13 = PACA
+ * r9, r10, r11 are clobbered by this function
+ * No other registers are examined or changed.
+ */
+_GLOBAL(slb_allocate_realmode)
+ /* r3 = faulting address */
+
+ srdi r9,r3,60 /* get region */
+ srdi r10,r3,28 /* get esid */
+ cmpldi cr7,r9,0xc /* cmp KERNELBASE for later use */
+
+ /* r3 = address, r10 = esid, cr7 = <>KERNELBASE */
+ blt cr7,0f /* user or kernel? */
+
+ /* kernel address: proto-VSID = ESID */
+ /* WARNING - MAGIC: we don't use the VSID 0xfffffffff, but
+ * this code will generate the protoVSID 0xfffffffff for the
+ * top segment. That's ok, the scramble below will translate
+ * it to VSID 0, which is reserved as a bad VSID - one which
+ * will never have any pages in it. */
+
+ /* Check if hitting the linear mapping of the vmalloc/ioremap
+ * kernel space
+ */
+ bne cr7,1f
+
+ /* Linear mapping encoding bits, the "li" instruction below will
+ * be patched by the kernel at boot
+ */
+_GLOBAL(slb_miss_kernel_load_linear)
+ li r11,0
+ b slb_finish_load
+
+1: /* vmalloc/ioremap mapping encoding bits, the "li" instruction below
+ * will be patched by the kernel at boot
+ */
+_GLOBAL(slb_miss_kernel_load_virtual)
+ li r11,0
+ b slb_finish_load
+
+
+0: /* user address: proto-VSID = context << 15 | ESID. First check
+ * if the address is within the boundaries of the user region
+ */
+ srdi. r9,r10,USER_ESID_BITS
+ bne- 8f /* invalid ea bits set */
+
+ /* Figure out if the segment contains huge pages */
+#ifdef CONFIG_HUGETLB_PAGE
+BEGIN_FTR_SECTION
+ b 1f
+END_FTR_SECTION_IFCLR(CPU_FTR_16M_PAGE)
+ cmpldi r10,16
+
+ lhz r9,PACALOWHTLBAREAS(r13)
+ mr r11,r10
+ blt 5f
+
+ lhz r9,PACAHIGHHTLBAREAS(r13)
+ srdi r11,r10,(HTLB_AREA_SHIFT-SID_SHIFT)
+
+5: srd r9,r9,r11
+ andi. r9,r9,1
+ beq 1f
+_GLOBAL(slb_miss_user_load_huge)
+ li r11,0
+ b 2f
+1:
+#endif /* CONFIG_HUGETLB_PAGE */
+
+_GLOBAL(slb_miss_user_load_normal)
+ li r11,0
+
+2:
+ ld r9,PACACONTEXTID(r13)
+ rldimi r10,r9,USER_ESID_BITS,0
+ b slb_finish_load
+
+8: /* invalid EA */
+ li r10,0 /* BAD_VSID */
+ li r11,SLB_VSID_USER /* flags don't much matter */
+ b slb_finish_load
+
+#ifdef __DISABLED__
+
+/* void slb_allocate_user(unsigned long ea);
+ *
+ * Create an SLB entry for the given EA (user or kernel).
+ * r3 = faulting address, r13 = PACA
+ * r9, r10, r11 are clobbered by this function
+ * No other registers are examined or changed.
+ *
+ * It is called with translation enabled in order to be able to walk the
+ * page tables. This is not currently used.
+ */
+_GLOBAL(slb_allocate_user)
+ /* r3 = faulting address */
+ srdi r10,r3,28 /* get esid */
+
+ crset 4*cr7+lt /* set "user" flag for later */
+
+ /* check if we fit in the range covered by the pagetables*/
+ srdi. r9,r3,PGTABLE_EADDR_SIZE
+ crnot 4*cr0+eq,4*cr0+eq
+ beqlr
+
+ /* now we need to get to the page tables in order to get the page
+ * size encoding from the PMD. In the future, we'll be able to deal
+ * with 1T segments too by getting the encoding from the PGD instead
+ */
+ ld r9,PACAPGDIR(r13)
+ cmpldi cr0,r9,0
+ beqlr
+ rlwinm r11,r10,8,25,28
+ ldx r9,r9,r11 /* get pgd_t */
+ cmpldi cr0,r9,0
+ beqlr
+ rlwinm r11,r10,3,17,28
+ ldx r9,r9,r11 /* get pmd_t */
+ cmpldi cr0,r9,0
+ beqlr
+
+ /* build vsid flags */
+ andi. r11,r9,SLB_VSID_LLP
+ ori r11,r11,SLB_VSID_USER
+
+ /* get context to calculate proto-VSID */
+ ld r9,PACACONTEXTID(r13)
+ rldimi r10,r9,USER_ESID_BITS,0
+
+ /* fall through slb_finish_load */
+
+#endif /* __DISABLED__ */
+
+
+/*
+ * Finish loading of an SLB entry and return
+ *
+ * r3 = EA, r10 = proto-VSID, r11 = flags, clobbers r9, cr7 = <>KERNELBASE
+ */
+slb_finish_load:
+ ASM_VSID_SCRAMBLE(r10,r9)
+ rldimi r11,r10,SLB_VSID_SHIFT,16 /* combine VSID and flags */
+
+ /* r3 = EA, r11 = VSID data */
+ /*
+ * Find a slot, round robin. Previously we tried to find a
+ * free slot first but that took too long. Unfortunately we
+ * dont have any LRU information to help us choose a slot.
+ */
+#ifdef CONFIG_PPC_ISERIES
+ /*
+ * On iSeries, the "bolted" stack segment can be cast out on
+ * shared processor switch so we need to check for a miss on
+ * it and restore it to the right slot.
+ */
+ ld r9,PACAKSAVE(r13)
+ clrrdi r9,r9,28
+ clrrdi r3,r3,28
+ li r10,SLB_NUM_BOLTED-1 /* Stack goes in last bolted slot */
+ cmpld r9,r3
+ beq 3f
+#endif /* CONFIG_PPC_ISERIES */
+
+ ld r10,PACASTABRR(r13)
+ addi r10,r10,1
+ /* use a cpu feature mask if we ever change our slb size */
+ cmpldi r10,SLB_NUM_ENTRIES
+
+ blt+ 4f
+ li r10,SLB_NUM_BOLTED
+
+4:
+ std r10,PACASTABRR(r13)
+
+3:
+ rldimi r3,r10,0,36 /* r3= EA[0:35] | entry */
+ oris r10,r3,SLB_ESID_V@h /* r3 |= SLB_ESID_V */
+
+ /* r3 = ESID data, r11 = VSID data */
+
+ /*
+ * No need for an isync before or after this slbmte. The exception
+ * we enter with and the rfid we exit with are context synchronizing.
+ */
+ slbmte r11,r10
+
+ /* we're done for kernel addresses */
+ crclr 4*cr0+eq /* set result to "success" */
+ bgelr cr7
+
+ /* Update the slb cache */
+ lhz r3,PACASLBCACHEPTR(r13) /* offset = paca->slb_cache_ptr */
+ cmpldi r3,SLB_CACHE_ENTRIES
+ bge 1f
+
+ /* still room in the slb cache */
+ sldi r11,r3,1 /* r11 = offset * sizeof(u16) */
+ rldicl r10,r10,36,28 /* get low 16 bits of the ESID */
+ add r11,r11,r13 /* r11 = (u16 *)paca + offset */
+ sth r10,PACASLBCACHE(r11) /* paca->slb_cache[offset] = esid */
+ addi r3,r3,1 /* offset++ */
+ b 2f
+1: /* offset >= SLB_CACHE_ENTRIES */
+ li r3,SLB_CACHE_ENTRIES+1
+2:
+ sth r3,PACASLBCACHEPTR(r13) /* paca->slb_cache_ptr = offset */
+ crclr 4*cr0+eq /* set result to "success" */
+ blr
+
diff --git a/arch/ppc64/mm/stab.c b/arch/powerpc/mm/stab.c
index 1b83f002bf27..cfbb4e1f966b 100644
--- a/arch/ppc64/mm/stab.c
+++ b/arch/powerpc/mm/stab.c
@@ -20,13 +20,13 @@
#include <asm/cputable.h>
#include <asm/lmb.h>
#include <asm/abs_addr.h>
+#include <asm/firmware.h>
struct stab_entry {
unsigned long esid_data;
unsigned long vsid_data;
};
-/* Both the segment table and SLB code uses the following cache */
#define NR_STAB_CACHE_ENTRIES 8
DEFINE_PER_CPU(long, stab_cache_ptr);
DEFINE_PER_CPU(long, stab_cache[NR_STAB_CACHE_ENTRIES]);
@@ -186,7 +186,7 @@ void switch_stab(struct task_struct *tsk, struct mm_struct *mm)
/* Never flush the first entry. */
ste += 1;
for (entry = 1;
- entry < (PAGE_SIZE / sizeof(struct stab_entry));
+ entry < (HW_PAGE_SIZE / sizeof(struct stab_entry));
entry++, ste++) {
unsigned long ea;
ea = ste->esid_data & ESID_MASK;
@@ -200,6 +200,10 @@ void switch_stab(struct task_struct *tsk, struct mm_struct *mm)
__get_cpu_var(stab_cache_ptr) = 0;
+#ifdef CONFIG_PPC_64K_PAGES
+ get_paca()->pgdir = mm->pgd;
+#endif /* CONFIG_PPC_64K_PAGES */
+
/* Now preload some entries for the new task */
if (test_tsk_thread_flag(tsk, TIF_32BIT))
unmapped_base = TASK_UNMAPPED_BASE_USER32;
@@ -223,8 +227,6 @@ void switch_stab(struct task_struct *tsk, struct mm_struct *mm)
asm volatile("sync" : : : "memory");
}
-extern void slb_initialize(void);
-
/*
* Allocate segment tables for secondary CPUs. These must all go in
* the first (bolted) segment, so that do_stab_bolted won't get a
@@ -243,18 +245,21 @@ void stabs_alloc(void)
if (cpu == 0)
continue; /* stab for CPU 0 is statically allocated */
- newstab = lmb_alloc_base(PAGE_SIZE, PAGE_SIZE, 1<<SID_SHIFT);
+ newstab = lmb_alloc_base(HW_PAGE_SIZE, HW_PAGE_SIZE,
+ 1<<SID_SHIFT);
if (! newstab)
panic("Unable to allocate segment table for CPU %d.\n",
cpu);
newstab += KERNELBASE;
- memset((void *)newstab, 0, PAGE_SIZE);
+ memset((void *)newstab, 0, HW_PAGE_SIZE);
paca[cpu].stab_addr = newstab;
paca[cpu].stab_real = virt_to_abs(newstab);
- printk(KERN_DEBUG "Segment table for CPU %d at 0x%lx virtual, 0x%lx absolute\n", cpu, paca[cpu].stab_addr, paca[cpu].stab_real);
+ printk(KERN_INFO "Segment table for CPU %d at 0x%lx "
+ "virtual, 0x%lx absolute\n",
+ cpu, paca[cpu].stab_addr, paca[cpu].stab_real);
}
}
@@ -266,14 +271,28 @@ void stabs_alloc(void)
void stab_initialize(unsigned long stab)
{
unsigned long vsid = get_kernel_vsid(KERNELBASE);
+ unsigned long stabreal;
- if (cpu_has_feature(CPU_FTR_SLB)) {
- slb_initialize();
- } else {
- asm volatile("isync; slbia; isync":::"memory");
- make_ste(stab, GET_ESID(KERNELBASE), vsid);
+ asm volatile("isync; slbia; isync":::"memory");
+ make_ste(stab, GET_ESID(KERNELBASE), vsid);
- /* Order update */
- asm volatile("sync":::"memory");
+ /* Order update */
+ asm volatile("sync":::"memory");
+
+ /* Set ASR */
+ stabreal = get_paca()->stab_real | 0x1ul;
+
+#ifdef CONFIG_PPC_ISERIES
+ if (firmware_has_feature(FW_FEATURE_ISERIES)) {
+ HvCall1(HvCallBaseSetASR, stabreal);
+ return;
+ }
+#endif /* CONFIG_PPC_ISERIES */
+#ifdef CONFIG_PPC_PSERIES
+ if (platform_is_lpar()) {
+ plpar_hcall_norets(H_SET_ASR, stabreal);
+ return;
}
+#endif
+ mtspr(SPRN_ASR, stabreal);
}
diff --git a/arch/powerpc/mm/tlb_32.c b/arch/powerpc/mm/tlb_32.c
new file mode 100644
index 000000000000..6c3dc3c44c86
--- /dev/null
+++ b/arch/powerpc/mm/tlb_32.c
@@ -0,0 +1,183 @@
+/*
+ * This file contains the routines for TLB flushing.
+ * On machines where the MMU uses a hash table to store virtual to
+ * physical translations, these routines flush entries from the
+ * hash table also.
+ * -- paulus
+ *
+ * Derived from arch/ppc/mm/init.c:
+ * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
+ *
+ * Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au)
+ * and Cort Dougan (PReP) (cort@cs.nmt.edu)
+ * Copyright (C) 1996 Paul Mackerras
+ * Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk).
+ *
+ * Derived from "arch/i386/mm/init.c"
+ * Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds
+ *
+ * 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/config.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <linux/highmem.h>
+#include <asm/tlbflush.h>
+#include <asm/tlb.h>
+
+#include "mmu_decl.h"
+
+/*
+ * Called when unmapping pages to flush entries from the TLB/hash table.
+ */
+void flush_hash_entry(struct mm_struct *mm, pte_t *ptep, unsigned long addr)
+{
+ unsigned long ptephys;
+
+ if (Hash != 0) {
+ ptephys = __pa(ptep) & PAGE_MASK;
+ flush_hash_pages(mm->context, addr, ptephys, 1);
+ }
+}
+
+/*
+ * Called by ptep_set_access_flags, must flush on CPUs for which the
+ * DSI handler can't just "fixup" the TLB on a write fault
+ */
+void flush_tlb_page_nohash(struct vm_area_struct *vma, unsigned long addr)
+{
+ if (Hash != 0)
+ return;
+ _tlbie(addr);
+}
+
+/*
+ * Called at the end of a mmu_gather operation to make sure the
+ * TLB flush is completely done.
+ */
+void tlb_flush(struct mmu_gather *tlb)
+{
+ if (Hash == 0) {
+ /*
+ * 603 needs to flush the whole TLB here since
+ * it doesn't use a hash table.
+ */
+ _tlbia();
+ }
+}
+
+/*
+ * TLB flushing:
+ *
+ * - flush_tlb_mm(mm) flushes the specified mm context TLB's
+ * - flush_tlb_page(vma, vmaddr) flushes one page
+ * - flush_tlb_range(vma, start, end) flushes a range of pages
+ * - flush_tlb_kernel_range(start, end) flushes kernel pages
+ *
+ * since the hardware hash table functions as an extension of the
+ * tlb as far as the linux tables are concerned, flush it too.
+ * -- Cort
+ */
+
+/*
+ * 750 SMP is a Bad Idea because the 750 doesn't broadcast all
+ * the cache operations on the bus. Hence we need to use an IPI
+ * to get the other CPU(s) to invalidate their TLBs.
+ */
+#ifdef CONFIG_SMP_750
+#define FINISH_FLUSH smp_send_tlb_invalidate(0)
+#else
+#define FINISH_FLUSH do { } while (0)
+#endif
+
+static void flush_range(struct mm_struct *mm, unsigned long start,
+ unsigned long end)
+{
+ pmd_t *pmd;
+ unsigned long pmd_end;
+ int count;
+ unsigned int ctx = mm->context;
+
+ if (Hash == 0) {
+ _tlbia();
+ return;
+ }
+ start &= PAGE_MASK;
+ if (start >= end)
+ return;
+ end = (end - 1) | ~PAGE_MASK;
+ pmd = pmd_offset(pgd_offset(mm, start), start);
+ for (;;) {
+ pmd_end = ((start + PGDIR_SIZE) & PGDIR_MASK) - 1;
+ if (pmd_end > end)
+ pmd_end = end;
+ if (!pmd_none(*pmd)) {
+ count = ((pmd_end - start) >> PAGE_SHIFT) + 1;
+ flush_hash_pages(ctx, start, pmd_val(*pmd), count);
+ }
+ if (pmd_end == end)
+ break;
+ start = pmd_end + 1;
+ ++pmd;
+ }
+}
+
+/*
+ * Flush kernel TLB entries in the given range
+ */
+void flush_tlb_kernel_range(unsigned long start, unsigned long end)
+{
+ flush_range(&init_mm, start, end);
+ FINISH_FLUSH;
+}
+
+/*
+ * Flush all the (user) entries for the address space described by mm.
+ */
+void flush_tlb_mm(struct mm_struct *mm)
+{
+ struct vm_area_struct *mp;
+
+ if (Hash == 0) {
+ _tlbia();
+ return;
+ }
+
+ for (mp = mm->mmap; mp != NULL; mp = mp->vm_next)
+ flush_range(mp->vm_mm, mp->vm_start, mp->vm_end);
+ FINISH_FLUSH;
+}
+
+void flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr)
+{
+ struct mm_struct *mm;
+ pmd_t *pmd;
+
+ if (Hash == 0) {
+ _tlbie(vmaddr);
+ return;
+ }
+ mm = (vmaddr < TASK_SIZE)? vma->vm_mm: &init_mm;
+ pmd = pmd_offset(pgd_offset(mm, vmaddr), vmaddr);
+ if (!pmd_none(*pmd))
+ flush_hash_pages(mm->context, vmaddr, pmd_val(*pmd), 1);
+ FINISH_FLUSH;
+}
+
+/*
+ * For each address in the range, find the pte for the address
+ * and check _PAGE_HASHPTE bit; if it is set, find and destroy
+ * the corresponding HPTE.
+ */
+void flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
+ unsigned long end)
+{
+ flush_range(vma->vm_mm, start, end);
+ FINISH_FLUSH;
+}
diff --git a/arch/ppc64/mm/tlb.c b/arch/powerpc/mm/tlb_64.c
index 21fbffb23a43..53e31b834ace 100644
--- a/arch/ppc64/mm/tlb.c
+++ b/arch/powerpc/mm/tlb_64.c
@@ -21,6 +21,7 @@
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
+
#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/mm.h>
@@ -30,7 +31,7 @@
#include <asm/pgalloc.h>
#include <asm/tlbflush.h>
#include <asm/tlb.h>
-#include <linux/highmem.h>
+#include <asm/bug.h>
DEFINE_PER_CPU(struct ppc64_tlb_batch, ppc64_tlb_batch);
@@ -126,36 +127,54 @@ void pgtable_free_tlb(struct mmu_gather *tlb, pgtable_free_t pgf)
* (if we remove it we should clear the _PTE_HPTEFLAGS bits).
*/
void hpte_update(struct mm_struct *mm, unsigned long addr,
- unsigned long pte, int wrprot)
+ pte_t *ptep, unsigned long pte, int huge)
{
- int i;
- unsigned long context = 0;
struct ppc64_tlb_batch *batch = &__get_cpu_var(ppc64_tlb_batch);
+ unsigned long vsid;
+ unsigned int psize = mmu_virtual_psize;
+ int i;
- if (REGION_ID(addr) == USER_REGION_ID)
- context = mm->context.id;
i = batch->index;
+ /* We mask the address for the base page size. Huge pages will
+ * have applied their own masking already
+ */
+ addr &= PAGE_MASK;
+
+ /* Get page size (maybe move back to caller) */
+ if (huge) {
+#ifdef CONFIG_HUGETLB_PAGE
+ psize = mmu_huge_psize;
+#else
+ BUG();
+#endif
+ }
+
/*
* This can happen when we are in the middle of a TLB batch and
* we encounter memory pressure (eg copy_page_range when it tries
* to allocate a new pte). If we have to reclaim memory and end
* up scanning and resetting referenced bits then our batch context
* will change mid stream.
+ *
+ * We also need to ensure only one page size is present in a given
+ * batch
*/
- if (i != 0 && (context != batch->context ||
- batch->large != pte_huge(pte))) {
+ if (i != 0 && (mm != batch->mm || batch->psize != psize)) {
flush_tlb_pending();
i = 0;
}
-
if (i == 0) {
- batch->context = context;
batch->mm = mm;
- batch->large = pte_huge(pte);
+ batch->psize = psize;
}
- batch->pte[i] = __pte(pte);
- batch->addr[i] = addr;
+ if (addr < KERNELBASE) {
+ vsid = get_vsid(mm->context.id, addr);
+ WARN_ON(vsid == 0);
+ } else
+ vsid = get_kernel_vsid(addr);
+ batch->vaddr[i] = (vsid << 28 ) | (addr & 0x0fffffff);
+ batch->pte[i] = __real_pte(__pte(pte), ptep);
batch->index = ++i;
if (i >= PPC64_TLB_BATCH_NR)
flush_tlb_pending();
@@ -177,10 +196,10 @@ void __flush_tlb_pending(struct ppc64_tlb_batch *batch)
local = 1;
if (i == 1)
- flush_hash_page(batch->context, batch->addr[0], batch->pte[0],
- local);
+ flush_hash_page(batch->vaddr[0], batch->pte[0],
+ batch->psize, local);
else
- flush_hash_range(batch->context, i, local);
+ flush_hash_range(i, local);
batch->index = 0;
put_cpu();
}
diff --git a/arch/ppc/oprofile/Kconfig b/arch/powerpc/oprofile/Kconfig
index 19d37730b664..eb2dece76a54 100644
--- a/arch/ppc/oprofile/Kconfig
+++ b/arch/powerpc/oprofile/Kconfig
@@ -1,7 +1,3 @@
-
-menu "Profiling support"
- depends on EXPERIMENTAL
-
config PROFILING
bool "Profiling support (EXPERIMENTAL)"
help
@@ -19,5 +15,3 @@ config OPROFILE
If unsure, say N.
-endmenu
-
diff --git a/arch/ppc/oprofile/Makefile b/arch/powerpc/oprofile/Makefile
index e2218d32a4eb..0782d0cca89c 100644
--- a/arch/ppc/oprofile/Makefile
+++ b/arch/powerpc/oprofile/Makefile
@@ -7,8 +7,5 @@ DRIVER_OBJS := $(addprefix ../../../drivers/oprofile/, \
timer_int.o )
oprofile-y := $(DRIVER_OBJS) common.o
-
-ifeq ($(CONFIG_FSL_BOOKE),y)
- oprofile-y += op_model_fsl_booke.o
-endif
-
+oprofile-$(CONFIG_PPC64) += op_model_rs64.o op_model_power4.o
+oprofile-$(CONFIG_FSL_BOOKE) += op_model_fsl_booke.o
diff --git a/arch/ppc64/oprofile/common.c b/arch/powerpc/oprofile/common.c
index e5f572710aa0..af2c05d20ba5 100644
--- a/arch/ppc64/oprofile/common.c
+++ b/arch/powerpc/oprofile/common.c
@@ -1,5 +1,9 @@
/*
+ * PPC 64 oprofile support:
* Copyright (C) 2004 Anton Blanchard <anton@au.ibm.com>, IBM
+ * PPC 32 oprofile support: (based on PPC 64 support)
+ * Copyright (C) Freescale Semiconductor, Inc 2004
+ * Author: Andy Fleming
*
* Based on alpha version.
*
@@ -10,6 +14,9 @@
*/
#include <linux/oprofile.h>
+#ifndef __powerpc64__
+#include <linux/slab.h>
+#endif /* ! __powerpc64__ */
#include <linux/init.h>
#include <linux/smp.h>
#include <linux/errno.h>
@@ -19,17 +26,21 @@
#include <asm/cputable.h>
#include <asm/oprofile_impl.h>
-static struct op_ppc64_model *model;
+static struct op_powerpc_model *model;
static struct op_counter_config ctr[OP_MAX_COUNTER];
static struct op_system_config sys;
+#ifndef __powerpc64__
+static char *cpu_type;
+#endif /* ! __powerpc64__ */
+
static void op_handle_interrupt(struct pt_regs *regs)
{
model->handle_interrupt(regs, ctr);
}
-static int op_ppc64_setup(void)
+static int op_powerpc_setup(void)
{
int err;
@@ -42,41 +53,49 @@ static int op_ppc64_setup(void)
model->reg_setup(ctr, &sys, model->num_counters);
/* Configure the registers on all cpus. */
+#ifdef __powerpc64__
on_each_cpu(model->cpu_setup, NULL, 0, 1);
+#else /* __powerpc64__ */
+#if 0
+ /* FIXME: Make multi-cpu work */
+ on_each_cpu(model->reg_setup, NULL, 0, 1);
+#endif
+#endif /* __powerpc64__ */
return 0;
}
-static void op_ppc64_shutdown(void)
+static void op_powerpc_shutdown(void)
{
release_pmc_hardware();
}
-static void op_ppc64_cpu_start(void *dummy)
+static void op_powerpc_cpu_start(void *dummy)
{
model->start(ctr);
}
-static int op_ppc64_start(void)
+static int op_powerpc_start(void)
{
- on_each_cpu(op_ppc64_cpu_start, NULL, 0, 1);
+ on_each_cpu(op_powerpc_cpu_start, NULL, 0, 1);
return 0;
}
-static inline void op_ppc64_cpu_stop(void *dummy)
+static inline void op_powerpc_cpu_stop(void *dummy)
{
model->stop();
}
-static void op_ppc64_stop(void)
+static void op_powerpc_stop(void)
{
- on_each_cpu(op_ppc64_cpu_stop, NULL, 0, 1);
+ on_each_cpu(op_powerpc_cpu_stop, NULL, 0, 1);
}
-static int op_ppc64_create_files(struct super_block *sb, struct dentry *root)
+static int op_powerpc_create_files(struct super_block *sb, struct dentry *root)
{
int i;
+#ifdef __powerpc64__
/*
* There is one mmcr0, mmcr1 and mmcra for setting the events for
* all of the counters.
@@ -84,6 +103,7 @@ static int op_ppc64_create_files(struct super_block *sb, struct dentry *root)
oprofilefs_create_ulong(sb, root, "mmcr0", &sys.mmcr0);
oprofilefs_create_ulong(sb, root, "mmcr1", &sys.mmcr1);
oprofilefs_create_ulong(sb, root, "mmcra", &sys.mmcra);
+#endif /* __powerpc64__ */
for (i = 0; i < model->num_counters; ++i) {
struct dentry *dir;
@@ -95,44 +115,70 @@ static int op_ppc64_create_files(struct super_block *sb, struct dentry *root)
oprofilefs_create_ulong(sb, dir, "enabled", &ctr[i].enabled);
oprofilefs_create_ulong(sb, dir, "event", &ctr[i].event);
oprofilefs_create_ulong(sb, dir, "count", &ctr[i].count);
+#ifdef __powerpc64__
/*
* We dont support per counter user/kernel selection, but
* we leave the entries because userspace expects them
*/
+#endif /* __powerpc64__ */
oprofilefs_create_ulong(sb, dir, "kernel", &ctr[i].kernel);
oprofilefs_create_ulong(sb, dir, "user", &ctr[i].user);
+
+#ifndef __powerpc64__
+ /* FIXME: Not sure if this is used */
+#endif /* ! __powerpc64__ */
oprofilefs_create_ulong(sb, dir, "unit_mask", &ctr[i].unit_mask);
}
oprofilefs_create_ulong(sb, root, "enable_kernel", &sys.enable_kernel);
oprofilefs_create_ulong(sb, root, "enable_user", &sys.enable_user);
+#ifdef __powerpc64__
oprofilefs_create_ulong(sb, root, "backtrace_spinlocks",
&sys.backtrace_spinlocks);
+#endif /* __powerpc64__ */
/* Default to tracing both kernel and user */
sys.enable_kernel = 1;
sys.enable_user = 1;
-
+#ifdef __powerpc64__
/* Turn on backtracing through spinlocks by default */
sys.backtrace_spinlocks = 1;
+#endif /* __powerpc64__ */
return 0;
}
int __init oprofile_arch_init(struct oprofile_operations *ops)
{
+#ifndef __powerpc64__
+#ifdef CONFIG_FSL_BOOKE
+ model = &op_model_fsl_booke;
+#else
+ return -ENODEV;
+#endif
+
+ cpu_type = kmalloc(32, GFP_KERNEL);
+ if (NULL == cpu_type)
+ return -ENOMEM;
+
+ sprintf(cpu_type, "ppc/%s", cur_cpu_spec->cpu_name);
+
+ model->num_counters = cur_cpu_spec->num_pmcs;
+
+ ops->cpu_type = cpu_type;
+#else /* __powerpc64__ */
if (!cur_cpu_spec->oprofile_model || !cur_cpu_spec->oprofile_cpu_type)
return -ENODEV;
-
model = cur_cpu_spec->oprofile_model;
model->num_counters = cur_cpu_spec->num_pmcs;
ops->cpu_type = cur_cpu_spec->oprofile_cpu_type;
- ops->create_files = op_ppc64_create_files;
- ops->setup = op_ppc64_setup;
- ops->shutdown = op_ppc64_shutdown;
- ops->start = op_ppc64_start;
- ops->stop = op_ppc64_stop;
+#endif /* __powerpc64__ */
+ ops->create_files = op_powerpc_create_files;
+ ops->setup = op_powerpc_setup;
+ ops->shutdown = op_powerpc_shutdown;
+ ops->start = op_powerpc_start;
+ ops->stop = op_powerpc_stop;
printk(KERN_INFO "oprofile: using %s performance monitoring.\n",
ops->cpu_type);
@@ -142,4 +188,8 @@ int __init oprofile_arch_init(struct oprofile_operations *ops)
void oprofile_arch_exit(void)
{
+#ifndef __powerpc64__
+ kfree(cpu_type);
+ cpu_type = NULL;
+#endif /* ! __powerpc64__ */
}
diff --git a/arch/ppc/oprofile/op_model_fsl_booke.c b/arch/powerpc/oprofile/op_model_fsl_booke.c
index fc9c859358c6..86124a94c9af 100644
--- a/arch/ppc/oprofile/op_model_fsl_booke.c
+++ b/arch/powerpc/oprofile/op_model_fsl_booke.c
@@ -24,9 +24,8 @@
#include <asm/cputable.h>
#include <asm/reg_booke.h>
#include <asm/page.h>
-#include <asm/perfmon.h>
-
-#include "op_impl.h"
+#include <asm/pmc.h>
+#include <asm/oprofile_impl.h>
static unsigned long reset_value[OP_MAX_COUNTER];
@@ -176,7 +175,7 @@ static void fsl_booke_handle_interrupt(struct pt_regs *regs,
pmc_start_ctrs(1);
}
-struct op_ppc32_model op_model_fsl_booke = {
+struct op_powerpc_model op_model_fsl_booke = {
.reg_setup = fsl_booke_reg_setup,
.start = fsl_booke_start,
.stop = fsl_booke_stop,
diff --git a/arch/ppc64/oprofile/op_model_power4.c b/arch/powerpc/oprofile/op_model_power4.c
index 32b2bb5625fe..e3a024e324b6 100644
--- a/arch/ppc64/oprofile/op_model_power4.c
+++ b/arch/powerpc/oprofile/op_model_power4.c
@@ -17,6 +17,7 @@
#include <asm/systemcfg.h>
#include <asm/rtas.h>
#include <asm/oprofile_impl.h>
+#include <asm/reg.h>
#define dbg(args...)
@@ -81,6 +82,26 @@ static void power4_reg_setup(struct op_counter_config *ctr,
extern void ppc64_enable_pmcs(void);
+/*
+ * Older CPUs require the MMCRA sample bit to be always set, but newer
+ * CPUs only want it set for some groups. Eventually we will remove all
+ * knowledge of this bit in the kernel, oprofile userspace should be
+ * setting it when required.
+ *
+ * In order to keep current installations working we force the bit for
+ * those older CPUs. Once everyone has updated their oprofile userspace we
+ * can remove this hack.
+ */
+static inline int mmcra_must_set_sample(void)
+{
+ if (__is_processor(PV_POWER4) || __is_processor(PV_POWER4p) ||
+ __is_processor(PV_970) || __is_processor(PV_970FX) ||
+ __is_processor(PV_970MP))
+ return 1;
+
+ return 0;
+}
+
static void power4_cpu_setup(void *unused)
{
unsigned int mmcr0 = mmcr0_val;
@@ -98,7 +119,8 @@ static void power4_cpu_setup(void *unused)
mtspr(SPRN_MMCR1, mmcr1_val);
- mmcra |= MMCRA_SAMPLE_ENABLE;
+ if (mmcra_must_set_sample())
+ mmcra |= MMCRA_SAMPLE_ENABLE;
mtspr(SPRN_MMCRA, mmcra);
dbg("setup on cpu %d, mmcr0 %lx\n", smp_processor_id(),
@@ -211,8 +233,7 @@ static unsigned long get_pc(struct pt_regs *regs)
mmcra = mfspr(SPRN_MMCRA);
/* Were we in the hypervisor? */
- if ((systemcfg->platform == PLATFORM_PSERIES_LPAR) &&
- (mmcra & MMCRA_SIHV))
+ if (platform_is_lpar() && (mmcra & MMCRA_SIHV))
/* function descriptor madness */
return *((unsigned long *)hypervisor_bucket);
@@ -300,7 +321,7 @@ static void power4_handle_interrupt(struct pt_regs *regs,
mtspr(SPRN_MMCR0, mmcr0);
}
-struct op_ppc64_model op_model_power4 = {
+struct op_powerpc_model op_model_power4 = {
.reg_setup = power4_reg_setup,
.cpu_setup = power4_cpu_setup,
.start = power4_start,
diff --git a/arch/ppc64/oprofile/op_model_rs64.c b/arch/powerpc/oprofile/op_model_rs64.c
index 08c5b333f5c4..e010b85996e8 100644
--- a/arch/ppc64/oprofile/op_model_rs64.c
+++ b/arch/powerpc/oprofile/op_model_rs64.c
@@ -209,7 +209,7 @@ static void rs64_handle_interrupt(struct pt_regs *regs,
mtspr(SPRN_MMCR0, mmcr0);
}
-struct op_ppc64_model op_model_rs64 = {
+struct op_powerpc_model op_model_rs64 = {
.reg_setup = rs64_reg_setup,
.cpu_setup = rs64_cpu_setup,
.start = rs64_start,
diff --git a/arch/powerpc/platforms/4xx/Kconfig b/arch/powerpc/platforms/4xx/Kconfig
new file mode 100644
index 000000000000..ed39d6a3d22a
--- /dev/null
+++ b/arch/powerpc/platforms/4xx/Kconfig
@@ -0,0 +1,280 @@
+config 4xx
+ bool
+ depends on 40x || 44x
+ default y
+
+config WANT_EARLY_SERIAL
+ bool
+ select SERIAL_8250
+ default n
+
+menu "AMCC 4xx options"
+ depends on 4xx
+
+choice
+ prompt "Machine Type"
+ depends on 40x
+ default WALNUT
+
+config BUBINGA
+ bool "Bubinga"
+ select WANT_EARLY_SERIAL
+ help
+ This option enables support for the IBM 405EP evaluation board.
+
+config CPCI405
+ bool "CPCI405"
+ help
+ This option enables support for the CPCI405 board.
+
+config EP405
+ bool "EP405/EP405PC"
+ help
+ This option enables support for the EP405/EP405PC boards.
+
+config REDWOOD_5
+ bool "Redwood-5"
+ help
+ This option enables support for the IBM STB04 evaluation board.
+
+config REDWOOD_6
+ bool "Redwood-6"
+ help
+ This option enables support for the IBM STBx25xx evaluation board.
+
+config SYCAMORE
+ bool "Sycamore"
+ help
+ This option enables support for the IBM PPC405GPr evaluation board.
+
+config WALNUT
+ bool "Walnut"
+ help
+ This option enables support for the IBM PPC405GP evaluation board.
+
+config XILINX_ML300
+ bool "Xilinx-ML300"
+ help
+ This option enables support for the Xilinx ML300 evaluation board.
+
+endchoice
+
+choice
+ prompt "Machine Type"
+ depends on 44x
+ default EBONY
+
+config BAMBOO
+ bool "Bamboo"
+ select WANT_EARLY_SERIAL
+ help
+ This option enables support for the IBM PPC440EP evaluation board.
+
+config EBONY
+ bool "Ebony"
+ select WANT_EARLY_SERIAL
+ help
+ This option enables support for the IBM PPC440GP evaluation board.
+
+config LUAN
+ bool "Luan"
+ select WANT_EARLY_SERIAL
+ help
+ This option enables support for the IBM PPC440SP evaluation board.
+
+config OCOTEA
+ bool "Ocotea"
+ select WANT_EARLY_SERIAL
+ help
+ This option enables support for the IBM PPC440GX evaluation board.
+
+endchoice
+
+config EP405PC
+ bool "EP405PC Support"
+ depends on EP405
+
+
+# It's often necessary to know the specific 4xx processor type.
+# Fortunately, it is impled (so far) from the board type, so we
+# don't need to ask more redundant questions.
+config NP405H
+ bool
+ depends on ASH
+ default y
+
+config 440EP
+ bool
+ depends on BAMBOO
+ select PPC_FPU
+ default y
+
+config 440GP
+ bool
+ depends on EBONY
+ default y
+
+config 440GX
+ bool
+ depends on OCOTEA
+ default y
+
+config 440SP
+ bool
+ depends on LUAN
+ default y
+
+config 440
+ bool
+ depends on 440GP || 440SP || 440EP
+ default y
+
+config 440A
+ bool
+ depends on 440GX
+ default y
+
+config IBM440EP_ERR42
+ bool
+ depends on 440EP
+ default y
+
+# All 405-based cores up until the 405GPR and 405EP have this errata.
+config IBM405_ERR77
+ bool
+ depends on 40x && !403GCX && !405GPR && !405EP
+ default y
+
+# All 40x-based cores, up until the 405GPR and 405EP have this errata.
+config IBM405_ERR51
+ bool
+ depends on 40x && !405GPR && !405EP
+ default y
+
+config BOOKE
+ bool
+ depends on 44x
+ default y
+
+config IBM_OCP
+ bool
+ depends on ASH || BAMBOO || BUBINGA || CPCI405 || EBONY || EP405 || LUAN || OCOTEA || REDWOOD_5 || REDWOOD_6 || SYCAMORE || WALNUT
+ default y
+
+config XILINX_OCP
+ bool
+ depends on XILINX_ML300
+ default y
+
+config IBM_EMAC4
+ bool
+ depends on 440GX || 440SP
+ default y
+
+config BIOS_FIXUP
+ bool
+ depends on BUBINGA || EP405 || SYCAMORE || WALNUT
+ default y
+
+# OAK doesn't exist but wanted to keep this around for any future 403GCX boards
+config 403GCX
+ bool
+ depends OAK
+ default y
+
+config 405EP
+ bool
+ depends on BUBINGA
+ default y
+
+config 405GP
+ bool
+ depends on CPCI405 || EP405 || WALNUT
+ default y
+
+config 405GPR
+ bool
+ depends on SYCAMORE
+ default y
+
+config VIRTEX_II_PRO
+ bool
+ depends on XILINX_ML300
+ default y
+
+config STB03xxx
+ bool
+ depends on REDWOOD_5 || REDWOOD_6
+ default y
+
+config EMBEDDEDBOOT
+ bool
+ depends on EP405 || XILINX_ML300
+ default y
+
+config IBM_OPENBIOS
+ bool
+ depends on ASH || BUBINGA || REDWOOD_5 || REDWOOD_6 || SYCAMORE || WALNUT
+ default y
+
+config PPC4xx_DMA
+ bool "PPC4xx DMA controller support"
+ depends on 4xx
+
+config PPC4xx_EDMA
+ bool
+ depends on !STB03xxx && PPC4xx_DMA
+ default y
+
+config PPC_GEN550
+ bool
+ depends on 4xx
+ default y
+
+choice
+ prompt "TTYS0 device and default console"
+ depends on 40x
+ default UART0_TTYS0
+
+config UART0_TTYS0
+ bool "UART0"
+
+config UART0_TTYS1
+ bool "UART1"
+
+endchoice
+
+config SERIAL_SICC
+ bool "SICC Serial port support"
+ depends on STB03xxx
+
+config UART1_DFLT_CONSOLE
+ bool
+ depends on SERIAL_SICC && UART0_TTYS1
+ default y
+
+config SERIAL_SICC_CONSOLE
+ bool
+ depends on SERIAL_SICC && UART0_TTYS1
+ default y
+endmenu
+
+
+menu "IBM 40x options"
+ depends on 40x
+
+config SERIAL_SICC
+ bool "SICC Serial port"
+ depends on STB03xxx
+
+config UART1_DFLT_CONSOLE
+ bool
+ depends on SERIAL_SICC && UART0_TTYS1
+ default y
+
+config SERIAL_SICC_CONSOLE
+ bool
+ depends on SERIAL_SICC && UART0_TTYS1
+ default y
+
+endmenu
diff --git a/arch/powerpc/platforms/4xx/Makefile b/arch/powerpc/platforms/4xx/Makefile
new file mode 100644
index 000000000000..79ff6b1e887c
--- /dev/null
+++ b/arch/powerpc/platforms/4xx/Makefile
@@ -0,0 +1 @@
+# empty makefile so make clean works \ No newline at end of file
diff --git a/arch/powerpc/platforms/85xx/Kconfig b/arch/powerpc/platforms/85xx/Kconfig
new file mode 100644
index 000000000000..c5bc2821d991
--- /dev/null
+++ b/arch/powerpc/platforms/85xx/Kconfig
@@ -0,0 +1,86 @@
+config 85xx
+ bool
+ depends on E500
+ default y
+
+config PPC_INDIRECT_PCI_BE
+ bool
+ depends on 85xx
+ default y
+
+menu "Freescale 85xx options"
+ depends on E500
+
+choice
+ prompt "Machine Type"
+ depends on 85xx
+ default MPC8540_ADS
+
+config MPC8540_ADS
+ bool "Freescale MPC8540 ADS"
+ help
+ This option enables support for the MPC 8540 ADS evaluation board.
+
+config MPC8548_CDS
+ bool "Freescale MPC8548 CDS"
+ help
+ This option enablese support for the MPC8548 CDS evaluation board.
+
+config MPC8555_CDS
+ bool "Freescale MPC8555 CDS"
+ help
+ This option enablese support for the MPC8555 CDS evaluation board.
+
+config MPC8560_ADS
+ bool "Freescale MPC8560 ADS"
+ help
+ This option enables support for the MPC 8560 ADS evaluation board.
+
+config SBC8560
+ bool "WindRiver PowerQUICC III SBC8560"
+ help
+ This option enables support for the WindRiver PowerQUICC III
+ SBC8560 board.
+
+config STX_GP3
+ bool "Silicon Turnkey Express GP3"
+ help
+ This option enables support for the Silicon Turnkey Express GP3
+ board.
+
+endchoice
+
+# It's often necessary to know the specific 85xx processor type.
+# Fortunately, it is implied (so far) from the board type, so we
+# don't need to ask more redundant questions.
+config MPC8540
+ bool
+ depends on MPC8540_ADS
+ default y
+
+config MPC8548
+ bool
+ depends on MPC8548_CDS
+ default y
+
+config MPC8555
+ bool
+ depends on MPC8555_CDS
+ default y
+
+config MPC8560
+ bool
+ depends on SBC8560 || MPC8560_ADS || STX_GP3
+ default y
+
+config 85xx_PCI2
+ bool "Supprt for 2nd PCI host controller"
+ depends on MPC8555_CDS
+ default y
+
+config PPC_GEN550
+ bool
+ depends on MPC8540 || SBC8560 || MPC8555
+ default y
+
+endmenu
diff --git a/arch/powerpc/platforms/85xx/Makefile b/arch/powerpc/platforms/85xx/Makefile
new file mode 100644
index 000000000000..6407197ffd89
--- /dev/null
+++ b/arch/powerpc/platforms/85xx/Makefile
@@ -0,0 +1 @@
+# empty makefile so make clean works
diff --git a/arch/powerpc/platforms/8xx/Kconfig b/arch/powerpc/platforms/8xx/Kconfig
new file mode 100644
index 000000000000..c8c0ba3cf8e8
--- /dev/null
+++ b/arch/powerpc/platforms/8xx/Kconfig
@@ -0,0 +1,352 @@
+config FADS
+ bool
+
+choice
+ prompt "8xx Machine Type"
+ depends on 8xx
+ default RPXLITE
+
+config RPXLITE
+ bool "RPX-Lite"
+ ---help---
+ Single-board computers based around the PowerPC MPC8xx chips and
+ intended for embedded applications. The following types are
+ supported:
+
+ RPX-Lite:
+ Embedded Planet RPX Lite. PC104 form-factor SBC based on the MPC823.
+
+ RPX-Classic:
+ Embedded Planet RPX Classic Low-fat. Credit-card-size SBC based on
+ the MPC 860
+
+ BSE-IP:
+ Bright Star Engineering ip-Engine.
+
+ TQM823L:
+ TQM850L:
+ TQM855L:
+ TQM860L:
+ MPC8xx based family of mini modules, half credit card size,
+ up to 64 MB of RAM, 8 MB Flash, (Fast) Ethernet, 2 x serial ports,
+ 2 x CAN bus interface, ...
+ Manufacturer: TQ Components, www.tq-group.de
+ Date of Release: October (?) 1999
+ End of Life: not yet :-)
+ URL:
+ - module: <http://www.denx.de/PDF/TQM8xxLHWM201.pdf>
+ - starter kit: <http://www.denx.de/PDF/STK8xxLHWM201.pdf>
+ - images: <http://www.denx.de/embedded-ppc-en.html>
+
+ FPS850L:
+ FingerPrint Sensor System (based on TQM850L)
+ Manufacturer: IKENDI AG, <http://www.ikendi.com/>
+ Date of Release: November 1999
+ End of life: end 2000 ?
+ URL: see TQM850L
+
+ IVMS8:
+ MPC860 based board used in the "Integrated Voice Mail System",
+ Small Version (8 voice channels)
+ Manufacturer: Speech Design, <http://www.speech-design.de/>
+ Date of Release: December 2000 (?)
+ End of life: -
+ URL: <http://www.speech-design.de/>
+
+ IVML24:
+ MPC860 based board used in the "Integrated Voice Mail System",
+ Large Version (24 voice channels)
+ Manufacturer: Speech Design, <http://www.speech-design.de/>
+ Date of Release: March 2001 (?)
+ End of life: -
+ URL: <http://www.speech-design.de/>
+
+ HERMES:
+ Hermes-Pro ISDN/LAN router with integrated 8 x hub
+ Manufacturer: Multidata Gesellschaft fur Datentechnik und Informatik
+ <http://www.multidata.de/>
+ Date of Release: 2000 (?)
+ End of life: -
+ URL: <http://www.multidata.de/english/products/hpro.htm>
+
+ IP860:
+ VMEBus IP (Industry Pack) carrier board with MPC860
+ Manufacturer: MicroSys GmbH, <http://www.microsys.de/>
+ Date of Release: ?
+ End of life: -
+ URL: <http://www.microsys.de/html/ip860.html>
+
+ PCU_E:
+ PCU = Peripheral Controller Unit, Extended
+ Manufacturer: Siemens AG, ICN (Information and Communication Networks)
+ <http://www.siemens.de/page/1,3771,224315-1-999_2_226207-0,00.html>
+ Date of Release: April 2001
+ End of life: August 2001
+ URL: n. a.
+
+config RPXCLASSIC
+ bool "RPX-Classic"
+ help
+ The RPX-Classic is a single-board computer based on the Motorola
+ MPC860. It features 16MB of DRAM and a variable amount of flash,
+ I2C EEPROM, thermal monitoring, a PCMCIA slot, a DIP switch and two
+ LEDs. Variants with Ethernet ports exist. Say Y here to support it
+ directly.
+
+config BSEIP
+ bool "BSE-IP"
+ help
+ Say Y here to support the Bright Star Engineering ipEngine SBC.
+ This is a credit-card-sized device featuring a MPC823 processor,
+ 26MB DRAM, 4MB flash, Ethernet, a 16K-gate FPGA, USB, an LCD/video
+ controller, and two RS232 ports.
+
+config MPC8XXFADS
+ bool "FADS"
+ select FADS
+
+config MPC86XADS
+ bool "MPC86XADS"
+ help
+ MPC86x Application Development System by Freescale Semiconductor.
+ The MPC86xADS is meant to serve as a platform for s/w and h/w
+ development around the MPC86X processor families.
+ select FADS
+
+config MPC885ADS
+ bool "MPC885ADS"
+ help
+ Freescale Semiconductor MPC885 Application Development System (ADS).
+ Also known as DUET.
+ The MPC885ADS is meant to serve as a platform for s/w and h/w
+ development around the MPC885 processor family.
+
+config TQM823L
+ bool "TQM823L"
+ help
+ Say Y here to support the TQM823L, one of an MPC8xx-based family of
+ mini SBCs (half credit-card size) from TQ Components first released
+ in late 1999. Technical references are at
+ <http://www.denx.de/PDF/TQM8xxLHWM201.pdf>, and
+ <http://www.denx.de/PDF/STK8xxLHWM201.pdf>, and an image at
+ <http://www.denx.de/embedded-ppc-en.html>.
+
+config TQM850L
+ bool "TQM850L"
+ help
+ Say Y here to support the TQM850L, one of an MPC8xx-based family of
+ mini SBCs (half credit-card size) from TQ Components first released
+ in late 1999. Technical references are at
+ <http://www.denx.de/PDF/TQM8xxLHWM201.pdf>, and
+ <http://www.denx.de/PDF/STK8xxLHWM201.pdf>, and an image at
+ <http://www.denx.de/embedded-ppc-en.html>.
+
+config TQM855L
+ bool "TQM855L"
+ help
+ Say Y here to support the TQM855L, one of an MPC8xx-based family of
+ mini SBCs (half credit-card size) from TQ Components first released
+ in late 1999. Technical references are at
+ <http://www.denx.de/PDF/TQM8xxLHWM201.pdf>, and
+ <http://www.denx.de/PDF/STK8xxLHWM201.pdf>, and an image at
+ <http://www.denx.de/embedded-ppc-en.html>.
+
+config TQM860L
+ bool "TQM860L"
+ help
+ Say Y here to support the TQM860L, one of an MPC8xx-based family of
+ mini SBCs (half credit-card size) from TQ Components first released
+ in late 1999. Technical references are at
+ <http://www.denx.de/PDF/TQM8xxLHWM201.pdf>, and
+ <http://www.denx.de/PDF/STK8xxLHWM201.pdf>, and an image at
+ <http://www.denx.de/embedded-ppc-en.html>.
+
+config FPS850L
+ bool "FPS850L"
+
+config IVMS8
+ bool "IVMS8"
+ help
+ Say Y here to support the Integrated Voice-Mail Small 8-channel SBC
+ from Speech Design, released March 2001. The manufacturer's website
+ is at <http://www.speech-design.de/>.
+
+config IVML24
+ bool "IVML24"
+ help
+ Say Y here to support the Integrated Voice-Mail Large 24-channel SBC
+ from Speech Design, released March 2001. The manufacturer's website
+ is at <http://www.speech-design.de/>.
+
+config HERMES_PRO
+ bool "HERMES"
+
+config IP860
+ bool "IP860"
+
+config LWMON
+ bool "LWMON"
+
+config PCU_E
+ bool "PCU_E"
+
+config CCM
+ bool "CCM"
+
+config LANTEC
+ bool "LANTEC"
+
+config MBX
+ bool "MBX"
+ help
+ MBX is a line of Motorola single-board computer based around the
+ MPC821 and MPC860 processors, and intended for embedded-controller
+ applications. Say Y here to support these boards directly.
+
+config WINCEPT
+ bool "WinCept"
+ help
+ The Wincept 100/110 is a Motorola single-board computer based on the
+ MPC821 PowerPC, introduced in 1998 and designed to be used in
+ thin-client machines. Say Y to support it directly.
+
+endchoice
+
+#
+# MPC8xx Communication options
+#
+
+menu "MPC8xx CPM Options"
+ depends on 8xx
+
+config SCC_ENET
+ bool "CPM SCC Ethernet"
+ depends on NET_ETHERNET
+ help
+ Enable Ethernet support via the Motorola MPC8xx serial
+ communications controller.
+
+choice
+ prompt "SCC used for Ethernet"
+ depends on SCC_ENET
+ default SCC1_ENET
+
+config SCC1_ENET
+ bool "SCC1"
+ help
+ Use MPC8xx serial communications controller 1 to drive Ethernet
+ (default).
+
+config SCC2_ENET
+ bool "SCC2"
+ help
+ Use MPC8xx serial communications controller 2 to drive Ethernet.
+
+config SCC3_ENET
+ bool "SCC3"
+ help
+ Use MPC8xx serial communications controller 3 to drive Ethernet.
+
+endchoice
+
+config FEC_ENET
+ bool "860T FEC Ethernet"
+ depends on NET_ETHERNET
+ help
+ Enable Ethernet support via the Fast Ethernet Controller (FCC) on
+ the Motorola MPC8260.
+
+config USE_MDIO
+ bool "Use MDIO for PHY configuration"
+ depends on FEC_ENET
+ help
+ On some boards the hardware configuration of the ethernet PHY can be
+ used without any software interaction over the MDIO interface, so
+ all MII code can be omitted. Say N here if unsure or if you don't
+ need link status reports.
+
+config FEC_AM79C874
+ bool "Support AMD79C874 PHY"
+ depends on USE_MDIO
+
+config FEC_LXT970
+ bool "Support LXT970 PHY"
+ depends on USE_MDIO
+
+config FEC_LXT971
+ bool "Support LXT971 PHY"
+ depends on USE_MDIO
+
+config FEC_QS6612
+ bool "Support QS6612 PHY"
+ depends on USE_MDIO
+
+config ENET_BIG_BUFFERS
+ bool "Use Big CPM Ethernet Buffers"
+ depends on SCC_ENET || FEC_ENET
+ help
+ Allocate large buffers for MPC8xx Ethernet. Increases throughput
+ and decreases the likelihood of dropped packets, but costs memory.
+
+config HTDMSOUND
+ bool "Embedded Planet HIOX Audio"
+ depends on SOUND=y
+
+# This doesn't really belong here, but it is convenient to ask
+# 8xx specific questions.
+comment "Generic MPC8xx Options"
+
+config 8xx_COPYBACK
+ bool "Copy-Back Data Cache (else Writethrough)"
+ help
+ Saying Y here will cause the cache on an MPC8xx processor to be used
+ in Copy-Back mode. If you say N here, it is used in Writethrough
+ mode.
+
+ If in doubt, say Y here.
+
+config 8xx_CPU6
+ bool "CPU6 Silicon Errata (860 Pre Rev. C)"
+ help
+ MPC860 CPUs, prior to Rev C have some bugs in the silicon, which
+ require workarounds for Linux (and most other OSes to work). If you
+ get a BUG() very early in boot, this might fix the problem. For
+ more details read the document entitled "MPC860 Family Device Errata
+ Reference" on Motorola's website. This option also incurs a
+ performance hit.
+
+ If in doubt, say N here.
+
+choice
+ prompt "Microcode patch selection"
+ default NO_UCODE_PATCH
+ help
+ Help not implemented yet, coming soon.
+
+config NO_UCODE_PATCH
+ bool "None"
+
+config USB_SOF_UCODE_PATCH
+ bool "USB SOF patch"
+ help
+ Help not implemented yet, coming soon.
+
+config I2C_SPI_UCODE_PATCH
+ bool "I2C/SPI relocation patch"
+ help
+ Help not implemented yet, coming soon.
+
+config I2C_SPI_SMC1_UCODE_PATCH
+ bool "I2C/SPI/SMC1 relocation patch"
+ help
+ Help not implemented yet, coming soon.
+
+endchoice
+
+config UCODE_PATCH
+ bool
+ default y
+ depends on !NO_UCODE_PATCH
+
+endmenu
+
diff --git a/arch/powerpc/platforms/Makefile b/arch/powerpc/platforms/Makefile
new file mode 100644
index 000000000000..8836b3a00668
--- /dev/null
+++ b/arch/powerpc/platforms/Makefile
@@ -0,0 +1,14 @@
+ifeq ($(CONFIG_PPC_MERGE),y)
+obj-$(CONFIG_PPC_PMAC) += powermac/
+else
+ifeq ($(CONFIG_PPC64),y)
+obj-$(CONFIG_PPC_PMAC) += powermac/
+endif
+endif
+obj-$(CONFIG_PPC_CHRP) += chrp/
+obj-$(CONFIG_4xx) += 4xx/
+obj-$(CONFIG_85xx) += 85xx/
+obj-$(CONFIG_PPC_PSERIES) += pseries/
+obj-$(CONFIG_PPC_ISERIES) += iseries/
+obj-$(CONFIG_PPC_MAPLE) += maple/
+obj-$(CONFIG_PPC_CELL) += cell/
diff --git a/arch/powerpc/platforms/apus/Kconfig b/arch/powerpc/platforms/apus/Kconfig
new file mode 100644
index 000000000000..6bde3bffed86
--- /dev/null
+++ b/arch/powerpc/platforms/apus/Kconfig
@@ -0,0 +1,130 @@
+
+config AMIGA
+ bool
+ depends on APUS
+ default y
+ help
+ This option enables support for the Amiga series of computers.
+
+config ZORRO
+ bool
+ depends on APUS
+ default y
+ help
+ This enables support for the Zorro bus in the Amiga. If you have
+ expansion cards in your Amiga that conform to the Amiga
+ AutoConfig(tm) specification, say Y, otherwise N. Note that even
+ expansion cards that do not fit in the Zorro slots but fit in e.g.
+ the CPU slot may fall in this category, so you have to say Y to let
+ Linux use these.
+
+config ABSTRACT_CONSOLE
+ bool
+ depends on APUS
+ default y
+
+config APUS_FAST_EXCEPT
+ bool
+ depends on APUS
+ default y
+
+config AMIGA_PCMCIA
+ bool "Amiga 1200/600 PCMCIA support"
+ depends on APUS && EXPERIMENTAL
+ help
+ Include support in the kernel for pcmcia on Amiga 1200 and Amiga
+ 600. If you intend to use pcmcia cards say Y; otherwise say N.
+
+config AMIGA_BUILTIN_SERIAL
+ tristate "Amiga builtin serial support"
+ depends on APUS
+ help
+ If you want to use your Amiga's built-in serial port in Linux,
+ answer Y.
+
+ To compile this driver as a module, choose M here.
+
+config GVPIOEXT
+ tristate "GVP IO-Extender support"
+ depends on APUS
+ help
+ If you want to use a GVP IO-Extender serial card in Linux, say Y.
+ Otherwise, say N.
+
+config GVPIOEXT_LP
+ tristate "GVP IO-Extender parallel printer support"
+ depends on GVPIOEXT
+ help
+ Say Y to enable driving a printer from the parallel port on your
+ GVP IO-Extender card, N otherwise.
+
+config GVPIOEXT_PLIP
+ tristate "GVP IO-Extender PLIP support"
+ depends on GVPIOEXT
+ help
+ Say Y to enable doing IP over the parallel port on your GVP
+ IO-Extender card, N otherwise.
+
+config MULTIFACE_III_TTY
+ tristate "Multiface Card III serial support"
+ depends on APUS
+ help
+ If you want to use a Multiface III card's serial port in Linux,
+ answer Y.
+
+ To compile this driver as a module, choose M here.
+
+config A2232
+ tristate "Commodore A2232 serial support (EXPERIMENTAL)"
+ depends on EXPERIMENTAL && APUS
+ ---help---
+ This option supports the 2232 7-port serial card shipped with the
+ Amiga 2000 and other Zorro-bus machines, dating from 1989. At
+ a max of 19,200 bps, the ports are served by a 6551 ACIA UART chip
+ each, plus a 8520 CIA, and a master 6502 CPU and buffer as well. The
+ ports were connected with 8 pin DIN connectors on the card bracket,
+ for which 8 pin to DB25 adapters were supplied. The card also had
+ jumpers internally to toggle various pinning configurations.
+
+ This driver can be built as a module; but then "generic_serial"
+ will also be built as a module. This has to be loaded before
+ "ser_a2232". If you want to do this, answer M here.
+
+config WHIPPET_SERIAL
+ tristate "Hisoft Whippet PCMCIA serial support"
+ depends on AMIGA_PCMCIA
+ help
+ HiSoft has a web page at <http://www.hisoft.co.uk/>, but there
+ is no listing for the Whippet in their Amiga section.
+
+config APNE
+ tristate "PCMCIA NE2000 support"
+ depends on AMIGA_PCMCIA
+ help
+ If you have a PCMCIA NE2000 compatible adapter, say Y. Otherwise,
+ say N.
+
+ To compile this driver as a module, choose M here: the
+ module will be called apne.
+
+config SERIAL_CONSOLE
+ bool "Support for serial port console"
+ depends on APUS && (AMIGA_BUILTIN_SERIAL=y || GVPIOEXT=y || MULTIFACE_III_TTY=y)
+
+config HEARTBEAT
+ bool "Use power LED as a heartbeat"
+ depends on APUS
+ help
+ Use the power-on LED on your machine as a load meter. The exact
+ behavior is platform-dependent, but normally the flash frequency is
+ a hyperbolic function of the 5-minute load average.
+
+config PROC_HARDWARE
+ bool "/proc/hardware support"
+ depends on APUS
+
+source "drivers/zorro/Kconfig"
+
+config PCI_PERMEDIA
+ bool "PCI for Permedia2"
+ depends on !4xx && !8xx && APUS
diff --git a/arch/powerpc/platforms/cell/Makefile b/arch/powerpc/platforms/cell/Makefile
new file mode 100644
index 000000000000..55e094b96bc0
--- /dev/null
+++ b/arch/powerpc/platforms/cell/Makefile
@@ -0,0 +1,2 @@
+obj-y += interrupt.o iommu.o setup.o spider-pic.o
+obj-$(CONFIG_SMP) += smp.o
diff --git a/arch/ppc64/kernel/bpa_iic.c b/arch/powerpc/platforms/cell/interrupt.c
index 0aaa878e19d3..7fbe78a9327d 100644
--- a/arch/ppc64/kernel/bpa_iic.c
+++ b/arch/powerpc/platforms/cell/interrupt.c
@@ -1,5 +1,5 @@
/*
- * BPA Internal Interrupt Controller
+ * Cell Internal Interrupt Controller
*
* (C) Copyright IBM Deutschland Entwicklung GmbH 2005
*
@@ -31,7 +31,7 @@
#include <asm/prom.h>
#include <asm/ptrace.h>
-#include "bpa_iic.h"
+#include "interrupt.h"
struct iic_pending_bits {
u32 data;
@@ -89,7 +89,7 @@ static void iic_end(unsigned int irq)
}
static struct hw_interrupt_type iic_pic = {
- .typename = " BPA-IIC ",
+ .typename = " CELL-IIC ",
.startup = iic_startup,
.enable = iic_enable,
.disable = iic_disable,
@@ -106,7 +106,7 @@ static int iic_external_get_irq(struct iic_pending_bits pending)
irq = -1;
/*
- * This mapping is specific to the Broadband
+ * This mapping is specific to the Cell Broadband
* Engine. We might need to get the numbers
* from the device tree to support future CPUs.
*/
diff --git a/arch/ppc64/kernel/bpa_iic.h b/arch/powerpc/platforms/cell/interrupt.h
index 6833c3022166..37d58e6fd0c6 100644
--- a/arch/ppc64/kernel/bpa_iic.h
+++ b/arch/powerpc/platforms/cell/interrupt.h
@@ -1,5 +1,5 @@
-#ifndef ASM_BPA_IIC_H
-#define ASM_BPA_IIC_H
+#ifndef ASM_CELL_PIC_H
+#define ASM_CELL_PIC_H
#ifdef __KERNEL__
/*
* Mapping of IIC pending bits into per-node
@@ -21,7 +21,7 @@
* + node number
* * don't care
*
- * A node consists of a Broadband Engine and an optional
+ * A node consists of a Cell Broadband Engine and an optional
* south bridge device providing a maximum of 64 IRQs.
* The south bridge may be connected to either IOIF0
* or IOIF1.
@@ -59,4 +59,4 @@ extern void spider_init_IRQ(void);
extern int spider_get_irq(unsigned long int_pending);
#endif
-#endif /* ASM_BPA_IIC_H */
+#endif /* ASM_CELL_PIC_H */
diff --git a/arch/ppc64/kernel/bpa_iommu.c b/arch/powerpc/platforms/cell/iommu.c
index 5f2460090e03..74f999b4ac9e 100644
--- a/arch/ppc64/kernel/bpa_iommu.c
+++ b/arch/powerpc/platforms/cell/iommu.c
@@ -1,5 +1,5 @@
/*
- * IOMMU implementation for Broadband Processor Architecture
+ * IOMMU implementation for Cell Broadband Processor Architecture
* We just establish a linear mapping at boot by setting all the
* IOPT cache entries in the CPU.
* The mapping functions should be identical to pci_direct_iommu,
@@ -39,9 +39,9 @@
#include <asm/pmac_feature.h>
#include <asm/abs_addr.h>
#include <asm/system.h>
+#include <asm/ppc-pci.h>
-#include "pci.h"
-#include "bpa_iommu.h"
+#include "iommu.h"
static inline unsigned long
get_iopt_entry(unsigned long real_address, unsigned long ioid,
@@ -276,7 +276,7 @@ static void iommu_dev_setup_null(struct pci_dev *d) { }
* for each DMA window used by any device. For now, we
* happen to know that there is only one DMA window in use,
* starting at iopt_phys_offset. */
-static void bpa_map_iommu(void)
+static void cell_map_iommu(void)
{
unsigned long address;
void __iomem *base;
@@ -309,7 +309,7 @@ static void bpa_map_iommu(void)
}
-static void *bpa_alloc_coherent(struct device *hwdev, size_t size,
+static void *cell_alloc_coherent(struct device *hwdev, size_t size,
dma_addr_t *dma_handle, gfp_t flag)
{
void *ret;
@@ -317,65 +317,65 @@ static void *bpa_alloc_coherent(struct device *hwdev, size_t size,
ret = (void *)__get_free_pages(flag, get_order(size));
if (ret != NULL) {
memset(ret, 0, size);
- *dma_handle = virt_to_abs(ret) | BPA_DMA_VALID;
+ *dma_handle = virt_to_abs(ret) | CELL_DMA_VALID;
}
return ret;
}
-static void bpa_free_coherent(struct device *hwdev, size_t size,
+static void cell_free_coherent(struct device *hwdev, size_t size,
void *vaddr, dma_addr_t dma_handle)
{
free_pages((unsigned long)vaddr, get_order(size));
}
-static dma_addr_t bpa_map_single(struct device *hwdev, void *ptr,
+static dma_addr_t cell_map_single(struct device *hwdev, void *ptr,
size_t size, enum dma_data_direction direction)
{
- return virt_to_abs(ptr) | BPA_DMA_VALID;
+ return virt_to_abs(ptr) | CELL_DMA_VALID;
}
-static void bpa_unmap_single(struct device *hwdev, dma_addr_t dma_addr,
+static void cell_unmap_single(struct device *hwdev, dma_addr_t dma_addr,
size_t size, enum dma_data_direction direction)
{
}
-static int bpa_map_sg(struct device *hwdev, struct scatterlist *sg,
+static int cell_map_sg(struct device *hwdev, struct scatterlist *sg,
int nents, enum dma_data_direction direction)
{
int i;
for (i = 0; i < nents; i++, sg++) {
sg->dma_address = (page_to_phys(sg->page) + sg->offset)
- | BPA_DMA_VALID;
+ | CELL_DMA_VALID;
sg->dma_length = sg->length;
}
return nents;
}
-static void bpa_unmap_sg(struct device *hwdev, struct scatterlist *sg,
+static void cell_unmap_sg(struct device *hwdev, struct scatterlist *sg,
int nents, enum dma_data_direction direction)
{
}
-static int bpa_dma_supported(struct device *dev, u64 mask)
+static int cell_dma_supported(struct device *dev, u64 mask)
{
return mask < 0x100000000ull;
}
-void bpa_init_iommu(void)
+void cell_init_iommu(void)
{
- bpa_map_iommu();
+ cell_map_iommu();
/* Direct I/O, IOMMU off */
ppc_md.iommu_dev_setup = iommu_dev_setup_null;
ppc_md.iommu_bus_setup = iommu_bus_setup_null;
- pci_dma_ops.alloc_coherent = bpa_alloc_coherent;
- pci_dma_ops.free_coherent = bpa_free_coherent;
- pci_dma_ops.map_single = bpa_map_single;
- pci_dma_ops.unmap_single = bpa_unmap_single;
- pci_dma_ops.map_sg = bpa_map_sg;
- pci_dma_ops.unmap_sg = bpa_unmap_sg;
- pci_dma_ops.dma_supported = bpa_dma_supported;
+ pci_dma_ops.alloc_coherent = cell_alloc_coherent;
+ pci_dma_ops.free_coherent = cell_free_coherent;
+ pci_dma_ops.map_single = cell_map_single;
+ pci_dma_ops.unmap_single = cell_unmap_single;
+ pci_dma_ops.map_sg = cell_map_sg;
+ pci_dma_ops.unmap_sg = cell_unmap_sg;
+ pci_dma_ops.dma_supported = cell_dma_supported;
}
diff --git a/arch/ppc64/kernel/bpa_iommu.h b/arch/powerpc/platforms/cell/iommu.h
index e547d77dfa04..490d77abfe85 100644
--- a/arch/ppc64/kernel/bpa_iommu.h
+++ b/arch/powerpc/platforms/cell/iommu.h
@@ -1,5 +1,5 @@
-#ifndef BPA_IOMMU_H
-#define BPA_IOMMU_H
+#ifndef CELL_IOMMU_H
+#define CELL_IOMMU_H
/* some constants */
enum {
@@ -55,11 +55,11 @@ enum {
/* The high bit needs to be set on every DMA address,
only 2GB are addressable */
- BPA_DMA_VALID = 0x80000000,
- BPA_DMA_MASK = 0x7fffffff,
+ CELL_DMA_VALID = 0x80000000,
+ CELL_DMA_MASK = 0x7fffffff,
};
-void bpa_init_iommu(void);
+void cell_init_iommu(void);
#endif
diff --git a/arch/ppc64/kernel/bpa_setup.c b/arch/powerpc/platforms/cell/setup.c
index 57b3db66f458..9a495634d0c2 100644
--- a/arch/ppc64/kernel/bpa_setup.c
+++ b/arch/powerpc/platforms/cell/setup.c
@@ -1,11 +1,11 @@
/*
- * linux/arch/ppc/kernel/bpa_setup.c
+ * linux/arch/powerpc/platforms/cell/cell_setup.c
*
* Copyright (C) 1995 Linus Torvalds
* Adapted from 'alpha' version by Gary Thomas
* Modified by Cort Dougan (cort@cs.nmt.edu)
* Modified by PPC64 Team, IBM Corp
- * Modified by BPA Team, IBM Deutschland Entwicklung GmbH
+ * Modified by Cell Team, IBM Deutschland Entwicklung GmbH
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -43,10 +43,11 @@
#include <asm/time.h>
#include <asm/nvram.h>
#include <asm/cputable.h>
+#include <asm/ppc-pci.h>
+#include <asm/irq.h>
-#include "pci.h"
-#include "bpa_iic.h"
-#include "bpa_iommu.h"
+#include "interrupt.h"
+#include "iommu.h"
#ifdef DEBUG
#define DBG(fmt...) udbg_printf(fmt)
@@ -54,7 +55,7 @@
#define DBG(fmt...)
#endif
-void bpa_get_cpuinfo(struct seq_file *m)
+void cell_show_cpuinfo(struct seq_file *m)
{
struct device_node *root;
const char *model = "";
@@ -62,22 +63,22 @@ void bpa_get_cpuinfo(struct seq_file *m)
root = of_find_node_by_path("/");
if (root)
model = get_property(root, "model", NULL);
- seq_printf(m, "machine\t\t: BPA %s\n", model);
+ seq_printf(m, "machine\t\t: CHRP %s\n", model);
of_node_put(root);
}
-static void bpa_progress(char *s, unsigned short hex)
+static void cell_progress(char *s, unsigned short hex)
{
printk("*** %04x : %s\n", hex, s ? s : "");
}
-static void __init bpa_setup_arch(void)
+static void __init cell_setup_arch(void)
{
ppc_md.init_IRQ = iic_init_IRQ;
ppc_md.get_irq = iic_get_irq;
#ifdef CONFIG_SMP
- smp_init_pSeries();
+ smp_init_cell();
#endif
/* init to some ~sane value until calibrate_delay() runs */
@@ -96,39 +97,39 @@ static void __init bpa_setup_arch(void)
conswitchp = &dummy_con;
#endif
- bpa_nvram_init();
+ mmio_nvram_init();
}
/*
* Early initialization. Relocation is on but do not reference unbolted pages
*/
-static void __init bpa_init_early(void)
+static void __init cell_init_early(void)
{
- DBG(" -> bpa_init_early()\n");
+ DBG(" -> cell_init_early()\n");
hpte_init_native();
- bpa_init_iommu();
+ cell_init_iommu();
- ppc64_interrupt_controller = IC_BPA_IIC;
+ ppc64_interrupt_controller = IC_CELL_PIC;
- DBG(" <- bpa_init_early()\n");
+ DBG(" <- cell_init_early()\n");
}
-static int __init bpa_probe(int platform)
+static int __init cell_probe(int platform)
{
- if (platform != PLATFORM_BPA)
+ if (platform != PLATFORM_CELL)
return 0;
return 1;
}
-struct machdep_calls __initdata bpa_md = {
- .probe = bpa_probe,
- .setup_arch = bpa_setup_arch,
- .init_early = bpa_init_early,
- .get_cpuinfo = bpa_get_cpuinfo,
+struct machdep_calls __initdata cell_md = {
+ .probe = cell_probe,
+ .setup_arch = cell_setup_arch,
+ .init_early = cell_init_early,
+ .show_cpuinfo = cell_show_cpuinfo,
.restart = rtas_restart,
.power_off = rtas_power_off,
.halt = rtas_halt,
@@ -136,5 +137,5 @@ struct machdep_calls __initdata bpa_md = {
.get_rtc_time = rtas_get_rtc_time,
.set_rtc_time = rtas_set_rtc_time,
.calibrate_decr = generic_calibrate_decr,
- .progress = bpa_progress,
+ .progress = cell_progress,
};
diff --git a/arch/powerpc/platforms/cell/smp.c b/arch/powerpc/platforms/cell/smp.c
new file mode 100644
index 000000000000..de96eadf419d
--- /dev/null
+++ b/arch/powerpc/platforms/cell/smp.c
@@ -0,0 +1,230 @@
+/*
+ * SMP support for BPA machines.
+ *
+ * Dave Engebretsen, Peter Bergner, and
+ * Mike Corrigan {engebret|bergner|mikec}@us.ibm.com
+ *
+ * Plus various changes from other IBM teams...
+ *
+ * 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.
+ */
+
+#undef DEBUG
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/smp.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/spinlock.h>
+#include <linux/cache.h>
+#include <linux/err.h>
+#include <linux/sysdev.h>
+#include <linux/cpu.h>
+
+#include <asm/ptrace.h>
+#include <asm/atomic.h>
+#include <asm/irq.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/io.h>
+#include <asm/prom.h>
+#include <asm/smp.h>
+#include <asm/paca.h>
+#include <asm/time.h>
+#include <asm/machdep.h>
+#include <asm/cputable.h>
+#include <asm/firmware.h>
+#include <asm/system.h>
+#include <asm/rtas.h>
+
+#include "interrupt.h"
+
+#ifdef DEBUG
+#define DBG(fmt...) udbg_printf(fmt)
+#else
+#define DBG(fmt...)
+#endif
+
+/*
+ * The primary thread of each non-boot processor is recorded here before
+ * smp init.
+ */
+static cpumask_t of_spin_map;
+
+extern void pSeries_secondary_smp_init(unsigned long);
+
+/**
+ * smp_startup_cpu() - start the given cpu
+ *
+ * At boot time, there is nothing to do for primary threads which were
+ * started from Open Firmware. For anything else, call RTAS with the
+ * appropriate start location.
+ *
+ * Returns:
+ * 0 - failure
+ * 1 - success
+ */
+static inline int __devinit smp_startup_cpu(unsigned int lcpu)
+{
+ int status;
+ unsigned long start_here = __pa((u32)*((unsigned long *)
+ pSeries_secondary_smp_init));
+ unsigned int pcpu;
+ int start_cpu;
+
+ if (cpu_isset(lcpu, of_spin_map))
+ /* Already started by OF and sitting in spin loop */
+ return 1;
+
+ pcpu = get_hard_smp_processor_id(lcpu);
+
+ /* Fixup atomic count: it exited inside IRQ handler. */
+ paca[lcpu].__current->thread_info->preempt_count = 0;
+
+ /*
+ * If the RTAS start-cpu token does not exist then presume the
+ * cpu is already spinning.
+ */
+ start_cpu = rtas_token("start-cpu");
+ if (start_cpu == RTAS_UNKNOWN_SERVICE)
+ return 1;
+
+ status = rtas_call(start_cpu, 3, 1, NULL, pcpu, start_here, lcpu);
+ if (status != 0) {
+ printk(KERN_ERR "start-cpu failed: %i\n", status);
+ return 0;
+ }
+
+ return 1;
+}
+
+static void smp_iic_message_pass(int target, int msg)
+{
+ unsigned int i;
+
+ if (target < NR_CPUS) {
+ iic_cause_IPI(target, msg);
+ } else {
+ for_each_online_cpu(i) {
+ if (target == MSG_ALL_BUT_SELF
+ && i == smp_processor_id())
+ continue;
+ iic_cause_IPI(i, msg);
+ }
+ }
+}
+
+static int __init smp_iic_probe(void)
+{
+ iic_request_IPIs();
+
+ return cpus_weight(cpu_possible_map);
+}
+
+static void __devinit smp_iic_setup_cpu(int cpu)
+{
+ if (cpu != boot_cpuid)
+ iic_setup_cpu();
+}
+
+static DEFINE_SPINLOCK(timebase_lock);
+static unsigned long timebase = 0;
+
+static void __devinit cell_give_timebase(void)
+{
+ spin_lock(&timebase_lock);
+ rtas_call(rtas_token("freeze-time-base"), 0, 1, NULL);
+ timebase = get_tb();
+ spin_unlock(&timebase_lock);
+
+ while (timebase)
+ barrier();
+ rtas_call(rtas_token("thaw-time-base"), 0, 1, NULL);
+}
+
+static void __devinit cell_take_timebase(void)
+{
+ while (!timebase)
+ barrier();
+ spin_lock(&timebase_lock);
+ set_tb(timebase >> 32, timebase & 0xffffffff);
+ timebase = 0;
+ spin_unlock(&timebase_lock);
+}
+
+static void __devinit smp_cell_kick_cpu(int nr)
+{
+ BUG_ON(nr < 0 || nr >= NR_CPUS);
+
+ if (!smp_startup_cpu(nr))
+ return;
+
+ /*
+ * The processor is currently spinning, waiting for the
+ * cpu_start field to become non-zero After we set cpu_start,
+ * the processor will continue on to secondary_start
+ */
+ paca[nr].cpu_start = 1;
+}
+
+static int smp_cell_cpu_bootable(unsigned int nr)
+{
+ /* Special case - we inhibit secondary thread startup
+ * during boot if the user requests it. Odd-numbered
+ * cpus are assumed to be secondary threads.
+ */
+ if (system_state < SYSTEM_RUNNING &&
+ cpu_has_feature(CPU_FTR_SMT) &&
+ !smt_enabled_at_boot && nr % 2 != 0)
+ return 0;
+
+ return 1;
+}
+static struct smp_ops_t bpa_iic_smp_ops = {
+ .message_pass = smp_iic_message_pass,
+ .probe = smp_iic_probe,
+ .kick_cpu = smp_cell_kick_cpu,
+ .setup_cpu = smp_iic_setup_cpu,
+ .cpu_bootable = smp_cell_cpu_bootable,
+};
+
+/* This is called very early */
+void __init smp_init_cell(void)
+{
+ int i;
+
+ DBG(" -> smp_init_cell()\n");
+
+ smp_ops = &bpa_iic_smp_ops;
+
+ /* Mark threads which are still spinning in hold loops. */
+ if (cpu_has_feature(CPU_FTR_SMT)) {
+ for_each_present_cpu(i) {
+ if (i % 2 == 0)
+ /*
+ * Even-numbered logical cpus correspond to
+ * primary threads.
+ */
+ cpu_set(i, of_spin_map);
+ }
+ } else {
+ of_spin_map = cpu_present_map;
+ }
+
+ cpu_clear(boot_cpuid, of_spin_map);
+
+ /* Non-lpar has additional take/give timebase */
+ if (rtas_token("freeze-time-base") != RTAS_UNKNOWN_SERVICE) {
+ smp_ops->give_timebase = cell_give_timebase;
+ smp_ops->take_timebase = cell_take_timebase;
+ }
+
+ DBG(" <- smp_init_cell()\n");
+}
diff --git a/arch/ppc64/kernel/spider-pic.c b/arch/powerpc/platforms/cell/spider-pic.c
index d5c9a02fb119..e74132188bdf 100644
--- a/arch/ppc64/kernel/spider-pic.c
+++ b/arch/powerpc/platforms/cell/spider-pic.c
@@ -27,7 +27,7 @@
#include <asm/prom.h>
#include <asm/io.h>
-#include "bpa_iic.h"
+#include "interrupt.h"
/* register layout taken from Spider spec, table 7.4-4 */
enum {
diff --git a/arch/powerpc/platforms/chrp/Makefile b/arch/powerpc/platforms/chrp/Makefile
new file mode 100644
index 000000000000..902feb1ac431
--- /dev/null
+++ b/arch/powerpc/platforms/chrp/Makefile
@@ -0,0 +1,4 @@
+obj-y += setup.o time.o pegasos_eth.o
+obj-$(CONFIG_PCI) += pci.o
+obj-$(CONFIG_SMP) += smp.o
+obj-$(CONFIG_NVRAM) += nvram.o
diff --git a/arch/powerpc/platforms/chrp/chrp.h b/arch/powerpc/platforms/chrp/chrp.h
new file mode 100644
index 000000000000..3a2057fa314a
--- /dev/null
+++ b/arch/powerpc/platforms/chrp/chrp.h
@@ -0,0 +1,12 @@
+/*
+ * Declarations of CHRP platform-specific things.
+ */
+
+extern void chrp_nvram_init(void);
+extern void chrp_get_rtc_time(struct rtc_time *);
+extern int chrp_set_rtc_time(struct rtc_time *);
+extern void chrp_calibrate_decr(void);
+extern long chrp_time_init(void);
+
+extern void chrp_find_bridges(void);
+extern void chrp_event_scan(void);
diff --git a/arch/powerpc/platforms/chrp/nvram.c b/arch/powerpc/platforms/chrp/nvram.c
new file mode 100644
index 000000000000..150f67d6f90c
--- /dev/null
+++ b/arch/powerpc/platforms/chrp/nvram.c
@@ -0,0 +1,89 @@
+/*
+ * c 2001 PPC 64 Team, IBM Corp
+ *
+ * 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.
+ *
+ * /dev/nvram driver for PPC
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <asm/uaccess.h>
+#include <asm/prom.h>
+#include <asm/machdep.h>
+#include <asm/rtas.h>
+#include "chrp.h"
+
+static unsigned int nvram_size;
+static unsigned char nvram_buf[4];
+static DEFINE_SPINLOCK(nvram_lock);
+
+static unsigned char chrp_nvram_read(int addr)
+{
+ unsigned int done;
+ unsigned long flags;
+ unsigned char ret;
+
+ if (addr >= nvram_size) {
+ printk(KERN_DEBUG "%s: read addr %d > nvram_size %u\n",
+ current->comm, addr, nvram_size);
+ return 0xff;
+ }
+ spin_lock_irqsave(&nvram_lock, flags);
+ if ((rtas_call(rtas_token("nvram-fetch"), 3, 2, &done, addr,
+ __pa(nvram_buf), 1) != 0) || 1 != done)
+ ret = 0xff;
+ else
+ ret = nvram_buf[0];
+ spin_unlock_irqrestore(&nvram_lock, flags);
+
+ return ret;
+}
+
+static void chrp_nvram_write(int addr, unsigned char val)
+{
+ unsigned int done;
+ unsigned long flags;
+
+ if (addr >= nvram_size) {
+ printk(KERN_DEBUG "%s: write addr %d > nvram_size %u\n",
+ current->comm, addr, nvram_size);
+ return;
+ }
+ spin_lock_irqsave(&nvram_lock, flags);
+ nvram_buf[0] = val;
+ if ((rtas_call(rtas_token("nvram-store"), 3, 2, &done, addr,
+ __pa(nvram_buf), 1) != 0) || 1 != done)
+ printk(KERN_DEBUG "rtas IO error storing 0x%02x at %d", val, addr);
+ spin_unlock_irqrestore(&nvram_lock, flags);
+}
+
+void __init chrp_nvram_init(void)
+{
+ struct device_node *nvram;
+ unsigned int *nbytes_p, proplen;
+
+ nvram = of_find_node_by_type(NULL, "nvram");
+ if (nvram == NULL)
+ return;
+
+ nbytes_p = (unsigned int *)get_property(nvram, "#bytes", &proplen);
+ if (nbytes_p == NULL || proplen != sizeof(unsigned int))
+ return;
+
+ nvram_size = *nbytes_p;
+
+ printk(KERN_INFO "CHRP nvram contains %u bytes\n", nvram_size);
+ of_node_put(nvram);
+
+ ppc_md.nvram_read_val = chrp_nvram_read;
+ ppc_md.nvram_write_val = chrp_nvram_write;
+
+ return;
+}
diff --git a/arch/powerpc/platforms/chrp/pci.c b/arch/powerpc/platforms/chrp/pci.c
new file mode 100644
index 000000000000..82c429d487f3
--- /dev/null
+++ b/arch/powerpc/platforms/chrp/pci.c
@@ -0,0 +1,310 @@
+/*
+ * CHRP pci routines.
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/delay.h>
+#include <linux/string.h>
+#include <linux/init.h>
+#include <linux/ide.h>
+
+#include <asm/io.h>
+#include <asm/pgtable.h>
+#include <asm/irq.h>
+#include <asm/hydra.h>
+#include <asm/prom.h>
+#include <asm/gg2.h>
+#include <asm/machdep.h>
+#include <asm/sections.h>
+#include <asm/pci-bridge.h>
+#include <asm/open_pic.h>
+#include <asm/grackle.h>
+#include <asm/rtas.h>
+
+/* LongTrail */
+void __iomem *gg2_pci_config_base;
+
+/*
+ * The VLSI Golden Gate II has only 512K of PCI configuration space, so we
+ * limit the bus number to 3 bits
+ */
+
+int gg2_read_config(struct pci_bus *bus, unsigned int devfn, int off,
+ int len, u32 *val)
+{
+ volatile void __iomem *cfg_data;
+ struct pci_controller *hose = bus->sysdata;
+
+ if (bus->number > 7)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+ /*
+ * Note: the caller has already checked that off is
+ * suitably aligned and that len is 1, 2 or 4.
+ */
+ cfg_data = hose->cfg_data + ((bus->number<<16) | (devfn<<8) | off);
+ switch (len) {
+ case 1:
+ *val = in_8(cfg_data);
+ break;
+ case 2:
+ *val = in_le16(cfg_data);
+ break;
+ default:
+ *val = in_le32(cfg_data);
+ break;
+ }
+ return PCIBIOS_SUCCESSFUL;
+}
+
+int gg2_write_config(struct pci_bus *bus, unsigned int devfn, int off,
+ int len, u32 val)
+{
+ volatile void __iomem *cfg_data;
+ struct pci_controller *hose = bus->sysdata;
+
+ if (bus->number > 7)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+ /*
+ * Note: the caller has already checked that off is
+ * suitably aligned and that len is 1, 2 or 4.
+ */
+ cfg_data = hose->cfg_data + ((bus->number<<16) | (devfn<<8) | off);
+ switch (len) {
+ case 1:
+ out_8(cfg_data, val);
+ break;
+ case 2:
+ out_le16(cfg_data, val);
+ break;
+ default:
+ out_le32(cfg_data, val);
+ break;
+ }
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static struct pci_ops gg2_pci_ops =
+{
+ gg2_read_config,
+ gg2_write_config
+};
+
+/*
+ * Access functions for PCI config space using RTAS calls.
+ */
+int rtas_read_config(struct pci_bus *bus, unsigned int devfn, int offset,
+ int len, u32 *val)
+{
+ struct pci_controller *hose = bus->sysdata;
+ unsigned long addr = (offset & 0xff) | ((devfn & 0xff) << 8)
+ | (((bus->number - hose->first_busno) & 0xff) << 16)
+ | (hose->index << 24);
+ int ret = -1;
+ int rval;
+
+ rval = rtas_call(rtas_token("read-pci-config"), 2, 2, &ret, addr, len);
+ *val = ret;
+ return rval? PCIBIOS_DEVICE_NOT_FOUND: PCIBIOS_SUCCESSFUL;
+}
+
+int rtas_write_config(struct pci_bus *bus, unsigned int devfn, int offset,
+ int len, u32 val)
+{
+ struct pci_controller *hose = bus->sysdata;
+ unsigned long addr = (offset & 0xff) | ((devfn & 0xff) << 8)
+ | (((bus->number - hose->first_busno) & 0xff) << 16)
+ | (hose->index << 24);
+ int rval;
+
+ rval = rtas_call(rtas_token("write-pci-config"), 3, 1, NULL,
+ addr, len, val);
+ return rval? PCIBIOS_DEVICE_NOT_FOUND: PCIBIOS_SUCCESSFUL;
+}
+
+static struct pci_ops rtas_pci_ops =
+{
+ rtas_read_config,
+ rtas_write_config
+};
+
+volatile struct Hydra __iomem *Hydra = NULL;
+
+int __init
+hydra_init(void)
+{
+ struct device_node *np;
+
+ np = find_devices("mac-io");
+ if (np == NULL || np->n_addrs == 0)
+ return 0;
+ Hydra = ioremap(np->addrs[0].address, np->addrs[0].size);
+ printk("Hydra Mac I/O at %lx\n", np->addrs[0].address);
+ printk("Hydra Feature_Control was %x",
+ in_le32(&Hydra->Feature_Control));
+ out_le32(&Hydra->Feature_Control, (HYDRA_FC_SCC_CELL_EN |
+ HYDRA_FC_SCSI_CELL_EN |
+ HYDRA_FC_SCCA_ENABLE |
+ HYDRA_FC_SCCB_ENABLE |
+ HYDRA_FC_ARB_BYPASS |
+ HYDRA_FC_MPIC_ENABLE |
+ HYDRA_FC_SLOW_SCC_PCLK |
+ HYDRA_FC_MPIC_IS_MASTER));
+ printk(", now %x\n", in_le32(&Hydra->Feature_Control));
+ return 1;
+}
+
+void __init
+chrp_pcibios_fixup(void)
+{
+ struct pci_dev *dev = NULL;
+ struct device_node *np;
+
+ /* PCI interrupts are controlled by the OpenPIC */
+ for_each_pci_dev(dev) {
+ np = pci_device_to_OF_node(dev);
+ if ((np != 0) && (np->n_intrs > 0) && (np->intrs[0].line != 0))
+ dev->irq = np->intrs[0].line;
+ pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
+ }
+}
+
+#define PRG_CL_RESET_VALID 0x00010000
+
+static void __init
+setup_python(struct pci_controller *hose, struct device_node *dev)
+{
+ u32 __iomem *reg;
+ u32 val;
+ unsigned long addr = dev->addrs[0].address;
+
+ setup_indirect_pci(hose, addr + 0xf8000, addr + 0xf8010);
+
+ /* Clear the magic go-slow bit */
+ reg = ioremap(dev->addrs[0].address + 0xf6000, 0x40);
+ val = in_be32(&reg[12]);
+ if (val & PRG_CL_RESET_VALID) {
+ out_be32(&reg[12], val & ~PRG_CL_RESET_VALID);
+ in_be32(&reg[12]);
+ }
+ iounmap(reg);
+}
+
+/* Marvell Discovery II based Pegasos 2 */
+static void __init setup_peg2(struct pci_controller *hose, struct device_node *dev)
+{
+ struct device_node *root = find_path_device("/");
+ struct device_node *rtas;
+
+ rtas = of_find_node_by_name (root, "rtas");
+ if (rtas) {
+ hose->ops = &rtas_pci_ops;
+ } else {
+ printk ("RTAS supporting Pegasos OF not found, please upgrade"
+ " your firmware\n");
+ }
+ pci_assign_all_buses = 1;
+}
+
+void __init
+chrp_find_bridges(void)
+{
+ struct device_node *dev;
+ int *bus_range;
+ int len, index = -1;
+ struct pci_controller *hose;
+ unsigned int *dma;
+ char *model, *machine;
+ int is_longtrail = 0, is_mot = 0, is_pegasos = 0;
+ struct device_node *root = find_path_device("/");
+
+ /*
+ * The PCI host bridge nodes on some machines don't have
+ * properties to adequately identify them, so we have to
+ * look at what sort of machine this is as well.
+ */
+ machine = get_property(root, "model", NULL);
+ if (machine != NULL) {
+ is_longtrail = strncmp(machine, "IBM,LongTrail", 13) == 0;
+ is_mot = strncmp(machine, "MOT", 3) == 0;
+ if (strncmp(machine, "Pegasos2", 8) == 0)
+ is_pegasos = 2;
+ else if (strncmp(machine, "Pegasos", 7) == 0)
+ is_pegasos = 1;
+ }
+ for (dev = root->child; dev != NULL; dev = dev->sibling) {
+ if (dev->type == NULL || strcmp(dev->type, "pci") != 0)
+ continue;
+ ++index;
+ /* The GG2 bridge on the LongTrail doesn't have an address */
+ if (dev->n_addrs < 1 && !is_longtrail) {
+ printk(KERN_WARNING "Can't use %s: no address\n",
+ dev->full_name);
+ continue;
+ }
+ bus_range = (int *) get_property(dev, "bus-range", &len);
+ if (bus_range == NULL || len < 2 * sizeof(int)) {
+ printk(KERN_WARNING "Can't get bus-range for %s\n",
+ dev->full_name);
+ continue;
+ }
+ if (bus_range[1] == bus_range[0])
+ printk(KERN_INFO "PCI bus %d", bus_range[0]);
+ else
+ printk(KERN_INFO "PCI buses %d..%d",
+ bus_range[0], bus_range[1]);
+ printk(" controlled by %s", dev->type);
+ if (dev->n_addrs > 0)
+ printk(" at %lx", dev->addrs[0].address);
+ printk("\n");
+
+ hose = pcibios_alloc_controller();
+ if (!hose) {
+ printk("Can't allocate PCI controller structure for %s\n",
+ dev->full_name);
+ continue;
+ }
+ hose->arch_data = dev;
+ hose->first_busno = bus_range[0];
+ hose->last_busno = bus_range[1];
+
+ model = get_property(dev, "model", NULL);
+ if (model == NULL)
+ model = "<none>";
+ if (device_is_compatible(dev, "IBM,python")) {
+ setup_python(hose, dev);
+ } else if (is_mot
+ || strncmp(model, "Motorola, Grackle", 17) == 0) {
+ setup_grackle(hose);
+ } else if (is_longtrail) {
+ void __iomem *p = ioremap(GG2_PCI_CONFIG_BASE, 0x80000);
+ hose->ops = &gg2_pci_ops;
+ hose->cfg_data = p;
+ gg2_pci_config_base = p;
+ } else if (is_pegasos == 1) {
+ setup_indirect_pci(hose, 0xfec00cf8, 0xfee00cfc);
+ } else if (is_pegasos == 2) {
+ setup_peg2(hose, dev);
+ } else {
+ printk("No methods for %s (model %s), using RTAS\n",
+ dev->full_name, model);
+ hose->ops = &rtas_pci_ops;
+ }
+
+ pci_process_bridge_OF_ranges(hose, dev, index == 0);
+
+ /* check the first bridge for a property that we can
+ use to set pci_dram_offset */
+ dma = (unsigned int *)
+ get_property(dev, "ibm,dma-ranges", &len);
+ if (index == 0 && dma != NULL && len >= 6 * sizeof(*dma)) {
+ pci_dram_offset = dma[2] - dma[3];
+ printk("pci_dram_offset = %lx\n", pci_dram_offset);
+ }
+ }
+
+ /* Do not fixup interrupts from OF tree on pegasos */
+ if (is_pegasos == 0)
+ ppc_md.pcibios_fixup = chrp_pcibios_fixup;
+}
diff --git a/arch/powerpc/platforms/chrp/pegasos_eth.c b/arch/powerpc/platforms/chrp/pegasos_eth.c
new file mode 100644
index 000000000000..29c86781c493
--- /dev/null
+++ b/arch/powerpc/platforms/chrp/pegasos_eth.c
@@ -0,0 +1,214 @@
+/*
+ * arch/ppc/platforms/chrp_pegasos_eth.c
+ *
+ * Copyright (C) 2005 Sven Luther <sl@bplan-gmbh.de>
+ * Thanks to :
+ * Dale Farnsworth <dale@farnsworth.org>
+ * Mark A. Greer <mgreer@mvista.com>
+ * Nicolas DET <nd@bplan-gmbh.de>
+ * Benjamin Herrenschmidt <benh@kernel.crashing.org>
+ * And anyone else who helped me on this.
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/mv643xx.h>
+#include <linux/pci.h>
+
+#define PEGASOS2_MARVELL_REGBASE (0xf1000000)
+#define PEGASOS2_MARVELL_REGSIZE (0x00004000)
+#define PEGASOS2_SRAM_BASE (0xf2000000)
+#define PEGASOS2_SRAM_SIZE (256*1024)
+
+#define PEGASOS2_SRAM_BASE_ETH0 (PEGASOS2_SRAM_BASE)
+#define PEGASOS2_SRAM_BASE_ETH1 (PEGASOS2_SRAM_BASE_ETH0 + (PEGASOS2_SRAM_SIZE / 2) )
+
+
+#define PEGASOS2_SRAM_RXRING_SIZE (PEGASOS2_SRAM_SIZE/4)
+#define PEGASOS2_SRAM_TXRING_SIZE (PEGASOS2_SRAM_SIZE/4)
+
+#undef BE_VERBOSE
+
+static struct resource mv643xx_eth_shared_resources[] = {
+ [0] = {
+ .name = "ethernet shared base",
+ .start = 0xf1000000 + MV643XX_ETH_SHARED_REGS,
+ .end = 0xf1000000 + MV643XX_ETH_SHARED_REGS +
+ MV643XX_ETH_SHARED_REGS_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device mv643xx_eth_shared_device = {
+ .name = MV643XX_ETH_SHARED_NAME,
+ .id = 0,
+ .num_resources = ARRAY_SIZE(mv643xx_eth_shared_resources),
+ .resource = mv643xx_eth_shared_resources,
+};
+
+static struct resource mv643xx_eth0_resources[] = {
+ [0] = {
+ .name = "eth0 irq",
+ .start = 9,
+ .end = 9,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+
+static struct mv643xx_eth_platform_data eth0_pd = {
+ .tx_sram_addr = PEGASOS2_SRAM_BASE_ETH0,
+ .tx_sram_size = PEGASOS2_SRAM_TXRING_SIZE,
+ .tx_queue_size = PEGASOS2_SRAM_TXRING_SIZE/16,
+
+ .rx_sram_addr = PEGASOS2_SRAM_BASE_ETH0 + PEGASOS2_SRAM_TXRING_SIZE,
+ .rx_sram_size = PEGASOS2_SRAM_RXRING_SIZE,
+ .rx_queue_size = PEGASOS2_SRAM_RXRING_SIZE/16,
+};
+
+static struct platform_device eth0_device = {
+ .name = MV643XX_ETH_NAME,
+ .id = 0,
+ .num_resources = ARRAY_SIZE(mv643xx_eth0_resources),
+ .resource = mv643xx_eth0_resources,
+ .dev = {
+ .platform_data = &eth0_pd,
+ },
+};
+
+static struct resource mv643xx_eth1_resources[] = {
+ [0] = {
+ .name = "eth1 irq",
+ .start = 9,
+ .end = 9,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct mv643xx_eth_platform_data eth1_pd = {
+ .tx_sram_addr = PEGASOS2_SRAM_BASE_ETH1,
+ .tx_sram_size = PEGASOS2_SRAM_TXRING_SIZE,
+ .tx_queue_size = PEGASOS2_SRAM_TXRING_SIZE/16,
+
+ .rx_sram_addr = PEGASOS2_SRAM_BASE_ETH1 + PEGASOS2_SRAM_TXRING_SIZE,
+ .rx_sram_size = PEGASOS2_SRAM_RXRING_SIZE,
+ .rx_queue_size = PEGASOS2_SRAM_RXRING_SIZE/16,
+};
+
+static struct platform_device eth1_device = {
+ .name = MV643XX_ETH_NAME,
+ .id = 1,
+ .num_resources = ARRAY_SIZE(mv643xx_eth1_resources),
+ .resource = mv643xx_eth1_resources,
+ .dev = {
+ .platform_data = &eth1_pd,
+ },
+};
+
+static struct platform_device *mv643xx_eth_pd_devs[] __initdata = {
+ &mv643xx_eth_shared_device,
+ &eth0_device,
+ &eth1_device,
+};
+
+/***********/
+/***********/
+#define MV_READ(offset,val) { val = readl(mv643xx_reg_base + offset); }
+#define MV_WRITE(offset,data) writel(data, mv643xx_reg_base + offset)
+
+static void __iomem *mv643xx_reg_base;
+
+static int Enable_SRAM(void)
+{
+ u32 ALong;
+
+ if (mv643xx_reg_base == NULL)
+ mv643xx_reg_base = ioremap(PEGASOS2_MARVELL_REGBASE,
+ PEGASOS2_MARVELL_REGSIZE);
+
+ if (mv643xx_reg_base == NULL)
+ return -ENOMEM;
+
+#ifdef BE_VERBOSE
+ printk("Pegasos II/Marvell MV64361: register remapped from %p to %p\n",
+ (void *)PEGASOS2_MARVELL_REGBASE, (void *)mv643xx_reg_base);
+#endif
+
+ MV_WRITE(MV64340_SRAM_CONFIG, 0);
+
+ MV_WRITE(MV64340_INTEGRATED_SRAM_BASE_ADDR, PEGASOS2_SRAM_BASE >> 16);
+
+ MV_READ(MV64340_BASE_ADDR_ENABLE, ALong);
+ ALong &= ~(1 << 19);
+ MV_WRITE(MV64340_BASE_ADDR_ENABLE, ALong);
+
+ ALong = 0x02;
+ ALong |= PEGASOS2_SRAM_BASE & 0xffff0000;
+ MV_WRITE(MV643XX_ETH_BAR_4, ALong);
+
+ MV_WRITE(MV643XX_ETH_SIZE_REG_4, (PEGASOS2_SRAM_SIZE-1) & 0xffff0000);
+
+ MV_READ(MV643XX_ETH_BASE_ADDR_ENABLE_REG, ALong);
+ ALong &= ~(1 << 4);
+ MV_WRITE(MV643XX_ETH_BASE_ADDR_ENABLE_REG, ALong);
+
+#ifdef BE_VERBOSE
+ printk("Pegasos II/Marvell MV64361: register unmapped\n");
+ printk("Pegasos II/Marvell MV64361: SRAM at %p, size=%x\n", (void*) PEGASOS2_SRAM_BASE, PEGASOS2_SRAM_SIZE);
+#endif
+
+ iounmap(mv643xx_reg_base);
+ mv643xx_reg_base = NULL;
+
+ return 1;
+}
+
+
+/***********/
+/***********/
+int mv643xx_eth_add_pds(void)
+{
+ int ret = 0;
+ static struct pci_device_id pci_marvell_mv64360[] = {
+ { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, PCI_DEVICE_ID_MARVELL_MV64360) },
+ { }
+ };
+
+#ifdef BE_VERBOSE
+ printk("Pegasos II/Marvell MV64361: init\n");
+#endif
+
+ if (pci_dev_present(pci_marvell_mv64360)) {
+ ret = platform_add_devices(mv643xx_eth_pd_devs,
+ ARRAY_SIZE(mv643xx_eth_pd_devs));
+
+ if ( Enable_SRAM() < 0)
+ {
+ eth0_pd.tx_sram_addr = 0;
+ eth0_pd.tx_sram_size = 0;
+ eth0_pd.rx_sram_addr = 0;
+ eth0_pd.rx_sram_size = 0;
+
+ eth1_pd.tx_sram_addr = 0;
+ eth1_pd.tx_sram_size = 0;
+ eth1_pd.rx_sram_addr = 0;
+ eth1_pd.rx_sram_size = 0;
+
+#ifdef BE_VERBOSE
+ printk("Pegasos II/Marvell MV64361: Can't enable the "
+ "SRAM\n");
+#endif
+ }
+ }
+
+#ifdef BE_VERBOSE
+ printk("Pegasos II/Marvell MV64361: init is over\n");
+#endif
+
+ return ret;
+}
+
+device_initcall(mv643xx_eth_add_pds);
diff --git a/arch/powerpc/platforms/chrp/setup.c b/arch/powerpc/platforms/chrp/setup.c
new file mode 100644
index 000000000000..4099ddab9205
--- /dev/null
+++ b/arch/powerpc/platforms/chrp/setup.c
@@ -0,0 +1,524 @@
+/*
+ * arch/ppc/platforms/setup.c
+ *
+ * Copyright (C) 1995 Linus Torvalds
+ * Adapted from 'alpha' version by Gary Thomas
+ * Modified by Cort Dougan (cort@cs.nmt.edu)
+ */
+
+/*
+ * bootup setup stuff..
+ */
+
+#include <linux/config.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/stddef.h>
+#include <linux/unistd.h>
+#include <linux/ptrace.h>
+#include <linux/slab.h>
+#include <linux/user.h>
+#include <linux/a.out.h>
+#include <linux/tty.h>
+#include <linux/major.h>
+#include <linux/interrupt.h>
+#include <linux/reboot.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/version.h>
+#include <linux/adb.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/ide.h>
+#include <linux/console.h>
+#include <linux/seq_file.h>
+#include <linux/root_dev.h>
+#include <linux/initrd.h>
+#include <linux/module.h>
+
+#include <asm/io.h>
+#include <asm/pgtable.h>
+#include <asm/prom.h>
+#include <asm/gg2.h>
+#include <asm/pci-bridge.h>
+#include <asm/dma.h>
+#include <asm/machdep.h>
+#include <asm/irq.h>
+#include <asm/hydra.h>
+#include <asm/sections.h>
+#include <asm/time.h>
+#include <asm/btext.h>
+#include <asm/i8259.h>
+#include <asm/mpic.h>
+#include <asm/rtas.h>
+#include <asm/xmon.h>
+
+#include "chrp.h"
+
+void rtas_indicator_progress(char *, unsigned short);
+void btext_progress(char *, unsigned short);
+
+int _chrp_type;
+EXPORT_SYMBOL(_chrp_type);
+
+struct mpic *chrp_mpic;
+
+/*
+ * XXX this should be in xmon.h, but putting it there means xmon.h
+ * has to include <linux/interrupt.h> (to get irqreturn_t), which
+ * causes all sorts of problems. -- paulus
+ */
+extern irqreturn_t xmon_irq(int, void *, struct pt_regs *);
+
+extern unsigned long loops_per_jiffy;
+
+#ifdef CONFIG_SMP
+extern struct smp_ops_t chrp_smp_ops;
+#endif
+
+static const char *gg2_memtypes[4] = {
+ "FPM", "SDRAM", "EDO", "BEDO"
+};
+static const char *gg2_cachesizes[4] = {
+ "256 KB", "512 KB", "1 MB", "Reserved"
+};
+static const char *gg2_cachetypes[4] = {
+ "Asynchronous", "Reserved", "Flow-Through Synchronous",
+ "Pipelined Synchronous"
+};
+static const char *gg2_cachemodes[4] = {
+ "Disabled", "Write-Through", "Copy-Back", "Transparent Mode"
+};
+
+void chrp_show_cpuinfo(struct seq_file *m)
+{
+ int i, sdramen;
+ unsigned int t;
+ struct device_node *root;
+ const char *model = "";
+
+ root = find_path_device("/");
+ if (root)
+ model = get_property(root, "model", NULL);
+ seq_printf(m, "machine\t\t: CHRP %s\n", model);
+
+ /* longtrail (goldengate) stuff */
+ if (!strncmp(model, "IBM,LongTrail", 13)) {
+ /* VLSI VAS96011/12 `Golden Gate 2' */
+ /* Memory banks */
+ sdramen = (in_le32(gg2_pci_config_base + GG2_PCI_DRAM_CTRL)
+ >>31) & 1;
+ for (i = 0; i < (sdramen ? 4 : 6); i++) {
+ t = in_le32(gg2_pci_config_base+
+ GG2_PCI_DRAM_BANK0+
+ i*4);
+ if (!(t & 1))
+ continue;
+ switch ((t>>8) & 0x1f) {
+ case 0x1f:
+ model = "4 MB";
+ break;
+ case 0x1e:
+ model = "8 MB";
+ break;
+ case 0x1c:
+ model = "16 MB";
+ break;
+ case 0x18:
+ model = "32 MB";
+ break;
+ case 0x10:
+ model = "64 MB";
+ break;
+ case 0x00:
+ model = "128 MB";
+ break;
+ default:
+ model = "Reserved";
+ break;
+ }
+ seq_printf(m, "memory bank %d\t: %s %s\n", i, model,
+ gg2_memtypes[sdramen ? 1 : ((t>>1) & 3)]);
+ }
+ /* L2 cache */
+ t = in_le32(gg2_pci_config_base+GG2_PCI_CC_CTRL);
+ seq_printf(m, "board l2\t: %s %s (%s)\n",
+ gg2_cachesizes[(t>>7) & 3],
+ gg2_cachetypes[(t>>2) & 3],
+ gg2_cachemodes[t & 3]);
+ }
+}
+
+/*
+ * Fixes for the National Semiconductor PC78308VUL SuperI/O
+ *
+ * Some versions of Open Firmware incorrectly initialize the IRQ settings
+ * for keyboard and mouse
+ */
+static inline void __init sio_write(u8 val, u8 index)
+{
+ outb(index, 0x15c);
+ outb(val, 0x15d);
+}
+
+static inline u8 __init sio_read(u8 index)
+{
+ outb(index, 0x15c);
+ return inb(0x15d);
+}
+
+static void __init sio_fixup_irq(const char *name, u8 device, u8 level,
+ u8 type)
+{
+ u8 level0, type0, active;
+
+ /* select logical device */
+ sio_write(device, 0x07);
+ active = sio_read(0x30);
+ level0 = sio_read(0x70);
+ type0 = sio_read(0x71);
+ if (level0 != level || type0 != type || !active) {
+ printk(KERN_WARNING "sio: %s irq level %d, type %d, %sactive: "
+ "remapping to level %d, type %d, active\n",
+ name, level0, type0, !active ? "in" : "", level, type);
+ sio_write(0x01, 0x30);
+ sio_write(level, 0x70);
+ sio_write(type, 0x71);
+ }
+}
+
+static void __init sio_init(void)
+{
+ struct device_node *root;
+
+ if ((root = find_path_device("/")) &&
+ !strncmp(get_property(root, "model", NULL), "IBM,LongTrail", 13)) {
+ /* logical device 0 (KBC/Keyboard) */
+ sio_fixup_irq("keyboard", 0, 1, 2);
+ /* select logical device 1 (KBC/Mouse) */
+ sio_fixup_irq("mouse", 1, 12, 2);
+ }
+}
+
+
+static void __init pegasos_set_l2cr(void)
+{
+ struct device_node *np;
+
+ /* On Pegasos, enable the l2 cache if needed, as the OF forgets it */
+ if (_chrp_type != _CHRP_Pegasos)
+ return;
+
+ /* Enable L2 cache if needed */
+ np = find_type_devices("cpu");
+ if (np != NULL) {
+ unsigned int *l2cr = (unsigned int *)
+ get_property (np, "l2cr", NULL);
+ if (l2cr == NULL) {
+ printk ("Pegasos l2cr : no cpu l2cr property found\n");
+ return;
+ }
+ if (!((*l2cr) & 0x80000000)) {
+ printk ("Pegasos l2cr : L2 cache was not active, "
+ "activating\n");
+ _set_L2CR(0);
+ _set_L2CR((*l2cr) | 0x80000000);
+ }
+ }
+}
+
+void __init chrp_setup_arch(void)
+{
+ struct device_node *root = find_path_device ("/");
+ char *machine = NULL;
+ struct device_node *device;
+ unsigned int *p = NULL;
+
+ /* init to some ~sane value until calibrate_delay() runs */
+ loops_per_jiffy = 50000000/HZ;
+
+ if (root)
+ machine = get_property(root, "model", NULL);
+ if (machine && strncmp(machine, "Pegasos", 7) == 0) {
+ _chrp_type = _CHRP_Pegasos;
+ } else if (machine && strncmp(machine, "IBM", 3) == 0) {
+ _chrp_type = _CHRP_IBM;
+ } else if (machine && strncmp(machine, "MOT", 3) == 0) {
+ _chrp_type = _CHRP_Motorola;
+ } else {
+ /* Let's assume it is an IBM chrp if all else fails */
+ _chrp_type = _CHRP_IBM;
+ }
+ printk("chrp type = %x\n", _chrp_type);
+
+ rtas_initialize();
+ if (rtas_token("display-character") >= 0)
+ ppc_md.progress = rtas_progress;
+
+#ifdef CONFIG_BOOTX_TEXT
+ if (ppc_md.progress == NULL && boot_text_mapped)
+ ppc_md.progress = btext_progress;
+#endif
+
+#ifdef CONFIG_BLK_DEV_INITRD
+ /* this is fine for chrp */
+ initrd_below_start_ok = 1;
+
+ if (initrd_start)
+ ROOT_DEV = Root_RAM0;
+ else
+#endif
+ ROOT_DEV = Root_SDA2; /* sda2 (sda1 is for the kernel) */
+
+ /* On pegasos, enable the L2 cache if not already done by OF */
+ pegasos_set_l2cr();
+
+ /* Lookup PCI host bridges */
+ chrp_find_bridges();
+
+ /*
+ * Temporary fixes for PCI devices.
+ * -- Geert
+ */
+ hydra_init(); /* Mac I/O */
+
+ /*
+ * Fix the Super I/O configuration
+ */
+ sio_init();
+
+ /* Get the event scan rate for the rtas so we know how
+ * often it expects a heartbeat. -- Cort
+ */
+ device = find_devices("rtas");
+ if (device)
+ p = (unsigned int *) get_property
+ (device, "rtas-event-scan-rate", NULL);
+ if (p && *p) {
+ ppc_md.heartbeat = chrp_event_scan;
+ ppc_md.heartbeat_reset = HZ / (*p * 30) - 1;
+ ppc_md.heartbeat_count = 1;
+ printk("RTAS Event Scan Rate: %u (%lu jiffies)\n",
+ *p, ppc_md.heartbeat_reset);
+ }
+
+ pci_create_OF_bus_map();
+
+ /*
+ * Print the banner, then scroll down so boot progress
+ * can be printed. -- Cort
+ */
+ if (ppc_md.progress) ppc_md.progress("Linux/PPC "UTS_RELEASE"\n", 0x0);
+}
+
+void
+chrp_event_scan(void)
+{
+ unsigned char log[1024];
+ int ret = 0;
+
+ /* XXX: we should loop until the hardware says no more error logs -- Cort */
+ rtas_call(rtas_token("event-scan"), 4, 1, &ret, 0xffffffff, 0,
+ __pa(log), 1024);
+ ppc_md.heartbeat_count = ppc_md.heartbeat_reset;
+}
+
+/*
+ * Finds the open-pic node and sets up the mpic driver.
+ */
+static void __init chrp_find_openpic(void)
+{
+ struct device_node *np, *root;
+ int len, i, j, irq_count;
+ int isu_size, idu_size;
+ unsigned int *iranges, *opprop = NULL;
+ int oplen = 0;
+ unsigned long opaddr;
+ int na = 1;
+ unsigned char init_senses[NR_IRQS - NUM_8259_INTERRUPTS];
+
+ np = find_type_devices("open-pic");
+ if (np == NULL)
+ return;
+ root = find_path_device("/");
+ if (root) {
+ opprop = (unsigned int *) get_property
+ (root, "platform-open-pic", &oplen);
+ na = prom_n_addr_cells(root);
+ }
+ if (opprop && oplen >= na * sizeof(unsigned int)) {
+ opaddr = opprop[na-1]; /* assume 32-bit */
+ oplen /= na * sizeof(unsigned int);
+ } else {
+ if (np->n_addrs == 0)
+ return;
+ opaddr = np->addrs[0].address;
+ oplen = 0;
+ }
+
+ printk(KERN_INFO "OpenPIC at %lx\n", opaddr);
+
+ irq_count = NR_IRQS - NUM_ISA_INTERRUPTS - 4; /* leave room for IPIs */
+ prom_get_irq_senses(init_senses, NUM_ISA_INTERRUPTS, NR_IRQS - 4);
+ /* i8259 cascade is always positive level */
+ init_senses[0] = IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE;
+
+ iranges = (unsigned int *) get_property(np, "interrupt-ranges", &len);
+ if (iranges == NULL)
+ len = 0; /* non-distributed mpic */
+ else
+ len /= 2 * sizeof(unsigned int);
+
+ /*
+ * The first pair of cells in interrupt-ranges refers to the
+ * IDU; subsequent pairs refer to the ISUs.
+ */
+ if (oplen < len) {
+ printk(KERN_ERR "Insufficient addresses for distributed"
+ " OpenPIC (%d < %d)\n", np->n_addrs, len);
+ len = oplen;
+ }
+
+ isu_size = 0;
+ idu_size = 0;
+ if (len > 0 && iranges[1] != 0) {
+ printk(KERN_INFO "OpenPIC irqs %d..%d in IDU\n",
+ iranges[0], iranges[0] + iranges[1] - 1);
+ idu_size = iranges[1];
+ }
+ if (len > 1)
+ isu_size = iranges[3];
+
+ chrp_mpic = mpic_alloc(opaddr, MPIC_PRIMARY,
+ isu_size, NUM_ISA_INTERRUPTS, irq_count,
+ NR_IRQS - 4, init_senses, irq_count,
+ " MPIC ");
+ if (chrp_mpic == NULL) {
+ printk(KERN_ERR "Failed to allocate MPIC structure\n");
+ return;
+ }
+
+ j = na - 1;
+ for (i = 1; i < len; ++i) {
+ iranges += 2;
+ j += na;
+ printk(KERN_INFO "OpenPIC irqs %d..%d in ISU at %x\n",
+ iranges[0], iranges[0] + iranges[1] - 1,
+ opprop[j]);
+ mpic_assign_isu(chrp_mpic, i - 1, opprop[j]);
+ }
+
+ mpic_init(chrp_mpic);
+ mpic_setup_cascade(NUM_ISA_INTERRUPTS, i8259_irq_cascade, NULL);
+}
+
+#if defined(CONFIG_VT) && defined(CONFIG_INPUT_ADBHID) && defined(XMON)
+static struct irqaction xmon_irqaction = {
+ .handler = xmon_irq,
+ .mask = CPU_MASK_NONE,
+ .name = "XMON break",
+};
+#endif
+
+void __init chrp_init_IRQ(void)
+{
+ struct device_node *np;
+ unsigned long chrp_int_ack = 0;
+#if defined(CONFIG_VT) && defined(CONFIG_INPUT_ADBHID) && defined(XMON)
+ struct device_node *kbd;
+#endif
+
+ for (np = find_devices("pci"); np != NULL; np = np->next) {
+ unsigned int *addrp = (unsigned int *)
+ get_property(np, "8259-interrupt-acknowledge", NULL);
+
+ if (addrp == NULL)
+ continue;
+ chrp_int_ack = addrp[prom_n_addr_cells(np)-1];
+ break;
+ }
+ if (np == NULL)
+ printk(KERN_ERR "Cannot find PCI interrupt acknowledge address\n");
+
+ chrp_find_openpic();
+
+ i8259_init(chrp_int_ack, 0);
+
+ if (_chrp_type == _CHRP_Pegasos)
+ ppc_md.get_irq = i8259_irq;
+ else
+ ppc_md.get_irq = mpic_get_irq;
+
+#if defined(CONFIG_VT) && defined(CONFIG_INPUT_ADBHID) && defined(XMON)
+ /* see if there is a keyboard in the device tree
+ with a parent of type "adb" */
+ for (kbd = find_devices("keyboard"); kbd; kbd = kbd->next)
+ if (kbd->parent && kbd->parent->type
+ && strcmp(kbd->parent->type, "adb") == 0)
+ break;
+ if (kbd)
+ setup_irq(HYDRA_INT_ADB_NMI, &xmon_irqaction);
+#endif
+}
+
+void __init
+chrp_init2(void)
+{
+#ifdef CONFIG_NVRAM
+ chrp_nvram_init();
+#endif
+
+ request_region(0x20,0x20,"pic1");
+ request_region(0xa0,0x20,"pic2");
+ request_region(0x00,0x20,"dma1");
+ request_region(0x40,0x20,"timer");
+ request_region(0x80,0x10,"dma page reg");
+ request_region(0xc0,0x20,"dma2");
+
+ if (ppc_md.progress)
+ ppc_md.progress(" Have fun! ", 0x7777);
+}
+
+void __init chrp_init(void)
+{
+ ISA_DMA_THRESHOLD = ~0L;
+ DMA_MODE_READ = 0x44;
+ DMA_MODE_WRITE = 0x48;
+ isa_io_base = CHRP_ISA_IO_BASE; /* default value */
+ ppc_do_canonicalize_irqs = 1;
+
+ /* Assume we have an 8259... */
+ __irq_offset_value = NUM_ISA_INTERRUPTS;
+
+ ppc_md.setup_arch = chrp_setup_arch;
+ ppc_md.show_cpuinfo = chrp_show_cpuinfo;
+
+ ppc_md.init_IRQ = chrp_init_IRQ;
+ ppc_md.init = chrp_init2;
+
+ ppc_md.phys_mem_access_prot = pci_phys_mem_access_prot;
+
+ ppc_md.restart = rtas_restart;
+ ppc_md.power_off = rtas_power_off;
+ ppc_md.halt = rtas_halt;
+
+ ppc_md.time_init = chrp_time_init;
+ ppc_md.set_rtc_time = chrp_set_rtc_time;
+ ppc_md.get_rtc_time = chrp_get_rtc_time;
+ ppc_md.calibrate_decr = chrp_calibrate_decr;
+
+#ifdef CONFIG_SMP
+ smp_ops = &chrp_smp_ops;
+#endif /* CONFIG_SMP */
+}
+
+#ifdef CONFIG_BOOTX_TEXT
+void
+btext_progress(char *s, unsigned short hex)
+{
+ btext_drawstring(s);
+ btext_drawstring("\n");
+}
+#endif /* CONFIG_BOOTX_TEXT */
diff --git a/arch/powerpc/platforms/chrp/smp.c b/arch/powerpc/platforms/chrp/smp.c
new file mode 100644
index 000000000000..bb2315997d45
--- /dev/null
+++ b/arch/powerpc/platforms/chrp/smp.c
@@ -0,0 +1,85 @@
+/*
+ * Smp support for CHRP machines.
+ *
+ * Written by Cort Dougan (cort@cs.nmt.edu) borrowing a great
+ * deal of code from the sparc and intel versions.
+ *
+ * Copyright (C) 1999 Cort Dougan <cort@cs.nmt.edu>
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/interrupt.h>
+#include <linux/kernel_stat.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/spinlock.h>
+
+#include <asm/ptrace.h>
+#include <asm/atomic.h>
+#include <asm/irq.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/sections.h>
+#include <asm/io.h>
+#include <asm/prom.h>
+#include <asm/smp.h>
+#include <asm/residual.h>
+#include <asm/time.h>
+#include <asm/open_pic.h>
+#include <asm/machdep.h>
+#include <asm/smp.h>
+#include <asm/mpic.h>
+
+static void __devinit smp_chrp_kick_cpu(int nr)
+{
+ *(unsigned long *)KERNELBASE = nr;
+ asm volatile("dcbf 0,%0"::"r"(KERNELBASE):"memory");
+}
+
+static void __devinit smp_chrp_setup_cpu(int cpu_nr)
+{
+ mpic_setup_this_cpu();
+}
+
+static DEFINE_SPINLOCK(timebase_lock);
+static unsigned int timebase_upper = 0, timebase_lower = 0;
+
+void __devinit smp_chrp_give_timebase(void)
+{
+ spin_lock(&timebase_lock);
+ rtas_call(rtas_token("freeze-time-base"), 0, 1, NULL);
+ timebase_upper = get_tbu();
+ timebase_lower = get_tbl();
+ spin_unlock(&timebase_lock);
+
+ while (timebase_upper || timebase_lower)
+ barrier();
+ rtas_call(rtas_token("thaw-time-base"), 0, 1, NULL);
+}
+
+void __devinit smp_chrp_take_timebase(void)
+{
+ while (!(timebase_upper || timebase_lower))
+ barrier();
+ spin_lock(&timebase_lock);
+ set_tb(timebase_upper, timebase_lower);
+ timebase_upper = 0;
+ timebase_lower = 0;
+ spin_unlock(&timebase_lock);
+ printk("CPU %i taken timebase\n", smp_processor_id());
+}
+
+/* CHRP with openpic */
+struct smp_ops_t chrp_smp_ops = {
+ .message_pass = smp_mpic_message_pass,
+ .probe = smp_mpic_probe,
+ .kick_cpu = smp_chrp_kick_cpu,
+ .setup_cpu = smp_chrp_setup_cpu,
+ .give_timebase = smp_chrp_give_timebase,
+ .take_timebase = smp_chrp_take_timebase,
+};
diff --git a/arch/powerpc/platforms/chrp/time.c b/arch/powerpc/platforms/chrp/time.c
new file mode 100644
index 000000000000..9e53535ddb82
--- /dev/null
+++ b/arch/powerpc/platforms/chrp/time.c
@@ -0,0 +1,188 @@
+/*
+ * arch/ppc/platforms/chrp_time.c
+ *
+ * Copyright (C) 1991, 1992, 1995 Linus Torvalds
+ *
+ * Adapted for PowerPC (PReP) by Gary Thomas
+ * Modified by Cort Dougan (cort@cs.nmt.edu).
+ * Copied and modified from arch/i386/kernel/time.c
+ *
+ */
+#include <linux/errno.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/timex.h>
+#include <linux/kernel_stat.h>
+#include <linux/mc146818rtc.h>
+#include <linux/init.h>
+#include <linux/bcd.h>
+
+#include <asm/io.h>
+#include <asm/nvram.h>
+#include <asm/prom.h>
+#include <asm/sections.h>
+#include <asm/time.h>
+
+extern spinlock_t rtc_lock;
+
+static int nvram_as1 = NVRAM_AS1;
+static int nvram_as0 = NVRAM_AS0;
+static int nvram_data = NVRAM_DATA;
+
+long __init chrp_time_init(void)
+{
+ struct device_node *rtcs;
+ int base;
+
+ rtcs = find_compatible_devices("rtc", "pnpPNP,b00");
+ if (rtcs == NULL)
+ rtcs = find_compatible_devices("rtc", "ds1385-rtc");
+ if (rtcs == NULL || rtcs->addrs == NULL)
+ return 0;
+ base = rtcs->addrs[0].address;
+ nvram_as1 = 0;
+ nvram_as0 = base;
+ nvram_data = base + 1;
+
+ return 0;
+}
+
+int chrp_cmos_clock_read(int addr)
+{
+ if (nvram_as1 != 0)
+ outb(addr>>8, nvram_as1);
+ outb(addr, nvram_as0);
+ return (inb(nvram_data));
+}
+
+void chrp_cmos_clock_write(unsigned long val, int addr)
+{
+ if (nvram_as1 != 0)
+ outb(addr>>8, nvram_as1);
+ outb(addr, nvram_as0);
+ outb(val, nvram_data);
+ return;
+}
+
+/*
+ * Set the hardware clock. -- Cort
+ */
+int chrp_set_rtc_time(struct rtc_time *tmarg)
+{
+ unsigned char save_control, save_freq_select;
+ struct rtc_time tm = *tmarg;
+
+ spin_lock(&rtc_lock);
+
+ save_control = chrp_cmos_clock_read(RTC_CONTROL); /* tell the clock it's being set */
+
+ chrp_cmos_clock_write((save_control|RTC_SET), RTC_CONTROL);
+
+ save_freq_select = chrp_cmos_clock_read(RTC_FREQ_SELECT); /* stop and reset prescaler */
+
+ chrp_cmos_clock_write((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT);
+
+ tm.tm_year -= 1900;
+ if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
+ BIN_TO_BCD(tm.tm_sec);
+ BIN_TO_BCD(tm.tm_min);
+ BIN_TO_BCD(tm.tm_hour);
+ BIN_TO_BCD(tm.tm_mon);
+ BIN_TO_BCD(tm.tm_mday);
+ BIN_TO_BCD(tm.tm_year);
+ }
+ chrp_cmos_clock_write(tm.tm_sec,RTC_SECONDS);
+ chrp_cmos_clock_write(tm.tm_min,RTC_MINUTES);
+ chrp_cmos_clock_write(tm.tm_hour,RTC_HOURS);
+ chrp_cmos_clock_write(tm.tm_mon,RTC_MONTH);
+ chrp_cmos_clock_write(tm.tm_mday,RTC_DAY_OF_MONTH);
+ chrp_cmos_clock_write(tm.tm_year,RTC_YEAR);
+
+ /* The following flags have to be released exactly in this order,
+ * otherwise the DS12887 (popular MC146818A clone with integrated
+ * battery and quartz) will not reset the oscillator and will not
+ * update precisely 500 ms later. You won't find this mentioned in
+ * the Dallas Semiconductor data sheets, but who believes data
+ * sheets anyway ... -- Markus Kuhn
+ */
+ chrp_cmos_clock_write(save_control, RTC_CONTROL);
+ chrp_cmos_clock_write(save_freq_select, RTC_FREQ_SELECT);
+
+ spin_unlock(&rtc_lock);
+ return 0;
+}
+
+void chrp_get_rtc_time(struct rtc_time *tm)
+{
+ unsigned int year, mon, day, hour, min, sec;
+ int uip, i;
+
+ /* The Linux interpretation of the CMOS clock register contents:
+ * When the Update-In-Progress (UIP) flag goes from 1 to 0, the
+ * RTC registers show the second which has precisely just started.
+ * Let's hope other operating systems interpret the RTC the same way.
+ */
+
+ /* Since the UIP flag is set for about 2.2 ms and the clock
+ * is typically written with a precision of 1 jiffy, trying
+ * to obtain a precision better than a few milliseconds is
+ * an illusion. Only consistency is interesting, this also
+ * allows to use the routine for /dev/rtc without a potential
+ * 1 second kernel busy loop triggered by any reader of /dev/rtc.
+ */
+
+ for ( i = 0; i<1000000; i++) {
+ uip = chrp_cmos_clock_read(RTC_FREQ_SELECT);
+ sec = chrp_cmos_clock_read(RTC_SECONDS);
+ min = chrp_cmos_clock_read(RTC_MINUTES);
+ hour = chrp_cmos_clock_read(RTC_HOURS);
+ day = chrp_cmos_clock_read(RTC_DAY_OF_MONTH);
+ mon = chrp_cmos_clock_read(RTC_MONTH);
+ year = chrp_cmos_clock_read(RTC_YEAR);
+ uip |= chrp_cmos_clock_read(RTC_FREQ_SELECT);
+ if ((uip & RTC_UIP)==0) break;
+ }
+
+ if (!(chrp_cmos_clock_read(RTC_CONTROL) & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
+ BCD_TO_BIN(sec);
+ BCD_TO_BIN(min);
+ BCD_TO_BIN(hour);
+ BCD_TO_BIN(day);
+ BCD_TO_BIN(mon);
+ BCD_TO_BIN(year);
+ }
+ if ((year += 1900) < 1970)
+ year += 100;
+ tm->tm_sec = sec;
+ tm->tm_min = min;
+ tm->tm_hour = hour;
+ tm->tm_mday = day;
+ tm->tm_mon = mon;
+ tm->tm_year = year;
+}
+
+
+void __init chrp_calibrate_decr(void)
+{
+ struct device_node *cpu;
+ unsigned int freq, *fp;
+
+ /*
+ * The cpu node should have a timebase-frequency property
+ * to tell us the rate at which the decrementer counts.
+ */
+ freq = 16666000; /* hardcoded default */
+ cpu = find_type_devices("cpu");
+ if (cpu != 0) {
+ fp = (unsigned int *)
+ get_property(cpu, "timebase-frequency", NULL);
+ if (fp != 0)
+ freq = *fp;
+ }
+ ppc_tb_freq = freq;
+}
diff --git a/arch/powerpc/platforms/embedded6xx/Kconfig b/arch/powerpc/platforms/embedded6xx/Kconfig
new file mode 100644
index 000000000000..81250090f98d
--- /dev/null
+++ b/arch/powerpc/platforms/embedded6xx/Kconfig
@@ -0,0 +1,318 @@
+choice
+ prompt "Machine Type"
+ depends on EMBEDDED6xx
+
+config KATANA
+ bool "Artesyn-Katana"
+ help
+ Select KATANA if configuring an Artesyn KATANA 750i or 3750
+ cPCI board.
+
+config WILLOW
+ bool "Cogent-Willow"
+
+config CPCI690
+ bool "Force-CPCI690"
+ help
+ Select CPCI690 if configuring a Force CPCI690 cPCI board.
+
+config POWERPMC250
+ bool "Force-PowerPMC250"
+
+config CHESTNUT
+ bool "IBM 750FX Eval board or 750GX Eval board"
+ help
+ Select CHESTNUT if configuring an IBM 750FX Eval Board or a
+ IBM 750GX Eval board.
+
+config SPRUCE
+ bool "IBM-Spruce"
+ select PPC_INDIRECT_PCI
+
+config HDPU
+ bool "Sky-HDPU"
+ help
+ Select HDPU if configuring a Sky Computers Compute Blade.
+
+config HDPU_FEATURES
+ depends HDPU
+ tristate "HDPU-Features"
+ help
+ Select to enable HDPU enhanced features.
+
+config EV64260
+ bool "Marvell-EV64260BP"
+ help
+ Select EV64260 if configuring a Marvell (formerly Galileo)
+ EV64260BP Evaluation platform.
+
+config LOPEC
+ bool "Motorola-LoPEC"
+ select PPC_I8259
+
+config MVME5100
+ bool "Motorola-MVME5100"
+ select PPC_INDIRECT_PCI
+
+config PPLUS
+ bool "Motorola-PowerPlus"
+ select PPC_I8259
+ select PPC_INDIRECT_PCI
+
+config PRPMC750
+ bool "Motorola-PrPMC750"
+ select PPC_INDIRECT_PCI
+
+config PRPMC800
+ bool "Motorola-PrPMC800"
+ select PPC_INDIRECT_PCI
+
+config SANDPOINT
+ bool "Motorola-Sandpoint"
+ select PPC_I8259
+ help
+ Select SANDPOINT if configuring for a Motorola Sandpoint X3
+ (any flavor).
+
+config RADSTONE_PPC7D
+ bool "Radstone Technology PPC7D board"
+ select PPC_I8259
+
+config PAL4
+ bool "SBS-Palomar4"
+
+config GEMINI
+ bool "Synergy-Gemini"
+ select PPC_INDIRECT_PCI
+ depends on BROKEN
+ help
+ Select Gemini if configuring for a Synergy Microsystems' Gemini
+ series Single Board Computer. More information is available at:
+ <http://www.synergymicro.com/PressRel/97_10_15.html>.
+
+config EST8260
+ bool "EST8260"
+ ---help---
+ The EST8260 is a single-board computer manufactured by Wind River
+ Systems, Inc. (formerly Embedded Support Tools Corp.) and based on
+ the MPC8260. Wind River Systems has a website at
+ <http://www.windriver.com/>, but the EST8260 cannot be found on it
+ and has probably been discontinued or rebadged.
+
+config SBC82xx
+ bool "SBC82xx"
+ ---help---
+ SBC PowerQUICC II, single-board computer with MPC82xx CPU
+ Manufacturer: Wind River Systems, Inc.
+ Date of Release: May 2003
+ End of Life: -
+ URL: <http://www.windriver.com/>
+
+config SBS8260
+ bool "SBS8260"
+
+config RPX8260
+ bool "RPXSUPER"
+
+config TQM8260
+ bool "TQM8260"
+ ---help---
+ MPC8260 based module, little larger than credit card,
+ up to 128 MB global + 64 MB local RAM, 32 MB Flash,
+ 32 kB EEPROM, 256 kB L@ Cache, 10baseT + 100baseT Ethernet,
+ 2 x serial ports, ...
+ Manufacturer: TQ Components, www.tq-group.de
+ Date of Release: June 2001
+ End of Life: not yet :-)
+ URL: <http://www.denx.de/PDF/TQM82xx_SPEC_Rev005.pdf>
+
+config ADS8272
+ bool "ADS8272"
+
+config PQ2FADS
+ bool "Freescale-PQ2FADS"
+ help
+ Select PQ2FADS if you wish to configure for a Freescale
+ PQ2FADS board (-VR or -ZU).
+
+config LITE5200
+ bool "Freescale LITE5200 / (IceCube)"
+ select PPC_MPC52xx
+ help
+ Support for the LITE5200 dev board for the MPC5200 from Freescale.
+ This is for the LITE5200 version 2.0 board. Don't know if it changes
+ much but it's only been tested on this board version. I think this
+ board is also known as IceCube.
+
+config MPC834x_SYS
+ bool "Freescale MPC834x SYS"
+ help
+ This option enables support for the MPC 834x SYS evaluation board.
+
+ Be aware that PCI buses can only function when SYS board is plugged
+ into the PIB (Platform IO Board) board from Freescale which provide
+ 3 PCI slots. The PIBs PCI initialization is the bootloader's
+ responsiblilty.
+
+config EV64360
+ bool "Marvell-EV64360BP"
+ help
+ Select EV64360 if configuring a Marvell EV64360BP Evaluation
+ platform.
+endchoice
+
+config PQ2ADS
+ bool
+ depends on ADS8272
+ default y
+
+config TQM8xxL
+ bool
+ depends on 8xx && (TQM823L || TQM850L || FPS850L || TQM855L || TQM860L)
+ default y
+
+config PPC_MPC52xx
+ bool
+
+config 8260
+ bool "CPM2 Support" if WILLOW
+ depends on 6xx
+ default y if TQM8260 || RPX8260 || EST8260 || SBS8260 || SBC82xx || PQ2FADS
+ help
+ The MPC8260 is a typical embedded CPU made by Motorola. Selecting
+ this option means that you wish to build a kernel for a machine with
+ an 8260 class CPU.
+
+config 8272
+ bool
+ depends on 6xx
+ default y if ADS8272
+ select 8260
+ help
+ The MPC8272 CPM has a different internal dpram setup than other CPM2
+ devices
+
+config 83xx
+ bool
+ default y if MPC834x_SYS
+
+config MPC834x
+ bool
+ default y if MPC834x_SYS
+
+config CPM2
+ bool
+ depends on 8260 || MPC8560 || MPC8555
+ default y
+ help
+ The CPM2 (Communications Processor Module) is a coprocessor on
+ embedded CPUs made by Motorola. Selecting this option means that
+ you wish to build a kernel for a machine with a CPM2 coprocessor
+ on it (826x, 827x, 8560).
+
+config PPC_GEN550
+ bool
+ depends on SANDPOINT || SPRUCE || PPLUS || \
+ PRPMC750 || PRPMC800 || LOPEC || \
+ (EV64260 && !SERIAL_MPSC) || CHESTNUT || RADSTONE_PPC7D || \
+ 83xx
+ default y
+
+config FORCE
+ bool
+ depends on 6xx && POWERPMC250
+ default y
+
+config GT64260
+ bool
+ depends on EV64260 || CPCI690
+ default y
+
+config MV64360 # Really MV64360 & MV64460
+ bool
+ depends on CHESTNUT || KATANA || RADSTONE_PPC7D || HDPU || EV64360
+ default y
+
+config MV64X60
+ bool
+ depends on (GT64260 || MV64360)
+ select PPC_INDIRECT_PCI
+ default y
+
+menu "Set bridge options"
+ depends on MV64X60
+
+config NOT_COHERENT_CACHE
+ bool "Turn off Cache Coherency"
+ default n
+ help
+ Some 64x60 bridges lock up when trying to enforce cache coherency.
+ When this option is selected, cache coherency will be turned off.
+ Note that this can cause other problems (e.g., stale data being
+ speculatively loaded via a cached mapping). Use at your own risk.
+
+config MV64X60_BASE
+ hex "Set bridge base used by firmware"
+ default "0xf1000000"
+ help
+ A firmware can leave the base address of the bridge's registers at
+ a non-standard location. If so, set this value to reflect the
+ address of that non-standard location.
+
+config MV64X60_NEW_BASE
+ hex "Set bridge base used by kernel"
+ default "0xf1000000"
+ help
+ If the current base address of the bridge's registers is not where
+ you want it, set this value to the address that you want it moved to.
+
+endmenu
+
+config NONMONARCH_SUPPORT
+ bool "Enable Non-Monarch Support"
+ depends on PRPMC800
+
+config HARRIER
+ bool
+ depends on PRPMC800
+ default y
+
+config EPIC_SERIAL_MODE
+ bool
+ depends on 6xx && (LOPEC || SANDPOINT)
+ default y
+
+config MPC10X_BRIDGE
+ bool
+ depends on POWERPMC250 || LOPEC || SANDPOINT
+ select PPC_INDIRECT_PCI
+ default y
+
+config MPC10X_OPENPIC
+ bool
+ depends on POWERPMC250 || LOPEC || SANDPOINT
+ default y
+
+config MPC10X_STORE_GATHERING
+ bool "Enable MPC10x store gathering"
+ depends on MPC10X_BRIDGE
+
+config SANDPOINT_ENABLE_UART1
+ bool "Enable DUART mode on Sandpoint"
+ depends on SANDPOINT
+ help
+ If this option is enabled then the MPC824x processor will run
+ in DUART mode instead of UART mode.
+
+config HARRIER_STORE_GATHERING
+ bool "Enable Harrier store gathering"
+ depends on HARRIER
+
+config MVME5100_IPMC761_PRESENT
+ bool "MVME5100 configured with an IPMC761"
+ depends on MVME5100
+ select PPC_I8259
+
+config SPRUCE_BAUD_33M
+ bool "Spruce baud clock support"
+ depends on SPRUCE
diff --git a/arch/powerpc/platforms/iseries/Kconfig b/arch/powerpc/platforms/iseries/Kconfig
new file mode 100644
index 000000000000..3d957a30c8c2
--- /dev/null
+++ b/arch/powerpc/platforms/iseries/Kconfig
@@ -0,0 +1,31 @@
+
+menu "iSeries device drivers"
+ depends on PPC_ISERIES
+
+config VIOCONS
+ tristate "iSeries Virtual Console Support"
+
+config VIODASD
+ tristate "iSeries Virtual I/O disk support"
+ help
+ If you are running on an iSeries system and you want to use
+ virtual disks created and managed by OS/400, say Y.
+
+config VIOCD
+ tristate "iSeries Virtual I/O CD support"
+ help
+ If you are running Linux on an IBM iSeries system and you want to
+ read a CD drive owned by OS/400, say Y here.
+
+config VIOTAPE
+ tristate "iSeries Virtual Tape Support"
+ help
+ If you are running Linux on an iSeries system and you want Linux
+ to read and/or write a tape drive owned by OS/400, say Y here.
+
+endmenu
+
+config VIOPATH
+ bool
+ depends on VIOCONS || VIODASD || VIOCD || VIOTAPE || VETH
+ default y
diff --git a/arch/powerpc/platforms/iseries/Makefile b/arch/powerpc/platforms/iseries/Makefile
new file mode 100644
index 000000000000..127b465308be
--- /dev/null
+++ b/arch/powerpc/platforms/iseries/Makefile
@@ -0,0 +1,9 @@
+EXTRA_CFLAGS += -mno-minimal-toc
+
+obj-y += hvlog.o hvlpconfig.o lpardata.o setup.o mf.o lpevents.o \
+ hvcall.o proc.o htab.o iommu.o misc.o
+obj-$(CONFIG_PCI) += pci.o irq.o vpdinfo.o
+obj-$(CONFIG_IBMVIO) += vio.o
+obj-$(CONFIG_SMP) += smp.o
+obj-$(CONFIG_VIOPATH) += viopath.o
+obj-$(CONFIG_MODULES) += ksyms.o
diff --git a/include/asm-ppc64/iSeries/HvCallHpt.h b/arch/powerpc/platforms/iseries/call_hpt.h
index 43a1969230b8..a843b0f87b72 100644
--- a/include/asm-ppc64/iSeries/HvCallHpt.h
+++ b/arch/powerpc/platforms/iseries/call_hpt.h
@@ -1,5 +1,4 @@
/*
- * HvCallHpt.h
* Copyright (C) 2001 Mike Corrigan IBM Corporation
*
* This program is free software; you can redistribute it and/or modify
@@ -16,16 +15,16 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#ifndef _HVCALLHPT_H
-#define _HVCALLHPT_H
+#ifndef _PLATFORMS_ISERIES_CALL_HPT_H
+#define _PLATFORMS_ISERIES_CALL_HPT_H
/*
* This file contains the "hypervisor call" interface which is used to
* drive the hypervisor from the OS.
*/
-#include <asm/iSeries/HvCallSc.h>
-#include <asm/iSeries/HvTypes.h>
+#include <asm/iseries/hv_call_sc.h>
+#include <asm/iseries/hv_types.h>
#include <asm/mmu.h>
#define HvCallHptGetHptAddress HvCallHpt + 0
@@ -99,4 +98,4 @@ static inline void HvCallHpt_addValidate(u32 hpteIndex, u32 hBit, hpte_t *hpte)
HvCall4(HvCallHptAddValidate, hpteIndex, hBit, hpte->v, hpte->r);
}
-#endif /* _HVCALLHPT_H */
+#endif /* _PLATFORMS_ISERIES_CALL_HPT_H */
diff --git a/include/asm-ppc64/iSeries/HvCallPci.h b/arch/powerpc/platforms/iseries/call_pci.h
index c8d675c40f5e..59d4e0ad5cf3 100644
--- a/include/asm-ppc64/iSeries/HvCallPci.h
+++ b/arch/powerpc/platforms/iseries/call_pci.h
@@ -22,11 +22,11 @@
* Created, Jan 9, 2001
*/
-#ifndef _HVCALLPCI_H
-#define _HVCALLPCI_H
+#ifndef _PLATFORMS_ISERIES_CALL_PCI_H
+#define _PLATFORMS_ISERIES_CALL_PCI_H
-#include <asm/iSeries/HvCallSc.h>
-#include <asm/iSeries/HvTypes.h>
+#include <asm/iseries/hv_call_sc.h>
+#include <asm/iseries/hv_types.h>
/*
* DSA == Direct Select Address
@@ -126,25 +126,6 @@ enum HvCallPci_VpdType {
#define HvCallPciUnmaskInterrupts HvCallPci + 49
#define HvCallPciGetBusUnitInfo HvCallPci + 50
-static inline u64 HvCallPci_configLoad8(u16 busNumber, u8 subBusNumber,
- u8 deviceId, u32 offset, u8 *value)
-{
- struct HvCallPci_DsaAddr dsa;
- struct HvCallPci_LoadReturn retVal;
-
- *((u64*)&dsa) = 0;
-
- dsa.busNumber = busNumber;
- dsa.subBusNumber = subBusNumber;
- dsa.deviceId = deviceId;
-
- HvCall3Ret16(HvCallPciConfigLoad8, &retVal, *(u64 *)&dsa, offset, 0);
-
- *value = retVal.value;
-
- return retVal.rc;
-}
-
static inline u64 HvCallPci_configLoad16(u16 busNumber, u8 subBusNumber,
u8 deviceId, u32 offset, u16 *value)
{
@@ -164,25 +145,6 @@ static inline u64 HvCallPci_configLoad16(u16 busNumber, u8 subBusNumber,
return retVal.rc;
}
-static inline u64 HvCallPci_configLoad32(u16 busNumber, u8 subBusNumber,
- u8 deviceId, u32 offset, u32 *value)
-{
- struct HvCallPci_DsaAddr dsa;
- struct HvCallPci_LoadReturn retVal;
-
- *((u64*)&dsa) = 0;
-
- dsa.busNumber = busNumber;
- dsa.subBusNumber = subBusNumber;
- dsa.deviceId = deviceId;
-
- HvCall3Ret16(HvCallPciConfigLoad32, &retVal, *(u64 *)&dsa, offset, 0);
-
- *value = retVal.value;
-
- return retVal.rc;
-}
-
static inline u64 HvCallPci_configStore8(u16 busNumber, u8 subBusNumber,
u8 deviceId, u32 offset, u8 value)
{
@@ -197,186 +159,6 @@ static inline u64 HvCallPci_configStore8(u16 busNumber, u8 subBusNumber,
return HvCall4(HvCallPciConfigStore8, *(u64 *)&dsa, offset, value, 0);
}
-static inline u64 HvCallPci_configStore16(u16 busNumber, u8 subBusNumber,
- u8 deviceId, u32 offset, u16 value)
-{
- struct HvCallPci_DsaAddr dsa;
-
- *((u64*)&dsa) = 0;
-
- dsa.busNumber = busNumber;
- dsa.subBusNumber = subBusNumber;
- dsa.deviceId = deviceId;
-
- return HvCall4(HvCallPciConfigStore16, *(u64 *)&dsa, offset, value, 0);
-}
-
-static inline u64 HvCallPci_configStore32(u16 busNumber, u8 subBusNumber,
- u8 deviceId, u32 offset, u32 value)
-{
- struct HvCallPci_DsaAddr dsa;
-
- *((u64*)&dsa) = 0;
-
- dsa.busNumber = busNumber;
- dsa.subBusNumber = subBusNumber;
- dsa.deviceId = deviceId;
-
- return HvCall4(HvCallPciConfigStore32, *(u64 *)&dsa, offset, value, 0);
-}
-
-static inline u64 HvCallPci_barLoad8(u16 busNumberParm, u8 subBusParm,
- u8 deviceIdParm, u8 barNumberParm, u64 offsetParm,
- u8 *valueParm)
-{
- struct HvCallPci_DsaAddr dsa;
- struct HvCallPci_LoadReturn retVal;
-
- *((u64*)&dsa) = 0;
-
- dsa.busNumber = busNumberParm;
- dsa.subBusNumber = subBusParm;
- dsa.deviceId = deviceIdParm;
- dsa.barNumber = barNumberParm;
-
- HvCall3Ret16(HvCallPciBarLoad8, &retVal, *(u64 *)&dsa, offsetParm, 0);
-
- *valueParm = retVal.value;
-
- return retVal.rc;
-}
-
-static inline u64 HvCallPci_barLoad16(u16 busNumberParm, u8 subBusParm,
- u8 deviceIdParm, u8 barNumberParm, u64 offsetParm,
- u16 *valueParm)
-{
- struct HvCallPci_DsaAddr dsa;
- struct HvCallPci_LoadReturn retVal;
-
- *((u64*)&dsa) = 0;
-
- dsa.busNumber = busNumberParm;
- dsa.subBusNumber = subBusParm;
- dsa.deviceId = deviceIdParm;
- dsa.barNumber = barNumberParm;
-
- HvCall3Ret16(HvCallPciBarLoad16, &retVal, *(u64 *)&dsa, offsetParm, 0);
-
- *valueParm = retVal.value;
-
- return retVal.rc;
-}
-
-static inline u64 HvCallPci_barLoad32(u16 busNumberParm, u8 subBusParm,
- u8 deviceIdParm, u8 barNumberParm, u64 offsetParm,
- u32 *valueParm)
-{
- struct HvCallPci_DsaAddr dsa;
- struct HvCallPci_LoadReturn retVal;
-
- *((u64*)&dsa) = 0;
-
- dsa.busNumber = busNumberParm;
- dsa.subBusNumber = subBusParm;
- dsa.deviceId = deviceIdParm;
- dsa.barNumber = barNumberParm;
-
- HvCall3Ret16(HvCallPciBarLoad32, &retVal, *(u64 *)&dsa, offsetParm, 0);
-
- *valueParm = retVal.value;
-
- return retVal.rc;
-}
-
-static inline u64 HvCallPci_barLoad64(u16 busNumberParm, u8 subBusParm,
- u8 deviceIdParm, u8 barNumberParm, u64 offsetParm,
- u64 *valueParm)
-{
- struct HvCallPci_DsaAddr dsa;
- struct HvCallPci_LoadReturn retVal;
-
- *((u64*)&dsa) = 0;
-
- dsa.busNumber = busNumberParm;
- dsa.subBusNumber = subBusParm;
- dsa.deviceId = deviceIdParm;
- dsa.barNumber = barNumberParm;
-
- HvCall3Ret16(HvCallPciBarLoad64, &retVal, *(u64 *)&dsa, offsetParm, 0);
-
- *valueParm = retVal.value;
-
- return retVal.rc;
-}
-
-static inline u64 HvCallPci_barStore8(u16 busNumberParm, u8 subBusParm,
- u8 deviceIdParm, u8 barNumberParm, u64 offsetParm,
- u8 valueParm)
-{
- struct HvCallPci_DsaAddr dsa;
-
- *((u64*)&dsa) = 0;
-
- dsa.busNumber = busNumberParm;
- dsa.subBusNumber = subBusParm;
- dsa.deviceId = deviceIdParm;
- dsa.barNumber = barNumberParm;
-
- return HvCall4(HvCallPciBarStore8, *(u64 *)&dsa, offsetParm,
- valueParm, 0);
-}
-
-static inline u64 HvCallPci_barStore16(u16 busNumberParm, u8 subBusParm,
- u8 deviceIdParm, u8 barNumberParm, u64 offsetParm,
- u16 valueParm)
-{
- struct HvCallPci_DsaAddr dsa;
-
- *((u64*)&dsa) = 0;
-
- dsa.busNumber = busNumberParm;
- dsa.subBusNumber = subBusParm;
- dsa.deviceId = deviceIdParm;
- dsa.barNumber = barNumberParm;
-
- return HvCall4(HvCallPciBarStore16, *(u64 *)&dsa, offsetParm,
- valueParm, 0);
-}
-
-static inline u64 HvCallPci_barStore32(u16 busNumberParm, u8 subBusParm,
- u8 deviceIdParm, u8 barNumberParm, u64 offsetParm,
- u32 valueParm)
-{
- struct HvCallPci_DsaAddr dsa;
-
- *((u64*)&dsa) = 0;
-
- dsa.busNumber = busNumberParm;
- dsa.subBusNumber = subBusParm;
- dsa.deviceId = deviceIdParm;
- dsa.barNumber = barNumberParm;
-
- return HvCall4(HvCallPciBarStore32, *(u64 *)&dsa, offsetParm,
- valueParm, 0);
-}
-
-static inline u64 HvCallPci_barStore64(u16 busNumberParm, u8 subBusParm,
- u8 deviceIdParm, u8 barNumberParm, u64 offsetParm,
- u64 valueParm)
-{
- struct HvCallPci_DsaAddr dsa;
-
- *((u64*)&dsa) = 0;
-
- dsa.busNumber = busNumberParm;
- dsa.subBusNumber = subBusParm;
- dsa.deviceId = deviceIdParm;
- dsa.barNumber = barNumberParm;
-
- return HvCall4(HvCallPciBarStore64, *(u64 *)&dsa, offsetParm,
- valueParm, 0);
-}
-
static inline u64 HvCallPci_eoi(u16 busNumberParm, u8 subBusParm,
u8 deviceIdParm)
{
@@ -437,20 +219,6 @@ static inline u64 HvCallPci_unmaskFisr(u16 busNumberParm, u8 subBusParm,
return HvCall2(HvCallPciUnmaskFisr, *(u64*)&dsa, fisrMask);
}
-static inline u64 HvCallPci_setSlotReset(u16 busNumberParm, u8 subBusParm,
- u8 deviceIdParm, u64 onNotOff)
-{
- struct HvCallPci_DsaAddr dsa;
-
- *((u64*)&dsa) = 0;
-
- dsa.busNumber = busNumberParm;
- dsa.subBusNumber = subBusParm;
- dsa.deviceId = deviceIdParm;
-
- return HvCall2(HvCallPciSetSlotReset, *(u64*)&dsa, onNotOff);
-}
-
static inline u64 HvCallPci_getDeviceInfo(u16 busNumberParm, u8 subBusParm,
u8 deviceNumberParm, u64 parms, u32 sizeofParms)
{
@@ -519,15 +287,4 @@ static inline int HvCallPci_getBusVpd(u16 busNumParm, u64 destParm,
return xRc & 0xFFFF;
}
-static inline int HvCallPci_getBusAdapterVpd(u16 busNumParm, u64 destParm,
- u16 sizeParm)
-{
- u64 xRc = HvCall4(HvCallPciGetCardVpd, busNumParm, destParm,
- sizeParm, HvCallPci_BusAdapterVpd);
- if (xRc == -1)
- return -1;
- else
- return xRc & 0xFFFF;
-}
-
-#endif /* _HVCALLPCI_H */
+#endif /* _PLATFORMS_ISERIES_CALL_PCI_H */
diff --git a/include/asm-ppc64/iSeries/HvCallSm.h b/arch/powerpc/platforms/iseries/call_sm.h
index 8a3dbb071a43..c7e251619f48 100644
--- a/include/asm-ppc64/iSeries/HvCallSm.h
+++ b/arch/powerpc/platforms/iseries/call_sm.h
@@ -1,5 +1,4 @@
/*
- * HvCallSm.h
* Copyright (C) 2001 Mike Corrigan IBM Corporation
*
* This program is free software; you can redistribute it and/or modify
@@ -16,16 +15,16 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#ifndef _HVCALLSM_H
-#define _HVCALLSM_H
+#ifndef _ISERIES_CALL_SM_H
+#define _ISERIES_CALL_SM_H
/*
* This file contains the "hypervisor call" interface which is used to
* drive the hypervisor from the OS.
*/
-#include <asm/iSeries/HvCallSc.h>
-#include <asm/iSeries/HvTypes.h>
+#include <asm/iseries/hv_call_sc.h>
+#include <asm/iseries/hv_types.h>
#define HvCallSmGet64BitsOfAccessMap HvCallSm + 11
@@ -35,4 +34,4 @@ static inline u64 HvCallSm_get64BitsOfAccessMap(HvLpIndex lpIndex,
return HvCall2(HvCallSmGet64BitsOfAccessMap, lpIndex, indexIntoBitMap);
}
-#endif /* _HVCALLSM_H */
+#endif /* _ISERIES_CALL_SM_H */
diff --git a/arch/ppc64/kernel/iSeries_htab.c b/arch/powerpc/platforms/iseries/htab.c
index 073b76661747..30bdcf3925d9 100644
--- a/arch/ppc64/kernel/iSeries_htab.c
+++ b/arch/powerpc/platforms/iseries/htab.c
@@ -1,10 +1,10 @@
/*
* iSeries hashtable management.
- * Derived from pSeries_htab.c
+ * Derived from pSeries_htab.c
*
* SMP scalability work:
* Copyright (C) 2001 Anton Blanchard <anton@au.ibm.com>, IBM
- *
+ *
* 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
@@ -14,11 +14,13 @@
#include <asm/pgtable.h>
#include <asm/mmu.h>
#include <asm/mmu_context.h>
-#include <asm/iSeries/HvCallHpt.h>
#include <asm/abs_addr.h>
#include <linux/spinlock.h>
-static spinlock_t iSeries_hlocks[64] __cacheline_aligned_in_smp = { [0 ... 63] = SPIN_LOCK_UNLOCKED};
+#include "call_hpt.h"
+
+static spinlock_t iSeries_hlocks[64] __cacheline_aligned_in_smp =
+ { [0 ... 63] = SPIN_LOCK_UNLOCKED};
/*
* Very primitive algorithm for picking up a lock
@@ -37,15 +39,16 @@ static inline void iSeries_hunlock(unsigned long slot)
spin_unlock(&iSeries_hlocks[(slot >> 4) & 0x3f]);
}
-static long iSeries_hpte_insert(unsigned long hpte_group, unsigned long va,
- unsigned long prpn, unsigned long vflags,
- unsigned long rflags)
+long iSeries_hpte_insert(unsigned long hpte_group, unsigned long va,
+ unsigned long pa, unsigned long rflags,
+ unsigned long vflags, int psize)
{
- unsigned long arpn;
long slot;
hpte_t lhpte;
int secondary = 0;
+ BUG_ON(psize != MMU_PAGE_4K);
+
/*
* The hypervisor tries both primary and secondary.
* If we are being called to insert in the secondary,
@@ -57,8 +60,19 @@ static long iSeries_hpte_insert(unsigned long hpte_group, unsigned long va,
iSeries_hlock(hpte_group);
- slot = HvCallHpt_findValid(&lhpte, va >> PAGE_SHIFT);
- BUG_ON(lhpte.v & HPTE_V_VALID);
+ slot = HvCallHpt_findValid(&lhpte, va >> HW_PAGE_SHIFT);
+ if (unlikely(lhpte.v & HPTE_V_VALID)) {
+ if (vflags & HPTE_V_BOLTED) {
+ HvCallHpt_setSwBits(slot, 0x10, 0);
+ HvCallHpt_setPp(slot, PP_RWXX);
+ iSeries_hunlock(hpte_group);
+ if (slot < 0)
+ return 0x8 | (slot & 7);
+ else
+ return slot & 7;
+ }
+ BUG();
+ }
if (slot == -1) { /* No available entry found in either group */
iSeries_hunlock(hpte_group);
@@ -71,10 +85,9 @@ static long iSeries_hpte_insert(unsigned long hpte_group, unsigned long va,
slot &= 0x7fffffffffffffff;
}
- arpn = phys_to_abs(prpn << PAGE_SHIFT) >> PAGE_SHIFT;
- lhpte.v = (va >> 23) << HPTE_V_AVPN_SHIFT | vflags | HPTE_V_VALID;
- lhpte.r = (arpn << HPTE_R_RPN_SHIFT) | rflags;
+ lhpte.v = hpte_encode_v(va, MMU_PAGE_4K) | vflags | HPTE_V_VALID;
+ lhpte.r = hpte_encode_r(phys_to_abs(pa), MMU_PAGE_4K) | rflags;
/* Now fill in the actual HPTE */
HvCallHpt_addValidate(slot, secondary, &lhpte);
@@ -107,7 +120,7 @@ static long iSeries_hpte_remove(unsigned long hpte_group)
hpte_v = iSeries_hpte_getword0(hpte_group + slot_offset);
if (! (hpte_v & HPTE_V_BOLTED)) {
- HvCallHpt_invalidateSetSwBitsGet(hpte_group +
+ HvCallHpt_invalidateSetSwBitsGet(hpte_group +
slot_offset, 0, 0);
iSeries_hunlock(hpte_group);
return i;
@@ -124,20 +137,22 @@ static long iSeries_hpte_remove(unsigned long hpte_group)
/*
* The HyperVisor expects the "flags" argument in this form:
- * bits 0..59 : reserved
- * bit 60 : N
- * bits 61..63 : PP2,PP1,PP0
+ * bits 0..59 : reserved
+ * bit 60 : N
+ * bits 61..63 : PP2,PP1,PP0
*/
static long iSeries_hpte_updatepp(unsigned long slot, unsigned long newpp,
- unsigned long va, int large, int local)
+ unsigned long va, int psize, int local)
{
hpte_t hpte;
- unsigned long avpn = va >> 23;
+ unsigned long want_v;
iSeries_hlock(slot);
HvCallHpt_get(&hpte, slot);
- if ((HPTE_V_AVPN_VAL(hpte.v) == avpn) && (hpte.v & HPTE_V_VALID)) {
+ want_v = hpte_encode_v(va, MMU_PAGE_4K);
+
+ if (HPTE_V_COMPARE(hpte.v, want_v) && (hpte.v & HPTE_V_VALID)) {
/*
* Hypervisor expects bits as NPPP, which is
* different from how they are mapped in our PP.
@@ -152,7 +167,7 @@ static long iSeries_hpte_updatepp(unsigned long slot, unsigned long newpp,
}
/*
- * Functions used to find the PTE for a particular virtual address.
+ * Functions used to find the PTE for a particular virtual address.
* Only used during boot when bolting pages.
*
* Input : vpn : virtual page number
@@ -170,7 +185,7 @@ static long iSeries_hpte_find(unsigned long vpn)
* 0x00000000xxxxxxxx : Entry found in primary group, slot x
* 0x80000000xxxxxxxx : Entry found in secondary group, slot x
*/
- slot = HvCallHpt_findValid(&hpte, vpn);
+ slot = HvCallHpt_findValid(&hpte, vpn);
if (hpte.v & HPTE_V_VALID) {
if (slot < 0) {
slot &= 0x7fffffffffffffff;
@@ -189,22 +204,25 @@ static long iSeries_hpte_find(unsigned long vpn)
*
* No need to lock here because we should be the only user.
*/
-static void iSeries_hpte_updateboltedpp(unsigned long newpp, unsigned long ea)
+static void iSeries_hpte_updateboltedpp(unsigned long newpp, unsigned long ea,
+ int psize)
{
unsigned long vsid,va,vpn;
long slot;
+ BUG_ON(psize != MMU_PAGE_4K);
+
vsid = get_kernel_vsid(ea);
va = (vsid << 28) | (ea & 0x0fffffff);
- vpn = va >> PAGE_SHIFT;
- slot = iSeries_hpte_find(vpn);
+ vpn = va >> HW_PAGE_SHIFT;
+ slot = iSeries_hpte_find(vpn);
if (slot == -1)
panic("updateboltedpp: Could not find page to bolt\n");
HvCallHpt_setPp(slot, newpp);
}
static void iSeries_hpte_invalidate(unsigned long slot, unsigned long va,
- int large, int local)
+ int psize, int local)
{
unsigned long hpte_v;
unsigned long avpn = va >> 23;
@@ -215,7 +233,7 @@ static void iSeries_hpte_invalidate(unsigned long slot, unsigned long va,
iSeries_hlock(slot);
hpte_v = iSeries_hpte_getword0(slot);
-
+
if ((HPTE_V_AVPN_VAL(hpte_v) == avpn) && (hpte_v & HPTE_V_VALID))
HvCallHpt_invalidateSetSwBitsGet(slot, 0, 0);
@@ -230,7 +248,7 @@ void hpte_init_iSeries(void)
ppc_md.hpte_updatepp = iSeries_hpte_updatepp;
ppc_md.hpte_updateboltedpp = iSeries_hpte_updateboltedpp;
ppc_md.hpte_insert = iSeries_hpte_insert;
- ppc_md.hpte_remove = iSeries_hpte_remove;
+ ppc_md.hpte_remove = iSeries_hpte_remove;
htab_finish_init();
}
diff --git a/arch/ppc64/kernel/hvCall.S b/arch/powerpc/platforms/iseries/hvcall.S
index 4c699eab1b95..07ae6ad5f49f 100644
--- a/arch/ppc64/kernel/hvCall.S
+++ b/arch/powerpc/platforms/iseries/hvcall.S
@@ -1,7 +1,4 @@
/*
- * arch/ppc64/kernel/hvCall.S
- *
- *
* This file contains the code to perform calls to the
* iSeries LPAR hypervisor
*
@@ -13,15 +10,16 @@
#include <asm/ppc_asm.h>
#include <asm/processor.h>
+#include <asm/ptrace.h> /* XXX for STACK_FRAME_OVERHEAD */
.text
-/*
+/*
* Hypervisor call
- *
+ *
* Invoke the iSeries hypervisor via the System Call instruction
* Parameters are passed to this routine in registers r3 - r10
- *
+ *
* r3 contains the HV function to be called
* r4-r10 contain the operands to the hypervisor function
*
@@ -41,11 +39,11 @@ _GLOBAL(HvCall7)
mfcr r0
std r0,-8(r1)
stdu r1,-(STACK_FRAME_OVERHEAD+16)(r1)
-
+
/* r0 = 0xffffffffffffffff indicates a hypervisor call */
-
+
li r0,-1
-
+
/* Invoke the hypervisor */
sc
@@ -55,7 +53,7 @@ _GLOBAL(HvCall7)
mtcrf 0xff,r0
/* return to caller, return value in r3 */
-
+
blr
_GLOBAL(HvCall0Ret16)
@@ -92,7 +90,5 @@ _GLOBAL(HvCall7Ret16)
ld r0,-8(r1)
mtcrf 0xff,r0
ld r31,-16(r1)
-
- blr
-
+ blr
diff --git a/arch/ppc64/kernel/HvCall.c b/arch/powerpc/platforms/iseries/hvlog.c
index b772e65b57a2..f476d71194fa 100644
--- a/arch/ppc64/kernel/HvCall.c
+++ b/arch/powerpc/platforms/iseries/hvlog.c
@@ -1,5 +1,4 @@
/*
- * HvCall.c
* Copyright (C) 2001 Mike Corrigan IBM Corporation
*
* This program is free software; you can redistribute it and/or modify
@@ -10,9 +9,9 @@
#include <asm/page.h>
#include <asm/abs_addr.h>
-#include <asm/iSeries/HvCall.h>
-#include <asm/iSeries/HvCallSc.h>
-#include <asm/iSeries/HvTypes.h>
+#include <asm/iseries/hv_call.h>
+#include <asm/iseries/hv_call_sc.h>
+#include <asm/iseries/hv_types.h>
void HvCall_writeLogBuffer(const void *buffer, u64 len)
@@ -23,7 +22,7 @@ void HvCall_writeLogBuffer(const void *buffer, u64 len)
while (len) {
hv_buf.addr = cur;
- left_this_page = ((cur & PAGE_MASK) + PAGE_SIZE) - cur;
+ left_this_page = ((cur & HW_PAGE_MASK) + HW_PAGE_SIZE) - cur;
if (left_this_page > len)
left_this_page = len;
hv_buf.len = left_this_page;
@@ -31,6 +30,6 @@ void HvCall_writeLogBuffer(const void *buffer, u64 len)
HvCall2(HvCallBaseWriteLogBuffer,
virt_to_abs(&hv_buf),
left_this_page);
- cur = (cur & PAGE_MASK) + PAGE_SIZE;
+ cur = (cur & HW_PAGE_MASK) + HW_PAGE_SIZE;
}
}
diff --git a/arch/ppc64/kernel/HvLpConfig.c b/arch/powerpc/platforms/iseries/hvlpconfig.c
index cb1d6473203c..663a1affb4bb 100644
--- a/arch/ppc64/kernel/HvLpConfig.c
+++ b/arch/powerpc/platforms/iseries/hvlpconfig.c
@@ -1,5 +1,4 @@
/*
- * HvLpConfig.c
* Copyright (C) 2001 Kyle A. Lucke, IBM Corporation
*
* This program is free software; you can redistribute it and/or modify
@@ -18,7 +17,7 @@
*/
#include <linux/module.h>
-#include <asm/iSeries/HvLpConfig.h>
+#include <asm/iseries/hv_lp_config.h>
HvLpIndex HvLpConfig_getLpIndex_outline(void)
{
diff --git a/arch/ppc64/kernel/iSeries_iommu.c b/arch/powerpc/platforms/iseries/iommu.c
index f8ff1bb054dc..bf081b345820 100644
--- a/arch/ppc64/kernel/iSeries_iommu.c
+++ b/arch/powerpc/platforms/iseries/iommu.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc64/kernel/iSeries_iommu.c
- *
* Copyright (C) 2001 Mike Corrigan & Dave Engebretsen, IBM Corporation
*
* Rewrite, cleanup:
@@ -30,9 +28,11 @@
#include <linux/list.h>
#include <asm/iommu.h>
+#include <asm/tce.h>
#include <asm/machdep.h>
-#include <asm/iSeries/HvCallXm.h>
-#include <asm/iSeries/iSeries_pci.h>
+#include <asm/abs_addr.h>
+#include <asm/pci-bridge.h>
+#include <asm/iseries/hv_call_xm.h>
extern struct list_head iSeries_Global_Device_List;
@@ -43,9 +43,12 @@ static void tce_build_iSeries(struct iommu_table *tbl, long index, long npages,
u64 rc;
union tce_entry tce;
+ index <<= TCE_PAGE_FACTOR;
+ npages <<= TCE_PAGE_FACTOR;
+
while (npages--) {
tce.te_word = 0;
- tce.te_bits.tb_rpn = virt_to_abs(uaddr) >> PAGE_SHIFT;
+ tce.te_bits.tb_rpn = virt_to_abs(uaddr) >> TCE_SHIFT;
if (tbl->it_type == TCE_VB) {
/* Virtual Bus */
@@ -66,7 +69,7 @@ static void tce_build_iSeries(struct iommu_table *tbl, long index, long npages,
panic("PCI_DMA: HvCallXm_setTce failed, Rc: 0x%lx\n",
rc);
index++;
- uaddr += PAGE_SIZE;
+ uaddr += TCE_PAGE_SIZE;
}
}
@@ -74,6 +77,9 @@ static void tce_free_iSeries(struct iommu_table *tbl, long index, long npages)
{
u64 rc;
+ npages <<= TCE_PAGE_FACTOR;
+ index <<= TCE_PAGE_FACTOR;
+
while (npages--) {
rc = HvCallXm_setTce((u64)tbl->it_index, (u64)index, 0);
if (rc)
@@ -83,26 +89,6 @@ static void tce_free_iSeries(struct iommu_table *tbl, long index, long npages)
}
}
-#ifdef CONFIG_PCI
-/*
- * This function compares the known tables to find an iommu_table
- * that has already been built for hardware TCEs.
- */
-static struct iommu_table *iommu_table_find(struct iommu_table * tbl)
-{
- struct iSeries_Device_Node *dp;
-
- list_for_each_entry(dp, &iSeries_Global_Device_List, Device_List) {
- if ((dp->iommu_table != NULL) &&
- (dp->iommu_table->it_type == TCE_PCI) &&
- (dp->iommu_table->it_offset == tbl->it_offset) &&
- (dp->iommu_table->it_index == tbl->it_index) &&
- (dp->iommu_table->it_size == tbl->it_size))
- return dp->iommu_table;
- }
- return NULL;
-}
-
/*
* Call Hv with the architected data structure to get TCE table info.
* info. Put the returned data into the Linux representation of the
@@ -112,8 +98,10 @@ static struct iommu_table *iommu_table_find(struct iommu_table * tbl)
* 2. TCE table per Bus.
* 3. TCE Table per IOA.
*/
-static void iommu_table_getparms(struct iSeries_Device_Node* dn,
- struct iommu_table* tbl)
+void iommu_table_getparms_iSeries(unsigned long busno,
+ unsigned char slotno,
+ unsigned char virtbus,
+ struct iommu_table* tbl)
{
struct iommu_table_cb *parms;
@@ -123,39 +111,63 @@ static void iommu_table_getparms(struct iSeries_Device_Node* dn,
memset(parms, 0, sizeof(*parms));
- parms->itc_busno = ISERIES_BUS(dn);
- parms->itc_slotno = dn->LogicalSlot;
- parms->itc_virtbus = 0;
+ parms->itc_busno = busno;
+ parms->itc_slotno = slotno;
+ parms->itc_virtbus = virtbus;
- HvCallXm_getTceTableParms(ISERIES_HV_ADDR(parms));
+ HvCallXm_getTceTableParms(iseries_hv_addr(parms));
if (parms->itc_size == 0)
panic("PCI_DMA: parms->size is zero, parms is 0x%p", parms);
/* itc_size is in pages worth of table, it_size is in # of entries */
- tbl->it_size = (parms->itc_size * PAGE_SIZE) / sizeof(union tce_entry);
+ tbl->it_size = ((parms->itc_size * TCE_PAGE_SIZE) /
+ sizeof(union tce_entry)) >> TCE_PAGE_FACTOR;
tbl->it_busno = parms->itc_busno;
- tbl->it_offset = parms->itc_offset;
+ tbl->it_offset = parms->itc_offset >> TCE_PAGE_FACTOR;
tbl->it_index = parms->itc_index;
tbl->it_blocksize = 1;
- tbl->it_type = TCE_PCI;
+ tbl->it_type = virtbus ? TCE_VB : TCE_PCI;
kfree(parms);
}
-void iommu_devnode_init_iSeries(struct iSeries_Device_Node *dn)
+#ifdef CONFIG_PCI
+/*
+ * This function compares the known tables to find an iommu_table
+ * that has already been built for hardware TCEs.
+ */
+static struct iommu_table *iommu_table_find(struct iommu_table * tbl)
+{
+ struct pci_dn *pdn;
+
+ list_for_each_entry(pdn, &iSeries_Global_Device_List, Device_List) {
+ struct iommu_table *it = pdn->iommu_table;
+ if ((it != NULL) &&
+ (it->it_type == TCE_PCI) &&
+ (it->it_offset == tbl->it_offset) &&
+ (it->it_index == tbl->it_index) &&
+ (it->it_size == tbl->it_size))
+ return it;
+ }
+ return NULL;
+}
+
+
+void iommu_devnode_init_iSeries(struct device_node *dn)
{
struct iommu_table *tbl;
+ struct pci_dn *pdn = PCI_DN(dn);
tbl = kmalloc(sizeof(struct iommu_table), GFP_KERNEL);
- iommu_table_getparms(dn, tbl);
+ iommu_table_getparms_iSeries(pdn->busno, pdn->LogicalSlot, 0, tbl);
/* Look for existing tce table */
- dn->iommu_table = iommu_table_find(tbl);
- if (dn->iommu_table == NULL)
- dn->iommu_table = iommu_init_table(tbl);
+ pdn->iommu_table = iommu_table_find(tbl);
+ if (pdn->iommu_table == NULL)
+ pdn->iommu_table = iommu_init_table(tbl);
else
kfree(tbl);
}
diff --git a/include/asm-ppc64/iSeries/ItIplParmsReal.h b/arch/powerpc/platforms/iseries/ipl_parms.h
index ae3417dc599e..77c135ddbf1b 100644
--- a/include/asm-ppc64/iSeries/ItIplParmsReal.h
+++ b/arch/powerpc/platforms/iseries/ipl_parms.h
@@ -1,5 +1,4 @@
/*
- * ItIplParmsReal.h
* Copyright (C) 2001 Mike Corrigan IBM Corporation
*
* This program is free software; you can redistribute it and/or modify
@@ -16,8 +15,8 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#ifndef _ITIPLPARMSREAL_H
-#define _ITIPLPARMSREAL_H
+#ifndef _ISERIES_IPL_PARMS_H
+#define _ISERIES_IPL_PARMS_H
/*
* This struct maps the IPL Parameters DMA'd from the SP.
@@ -68,4 +67,4 @@ struct ItIplParmsReal {
extern struct ItIplParmsReal xItIplParmsReal;
-#endif /* _ITIPLPARMSREAL_H */
+#endif /* _ISERIES_IPL_PARMS_H */
diff --git a/arch/ppc64/kernel/iSeries_irq.c b/arch/powerpc/platforms/iseries/irq.c
index 77376c1bd611..01090e9ce0cf 100644
--- a/arch/ppc64/kernel/iSeries_irq.c
+++ b/arch/powerpc/platforms/iseries/irq.c
@@ -35,12 +35,12 @@
#include <linux/irq.h>
#include <linux/spinlock.h>
-#include <asm/ppcdebug.h>
-#include <asm/iSeries/HvTypes.h>
-#include <asm/iSeries/HvLpEvent.h>
-#include <asm/iSeries/HvCallPci.h>
-#include <asm/iSeries/HvCallXm.h>
-#include <asm/iSeries/iSeries_irq.h>
+#include <asm/iseries/hv_types.h>
+#include <asm/iseries/hv_lp_event.h>
+#include <asm/iseries/hv_call_xm.h>
+
+#include "irq.h"
+#include "call_pci.h"
/* This maps virtual irq numbers to real irqs */
unsigned int virt_irq_to_real_map[NR_IRQS];
@@ -103,6 +103,9 @@ static void intReceived(struct XmPciLpEvent *eventParm,
struct pt_regs *regsParm)
{
int irq;
+#ifdef CONFIG_IRQSTACKS
+ struct thread_info *curtp, *irqtp;
+#endif
++Pci_Interrupt_Count;
@@ -110,7 +113,20 @@ static void intReceived(struct XmPciLpEvent *eventParm,
case XmPciLpEvent_SlotInterrupt:
irq = eventParm->hvLpEvent.xCorrelationToken;
/* Dispatch the interrupt handlers for this irq */
- ppc_irq_dispatch_handler(regsParm, irq);
+#ifdef CONFIG_IRQSTACKS
+ /* Switch to the irq stack to handle this */
+ curtp = current_thread_info();
+ irqtp = hardirq_ctx[smp_processor_id()];
+ if (curtp != irqtp) {
+ irqtp->task = curtp->task;
+ irqtp->flags = 0;
+ call___do_IRQ(irq, regsParm, irqtp);
+ irqtp->task = NULL;
+ if (irqtp->flags)
+ set_bits(irqtp->flags, &curtp->flags);
+ } else
+#endif
+ __do_IRQ(irq, regsParm);
HvCallPci_eoi(eventParm->eventData.slotInterrupt.busNumber,
eventParm->eventData.slotInterrupt.subBusNumber,
eventParm->eventData.slotInterrupt.deviceId);
@@ -226,8 +242,6 @@ static void iSeries_enable_IRQ(unsigned int irq)
/* Unmask secondary INTA */
mask = 0x80000000;
HvCallPci_unmaskInterrupts(bus, subBus, deviceId, mask);
- PPCDBG(PPCDBG_BUSWALK, "iSeries_enable_IRQ 0x%02X.%02X.%02X 0x%04X\n",
- bus, subBus, deviceId, irq);
}
/* This is called by iSeries_activate_IRQs */
@@ -309,15 +323,11 @@ static void iSeries_disable_IRQ(unsigned int irq)
/* Mask secondary INTA */
mask = 0x80000000;
HvCallPci_maskInterrupts(bus, subBus, deviceId, mask);
- PPCDBG(PPCDBG_BUSWALK, "iSeries_disable_IRQ 0x%02X.%02X.%02X 0x%04X\n",
- bus, subBus, deviceId, irq);
}
/*
- * Need to define this so ppc_irq_dispatch_handler will NOT call
- * enable_IRQ at the end of interrupt handling. However, this does
- * nothing because there is not enough information provided to do
- * the EOI HvCall. This is done by XmPciLpEvent.c
+ * This does nothing because there is not enough information
+ * provided to do the EOI HvCall. This is done by XmPciLpEvent.c
*/
static void iSeries_end_IRQ(unsigned int irq)
{
@@ -351,3 +361,15 @@ int __init iSeries_allocate_IRQ(HvBusNumber busNumber,
irq_desc[virtirq].handler = &iSeries_IRQ_handler;
return virtirq;
}
+
+int virt_irq_create_mapping(unsigned int real_irq)
+{
+ BUG(); /* Don't call this on iSeries, yet */
+
+ return 0;
+}
+
+void virt_irq_init(void)
+{
+ return;
+}
diff --git a/include/asm-ppc64/iSeries/iSeries_irq.h b/arch/powerpc/platforms/iseries/irq.h
index 6c9767ac1302..5f643f16ecc0 100644
--- a/include/asm-ppc64/iSeries/iSeries_irq.h
+++ b/arch/powerpc/platforms/iseries/irq.h
@@ -1,8 +1,8 @@
-#ifndef __ISERIES_IRQ_H__
-#define __ISERIES_IRQ_H__
+#ifndef _ISERIES_IRQ_H
+#define _ISERIES_IRQ_H
extern void iSeries_init_IRQ(void);
extern int iSeries_allocate_IRQ(HvBusNumber, HvSubBusNumber, HvAgentId);
extern void iSeries_activate_IRQs(void);
-#endif /* __ISERIES_IRQ_H__ */
+#endif /* _ISERIES_IRQ_H */
diff --git a/arch/powerpc/platforms/iseries/ksyms.c b/arch/powerpc/platforms/iseries/ksyms.c
new file mode 100644
index 000000000000..a2200842f4e5
--- /dev/null
+++ b/arch/powerpc/platforms/iseries/ksyms.c
@@ -0,0 +1,27 @@
+/*
+ * (C) 2001-2005 PPC 64 Team, IBM Corp
+ *
+ * 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/module.h>
+
+#include <asm/hw_irq.h>
+#include <asm/iseries/hv_call_sc.h>
+
+EXPORT_SYMBOL(HvCall0);
+EXPORT_SYMBOL(HvCall1);
+EXPORT_SYMBOL(HvCall2);
+EXPORT_SYMBOL(HvCall3);
+EXPORT_SYMBOL(HvCall4);
+EXPORT_SYMBOL(HvCall5);
+EXPORT_SYMBOL(HvCall6);
+EXPORT_SYMBOL(HvCall7);
+
+#ifdef CONFIG_SMP
+EXPORT_SYMBOL(local_get_flags);
+EXPORT_SYMBOL(local_irq_disable);
+EXPORT_SYMBOL(local_irq_restore);
+#endif
diff --git a/arch/ppc64/kernel/LparData.c b/arch/powerpc/platforms/iseries/lpardata.c
index 0a9c23ca2f0c..bb8c91537f35 100644
--- a/arch/ppc64/kernel/LparData.c
+++ b/arch/powerpc/platforms/iseries/lpardata.c
@@ -1,4 +1,4 @@
-/*
+/*
* Copyright 2001 Mike Corrigan, IBM Corp
*
* This program is free software; you can redistribute it and/or
@@ -13,24 +13,24 @@
#include <linux/bitops.h>
#include <asm/processor.h>
#include <asm/ptrace.h>
-#include <asm/naca.h>
#include <asm/abs_addr.h>
-#include <asm/iSeries/ItLpNaca.h>
+#include <asm/iseries/it_lp_naca.h>
#include <asm/lppaca.h>
-#include <asm/iSeries/ItLpRegSave.h>
+#include <asm/iseries/it_lp_reg_save.h>
#include <asm/paca.h>
-#include <asm/iSeries/HvReleaseData.h>
-#include <asm/iSeries/LparMap.h>
-#include <asm/iSeries/ItVpdAreas.h>
-#include <asm/iSeries/ItIplParmsReal.h>
-#include <asm/iSeries/ItExtVpdPanel.h>
-#include <asm/iSeries/ItLpQueue.h>
-#include <asm/iSeries/IoHriProcessorVpd.h>
-#include <asm/iSeries/ItSpCommArea.h>
+#include <asm/iseries/lpar_map.h>
+#include <asm/iseries/it_exp_vpd_panel.h>
+#include <asm/iseries/it_lp_queue.h>
+#include "naca.h"
+#include "vpd_areas.h"
+#include "spcomm_area.h"
+#include "ipl_parms.h"
+#include "processor_vpd.h"
+#include "release_data.h"
-/* The HvReleaseData is the root of the information shared between
- * the hypervisor and Linux.
+/* The HvReleaseData is the root of the information shared between
+ * the hypervisor and Linux.
*/
struct HvReleaseData hvReleaseData = {
.xDesc = 0xc8a5d9c4, /* "HvRD" ebcdic */
@@ -79,7 +79,7 @@ extern void trap_0e_iSeries(void);
extern void performance_monitor_iSeries(void);
extern void data_access_slb_iSeries(void);
extern void instruction_access_slb_iSeries(void);
-
+
struct ItLpNaca itLpNaca = {
.xDesc = 0xd397d581, /* "LpNa" ebcdic */
.xSize = 0x0400, /* size of ItLpNaca */
@@ -106,7 +106,7 @@ struct ItLpNaca itLpNaca = {
.xLoadAreaChunks = 0, /* chunks for load area */
.xPaseSysCallCRMask = 0, /* PASE mask */
.xSlicSegmentTablePtr = 0, /* seg table */
- .xOldLpQueue = { 0 }, /* Old LP Queue */
+ .xOldLpQueue = { 0 }, /* Old LP Queue */
.xInterruptHdlr = {
(u64)system_reset_iSeries, /* 0x100 System Reset */
(u64)machine_check_iSeries, /* 0x200 Machine Check */
@@ -134,7 +134,7 @@ struct ItLpNaca itLpNaca = {
EXPORT_SYMBOL(itLpNaca);
/* May be filled in by the hypervisor so cannot end up in the BSS */
-struct ItIplParmsReal xItIplParmsReal __attribute__((__section__(".data")));
+struct ItIplParmsReal xItIplParmsReal __attribute__((__section__(".data")));
/* May be filled in by the hypervisor so cannot end up in the BSS */
struct ItExtVpdPanel xItExtVpdPanel __attribute__((__section__(".data")));
@@ -151,7 +151,7 @@ struct IoHriProcessorVpd xIoHriProcessorVpd[maxPhysicalProcessors] = {
.xPVR = 0x3600
}
};
-
+
/* Space for Main Store Vpd 27,200 bytes */
/* May be filled in by the hypervisor so cannot end up in the BSS */
u64 xMsVpd[3400] __attribute__((__section__(".data")));
@@ -197,7 +197,7 @@ struct ItVpdAreas itVpdAreas = {
26992, /* 7 length of MS VPD */
0, /* 8 */
sizeof(struct ItLpNaca),/* 9 length of LP Naca */
- 0, /* 10 */
+ 0, /* 10 */
256, /* 11 length of Recovery Log Buf */
sizeof(struct SpCommArea), /* 12 length of SP Comm Area */
0,0,0, /* 13 - 15 */
@@ -207,7 +207,7 @@ struct ItVpdAreas itVpdAreas = {
0,0 /* 24 - 25 */
},
.xSlicVpdAdrs = { /* VPD addresses */
- 0,0,0, /* 0 - 2 */
+ 0,0,0, /* 0 - 2 */
&xItExtVpdPanel, /* 3 Extended VPD */
&paca[0], /* 4 first Paca */
0, /* 5 */
diff --git a/arch/ppc64/kernel/ItLpQueue.c b/arch/powerpc/platforms/iseries/lpevents.c
index 4231861288a3..e9fb98bf895f 100644
--- a/arch/ppc64/kernel/ItLpQueue.c
+++ b/arch/powerpc/platforms/iseries/lpevents.c
@@ -1,5 +1,4 @@
/*
- * ItLpQueue.c
* Copyright (C) 2001 Mike Corrigan IBM Corporation
*
* This program is free software; you can redistribute it and/or modify
@@ -14,11 +13,14 @@
#include <linux/bootmem.h>
#include <linux/seq_file.h>
#include <linux/proc_fs.h>
+#include <linux/module.h>
+
#include <asm/system.h>
#include <asm/paca.h>
-#include <asm/iSeries/ItLpQueue.h>
-#include <asm/iSeries/HvLpEvent.h>
-#include <asm/iSeries/HvCallEvent.h>
+#include <asm/iseries/it_lp_queue.h>
+#include <asm/iseries/hv_lp_event.h>
+#include <asm/iseries/hv_call_event.h>
+#include <asm/iseries/it_lp_naca.h>
/*
* The LpQueue is used to pass event data from the hypervisor to
@@ -43,7 +45,8 @@ static char *event_types[HvLpEvent_Type_NumTypes] = {
};
/* Array of LpEvent handler functions */
-extern LpEventHandler lpEventHandler[HvLpEvent_Type_NumTypes];
+static LpEventHandler lpEventHandler[HvLpEvent_Type_NumTypes];
+static unsigned lpEventHandlerPaths[HvLpEvent_Type_NumTypes];
static struct HvLpEvent * get_next_hvlpevent(void)
{
@@ -181,11 +184,7 @@ void setup_hvlpevent_queue(void)
{
void *eventStack;
- /*
- * Allocate a page for the Event Stack. The Hypervisor needs the
- * absolute real address, so we subtract out the KERNELBASE and add
- * in the absolute real address of the kernel load area.
- */
+ /* Allocate a page for the Event Stack. */
eventStack = alloc_bootmem_pages(LpEventStackSize);
memset(eventStack, 0, LpEventStackSize);
@@ -199,6 +198,70 @@ void setup_hvlpevent_queue(void)
hvlpevent_queue.xIndex = 0;
}
+/* Register a handler for an LpEvent type */
+int HvLpEvent_registerHandler(HvLpEvent_Type eventType, LpEventHandler handler)
+{
+ if (eventType < HvLpEvent_Type_NumTypes) {
+ lpEventHandler[eventType] = handler;
+ return 0;
+ }
+ return 1;
+}
+EXPORT_SYMBOL(HvLpEvent_registerHandler);
+
+int HvLpEvent_unregisterHandler(HvLpEvent_Type eventType)
+{
+ might_sleep();
+
+ if (eventType < HvLpEvent_Type_NumTypes) {
+ if (!lpEventHandlerPaths[eventType]) {
+ lpEventHandler[eventType] = NULL;
+ /*
+ * We now sleep until all other CPUs have scheduled.
+ * This ensures that the deletion is seen by all
+ * other CPUs, and that the deleted handler isn't
+ * still running on another CPU when we return.
+ */
+ synchronize_rcu();
+ return 0;
+ }
+ }
+ return 1;
+}
+EXPORT_SYMBOL(HvLpEvent_unregisterHandler);
+
+/*
+ * lpIndex is the partition index of the target partition.
+ * needed only for VirtualIo, VirtualLan and SessionMgr. Zero
+ * indicates to use our partition index - for the other types.
+ */
+int HvLpEvent_openPath(HvLpEvent_Type eventType, HvLpIndex lpIndex)
+{
+ if ((eventType < HvLpEvent_Type_NumTypes) &&
+ lpEventHandler[eventType]) {
+ if (lpIndex == 0)
+ lpIndex = itLpNaca.xLpIndex;
+ HvCallEvent_openLpEventPath(lpIndex, eventType);
+ ++lpEventHandlerPaths[eventType];
+ return 0;
+ }
+ return 1;
+}
+
+int HvLpEvent_closePath(HvLpEvent_Type eventType, HvLpIndex lpIndex)
+{
+ if ((eventType < HvLpEvent_Type_NumTypes) &&
+ lpEventHandler[eventType] &&
+ lpEventHandlerPaths[eventType]) {
+ if (lpIndex == 0)
+ lpIndex = itLpNaca.xLpIndex;
+ HvCallEvent_closeLpEventPath(lpIndex, eventType);
+ --lpEventHandlerPaths[eventType];
+ return 0;
+ }
+ return 1;
+}
+
static int proc_lpevents_show(struct seq_file *m, void *v)
{
int cpu, i;
diff --git a/include/asm-ppc64/iSeries/IoHriMainStore.h b/arch/powerpc/platforms/iseries/main_store.h
index 45ed3ea67d06..74f6889f834f 100644
--- a/include/asm-ppc64/iSeries/IoHriMainStore.h
+++ b/arch/powerpc/platforms/iseries/main_store.h
@@ -1,5 +1,4 @@
/*
- * IoHriMainStore.h
* Copyright (C) 2001 Mike Corrigan IBM Corporation
*
* This program is free software; you can redistribute it and/or modify
@@ -17,8 +16,8 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#ifndef _IOHRIMAINSTORE_H
-#define _IOHRIMAINSTORE_H
+#ifndef _ISERIES_MAIN_STORE_H
+#define _ISERIES_MAIN_STORE_H
/* Main Store Vpd for Condor,iStar,sStar */
struct IoHriMainStoreSegment4 {
@@ -163,4 +162,4 @@ struct IoHriMainStoreSegment5 {
extern u64 xMsVpd[];
-#endif /* _IOHRIMAINSTORE_H */
+#endif /* _ISERIES_MAIN_STORE_H */
diff --git a/arch/ppc64/kernel/mf.c b/arch/powerpc/platforms/iseries/mf.c
index ef4a338ebd01..49e7e4b85847 100644
--- a/arch/ppc64/kernel/mf.c
+++ b/arch/powerpc/platforms/iseries/mf.c
@@ -1,29 +1,28 @@
/*
- * mf.c
- * Copyright (C) 2001 Troy D. Armstrong IBM Corporation
- * Copyright (C) 2004-2005 Stephen Rothwell IBM Corporation
- *
- * This modules exists as an interface between a Linux secondary partition
- * running on an iSeries and the primary partition's Virtual Service
- * Processor (VSP) object. The VSP has final authority over powering on/off
- * all partitions in the iSeries. It also provides miscellaneous low-level
- * machine facility type operations.
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
+ * Copyright (C) 2001 Troy D. Armstrong IBM Corporation
+ * Copyright (C) 2004-2005 Stephen Rothwell IBM Corporation
+ *
+ * This modules exists as an interface between a Linux secondary partition
+ * running on an iSeries and the primary partition's Virtual Service
+ * Processor (VSP) object. The VSP has final authority over powering on/off
+ * all partitions in the iSeries. It also provides miscellaneous low-level
+ * machine facility type operations.
+ *
+ *
+ * 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/types.h>
#include <linux/errno.h>
@@ -33,14 +32,20 @@
#include <linux/delay.h>
#include <linux/dma-mapping.h>
#include <linux/bcd.h>
+#include <linux/rtc.h>
#include <asm/time.h>
#include <asm/uaccess.h>
#include <asm/paca.h>
-#include <asm/iSeries/vio.h>
-#include <asm/iSeries/mf.h>
-#include <asm/iSeries/HvLpConfig.h>
-#include <asm/iSeries/ItLpQueue.h>
+#include <asm/abs_addr.h>
+#include <asm/iseries/vio.h>
+#include <asm/iseries/mf.h>
+#include <asm/iseries/hv_lp_config.h>
+#include <asm/iseries/it_lp_queue.h>
+
+#include "setup.h"
+
+extern int piranha_simulator;
/*
* This is the structure layout for the Machine Facilites LPAR event
@@ -1061,10 +1066,10 @@ static void mf_getSrcHistory(char *buffer, int size)
ev->event.data.vsp_cmd.lp_index = HvLpConfig_getLpIndex();
ev->event.data.vsp_cmd.result_code = 0xFF;
ev->event.data.vsp_cmd.reserved = 0;
- ev->event.data.vsp_cmd.sub_data.page[0] = ISERIES_HV_ADDR(pages[0]);
- ev->event.data.vsp_cmd.sub_data.page[1] = ISERIES_HV_ADDR(pages[1]);
- ev->event.data.vsp_cmd.sub_data.page[2] = ISERIES_HV_ADDR(pages[2]);
- ev->event.data.vsp_cmd.sub_data.page[3] = ISERIES_HV_ADDR(pages[3]);
+ ev->event.data.vsp_cmd.sub_data.page[0] = iseries_hv_addr(pages[0]);
+ ev->event.data.vsp_cmd.sub_data.page[1] = iseries_hv_addr(pages[1]);
+ ev->event.data.vsp_cmd.sub_data.page[2] = iseries_hv_addr(pages[2]);
+ ev->event.data.vsp_cmd.sub_data.page[3] = iseries_hv_addr(pages[3]);
mb();
if (signal_event(ev) != 0)
return;
@@ -1279,3 +1284,38 @@ static int __init mf_proc_init(void)
__initcall(mf_proc_init);
#endif /* CONFIG_PROC_FS */
+
+/*
+ * Get the RTC from the virtual service processor
+ * This requires flowing LpEvents to the primary partition
+ */
+void iSeries_get_rtc_time(struct rtc_time *rtc_tm)
+{
+ if (piranha_simulator)
+ return;
+
+ mf_get_rtc(rtc_tm);
+ rtc_tm->tm_mon--;
+}
+
+/*
+ * Set the RTC in the virtual service processor
+ * This requires flowing LpEvents to the primary partition
+ */
+int iSeries_set_rtc_time(struct rtc_time *tm)
+{
+ mf_set_rtc(tm);
+ return 0;
+}
+
+unsigned long iSeries_get_boot_time(void)
+{
+ struct rtc_time tm;
+
+ if (piranha_simulator)
+ return 0;
+
+ mf_get_boot_rtc(&tm);
+ return mktime(tm.tm_year + 1900, tm.tm_mon, tm.tm_mday,
+ tm.tm_hour, tm.tm_min, tm.tm_sec);
+}
diff --git a/arch/powerpc/platforms/iseries/misc.S b/arch/powerpc/platforms/iseries/misc.S
new file mode 100644
index 000000000000..dfe7aa1ba098
--- /dev/null
+++ b/arch/powerpc/platforms/iseries/misc.S
@@ -0,0 +1,56 @@
+/*
+ * This file contains miscellaneous low-level functions.
+ * Copyright (C) 1995-2005 IBM Corp
+ *
+ * Largely rewritten by Cort Dougan (cort@cs.nmt.edu)
+ * and Paul Mackerras.
+ * Adapted for iSeries by Mike Corrigan (mikejc@us.ibm.com)
+ * PPC64 updates by Dave Engebretsen (engebret@us.ibm.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <asm/processor.h>
+#include <asm/asm-offsets.h>
+#include <asm/ppc_asm.h>
+
+ .text
+
+/* unsigned long local_save_flags(void) */
+_GLOBAL(local_get_flags)
+ lbz r3,PACAPROCENABLED(r13)
+ blr
+
+/* unsigned long local_irq_disable(void) */
+_GLOBAL(local_irq_disable)
+ lbz r3,PACAPROCENABLED(r13)
+ li r4,0
+ stb r4,PACAPROCENABLED(r13)
+ blr /* Done */
+
+/* void local_irq_restore(unsigned long flags) */
+_GLOBAL(local_irq_restore)
+ lbz r5,PACAPROCENABLED(r13)
+ /* Check if things are setup the way we want _already_. */
+ cmpw 0,r3,r5
+ beqlr
+ /* are we enabling interrupts? */
+ cmpdi 0,r3,0
+ stb r3,PACAPROCENABLED(r13)
+ beqlr
+ /* Check pending interrupts */
+ /* A decrementer, IPI or PMC interrupt may have occurred
+ * while we were in the hypervisor (which enables) */
+ ld r4,PACALPPACA+LPPACAANYINT(r13)
+ cmpdi r4,0
+ beqlr
+
+ /*
+ * Handle pending interrupts in interrupt context
+ */
+ li r0,0x5555
+ sc
+ blr
diff --git a/include/asm-ppc64/naca.h b/arch/powerpc/platforms/iseries/naca.h
index d2afe6447597..ab2372eb8d2e 100644
--- a/include/asm-ppc64/naca.h
+++ b/arch/powerpc/platforms/iseries/naca.h
@@ -1,7 +1,7 @@
-#ifndef _NACA_H
-#define _NACA_H
+#ifndef _PLATFORMS_ISERIES_NACA_H
+#define _PLATFORMS_ISERIES_NACA_H
-/*
+/*
* c 2001 PPC 64 Team, IBM Corp
*
* This program is free software; you can redistribute it and/or
@@ -21,4 +21,4 @@ struct naca_struct {
extern struct naca_struct naca;
-#endif /* _NACA_H */
+#endif /* _PLATFORMS_ISERIES_NACA_H */
diff --git a/arch/ppc64/kernel/iSeries_pci.c b/arch/powerpc/platforms/iseries/pci.c
index fbc273c32bcc..4b75131773a6 100644
--- a/arch/ppc64/kernel/iSeries_pci.c
+++ b/arch/powerpc/platforms/iseries/pci.c
@@ -1,28 +1,26 @@
/*
- * iSeries_pci.c
- *
* Copyright (C) 2001 Allan Trautman, IBM Corporation
*
* iSeries specific routines for PCI.
- *
+ *
* Based on code from pci.c and iSeries_pci.c 32bit
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
- *
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <linux/kernel.h>
-#include <linux/list.h>
+#include <linux/list.h>
#include <linux/string.h>
#include <linux/init.h>
#include <linux/module.h>
@@ -34,23 +32,24 @@
#include <asm/prom.h>
#include <asm/machdep.h>
#include <asm/pci-bridge.h>
-#include <asm/ppcdebug.h>
#include <asm/iommu.h>
+#include <asm/abs_addr.h>
-#include <asm/iSeries/HvCallPci.h>
-#include <asm/iSeries/HvCallXm.h>
-#include <asm/iSeries/iSeries_irq.h>
-#include <asm/iSeries/iSeries_pci.h>
-#include <asm/iSeries/mf.h>
+#include <asm/iseries/hv_call_xm.h>
+#include <asm/iseries/mf.h>
+#include <asm/ppc-pci.h>
+
+#include "irq.h"
#include "pci.h"
+#include "call_pci.h"
extern unsigned long io_page_mask;
/*
- * Forward declares of prototypes.
+ * Forward declares of prototypes.
*/
-static struct iSeries_Device_Node *find_Device_Node(int bus, int devfn);
+static struct device_node *find_Device_Node(int bus, int devfn);
static void scan_PHB_slots(struct pci_controller *Phb);
static void scan_EADS_bridge(HvBusNumber Bus, HvSubBusNumber SubBus, int IdSel);
static int scan_bridge_slot(HvBusNumber Bus, struct HvCallPci_BridgeInfo *Info);
@@ -68,7 +67,7 @@ static long Pci_Cfg_Write_Count;
#endif
static long Pci_Error_Count;
-static int Pci_Retry_Max = 3; /* Only retry 3 times */
+static int Pci_Retry_Max = 3; /* Only retry 3 times */
static int Pci_Error_Flag = 1; /* Set Retry Error on. */
static struct pci_ops iSeries_pci_ops;
@@ -87,7 +86,7 @@ static long current_iomm_table_entry;
/*
* Lookup Tables.
*/
-static struct iSeries_Device_Node **iomm_table;
+static struct device_node **iomm_table;
static u8 *iobar_table;
/*
@@ -179,7 +178,7 @@ static void allocate_device_bars(struct pci_dev *dev)
for (bar_num = 0; bar_num <= PCI_ROM_RESOURCE; ++bar_num) {
bar_res = &dev->resource[bar_num];
iomm_table_allocate_entry(dev, bar_num);
- }
+ }
}
/*
@@ -201,29 +200,27 @@ static void pci_Log_Error(char *Error_Text, int Bus, int SubBus,
/*
* build_device_node(u16 Bus, int SubBus, u8 DevFn)
*/
-static struct iSeries_Device_Node *build_device_node(HvBusNumber Bus,
+static struct device_node *build_device_node(HvBusNumber Bus,
HvSubBusNumber SubBus, int AgentId, int Function)
{
- struct iSeries_Device_Node *node;
-
- PPCDBG(PPCDBG_BUSWALK,
- "-build_device_node 0x%02X.%02X.%02X Function: %02X\n",
- Bus, SubBus, AgentId, Function);
+ struct device_node *node;
+ struct pci_dn *pdn;
- node = kmalloc(sizeof(struct iSeries_Device_Node), GFP_KERNEL);
+ node = kmalloc(sizeof(struct device_node), GFP_KERNEL);
if (node == NULL)
return NULL;
-
- memset(node, 0, sizeof(struct iSeries_Device_Node));
- list_add_tail(&node->Device_List, &iSeries_Global_Device_List);
-#if 0
- node->DsaAddr = ((u64)Bus << 48) + ((u64)SubBus << 40) + ((u64)0x10 << 32);
-#endif
- node->DsaAddr.DsaAddr = 0;
- node->DsaAddr.Dsa.busNumber = Bus;
- node->DsaAddr.Dsa.subBusNumber = SubBus;
- node->DsaAddr.Dsa.deviceId = 0x10;
- node->DevFn = PCI_DEVFN(ISERIES_ENCODE_DEVICE(AgentId), Function);
+ memset(node, 0, sizeof(struct device_node));
+ pdn = kzalloc(sizeof(*pdn), GFP_KERNEL);
+ if (pdn == NULL) {
+ kfree(node);
+ return NULL;
+ }
+ node->data = pdn;
+ pdn->node = node;
+ list_add_tail(&pdn->Device_List, &iSeries_Global_Device_List);
+ pdn->busno = Bus;
+ pdn->bussubno = SubBus;
+ pdn->devfn = PCI_DEVFN(ISERIES_ENCODE_DEVICE(AgentId), Function);
return node;
}
@@ -241,8 +238,6 @@ unsigned long __init find_and_init_phbs(void)
struct pci_controller *phb;
HvBusNumber bus;
- PPCDBG(PPCDBG_BUSWALK, "find_and_init_phbs Entry\n");
-
/* Check all possible buses. */
for (bus = 0; bus < 256; bus++) {
int ret = HvCallXm_testBus(bus);
@@ -259,9 +254,6 @@ unsigned long __init find_and_init_phbs(void)
phb->last_busno = bus;
phb->ops = &iSeries_pci_ops;
- PPCDBG(PPCDBG_BUSWALK, "PCI:Create iSeries pci_controller(%p), Bus: %04X\n",
- phb, bus);
-
/* Find and connect the devices. */
scan_PHB_slots(phb);
}
@@ -278,28 +270,24 @@ unsigned long __init find_and_init_phbs(void)
/*
* iSeries_pcibios_init
- *
+ *
* Chance to initialize and structures or variable before PCI Bus walk.
*/
void iSeries_pcibios_init(void)
{
- PPCDBG(PPCDBG_BUSWALK, "iSeries_pcibios_init Entry.\n");
iomm_table_initialize();
find_and_init_phbs();
io_page_mask = -1;
- PPCDBG(PPCDBG_BUSWALK, "iSeries_pcibios_init Exit.\n");
}
/*
- * iSeries_pci_final_fixup(void)
+ * iSeries_pci_final_fixup(void)
*/
void __init iSeries_pci_final_fixup(void)
{
struct pci_dev *pdev = NULL;
- struct iSeries_Device_Node *node;
- int DeviceCount = 0;
-
- PPCDBG(PPCDBG_BUSWALK, "iSeries_pcibios_fixup Entry.\n");
+ struct device_node *node;
+ int DeviceCount = 0;
/* Fix up at the device node and pci_dev relationship */
mf_display_src(0xC9000100);
@@ -313,17 +301,14 @@ void __init iSeries_pci_final_fixup(void)
if (node != NULL) {
++DeviceCount;
pdev->sysdata = (void *)node;
- node->PciDev = pdev;
- PPCDBG(PPCDBG_BUSWALK,
- "pdev 0x%p <==> DevNode 0x%p\n",
- pdev, node);
+ PCI_DN(node)->pcidev = pdev;
allocate_device_bars(pdev);
iSeries_Device_Information(pdev, DeviceCount);
iommu_devnode_init_iSeries(node);
} else
printk("PCI: Device Tree not found for 0x%016lX\n",
(unsigned long)pdev);
- pdev->irq = node->Irq;
+ pdev->irq = PCI_DN(node)->Irq;
}
iSeries_activate_IRQs();
mf_display_src(0xC9000200);
@@ -331,25 +316,22 @@ void __init iSeries_pci_final_fixup(void)
void pcibios_fixup_bus(struct pci_bus *PciBus)
{
- PPCDBG(PPCDBG_BUSWALK, "iSeries_pcibios_fixup_bus(0x%04X) Entry.\n",
- PciBus->number);
}
void pcibios_fixup_resources(struct pci_dev *pdev)
{
- PPCDBG(PPCDBG_BUSWALK, "fixup_resources pdev %p\n", pdev);
-}
+}
/*
- * Loop through each node function to find usable EADs bridges.
+ * Loop through each node function to find usable EADs bridges.
*/
static void scan_PHB_slots(struct pci_controller *Phb)
{
struct HvCallPci_DeviceInfo *DevInfo;
- HvBusNumber bus = Phb->local_number; /* System Bus */
+ HvBusNumber bus = Phb->local_number; /* System Bus */
const HvSubBusNumber SubBus = 0; /* EADs is always 0. */
int HvRc = 0;
- int IdSel;
+ int IdSel;
const int MaxAgents = 8;
DevInfo = (struct HvCallPci_DeviceInfo*)
@@ -358,11 +340,11 @@ static void scan_PHB_slots(struct pci_controller *Phb)
return;
/*
- * Probe for EADs Bridges
+ * Probe for EADs Bridges
*/
for (IdSel = 1; IdSel < MaxAgents; ++IdSel) {
- HvRc = HvCallPci_getDeviceInfo(bus, SubBus, IdSel,
- ISERIES_HV_ADDR(DevInfo),
+ HvRc = HvCallPci_getDeviceInfo(bus, SubBus, IdSel,
+ iseries_hv_addr(DevInfo),
sizeof(struct HvCallPci_DeviceInfo));
if (HvRc == 0) {
if (DevInfo->deviceType == HvCallPci_NodeDevice)
@@ -393,33 +375,22 @@ static void scan_EADS_bridge(HvBusNumber bus, HvSubBusNumber SubBus,
/* Note: hvSubBus and irq is always be 0 at this level! */
for (Function = 0; Function < 8; ++Function) {
- AgentId = ISERIES_PCI_AGENTID(IdSel, Function);
+ AgentId = ISERIES_PCI_AGENTID(IdSel, Function);
HvRc = HvCallXm_connectBusUnit(bus, SubBus, AgentId, 0);
- if (HvRc == 0) {
+ if (HvRc == 0) {
printk("found device at bus %d idsel %d func %d (AgentId %x)\n",
bus, IdSel, Function, AgentId);
- /* Connect EADs: 0x18.00.12 = 0x00 */
- PPCDBG(PPCDBG_BUSWALK,
- "PCI:Connect EADs: 0x%02X.%02X.%02X\n",
- bus, SubBus, AgentId);
- HvRc = HvCallPci_getBusUnitInfo(bus, SubBus, AgentId,
- ISERIES_HV_ADDR(BridgeInfo),
+ /* Connect EADs: 0x18.00.12 = 0x00 */
+ HvRc = HvCallPci_getBusUnitInfo(bus, SubBus, AgentId,
+ iseries_hv_addr(BridgeInfo),
sizeof(struct HvCallPci_BridgeInfo));
- if (HvRc == 0) {
+ if (HvRc == 0) {
printk("bridge info: type %x subbus %x maxAgents %x maxsubbus %x logslot %x\n",
BridgeInfo->busUnitInfo.deviceType,
BridgeInfo->subBusNumber,
BridgeInfo->maxAgents,
BridgeInfo->maxSubBusNumber,
BridgeInfo->logicalSlotNumber);
- PPCDBG(PPCDBG_BUSWALK,
- "PCI: BridgeInfo, Type:0x%02X, SubBus:0x%02X, MaxAgents:0x%02X, MaxSubBus: 0x%02X, LSlot: 0x%02X\n",
- BridgeInfo->busUnitInfo.deviceType,
- BridgeInfo->subBusNumber,
- BridgeInfo->maxAgents,
- BridgeInfo->maxSubBusNumber,
- BridgeInfo->logicalSlotNumber);
-
if (BridgeInfo->busUnitInfo.deviceType ==
HvCallPci_BridgeDevice) {
/* Scan_Bridge_Slot...: 0x18.00.12 */
@@ -428,7 +399,7 @@ static void scan_EADS_bridge(HvBusNumber bus, HvSubBusNumber SubBus,
printk("PCI: Invalid Bridge Configuration(0x%02X)",
BridgeInfo->busUnitInfo.deviceType);
}
- } else if (HvRc != 0x000B)
+ } else if (HvRc != 0x000B)
pci_Log_Error("EADs Connect",
bus, SubBus, AgentId, HvRc);
}
@@ -441,7 +412,7 @@ static void scan_EADS_bridge(HvBusNumber bus, HvSubBusNumber SubBus,
static int scan_bridge_slot(HvBusNumber Bus,
struct HvCallPci_BridgeInfo *BridgeInfo)
{
- struct iSeries_Device_Node *node;
+ struct device_node *node;
HvSubBusNumber SubBus = BridgeInfo->subBusNumber;
u16 VendorId = 0;
int HvRc = 0;
@@ -451,16 +422,13 @@ static int scan_bridge_slot(HvBusNumber Bus,
HvAgentId EADsIdSel = ISERIES_PCI_AGENTID(IdSel, Function);
/* iSeries_allocate_IRQ.: 0x18.00.12(0xA3) */
- Irq = iSeries_allocate_IRQ(Bus, 0, EADsIdSel);
- PPCDBG(PPCDBG_BUSWALK,
- "PCI:- allocate and assign IRQ 0x%02X.%02X.%02X = 0x%02X\n",
- Bus, 0, EADsIdSel, Irq);
+ Irq = iSeries_allocate_IRQ(Bus, 0, EADsIdSel);
/*
- * Connect all functions of any device found.
+ * Connect all functions of any device found.
*/
- for (IdSel = 1; IdSel <= BridgeInfo->maxAgents; ++IdSel) {
- for (Function = 0; Function < 8; ++Function) {
+ for (IdSel = 1; IdSel <= BridgeInfo->maxAgents; ++IdSel) {
+ for (Function = 0; Function < 8; ++Function) {
HvAgentId AgentId = ISERIES_PCI_AGENTID(IdSel, Function);
HvRc = HvCallXm_connectBusUnit(Bus, SubBus,
AgentId, Irq);
@@ -480,19 +448,16 @@ static int scan_bridge_slot(HvBusNumber Bus,
printk("read vendor ID: %x\n", VendorId);
/* FoundDevice: 0x18.28.10 = 0x12AE */
- PPCDBG(PPCDBG_BUSWALK,
- "PCI:- FoundDevice: 0x%02X.%02X.%02X = 0x%04X, irq %d\n",
- Bus, SubBus, AgentId, VendorId, Irq);
HvRc = HvCallPci_configStore8(Bus, SubBus, AgentId,
- PCI_INTERRUPT_LINE, Irq);
+ PCI_INTERRUPT_LINE, Irq);
if (HvRc != 0)
pci_Log_Error("PciCfgStore Irq Failed!",
Bus, SubBus, AgentId, HvRc);
++DeviceCount;
node = build_device_node(Bus, SubBus, EADsIdSel, Function);
- node->Irq = Irq;
- node->LogicalSlot = BridgeInfo->logicalSlotNumber;
+ PCI_DN(node)->Irq = Irq;
+ PCI_DN(node)->LogicalSlot = BridgeInfo->logicalSlotNumber;
} /* for (Function = 0; Function < 8; ++Function) */
} /* for (IdSel = 1; IdSel <= MaxAgents; ++IdSel) */
@@ -542,16 +507,13 @@ EXPORT_SYMBOL(iSeries_memcpy_fromio);
/*
* Look down the chain to find the matching Device Device
*/
-static struct iSeries_Device_Node *find_Device_Node(int bus, int devfn)
+static struct device_node *find_Device_Node(int bus, int devfn)
{
- struct list_head *pos;
-
- list_for_each(pos, &iSeries_Global_Device_List) {
- struct iSeries_Device_Node *node =
- list_entry(pos, struct iSeries_Device_Node, Device_List);
+ struct pci_dn *pdn;
- if ((bus == ISERIES_BUS(node)) && (devfn == node->DevFn))
- return node;
+ list_for_each_entry(pdn, &iSeries_Global_Device_List, Device_List) {
+ if ((bus == pdn->busno) && (devfn == pdn->devfn))
+ return pdn->node;
}
return NULL;
}
@@ -562,12 +524,12 @@ static struct iSeries_Device_Node *find_Device_Node(int bus, int devfn)
* Sanity Check Node PciDev to passed pci_dev
* If none is found, returns a NULL which the client must handle.
*/
-static struct iSeries_Device_Node *get_Device_Node(struct pci_dev *pdev)
+static struct device_node *get_Device_Node(struct pci_dev *pdev)
{
- struct iSeries_Device_Node *node;
+ struct device_node *node;
node = pdev->sysdata;
- if (node == NULL || node->PciDev != pdev)
+ if (node == NULL || PCI_DN(node)->pcidev != pdev)
node = find_Device_Node(pdev->bus->number, pdev->devfn);
return node;
}
@@ -595,7 +557,7 @@ static u64 hv_cfg_write_func[4] = {
static int iSeries_pci_read_config(struct pci_bus *bus, unsigned int devfn,
int offset, int size, u32 *val)
{
- struct iSeries_Device_Node *node = find_Device_Node(bus->number, devfn);
+ struct device_node *node = find_Device_Node(bus->number, devfn);
u64 fn;
struct HvCallPci_LoadReturn ret;
@@ -607,7 +569,7 @@ static int iSeries_pci_read_config(struct pci_bus *bus, unsigned int devfn,
}
fn = hv_cfg_read_func[(size - 1) & 3];
- HvCall3Ret16(fn, &ret, node->DsaAddr.DsaAddr, offset, 0);
+ HvCall3Ret16(fn, &ret, iseries_ds_addr(node), offset, 0);
if (ret.rc != 0) {
*val = ~0;
@@ -625,7 +587,7 @@ static int iSeries_pci_read_config(struct pci_bus *bus, unsigned int devfn,
static int iSeries_pci_write_config(struct pci_bus *bus, unsigned int devfn,
int offset, int size, u32 val)
{
- struct iSeries_Device_Node *node = find_Device_Node(bus->number, devfn);
+ struct device_node *node = find_Device_Node(bus->number, devfn);
u64 fn;
u64 ret;
@@ -635,7 +597,7 @@ static int iSeries_pci_write_config(struct pci_bus *bus, unsigned int devfn,
return PCIBIOS_BAD_REGISTER_NUMBER;
fn = hv_cfg_write_func[(size - 1) & 3];
- ret = HvCall4(fn, node->DsaAddr.DsaAddr, offset, val, 0);
+ ret = HvCall4(fn, iseries_ds_addr(node), offset, val, 0);
if (ret != 0)
return PCIBIOS_DEVICE_NOT_FOUND;
@@ -657,14 +619,16 @@ static struct pci_ops iSeries_pci_ops = {
* PCI: Device 23.90 ReadL Retry( 1)
* PCI: Device 23.90 ReadL Retry Successful(1)
*/
-static int CheckReturnCode(char *TextHdr, struct iSeries_Device_Node *DevNode,
+static int CheckReturnCode(char *TextHdr, struct device_node *DevNode,
int *retry, u64 ret)
{
if (ret != 0) {
+ struct pci_dn *pdn = PCI_DN(DevNode);
+
++Pci_Error_Count;
(*retry)++;
printk("PCI: %s: Device 0x%04X:%02X I/O Error(%2d): 0x%04X\n",
- TextHdr, DevNode->DsaAddr.Dsa.busNumber, DevNode->DevFn,
+ TextHdr, pdn->busno, pdn->devfn,
*retry, (int)ret);
/*
* Bump the retry and check for retry count exceeded.
@@ -687,14 +651,14 @@ static int CheckReturnCode(char *TextHdr, struct iSeries_Device_Node *DevNode,
* Note: Make sure the passed variable end up on the stack to avoid
* the exposure of being device global.
*/
-static inline struct iSeries_Device_Node *xlate_iomm_address(
+static inline struct device_node *xlate_iomm_address(
const volatile void __iomem *IoAddress,
u64 *dsaptr, u64 *BarOffsetPtr)
{
unsigned long OrigIoAddr;
unsigned long BaseIoAddr;
unsigned long TableIndex;
- struct iSeries_Device_Node *DevNode;
+ struct device_node *DevNode;
OrigIoAddr = (unsigned long __force)IoAddress;
if ((OrigIoAddr < BASE_IO_MEMORY) || (OrigIoAddr >= max_io_memory))
@@ -705,7 +669,7 @@ static inline struct iSeries_Device_Node *xlate_iomm_address(
if (DevNode != NULL) {
int barnum = iobar_table[TableIndex];
- *dsaptr = DevNode->DsaAddr.DsaAddr | (barnum << 24);
+ *dsaptr = iseries_ds_addr(DevNode) | (barnum << 24);
*BarOffsetPtr = BaseIoAddr % IOMM_TABLE_ENTRY_SIZE;
} else
panic("PCI: Invalid PCI IoAddress detected!\n");
@@ -727,7 +691,7 @@ u8 iSeries_Read_Byte(const volatile void __iomem *IoAddress)
u64 dsa;
int retry = 0;
struct HvCallPci_LoadReturn ret;
- struct iSeries_Device_Node *DevNode =
+ struct device_node *DevNode =
xlate_iomm_address(IoAddress, &dsa, &BarOffset);
if (DevNode == NULL) {
@@ -757,7 +721,7 @@ u16 iSeries_Read_Word(const volatile void __iomem *IoAddress)
u64 dsa;
int retry = 0;
struct HvCallPci_LoadReturn ret;
- struct iSeries_Device_Node *DevNode =
+ struct device_node *DevNode =
xlate_iomm_address(IoAddress, &dsa, &BarOffset);
if (DevNode == NULL) {
@@ -788,7 +752,7 @@ u32 iSeries_Read_Long(const volatile void __iomem *IoAddress)
u64 dsa;
int retry = 0;
struct HvCallPci_LoadReturn ret;
- struct iSeries_Device_Node *DevNode =
+ struct device_node *DevNode =
xlate_iomm_address(IoAddress, &dsa, &BarOffset);
if (DevNode == NULL) {
@@ -826,7 +790,7 @@ void iSeries_Write_Byte(u8 data, volatile void __iomem *IoAddress)
u64 dsa;
int retry = 0;
u64 rc;
- struct iSeries_Device_Node *DevNode =
+ struct device_node *DevNode =
xlate_iomm_address(IoAddress, &dsa, &BarOffset);
if (DevNode == NULL) {
@@ -854,7 +818,7 @@ void iSeries_Write_Word(u16 data, volatile void __iomem *IoAddress)
u64 dsa;
int retry = 0;
u64 rc;
- struct iSeries_Device_Node *DevNode =
+ struct device_node *DevNode =
xlate_iomm_address(IoAddress, &dsa, &BarOffset);
if (DevNode == NULL) {
@@ -882,7 +846,7 @@ void iSeries_Write_Long(u32 data, volatile void __iomem *IoAddress)
u64 dsa;
int retry = 0;
u64 rc;
- struct iSeries_Device_Node *DevNode =
+ struct device_node *DevNode =
xlate_iomm_address(IoAddress, &dsa, &BarOffset);
if (DevNode == NULL) {
diff --git a/include/asm-ppc64/iSeries/iSeries_pci.h b/arch/powerpc/platforms/iseries/pci.h
index 575f611f8b33..33a8489fde54 100644
--- a/include/asm-ppc64/iSeries/iSeries_pci.h
+++ b/arch/powerpc/platforms/iseries/pci.h
@@ -1,8 +1,8 @@
-#ifndef _ISERIES_64_PCI_H
-#define _ISERIES_64_PCI_H
+#ifndef _PLATFORMS_ISERIES_PCI_H
+#define _PLATFORMS_ISERIES_PCI_H
/*
- * File iSeries_pci.h created by Allan Trautman on Tue Feb 20, 2001.
+ * Created by Allan Trautman on Tue Feb 20, 2001.
*
* Define some useful macros for the iSeries pci routines.
* Copyright (C) 2001 Allan H Trautman, IBM Corporation
@@ -30,23 +30,9 @@
* End Change Activity
*/
-#include <asm/iSeries/HvCallPci.h>
-#include <asm/abs_addr.h>
+#include <asm/pci-bridge.h>
struct pci_dev; /* For Forward Reference */
-struct iSeries_Device_Node;
-
-/*
- * Gets iSeries Bus, SubBus, DevFn using iSeries_Device_Node structure
- */
-
-#define ISERIES_BUS(DevPtr) DevPtr->DsaAddr.Dsa.busNumber
-#define ISERIES_SUBBUS(DevPtr) DevPtr->DsaAddr.Dsa.subBusNumber
-#define ISERIES_DEVICE(DevPtr) DevPtr->DsaAddr.Dsa.deviceId
-#define ISERIES_DSA(DevPtr) DevPtr->DsaAddr.DsaAddr
-#define ISERIES_DEVNODE(PciDev) ((struct iSeries_Device_Node *)PciDev->sysdata)
-
-#define EADsMaxAgents 7
/*
* Decodes Linux DevFn to iSeries DevFn, bridge device, or function.
@@ -62,27 +48,16 @@ struct iSeries_Device_Node;
#define ISERIES_GET_FUNCTION_FROM_SUBBUS(subbus) ((subbus >> 2) & 0x7)
/*
- * Converts Virtual Address to Real Address for Hypervisor calls
+ * Generate a Direct Select Address for the Hypervisor
*/
-#define ISERIES_HV_ADDR(virtaddr) \
- (0x8000000000000000 | virt_to_abs(virtaddr))
+static inline u64 iseries_ds_addr(struct device_node *node)
+{
+ struct pci_dn *pdn = PCI_DN(node);
-/*
- * iSeries Device Information
- */
-struct iSeries_Device_Node {
- struct list_head Device_List;
- struct pci_dev *PciDev;
- union HvDsaMap DsaAddr; /* Direct Select Address */
- /* busNumber, subBusNumber, */
- /* deviceId, barNumber */
- int DevFn; /* Linux devfn */
- int Irq; /* Assigned IRQ */
- int Flags; /* Possible flags(disable/bist)*/
- u8 LogicalSlot; /* Hv Slot Index for Tces */
- struct iommu_table *iommu_table;/* Device TCE Table */
-};
+ return ((u64)pdn->busno << 48) + ((u64)pdn->bussubno << 40)
+ + ((u64)0x10 << 32);
+}
extern void iSeries_Device_Information(struct pci_dev*, int);
-#endif /* _ISERIES_64_PCI_H */
+#endif /* _PLATFORMS_ISERIES_PCI_H */
diff --git a/arch/ppc64/kernel/iSeries_proc.c b/arch/powerpc/platforms/iseries/proc.c
index 0fe3116eba29..e68b6b5fa89f 100644
--- a/arch/ppc64/kernel/iSeries_proc.c
+++ b/arch/powerpc/platforms/iseries/proc.c
@@ -1,5 +1,4 @@
/*
- * iSeries_proc.c
* Copyright (C) 2001 Kyle A. Lucke IBM Corporation
* Copyright (C) 2001 Mike Corrigan & Dave Engebretsen IBM Corporation
*
@@ -25,10 +24,11 @@
#include <asm/processor.h>
#include <asm/time.h>
#include <asm/lppaca.h>
-#include <asm/iSeries/ItLpQueue.h>
-#include <asm/iSeries/HvCallXm.h>
-#include <asm/iSeries/IoHriMainStore.h>
-#include <asm/iSeries/IoHriProcessorVpd.h>
+#include <asm/iseries/it_lp_queue.h>
+#include <asm/iseries/hv_call_xm.h>
+
+#include "processor_vpd.h"
+#include "main_store.h"
static int __init iseries_proc_create(void)
{
@@ -68,12 +68,15 @@ static int proc_titantod_show(struct seq_file *m, void *v)
unsigned long tb_ticks = (tb0 - startTb);
unsigned long titan_jiffies = titan_usec / (1000000/HZ);
unsigned long titan_jiff_usec = titan_jiffies * (1000000/HZ);
- unsigned long titan_jiff_rem_usec = titan_usec - titan_jiff_usec;
+ unsigned long titan_jiff_rem_usec =
+ titan_usec - titan_jiff_usec;
unsigned long tb_jiffies = tb_ticks / tb_ticks_per_jiffy;
unsigned long tb_jiff_ticks = tb_jiffies * tb_ticks_per_jiffy;
unsigned long tb_jiff_rem_ticks = tb_ticks - tb_jiff_ticks;
- unsigned long tb_jiff_rem_usec = tb_jiff_rem_ticks / tb_ticks_per_usec;
- unsigned long new_tb_ticks_per_jiffy = (tb_ticks * (1000000/HZ))/titan_usec;
+ unsigned long tb_jiff_rem_usec =
+ tb_jiff_rem_ticks / tb_ticks_per_usec;
+ unsigned long new_tb_ticks_per_jiffy =
+ (tb_ticks * (1000000/HZ))/titan_usec;
seq_printf(m, " titan elapsed = %lu uSec\n", titan_usec);
seq_printf(m, " tb elapsed = %lu ticks\n", tb_ticks);
diff --git a/include/asm-ppc64/iSeries/IoHriProcessorVpd.h b/arch/powerpc/platforms/iseries/processor_vpd.h
index 73b73d80b8b1..7ac5d0d0dbfa 100644
--- a/include/asm-ppc64/iSeries/IoHriProcessorVpd.h
+++ b/arch/powerpc/platforms/iseries/processor_vpd.h
@@ -1,5 +1,4 @@
/*
- * IoHriProcessorVpd.h
* Copyright (C) 2001 Mike Corrigan IBM Corporation
*
* This program is free software; you can redistribute it and/or modify
@@ -16,8 +15,8 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#ifndef _IOHRIPROCESSORVPD_H
-#define _IOHRIPROCESSORVPD_H
+#ifndef _ISERIES_PROCESSOR_VPD_H
+#define _ISERIES_PROCESSOR_VPD_H
#include <asm/types.h>
@@ -83,4 +82,4 @@ struct IoHriProcessorVpd {
extern struct IoHriProcessorVpd xIoHriProcessorVpd[];
-#endif /* _IOHRIPROCESSORVPD_H */
+#endif /* _ISERIES_PROCESSOR_VPD_H */
diff --git a/include/asm-ppc64/iSeries/HvReleaseData.h b/arch/powerpc/platforms/iseries/release_data.h
index c8162e5ccb21..66189fd2e32d 100644
--- a/include/asm-ppc64/iSeries/HvReleaseData.h
+++ b/arch/powerpc/platforms/iseries/release_data.h
@@ -1,5 +1,4 @@
/*
- * HvReleaseData.h
* Copyright (C) 2001 Mike Corrigan IBM Corporation
*
* This program is free software; you can redistribute it and/or modify
@@ -16,8 +15,8 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#ifndef _HVRELEASEDATA_H
-#define _HVRELEASEDATA_H
+#ifndef _ISERIES_RELEASE_DATA_H
+#define _ISERIES_RELEASE_DATA_H
/*
* This control block contains the critical information about the
@@ -25,7 +24,7 @@
* address of the OS's NACA).
*/
#include <asm/types.h>
-#include <asm/naca.h>
+#include "naca.h"
/*
* When we IPL a secondary partition, we will check if if the
@@ -61,4 +60,4 @@ struct HvReleaseData {
extern struct HvReleaseData hvReleaseData;
-#endif /* _HVRELEASEDATA_H */
+#endif /* _ISERIES_RELEASE_DATA_H */
diff --git a/arch/ppc64/kernel/iSeries_setup.c b/arch/powerpc/platforms/iseries/setup.c
index 3ffefbbc6623..6a29f301436b 100644
--- a/arch/ppc64/kernel/iSeries_setup.c
+++ b/arch/powerpc/platforms/iseries/setup.c
@@ -2,8 +2,6 @@
* Copyright (c) 2000 Mike Corrigan <mikejc@us.ibm.com>
* Copyright (c) 1999-2000 Grant Erickson <grant@lcse.umn.edu>
*
- * Module name: iSeries_setup.c
- *
* Description:
* Architecture- / platform-specific boot-time initialization code for
* the IBM iSeries LPAR. Adapted from original code by Grant Erickson and
@@ -29,6 +27,7 @@
#include <linux/kdev_t.h>
#include <linux/major.h>
#include <linux/root_dev.h>
+#include <linux/kernel.h>
#include <asm/processor.h>
#include <asm/machdep.h>
@@ -40,27 +39,29 @@
#include <asm/sections.h>
#include <asm/iommu.h>
#include <asm/firmware.h>
-
+#include <asm/systemcfg.h>
+#include <asm/system.h>
#include <asm/time.h>
-#include "iSeries_setup.h"
-#include <asm/naca.h>
#include <asm/paca.h>
#include <asm/cache.h>
#include <asm/sections.h>
#include <asm/abs_addr.h>
-#include <asm/iSeries/HvCallHpt.h>
-#include <asm/iSeries/HvLpConfig.h>
-#include <asm/iSeries/HvCallEvent.h>
-#include <asm/iSeries/HvCallSm.h>
-#include <asm/iSeries/HvCallXm.h>
-#include <asm/iSeries/ItLpQueue.h>
-#include <asm/iSeries/IoHriMainStore.h>
-#include <asm/iSeries/mf.h>
-#include <asm/iSeries/HvLpEvent.h>
-#include <asm/iSeries/iSeries_irq.h>
-#include <asm/iSeries/IoHriProcessorVpd.h>
-#include <asm/iSeries/ItVpdAreas.h>
-#include <asm/iSeries/LparMap.h>
+#include <asm/iseries/hv_lp_config.h>
+#include <asm/iseries/hv_call_event.h>
+#include <asm/iseries/hv_call_xm.h>
+#include <asm/iseries/it_lp_queue.h>
+#include <asm/iseries/mf.h>
+#include <asm/iseries/hv_lp_event.h>
+#include <asm/iseries/lpar_map.h>
+
+#include "naca.h"
+#include "setup.h"
+#include "irq.h"
+#include "vpd_areas.h"
+#include "processor_vpd.h"
+#include "main_store.h"
+#include "call_sm.h"
+#include "call_hpt.h"
extern void hvlog(char *fmt, ...);
@@ -71,11 +72,9 @@ extern void hvlog(char *fmt, ...);
#endif
/* Function Prototypes */
-extern void ppcdbg_initialize(void);
-
-static void build_iSeries_Memory_Map(void);
-static void setup_iSeries_cache_sizes(void);
-static void iSeries_bolt_kernel(unsigned long saddr, unsigned long eaddr);
+static unsigned long build_iSeries_Memory_Map(void);
+static void iseries_shared_idle(void);
+static void iseries_dedicated_idle(void);
#ifdef CONFIG_PCI
extern void iSeries_pci_final_fixup(void);
#else
@@ -83,18 +82,9 @@ static void iSeries_pci_final_fixup(void) { }
#endif
/* Global Variables */
-static unsigned long procFreqHz;
-static unsigned long procFreqMhz;
-static unsigned long procFreqMhzHundreths;
-
-static unsigned long tbFreqHz;
-static unsigned long tbFreqMhz;
-static unsigned long tbFreqMhzHundreths;
-
int piranha_simulator;
extern int rd_size; /* Defined in drivers/block/rd.c */
-extern unsigned long klimit;
extern unsigned long embedded_sysmap_start;
extern unsigned long embedded_sysmap_end;
@@ -103,6 +93,8 @@ extern unsigned long iSeries_recal_titan;
static int mf_initialized;
+static unsigned long cmd_mem_limit;
+
struct MemoryBlock {
unsigned long absStart;
unsigned long absEnd;
@@ -311,13 +303,11 @@ static void __init iSeries_get_cmdline(void)
static void __init iSeries_init_early(void)
{
- extern unsigned long memory_limit;
-
DBG(" -> iSeries_init_early()\n");
ppc64_firmware_features = FW_FEATURE_ISERIES;
- ppcdbg_initialize();
+ ppc64_interrupt_controller = IC_ISERIES;
#if defined(CONFIG_BLK_DEV_INITRD)
/*
@@ -326,11 +316,11 @@ static void __init iSeries_init_early(void)
*/
if (naca.xRamDisk) {
initrd_start = (unsigned long)__va(naca.xRamDisk);
- initrd_end = initrd_start + naca.xRamDiskSize * PAGE_SIZE;
+ initrd_end = initrd_start + naca.xRamDiskSize * HW_PAGE_SIZE;
initrd_below_start_ok = 1; // ramdisk in kernel space
ROOT_DEV = Root_RAM0;
- if (((rd_size * 1024) / PAGE_SIZE) < naca.xRamDiskSize)
- rd_size = (naca.xRamDiskSize * PAGE_SIZE) / 1024;
+ if (((rd_size * 1024) / HW_PAGE_SIZE) < naca.xRamDiskSize)
+ rd_size = (naca.xRamDiskSize * HW_PAGE_SIZE) / 1024;
} else
#endif /* CONFIG_BLK_DEV_INITRD */
{
@@ -341,12 +331,6 @@ static void __init iSeries_init_early(void)
iSeries_recal_titan = HvCallXm_loadTod();
/*
- * Cache sizes must be initialized before hpte_init_iSeries is called
- * as the later need them for flush_icache_range()
- */
- setup_iSeries_cache_sizes();
-
- /*
* Initialize the hash table management pointers
*/
hpte_init_iSeries();
@@ -356,37 +340,6 @@ static void __init iSeries_init_early(void)
*/
iommu_init_early_iSeries();
- /*
- * Initialize the table which translate Linux physical addresses to
- * AS/400 absolute addresses
- */
- build_iSeries_Memory_Map();
-
- iSeries_get_cmdline();
-
- /* Save unparsed command line copy for /proc/cmdline */
- strlcpy(saved_command_line, cmd_line, COMMAND_LINE_SIZE);
-
- /* Parse early parameters, in particular mem=x */
- parse_early_param();
-
- if (memory_limit) {
- if (memory_limit < systemcfg->physicalMemorySize)
- systemcfg->physicalMemorySize = memory_limit;
- else {
- printk("Ignoring mem=%lu >= ram_top.\n", memory_limit);
- memory_limit = 0;
- }
- }
-
- /* Bolt kernel mappings for all of memory (or just a bit if we've got a limit) */
- iSeries_bolt_kernel(0, systemcfg->physicalMemorySize);
-
- lmb_init();
- lmb_add(0, systemcfg->physicalMemorySize);
- lmb_analyze();
- lmb_reserve(0, __pa(klimit));
-
/* Initialize machine-dependency vectors */
#ifdef CONFIG_SMP
smp_init_iSeries();
@@ -450,14 +403,15 @@ void mschunks_alloc(unsigned long num_chunks)
* a table used to translate Linux's physical addresses to these
* absolute addresses. Absolute addresses are needed when
* communicating with the hypervisor (e.g. to build HPT entries)
+ *
+ * Returns the physical memory size
*/
-static void __init build_iSeries_Memory_Map(void)
+static unsigned long __init build_iSeries_Memory_Map(void)
{
u32 loadAreaFirstChunk, loadAreaLastChunk, loadAreaSize;
u32 nextPhysChunk;
u32 hptFirstChunk, hptLastChunk, hptSizeChunks, hptSizePages;
- u32 num_ptegs;
u32 totalChunks,moreChunks;
u32 currChunk, thisChunk, absChunk;
u32 currDword;
@@ -514,16 +468,14 @@ static void __init build_iSeries_Memory_Map(void)
*/
hptFirstChunk = (u32)addr_to_chunk(HvCallHpt_getHptAddress());
hptSizePages = (u32)HvCallHpt_getHptPages();
- hptSizeChunks = hptSizePages >> (MSCHUNKS_CHUNK_SHIFT - PAGE_SHIFT);
+ hptSizeChunks = hptSizePages >>
+ (MSCHUNKS_CHUNK_SHIFT - HW_PAGE_SHIFT);
hptLastChunk = hptFirstChunk + hptSizeChunks - 1;
printk("HPT absolute addr = %016lx, size = %dK\n",
chunk_to_addr(hptFirstChunk), hptSizeChunks * 256);
- /* Fill in the hashed page table hash mask */
- num_ptegs = hptSizePages *
- (PAGE_SIZE / (sizeof(hpte_t) * HPTES_PER_GROUP));
- htab_hash_mask = num_ptegs - 1;
+ ppc64_pft_size = __ilog2(hptSizePages * HW_PAGE_SIZE);
/*
* The actual hashed page table is in the hypervisor,
@@ -588,104 +540,7 @@ static void __init build_iSeries_Memory_Map(void)
* which should be equal to
* nextPhysChunk
*/
- systemcfg->physicalMemorySize = chunk_to_addr(nextPhysChunk);
-}
-
-/*
- * Set up the variables that describe the cache line sizes
- * for this machine.
- */
-static void __init setup_iSeries_cache_sizes(void)
-{
- unsigned int i, n;
- unsigned int procIx = get_paca()->lppaca.dyn_hv_phys_proc_index;
-
- systemcfg->icache_size =
- ppc64_caches.isize = xIoHriProcessorVpd[procIx].xInstCacheSize * 1024;
- systemcfg->icache_line_size =
- ppc64_caches.iline_size =
- xIoHriProcessorVpd[procIx].xInstCacheOperandSize;
- systemcfg->dcache_size =
- ppc64_caches.dsize =
- xIoHriProcessorVpd[procIx].xDataL1CacheSizeKB * 1024;
- systemcfg->dcache_line_size =
- ppc64_caches.dline_size =
- xIoHriProcessorVpd[procIx].xDataCacheOperandSize;
- ppc64_caches.ilines_per_page = PAGE_SIZE / ppc64_caches.iline_size;
- ppc64_caches.dlines_per_page = PAGE_SIZE / ppc64_caches.dline_size;
-
- i = ppc64_caches.iline_size;
- n = 0;
- while ((i = (i / 2)))
- ++n;
- ppc64_caches.log_iline_size = n;
-
- i = ppc64_caches.dline_size;
- n = 0;
- while ((i = (i / 2)))
- ++n;
- ppc64_caches.log_dline_size = n;
-
- printk("D-cache line size = %d\n",
- (unsigned int)ppc64_caches.dline_size);
- printk("I-cache line size = %d\n",
- (unsigned int)ppc64_caches.iline_size);
-}
-
-/*
- * Create a pte. Used during initialization only.
- */
-static void iSeries_make_pte(unsigned long va, unsigned long pa,
- int mode)
-{
- hpte_t local_hpte, rhpte;
- unsigned long hash, vpn;
- long slot;
-
- vpn = va >> PAGE_SHIFT;
- hash = hpt_hash(vpn, 0);
-
- local_hpte.r = pa | mode;
- local_hpte.v = ((va >> 23) << HPTE_V_AVPN_SHIFT)
- | HPTE_V_BOLTED | HPTE_V_VALID;
-
- slot = HvCallHpt_findValid(&rhpte, vpn);
- if (slot < 0) {
- /* Must find space in primary group */
- panic("hash_page: hpte already exists\n");
- }
- HvCallHpt_addValidate(slot, 0, &local_hpte);
-}
-
-/*
- * Bolt the kernel addr space into the HPT
- */
-static void __init iSeries_bolt_kernel(unsigned long saddr, unsigned long eaddr)
-{
- unsigned long pa;
- unsigned long mode_rw = _PAGE_ACCESSED | _PAGE_COHERENT | PP_RWXX;
- hpte_t hpte;
-
- for (pa = saddr; pa < eaddr ;pa += PAGE_SIZE) {
- unsigned long ea = (unsigned long)__va(pa);
- unsigned long vsid = get_kernel_vsid(ea);
- unsigned long va = (vsid << 28) | (pa & 0xfffffff);
- unsigned long vpn = va >> PAGE_SHIFT;
- unsigned long slot = HvCallHpt_findValid(&hpte, vpn);
-
- /* Make non-kernel text non-executable */
- if (!in_kernel_text(ea))
- mode_rw |= HW_NO_EXEC;
-
- if (hpte.v & HPTE_V_VALID) {
- /* HPTE exists, so just bolt it */
- HvCallHpt_setSwBits(slot, 0x10, 0);
- /* And make sure the pp bits are correct */
- HvCallHpt_setPp(slot, PP_RWXX);
- } else
- /* No HPTE exists, so create a new bolted one */
- iSeries_make_pte(va, phys_to_abs(pa), mode_rw);
- }
+ return chunk_to_addr(nextPhysChunk);
}
/*
@@ -695,41 +550,27 @@ static void __init iSeries_setup_arch(void)
{
unsigned procIx = get_paca()->lppaca.dyn_hv_phys_proc_index;
- /* Add an eye catcher and the systemcfg layout version number */
- strcpy(systemcfg->eye_catcher, "SYSTEMCFG:PPC64");
- systemcfg->version.major = SYSTEMCFG_MAJOR;
- systemcfg->version.minor = SYSTEMCFG_MINOR;
+ if (get_paca()->lppaca.shared_proc) {
+ ppc_md.idle_loop = iseries_shared_idle;
+ printk(KERN_INFO "Using shared processor idle loop\n");
+ } else {
+ ppc_md.idle_loop = iseries_dedicated_idle;
+ printk(KERN_INFO "Using dedicated idle loop\n");
+ }
/* Setup the Lp Event Queue */
setup_hvlpevent_queue();
- /* Compute processor frequency */
- procFreqHz = ((1UL << 34) * 1000000) /
- xIoHriProcessorVpd[procIx].xProcFreq;
- procFreqMhz = procFreqHz / 1000000;
- procFreqMhzHundreths = (procFreqHz / 10000) - (procFreqMhz * 100);
- ppc_proc_freq = procFreqHz;
-
- /* Compute time base frequency */
- tbFreqHz = ((1UL << 32) * 1000000) /
- xIoHriProcessorVpd[procIx].xTimeBaseFreq;
- tbFreqMhz = tbFreqHz / 1000000;
- tbFreqMhzHundreths = (tbFreqHz / 10000) - (tbFreqMhz * 100);
- ppc_tb_freq = tbFreqHz;
-
printk("Max logical processors = %d\n",
itVpdAreas.xSlicMaxLogicalProcs);
printk("Max physical processors = %d\n",
itVpdAreas.xSlicMaxPhysicalProcs);
- printk("Processor frequency = %lu.%02lu\n", procFreqMhz,
- procFreqMhzHundreths);
- printk("Time base frequency = %lu.%02lu\n", tbFreqMhz,
- tbFreqMhzHundreths);
- systemcfg->processor = xIoHriProcessorVpd[procIx].xPVR;
- printk("Processor version = %x\n", systemcfg->processor);
+
+ _systemcfg->processor = xIoHriProcessorVpd[procIx].xPVR;
+ printk("Processor version = %x\n", _systemcfg->processor);
}
-static void iSeries_get_cpuinfo(struct seq_file *m)
+static void iSeries_show_cpuinfo(struct seq_file *m)
{
seq_printf(m, "machine\t\t: 64-bit iSeries Logical Partition\n");
}
@@ -768,49 +609,6 @@ static void iSeries_halt(void)
mf_power_off();
}
-/*
- * void __init iSeries_calibrate_decr()
- *
- * Description:
- * This routine retrieves the internal processor frequency from the VPD,
- * and sets up the kernel timer decrementer based on that value.
- *
- */
-static void __init iSeries_calibrate_decr(void)
-{
- unsigned long cyclesPerUsec;
- struct div_result divres;
-
- /* Compute decrementer (and TB) frequency in cycles/sec */
- cyclesPerUsec = ppc_tb_freq / 1000000;
-
- /*
- * Set the amount to refresh the decrementer by. This
- * is the number of decrementer ticks it takes for
- * 1/HZ seconds.
- */
- tb_ticks_per_jiffy = ppc_tb_freq / HZ;
-
-#if 0
- /* TEST CODE FOR ADJTIME */
- tb_ticks_per_jiffy += tb_ticks_per_jiffy / 5000;
- /* END OF TEST CODE */
-#endif
-
- /*
- * tb_ticks_per_sec = freq; would give better accuracy
- * but tb_ticks_per_sec = tb_ticks_per_jiffy*HZ; assures
- * that jiffies (and xtime) will match the time returned
- * by do_gettimeofday.
- */
- tb_ticks_per_sec = tb_ticks_per_jiffy * HZ;
- tb_ticks_per_usec = cyclesPerUsec;
- tb_to_us = mulhwu_scale_factor(ppc_tb_freq, 1000000);
- div128_by_32(1024 * 1024, 0, tb_ticks_per_sec, &divres);
- tb_to_xs = divres.result_low;
- setup_default_decr();
-}
-
static void __init iSeries_progress(char * st, unsigned short code)
{
printk("Progress: [%04x] - %s\n", (unsigned)code, st);
@@ -830,7 +628,7 @@ static void __init iSeries_fixup_klimit(void)
*/
if (naca.xRamDisk)
klimit = KERNELBASE + (u64)naca.xRamDisk +
- (naca.xRamDiskSize * PAGE_SIZE);
+ (naca.xRamDiskSize * HW_PAGE_SIZE);
else {
/*
* No ram disk was included - check and see if there
@@ -878,7 +676,7 @@ static void yield_shared_processor(void)
process_iSeries_events();
}
-static int iseries_shared_idle(void)
+static void iseries_shared_idle(void)
{
while (1) {
while (!need_resched() && !hvlpevent_is_pending()) {
@@ -898,22 +696,18 @@ static int iseries_shared_idle(void)
if (hvlpevent_is_pending())
process_iSeries_events();
+ preempt_enable_no_resched();
schedule();
+ preempt_disable();
}
-
- return 0;
}
-static int iseries_dedicated_idle(void)
+static void iseries_dedicated_idle(void)
{
- long oldval;
+ set_thread_flag(TIF_POLLING_NRFLAG);
while (1) {
- oldval = test_and_clear_thread_flag(TIF_NEED_RESCHED);
-
- if (!oldval) {
- set_thread_flag(TIF_POLLING_NRFLAG);
-
+ if (!need_resched()) {
while (!need_resched()) {
ppc64_runlatch_off();
HMT_low();
@@ -926,52 +720,283 @@ static int iseries_dedicated_idle(void)
}
HMT_medium();
- clear_thread_flag(TIF_POLLING_NRFLAG);
- } else {
- set_need_resched();
}
ppc64_runlatch_on();
+ preempt_enable_no_resched();
schedule();
+ preempt_disable();
}
-
- return 0;
}
#ifndef CONFIG_PCI
void __init iSeries_init_IRQ(void) { }
#endif
-void __init iSeries_early_setup(void)
+static int __init iseries_probe(int platform)
{
- iSeries_fixup_klimit();
+ return PLATFORM_ISERIES_LPAR == platform;
+}
+
+struct machdep_calls __initdata iseries_md = {
+ .setup_arch = iSeries_setup_arch,
+ .show_cpuinfo = iSeries_show_cpuinfo,
+ .init_IRQ = iSeries_init_IRQ,
+ .get_irq = iSeries_get_irq,
+ .init_early = iSeries_init_early,
+ .pcibios_fixup = iSeries_pci_final_fixup,
+ .restart = iSeries_restart,
+ .power_off = iSeries_power_off,
+ .halt = iSeries_halt,
+ .get_boot_time = iSeries_get_boot_time,
+ .set_rtc_time = iSeries_set_rtc_time,
+ .get_rtc_time = iSeries_get_rtc_time,
+ .calibrate_decr = generic_calibrate_decr,
+ .progress = iSeries_progress,
+ .probe = iseries_probe,
+ /* XXX Implement enable_pmcs for iSeries */
+};
- ppc_md.setup_arch = iSeries_setup_arch;
- ppc_md.get_cpuinfo = iSeries_get_cpuinfo;
- ppc_md.init_IRQ = iSeries_init_IRQ;
- ppc_md.get_irq = iSeries_get_irq;
- ppc_md.init_early = iSeries_init_early,
+struct blob {
+ unsigned char data[PAGE_SIZE];
+ unsigned long next;
+};
- ppc_md.pcibios_fixup = iSeries_pci_final_fixup;
+struct iseries_flat_dt {
+ struct boot_param_header header;
+ u64 reserve_map[2];
+ struct blob dt;
+ struct blob strings;
+};
- ppc_md.restart = iSeries_restart;
- ppc_md.power_off = iSeries_power_off;
- ppc_md.halt = iSeries_halt;
+struct iseries_flat_dt iseries_dt;
- ppc_md.get_boot_time = iSeries_get_boot_time;
- ppc_md.set_rtc_time = iSeries_set_rtc_time;
- ppc_md.get_rtc_time = iSeries_get_rtc_time;
- ppc_md.calibrate_decr = iSeries_calibrate_decr;
- ppc_md.progress = iSeries_progress;
+void dt_init(struct iseries_flat_dt *dt)
+{
+ dt->header.off_mem_rsvmap =
+ offsetof(struct iseries_flat_dt, reserve_map);
+ dt->header.off_dt_struct = offsetof(struct iseries_flat_dt, dt);
+ dt->header.off_dt_strings = offsetof(struct iseries_flat_dt, strings);
+ dt->header.totalsize = sizeof(struct iseries_flat_dt);
+ dt->header.dt_strings_size = sizeof(struct blob);
- /* XXX Implement enable_pmcs for iSeries */
+ /* There is no notion of hardware cpu id on iSeries */
+ dt->header.boot_cpuid_phys = smp_processor_id();
- if (get_paca()->lppaca.shared_proc) {
- ppc_md.idle_loop = iseries_shared_idle;
- printk(KERN_INFO "Using shared processor idle loop\n");
- } else {
- ppc_md.idle_loop = iseries_dedicated_idle;
- printk(KERN_INFO "Using dedicated idle loop\n");
+ dt->dt.next = (unsigned long)&dt->dt.data;
+ dt->strings.next = (unsigned long)&dt->strings.data;
+
+ dt->header.magic = OF_DT_HEADER;
+ dt->header.version = 0x10;
+ dt->header.last_comp_version = 0x10;
+
+ dt->reserve_map[0] = 0;
+ dt->reserve_map[1] = 0;
+}
+
+void dt_check_blob(struct blob *b)
+{
+ if (b->next >= (unsigned long)&b->next) {
+ DBG("Ran out of space in flat device tree blob!\n");
+ BUG();
+ }
+}
+
+void dt_push_u32(struct iseries_flat_dt *dt, u32 value)
+{
+ *((u32*)dt->dt.next) = value;
+ dt->dt.next += sizeof(u32);
+
+ dt_check_blob(&dt->dt);
+}
+
+void dt_push_u64(struct iseries_flat_dt *dt, u64 value)
+{
+ *((u64*)dt->dt.next) = value;
+ dt->dt.next += sizeof(u64);
+
+ dt_check_blob(&dt->dt);
+}
+
+unsigned long dt_push_bytes(struct blob *blob, char *data, int len)
+{
+ unsigned long start = blob->next - (unsigned long)blob->data;
+
+ memcpy((char *)blob->next, data, len);
+ blob->next = _ALIGN(blob->next + len, 4);
+
+ dt_check_blob(blob);
+
+ return start;
+}
+
+void dt_start_node(struct iseries_flat_dt *dt, char *name)
+{
+ dt_push_u32(dt, OF_DT_BEGIN_NODE);
+ dt_push_bytes(&dt->dt, name, strlen(name) + 1);
+}
+
+#define dt_end_node(dt) dt_push_u32(dt, OF_DT_END_NODE)
+
+void dt_prop(struct iseries_flat_dt *dt, char *name, char *data, int len)
+{
+ unsigned long offset;
+
+ dt_push_u32(dt, OF_DT_PROP);
+
+ /* Length of the data */
+ dt_push_u32(dt, len);
+
+ /* Put the property name in the string blob. */
+ offset = dt_push_bytes(&dt->strings, name, strlen(name) + 1);
+
+ /* The offset of the properties name in the string blob. */
+ dt_push_u32(dt, (u32)offset);
+
+ /* The actual data. */
+ dt_push_bytes(&dt->dt, data, len);
+}
+
+void dt_prop_str(struct iseries_flat_dt *dt, char *name, char *data)
+{
+ dt_prop(dt, name, data, strlen(data) + 1); /* + 1 for NULL */
+}
+
+void dt_prop_u32(struct iseries_flat_dt *dt, char *name, u32 data)
+{
+ dt_prop(dt, name, (char *)&data, sizeof(u32));
+}
+
+void dt_prop_u64(struct iseries_flat_dt *dt, char *name, u64 data)
+{
+ dt_prop(dt, name, (char *)&data, sizeof(u64));
+}
+
+void dt_prop_u64_list(struct iseries_flat_dt *dt, char *name, u64 *data, int n)
+{
+ dt_prop(dt, name, (char *)data, sizeof(u64) * n);
+}
+
+void dt_prop_empty(struct iseries_flat_dt *dt, char *name)
+{
+ dt_prop(dt, name, NULL, 0);
+}
+
+void dt_cpus(struct iseries_flat_dt *dt)
+{
+ unsigned char buf[32];
+ unsigned char *p;
+ unsigned int i, index;
+ struct IoHriProcessorVpd *d;
+
+ /* yuck */
+ snprintf(buf, 32, "PowerPC,%s", cur_cpu_spec->cpu_name);
+ p = strchr(buf, ' ');
+ if (!p) p = buf + strlen(buf);
+
+ dt_start_node(dt, "cpus");
+ dt_prop_u32(dt, "#address-cells", 1);
+ dt_prop_u32(dt, "#size-cells", 0);
+
+ for (i = 0; i < NR_CPUS; i++) {
+ if (paca[i].lppaca.dyn_proc_status >= 2)
+ continue;
+
+ snprintf(p, 32 - (p - buf), "@%d", i);
+ dt_start_node(dt, buf);
+
+ dt_prop_str(dt, "device_type", "cpu");
+
+ index = paca[i].lppaca.dyn_hv_phys_proc_index;
+ d = &xIoHriProcessorVpd[index];
+
+ dt_prop_u32(dt, "i-cache-size", d->xInstCacheSize * 1024);
+ dt_prop_u32(dt, "i-cache-line-size", d->xInstCacheOperandSize);
+
+ dt_prop_u32(dt, "d-cache-size", d->xDataL1CacheSizeKB * 1024);
+ dt_prop_u32(dt, "d-cache-line-size", d->xDataCacheOperandSize);
+
+ /* magic conversions to Hz copied from old code */
+ dt_prop_u32(dt, "clock-frequency",
+ ((1UL << 34) * 1000000) / d->xProcFreq);
+ dt_prop_u32(dt, "timebase-frequency",
+ ((1UL << 32) * 1000000) / d->xTimeBaseFreq);
+
+ dt_prop_u32(dt, "reg", i);
+
+ dt_end_node(dt);
}
+
+ dt_end_node(dt);
+}
+
+void build_flat_dt(struct iseries_flat_dt *dt, unsigned long phys_mem_size)
+{
+ u64 tmp[2];
+
+ dt_init(dt);
+
+ dt_start_node(dt, "");
+
+ dt_prop_u32(dt, "#address-cells", 2);
+ dt_prop_u32(dt, "#size-cells", 2);
+
+ /* /memory */
+ dt_start_node(dt, "memory@0");
+ dt_prop_str(dt, "name", "memory");
+ dt_prop_str(dt, "device_type", "memory");
+ tmp[0] = 0;
+ tmp[1] = phys_mem_size;
+ dt_prop_u64_list(dt, "reg", tmp, 2);
+ dt_end_node(dt);
+
+ /* /chosen */
+ dt_start_node(dt, "chosen");
+ dt_prop_u32(dt, "linux,platform", PLATFORM_ISERIES_LPAR);
+ if (cmd_mem_limit)
+ dt_prop_u64(dt, "linux,memory-limit", cmd_mem_limit);
+ dt_end_node(dt);
+
+ dt_cpus(dt);
+
+ dt_end_node(dt);
+
+ dt_push_u32(dt, OF_DT_END);
+}
+
+void * __init iSeries_early_setup(void)
+{
+ unsigned long phys_mem_size;
+
+ iSeries_fixup_klimit();
+
+ /*
+ * Initialize the table which translate Linux physical addresses to
+ * AS/400 absolute addresses
+ */
+ phys_mem_size = build_iSeries_Memory_Map();
+
+ iSeries_get_cmdline();
+
+ /* Save unparsed command line copy for /proc/cmdline */
+ strlcpy(saved_command_line, cmd_line, COMMAND_LINE_SIZE);
+
+ /* Parse early parameters, in particular mem=x */
+ parse_early_param();
+
+ build_flat_dt(&iseries_dt, phys_mem_size);
+
+ return (void *) __pa(&iseries_dt);
}
+/*
+ * On iSeries we just parse the mem=X option from the command line.
+ * On pSeries it's a bit more complicated, see prom_init_mem()
+ */
+static int __init early_parsemem(char *p)
+{
+ if (p)
+ cmd_mem_limit = ALIGN(memparse(p, &p), PAGE_SIZE);
+ return 0;
+}
+early_param("mem", early_parsemem);
diff --git a/arch/ppc64/kernel/iSeries_setup.h b/arch/powerpc/platforms/iseries/setup.h
index c6eb29a245ac..5213044ec411 100644
--- a/arch/ppc64/kernel/iSeries_setup.h
+++ b/arch/powerpc/platforms/iseries/setup.h
@@ -2,8 +2,6 @@
* Copyright (c) 2000 Mike Corrigan <mikejc@us.ibm.com>
* Copyright (c) 1999-2000 Grant Erickson <grant@lcse.umn.edu>
*
- * Module name: as400_setup.h
- *
* Description:
* Architecture- / platform-specific boot-time initialization code for
* the IBM AS/400 LPAR. Adapted from original code by Grant Erickson and
@@ -19,7 +17,7 @@
#ifndef __ISERIES_SETUP_H__
#define __ISERIES_SETUP_H__
-extern void iSeries_get_boot_time(struct rtc_time *tm);
+extern unsigned long iSeries_get_boot_time(void);
extern int iSeries_set_rtc_time(struct rtc_time *tm);
extern void iSeries_get_rtc_time(struct rtc_time *tm);
diff --git a/arch/ppc64/kernel/iSeries_smp.c b/arch/powerpc/platforms/iseries/smp.c
index f74386e31638..fcb094ec6aec 100644
--- a/arch/ppc64/kernel/iSeries_smp.c
+++ b/arch/powerpc/platforms/iseries/smp.c
@@ -38,26 +38,25 @@
#include <asm/io.h>
#include <asm/smp.h>
#include <asm/paca.h>
-#include <asm/iSeries/HvCall.h>
+#include <asm/iseries/hv_call.h>
#include <asm/time.h>
-#include <asm/ppcdebug.h>
#include <asm/machdep.h>
#include <asm/cputable.h>
#include <asm/system.h>
static unsigned long iSeries_smp_message[NR_CPUS];
-void iSeries_smp_message_recv( struct pt_regs * regs )
+void iSeries_smp_message_recv(struct pt_regs *regs)
{
int cpu = smp_processor_id();
int msg;
- if ( num_online_cpus() < 2 )
+ if (num_online_cpus() < 2)
return;
- for ( msg = 0; msg < 4; ++msg )
- if ( test_and_clear_bit( msg, &iSeries_smp_message[cpu] ) )
- smp_message_recv( msg, regs );
+ for (msg = 0; msg < 4; msg++)
+ if (test_and_clear_bit(msg, &iSeries_smp_message[cpu]))
+ smp_message_recv(msg, regs);
}
static inline void smp_iSeries_do_message(int cpu, int msg)
@@ -74,48 +73,22 @@ static void smp_iSeries_message_pass(int target, int msg)
smp_iSeries_do_message(target, msg);
else {
for_each_online_cpu(i) {
- if (target == MSG_ALL_BUT_SELF
- && i == smp_processor_id())
+ if ((target == MSG_ALL_BUT_SELF) &&
+ (i == smp_processor_id()))
continue;
smp_iSeries_do_message(i, msg);
}
}
}
-static int smp_iSeries_numProcs(void)
-{
- unsigned np, i;
-
- np = 0;
- for (i=0; i < NR_CPUS; ++i) {
- if (paca[i].lppaca.dyn_proc_status < 2) {
- cpu_set(i, cpu_possible_map);
- cpu_set(i, cpu_present_map);
- cpu_set(i, cpu_sibling_map[i]);
- ++np;
- }
- }
- return np;
-}
-
static int smp_iSeries_probe(void)
{
- unsigned i;
- unsigned np = 0;
-
- for (i=0; i < NR_CPUS; ++i) {
- if (paca[i].lppaca.dyn_proc_status < 2) {
- /*paca[i].active = 1;*/
- ++np;
- }
- }
-
- return np;
+ return cpus_weight(cpu_possible_map);
}
static void smp_iSeries_kick_cpu(int nr)
{
- BUG_ON(nr < 0 || nr >= NR_CPUS);
+ BUG_ON((nr < 0) || (nr >= NR_CPUS));
/* Verify that our partition has a processor nr */
if (paca[nr].lppaca.dyn_proc_status >= 2)
@@ -144,6 +117,4 @@ static struct smp_ops_t iSeries_smp_ops = {
void __init smp_init_iSeries(void)
{
smp_ops = &iSeries_smp_ops;
- systemcfg->processorCount = smp_iSeries_numProcs();
}
-
diff --git a/include/asm-ppc64/iSeries/ItSpCommArea.h b/arch/powerpc/platforms/iseries/spcomm_area.h
index 5535f8271c9f..6e3b685115c9 100644
--- a/include/asm-ppc64/iSeries/ItSpCommArea.h
+++ b/arch/powerpc/platforms/iseries/spcomm_area.h
@@ -1,5 +1,4 @@
/*
- * ItSpCommArea.h
* Copyright (C) 2001 Mike Corrigan IBM Corporation
*
* This program is free software; you can redistribute it and/or modify
@@ -17,8 +16,8 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#ifndef _ITSPCOMMAREA_H
-#define _ITSPCOMMAREA_H
+#ifndef _ISERIES_SPCOMM_AREA_H
+#define _ISERIES_SPCOMM_AREA_H
struct SpCommArea {
@@ -34,4 +33,4 @@ struct SpCommArea {
extern struct SpCommArea xSpCommArea;
-#endif /* _ITSPCOMMAREA_H */
+#endif /* _ISERIES_SPCOMM_AREA_H */
diff --git a/arch/ppc64/kernel/iSeries_vio.c b/arch/powerpc/platforms/iseries/vio.c
index 6b754b0c8344..384360ee06ec 100644
--- a/arch/ppc64/kernel/iSeries_vio.c
+++ b/arch/powerpc/platforms/iseries/vio.c
@@ -14,12 +14,13 @@
#include <asm/vio.h>
#include <asm/iommu.h>
+#include <asm/tce.h>
#include <asm/abs_addr.h>
#include <asm/page.h>
-#include <asm/iSeries/vio.h>
-#include <asm/iSeries/HvTypes.h>
-#include <asm/iSeries/HvLpConfig.h>
-#include <asm/iSeries/HvCallXm.h>
+#include <asm/iseries/vio.h>
+#include <asm/iseries/hv_types.h>
+#include <asm/iseries/hv_lp_config.h>
+#include <asm/iseries/hv_call_xm.h>
struct device *iSeries_vio_dev = &vio_bus_device.dev;
EXPORT_SYMBOL(iSeries_vio_dev);
@@ -29,41 +30,14 @@ static struct iommu_table vio_iommu_table;
static void __init iommu_vio_init(void)
{
- struct iommu_table *t;
- struct iommu_table_cb cb;
- unsigned long cbp;
- unsigned long itc_entries;
+ iommu_table_getparms_iSeries(255, 0, 0xff, &veth_iommu_table);
+ veth_iommu_table.it_size /= 2;
+ vio_iommu_table = veth_iommu_table;
+ vio_iommu_table.it_offset += veth_iommu_table.it_size;
- cb.itc_busno = 255; /* Bus 255 is the virtual bus */
- cb.itc_virtbus = 0xff; /* Ask for virtual bus */
-
- cbp = virt_to_abs(&cb);
- HvCallXm_getTceTableParms(cbp);
-
- itc_entries = cb.itc_size * PAGE_SIZE / sizeof(union tce_entry);
- veth_iommu_table.it_size = itc_entries / 2;
- veth_iommu_table.it_busno = cb.itc_busno;
- veth_iommu_table.it_offset = cb.itc_offset;
- veth_iommu_table.it_index = cb.itc_index;
- veth_iommu_table.it_type = TCE_VB;
- veth_iommu_table.it_blocksize = 1;
-
- t = iommu_init_table(&veth_iommu_table);
-
- if (!t)
+ if (!iommu_init_table(&veth_iommu_table))
printk("Virtual Bus VETH TCE table failed.\n");
-
- vio_iommu_table.it_size = itc_entries - veth_iommu_table.it_size;
- vio_iommu_table.it_busno = cb.itc_busno;
- vio_iommu_table.it_offset = cb.itc_offset +
- veth_iommu_table.it_size;
- vio_iommu_table.it_index = cb.itc_index;
- vio_iommu_table.it_type = TCE_VB;
- vio_iommu_table.it_blocksize = 1;
-
- t = iommu_init_table(&vio_iommu_table);
-
- if (!t)
+ if (!iommu_init_table(&vio_iommu_table))
printk("Virtual Bus VIO TCE table failed.\n");
}
diff --git a/arch/ppc64/kernel/viopath.c b/arch/powerpc/platforms/iseries/viopath.c
index 2a6c4f01c45e..842672695598 100644
--- a/arch/ppc64/kernel/viopath.c
+++ b/arch/powerpc/platforms/iseries/viopath.c
@@ -1,5 +1,4 @@
/* -*- linux-c -*-
- * arch/ppc64/kernel/viopath.c
*
* iSeries Virtual I/O Message Path code
*
@@ -7,7 +6,7 @@
* Ryan Arnold <ryanarn@us.ibm.com>
* Colin Devilbiss <devilbis@us.ibm.com>
*
- * (C) Copyright 2000-2003 IBM Corporation
+ * (C) Copyright 2000-2005 IBM Corporation
*
* This code is used by the iSeries virtual disk, cd,
* tape, and console to communicate with OS/400 in another
@@ -42,12 +41,12 @@
#include <asm/system.h>
#include <asm/uaccess.h>
-#include <asm/iSeries/HvTypes.h>
-#include <asm/iSeries/ItExtVpdPanel.h>
-#include <asm/iSeries/HvLpEvent.h>
-#include <asm/iSeries/HvLpConfig.h>
-#include <asm/iSeries/mf.h>
-#include <asm/iSeries/vio.h>
+#include <asm/iseries/hv_types.h>
+#include <asm/iseries/it_exp_vpd_panel.h>
+#include <asm/iseries/hv_lp_event.h>
+#include <asm/iseries/hv_lp_config.h>
+#include <asm/iseries/mf.h>
+#include <asm/iseries/vio.h>
/* Status of the path to each other partition in the system.
* This is overkill, since we will only ever establish connections
@@ -69,7 +68,8 @@ static DEFINE_SPINLOCK(statuslock);
* For each kind of event we allocate a buffer that is
* guaranteed not to cross a page boundary
*/
-static unsigned char event_buffer[VIO_MAX_SUBTYPES * 256] __page_aligned;
+static unsigned char event_buffer[VIO_MAX_SUBTYPES * 256]
+ __attribute__((__aligned__(4096)));
static atomic_t event_buffer_available[VIO_MAX_SUBTYPES];
static int event_buffer_initialised;
@@ -117,12 +117,12 @@ static int proc_viopath_show(struct seq_file *m, void *v)
HvLpEvent_Rc hvrc;
DECLARE_MUTEX_LOCKED(Semaphore);
- buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
+ buf = kmalloc(HW_PAGE_SIZE, GFP_KERNEL);
if (!buf)
return 0;
- memset(buf, 0, PAGE_SIZE);
+ memset(buf, 0, HW_PAGE_SIZE);
- handle = dma_map_single(iSeries_vio_dev, buf, PAGE_SIZE,
+ handle = dma_map_single(iSeries_vio_dev, buf, HW_PAGE_SIZE,
DMA_FROM_DEVICE);
hvrc = HvCallEvent_signalLpEventFast(viopath_hostLp,
@@ -132,7 +132,7 @@ static int proc_viopath_show(struct seq_file *m, void *v)
viopath_sourceinst(viopath_hostLp),
viopath_targetinst(viopath_hostLp),
(u64)(unsigned long)&Semaphore, VIOVERSION << 16,
- ((u64)handle) << 32, PAGE_SIZE, 0, 0);
+ ((u64)handle) << 32, HW_PAGE_SIZE, 0, 0);
if (hvrc != HvLpEvent_Rc_Good)
printk(VIOPATH_KERN_WARN "hv error on op %d\n", (int)hvrc);
@@ -141,7 +141,7 @@ static int proc_viopath_show(struct seq_file *m, void *v)
vlanMap = HvLpConfig_getVirtualLanIndexMap();
- buf[PAGE_SIZE-1] = '\0';
+ buf[HW_PAGE_SIZE-1] = '\0';
seq_printf(m, "%s", buf);
seq_printf(m, "AVAILABLE_VETH=%x\n", vlanMap);
seq_printf(m, "SRLNBR=%c%c%c%c%c%c%c\n",
@@ -153,7 +153,8 @@ static int proc_viopath_show(struct seq_file *m, void *v)
e2a(xItExtVpdPanel.systemSerial[4]),
e2a(xItExtVpdPanel.systemSerial[5]));
- dma_unmap_single(iSeries_vio_dev, handle, PAGE_SIZE, DMA_FROM_DEVICE);
+ dma_unmap_single(iSeries_vio_dev, handle, HW_PAGE_SIZE,
+ DMA_FROM_DEVICE);
kfree(buf);
return 0;
diff --git a/include/asm-ppc64/iSeries/ItVpdAreas.h b/arch/powerpc/platforms/iseries/vpd_areas.h
index 71b3ad24f95a..601e6dd860ed 100644
--- a/include/asm-ppc64/iSeries/ItVpdAreas.h
+++ b/arch/powerpc/platforms/iseries/vpd_areas.h
@@ -1,5 +1,4 @@
/*
- * ItVpdAreas.h
* Copyright (C) 2001 Mike Corrigan IBM Corporation
*
* This program is free software; you can redistribute it and/or modify
@@ -16,8 +15,8 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#ifndef _ITVPDAREAS_H
-#define _ITVPDAREAS_H
+#ifndef _ISERIES_VPD_AREAS_H
+#define _ISERIES_VPD_AREAS_H
/*
* This file defines the address and length of all of the VPD area passed to
@@ -86,4 +85,4 @@ struct ItVpdAreas {
extern struct ItVpdAreas itVpdAreas;
-#endif /* _ITVPDAREAS_H */
+#endif /* _ISERIES_VPD_AREAS_H */
diff --git a/arch/ppc64/kernel/iSeries_VpdInfo.c b/arch/powerpc/platforms/iseries/vpdinfo.c
index 5d921792571f..23a6d1e5b429 100644
--- a/arch/ppc64/kernel/iSeries_VpdInfo.c
+++ b/arch/powerpc/platforms/iseries/vpdinfo.c
@@ -1,6 +1,4 @@
/*
- * File iSeries_vpdInfo.c created by Allan Trautman on Fri Feb 2 2001.
- *
* This code gets the card location of the hardware
* Copyright (C) 2001 <Allan H Trautman> <IBM Corp>
* Copyright (C) 2005 Stephen Rothwel, IBM Corp
@@ -29,12 +27,15 @@
#include <linux/init.h>
#include <linux/module.h>
#include <linux/pci.h>
+
#include <asm/types.h>
#include <asm/resource.h>
+#include <asm/abs_addr.h>
+#include <asm/pci-bridge.h>
+#include <asm/iseries/hv_types.h>
-#include <asm/iSeries/HvCallPci.h>
-#include <asm/iSeries/HvTypes.h>
-#include <asm/iSeries/iSeries_pci.h>
+#include "pci.h"
+#include "call_pci.h"
/*
* Size of Bus VPD data
@@ -214,7 +215,7 @@ static void __init iSeries_Get_Location_Code(u16 bus, HvAgentId agent,
printk("PCI: Bus VPD Buffer allocation failure.\n");
return;
}
- BusVpdLen = HvCallPci_getBusVpd(bus, ISERIES_HV_ADDR(BusVpdPtr),
+ BusVpdLen = HvCallPci_getBusVpd(bus, iseries_hv_addr(BusVpdPtr),
BUS_VPDSIZE);
if (BusVpdLen == 0) {
printk("PCI: Bus VPD Buffer zero length.\n");
@@ -242,7 +243,8 @@ out_free:
*/
void __init iSeries_Device_Information(struct pci_dev *PciDev, int count)
{
- struct iSeries_Device_Node *DevNode = PciDev->sysdata;
+ struct device_node *DevNode = PciDev->sysdata;
+ struct pci_dn *pdn;
u16 bus;
u8 frame;
char card[4];
@@ -255,8 +257,9 @@ void __init iSeries_Device_Information(struct pci_dev *PciDev, int count)
return;
}
- bus = ISERIES_BUS(DevNode);
- subbus = ISERIES_SUBBUS(DevNode);
+ pdn = PCI_DN(DevNode);
+ bus = pdn->busno;
+ subbus = pdn->bussubno;
agent = ISERIES_PCI_AGENTID(ISERIES_GET_DEVICE_FROM_SUBBUS(subbus),
ISERIES_GET_FUNCTION_FROM_SUBBUS(subbus));
iSeries_Get_Location_Code(bus, agent, &frame, card);
diff --git a/arch/powerpc/platforms/maple/Makefile b/arch/powerpc/platforms/maple/Makefile
new file mode 100644
index 000000000000..1be1a993c5f5
--- /dev/null
+++ b/arch/powerpc/platforms/maple/Makefile
@@ -0,0 +1 @@
+obj-y += setup.o pci.o time.o
diff --git a/arch/powerpc/platforms/maple/maple.h b/arch/powerpc/platforms/maple/maple.h
new file mode 100644
index 000000000000..0657c579b840
--- /dev/null
+++ b/arch/powerpc/platforms/maple/maple.h
@@ -0,0 +1,12 @@
+/*
+ * Declarations for maple-specific code.
+ *
+ * Maple is the name of a PPC970 evaluation board.
+ */
+extern int maple_set_rtc_time(struct rtc_time *tm);
+extern void maple_get_rtc_time(struct rtc_time *tm);
+extern unsigned long maple_get_boot_time(void);
+extern void maple_calibrate_decr(void);
+extern void maple_pci_init(void);
+extern void maple_pcibios_fixup(void);
+extern int maple_pci_get_legacy_ide_irq(struct pci_dev *dev, int channel);
diff --git a/arch/ppc64/kernel/maple_pci.c b/arch/powerpc/platforms/maple/pci.c
index 1d297e0edfc0..895aeb3f75d0 100644
--- a/arch/ppc64/kernel/maple_pci.c
+++ b/arch/powerpc/platforms/maple/pci.c
@@ -23,8 +23,9 @@
#include <asm/pci-bridge.h>
#include <asm/machdep.h>
#include <asm/iommu.h>
+#include <asm/ppc-pci.h>
-#include "pci.h"
+#include "maple.h"
#ifdef DEBUG
#define DBG(x...) printk(x)
@@ -276,7 +277,7 @@ static void __init setup_u3_agp(struct pci_controller* hose)
{
/* On G5, we move AGP up to high bus number so we don't need
* to reassign bus numbers for HT. If we ever have P2P bridges
- * on AGP, we'll have to move pci_assign_all_busses to the
+ * on AGP, we'll have to move pci_assign_all_buses to the
* pci_controller structure so we enable it for AGP and not for
* HT childs.
* We hard code the address because of the different size of
@@ -360,7 +361,7 @@ static int __init add_bridge(struct device_node *dev)
/* Interpret the "ranges" property */
/* This also maps the I/O region and sets isa_io/mem_base */
- pci_process_bridge_OF_ranges(hose, dev);
+ pci_process_bridge_OF_ranges(hose, dev, primary);
pci_setup_phb_io(hose, primary);
/* Fixup "bus-range" OF property */
@@ -379,9 +380,6 @@ void __init maple_pcibios_fixup(void)
for_each_pci_dev(dev)
pci_read_irq_line(dev);
- /* Do the mapping of the IO space */
- phbs_remap_io();
-
DBG(" <- maple_pcibios_fixup\n");
}
diff --git a/arch/ppc64/kernel/maple_setup.c b/arch/powerpc/platforms/maple/setup.c
index fc0567498a3a..7ece8983a105 100644
--- a/arch/ppc64/kernel/maple_setup.c
+++ b/arch/powerpc/platforms/maple/setup.c
@@ -1,5 +1,5 @@
/*
- * arch/ppc64/kernel/maple_setup.c
+ * Maple (970 eval board) setup code
*
* (c) Copyright 2004 Benjamin Herrenschmidt (benh@kernel.crashing.org),
* IBM Corp.
@@ -59,8 +59,10 @@
#include <asm/time.h>
#include <asm/of_device.h>
#include <asm/lmb.h>
+#include <asm/mpic.h>
+#include <asm/udbg.h>
-#include "mpic.h"
+#include "maple.h"
#ifdef DEBUG
#define DBG(fmt...) udbg_printf(fmt)
@@ -68,13 +70,6 @@
#define DBG(fmt...)
#endif
-extern int maple_set_rtc_time(struct rtc_time *tm);
-extern void maple_get_rtc_time(struct rtc_time *tm);
-extern void maple_get_boot_time(struct rtc_time *tm);
-extern void maple_calibrate_decr(void);
-extern void maple_pci_init(void);
-extern void maple_pcibios_fixup(void);
-extern int maple_pci_get_legacy_ide_irq(struct pci_dev *dev, int channel);
extern void generic_find_legacy_serial_ports(u64 *physport,
unsigned int *default_speed);
diff --git a/arch/ppc64/kernel/maple_time.c b/arch/powerpc/platforms/maple/time.c
index d65210abcd03..40fc07a8e606 100644
--- a/arch/ppc64/kernel/maple_time.c
+++ b/arch/powerpc/platforms/maple/time.c
@@ -36,6 +36,8 @@
#include <asm/machdep.h>
#include <asm/time.h>
+#include "maple.h"
+
#ifdef DEBUG
#define DBG(x...) printk(x)
#else
@@ -156,8 +158,9 @@ int maple_set_rtc_time(struct rtc_time *tm)
return 0;
}
-void __init maple_get_boot_time(struct rtc_time *tm)
+unsigned long __init maple_get_boot_time(void)
{
+ struct rtc_time tm;
struct device_node *rtcs;
rtcs = find_compatible_devices("rtc", "pnpPNP,b00");
@@ -170,6 +173,8 @@ void __init maple_get_boot_time(struct rtc_time *tm)
"legacy address (0x%x)\n", maple_rtc_addr);
}
- maple_get_rtc_time(tm);
+ maple_get_rtc_time(&tm);
+ return mktime(tm.tm_year+1900, tm.tm_mon+1, tm.tm_mday,
+ tm.tm_hour, tm.tm_min, tm.tm_sec);
}
diff --git a/arch/powerpc/platforms/powermac/Makefile b/arch/powerpc/platforms/powermac/Makefile
new file mode 100644
index 000000000000..c9df44fcf571
--- /dev/null
+++ b/arch/powerpc/platforms/powermac/Makefile
@@ -0,0 +1,9 @@
+obj-y += pic.o setup.o time.o feature.o pci.o \
+ sleep.o low_i2c.o cache.o
+obj-$(CONFIG_PMAC_BACKLIGHT) += backlight.o
+obj-$(CONFIG_CPU_FREQ_PMAC) += cpufreq_32.o
+obj-$(CONFIG_CPU_FREQ_PMAC64) += cpufreq_64.o
+obj-$(CONFIG_NVRAM) += nvram.o
+# ppc64 pmac doesn't define CONFIG_NVRAM but needs nvram stuff
+obj-$(CONFIG_PPC64) += nvram.o
+obj-$(CONFIG_SMP) += smp.o
diff --git a/arch/powerpc/platforms/powermac/backlight.c b/arch/powerpc/platforms/powermac/backlight.c
new file mode 100644
index 000000000000..8be2f7d071f0
--- /dev/null
+++ b/arch/powerpc/platforms/powermac/backlight.c
@@ -0,0 +1,202 @@
+/*
+ * Miscellaneous procedures for dealing with the PowerMac hardware.
+ * Contains support for the backlight.
+ *
+ * Copyright (C) 2000 Benjamin Herrenschmidt
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/stddef.h>
+#include <linux/reboot.h>
+#include <linux/nvram.h>
+#include <linux/console.h>
+#include <asm/sections.h>
+#include <asm/ptrace.h>
+#include <asm/io.h>
+#include <asm/pgtable.h>
+#include <asm/system.h>
+#include <asm/prom.h>
+#include <asm/machdep.h>
+#include <asm/nvram.h>
+#include <asm/backlight.h>
+
+#include <linux/adb.h>
+#include <linux/pmu.h>
+
+static struct backlight_controller *backlighter;
+static void* backlighter_data;
+static int backlight_autosave;
+static int backlight_level = BACKLIGHT_MAX;
+static int backlight_enabled = 1;
+static int backlight_req_level = -1;
+static int backlight_req_enable = -1;
+
+static void backlight_callback(void *);
+static DECLARE_WORK(backlight_work, backlight_callback, NULL);
+
+void register_backlight_controller(struct backlight_controller *ctrler,
+ void *data, char *type)
+{
+ struct device_node* bk_node;
+ char *prop;
+ int valid = 0;
+
+ /* There's already a matching controller, bail out */
+ if (backlighter != NULL)
+ return;
+
+ bk_node = find_devices("backlight");
+
+#ifdef CONFIG_ADB_PMU
+ /* Special case for the old PowerBook since I can't test on it */
+ backlight_autosave = machine_is_compatible("AAPL,3400/2400")
+ || machine_is_compatible("AAPL,3500");
+ if ((backlight_autosave
+ || machine_is_compatible("AAPL,PowerBook1998")
+ || machine_is_compatible("PowerBook1,1"))
+ && !strcmp(type, "pmu"))
+ valid = 1;
+#endif
+ if (bk_node) {
+ prop = get_property(bk_node, "backlight-control", NULL);
+ if (prop && !strncmp(prop, type, strlen(type)))
+ valid = 1;
+ }
+ if (!valid)
+ return;
+ backlighter = ctrler;
+ backlighter_data = data;
+
+ if (bk_node && !backlight_autosave)
+ prop = get_property(bk_node, "bklt", NULL);
+ else
+ prop = NULL;
+ if (prop) {
+ backlight_level = ((*prop)+1) >> 1;
+ if (backlight_level > BACKLIGHT_MAX)
+ backlight_level = BACKLIGHT_MAX;
+ }
+
+#ifdef CONFIG_ADB_PMU
+ if (backlight_autosave) {
+ struct adb_request req;
+ pmu_request(&req, NULL, 2, 0xd9, 0);
+ while (!req.complete)
+ pmu_poll();
+ backlight_level = req.reply[0] >> 4;
+ }
+#endif
+ acquire_console_sem();
+ if (!backlighter->set_enable(1, backlight_level, data))
+ backlight_enabled = 1;
+ release_console_sem();
+
+ printk(KERN_INFO "Registered \"%s\" backlight controller,"
+ "level: %d/15\n", type, backlight_level);
+}
+EXPORT_SYMBOL(register_backlight_controller);
+
+void unregister_backlight_controller(struct backlight_controller
+ *ctrler, void *data)
+{
+ /* We keep the current backlight level (for now) */
+ if (ctrler == backlighter && data == backlighter_data)
+ backlighter = NULL;
+}
+EXPORT_SYMBOL(unregister_backlight_controller);
+
+static int __set_backlight_enable(int enable)
+{
+ int rc;
+
+ if (!backlighter)
+ return -ENODEV;
+ acquire_console_sem();
+ rc = backlighter->set_enable(enable, backlight_level,
+ backlighter_data);
+ if (!rc)
+ backlight_enabled = enable;
+ release_console_sem();
+ return rc;
+}
+int set_backlight_enable(int enable)
+{
+ if (!backlighter)
+ return -ENODEV;
+ backlight_req_enable = enable;
+ schedule_work(&backlight_work);
+ return 0;
+}
+
+EXPORT_SYMBOL(set_backlight_enable);
+
+int get_backlight_enable(void)
+{
+ if (!backlighter)
+ return -ENODEV;
+ return backlight_enabled;
+}
+EXPORT_SYMBOL(get_backlight_enable);
+
+static int __set_backlight_level(int level)
+{
+ int rc = 0;
+
+ if (!backlighter)
+ return -ENODEV;
+ if (level < BACKLIGHT_MIN)
+ level = BACKLIGHT_OFF;
+ if (level > BACKLIGHT_MAX)
+ level = BACKLIGHT_MAX;
+ acquire_console_sem();
+ if (backlight_enabled)
+ rc = backlighter->set_level(level, backlighter_data);
+ if (!rc)
+ backlight_level = level;
+ release_console_sem();
+ if (!rc && !backlight_autosave) {
+ level <<=1;
+ if (level & 0x10)
+ level |= 0x01;
+ // -- todo: save to property "bklt"
+ }
+ return rc;
+}
+int set_backlight_level(int level)
+{
+ if (!backlighter)
+ return -ENODEV;
+ backlight_req_level = level;
+ schedule_work(&backlight_work);
+ return 0;
+}
+
+EXPORT_SYMBOL(set_backlight_level);
+
+int get_backlight_level(void)
+{
+ if (!backlighter)
+ return -ENODEV;
+ return backlight_level;
+}
+EXPORT_SYMBOL(get_backlight_level);
+
+static void backlight_callback(void *dummy)
+{
+ int level, enable;
+
+ do {
+ level = backlight_req_level;
+ enable = backlight_req_enable;
+ mb();
+
+ if (level >= 0)
+ __set_backlight_level(level);
+ if (enable >= 0)
+ __set_backlight_enable(enable);
+ } while(cmpxchg(&backlight_req_level, level, -1) != level ||
+ cmpxchg(&backlight_req_enable, enable, -1) != enable);
+}
diff --git a/arch/powerpc/platforms/powermac/cache.S b/arch/powerpc/platforms/powermac/cache.S
new file mode 100644
index 000000000000..fb977de6b704
--- /dev/null
+++ b/arch/powerpc/platforms/powermac/cache.S
@@ -0,0 +1,359 @@
+/*
+ * This file contains low-level cache management functions
+ * used for sleep and CPU speed changes on Apple machines.
+ * (In fact the only thing that is Apple-specific is that we assume
+ * that we can read from ROM at physical address 0xfff00000.)
+ *
+ * Copyright (C) 2004 Paul Mackerras (paulus@samba.org) and
+ * Benjamin Herrenschmidt (benh@kernel.crashing.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/config.h>
+#include <asm/processor.h>
+#include <asm/ppc_asm.h>
+#include <asm/cputable.h>
+
+/*
+ * Flush and disable all data caches (dL1, L2, L3). This is used
+ * when going to sleep, when doing a PMU based cpufreq transition,
+ * or when "offlining" a CPU on SMP machines. This code is over
+ * paranoid, but I've had enough issues with various CPU revs and
+ * bugs that I decided it was worth beeing over cautious
+ */
+
+_GLOBAL(flush_disable_caches)
+#ifndef CONFIG_6xx
+ blr
+#else
+BEGIN_FTR_SECTION
+ b flush_disable_745x
+END_FTR_SECTION_IFSET(CPU_FTR_SPEC7450)
+BEGIN_FTR_SECTION
+ b flush_disable_75x
+END_FTR_SECTION_IFSET(CPU_FTR_L2CR)
+ b __flush_disable_L1
+
+/* This is the code for G3 and 74[01]0 */
+flush_disable_75x:
+ mflr r10
+
+ /* Turn off EE and DR in MSR */
+ mfmsr r11
+ rlwinm r0,r11,0,~MSR_EE
+ rlwinm r0,r0,0,~MSR_DR
+ sync
+ mtmsr r0
+ isync
+
+ /* Stop DST streams */
+BEGIN_FTR_SECTION
+ DSSALL
+ sync
+END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
+
+ /* Stop DPM */
+ mfspr r8,SPRN_HID0 /* Save SPRN_HID0 in r8 */
+ rlwinm r4,r8,0,12,10 /* Turn off HID0[DPM] */
+ sync
+ mtspr SPRN_HID0,r4 /* Disable DPM */
+ sync
+
+ /* Disp-flush L1. We have a weird problem here that I never
+ * totally figured out. On 750FX, using the ROM for the flush
+ * results in a non-working flush. We use that workaround for
+ * now until I finally understand what's going on. --BenH
+ */
+
+ /* ROM base by default */
+ lis r4,0xfff0
+ mfpvr r3
+ srwi r3,r3,16
+ cmplwi cr0,r3,0x7000
+ bne+ 1f
+ /* RAM base on 750FX */
+ li r4,0
+1: li r4,0x4000
+ mtctr r4
+1: lwz r0,0(r4)
+ addi r4,r4,32
+ bdnz 1b
+ sync
+ isync
+
+ /* Disable / invalidate / enable L1 data */
+ mfspr r3,SPRN_HID0
+ rlwinm r3,r3,0,~(HID0_DCE | HID0_ICE)
+ mtspr SPRN_HID0,r3
+ sync
+ isync
+ ori r3,r3,(HID0_DCE|HID0_DCI|HID0_ICE|HID0_ICFI)
+ sync
+ isync
+ mtspr SPRN_HID0,r3
+ xori r3,r3,(HID0_DCI|HID0_ICFI)
+ mtspr SPRN_HID0,r3
+ sync
+
+ /* Get the current enable bit of the L2CR into r4 */
+ mfspr r5,SPRN_L2CR
+ /* Set to data-only (pre-745x bit) */
+ oris r3,r5,L2CR_L2DO@h
+ b 2f
+ /* When disabling L2, code must be in L1 */
+ .balign 32
+1: mtspr SPRN_L2CR,r3
+3: sync
+ isync
+ b 1f
+2: b 3f
+3: sync
+ isync
+ b 1b
+1: /* disp-flush L2. The interesting thing here is that the L2 can be
+ * up to 2Mb ... so using the ROM, we'll end up wrapping back to memory
+ * but that is probbaly fine. We disp-flush over 4Mb to be safe
+ */
+ lis r4,2
+ mtctr r4
+ lis r4,0xfff0
+1: lwz r0,0(r4)
+ addi r4,r4,32
+ bdnz 1b
+ sync
+ isync
+ lis r4,2
+ mtctr r4
+ lis r4,0xfff0
+1: dcbf 0,r4
+ addi r4,r4,32
+ bdnz 1b
+ sync
+ isync
+
+ /* now disable L2 */
+ rlwinm r5,r5,0,~L2CR_L2E
+ b 2f
+ /* When disabling L2, code must be in L1 */
+ .balign 32
+1: mtspr SPRN_L2CR,r5
+3: sync
+ isync
+ b 1f
+2: b 3f
+3: sync
+ isync
+ b 1b
+1: sync
+ isync
+ /* Invalidate L2. This is pre-745x, we clear the L2I bit ourselves */
+ oris r4,r5,L2CR_L2I@h
+ mtspr SPRN_L2CR,r4
+ sync
+ isync
+
+ /* Wait for the invalidation to complete */
+1: mfspr r3,SPRN_L2CR
+ rlwinm. r0,r3,0,31,31
+ bne 1b
+
+ /* Clear L2I */
+ xoris r4,r4,L2CR_L2I@h
+ sync
+ mtspr SPRN_L2CR,r4
+ sync
+
+ /* now disable the L1 data cache */
+ mfspr r0,SPRN_HID0
+ rlwinm r0,r0,0,~(HID0_DCE|HID0_ICE)
+ mtspr SPRN_HID0,r0
+ sync
+ isync
+
+ /* Restore HID0[DPM] to whatever it was before */
+ sync
+ mfspr r0,SPRN_HID0
+ rlwimi r0,r8,0,11,11 /* Turn back HID0[DPM] */
+ mtspr SPRN_HID0,r0
+ sync
+
+ /* restore DR and EE */
+ sync
+ mtmsr r11
+ isync
+
+ mtlr r10
+ blr
+
+/* This code is for 745x processors */
+flush_disable_745x:
+ /* Turn off EE and DR in MSR */
+ mfmsr r11
+ rlwinm r0,r11,0,~MSR_EE
+ rlwinm r0,r0,0,~MSR_DR
+ sync
+ mtmsr r0
+ isync
+
+ /* Stop prefetch streams */
+ DSSALL
+ sync
+
+ /* Disable L2 prefetching */
+ mfspr r0,SPRN_MSSCR0
+ rlwinm r0,r0,0,0,29
+ mtspr SPRN_MSSCR0,r0
+ sync
+ isync
+ lis r4,0
+ dcbf 0,r4
+ dcbf 0,r4
+ dcbf 0,r4
+ dcbf 0,r4
+ dcbf 0,r4
+ dcbf 0,r4
+ dcbf 0,r4
+ dcbf 0,r4
+
+ /* Due to a bug with the HW flush on some CPU revs, we occasionally
+ * experience data corruption. I'm adding a displacement flush along
+ * with a dcbf loop over a few Mb to "help". The problem isn't totally
+ * fixed by this in theory, but at least, in practice, I couldn't reproduce
+ * it even with a big hammer...
+ */
+
+ lis r4,0x0002
+ mtctr r4
+ li r4,0
+1:
+ lwz r0,0(r4)
+ addi r4,r4,32 /* Go to start of next cache line */
+ bdnz 1b
+ isync
+
+ /* Now, flush the first 4MB of memory */
+ lis r4,0x0002
+ mtctr r4
+ li r4,0
+ sync
+1:
+ dcbf 0,r4
+ addi r4,r4,32 /* Go to start of next cache line */
+ bdnz 1b
+
+ /* Flush and disable the L1 data cache */
+ mfspr r6,SPRN_LDSTCR
+ lis r3,0xfff0 /* read from ROM for displacement flush */
+ li r4,0xfe /* start with only way 0 unlocked */
+ li r5,128 /* 128 lines in each way */
+1: mtctr r5
+ rlwimi r6,r4,0,24,31
+ mtspr SPRN_LDSTCR,r6
+ sync
+ isync
+2: lwz r0,0(r3) /* touch each cache line */
+ addi r3,r3,32
+ bdnz 2b
+ rlwinm r4,r4,1,24,30 /* move on to the next way */
+ ori r4,r4,1
+ cmpwi r4,0xff /* all done? */
+ bne 1b
+ /* now unlock the L1 data cache */
+ li r4,0
+ rlwimi r6,r4,0,24,31
+ sync
+ mtspr SPRN_LDSTCR,r6
+ sync
+ isync
+
+ /* Flush the L2 cache using the hardware assist */
+ mfspr r3,SPRN_L2CR
+ cmpwi r3,0 /* check if it is enabled first */
+ bge 4f
+ oris r0,r3,(L2CR_L2IO_745x|L2CR_L2DO_745x)@h
+ b 2f
+ /* When disabling/locking L2, code must be in L1 */
+ .balign 32
+1: mtspr SPRN_L2CR,r0 /* lock the L2 cache */
+3: sync
+ isync
+ b 1f
+2: b 3f
+3: sync
+ isync
+ b 1b
+1: sync
+ isync
+ ori r0,r3,L2CR_L2HWF_745x
+ sync
+ mtspr SPRN_L2CR,r0 /* set the hardware flush bit */
+3: mfspr r0,SPRN_L2CR /* wait for it to go to 0 */
+ andi. r0,r0,L2CR_L2HWF_745x
+ bne 3b
+ sync
+ rlwinm r3,r3,0,~L2CR_L2E
+ b 2f
+ /* When disabling L2, code must be in L1 */
+ .balign 32
+1: mtspr SPRN_L2CR,r3 /* disable the L2 cache */
+3: sync
+ isync
+ b 1f
+2: b 3f
+3: sync
+ isync
+ b 1b
+1: sync
+ isync
+ oris r4,r3,L2CR_L2I@h
+ mtspr SPRN_L2CR,r4
+ sync
+ isync
+1: mfspr r4,SPRN_L2CR
+ andis. r0,r4,L2CR_L2I@h
+ bne 1b
+ sync
+
+BEGIN_FTR_SECTION
+ /* Flush the L3 cache using the hardware assist */
+4: mfspr r3,SPRN_L3CR
+ cmpwi r3,0 /* check if it is enabled */
+ bge 6f
+ oris r0,r3,L3CR_L3IO@h
+ ori r0,r0,L3CR_L3DO
+ sync
+ mtspr SPRN_L3CR,r0 /* lock the L3 cache */
+ sync
+ isync
+ ori r0,r0,L3CR_L3HWF
+ sync
+ mtspr SPRN_L3CR,r0 /* set the hardware flush bit */
+5: mfspr r0,SPRN_L3CR /* wait for it to go to zero */
+ andi. r0,r0,L3CR_L3HWF
+ bne 5b
+ rlwinm r3,r3,0,~L3CR_L3E
+ sync
+ mtspr SPRN_L3CR,r3 /* disable the L3 cache */
+ sync
+ ori r4,r3,L3CR_L3I
+ mtspr SPRN_L3CR,r4
+1: mfspr r4,SPRN_L3CR
+ andi. r0,r4,L3CR_L3I
+ bne 1b
+ sync
+END_FTR_SECTION_IFSET(CPU_FTR_L3CR)
+
+6: mfspr r0,SPRN_HID0 /* now disable the L1 data cache */
+ rlwinm r0,r0,0,~HID0_DCE
+ mtspr SPRN_HID0,r0
+ sync
+ isync
+ mtmsr r11 /* restore DR and EE */
+ isync
+ blr
+#endif /* CONFIG_6xx */
diff --git a/arch/powerpc/platforms/powermac/cpufreq_32.c b/arch/powerpc/platforms/powermac/cpufreq_32.c
new file mode 100644
index 000000000000..56fd4e05fede
--- /dev/null
+++ b/arch/powerpc/platforms/powermac/cpufreq_32.c
@@ -0,0 +1,727 @@
+/*
+ * arch/ppc/platforms/pmac_cpufreq.c
+ *
+ * Copyright (C) 2002 - 2005 Benjamin Herrenschmidt <benh@kernel.crashing.org>
+ * Copyright (C) 2004 John Steele Scott <toojays@toojays.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.
+ *
+ * TODO: Need a big cleanup here. Basically, we need to have different
+ * cpufreq_driver structures for the different type of HW instead of the
+ * current mess. We also need to better deal with the detection of the
+ * type of machine.
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/sched.h>
+#include <linux/adb.h>
+#include <linux/pmu.h>
+#include <linux/slab.h>
+#include <linux/cpufreq.h>
+#include <linux/init.h>
+#include <linux/sysdev.h>
+#include <linux/i2c.h>
+#include <linux/hardirq.h>
+#include <asm/prom.h>
+#include <asm/machdep.h>
+#include <asm/irq.h>
+#include <asm/pmac_feature.h>
+#include <asm/mmu_context.h>
+#include <asm/sections.h>
+#include <asm/cputable.h>
+#include <asm/time.h>
+#include <asm/system.h>
+#include <asm/mpic.h>
+#include <asm/keylargo.h>
+
+/* WARNING !!! This will cause calibrate_delay() to be called,
+ * but this is an __init function ! So you MUST go edit
+ * init/main.c to make it non-init before enabling DEBUG_FREQ
+ */
+#undef DEBUG_FREQ
+
+/*
+ * There is a problem with the core cpufreq code on SMP kernels,
+ * it won't recalculate the Bogomips properly
+ */
+#ifdef CONFIG_SMP
+#warning "WARNING, CPUFREQ not recommended on SMP kernels"
+#endif
+
+extern void low_choose_7447a_dfs(int dfs);
+extern void low_choose_750fx_pll(int pll);
+extern void low_sleep_handler(void);
+
+/*
+ * Currently, PowerMac cpufreq supports only high & low frequencies
+ * that are set by the firmware
+ */
+static unsigned int low_freq;
+static unsigned int hi_freq;
+static unsigned int cur_freq;
+static unsigned int sleep_freq;
+
+/*
+ * Different models uses different mecanisms to switch the frequency
+ */
+static int (*set_speed_proc)(int low_speed);
+static unsigned int (*get_speed_proc)(void);
+
+/*
+ * Some definitions used by the various speedprocs
+ */
+static u32 voltage_gpio;
+static u32 frequency_gpio;
+static u32 slew_done_gpio;
+static int no_schedule;
+static int has_cpu_l2lve;
+static int is_pmu_based;
+
+/* There are only two frequency states for each processor. Values
+ * are in kHz for the time being.
+ */
+#define CPUFREQ_HIGH 0
+#define CPUFREQ_LOW 1
+
+static struct cpufreq_frequency_table pmac_cpu_freqs[] = {
+ {CPUFREQ_HIGH, 0},
+ {CPUFREQ_LOW, 0},
+ {0, CPUFREQ_TABLE_END},
+};
+
+static struct freq_attr* pmac_cpu_freqs_attr[] = {
+ &cpufreq_freq_attr_scaling_available_freqs,
+ NULL,
+};
+
+static inline void local_delay(unsigned long ms)
+{
+ if (no_schedule)
+ mdelay(ms);
+ else
+ msleep(ms);
+}
+
+#ifdef DEBUG_FREQ
+static inline void debug_calc_bogomips(void)
+{
+ /* This will cause a recalc of bogomips and display the
+ * result. We backup/restore the value to avoid affecting the
+ * core cpufreq framework's own calculation.
+ */
+ extern void calibrate_delay(void);
+
+ unsigned long save_lpj = loops_per_jiffy;
+ calibrate_delay();
+ loops_per_jiffy = save_lpj;
+}
+#endif /* DEBUG_FREQ */
+
+/* Switch CPU speed under 750FX CPU control
+ */
+static int cpu_750fx_cpu_speed(int low_speed)
+{
+ u32 hid2;
+
+ if (low_speed == 0) {
+ /* ramping up, set voltage first */
+ pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, voltage_gpio, 0x05);
+ /* Make sure we sleep for at least 1ms */
+ local_delay(10);
+
+ /* tweak L2 for high voltage */
+ if (has_cpu_l2lve) {
+ hid2 = mfspr(SPRN_HID2);
+ hid2 &= ~0x2000;
+ mtspr(SPRN_HID2, hid2);
+ }
+ }
+#ifdef CONFIG_6xx
+ low_choose_750fx_pll(low_speed);
+#endif
+ if (low_speed == 1) {
+ /* tweak L2 for low voltage */
+ if (has_cpu_l2lve) {
+ hid2 = mfspr(SPRN_HID2);
+ hid2 |= 0x2000;
+ mtspr(SPRN_HID2, hid2);
+ }
+
+ /* ramping down, set voltage last */
+ pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, voltage_gpio, 0x04);
+ local_delay(10);
+ }
+
+ return 0;
+}
+
+static unsigned int cpu_750fx_get_cpu_speed(void)
+{
+ if (mfspr(SPRN_HID1) & HID1_PS)
+ return low_freq;
+ else
+ return hi_freq;
+}
+
+/* Switch CPU speed using DFS */
+static int dfs_set_cpu_speed(int low_speed)
+{
+ if (low_speed == 0) {
+ /* ramping up, set voltage first */
+ pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, voltage_gpio, 0x05);
+ /* Make sure we sleep for at least 1ms */
+ local_delay(1);
+ }
+
+ /* set frequency */
+#ifdef CONFIG_6xx
+ low_choose_7447a_dfs(low_speed);
+#endif
+ udelay(100);
+
+ if (low_speed == 1) {
+ /* ramping down, set voltage last */
+ pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, voltage_gpio, 0x04);
+ local_delay(1);
+ }
+
+ return 0;
+}
+
+static unsigned int dfs_get_cpu_speed(void)
+{
+ if (mfspr(SPRN_HID1) & HID1_DFS)
+ return low_freq;
+ else
+ return hi_freq;
+}
+
+
+/* Switch CPU speed using slewing GPIOs
+ */
+static int gpios_set_cpu_speed(int low_speed)
+{
+ int gpio, timeout = 0;
+
+ /* If ramping up, set voltage first */
+ if (low_speed == 0) {
+ pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, voltage_gpio, 0x05);
+ /* Delay is way too big but it's ok, we schedule */
+ local_delay(10);
+ }
+
+ /* Set frequency */
+ gpio = pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, frequency_gpio, 0);
+ if (low_speed == ((gpio & 0x01) == 0))
+ goto skip;
+
+ pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, frequency_gpio,
+ low_speed ? 0x04 : 0x05);
+ udelay(200);
+ do {
+ if (++timeout > 100)
+ break;
+ local_delay(1);
+ gpio = pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, slew_done_gpio, 0);
+ } while((gpio & 0x02) == 0);
+ skip:
+ /* If ramping down, set voltage last */
+ if (low_speed == 1) {
+ pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, voltage_gpio, 0x04);
+ /* Delay is way too big but it's ok, we schedule */
+ local_delay(10);
+ }
+
+#ifdef DEBUG_FREQ
+ debug_calc_bogomips();
+#endif
+
+ return 0;
+}
+
+/* Switch CPU speed under PMU control
+ */
+static int pmu_set_cpu_speed(int low_speed)
+{
+ struct adb_request req;
+ unsigned long save_l2cr;
+ unsigned long save_l3cr;
+ unsigned int pic_prio;
+ unsigned long flags;
+
+ preempt_disable();
+
+#ifdef DEBUG_FREQ
+ printk(KERN_DEBUG "HID1, before: %x\n", mfspr(SPRN_HID1));
+#endif
+ pmu_suspend();
+
+ /* Disable all interrupt sources on openpic */
+ pic_prio = mpic_cpu_get_priority();
+ mpic_cpu_set_priority(0xf);
+
+ /* Make sure the decrementer won't interrupt us */
+ asm volatile("mtdec %0" : : "r" (0x7fffffff));
+ /* Make sure any pending DEC interrupt occuring while we did
+ * the above didn't re-enable the DEC */
+ mb();
+ asm volatile("mtdec %0" : : "r" (0x7fffffff));
+
+ /* We can now disable MSR_EE */
+ local_irq_save(flags);
+
+ /* Giveup the FPU & vec */
+ enable_kernel_fp();
+
+#ifdef CONFIG_ALTIVEC
+ if (cpu_has_feature(CPU_FTR_ALTIVEC))
+ enable_kernel_altivec();
+#endif /* CONFIG_ALTIVEC */
+
+ /* Save & disable L2 and L3 caches */
+ save_l3cr = _get_L3CR(); /* (returns -1 if not available) */
+ save_l2cr = _get_L2CR(); /* (returns -1 if not available) */
+
+ /* Send the new speed command. My assumption is that this command
+ * will cause PLL_CFG[0..3] to be changed next time CPU goes to sleep
+ */
+ pmu_request(&req, NULL, 6, PMU_CPU_SPEED, 'W', 'O', 'O', 'F', low_speed);
+ while (!req.complete)
+ pmu_poll();
+
+ /* Prepare the northbridge for the speed transition */
+ pmac_call_feature(PMAC_FTR_SLEEP_STATE,NULL,1,1);
+
+ /* Call low level code to backup CPU state and recover from
+ * hardware reset
+ */
+ low_sleep_handler();
+
+ /* Restore the northbridge */
+ pmac_call_feature(PMAC_FTR_SLEEP_STATE,NULL,1,0);
+
+ /* Restore L2 cache */
+ if (save_l2cr != 0xffffffff && (save_l2cr & L2CR_L2E) != 0)
+ _set_L2CR(save_l2cr);
+ /* Restore L3 cache */
+ if (save_l3cr != 0xffffffff && (save_l3cr & L3CR_L3E) != 0)
+ _set_L3CR(save_l3cr);
+
+ /* Restore userland MMU context */
+ set_context(current->active_mm->context, current->active_mm->pgd);
+
+#ifdef DEBUG_FREQ
+ printk(KERN_DEBUG "HID1, after: %x\n", mfspr(SPRN_HID1));
+#endif
+
+ /* Restore low level PMU operations */
+ pmu_unlock();
+
+ /* Restore decrementer */
+ wakeup_decrementer();
+
+ /* Restore interrupts */
+ mpic_cpu_set_priority(pic_prio);
+
+ /* Let interrupts flow again ... */
+ local_irq_restore(flags);
+
+#ifdef DEBUG_FREQ
+ debug_calc_bogomips();
+#endif
+
+ pmu_resume();
+
+ preempt_enable();
+
+ return 0;
+}
+
+static int do_set_cpu_speed(int speed_mode, int notify)
+{
+ struct cpufreq_freqs freqs;
+ unsigned long l3cr;
+ static unsigned long prev_l3cr;
+
+ freqs.old = cur_freq;
+ freqs.new = (speed_mode == CPUFREQ_HIGH) ? hi_freq : low_freq;
+ freqs.cpu = smp_processor_id();
+
+ if (freqs.old == freqs.new)
+ return 0;
+
+ if (notify)
+ cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+ if (speed_mode == CPUFREQ_LOW &&
+ cpu_has_feature(CPU_FTR_L3CR)) {
+ l3cr = _get_L3CR();
+ if (l3cr & L3CR_L3E) {
+ prev_l3cr = l3cr;
+ _set_L3CR(0);
+ }
+ }
+ set_speed_proc(speed_mode == CPUFREQ_LOW);
+ if (speed_mode == CPUFREQ_HIGH &&
+ cpu_has_feature(CPU_FTR_L3CR)) {
+ l3cr = _get_L3CR();
+ if ((prev_l3cr & L3CR_L3E) && l3cr != prev_l3cr)
+ _set_L3CR(prev_l3cr);
+ }
+ if (notify)
+ cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+ cur_freq = (speed_mode == CPUFREQ_HIGH) ? hi_freq : low_freq;
+
+ return 0;
+}
+
+static unsigned int pmac_cpufreq_get_speed(unsigned int cpu)
+{
+ return cur_freq;
+}
+
+static int pmac_cpufreq_verify(struct cpufreq_policy *policy)
+{
+ return cpufreq_frequency_table_verify(policy, pmac_cpu_freqs);
+}
+
+static int pmac_cpufreq_target( struct cpufreq_policy *policy,
+ unsigned int target_freq,
+ unsigned int relation)
+{
+ unsigned int newstate = 0;
+ int rc;
+
+ if (cpufreq_frequency_table_target(policy, pmac_cpu_freqs,
+ target_freq, relation, &newstate))
+ return -EINVAL;
+
+ rc = do_set_cpu_speed(newstate, 1);
+
+ ppc_proc_freq = cur_freq * 1000ul;
+ return rc;
+}
+
+static int pmac_cpufreq_cpu_init(struct cpufreq_policy *policy)
+{
+ if (policy->cpu != 0)
+ return -ENODEV;
+
+ policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
+ policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
+ policy->cur = cur_freq;
+
+ cpufreq_frequency_table_get_attr(pmac_cpu_freqs, policy->cpu);
+ return cpufreq_frequency_table_cpuinfo(policy, pmac_cpu_freqs);
+}
+
+static u32 read_gpio(struct device_node *np)
+{
+ u32 *reg = (u32 *)get_property(np, "reg", NULL);
+ u32 offset;
+
+ if (reg == NULL)
+ return 0;
+ /* That works for all keylargos but shall be fixed properly
+ * some day... The problem is that it seems we can't rely
+ * on the "reg" property of the GPIO nodes, they are either
+ * relative to the base of KeyLargo or to the base of the
+ * GPIO space, and the device-tree doesn't help.
+ */
+ offset = *reg;
+ if (offset < KEYLARGO_GPIO_LEVELS0)
+ offset += KEYLARGO_GPIO_LEVELS0;
+ return offset;
+}
+
+static int pmac_cpufreq_suspend(struct cpufreq_policy *policy, pm_message_t pmsg)
+{
+ /* Ok, this could be made a bit smarter, but let's be robust for now. We
+ * always force a speed change to high speed before sleep, to make sure
+ * we have appropriate voltage and/or bus speed for the wakeup process,
+ * and to make sure our loops_per_jiffies are "good enough", that is will
+ * not cause too short delays if we sleep in low speed and wake in high
+ * speed..
+ */
+ no_schedule = 1;
+ sleep_freq = cur_freq;
+ if (cur_freq == low_freq && !is_pmu_based)
+ do_set_cpu_speed(CPUFREQ_HIGH, 0);
+ return 0;
+}
+
+static int pmac_cpufreq_resume(struct cpufreq_policy *policy)
+{
+ /* If we resume, first check if we have a get() function */
+ if (get_speed_proc)
+ cur_freq = get_speed_proc();
+ else
+ cur_freq = 0;
+
+ /* We don't, hrm... we don't really know our speed here, best
+ * is that we force a switch to whatever it was, which is
+ * probably high speed due to our suspend() routine
+ */
+ do_set_cpu_speed(sleep_freq == low_freq ?
+ CPUFREQ_LOW : CPUFREQ_HIGH, 0);
+
+ ppc_proc_freq = cur_freq * 1000ul;
+
+ no_schedule = 0;
+ return 0;
+}
+
+static struct cpufreq_driver pmac_cpufreq_driver = {
+ .verify = pmac_cpufreq_verify,
+ .target = pmac_cpufreq_target,
+ .get = pmac_cpufreq_get_speed,
+ .init = pmac_cpufreq_cpu_init,
+ .suspend = pmac_cpufreq_suspend,
+ .resume = pmac_cpufreq_resume,
+ .flags = CPUFREQ_PM_NO_WARN,
+ .attr = pmac_cpu_freqs_attr,
+ .name = "powermac",
+ .owner = THIS_MODULE,
+};
+
+
+static int pmac_cpufreq_init_MacRISC3(struct device_node *cpunode)
+{
+ struct device_node *volt_gpio_np = of_find_node_by_name(NULL,
+ "voltage-gpio");
+ struct device_node *freq_gpio_np = of_find_node_by_name(NULL,
+ "frequency-gpio");
+ struct device_node *slew_done_gpio_np = of_find_node_by_name(NULL,
+ "slewing-done");
+ u32 *value;
+
+ /*
+ * Check to see if it's GPIO driven or PMU only
+ *
+ * The way we extract the GPIO address is slightly hackish, but it
+ * works well enough for now. We need to abstract the whole GPIO
+ * stuff sooner or later anyway
+ */
+
+ if (volt_gpio_np)
+ voltage_gpio = read_gpio(volt_gpio_np);
+ if (freq_gpio_np)
+ frequency_gpio = read_gpio(freq_gpio_np);
+ if (slew_done_gpio_np)
+ slew_done_gpio = read_gpio(slew_done_gpio_np);
+
+ /* If we use the frequency GPIOs, calculate the min/max speeds based
+ * on the bus frequencies
+ */
+ if (frequency_gpio && slew_done_gpio) {
+ int lenp, rc;
+ u32 *freqs, *ratio;
+
+ freqs = (u32 *)get_property(cpunode, "bus-frequencies", &lenp);
+ lenp /= sizeof(u32);
+ if (freqs == NULL || lenp != 2) {
+ printk(KERN_ERR "cpufreq: bus-frequencies incorrect or missing\n");
+ return 1;
+ }
+ ratio = (u32 *)get_property(cpunode, "processor-to-bus-ratio*2", NULL);
+ if (ratio == NULL) {
+ printk(KERN_ERR "cpufreq: processor-to-bus-ratio*2 missing\n");
+ return 1;
+ }
+
+ /* Get the min/max bus frequencies */
+ low_freq = min(freqs[0], freqs[1]);
+ hi_freq = max(freqs[0], freqs[1]);
+
+ /* Grrrr.. It _seems_ that the device-tree is lying on the low bus
+ * frequency, it claims it to be around 84Mhz on some models while
+ * it appears to be approx. 101Mhz on all. Let's hack around here...
+ * fortunately, we don't need to be too precise
+ */
+ if (low_freq < 98000000)
+ low_freq = 101000000;
+
+ /* Convert those to CPU core clocks */
+ low_freq = (low_freq * (*ratio)) / 2000;
+ hi_freq = (hi_freq * (*ratio)) / 2000;
+
+ /* Now we get the frequencies, we read the GPIO to see what is out current
+ * speed
+ */
+ rc = pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, frequency_gpio, 0);
+ cur_freq = (rc & 0x01) ? hi_freq : low_freq;
+
+ set_speed_proc = gpios_set_cpu_speed;
+ return 1;
+ }
+
+ /* If we use the PMU, look for the min & max frequencies in the
+ * device-tree
+ */
+ value = (u32 *)get_property(cpunode, "min-clock-frequency", NULL);
+ if (!value)
+ return 1;
+ low_freq = (*value) / 1000;
+ /* The PowerBook G4 12" (PowerBook6,1) has an error in the device-tree
+ * here */
+ if (low_freq < 100000)
+ low_freq *= 10;
+
+ value = (u32 *)get_property(cpunode, "max-clock-frequency", NULL);
+ if (!value)
+ return 1;
+ hi_freq = (*value) / 1000;
+ set_speed_proc = pmu_set_cpu_speed;
+ is_pmu_based = 1;
+
+ return 0;
+}
+
+static int pmac_cpufreq_init_7447A(struct device_node *cpunode)
+{
+ struct device_node *volt_gpio_np;
+
+ if (get_property(cpunode, "dynamic-power-step", NULL) == NULL)
+ return 1;
+
+ volt_gpio_np = of_find_node_by_name(NULL, "cpu-vcore-select");
+ if (volt_gpio_np)
+ voltage_gpio = read_gpio(volt_gpio_np);
+ if (!voltage_gpio){
+ printk(KERN_ERR "cpufreq: missing cpu-vcore-select gpio\n");
+ return 1;
+ }
+
+ /* OF only reports the high frequency */
+ hi_freq = cur_freq;
+ low_freq = cur_freq/2;
+
+ /* Read actual frequency from CPU */
+ cur_freq = dfs_get_cpu_speed();
+ set_speed_proc = dfs_set_cpu_speed;
+ get_speed_proc = dfs_get_cpu_speed;
+
+ return 0;
+}
+
+static int pmac_cpufreq_init_750FX(struct device_node *cpunode)
+{
+ struct device_node *volt_gpio_np;
+ u32 pvr, *value;
+
+ if (get_property(cpunode, "dynamic-power-step", NULL) == NULL)
+ return 1;
+
+ hi_freq = cur_freq;
+ value = (u32 *)get_property(cpunode, "reduced-clock-frequency", NULL);
+ if (!value)
+ return 1;
+ low_freq = (*value) / 1000;
+
+ volt_gpio_np = of_find_node_by_name(NULL, "cpu-vcore-select");
+ if (volt_gpio_np)
+ voltage_gpio = read_gpio(volt_gpio_np);
+
+ pvr = mfspr(SPRN_PVR);
+ has_cpu_l2lve = !((pvr & 0xf00) == 0x100);
+
+ set_speed_proc = cpu_750fx_cpu_speed;
+ get_speed_proc = cpu_750fx_get_cpu_speed;
+ cur_freq = cpu_750fx_get_cpu_speed();
+
+ return 0;
+}
+
+/* Currently, we support the following machines:
+ *
+ * - Titanium PowerBook 1Ghz (PMU based, 667Mhz & 1Ghz)
+ * - Titanium PowerBook 800 (PMU based, 667Mhz & 800Mhz)
+ * - Titanium PowerBook 400 (PMU based, 300Mhz & 400Mhz)
+ * - Titanium PowerBook 500 (PMU based, 300Mhz & 500Mhz)
+ * - iBook2 500/600 (PMU based, 400Mhz & 500/600Mhz)
+ * - iBook2 700 (CPU based, 400Mhz & 700Mhz, support low voltage)
+ * - Recent MacRISC3 laptops
+ * - All new machines with 7447A CPUs
+ */
+static int __init pmac_cpufreq_setup(void)
+{
+ struct device_node *cpunode;
+ u32 *value;
+
+ if (strstr(cmd_line, "nocpufreq"))
+ return 0;
+
+ /* Assume only one CPU */
+ cpunode = find_type_devices("cpu");
+ if (!cpunode)
+ goto out;
+
+ /* Get current cpu clock freq */
+ value = (u32 *)get_property(cpunode, "clock-frequency", NULL);
+ if (!value)
+ goto out;
+ cur_freq = (*value) / 1000;
+
+ /* Check for 7447A based MacRISC3 */
+ if (machine_is_compatible("MacRISC3") &&
+ get_property(cpunode, "dynamic-power-step", NULL) &&
+ PVR_VER(mfspr(SPRN_PVR)) == 0x8003) {
+ pmac_cpufreq_init_7447A(cpunode);
+ /* Check for other MacRISC3 machines */
+ } else if (machine_is_compatible("PowerBook3,4") ||
+ machine_is_compatible("PowerBook3,5") ||
+ machine_is_compatible("MacRISC3")) {
+ pmac_cpufreq_init_MacRISC3(cpunode);
+ /* Else check for iBook2 500/600 */
+ } else if (machine_is_compatible("PowerBook4,1")) {
+ hi_freq = cur_freq;
+ low_freq = 400000;
+ set_speed_proc = pmu_set_cpu_speed;
+ is_pmu_based = 1;
+ }
+ /* Else check for TiPb 550 */
+ else if (machine_is_compatible("PowerBook3,3") && cur_freq == 550000) {
+ hi_freq = cur_freq;
+ low_freq = 500000;
+ set_speed_proc = pmu_set_cpu_speed;
+ is_pmu_based = 1;
+ }
+ /* Else check for TiPb 400 & 500 */
+ else if (machine_is_compatible("PowerBook3,2")) {
+ /* We only know about the 400 MHz and the 500Mhz model
+ * they both have 300 MHz as low frequency
+ */
+ if (cur_freq < 350000 || cur_freq > 550000)
+ goto out;
+ hi_freq = cur_freq;
+ low_freq = 300000;
+ set_speed_proc = pmu_set_cpu_speed;
+ is_pmu_based = 1;
+ }
+ /* Else check for 750FX */
+ else if (PVR_VER(mfspr(SPRN_PVR)) == 0x7000)
+ pmac_cpufreq_init_750FX(cpunode);
+out:
+ if (set_speed_proc == NULL)
+ return -ENODEV;
+
+ pmac_cpu_freqs[CPUFREQ_LOW].frequency = low_freq;
+ pmac_cpu_freqs[CPUFREQ_HIGH].frequency = hi_freq;
+ ppc_proc_freq = cur_freq * 1000ul;
+
+ printk(KERN_INFO "Registering PowerMac CPU frequency driver\n");
+ printk(KERN_INFO "Low: %d Mhz, High: %d Mhz, Boot: %d Mhz\n",
+ low_freq/1000, hi_freq/1000, cur_freq/1000);
+
+ return cpufreq_register_driver(&pmac_cpufreq_driver);
+}
+
+module_init(pmac_cpufreq_setup);
+
diff --git a/arch/powerpc/platforms/powermac/cpufreq_64.c b/arch/powerpc/platforms/powermac/cpufreq_64.c
new file mode 100644
index 000000000000..39150342c6f1
--- /dev/null
+++ b/arch/powerpc/platforms/powermac/cpufreq_64.c
@@ -0,0 +1,323 @@
+/*
+ * Copyright (C) 2002 - 2005 Benjamin Herrenschmidt <benh@kernel.crashing.org>
+ * and Markus Demleitner <msdemlei@cl.uni-heidelberg.de>
+ *
+ * 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 driver adds basic cpufreq support for SMU & 970FX based G5 Macs,
+ * that is iMac G5 and latest single CPU desktop.
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/cpufreq.h>
+#include <linux/init.h>
+#include <linux/completion.h>
+#include <asm/prom.h>
+#include <asm/machdep.h>
+#include <asm/irq.h>
+#include <asm/sections.h>
+#include <asm/cputable.h>
+#include <asm/time.h>
+#include <asm/smu.h>
+
+#undef DEBUG
+
+#ifdef DEBUG
+#define DBG(fmt...) printk(fmt)
+#else
+#define DBG(fmt...)
+#endif
+
+/* see 970FX user manual */
+
+#define SCOM_PCR 0x0aa001 /* PCR scom addr */
+
+#define PCR_HILO_SELECT 0x80000000U /* 1 = PCR, 0 = PCRH */
+#define PCR_SPEED_FULL 0x00000000U /* 1:1 speed value */
+#define PCR_SPEED_HALF 0x00020000U /* 1:2 speed value */
+#define PCR_SPEED_QUARTER 0x00040000U /* 1:4 speed value */
+#define PCR_SPEED_MASK 0x000e0000U /* speed mask */
+#define PCR_SPEED_SHIFT 17
+#define PCR_FREQ_REQ_VALID 0x00010000U /* freq request valid */
+#define PCR_VOLT_REQ_VALID 0x00008000U /* volt request valid */
+#define PCR_TARGET_TIME_MASK 0x00006000U /* target time */
+#define PCR_STATLAT_MASK 0x00001f00U /* STATLAT value */
+#define PCR_SNOOPLAT_MASK 0x000000f0U /* SNOOPLAT value */
+#define PCR_SNOOPACC_MASK 0x0000000fU /* SNOOPACC value */
+
+#define SCOM_PSR 0x408001 /* PSR scom addr */
+/* warning: PSR is a 64 bits register */
+#define PSR_CMD_RECEIVED 0x2000000000000000U /* command received */
+#define PSR_CMD_COMPLETED 0x1000000000000000U /* command completed */
+#define PSR_CUR_SPEED_MASK 0x0300000000000000U /* current speed */
+#define PSR_CUR_SPEED_SHIFT (56)
+
+/*
+ * The G5 only supports two frequencies (Quarter speed is not supported)
+ */
+#define CPUFREQ_HIGH 0
+#define CPUFREQ_LOW 1
+
+static struct cpufreq_frequency_table g5_cpu_freqs[] = {
+ {CPUFREQ_HIGH, 0},
+ {CPUFREQ_LOW, 0},
+ {0, CPUFREQ_TABLE_END},
+};
+
+static struct freq_attr* g5_cpu_freqs_attr[] = {
+ &cpufreq_freq_attr_scaling_available_freqs,
+ NULL,
+};
+
+/* Power mode data is an array of the 32 bits PCR values to use for
+ * the various frequencies, retreived from the device-tree
+ */
+static u32 *g5_pmode_data;
+static int g5_pmode_max;
+static int g5_pmode_cur;
+
+static DECLARE_MUTEX(g5_switch_mutex);
+
+
+static struct smu_sdbp_fvt *g5_fvt_table; /* table of op. points */
+static int g5_fvt_count; /* number of op. points */
+static int g5_fvt_cur; /* current op. point */
+
+/* ----------------- real hardware interface */
+
+static void g5_switch_volt(int speed_mode)
+{
+ struct smu_simple_cmd cmd;
+
+ DECLARE_COMPLETION(comp);
+ smu_queue_simple(&cmd, SMU_CMD_POWER_COMMAND, 8, smu_done_complete,
+ &comp, 'V', 'S', 'L', 'E', 'W',
+ 0xff, g5_fvt_cur+1, speed_mode);
+ wait_for_completion(&comp);
+}
+
+static int g5_switch_freq(int speed_mode)
+{
+ struct cpufreq_freqs freqs;
+ int to;
+
+ if (g5_pmode_cur == speed_mode)
+ return 0;
+
+ down(&g5_switch_mutex);
+
+ freqs.old = g5_cpu_freqs[g5_pmode_cur].frequency;
+ freqs.new = g5_cpu_freqs[speed_mode].frequency;
+ freqs.cpu = 0;
+
+ cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+
+ /* If frequency is going up, first ramp up the voltage */
+ if (speed_mode < g5_pmode_cur)
+ g5_switch_volt(speed_mode);
+
+ /* Clear PCR high */
+ scom970_write(SCOM_PCR, 0);
+ /* Clear PCR low */
+ scom970_write(SCOM_PCR, PCR_HILO_SELECT | 0);
+ /* Set PCR low */
+ scom970_write(SCOM_PCR, PCR_HILO_SELECT |
+ g5_pmode_data[speed_mode]);
+
+ /* Wait for completion */
+ for (to = 0; to < 10; to++) {
+ unsigned long psr = scom970_read(SCOM_PSR);
+
+ if ((psr & PSR_CMD_RECEIVED) == 0 &&
+ (((psr >> PSR_CUR_SPEED_SHIFT) ^
+ (g5_pmode_data[speed_mode] >> PCR_SPEED_SHIFT)) & 0x3)
+ == 0)
+ break;
+ if (psr & PSR_CMD_COMPLETED)
+ break;
+ udelay(100);
+ }
+
+ /* If frequency is going down, last ramp the voltage */
+ if (speed_mode > g5_pmode_cur)
+ g5_switch_volt(speed_mode);
+
+ g5_pmode_cur = speed_mode;
+ ppc_proc_freq = g5_cpu_freqs[speed_mode].frequency * 1000ul;
+
+ cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+
+ up(&g5_switch_mutex);
+
+ return 0;
+}
+
+static int g5_query_freq(void)
+{
+ unsigned long psr = scom970_read(SCOM_PSR);
+ int i;
+
+ for (i = 0; i <= g5_pmode_max; i++)
+ if ((((psr >> PSR_CUR_SPEED_SHIFT) ^
+ (g5_pmode_data[i] >> PCR_SPEED_SHIFT)) & 0x3) == 0)
+ break;
+ return i;
+}
+
+/* ----------------- cpufreq bookkeeping */
+
+static int g5_cpufreq_verify(struct cpufreq_policy *policy)
+{
+ return cpufreq_frequency_table_verify(policy, g5_cpu_freqs);
+}
+
+static int g5_cpufreq_target(struct cpufreq_policy *policy,
+ unsigned int target_freq, unsigned int relation)
+{
+ unsigned int newstate = 0;
+
+ if (cpufreq_frequency_table_target(policy, g5_cpu_freqs,
+ target_freq, relation, &newstate))
+ return -EINVAL;
+
+ return g5_switch_freq(newstate);
+}
+
+static unsigned int g5_cpufreq_get_speed(unsigned int cpu)
+{
+ return g5_cpu_freqs[g5_pmode_cur].frequency;
+}
+
+static int g5_cpufreq_cpu_init(struct cpufreq_policy *policy)
+{
+ if (policy->cpu != 0)
+ return -ENODEV;
+
+ policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
+ policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
+ policy->cur = g5_cpu_freqs[g5_query_freq()].frequency;
+ cpufreq_frequency_table_get_attr(g5_cpu_freqs, policy->cpu);
+
+ return cpufreq_frequency_table_cpuinfo(policy,
+ g5_cpu_freqs);
+}
+
+
+static struct cpufreq_driver g5_cpufreq_driver = {
+ .name = "powermac",
+ .owner = THIS_MODULE,
+ .flags = CPUFREQ_CONST_LOOPS,
+ .init = g5_cpufreq_cpu_init,
+ .verify = g5_cpufreq_verify,
+ .target = g5_cpufreq_target,
+ .get = g5_cpufreq_get_speed,
+ .attr = g5_cpu_freqs_attr,
+};
+
+
+static int __init g5_cpufreq_init(void)
+{
+ struct device_node *cpunode;
+ unsigned int psize, ssize;
+ struct smu_sdbp_header *shdr;
+ unsigned long max_freq;
+ u32 *valp;
+ int rc = -ENODEV;
+
+ /* Look for CPU and SMU nodes */
+ cpunode = of_find_node_by_type(NULL, "cpu");
+ if (!cpunode) {
+ DBG("No CPU node !\n");
+ return -ENODEV;
+ }
+
+ /* Check 970FX for now */
+ valp = (u32 *)get_property(cpunode, "cpu-version", NULL);
+ if (!valp) {
+ DBG("No cpu-version property !\n");
+ goto bail_noprops;
+ }
+ if (((*valp) >> 16) != 0x3c) {
+ DBG("Wrong CPU version: %08x\n", *valp);
+ goto bail_noprops;
+ }
+
+ /* Look for the powertune data in the device-tree */
+ g5_pmode_data = (u32 *)get_property(cpunode, "power-mode-data",&psize);
+ if (!g5_pmode_data) {
+ DBG("No power-mode-data !\n");
+ goto bail_noprops;
+ }
+ g5_pmode_max = psize / sizeof(u32) - 1;
+
+ /* Look for the FVT table */
+ shdr = smu_get_sdb_partition(SMU_SDB_FVT_ID, NULL);
+ if (!shdr)
+ goto bail_noprops;
+ g5_fvt_table = (struct smu_sdbp_fvt *)&shdr[1];
+ ssize = (shdr->len * sizeof(u32)) - sizeof(struct smu_sdbp_header);
+ g5_fvt_count = ssize / sizeof(struct smu_sdbp_fvt);
+ g5_fvt_cur = 0;
+
+ /* Sanity checking */
+ if (g5_fvt_count < 1 || g5_pmode_max < 1)
+ goto bail_noprops;
+
+ /*
+ * From what I see, clock-frequency is always the maximal frequency.
+ * The current driver can not slew sysclk yet, so we really only deal
+ * with powertune steps for now. We also only implement full freq and
+ * half freq in this version. So far, I haven't yet seen a machine
+ * supporting anything else.
+ */
+ valp = (u32 *)get_property(cpunode, "clock-frequency", NULL);
+ if (!valp)
+ return -ENODEV;
+ max_freq = (*valp)/1000;
+ g5_cpu_freqs[0].frequency = max_freq;
+ g5_cpu_freqs[1].frequency = max_freq/2;
+
+ /* Check current frequency */
+ g5_pmode_cur = g5_query_freq();
+ if (g5_pmode_cur > 1)
+ /* We don't support anything but 1:1 and 1:2, fixup ... */
+ g5_pmode_cur = 1;
+
+ /* Force apply current frequency to make sure everything is in
+ * sync (voltage is right for example). Firmware may leave us with
+ * a strange setting ...
+ */
+ g5_switch_freq(g5_pmode_cur);
+
+ printk(KERN_INFO "Registering G5 CPU frequency driver\n");
+ printk(KERN_INFO "Low: %d Mhz, High: %d Mhz, Cur: %d MHz\n",
+ g5_cpu_freqs[1].frequency/1000,
+ g5_cpu_freqs[0].frequency/1000,
+ g5_cpu_freqs[g5_pmode_cur].frequency/1000);
+
+ rc = cpufreq_register_driver(&g5_cpufreq_driver);
+
+ /* We keep the CPU node on hold... hopefully, Apple G5 don't have
+ * hotplug CPU with a dynamic device-tree ...
+ */
+ return rc;
+
+ bail_noprops:
+ of_node_put(cpunode);
+
+ return rc;
+}
+
+module_init(g5_cpufreq_init);
+
+
+MODULE_LICENSE("GPL");
diff --git a/arch/powerpc/platforms/powermac/feature.c b/arch/powerpc/platforms/powermac/feature.c
new file mode 100644
index 000000000000..10f1d942c661
--- /dev/null
+++ b/arch/powerpc/platforms/powermac/feature.c
@@ -0,0 +1,3063 @@
+/*
+ * arch/ppc/platforms/pmac_feature.c
+ *
+ * Copyright (C) 1996-2001 Paul Mackerras (paulus@cs.anu.edu.au)
+ * Ben. Herrenschmidt (benh@kernel.crashing.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.
+ *
+ * TODO:
+ *
+ * - Replace mdelay with some schedule loop if possible
+ * - Shorten some obfuscated delays on some routines (like modem
+ * power)
+ * - Refcount some clocks (see darwin)
+ * - Split split split...
+ *
+ */
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/spinlock.h>
+#include <linux/adb.h>
+#include <linux/pmu.h>
+#include <linux/ioport.h>
+#include <linux/pci.h>
+#include <asm/sections.h>
+#include <asm/errno.h>
+#include <asm/ohare.h>
+#include <asm/heathrow.h>
+#include <asm/keylargo.h>
+#include <asm/uninorth.h>
+#include <asm/io.h>
+#include <asm/prom.h>
+#include <asm/machdep.h>
+#include <asm/pmac_feature.h>
+#include <asm/dbdma.h>
+#include <asm/pci-bridge.h>
+#include <asm/pmac_low_i2c.h>
+
+#undef DEBUG_FEATURE
+
+#ifdef DEBUG_FEATURE
+#define DBG(fmt...) printk(KERN_DEBUG fmt)
+#else
+#define DBG(fmt...)
+#endif
+
+#ifdef CONFIG_6xx
+extern int powersave_lowspeed;
+#endif
+
+extern int powersave_nap;
+extern struct device_node *k2_skiplist[2];
+
+
+/*
+ * We use a single global lock to protect accesses. Each driver has
+ * to take care of its own locking
+ */
+static DEFINE_SPINLOCK(feature_lock);
+
+#define LOCK(flags) spin_lock_irqsave(&feature_lock, flags);
+#define UNLOCK(flags) spin_unlock_irqrestore(&feature_lock, flags);
+
+
+/*
+ * Instance of some macio stuffs
+ */
+struct macio_chip macio_chips[MAX_MACIO_CHIPS];
+
+struct macio_chip *macio_find(struct device_node *child, int type)
+{
+ while(child) {
+ int i;
+
+ for (i=0; i < MAX_MACIO_CHIPS && macio_chips[i].of_node; i++)
+ if (child == macio_chips[i].of_node &&
+ (!type || macio_chips[i].type == type))
+ return &macio_chips[i];
+ child = child->parent;
+ }
+ return NULL;
+}
+EXPORT_SYMBOL_GPL(macio_find);
+
+static const char *macio_names[] =
+{
+ "Unknown",
+ "Grand Central",
+ "OHare",
+ "OHareII",
+ "Heathrow",
+ "Gatwick",
+ "Paddington",
+ "Keylargo",
+ "Pangea",
+ "Intrepid",
+ "K2"
+};
+
+
+
+/*
+ * Uninorth reg. access. Note that Uni-N regs are big endian
+ */
+
+#define UN_REG(r) (uninorth_base + ((r) >> 2))
+#define UN_IN(r) (in_be32(UN_REG(r)))
+#define UN_OUT(r,v) (out_be32(UN_REG(r), (v)))
+#define UN_BIS(r,v) (UN_OUT((r), UN_IN(r) | (v)))
+#define UN_BIC(r,v) (UN_OUT((r), UN_IN(r) & ~(v)))
+
+static struct device_node *uninorth_node;
+static u32 __iomem *uninorth_base;
+static u32 uninorth_rev;
+static int uninorth_u3;
+static void __iomem *u3_ht;
+
+/*
+ * For each motherboard family, we have a table of functions pointers
+ * that handle the various features.
+ */
+
+typedef long (*feature_call)(struct device_node *node, long param, long value);
+
+struct feature_table_entry {
+ unsigned int selector;
+ feature_call function;
+};
+
+struct pmac_mb_def
+{
+ const char* model_string;
+ const char* model_name;
+ int model_id;
+ struct feature_table_entry* features;
+ unsigned long board_flags;
+};
+static struct pmac_mb_def pmac_mb;
+
+/*
+ * Here are the chip specific feature functions
+ */
+
+static inline int simple_feature_tweak(struct device_node *node, int type,
+ int reg, u32 mask, int value)
+{
+ struct macio_chip* macio;
+ unsigned long flags;
+
+ macio = macio_find(node, type);
+ if (!macio)
+ return -ENODEV;
+ LOCK(flags);
+ if (value)
+ MACIO_BIS(reg, mask);
+ else
+ MACIO_BIC(reg, mask);
+ (void)MACIO_IN32(reg);
+ UNLOCK(flags);
+
+ return 0;
+}
+
+#ifndef CONFIG_POWER4
+
+static long ohare_htw_scc_enable(struct device_node *node, long param,
+ long value)
+{
+ struct macio_chip* macio;
+ unsigned long chan_mask;
+ unsigned long fcr;
+ unsigned long flags;
+ int htw, trans;
+ unsigned long rmask;
+
+ macio = macio_find(node, 0);
+ if (!macio)
+ return -ENODEV;
+ if (!strcmp(node->name, "ch-a"))
+ chan_mask = MACIO_FLAG_SCCA_ON;
+ else if (!strcmp(node->name, "ch-b"))
+ chan_mask = MACIO_FLAG_SCCB_ON;
+ else
+ return -ENODEV;
+
+ htw = (macio->type == macio_heathrow || macio->type == macio_paddington
+ || macio->type == macio_gatwick);
+ /* On these machines, the HRW_SCC_TRANS_EN_N bit mustn't be touched */
+ trans = (pmac_mb.model_id != PMAC_TYPE_YOSEMITE &&
+ pmac_mb.model_id != PMAC_TYPE_YIKES);
+ if (value) {
+#ifdef CONFIG_ADB_PMU
+ if ((param & 0xfff) == PMAC_SCC_IRDA)
+ pmu_enable_irled(1);
+#endif /* CONFIG_ADB_PMU */
+ LOCK(flags);
+ fcr = MACIO_IN32(OHARE_FCR);
+ /* Check if scc cell need enabling */
+ if (!(fcr & OH_SCC_ENABLE)) {
+ fcr |= OH_SCC_ENABLE;
+ if (htw) {
+ /* Side effect: this will also power up the
+ * modem, but it's too messy to figure out on which
+ * ports this controls the tranceiver and on which
+ * it controls the modem
+ */
+ if (trans)
+ fcr &= ~HRW_SCC_TRANS_EN_N;
+ MACIO_OUT32(OHARE_FCR, fcr);
+ fcr |= (rmask = HRW_RESET_SCC);
+ MACIO_OUT32(OHARE_FCR, fcr);
+ } else {
+ fcr |= (rmask = OH_SCC_RESET);
+ MACIO_OUT32(OHARE_FCR, fcr);
+ }
+ UNLOCK(flags);
+ (void)MACIO_IN32(OHARE_FCR);
+ mdelay(15);
+ LOCK(flags);
+ fcr &= ~rmask;
+ MACIO_OUT32(OHARE_FCR, fcr);
+ }
+ if (chan_mask & MACIO_FLAG_SCCA_ON)
+ fcr |= OH_SCCA_IO;
+ if (chan_mask & MACIO_FLAG_SCCB_ON)
+ fcr |= OH_SCCB_IO;
+ MACIO_OUT32(OHARE_FCR, fcr);
+ macio->flags |= chan_mask;
+ UNLOCK(flags);
+ if (param & PMAC_SCC_FLAG_XMON)
+ macio->flags |= MACIO_FLAG_SCC_LOCKED;
+ } else {
+ if (macio->flags & MACIO_FLAG_SCC_LOCKED)
+ return -EPERM;
+ LOCK(flags);
+ fcr = MACIO_IN32(OHARE_FCR);
+ if (chan_mask & MACIO_FLAG_SCCA_ON)
+ fcr &= ~OH_SCCA_IO;
+ if (chan_mask & MACIO_FLAG_SCCB_ON)
+ fcr &= ~OH_SCCB_IO;
+ MACIO_OUT32(OHARE_FCR, fcr);
+ if ((fcr & (OH_SCCA_IO | OH_SCCB_IO)) == 0) {
+ fcr &= ~OH_SCC_ENABLE;
+ if (htw && trans)
+ fcr |= HRW_SCC_TRANS_EN_N;
+ MACIO_OUT32(OHARE_FCR, fcr);
+ }
+ macio->flags &= ~(chan_mask);
+ UNLOCK(flags);
+ mdelay(10);
+#ifdef CONFIG_ADB_PMU
+ if ((param & 0xfff) == PMAC_SCC_IRDA)
+ pmu_enable_irled(0);
+#endif /* CONFIG_ADB_PMU */
+ }
+ return 0;
+}
+
+static long ohare_floppy_enable(struct device_node *node, long param,
+ long value)
+{
+ return simple_feature_tweak(node, macio_ohare,
+ OHARE_FCR, OH_FLOPPY_ENABLE, value);
+}
+
+static long ohare_mesh_enable(struct device_node *node, long param, long value)
+{
+ return simple_feature_tweak(node, macio_ohare,
+ OHARE_FCR, OH_MESH_ENABLE, value);
+}
+
+static long ohare_ide_enable(struct device_node *node, long param, long value)
+{
+ switch(param) {
+ case 0:
+ /* For some reason, setting the bit in set_initial_features()
+ * doesn't stick. I'm still investigating... --BenH.
+ */
+ if (value)
+ simple_feature_tweak(node, macio_ohare,
+ OHARE_FCR, OH_IOBUS_ENABLE, 1);
+ return simple_feature_tweak(node, macio_ohare,
+ OHARE_FCR, OH_IDE0_ENABLE, value);
+ case 1:
+ return simple_feature_tweak(node, macio_ohare,
+ OHARE_FCR, OH_BAY_IDE_ENABLE, value);
+ default:
+ return -ENODEV;
+ }
+}
+
+static long ohare_ide_reset(struct device_node *node, long param, long value)
+{
+ switch(param) {
+ case 0:
+ return simple_feature_tweak(node, macio_ohare,
+ OHARE_FCR, OH_IDE0_RESET_N, !value);
+ case 1:
+ return simple_feature_tweak(node, macio_ohare,
+ OHARE_FCR, OH_IDE1_RESET_N, !value);
+ default:
+ return -ENODEV;
+ }
+}
+
+static long ohare_sleep_state(struct device_node *node, long param, long value)
+{
+ struct macio_chip* macio = &macio_chips[0];
+
+ if ((pmac_mb.board_flags & PMAC_MB_CAN_SLEEP) == 0)
+ return -EPERM;
+ if (value == 1) {
+ MACIO_BIC(OHARE_FCR, OH_IOBUS_ENABLE);
+ } else if (value == 0) {
+ MACIO_BIS(OHARE_FCR, OH_IOBUS_ENABLE);
+ }
+
+ return 0;
+}
+
+static long heathrow_modem_enable(struct device_node *node, long param,
+ long value)
+{
+ struct macio_chip* macio;
+ u8 gpio;
+ unsigned long flags;
+
+ macio = macio_find(node, macio_unknown);
+ if (!macio)
+ return -ENODEV;
+ gpio = MACIO_IN8(HRW_GPIO_MODEM_RESET) & ~1;
+ if (!value) {
+ LOCK(flags);
+ MACIO_OUT8(HRW_GPIO_MODEM_RESET, gpio);
+ UNLOCK(flags);
+ (void)MACIO_IN8(HRW_GPIO_MODEM_RESET);
+ mdelay(250);
+ }
+ if (pmac_mb.model_id != PMAC_TYPE_YOSEMITE &&
+ pmac_mb.model_id != PMAC_TYPE_YIKES) {
+ LOCK(flags);
+ if (value)
+ MACIO_BIC(HEATHROW_FCR, HRW_SCC_TRANS_EN_N);
+ else
+ MACIO_BIS(HEATHROW_FCR, HRW_SCC_TRANS_EN_N);
+ UNLOCK(flags);
+ (void)MACIO_IN32(HEATHROW_FCR);
+ mdelay(250);
+ }
+ if (value) {
+ LOCK(flags);
+ MACIO_OUT8(HRW_GPIO_MODEM_RESET, gpio | 1);
+ (void)MACIO_IN8(HRW_GPIO_MODEM_RESET);
+ UNLOCK(flags); mdelay(250); LOCK(flags);
+ MACIO_OUT8(HRW_GPIO_MODEM_RESET, gpio);
+ (void)MACIO_IN8(HRW_GPIO_MODEM_RESET);
+ UNLOCK(flags); mdelay(250); LOCK(flags);
+ MACIO_OUT8(HRW_GPIO_MODEM_RESET, gpio | 1);
+ (void)MACIO_IN8(HRW_GPIO_MODEM_RESET);
+ UNLOCK(flags); mdelay(250);
+ }
+ return 0;
+}
+
+static long heathrow_floppy_enable(struct device_node *node, long param,
+ long value)
+{
+ return simple_feature_tweak(node, macio_unknown,
+ HEATHROW_FCR,
+ HRW_SWIM_ENABLE|HRW_BAY_FLOPPY_ENABLE,
+ value);
+}
+
+static long heathrow_mesh_enable(struct device_node *node, long param,
+ long value)
+{
+ struct macio_chip* macio;
+ unsigned long flags;
+
+ macio = macio_find(node, macio_unknown);
+ if (!macio)
+ return -ENODEV;
+ LOCK(flags);
+ /* Set clear mesh cell enable */
+ if (value)
+ MACIO_BIS(HEATHROW_FCR, HRW_MESH_ENABLE);
+ else
+ MACIO_BIC(HEATHROW_FCR, HRW_MESH_ENABLE);
+ (void)MACIO_IN32(HEATHROW_FCR);
+ udelay(10);
+ /* Set/Clear termination power */
+ if (value)
+ MACIO_BIC(HEATHROW_MBCR, 0x04000000);
+ else
+ MACIO_BIS(HEATHROW_MBCR, 0x04000000);
+ (void)MACIO_IN32(HEATHROW_MBCR);
+ udelay(10);
+ UNLOCK(flags);
+
+ return 0;
+}
+
+static long heathrow_ide_enable(struct device_node *node, long param,
+ long value)
+{
+ switch(param) {
+ case 0:
+ return simple_feature_tweak(node, macio_unknown,
+ HEATHROW_FCR, HRW_IDE0_ENABLE, value);
+ case 1:
+ return simple_feature_tweak(node, macio_unknown,
+ HEATHROW_FCR, HRW_BAY_IDE_ENABLE, value);
+ default:
+ return -ENODEV;
+ }
+}
+
+static long heathrow_ide_reset(struct device_node *node, long param,
+ long value)
+{
+ switch(param) {
+ case 0:
+ return simple_feature_tweak(node, macio_unknown,
+ HEATHROW_FCR, HRW_IDE0_RESET_N, !value);
+ case 1:
+ return simple_feature_tweak(node, macio_unknown,
+ HEATHROW_FCR, HRW_IDE1_RESET_N, !value);
+ default:
+ return -ENODEV;
+ }
+}
+
+static long heathrow_bmac_enable(struct device_node *node, long param,
+ long value)
+{
+ struct macio_chip* macio;
+ unsigned long flags;
+
+ macio = macio_find(node, 0);
+ if (!macio)
+ return -ENODEV;
+ if (value) {
+ LOCK(flags);
+ MACIO_BIS(HEATHROW_FCR, HRW_BMAC_IO_ENABLE);
+ MACIO_BIS(HEATHROW_FCR, HRW_BMAC_RESET);
+ UNLOCK(flags);
+ (void)MACIO_IN32(HEATHROW_FCR);
+ mdelay(10);
+ LOCK(flags);
+ MACIO_BIC(HEATHROW_FCR, HRW_BMAC_RESET);
+ UNLOCK(flags);
+ (void)MACIO_IN32(HEATHROW_FCR);
+ mdelay(10);
+ } else {
+ LOCK(flags);
+ MACIO_BIC(HEATHROW_FCR, HRW_BMAC_IO_ENABLE);
+ UNLOCK(flags);
+ }
+ return 0;
+}
+
+static long heathrow_sound_enable(struct device_node *node, long param,
+ long value)
+{
+ struct macio_chip* macio;
+ unsigned long flags;
+
+ /* B&W G3 and Yikes don't support that properly (the
+ * sound appear to never come back after beeing shut down).
+ */
+ if (pmac_mb.model_id == PMAC_TYPE_YOSEMITE ||
+ pmac_mb.model_id == PMAC_TYPE_YIKES)
+ return 0;
+
+ macio = macio_find(node, 0);
+ if (!macio)
+ return -ENODEV;
+ if (value) {
+ LOCK(flags);
+ MACIO_BIS(HEATHROW_FCR, HRW_SOUND_CLK_ENABLE);
+ MACIO_BIC(HEATHROW_FCR, HRW_SOUND_POWER_N);
+ UNLOCK(flags);
+ (void)MACIO_IN32(HEATHROW_FCR);
+ } else {
+ LOCK(flags);
+ MACIO_BIS(HEATHROW_FCR, HRW_SOUND_POWER_N);
+ MACIO_BIC(HEATHROW_FCR, HRW_SOUND_CLK_ENABLE);
+ UNLOCK(flags);
+ }
+ return 0;
+}
+
+static u32 save_fcr[6];
+static u32 save_mbcr;
+static u32 save_gpio_levels[2];
+static u8 save_gpio_extint[KEYLARGO_GPIO_EXTINT_CNT];
+static u8 save_gpio_normal[KEYLARGO_GPIO_CNT];
+static u32 save_unin_clock_ctl;
+static struct dbdma_regs save_dbdma[13];
+static struct dbdma_regs save_alt_dbdma[13];
+
+static void dbdma_save(struct macio_chip *macio, struct dbdma_regs *save)
+{
+ int i;
+
+ /* Save state & config of DBDMA channels */
+ for (i = 0; i < 13; i++) {
+ volatile struct dbdma_regs __iomem * chan = (void __iomem *)
+ (macio->base + ((0x8000+i*0x100)>>2));
+ save[i].cmdptr_hi = in_le32(&chan->cmdptr_hi);
+ save[i].cmdptr = in_le32(&chan->cmdptr);
+ save[i].intr_sel = in_le32(&chan->intr_sel);
+ save[i].br_sel = in_le32(&chan->br_sel);
+ save[i].wait_sel = in_le32(&chan->wait_sel);
+ }
+}
+
+static void dbdma_restore(struct macio_chip *macio, struct dbdma_regs *save)
+{
+ int i;
+
+ /* Save state & config of DBDMA channels */
+ for (i = 0; i < 13; i++) {
+ volatile struct dbdma_regs __iomem * chan = (void __iomem *)
+ (macio->base + ((0x8000+i*0x100)>>2));
+ out_le32(&chan->control, (ACTIVE|DEAD|WAKE|FLUSH|PAUSE|RUN)<<16);
+ while (in_le32(&chan->status) & ACTIVE)
+ mb();
+ out_le32(&chan->cmdptr_hi, save[i].cmdptr_hi);
+ out_le32(&chan->cmdptr, save[i].cmdptr);
+ out_le32(&chan->intr_sel, save[i].intr_sel);
+ out_le32(&chan->br_sel, save[i].br_sel);
+ out_le32(&chan->wait_sel, save[i].wait_sel);
+ }
+}
+
+static void heathrow_sleep(struct macio_chip *macio, int secondary)
+{
+ if (secondary) {
+ dbdma_save(macio, save_alt_dbdma);
+ save_fcr[2] = MACIO_IN32(0x38);
+ save_fcr[3] = MACIO_IN32(0x3c);
+ } else {
+ dbdma_save(macio, save_dbdma);
+ save_fcr[0] = MACIO_IN32(0x38);
+ save_fcr[1] = MACIO_IN32(0x3c);
+ save_mbcr = MACIO_IN32(0x34);
+ /* Make sure sound is shut down */
+ MACIO_BIS(HEATHROW_FCR, HRW_SOUND_POWER_N);
+ MACIO_BIC(HEATHROW_FCR, HRW_SOUND_CLK_ENABLE);
+ /* This seems to be necessary as well or the fan
+ * keeps coming up and battery drains fast */
+ MACIO_BIC(HEATHROW_FCR, HRW_IOBUS_ENABLE);
+ MACIO_BIC(HEATHROW_FCR, HRW_IDE0_RESET_N);
+ /* Make sure eth is down even if module or sleep
+ * won't work properly */
+ MACIO_BIC(HEATHROW_FCR, HRW_BMAC_IO_ENABLE | HRW_BMAC_RESET);
+ }
+ /* Make sure modem is shut down */
+ MACIO_OUT8(HRW_GPIO_MODEM_RESET,
+ MACIO_IN8(HRW_GPIO_MODEM_RESET) & ~1);
+ MACIO_BIS(HEATHROW_FCR, HRW_SCC_TRANS_EN_N);
+ MACIO_BIC(HEATHROW_FCR, OH_SCCA_IO|OH_SCCB_IO|HRW_SCC_ENABLE);
+
+ /* Let things settle */
+ (void)MACIO_IN32(HEATHROW_FCR);
+}
+
+static void heathrow_wakeup(struct macio_chip *macio, int secondary)
+{
+ if (secondary) {
+ MACIO_OUT32(0x38, save_fcr[2]);
+ (void)MACIO_IN32(0x38);
+ mdelay(1);
+ MACIO_OUT32(0x3c, save_fcr[3]);
+ (void)MACIO_IN32(0x38);
+ mdelay(10);
+ dbdma_restore(macio, save_alt_dbdma);
+ } else {
+ MACIO_OUT32(0x38, save_fcr[0] | HRW_IOBUS_ENABLE);
+ (void)MACIO_IN32(0x38);
+ mdelay(1);
+ MACIO_OUT32(0x3c, save_fcr[1]);
+ (void)MACIO_IN32(0x38);
+ mdelay(1);
+ MACIO_OUT32(0x34, save_mbcr);
+ (void)MACIO_IN32(0x38);
+ mdelay(10);
+ dbdma_restore(macio, save_dbdma);
+ }
+}
+
+static long heathrow_sleep_state(struct device_node *node, long param,
+ long value)
+{
+ if ((pmac_mb.board_flags & PMAC_MB_CAN_SLEEP) == 0)
+ return -EPERM;
+ if (value == 1) {
+ if (macio_chips[1].type == macio_gatwick)
+ heathrow_sleep(&macio_chips[0], 1);
+ heathrow_sleep(&macio_chips[0], 0);
+ } else if (value == 0) {
+ heathrow_wakeup(&macio_chips[0], 0);
+ if (macio_chips[1].type == macio_gatwick)
+ heathrow_wakeup(&macio_chips[0], 1);
+ }
+ return 0;
+}
+
+static long core99_scc_enable(struct device_node *node, long param, long value)
+{
+ struct macio_chip* macio;
+ unsigned long flags;
+ unsigned long chan_mask;
+ u32 fcr;
+
+ macio = macio_find(node, 0);
+ if (!macio)
+ return -ENODEV;
+ if (!strcmp(node->name, "ch-a"))
+ chan_mask = MACIO_FLAG_SCCA_ON;
+ else if (!strcmp(node->name, "ch-b"))
+ chan_mask = MACIO_FLAG_SCCB_ON;
+ else
+ return -ENODEV;
+
+ if (value) {
+ int need_reset_scc = 0;
+ int need_reset_irda = 0;
+
+ LOCK(flags);
+ fcr = MACIO_IN32(KEYLARGO_FCR0);
+ /* Check if scc cell need enabling */
+ if (!(fcr & KL0_SCC_CELL_ENABLE)) {
+ fcr |= KL0_SCC_CELL_ENABLE;
+ need_reset_scc = 1;
+ }
+ if (chan_mask & MACIO_FLAG_SCCA_ON) {
+ fcr |= KL0_SCCA_ENABLE;
+ /* Don't enable line drivers for I2S modem */
+ if ((param & 0xfff) == PMAC_SCC_I2S1)
+ fcr &= ~KL0_SCC_A_INTF_ENABLE;
+ else
+ fcr |= KL0_SCC_A_INTF_ENABLE;
+ }
+ if (chan_mask & MACIO_FLAG_SCCB_ON) {
+ fcr |= KL0_SCCB_ENABLE;
+ /* Perform irda specific inits */
+ if ((param & 0xfff) == PMAC_SCC_IRDA) {
+ fcr &= ~KL0_SCC_B_INTF_ENABLE;
+ fcr |= KL0_IRDA_ENABLE;
+ fcr |= KL0_IRDA_CLK32_ENABLE | KL0_IRDA_CLK19_ENABLE;
+ fcr |= KL0_IRDA_SOURCE1_SEL;
+ fcr &= ~(KL0_IRDA_FAST_CONNECT|KL0_IRDA_DEFAULT1|KL0_IRDA_DEFAULT0);
+ fcr &= ~(KL0_IRDA_SOURCE2_SEL|KL0_IRDA_HIGH_BAND);
+ need_reset_irda = 1;
+ } else
+ fcr |= KL0_SCC_B_INTF_ENABLE;
+ }
+ MACIO_OUT32(KEYLARGO_FCR0, fcr);
+ macio->flags |= chan_mask;
+ if (need_reset_scc) {
+ MACIO_BIS(KEYLARGO_FCR0, KL0_SCC_RESET);
+ (void)MACIO_IN32(KEYLARGO_FCR0);
+ UNLOCK(flags);
+ mdelay(15);
+ LOCK(flags);
+ MACIO_BIC(KEYLARGO_FCR0, KL0_SCC_RESET);
+ }
+ if (need_reset_irda) {
+ MACIO_BIS(KEYLARGO_FCR0, KL0_IRDA_RESET);
+ (void)MACIO_IN32(KEYLARGO_FCR0);
+ UNLOCK(flags);
+ mdelay(15);
+ LOCK(flags);
+ MACIO_BIC(KEYLARGO_FCR0, KL0_IRDA_RESET);
+ }
+ UNLOCK(flags);
+ if (param & PMAC_SCC_FLAG_XMON)
+ macio->flags |= MACIO_FLAG_SCC_LOCKED;
+ } else {
+ if (macio->flags & MACIO_FLAG_SCC_LOCKED)
+ return -EPERM;
+ LOCK(flags);
+ fcr = MACIO_IN32(KEYLARGO_FCR0);
+ if (chan_mask & MACIO_FLAG_SCCA_ON)
+ fcr &= ~KL0_SCCA_ENABLE;
+ if (chan_mask & MACIO_FLAG_SCCB_ON) {
+ fcr &= ~KL0_SCCB_ENABLE;
+ /* Perform irda specific clears */
+ if ((param & 0xfff) == PMAC_SCC_IRDA) {
+ fcr &= ~KL0_IRDA_ENABLE;
+ fcr &= ~(KL0_IRDA_CLK32_ENABLE | KL0_IRDA_CLK19_ENABLE);
+ fcr &= ~(KL0_IRDA_FAST_CONNECT|KL0_IRDA_DEFAULT1|KL0_IRDA_DEFAULT0);
+ fcr &= ~(KL0_IRDA_SOURCE1_SEL|KL0_IRDA_SOURCE2_SEL|KL0_IRDA_HIGH_BAND);
+ }
+ }
+ MACIO_OUT32(KEYLARGO_FCR0, fcr);
+ if ((fcr & (KL0_SCCA_ENABLE | KL0_SCCB_ENABLE)) == 0) {
+ fcr &= ~KL0_SCC_CELL_ENABLE;
+ MACIO_OUT32(KEYLARGO_FCR0, fcr);
+ }
+ macio->flags &= ~(chan_mask);
+ UNLOCK(flags);
+ mdelay(10);
+ }
+ return 0;
+}
+
+static long
+core99_modem_enable(struct device_node *node, long param, long value)
+{
+ struct macio_chip* macio;
+ u8 gpio;
+ unsigned long flags;
+
+ /* Hack for internal USB modem */
+ if (node == NULL) {
+ if (macio_chips[0].type != macio_keylargo)
+ return -ENODEV;
+ node = macio_chips[0].of_node;
+ }
+ macio = macio_find(node, 0);
+ if (!macio)
+ return -ENODEV;
+ gpio = MACIO_IN8(KL_GPIO_MODEM_RESET);
+ gpio |= KEYLARGO_GPIO_OUTPUT_ENABLE;
+ gpio &= ~KEYLARGO_GPIO_OUTOUT_DATA;
+
+ if (!value) {
+ LOCK(flags);
+ MACIO_OUT8(KL_GPIO_MODEM_RESET, gpio);
+ UNLOCK(flags);
+ (void)MACIO_IN8(KL_GPIO_MODEM_RESET);
+ mdelay(250);
+ }
+ LOCK(flags);
+ if (value) {
+ MACIO_BIC(KEYLARGO_FCR2, KL2_ALT_DATA_OUT);
+ UNLOCK(flags);
+ (void)MACIO_IN32(KEYLARGO_FCR2);
+ mdelay(250);
+ } else {
+ MACIO_BIS(KEYLARGO_FCR2, KL2_ALT_DATA_OUT);
+ UNLOCK(flags);
+ }
+ if (value) {
+ LOCK(flags);
+ MACIO_OUT8(KL_GPIO_MODEM_RESET, gpio | KEYLARGO_GPIO_OUTOUT_DATA);
+ (void)MACIO_IN8(KL_GPIO_MODEM_RESET);
+ UNLOCK(flags); mdelay(250); LOCK(flags);
+ MACIO_OUT8(KL_GPIO_MODEM_RESET, gpio);
+ (void)MACIO_IN8(KL_GPIO_MODEM_RESET);
+ UNLOCK(flags); mdelay(250); LOCK(flags);
+ MACIO_OUT8(KL_GPIO_MODEM_RESET, gpio | KEYLARGO_GPIO_OUTOUT_DATA);
+ (void)MACIO_IN8(KL_GPIO_MODEM_RESET);
+ UNLOCK(flags); mdelay(250);
+ }
+ return 0;
+}
+
+static long
+pangea_modem_enable(struct device_node *node, long param, long value)
+{
+ struct macio_chip* macio;
+ u8 gpio;
+ unsigned long flags;
+
+ /* Hack for internal USB modem */
+ if (node == NULL) {
+ if (macio_chips[0].type != macio_pangea &&
+ macio_chips[0].type != macio_intrepid)
+ return -ENODEV;
+ node = macio_chips[0].of_node;
+ }
+ macio = macio_find(node, 0);
+ if (!macio)
+ return -ENODEV;
+ gpio = MACIO_IN8(KL_GPIO_MODEM_RESET);
+ gpio |= KEYLARGO_GPIO_OUTPUT_ENABLE;
+ gpio &= ~KEYLARGO_GPIO_OUTOUT_DATA;
+
+ if (!value) {
+ LOCK(flags);
+ MACIO_OUT8(KL_GPIO_MODEM_RESET, gpio);
+ UNLOCK(flags);
+ (void)MACIO_IN8(KL_GPIO_MODEM_RESET);
+ mdelay(250);
+ }
+ LOCK(flags);
+ if (value) {
+ MACIO_OUT8(KL_GPIO_MODEM_POWER,
+ KEYLARGO_GPIO_OUTPUT_ENABLE);
+ UNLOCK(flags);
+ (void)MACIO_IN32(KEYLARGO_FCR2);
+ mdelay(250);
+ } else {
+ MACIO_OUT8(KL_GPIO_MODEM_POWER,
+ KEYLARGO_GPIO_OUTPUT_ENABLE | KEYLARGO_GPIO_OUTOUT_DATA);
+ UNLOCK(flags);
+ }
+ if (value) {
+ LOCK(flags);
+ MACIO_OUT8(KL_GPIO_MODEM_RESET, gpio | KEYLARGO_GPIO_OUTOUT_DATA);
+ (void)MACIO_IN8(KL_GPIO_MODEM_RESET);
+ UNLOCK(flags); mdelay(250); LOCK(flags);
+ MACIO_OUT8(KL_GPIO_MODEM_RESET, gpio);
+ (void)MACIO_IN8(KL_GPIO_MODEM_RESET);
+ UNLOCK(flags); mdelay(250); LOCK(flags);
+ MACIO_OUT8(KL_GPIO_MODEM_RESET, gpio | KEYLARGO_GPIO_OUTOUT_DATA);
+ (void)MACIO_IN8(KL_GPIO_MODEM_RESET);
+ UNLOCK(flags); mdelay(250);
+ }
+ return 0;
+}
+
+static long
+core99_ata100_enable(struct device_node *node, long value)
+{
+ unsigned long flags;
+ struct pci_dev *pdev = NULL;
+ u8 pbus, pid;
+
+ if (uninorth_rev < 0x24)
+ return -ENODEV;
+
+ LOCK(flags);
+ if (value)
+ UN_BIS(UNI_N_CLOCK_CNTL, UNI_N_CLOCK_CNTL_ATA100);
+ else
+ UN_BIC(UNI_N_CLOCK_CNTL, UNI_N_CLOCK_CNTL_ATA100);
+ (void)UN_IN(UNI_N_CLOCK_CNTL);
+ UNLOCK(flags);
+ udelay(20);
+
+ if (value) {
+ if (pci_device_from_OF_node(node, &pbus, &pid) == 0)
+ pdev = pci_find_slot(pbus, pid);
+ if (pdev == NULL)
+ return 0;
+ pci_enable_device(pdev);
+ pci_set_master(pdev);
+ }
+ return 0;
+}
+
+static long
+core99_ide_enable(struct device_node *node, long param, long value)
+{
+ /* Bus ID 0 to 2 are KeyLargo based IDE, busID 3 is U2
+ * based ata-100
+ */
+ switch(param) {
+ case 0:
+ return simple_feature_tweak(node, macio_unknown,
+ KEYLARGO_FCR1, KL1_EIDE0_ENABLE, value);
+ case 1:
+ return simple_feature_tweak(node, macio_unknown,
+ KEYLARGO_FCR1, KL1_EIDE1_ENABLE, value);
+ case 2:
+ return simple_feature_tweak(node, macio_unknown,
+ KEYLARGO_FCR1, KL1_UIDE_ENABLE, value);
+ case 3:
+ return core99_ata100_enable(node, value);
+ default:
+ return -ENODEV;
+ }
+}
+
+static long
+core99_ide_reset(struct device_node *node, long param, long value)
+{
+ switch(param) {
+ case 0:
+ return simple_feature_tweak(node, macio_unknown,
+ KEYLARGO_FCR1, KL1_EIDE0_RESET_N, !value);
+ case 1:
+ return simple_feature_tweak(node, macio_unknown,
+ KEYLARGO_FCR1, KL1_EIDE1_RESET_N, !value);
+ case 2:
+ return simple_feature_tweak(node, macio_unknown,
+ KEYLARGO_FCR1, KL1_UIDE_RESET_N, !value);
+ default:
+ return -ENODEV;
+ }
+}
+
+static long
+core99_gmac_enable(struct device_node *node, long param, long value)
+{
+ unsigned long flags;
+
+ LOCK(flags);
+ if (value)
+ UN_BIS(UNI_N_CLOCK_CNTL, UNI_N_CLOCK_CNTL_GMAC);
+ else
+ UN_BIC(UNI_N_CLOCK_CNTL, UNI_N_CLOCK_CNTL_GMAC);
+ (void)UN_IN(UNI_N_CLOCK_CNTL);
+ UNLOCK(flags);
+ udelay(20);
+
+ return 0;
+}
+
+static long
+core99_gmac_phy_reset(struct device_node *node, long param, long value)
+{
+ unsigned long flags;
+ struct macio_chip *macio;
+
+ macio = &macio_chips[0];
+ if (macio->type != macio_keylargo && macio->type != macio_pangea &&
+ macio->type != macio_intrepid)
+ return -ENODEV;
+
+ LOCK(flags);
+ MACIO_OUT8(KL_GPIO_ETH_PHY_RESET, KEYLARGO_GPIO_OUTPUT_ENABLE);
+ (void)MACIO_IN8(KL_GPIO_ETH_PHY_RESET);
+ UNLOCK(flags);
+ mdelay(10);
+ LOCK(flags);
+ MACIO_OUT8(KL_GPIO_ETH_PHY_RESET, /*KEYLARGO_GPIO_OUTPUT_ENABLE | */
+ KEYLARGO_GPIO_OUTOUT_DATA);
+ UNLOCK(flags);
+ mdelay(10);
+
+ return 0;
+}
+
+static long
+core99_sound_chip_enable(struct device_node *node, long param, long value)
+{
+ struct macio_chip* macio;
+ unsigned long flags;
+
+ macio = macio_find(node, 0);
+ if (!macio)
+ return -ENODEV;
+
+ /* Do a better probe code, screamer G4 desktops &
+ * iMacs can do that too, add a recalibrate in
+ * the driver as well
+ */
+ if (pmac_mb.model_id == PMAC_TYPE_PISMO ||
+ pmac_mb.model_id == PMAC_TYPE_TITANIUM) {
+ LOCK(flags);
+ if (value)
+ MACIO_OUT8(KL_GPIO_SOUND_POWER,
+ KEYLARGO_GPIO_OUTPUT_ENABLE |
+ KEYLARGO_GPIO_OUTOUT_DATA);
+ else
+ MACIO_OUT8(KL_GPIO_SOUND_POWER,
+ KEYLARGO_GPIO_OUTPUT_ENABLE);
+ (void)MACIO_IN8(KL_GPIO_SOUND_POWER);
+ UNLOCK(flags);
+ }
+ return 0;
+}
+
+static long
+core99_airport_enable(struct device_node *node, long param, long value)
+{
+ struct macio_chip* macio;
+ unsigned long flags;
+ int state;
+
+ macio = macio_find(node, 0);
+ if (!macio)
+ return -ENODEV;
+
+ /* Hint: we allow passing of macio itself for the sake of the
+ * sleep code
+ */
+ if (node != macio->of_node &&
+ (!node->parent || node->parent != macio->of_node))
+ return -ENODEV;
+ state = (macio->flags & MACIO_FLAG_AIRPORT_ON) != 0;
+ if (value == state)
+ return 0;
+ if (value) {
+ /* This code is a reproduction of OF enable-cardslot
+ * and init-wireless methods, slightly hacked until
+ * I got it working.
+ */
+ LOCK(flags);
+ MACIO_OUT8(KEYLARGO_GPIO_0+0xf, 5);
+ (void)MACIO_IN8(KEYLARGO_GPIO_0+0xf);
+ UNLOCK(flags);
+ mdelay(10);
+ LOCK(flags);
+ MACIO_OUT8(KEYLARGO_GPIO_0+0xf, 4);
+ (void)MACIO_IN8(KEYLARGO_GPIO_0+0xf);
+ UNLOCK(flags);
+
+ mdelay(10);
+
+ LOCK(flags);
+ MACIO_BIC(KEYLARGO_FCR2, KL2_CARDSEL_16);
+ (void)MACIO_IN32(KEYLARGO_FCR2);
+ udelay(10);
+ MACIO_OUT8(KEYLARGO_GPIO_EXTINT_0+0xb, 0);
+ (void)MACIO_IN8(KEYLARGO_GPIO_EXTINT_0+0xb);
+ udelay(10);
+ MACIO_OUT8(KEYLARGO_GPIO_EXTINT_0+0xa, 0x28);
+ (void)MACIO_IN8(KEYLARGO_GPIO_EXTINT_0+0xa);
+ udelay(10);
+ MACIO_OUT8(KEYLARGO_GPIO_EXTINT_0+0xd, 0x28);
+ (void)MACIO_IN8(KEYLARGO_GPIO_EXTINT_0+0xd);
+ udelay(10);
+ MACIO_OUT8(KEYLARGO_GPIO_0+0xd, 0x28);
+ (void)MACIO_IN8(KEYLARGO_GPIO_0+0xd);
+ udelay(10);
+ MACIO_OUT8(KEYLARGO_GPIO_0+0xe, 0x28);
+ (void)MACIO_IN8(KEYLARGO_GPIO_0+0xe);
+ UNLOCK(flags);
+ udelay(10);
+ MACIO_OUT32(0x1c000, 0);
+ mdelay(1);
+ MACIO_OUT8(0x1a3e0, 0x41);
+ (void)MACIO_IN8(0x1a3e0);
+ udelay(10);
+ LOCK(flags);
+ MACIO_BIS(KEYLARGO_FCR2, KL2_CARDSEL_16);
+ (void)MACIO_IN32(KEYLARGO_FCR2);
+ UNLOCK(flags);
+ mdelay(100);
+
+ macio->flags |= MACIO_FLAG_AIRPORT_ON;
+ } else {
+ LOCK(flags);
+ MACIO_BIC(KEYLARGO_FCR2, KL2_CARDSEL_16);
+ (void)MACIO_IN32(KEYLARGO_FCR2);
+ MACIO_OUT8(KL_GPIO_AIRPORT_0, 0);
+ MACIO_OUT8(KL_GPIO_AIRPORT_1, 0);
+ MACIO_OUT8(KL_GPIO_AIRPORT_2, 0);
+ MACIO_OUT8(KL_GPIO_AIRPORT_3, 0);
+ MACIO_OUT8(KL_GPIO_AIRPORT_4, 0);
+ (void)MACIO_IN8(KL_GPIO_AIRPORT_4);
+ UNLOCK(flags);
+
+ macio->flags &= ~MACIO_FLAG_AIRPORT_ON;
+ }
+ return 0;
+}
+
+#ifdef CONFIG_SMP
+static long
+core99_reset_cpu(struct device_node *node, long param, long value)
+{
+ unsigned int reset_io = 0;
+ unsigned long flags;
+ struct macio_chip *macio;
+ struct device_node *np;
+ const int dflt_reset_lines[] = { KL_GPIO_RESET_CPU0,
+ KL_GPIO_RESET_CPU1,
+ KL_GPIO_RESET_CPU2,
+ KL_GPIO_RESET_CPU3 };
+
+ macio = &macio_chips[0];
+ if (macio->type != macio_keylargo)
+ return -ENODEV;
+
+ np = find_path_device("/cpus");
+ if (np == NULL)
+ return -ENODEV;
+ for (np = np->child; np != NULL; np = np->sibling) {
+ u32 *num = (u32 *)get_property(np, "reg", NULL);
+ u32 *rst = (u32 *)get_property(np, "soft-reset", NULL);
+ if (num == NULL || rst == NULL)
+ continue;
+ if (param == *num) {
+ reset_io = *rst;
+ break;
+ }
+ }
+ if (np == NULL || reset_io == 0)
+ reset_io = dflt_reset_lines[param];
+
+ LOCK(flags);
+ MACIO_OUT8(reset_io, KEYLARGO_GPIO_OUTPUT_ENABLE);
+ (void)MACIO_IN8(reset_io);
+ udelay(1);
+ MACIO_OUT8(reset_io, 0);
+ (void)MACIO_IN8(reset_io);
+ UNLOCK(flags);
+
+ return 0;
+}
+#endif /* CONFIG_SMP */
+
+static long
+core99_usb_enable(struct device_node *node, long param, long value)
+{
+ struct macio_chip *macio;
+ unsigned long flags;
+ char *prop;
+ int number;
+ u32 reg;
+
+ macio = &macio_chips[0];
+ if (macio->type != macio_keylargo && macio->type != macio_pangea &&
+ macio->type != macio_intrepid)
+ return -ENODEV;
+
+ prop = (char *)get_property(node, "AAPL,clock-id", NULL);
+ if (!prop)
+ return -ENODEV;
+ if (strncmp(prop, "usb0u048", 8) == 0)
+ number = 0;
+ else if (strncmp(prop, "usb1u148", 8) == 0)
+ number = 2;
+ else if (strncmp(prop, "usb2u248", 8) == 0)
+ number = 4;
+ else
+ return -ENODEV;
+
+ /* Sorry for the brute-force locking, but this is only used during
+ * sleep and the timing seem to be critical
+ */
+ LOCK(flags);
+ if (value) {
+ /* Turn ON */
+ if (number == 0) {
+ MACIO_BIC(KEYLARGO_FCR0, (KL0_USB0_PAD_SUSPEND0 | KL0_USB0_PAD_SUSPEND1));
+ (void)MACIO_IN32(KEYLARGO_FCR0);
+ UNLOCK(flags);
+ mdelay(1);
+ LOCK(flags);
+ MACIO_BIS(KEYLARGO_FCR0, KL0_USB0_CELL_ENABLE);
+ } else if (number == 2) {
+ MACIO_BIC(KEYLARGO_FCR0, (KL0_USB1_PAD_SUSPEND0 | KL0_USB1_PAD_SUSPEND1));
+ UNLOCK(flags);
+ (void)MACIO_IN32(KEYLARGO_FCR0);
+ mdelay(1);
+ LOCK(flags);
+ MACIO_BIS(KEYLARGO_FCR0, KL0_USB1_CELL_ENABLE);
+ } else if (number == 4) {
+ MACIO_BIC(KEYLARGO_FCR1, (KL1_USB2_PAD_SUSPEND0 | KL1_USB2_PAD_SUSPEND1));
+ UNLOCK(flags);
+ (void)MACIO_IN32(KEYLARGO_FCR1);
+ mdelay(1);
+ LOCK(flags);
+ MACIO_BIS(KEYLARGO_FCR1, KL1_USB2_CELL_ENABLE);
+ }
+ if (number < 4) {
+ reg = MACIO_IN32(KEYLARGO_FCR4);
+ reg &= ~(KL4_PORT_WAKEUP_ENABLE(number) | KL4_PORT_RESUME_WAKE_EN(number) |
+ KL4_PORT_CONNECT_WAKE_EN(number) | KL4_PORT_DISCONNECT_WAKE_EN(number));
+ reg &= ~(KL4_PORT_WAKEUP_ENABLE(number+1) | KL4_PORT_RESUME_WAKE_EN(number+1) |
+ KL4_PORT_CONNECT_WAKE_EN(number+1) | KL4_PORT_DISCONNECT_WAKE_EN(number+1));
+ MACIO_OUT32(KEYLARGO_FCR4, reg);
+ (void)MACIO_IN32(KEYLARGO_FCR4);
+ udelay(10);
+ } else {
+ reg = MACIO_IN32(KEYLARGO_FCR3);
+ reg &= ~(KL3_IT_PORT_WAKEUP_ENABLE(0) | KL3_IT_PORT_RESUME_WAKE_EN(0) |
+ KL3_IT_PORT_CONNECT_WAKE_EN(0) | KL3_IT_PORT_DISCONNECT_WAKE_EN(0));
+ reg &= ~(KL3_IT_PORT_WAKEUP_ENABLE(1) | KL3_IT_PORT_RESUME_WAKE_EN(1) |
+ KL3_IT_PORT_CONNECT_WAKE_EN(1) | KL3_IT_PORT_DISCONNECT_WAKE_EN(1));
+ MACIO_OUT32(KEYLARGO_FCR3, reg);
+ (void)MACIO_IN32(KEYLARGO_FCR3);
+ udelay(10);
+ }
+ if (macio->type == macio_intrepid) {
+ /* wait for clock stopped bits to clear */
+ u32 test0 = 0, test1 = 0;
+ u32 status0, status1;
+ int timeout = 1000;
+
+ UNLOCK(flags);
+ switch (number) {
+ case 0:
+ test0 = UNI_N_CLOCK_STOPPED_USB0;
+ test1 = UNI_N_CLOCK_STOPPED_USB0PCI;
+ break;
+ case 2:
+ test0 = UNI_N_CLOCK_STOPPED_USB1;
+ test1 = UNI_N_CLOCK_STOPPED_USB1PCI;
+ break;
+ case 4:
+ test0 = UNI_N_CLOCK_STOPPED_USB2;
+ test1 = UNI_N_CLOCK_STOPPED_USB2PCI;
+ break;
+ }
+ do {
+ if (--timeout <= 0) {
+ printk(KERN_ERR "core99_usb_enable: "
+ "Timeout waiting for clocks\n");
+ break;
+ }
+ mdelay(1);
+ status0 = UN_IN(UNI_N_CLOCK_STOP_STATUS0);
+ status1 = UN_IN(UNI_N_CLOCK_STOP_STATUS1);
+ } while ((status0 & test0) | (status1 & test1));
+ LOCK(flags);
+ }
+ } else {
+ /* Turn OFF */
+ if (number < 4) {
+ reg = MACIO_IN32(KEYLARGO_FCR4);
+ reg |= KL4_PORT_WAKEUP_ENABLE(number) | KL4_PORT_RESUME_WAKE_EN(number) |
+ KL4_PORT_CONNECT_WAKE_EN(number) | KL4_PORT_DISCONNECT_WAKE_EN(number);
+ reg |= KL4_PORT_WAKEUP_ENABLE(number+1) | KL4_PORT_RESUME_WAKE_EN(number+1) |
+ KL4_PORT_CONNECT_WAKE_EN(number+1) | KL4_PORT_DISCONNECT_WAKE_EN(number+1);
+ MACIO_OUT32(KEYLARGO_FCR4, reg);
+ (void)MACIO_IN32(KEYLARGO_FCR4);
+ udelay(1);
+ } else {
+ reg = MACIO_IN32(KEYLARGO_FCR3);
+ reg |= KL3_IT_PORT_WAKEUP_ENABLE(0) | KL3_IT_PORT_RESUME_WAKE_EN(0) |
+ KL3_IT_PORT_CONNECT_WAKE_EN(0) | KL3_IT_PORT_DISCONNECT_WAKE_EN(0);
+ reg |= KL3_IT_PORT_WAKEUP_ENABLE(1) | KL3_IT_PORT_RESUME_WAKE_EN(1) |
+ KL3_IT_PORT_CONNECT_WAKE_EN(1) | KL3_IT_PORT_DISCONNECT_WAKE_EN(1);
+ MACIO_OUT32(KEYLARGO_FCR3, reg);
+ (void)MACIO_IN32(KEYLARGO_FCR3);
+ udelay(1);
+ }
+ if (number == 0) {
+ if (macio->type != macio_intrepid)
+ MACIO_BIC(KEYLARGO_FCR0, KL0_USB0_CELL_ENABLE);
+ (void)MACIO_IN32(KEYLARGO_FCR0);
+ udelay(1);
+ MACIO_BIS(KEYLARGO_FCR0, (KL0_USB0_PAD_SUSPEND0 | KL0_USB0_PAD_SUSPEND1));
+ (void)MACIO_IN32(KEYLARGO_FCR0);
+ } else if (number == 2) {
+ if (macio->type != macio_intrepid)
+ MACIO_BIC(KEYLARGO_FCR0, KL0_USB1_CELL_ENABLE);
+ (void)MACIO_IN32(KEYLARGO_FCR0);
+ udelay(1);
+ MACIO_BIS(KEYLARGO_FCR0, (KL0_USB1_PAD_SUSPEND0 | KL0_USB1_PAD_SUSPEND1));
+ (void)MACIO_IN32(KEYLARGO_FCR0);
+ } else if (number == 4) {
+ udelay(1);
+ MACIO_BIS(KEYLARGO_FCR1, (KL1_USB2_PAD_SUSPEND0 | KL1_USB2_PAD_SUSPEND1));
+ (void)MACIO_IN32(KEYLARGO_FCR1);
+ }
+ udelay(1);
+ }
+ UNLOCK(flags);
+
+ return 0;
+}
+
+static long
+core99_firewire_enable(struct device_node *node, long param, long value)
+{
+ unsigned long flags;
+ struct macio_chip *macio;
+
+ macio = &macio_chips[0];
+ if (macio->type != macio_keylargo && macio->type != macio_pangea &&
+ macio->type != macio_intrepid)
+ return -ENODEV;
+ if (!(macio->flags & MACIO_FLAG_FW_SUPPORTED))
+ return -ENODEV;
+
+ LOCK(flags);
+ if (value) {
+ UN_BIS(UNI_N_CLOCK_CNTL, UNI_N_CLOCK_CNTL_FW);
+ (void)UN_IN(UNI_N_CLOCK_CNTL);
+ } else {
+ UN_BIC(UNI_N_CLOCK_CNTL, UNI_N_CLOCK_CNTL_FW);
+ (void)UN_IN(UNI_N_CLOCK_CNTL);
+ }
+ UNLOCK(flags);
+ mdelay(1);
+
+ return 0;
+}
+
+static long
+core99_firewire_cable_power(struct device_node *node, long param, long value)
+{
+ unsigned long flags;
+ struct macio_chip *macio;
+
+ /* Trick: we allow NULL node */
+ if ((pmac_mb.board_flags & PMAC_MB_HAS_FW_POWER) == 0)
+ return -ENODEV;
+ macio = &macio_chips[0];
+ if (macio->type != macio_keylargo && macio->type != macio_pangea &&
+ macio->type != macio_intrepid)
+ return -ENODEV;
+ if (!(macio->flags & MACIO_FLAG_FW_SUPPORTED))
+ return -ENODEV;
+
+ LOCK(flags);
+ if (value) {
+ MACIO_OUT8(KL_GPIO_FW_CABLE_POWER , 0);
+ MACIO_IN8(KL_GPIO_FW_CABLE_POWER);
+ udelay(10);
+ } else {
+ MACIO_OUT8(KL_GPIO_FW_CABLE_POWER , 4);
+ MACIO_IN8(KL_GPIO_FW_CABLE_POWER); udelay(10);
+ }
+ UNLOCK(flags);
+ mdelay(1);
+
+ return 0;
+}
+
+static long
+intrepid_aack_delay_enable(struct device_node *node, long param, long value)
+{
+ unsigned long flags;
+
+ if (uninorth_rev < 0xd2)
+ return -ENODEV;
+
+ LOCK(flags);
+ if (param)
+ UN_BIS(UNI_N_AACK_DELAY, UNI_N_AACK_DELAY_ENABLE);
+ else
+ UN_BIC(UNI_N_AACK_DELAY, UNI_N_AACK_DELAY_ENABLE);
+ UNLOCK(flags);
+
+ return 0;
+}
+
+
+#endif /* CONFIG_POWER4 */
+
+static long
+core99_read_gpio(struct device_node *node, long param, long value)
+{
+ struct macio_chip *macio = &macio_chips[0];
+
+ return MACIO_IN8(param);
+}
+
+
+static long
+core99_write_gpio(struct device_node *node, long param, long value)
+{
+ struct macio_chip *macio = &macio_chips[0];
+
+ MACIO_OUT8(param, (u8)(value & 0xff));
+ return 0;
+}
+
+#ifdef CONFIG_POWER4
+static long g5_gmac_enable(struct device_node *node, long param, long value)
+{
+ struct macio_chip *macio = &macio_chips[0];
+ unsigned long flags;
+
+ if (node == NULL)
+ return -ENODEV;
+
+ LOCK(flags);
+ if (value) {
+ MACIO_BIS(KEYLARGO_FCR1, K2_FCR1_GMAC_CLK_ENABLE);
+ mb();
+ k2_skiplist[0] = NULL;
+ } else {
+ k2_skiplist[0] = node;
+ mb();
+ MACIO_BIC(KEYLARGO_FCR1, K2_FCR1_GMAC_CLK_ENABLE);
+ }
+
+ UNLOCK(flags);
+ mdelay(1);
+
+ return 0;
+}
+
+static long g5_fw_enable(struct device_node *node, long param, long value)
+{
+ struct macio_chip *macio = &macio_chips[0];
+ unsigned long flags;
+
+ if (node == NULL)
+ return -ENODEV;
+
+ LOCK(flags);
+ if (value) {
+ MACIO_BIS(KEYLARGO_FCR1, K2_FCR1_FW_CLK_ENABLE);
+ mb();
+ k2_skiplist[1] = NULL;
+ } else {
+ k2_skiplist[1] = node;
+ mb();
+ MACIO_BIC(KEYLARGO_FCR1, K2_FCR1_FW_CLK_ENABLE);
+ }
+
+ UNLOCK(flags);
+ mdelay(1);
+
+ return 0;
+}
+
+static long g5_mpic_enable(struct device_node *node, long param, long value)
+{
+ unsigned long flags;
+
+ if (node->parent == NULL || strcmp(node->parent->name, "u3"))
+ return 0;
+
+ LOCK(flags);
+ UN_BIS(U3_TOGGLE_REG, U3_MPIC_RESET | U3_MPIC_OUTPUT_ENABLE);
+ UNLOCK(flags);
+
+ return 0;
+}
+
+static long g5_eth_phy_reset(struct device_node *node, long param, long value)
+{
+ struct macio_chip *macio = &macio_chips[0];
+ struct device_node *phy;
+ int need_reset;
+
+ /*
+ * We must not reset the combo PHYs, only the BCM5221 found in
+ * the iMac G5.
+ */
+ phy = of_get_next_child(node, NULL);
+ if (!phy)
+ return -ENODEV;
+ need_reset = device_is_compatible(phy, "B5221");
+ of_node_put(phy);
+ if (!need_reset)
+ return 0;
+
+ /* PHY reset is GPIO 29, not in device-tree unfortunately */
+ MACIO_OUT8(K2_GPIO_EXTINT_0 + 29,
+ KEYLARGO_GPIO_OUTPUT_ENABLE | KEYLARGO_GPIO_OUTOUT_DATA);
+ /* Thankfully, this is now always called at a time when we can
+ * schedule by sungem.
+ */
+ msleep(10);
+ MACIO_OUT8(K2_GPIO_EXTINT_0 + 29, 0);
+
+ return 0;
+}
+
+static long g5_i2s_enable(struct device_node *node, long param, long value)
+{
+ /* Very crude implementation for now */
+ struct macio_chip *macio = &macio_chips[0];
+ unsigned long flags;
+
+ if (value == 0)
+ return 0; /* don't disable yet */
+
+ LOCK(flags);
+ MACIO_BIS(KEYLARGO_FCR3, KL3_CLK45_ENABLE | KL3_CLK49_ENABLE |
+ KL3_I2S0_CLK18_ENABLE);
+ udelay(10);
+ MACIO_BIS(KEYLARGO_FCR1, K2_FCR1_I2S0_CELL_ENABLE |
+ K2_FCR1_I2S0_CLK_ENABLE_BIT | K2_FCR1_I2S0_ENABLE);
+ udelay(10);
+ MACIO_BIC(KEYLARGO_FCR1, K2_FCR1_I2S0_RESET);
+ UNLOCK(flags);
+ udelay(10);
+
+ return 0;
+}
+
+
+#ifdef CONFIG_SMP
+static long g5_reset_cpu(struct device_node *node, long param, long value)
+{
+ unsigned int reset_io = 0;
+ unsigned long flags;
+ struct macio_chip *macio;
+ struct device_node *np;
+
+ macio = &macio_chips[0];
+ if (macio->type != macio_keylargo2)
+ return -ENODEV;
+
+ np = find_path_device("/cpus");
+ if (np == NULL)
+ return -ENODEV;
+ for (np = np->child; np != NULL; np = np->sibling) {
+ u32 *num = (u32 *)get_property(np, "reg", NULL);
+ u32 *rst = (u32 *)get_property(np, "soft-reset", NULL);
+ if (num == NULL || rst == NULL)
+ continue;
+ if (param == *num) {
+ reset_io = *rst;
+ break;
+ }
+ }
+ if (np == NULL || reset_io == 0)
+ return -ENODEV;
+
+ LOCK(flags);
+ MACIO_OUT8(reset_io, KEYLARGO_GPIO_OUTPUT_ENABLE);
+ (void)MACIO_IN8(reset_io);
+ udelay(1);
+ MACIO_OUT8(reset_io, 0);
+ (void)MACIO_IN8(reset_io);
+ UNLOCK(flags);
+
+ return 0;
+}
+#endif /* CONFIG_SMP */
+
+/*
+ * This can be called from pmac_smp so isn't static
+ *
+ * This takes the second CPU off the bus on dual CPU machines
+ * running UP
+ */
+void g5_phy_disable_cpu1(void)
+{
+ UN_OUT(U3_API_PHY_CONFIG_1, 0);
+}
+#endif /* CONFIG_POWER4 */
+
+#ifndef CONFIG_POWER4
+
+static void
+keylargo_shutdown(struct macio_chip *macio, int sleep_mode)
+{
+ u32 temp;
+
+ if (sleep_mode) {
+ mdelay(1);
+ MACIO_BIS(KEYLARGO_FCR0, KL0_USB_REF_SUSPEND);
+ (void)MACIO_IN32(KEYLARGO_FCR0);
+ mdelay(1);
+ }
+
+ MACIO_BIC(KEYLARGO_FCR0,KL0_SCCA_ENABLE | KL0_SCCB_ENABLE |
+ KL0_SCC_CELL_ENABLE |
+ KL0_IRDA_ENABLE | KL0_IRDA_CLK32_ENABLE |
+ KL0_IRDA_CLK19_ENABLE);
+
+ MACIO_BIC(KEYLARGO_MBCR, KL_MBCR_MB0_DEV_MASK);
+ MACIO_BIS(KEYLARGO_MBCR, KL_MBCR_MB0_IDE_ENABLE);
+
+ MACIO_BIC(KEYLARGO_FCR1,
+ KL1_AUDIO_SEL_22MCLK | KL1_AUDIO_CLK_ENABLE_BIT |
+ KL1_AUDIO_CLK_OUT_ENABLE | KL1_AUDIO_CELL_ENABLE |
+ KL1_I2S0_CELL_ENABLE | KL1_I2S0_CLK_ENABLE_BIT |
+ KL1_I2S0_ENABLE | KL1_I2S1_CELL_ENABLE |
+ KL1_I2S1_CLK_ENABLE_BIT | KL1_I2S1_ENABLE |
+ KL1_EIDE0_ENABLE | KL1_EIDE0_RESET_N |
+ KL1_EIDE1_ENABLE | KL1_EIDE1_RESET_N |
+ KL1_UIDE_ENABLE);
+
+ MACIO_BIS(KEYLARGO_FCR2, KL2_ALT_DATA_OUT);
+ MACIO_BIC(KEYLARGO_FCR2, KL2_IOBUS_ENABLE);
+
+ temp = MACIO_IN32(KEYLARGO_FCR3);
+ if (macio->rev >= 2) {
+ temp |= KL3_SHUTDOWN_PLL2X;
+ if (sleep_mode)
+ temp |= KL3_SHUTDOWN_PLL_TOTAL;
+ }
+
+ temp |= KL3_SHUTDOWN_PLLKW6 | KL3_SHUTDOWN_PLLKW4 |
+ KL3_SHUTDOWN_PLLKW35;
+ if (sleep_mode)
+ temp |= KL3_SHUTDOWN_PLLKW12;
+ temp &= ~(KL3_CLK66_ENABLE | KL3_CLK49_ENABLE | KL3_CLK45_ENABLE
+ | KL3_CLK31_ENABLE | KL3_I2S1_CLK18_ENABLE | KL3_I2S0_CLK18_ENABLE);
+ if (sleep_mode)
+ temp &= ~(KL3_TIMER_CLK18_ENABLE | KL3_VIA_CLK16_ENABLE);
+ MACIO_OUT32(KEYLARGO_FCR3, temp);
+
+ /* Flush posted writes & wait a bit */
+ (void)MACIO_IN32(KEYLARGO_FCR0); mdelay(1);
+}
+
+static void
+pangea_shutdown(struct macio_chip *macio, int sleep_mode)
+{
+ u32 temp;
+
+ MACIO_BIC(KEYLARGO_FCR0,KL0_SCCA_ENABLE | KL0_SCCB_ENABLE |
+ KL0_SCC_CELL_ENABLE |
+ KL0_USB0_CELL_ENABLE | KL0_USB1_CELL_ENABLE);
+
+ MACIO_BIC(KEYLARGO_FCR1,
+ KL1_AUDIO_SEL_22MCLK | KL1_AUDIO_CLK_ENABLE_BIT |
+ KL1_AUDIO_CLK_OUT_ENABLE | KL1_AUDIO_CELL_ENABLE |
+ KL1_I2S0_CELL_ENABLE | KL1_I2S0_CLK_ENABLE_BIT |
+ KL1_I2S0_ENABLE | KL1_I2S1_CELL_ENABLE |
+ KL1_I2S1_CLK_ENABLE_BIT | KL1_I2S1_ENABLE |
+ KL1_UIDE_ENABLE);
+ if (pmac_mb.board_flags & PMAC_MB_MOBILE)
+ MACIO_BIC(KEYLARGO_FCR1, KL1_UIDE_RESET_N);
+
+ MACIO_BIS(KEYLARGO_FCR2, KL2_ALT_DATA_OUT);
+
+ temp = MACIO_IN32(KEYLARGO_FCR3);
+ temp |= KL3_SHUTDOWN_PLLKW6 | KL3_SHUTDOWN_PLLKW4 |
+ KL3_SHUTDOWN_PLLKW35;
+ temp &= ~(KL3_CLK49_ENABLE | KL3_CLK45_ENABLE | KL3_CLK31_ENABLE
+ | KL3_I2S0_CLK18_ENABLE | KL3_I2S1_CLK18_ENABLE);
+ if (sleep_mode)
+ temp &= ~(KL3_VIA_CLK16_ENABLE | KL3_TIMER_CLK18_ENABLE);
+ MACIO_OUT32(KEYLARGO_FCR3, temp);
+
+ /* Flush posted writes & wait a bit */
+ (void)MACIO_IN32(KEYLARGO_FCR0); mdelay(1);
+}
+
+static void
+intrepid_shutdown(struct macio_chip *macio, int sleep_mode)
+{
+ u32 temp;
+
+ MACIO_BIC(KEYLARGO_FCR0,KL0_SCCA_ENABLE | KL0_SCCB_ENABLE |
+ KL0_SCC_CELL_ENABLE);
+
+ MACIO_BIC(KEYLARGO_FCR1,
+ /*KL1_USB2_CELL_ENABLE |*/
+ KL1_I2S0_CELL_ENABLE | KL1_I2S0_CLK_ENABLE_BIT |
+ KL1_I2S0_ENABLE | KL1_I2S1_CELL_ENABLE |
+ KL1_I2S1_CLK_ENABLE_BIT | KL1_I2S1_ENABLE);
+ if (pmac_mb.board_flags & PMAC_MB_MOBILE)
+ MACIO_BIC(KEYLARGO_FCR1, KL1_UIDE_RESET_N);
+
+ temp = MACIO_IN32(KEYLARGO_FCR3);
+ temp &= ~(KL3_CLK49_ENABLE | KL3_CLK45_ENABLE |
+ KL3_I2S1_CLK18_ENABLE | KL3_I2S0_CLK18_ENABLE);
+ if (sleep_mode)
+ temp &= ~(KL3_TIMER_CLK18_ENABLE | KL3_IT_VIA_CLK32_ENABLE);
+ MACIO_OUT32(KEYLARGO_FCR3, temp);
+
+ /* Flush posted writes & wait a bit */
+ (void)MACIO_IN32(KEYLARGO_FCR0);
+ mdelay(10);
+}
+
+
+void pmac_tweak_clock_spreading(int enable)
+{
+ struct macio_chip *macio = &macio_chips[0];
+
+ /* Hack for doing clock spreading on some machines PowerBooks and
+ * iBooks. This implements the "platform-do-clockspreading" OF
+ * property as decoded manually on various models. For safety, we also
+ * check the product ID in the device-tree in cases we'll whack the i2c
+ * chip to make reasonably sure we won't set wrong values in there
+ *
+ * Of course, ultimately, we have to implement a real parser for
+ * the platform-do-* stuff...
+ */
+
+ if (macio->type == macio_intrepid) {
+ if (enable)
+ UN_OUT(UNI_N_CLOCK_SPREADING, 2);
+ else
+ UN_OUT(UNI_N_CLOCK_SPREADING, 0);
+ mdelay(40);
+ }
+
+ while (machine_is_compatible("PowerBook5,2") ||
+ machine_is_compatible("PowerBook5,3") ||
+ machine_is_compatible("PowerBook6,2") ||
+ machine_is_compatible("PowerBook6,3")) {
+ struct device_node *ui2c = of_find_node_by_type(NULL, "i2c");
+ struct device_node *dt = of_find_node_by_name(NULL, "device-tree");
+ u8 buffer[9];
+ u32 *productID;
+ int i, rc, changed = 0;
+
+ if (dt == NULL)
+ break;
+ productID = (u32 *)get_property(dt, "pid#", NULL);
+ if (productID == NULL)
+ break;
+ while(ui2c) {
+ struct device_node *p = of_get_parent(ui2c);
+ if (p && !strcmp(p->name, "uni-n"))
+ break;
+ ui2c = of_find_node_by_type(ui2c, "i2c");
+ }
+ if (ui2c == NULL)
+ break;
+ DBG("Trying to bump clock speed for PID: %08x...\n", *productID);
+ rc = pmac_low_i2c_open(ui2c, 1);
+ if (rc != 0)
+ break;
+ pmac_low_i2c_setmode(ui2c, pmac_low_i2c_mode_combined);
+ rc = pmac_low_i2c_xfer(ui2c, 0xd2 | pmac_low_i2c_read, 0x80, buffer, 9);
+ DBG("read result: %d,", rc);
+ if (rc != 0) {
+ pmac_low_i2c_close(ui2c);
+ break;
+ }
+ for (i=0; i<9; i++)
+ DBG(" %02x", buffer[i]);
+ DBG("\n");
+
+ switch(*productID) {
+ case 0x1182: /* AlBook 12" rev 2 */
+ case 0x1183: /* iBook G4 12" */
+ buffer[0] = (buffer[0] & 0x8f) | 0x70;
+ buffer[2] = (buffer[2] & 0x7f) | 0x00;
+ buffer[5] = (buffer[5] & 0x80) | 0x31;
+ buffer[6] = (buffer[6] & 0x40) | 0xb0;
+ buffer[7] = (buffer[7] & 0x00) | (enable ? 0xc0 : 0xba);
+ buffer[8] = (buffer[8] & 0x00) | 0x30;
+ changed = 1;
+ break;
+ case 0x3142: /* AlBook 15" (ATI M10) */
+ case 0x3143: /* AlBook 17" (ATI M10) */
+ buffer[0] = (buffer[0] & 0xaf) | 0x50;
+ buffer[2] = (buffer[2] & 0x7f) | 0x00;
+ buffer[5] = (buffer[5] & 0x80) | 0x31;
+ buffer[6] = (buffer[6] & 0x40) | 0xb0;
+ buffer[7] = (buffer[7] & 0x00) | (enable ? 0xd0 : 0xc0);
+ buffer[8] = (buffer[8] & 0x00) | 0x30;
+ changed = 1;
+ break;
+ default:
+ DBG("i2c-hwclock: Machine model not handled\n");
+ break;
+ }
+ if (!changed) {
+ pmac_low_i2c_close(ui2c);
+ break;
+ }
+ pmac_low_i2c_setmode(ui2c, pmac_low_i2c_mode_stdsub);
+ rc = pmac_low_i2c_xfer(ui2c, 0xd2 | pmac_low_i2c_write, 0x80, buffer, 9);
+ DBG("write result: %d,", rc);
+ pmac_low_i2c_setmode(ui2c, pmac_low_i2c_mode_combined);
+ rc = pmac_low_i2c_xfer(ui2c, 0xd2 | pmac_low_i2c_read, 0x80, buffer, 9);
+ DBG("read result: %d,", rc);
+ if (rc != 0) {
+ pmac_low_i2c_close(ui2c);
+ break;
+ }
+ for (i=0; i<9; i++)
+ DBG(" %02x", buffer[i]);
+ pmac_low_i2c_close(ui2c);
+ break;
+ }
+}
+
+
+static int
+core99_sleep(void)
+{
+ struct macio_chip *macio;
+ int i;
+
+ macio = &macio_chips[0];
+ if (macio->type != macio_keylargo && macio->type != macio_pangea &&
+ macio->type != macio_intrepid)
+ return -ENODEV;
+
+ /* We power off the wireless slot in case it was not done
+ * by the driver. We don't power it on automatically however
+ */
+ if (macio->flags & MACIO_FLAG_AIRPORT_ON)
+ core99_airport_enable(macio->of_node, 0, 0);
+
+ /* We power off the FW cable. Should be done by the driver... */
+ if (macio->flags & MACIO_FLAG_FW_SUPPORTED) {
+ core99_firewire_enable(NULL, 0, 0);
+ core99_firewire_cable_power(NULL, 0, 0);
+ }
+
+ /* We make sure int. modem is off (in case driver lost it) */
+ if (macio->type == macio_keylargo)
+ core99_modem_enable(macio->of_node, 0, 0);
+ else
+ pangea_modem_enable(macio->of_node, 0, 0);
+
+ /* We make sure the sound is off as well */
+ core99_sound_chip_enable(macio->of_node, 0, 0);
+
+ /*
+ * Save various bits of KeyLargo
+ */
+
+ /* Save the state of the various GPIOs */
+ save_gpio_levels[0] = MACIO_IN32(KEYLARGO_GPIO_LEVELS0);
+ save_gpio_levels[1] = MACIO_IN32(KEYLARGO_GPIO_LEVELS1);
+ for (i=0; i<KEYLARGO_GPIO_EXTINT_CNT; i++)
+ save_gpio_extint[i] = MACIO_IN8(KEYLARGO_GPIO_EXTINT_0+i);
+ for (i=0; i<KEYLARGO_GPIO_CNT; i++)
+ save_gpio_normal[i] = MACIO_IN8(KEYLARGO_GPIO_0+i);
+
+ /* Save the FCRs */
+ if (macio->type == macio_keylargo)
+ save_mbcr = MACIO_IN32(KEYLARGO_MBCR);
+ save_fcr[0] = MACIO_IN32(KEYLARGO_FCR0);
+ save_fcr[1] = MACIO_IN32(KEYLARGO_FCR1);
+ save_fcr[2] = MACIO_IN32(KEYLARGO_FCR2);
+ save_fcr[3] = MACIO_IN32(KEYLARGO_FCR3);
+ save_fcr[4] = MACIO_IN32(KEYLARGO_FCR4);
+ if (macio->type == macio_pangea || macio->type == macio_intrepid)
+ save_fcr[5] = MACIO_IN32(KEYLARGO_FCR5);
+
+ /* Save state & config of DBDMA channels */
+ dbdma_save(macio, save_dbdma);
+
+ /*
+ * Turn off as much as we can
+ */
+ if (macio->type == macio_pangea)
+ pangea_shutdown(macio, 1);
+ else if (macio->type == macio_intrepid)
+ intrepid_shutdown(macio, 1);
+ else if (macio->type == macio_keylargo)
+ keylargo_shutdown(macio, 1);
+
+ /*
+ * Put the host bridge to sleep
+ */
+
+ save_unin_clock_ctl = UN_IN(UNI_N_CLOCK_CNTL);
+ /* Note: do not switch GMAC off, driver does it when necessary, WOL must keep it
+ * enabled !
+ */
+ UN_OUT(UNI_N_CLOCK_CNTL, save_unin_clock_ctl &
+ ~(/*UNI_N_CLOCK_CNTL_GMAC|*/UNI_N_CLOCK_CNTL_FW/*|UNI_N_CLOCK_CNTL_PCI*/));
+ udelay(100);
+ UN_OUT(UNI_N_HWINIT_STATE, UNI_N_HWINIT_STATE_SLEEPING);
+ UN_OUT(UNI_N_POWER_MGT, UNI_N_POWER_MGT_SLEEP);
+ mdelay(10);
+
+ /*
+ * FIXME: A bit of black magic with OpenPIC (don't ask me why)
+ */
+ if (pmac_mb.model_id == PMAC_TYPE_SAWTOOTH) {
+ MACIO_BIS(0x506e0, 0x00400000);
+ MACIO_BIS(0x506e0, 0x80000000);
+ }
+ return 0;
+}
+
+static int
+core99_wake_up(void)
+{
+ struct macio_chip *macio;
+ int i;
+
+ macio = &macio_chips[0];
+ if (macio->type != macio_keylargo && macio->type != macio_pangea &&
+ macio->type != macio_intrepid)
+ return -ENODEV;
+
+ /*
+ * Wakeup the host bridge
+ */
+ UN_OUT(UNI_N_POWER_MGT, UNI_N_POWER_MGT_NORMAL);
+ udelay(10);
+ UN_OUT(UNI_N_HWINIT_STATE, UNI_N_HWINIT_STATE_RUNNING);
+ udelay(10);
+
+ /*
+ * Restore KeyLargo
+ */
+
+ if (macio->type == macio_keylargo) {
+ MACIO_OUT32(KEYLARGO_MBCR, save_mbcr);
+ (void)MACIO_IN32(KEYLARGO_MBCR); udelay(10);
+ }
+ MACIO_OUT32(KEYLARGO_FCR0, save_fcr[0]);
+ (void)MACIO_IN32(KEYLARGO_FCR0); udelay(10);
+ MACIO_OUT32(KEYLARGO_FCR1, save_fcr[1]);
+ (void)MACIO_IN32(KEYLARGO_FCR1); udelay(10);
+ MACIO_OUT32(KEYLARGO_FCR2, save_fcr[2]);
+ (void)MACIO_IN32(KEYLARGO_FCR2); udelay(10);
+ MACIO_OUT32(KEYLARGO_FCR3, save_fcr[3]);
+ (void)MACIO_IN32(KEYLARGO_FCR3); udelay(10);
+ MACIO_OUT32(KEYLARGO_FCR4, save_fcr[4]);
+ (void)MACIO_IN32(KEYLARGO_FCR4); udelay(10);
+ if (macio->type == macio_pangea || macio->type == macio_intrepid) {
+ MACIO_OUT32(KEYLARGO_FCR5, save_fcr[5]);
+ (void)MACIO_IN32(KEYLARGO_FCR5); udelay(10);
+ }
+
+ dbdma_restore(macio, save_dbdma);
+
+ MACIO_OUT32(KEYLARGO_GPIO_LEVELS0, save_gpio_levels[0]);
+ MACIO_OUT32(KEYLARGO_GPIO_LEVELS1, save_gpio_levels[1]);
+ for (i=0; i<KEYLARGO_GPIO_EXTINT_CNT; i++)
+ MACIO_OUT8(KEYLARGO_GPIO_EXTINT_0+i, save_gpio_extint[i]);
+ for (i=0; i<KEYLARGO_GPIO_CNT; i++)
+ MACIO_OUT8(KEYLARGO_GPIO_0+i, save_gpio_normal[i]);
+
+ /* FIXME more black magic with OpenPIC ... */
+ if (pmac_mb.model_id == PMAC_TYPE_SAWTOOTH) {
+ MACIO_BIC(0x506e0, 0x00400000);
+ MACIO_BIC(0x506e0, 0x80000000);
+ }
+
+ UN_OUT(UNI_N_CLOCK_CNTL, save_unin_clock_ctl);
+ udelay(100);
+
+ return 0;
+}
+
+static long
+core99_sleep_state(struct device_node *node, long param, long value)
+{
+ /* Param == 1 means to enter the "fake sleep" mode that is
+ * used for CPU speed switch
+ */
+ if (param == 1) {
+ if (value == 1) {
+ UN_OUT(UNI_N_HWINIT_STATE, UNI_N_HWINIT_STATE_SLEEPING);
+ UN_OUT(UNI_N_POWER_MGT, UNI_N_POWER_MGT_IDLE2);
+ } else {
+ UN_OUT(UNI_N_POWER_MGT, UNI_N_POWER_MGT_NORMAL);
+ udelay(10);
+ UN_OUT(UNI_N_HWINIT_STATE, UNI_N_HWINIT_STATE_RUNNING);
+ udelay(10);
+ }
+ return 0;
+ }
+ if ((pmac_mb.board_flags & PMAC_MB_CAN_SLEEP) == 0)
+ return -EPERM;
+
+ if (value == 1)
+ return core99_sleep();
+ else if (value == 0)
+ return core99_wake_up();
+ return 0;
+}
+
+#endif /* CONFIG_POWER4 */
+
+static long
+generic_dev_can_wake(struct device_node *node, long param, long value)
+{
+ /* Todo: eventually check we are really dealing with on-board
+ * video device ...
+ */
+
+ if (pmac_mb.board_flags & PMAC_MB_MAY_SLEEP)
+ pmac_mb.board_flags |= PMAC_MB_CAN_SLEEP;
+ return 0;
+}
+
+static long generic_get_mb_info(struct device_node *node, long param, long value)
+{
+ switch(param) {
+ case PMAC_MB_INFO_MODEL:
+ return pmac_mb.model_id;
+ case PMAC_MB_INFO_FLAGS:
+ return pmac_mb.board_flags;
+ case PMAC_MB_INFO_NAME:
+ /* hack hack hack... but should work */
+ *((const char **)value) = pmac_mb.model_name;
+ return 0;
+ }
+ return -EINVAL;
+}
+
+
+/*
+ * Table definitions
+ */
+
+/* Used on any machine
+ */
+static struct feature_table_entry any_features[] = {
+ { PMAC_FTR_GET_MB_INFO, generic_get_mb_info },
+ { PMAC_FTR_DEVICE_CAN_WAKE, generic_dev_can_wake },
+ { 0, NULL }
+};
+
+#ifndef CONFIG_POWER4
+
+/* OHare based motherboards. Currently, we only use these on the
+ * 2400,3400 and 3500 series powerbooks. Some older desktops seem
+ * to have issues with turning on/off those asic cells
+ */
+static struct feature_table_entry ohare_features[] = {
+ { PMAC_FTR_SCC_ENABLE, ohare_htw_scc_enable },
+ { PMAC_FTR_SWIM3_ENABLE, ohare_floppy_enable },
+ { PMAC_FTR_MESH_ENABLE, ohare_mesh_enable },
+ { PMAC_FTR_IDE_ENABLE, ohare_ide_enable},
+ { PMAC_FTR_IDE_RESET, ohare_ide_reset},
+ { PMAC_FTR_SLEEP_STATE, ohare_sleep_state },
+ { 0, NULL }
+};
+
+/* Heathrow desktop machines (Beige G3).
+ * Separated as some features couldn't be properly tested
+ * and the serial port control bits appear to confuse it.
+ */
+static struct feature_table_entry heathrow_desktop_features[] = {
+ { PMAC_FTR_SWIM3_ENABLE, heathrow_floppy_enable },
+ { PMAC_FTR_MESH_ENABLE, heathrow_mesh_enable },
+ { PMAC_FTR_IDE_ENABLE, heathrow_ide_enable },
+ { PMAC_FTR_IDE_RESET, heathrow_ide_reset },
+ { PMAC_FTR_BMAC_ENABLE, heathrow_bmac_enable },
+ { 0, NULL }
+};
+
+/* Heathrow based laptop, that is the Wallstreet and mainstreet
+ * powerbooks.
+ */
+static struct feature_table_entry heathrow_laptop_features[] = {
+ { PMAC_FTR_SCC_ENABLE, ohare_htw_scc_enable },
+ { PMAC_FTR_MODEM_ENABLE, heathrow_modem_enable },
+ { PMAC_FTR_SWIM3_ENABLE, heathrow_floppy_enable },
+ { PMAC_FTR_MESH_ENABLE, heathrow_mesh_enable },
+ { PMAC_FTR_IDE_ENABLE, heathrow_ide_enable },
+ { PMAC_FTR_IDE_RESET, heathrow_ide_reset },
+ { PMAC_FTR_BMAC_ENABLE, heathrow_bmac_enable },
+ { PMAC_FTR_SOUND_CHIP_ENABLE, heathrow_sound_enable },
+ { PMAC_FTR_SLEEP_STATE, heathrow_sleep_state },
+ { 0, NULL }
+};
+
+/* Paddington based machines
+ * The lombard (101) powerbook, first iMac models, B&W G3 and Yikes G4.
+ */
+static struct feature_table_entry paddington_features[] = {
+ { PMAC_FTR_SCC_ENABLE, ohare_htw_scc_enable },
+ { PMAC_FTR_MODEM_ENABLE, heathrow_modem_enable },
+ { PMAC_FTR_SWIM3_ENABLE, heathrow_floppy_enable },
+ { PMAC_FTR_MESH_ENABLE, heathrow_mesh_enable },
+ { PMAC_FTR_IDE_ENABLE, heathrow_ide_enable },
+ { PMAC_FTR_IDE_RESET, heathrow_ide_reset },
+ { PMAC_FTR_BMAC_ENABLE, heathrow_bmac_enable },
+ { PMAC_FTR_SOUND_CHIP_ENABLE, heathrow_sound_enable },
+ { PMAC_FTR_SLEEP_STATE, heathrow_sleep_state },
+ { 0, NULL }
+};
+
+/* Core99 & MacRISC 2 machines (all machines released since the
+ * iBook (included), that is all AGP machines, except pangea
+ * chipset. The pangea chipset is the "combo" UniNorth/KeyLargo
+ * used on iBook2 & iMac "flow power".
+ */
+static struct feature_table_entry core99_features[] = {
+ { PMAC_FTR_SCC_ENABLE, core99_scc_enable },
+ { PMAC_FTR_MODEM_ENABLE, core99_modem_enable },
+ { PMAC_FTR_IDE_ENABLE, core99_ide_enable },
+ { PMAC_FTR_IDE_RESET, core99_ide_reset },
+ { PMAC_FTR_GMAC_ENABLE, core99_gmac_enable },
+ { PMAC_FTR_GMAC_PHY_RESET, core99_gmac_phy_reset },
+ { PMAC_FTR_SOUND_CHIP_ENABLE, core99_sound_chip_enable },
+ { PMAC_FTR_AIRPORT_ENABLE, core99_airport_enable },
+ { PMAC_FTR_USB_ENABLE, core99_usb_enable },
+ { PMAC_FTR_1394_ENABLE, core99_firewire_enable },
+ { PMAC_FTR_1394_CABLE_POWER, core99_firewire_cable_power },
+ { PMAC_FTR_SLEEP_STATE, core99_sleep_state },
+#ifdef CONFIG_SMP
+ { PMAC_FTR_RESET_CPU, core99_reset_cpu },
+#endif /* CONFIG_SMP */
+ { PMAC_FTR_READ_GPIO, core99_read_gpio },
+ { PMAC_FTR_WRITE_GPIO, core99_write_gpio },
+ { 0, NULL }
+};
+
+/* RackMac
+ */
+static struct feature_table_entry rackmac_features[] = {
+ { PMAC_FTR_SCC_ENABLE, core99_scc_enable },
+ { PMAC_FTR_IDE_ENABLE, core99_ide_enable },
+ { PMAC_FTR_IDE_RESET, core99_ide_reset },
+ { PMAC_FTR_GMAC_ENABLE, core99_gmac_enable },
+ { PMAC_FTR_GMAC_PHY_RESET, core99_gmac_phy_reset },
+ { PMAC_FTR_USB_ENABLE, core99_usb_enable },
+ { PMAC_FTR_1394_ENABLE, core99_firewire_enable },
+ { PMAC_FTR_1394_CABLE_POWER, core99_firewire_cable_power },
+ { PMAC_FTR_SLEEP_STATE, core99_sleep_state },
+#ifdef CONFIG_SMP
+ { PMAC_FTR_RESET_CPU, core99_reset_cpu },
+#endif /* CONFIG_SMP */
+ { PMAC_FTR_READ_GPIO, core99_read_gpio },
+ { PMAC_FTR_WRITE_GPIO, core99_write_gpio },
+ { 0, NULL }
+};
+
+/* Pangea features
+ */
+static struct feature_table_entry pangea_features[] = {
+ { PMAC_FTR_SCC_ENABLE, core99_scc_enable },
+ { PMAC_FTR_MODEM_ENABLE, pangea_modem_enable },
+ { PMAC_FTR_IDE_ENABLE, core99_ide_enable },
+ { PMAC_FTR_IDE_RESET, core99_ide_reset },
+ { PMAC_FTR_GMAC_ENABLE, core99_gmac_enable },
+ { PMAC_FTR_GMAC_PHY_RESET, core99_gmac_phy_reset },
+ { PMAC_FTR_SOUND_CHIP_ENABLE, core99_sound_chip_enable },
+ { PMAC_FTR_AIRPORT_ENABLE, core99_airport_enable },
+ { PMAC_FTR_USB_ENABLE, core99_usb_enable },
+ { PMAC_FTR_1394_ENABLE, core99_firewire_enable },
+ { PMAC_FTR_1394_CABLE_POWER, core99_firewire_cable_power },
+ { PMAC_FTR_SLEEP_STATE, core99_sleep_state },
+ { PMAC_FTR_READ_GPIO, core99_read_gpio },
+ { PMAC_FTR_WRITE_GPIO, core99_write_gpio },
+ { 0, NULL }
+};
+
+/* Intrepid features
+ */
+static struct feature_table_entry intrepid_features[] = {
+ { PMAC_FTR_SCC_ENABLE, core99_scc_enable },
+ { PMAC_FTR_MODEM_ENABLE, pangea_modem_enable },
+ { PMAC_FTR_IDE_ENABLE, core99_ide_enable },
+ { PMAC_FTR_IDE_RESET, core99_ide_reset },
+ { PMAC_FTR_GMAC_ENABLE, core99_gmac_enable },
+ { PMAC_FTR_GMAC_PHY_RESET, core99_gmac_phy_reset },
+ { PMAC_FTR_SOUND_CHIP_ENABLE, core99_sound_chip_enable },
+ { PMAC_FTR_AIRPORT_ENABLE, core99_airport_enable },
+ { PMAC_FTR_USB_ENABLE, core99_usb_enable },
+ { PMAC_FTR_1394_ENABLE, core99_firewire_enable },
+ { PMAC_FTR_1394_CABLE_POWER, core99_firewire_cable_power },
+ { PMAC_FTR_SLEEP_STATE, core99_sleep_state },
+ { PMAC_FTR_READ_GPIO, core99_read_gpio },
+ { PMAC_FTR_WRITE_GPIO, core99_write_gpio },
+ { PMAC_FTR_AACK_DELAY_ENABLE, intrepid_aack_delay_enable },
+ { 0, NULL }
+};
+
+#else /* CONFIG_POWER4 */
+
+/* G5 features
+ */
+static struct feature_table_entry g5_features[] = {
+ { PMAC_FTR_GMAC_ENABLE, g5_gmac_enable },
+ { PMAC_FTR_1394_ENABLE, g5_fw_enable },
+ { PMAC_FTR_ENABLE_MPIC, g5_mpic_enable },
+ { PMAC_FTR_GMAC_PHY_RESET, g5_eth_phy_reset },
+ { PMAC_FTR_SOUND_CHIP_ENABLE, g5_i2s_enable },
+#ifdef CONFIG_SMP
+ { PMAC_FTR_RESET_CPU, g5_reset_cpu },
+#endif /* CONFIG_SMP */
+ { PMAC_FTR_READ_GPIO, core99_read_gpio },
+ { PMAC_FTR_WRITE_GPIO, core99_write_gpio },
+ { 0, NULL }
+};
+
+#endif /* CONFIG_POWER4 */
+
+static struct pmac_mb_def pmac_mb_defs[] = {
+#ifndef CONFIG_POWER4
+ /*
+ * Desktops
+ */
+
+ { "AAPL,8500", "PowerMac 8500/8600",
+ PMAC_TYPE_PSURGE, NULL,
+ 0
+ },
+ { "AAPL,9500", "PowerMac 9500/9600",
+ PMAC_TYPE_PSURGE, NULL,
+ 0
+ },
+ { "AAPL,7200", "PowerMac 7200",
+ PMAC_TYPE_PSURGE, NULL,
+ 0
+ },
+ { "AAPL,7300", "PowerMac 7200/7300",
+ PMAC_TYPE_PSURGE, NULL,
+ 0
+ },
+ { "AAPL,7500", "PowerMac 7500",
+ PMAC_TYPE_PSURGE, NULL,
+ 0
+ },
+ { "AAPL,ShinerESB", "Apple Network Server",
+ PMAC_TYPE_ANS, NULL,
+ 0
+ },
+ { "AAPL,e407", "Alchemy",
+ PMAC_TYPE_ALCHEMY, NULL,
+ 0
+ },
+ { "AAPL,e411", "Gazelle",
+ PMAC_TYPE_GAZELLE, NULL,
+ 0
+ },
+ { "AAPL,Gossamer", "PowerMac G3 (Gossamer)",
+ PMAC_TYPE_GOSSAMER, heathrow_desktop_features,
+ 0
+ },
+ { "AAPL,PowerMac G3", "PowerMac G3 (Silk)",
+ PMAC_TYPE_SILK, heathrow_desktop_features,
+ 0
+ },
+ { "PowerMac1,1", "Blue&White G3",
+ PMAC_TYPE_YOSEMITE, paddington_features,
+ 0
+ },
+ { "PowerMac1,2", "PowerMac G4 PCI Graphics",
+ PMAC_TYPE_YIKES, paddington_features,
+ 0
+ },
+ { "PowerMac2,1", "iMac FireWire",
+ PMAC_TYPE_FW_IMAC, core99_features,
+ PMAC_MB_MAY_SLEEP | PMAC_MB_OLD_CORE99
+ },
+ { "PowerMac2,2", "iMac FireWire",
+ PMAC_TYPE_FW_IMAC, core99_features,
+ PMAC_MB_MAY_SLEEP | PMAC_MB_OLD_CORE99
+ },
+ { "PowerMac3,1", "PowerMac G4 AGP Graphics",
+ PMAC_TYPE_SAWTOOTH, core99_features,
+ PMAC_MB_OLD_CORE99
+ },
+ { "PowerMac3,2", "PowerMac G4 AGP Graphics",
+ PMAC_TYPE_SAWTOOTH, core99_features,
+ PMAC_MB_MAY_SLEEP | PMAC_MB_OLD_CORE99
+ },
+ { "PowerMac3,3", "PowerMac G4 AGP Graphics",
+ PMAC_TYPE_SAWTOOTH, core99_features,
+ PMAC_MB_MAY_SLEEP | PMAC_MB_OLD_CORE99
+ },
+ { "PowerMac3,4", "PowerMac G4 Silver",
+ PMAC_TYPE_QUICKSILVER, core99_features,
+ PMAC_MB_MAY_SLEEP
+ },
+ { "PowerMac3,5", "PowerMac G4 Silver",
+ PMAC_TYPE_QUICKSILVER, core99_features,
+ PMAC_MB_MAY_SLEEP
+ },
+ { "PowerMac3,6", "PowerMac G4 Windtunnel",
+ PMAC_TYPE_WINDTUNNEL, core99_features,
+ PMAC_MB_MAY_SLEEP,
+ },
+ { "PowerMac4,1", "iMac \"Flower Power\"",
+ PMAC_TYPE_PANGEA_IMAC, pangea_features,
+ PMAC_MB_MAY_SLEEP
+ },
+ { "PowerMac4,2", "Flat panel iMac",
+ PMAC_TYPE_FLAT_PANEL_IMAC, pangea_features,
+ PMAC_MB_CAN_SLEEP
+ },
+ { "PowerMac4,4", "eMac",
+ PMAC_TYPE_EMAC, core99_features,
+ PMAC_MB_MAY_SLEEP
+ },
+ { "PowerMac5,1", "PowerMac G4 Cube",
+ PMAC_TYPE_CUBE, core99_features,
+ PMAC_MB_MAY_SLEEP | PMAC_MB_OLD_CORE99
+ },
+ { "PowerMac6,1", "Flat panel iMac",
+ PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features,
+ PMAC_MB_MAY_SLEEP,
+ },
+ { "PowerMac6,3", "Flat panel iMac",
+ PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features,
+ PMAC_MB_MAY_SLEEP,
+ },
+ { "PowerMac6,4", "eMac",
+ PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features,
+ PMAC_MB_MAY_SLEEP,
+ },
+ { "PowerMac10,1", "Mac mini",
+ PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features,
+ PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER,
+ },
+ { "iMac,1", "iMac (first generation)",
+ PMAC_TYPE_ORIG_IMAC, paddington_features,
+ 0
+ },
+
+ /*
+ * Xserve's
+ */
+
+ { "RackMac1,1", "XServe",
+ PMAC_TYPE_RACKMAC, rackmac_features,
+ 0,
+ },
+ { "RackMac1,2", "XServe rev. 2",
+ PMAC_TYPE_RACKMAC, rackmac_features,
+ 0,
+ },
+
+ /*
+ * Laptops
+ */
+
+ { "AAPL,3400/2400", "PowerBook 3400",
+ PMAC_TYPE_HOOPER, ohare_features,
+ PMAC_MB_CAN_SLEEP | PMAC_MB_MOBILE
+ },
+ { "AAPL,3500", "PowerBook 3500",
+ PMAC_TYPE_KANGA, ohare_features,
+ PMAC_MB_CAN_SLEEP | PMAC_MB_MOBILE
+ },
+ { "AAPL,PowerBook1998", "PowerBook Wallstreet",
+ PMAC_TYPE_WALLSTREET, heathrow_laptop_features,
+ PMAC_MB_CAN_SLEEP | PMAC_MB_MOBILE
+ },
+ { "PowerBook1,1", "PowerBook 101 (Lombard)",
+ PMAC_TYPE_101_PBOOK, paddington_features,
+ PMAC_MB_CAN_SLEEP | PMAC_MB_MOBILE
+ },
+ { "PowerBook2,1", "iBook (first generation)",
+ PMAC_TYPE_ORIG_IBOOK, core99_features,
+ PMAC_MB_CAN_SLEEP | PMAC_MB_OLD_CORE99 | PMAC_MB_MOBILE
+ },
+ { "PowerBook2,2", "iBook FireWire",
+ PMAC_TYPE_FW_IBOOK, core99_features,
+ PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER |
+ PMAC_MB_OLD_CORE99 | PMAC_MB_MOBILE
+ },
+ { "PowerBook3,1", "PowerBook Pismo",
+ PMAC_TYPE_PISMO, core99_features,
+ PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER |
+ PMAC_MB_OLD_CORE99 | PMAC_MB_MOBILE
+ },
+ { "PowerBook3,2", "PowerBook Titanium",
+ PMAC_TYPE_TITANIUM, core99_features,
+ PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE
+ },
+ { "PowerBook3,3", "PowerBook Titanium II",
+ PMAC_TYPE_TITANIUM2, core99_features,
+ PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE
+ },
+ { "PowerBook3,4", "PowerBook Titanium III",
+ PMAC_TYPE_TITANIUM3, core99_features,
+ PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE
+ },
+ { "PowerBook3,5", "PowerBook Titanium IV",
+ PMAC_TYPE_TITANIUM4, core99_features,
+ PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE
+ },
+ { "PowerBook4,1", "iBook 2",
+ PMAC_TYPE_IBOOK2, pangea_features,
+ PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE
+ },
+ { "PowerBook4,2", "iBook 2",
+ PMAC_TYPE_IBOOK2, pangea_features,
+ PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE
+ },
+ { "PowerBook4,3", "iBook 2 rev. 2",
+ PMAC_TYPE_IBOOK2, pangea_features,
+ PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE
+ },
+ { "PowerBook5,1", "PowerBook G4 17\"",
+ PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features,
+ PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
+ },
+ { "PowerBook5,2", "PowerBook G4 15\"",
+ PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features,
+ PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
+ },
+ { "PowerBook5,3", "PowerBook G4 17\"",
+ PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features,
+ PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
+ },
+ { "PowerBook5,4", "PowerBook G4 15\"",
+ PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features,
+ PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
+ },
+ { "PowerBook5,5", "PowerBook G4 17\"",
+ PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features,
+ PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
+ },
+ { "PowerBook5,6", "PowerBook G4 15\"",
+ PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features,
+ PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
+ },
+ { "PowerBook5,7", "PowerBook G4 17\"",
+ PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features,
+ PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
+ },
+ { "PowerBook6,1", "PowerBook G4 12\"",
+ PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features,
+ PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
+ },
+ { "PowerBook6,2", "PowerBook G4",
+ PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features,
+ PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
+ },
+ { "PowerBook6,3", "iBook G4",
+ PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features,
+ PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
+ },
+ { "PowerBook6,4", "PowerBook G4 12\"",
+ PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features,
+ PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
+ },
+ { "PowerBook6,5", "iBook G4",
+ PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features,
+ PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
+ },
+ { "PowerBook6,7", "iBook G4",
+ PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features,
+ PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
+ },
+ { "PowerBook6,8", "PowerBook G4 12\"",
+ PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features,
+ PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
+ },
+#else /* CONFIG_POWER4 */
+ { "PowerMac7,2", "PowerMac G5",
+ PMAC_TYPE_POWERMAC_G5, g5_features,
+ 0,
+ },
+#ifdef CONFIG_PPC64
+ { "PowerMac7,3", "PowerMac G5",
+ PMAC_TYPE_POWERMAC_G5, g5_features,
+ 0,
+ },
+ { "PowerMac8,1", "iMac G5",
+ PMAC_TYPE_IMAC_G5, g5_features,
+ 0,
+ },
+ { "PowerMac9,1", "PowerMac G5",
+ PMAC_TYPE_POWERMAC_G5_U3L, g5_features,
+ 0,
+ },
+ { "RackMac3,1", "XServe G5",
+ PMAC_TYPE_XSERVE_G5, g5_features,
+ 0,
+ },
+#endif /* CONFIG_PPC64 */
+#endif /* CONFIG_POWER4 */
+};
+
+/*
+ * The toplevel feature_call callback
+ */
+long pmac_do_feature_call(unsigned int selector, ...)
+{
+ struct device_node *node;
+ long param, value;
+ int i;
+ feature_call func = NULL;
+ va_list args;
+
+ if (pmac_mb.features)
+ for (i=0; pmac_mb.features[i].function; i++)
+ if (pmac_mb.features[i].selector == selector) {
+ func = pmac_mb.features[i].function;
+ break;
+ }
+ if (!func)
+ for (i=0; any_features[i].function; i++)
+ if (any_features[i].selector == selector) {
+ func = any_features[i].function;
+ break;
+ }
+ if (!func)
+ return -ENODEV;
+
+ va_start(args, selector);
+ node = (struct device_node*)va_arg(args, void*);
+ param = va_arg(args, long);
+ value = va_arg(args, long);
+ va_end(args);
+
+ return func(node, param, value);
+}
+
+static int __init probe_motherboard(void)
+{
+ int i;
+ struct macio_chip *macio = &macio_chips[0];
+ const char *model = NULL;
+ struct device_node *dt;
+
+ /* Lookup known motherboard type in device-tree. First try an
+ * exact match on the "model" property, then try a "compatible"
+ * match is none is found.
+ */
+ dt = find_devices("device-tree");
+ if (dt != NULL)
+ model = (const char *) get_property(dt, "model", NULL);
+ for(i=0; model && i<(sizeof(pmac_mb_defs)/sizeof(struct pmac_mb_def)); i++) {
+ if (strcmp(model, pmac_mb_defs[i].model_string) == 0) {
+ pmac_mb = pmac_mb_defs[i];
+ goto found;
+ }
+ }
+ for(i=0; i<(sizeof(pmac_mb_defs)/sizeof(struct pmac_mb_def)); i++) {
+ if (machine_is_compatible(pmac_mb_defs[i].model_string)) {
+ pmac_mb = pmac_mb_defs[i];
+ goto found;
+ }
+ }
+
+ /* Fallback to selection depending on mac-io chip type */
+ switch(macio->type) {
+#ifndef CONFIG_POWER4
+ case macio_grand_central:
+ pmac_mb.model_id = PMAC_TYPE_PSURGE;
+ pmac_mb.model_name = "Unknown PowerSurge";
+ break;
+ case macio_ohare:
+ pmac_mb.model_id = PMAC_TYPE_UNKNOWN_OHARE;
+ pmac_mb.model_name = "Unknown OHare-based";
+ break;
+ case macio_heathrow:
+ pmac_mb.model_id = PMAC_TYPE_UNKNOWN_HEATHROW;
+ pmac_mb.model_name = "Unknown Heathrow-based";
+ pmac_mb.features = heathrow_desktop_features;
+ break;
+ case macio_paddington:
+ pmac_mb.model_id = PMAC_TYPE_UNKNOWN_PADDINGTON;
+ pmac_mb.model_name = "Unknown Paddington-based";
+ pmac_mb.features = paddington_features;
+ break;
+ case macio_keylargo:
+ pmac_mb.model_id = PMAC_TYPE_UNKNOWN_CORE99;
+ pmac_mb.model_name = "Unknown Keylargo-based";
+ pmac_mb.features = core99_features;
+ break;
+ case macio_pangea:
+ pmac_mb.model_id = PMAC_TYPE_UNKNOWN_PANGEA;
+ pmac_mb.model_name = "Unknown Pangea-based";
+ pmac_mb.features = pangea_features;
+ break;
+ case macio_intrepid:
+ pmac_mb.model_id = PMAC_TYPE_UNKNOWN_INTREPID;
+ pmac_mb.model_name = "Unknown Intrepid-based";
+ pmac_mb.features = intrepid_features;
+ break;
+#else /* CONFIG_POWER4 */
+ case macio_keylargo2:
+ pmac_mb.model_id = PMAC_TYPE_UNKNOWN_K2;
+ pmac_mb.model_name = "Unknown K2-based";
+ pmac_mb.features = g5_features;
+ break;
+#endif /* CONFIG_POWER4 */
+ default:
+ return -ENODEV;
+ }
+found:
+#ifndef CONFIG_POWER4
+ /* Fixup Hooper vs. Comet */
+ if (pmac_mb.model_id == PMAC_TYPE_HOOPER) {
+ u32 __iomem * mach_id_ptr = ioremap(0xf3000034, 4);
+ if (!mach_id_ptr)
+ return -ENODEV;
+ /* Here, I used to disable the media-bay on comet. It
+ * appears this is wrong, the floppy connector is actually
+ * a kind of media-bay and works with the current driver.
+ */
+ if (__raw_readl(mach_id_ptr) & 0x20000000UL)
+ pmac_mb.model_id = PMAC_TYPE_COMET;
+ iounmap(mach_id_ptr);
+ }
+#endif /* CONFIG_POWER4 */
+
+#ifdef CONFIG_6xx
+ /* Set default value of powersave_nap on machines that support it.
+ * It appears that uninorth rev 3 has a problem with it, we don't
+ * enable it on those. In theory, the flush-on-lock property is
+ * supposed to be set when not supported, but I'm not very confident
+ * that all Apple OF revs did it properly, I do it the paranoid way.
+ */
+ while (uninorth_base && uninorth_rev > 3) {
+ struct device_node *np = find_path_device("/cpus");
+ if (!np || !np->child) {
+ printk(KERN_WARNING "Can't find CPU(s) in device tree !\n");
+ break;
+ }
+ np = np->child;
+ /* Nap mode not supported on SMP */
+ if (np->sibling)
+ break;
+ /* Nap mode not supported if flush-on-lock property is present */
+ if (get_property(np, "flush-on-lock", NULL))
+ break;
+ powersave_nap = 1;
+ printk(KERN_INFO "Processor NAP mode on idle enabled.\n");
+ break;
+ }
+
+ /* On CPUs that support it (750FX), lowspeed by default during
+ * NAP mode
+ */
+ powersave_lowspeed = 1;
+#endif /* CONFIG_6xx */
+#ifdef CONFIG_POWER4
+ powersave_nap = 1;
+#endif
+ /* Check for "mobile" machine */
+ if (model && (strncmp(model, "PowerBook", 9) == 0
+ || strncmp(model, "iBook", 5) == 0))
+ pmac_mb.board_flags |= PMAC_MB_MOBILE;
+
+
+ printk(KERN_INFO "PowerMac motherboard: %s\n", pmac_mb.model_name);
+ return 0;
+}
+
+/* Initialize the Core99 UniNorth host bridge and memory controller
+ */
+static void __init probe_uninorth(void)
+{
+ unsigned long actrl;
+
+ /* Locate core99 Uni-N */
+ uninorth_node = of_find_node_by_name(NULL, "uni-n");
+ /* Locate G5 u3 */
+ if (uninorth_node == NULL) {
+ uninorth_node = of_find_node_by_name(NULL, "u3");
+ uninorth_u3 = 1;
+ }
+ if (uninorth_node && uninorth_node->n_addrs > 0) {
+ unsigned long address = uninorth_node->addrs[0].address;
+ uninorth_base = ioremap(address, 0x40000);
+ uninorth_rev = in_be32(UN_REG(UNI_N_VERSION));
+ if (uninorth_u3)
+ u3_ht = ioremap(address + U3_HT_CONFIG_BASE, 0x1000);
+ } else
+ uninorth_node = NULL;
+
+ if (!uninorth_node)
+ return;
+
+ printk(KERN_INFO "Found %s memory controller & host bridge, revision: %d\n",
+ uninorth_u3 ? "U3" : "UniNorth", uninorth_rev);
+ printk(KERN_INFO "Mapped at 0x%08lx\n", (unsigned long)uninorth_base);
+
+ /* Set the arbitrer QAck delay according to what Apple does
+ */
+ if (uninorth_rev < 0x11) {
+ actrl = UN_IN(UNI_N_ARB_CTRL) & ~UNI_N_ARB_CTRL_QACK_DELAY_MASK;
+ actrl |= ((uninorth_rev < 3) ? UNI_N_ARB_CTRL_QACK_DELAY105 :
+ UNI_N_ARB_CTRL_QACK_DELAY) << UNI_N_ARB_CTRL_QACK_DELAY_SHIFT;
+ UN_OUT(UNI_N_ARB_CTRL, actrl);
+ }
+
+ /* Some more magic as done by them in recent MacOS X on UniNorth
+ * revs 1.5 to 2.O and Pangea. Seem to toggle the UniN Maxbus/PCI
+ * memory timeout
+ */
+ if ((uninorth_rev >= 0x11 && uninorth_rev <= 0x24) || uninorth_rev == 0xc0)
+ UN_OUT(0x2160, UN_IN(0x2160) & 0x00ffffff);
+}
+
+static void __init probe_one_macio(const char *name, const char *compat, int type)
+{
+ struct device_node* node;
+ int i;
+ volatile u32 __iomem * base;
+ u32* revp;
+
+ node = find_devices(name);
+ if (!node || !node->n_addrs)
+ return;
+ if (compat)
+ do {
+ if (device_is_compatible(node, compat))
+ break;
+ node = node->next;
+ } while (node);
+ if (!node)
+ return;
+ for(i=0; i<MAX_MACIO_CHIPS; i++) {
+ if (!macio_chips[i].of_node)
+ break;
+ if (macio_chips[i].of_node == node)
+ return;
+ }
+ if (i >= MAX_MACIO_CHIPS) {
+ printk(KERN_ERR "pmac_feature: Please increase MAX_MACIO_CHIPS !\n");
+ printk(KERN_ERR "pmac_feature: %s skipped\n", node->full_name);
+ return;
+ }
+ base = ioremap(node->addrs[0].address, node->addrs[0].size);
+ if (!base) {
+ printk(KERN_ERR "pmac_feature: Can't map mac-io chip !\n");
+ return;
+ }
+ if (type == macio_keylargo) {
+ u32 *did = (u32 *)get_property(node, "device-id", NULL);
+ if (*did == 0x00000025)
+ type = macio_pangea;
+ if (*did == 0x0000003e)
+ type = macio_intrepid;
+ }
+ macio_chips[i].of_node = node;
+ macio_chips[i].type = type;
+ macio_chips[i].base = base;
+ macio_chips[i].flags = MACIO_FLAG_SCCB_ON | MACIO_FLAG_SCCB_ON;
+ macio_chips[i].name = macio_names[type];
+ revp = (u32 *)get_property(node, "revision-id", NULL);
+ if (revp)
+ macio_chips[i].rev = *revp;
+ printk(KERN_INFO "Found a %s mac-io controller, rev: %d, mapped at 0x%p\n",
+ macio_names[type], macio_chips[i].rev, macio_chips[i].base);
+}
+
+static int __init
+probe_macios(void)
+{
+ /* Warning, ordering is important */
+ probe_one_macio("gc", NULL, macio_grand_central);
+ probe_one_macio("ohare", NULL, macio_ohare);
+ probe_one_macio("pci106b,7", NULL, macio_ohareII);
+ probe_one_macio("mac-io", "keylargo", macio_keylargo);
+ probe_one_macio("mac-io", "paddington", macio_paddington);
+ probe_one_macio("mac-io", "gatwick", macio_gatwick);
+ probe_one_macio("mac-io", "heathrow", macio_heathrow);
+ probe_one_macio("mac-io", "K2-Keylargo", macio_keylargo2);
+
+ /* Make sure the "main" macio chip appear first */
+ if (macio_chips[0].type == macio_gatwick
+ && macio_chips[1].type == macio_heathrow) {
+ struct macio_chip temp = macio_chips[0];
+ macio_chips[0] = macio_chips[1];
+ macio_chips[1] = temp;
+ }
+ if (macio_chips[0].type == macio_ohareII
+ && macio_chips[1].type == macio_ohare) {
+ struct macio_chip temp = macio_chips[0];
+ macio_chips[0] = macio_chips[1];
+ macio_chips[1] = temp;
+ }
+ macio_chips[0].lbus.index = 0;
+ macio_chips[1].lbus.index = 1;
+
+ return (macio_chips[0].of_node == NULL) ? -ENODEV : 0;
+}
+
+static void __init
+initial_serial_shutdown(struct device_node *np)
+{
+ int len;
+ struct slot_names_prop {
+ int count;
+ char name[1];
+ } *slots;
+ char *conn;
+ int port_type = PMAC_SCC_ASYNC;
+ int modem = 0;
+
+ slots = (struct slot_names_prop *)get_property(np, "slot-names", &len);
+ conn = get_property(np, "AAPL,connector", &len);
+ if (conn && (strcmp(conn, "infrared") == 0))
+ port_type = PMAC_SCC_IRDA;
+ else if (device_is_compatible(np, "cobalt"))
+ modem = 1;
+ else if (slots && slots->count > 0) {
+ if (strcmp(slots->name, "IrDA") == 0)
+ port_type = PMAC_SCC_IRDA;
+ else if (strcmp(slots->name, "Modem") == 0)
+ modem = 1;
+ }
+ if (modem)
+ pmac_call_feature(PMAC_FTR_MODEM_ENABLE, np, 0, 0);
+ pmac_call_feature(PMAC_FTR_SCC_ENABLE, np, port_type, 0);
+}
+
+static void __init
+set_initial_features(void)
+{
+ struct device_node *np;
+
+ /* That hack appears to be necessary for some StarMax motherboards
+ * but I'm not too sure it was audited for side-effects on other
+ * ohare based machines...
+ * Since I still have difficulties figuring the right way to
+ * differenciate them all and since that hack was there for a long
+ * time, I'll keep it around
+ */
+ if (macio_chips[0].type == macio_ohare && !find_devices("via-pmu")) {
+ struct macio_chip *macio = &macio_chips[0];
+ MACIO_OUT32(OHARE_FCR, STARMAX_FEATURES);
+ } else if (macio_chips[0].type == macio_ohare) {
+ struct macio_chip *macio = &macio_chips[0];
+ MACIO_BIS(OHARE_FCR, OH_IOBUS_ENABLE);
+ } else if (macio_chips[1].type == macio_ohare) {
+ struct macio_chip *macio = &macio_chips[1];
+ MACIO_BIS(OHARE_FCR, OH_IOBUS_ENABLE);
+ }
+
+#ifdef CONFIG_POWER4
+ if (macio_chips[0].type == macio_keylargo2) {
+#ifndef CONFIG_SMP
+ /* On SMP machines running UP, we have the second CPU eating
+ * bus cycles. We need to take it off the bus. This is done
+ * from pmac_smp for SMP kernels running on one CPU
+ */
+ np = of_find_node_by_type(NULL, "cpu");
+ if (np != NULL)
+ np = of_find_node_by_type(np, "cpu");
+ if (np != NULL) {
+ g5_phy_disable_cpu1();
+ of_node_put(np);
+ }
+#endif /* CONFIG_SMP */
+ /* Enable GMAC for now for PCI probing. It will be disabled
+ * later on after PCI probe
+ */
+ np = of_find_node_by_name(NULL, "ethernet");
+ while(np) {
+ if (device_is_compatible(np, "K2-GMAC"))
+ g5_gmac_enable(np, 0, 1);
+ np = of_find_node_by_name(np, "ethernet");
+ }
+
+ /* Enable FW before PCI probe. Will be disabled later on
+ * Note: We should have a batter way to check that we are
+ * dealing with uninorth internal cell and not a PCI cell
+ * on the external PCI. The code below works though.
+ */
+ np = of_find_node_by_name(NULL, "firewire");
+ while(np) {
+ if (device_is_compatible(np, "pci106b,5811")) {
+ macio_chips[0].flags |= MACIO_FLAG_FW_SUPPORTED;
+ g5_fw_enable(np, 0, 1);
+ }
+ np = of_find_node_by_name(np, "firewire");
+ }
+ }
+#else /* CONFIG_POWER4 */
+
+ if (macio_chips[0].type == macio_keylargo ||
+ macio_chips[0].type == macio_pangea ||
+ macio_chips[0].type == macio_intrepid) {
+ /* Enable GMAC for now for PCI probing. It will be disabled
+ * later on after PCI probe
+ */
+ np = of_find_node_by_name(NULL, "ethernet");
+ while(np) {
+ if (np->parent
+ && device_is_compatible(np->parent, "uni-north")
+ && device_is_compatible(np, "gmac"))
+ core99_gmac_enable(np, 0, 1);
+ np = of_find_node_by_name(np, "ethernet");
+ }
+
+ /* Enable FW before PCI probe. Will be disabled later on
+ * Note: We should have a batter way to check that we are
+ * dealing with uninorth internal cell and not a PCI cell
+ * on the external PCI. The code below works though.
+ */
+ np = of_find_node_by_name(NULL, "firewire");
+ while(np) {
+ if (np->parent
+ && device_is_compatible(np->parent, "uni-north")
+ && (device_is_compatible(np, "pci106b,18") ||
+ device_is_compatible(np, "pci106b,30") ||
+ device_is_compatible(np, "pci11c1,5811"))) {
+ macio_chips[0].flags |= MACIO_FLAG_FW_SUPPORTED;
+ core99_firewire_enable(np, 0, 1);
+ }
+ np = of_find_node_by_name(np, "firewire");
+ }
+
+ /* Enable ATA-100 before PCI probe. */
+ np = of_find_node_by_name(NULL, "ata-6");
+ while(np) {
+ if (np->parent
+ && device_is_compatible(np->parent, "uni-north")
+ && device_is_compatible(np, "kauai-ata")) {
+ core99_ata100_enable(np, 1);
+ }
+ np = of_find_node_by_name(np, "ata-6");
+ }
+
+ /* Switch airport off */
+ np = find_devices("radio");
+ while(np) {
+ if (np && np->parent == macio_chips[0].of_node) {
+ macio_chips[0].flags |= MACIO_FLAG_AIRPORT_ON;
+ core99_airport_enable(np, 0, 0);
+ }
+ np = np->next;
+ }
+ }
+
+ /* On all machines that support sound PM, switch sound off */
+ if (macio_chips[0].of_node)
+ pmac_do_feature_call(PMAC_FTR_SOUND_CHIP_ENABLE,
+ macio_chips[0].of_node, 0, 0);
+
+ /* While on some desktop G3s, we turn it back on */
+ if (macio_chips[0].of_node && macio_chips[0].type == macio_heathrow
+ && (pmac_mb.model_id == PMAC_TYPE_GOSSAMER ||
+ pmac_mb.model_id == PMAC_TYPE_SILK)) {
+ struct macio_chip *macio = &macio_chips[0];
+ MACIO_BIS(HEATHROW_FCR, HRW_SOUND_CLK_ENABLE);
+ MACIO_BIC(HEATHROW_FCR, HRW_SOUND_POWER_N);
+ }
+
+ /* Some machine models need the clock chip to be properly setup for
+ * clock spreading now. This should be a platform function but we
+ * don't do these at the moment
+ */
+ pmac_tweak_clock_spreading(1);
+
+#endif /* CONFIG_POWER4 */
+
+ /* On all machines, switch modem & serial ports off */
+ np = find_devices("ch-a");
+ while(np) {
+ initial_serial_shutdown(np);
+ np = np->next;
+ }
+ np = find_devices("ch-b");
+ while(np) {
+ initial_serial_shutdown(np);
+ np = np->next;
+ }
+}
+
+void __init
+pmac_feature_init(void)
+{
+ /* Detect the UniNorth memory controller */
+ probe_uninorth();
+
+ /* Probe mac-io controllers */
+ if (probe_macios()) {
+ printk(KERN_WARNING "No mac-io chip found\n");
+ return;
+ }
+
+ /* Setup low-level i2c stuffs */
+ pmac_init_low_i2c();
+
+ /* Probe machine type */
+ if (probe_motherboard())
+ printk(KERN_WARNING "Unknown PowerMac !\n");
+
+ /* Set some initial features (turn off some chips that will
+ * be later turned on)
+ */
+ set_initial_features();
+}
+
+int __init pmac_feature_late_init(void)
+{
+#if 0
+ struct device_node *np;
+
+ /* Request some resources late */
+ if (uninorth_node)
+ request_OF_resource(uninorth_node, 0, NULL);
+ np = find_devices("hammerhead");
+ if (np)
+ request_OF_resource(np, 0, NULL);
+ np = find_devices("interrupt-controller");
+ if (np)
+ request_OF_resource(np, 0, NULL);
+#endif
+ return 0;
+}
+
+device_initcall(pmac_feature_late_init);
+
+#if 0
+static void dump_HT_speeds(char *name, u32 cfg, u32 frq)
+{
+ int freqs[16] = { 200,300,400,500,600,800,1000,0,0,0,0,0,0,0,0,0 };
+ int bits[8] = { 8,16,0,32,2,4,0,0 };
+ int freq = (frq >> 8) & 0xf;
+
+ if (freqs[freq] == 0)
+ printk("%s: Unknown HT link frequency %x\n", name, freq);
+ else
+ printk("%s: %d MHz on main link, (%d in / %d out) bits width\n",
+ name, freqs[freq],
+ bits[(cfg >> 28) & 0x7], bits[(cfg >> 24) & 0x7]);
+}
+
+void __init pmac_check_ht_link(void)
+{
+ u32 ufreq, freq, ucfg, cfg;
+ struct device_node *pcix_node;
+ u8 px_bus, px_devfn;
+ struct pci_controller *px_hose;
+
+ (void)in_be32(u3_ht + U3_HT_LINK_COMMAND);
+ ucfg = cfg = in_be32(u3_ht + U3_HT_LINK_CONFIG);
+ ufreq = freq = in_be32(u3_ht + U3_HT_LINK_FREQ);
+ dump_HT_speeds("U3 HyperTransport", cfg, freq);
+
+ pcix_node = of_find_compatible_node(NULL, "pci", "pci-x");
+ if (pcix_node == NULL) {
+ printk("No PCI-X bridge found\n");
+ return;
+ }
+ if (pci_device_from_OF_node(pcix_node, &px_bus, &px_devfn) != 0) {
+ printk("PCI-X bridge found but not matched to pci\n");
+ return;
+ }
+ px_hose = pci_find_hose_for_OF_device(pcix_node);
+ if (px_hose == NULL) {
+ printk("PCI-X bridge found but not matched to host\n");
+ return;
+ }
+ early_read_config_dword(px_hose, px_bus, px_devfn, 0xc4, &cfg);
+ early_read_config_dword(px_hose, px_bus, px_devfn, 0xcc, &freq);
+ dump_HT_speeds("PCI-X HT Uplink", cfg, freq);
+ early_read_config_dword(px_hose, px_bus, px_devfn, 0xc8, &cfg);
+ early_read_config_dword(px_hose, px_bus, px_devfn, 0xd0, &freq);
+ dump_HT_speeds("PCI-X HT Downlink", cfg, freq);
+}
+#endif /* 0 */
+
+/*
+ * Early video resume hook
+ */
+
+static void (*pmac_early_vresume_proc)(void *data);
+static void *pmac_early_vresume_data;
+
+void pmac_set_early_video_resume(void (*proc)(void *data), void *data)
+{
+ if (_machine != _MACH_Pmac)
+ return;
+ preempt_disable();
+ pmac_early_vresume_proc = proc;
+ pmac_early_vresume_data = data;
+ preempt_enable();
+}
+EXPORT_SYMBOL(pmac_set_early_video_resume);
+
+void pmac_call_early_video_resume(void)
+{
+ if (pmac_early_vresume_proc)
+ pmac_early_vresume_proc(pmac_early_vresume_data);
+}
+
+/*
+ * AGP related suspend/resume code
+ */
+
+static struct pci_dev *pmac_agp_bridge;
+static int (*pmac_agp_suspend)(struct pci_dev *bridge);
+static int (*pmac_agp_resume)(struct pci_dev *bridge);
+
+void pmac_register_agp_pm(struct pci_dev *bridge,
+ int (*suspend)(struct pci_dev *bridge),
+ int (*resume)(struct pci_dev *bridge))
+{
+ if (suspend || resume) {
+ pmac_agp_bridge = bridge;
+ pmac_agp_suspend = suspend;
+ pmac_agp_resume = resume;
+ return;
+ }
+ if (bridge != pmac_agp_bridge)
+ return;
+ pmac_agp_suspend = pmac_agp_resume = NULL;
+ return;
+}
+EXPORT_SYMBOL(pmac_register_agp_pm);
+
+void pmac_suspend_agp_for_card(struct pci_dev *dev)
+{
+ if (pmac_agp_bridge == NULL || pmac_agp_suspend == NULL)
+ return;
+ if (pmac_agp_bridge->bus != dev->bus)
+ return;
+ pmac_agp_suspend(pmac_agp_bridge);
+}
+EXPORT_SYMBOL(pmac_suspend_agp_for_card);
+
+void pmac_resume_agp_for_card(struct pci_dev *dev)
+{
+ if (pmac_agp_bridge == NULL || pmac_agp_resume == NULL)
+ return;
+ if (pmac_agp_bridge->bus != dev->bus)
+ return;
+ pmac_agp_resume(pmac_agp_bridge);
+}
+EXPORT_SYMBOL(pmac_resume_agp_for_card);
diff --git a/arch/ppc64/kernel/pmac_low_i2c.c b/arch/powerpc/platforms/powermac/low_i2c.c
index f3f39e8e337a..f3f39e8e337a 100644
--- a/arch/ppc64/kernel/pmac_low_i2c.c
+++ b/arch/powerpc/platforms/powermac/low_i2c.c
diff --git a/arch/ppc64/kernel/pmac_nvram.c b/arch/powerpc/platforms/powermac/nvram.c
index e32a902236e3..4042e2f06ee0 100644
--- a/arch/ppc64/kernel/pmac_nvram.c
+++ b/arch/powerpc/platforms/powermac/nvram.c
@@ -15,10 +15,13 @@
#include <linux/kernel.h>
#include <linux/stddef.h>
#include <linux/string.h>
+#include <linux/nvram.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/errno.h>
+#include <linux/adb.h>
+#include <linux/pmu.h>
#include <linux/bootmem.h>
#include <linux/completion.h>
#include <linux/spinlock.h>
@@ -72,20 +75,38 @@ struct core99_header {
/*
* Read and write the non-volatile RAM on PowerMacs and CHRP machines.
*/
+static int nvram_naddrs;
static volatile unsigned char *nvram_data;
+static int is_core_99;
static int core99_bank = 0;
+static int nvram_partitions[3];
// XXX Turn that into a sem
static DEFINE_SPINLOCK(nv_lock);
+extern int pmac_newworld;
extern int system_running;
static int (*core99_write_bank)(int bank, u8* datas);
static int (*core99_erase_bank)(int bank);
-static char *nvram_image __pmacdata;
+static char *nvram_image;
-static ssize_t __pmac core99_nvram_read(char *buf, size_t count, loff_t *index)
+static unsigned char core99_nvram_read_byte(int addr)
+{
+ if (nvram_image == NULL)
+ return 0xff;
+ return nvram_image[addr];
+}
+
+static void core99_nvram_write_byte(int addr, unsigned char val)
+{
+ if (nvram_image == NULL)
+ return;
+ nvram_image[addr] = val;
+}
+
+static ssize_t core99_nvram_read(char *buf, size_t count, loff_t *index)
{
int i;
@@ -103,7 +124,7 @@ static ssize_t __pmac core99_nvram_read(char *buf, size_t count, loff_t *index)
return count;
}
-static ssize_t __pmac core99_nvram_write(char *buf, size_t count, loff_t *index)
+static ssize_t core99_nvram_write(char *buf, size_t count, loff_t *index)
{
int i;
@@ -121,14 +142,95 @@ static ssize_t __pmac core99_nvram_write(char *buf, size_t count, loff_t *index)
return count;
}
-static ssize_t __pmac core99_nvram_size(void)
+static ssize_t core99_nvram_size(void)
{
if (nvram_image == NULL)
return -ENODEV;
return NVRAM_SIZE;
}
-static u8 __pmac chrp_checksum(struct chrp_header* hdr)
+#ifdef CONFIG_PPC32
+static volatile unsigned char *nvram_addr;
+static int nvram_mult;
+
+static unsigned char direct_nvram_read_byte(int addr)
+{
+ return in_8(&nvram_data[(addr & (NVRAM_SIZE - 1)) * nvram_mult]);
+}
+
+static void direct_nvram_write_byte(int addr, unsigned char val)
+{
+ out_8(&nvram_data[(addr & (NVRAM_SIZE - 1)) * nvram_mult], val);
+}
+
+
+static unsigned char indirect_nvram_read_byte(int addr)
+{
+ unsigned char val;
+ unsigned long flags;
+
+ spin_lock_irqsave(&nv_lock, flags);
+ out_8(nvram_addr, addr >> 5);
+ val = in_8(&nvram_data[(addr & 0x1f) << 4]);
+ spin_unlock_irqrestore(&nv_lock, flags);
+
+ return val;
+}
+
+static void indirect_nvram_write_byte(int addr, unsigned char val)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&nv_lock, flags);
+ out_8(nvram_addr, addr >> 5);
+ out_8(&nvram_data[(addr & 0x1f) << 4], val);
+ spin_unlock_irqrestore(&nv_lock, flags);
+}
+
+
+#ifdef CONFIG_ADB_PMU
+
+static void pmu_nvram_complete(struct adb_request *req)
+{
+ if (req->arg)
+ complete((struct completion *)req->arg);
+}
+
+static unsigned char pmu_nvram_read_byte(int addr)
+{
+ struct adb_request req;
+ DECLARE_COMPLETION(req_complete);
+
+ req.arg = system_state == SYSTEM_RUNNING ? &req_complete : NULL;
+ if (pmu_request(&req, pmu_nvram_complete, 3, PMU_READ_NVRAM,
+ (addr >> 8) & 0xff, addr & 0xff))
+ return 0xff;
+ if (system_state == SYSTEM_RUNNING)
+ wait_for_completion(&req_complete);
+ while (!req.complete)
+ pmu_poll();
+ return req.reply[0];
+}
+
+static void pmu_nvram_write_byte(int addr, unsigned char val)
+{
+ struct adb_request req;
+ DECLARE_COMPLETION(req_complete);
+
+ req.arg = system_state == SYSTEM_RUNNING ? &req_complete : NULL;
+ if (pmu_request(&req, pmu_nvram_complete, 4, PMU_WRITE_NVRAM,
+ (addr >> 8) & 0xff, addr & 0xff, val))
+ return;
+ if (system_state == SYSTEM_RUNNING)
+ wait_for_completion(&req_complete);
+ while (!req.complete)
+ pmu_poll();
+}
+
+#endif /* CONFIG_ADB_PMU */
+#endif /* CONFIG_PPC32 */
+
+static u8 chrp_checksum(struct chrp_header* hdr)
{
u8 *ptr;
u16 sum = hdr->signature;
@@ -139,7 +241,7 @@ static u8 __pmac chrp_checksum(struct chrp_header* hdr)
return sum;
}
-static u32 __pmac core99_calc_adler(u8 *buffer)
+static u32 core99_calc_adler(u8 *buffer)
{
int cnt;
u32 low, high;
@@ -161,7 +263,7 @@ static u32 __pmac core99_calc_adler(u8 *buffer)
return (high << 16) | low;
}
-static u32 __pmac core99_check(u8* datas)
+static u32 core99_check(u8* datas)
{
struct core99_header* hdr99 = (struct core99_header*)datas;
@@ -180,7 +282,7 @@ static u32 __pmac core99_check(u8* datas)
return hdr99->generation;
}
-static int __pmac sm_erase_bank(int bank)
+static int sm_erase_bank(int bank)
{
int stat, i;
unsigned long timeout;
@@ -194,7 +296,7 @@ static int __pmac sm_erase_bank(int bank)
timeout = 0;
do {
if (++timeout > 1000000) {
- printk(KERN_ERR "nvram: Sharp/Miron flash erase timeout !\n");
+ printk(KERN_ERR "nvram: Sharp/Micron flash erase timeout !\n");
break;
}
out_8(base, SM_FLASH_CMD_READ_STATUS);
@@ -212,7 +314,7 @@ static int __pmac sm_erase_bank(int bank)
return 0;
}
-static int __pmac sm_write_bank(int bank, u8* datas)
+static int sm_write_bank(int bank, u8* datas)
{
int i, stat = 0;
unsigned long timeout;
@@ -247,7 +349,7 @@ static int __pmac sm_write_bank(int bank, u8* datas)
return 0;
}
-static int __pmac amd_erase_bank(int bank)
+static int amd_erase_bank(int bank)
{
int i, stat = 0;
unsigned long timeout;
@@ -294,7 +396,7 @@ static int __pmac amd_erase_bank(int bank)
return 0;
}
-static int __pmac amd_write_bank(int bank, u8* datas)
+static int amd_write_bank(int bank, u8* datas)
{
int i, stat = 0;
unsigned long timeout;
@@ -340,12 +442,49 @@ static int __pmac amd_write_bank(int bank, u8* datas)
return 0;
}
+static void __init lookup_partitions(void)
+{
+ u8 buffer[17];
+ int i, offset;
+ struct chrp_header* hdr;
+
+ if (pmac_newworld) {
+ nvram_partitions[pmac_nvram_OF] = -1;
+ nvram_partitions[pmac_nvram_XPRAM] = -1;
+ nvram_partitions[pmac_nvram_NR] = -1;
+ hdr = (struct chrp_header *)buffer;
+
+ offset = 0;
+ buffer[16] = 0;
+ do {
+ for (i=0;i<16;i++)
+ buffer[i] = ppc_md.nvram_read_val(offset+i);
+ if (!strcmp(hdr->name, "common"))
+ nvram_partitions[pmac_nvram_OF] = offset + 0x10;
+ if (!strcmp(hdr->name, "APL,MacOS75")) {
+ nvram_partitions[pmac_nvram_XPRAM] = offset + 0x10;
+ nvram_partitions[pmac_nvram_NR] = offset + 0x110;
+ }
+ offset += (hdr->len * 0x10);
+ } while(offset < NVRAM_SIZE);
+ } else {
+ nvram_partitions[pmac_nvram_OF] = 0x1800;
+ nvram_partitions[pmac_nvram_XPRAM] = 0x1300;
+ nvram_partitions[pmac_nvram_NR] = 0x1400;
+ }
+ DBG("nvram: OF partition at 0x%x\n", nvram_partitions[pmac_nvram_OF]);
+ DBG("nvram: XP partition at 0x%x\n", nvram_partitions[pmac_nvram_XPRAM]);
+ DBG("nvram: NR partition at 0x%x\n", nvram_partitions[pmac_nvram_NR]);
+}
-static int __pmac core99_nvram_sync(void)
+static void core99_nvram_sync(void)
{
struct core99_header* hdr99;
unsigned long flags;
+ if (!is_core_99 || !nvram_data || !nvram_image)
+ return;
+
spin_lock_irqsave(&nv_lock, flags);
if (!memcmp(nvram_image, (u8*)nvram_data + core99_bank*NVRAM_SIZE,
NVRAM_SIZE))
@@ -370,32 +509,28 @@ static int __pmac core99_nvram_sync(void)
bail:
spin_unlock_irqrestore(&nv_lock, flags);
- return 0;
+#ifdef DEBUG
+ mdelay(2000);
+#endif
}
-int __init pmac_nvram_init(void)
+static int __init core99_nvram_setup(struct device_node *dp)
{
- struct device_node *dp;
- u32 gen_bank0, gen_bank1;
int i;
+ u32 gen_bank0, gen_bank1;
- dp = find_devices("nvram");
- if (dp == NULL) {
- printk(KERN_ERR "Can't find NVRAM device\n");
- return -ENODEV;
- }
- if (!device_is_compatible(dp, "nvram,flash")) {
- printk(KERN_ERR "Incompatible type of NVRAM\n");
- return -ENXIO;
+ if (nvram_naddrs < 1) {
+ printk(KERN_ERR "nvram: no address\n");
+ return -EINVAL;
}
-
nvram_image = alloc_bootmem(NVRAM_SIZE);
if (nvram_image == NULL) {
printk(KERN_ERR "nvram: can't allocate ram image\n");
return -ENOMEM;
}
nvram_data = ioremap(dp->addrs[0].address, NVRAM_SIZE*2);
-
+ nvram_naddrs = 1; /* Make sure we get the correct case */
+
DBG("nvram: Checking bank 0...\n");
gen_bank0 = core99_check((u8 *)nvram_data);
@@ -408,11 +543,12 @@ int __init pmac_nvram_init(void)
for (i=0; i<NVRAM_SIZE; i++)
nvram_image[i] = nvram_data[i + core99_bank*NVRAM_SIZE];
+ ppc_md.nvram_read_val = core99_nvram_read_byte;
+ ppc_md.nvram_write_val = core99_nvram_write_byte;
ppc_md.nvram_read = core99_nvram_read;
ppc_md.nvram_write = core99_nvram_write;
ppc_md.nvram_size = core99_nvram_size;
ppc_md.nvram_sync = core99_nvram_sync;
-
/*
* Maybe we could be smarter here though making an exclusive list
* of known flash chips is a bit nasty as older OF didn't provide us
@@ -427,67 +563,81 @@ int __init pmac_nvram_init(void)
core99_erase_bank = sm_erase_bank;
core99_write_bank = sm_write_bank;
}
-
return 0;
}
-int __pmac pmac_get_partition(int partition)
+int __init pmac_nvram_init(void)
{
- struct nvram_partition *part;
- const char *name;
- int sig;
-
- switch(partition) {
- case pmac_nvram_OF:
- name = "common";
- sig = NVRAM_SIG_SYS;
- break;
- case pmac_nvram_XPRAM:
- name = "APL,MacOS75";
- sig = NVRAM_SIG_OS;
- break;
- case pmac_nvram_NR:
- default:
- /* Oldworld stuff */
+ struct device_node *dp;
+ int err = 0;
+
+ nvram_naddrs = 0;
+
+ dp = find_devices("nvram");
+ if (dp == NULL) {
+ printk(KERN_ERR "Can't find NVRAM device\n");
return -ENODEV;
}
+ nvram_naddrs = dp->n_addrs;
+ is_core_99 = device_is_compatible(dp, "nvram,flash");
+ if (is_core_99)
+ err = core99_nvram_setup(dp);
+#ifdef CONFIG_PPC32
+ else if (_machine == _MACH_chrp && nvram_naddrs == 1) {
+ nvram_data = ioremap(dp->addrs[0].address + isa_mem_base,
+ dp->addrs[0].size);
+ nvram_mult = 1;
+ ppc_md.nvram_read_val = direct_nvram_read_byte;
+ ppc_md.nvram_write_val = direct_nvram_write_byte;
+ } else if (nvram_naddrs == 1) {
+ nvram_data = ioremap(dp->addrs[0].address, dp->addrs[0].size);
+ nvram_mult = (dp->addrs[0].size + NVRAM_SIZE - 1) / NVRAM_SIZE;
+ ppc_md.nvram_read_val = direct_nvram_read_byte;
+ ppc_md.nvram_write_val = direct_nvram_write_byte;
+ } else if (nvram_naddrs == 2) {
+ nvram_addr = ioremap(dp->addrs[0].address, dp->addrs[0].size);
+ nvram_data = ioremap(dp->addrs[1].address, dp->addrs[1].size);
+ ppc_md.nvram_read_val = indirect_nvram_read_byte;
+ ppc_md.nvram_write_val = indirect_nvram_write_byte;
+ } else if (nvram_naddrs == 0 && sys_ctrler == SYS_CTRLER_PMU) {
+#ifdef CONFIG_ADB_PMU
+ nvram_naddrs = -1;
+ ppc_md.nvram_read_val = pmu_nvram_read_byte;
+ ppc_md.nvram_write_val = pmu_nvram_write_byte;
+#endif /* CONFIG_ADB_PMU */
+ }
+#endif
+ else {
+ printk(KERN_ERR "Incompatible type of NVRAM\n");
+ return -ENXIO;
+ }
+ lookup_partitions();
+ return err;
+}
- part = nvram_find_partition(sig, name);
- if (part == NULL)
- return 0;
-
- return part->index;
+int pmac_get_partition(int partition)
+{
+ return nvram_partitions[partition];
}
-u8 __pmac pmac_xpram_read(int xpaddr)
+u8 pmac_xpram_read(int xpaddr)
{
int offset = pmac_get_partition(pmac_nvram_XPRAM);
- loff_t index;
- u8 buf;
- ssize_t count;
if (offset < 0 || xpaddr < 0 || xpaddr > 0x100)
return 0xff;
- index = offset + xpaddr;
- count = ppc_md.nvram_read(&buf, 1, &index);
- if (count != 1)
- return 0xff;
- return buf;
+ return ppc_md.nvram_read_val(xpaddr + offset);
}
-void __pmac pmac_xpram_write(int xpaddr, u8 data)
+void pmac_xpram_write(int xpaddr, u8 data)
{
int offset = pmac_get_partition(pmac_nvram_XPRAM);
- loff_t index;
- u8 buf;
if (offset < 0 || xpaddr < 0 || xpaddr > 0x100)
return;
- index = offset + xpaddr;
- buf = data;
- ppc_md.nvram_write(&buf, 1, &index);
+ ppc_md.nvram_write_val(xpaddr + offset, data);
}
EXPORT_SYMBOL(pmac_get_partition);
diff --git a/arch/powerpc/platforms/powermac/pci.c b/arch/powerpc/platforms/powermac/pci.c
new file mode 100644
index 000000000000..dfd41b9781a9
--- /dev/null
+++ b/arch/powerpc/platforms/powermac/pci.c
@@ -0,0 +1,1167 @@
+/*
+ * Support for PCI bridges found on Power Macintoshes.
+ *
+ * Copyright (C) 2003 Benjamin Herrenschmuidt (benh@kernel.crashing.org)
+ * Copyright (C) 1997 Paul Mackerras (paulus@samba.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/pci.h>
+#include <linux/delay.h>
+#include <linux/string.h>
+#include <linux/init.h>
+#include <linux/bootmem.h>
+
+#include <asm/sections.h>
+#include <asm/io.h>
+#include <asm/prom.h>
+#include <asm/pci-bridge.h>
+#include <asm/machdep.h>
+#include <asm/pmac_feature.h>
+#include <asm/grackle.h>
+#ifdef CONFIG_PPC64
+#include <asm/iommu.h>
+#include <asm/ppc-pci.h>
+#endif
+
+#undef DEBUG
+
+#ifdef DEBUG
+#define DBG(x...) printk(x)
+#else
+#define DBG(x...)
+#endif
+
+static int add_bridge(struct device_node *dev);
+
+/* XXX Could be per-controller, but I don't think we risk anything by
+ * assuming we won't have both UniNorth and Bandit */
+static int has_uninorth;
+#ifdef CONFIG_PPC64
+static struct pci_controller *u3_agp;
+static struct pci_controller *u3_ht;
+#endif /* CONFIG_PPC64 */
+
+extern u8 pci_cache_line_size;
+extern int pcibios_assign_bus_offset;
+
+struct device_node *k2_skiplist[2];
+
+/*
+ * Magic constants for enabling cache coherency in the bandit/PSX bridge.
+ */
+#define BANDIT_DEVID_2 8
+#define BANDIT_REVID 3
+
+#define BANDIT_DEVNUM 11
+#define BANDIT_MAGIC 0x50
+#define BANDIT_COHERENT 0x40
+
+static int __init fixup_one_level_bus_range(struct device_node *node, int higher)
+{
+ for (; node != 0;node = node->sibling) {
+ int * bus_range;
+ unsigned int *class_code;
+ int len;
+
+ /* For PCI<->PCI bridges or CardBus bridges, we go down */
+ class_code = (unsigned int *) get_property(node, "class-code", NULL);
+ if (!class_code || ((*class_code >> 8) != PCI_CLASS_BRIDGE_PCI &&
+ (*class_code >> 8) != PCI_CLASS_BRIDGE_CARDBUS))
+ continue;
+ bus_range = (int *) get_property(node, "bus-range", &len);
+ if (bus_range != NULL && len > 2 * sizeof(int)) {
+ if (bus_range[1] > higher)
+ higher = bus_range[1];
+ }
+ higher = fixup_one_level_bus_range(node->child, higher);
+ }
+ return higher;
+}
+
+/* This routine fixes the "bus-range" property of all bridges in the
+ * system since they tend to have their "last" member wrong on macs
+ *
+ * Note that the bus numbers manipulated here are OF bus numbers, they
+ * are not Linux bus numbers.
+ */
+static void __init fixup_bus_range(struct device_node *bridge)
+{
+ int * bus_range;
+ int len;
+
+ /* Lookup the "bus-range" property for the hose */
+ bus_range = (int *) get_property(bridge, "bus-range", &len);
+ if (bus_range == NULL || len < 2 * sizeof(int)) {
+ printk(KERN_WARNING "Can't get bus-range for %s\n",
+ bridge->full_name);
+ return;
+ }
+ bus_range[1] = fixup_one_level_bus_range(bridge->child, bus_range[1]);
+}
+
+/*
+ * Apple MacRISC (U3, UniNorth, Bandit, Chaos) PCI controllers.
+ *
+ * The "Bandit" version is present in all early PCI PowerMacs,
+ * and up to the first ones using Grackle. Some machines may
+ * have 2 bandit controllers (2 PCI busses).
+ *
+ * "Chaos" is used in some "Bandit"-type machines as a bridge
+ * for the separate display bus. It is accessed the same
+ * way as bandit, but cannot be probed for devices. It therefore
+ * has its own config access functions.
+ *
+ * The "UniNorth" version is present in all Core99 machines
+ * (iBook, G4, new IMacs, and all the recent Apple machines).
+ * It contains 3 controllers in one ASIC.
+ *
+ * The U3 is the bridge used on G5 machines. It contains an
+ * AGP bus which is dealt with the old UniNorth access routines
+ * and a HyperTransport bus which uses its own set of access
+ * functions.
+ */
+
+#define MACRISC_CFA0(devfn, off) \
+ ((1 << (unsigned long)PCI_SLOT(dev_fn)) \
+ | (((unsigned long)PCI_FUNC(dev_fn)) << 8) \
+ | (((unsigned long)(off)) & 0xFCUL))
+
+#define MACRISC_CFA1(bus, devfn, off) \
+ ((((unsigned long)(bus)) << 16) \
+ |(((unsigned long)(devfn)) << 8) \
+ |(((unsigned long)(off)) & 0xFCUL) \
+ |1UL)
+
+static unsigned long macrisc_cfg_access(struct pci_controller* hose,
+ u8 bus, u8 dev_fn, u8 offset)
+{
+ unsigned int caddr;
+
+ if (bus == hose->first_busno) {
+ if (dev_fn < (11 << 3))
+ return 0;
+ caddr = MACRISC_CFA0(dev_fn, offset);
+ } else
+ caddr = MACRISC_CFA1(bus, dev_fn, offset);
+
+ /* Uninorth will return garbage if we don't read back the value ! */
+ do {
+ out_le32(hose->cfg_addr, caddr);
+ } while (in_le32(hose->cfg_addr) != caddr);
+
+ offset &= has_uninorth ? 0x07 : 0x03;
+ return ((unsigned long)hose->cfg_data) + offset;
+}
+
+static int macrisc_read_config(struct pci_bus *bus, unsigned int devfn,
+ int offset, int len, u32 *val)
+{
+ struct pci_controller *hose;
+ unsigned long addr;
+
+ hose = pci_bus_to_host(bus);
+ if (hose == NULL)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ addr = macrisc_cfg_access(hose, bus->number, devfn, offset);
+ if (!addr)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+ /*
+ * Note: the caller has already checked that offset is
+ * suitably aligned and that len is 1, 2 or 4.
+ */
+ switch (len) {
+ case 1:
+ *val = in_8((u8 *)addr);
+ break;
+ case 2:
+ *val = in_le16((u16 *)addr);
+ break;
+ default:
+ *val = in_le32((u32 *)addr);
+ break;
+ }
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int macrisc_write_config(struct pci_bus *bus, unsigned int devfn,
+ int offset, int len, u32 val)
+{
+ struct pci_controller *hose;
+ unsigned long addr;
+
+ hose = pci_bus_to_host(bus);
+ if (hose == NULL)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ addr = macrisc_cfg_access(hose, bus->number, devfn, offset);
+ if (!addr)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+ /*
+ * Note: the caller has already checked that offset is
+ * suitably aligned and that len is 1, 2 or 4.
+ */
+ switch (len) {
+ case 1:
+ out_8((u8 *)addr, val);
+ (void) in_8((u8 *)addr);
+ break;
+ case 2:
+ out_le16((u16 *)addr, val);
+ (void) in_le16((u16 *)addr);
+ break;
+ default:
+ out_le32((u32 *)addr, val);
+ (void) in_le32((u32 *)addr);
+ break;
+ }
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static struct pci_ops macrisc_pci_ops =
+{
+ macrisc_read_config,
+ macrisc_write_config
+};
+
+#ifdef CONFIG_PPC32
+/*
+ * Verify that a specific (bus, dev_fn) exists on chaos
+ */
+static int
+chaos_validate_dev(struct pci_bus *bus, int devfn, int offset)
+{
+ struct device_node *np;
+ u32 *vendor, *device;
+
+ np = pci_busdev_to_OF_node(bus, devfn);
+ if (np == NULL)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ vendor = (u32 *)get_property(np, "vendor-id", NULL);
+ device = (u32 *)get_property(np, "device-id", NULL);
+ if (vendor == NULL || device == NULL)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ if ((*vendor == 0x106b) && (*device == 3) && (offset >= 0x10)
+ && (offset != 0x14) && (offset != 0x18) && (offset <= 0x24))
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+chaos_read_config(struct pci_bus *bus, unsigned int devfn, int offset,
+ int len, u32 *val)
+{
+ int result = chaos_validate_dev(bus, devfn, offset);
+ if (result == PCIBIOS_BAD_REGISTER_NUMBER)
+ *val = ~0U;
+ if (result != PCIBIOS_SUCCESSFUL)
+ return result;
+ return macrisc_read_config(bus, devfn, offset, len, val);
+}
+
+static int
+chaos_write_config(struct pci_bus *bus, unsigned int devfn, int offset,
+ int len, u32 val)
+{
+ int result = chaos_validate_dev(bus, devfn, offset);
+ if (result != PCIBIOS_SUCCESSFUL)
+ return result;
+ return macrisc_write_config(bus, devfn, offset, len, val);
+}
+
+static struct pci_ops chaos_pci_ops =
+{
+ chaos_read_config,
+ chaos_write_config
+};
+
+static void __init setup_chaos(struct pci_controller *hose,
+ struct reg_property *addr)
+{
+ /* assume a `chaos' bridge */
+ hose->ops = &chaos_pci_ops;
+ hose->cfg_addr = ioremap(addr->address + 0x800000, 0x1000);
+ hose->cfg_data = ioremap(addr->address + 0xc00000, 0x1000);
+}
+#else
+#define setup_chaos(hose, addr)
+#endif /* CONFIG_PPC32 */
+
+#ifdef CONFIG_PPC64
+/*
+ * These versions of U3 HyperTransport config space access ops do not
+ * implement self-view of the HT host yet
+ */
+
+/*
+ * This function deals with some "special cases" devices.
+ *
+ * 0 -> No special case
+ * 1 -> Skip the device but act as if the access was successfull
+ * (return 0xff's on reads, eventually, cache config space
+ * accesses in a later version)
+ * -1 -> Hide the device (unsuccessful acess)
+ */
+static int u3_ht_skip_device(struct pci_controller *hose,
+ struct pci_bus *bus, unsigned int devfn)
+{
+ struct device_node *busdn, *dn;
+ int i;
+
+ /* We only allow config cycles to devices that are in OF device-tree
+ * as we are apparently having some weird things going on with some
+ * revs of K2 on recent G5s
+ */
+ if (bus->self)
+ busdn = pci_device_to_OF_node(bus->self);
+ else
+ busdn = hose->arch_data;
+ for (dn = busdn->child; dn; dn = dn->sibling)
+ if (dn->data && PCI_DN(dn)->devfn == devfn)
+ break;
+ if (dn == NULL)
+ return -1;
+
+ /*
+ * When a device in K2 is powered down, we die on config
+ * cycle accesses. Fix that here.
+ */
+ for (i=0; i<2; i++)
+ if (k2_skiplist[i] == dn)
+ return 1;
+
+ return 0;
+}
+
+#define U3_HT_CFA0(devfn, off) \
+ ((((unsigned long)devfn) << 8) | offset)
+#define U3_HT_CFA1(bus, devfn, off) \
+ (U3_HT_CFA0(devfn, off) \
+ + (((unsigned long)bus) << 16) \
+ + 0x01000000UL)
+
+static unsigned long u3_ht_cfg_access(struct pci_controller* hose,
+ u8 bus, u8 devfn, u8 offset)
+{
+ if (bus == hose->first_busno) {
+ /* For now, we don't self probe U3 HT bridge */
+ if (PCI_SLOT(devfn) == 0)
+ return 0;
+ return ((unsigned long)hose->cfg_data) + U3_HT_CFA0(devfn, offset);
+ } else
+ return ((unsigned long)hose->cfg_data) + U3_HT_CFA1(bus, devfn, offset);
+}
+
+static int u3_ht_read_config(struct pci_bus *bus, unsigned int devfn,
+ int offset, int len, u32 *val)
+{
+ struct pci_controller *hose;
+ unsigned long addr;
+
+ hose = pci_bus_to_host(bus);
+ if (hose == NULL)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ addr = u3_ht_cfg_access(hose, bus->number, devfn, offset);
+ if (!addr)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ switch (u3_ht_skip_device(hose, bus, devfn)) {
+ case 0:
+ break;
+ case 1:
+ switch (len) {
+ case 1:
+ *val = 0xff; break;
+ case 2:
+ *val = 0xffff; break;
+ default:
+ *val = 0xfffffffful; break;
+ }
+ return PCIBIOS_SUCCESSFUL;
+ default:
+ return PCIBIOS_DEVICE_NOT_FOUND;
+ }
+
+ /*
+ * Note: the caller has already checked that offset is
+ * suitably aligned and that len is 1, 2 or 4.
+ */
+ switch (len) {
+ case 1:
+ *val = in_8((u8 *)addr);
+ break;
+ case 2:
+ *val = in_le16((u16 *)addr);
+ break;
+ default:
+ *val = in_le32((u32 *)addr);
+ break;
+ }
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int u3_ht_write_config(struct pci_bus *bus, unsigned int devfn,
+ int offset, int len, u32 val)
+{
+ struct pci_controller *hose;
+ unsigned long addr;
+
+ hose = pci_bus_to_host(bus);
+ if (hose == NULL)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ addr = u3_ht_cfg_access(hose, bus->number, devfn, offset);
+ if (!addr)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ switch (u3_ht_skip_device(hose, bus, devfn)) {
+ case 0:
+ break;
+ case 1:
+ return PCIBIOS_SUCCESSFUL;
+ default:
+ return PCIBIOS_DEVICE_NOT_FOUND;
+ }
+
+ /*
+ * Note: the caller has already checked that offset is
+ * suitably aligned and that len is 1, 2 or 4.
+ */
+ switch (len) {
+ case 1:
+ out_8((u8 *)addr, val);
+ (void) in_8((u8 *)addr);
+ break;
+ case 2:
+ out_le16((u16 *)addr, val);
+ (void) in_le16((u16 *)addr);
+ break;
+ default:
+ out_le32((u32 *)addr, val);
+ (void) in_le32((u32 *)addr);
+ break;
+ }
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static struct pci_ops u3_ht_pci_ops =
+{
+ u3_ht_read_config,
+ u3_ht_write_config
+};
+#endif /* CONFIG_PPC64 */
+
+#ifdef CONFIG_PPC32
+/*
+ * For a bandit bridge, turn on cache coherency if necessary.
+ * N.B. we could clean this up using the hose ops directly.
+ */
+static void __init init_bandit(struct pci_controller *bp)
+{
+ unsigned int vendev, magic;
+ int rev;
+
+ /* read the word at offset 0 in config space for device 11 */
+ out_le32(bp->cfg_addr, (1UL << BANDIT_DEVNUM) + PCI_VENDOR_ID);
+ udelay(2);
+ vendev = in_le32(bp->cfg_data);
+ if (vendev == (PCI_DEVICE_ID_APPLE_BANDIT << 16) +
+ PCI_VENDOR_ID_APPLE) {
+ /* read the revision id */
+ out_le32(bp->cfg_addr,
+ (1UL << BANDIT_DEVNUM) + PCI_REVISION_ID);
+ udelay(2);
+ rev = in_8(bp->cfg_data);
+ if (rev != BANDIT_REVID)
+ printk(KERN_WARNING
+ "Unknown revision %d for bandit\n", rev);
+ } else if (vendev != (BANDIT_DEVID_2 << 16) + PCI_VENDOR_ID_APPLE) {
+ printk(KERN_WARNING "bandit isn't? (%x)\n", vendev);
+ return;
+ }
+
+ /* read the word at offset 0x50 */
+ out_le32(bp->cfg_addr, (1UL << BANDIT_DEVNUM) + BANDIT_MAGIC);
+ udelay(2);
+ magic = in_le32(bp->cfg_data);
+ if ((magic & BANDIT_COHERENT) != 0)
+ return;
+ magic |= BANDIT_COHERENT;
+ udelay(2);
+ out_le32(bp->cfg_data, magic);
+ printk(KERN_INFO "Cache coherency enabled for bandit/PSX\n");
+}
+
+/*
+ * Tweak the PCI-PCI bridge chip on the blue & white G3s.
+ */
+static void __init init_p2pbridge(void)
+{
+ struct device_node *p2pbridge;
+ struct pci_controller* hose;
+ u8 bus, devfn;
+ u16 val;
+
+ /* XXX it would be better here to identify the specific
+ PCI-PCI bridge chip we have. */
+ if ((p2pbridge = find_devices("pci-bridge")) == 0
+ || p2pbridge->parent == NULL
+ || strcmp(p2pbridge->parent->name, "pci") != 0)
+ return;
+ if (pci_device_from_OF_node(p2pbridge, &bus, &devfn) < 0) {
+ DBG("Can't find PCI infos for PCI<->PCI bridge\n");
+ return;
+ }
+ /* Warning: At this point, we have not yet renumbered all busses.
+ * So we must use OF walking to find out hose
+ */
+ hose = pci_find_hose_for_OF_device(p2pbridge);
+ if (!hose) {
+ DBG("Can't find hose for PCI<->PCI bridge\n");
+ return;
+ }
+ if (early_read_config_word(hose, bus, devfn,
+ PCI_BRIDGE_CONTROL, &val) < 0) {
+ printk(KERN_ERR "init_p2pbridge: couldn't read bridge control\n");
+ return;
+ }
+ val &= ~PCI_BRIDGE_CTL_MASTER_ABORT;
+ early_write_config_word(hose, bus, devfn, PCI_BRIDGE_CONTROL, val);
+}
+
+/*
+ * Some Apple desktop machines have a NEC PD720100A USB2 controller
+ * on the motherboard. Open Firmware, on these, will disable the
+ * EHCI part of it so it behaves like a pair of OHCI's. This fixup
+ * code re-enables it ;)
+ */
+static void __init fixup_nec_usb2(void)
+{
+ struct device_node *nec;
+
+ for (nec = NULL; (nec = of_find_node_by_name(nec, "usb")) != NULL;) {
+ struct pci_controller *hose;
+ u32 data, *prop;
+ u8 bus, devfn;
+
+ prop = (u32 *)get_property(nec, "vendor-id", NULL);
+ if (prop == NULL)
+ continue;
+ if (0x1033 != *prop)
+ continue;
+ prop = (u32 *)get_property(nec, "device-id", NULL);
+ if (prop == NULL)
+ continue;
+ if (0x0035 != *prop)
+ continue;
+ prop = (u32 *)get_property(nec, "reg", NULL);
+ if (prop == NULL)
+ continue;
+ devfn = (prop[0] >> 8) & 0xff;
+ bus = (prop[0] >> 16) & 0xff;
+ if (PCI_FUNC(devfn) != 0)
+ continue;
+ hose = pci_find_hose_for_OF_device(nec);
+ if (!hose)
+ continue;
+ early_read_config_dword(hose, bus, devfn, 0xe4, &data);
+ if (data & 1UL) {
+ printk("Found NEC PD720100A USB2 chip with disabled EHCI, fixing up...\n");
+ data &= ~1UL;
+ early_write_config_dword(hose, bus, devfn, 0xe4, data);
+ early_write_config_byte(hose, bus, devfn | 2, PCI_INTERRUPT_LINE,
+ nec->intrs[0].line);
+ }
+ }
+}
+
+static void __init setup_bandit(struct pci_controller *hose,
+ struct reg_property *addr)
+{
+ hose->ops = &macrisc_pci_ops;
+ hose->cfg_addr = ioremap(addr->address + 0x800000, 0x1000);
+ hose->cfg_data = ioremap(addr->address + 0xc00000, 0x1000);
+ init_bandit(hose);
+}
+
+static int __init setup_uninorth(struct pci_controller *hose,
+ struct reg_property *addr)
+{
+ pci_assign_all_buses = 1;
+ has_uninorth = 1;
+ hose->ops = &macrisc_pci_ops;
+ hose->cfg_addr = ioremap(addr->address + 0x800000, 0x1000);
+ hose->cfg_data = ioremap(addr->address + 0xc00000, 0x1000);
+ /* We "know" that the bridge at f2000000 has the PCI slots. */
+ return addr->address == 0xf2000000;
+}
+#endif
+
+#ifdef CONFIG_PPC64
+static void __init setup_u3_agp(struct pci_controller* hose)
+{
+ /* On G5, we move AGP up to high bus number so we don't need
+ * to reassign bus numbers for HT. If we ever have P2P bridges
+ * on AGP, we'll have to move pci_assign_all_busses to the
+ * pci_controller structure so we enable it for AGP and not for
+ * HT childs.
+ * We hard code the address because of the different size of
+ * the reg address cell, we shall fix that by killing struct
+ * reg_property and using some accessor functions instead
+ */
+ hose->first_busno = 0xf0;
+ hose->last_busno = 0xff;
+ has_uninorth = 1;
+ hose->ops = &macrisc_pci_ops;
+ hose->cfg_addr = ioremap(0xf0000000 + 0x800000, 0x1000);
+ hose->cfg_data = ioremap(0xf0000000 + 0xc00000, 0x1000);
+
+ u3_agp = hose;
+}
+
+static void __init setup_u3_ht(struct pci_controller* hose)
+{
+ struct device_node *np = (struct device_node *)hose->arch_data;
+ int i, cur;
+
+ hose->ops = &u3_ht_pci_ops;
+
+ /* We hard code the address because of the different size of
+ * the reg address cell, we shall fix that by killing struct
+ * reg_property and using some accessor functions instead
+ */
+ hose->cfg_data = (volatile unsigned char *)ioremap(0xf2000000, 0x02000000);
+
+ /*
+ * /ht node doesn't expose a "ranges" property, so we "remove" regions that
+ * have been allocated to AGP. So far, this version of the code doesn't assign
+ * any of the 0xfxxxxxxx "fine" memory regions to /ht.
+ * We need to fix that sooner or later by either parsing all child "ranges"
+ * properties or figuring out the U3 address space decoding logic and
+ * then read its configuration register (if any).
+ */
+ hose->io_base_phys = 0xf4000000;
+ hose->pci_io_size = 0x00400000;
+ hose->io_resource.name = np->full_name;
+ hose->io_resource.start = 0;
+ hose->io_resource.end = 0x003fffff;
+ hose->io_resource.flags = IORESOURCE_IO;
+ hose->pci_mem_offset = 0;
+ hose->first_busno = 0;
+ hose->last_busno = 0xef;
+ hose->mem_resources[0].name = np->full_name;
+ hose->mem_resources[0].start = 0x80000000;
+ hose->mem_resources[0].end = 0xefffffff;
+ hose->mem_resources[0].flags = IORESOURCE_MEM;
+
+ u3_ht = hose;
+
+ if (u3_agp == NULL) {
+ DBG("U3 has no AGP, using full resource range\n");
+ return;
+ }
+
+ /* We "remove" the AGP resources from the resources allocated to HT, that
+ * is we create "holes". However, that code does assumptions that so far
+ * happen to be true (cross fingers...), typically that resources in the
+ * AGP node are properly ordered
+ */
+ cur = 0;
+ for (i=0; i<3; i++) {
+ struct resource *res = &u3_agp->mem_resources[i];
+ if (res->flags != IORESOURCE_MEM)
+ continue;
+ /* We don't care about "fine" resources */
+ if (res->start >= 0xf0000000)
+ continue;
+ /* Check if it's just a matter of "shrinking" us in one direction */
+ if (hose->mem_resources[cur].start == res->start) {
+ DBG("U3/HT: shrink start of %d, %08lx -> %08lx\n",
+ cur, hose->mem_resources[cur].start, res->end + 1);
+ hose->mem_resources[cur].start = res->end + 1;
+ continue;
+ }
+ if (hose->mem_resources[cur].end == res->end) {
+ DBG("U3/HT: shrink end of %d, %08lx -> %08lx\n",
+ cur, hose->mem_resources[cur].end, res->start - 1);
+ hose->mem_resources[cur].end = res->start - 1;
+ continue;
+ }
+ /* No, it's not the case, we need a hole */
+ if (cur == 2) {
+ /* not enough resources for a hole, we drop part of the range */
+ printk(KERN_WARNING "Running out of resources for /ht host !\n");
+ hose->mem_resources[cur].end = res->start - 1;
+ continue;
+ }
+ cur++;
+ DBG("U3/HT: hole, %d end at %08lx, %d start at %08lx\n",
+ cur-1, res->start - 1, cur, res->end + 1);
+ hose->mem_resources[cur].name = np->full_name;
+ hose->mem_resources[cur].flags = IORESOURCE_MEM;
+ hose->mem_resources[cur].start = res->end + 1;
+ hose->mem_resources[cur].end = hose->mem_resources[cur-1].end;
+ hose->mem_resources[cur-1].end = res->start - 1;
+ }
+}
+
+/* XXX this needs to be converged between ppc32 and ppc64... */
+static struct pci_controller * __init pcibios_alloc_controller(void)
+{
+ struct pci_controller *hose;
+
+ hose = alloc_bootmem(sizeof(struct pci_controller));
+ if (hose)
+ pci_setup_pci_controller(hose);
+ return hose;
+}
+#endif
+
+/*
+ * We assume that if we have a G3 powermac, we have one bridge called
+ * "pci" (a MPC106) and no bandit or chaos bridges, and contrariwise,
+ * if we have one or more bandit or chaos bridges, we don't have a MPC106.
+ */
+static int __init add_bridge(struct device_node *dev)
+{
+ int len;
+ struct pci_controller *hose;
+#ifdef CONFIG_PPC32
+ struct reg_property *addr;
+#endif
+ char *disp_name;
+ int *bus_range;
+ int primary = 1;
+
+ DBG("Adding PCI host bridge %s\n", dev->full_name);
+
+#ifdef CONFIG_PPC32
+ /* XXX fix this */
+ addr = (struct reg_property *) get_property(dev, "reg", &len);
+ if (addr == NULL || len < sizeof(*addr)) {
+ printk(KERN_WARNING "Can't use %s: no address\n",
+ dev->full_name);
+ return -ENODEV;
+ }
+#endif
+ bus_range = (int *) get_property(dev, "bus-range", &len);
+ if (bus_range == NULL || len < 2 * sizeof(int)) {
+ printk(KERN_WARNING "Can't get bus-range for %s, assume bus 0\n",
+ dev->full_name);
+ }
+
+ hose = pcibios_alloc_controller();
+ if (!hose)
+ return -ENOMEM;
+ hose->arch_data = dev;
+ hose->first_busno = bus_range ? bus_range[0] : 0;
+ hose->last_busno = bus_range ? bus_range[1] : 0xff;
+
+ disp_name = NULL;
+#ifdef CONFIG_POWER4
+ if (device_is_compatible(dev, "u3-agp")) {
+ setup_u3_agp(hose);
+ disp_name = "U3-AGP";
+ primary = 0;
+ } else if (device_is_compatible(dev, "u3-ht")) {
+ setup_u3_ht(hose);
+ disp_name = "U3-HT";
+ primary = 1;
+ }
+ printk(KERN_INFO "Found %s PCI host bridge. Firmware bus number: %d->%d\n",
+ disp_name, hose->first_busno, hose->last_busno);
+#else
+ if (device_is_compatible(dev, "uni-north")) {
+ primary = setup_uninorth(hose, addr);
+ disp_name = "UniNorth";
+ } else if (strcmp(dev->name, "pci") == 0) {
+ /* XXX assume this is a mpc106 (grackle) */
+ setup_grackle(hose);
+ disp_name = "Grackle (MPC106)";
+ } else if (strcmp(dev->name, "bandit") == 0) {
+ setup_bandit(hose, addr);
+ disp_name = "Bandit";
+ } else if (strcmp(dev->name, "chaos") == 0) {
+ setup_chaos(hose, addr);
+ disp_name = "Chaos";
+ primary = 0;
+ }
+ printk(KERN_INFO "Found %s PCI host bridge at 0x%08lx. Firmware bus number: %d->%d\n",
+ disp_name, addr->address, hose->first_busno, hose->last_busno);
+#endif
+ DBG(" ->Hose at 0x%p, cfg_addr=0x%p,cfg_data=0x%p\n",
+ hose, hose->cfg_addr, hose->cfg_data);
+
+ /* Interpret the "ranges" property */
+ /* This also maps the I/O region and sets isa_io/mem_base */
+ pci_process_bridge_OF_ranges(hose, dev, primary);
+
+ /* Fixup "bus-range" OF property */
+ fixup_bus_range(dev);
+
+ return 0;
+}
+
+static void __init
+pcibios_fixup_OF_interrupts(void)
+{
+ struct pci_dev* dev = NULL;
+
+ /*
+ * Open Firmware often doesn't initialize the
+ * PCI_INTERRUPT_LINE config register properly, so we
+ * should find the device node and apply the interrupt
+ * obtained from the OF device-tree
+ */
+ for_each_pci_dev(dev) {
+ struct device_node *node;
+ node = pci_device_to_OF_node(dev);
+ /* this is the node, see if it has interrupts */
+ if (node && node->n_intrs > 0)
+ dev->irq = node->intrs[0].line;
+ pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
+ }
+}
+
+void __init
+pmac_pcibios_fixup(void)
+{
+ /* Fixup interrupts according to OF tree */
+ pcibios_fixup_OF_interrupts();
+}
+
+#ifdef CONFIG_PPC64
+static void __init pmac_fixup_phb_resources(void)
+{
+ struct pci_controller *hose, *tmp;
+
+ list_for_each_entry_safe(hose, tmp, &hose_list, list_node) {
+ printk(KERN_INFO "PCI Host %d, io start: %lx; io end: %lx\n",
+ hose->global_number,
+ hose->io_resource.start, hose->io_resource.end);
+ }
+}
+#endif
+
+void __init pmac_pci_init(void)
+{
+ struct device_node *np, *root;
+ struct device_node *ht = NULL;
+
+ root = of_find_node_by_path("/");
+ if (root == NULL) {
+ printk(KERN_CRIT "pmac_pci_init: can't find root "
+ "of device tree\n");
+ return;
+ }
+ for (np = NULL; (np = of_get_next_child(root, np)) != NULL;) {
+ if (np->name == NULL)
+ continue;
+ if (strcmp(np->name, "bandit") == 0
+ || strcmp(np->name, "chaos") == 0
+ || strcmp(np->name, "pci") == 0) {
+ if (add_bridge(np) == 0)
+ of_node_get(np);
+ }
+ if (strcmp(np->name, "ht") == 0) {
+ of_node_get(np);
+ ht = np;
+ }
+ }
+ of_node_put(root);
+
+#ifdef CONFIG_PPC64
+ /* Probe HT last as it relies on the agp resources to be already
+ * setup
+ */
+ if (ht && add_bridge(ht) != 0)
+ of_node_put(ht);
+
+ /*
+ * We need to call pci_setup_phb_io for the HT bridge first
+ * so it gets the I/O port numbers starting at 0, and we
+ * need to call it for the AGP bridge after that so it gets
+ * small positive I/O port numbers.
+ */
+ if (u3_ht)
+ pci_setup_phb_io(u3_ht, 1);
+ if (u3_agp)
+ pci_setup_phb_io(u3_agp, 0);
+
+ /*
+ * On ppc64, fixup the IO resources on our host bridges as
+ * the common code does it only for children of the host bridges
+ */
+ pmac_fixup_phb_resources();
+
+ /* Setup the linkage between OF nodes and PHBs */
+ pci_devs_phb_init();
+
+ /* Fixup the PCI<->OF mapping for U3 AGP due to bus renumbering. We
+ * assume there is no P2P bridge on the AGP bus, which should be a
+ * safe assumptions hopefully.
+ */
+ if (u3_agp) {
+ struct device_node *np = u3_agp->arch_data;
+ PCI_DN(np)->busno = 0xf0;
+ for (np = np->child; np; np = np->sibling)
+ PCI_DN(np)->busno = 0xf0;
+ }
+
+ /* pmac_check_ht_link(); */
+
+ /* Tell pci.c to not use the common resource allocation mechanism */
+ pci_probe_only = 1;
+
+ /* Allow all IO */
+ io_page_mask = -1;
+
+#else /* CONFIG_PPC64 */
+ init_p2pbridge();
+ fixup_nec_usb2();
+
+ /* We are still having some issues with the Xserve G4, enabling
+ * some offset between bus number and domains for now when we
+ * assign all busses should help for now
+ */
+ if (pci_assign_all_buses)
+ pcibios_assign_bus_offset = 0x10;
+#endif
+}
+
+int
+pmac_pci_enable_device_hook(struct pci_dev *dev, int initial)
+{
+ struct device_node* node;
+ int updatecfg = 0;
+ int uninorth_child;
+
+ node = pci_device_to_OF_node(dev);
+
+ /* We don't want to enable USB controllers absent from the OF tree
+ * (iBook second controller)
+ */
+ if (dev->vendor == PCI_VENDOR_ID_APPLE
+ && (dev->class == ((PCI_CLASS_SERIAL_USB << 8) | 0x10))
+ && !node) {
+ printk(KERN_INFO "Apple USB OHCI %s disabled by firmware\n",
+ pci_name(dev));
+ return -EINVAL;
+ }
+
+ if (!node)
+ return 0;
+
+ uninorth_child = node->parent &&
+ device_is_compatible(node->parent, "uni-north");
+
+ /* Firewire & GMAC were disabled after PCI probe, the driver is
+ * claiming them, we must re-enable them now.
+ */
+ if (uninorth_child && !strcmp(node->name, "firewire") &&
+ (device_is_compatible(node, "pci106b,18") ||
+ device_is_compatible(node, "pci106b,30") ||
+ device_is_compatible(node, "pci11c1,5811"))) {
+ pmac_call_feature(PMAC_FTR_1394_CABLE_POWER, node, 0, 1);
+ pmac_call_feature(PMAC_FTR_1394_ENABLE, node, 0, 1);
+ updatecfg = 1;
+ }
+ if (uninorth_child && !strcmp(node->name, "ethernet") &&
+ device_is_compatible(node, "gmac")) {
+ pmac_call_feature(PMAC_FTR_GMAC_ENABLE, node, 0, 1);
+ updatecfg = 1;
+ }
+
+ if (updatecfg) {
+ u16 cmd;
+
+ /*
+ * Make sure PCI is correctly configured
+ *
+ * We use old pci_bios versions of the function since, by
+ * default, gmac is not powered up, and so will be absent
+ * from the kernel initial PCI lookup.
+ *
+ * Should be replaced by 2.4 new PCI mechanisms and really
+ * register the device.
+ */
+ pci_read_config_word(dev, PCI_COMMAND, &cmd);
+ cmd |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER
+ | PCI_COMMAND_INVALIDATE;
+ pci_write_config_word(dev, PCI_COMMAND, cmd);
+ pci_write_config_byte(dev, PCI_LATENCY_TIMER, 16);
+ pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE,
+ L1_CACHE_BYTES >> 2);
+ }
+
+ return 0;
+}
+
+/* We power down some devices after they have been probed. They'll
+ * be powered back on later on
+ */
+void __init pmac_pcibios_after_init(void)
+{
+ struct device_node* nd;
+
+#ifdef CONFIG_BLK_DEV_IDE
+ struct pci_dev *dev = NULL;
+
+ /* OF fails to initialize IDE controllers on macs
+ * (and maybe other machines)
+ *
+ * Ideally, this should be moved to the IDE layer, but we need
+ * to check specifically with Andre Hedrick how to do it cleanly
+ * since the common IDE code seem to care about the fact that the
+ * BIOS may have disabled a controller.
+ *
+ * -- BenH
+ */
+ for_each_pci_dev(dev) {
+ if ((dev->class >> 16) == PCI_BASE_CLASS_STORAGE)
+ pci_enable_device(dev);
+ }
+#endif /* CONFIG_BLK_DEV_IDE */
+
+ nd = find_devices("firewire");
+ while (nd) {
+ if (nd->parent && (device_is_compatible(nd, "pci106b,18") ||
+ device_is_compatible(nd, "pci106b,30") ||
+ device_is_compatible(nd, "pci11c1,5811"))
+ && device_is_compatible(nd->parent, "uni-north")) {
+ pmac_call_feature(PMAC_FTR_1394_ENABLE, nd, 0, 0);
+ pmac_call_feature(PMAC_FTR_1394_CABLE_POWER, nd, 0, 0);
+ }
+ nd = nd->next;
+ }
+ nd = find_devices("ethernet");
+ while (nd) {
+ if (nd->parent && device_is_compatible(nd, "gmac")
+ && device_is_compatible(nd->parent, "uni-north"))
+ pmac_call_feature(PMAC_FTR_GMAC_ENABLE, nd, 0, 0);
+ nd = nd->next;
+ }
+}
+
+#ifdef CONFIG_PPC32
+void pmac_pci_fixup_cardbus(struct pci_dev* dev)
+{
+ if (_machine != _MACH_Pmac)
+ return;
+ /*
+ * Fix the interrupt routing on the various cardbus bridges
+ * used on powerbooks
+ */
+ if (dev->vendor != PCI_VENDOR_ID_TI)
+ return;
+ if (dev->device == PCI_DEVICE_ID_TI_1130 ||
+ dev->device == PCI_DEVICE_ID_TI_1131) {
+ u8 val;
+ /* Enable PCI interrupt */
+ if (pci_read_config_byte(dev, 0x91, &val) == 0)
+ pci_write_config_byte(dev, 0x91, val | 0x30);
+ /* Disable ISA interrupt mode */
+ if (pci_read_config_byte(dev, 0x92, &val) == 0)
+ pci_write_config_byte(dev, 0x92, val & ~0x06);
+ }
+ if (dev->device == PCI_DEVICE_ID_TI_1210 ||
+ dev->device == PCI_DEVICE_ID_TI_1211 ||
+ dev->device == PCI_DEVICE_ID_TI_1410 ||
+ dev->device == PCI_DEVICE_ID_TI_1510) {
+ u8 val;
+ /* 0x8c == TI122X_IRQMUX, 2 says to route the INTA
+ signal out the MFUNC0 pin */
+ if (pci_read_config_byte(dev, 0x8c, &val) == 0)
+ pci_write_config_byte(dev, 0x8c, (val & ~0x0f) | 2);
+ /* Disable ISA interrupt mode */
+ if (pci_read_config_byte(dev, 0x92, &val) == 0)
+ pci_write_config_byte(dev, 0x92, val & ~0x06);
+ }
+}
+
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_TI, PCI_ANY_ID, pmac_pci_fixup_cardbus);
+
+void pmac_pci_fixup_pciata(struct pci_dev* dev)
+{
+ u8 progif = 0;
+
+ /*
+ * On PowerMacs, we try to switch any PCI ATA controller to
+ * fully native mode
+ */
+ if (_machine != _MACH_Pmac)
+ return;
+ /* Some controllers don't have the class IDE */
+ if (dev->vendor == PCI_VENDOR_ID_PROMISE)
+ switch(dev->device) {
+ case PCI_DEVICE_ID_PROMISE_20246:
+ case PCI_DEVICE_ID_PROMISE_20262:
+ case PCI_DEVICE_ID_PROMISE_20263:
+ case PCI_DEVICE_ID_PROMISE_20265:
+ case PCI_DEVICE_ID_PROMISE_20267:
+ case PCI_DEVICE_ID_PROMISE_20268:
+ case PCI_DEVICE_ID_PROMISE_20269:
+ case PCI_DEVICE_ID_PROMISE_20270:
+ case PCI_DEVICE_ID_PROMISE_20271:
+ case PCI_DEVICE_ID_PROMISE_20275:
+ case PCI_DEVICE_ID_PROMISE_20276:
+ case PCI_DEVICE_ID_PROMISE_20277:
+ goto good;
+ }
+ /* Others, check PCI class */
+ if ((dev->class >> 8) != PCI_CLASS_STORAGE_IDE)
+ return;
+ good:
+ pci_read_config_byte(dev, PCI_CLASS_PROG, &progif);
+ if ((progif & 5) != 5) {
+ printk(KERN_INFO "Forcing PCI IDE into native mode: %s\n", pci_name(dev));
+ (void) pci_write_config_byte(dev, PCI_CLASS_PROG, progif|5);
+ if (pci_read_config_byte(dev, PCI_CLASS_PROG, &progif) ||
+ (progif & 5) != 5)
+ printk(KERN_ERR "Rewrite of PROGIF failed !\n");
+ }
+}
+DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, pmac_pci_fixup_pciata);
+#endif
+
+/*
+ * Disable second function on K2-SATA, it's broken
+ * and disable IO BARs on first one
+ */
+static void fixup_k2_sata(struct pci_dev* dev)
+{
+ int i;
+ u16 cmd;
+
+ if (PCI_FUNC(dev->devfn) > 0) {
+ pci_read_config_word(dev, PCI_COMMAND, &cmd);
+ cmd &= ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY);
+ pci_write_config_word(dev, PCI_COMMAND, cmd);
+ for (i = 0; i < 6; i++) {
+ dev->resource[i].start = dev->resource[i].end = 0;
+ dev->resource[i].flags = 0;
+ pci_write_config_dword(dev, PCI_BASE_ADDRESS_0 + 4 * i, 0);
+ }
+ } else {
+ pci_read_config_word(dev, PCI_COMMAND, &cmd);
+ cmd &= ~PCI_COMMAND_IO;
+ pci_write_config_word(dev, PCI_COMMAND, cmd);
+ for (i = 0; i < 5; i++) {
+ dev->resource[i].start = dev->resource[i].end = 0;
+ dev->resource[i].flags = 0;
+ pci_write_config_dword(dev, PCI_BASE_ADDRESS_0 + 4 * i, 0);
+ }
+ }
+}
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SERVERWORKS, 0x0240, fixup_k2_sata);
+
diff --git a/arch/powerpc/platforms/powermac/pic.c b/arch/powerpc/platforms/powermac/pic.c
new file mode 100644
index 000000000000..90040c49494d
--- /dev/null
+++ b/arch/powerpc/platforms/powermac/pic.c
@@ -0,0 +1,681 @@
+/*
+ * Support for the interrupt controllers found on Power Macintosh,
+ * currently Apple's "Grand Central" interrupt controller in all
+ * it's incarnations. OpenPIC support used on newer machines is
+ * in a separate file
+ *
+ * Copyright (C) 1997 Paul Mackerras (paulus@samba.org)
+ *
+ * Maintained by Benjamin Herrenschmidt (benh@kernel.crashing.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/config.h>
+#include <linux/stddef.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/signal.h>
+#include <linux/pci.h>
+#include <linux/interrupt.h>
+#include <linux/sysdev.h>
+#include <linux/adb.h>
+#include <linux/pmu.h>
+#include <linux/module.h>
+
+#include <asm/sections.h>
+#include <asm/io.h>
+#include <asm/smp.h>
+#include <asm/prom.h>
+#include <asm/pci-bridge.h>
+#include <asm/time.h>
+#include <asm/pmac_feature.h>
+#include <asm/mpic.h>
+
+#include "pmac.h"
+
+/*
+ * XXX this should be in xmon.h, but putting it there means xmon.h
+ * has to include <linux/interrupt.h> (to get irqreturn_t), which
+ * causes all sorts of problems. -- paulus
+ */
+extern irqreturn_t xmon_irq(int, void *, struct pt_regs *);
+
+#ifdef CONFIG_PPC32
+struct pmac_irq_hw {
+ unsigned int event;
+ unsigned int enable;
+ unsigned int ack;
+ unsigned int level;
+};
+
+/* Default addresses */
+static volatile struct pmac_irq_hw *pmac_irq_hw[4] = {
+ (struct pmac_irq_hw *) 0xf3000020,
+ (struct pmac_irq_hw *) 0xf3000010,
+ (struct pmac_irq_hw *) 0xf4000020,
+ (struct pmac_irq_hw *) 0xf4000010,
+};
+
+#define GC_LEVEL_MASK 0x3ff00000
+#define OHARE_LEVEL_MASK 0x1ff00000
+#define HEATHROW_LEVEL_MASK 0x1ff00000
+
+static int max_irqs;
+static int max_real_irqs;
+static u32 level_mask[4];
+
+static DEFINE_SPINLOCK(pmac_pic_lock);
+
+#define GATWICK_IRQ_POOL_SIZE 10
+static struct interrupt_info gatwick_int_pool[GATWICK_IRQ_POOL_SIZE];
+
+#define NR_MASK_WORDS ((NR_IRQS + 31) / 32)
+static unsigned long ppc_lost_interrupts[NR_MASK_WORDS];
+
+/*
+ * Mark an irq as "lost". This is only used on the pmac
+ * since it can lose interrupts (see pmac_set_irq_mask).
+ * -- Cort
+ */
+void
+__set_lost(unsigned long irq_nr, int nokick)
+{
+ if (!test_and_set_bit(irq_nr, ppc_lost_interrupts)) {
+ atomic_inc(&ppc_n_lost_interrupts);
+ if (!nokick)
+ set_dec(1);
+ }
+}
+
+static void
+pmac_mask_and_ack_irq(unsigned int irq_nr)
+{
+ unsigned long bit = 1UL << (irq_nr & 0x1f);
+ int i = irq_nr >> 5;
+ unsigned long flags;
+
+ if ((unsigned)irq_nr >= max_irqs)
+ return;
+
+ clear_bit(irq_nr, ppc_cached_irq_mask);
+ if (test_and_clear_bit(irq_nr, ppc_lost_interrupts))
+ atomic_dec(&ppc_n_lost_interrupts);
+ spin_lock_irqsave(&pmac_pic_lock, flags);
+ out_le32(&pmac_irq_hw[i]->enable, ppc_cached_irq_mask[i]);
+ out_le32(&pmac_irq_hw[i]->ack, bit);
+ do {
+ /* make sure ack gets to controller before we enable
+ interrupts */
+ mb();
+ } while((in_le32(&pmac_irq_hw[i]->enable) & bit)
+ != (ppc_cached_irq_mask[i] & bit));
+ spin_unlock_irqrestore(&pmac_pic_lock, flags);
+}
+
+static void pmac_set_irq_mask(unsigned int irq_nr, int nokicklost)
+{
+ unsigned long bit = 1UL << (irq_nr & 0x1f);
+ int i = irq_nr >> 5;
+ unsigned long flags;
+
+ if ((unsigned)irq_nr >= max_irqs)
+ return;
+
+ spin_lock_irqsave(&pmac_pic_lock, flags);
+ /* enable unmasked interrupts */
+ out_le32(&pmac_irq_hw[i]->enable, ppc_cached_irq_mask[i]);
+
+ do {
+ /* make sure mask gets to controller before we
+ return to user */
+ mb();
+ } while((in_le32(&pmac_irq_hw[i]->enable) & bit)
+ != (ppc_cached_irq_mask[i] & bit));
+
+ /*
+ * Unfortunately, setting the bit in the enable register
+ * when the device interrupt is already on *doesn't* set
+ * the bit in the flag register or request another interrupt.
+ */
+ if (bit & ppc_cached_irq_mask[i] & in_le32(&pmac_irq_hw[i]->level))
+ __set_lost((ulong)irq_nr, nokicklost);
+ spin_unlock_irqrestore(&pmac_pic_lock, flags);
+}
+
+/* When an irq gets requested for the first client, if it's an
+ * edge interrupt, we clear any previous one on the controller
+ */
+static unsigned int pmac_startup_irq(unsigned int irq_nr)
+{
+ unsigned long bit = 1UL << (irq_nr & 0x1f);
+ int i = irq_nr >> 5;
+
+ if ((irq_desc[irq_nr].status & IRQ_LEVEL) == 0)
+ out_le32(&pmac_irq_hw[i]->ack, bit);
+ set_bit(irq_nr, ppc_cached_irq_mask);
+ pmac_set_irq_mask(irq_nr, 0);
+
+ return 0;
+}
+
+static void pmac_mask_irq(unsigned int irq_nr)
+{
+ clear_bit(irq_nr, ppc_cached_irq_mask);
+ pmac_set_irq_mask(irq_nr, 0);
+ mb();
+}
+
+static void pmac_unmask_irq(unsigned int irq_nr)
+{
+ set_bit(irq_nr, ppc_cached_irq_mask);
+ pmac_set_irq_mask(irq_nr, 0);
+}
+
+static void pmac_end_irq(unsigned int irq_nr)
+{
+ if (!(irq_desc[irq_nr].status & (IRQ_DISABLED|IRQ_INPROGRESS))
+ && irq_desc[irq_nr].action) {
+ set_bit(irq_nr, ppc_cached_irq_mask);
+ pmac_set_irq_mask(irq_nr, 1);
+ }
+}
+
+
+struct hw_interrupt_type pmac_pic = {
+ .typename = " PMAC-PIC ",
+ .startup = pmac_startup_irq,
+ .enable = pmac_unmask_irq,
+ .disable = pmac_mask_irq,
+ .ack = pmac_mask_and_ack_irq,
+ .end = pmac_end_irq,
+};
+
+struct hw_interrupt_type gatwick_pic = {
+ .typename = " GATWICK ",
+ .startup = pmac_startup_irq,
+ .enable = pmac_unmask_irq,
+ .disable = pmac_mask_irq,
+ .ack = pmac_mask_and_ack_irq,
+ .end = pmac_end_irq,
+};
+
+static irqreturn_t gatwick_action(int cpl, void *dev_id, struct pt_regs *regs)
+{
+ int irq, bits;
+
+ for (irq = max_irqs; (irq -= 32) >= max_real_irqs; ) {
+ int i = irq >> 5;
+ bits = in_le32(&pmac_irq_hw[i]->event) | ppc_lost_interrupts[i];
+ /* We must read level interrupts from the level register */
+ bits |= (in_le32(&pmac_irq_hw[i]->level) & level_mask[i]);
+ bits &= ppc_cached_irq_mask[i];
+ if (bits == 0)
+ continue;
+ irq += __ilog2(bits);
+ __do_IRQ(irq, regs);
+ return IRQ_HANDLED;
+ }
+ printk("gatwick irq not from gatwick pic\n");
+ return IRQ_NONE;
+}
+
+int
+pmac_get_irq(struct pt_regs *regs)
+{
+ int irq;
+ unsigned long bits = 0;
+
+#ifdef CONFIG_SMP
+ void psurge_smp_message_recv(struct pt_regs *);
+
+ /* IPI's are a hack on the powersurge -- Cort */
+ if ( smp_processor_id() != 0 ) {
+ psurge_smp_message_recv(regs);
+ return -2; /* ignore, already handled */
+ }
+#endif /* CONFIG_SMP */
+ for (irq = max_real_irqs; (irq -= 32) >= 0; ) {
+ int i = irq >> 5;
+ bits = in_le32(&pmac_irq_hw[i]->event) | ppc_lost_interrupts[i];
+ /* We must read level interrupts from the level register */
+ bits |= (in_le32(&pmac_irq_hw[i]->level) & level_mask[i]);
+ bits &= ppc_cached_irq_mask[i];
+ if (bits == 0)
+ continue;
+ irq += __ilog2(bits);
+ break;
+ }
+
+ return irq;
+}
+
+/* This routine will fix some missing interrupt values in the device tree
+ * on the gatwick mac-io controller used by some PowerBooks
+ */
+static void __init
+pmac_fix_gatwick_interrupts(struct device_node *gw, int irq_base)
+{
+ struct device_node *node;
+ int count;
+
+ memset(gatwick_int_pool, 0, sizeof(gatwick_int_pool));
+ node = gw->child;
+ count = 0;
+ while(node)
+ {
+ /* Fix SCC */
+ if (strcasecmp(node->name, "escc") == 0)
+ if (node->child) {
+ if (node->child->n_intrs < 3) {
+ node->child->intrs = &gatwick_int_pool[count];
+ count += 3;
+ }
+ node->child->n_intrs = 3;
+ node->child->intrs[0].line = 15+irq_base;
+ node->child->intrs[1].line = 4+irq_base;
+ node->child->intrs[2].line = 5+irq_base;
+ printk(KERN_INFO "irq: fixed SCC on second controller (%d,%d,%d)\n",
+ node->child->intrs[0].line,
+ node->child->intrs[1].line,
+ node->child->intrs[2].line);
+ }
+ /* Fix media-bay & left SWIM */
+ if (strcasecmp(node->name, "media-bay") == 0) {
+ struct device_node* ya_node;
+
+ if (node->n_intrs == 0)
+ node->intrs = &gatwick_int_pool[count++];
+ node->n_intrs = 1;
+ node->intrs[0].line = 29+irq_base;
+ printk(KERN_INFO "irq: fixed media-bay on second controller (%d)\n",
+ node->intrs[0].line);
+
+ ya_node = node->child;
+ while(ya_node)
+ {
+ if (strcasecmp(ya_node->name, "floppy") == 0) {
+ if (ya_node->n_intrs < 2) {
+ ya_node->intrs = &gatwick_int_pool[count];
+ count += 2;
+ }
+ ya_node->n_intrs = 2;
+ ya_node->intrs[0].line = 19+irq_base;
+ ya_node->intrs[1].line = 1+irq_base;
+ printk(KERN_INFO "irq: fixed floppy on second controller (%d,%d)\n",
+ ya_node->intrs[0].line, ya_node->intrs[1].line);
+ }
+ if (strcasecmp(ya_node->name, "ata4") == 0) {
+ if (ya_node->n_intrs < 2) {
+ ya_node->intrs = &gatwick_int_pool[count];
+ count += 2;
+ }
+ ya_node->n_intrs = 2;
+ ya_node->intrs[0].line = 14+irq_base;
+ ya_node->intrs[1].line = 3+irq_base;
+ printk(KERN_INFO "irq: fixed ide on second controller (%d,%d)\n",
+ ya_node->intrs[0].line, ya_node->intrs[1].line);
+ }
+ ya_node = ya_node->sibling;
+ }
+ }
+ node = node->sibling;
+ }
+ if (count > 10) {
+ printk("WARNING !! Gatwick interrupt pool overflow\n");
+ printk(" GATWICK_IRQ_POOL_SIZE = %d\n", GATWICK_IRQ_POOL_SIZE);
+ printk(" requested = %d\n", count);
+ }
+}
+
+/*
+ * The PowerBook 3400/2400/3500 can have a combo ethernet/modem
+ * card which includes an ohare chip that acts as a second interrupt
+ * controller. If we find this second ohare, set it up and fix the
+ * interrupt value in the device tree for the ethernet chip.
+ */
+static int __init enable_second_ohare(void)
+{
+ unsigned char bus, devfn;
+ unsigned short cmd;
+ unsigned long addr;
+ struct device_node *irqctrler = find_devices("pci106b,7");
+ struct device_node *ether;
+
+ if (irqctrler == NULL || irqctrler->n_addrs <= 0)
+ return -1;
+ addr = (unsigned long) ioremap(irqctrler->addrs[0].address, 0x40);
+ pmac_irq_hw[1] = (volatile struct pmac_irq_hw *)(addr + 0x20);
+ max_irqs = 64;
+ if (pci_device_from_OF_node(irqctrler, &bus, &devfn) == 0) {
+ struct pci_controller* hose = pci_find_hose_for_OF_device(irqctrler);
+ if (!hose)
+ printk(KERN_ERR "Can't find PCI hose for OHare2 !\n");
+ else {
+ early_read_config_word(hose, bus, devfn, PCI_COMMAND, &cmd);
+ cmd |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER;
+ cmd &= ~PCI_COMMAND_IO;
+ early_write_config_word(hose, bus, devfn, PCI_COMMAND, cmd);
+ }
+ }
+
+ /* Fix interrupt for the modem/ethernet combo controller. The number
+ in the device tree (27) is bogus (correct for the ethernet-only
+ board but not the combo ethernet/modem board).
+ The real interrupt is 28 on the second controller -> 28+32 = 60.
+ */
+ ether = find_devices("pci1011,14");
+ if (ether && ether->n_intrs > 0) {
+ ether->intrs[0].line = 60;
+ printk(KERN_INFO "irq: Fixed ethernet IRQ to %d\n",
+ ether->intrs[0].line);
+ }
+
+ /* Return the interrupt number of the cascade */
+ return irqctrler->intrs[0].line;
+}
+
+#ifdef CONFIG_XMON
+static struct irqaction xmon_action = {
+ .handler = xmon_irq,
+ .flags = 0,
+ .mask = CPU_MASK_NONE,
+ .name = "NMI - XMON"
+};
+#endif
+
+static struct irqaction gatwick_cascade_action = {
+ .handler = gatwick_action,
+ .flags = SA_INTERRUPT,
+ .mask = CPU_MASK_NONE,
+ .name = "cascade",
+};
+#endif /* CONFIG_PPC32 */
+
+static int pmac_u3_cascade(struct pt_regs *regs, void *data)
+{
+ return mpic_get_one_irq((struct mpic *)data, regs);
+}
+
+void __init pmac_pic_init(void)
+{
+ struct device_node *irqctrler = NULL;
+ struct device_node *irqctrler2 = NULL;
+ struct device_node *np;
+#ifdef CONFIG_PPC32
+ int i;
+ unsigned long addr;
+ int irq_cascade = -1;
+#endif
+ struct mpic *mpic1, *mpic2;
+
+ /* We first try to detect Apple's new Core99 chipset, since mac-io
+ * is quite different on those machines and contains an IBM MPIC2.
+ */
+ np = find_type_devices("open-pic");
+ while (np) {
+ if (np->parent && !strcmp(np->parent->name, "u3"))
+ irqctrler2 = np;
+ else
+ irqctrler = np;
+ np = np->next;
+ }
+ if (irqctrler != NULL && irqctrler->n_addrs > 0) {
+ unsigned char senses[128];
+
+ printk(KERN_INFO "PowerMac using OpenPIC irq controller at 0x%08x\n",
+ (unsigned int)irqctrler->addrs[0].address);
+ pmac_call_feature(PMAC_FTR_ENABLE_MPIC, irqctrler, 0, 0);
+
+ prom_get_irq_senses(senses, 0, 128);
+ mpic1 = mpic_alloc(irqctrler->addrs[0].address,
+ MPIC_PRIMARY | MPIC_WANTS_RESET,
+ 0, 0, 128, 252, senses, 128, " OpenPIC ");
+ BUG_ON(mpic1 == NULL);
+ mpic_init(mpic1);
+
+ if (irqctrler2 != NULL && irqctrler2->n_intrs > 0 &&
+ irqctrler2->n_addrs > 0) {
+ printk(KERN_INFO "Slave OpenPIC at 0x%08x hooked on IRQ %d\n",
+ (u32)irqctrler2->addrs[0].address,
+ irqctrler2->intrs[0].line);
+
+ pmac_call_feature(PMAC_FTR_ENABLE_MPIC, irqctrler2, 0, 0);
+ prom_get_irq_senses(senses, 128, 128 + 124);
+
+ /* We don't need to set MPIC_BROKEN_U3 here since we don't have
+ * hypertransport interrupts routed to it
+ */
+ mpic2 = mpic_alloc(irqctrler2->addrs[0].address,
+ MPIC_BIG_ENDIAN | MPIC_WANTS_RESET,
+ 0, 128, 124, 0, senses, 124,
+ " U3-MPIC ");
+ BUG_ON(mpic2 == NULL);
+ mpic_init(mpic2);
+ mpic_setup_cascade(irqctrler2->intrs[0].line,
+ pmac_u3_cascade, mpic2);
+ }
+#if defined(CONFIG_XMON) && defined(CONFIG_PPC32)
+ {
+ struct device_node* pswitch;
+ int nmi_irq;
+
+ pswitch = find_devices("programmer-switch");
+ if (pswitch && pswitch->n_intrs) {
+ nmi_irq = pswitch->intrs[0].line;
+ mpic_irq_set_priority(nmi_irq, 9);
+ setup_irq(nmi_irq, &xmon_action);
+ }
+ }
+#endif /* CONFIG_XMON */
+ return;
+ }
+ irqctrler = NULL;
+
+#ifdef CONFIG_PPC32
+ /* Get the level/edge settings, assume if it's not
+ * a Grand Central nor an OHare, then it's an Heathrow
+ * (or Paddington).
+ */
+ ppc_md.get_irq = pmac_get_irq;
+ if (find_devices("gc"))
+ level_mask[0] = GC_LEVEL_MASK;
+ else if (find_devices("ohare")) {
+ level_mask[0] = OHARE_LEVEL_MASK;
+ /* We might have a second cascaded ohare */
+ level_mask[1] = OHARE_LEVEL_MASK;
+ } else {
+ level_mask[0] = HEATHROW_LEVEL_MASK;
+ level_mask[1] = 0;
+ /* We might have a second cascaded heathrow */
+ level_mask[2] = HEATHROW_LEVEL_MASK;
+ level_mask[3] = 0;
+ }
+
+ /*
+ * G3 powermacs and 1999 G3 PowerBooks have 64 interrupts,
+ * 1998 G3 Series PowerBooks have 128,
+ * other powermacs have 32.
+ * The combo ethernet/modem card for the Powerstar powerbooks
+ * (2400/3400/3500, ohare based) has a second ohare chip
+ * effectively making a total of 64.
+ */
+ max_irqs = max_real_irqs = 32;
+ irqctrler = find_devices("mac-io");
+ if (irqctrler)
+ {
+ max_real_irqs = 64;
+ if (irqctrler->next)
+ max_irqs = 128;
+ else
+ max_irqs = 64;
+ }
+ for ( i = 0; i < max_real_irqs ; i++ )
+ irq_desc[i].handler = &pmac_pic;
+
+ /* get addresses of first controller */
+ if (irqctrler) {
+ if (irqctrler->n_addrs > 0) {
+ addr = (unsigned long)
+ ioremap(irqctrler->addrs[0].address, 0x40);
+ for (i = 0; i < 2; ++i)
+ pmac_irq_hw[i] = (volatile struct pmac_irq_hw*)
+ (addr + (2 - i) * 0x10);
+ }
+
+ /* get addresses of second controller */
+ irqctrler = irqctrler->next;
+ if (irqctrler && irqctrler->n_addrs > 0) {
+ addr = (unsigned long)
+ ioremap(irqctrler->addrs[0].address, 0x40);
+ for (i = 2; i < 4; ++i)
+ pmac_irq_hw[i] = (volatile struct pmac_irq_hw*)
+ (addr + (4 - i) * 0x10);
+ irq_cascade = irqctrler->intrs[0].line;
+ if (device_is_compatible(irqctrler, "gatwick"))
+ pmac_fix_gatwick_interrupts(irqctrler, max_real_irqs);
+ }
+ } else {
+ /* older powermacs have a GC (grand central) or ohare at
+ f3000000, with interrupt control registers at f3000020. */
+ addr = (unsigned long) ioremap(0xf3000000, 0x40);
+ pmac_irq_hw[0] = (volatile struct pmac_irq_hw *) (addr + 0x20);
+ }
+
+ /* PowerBooks 3400 and 3500 can have a second controller in a second
+ ohare chip, on the combo ethernet/modem card */
+ if (machine_is_compatible("AAPL,3400/2400")
+ || machine_is_compatible("AAPL,3500"))
+ irq_cascade = enable_second_ohare();
+
+ /* disable all interrupts in all controllers */
+ for (i = 0; i * 32 < max_irqs; ++i)
+ out_le32(&pmac_irq_hw[i]->enable, 0);
+ /* mark level interrupts */
+ for (i = 0; i < max_irqs; i++)
+ if (level_mask[i >> 5] & (1UL << (i & 0x1f)))
+ irq_desc[i].status = IRQ_LEVEL;
+
+ /* get interrupt line of secondary interrupt controller */
+ if (irq_cascade >= 0) {
+ printk(KERN_INFO "irq: secondary controller on irq %d\n",
+ (int)irq_cascade);
+ for ( i = max_real_irqs ; i < max_irqs ; i++ )
+ irq_desc[i].handler = &gatwick_pic;
+ setup_irq(irq_cascade, &gatwick_cascade_action);
+ }
+ printk("System has %d possible interrupts\n", max_irqs);
+ if (max_irqs != max_real_irqs)
+ printk(KERN_DEBUG "%d interrupts on main controller\n",
+ max_real_irqs);
+
+#ifdef CONFIG_XMON
+ setup_irq(20, &xmon_action);
+#endif /* CONFIG_XMON */
+#endif /* CONFIG_PPC32 */
+}
+
+#if defined(CONFIG_PM) && defined(CONFIG_PPC32)
+/*
+ * These procedures are used in implementing sleep on the powerbooks.
+ * sleep_save_intrs() saves the states of all interrupt enables
+ * and disables all interrupts except for the nominated one.
+ * sleep_restore_intrs() restores the states of all interrupt enables.
+ */
+unsigned long sleep_save_mask[2];
+
+/* This used to be passed by the PMU driver but that link got
+ * broken with the new driver model. We use this tweak for now...
+ */
+static int pmacpic_find_viaint(void)
+{
+ int viaint = -1;
+
+#ifdef CONFIG_ADB_PMU
+ struct device_node *np;
+
+ if (pmu_get_model() != PMU_OHARE_BASED)
+ goto not_found;
+ np = of_find_node_by_name(NULL, "via-pmu");
+ if (np == NULL)
+ goto not_found;
+ viaint = np->intrs[0].line;
+#endif /* CONFIG_ADB_PMU */
+
+not_found:
+ return viaint;
+}
+
+static int pmacpic_suspend(struct sys_device *sysdev, pm_message_t state)
+{
+ int viaint = pmacpic_find_viaint();
+
+ sleep_save_mask[0] = ppc_cached_irq_mask[0];
+ sleep_save_mask[1] = ppc_cached_irq_mask[1];
+ ppc_cached_irq_mask[0] = 0;
+ ppc_cached_irq_mask[1] = 0;
+ if (viaint > 0)
+ set_bit(viaint, ppc_cached_irq_mask);
+ out_le32(&pmac_irq_hw[0]->enable, ppc_cached_irq_mask[0]);
+ if (max_real_irqs > 32)
+ out_le32(&pmac_irq_hw[1]->enable, ppc_cached_irq_mask[1]);
+ (void)in_le32(&pmac_irq_hw[0]->event);
+ /* make sure mask gets to controller before we return to caller */
+ mb();
+ (void)in_le32(&pmac_irq_hw[0]->enable);
+
+ return 0;
+}
+
+static int pmacpic_resume(struct sys_device *sysdev)
+{
+ int i;
+
+ out_le32(&pmac_irq_hw[0]->enable, 0);
+ if (max_real_irqs > 32)
+ out_le32(&pmac_irq_hw[1]->enable, 0);
+ mb();
+ for (i = 0; i < max_real_irqs; ++i)
+ if (test_bit(i, sleep_save_mask))
+ pmac_unmask_irq(i);
+
+ return 0;
+}
+
+#endif /* CONFIG_PM && CONFIG_PPC32 */
+
+static struct sysdev_class pmacpic_sysclass = {
+ set_kset_name("pmac_pic"),
+};
+
+static struct sys_device device_pmacpic = {
+ .id = 0,
+ .cls = &pmacpic_sysclass,
+};
+
+static struct sysdev_driver driver_pmacpic = {
+#if defined(CONFIG_PM) && defined(CONFIG_PPC32)
+ .suspend = &pmacpic_suspend,
+ .resume = &pmacpic_resume,
+#endif /* CONFIG_PM && CONFIG_PPC32 */
+};
+
+static int __init init_pmacpic_sysfs(void)
+{
+#ifdef CONFIG_PPC32
+ if (max_irqs == 0)
+ return -ENODEV;
+#endif
+ printk(KERN_DEBUG "Registering pmac pic with sysfs...\n");
+ sysdev_class_register(&pmacpic_sysclass);
+ sysdev_register(&device_pmacpic);
+ sysdev_driver_register(&pmacpic_sysclass, &driver_pmacpic);
+ return 0;
+}
+
+subsys_initcall(init_pmacpic_sysfs);
+
diff --git a/arch/powerpc/platforms/powermac/pic.h b/arch/powerpc/platforms/powermac/pic.h
new file mode 100644
index 000000000000..664103dfeef9
--- /dev/null
+++ b/arch/powerpc/platforms/powermac/pic.h
@@ -0,0 +1,11 @@
+#ifndef __PPC_PLATFORMS_PMAC_PIC_H
+#define __PPC_PLATFORMS_PMAC_PIC_H
+
+#include <linux/irq.h>
+
+extern struct hw_interrupt_type pmac_pic;
+
+void pmac_pic_init(void);
+int pmac_get_irq(struct pt_regs *regs);
+
+#endif /* __PPC_PLATFORMS_PMAC_PIC_H */
diff --git a/arch/powerpc/platforms/powermac/pmac.h b/arch/powerpc/platforms/powermac/pmac.h
new file mode 100644
index 000000000000..2ad25e13423e
--- /dev/null
+++ b/arch/powerpc/platforms/powermac/pmac.h
@@ -0,0 +1,51 @@
+#ifndef __PMAC_H__
+#define __PMAC_H__
+
+#include <linux/pci.h>
+#include <linux/ide.h>
+#include <linux/irq.h>
+
+/*
+ * Declaration for the various functions exported by the
+ * pmac_* files. Mostly for use by pmac_setup
+ */
+
+struct rtc_time;
+
+extern long pmac_time_init(void);
+extern unsigned long pmac_get_boot_time(void);
+extern void pmac_get_rtc_time(struct rtc_time *);
+extern int pmac_set_rtc_time(struct rtc_time *);
+extern void pmac_read_rtc_time(void);
+extern void pmac_calibrate_decr(void);
+extern void pmac_pcibios_fixup(void);
+extern void pmac_pci_init(void);
+extern unsigned long pmac_ide_get_base(int index);
+extern void pmac_ide_init_hwif_ports(hw_regs_t *hw,
+ unsigned long data_port, unsigned long ctrl_port, int *irq);
+
+extern void pmac_nvram_update(void);
+extern unsigned char pmac_nvram_read_byte(int addr);
+extern void pmac_nvram_write_byte(int addr, unsigned char val);
+extern int pmac_pci_enable_device_hook(struct pci_dev *dev, int initial);
+extern void pmac_pcibios_after_init(void);
+extern int of_show_percpuinfo(struct seq_file *m, int i);
+
+extern void pmac_pci_init(void);
+extern void pmac_setup_pci_dma(void);
+extern void pmac_check_ht_link(void);
+
+extern void pmac_setup_smp(void);
+
+extern unsigned long pmac_ide_get_base(int index);
+extern void pmac_ide_init_hwif_ports(hw_regs_t *hw,
+ unsigned long data_port, unsigned long ctrl_port, int *irq);
+
+extern int pmac_nvram_init(void);
+
+extern struct hw_interrupt_type pmac_pic;
+
+void pmac_pic_init(void);
+int pmac_get_irq(struct pt_regs *regs);
+
+#endif /* __PMAC_H__ */
diff --git a/arch/powerpc/platforms/powermac/setup.c b/arch/powerpc/platforms/powermac/setup.c
new file mode 100644
index 000000000000..7acb0546671f
--- /dev/null
+++ b/arch/powerpc/platforms/powermac/setup.c
@@ -0,0 +1,782 @@
+/*
+ * Powermac setup and early boot code plus other random bits.
+ *
+ * PowerPC version
+ * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
+ *
+ * Adapted for Power Macintosh by Paul Mackerras
+ * Copyright (C) 1996 Paul Mackerras (paulus@samba.org)
+ *
+ * Derived from "arch/alpha/kernel/setup.c"
+ * Copyright (C) 1995 Linus Torvalds
+ *
+ * Maintained by Benjamin Herrenschmidt (benh@kernel.crashing.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.
+ *
+ */
+
+/*
+ * bootup setup stuff..
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/stddef.h>
+#include <linux/unistd.h>
+#include <linux/ptrace.h>
+#include <linux/slab.h>
+#include <linux/user.h>
+#include <linux/a.out.h>
+#include <linux/tty.h>
+#include <linux/string.h>
+#include <linux/delay.h>
+#include <linux/ioport.h>
+#include <linux/major.h>
+#include <linux/initrd.h>
+#include <linux/vt_kern.h>
+#include <linux/console.h>
+#include <linux/ide.h>
+#include <linux/pci.h>
+#include <linux/adb.h>
+#include <linux/cuda.h>
+#include <linux/pmu.h>
+#include <linux/irq.h>
+#include <linux/seq_file.h>
+#include <linux/root_dev.h>
+#include <linux/bitops.h>
+#include <linux/suspend.h>
+
+#include <asm/reg.h>
+#include <asm/sections.h>
+#include <asm/prom.h>
+#include <asm/system.h>
+#include <asm/pgtable.h>
+#include <asm/io.h>
+#include <asm/pci-bridge.h>
+#include <asm/ohare.h>
+#include <asm/mediabay.h>
+#include <asm/machdep.h>
+#include <asm/dma.h>
+#include <asm/cputable.h>
+#include <asm/btext.h>
+#include <asm/pmac_feature.h>
+#include <asm/time.h>
+#include <asm/of_device.h>
+#include <asm/mmu_context.h>
+#include <asm/iommu.h>
+#include <asm/smu.h>
+#include <asm/pmc.h>
+#include <asm/mpic.h>
+#include <asm/lmb.h>
+
+#include "pmac.h"
+
+#undef SHOW_GATWICK_IRQS
+
+unsigned char drive_info;
+
+int ppc_override_l2cr = 0;
+int ppc_override_l2cr_value;
+int has_l2cache = 0;
+
+int pmac_newworld = 1;
+
+static int current_root_goodness = -1;
+
+extern int pmac_newworld;
+extern struct machdep_calls pmac_md;
+
+#define DEFAULT_ROOT_DEVICE Root_SDA1 /* sda1 - slightly silly choice */
+
+#ifdef CONFIG_PPC64
+#include <asm/udbg.h>
+int sccdbg;
+#endif
+
+extern void zs_kgdb_hook(int tty_num);
+
+sys_ctrler_t sys_ctrler = SYS_CTRLER_UNKNOWN;
+EXPORT_SYMBOL(sys_ctrler);
+
+#ifdef CONFIG_PMAC_SMU
+unsigned long smu_cmdbuf_abs;
+EXPORT_SYMBOL(smu_cmdbuf_abs);
+#endif
+
+#ifdef CONFIG_SMP
+extern struct smp_ops_t psurge_smp_ops;
+extern struct smp_ops_t core99_smp_ops;
+#endif /* CONFIG_SMP */
+
+static void pmac_show_cpuinfo(struct seq_file *m)
+{
+ struct device_node *np;
+ char *pp;
+ int plen;
+ int mbmodel;
+ unsigned int mbflags;
+ char* mbname;
+
+ mbmodel = pmac_call_feature(PMAC_FTR_GET_MB_INFO, NULL,
+ PMAC_MB_INFO_MODEL, 0);
+ mbflags = pmac_call_feature(PMAC_FTR_GET_MB_INFO, NULL,
+ PMAC_MB_INFO_FLAGS, 0);
+ if (pmac_call_feature(PMAC_FTR_GET_MB_INFO, NULL, PMAC_MB_INFO_NAME,
+ (long) &mbname) != 0)
+ mbname = "Unknown";
+
+ /* find motherboard type */
+ seq_printf(m, "machine\t\t: ");
+ np = of_find_node_by_path("/");
+ if (np != NULL) {
+ pp = (char *) get_property(np, "model", NULL);
+ if (pp != NULL)
+ seq_printf(m, "%s\n", pp);
+ else
+ seq_printf(m, "PowerMac\n");
+ pp = (char *) get_property(np, "compatible", &plen);
+ if (pp != NULL) {
+ seq_printf(m, "motherboard\t:");
+ while (plen > 0) {
+ int l = strlen(pp) + 1;
+ seq_printf(m, " %s", pp);
+ plen -= l;
+ pp += l;
+ }
+ seq_printf(m, "\n");
+ }
+ of_node_put(np);
+ } else
+ seq_printf(m, "PowerMac\n");
+
+ /* print parsed model */
+ seq_printf(m, "detected as\t: %d (%s)\n", mbmodel, mbname);
+ seq_printf(m, "pmac flags\t: %08x\n", mbflags);
+
+ /* find l2 cache info */
+ np = of_find_node_by_name(NULL, "l2-cache");
+ if (np == NULL)
+ np = of_find_node_by_type(NULL, "cache");
+ if (np != NULL) {
+ unsigned int *ic = (unsigned int *)
+ get_property(np, "i-cache-size", NULL);
+ unsigned int *dc = (unsigned int *)
+ get_property(np, "d-cache-size", NULL);
+ seq_printf(m, "L2 cache\t:");
+ has_l2cache = 1;
+ if (get_property(np, "cache-unified", NULL) != 0 && dc) {
+ seq_printf(m, " %dK unified", *dc / 1024);
+ } else {
+ if (ic)
+ seq_printf(m, " %dK instruction", *ic / 1024);
+ if (dc)
+ seq_printf(m, "%s %dK data",
+ (ic? " +": ""), *dc / 1024);
+ }
+ pp = get_property(np, "ram-type", NULL);
+ if (pp)
+ seq_printf(m, " %s", pp);
+ seq_printf(m, "\n");
+ of_node_put(np);
+ }
+
+ /* Indicate newworld/oldworld */
+ seq_printf(m, "pmac-generation\t: %s\n",
+ pmac_newworld ? "NewWorld" : "OldWorld");
+}
+
+#ifndef CONFIG_ADB_CUDA
+int find_via_cuda(void)
+{
+ if (!find_devices("via-cuda"))
+ return 0;
+ printk("WARNING ! Your machine is CUDA-based but your kernel\n");
+ printk(" wasn't compiled with CONFIG_ADB_CUDA option !\n");
+ return 0;
+}
+#endif
+
+#ifndef CONFIG_ADB_PMU
+int find_via_pmu(void)
+{
+ if (!find_devices("via-pmu"))
+ return 0;
+ printk("WARNING ! Your machine is PMU-based but your kernel\n");
+ printk(" wasn't compiled with CONFIG_ADB_PMU option !\n");
+ return 0;
+}
+#endif
+
+#ifndef CONFIG_PMAC_SMU
+int smu_init(void)
+{
+ /* should check and warn if SMU is present */
+ return 0;
+}
+#endif
+
+#ifdef CONFIG_PPC32
+static volatile u32 *sysctrl_regs;
+
+static void __init ohare_init(void)
+{
+ /* this area has the CPU identification register
+ and some registers used by smp boards */
+ sysctrl_regs = (volatile u32 *) ioremap(0xf8000000, 0x1000);
+
+ /*
+ * Turn on the L2 cache.
+ * We assume that we have a PSX memory controller iff
+ * we have an ohare I/O controller.
+ */
+ if (find_devices("ohare") != NULL) {
+ if (((sysctrl_regs[2] >> 24) & 0xf) >= 3) {
+ if (sysctrl_regs[4] & 0x10)
+ sysctrl_regs[4] |= 0x04000020;
+ else
+ sysctrl_regs[4] |= 0x04000000;
+ if(has_l2cache)
+ printk(KERN_INFO "Level 2 cache enabled\n");
+ }
+ }
+}
+
+static void __init l2cr_init(void)
+{
+ /* Checks "l2cr-value" property in the registry */
+ if (cpu_has_feature(CPU_FTR_L2CR)) {
+ struct device_node *np = find_devices("cpus");
+ if (np == 0)
+ np = find_type_devices("cpu");
+ if (np != 0) {
+ unsigned int *l2cr = (unsigned int *)
+ get_property(np, "l2cr-value", NULL);
+ if (l2cr != 0) {
+ ppc_override_l2cr = 1;
+ ppc_override_l2cr_value = *l2cr;
+ _set_L2CR(0);
+ _set_L2CR(ppc_override_l2cr_value);
+ }
+ }
+ }
+
+ if (ppc_override_l2cr)
+ printk(KERN_INFO "L2CR overridden (0x%x), "
+ "backside cache is %s\n",
+ ppc_override_l2cr_value,
+ (ppc_override_l2cr_value & 0x80000000)
+ ? "enabled" : "disabled");
+}
+#endif
+
+void __init pmac_setup_arch(void)
+{
+ struct device_node *cpu, *ic;
+ int *fp;
+ unsigned long pvr;
+
+ pvr = PVR_VER(mfspr(SPRN_PVR));
+
+ /* Set loops_per_jiffy to a half-way reasonable value,
+ for use until calibrate_delay gets called. */
+ loops_per_jiffy = 50000000 / HZ;
+ cpu = of_find_node_by_type(NULL, "cpu");
+ if (cpu != NULL) {
+ fp = (int *) get_property(cpu, "clock-frequency", NULL);
+ if (fp != NULL) {
+ if (pvr >= 0x30 && pvr < 0x80)
+ /* PPC970 etc. */
+ loops_per_jiffy = *fp / (3 * HZ);
+ else if (pvr == 4 || pvr >= 8)
+ /* 604, G3, G4 etc. */
+ loops_per_jiffy = *fp / HZ;
+ else
+ /* 601, 603, etc. */
+ loops_per_jiffy = *fp / (2 * HZ);
+ }
+ of_node_put(cpu);
+ }
+
+ /* See if newworld or oldworld */
+ for (ic = NULL; (ic = of_find_all_nodes(ic)) != NULL; )
+ if (get_property(ic, "interrupt-controller", NULL))
+ break;
+ pmac_newworld = (ic != NULL);
+ if (ic)
+ of_node_put(ic);
+
+ /* Lookup PCI hosts */
+ pmac_pci_init();
+
+#ifdef CONFIG_PPC32
+ ohare_init();
+ l2cr_init();
+#endif /* CONFIG_PPC32 */
+
+#ifdef CONFIG_PPC64
+ /* Probe motherboard chipset */
+ /* this is done earlier in setup_arch for 32-bit */
+ pmac_feature_init();
+
+ /* We can NAP */
+ powersave_nap = 1;
+ printk(KERN_INFO "Using native/NAP idle loop\n");
+#endif
+
+#ifdef CONFIG_KGDB
+ zs_kgdb_hook(0);
+#endif
+
+ find_via_cuda();
+ find_via_pmu();
+ smu_init();
+
+#if defined(CONFIG_NVRAM) || defined(CONFIG_PPC64)
+ pmac_nvram_init();
+#endif
+
+#ifdef CONFIG_PPC32
+#ifdef CONFIG_BLK_DEV_INITRD
+ if (initrd_start)
+ ROOT_DEV = Root_RAM0;
+ else
+#endif
+ ROOT_DEV = DEFAULT_ROOT_DEVICE;
+#endif
+
+#ifdef CONFIG_SMP
+ /* Check for Core99 */
+ if (find_devices("uni-n") || find_devices("u3"))
+ smp_ops = &core99_smp_ops;
+#ifdef CONFIG_PPC32
+ else
+ smp_ops = &psurge_smp_ops;
+#endif
+#endif /* CONFIG_SMP */
+}
+
+char *bootpath;
+char *bootdevice;
+void *boot_host;
+int boot_target;
+int boot_part;
+extern dev_t boot_dev;
+
+#ifdef CONFIG_SCSI
+void __init note_scsi_host(struct device_node *node, void *host)
+{
+ int l;
+ char *p;
+
+ l = strlen(node->full_name);
+ if (bootpath != NULL && bootdevice != NULL
+ && strncmp(node->full_name, bootdevice, l) == 0
+ && (bootdevice[l] == '/' || bootdevice[l] == 0)) {
+ boot_host = host;
+ /*
+ * There's a bug in OF 1.0.5. (Why am I not surprised.)
+ * If you pass a path like scsi/sd@1:0 to canon, it returns
+ * something like /bandit@F2000000/gc@10/53c94@10000/sd@0,0
+ * That is, the scsi target number doesn't get preserved.
+ * So we pick the target number out of bootpath and use that.
+ */
+ p = strstr(bootpath, "/sd@");
+ if (p != NULL) {
+ p += 4;
+ boot_target = simple_strtoul(p, NULL, 10);
+ p = strchr(p, ':');
+ if (p != NULL)
+ boot_part = simple_strtoul(p + 1, NULL, 10);
+ }
+ }
+}
+EXPORT_SYMBOL(note_scsi_host);
+#endif
+
+#if defined(CONFIG_BLK_DEV_IDE) && defined(CONFIG_BLK_DEV_IDE_PMAC)
+static dev_t __init find_ide_boot(void)
+{
+ char *p;
+ int n;
+ dev_t __init pmac_find_ide_boot(char *bootdevice, int n);
+
+ if (bootdevice == NULL)
+ return 0;
+ p = strrchr(bootdevice, '/');
+ if (p == NULL)
+ return 0;
+ n = p - bootdevice;
+
+ return pmac_find_ide_boot(bootdevice, n);
+}
+#endif /* CONFIG_BLK_DEV_IDE && CONFIG_BLK_DEV_IDE_PMAC */
+
+static void __init find_boot_device(void)
+{
+#if defined(CONFIG_BLK_DEV_IDE) && defined(CONFIG_BLK_DEV_IDE_PMAC)
+ boot_dev = find_ide_boot();
+#endif
+}
+
+/* TODO: Merge the suspend-to-ram with the common code !!!
+ * currently, this is a stub implementation for suspend-to-disk
+ * only
+ */
+
+#ifdef CONFIG_SOFTWARE_SUSPEND
+
+static int pmac_pm_prepare(suspend_state_t state)
+{
+ printk(KERN_DEBUG "%s(%d)\n", __FUNCTION__, state);
+
+ return 0;
+}
+
+static int pmac_pm_enter(suspend_state_t state)
+{
+ printk(KERN_DEBUG "%s(%d)\n", __FUNCTION__, state);
+
+ /* Giveup the lazy FPU & vec so we don't have to back them
+ * up from the low level code
+ */
+ enable_kernel_fp();
+
+#ifdef CONFIG_ALTIVEC
+ if (cur_cpu_spec->cpu_features & CPU_FTR_ALTIVEC)
+ enable_kernel_altivec();
+#endif /* CONFIG_ALTIVEC */
+
+ return 0;
+}
+
+static int pmac_pm_finish(suspend_state_t state)
+{
+ printk(KERN_DEBUG "%s(%d)\n", __FUNCTION__, state);
+
+ /* Restore userland MMU context */
+ set_context(current->active_mm->context, current->active_mm->pgd);
+
+ return 0;
+}
+
+static struct pm_ops pmac_pm_ops = {
+ .pm_disk_mode = PM_DISK_SHUTDOWN,
+ .prepare = pmac_pm_prepare,
+ .enter = pmac_pm_enter,
+ .finish = pmac_pm_finish,
+};
+
+#endif /* CONFIG_SOFTWARE_SUSPEND */
+
+static int initializing = 1;
+
+static int pmac_late_init(void)
+{
+ initializing = 0;
+#ifdef CONFIG_SOFTWARE_SUSPEND
+ pm_set_ops(&pmac_pm_ops);
+#endif /* CONFIG_SOFTWARE_SUSPEND */
+ return 0;
+}
+
+late_initcall(pmac_late_init);
+
+/* can't be __init - can be called whenever a disk is first accessed */
+void note_bootable_part(dev_t dev, int part, int goodness)
+{
+ static int found_boot = 0;
+ char *p;
+
+ if (!initializing)
+ return;
+ if ((goodness <= current_root_goodness) &&
+ ROOT_DEV != DEFAULT_ROOT_DEVICE)
+ return;
+ p = strstr(saved_command_line, "root=");
+ if (p != NULL && (p == saved_command_line || p[-1] == ' '))
+ return;
+
+ if (!found_boot) {
+ find_boot_device();
+ found_boot = 1;
+ }
+ if (!boot_dev || dev == boot_dev) {
+ ROOT_DEV = dev + part;
+ boot_dev = 0;
+ current_root_goodness = goodness;
+ }
+}
+
+#ifdef CONFIG_ADB_CUDA
+static void cuda_restart(void)
+{
+ struct adb_request req;
+
+ cuda_request(&req, NULL, 2, CUDA_PACKET, CUDA_RESET_SYSTEM);
+ for (;;)
+ cuda_poll();
+}
+
+static void cuda_shutdown(void)
+{
+ struct adb_request req;
+
+ cuda_request(&req, NULL, 2, CUDA_PACKET, CUDA_POWERDOWN);
+ for (;;)
+ cuda_poll();
+}
+
+#else
+#define cuda_restart()
+#define cuda_shutdown()
+#endif
+
+#ifndef CONFIG_ADB_PMU
+#define pmu_restart()
+#define pmu_shutdown()
+#endif
+
+#ifndef CONFIG_PMAC_SMU
+#define smu_restart()
+#define smu_shutdown()
+#endif
+
+static void pmac_restart(char *cmd)
+{
+ switch (sys_ctrler) {
+ case SYS_CTRLER_CUDA:
+ cuda_restart();
+ break;
+ case SYS_CTRLER_PMU:
+ pmu_restart();
+ break;
+ case SYS_CTRLER_SMU:
+ smu_restart();
+ break;
+ default: ;
+ }
+}
+
+static void pmac_power_off(void)
+{
+ switch (sys_ctrler) {
+ case SYS_CTRLER_CUDA:
+ cuda_shutdown();
+ break;
+ case SYS_CTRLER_PMU:
+ pmu_shutdown();
+ break;
+ case SYS_CTRLER_SMU:
+ smu_shutdown();
+ break;
+ default: ;
+ }
+}
+
+static void
+pmac_halt(void)
+{
+ pmac_power_off();
+}
+
+#ifdef CONFIG_PPC32
+void __init pmac_init(void)
+{
+ /* isa_io_base gets set in pmac_pci_init */
+ isa_mem_base = PMAC_ISA_MEM_BASE;
+ pci_dram_offset = PMAC_PCI_DRAM_OFFSET;
+ ISA_DMA_THRESHOLD = ~0L;
+ DMA_MODE_READ = 1;
+ DMA_MODE_WRITE = 2;
+
+ ppc_md = pmac_md;
+
+#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
+#ifdef CONFIG_BLK_DEV_IDE_PMAC
+ ppc_ide_md.ide_init_hwif = pmac_ide_init_hwif_ports;
+ ppc_ide_md.default_io_base = pmac_ide_get_base;
+#endif /* CONFIG_BLK_DEV_IDE_PMAC */
+#endif /* defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) */
+
+ if (ppc_md.progress) ppc_md.progress("pmac_init(): exit", 0);
+
+}
+#endif
+
+/*
+ * Early initialization.
+ */
+static void __init pmac_init_early(void)
+{
+#ifdef CONFIG_PPC64
+ /* Initialize hash table, from now on, we can take hash faults
+ * and call ioremap
+ */
+ hpte_init_native();
+
+ /* Init SCC */
+ if (strstr(cmd_line, "sccdbg")) {
+ sccdbg = 1;
+ udbg_init_scc(NULL);
+ }
+
+ /* Setup interrupt mapping options */
+ ppc64_interrupt_controller = IC_OPEN_PIC;
+
+ iommu_init_early_u3();
+#endif
+}
+
+static void __init pmac_progress(char *s, unsigned short hex)
+{
+#ifdef CONFIG_PPC64
+ if (sccdbg) {
+ udbg_puts(s);
+ udbg_puts("\n");
+ return;
+ }
+#endif
+#ifdef CONFIG_BOOTX_TEXT
+ if (boot_text_mapped) {
+ btext_drawstring(s);
+ btext_drawchar('\n');
+ }
+#endif /* CONFIG_BOOTX_TEXT */
+}
+
+/*
+ * pmac has no legacy IO, anything calling this function has to
+ * fail or bad things will happen
+ */
+static int pmac_check_legacy_ioport(unsigned int baseport)
+{
+ return -ENODEV;
+}
+
+static int __init pmac_declare_of_platform_devices(void)
+{
+ struct device_node *np, *npp;
+
+ np = find_devices("uni-n");
+ if (np) {
+ for (np = np->child; np != NULL; np = np->sibling)
+ if (strncmp(np->name, "i2c", 3) == 0) {
+ of_platform_device_create(np, "uni-n-i2c",
+ NULL);
+ break;
+ }
+ }
+ np = find_devices("valkyrie");
+ if (np)
+ of_platform_device_create(np, "valkyrie", NULL);
+ np = find_devices("platinum");
+ if (np)
+ of_platform_device_create(np, "platinum", NULL);
+
+ npp = of_find_node_by_name(NULL, "u3");
+ if (npp) {
+ for (np = NULL; (np = of_get_next_child(npp, np)) != NULL;) {
+ if (strncmp(np->name, "i2c", 3) == 0) {
+ of_platform_device_create(np, "u3-i2c", NULL);
+ of_node_put(np);
+ break;
+ }
+ }
+ of_node_put(npp);
+ }
+ np = of_find_node_by_type(NULL, "smu");
+ if (np) {
+ of_platform_device_create(np, "smu", NULL);
+ of_node_put(np);
+ }
+
+ return 0;
+}
+
+device_initcall(pmac_declare_of_platform_devices);
+
+/*
+ * Called very early, MMU is off, device-tree isn't unflattened
+ */
+static int __init pmac_probe(int platform)
+{
+#ifdef CONFIG_PPC64
+ if (platform != PLATFORM_POWERMAC)
+ return 0;
+
+ /*
+ * On U3, the DART (iommu) must be allocated now since it
+ * has an impact on htab_initialize (due to the large page it
+ * occupies having to be broken up so the DART itself is not
+ * part of the cacheable linar mapping
+ */
+ alloc_u3_dart_table();
+#endif
+
+#ifdef CONFIG_PMAC_SMU
+ /*
+ * SMU based G5s need some memory below 2Gb, at least the current
+ * driver needs that. We have to allocate it now. We allocate 4k
+ * (1 small page) for now.
+ */
+ smu_cmdbuf_abs = lmb_alloc_base(4096, 4096, 0x80000000UL);
+#endif /* CONFIG_PMAC_SMU */
+
+ return 1;
+}
+
+#ifdef CONFIG_PPC64
+static int pmac_probe_mode(struct pci_bus *bus)
+{
+ struct device_node *node = bus->sysdata;
+
+ /* We need to use normal PCI probing for the AGP bus,
+ since the device for the AGP bridge isn't in the tree. */
+ if (bus->self == NULL && device_is_compatible(node, "u3-agp"))
+ return PCI_PROBE_NORMAL;
+
+ return PCI_PROBE_DEVTREE;
+}
+#endif
+
+struct machdep_calls __initdata pmac_md = {
+#if defined(CONFIG_HOTPLUG_CPU) && defined(CONFIG_PPC64)
+ .cpu_die = generic_mach_cpu_die,
+#endif
+ .probe = pmac_probe,
+ .setup_arch = pmac_setup_arch,
+ .init_early = pmac_init_early,
+ .show_cpuinfo = pmac_show_cpuinfo,
+ .init_IRQ = pmac_pic_init,
+ .get_irq = mpic_get_irq, /* changed later */
+ .pcibios_fixup = pmac_pcibios_fixup,
+ .restart = pmac_restart,
+ .power_off = pmac_power_off,
+ .halt = pmac_halt,
+ .time_init = pmac_time_init,
+ .get_boot_time = pmac_get_boot_time,
+ .set_rtc_time = pmac_set_rtc_time,
+ .get_rtc_time = pmac_get_rtc_time,
+ .calibrate_decr = pmac_calibrate_decr,
+ .feature_call = pmac_do_feature_call,
+ .check_legacy_ioport = pmac_check_legacy_ioport,
+ .progress = pmac_progress,
+#ifdef CONFIG_PPC64
+ .pci_probe_mode = pmac_probe_mode,
+ .idle_loop = native_idle,
+ .enable_pmcs = power4_enable_pmcs,
+#endif
+#ifdef CONFIG_PPC32
+ .pcibios_enable_device_hook = pmac_pci_enable_device_hook,
+ .pcibios_after_init = pmac_pcibios_after_init,
+ .phys_mem_access_prot = pci_phys_mem_access_prot,
+#endif
+};
diff --git a/arch/powerpc/platforms/powermac/sleep.S b/arch/powerpc/platforms/powermac/sleep.S
new file mode 100644
index 000000000000..22b113d19b24
--- /dev/null
+++ b/arch/powerpc/platforms/powermac/sleep.S
@@ -0,0 +1,396 @@
+/*
+ * This file contains sleep low-level functions for PowerBook G3.
+ * Copyright (C) 1999 Benjamin Herrenschmidt (benh@kernel.crashing.org)
+ * and Paul Mackerras (paulus@samba.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/config.h>
+#include <asm/processor.h>
+#include <asm/page.h>
+#include <asm/ppc_asm.h>
+#include <asm/cputable.h>
+#include <asm/cache.h>
+#include <asm/thread_info.h>
+#include <asm/asm-offsets.h>
+
+#define MAGIC 0x4c617273 /* 'Lars' */
+
+/*
+ * Structure for storing CPU registers on the stack.
+ */
+#define SL_SP 0
+#define SL_PC 4
+#define SL_MSR 8
+#define SL_SDR1 0xc
+#define SL_SPRG0 0x10 /* 4 sprg's */
+#define SL_DBAT0 0x20
+#define SL_IBAT0 0x28
+#define SL_DBAT1 0x30
+#define SL_IBAT1 0x38
+#define SL_DBAT2 0x40
+#define SL_IBAT2 0x48
+#define SL_DBAT3 0x50
+#define SL_IBAT3 0x58
+#define SL_TB 0x60
+#define SL_R2 0x68
+#define SL_CR 0x6c
+#define SL_R12 0x70 /* r12 to r31 */
+#define SL_SIZE (SL_R12 + 80)
+
+ .section .text
+ .align 5
+
+#if defined(CONFIG_PM) || defined(CONFIG_CPU_FREQ_PMAC)
+
+/* This gets called by via-pmu.c late during the sleep process.
+ * The PMU was already send the sleep command and will shut us down
+ * soon. We need to save all that is needed and setup the wakeup
+ * vector that will be called by the ROM on wakeup
+ */
+_GLOBAL(low_sleep_handler)
+#ifndef CONFIG_6xx
+ blr
+#else
+ mflr r0
+ stw r0,4(r1)
+ stwu r1,-SL_SIZE(r1)
+ mfcr r0
+ stw r0,SL_CR(r1)
+ stw r2,SL_R2(r1)
+ stmw r12,SL_R12(r1)
+
+ /* Save MSR & SDR1 */
+ mfmsr r4
+ stw r4,SL_MSR(r1)
+ mfsdr1 r4
+ stw r4,SL_SDR1(r1)
+
+ /* Get a stable timebase and save it */
+1: mftbu r4
+ stw r4,SL_TB(r1)
+ mftb r5
+ stw r5,SL_TB+4(r1)
+ mftbu r3
+ cmpw r3,r4
+ bne 1b
+
+ /* Save SPRGs */
+ mfsprg r4,0
+ stw r4,SL_SPRG0(r1)
+ mfsprg r4,1
+ stw r4,SL_SPRG0+4(r1)
+ mfsprg r4,2
+ stw r4,SL_SPRG0+8(r1)
+ mfsprg r4,3
+ stw r4,SL_SPRG0+12(r1)
+
+ /* Save BATs */
+ mfdbatu r4,0
+ stw r4,SL_DBAT0(r1)
+ mfdbatl r4,0
+ stw r4,SL_DBAT0+4(r1)
+ mfdbatu r4,1
+ stw r4,SL_DBAT1(r1)
+ mfdbatl r4,1
+ stw r4,SL_DBAT1+4(r1)
+ mfdbatu r4,2
+ stw r4,SL_DBAT2(r1)
+ mfdbatl r4,2
+ stw r4,SL_DBAT2+4(r1)
+ mfdbatu r4,3
+ stw r4,SL_DBAT3(r1)
+ mfdbatl r4,3
+ stw r4,SL_DBAT3+4(r1)
+ mfibatu r4,0
+ stw r4,SL_IBAT0(r1)
+ mfibatl r4,0
+ stw r4,SL_IBAT0+4(r1)
+ mfibatu r4,1
+ stw r4,SL_IBAT1(r1)
+ mfibatl r4,1
+ stw r4,SL_IBAT1+4(r1)
+ mfibatu r4,2
+ stw r4,SL_IBAT2(r1)
+ mfibatl r4,2
+ stw r4,SL_IBAT2+4(r1)
+ mfibatu r4,3
+ stw r4,SL_IBAT3(r1)
+ mfibatl r4,3
+ stw r4,SL_IBAT3+4(r1)
+
+ /* Backup various CPU config stuffs */
+ bl __save_cpu_setup
+
+ /* The ROM can wake us up via 2 different vectors:
+ * - On wallstreet & lombard, we must write a magic
+ * value 'Lars' at address 4 and a pointer to a
+ * memory location containing the PC to resume from
+ * at address 0.
+ * - On Core99, we must store the wakeup vector at
+ * address 0x80 and eventually it's parameters
+ * at address 0x84. I've have some trouble with those
+ * parameters however and I no longer use them.
+ */
+ lis r5,grackle_wake_up@ha
+ addi r5,r5,grackle_wake_up@l
+ tophys(r5,r5)
+ stw r5,SL_PC(r1)
+ lis r4,KERNELBASE@h
+ tophys(r5,r1)
+ addi r5,r5,SL_PC
+ lis r6,MAGIC@ha
+ addi r6,r6,MAGIC@l
+ stw r5,0(r4)
+ stw r6,4(r4)
+ /* Setup stuffs at 0x80-0x84 for Core99 */
+ lis r3,core99_wake_up@ha
+ addi r3,r3,core99_wake_up@l
+ tophys(r3,r3)
+ stw r3,0x80(r4)
+ stw r5,0x84(r4)
+ /* Store a pointer to our backup storage into
+ * a kernel global
+ */
+ lis r3,sleep_storage@ha
+ addi r3,r3,sleep_storage@l
+ stw r5,0(r3)
+
+ .globl low_cpu_die
+low_cpu_die:
+ /* Flush & disable all caches */
+ bl flush_disable_caches
+
+ /* Turn off data relocation. */
+ mfmsr r3 /* Save MSR in r7 */
+ rlwinm r3,r3,0,28,26 /* Turn off DR bit */
+ sync
+ mtmsr r3
+ isync
+
+BEGIN_FTR_SECTION
+ /* Flush any pending L2 data prefetches to work around HW bug */
+ sync
+ lis r3,0xfff0
+ lwz r0,0(r3) /* perform cache-inhibited load to ROM */
+ sync /* (caches are disabled at this point) */
+END_FTR_SECTION_IFSET(CPU_FTR_SPEC7450)
+
+/*
+ * Set the HID0 and MSR for sleep.
+ */
+ mfspr r2,SPRN_HID0
+ rlwinm r2,r2,0,10,7 /* clear doze, nap */
+ oris r2,r2,HID0_SLEEP@h
+ sync
+ isync
+ mtspr SPRN_HID0,r2
+ sync
+
+/* This loop puts us back to sleep in case we have a spurrious
+ * wakeup so that the host bridge properly stays asleep. The
+ * CPU will be turned off, either after a known time (about 1
+ * second) on wallstreet & lombard, or as soon as the CPU enters
+ * SLEEP mode on core99
+ */
+ mfmsr r2
+ oris r2,r2,MSR_POW@h
+1: sync
+ mtmsr r2
+ isync
+ b 1b
+
+/*
+ * Here is the resume code.
+ */
+
+
+/*
+ * Core99 machines resume here
+ * r4 has the physical address of SL_PC(sp) (unused)
+ */
+_GLOBAL(core99_wake_up)
+ /* Make sure HID0 no longer contains any sleep bit and that data cache
+ * is disabled
+ */
+ mfspr r3,SPRN_HID0
+ rlwinm r3,r3,0,11,7 /* clear SLEEP, NAP, DOZE bits */
+ rlwinm 3,r3,0,18,15 /* clear DCE, ICE */
+ mtspr SPRN_HID0,r3
+ sync
+ isync
+
+ /* sanitize MSR */
+ mfmsr r3
+ ori r3,r3,MSR_EE|MSR_IP
+ xori r3,r3,MSR_EE|MSR_IP
+ sync
+ isync
+ mtmsr r3
+ sync
+ isync
+
+ /* Recover sleep storage */
+ lis r3,sleep_storage@ha
+ addi r3,r3,sleep_storage@l
+ tophys(r3,r3)
+ lwz r1,0(r3)
+
+ /* Pass thru to older resume code ... */
+/*
+ * Here is the resume code for older machines.
+ * r1 has the physical address of SL_PC(sp).
+ */
+
+grackle_wake_up:
+
+ /* Restore the kernel's segment registers before
+ * we do any r1 memory access as we are not sure they
+ * are in a sane state above the first 256Mb region
+ */
+ li r0,16 /* load up segment register values */
+ mtctr r0 /* for context 0 */
+ lis r3,0x2000 /* Ku = 1, VSID = 0 */
+ li r4,0
+3: mtsrin r3,r4
+ addi r3,r3,0x111 /* increment VSID */
+ addis r4,r4,0x1000 /* address of next segment */
+ bdnz 3b
+ sync
+ isync
+
+ subi r1,r1,SL_PC
+
+ /* Restore various CPU config stuffs */
+ bl __restore_cpu_setup
+
+ /* Make sure all FPRs have been initialized */
+ bl reloc_offset
+ bl __init_fpu_registers
+
+ /* Invalidate & enable L1 cache, we don't care about
+ * whatever the ROM may have tried to write to memory
+ */
+ bl __inval_enable_L1
+
+ /* Restore the BATs, and SDR1. Then we can turn on the MMU. */
+ lwz r4,SL_SDR1(r1)
+ mtsdr1 r4
+ lwz r4,SL_SPRG0(r1)
+ mtsprg 0,r4
+ lwz r4,SL_SPRG0+4(r1)
+ mtsprg 1,r4
+ lwz r4,SL_SPRG0+8(r1)
+ mtsprg 2,r4
+ lwz r4,SL_SPRG0+12(r1)
+ mtsprg 3,r4
+
+ lwz r4,SL_DBAT0(r1)
+ mtdbatu 0,r4
+ lwz r4,SL_DBAT0+4(r1)
+ mtdbatl 0,r4
+ lwz r4,SL_DBAT1(r1)
+ mtdbatu 1,r4
+ lwz r4,SL_DBAT1+4(r1)
+ mtdbatl 1,r4
+ lwz r4,SL_DBAT2(r1)
+ mtdbatu 2,r4
+ lwz r4,SL_DBAT2+4(r1)
+ mtdbatl 2,r4
+ lwz r4,SL_DBAT3(r1)
+ mtdbatu 3,r4
+ lwz r4,SL_DBAT3+4(r1)
+ mtdbatl 3,r4
+ lwz r4,SL_IBAT0(r1)
+ mtibatu 0,r4
+ lwz r4,SL_IBAT0+4(r1)
+ mtibatl 0,r4
+ lwz r4,SL_IBAT1(r1)
+ mtibatu 1,r4
+ lwz r4,SL_IBAT1+4(r1)
+ mtibatl 1,r4
+ lwz r4,SL_IBAT2(r1)
+ mtibatu 2,r4
+ lwz r4,SL_IBAT2+4(r1)
+ mtibatl 2,r4
+ lwz r4,SL_IBAT3(r1)
+ mtibatu 3,r4
+ lwz r4,SL_IBAT3+4(r1)
+ mtibatl 3,r4
+
+BEGIN_FTR_SECTION
+ li r4,0
+ mtspr SPRN_DBAT4U,r4
+ mtspr SPRN_DBAT4L,r4
+ mtspr SPRN_DBAT5U,r4
+ mtspr SPRN_DBAT5L,r4
+ mtspr SPRN_DBAT6U,r4
+ mtspr SPRN_DBAT6L,r4
+ mtspr SPRN_DBAT7U,r4
+ mtspr SPRN_DBAT7L,r4
+ mtspr SPRN_IBAT4U,r4
+ mtspr SPRN_IBAT4L,r4
+ mtspr SPRN_IBAT5U,r4
+ mtspr SPRN_IBAT5L,r4
+ mtspr SPRN_IBAT6U,r4
+ mtspr SPRN_IBAT6L,r4
+ mtspr SPRN_IBAT7U,r4
+ mtspr SPRN_IBAT7L,r4
+END_FTR_SECTION_IFSET(CPU_FTR_HAS_HIGH_BATS)
+
+ /* Flush all TLBs */
+ lis r4,0x1000
+1: addic. r4,r4,-0x1000
+ tlbie r4
+ blt 1b
+ sync
+
+ /* restore the MSR and turn on the MMU */
+ lwz r3,SL_MSR(r1)
+ bl turn_on_mmu
+
+ /* get back the stack pointer */
+ tovirt(r1,r1)
+
+ /* Restore TB */
+ li r3,0
+ mttbl r3
+ lwz r3,SL_TB(r1)
+ lwz r4,SL_TB+4(r1)
+ mttbu r3
+ mttbl r4
+
+ /* Restore the callee-saved registers and return */
+ lwz r0,SL_CR(r1)
+ mtcr r0
+ lwz r2,SL_R2(r1)
+ lmw r12,SL_R12(r1)
+ addi r1,r1,SL_SIZE
+ lwz r0,4(r1)
+ mtlr r0
+ blr
+
+turn_on_mmu:
+ mflr r4
+ tovirt(r4,r4)
+ mtsrr0 r4
+ mtsrr1 r3
+ sync
+ isync
+ rfi
+
+#endif /* defined(CONFIG_PM) || defined(CONFIG_CPU_FREQ) */
+
+ .section .data
+ .balign L1_CACHE_BYTES
+sleep_storage:
+ .long 0
+ .balign L1_CACHE_BYTES, 0
+
+#endif /* CONFIG_6xx */
+ .section .text
diff --git a/arch/powerpc/platforms/powermac/smp.c b/arch/powerpc/platforms/powermac/smp.c
new file mode 100644
index 000000000000..957b09103422
--- /dev/null
+++ b/arch/powerpc/platforms/powermac/smp.c
@@ -0,0 +1,876 @@
+/*
+ * SMP support for power macintosh.
+ *
+ * We support both the old "powersurge" SMP architecture
+ * and the current Core99 (G4 PowerMac) machines.
+ *
+ * Note that we don't support the very first rev. of
+ * Apple/DayStar 2 CPUs board, the one with the funky
+ * watchdog. Hopefully, none of these should be there except
+ * maybe internally to Apple. I should probably still add some
+ * code to detect this card though and disable SMP. --BenH.
+ *
+ * Support Macintosh G4 SMP by Troy Benjegerdes (hozer@drgw.net)
+ * and Ben Herrenschmidt <benh@kernel.crashing.org>.
+ *
+ * Support for DayStar quad CPU cards
+ * Copyright (C) XLR8, Inc. 1994-2000
+ *
+ * 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/config.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/interrupt.h>
+#include <linux/kernel_stat.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/spinlock.h>
+#include <linux/errno.h>
+#include <linux/hardirq.h>
+#include <linux/cpu.h>
+
+#include <asm/ptrace.h>
+#include <asm/atomic.h>
+#include <asm/irq.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/sections.h>
+#include <asm/io.h>
+#include <asm/prom.h>
+#include <asm/smp.h>
+#include <asm/machdep.h>
+#include <asm/pmac_feature.h>
+#include <asm/time.h>
+#include <asm/mpic.h>
+#include <asm/cacheflush.h>
+#include <asm/keylargo.h>
+#include <asm/pmac_low_i2c.h>
+
+#undef DEBUG
+
+#ifdef DEBUG
+#define DBG(fmt...) udbg_printf(fmt)
+#else
+#define DBG(fmt...)
+#endif
+
+extern void __secondary_start_pmac_0(void);
+
+#ifdef CONFIG_PPC32
+
+/* Sync flag for HW tb sync */
+static volatile int sec_tb_reset = 0;
+
+/*
+ * Powersurge (old powermac SMP) support.
+ */
+
+/* Addresses for powersurge registers */
+#define HAMMERHEAD_BASE 0xf8000000
+#define HHEAD_CONFIG 0x90
+#define HHEAD_SEC_INTR 0xc0
+
+/* register for interrupting the primary processor on the powersurge */
+/* N.B. this is actually the ethernet ROM! */
+#define PSURGE_PRI_INTR 0xf3019000
+
+/* register for storing the start address for the secondary processor */
+/* N.B. this is the PCI config space address register for the 1st bridge */
+#define PSURGE_START 0xf2800000
+
+/* Daystar/XLR8 4-CPU card */
+#define PSURGE_QUAD_REG_ADDR 0xf8800000
+
+#define PSURGE_QUAD_IRQ_SET 0
+#define PSURGE_QUAD_IRQ_CLR 1
+#define PSURGE_QUAD_IRQ_PRIMARY 2
+#define PSURGE_QUAD_CKSTOP_CTL 3
+#define PSURGE_QUAD_PRIMARY_ARB 4
+#define PSURGE_QUAD_BOARD_ID 6
+#define PSURGE_QUAD_WHICH_CPU 7
+#define PSURGE_QUAD_CKSTOP_RDBK 8
+#define PSURGE_QUAD_RESET_CTL 11
+
+#define PSURGE_QUAD_OUT(r, v) (out_8(quad_base + ((r) << 4) + 4, (v)))
+#define PSURGE_QUAD_IN(r) (in_8(quad_base + ((r) << 4) + 4) & 0x0f)
+#define PSURGE_QUAD_BIS(r, v) (PSURGE_QUAD_OUT((r), PSURGE_QUAD_IN(r) | (v)))
+#define PSURGE_QUAD_BIC(r, v) (PSURGE_QUAD_OUT((r), PSURGE_QUAD_IN(r) & ~(v)))
+
+/* virtual addresses for the above */
+static volatile u8 __iomem *hhead_base;
+static volatile u8 __iomem *quad_base;
+static volatile u32 __iomem *psurge_pri_intr;
+static volatile u8 __iomem *psurge_sec_intr;
+static volatile u32 __iomem *psurge_start;
+
+/* values for psurge_type */
+#define PSURGE_NONE -1
+#define PSURGE_DUAL 0
+#define PSURGE_QUAD_OKEE 1
+#define PSURGE_QUAD_COTTON 2
+#define PSURGE_QUAD_ICEGRASS 3
+
+/* what sort of powersurge board we have */
+static int psurge_type = PSURGE_NONE;
+
+/*
+ * Set and clear IPIs for powersurge.
+ */
+static inline void psurge_set_ipi(int cpu)
+{
+ if (psurge_type == PSURGE_NONE)
+ return;
+ if (cpu == 0)
+ in_be32(psurge_pri_intr);
+ else if (psurge_type == PSURGE_DUAL)
+ out_8(psurge_sec_intr, 0);
+ else
+ PSURGE_QUAD_OUT(PSURGE_QUAD_IRQ_SET, 1 << cpu);
+}
+
+static inline void psurge_clr_ipi(int cpu)
+{
+ if (cpu > 0) {
+ switch(psurge_type) {
+ case PSURGE_DUAL:
+ out_8(psurge_sec_intr, ~0);
+ case PSURGE_NONE:
+ break;
+ default:
+ PSURGE_QUAD_OUT(PSURGE_QUAD_IRQ_CLR, 1 << cpu);
+ }
+ }
+}
+
+/*
+ * On powersurge (old SMP powermac architecture) we don't have
+ * separate IPIs for separate messages like openpic does. Instead
+ * we have a bitmap for each processor, where a 1 bit means that
+ * the corresponding message is pending for that processor.
+ * Ideally each cpu's entry would be in a different cache line.
+ * -- paulus.
+ */
+static unsigned long psurge_smp_message[NR_CPUS];
+
+void psurge_smp_message_recv(struct pt_regs *regs)
+{
+ int cpu = smp_processor_id();
+ int msg;
+
+ /* clear interrupt */
+ psurge_clr_ipi(cpu);
+
+ if (num_online_cpus() < 2)
+ return;
+
+ /* make sure there is a message there */
+ for (msg = 0; msg < 4; msg++)
+ if (test_and_clear_bit(msg, &psurge_smp_message[cpu]))
+ smp_message_recv(msg, regs);
+}
+
+irqreturn_t psurge_primary_intr(int irq, void *d, struct pt_regs *regs)
+{
+ psurge_smp_message_recv(regs);
+ return IRQ_HANDLED;
+}
+
+static void smp_psurge_message_pass(int target, int msg)
+{
+ int i;
+
+ if (num_online_cpus() < 2)
+ return;
+
+ for (i = 0; i < NR_CPUS; i++) {
+ if (!cpu_online(i))
+ continue;
+ if (target == MSG_ALL
+ || (target == MSG_ALL_BUT_SELF && i != smp_processor_id())
+ || target == i) {
+ set_bit(msg, &psurge_smp_message[i]);
+ psurge_set_ipi(i);
+ }
+ }
+}
+
+/*
+ * Determine a quad card presence. We read the board ID register, we
+ * force the data bus to change to something else, and we read it again.
+ * It it's stable, then the register probably exist (ugh !)
+ */
+static int __init psurge_quad_probe(void)
+{
+ int type;
+ unsigned int i;
+
+ type = PSURGE_QUAD_IN(PSURGE_QUAD_BOARD_ID);
+ if (type < PSURGE_QUAD_OKEE || type > PSURGE_QUAD_ICEGRASS
+ || type != PSURGE_QUAD_IN(PSURGE_QUAD_BOARD_ID))
+ return PSURGE_DUAL;
+
+ /* looks OK, try a slightly more rigorous test */
+ /* bogus is not necessarily cacheline-aligned,
+ though I don't suppose that really matters. -- paulus */
+ for (i = 0; i < 100; i++) {
+ volatile u32 bogus[8];
+ bogus[(0+i)%8] = 0x00000000;
+ bogus[(1+i)%8] = 0x55555555;
+ bogus[(2+i)%8] = 0xFFFFFFFF;
+ bogus[(3+i)%8] = 0xAAAAAAAA;
+ bogus[(4+i)%8] = 0x33333333;
+ bogus[(5+i)%8] = 0xCCCCCCCC;
+ bogus[(6+i)%8] = 0xCCCCCCCC;
+ bogus[(7+i)%8] = 0x33333333;
+ wmb();
+ asm volatile("dcbf 0,%0" : : "r" (bogus) : "memory");
+ mb();
+ if (type != PSURGE_QUAD_IN(PSURGE_QUAD_BOARD_ID))
+ return PSURGE_DUAL;
+ }
+ return type;
+}
+
+static void __init psurge_quad_init(void)
+{
+ int procbits;
+
+ if (ppc_md.progress) ppc_md.progress("psurge_quad_init", 0x351);
+ procbits = ~PSURGE_QUAD_IN(PSURGE_QUAD_WHICH_CPU);
+ if (psurge_type == PSURGE_QUAD_ICEGRASS)
+ PSURGE_QUAD_BIS(PSURGE_QUAD_RESET_CTL, procbits);
+ else
+ PSURGE_QUAD_BIC(PSURGE_QUAD_CKSTOP_CTL, procbits);
+ mdelay(33);
+ out_8(psurge_sec_intr, ~0);
+ PSURGE_QUAD_OUT(PSURGE_QUAD_IRQ_CLR, procbits);
+ PSURGE_QUAD_BIS(PSURGE_QUAD_RESET_CTL, procbits);
+ if (psurge_type != PSURGE_QUAD_ICEGRASS)
+ PSURGE_QUAD_BIS(PSURGE_QUAD_CKSTOP_CTL, procbits);
+ PSURGE_QUAD_BIC(PSURGE_QUAD_PRIMARY_ARB, procbits);
+ mdelay(33);
+ PSURGE_QUAD_BIC(PSURGE_QUAD_RESET_CTL, procbits);
+ mdelay(33);
+ PSURGE_QUAD_BIS(PSURGE_QUAD_PRIMARY_ARB, procbits);
+ mdelay(33);
+}
+
+static int __init smp_psurge_probe(void)
+{
+ int i, ncpus;
+
+ /* We don't do SMP on the PPC601 -- paulus */
+ if (PVR_VER(mfspr(SPRN_PVR)) == 1)
+ return 1;
+
+ /*
+ * The powersurge cpu board can be used in the generation
+ * of powermacs that have a socket for an upgradeable cpu card,
+ * including the 7500, 8500, 9500, 9600.
+ * The device tree doesn't tell you if you have 2 cpus because
+ * OF doesn't know anything about the 2nd processor.
+ * Instead we look for magic bits in magic registers,
+ * in the hammerhead memory controller in the case of the
+ * dual-cpu powersurge board. -- paulus.
+ */
+ if (find_devices("hammerhead") == NULL)
+ return 1;
+
+ hhead_base = ioremap(HAMMERHEAD_BASE, 0x800);
+ quad_base = ioremap(PSURGE_QUAD_REG_ADDR, 1024);
+ psurge_sec_intr = hhead_base + HHEAD_SEC_INTR;
+
+ psurge_type = psurge_quad_probe();
+ if (psurge_type != PSURGE_DUAL) {
+ psurge_quad_init();
+ /* All released cards using this HW design have 4 CPUs */
+ ncpus = 4;
+ } else {
+ iounmap(quad_base);
+ if ((in_8(hhead_base + HHEAD_CONFIG) & 0x02) == 0) {
+ /* not a dual-cpu card */
+ iounmap(hhead_base);
+ psurge_type = PSURGE_NONE;
+ return 1;
+ }
+ ncpus = 2;
+ }
+
+ psurge_start = ioremap(PSURGE_START, 4);
+ psurge_pri_intr = ioremap(PSURGE_PRI_INTR, 4);
+
+ /*
+ * This is necessary because OF doesn't know about the
+ * secondary cpu(s), and thus there aren't nodes in the
+ * device tree for them, and smp_setup_cpu_maps hasn't
+ * set their bits in cpu_possible_map and cpu_present_map.
+ */
+ if (ncpus > NR_CPUS)
+ ncpus = NR_CPUS;
+ for (i = 1; i < ncpus ; ++i) {
+ cpu_set(i, cpu_present_map);
+ cpu_set(i, cpu_possible_map);
+ set_hard_smp_processor_id(i, i);
+ }
+
+ if (ppc_md.progress) ppc_md.progress("smp_psurge_probe - done", 0x352);
+
+ return ncpus;
+}
+
+static void __init smp_psurge_kick_cpu(int nr)
+{
+ unsigned long start = __pa(__secondary_start_pmac_0) + nr * 8;
+ unsigned long a;
+
+ /* may need to flush here if secondary bats aren't setup */
+ for (a = KERNELBASE; a < KERNELBASE + 0x800000; a += 32)
+ asm volatile("dcbf 0,%0" : : "r" (a) : "memory");
+ asm volatile("sync");
+
+ if (ppc_md.progress) ppc_md.progress("smp_psurge_kick_cpu", 0x353);
+
+ out_be32(psurge_start, start);
+ mb();
+
+ psurge_set_ipi(nr);
+ udelay(10);
+ psurge_clr_ipi(nr);
+
+ if (ppc_md.progress) ppc_md.progress("smp_psurge_kick_cpu - done", 0x354);
+}
+
+/*
+ * With the dual-cpu powersurge board, the decrementers and timebases
+ * of both cpus are frozen after the secondary cpu is started up,
+ * until we give the secondary cpu another interrupt. This routine
+ * uses this to get the timebases synchronized.
+ * -- paulus.
+ */
+static void __init psurge_dual_sync_tb(int cpu_nr)
+{
+ int t;
+
+ set_dec(tb_ticks_per_jiffy);
+ /* XXX fixme */
+ set_tb(0, 0);
+ last_jiffy_stamp(cpu_nr) = 0;
+
+ if (cpu_nr > 0) {
+ mb();
+ sec_tb_reset = 1;
+ return;
+ }
+
+ /* wait for the secondary to have reset its TB before proceeding */
+ for (t = 10000000; t > 0 && !sec_tb_reset; --t)
+ ;
+
+ /* now interrupt the secondary, starting both TBs */
+ psurge_set_ipi(1);
+}
+
+static struct irqaction psurge_irqaction = {
+ .handler = psurge_primary_intr,
+ .flags = SA_INTERRUPT,
+ .mask = CPU_MASK_NONE,
+ .name = "primary IPI",
+};
+
+static void __init smp_psurge_setup_cpu(int cpu_nr)
+{
+
+ if (cpu_nr == 0) {
+ /* If we failed to start the second CPU, we should still
+ * send it an IPI to start the timebase & DEC or we might
+ * have them stuck.
+ */
+ if (num_online_cpus() < 2) {
+ if (psurge_type == PSURGE_DUAL)
+ psurge_set_ipi(1);
+ return;
+ }
+ /* reset the entry point so if we get another intr we won't
+ * try to startup again */
+ out_be32(psurge_start, 0x100);
+ if (setup_irq(30, &psurge_irqaction))
+ printk(KERN_ERR "Couldn't get primary IPI interrupt");
+ }
+
+ if (psurge_type == PSURGE_DUAL)
+ psurge_dual_sync_tb(cpu_nr);
+}
+
+void __init smp_psurge_take_timebase(void)
+{
+ /* Dummy implementation */
+}
+
+void __init smp_psurge_give_timebase(void)
+{
+ /* Dummy implementation */
+}
+
+/* PowerSurge-style Macs */
+struct smp_ops_t psurge_smp_ops = {
+ .message_pass = smp_psurge_message_pass,
+ .probe = smp_psurge_probe,
+ .kick_cpu = smp_psurge_kick_cpu,
+ .setup_cpu = smp_psurge_setup_cpu,
+ .give_timebase = smp_psurge_give_timebase,
+ .take_timebase = smp_psurge_take_timebase,
+};
+#endif /* CONFIG_PPC32 - actually powersurge support */
+
+#ifdef CONFIG_PPC64
+/*
+ * G5s enable/disable the timebase via an i2c-connected clock chip.
+ */
+static struct device_node *pmac_tb_clock_chip_host;
+static u8 pmac_tb_pulsar_addr;
+static void (*pmac_tb_freeze)(int freeze);
+static DEFINE_SPINLOCK(timebase_lock);
+static unsigned long timebase;
+
+static void smp_core99_cypress_tb_freeze(int freeze)
+{
+ u8 data;
+ int rc;
+
+ /* Strangely, the device-tree says address is 0xd2, but darwin
+ * accesses 0xd0 ...
+ */
+ pmac_low_i2c_setmode(pmac_tb_clock_chip_host, pmac_low_i2c_mode_combined);
+ rc = pmac_low_i2c_xfer(pmac_tb_clock_chip_host,
+ 0xd0 | pmac_low_i2c_read,
+ 0x81, &data, 1);
+ if (rc != 0)
+ goto bail;
+
+ data = (data & 0xf3) | (freeze ? 0x00 : 0x0c);
+
+ pmac_low_i2c_setmode(pmac_tb_clock_chip_host, pmac_low_i2c_mode_stdsub);
+ rc = pmac_low_i2c_xfer(pmac_tb_clock_chip_host,
+ 0xd0 | pmac_low_i2c_write,
+ 0x81, &data, 1);
+
+ bail:
+ if (rc != 0) {
+ printk("Cypress Timebase %s rc: %d\n",
+ freeze ? "freeze" : "unfreeze", rc);
+ panic("Timebase freeze failed !\n");
+ }
+}
+
+
+static void smp_core99_pulsar_tb_freeze(int freeze)
+{
+ u8 data;
+ int rc;
+
+ pmac_low_i2c_setmode(pmac_tb_clock_chip_host, pmac_low_i2c_mode_combined);
+ rc = pmac_low_i2c_xfer(pmac_tb_clock_chip_host,
+ pmac_tb_pulsar_addr | pmac_low_i2c_read,
+ 0x2e, &data, 1);
+ if (rc != 0)
+ goto bail;
+
+ data = (data & 0x88) | (freeze ? 0x11 : 0x22);
+
+ pmac_low_i2c_setmode(pmac_tb_clock_chip_host, pmac_low_i2c_mode_stdsub);
+ rc = pmac_low_i2c_xfer(pmac_tb_clock_chip_host,
+ pmac_tb_pulsar_addr | pmac_low_i2c_write,
+ 0x2e, &data, 1);
+ bail:
+ if (rc != 0) {
+ printk(KERN_ERR "Pulsar Timebase %s rc: %d\n",
+ freeze ? "freeze" : "unfreeze", rc);
+ panic("Timebase freeze failed !\n");
+ }
+}
+
+
+static void smp_core99_give_timebase(void)
+{
+ /* Open i2c bus for synchronous access */
+ if (pmac_low_i2c_open(pmac_tb_clock_chip_host, 0))
+ panic("Can't open i2c for TB sync !\n");
+
+ spin_lock(&timebase_lock);
+ (*pmac_tb_freeze)(1);
+ mb();
+ timebase = get_tb();
+ spin_unlock(&timebase_lock);
+
+ while (timebase)
+ barrier();
+
+ spin_lock(&timebase_lock);
+ (*pmac_tb_freeze)(0);
+ spin_unlock(&timebase_lock);
+
+ /* Close i2c bus */
+ pmac_low_i2c_close(pmac_tb_clock_chip_host);
+}
+
+
+static void __devinit smp_core99_take_timebase(void)
+{
+ while (!timebase)
+ barrier();
+ spin_lock(&timebase_lock);
+ set_tb(timebase >> 32, timebase & 0xffffffff);
+ timebase = 0;
+ spin_unlock(&timebase_lock);
+}
+
+static void __init smp_core99_setup(int ncpus)
+{
+ struct device_node *cc = NULL;
+ struct device_node *p;
+ u32 *reg;
+ int ok;
+
+ /* HW sync only on these platforms */
+ if (!machine_is_compatible("PowerMac7,2") &&
+ !machine_is_compatible("PowerMac7,3") &&
+ !machine_is_compatible("RackMac3,1"))
+ return;
+
+ /* Look for the clock chip */
+ while ((cc = of_find_node_by_name(cc, "i2c-hwclock")) != NULL) {
+ p = of_get_parent(cc);
+ ok = p && device_is_compatible(p, "uni-n-i2c");
+ of_node_put(p);
+ if (!ok)
+ continue;
+
+ reg = (u32 *)get_property(cc, "reg", NULL);
+ if (reg == NULL)
+ continue;
+
+ switch (*reg) {
+ case 0xd2:
+ if (device_is_compatible(cc, "pulsar-legacy-slewing")) {
+ pmac_tb_freeze = smp_core99_pulsar_tb_freeze;
+ pmac_tb_pulsar_addr = 0xd2;
+ printk(KERN_INFO "Timebase clock is Pulsar chip\n");
+ } else if (device_is_compatible(cc, "cy28508")) {
+ pmac_tb_freeze = smp_core99_cypress_tb_freeze;
+ printk(KERN_INFO "Timebase clock is Cypress chip\n");
+ }
+ break;
+ case 0xd4:
+ pmac_tb_freeze = smp_core99_pulsar_tb_freeze;
+ pmac_tb_pulsar_addr = 0xd4;
+ printk(KERN_INFO "Timebase clock is Pulsar chip\n");
+ break;
+ }
+ if (pmac_tb_freeze != NULL) {
+ pmac_tb_clock_chip_host = of_get_parent(cc);
+ of_node_put(cc);
+ break;
+ }
+ }
+ if (pmac_tb_freeze == NULL) {
+ smp_ops->give_timebase = smp_generic_give_timebase;
+ smp_ops->take_timebase = smp_generic_take_timebase;
+ }
+}
+
+/* nothing to do here, caches are already set up by service processor */
+static inline void __devinit core99_init_caches(int cpu)
+{
+}
+
+#else /* CONFIG_PPC64 */
+
+/*
+ * SMP G4 powermacs use a GPIO to enable/disable the timebase.
+ */
+
+static unsigned int core99_tb_gpio; /* Timebase freeze GPIO */
+
+static unsigned int pri_tb_hi, pri_tb_lo;
+static unsigned int pri_tb_stamp;
+
+/* not __init, called in sleep/wakeup code */
+void smp_core99_give_timebase(void)
+{
+ unsigned long flags;
+ unsigned int t;
+
+ /* wait for the secondary to be in take_timebase */
+ for (t = 100000; t > 0 && !sec_tb_reset; --t)
+ udelay(10);
+ if (!sec_tb_reset) {
+ printk(KERN_WARNING "Timeout waiting sync on second CPU\n");
+ return;
+ }
+
+ /* freeze the timebase and read it */
+ /* disable interrupts so the timebase is disabled for the
+ shortest possible time */
+ local_irq_save(flags);
+ pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, core99_tb_gpio, 4);
+ pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, core99_tb_gpio, 0);
+ mb();
+ pri_tb_hi = get_tbu();
+ pri_tb_lo = get_tbl();
+ pri_tb_stamp = last_jiffy_stamp(smp_processor_id());
+ mb();
+
+ /* tell the secondary we're ready */
+ sec_tb_reset = 2;
+ mb();
+
+ /* wait for the secondary to have taken it */
+ for (t = 100000; t > 0 && sec_tb_reset; --t)
+ udelay(10);
+ if (sec_tb_reset)
+ /* XXX BUG_ON here? */
+ printk(KERN_WARNING "Timeout waiting sync(2) on second CPU\n");
+
+ /* Now, restart the timebase by leaving the GPIO to an open collector */
+ pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, core99_tb_gpio, 0);
+ pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, core99_tb_gpio, 0);
+ local_irq_restore(flags);
+}
+
+/* not __init, called in sleep/wakeup code */
+void smp_core99_take_timebase(void)
+{
+ unsigned long flags;
+
+ /* tell the primary we're here */
+ sec_tb_reset = 1;
+ mb();
+
+ /* wait for the primary to set pri_tb_hi/lo */
+ while (sec_tb_reset < 2)
+ mb();
+
+ /* set our stuff the same as the primary */
+ local_irq_save(flags);
+ set_dec(1);
+ set_tb(pri_tb_hi, pri_tb_lo);
+ last_jiffy_stamp(smp_processor_id()) = pri_tb_stamp;
+ mb();
+
+ /* tell the primary we're done */
+ sec_tb_reset = 0;
+ mb();
+ local_irq_restore(flags);
+}
+
+/* L2 and L3 cache settings to pass from CPU0 to CPU1 on G4 cpus */
+volatile static long int core99_l2_cache;
+volatile static long int core99_l3_cache;
+
+static void __devinit core99_init_caches(int cpu)
+{
+ if (!cpu_has_feature(CPU_FTR_L2CR))
+ return;
+
+ if (cpu == 0) {
+ core99_l2_cache = _get_L2CR();
+ printk("CPU0: L2CR is %lx\n", core99_l2_cache);
+ } else {
+ printk("CPU%d: L2CR was %lx\n", cpu, _get_L2CR());
+ _set_L2CR(0);
+ _set_L2CR(core99_l2_cache);
+ printk("CPU%d: L2CR set to %lx\n", cpu, core99_l2_cache);
+ }
+
+ if (!cpu_has_feature(CPU_FTR_L3CR))
+ return;
+
+ if (cpu == 0){
+ core99_l3_cache = _get_L3CR();
+ printk("CPU0: L3CR is %lx\n", core99_l3_cache);
+ } else {
+ printk("CPU%d: L3CR was %lx\n", cpu, _get_L3CR());
+ _set_L3CR(0);
+ _set_L3CR(core99_l3_cache);
+ printk("CPU%d: L3CR set to %lx\n", cpu, core99_l3_cache);
+ }
+}
+
+static void __init smp_core99_setup(int ncpus)
+{
+ struct device_node *cpu;
+ u32 *tbprop = NULL;
+ int i;
+
+ core99_tb_gpio = KL_GPIO_TB_ENABLE; /* default value */
+ cpu = of_find_node_by_type(NULL, "cpu");
+ if (cpu != NULL) {
+ tbprop = (u32 *)get_property(cpu, "timebase-enable", NULL);
+ if (tbprop)
+ core99_tb_gpio = *tbprop;
+ of_node_put(cpu);
+ }
+
+ /* XXX should get this from reg properties */
+ for (i = 1; i < ncpus; ++i)
+ smp_hw_index[i] = i;
+ powersave_nap = 0;
+}
+#endif
+
+static int __init smp_core99_probe(void)
+{
+ struct device_node *cpus;
+ int ncpus = 0;
+
+ if (ppc_md.progress) ppc_md.progress("smp_core99_probe", 0x345);
+
+ /* Count CPUs in the device-tree */
+ for (cpus = NULL; (cpus = of_find_node_by_type(cpus, "cpu")) != NULL;)
+ ++ncpus;
+
+ printk(KERN_INFO "PowerMac SMP probe found %d cpus\n", ncpus);
+
+ /* Nothing more to do if less than 2 of them */
+ if (ncpus <= 1)
+ return 1;
+
+ smp_core99_setup(ncpus);
+ mpic_request_ipis();
+ core99_init_caches(0);
+
+ return ncpus;
+}
+
+static void __devinit smp_core99_kick_cpu(int nr)
+{
+ unsigned int save_vector;
+ unsigned long new_vector;
+ unsigned long flags;
+ volatile unsigned int *vector
+ = ((volatile unsigned int *)(KERNELBASE+0x100));
+
+ if (nr < 0 || nr > 3)
+ return;
+ if (ppc_md.progress) ppc_md.progress("smp_core99_kick_cpu", 0x346);
+
+ local_irq_save(flags);
+ local_irq_disable();
+
+ /* Save reset vector */
+ save_vector = *vector;
+
+ /* Setup fake reset vector that does
+ * b __secondary_start_pmac_0 + nr*8 - KERNELBASE
+ */
+ new_vector = (unsigned long) __secondary_start_pmac_0 + nr * 8;
+ *vector = 0x48000002 + new_vector - KERNELBASE;
+
+ /* flush data cache and inval instruction cache */
+ flush_icache_range((unsigned long) vector, (unsigned long) vector + 4);
+
+ /* Put some life in our friend */
+ pmac_call_feature(PMAC_FTR_RESET_CPU, NULL, nr, 0);
+
+ /* FIXME: We wait a bit for the CPU to take the exception, I should
+ * instead wait for the entry code to set something for me. Well,
+ * ideally, all that crap will be done in prom.c and the CPU left
+ * in a RAM-based wait loop like CHRP.
+ */
+ mdelay(1);
+
+ /* Restore our exception vector */
+ *vector = save_vector;
+ flush_icache_range((unsigned long) vector, (unsigned long) vector + 4);
+
+ local_irq_restore(flags);
+ if (ppc_md.progress) ppc_md.progress("smp_core99_kick_cpu done", 0x347);
+}
+
+static void __devinit smp_core99_setup_cpu(int cpu_nr)
+{
+ /* Setup L2/L3 */
+ if (cpu_nr != 0)
+ core99_init_caches(cpu_nr);
+
+ /* Setup openpic */
+ mpic_setup_this_cpu();
+
+ if (cpu_nr == 0) {
+#ifdef CONFIG_POWER4
+ extern void g5_phy_disable_cpu1(void);
+
+ /* If we didn't start the second CPU, we must take
+ * it off the bus
+ */
+ if (machine_is_compatible("MacRISC4") &&
+ num_online_cpus() < 2)
+ g5_phy_disable_cpu1();
+#endif /* CONFIG_POWER4 */
+ if (ppc_md.progress) ppc_md.progress("core99_setup_cpu 0 done", 0x349);
+ }
+}
+
+
+#if defined(CONFIG_HOTPLUG_CPU) && defined(CONFIG_PPC32)
+
+int smp_core99_cpu_disable(void)
+{
+ cpu_clear(smp_processor_id(), cpu_online_map);
+
+ /* XXX reset cpu affinity here */
+ mpic_cpu_set_priority(0xf);
+ asm volatile("mtdec %0" : : "r" (0x7fffffff));
+ mb();
+ udelay(20);
+ asm volatile("mtdec %0" : : "r" (0x7fffffff));
+ return 0;
+}
+
+extern void low_cpu_die(void) __attribute__((noreturn)); /* in sleep.S */
+static int cpu_dead[NR_CPUS];
+
+void cpu_die(void)
+{
+ local_irq_disable();
+ cpu_dead[smp_processor_id()] = 1;
+ mb();
+ low_cpu_die();
+}
+
+void smp_core99_cpu_die(unsigned int cpu)
+{
+ int timeout;
+
+ timeout = 1000;
+ while (!cpu_dead[cpu]) {
+ if (--timeout == 0) {
+ printk("CPU %u refused to die!\n", cpu);
+ break;
+ }
+ msleep(1);
+ }
+ cpu_dead[cpu] = 0;
+}
+
+#endif
+
+/* Core99 Macs (dual G4s and G5s) */
+struct smp_ops_t core99_smp_ops = {
+ .message_pass = smp_mpic_message_pass,
+ .probe = smp_core99_probe,
+ .kick_cpu = smp_core99_kick_cpu,
+ .setup_cpu = smp_core99_setup_cpu,
+ .give_timebase = smp_core99_give_timebase,
+ .take_timebase = smp_core99_take_timebase,
+#if defined(CONFIG_HOTPLUG_CPU) && defined(CONFIG_PPC32)
+ .cpu_disable = smp_core99_cpu_disable,
+ .cpu_die = smp_core99_cpu_die,
+#endif
+};
diff --git a/arch/powerpc/platforms/powermac/time.c b/arch/powerpc/platforms/powermac/time.c
new file mode 100644
index 000000000000..5947b21a8588
--- /dev/null
+++ b/arch/powerpc/platforms/powermac/time.c
@@ -0,0 +1,360 @@
+/*
+ * Support for periodic interrupts (100 per second) and for getting
+ * the current time from the RTC on Power Macintoshes.
+ *
+ * We use the decrementer register for our periodic interrupts.
+ *
+ * Paul Mackerras August 1996.
+ * Copyright (C) 1996 Paul Mackerras.
+ * Copyright (C) 2003-2005 Benjamin Herrenschmidt.
+ *
+ */
+#include <linux/config.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/param.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <linux/time.h>
+#include <linux/adb.h>
+#include <linux/cuda.h>
+#include <linux/pmu.h>
+#include <linux/interrupt.h>
+#include <linux/hardirq.h>
+#include <linux/rtc.h>
+
+#include <asm/sections.h>
+#include <asm/prom.h>
+#include <asm/system.h>
+#include <asm/io.h>
+#include <asm/pgtable.h>
+#include <asm/machdep.h>
+#include <asm/time.h>
+#include <asm/nvram.h>
+#include <asm/smu.h>
+
+#undef DEBUG
+
+#ifdef DEBUG
+#define DBG(x...) printk(x)
+#else
+#define DBG(x...)
+#endif
+
+/* Apparently the RTC stores seconds since 1 Jan 1904 */
+#define RTC_OFFSET 2082844800
+
+/*
+ * Calibrate the decrementer frequency with the VIA timer 1.
+ */
+#define VIA_TIMER_FREQ_6 4700000 /* time 1 frequency * 6 */
+
+/* VIA registers */
+#define RS 0x200 /* skip between registers */
+#define T1CL (4*RS) /* Timer 1 ctr/latch (low 8 bits) */
+#define T1CH (5*RS) /* Timer 1 counter (high 8 bits) */
+#define T1LL (6*RS) /* Timer 1 latch (low 8 bits) */
+#define T1LH (7*RS) /* Timer 1 latch (high 8 bits) */
+#define ACR (11*RS) /* Auxiliary control register */
+#define IFR (13*RS) /* Interrupt flag register */
+
+/* Bits in ACR */
+#define T1MODE 0xc0 /* Timer 1 mode */
+#define T1MODE_CONT 0x40 /* continuous interrupts */
+
+/* Bits in IFR and IER */
+#define T1_INT 0x40 /* Timer 1 interrupt */
+
+long __init pmac_time_init(void)
+{
+ s32 delta = 0;
+#ifdef CONFIG_NVRAM
+ int dst;
+
+ delta = ((s32)pmac_xpram_read(PMAC_XPRAM_MACHINE_LOC + 0x9)) << 16;
+ delta |= ((s32)pmac_xpram_read(PMAC_XPRAM_MACHINE_LOC + 0xa)) << 8;
+ delta |= pmac_xpram_read(PMAC_XPRAM_MACHINE_LOC + 0xb);
+ if (delta & 0x00800000UL)
+ delta |= 0xFF000000UL;
+ dst = ((pmac_xpram_read(PMAC_XPRAM_MACHINE_LOC + 0x8) & 0x80) != 0);
+ printk("GMT Delta read from XPRAM: %d minutes, DST: %s\n", delta/60,
+ dst ? "on" : "off");
+#endif
+ return delta;
+}
+
+static void to_rtc_time(unsigned long now, struct rtc_time *tm)
+{
+ to_tm(now, tm);
+ tm->tm_year -= 1900;
+ tm->tm_mon -= 1;
+}
+
+static unsigned long from_rtc_time(struct rtc_time *tm)
+{
+ return mktime(tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday,
+ tm->tm_hour, tm->tm_min, tm->tm_sec);
+}
+
+#ifdef CONFIG_ADB_CUDA
+static unsigned long cuda_get_time(void)
+{
+ struct adb_request req;
+ unsigned long now;
+
+ if (cuda_request(&req, NULL, 2, CUDA_PACKET, CUDA_GET_TIME) < 0)
+ return 0;
+ while (!req.complete)
+ cuda_poll();
+ if (req.reply_len != 7)
+ printk(KERN_ERR "cuda_get_time: got %d byte reply\n",
+ req.reply_len);
+ now = (req.reply[3] << 24) + (req.reply[4] << 16)
+ + (req.reply[5] << 8) + req.reply[6];
+ return now - RTC_OFFSET;
+}
+
+#define cuda_get_rtc_time(tm) to_rtc_time(cuda_get_time(), (tm))
+
+static int cuda_set_rtc_time(struct rtc_time *tm)
+{
+ unsigned int nowtime;
+ struct adb_request req;
+
+ nowtime = from_rtc_time(tm) + RTC_OFFSET;
+ if (cuda_request(&req, NULL, 6, CUDA_PACKET, CUDA_SET_TIME,
+ nowtime >> 24, nowtime >> 16, nowtime >> 8,
+ nowtime) < 0)
+ return -ENXIO;
+ while (!req.complete)
+ cuda_poll();
+ if ((req.reply_len != 3) && (req.reply_len != 7))
+ printk(KERN_ERR "cuda_set_rtc_time: got %d byte reply\n",
+ req.reply_len);
+ return 0;
+}
+
+#else
+#define cuda_get_time() 0
+#define cuda_get_rtc_time(tm)
+#define cuda_set_rtc_time(tm) 0
+#endif
+
+#ifdef CONFIG_ADB_PMU
+static unsigned long pmu_get_time(void)
+{
+ struct adb_request req;
+ unsigned long now;
+
+ if (pmu_request(&req, NULL, 1, PMU_READ_RTC) < 0)
+ return 0;
+ pmu_wait_complete(&req);
+ if (req.reply_len != 4)
+ printk(KERN_ERR "pmu_get_time: got %d byte reply from PMU\n",
+ req.reply_len);
+ now = (req.reply[0] << 24) + (req.reply[1] << 16)
+ + (req.reply[2] << 8) + req.reply[3];
+ return now - RTC_OFFSET;
+}
+
+#define pmu_get_rtc_time(tm) to_rtc_time(pmu_get_time(), (tm))
+
+static int pmu_set_rtc_time(struct rtc_time *tm)
+{
+ unsigned int nowtime;
+ struct adb_request req;
+
+ nowtime = from_rtc_time(tm) + RTC_OFFSET;
+ if (pmu_request(&req, NULL, 5, PMU_SET_RTC, nowtime >> 24,
+ nowtime >> 16, nowtime >> 8, nowtime) < 0)
+ return -ENXIO;
+ pmu_wait_complete(&req);
+ if (req.reply_len != 0)
+ printk(KERN_ERR "pmu_set_rtc_time: %d byte reply from PMU\n",
+ req.reply_len);
+ return 0;
+}
+
+#else
+#define pmu_get_time() 0
+#define pmu_get_rtc_time(tm)
+#define pmu_set_rtc_time(tm) 0
+#endif
+
+#ifdef CONFIG_PMAC_SMU
+static unsigned long smu_get_time(void)
+{
+ struct rtc_time tm;
+
+ if (smu_get_rtc_time(&tm, 1))
+ return 0;
+ return from_rtc_time(&tm);
+}
+
+#else
+#define smu_get_time() 0
+#define smu_get_rtc_time(tm, spin)
+#define smu_set_rtc_time(tm, spin) 0
+#endif
+
+unsigned long pmac_get_boot_time(void)
+{
+ /* Get the time from the RTC, used only at boot time */
+ switch (sys_ctrler) {
+ case SYS_CTRLER_CUDA:
+ return cuda_get_time();
+ case SYS_CTRLER_PMU:
+ return pmu_get_time();
+ case SYS_CTRLER_SMU:
+ return smu_get_time();
+ default:
+ return 0;
+ }
+}
+
+void pmac_get_rtc_time(struct rtc_time *tm)
+{
+ /* Get the time from the RTC, used only at boot time */
+ switch (sys_ctrler) {
+ case SYS_CTRLER_CUDA:
+ cuda_get_rtc_time(tm);
+ break;
+ case SYS_CTRLER_PMU:
+ pmu_get_rtc_time(tm);
+ break;
+ case SYS_CTRLER_SMU:
+ smu_get_rtc_time(tm, 1);
+ break;
+ default:
+ ;
+ }
+}
+
+int pmac_set_rtc_time(struct rtc_time *tm)
+{
+ switch (sys_ctrler) {
+ case SYS_CTRLER_CUDA:
+ return cuda_set_rtc_time(tm);
+ case SYS_CTRLER_PMU:
+ return pmu_set_rtc_time(tm);
+ case SYS_CTRLER_SMU:
+ return smu_set_rtc_time(tm, 1);
+ default:
+ return -ENODEV;
+ }
+}
+
+#ifdef CONFIG_PPC32
+/*
+ * Calibrate the decrementer register using VIA timer 1.
+ * This is used both on powermacs and CHRP machines.
+ */
+int __init via_calibrate_decr(void)
+{
+ struct device_node *vias;
+ volatile unsigned char __iomem *via;
+ int count = VIA_TIMER_FREQ_6 / 100;
+ unsigned int dstart, dend;
+
+ vias = find_devices("via-cuda");
+ if (vias == 0)
+ vias = find_devices("via-pmu");
+ if (vias == 0)
+ vias = find_devices("via");
+ if (vias == 0 || vias->n_addrs == 0)
+ return 0;
+ via = ioremap(vias->addrs[0].address, vias->addrs[0].size);
+
+ /* set timer 1 for continuous interrupts */
+ out_8(&via[ACR], (via[ACR] & ~T1MODE) | T1MODE_CONT);
+ /* set the counter to a small value */
+ out_8(&via[T1CH], 2);
+ /* set the latch to `count' */
+ out_8(&via[T1LL], count);
+ out_8(&via[T1LH], count >> 8);
+ /* wait until it hits 0 */
+ while ((in_8(&via[IFR]) & T1_INT) == 0)
+ ;
+ dstart = get_dec();
+ /* clear the interrupt & wait until it hits 0 again */
+ in_8(&via[T1CL]);
+ while ((in_8(&via[IFR]) & T1_INT) == 0)
+ ;
+ dend = get_dec();
+
+ ppc_tb_freq = (dstart - dend) * 100 / 6;
+
+ iounmap(via);
+
+ return 1;
+}
+#endif
+
+#ifdef CONFIG_PM
+/*
+ * Reset the time after a sleep.
+ */
+static int
+time_sleep_notify(struct pmu_sleep_notifier *self, int when)
+{
+ static unsigned long time_diff;
+ unsigned long flags;
+ unsigned long seq;
+ struct timespec tv;
+
+ switch (when) {
+ case PBOOK_SLEEP_NOW:
+ do {
+ seq = read_seqbegin_irqsave(&xtime_lock, flags);
+ time_diff = xtime.tv_sec - pmac_get_boot_time();
+ } while (read_seqretry_irqrestore(&xtime_lock, seq, flags));
+ break;
+ case PBOOK_WAKE:
+ tv.tv_sec = pmac_get_boot_time() + time_diff;
+ tv.tv_nsec = 0;
+ do_settimeofday(&tv);
+ break;
+ }
+ return PBOOK_SLEEP_OK;
+}
+
+static struct pmu_sleep_notifier time_sleep_notifier = {
+ time_sleep_notify, SLEEP_LEVEL_MISC,
+};
+#endif /* CONFIG_PM */
+
+/*
+ * Query the OF and get the decr frequency.
+ */
+void __init pmac_calibrate_decr(void)
+{
+#ifdef CONFIG_PM
+ /* XXX why here? */
+ pmu_register_sleep_notifier(&time_sleep_notifier);
+#endif /* CONFIG_PM */
+
+ generic_calibrate_decr();
+
+#ifdef CONFIG_PPC32
+ /* We assume MacRISC2 machines have correct device-tree
+ * calibration. That's better since the VIA itself seems
+ * to be slightly off. --BenH
+ */
+ if (!machine_is_compatible("MacRISC2") &&
+ !machine_is_compatible("MacRISC3") &&
+ !machine_is_compatible("MacRISC4"))
+ if (via_calibrate_decr())
+ return;
+
+ /* Special case: QuickSilver G4s seem to have a badly calibrated
+ * timebase-frequency in OF, VIA is much better on these. We should
+ * probably implement calibration based on the KL timer on these
+ * machines anyway... -BenH
+ */
+ if (machine_is_compatible("PowerMac3,5"))
+ if (via_calibrate_decr())
+ return;
+#endif
+}
diff --git a/arch/powerpc/platforms/prep/Kconfig b/arch/powerpc/platforms/prep/Kconfig
new file mode 100644
index 000000000000..673ac47a1626
--- /dev/null
+++ b/arch/powerpc/platforms/prep/Kconfig
@@ -0,0 +1,22 @@
+
+config PREP_RESIDUAL
+ bool "Support for PReP Residual Data"
+ depends on PPC_PREP
+ help
+ Some PReP systems have residual data passed to the kernel by the
+ firmware. This allows detection of memory size, devices present and
+ other useful pieces of information. Sometimes this information is
+ not present or incorrect, in which case it could lead to the machine
+ behaving incorrectly. If this happens, either disable PREP_RESIDUAL
+ or pass the 'noresidual' option to the kernel.
+
+ If you are running a PReP system, say Y here, otherwise say N.
+
+config PROC_PREPRESIDUAL
+ bool "Support for reading of PReP Residual Data in /proc"
+ depends on PREP_RESIDUAL && PROC_FS
+ help
+ Enabling this option will create a /proc/residual file which allows
+ you to get at the residual data on PReP systems. You will need a tool
+ (lsresidual) to parse it. If you aren't on a PReP system, you don't
+ want this.
diff --git a/arch/powerpc/platforms/pseries/Kconfig b/arch/powerpc/platforms/pseries/Kconfig
new file mode 100644
index 000000000000..e3fc3407bb1f
--- /dev/null
+++ b/arch/powerpc/platforms/pseries/Kconfig
@@ -0,0 +1,33 @@
+
+config PPC_SPLPAR
+ depends on PPC_PSERIES
+ bool "Support for shared-processor logical partitions"
+ default n
+ help
+ Enabling this option will make the kernel run more efficiently
+ on logically-partitioned pSeries systems which use shared
+ processors, that is, which share physical processors between
+ two or more partitions.
+
+config HMT
+ bool "Hardware multithreading"
+ depends on SMP && PPC_PSERIES && BROKEN
+ help
+ This option enables hardware multithreading on RS64 cpus.
+ pSeries systems p620 and p660 have such a cpu type.
+
+config EEH
+ bool "PCI Extended Error Handling (EEH)" if EMBEDDED
+ depends on PPC_PSERIES
+ default y if !EMBEDDED
+
+config SCANLOG
+ tristate "Scanlog dump interface"
+ depends on RTAS_PROC && PPC_PSERIES
+
+config LPARCFG
+ tristate "LPAR Configuration Data"
+ depends on PPC_PSERIES || PPC_ISERIES
+ help
+ Provide system capacity information via human readable
+ <key word>=<value> pairs through a /proc/ppc64/lparcfg interface.
diff --git a/arch/powerpc/platforms/pseries/Makefile b/arch/powerpc/platforms/pseries/Makefile
new file mode 100644
index 000000000000..e7ca5b1f591e
--- /dev/null
+++ b/arch/powerpc/platforms/pseries/Makefile
@@ -0,0 +1,7 @@
+obj-y := pci.o lpar.o hvCall.o nvram.o reconfig.o \
+ setup.o iommu.o ras.o rtasd.o
+obj-$(CONFIG_SMP) += smp.o
+obj-$(CONFIG_IBMVIO) += vio.o
+obj-$(CONFIG_XICS) += xics.o
+obj-$(CONFIG_SCANLOG) += scanlog.o
+obj-$(CONFIG_EEH) += eeh.o eeh_event.o
diff --git a/arch/ppc64/kernel/eeh.c b/arch/powerpc/platforms/pseries/eeh.c
index ba93fd731222..79de2310e70b 100644
--- a/arch/ppc64/kernel/eeh.c
+++ b/arch/powerpc/platforms/pseries/eeh.c
@@ -1,39 +1,37 @@
/*
* eeh.c
* Copyright (C) 2001 Dave Engebretsen & Todd Inglett IBM 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
*/
-#include <linux/bootmem.h>
+#include <linux/delay.h>
#include <linux/init.h>
#include <linux/list.h>
-#include <linux/mm.h>
-#include <linux/notifier.h>
#include <linux/pci.h>
#include <linux/proc_fs.h>
#include <linux/rbtree.h>
#include <linux/seq_file.h>
#include <linux/spinlock.h>
+#include <asm/atomic.h>
#include <asm/eeh.h>
+#include <asm/eeh_event.h>
#include <asm/io.h>
#include <asm/machdep.h>
+#include <asm/ppc-pci.h>
#include <asm/rtas.h>
-#include <asm/atomic.h>
-#include <asm/systemcfg.h>
-#include "pci.h"
#undef DEBUG
@@ -49,8 +47,8 @@
* were "empty": all reads return 0xff's and all writes are silently
* ignored. EEH slot isolation events can be triggered by parity
* errors on the address or data busses (e.g. during posted writes),
- * which in turn might be caused by dust, vibration, humidity,
- * radioactivity or plain-old failed hardware.
+ * which in turn might be caused by low voltage on the bus, dust,
+ * vibration, humidity, radioactivity or plain-old failed hardware.
*
* Note, however, that one of the leading causes of EEH slot
* freeze events are buggy device drivers, buggy device microcode,
@@ -71,26 +69,15 @@
* and sent out for processing.
*/
-/** Bus Unit ID macros; get low and hi 32-bits of the 64-bit BUID */
-#define BUID_HI(buid) ((buid) >> 32)
-#define BUID_LO(buid) ((buid) & 0xffffffff)
-
-/* EEH event workqueue setup. */
-static DEFINE_SPINLOCK(eeh_eventlist_lock);
-LIST_HEAD(eeh_eventlist);
-static void eeh_event_handler(void *);
-DECLARE_WORK(eeh_event_wq, eeh_event_handler, NULL);
-
-static struct notifier_block *eeh_notifier_chain;
-
-/*
- * If a device driver keeps reading an MMIO register in an interrupt
+/* If a device driver keeps reading an MMIO register in an interrupt
* handler after a slot isolation event has occurred, we assume it
* is broken and panic. This sets the threshold for how many read
* attempts we allow before panicking.
*/
-#define EEH_MAX_FAILS 1000
-static atomic_t eeh_fail_count;
+#define EEH_MAX_FAILS 100000
+
+/* Misc forward declaraions */
+static void eeh_save_bars(struct pci_dev * pdev, struct pci_dn *pdn);
/* RTAS tokens */
static int ibm_set_eeh_option;
@@ -101,12 +88,19 @@ static int ibm_slot_error_detail;
static int eeh_subsystem_enabled;
+/* Lock to avoid races due to multiple reports of an error */
+static DEFINE_SPINLOCK(confirm_error_lock);
+
/* Buffer for reporting slot-error-detail rtas calls */
static unsigned char slot_errbuf[RTAS_ERROR_LOG_MAX];
static DEFINE_SPINLOCK(slot_errbuf_lock);
static int eeh_error_buf_size;
/* System monitoring statistics */
+static DEFINE_PER_CPU(unsigned long, no_device);
+static DEFINE_PER_CPU(unsigned long, no_dn);
+static DEFINE_PER_CPU(unsigned long, no_cfg_addr);
+static DEFINE_PER_CPU(unsigned long, ignored_check);
static DEFINE_PER_CPU(unsigned long, total_mmio_ffs);
static DEFINE_PER_CPU(unsigned long, false_positives);
static DEFINE_PER_CPU(unsigned long, ignored_failures);
@@ -224,9 +218,9 @@ pci_addr_cache_insert(struct pci_dev *dev, unsigned long alo,
while (*p) {
parent = *p;
piar = rb_entry(parent, struct pci_io_addr_range, rb_node);
- if (alo < piar->addr_lo) {
+ if (ahi < piar->addr_lo) {
p = &parent->rb_left;
- } else if (ahi > piar->addr_hi) {
+ } else if (alo > piar->addr_hi) {
p = &parent->rb_right;
} else {
if (dev != piar->pcidev ||
@@ -245,6 +239,11 @@ pci_addr_cache_insert(struct pci_dev *dev, unsigned long alo,
piar->pcidev = dev;
piar->flags = flags;
+#ifdef DEBUG
+ printk(KERN_DEBUG "PIAR: insert range=[%lx:%lx] dev=%s\n",
+ alo, ahi, pci_name (dev));
+#endif
+
rb_link_node(&piar->rb_node, parent, p);
rb_insert_color(&piar->rb_node, &pci_io_addr_cache_root.rb_root);
@@ -260,18 +259,17 @@ static void __pci_addr_cache_insert_device(struct pci_dev *dev)
dn = pci_device_to_OF_node(dev);
if (!dn) {
- printk(KERN_WARNING "PCI: no pci dn found for dev=%s\n",
- pci_name(dev));
+ printk(KERN_WARNING "PCI: no pci dn found for dev=%s\n", pci_name(dev));
return;
}
/* Skip any devices for which EEH is not enabled. */
- pdn = dn->data;
+ pdn = PCI_DN(dn);
if (!(pdn->eeh_mode & EEH_MODE_SUPPORTED) ||
pdn->eeh_mode & EEH_MODE_NOCHECK) {
#ifdef DEBUG
- printk(KERN_INFO "PCI: skip building address cache for=%s\n",
- pci_name(dev));
+ printk(KERN_INFO "PCI: skip building address cache for=%s - %s\n",
+ pci_name(dev), pdn->node->full_name);
#endif
return;
}
@@ -307,7 +305,7 @@ static void __pci_addr_cache_insert_device(struct pci_dev *dev)
* we maintain a cache of devices that can be quickly searched.
* This routine adds a device to that cache.
*/
-void pci_addr_cache_insert_device(struct pci_dev *dev)
+static void pci_addr_cache_insert_device(struct pci_dev *dev)
{
unsigned long flags;
@@ -350,7 +348,7 @@ restart:
* the tree multiple times (once per resource).
* But so what; device removal doesn't need to be that fast.
*/
-void pci_addr_cache_remove_device(struct pci_dev *dev)
+static void pci_addr_cache_remove_device(struct pci_dev *dev)
{
unsigned long flags;
@@ -370,8 +368,12 @@ void pci_addr_cache_remove_device(struct pci_dev *dev)
*/
void __init pci_addr_cache_build(void)
{
+ struct device_node *dn;
struct pci_dev *dev = NULL;
+ if (!eeh_subsystem_enabled)
+ return;
+
spin_lock_init(&pci_io_addr_cache_root.piar_lock);
while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
@@ -380,6 +382,10 @@ void __init pci_addr_cache_build(void)
continue;
}
pci_addr_cache_insert_device(dev);
+
+ /* Save the BAR's; firmware doesn't restore these after EEH reset */
+ dn = pci_device_to_OF_node(dev);
+ eeh_save_bars(dev, PCI_DN(dn));
}
#ifdef DEBUG
@@ -391,22 +397,26 @@ void __init pci_addr_cache_build(void)
/* --------------------------------------------------------------- */
/* Above lies the PCI Address Cache. Below lies the EEH event infrastructure */
-/**
- * eeh_register_notifier - Register to find out about EEH events.
- * @nb: notifier block to callback on events
- */
-int eeh_register_notifier(struct notifier_block *nb)
+void eeh_slot_error_detail (struct pci_dn *pdn, int severity)
{
- return notifier_chain_register(&eeh_notifier_chain, nb);
-}
+ unsigned long flags;
+ int rc;
-/**
- * eeh_unregister_notifier - Unregister to an EEH event notifier.
- * @nb: notifier block to callback on events
- */
-int eeh_unregister_notifier(struct notifier_block *nb)
-{
- return notifier_chain_unregister(&eeh_notifier_chain, nb);
+ /* Log the error with the rtas logger */
+ spin_lock_irqsave(&slot_errbuf_lock, flags);
+ memset(slot_errbuf, 0, eeh_error_buf_size);
+
+ rc = rtas_call(ibm_slot_error_detail,
+ 8, 1, NULL, pdn->eeh_config_addr,
+ BUID_HI(pdn->phb->buid),
+ BUID_LO(pdn->phb->buid), NULL, 0,
+ virt_to_phys(slot_errbuf),
+ eeh_error_buf_size,
+ severity);
+
+ if (rc == 0)
+ log_error(slot_errbuf, ERR_TYPE_RTAS_LOG, 0);
+ spin_unlock_irqrestore(&slot_errbuf_lock, flags);
}
/**
@@ -414,16 +424,16 @@ int eeh_unregister_notifier(struct notifier_block *nb)
* @dn: device node to read
* @rets: array to return results in
*/
-static int read_slot_reset_state(struct device_node *dn, int rets[])
+static int read_slot_reset_state(struct pci_dn *pdn, int rets[])
{
int token, outputs;
- struct pci_dn *pdn = dn->data;
if (ibm_read_slot_reset_state2 != RTAS_UNKNOWN_SERVICE) {
token = ibm_read_slot_reset_state2;
outputs = 4;
} else {
token = ibm_read_slot_reset_state;
+ rets[2] = 0; /* fake PE Unavailable info */
outputs = 3;
}
@@ -432,87 +442,84 @@ static int read_slot_reset_state(struct device_node *dn, int rets[])
}
/**
- * eeh_panic - call panic() for an eeh event that cannot be handled.
- * The philosophy of this routine is that it is better to panic and
- * halt the OS than it is to risk possible data corruption by
- * oblivious device drivers that don't know better.
- *
- * @dev pci device that had an eeh event
- * @reset_state current reset state of the device slot
+ * eeh_token_to_phys - convert EEH address token to phys address
+ * @token i/o token, should be address in the form 0xA....
*/
-static void eeh_panic(struct pci_dev *dev, int reset_state)
+static inline unsigned long eeh_token_to_phys(unsigned long token)
{
- /*
- * XXX We should create a separate sysctl for this.
- *
- * Since the panic_on_oops sysctl is used to halt the system
- * in light of potential corruption, we can use it here.
- */
- if (panic_on_oops)
- panic("EEH: MMIO failure (%d) on device:%s\n", reset_state,
- pci_name(dev));
- else {
- __get_cpu_var(ignored_failures)++;
- printk(KERN_INFO "EEH: Ignored MMIO failure (%d) on device:%s\n",
- reset_state, pci_name(dev));
- }
+ pte_t *ptep;
+ unsigned long pa;
+
+ ptep = find_linux_pte(init_mm.pgd, token);
+ if (!ptep)
+ return token;
+ pa = pte_pfn(*ptep) << PAGE_SHIFT;
+
+ return pa | (token & (PAGE_SIZE-1));
}
-/**
- * eeh_event_handler - dispatch EEH events. The detection of a frozen
- * slot can occur inside an interrupt, where it can be hard to do
- * anything about it. The goal of this routine is to pull these
- * detection events out of the context of the interrupt handler, and
- * re-dispatch them for processing at a later time in a normal context.
- *
- * @dummy - unused
+/**
+ * Return the "partitionable endpoint" (pe) under which this device lies
*/
-static void eeh_event_handler(void *dummy)
+static struct device_node * find_device_pe(struct device_node *dn)
{
- unsigned long flags;
- struct eeh_event *event;
-
- while (1) {
- spin_lock_irqsave(&eeh_eventlist_lock, flags);
- event = NULL;
- if (!list_empty(&eeh_eventlist)) {
- event = list_entry(eeh_eventlist.next, struct eeh_event, list);
- list_del(&event->list);
- }
- spin_unlock_irqrestore(&eeh_eventlist_lock, flags);
- if (event == NULL)
- break;
-
- printk(KERN_INFO "EEH: MMIO failure (%d), notifiying device "
- "%s\n", event->reset_state,
- pci_name(event->dev));
+ while ((dn->parent) && PCI_DN(dn->parent) &&
+ (PCI_DN(dn->parent)->eeh_mode & EEH_MODE_SUPPORTED)) {
+ dn = dn->parent;
+ }
+ return dn;
+}
- atomic_set(&eeh_fail_count, 0);
- notifier_call_chain (&eeh_notifier_chain,
- EEH_NOTIFY_FREEZE, event);
+/** Mark all devices that are peers of this device as failed.
+ * Mark the device driver too, so that it can see the failure
+ * immediately; this is critical, since some drivers poll
+ * status registers in interrupts ... If a driver is polling,
+ * and the slot is frozen, then the driver can deadlock in
+ * an interrupt context, which is bad.
+ */
- __get_cpu_var(slot_resets)++;
+static void __eeh_mark_slot (struct device_node *dn, int mode_flag)
+{
+ while (dn) {
+ if (PCI_DN(dn)) {
+ PCI_DN(dn)->eeh_mode |= mode_flag;
- pci_dev_put(event->dev);
- kfree(event);
+ if (dn->child)
+ __eeh_mark_slot (dn->child, mode_flag);
+ }
+ dn = dn->sibling;
}
}
-/**
- * eeh_token_to_phys - convert EEH address token to phys address
- * @token i/o token, should be address in the form 0xE....
- */
-static inline unsigned long eeh_token_to_phys(unsigned long token)
+void eeh_mark_slot (struct device_node *dn, int mode_flag)
{
- pte_t *ptep;
- unsigned long pa;
+ dn = find_device_pe (dn);
+ PCI_DN(dn)->eeh_mode |= mode_flag;
+ __eeh_mark_slot (dn->child, mode_flag);
+}
- ptep = find_linux_pte(init_mm.pgd, token);
- if (!ptep)
- return token;
- pa = pte_pfn(*ptep) << PAGE_SHIFT;
+static void __eeh_clear_slot (struct device_node *dn, int mode_flag)
+{
+ while (dn) {
+ if (PCI_DN(dn)) {
+ PCI_DN(dn)->eeh_mode &= ~mode_flag;
+ PCI_DN(dn)->eeh_check_count = 0;
+ if (dn->child)
+ __eeh_clear_slot (dn->child, mode_flag);
+ }
+ dn = dn->sibling;
+ }
+}
- return pa | (token & (PAGE_SIZE-1));
+void eeh_clear_slot (struct device_node *dn, int mode_flag)
+{
+ unsigned long flags;
+ spin_lock_irqsave(&confirm_error_lock, flags);
+ dn = find_device_pe (dn);
+ PCI_DN(dn)->eeh_mode &= ~mode_flag;
+ PCI_DN(dn)->eeh_check_count = 0;
+ __eeh_clear_slot (dn->child, mode_flag);
+ spin_unlock_irqrestore(&confirm_error_lock, flags);
}
/**
@@ -526,7 +533,7 @@ static inline unsigned long eeh_token_to_phys(unsigned long token)
* will query firmware for the EEH status.
*
* Returns 0 if there has not been an EEH error; otherwise returns
- * a non-zero value and queues up a solt isolation event notification.
+ * a non-zero value and queues up a slot isolation event notification.
*
* It is safe to call this routine in an interrupt context.
*/
@@ -535,42 +542,59 @@ int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev)
int ret;
int rets[3];
unsigned long flags;
- int rc, reset_state;
- struct eeh_event *event;
struct pci_dn *pdn;
+ int rc = 0;
__get_cpu_var(total_mmio_ffs)++;
if (!eeh_subsystem_enabled)
return 0;
- if (!dn)
+ if (!dn) {
+ __get_cpu_var(no_dn)++;
return 0;
- pdn = dn->data;
+ }
+ pdn = PCI_DN(dn);
/* Access to IO BARs might get this far and still not want checking. */
- if (!pdn->eeh_capable || !(pdn->eeh_mode & EEH_MODE_SUPPORTED) ||
+ if (!(pdn->eeh_mode & EEH_MODE_SUPPORTED) ||
pdn->eeh_mode & EEH_MODE_NOCHECK) {
+ __get_cpu_var(ignored_check)++;
+#ifdef DEBUG
+ printk ("EEH:ignored check (%x) for %s %s\n",
+ pdn->eeh_mode, pci_name (dev), dn->full_name);
+#endif
return 0;
}
if (!pdn->eeh_config_addr) {
+ __get_cpu_var(no_cfg_addr)++;
return 0;
}
- /*
- * If we already have a pending isolation event for this
- * slot, we know it's bad already, we don't need to check...
+ /* If we already have a pending isolation event for this
+ * slot, we know it's bad already, we don't need to check.
+ * Do this checking under a lock; as multiple PCI devices
+ * in one slot might report errors simultaneously, and we
+ * only want one error recovery routine running.
*/
+ spin_lock_irqsave(&confirm_error_lock, flags);
+ rc = 1;
if (pdn->eeh_mode & EEH_MODE_ISOLATED) {
- atomic_inc(&eeh_fail_count);
- if (atomic_read(&eeh_fail_count) >= EEH_MAX_FAILS) {
+ pdn->eeh_check_count ++;
+ if (pdn->eeh_check_count >= EEH_MAX_FAILS) {
+ printk (KERN_ERR "EEH: Device driver ignored %d bad reads, panicing\n",
+ pdn->eeh_check_count);
+ dump_stack();
+
/* re-read the slot reset state */
- if (read_slot_reset_state(dn, rets) != 0)
+ if (read_slot_reset_state(pdn, rets) != 0)
rets[0] = -1; /* reset state unknown */
- eeh_panic(dev, rets[0]);
+
+ /* If we are here, then we hit an infinite loop. Stop. */
+ panic("EEH: MMIO halt (%d) on device:%s\n", rets[0], pci_name(dev));
}
- return 0;
+ goto dn_unlock;
}
/*
@@ -580,66 +604,69 @@ int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev)
* function zero of a multi-function device.
* In any case they must share a common PHB.
*/
- ret = read_slot_reset_state(dn, rets);
- if (!(ret == 0 && rets[1] == 1 && (rets[0] == 2 || rets[0] == 4))) {
+ ret = read_slot_reset_state(pdn, rets);
+
+ /* If the call to firmware failed, punt */
+ if (ret != 0) {
+ printk(KERN_WARNING "EEH: read_slot_reset_state() failed; rc=%d dn=%s\n",
+ ret, dn->full_name);
__get_cpu_var(false_positives)++;
- return 0;
+ rc = 0;
+ goto dn_unlock;
}
- /* prevent repeated reports of this failure */
- pdn->eeh_mode |= EEH_MODE_ISOLATED;
-
- reset_state = rets[0];
-
- spin_lock_irqsave(&slot_errbuf_lock, flags);
- memset(slot_errbuf, 0, eeh_error_buf_size);
-
- rc = rtas_call(ibm_slot_error_detail,
- 8, 1, NULL, pdn->eeh_config_addr,
- BUID_HI(pdn->phb->buid),
- BUID_LO(pdn->phb->buid), NULL, 0,
- virt_to_phys(slot_errbuf),
- eeh_error_buf_size,
- 1 /* Temporary Error */);
-
- if (rc == 0)
- log_error(slot_errbuf, ERR_TYPE_RTAS_LOG, 0);
- spin_unlock_irqrestore(&slot_errbuf_lock, flags);
+ /* If EEH is not supported on this device, punt. */
+ if (rets[1] != 1) {
+ printk(KERN_WARNING "EEH: event on unsupported device, rc=%d dn=%s\n",
+ ret, dn->full_name);
+ __get_cpu_var(false_positives)++;
+ rc = 0;
+ goto dn_unlock;
+ }
- printk(KERN_INFO "EEH: MMIO failure (%d) on device: %s %s\n",
- rets[0], dn->name, dn->full_name);
- event = kmalloc(sizeof(*event), GFP_ATOMIC);
- if (event == NULL) {
- eeh_panic(dev, reset_state);
- return 1;
- }
+ /* If not the kind of error we know about, punt. */
+ if (rets[0] != 2 && rets[0] != 4 && rets[0] != 5) {
+ __get_cpu_var(false_positives)++;
+ rc = 0;
+ goto dn_unlock;
+ }
- event->dev = dev;
- event->dn = dn;
- event->reset_state = reset_state;
+ /* Note that config-io to empty slots may fail;
+ * we recognize empty because they don't have children. */
+ if ((rets[0] == 5) && (dn->child == NULL)) {
+ __get_cpu_var(false_positives)++;
+ rc = 0;
+ goto dn_unlock;
+ }
- /* We may or may not be called in an interrupt context */
- spin_lock_irqsave(&eeh_eventlist_lock, flags);
- list_add(&event->list, &eeh_eventlist);
- spin_unlock_irqrestore(&eeh_eventlist_lock, flags);
+ __get_cpu_var(slot_resets)++;
+
+ /* Avoid repeated reports of this failure, including problems
+ * with other functions on this device, and functions under
+ * bridges. */
+ eeh_mark_slot (dn, EEH_MODE_ISOLATED);
+ spin_unlock_irqrestore(&confirm_error_lock, flags);
+ eeh_send_failure_event (dn, dev, rets[0], rets[2]);
+
/* Most EEH events are due to device driver bugs. Having
* a stack trace will help the device-driver authors figure
* out what happened. So print that out. */
- dump_stack();
- schedule_work(&eeh_event_wq);
+ if (rets[0] != 5) dump_stack();
+ return 1;
- return 0;
+dn_unlock:
+ spin_unlock_irqrestore(&confirm_error_lock, flags);
+ return rc;
}
-EXPORT_SYMBOL(eeh_dn_check_failure);
+EXPORT_SYMBOL_GPL(eeh_dn_check_failure);
/**
* eeh_check_failure - check if all 1's data is due to EEH slot freeze
* @token i/o token, should be address in the form 0xA....
* @val value, should be all 1's (XXX why do we need this arg??)
*
- * Check for an eeh failure at the given token address.
* Check for an EEH failure at the given token address. Call this
* routine if the result of a read was all 0xff's and you want to
* find out if this is due to an EEH slot freeze event. This routine
@@ -656,8 +683,10 @@ unsigned long eeh_check_failure(const volatile void __iomem *token, unsigned lon
/* Finding the phys addr + pci device; this is pretty quick. */
addr = eeh_token_to_phys((unsigned long __force) token);
dev = pci_get_device_by_addr(addr);
- if (!dev)
+ if (!dev) {
+ __get_cpu_var(no_device)++;
return val;
+ }
dn = pci_device_to_OF_node(dev);
eeh_dn_check_failure (dn, dev);
@@ -668,6 +697,217 @@ unsigned long eeh_check_failure(const volatile void __iomem *token, unsigned lon
EXPORT_SYMBOL(eeh_check_failure);
+/* ------------------------------------------------------------- */
+/* The code below deals with error recovery */
+
+/** Return negative value if a permanent error, else return
+ * a number of milliseconds to wait until the PCI slot is
+ * ready to be used.
+ */
+static int
+eeh_slot_availability(struct pci_dn *pdn)
+{
+ int rc;
+ int rets[3];
+
+ rc = read_slot_reset_state(pdn, rets);
+
+ if (rc) return rc;
+
+ if (rets[1] == 0) return -1; /* EEH is not supported */
+ if (rets[0] == 0) return 0; /* Oll Korrect */
+ if (rets[0] == 5) {
+ if (rets[2] == 0) return -1; /* permanently unavailable */
+ return rets[2]; /* number of millisecs to wait */
+ }
+ return -1;
+}
+
+/** rtas_pci_slot_reset raises/lowers the pci #RST line
+ * state: 1/0 to raise/lower the #RST
+ *
+ * Clear the EEH-frozen condition on a slot. This routine
+ * asserts the PCI #RST line if the 'state' argument is '1',
+ * and drops the #RST line if 'state is '0'. This routine is
+ * safe to call in an interrupt context.
+ *
+ */
+
+static void
+rtas_pci_slot_reset(struct pci_dn *pdn, int state)
+{
+ int rc;
+
+ BUG_ON (pdn==NULL);
+
+ if (!pdn->phb) {
+ printk (KERN_WARNING "EEH: in slot reset, device node %s has no phb\n",
+ pdn->node->full_name);
+ return;
+ }
+
+ rc = rtas_call(ibm_set_slot_reset,4,1, NULL,
+ pdn->eeh_config_addr,
+ BUID_HI(pdn->phb->buid),
+ BUID_LO(pdn->phb->buid),
+ state);
+ if (rc) {
+ printk (KERN_WARNING "EEH: Unable to reset the failed slot, (%d) #RST=%d dn=%s\n",
+ rc, state, pdn->node->full_name);
+ return;
+ }
+}
+
+/** rtas_set_slot_reset -- assert the pci #RST line for 1/4 second
+ * dn -- device node to be reset.
+ */
+
+void
+rtas_set_slot_reset(struct pci_dn *pdn)
+{
+ int i, rc;
+
+ rtas_pci_slot_reset (pdn, 1);
+
+ /* The PCI bus requires that the reset be held high for at least
+ * a 100 milliseconds. We wait a bit longer 'just in case'. */
+
+#define PCI_BUS_RST_HOLD_TIME_MSEC 250
+ msleep (PCI_BUS_RST_HOLD_TIME_MSEC);
+
+ /* We might get hit with another EEH freeze as soon as the
+ * pci slot reset line is dropped. Make sure we don't miss
+ * these, and clear the flag now. */
+ eeh_clear_slot (pdn->node, EEH_MODE_ISOLATED);
+
+ rtas_pci_slot_reset (pdn, 0);
+
+ /* After a PCI slot has been reset, the PCI Express spec requires
+ * a 1.5 second idle time for the bus to stabilize, before starting
+ * up traffic. */
+#define PCI_BUS_SETTLE_TIME_MSEC 1800
+ msleep (PCI_BUS_SETTLE_TIME_MSEC);
+
+ /* Now double check with the firmware to make sure the device is
+ * ready to be used; if not, wait for recovery. */
+ for (i=0; i<10; i++) {
+ rc = eeh_slot_availability (pdn);
+ if (rc <= 0) break;
+
+ msleep (rc+100);
+ }
+}
+
+/* ------------------------------------------------------- */
+/** Save and restore of PCI BARs
+ *
+ * Although firmware will set up BARs during boot, it doesn't
+ * set up device BAR's after a device reset, although it will,
+ * if requested, set up bridge configuration. Thus, we need to
+ * configure the PCI devices ourselves.
+ */
+
+/**
+ * __restore_bars - Restore the Base Address Registers
+ * Loads the PCI configuration space base address registers,
+ * the expansion ROM base address, the latency timer, and etc.
+ * from the saved values in the device node.
+ */
+static inline void __restore_bars (struct pci_dn *pdn)
+{
+ int i;
+
+ if (NULL==pdn->phb) return;
+ for (i=4; i<10; i++) {
+ rtas_write_config(pdn, i*4, 4, pdn->config_space[i]);
+ }
+
+ /* 12 == Expansion ROM Address */
+ rtas_write_config(pdn, 12*4, 4, pdn->config_space[12]);
+
+#define BYTE_SWAP(OFF) (8*((OFF)/4)+3-(OFF))
+#define SAVED_BYTE(OFF) (((u8 *)(pdn->config_space))[BYTE_SWAP(OFF)])
+
+ rtas_write_config (pdn, PCI_CACHE_LINE_SIZE, 1,
+ SAVED_BYTE(PCI_CACHE_LINE_SIZE));
+
+ rtas_write_config (pdn, PCI_LATENCY_TIMER, 1,
+ SAVED_BYTE(PCI_LATENCY_TIMER));
+
+ /* max latency, min grant, interrupt pin and line */
+ rtas_write_config(pdn, 15*4, 4, pdn->config_space[15]);
+}
+
+/**
+ * eeh_restore_bars - restore the PCI config space info
+ *
+ * This routine performs a recursive walk to the children
+ * of this device as well.
+ */
+void eeh_restore_bars(struct pci_dn *pdn)
+{
+ struct device_node *dn;
+ if (!pdn)
+ return;
+
+ if (! pdn->eeh_is_bridge)
+ __restore_bars (pdn);
+
+ dn = pdn->node->child;
+ while (dn) {
+ eeh_restore_bars (PCI_DN(dn));
+ dn = dn->sibling;
+ }
+}
+
+/**
+ * eeh_save_bars - save device bars
+ *
+ * Save the values of the device bars. Unlike the restore
+ * routine, this routine is *not* recursive. This is because
+ * PCI devices are added individuallly; but, for the restore,
+ * an entire slot is reset at a time.
+ */
+static void eeh_save_bars(struct pci_dev * pdev, struct pci_dn *pdn)
+{
+ int i;
+
+ if (!pdev || !pdn )
+ return;
+
+ for (i = 0; i < 16; i++)
+ pci_read_config_dword(pdev, i * 4, &pdn->config_space[i]);
+
+ if (pdev->hdr_type == PCI_HEADER_TYPE_BRIDGE)
+ pdn->eeh_is_bridge = 1;
+}
+
+void
+rtas_configure_bridge(struct pci_dn *pdn)
+{
+ int token = rtas_token ("ibm,configure-bridge");
+ int rc;
+
+ if (token == RTAS_UNKNOWN_SERVICE)
+ return;
+ rc = rtas_call(token,3,1, NULL,
+ pdn->eeh_config_addr,
+ BUID_HI(pdn->phb->buid),
+ BUID_LO(pdn->phb->buid));
+ if (rc) {
+ printk (KERN_WARNING "EEH: Unable to configure device bridge (%d) for %s\n",
+ rc, pdn->node->full_name);
+ }
+}
+
+/* ------------------------------------------------------------- */
+/* The code below deals with enabling EEH for devices during the
+ * early boot sequence. EEH must be enabled before any PCI probing
+ * can be done.
+ */
+
+#define EEH_ENABLE 1
+
struct eeh_early_enable_info {
unsigned int buid_hi;
unsigned int buid_lo;
@@ -684,9 +924,11 @@ static void *early_enable_eeh(struct device_node *dn, void *data)
u32 *device_id = (u32 *)get_property(dn, "device-id", NULL);
u32 *regs;
int enable;
- struct pci_dn *pdn = dn->data;
+ struct pci_dn *pdn = PCI_DN(dn);
pdn->eeh_mode = 0;
+ pdn->eeh_check_count = 0;
+ pdn->eeh_freeze_count = 0;
if (status && strcmp(status, "ok") != 0)
return NULL; /* ignore devices with bad status */
@@ -723,8 +965,9 @@ static void *early_enable_eeh(struct device_node *dn, void *data)
/* First register entry is addr (00BBSS00) */
/* Try to enable eeh */
ret = rtas_call(ibm_set_eeh_option, 4, 1, NULL,
- regs[0], info->buid_hi, info->buid_lo,
- EEH_ENABLE);
+ regs[0], info->buid_hi, info->buid_lo,
+ EEH_ENABLE);
+
if (ret == 0) {
eeh_subsystem_enabled = 1;
pdn->eeh_mode |= EEH_MODE_SUPPORTED;
@@ -736,7 +979,7 @@ static void *early_enable_eeh(struct device_node *dn, void *data)
/* This device doesn't support EEH, but it may have an
* EEH parent, in which case we mark it as supported. */
- if (dn->parent && dn->parent->data
+ if (dn->parent && PCI_DN(dn->parent)
&& (PCI_DN(dn->parent)->eeh_mode & EEH_MODE_SUPPORTED)) {
/* Parent supports EEH. */
pdn->eeh_mode |= EEH_MODE_SUPPORTED;
@@ -749,7 +992,7 @@ static void *early_enable_eeh(struct device_node *dn, void *data)
dn->full_name);
}
- return NULL;
+ return NULL;
}
/*
@@ -770,6 +1013,9 @@ void __init eeh_init(void)
struct device_node *phb, *np;
struct eeh_early_enable_info info;
+ spin_lock_init(&confirm_error_lock);
+ spin_lock_init(&slot_errbuf_lock);
+
np = of_find_node_by_path("/rtas");
if (np == NULL)
return;
@@ -797,13 +1043,11 @@ void __init eeh_init(void)
for (phb = of_find_node_by_name(NULL, "pci"); phb;
phb = of_find_node_by_name(phb, "pci")) {
unsigned long buid;
- struct pci_dn *pci;
buid = get_phb_buid(phb);
- if (buid == 0 || phb->data == NULL)
+ if (buid == 0 || PCI_DN(phb) == NULL)
continue;
- pci = phb->data;
info.buid_lo = BUID_LO(buid);
info.buid_hi = BUID_HI(buid);
traverse_pci_devices(phb, early_enable_eeh, &info);
@@ -832,11 +1076,13 @@ void eeh_add_device_early(struct device_node *dn)
struct pci_controller *phb;
struct eeh_early_enable_info info;
- if (!dn || !dn->data)
+ if (!dn || !PCI_DN(dn))
return;
phb = PCI_DN(dn)->phb;
if (NULL == phb || 0 == phb->buid) {
- printk(KERN_WARNING "EEH: Expected buid but found none\n");
+ printk(KERN_WARNING "EEH: Expected buid but found none for %s\n",
+ dn->full_name);
+ dump_stack();
return;
}
@@ -844,7 +1090,7 @@ void eeh_add_device_early(struct device_node *dn)
info.buid_lo = BUID_LO(phb->buid);
early_enable_eeh(dn, &info);
}
-EXPORT_SYMBOL(eeh_add_device_early);
+EXPORT_SYMBOL_GPL(eeh_add_device_early);
/**
* eeh_add_device_late - perform EEH initialization for the indicated pci device
@@ -855,6 +1101,9 @@ EXPORT_SYMBOL(eeh_add_device_early);
*/
void eeh_add_device_late(struct pci_dev *dev)
{
+ struct device_node *dn;
+ struct pci_dn *pdn;
+
if (!dev || !eeh_subsystem_enabled)
return;
@@ -862,9 +1111,15 @@ void eeh_add_device_late(struct pci_dev *dev)
printk(KERN_DEBUG "EEH: adding device %s\n", pci_name(dev));
#endif
+ pci_dev_get (dev);
+ dn = pci_device_to_OF_node(dev);
+ pdn = PCI_DN(dn);
+ pdn->pcidev = dev;
+
pci_addr_cache_insert_device (dev);
+ eeh_save_bars(dev, pdn);
}
-EXPORT_SYMBOL(eeh_add_device_late);
+EXPORT_SYMBOL_GPL(eeh_add_device_late);
/**
* eeh_remove_device - undo EEH setup for the indicated pci device
@@ -875,6 +1130,7 @@ EXPORT_SYMBOL(eeh_add_device_late);
*/
void eeh_remove_device(struct pci_dev *dev)
{
+ struct device_node *dn;
if (!dev || !eeh_subsystem_enabled)
return;
@@ -883,20 +1139,29 @@ void eeh_remove_device(struct pci_dev *dev)
printk(KERN_DEBUG "EEH: remove device %s\n", pci_name(dev));
#endif
pci_addr_cache_remove_device(dev);
+
+ dn = pci_device_to_OF_node(dev);
+ PCI_DN(dn)->pcidev = NULL;
+ pci_dev_put (dev);
}
-EXPORT_SYMBOL(eeh_remove_device);
+EXPORT_SYMBOL_GPL(eeh_remove_device);
static int proc_eeh_show(struct seq_file *m, void *v)
{
unsigned int cpu;
unsigned long ffs = 0, positives = 0, failures = 0;
unsigned long resets = 0;
+ unsigned long no_dev = 0, no_dn = 0, no_cfg = 0, no_check = 0;
for_each_cpu(cpu) {
ffs += per_cpu(total_mmio_ffs, cpu);
positives += per_cpu(false_positives, cpu);
failures += per_cpu(ignored_failures, cpu);
resets += per_cpu(slot_resets, cpu);
+ no_dev += per_cpu(no_device, cpu);
+ no_dn += per_cpu(no_dn, cpu);
+ no_cfg += per_cpu(no_cfg_addr, cpu);
+ no_check += per_cpu(ignored_check, cpu);
}
if (0 == eeh_subsystem_enabled) {
@@ -904,13 +1169,17 @@ static int proc_eeh_show(struct seq_file *m, void *v)
seq_printf(m, "eeh_total_mmio_ffs=%ld\n", ffs);
} else {
seq_printf(m, "EEH Subsystem is enabled\n");
- seq_printf(m, "eeh_total_mmio_ffs=%ld\n"
- "eeh_false_positives=%ld\n"
- "eeh_ignored_failures=%ld\n"
- "eeh_slot_resets=%ld\n"
- "eeh_fail_count=%d\n",
- ffs, positives, failures, resets,
- eeh_fail_count.counter);
+ seq_printf(m,
+ "no device=%ld\n"
+ "no device node=%ld\n"
+ "no config address=%ld\n"
+ "check not wanted=%ld\n"
+ "eeh_total_mmio_ffs=%ld\n"
+ "eeh_false_positives=%ld\n"
+ "eeh_ignored_failures=%ld\n"
+ "eeh_slot_resets=%ld\n",
+ no_dev, no_dn, no_cfg, no_check,
+ ffs, positives, failures, resets);
}
return 0;
@@ -932,7 +1201,7 @@ static int __init eeh_init_proc(void)
{
struct proc_dir_entry *e;
- if (systemcfg->platform & PLATFORM_PSERIES) {
+ if (platform_is_pseries()) {
e = create_proc_entry("ppc64/eeh", 0, NULL);
if (e)
e->proc_fops = &proc_eeh_operations;
diff --git a/arch/powerpc/platforms/pseries/eeh_event.c b/arch/powerpc/platforms/pseries/eeh_event.c
new file mode 100644
index 000000000000..92497333c2b6
--- /dev/null
+++ b/arch/powerpc/platforms/pseries/eeh_event.c
@@ -0,0 +1,155 @@
+/*
+ * eeh_event.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Copyright (c) 2005 Linas Vepstas <linas@linas.org>
+ */
+
+#include <linux/list.h>
+#include <linux/pci.h>
+#include <asm/eeh_event.h>
+
+/** Overview:
+ * EEH error states may be detected within exception handlers;
+ * however, the recovery processing needs to occur asynchronously
+ * in a normal kernel context and not an interrupt context.
+ * This pair of routines creates an event and queues it onto a
+ * work-queue, where a worker thread can drive recovery.
+ */
+
+/* EEH event workqueue setup. */
+static spinlock_t eeh_eventlist_lock = SPIN_LOCK_UNLOCKED;
+LIST_HEAD(eeh_eventlist);
+static void eeh_thread_launcher(void *);
+DECLARE_WORK(eeh_event_wq, eeh_thread_launcher, NULL);
+
+/**
+ * eeh_panic - call panic() for an eeh event that cannot be handled.
+ * The philosophy of this routine is that it is better to panic and
+ * halt the OS than it is to risk possible data corruption by
+ * oblivious device drivers that don't know better.
+ *
+ * @dev pci device that had an eeh event
+ * @reset_state current reset state of the device slot
+ */
+static void eeh_panic(struct pci_dev *dev, int reset_state)
+{
+ /*
+ * Since the panic_on_oops sysctl is used to halt the system
+ * in light of potential corruption, we can use it here.
+ */
+ if (panic_on_oops) {
+ panic("EEH: MMIO failure (%d) on device:%s\n", reset_state,
+ pci_name(dev));
+ }
+ else {
+ printk(KERN_INFO "EEH: Ignored MMIO failure (%d) on device:%s\n",
+ reset_state, pci_name(dev));
+ }
+}
+
+/**
+ * eeh_event_handler - dispatch EEH events. The detection of a frozen
+ * slot can occur inside an interrupt, where it can be hard to do
+ * anything about it. The goal of this routine is to pull these
+ * detection events out of the context of the interrupt handler, and
+ * re-dispatch them for processing at a later time in a normal context.
+ *
+ * @dummy - unused
+ */
+static int eeh_event_handler(void * dummy)
+{
+ unsigned long flags;
+ struct eeh_event *event;
+
+ daemonize ("eehd");
+
+ while (1) {
+ set_current_state(TASK_INTERRUPTIBLE);
+
+ spin_lock_irqsave(&eeh_eventlist_lock, flags);
+ event = NULL;
+ if (!list_empty(&eeh_eventlist)) {
+ event = list_entry(eeh_eventlist.next, struct eeh_event, list);
+ list_del(&event->list);
+ }
+ spin_unlock_irqrestore(&eeh_eventlist_lock, flags);
+ if (event == NULL)
+ break;
+
+ printk(KERN_INFO "EEH: Detected PCI bus error on device %s\n",
+ pci_name(event->dev));
+
+ eeh_panic (event->dev, event->state);
+
+ kfree(event);
+ }
+
+ return 0;
+}
+
+/**
+ * eeh_thread_launcher
+ *
+ * @dummy - unused
+ */
+static void eeh_thread_launcher(void *dummy)
+{
+ if (kernel_thread(eeh_event_handler, NULL, CLONE_KERNEL) < 0)
+ printk(KERN_ERR "Failed to start EEH daemon\n");
+}
+
+/**
+ * eeh_send_failure_event - generate a PCI error event
+ * @dev pci device
+ *
+ * This routine can be called within an interrupt context;
+ * the actual event will be delivered in a normal context
+ * (from a workqueue).
+ */
+int eeh_send_failure_event (struct device_node *dn,
+ struct pci_dev *dev,
+ int state,
+ int time_unavail)
+{
+ unsigned long flags;
+ struct eeh_event *event;
+
+ event = kmalloc(sizeof(*event), GFP_ATOMIC);
+ if (event == NULL) {
+ printk (KERN_ERR "EEH: out of memory, event not handled\n");
+ return 1;
+ }
+
+ if (dev)
+ pci_dev_get(dev);
+
+ event->dn = dn;
+ event->dev = dev;
+ event->state = state;
+ event->time_unavail = time_unavail;
+
+ /* We may or may not be called in an interrupt context */
+ spin_lock_irqsave(&eeh_eventlist_lock, flags);
+ list_add(&event->list, &eeh_eventlist);
+ spin_unlock_irqrestore(&eeh_eventlist_lock, flags);
+
+ schedule_work(&eeh_event_wq);
+
+ return 0;
+}
+
+/********************** END OF FILE ******************************/
diff --git a/arch/ppc64/kernel/pSeries_hvCall.S b/arch/powerpc/platforms/pseries/hvCall.S
index 176e8da76466..176e8da76466 100644
--- a/arch/ppc64/kernel/pSeries_hvCall.S
+++ b/arch/powerpc/platforms/pseries/hvCall.S
diff --git a/arch/ppc64/kernel/pSeries_iommu.c b/arch/powerpc/platforms/pseries/iommu.c
index d17f0108a032..97ba5214417f 100644
--- a/arch/ppc64/kernel/pSeries_iommu.c
+++ b/arch/powerpc/platforms/pseries/iommu.c
@@ -37,16 +37,17 @@
#include <asm/io.h>
#include <asm/prom.h>
#include <asm/rtas.h>
-#include <asm/ppcdebug.h>
#include <asm/iommu.h>
#include <asm/pci-bridge.h>
#include <asm/machdep.h>
#include <asm/abs_addr.h>
-#include <asm/plpar_wrappers.h>
#include <asm/pSeries_reconfig.h>
-#include <asm/systemcfg.h>
#include <asm/firmware.h>
-#include "pci.h"
+#include <asm/tce.h>
+#include <asm/ppc-pci.h>
+#include <asm/udbg.h>
+
+#include "plpar_wrappers.h"
#define DBG(fmt...)
@@ -59,6 +60,9 @@ static void tce_build_pSeries(struct iommu_table *tbl, long index,
union tce_entry t;
union tce_entry *tp;
+ index <<= TCE_PAGE_FACTOR;
+ npages <<= TCE_PAGE_FACTOR;
+
t.te_word = 0;
t.te_rdwr = 1; // Read allowed
@@ -69,11 +73,11 @@ static void tce_build_pSeries(struct iommu_table *tbl, long index,
while (npages--) {
/* can't move this out since we might cross LMB boundary */
- t.te_rpn = (virt_to_abs(uaddr)) >> PAGE_SHIFT;
+ t.te_rpn = (virt_to_abs(uaddr)) >> TCE_SHIFT;
tp->te_word = t.te_word;
- uaddr += PAGE_SIZE;
+ uaddr += TCE_PAGE_SIZE;
tp++;
}
}
@@ -84,6 +88,9 @@ static void tce_free_pSeries(struct iommu_table *tbl, long index, long npages)
union tce_entry t;
union tce_entry *tp;
+ npages <<= TCE_PAGE_FACTOR;
+ index <<= TCE_PAGE_FACTOR;
+
t.te_word = 0;
tp = ((union tce_entry *)tbl->it_base) + index;
@@ -103,7 +110,7 @@ static void tce_build_pSeriesLP(struct iommu_table *tbl, long tcenum,
union tce_entry tce;
tce.te_word = 0;
- tce.te_rpn = (virt_to_abs(uaddr)) >> PAGE_SHIFT;
+ tce.te_rpn = (virt_to_abs(uaddr)) >> TCE_SHIFT;
tce.te_rdwr = 1;
if (direction != DMA_TO_DEVICE)
tce.te_pciwr = 1;
@@ -136,6 +143,9 @@ static void tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum,
union tce_entry tce, *tcep;
long l, limit;
+ tcenum <<= TCE_PAGE_FACTOR;
+ npages <<= TCE_PAGE_FACTOR;
+
if (npages == 1)
return tce_build_pSeriesLP(tbl, tcenum, npages, uaddr,
direction);
@@ -155,7 +165,7 @@ static void tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum,
}
tce.te_word = 0;
- tce.te_rpn = (virt_to_abs(uaddr)) >> PAGE_SHIFT;
+ tce.te_rpn = (virt_to_abs(uaddr)) >> TCE_SHIFT;
tce.te_rdwr = 1;
if (direction != DMA_TO_DEVICE)
tce.te_pciwr = 1;
@@ -166,7 +176,7 @@ static void tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum,
* Set up the page with TCE data, looping through and setting
* the values.
*/
- limit = min_t(long, npages, PAGE_SIZE/sizeof(union tce_entry));
+ limit = min_t(long, npages, 4096/sizeof(union tce_entry));
for (l = 0; l < limit; l++) {
tcep[l] = tce;
@@ -196,6 +206,9 @@ static void tce_free_pSeriesLP(struct iommu_table *tbl, long tcenum, long npages
u64 rc;
union tce_entry tce;
+ tcenum <<= TCE_PAGE_FACTOR;
+ npages <<= TCE_PAGE_FACTOR;
+
tce.te_word = 0;
while (npages--) {
@@ -221,6 +234,9 @@ static void tce_freemulti_pSeriesLP(struct iommu_table *tbl, long tcenum, long n
u64 rc;
union tce_entry tce;
+ tcenum <<= TCE_PAGE_FACTOR;
+ npages <<= TCE_PAGE_FACTOR;
+
tce.te_word = 0;
rc = plpar_tce_stuff((u64)tbl->it_index,
@@ -482,7 +498,7 @@ static int iommu_reconfig_notifier(struct notifier_block *nb, unsigned long acti
switch (action) {
case PSERIES_RECONFIG_REMOVE:
- if (pci->iommu_table &&
+ if (pci && pci->iommu_table &&
get_property(np, "ibm,dma-window", NULL))
iommu_free_table(np);
break;
@@ -565,7 +581,7 @@ void iommu_init_early_pSeries(void)
return;
}
- if (systemcfg->platform & PLATFORM_LPAR) {
+ if (platform_is_lpar()) {
if (firmware_has_feature(FW_FEATURE_MULTITCE)) {
ppc_md.tce_build = tce_buildmulti_pSeriesLP;
ppc_md.tce_free = tce_freemulti_pSeriesLP;
diff --git a/arch/ppc64/kernel/pSeries_lpar.c b/arch/powerpc/platforms/pseries/lpar.c
index a6de83f2078f..a50e5f3f396d 100644
--- a/arch/ppc64/kernel/pSeries_lpar.c
+++ b/arch/powerpc/platforms/pseries/lpar.c
@@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#define DEBUG
+#undef DEBUG_LOW
#include <linux/config.h>
#include <linux/kernel.h>
@@ -31,19 +31,21 @@
#include <asm/machdep.h>
#include <asm/abs_addr.h>
#include <asm/mmu_context.h>
-#include <asm/ppcdebug.h>
#include <asm/iommu.h>
#include <asm/tlbflush.h>
#include <asm/tlb.h>
#include <asm/prom.h>
#include <asm/abs_addr.h>
#include <asm/cputable.h>
-#include <asm/plpar_wrappers.h>
+#include <asm/udbg.h>
+#include <asm/smp.h>
-#ifdef DEBUG
-#define DBG(fmt...) udbg_printf(fmt)
+#include "plpar_wrappers.h"
+
+#ifdef DEBUG_LOW
+#define DBG_LOW(fmt...) do { udbg_printf(fmt); } while(0)
#else
-#define DBG(fmt...)
+#define DBG_LOW(fmt...) do { } while(0)
#endif
/* in pSeries_hvCall.S */
@@ -260,27 +262,24 @@ out:
void vpa_init(int cpu)
{
int hwcpu = get_hard_smp_processor_id(cpu);
- unsigned long vpa = (unsigned long)&(paca[cpu].lppaca);
+ unsigned long vpa = __pa(&paca[cpu].lppaca);
long ret;
- unsigned long flags;
-
- /* Register the Virtual Processor Area (VPA) */
- flags = 1UL << (63 - 18);
if (cpu_has_feature(CPU_FTR_ALTIVEC))
paca[cpu].lppaca.vmxregs_in_use = 1;
- ret = register_vpa(flags, hwcpu, __pa(vpa));
+ ret = register_vpa(hwcpu, vpa);
if (ret)
printk(KERN_ERR "WARNING: vpa_init: VPA registration for "
"cpu %d (hw %d) of area %lx returns %ld\n",
- cpu, hwcpu, __pa(vpa), ret);
+ cpu, hwcpu, vpa, ret);
}
long pSeries_lpar_hpte_insert(unsigned long hpte_group,
- unsigned long va, unsigned long prpn,
- unsigned long vflags, unsigned long rflags)
+ unsigned long va, unsigned long pa,
+ unsigned long rflags, unsigned long vflags,
+ int psize)
{
unsigned long lpar_rc;
unsigned long flags;
@@ -288,11 +287,28 @@ long pSeries_lpar_hpte_insert(unsigned long hpte_group,
unsigned long hpte_v, hpte_r;
unsigned long dummy0, dummy1;
- hpte_v = ((va >> 23) << HPTE_V_AVPN_SHIFT) | vflags | HPTE_V_VALID;
- if (vflags & HPTE_V_LARGE)
- hpte_v &= ~(1UL << HPTE_V_AVPN_SHIFT);
-
- hpte_r = (prpn << HPTE_R_RPN_SHIFT) | rflags;
+ if (!(vflags & HPTE_V_BOLTED))
+ DBG_LOW("hpte_insert(group=%lx, va=%016lx, pa=%016lx, "
+ "rflags=%lx, vflags=%lx, psize=%d)\n",
+ hpte_group, va, pa, rflags, vflags, psize);
+
+ hpte_v = hpte_encode_v(va, psize) | vflags | HPTE_V_VALID;
+ hpte_r = hpte_encode_r(pa, psize) | rflags;
+
+ if (!(vflags & HPTE_V_BOLTED))
+ DBG_LOW(" hpte_v=%016lx, hpte_r=%016lx\n", hpte_v, hpte_r);
+
+#if 1
+ {
+ int i;
+ for (i=0;i<8;i++) {
+ unsigned long w0, w1;
+ plpar_pte_read(0, hpte_group, &w0, &w1);
+ BUG_ON (HPTE_V_COMPARE(hpte_v, w0)
+ && (w0 & HPTE_V_VALID));
+ }
+ }
+#endif
/* Now fill in the actual HPTE */
/* Set CEC cookie to 0 */
@@ -302,23 +318,30 @@ long pSeries_lpar_hpte_insert(unsigned long hpte_group,
/* Exact = 0 */
flags = 0;
- /* XXX why is this here? - Anton */
+ /* Make pHyp happy */
if (rflags & (_PAGE_GUARDED|_PAGE_NO_CACHE))
hpte_r &= ~_PAGE_COHERENT;
lpar_rc = plpar_hcall(H_ENTER, flags, hpte_group, hpte_v,
hpte_r, &slot, &dummy0, &dummy1);
-
- if (unlikely(lpar_rc == H_PTEG_Full))
+ if (unlikely(lpar_rc == H_PTEG_Full)) {
+ if (!(vflags & HPTE_V_BOLTED))
+ DBG_LOW(" full\n");
return -1;
+ }
/*
* Since we try and ioremap PHBs we don't own, the pte insert
* will fail. However we must catch the failure in hash_page
* or we will loop forever, so return -2 in this case.
*/
- if (unlikely(lpar_rc != H_Success))
+ if (unlikely(lpar_rc != H_Success)) {
+ if (!(vflags & HPTE_V_BOLTED))
+ DBG_LOW(" lpar err %d\n", lpar_rc);
return -2;
+ }
+ if (!(vflags & HPTE_V_BOLTED))
+ DBG_LOW(" -> slot: %d\n", slot & 7);
/* Because of iSeries, we have to pass down the secondary
* bucket bit here as well
@@ -343,10 +366,8 @@ static long pSeries_lpar_hpte_remove(unsigned long hpte_group)
/* don't remove a bolted entry */
lpar_rc = plpar_pte_remove(H_ANDCOND, hpte_group + slot_offset,
(0x1UL << 4), &dummy1, &dummy2);
-
if (lpar_rc == H_Success)
return i;
-
BUG_ON(lpar_rc != H_Not_Found);
slot_offset++;
@@ -374,20 +395,28 @@ static void pSeries_lpar_hptab_clear(void)
* We can probably optimize here and assume the high bits of newpp are
* already zero. For now I am paranoid.
*/
-static long pSeries_lpar_hpte_updatepp(unsigned long slot, unsigned long newpp,
- unsigned long va, int large, int local)
+static long pSeries_lpar_hpte_updatepp(unsigned long slot,
+ unsigned long newpp,
+ unsigned long va,
+ int psize, int local)
{
unsigned long lpar_rc;
unsigned long flags = (newpp & 7) | H_AVPN;
- unsigned long avpn = va >> 23;
+ unsigned long want_v;
- if (large)
- avpn &= ~0x1UL;
+ want_v = hpte_encode_v(va, psize);
- lpar_rc = plpar_pte_protect(flags, slot, (avpn << 7));
+ DBG_LOW(" update: avpnv=%016lx, hash=%016lx, f=%x, psize: %d ... ",
+ want_v & HPTE_V_AVPN, slot, flags, psize);
- if (lpar_rc == H_Not_Found)
+ lpar_rc = plpar_pte_protect(flags, slot, want_v & HPTE_V_AVPN);
+
+ if (lpar_rc == H_Not_Found) {
+ DBG_LOW("not found !\n");
return -1;
+ }
+
+ DBG_LOW("ok\n");
BUG_ON(lpar_rc != H_Success);
@@ -413,21 +442,22 @@ static unsigned long pSeries_lpar_hpte_getword0(unsigned long slot)
return dword0;
}
-static long pSeries_lpar_hpte_find(unsigned long vpn)
+static long pSeries_lpar_hpte_find(unsigned long va, int psize)
{
unsigned long hash;
unsigned long i, j;
long slot;
- unsigned long hpte_v;
+ unsigned long want_v, hpte_v;
- hash = hpt_hash(vpn, 0);
+ hash = hpt_hash(va, mmu_psize_defs[psize].shift);
+ want_v = hpte_encode_v(va, psize);
for (j = 0; j < 2; j++) {
slot = (hash & htab_hash_mask) * HPTES_PER_GROUP;
for (i = 0; i < HPTES_PER_GROUP; i++) {
hpte_v = pSeries_lpar_hpte_getword0(slot);
- if ((HPTE_V_AVPN_VAL(hpte_v) == (vpn >> 11))
+ if (HPTE_V_COMPARE(hpte_v, want_v)
&& (hpte_v & HPTE_V_VALID)
&& (!!(hpte_v & HPTE_V_SECONDARY) == j)) {
/* HPTE matches */
@@ -444,17 +474,15 @@ static long pSeries_lpar_hpte_find(unsigned long vpn)
}
static void pSeries_lpar_hpte_updateboltedpp(unsigned long newpp,
- unsigned long ea)
+ unsigned long ea,
+ int psize)
{
- unsigned long lpar_rc;
- unsigned long vsid, va, vpn, flags;
- long slot;
+ unsigned long lpar_rc, slot, vsid, va, flags;
vsid = get_kernel_vsid(ea);
va = (vsid << 28) | (ea & 0x0fffffff);
- vpn = va >> PAGE_SHIFT;
- slot = pSeries_lpar_hpte_find(vpn);
+ slot = pSeries_lpar_hpte_find(va, psize);
BUG_ON(slot == -1);
flags = newpp & 7;
@@ -464,18 +492,18 @@ static void pSeries_lpar_hpte_updateboltedpp(unsigned long newpp,
}
static void pSeries_lpar_hpte_invalidate(unsigned long slot, unsigned long va,
- int large, int local)
+ int psize, int local)
{
- unsigned long avpn = va >> 23;
+ unsigned long want_v;
unsigned long lpar_rc;
unsigned long dummy1, dummy2;
- if (large)
- avpn &= ~0x1UL;
-
- lpar_rc = plpar_pte_remove(H_AVPN, slot, (avpn << 7), &dummy1,
- &dummy2);
+ DBG_LOW(" inval : slot=%lx, va=%016lx, psize: %d, local: %d",
+ slot, va, psize, local);
+ want_v = hpte_encode_v(va, psize);
+ lpar_rc = plpar_pte_remove(H_AVPN, slot, want_v & HPTE_V_AVPN,
+ &dummy1, &dummy2);
if (lpar_rc == H_Not_Found)
return;
@@ -486,8 +514,7 @@ static void pSeries_lpar_hpte_invalidate(unsigned long slot, unsigned long va,
* Take a spinlock around flushes to avoid bouncing the hypervisor tlbie
* lock.
*/
-void pSeries_lpar_flush_hash_range(unsigned long context, unsigned long number,
- int local)
+void pSeries_lpar_flush_hash_range(unsigned long number, int local)
{
int i;
unsigned long flags = 0;
@@ -498,7 +525,8 @@ void pSeries_lpar_flush_hash_range(unsigned long context, unsigned long number,
spin_lock_irqsave(&pSeries_lpar_tlbie_lock, flags);
for (i = 0; i < number; i++)
- flush_hash_page(context, batch->addr[i], batch->pte[i], local);
+ flush_hash_page(batch->vaddr[i], batch->pte[i],
+ batch->psize, local);
if (lock_tlbie)
spin_unlock_irqrestore(&pSeries_lpar_tlbie_lock, flags);
diff --git a/arch/ppc64/kernel/pSeries_nvram.c b/arch/powerpc/platforms/pseries/nvram.c
index 18abfb1f4e24..18abfb1f4e24 100644
--- a/arch/ppc64/kernel/pSeries_nvram.c
+++ b/arch/powerpc/platforms/pseries/nvram.c
diff --git a/arch/ppc64/kernel/pSeries_pci.c b/arch/powerpc/platforms/pseries/pci.c
index 928f8febdb3b..999a9620b5ce 100644
--- a/arch/ppc64/kernel/pSeries_pci.c
+++ b/arch/powerpc/platforms/pseries/pci.c
@@ -29,8 +29,7 @@
#include <asm/pci-bridge.h>
#include <asm/prom.h>
-
-#include "pci.h"
+#include <asm/ppc-pci.h>
static int __devinitdata s7a_workaround = -1;
@@ -108,7 +107,6 @@ static void __init pSeries_request_regions(void)
void __init pSeries_final_fixup(void)
{
- phbs_remap_io();
pSeries_request_regions();
pci_addr_cache_build();
@@ -124,7 +122,7 @@ static void fixup_winbond_82c105(struct pci_dev* dev)
int i;
unsigned int reg;
- if (!(systemcfg->platform & PLATFORM_PSERIES))
+ if (!platform_is_pseries())
return;
printk("Using INTC for W82c105 IDE controller.\n");
diff --git a/arch/powerpc/platforms/pseries/plpar_wrappers.h b/arch/powerpc/platforms/pseries/plpar_wrappers.h
new file mode 100644
index 000000000000..3bd1b3e06003
--- /dev/null
+++ b/arch/powerpc/platforms/pseries/plpar_wrappers.h
@@ -0,0 +1,110 @@
+#ifndef _PSERIES_PLPAR_WRAPPERS_H
+#define _PSERIES_PLPAR_WRAPPERS_H
+
+#include <asm/hvcall.h>
+
+static inline long poll_pending(void)
+{
+ unsigned long dummy;
+ return plpar_hcall(H_POLL_PENDING, 0, 0, 0, 0, &dummy, &dummy, &dummy);
+}
+
+static inline long prod_processor(void)
+{
+ plpar_hcall_norets(H_PROD);
+ return 0;
+}
+
+static inline long cede_processor(void)
+{
+ plpar_hcall_norets(H_CEDE);
+ return 0;
+}
+
+static inline long vpa_call(unsigned long flags, unsigned long cpu,
+ unsigned long vpa)
+{
+ /* flags are in bits 16-18 (counting from most significant bit) */
+ flags = flags << (63 - 18);
+
+ return plpar_hcall_norets(H_REGISTER_VPA, flags, cpu, vpa);
+}
+
+static inline long unregister_vpa(unsigned long cpu, unsigned long vpa)
+{
+ return vpa_call(0x5, cpu, vpa);
+}
+
+static inline long register_vpa(unsigned long cpu, unsigned long vpa)
+{
+ return vpa_call(0x1, cpu, vpa);
+}
+
+extern void vpa_init(int cpu);
+
+static inline long plpar_pte_remove(unsigned long flags, unsigned long ptex,
+ unsigned long avpn, unsigned long *old_pteh_ret,
+ unsigned long *old_ptel_ret)
+{
+ unsigned long dummy;
+ return plpar_hcall(H_REMOVE, flags, ptex, avpn, 0, old_pteh_ret,
+ old_ptel_ret, &dummy);
+}
+
+static inline long plpar_pte_read(unsigned long flags, unsigned long ptex,
+ unsigned long *old_pteh_ret, unsigned long *old_ptel_ret)
+{
+ unsigned long dummy;
+ return plpar_hcall(H_READ, flags, ptex, 0, 0, old_pteh_ret,
+ old_ptel_ret, &dummy);
+}
+
+static inline long plpar_pte_protect(unsigned long flags, unsigned long ptex,
+ unsigned long avpn)
+{
+ return plpar_hcall_norets(H_PROTECT, flags, ptex, avpn);
+}
+
+static inline long plpar_tce_get(unsigned long liobn, unsigned long ioba,
+ unsigned long *tce_ret)
+{
+ unsigned long dummy;
+ return plpar_hcall(H_GET_TCE, liobn, ioba, 0, 0, tce_ret, &dummy,
+ &dummy);
+}
+
+static inline long plpar_tce_put(unsigned long liobn, unsigned long ioba,
+ unsigned long tceval)
+{
+ return plpar_hcall_norets(H_PUT_TCE, liobn, ioba, tceval);
+}
+
+static inline long plpar_tce_put_indirect(unsigned long liobn,
+ unsigned long ioba, unsigned long page, unsigned long count)
+{
+ return plpar_hcall_norets(H_PUT_TCE_INDIRECT, liobn, ioba, page, count);
+}
+
+static inline long plpar_tce_stuff(unsigned long liobn, unsigned long ioba,
+ unsigned long tceval, unsigned long count)
+{
+ return plpar_hcall_norets(H_STUFF_TCE, liobn, ioba, tceval, count);
+}
+
+static inline long plpar_get_term_char(unsigned long termno,
+ unsigned long *len_ret, char *buf_ret)
+{
+ unsigned long *lbuf = (unsigned long *)buf_ret; /* TODO: alignment? */
+ return plpar_hcall(H_GET_TERM_CHAR, termno, 0, 0, 0, len_ret,
+ lbuf + 0, lbuf + 1);
+}
+
+static inline long plpar_put_term_char(unsigned long termno, unsigned long len,
+ const char *buffer)
+{
+ unsigned long *lbuf = (unsigned long *)buffer; /* TODO: alignment? */
+ return plpar_hcall_norets(H_PUT_TERM_CHAR, termno, len, lbuf[0],
+ lbuf[1]);
+}
+
+#endif /* _PSERIES_PLPAR_WRAPPERS_H */
diff --git a/arch/ppc64/kernel/ras.c b/arch/powerpc/platforms/pseries/ras.c
index 41b97dc9cc0a..fbd214d68b07 100644
--- a/arch/ppc64/kernel/ras.c
+++ b/arch/powerpc/platforms/pseries/ras.c
@@ -1,17 +1,16 @@
/*
- * ras.c
* Copyright (C) 2001 Dave Engebretsen IBM 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
@@ -19,7 +18,7 @@
/* Change Activity:
* 2001/09/21 : engebret : Created with minimal EPOW and HW exception support.
- * End Change Activity
+ * End Change Activity
*/
#include <linux/errno.h>
@@ -49,7 +48,7 @@
#include <asm/ptrace.h>
#include <asm/machdep.h>
#include <asm/rtas.h>
-#include <asm/ppcdebug.h>
+#include <asm/udbg.h>
static unsigned char ras_log_buf[RTAS_ERROR_LOG_MAX];
static DEFINE_SPINLOCK(ras_log_buf_lock);
@@ -323,7 +322,7 @@ static int recover_mce(struct pt_regs *regs, struct rtas_error_log * err)
nonfatal = 1;
}
- log_error((char *)err, ERR_TYPE_RTAS_LOG, !nonfatal);
+ log_error((char *)err, ERR_TYPE_RTAS_LOG, !nonfatal);
return nonfatal;
}
diff --git a/arch/ppc64/kernel/pSeries_reconfig.c b/arch/powerpc/platforms/pseries/reconfig.c
index 58c61219d08e..d8864164dbe8 100644
--- a/arch/ppc64/kernel/pSeries_reconfig.c
+++ b/arch/powerpc/platforms/pseries/reconfig.c
@@ -286,10 +286,8 @@ static struct property *new_property(const char *name, const int length,
return new;
cleanup:
- if (new->name)
- kfree(new->name);
- if (new->value)
- kfree(new->value);
+ kfree(new->name);
+ kfree(new->value);
kfree(new);
return NULL;
}
@@ -410,7 +408,7 @@ static int proc_ppc64_create_ofdt(void)
{
struct proc_dir_entry *ent;
- if (!(systemcfg->platform & PLATFORM_PSERIES))
+ if (!platform_is_pseries())
return 0;
ent = create_proc_entry("ppc64/ofdt", S_IWUSR, NULL);
diff --git a/arch/ppc64/kernel/rtasd.c b/arch/powerpc/platforms/pseries/rtasd.c
index e26b0420b6dd..00cf331a1dc4 100644
--- a/arch/ppc64/kernel/rtasd.c
+++ b/arch/powerpc/platforms/pseries/rtasd.c
@@ -482,10 +482,12 @@ static int __init rtas_init(void)
{
struct proc_dir_entry *entry;
- /* No RTAS, only warn if we are on a pSeries box */
+ if (!platform_is_pseries())
+ return 0;
+
+ /* No RTAS */
if (rtas_token("event-scan") == RTAS_UNKNOWN_SERVICE) {
- if (systemcfg->platform & PLATFORM_PSERIES)
- printk(KERN_INFO "rtasd: no event-scan on system\n");
+ printk(KERN_INFO "rtasd: no event-scan on system\n");
return 1;
}
diff --git a/arch/ppc64/kernel/scanlog.c b/arch/powerpc/platforms/pseries/scanlog.c
index 215bf8900304..2edc947f7c44 100644
--- a/arch/ppc64/kernel/scanlog.c
+++ b/arch/powerpc/platforms/pseries/scanlog.c
@@ -225,8 +225,7 @@ int __init scanlog_init(void)
void __exit scanlog_cleanup(void)
{
if (proc_ppc64_scan_log_dump) {
- if (proc_ppc64_scan_log_dump->data)
- kfree(proc_ppc64_scan_log_dump->data);
+ kfree(proc_ppc64_scan_log_dump->data);
remove_proc_entry("scan-log-dump", proc_ppc64_scan_log_dump->parent);
}
}
diff --git a/arch/ppc64/kernel/pSeries_setup.c b/arch/powerpc/platforms/pseries/setup.c
index 3009701eb90d..e94247c28d42 100644
--- a/arch/ppc64/kernel/pSeries_setup.c
+++ b/arch/powerpc/platforms/pseries/setup.c
@@ -1,5 +1,5 @@
/*
- * linux/arch/ppc/kernel/setup.c
+ * 64-bit pSeries and RS/6000 setup code.
*
* Copyright (C) 1995 Linus Torvalds
* Adapted from 'alpha' version by Gary Thomas
@@ -58,14 +58,16 @@
#include <asm/irq.h>
#include <asm/time.h>
#include <asm/nvram.h>
-#include <asm/plpar_wrappers.h>
-#include <asm/xics.h>
+#include "xics.h"
#include <asm/firmware.h>
#include <asm/pmc.h>
+#include <asm/mpic.h>
+#include <asm/ppc-pci.h>
+#include <asm/i8259.h>
+#include <asm/udbg.h>
+#include <asm/smp.h>
-#include "i8259.h"
-#include "mpic.h"
-#include "pci.h"
+#include "plpar_wrappers.h"
#ifdef DEBUG
#define DBG(fmt...) udbg_printf(fmt)
@@ -84,13 +86,12 @@ int fwnmi_active; /* TRUE if an FWNMI handler is present */
extern void pSeries_system_reset_exception(struct pt_regs *regs);
extern int pSeries_machine_check_exception(struct pt_regs *regs);
-static int pseries_shared_idle(void);
-static int pseries_dedicated_idle(void);
+static void pseries_shared_idle(void);
+static void pseries_dedicated_idle(void);
-static volatile void __iomem * chrp_int_ack_special;
struct mpic *pSeries_mpic;
-void pSeries_get_cpuinfo(struct seq_file *m)
+void pSeries_show_cpuinfo(struct seq_file *m)
{
struct device_node *root;
const char *model = "";
@@ -119,19 +120,11 @@ static void __init fwnmi_init(void)
fwnmi_active = 1;
}
-static int pSeries_irq_cascade(struct pt_regs *regs, void *data)
-{
- if (chrp_int_ack_special)
- return readb(chrp_int_ack_special);
- else
- return i8259_irq(smp_processor_id());
-}
-
static void __init pSeries_init_mpic(void)
{
unsigned int *addrp;
struct device_node *np;
- int i;
+ unsigned long intack = 0;
/* All ISUs are setup, complete initialization */
mpic_init(pSeries_mpic);
@@ -142,16 +135,14 @@ static void __init pSeries_init_mpic(void)
get_property(np, "8259-interrupt-acknowledge", NULL)))
printk(KERN_ERR "Cannot find pci to get ack address\n");
else
- chrp_int_ack_special = ioremap(addrp[prom_n_addr_cells(np)-1], 1);
+ intack = addrp[prom_n_addr_cells(np)-1];
of_node_put(np);
/* Setup the legacy interrupts & controller */
- for (i = 0; i < NUM_ISA_INTERRUPTS; i++)
- irq_desc[i].handler = &i8259_pic;
- i8259_init(0);
+ i8259_init(intack, 0);
/* Hook cascade to mpic */
- mpic_setup_cascade(NUM_ISA_INTERRUPTS, pSeries_irq_cascade, NULL);
+ mpic_setup_cascade(NUM_ISA_INTERRUPTS, i8259_irq_cascade, NULL);
}
static void __init pSeries_setup_mpic(void)
@@ -241,10 +232,6 @@ static void __init pSeries_setup_arch(void)
find_and_init_phbs();
eeh_init();
-#ifdef CONFIG_DUMMY_CONSOLE
- conswitchp = &dummy_con;
-#endif
-
pSeries_nvram_init();
/* Choose an idle loop */
@@ -262,7 +249,7 @@ static void __init pSeries_setup_arch(void)
ppc_md.idle_loop = default_idle;
}
- if (systemcfg->platform & PLATFORM_LPAR)
+ if (platform_is_lpar())
ppc_md.enable_pmcs = pseries_lpar_enable_pmcs;
else
ppc_md.enable_pmcs = power4_enable_pmcs;
@@ -365,6 +352,17 @@ static void pSeries_mach_cpu_die(void)
for(;;);
}
+static int pseries_set_dabr(unsigned long dabr)
+{
+ return plpar_hcall_norets(H_SET_DABR, dabr);
+}
+
+static int pseries_set_xdabr(unsigned long dabr)
+{
+ /* We want to catch accesses from kernel and userspace */
+ return plpar_hcall_norets(H_SET_XDABR, dabr,
+ H_DABRX_KERNEL | H_DABRX_USER);
+}
/*
* Early initialization. Relocation is on but do not reference unbolted pages
@@ -380,7 +378,7 @@ static void __init pSeries_init_early(void)
fw_feature_init();
- if (systemcfg->platform & PLATFORM_LPAR)
+ if (platform_is_lpar())
hpte_init_lpar();
else {
hpte_init_native();
@@ -390,7 +388,7 @@ static void __init pSeries_init_early(void)
generic_find_legacy_serial_ports(&physport, &default_speed);
- if (systemcfg->platform & PLATFORM_LPAR)
+ if (platform_is_lpar())
find_udbg_vterm();
else if (physport) {
/* Map the uart for udbg. */
@@ -400,6 +398,10 @@ static void __init pSeries_init_early(void)
DBG("Hello World !\n");
}
+ if (firmware_has_feature(FW_FEATURE_DABR))
+ ppc_md.set_dabr = pseries_set_dabr;
+ else if (firmware_has_feature(FW_FEATURE_XDABR))
+ ppc_md.set_dabr = pseries_set_xdabr;
iommu_init_early_pSeries();
@@ -467,6 +469,7 @@ static inline void dedicated_idle_sleep(unsigned int cpu)
* more.
*/
clear_thread_flag(TIF_POLLING_NRFLAG);
+ smp_mb__after_clear_bit();
/*
* SMT dynamic mode. Cede will result in this thread going
@@ -479,6 +482,7 @@ static inline void dedicated_idle_sleep(unsigned int cpu)
cede_processor();
else
local_irq_enable();
+ set_thread_flag(TIF_POLLING_NRFLAG);
} else {
/*
* Give the HV an opportunity at the processor, since we are
@@ -488,13 +492,13 @@ static inline void dedicated_idle_sleep(unsigned int cpu)
}
}
-static int pseries_dedicated_idle(void)
-{
- long oldval;
+static void pseries_dedicated_idle(void)
+{
struct paca_struct *lpaca = get_paca();
unsigned int cpu = smp_processor_id();
unsigned long start_snooze;
unsigned long *smt_snooze_delay = &__get_cpu_var(smt_snooze_delay);
+ set_thread_flag(TIF_POLLING_NRFLAG);
while (1) {
/*
@@ -503,10 +507,7 @@ static int pseries_dedicated_idle(void)
*/
lpaca->lppaca.idle = 1;
- oldval = test_and_clear_thread_flag(TIF_NEED_RESCHED);
- if (!oldval) {
- set_thread_flag(TIF_POLLING_NRFLAG);
-
+ if (!need_resched()) {
start_snooze = __get_tb() +
*smt_snooze_delay * tb_ticks_per_usec;
@@ -529,22 +530,21 @@ static int pseries_dedicated_idle(void)
}
HMT_medium();
- clear_thread_flag(TIF_POLLING_NRFLAG);
- } else {
- set_need_resched();
}
lpaca->lppaca.idle = 0;
ppc64_runlatch_on();
+ preempt_enable_no_resched();
schedule();
+ preempt_disable();
if (cpu_is_offline(cpu) && system_state == SYSTEM_RUNNING)
cpu_die();
}
}
-static int pseries_shared_idle(void)
+static void pseries_shared_idle(void)
{
struct paca_struct *lpaca = get_paca();
unsigned int cpu = smp_processor_id();
@@ -581,18 +581,18 @@ static int pseries_shared_idle(void)
lpaca->lppaca.idle = 0;
ppc64_runlatch_on();
+ preempt_enable_no_resched();
schedule();
+ preempt_disable();
if (cpu_is_offline(cpu) && system_state == SYSTEM_RUNNING)
cpu_die();
}
-
- return 0;
}
static int pSeries_pci_probe_mode(struct pci_bus *bus)
{
- if (systemcfg->platform & PLATFORM_LPAR)
+ if (platform_is_lpar())
return PCI_PROBE_DEVTREE;
return PCI_PROBE_NORMAL;
}
@@ -601,7 +601,7 @@ struct machdep_calls __initdata pSeries_md = {
.probe = pSeries_probe,
.setup_arch = pSeries_setup_arch,
.init_early = pSeries_init_early,
- .get_cpuinfo = pSeries_get_cpuinfo,
+ .show_cpuinfo = pSeries_show_cpuinfo,
.log_error = pSeries_log_error,
.pcibios_fixup = pSeries_final_fixup,
.pci_probe_mode = pSeries_pci_probe_mode,
diff --git a/arch/ppc64/kernel/pSeries_smp.c b/arch/powerpc/platforms/pseries/smp.c
index d2c7e2c4733b..3ba794ca3288 100644
--- a/arch/ppc64/kernel/pSeries_smp.c
+++ b/arch/powerpc/platforms/pseries/smp.c
@@ -1,5 +1,5 @@
/*
- * SMP support for pSeries and BPA machines.
+ * SMP support for pSeries machines.
*
* Dave Engebretsen, Peter Bergner, and
* Mike Corrigan {engebret|bergner|mikec}@us.ibm.com
@@ -39,16 +39,16 @@
#include <asm/paca.h>
#include <asm/time.h>
#include <asm/machdep.h>
-#include <asm/xics.h>
+#include "xics.h"
#include <asm/cputable.h>
#include <asm/firmware.h>
#include <asm/system.h>
#include <asm/rtas.h>
-#include <asm/plpar_wrappers.h>
#include <asm/pSeries_reconfig.h>
+#include <asm/mpic.h>
+#include <asm/systemcfg.h>
-#include "mpic.h"
-#include "bpa_iic.h"
+#include "plpar_wrappers.h"
#ifdef DEBUG
#define DBG(fmt...) udbg_printf(fmt)
@@ -97,7 +97,7 @@ int pSeries_cpu_disable(void)
int cpu = smp_processor_id();
cpu_clear(cpu, cpu_online_map);
- systemcfg->processorCount--;
+ _systemcfg->processorCount--;
/*fix boot_cpuid here*/
if (cpu == boot_cpuid)
@@ -343,36 +343,6 @@ static void __devinit smp_xics_setup_cpu(int cpu)
}
#endif /* CONFIG_XICS */
-#ifdef CONFIG_BPA_IIC
-static void smp_iic_message_pass(int target, int msg)
-{
- unsigned int i;
-
- if (target < NR_CPUS) {
- iic_cause_IPI(target, msg);
- } else {
- for_each_online_cpu(i) {
- if (target == MSG_ALL_BUT_SELF
- && i == smp_processor_id())
- continue;
- iic_cause_IPI(i, msg);
- }
- }
-}
-
-static int __init smp_iic_probe(void)
-{
- iic_request_IPIs();
-
- return cpus_weight(cpu_possible_map);
-}
-
-static void __devinit smp_iic_setup_cpu(int cpu)
-{
- if (cpu != boot_cpuid)
- iic_setup_cpu();
-}
-#endif /* CONFIG_BPA_IIC */
static DEFINE_SPINLOCK(timebase_lock);
static unsigned long timebase = 0;
@@ -444,15 +414,6 @@ static struct smp_ops_t pSeries_xics_smp_ops = {
.cpu_bootable = smp_pSeries_cpu_bootable,
};
#endif
-#ifdef CONFIG_BPA_IIC
-static struct smp_ops_t bpa_iic_smp_ops = {
- .message_pass = smp_iic_message_pass,
- .probe = smp_iic_probe,
- .kick_cpu = smp_pSeries_kick_cpu,
- .setup_cpu = smp_iic_setup_cpu,
- .cpu_bootable = smp_pSeries_cpu_bootable,
-};
-#endif
/* This is called very early */
void __init smp_init_pSeries(void)
@@ -472,11 +433,6 @@ void __init smp_init_pSeries(void)
smp_ops = &pSeries_xics_smp_ops;
break;
#endif
-#ifdef CONFIG_BPA_IIC
- case IC_BPA_IIC:
- smp_ops = &bpa_iic_smp_ops;
- break;
-#endif
default:
panic("Invalid interrupt controller");
}
@@ -486,7 +442,7 @@ void __init smp_init_pSeries(void)
smp_ops->cpu_die = pSeries_cpu_die;
/* Processors can be added/removed only on LPAR */
- if (systemcfg->platform == PLATFORM_PSERIES_LPAR)
+ if (platform_is_lpar())
pSeries_reconfig_notifier_register(&pSeries_smp_nb);
#endif
diff --git a/arch/ppc64/kernel/pSeries_vio.c b/arch/powerpc/platforms/pseries/vio.c
index e0ae06f58f86..866379b80c09 100644
--- a/arch/ppc64/kernel/pSeries_vio.c
+++ b/arch/powerpc/platforms/pseries/vio.c
@@ -22,6 +22,7 @@
#include <asm/prom.h>
#include <asm/vio.h>
#include <asm/hvcall.h>
+#include <asm/tce.h>
extern struct subsystem devices_subsys; /* needed for vio_find_name() */
diff --git a/arch/ppc64/kernel/xics.c b/arch/powerpc/platforms/pseries/xics.c
index daf93885dcfa..72ac18067ece 100644
--- a/arch/ppc64/kernel/xics.c
+++ b/arch/powerpc/platforms/pseries/xics.c
@@ -1,5 +1,5 @@
-/*
- * arch/ppc64/kernel/xics.c
+/*
+ * arch/powerpc/platforms/pseries/xics.c
*
* Copyright 2000 IBM Corporation.
*
@@ -25,11 +25,11 @@
#include <asm/pgtable.h>
#include <asm/smp.h>
#include <asm/rtas.h>
-#include <asm/xics.h>
#include <asm/hvcall.h>
#include <asm/machdep.h>
+#include <asm/i8259.h>
-#include "i8259.h"
+#include "xics.h"
static unsigned int xics_startup(unsigned int irq);
static void xics_enable_irq(unsigned int irq);
@@ -62,7 +62,7 @@ static struct radix_tree_root irq_map = RADIX_TREE_INIT(GFP_ATOMIC);
/* Want a priority other than 0. Various HW issues require this. */
#define DEFAULT_PRIORITY 5
-/*
+/*
* Mark IPIs as higher priority so we can take them inside interrupts that
* arent marked SA_INTERRUPT
*/
@@ -169,11 +169,11 @@ static inline long plpar_xirr(unsigned long *xirr_ret)
static int pSeriesLP_xirr_info_get(int n_cpu)
{
unsigned long lpar_rc;
- unsigned long return_value;
+ unsigned long return_value;
lpar_rc = plpar_xirr(&return_value);
if (lpar_rc != H_Success)
- panic(" bad return code xirr - rc = %lx \n", lpar_rc);
+ panic(" bad return code xirr - rc = %lx \n", lpar_rc);
return (int)return_value;
}
@@ -185,7 +185,7 @@ static void pSeriesLP_xirr_info_set(int n_cpu, int value)
lpar_rc = plpar_eoi(val64);
if (lpar_rc != H_Success)
panic("bad return code EOI - rc = %ld, value=%lx\n", lpar_rc,
- val64);
+ val64);
}
void pSeriesLP_cppr_info(int n_cpu, u8 value)
@@ -194,7 +194,7 @@ void pSeriesLP_cppr_info(int n_cpu, u8 value)
lpar_rc = plpar_cppr(value);
if (lpar_rc != H_Success)
- panic("bad return code cppr - rc = %lx\n", lpar_rc);
+ panic("bad return code cppr - rc = %lx\n", lpar_rc);
}
static void pSeriesLP_qirr_info(int n_cpu , u8 value)
@@ -203,7 +203,7 @@ static void pSeriesLP_qirr_info(int n_cpu , u8 value)
lpar_rc = plpar_ipi(get_hard_smp_processor_id(n_cpu), value);
if (lpar_rc != H_Success)
- panic("bad return code qirr - rc = %lx\n", lpar_rc);
+ panic("bad return code qirr - rc = %lx\n", lpar_rc);
}
xics_ops pSeriesLP_ops = {
@@ -366,7 +366,7 @@ int xics_get_irq(struct pt_regs *regs)
/* for sanity, this had better be < NR_IRQS - 16 */
if (vec == xics_irq_8259_cascade_real) {
- irq = i8259_irq(cpu);
+ irq = i8259_irq(regs);
if (irq == -1) {
/* Spurious cascaded interrupt. Still must ack xics */
xics_end_irq(irq_offset_up(xics_irq_8259_cascade));
@@ -462,7 +462,7 @@ void xics_init_IRQ(void)
struct xics_interrupt_node {
unsigned long addr;
unsigned long size;
- } intnodes[NR_CPUS];
+ } intnodes[NR_CPUS];
ppc64_boot_msg(0x20, "XICS Init");
@@ -487,7 +487,7 @@ nextnode:
ireg = (uint *)get_property(np, "reg", &ilen);
if (!ireg)
panic("xics_init_IRQ: can't find interrupt reg property");
-
+
while (ilen) {
intnodes[indx].addr = (unsigned long)*ireg++ << 32;
ilen -= sizeof(uint);
@@ -545,7 +545,9 @@ nextnode:
of_node_put(np);
}
- if (systemcfg->platform == PLATFORM_PSERIES) {
+ if (platform_is_lpar())
+ ops = &pSeriesLP_ops;
+ else {
#ifdef CONFIG_SMP
for_each_cpu(i) {
int hard_id;
@@ -555,18 +557,17 @@ nextnode:
continue;
hard_id = get_hard_smp_processor_id(i);
- xics_per_cpu[i] = ioremap(intnodes[hard_id].addr,
+ xics_per_cpu[i] = ioremap(intnodes[hard_id].addr,
intnodes[hard_id].size);
}
#else
xics_per_cpu[0] = ioremap(intr_base, intr_size);
#endif /* CONFIG_SMP */
- } else if (systemcfg->platform == PLATFORM_PSERIES_LPAR) {
- ops = &pSeriesLP_ops;
}
xics_8259_pic.enable = i8259_pic.enable;
xics_8259_pic.disable = i8259_pic.disable;
+ xics_8259_pic.end = i8259_pic.end;
for (i = 0; i < 16; ++i)
get_irq_desc(i)->handler = &xics_8259_pic;
for (; i < NR_IRQS; ++i)
@@ -589,7 +590,7 @@ static int __init xics_setup_i8259(void)
no_action, 0, "8259 cascade", NULL))
printk(KERN_ERR "xics_setup_i8259: couldn't get 8259 "
"cascade\n");
- i8259_init(0);
+ i8259_init(0, 0);
}
return 0;
}
diff --git a/include/asm-ppc64/xics.h b/arch/powerpc/platforms/pseries/xics.h
index 1092af55d707..e14c70868f1d 100644
--- a/include/asm-ppc64/xics.h
+++ b/arch/powerpc/platforms/pseries/xics.h
@@ -1,5 +1,5 @@
-/*
- * arch/ppc64/kernel/xics.h
+/*
+ * arch/powerpc/platforms/pseries/xics.h
*
* Copyright 2000 IBM Corporation.
*
@@ -9,8 +9,8 @@
* 2 of the License, or (at your option) any later version.
*/
-#ifndef _PPC64_KERNEL_XICS_H
-#define _PPC64_KERNEL_XICS_H
+#ifndef _POWERPC_KERNEL_XICS_H
+#define _POWERPC_KERNEL_XICS_H
#include <linux/cache.h>
@@ -31,4 +31,4 @@ struct xics_ipi_struct {
extern struct xics_ipi_struct xics_ipi_message[NR_CPUS] __cacheline_aligned;
-#endif /* _PPC64_KERNEL_XICS_H */
+#endif /* _POWERPC_KERNEL_XICS_H */
diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile
new file mode 100644
index 000000000000..6b7efcfc352a
--- /dev/null
+++ b/arch/powerpc/sysdev/Makefile
@@ -0,0 +1,8 @@
+obj-$(CONFIG_MPIC) += mpic.o
+obj-$(CONFIG_PPC_INDIRECT_PCI) += indirect_pci.o
+obj-$(CONFIG_PPC_I8259) += i8259.o
+obj-$(CONFIG_PPC_MPC106) += grackle.o
+obj-$(CONFIG_BOOKE) += dcr.o
+obj-$(CONFIG_40x) += dcr.o
+obj-$(CONFIG_U3_DART) += u3_iommu.o
+obj-$(CONFIG_MMIO_NVRAM) += mmio_nvram.o
diff --git a/arch/powerpc/sysdev/dart.h b/arch/powerpc/sysdev/dart.h
new file mode 100644
index 000000000000..ea8f0d9eed8a
--- /dev/null
+++ b/arch/powerpc/sysdev/dart.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2004 Olof Johansson <olof@austin.ibm.com>, IBM 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 _POWERPC_SYSDEV_DART_H
+#define _POWERPC_SYSDEV_DART_H
+
+
+/* physical base of DART registers */
+#define DART_BASE 0xf8033000UL
+
+/* Offset from base to control register */
+#define DARTCNTL 0
+/* Offset from base to exception register */
+#define DARTEXCP 0x10
+/* Offset from base to TLB tag registers */
+#define DARTTAG 0x1000
+
+
+/* Control Register fields */
+
+/* base address of table (pfn) */
+#define DARTCNTL_BASE_MASK 0xfffff
+#define DARTCNTL_BASE_SHIFT 12
+
+#define DARTCNTL_FLUSHTLB 0x400
+#define DARTCNTL_ENABLE 0x200
+
+/* size of table in pages */
+#define DARTCNTL_SIZE_MASK 0x1ff
+#define DARTCNTL_SIZE_SHIFT 0
+
+
+/* DART table fields */
+
+#define DARTMAP_VALID 0x80000000
+#define DARTMAP_RPNMASK 0x00ffffff
+
+
+#define DART_PAGE_SHIFT 12
+#define DART_PAGE_SIZE (1 << DART_PAGE_SHIFT)
+#define DART_PAGE_FACTOR (PAGE_SHIFT - DART_PAGE_SHIFT)
+
+
+#endif /* _POWERPC_SYSDEV_DART_H */
diff --git a/arch/ppc/syslib/dcr.S b/arch/powerpc/sysdev/dcr.S
index 895f10243a43..895f10243a43 100644
--- a/arch/ppc/syslib/dcr.S
+++ b/arch/powerpc/sysdev/dcr.S
diff --git a/arch/powerpc/sysdev/grackle.c b/arch/powerpc/sysdev/grackle.c
new file mode 100644
index 000000000000..b6ec793a23be
--- /dev/null
+++ b/arch/powerpc/sysdev/grackle.c
@@ -0,0 +1,64 @@
+/*
+ * Functions for setting up and using a MPC106 northbridge
+ * Extracted from arch/powerpc/platforms/powermac/pci.c.
+ *
+ * Copyright (C) 2003 Benjamin Herrenschmuidt (benh@kernel.crashing.org)
+ * Copyright (C) 1997 Paul Mackerras (paulus@samba.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/pci.h>
+#include <linux/init.h>
+
+#include <asm/io.h>
+#include <asm/prom.h>
+#include <asm/pci-bridge.h>
+#include <asm/grackle.h>
+
+#define GRACKLE_CFA(b, d, o) (0x80 | ((b) << 8) | ((d) << 16) \
+ | (((o) & ~3) << 24))
+
+#define GRACKLE_PICR1_STG 0x00000040
+#define GRACKLE_PICR1_LOOPSNOOP 0x00000010
+
+/* N.B. this is called before bridges is initialized, so we can't
+ use grackle_pcibios_{read,write}_config_dword. */
+static inline void grackle_set_stg(struct pci_controller* bp, int enable)
+{
+ unsigned int val;
+
+ out_be32(bp->cfg_addr, GRACKLE_CFA(0, 0, 0xa8));
+ val = in_le32(bp->cfg_data);
+ val = enable? (val | GRACKLE_PICR1_STG) :
+ (val & ~GRACKLE_PICR1_STG);
+ out_be32(bp->cfg_addr, GRACKLE_CFA(0, 0, 0xa8));
+ out_le32(bp->cfg_data, val);
+ (void)in_le32(bp->cfg_data);
+}
+
+static inline void grackle_set_loop_snoop(struct pci_controller *bp, int enable)
+{
+ unsigned int val;
+
+ out_be32(bp->cfg_addr, GRACKLE_CFA(0, 0, 0xa8));
+ val = in_le32(bp->cfg_data);
+ val = enable? (val | GRACKLE_PICR1_LOOPSNOOP) :
+ (val & ~GRACKLE_PICR1_LOOPSNOOP);
+ out_be32(bp->cfg_addr, GRACKLE_CFA(0, 0, 0xa8));
+ out_le32(bp->cfg_data, val);
+ (void)in_le32(bp->cfg_data);
+}
+
+void __init setup_grackle(struct pci_controller *hose)
+{
+ setup_indirect_pci(hose, 0xfec00000, 0xfee00000);
+ if (machine_is_compatible("AAPL,PowerBook1998"))
+ grackle_set_loop_snoop(hose, 1);
+#if 0 /* Disabled for now, HW problems ??? */
+ grackle_set_stg(hose, 1);
+#endif
+}
diff --git a/arch/ppc/syslib/i8259.c b/arch/powerpc/sysdev/i8259.c
index 5c7908c20e43..b7ac32fdd776 100644
--- a/arch/ppc/syslib/i8259.c
+++ b/arch/powerpc/sysdev/i8259.c
@@ -1,18 +1,26 @@
+/*
+ * i8259 interrupt controller driver.
+ *
+ * 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/init.h>
#include <linux/ioport.h>
#include <linux/interrupt.h>
#include <asm/io.h>
#include <asm/i8259.h>
-static volatile unsigned char *pci_intack; /* RO, gives us the irq vector */
+static volatile void __iomem *pci_intack; /* RO, gives us the irq vector */
-unsigned char cached_8259[2] = { 0xff, 0xff };
+static unsigned char cached_8259[2] = { 0xff, 0xff };
#define cached_A1 (cached_8259[0])
#define cached_21 (cached_8259[1])
static DEFINE_SPINLOCK(i8259_lock);
-int i8259_pic_irq_offset;
+static int i8259_pic_irq_offset;
/*
* Acknowledge the IRQ using either the PCI host bridge's interrupt
@@ -20,8 +28,7 @@ int i8259_pic_irq_offset;
* which is called. It should be noted that polling is broken on some
* IBM and Motorola PReP boxes so we must use the int-ack feature on them.
*/
-int
-i8259_irq(struct pt_regs *regs)
+int i8259_irq(struct pt_regs *regs)
{
int irq;
@@ -29,7 +36,7 @@ i8259_irq(struct pt_regs *regs)
/* Either int-ack or poll for the IRQ */
if (pci_intack)
- irq = *pci_intack;
+ irq = readb(pci_intack);
else {
/* Perform an interrupt acknowledge cycle on controller 1. */
outb(0x0C, 0x20); /* prepare for poll */
@@ -59,7 +66,12 @@ i8259_irq(struct pt_regs *regs)
}
spin_unlock(&i8259_lock);
- return irq;
+ return irq + i8259_pic_irq_offset;
+}
+
+int i8259_irq_cascade(struct pt_regs *regs, void *unused)
+{
+ return i8259_irq(regs);
}
static void i8259_mask_and_ack_irq(unsigned int irq_nr)
@@ -67,20 +79,18 @@ static void i8259_mask_and_ack_irq(unsigned int irq_nr)
unsigned long flags;
spin_lock_irqsave(&i8259_lock, flags);
- if ( irq_nr >= i8259_pic_irq_offset )
- irq_nr -= i8259_pic_irq_offset;
-
+ irq_nr -= i8259_pic_irq_offset;
if (irq_nr > 7) {
cached_A1 |= 1 << (irq_nr-8);
- inb(0xA1); /* DUMMY */
- outb(cached_A1,0xA1);
- outb(0x20,0xA0); /* Non-specific EOI */
- outb(0x20,0x20); /* Non-specific EOI to cascade */
+ inb(0xA1); /* DUMMY */
+ outb(cached_A1, 0xA1);
+ outb(0x20, 0xA0); /* Non-specific EOI */
+ outb(0x20, 0x20); /* Non-specific EOI to cascade */
} else {
cached_21 |= 1 << irq_nr;
- inb(0x21); /* DUMMY */
- outb(cached_21,0x21);
- outb(0x20,0x20); /* Non-specific EOI */
+ inb(0x21); /* DUMMY */
+ outb(cached_21, 0x21);
+ outb(0x20, 0x20); /* Non-specific EOI */
}
spin_unlock_irqrestore(&i8259_lock, flags);
}
@@ -96,9 +106,8 @@ static void i8259_mask_irq(unsigned int irq_nr)
unsigned long flags;
spin_lock_irqsave(&i8259_lock, flags);
- if ( irq_nr >= i8259_pic_irq_offset )
- irq_nr -= i8259_pic_irq_offset;
- if ( irq_nr < 8 )
+ irq_nr -= i8259_pic_irq_offset;
+ if (irq_nr < 8)
cached_21 |= 1 << irq_nr;
else
cached_A1 |= 1 << (irq_nr-8);
@@ -111,9 +120,8 @@ static void i8259_unmask_irq(unsigned int irq_nr)
unsigned long flags;
spin_lock_irqsave(&i8259_lock, flags);
- if ( irq_nr >= i8259_pic_irq_offset )
- irq_nr -= i8259_pic_irq_offset;
- if ( irq_nr < 8 )
+ irq_nr -= i8259_pic_irq_offset;
+ if (irq_nr < 8)
cached_21 &= ~(1 << irq_nr);
else
cached_A1 &= ~(1 << (irq_nr-8));
@@ -169,12 +177,14 @@ static struct irqaction i8259_irqaction = {
* intack_addr - PCI interrupt acknowledge (real) address which will return
* the active irq from the 8259
*/
-void __init
-i8259_init(long intack_addr)
+void __init i8259_init(unsigned long intack_addr, int offset)
{
unsigned long flags;
+ int i;
spin_lock_irqsave(&i8259_lock, flags);
+ i8259_pic_irq_offset = offset;
+
/* init master interrupt controller */
outb(0x11, 0x20); /* Start init sequence */
outb(0x00, 0x21); /* Vector base */
@@ -197,12 +207,16 @@ i8259_init(long intack_addr)
spin_unlock_irqrestore(&i8259_lock, flags);
+ for (i = 0; i < NUM_ISA_INTERRUPTS; ++i)
+ irq_desc[offset + i].handler = &i8259_pic;
+
/* reserve our resources */
- setup_irq( i8259_pic_irq_offset + 2, &i8259_irqaction);
+ setup_irq(offset + 2, &i8259_irqaction);
request_resource(&ioport_resource, &pic1_iores);
request_resource(&ioport_resource, &pic2_iores);
request_resource(&ioport_resource, &pic_edgectrl_iores);
if (intack_addr != 0)
pci_intack = ioremap(intack_addr, 1);
+
}
diff --git a/arch/ppc/syslib/indirect_pci.c b/arch/powerpc/sysdev/indirect_pci.c
index e71488469704..e71488469704 100644
--- a/arch/ppc/syslib/indirect_pci.c
+++ b/arch/powerpc/sysdev/indirect_pci.c
diff --git a/arch/ppc64/kernel/bpa_nvram.c b/arch/powerpc/sysdev/mmio_nvram.c
index 06a119cfceb5..74e0d31a3559 100644
--- a/arch/ppc64/kernel/bpa_nvram.c
+++ b/arch/powerpc/sysdev/mmio_nvram.c
@@ -1,5 +1,5 @@
/*
- * NVRAM for CPBW
+ * memory mapped NVRAM
*
* (C) Copyright IBM Corp. 2005
*
@@ -30,54 +30,54 @@
#include <asm/nvram.h>
#include <asm/prom.h>
-static void __iomem *bpa_nvram_start;
-static long bpa_nvram_len;
-static spinlock_t bpa_nvram_lock = SPIN_LOCK_UNLOCKED;
+static void __iomem *mmio_nvram_start;
+static long mmio_nvram_len;
+static spinlock_t mmio_nvram_lock = SPIN_LOCK_UNLOCKED;
-static ssize_t bpa_nvram_read(char *buf, size_t count, loff_t *index)
+static ssize_t mmio_nvram_read(char *buf, size_t count, loff_t *index)
{
unsigned long flags;
- if (*index >= bpa_nvram_len)
+ if (*index >= mmio_nvram_len)
return 0;
- if (*index + count > bpa_nvram_len)
- count = bpa_nvram_len - *index;
+ if (*index + count > mmio_nvram_len)
+ count = mmio_nvram_len - *index;
- spin_lock_irqsave(&bpa_nvram_lock, flags);
+ spin_lock_irqsave(&mmio_nvram_lock, flags);
- memcpy_fromio(buf, bpa_nvram_start + *index, count);
+ memcpy_fromio(buf, mmio_nvram_start + *index, count);
- spin_unlock_irqrestore(&bpa_nvram_lock, flags);
+ spin_unlock_irqrestore(&mmio_nvram_lock, flags);
*index += count;
return count;
}
-static ssize_t bpa_nvram_write(char *buf, size_t count, loff_t *index)
+static ssize_t mmio_nvram_write(char *buf, size_t count, loff_t *index)
{
unsigned long flags;
- if (*index >= bpa_nvram_len)
+ if (*index >= mmio_nvram_len)
return 0;
- if (*index + count > bpa_nvram_len)
- count = bpa_nvram_len - *index;
+ if (*index + count > mmio_nvram_len)
+ count = mmio_nvram_len - *index;
- spin_lock_irqsave(&bpa_nvram_lock, flags);
+ spin_lock_irqsave(&mmio_nvram_lock, flags);
- memcpy_toio(bpa_nvram_start + *index, buf, count);
+ memcpy_toio(mmio_nvram_start + *index, buf, count);
- spin_unlock_irqrestore(&bpa_nvram_lock, flags);
+ spin_unlock_irqrestore(&mmio_nvram_lock, flags);
*index += count;
return count;
}
-static ssize_t bpa_nvram_get_size(void)
+static ssize_t mmio_nvram_get_size(void)
{
- return bpa_nvram_len;
+ return mmio_nvram_len;
}
-int __init bpa_nvram_init(void)
+int __init mmio_nvram_init(void)
{
struct device_node *nvram_node;
unsigned long *buffer;
@@ -97,20 +97,20 @@ int __init bpa_nvram_init(void)
ret = -ENODEV;
nvram_addr = buffer[0];
- bpa_nvram_len = buffer[1];
- if ( (!bpa_nvram_len) || (!nvram_addr) )
+ mmio_nvram_len = buffer[1];
+ if ( (!mmio_nvram_len) || (!nvram_addr) )
goto out;
- bpa_nvram_start = ioremap(nvram_addr, bpa_nvram_len);
- if (!bpa_nvram_start)
+ mmio_nvram_start = ioremap(nvram_addr, mmio_nvram_len);
+ if (!mmio_nvram_start)
goto out;
- printk(KERN_INFO "BPA NVRAM, %luk mapped to %p\n",
- bpa_nvram_len >> 10, bpa_nvram_start);
+ printk(KERN_INFO "mmio NVRAM, %luk mapped to %p\n",
+ mmio_nvram_len >> 10, mmio_nvram_start);
- ppc_md.nvram_read = bpa_nvram_read;
- ppc_md.nvram_write = bpa_nvram_write;
- ppc_md.nvram_size = bpa_nvram_get_size;
+ ppc_md.nvram_read = mmio_nvram_read;
+ ppc_md.nvram_write = mmio_nvram_write;
+ ppc_md.nvram_size = mmio_nvram_get_size;
out:
of_node_put(nvram_node);
diff --git a/arch/ppc64/kernel/mpic.c b/arch/powerpc/sysdev/mpic.c
index 5f5bc73754d9..105f05341a41 100644
--- a/arch/ppc64/kernel/mpic.c
+++ b/arch/powerpc/sysdev/mpic.c
@@ -1,5 +1,5 @@
/*
- * arch/ppc64/kernel/mpic.c
+ * arch/powerpc/kernel/mpic.c
*
* Driver for interrupt controllers following the OpenPIC standard, the
* common implementation beeing IBM's MPIC. This driver also can deal
@@ -31,8 +31,8 @@
#include <asm/pgtable.h>
#include <asm/irq.h>
#include <asm/machdep.h>
-
-#include "mpic.h"
+#include <asm/mpic.h>
+#include <asm/smp.h>
#ifdef DEBUG
#define DBG(fmt...) printk(fmt)
@@ -44,6 +44,9 @@ static struct mpic *mpics;
static struct mpic *mpic_primary;
static DEFINE_SPINLOCK(mpic_lock);
+#ifdef CONFIG_PPC32 /* XXX for now */
+#define distribute_irqs CONFIG_IRQ_ALL_CPUS
+#endif
/*
* Register accessor functions
@@ -355,7 +358,7 @@ static void mpic_enable_irq(unsigned int irq)
struct mpic *mpic = mpic_from_irq(irq);
unsigned int src = irq - mpic->irq_offset;
- DBG("%s: enable_irq: %d (src %d)\n", mpic->name, irq, src);
+ DBG("%p: %s: enable_irq: %d (src %d)\n", mpic, mpic->name, irq, src);
mpic_irq_write(src, MPIC_IRQ_VECTOR_PRI,
mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) & ~MPIC_VECPRI_MASK);
@@ -480,6 +483,7 @@ struct mpic * __init mpic_alloc(unsigned long phys_addr,
if (mpic == NULL)
return NULL;
+
memset(mpic, 0, sizeof(struct mpic));
mpic->name = name;
@@ -506,7 +510,7 @@ struct mpic * __init mpic_alloc(unsigned long phys_addr,
mpic->senses_count = senses_count;
/* Map the global registers */
- mpic->gregs = ioremap(phys_addr + MPIC_GREG_BASE, 0x2000);
+ mpic->gregs = ioremap(phys_addr + MPIC_GREG_BASE, 0x1000);
mpic->tmregs = mpic->gregs + ((MPIC_TIMER_BASE - MPIC_GREG_BASE) >> 2);
BUG_ON(mpic->gregs == NULL);
@@ -644,7 +648,6 @@ void __init mpic_init(struct mpic *mpic)
continue;
irq_desc[mpic->ipi_offset+i].status |= IRQ_PER_CPU;
irq_desc[mpic->ipi_offset+i].handler = &mpic->hc_ipi;
-
#endif /* CONFIG_SMP */
}
@@ -700,7 +703,7 @@ void __init mpic_init(struct mpic *mpic)
/* init hw */
mpic_irq_write(i, MPIC_IRQ_VECTOR_PRI, vecpri);
mpic_irq_write(i, MPIC_IRQ_DESTINATION,
- 1 << get_hard_smp_processor_id(boot_cpuid));
+ 1 << hard_smp_processor_id());
/* init linux descriptors */
if (i < mpic->irq_count) {
@@ -792,6 +795,21 @@ void mpic_setup_this_cpu(void)
#endif /* CONFIG_SMP */
}
+int mpic_cpu_get_priority(void)
+{
+ struct mpic *mpic = mpic_primary;
+
+ return mpic_cpu_read(MPIC_CPU_CURRENT_TASK_PRI);
+}
+
+void mpic_cpu_set_priority(int prio)
+{
+ struct mpic *mpic = mpic_primary;
+
+ prio &= MPIC_CPU_TASKPRI_MASK;
+ mpic_cpu_write(MPIC_CPU_CURRENT_TASK_PRI, prio);
+}
+
/*
* XXX: someone who knows mpic should check this.
* do we need to eoi the ipi including for kexec cpu here (see xics comments)?
@@ -885,4 +903,25 @@ void mpic_request_ipis(void)
printk("IPIs requested... \n");
}
+
+void smp_mpic_message_pass(int target, int msg)
+{
+ /* make sure we're sending something that translates to an IPI */
+ if ((unsigned int)msg > 3) {
+ printk("SMP %d: smp_message_pass: unknown msg %d\n",
+ smp_processor_id(), msg);
+ return;
+ }
+ switch (target) {
+ case MSG_ALL:
+ mpic_send_ipi(msg, 0xffffffff);
+ break;
+ case MSG_ALL_BUT_SELF:
+ mpic_send_ipi(msg, 0xffffffff & ~(1 << smp_processor_id()));
+ break;
+ default:
+ mpic_send_ipi(msg, 1 << target);
+ break;
+ }
+}
#endif /* CONFIG_SMP */
diff --git a/arch/ppc64/kernel/u3_iommu.c b/arch/powerpc/sysdev/u3_iommu.c
index 41ea09cb9ac7..f32baf7f4693 100644
--- a/arch/ppc64/kernel/u3_iommu.c
+++ b/arch/powerpc/sysdev/u3_iommu.c
@@ -1,5 +1,5 @@
/*
- * arch/ppc64/kernel/u3_iommu.c
+ * arch/powerpc/sysdev/u3_iommu.c
*
* Copyright (C) 2004 Olof Johansson <olof@austin.ibm.com>, IBM Corporation
*
@@ -37,46 +37,18 @@
#include <linux/vmalloc.h>
#include <asm/io.h>
#include <asm/prom.h>
-#include <asm/ppcdebug.h>
#include <asm/iommu.h>
#include <asm/pci-bridge.h>
#include <asm/machdep.h>
#include <asm/abs_addr.h>
#include <asm/cacheflush.h>
#include <asm/lmb.h>
+#include <asm/ppc-pci.h>
-#include "pci.h"
+#include "dart.h"
extern int iommu_force_on;
-/* physical base of DART registers */
-#define DART_BASE 0xf8033000UL
-
-/* Offset from base to control register */
-#define DARTCNTL 0
-/* Offset from base to exception register */
-#define DARTEXCP 0x10
-/* Offset from base to TLB tag registers */
-#define DARTTAG 0x1000
-
-
-/* Control Register fields */
-
-/* base address of table (pfn) */
-#define DARTCNTL_BASE_MASK 0xfffff
-#define DARTCNTL_BASE_SHIFT 12
-
-#define DARTCNTL_FLUSHTLB 0x400
-#define DARTCNTL_ENABLE 0x200
-
-/* size of table in pages */
-#define DARTCNTL_SIZE_MASK 0x1ff
-#define DARTCNTL_SIZE_SHIFT 0
-
-/* DART table fields */
-#define DARTMAP_VALID 0x80000000
-#define DARTMAP_RPNMASK 0x00ffffff
-
/* Physical base address and size of the DART table */
unsigned long dart_tablebase; /* exported to htab_initialize */
static unsigned long dart_tablesize;
@@ -152,18 +124,21 @@ static void dart_build(struct iommu_table *tbl, long index,
DBG("dart: build at: %lx, %lx, addr: %x\n", index, npages, uaddr);
+ index <<= DART_PAGE_FACTOR;
+ npages <<= DART_PAGE_FACTOR;
+
dp = ((unsigned int*)tbl->it_base) + index;
/* On U3, all memory is contigous, so we can move this
* out of the loop.
*/
while (npages--) {
- rpn = virt_to_abs(uaddr) >> PAGE_SHIFT;
+ rpn = virt_to_abs(uaddr) >> DART_PAGE_SHIFT;
*(dp++) = DARTMAP_VALID | (rpn & DARTMAP_RPNMASK);
rpn++;
- uaddr += PAGE_SIZE;
+ uaddr += DART_PAGE_SIZE;
}
dart_dirty = 1;
@@ -181,6 +156,9 @@ static void dart_free(struct iommu_table *tbl, long index, long npages)
DBG("dart: free at: %lx, %lx\n", index, npages);
+ index <<= DART_PAGE_FACTOR;
+ npages <<= DART_PAGE_FACTOR;
+
dp = ((unsigned int *)tbl->it_base) + index;
while (npages--)
@@ -209,10 +187,10 @@ static int dart_init(struct device_node *dart_node)
* that to work around what looks like a problem with the HT bridge
* prefetching into invalid pages and corrupting data
*/
- tmp = lmb_alloc(PAGE_SIZE, PAGE_SIZE);
+ tmp = lmb_alloc(DART_PAGE_SIZE, DART_PAGE_SIZE);
if (!tmp)
panic("U3-DART: Cannot allocate spare page!");
- dart_emptyval = DARTMAP_VALID | ((tmp >> PAGE_SHIFT) & DARTMAP_RPNMASK);
+ dart_emptyval = DARTMAP_VALID | ((tmp >> DART_PAGE_SHIFT) & DARTMAP_RPNMASK);
/* Map in DART registers. FIXME: Use device node to get base address */
dart = ioremap(DART_BASE, 0x7000);
@@ -223,8 +201,8 @@ static int dart_init(struct device_node *dart_node)
* table size and enable bit
*/
regword = DARTCNTL_ENABLE |
- ((dart_tablebase >> PAGE_SHIFT) << DARTCNTL_BASE_SHIFT) |
- (((dart_tablesize >> PAGE_SHIFT) & DARTCNTL_SIZE_MASK)
+ ((dart_tablebase >> DART_PAGE_SHIFT) << DARTCNTL_BASE_SHIFT) |
+ (((dart_tablesize >> DART_PAGE_SHIFT) & DARTCNTL_SIZE_MASK)
<< DARTCNTL_SIZE_SHIFT);
dart_vbase = ioremap(virt_to_abs(dart_tablebase), dart_tablesize);
@@ -248,7 +226,7 @@ static void iommu_table_u3_setup(void)
iommu_table_u3.it_busno = 0;
iommu_table_u3.it_offset = 0;
/* it_size is in number of entries */
- iommu_table_u3.it_size = dart_tablesize / sizeof(u32);
+ iommu_table_u3.it_size = (dart_tablesize / sizeof(u32)) >> DART_PAGE_FACTOR;
/* Initialize the common IOMMU code */
iommu_table_u3.it_base = (unsigned long)dart_vbase;
diff --git a/arch/powerpc/xmon/Makefile b/arch/powerpc/xmon/Makefile
new file mode 100644
index 000000000000..b20312e5ed27
--- /dev/null
+++ b/arch/powerpc/xmon/Makefile
@@ -0,0 +1,11 @@
+# Makefile for xmon
+
+ifdef CONFIG_PPC64
+EXTRA_CFLAGS += -mno-minimal-toc
+endif
+
+obj-$(CONFIG_8xx) += start_8xx.o
+obj-$(CONFIG_6xx) += start_32.o
+obj-$(CONFIG_4xx) += start_32.o
+obj-$(CONFIG_PPC64) += start_64.o
+obj-y += xmon.o ppc-dis.o ppc-opc.o setjmp.o nonstdio.o
diff --git a/arch/ppc64/xmon/ansidecl.h b/arch/powerpc/xmon/ansidecl.h
index c9b9f0929e9e..c9b9f0929e9e 100644
--- a/arch/ppc64/xmon/ansidecl.h
+++ b/arch/powerpc/xmon/ansidecl.h
diff --git a/arch/powerpc/xmon/nonstdio.c b/arch/powerpc/xmon/nonstdio.c
new file mode 100644
index 000000000000..78765833f4c0
--- /dev/null
+++ b/arch/powerpc/xmon/nonstdio.c
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 1996-2005 Paul Mackerras.
+ *
+ * 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/string.h>
+#include <asm/time.h>
+#include "nonstdio.h"
+
+int xmon_putchar(int c)
+{
+ char ch = c;
+
+ if (c == '\n')
+ xmon_putchar('\r');
+ return xmon_write(&ch, 1) == 1? c: -1;
+}
+
+static char line[256];
+static char *lineptr;
+static int lineleft;
+
+int xmon_expect(const char *str, unsigned long timeout)
+{
+ int c;
+ unsigned long t0;
+
+ /* assume 25MHz default timebase if tb_ticks_per_sec not set yet */
+ timeout *= tb_ticks_per_sec? tb_ticks_per_sec: 25000000;
+ t0 = get_tbl();
+ do {
+ lineptr = line;
+ for (;;) {
+ c = xmon_read_poll();
+ if (c == -1) {
+ if (get_tbl() - t0 > timeout)
+ return 0;
+ continue;
+ }
+ if (c == '\n')
+ break;
+ if (c != '\r' && lineptr < &line[sizeof(line) - 1])
+ *lineptr++ = c;
+ }
+ *lineptr = 0;
+ } while (strstr(line, str) == NULL);
+ return 1;
+}
+
+int xmon_getchar(void)
+{
+ int c;
+
+ if (lineleft == 0) {
+ lineptr = line;
+ for (;;) {
+ c = xmon_readchar();
+ if (c == -1 || c == 4)
+ break;
+ if (c == '\r' || c == '\n') {
+ *lineptr++ = '\n';
+ xmon_putchar('\n');
+ break;
+ }
+ switch (c) {
+ case 0177:
+ case '\b':
+ if (lineptr > line) {
+ xmon_putchar('\b');
+ xmon_putchar(' ');
+ xmon_putchar('\b');
+ --lineptr;
+ }
+ break;
+ case 'U' & 0x1F:
+ while (lineptr > line) {
+ xmon_putchar('\b');
+ xmon_putchar(' ');
+ xmon_putchar('\b');
+ --lineptr;
+ }
+ break;
+ default:
+ if (lineptr >= &line[sizeof(line) - 1])
+ xmon_putchar('\a');
+ else {
+ xmon_putchar(c);
+ *lineptr++ = c;
+ }
+ }
+ }
+ lineleft = lineptr - line;
+ lineptr = line;
+ }
+ if (lineleft == 0)
+ return -1;
+ --lineleft;
+ return *lineptr++;
+}
+
+char *xmon_gets(char *str, int nb)
+{
+ char *p;
+ int c;
+
+ for (p = str; p < str + nb - 1; ) {
+ c = xmon_getchar();
+ if (c == -1) {
+ if (p == str)
+ return NULL;
+ break;
+ }
+ *p++ = c;
+ if (c == '\n')
+ break;
+ }
+ *p = 0;
+ return str;
+}
+
+void xmon_printf(const char *format, ...)
+{
+ va_list args;
+ int n;
+ static char xmon_outbuf[1024];
+
+ va_start(args, format);
+ n = vsnprintf(xmon_outbuf, sizeof(xmon_outbuf), format, args);
+ va_end(args);
+ xmon_write(xmon_outbuf, n);
+}
diff --git a/arch/powerpc/xmon/nonstdio.h b/arch/powerpc/xmon/nonstdio.h
new file mode 100644
index 000000000000..47cebbd2b1b1
--- /dev/null
+++ b/arch/powerpc/xmon/nonstdio.h
@@ -0,0 +1,14 @@
+#define EOF (-1)
+
+#define printf xmon_printf
+#define putchar xmon_putchar
+
+extern int xmon_putchar(int c);
+extern int xmon_getchar(void);
+extern char *xmon_gets(char *, int);
+extern void xmon_printf(const char *, ...);
+extern void xmon_map_scc(void);
+extern int xmon_expect(const char *str, unsigned long timeout);
+extern int xmon_write(void *ptr, int nb);
+extern int xmon_readchar(void);
+extern int xmon_read_poll(void);
diff --git a/arch/ppc64/xmon/ppc-dis.c b/arch/powerpc/xmon/ppc-dis.c
index ac0a9d2427e0..ac0a9d2427e0 100644
--- a/arch/ppc64/xmon/ppc-dis.c
+++ b/arch/powerpc/xmon/ppc-dis.c
diff --git a/arch/ppc64/xmon/ppc-opc.c b/arch/powerpc/xmon/ppc-opc.c
index 5ee8fc32f824..5ee8fc32f824 100644
--- a/arch/ppc64/xmon/ppc-opc.c
+++ b/arch/powerpc/xmon/ppc-opc.c
diff --git a/arch/ppc64/xmon/ppc.h b/arch/powerpc/xmon/ppc.h
index 342237e8dd69..342237e8dd69 100644
--- a/arch/ppc64/xmon/ppc.h
+++ b/arch/powerpc/xmon/ppc.h
diff --git a/arch/powerpc/xmon/setjmp.S b/arch/powerpc/xmon/setjmp.S
new file mode 100644
index 000000000000..96a91f10e2ec
--- /dev/null
+++ b/arch/powerpc/xmon/setjmp.S
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 1996 Paul Mackerras.
+ *
+ * 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.
+ *
+ * NOTE: assert(sizeof(buf) > 23 * sizeof(long))
+ */
+#include <asm/processor.h>
+#include <asm/ppc_asm.h>
+#include <asm/asm-offsets.h>
+
+_GLOBAL(xmon_setjmp)
+ mflr r0
+ PPC_STL r0,0(r3)
+ PPC_STL r1,SZL(r3)
+ PPC_STL r2,2*SZL(r3)
+ mfcr r0
+ PPC_STL r0,3*SZL(r3)
+ PPC_STL r13,4*SZL(r3)
+ PPC_STL r14,5*SZL(r3)
+ PPC_STL r15,6*SZL(r3)
+ PPC_STL r16,7*SZL(r3)
+ PPC_STL r17,8*SZL(r3)
+ PPC_STL r18,9*SZL(r3)
+ PPC_STL r19,10*SZL(r3)
+ PPC_STL r20,11*SZL(r3)
+ PPC_STL r21,12*SZL(r3)
+ PPC_STL r22,13*SZL(r3)
+ PPC_STL r23,14*SZL(r3)
+ PPC_STL r24,15*SZL(r3)
+ PPC_STL r25,16*SZL(r3)
+ PPC_STL r26,17*SZL(r3)
+ PPC_STL r27,18*SZL(r3)
+ PPC_STL r28,19*SZL(r3)
+ PPC_STL r29,20*SZL(r3)
+ PPC_STL r30,21*SZL(r3)
+ PPC_STL r31,22*SZL(r3)
+ li r3,0
+ blr
+
+_GLOBAL(xmon_longjmp)
+ PPC_LCMPI r4,0
+ bne 1f
+ li r4,1
+1: PPC_LL r13,4*SZL(r3)
+ PPC_LL r14,5*SZL(r3)
+ PPC_LL r15,6*SZL(r3)
+ PPC_LL r16,7*SZL(r3)
+ PPC_LL r17,8*SZL(r3)
+ PPC_LL r18,9*SZL(r3)
+ PPC_LL r19,10*SZL(r3)
+ PPC_LL r20,11*SZL(r3)
+ PPC_LL r21,12*SZL(r3)
+ PPC_LL r22,13*SZL(r3)
+ PPC_LL r23,14*SZL(r3)
+ PPC_LL r24,15*SZL(r3)
+ PPC_LL r25,16*SZL(r3)
+ PPC_LL r26,17*SZL(r3)
+ PPC_LL r27,18*SZL(r3)
+ PPC_LL r28,19*SZL(r3)
+ PPC_LL r29,20*SZL(r3)
+ PPC_LL r30,21*SZL(r3)
+ PPC_LL r31,22*SZL(r3)
+ PPC_LL r0,3*SZL(r3)
+ mtcrf 0x38,r0
+ PPC_LL r0,0(r3)
+ PPC_LL r1,SZL(r3)
+ PPC_LL r2,2*SZL(r3)
+ mtlr r0
+ mr r3,r4
+ blr
+
+/*
+ * Grab the register values as they are now.
+ * This won't do a particularily good job because we really
+ * want our caller's caller's registers, and our caller has
+ * already executed its prologue.
+ * ToDo: We could reach back into the caller's save area to do
+ * a better job of representing the caller's state (note that
+ * that will be different for 32-bit and 64-bit, because of the
+ * different ABIs, though).
+ */
+_GLOBAL(xmon_save_regs)
+ PPC_STL r0,0*SZL(r3)
+ PPC_STL r2,2*SZL(r3)
+ PPC_STL r3,3*SZL(r3)
+ PPC_STL r4,4*SZL(r3)
+ PPC_STL r5,5*SZL(r3)
+ PPC_STL r6,6*SZL(r3)
+ PPC_STL r7,7*SZL(r3)
+ PPC_STL r8,8*SZL(r3)
+ PPC_STL r9,9*SZL(r3)
+ PPC_STL r10,10*SZL(r3)
+ PPC_STL r11,11*SZL(r3)
+ PPC_STL r12,12*SZL(r3)
+ PPC_STL r13,13*SZL(r3)
+ PPC_STL r14,14*SZL(r3)
+ PPC_STL r15,15*SZL(r3)
+ PPC_STL r16,16*SZL(r3)
+ PPC_STL r17,17*SZL(r3)
+ PPC_STL r18,18*SZL(r3)
+ PPC_STL r19,19*SZL(r3)
+ PPC_STL r20,20*SZL(r3)
+ PPC_STL r21,21*SZL(r3)
+ PPC_STL r22,22*SZL(r3)
+ PPC_STL r23,23*SZL(r3)
+ PPC_STL r24,24*SZL(r3)
+ PPC_STL r25,25*SZL(r3)
+ PPC_STL r26,26*SZL(r3)
+ PPC_STL r27,27*SZL(r3)
+ PPC_STL r28,28*SZL(r3)
+ PPC_STL r29,29*SZL(r3)
+ PPC_STL r30,30*SZL(r3)
+ PPC_STL r31,31*SZL(r3)
+ /* go up one stack frame for SP */
+ PPC_LL r4,0(r1)
+ PPC_STL r4,1*SZL(r3)
+ /* get caller's LR */
+ PPC_LL r0,LRSAVE(r4)
+ PPC_STL r0,_NIP-STACK_FRAME_OVERHEAD(r3)
+ PPC_STL r0,_LINK-STACK_FRAME_OVERHEAD(r3)
+ mfmsr r0
+ PPC_STL r0,_MSR-STACK_FRAME_OVERHEAD(r3)
+ mfctr r0
+ PPC_STL r0,_CTR-STACK_FRAME_OVERHEAD(r3)
+ mfxer r0
+ PPC_STL r0,_XER-STACK_FRAME_OVERHEAD(r3)
+ mfcr r0
+ PPC_STL r0,_CCR-STACK_FRAME_OVERHEAD(r3)
+ li r0,0
+ PPC_STL r0,_TRAP-STACK_FRAME_OVERHEAD(r3)
+ blr
diff --git a/arch/powerpc/xmon/start_32.c b/arch/powerpc/xmon/start_32.c
new file mode 100644
index 000000000000..c2464df4217e
--- /dev/null
+++ b/arch/powerpc/xmon/start_32.c
@@ -0,0 +1,441 @@
+/*
+ * Copyright (C) 1996 Paul Mackerras.
+ */
+#include <linux/config.h>
+#include <linux/string.h>
+#include <asm/machdep.h>
+#include <asm/io.h>
+#include <asm/page.h>
+#include <linux/adb.h>
+#include <linux/pmu.h>
+#include <linux/cuda.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/bitops.h>
+#include <asm/xmon.h>
+#include <asm/prom.h>
+#include <asm/bootx.h>
+#include <asm/machdep.h>
+#include <asm/errno.h>
+#include <asm/pmac_feature.h>
+#include <asm/processor.h>
+#include <asm/delay.h>
+#include <asm/btext.h>
+#include <asm/time.h>
+#include "nonstdio.h"
+
+static volatile unsigned char __iomem *sccc, *sccd;
+unsigned int TXRDY, RXRDY, DLAB;
+
+static int use_serial;
+static int use_screen;
+static int via_modem;
+static int xmon_use_sccb;
+static struct device_node *channel_node;
+
+void buf_access(void)
+{
+ if (DLAB)
+ sccd[3] &= ~DLAB; /* reset DLAB */
+}
+
+extern int adb_init(void);
+
+#ifdef CONFIG_PPC_CHRP
+/*
+ * This looks in the "ranges" property for the primary PCI host bridge
+ * to find the physical address of the start of PCI/ISA I/O space.
+ * It is basically a cut-down version of pci_process_bridge_OF_ranges.
+ */
+static unsigned long chrp_find_phys_io_base(void)
+{
+ struct device_node *node;
+ unsigned int *ranges;
+ unsigned long base = CHRP_ISA_IO_BASE;
+ int rlen = 0;
+ int np;
+
+ node = find_devices("isa");
+ if (node != NULL) {
+ node = node->parent;
+ if (node == NULL || node->type == NULL
+ || strcmp(node->type, "pci") != 0)
+ node = NULL;
+ }
+ if (node == NULL)
+ node = find_devices("pci");
+ if (node == NULL)
+ return base;
+
+ ranges = (unsigned int *) get_property(node, "ranges", &rlen);
+ np = prom_n_addr_cells(node) + 5;
+ while ((rlen -= np * sizeof(unsigned int)) >= 0) {
+ if ((ranges[0] >> 24) == 1 && ranges[2] == 0) {
+ /* I/O space starting at 0, grab the phys base */
+ base = ranges[np - 3];
+ break;
+ }
+ ranges += np;
+ }
+ return base;
+}
+#endif /* CONFIG_PPC_CHRP */
+
+void xmon_map_scc(void)
+{
+#ifdef CONFIG_PPC_MULTIPLATFORM
+ volatile unsigned char __iomem *base;
+
+ if (_machine == _MACH_Pmac) {
+ struct device_node *np;
+ unsigned long addr;
+#ifdef CONFIG_BOOTX_TEXT
+ if (!use_screen && !use_serial
+ && !machine_is_compatible("iMac")) {
+ /* see if there is a keyboard in the device tree
+ with a parent of type "adb" */
+ for (np = find_devices("keyboard"); np; np = np->next)
+ if (np->parent && np->parent->type
+ && strcmp(np->parent->type, "adb") == 0)
+ break;
+
+ /* needs to be hacked if xmon_printk is to be used
+ from within find_via_pmu() */
+#ifdef CONFIG_ADB_PMU
+ if (np != NULL && boot_text_mapped && find_via_pmu())
+ use_screen = 1;
+#endif
+#ifdef CONFIG_ADB_CUDA
+ if (np != NULL && boot_text_mapped && find_via_cuda())
+ use_screen = 1;
+#endif
+ }
+ if (!use_screen && (np = find_devices("escc")) != NULL) {
+ /*
+ * look for the device node for the serial port
+ * we're using and see if it says it has a modem
+ */
+ char *name = xmon_use_sccb? "ch-b": "ch-a";
+ char *slots;
+ int l;
+
+ np = np->child;
+ while (np != NULL && strcmp(np->name, name) != 0)
+ np = np->sibling;
+ if (np != NULL) {
+ /* XXX should parse this properly */
+ channel_node = np;
+ slots = get_property(np, "slot-names", &l);
+ if (slots != NULL && l >= 10
+ && strcmp(slots+4, "Modem") == 0)
+ via_modem = 1;
+ }
+ }
+ btext_drawstring("xmon uses ");
+ if (use_screen)
+ btext_drawstring("screen and keyboard\n");
+ else {
+ if (via_modem)
+ btext_drawstring("modem on ");
+ btext_drawstring(xmon_use_sccb? "printer": "modem");
+ btext_drawstring(" port\n");
+ }
+
+#endif /* CONFIG_BOOTX_TEXT */
+
+#ifdef CHRP_ESCC
+ addr = 0xc1013020;
+#else
+ addr = 0xf3013020;
+#endif
+ TXRDY = 4;
+ RXRDY = 1;
+
+ np = find_devices("mac-io");
+ if (np && np->n_addrs)
+ addr = np->addrs[0].address + 0x13020;
+ base = (volatile unsigned char *) ioremap(addr & PAGE_MASK, PAGE_SIZE);
+ sccc = base + (addr & ~PAGE_MASK);
+ sccd = sccc + 0x10;
+
+ } else {
+ base = (volatile unsigned char *) isa_io_base;
+
+#ifdef CONFIG_PPC_CHRP
+ if (_machine == _MACH_chrp)
+ base = (volatile unsigned char __iomem *)
+ ioremap(chrp_find_phys_io_base(), 0x1000);
+#endif
+
+ sccc = base + 0x3fd;
+ sccd = base + 0x3f8;
+ if (xmon_use_sccb) {
+ sccc -= 0x100;
+ sccd -= 0x100;
+ }
+ TXRDY = 0x20;
+ RXRDY = 1;
+ DLAB = 0x80;
+ }
+#elif defined(CONFIG_GEMINI)
+ /* should already be mapped by the kernel boot */
+ sccc = (volatile unsigned char __iomem *) 0xffeffb0d;
+ sccd = (volatile unsigned char __iomem *) 0xffeffb08;
+ TXRDY = 0x20;
+ RXRDY = 1;
+ DLAB = 0x80;
+#elif defined(CONFIG_405GP)
+ sccc = (volatile unsigned char __iomem *)0xef600305;
+ sccd = (volatile unsigned char __iomem *)0xef600300;
+ TXRDY = 0x20;
+ RXRDY = 1;
+ DLAB = 0x80;
+#endif /* platform */
+}
+
+static int scc_initialized = 0;
+
+void xmon_init_scc(void);
+extern void cuda_poll(void);
+
+static inline void do_poll_adb(void)
+{
+#ifdef CONFIG_ADB_PMU
+ if (sys_ctrler == SYS_CTRLER_PMU)
+ pmu_poll_adb();
+#endif /* CONFIG_ADB_PMU */
+#ifdef CONFIG_ADB_CUDA
+ if (sys_ctrler == SYS_CTRLER_CUDA)
+ cuda_poll();
+#endif /* CONFIG_ADB_CUDA */
+}
+
+int xmon_write(void *ptr, int nb)
+{
+ char *p = ptr;
+ int i, c, ct;
+
+#ifdef CONFIG_SMP
+ static unsigned long xmon_write_lock;
+ int lock_wait = 1000000;
+ int locked;
+
+ while ((locked = test_and_set_bit(0, &xmon_write_lock)) != 0)
+ if (--lock_wait == 0)
+ break;
+#endif
+
+#ifdef CONFIG_BOOTX_TEXT
+ if (use_screen) {
+ /* write it on the screen */
+ for (i = 0; i < nb; ++i)
+ btext_drawchar(*p++);
+ goto out;
+ }
+#endif
+ if (!scc_initialized)
+ xmon_init_scc();
+ ct = 0;
+ for (i = 0; i < nb; ++i) {
+ while ((*sccc & TXRDY) == 0)
+ do_poll_adb();
+ c = p[i];
+ if (c == '\n' && !ct) {
+ c = '\r';
+ ct = 1;
+ --i;
+ } else {
+ ct = 0;
+ }
+ buf_access();
+ *sccd = c;
+ eieio();
+ }
+
+ out:
+#ifdef CONFIG_SMP
+ if (!locked)
+ clear_bit(0, &xmon_write_lock);
+#endif
+ return nb;
+}
+
+int xmon_wants_key;
+int xmon_adb_keycode;
+
+#ifdef CONFIG_BOOTX_TEXT
+static int xmon_adb_shiftstate;
+
+static unsigned char xmon_keytab[128] =
+ "asdfhgzxcv\000bqwer" /* 0x00 - 0x0f */
+ "yt123465=97-80]o" /* 0x10 - 0x1f */
+ "u[ip\rlj'k;\\,/nm." /* 0x20 - 0x2f */
+ "\t `\177\0\033\0\0\0\0\0\0\0\0\0\0" /* 0x30 - 0x3f */
+ "\0.\0*\0+\0\0\0\0\0/\r\0-\0" /* 0x40 - 0x4f */
+ "\0\0000123456789\0\0\0"; /* 0x50 - 0x5f */
+
+static unsigned char xmon_shift_keytab[128] =
+ "ASDFHGZXCV\000BQWER" /* 0x00 - 0x0f */
+ "YT!@#$^%+(&_*)}O" /* 0x10 - 0x1f */
+ "U{IP\rLJ\"K:|<?NM>" /* 0x20 - 0x2f */
+ "\t ~\177\0\033\0\0\0\0\0\0\0\0\0\0" /* 0x30 - 0x3f */
+ "\0.\0*\0+\0\0\0\0\0/\r\0-\0" /* 0x40 - 0x4f */
+ "\0\0000123456789\0\0\0"; /* 0x50 - 0x5f */
+
+static int xmon_get_adb_key(void)
+{
+ int k, t, on;
+
+ xmon_wants_key = 1;
+ for (;;) {
+ xmon_adb_keycode = -1;
+ t = 0;
+ on = 0;
+ do {
+ if (--t < 0) {
+ on = 1 - on;
+ btext_drawchar(on? 0xdb: 0x20);
+ btext_drawchar('\b');
+ t = 200000;
+ }
+ do_poll_adb();
+ } while (xmon_adb_keycode == -1);
+ k = xmon_adb_keycode;
+ if (on)
+ btext_drawstring(" \b");
+
+ /* test for shift keys */
+ if ((k & 0x7f) == 0x38 || (k & 0x7f) == 0x7b) {
+ xmon_adb_shiftstate = (k & 0x80) == 0;
+ continue;
+ }
+ if (k >= 0x80)
+ continue; /* ignore up transitions */
+ k = (xmon_adb_shiftstate? xmon_shift_keytab: xmon_keytab)[k];
+ if (k != 0)
+ break;
+ }
+ xmon_wants_key = 0;
+ return k;
+}
+#endif /* CONFIG_BOOTX_TEXT */
+
+int xmon_readchar(void)
+{
+#ifdef CONFIG_BOOTX_TEXT
+ if (use_screen)
+ return xmon_get_adb_key();
+#endif
+ if (!scc_initialized)
+ xmon_init_scc();
+ while ((*sccc & RXRDY) == 0)
+ do_poll_adb();
+ buf_access();
+ return *sccd;
+}
+
+int xmon_read_poll(void)
+{
+ if ((*sccc & RXRDY) == 0) {
+ do_poll_adb();
+ return -1;
+ }
+ buf_access();
+ return *sccd;
+}
+
+static unsigned char scc_inittab[] = {
+ 13, 0, /* set baud rate divisor */
+ 12, 1,
+ 14, 1, /* baud rate gen enable, src=rtxc */
+ 11, 0x50, /* clocks = br gen */
+ 5, 0xea, /* tx 8 bits, assert DTR & RTS */
+ 4, 0x46, /* x16 clock, 1 stop */
+ 3, 0xc1, /* rx enable, 8 bits */
+};
+
+void xmon_init_scc(void)
+{
+ if ( _machine == _MACH_chrp )
+ {
+ sccd[3] = 0x83; eieio(); /* LCR = 8N1 + DLAB */
+ sccd[0] = 12; eieio(); /* DLL = 9600 baud */
+ sccd[1] = 0; eieio();
+ sccd[2] = 0; eieio(); /* FCR = 0 */
+ sccd[3] = 3; eieio(); /* LCR = 8N1 */
+ sccd[1] = 0; eieio(); /* IER = 0 */
+ }
+ else if ( _machine == _MACH_Pmac )
+ {
+ int i, x;
+ unsigned long timeout;
+
+ if (channel_node != 0)
+ pmac_call_feature(
+ PMAC_FTR_SCC_ENABLE,
+ channel_node,
+ PMAC_SCC_ASYNC | PMAC_SCC_FLAG_XMON, 1);
+ printk(KERN_INFO "Serial port locked ON by debugger !\n");
+ if (via_modem && channel_node != 0) {
+ unsigned int t0;
+
+ pmac_call_feature(
+ PMAC_FTR_MODEM_ENABLE,
+ channel_node, 0, 1);
+ printk(KERN_INFO "Modem powered up by debugger !\n");
+ t0 = get_tbl();
+ timeout = 3 * tb_ticks_per_sec;
+ if (timeout == 0)
+ /* assume 25MHz if tb_ticks_per_sec not set */
+ timeout = 75000000;
+ while (get_tbl() - t0 < timeout)
+ eieio();
+ }
+ /* use the B channel if requested */
+ if (xmon_use_sccb) {
+ sccc = (volatile unsigned char *)
+ ((unsigned long)sccc & ~0x20);
+ sccd = sccc + 0x10;
+ }
+ for (i = 20000; i != 0; --i) {
+ x = *sccc; eieio();
+ }
+ *sccc = 9; eieio(); /* reset A or B side */
+ *sccc = ((unsigned long)sccc & 0x20)? 0x80: 0x40; eieio();
+ for (i = 0; i < sizeof(scc_inittab); ++i) {
+ *sccc = scc_inittab[i];
+ eieio();
+ }
+ }
+ scc_initialized = 1;
+ if (via_modem) {
+ for (;;) {
+ xmon_write("ATE1V1\r", 7);
+ if (xmon_expect("OK", 5)) {
+ xmon_write("ATA\r", 4);
+ if (xmon_expect("CONNECT", 40))
+ break;
+ }
+ xmon_write("+++", 3);
+ xmon_expect("OK", 3);
+ }
+ }
+}
+
+void xmon_enter(void)
+{
+#ifdef CONFIG_ADB_PMU
+ if (_machine == _MACH_Pmac) {
+ pmu_suspend();
+ }
+#endif
+}
+
+void xmon_leave(void)
+{
+#ifdef CONFIG_ADB_PMU
+ if (_machine == _MACH_Pmac) {
+ pmu_resume();
+ }
+#endif
+}
diff --git a/arch/powerpc/xmon/start_64.c b/arch/powerpc/xmon/start_64.c
new file mode 100644
index 000000000000..712552c4f242
--- /dev/null
+++ b/arch/powerpc/xmon/start_64.c
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 1996 Paul Mackerras.
+ *
+ * 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 <asm/machdep.h>
+#include <asm/udbg.h>
+#include "nonstdio.h"
+
+void xmon_map_scc(void)
+{
+}
+
+int xmon_write(void *ptr, int nb)
+{
+ return udbg_write(ptr, nb);
+}
+
+int xmon_readchar(void)
+{
+ if (udbg_getc)
+ return udbg_getc();
+ return -1;
+}
+
+int xmon_read_poll(void)
+{
+ if (udbg_getc_poll)
+ return udbg_getc_poll();
+ return -1;
+}
diff --git a/arch/powerpc/xmon/start_8xx.c b/arch/powerpc/xmon/start_8xx.c
new file mode 100644
index 000000000000..4c17b0486ad5
--- /dev/null
+++ b/arch/powerpc/xmon/start_8xx.c
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 1996 Paul Mackerras.
+ * Copyright (C) 2000 Dan Malek.
+ * Quick hack of Paul's code to make XMON work on 8xx processors. Lots
+ * of assumptions, like the SMC1 is used, it has been initialized by the
+ * loader at some point, and we can just stuff and suck bytes.
+ * We rely upon the 8xx uart driver to support us, as the interface
+ * changes between boot up and operational phases of the kernel.
+ */
+#include <linux/string.h>
+#include <asm/machdep.h>
+#include <asm/io.h>
+#include <asm/page.h>
+#include <linux/kernel.h>
+#include <asm/8xx_immap.h>
+#include <asm/mpc8xx.h>
+#include <asm/commproc.h>
+#include "nonstdio.h"
+
+extern int xmon_8xx_write(char *str, int nb);
+extern int xmon_8xx_read_poll(void);
+extern int xmon_8xx_read_char(void);
+
+void xmon_map_scc(void)
+{
+ cpmp = (cpm8xx_t *)&(((immap_t *)IMAP_ADDR)->im_cpm);
+}
+
+void xmon_init_scc(void);
+
+int xmon_write(void *ptr, int nb)
+{
+ return(xmon_8xx_write(ptr, nb));
+}
+
+int xmon_readchar(void)
+{
+ return xmon_8xx_read_char();
+}
+
+int xmon_read_poll(void)
+{
+ return(xmon_8xx_read_poll());
+}
diff --git a/arch/ppc64/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
index 74e63a886a69..cfcb2a56d662 100644
--- a/arch/ppc64/xmon/xmon.c
+++ b/arch/powerpc/xmon/xmon.c
@@ -1,7 +1,7 @@
/*
* Routines providing a simple monitor for use on the PowerMac.
*
- * Copyright (C) 1996 Paul Mackerras.
+ * Copyright (C) 1996-2005 Paul Mackerras.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -17,25 +17,32 @@
#include <linux/delay.h>
#include <linux/kallsyms.h>
#include <linux/cpumask.h>
+#include <linux/module.h>
+#include <linux/sysrq.h>
#include <asm/ptrace.h>
#include <asm/string.h>
#include <asm/prom.h>
#include <asm/machdep.h>
+#include <asm/xmon.h>
+#ifdef CONFIG_PMAC_BACKLIGHT
+#include <asm/backlight.h>
+#endif
#include <asm/processor.h>
#include <asm/pgtable.h>
#include <asm/mmu.h>
#include <asm/mmu_context.h>
-#include <asm/paca.h>
-#include <asm/ppcdebug.h>
#include <asm/cputable.h>
#include <asm/rtas.h>
#include <asm/sstep.h>
#include <asm/bug.h>
+
+#ifdef CONFIG_PPC64
#include <asm/hvcall.h>
+#include <asm/paca.h>
+#endif
#include "nonstdio.h"
-#include "privinst.h"
#define scanhex xmon_scanhex
#define skipbl xmon_skipbl
@@ -58,7 +65,7 @@ static unsigned long ncsum = 4096;
static int termch;
static char tmpstr[128];
-#define JMP_BUF_LEN (184/sizeof(long))
+#define JMP_BUF_LEN 23
static long bus_error_jmp[JMP_BUF_LEN];
static int catch_memory_errors;
static long *xmon_fault_jmp[NR_CPUS];
@@ -130,23 +137,31 @@ static void cacheflush(void);
static int cpu_cmd(void);
static void csum(void);
static void bootcmds(void);
+static void proccall(void);
void dump_segments(void);
static void symbol_lookup(void);
static void xmon_print_symbol(unsigned long address, const char *mid,
const char *after);
static const char *getvecname(unsigned long vec);
-static void debug_trace(void);
-
extern int print_insn_powerpc(unsigned long, unsigned long, int);
-extern void printf(const char *fmt, ...);
-extern void xmon_vfprintf(void *f, const char *fmt, va_list ap);
-extern int xmon_putc(int c, void *f);
-extern int putchar(int ch);
-extern int xmon_read_poll(void);
-extern int setjmp(long *);
-extern void longjmp(long *, int);
-extern unsigned long _ASR;
+
+extern void xmon_enter(void);
+extern void xmon_leave(void);
+
+extern long setjmp(long *);
+extern void longjmp(long *, long);
+extern void xmon_save_regs(struct pt_regs *);
+
+#ifdef CONFIG_PPC64
+#define REG "%.16lx"
+#define REGS_PER_LINE 4
+#define LAST_VOLATILE 13
+#else
+#define REG "%.8lx"
+#define REGS_PER_LINE 8
+#define LAST_VOLATILE 12
+#endif
#define GETWORD(v) (((v)[0] << 24) + ((v)[1] << 16) + ((v)[2] << 8) + (v)[3])
@@ -186,47 +201,45 @@ Commands:\n\
ml locate a block of memory\n\
mz zero a block of memory\n\
mi show information about memory allocation\n\
- p show the task list\n\
+ p call a procedure\n\
r print registers\n\
s single step\n\
S print special registers\n\
t print backtrace\n\
- T Enable/Disable PPCDBG flags\n\
x exit monitor and recover\n\
- X exit monitor and dont recover\n\
- u dump segment table or SLB\n\
- ? help\n"
- "\
- zr reboot\n\
+ X exit monitor and dont recover\n"
+#ifdef CONFIG_PPC64
+" u dump segment table or SLB\n"
+#endif
+#ifdef CONFIG_PPC_STD_MMU_32
+" u dump segment registers\n"
+#endif
+" ? help\n"
+" zr reboot\n\
zh halt\n"
;
static struct pt_regs *xmon_regs;
-extern inline void sync(void)
+static inline void sync(void)
{
asm volatile("sync; isync");
}
-/* (Ref: 64-bit PowerPC ELF ABI Spplement; Ian Lance Taylor, Zembu Labs).
- A PPC stack frame looks like this:
-
- High Address
- Back Chain
- FP reg save area
- GP reg save area
- Local var space
- Parameter save area (SP+48)
- TOC save area (SP+40)
- link editor doubleword (SP+32)
- compiler doubleword (SP+24)
- LR save (SP+16)
- CR save (SP+8)
- Back Chain (SP+0)
-
- Note that the LR (ret addr) may not be saved in the current frame if
- no functions have been called from the current function.
- */
+static inline void store_inst(void *p)
+{
+ asm volatile ("dcbst 0,%0; sync; icbi 0,%0; isync" : : "r" (p));
+}
+
+static inline void cflush(void *p)
+{
+ asm volatile ("dcbf 0,%0; icbi 0,%0" : : "r" (p));
+}
+
+static inline void cinval(void *p)
+{
+ asm volatile ("dcbi 0,%0; icbi 0,%0" : : "r" (p));
+}
/*
* Disable surveillance (the service processor watchdog function)
@@ -310,8 +323,8 @@ int xmon_core(struct pt_regs *regs, int fromipi)
unsigned long timeout;
#endif
- msr = get_msr();
- set_msrd(msr & ~MSR_EE); /* disable interrupts */
+ msr = mfmsr();
+ mtmsr(msr & ~MSR_EE); /* disable interrupts */
bp = in_breakpoint_table(regs->nip, &offset);
if (bp != NULL) {
@@ -487,7 +500,7 @@ int xmon_core(struct pt_regs *regs, int fromipi)
insert_cpu_bpts();
- set_msrd(msr); /* restore interrupt enable */
+ mtmsr(msr); /* restore interrupt enable */
return cmd != 'X';
}
@@ -497,56 +510,23 @@ int xmon(struct pt_regs *excp)
struct pt_regs regs;
if (excp == NULL) {
- /* Ok, grab regs as they are now.
- This won't do a particularily good job because the
- prologue has already been executed.
- ToDo: We could reach back into the callers save
- area to do a better job of representing the
- caller's state.
- */
- asm volatile ("std 0,0(%0)\n\
- std 1,8(%0)\n\
- std 2,16(%0)\n\
- std 3,24(%0)\n\
- std 4,32(%0)\n\
- std 5,40(%0)\n\
- std 6,48(%0)\n\
- std 7,56(%0)\n\
- std 8,64(%0)\n\
- std 9,72(%0)\n\
- std 10,80(%0)\n\
- std 11,88(%0)\n\
- std 12,96(%0)\n\
- std 13,104(%0)\n\
- std 14,112(%0)\n\
- std 15,120(%0)\n\
- std 16,128(%0)\n\
- std 17,136(%0)\n\
- std 18,144(%0)\n\
- std 19,152(%0)\n\
- std 20,160(%0)\n\
- std 21,168(%0)\n\
- std 22,176(%0)\n\
- std 23,184(%0)\n\
- std 24,192(%0)\n\
- std 25,200(%0)\n\
- std 26,208(%0)\n\
- std 27,216(%0)\n\
- std 28,224(%0)\n\
- std 29,232(%0)\n\
- std 30,240(%0)\n\
- std 31,248(%0)" : : "b" (&regs));
-
- regs.nip = regs.link = ((unsigned long *)(regs.gpr[1]))[2];
- regs.msr = get_msr();
- regs.ctr = get_ctr();
- regs.xer = get_xer();
- regs.ccr = get_cr();
- regs.trap = 0;
+ xmon_save_regs(&regs);
excp = &regs;
}
return xmon_core(excp, 0);
}
+EXPORT_SYMBOL(xmon);
+
+irqreturn_t
+xmon_irq(int irq, void *d, struct pt_regs *regs)
+{
+ unsigned long flags;
+ local_irq_save(flags);
+ printf("Keyboard interrupt\n");
+ xmon(regs);
+ local_irq_restore(flags);
+ return IRQ_HANDLED;
+}
int xmon_bpt(struct pt_regs *regs)
{
@@ -718,7 +698,7 @@ static void insert_cpu_bpts(void)
if (dabr.enabled)
set_dabr(dabr.address | (dabr.enabled & 7));
if (iabr && cpu_has_feature(CPU_FTR_IABR))
- set_iabr(iabr->address
+ mtspr(SPRN_IABR, iabr->address
| (iabr->enabled & (BP_IABR|BP_IABR_TE)));
}
@@ -746,7 +726,7 @@ static void remove_cpu_bpts(void)
{
set_dabr(0);
if (cpu_has_feature(CPU_FTR_IABR))
- set_iabr(0);
+ mtspr(SPRN_IABR, 0);
}
/* Command interpreting routine */
@@ -764,7 +744,6 @@ cmds(struct pt_regs *excp)
printf("%x:", smp_processor_id());
#endif /* CONFIG_SMP */
printf("mon> ");
- fflush(stdout);
flush_input();
termch = 0;
cmd = skipbl();
@@ -830,9 +809,6 @@ cmds(struct pt_regs *excp)
case '?':
printf(help_string);
break;
- case 'p':
- show_state();
- break;
case 'b':
bpt_cmds();
break;
@@ -846,12 +822,14 @@ cmds(struct pt_regs *excp)
case 'z':
bootcmds();
break;
- case 'T':
- debug_trace();
+ case 'p':
+ proccall();
break;
+#ifdef CONFIG_PPC_STD_MMU
case 'u':
dump_segments();
break;
+#endif
default:
printf("Unrecognized command: ");
do {
@@ -1070,6 +1048,7 @@ bpt_cmds(void)
cmd = inchar();
switch (cmd) {
+#ifndef CONFIG_8xx
case 'd': /* bd - hardware data breakpoint */
mode = 7;
cmd = inchar();
@@ -1111,6 +1090,7 @@ bpt_cmds(void)
iabr = bp;
}
break;
+#endif
case 'c':
if (!scanhex(&a)) {
@@ -1152,7 +1132,7 @@ bpt_cmds(void)
/* print all breakpoints */
printf(" type address\n");
if (dabr.enabled) {
- printf(" data %.16lx [", dabr.address);
+ printf(" data "REG" [", dabr.address);
if (dabr.enabled & 1)
printf("r");
if (dabr.enabled & 2)
@@ -1231,6 +1211,18 @@ static void get_function_bounds(unsigned long pc, unsigned long *startp,
static int xmon_depth_to_print = 64;
+#ifdef CONFIG_PPC64
+#define LRSAVE_OFFSET 0x10
+#define REG_FRAME_MARKER 0x7265677368657265ul /* "regshere" */
+#define MARKER_OFFSET 0x60
+#define REGS_OFFSET 0x70
+#else
+#define LRSAVE_OFFSET 4
+#define REG_FRAME_MARKER 0x72656773
+#define MARKER_OFFSET 8
+#define REGS_OFFSET 16
+#endif
+
static void xmon_show_stack(unsigned long sp, unsigned long lr,
unsigned long pc)
{
@@ -1247,7 +1239,7 @@ static void xmon_show_stack(unsigned long sp, unsigned long lr,
break;
}
- if (!mread(sp + 16, &ip, sizeof(unsigned long))
+ if (!mread(sp + LRSAVE_OFFSET, &ip, sizeof(unsigned long))
|| !mread(sp, &newsp, sizeof(unsigned long))) {
printf("Couldn't read stack frame at %lx\n", sp);
break;
@@ -1266,7 +1258,7 @@ static void xmon_show_stack(unsigned long sp, unsigned long lr,
get_function_bounds(pc, &fnstart, &fnend);
nextip = 0;
if (newsp > sp)
- mread(newsp + 16, &nextip,
+ mread(newsp + LRSAVE_OFFSET, &nextip,
sizeof(unsigned long));
if (lr == ip) {
if (lr < PAGE_OFFSET
@@ -1280,24 +1272,24 @@ static void xmon_show_stack(unsigned long sp, unsigned long lr,
xmon_print_symbol(lr, " ", "\n");
}
if (printip) {
- printf("[%.16lx] ", sp);
+ printf("["REG"] ", sp);
xmon_print_symbol(ip, " ", " (unreliable)\n");
}
pc = lr = 0;
} else {
- printf("[%.16lx] ", sp);
+ printf("["REG"] ", sp);
xmon_print_symbol(ip, " ", "\n");
}
/* Look for "regshere" marker to see if this is
an exception frame. */
- if (mread(sp + 0x60, &marker, sizeof(unsigned long))
- && marker == 0x7265677368657265ul) {
- if (mread(sp + 0x70, &regs, sizeof(regs))
+ if (mread(sp + MARKER_OFFSET, &marker, sizeof(unsigned long))
+ && marker == REG_FRAME_MARKER) {
+ if (mread(sp + REGS_OFFSET, &regs, sizeof(regs))
!= sizeof(regs)) {
printf("Couldn't read registers at %lx\n",
- sp + 0x70);
+ sp + REGS_OFFSET);
break;
}
printf("--- Exception: %lx %s at ", regs.trap,
@@ -1371,7 +1363,9 @@ void excprint(struct pt_regs *fp)
}
printf(" current = 0x%lx\n", current);
+#ifdef CONFIG_PPC64
printf(" paca = 0x%lx\n", get_paca());
+#endif
if (current) {
printf(" pid = %ld, comm = %s\n",
current->pid, current->comm);
@@ -1383,7 +1377,7 @@ void excprint(struct pt_regs *fp)
void prregs(struct pt_regs *fp)
{
- int n;
+ int n, trap;
unsigned long base;
struct pt_regs regs;
@@ -1396,7 +1390,7 @@ void prregs(struct pt_regs *fp)
__delay(200);
} else {
catch_memory_errors = 0;
- printf("*** Error reading registers from %.16lx\n",
+ printf("*** Error reading registers from "REG"\n",
base);
return;
}
@@ -1404,22 +1398,36 @@ void prregs(struct pt_regs *fp)
fp = &regs;
}
+#ifdef CONFIG_PPC64
if (FULL_REGS(fp)) {
for (n = 0; n < 16; ++n)
- printf("R%.2ld = %.16lx R%.2ld = %.16lx\n",
+ printf("R%.2ld = "REG" R%.2ld = "REG"\n",
n, fp->gpr[n], n+16, fp->gpr[n+16]);
} else {
for (n = 0; n < 7; ++n)
- printf("R%.2ld = %.16lx R%.2ld = %.16lx\n",
+ printf("R%.2ld = "REG" R%.2ld = "REG"\n",
n, fp->gpr[n], n+7, fp->gpr[n+7]);
}
+#else
+ for (n = 0; n < 32; ++n) {
+ printf("R%.2d = %.8x%s", n, fp->gpr[n],
+ (n & 3) == 3? "\n": " ");
+ if (n == 12 && !FULL_REGS(fp)) {
+ printf("\n");
+ break;
+ }
+ }
+#endif
printf("pc = ");
xmon_print_symbol(fp->nip, " ", "\n");
printf("lr = ");
xmon_print_symbol(fp->link, " ", "\n");
- printf("msr = %.16lx cr = %.8lx\n", fp->msr, fp->ccr);
- printf("ctr = %.16lx xer = %.16lx trap = %8lx\n",
+ printf("msr = "REG" cr = %.8lx\n", fp->msr, fp->ccr);
+ printf("ctr = "REG" xer = "REG" trap = %4lx\n",
fp->ctr, fp->xer, fp->trap);
+ trap = TRAP(fp);
+ if (trap == 0x300 || trap == 0x380 || trap == 0x600)
+ printf("dar = "REG" dsisr = %.8lx\n", fp->dar, fp->dsisr);
}
void cacheflush(void)
@@ -1519,8 +1527,7 @@ static unsigned long regno;
extern char exc_prolog;
extern char dec_exc;
-void
-super_regs(void)
+void super_regs(void)
{
int cmd;
unsigned long val;
@@ -1536,12 +1543,14 @@ super_regs(void)
asm("mr %0,1" : "=r" (sp) :);
asm("mr %0,2" : "=r" (toc) :);
- printf("msr = %.16lx sprg0= %.16lx\n", get_msr(), get_sprg0());
- printf("pvr = %.16lx sprg1= %.16lx\n", get_pvr(), get_sprg1());
- printf("dec = %.16lx sprg2= %.16lx\n", get_dec(), get_sprg2());
- printf("sp = %.16lx sprg3= %.16lx\n", sp, get_sprg3());
- printf("toc = %.16lx dar = %.16lx\n", toc, get_dar());
- printf("srr0 = %.16lx srr1 = %.16lx\n", get_srr0(), get_srr1());
+ printf("msr = "REG" sprg0= "REG"\n",
+ mfmsr(), mfspr(SPRN_SPRG0));
+ printf("pvr = "REG" sprg1= "REG"\n",
+ mfspr(SPRN_PVR), mfspr(SPRN_SPRG1));
+ printf("dec = "REG" sprg2= "REG"\n",
+ mfspr(SPRN_DEC), mfspr(SPRN_SPRG2));
+ printf("sp = "REG" sprg3= "REG"\n", sp, mfspr(SPRN_SPRG3));
+ printf("toc = "REG" dar = "REG"\n", toc, mfspr(SPRN_DAR));
#ifdef CONFIG_PPC_ISERIES
// Dump out relevant Paca data areas.
printf("Paca: \n");
@@ -1578,11 +1587,6 @@ super_regs(void)
case 'r':
printf("spr %lx = %lx\n", regno, read_spr(regno));
break;
- case 'm':
- val = get_msr();
- scanhex(&val);
- set_msrd(val);
- break;
}
scannl();
}
@@ -1604,13 +1608,13 @@ mread(unsigned long adrs, void *buf, int size)
q = (char *)buf;
switch (size) {
case 2:
- *(short *)q = *(short *)p;
+ *(u16 *)q = *(u16 *)p;
break;
case 4:
- *(int *)q = *(int *)p;
+ *(u32 *)q = *(u32 *)p;
break;
case 8:
- *(long *)q = *(long *)p;
+ *(u64 *)q = *(u64 *)p;
break;
default:
for( ; n < size; ++n) {
@@ -1641,13 +1645,13 @@ mwrite(unsigned long adrs, void *buf, int size)
q = (char *) buf;
switch (size) {
case 2:
- *(short *)p = *(short *)q;
+ *(u16 *)p = *(u16 *)q;
break;
case 4:
- *(int *)p = *(int *)q;
+ *(u32 *)p = *(u32 *)q;
break;
case 8:
- *(long *)p = *(long *)q;
+ *(u64 *)p = *(u64 *)q;
break;
default:
for ( ; n < size; ++n) {
@@ -1667,11 +1671,12 @@ mwrite(unsigned long adrs, void *buf, int size)
}
static int fault_type;
+static int fault_except;
static char *fault_chars[] = { "--", "**", "##" };
-static int
-handle_fault(struct pt_regs *regs)
+static int handle_fault(struct pt_regs *regs)
{
+ fault_except = TRAP(regs);
switch (TRAP(regs)) {
case 0x200:
fault_type = 0;
@@ -1787,7 +1792,7 @@ memex(void)
for(;;){
if (!mnoread)
n = mread(adrs, val, size);
- printf("%.16x%c", adrs, brev? 'r': ' ');
+ printf(REG"%c", adrs, brev? 'r': ' ');
if (!mnoread) {
if (brev)
byterev(val, size);
@@ -1960,23 +1965,24 @@ prdump(unsigned long adrs, long ndump)
unsigned char temp[16];
for (n = ndump; n > 0;) {
- printf("%.16lx", adrs);
+ printf(REG, adrs);
putchar(' ');
r = n < 16? n: 16;
nr = mread(adrs, temp, r);
adrs += nr;
for (m = 0; m < r; ++m) {
- if ((m & 7) == 0 && m > 0)
- putchar(' ');
+ if ((m & (sizeof(long) - 1)) == 0 && m > 0)
+ putchar(' ');
if (m < nr)
printf("%.2x", temp[m]);
else
printf("%s", fault_chars[fault_type]);
}
- if (m <= 8)
- printf(" ");
- for (; m < 16; ++m)
+ for (; m < 16; ++m) {
+ if ((m & (sizeof(long) - 1)) == 0)
+ putchar(' ');
printf(" ");
+ }
printf(" |");
for (m = 0; m < r; ++m) {
if (m < nr) {
@@ -2008,7 +2014,7 @@ ppc_inst_dump(unsigned long adr, long count, int praddr)
if (nr == 0) {
if (praddr) {
const char *x = fault_chars[fault_type];
- printf("%.16lx %s%s%s%s\n", adr, x, x, x, x);
+ printf(REG" %s%s%s%s\n", adr, x, x, x, x);
}
break;
}
@@ -2023,7 +2029,7 @@ ppc_inst_dump(unsigned long adr, long count, int praddr)
dotted = 0;
last_inst = inst;
if (praddr)
- printf("%.16lx %.8x", adr, inst);
+ printf(REG" %.8x", adr, inst);
printf("\t");
print_insn_powerpc(inst, adr, 0); /* always returns 4 */
printf("\n");
@@ -2141,7 +2147,6 @@ memzcan(void)
ok = mread(a, &v, 1);
if (ok && !ook) {
printf("%.8x .. ", a);
- fflush(stdout);
} else if (!ok && ook)
printf("%.8x\n", a - mskip);
ook = ok;
@@ -2152,6 +2157,42 @@ memzcan(void)
printf("%.8x\n", a - mskip);
}
+void proccall(void)
+{
+ unsigned long args[8];
+ unsigned long ret;
+ int i;
+ typedef unsigned long (*callfunc_t)(unsigned long, unsigned long,
+ unsigned long, unsigned long, unsigned long,
+ unsigned long, unsigned long, unsigned long);
+ callfunc_t func;
+
+ if (!scanhex(&adrs))
+ return;
+ if (termch != '\n')
+ termch = 0;
+ for (i = 0; i < 8; ++i)
+ args[i] = 0;
+ for (i = 0; i < 8; ++i) {
+ if (!scanhex(&args[i]) || termch == '\n')
+ break;
+ termch = 0;
+ }
+ func = (callfunc_t) adrs;
+ ret = 0;
+ if (setjmp(bus_error_jmp) == 0) {
+ catch_memory_errors = 1;
+ sync();
+ ret = func(args[0], args[1], args[2], args[3],
+ args[4], args[5], args[6], args[7]);
+ sync();
+ printf("return value is %x\n", ret);
+ } else {
+ printf("*** %x exception occurred\n", fault_except);
+ }
+ catch_memory_errors = 0;
+}
+
/* Input scanning routines */
int
skipbl(void)
@@ -2174,7 +2215,12 @@ static char *regnames[N_PTREGS] = {
"r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
"r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
"r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
- "pc", "msr", "or3", "ctr", "lr", "xer", "ccr", "softe",
+ "pc", "msr", "or3", "ctr", "lr", "xer", "ccr",
+#ifdef CONFIG_PPC64
+ "softe",
+#else
+ "mq",
+#endif
"trap", "dar", "dsisr", "res"
};
@@ -2280,8 +2326,7 @@ scannl(void)
c = inchar();
}
-int
-hexdigit(int c)
+int hexdigit(int c)
{
if( '0' <= c && c <= '9' )
return c - '0';
@@ -2322,7 +2367,7 @@ int
inchar(void)
{
if (lineptr == NULL || *lineptr == 0) {
- if (fgets(line, sizeof(line), stdin) == NULL) {
+ if (xmon_gets(line, sizeof(line)) == NULL) {
lineptr = NULL;
return EOF;
}
@@ -2378,7 +2423,7 @@ static void xmon_print_symbol(unsigned long address, const char *mid,
const char *name = NULL;
unsigned long offset, size;
- printf("%.16lx", address);
+ printf(REG, address);
if (setjmp(bus_error_jmp) == 0) {
catch_memory_errors = 1;
sync();
@@ -2399,55 +2444,7 @@ static void xmon_print_symbol(unsigned long address, const char *mid,
printf("%s", after);
}
-static void debug_trace(void)
-{
- unsigned long val, cmd, on;
-
- cmd = skipbl();
- if (cmd == '\n') {
- /* show current state */
- unsigned long i;
- printf("ppc64_debug_switch = 0x%lx\n", ppc64_debug_switch);
- for (i = 0; i < PPCDBG_NUM_FLAGS ;i++) {
- on = PPCDBG_BITVAL(i) & ppc64_debug_switch;
- printf("%02x %s %12s ", i, on ? "on " : "off", trace_names[i] ? trace_names[i] : "");
- if (((i+1) % 3) == 0)
- printf("\n");
- }
- printf("\n");
- return;
- }
- while (cmd != '\n') {
- on = 1; /* default if no sign given */
- while (cmd == '+' || cmd == '-') {
- on = (cmd == '+');
- cmd = inchar();
- if (cmd == ' ' || cmd == '\n') { /* Turn on or off based on + or - */
- ppc64_debug_switch = on ? PPCDBG_ALL:PPCDBG_NONE;
- printf("Setting all values to %s...\n", on ? "on" : "off");
- if (cmd == '\n') return;
- else cmd = skipbl();
- }
- else
- termch = cmd;
- }
- termch = cmd; /* not +/- ... let scanhex see it */
- scanhex((void *)&val);
- if (val >= 64) {
- printf("Value %x out of range:\n", val);
- return;
- }
- if (on) {
- ppc64_debug_switch |= PPCDBG_BITVAL(val);
- printf("enable debug %x %s\n", val, trace_names[val] ? trace_names[val] : "");
- } else {
- ppc64_debug_switch &= ~PPCDBG_BITVAL(val);
- printf("disable debug %x %s\n", val, trace_names[val] ? trace_names[val] : "");
- }
- cmd = skipbl();
- }
-}
-
+#ifdef CONFIG_PPC64
static void dump_slb(void)
{
int i;
@@ -2484,6 +2481,27 @@ static void dump_stab(void)
}
}
+void dump_segments(void)
+{
+ if (cpu_has_feature(CPU_FTR_SLB))
+ dump_slb();
+ else
+ dump_stab();
+}
+#endif
+
+#ifdef CONFIG_PPC_STD_MMU_32
+void dump_segments(void)
+{
+ int i;
+
+ printf("sr0-15 =");
+ for (i = 0; i < 16; ++i)
+ printf(" %x", mfsrin(i));
+ printf("\n");
+}
+#endif
+
void xmon_init(int enable)
{
if (enable) {
@@ -2503,12 +2521,29 @@ void xmon_init(int enable)
__debugger_dabr_match = NULL;
__debugger_fault_handler = NULL;
}
+ xmon_map_scc();
}
-void dump_segments(void)
+#ifdef CONFIG_MAGIC_SYSRQ
+static void sysrq_handle_xmon(int key, struct pt_regs *pt_regs,
+ struct tty_struct *tty)
{
- if (cpu_has_feature(CPU_FTR_SLB))
- dump_slb();
- else
- dump_stab();
+ /* ensure xmon is enabled */
+ xmon_init(1);
+ debugger(pt_regs);
+}
+
+static struct sysrq_key_op sysrq_xmon_op =
+{
+ .handler = sysrq_handle_xmon,
+ .help_msg = "Xmon",
+ .action_msg = "Entering xmon",
+};
+
+static int __init setup_xmon_sysrq(void)
+{
+ register_sysrq_key('x', &sysrq_xmon_op);
+ return 0;
}
+__initcall(setup_xmon_sysrq);
+#endif /* CONFIG_MAGIC_SYSRQ */
diff --git a/arch/ppc/4xx_io/serial_sicc.c b/arch/ppc/4xx_io/serial_sicc.c
index e95c48d57571..84d96b857e4a 100644
--- a/arch/ppc/4xx_io/serial_sicc.c
+++ b/arch/ppc/4xx_io/serial_sicc.c
@@ -1145,8 +1145,8 @@ static int set_serial_info(struct SICC_info *info,
info->flags = ((state->flags & ~ASYNC_INTERNAL_FLAGS) |
(info->flags & ASYNC_INTERNAL_FLAGS));
state->custom_divisor = new_serial.custom_divisor;
- state->close_delay = new_serial.close_delay * HZ / 100;
- state->closing_wait = new_serial.closing_wait * HZ / 100;
+ state->close_delay = msecs_to_jiffies(10 * new_serial.close_delay);
+ state->closing_wait = msecs_to_jiffies(10 * new_serial.closing_wait);
info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
port->fifosize = new_serial.xmit_fifo_size;
@@ -1465,10 +1465,8 @@ static void siccuart_close(struct tty_struct *tty, struct file *filp)
info->event = 0;
info->tty = NULL;
if (info->blocked_open) {
- if (info->state->close_delay) {
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(info->state->close_delay);
- }
+ if (info->state->close_delay)
+ schedule_timeout_interruptible(info->state->close_delay);
wake_up_interruptible(&info->open_wait);
}
info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
@@ -1496,7 +1494,7 @@ static void siccuart_wait_until_sent(struct tty_struct *tty, int timeout)
* Note: we have to use pretty tight timings here to satisfy
* the NIST-PCTS.
*/
- char_time = (info->timeout - HZ/50) / info->port->fifosize;
+ char_time = (info->timeout - msecs_to_jiffies(20)) / info->port->fifosize;
char_time = char_time / 5;
if (char_time == 0)
char_time = 1;
@@ -1521,8 +1519,7 @@ static void siccuart_wait_until_sent(struct tty_struct *tty, int timeout)
tty->index, jiffies,
expire, char_time);
while ((readb(info->port->uart_base + BL_SICC_LSR) & _LSR_TX_ALL) != _LSR_TX_ALL) {
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(char_time);
+ schedule_timeout_interruptible(char_time);
if (signal_pending(current))
break;
if (timeout && time_after(jiffies, expire))
@@ -1773,7 +1770,7 @@ int __init siccuart_init(void)
for (i = 0; i < SERIAL_SICC_NR; i++) {
struct SICC_state *state = sicc_state + i;
state->line = i;
- state->close_delay = 5 * HZ / 10;
+ state->close_delay = msecs_to_jiffies(500);
state->closing_wait = 30 * HZ;
spin_lock_init(&state->sicc_lock);
}
diff --git a/arch/ppc/8260_io/fcc_enet.c b/arch/ppc/8260_io/fcc_enet.c
index 2086c6ad1147..4edeede9ccfd 100644
--- a/arch/ppc/8260_io/fcc_enet.c
+++ b/arch/ppc/8260_io/fcc_enet.c
@@ -1309,8 +1309,7 @@ static void mii_dm9161_wait(uint mii_reg, struct net_device *dev)
/* Davicom takes a bit to come up after a reset,
* so wait here for a bit */
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(timeout);
+ schedule_timeout_uninterruptible(timeout);
}
static phy_info_t phy_info_dm9161 = {
diff --git a/arch/ppc/8xx_io/commproc.c b/arch/ppc/8xx_io/commproc.c
index 11726e2a4ec8..579cd40258b9 100644
--- a/arch/ppc/8xx_io/commproc.c
+++ b/arch/ppc/8xx_io/commproc.c
@@ -73,7 +73,7 @@ cpm_mask_irq(unsigned int irq)
{
int cpm_vec = irq - CPM_IRQ_OFFSET;
- ((immap_t *)IMAP_ADDR)->im_cpic.cpic_cimr &= ~(1 << cpm_vec);
+ out_be32(&((immap_t *)IMAP_ADDR)->im_cpic.cpic_cimr, in_be32(&((immap_t *)IMAP_ADDR)->im_cpic.cpic_cimr) & ~(1 << cpm_vec));
}
static void
@@ -81,7 +81,7 @@ cpm_unmask_irq(unsigned int irq)
{
int cpm_vec = irq - CPM_IRQ_OFFSET;
- ((immap_t *)IMAP_ADDR)->im_cpic.cpic_cimr |= (1 << cpm_vec);
+ out_be32(&((immap_t *)IMAP_ADDR)->im_cpic.cpic_cimr, in_be32(&((immap_t *)IMAP_ADDR)->im_cpic.cpic_cimr) | (1 << cpm_vec));
}
static void
@@ -95,7 +95,7 @@ cpm_eoi(unsigned int irq)
{
int cpm_vec = irq - CPM_IRQ_OFFSET;
- ((immap_t *)IMAP_ADDR)->im_cpic.cpic_cisr = (1 << cpm_vec);
+ out_be32(&((immap_t *)IMAP_ADDR)->im_cpic.cpic_cisr, (1 << cpm_vec));
}
struct hw_interrupt_type cpm_pic = {
@@ -133,7 +133,7 @@ m8xx_cpm_reset(void)
* manual recommends it.
* Bit 25, FAM can also be set to use FEC aggressive mode (860T).
*/
- imp->im_siu_conf.sc_sdcr = 1;
+ out_be32(&imp->im_siu_conf.sc_sdcr, 1),
/* Reclaim the DP memory for our use. */
m8xx_cpm_dpinit();
@@ -178,10 +178,10 @@ cpm_interrupt_init(void)
/* Initialize the CPM interrupt controller.
*/
- ((immap_t *)IMAP_ADDR)->im_cpic.cpic_cicr =
+ out_be32(&((immap_t *)IMAP_ADDR)->im_cpic.cpic_cicr,
(CICR_SCD_SCC4 | CICR_SCC_SCC3 | CICR_SCB_SCC2 | CICR_SCA_SCC1) |
- ((CPM_INTERRUPT/2) << 13) | CICR_HP_MASK;
- ((immap_t *)IMAP_ADDR)->im_cpic.cpic_cimr = 0;
+ ((CPM_INTERRUPT/2) << 13) | CICR_HP_MASK);
+ out_be32(&((immap_t *)IMAP_ADDR)->im_cpic.cpic_cimr, 0);
/* install the CPM interrupt controller routines for the CPM
* interrupt vectors
@@ -198,7 +198,7 @@ cpm_interrupt_init(void)
if (setup_irq(CPM_IRQ_OFFSET + CPMVEC_ERROR, &cpm_error_irqaction))
panic("Could not allocate CPM error IRQ!");
- ((immap_t *)IMAP_ADDR)->im_cpic.cpic_cicr |= CICR_IEN;
+ out_be32(&((immap_t *)IMAP_ADDR)->im_cpic.cpic_cicr, in_be32(&((immap_t *)IMAP_ADDR)->im_cpic.cpic_cicr) | CICR_IEN);
}
/*
@@ -212,8 +212,8 @@ cpm_get_irq(struct pt_regs *regs)
/* Get the vector by setting the ACK bit and then reading
* the register.
*/
- ((volatile immap_t *)IMAP_ADDR)->im_cpic.cpic_civr = 1;
- cpm_vec = ((volatile immap_t *)IMAP_ADDR)->im_cpic.cpic_civr;
+ out_be16(&((volatile immap_t *)IMAP_ADDR)->im_cpic.cpic_civr, 1);
+ cpm_vec = in_be16(&((volatile immap_t *)IMAP_ADDR)->im_cpic.cpic_civr);
cpm_vec >>= 11;
return cpm_vec;
@@ -388,9 +388,8 @@ void m8xx_cpm_dpinit(void)
/*
* Allocate the requested size worth of DP memory.
- * This function used to return an index into the DPRAM area.
- * Now it returns the actuall physical address of that area.
- * use m8xx_cpm_dpram_offset() to get the index
+ * This function returns an offset into the DPRAM area.
+ * Use cpm_dpram_addr() to get the virtual address of the area.
*/
uint cpm_dpalloc(uint size, uint align)
{
diff --git a/arch/ppc/8xx_io/cs4218.h b/arch/ppc/8xx_io/cs4218.h
index a3c38c5a5db2..f1c7392255f8 100644
--- a/arch/ppc/8xx_io/cs4218.h
+++ b/arch/ppc/8xx_io/cs4218.h
@@ -78,7 +78,7 @@ typedef struct {
const char *name2;
void (*open)(void);
void (*release)(void);
- void *(*dma_alloc)(unsigned int, int);
+ void *(*dma_alloc)(unsigned int, gfp_t);
void (*dma_free)(void *, unsigned int);
int (*irqinit)(void);
#ifdef MODULE
diff --git a/arch/ppc/8xx_io/cs4218_tdm.c b/arch/ppc/8xx_io/cs4218_tdm.c
index 2ca9ec7ec3a7..49eb2a7e65c0 100644
--- a/arch/ppc/8xx_io/cs4218_tdm.c
+++ b/arch/ppc/8xx_io/cs4218_tdm.c
@@ -318,7 +318,7 @@ struct cs_sound_settings {
static struct cs_sound_settings sound;
-static void *CS_Alloc(unsigned int size, int flags);
+static void *CS_Alloc(unsigned int size, gfp_t flags);
static void CS_Free(void *ptr, unsigned int size);
static int CS_IrqInit(void);
#ifdef MODULE
@@ -959,7 +959,7 @@ static TRANS transCSNormalRead = {
/*** Low level stuff *********************************************************/
-static void *CS_Alloc(unsigned int size, int flags)
+static void *CS_Alloc(unsigned int size, gfp_t flags)
{
int order;
@@ -1013,8 +1013,7 @@ static void CS_IrqCleanup(void)
*/
cpm_free_handler(CPMVEC_SMC2);
- if (beep_buf)
- kfree(beep_buf);
+ kfree(beep_buf);
kd_mksound = orig_mksound;
}
#endif /* MODULE */
diff --git a/arch/ppc/Kconfig b/arch/ppc/Kconfig
index 776941c75672..8fa51b0a32d2 100644
--- a/arch/ppc/Kconfig
+++ b/arch/ppc/Kconfig
@@ -568,6 +568,7 @@ config CHESTNUT
config SPRUCE
bool "IBM-Spruce"
+ select PPC_INDIRECT_PCI
config HDPU
bool "Sky-HDPU"
@@ -588,27 +589,35 @@ config EV64260
config LOPEC
bool "Motorola-LoPEC"
+ select PPC_I8259
config MVME5100
bool "Motorola-MVME5100"
+ select PPC_INDIRECT_PCI
config PPLUS
bool "Motorola-PowerPlus"
+ select PPC_I8259
+ select PPC_INDIRECT_PCI
config PRPMC750
bool "Motorola-PrPMC750"
+ select PPC_INDIRECT_PCI
config PRPMC800
bool "Motorola-PrPMC800"
+ select PPC_INDIRECT_PCI
config SANDPOINT
bool "Motorola-Sandpoint"
+ select PPC_I8259
help
Select SANDPOINT if configuring for a Motorola Sandpoint X3
(any flavor).
config RADSTONE_PPC7D
bool "Radstone Technology PPC7D board"
+ select PPC_I8259
config PAL4
bool "SBS-Palomar4"
@@ -616,6 +625,7 @@ config PAL4
config GEMINI
bool "Synergy-Gemini"
depends on BROKEN
+ select PPC_INDIRECT_PCI
help
Select Gemini if configuring for a Synergy Microsystems' Gemini
series Single Board Computer. More information is available at:
@@ -736,6 +746,16 @@ config MPC834x
bool
default y if MPC834x_SYS
+config CPM1
+ bool
+ depends on 8xx
+ default y
+ help
+ The CPM1 (Communications Processor Module) is a coprocessor on
+ embedded CPUs made by Motorola. Selecting this option means that
+ you wish to build a kernel for a machine with a CPM1 coprocessor
+ on it (8xx, 827x, 8560).
+
config CPM2
bool
depends on 8260 || MPC8560 || MPC8555
@@ -747,13 +767,16 @@ config CPM2
on it (826x, 827x, 8560).
config PPC_CHRP
- bool
+ bool " Common Hardware Reference Platform (CHRP) based machines"
depends on PPC_MULTIPLATFORM
+ select PPC_I8259
+ select PPC_INDIRECT_PCI
default y
config PPC_PMAC
- bool
+ bool " Apple PowerMac based machines"
depends on PPC_MULTIPLATFORM
+ select PPC_INDIRECT_PCI
default y
config PPC_PMAC64
@@ -762,8 +785,10 @@ config PPC_PMAC64
default y
config PPC_PREP
- bool
+ bool " PowerPC Reference Platform (PReP) based machines"
depends on PPC_MULTIPLATFORM
+ select PPC_I8259
+ select PPC_INDIRECT_PCI
default y
config PPC_OF
@@ -797,6 +822,7 @@ config MV64360 # Really MV64360 & MV64460
config MV64X60
bool
depends on (GT64260 || MV64360)
+ select PPC_INDIRECT_PCI
default y
menu "Set bridge options"
@@ -845,6 +871,7 @@ config EPIC_SERIAL_MODE
config MPC10X_BRIDGE
bool
depends on POWERPMC250 || LOPEC || SANDPOINT
+ select PPC_INDIRECT_PCI
default y
config MPC10X_OPENPIC
@@ -870,6 +897,7 @@ config HARRIER_STORE_GATHERING
config MVME5100_IPMC761_PRESENT
bool "MVME5100 configured with an IPMC761"
depends on MVME5100
+ select PPC_I8259
config SPRUCE_BAUD_33M
bool "Spruce baud clock support"
@@ -1127,6 +1155,7 @@ menu "Bus options"
config ISA
bool "Support for ISA-bus hardware"
depends on PPC_PREP || PPC_CHRP
+ select PPC_I8259
help
Find out whether you have ISA slots on your motherboard. ISA is the
name of a bus system, i.e. the way the CPU talks to the other stuff
@@ -1139,6 +1168,17 @@ config GENERIC_ISA_DMA
depends on POWER3 || POWER4 || 6xx && !CPM2
default y
+config PPC_I8259
+ bool
+ default y if 85xx
+ default n
+
+config PPC_INDIRECT_PCI
+ bool
+ depends on PCI
+ default y if 40x || 44x || 85xx || 83xx
+ default n
+
config EISA
bool
help
@@ -1175,6 +1215,7 @@ config MPC83xx_PCI2
config PCI_QSPAN
bool "QSpan PCI"
depends on !4xx && !CPM2 && 8xx
+ select PPC_I8259
help
Say Y here if you have a system based on a Motorola 8xx-series
embedded processor with a QSPAN PCI interface, otherwise say N.
@@ -1182,6 +1223,7 @@ config PCI_QSPAN
config PCI_8260
bool
depends on PCI && 8260
+ select PPC_INDIRECT_PCI
default y
config 8260_PCI9
@@ -1215,6 +1257,14 @@ source "drivers/pci/Kconfig"
source "drivers/pcmcia/Kconfig"
+config RAPIDIO
+ bool "RapidIO support" if MPC8540 || MPC8560
+ help
+ If you say Y here, the kernel will include drivers and
+ infrastructure code to support RapidIO interconnect devices.
+
+source "drivers/rapidio/Kconfig"
+
endmenu
menu "Advanced setup"
@@ -1368,7 +1418,7 @@ endmenu
source "lib/Kconfig"
-source "arch/ppc/oprofile/Kconfig"
+source "arch/powerpc/oprofile/Kconfig"
source "arch/ppc/Kconfig.debug"
diff --git a/arch/ppc/Makefile b/arch/ppc/Makefile
index 16e2675f3270..e719a4933af1 100644
--- a/arch/ppc/Makefile
+++ b/arch/ppc/Makefile
@@ -26,6 +26,10 @@ CPPFLAGS += -Iarch/$(ARCH) -Iarch/$(ARCH)/include
AFLAGS += -Iarch/$(ARCH)
CFLAGS += -Iarch/$(ARCH) -msoft-float -pipe \
-ffixed-r2 -mmultiple
+
+# No AltiVec instruction when building kernel
+CFLAGS += $(call cc-option, -mno-altivec)
+
CPP = $(CC) -E $(CFLAGS)
# Temporary hack until we have migrated to asm-powerpc
LINUXINCLUDE += -Iarch/$(ARCH)/include
@@ -57,10 +61,13 @@ head-$(CONFIG_FSL_BOOKE) := arch/ppc/kernel/head_fsl_booke.o
head-$(CONFIG_6xx) += arch/ppc/kernel/idle_6xx.o
head-$(CONFIG_POWER4) += arch/ppc/kernel/idle_power4.o
-head-$(CONFIG_PPC_FPU) += arch/ppc/kernel/fpu.o
+head-$(CONFIG_PPC_FPU) += arch/powerpc/kernel/fpu.o
-core-y += arch/ppc/kernel/ arch/ppc/platforms/ \
- arch/ppc/mm/ arch/ppc/lib/ arch/ppc/syslib/
+core-y += arch/ppc/kernel/ arch/powerpc/kernel/ \
+ arch/ppc/platforms/ \
+ arch/ppc/mm/ arch/ppc/lib/ \
+ arch/ppc/syslib/ arch/powerpc/sysdev/ \
+ arch/powerpc/lib/
core-$(CONFIG_4xx) += arch/ppc/platforms/4xx/
core-$(CONFIG_83xx) += arch/ppc/platforms/83xx/
core-$(CONFIG_85xx) += arch/ppc/platforms/85xx/
@@ -71,7 +78,7 @@ drivers-$(CONFIG_8xx) += arch/ppc/8xx_io/
drivers-$(CONFIG_4xx) += arch/ppc/4xx_io/
drivers-$(CONFIG_CPM2) += arch/ppc/8260_io/
-drivers-$(CONFIG_OPROFILE) += arch/ppc/oprofile/
+drivers-$(CONFIG_OPROFILE) += arch/powerpc/oprofile/
BOOT_TARGETS = zImage zImage.initrd znetboot znetboot.initrd vmlinux.sm
diff --git a/arch/ppc/boot/include/of1275.h b/arch/ppc/boot/include/of1275.h
index 69173df76db0..4ed88acfa73a 100644
--- a/arch/ppc/boot/include/of1275.h
+++ b/arch/ppc/boot/include/of1275.h
@@ -19,6 +19,9 @@ extern prom_entry of_prom_entry;
/* function declarations */
+int call_prom(const char *service, int nargs, int nret, ...);
+int call_prom_ret(const char *service, int nargs, int nret,
+ unsigned int *rets, ...);
void * claim(unsigned int virt, unsigned int size, unsigned int align);
int map(unsigned int phys, unsigned int virt, unsigned int size);
void enter(void);
diff --git a/arch/ppc/boot/of1275/Makefile b/arch/ppc/boot/of1275/Makefile
index 02e6f235d7cb..0b979c004972 100644
--- a/arch/ppc/boot/of1275/Makefile
+++ b/arch/ppc/boot/of1275/Makefile
@@ -3,4 +3,4 @@
#
lib-y := claim.o enter.o exit.o finddevice.o getprop.o ofinit.o \
- ofstdio.o read.o release.o write.o map.o
+ ofstdio.o read.o release.o write.o map.o call_prom.o
diff --git a/arch/ppc/boot/of1275/call_prom.c b/arch/ppc/boot/of1275/call_prom.c
new file mode 100644
index 000000000000..9479a3a2b8c7
--- /dev/null
+++ b/arch/ppc/boot/of1275/call_prom.c
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 1996-2005 Paul Mackerras.
+ *
+ * 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 "of1275.h"
+#include <stdarg.h>
+
+int call_prom(const char *service, int nargs, int nret, ...)
+{
+ int i;
+ struct prom_args {
+ const char *service;
+ int nargs;
+ int nret;
+ unsigned int args[12];
+ } args;
+ va_list list;
+
+ args.service = service;
+ args.nargs = nargs;
+ args.nret = nret;
+
+ va_start(list, nret);
+ for (i = 0; i < nargs; i++)
+ args.args[i] = va_arg(list, unsigned int);
+ va_end(list);
+
+ for (i = 0; i < nret; i++)
+ args.args[nargs+i] = 0;
+
+ if (of_prom_entry(&args) < 0)
+ return -1;
+
+ return (nret > 0)? args.args[nargs]: 0;
+}
+
+int call_prom_ret(const char *service, int nargs, int nret,
+ unsigned int *rets, ...)
+{
+ int i;
+ struct prom_args {
+ const char *service;
+ int nargs;
+ int nret;
+ unsigned int args[12];
+ } args;
+ va_list list;
+
+ args.service = service;
+ args.nargs = nargs;
+ args.nret = nret;
+
+ va_start(list, rets);
+ for (i = 0; i < nargs; i++)
+ args.args[i] = va_arg(list, unsigned int);
+ va_end(list);
+
+ for (i = 0; i < nret; i++)
+ args.args[nargs+i] = 0;
+
+ if (of_prom_entry(&args) < 0)
+ return -1;
+
+ if (rets != (void *) 0)
+ for (i = 1; i < nret; ++i)
+ rets[i-1] = args.args[nargs+i];
+
+ return (nret > 0)? args.args[nargs]: 0;
+}
diff --git a/arch/ppc/boot/of1275/claim.c b/arch/ppc/boot/of1275/claim.c
index e060292ae2a7..1ed3aeeff8ae 100644
--- a/arch/ppc/boot/of1275/claim.c
+++ b/arch/ppc/boot/of1275/claim.c
@@ -9,26 +9,84 @@
*/
#include "of1275.h"
+#include "nonstdio.h"
-void *
-claim(unsigned int virt, unsigned int size, unsigned int align)
+/*
+ * Older OF's require that when claiming a specific range of addresses,
+ * we claim the physical space in the /memory node and the virtual
+ * space in the chosen mmu node, and then do a map operation to
+ * map virtual to physical.
+ */
+static int need_map = -1;
+static ihandle chosen_mmu;
+static phandle memory;
+
+/* returns true if s2 is a prefix of s1 */
+static int string_match(const char *s1, const char *s2)
+{
+ for (; *s2; ++s2)
+ if (*s1++ != *s2)
+ return 0;
+ return 1;
+}
+
+static int check_of_version(void)
+{
+ phandle oprom, chosen;
+ char version[64];
+
+ oprom = finddevice("/openprom");
+ if (oprom == OF_INVALID_HANDLE)
+ return 0;
+ if (getprop(oprom, "model", version, sizeof(version)) <= 0)
+ return 0;
+ version[sizeof(version)-1] = 0;
+ printf("OF version = '%s'\n", version);
+ if (!string_match(version, "Open Firmware, 1.")
+ && !string_match(version, "FirmWorks,3."))
+ return 0;
+ chosen = finddevice("/chosen");
+ if (chosen == OF_INVALID_HANDLE) {
+ chosen = finddevice("/chosen@0");
+ if (chosen == OF_INVALID_HANDLE) {
+ printf("no chosen\n");
+ return 0;
+ }
+ }
+ if (getprop(chosen, "mmu", &chosen_mmu, sizeof(chosen_mmu)) <= 0) {
+ printf("no mmu\n");
+ return 0;
+ }
+ memory = (ihandle) call_prom("open", 1, 1, "/memory");
+ if (memory == OF_INVALID_HANDLE) {
+ memory = (ihandle) call_prom("open", 1, 1, "/memory@0");
+ if (memory == OF_INVALID_HANDLE) {
+ printf("no memory node\n");
+ return 0;
+ }
+ }
+ printf("old OF detected\n");
+ return 1;
+}
+
+void *claim(unsigned int virt, unsigned int size, unsigned int align)
{
- struct prom_args {
- char *service;
- int nargs;
- int nret;
- unsigned int virt;
- unsigned int size;
- unsigned int align;
- void *ret;
- } args;
+ int ret;
+ unsigned int result;
- args.service = "claim";
- args.nargs = 3;
- args.nret = 1;
- args.virt = virt;
- args.size = size;
- args.align = align;
- (*of_prom_entry)(&args);
- return args.ret;
+ if (need_map < 0)
+ need_map = check_of_version();
+ if (align || !need_map)
+ return (void *) call_prom("claim", 3, 1, virt, size, align);
+
+ ret = call_prom_ret("call-method", 5, 2, &result, "claim", memory,
+ align, size, virt);
+ if (ret != 0 || result == -1)
+ return (void *) -1;
+ ret = call_prom_ret("call-method", 5, 2, &result, "claim", chosen_mmu,
+ align, size, virt);
+ /* 0x12 == coherent + read/write */
+ ret = call_prom("call-method", 6, 1, "map", chosen_mmu,
+ 0x12, size, virt, virt);
+ return virt;
}
diff --git a/arch/ppc/boot/of1275/finddevice.c b/arch/ppc/boot/of1275/finddevice.c
index 2c0f7cbb793e..0dcb1201b772 100644
--- a/arch/ppc/boot/of1275/finddevice.c
+++ b/arch/ppc/boot/of1275/finddevice.c
@@ -10,22 +10,7 @@
#include "of1275.h"
-phandle
-finddevice(const char *name)
+phandle finddevice(const char *name)
{
- struct prom_args {
- char *service;
- int nargs;
- int nret;
- const char *devspec;
- phandle device;
- } args;
-
- args.service = "finddevice";
- args.nargs = 1;
- args.nret = 1;
- args.devspec = name;
- args.device = OF_INVALID_HANDLE;
- (*of_prom_entry)(&args);
- return args.device;
+ return (phandle) call_prom("finddevice", 1, 1, name);
}
diff --git a/arch/ppc/boot/openfirmware/Makefile b/arch/ppc/boot/openfirmware/Makefile
index 03415238fabf..83a6433459ce 100644
--- a/arch/ppc/boot/openfirmware/Makefile
+++ b/arch/ppc/boot/openfirmware/Makefile
@@ -80,8 +80,7 @@ $(obj)/note: $(utils)/mknote FORCE
$(call if_changed,mknote)
-$(obj)/coffcrt0.o: EXTRA_AFLAGS := -traditional -DXCOFF
-$(obj)/crt0.o: EXTRA_AFLAGS := -traditional
+$(obj)/coffcrt0.o: EXTRA_AFLAGS := -DXCOFF
targets += coffcrt0.o crt0.o
$(obj)/coffcrt0.o $(obj)/crt0.o: $(common)/crt0.S FORCE
$(call if_changed_dep,as_o_S)
diff --git a/arch/ppc/boot/openfirmware/chrpmain.c b/arch/ppc/boot/openfirmware/chrpmain.c
index effe4a0624b0..245dbd9fc120 100644
--- a/arch/ppc/boot/openfirmware/chrpmain.c
+++ b/arch/ppc/boot/openfirmware/chrpmain.c
@@ -78,7 +78,7 @@ boot(int a1, int a2, void *prom)
begin_avail = avail_high = avail_ram;
end_avail = scratch + sizeof(scratch);
printf("gunzipping (0x%p <- 0x%p:0x%p)...", dst, im, im+len);
- gunzip(dst, 0x400000, im, &len);
+ gunzip(dst, PROG_SIZE - PROG_START, im, &len);
printf("done %u bytes\n\r", len);
printf("%u bytes of heap consumed, max in use %u\n\r",
avail_high - begin_avail, heap_max);
diff --git a/arch/ppc/boot/openfirmware/coffmain.c b/arch/ppc/boot/openfirmware/coffmain.c
index 04ba9d57e110..2da8855e2be0 100644
--- a/arch/ppc/boot/openfirmware/coffmain.c
+++ b/arch/ppc/boot/openfirmware/coffmain.c
@@ -38,7 +38,7 @@ static char heap[SCRATCH_SIZE];
static unsigned long ram_start = 0;
static unsigned long ram_end = 0x1000000;
-static unsigned long prog_start = 0x900000;
+static unsigned long prog_start = 0x800000;
static unsigned long prog_size = 0x700000;
typedef void (*kernel_start_t)(int, int, void *);
diff --git a/arch/ppc/boot/simple/Makefile b/arch/ppc/boot/simple/Makefile
index b7bd8f61a4ad..82df88b01bbe 100644
--- a/arch/ppc/boot/simple/Makefile
+++ b/arch/ppc/boot/simple/Makefile
@@ -67,6 +67,12 @@ zimageinitrd-$(CONFIG_BAMBOO) := zImage.initrd-TREE
entrypoint-$(CONFIG_BAMBOO) := 0x01000000
extra.o-$(CONFIG_BAMBOO) := pibs.o
+ zimage-$(CONFIG_BUBINGA) := zImage-TREE
+zimageinitrd-$(CONFIG_BUBINGA) := zImage.initrd-TREE
+ end-$(CONFIG_BUBINGA) := bubinga
+ entrypoint-$(CONFIG_BUBINGA) := 0x01000000
+ extra.o-$(CONFIG_BUBINGA) := openbios.o
+
zimage-$(CONFIG_EBONY) := zImage-TREE
zimageinitrd-$(CONFIG_EBONY) := zImage.initrd-TREE
end-$(CONFIG_EBONY) := ebony
@@ -79,12 +85,30 @@ zimageinitrd-$(CONFIG_LUAN) := zImage.initrd-TREE
entrypoint-$(CONFIG_LUAN) := 0x01000000
extra.o-$(CONFIG_LUAN) := pibs.o
+ zimage-$(CONFIG_YUCCA) := zImage-TREE
+zimageinitrd-$(CONFIG_YUCCA) := zImage.initrd-TREE
+ end-$(CONFIG_YUCCA) := yucca
+ entrypoint-$(CONFIG_YUCCA) := 0x01000000
+ extra.o-$(CONFIG_YUCCA) := pibs.o
+
zimage-$(CONFIG_OCOTEA) := zImage-TREE
zimageinitrd-$(CONFIG_OCOTEA) := zImage.initrd-TREE
end-$(CONFIG_OCOTEA) := ocotea
entrypoint-$(CONFIG_OCOTEA) := 0x01000000
extra.o-$(CONFIG_OCOTEA) := pibs.o
+ zimage-$(CONFIG_SYCAMORE) := zImage-TREE
+zimageinitrd-$(CONFIG_SYCAMORE) := zImage.initrd-TREE
+ end-$(CONFIG_SYCAMORE) := sycamore
+ entrypoint-$(CONFIG_SYCAMORE) := 0x01000000
+ extra.o-$(CONFIG_SYCAMORE) := openbios.o
+
+ zimage-$(CONFIG_WALNUT) := zImage-TREE
+zimageinitrd-$(CONFIG_WALNUT) := zImage.initrd-TREE
+ end-$(CONFIG_WALNUT) := walnut
+ entrypoint-$(CONFIG_WALNUT) := 0x01000000
+ extra.o-$(CONFIG_WALNUT) := openbios.o
+
extra.o-$(CONFIG_EV64260) := misc-ev64260.o
end-$(CONFIG_EV64260) := ev64260
cacheflag-$(CONFIG_EV64260) := -include $(clear_L2_L3)
@@ -162,7 +186,8 @@ OBJCOPY_ARGS := -O elf32-powerpc
# head.o and relocate.o must be at the start.
boot-y := head.o relocate.o $(extra.o-y) $(misc-y)
-boot-$(CONFIG_40x) += embed_config.o
+boot-$(CONFIG_REDWOOD_5) += embed_config.o
+boot-$(CONFIG_REDWOOD_6) += embed_config.o
boot-$(CONFIG_8xx) += embed_config.o
boot-$(CONFIG_8260) += embed_config.o
boot-$(CONFIG_BSEIP) += iic.o
diff --git a/arch/ppc/boot/simple/misc.c b/arch/ppc/boot/simple/misc.c
index e02de5b467a4..f415d6c62362 100644
--- a/arch/ppc/boot/simple/misc.c
+++ b/arch/ppc/boot/simple/misc.c
@@ -23,7 +23,7 @@
#include <asm/page.h>
#include <asm/mmu.h>
#include <asm/bootinfo.h>
-#ifdef CONFIG_44x
+#ifdef CONFIG_4xx
#include <asm/ibm4xx.h>
#endif
#include <asm/reg.h>
@@ -88,6 +88,14 @@ get_mem_size(void)
return 0;
}
+#if defined(CONFIG_40x)
+#define PPC4xx_EMAC0_MR0 EMAC0_BASE
+#endif
+
+#if defined(CONFIG_44x) && defined(PPC44x_EMAC0_MR0)
+#define PPC4xx_EMAC0_MR0 PPC44x_EMAC0_MR0
+#endif
+
struct bi_record *
decompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum)
{
@@ -103,13 +111,13 @@ decompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum)
com_port = serial_init(0, NULL);
#endif
-#if defined(CONFIG_44x) && defined(PPC44x_EMAC0_MR0)
+#if defined(PPC4xx_EMAC0_MR0)
/* Reset MAL */
mtdcr(DCRN_MALCR(DCRN_MAL_BASE), MALCR_MMSR);
/* Wait for reset */
while (mfdcr(DCRN_MALCR(DCRN_MAL_BASE)) & MALCR_MMSR) {};
/* Reset EMAC */
- *(volatile unsigned long *)PPC44x_EMAC0_MR0 = 0x20000000;
+ *(volatile unsigned long *)PPC4xx_EMAC0_MR0 = 0x20000000;
__asm__ __volatile__("eieio");
#endif
@@ -164,7 +172,9 @@ decompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum)
puts(" "); puthex((unsigned long)(&__ramdisk_end));puts("\n");
}
+#ifndef CONFIG_40x /* don't overwrite the 40x image located at 0x00400000! */
avail_ram = (char *)0x00400000;
+#endif
end_avail = (char *)0x00800000;
puts("avail ram: "); puthex((unsigned long)avail_ram); puts(" ");
puthex((unsigned long)end_avail); puts("\n");
diff --git a/arch/ppc/boot/simple/openbios.c b/arch/ppc/boot/simple/openbios.c
index c732b6d70cfb..81f11d8b30a7 100644
--- a/arch/ppc/boot/simple/openbios.c
+++ b/arch/ppc/boot/simple/openbios.c
@@ -1,19 +1,43 @@
/*
* arch/ppc/boot/simple/openbios.c
*
- * 2005 (c) SYSGO AG - g.jaeger@sysgo.com
+ * Copyright (c) 2005 DENX Software Engineering
+ * Stefan Roese <sr@denx.de>
+ *
+ * Based on original work by
+ * 2005 (c) SYSGO AG - g.jaeger@sysgo.com
+ *
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without
* any warranty of any kind, whether express or implied.
*
- * Derived from arch/ppc/boot/simple/pibs.c (from MontaVista)
*/
#include <linux/types.h>
#include <linux/config.h>
#include <linux/string.h>
#include <asm/ppcboot.h>
-#include <platforms/4xx/ebony.h>
+#include <asm/ibm4xx.h>
+#include <asm/reg.h>
+#ifdef CONFIG_40x
+#include <asm/io.h>
+#endif
+
+#if defined(CONFIG_BUBINGA)
+#define BOARD_INFO_VECTOR 0xFFF80B50 /* openbios 1.19 moved this vector down - armin */
+#else
+#define BOARD_INFO_VECTOR 0xFFFE0B50
+#endif
+
+#ifdef CONFIG_40x
+/* Supply a default Ethernet address for those eval boards that don't
+ * ship with one. This is an address from the MBX board I have, so
+ * it is unlikely you will find it on your network.
+ */
+static ushort def_enet_addr[] = { 0x0800, 0x3e26, 0x1559 };
+
+extern unsigned long timebase_period_ns;
+#endif /* CONFIG_40x */
extern unsigned long decompress_kernel(unsigned long load_addr, int num_words,
unsigned long cksum);
@@ -23,15 +47,85 @@ extern unsigned long decompress_kernel(unsigned long load_addr, int num_words,
bd_t hold_resid_buf __attribute__ ((__section__ (".data.boot")));
bd_t *hold_residual = &hold_resid_buf;
+typedef struct openbios_board_info {
+ unsigned char bi_s_version[4]; /* Version of this structure */
+ unsigned char bi_r_version[30]; /* Version of the IBM ROM */
+ unsigned int bi_memsize; /* DRAM installed, in bytes */
+#ifdef CONFIG_405EP
+ unsigned char bi_enetaddr[2][6]; /* Local Ethernet MAC address */
+#else /* CONFIG_405EP */
+ unsigned char bi_enetaddr[6]; /* Local Ethernet MAC address */
+#endif /* CONFIG_405EP */
+ unsigned char bi_pci_enetaddr[6]; /* PCI Ethernet MAC address */
+ unsigned int bi_intfreq; /* Processor speed, in Hz */
+ unsigned int bi_busfreq; /* PLB Bus speed, in Hz */
+ unsigned int bi_pci_busfreq; /* PCI Bus speed, in Hz */
+#ifdef CONFIG_405EP
+ unsigned int bi_opb_busfreq; /* OPB Bus speed, in Hz */
+ unsigned int bi_pllouta_freq; /* PLL OUTA speed, in Hz */
+#endif /* CONFIG_405EP */
+} openbios_bd_t;
+
void *
load_kernel(unsigned long load_addr, int num_words, unsigned long cksum,
void *ign1, void *ign2)
{
- decompress_kernel(load_addr, num_words, cksum);
+#ifdef CONFIG_40x
+ openbios_bd_t *openbios_bd = NULL;
+ openbios_bd_t *(*get_board_info)(void) =
+ (openbios_bd_t *(*)(void))(*(unsigned long *)BOARD_INFO_VECTOR);
+
+ /*
+ * On 40x platforms we not only need the MAC-addresses, but also the
+ * clocks and memsize. Now try to get all values using the OpenBIOS
+ * "get_board_info()" callback.
+ */
+ if ((openbios_bd = get_board_info()) != NULL) {
+ /*
+ * Copy bd_info from OpenBIOS struct into U-Boot struct
+ * used by kernel
+ */
+ hold_residual->bi_memsize = openbios_bd->bi_memsize;
+ hold_residual->bi_intfreq = openbios_bd->bi_intfreq;
+ hold_residual->bi_busfreq = openbios_bd->bi_busfreq;
+ hold_residual->bi_pci_busfreq = openbios_bd->bi_pci_busfreq;
+ memcpy(hold_residual->bi_pci_enetaddr, openbios_bd->bi_pci_enetaddr, 6);
+#ifdef CONFIG_405EP
+ memcpy(hold_residual->bi_enetaddr, openbios_bd->bi_enetaddr[0], 6);
+ memcpy(hold_residual->bi_enet1addr, openbios_bd->bi_enetaddr[1], 6);
+ hold_residual->bi_opbfreq = openbios_bd->bi_opb_busfreq;
+ hold_residual->bi_procfreq = openbios_bd->bi_pllouta_freq;
+#else /* CONFIG_405EP */
+ memcpy(hold_residual->bi_enetaddr, openbios_bd->bi_enetaddr, 6);
+#endif /* CONFIG_405EP */
+ } else {
+ /* Hmmm...better try to stuff some defaults.
+ */
+ hold_residual->bi_memsize = 16 * 1024 * 1024;
+ hold_residual->bi_intfreq = 200000000;
+ hold_residual->bi_busfreq = 100000000;
+ hold_residual->bi_pci_busfreq = 66666666;
+
+ /*
+ * Only supply one mac-address in this fallback
+ */
+ memcpy(hold_residual->bi_enetaddr, (void *)def_enet_addr, 6);
+#ifdef CONFIG_405EP
+ hold_residual->bi_opbfreq = 50000000;
+ hold_residual->bi_procfreq = 200000000;
+#endif /* CONFIG_405EP */
+ }
+ timebase_period_ns = 1000000000 / hold_residual->bi_intfreq;
+#endif /* CONFIG_40x */
+
+#ifdef CONFIG_440GP
/* simply copy the MAC addresses */
- memcpy(hold_residual->bi_enetaddr, (char *)EBONY_OPENBIOS_MAC_BASE, 6);
- memcpy(hold_residual->bi_enet1addr, (char *)(EBONY_OPENBIOS_MAC_BASE+EBONY_OPENBIOS_MAC_OFFSET), 6);
+ memcpy(hold_residual->bi_enetaddr, (char *)OPENBIOS_MAC_BASE, 6);
+ memcpy(hold_residual->bi_enet1addr, (char *)(OPENBIOS_MAC_BASE+OPENBIOS_MAC_OFFSET), 6);
+#endif /* CONFIG_440GP */
+
+ decompress_kernel(load_addr, num_words, cksum);
return (void *)hold_residual;
}
diff --git a/arch/ppc/configs/ev64360_defconfig b/arch/ppc/configs/ev64360_defconfig
index de9bbb791db9..d471e578dcb5 100644
--- a/arch/ppc/configs/ev64360_defconfig
+++ b/arch/ppc/configs/ev64360_defconfig
@@ -1,17 +1,17 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.13-rc5
-# Fri Aug 5 15:18:23 2005
+# Linux kernel version: 2.6.14
+# Fri Oct 28 19:15:34 2005
#
CONFIG_MMU=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_RWSEM_XCHGADD_ALGORITHM=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_HAVE_DEC_LOCK=y
CONFIG_PPC=y
CONFIG_PPC32=y
CONFIG_GENERIC_NVRAM=y
CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
#
# Code maturity level options
@@ -26,6 +26,7 @@ CONFIG_INIT_ENV_ARG_LIMIT=32
# General setup
#
CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
CONFIG_POSIX_MQUEUE=y
@@ -35,6 +36,7 @@ CONFIG_SYSCTL=y
CONFIG_HOTPLUG=y
CONFIG_KOBJECT_UEVENT=y
# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
# CONFIG_EMBEDDED is not set
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
@@ -74,7 +76,7 @@ CONFIG_TAU=y
# CONFIG_TAU_AVERAGE is not set
# CONFIG_KEXEC is not set
# CONFIG_CPU_FREQ is not set
-# CONFIG_PM is not set
+# CONFIG_WANT_EARLY_SERIAL is not set
CONFIG_PPC_STD_MMU=y
CONFIG_NOT_COHERENT_CACHE=y
@@ -86,22 +88,18 @@ CONFIG_NOT_COHERENT_CACHE=y
# CONFIG_KATANA is not set
# CONFIG_WILLOW is not set
# CONFIG_CPCI690 is not set
-# CONFIG_PCORE is not set
# CONFIG_POWERPMC250 is not set
# CONFIG_CHESTNUT is not set
# CONFIG_SPRUCE is not set
# CONFIG_HDPU is not set
# CONFIG_EV64260 is not set
# CONFIG_LOPEC is not set
-# CONFIG_MCPN765 is not set
# CONFIG_MVME5100 is not set
# CONFIG_PPLUS is not set
# CONFIG_PRPMC750 is not set
# CONFIG_PRPMC800 is not set
# CONFIG_SANDPOINT is not set
# CONFIG_RADSTONE_PPC7D is not set
-# CONFIG_ADIR is not set
-# CONFIG_K2 is not set
# CONFIG_PAL4 is not set
# CONFIG_GEMINI is not set
# CONFIG_EST8260 is not set
@@ -138,10 +136,13 @@ CONFIG_FLATMEM_MANUAL=y
# CONFIG_SPARSEMEM_MANUAL is not set
CONFIG_FLATMEM=y
CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
CONFIG_BINFMT_ELF=y
CONFIG_BINFMT_MISC=y
CONFIG_CMDLINE_BOOL=y
CONFIG_CMDLINE="console=ttyMM0,115200 root=/dev/mtdblock1 rw rootfstype=jffs2"
+# CONFIG_PM is not set
+# CONFIG_SOFTWARE_SUSPEND is not set
CONFIG_SECCOMP=y
CONFIG_ISA_DMA_API=y
@@ -152,7 +153,6 @@ CONFIG_GENERIC_ISA_DMA=y
CONFIG_PCI=y
CONFIG_PCI_DOMAINS=y
# CONFIG_PCI_LEGACY_PROC is not set
-# CONFIG_PCI_NAMES is not set
#
# PCCARD (PCMCIA/CardBus) support
@@ -206,14 +206,19 @@ CONFIG_SYN_COOKIES=y
# CONFIG_INET_ESP is not set
# CONFIG_INET_IPCOMP is not set
# CONFIG_INET_TUNNEL is not set
-CONFIG_IP_TCPDIAG=y
-# CONFIG_IP_TCPDIAG_IPV6 is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
# CONFIG_TCP_CONG_ADVANCED is not set
CONFIG_TCP_CONG_BIC=y
# CONFIG_IPV6 is not set
# CONFIG_NETFILTER is not set
#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
# SCTP Configuration (EXPERIMENTAL)
#
# CONFIG_IP_SCTP is not set
@@ -239,6 +244,7 @@ CONFIG_TCP_CONG_BIC=y
# CONFIG_HAMRADIO is not set
# CONFIG_IRDA is not set
# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
#
# Device Drivers
@@ -252,6 +258,11 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_FW_LOADER is not set
#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+
+#
# Memory Technology Devices (MTD)
#
CONFIG_MTD=y
@@ -358,7 +369,6 @@ CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=32768
CONFIG_BLK_DEV_INITRD=y
-CONFIG_INITRAMFS_SOURCE=""
# CONFIG_LBD is not set
# CONFIG_CDROM_PKTCDVD is not set
@@ -379,6 +389,7 @@ CONFIG_IOSCHED_CFQ=y
#
# SCSI device support
#
+# CONFIG_RAID_ATTRS is not set
# CONFIG_SCSI is not set
#
@@ -420,6 +431,10 @@ CONFIG_NETDEVICES=y
# CONFIG_ARCNET is not set
#
+# PHY device support
+#
+
+#
# Ethernet (10 or 100Mbit)
#
# CONFIG_NET_ETHERNET is not set
@@ -434,6 +449,7 @@ CONFIG_NETDEVICES=y
# CONFIG_HAMACHI is not set
# CONFIG_YELLOWFIN is not set
# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
# CONFIG_SKGE is not set
# CONFIG_SK98LIN is not set
# CONFIG_TIGON3 is not set
@@ -446,6 +462,7 @@ CONFIG_MV643XX_ETH_0=y
#
# Ethernet (10000 Mbit)
#
+# CONFIG_CHELSIO_T1 is not set
# CONFIG_IXGB is not set
# CONFIG_S2IO is not set
@@ -547,7 +564,20 @@ CONFIG_LEGACY_PTY_COUNT=256
#
# Watchdog Cards
#
-# CONFIG_WATCHDOG is not set
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+CONFIG_MV64X60_WDT=y
+
+#
+# PCI-based Watchdog Cards
+#
+# CONFIG_PCIPCWATCHDOG is not set
+# CONFIG_WDTPCI is not set
# CONFIG_NVRAM is not set
CONFIG_GEN_RTC=y
# CONFIG_GEN_RTC_X is not set
@@ -571,7 +601,6 @@ CONFIG_GEN_RTC=y
# I2C support
#
# CONFIG_I2C is not set
-# CONFIG_I2C_SENSOR is not set
#
# Dallas's 1-wire bus
@@ -582,6 +611,7 @@ CONFIG_GEN_RTC=y
# Hardware Monitoring support
#
CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
# CONFIG_HWMON_DEBUG_CHIP is not set
#
@@ -589,6 +619,10 @@ CONFIG_HWMON=y
#
#
+# Multimedia Capabilities Port drivers
+#
+
+#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
@@ -651,10 +685,6 @@ CONFIG_EXT2_FS=y
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
# CONFIG_FS_POSIX_ACL is not set
-
-#
-# XFS support
-#
# CONFIG_XFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
@@ -663,6 +693,7 @@ CONFIG_INOTIFY=y
CONFIG_DNOTIFY=y
# CONFIG_AUTOFS_FS is not set
# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
#
# CD-ROM/DVD Filesystems
@@ -683,11 +714,10 @@ CONFIG_DNOTIFY=y
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_SYSFS=y
-# CONFIG_DEVPTS_FS_XATTR is not set
CONFIG_TMPFS=y
-# CONFIG_TMPFS_XATTR is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
+# CONFIG_RELAYFS_FS is not set
#
# Miscellaneous filesystems
@@ -735,6 +765,7 @@ CONFIG_SUNRPC=y
# CONFIG_NCP_FS is not set
# CONFIG_CODA_FS is not set
# CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
#
# Partition Types
@@ -751,6 +782,7 @@ CONFIG_MSDOS_PARTITION=y
# Library routines
#
# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
CONFIG_CRC32=y
# CONFIG_LIBCRC32C is not set
CONFIG_ZLIB_INFLATE=y
@@ -767,6 +799,7 @@ CONFIG_ZLIB_DEFLATE=y
# CONFIG_PRINTK_TIME is not set
# CONFIG_DEBUG_KERNEL is not set
CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_SERIAL_TEXT_DEBUG is not set
#
# Security options
diff --git a/arch/ppc/configs/mpc834x_sys_defconfig b/arch/ppc/configs/mpc834x_sys_defconfig
index 4a5522ca8207..673dc64ebcb1 100644
--- a/arch/ppc/configs/mpc834x_sys_defconfig
+++ b/arch/ppc/configs/mpc834x_sys_defconfig
@@ -1,16 +1,17 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-rc4
-# Thu Feb 17 16:12:23 2005
+# Linux kernel version: 2.6.14
+# Mon Nov 7 15:38:29 2005
#
CONFIG_MMU=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_RWSEM_XCHGADD_ALGORITHM=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_HAVE_DEC_LOCK=y
CONFIG_PPC=y
CONFIG_PPC32=y
CONFIG_GENERIC_NVRAM=y
+CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
#
# Code maturity level options
@@ -18,23 +19,28 @@ CONFIG_GENERIC_NVRAM=y
CONFIG_EXPERIMENTAL=y
CONFIG_CLEAN_COMPILE=y
CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
#
# General setup
#
CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
# CONFIG_POSIX_MQUEUE is not set
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
# CONFIG_HOTPLUG is not set
CONFIG_KOBJECT_UEVENT=y
# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
CONFIG_EMBEDDED=y
# CONFIG_KALLSYMS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
# CONFIG_EPOLL is not set
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
@@ -44,6 +50,7 @@ CONFIG_CC_ALIGN_LABELS=0
CONFIG_CC_ALIGN_LOOPS=0
CONFIG_CC_ALIGN_JUMPS=0
# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
#
# Loadable module support
@@ -59,34 +66,84 @@ CONFIG_6xx=y
# CONFIG_POWER3 is not set
# CONFIG_POWER4 is not set
# CONFIG_8xx is not set
+# CONFIG_E200 is not set
# CONFIG_E500 is not set
+CONFIG_PPC_FPU=y
+# CONFIG_KEXEC is not set
# CONFIG_CPU_FREQ is not set
+# CONFIG_WANT_EARLY_SERIAL is not set
CONFIG_PPC_GEN550=y
-CONFIG_83xx=y
-
-#
-# Freescale 83xx options
-#
-CONFIG_MPC834x_SYS=y
-CONFIG_MPC834x=y
CONFIG_PPC_STD_MMU=y
#
# Platform options
#
+# CONFIG_PPC_MULTIPLATFORM is not set
+# CONFIG_APUS is not set
+# CONFIG_KATANA is not set
+# CONFIG_WILLOW is not set
+# CONFIG_CPCI690 is not set
+# CONFIG_POWERPMC250 is not set
+# CONFIG_CHESTNUT is not set
+# CONFIG_SPRUCE is not set
+# CONFIG_HDPU is not set
+# CONFIG_EV64260 is not set
+# CONFIG_LOPEC is not set
+# CONFIG_MVME5100 is not set
+# CONFIG_PPLUS is not set
+# CONFIG_PRPMC750 is not set
+# CONFIG_PRPMC800 is not set
+# CONFIG_SANDPOINT is not set
+# CONFIG_RADSTONE_PPC7D is not set
+# CONFIG_PAL4 is not set
+# CONFIG_GEMINI is not set
+# CONFIG_EST8260 is not set
+# CONFIG_SBC82xx is not set
+# CONFIG_SBS8260 is not set
+# CONFIG_RPX8260 is not set
+# CONFIG_TQM8260 is not set
+# CONFIG_ADS8272 is not set
+# CONFIG_PQ2FADS is not set
+# CONFIG_LITE5200 is not set
+CONFIG_MPC834x_SYS=y
+# CONFIG_EV64360 is not set
+CONFIG_83xx=y
+CONFIG_MPC834x=y
# CONFIG_SMP is not set
-# CONFIG_PREEMPT is not set
# CONFIG_HIGHMEM is not set
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4
CONFIG_BINFMT_ELF=y
# CONFIG_BINFMT_MISC is not set
# CONFIG_CMDLINE_BOOL is not set
+# CONFIG_PM is not set
+# CONFIG_SOFTWARE_SUSPEND is not set
+CONFIG_SECCOMP=y
+CONFIG_ISA_DMA_API=y
#
# Bus options
#
CONFIG_GENERIC_ISA_DMA=y
-# CONFIG_PCI is not set
-# CONFIG_PCI_DOMAINS is not set
+# CONFIG_PPC_I8259 is not set
+CONFIG_PPC_INDIRECT_PCI=y
+CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
+# CONFIG_MPC83xx_PCI2 is not set
+CONFIG_PCI_LEGACY_PROC=y
#
# PCCARD (PCMCIA/CardBus) support
@@ -94,10 +151,6 @@ CONFIG_GENERIC_ISA_DMA=y
# CONFIG_PCCARD is not set
#
-# PC-card bridges
-#
-
-#
# Advanced setup
#
# CONFIG_ADVANCED_OPTIONS is not set
@@ -112,6 +165,75 @@ CONFIG_TASK_SIZE=0x80000000
CONFIG_BOOT_LOAD=0x00800000
#
+# Networking
+#
+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=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+# CONFIG_IPV6 is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# 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_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
+
+#
# Device Drivers
#
@@ -123,6 +245,11 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_FW_LOADER is not set
#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+
+#
# Memory Technology Devices (MTD)
#
# CONFIG_MTD is not set
@@ -140,15 +267,19 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
# Block devices
#
# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
# CONFIG_BLK_DEV_COW_COMMON is not set
CONFIG_BLK_DEV_LOOP=y
# CONFIG_BLK_DEV_CRYPTOLOOP is not set
# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_SX8 is not set
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=32768
CONFIG_BLK_DEV_INITRD=y
-CONFIG_INITRAMFS_SOURCE=""
# CONFIG_LBD is not set
# CONFIG_CDROM_PKTCDVD is not set
@@ -159,6 +290,11 @@ 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_ATA_OVER_ETH is not set
#
@@ -169,6 +305,7 @@ CONFIG_IOSCHED_CFQ=y
#
# SCSI device support
#
+# CONFIG_RAID_ATTRS is not set
# CONFIG_SCSI is not set
#
@@ -179,110 +316,116 @@ CONFIG_IOSCHED_CFQ=y
#
# Fusion MPT device support
#
+# CONFIG_FUSION is not set
#
# IEEE 1394 (FireWire) support
#
+# CONFIG_IEEE1394 is not set
#
# I2O device support
#
+# CONFIG_I2O is not set
#
# Macintosh device drivers
#
#
-# Networking support
+# Network device support
#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
-# CONFIG_NETLINK_DEV is not set
-CONFIG_UNIX=y
-# CONFIG_NET_KEY is not set
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-# CONFIG_IP_ADVANCED_ROUTER is not set
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-CONFIG_IP_PNP_BOOTP=y
-# CONFIG_IP_PNP_RARP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_IP_MROUTE is not set
-# CONFIG_ARPD is not set
-CONFIG_SYN_COOKIES=y
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-# CONFIG_INET_TUNNEL is not set
-CONFIG_IP_TCPDIAG=y
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-# CONFIG_IPV6 is not set
-# CONFIG_NETFILTER is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
#
-# SCTP Configuration (EXPERIMENTAL)
+# ARCnet devices
#
-# CONFIG_IP_SCTP 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_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
+# CONFIG_ARCNET is not set
#
-# QoS and/or fair queueing
+# PHY device support
#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
+CONFIG_PHYLIB=y
#
-# Network testing
+# MII PHY device drivers
#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
-CONFIG_NETDEVICES=y
-# CONFIG_DUMMY is not set
-# CONFIG_BONDING is not set
-# CONFIG_EQUALIZER is not set
-# CONFIG_TUN is not set
+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
#
# Ethernet (10 or 100Mbit)
#
CONFIG_NET_ETHERNET=y
CONFIG_MII=y
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_CASSINI is not set
+# CONFIG_NET_VENDOR_3COM is not set
+
+#
+# Tulip family network device support
+#
+# CONFIG_NET_TULIP is not set
+# CONFIG_HP100 is not set
+CONFIG_NET_PCI=y
+# CONFIG_PCNET32 is not set
+# CONFIG_AMD8111_ETH is not set
+# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_B44 is not set
+# CONFIG_FORCEDETH is not set
+# CONFIG_DGRS is not set
+# CONFIG_EEPRO100 is not set
+CONFIG_E100=y
+# CONFIG_FEALNX is not set
+# CONFIG_NATSEMI is not set
+# CONFIG_NE2K_PCI is not set
+# CONFIG_8139CP is not set
+# CONFIG_8139TOO is not set
+# CONFIG_SIS900 is not set
+# CONFIG_EPIC100 is not set
+# CONFIG_SUNDANCE is not set
+# CONFIG_TLAN is not set
+# CONFIG_VIA_RHINE is not set
#
# Ethernet (1000 Mbit)
#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+CONFIG_E1000=y
+# CONFIG_E1000_NAPI is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_VIA_VELOCITY is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
CONFIG_GIANFAR=y
# CONFIG_GFAR_NAPI is not set
#
# Ethernet (10000 Mbit)
#
+# CONFIG_CHELSIO_T1 is not set
+# CONFIG_IXGB is not set
+# CONFIG_S2IO is not set
#
# Token Ring devices
#
+# CONFIG_TR is not set
#
# Wireless LAN (non-hamradio)
@@ -293,10 +436,14 @@ CONFIG_GIANFAR=y
# Wan interfaces
#
# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
# CONFIG_PPP is not set
# CONFIG_SLIP is not set
# CONFIG_SHAPER is not set
# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
#
# ISDN subsystem
@@ -323,14 +470,6 @@ CONFIG_INPUT=y
# CONFIG_INPUT_EVBUG is not set
#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-# CONFIG_SERIO is not set
-# CONFIG_SERIO_I8042 is not set
-
-#
# Input Device Drivers
#
# CONFIG_INPUT_KEYBOARD is not set
@@ -340,6 +479,12 @@ CONFIG_SOUND_GAMEPORT=y
# CONFIG_INPUT_MISC is not set
#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
# Character devices
#
# CONFIG_VT is not set
@@ -358,6 +503,7 @@ CONFIG_SERIAL_8250_NR_UARTS=4
#
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
CONFIG_UNIX98_PTYS=y
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
@@ -376,6 +522,7 @@ CONFIG_GEN_RTC=y
# CONFIG_GEN_RTC_X is not set
# CONFIG_DTLK is not set
# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
#
# Ftape, the floppy tape device driver
@@ -385,6 +532,12 @@ CONFIG_GEN_RTC=y
# CONFIG_RAW_DRIVER is not set
#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+# CONFIG_TELCLOCK is not set
+
+#
# I2C support
#
CONFIG_I2C=y
@@ -400,23 +553,68 @@ CONFIG_I2C_CHARDEV=y
#
# I2C Hardware Bus support
#
-# CONFIG_I2C_ISA is not set
+# 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_PIIX4 is not set
CONFIG_I2C_MPC=y
+# CONFIG_I2C_NFORCE2 is not set
# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_PROSAVAGE is not set
+# CONFIG_I2C_SAVAGE4 is not set
+# CONFIG_SCx200_ACB is not set
+# CONFIG_I2C_SIS5595 is not set
+# CONFIG_I2C_SIS630 is not set
+# CONFIG_I2C_SIS96X is not set
+# CONFIG_I2C_VIA is not set
+# CONFIG_I2C_VIAPRO is not set
+# CONFIG_I2C_VOODOO3 is not set
# CONFIG_I2C_PCA_ISA is not set
#
-# Hardware Sensors Chip support
+# Miscellaneous I2C Chip support
+#
+# CONFIG_SENSORS_DS1337 is not set
+# CONFIG_SENSORS_DS1374 is not set
+# CONFIG_SENSORS_EEPROM is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_SENSORS_PCA9539 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_SENSORS_RTC8564 is not set
+# CONFIG_SENSORS_M41T00 is not set
+# CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_RTC_X1205_I2C 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
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Hardware Monitoring support
#
-# CONFIG_I2C_SENSOR is not set
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
# CONFIG_SENSORS_ADM1021 is not set
# CONFIG_SENSORS_ADM1025 is not set
# CONFIG_SENSORS_ADM1026 is not set
# CONFIG_SENSORS_ADM1031 is not set
+# CONFIG_SENSORS_ADM9240 is not set
# CONFIG_SENSORS_ASB100 is not set
+# CONFIG_SENSORS_ATXP1 is not set
# CONFIG_SENSORS_DS1621 is not set
# CONFIG_SENSORS_FSCHER is not set
+# CONFIG_SENSORS_FSCPOS is not set
# CONFIG_SENSORS_GL518SM is not set
+# CONFIG_SENSORS_GL520SM is not set
# CONFIG_SENSORS_IT87 is not set
# CONFIG_SENSORS_LM63 is not set
# CONFIG_SENSORS_LM75 is not set
@@ -427,33 +625,26 @@ CONFIG_I2C_MPC=y
# CONFIG_SENSORS_LM85 is not set
# CONFIG_SENSORS_LM87 is not set
# CONFIG_SENSORS_LM90 is not set
+# CONFIG_SENSORS_LM92 is not set
# CONFIG_SENSORS_MAX1619 is not set
# CONFIG_SENSORS_PC87360 is not set
-# CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_SIS5595 is not set
# CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_VIA686A is not set
# CONFIG_SENSORS_W83781D is not set
+# CONFIG_SENSORS_W83792D is not set
# CONFIG_SENSORS_W83L785TS is not set
# CONFIG_SENSORS_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
#
-# Other I2C Chip support
-#
-# CONFIG_SENSORS_EEPROM is not set
-# CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_SENSORS_PCF8591 is not set
-# CONFIG_SENSORS_RTC8564 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
-
-#
-# Dallas's 1-wire bus
+# Misc devices
#
-# CONFIG_W1 is not set
#
-# Misc devices
+# Multimedia Capabilities Port drivers
#
#
@@ -479,11 +670,12 @@ CONFIG_I2C_MPC=y
#
# USB support
#
-# CONFIG_USB_ARCH_HAS_HCD is not set
-# CONFIG_USB_ARCH_HAS_OHCI is not set
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+# CONFIG_USB is not set
#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
#
#
@@ -502,10 +694,15 @@ CONFIG_I2C_MPC=y
# CONFIG_INFINIBAND is not set
#
+# SN Devices
+#
+
+#
# File systems
#
CONFIG_EXT2_FS=y
# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
CONFIG_EXT3_FS=y
CONFIG_EXT3_FS_XATTR=y
# CONFIG_EXT3_FS_POSIX_ACL is not set
@@ -515,17 +712,16 @@ CONFIG_JBD=y
CONFIG_FS_MBCACHE=y
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
-
-#
-# XFS support
-#
+# CONFIG_FS_POSIX_ACL is not set
# CONFIG_XFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
# CONFIG_QUOTA is not set
CONFIG_DNOTIFY=y
# CONFIG_AUTOFS_FS is not set
# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
#
# CD-ROM/DVD Filesystems
@@ -546,12 +742,10 @@ CONFIG_DNOTIFY=y
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
-# CONFIG_DEVPTS_FS_XATTR is not set
CONFIG_TMPFS=y
-# CONFIG_TMPFS_XATTR is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
+# CONFIG_RELAYFS_FS is not set
#
# Miscellaneous filesystems
@@ -580,6 +774,7 @@ CONFIG_NFS_FS=y
# CONFIG_NFSD is not set
CONFIG_ROOT_NFS=y
CONFIG_LOCKD=y
+CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
@@ -588,6 +783,7 @@ CONFIG_SUNRPC=y
# CONFIG_NCP_FS is not set
# CONFIG_CODA_FS is not set
# CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
#
# Partition Types
@@ -614,6 +810,7 @@ CONFIG_PARTITION_ADVANCED=y
# Library routines
#
# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
CONFIG_CRC32=y
# CONFIG_LIBCRC32C is not set
@@ -625,7 +822,9 @@ CONFIG_CRC32=y
#
# Kernel hacking
#
+# CONFIG_PRINTK_TIME is not set
# CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=14
# CONFIG_SERIAL_TEXT_DEBUG is not set
#
diff --git a/arch/ppc/configs/stx_gp3_defconfig b/arch/ppc/configs/stx_gp3_defconfig
index 66dae8367659..3fedc43e44ad 100644
--- a/arch/ppc/configs/stx_gp3_defconfig
+++ b/arch/ppc/configs/stx_gp3_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-rc2
-# Wed Jan 26 14:32:58 2005
+# Linux kernel version: 2.6.12-rc4
+# Tue May 24 18:11:04 2005
#
CONFIG_MMU=y
CONFIG_GENERIC_HARDIRQS=y
@@ -11,6 +11,7 @@ CONFIG_HAVE_DEC_LOCK=y
CONFIG_PPC=y
CONFIG_PPC32=y
CONFIG_GENERIC_NVRAM=y
+CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
#
# Code maturity level options
@@ -18,6 +19,7 @@ CONFIG_GENERIC_NVRAM=y
CONFIG_EXPERIMENTAL=y
CONFIG_CLEAN_COMPILE=y
CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
#
# General setup
@@ -29,7 +31,6 @@ CONFIG_SYSVIPC=y
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
CONFIG_HOTPLUG=y
CONFIG_KOBJECT_UEVENT=y
# CONFIG_IKCONFIG is not set
@@ -37,6 +38,9 @@ CONFIG_EMBEDDED=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_ALL is not set
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
@@ -46,6 +50,7 @@ CONFIG_CC_ALIGN_LABELS=0
CONFIG_CC_ALIGN_LOOPS=0
CONFIG_CC_ALIGN_JUMPS=0
# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
#
# Loadable module support
@@ -69,9 +74,11 @@ CONFIG_KMOD=y
CONFIG_E500=y
CONFIG_BOOKE=y
CONFIG_FSL_BOOKE=y
+# CONFIG_PHYS_64BIT is not set
# CONFIG_SPE is not set
CONFIG_MATH_EMULATION=y
# CONFIG_CPU_FREQ is not set
+# CONFIG_PM is not set
CONFIG_85xx=y
CONFIG_PPC_INDIRECT_PCI_BE=y
@@ -96,6 +103,7 @@ CONFIG_HIGHMEM=y
CONFIG_BINFMT_ELF=y
CONFIG_BINFMT_MISC=m
# CONFIG_CMDLINE_BOOL is not set
+CONFIG_ISA_DMA_API=y
#
# Bus options
@@ -104,15 +112,15 @@ CONFIG_PCI=y
CONFIG_PCI_DOMAINS=y
# CONFIG_PCI_LEGACY_PROC is not set
# CONFIG_PCI_NAMES is not set
+# CONFIG_PCI_DEBUG is not set
#
# PCCARD (PCMCIA/CardBus) support
#
# CONFIG_PCCARD is not set
-
-#
-# PC-card bridges
-#
+CONFIG_RAPIDIO=y
+CONFIG_RAPIDIO_8_BIT_TRANSPORT=y
+CONFIG_RAPIDIO_DISC_TIMEOUT=30
#
# Advanced setup
@@ -152,7 +160,7 @@ CONFIG_PARPORT=m
CONFIG_PARPORT_PC=m
# CONFIG_PARPORT_PC_FIFO is not set
# CONFIG_PARPORT_PC_SUPERIO is not set
-# CONFIG_PARPORT_OTHER is not set
+# CONFIG_PARPORT_GSC is not set
# CONFIG_PARPORT_1284 is not set
#
@@ -264,7 +272,6 @@ CONFIG_SCSI_CONSTANTS=y
# CONFIG_SCSI_BUSLOGIC is not set
# CONFIG_SCSI_DMX3191D is not set
# CONFIG_SCSI_EATA is not set
-# CONFIG_SCSI_EATA_PIO is not set
# CONFIG_SCSI_FUTURE_DOMAIN is not set
# CONFIG_SCSI_GDTH is not set
# CONFIG_SCSI_IPS is not set
@@ -274,7 +281,6 @@ CONFIG_SCSI_CONSTANTS=y
# CONFIG_SCSI_IMM is not set
# CONFIG_SCSI_SYM53C8XX_2 is not set
# CONFIG_SCSI_IPR is not set
-# CONFIG_SCSI_QLOGIC_ISP is not set
# CONFIG_SCSI_QLOGIC_FC is not set
# CONFIG_SCSI_QLOGIC_1280 is not set
CONFIG_SCSI_QLA2XXX=m
@@ -283,6 +289,7 @@ CONFIG_SCSI_QLA2XXX=m
# CONFIG_SCSI_QLA2300 is not set
# CONFIG_SCSI_QLA2322 is not set
# CONFIG_SCSI_QLA6312 is not set
+# CONFIG_SCSI_LPFC is not set
# CONFIG_SCSI_DC395x is not set
# CONFIG_SCSI_DC390T is not set
# CONFIG_SCSI_NSP32 is not set
@@ -322,7 +329,6 @@ CONFIG_NET=y
#
CONFIG_PACKET=y
# CONFIG_PACKET_MMAP is not set
-# CONFIG_NETLINK_DEV is not set
CONFIG_UNIX=y
# CONFIG_NET_KEY is not set
CONFIG_INET=y
@@ -431,7 +437,7 @@ CONFIG_IP_NF_NAT_FTP=m
#
# Network testing
#
-# CONFIG_NET_PKTGEN is not set
+CONFIG_NET_PKTGEN=y
# CONFIG_NETPOLL is not set
# CONFIG_NET_POLL_CONTROLLER is not set
# CONFIG_HAMRADIO is not set
@@ -499,6 +505,7 @@ CONFIG_GFAR_NAPI=y
# Wan interfaces
#
# CONFIG_WAN is not set
+CONFIG_RIONET=y
# CONFIG_FDDI is not set
# CONFIG_HIPPI is not set
# CONFIG_PLIP is not set
@@ -536,20 +543,6 @@ CONFIG_INPUT_EVDEV=m
# CONFIG_INPUT_EVBUG is not set
#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=y
-CONFIG_SERIO_I8042=y
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_PARKBD is not set
-# CONFIG_SERIO_PCIPS2 is not set
-CONFIG_SERIO_LIBPS2=y
-# CONFIG_SERIO_RAW is not set
-
-#
# Input Device Drivers
#
CONFIG_INPUT_KEYBOARD=y
@@ -567,6 +560,19 @@ CONFIG_MOUSE_PS2=y
# CONFIG_INPUT_MISC is not set
#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_I8042=y
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_PARKBD is not set
+# CONFIG_SERIO_PCIPS2 is not set
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+CONFIG_SOUND_GAMEPORT=y
+
+#
# Character devices
#
# CONFIG_VT is not set
@@ -590,6 +596,7 @@ CONFIG_SERIAL_CPM_SCC2=y
# CONFIG_SERIAL_CPM_SCC4 is not set
# CONFIG_SERIAL_CPM_SMC1 is not set
# CONFIG_SERIAL_CPM_SMC2 is not set
+# CONFIG_SERIAL_JSM is not set
CONFIG_UNIX98_PTYS=y
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
@@ -626,6 +633,11 @@ CONFIG_DRM=m
# CONFIG_RAW_DRIVER is not set
#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+
+#
# I2C support
#
CONFIG_I2C=m
@@ -648,12 +660,12 @@ CONFIG_I2C_ALGOBIT=m
# CONFIG_I2C_AMD8111 is not set
# CONFIG_I2C_I801 is not set
# CONFIG_I2C_I810 is not set
+# CONFIG_I2C_PIIX4 is not set
# CONFIG_I2C_ISA is not set
# CONFIG_I2C_MPC is not set
# CONFIG_I2C_NFORCE2 is not set
# CONFIG_I2C_PARPORT is not set
# CONFIG_I2C_PARPORT_LIGHT is not set
-# CONFIG_I2C_PIIX4 is not set
# CONFIG_I2C_PROSAVAGE is not set
# CONFIG_I2C_SAVAGE4 is not set
# CONFIG_SCx200_ACB is not set
@@ -677,7 +689,9 @@ CONFIG_I2C_ALGOBIT=m
# CONFIG_SENSORS_ASB100 is not set
# CONFIG_SENSORS_DS1621 is not set
# CONFIG_SENSORS_FSCHER is not set
+# CONFIG_SENSORS_FSCPOS is not set
# CONFIG_SENSORS_GL518SM is not set
+# CONFIG_SENSORS_GL520SM is not set
# CONFIG_SENSORS_IT87 is not set
# CONFIG_SENSORS_LM63 is not set
# CONFIG_SENSORS_LM75 is not set
@@ -688,9 +702,11 @@ CONFIG_I2C_ALGOBIT=m
# CONFIG_SENSORS_LM85 is not set
# CONFIG_SENSORS_LM87 is not set
# CONFIG_SENSORS_LM90 is not set
+# CONFIG_SENSORS_LM92 is not set
# CONFIG_SENSORS_MAX1619 is not set
# CONFIG_SENSORS_PC87360 is not set
# CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_SIS5595 is not set
# CONFIG_SENSORS_SMSC47M1 is not set
# CONFIG_SENSORS_VIA686A is not set
# CONFIG_SENSORS_W83781D is not set
@@ -700,10 +716,12 @@ CONFIG_I2C_ALGOBIT=m
#
# Other I2C Chip support
#
+# CONFIG_SENSORS_DS1337 is not set
# CONFIG_SENSORS_EEPROM is not set
# CONFIG_SENSORS_PCF8574 is not set
# CONFIG_SENSORS_PCF8591 is not set
# CONFIG_SENSORS_RTC8564 is not set
+# CONFIG_SENSORS_M41T00 is not set
# CONFIG_I2C_DEBUG_CORE is not set
# CONFIG_I2C_DEBUG_ALGO is not set
# CONFIG_I2C_DEBUG_BUS is not set
@@ -732,7 +750,6 @@ CONFIG_I2C_ALGOBIT=m
# Graphics support
#
# CONFIG_FB is not set
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Sound
@@ -752,13 +769,9 @@ CONFIG_SOUND=m
#
# USB support
#
-# CONFIG_USB is not set
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB_ARCH_HAS_OHCI=y
-
-#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
-#
+# CONFIG_USB is not set
#
# USB Gadget Support
@@ -789,6 +802,10 @@ CONFIG_JBD_DEBUG=y
CONFIG_FS_MBCACHE=y
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
+
+#
+# XFS support
+#
# CONFIG_XFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
@@ -859,7 +876,6 @@ CONFIG_NFS_V3=y
CONFIG_ROOT_NFS=y
CONFIG_LOCKD=y
CONFIG_LOCKD_V4=y
-# CONFIG_EXPORTFS is not set
CONFIG_SUNRPC=y
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
@@ -942,8 +958,10 @@ CONFIG_ZLIB_INFLATE=m
#
# Kernel hacking
#
+# CONFIG_PRINTK_TIME is not set
CONFIG_DEBUG_KERNEL=y
# CONFIG_MAGIC_SYSRQ is not set
+CONFIG_LOG_BUF_SHIFT=14
# CONFIG_SCHEDSTATS is not set
# CONFIG_DEBUG_SLAB is not set
# CONFIG_DEBUG_SPINLOCK is not set
diff --git a/arch/ppc/kernel/Makefile b/arch/ppc/kernel/Makefile
index b1457a8a9c0f..17a4da65e275 100644
--- a/arch/ppc/kernel/Makefile
+++ b/arch/ppc/kernel/Makefile
@@ -1,6 +1,7 @@
#
# Makefile for the linux kernel.
#
+ifneq ($(CONFIG_PPC_MERGE),y)
extra-$(CONFIG_PPC_STD_MMU) := head.o
extra-$(CONFIG_40x) := head_4xx.o
@@ -9,23 +10,22 @@ extra-$(CONFIG_FSL_BOOKE) := head_fsl_booke.o
extra-$(CONFIG_8xx) := head_8xx.o
extra-$(CONFIG_6xx) += idle_6xx.o
extra-$(CONFIG_POWER4) += idle_power4.o
-extra-$(CONFIG_PPC_FPU) += fpu.o
extra-y += vmlinux.lds
-obj-y := entry.o traps.o irq.o idle.o time.o misc.o \
- process.o signal.o ptrace.o align.o \
- semaphore.o syscalls.o setup.o \
- cputable.o ppc_htab.o perfmon.o
+obj-y := entry.o traps.o idle.o time.o misc.o \
+ process.o align.o \
+ setup.o \
+ ppc_htab.o
obj-$(CONFIG_6xx) += l2cr.o cpu_setup_6xx.o
obj-$(CONFIG_SOFTWARE_SUSPEND) += swsusp.o
obj-$(CONFIG_POWER4) += cpu_setup_power4.o
obj-$(CONFIG_MODULES) += module.o ppc_ksyms.o
obj-$(CONFIG_NOT_COHERENT_CACHE) += dma-mapping.o
obj-$(CONFIG_PCI) += pci.o
+obj-$(CONFIG_RAPIDIO) += rio.o
obj-$(CONFIG_KGDB) += ppc-stub.o
obj-$(CONFIG_SMP) += smp.o smp-tbsync.o
obj-$(CONFIG_TAU) += temp.o
-obj-$(CONFIG_ALTIVEC) += vecemu.o vector.o
ifndef CONFIG_E200
obj-$(CONFIG_FSL_BOOKE) += perfmon_fsl_booke.o
endif
@@ -35,3 +35,19 @@ ifndef CONFIG_MATH_EMULATION
obj-$(CONFIG_8xx) += softemu8xx.o
endif
+# These are here while we do the architecture merge
+
+else
+obj-y := idle.o align.o
+obj-$(CONFIG_6xx) += l2cr.o cpu_setup_6xx.o
+obj-$(CONFIG_SOFTWARE_SUSPEND) += swsusp.o
+obj-$(CONFIG_MODULES) += module.o
+obj-$(CONFIG_NOT_COHERENT_CACHE) += dma-mapping.o
+obj-$(CONFIG_PCI) += pci.o
+obj-$(CONFIG_KGDB) += ppc-stub.o
+obj-$(CONFIG_TAU) += temp.o
+ifndef CONFIG_E200
+obj-$(CONFIG_FSL_BOOKE) += perfmon_fsl_booke.o
+endif
+obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o
+endif
diff --git a/arch/ppc/kernel/align.c b/arch/ppc/kernel/align.c
index ff81da9598d8..ab398c4b70b6 100644
--- a/arch/ppc/kernel/align.c
+++ b/arch/ppc/kernel/align.c
@@ -375,7 +375,7 @@ fix_alignment(struct pt_regs *regs)
#ifdef CONFIG_PPC_FPU
preempt_disable();
enable_kernel_fp();
- cvt_fd(&data.f, &data.d, &current->thread.fpscr);
+ cvt_fd(&data.f, &data.d, &current->thread);
preempt_enable();
#else
return 0;
@@ -385,7 +385,7 @@ fix_alignment(struct pt_regs *regs)
#ifdef CONFIG_PPC_FPU
preempt_disable();
enable_kernel_fp();
- cvt_df(&data.d, &data.f, &current->thread.fpscr);
+ cvt_df(&data.d, &data.f, &current->thread);
preempt_enable();
#else
return 0;
diff --git a/arch/ppc/kernel/asm-offsets.c b/arch/ppc/kernel/asm-offsets.c
index d9ad1d776d0e..968261d69572 100644
--- a/arch/ppc/kernel/asm-offsets.c
+++ b/arch/ppc/kernel/asm-offsets.c
@@ -130,10 +130,10 @@ main(void)
DEFINE(CPU_SPEC_FEATURES, offsetof(struct cpu_spec, cpu_features));
DEFINE(CPU_SPEC_SETUP, offsetof(struct cpu_spec, cpu_setup));
+ DEFINE(TI_SC_NOERR, offsetof(struct thread_info, syscall_noerror));
DEFINE(TI_TASK, offsetof(struct thread_info, task));
DEFINE(TI_EXECDOMAIN, offsetof(struct thread_info, exec_domain));
DEFINE(TI_FLAGS, offsetof(struct thread_info, flags));
- DEFINE(TI_LOCAL_FLAGS, offsetof(struct thread_info, local_flags));
DEFINE(TI_CPU, offsetof(struct thread_info, cpu));
DEFINE(TI_PREEMPT, offsetof(struct thread_info, preempt_count));
@@ -141,6 +141,7 @@ main(void)
DEFINE(pbe_orig_address, offsetof(struct pbe, orig_address));
DEFINE(pbe_next, offsetof(struct pbe, next));
+ DEFINE(TASK_SIZE, TASK_SIZE);
DEFINE(NUM_USER_SEGMENTS, TASK_SIZE>>28);
return 0;
}
diff --git a/arch/ppc/kernel/bitops.c b/arch/ppc/kernel/bitops.c
deleted file mode 100644
index 7f53d193968b..000000000000
--- a/arch/ppc/kernel/bitops.c
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Copyright (C) 1996 Paul Mackerras.
- */
-
-#include <linux/kernel.h>
-#include <linux/bitops.h>
-
-/*
- * If the bitops are not inlined in bitops.h, they are defined here.
- * -- paulus
- */
-#if !__INLINE_BITOPS
-void set_bit(int nr, volatile void * addr)
-{
- unsigned long old;
- unsigned long mask = 1 << (nr & 0x1f);
- unsigned long *p = ((unsigned long *)addr) + (nr >> 5);
-
- __asm__ __volatile__(SMP_WMB "\n\
-1: lwarx %0,0,%3 \n\
- or %0,%0,%2 \n"
- PPC405_ERR77(0,%3)
-" stwcx. %0,0,%3 \n\
- bne 1b"
- SMP_MB
- : "=&r" (old), "=m" (*p)
- : "r" (mask), "r" (p), "m" (*p)
- : "cc" );
-}
-
-void clear_bit(int nr, volatile void *addr)
-{
- unsigned long old;
- unsigned long mask = 1 << (nr & 0x1f);
- unsigned long *p = ((unsigned long *)addr) + (nr >> 5);
-
- __asm__ __volatile__(SMP_WMB "\n\
-1: lwarx %0,0,%3 \n\
- andc %0,%0,%2 \n"
- PPC405_ERR77(0,%3)
-" stwcx. %0,0,%3 \n\
- bne 1b"
- SMP_MB
- : "=&r" (old), "=m" (*p)
- : "r" (mask), "r" (p), "m" (*p)
- : "cc");
-}
-
-void change_bit(int nr, volatile void *addr)
-{
- unsigned long old;
- unsigned long mask = 1 << (nr & 0x1f);
- unsigned long *p = ((unsigned long *)addr) + (nr >> 5);
-
- __asm__ __volatile__(SMP_WMB "\n\
-1: lwarx %0,0,%3 \n\
- xor %0,%0,%2 \n"
- PPC405_ERR77(0,%3)
-" stwcx. %0,0,%3 \n\
- bne 1b"
- SMP_MB
- : "=&r" (old), "=m" (*p)
- : "r" (mask), "r" (p), "m" (*p)
- : "cc");
-}
-
-int test_and_set_bit(int nr, volatile void *addr)
-{
- unsigned int old, t;
- unsigned int mask = 1 << (nr & 0x1f);
- volatile unsigned int *p = ((volatile unsigned int *)addr) + (nr >> 5);
-
- __asm__ __volatile__(SMP_WMB "\n\
-1: lwarx %0,0,%4 \n\
- or %1,%0,%3 \n"
- PPC405_ERR77(0,%4)
-" stwcx. %1,0,%4 \n\
- bne 1b"
- SMP_MB
- : "=&r" (old), "=&r" (t), "=m" (*p)
- : "r" (mask), "r" (p), "m" (*p)
- : "cc");
-
- return (old & mask) != 0;
-}
-
-int test_and_clear_bit(int nr, volatile void *addr)
-{
- unsigned int old, t;
- unsigned int mask = 1 << (nr & 0x1f);
- volatile unsigned int *p = ((volatile unsigned int *)addr) + (nr >> 5);
-
- __asm__ __volatile__(SMP_WMB "\n\
-1: lwarx %0,0,%4 \n\
- andc %1,%0,%3 \n"
- PPC405_ERR77(0,%4)
-" stwcx. %1,0,%4 \n\
- bne 1b"
- SMP_MB
- : "=&r" (old), "=&r" (t), "=m" (*p)
- : "r" (mask), "r" (p), "m" (*p)
- : "cc");
-
- return (old & mask) != 0;
-}
-
-int test_and_change_bit(int nr, volatile void *addr)
-{
- unsigned int old, t;
- unsigned int mask = 1 << (nr & 0x1f);
- volatile unsigned int *p = ((volatile unsigned int *)addr) + (nr >> 5);
-
- __asm__ __volatile__(SMP_WMB "\n\
-1: lwarx %0,0,%4 \n\
- xor %1,%0,%3 \n"
- PPC405_ERR77(0,%4)
-" stwcx. %1,0,%4 \n\
- bne 1b"
- SMP_MB
- : "=&r" (old), "=&r" (t), "=m" (*p)
- : "r" (mask), "r" (p), "m" (*p)
- : "cc");
-
- return (old & mask) != 0;
-}
-#endif /* !__INLINE_BITOPS */
diff --git a/arch/ppc/kernel/cpu_setup_6xx.S b/arch/ppc/kernel/cpu_setup_6xx.S
index ba396438ede3..55ed7716636f 100644
--- a/arch/ppc/kernel/cpu_setup_6xx.S
+++ b/arch/ppc/kernel/cpu_setup_6xx.S
@@ -17,8 +17,6 @@
#include <asm/asm-offsets.h>
#include <asm/cache.h>
-_GLOBAL(__setup_cpu_601)
- blr
_GLOBAL(__setup_cpu_603)
b setup_common_caches
_GLOBAL(__setup_cpu_604)
@@ -292,10 +290,10 @@ _GLOBAL(__init_fpu_registers)
#define CS_SIZE 32
.data
- .balign L1_CACHE_LINE_SIZE
+ .balign L1_CACHE_BYTES
cpu_state_storage:
.space CS_SIZE
- .balign L1_CACHE_LINE_SIZE,0
+ .balign L1_CACHE_BYTES,0
.text
/* Called in normal context to backup CPU 0 state. This
diff --git a/arch/ppc/kernel/cpu_setup_power4.S b/arch/ppc/kernel/cpu_setup_power4.S
index 7e4fbb653724..d7bfd60e21fc 100644
--- a/arch/ppc/kernel/cpu_setup_power4.S
+++ b/arch/ppc/kernel/cpu_setup_power4.S
@@ -63,8 +63,6 @@ _GLOBAL(__970_cpu_preinit)
isync
blr
-_GLOBAL(__setup_cpu_power4)
- blr
_GLOBAL(__setup_cpu_ppc970)
mfspr r0,SPRN_HID0
li r11,5 /* clear DOZE and SLEEP */
@@ -88,10 +86,10 @@ _GLOBAL(__setup_cpu_ppc970)
#define CS_SIZE 32
.data
- .balign L1_CACHE_LINE_SIZE
+ .balign L1_CACHE_BYTES
cpu_state_storage:
.space CS_SIZE
- .balign L1_CACHE_LINE_SIZE,0
+ .balign L1_CACHE_BYTES,0
.text
/* Called in normal context to backup CPU 0 state. This
diff --git a/arch/ppc/kernel/dma-mapping.c b/arch/ppc/kernel/dma-mapping.c
index 8edee806dae7..685fd0defe23 100644
--- a/arch/ppc/kernel/dma-mapping.c
+++ b/arch/ppc/kernel/dma-mapping.c
@@ -115,7 +115,7 @@ static struct vm_region consistent_head = {
};
static struct vm_region *
-vm_region_alloc(struct vm_region *head, size_t size, int gfp)
+vm_region_alloc(struct vm_region *head, size_t size, gfp_t gfp)
{
unsigned long addr = head->vm_start, end = head->vm_end - size;
unsigned long flags;
@@ -173,7 +173,7 @@ static struct vm_region *vm_region_find(struct vm_region *head, unsigned long ad
* virtual and bus address for that space.
*/
void *
-__dma_alloc_coherent(size_t size, dma_addr_t *handle, int gfp)
+__dma_alloc_coherent(size_t size, dma_addr_t *handle, gfp_t gfp)
{
struct page *page;
struct vm_region *c;
@@ -335,8 +335,6 @@ static int __init dma_alloc_init(void)
pte_t *pte;
int ret = 0;
- spin_lock(&init_mm.page_table_lock);
-
do {
pgd = pgd_offset(&init_mm, CONSISTENT_BASE);
pmd = pmd_alloc(&init_mm, pgd, CONSISTENT_BASE);
@@ -347,7 +345,7 @@ static int __init dma_alloc_init(void)
}
WARN_ON(!pmd_none(*pmd));
- pte = pte_alloc_kernel(&init_mm, pmd, CONSISTENT_BASE);
+ pte = pte_alloc_kernel(pmd, CONSISTENT_BASE);
if (!pte) {
printk(KERN_ERR "%s: no pte tables\n", __func__);
ret = -ENOMEM;
@@ -357,8 +355,6 @@ static int __init dma_alloc_init(void)
consistent_pte = pte;
} while (0);
- spin_unlock(&init_mm.page_table_lock);
-
return ret;
}
diff --git a/arch/ppc/kernel/entry.S b/arch/ppc/kernel/entry.S
index 03d4886869f3..f044edbb454f 100644
--- a/arch/ppc/kernel/entry.S
+++ b/arch/ppc/kernel/entry.S
@@ -200,9 +200,8 @@ _GLOBAL(DoSyscall)
bl do_show_syscall
#endif /* SHOW_SYSCALLS */
rlwinm r10,r1,0,0,18 /* current_thread_info() */
- lwz r11,TI_LOCAL_FLAGS(r10)
- rlwinm r11,r11,0,~_TIFL_FORCE_NOERROR
- stw r11,TI_LOCAL_FLAGS(r10)
+ li r11,0
+ stb r11,TI_SC_NOERR(r10)
lwz r11,TI_FLAGS(r10)
andi. r11,r11,_TIF_SYSCALL_T_OR_A
bne- syscall_dotrace
@@ -227,8 +226,8 @@ ret_from_syscall:
cmplw 0,r3,r11
rlwinm r12,r1,0,0,18 /* current_thread_info() */
blt+ 30f
- lwz r11,TI_LOCAL_FLAGS(r12)
- andi. r11,r11,_TIFL_FORCE_NOERROR
+ lbz r11,TI_SC_NOERR(r12)
+ cmpwi r11,0
bne 30f
neg r3,r3
lwz r10,_CCR(r1) /* Set SO bit in CR */
@@ -633,7 +632,8 @@ sigreturn_exit:
rlwinm r12,r1,0,0,18 /* current_thread_info() */
lwz r9,TI_FLAGS(r12)
andi. r0,r9,_TIF_SYSCALL_T_OR_A
- bnel- do_syscall_trace_leave
+ beq+ ret_from_except_full
+ bl do_syscall_trace_leave
/* fall through */
.globl ret_from_except_full
diff --git a/arch/ppc/kernel/head.S b/arch/ppc/kernel/head.S
index 1960fb8c259c..c5a890dca9cf 100644
--- a/arch/ppc/kernel/head.S
+++ b/arch/ppc/kernel/head.S
@@ -349,12 +349,12 @@ i##n: \
/* System reset */
/* core99 pmac starts the seconary here by changing the vector, and
- putting it back to what it was (UnknownException) when done. */
+ putting it back to what it was (unknown_exception) when done. */
#if defined(CONFIG_GEMINI) && defined(CONFIG_SMP)
. = 0x100
b __secondary_start_gemini
#else
- EXCEPTION(0x100, Reset, UnknownException, EXC_XFER_STD)
+ EXCEPTION(0x100, Reset, unknown_exception, EXC_XFER_STD)
#endif
/* Machine check */
@@ -389,7 +389,7 @@ i##n: \
cmpwi cr1,r4,0
bne cr1,1f
#endif
- EXC_XFER_STD(0x200, MachineCheckException)
+ EXC_XFER_STD(0x200, machine_check_exception)
#ifdef CONFIG_PPC_CHRP
1: b machine_check_in_rtas
#endif
@@ -456,10 +456,10 @@ Alignment:
mfspr r5,SPRN_DSISR
stw r5,_DSISR(r11)
addi r3,r1,STACK_FRAME_OVERHEAD
- EXC_XFER_EE(0x600, AlignmentException)
+ EXC_XFER_EE(0x600, alignment_exception)
/* Program check exception */
- EXCEPTION(0x700, ProgramCheck, ProgramCheckException, EXC_XFER_STD)
+ EXCEPTION(0x700, ProgramCheck, program_check_exception, EXC_XFER_STD)
/* Floating-point unavailable */
. = 0x800
@@ -467,13 +467,13 @@ FPUnavailable:
EXCEPTION_PROLOG
bne load_up_fpu /* if from user, just load it up */
addi r3,r1,STACK_FRAME_OVERHEAD
- EXC_XFER_EE_LITE(0x800, KernelFP)
+ EXC_XFER_EE_LITE(0x800, kernel_fp_unavailable_exception)
/* Decrementer */
EXCEPTION(0x900, Decrementer, timer_interrupt, EXC_XFER_LITE)
- EXCEPTION(0xa00, Trap_0a, UnknownException, EXC_XFER_EE)
- EXCEPTION(0xb00, Trap_0b, UnknownException, EXC_XFER_EE)
+ EXCEPTION(0xa00, Trap_0a, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0xb00, Trap_0b, unknown_exception, EXC_XFER_EE)
/* System call */
. = 0xc00
@@ -482,8 +482,8 @@ SystemCall:
EXC_XFER_EE_LITE(0xc00, DoSyscall)
/* Single step - not used on 601 */
- EXCEPTION(0xd00, SingleStep, SingleStepException, EXC_XFER_STD)
- EXCEPTION(0xe00, Trap_0e, UnknownException, EXC_XFER_EE)
+ EXCEPTION(0xd00, SingleStep, single_step_exception, EXC_XFER_STD)
+ EXCEPTION(0xe00, Trap_0e, unknown_exception, EXC_XFER_EE)
/*
* The Altivec unavailable trap is at 0x0f20. Foo.
@@ -502,7 +502,7 @@ SystemCall:
Trap_0f:
EXCEPTION_PROLOG
addi r3,r1,STACK_FRAME_OVERHEAD
- EXC_XFER_EE(0xf00, UnknownException)
+ EXC_XFER_EE(0xf00, unknown_exception)
/*
* Handle TLB miss for instruction on 603/603e.
@@ -702,44 +702,44 @@ DataStoreTLBMiss:
rfi
#ifndef CONFIG_ALTIVEC
-#define AltivecAssistException UnknownException
+#define altivec_assist_exception unknown_exception
#endif
- EXCEPTION(0x1300, Trap_13, InstructionBreakpoint, EXC_XFER_EE)
+ EXCEPTION(0x1300, Trap_13, instruction_breakpoint_exception, EXC_XFER_EE)
EXCEPTION(0x1400, SMI, SMIException, EXC_XFER_EE)
- EXCEPTION(0x1500, Trap_15, UnknownException, EXC_XFER_EE)
+ EXCEPTION(0x1500, Trap_15, unknown_exception, EXC_XFER_EE)
#ifdef CONFIG_POWER4
- EXCEPTION(0x1600, Trap_16, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x1700, Trap_17, AltivecAssistException, EXC_XFER_EE)
+ EXCEPTION(0x1600, Trap_16, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x1700, Trap_17, altivec_assist_exception, EXC_XFER_EE)
EXCEPTION(0x1800, Trap_18, TAUException, EXC_XFER_STD)
#else /* !CONFIG_POWER4 */
- EXCEPTION(0x1600, Trap_16, AltivecAssistException, EXC_XFER_EE)
+ EXCEPTION(0x1600, Trap_16, altivec_assist_exception, EXC_XFER_EE)
EXCEPTION(0x1700, Trap_17, TAUException, EXC_XFER_STD)
- EXCEPTION(0x1800, Trap_18, UnknownException, EXC_XFER_EE)
+ EXCEPTION(0x1800, Trap_18, unknown_exception, EXC_XFER_EE)
#endif /* CONFIG_POWER4 */
- EXCEPTION(0x1900, Trap_19, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x1a00, Trap_1a, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x1b00, Trap_1b, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x1c00, Trap_1c, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x1d00, Trap_1d, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x1e00, Trap_1e, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x1f00, Trap_1f, UnknownException, EXC_XFER_EE)
+ EXCEPTION(0x1900, Trap_19, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x1a00, Trap_1a, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x1b00, Trap_1b, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x1c00, Trap_1c, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x1d00, Trap_1d, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x1e00, Trap_1e, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x1f00, Trap_1f, unknown_exception, EXC_XFER_EE)
EXCEPTION(0x2000, RunMode, RunModeException, EXC_XFER_EE)
- EXCEPTION(0x2100, Trap_21, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x2200, Trap_22, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x2300, Trap_23, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x2400, Trap_24, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x2500, Trap_25, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x2600, Trap_26, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x2700, Trap_27, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x2800, Trap_28, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x2900, Trap_29, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x2a00, Trap_2a, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x2b00, Trap_2b, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x2c00, Trap_2c, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x2d00, Trap_2d, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x2e00, Trap_2e, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x2f00, MOLTrampoline, UnknownException, EXC_XFER_EE_LITE)
+ EXCEPTION(0x2100, Trap_21, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x2200, Trap_22, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x2300, Trap_23, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x2400, Trap_24, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x2500, Trap_25, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x2600, Trap_26, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x2700, Trap_27, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x2800, Trap_28, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x2900, Trap_29, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x2a00, Trap_2a, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x2b00, Trap_2b, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x2c00, Trap_2c, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x2d00, Trap_2d, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x2e00, Trap_2e, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x2f00, MOLTrampoline, unknown_exception, EXC_XFER_EE_LITE)
.globl mol_trampoline
.set mol_trampoline, i0x2f00
@@ -751,7 +751,7 @@ AltiVecUnavailable:
#ifdef CONFIG_ALTIVEC
bne load_up_altivec /* if from user, just load it up */
#endif /* CONFIG_ALTIVEC */
- EXC_XFER_EE_LITE(0xf20, AltivecUnavailException)
+ EXC_XFER_EE_LITE(0xf20, altivec_unavailable_exception)
#ifdef CONFIG_PPC64BRIDGE
DataAccess:
@@ -767,12 +767,12 @@ DataSegment:
addi r3,r1,STACK_FRAME_OVERHEAD
mfspr r4,SPRN_DAR
stw r4,_DAR(r11)
- EXC_XFER_STD(0x380, UnknownException)
+ EXC_XFER_STD(0x380, unknown_exception)
InstructionSegment:
EXCEPTION_PROLOG
addi r3,r1,STACK_FRAME_OVERHEAD
- EXC_XFER_STD(0x480, UnknownException)
+ EXC_XFER_STD(0x480, unknown_exception)
#endif /* CONFIG_PPC64BRIDGE */
#ifdef CONFIG_ALTIVEC
@@ -804,7 +804,7 @@ load_up_altivec:
beq 1f
add r4,r4,r6
addi r4,r4,THREAD /* want THREAD of last_task_used_altivec */
- SAVE_32VR(0,r10,r4)
+ SAVE_32VRS(0,r10,r4)
mfvscr vr0
li r10,THREAD_VSCR
stvx vr0,r10,r4
@@ -824,7 +824,7 @@ load_up_altivec:
stw r4,THREAD_USED_VR(r5)
lvx vr0,r10,r5
mtvscr vr0
- REST_32VR(0,r10,r5)
+ REST_32VRS(0,r10,r5)
#ifndef CONFIG_SMP
subi r4,r5,THREAD
sub r4,r4,r6
@@ -870,7 +870,7 @@ giveup_altivec:
addi r3,r3,THREAD /* want THREAD of task */
lwz r5,PT_REGS(r3)
cmpwi 0,r5,0
- SAVE_32VR(0, r4, r3)
+ SAVE_32VRS(0, r4, r3)
mfvscr vr0
li r4,THREAD_VSCR
stvx vr0,r4,r3
@@ -916,7 +916,7 @@ relocate_kernel:
copy_and_flush:
addi r5,r5,-4
addi r6,r6,-4
-4: li r0,L1_CACHE_LINE_SIZE/4
+4: li r0,L1_CACHE_BYTES/4
mtctr r0
3: addi r6,r6,4 /* copy a cache line */
lwzx r0,r6,r4
@@ -1059,7 +1059,6 @@ __secondary_start:
lis r3,-KERNELBASE@h
mr r4,r24
- bl identify_cpu
bl call_setup_cpu /* Call setup_cpu for this CPU */
#ifdef CONFIG_6xx
lis r3,-KERNELBASE@h
@@ -1109,11 +1108,6 @@ __secondary_start:
* Those generic dummy functions are kept for CPUs not
* included in CONFIG_6xx
*/
-_GLOBAL(__setup_cpu_power3)
- blr
-_GLOBAL(__setup_cpu_generic)
- blr
-
#if !defined(CONFIG_6xx) && !defined(CONFIG_POWER4)
_GLOBAL(__save_cpu_setup)
blr
diff --git a/arch/ppc/kernel/head_44x.S b/arch/ppc/kernel/head_44x.S
index 599245b0407e..677c571aa276 100644
--- a/arch/ppc/kernel/head_44x.S
+++ b/arch/ppc/kernel/head_44x.S
@@ -190,8 +190,8 @@ skpinv: addi r4,r4,1 /* Increment */
/* xlat fields */
lis r4,UART0_PHYS_IO_BASE@h /* RPN depends on SoC */
-#ifndef CONFIG_440EP
- ori r4,r4,0x0001 /* ERPN is 1 for second 4GB page */
+#ifdef UART0_PHYS_ERPN
+ ori r4,r4,UART0_PHYS_ERPN /* Add ERPN if above 4GB */
#endif
/* attrib fields */
@@ -309,13 +309,13 @@ skpinv: addi r4,r4,1 /* Increment */
interrupt_base:
/* Critical Input Interrupt */
- CRITICAL_EXCEPTION(0x0100, CriticalInput, UnknownException)
+ CRITICAL_EXCEPTION(0x0100, CriticalInput, unknown_exception)
/* Machine Check Interrupt */
#ifdef CONFIG_440A
- MCHECK_EXCEPTION(0x0200, MachineCheck, MachineCheckException)
+ MCHECK_EXCEPTION(0x0200, MachineCheck, machine_check_exception)
#else
- CRITICAL_EXCEPTION(0x0200, MachineCheck, MachineCheckException)
+ CRITICAL_EXCEPTION(0x0200, MachineCheck, machine_check_exception)
#endif
/* Data Storage Interrupt */
@@ -442,7 +442,7 @@ interrupt_base:
#ifdef CONFIG_PPC_FPU
FP_UNAVAILABLE_EXCEPTION
#else
- EXCEPTION(0x2010, FloatingPointUnavailable, UnknownException, EXC_XFER_EE)
+ EXCEPTION(0x2010, FloatingPointUnavailable, unknown_exception, EXC_XFER_EE)
#endif
/* System Call Interrupt */
@@ -451,21 +451,21 @@ interrupt_base:
EXC_XFER_EE_LITE(0x0c00, DoSyscall)
/* Auxillary Processor Unavailable Interrupt */
- EXCEPTION(0x2020, AuxillaryProcessorUnavailable, UnknownException, EXC_XFER_EE)
+ EXCEPTION(0x2020, AuxillaryProcessorUnavailable, unknown_exception, EXC_XFER_EE)
/* Decrementer Interrupt */
DECREMENTER_EXCEPTION
/* Fixed Internal Timer Interrupt */
/* TODO: Add FIT support */
- EXCEPTION(0x1010, FixedIntervalTimer, UnknownException, EXC_XFER_EE)
+ EXCEPTION(0x1010, FixedIntervalTimer, unknown_exception, EXC_XFER_EE)
/* Watchdog Timer Interrupt */
/* TODO: Add watchdog support */
#ifdef CONFIG_BOOKE_WDT
CRITICAL_EXCEPTION(0x1020, WatchdogTimer, WatchdogException)
#else
- CRITICAL_EXCEPTION(0x1020, WatchdogTimer, UnknownException)
+ CRITICAL_EXCEPTION(0x1020, WatchdogTimer, unknown_exception)
#endif
/* Data TLB Error Interrupt */
@@ -743,14 +743,18 @@ _GLOBAL(set_context)
* goes at the beginning of the data segment, which is page-aligned.
*/
.data
-_GLOBAL(sdata)
-_GLOBAL(empty_zero_page)
+ .align 12
+ .globl sdata
+sdata:
+ .globl empty_zero_page
+empty_zero_page:
.space 4096
/*
* To support >32-bit physical addresses, we use an 8KB pgdir.
*/
-_GLOBAL(swapper_pg_dir)
+ .globl swapper_pg_dir
+swapper_pg_dir:
.space 8192
/* Reserved 4k for the critical exception stack & 4k for the machine
@@ -759,13 +763,15 @@ _GLOBAL(swapper_pg_dir)
.align 12
exception_stack_bottom:
.space BOOKE_EXCEPTION_STACK_SIZE
-_GLOBAL(exception_stack_top)
+ .globl exception_stack_top
+exception_stack_top:
/*
* This space gets a copy of optional info passed to us by the bootstrap
* which is used to pass parameters into the kernel like root=/dev/sda1, etc.
*/
-_GLOBAL(cmd_line)
+ .globl cmd_line
+cmd_line:
.space 512
/*
@@ -774,5 +780,3 @@ _GLOBAL(cmd_line)
*/
abatron_pteptrs:
.space 8
-
-
diff --git a/arch/ppc/kernel/head_4xx.S b/arch/ppc/kernel/head_4xx.S
index 8562b807b37c..10c261c67021 100644
--- a/arch/ppc/kernel/head_4xx.S
+++ b/arch/ppc/kernel/head_4xx.S
@@ -245,12 +245,12 @@ label:
/*
* 0x0100 - Critical Interrupt Exception
*/
- CRITICAL_EXCEPTION(0x0100, CriticalInterrupt, UnknownException)
+ CRITICAL_EXCEPTION(0x0100, CriticalInterrupt, unknown_exception)
/*
* 0x0200 - Machine Check Exception
*/
- CRITICAL_EXCEPTION(0x0200, MachineCheck, MachineCheckException)
+ CRITICAL_EXCEPTION(0x0200, MachineCheck, machine_check_exception)
/*
* 0x0300 - Data Storage Exception
@@ -405,7 +405,7 @@ label:
mfspr r4,SPRN_DEAR /* Grab the DEAR and save it */
stw r4,_DEAR(r11)
addi r3,r1,STACK_FRAME_OVERHEAD
- EXC_XFER_EE(0x600, AlignmentException)
+ EXC_XFER_EE(0x600, alignment_exception)
/* 0x0700 - Program Exception */
START_EXCEPTION(0x0700, ProgramCheck)
@@ -413,21 +413,21 @@ label:
mfspr r4,SPRN_ESR /* Grab the ESR and save it */
stw r4,_ESR(r11)
addi r3,r1,STACK_FRAME_OVERHEAD
- EXC_XFER_STD(0x700, ProgramCheckException)
+ EXC_XFER_STD(0x700, program_check_exception)
- EXCEPTION(0x0800, Trap_08, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x0900, Trap_09, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x0A00, Trap_0A, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x0B00, Trap_0B, UnknownException, EXC_XFER_EE)
+ EXCEPTION(0x0800, Trap_08, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x0900, Trap_09, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x0A00, Trap_0A, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x0B00, Trap_0B, unknown_exception, EXC_XFER_EE)
/* 0x0C00 - System Call Exception */
START_EXCEPTION(0x0C00, SystemCall)
NORMAL_EXCEPTION_PROLOG
EXC_XFER_EE_LITE(0xc00, DoSyscall)
- EXCEPTION(0x0D00, Trap_0D, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x0E00, Trap_0E, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x0F00, Trap_0F, UnknownException, EXC_XFER_EE)
+ EXCEPTION(0x0D00, Trap_0D, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x0E00, Trap_0E, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x0F00, Trap_0F, unknown_exception, EXC_XFER_EE)
/* 0x1000 - Programmable Interval Timer (PIT) Exception */
START_EXCEPTION(0x1000, Decrementer)
@@ -444,14 +444,14 @@ label:
/* 0x1010 - Fixed Interval Timer (FIT) Exception
*/
- STND_EXCEPTION(0x1010, FITException, UnknownException)
+ STND_EXCEPTION(0x1010, FITException, unknown_exception)
/* 0x1020 - Watchdog Timer (WDT) Exception
*/
#ifdef CONFIG_BOOKE_WDT
CRITICAL_EXCEPTION(0x1020, WDTException, WatchdogException)
#else
- CRITICAL_EXCEPTION(0x1020, WDTException, UnknownException)
+ CRITICAL_EXCEPTION(0x1020, WDTException, unknown_exception)
#endif
#endif
@@ -656,25 +656,25 @@ label:
mfspr r10, SPRN_SPRG0
b InstructionAccess
- EXCEPTION(0x1300, Trap_13, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x1400, Trap_14, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x1500, Trap_15, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x1600, Trap_16, UnknownException, EXC_XFER_EE)
+ EXCEPTION(0x1300, Trap_13, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x1400, Trap_14, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x1500, Trap_15, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x1600, Trap_16, unknown_exception, EXC_XFER_EE)
#ifdef CONFIG_IBM405_ERR51
/* 405GP errata 51 */
START_EXCEPTION(0x1700, Trap_17)
b DTLBMiss
#else
- EXCEPTION(0x1700, Trap_17, UnknownException, EXC_XFER_EE)
+ EXCEPTION(0x1700, Trap_17, unknown_exception, EXC_XFER_EE)
#endif
- EXCEPTION(0x1800, Trap_18, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x1900, Trap_19, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x1A00, Trap_1A, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x1B00, Trap_1B, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x1C00, Trap_1C, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x1D00, Trap_1D, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x1E00, Trap_1E, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x1F00, Trap_1F, UnknownException, EXC_XFER_EE)
+ EXCEPTION(0x1800, Trap_18, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x1900, Trap_19, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x1A00, Trap_1A, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x1B00, Trap_1B, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x1C00, Trap_1C, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x1D00, Trap_1D, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x1E00, Trap_1E, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x1F00, Trap_1F, unknown_exception, EXC_XFER_EE)
/* Check for a single step debug exception while in an exception
* handler before state has been saved. This is to catch the case
@@ -988,10 +988,14 @@ _GLOBAL(set_context)
* goes at the beginning of the data segment, which is page-aligned.
*/
.data
-_GLOBAL(sdata)
-_GLOBAL(empty_zero_page)
+ .align 12
+ .globl sdata
+sdata:
+ .globl empty_zero_page
+empty_zero_page:
.space 4096
-_GLOBAL(swapper_pg_dir)
+ .globl swapper_pg_dir
+swapper_pg_dir:
.space 4096
@@ -1001,12 +1005,14 @@ _GLOBAL(swapper_pg_dir)
exception_stack_bottom:
.space 4096
critical_stack_top:
-_GLOBAL(exception_stack_top)
+ .globl exception_stack_top
+exception_stack_top:
/* This space gets a copy of optional info passed to us by the bootstrap
* which is used to pass parameters into the kernel like root=/dev/sda1, etc.
*/
-_GLOBAL(cmd_line)
+ .globl cmd_line
+cmd_line:
.space 512
/* Room for two PTE pointers, usually the kernel and current user pointers
diff --git a/arch/ppc/kernel/head_8xx.S b/arch/ppc/kernel/head_8xx.S
index cb1a3a54a026..de0978742221 100644
--- a/arch/ppc/kernel/head_8xx.S
+++ b/arch/ppc/kernel/head_8xx.S
@@ -203,7 +203,7 @@ i##n: \
ret_from_except)
/* System reset */
- EXCEPTION(0x100, Reset, UnknownException, EXC_XFER_STD)
+ EXCEPTION(0x100, Reset, unknown_exception, EXC_XFER_STD)
/* Machine check */
. = 0x200
@@ -214,7 +214,7 @@ MachineCheck:
mfspr r5,SPRN_DSISR
stw r5,_DSISR(r11)
addi r3,r1,STACK_FRAME_OVERHEAD
- EXC_XFER_STD(0x200, MachineCheckException)
+ EXC_XFER_STD(0x200, machine_check_exception)
/* Data access exception.
* This is "never generated" by the MPC8xx. We jump to it for other
@@ -252,20 +252,20 @@ Alignment:
mfspr r5,SPRN_DSISR
stw r5,_DSISR(r11)
addi r3,r1,STACK_FRAME_OVERHEAD
- EXC_XFER_EE(0x600, AlignmentException)
+ EXC_XFER_EE(0x600, alignment_exception)
/* Program check exception */
- EXCEPTION(0x700, ProgramCheck, ProgramCheckException, EXC_XFER_STD)
+ EXCEPTION(0x700, ProgramCheck, program_check_exception, EXC_XFER_STD)
/* No FPU on MPC8xx. This exception is not supposed to happen.
*/
- EXCEPTION(0x800, FPUnavailable, UnknownException, EXC_XFER_STD)
+ EXCEPTION(0x800, FPUnavailable, unknown_exception, EXC_XFER_STD)
/* Decrementer */
EXCEPTION(0x900, Decrementer, timer_interrupt, EXC_XFER_LITE)
- EXCEPTION(0xa00, Trap_0a, UnknownException, EXC_XFER_EE)
- EXCEPTION(0xb00, Trap_0b, UnknownException, EXC_XFER_EE)
+ EXCEPTION(0xa00, Trap_0a, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0xb00, Trap_0b, unknown_exception, EXC_XFER_EE)
/* System call */
. = 0xc00
@@ -274,9 +274,9 @@ SystemCall:
EXC_XFER_EE_LITE(0xc00, DoSyscall)
/* Single step - not used on 601 */
- EXCEPTION(0xd00, SingleStep, SingleStepException, EXC_XFER_STD)
- EXCEPTION(0xe00, Trap_0e, UnknownException, EXC_XFER_EE)
- EXCEPTION(0xf00, Trap_0f, UnknownException, EXC_XFER_EE)
+ EXCEPTION(0xd00, SingleStep, single_step_exception, EXC_XFER_STD)
+ EXCEPTION(0xe00, Trap_0e, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0xf00, Trap_0f, unknown_exception, EXC_XFER_EE)
/* On the MPC8xx, this is a software emulation interrupt. It occurs
* for all unimplemented and illegal instructions.
@@ -540,22 +540,22 @@ DataTLBError:
#endif
b DataAccess
- EXCEPTION(0x1500, Trap_15, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x1600, Trap_16, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x1700, Trap_17, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x1800, Trap_18, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x1900, Trap_19, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x1a00, Trap_1a, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x1b00, Trap_1b, UnknownException, EXC_XFER_EE)
+ EXCEPTION(0x1500, Trap_15, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x1600, Trap_16, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x1700, Trap_17, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x1800, Trap_18, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x1900, Trap_19, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x1a00, Trap_1a, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x1b00, Trap_1b, unknown_exception, EXC_XFER_EE)
/* On the MPC8xx, these next four traps are used for development
* support of breakpoints and such. Someday I will get around to
* using them.
*/
- EXCEPTION(0x1c00, Trap_1c, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x1d00, Trap_1d, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x1e00, Trap_1e, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x1f00, Trap_1f, UnknownException, EXC_XFER_EE)
+ EXCEPTION(0x1c00, Trap_1c, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x1d00, Trap_1d, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x1e00, Trap_1e, unknown_exception, EXC_XFER_EE)
+ EXCEPTION(0x1f00, Trap_1f, unknown_exception, EXC_XFER_EE)
. = 0x2000
diff --git a/arch/ppc/kernel/head_booke.h b/arch/ppc/kernel/head_booke.h
index 9342acf12e72..f3d274c6b231 100644
--- a/arch/ppc/kernel/head_booke.h
+++ b/arch/ppc/kernel/head_booke.h
@@ -335,7 +335,7 @@ label:
mfspr r4,SPRN_DEAR; /* Grab the DEAR and save it */ \
stw r4,_DEAR(r11); \
addi r3,r1,STACK_FRAME_OVERHEAD; \
- EXC_XFER_EE(0x0600, AlignmentException)
+ EXC_XFER_EE(0x0600, alignment_exception)
#define PROGRAM_EXCEPTION \
START_EXCEPTION(Program) \
@@ -343,7 +343,7 @@ label:
mfspr r4,SPRN_ESR; /* Grab the ESR and save it */ \
stw r4,_ESR(r11); \
addi r3,r1,STACK_FRAME_OVERHEAD; \
- EXC_XFER_STD(0x0700, ProgramCheckException)
+ EXC_XFER_STD(0x0700, program_check_exception)
#define DECREMENTER_EXCEPTION \
START_EXCEPTION(Decrementer) \
@@ -358,6 +358,6 @@ label:
NORMAL_EXCEPTION_PROLOG; \
bne load_up_fpu; /* if from user, just load it up */ \
addi r3,r1,STACK_FRAME_OVERHEAD; \
- EXC_XFER_EE_LITE(0x800, KernelFP)
+ EXC_XFER_EE_LITE(0x800, kernel_fp_unavailable_exception)
#endif /* __HEAD_BOOKE_H__ */
diff --git a/arch/ppc/kernel/head_fsl_booke.S b/arch/ppc/kernel/head_fsl_booke.S
index 8e52e8408316..5063c603fad4 100644
--- a/arch/ppc/kernel/head_fsl_booke.S
+++ b/arch/ppc/kernel/head_fsl_booke.S
@@ -426,14 +426,14 @@ skpinv: addi r6,r6,1 /* Increment */
interrupt_base:
/* Critical Input Interrupt */
- CRITICAL_EXCEPTION(0x0100, CriticalInput, UnknownException)
+ CRITICAL_EXCEPTION(0x0100, CriticalInput, unknown_exception)
/* Machine Check Interrupt */
#ifdef CONFIG_E200
/* no RFMCI, MCSRRs on E200 */
- CRITICAL_EXCEPTION(0x0200, MachineCheck, MachineCheckException)
+ CRITICAL_EXCEPTION(0x0200, MachineCheck, machine_check_exception)
#else
- MCHECK_EXCEPTION(0x0200, MachineCheck, MachineCheckException)
+ MCHECK_EXCEPTION(0x0200, MachineCheck, machine_check_exception)
#endif
/* Data Storage Interrupt */
@@ -542,9 +542,9 @@ interrupt_base:
#else
#ifdef CONFIG_E200
/* E200 treats 'normal' floating point instructions as FP Unavail exception */
- EXCEPTION(0x0800, FloatingPointUnavailable, ProgramCheckException, EXC_XFER_EE)
+ EXCEPTION(0x0800, FloatingPointUnavailable, program_check_exception, EXC_XFER_EE)
#else
- EXCEPTION(0x0800, FloatingPointUnavailable, UnknownException, EXC_XFER_EE)
+ EXCEPTION(0x0800, FloatingPointUnavailable, unknown_exception, EXC_XFER_EE)
#endif
#endif
@@ -554,20 +554,20 @@ interrupt_base:
EXC_XFER_EE_LITE(0x0c00, DoSyscall)
/* Auxillary Processor Unavailable Interrupt */
- EXCEPTION(0x2900, AuxillaryProcessorUnavailable, UnknownException, EXC_XFER_EE)
+ EXCEPTION(0x2900, AuxillaryProcessorUnavailable, unknown_exception, EXC_XFER_EE)
/* Decrementer Interrupt */
DECREMENTER_EXCEPTION
/* Fixed Internal Timer Interrupt */
/* TODO: Add FIT support */
- EXCEPTION(0x3100, FixedIntervalTimer, UnknownException, EXC_XFER_EE)
+ EXCEPTION(0x3100, FixedIntervalTimer, unknown_exception, EXC_XFER_EE)
/* Watchdog Timer Interrupt */
#ifdef CONFIG_BOOKE_WDT
CRITICAL_EXCEPTION(0x3200, WatchdogTimer, WatchdogException)
#else
- CRITICAL_EXCEPTION(0x3200, WatchdogTimer, UnknownException)
+ CRITICAL_EXCEPTION(0x3200, WatchdogTimer, unknown_exception)
#endif
/* Data TLB Error Interrupt */
@@ -696,21 +696,21 @@ interrupt_base:
addi r3,r1,STACK_FRAME_OVERHEAD
EXC_XFER_EE_LITE(0x2010, KernelSPE)
#else
- EXCEPTION(0x2020, SPEUnavailable, UnknownException, EXC_XFER_EE)
+ EXCEPTION(0x2020, SPEUnavailable, unknown_exception, EXC_XFER_EE)
#endif /* CONFIG_SPE */
/* SPE Floating Point Data */
#ifdef CONFIG_SPE
EXCEPTION(0x2030, SPEFloatingPointData, SPEFloatingPointException, EXC_XFER_EE);
#else
- EXCEPTION(0x2040, SPEFloatingPointData, UnknownException, EXC_XFER_EE)
+ EXCEPTION(0x2040, SPEFloatingPointData, unknown_exception, EXC_XFER_EE)
#endif /* CONFIG_SPE */
/* SPE Floating Point Round */
- EXCEPTION(0x2050, SPEFloatingPointRound, UnknownException, EXC_XFER_EE)
+ EXCEPTION(0x2050, SPEFloatingPointRound, unknown_exception, EXC_XFER_EE)
/* Performance Monitor */
- EXCEPTION(0x2060, PerformanceMonitor, PerformanceMonitorException, EXC_XFER_STD)
+ EXCEPTION(0x2060, PerformanceMonitor, performance_monitor_exception, EXC_XFER_STD)
/* Debug Interrupt */
@@ -853,7 +853,7 @@ load_up_spe:
cmpi 0,r4,0
beq 1f
addi r4,r4,THREAD /* want THREAD of last_task_used_spe */
- SAVE_32EVR(0,r10,r4)
+ SAVE_32EVRS(0,r10,r4)
evxor evr10, evr10, evr10 /* clear out evr10 */
evmwumiaa evr10, evr10, evr10 /* evr10 <- ACC = 0 * 0 + ACC */
li r5,THREAD_ACC
@@ -873,7 +873,7 @@ load_up_spe:
stw r4,THREAD_USED_SPE(r5)
evlddx evr4,r10,r5
evmra evr4,evr4
- REST_32EVR(0,r10,r5)
+ REST_32EVRS(0,r10,r5)
#ifndef CONFIG_SMP
subi r4,r5,THREAD
stw r4,last_task_used_spe@l(r3)
@@ -963,7 +963,7 @@ _GLOBAL(giveup_spe)
addi r3,r3,THREAD /* want THREAD of task */
lwz r5,PT_REGS(r3)
cmpi 0,r5,0
- SAVE_32EVR(0, r4, r3)
+ SAVE_32EVRS(0, r4, r3)
evxor evr6, evr6, evr6 /* clear out evr6 */
evmwumiaa evr6, evr6, evr6 /* evr6 <- ACC = 0 * 0 + ACC */
li r4,THREAD_ACC
@@ -1028,10 +1028,14 @@ _GLOBAL(set_context)
* goes at the beginning of the data segment, which is page-aligned.
*/
.data
-_GLOBAL(sdata)
-_GLOBAL(empty_zero_page)
+ .align 12
+ .globl sdata
+sdata:
+ .globl empty_zero_page
+empty_zero_page:
.space 4096
-_GLOBAL(swapper_pg_dir)
+ .globl swapper_pg_dir
+swapper_pg_dir:
.space 4096
/* Reserved 4k for the critical exception stack & 4k for the machine
@@ -1040,13 +1044,15 @@ _GLOBAL(swapper_pg_dir)
.align 12
exception_stack_bottom:
.space BOOKE_EXCEPTION_STACK_SIZE * NR_CPUS
-_GLOBAL(exception_stack_top)
+ .globl exception_stack_top
+exception_stack_top:
/*
* This space gets a copy of optional info passed to us by the bootstrap
* which is used to pass parameters into the kernel like root=/dev/sda1, etc.
*/
-_GLOBAL(cmd_line)
+ .globl cmd_line
+cmd_line:
.space 512
/*
@@ -1055,4 +1061,3 @@ _GLOBAL(cmd_line)
*/
abatron_pteptrs:
.space 8
-
diff --git a/arch/ppc/kernel/idle.c b/arch/ppc/kernel/idle.c
index fba29c876b62..821a75e45602 100644
--- a/arch/ppc/kernel/idle.c
+++ b/arch/ppc/kernel/idle.c
@@ -32,6 +32,7 @@
#include <asm/cache.h>
#include <asm/cputable.h>
#include <asm/machdep.h>
+#include <asm/smp.h>
void default_idle(void)
{
@@ -52,10 +53,6 @@ void default_idle(void)
}
#endif
}
- if (need_resched())
- schedule();
- if (cpu_is_offline(cpu) && system_state == SYSTEM_RUNNING)
- cpu_die();
}
/*
@@ -63,18 +60,29 @@ void default_idle(void)
*/
void cpu_idle(void)
{
- for (;;)
- if (ppc_md.idle != NULL)
- ppc_md.idle();
- else
- default_idle();
+ int cpu = smp_processor_id();
+
+ for (;;) {
+ while (!need_resched()) {
+ if (ppc_md.idle != NULL)
+ ppc_md.idle();
+ else
+ default_idle();
+ }
+
+ if (cpu_is_offline(cpu) && system_state == SYSTEM_RUNNING)
+ cpu_die();
+ preempt_enable_no_resched();
+ schedule();
+ preempt_disable();
+ }
}
#if defined(CONFIG_SYSCTL) && defined(CONFIG_6xx)
/*
* Register the sysctl to set/clear powersave_nap.
*/
-extern unsigned long powersave_nap;
+extern int powersave_nap;
static ctl_table powersave_nap_ctl_table[]={
{
diff --git a/arch/ppc/kernel/irq.c b/arch/ppc/kernel/irq.c
deleted file mode 100644
index 8843f3af230f..000000000000
--- a/arch/ppc/kernel/irq.c
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * arch/ppc/kernel/irq.c
- *
- * Derived from arch/i386/kernel/irq.c
- * Copyright (C) 1992 Linus Torvalds
- * Adapted from arch/i386 by Gary Thomas
- * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
- * Updated and modified by Cort Dougan <cort@fsmlabs.com>
- * Copyright (C) 1996-2001 Cort Dougan
- * Adapted for Power Macintosh by Paul Mackerras
- * Copyright (C) 1996 Paul Mackerras (paulus@cs.anu.edu.au)
- * Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk).
- *
- * This file contains the code used by various IRQ handling routines:
- * asking for different IRQ's should be done through these routines
- * instead of just grabbing them. Thus setups with different IRQ numbers
- * shouldn't result in any weird surprises, and installing new handlers
- * should be easier.
- *
- * The MPC8xx has an interrupt mask in the SIU. If a bit is set, the
- * interrupt is _enabled_. As expected, IRQ0 is bit 0 in the 32-bit
- * mask register (of which only 16 are defined), hence the weird shifting
- * and complement of the cached_irq_mask. I want to be able to stuff
- * this right into the SIU SMASK register.
- * Many of the prep/chrp functions are conditional compiled on CONFIG_8xx
- * to reduce code space and undefined function references.
- */
-
-#include <linux/errno.h>
-#include <linux/module.h>
-#include <linux/threads.h>
-#include <linux/kernel_stat.h>
-#include <linux/signal.h>
-#include <linux/sched.h>
-#include <linux/ptrace.h>
-#include <linux/ioport.h>
-#include <linux/interrupt.h>
-#include <linux/timex.h>
-#include <linux/config.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/pci.h>
-#include <linux/delay.h>
-#include <linux/irq.h>
-#include <linux/proc_fs.h>
-#include <linux/random.h>
-#include <linux/seq_file.h>
-#include <linux/cpumask.h>
-#include <linux/profile.h>
-#include <linux/bitops.h>
-
-#include <asm/uaccess.h>
-#include <asm/system.h>
-#include <asm/io.h>
-#include <asm/pgtable.h>
-#include <asm/irq.h>
-#include <asm/cache.h>
-#include <asm/prom.h>
-#include <asm/ptrace.h>
-
-#define NR_MASK_WORDS ((NR_IRQS + 31) / 32)
-
-extern atomic_t ipi_recv;
-extern atomic_t ipi_sent;
-
-#define MAXCOUNT 10000000
-
-int ppc_spurious_interrupts = 0;
-struct irqaction *ppc_irq_action[NR_IRQS];
-unsigned long ppc_cached_irq_mask[NR_MASK_WORDS];
-unsigned long ppc_lost_interrupts[NR_MASK_WORDS];
-atomic_t ppc_n_lost_interrupts;
-
-#ifdef CONFIG_TAU_INT
-extern int tau_initialized;
-extern int tau_interrupts(int);
-#endif
-
-int show_interrupts(struct seq_file *p, void *v)
-{
- int i = *(loff_t *) v, j;
- struct irqaction * action;
- unsigned long flags;
-
- if (i == 0) {
- seq_puts(p, " ");
- for (j=0; j<NR_CPUS; j++)
- if (cpu_online(j))
- seq_printf(p, "CPU%d ", j);
- seq_putc(p, '\n');
- }
-
- if (i < NR_IRQS) {
- spin_lock_irqsave(&irq_desc[i].lock, flags);
- action = irq_desc[i].action;
- if ( !action || !action->handler )
- goto skip;
- seq_printf(p, "%3d: ", i);
-#ifdef CONFIG_SMP
- for (j = 0; j < NR_CPUS; j++)
- if (cpu_online(j))
- seq_printf(p, "%10u ",
- kstat_cpu(j).irqs[i]);
-#else
- seq_printf(p, "%10u ", kstat_irqs(i));
-#endif /* CONFIG_SMP */
- if (irq_desc[i].handler)
- seq_printf(p, " %s ", irq_desc[i].handler->typename);
- else
- seq_puts(p, " None ");
- seq_printf(p, "%s", (irq_desc[i].status & IRQ_LEVEL) ? "Level " : "Edge ");
- seq_printf(p, " %s", action->name);
- for (action = action->next; action; action = action->next)
- seq_printf(p, ", %s", action->name);
- seq_putc(p, '\n');
-skip:
- spin_unlock_irqrestore(&irq_desc[i].lock, flags);
- } else if (i == NR_IRQS) {
-#ifdef CONFIG_TAU_INT
- if (tau_initialized){
- seq_puts(p, "TAU: ");
- for (j = 0; j < NR_CPUS; j++)
- if (cpu_online(j))
- seq_printf(p, "%10u ", tau_interrupts(j));
- seq_puts(p, " PowerPC Thermal Assist (cpu temp)\n");
- }
-#endif
-#ifdef CONFIG_SMP
- /* should this be per processor send/receive? */
- seq_printf(p, "IPI (recv/sent): %10u/%u\n",
- atomic_read(&ipi_recv), atomic_read(&ipi_sent));
-#endif
- seq_printf(p, "BAD: %10u\n", ppc_spurious_interrupts);
- }
- return 0;
-}
-
-void do_IRQ(struct pt_regs *regs)
-{
- int irq, first = 1;
- irq_enter();
-
- /*
- * Every platform is required to implement ppc_md.get_irq.
- * This function will either return an irq number or -1 to
- * indicate there are no more pending. But the first time
- * through the loop this means there wasn't and IRQ pending.
- * The value -2 is for buggy hardware and means that this IRQ
- * has already been handled. -- Tom
- */
- while ((irq = ppc_md.get_irq(regs)) >= 0) {
- __do_IRQ(irq, regs);
- first = 0;
- }
- if (irq != -2 && first)
- /* That's not SMP safe ... but who cares ? */
- ppc_spurious_interrupts++;
- irq_exit();
-}
-
-void __init init_IRQ(void)
-{
- ppc_md.init_IRQ();
-}
diff --git a/arch/ppc/kernel/l2cr.S b/arch/ppc/kernel/l2cr.S
index 861115249b35..d7f4e982b539 100644
--- a/arch/ppc/kernel/l2cr.S
+++ b/arch/ppc/kernel/l2cr.S
@@ -203,7 +203,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_SPEC7450)
* L1 icache
*/
b 20f
- .balign L1_CACHE_LINE_SIZE
+ .balign L1_CACHE_BYTES
22:
sync
mtspr SPRN_L2CR,r3
diff --git a/arch/ppc/kernel/machine_kexec.c b/arch/ppc/kernel/machine_kexec.c
index a72787747df7..a882b0dbe8de 100644
--- a/arch/ppc/kernel/machine_kexec.c
+++ b/arch/ppc/kernel/machine_kexec.c
@@ -32,7 +32,7 @@ const extern unsigned int relocate_new_kernel_size;
* Provide a dummy crash_notes definition while crash dump arrives to ppc.
* This prevents breakage of crash_notes attribute in kernel/ksysfs.c.
*/
-void *crash_notes = NULL;
+note_buf_t crash_notes[NR_CPUS];
void machine_shutdown(void)
{
diff --git a/arch/ppc/kernel/misc.S b/arch/ppc/kernel/misc.S
index 90d917d2e856..5e61124581d0 100644
--- a/arch/ppc/kernel/misc.S
+++ b/arch/ppc/kernel/misc.S
@@ -25,6 +25,11 @@
#include <asm/thread_info.h>
#include <asm/asm-offsets.h>
+#ifdef CONFIG_8xx
+#define ISYNC_8xx isync
+#else
+#define ISYNC_8xx
+#endif
.text
.align 5
@@ -125,9 +130,8 @@ _GLOBAL(identify_cpu)
1:
addis r6,r3,cur_cpu_spec@ha
addi r6,r6,cur_cpu_spec@l
- slwi r4,r4,2
sub r8,r8,r3
- stwx r8,r4,r6
+ stw r8,0(r6)
blr
/*
@@ -186,19 +190,18 @@ _GLOBAL(do_cpu_ftr_fixups)
*
* Setup function is called with:
* r3 = data offset
- * r4 = CPU number
- * r5 = ptr to CPU spec (relocated)
+ * r4 = ptr to CPU spec (relocated)
*/
_GLOBAL(call_setup_cpu)
- addis r5,r3,cur_cpu_spec@ha
- addi r5,r5,cur_cpu_spec@l
- slwi r4,r24,2
- lwzx r5,r4,r5
+ addis r4,r3,cur_cpu_spec@ha
+ addi r4,r4,cur_cpu_spec@l
+ lwz r4,0(r4)
+ add r4,r4,r3
+ lwz r5,CPU_SPEC_SETUP(r4)
+ cmpi 0,r5,0
add r5,r5,r3
- lwz r6,CPU_SPEC_SETUP(r5)
- add r6,r6,r3
- mtctr r6
- mr r4,r24
+ beqlr
+ mtctr r5
bctr
#if defined(CONFIG_CPU_FREQ_PMAC) && defined(CONFIG_6xx)
@@ -273,134 +276,6 @@ _GLOBAL(low_choose_7447a_dfs)
#endif /* CONFIG_CPU_FREQ_PMAC && CONFIG_6xx */
-/* void local_save_flags_ptr(unsigned long *flags) */
-_GLOBAL(local_save_flags_ptr)
- mfmsr r4
- stw r4,0(r3)
- blr
- /*
- * Need these nops here for taking over save/restore to
- * handle lost intrs
- * -- Cort
- */
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
-_GLOBAL(local_save_flags_ptr_end)
-
-/* void local_irq_restore(unsigned long flags) */
-_GLOBAL(local_irq_restore)
-/*
- * Just set/clear the MSR_EE bit through restore/flags but do not
- * change anything else. This is needed by the RT system and makes
- * sense anyway.
- * -- Cort
- */
- mfmsr r4
- /* Copy all except the MSR_EE bit from r4 (current MSR value)
- to r3. This is the sort of thing the rlwimi instruction is
- designed for. -- paulus. */
- rlwimi r3,r4,0,17,15
- /* Check if things are setup the way we want _already_. */
- cmpw 0,r3,r4
- beqlr
-1: SYNC
- mtmsr r3
- SYNC
- blr
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
-_GLOBAL(local_irq_restore_end)
-
-_GLOBAL(local_irq_disable)
- mfmsr r0 /* Get current interrupt state */
- rlwinm r3,r0,16+1,32-1,31 /* Extract old value of 'EE' */
- rlwinm r0,r0,0,17,15 /* clear MSR_EE in r0 */
- SYNC /* Some chip revs have problems here... */
- mtmsr r0 /* Update machine state */
- blr /* Done */
- /*
- * Need these nops here for taking over save/restore to
- * handle lost intrs
- * -- Cort
- */
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
-_GLOBAL(local_irq_disable_end)
-
-_GLOBAL(local_irq_enable)
- mfmsr r3 /* Get current state */
- ori r3,r3,MSR_EE /* Turn on 'EE' bit */
- SYNC /* Some chip revs have problems here... */
- mtmsr r3 /* Update machine state */
- blr
- /*
- * Need these nops here for taking over save/restore to
- * handle lost intrs
- * -- Cort
- */
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
-_GLOBAL(local_irq_enable_end)
-
/*
* complement mask on the msr then "or" some values on.
* _nmask_and_or_msr(nmask, value_to_or)
@@ -622,27 +497,27 @@ END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE)
* and invalidate the corresponding instruction cache blocks.
* This is a no-op on the 601.
*
- * flush_icache_range(unsigned long start, unsigned long stop)
+ * __flush_icache_range(unsigned long start, unsigned long stop)
*/
-_GLOBAL(flush_icache_range)
+_GLOBAL(__flush_icache_range)
BEGIN_FTR_SECTION
blr /* for 601, do nothing */
END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE)
- li r5,L1_CACHE_LINE_SIZE-1
+ li r5,L1_CACHE_BYTES-1
andc r3,r3,r5
subf r4,r3,r4
add r4,r4,r5
- srwi. r4,r4,LG_L1_CACHE_LINE_SIZE
+ srwi. r4,r4,L1_CACHE_SHIFT
beqlr
mtctr r4
mr r6,r3
1: dcbst 0,r3
- addi r3,r3,L1_CACHE_LINE_SIZE
+ addi r3,r3,L1_CACHE_BYTES
bdnz 1b
sync /* wait for dcbst's to get to ram */
mtctr r4
2: icbi 0,r6
- addi r6,r6,L1_CACHE_LINE_SIZE
+ addi r6,r6,L1_CACHE_BYTES
bdnz 2b
sync /* additional sync needed on g4 */
isync
@@ -655,16 +530,16 @@ END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE)
* clean_dcache_range(unsigned long start, unsigned long stop)
*/
_GLOBAL(clean_dcache_range)
- li r5,L1_CACHE_LINE_SIZE-1
+ li r5,L1_CACHE_BYTES-1
andc r3,r3,r5
subf r4,r3,r4
add r4,r4,r5
- srwi. r4,r4,LG_L1_CACHE_LINE_SIZE
+ srwi. r4,r4,L1_CACHE_SHIFT
beqlr
mtctr r4
1: dcbst 0,r3
- addi r3,r3,L1_CACHE_LINE_SIZE
+ addi r3,r3,L1_CACHE_BYTES
bdnz 1b
sync /* wait for dcbst's to get to ram */
blr
@@ -676,16 +551,16 @@ _GLOBAL(clean_dcache_range)
* flush_dcache_range(unsigned long start, unsigned long stop)
*/
_GLOBAL(flush_dcache_range)
- li r5,L1_CACHE_LINE_SIZE-1
+ li r5,L1_CACHE_BYTES-1
andc r3,r3,r5
subf r4,r3,r4
add r4,r4,r5
- srwi. r4,r4,LG_L1_CACHE_LINE_SIZE
+ srwi. r4,r4,L1_CACHE_SHIFT
beqlr
mtctr r4
1: dcbf 0,r3
- addi r3,r3,L1_CACHE_LINE_SIZE
+ addi r3,r3,L1_CACHE_BYTES
bdnz 1b
sync /* wait for dcbst's to get to ram */
blr
@@ -698,16 +573,16 @@ _GLOBAL(flush_dcache_range)
* invalidate_dcache_range(unsigned long start, unsigned long stop)
*/
_GLOBAL(invalidate_dcache_range)
- li r5,L1_CACHE_LINE_SIZE-1
+ li r5,L1_CACHE_BYTES-1
andc r3,r3,r5
subf r4,r3,r4
add r4,r4,r5
- srwi. r4,r4,LG_L1_CACHE_LINE_SIZE
+ srwi. r4,r4,L1_CACHE_SHIFT
beqlr
mtctr r4
1: dcbi 0,r3
- addi r3,r3,L1_CACHE_LINE_SIZE
+ addi r3,r3,L1_CACHE_BYTES
bdnz 1b
sync /* wait for dcbi's to get to ram */
blr
@@ -728,7 +603,7 @@ _GLOBAL(flush_dcache_all)
mtctr r4
lis r5, KERNELBASE@h
1: lwz r3, 0(r5) /* Load one word from every line */
- addi r5, r5, L1_CACHE_LINE_SIZE
+ addi r5, r5, L1_CACHE_BYTES
bdnz 1b
blr
#endif /* CONFIG_NOT_COHERENT_CACHE */
@@ -746,16 +621,16 @@ BEGIN_FTR_SECTION
blr /* for 601, do nothing */
END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE)
rlwinm r3,r3,0,0,19 /* Get page base address */
- li r4,4096/L1_CACHE_LINE_SIZE /* Number of lines in a page */
+ li r4,4096/L1_CACHE_BYTES /* Number of lines in a page */
mtctr r4
mr r6,r3
0: dcbst 0,r3 /* Write line to ram */
- addi r3,r3,L1_CACHE_LINE_SIZE
+ addi r3,r3,L1_CACHE_BYTES
bdnz 0b
sync
mtctr r4
1: icbi 0,r6
- addi r6,r6,L1_CACHE_LINE_SIZE
+ addi r6,r6,L1_CACHE_BYTES
bdnz 1b
sync
isync
@@ -778,16 +653,16 @@ END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE)
mtmsr r0
isync
rlwinm r3,r3,0,0,19 /* Get page base address */
- li r4,4096/L1_CACHE_LINE_SIZE /* Number of lines in a page */
+ li r4,4096/L1_CACHE_BYTES /* Number of lines in a page */
mtctr r4
mr r6,r3
0: dcbst 0,r3 /* Write line to ram */
- addi r3,r3,L1_CACHE_LINE_SIZE
+ addi r3,r3,L1_CACHE_BYTES
bdnz 0b
sync
mtctr r4
1: icbi 0,r6
- addi r6,r6,L1_CACHE_LINE_SIZE
+ addi r6,r6,L1_CACHE_BYTES
bdnz 1b
sync
mtmsr r10 /* restore DR */
@@ -802,7 +677,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE)
* void clear_pages(void *page, int order) ;
*/
_GLOBAL(clear_pages)
- li r0,4096/L1_CACHE_LINE_SIZE
+ li r0,4096/L1_CACHE_BYTES
slw r0,r0,r4
mtctr r0
#ifdef CONFIG_8xx
@@ -814,7 +689,7 @@ _GLOBAL(clear_pages)
#else
1: dcbz 0,r3
#endif
- addi r3,r3,L1_CACHE_LINE_SIZE
+ addi r3,r3,L1_CACHE_BYTES
bdnz 1b
blr
@@ -840,7 +715,7 @@ _GLOBAL(copy_page)
#ifdef CONFIG_8xx
/* don't use prefetch on 8xx */
- li r0,4096/L1_CACHE_LINE_SIZE
+ li r0,4096/L1_CACHE_BYTES
mtctr r0
1: COPY_16_BYTES
bdnz 1b
@@ -854,13 +729,13 @@ _GLOBAL(copy_page)
li r11,4
mtctr r0
11: dcbt r11,r4
- addi r11,r11,L1_CACHE_LINE_SIZE
+ addi r11,r11,L1_CACHE_BYTES
bdnz 11b
#else /* MAX_COPY_PREFETCH == 1 */
dcbt r5,r4
- li r11,L1_CACHE_LINE_SIZE+4
+ li r11,L1_CACHE_BYTES+4
#endif /* MAX_COPY_PREFETCH */
- li r0,4096/L1_CACHE_LINE_SIZE - MAX_COPY_PREFETCH
+ li r0,4096/L1_CACHE_BYTES - MAX_COPY_PREFETCH
crclr 4*cr0+eq
2:
mtctr r0
@@ -868,12 +743,12 @@ _GLOBAL(copy_page)
dcbt r11,r4
dcbz r5,r3
COPY_16_BYTES
-#if L1_CACHE_LINE_SIZE >= 32
+#if L1_CACHE_BYTES >= 32
COPY_16_BYTES
-#if L1_CACHE_LINE_SIZE >= 64
+#if L1_CACHE_BYTES >= 64
COPY_16_BYTES
COPY_16_BYTES
-#if L1_CACHE_LINE_SIZE >= 128
+#if L1_CACHE_BYTES >= 128
COPY_16_BYTES
COPY_16_BYTES
COPY_16_BYTES
@@ -930,8 +805,18 @@ _GLOBAL(_insb)
subi r4,r4,1
blelr-
00: lbz r5,0(r3)
- eieio
- stbu r5,1(r4)
+01: eieio
+02: stbu r5,1(r4)
+ ISYNC_8xx
+ .section .fixup,"ax"
+03: blr
+ .text
+ .section __ex_table, "a"
+ .align 2
+ .long 00b, 03b
+ .long 01b, 03b
+ .long 02b, 03b
+ .text
bdnz 00b
blr
@@ -941,8 +826,18 @@ _GLOBAL(_outsb)
subi r4,r4,1
blelr-
00: lbzu r5,1(r4)
- stb r5,0(r3)
- eieio
+01: stb r5,0(r3)
+02: eieio
+ ISYNC_8xx
+ .section .fixup,"ax"
+03: blr
+ .text
+ .section __ex_table, "a"
+ .align 2
+ .long 00b, 03b
+ .long 01b, 03b
+ .long 02b, 03b
+ .text
bdnz 00b
blr
@@ -952,8 +847,18 @@ _GLOBAL(_insw)
subi r4,r4,2
blelr-
00: lhbrx r5,0,r3
- eieio
- sthu r5,2(r4)
+01: eieio
+02: sthu r5,2(r4)
+ ISYNC_8xx
+ .section .fixup,"ax"
+03: blr
+ .text
+ .section __ex_table, "a"
+ .align 2
+ .long 00b, 03b
+ .long 01b, 03b
+ .long 02b, 03b
+ .text
bdnz 00b
blr
@@ -963,8 +868,18 @@ _GLOBAL(_outsw)
subi r4,r4,2
blelr-
00: lhzu r5,2(r4)
- eieio
- sthbrx r5,0,r3
+01: eieio
+02: sthbrx r5,0,r3
+ ISYNC_8xx
+ .section .fixup,"ax"
+03: blr
+ .text
+ .section __ex_table, "a"
+ .align 2
+ .long 00b, 03b
+ .long 01b, 03b
+ .long 02b, 03b
+ .text
bdnz 00b
blr
@@ -974,8 +889,18 @@ _GLOBAL(_insl)
subi r4,r4,4
blelr-
00: lwbrx r5,0,r3
- eieio
- stwu r5,4(r4)
+01: eieio
+02: stwu r5,4(r4)
+ ISYNC_8xx
+ .section .fixup,"ax"
+03: blr
+ .text
+ .section __ex_table, "a"
+ .align 2
+ .long 00b, 03b
+ .long 01b, 03b
+ .long 02b, 03b
+ .text
bdnz 00b
blr
@@ -985,8 +910,18 @@ _GLOBAL(_outsl)
subi r4,r4,4
blelr-
00: lwzu r5,4(r4)
- stwbrx r5,0,r3
- eieio
+01: stwbrx r5,0,r3
+02: eieio
+ ISYNC_8xx
+ .section .fixup,"ax"
+03: blr
+ .text
+ .section __ex_table, "a"
+ .align 2
+ .long 00b, 03b
+ .long 01b, 03b
+ .long 02b, 03b
+ .text
bdnz 00b
blr
@@ -997,8 +932,18 @@ _GLOBAL(_insw_ns)
subi r4,r4,2
blelr-
00: lhz r5,0(r3)
- eieio
- sthu r5,2(r4)
+01: eieio
+02: sthu r5,2(r4)
+ ISYNC_8xx
+ .section .fixup,"ax"
+03: blr
+ .text
+ .section __ex_table, "a"
+ .align 2
+ .long 00b, 03b
+ .long 01b, 03b
+ .long 02b, 03b
+ .text
bdnz 00b
blr
@@ -1009,8 +954,18 @@ _GLOBAL(_outsw_ns)
subi r4,r4,2
blelr-
00: lhzu r5,2(r4)
- sth r5,0(r3)
- eieio
+01: sth r5,0(r3)
+02: eieio
+ ISYNC_8xx
+ .section .fixup,"ax"
+03: blr
+ .text
+ .section __ex_table, "a"
+ .align 2
+ .long 00b, 03b
+ .long 01b, 03b
+ .long 02b, 03b
+ .text
bdnz 00b
blr
@@ -1021,8 +976,18 @@ _GLOBAL(_insl_ns)
subi r4,r4,4
blelr-
00: lwz r5,0(r3)
- eieio
- stwu r5,4(r4)
+01: eieio
+02: stwu r5,4(r4)
+ ISYNC_8xx
+ .section .fixup,"ax"
+03: blr
+ .text
+ .section __ex_table, "a"
+ .align 2
+ .long 00b, 03b
+ .long 01b, 03b
+ .long 02b, 03b
+ .text
bdnz 00b
blr
@@ -1033,8 +998,18 @@ _GLOBAL(_outsl_ns)
subi r4,r4,4
blelr-
00: lwzu r5,4(r4)
- stw r5,0(r3)
- eieio
+01: stw r5,0(r3)
+02: eieio
+ ISYNC_8xx
+ .section .fixup,"ax"
+03: blr
+ .text
+ .section __ex_table, "a"
+ .align 2
+ .long 00b, 03b
+ .long 01b, 03b
+ .long 02b, 03b
+ .text
bdnz 00b
blr
@@ -1098,33 +1073,6 @@ _GLOBAL(_get_SP)
blr
/*
- * These are used in the alignment trap handler when emulating
- * single-precision loads and stores.
- * We restore and save the fpscr so the task gets the same result
- * and exceptions as if the cpu had performed the load or store.
- */
-
-#ifdef CONFIG_PPC_FPU
-_GLOBAL(cvt_fd)
- lfd 0,-4(r5) /* load up fpscr value */
- mtfsf 0xff,0
- lfs 0,0(r3)
- stfd 0,0(r4)
- mffs 0 /* save new fpscr value */
- stfd 0,-4(r5)
- blr
-
-_GLOBAL(cvt_df)
- lfd 0,-4(r5) /* load up fpscr value */
- mtfsf 0xff,0
- lfd 0,0(r3)
- stfs 0,0(r4)
- mffs 0 /* save new fpscr value */
- stfd 0,-4(r5)
- blr
-#endif
-
-/*
* Create a kernel thread
* kernel_thread(fn, arg, flags)
*/
diff --git a/arch/ppc/kernel/pci.c b/arch/ppc/kernel/pci.c
index 854e45beb387..48ed58f995c0 100644
--- a/arch/ppc/kernel/pci.c
+++ b/arch/ppc/kernel/pci.c
@@ -21,6 +21,7 @@
#include <asm/byteorder.h>
#include <asm/irq.h>
#include <asm/uaccess.h>
+#include <asm/machdep.h>
#undef DEBUG
@@ -53,7 +54,7 @@ static u8* pci_to_OF_bus_map;
/* By default, we don't re-assign bus numbers. We do this only on
* some pmacs
*/
-int pci_assign_all_busses;
+int pci_assign_all_buses;
struct pci_controller* hose_head;
struct pci_controller** hose_tail = &hose_head;
@@ -61,20 +62,6 @@ struct pci_controller** hose_tail = &hose_head;
static int pci_bus_count;
static void
-fixup_rev1_53c810(struct pci_dev* dev)
-{
- /* rev 1 ncr53c810 chips don't set the class at all which means
- * they don't get their resources remapped. Fix that here.
- */
-
- if ((dev->class == PCI_CLASS_NOT_DEFINED)) {
- printk("NCR 53c810 rev 1 detected, setting PCI class.\n");
- dev->class = PCI_CLASS_STORAGE_SCSI;
- }
-}
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NCR, PCI_DEVICE_ID_NCR_53C810, fixup_rev1_53c810);
-
-static void
fixup_broken_pcnet32(struct pci_dev* dev)
{
if ((dev->class>>8 == PCI_CLASS_NETWORK_ETHERNET)) {
@@ -644,7 +631,7 @@ pcibios_alloc_controller(void)
/*
* Functions below are used on OpenFirmware machines.
*/
-static void __openfirmware
+static void
make_one_node_map(struct device_node* node, u8 pci_bus)
{
int *bus_range;
@@ -678,7 +665,7 @@ make_one_node_map(struct device_node* node, u8 pci_bus)
}
}
-void __openfirmware
+void
pcibios_make_OF_bus_map(void)
{
int i;
@@ -720,7 +707,7 @@ pcibios_make_OF_bus_map(void)
typedef int (*pci_OF_scan_iterator)(struct device_node* node, void* data);
-static struct device_node* __openfirmware
+static struct device_node*
scan_OF_pci_childs(struct device_node* node, pci_OF_scan_iterator filter, void* data)
{
struct device_node* sub_node;
@@ -761,7 +748,7 @@ scan_OF_pci_childs_iterator(struct device_node* node, void* data)
return 0;
}
-static struct device_node* __openfirmware
+static struct device_node*
scan_OF_childs_for_device(struct device_node* node, u8 bus, u8 dev_fn)
{
u8 filter_data[2] = {bus, dev_fn};
@@ -813,18 +800,20 @@ pci_busdev_to_OF_node(struct pci_bus *bus, int devfn)
/* Now, lookup childs of the hose */
return scan_OF_childs_for_device(node->child, busnr, devfn);
}
+EXPORT_SYMBOL(pci_busdev_to_OF_node);
struct device_node*
pci_device_to_OF_node(struct pci_dev *dev)
{
return pci_busdev_to_OF_node(dev->bus, dev->devfn);
}
+EXPORT_SYMBOL(pci_device_to_OF_node);
/* This routine is meant to be used early during boot, when the
* PCI bus numbers have not yet been assigned, and you need to
* issue PCI config cycles to an OF device.
* It could also be used to "fix" RTAS config cycles if you want
- * to set pci_assign_all_busses to 1 and still use RTAS for PCI
+ * to set pci_assign_all_buses to 1 and still use RTAS for PCI
* config cycles.
*/
struct pci_controller*
@@ -842,7 +831,7 @@ pci_find_hose_for_OF_device(struct device_node* node)
return NULL;
}
-static int __openfirmware
+static int
find_OF_pci_device_filter(struct device_node* node, void* data)
{
return ((void *)node == data);
@@ -890,6 +879,7 @@ pci_device_from_OF_node(struct device_node* node, u8* bus, u8* devfn)
}
return -ENODEV;
}
+EXPORT_SYMBOL(pci_device_from_OF_node);
void __init
pci_process_bridge_OF_ranges(struct pci_controller *hose,
@@ -1030,6 +1020,10 @@ static ssize_t pci_show_devspec(struct device *dev, struct device_attribute *att
}
static DEVICE_ATTR(devspec, S_IRUGO, pci_show_devspec, NULL);
+#else /* CONFIG_PPC_OF */
+void pcibios_make_OF_bus_map(void)
+{
+}
#endif /* CONFIG_PPC_OF */
/* Add sysfs properties */
@@ -1262,12 +1256,12 @@ pcibios_init(void)
/* Scan all of the recorded PCI controllers. */
for (next_busno = 0, hose = hose_head; hose; hose = hose->next) {
- if (pci_assign_all_busses)
+ if (pci_assign_all_buses)
hose->first_busno = next_busno;
hose->last_busno = 0xff;
bus = pci_scan_bus(hose->first_busno, hose->ops, hose);
hose->last_busno = bus->subordinate;
- if (pci_assign_all_busses || next_busno <= hose->last_busno)
+ if (pci_assign_all_buses || next_busno <= hose->last_busno)
next_busno = hose->last_busno + pcibios_assign_bus_offset;
}
pci_bus_count = next_busno;
@@ -1276,7 +1270,7 @@ pcibios_init(void)
* numbers vs. kernel bus numbers since we may have to
* remap them.
*/
- if (pci_assign_all_busses && have_of)
+ if (pci_assign_all_buses && have_of)
pcibios_make_OF_bus_map();
/* Do machine dependent PCI interrupt routing */
@@ -1586,16 +1580,17 @@ static pgprot_t __pci_mmap_set_pgprot(struct pci_dev *dev, struct resource *rp,
* above routine
*/
pgprot_t pci_phys_mem_access_prot(struct file *file,
- unsigned long offset,
+ unsigned long pfn,
unsigned long size,
pgprot_t protection)
{
struct pci_dev *pdev = NULL;
struct resource *found = NULL;
unsigned long prot = pgprot_val(protection);
+ unsigned long offset = pfn << PAGE_SHIFT;
int i;
- if (page_is_ram(offset >> PAGE_SHIFT))
+ if (page_is_ram(pfn))
return prot;
prot |= _PAGE_NO_CACHE | _PAGE_GUARDED;
diff --git a/arch/ppc/kernel/perfmon.c b/arch/ppc/kernel/perfmon.c
deleted file mode 100644
index 22df9a596a0f..000000000000
--- a/arch/ppc/kernel/perfmon.c
+++ /dev/null
@@ -1,96 +0,0 @@
-/* kernel/perfmon.c
- * PPC 32 Performance Monitor Infrastructure
- *
- * Author: Andy Fleming
- * Copyright (c) 2004 Freescale Semiconductor, Inc
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-
-#include <linux/errno.h>
-#include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/stddef.h>
-#include <linux/unistd.h>
-#include <linux/ptrace.h>
-#include <linux/slab.h>
-#include <linux/user.h>
-#include <linux/a.out.h>
-#include <linux/interrupt.h>
-#include <linux/config.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/prctl.h>
-
-#include <asm/pgtable.h>
-#include <asm/uaccess.h>
-#include <asm/system.h>
-#include <asm/io.h>
-#include <asm/reg.h>
-#include <asm/xmon.h>
-
-/* A lock to regulate grabbing the interrupt */
-DEFINE_SPINLOCK(perfmon_lock);
-
-#if defined (CONFIG_FSL_BOOKE) && !defined (CONFIG_E200)
-static void dummy_perf(struct pt_regs *regs)
-{
- unsigned int pmgc0 = mfpmr(PMRN_PMGC0);
-
- pmgc0 &= ~PMGC0_PMIE;
- mtpmr(PMRN_PMGC0, pmgc0);
-}
-
-#elif defined(CONFIG_6xx)
-/* Ensure exceptions are disabled */
-static void dummy_perf(struct pt_regs *regs)
-{
- unsigned int mmcr0 = mfspr(SPRN_MMCR0);
-
- mmcr0 &= ~MMCR0_PMXE;
- mtspr(SPRN_MMCR0, mmcr0);
-}
-#else
-static void dummy_perf(struct pt_regs *regs)
-{
-}
-#endif
-
-void (*perf_irq)(struct pt_regs *) = dummy_perf;
-
-/* Grab the interrupt, if it's free.
- * Returns 0 on success, -1 if the interrupt is taken already */
-int request_perfmon_irq(void (*handler)(struct pt_regs *))
-{
- int err = 0;
-
- spin_lock(&perfmon_lock);
-
- if (perf_irq == dummy_perf)
- perf_irq = handler;
- else {
- pr_info("perfmon irq already handled by %p\n", perf_irq);
- err = -1;
- }
-
- spin_unlock(&perfmon_lock);
-
- return err;
-}
-
-void free_perfmon_irq(void)
-{
- spin_lock(&perfmon_lock);
-
- perf_irq = dummy_perf;
-
- spin_unlock(&perfmon_lock);
-}
-
-EXPORT_SYMBOL(perf_irq);
-EXPORT_SYMBOL(request_perfmon_irq);
-EXPORT_SYMBOL(free_perfmon_irq);
diff --git a/arch/ppc/kernel/perfmon_fsl_booke.c b/arch/ppc/kernel/perfmon_fsl_booke.c
index 03526bfb0840..32455dfcc36b 100644
--- a/arch/ppc/kernel/perfmon_fsl_booke.c
+++ b/arch/ppc/kernel/perfmon_fsl_booke.c
@@ -32,7 +32,7 @@
#include <asm/io.h>
#include <asm/reg.h>
#include <asm/xmon.h>
-#include <asm/perfmon.h>
+#include <asm/pmc.h>
static inline u32 get_pmlca(int ctr);
static inline void set_pmlca(int ctr, u32 pmlca);
diff --git a/arch/ppc/kernel/ppc_ksyms.c b/arch/ppc/kernel/ppc_ksyms.c
index 88f6bb7b6964..66073f775193 100644
--- a/arch/ppc/kernel/ppc_ksyms.c
+++ b/arch/ppc/kernel/ppc_ksyms.c
@@ -46,6 +46,7 @@
#include <asm/btext.h>
#include <asm/div64.h>
#include <asm/xmon.h>
+#include <asm/signal.h>
#ifdef CONFIG_8xx
#include <asm/commproc.h>
@@ -53,11 +54,10 @@
extern void transfer_to_handler(void);
extern void do_IRQ(struct pt_regs *regs);
-extern void MachineCheckException(struct pt_regs *regs);
-extern void AlignmentException(struct pt_regs *regs);
-extern void ProgramCheckException(struct pt_regs *regs);
-extern void SingleStepException(struct pt_regs *regs);
-extern int do_signal(sigset_t *, struct pt_regs *);
+extern void machine_check_exception(struct pt_regs *regs);
+extern void alignment_exception(struct pt_regs *regs);
+extern void program_check_exception(struct pt_regs *regs);
+extern void single_step_exception(struct pt_regs *regs);
extern int pmac_newworld;
extern int sys_sigreturn(struct pt_regs *regs);
@@ -72,13 +72,12 @@ EXPORT_SYMBOL(clear_user_page);
EXPORT_SYMBOL(do_signal);
EXPORT_SYMBOL(transfer_to_handler);
EXPORT_SYMBOL(do_IRQ);
-EXPORT_SYMBOL(MachineCheckException);
-EXPORT_SYMBOL(AlignmentException);
-EXPORT_SYMBOL(ProgramCheckException);
-EXPORT_SYMBOL(SingleStepException);
+EXPORT_SYMBOL(machine_check_exception);
+EXPORT_SYMBOL(alignment_exception);
+EXPORT_SYMBOL(program_check_exception);
+EXPORT_SYMBOL(single_step_exception);
EXPORT_SYMBOL(sys_sigreturn);
EXPORT_SYMBOL(ppc_n_lost_interrupts);
-EXPORT_SYMBOL(ppc_lost_interrupts);
EXPORT_SYMBOL(ISA_DMA_THRESHOLD);
EXPORT_SYMBOL(DMA_MODE_READ);
@@ -131,6 +130,11 @@ EXPORT_SYMBOL(outw);
EXPORT_SYMBOL(outl);
EXPORT_SYMBOL(outsl);*/
+EXPORT_SYMBOL(__ide_mm_insl);
+EXPORT_SYMBOL(__ide_mm_outsw);
+EXPORT_SYMBOL(__ide_mm_insw);
+EXPORT_SYMBOL(__ide_mm_outsl);
+
EXPORT_SYMBOL(_insb);
EXPORT_SYMBOL(_outsb);
EXPORT_SYMBOL(_insw);
@@ -171,6 +175,7 @@ EXPORT_SYMBOL(pci_bus_to_phys);
#endif /* CONFIG_PCI */
#ifdef CONFIG_NOT_COHERENT_CACHE
+extern void flush_dcache_all(void);
EXPORT_SYMBOL(flush_dcache_all);
#endif
@@ -212,9 +217,6 @@ EXPORT_SYMBOL(adb_try_handler_change);
EXPORT_SYMBOL(cuda_request);
EXPORT_SYMBOL(cuda_poll);
#endif /* CONFIG_ADB_CUDA */
-#ifdef CONFIG_PPC_MULTIPLATFORM
-EXPORT_SYMBOL(_machine);
-#endif
#ifdef CONFIG_PPC_PMAC
EXPORT_SYMBOL(sys_ctrler);
EXPORT_SYMBOL(pmac_newworld);
@@ -230,9 +232,6 @@ EXPORT_SYMBOL(find_all_nodes);
EXPORT_SYMBOL(get_property);
EXPORT_SYMBOL(request_OF_resource);
EXPORT_SYMBOL(release_OF_resource);
-EXPORT_SYMBOL(pci_busdev_to_OF_node);
-EXPORT_SYMBOL(pci_device_to_OF_node);
-EXPORT_SYMBOL(pci_device_from_OF_node);
EXPORT_SYMBOL(of_find_node_by_name);
EXPORT_SYMBOL(of_find_node_by_type);
EXPORT_SYMBOL(of_find_compatible_node);
@@ -272,16 +271,6 @@ EXPORT_SYMBOL(screen_info);
#endif
EXPORT_SYMBOL(__delay);
-#ifndef INLINE_IRQS
-EXPORT_SYMBOL(local_irq_enable);
-EXPORT_SYMBOL(local_irq_enable_end);
-EXPORT_SYMBOL(local_irq_disable);
-EXPORT_SYMBOL(local_irq_disable_end);
-EXPORT_SYMBOL(local_save_flags_ptr);
-EXPORT_SYMBOL(local_save_flags_ptr_end);
-EXPORT_SYMBOL(local_irq_restore);
-EXPORT_SYMBOL(local_irq_restore_end);
-#endif
EXPORT_SYMBOL(timer_interrupt);
EXPORT_SYMBOL(irq_desc);
EXPORT_SYMBOL(tb_ticks_per_jiffy);
@@ -335,11 +324,6 @@ EXPORT_SYMBOL(mmu_hash_lock); /* For MOL */
extern long *intercept_table;
EXPORT_SYMBOL(intercept_table);
#endif /* CONFIG_PPC_STD_MMU */
-EXPORT_SYMBOL(cur_cpu_spec);
-#ifdef CONFIG_PPC_PMAC
-extern unsigned long agp_special_page;
-EXPORT_SYMBOL(agp_special_page);
-#endif
#if defined(CONFIG_40x) || defined(CONFIG_BOOKE)
EXPORT_SYMBOL(__mtdcr);
EXPORT_SYMBOL(__mfdcr);
diff --git a/arch/ppc/kernel/process.c b/arch/ppc/kernel/process.c
index 82de66e4db6d..cb1c7b92f8c6 100644
--- a/arch/ppc/kernel/process.c
+++ b/arch/ppc/kernel/process.c
@@ -152,18 +152,66 @@ int check_stack(struct task_struct *tsk)
}
#endif /* defined(CHECK_STACK) */
-#ifdef CONFIG_ALTIVEC
-int
-dump_altivec(struct pt_regs *regs, elf_vrregset_t *vrregs)
+/*
+ * Make sure the floating-point register state in the
+ * the thread_struct is up to date for task tsk.
+ */
+void flush_fp_to_thread(struct task_struct *tsk)
{
- if (regs->msr & MSR_VEC)
- giveup_altivec(current);
- memcpy(vrregs, &current->thread.vr[0], sizeof(*vrregs));
+ if (tsk->thread.regs) {
+ /*
+ * We need to disable preemption here because if we didn't,
+ * another process could get scheduled after the regs->msr
+ * test but before we have finished saving the FP registers
+ * to the thread_struct. That process could take over the
+ * FPU, and then when we get scheduled again we would store
+ * bogus values for the remaining FP registers.
+ */
+ preempt_disable();
+ if (tsk->thread.regs->msr & MSR_FP) {
+#ifdef CONFIG_SMP
+ /*
+ * This should only ever be called for current or
+ * for a stopped child process. Since we save away
+ * the FP register state on context switch on SMP,
+ * there is something wrong if a stopped child appears
+ * to still have its FP state in the CPU registers.
+ */
+ BUG_ON(tsk != current);
+#endif
+ giveup_fpu(current);
+ }
+ preempt_enable();
+ }
+}
+
+void enable_kernel_fp(void)
+{
+ WARN_ON(preemptible());
+
+#ifdef CONFIG_SMP
+ if (current->thread.regs && (current->thread.regs->msr & MSR_FP))
+ giveup_fpu(current);
+ else
+ giveup_fpu(NULL); /* just enables FP for kernel */
+#else
+ giveup_fpu(last_task_used_math);
+#endif /* CONFIG_SMP */
+}
+EXPORT_SYMBOL(enable_kernel_fp);
+
+int dump_task_fpu(struct task_struct *tsk, elf_fpregset_t *fpregs)
+{
+ preempt_disable();
+ if (tsk->thread.regs && (tsk->thread.regs->msr & MSR_FP))
+ giveup_fpu(tsk);
+ preempt_enable();
+ memcpy(fpregs, &tsk->thread.fpr[0], sizeof(*fpregs));
return 1;
}
-void
-enable_kernel_altivec(void)
+#ifdef CONFIG_ALTIVEC
+void enable_kernel_altivec(void)
{
WARN_ON(preemptible());
@@ -177,19 +225,35 @@ enable_kernel_altivec(void)
#endif /* __SMP __ */
}
EXPORT_SYMBOL(enable_kernel_altivec);
-#endif /* CONFIG_ALTIVEC */
-#ifdef CONFIG_SPE
-int
-dump_spe(struct pt_regs *regs, elf_vrregset_t *evrregs)
+/*
+ * Make sure the VMX/Altivec register state in the
+ * the thread_struct is up to date for task tsk.
+ */
+void flush_altivec_to_thread(struct task_struct *tsk)
{
- if (regs->msr & MSR_SPE)
- giveup_spe(current);
- /* We copy u32 evr[32] + u64 acc + u32 spefscr -> 35 */
- memcpy(evrregs, &current->thread.evr[0], sizeof(u32) * 35);
+ if (tsk->thread.regs) {
+ preempt_disable();
+ if (tsk->thread.regs->msr & MSR_VEC) {
+#ifdef CONFIG_SMP
+ BUG_ON(tsk != current);
+#endif
+ giveup_altivec(current);
+ }
+ preempt_enable();
+ }
+}
+
+int dump_altivec(struct pt_regs *regs, elf_vrregset_t *vrregs)
+{
+ if (regs->msr & MSR_VEC)
+ giveup_altivec(current);
+ memcpy(vrregs, &current->thread.vr[0], sizeof(*vrregs));
return 1;
}
+#endif /* CONFIG_ALTIVEC */
+#ifdef CONFIG_SPE
void
enable_kernel_spe(void)
{
@@ -205,34 +269,30 @@ enable_kernel_spe(void)
#endif /* __SMP __ */
}
EXPORT_SYMBOL(enable_kernel_spe);
-#endif /* CONFIG_SPE */
-void
-enable_kernel_fp(void)
+void flush_spe_to_thread(struct task_struct *tsk)
{
- WARN_ON(preemptible());
-
+ if (tsk->thread.regs) {
+ preempt_disable();
+ if (tsk->thread.regs->msr & MSR_SPE) {
#ifdef CONFIG_SMP
- if (current->thread.regs && (current->thread.regs->msr & MSR_FP))
- giveup_fpu(current);
- else
- giveup_fpu(NULL); /* just enables FP for kernel */
-#else
- giveup_fpu(last_task_used_math);
-#endif /* CONFIG_SMP */
+ BUG_ON(tsk != current);
+#endif
+ giveup_spe(current);
+ }
+ preempt_enable();
+ }
}
-EXPORT_SYMBOL(enable_kernel_fp);
-int
-dump_task_fpu(struct task_struct *tsk, elf_fpregset_t *fpregs)
+int dump_spe(struct pt_regs *regs, elf_vrregset_t *evrregs)
{
- preempt_disable();
- if (tsk->thread.regs && (tsk->thread.regs->msr & MSR_FP))
- giveup_fpu(tsk);
- preempt_enable();
- memcpy(fpregs, &tsk->thread.fpr[0], sizeof(*fpregs));
+ if (regs->msr & MSR_SPE)
+ giveup_spe(current);
+ /* We copy u32 evr[32] + u64 acc + u32 spefscr -> 35 */
+ memcpy(evrregs, &current->thread.evr[0], sizeof(u32) * 35);
return 1;
}
+#endif /* CONFIG_SPE */
struct task_struct *__switch_to(struct task_struct *prev,
struct task_struct *new)
@@ -287,11 +347,13 @@ struct task_struct *__switch_to(struct task_struct *prev,
#endif /* CONFIG_SPE */
#endif /* CONFIG_SMP */
+#ifdef CONFIG_ALTIVEC
/* Avoid the trap. On smp this this never happens since
* we don't set last_task_used_altivec -- Cort
*/
if (new->thread.regs && last_task_used_altivec == new)
new->thread.regs->msr |= MSR_VEC;
+#endif
#ifdef CONFIG_SPE
/* Avoid the trap. On smp this this never happens since
* we don't set last_task_used_spe
@@ -482,7 +544,7 @@ void start_thread(struct pt_regs *regs, unsigned long nip, unsigned long sp)
last_task_used_spe = NULL;
#endif
memset(current->thread.fpr, 0, sizeof(current->thread.fpr));
- current->thread.fpscr = 0;
+ current->thread.fpscr.val = 0;
#ifdef CONFIG_ALTIVEC
memset(current->thread.vr, 0, sizeof(current->thread.vr));
memset(&current->thread.vscr, 0, sizeof(current->thread.vscr));
@@ -557,14 +619,16 @@ int sys_clone(unsigned long clone_flags, unsigned long usp,
return do_fork(clone_flags, usp, regs, 0, parent_tidp, child_tidp);
}
-int sys_fork(int p1, int p2, int p3, int p4, int p5, int p6,
+int sys_fork(unsigned long p1, unsigned long p2, unsigned long p3,
+ unsigned long p4, unsigned long p5, unsigned long p6,
struct pt_regs *regs)
{
CHECK_FULL_REGS(regs);
return do_fork(SIGCHLD, regs->gpr[1], regs, 0, NULL, NULL);
}
-int sys_vfork(int p1, int p2, int p3, int p4, int p5, int p6,
+int sys_vfork(unsigned long p1, unsigned long p2, unsigned long p3,
+ unsigned long p4, unsigned long p5, unsigned long p6,
struct pt_regs *regs)
{
CHECK_FULL_REGS(regs);
diff --git a/arch/ppc/kernel/rio.c b/arch/ppc/kernel/rio.c
new file mode 100644
index 000000000000..29487fedfc76
--- /dev/null
+++ b/arch/ppc/kernel/rio.c
@@ -0,0 +1,52 @@
+/*
+ * RapidIO PPC32 support
+ *
+ * Copyright 2005 MontaVista Software, Inc.
+ * Matt Porter <mporter@kernel.crashing.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/init.h>
+#include <linux/kernel.h>
+#include <linux/rio.h>
+
+#include <asm/rio.h>
+
+/**
+ * platform_rio_init - Do platform specific RIO init
+ *
+ * Any platform specific initialization of RapdIO
+ * hardware is done here as well as registration
+ * of any active master ports in the system.
+ */
+void __attribute__ ((weak))
+ platform_rio_init(void)
+{
+ printk(KERN_WARNING "RIO: No platform_rio_init() present\n");
+}
+
+/**
+ * ppc_rio_init - Do PPC32 RIO init
+ *
+ * Calls platform-specific RIO init code and then calls
+ * rio_init_mports() to initialize any master ports that
+ * have been registered with the RIO subsystem.
+ */
+static int __init ppc_rio_init(void)
+{
+ printk(KERN_INFO "RIO: RapidIO init\n");
+
+ /* Platform specific initialization */
+ platform_rio_init();
+
+ /* Enumerate all registered ports */
+ rio_init_mports();
+
+ return 0;
+}
+
+subsys_initcall(ppc_rio_init);
diff --git a/arch/ppc/kernel/setup.c b/arch/ppc/kernel/setup.c
index 545cfd0fab59..dc55e1abc45b 100644
--- a/arch/ppc/kernel/setup.c
+++ b/arch/ppc/kernel/setup.c
@@ -71,10 +71,12 @@ struct ide_machdep_calls ppc_ide_md;
unsigned long boot_mem_size;
unsigned long ISA_DMA_THRESHOLD;
-unsigned long DMA_MODE_READ, DMA_MODE_WRITE;
+unsigned int DMA_MODE_READ;
+unsigned int DMA_MODE_WRITE;
#ifdef CONFIG_PPC_MULTIPLATFORM
int _machine = 0;
+EXPORT_SYMBOL(_machine);
extern void prep_init(unsigned long r3, unsigned long r4,
unsigned long r5, unsigned long r6, unsigned long r7);
@@ -82,8 +84,18 @@ extern void pmac_init(unsigned long r3, unsigned long r4,
unsigned long r5, unsigned long r6, unsigned long r7);
extern void chrp_init(unsigned long r3, unsigned long r4,
unsigned long r5, unsigned long r6, unsigned long r7);
+
+dev_t boot_dev;
#endif /* CONFIG_PPC_MULTIPLATFORM */
+int have_of;
+EXPORT_SYMBOL(have_of);
+
+#ifdef __DO_IRQ_CANON
+int ppc_do_canonicalize_irqs;
+EXPORT_SYMBOL(ppc_do_canonicalize_irqs);
+#endif
+
#ifdef CONFIG_MAGIC_SYSRQ
unsigned long SYSRQ_KEY = 0x54;
#endif /* CONFIG_MAGIC_SYSRQ */
@@ -185,18 +197,18 @@ int show_cpuinfo(struct seq_file *m, void *v)
seq_printf(m, "processor\t: %d\n", i);
seq_printf(m, "cpu\t\t: ");
- if (cur_cpu_spec[i]->pvr_mask)
- seq_printf(m, "%s", cur_cpu_spec[i]->cpu_name);
+ if (cur_cpu_spec->pvr_mask)
+ seq_printf(m, "%s", cur_cpu_spec->cpu_name);
else
seq_printf(m, "unknown (%08x)", pvr);
#ifdef CONFIG_ALTIVEC
- if (cur_cpu_spec[i]->cpu_features & CPU_FTR_ALTIVEC)
+ if (cur_cpu_spec->cpu_features & CPU_FTR_ALTIVEC)
seq_printf(m, ", altivec supported");
#endif
seq_printf(m, "\n");
#ifdef CONFIG_TAU
- if (cur_cpu_spec[i]->cpu_features & CPU_FTR_TAU) {
+ if (cur_cpu_spec->cpu_features & CPU_FTR_TAU) {
#ifdef CONFIG_TAU_AVERAGE
/* more straightforward, but potentially misleading */
seq_printf(m, "temperature \t: %u C (uncalibrated)\n",
@@ -339,7 +351,7 @@ early_init(int r3, int r4, int r5)
* Assume here that all clock rates are the same in a
* smp system. -- Cort
*/
-int __openfirmware
+int
of_show_percpuinfo(struct seq_file *m, int i)
{
struct device_node *cpu_node;
@@ -404,11 +416,15 @@ platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
_machine = _MACH_prep;
}
+#ifdef CONFIG_PPC_PREP
/* not much more to do here, if prep */
if (_machine == _MACH_prep) {
prep_init(r3, r4, r5, r6, r7);
return;
}
+#endif
+
+ have_of = 1;
/* prom_init has already been called from __start */
if (boot_infos)
@@ -479,12 +495,16 @@ platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
#endif /* CONFIG_ADB */
switch (_machine) {
+#ifdef CONFIG_PPC_PMAC
case _MACH_Pmac:
pmac_init(r3, r4, r5, r6, r7);
break;
+#endif
+#ifdef CONFIG_PPC_CHRP
case _MACH_chrp:
chrp_init(r3, r4, r5, r6, r7);
break;
+#endif
}
}
@@ -721,7 +741,7 @@ void __init setup_arch(char **cmdline_p)
#endif
#ifdef CONFIG_XMON
- xmon_map_scc();
+ xmon_init(1);
if (strstr(cmd_line, "xmon"))
xmon(NULL);
#endif /* CONFIG_XMON */
@@ -745,12 +765,12 @@ void __init setup_arch(char **cmdline_p)
* for a possibly more accurate value.
*/
if (cpu_has_feature(CPU_FTR_SPLIT_ID_CACHE)) {
- dcache_bsize = cur_cpu_spec[0]->dcache_bsize;
- icache_bsize = cur_cpu_spec[0]->icache_bsize;
+ dcache_bsize = cur_cpu_spec->dcache_bsize;
+ icache_bsize = cur_cpu_spec->icache_bsize;
ucache_bsize = 0;
} else
ucache_bsize = dcache_bsize = icache_bsize
- = cur_cpu_spec[0]->dcache_bsize;
+ = cur_cpu_spec->dcache_bsize;
/* reboot on panic */
panic_timeout = 180;
diff --git a/arch/ppc/kernel/signal.c b/arch/ppc/kernel/signal.c
deleted file mode 100644
index 2244bf91e593..000000000000
--- a/arch/ppc/kernel/signal.c
+++ /dev/null
@@ -1,771 +0,0 @@
-/*
- * arch/ppc/kernel/signal.c
- *
- * PowerPC version
- * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
- *
- * Derived from "arch/i386/kernel/signal.c"
- * Copyright (C) 1991, 1992 Linus Torvalds
- * 1997-11-28 Modified for POSIX.1b signals by Richard Henderson
- *
- * 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/sched.h>
-#include <linux/mm.h>
-#include <linux/smp.h>
-#include <linux/smp_lock.h>
-#include <linux/kernel.h>
-#include <linux/signal.h>
-#include <linux/errno.h>
-#include <linux/wait.h>
-#include <linux/ptrace.h>
-#include <linux/unistd.h>
-#include <linux/stddef.h>
-#include <linux/elf.h>
-#include <linux/tty.h>
-#include <linux/binfmts.h>
-#include <linux/suspend.h>
-#include <asm/ucontext.h>
-#include <asm/uaccess.h>
-#include <asm/pgtable.h>
-#include <asm/cacheflush.h>
-
-#undef DEBUG_SIG
-
-#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
-
-extern void sigreturn_exit(struct pt_regs *);
-
-#define GP_REGS_SIZE min(sizeof(elf_gregset_t), sizeof(struct pt_regs))
-
-int do_signal(sigset_t *oldset, struct pt_regs *regs);
-
-/*
- * Atomically swap in the new signal mask, and wait for a signal.
- */
-int
-sys_sigsuspend(old_sigset_t mask, int p2, int p3, int p4, int p6, int p7,
- struct pt_regs *regs)
-{
- sigset_t saveset;
-
- mask &= _BLOCKABLE;
- spin_lock_irq(&current->sighand->siglock);
- saveset = current->blocked;
- siginitset(&current->blocked, mask);
- recalc_sigpending();
- spin_unlock_irq(&current->sighand->siglock);
-
- regs->result = -EINTR;
- regs->gpr[3] = EINTR;
- regs->ccr |= 0x10000000;
- while (1) {
- current->state = TASK_INTERRUPTIBLE;
- schedule();
- if (do_signal(&saveset, regs))
- sigreturn_exit(regs);
- }
-}
-
-int
-sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize, int p3, int p4,
- int p6, int p7, struct pt_regs *regs)
-{
- sigset_t saveset, newset;
-
- /* XXX: Don't preclude handling different sized sigset_t's. */
- if (sigsetsize != sizeof(sigset_t))
- return -EINVAL;
-
- if (copy_from_user(&newset, unewset, sizeof(newset)))
- return -EFAULT;
- sigdelsetmask(&newset, ~_BLOCKABLE);
-
- spin_lock_irq(&current->sighand->siglock);
- saveset = current->blocked;
- current->blocked = newset;
- recalc_sigpending();
- spin_unlock_irq(&current->sighand->siglock);
-
- regs->result = -EINTR;
- regs->gpr[3] = EINTR;
- regs->ccr |= 0x10000000;
- while (1) {
- current->state = TASK_INTERRUPTIBLE;
- schedule();
- if (do_signal(&saveset, regs))
- sigreturn_exit(regs);
- }
-}
-
-
-int
-sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss, int r5,
- int r6, int r7, int r8, struct pt_regs *regs)
-{
- return do_sigaltstack(uss, uoss, regs->gpr[1]);
-}
-
-int
-sys_sigaction(int sig, const struct old_sigaction __user *act,
- struct old_sigaction __user *oact)
-{
- struct k_sigaction new_ka, old_ka;
- int ret;
-
- if (act) {
- old_sigset_t mask;
- if (!access_ok(VERIFY_READ, act, sizeof(*act)) ||
- __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
- __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
- return -EFAULT;
- __get_user(new_ka.sa.sa_flags, &act->sa_flags);
- __get_user(mask, &act->sa_mask);
- siginitset(&new_ka.sa.sa_mask, mask);
- }
-
- ret = do_sigaction(sig, (act? &new_ka: NULL), (oact? &old_ka: NULL));
-
- if (!ret && oact) {
- if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) ||
- __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
- __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
- return -EFAULT;
- __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
- __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
- }
-
- return ret;
-}
-
-/*
- * When we have signals to deliver, we set up on the
- * user stack, going down from the original stack pointer:
- * a sigregs struct
- * a sigcontext struct
- * a gap of __SIGNAL_FRAMESIZE bytes
- *
- * Each of these things must be a multiple of 16 bytes in size.
- *
- */
-struct sigregs {
- struct mcontext mctx; /* all the register values */
- /* Programs using the rs6000/xcoff abi can save up to 19 gp regs
- and 18 fp regs below sp before decrementing it. */
- int abigap[56];
-};
-
-/* We use the mc_pad field for the signal return trampoline. */
-#define tramp mc_pad
-
-/*
- * When we have rt signals to deliver, we set up on the
- * user stack, going down from the original stack pointer:
- * one rt_sigframe struct (siginfo + ucontext + ABI gap)
- * a gap of __SIGNAL_FRAMESIZE+16 bytes
- * (the +16 is to get the siginfo and ucontext in the same
- * positions as in older kernels).
- *
- * Each of these things must be a multiple of 16 bytes in size.
- *
- */
-struct rt_sigframe
-{
- struct siginfo info;
- struct ucontext uc;
- /* Programs using the rs6000/xcoff abi can save up to 19 gp regs
- and 18 fp regs below sp before decrementing it. */
- int abigap[56];
-};
-
-/*
- * Save the current user registers on the user stack.
- * We only save the altivec/spe registers if the process has used
- * altivec/spe instructions at some point.
- */
-static int
-save_user_regs(struct pt_regs *regs, struct mcontext __user *frame, int sigret)
-{
- /* save general and floating-point registers */
- CHECK_FULL_REGS(regs);
- preempt_disable();
- if (regs->msr & MSR_FP)
- giveup_fpu(current);
-#ifdef CONFIG_ALTIVEC
- if (current->thread.used_vr && (regs->msr & MSR_VEC))
- giveup_altivec(current);
-#endif /* CONFIG_ALTIVEC */
-#ifdef CONFIG_SPE
- if (current->thread.used_spe && (regs->msr & MSR_SPE))
- giveup_spe(current);
-#endif /* CONFIG_ALTIVEC */
- preempt_enable();
-
- if (__copy_to_user(&frame->mc_gregs, regs, GP_REGS_SIZE)
- || __copy_to_user(&frame->mc_fregs, current->thread.fpr,
- ELF_NFPREG * sizeof(double)))
- return 1;
-
- current->thread.fpscr = 0; /* turn off all fp exceptions */
-
-#ifdef CONFIG_ALTIVEC
- /* save altivec registers */
- if (current->thread.used_vr) {
- if (__copy_to_user(&frame->mc_vregs, current->thread.vr,
- ELF_NVRREG * sizeof(vector128)))
- return 1;
- /* set MSR_VEC in the saved MSR value to indicate that
- frame->mc_vregs contains valid data */
- if (__put_user(regs->msr | MSR_VEC, &frame->mc_gregs[PT_MSR]))
- return 1;
- }
- /* else assert((regs->msr & MSR_VEC) == 0) */
-
- /* We always copy to/from vrsave, it's 0 if we don't have or don't
- * use altivec. Since VSCR only contains 32 bits saved in the least
- * significant bits of a vector, we "cheat" and stuff VRSAVE in the
- * most significant bits of that same vector. --BenH
- */
- if (__put_user(current->thread.vrsave, (u32 __user *)&frame->mc_vregs[32]))
- return 1;
-#endif /* CONFIG_ALTIVEC */
-
-#ifdef CONFIG_SPE
- /* save spe registers */
- if (current->thread.used_spe) {
- if (__copy_to_user(&frame->mc_vregs, current->thread.evr,
- ELF_NEVRREG * sizeof(u32)))
- return 1;
- /* set MSR_SPE in the saved MSR value to indicate that
- frame->mc_vregs contains valid data */
- if (__put_user(regs->msr | MSR_SPE, &frame->mc_gregs[PT_MSR]))
- return 1;
- }
- /* else assert((regs->msr & MSR_SPE) == 0) */
-
- /* We always copy to/from spefscr */
- if (__put_user(current->thread.spefscr, (u32 *)&frame->mc_vregs + ELF_NEVRREG))
- return 1;
-#endif /* CONFIG_SPE */
-
- if (sigret) {
- /* Set up the sigreturn trampoline: li r0,sigret; sc */
- if (__put_user(0x38000000UL + sigret, &frame->tramp[0])
- || __put_user(0x44000002UL, &frame->tramp[1]))
- return 1;
- flush_icache_range((unsigned long) &frame->tramp[0],
- (unsigned long) &frame->tramp[2]);
- }
-
- return 0;
-}
-
-/*
- * Restore the current user register values from the user stack,
- * (except for MSR).
- */
-static int
-restore_user_regs(struct pt_regs *regs, struct mcontext __user *sr, int sig)
-{
- unsigned long save_r2 = 0;
-#if defined(CONFIG_ALTIVEC) || defined(CONFIG_SPE)
- unsigned long msr;
-#endif
-
- /* backup/restore the TLS as we don't want it to be modified */
- if (!sig)
- save_r2 = regs->gpr[2];
- /* copy up to but not including MSR */
- if (__copy_from_user(regs, &sr->mc_gregs, PT_MSR * sizeof(elf_greg_t)))
- return 1;
- /* copy from orig_r3 (the word after the MSR) up to the end */
- if (__copy_from_user(&regs->orig_gpr3, &sr->mc_gregs[PT_ORIG_R3],
- GP_REGS_SIZE - PT_ORIG_R3 * sizeof(elf_greg_t)))
- return 1;
- if (!sig)
- regs->gpr[2] = save_r2;
-
- /* force the process to reload the FP registers from
- current->thread when it next does FP instructions */
- regs->msr &= ~(MSR_FP | MSR_FE0 | MSR_FE1);
- if (__copy_from_user(current->thread.fpr, &sr->mc_fregs,
- sizeof(sr->mc_fregs)))
- return 1;
-
-#ifdef CONFIG_ALTIVEC
- /* force the process to reload the altivec registers from
- current->thread when it next does altivec instructions */
- regs->msr &= ~MSR_VEC;
- if (!__get_user(msr, &sr->mc_gregs[PT_MSR]) && (msr & MSR_VEC) != 0) {
- /* restore altivec registers from the stack */
- if (__copy_from_user(current->thread.vr, &sr->mc_vregs,
- sizeof(sr->mc_vregs)))
- return 1;
- } else if (current->thread.used_vr)
- memset(&current->thread.vr, 0, ELF_NVRREG * sizeof(vector128));
-
- /* Always get VRSAVE back */
- if (__get_user(current->thread.vrsave, (u32 __user *)&sr->mc_vregs[32]))
- return 1;
-#endif /* CONFIG_ALTIVEC */
-
-#ifdef CONFIG_SPE
- /* force the process to reload the spe registers from
- current->thread when it next does spe instructions */
- regs->msr &= ~MSR_SPE;
- if (!__get_user(msr, &sr->mc_gregs[PT_MSR]) && (msr & MSR_SPE) != 0) {
- /* restore spe registers from the stack */
- if (__copy_from_user(current->thread.evr, &sr->mc_vregs,
- ELF_NEVRREG * sizeof(u32)))
- return 1;
- } else if (current->thread.used_spe)
- memset(&current->thread.evr, 0, ELF_NEVRREG * sizeof(u32));
-
- /* Always get SPEFSCR back */
- if (__get_user(current->thread.spefscr, (u32 *)&sr->mc_vregs + ELF_NEVRREG))
- return 1;
-#endif /* CONFIG_SPE */
-
-#ifndef CONFIG_SMP
- preempt_disable();
- if (last_task_used_math == current)
- last_task_used_math = NULL;
- if (last_task_used_altivec == current)
- last_task_used_altivec = NULL;
- if (last_task_used_spe == current)
- last_task_used_spe = NULL;
- preempt_enable();
-#endif
- return 0;
-}
-
-/*
- * Restore the user process's signal mask
- */
-static void
-restore_sigmask(sigset_t *set)
-{
- sigdelsetmask(set, ~_BLOCKABLE);
- spin_lock_irq(&current->sighand->siglock);
- current->blocked = *set;
- recalc_sigpending();
- spin_unlock_irq(&current->sighand->siglock);
-}
-
-/*
- * Set up a signal frame for a "real-time" signal handler
- * (one which gets siginfo).
- */
-static void
-handle_rt_signal(unsigned long sig, struct k_sigaction *ka,
- siginfo_t *info, sigset_t *oldset, struct pt_regs * regs,
- unsigned long newsp)
-{
- struct rt_sigframe __user *rt_sf;
- struct mcontext __user *frame;
- unsigned long origsp = newsp;
-
- /* Set up Signal Frame */
- /* Put a Real Time Context onto stack */
- newsp -= sizeof(*rt_sf);
- rt_sf = (struct rt_sigframe __user *) newsp;
-
- /* create a stack frame for the caller of the handler */
- newsp -= __SIGNAL_FRAMESIZE + 16;
-
- if (!access_ok(VERIFY_WRITE, (void __user *) newsp, origsp - newsp))
- goto badframe;
-
- /* Put the siginfo & fill in most of the ucontext */
- if (copy_siginfo_to_user(&rt_sf->info, info)
- || __put_user(0, &rt_sf->uc.uc_flags)
- || __put_user(0, &rt_sf->uc.uc_link)
- || __put_user(current->sas_ss_sp, &rt_sf->uc.uc_stack.ss_sp)
- || __put_user(sas_ss_flags(regs->gpr[1]),
- &rt_sf->uc.uc_stack.ss_flags)
- || __put_user(current->sas_ss_size, &rt_sf->uc.uc_stack.ss_size)
- || __put_user(&rt_sf->uc.uc_mcontext, &rt_sf->uc.uc_regs)
- || __copy_to_user(&rt_sf->uc.uc_sigmask, oldset, sizeof(*oldset)))
- goto badframe;
-
- /* Save user registers on the stack */
- frame = &rt_sf->uc.uc_mcontext;
- if (save_user_regs(regs, frame, __NR_rt_sigreturn))
- goto badframe;
-
- if (put_user(regs->gpr[1], (unsigned long __user *)newsp))
- goto badframe;
- regs->gpr[1] = newsp;
- regs->gpr[3] = sig;
- regs->gpr[4] = (unsigned long) &rt_sf->info;
- regs->gpr[5] = (unsigned long) &rt_sf->uc;
- regs->gpr[6] = (unsigned long) rt_sf;
- regs->nip = (unsigned long) ka->sa.sa_handler;
- regs->link = (unsigned long) frame->tramp;
- regs->trap = 0;
-
- return;
-
-badframe:
-#ifdef DEBUG_SIG
- printk("badframe in handle_rt_signal, regs=%p frame=%p newsp=%lx\n",
- regs, frame, newsp);
-#endif
- force_sigsegv(sig, current);
-}
-
-static int do_setcontext(struct ucontext __user *ucp, struct pt_regs *regs, int sig)
-{
- sigset_t set;
- struct mcontext __user *mcp;
-
- if (__copy_from_user(&set, &ucp->uc_sigmask, sizeof(set))
- || __get_user(mcp, &ucp->uc_regs))
- return -EFAULT;
- restore_sigmask(&set);
- if (restore_user_regs(regs, mcp, sig))
- return -EFAULT;
-
- return 0;
-}
-
-int sys_swapcontext(struct ucontext __user *old_ctx,
- struct ucontext __user *new_ctx,
- int ctx_size, int r6, int r7, int r8, struct pt_regs *regs)
-{
- unsigned char tmp;
-
- /* Context size is for future use. Right now, we only make sure
- * we are passed something we understand
- */
- if (ctx_size < sizeof(struct ucontext))
- return -EINVAL;
-
- if (old_ctx != NULL) {
- if (!access_ok(VERIFY_WRITE, old_ctx, sizeof(*old_ctx))
- || save_user_regs(regs, &old_ctx->uc_mcontext, 0)
- || __copy_to_user(&old_ctx->uc_sigmask,
- &current->blocked, sizeof(sigset_t))
- || __put_user(&old_ctx->uc_mcontext, &old_ctx->uc_regs))
- return -EFAULT;
- }
- if (new_ctx == NULL)
- return 0;
- if (!access_ok(VERIFY_READ, new_ctx, sizeof(*new_ctx))
- || __get_user(tmp, (u8 __user *) new_ctx)
- || __get_user(tmp, (u8 __user *) (new_ctx + 1) - 1))
- return -EFAULT;
-
- /*
- * If we get a fault copying the context into the kernel's
- * image of the user's registers, we can't just return -EFAULT
- * because the user's registers will be corrupted. For instance
- * the NIP value may have been updated but not some of the
- * other registers. Given that we have done the access_ok
- * and successfully read the first and last bytes of the region
- * above, this should only happen in an out-of-memory situation
- * or if another thread unmaps the region containing the context.
- * We kill the task with a SIGSEGV in this situation.
- */
- if (do_setcontext(new_ctx, regs, 0))
- do_exit(SIGSEGV);
- sigreturn_exit(regs);
- /* doesn't actually return back to here */
- return 0;
-}
-
-int sys_rt_sigreturn(int r3, int r4, int r5, int r6, int r7, int r8,
- struct pt_regs *regs)
-{
- struct rt_sigframe __user *rt_sf;
-
- /* Always make any pending restarted system calls return -EINTR */
- current_thread_info()->restart_block.fn = do_no_restart_syscall;
-
- rt_sf = (struct rt_sigframe __user *)
- (regs->gpr[1] + __SIGNAL_FRAMESIZE + 16);
- if (!access_ok(VERIFY_READ, rt_sf, sizeof(struct rt_sigframe)))
- goto bad;
- if (do_setcontext(&rt_sf->uc, regs, 1))
- goto bad;
-
- /*
- * It's not clear whether or why it is desirable to save the
- * sigaltstack setting on signal delivery and restore it on
- * signal return. But other architectures do this and we have
- * always done it up until now so it is probably better not to
- * change it. -- paulus
- */
- do_sigaltstack(&rt_sf->uc.uc_stack, NULL, regs->gpr[1]);
-
- sigreturn_exit(regs); /* doesn't return here */
- return 0;
-
- bad:
- force_sig(SIGSEGV, current);
- return 0;
-}
-
-int sys_debug_setcontext(struct ucontext __user *ctx,
- int ndbg, struct sig_dbg_op __user *dbg,
- int r6, int r7, int r8,
- struct pt_regs *regs)
-{
- struct sig_dbg_op op;
- int i;
- unsigned long new_msr = regs->msr;
-#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
- unsigned long new_dbcr0 = current->thread.dbcr0;
-#endif
-
- for (i=0; i<ndbg; i++) {
- if (__copy_from_user(&op, dbg, sizeof(op)))
- return -EFAULT;
- switch (op.dbg_type) {
- case SIG_DBG_SINGLE_STEPPING:
-#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
- if (op.dbg_value) {
- new_msr |= MSR_DE;
- new_dbcr0 |= (DBCR0_IDM | DBCR0_IC);
- } else {
- new_msr &= ~MSR_DE;
- new_dbcr0 &= ~(DBCR0_IDM | DBCR0_IC);
- }
-#else
- if (op.dbg_value)
- new_msr |= MSR_SE;
- else
- new_msr &= ~MSR_SE;
-#endif
- break;
- case SIG_DBG_BRANCH_TRACING:
-#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
- return -EINVAL;
-#else
- if (op.dbg_value)
- new_msr |= MSR_BE;
- else
- new_msr &= ~MSR_BE;
-#endif
- break;
-
- default:
- return -EINVAL;
- }
- }
-
- /* We wait until here to actually install the values in the
- registers so if we fail in the above loop, it will not
- affect the contents of these registers. After this point,
- failure is a problem, anyway, and it's very unlikely unless
- the user is really doing something wrong. */
- regs->msr = new_msr;
-#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
- current->thread.dbcr0 = new_dbcr0;
-#endif
-
- /*
- * If we get a fault copying the context into the kernel's
- * image of the user's registers, we can't just return -EFAULT
- * because the user's registers will be corrupted. For instance
- * the NIP value may have been updated but not some of the
- * other registers. Given that we have done the access_ok
- * and successfully read the first and last bytes of the region
- * above, this should only happen in an out-of-memory situation
- * or if another thread unmaps the region containing the context.
- * We kill the task with a SIGSEGV in this situation.
- */
- if (do_setcontext(ctx, regs, 1)) {
- force_sig(SIGSEGV, current);
- goto out;
- }
-
- /*
- * It's not clear whether or why it is desirable to save the
- * sigaltstack setting on signal delivery and restore it on
- * signal return. But other architectures do this and we have
- * always done it up until now so it is probably better not to
- * change it. -- paulus
- */
- do_sigaltstack(&ctx->uc_stack, NULL, regs->gpr[1]);
-
- sigreturn_exit(regs);
- /* doesn't actually return back to here */
-
- out:
- return 0;
-}
-
-/*
- * OK, we're invoking a handler
- */
-static void
-handle_signal(unsigned long sig, struct k_sigaction *ka,
- siginfo_t *info, sigset_t *oldset, struct pt_regs * regs,
- unsigned long newsp)
-{
- struct sigcontext __user *sc;
- struct sigregs __user *frame;
- unsigned long origsp = newsp;
-
- /* Set up Signal Frame */
- newsp -= sizeof(struct sigregs);
- frame = (struct sigregs __user *) newsp;
-
- /* Put a sigcontext on the stack */
- newsp -= sizeof(*sc);
- sc = (struct sigcontext __user *) newsp;
-
- /* create a stack frame for the caller of the handler */
- newsp -= __SIGNAL_FRAMESIZE;
-
- if (!access_ok(VERIFY_WRITE, (void __user *) newsp, origsp - newsp))
- goto badframe;
-
-#if _NSIG != 64
-#error "Please adjust handle_signal()"
-#endif
- if (__put_user((unsigned long) ka->sa.sa_handler, &sc->handler)
- || __put_user(oldset->sig[0], &sc->oldmask)
- || __put_user(oldset->sig[1], &sc->_unused[3])
- || __put_user((struct pt_regs __user *)frame, &sc->regs)
- || __put_user(sig, &sc->signal))
- goto badframe;
-
- if (save_user_regs(regs, &frame->mctx, __NR_sigreturn))
- goto badframe;
-
- if (put_user(regs->gpr[1], (unsigned long __user *)newsp))
- goto badframe;
- regs->gpr[1] = newsp;
- regs->gpr[3] = sig;
- regs->gpr[4] = (unsigned long) sc;
- regs->nip = (unsigned long) ka->sa.sa_handler;
- regs->link = (unsigned long) frame->mctx.tramp;
- regs->trap = 0;
-
- return;
-
-badframe:
-#ifdef DEBUG_SIG
- printk("badframe in handle_signal, regs=%p frame=%p newsp=%lx\n",
- regs, frame, newsp);
-#endif
- force_sigsegv(sig, current);
-}
-
-/*
- * Do a signal return; undo the signal stack.
- */
-int sys_sigreturn(int r3, int r4, int r5, int r6, int r7, int r8,
- struct pt_regs *regs)
-{
- struct sigcontext __user *sc;
- struct sigcontext sigctx;
- struct mcontext __user *sr;
- sigset_t set;
-
- /* Always make any pending restarted system calls return -EINTR */
- current_thread_info()->restart_block.fn = do_no_restart_syscall;
-
- sc = (struct sigcontext __user *)(regs->gpr[1] + __SIGNAL_FRAMESIZE);
- if (copy_from_user(&sigctx, sc, sizeof(sigctx)))
- goto badframe;
-
- set.sig[0] = sigctx.oldmask;
- set.sig[1] = sigctx._unused[3];
- restore_sigmask(&set);
-
- sr = (struct mcontext __user *) sigctx.regs;
- if (!access_ok(VERIFY_READ, sr, sizeof(*sr))
- || restore_user_regs(regs, sr, 1))
- goto badframe;
-
- sigreturn_exit(regs); /* doesn't return */
- return 0;
-
-badframe:
- force_sig(SIGSEGV, current);
- return 0;
-}
-
-/*
- * Note that 'init' is a special process: it doesn't get signals it doesn't
- * want to handle. Thus you cannot kill init even with a SIGKILL even by
- * mistake.
- */
-int do_signal(sigset_t *oldset, struct pt_regs *regs)
-{
- siginfo_t info;
- struct k_sigaction ka;
- unsigned long frame, newsp;
- int signr, ret;
-
- if (try_to_freeze()) {
- signr = 0;
- if (!signal_pending(current))
- goto no_signal;
- }
-
- if (!oldset)
- oldset = &current->blocked;
-
- newsp = frame = 0;
-
- signr = get_signal_to_deliver(&info, &ka, regs, NULL);
- no_signal:
- if (TRAP(regs) == 0x0C00 /* System Call! */
- && regs->ccr & 0x10000000 /* error signalled */
- && ((ret = regs->gpr[3]) == ERESTARTSYS
- || ret == ERESTARTNOHAND || ret == ERESTARTNOINTR
- || ret == ERESTART_RESTARTBLOCK)) {
-
- if (signr > 0
- && (ret == ERESTARTNOHAND || ret == ERESTART_RESTARTBLOCK
- || (ret == ERESTARTSYS
- && !(ka.sa.sa_flags & SA_RESTART)))) {
- /* make the system call return an EINTR error */
- regs->result = -EINTR;
- regs->gpr[3] = EINTR;
- /* note that the cr0.SO bit is already set */
- } else {
- regs->nip -= 4; /* Back up & retry system call */
- regs->result = 0;
- regs->trap = 0;
- if (ret == ERESTART_RESTARTBLOCK)
- regs->gpr[0] = __NR_restart_syscall;
- else
- regs->gpr[3] = regs->orig_gpr3;
- }
- }
-
- if (signr == 0)
- return 0; /* no signals delivered */
-
- if ((ka.sa.sa_flags & SA_ONSTACK) && current->sas_ss_size
- && !on_sig_stack(regs->gpr[1]))
- newsp = current->sas_ss_sp + current->sas_ss_size;
- else
- newsp = regs->gpr[1];
- newsp &= ~0xfUL;
-
- /* Whee! Actually deliver the signal. */
- if (ka.sa.sa_flags & SA_SIGINFO)
- handle_rt_signal(signr, &ka, &info, oldset, regs, newsp);
- else
- handle_signal(signr, &ka, &info, oldset, regs, newsp);
-
- spin_lock_irq(&current->sighand->siglock);
- sigorsets(&current->blocked,&current->blocked,&ka.sa.sa_mask);
- if (!(ka.sa.sa_flags & SA_NODEFER))
- sigaddset(&current->blocked, signr);
- recalc_sigpending();
- spin_unlock_irq(&current->sighand->siglock);
-
- return 1;
-}
-
diff --git a/arch/ppc/kernel/smp.c b/arch/ppc/kernel/smp.c
index 726fe7ce1747..43b8fc2ca591 100644
--- a/arch/ppc/kernel/smp.c
+++ b/arch/ppc/kernel/smp.c
@@ -34,11 +34,11 @@
#include <asm/thread_info.h>
#include <asm/tlbflush.h>
#include <asm/xmon.h>
+#include <asm/machdep.h>
volatile int smp_commenced;
int smp_tb_synchronized;
struct cpuinfo_PPC cpu_data[NR_CPUS];
-struct klock_info_struct klock_info = { KLOCK_CLEAR, 0 };
atomic_t ipi_recv;
atomic_t ipi_sent;
cpumask_t cpu_online_map;
@@ -51,7 +51,7 @@ EXPORT_SYMBOL(cpu_online_map);
EXPORT_SYMBOL(cpu_possible_map);
/* SMP operations for this machine */
-static struct smp_ops_t *smp_ops;
+struct smp_ops_t *smp_ops;
/* all cpu mappings are 1-1 -- Cort */
volatile unsigned long cpu_callin_map[NR_CPUS];
@@ -74,11 +74,11 @@ extern void __save_cpu_setup(void);
#define PPC_MSG_XMON_BREAK 3
static inline void
-smp_message_pass(int target, int msg, unsigned long data, int wait)
+smp_message_pass(int target, int msg)
{
- if (smp_ops){
+ if (smp_ops) {
atomic_inc(&ipi_sent);
- smp_ops->message_pass(target,msg,data,wait);
+ smp_ops->message_pass(target, msg);
}
}
@@ -119,7 +119,7 @@ void smp_message_recv(int msg, struct pt_regs *regs)
void smp_send_tlb_invalidate(int cpu)
{
if ( PVR_VER(mfspr(SPRN_PVR)) == 8 )
- smp_message_pass(MSG_ALL_BUT_SELF, PPC_MSG_INVALIDATE_TLB, 0, 0);
+ smp_message_pass(MSG_ALL_BUT_SELF, PPC_MSG_INVALIDATE_TLB);
}
void smp_send_reschedule(int cpu)
@@ -135,13 +135,13 @@ void smp_send_reschedule(int cpu)
*/
/* This is only used if `cpu' is running an idle task,
so it will reschedule itself anyway... */
- smp_message_pass(cpu, PPC_MSG_RESCHEDULE, 0, 0);
+ smp_message_pass(cpu, PPC_MSG_RESCHEDULE);
}
#ifdef CONFIG_XMON
void smp_send_xmon_break(int cpu)
{
- smp_message_pass(cpu, PPC_MSG_XMON_BREAK, 0, 0);
+ smp_message_pass(cpu, PPC_MSG_XMON_BREAK);
}
#endif /* CONFIG_XMON */
@@ -224,7 +224,7 @@ static int __smp_call_function(void (*func) (void *info), void *info,
spin_lock(&call_lock);
call_data = &data;
/* Send a message to all other CPUs and wait for them to respond */
- smp_message_pass(target, PPC_MSG_CALL_FUNCTION, 0, 0);
+ smp_message_pass(target, PPC_MSG_CALL_FUNCTION);
/* Wait for response */
timeout = 1000000;
@@ -294,7 +294,6 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
smp_store_cpu_info(smp_processor_id());
cpu_callin_map[smp_processor_id()] = 1;
- smp_ops = ppc_md.smp_ops;
if (smp_ops == NULL) {
printk("SMP not supported on this machine.\n");
return;
@@ -308,9 +307,6 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
/* Backup CPU 0 state */
__save_cpu_setup();
- if (smp_ops->space_timers)
- smp_ops->space_timers(num_cpus);
-
for_each_cpu(cpu) {
if (cpu == smp_processor_id())
continue;
@@ -345,6 +341,7 @@ int __devinit start_secondary(void *unused)
cpu = smp_processor_id();
smp_store_cpu_info(cpu);
set_dec(tb_ticks_per_jiffy);
+ preempt_disable();
cpu_callin_map[cpu] = 1;
printk("CPU %d done callin...\n", cpu);
diff --git a/arch/ppc/kernel/syscalls.c b/arch/ppc/kernel/syscalls.c
deleted file mode 100644
index 127f040de9de..000000000000
--- a/arch/ppc/kernel/syscalls.c
+++ /dev/null
@@ -1,268 +0,0 @@
-/*
- * arch/ppc/kernel/sys_ppc.c
- *
- * PowerPC version
- * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
- *
- * Derived from "arch/i386/kernel/sys_i386.c"
- * Adapted from the i386 version by Gary Thomas
- * Modified by Cort Dougan (cort@cs.nmt.edu)
- * and Paul Mackerras (paulus@cs.anu.edu.au).
- *
- * This file contains various random system calls that
- * have a non-standard calling sequence on the Linux/PPC
- * platform.
- *
- * 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/errno.h>
-#include <linux/sched.h>
-#include <linux/mm.h>
-#include <linux/smp.h>
-#include <linux/smp_lock.h>
-#include <linux/sem.h>
-#include <linux/msg.h>
-#include <linux/shm.h>
-#include <linux/stat.h>
-#include <linux/syscalls.h>
-#include <linux/mman.h>
-#include <linux/sys.h>
-#include <linux/ipc.h>
-#include <linux/utsname.h>
-#include <linux/file.h>
-#include <linux/unistd.h>
-
-#include <asm/uaccess.h>
-#include <asm/ipc.h>
-#include <asm/semaphore.h>
-
-
-/*
- * sys_ipc() is the de-multiplexer for the SysV IPC calls..
- *
- * This is really horribly ugly.
- */
-int
-sys_ipc (uint call, int first, int second, int third, void __user *ptr, long fifth)
-{
- int version, ret;
-
- version = call >> 16; /* hack for backward compatibility */
- call &= 0xffff;
-
- ret = -ENOSYS;
- switch (call) {
- case SEMOP:
- ret = sys_semtimedop (first, (struct sembuf __user *)ptr,
- second, NULL);
- break;
- case SEMTIMEDOP:
- ret = sys_semtimedop (first, (struct sembuf __user *)ptr,
- second, (const struct timespec __user *) fifth);
- break;
- case SEMGET:
- ret = sys_semget (first, second, third);
- break;
- case SEMCTL: {
- union semun fourth;
-
- if (!ptr)
- break;
- if ((ret = access_ok(VERIFY_READ, ptr, sizeof(long)) ? 0 : -EFAULT)
- || (ret = get_user(fourth.__pad, (void __user *__user *)ptr)))
- break;
- ret = sys_semctl (first, second, third, fourth);
- break;
- }
- case MSGSND:
- ret = sys_msgsnd (first, (struct msgbuf __user *) ptr, second, third);
- break;
- case MSGRCV:
- switch (version) {
- case 0: {
- struct ipc_kludge tmp;
-
- if (!ptr)
- break;
- if ((ret = access_ok(VERIFY_READ, ptr, sizeof(tmp)) ? 0 : -EFAULT)
- || (ret = copy_from_user(&tmp,
- (struct ipc_kludge __user *) ptr,
- sizeof (tmp)) ? -EFAULT : 0))
- break;
- ret = sys_msgrcv (first, tmp.msgp, second, tmp.msgtyp,
- third);
- break;
- }
- default:
- ret = sys_msgrcv (first, (struct msgbuf __user *) ptr,
- second, fifth, third);
- break;
- }
- break;
- case MSGGET:
- ret = sys_msgget ((key_t) first, second);
- break;
- case MSGCTL:
- ret = sys_msgctl (first, second, (struct msqid_ds __user *) ptr);
- break;
- case SHMAT: {
- ulong raddr;
-
- if ((ret = access_ok(VERIFY_WRITE, (ulong __user *) third,
- sizeof(ulong)) ? 0 : -EFAULT))
- break;
- ret = do_shmat (first, (char __user *) ptr, second, &raddr);
- if (ret)
- break;
- ret = put_user (raddr, (ulong __user *) third);
- break;
- }
- case SHMDT:
- ret = sys_shmdt ((char __user *)ptr);
- break;
- case SHMGET:
- ret = sys_shmget (first, second, third);
- break;
- case SHMCTL:
- ret = sys_shmctl (first, second, (struct shmid_ds __user *) ptr);
- break;
- }
-
- return ret;
-}
-
-/*
- * sys_pipe() is the normal C calling standard for creating
- * a pipe. It's not the way unix traditionally does this, though.
- */
-int sys_pipe(int __user *fildes)
-{
- int fd[2];
- int error;
-
- error = do_pipe(fd);
- if (!error) {
- if (copy_to_user(fildes, fd, 2*sizeof(int)))
- error = -EFAULT;
- }
- return error;
-}
-
-static inline unsigned long
-do_mmap2(unsigned long addr, size_t len,
- unsigned long prot, unsigned long flags,
- unsigned long fd, unsigned long pgoff)
-{
- struct file * file = NULL;
- int ret = -EBADF;
-
- flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
- if (!(flags & MAP_ANONYMOUS)) {
- if (!(file = fget(fd)))
- goto out;
- }
-
- down_write(&current->mm->mmap_sem);
- ret = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
- up_write(&current->mm->mmap_sem);
- if (file)
- fput(file);
-out:
- return ret;
-}
-
-unsigned long sys_mmap2(unsigned long addr, size_t len,
- unsigned long prot, unsigned long flags,
- unsigned long fd, unsigned long pgoff)
-{
- return do_mmap2(addr, len, prot, flags, fd, pgoff);
-}
-
-unsigned long sys_mmap(unsigned long addr, size_t len,
- unsigned long prot, unsigned long flags,
- unsigned long fd, off_t offset)
-{
- int err = -EINVAL;
-
- if (offset & ~PAGE_MASK)
- goto out;
-
- err = do_mmap2(addr, len, prot, flags, fd, offset >> PAGE_SHIFT);
-out:
- return err;
-}
-
-/*
- * Due to some executables calling the wrong select we sometimes
- * get wrong args. This determines how the args are being passed
- * (a single ptr to them all args passed) then calls
- * sys_select() with the appropriate args. -- Cort
- */
-int
-ppc_select(int n, fd_set __user *inp, fd_set __user *outp, fd_set __user *exp, struct timeval __user *tvp)
-{
- if ( (unsigned long)n >= 4096 )
- {
- unsigned long __user *buffer = (unsigned long __user *)n;
- if (!access_ok(VERIFY_READ, buffer, 5*sizeof(unsigned long))
- || __get_user(n, buffer)
- || __get_user(inp, ((fd_set __user * __user *)(buffer+1)))
- || __get_user(outp, ((fd_set __user * __user *)(buffer+2)))
- || __get_user(exp, ((fd_set __user * __user *)(buffer+3)))
- || __get_user(tvp, ((struct timeval __user * __user *)(buffer+4))))
- return -EFAULT;
- }
- return sys_select(n, inp, outp, exp, tvp);
-}
-
-int sys_uname(struct old_utsname __user * name)
-{
- int err = -EFAULT;
-
- down_read(&uts_sem);
- if (name && !copy_to_user(name, &system_utsname, sizeof (*name)))
- err = 0;
- up_read(&uts_sem);
- return err;
-}
-
-int sys_olduname(struct oldold_utsname __user * name)
-{
- int error;
-
- if (!name)
- return -EFAULT;
- if (!access_ok(VERIFY_WRITE,name,sizeof(struct oldold_utsname)))
- return -EFAULT;
-
- down_read(&uts_sem);
- error = __copy_to_user(&name->sysname,&system_utsname.sysname,__OLD_UTS_LEN);
- error -= __put_user(0,name->sysname+__OLD_UTS_LEN);
- error -= __copy_to_user(&name->nodename,&system_utsname.nodename,__OLD_UTS_LEN);
- error -= __put_user(0,name->nodename+__OLD_UTS_LEN);
- error -= __copy_to_user(&name->release,&system_utsname.release,__OLD_UTS_LEN);
- error -= __put_user(0,name->release+__OLD_UTS_LEN);
- error -= __copy_to_user(&name->version,&system_utsname.version,__OLD_UTS_LEN);
- error -= __put_user(0,name->version+__OLD_UTS_LEN);
- error -= __copy_to_user(&name->machine,&system_utsname.machine,__OLD_UTS_LEN);
- error = __put_user(0,name->machine+__OLD_UTS_LEN);
- up_read(&uts_sem);
-
- error = error ? -EFAULT : 0;
- return error;
-}
-
-/*
- * We put the arguments in a different order so we only use 6
- * registers for arguments, rather than 7 as sys_fadvise64_64 needs
- * (because `offset' goes in r5/r6).
- */
-long ppc_fadvise64_64(int fd, int advice, loff_t offset, loff_t len)
-{
- return sys_fadvise64_64(fd, offset, len, advice);
-}
diff --git a/arch/ppc/kernel/time.c b/arch/ppc/kernel/time.c
index 22d7fd1e0aea..53ea723af60a 100644
--- a/arch/ppc/kernel/time.c
+++ b/arch/ppc/kernel/time.c
@@ -66,11 +66,6 @@
#include <asm/time.h>
-/* XXX false sharing with below? */
-u64 jiffies_64 = INITIAL_JIFFIES;
-
-EXPORT_SYMBOL(jiffies_64);
-
unsigned long disarm_decr[NR_CPUS];
extern struct timezone sys_tz;
@@ -121,6 +116,15 @@ unsigned long profile_pc(struct pt_regs *regs)
EXPORT_SYMBOL(profile_pc);
#endif
+void wakeup_decrementer(void)
+{
+ set_dec(tb_ticks_per_jiffy);
+ /* No currently-supported powerbook has a 601,
+ * so use get_tbl, not native
+ */
+ last_jiffy_stamp(0) = tb_last_stamp = get_tbl();
+}
+
/*
* timer_interrupt - gets called when the decrementer overflows,
* with interrupts disabled.
diff --git a/arch/ppc/kernel/traps.c b/arch/ppc/kernel/traps.c
index 961ede87be72..9dbc4d28fa28 100644
--- a/arch/ppc/kernel/traps.c
+++ b/arch/ppc/kernel/traps.c
@@ -41,10 +41,15 @@
#ifdef CONFIG_PMAC_BACKLIGHT
#include <asm/backlight.h>
#endif
-#include <asm/perfmon.h>
+#include <asm/pmc.h>
#ifdef CONFIG_XMON
-void (*debugger)(struct pt_regs *regs) = xmon;
+extern int xmon_bpt(struct pt_regs *regs);
+extern int xmon_sstep(struct pt_regs *regs);
+extern int xmon_iabr_match(struct pt_regs *regs);
+extern int xmon_dabr_match(struct pt_regs *regs);
+
+int (*debugger)(struct pt_regs *regs) = xmon;
int (*debugger_bpt)(struct pt_regs *regs) = xmon_bpt;
int (*debugger_sstep)(struct pt_regs *regs) = xmon_sstep;
int (*debugger_iabr_match)(struct pt_regs *regs) = xmon_iabr_match;
@@ -52,7 +57,7 @@ int (*debugger_dabr_match)(struct pt_regs *regs) = xmon_dabr_match;
void (*debugger_fault_handler)(struct pt_regs *regs);
#else
#ifdef CONFIG_KGDB
-void (*debugger)(struct pt_regs *regs);
+int (*debugger)(struct pt_regs *regs);
int (*debugger_bpt)(struct pt_regs *regs);
int (*debugger_sstep)(struct pt_regs *regs);
int (*debugger_iabr_match)(struct pt_regs *regs);
@@ -74,7 +79,7 @@ void (*debugger_fault_handler)(struct pt_regs *regs);
DEFINE_SPINLOCK(die_lock);
-void die(const char * str, struct pt_regs * fp, long err)
+int die(const char * str, struct pt_regs * fp, long err)
{
static int die_counter;
int nl = 0;
@@ -154,7 +159,7 @@ void _exception(int signr, struct pt_regs *regs, int code, unsigned long addr)
*/
static inline int check_io_access(struct pt_regs *regs)
{
-#ifdef CONFIG_PPC_PMAC
+#if defined CONFIG_PPC_PMAC || defined CONFIG_8xx
unsigned long msr = regs->msr;
const struct exception_table_entry *entry;
unsigned int *nip = (unsigned int *)regs->nip;
@@ -173,7 +178,11 @@ static inline int check_io_access(struct pt_regs *regs)
nip -= 2;
else if (*nip == 0x4c00012c) /* isync */
--nip;
- if (*nip == 0x7c0004ac || (*nip >> 26) == 3) {
+ /* eieio from I/O string functions */
+ else if ((*nip) == 0x7c0006ac || *(nip+1) == 0x7c0006ac)
+ nip += 2;
+ if (*nip == 0x7c0004ac || (*nip >> 26) == 3 ||
+ (*(nip+1) >> 26) == 3) {
/* sync or twi */
unsigned int rb;
@@ -232,7 +241,7 @@ platform_machine_check(struct pt_regs *regs)
{
}
-void MachineCheckException(struct pt_regs *regs)
+void machine_check_exception(struct pt_regs *regs)
{
unsigned long reason = get_mc_reason(regs);
@@ -393,14 +402,14 @@ void SMIException(struct pt_regs *regs)
#endif
}
-void UnknownException(struct pt_regs *regs)
+void unknown_exception(struct pt_regs *regs)
{
printk("Bad trap at PC: %lx, MSR: %lx, vector=%lx %s\n",
regs->nip, regs->msr, regs->trap, print_tainted());
_exception(SIGTRAP, regs, 0, 0);
}
-void InstructionBreakpoint(struct pt_regs *regs)
+void instruction_breakpoint_exception(struct pt_regs *regs)
{
if (debugger_iabr_match(regs))
return;
@@ -575,7 +584,7 @@ extern struct bug_entry __start___bug_table[], __stop___bug_table[];
#define module_find_bug(x) NULL
#endif
-static struct bug_entry *find_bug(unsigned long bugaddr)
+struct bug_entry *find_bug(unsigned long bugaddr)
{
struct bug_entry *bug;
@@ -601,28 +610,28 @@ int check_bug_trap(struct pt_regs *regs)
if (bug->line & BUG_WARNING_TRAP) {
/* this is a WARN_ON rather than BUG/BUG_ON */
#ifdef CONFIG_XMON
- xmon_printf(KERN_ERR "Badness in %s at %s:%d\n",
+ xmon_printf(KERN_ERR "Badness in %s at %s:%ld\n",
bug->function, bug->file,
bug->line & ~BUG_WARNING_TRAP);
#endif /* CONFIG_XMON */
- printk(KERN_ERR "Badness in %s at %s:%d\n",
+ printk(KERN_ERR "Badness in %s at %s:%ld\n",
bug->function, bug->file,
bug->line & ~BUG_WARNING_TRAP);
dump_stack();
return 1;
}
#ifdef CONFIG_XMON
- xmon_printf(KERN_CRIT "kernel BUG in %s at %s:%d!\n",
+ xmon_printf(KERN_CRIT "kernel BUG in %s at %s:%ld!\n",
bug->function, bug->file, bug->line);
xmon(regs);
#endif /* CONFIG_XMON */
- printk(KERN_CRIT "kernel BUG in %s at %s:%d!\n",
+ printk(KERN_CRIT "kernel BUG in %s at %s:%ld!\n",
bug->function, bug->file, bug->line);
return 0;
}
-void ProgramCheckException(struct pt_regs *regs)
+void program_check_exception(struct pt_regs *regs)
{
unsigned int reason = get_reason(regs);
extern int do_mathemu(struct pt_regs *regs);
@@ -654,7 +663,7 @@ void ProgramCheckException(struct pt_regs *regs)
giveup_fpu(current);
preempt_enable();
- fpscr = current->thread.fpscr;
+ fpscr = current->thread.fpscr.val;
fpscr &= fpscr << 22; /* mask summary bits with enables */
if (fpscr & FPSCR_VX)
code = FPE_FLTINV;
@@ -701,7 +710,7 @@ void ProgramCheckException(struct pt_regs *regs)
_exception(SIGILL, regs, ILL_ILLOPC, regs->nip);
}
-void SingleStepException(struct pt_regs *regs)
+void single_step_exception(struct pt_regs *regs)
{
regs->msr &= ~(MSR_SE | MSR_BE); /* Turn off 'trace' bits */
if (debugger_sstep(regs))
@@ -709,7 +718,7 @@ void SingleStepException(struct pt_regs *regs)
_exception(SIGTRAP, regs, TRAP_TRACE, 0);
}
-void AlignmentException(struct pt_regs *regs)
+void alignment_exception(struct pt_regs *regs)
{
int fixed;
@@ -814,7 +823,18 @@ void TAUException(struct pt_regs *regs)
}
#endif /* CONFIG_INT_TAU */
-void AltivecUnavailException(struct pt_regs *regs)
+/*
+ * FP unavailable trap from kernel - print a message, but let
+ * the task use FP in the kernel until it returns to user mode.
+ */
+void kernel_fp_unavailable_exception(struct pt_regs *regs)
+{
+ regs->msr |= MSR_FP;
+ printk(KERN_ERR "floating point used in kernel (task=%p, pc=%lx)\n",
+ current, regs->nip);
+}
+
+void altivec_unavailable_exception(struct pt_regs *regs)
{
static int kernel_altivec_count;
@@ -835,7 +855,7 @@ void AltivecUnavailException(struct pt_regs *regs)
}
#ifdef CONFIG_ALTIVEC
-void AltivecAssistException(struct pt_regs *regs)
+void altivec_assist_exception(struct pt_regs *regs)
{
int err;
@@ -872,7 +892,7 @@ void AltivecAssistException(struct pt_regs *regs)
#endif /* CONFIG_ALTIVEC */
#ifdef CONFIG_E500
-void PerformanceMonitorException(struct pt_regs *regs)
+void performance_monitor_exception(struct pt_regs *regs)
{
perf_irq(regs);
}
diff --git a/arch/ppc/kernel/vector.S b/arch/ppc/kernel/vector.S
deleted file mode 100644
index 82a21346bf80..000000000000
--- a/arch/ppc/kernel/vector.S
+++ /dev/null
@@ -1,217 +0,0 @@
-#include <asm/ppc_asm.h>
-#include <asm/processor.h>
-
-/*
- * The routines below are in assembler so we can closely control the
- * usage of floating-point registers. These routines must be called
- * with preempt disabled.
- */
- .data
-fpzero:
- .long 0
-fpone:
- .long 0x3f800000 /* 1.0 in single-precision FP */
-fphalf:
- .long 0x3f000000 /* 0.5 in single-precision FP */
-
- .text
-/*
- * Internal routine to enable floating point and set FPSCR to 0.
- * Don't call it from C; it doesn't use the normal calling convention.
- */
-fpenable:
- mfmsr r10
- ori r11,r10,MSR_FP
- mtmsr r11
- isync
- stfd fr0,24(r1)
- stfd fr1,16(r1)
- stfd fr31,8(r1)
- lis r11,fpzero@ha
- mffs fr31
- lfs fr1,fpzero@l(r11)
- mtfsf 0xff,fr1
- blr
-
-fpdisable:
- mtfsf 0xff,fr31
- lfd fr31,8(r1)
- lfd fr1,16(r1)
- lfd fr0,24(r1)
- mtmsr r10
- isync
- blr
-
-/*
- * Vector add, floating point.
- */
- .globl vaddfp
-vaddfp:
- stwu r1,-32(r1)
- mflr r0
- stw r0,36(r1)
- bl fpenable
- li r0,4
- mtctr r0
- li r6,0
-1: lfsx fr0,r4,r6
- lfsx fr1,r5,r6
- fadds fr0,fr0,fr1
- stfsx fr0,r3,r6
- addi r6,r6,4
- bdnz 1b
- bl fpdisable
- lwz r0,36(r1)
- mtlr r0
- addi r1,r1,32
- blr
-
-/*
- * Vector subtract, floating point.
- */
- .globl vsubfp
-vsubfp:
- stwu r1,-32(r1)
- mflr r0
- stw r0,36(r1)
- bl fpenable
- li r0,4
- mtctr r0
- li r6,0
-1: lfsx fr0,r4,r6
- lfsx fr1,r5,r6
- fsubs fr0,fr0,fr1
- stfsx fr0,r3,r6
- addi r6,r6,4
- bdnz 1b
- bl fpdisable
- lwz r0,36(r1)
- mtlr r0
- addi r1,r1,32
- blr
-
-/*
- * Vector multiply and add, floating point.
- */
- .globl vmaddfp
-vmaddfp:
- stwu r1,-48(r1)
- mflr r0
- stw r0,52(r1)
- bl fpenable
- stfd fr2,32(r1)
- li r0,4
- mtctr r0
- li r7,0
-1: lfsx fr0,r4,r7
- lfsx fr1,r5,r7
- lfsx fr2,r6,r7
- fmadds fr0,fr0,fr2,fr1
- stfsx fr0,r3,r7
- addi r7,r7,4
- bdnz 1b
- lfd fr2,32(r1)
- bl fpdisable
- lwz r0,52(r1)
- mtlr r0
- addi r1,r1,48
- blr
-
-/*
- * Vector negative multiply and subtract, floating point.
- */
- .globl vnmsubfp
-vnmsubfp:
- stwu r1,-48(r1)
- mflr r0
- stw r0,52(r1)
- bl fpenable
- stfd fr2,32(r1)
- li r0,4
- mtctr r0
- li r7,0
-1: lfsx fr0,r4,r7
- lfsx fr1,r5,r7
- lfsx fr2,r6,r7
- fnmsubs fr0,fr0,fr2,fr1
- stfsx fr0,r3,r7
- addi r7,r7,4
- bdnz 1b
- lfd fr2,32(r1)
- bl fpdisable
- lwz r0,52(r1)
- mtlr r0
- addi r1,r1,48
- blr
-
-/*
- * Vector reciprocal estimate. We just compute 1.0/x.
- * r3 -> destination, r4 -> source.
- */
- .globl vrefp
-vrefp:
- stwu r1,-32(r1)
- mflr r0
- stw r0,36(r1)
- bl fpenable
- lis r9,fpone@ha
- li r0,4
- lfs fr1,fpone@l(r9)
- mtctr r0
- li r6,0
-1: lfsx fr0,r4,r6
- fdivs fr0,fr1,fr0
- stfsx fr0,r3,r6
- addi r6,r6,4
- bdnz 1b
- bl fpdisable
- lwz r0,36(r1)
- mtlr r0
- addi r1,r1,32
- blr
-
-/*
- * Vector reciprocal square-root estimate, floating point.
- * We use the frsqrte instruction for the initial estimate followed
- * by 2 iterations of Newton-Raphson to get sufficient accuracy.
- * r3 -> destination, r4 -> source.
- */
- .globl vrsqrtefp
-vrsqrtefp:
- stwu r1,-48(r1)
- mflr r0
- stw r0,52(r1)
- bl fpenable
- stfd fr2,32(r1)
- stfd fr3,40(r1)
- stfd fr4,48(r1)
- stfd fr5,56(r1)
- lis r9,fpone@ha
- lis r8,fphalf@ha
- li r0,4
- lfs fr4,fpone@l(r9)
- lfs fr5,fphalf@l(r8)
- mtctr r0
- li r6,0
-1: lfsx fr0,r4,r6
- frsqrte fr1,fr0 /* r = frsqrte(s) */
- fmuls fr3,fr1,fr0 /* r * s */
- fmuls fr2,fr1,fr5 /* r * 0.5 */
- fnmsubs fr3,fr1,fr3,fr4 /* 1 - s * r * r */
- fmadds fr1,fr2,fr3,fr1 /* r = r + 0.5 * r * (1 - s * r * r) */
- fmuls fr3,fr1,fr0 /* r * s */
- fmuls fr2,fr1,fr5 /* r * 0.5 */
- fnmsubs fr3,fr1,fr3,fr4 /* 1 - s * r * r */
- fmadds fr1,fr2,fr3,fr1 /* r = r + 0.5 * r * (1 - s * r * r) */
- stfsx fr1,r3,r6
- addi r6,r6,4
- bdnz 1b
- lfd fr5,56(r1)
- lfd fr4,48(r1)
- lfd fr3,40(r1)
- lfd fr2,32(r1)
- bl fpdisable
- lwz r0,36(r1)
- mtlr r0
- addi r1,r1,32
- blr
diff --git a/arch/ppc/kernel/vmlinux.lds.S b/arch/ppc/kernel/vmlinux.lds.S
index 17d2db7e537d..09c6525cfa61 100644
--- a/arch/ppc/kernel/vmlinux.lds.S
+++ b/arch/ppc/kernel/vmlinux.lds.S
@@ -149,32 +149,6 @@ SECTIONS
. = ALIGN(4096);
_sextratext = .;
- __pmac_begin = .;
- .pmac.text : { *(.pmac.text) }
- .pmac.data : { *(.pmac.data) }
- . = ALIGN(4096);
- __pmac_end = .;
-
- . = ALIGN(4096);
- __prep_begin = .;
- .prep.text : { *(.prep.text) }
- .prep.data : { *(.prep.data) }
- . = ALIGN(4096);
- __prep_end = .;
-
- . = ALIGN(4096);
- __chrp_begin = .;
- .chrp.text : { *(.chrp.text) }
- .chrp.data : { *(.chrp.data) }
- . = ALIGN(4096);
- __chrp_end = .;
-
- . = ALIGN(4096);
- __openfirmware_begin = .;
- .openfirmware.text : { *(.openfirmware.text) }
- .openfirmware.data : { *(.openfirmware.data) }
- . = ALIGN(4096);
- __openfirmware_end = .;
_eextratext = .;
__bss_start = .;
diff --git a/arch/ppc/lib/string.S b/arch/ppc/lib/string.S
index 36c9b97fd92a..2e258c49e8be 100644
--- a/arch/ppc/lib/string.S
+++ b/arch/ppc/lib/string.S
@@ -65,9 +65,9 @@
.stabs "arch/ppc/lib/",N_SO,0,0,0f
.stabs "string.S",N_SO,0,0,0f
-CACHELINE_BYTES = L1_CACHE_LINE_SIZE
-LG_CACHELINE_BYTES = LG_L1_CACHE_LINE_SIZE
-CACHELINE_MASK = (L1_CACHE_LINE_SIZE-1)
+CACHELINE_BYTES = L1_CACHE_BYTES
+LG_CACHELINE_BYTES = L1_CACHE_SHIFT
+CACHELINE_MASK = (L1_CACHE_BYTES-1)
_GLOBAL(strcpy)
addi r5,r3,-1
@@ -265,12 +265,12 @@ _GLOBAL(cacheable_memcpy)
dcbz r11,r6
#endif
COPY_16_BYTES
-#if L1_CACHE_LINE_SIZE >= 32
+#if L1_CACHE_BYTES >= 32
COPY_16_BYTES
-#if L1_CACHE_LINE_SIZE >= 64
+#if L1_CACHE_BYTES >= 64
COPY_16_BYTES
COPY_16_BYTES
-#if L1_CACHE_LINE_SIZE >= 128
+#if L1_CACHE_BYTES >= 128
COPY_16_BYTES
COPY_16_BYTES
COPY_16_BYTES
@@ -485,12 +485,12 @@ _GLOBAL(__copy_tofrom_user)
.text
/* the main body of the cacheline loop */
COPY_16_BYTES_WITHEX(0)
-#if L1_CACHE_LINE_SIZE >= 32
+#if L1_CACHE_BYTES >= 32
COPY_16_BYTES_WITHEX(1)
-#if L1_CACHE_LINE_SIZE >= 64
+#if L1_CACHE_BYTES >= 64
COPY_16_BYTES_WITHEX(2)
COPY_16_BYTES_WITHEX(3)
-#if L1_CACHE_LINE_SIZE >= 128
+#if L1_CACHE_BYTES >= 128
COPY_16_BYTES_WITHEX(4)
COPY_16_BYTES_WITHEX(5)
COPY_16_BYTES_WITHEX(6)
@@ -544,12 +544,12 @@ _GLOBAL(__copy_tofrom_user)
* 104f (if in read part) or 105f (if in write part), after updating r5
*/
COPY_16_BYTES_EXCODE(0)
-#if L1_CACHE_LINE_SIZE >= 32
+#if L1_CACHE_BYTES >= 32
COPY_16_BYTES_EXCODE(1)
-#if L1_CACHE_LINE_SIZE >= 64
+#if L1_CACHE_BYTES >= 64
COPY_16_BYTES_EXCODE(2)
COPY_16_BYTES_EXCODE(3)
-#if L1_CACHE_LINE_SIZE >= 128
+#if L1_CACHE_BYTES >= 128
COPY_16_BYTES_EXCODE(4)
COPY_16_BYTES_EXCODE(5)
COPY_16_BYTES_EXCODE(6)
diff --git a/arch/ppc/math-emu/sfp-machine.h b/arch/ppc/math-emu/sfp-machine.h
index 686e06d29186..4b17d83cfcdd 100644
--- a/arch/ppc/math-emu/sfp-machine.h
+++ b/arch/ppc/math-emu/sfp-machine.h
@@ -166,7 +166,7 @@ extern int fp_pack_ds(void *, long, unsigned long, unsigned long, long, long);
#include <linux/kernel.h>
#include <linux/sched.h>
-#define __FPU_FPSCR (current->thread.fpscr)
+#define __FPU_FPSCR (current->thread.fpscr.val)
/* We only actually write to the destination register
* if exceptions signalled (if any) will not trap.
diff --git a/arch/ppc/mm/4xx_mmu.c b/arch/ppc/mm/4xx_mmu.c
index b7bcbc232f39..4d006aa1a0d1 100644
--- a/arch/ppc/mm/4xx_mmu.c
+++ b/arch/ppc/mm/4xx_mmu.c
@@ -110,13 +110,11 @@ unsigned long __init mmu_mapin_ram(void)
pmd_t *pmdp;
unsigned long val = p | _PMD_SIZE_16M | _PAGE_HWEXEC | _PAGE_HWWRITE;
- spin_lock(&init_mm.page_table_lock);
pmdp = pmd_offset(pgd_offset_k(v), v);
pmd_val(*pmdp++) = val;
pmd_val(*pmdp++) = val;
pmd_val(*pmdp++) = val;
pmd_val(*pmdp++) = val;
- spin_unlock(&init_mm.page_table_lock);
v += LARGE_PAGE_SIZE_16M;
p += LARGE_PAGE_SIZE_16M;
@@ -127,10 +125,8 @@ unsigned long __init mmu_mapin_ram(void)
pmd_t *pmdp;
unsigned long val = p | _PMD_SIZE_4M | _PAGE_HWEXEC | _PAGE_HWWRITE;
- spin_lock(&init_mm.page_table_lock);
pmdp = pmd_offset(pgd_offset_k(v), v);
pmd_val(*pmdp) = val;
- spin_unlock(&init_mm.page_table_lock);
v += LARGE_PAGE_SIZE_4M;
p += LARGE_PAGE_SIZE_4M;
diff --git a/arch/ppc/mm/init.c b/arch/ppc/mm/init.c
index f421a4b337f6..99b48abd3296 100644
--- a/arch/ppc/mm/init.c
+++ b/arch/ppc/mm/init.c
@@ -69,15 +69,12 @@ int init_bootmem_done;
int boot_mapsize;
#ifdef CONFIG_PPC_PMAC
unsigned long agp_special_page;
+EXPORT_SYMBOL(agp_special_page);
#endif
extern char _end[];
extern char etext[], _stext[];
extern char __init_begin, __init_end;
-extern char __prep_begin, __prep_end;
-extern char __chrp_begin, __chrp_end;
-extern char __pmac_begin, __pmac_end;
-extern char __openfirmware_begin, __openfirmware_end;
#ifdef CONFIG_HIGHMEM
pte_t *kmap_pte;
@@ -167,14 +164,6 @@ void free_initmem(void)
printk ("Freeing unused kernel memory:");
FREESEC(init);
- if (_machine != _MACH_Pmac)
- FREESEC(pmac);
- if (_machine != _MACH_chrp)
- FREESEC(chrp);
- if (_machine != _MACH_prep)
- FREESEC(prep);
- if (!have_of)
- FREESEC(openfirmware);
printk("\n");
ppc_md.progress = NULL;
#undef FREESEC
@@ -648,18 +637,16 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long address,
*/
int page_is_ram(unsigned long pfn)
{
- unsigned long paddr = (pfn << PAGE_SHIFT);
-
- return paddr < __pa(high_memory);
+ return pfn < max_pfn;
}
-pgprot_t phys_mem_access_prot(struct file *file, unsigned long addr,
+pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
unsigned long size, pgprot_t vma_prot)
{
if (ppc_md.phys_mem_access_prot)
- return ppc_md.phys_mem_access_prot(file, addr, size, vma_prot);
+ return ppc_md.phys_mem_access_prot(file, pfn, size, vma_prot);
- if (!page_is_ram(addr >> PAGE_SHIFT))
+ if (!page_is_ram(pfn))
vma_prot = __pgprot(pgprot_val(vma_prot)
| _PAGE_GUARDED | _PAGE_NO_CACHE);
return vma_prot;
diff --git a/arch/ppc/mm/pgtable.c b/arch/ppc/mm/pgtable.c
index 81a3d7446d37..6ea9185fd120 100644
--- a/arch/ppc/mm/pgtable.c
+++ b/arch/ppc/mm/pgtable.c
@@ -114,9 +114,9 @@ struct page *pte_alloc_one(struct mm_struct *mm, unsigned long address)
struct page *ptepage;
#ifdef CONFIG_HIGHPTE
- int flags = GFP_KERNEL | __GFP_HIGHMEM | __GFP_REPEAT;
+ gfp_t flags = GFP_KERNEL | __GFP_HIGHMEM | __GFP_REPEAT;
#else
- int flags = GFP_KERNEL | __GFP_REPEAT;
+ gfp_t flags = GFP_KERNEL | __GFP_REPEAT;
#endif
ptepage = alloc_pages(flags, 0);
@@ -280,18 +280,16 @@ map_page(unsigned long va, phys_addr_t pa, int flags)
pte_t *pg;
int err = -ENOMEM;
- spin_lock(&init_mm.page_table_lock);
/* Use upper 10 bits of VA to index the first level map */
pd = pmd_offset(pgd_offset_k(va), va);
/* Use middle 10 bits of VA to index the second-level map */
- pg = pte_alloc_kernel(&init_mm, pd, va);
+ pg = pte_alloc_kernel(pd, va);
if (pg != 0) {
err = 0;
set_pte_at(&init_mm, va, pg, pfn_pte(pa >> PAGE_SHIFT, __pgprot(flags)));
if (mem_init_done)
flush_HPTE(0, va, pmd_val(*pd));
}
- spin_unlock(&init_mm.page_table_lock);
return err;
}
diff --git a/arch/ppc/oprofile/common.c b/arch/ppc/oprofile/common.c
deleted file mode 100644
index 3169c67abea7..000000000000
--- a/arch/ppc/oprofile/common.c
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * PPC 32 oprofile support
- * Based on PPC64 oprofile support
- * Copyright (C) 2004 Anton Blanchard <anton@au.ibm.com>, IBM
- *
- * Copyright (C) Freescale Semiconductor, Inc 2004
- *
- * Author: Andy Fleming
- *
- * 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/oprofile.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-#include <linux/smp.h>
-#include <linux/errno.h>
-#include <asm/ptrace.h>
-#include <asm/system.h>
-#include <asm/perfmon.h>
-#include <asm/cputable.h>
-
-#include "op_impl.h"
-
-static struct op_ppc32_model *model;
-
-static struct op_counter_config ctr[OP_MAX_COUNTER];
-static struct op_system_config sys;
-
-static void op_handle_interrupt(struct pt_regs *regs)
-{
- model->handle_interrupt(regs, ctr);
-}
-
-static int op_ppc32_setup(void)
-{
- /* Install our interrupt handler into the existing hook. */
- if(request_perfmon_irq(&op_handle_interrupt))
- return -EBUSY;
-
- mb();
-
- /* Pre-compute the values to stuff in the hardware registers. */
- model->reg_setup(ctr, &sys, model->num_counters);
-
-#if 0
- /* FIXME: Make multi-cpu work */
- /* Configure the registers on all cpus. */
- on_each_cpu(model->reg_setup, NULL, 0, 1);
-#endif
-
- return 0;
-}
-
-static void op_ppc32_shutdown(void)
-{
- mb();
-
- /* Remove our interrupt handler. We may be removing this module. */
- free_perfmon_irq();
-}
-
-static void op_ppc32_cpu_start(void *dummy)
-{
- model->start(ctr);
-}
-
-static int op_ppc32_start(void)
-{
- on_each_cpu(op_ppc32_cpu_start, NULL, 0, 1);
- return 0;
-}
-
-static inline void op_ppc32_cpu_stop(void *dummy)
-{
- model->stop();
-}
-
-static void op_ppc32_stop(void)
-{
- on_each_cpu(op_ppc32_cpu_stop, NULL, 0, 1);
-}
-
-static int op_ppc32_create_files(struct super_block *sb, struct dentry *root)
-{
- int i;
-
- for (i = 0; i < model->num_counters; ++i) {
- struct dentry *dir;
- char buf[3];
-
- snprintf(buf, sizeof buf, "%d", i);
- dir = oprofilefs_mkdir(sb, root, buf);
-
- oprofilefs_create_ulong(sb, dir, "enabled", &ctr[i].enabled);
- oprofilefs_create_ulong(sb, dir, "event", &ctr[i].event);
- oprofilefs_create_ulong(sb, dir, "count", &ctr[i].count);
- oprofilefs_create_ulong(sb, dir, "kernel", &ctr[i].kernel);
- oprofilefs_create_ulong(sb, dir, "user", &ctr[i].user);
-
- /* FIXME: Not sure if this is used */
- oprofilefs_create_ulong(sb, dir, "unit_mask", &ctr[i].unit_mask);
- }
-
- oprofilefs_create_ulong(sb, root, "enable_kernel", &sys.enable_kernel);
- oprofilefs_create_ulong(sb, root, "enable_user", &sys.enable_user);
-
- /* Default to tracing both kernel and user */
- sys.enable_kernel = 1;
- sys.enable_user = 1;
-
- return 0;
-}
-
-static struct oprofile_operations oprof_ppc32_ops = {
- .create_files = op_ppc32_create_files,
- .setup = op_ppc32_setup,
- .shutdown = op_ppc32_shutdown,
- .start = op_ppc32_start,
- .stop = op_ppc32_stop,
- .cpu_type = NULL /* To be filled in below. */
-};
-
-int __init oprofile_arch_init(struct oprofile_operations *ops)
-{
- char *name;
- int cpu_id = smp_processor_id();
-
-#ifdef CONFIG_FSL_BOOKE
- model = &op_model_fsl_booke;
-#else
- return -ENODEV;
-#endif
-
- name = kmalloc(32, GFP_KERNEL);
-
- if (NULL == name)
- return -ENOMEM;
-
- sprintf(name, "ppc/%s", cur_cpu_spec[cpu_id]->cpu_name);
-
- oprof_ppc32_ops.cpu_type = name;
-
- model->num_counters = cur_cpu_spec[cpu_id]->num_pmcs;
-
- *ops = oprof_ppc32_ops;
-
- printk(KERN_INFO "oprofile: using %s performance monitoring.\n",
- oprof_ppc32_ops.cpu_type);
-
- return 0;
-}
-
-void oprofile_arch_exit(void)
-{
- kfree(oprof_ppc32_ops.cpu_type);
- oprof_ppc32_ops.cpu_type = NULL;
-}
diff --git a/arch/ppc/oprofile/op_impl.h b/arch/ppc/oprofile/op_impl.h
deleted file mode 100644
index bc336dc971e3..000000000000
--- a/arch/ppc/oprofile/op_impl.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2004 Anton Blanchard <anton@au.ibm.com>, IBM
- *
- * Based on alpha version.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-
-#ifndef OP_IMPL_H
-#define OP_IMPL_H 1
-
-#define OP_MAX_COUNTER 8
-
-/* Per-counter configuration as set via oprofilefs. */
-struct op_counter_config {
- unsigned long enabled;
- unsigned long event;
- unsigned long count;
- unsigned long kernel;
- unsigned long user;
- unsigned long unit_mask;
-};
-
-/* System-wide configuration as set via oprofilefs. */
-struct op_system_config {
- unsigned long enable_kernel;
- unsigned long enable_user;
-};
-
-/* Per-arch configuration */
-struct op_ppc32_model {
- void (*reg_setup) (struct op_counter_config *,
- struct op_system_config *,
- int num_counters);
- void (*start) (struct op_counter_config *);
- void (*stop) (void);
- void (*handle_interrupt) (struct pt_regs *,
- struct op_counter_config *);
- int num_counters;
-};
-
-#endif /* OP_IMPL_H */
diff --git a/arch/ppc/platforms/4xx/Kconfig b/arch/ppc/platforms/4xx/Kconfig
index 76f4476cab44..d8837911bbc6 100644
--- a/arch/ppc/platforms/4xx/Kconfig
+++ b/arch/ppc/platforms/4xx/Kconfig
@@ -82,6 +82,12 @@ config LUAN
help
This option enables support for the IBM PPC440SP evaluation board.
+config YUCCA
+ bool "Yucca"
+ select WANT_EARLY_SERIAL
+ help
+ This option enables support for the AMCC PPC440SPe evaluation board.
+
config OCOTEA
bool "Ocotea"
select WANT_EARLY_SERIAL
@@ -124,9 +130,14 @@ config 440SP
depends on LUAN
default y
+config 440SPE
+ bool
+ depends on YUCCA
+ default y
+
config 440
bool
- depends on 440GP || 440SP || 440EP
+ depends on 440GP || 440SP || 440SPE || 440EP
default y
config 440A
@@ -158,7 +169,7 @@ config BOOKE
config IBM_OCP
bool
- depends on ASH || BAMBOO || BUBINGA || CPCI405 || EBONY || EP405 || LUAN || OCOTEA || REDWOOD_5 || REDWOOD_6 || SYCAMORE || WALNUT
+ depends on ASH || BAMBOO || BUBINGA || CPCI405 || EBONY || EP405 || LUAN || YUCCA || OCOTEA || REDWOOD_5 || REDWOOD_6 || SYCAMORE || WALNUT
default y
config XILINX_OCP
@@ -168,7 +179,7 @@ config XILINX_OCP
config IBM_EMAC4
bool
- depends on 440GX || 440SP
+ depends on 440GX || 440SP || 440SPE
default y
config BIOS_FIXUP
@@ -214,7 +225,7 @@ config EMBEDDEDBOOT
config IBM_OPENBIOS
bool
- depends on ASH || BUBINGA || REDWOOD_5 || REDWOOD_6 || SYCAMORE || WALNUT
+ depends on ASH || REDWOOD_5 || REDWOOD_6
default y
config PPC4xx_DMA
diff --git a/arch/ppc/platforms/4xx/Makefile b/arch/ppc/platforms/4xx/Makefile
index 1dd6d7fd6a9a..c9bb61170954 100644
--- a/arch/ppc/platforms/4xx/Makefile
+++ b/arch/ppc/platforms/4xx/Makefile
@@ -7,6 +7,7 @@ obj-$(CONFIG_EBONY) += ebony.o
obj-$(CONFIG_EP405) += ep405.o
obj-$(CONFIG_BUBINGA) += bubinga.o
obj-$(CONFIG_LUAN) += luan.o
+obj-$(CONFIG_YUCCA) += yucca.o
obj-$(CONFIG_OCOTEA) += ocotea.o
obj-$(CONFIG_REDWOOD_5) += redwood5.o
obj-$(CONFIG_REDWOOD_6) += redwood6.o
@@ -22,6 +23,7 @@ obj-$(CONFIG_440EP) += ibm440ep.o
obj-$(CONFIG_440GP) += ibm440gp.o
obj-$(CONFIG_440GX) += ibm440gx.o
obj-$(CONFIG_440SP) += ibm440sp.o
+obj-$(CONFIG_440SPE) += ppc440spe.o
obj-$(CONFIG_405EP) += ibm405ep.o
obj-$(CONFIG_405GPR) += ibm405gpr.o
obj-$(CONFIG_VIRTEX_II_PRO) += virtex-ii_pro.o
diff --git a/arch/ppc/platforms/4xx/bamboo.c b/arch/ppc/platforms/4xx/bamboo.c
index 78a403b48dba..159b228eca1e 100644
--- a/arch/ppc/platforms/4xx/bamboo.c
+++ b/arch/ppc/platforms/4xx/bamboo.c
@@ -51,7 +51,7 @@
#include <syslib/gen550.h>
#include <syslib/ibm440gx_common.h>
-bd_t __res;
+extern bd_t __res;
static struct ibm44x_clocks clocks __initdata;
@@ -425,17 +425,7 @@ bamboo_setup_arch(void)
void __init platform_init(unsigned long r3, unsigned long r4,
unsigned long r5, unsigned long r6, unsigned long r7)
{
- parse_bootinfo(find_bootinfo());
-
- /*
- * If we were passed in a board information, copy it into the
- * residual data area.
- */
- if (r3)
- __res = *(bd_t *)(r3 + KERNELBASE);
-
-
- ibm44x_platform_init();
+ ibm44x_platform_init(r3, r4, r5, r6, r7);
ppc_md.setup_arch = bamboo_setup_arch;
ppc_md.show_cpuinfo = bamboo_show_cpuinfo;
diff --git a/arch/ppc/platforms/4xx/bubinga.c b/arch/ppc/platforms/4xx/bubinga.c
index 3678abf86313..8110f55668c5 100644
--- a/arch/ppc/platforms/4xx/bubinga.c
+++ b/arch/ppc/platforms/4xx/bubinga.c
@@ -89,7 +89,7 @@ bubinga_early_serial_map(void)
* by 16.
*/
uart_div = (mfdcr(DCRN_CPC0_UCR_BASE) & DCRN_CPC0_UCR_U0DIV);
- uart_clock = __res.bi_pllouta_freq / uart_div;
+ uart_clock = __res.bi_procfreq / uart_div;
/* Setup serial port access */
memset(&port, 0, sizeof(port));
diff --git a/arch/ppc/platforms/4xx/bubinga.h b/arch/ppc/platforms/4xx/bubinga.h
index b1df856f8e22..b5380cfaf5c0 100644
--- a/arch/ppc/platforms/4xx/bubinga.h
+++ b/arch/ppc/platforms/4xx/bubinga.h
@@ -1,52 +1,34 @@
/*
- * Support for IBM PPC 405EP evaluation board (Bubinga).
+ * arch/ppc/platforms/4xx/bubinga.h
*
- * Author: SAW (IBM), derived from walnut.h.
- * Maintained by MontaVista Software <source@mvista.com>
+ * Bubinga board definitions
+ *
+ * Copyright (c) 2005 DENX Software Engineering
+ * Stefan Roese <sr@denx.de>
+ *
+ * Based on original work by
+ * SAW (IBM)
+ * 2003 (c) MontaVista Softare 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.
*
- * 2003 (c) MontaVista Softare Inc. This file is licensed under the
- * terms of the GNU General Public License version 2. This program is
- * licensed "as is" without any warranty of any kind, whether express
- * or implied.
*/
#ifdef __KERNEL__
#ifndef __BUBINGA_H__
#define __BUBINGA_H__
-/* 405EP */
+#include <linux/config.h>
#include <platforms/4xx/ibm405ep.h>
-
-#ifndef __ASSEMBLY__
-/*
- * Data structure defining board information maintained by the boot
- * ROM on IBM's evaluation board. An effort has been made to
- * keep the field names consistent with the 8xx 'bd_t' board info
- * structures.
- */
-
-typedef struct board_info {
- unsigned char bi_s_version[4]; /* Version of this structure */
- unsigned char bi_r_version[30]; /* Version of the IBM ROM */
- unsigned int bi_memsize; /* DRAM installed, in bytes */
- unsigned char bi_enetaddr[2][6]; /* Local Ethernet MAC address */ unsigned char bi_pci_enetaddr[6]; /* PCI Ethernet MAC address */
- unsigned int bi_intfreq; /* Processor speed, in Hz */
- unsigned int bi_busfreq; /* PLB Bus speed, in Hz */
- unsigned int bi_pci_busfreq; /* PCI Bus speed, in Hz */
- unsigned int bi_opb_busfreq; /* OPB Bus speed, in Hz */
- unsigned int bi_pllouta_freq; /* PLL OUTA speed, in Hz */
-} bd_t;
-
-/* Some 4xx parts use a different timebase frequency from the internal clock.
-*/
-#define bi_tbfreq bi_intfreq
-
+#include <asm/ppcboot.h>
/* Memory map for the Bubinga board.
* Generic 4xx plus RTC.
*/
-extern void *bubinga_rtc_base;
#define BUBINGA_RTC_PADDR ((uint)0xf0000000)
#define BUBINGA_RTC_VADDR BUBINGA_RTC_PADDR
#define BUBINGA_RTC_SIZE ((uint)8*1024)
@@ -58,12 +40,18 @@ extern void *bubinga_rtc_base;
* for typical configurations at various CPU speeds.
* The base baud is calculated as (FWDA / EXT UART DIV / 16)
*/
-#define BASE_BAUD 0
+#define BASE_BAUD 0
-#define BUBINGA_FPGA_BASE 0xF0300000
+/* Flash */
+#define PPC40x_FPGA_BASE 0xF0300000
+#define PPC40x_FPGA_REG_OFFS 1 /* offset to flash map reg */
+#define PPC40x_FLASH_ONBD_N(x) (x & 0x02)
+#define PPC40x_FLASH_SRAM_SEL(x) (x & 0x01)
+#define PPC40x_FLASH_LOW 0xFFF00000
+#define PPC40x_FLASH_HIGH 0xFFF80000
+#define PPC40x_FLASH_SIZE 0x80000
-#define PPC4xx_MACHINE_NAME "IBM Bubinga"
+#define PPC4xx_MACHINE_NAME "IBM Bubinga"
-#endif /* !__ASSEMBLY__ */
#endif /* __BUBINGA_H__ */
#endif /* __KERNEL__ */
diff --git a/arch/ppc/platforms/4xx/ebony.c b/arch/ppc/platforms/4xx/ebony.c
index 27b778ab903b..64ebae19cdbb 100644
--- a/arch/ppc/platforms/4xx/ebony.c
+++ b/arch/ppc/platforms/4xx/ebony.c
@@ -54,7 +54,7 @@
#include <syslib/gen550.h>
#include <syslib/ibm440gp_common.h>
-bd_t __res;
+extern bd_t __res;
static struct ibm44x_clocks clocks __initdata;
@@ -90,7 +90,7 @@ ebony_calibrate_decr(void)
* on Rev. C silicon then errata forces us to
* use the internal clock.
*/
- if (strcmp(cur_cpu_spec[0]->cpu_name, "440GP Rev. B") == 0)
+ if (strcmp(cur_cpu_spec->cpu_name, "440GP Rev. B") == 0)
freq = EBONY_440GP_RB_SYSCLK;
else
freq = EBONY_440GP_RC_SYSCLK;
@@ -317,16 +317,7 @@ ebony_setup_arch(void)
void __init platform_init(unsigned long r3, unsigned long r4,
unsigned long r5, unsigned long r6, unsigned long r7)
{
- parse_bootinfo(find_bootinfo());
-
- /*
- * If we were passed in a board information, copy it into the
- * residual data area.
- */
- if (r3)
- __res = *(bd_t *)(r3 + KERNELBASE);
-
- ibm44x_platform_init();
+ ibm44x_platform_init(r3, r4, r5, r6, r7);
ppc_md.setup_arch = ebony_setup_arch;
ppc_md.show_cpuinfo = ebony_show_cpuinfo;
diff --git a/arch/ppc/platforms/4xx/ebony.h b/arch/ppc/platforms/4xx/ebony.h
index d08faa46a0ae..b91ad4272dfe 100644
--- a/arch/ppc/platforms/4xx/ebony.h
+++ b/arch/ppc/platforms/4xx/ebony.h
@@ -24,8 +24,8 @@
#define PPC44x_EMAC0_MR0 0xE0000800
/* Where to find the MAC info */
-#define EBONY_OPENBIOS_MAC_BASE 0xfffffe0c
-#define EBONY_OPENBIOS_MAC_OFFSET 0x0c
+#define OPENBIOS_MAC_BASE 0xfffffe0c
+#define OPENBIOS_MAC_OFFSET 0x0c
/* Default clock rates for Rev. B and Rev. C silicon */
#define EBONY_440GP_RB_SYSCLK 33000000
diff --git a/arch/ppc/platforms/4xx/ibm440ep.c b/arch/ppc/platforms/4xx/ibm440ep.c
index 4712de8ff80f..65ac0b9c2d05 100644
--- a/arch/ppc/platforms/4xx/ibm440ep.c
+++ b/arch/ppc/platforms/4xx/ibm440ep.c
@@ -14,6 +14,7 @@
*/
#include <linux/init.h>
#include <linux/module.h>
+#include <linux/platform_device.h>
#include <platforms/4xx/ibm440ep.h>
#include <asm/ocp.h>
#include <asm/ppc4xx_pic.h>
diff --git a/arch/ppc/platforms/4xx/ibmstb4.c b/arch/ppc/platforms/4xx/ibmstb4.c
index d90627b68faa..7e33bb635443 100644
--- a/arch/ppc/platforms/4xx/ibmstb4.c
+++ b/arch/ppc/platforms/4xx/ibmstb4.c
@@ -10,6 +10,7 @@
*/
#include <linux/init.h>
+#include <linux/platform_device.h>
#include <asm/ocp.h>
#include <asm/ppc4xx_pic.h>
#include <platforms/4xx/ibmstb4.h>
diff --git a/arch/ppc/platforms/4xx/luan.c b/arch/ppc/platforms/4xx/luan.c
index 16d953bda22c..d810b736d9bf 100644
--- a/arch/ppc/platforms/4xx/luan.c
+++ b/arch/ppc/platforms/4xx/luan.c
@@ -52,7 +52,7 @@
#include <syslib/ibm440gx_common.h>
#include <syslib/ibm440sp_common.h>
-bd_t __res;
+extern bd_t __res;
static struct ibm44x_clocks clocks __initdata;
@@ -355,16 +355,7 @@ luan_setup_arch(void)
void __init platform_init(unsigned long r3, unsigned long r4,
unsigned long r5, unsigned long r6, unsigned long r7)
{
- parse_bootinfo(find_bootinfo());
-
- /*
- * If we were passed in a board information, copy it into the
- * residual data area.
- */
- if (r3)
- __res = *(bd_t *)(r3 + KERNELBASE);
-
- ibm44x_platform_init();
+ ibm44x_platform_init(r3, r4, r5, r6, r7);
ppc_md.setup_arch = luan_setup_arch;
ppc_md.show_cpuinfo = luan_show_cpuinfo;
diff --git a/arch/ppc/platforms/4xx/ocotea.c b/arch/ppc/platforms/4xx/ocotea.c
index 506949c5dd29..73b2c98158f6 100644
--- a/arch/ppc/platforms/4xx/ocotea.c
+++ b/arch/ppc/platforms/4xx/ocotea.c
@@ -52,7 +52,7 @@
#include <syslib/gen550.h>
#include <syslib/ibm440gx_common.h>
-bd_t __res;
+extern bd_t __res;
static struct ibm44x_clocks clocks __initdata;
@@ -286,6 +286,15 @@ ocotea_setup_arch(void)
ibm440gx_tah_enable();
+ /*
+ * Determine various clocks.
+ * To be completely correct we should get SysClk
+ * from FPGA, because it can be changed by on-board switches
+ * --ebs
+ */
+ ibm440gx_get_clocks(&clocks, 33333333, 6 * 1843200);
+ ocp_sys_info.opb_bus_freq = clocks.opb;
+
/* Setup TODC access */
TODC_INIT(TODC_TYPE_DS1743,
0,
@@ -324,25 +333,7 @@ static void __init ocotea_init(void)
void __init platform_init(unsigned long r3, unsigned long r4,
unsigned long r5, unsigned long r6, unsigned long r7)
{
- parse_bootinfo(find_bootinfo());
-
- /*
- * If we were passed in a board information, copy it into the
- * residual data area.
- */
- if (r3)
- __res = *(bd_t *)(r3 + KERNELBASE);
-
- /*
- * Determine various clocks.
- * To be completely correct we should get SysClk
- * from FPGA, because it can be changed by on-board switches
- * --ebs
- */
- ibm440gx_get_clocks(&clocks, 33333333, 6 * 1843200);
- ocp_sys_info.opb_bus_freq = clocks.opb;
-
- ibm44x_platform_init();
+ ibm44x_platform_init(r3, r4, r5, r6, r7);
ppc_md.setup_arch = ocotea_setup_arch;
ppc_md.show_cpuinfo = ocotea_show_cpuinfo;
diff --git a/arch/ppc/platforms/4xx/ppc440spe.c b/arch/ppc/platforms/4xx/ppc440spe.c
new file mode 100644
index 000000000000..6139a0b3393e
--- /dev/null
+++ b/arch/ppc/platforms/4xx/ppc440spe.c
@@ -0,0 +1,148 @@
+/*
+ * arch/ppc/platforms/4xx/ppc440spe.c
+ *
+ * PPC440SPe I/O descriptions
+ *
+ * Roland Dreier <rolandd@cisco.com>
+ * Copyright (c) 2005 Cisco Systems. All rights reserved.
+ *
+ * Matt Porter <mporter@kernel.crashing.org>
+ * Copyright 2002-2005 MontaVista Software Inc.
+ *
+ * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
+ * Copyright (c) 2003, 2004 Zultys Technologies
+ *
+ * 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/init.h>
+#include <linux/module.h>
+#include <platforms/4xx/ppc440spe.h>
+#include <asm/ocp.h>
+#include <asm/ppc4xx_pic.h>
+
+static struct ocp_func_emac_data ppc440spe_emac0_def = {
+ .rgmii_idx = -1, /* No RGMII */
+ .rgmii_mux = -1, /* No RGMII */
+ .zmii_idx = -1, /* No ZMII */
+ .zmii_mux = -1, /* No ZMII */
+ .mal_idx = 0, /* MAL device index */
+ .mal_rx_chan = 0, /* MAL rx channel number */
+ .mal_tx_chan = 0, /* MAL tx channel number */
+ .wol_irq = 61, /* WOL interrupt number */
+ .mdio_idx = -1, /* No shared MDIO */
+ .tah_idx = -1, /* No TAH */
+};
+OCP_SYSFS_EMAC_DATA()
+
+static struct ocp_func_mal_data ppc440spe_mal0_def = {
+ .num_tx_chans = 1, /* Number of TX channels */
+ .num_rx_chans = 1, /* Number of RX channels */
+ .txeob_irq = 38, /* TX End Of Buffer IRQ */
+ .rxeob_irq = 39, /* RX End Of Buffer IRQ */
+ .txde_irq = 34, /* TX Descriptor Error IRQ */
+ .rxde_irq = 35, /* RX Descriptor Error IRQ */
+ .serr_irq = 33, /* MAL System Error IRQ */
+ .dcr_base = DCRN_MAL_BASE /* MAL0_CFG DCR number */
+};
+OCP_SYSFS_MAL_DATA()
+
+static struct ocp_func_iic_data ppc440spe_iic0_def = {
+ .fast_mode = 0, /* Use standad mode (100Khz) */
+};
+
+static struct ocp_func_iic_data ppc440spe_iic1_def = {
+ .fast_mode = 0, /* Use standad mode (100Khz) */
+};
+OCP_SYSFS_IIC_DATA()
+
+struct ocp_def core_ocp[] = {
+ { .vendor = OCP_VENDOR_IBM,
+ .function = OCP_FUNC_16550,
+ .index = 0,
+ .paddr = PPC440SPE_UART0_ADDR,
+ .irq = UART0_INT,
+ .pm = IBM_CPM_UART0,
+ },
+ { .vendor = OCP_VENDOR_IBM,
+ .function = OCP_FUNC_16550,
+ .index = 1,
+ .paddr = PPC440SPE_UART1_ADDR,
+ .irq = UART1_INT,
+ .pm = IBM_CPM_UART1,
+ },
+ { .vendor = OCP_VENDOR_IBM,
+ .function = OCP_FUNC_16550,
+ .index = 2,
+ .paddr = PPC440SPE_UART2_ADDR,
+ .irq = UART2_INT,
+ .pm = IBM_CPM_UART2,
+ },
+ { .vendor = OCP_VENDOR_IBM,
+ .function = OCP_FUNC_IIC,
+ .index = 0,
+ .paddr = 0x00000004f0000400ULL,
+ .irq = 2,
+ .pm = IBM_CPM_IIC0,
+ .additions = &ppc440spe_iic0_def,
+ .show = &ocp_show_iic_data
+ },
+ { .vendor = OCP_VENDOR_IBM,
+ .function = OCP_FUNC_IIC,
+ .index = 1,
+ .paddr = 0x00000004f0000500ULL,
+ .irq = 3,
+ .pm = IBM_CPM_IIC1,
+ .additions = &ppc440spe_iic1_def,
+ .show = &ocp_show_iic_data
+ },
+ { .vendor = OCP_VENDOR_IBM,
+ .function = OCP_FUNC_GPIO,
+ .index = 0,
+ .paddr = 0x00000004f0000700ULL,
+ .irq = OCP_IRQ_NA,
+ .pm = IBM_CPM_GPIO0,
+ },
+ { .vendor = OCP_VENDOR_IBM,
+ .function = OCP_FUNC_MAL,
+ .paddr = OCP_PADDR_NA,
+ .irq = OCP_IRQ_NA,
+ .pm = OCP_CPM_NA,
+ .additions = &ppc440spe_mal0_def,
+ .show = &ocp_show_mal_data,
+ },
+ { .vendor = OCP_VENDOR_IBM,
+ .function = OCP_FUNC_EMAC,
+ .index = 0,
+ .paddr = 0x00000004f0000800ULL,
+ .irq = 60,
+ .pm = OCP_CPM_NA,
+ .additions = &ppc440spe_emac0_def,
+ .show = &ocp_show_emac_data,
+ },
+ { .vendor = OCP_VENDOR_INVALID
+ }
+};
+
+/* Polarity and triggering settings for internal interrupt sources */
+struct ppc4xx_uic_settings ppc4xx_core_uic_cfg[] __initdata = {
+ { .polarity = 0xffffffff,
+ .triggering = 0x010f0004,
+ .ext_irq_mask = 0x00000000,
+ },
+ { .polarity = 0xffffffff,
+ .triggering = 0x001f8040,
+ .ext_irq_mask = 0x00007c30, /* IRQ6 - IRQ7, IRQ8 - IRQ12 */
+ },
+ { .polarity = 0xffffffff,
+ .triggering = 0x00000000,
+ .ext_irq_mask = 0x000000fc, /* IRQ0 - IRQ5 */
+ },
+ { .polarity = 0xffffffff,
+ .triggering = 0x00000000,
+ .ext_irq_mask = 0x00000000,
+ },
+};
diff --git a/arch/ppc/platforms/4xx/ppc440spe.h b/arch/ppc/platforms/4xx/ppc440spe.h
new file mode 100644
index 000000000000..2216846973b8
--- /dev/null
+++ b/arch/ppc/platforms/4xx/ppc440spe.h
@@ -0,0 +1,66 @@
+/*
+ * arch/ppc/platforms/4xx/ibm440spe.h
+ *
+ * PPC440SPe definitions
+ *
+ * Roland Dreier <rolandd@cisco.com>
+ * Copyright (c) 2005 Cisco Systems. All rights reserved.
+ *
+ * Matt Porter <mporter@kernel.crashing.org>
+ * Copyright 2004-2005 MontaVista Software, 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 __PPC_PLATFORMS_PPC440SPE_H
+#define __PPC_PLATFORMS_PPC440SPE_H
+
+#include <linux/config.h>
+
+#include <asm/ibm44x.h>
+
+/* UART */
+#define PPC440SPE_UART0_ADDR 0x00000004f0000200ULL
+#define PPC440SPE_UART1_ADDR 0x00000004f0000300ULL
+#define PPC440SPE_UART2_ADDR 0x00000004f0000600ULL
+#define UART0_INT 0
+#define UART1_INT 1
+#define UART2_INT 37
+
+/* Clock and Power Management */
+#define IBM_CPM_IIC0 0x80000000 /* IIC interface */
+#define IBM_CPM_IIC1 0x40000000 /* IIC interface */
+#define IBM_CPM_PCI 0x20000000 /* PCI bridge */
+#define IBM_CPM_CPU 0x02000000 /* processor core */
+#define IBM_CPM_DMA 0x01000000 /* DMA controller */
+#define IBM_CPM_BGO 0x00800000 /* PLB to OPB bus arbiter */
+#define IBM_CPM_BGI 0x00400000 /* OPB to PLB bridge */
+#define IBM_CPM_EBC 0x00200000 /* External Bux Controller */
+#define IBM_CPM_EBM 0x00100000 /* Ext Bus Master Interface */
+#define IBM_CPM_DMC 0x00080000 /* SDRAM peripheral controller */
+#define IBM_CPM_PLB 0x00040000 /* PLB bus arbiter */
+#define IBM_CPM_SRAM 0x00020000 /* SRAM memory controller */
+#define IBM_CPM_PPM 0x00002000 /* PLB Performance Monitor */
+#define IBM_CPM_UIC1 0x00001000 /* Universal Interrupt Controller */
+#define IBM_CPM_GPIO0 0x00000800 /* General Purpose IO (??) */
+#define IBM_CPM_GPT 0x00000400 /* General Purpose Timers */
+#define IBM_CPM_UART0 0x00000200 /* serial port 0 */
+#define IBM_CPM_UART1 0x00000100 /* serial port 1 */
+#define IBM_CPM_UART2 0x00000100 /* serial port 1 */
+#define IBM_CPM_UIC0 0x00000080 /* Universal Interrupt Controller */
+#define IBM_CPM_TMRCLK 0x00000040 /* CPU timers */
+#define IBM_CPM_EMAC0 0x00000020 /* EMAC 0 */
+
+#define DFLT_IBM4xx_PM ~(IBM_CPM_UIC | IBM_CPM_UIC1 | IBM_CPM_CPU \
+ | IBM_CPM_EBC | IBM_CPM_SRAM | IBM_CPM_BGO \
+ | IBM_CPM_EBM | IBM_CPM_PLB | IBM_CPM_OPB \
+ | IBM_CPM_TMRCLK | IBM_CPM_DMA | IBM_CPM_PCI \
+ | IBM_CPM_TAHOE0 | IBM_CPM_TAHOE1 \
+ | IBM_CPM_EMAC0 | IBM_CPM_EMAC1 \
+ | IBM_CPM_EMAC2 | IBM_CPM_EMAC3 )
+#endif /* __PPC_PLATFORMS_PPC440SP_H */
+#endif /* __KERNEL__ */
diff --git a/arch/ppc/platforms/4xx/redwood5.c b/arch/ppc/platforms/4xx/redwood5.c
index bee8b4ac8afd..611ac861804d 100644
--- a/arch/ppc/platforms/4xx/redwood5.c
+++ b/arch/ppc/platforms/4xx/redwood5.c
@@ -14,7 +14,7 @@
#include <linux/config.h>
#include <linux/init.h>
#include <linux/pagemap.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <linux/ioport.h>
#include <asm/io.h>
#include <asm/machdep.h>
diff --git a/arch/ppc/platforms/4xx/redwood6.c b/arch/ppc/platforms/4xx/redwood6.c
index 8b1012994dfc..b13116691289 100644
--- a/arch/ppc/platforms/4xx/redwood6.c
+++ b/arch/ppc/platforms/4xx/redwood6.c
@@ -12,7 +12,7 @@
#include <linux/config.h>
#include <linux/init.h>
#include <linux/pagemap.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <linux/ioport.h>
#include <asm/io.h>
#include <asm/ppc4xx_pic.h>
diff --git a/arch/ppc/platforms/4xx/sycamore.c b/arch/ppc/platforms/4xx/sycamore.c
index d8019eec4704..281b4a2ffb96 100644
--- a/arch/ppc/platforms/4xx/sycamore.c
+++ b/arch/ppc/platforms/4xx/sycamore.c
@@ -88,9 +88,6 @@ ppc405_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
void __init
sycamore_setup_arch(void)
{
-#define SYCAMORE_PS2_BASE 0xF0100000
-#define SYCAMORE_FPGA_BASE 0xF0300000
-
void *fpga_brdc;
unsigned char fpga_brdc_data;
void *fpga_enable;
@@ -100,7 +97,7 @@ sycamore_setup_arch(void)
ppc4xx_setup_arch();
- ibm_ocp_set_emac(0, 1);
+ ibm_ocp_set_emac(0, 0);
kb_data = ioremap(SYCAMORE_PS2_BASE, 8);
if (!kb_data) {
@@ -111,7 +108,7 @@ sycamore_setup_arch(void)
kb_cs = kb_data + 1;
- fpga_status = ioremap(SYCAMORE_FPGA_BASE, 8);
+ fpga_status = ioremap(PPC40x_FPGA_BASE, 8);
if (!fpga_status) {
printk(KERN_CRIT
"sycamore_setup_arch() fpga_status ioremap failed\n");
diff --git a/arch/ppc/platforms/4xx/sycamore.h b/arch/ppc/platforms/4xx/sycamore.h
index 3e7b4e2c8c57..1cd6c824fd62 100644
--- a/arch/ppc/platforms/4xx/sycamore.h
+++ b/arch/ppc/platforms/4xx/sycamore.h
@@ -1,67 +1,52 @@
/*
* arch/ppc/platforms/4xx/sycamore.h
*
- * Macros, definitions, and data structures specific to the IBM PowerPC
- * 405GPr "Sycamore" evaluation board.
+ * Sycamore board definitions
*
- * Author: Armin Kuster <akuster@mvista.com>
+ * Copyright (c) 2005 DENX Software Engineering
+ * Stefan Roese <sr@denx.de>
+ *
+ * Based on original work by
+ * Armin Kuster <akuster@mvista.com>
+ * 2000 (c) MontaVista, Software, 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.
*
- * 2000 (c) MontaVista, Software, Inc. This file is licensed under
- * the terms of the GNU General Public License version 2. This program
- * is licensed "as is" without any warranty of any kind, whether express
- * or implied.
*/
#ifdef __KERNEL__
#ifndef __ASM_SYCAMORE_H__
#define __ASM_SYCAMORE_H__
+#include <linux/config.h>
#include <platforms/4xx/ibm405gpr.h>
+#include <asm/ppcboot.h>
-#ifndef __ASSEMBLY__
-/*
- * Data structure defining board information maintained by the boot
- * ROM on IBM's "Sycamore" evaluation board. An effort has been made to
- * keep the field names consistent with the 8xx 'bd_t' board info
- * structures.
- */
-
-typedef struct board_info {
- unsigned char bi_s_version[4]; /* Version of this structure */
- unsigned char bi_r_version[30]; /* Version of the IBM ROM */
- unsigned int bi_memsize; /* DRAM installed, in bytes */
- unsigned char bi_enetaddr[6]; /* Local Ethernet MAC address */
- unsigned char bi_pci_enetaddr[6]; /* PCI Ethernet MAC address */
- unsigned int bi_intfreq; /* Processor speed, in Hz */
- unsigned int bi_busfreq; /* PLB Bus speed, in Hz */
- unsigned int bi_pci_busfreq; /* PCI Bus speed, in Hz */
-} bd_t;
-
-/* Some 4xx parts use a different timebase frequency from the internal clock.
-*/
-#define bi_tbfreq bi_intfreq
-
-
-/* Memory map for the IBM "Sycamore" 405GP evaluation board.
+/* Memory map for the IBM "Sycamore" 405GPr evaluation board.
* Generic 4xx plus RTC.
*/
-extern void *sycamore_rtc_base;
#define SYCAMORE_RTC_PADDR ((uint)0xf0000000)
#define SYCAMORE_RTC_VADDR SYCAMORE_RTC_PADDR
-#define SYCAMORE_RTC_SIZE ((uint)8*1024)
+#define SYCAMORE_RTC_SIZE ((uint)8*1024)
-#ifdef CONFIG_PPC405GP_INTERNAL_CLOCK
-#define BASE_BAUD 201600
-#else
#define BASE_BAUD 691200
-#endif
-#define SYCAMORE_PS2_BASE 0xF0100000
-#define SYCAMORE_FPGA_BASE 0xF0300000
+#define SYCAMORE_PS2_BASE 0xF0100000
+
+/* Flash */
+#define PPC40x_FPGA_BASE 0xF0300000
+#define PPC40x_FPGA_REG_OFFS 5 /* offset to flash map reg */
+#define PPC40x_FLASH_ONBD_N(x) (x & 0x02)
+#define PPC40x_FLASH_SRAM_SEL(x) (x & 0x01)
+#define PPC40x_FLASH_LOW 0xFFF00000
+#define PPC40x_FLASH_HIGH 0xFFF80000
+#define PPC40x_FLASH_SIZE 0x80000
#define PPC4xx_MACHINE_NAME "IBM Sycamore"
-#endif /* !__ASSEMBLY__ */
#endif /* __ASM_SYCAMORE_H__ */
#endif /* __KERNEL__ */
diff --git a/arch/ppc/platforms/4xx/walnut.c b/arch/ppc/platforms/4xx/walnut.c
index a33eda4b7489..74cb33182d9f 100644
--- a/arch/ppc/platforms/4xx/walnut.c
+++ b/arch/ppc/platforms/4xx/walnut.c
@@ -90,7 +90,7 @@ walnut_setup_arch(void)
kb_cs = kb_data + 1;
- fpga_status = ioremap(WALNUT_FPGA_BASE, 8);
+ fpga_status = ioremap(PPC40x_FPGA_BASE, 8);
if (!fpga_status) {
printk(KERN_CRIT
"walnut_setup_arch() fpga_status ioremap failed\n");
diff --git a/arch/ppc/platforms/4xx/walnut.h b/arch/ppc/platforms/4xx/walnut.h
index 04cfbf3696b9..dcf2691698c0 100644
--- a/arch/ppc/platforms/4xx/walnut.h
+++ b/arch/ppc/platforms/4xx/walnut.h
@@ -1,72 +1,55 @@
/*
* arch/ppc/platforms/4xx/walnut.h
*
- * Macros, definitions, and data structures specific to the IBM PowerPC
- * 405GP "Walnut" evaluation board.
+ * Walnut board definitions
*
- * Authors: Grant Erickson <grant@lcse.umn.edu>, Frank Rowand
- * <frank_rowand@mvista.com>, Debbie Chu <debbie_chu@mvista.com> or
- * source@mvista.com
+ * Copyright (c) 2005 DENX Software Engineering
+ * Stefan Roese <sr@denx.de>
*
- * Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu>
+ * Based on original work by
+ * Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu>
+ * Frank Rowand <frank_rowand@mvista.com>
+ * Debbie Chu <debbie_chu@mvista.com>
+ * 2000 (c) MontaVista, Software, 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.
*
- * 2000 (c) MontaVista, Software, Inc. This file is licensed under
- * the terms of the GNU General Public License version 2. This program
- * is licensed "as is" without any warranty of any kind, whether express
- * or implied.
*/
#ifdef __KERNEL__
#ifndef __ASM_WALNUT_H__
#define __ASM_WALNUT_H__
-/* We have a 405GP core */
+#include <linux/config.h>
#include <platforms/4xx/ibm405gp.h>
-
-#ifndef __ASSEMBLY__
-/*
- * Data structure defining board information maintained by the boot
- * ROM on IBM's "Walnut" evaluation board. An effort has been made to
- * keep the field names consistent with the 8xx 'bd_t' board info
- * structures.
- */
-
-typedef struct board_info {
- unsigned char bi_s_version[4]; /* Version of this structure */
- unsigned char bi_r_version[30]; /* Version of the IBM ROM */
- unsigned int bi_memsize; /* DRAM installed, in bytes */
- unsigned char bi_enetaddr[6]; /* Local Ethernet MAC address */
- unsigned char bi_pci_enetaddr[6]; /* PCI Ethernet MAC address */
- unsigned int bi_intfreq; /* Processor speed, in Hz */
- unsigned int bi_busfreq; /* PLB Bus speed, in Hz */
- unsigned int bi_pci_busfreq; /* PCI Bus speed, in Hz */
-} bd_t;
-
-/* Some 4xx parts use a different timebase frequency from the internal clock.
-*/
-#define bi_tbfreq bi_intfreq
-
+#include <asm/ppcboot.h>
/* Memory map for the IBM "Walnut" 405GP evaluation board.
* Generic 4xx plus RTC.
*/
-extern void *walnut_rtc_base;
#define WALNUT_RTC_PADDR ((uint)0xf0000000)
#define WALNUT_RTC_VADDR WALNUT_RTC_PADDR
#define WALNUT_RTC_SIZE ((uint)8*1024)
-#ifdef CONFIG_PPC405GP_INTERNAL_CLOCK
-#define BASE_BAUD 201600
-#else
#define BASE_BAUD 691200
-#endif
#define WALNUT_PS2_BASE 0xF0100000
-#define WALNUT_FPGA_BASE 0xF0300000
+
+/* Flash */
+#define PPC40x_FPGA_BASE 0xF0300000
+#define PPC40x_FPGA_REG_OFFS 5 /* offset to flash map reg */
+#define PPC40x_FLASH_ONBD_N(x) (x & 0x02)
+#define PPC40x_FLASH_SRAM_SEL(x) (x & 0x01)
+#define PPC40x_FLASH_LOW 0xFFF00000
+#define PPC40x_FLASH_HIGH 0xFFF80000
+#define PPC40x_FLASH_SIZE 0x80000
+#define WALNUT_FPGA_BASE PPC40x_FPGA_BASE
#define PPC4xx_MACHINE_NAME "IBM Walnut"
-#endif /* !__ASSEMBLY__ */
#endif /* __ASM_WALNUT_H__ */
#endif /* __KERNEL__ */
diff --git a/arch/ppc/platforms/4xx/yucca.c b/arch/ppc/platforms/4xx/yucca.c
new file mode 100644
index 000000000000..e60f4bd437ec
--- /dev/null
+++ b/arch/ppc/platforms/4xx/yucca.c
@@ -0,0 +1,395 @@
+/*
+ * arch/ppc/platforms/4xx/yucca.c
+ *
+ * Yucca board specific routines
+ *
+ * Roland Dreier <rolandd@cisco.com> (based on luan.c by Matt Porter)
+ *
+ * Copyright 2004-2005 MontaVista Software Inc.
+ * Copyright (c) 2005 Cisco Systems. 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.
+ */
+
+#include <linux/config.h>
+#include <linux/stddef.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/reboot.h>
+#include <linux/pci.h>
+#include <linux/kdev_t.h>
+#include <linux/types.h>
+#include <linux/major.h>
+#include <linux/blkdev.h>
+#include <linux/console.h>
+#include <linux/delay.h>
+#include <linux/ide.h>
+#include <linux/initrd.h>
+#include <linux/seq_file.h>
+#include <linux/root_dev.h>
+#include <linux/tty.h>
+#include <linux/serial.h>
+#include <linux/serial_core.h>
+
+#include <asm/system.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+#include <asm/dma.h>
+#include <asm/io.h>
+#include <asm/machdep.h>
+#include <asm/ocp.h>
+#include <asm/pci-bridge.h>
+#include <asm/time.h>
+#include <asm/todc.h>
+#include <asm/bootinfo.h>
+#include <asm/ppc4xx_pic.h>
+#include <asm/ppcboot.h>
+
+#include <syslib/ibm44x_common.h>
+#include <syslib/ibm440gx_common.h>
+#include <syslib/ibm440sp_common.h>
+#include <syslib/ppc440spe_pcie.h>
+
+extern bd_t __res;
+
+static struct ibm44x_clocks clocks __initdata;
+
+static void __init
+yucca_calibrate_decr(void)
+{
+ unsigned int freq;
+
+ if (mfspr(SPRN_CCR1) & CCR1_TCS)
+ freq = YUCCA_TMR_CLK;
+ else
+ freq = clocks.cpu;
+
+ ibm44x_calibrate_decr(freq);
+}
+
+static int
+yucca_show_cpuinfo(struct seq_file *m)
+{
+ seq_printf(m, "vendor\t\t: AMCC\n");
+ seq_printf(m, "machine\t\t: PPC440SPe EVB (Yucca)\n");
+
+ return 0;
+}
+
+static enum {
+ HOSE_UNKNOWN,
+ HOSE_PCIX,
+ HOSE_PCIE0,
+ HOSE_PCIE1,
+ HOSE_PCIE2
+} hose_type[4];
+
+static inline int
+yucca_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
+{
+ struct pci_controller *hose = pci_bus_to_hose(dev->bus->number);
+
+ if (hose_type[hose->index] == HOSE_PCIX) {
+ static char pci_irq_table[][4] =
+ /*
+ * PCI IDSEL/INTPIN->INTLINE
+ * A B C D
+ */
+ {
+ { 81, -1, -1, -1 }, /* IDSEL 1 - PCIX0 Slot 0 */
+ };
+ const long min_idsel = 1, max_idsel = 1, irqs_per_slot = 4;
+ return PCI_IRQ_TABLE_LOOKUP;
+ } else if (hose_type[hose->index] == HOSE_PCIE0) {
+ static char pci_irq_table[][4] =
+ /*
+ * PCI IDSEL/INTPIN->INTLINE
+ * A B C D
+ */
+ {
+ { 96, 97, 98, 99 },
+ };
+ const long min_idsel = 1, max_idsel = 1, irqs_per_slot = 4;
+ return PCI_IRQ_TABLE_LOOKUP;
+ } else if (hose_type[hose->index] == HOSE_PCIE1) {
+ static char pci_irq_table[][4] =
+ /*
+ * PCI IDSEL/INTPIN->INTLINE
+ * A B C D
+ */
+ {
+ { 100, 101, 102, 103 },
+ };
+ const long min_idsel = 1, max_idsel = 1, irqs_per_slot = 4;
+ return PCI_IRQ_TABLE_LOOKUP;
+ } else if (hose_type[hose->index] == HOSE_PCIE2) {
+ static char pci_irq_table[][4] =
+ /*
+ * PCI IDSEL/INTPIN->INTLINE
+ * A B C D
+ */
+ {
+ { 104, 105, 106, 107 },
+ };
+ const long min_idsel = 1, max_idsel = 1, irqs_per_slot = 4;
+ return PCI_IRQ_TABLE_LOOKUP;
+ }
+ return -1;
+}
+
+static void __init yucca_set_emacdata(void)
+{
+ struct ocp_def *def;
+ struct ocp_func_emac_data *emacdata;
+
+ /* Set phy_map, phy_mode, and mac_addr for the EMAC */
+ def = ocp_get_one_device(OCP_VENDOR_IBM, OCP_FUNC_EMAC, 0);
+ emacdata = def->additions;
+ emacdata->phy_map = 0x00000001; /* Skip 0x00 */
+ emacdata->phy_mode = PHY_MODE_GMII;
+ memcpy(emacdata->mac_addr, __res.bi_enetaddr, 6);
+}
+
+static int __init yucca_pcie_card_present(int port)
+{
+ void __iomem *pcie_fpga_base;
+ u16 reg;
+
+ pcie_fpga_base = ioremap64(YUCCA_FPGA_REG_BASE, YUCCA_FPGA_REG_SIZE);
+ reg = in_be16(pcie_fpga_base + FPGA_REG1C);
+ iounmap(pcie_fpga_base);
+
+ switch(port) {
+ case 0: return !(reg & FPGA_REG1C_PE0_PRSNT);
+ case 1: return !(reg & FPGA_REG1C_PE1_PRSNT);
+ case 2: return !(reg & FPGA_REG1C_PE2_PRSNT);
+ default: return 0;
+ }
+}
+
+/*
+ * For the given slot, set rootpoint mode, send power to the slot,
+ * turn on the green LED and turn off the yellow LED, enable the clock
+ * and turn off reset.
+ */
+static void __init yucca_setup_pcie_fpga_rootpoint(int port)
+{
+ void __iomem *pcie_reg_fpga_base;
+ u16 power, clock, green_led, yellow_led, reset_off, rootpoint, endpoint;
+
+ pcie_reg_fpga_base = ioremap64(YUCCA_FPGA_REG_BASE, YUCCA_FPGA_REG_SIZE);
+
+ switch(port) {
+ case 0:
+ rootpoint = FPGA_REG1C_PE0_ROOTPOINT;
+ endpoint = 0;
+ power = FPGA_REG1A_PE0_PWRON;
+ green_led = FPGA_REG1A_PE0_GLED;
+ clock = FPGA_REG1A_PE0_REFCLK_ENABLE;
+ yellow_led = FPGA_REG1A_PE0_YLED;
+ reset_off = FPGA_REG1C_PE0_PERST;
+ break;
+ case 1:
+ rootpoint = 0;
+ endpoint = FPGA_REG1C_PE1_ENDPOINT;
+ power = FPGA_REG1A_PE1_PWRON;
+ green_led = FPGA_REG1A_PE1_GLED;
+ clock = FPGA_REG1A_PE1_REFCLK_ENABLE;
+ yellow_led = FPGA_REG1A_PE1_YLED;
+ reset_off = FPGA_REG1C_PE1_PERST;
+ break;
+ case 2:
+ rootpoint = 0;
+ endpoint = FPGA_REG1C_PE2_ENDPOINT;
+ power = FPGA_REG1A_PE2_PWRON;
+ green_led = FPGA_REG1A_PE2_GLED;
+ clock = FPGA_REG1A_PE2_REFCLK_ENABLE;
+ yellow_led = FPGA_REG1A_PE2_YLED;
+ reset_off = FPGA_REG1C_PE2_PERST;
+ break;
+
+ default:
+ return;
+ }
+
+ out_be16(pcie_reg_fpga_base + FPGA_REG1A,
+ ~(power | clock | green_led) &
+ (yellow_led | in_be16(pcie_reg_fpga_base + FPGA_REG1A)));
+ out_be16(pcie_reg_fpga_base + FPGA_REG1C,
+ ~(endpoint | reset_off) &
+ (rootpoint | in_be16(pcie_reg_fpga_base + FPGA_REG1C)));
+
+ /*
+ * Leave device in reset for a while after powering on the
+ * slot to give it a chance to initialize.
+ */
+ mdelay(250);
+
+ out_be16(pcie_reg_fpga_base + FPGA_REG1C,
+ reset_off | in_be16(pcie_reg_fpga_base + FPGA_REG1C));
+
+ iounmap(pcie_reg_fpga_base);
+}
+
+static void __init
+yucca_setup_hoses(void)
+{
+ struct pci_controller *hose;
+ char name[20];
+ int i;
+
+ if (0 && ppc440spe_init_pcie()) {
+ printk(KERN_WARNING "PPC440SPe PCI Express initialization failed\n");
+ return;
+ }
+
+ for (i = 0; i <= 2; ++i) {
+ if (!yucca_pcie_card_present(i))
+ continue;
+
+ printk(KERN_INFO "PCIE%d: card present\n", i);
+ yucca_setup_pcie_fpga_rootpoint(i);
+ if (ppc440spe_init_pcie_rootport(i)) {
+ printk(KERN_WARNING "PCIE%d: initialization failed\n", i);
+ continue;
+ }
+
+ hose = pcibios_alloc_controller();
+ if (!hose)
+ return;
+
+ sprintf(name, "PCIE%d host bridge", i);
+ pci_init_resource(&hose->io_resource,
+ YUCCA_PCIX_LOWER_IO,
+ YUCCA_PCIX_UPPER_IO,
+ IORESOURCE_IO,
+ name);
+
+ hose->mem_space.start = YUCCA_PCIE_LOWER_MEM +
+ i * YUCCA_PCIE_MEM_SIZE;
+ hose->mem_space.end = hose->mem_space.start +
+ YUCCA_PCIE_MEM_SIZE - 1;
+
+ pci_init_resource(&hose->mem_resources[0],
+ hose->mem_space.start,
+ hose->mem_space.end,
+ IORESOURCE_MEM,
+ name);
+
+ hose->first_busno = 0;
+ hose->last_busno = 15;
+ hose_type[hose->index] = HOSE_PCIE0 + i;
+
+ ppc440spe_setup_pcie(hose, i);
+ hose->last_busno = pciauto_bus_scan(hose, hose->first_busno);
+ }
+
+ ppc_md.pci_swizzle = common_swizzle;
+ ppc_md.pci_map_irq = yucca_map_irq;
+}
+
+TODC_ALLOC();
+
+static void __init
+yucca_early_serial_map(void)
+{
+ struct uart_port port;
+
+ /* Setup ioremapped serial port access */
+ memset(&port, 0, sizeof(port));
+ port.membase = ioremap64(PPC440SPE_UART0_ADDR, 8);
+ port.irq = UART0_INT;
+ port.uartclk = clocks.uart0;
+ port.regshift = 0;
+ port.iotype = SERIAL_IO_MEM;
+ port.flags = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST;
+ port.line = 0;
+
+ if (early_serial_setup(&port) != 0) {
+ printk("Early serial init of port 0 failed\n");
+ }
+
+ port.membase = ioremap64(PPC440SPE_UART1_ADDR, 8);
+ port.irq = UART1_INT;
+ port.uartclk = clocks.uart1;
+ port.line = 1;
+
+ if (early_serial_setup(&port) != 0) {
+ printk("Early serial init of port 1 failed\n");
+ }
+
+ port.membase = ioremap64(PPC440SPE_UART2_ADDR, 8);
+ port.irq = UART2_INT;
+ port.uartclk = BASE_BAUD;
+ port.line = 2;
+
+ if (early_serial_setup(&port) != 0) {
+ printk("Early serial init of port 2 failed\n");
+ }
+}
+
+static void __init
+yucca_setup_arch(void)
+{
+ yucca_set_emacdata();
+
+#if !defined(CONFIG_BDI_SWITCH)
+ /*
+ * The Abatron BDI JTAG debugger does not tolerate others
+ * mucking with the debug registers.
+ */
+ mtspr(SPRN_DBCR0, (DBCR0_TDE | DBCR0_IDM));
+#endif
+
+ /*
+ * Determine various clocks.
+ * To be completely correct we should get SysClk
+ * from FPGA, because it can be changed by on-board switches
+ * --ebs
+ */
+ /* 440GX and 440SPe clocking is the same - rd */
+ ibm440gx_get_clocks(&clocks, 33333333, 6 * 1843200);
+ ocp_sys_info.opb_bus_freq = clocks.opb;
+
+ /* init to some ~sane value until calibrate_delay() runs */
+ loops_per_jiffy = 50000000/HZ;
+
+ /* Setup PCIXn host bridges */
+ yucca_setup_hoses();
+
+#ifdef CONFIG_BLK_DEV_INITRD
+ if (initrd_start)
+ ROOT_DEV = Root_RAM0;
+ else
+#endif
+#ifdef CONFIG_ROOT_NFS
+ ROOT_DEV = Root_NFS;
+#else
+ ROOT_DEV = Root_HDA1;
+#endif
+
+ yucca_early_serial_map();
+
+ /* Identify the system */
+ printk("Yucca port (Roland Dreier <rolandd@cisco.com>)\n");
+}
+
+void __init platform_init(unsigned long r3, unsigned long r4,
+ unsigned long r5, unsigned long r6, unsigned long r7)
+{
+ ibm44x_platform_init(r3, r4, r5, r6, r7);
+
+ ppc_md.setup_arch = yucca_setup_arch;
+ ppc_md.show_cpuinfo = yucca_show_cpuinfo;
+ ppc_md.find_end_of_memory = ibm440sp_find_end_of_memory;
+ ppc_md.get_irq = NULL; /* Set in ppc4xx_pic_init() */
+
+ ppc_md.calibrate_decr = yucca_calibrate_decr;
+#ifdef CONFIG_KGDB
+ ppc_md.early_serial_map = yucca_early_serial_map;
+#endif
+}
diff --git a/arch/ppc/platforms/4xx/yucca.h b/arch/ppc/platforms/4xx/yucca.h
new file mode 100644
index 000000000000..01a4afea1514
--- /dev/null
+++ b/arch/ppc/platforms/4xx/yucca.h
@@ -0,0 +1,111 @@
+/*
+ * arch/ppc/platforms/4xx/yucca.h
+ *
+ * Yucca board definitions
+ *
+ * Roland Dreier <rolandd@cisco.com> (based on luan.h by Matt Porter)
+ *
+ * Copyright 2004-2005 MontaVista Software Inc.
+ * Copyright (c) 2005 Cisco Systems. 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.
+ *
+ */
+
+#ifdef __KERNEL__
+#ifndef __ASM_YUCCA_H__
+#define __ASM_YUCCA_H__
+
+#include <linux/config.h>
+#include <platforms/4xx/ppc440spe.h>
+
+/* F/W TLB mapping used in bootloader glue to reset EMAC */
+#define PPC44x_EMAC0_MR0 0xa0000800
+
+/* Location of MAC addresses in PIBS image */
+#define PIBS_FLASH_BASE 0xffe00000
+#define PIBS_MAC_BASE (PIBS_FLASH_BASE+0x1b0400)
+
+/* External timer clock frequency */
+#define YUCCA_TMR_CLK 25000000
+
+/*
+ * FPGA registers
+ */
+#define YUCCA_FPGA_REG_BASE 0x00000004e2000000ULL
+#define YUCCA_FPGA_REG_SIZE 0x24
+
+#define FPGA_REG1A 0x1a
+
+#define FPGA_REG1A_PE0_GLED 0x8000
+#define FPGA_REG1A_PE1_GLED 0x4000
+#define FPGA_REG1A_PE2_GLED 0x2000
+#define FPGA_REG1A_PE0_YLED 0x1000
+#define FPGA_REG1A_PE1_YLED 0x0800
+#define FPGA_REG1A_PE2_YLED 0x0400
+#define FPGA_REG1A_PE0_PWRON 0x0200
+#define FPGA_REG1A_PE1_PWRON 0x0100
+#define FPGA_REG1A_PE2_PWRON 0x0080
+#define FPGA_REG1A_PE0_REFCLK_ENABLE 0x0040
+#define FPGA_REG1A_PE1_REFCLK_ENABLE 0x0020
+#define FPGA_REG1A_PE2_REFCLK_ENABLE 0x0010
+#define FPGA_REG1A_PE_SPREAD0 0x0008
+#define FPGA_REG1A_PE_SPREAD1 0x0004
+#define FPGA_REG1A_PE_SELSOURCE_0 0x0002
+#define FPGA_REG1A_PE_SELSOURCE_1 0x0001
+
+#define FPGA_REG1C 0x1c
+
+#define FPGA_REG1C_PE0_ROOTPOINT 0x8000
+#define FPGA_REG1C_PE1_ENDPOINT 0x4000
+#define FPGA_REG1C_PE2_ENDPOINT 0x2000
+#define FPGA_REG1C_PE0_PRSNT 0x1000
+#define FPGA_REG1C_PE1_PRSNT 0x0800
+#define FPGA_REG1C_PE2_PRSNT 0x0400
+#define FPGA_REG1C_PE0_WAKE 0x0080
+#define FPGA_REG1C_PE1_WAKE 0x0040
+#define FPGA_REG1C_PE2_WAKE 0x0020
+#define FPGA_REG1C_PE0_PERST 0x0010
+#define FPGA_REG1C_PE1_PERST 0x0008
+#define FPGA_REG1C_PE2_PERST 0x0004
+
+/*
+ * Serial port defines
+ */
+#define RS_TABLE_SIZE 3
+
+/* PIBS defined UART mappings, used before early_serial_setup */
+#define UART0_IO_BASE 0xa0000200
+#define UART1_IO_BASE 0xa0000300
+#define UART2_IO_BASE 0xa0000600
+
+#define BASE_BAUD 11059200
+#define STD_UART_OP(num) \
+ { 0, BASE_BAUD, 0, UART##num##_INT, \
+ (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST), \
+ iomem_base: (void*)UART##num##_IO_BASE, \
+ io_type: SERIAL_IO_MEM},
+
+#define SERIAL_PORT_DFNS \
+ STD_UART_OP(0) \
+ STD_UART_OP(1) \
+ STD_UART_OP(2)
+
+/* PCI support */
+#define YUCCA_PCIX_LOWER_IO 0x00000000
+#define YUCCA_PCIX_UPPER_IO 0x0000ffff
+#define YUCCA_PCIX_LOWER_MEM 0x80000000
+#define YUCCA_PCIX_UPPER_MEM 0x8fffffff
+#define YUCCA_PCIE_LOWER_MEM 0x90000000
+#define YUCCA_PCIE_MEM_SIZE 0x10000000
+
+#define YUCCA_PCIX_MEM_SIZE 0x10000000
+#define YUCCA_PCIX_MEM_OFFSET 0x00000000
+#define YUCCA_PCIE_MEM_SIZE 0x10000000
+#define YUCCA_PCIE_MEM_OFFSET 0x00000000
+
+#endif /* __ASM_YUCCA_H__ */
+#endif /* __KERNEL__ */
diff --git a/arch/ppc/platforms/83xx/mpc834x_sys.c b/arch/ppc/platforms/83xx/mpc834x_sys.c
index 79b3f533d0a3..98edc75f4105 100644
--- a/arch/ppc/platforms/83xx/mpc834x_sys.c
+++ b/arch/ppc/platforms/83xx/mpc834x_sys.c
@@ -51,6 +51,9 @@
#include <syslib/ppc83xx_setup.h>
+static const char *GFAR_PHY_0 = "phy0:0";
+static const char *GFAR_PHY_1 = "phy0:1";
+
#ifndef CONFIG_PCI
unsigned long isa_io_base = 0;
unsigned long isa_mem_base = 0;
@@ -97,6 +100,7 @@ mpc834x_sys_setup_arch(void)
bd_t *binfo = (bd_t *) __res;
unsigned int freq;
struct gianfar_platform_data *pdata;
+ struct gianfar_mdio_data *mdata;
/* get the core frequency */
freq = binfo->bi_intfreq;
@@ -111,24 +115,27 @@ mpc834x_sys_setup_arch(void)
#endif
mpc83xx_early_serial_map();
+ /* setup the board related info for the MDIO bus */
+ mdata = (struct gianfar_mdio_data *) ppc_sys_get_pdata(MPC83xx_MDIO);
+
+ mdata->irq[0] = MPC83xx_IRQ_EXT1;
+ mdata->irq[1] = MPC83xx_IRQ_EXT2;
+ mdata->irq[2] = -1;
+ mdata->irq[31] = -1;
+ mdata->paddr += binfo->bi_immr_base;
+
/* setup the board related information for the enet controllers */
pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC83xx_TSEC1);
if (pdata) {
pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR;
- pdata->interruptPHY = MPC83xx_IRQ_EXT1;
- pdata->phyid = 0;
- /* fixup phy address */
- pdata->phy_reg_addr += binfo->bi_immr_base;
+ pdata->bus_id = GFAR_PHY_0;
memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6);
}
pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC83xx_TSEC2);
if (pdata) {
pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR;
- pdata->interruptPHY = MPC83xx_IRQ_EXT2;
- pdata->phyid = 1;
- /* fixup phy address */
- pdata->phy_reg_addr += binfo->bi_immr_base;
+ pdata->bus_id = GFAR_PHY_1;
memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6);
}
diff --git a/arch/ppc/platforms/83xx/mpc834x_sys.h b/arch/ppc/platforms/83xx/mpc834x_sys.h
index 1584cd77a9ef..58e44c042535 100644
--- a/arch/ppc/platforms/83xx/mpc834x_sys.h
+++ b/arch/ppc/platforms/83xx/mpc834x_sys.h
@@ -19,7 +19,6 @@
#include <linux/config.h>
#include <linux/init.h>
-#include <linux/seq_file.h>
#include <syslib/ppc83xx_setup.h>
#include <asm/ppcboot.h>
diff --git a/arch/ppc/platforms/85xx/mpc8540_ads.c b/arch/ppc/platforms/85xx/mpc8540_ads.c
index 7dc8a68acfd0..7e952c1228cb 100644
--- a/arch/ppc/platforms/85xx/mpc8540_ads.c
+++ b/arch/ppc/platforms/85xx/mpc8540_ads.c
@@ -52,6 +52,10 @@
#include <syslib/ppc85xx_setup.h>
+static const char *GFAR_PHY_0 = "phy0:0";
+static const char *GFAR_PHY_1 = "phy0:1";
+static const char *GFAR_PHY_3 = "phy0:3";
+
/* ************************************************************************
*
* Setup the architecture
@@ -63,6 +67,7 @@ mpc8540ads_setup_arch(void)
bd_t *binfo = (bd_t *) __res;
unsigned int freq;
struct gianfar_platform_data *pdata;
+ struct gianfar_mdio_data *mdata;
/* get the core frequency */
freq = binfo->bi_intfreq;
@@ -89,34 +94,35 @@ mpc8540ads_setup_arch(void)
invalidate_tlbcam_entry(num_tlbcam_entries - 1);
#endif
+ /* setup the board related info for the MDIO bus */
+ mdata = (struct gianfar_mdio_data *) ppc_sys_get_pdata(MPC85xx_MDIO);
+
+ mdata->irq[0] = MPC85xx_IRQ_EXT5;
+ mdata->irq[1] = MPC85xx_IRQ_EXT5;
+ mdata->irq[2] = -1;
+ mdata->irq[3] = MPC85xx_IRQ_EXT5;
+ mdata->irq[31] = -1;
+ mdata->paddr += binfo->bi_immr_base;
+
/* setup the board related information for the enet controllers */
pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC1);
if (pdata) {
pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR;
- pdata->interruptPHY = MPC85xx_IRQ_EXT5;
- pdata->phyid = 0;
- /* fixup phy address */
- pdata->phy_reg_addr += binfo->bi_immr_base;
+ pdata->bus_id = GFAR_PHY_0;
memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6);
}
pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC2);
if (pdata) {
pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR;
- pdata->interruptPHY = MPC85xx_IRQ_EXT5;
- pdata->phyid = 1;
- /* fixup phy address */
- pdata->phy_reg_addr += binfo->bi_immr_base;
+ pdata->bus_id = GFAR_PHY_1;
memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6);
}
pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_FEC);
if (pdata) {
pdata->board_flags = 0;
- pdata->interruptPHY = MPC85xx_IRQ_EXT5;
- pdata->phyid = 3;
- /* fixup phy address */
- pdata->phy_reg_addr += binfo->bi_immr_base;
+ pdata->bus_id = GFAR_PHY_3;
memcpy(pdata->mac_addr, binfo->bi_enet2addr, 6);
}
diff --git a/arch/ppc/platforms/85xx/mpc8560_ads.c b/arch/ppc/platforms/85xx/mpc8560_ads.c
index 8841fd7da6ee..208433f1e93a 100644
--- a/arch/ppc/platforms/85xx/mpc8560_ads.c
+++ b/arch/ppc/platforms/85xx/mpc8560_ads.c
@@ -56,6 +56,10 @@
#include <syslib/ppc85xx_setup.h>
+static const char *GFAR_PHY_0 = "phy0:0";
+static const char *GFAR_PHY_1 = "phy0:1";
+static const char *GFAR_PHY_3 = "phy0:3";
+
/* ************************************************************************
*
* Setup the architecture
@@ -68,6 +72,7 @@ mpc8560ads_setup_arch(void)
bd_t *binfo = (bd_t *) __res;
unsigned int freq;
struct gianfar_platform_data *pdata;
+ struct gianfar_mdio_data *mdata;
cpm2_reset();
@@ -86,24 +91,28 @@ mpc8560ads_setup_arch(void)
mpc85xx_setup_hose();
#endif
+ /* setup the board related info for the MDIO bus */
+ mdata = (struct gianfar_mdio_data *) ppc_sys_get_pdata(MPC85xx_MDIO);
+
+ mdata->irq[0] = MPC85xx_IRQ_EXT5;
+ mdata->irq[1] = MPC85xx_IRQ_EXT5;
+ mdata->irq[2] = -1;
+ mdata->irq[3] = MPC85xx_IRQ_EXT5;
+ mdata->irq[31] = -1;
+ mdata->paddr += binfo->bi_immr_base;
+
/* setup the board related information for the enet controllers */
pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC1);
if (pdata) {
pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR;
- pdata->interruptPHY = MPC85xx_IRQ_EXT5;
- pdata->phyid = 0;
- /* fixup phy address */
- pdata->phy_reg_addr += binfo->bi_immr_base;
+ pdata->bus_id = GFAR_PHY_0;
memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6);
}
pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC2);
if (pdata) {
pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR;
- pdata->interruptPHY = MPC85xx_IRQ_EXT5;
- pdata->phyid = 1;
- /* fixup phy address */
- pdata->phy_reg_addr += binfo->bi_immr_base;
+ pdata->bus_id = GFAR_PHY_1;
memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6);
}
diff --git a/arch/ppc/platforms/85xx/mpc85xx_ads_common.c b/arch/ppc/platforms/85xx/mpc85xx_ads_common.c
index bd3ac0136756..16ad092d8a06 100644
--- a/arch/ppc/platforms/85xx/mpc85xx_ads_common.c
+++ b/arch/ppc/platforms/85xx/mpc85xx_ads_common.c
@@ -45,6 +45,8 @@
#include <mm/mmu_decl.h>
+#include <syslib/ppc85xx_rio.h>
+
#include <platforms/85xx/mpc85xx_ads_common.h>
#ifndef CONFIG_PCI
@@ -189,3 +191,11 @@ mpc85xx_exclude_device(u_char bus, u_char devfn)
}
#endif /* CONFIG_PCI */
+
+#ifdef CONFIG_RAPIDIO
+void platform_rio_init(void)
+{
+ /* 512MB RIO LAW at 0xc0000000 */
+ mpc85xx_rio_setup(0xc0000000, 0x20000000);
+}
+#endif /* CONFIG_RAPIDIO */
diff --git a/arch/ppc/platforms/85xx/mpc85xx_ads_common.h b/arch/ppc/platforms/85xx/mpc85xx_ads_common.h
index 3875e839cff7..84acf6e8d45e 100644
--- a/arch/ppc/platforms/85xx/mpc85xx_ads_common.h
+++ b/arch/ppc/platforms/85xx/mpc85xx_ads_common.h
@@ -19,7 +19,6 @@
#include <linux/config.h>
#include <linux/init.h>
-#include <linux/seq_file.h>
#include <asm/ppcboot.h>
#define BOARD_CCSRBAR ((uint)0xe0000000)
diff --git a/arch/ppc/platforms/85xx/mpc85xx_cds_common.c b/arch/ppc/platforms/85xx/mpc85xx_cds_common.c
index 9f9039498ae5..a21156967a5e 100644
--- a/arch/ppc/platforms/85xx/mpc85xx_cds_common.c
+++ b/arch/ppc/platforms/85xx/mpc85xx_cds_common.c
@@ -173,10 +173,7 @@ mpc85xx_cds_init_IRQ(void)
#ifdef CONFIG_PCI
openpic_hookup_cascade(PIRQ0A, "82c59 cascade", i8259_irq);
- for (i = 0; i < NUM_8259_INTERRUPTS; i++)
- irq_desc[i].handler = &i8259_pic;
-
- i8259_init(0);
+ i8259_init(0, 0);
#endif
#ifdef CONFIG_CPM2
@@ -394,6 +391,9 @@ mpc85xx_cds_pcibios_fixup(void)
TODC_ALLOC();
+static const char *GFAR_PHY_0 = "phy0:0";
+static const char *GFAR_PHY_1 = "phy0:1";
+
/* ************************************************************************
*
* Setup the architecture
@@ -405,6 +405,7 @@ mpc85xx_cds_setup_arch(void)
bd_t *binfo = (bd_t *) __res;
unsigned int freq;
struct gianfar_platform_data *pdata;
+ struct gianfar_mdio_data *mdata;
/* get the core frequency */
freq = binfo->bi_intfreq;
@@ -448,44 +449,42 @@ mpc85xx_cds_setup_arch(void)
invalidate_tlbcam_entry(num_tlbcam_entries - 1);
#endif
+ /* setup the board related info for the MDIO bus */
+ mdata = (struct gianfar_mdio_data *) ppc_sys_get_pdata(MPC85xx_MDIO);
+
+ mdata->irq[0] = MPC85xx_IRQ_EXT5;
+ mdata->irq[1] = MPC85xx_IRQ_EXT5;
+ mdata->irq[2] = -1;
+ mdata->irq[3] = -1;
+ mdata->irq[31] = -1;
+ mdata->paddr += binfo->bi_immr_base;
+
/* setup the board related information for the enet controllers */
pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC1);
if (pdata) {
pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR;
- pdata->interruptPHY = MPC85xx_IRQ_EXT5;
- pdata->phyid = 0;
- /* fixup phy address */
- pdata->phy_reg_addr += binfo->bi_immr_base;
+ pdata->bus_id = GFAR_PHY_0;
memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6);
}
pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC2);
if (pdata) {
pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR;
- pdata->interruptPHY = MPC85xx_IRQ_EXT5;
- pdata->phyid = 1;
- /* fixup phy address */
- pdata->phy_reg_addr += binfo->bi_immr_base;
+ pdata->bus_id = GFAR_PHY_1;
memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6);
}
pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_eTSEC1);
if (pdata) {
pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR;
- pdata->interruptPHY = MPC85xx_IRQ_EXT5;
- pdata->phyid = 0;
- /* fixup phy address */
- pdata->phy_reg_addr += binfo->bi_immr_base;
+ pdata->bus_id = GFAR_PHY_0;
memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6);
}
pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_eTSEC2);
if (pdata) {
pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR;
- pdata->interruptPHY = MPC85xx_IRQ_EXT5;
- pdata->phyid = 1;
- /* fixup phy address */
- pdata->phy_reg_addr += binfo->bi_immr_base;
+ pdata->bus_id = GFAR_PHY_1;
memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6);
}
diff --git a/arch/ppc/platforms/85xx/sbc8560.c b/arch/ppc/platforms/85xx/sbc8560.c
index c76760a781c1..b4ee1707a836 100644
--- a/arch/ppc/platforms/85xx/sbc8560.c
+++ b/arch/ppc/platforms/85xx/sbc8560.c
@@ -91,6 +91,9 @@ sbc8560_early_serial_map(void)
}
#endif
+static const char *GFAR_PHY_25 = "phy0:25";
+static const char *GFAR_PHY_26 = "phy0:26";
+
/* ************************************************************************
*
* Setup the architecture
@@ -102,6 +105,7 @@ sbc8560_setup_arch(void)
bd_t *binfo = (bd_t *) __res;
unsigned int freq;
struct gianfar_platform_data *pdata;
+ struct gianfar_mdio_data *mdata;
/* get the core frequency */
freq = binfo->bi_intfreq;
@@ -126,24 +130,26 @@ sbc8560_setup_arch(void)
invalidate_tlbcam_entry(num_tlbcam_entries - 1);
#endif
+ /* setup the board related info for the MDIO bus */
+ mdata = (struct gianfar_mdio_data *) ppc_sys_get_pdata(MPC85xx_MDIO);
+
+ mdata->irq[25] = MPC85xx_IRQ_EXT6;
+ mdata->irq[26] = MPC85xx_IRQ_EXT7;
+ mdata->irq[31] = -1;
+ mdata->paddr += binfo->bi_immr_base;
+
/* setup the board related information for the enet controllers */
pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC1);
if (pdata) {
pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR;
- pdata->interruptPHY = MPC85xx_IRQ_EXT6;
- pdata->phyid = 25;
- /* fixup phy address */
- pdata->phy_reg_addr += binfo->bi_immr_base;
+ pdata->bus_id = GFAR_PHY_25;
memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6);
}
pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC2);
if (pdata) {
pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR;
- pdata->interruptPHY = MPC85xx_IRQ_EXT7;
- pdata->phyid = 26;
- /* fixup phy address */
- pdata->phy_reg_addr += binfo->bi_immr_base;
+ pdata->bus_id = GFAR_PHY_26;
memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6);
}
diff --git a/arch/ppc/platforms/85xx/stx_gp3.c b/arch/ppc/platforms/85xx/stx_gp3.c
index 20940f4044f4..15ce9d070634 100644
--- a/arch/ppc/platforms/85xx/stx_gp3.c
+++ b/arch/ppc/platforms/85xx/stx_gp3.c
@@ -37,6 +37,7 @@
#include <linux/module.h>
#include <linux/fsl_devices.h>
#include <linux/interrupt.h>
+#include <linux/rio.h>
#include <asm/system.h>
#include <asm/pgtable.h>
@@ -57,6 +58,7 @@
#include <syslib/cpm2_pic.h>
#include <syslib/ppc85xx_common.h>
+#include <syslib/ppc85xx_rio.h>
unsigned char __res[sizeof(bd_t)];
@@ -91,6 +93,9 @@ static u8 gp3_openpic_initsenses[] __initdata = {
0x0, /* External 11: */
};
+static const char *GFAR_PHY_2 = "phy0:2";
+static const char *GFAR_PHY_4 = "phy0:4";
+
/*
* Setup the architecture
*/
@@ -100,6 +105,7 @@ gp3_setup_arch(void)
bd_t *binfo = (bd_t *) __res;
unsigned int freq;
struct gianfar_platform_data *pdata;
+ struct gianfar_mdio_data *mdata;
cpm2_reset();
@@ -118,23 +124,26 @@ gp3_setup_arch(void)
mpc85xx_setup_hose();
#endif
+ /* setup the board related info for the MDIO bus */
+ mdata = (struct gianfar_mdio_data *) ppc_sys_get_pdata(MPC85xx_MDIO);
+
+ mdata->irq[2] = MPC85xx_IRQ_EXT5;
+ mdata->irq[4] = MPC85xx_IRQ_EXT5;
+ mdata->irq[31] = -1;
+ mdata->paddr += binfo->bi_immr_base;
+
/* setup the board related information for the enet controllers */
pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC1);
if (pdata) {
/* pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; */
- pdata->interruptPHY = MPC85xx_IRQ_EXT5;
- pdata->phyid = 2;
- pdata->phy_reg_addr += binfo->bi_immr_base;
+ pdata->bus_id = GFAR_PHY_2;
memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6);
}
pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC2);
if (pdata) {
/* pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; */
- pdata->interruptPHY = MPC85xx_IRQ_EXT5;
- pdata->phyid = 4;
- /* fixup phy address */
- pdata->phy_reg_addr += binfo->bi_immr_base;
+ pdata->bus_id = GFAR_PHY_4;
memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6);
}
@@ -266,6 +275,18 @@ int mpc85xx_exclude_device(u_char bus, u_char devfn)
}
#endif /* CONFIG_PCI */
+#ifdef CONFIG_RAPIDIO
+void
+platform_rio_init(void)
+{
+ /*
+ * The STx firmware configures the RapidIO Local Access Window
+ * at 0xc0000000 with a size of 512MB.
+ */
+ mpc85xx_rio_setup(0xc0000000, 0x20000000);
+}
+#endif /* CONFIG_RAPIDIO */
+
void __init
platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
unsigned long r6, unsigned long r7)
diff --git a/arch/ppc/platforms/Makefile b/arch/ppc/platforms/Makefile
index ff7452e5d8e5..7c5cdabf6f3c 100644
--- a/arch/ppc/platforms/Makefile
+++ b/arch/ppc/platforms/Makefile
@@ -14,6 +14,9 @@ obj-$(CONFIG_PPC_PMAC) += pmac_pic.o pmac_setup.o pmac_time.o \
pmac_low_i2c.o pmac_cache.o
obj-$(CONFIG_PPC_CHRP) += chrp_setup.o chrp_time.o chrp_pci.o \
chrp_pegasos_eth.o
+ifeq ($(CONFIG_PPC_CHRP),y)
+obj-$(CONFIG_NVRAM) += chrp_nvram.o
+endif
obj-$(CONFIG_PPC_PREP) += prep_pci.o prep_setup.o
ifeq ($(CONFIG_PPC_PMAC),y)
obj-$(CONFIG_NVRAM) += pmac_nvram.o
diff --git a/arch/ppc/platforms/chestnut.c b/arch/ppc/platforms/chestnut.c
index df6ff98c023a..48a4a510d598 100644
--- a/arch/ppc/platforms/chestnut.c
+++ b/arch/ppc/platforms/chestnut.c
@@ -541,7 +541,6 @@ platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
ppc_md.setup_arch = chestnut_setup_arch;
ppc_md.show_cpuinfo = chestnut_show_cpuinfo;
- ppc_md.irq_canonicalize = NULL;
ppc_md.init_IRQ = mv64360_init_irq;
ppc_md.get_irq = mv64360_get_irq;
ppc_md.init = NULL;
diff --git a/arch/ppc/platforms/chrp_nvram.c b/arch/ppc/platforms/chrp_nvram.c
new file mode 100644
index 000000000000..465ba9b090ef
--- /dev/null
+++ b/arch/ppc/platforms/chrp_nvram.c
@@ -0,0 +1,83 @@
+/*
+ * c 2001 PPC 64 Team, IBM Corp
+ *
+ * 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.
+ *
+ * /dev/nvram driver for PPC
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <asm/uaccess.h>
+#include <asm/prom.h>
+#include <asm/machdep.h>
+
+static unsigned int nvram_size;
+static unsigned char nvram_buf[4];
+static DEFINE_SPINLOCK(nvram_lock);
+
+static unsigned char chrp_nvram_read(int addr)
+{
+ unsigned long done, flags;
+ unsigned char ret;
+
+ if (addr >= nvram_size) {
+ printk(KERN_DEBUG "%s: read addr %d > nvram_size %u\n",
+ current->comm, addr, nvram_size);
+ return 0xff;
+ }
+ spin_lock_irqsave(&nvram_lock, flags);
+ if ((call_rtas("nvram-fetch", 3, 2, &done, addr, __pa(nvram_buf), 1) != 0) || 1 != done)
+ ret = 0xff;
+ else
+ ret = nvram_buf[0];
+ spin_unlock_irqrestore(&nvram_lock, flags);
+
+ return ret;
+}
+
+static void chrp_nvram_write(int addr, unsigned char val)
+{
+ unsigned long done, flags;
+
+ if (addr >= nvram_size) {
+ printk(KERN_DEBUG "%s: write addr %d > nvram_size %u\n",
+ current->comm, addr, nvram_size);
+ return;
+ }
+ spin_lock_irqsave(&nvram_lock, flags);
+ nvram_buf[0] = val;
+ if ((call_rtas("nvram-store", 3, 2, &done, addr, __pa(nvram_buf), 1) != 0) || 1 != done)
+ printk(KERN_DEBUG "rtas IO error storing 0x%02x at %d", val, addr);
+ spin_unlock_irqrestore(&nvram_lock, flags);
+}
+
+void __init chrp_nvram_init(void)
+{
+ struct device_node *nvram;
+ unsigned int *nbytes_p, proplen;
+
+ nvram = of_find_node_by_type(NULL, "nvram");
+ if (nvram == NULL)
+ return;
+
+ nbytes_p = (unsigned int *)get_property(nvram, "#bytes", &proplen);
+ if (nbytes_p == NULL || proplen != sizeof(unsigned int))
+ return;
+
+ nvram_size = *nbytes_p;
+
+ printk(KERN_INFO "CHRP nvram contains %u bytes\n", nvram_size);
+ of_node_put(nvram);
+
+ ppc_md.nvram_read_val = chrp_nvram_read;
+ ppc_md.nvram_write_val = chrp_nvram_write;
+
+ return;
+}
diff --git a/arch/ppc/platforms/chrp_pci.c b/arch/ppc/platforms/chrp_pci.c
index 7d3fbb5c5db2..bd047aac01b1 100644
--- a/arch/ppc/platforms/chrp_pci.c
+++ b/arch/ppc/platforms/chrp_pci.c
@@ -29,7 +29,7 @@ void __iomem *gg2_pci_config_base;
* limit the bus number to 3 bits
*/
-int __chrp gg2_read_config(struct pci_bus *bus, unsigned int devfn, int off,
+int gg2_read_config(struct pci_bus *bus, unsigned int devfn, int off,
int len, u32 *val)
{
volatile void __iomem *cfg_data;
@@ -56,7 +56,7 @@ int __chrp gg2_read_config(struct pci_bus *bus, unsigned int devfn, int off,
return PCIBIOS_SUCCESSFUL;
}
-int __chrp gg2_write_config(struct pci_bus *bus, unsigned int devfn, int off,
+int gg2_write_config(struct pci_bus *bus, unsigned int devfn, int off,
int len, u32 val)
{
volatile void __iomem *cfg_data;
@@ -92,7 +92,7 @@ static struct pci_ops gg2_pci_ops =
/*
* Access functions for PCI config space using RTAS calls.
*/
-int __chrp
+int
rtas_read_config(struct pci_bus *bus, unsigned int devfn, int offset,
int len, u32 *val)
{
@@ -108,7 +108,7 @@ rtas_read_config(struct pci_bus *bus, unsigned int devfn, int offset,
return rval? PCIBIOS_DEVICE_NOT_FOUND: PCIBIOS_SUCCESSFUL;
}
-int __chrp
+int
rtas_write_config(struct pci_bus *bus, unsigned int devfn, int offset,
int len, u32 val)
{
@@ -203,7 +203,7 @@ static void __init setup_peg2(struct pci_controller *hose, struct device_node *d
printk ("RTAS supporting Pegasos OF not found, please upgrade"
" your firmware\n");
}
- pci_assign_all_busses = 1;
+ pci_assign_all_buses = 1;
}
void __init
diff --git a/arch/ppc/platforms/chrp_pegasos_eth.c b/arch/ppc/platforms/chrp_pegasos_eth.c
index cad5bfa153b2..108a6e265185 100644
--- a/arch/ppc/platforms/chrp_pegasos_eth.c
+++ b/arch/ppc/platforms/chrp_pegasos_eth.c
@@ -13,11 +13,24 @@
#include <linux/types.h>
#include <linux/init.h>
#include <linux/ioport.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <linux/mv643xx.h>
#include <linux/pci.h>
-/* Pegasos 2 specific Marvell MV 64361 gigabit ethernet port setup */
+#define PEGASOS2_MARVELL_REGBASE (0xf1000000)
+#define PEGASOS2_MARVELL_REGSIZE (0x00004000)
+#define PEGASOS2_SRAM_BASE (0xf2000000)
+#define PEGASOS2_SRAM_SIZE (256*1024)
+
+#define PEGASOS2_SRAM_BASE_ETH0 (PEGASOS2_SRAM_BASE)
+#define PEGASOS2_SRAM_BASE_ETH1 (PEGASOS2_SRAM_BASE_ETH0 + (PEGASOS2_SRAM_SIZE / 2) )
+
+
+#define PEGASOS2_SRAM_RXRING_SIZE (PEGASOS2_SRAM_SIZE/4)
+#define PEGASOS2_SRAM_TXRING_SIZE (PEGASOS2_SRAM_SIZE/4)
+
+#undef BE_VERBOSE
+
static struct resource mv643xx_eth_shared_resources[] = {
[0] = {
.name = "ethernet shared base",
@@ -44,7 +57,16 @@ static struct resource mv643xx_eth0_resources[] = {
},
};
-static struct mv643xx_eth_platform_data eth0_pd;
+
+static struct mv643xx_eth_platform_data eth0_pd = {
+ .tx_sram_addr = PEGASOS2_SRAM_BASE_ETH0,
+ .tx_sram_size = PEGASOS2_SRAM_TXRING_SIZE,
+ .tx_queue_size = PEGASOS2_SRAM_TXRING_SIZE/16,
+
+ .rx_sram_addr = PEGASOS2_SRAM_BASE_ETH0 + PEGASOS2_SRAM_TXRING_SIZE,
+ .rx_sram_size = PEGASOS2_SRAM_RXRING_SIZE,
+ .rx_queue_size = PEGASOS2_SRAM_RXRING_SIZE/16,
+};
static struct platform_device eth0_device = {
.name = MV643XX_ETH_NAME,
@@ -65,7 +87,15 @@ static struct resource mv643xx_eth1_resources[] = {
},
};
-static struct mv643xx_eth_platform_data eth1_pd;
+static struct mv643xx_eth_platform_data eth1_pd = {
+ .tx_sram_addr = PEGASOS2_SRAM_BASE_ETH1,
+ .tx_sram_size = PEGASOS2_SRAM_TXRING_SIZE,
+ .tx_queue_size = PEGASOS2_SRAM_TXRING_SIZE/16,
+
+ .rx_sram_addr = PEGASOS2_SRAM_BASE_ETH1 + PEGASOS2_SRAM_TXRING_SIZE,
+ .rx_sram_size = PEGASOS2_SRAM_RXRING_SIZE,
+ .rx_queue_size = PEGASOS2_SRAM_RXRING_SIZE/16,
+};
static struct platform_device eth1_device = {
.name = MV643XX_ETH_NAME,
@@ -83,9 +113,62 @@ static struct platform_device *mv643xx_eth_pd_devs[] __initdata = {
&eth1_device,
};
+/***********/
+/***********/
+#define MV_READ(offset,val) { val = readl(mv643xx_reg_base + offset); }
+#define MV_WRITE(offset,data) writel(data, mv643xx_reg_base + offset)
+
+static void __iomem *mv643xx_reg_base;
+
+static int Enable_SRAM(void)
+{
+ u32 ALong;
+
+ if (mv643xx_reg_base == NULL)
+ mv643xx_reg_base = ioremap(PEGASOS2_MARVELL_REGBASE,
+ PEGASOS2_MARVELL_REGSIZE);
+
+ if (mv643xx_reg_base == NULL)
+ return -ENOMEM;
+
+#ifdef BE_VERBOSE
+ printk("Pegasos II/Marvell MV64361: register remapped from %p to %p\n",
+ (void *)PEGASOS2_MARVELL_REGBASE, (void *)mv643xx_reg_base);
+#endif
+
+ MV_WRITE(MV64340_SRAM_CONFIG, 0);
-int
-mv643xx_eth_add_pds(void)
+ MV_WRITE(MV64340_INTEGRATED_SRAM_BASE_ADDR, PEGASOS2_SRAM_BASE >> 16);
+
+ MV_READ(MV64340_BASE_ADDR_ENABLE, ALong);
+ ALong &= ~(1 << 19);
+ MV_WRITE(MV64340_BASE_ADDR_ENABLE, ALong);
+
+ ALong = 0x02;
+ ALong |= PEGASOS2_SRAM_BASE & 0xffff0000;
+ MV_WRITE(MV643XX_ETH_BAR_4, ALong);
+
+ MV_WRITE(MV643XX_ETH_SIZE_REG_4, (PEGASOS2_SRAM_SIZE-1) & 0xffff0000);
+
+ MV_READ(MV643XX_ETH_BASE_ADDR_ENABLE_REG, ALong);
+ ALong &= ~(1 << 4);
+ MV_WRITE(MV643XX_ETH_BASE_ADDR_ENABLE_REG, ALong);
+
+#ifdef BE_VERBOSE
+ printk("Pegasos II/Marvell MV64361: register unmapped\n");
+ printk("Pegasos II/Marvell MV64361: SRAM at %p, size=%x\n", (void*) PEGASOS2_SRAM_BASE, PEGASOS2_SRAM_SIZE);
+#endif
+
+ iounmap(mv643xx_reg_base);
+ mv643xx_reg_base = NULL;
+
+ return 1;
+}
+
+
+/***********/
+/***********/
+int mv643xx_eth_add_pds(void)
{
int ret = 0;
static struct pci_device_id pci_marvell_mv64360[] = {
@@ -93,9 +176,38 @@ mv643xx_eth_add_pds(void)
{ }
};
+#ifdef BE_VERBOSE
+ printk("Pegasos II/Marvell MV64361: init\n");
+#endif
+
if (pci_dev_present(pci_marvell_mv64360)) {
- ret = platform_add_devices(mv643xx_eth_pd_devs, ARRAY_SIZE(mv643xx_eth_pd_devs));
+ ret = platform_add_devices(mv643xx_eth_pd_devs,
+ ARRAY_SIZE(mv643xx_eth_pd_devs));
+
+ if ( Enable_SRAM() < 0)
+ {
+ eth0_pd.tx_sram_addr = 0;
+ eth0_pd.tx_sram_size = 0;
+ eth0_pd.rx_sram_addr = 0;
+ eth0_pd.rx_sram_size = 0;
+
+ eth1_pd.tx_sram_addr = 0;
+ eth1_pd.tx_sram_size = 0;
+ eth1_pd.rx_sram_addr = 0;
+ eth1_pd.rx_sram_size = 0;
+
+#ifdef BE_VERBOSE
+ printk("Pegasos II/Marvell MV64361: Can't enable the "
+ "SRAM\n");
+#endif
+ }
}
+
+#ifdef BE_VERBOSE
+ printk("Pegasos II/Marvell MV64361: init is over\n");
+#endif
+
return ret;
}
+
device_initcall(mv643xx_eth_add_pds);
diff --git a/arch/ppc/platforms/chrp_setup.c b/arch/ppc/platforms/chrp_setup.c
index 66346f0de7ec..f1b70ab3c6fd 100644
--- a/arch/ppc/platforms/chrp_setup.c
+++ b/arch/ppc/platforms/chrp_setup.c
@@ -104,7 +104,7 @@ static const char *gg2_cachemodes[4] = {
"Disabled", "Write-Through", "Copy-Back", "Transparent Mode"
};
-int __chrp
+int
chrp_show_cpuinfo(struct seq_file *m)
{
int i, sdramen;
@@ -302,7 +302,7 @@ void __init chrp_setup_arch(void)
pci_create_OF_bus_map();
}
-void __chrp
+void
chrp_event_scan(void)
{
unsigned char log[1024];
@@ -313,7 +313,7 @@ chrp_event_scan(void)
ppc_md.heartbeat_count = ppc_md.heartbeat_reset;
}
-void __chrp
+void
chrp_restart(char *cmd)
{
printk("RTAS system-reboot returned %d\n",
@@ -321,7 +321,7 @@ chrp_restart(char *cmd)
for (;;);
}
-void __chrp
+void
chrp_power_off(void)
{
/* allow power on only with power button press */
@@ -330,20 +330,12 @@ chrp_power_off(void)
for (;;);
}
-void __chrp
+void
chrp_halt(void)
{
chrp_power_off();
}
-u_int __chrp
-chrp_irq_canonicalize(u_int irq)
-{
- if (irq == 2)
- return 9;
- return irq;
-}
-
/*
* Finds the open-pic node and sets OpenPIC_Addr based on its reg property.
* Then checks if it has an interrupt-ranges property. If it does then
@@ -444,9 +436,7 @@ void __init chrp_init_IRQ(void)
i8259_irq);
}
- for (i = 0; i < NUM_8259_INTERRUPTS; i++)
- irq_desc[i].handler = &i8259_pic;
- i8259_init(chrp_int_ack);
+ i8259_init(chrp_int_ack, 0);
#if defined(CONFIG_VT) && defined(CONFIG_INPUT_ADBHID) && defined(XMON)
/* see if there is a keyboard in the device tree
@@ -464,8 +454,7 @@ void __init
chrp_init2(void)
{
#ifdef CONFIG_NVRAM
-// XX replace this in a more saner way
-// pmac_nvram_init();
+ chrp_nvram_init();
#endif
request_region(0x20,0x20,"pic1");
@@ -499,6 +488,7 @@ chrp_init(unsigned long r3, unsigned long r4, unsigned long r5,
DMA_MODE_READ = 0x44;
DMA_MODE_WRITE = 0x48;
isa_io_base = CHRP_ISA_IO_BASE; /* default value */
+ ppc_do_canonicalize_irqs = 1;
if (root)
machine = get_property(root, "model", NULL);
@@ -517,7 +507,6 @@ chrp_init(unsigned long r3, unsigned long r4, unsigned long r5,
ppc_md.show_percpuinfo = of_show_percpuinfo;
ppc_md.show_cpuinfo = chrp_show_cpuinfo;
- ppc_md.irq_canonicalize = chrp_irq_canonicalize;
ppc_md.init_IRQ = chrp_init_IRQ;
if (_chrp_type == _CHRP_Pegasos)
ppc_md.get_irq = i8259_irq;
@@ -561,7 +550,7 @@ chrp_init(unsigned long r3, unsigned long r4, unsigned long r5,
#endif
#ifdef CONFIG_SMP
- ppc_md.smp_ops = &chrp_smp_ops;
+ smp_ops = &chrp_smp_ops;
#endif /* CONFIG_SMP */
/*
@@ -571,7 +560,7 @@ chrp_init(unsigned long r3, unsigned long r4, unsigned long r5,
if (ppc_md.progress) ppc_md.progress("Linux/PPC "UTS_RELEASE"\n", 0x0);
}
-void __chrp
+void
rtas_display_progress(char *s, unsigned short hex)
{
int width;
@@ -598,7 +587,7 @@ rtas_display_progress(char *s, unsigned short hex)
call_rtas( "display-character", 1, 1, NULL, ' ' );
}
-void __chrp
+void
rtas_indicator_progress(char *s, unsigned short hex)
{
call_rtas("set-indicator", 3, 1, NULL, 6, 0, hex);
diff --git a/arch/ppc/platforms/chrp_smp.c b/arch/ppc/platforms/chrp_smp.c
index 0ea1f7d9e46a..97e539557ecb 100644
--- a/arch/ppc/platforms/chrp_smp.c
+++ b/arch/ppc/platforms/chrp_smp.c
@@ -31,6 +31,7 @@
#include <asm/residual.h>
#include <asm/time.h>
#include <asm/open_pic.h>
+#include <asm/machdep.h>
extern unsigned long smp_chrp_cpu_nr;
@@ -88,7 +89,7 @@ smp_chrp_take_timebase(void)
}
/* CHRP with openpic */
-struct smp_ops_t chrp_smp_ops __chrpdata = {
+struct smp_ops_t chrp_smp_ops = {
.message_pass = smp_openpic_message_pass,
.probe = smp_chrp_probe,
.kick_cpu = smp_chrp_kick_cpu,
diff --git a/arch/ppc/platforms/chrp_time.c b/arch/ppc/platforms/chrp_time.c
index 6037ce7796f5..29d074c305f0 100644
--- a/arch/ppc/platforms/chrp_time.c
+++ b/arch/ppc/platforms/chrp_time.c
@@ -52,7 +52,7 @@ long __init chrp_time_init(void)
return 0;
}
-int __chrp chrp_cmos_clock_read(int addr)
+int chrp_cmos_clock_read(int addr)
{
if (nvram_as1 != 0)
outb(addr>>8, nvram_as1);
@@ -60,7 +60,7 @@ int __chrp chrp_cmos_clock_read(int addr)
return (inb(nvram_data));
}
-void __chrp chrp_cmos_clock_write(unsigned long val, int addr)
+void chrp_cmos_clock_write(unsigned long val, int addr)
{
if (nvram_as1 != 0)
outb(addr>>8, nvram_as1);
@@ -72,7 +72,7 @@ void __chrp chrp_cmos_clock_write(unsigned long val, int addr)
/*
* Set the hardware clock. -- Cort
*/
-int __chrp chrp_set_rtc_time(unsigned long nowtime)
+int chrp_set_rtc_time(unsigned long nowtime)
{
unsigned char save_control, save_freq_select;
struct rtc_time tm;
@@ -118,7 +118,7 @@ int __chrp chrp_set_rtc_time(unsigned long nowtime)
return 0;
}
-unsigned long __chrp chrp_get_rtc_time(void)
+unsigned long chrp_get_rtc_time(void)
{
unsigned int year, mon, day, hour, min, sec;
int uip, i;
diff --git a/arch/ppc/platforms/cpci690.c b/arch/ppc/platforms/cpci690.c
index f64ac2acb603..6ca7bcac9474 100644
--- a/arch/ppc/platforms/cpci690.c
+++ b/arch/ppc/platforms/cpci690.c
@@ -21,6 +21,7 @@
#include <linux/initrd.h>
#include <linux/root_dev.h>
#include <linux/mv643xx.h>
+#include <linux/platform_device.h>
#include <asm/bootinfo.h>
#include <asm/machdep.h>
#include <asm/todc.h>
diff --git a/arch/ppc/platforms/ev64260.c b/arch/ppc/platforms/ev64260.c
index aa50637a5cfb..32358b3fb236 100644
--- a/arch/ppc/platforms/ev64260.c
+++ b/arch/ppc/platforms/ev64260.c
@@ -33,6 +33,7 @@
#include <linux/console.h>
#include <linux/initrd.h>
#include <linux/root_dev.h>
+#include <linux/platform_device.h>
#if !defined(CONFIG_SERIAL_MPSC_CONSOLE)
#include <linux/serial.h>
#include <linux/tty.h>
diff --git a/arch/ppc/platforms/ev64360.c b/arch/ppc/platforms/ev64360.c
index 9811a8a52c25..b9d844f88c2b 100644
--- a/arch/ppc/platforms/ev64360.c
+++ b/arch/ppc/platforms/ev64360.c
@@ -25,6 +25,7 @@
#include <linux/bootmem.h>
#include <linux/mtd/physmap.h>
#include <linux/mv643xx.h>
+#include <linux/platform_device.h>
#ifdef CONFIG_BOOTIMG
#include <linux/bootimg.h>
#endif
@@ -35,6 +36,7 @@
#include <asm/bootinfo.h>
#include <asm/ppcboot.h>
#include <asm/mv64x60.h>
+#include <asm/machdep.h>
#include <platforms/ev64360.h>
#define BOARD_VENDOR "Marvell"
@@ -50,6 +52,8 @@ static u32 ev64360_bus_frequency;
unsigned char __res[sizeof(bd_t)];
+TODC_ALLOC();
+
static int __init
ev64360_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
{
@@ -180,6 +184,9 @@ ev64360_setup_peripherals(void)
EV64360_RTC_WINDOW_BASE, EV64360_RTC_WINDOW_SIZE, 0);
bh.ci->enable_window_32bit(&bh, MV64x60_CPU2DEV_1_WIN);
+ TODC_INIT(TODC_TYPE_DS1501, 0, 0,
+ ioremap(EV64360_RTC_WINDOW_BASE, EV64360_RTC_WINDOW_SIZE), 8);
+
mv64x60_set_32bit_window(&bh, MV64x60_CPU2SRAM_WIN,
EV64360_INTERNAL_SRAM_BASE, MV64360_SRAM_SIZE, 0);
bh.ci->enable_window_32bit(&bh, MV64x60_CPU2SRAM_WIN);
@@ -494,6 +501,13 @@ platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
ppc_md.power_off = ev64360_power_off;
ppc_md.halt = ev64360_halt;
ppc_md.find_end_of_memory = ev64360_find_end_of_memory;
+ ppc_md.init = NULL;
+
+ ppc_md.time_init = todc_time_init;
+ ppc_md.set_rtc_time = todc_set_rtc_time;
+ ppc_md.get_rtc_time = todc_get_rtc_time;
+ ppc_md.nvram_read_val = todc_direct_read_val;
+ ppc_md.nvram_write_val = todc_direct_write_val;
ppc_md.calibrate_decr = ev64360_calibrate_decr;
#if defined(CONFIG_SERIAL_TEXT_DEBUG) && defined(CONFIG_SERIAL_MPSC_CONSOLE)
diff --git a/arch/ppc/platforms/fads.h b/arch/ppc/platforms/fads.h
index b60c56450b67..a48fb8d723e4 100644
--- a/arch/ppc/platforms/fads.h
+++ b/arch/ppc/platforms/fads.h
@@ -25,6 +25,8 @@
#if defined(CONFIG_MPC86XADS)
+#define BOARD_CHIP_NAME "MPC86X"
+
/* U-Boot maps BCSR to 0xff080000 */
#define BCSR_ADDR ((uint)0xff080000)
diff --git a/arch/ppc/platforms/gemini_setup.c b/arch/ppc/platforms/gemini_setup.c
index 3a5ff9fb71d6..729897c59033 100644
--- a/arch/ppc/platforms/gemini_setup.c
+++ b/arch/ppc/platforms/gemini_setup.c
@@ -35,6 +35,7 @@
#include <asm/time.h>
#include <asm/open_pic.h>
#include <asm/bootinfo.h>
+#include <asm/machdep.h>
void gemini_find_bridges(void);
static int gemini_get_clock_speed(void);
@@ -555,7 +556,6 @@ void __init platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
ppc_md.setup_arch = gemini_setup_arch;
ppc_md.show_cpuinfo = gemini_show_cpuinfo;
- ppc_md.irq_canonicalize = NULL;
ppc_md.init_IRQ = gemini_init_IRQ;
ppc_md.get_irq = openpic_get_irq;
ppc_md.init = NULL;
@@ -575,6 +575,6 @@ void __init platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
ppc_md.pcibios_fixup_bus = gemini_pcibios_fixup;
#ifdef CONFIG_SMP
- ppc_md.smp_ops = &gemini_smp_ops;
+ smp_ops = &gemini_smp_ops;
#endif /* CONFIG_SMP */
}
diff --git a/arch/ppc/platforms/hdpu.c b/arch/ppc/platforms/hdpu.c
index ff3796860123..50039a204c24 100644
--- a/arch/ppc/platforms/hdpu.c
+++ b/arch/ppc/platforms/hdpu.c
@@ -22,6 +22,7 @@
#include <linux/irq.h>
#include <linux/ide.h>
#include <linux/seq_file.h>
+#include <linux/platform_device.h>
#include <linux/initrd.h>
#include <linux/root_dev.h>
@@ -609,11 +610,6 @@ static void parse_bootinfo(unsigned long r3,
}
#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
-static int hdpu_ide_check_region(ide_ioreg_t from, unsigned int extent)
-{
- return check_region(from, extent);
-}
-
static void
hdpu_ide_request_region(ide_ioreg_t from, unsigned int extent, const char *name)
{
@@ -753,7 +749,7 @@ static int smp_hdpu_probe(void)
}
static void
-smp_hdpu_message_pass(int target, int msg, unsigned long data, int wait)
+smp_hdpu_message_pass(int target, int msg)
{
if (msg > 0x3) {
printk("SMP %d: smp_message_pass: unknown msg %d\n",
@@ -949,7 +945,7 @@ platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
#endif /* CONFIG_SERIAL_TEXT_DEBUG */
#ifdef CONFIG_SMP
- ppc_md.smp_ops = &hdpu_smp_ops;
+ smp_ops = &hdpu_smp_ops;
#endif /* CONFIG_SMP */
#if defined(CONFIG_SERIAL_MPSC) || defined(CONFIG_MV643XX_ETH)
diff --git a/arch/ppc/platforms/katana.c b/arch/ppc/platforms/katana.c
index 2b53afae0e9c..6e58e30ceed1 100644
--- a/arch/ppc/platforms/katana.c
+++ b/arch/ppc/platforms/katana.c
@@ -29,6 +29,7 @@
#include <linux/seq_file.h>
#include <linux/mtd/physmap.h>
#include <linux/mv643xx.h>
+#include <linux/platform_device.h>
#ifdef CONFIG_BOOTIMG
#include <linux/bootimg.h>
#endif
@@ -42,6 +43,7 @@
#include <asm/ppcboot.h>
#include <asm/mv64x60.h>
#include <platforms/katana.h>
+#include <asm/machdep.h>
static struct mv64x60_handle bh;
static katana_id_t katana_id;
@@ -520,7 +522,7 @@ katana_fixup_resources(struct pci_dev *dev)
{
u16 v16;
- pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, L1_CACHE_LINE_SIZE>>2);
+ pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, L1_CACHE_BYTES>>2);
pci_read_config_word(dev, PCI_COMMAND, &v16);
v16 |= PCI_COMMAND_INVALIDATE | PCI_COMMAND_FAST_BACK;
diff --git a/arch/ppc/platforms/lite5200.c b/arch/ppc/platforms/lite5200.c
index b604cf8b3cae..d44cc991179f 100644
--- a/arch/ppc/platforms/lite5200.c
+++ b/arch/ppc/platforms/lite5200.c
@@ -35,6 +35,7 @@
#include <asm/io.h>
#include <asm/mpc52xx.h>
#include <asm/ppc_sys.h>
+#include <asm/machdep.h>
#include <syslib/mpc52xx_pci.h>
diff --git a/arch/ppc/platforms/lopec.c b/arch/ppc/platforms/lopec.c
index a5569525e0af..06d247c23b82 100644
--- a/arch/ppc/platforms/lopec.c
+++ b/arch/ppc/platforms/lopec.c
@@ -144,15 +144,6 @@ lopec_show_cpuinfo(struct seq_file *m)
return 0;
}
-static u32
-lopec_irq_canonicalize(u32 irq)
-{
- if (irq == 2)
- return 9;
- else
- return irq;
-}
-
static void
lopec_restart(char *cmd)
{
@@ -276,15 +267,11 @@ lopec_init_IRQ(void)
openpic_hookup_cascade(NUM_8259_INTERRUPTS, "82c59 cascade",
&i8259_irq);
- /* Map i8259 interrupts */
- for(i = 0; i < NUM_8259_INTERRUPTS; i++)
- irq_desc[i].handler = &i8259_pic;
-
/*
* The EPIC allows for a read in the range of 0xFEF00000 ->
* 0xFEFFFFFF to generate a PCI interrupt-acknowledge transaction.
*/
- i8259_init(0xfef00000);
+ i8259_init(0xfef00000, 0);
}
static int __init
@@ -379,10 +366,10 @@ platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
ISA_DMA_THRESHOLD = 0x00ffffff;
DMA_MODE_READ = 0x44;
DMA_MODE_WRITE = 0x48;
+ ppc_do_canonicalize_irqs = 1;
ppc_md.setup_arch = lopec_setup_arch;
ppc_md.show_cpuinfo = lopec_show_cpuinfo;
- ppc_md.irq_canonicalize = lopec_irq_canonicalize;
ppc_md.init_IRQ = lopec_init_IRQ;
ppc_md.get_irq = openpic_get_irq;
diff --git a/arch/ppc/platforms/mpc885ads.h b/arch/ppc/platforms/mpc885ads.h
index eb386635b0fd..a80b7d116b49 100644
--- a/arch/ppc/platforms/mpc885ads.h
+++ b/arch/ppc/platforms/mpc885ads.h
@@ -88,5 +88,7 @@
#define SICR_ENET_MASK ((uint)0x00ff0000)
#define SICR_ENET_CLKRT ((uint)0x002c0000)
+#define BOARD_CHIP_NAME "MPC885"
+
#endif /* __ASM_MPC885ADS_H__ */
#endif /* __KERNEL__ */
diff --git a/arch/ppc/platforms/mvme5100.c b/arch/ppc/platforms/mvme5100.c
index ce2ce88c8033..108eb182dddc 100644
--- a/arch/ppc/platforms/mvme5100.c
+++ b/arch/ppc/platforms/mvme5100.c
@@ -223,11 +223,7 @@ mvme5100_init_IRQ(void)
openpic_hookup_cascade(NUM_8259_INTERRUPTS, "82c59 cascade",
&i8259_irq);
- /* Map i8259 interrupts. */
- for (i = 0; i < NUM_8259_INTERRUPTS; i++)
- irq_desc[i].handler = &i8259_pic;
-
- i8259_init(0);
+ i8259_init(0, 0);
#else
openpic_init(0);
#endif
diff --git a/arch/ppc/platforms/pal4_setup.c b/arch/ppc/platforms/pal4_setup.c
index 12446b93e38c..f93a3f871932 100644
--- a/arch/ppc/platforms/pal4_setup.c
+++ b/arch/ppc/platforms/pal4_setup.c
@@ -28,6 +28,7 @@
#include <asm/io.h>
#include <asm/todc.h>
#include <asm/bootinfo.h>
+#include <asm/machdep.h>
#include <syslib/cpc700.h>
diff --git a/arch/ppc/platforms/pmac_backlight.c b/arch/ppc/platforms/pmac_backlight.c
index ed2b1cebc19a..8be2f7d071f0 100644
--- a/arch/ppc/platforms/pmac_backlight.c
+++ b/arch/ppc/platforms/pmac_backlight.c
@@ -37,7 +37,7 @@ static int backlight_req_enable = -1;
static void backlight_callback(void *);
static DECLARE_WORK(backlight_work, backlight_callback, NULL);
-void __pmac register_backlight_controller(struct backlight_controller *ctrler,
+void register_backlight_controller(struct backlight_controller *ctrler,
void *data, char *type)
{
struct device_node* bk_node;
@@ -99,7 +99,7 @@ void __pmac register_backlight_controller(struct backlight_controller *ctrler,
}
EXPORT_SYMBOL(register_backlight_controller);
-void __pmac unregister_backlight_controller(struct backlight_controller
+void unregister_backlight_controller(struct backlight_controller
*ctrler, void *data)
{
/* We keep the current backlight level (for now) */
@@ -108,7 +108,7 @@ void __pmac unregister_backlight_controller(struct backlight_controller
}
EXPORT_SYMBOL(unregister_backlight_controller);
-static int __pmac __set_backlight_enable(int enable)
+static int __set_backlight_enable(int enable)
{
int rc;
@@ -122,7 +122,7 @@ static int __pmac __set_backlight_enable(int enable)
release_console_sem();
return rc;
}
-int __pmac set_backlight_enable(int enable)
+int set_backlight_enable(int enable)
{
if (!backlighter)
return -ENODEV;
@@ -133,7 +133,7 @@ int __pmac set_backlight_enable(int enable)
EXPORT_SYMBOL(set_backlight_enable);
-int __pmac get_backlight_enable(void)
+int get_backlight_enable(void)
{
if (!backlighter)
return -ENODEV;
@@ -141,7 +141,7 @@ int __pmac get_backlight_enable(void)
}
EXPORT_SYMBOL(get_backlight_enable);
-static int __pmac __set_backlight_level(int level)
+static int __set_backlight_level(int level)
{
int rc = 0;
@@ -165,7 +165,7 @@ static int __pmac __set_backlight_level(int level)
}
return rc;
}
-int __pmac set_backlight_level(int level)
+int set_backlight_level(int level)
{
if (!backlighter)
return -ENODEV;
@@ -176,7 +176,7 @@ int __pmac set_backlight_level(int level)
EXPORT_SYMBOL(set_backlight_level);
-int __pmac get_backlight_level(void)
+int get_backlight_level(void)
{
if (!backlighter)
return -ENODEV;
diff --git a/arch/ppc/platforms/pmac_cpufreq.c b/arch/ppc/platforms/pmac_cpufreq.c
index d4bc5f67ec53..fba7e4d7c0bf 100644
--- a/arch/ppc/platforms/pmac_cpufreq.c
+++ b/arch/ppc/platforms/pmac_cpufreq.c
@@ -136,7 +136,7 @@ static inline void debug_calc_bogomips(void)
/* Switch CPU speed under 750FX CPU control
*/
-static int __pmac cpu_750fx_cpu_speed(int low_speed)
+static int cpu_750fx_cpu_speed(int low_speed)
{
u32 hid2;
@@ -172,7 +172,7 @@ static int __pmac cpu_750fx_cpu_speed(int low_speed)
return 0;
}
-static unsigned int __pmac cpu_750fx_get_cpu_speed(void)
+static unsigned int cpu_750fx_get_cpu_speed(void)
{
if (mfspr(SPRN_HID1) & HID1_PS)
return low_freq;
@@ -181,7 +181,7 @@ static unsigned int __pmac cpu_750fx_get_cpu_speed(void)
}
/* Switch CPU speed using DFS */
-static int __pmac dfs_set_cpu_speed(int low_speed)
+static int dfs_set_cpu_speed(int low_speed)
{
if (low_speed == 0) {
/* ramping up, set voltage first */
@@ -205,7 +205,7 @@ static int __pmac dfs_set_cpu_speed(int low_speed)
return 0;
}
-static unsigned int __pmac dfs_get_cpu_speed(void)
+static unsigned int dfs_get_cpu_speed(void)
{
if (mfspr(SPRN_HID1) & HID1_DFS)
return low_freq;
@@ -216,7 +216,7 @@ static unsigned int __pmac dfs_get_cpu_speed(void)
/* Switch CPU speed using slewing GPIOs
*/
-static int __pmac gpios_set_cpu_speed(int low_speed)
+static int gpios_set_cpu_speed(int low_speed)
{
int gpio, timeout = 0;
@@ -258,7 +258,7 @@ static int __pmac gpios_set_cpu_speed(int low_speed)
/* Switch CPU speed under PMU control
*/
-static int __pmac pmu_set_cpu_speed(int low_speed)
+static int pmu_set_cpu_speed(int low_speed)
{
struct adb_request req;
unsigned long save_l2cr;
@@ -354,7 +354,7 @@ static int __pmac pmu_set_cpu_speed(int low_speed)
return 0;
}
-static int __pmac do_set_cpu_speed(int speed_mode, int notify)
+static int do_set_cpu_speed(int speed_mode, int notify)
{
struct cpufreq_freqs freqs;
unsigned long l3cr;
@@ -391,17 +391,17 @@ static int __pmac do_set_cpu_speed(int speed_mode, int notify)
return 0;
}
-static unsigned int __pmac pmac_cpufreq_get_speed(unsigned int cpu)
+static unsigned int pmac_cpufreq_get_speed(unsigned int cpu)
{
return cur_freq;
}
-static int __pmac pmac_cpufreq_verify(struct cpufreq_policy *policy)
+static int pmac_cpufreq_verify(struct cpufreq_policy *policy)
{
return cpufreq_frequency_table_verify(policy, pmac_cpu_freqs);
}
-static int __pmac pmac_cpufreq_target( struct cpufreq_policy *policy,
+static int pmac_cpufreq_target( struct cpufreq_policy *policy,
unsigned int target_freq,
unsigned int relation)
{
@@ -414,13 +414,13 @@ static int __pmac pmac_cpufreq_target( struct cpufreq_policy *policy,
return do_set_cpu_speed(newstate, 1);
}
-unsigned int __pmac pmac_get_one_cpufreq(int i)
+unsigned int pmac_get_one_cpufreq(int i)
{
/* Supports only one CPU for now */
return (i == 0) ? cur_freq : 0;
}
-static int __pmac pmac_cpufreq_cpu_init(struct cpufreq_policy *policy)
+static int pmac_cpufreq_cpu_init(struct cpufreq_policy *policy)
{
if (policy->cpu != 0)
return -ENODEV;
@@ -433,7 +433,7 @@ static int __pmac pmac_cpufreq_cpu_init(struct cpufreq_policy *policy)
return cpufreq_frequency_table_cpuinfo(policy, pmac_cpu_freqs);
}
-static u32 __pmac read_gpio(struct device_node *np)
+static u32 read_gpio(struct device_node *np)
{
u32 *reg = (u32 *)get_property(np, "reg", NULL);
u32 offset;
@@ -452,7 +452,7 @@ static u32 __pmac read_gpio(struct device_node *np)
return offset;
}
-static int __pmac pmac_cpufreq_suspend(struct cpufreq_policy *policy, pm_message_t pmsg)
+static int pmac_cpufreq_suspend(struct cpufreq_policy *policy, pm_message_t pmsg)
{
/* Ok, this could be made a bit smarter, but let's be robust for now. We
* always force a speed change to high speed before sleep, to make sure
@@ -468,7 +468,7 @@ static int __pmac pmac_cpufreq_suspend(struct cpufreq_policy *policy, pm_message
return 0;
}
-static int __pmac pmac_cpufreq_resume(struct cpufreq_policy *policy)
+static int pmac_cpufreq_resume(struct cpufreq_policy *policy)
{
/* If we resume, first check if we have a get() function */
if (get_speed_proc)
@@ -501,7 +501,7 @@ static struct cpufreq_driver pmac_cpufreq_driver = {
};
-static int __pmac pmac_cpufreq_init_MacRISC3(struct device_node *cpunode)
+static int pmac_cpufreq_init_MacRISC3(struct device_node *cpunode)
{
struct device_node *volt_gpio_np = of_find_node_by_name(NULL,
"voltage-gpio");
@@ -593,7 +593,7 @@ static int __pmac pmac_cpufreq_init_MacRISC3(struct device_node *cpunode)
return 0;
}
-static int __pmac pmac_cpufreq_init_7447A(struct device_node *cpunode)
+static int pmac_cpufreq_init_7447A(struct device_node *cpunode)
{
struct device_node *volt_gpio_np;
@@ -620,7 +620,7 @@ static int __pmac pmac_cpufreq_init_7447A(struct device_node *cpunode)
return 0;
}
-static int __pmac pmac_cpufreq_init_750FX(struct device_node *cpunode)
+static int pmac_cpufreq_init_750FX(struct device_node *cpunode)
{
struct device_node *volt_gpio_np;
u32 pvr, *value;
diff --git a/arch/ppc/platforms/pmac_feature.c b/arch/ppc/platforms/pmac_feature.c
index dd6d45ae0501..58884a63ebdb 100644
--- a/arch/ppc/platforms/pmac_feature.c
+++ b/arch/ppc/platforms/pmac_feature.c
@@ -63,7 +63,7 @@ extern struct device_node *k2_skiplist[2];
* We use a single global lock to protect accesses. Each driver has
* to take care of its own locking
*/
-static DEFINE_SPINLOCK(feature_lock __pmacdata);
+static DEFINE_SPINLOCK(feature_lock);
#define LOCK(flags) spin_lock_irqsave(&feature_lock, flags);
#define UNLOCK(flags) spin_unlock_irqrestore(&feature_lock, flags);
@@ -72,9 +72,9 @@ static DEFINE_SPINLOCK(feature_lock __pmacdata);
/*
* Instance of some macio stuffs
*/
-struct macio_chip macio_chips[MAX_MACIO_CHIPS] __pmacdata;
+struct macio_chip macio_chips[MAX_MACIO_CHIPS];
-struct macio_chip* __pmac macio_find(struct device_node* child, int type)
+struct macio_chip* macio_find(struct device_node* child, int type)
{
while(child) {
int i;
@@ -89,7 +89,7 @@ struct macio_chip* __pmac macio_find(struct device_node* child, int type)
}
EXPORT_SYMBOL_GPL(macio_find);
-static const char* macio_names[] __pmacdata =
+static const char* macio_names[] =
{
"Unknown",
"Grand Central",
@@ -116,10 +116,10 @@ static const char* macio_names[] __pmacdata =
#define UN_BIS(r,v) (UN_OUT((r), UN_IN(r) | (v)))
#define UN_BIC(r,v) (UN_OUT((r), UN_IN(r) & ~(v)))
-static struct device_node* uninorth_node __pmacdata;
-static u32 __iomem * uninorth_base __pmacdata;
-static u32 uninorth_rev __pmacdata;
-static int uninorth_u3 __pmacdata;
+static struct device_node* uninorth_node;
+static u32 __iomem * uninorth_base;
+static u32 uninorth_rev;
+static int uninorth_u3;
static void __iomem *u3_ht;
/*
@@ -142,13 +142,13 @@ struct pmac_mb_def
struct feature_table_entry* features;
unsigned long board_flags;
};
-static struct pmac_mb_def pmac_mb __pmacdata;
+static struct pmac_mb_def pmac_mb;
/*
* Here are the chip specific feature functions
*/
-static inline int __pmac
+static inline int
simple_feature_tweak(struct device_node* node, int type, int reg, u32 mask, int value)
{
struct macio_chip* macio;
@@ -170,7 +170,7 @@ simple_feature_tweak(struct device_node* node, int type, int reg, u32 mask, int
#ifndef CONFIG_POWER4
-static long __pmac
+static long
ohare_htw_scc_enable(struct device_node* node, long param, long value)
{
struct macio_chip* macio;
@@ -263,21 +263,21 @@ ohare_htw_scc_enable(struct device_node* node, long param, long value)
return 0;
}
-static long __pmac
+static long
ohare_floppy_enable(struct device_node* node, long param, long value)
{
return simple_feature_tweak(node, macio_ohare,
OHARE_FCR, OH_FLOPPY_ENABLE, value);
}
-static long __pmac
+static long
ohare_mesh_enable(struct device_node* node, long param, long value)
{
return simple_feature_tweak(node, macio_ohare,
OHARE_FCR, OH_MESH_ENABLE, value);
}
-static long __pmac
+static long
ohare_ide_enable(struct device_node* node, long param, long value)
{
switch(param) {
@@ -298,7 +298,7 @@ ohare_ide_enable(struct device_node* node, long param, long value)
}
}
-static long __pmac
+static long
ohare_ide_reset(struct device_node* node, long param, long value)
{
switch(param) {
@@ -313,7 +313,7 @@ ohare_ide_reset(struct device_node* node, long param, long value)
}
}
-static long __pmac
+static long
ohare_sleep_state(struct device_node* node, long param, long value)
{
struct macio_chip* macio = &macio_chips[0];
@@ -329,7 +329,7 @@ ohare_sleep_state(struct device_node* node, long param, long value)
return 0;
}
-static long __pmac
+static long
heathrow_modem_enable(struct device_node* node, long param, long value)
{
struct macio_chip* macio;
@@ -373,7 +373,7 @@ heathrow_modem_enable(struct device_node* node, long param, long value)
return 0;
}
-static long __pmac
+static long
heathrow_floppy_enable(struct device_node* node, long param, long value)
{
return simple_feature_tweak(node, macio_unknown,
@@ -382,7 +382,7 @@ heathrow_floppy_enable(struct device_node* node, long param, long value)
value);
}
-static long __pmac
+static long
heathrow_mesh_enable(struct device_node* node, long param, long value)
{
struct macio_chip* macio;
@@ -411,7 +411,7 @@ heathrow_mesh_enable(struct device_node* node, long param, long value)
return 0;
}
-static long __pmac
+static long
heathrow_ide_enable(struct device_node* node, long param, long value)
{
switch(param) {
@@ -426,7 +426,7 @@ heathrow_ide_enable(struct device_node* node, long param, long value)
}
}
-static long __pmac
+static long
heathrow_ide_reset(struct device_node* node, long param, long value)
{
switch(param) {
@@ -441,7 +441,7 @@ heathrow_ide_reset(struct device_node* node, long param, long value)
}
}
-static long __pmac
+static long
heathrow_bmac_enable(struct device_node* node, long param, long value)
{
struct macio_chip* macio;
@@ -470,7 +470,7 @@ heathrow_bmac_enable(struct device_node* node, long param, long value)
return 0;
}
-static long __pmac
+static long
heathrow_sound_enable(struct device_node* node, long param, long value)
{
struct macio_chip* macio;
@@ -501,16 +501,16 @@ heathrow_sound_enable(struct device_node* node, long param, long value)
return 0;
}
-static u32 save_fcr[6] __pmacdata;
-static u32 save_mbcr __pmacdata;
-static u32 save_gpio_levels[2] __pmacdata;
-static u8 save_gpio_extint[KEYLARGO_GPIO_EXTINT_CNT] __pmacdata;
-static u8 save_gpio_normal[KEYLARGO_GPIO_CNT] __pmacdata;
-static u32 save_unin_clock_ctl __pmacdata;
-static struct dbdma_regs save_dbdma[13] __pmacdata;
-static struct dbdma_regs save_alt_dbdma[13] __pmacdata;
+static u32 save_fcr[6];
+static u32 save_mbcr;
+static u32 save_gpio_levels[2];
+static u8 save_gpio_extint[KEYLARGO_GPIO_EXTINT_CNT];
+static u8 save_gpio_normal[KEYLARGO_GPIO_CNT];
+static u32 save_unin_clock_ctl;
+static struct dbdma_regs save_dbdma[13];
+static struct dbdma_regs save_alt_dbdma[13];
-static void __pmac
+static void
dbdma_save(struct macio_chip* macio, struct dbdma_regs* save)
{
int i;
@@ -527,7 +527,7 @@ dbdma_save(struct macio_chip* macio, struct dbdma_regs* save)
}
}
-static void __pmac
+static void
dbdma_restore(struct macio_chip* macio, struct dbdma_regs* save)
{
int i;
@@ -547,7 +547,7 @@ dbdma_restore(struct macio_chip* macio, struct dbdma_regs* save)
}
}
-static void __pmac
+static void
heathrow_sleep(struct macio_chip* macio, int secondary)
{
if (secondary) {
@@ -580,7 +580,7 @@ heathrow_sleep(struct macio_chip* macio, int secondary)
(void)MACIO_IN32(HEATHROW_FCR);
}
-static void __pmac
+static void
heathrow_wakeup(struct macio_chip* macio, int secondary)
{
if (secondary) {
@@ -605,7 +605,7 @@ heathrow_wakeup(struct macio_chip* macio, int secondary)
}
}
-static long __pmac
+static long
heathrow_sleep_state(struct device_node* node, long param, long value)
{
if ((pmac_mb.board_flags & PMAC_MB_CAN_SLEEP) == 0)
@@ -622,7 +622,7 @@ heathrow_sleep_state(struct device_node* node, long param, long value)
return 0;
}
-static long __pmac
+static long
core99_scc_enable(struct device_node* node, long param, long value)
{
struct macio_chip* macio;
@@ -723,7 +723,7 @@ core99_scc_enable(struct device_node* node, long param, long value)
return 0;
}
-static long __pmac
+static long
core99_modem_enable(struct device_node* node, long param, long value)
{
struct macio_chip* macio;
@@ -775,7 +775,7 @@ core99_modem_enable(struct device_node* node, long param, long value)
return 0;
}
-static long __pmac
+static long
pangea_modem_enable(struct device_node* node, long param, long value)
{
struct macio_chip* macio;
@@ -830,7 +830,7 @@ pangea_modem_enable(struct device_node* node, long param, long value)
return 0;
}
-static long __pmac
+static long
core99_ata100_enable(struct device_node* node, long value)
{
unsigned long flags;
@@ -860,7 +860,7 @@ core99_ata100_enable(struct device_node* node, long value)
return 0;
}
-static long __pmac
+static long
core99_ide_enable(struct device_node* node, long param, long value)
{
/* Bus ID 0 to 2 are KeyLargo based IDE, busID 3 is U2
@@ -883,7 +883,7 @@ core99_ide_enable(struct device_node* node, long param, long value)
}
}
-static long __pmac
+static long
core99_ide_reset(struct device_node* node, long param, long value)
{
switch(param) {
@@ -901,7 +901,7 @@ core99_ide_reset(struct device_node* node, long param, long value)
}
}
-static long __pmac
+static long
core99_gmac_enable(struct device_node* node, long param, long value)
{
unsigned long flags;
@@ -918,7 +918,7 @@ core99_gmac_enable(struct device_node* node, long param, long value)
return 0;
}
-static long __pmac
+static long
core99_gmac_phy_reset(struct device_node* node, long param, long value)
{
unsigned long flags;
@@ -943,7 +943,7 @@ core99_gmac_phy_reset(struct device_node* node, long param, long value)
return 0;
}
-static long __pmac
+static long
core99_sound_chip_enable(struct device_node* node, long param, long value)
{
struct macio_chip* macio;
@@ -973,7 +973,7 @@ core99_sound_chip_enable(struct device_node* node, long param, long value)
return 0;
}
-static long __pmac
+static long
core99_airport_enable(struct device_node* node, long param, long value)
{
struct macio_chip* macio;
@@ -1060,7 +1060,7 @@ core99_airport_enable(struct device_node* node, long param, long value)
}
#ifdef CONFIG_SMP
-static long __pmac
+static long
core99_reset_cpu(struct device_node* node, long param, long value)
{
unsigned int reset_io = 0;
@@ -1104,7 +1104,7 @@ core99_reset_cpu(struct device_node* node, long param, long value)
}
#endif /* CONFIG_SMP */
-static long __pmac
+static long
core99_usb_enable(struct device_node* node, long param, long value)
{
struct macio_chip* macio;
@@ -1257,7 +1257,7 @@ core99_usb_enable(struct device_node* node, long param, long value)
return 0;
}
-static long __pmac
+static long
core99_firewire_enable(struct device_node* node, long param, long value)
{
unsigned long flags;
@@ -1284,7 +1284,7 @@ core99_firewire_enable(struct device_node* node, long param, long value)
return 0;
}
-static long __pmac
+static long
core99_firewire_cable_power(struct device_node* node, long param, long value)
{
unsigned long flags;
@@ -1315,7 +1315,7 @@ core99_firewire_cable_power(struct device_node* node, long param, long value)
return 0;
}
-static long __pmac
+static long
intrepid_aack_delay_enable(struct device_node* node, long param, long value)
{
unsigned long flags;
@@ -1336,7 +1336,7 @@ intrepid_aack_delay_enable(struct device_node* node, long param, long value)
#endif /* CONFIG_POWER4 */
-static long __pmac
+static long
core99_read_gpio(struct device_node* node, long param, long value)
{
struct macio_chip* macio = &macio_chips[0];
@@ -1345,7 +1345,7 @@ core99_read_gpio(struct device_node* node, long param, long value)
}
-static long __pmac
+static long
core99_write_gpio(struct device_node* node, long param, long value)
{
struct macio_chip* macio = &macio_chips[0];
@@ -1356,7 +1356,7 @@ core99_write_gpio(struct device_node* node, long param, long value)
#ifdef CONFIG_POWER4
-static long __pmac
+static long
g5_gmac_enable(struct device_node* node, long param, long value)
{
struct macio_chip* macio = &macio_chips[0];
@@ -1380,7 +1380,7 @@ g5_gmac_enable(struct device_node* node, long param, long value)
return 0;
}
-static long __pmac
+static long
g5_fw_enable(struct device_node* node, long param, long value)
{
struct macio_chip* macio = &macio_chips[0];
@@ -1403,7 +1403,7 @@ g5_fw_enable(struct device_node* node, long param, long value)
return 0;
}
-static long __pmac
+static long
g5_mpic_enable(struct device_node* node, long param, long value)
{
unsigned long flags;
@@ -1419,7 +1419,7 @@ g5_mpic_enable(struct device_node* node, long param, long value)
}
#ifdef CONFIG_SMP
-static long __pmac
+static long
g5_reset_cpu(struct device_node* node, long param, long value)
{
unsigned int reset_io = 0;
@@ -1465,7 +1465,7 @@ g5_reset_cpu(struct device_node* node, long param, long value)
* This takes the second CPU off the bus on dual CPU machines
* running UP
*/
-void __pmac g5_phy_disable_cpu1(void)
+void g5_phy_disable_cpu1(void)
{
UN_OUT(U3_API_PHY_CONFIG_1, 0);
}
@@ -1474,7 +1474,7 @@ void __pmac g5_phy_disable_cpu1(void)
#ifndef CONFIG_POWER4
-static void __pmac
+static void
keylargo_shutdown(struct macio_chip* macio, int sleep_mode)
{
u32 temp;
@@ -1528,7 +1528,7 @@ keylargo_shutdown(struct macio_chip* macio, int sleep_mode)
(void)MACIO_IN32(KEYLARGO_FCR0); mdelay(1);
}
-static void __pmac
+static void
pangea_shutdown(struct macio_chip* macio, int sleep_mode)
{
u32 temp;
@@ -1562,7 +1562,7 @@ pangea_shutdown(struct macio_chip* macio, int sleep_mode)
(void)MACIO_IN32(KEYLARGO_FCR0); mdelay(1);
}
-static void __pmac
+static void
intrepid_shutdown(struct macio_chip* macio, int sleep_mode)
{
u32 temp;
@@ -1591,7 +1591,7 @@ intrepid_shutdown(struct macio_chip* macio, int sleep_mode)
}
-void __pmac pmac_tweak_clock_spreading(int enable)
+void pmac_tweak_clock_spreading(int enable)
{
struct macio_chip* macio = &macio_chips[0];
@@ -1698,7 +1698,7 @@ void __pmac pmac_tweak_clock_spreading(int enable)
}
-static int __pmac
+static int
core99_sleep(void)
{
struct macio_chip* macio;
@@ -1791,7 +1791,7 @@ core99_sleep(void)
return 0;
}
-static int __pmac
+static int
core99_wake_up(void)
{
struct macio_chip* macio;
@@ -1854,7 +1854,7 @@ core99_wake_up(void)
return 0;
}
-static long __pmac
+static long
core99_sleep_state(struct device_node* node, long param, long value)
{
/* Param == 1 means to enter the "fake sleep" mode that is
@@ -1884,7 +1884,7 @@ core99_sleep_state(struct device_node* node, long param, long value)
#endif /* CONFIG_POWER4 */
-static long __pmac
+static long
generic_dev_can_wake(struct device_node* node, long param, long value)
{
/* Todo: eventually check we are really dealing with on-board
@@ -1896,7 +1896,7 @@ generic_dev_can_wake(struct device_node* node, long param, long value)
return 0;
}
-static long __pmac
+static long
generic_get_mb_info(struct device_node* node, long param, long value)
{
switch(param) {
@@ -1919,7 +1919,7 @@ generic_get_mb_info(struct device_node* node, long param, long value)
/* Used on any machine
*/
-static struct feature_table_entry any_features[] __pmacdata = {
+static struct feature_table_entry any_features[] = {
{ PMAC_FTR_GET_MB_INFO, generic_get_mb_info },
{ PMAC_FTR_DEVICE_CAN_WAKE, generic_dev_can_wake },
{ 0, NULL }
@@ -1931,7 +1931,7 @@ static struct feature_table_entry any_features[] __pmacdata = {
* 2400,3400 and 3500 series powerbooks. Some older desktops seem
* to have issues with turning on/off those asic cells
*/
-static struct feature_table_entry ohare_features[] __pmacdata = {
+static struct feature_table_entry ohare_features[] = {
{ PMAC_FTR_SCC_ENABLE, ohare_htw_scc_enable },
{ PMAC_FTR_SWIM3_ENABLE, ohare_floppy_enable },
{ PMAC_FTR_MESH_ENABLE, ohare_mesh_enable },
@@ -1945,7 +1945,7 @@ static struct feature_table_entry ohare_features[] __pmacdata = {
* Separated as some features couldn't be properly tested
* and the serial port control bits appear to confuse it.
*/
-static struct feature_table_entry heathrow_desktop_features[] __pmacdata = {
+static struct feature_table_entry heathrow_desktop_features[] = {
{ PMAC_FTR_SWIM3_ENABLE, heathrow_floppy_enable },
{ PMAC_FTR_MESH_ENABLE, heathrow_mesh_enable },
{ PMAC_FTR_IDE_ENABLE, heathrow_ide_enable },
@@ -1957,7 +1957,7 @@ static struct feature_table_entry heathrow_desktop_features[] __pmacdata = {
/* Heathrow based laptop, that is the Wallstreet and mainstreet
* powerbooks.
*/
-static struct feature_table_entry heathrow_laptop_features[] __pmacdata = {
+static struct feature_table_entry heathrow_laptop_features[] = {
{ PMAC_FTR_SCC_ENABLE, ohare_htw_scc_enable },
{ PMAC_FTR_MODEM_ENABLE, heathrow_modem_enable },
{ PMAC_FTR_SWIM3_ENABLE, heathrow_floppy_enable },
@@ -1973,7 +1973,7 @@ static struct feature_table_entry heathrow_laptop_features[] __pmacdata = {
/* Paddington based machines
* The lombard (101) powerbook, first iMac models, B&W G3 and Yikes G4.
*/
-static struct feature_table_entry paddington_features[] __pmacdata = {
+static struct feature_table_entry paddington_features[] = {
{ PMAC_FTR_SCC_ENABLE, ohare_htw_scc_enable },
{ PMAC_FTR_MODEM_ENABLE, heathrow_modem_enable },
{ PMAC_FTR_SWIM3_ENABLE, heathrow_floppy_enable },
@@ -1991,7 +1991,7 @@ static struct feature_table_entry paddington_features[] __pmacdata = {
* chipset. The pangea chipset is the "combo" UniNorth/KeyLargo
* used on iBook2 & iMac "flow power".
*/
-static struct feature_table_entry core99_features[] __pmacdata = {
+static struct feature_table_entry core99_features[] = {
{ PMAC_FTR_SCC_ENABLE, core99_scc_enable },
{ PMAC_FTR_MODEM_ENABLE, core99_modem_enable },
{ PMAC_FTR_IDE_ENABLE, core99_ide_enable },
@@ -2014,7 +2014,7 @@ static struct feature_table_entry core99_features[] __pmacdata = {
/* RackMac
*/
-static struct feature_table_entry rackmac_features[] __pmacdata = {
+static struct feature_table_entry rackmac_features[] = {
{ PMAC_FTR_SCC_ENABLE, core99_scc_enable },
{ PMAC_FTR_IDE_ENABLE, core99_ide_enable },
{ PMAC_FTR_IDE_RESET, core99_ide_reset },
@@ -2034,7 +2034,7 @@ static struct feature_table_entry rackmac_features[] __pmacdata = {
/* Pangea features
*/
-static struct feature_table_entry pangea_features[] __pmacdata = {
+static struct feature_table_entry pangea_features[] = {
{ PMAC_FTR_SCC_ENABLE, core99_scc_enable },
{ PMAC_FTR_MODEM_ENABLE, pangea_modem_enable },
{ PMAC_FTR_IDE_ENABLE, core99_ide_enable },
@@ -2054,7 +2054,7 @@ static struct feature_table_entry pangea_features[] __pmacdata = {
/* Intrepid features
*/
-static struct feature_table_entry intrepid_features[] __pmacdata = {
+static struct feature_table_entry intrepid_features[] = {
{ PMAC_FTR_SCC_ENABLE, core99_scc_enable },
{ PMAC_FTR_MODEM_ENABLE, pangea_modem_enable },
{ PMAC_FTR_IDE_ENABLE, core99_ide_enable },
@@ -2077,7 +2077,7 @@ static struct feature_table_entry intrepid_features[] __pmacdata = {
/* G5 features
*/
-static struct feature_table_entry g5_features[] __pmacdata = {
+static struct feature_table_entry g5_features[] = {
{ PMAC_FTR_GMAC_ENABLE, g5_gmac_enable },
{ PMAC_FTR_1394_ENABLE, g5_fw_enable },
{ PMAC_FTR_ENABLE_MPIC, g5_mpic_enable },
@@ -2091,7 +2091,7 @@ static struct feature_table_entry g5_features[] __pmacdata = {
#endif /* CONFIG_POWER4 */
-static struct pmac_mb_def pmac_mb_defs[] __pmacdata = {
+static struct pmac_mb_def pmac_mb_defs[] = {
#ifndef CONFIG_POWER4
/*
* Desktops
@@ -2356,7 +2356,7 @@ static struct pmac_mb_def pmac_mb_defs[] __pmacdata = {
/*
* The toplevel feature_call callback
*/
-long __pmac
+long
pmac_do_feature_call(unsigned int selector, ...)
{
struct device_node* node;
@@ -2939,8 +2939,8 @@ void __init pmac_check_ht_link(void)
* Early video resume hook
*/
-static void (*pmac_early_vresume_proc)(void *data) __pmacdata;
-static void *pmac_early_vresume_data __pmacdata;
+static void (*pmac_early_vresume_proc)(void *data);
+static void *pmac_early_vresume_data;
void pmac_set_early_video_resume(void (*proc)(void *data), void *data)
{
@@ -2953,7 +2953,7 @@ void pmac_set_early_video_resume(void (*proc)(void *data), void *data)
}
EXPORT_SYMBOL(pmac_set_early_video_resume);
-void __pmac pmac_call_early_video_resume(void)
+void pmac_call_early_video_resume(void)
{
if (pmac_early_vresume_proc)
pmac_early_vresume_proc(pmac_early_vresume_data);
@@ -2963,11 +2963,11 @@ void __pmac pmac_call_early_video_resume(void)
* AGP related suspend/resume code
*/
-static struct pci_dev *pmac_agp_bridge __pmacdata;
-static int (*pmac_agp_suspend)(struct pci_dev *bridge) __pmacdata;
-static int (*pmac_agp_resume)(struct pci_dev *bridge) __pmacdata;
+static struct pci_dev *pmac_agp_bridge;
+static int (*pmac_agp_suspend)(struct pci_dev *bridge);
+static int (*pmac_agp_resume)(struct pci_dev *bridge);
-void __pmac pmac_register_agp_pm(struct pci_dev *bridge,
+void pmac_register_agp_pm(struct pci_dev *bridge,
int (*suspend)(struct pci_dev *bridge),
int (*resume)(struct pci_dev *bridge))
{
@@ -2984,7 +2984,7 @@ void __pmac pmac_register_agp_pm(struct pci_dev *bridge,
}
EXPORT_SYMBOL(pmac_register_agp_pm);
-void __pmac pmac_suspend_agp_for_card(struct pci_dev *dev)
+void pmac_suspend_agp_for_card(struct pci_dev *dev)
{
if (pmac_agp_bridge == NULL || pmac_agp_suspend == NULL)
return;
@@ -2994,7 +2994,7 @@ void __pmac pmac_suspend_agp_for_card(struct pci_dev *dev)
}
EXPORT_SYMBOL(pmac_suspend_agp_for_card);
-void __pmac pmac_resume_agp_for_card(struct pci_dev *dev)
+void pmac_resume_agp_for_card(struct pci_dev *dev)
{
if (pmac_agp_bridge == NULL || pmac_agp_resume == NULL)
return;
diff --git a/arch/ppc/platforms/pmac_nvram.c b/arch/ppc/platforms/pmac_nvram.c
index c9de64205996..8c9b008c7226 100644
--- a/arch/ppc/platforms/pmac_nvram.c
+++ b/arch/ppc/platforms/pmac_nvram.c
@@ -88,17 +88,17 @@ extern int system_running;
static int (*core99_write_bank)(int bank, u8* datas);
static int (*core99_erase_bank)(int bank);
-static char *nvram_image __pmacdata;
+static char *nvram_image;
-static unsigned char __pmac core99_nvram_read_byte(int addr)
+static unsigned char core99_nvram_read_byte(int addr)
{
if (nvram_image == NULL)
return 0xff;
return nvram_image[addr];
}
-static void __pmac core99_nvram_write_byte(int addr, unsigned char val)
+static void core99_nvram_write_byte(int addr, unsigned char val)
{
if (nvram_image == NULL)
return;
@@ -106,18 +106,18 @@ static void __pmac core99_nvram_write_byte(int addr, unsigned char val)
}
-static unsigned char __openfirmware direct_nvram_read_byte(int addr)
+static unsigned char direct_nvram_read_byte(int addr)
{
return in_8(&nvram_data[(addr & (NVRAM_SIZE - 1)) * nvram_mult]);
}
-static void __openfirmware direct_nvram_write_byte(int addr, unsigned char val)
+static void direct_nvram_write_byte(int addr, unsigned char val)
{
out_8(&nvram_data[(addr & (NVRAM_SIZE - 1)) * nvram_mult], val);
}
-static unsigned char __pmac indirect_nvram_read_byte(int addr)
+static unsigned char indirect_nvram_read_byte(int addr)
{
unsigned char val;
unsigned long flags;
@@ -130,7 +130,7 @@ static unsigned char __pmac indirect_nvram_read_byte(int addr)
return val;
}
-static void __pmac indirect_nvram_write_byte(int addr, unsigned char val)
+static void indirect_nvram_write_byte(int addr, unsigned char val)
{
unsigned long flags;
@@ -143,13 +143,13 @@ static void __pmac indirect_nvram_write_byte(int addr, unsigned char val)
#ifdef CONFIG_ADB_PMU
-static void __pmac pmu_nvram_complete(struct adb_request *req)
+static void pmu_nvram_complete(struct adb_request *req)
{
if (req->arg)
complete((struct completion *)req->arg);
}
-static unsigned char __pmac pmu_nvram_read_byte(int addr)
+static unsigned char pmu_nvram_read_byte(int addr)
{
struct adb_request req;
DECLARE_COMPLETION(req_complete);
@@ -165,7 +165,7 @@ static unsigned char __pmac pmu_nvram_read_byte(int addr)
return req.reply[0];
}
-static void __pmac pmu_nvram_write_byte(int addr, unsigned char val)
+static void pmu_nvram_write_byte(int addr, unsigned char val)
{
struct adb_request req;
DECLARE_COMPLETION(req_complete);
@@ -183,7 +183,7 @@ static void __pmac pmu_nvram_write_byte(int addr, unsigned char val)
#endif /* CONFIG_ADB_PMU */
-static u8 __pmac chrp_checksum(struct chrp_header* hdr)
+static u8 chrp_checksum(struct chrp_header* hdr)
{
u8 *ptr;
u16 sum = hdr->signature;
@@ -194,7 +194,7 @@ static u8 __pmac chrp_checksum(struct chrp_header* hdr)
return sum;
}
-static u32 __pmac core99_calc_adler(u8 *buffer)
+static u32 core99_calc_adler(u8 *buffer)
{
int cnt;
u32 low, high;
@@ -216,7 +216,7 @@ static u32 __pmac core99_calc_adler(u8 *buffer)
return (high << 16) | low;
}
-static u32 __pmac core99_check(u8* datas)
+static u32 core99_check(u8* datas)
{
struct core99_header* hdr99 = (struct core99_header*)datas;
@@ -235,7 +235,7 @@ static u32 __pmac core99_check(u8* datas)
return hdr99->generation;
}
-static int __pmac sm_erase_bank(int bank)
+static int sm_erase_bank(int bank)
{
int stat, i;
unsigned long timeout;
@@ -267,7 +267,7 @@ static int __pmac sm_erase_bank(int bank)
return 0;
}
-static int __pmac sm_write_bank(int bank, u8* datas)
+static int sm_write_bank(int bank, u8* datas)
{
int i, stat = 0;
unsigned long timeout;
@@ -302,7 +302,7 @@ static int __pmac sm_write_bank(int bank, u8* datas)
return 0;
}
-static int __pmac amd_erase_bank(int bank)
+static int amd_erase_bank(int bank)
{
int i, stat = 0;
unsigned long timeout;
@@ -349,7 +349,7 @@ static int __pmac amd_erase_bank(int bank)
return 0;
}
-static int __pmac amd_write_bank(int bank, u8* datas)
+static int amd_write_bank(int bank, u8* datas)
{
int i, stat = 0;
unsigned long timeout;
@@ -430,7 +430,7 @@ static void __init lookup_partitions(void)
DBG("nvram: NR partition at 0x%x\n", nvram_partitions[pmac_nvram_NR]);
}
-static void __pmac core99_nvram_sync(void)
+static void core99_nvram_sync(void)
{
struct core99_header* hdr99;
unsigned long flags;
@@ -554,12 +554,12 @@ void __init pmac_nvram_init(void)
lookup_partitions();
}
-int __pmac pmac_get_partition(int partition)
+int pmac_get_partition(int partition)
{
return nvram_partitions[partition];
}
-u8 __pmac pmac_xpram_read(int xpaddr)
+u8 pmac_xpram_read(int xpaddr)
{
int offset = nvram_partitions[pmac_nvram_XPRAM];
@@ -569,7 +569,7 @@ u8 __pmac pmac_xpram_read(int xpaddr)
return ppc_md.nvram_read_val(xpaddr + offset);
}
-void __pmac pmac_xpram_write(int xpaddr, u8 data)
+void pmac_xpram_write(int xpaddr, u8 data)
{
int offset = nvram_partitions[pmac_nvram_XPRAM];
diff --git a/arch/ppc/platforms/pmac_pci.c b/arch/ppc/platforms/pmac_pci.c
index 719fb49fe2bc..786295b6ddd0 100644
--- a/arch/ppc/platforms/pmac_pci.c
+++ b/arch/ppc/platforms/pmac_pci.c
@@ -141,7 +141,7 @@ fixup_bus_range(struct device_node *bridge)
|(((unsigned long)(off)) & 0xFCUL) \
|1UL)
-static void volatile __iomem * __pmac
+static void volatile __iomem *
macrisc_cfg_access(struct pci_controller* hose, u8 bus, u8 dev_fn, u8 offset)
{
unsigned int caddr;
@@ -162,7 +162,7 @@ macrisc_cfg_access(struct pci_controller* hose, u8 bus, u8 dev_fn, u8 offset)
return hose->cfg_data + offset;
}
-static int __pmac
+static int
macrisc_read_config(struct pci_bus *bus, unsigned int devfn, int offset,
int len, u32 *val)
{
@@ -190,7 +190,7 @@ macrisc_read_config(struct pci_bus *bus, unsigned int devfn, int offset,
return PCIBIOS_SUCCESSFUL;
}
-static int __pmac
+static int
macrisc_write_config(struct pci_bus *bus, unsigned int devfn, int offset,
int len, u32 val)
{
@@ -230,7 +230,7 @@ static struct pci_ops macrisc_pci_ops =
/*
* Verifiy that a specific (bus, dev_fn) exists on chaos
*/
-static int __pmac
+static int
chaos_validate_dev(struct pci_bus *bus, int devfn, int offset)
{
struct device_node *np;
@@ -252,7 +252,7 @@ chaos_validate_dev(struct pci_bus *bus, int devfn, int offset)
return PCIBIOS_SUCCESSFUL;
}
-static int __pmac
+static int
chaos_read_config(struct pci_bus *bus, unsigned int devfn, int offset,
int len, u32 *val)
{
@@ -264,7 +264,7 @@ chaos_read_config(struct pci_bus *bus, unsigned int devfn, int offset,
return macrisc_read_config(bus, devfn, offset, len, val);
}
-static int __pmac
+static int
chaos_write_config(struct pci_bus *bus, unsigned int devfn, int offset,
int len, u32 val)
{
@@ -294,7 +294,7 @@ static struct pci_ops chaos_pci_ops =
+ (((unsigned long)bus) << 16) \
+ 0x01000000UL)
-static void volatile __iomem * __pmac
+static void volatile __iomem *
u3_ht_cfg_access(struct pci_controller* hose, u8 bus, u8 devfn, u8 offset)
{
if (bus == hose->first_busno) {
@@ -307,7 +307,7 @@ u3_ht_cfg_access(struct pci_controller* hose, u8 bus, u8 devfn, u8 offset)
return hose->cfg_data + U3_HT_CFA1(bus, devfn, offset);
}
-static int __pmac
+static int
u3_ht_read_config(struct pci_bus *bus, unsigned int devfn, int offset,
int len, u32 *val)
{
@@ -357,7 +357,7 @@ u3_ht_read_config(struct pci_bus *bus, unsigned int devfn, int offset,
return PCIBIOS_SUCCESSFUL;
}
-static int __pmac
+static int
u3_ht_write_config(struct pci_bus *bus, unsigned int devfn, int offset,
int len, u32 val)
{
@@ -575,7 +575,7 @@ pmac_find_bridges(void)
* some offset between bus number and domains for now when we
* assign all busses should help for now
*/
- if (pci_assign_all_busses)
+ if (pci_assign_all_buses)
pcibios_assign_bus_offset = 0x10;
#ifdef CONFIG_POWER4
@@ -643,7 +643,7 @@ static inline void grackle_set_loop_snoop(struct pci_controller *bp, int enable)
static int __init
setup_uninorth(struct pci_controller* hose, struct reg_property* addr)
{
- pci_assign_all_busses = 1;
+ pci_assign_all_buses = 1;
has_uninorth = 1;
hose->ops = &macrisc_pci_ops;
hose->cfg_addr = ioremap(addr->address + 0x800000, 0x1000);
@@ -677,7 +677,7 @@ setup_u3_agp(struct pci_controller* hose, struct reg_property* addr)
{
/* On G5, we move AGP up to high bus number so we don't need
* to reassign bus numbers for HT. If we ever have P2P bridges
- * on AGP, we'll have to move pci_assign_all_busses to the
+ * on AGP, we'll have to move pci_assign_all_buses to the
* pci_controller structure so we enable it for AGP and not for
* HT childs.
* We hard code the address because of the different size of
@@ -899,7 +899,7 @@ pmac_pcibios_fixup(void)
pcibios_fixup_OF_interrupts();
}
-int __pmac
+int
pmac_pci_enable_device_hook(struct pci_dev *dev, int initial)
{
struct device_node* node;
@@ -1096,7 +1096,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, pmac_pci_fixup_pciata);
* Disable second function on K2-SATA, it's broken
* and disable IO BARs on first one
*/
-void __pmac pmac_pci_fixup_k2_sata(struct pci_dev* dev)
+void pmac_pci_fixup_k2_sata(struct pci_dev* dev)
{
int i;
u16 cmd;
diff --git a/arch/ppc/platforms/pmac_pic.c b/arch/ppc/platforms/pmac_pic.c
index 2ce058895e03..4742bf609357 100644
--- a/arch/ppc/platforms/pmac_pic.c
+++ b/arch/ppc/platforms/pmac_pic.c
@@ -35,6 +35,7 @@
#include <asm/open_pic.h>
#include <asm/xmon.h>
#include <asm/pmac_feature.h>
+#include <asm/machdep.h>
#include "pmac_pic.h"
@@ -53,7 +54,7 @@ struct pmac_irq_hw {
};
/* Default addresses */
-static volatile struct pmac_irq_hw *pmac_irq_hw[4] __pmacdata = {
+static volatile struct pmac_irq_hw *pmac_irq_hw[4] = {
(struct pmac_irq_hw *) 0xf3000020,
(struct pmac_irq_hw *) 0xf3000010,
(struct pmac_irq_hw *) 0xf4000020,
@@ -64,22 +65,25 @@ static volatile struct pmac_irq_hw *pmac_irq_hw[4] __pmacdata = {
#define OHARE_LEVEL_MASK 0x1ff00000
#define HEATHROW_LEVEL_MASK 0x1ff00000
-static int max_irqs __pmacdata;
-static int max_real_irqs __pmacdata;
-static u32 level_mask[4] __pmacdata;
+static int max_irqs;
+static int max_real_irqs;
+static u32 level_mask[4];
-static DEFINE_SPINLOCK(pmac_pic_lock __pmacdata);
+static DEFINE_SPINLOCK(pmac_pic_lock);
#define GATWICK_IRQ_POOL_SIZE 10
-static struct interrupt_info gatwick_int_pool[GATWICK_IRQ_POOL_SIZE] __pmacdata;
+static struct interrupt_info gatwick_int_pool[GATWICK_IRQ_POOL_SIZE];
+
+#define NR_MASK_WORDS ((NR_IRQS + 31) / 32)
+static unsigned long ppc_lost_interrupts[NR_MASK_WORDS];
/*
* Mark an irq as "lost". This is only used on the pmac
* since it can lose interrupts (see pmac_set_irq_mask).
* -- Cort
*/
-void __pmac
+void
__set_lost(unsigned long irq_nr, int nokick)
{
if (!test_and_set_bit(irq_nr, ppc_lost_interrupts)) {
@@ -89,7 +93,7 @@ __set_lost(unsigned long irq_nr, int nokick)
}
}
-static void __pmac
+static void
pmac_mask_and_ack_irq(unsigned int irq_nr)
{
unsigned long bit = 1UL << (irq_nr & 0x1f);
@@ -114,7 +118,7 @@ pmac_mask_and_ack_irq(unsigned int irq_nr)
spin_unlock_irqrestore(&pmac_pic_lock, flags);
}
-static void __pmac pmac_set_irq_mask(unsigned int irq_nr, int nokicklost)
+static void pmac_set_irq_mask(unsigned int irq_nr, int nokicklost)
{
unsigned long bit = 1UL << (irq_nr & 0x1f);
int i = irq_nr >> 5;
@@ -147,7 +151,7 @@ static void __pmac pmac_set_irq_mask(unsigned int irq_nr, int nokicklost)
/* When an irq gets requested for the first client, if it's an
* edge interrupt, we clear any previous one on the controller
*/
-static unsigned int __pmac pmac_startup_irq(unsigned int irq_nr)
+static unsigned int pmac_startup_irq(unsigned int irq_nr)
{
unsigned long bit = 1UL << (irq_nr & 0x1f);
int i = irq_nr >> 5;
@@ -160,20 +164,20 @@ static unsigned int __pmac pmac_startup_irq(unsigned int irq_nr)
return 0;
}
-static void __pmac pmac_mask_irq(unsigned int irq_nr)
+static void pmac_mask_irq(unsigned int irq_nr)
{
clear_bit(irq_nr, ppc_cached_irq_mask);
pmac_set_irq_mask(irq_nr, 0);
mb();
}
-static void __pmac pmac_unmask_irq(unsigned int irq_nr)
+static void pmac_unmask_irq(unsigned int irq_nr)
{
set_bit(irq_nr, ppc_cached_irq_mask);
pmac_set_irq_mask(irq_nr, 0);
}
-static void __pmac pmac_end_irq(unsigned int irq_nr)
+static void pmac_end_irq(unsigned int irq_nr)
{
if (!(irq_desc[irq_nr].status & (IRQ_DISABLED|IRQ_INPROGRESS))
&& irq_desc[irq_nr].action) {
diff --git a/arch/ppc/platforms/pmac_setup.c b/arch/ppc/platforms/pmac_setup.c
index d6356f480d90..55d2beffe560 100644
--- a/arch/ppc/platforms/pmac_setup.c
+++ b/arch/ppc/platforms/pmac_setup.c
@@ -122,7 +122,7 @@ extern struct smp_ops_t psurge_smp_ops;
extern struct smp_ops_t core99_smp_ops;
#endif /* CONFIG_SMP */
-static int __pmac
+static int
pmac_show_cpuinfo(struct seq_file *m)
{
struct device_node *np;
@@ -226,7 +226,7 @@ pmac_show_cpuinfo(struct seq_file *m)
return 0;
}
-static int __openfirmware
+static int
pmac_show_percpuinfo(struct seq_file *m, int i)
{
#ifdef CONFIG_CPU_FREQ_PMAC
@@ -330,9 +330,9 @@ pmac_setup_arch(void)
#ifdef CONFIG_SMP
/* Check for Core99 */
if (find_devices("uni-n") || find_devices("u3"))
- ppc_md.smp_ops = &core99_smp_ops;
+ smp_ops = &core99_smp_ops;
else
- ppc_md.smp_ops = &psurge_smp_ops;
+ smp_ops = &psurge_smp_ops;
#endif /* CONFIG_SMP */
pci_create_OF_bus_map();
@@ -447,7 +447,7 @@ static int pmac_pm_enter(suspend_state_t state)
enable_kernel_fp();
#ifdef CONFIG_ALTIVEC
- if (cur_cpu_spec[0]->cpu_features & CPU_FTR_ALTIVEC)
+ if (cur_cpu_spec->cpu_features & CPU_FTR_ALTIVEC)
enable_kernel_altivec();
#endif /* CONFIG_ALTIVEC */
@@ -485,7 +485,7 @@ static int pmac_late_init(void)
late_initcall(pmac_late_init);
/* can't be __init - can be called whenever a disk is first accessed */
-void __pmac
+void
note_bootable_part(dev_t dev, int part, int goodness)
{
static int found_boot = 0;
@@ -511,7 +511,7 @@ note_bootable_part(dev_t dev, int part, int goodness)
}
}
-static void __pmac
+static void
pmac_restart(char *cmd)
{
#ifdef CONFIG_ADB_CUDA
@@ -536,7 +536,7 @@ pmac_restart(char *cmd)
}
}
-static void __pmac
+static void
pmac_power_off(void)
{
#ifdef CONFIG_ADB_CUDA
@@ -561,7 +561,7 @@ pmac_power_off(void)
}
}
-static void __pmac
+static void
pmac_halt(void)
{
pmac_power_off();
@@ -661,7 +661,6 @@ pmac_init(unsigned long r3, unsigned long r4, unsigned long r5,
ppc_md.setup_arch = pmac_setup_arch;
ppc_md.show_cpuinfo = pmac_show_cpuinfo;
ppc_md.show_percpuinfo = pmac_show_percpuinfo;
- ppc_md.irq_canonicalize = NULL;
ppc_md.init_IRQ = pmac_pic_init;
ppc_md.get_irq = pmac_get_irq; /* Changed later on ... */
diff --git a/arch/ppc/platforms/pmac_sleep.S b/arch/ppc/platforms/pmac_sleep.S
index 88419c77ac43..22b113d19b24 100644
--- a/arch/ppc/platforms/pmac_sleep.S
+++ b/arch/ppc/platforms/pmac_sleep.S
@@ -387,10 +387,10 @@ turn_on_mmu:
#endif /* defined(CONFIG_PM) || defined(CONFIG_CPU_FREQ) */
.section .data
- .balign L1_CACHE_LINE_SIZE
+ .balign L1_CACHE_BYTES
sleep_storage:
.long 0
- .balign L1_CACHE_LINE_SIZE, 0
+ .balign L1_CACHE_BYTES, 0
#endif /* CONFIG_6xx */
.section .text
diff --git a/arch/ppc/platforms/pmac_smp.c b/arch/ppc/platforms/pmac_smp.c
index 794a23994b82..26ff26238f03 100644
--- a/arch/ppc/platforms/pmac_smp.c
+++ b/arch/ppc/platforms/pmac_smp.c
@@ -186,7 +186,7 @@ static inline void psurge_clr_ipi(int cpu)
*/
static unsigned long psurge_smp_message[NR_CPUS];
-void __pmac psurge_smp_message_recv(struct pt_regs *regs)
+void psurge_smp_message_recv(struct pt_regs *regs)
{
int cpu = smp_processor_id();
int msg;
@@ -203,14 +203,13 @@ void __pmac psurge_smp_message_recv(struct pt_regs *regs)
smp_message_recv(msg, regs);
}
-irqreturn_t __pmac psurge_primary_intr(int irq, void *d, struct pt_regs *regs)
+irqreturn_t psurge_primary_intr(int irq, void *d, struct pt_regs *regs)
{
psurge_smp_message_recv(regs);
return IRQ_HANDLED;
}
-static void __pmac smp_psurge_message_pass(int target, int msg, unsigned long data,
- int wait)
+static void smp_psurge_message_pass(int target, int msg)
{
int i;
@@ -629,7 +628,7 @@ void smp_core99_give_timebase(void)
/* PowerSurge-style Macs */
-struct smp_ops_t psurge_smp_ops __pmacdata = {
+struct smp_ops_t psurge_smp_ops = {
.message_pass = smp_psurge_message_pass,
.probe = smp_psurge_probe,
.kick_cpu = smp_psurge_kick_cpu,
@@ -639,7 +638,7 @@ struct smp_ops_t psurge_smp_ops __pmacdata = {
};
/* Core99 Macs (dual G4s) */
-struct smp_ops_t core99_smp_ops __pmacdata = {
+struct smp_ops_t core99_smp_ops = {
.message_pass = smp_openpic_message_pass,
.probe = smp_core99_probe,
.kick_cpu = smp_core99_kick_cpu,
diff --git a/arch/ppc/platforms/pmac_time.c b/arch/ppc/platforms/pmac_time.c
index efb819f9490d..edb9fcc64790 100644
--- a/arch/ppc/platforms/pmac_time.c
+++ b/arch/ppc/platforms/pmac_time.c
@@ -77,7 +77,7 @@ pmac_time_init(void)
#endif
}
-unsigned long __pmac
+unsigned long
pmac_get_rtc_time(void)
{
#if defined(CONFIG_ADB_CUDA) || defined(CONFIG_ADB_PMU)
@@ -118,7 +118,7 @@ pmac_get_rtc_time(void)
return 0;
}
-int __pmac
+int
pmac_set_rtc_time(unsigned long nowtime)
{
#if defined(CONFIG_ADB_CUDA) || defined(CONFIG_ADB_PMU)
@@ -210,7 +210,7 @@ via_calibrate_decr(void)
/*
* Reset the time after a sleep.
*/
-static int __pmac
+static int
time_sleep_notify(struct pmu_sleep_notifier *self, int when)
{
static unsigned long time_diff;
@@ -235,7 +235,7 @@ time_sleep_notify(struct pmu_sleep_notifier *self, int when)
return PBOOK_SLEEP_OK;
}
-static struct pmu_sleep_notifier time_sleep_notifier __pmacdata = {
+static struct pmu_sleep_notifier time_sleep_notifier = {
time_sleep_notify, SLEEP_LEVEL_MISC,
};
#endif /* CONFIG_PM */
diff --git a/arch/ppc/platforms/pplus.c b/arch/ppc/platforms/pplus.c
index e70aae20d6f9..22bd40cfb092 100644
--- a/arch/ppc/platforms/pplus.c
+++ b/arch/ppc/platforms/pplus.c
@@ -646,14 +646,6 @@ static void pplus_power_off(void)
pplus_halt();
}
-static unsigned int pplus_irq_canonicalize(u_int irq)
-{
- if (irq == 2)
- return 9;
- else
- return irq;
-}
-
static void __init pplus_init_IRQ(void)
{
int i;
@@ -673,10 +665,7 @@ static void __init pplus_init_IRQ(void)
ppc_md.get_irq = openpic_get_irq;
}
- for (i = 0; i < NUM_8259_INTERRUPTS; i++)
- irq_desc[i].handler = &i8259_pic;
-
- i8259_init(0);
+ i8259_init(0, 0);
if (ppc_md.progress)
ppc_md.progress("init_irq: exit", 0);
@@ -872,10 +861,10 @@ platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
ISA_DMA_THRESHOLD = 0x00ffffff;
DMA_MODE_READ = 0x44;
DMA_MODE_WRITE = 0x48;
+ ppc_do_canonicalize_irqs = 1;
ppc_md.setup_arch = pplus_setup_arch;
ppc_md.show_cpuinfo = pplus_show_cpuinfo;
- ppc_md.irq_canonicalize = pplus_irq_canonicalize;
ppc_md.init_IRQ = pplus_init_IRQ;
/* this gets changed later on if we have an OpenPIC -- Cort */
ppc_md.get_irq = i8259_irq;
@@ -911,6 +900,6 @@ platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
ppc_md.kgdb_map_scc = gen550_kgdb_map_scc;
#endif
#ifdef CONFIG_SMP
- ppc_md.smp_ops = &pplus_smp_ops;
+ smp_ops = &pplus_smp_ops;
#endif /* CONFIG_SMP */
}
diff --git a/arch/ppc/platforms/prep_pci.c b/arch/ppc/platforms/prep_pci.c
index 4760cb64251d..e50b9996848c 100644
--- a/arch/ppc/platforms/prep_pci.c
+++ b/arch/ppc/platforms/prep_pci.c
@@ -43,7 +43,7 @@ static unsigned long *ProcInfo;
/* Tables for known hardware */
/* Motorola PowerStackII - Utah */
-static char Utah_pci_IRQ_map[23] __prepdata =
+static char Utah_pci_IRQ_map[23] =
{
0, /* Slot 0 - unused */
0, /* Slot 1 - unused */
@@ -72,7 +72,7 @@ static char Utah_pci_IRQ_map[23] __prepdata =
0, /* Slot 22 - unused */
};
-static char Utah_pci_IRQ_routes[] __prepdata =
+static char Utah_pci_IRQ_routes[] =
{
0, /* Line 0 - Unused */
9, /* Line 1 */
@@ -84,7 +84,7 @@ static char Utah_pci_IRQ_routes[] __prepdata =
/* Motorola PowerStackII - Omaha */
/* no integrated SCSI or ethernet */
-static char Omaha_pci_IRQ_map[23] __prepdata =
+static char Omaha_pci_IRQ_map[23] =
{
0, /* Slot 0 - unused */
0, /* Slot 1 - unused */
@@ -111,7 +111,7 @@ static char Omaha_pci_IRQ_map[23] __prepdata =
0,
};
-static char Omaha_pci_IRQ_routes[] __prepdata =
+static char Omaha_pci_IRQ_routes[] =
{
0, /* Line 0 - Unused */
9, /* Line 1 */
@@ -121,7 +121,7 @@ static char Omaha_pci_IRQ_routes[] __prepdata =
};
/* Motorola PowerStack */
-static char Blackhawk_pci_IRQ_map[19] __prepdata =
+static char Blackhawk_pci_IRQ_map[19] =
{
0, /* Slot 0 - unused */
0, /* Slot 1 - unused */
@@ -144,7 +144,7 @@ static char Blackhawk_pci_IRQ_map[19] __prepdata =
3, /* Slot P5 */
};
-static char Blackhawk_pci_IRQ_routes[] __prepdata =
+static char Blackhawk_pci_IRQ_routes[] =
{
0, /* Line 0 - Unused */
9, /* Line 1 */
@@ -154,7 +154,7 @@ static char Blackhawk_pci_IRQ_routes[] __prepdata =
};
/* Motorola Mesquite */
-static char Mesquite_pci_IRQ_map[23] __prepdata =
+static char Mesquite_pci_IRQ_map[23] =
{
0, /* Slot 0 - unused */
0, /* Slot 1 - unused */
@@ -182,7 +182,7 @@ static char Mesquite_pci_IRQ_map[23] __prepdata =
};
/* Motorola Sitka */
-static char Sitka_pci_IRQ_map[21] __prepdata =
+static char Sitka_pci_IRQ_map[21] =
{
0, /* Slot 0 - unused */
0, /* Slot 1 - unused */
@@ -208,7 +208,7 @@ static char Sitka_pci_IRQ_map[21] __prepdata =
};
/* Motorola MTX */
-static char MTX_pci_IRQ_map[23] __prepdata =
+static char MTX_pci_IRQ_map[23] =
{
0, /* Slot 0 - unused */
0, /* Slot 1 - unused */
@@ -237,7 +237,7 @@ static char MTX_pci_IRQ_map[23] __prepdata =
/* Motorola MTX Plus */
/* Secondary bus interrupt routing is not supported yet */
-static char MTXplus_pci_IRQ_map[23] __prepdata =
+static char MTXplus_pci_IRQ_map[23] =
{
0, /* Slot 0 - unused */
0, /* Slot 1 - unused */
@@ -264,13 +264,13 @@ static char MTXplus_pci_IRQ_map[23] __prepdata =
0, /* Slot 22 - unused */
};
-static char Raven_pci_IRQ_routes[] __prepdata =
+static char Raven_pci_IRQ_routes[] =
{
0, /* This is a dummy structure */
};
/* Motorola MVME16xx */
-static char Genesis_pci_IRQ_map[16] __prepdata =
+static char Genesis_pci_IRQ_map[16] =
{
0, /* Slot 0 - unused */
0, /* Slot 1 - unused */
@@ -290,7 +290,7 @@ static char Genesis_pci_IRQ_map[16] __prepdata =
0, /* Slot 15 - unused */
};
-static char Genesis_pci_IRQ_routes[] __prepdata =
+static char Genesis_pci_IRQ_routes[] =
{
0, /* Line 0 - Unused */
10, /* Line 1 */
@@ -299,7 +299,7 @@ static char Genesis_pci_IRQ_routes[] __prepdata =
15 /* Line 4 */
};
-static char Genesis2_pci_IRQ_map[23] __prepdata =
+static char Genesis2_pci_IRQ_map[23] =
{
0, /* Slot 0 - unused */
0, /* Slot 1 - unused */
@@ -327,7 +327,7 @@ static char Genesis2_pci_IRQ_map[23] __prepdata =
};
/* Motorola Series-E */
-static char Comet_pci_IRQ_map[23] __prepdata =
+static char Comet_pci_IRQ_map[23] =
{
0, /* Slot 0 - unused */
0, /* Slot 1 - unused */
@@ -354,7 +354,7 @@ static char Comet_pci_IRQ_map[23] __prepdata =
0,
};
-static char Comet_pci_IRQ_routes[] __prepdata =
+static char Comet_pci_IRQ_routes[] =
{
0, /* Line 0 - Unused */
10, /* Line 1 */
@@ -364,7 +364,7 @@ static char Comet_pci_IRQ_routes[] __prepdata =
};
/* Motorola Series-EX */
-static char Comet2_pci_IRQ_map[23] __prepdata =
+static char Comet2_pci_IRQ_map[23] =
{
0, /* Slot 0 - unused */
0, /* Slot 1 - unused */
@@ -391,7 +391,7 @@ static char Comet2_pci_IRQ_map[23] __prepdata =
0,
};
-static char Comet2_pci_IRQ_routes[] __prepdata =
+static char Comet2_pci_IRQ_routes[] =
{
0, /* Line 0 - Unused */
10, /* Line 1 */
@@ -405,7 +405,7 @@ static char Comet2_pci_IRQ_routes[] __prepdata =
* This is actually based on the Carolina motherboard
* -- Cort
*/
-static char ibm8xx_pci_IRQ_map[23] __prepdata = {
+static char ibm8xx_pci_IRQ_map[23] = {
0, /* Slot 0 - unused */
0, /* Slot 1 - unused */
0, /* Slot 2 - unused */
@@ -431,7 +431,7 @@ static char ibm8xx_pci_IRQ_map[23] __prepdata = {
2, /* Slot 22 - PCI slot 1 PCIINTx# (See below) */
};
-static char ibm8xx_pci_IRQ_routes[] __prepdata = {
+static char ibm8xx_pci_IRQ_routes[] = {
0, /* Line 0 - unused */
15, /* Line 1 */
15, /* Line 2 */
@@ -443,7 +443,7 @@ static char ibm8xx_pci_IRQ_routes[] __prepdata = {
* a 6015 ibm board
* -- Cort
*/
-static char ibm6015_pci_IRQ_map[23] __prepdata = {
+static char ibm6015_pci_IRQ_map[23] = {
0, /* Slot 0 - unused */
0, /* Slot 1 - unused */
0, /* Slot 2 - unused */
@@ -469,7 +469,7 @@ static char ibm6015_pci_IRQ_map[23] __prepdata = {
2, /* Slot 22 - */
};
-static char ibm6015_pci_IRQ_routes[] __prepdata = {
+static char ibm6015_pci_IRQ_routes[] = {
0, /* Line 0 - unused */
13, /* Line 1 */
15, /* Line 2 */
@@ -479,7 +479,7 @@ static char ibm6015_pci_IRQ_routes[] __prepdata = {
/* IBM Nobis and Thinkpad 850 */
-static char Nobis_pci_IRQ_map[23] __prepdata ={
+static char Nobis_pci_IRQ_map[23] ={
0, /* Slot 0 - unused */
0, /* Slot 1 - unused */
0, /* Slot 2 - unused */
@@ -498,7 +498,7 @@ static char Nobis_pci_IRQ_map[23] __prepdata ={
0, /* Slot 15 - unused */
};
-static char Nobis_pci_IRQ_routes[] __prepdata = {
+static char Nobis_pci_IRQ_routes[] = {
0, /* Line 0 - Unused */
13, /* Line 1 */
13, /* Line 2 */
@@ -510,7 +510,7 @@ static char Nobis_pci_IRQ_routes[] __prepdata = {
* IBM RS/6000 43p/140 -- paulus
* XXX we should get all this from the residual data
*/
-static char ibm43p_pci_IRQ_map[23] __prepdata = {
+static char ibm43p_pci_IRQ_map[23] = {
0, /* Slot 0 - unused */
0, /* Slot 1 - unused */
0, /* Slot 2 - unused */
@@ -536,7 +536,7 @@ static char ibm43p_pci_IRQ_map[23] __prepdata = {
1, /* Slot 22 - PCI slot 1 PCIINTx# (See below) */
};
-static char ibm43p_pci_IRQ_routes[] __prepdata = {
+static char ibm43p_pci_IRQ_routes[] = {
0, /* Line 0 - unused */
15, /* Line 1 */
15, /* Line 2 */
@@ -559,7 +559,7 @@ struct powerplus_irq_list
* are routed to OpenPIC inputs 5-8. These values are offset by
* 16 in the table to reflect the Linux kernel interrupt value.
*/
-struct powerplus_irq_list Powerplus_pci_IRQ_list __prepdata =
+struct powerplus_irq_list Powerplus_pci_IRQ_list =
{
{25, 26, 27, 28},
{21, 22, 23, 24}
@@ -572,7 +572,7 @@ struct powerplus_irq_list Powerplus_pci_IRQ_list __prepdata =
* are routed to OpenPIC inputs 12-15. These values are offset by
* 16 in the table to reflect the Linux kernel interrupt value.
*/
-struct powerplus_irq_list Mesquite_pci_IRQ_list __prepdata =
+struct powerplus_irq_list Mesquite_pci_IRQ_list =
{
{24, 25, 26, 27},
{28, 29, 30, 31}
@@ -582,7 +582,7 @@ struct powerplus_irq_list Mesquite_pci_IRQ_list __prepdata =
* This table represents the standard PCI swizzle defined in the
* PCI bus specification.
*/
-static unsigned char prep_pci_intpins[4][4] __prepdata =
+static unsigned char prep_pci_intpins[4][4] =
{
{ 1, 2, 3, 4}, /* Buses 0, 4, 8, ... */
{ 2, 3, 4, 1}, /* Buses 1, 5, 9, ... */
@@ -622,7 +622,7 @@ static unsigned char prep_pci_intpins[4][4] __prepdata =
#define MIN_DEVNR 11
#define MAX_DEVNR 22
-static int __prep
+static int
prep_read_config(struct pci_bus *bus, unsigned int devfn, int offset,
int len, u32 *val)
{
@@ -652,7 +652,7 @@ prep_read_config(struct pci_bus *bus, unsigned int devfn, int offset,
return PCIBIOS_SUCCESSFUL;
}
-static int __prep
+static int
prep_write_config(struct pci_bus *bus, unsigned int devfn, int offset,
int len, u32 val)
{
@@ -804,7 +804,7 @@ struct mot_info {
void (*map_non0_bus)(struct pci_dev *); /* For boards with more than bus 0 devices. */
struct powerplus_irq_list *pci_irq_list; /* List of PCI MPIC inputs */
unsigned char secondary_bridge_devfn; /* devfn of secondary bus transparent bridge */
-} mot_info[] __prepdata = {
+} mot_info[] = {
{0x300, 0x00, 0x00, "MVME 2400", Genesis2_pci_IRQ_map, Raven_pci_IRQ_routes, Powerplus_Map_Non0, &Powerplus_pci_IRQ_list, 0xFF},
{0x010, 0x00, 0x00, "Genesis", Genesis_pci_IRQ_map, Genesis_pci_IRQ_routes, Powerplus_Map_Non0, &Powerplus_pci_IRQ_list, 0x00},
{0x020, 0x00, 0x00, "Powerstack (Series E)", Comet_pci_IRQ_map, Comet_pci_IRQ_routes, NULL, NULL, 0x00},
diff --git a/arch/ppc/platforms/prep_setup.c b/arch/ppc/platforms/prep_setup.c
index bc926be95472..4415748071dc 100644
--- a/arch/ppc/platforms/prep_setup.c
+++ b/arch/ppc/platforms/prep_setup.c
@@ -61,6 +61,15 @@
#include <asm/pci-bridge.h>
#include <asm/todc.h>
+/* prep registers for L2 */
+#define CACHECRBA 0x80000823 /* Cache configuration register address */
+#define L2CACHE_MASK 0x03 /* Mask for 2 L2 Cache bits */
+#define L2CACHE_512KB 0x00 /* 512KB */
+#define L2CACHE_256KB 0x01 /* 256KB */
+#define L2CACHE_1MB 0x02 /* 1MB */
+#define L2CACHE_NONE 0x03 /* NONE */
+#define L2CACHE_PARITY 0x08 /* Mask for L2 Cache Parity Protected bit */
+
TODC_ALLOC();
unsigned char ucSystemType;
@@ -89,9 +98,6 @@ extern void prep_tiger1_setup_pci(char *irq_edge_mask_lo, char *irq_edge_mask_hi
#define cached_21 (((char *)(ppc_cached_irq_mask))[3])
#define cached_A1 (((char *)(ppc_cached_irq_mask))[2])
-/* for the mac fs */
-dev_t boot_dev;
-
#ifdef CONFIG_SOUND_CS4232
long ppc_cs4232_dma, ppc_cs4232_dma2;
#endif
@@ -173,7 +179,7 @@ prep_carolina_enable_l2(void)
}
/* cpuinfo code common to all IBM PReP */
-static void __prep
+static void
prep_ibm_cpuinfo(struct seq_file *m)
{
unsigned int equip_reg = inb(PREP_IBM_EQUIPMENT);
@@ -209,14 +215,14 @@ prep_ibm_cpuinfo(struct seq_file *m)
}
}
-static int __prep
+static int
prep_gen_cpuinfo(struct seq_file *m)
{
prep_ibm_cpuinfo(m);
return 0;
}
-static int __prep
+static int
prep_sandalfoot_cpuinfo(struct seq_file *m)
{
unsigned int equip_reg = inb(PREP_IBM_EQUIPMENT);
@@ -243,7 +249,7 @@ prep_sandalfoot_cpuinfo(struct seq_file *m)
return 0;
}
-static int __prep
+static int
prep_thinkpad_cpuinfo(struct seq_file *m)
{
unsigned int equip_reg = inb(PREP_IBM_EQUIPMENT);
@@ -314,7 +320,7 @@ prep_thinkpad_cpuinfo(struct seq_file *m)
return 0;
}
-static int __prep
+static int
prep_carolina_cpuinfo(struct seq_file *m)
{
unsigned int equip_reg = inb(PREP_IBM_EQUIPMENT);
@@ -350,7 +356,7 @@ prep_carolina_cpuinfo(struct seq_file *m)
return 0;
}
-static int __prep
+static int
prep_tiger1_cpuinfo(struct seq_file *m)
{
unsigned int l2_reg = inb(PREP_IBM_L2INFO);
@@ -393,7 +399,7 @@ prep_tiger1_cpuinfo(struct seq_file *m)
/* Used by all Motorola PReP */
-static int __prep
+static int
prep_mot_cpuinfo(struct seq_file *m)
{
unsigned int cachew = *((unsigned char *)CACHECRBA);
@@ -454,7 +460,7 @@ no_l2:
return 0;
}
-static void __prep
+static void
prep_restart(char *cmd)
{
#define PREP_SP92 0x92 /* Special Port 92 */
@@ -473,7 +479,7 @@ prep_restart(char *cmd)
#undef PREP_SP92
}
-static void __prep
+static void
prep_halt(void)
{
local_irq_disable(); /* no interrupts */
@@ -488,7 +494,7 @@ prep_halt(void)
/* Carrera is the power manager in the Thinkpads. Unfortunately not much is
* known about it, so we can't power down.
*/
-static void __prep
+static void
prep_carrera_poweroff(void)
{
prep_halt();
@@ -501,7 +507,7 @@ prep_carrera_poweroff(void)
* somewhat in the IBM Carolina Technical Specification.
* -Hollis
*/
-static void __prep
+static void
utah_sig87c750_setbit(unsigned int bytenum, unsigned int bitnum, int value)
{
/*
@@ -539,7 +545,7 @@ utah_sig87c750_setbit(unsigned int bytenum, unsigned int bitnum, int value)
udelay(100); /* important: let controller recover */
}
-static void __prep
+static void
prep_sig750_poweroff(void)
{
/* tweak the power manager found in most IBM PRePs (except Thinkpads) */
@@ -554,7 +560,7 @@ prep_sig750_poweroff(void)
/* not reached */
}
-static int __prep
+static int
prep_show_percpuinfo(struct seq_file *m, int i)
{
/* PREP's without residual data will give incorrect values here */
@@ -700,12 +706,12 @@ prep_set_bat(void)
/*
* IBM 3-digit status LED
*/
-static unsigned int ibm_statusled_base __prepdata;
+static unsigned int ibm_statusled_base;
-static void __prep
+static void
ibm_statusled_progress(char *s, unsigned short hex);
-static int __prep
+static int
ibm_statusled_panic(struct notifier_block *dummy1, unsigned long dummy2,
void * dummy3)
{
@@ -713,13 +719,13 @@ ibm_statusled_panic(struct notifier_block *dummy1, unsigned long dummy2,
return NOTIFY_DONE;
}
-static struct notifier_block ibm_statusled_block __prepdata = {
+static struct notifier_block ibm_statusled_block = {
ibm_statusled_panic,
NULL,
INT_MAX /* try to do it first */
};
-static void __prep
+static void
ibm_statusled_progress(char *s, unsigned short hex)
{
static int notifier_installed;
@@ -945,19 +951,6 @@ prep_calibrate_decr(void)
todc_calibrate_decr();
}
-static unsigned int __prep
-prep_irq_canonicalize(u_int irq)
-{
- if (irq == 2)
- {
- return 9;
- }
- else
- {
- return irq;
- }
-}
-
static void __init
prep_init_IRQ(void)
{
@@ -970,11 +963,9 @@ prep_init_IRQ(void)
openpic_hookup_cascade(NUM_8259_INTERRUPTS, "82c59 cascade",
i8259_irq);
}
- for ( i = 0 ; i < NUM_8259_INTERRUPTS ; i++ )
- irq_desc[i].handler = &i8259_pic;
if (have_residual_data) {
- i8259_init(residual_isapic_addr());
+ i8259_init(residual_isapic_addr(), 0);
return;
}
@@ -985,18 +976,18 @@ prep_init_IRQ(void)
if (((pci_viddid & 0xffff) == PCI_VENDOR_ID_MOTOROLA)
&& ((pci_did == PCI_DEVICE_ID_MOTOROLA_RAVEN)
|| (pci_did == PCI_DEVICE_ID_MOTOROLA_HAWK)))
- i8259_init(0);
+ i8259_init(0, 0);
else
/* PCI interrupt ack address given in section 6.1.8 of the
* PReP specification. */
- i8259_init(MPC10X_MAPA_PCI_INTACK_ADDR);
+ i8259_init(MPC10X_MAPA_PCI_INTACK_ADDR, 0);
}
#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
/*
* IDE stuff.
*/
-static int __prep
+static int
prep_ide_default_irq(unsigned long base)
{
switch (base) {
@@ -1010,7 +1001,7 @@ prep_ide_default_irq(unsigned long base)
}
}
-static unsigned long __prep
+static unsigned long
prep_ide_default_io_base(int index)
{
switch (index) {
@@ -1055,7 +1046,7 @@ smp_prep_setup_cpu(int cpu_nr)
do_openpic_setup_cpu();
}
-static struct smp_ops_t prep_smp_ops __prepdata = {
+static struct smp_ops_t prep_smp_ops = {
smp_openpic_message_pass,
smp_prep_probe,
smp_prep_kick_cpu,
@@ -1113,6 +1104,7 @@ prep_init(unsigned long r3, unsigned long r4, unsigned long r5,
ISA_DMA_THRESHOLD = 0x00ffffff;
DMA_MODE_READ = 0x44;
DMA_MODE_WRITE = 0x48;
+ ppc_do_canonicalize_irqs = 1;
/* figure out what kind of prep workstation we are */
if (have_residual_data) {
@@ -1139,7 +1131,6 @@ prep_init(unsigned long r3, unsigned long r4, unsigned long r5,
ppc_md.setup_arch = prep_setup_arch;
ppc_md.show_percpuinfo = prep_show_percpuinfo;
ppc_md.show_cpuinfo = NULL; /* set in prep_setup_arch() */
- ppc_md.irq_canonicalize = prep_irq_canonicalize;
ppc_md.init_IRQ = prep_init_IRQ;
/* this gets changed later on if we have an OpenPIC -- Cort */
ppc_md.get_irq = i8259_irq;
@@ -1176,6 +1167,6 @@ prep_init(unsigned long r3, unsigned long r4, unsigned long r5,
#endif
#ifdef CONFIG_SMP
- ppc_md.smp_ops = &prep_smp_ops;
+ smp_ops = &prep_smp_ops;
#endif /* CONFIG_SMP */
}
diff --git a/arch/ppc/platforms/radstone_ppc7d.c b/arch/ppc/platforms/radstone_ppc7d.c
index 0376c8cff5d1..708b8739ecdd 100644
--- a/arch/ppc/platforms/radstone_ppc7d.c
+++ b/arch/ppc/platforms/radstone_ppc7d.c
@@ -40,6 +40,7 @@
#include <linux/serial_core.h>
#include <linux/mv643xx.h>
#include <linux/netdevice.h>
+#include <linux/platform_device.h>
#include <asm/system.h>
#include <asm/pgtable.h>
@@ -514,13 +515,9 @@ static void __init ppc7d_init_irq(void)
int irq;
pr_debug("%s\n", __FUNCTION__);
- i8259_init(0);
+ i8259_init(0, 0);
mv64360_init_irq();
- /* IRQ 0..15 are handled by the cascaded 8259's of the Ali1535 */
- for (irq = 0; irq < 16; irq++) {
- irq_desc[irq].handler = &i8259_pic;
- }
/* IRQs 5,6,9,10,11,14,15 are level sensitive */
irq_desc[5].status |= IRQ_LEVEL;
irq_desc[6].status |= IRQ_LEVEL;
@@ -1183,18 +1180,18 @@ static void __init ppc7d_setup_arch(void)
ROOT_DEV = Root_HDA1;
#endif
- if ((cur_cpu_spec[0]->cpu_features & CPU_FTR_SPEC7450) ||
- (cur_cpu_spec[0]->cpu_features & CPU_FTR_L3CR))
+ if ((cur_cpu_spec->cpu_features & CPU_FTR_SPEC7450) ||
+ (cur_cpu_spec->cpu_features & CPU_FTR_L3CR))
/* 745x is different. We only want to pass along enable. */
_set_L2CR(L2CR_L2E);
- else if (cur_cpu_spec[0]->cpu_features & CPU_FTR_L2CR)
+ else if (cur_cpu_spec->cpu_features & CPU_FTR_L2CR)
/* All modules have 1MB of L2. We also assume that an
* L2 divisor of 3 will work.
*/
_set_L2CR(L2CR_L2E | L2CR_L2SIZ_1MB | L2CR_L2CLK_DIV3
| L2CR_L2RAM_PIPE | L2CR_L2OH_1_0 | L2CR_L2DF);
- if (cur_cpu_spec[0]->cpu_features & CPU_FTR_L3CR)
+ if (cur_cpu_spec->cpu_features & CPU_FTR_L3CR)
/* No L3 cache */
_set_L3CR(0);
@@ -1424,6 +1421,7 @@ void __init platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
ppc_md.setup_arch = ppc7d_setup_arch;
ppc_md.init = ppc7d_init2;
ppc_md.show_cpuinfo = ppc7d_show_cpuinfo;
+ /* XXX this is broken... */
ppc_md.irq_canonicalize = ppc7d_irq_canonicalize;
ppc_md.init_IRQ = ppc7d_init_irq;
ppc_md.get_irq = ppc7d_get_irq;
diff --git a/arch/ppc/platforms/residual.c b/arch/ppc/platforms/residual.c
index 0f84ca603612..c9911601cfdf 100644
--- a/arch/ppc/platforms/residual.c
+++ b/arch/ppc/platforms/residual.c
@@ -47,7 +47,7 @@
#include <asm/ide.h>
-unsigned char __res[sizeof(RESIDUAL)] __prepdata = {0,};
+unsigned char __res[sizeof(RESIDUAL)] = {0,};
RESIDUAL *res = (RESIDUAL *)&__res;
char * PnP_BASE_TYPES[] __initdata = {
diff --git a/arch/ppc/platforms/sandpoint.c b/arch/ppc/platforms/sandpoint.c
index 5232283c1974..9eeed3572309 100644
--- a/arch/ppc/platforms/sandpoint.c
+++ b/arch/ppc/platforms/sandpoint.c
@@ -494,27 +494,10 @@ sandpoint_init_IRQ(void)
i8259_irq);
/*
- * openpic_init() has set up irq_desc[16-31] to be openpic
- * interrupts. We need to set irq_desc[0-15] to be i8259
- * interrupts.
- */
- for(i=0; i < NUM_8259_INTERRUPTS; i++)
- irq_desc[i].handler = &i8259_pic;
-
- /*
* The EPIC allows for a read in the range of 0xFEF00000 ->
* 0xFEFFFFFF to generate a PCI interrupt-acknowledge transaction.
*/
- i8259_init(0xfef00000);
-}
-
-static u32
-sandpoint_irq_canonicalize(u32 irq)
-{
- if (irq == 2)
- return 9;
- else
- return irq;
+ i8259_init(0xfef00000, 0);
}
static unsigned long __init
@@ -727,10 +710,10 @@ platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
ISA_DMA_THRESHOLD = 0x00ffffff;
DMA_MODE_READ = 0x44;
DMA_MODE_WRITE = 0x48;
+ ppc_do_canonicalize_irqs = 1;
ppc_md.setup_arch = sandpoint_setup_arch;
ppc_md.show_cpuinfo = sandpoint_show_cpuinfo;
- ppc_md.irq_canonicalize = sandpoint_irq_canonicalize;
ppc_md.init_IRQ = sandpoint_init_IRQ;
ppc_md.get_irq = openpic_get_irq;
diff --git a/arch/ppc/syslib/Makefile b/arch/ppc/syslib/Makefile
index b8d08f33f7ee..5b7f2b80e56e 100644
--- a/arch/ppc/syslib/Makefile
+++ b/arch/ppc/syslib/Makefile
@@ -15,6 +15,7 @@ obj-$(CONFIG_440EP) += ibm440gx_common.o
obj-$(CONFIG_440GP) += ibm440gp_common.o
obj-$(CONFIG_440GX) += ibm440gx_common.o
obj-$(CONFIG_440SP) += ibm440gx_common.o ibm440sp_common.o
+obj-$(CONFIG_440SPE) += ibm440gx_common.o ibm440sp_common.o ppc440spe_pcie.o
ifeq ($(CONFIG_4xx),y)
ifeq ($(CONFIG_VIRTEX_II_PRO),y)
obj-$(CONFIG_40x) += xilinx_pic.o
@@ -31,52 +32,51 @@ obj-$(CONFIG_GEN_RTC) += todc_time.o
obj-$(CONFIG_PPC4xx_DMA) += ppc4xx_dma.o
obj-$(CONFIG_PPC4xx_EDMA) += ppc4xx_sgdma.o
ifeq ($(CONFIG_40x),y)
-obj-$(CONFIG_PCI) += indirect_pci.o pci_auto.o ppc405_pci.o
+obj-$(CONFIG_PCI) += pci_auto.o ppc405_pci.o
endif
endif
obj-$(CONFIG_8xx) += m8xx_setup.o ppc8xx_pic.o $(wdt-mpc8xx-y) \
ppc_sys.o mpc8xx_devices.o mpc8xx_sys.o
-ifeq ($(CONFIG_8xx),y)
-obj-$(CONFIG_PCI) += qspan_pci.o i8259.o
-endif
-obj-$(CONFIG_PPC_OF) += prom_init.o prom.o of_device.o
-obj-$(CONFIG_PPC_PMAC) += open_pic.o indirect_pci.o
+obj-$(CONFIG_PCI_QSPAN) += qspan_pci.o
+obj-$(CONFIG_PPC_OF) += prom_init.o prom.o
+obj-$(CONFIG_PPC_PMAC) += open_pic.o
obj-$(CONFIG_POWER4) += open_pic2.o
-obj-$(CONFIG_PPC_CHRP) += open_pic.o indirect_pci.o i8259.o
-obj-$(CONFIG_PPC_PREP) += open_pic.o indirect_pci.o i8259.o todc_time.o
-obj-$(CONFIG_BAMBOO) += indirect_pci.o pci_auto.o todc_time.o
+obj-$(CONFIG_PPC_CHRP) += open_pic.o
+obj-$(CONFIG_PPC_PREP) += open_pic.o todc_time.o
+obj-$(CONFIG_BAMBOO) += pci_auto.o todc_time.o
obj-$(CONFIG_CPCI690) += todc_time.o pci_auto.o
-obj-$(CONFIG_EBONY) += indirect_pci.o pci_auto.o todc_time.o
+obj-$(CONFIG_EBONY) += pci_auto.o todc_time.o
obj-$(CONFIG_EV64260) += todc_time.o pci_auto.o
+obj-$(CONFIG_EV64360) += todc_time.o
obj-$(CONFIG_CHESTNUT) += mv64360_pic.o pci_auto.o
-obj-$(CONFIG_GEMINI) += open_pic.o indirect_pci.o
+obj-$(CONFIG_GEMINI) += open_pic.o
obj-$(CONFIG_GT64260) += gt64260_pic.o
-obj-$(CONFIG_LOPEC) += i8259.o pci_auto.o todc_time.o
+obj-$(CONFIG_LOPEC) += pci_auto.o todc_time.o
obj-$(CONFIG_HDPU) += pci_auto.o
-obj-$(CONFIG_LUAN) += indirect_pci.o pci_auto.o todc_time.o
+obj-$(CONFIG_LUAN) += pci_auto.o todc_time.o
+obj-$(CONFIG_YUCCA) += pci_auto.o todc_time.o
obj-$(CONFIG_KATANA) += pci_auto.o
obj-$(CONFIG_MV64360) += mv64360_pic.o
-obj-$(CONFIG_MV64X60) += mv64x60.o mv64x60_win.o indirect_pci.o
-obj-$(CONFIG_MVME5100) += open_pic.o todc_time.o indirect_pci.o \
+obj-$(CONFIG_MV64X60) += mv64x60.o mv64x60_win.o
+obj-$(CONFIG_MVME5100) += open_pic.o todc_time.o \
pci_auto.o hawk_common.o
-obj-$(CONFIG_MVME5100_IPMC761_PRESENT) += i8259.o
-obj-$(CONFIG_OCOTEA) += indirect_pci.o pci_auto.o todc_time.o
+obj-$(CONFIG_OCOTEA) += pci_auto.o todc_time.o
obj-$(CONFIG_PAL4) += cpc700_pic.o
obj-$(CONFIG_POWERPMC250) += pci_auto.o
-obj-$(CONFIG_PPLUS) += hawk_common.o open_pic.o i8259.o \
- indirect_pci.o todc_time.o pci_auto.o
-obj-$(CONFIG_PRPMC750) += open_pic.o indirect_pci.o pci_auto.o \
+obj-$(CONFIG_PPLUS) += hawk_common.o open_pic.o \
+ todc_time.o pci_auto.o
+obj-$(CONFIG_PRPMC750) += open_pic.o pci_auto.o \
hawk_common.o
obj-$(CONFIG_HARRIER) += harrier.o
-obj-$(CONFIG_PRPMC800) += open_pic.o indirect_pci.o pci_auto.o
-obj-$(CONFIG_RADSTONE_PPC7D) += i8259.o pci_auto.o
-obj-$(CONFIG_SANDPOINT) += i8259.o pci_auto.o todc_time.o
+obj-$(CONFIG_PRPMC800) += open_pic.o pci_auto.o
+obj-$(CONFIG_RADSTONE_PPC7D) += pci_auto.o
+obj-$(CONFIG_SANDPOINT) += pci_auto.o todc_time.o
obj-$(CONFIG_SBC82xx) += todc_time.o
-obj-$(CONFIG_SPRUCE) += cpc700_pic.o indirect_pci.o pci_auto.o \
+obj-$(CONFIG_SPRUCE) += cpc700_pic.o pci_auto.o \
todc_time.o
obj-$(CONFIG_8260) += m8260_setup.o pq2_devices.o pq2_sys.o \
ppc_sys.o
-obj-$(CONFIG_PCI_8260) += m82xx_pci.o indirect_pci.o pci_auto.o
+obj-$(CONFIG_PCI_8260) += m82xx_pci.o pci_auto.o
obj-$(CONFIG_8260_PCI9) += m8260_pci_erratum9.o
obj-$(CONFIG_CPM2) += cpm2_common.o cpm2_pic.o
ifeq ($(CONFIG_PPC_GEN550),y)
@@ -87,20 +87,19 @@ ifeq ($(CONFIG_SERIAL_MPSC_CONSOLE),y)
obj-$(CONFIG_SERIAL_TEXT_DEBUG) += mv64x60_dbg.o
endif
obj-$(CONFIG_BOOTX_TEXT) += btext.o
-obj-$(CONFIG_MPC10X_BRIDGE) += mpc10x_common.o indirect_pci.o ppc_sys.o
+obj-$(CONFIG_MPC10X_BRIDGE) += mpc10x_common.o ppc_sys.o
obj-$(CONFIG_MPC10X_OPENPIC) += open_pic.o
-obj-$(CONFIG_40x) += dcr.o
-obj-$(CONFIG_BOOKE) += dcr.o
obj-$(CONFIG_85xx) += open_pic.o ppc85xx_common.o ppc85xx_setup.o \
- ppc_sys.o i8259.o mpc85xx_sys.o \
+ ppc_sys.o mpc85xx_sys.o \
mpc85xx_devices.o
ifeq ($(CONFIG_85xx),y)
-obj-$(CONFIG_PCI) += indirect_pci.o pci_auto.o
+obj-$(CONFIG_PCI) += pci_auto.o
endif
+obj-$(CONFIG_RAPIDIO) += ppc85xx_rio.o
obj-$(CONFIG_83xx) += ipic.o ppc83xx_setup.o ppc_sys.o \
mpc83xx_sys.o mpc83xx_devices.o
ifeq ($(CONFIG_83xx),y)
-obj-$(CONFIG_PCI) += indirect_pci.o pci_auto.o
+obj-$(CONFIG_PCI) += pci_auto.o
endif
obj-$(CONFIG_MPC8548_CDS) += todc_time.o
obj-$(CONFIG_MPC8555_CDS) += todc_time.o
diff --git a/arch/ppc/syslib/btext.c b/arch/ppc/syslib/btext.c
index 7734f6836174..12fa83e6774a 100644
--- a/arch/ppc/syslib/btext.c
+++ b/arch/ppc/syslib/btext.c
@@ -53,8 +53,8 @@ extern char *klimit;
* chrp only uses it during early boot.
*/
#ifdef CONFIG_XMON
-#define BTEXT __pmac
-#define BTDATA __pmacdata
+#define BTEXT
+#define BTDATA
#else
#define BTEXT __init
#define BTDATA __initdata
@@ -187,7 +187,7 @@ btext_setup_display(int width, int height, int depth, int pitch,
* changes.
*/
-void __openfirmware
+void
map_boot_text(void)
{
unsigned long base, offset, size;
diff --git a/arch/ppc/syslib/gt64260_pic.c b/arch/ppc/syslib/gt64260_pic.c
index 44aa87385451..f97b3a9abd1e 100644
--- a/arch/ppc/syslib/gt64260_pic.c
+++ b/arch/ppc/syslib/gt64260_pic.c
@@ -45,6 +45,7 @@
#include <asm/system.h>
#include <asm/irq.h>
#include <asm/mv64x60.h>
+#include <asm/machdep.h>
#define CPU_INTR_STR "gt64260 cpu interface error"
#define PCI0_INTR_STR "gt64260 pci 0 error"
diff --git a/arch/ppc/syslib/ibm440gx_common.c b/arch/ppc/syslib/ibm440gx_common.c
index 0bb919859b8b..c36db279b43d 100644
--- a/arch/ppc/syslib/ibm440gx_common.c
+++ b/arch/ppc/syslib/ibm440gx_common.c
@@ -236,9 +236,9 @@ void __init ibm440gx_l2c_setup(struct ibm44x_clocks* p)
/* Disable L2C on rev.A, rev.B and 800MHz version of rev.C,
enable it on all other revisions
*/
- if (strcmp(cur_cpu_spec[0]->cpu_name, "440GX Rev. A") == 0 ||
- strcmp(cur_cpu_spec[0]->cpu_name, "440GX Rev. B") == 0
- || (strcmp(cur_cpu_spec[0]->cpu_name, "440GX Rev. C")
+ if (strcmp(cur_cpu_spec->cpu_name, "440GX Rev. A") == 0 ||
+ strcmp(cur_cpu_spec->cpu_name, "440GX Rev. B") == 0
+ || (strcmp(cur_cpu_spec->cpu_name, "440GX Rev. C")
== 0 && p->cpu > 667000000))
ibm440gx_l2c_disable();
else
diff --git a/arch/ppc/syslib/ibm440sp_common.c b/arch/ppc/syslib/ibm440sp_common.c
index 417d4cff77a0..cdafda127d81 100644
--- a/arch/ppc/syslib/ibm440sp_common.c
+++ b/arch/ppc/syslib/ibm440sp_common.c
@@ -1,7 +1,7 @@
/*
* arch/ppc/syslib/ibm440sp_common.c
*
- * PPC440SP system library
+ * PPC440SP/PPC440SPe system library
*
* Matt Porter <mporter@kernel.crashing.org>
* Copyright 2002-2005 MontaVista Software Inc.
@@ -35,7 +35,7 @@ unsigned long __init ibm440sp_find_end_of_memory(void)
u32 mem_size = 0;
/* Read two bank sizes and sum */
- for (i=0; i<2; i++)
+ for (i=0; i< MQ0_NUM_BANKS; i++)
switch (mfdcr(DCRN_MQ0_BS0BAS + i) & MQ0_CONFIG_SIZE_MASK) {
case MQ0_CONFIG_SIZE_8M:
mem_size += PPC44x_MEM_SIZE_8M;
diff --git a/arch/ppc/syslib/ibm44x_common.c b/arch/ppc/syslib/ibm44x_common.c
index 7612e0623f99..71db11d22158 100644
--- a/arch/ppc/syslib/ibm44x_common.c
+++ b/arch/ppc/syslib/ibm44x_common.c
@@ -20,6 +20,7 @@
#include <linux/types.h>
#include <linux/serial.h>
#include <linux/module.h>
+#include <linux/initrd.h>
#include <asm/ibm44x.h>
#include <asm/mmu.h>
@@ -27,9 +28,14 @@
#include <asm/time.h>
#include <asm/ppc4xx_pic.h>
#include <asm/param.h>
+#include <asm/bootinfo.h>
+#include <asm/ppcboot.h>
#include <syslib/gen550.h>
+/* Global Variables */
+bd_t __res;
+
phys_addr_t fixup_bigphys_addr(phys_addr_t addr, phys_addr_t size)
{
phys_addr_t page_4gb = 0;
@@ -150,8 +156,36 @@ static unsigned long __init ibm44x_find_end_of_memory(void)
return mem_size;
}
-void __init ibm44x_platform_init(void)
+void __init ibm44x_platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
+ unsigned long r6, unsigned long r7)
{
+ parse_bootinfo(find_bootinfo());
+
+ /*
+ * If we were passed in a board information, copy it into the
+ * residual data area.
+ */
+ if (r3)
+ __res = *(bd_t *)(r3 + KERNELBASE);
+
+#if defined(CONFIG_BLK_DEV_INITRD)
+ /*
+ * If the init RAM disk has been configured in, and there's a valid
+ * starting address for it, set it up.
+ */
+ if (r4) {
+ initrd_start = r4 + KERNELBASE;
+ initrd_end = r5 + KERNELBASE;
+ }
+#endif /* CONFIG_BLK_DEV_INITRD */
+
+ /* Copy the kernel command line arguments to a safe place. */
+
+ if (r6) {
+ *(char *) (r7 + KERNELBASE) = 0;
+ strcpy(cmd_line, (char *) (r6 + KERNELBASE));
+ }
+
ppc_md.init_IRQ = ppc4xx_pic_init;
ppc_md.find_end_of_memory = ibm44x_find_end_of_memory;
ppc_md.restart = ibm44x_restart;
@@ -178,12 +212,23 @@ void __init ibm44x_platform_init(void)
#endif
}
-/* Called from MachineCheckException */
+/* Called from machine_check_exception */
void platform_machine_check(struct pt_regs *regs)
{
+#if defined(CONFIG_440SP) || defined(CONFIG_440SPE)
+ printk("PLB0: BEAR=0x%08x%08x ACR= 0x%08x BESR= 0x%08x%08x\n",
+ mfdcr(DCRN_PLB0_BEARH), mfdcr(DCRN_PLB0_BEARL),
+ mfdcr(DCRN_PLB0_ACR), mfdcr(DCRN_PLB0_BESRH),
+ mfdcr(DCRN_PLB0_BESRL));
+ printk("PLB1: BEAR=0x%08x%08x ACR= 0x%08x BESR= 0x%08x%08x\n",
+ mfdcr(DCRN_PLB1_BEARH), mfdcr(DCRN_PLB1_BEARL),
+ mfdcr(DCRN_PLB1_ACR), mfdcr(DCRN_PLB1_BESRH),
+ mfdcr(DCRN_PLB1_BESRL));
+#else
printk("PLB0: BEAR=0x%08x%08x ACR= 0x%08x BESR= 0x%08x\n",
mfdcr(DCRN_PLB0_BEARH), mfdcr(DCRN_PLB0_BEARL),
mfdcr(DCRN_PLB0_ACR), mfdcr(DCRN_PLB0_BESR));
+#endif
printk("POB0: BEAR=0x%08x%08x BESR0=0x%08x BESR1=0x%08x\n",
mfdcr(DCRN_POB0_BEARH), mfdcr(DCRN_POB0_BEARL),
mfdcr(DCRN_POB0_BESR0), mfdcr(DCRN_POB0_BESR1));
diff --git a/arch/ppc/syslib/ibm44x_common.h b/arch/ppc/syslib/ibm44x_common.h
index c16b6a5ac6ab..b25a8995e4e9 100644
--- a/arch/ppc/syslib/ibm44x_common.h
+++ b/arch/ppc/syslib/ibm44x_common.h
@@ -36,7 +36,8 @@ struct ibm44x_clocks {
};
/* common 44x platform init */
-void ibm44x_platform_init(void) __init;
+void ibm44x_platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
+ unsigned long r6, unsigned long r7) __init;
/* initialize decrementer and tick-related variables */
void ibm44x_calibrate_decr(unsigned int freq) __init;
diff --git a/arch/ppc/syslib/m8260_setup.c b/arch/ppc/syslib/m8260_setup.c
index 8f80a42dfdb7..76a2aa4ce65e 100644
--- a/arch/ppc/syslib/m8260_setup.c
+++ b/arch/ppc/syslib/m8260_setup.c
@@ -62,6 +62,10 @@ m8260_setup_arch(void)
if (initrd_start)
ROOT_DEV = Root_RAM0;
#endif
+
+ identify_ppc_sys_by_name_and_id(BOARD_CHIP_NAME,
+ in_be32(CPM_MAP_ADDR + CPM_IMMR_OFFSET));
+
m82xx_board_setup();
}
diff --git a/arch/ppc/syslib/m82xx_pci.c b/arch/ppc/syslib/m82xx_pci.c
index 9db58c587b46..1d1c3956c1ae 100644
--- a/arch/ppc/syslib/m82xx_pci.c
+++ b/arch/ppc/syslib/m82xx_pci.c
@@ -302,11 +302,11 @@ pq2ads_setup_pci(struct pci_controller *hose)
void __init pq2_find_bridges(void)
{
- extern int pci_assign_all_busses;
+ extern int pci_assign_all_buses;
struct pci_controller * hose;
int host_bridge;
- pci_assign_all_busses = 1;
+ pci_assign_all_buses = 1;
hose = pcibios_alloc_controller();
diff --git a/arch/ppc/syslib/m8xx_setup.c b/arch/ppc/syslib/m8xx_setup.c
index 4c888da89b3c..1cc3abe6fa43 100644
--- a/arch/ppc/syslib/m8xx_setup.c
+++ b/arch/ppc/syslib/m8xx_setup.c
@@ -45,6 +45,7 @@
#include <asm/bootinfo.h>
#include <asm/time.h>
#include <asm/xmon.h>
+#include <asm/ppc_sys.h>
#include "ppc8xx_pic.h"
@@ -144,12 +145,12 @@ void __init m8xx_calibrate_decr(void)
int freq, fp, divisor;
/* Unlock the SCCR. */
- ((volatile immap_t *)IMAP_ADDR)->im_clkrstk.cark_sccrk = ~KAPWR_KEY;
- ((volatile immap_t *)IMAP_ADDR)->im_clkrstk.cark_sccrk = KAPWR_KEY;
+ out_be32(&((immap_t *)IMAP_ADDR)->im_clkrstk.cark_sccrk, ~KAPWR_KEY);
+ out_be32(&((immap_t *)IMAP_ADDR)->im_clkrstk.cark_sccrk, KAPWR_KEY);
/* Force all 8xx processors to use divide by 16 processor clock. */
- ((volatile immap_t *)IMAP_ADDR)->im_clkrst.car_sccr |= 0x02000000;
-
+ out_be32(&((immap_t *)IMAP_ADDR)->im_clkrst.car_sccr,
+ in_be32(&((immap_t *)IMAP_ADDR)->im_clkrst.car_sccr)|0x02000000);
/* Processor frequency is MHz.
* The value 'fp' is the number of decrementer ticks per second.
*/
@@ -175,28 +176,24 @@ void __init m8xx_calibrate_decr(void)
* we guarantee the registers are locked, then we unlock them
* for our use.
*/
- ((volatile immap_t *)IMAP_ADDR)->im_sitk.sitk_tbscrk = ~KAPWR_KEY;
- ((volatile immap_t *)IMAP_ADDR)->im_sitk.sitk_rtcsck = ~KAPWR_KEY;
- ((volatile immap_t *)IMAP_ADDR)->im_sitk.sitk_tbk = ~KAPWR_KEY;
- ((volatile immap_t *)IMAP_ADDR)->im_sitk.sitk_tbscrk = KAPWR_KEY;
- ((volatile immap_t *)IMAP_ADDR)->im_sitk.sitk_rtcsck = KAPWR_KEY;
- ((volatile immap_t *)IMAP_ADDR)->im_sitk.sitk_tbk = KAPWR_KEY;
+ out_be32(&((immap_t *)IMAP_ADDR)->im_sitk.sitk_tbscrk, ~KAPWR_KEY);
+ out_be32(&((immap_t *)IMAP_ADDR)->im_sitk.sitk_rtcsck, ~KAPWR_KEY);
+ out_be32(&((immap_t *)IMAP_ADDR)->im_sitk.sitk_tbk, ~KAPWR_KEY);
+ out_be32(&((immap_t *)IMAP_ADDR)->im_sitk.sitk_tbscrk, KAPWR_KEY);
+ out_be32(&((immap_t *)IMAP_ADDR)->im_sitk.sitk_rtcsck, KAPWR_KEY);
+ out_be32(&((immap_t *)IMAP_ADDR)->im_sitk.sitk_tbk, KAPWR_KEY);
/* Disable the RTC one second and alarm interrupts. */
- ((volatile immap_t *)IMAP_ADDR)->im_sit.sit_rtcsc &=
- ~(RTCSC_SIE | RTCSC_ALE);
+ out_be16(&((immap_t *)IMAP_ADDR)->im_sit.sit_rtcsc, in_be16(&((immap_t *)IMAP_ADDR)->im_sit.sit_rtcsc) & ~(RTCSC_SIE | RTCSC_ALE));
/* Enable the RTC */
- ((volatile immap_t *)IMAP_ADDR)->im_sit.sit_rtcsc |=
- (RTCSC_RTF | RTCSC_RTE);
+ out_be16(&((immap_t *)IMAP_ADDR)->im_sit.sit_rtcsc, in_be16(&((immap_t *)IMAP_ADDR)->im_sit.sit_rtcsc) | (RTCSC_RTF | RTCSC_RTE));
/* Enabling the decrementer also enables the timebase interrupts
* (or from the other point of view, to get decrementer interrupts
* we have to enable the timebase). The decrementer interrupt
* is wired into the vector table, nothing to do here for that.
*/
- ((volatile immap_t *)IMAP_ADDR)->im_sit.sit_tbscr =
- ((mk_int_int_mask(DEC_INTERRUPT) << 8) |
- (TBSCR_TBF | TBSCR_TBE));
+ out_be16(&((immap_t *)IMAP_ADDR)->im_sit.sit_tbscr, (mk_int_int_mask(DEC_INTERRUPT) << 8) | (TBSCR_TBF | TBSCR_TBE));
if (setup_irq(DEC_INTERRUPT, &tbint_irqaction))
panic("Could not allocate timer IRQ!");
@@ -216,9 +213,9 @@ void __init m8xx_calibrate_decr(void)
static int
m8xx_set_rtc_time(unsigned long time)
{
- ((volatile immap_t *)IMAP_ADDR)->im_sitk.sitk_rtck = KAPWR_KEY;
- ((volatile immap_t *)IMAP_ADDR)->im_sit.sit_rtc = time;
- ((volatile immap_t *)IMAP_ADDR)->im_sitk.sitk_rtck = ~KAPWR_KEY;
+ out_be32(&((immap_t *)IMAP_ADDR)->im_sitk.sitk_rtck, KAPWR_KEY);
+ out_be32(&((immap_t *)IMAP_ADDR)->im_sit.sit_rtc, time);
+ out_be32(&((immap_t *)IMAP_ADDR)->im_sitk.sitk_rtck, ~KAPWR_KEY);
return(0);
}
@@ -226,7 +223,7 @@ static unsigned long
m8xx_get_rtc_time(void)
{
/* Get time from the RTC. */
- return((unsigned long)(((immap_t *)IMAP_ADDR)->im_sit.sit_rtc));
+ return (unsigned long) in_be32(&((immap_t *)IMAP_ADDR)->im_sit.sit_rtc);
}
static void
@@ -235,13 +232,13 @@ m8xx_restart(char *cmd)
__volatile__ unsigned char dummy;
local_irq_disable();
- ((immap_t *)IMAP_ADDR)->im_clkrst.car_plprcr |= 0x00000080;
+ out_be32(&((immap_t *)IMAP_ADDR)->im_clkrst.car_plprcr, in_be32(&((immap_t *)IMAP_ADDR)->im_clkrst.car_plprcr) | 0x00000080);
/* Clear the ME bit in MSR to cause checkstop on machine check
*/
mtmsr(mfmsr() & ~0x1000);
- dummy = ((immap_t *)IMAP_ADDR)->im_clkrst.res[0];
+ dummy = in_8(&((immap_t *)IMAP_ADDR)->im_clkrst.res[0]);
printk("Restart failed\n");
while(1);
}
@@ -306,8 +303,7 @@ m8xx_init_IRQ(void)
i8259_init(0);
/* The i8259 cascade interrupt must be level sensitive. */
- ((immap_t *)IMAP_ADDR)->im_siu_conf.sc_siel &=
- ~(0x80000000 >> ISA_BRIDGE_INT);
+ out_be32(&((immap_t *)IMAP_ADDR)->im_siu_conf.sc_siel, in_be32(&((immap_t *)IMAP_ADDR)->im_siu_conf.sc_siel & ~(0x80000000 >> ISA_BRIDGE_INT)));
if (setup_irq(ISA_BRIDGE_INT, &mbx_i8259_irqaction))
enable_irq(ISA_BRIDGE_INT);
@@ -404,9 +400,10 @@ platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
strcpy(cmd_line, (char *)(r6+KERNELBASE));
}
+ identify_ppc_sys_by_name(BOARD_CHIP_NAME);
+
ppc_md.setup_arch = m8xx_setup_arch;
ppc_md.show_percpuinfo = m8xx_show_percpuinfo;
- ppc_md.irq_canonicalize = NULL;
ppc_md.init_IRQ = m8xx_init_IRQ;
ppc_md.get_irq = m8xx_get_irq;
ppc_md.init = NULL;
diff --git a/arch/ppc/syslib/m8xx_wdt.c b/arch/ppc/syslib/m8xx_wdt.c
index 2ddc857e7fc7..a21632d37e5a 100644
--- a/arch/ppc/syslib/m8xx_wdt.c
+++ b/arch/ppc/syslib/m8xx_wdt.c
@@ -14,6 +14,7 @@
#include <linux/irq.h>
#include <linux/kernel.h>
#include <linux/sched.h>
+#include <asm/io.h>
#include <asm/8xx_immap.h>
#include <syslib/m8xx_wdt.h>
@@ -29,8 +30,8 @@ void m8xx_wdt_reset(void)
{
volatile immap_t *imap = (volatile immap_t *)IMAP_ADDR;
- imap->im_siu_conf.sc_swsr = 0x556c; /* write magic1 */
- imap->im_siu_conf.sc_swsr = 0xaa39; /* write magic2 */
+ out_be16(&imap->im_siu_conf.sc_swsr, 0x556c); /* write magic1 */
+ out_be16(&imap->im_siu_conf.sc_swsr, 0xaa39); /* write magic2 */
}
static irqreturn_t m8xx_wdt_interrupt(int irq, void *dev, struct pt_regs *regs)
@@ -39,7 +40,7 @@ static irqreturn_t m8xx_wdt_interrupt(int irq, void *dev, struct pt_regs *regs)
m8xx_wdt_reset();
- imap->im_sit.sit_piscr |= PISCR_PS; /* clear irq */
+ out_be16(&imap->im_sit.sit_piscr, in_be16(&imap->im_sit.sit_piscr) | PISCR_PS); /* clear irq */
return IRQ_HANDLED;
}
@@ -51,7 +52,7 @@ void __init m8xx_wdt_handler_install(bd_t * binfo)
u32 sypcr;
u32 pitrtclk;
- sypcr = imap->im_siu_conf.sc_sypcr;
+ sypcr = in_be32(&imap->im_siu_conf.sc_sypcr);
if (!(sypcr & 0x04)) {
printk(KERN_NOTICE "m8xx_wdt: wdt disabled (SYPCR: 0x%08X)\n",
@@ -87,9 +88,9 @@ void __init m8xx_wdt_handler_install(bd_t * binfo)
else
pitc = pitrtclk * wdt_timeout / binfo->bi_intfreq / 2;
- imap->im_sit.sit_pitc = pitc << 16;
- imap->im_sit.sit_piscr =
- (mk_int_int_mask(PIT_INTERRUPT) << 8) | PISCR_PIE | PISCR_PTE;
+ out_be32(&imap->im_sit.sit_pitc, pitc << 16);
+
+ out_be16(&imap->im_sit.sit_piscr, (mk_int_int_mask(PIT_INTERRUPT) << 8) | PISCR_PIE | PISCR_PTE);
if (setup_irq(PIT_INTERRUPT, &m8xx_wdt_irqaction))
panic("m8xx_wdt: error setting up the watchdog irq!");
diff --git a/arch/ppc/syslib/mpc52xx_devices.c b/arch/ppc/syslib/mpc52xx_devices.c
index ad5182efca1d..da3c74bfdc92 100644
--- a/arch/ppc/syslib/mpc52xx_devices.c
+++ b/arch/ppc/syslib/mpc52xx_devices.c
@@ -15,6 +15,7 @@
#include <linux/fsl_devices.h>
#include <linux/resource.h>
+#include <linux/platform_device.h>
#include <asm/mpc52xx.h>
#include <asm/ppc_sys.h>
diff --git a/arch/ppc/syslib/mpc52xx_pci.c b/arch/ppc/syslib/mpc52xx_pci.c
index 59cf3e8bd1a0..4ac19080eb85 100644
--- a/arch/ppc/syslib/mpc52xx_pci.c
+++ b/arch/ppc/syslib/mpc52xx_pci.c
@@ -21,6 +21,7 @@
#include "mpc52xx_pci.h"
#include <asm/delay.h>
+#include <asm/machdep.h>
static int
@@ -181,7 +182,7 @@ mpc52xx_find_bridges(void)
struct mpc52xx_pci __iomem *pci_regs;
struct pci_controller *hose;
- pci_assign_all_busses = 1;
+ pci_assign_all_buses = 1;
pci_regs = ioremap(MPC52xx_PA(MPC52xx_PCI_OFFSET), MPC52xx_PCI_SIZE);
if (!pci_regs)
diff --git a/arch/ppc/syslib/mpc83xx_devices.c b/arch/ppc/syslib/mpc83xx_devices.c
index 95b3b8a7f0ba..f43fbf9a9389 100644
--- a/arch/ppc/syslib/mpc83xx_devices.c
+++ b/arch/ppc/syslib/mpc83xx_devices.c
@@ -21,23 +21,26 @@
#include <asm/mpc83xx.h>
#include <asm/irq.h>
#include <asm/ppc_sys.h>
+#include <asm/machdep.h>
/* We use offsets for IORESOURCE_MEM since we do not know at compile time
* what IMMRBAR is, will get fixed up by mach_mpc83xx_fixup
*/
+struct gianfar_mdio_data mpc83xx_mdio_pdata = {
+ .paddr = 0x24520,
+};
+
static struct gianfar_platform_data mpc83xx_tsec1_pdata = {
.device_flags = FSL_GIANFAR_DEV_HAS_GIGABIT |
FSL_GIANFAR_DEV_HAS_COALESCE | FSL_GIANFAR_DEV_HAS_RMON |
FSL_GIANFAR_DEV_HAS_MULTI_INTR,
- .phy_reg_addr = 0x24000,
};
static struct gianfar_platform_data mpc83xx_tsec2_pdata = {
.device_flags = FSL_GIANFAR_DEV_HAS_GIGABIT |
FSL_GIANFAR_DEV_HAS_COALESCE | FSL_GIANFAR_DEV_HAS_RMON |
FSL_GIANFAR_DEV_HAS_MULTI_INTR,
- .phy_reg_addr = 0x24000,
};
static struct fsl_i2c_platform_data mpc83xx_fsl_i2c1_pdata = {
@@ -219,6 +222,12 @@ struct platform_device ppc_sys_platform_devices[] = {
},
},
},
+ [MPC83xx_MDIO] = {
+ .name = "fsl-gianfar_mdio",
+ .id = 0,
+ .dev.platform_data = &mpc83xx_mdio_pdata,
+ .num_resources = 0,
+ },
};
static int __init mach_mpc83xx_fixup(struct platform_device *pdev)
diff --git a/arch/ppc/syslib/mpc83xx_sys.c b/arch/ppc/syslib/mpc83xx_sys.c
index 29aa63350025..da743446789b 100644
--- a/arch/ppc/syslib/mpc83xx_sys.c
+++ b/arch/ppc/syslib/mpc83xx_sys.c
@@ -24,72 +24,72 @@ struct ppc_sys_spec ppc_sys_specs[] = {
.ppc_sys_name = "8349E",
.mask = 0xFFFF0000,
.value = 0x80500000,
- .num_devices = 8,
+ .num_devices = 9,
.device_list = (enum ppc_sys_devices[])
{
MPC83xx_TSEC1, MPC83xx_TSEC2, MPC83xx_IIC1,
MPC83xx_IIC2, MPC83xx_DUART, MPC83xx_SEC2,
- MPC83xx_USB2_DR, MPC83xx_USB2_MPH
+ MPC83xx_USB2_DR, MPC83xx_USB2_MPH, MPC83xx_MDIO
},
},
{
.ppc_sys_name = "8349",
.mask = 0xFFFF0000,
.value = 0x80510000,
- .num_devices = 7,
+ .num_devices = 8,
.device_list = (enum ppc_sys_devices[])
{
MPC83xx_TSEC1, MPC83xx_TSEC2, MPC83xx_IIC1,
MPC83xx_IIC2, MPC83xx_DUART,
- MPC83xx_USB2_DR, MPC83xx_USB2_MPH
+ MPC83xx_USB2_DR, MPC83xx_USB2_MPH, MPC83xx_MDIO
},
},
{
.ppc_sys_name = "8347E",
.mask = 0xFFFF0000,
.value = 0x80520000,
- .num_devices = 8,
+ .num_devices = 9,
.device_list = (enum ppc_sys_devices[])
{
MPC83xx_TSEC1, MPC83xx_TSEC2, MPC83xx_IIC1,
MPC83xx_IIC2, MPC83xx_DUART, MPC83xx_SEC2,
- MPC83xx_USB2_DR, MPC83xx_USB2_MPH
+ MPC83xx_USB2_DR, MPC83xx_USB2_MPH, MPC83xx_MDIO
},
},
{
.ppc_sys_name = "8347",
.mask = 0xFFFF0000,
.value = 0x80530000,
- .num_devices = 7,
+ .num_devices = 8,
.device_list = (enum ppc_sys_devices[])
{
MPC83xx_TSEC1, MPC83xx_TSEC2, MPC83xx_IIC1,
MPC83xx_IIC2, MPC83xx_DUART,
- MPC83xx_USB2_DR, MPC83xx_USB2_MPH
+ MPC83xx_USB2_DR, MPC83xx_USB2_MPH, MPC83xx_MDIO
},
},
{
.ppc_sys_name = "8343E",
.mask = 0xFFFF0000,
.value = 0x80540000,
- .num_devices = 7,
+ .num_devices = 8,
.device_list = (enum ppc_sys_devices[])
{
MPC83xx_TSEC1, MPC83xx_TSEC2, MPC83xx_IIC1,
MPC83xx_IIC2, MPC83xx_DUART, MPC83xx_SEC2,
- MPC83xx_USB2_DR,
+ MPC83xx_USB2_DR, MPC83xx_MDIO
},
},
{
.ppc_sys_name = "8343",
.mask = 0xFFFF0000,
.value = 0x80550000,
- .num_devices = 6,
+ .num_devices = 7,
.device_list = (enum ppc_sys_devices[])
{
MPC83xx_TSEC1, MPC83xx_TSEC2, MPC83xx_IIC1,
MPC83xx_IIC2, MPC83xx_DUART,
- MPC83xx_USB2_DR,
+ MPC83xx_USB2_DR, MPC83xx_MDIO
},
},
{ /* default match */
diff --git a/arch/ppc/syslib/mpc85xx_devices.c b/arch/ppc/syslib/mpc85xx_devices.c
index bbc5ac0de878..2ede677a0a53 100644
--- a/arch/ppc/syslib/mpc85xx_devices.c
+++ b/arch/ppc/syslib/mpc85xx_devices.c
@@ -25,19 +25,20 @@
/* We use offsets for IORESOURCE_MEM since we do not know at compile time
* what CCSRBAR is, will get fixed up by mach_mpc85xx_fixup
*/
+struct gianfar_mdio_data mpc85xx_mdio_pdata = {
+ .paddr = MPC85xx_MIIM_OFFSET,
+};
static struct gianfar_platform_data mpc85xx_tsec1_pdata = {
.device_flags = FSL_GIANFAR_DEV_HAS_GIGABIT |
FSL_GIANFAR_DEV_HAS_COALESCE | FSL_GIANFAR_DEV_HAS_RMON |
FSL_GIANFAR_DEV_HAS_MULTI_INTR,
- .phy_reg_addr = MPC85xx_ENET1_OFFSET,
};
static struct gianfar_platform_data mpc85xx_tsec2_pdata = {
.device_flags = FSL_GIANFAR_DEV_HAS_GIGABIT |
FSL_GIANFAR_DEV_HAS_COALESCE | FSL_GIANFAR_DEV_HAS_RMON |
FSL_GIANFAR_DEV_HAS_MULTI_INTR,
- .phy_reg_addr = MPC85xx_ENET1_OFFSET,
};
static struct gianfar_platform_data mpc85xx_etsec1_pdata = {
@@ -46,7 +47,6 @@ static struct gianfar_platform_data mpc85xx_etsec1_pdata = {
FSL_GIANFAR_DEV_HAS_MULTI_INTR |
FSL_GIANFAR_DEV_HAS_CSUM | FSL_GIANFAR_DEV_HAS_VLAN |
FSL_GIANFAR_DEV_HAS_EXTENDED_HASH,
- .phy_reg_addr = MPC85xx_ENET1_OFFSET,
};
static struct gianfar_platform_data mpc85xx_etsec2_pdata = {
@@ -55,7 +55,6 @@ static struct gianfar_platform_data mpc85xx_etsec2_pdata = {
FSL_GIANFAR_DEV_HAS_MULTI_INTR |
FSL_GIANFAR_DEV_HAS_CSUM | FSL_GIANFAR_DEV_HAS_VLAN |
FSL_GIANFAR_DEV_HAS_EXTENDED_HASH,
- .phy_reg_addr = MPC85xx_ENET1_OFFSET,
};
static struct gianfar_platform_data mpc85xx_etsec3_pdata = {
@@ -64,7 +63,6 @@ static struct gianfar_platform_data mpc85xx_etsec3_pdata = {
FSL_GIANFAR_DEV_HAS_MULTI_INTR |
FSL_GIANFAR_DEV_HAS_CSUM | FSL_GIANFAR_DEV_HAS_VLAN |
FSL_GIANFAR_DEV_HAS_EXTENDED_HASH,
- .phy_reg_addr = MPC85xx_ENET1_OFFSET,
};
static struct gianfar_platform_data mpc85xx_etsec4_pdata = {
@@ -73,11 +71,10 @@ static struct gianfar_platform_data mpc85xx_etsec4_pdata = {
FSL_GIANFAR_DEV_HAS_MULTI_INTR |
FSL_GIANFAR_DEV_HAS_CSUM | FSL_GIANFAR_DEV_HAS_VLAN |
FSL_GIANFAR_DEV_HAS_EXTENDED_HASH,
- .phy_reg_addr = MPC85xx_ENET1_OFFSET,
};
static struct gianfar_platform_data mpc85xx_fec_pdata = {
- .phy_reg_addr = MPC85xx_ENET1_OFFSET,
+ .device_flags = 0,
};
static struct fsl_i2c_platform_data mpc85xx_fsl_i2c_pdata = {
@@ -719,6 +716,12 @@ struct platform_device ppc_sys_platform_devices[] = {
},
},
},
+ [MPC85xx_MDIO] = {
+ .name = "fsl-gianfar_mdio",
+ .id = 0,
+ .dev.platform_data = &mpc85xx_mdio_pdata,
+ .num_resources = 0,
+ },
};
static int __init mach_mpc85xx_fixup(struct platform_device *pdev)
diff --git a/arch/ppc/syslib/mpc85xx_sys.c b/arch/ppc/syslib/mpc85xx_sys.c
index 6e3184ab354f..cb68d8c58348 100644
--- a/arch/ppc/syslib/mpc85xx_sys.c
+++ b/arch/ppc/syslib/mpc85xx_sys.c
@@ -24,19 +24,19 @@ struct ppc_sys_spec ppc_sys_specs[] = {
.ppc_sys_name = "8540",
.mask = 0xFFFF0000,
.value = 0x80300000,
- .num_devices = 10,
+ .num_devices = 11,
.device_list = (enum ppc_sys_devices[])
{
MPC85xx_TSEC1, MPC85xx_TSEC2, MPC85xx_FEC, MPC85xx_IIC1,
MPC85xx_DMA0, MPC85xx_DMA1, MPC85xx_DMA2, MPC85xx_DMA3,
- MPC85xx_PERFMON, MPC85xx_DUART,
+ MPC85xx_PERFMON, MPC85xx_DUART, MPC85xx_MDIO,
},
},
{
.ppc_sys_name = "8560",
.mask = 0xFFFF0000,
.value = 0x80700000,
- .num_devices = 19,
+ .num_devices = 20,
.device_list = (enum ppc_sys_devices[])
{
MPC85xx_TSEC1, MPC85xx_TSEC2, MPC85xx_IIC1,
@@ -45,14 +45,14 @@ struct ppc_sys_spec ppc_sys_specs[] = {
MPC85xx_CPM_SPI, MPC85xx_CPM_I2C, MPC85xx_CPM_SCC1,
MPC85xx_CPM_SCC2, MPC85xx_CPM_SCC3, MPC85xx_CPM_SCC4,
MPC85xx_CPM_FCC1, MPC85xx_CPM_FCC2, MPC85xx_CPM_FCC3,
- MPC85xx_CPM_MCC1, MPC85xx_CPM_MCC2,
+ MPC85xx_CPM_MCC1, MPC85xx_CPM_MCC2, MPC85xx_MDIO,
},
},
{
.ppc_sys_name = "8541",
.mask = 0xFFFF0000,
.value = 0x80720000,
- .num_devices = 13,
+ .num_devices = 14,
.device_list = (enum ppc_sys_devices[])
{
MPC85xx_TSEC1, MPC85xx_TSEC2, MPC85xx_IIC1,
@@ -60,13 +60,14 @@ struct ppc_sys_spec ppc_sys_specs[] = {
MPC85xx_PERFMON, MPC85xx_DUART,
MPC85xx_CPM_SPI, MPC85xx_CPM_I2C,
MPC85xx_CPM_FCC1, MPC85xx_CPM_FCC2,
+ MPC85xx_MDIO,
},
},
{
.ppc_sys_name = "8541E",
.mask = 0xFFFF0000,
.value = 0x807A0000,
- .num_devices = 14,
+ .num_devices = 15,
.device_list = (enum ppc_sys_devices[])
{
MPC85xx_TSEC1, MPC85xx_TSEC2, MPC85xx_IIC1,
@@ -74,13 +75,14 @@ struct ppc_sys_spec ppc_sys_specs[] = {
MPC85xx_PERFMON, MPC85xx_DUART, MPC85xx_SEC2,
MPC85xx_CPM_SPI, MPC85xx_CPM_I2C,
MPC85xx_CPM_FCC1, MPC85xx_CPM_FCC2,
+ MPC85xx_MDIO,
},
},
{
.ppc_sys_name = "8555",
.mask = 0xFFFF0000,
.value = 0x80710000,
- .num_devices = 19,
+ .num_devices = 20,
.device_list = (enum ppc_sys_devices[])
{
MPC85xx_TSEC1, MPC85xx_TSEC2, MPC85xx_IIC1,
@@ -91,13 +93,14 @@ struct ppc_sys_spec ppc_sys_specs[] = {
MPC85xx_CPM_FCC1, MPC85xx_CPM_FCC2,
MPC85xx_CPM_SMC1, MPC85xx_CPM_SMC2,
MPC85xx_CPM_USB,
+ MPC85xx_MDIO,
},
},
{
.ppc_sys_name = "8555E",
.mask = 0xFFFF0000,
.value = 0x80790000,
- .num_devices = 20,
+ .num_devices = 21,
.device_list = (enum ppc_sys_devices[])
{
MPC85xx_TSEC1, MPC85xx_TSEC2, MPC85xx_IIC1,
@@ -108,6 +111,7 @@ struct ppc_sys_spec ppc_sys_specs[] = {
MPC85xx_CPM_FCC1, MPC85xx_CPM_FCC2,
MPC85xx_CPM_SMC1, MPC85xx_CPM_SMC2,
MPC85xx_CPM_USB,
+ MPC85xx_MDIO,
},
},
/* SVRs on 8548 rev1.0 matches for 8548/8547/8545 */
@@ -115,104 +119,112 @@ struct ppc_sys_spec ppc_sys_specs[] = {
.ppc_sys_name = "8548E",
.mask = 0xFFFF00F0,
.value = 0x80390010,
- .num_devices = 13,
+ .num_devices = 14,
.device_list = (enum ppc_sys_devices[])
{
MPC85xx_eTSEC1, MPC85xx_eTSEC2, MPC85xx_eTSEC3,
MPC85xx_eTSEC4, MPC85xx_IIC1, MPC85xx_IIC2,
MPC85xx_DMA0, MPC85xx_DMA1, MPC85xx_DMA2, MPC85xx_DMA3,
MPC85xx_PERFMON, MPC85xx_DUART, MPC85xx_SEC2,
+ MPC85xx_MDIO,
},
},
{
.ppc_sys_name = "8548",
.mask = 0xFFFF00F0,
.value = 0x80310010,
- .num_devices = 12,
+ .num_devices = 13,
.device_list = (enum ppc_sys_devices[])
{
MPC85xx_eTSEC1, MPC85xx_eTSEC2, MPC85xx_eTSEC3,
MPC85xx_eTSEC4, MPC85xx_IIC1, MPC85xx_IIC2,
MPC85xx_DMA0, MPC85xx_DMA1, MPC85xx_DMA2, MPC85xx_DMA3,
MPC85xx_PERFMON, MPC85xx_DUART,
+ MPC85xx_MDIO,
},
},
{
.ppc_sys_name = "8547E",
.mask = 0xFFFF00F0,
.value = 0x80390010,
- .num_devices = 13,
+ .num_devices = 14,
.device_list = (enum ppc_sys_devices[])
{
MPC85xx_eTSEC1, MPC85xx_eTSEC2, MPC85xx_eTSEC3,
MPC85xx_eTSEC4, MPC85xx_IIC1, MPC85xx_IIC2,
MPC85xx_DMA0, MPC85xx_DMA1, MPC85xx_DMA2, MPC85xx_DMA3,
MPC85xx_PERFMON, MPC85xx_DUART, MPC85xx_SEC2,
+ MPC85xx_MDIO,
},
},
{
.ppc_sys_name = "8547",
.mask = 0xFFFF00F0,
.value = 0x80310010,
- .num_devices = 12,
+ .num_devices = 13,
.device_list = (enum ppc_sys_devices[])
{
MPC85xx_eTSEC1, MPC85xx_eTSEC2, MPC85xx_eTSEC3,
MPC85xx_eTSEC4, MPC85xx_IIC1, MPC85xx_IIC2,
MPC85xx_DMA0, MPC85xx_DMA1, MPC85xx_DMA2, MPC85xx_DMA3,
MPC85xx_PERFMON, MPC85xx_DUART,
+ MPC85xx_MDIO,
},
},
{
.ppc_sys_name = "8545E",
.mask = 0xFFFF00F0,
.value = 0x80390010,
- .num_devices = 11,
+ .num_devices = 12,
.device_list = (enum ppc_sys_devices[])
{
MPC85xx_eTSEC1, MPC85xx_eTSEC2,
MPC85xx_IIC1, MPC85xx_IIC2,
MPC85xx_DMA0, MPC85xx_DMA1, MPC85xx_DMA2, MPC85xx_DMA3,
MPC85xx_PERFMON, MPC85xx_DUART, MPC85xx_SEC2,
+ MPC85xx_MDIO,
},
},
{
.ppc_sys_name = "8545",
.mask = 0xFFFF00F0,
.value = 0x80310010,
- .num_devices = 10,
+ .num_devices = 11,
.device_list = (enum ppc_sys_devices[])
{
MPC85xx_eTSEC1, MPC85xx_eTSEC2,
MPC85xx_IIC1, MPC85xx_IIC2,
MPC85xx_DMA0, MPC85xx_DMA1, MPC85xx_DMA2, MPC85xx_DMA3,
MPC85xx_PERFMON, MPC85xx_DUART,
+ MPC85xx_MDIO,
},
},
{
.ppc_sys_name = "8543E",
.mask = 0xFFFF00F0,
.value = 0x803A0010,
- .num_devices = 11,
+ .num_devices = 12,
.device_list = (enum ppc_sys_devices[])
{
MPC85xx_eTSEC1, MPC85xx_eTSEC2,
MPC85xx_IIC1, MPC85xx_IIC2,
MPC85xx_DMA0, MPC85xx_DMA1, MPC85xx_DMA2, MPC85xx_DMA3,
MPC85xx_PERFMON, MPC85xx_DUART, MPC85xx_SEC2,
+ MPC85xx_MDIO,
},
},
{
.ppc_sys_name = "8543",
.mask = 0xFFFF00F0,
.value = 0x80320010,
- .num_devices = 10,
+ .num_devices = 11,
.device_list = (enum ppc_sys_devices[])
{
MPC85xx_eTSEC1, MPC85xx_eTSEC2,
MPC85xx_IIC1, MPC85xx_IIC2,
MPC85xx_DMA0, MPC85xx_DMA1, MPC85xx_DMA2, MPC85xx_DMA3,
MPC85xx_PERFMON, MPC85xx_DUART,
+ MPC85xx_MDIO,
},
},
{ /* default match */
diff --git a/arch/ppc/syslib/mpc8xx_sys.c b/arch/ppc/syslib/mpc8xx_sys.c
index a532ccc861c0..3cc27d29e3af 100644
--- a/arch/ppc/syslib/mpc8xx_sys.c
+++ b/arch/ppc/syslib/mpc8xx_sys.c
@@ -24,7 +24,7 @@ struct ppc_sys_spec ppc_sys_specs[] = {
.ppc_sys_name = "MPC86X",
.mask = 0xFFFFFFFF,
.value = 0x00000000,
- .num_devices = 2,
+ .num_devices = 7,
.device_list = (enum ppc_sys_devices[])
{
MPC8xx_CPM_FEC1,
@@ -40,7 +40,7 @@ struct ppc_sys_spec ppc_sys_specs[] = {
.ppc_sys_name = "MPC885",
.mask = 0xFFFFFFFF,
.value = 0x00000000,
- .num_devices = 3,
+ .num_devices = 8,
.device_list = (enum ppc_sys_devices[])
{
MPC8xx_CPM_FEC1,
diff --git a/arch/ppc/syslib/mv64360_pic.c b/arch/ppc/syslib/mv64360_pic.c
index 8356da4678a2..58b0aa813e85 100644
--- a/arch/ppc/syslib/mv64360_pic.c
+++ b/arch/ppc/syslib/mv64360_pic.c
@@ -48,6 +48,7 @@
#include <asm/system.h>
#include <asm/irq.h>
#include <asm/mv64x60.h>
+#include <asm/machdep.h>
#ifdef CONFIG_IRQ_ALL_CPUS
#error "The mv64360 does not support distribution of IRQs on all CPUs"
diff --git a/arch/ppc/syslib/mv64x60.c b/arch/ppc/syslib/mv64x60.c
index 4849850a59ed..94ea346b7b4b 100644
--- a/arch/ppc/syslib/mv64x60.c
+++ b/arch/ppc/syslib/mv64x60.c
@@ -19,6 +19,7 @@
#include <linux/string.h>
#include <linux/spinlock.h>
#include <linux/mv643xx.h>
+#include <linux/platform_device.h>
#include <asm/byteorder.h>
#include <asm/io.h>
@@ -1304,7 +1305,7 @@ mv64x60_config_pci_params(struct pci_controller *hose,
early_write_config_word(hose, 0, devfn, PCI_COMMAND, u16_val);
/* Set latency timer, cache line size, clear BIST */
- u16_val = (pi->latency_timer << 8) | (L1_CACHE_LINE_SIZE >> 2);
+ u16_val = (pi->latency_timer << 8) | (L1_CACHE_BYTES >> 2);
early_write_config_word(hose, 0, devfn, PCI_CACHE_LINE_SIZE, u16_val);
mv64x60_pci_exclude_bridge = save_exclude;
diff --git a/arch/ppc/syslib/mv64x60_dbg.c b/arch/ppc/syslib/mv64x60_dbg.c
index 2927c7adf5e5..fa5b2e45e0ca 100644
--- a/arch/ppc/syslib/mv64x60_dbg.c
+++ b/arch/ppc/syslib/mv64x60_dbg.c
@@ -24,6 +24,7 @@
#include <linux/irq.h>
#include <asm/delay.h>
#include <asm/mv64x60.h>
+#include <asm/machdep.h>
#if defined(CONFIG_SERIAL_TEXT_DEBUG)
diff --git a/arch/ppc/syslib/of_device.c b/arch/ppc/syslib/of_device.c
deleted file mode 100644
index 93c7231ea709..000000000000
--- a/arch/ppc/syslib/of_device.c
+++ /dev/null
@@ -1,276 +0,0 @@
-#include <linux/config.h>
-#include <linux/string.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/mod_devicetable.h>
-#include <asm/errno.h>
-#include <asm/of_device.h>
-
-/**
- * of_match_device - Tell if an of_device structure has a matching
- * of_match structure
- * @ids: array of of device match structures to search in
- * @dev: the of device structure to match against
- *
- * Used by a driver to check whether an of_device present in the
- * system is in its list of supported devices.
- */
-const struct of_device_id * of_match_device(const struct of_device_id *matches,
- const struct of_device *dev)
-{
- if (!dev->node)
- return NULL;
- while (matches->name[0] || matches->type[0] || matches->compatible[0]) {
- int match = 1;
- if (matches->name[0])
- match &= dev->node->name
- && !strcmp(matches->name, dev->node->name);
- if (matches->type[0])
- match &= dev->node->type
- && !strcmp(matches->type, dev->node->type);
- if (matches->compatible[0])
- match &= device_is_compatible(dev->node,
- matches->compatible);
- if (match)
- return matches;
- matches++;
- }
- return NULL;
-}
-
-static int of_platform_bus_match(struct device *dev, struct device_driver *drv)
-{
- struct of_device * of_dev = to_of_device(dev);
- struct of_platform_driver * of_drv = to_of_platform_driver(drv);
- const struct of_device_id * matches = of_drv->match_table;
-
- if (!matches)
- return 0;
-
- return of_match_device(matches, of_dev) != NULL;
-}
-
-struct of_device *of_dev_get(struct of_device *dev)
-{
- struct device *tmp;
-
- if (!dev)
- return NULL;
- tmp = get_device(&dev->dev);
- if (tmp)
- return to_of_device(tmp);
- else
- return NULL;
-}
-
-void of_dev_put(struct of_device *dev)
-{
- if (dev)
- put_device(&dev->dev);
-}
-
-
-static int of_device_probe(struct device *dev)
-{
- int error = -ENODEV;
- struct of_platform_driver *drv;
- struct of_device *of_dev;
- const struct of_device_id *match;
-
- drv = to_of_platform_driver(dev->driver);
- of_dev = to_of_device(dev);
-
- if (!drv->probe)
- return error;
-
- of_dev_get(of_dev);
-
- match = of_match_device(drv->match_table, of_dev);
- if (match)
- error = drv->probe(of_dev, match);
- if (error)
- of_dev_put(of_dev);
-
- return error;
-}
-
-static int of_device_remove(struct device *dev)
-{
- struct of_device * of_dev = to_of_device(dev);
- struct of_platform_driver * drv = to_of_platform_driver(dev->driver);
-
- if (dev->driver && drv->remove)
- drv->remove(of_dev);
- return 0;
-}
-
-static int of_device_suspend(struct device *dev, pm_message_t state)
-{
- struct of_device * of_dev = to_of_device(dev);
- struct of_platform_driver * drv = to_of_platform_driver(dev->driver);
- int error = 0;
-
- if (dev->driver && drv->suspend)
- error = drv->suspend(of_dev, state);
- return error;
-}
-
-static int of_device_resume(struct device * dev)
-{
- struct of_device * of_dev = to_of_device(dev);
- struct of_platform_driver * drv = to_of_platform_driver(dev->driver);
- int error = 0;
-
- if (dev->driver && drv->resume)
- error = drv->resume(of_dev);
- return error;
-}
-
-struct bus_type of_platform_bus_type = {
- .name = "of_platform",
- .match = of_platform_bus_match,
- .suspend = of_device_suspend,
- .resume = of_device_resume,
-};
-
-static int __init of_bus_driver_init(void)
-{
- return bus_register(&of_platform_bus_type);
-}
-
-postcore_initcall(of_bus_driver_init);
-
-int of_register_driver(struct of_platform_driver *drv)
-{
- int count = 0;
-
- /* initialize common driver fields */
- drv->driver.name = drv->name;
- drv->driver.bus = &of_platform_bus_type;
- drv->driver.probe = of_device_probe;
- drv->driver.remove = of_device_remove;
-
- /* register with core */
- count = driver_register(&drv->driver);
- return count ? count : 1;
-}
-
-void of_unregister_driver(struct of_platform_driver *drv)
-{
- driver_unregister(&drv->driver);
-}
-
-
-static ssize_t dev_show_devspec(struct device *dev, struct device_attribute *attr, char *buf)
-{
- struct of_device *ofdev;
-
- ofdev = to_of_device(dev);
- return sprintf(buf, "%s", ofdev->node->full_name);
-}
-
-static DEVICE_ATTR(devspec, S_IRUGO, dev_show_devspec, NULL);
-
-/**
- * of_release_dev - free an of device structure when all users of it are finished.
- * @dev: device that's been disconnected
- *
- * Will be called only by the device core when all users of this of device are
- * done.
- */
-void of_release_dev(struct device *dev)
-{
- struct of_device *ofdev;
-
- ofdev = to_of_device(dev);
- of_node_put(ofdev->node);
- kfree(ofdev);
-}
-
-int of_device_register(struct of_device *ofdev)
-{
- int rc;
- struct of_device **odprop;
-
- BUG_ON(ofdev->node == NULL);
-
- odprop = (struct of_device **)get_property(ofdev->node, "linux,device", NULL);
- if (!odprop) {
- struct property *new_prop;
-
- new_prop = kmalloc(sizeof(struct property) + sizeof(struct of_device *),
- GFP_KERNEL);
- if (new_prop == NULL)
- return -ENOMEM;
- new_prop->name = "linux,device";
- new_prop->length = sizeof(sizeof(struct of_device *));
- new_prop->value = (unsigned char *)&new_prop[1];
- odprop = (struct of_device **)new_prop->value;
- *odprop = NULL;
- prom_add_property(ofdev->node, new_prop);
- }
- *odprop = ofdev;
-
- rc = device_register(&ofdev->dev);
- if (rc)
- return rc;
-
- device_create_file(&ofdev->dev, &dev_attr_devspec);
-
- return 0;
-}
-
-void of_device_unregister(struct of_device *ofdev)
-{
- struct of_device **odprop;
-
- device_remove_file(&ofdev->dev, &dev_attr_devspec);
-
- odprop = (struct of_device **)get_property(ofdev->node, "linux,device", NULL);
- if (odprop)
- *odprop = NULL;
-
- device_unregister(&ofdev->dev);
-}
-
-struct of_device* of_platform_device_create(struct device_node *np,
- const char *bus_id,
- struct device *parent)
-{
- struct of_device *dev;
- u32 *reg;
-
- dev = kmalloc(sizeof(*dev), GFP_KERNEL);
- if (!dev)
- return NULL;
- memset(dev, 0, sizeof(*dev));
-
- dev->node = of_node_get(np);
- dev->dma_mask = 0xffffffffUL;
- dev->dev.dma_mask = &dev->dma_mask;
- dev->dev.parent = parent;
- dev->dev.bus = &of_platform_bus_type;
- dev->dev.release = of_release_dev;
-
- reg = (u32 *)get_property(np, "reg", NULL);
- strlcpy(dev->dev.bus_id, bus_id, BUS_ID_SIZE);
-
- if (of_device_register(dev) != 0) {
- kfree(dev);
- return NULL;
- }
-
- return dev;
-}
-
-EXPORT_SYMBOL(of_match_device);
-EXPORT_SYMBOL(of_platform_bus_type);
-EXPORT_SYMBOL(of_register_driver);
-EXPORT_SYMBOL(of_unregister_driver);
-EXPORT_SYMBOL(of_device_register);
-EXPORT_SYMBOL(of_device_unregister);
-EXPORT_SYMBOL(of_dev_get);
-EXPORT_SYMBOL(of_dev_put);
-EXPORT_SYMBOL(of_platform_device_create);
-EXPORT_SYMBOL(of_release_dev);
diff --git a/arch/ppc/syslib/open_pic.c b/arch/ppc/syslib/open_pic.c
index 1cf5de21a3fd..894779712b46 100644
--- a/arch/ppc/syslib/open_pic.c
+++ b/arch/ppc/syslib/open_pic.c
@@ -23,6 +23,7 @@
#include <asm/sections.h>
#include <asm/open_pic.h>
#include <asm/i8259.h>
+#include <asm/machdep.h>
#include "open_pic_defs.h"
@@ -889,7 +890,7 @@ openpic_get_irq(struct pt_regs *regs)
#ifdef CONFIG_SMP
void
-smp_openpic_message_pass(int target, int msg, unsigned long data, int wait)
+smp_openpic_message_pass(int target, int msg)
{
cpumask_t mask = CPU_MASK_ALL;
/* make sure we're sending something that translates to an IPI */
diff --git a/arch/ppc/syslib/open_pic2.c b/arch/ppc/syslib/open_pic2.c
index 16cff91d9f41..1c40049b9a45 100644
--- a/arch/ppc/syslib/open_pic2.c
+++ b/arch/ppc/syslib/open_pic2.c
@@ -27,6 +27,7 @@
#include <asm/sections.h>
#include <asm/open_pic.h>
#include <asm/i8259.h>
+#include <asm/machdep.h>
#include "open_pic_defs.h"
diff --git a/arch/ppc/syslib/ppc403_pic.c b/arch/ppc/syslib/ppc403_pic.c
index ce4d1deb86e9..c46043c47225 100644
--- a/arch/ppc/syslib/ppc403_pic.c
+++ b/arch/ppc/syslib/ppc403_pic.c
@@ -26,6 +26,7 @@
#include <asm/system.h>
#include <asm/irq.h>
#include <asm/ppc4xx_pic.h>
+#include <asm/machdep.h>
/* Function Prototypes */
diff --git a/arch/ppc/syslib/ppc405_pci.c b/arch/ppc/syslib/ppc405_pci.c
index 81c83bf98df4..d6d838b16dac 100644
--- a/arch/ppc/syslib/ppc405_pci.c
+++ b/arch/ppc/syslib/ppc405_pci.c
@@ -89,13 +89,6 @@ ppc4xx_find_bridges(void)
isa_mem_base = 0;
pci_dram_offset = 0;
-#if (PSR_PCI_ARBIT_EN > 1)
- /* Check if running in slave mode */
- if ((mfdcr(DCRN_CHPSR) & PSR_PCI_ARBIT_EN) == 0) {
- printk("Running as PCI slave, kernel PCI disabled !\n");
- return;
- }
-#endif
/* Setup PCI32 hose */
hose_a = pcibios_alloc_controller();
if (!hose_a)
diff --git a/arch/ppc/syslib/ppc440spe_pcie.c b/arch/ppc/syslib/ppc440spe_pcie.c
new file mode 100644
index 000000000000..1509fc1ddfb6
--- /dev/null
+++ b/arch/ppc/syslib/ppc440spe_pcie.c
@@ -0,0 +1,442 @@
+/*
+ * Copyright (c) 2005 Cisco Systems. All rights reserved.
+ * Roland Dreier <rolandd@cisco.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/config.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+
+#include <asm/reg.h>
+#include <asm/io.h>
+#include <asm/ibm44x.h>
+
+#include "ppc440spe_pcie.h"
+
+static int
+pcie_read_config(struct pci_bus *bus, unsigned int devfn, int offset,
+ int len, u32 *val)
+{
+ struct pci_controller *hose = bus->sysdata;
+
+ if (PCI_SLOT(devfn) != 1)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ offset += devfn << 12;
+
+ /*
+ * Note: the caller has already checked that offset is
+ * suitably aligned and that len is 1, 2 or 4.
+ */
+ switch (len) {
+ case 1:
+ *val = in_8(hose->cfg_data + offset);
+ break;
+ case 2:
+ *val = in_le16(hose->cfg_data + offset);
+ break;
+ default:
+ *val = in_le32(hose->cfg_data + offset);
+ break;
+ }
+
+ if (0) printk("%s: read %x(%d) @ %x\n", __func__, *val, len, offset);
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+pcie_write_config(struct pci_bus *bus, unsigned int devfn, int offset,
+ int len, u32 val)
+{
+ struct pci_controller *hose = bus->sysdata;
+
+ if (PCI_SLOT(devfn) != 1)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ offset += devfn << 12;
+
+ switch (len) {
+ case 1:
+ out_8(hose->cfg_data + offset, val);
+ break;
+ case 2:
+ out_le16(hose->cfg_data + offset, val);
+ break;
+ default:
+ out_le32(hose->cfg_data + offset, val);
+ break;
+ }
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static struct pci_ops pcie_pci_ops =
+{
+ .read = pcie_read_config,
+ .write = pcie_write_config
+};
+
+enum {
+ PTYPE_ENDPOINT = 0x0,
+ PTYPE_LEGACY_ENDPOINT = 0x1,
+ PTYPE_ROOT_PORT = 0x4,
+
+ LNKW_X1 = 0x1,
+ LNKW_X4 = 0x4,
+ LNKW_X8 = 0x8
+};
+
+static void check_error(void)
+{
+ u32 valPE0, valPE1, valPE2;
+
+ /* SDR0_PEGPLLLCT1 reset */
+ if (!(valPE0 = SDR_READ(PESDR0_PLLLCT1) & 0x01000000)) {
+ printk(KERN_INFO "PCIE: SDR0_PEGPLLLCT1 reset error 0x%8x\n", valPE0);
+ }
+
+ valPE0 = SDR_READ(PESDR0_RCSSET);
+ valPE1 = SDR_READ(PESDR1_RCSSET);
+ valPE2 = SDR_READ(PESDR2_RCSSET);
+
+ /* SDR0_PExRCSSET rstgu */
+ if ( !(valPE0 & 0x01000000) ||
+ !(valPE1 & 0x01000000) ||
+ !(valPE2 & 0x01000000)) {
+ printk(KERN_INFO "PCIE: SDR0_PExRCSSET rstgu error\n");
+ }
+
+ /* SDR0_PExRCSSET rstdl */
+ if ( !(valPE0 & 0x00010000) ||
+ !(valPE1 & 0x00010000) ||
+ !(valPE2 & 0x00010000)) {
+ printk(KERN_INFO "PCIE: SDR0_PExRCSSET rstdl error\n");
+ }
+
+ /* SDR0_PExRCSSET rstpyn */
+ if ( (valPE0 & 0x00001000) ||
+ (valPE1 & 0x00001000) ||
+ (valPE2 & 0x00001000)) {
+ printk(KERN_INFO "PCIE: SDR0_PExRCSSET rstpyn error\n");
+ }
+
+ /* SDR0_PExRCSSET hldplb */
+ if ( (valPE0 & 0x10000000) ||
+ (valPE1 & 0x10000000) ||
+ (valPE2 & 0x10000000)) {
+ printk(KERN_INFO "PCIE: SDR0_PExRCSSET hldplb error\n");
+ }
+
+ /* SDR0_PExRCSSET rdy */
+ if ( (valPE0 & 0x00100000) ||
+ (valPE1 & 0x00100000) ||
+ (valPE2 & 0x00100000)) {
+ printk(KERN_INFO "PCIE: SDR0_PExRCSSET rdy error\n");
+ }
+
+ /* SDR0_PExRCSSET shutdown */
+ if ( (valPE0 & 0x00000100) ||
+ (valPE1 & 0x00000100) ||
+ (valPE2 & 0x00000100)) {
+ printk(KERN_INFO "PCIE: SDR0_PExRCSSET shutdown error\n");
+ }
+}
+
+/*
+ * Initialize PCI Express core as described in User Manual section 27.12.1
+ */
+int ppc440spe_init_pcie(void)
+{
+ /* Set PLL clock receiver to LVPECL */
+ SDR_WRITE(PESDR0_PLLLCT1, SDR_READ(PESDR0_PLLLCT1) | 1 << 28);
+
+ check_error();
+
+ printk(KERN_INFO "PCIE initialization OK\n");
+
+ if (!(SDR_READ(PESDR0_PLLLCT2) & 0x10000))
+ printk(KERN_INFO "PESDR_PLLCT2 resistance calibration failed (0x%08x)\n",
+ SDR_READ(PESDR0_PLLLCT2));
+
+ /* De-assert reset of PCIe PLL, wait for lock */
+ SDR_WRITE(PESDR0_PLLLCT1, SDR_READ(PESDR0_PLLLCT1) & ~(1 << 24));
+ udelay(3);
+
+ return 0;
+}
+
+int ppc440spe_init_pcie_rootport(int port)
+{
+ static int core_init;
+ void __iomem *utl_base;
+ u32 val = 0;
+ int i;
+
+ if (!core_init) {
+ ++core_init;
+ i = ppc440spe_init_pcie();
+ if (i)
+ return i;
+ }
+
+ /*
+ * Initialize various parts of the PCI Express core for our port:
+ *
+ * - Set as a root port and enable max width
+ * (PXIE0 -> X8, PCIE1 and PCIE2 -> X4).
+ * - Set up UTL configuration.
+ * - Increase SERDES drive strength to levels suggested by AMCC.
+ * - De-assert RSTPYN, RSTDL and RSTGU.
+ */
+ switch (port) {
+ case 0:
+ SDR_WRITE(PESDR0_DLPSET, PTYPE_ROOT_PORT << 20 | LNKW_X8 << 12);
+
+ SDR_WRITE(PESDR0_UTLSET1, 0x21222222);
+ SDR_WRITE(PESDR0_UTLSET2, 0x11000000);
+
+ SDR_WRITE(PESDR0_HSSL0SET1, 0x35000000);
+ SDR_WRITE(PESDR0_HSSL1SET1, 0x35000000);
+ SDR_WRITE(PESDR0_HSSL2SET1, 0x35000000);
+ SDR_WRITE(PESDR0_HSSL3SET1, 0x35000000);
+ SDR_WRITE(PESDR0_HSSL4SET1, 0x35000000);
+ SDR_WRITE(PESDR0_HSSL5SET1, 0x35000000);
+ SDR_WRITE(PESDR0_HSSL6SET1, 0x35000000);
+ SDR_WRITE(PESDR0_HSSL7SET1, 0x35000000);
+
+ SDR_WRITE(PESDR0_RCSSET,
+ (SDR_READ(PESDR0_RCSSET) & ~(1 << 24 | 1 << 16)) | 1 << 12);
+ break;
+
+ case 1:
+ SDR_WRITE(PESDR1_DLPSET, PTYPE_ROOT_PORT << 20 | LNKW_X4 << 12);
+
+ SDR_WRITE(PESDR1_UTLSET1, 0x21222222);
+ SDR_WRITE(PESDR1_UTLSET2, 0x11000000);
+
+ SDR_WRITE(PESDR1_HSSL0SET1, 0x35000000);
+ SDR_WRITE(PESDR1_HSSL1SET1, 0x35000000);
+ SDR_WRITE(PESDR1_HSSL2SET1, 0x35000000);
+ SDR_WRITE(PESDR1_HSSL3SET1, 0x35000000);
+
+ SDR_WRITE(PESDR1_RCSSET,
+ (SDR_READ(PESDR1_RCSSET) & ~(1 << 24 | 1 << 16)) | 1 << 12);
+ break;
+
+ case 2:
+ SDR_WRITE(PESDR2_DLPSET, PTYPE_ROOT_PORT << 20 | LNKW_X4 << 12);
+
+ SDR_WRITE(PESDR2_UTLSET1, 0x21222222);
+ SDR_WRITE(PESDR2_UTLSET2, 0x11000000);
+
+ SDR_WRITE(PESDR2_HSSL0SET1, 0x35000000);
+ SDR_WRITE(PESDR2_HSSL1SET1, 0x35000000);
+ SDR_WRITE(PESDR2_HSSL2SET1, 0x35000000);
+ SDR_WRITE(PESDR2_HSSL3SET1, 0x35000000);
+
+ SDR_WRITE(PESDR2_RCSSET,
+ (SDR_READ(PESDR2_RCSSET) & ~(1 << 24 | 1 << 16)) | 1 << 12);
+ break;
+ }
+
+ mdelay(1000);
+
+ switch (port) {
+ case 0: val = SDR_READ(PESDR0_RCSSTS); break;
+ case 1: val = SDR_READ(PESDR1_RCSSTS); break;
+ case 2: val = SDR_READ(PESDR2_RCSSTS); break;
+ }
+
+ if (!(val & (1 << 20)))
+ printk(KERN_INFO "PCIE%d: PGRST inactive\n", port);
+ else
+ printk(KERN_WARNING "PGRST for PCIE%d failed %08x\n", port, val);
+
+ switch (port) {
+ case 0: printk(KERN_INFO "PCIE0: LOOP %08x\n", SDR_READ(PESDR0_LOOP)); break;
+ case 1: printk(KERN_INFO "PCIE1: LOOP %08x\n", SDR_READ(PESDR1_LOOP)); break;
+ case 2: printk(KERN_INFO "PCIE2: LOOP %08x\n", SDR_READ(PESDR2_LOOP)); break;
+ }
+
+ /*
+ * Map UTL registers at 0xc_1000_0n00
+ */
+ switch (port) {
+ case 0:
+ mtdcr(DCRN_PEGPL_REGBAH(PCIE0), 0x0000000c);
+ mtdcr(DCRN_PEGPL_REGBAL(PCIE0), 0x10000000);
+ mtdcr(DCRN_PEGPL_REGMSK(PCIE0), 0x00007001);
+ mtdcr(DCRN_PEGPL_SPECIAL(PCIE0), 0x68782800);
+ break;
+
+ case 1:
+ mtdcr(DCRN_PEGPL_REGBAH(PCIE1), 0x0000000c);
+ mtdcr(DCRN_PEGPL_REGBAL(PCIE1), 0x10001000);
+ mtdcr(DCRN_PEGPL_REGMSK(PCIE1), 0x00007001);
+ mtdcr(DCRN_PEGPL_SPECIAL(PCIE1), 0x68782800);
+ break;
+
+ case 2:
+ mtdcr(DCRN_PEGPL_REGBAH(PCIE2), 0x0000000c);
+ mtdcr(DCRN_PEGPL_REGBAL(PCIE2), 0x10002000);
+ mtdcr(DCRN_PEGPL_REGMSK(PCIE2), 0x00007001);
+ mtdcr(DCRN_PEGPL_SPECIAL(PCIE2), 0x68782800);
+ }
+
+ utl_base = ioremap64(0xc10000000ull + 0x1000 * port, 0x100);
+
+ /*
+ * Set buffer allocations and then assert VRB and TXE.
+ */
+ out_be32(utl_base + PEUTL_OUTTR, 0x08000000);
+ out_be32(utl_base + PEUTL_INTR, 0x02000000);
+ out_be32(utl_base + PEUTL_OPDBSZ, 0x10000000);
+ out_be32(utl_base + PEUTL_PBBSZ, 0x53000000);
+ out_be32(utl_base + PEUTL_IPHBSZ, 0x08000000);
+ out_be32(utl_base + PEUTL_IPDBSZ, 0x10000000);
+ out_be32(utl_base + PEUTL_RCIRQEN, 0x00f00000);
+ out_be32(utl_base + PEUTL_PCTL, 0x80800066);
+
+ iounmap(utl_base);
+
+ /*
+ * We map PCI Express configuration access into the 512MB regions
+ * PCIE0: 0xc_4000_0000
+ * PCIE1: 0xc_8000_0000
+ * PCIE2: 0xc_c000_0000
+ */
+ switch (port) {
+ case 0:
+ mtdcr(DCRN_PEGPL_CFGBAH(PCIE0), 0x0000000c);
+ mtdcr(DCRN_PEGPL_CFGBAL(PCIE0), 0x40000000);
+ mtdcr(DCRN_PEGPL_CFGMSK(PCIE0), 0xe0000001); /* 512MB region, valid */
+ break;
+
+ case 1:
+ mtdcr(DCRN_PEGPL_CFGBAH(PCIE1), 0x0000000c);
+ mtdcr(DCRN_PEGPL_CFGBAL(PCIE1), 0x80000000);
+ mtdcr(DCRN_PEGPL_CFGMSK(PCIE1), 0xe0000001); /* 512MB region, valid */
+ break;
+
+ case 2:
+ mtdcr(DCRN_PEGPL_CFGBAH(PCIE2), 0x0000000c);
+ mtdcr(DCRN_PEGPL_CFGBAL(PCIE2), 0xc0000000);
+ mtdcr(DCRN_PEGPL_CFGMSK(PCIE2), 0xe0000001); /* 512MB region, valid */
+ break;
+ }
+
+ /*
+ * Check for VC0 active and assert RDY.
+ */
+ switch (port) {
+ case 0:
+ if (!(SDR_READ(PESDR0_RCSSTS) & (1 << 16)))
+ printk(KERN_WARNING "PCIE0: VC0 not active\n");
+ SDR_WRITE(PESDR0_RCSSET, SDR_READ(PESDR0_RCSSET) | 1 << 20);
+ break;
+ case 1:
+ if (!(SDR_READ(PESDR1_RCSSTS) & (1 << 16)))
+ printk(KERN_WARNING "PCIE0: VC0 not active\n");
+ SDR_WRITE(PESDR1_RCSSET, SDR_READ(PESDR1_RCSSET) | 1 << 20);
+ break;
+ case 2:
+ if (!(SDR_READ(PESDR2_RCSSTS) & (1 << 16)))
+ printk(KERN_WARNING "PCIE0: VC0 not active\n");
+ SDR_WRITE(PESDR2_RCSSET, SDR_READ(PESDR2_RCSSET) | 1 << 20);
+ break;
+ }
+
+#if 0
+ /* Dump all config regs */
+ for (i = 0x300; i <= 0x320; ++i)
+ printk("[%04x] 0x%08x\n", i, SDR_READ(i));
+ for (i = 0x340; i <= 0x353; ++i)
+ printk("[%04x] 0x%08x\n", i, SDR_READ(i));
+ for (i = 0x370; i <= 0x383; ++i)
+ printk("[%04x] 0x%08x\n", i, SDR_READ(i));
+ for (i = 0x3a0; i <= 0x3a2; ++i)
+ printk("[%04x] 0x%08x\n", i, SDR_READ(i));
+ for (i = 0x3c0; i <= 0x3c3; ++i)
+ printk("[%04x] 0x%08x\n", i, SDR_READ(i));
+#endif
+
+ mdelay(100);
+
+ return 0;
+}
+
+void ppc440spe_setup_pcie(struct pci_controller *hose, int port)
+{
+ void __iomem *mbase;
+
+ /*
+ * Map 16MB, which is enough for 4 bits of bus #
+ */
+ hose->cfg_data = ioremap64(0xc40000000ull + port * 0x40000000,
+ 1 << 24);
+ hose->ops = &pcie_pci_ops;
+
+ /*
+ * Set bus numbers on our root port
+ */
+ mbase = ioremap64(0xc50000000ull + port * 0x40000000, 4096);
+ out_8(mbase + PCI_PRIMARY_BUS, 0);
+ out_8(mbase + PCI_SECONDARY_BUS, 0);
+
+ /*
+ * Set up outbound translation to hose->mem_space from PLB
+ * addresses at an offset of 0xd_0000_0000. We set the low
+ * bits of the mask to 11 to turn off splitting into 8
+ * subregions and to enable the outbound translation.
+ */
+ out_le32(mbase + PECFG_POM0LAH, 0);
+ out_le32(mbase + PECFG_POM0LAL, hose->mem_space.start);
+
+ switch (port) {
+ case 0:
+ mtdcr(DCRN_PEGPL_OMR1BAH(PCIE0), 0x0000000d);
+ mtdcr(DCRN_PEGPL_OMR1BAL(PCIE0), hose->mem_space.start);
+ mtdcr(DCRN_PEGPL_OMR1MSKH(PCIE0), 0x7fffffff);
+ mtdcr(DCRN_PEGPL_OMR1MSKL(PCIE0),
+ ~(hose->mem_space.end - hose->mem_space.start) | 3);
+ break;
+ case 1:
+ mtdcr(DCRN_PEGPL_OMR1BAH(PCIE1), 0x0000000d);
+ mtdcr(DCRN_PEGPL_OMR1BAL(PCIE1), hose->mem_space.start);
+ mtdcr(DCRN_PEGPL_OMR1MSKH(PCIE1), 0x7fffffff);
+ mtdcr(DCRN_PEGPL_OMR1MSKL(PCIE1),
+ ~(hose->mem_space.end - hose->mem_space.start) | 3);
+
+ break;
+ case 2:
+ mtdcr(DCRN_PEGPL_OMR1BAH(PCIE2), 0x0000000d);
+ mtdcr(DCRN_PEGPL_OMR1BAL(PCIE2), hose->mem_space.start);
+ mtdcr(DCRN_PEGPL_OMR1MSKH(PCIE2), 0x7fffffff);
+ mtdcr(DCRN_PEGPL_OMR1MSKL(PCIE2),
+ ~(hose->mem_space.end - hose->mem_space.start) | 3);
+ break;
+ }
+
+ /* Set up 16GB inbound memory window at 0 */
+ out_le32(mbase + PCI_BASE_ADDRESS_0, 0);
+ out_le32(mbase + PCI_BASE_ADDRESS_1, 0);
+ out_le32(mbase + PECFG_BAR0HMPA, 0x7fffffc);
+ out_le32(mbase + PECFG_BAR0LMPA, 0);
+ out_le32(mbase + PECFG_PIM0LAL, 0);
+ out_le32(mbase + PECFG_PIM0LAH, 0);
+ out_le32(mbase + PECFG_PIMEN, 0x1);
+
+ /* Enable I/O, Mem, and Busmaster cycles */
+ out_le16(mbase + PCI_COMMAND,
+ in_le16(mbase + PCI_COMMAND) |
+ PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
+
+ iounmap(mbase);
+}
diff --git a/arch/ppc/syslib/ppc440spe_pcie.h b/arch/ppc/syslib/ppc440spe_pcie.h
new file mode 100644
index 000000000000..55b765ad3272
--- /dev/null
+++ b/arch/ppc/syslib/ppc440spe_pcie.h
@@ -0,0 +1,149 @@
+/*
+ * Copyright (c) 2005 Cisco Systems. All rights reserved.
+ * Roland Dreier <rolandd@cisco.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.
+ */
+
+#ifndef __PPC_SYSLIB_PPC440SPE_PCIE_H
+#define __PPC_SYSLIB_PPC440SPE_PCIE_H
+
+#define DCRN_SDR0_CFGADDR 0x00e
+#define DCRN_SDR0_CFGDATA 0x00f
+
+#define DCRN_PCIE0_BASE 0x100
+#define DCRN_PCIE1_BASE 0x120
+#define DCRN_PCIE2_BASE 0x140
+#define PCIE0 DCRN_PCIE0_BASE
+#define PCIE1 DCRN_PCIE1_BASE
+#define PCIE2 DCRN_PCIE2_BASE
+
+#define DCRN_PEGPL_CFGBAH(base) (base + 0x00)
+#define DCRN_PEGPL_CFGBAL(base) (base + 0x01)
+#define DCRN_PEGPL_CFGMSK(base) (base + 0x02)
+#define DCRN_PEGPL_MSGBAH(base) (base + 0x03)
+#define DCRN_PEGPL_MSGBAL(base) (base + 0x04)
+#define DCRN_PEGPL_MSGMSK(base) (base + 0x05)
+#define DCRN_PEGPL_OMR1BAH(base) (base + 0x06)
+#define DCRN_PEGPL_OMR1BAL(base) (base + 0x07)
+#define DCRN_PEGPL_OMR1MSKH(base) (base + 0x08)
+#define DCRN_PEGPL_OMR1MSKL(base) (base + 0x09)
+#define DCRN_PEGPL_REGBAH(base) (base + 0x12)
+#define DCRN_PEGPL_REGBAL(base) (base + 0x13)
+#define DCRN_PEGPL_REGMSK(base) (base + 0x14)
+#define DCRN_PEGPL_SPECIAL(base) (base + 0x15)
+
+/*
+ * System DCRs (SDRs)
+ */
+#define PESDR0_PLLLCT1 0x03a0
+#define PESDR0_PLLLCT2 0x03a1
+#define PESDR0_PLLLCT3 0x03a2
+
+#define PESDR0_UTLSET1 0x0300
+#define PESDR0_UTLSET2 0x0301
+#define PESDR0_DLPSET 0x0302
+#define PESDR0_LOOP 0x0303
+#define PESDR0_RCSSET 0x0304
+#define PESDR0_RCSSTS 0x0305
+#define PESDR0_HSSL0SET1 0x0306
+#define PESDR0_HSSL0SET2 0x0307
+#define PESDR0_HSSL0STS 0x0308
+#define PESDR0_HSSL1SET1 0x0309
+#define PESDR0_HSSL1SET2 0x030a
+#define PESDR0_HSSL1STS 0x030b
+#define PESDR0_HSSL2SET1 0x030c
+#define PESDR0_HSSL2SET2 0x030d
+#define PESDR0_HSSL2STS 0x030e
+#define PESDR0_HSSL3SET1 0x030f
+#define PESDR0_HSSL3SET2 0x0310
+#define PESDR0_HSSL3STS 0x0311
+#define PESDR0_HSSL4SET1 0x0312
+#define PESDR0_HSSL4SET2 0x0313
+#define PESDR0_HSSL4STS 0x0314
+#define PESDR0_HSSL5SET1 0x0315
+#define PESDR0_HSSL5SET2 0x0316
+#define PESDR0_HSSL5STS 0x0317
+#define PESDR0_HSSL6SET1 0x0318
+#define PESDR0_HSSL6SET2 0x0319
+#define PESDR0_HSSL6STS 0x031a
+#define PESDR0_HSSL7SET1 0x031b
+#define PESDR0_HSSL7SET2 0x031c
+#define PESDR0_HSSL7STS 0x031d
+#define PESDR0_HSSCTLSET 0x031e
+#define PESDR0_LANE_ABCD 0x031f
+#define PESDR0_LANE_EFGH 0x0320
+
+#define PESDR1_UTLSET1 0x0340
+#define PESDR1_UTLSET2 0x0341
+#define PESDR1_DLPSET 0x0342
+#define PESDR1_LOOP 0x0343
+#define PESDR1_RCSSET 0x0344
+#define PESDR1_RCSSTS 0x0345
+#define PESDR1_HSSL0SET1 0x0346
+#define PESDR1_HSSL0SET2 0x0347
+#define PESDR1_HSSL0STS 0x0348
+#define PESDR1_HSSL1SET1 0x0349
+#define PESDR1_HSSL1SET2 0x034a
+#define PESDR1_HSSL1STS 0x034b
+#define PESDR1_HSSL2SET1 0x034c
+#define PESDR1_HSSL2SET2 0x034d
+#define PESDR1_HSSL2STS 0x034e
+#define PESDR1_HSSL3SET1 0x034f
+#define PESDR1_HSSL3SET2 0x0350
+#define PESDR1_HSSL3STS 0x0351
+#define PESDR1_HSSCTLSET 0x0352
+#define PESDR1_LANE_ABCD 0x0353
+
+#define PESDR2_UTLSET1 0x0370
+#define PESDR2_UTLSET2 0x0371
+#define PESDR2_DLPSET 0x0372
+#define PESDR2_LOOP 0x0373
+#define PESDR2_RCSSET 0x0374
+#define PESDR2_RCSSTS 0x0375
+#define PESDR2_HSSL0SET1 0x0376
+#define PESDR2_HSSL0SET2 0x0377
+#define PESDR2_HSSL0STS 0x0378
+#define PESDR2_HSSL1SET1 0x0379
+#define PESDR2_HSSL1SET2 0x037a
+#define PESDR2_HSSL1STS 0x037b
+#define PESDR2_HSSL2SET1 0x037c
+#define PESDR2_HSSL2SET2 0x037d
+#define PESDR2_HSSL2STS 0x037e
+#define PESDR2_HSSL3SET1 0x037f
+#define PESDR2_HSSL3SET2 0x0380
+#define PESDR2_HSSL3STS 0x0381
+#define PESDR2_HSSCTLSET 0x0382
+#define PESDR2_LANE_ABCD 0x0383
+
+/*
+ * UTL register offsets
+ */
+#define PEUTL_PBBSZ 0x20
+#define PEUTL_OPDBSZ 0x68
+#define PEUTL_IPHBSZ 0x70
+#define PEUTL_IPDBSZ 0x78
+#define PEUTL_OUTTR 0x90
+#define PEUTL_INTR 0x98
+#define PEUTL_PCTL 0xa0
+#define PEUTL_RCIRQEN 0xb8
+
+/*
+ * Config space register offsets
+ */
+#define PECFG_BAR0LMPA 0x210
+#define PECFG_BAR0HMPA 0x214
+#define PECFG_PIMEN 0x33c
+#define PECFG_PIM0LAL 0x340
+#define PECFG_PIM0LAH 0x344
+#define PECFG_POM0LAL 0x380
+#define PECFG_POM0LAH 0x384
+
+int ppc440spe_init_pcie(void);
+int ppc440spe_init_pcie_rootport(int port);
+void ppc440spe_setup_pcie(struct pci_controller *hose, int port);
+
+#endif /* __PPC_SYSLIB_PPC440SPE_PCIE_H */
diff --git a/arch/ppc/syslib/ppc4xx_pic.c b/arch/ppc/syslib/ppc4xx_pic.c
index 40086212b9c3..aa4165144ec2 100644
--- a/arch/ppc/syslib/ppc4xx_pic.c
+++ b/arch/ppc/syslib/ppc4xx_pic.c
@@ -25,6 +25,7 @@
#include <asm/system.h>
#include <asm/irq.h>
#include <asm/ppc4xx_pic.h>
+#include <asm/machdep.h>
/* See comment in include/arch-ppc/ppc4xx_pic.h
* for more info about these two variables
@@ -37,6 +38,7 @@ extern unsigned char ppc4xx_uic_ext_irq_cfg[] __attribute__ ((weak));
#define IRQ_MASK_UICx(irq) (1 << (31 - ((irq) & 0x1f)))
#define IRQ_MASK_UIC1(irq) IRQ_MASK_UICx(irq)
#define IRQ_MASK_UIC2(irq) IRQ_MASK_UICx(irq)
+#define IRQ_MASK_UIC3(irq) IRQ_MASK_UICx(irq)
#define UIC_HANDLERS(n) \
static void ppc4xx_uic##n##_enable(unsigned int irq) \
@@ -87,7 +89,38 @@ static void ppc4xx_uic##n##_end(unsigned int irq) \
.end = ppc4xx_uic##n##_end, \
} \
-#if NR_UICS == 3
+#if NR_UICS == 4
+#define ACK_UIC0_PARENT
+#define ACK_UIC1_PARENT mtdcr(DCRN_UIC_SR(UIC0), UIC0_UIC1NC);
+#define ACK_UIC2_PARENT mtdcr(DCRN_UIC_SR(UIC0), UIC0_UIC2NC);
+#define ACK_UIC3_PARENT mtdcr(DCRN_UIC_SR(UIC0), UIC0_UIC3NC);
+UIC_HANDLERS(0);
+UIC_HANDLERS(1);
+UIC_HANDLERS(2);
+UIC_HANDLERS(3);
+
+static int ppc4xx_pic_get_irq(struct pt_regs *regs)
+{
+ u32 uic0 = mfdcr(DCRN_UIC_MSR(UIC0));
+ if (uic0 & UIC0_UIC1NC)
+ return 64 - ffs(mfdcr(DCRN_UIC_MSR(UIC1)));
+ else if (uic0 & UIC0_UIC2NC)
+ return 96 - ffs(mfdcr(DCRN_UIC_MSR(UIC2)));
+ else if (uic0 & UIC0_UIC3NC)
+ return 128 - ffs(mfdcr(DCRN_UIC_MSR(UIC3)));
+ else
+ return uic0 ? 32 - ffs(uic0) : -1;
+}
+
+static void __init ppc4xx_pic_impl_init(void)
+{
+ /* Enable cascade interrupts in UIC0 */
+ ppc_cached_irq_mask[0] |= UIC0_UIC1NC | UIC0_UIC2NC | UIC0_UIC3NC;
+ mtdcr(DCRN_UIC_SR(UIC0), UIC0_UIC1NC | UIC0_UIC2NC | UIC0_UIC3NC);
+ mtdcr(DCRN_UIC_ER(UIC0), ppc_cached_irq_mask[0]);
+}
+
+#elif NR_UICS == 3
#define ACK_UIC0_PARENT mtdcr(DCRN_UIC_SR(UICB), UICB_UIC0NC);
#define ACK_UIC1_PARENT mtdcr(DCRN_UIC_SR(UICB), UICB_UIC1NC);
#define ACK_UIC2_PARENT mtdcr(DCRN_UIC_SR(UICB), UICB_UIC2NC);
@@ -169,6 +202,9 @@ static struct ppc4xx_uic_impl {
{ .decl = DECLARE_UIC(1), .base = UIC1 },
#if NR_UICS > 2
{ .decl = DECLARE_UIC(2), .base = UIC2 },
+#if NR_UICS > 3
+ { .decl = DECLARE_UIC(3), .base = UIC3 },
+#endif
#endif
#endif
};
diff --git a/arch/ppc/syslib/ppc4xx_setup.c b/arch/ppc/syslib/ppc4xx_setup.c
index bf83240689dc..e83a83fd95e1 100644
--- a/arch/ppc/syslib/ppc4xx_setup.c
+++ b/arch/ppc/syslib/ppc4xx_setup.c
@@ -278,7 +278,7 @@ ppc4xx_init(unsigned long r3, unsigned long r4, unsigned long r5,
#endif /* defined(CONFIG_PCI) && defined(CONFIG_IDE) */
}
-/* Called from MachineCheckException */
+/* Called from machine_check_exception */
void platform_machine_check(struct pt_regs *regs)
{
#if defined(DCRN_PLB0_BEAR)
diff --git a/arch/ppc/syslib/ppc83xx_setup.c b/arch/ppc/syslib/ppc83xx_setup.c
index 890484e576e7..4da168a6ad03 100644
--- a/arch/ppc/syslib/ppc83xx_setup.c
+++ b/arch/ppc/syslib/ppc83xx_setup.c
@@ -40,6 +40,7 @@
#include <asm/ppc_sys.h>
#include <asm/kgdb.h>
#include <asm/delay.h>
+#include <asm/machdep.h>
#include <syslib/ppc83xx_setup.h>
#if defined(CONFIG_PCI)
diff --git a/arch/ppc/syslib/ppc85xx_rio.c b/arch/ppc/syslib/ppc85xx_rio.c
new file mode 100644
index 000000000000..297f3b549177
--- /dev/null
+++ b/arch/ppc/syslib/ppc85xx_rio.c
@@ -0,0 +1,938 @@
+/*
+ * MPC85xx RapidIO support
+ *
+ * Copyright 2005 MontaVista Software, Inc.
+ * Matt Porter <mporter@kernel.crashing.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/config.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/dma-mapping.h>
+#include <linux/interrupt.h>
+#include <linux/rio.h>
+#include <linux/rio_drv.h>
+
+#include <asm/io.h>
+
+#define RIO_REGS_BASE (CCSRBAR + 0xc0000)
+#define RIO_ATMU_REGS_OFFSET 0x10c00
+#define RIO_MSG_REGS_OFFSET 0x11000
+#define RIO_MAINT_WIN_SIZE 0x400000
+#define RIO_DBELL_WIN_SIZE 0x1000
+
+#define RIO_MSG_OMR_MUI 0x00000002
+#define RIO_MSG_OSR_TE 0x00000080
+#define RIO_MSG_OSR_QOI 0x00000020
+#define RIO_MSG_OSR_QFI 0x00000010
+#define RIO_MSG_OSR_MUB 0x00000004
+#define RIO_MSG_OSR_EOMI 0x00000002
+#define RIO_MSG_OSR_QEI 0x00000001
+
+#define RIO_MSG_IMR_MI 0x00000002
+#define RIO_MSG_ISR_TE 0x00000080
+#define RIO_MSG_ISR_QFI 0x00000010
+#define RIO_MSG_ISR_DIQI 0x00000001
+
+#define RIO_MSG_DESC_SIZE 32
+#define RIO_MSG_BUFFER_SIZE 4096
+#define RIO_MIN_TX_RING_SIZE 2
+#define RIO_MAX_TX_RING_SIZE 2048
+#define RIO_MIN_RX_RING_SIZE 2
+#define RIO_MAX_RX_RING_SIZE 2048
+
+#define DOORBELL_DMR_DI 0x00000002
+#define DOORBELL_DSR_TE 0x00000080
+#define DOORBELL_DSR_QFI 0x00000010
+#define DOORBELL_DSR_DIQI 0x00000001
+#define DOORBELL_TID_OFFSET 0x03
+#define DOORBELL_SID_OFFSET 0x05
+#define DOORBELL_INFO_OFFSET 0x06
+
+#define DOORBELL_MESSAGE_SIZE 0x08
+#define DBELL_SID(x) (*(u8 *)(x + DOORBELL_SID_OFFSET))
+#define DBELL_TID(x) (*(u8 *)(x + DOORBELL_TID_OFFSET))
+#define DBELL_INF(x) (*(u16 *)(x + DOORBELL_INFO_OFFSET))
+
+#define is_power_of_2(x) (((x) & ((x) - 1)) == 0)
+
+struct rio_atmu_regs {
+ u32 rowtar;
+ u32 pad1;
+ u32 rowbar;
+ u32 pad2;
+ u32 rowar;
+ u32 pad3[3];
+};
+
+struct rio_msg_regs {
+ u32 omr;
+ u32 osr;
+ u32 pad1;
+ u32 odqdpar;
+ u32 pad2;
+ u32 osar;
+ u32 odpr;
+ u32 odatr;
+ u32 odcr;
+ u32 pad3;
+ u32 odqepar;
+ u32 pad4[13];
+ u32 imr;
+ u32 isr;
+ u32 pad5;
+ u32 ifqdpar;
+ u32 pad6;
+ u32 ifqepar;
+ u32 pad7[250];
+ u32 dmr;
+ u32 dsr;
+ u32 pad8;
+ u32 dqdpar;
+ u32 pad9;
+ u32 dqepar;
+ u32 pad10[26];
+ u32 pwmr;
+ u32 pwsr;
+ u32 pad11;
+ u32 pwqbar;
+};
+
+struct rio_tx_desc {
+ u32 res1;
+ u32 saddr;
+ u32 dport;
+ u32 dattr;
+ u32 res2;
+ u32 res3;
+ u32 dwcnt;
+ u32 res4;
+};
+
+static u32 regs_win;
+static struct rio_atmu_regs *atmu_regs;
+static struct rio_atmu_regs *maint_atmu_regs;
+static struct rio_atmu_regs *dbell_atmu_regs;
+static u32 dbell_win;
+static u32 maint_win;
+static struct rio_msg_regs *msg_regs;
+
+static struct rio_dbell_ring {
+ void *virt;
+ dma_addr_t phys;
+} dbell_ring;
+
+static struct rio_msg_tx_ring {
+ void *virt;
+ dma_addr_t phys;
+ void *virt_buffer[RIO_MAX_TX_RING_SIZE];
+ dma_addr_t phys_buffer[RIO_MAX_TX_RING_SIZE];
+ int tx_slot;
+ int size;
+ void *dev_id;
+} msg_tx_ring;
+
+static struct rio_msg_rx_ring {
+ void *virt;
+ dma_addr_t phys;
+ void *virt_buffer[RIO_MAX_RX_RING_SIZE];
+ int rx_slot;
+ int size;
+ void *dev_id;
+} msg_rx_ring;
+
+/**
+ * mpc85xx_rio_doorbell_send - Send a MPC85xx doorbell message
+ * @index: ID of RapidIO interface
+ * @destid: Destination ID of target device
+ * @data: 16-bit info field of RapidIO doorbell message
+ *
+ * Sends a MPC85xx doorbell message. Returns %0 on success or
+ * %-EINVAL on failure.
+ */
+static int mpc85xx_rio_doorbell_send(int index, u16 destid, u16 data)
+{
+ pr_debug("mpc85xx_doorbell_send: index %d destid %4.4x data %4.4x\n",
+ index, destid, data);
+ out_be32((void *)&dbell_atmu_regs->rowtar, destid << 22);
+ out_be16((void *)(dbell_win), data);
+
+ return 0;
+}
+
+/**
+ * mpc85xx_local_config_read - Generate a MPC85xx local config space read
+ * @index: ID of RapdiIO interface
+ * @offset: Offset into configuration space
+ * @len: Length (in bytes) of the maintenance transaction
+ * @data: Value to be read into
+ *
+ * Generates a MPC85xx local configuration space read. Returns %0 on
+ * success or %-EINVAL on failure.
+ */
+static int mpc85xx_local_config_read(int index, u32 offset, int len, u32 * data)
+{
+ pr_debug("mpc85xx_local_config_read: index %d offset %8.8x\n", index,
+ offset);
+ *data = in_be32((void *)(regs_win + offset));
+
+ return 0;
+}
+
+/**
+ * mpc85xx_local_config_write - Generate a MPC85xx local config space write
+ * @index: ID of RapdiIO interface
+ * @offset: Offset into configuration space
+ * @len: Length (in bytes) of the maintenance transaction
+ * @data: Value to be written
+ *
+ * Generates a MPC85xx local configuration space write. Returns %0 on
+ * success or %-EINVAL on failure.
+ */
+static int mpc85xx_local_config_write(int index, u32 offset, int len, u32 data)
+{
+ pr_debug
+ ("mpc85xx_local_config_write: index %d offset %8.8x data %8.8x\n",
+ index, offset, data);
+ out_be32((void *)(regs_win + offset), data);
+
+ return 0;
+}
+
+/**
+ * mpc85xx_rio_config_read - Generate a MPC85xx read maintenance transaction
+ * @index: ID of RapdiIO interface
+ * @destid: Destination ID of transaction
+ * @hopcount: Number of hops to target device
+ * @offset: Offset into configuration space
+ * @len: Length (in bytes) of the maintenance transaction
+ * @val: Location to be read into
+ *
+ * Generates a MPC85xx read maintenance transaction. Returns %0 on
+ * success or %-EINVAL on failure.
+ */
+static int
+mpc85xx_rio_config_read(int index, u16 destid, u8 hopcount, u32 offset, int len,
+ u32 * val)
+{
+ u8 *data;
+
+ pr_debug
+ ("mpc85xx_rio_config_read: index %d destid %d hopcount %d offset %8.8x len %d\n",
+ index, destid, hopcount, offset, len);
+ out_be32((void *)&maint_atmu_regs->rowtar,
+ (destid << 22) | (hopcount << 12) | ((offset & ~0x3) >> 9));
+
+ data = (u8 *) maint_win + offset;
+ switch (len) {
+ case 1:
+ *val = in_8((u8 *) data);
+ break;
+ case 2:
+ *val = in_be16((u16 *) data);
+ break;
+ default:
+ *val = in_be32((u32 *) data);
+ break;
+ }
+
+ return 0;
+}
+
+/**
+ * mpc85xx_rio_config_write - Generate a MPC85xx write maintenance transaction
+ * @index: ID of RapdiIO interface
+ * @destid: Destination ID of transaction
+ * @hopcount: Number of hops to target device
+ * @offset: Offset into configuration space
+ * @len: Length (in bytes) of the maintenance transaction
+ * @val: Value to be written
+ *
+ * Generates an MPC85xx write maintenance transaction. Returns %0 on
+ * success or %-EINVAL on failure.
+ */
+static int
+mpc85xx_rio_config_write(int index, u16 destid, u8 hopcount, u32 offset,
+ int len, u32 val)
+{
+ u8 *data;
+ pr_debug
+ ("mpc85xx_rio_config_write: index %d destid %d hopcount %d offset %8.8x len %d val %8.8x\n",
+ index, destid, hopcount, offset, len, val);
+ out_be32((void *)&maint_atmu_regs->rowtar,
+ (destid << 22) | (hopcount << 12) | ((offset & ~0x3) >> 9));
+
+ data = (u8 *) maint_win + offset;
+ switch (len) {
+ case 1:
+ out_8((u8 *) data, val);
+ break;
+ case 2:
+ out_be16((u16 *) data, val);
+ break;
+ default:
+ out_be32((u32 *) data, val);
+ break;
+ }
+
+ return 0;
+}
+
+/**
+ * rio_hw_add_outb_message - Add message to the MPC85xx outbound message queue
+ * @mport: Master port with outbound message queue
+ * @rdev: Target of outbound message
+ * @mbox: Outbound mailbox
+ * @buffer: Message to add to outbound queue
+ * @len: Length of message
+ *
+ * Adds the @buffer message to the MPC85xx outbound message queue. Returns
+ * %0 on success or %-EINVAL on failure.
+ */
+int
+rio_hw_add_outb_message(struct rio_mport *mport, struct rio_dev *rdev, int mbox,
+ void *buffer, size_t len)
+{
+ u32 omr;
+ struct rio_tx_desc *desc =
+ (struct rio_tx_desc *)msg_tx_ring.virt + msg_tx_ring.tx_slot;
+ int ret = 0;
+
+ pr_debug
+ ("RIO: rio_hw_add_outb_message(): destid %4.4x mbox %d buffer %8.8x len %8.8x\n",
+ rdev->destid, mbox, (int)buffer, len);
+
+ if ((len < 8) || (len > RIO_MAX_MSG_SIZE)) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ /* Copy and clear rest of buffer */
+ memcpy(msg_tx_ring.virt_buffer[msg_tx_ring.tx_slot], buffer, len);
+ if (len < (RIO_MAX_MSG_SIZE - 4))
+ memset((void *)((u32) msg_tx_ring.
+ virt_buffer[msg_tx_ring.tx_slot] + len), 0,
+ RIO_MAX_MSG_SIZE - len);
+
+ /* Set mbox field for message */
+ desc->dport = mbox & 0x3;
+
+ /* Enable EOMI interrupt, set priority, and set destid */
+ desc->dattr = 0x28000000 | (rdev->destid << 2);
+
+ /* Set transfer size aligned to next power of 2 (in double words) */
+ desc->dwcnt = is_power_of_2(len) ? len : 1 << get_bitmask_order(len);
+
+ /* Set snooping and source buffer address */
+ desc->saddr = 0x00000004 | msg_tx_ring.phys_buffer[msg_tx_ring.tx_slot];
+
+ /* Increment enqueue pointer */
+ omr = in_be32((void *)&msg_regs->omr);
+ out_be32((void *)&msg_regs->omr, omr | RIO_MSG_OMR_MUI);
+
+ /* Go to next descriptor */
+ if (++msg_tx_ring.tx_slot == msg_tx_ring.size)
+ msg_tx_ring.tx_slot = 0;
+
+ out:
+ return ret;
+}
+
+EXPORT_SYMBOL_GPL(rio_hw_add_outb_message);
+
+/**
+ * mpc85xx_rio_tx_handler - MPC85xx outbound message interrupt handler
+ * @irq: Linux interrupt number
+ * @dev_instance: Pointer to interrupt-specific data
+ * @regs: Register context
+ *
+ * Handles outbound message interrupts. Executes a register outbound
+ * mailbox event handler and acks the interrupt occurence.
+ */
+static irqreturn_t
+mpc85xx_rio_tx_handler(int irq, void *dev_instance, struct pt_regs *regs)
+{
+ int osr;
+ struct rio_mport *port = (struct rio_mport *)dev_instance;
+
+ osr = in_be32((void *)&msg_regs->osr);
+
+ if (osr & RIO_MSG_OSR_TE) {
+ pr_info("RIO: outbound message transmission error\n");
+ out_be32((void *)&msg_regs->osr, RIO_MSG_OSR_TE);
+ goto out;
+ }
+
+ if (osr & RIO_MSG_OSR_QOI) {
+ pr_info("RIO: outbound message queue overflow\n");
+ out_be32((void *)&msg_regs->osr, RIO_MSG_OSR_QOI);
+ goto out;
+ }
+
+ if (osr & RIO_MSG_OSR_EOMI) {
+ u32 dqp = in_be32((void *)&msg_regs->odqdpar);
+ int slot = (dqp - msg_tx_ring.phys) >> 5;
+ port->outb_msg[0].mcback(port, msg_tx_ring.dev_id, -1, slot);
+
+ /* Ack the end-of-message interrupt */
+ out_be32((void *)&msg_regs->osr, RIO_MSG_OSR_EOMI);
+ }
+
+ out:
+ return IRQ_HANDLED;
+}
+
+/**
+ * rio_open_outb_mbox - Initialize MPC85xx outbound mailbox
+ * @mport: Master port implementing the outbound message unit
+ * @dev_id: Device specific pointer to pass on event
+ * @mbox: Mailbox to open
+ * @entries: Number of entries in the outbound mailbox ring
+ *
+ * Initializes buffer ring, request the outbound message interrupt,
+ * and enables the outbound message unit. Returns %0 on success and
+ * %-EINVAL or %-ENOMEM on failure.
+ */
+int rio_open_outb_mbox(struct rio_mport *mport, void *dev_id, int mbox, int entries)
+{
+ int i, j, rc = 0;
+
+ if ((entries < RIO_MIN_TX_RING_SIZE) ||
+ (entries > RIO_MAX_TX_RING_SIZE) || (!is_power_of_2(entries))) {
+ rc = -EINVAL;
+ goto out;
+ }
+
+ /* Initialize shadow copy ring */
+ msg_tx_ring.dev_id = dev_id;
+ msg_tx_ring.size = entries;
+
+ for (i = 0; i < msg_tx_ring.size; i++) {
+ if (!
+ (msg_tx_ring.virt_buffer[i] =
+ dma_alloc_coherent(NULL, RIO_MSG_BUFFER_SIZE,
+ &msg_tx_ring.phys_buffer[i],
+ GFP_KERNEL))) {
+ rc = -ENOMEM;
+ for (j = 0; j < msg_tx_ring.size; j++)
+ if (msg_tx_ring.virt_buffer[j])
+ dma_free_coherent(NULL,
+ RIO_MSG_BUFFER_SIZE,
+ msg_tx_ring.
+ virt_buffer[j],
+ msg_tx_ring.
+ phys_buffer[j]);
+ goto out;
+ }
+ }
+
+ /* Initialize outbound message descriptor ring */
+ if (!(msg_tx_ring.virt = dma_alloc_coherent(NULL,
+ msg_tx_ring.size *
+ RIO_MSG_DESC_SIZE,
+ &msg_tx_ring.phys,
+ GFP_KERNEL))) {
+ rc = -ENOMEM;
+ goto out_dma;
+ }
+ memset(msg_tx_ring.virt, 0, msg_tx_ring.size * RIO_MSG_DESC_SIZE);
+ msg_tx_ring.tx_slot = 0;
+
+ /* Point dequeue/enqueue pointers at first entry in ring */
+ out_be32((void *)&msg_regs->odqdpar, msg_tx_ring.phys);
+ out_be32((void *)&msg_regs->odqepar, msg_tx_ring.phys);
+
+ /* Configure for snooping */
+ out_be32((void *)&msg_regs->osar, 0x00000004);
+
+ /* Clear interrupt status */
+ out_be32((void *)&msg_regs->osr, 0x000000b3);
+
+ /* Hook up outbound message handler */
+ if ((rc =
+ request_irq(MPC85xx_IRQ_RIO_TX, mpc85xx_rio_tx_handler, 0,
+ "msg_tx", (void *)mport)) < 0)
+ goto out_irq;
+
+ /*
+ * Configure outbound message unit
+ * Snooping
+ * Interrupts (all enabled, except QEIE)
+ * Chaining mode
+ * Disable
+ */
+ out_be32((void *)&msg_regs->omr, 0x00100220);
+
+ /* Set number of entries */
+ out_be32((void *)&msg_regs->omr,
+ in_be32((void *)&msg_regs->omr) |
+ ((get_bitmask_order(entries) - 2) << 12));
+
+ /* Now enable the unit */
+ out_be32((void *)&msg_regs->omr, in_be32((void *)&msg_regs->omr) | 0x1);
+
+ out:
+ return rc;
+
+ out_irq:
+ dma_free_coherent(NULL, msg_tx_ring.size * RIO_MSG_DESC_SIZE,
+ msg_tx_ring.virt, msg_tx_ring.phys);
+
+ out_dma:
+ for (i = 0; i < msg_tx_ring.size; i++)
+ dma_free_coherent(NULL, RIO_MSG_BUFFER_SIZE,
+ msg_tx_ring.virt_buffer[i],
+ msg_tx_ring.phys_buffer[i]);
+
+ return rc;
+}
+
+/**
+ * rio_close_outb_mbox - Shut down MPC85xx outbound mailbox
+ * @mport: Master port implementing the outbound message unit
+ * @mbox: Mailbox to close
+ *
+ * Disables the outbound message unit, free all buffers, and
+ * frees the outbound message interrupt.
+ */
+void rio_close_outb_mbox(struct rio_mport *mport, int mbox)
+{
+ /* Disable inbound message unit */
+ out_be32((void *)&msg_regs->omr, 0);
+
+ /* Free ring */
+ dma_free_coherent(NULL, msg_tx_ring.size * RIO_MSG_DESC_SIZE,
+ msg_tx_ring.virt, msg_tx_ring.phys);
+
+ /* Free interrupt */
+ free_irq(MPC85xx_IRQ_RIO_TX, (void *)mport);
+}
+
+/**
+ * mpc85xx_rio_rx_handler - MPC85xx inbound message interrupt handler
+ * @irq: Linux interrupt number
+ * @dev_instance: Pointer to interrupt-specific data
+ * @regs: Register context
+ *
+ * Handles inbound message interrupts. Executes a registered inbound
+ * mailbox event handler and acks the interrupt occurence.
+ */
+static irqreturn_t
+mpc85xx_rio_rx_handler(int irq, void *dev_instance, struct pt_regs *regs)
+{
+ int isr;
+ struct rio_mport *port = (struct rio_mport *)dev_instance;
+
+ isr = in_be32((void *)&msg_regs->isr);
+
+ if (isr & RIO_MSG_ISR_TE) {
+ pr_info("RIO: inbound message reception error\n");
+ out_be32((void *)&msg_regs->isr, RIO_MSG_ISR_TE);
+ goto out;
+ }
+
+ /* XXX Need to check/dispatch until queue empty */
+ if (isr & RIO_MSG_ISR_DIQI) {
+ /*
+ * We implement *only* mailbox 0, but can receive messages
+ * for any mailbox/letter to that mailbox destination. So,
+ * make the callback with an unknown/invalid mailbox number
+ * argument.
+ */
+ port->inb_msg[0].mcback(port, msg_rx_ring.dev_id, -1, -1);
+
+ /* Ack the queueing interrupt */
+ out_be32((void *)&msg_regs->isr, RIO_MSG_ISR_DIQI);
+ }
+
+ out:
+ return IRQ_HANDLED;
+}
+
+/**
+ * rio_open_inb_mbox - Initialize MPC85xx inbound mailbox
+ * @mport: Master port implementing the inbound message unit
+ * @dev_id: Device specific pointer to pass on event
+ * @mbox: Mailbox to open
+ * @entries: Number of entries in the inbound mailbox ring
+ *
+ * Initializes buffer ring, request the inbound message interrupt,
+ * and enables the inbound message unit. Returns %0 on success
+ * and %-EINVAL or %-ENOMEM on failure.
+ */
+int rio_open_inb_mbox(struct rio_mport *mport, void *dev_id, int mbox, int entries)
+{
+ int i, rc = 0;
+
+ if ((entries < RIO_MIN_RX_RING_SIZE) ||
+ (entries > RIO_MAX_RX_RING_SIZE) || (!is_power_of_2(entries))) {
+ rc = -EINVAL;
+ goto out;
+ }
+
+ /* Initialize client buffer ring */
+ msg_rx_ring.dev_id = dev_id;
+ msg_rx_ring.size = entries;
+ msg_rx_ring.rx_slot = 0;
+ for (i = 0; i < msg_rx_ring.size; i++)
+ msg_rx_ring.virt_buffer[i] = NULL;
+
+ /* Initialize inbound message ring */
+ if (!(msg_rx_ring.virt = dma_alloc_coherent(NULL,
+ msg_rx_ring.size *
+ RIO_MAX_MSG_SIZE,
+ &msg_rx_ring.phys,
+ GFP_KERNEL))) {
+ rc = -ENOMEM;
+ goto out;
+ }
+
+ /* Point dequeue/enqueue pointers at first entry in ring */
+ out_be32((void *)&msg_regs->ifqdpar, (u32) msg_rx_ring.phys);
+ out_be32((void *)&msg_regs->ifqepar, (u32) msg_rx_ring.phys);
+
+ /* Clear interrupt status */
+ out_be32((void *)&msg_regs->isr, 0x00000091);
+
+ /* Hook up inbound message handler */
+ if ((rc =
+ request_irq(MPC85xx_IRQ_RIO_RX, mpc85xx_rio_rx_handler, 0,
+ "msg_rx", (void *)mport)) < 0) {
+ dma_free_coherent(NULL, RIO_MSG_BUFFER_SIZE,
+ msg_tx_ring.virt_buffer[i],
+ msg_tx_ring.phys_buffer[i]);
+ goto out;
+ }
+
+ /*
+ * Configure inbound message unit:
+ * Snooping
+ * 4KB max message size
+ * Unmask all interrupt sources
+ * Disable
+ */
+ out_be32((void *)&msg_regs->imr, 0x001b0060);
+
+ /* Set number of queue entries */
+ out_be32((void *)&msg_regs->imr,
+ in_be32((void *)&msg_regs->imr) |
+ ((get_bitmask_order(entries) - 2) << 12));
+
+ /* Now enable the unit */
+ out_be32((void *)&msg_regs->imr, in_be32((void *)&msg_regs->imr) | 0x1);
+
+ out:
+ return rc;
+}
+
+/**
+ * rio_close_inb_mbox - Shut down MPC85xx inbound mailbox
+ * @mport: Master port implementing the inbound message unit
+ * @mbox: Mailbox to close
+ *
+ * Disables the inbound message unit, free all buffers, and
+ * frees the inbound message interrupt.
+ */
+void rio_close_inb_mbox(struct rio_mport *mport, int mbox)
+{
+ /* Disable inbound message unit */
+ out_be32((void *)&msg_regs->imr, 0);
+
+ /* Free ring */
+ dma_free_coherent(NULL, msg_rx_ring.size * RIO_MAX_MSG_SIZE,
+ msg_rx_ring.virt, msg_rx_ring.phys);
+
+ /* Free interrupt */
+ free_irq(MPC85xx_IRQ_RIO_RX, (void *)mport);
+}
+
+/**
+ * rio_hw_add_inb_buffer - Add buffer to the MPC85xx inbound message queue
+ * @mport: Master port implementing the inbound message unit
+ * @mbox: Inbound mailbox number
+ * @buf: Buffer to add to inbound queue
+ *
+ * Adds the @buf buffer to the MPC85xx inbound message queue. Returns
+ * %0 on success or %-EINVAL on failure.
+ */
+int rio_hw_add_inb_buffer(struct rio_mport *mport, int mbox, void *buf)
+{
+ int rc = 0;
+
+ pr_debug("RIO: rio_hw_add_inb_buffer(), msg_rx_ring.rx_slot %d\n",
+ msg_rx_ring.rx_slot);
+
+ if (msg_rx_ring.virt_buffer[msg_rx_ring.rx_slot]) {
+ printk(KERN_ERR
+ "RIO: error adding inbound buffer %d, buffer exists\n",
+ msg_rx_ring.rx_slot);
+ rc = -EINVAL;
+ goto out;
+ }
+
+ msg_rx_ring.virt_buffer[msg_rx_ring.rx_slot] = buf;
+ if (++msg_rx_ring.rx_slot == msg_rx_ring.size)
+ msg_rx_ring.rx_slot = 0;
+
+ out:
+ return rc;
+}
+
+EXPORT_SYMBOL_GPL(rio_hw_add_inb_buffer);
+
+/**
+ * rio_hw_get_inb_message - Fetch inbound message from the MPC85xx message unit
+ * @mport: Master port implementing the inbound message unit
+ * @mbox: Inbound mailbox number
+ *
+ * Gets the next available inbound message from the inbound message queue.
+ * A pointer to the message is returned on success or NULL on failure.
+ */
+void *rio_hw_get_inb_message(struct rio_mport *mport, int mbox)
+{
+ u32 imr;
+ u32 phys_buf, virt_buf;
+ void *buf = NULL;
+ int buf_idx;
+
+ phys_buf = in_be32((void *)&msg_regs->ifqdpar);
+
+ /* If no more messages, then bail out */
+ if (phys_buf == in_be32((void *)&msg_regs->ifqepar))
+ goto out2;
+
+ virt_buf = (u32) msg_rx_ring.virt + (phys_buf - msg_rx_ring.phys);
+ buf_idx = (phys_buf - msg_rx_ring.phys) / RIO_MAX_MSG_SIZE;
+ buf = msg_rx_ring.virt_buffer[buf_idx];
+
+ if (!buf) {
+ printk(KERN_ERR
+ "RIO: inbound message copy failed, no buffers\n");
+ goto out1;
+ }
+
+ /* Copy max message size, caller is expected to allocate that big */
+ memcpy(buf, (void *)virt_buf, RIO_MAX_MSG_SIZE);
+
+ /* Clear the available buffer */
+ msg_rx_ring.virt_buffer[buf_idx] = NULL;
+
+ out1:
+ imr = in_be32((void *)&msg_regs->imr);
+ out_be32((void *)&msg_regs->imr, imr | RIO_MSG_IMR_MI);
+
+ out2:
+ return buf;
+}
+
+EXPORT_SYMBOL_GPL(rio_hw_get_inb_message);
+
+/**
+ * mpc85xx_rio_dbell_handler - MPC85xx doorbell interrupt handler
+ * @irq: Linux interrupt number
+ * @dev_instance: Pointer to interrupt-specific data
+ * @regs: Register context
+ *
+ * Handles doorbell interrupts. Parses a list of registered
+ * doorbell event handlers and executes a matching event handler.
+ */
+static irqreturn_t
+mpc85xx_rio_dbell_handler(int irq, void *dev_instance, struct pt_regs *regs)
+{
+ int dsr;
+ struct rio_mport *port = (struct rio_mport *)dev_instance;
+
+ dsr = in_be32((void *)&msg_regs->dsr);
+
+ if (dsr & DOORBELL_DSR_TE) {
+ pr_info("RIO: doorbell reception error\n");
+ out_be32((void *)&msg_regs->dsr, DOORBELL_DSR_TE);
+ goto out;
+ }
+
+ if (dsr & DOORBELL_DSR_QFI) {
+ pr_info("RIO: doorbell queue full\n");
+ out_be32((void *)&msg_regs->dsr, DOORBELL_DSR_QFI);
+ goto out;
+ }
+
+ /* XXX Need to check/dispatch until queue empty */
+ if (dsr & DOORBELL_DSR_DIQI) {
+ u32 dmsg =
+ (u32) dbell_ring.virt +
+ (in_be32((void *)&msg_regs->dqdpar) & 0xfff);
+ u32 dmr;
+ struct rio_dbell *dbell;
+ int found = 0;
+
+ pr_debug
+ ("RIO: processing doorbell, sid %2.2x tid %2.2x info %4.4x\n",
+ DBELL_SID(dmsg), DBELL_TID(dmsg), DBELL_INF(dmsg));
+
+ list_for_each_entry(dbell, &port->dbells, node) {
+ if ((dbell->res->start <= DBELL_INF(dmsg)) &&
+ (dbell->res->end >= DBELL_INF(dmsg))) {
+ found = 1;
+ break;
+ }
+ }
+ if (found) {
+ dbell->dinb(port, dbell->dev_id, DBELL_SID(dmsg), DBELL_TID(dmsg),
+ DBELL_INF(dmsg));
+ } else {
+ pr_debug
+ ("RIO: spurious doorbell, sid %2.2x tid %2.2x info %4.4x\n",
+ DBELL_SID(dmsg), DBELL_TID(dmsg), DBELL_INF(dmsg));
+ }
+ dmr = in_be32((void *)&msg_regs->dmr);
+ out_be32((void *)&msg_regs->dmr, dmr | DOORBELL_DMR_DI);
+ out_be32((void *)&msg_regs->dsr, DOORBELL_DSR_DIQI);
+ }
+
+ out:
+ return IRQ_HANDLED;
+}
+
+/**
+ * mpc85xx_rio_doorbell_init - MPC85xx doorbell interface init
+ * @mport: Master port implementing the inbound doorbell unit
+ *
+ * Initializes doorbell unit hardware and inbound DMA buffer
+ * ring. Called from mpc85xx_rio_setup(). Returns %0 on success
+ * or %-ENOMEM on failure.
+ */
+static int mpc85xx_rio_doorbell_init(struct rio_mport *mport)
+{
+ int rc = 0;
+
+ /* Map outbound doorbell window immediately after maintenance window */
+ if (!(dbell_win =
+ (u32) ioremap(mport->iores.start + RIO_MAINT_WIN_SIZE,
+ RIO_DBELL_WIN_SIZE))) {
+ printk(KERN_ERR
+ "RIO: unable to map outbound doorbell window\n");
+ rc = -ENOMEM;
+ goto out;
+ }
+
+ /* Initialize inbound doorbells */
+ if (!(dbell_ring.virt = dma_alloc_coherent(NULL,
+ 512 * DOORBELL_MESSAGE_SIZE,
+ &dbell_ring.phys,
+ GFP_KERNEL))) {
+ printk(KERN_ERR "RIO: unable allocate inbound doorbell ring\n");
+ rc = -ENOMEM;
+ iounmap((void *)dbell_win);
+ goto out;
+ }
+
+ /* Point dequeue/enqueue pointers at first entry in ring */
+ out_be32((void *)&msg_regs->dqdpar, (u32) dbell_ring.phys);
+ out_be32((void *)&msg_regs->dqepar, (u32) dbell_ring.phys);
+
+ /* Clear interrupt status */
+ out_be32((void *)&msg_regs->dsr, 0x00000091);
+
+ /* Hook up doorbell handler */
+ if ((rc =
+ request_irq(MPC85xx_IRQ_RIO_BELL, mpc85xx_rio_dbell_handler, 0,
+ "dbell_rx", (void *)mport) < 0)) {
+ iounmap((void *)dbell_win);
+ dma_free_coherent(NULL, 512 * DOORBELL_MESSAGE_SIZE,
+ dbell_ring.virt, dbell_ring.phys);
+ printk(KERN_ERR
+ "MPC85xx RIO: unable to request inbound doorbell irq");
+ goto out;
+ }
+
+ /* Configure doorbells for snooping, 512 entries, and enable */
+ out_be32((void *)&msg_regs->dmr, 0x00108161);
+
+ out:
+ return rc;
+}
+
+static char *cmdline = NULL;
+
+static int mpc85xx_rio_get_hdid(int index)
+{
+ /* XXX Need to parse multiple entries in some format */
+ if (!cmdline)
+ return -1;
+
+ return simple_strtol(cmdline, NULL, 0);
+}
+
+static int mpc85xx_rio_get_cmdline(char *s)
+{
+ if (!s)
+ return 0;
+
+ cmdline = s;
+ return 1;
+}
+
+__setup("riohdid=", mpc85xx_rio_get_cmdline);
+
+/**
+ * mpc85xx_rio_setup - Setup MPC85xx RapidIO interface
+ * @law_start: Starting physical address of RapidIO LAW
+ * @law_size: Size of RapidIO LAW
+ *
+ * Initializes MPC85xx RapidIO hardware interface, configures
+ * master port with system-specific info, and registers the
+ * master port with the RapidIO subsystem.
+ */
+void mpc85xx_rio_setup(int law_start, int law_size)
+{
+ struct rio_ops *ops;
+ struct rio_mport *port;
+
+ ops = kmalloc(sizeof(struct rio_ops), GFP_KERNEL);
+ ops->lcread = mpc85xx_local_config_read;
+ ops->lcwrite = mpc85xx_local_config_write;
+ ops->cread = mpc85xx_rio_config_read;
+ ops->cwrite = mpc85xx_rio_config_write;
+ ops->dsend = mpc85xx_rio_doorbell_send;
+
+ port = kmalloc(sizeof(struct rio_mport), GFP_KERNEL);
+ port->id = 0;
+ port->index = 0;
+ INIT_LIST_HEAD(&port->dbells);
+ port->iores.start = law_start;
+ port->iores.end = law_start + law_size;
+ port->iores.flags = IORESOURCE_MEM;
+
+ rio_init_dbell_res(&port->riores[RIO_DOORBELL_RESOURCE], 0, 0xffff);
+ rio_init_mbox_res(&port->riores[RIO_INB_MBOX_RESOURCE], 0, 0);
+ rio_init_mbox_res(&port->riores[RIO_OUTB_MBOX_RESOURCE], 0, 0);
+ strcpy(port->name, "RIO0 mport");
+
+ port->ops = ops;
+ port->host_deviceid = mpc85xx_rio_get_hdid(port->id);
+
+ rio_register_mport(port);
+
+ regs_win = (u32) ioremap(RIO_REGS_BASE, 0x20000);
+ atmu_regs = (struct rio_atmu_regs *)(regs_win + RIO_ATMU_REGS_OFFSET);
+ maint_atmu_regs = atmu_regs + 1;
+ dbell_atmu_regs = atmu_regs + 2;
+ msg_regs = (struct rio_msg_regs *)(regs_win + RIO_MSG_REGS_OFFSET);
+
+ /* Configure maintenance transaction window */
+ out_be32((void *)&maint_atmu_regs->rowbar, 0x000c0000);
+ out_be32((void *)&maint_atmu_regs->rowar, 0x80077015);
+
+ maint_win = (u32) ioremap(law_start, RIO_MAINT_WIN_SIZE);
+
+ /* Configure outbound doorbell window */
+ out_be32((void *)&dbell_atmu_regs->rowbar, 0x000c0400);
+ out_be32((void *)&dbell_atmu_regs->rowar, 0x8004200b);
+ mpc85xx_rio_doorbell_init(port);
+}
diff --git a/arch/ppc/syslib/ppc85xx_rio.h b/arch/ppc/syslib/ppc85xx_rio.h
new file mode 100644
index 000000000000..c0827a2c3eec
--- /dev/null
+++ b/arch/ppc/syslib/ppc85xx_rio.h
@@ -0,0 +1,21 @@
+/*
+ * MPC85xx RapidIO definitions
+ *
+ * Copyright 2005 MontaVista Software, Inc.
+ * Matt Porter <mporter@kernel.crashing.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.
+ */
+
+#ifndef __PPC_SYSLIB_PPC85XX_RIO_H
+#define __PPC_SYSLIB_PPC85XX_RIO_H
+
+#include <linux/config.h>
+#include <linux/init.h>
+
+extern void mpc85xx_rio_setup(int law_start, int law_size);
+
+#endif /* __PPC_SYSLIB_PPC85XX_RIO_H */
diff --git a/arch/ppc/syslib/ppc85xx_setup.c b/arch/ppc/syslib/ppc85xx_setup.c
index 832b8bf99ae7..de2f90576577 100644
--- a/arch/ppc/syslib/ppc85xx_setup.c
+++ b/arch/ppc/syslib/ppc85xx_setup.c
@@ -29,6 +29,7 @@
#include <asm/mmu.h>
#include <asm/ppc_sys.h>
#include <asm/kgdb.h>
+#include <asm/machdep.h>
#include <syslib/ppc85xx_setup.h>
diff --git a/arch/ppc/syslib/ppc8xx_pic.c b/arch/ppc/syslib/ppc8xx_pic.c
index d3b01c6c97de..3e6f51a61d46 100644
--- a/arch/ppc/syslib/ppc8xx_pic.c
+++ b/arch/ppc/syslib/ppc8xx_pic.c
@@ -6,6 +6,7 @@
#include <linux/signal.h>
#include <linux/interrupt.h>
#include <asm/irq.h>
+#include <asm/io.h>
#include <asm/8xx_immap.h>
#include <asm/mpc8xx.h>
#include "ppc8xx_pic.h"
@@ -29,8 +30,7 @@ static void m8xx_mask_irq(unsigned int irq_nr)
word = irq_nr >> 5;
ppc_cached_irq_mask[word] &= ~(1 << (31-bit));
- ((immap_t *)IMAP_ADDR)->im_siu_conf.sc_simask =
- ppc_cached_irq_mask[word];
+ out_be32(&((immap_t *)IMAP_ADDR)->im_siu_conf.sc_simask, ppc_cached_irq_mask[word]);
}
static void m8xx_unmask_irq(unsigned int irq_nr)
@@ -41,8 +41,7 @@ static void m8xx_unmask_irq(unsigned int irq_nr)
word = irq_nr >> 5;
ppc_cached_irq_mask[word] |= (1 << (31-bit));
- ((immap_t *)IMAP_ADDR)->im_siu_conf.sc_simask =
- ppc_cached_irq_mask[word];
+ out_be32(&((immap_t *)IMAP_ADDR)->im_siu_conf.sc_simask, ppc_cached_irq_mask[word]);
}
static void m8xx_end_irq(unsigned int irq_nr)
@@ -55,8 +54,7 @@ static void m8xx_end_irq(unsigned int irq_nr)
word = irq_nr >> 5;
ppc_cached_irq_mask[word] |= (1 << (31-bit));
- ((immap_t *)IMAP_ADDR)->im_siu_conf.sc_simask =
- ppc_cached_irq_mask[word];
+ out_be32(&((immap_t *)IMAP_ADDR)->im_siu_conf.sc_simask, ppc_cached_irq_mask[word]);
}
}
@@ -69,9 +67,8 @@ static void m8xx_mask_and_ack(unsigned int irq_nr)
word = irq_nr >> 5;
ppc_cached_irq_mask[word] &= ~(1 << (31-bit));
- ((immap_t *)IMAP_ADDR)->im_siu_conf.sc_simask =
- ppc_cached_irq_mask[word];
- ((immap_t *)IMAP_ADDR)->im_siu_conf.sc_sipend = 1 << (31-bit);
+ out_be32(&((immap_t *)IMAP_ADDR)->im_siu_conf.sc_simask, ppc_cached_irq_mask[word]);
+ out_be32(&((immap_t *)IMAP_ADDR)->im_siu_conf.sc_sipend, 1 << (31-bit));
}
struct hw_interrupt_type ppc8xx_pic = {
@@ -93,7 +90,7 @@ m8xx_get_irq(struct pt_regs *regs)
/* For MPC8xx, read the SIVEC register and shift the bits down
* to get the irq number.
*/
- irq = ((immap_t *)IMAP_ADDR)->im_siu_conf.sc_sivec >> 26;
+ irq = in_be32(&((immap_t *)IMAP_ADDR)->im_siu_conf.sc_sivec) >> 26;
/*
* When we read the sivec without an interrupt to process, we will
diff --git a/arch/ppc/syslib/ppc_sys.c b/arch/ppc/syslib/ppc_sys.c
index 52ba0c68078d..603f01190816 100644
--- a/arch/ppc/syslib/ppc_sys.c
+++ b/arch/ppc/syslib/ppc_sys.c
@@ -14,6 +14,7 @@
* option) any later version.
*/
+#include <linux/string.h>
#include <asm/ppc_sys.h>
int (*ppc_sys_device_fixup) (struct platform_device * pdev);
@@ -69,6 +70,9 @@ static int __init find_chip_by_name_and_id(char *name, u32 id)
matched[j++] = i;
i++;
}
+
+ ret = i;
+
if (j != 0) {
for (i = 0; i < j; i++) {
if ((ppc_sys_specs[matched[i]].mask & id) ==
diff --git a/arch/ppc/syslib/pq2_devices.c b/arch/ppc/syslib/pq2_devices.c
index 1d3869768f96..e960fe935325 100644
--- a/arch/ppc/syslib/pq2_devices.c
+++ b/arch/ppc/syslib/pq2_devices.c
@@ -13,11 +13,12 @@
#include <linux/init.h>
#include <linux/module.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <linux/ioport.h>
#include <asm/cpm2.h>
#include <asm/irq.h>
#include <asm/ppc_sys.h>
+#include <asm/machdep.h>
struct platform_device ppc_sys_platform_devices[] = {
[MPC82xx_CPM_FCC1] = {
diff --git a/arch/ppc/syslib/prep_nvram.c b/arch/ppc/syslib/prep_nvram.c
index 8599850ca772..2c6364d9641f 100644
--- a/arch/ppc/syslib/prep_nvram.c
+++ b/arch/ppc/syslib/prep_nvram.c
@@ -22,14 +22,14 @@
static char nvramData[MAX_PREP_NVRAM];
static NVRAM_MAP *nvram=(NVRAM_MAP *)&nvramData[0];
-unsigned char __prep prep_nvram_read_val(int addr)
+unsigned char prep_nvram_read_val(int addr)
{
outb(addr, PREP_NVRAM_AS0);
outb(addr>>8, PREP_NVRAM_AS1);
return inb(PREP_NVRAM_DATA);
}
-void __prep prep_nvram_write_val(int addr,
+void prep_nvram_write_val(int addr,
unsigned char val)
{
outb(addr, PREP_NVRAM_AS0);
@@ -81,8 +81,7 @@ void __init init_prep_nvram(void)
}
}
-__prep
-char __prep *prep_nvram_get_var(const char *name)
+char *prep_nvram_get_var(const char *name)
{
char *cp;
int namelen;
@@ -101,8 +100,7 @@ char __prep *prep_nvram_get_var(const char *name)
return NULL;
}
-__prep
-char __prep *prep_nvram_first_var(void)
+char *prep_nvram_first_var(void)
{
if (nvram->Header.GELength == 0) {
return NULL;
@@ -112,8 +110,7 @@ char __prep *prep_nvram_first_var(void)
}
}
-__prep
-char __prep *prep_nvram_next_var(char *name)
+char *prep_nvram_next_var(char *name)
{
char *cp;
diff --git a/arch/ppc/syslib/prom.c b/arch/ppc/syslib/prom.c
index 2c64ed627475..af4deace49e0 100644
--- a/arch/ppc/syslib/prom.c
+++ b/arch/ppc/syslib/prom.c
@@ -13,7 +13,6 @@
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/init.h>
-#include <linux/version.h>
#include <linux/threads.h>
#include <linux/spinlock.h>
#include <linux/ioport.h>
@@ -89,7 +88,7 @@ extern char cmd_line[512]; /* XXX */
extern boot_infos_t *boot_infos;
unsigned long dev_tree_size;
-void __openfirmware
+void
phys_call_rtas(int service, int nargs, int nret, ...)
{
va_list list;
@@ -862,7 +861,7 @@ find_type_devices(const char *type)
/*
* Returns all nodes linked together
*/
-struct device_node * __openfirmware
+struct device_node *
find_all_nodes(void)
{
struct device_node *head, **prevp, *np;
@@ -1165,7 +1164,7 @@ get_property(struct device_node *np, const char *name, int *lenp)
/*
* Add a property to a node
*/
-void __openfirmware
+int
prom_add_property(struct device_node* np, struct property* prop)
{
struct property **next = &np->properties;
@@ -1174,10 +1173,12 @@ prom_add_property(struct device_node* np, struct property* prop)
while (*next)
next = &(*next)->next;
*next = prop;
+
+ return 0;
}
/* I quickly hacked that one, check against spec ! */
-static inline unsigned long __openfirmware
+static inline unsigned long
bus_space_to_resource_flags(unsigned int bus_space)
{
u8 space = (bus_space >> 24) & 0xf;
@@ -1194,7 +1195,7 @@ bus_space_to_resource_flags(unsigned int bus_space)
}
}
-static struct resource* __openfirmware
+static struct resource*
find_parent_pci_resource(struct pci_dev* pdev, struct address_range *range)
{
unsigned long mask;
@@ -1224,7 +1225,7 @@ find_parent_pci_resource(struct pci_dev* pdev, struct address_range *range)
* or other nodes attached to the root node. Ultimately, put some
* link to resources in the OF node.
*/
-struct resource* __openfirmware
+struct resource*
request_OF_resource(struct device_node* node, int index, const char* name_postfix)
{
struct pci_dev* pcidev;
@@ -1280,7 +1281,7 @@ fail:
return NULL;
}
-int __openfirmware
+int
release_OF_resource(struct device_node* node, int index)
{
struct pci_dev* pcidev;
@@ -1335,10 +1336,8 @@ release_OF_resource(struct device_node* node, int index)
if (!res)
return -ENODEV;
- if (res->name) {
- kfree(res->name);
- res->name = NULL;
- }
+ kfree(res->name);
+ res->name = NULL;
release_resource(res);
kfree(res);
@@ -1346,7 +1345,7 @@ release_OF_resource(struct device_node* node, int index)
}
#if 0
-void __openfirmware
+void
print_properties(struct device_node *np)
{
struct property *pp;
@@ -1400,7 +1399,7 @@ print_properties(struct device_node *np)
static DEFINE_SPINLOCK(rtas_lock);
/* this can be called after setup -- Cort */
-int __openfirmware
+int
call_rtas(const char *service, int nargs, int nret,
unsigned long *outputs, ...)
{
diff --git a/arch/ppc/syslib/prom_init.c b/arch/ppc/syslib/prom_init.c
index 7f15136830f4..df14422ae1c6 100644
--- a/arch/ppc/syslib/prom_init.c
+++ b/arch/ppc/syslib/prom_init.c
@@ -9,7 +9,6 @@
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/init.h>
-#include <linux/version.h>
#include <linux/threads.h>
#include <linux/spinlock.h>
#include <linux/ioport.h>
diff --git a/arch/ppc/syslib/xilinx_pic.c b/arch/ppc/syslib/xilinx_pic.c
index 2cbcad278cef..47f04c71fe9c 100644
--- a/arch/ppc/syslib/xilinx_pic.c
+++ b/arch/ppc/syslib/xilinx_pic.c
@@ -17,6 +17,7 @@
#include <asm/io.h>
#include <asm/xparameters.h>
#include <asm/ibm4xx.h>
+#include <asm/machdep.h>
/* No one else should require these constants, so define them locally here. */
#define ISR 0 /* Interrupt Status Register */
diff --git a/arch/ppc/xmon/start.c b/arch/ppc/xmon/start.c
index 507d4eeffe07..98612d420346 100644
--- a/arch/ppc/xmon/start.c
+++ b/arch/ppc/xmon/start.c
@@ -478,8 +478,9 @@ void *xmon_stdout;
void *xmon_stderr;
void
-xmon_init(void)
+xmon_init(int arg)
{
+ xmon_map_scc();
}
int
diff --git a/arch/ppc/xmon/xmon.c b/arch/ppc/xmon/xmon.c
index be7869e39465..2b483b4f1602 100644
--- a/arch/ppc/xmon/xmon.c
+++ b/arch/ppc/xmon/xmon.c
@@ -148,9 +148,14 @@ Commands:\n\
r print registers\n\
S print special registers\n\
t print backtrace\n\
- la lookup address in system.map\n\
- ls lookup symbol in system.map\n\
+ la lookup address\n\
+ ls lookup symbol\n\
+ C checksum\n\
+ p call function with arguments\n\
+ T print time\n\
x exit monitor\n\
+ zr reboot\n\
+ zh halt\n\
";
static int xmon_trace[NR_CPUS];
@@ -215,8 +220,7 @@ static void get_tb(unsigned *p)
p[1] = lo;
}
-void
-xmon(struct pt_regs *excp)
+int xmon(struct pt_regs *excp)
{
struct pt_regs regs;
int msr, cmd;
@@ -285,6 +289,8 @@ xmon(struct pt_regs *excp)
#endif /* CONFIG_SMP */
set_msr(msr); /* restore interrupt enable */
get_tb(start_tb[smp_processor_id()]);
+
+ return cmd != 'X';
}
irqreturn_t
diff --git a/arch/ppc64/Kconfig b/arch/ppc64/Kconfig
index c658650af429..c9d32db9d76a 100644
--- a/arch/ppc64/Kconfig
+++ b/arch/ppc64/Kconfig
@@ -10,6 +10,9 @@ config MMU
bool
default y
+config PPC_STD_MMU
+ def_bool y
+
config UID16
bool
@@ -44,11 +47,16 @@ config ARCH_MAY_HAVE_PC_FDC
bool
default y
+config PPC_STD_MMU
+ bool
+ default y
+
# We optimistically allocate largepages from the VM, so make the limit
# large enough (16MB). This badly named config option is actually
# max order + 1
config FORCE_MAX_ZONEORDER
int
+ default "9" if PPC_64K_PAGES
default "13"
source "init/Kconfig"
@@ -86,12 +94,14 @@ config PPC_PMAC
bool " Apple G5 based machines"
default y
select U3_DART
+ select GENERIC_TBSYNC
config PPC_MAPLE
depends on PPC_MULTIPLATFORM
bool " Maple 970FX Evaluation Board"
select U3_DART
select MPIC_BROKEN_U3
+ select GENERIC_TBSYNC
default n
help
This option enables support for the Maple 970FX Evaluation Board.
@@ -120,6 +130,11 @@ config MPIC
bool
default y
+config PPC_I8259
+ depends on PPC_PSERIES
+ bool
+ default y
+
config BPA_IIC
depends on PPC_BPA
bool
@@ -159,6 +174,16 @@ config KEXEC
support. As of this writing the exact hardware interface is
strongly in flux, so no good recommendation can be made.
+source "drivers/cpufreq/Kconfig"
+
+config CPU_FREQ_PMAC64
+ bool "Support for some Apple G5s"
+ depends on CPU_FREQ && PMAC_SMU && PPC64
+ select CPU_FREQ_TABLE
+ help
+ This adds support for frequency switching on Apple iMac G5,
+ and some of the more recent desktop G5 machines as well.
+
config IBMVIO
depends on PPC_PSERIES || PPC_ISERIES
bool
@@ -174,6 +199,9 @@ config MPIC_BROKEN_U3
depends on PPC_MAPLE
default y
+config GENERIC_TBSYNC
+ def_bool n
+
config PPC_PMAC64
bool
depends on PPC_PMAC
@@ -186,6 +214,12 @@ config BOOTX_TEXT
Say Y here to see progress messages from the boot firmware in text
mode. Requires an Open Firmware compatible video card.
+config POWER4
+ def_bool y
+
+config PPC_FPU
+ def_bool y
+
config POWER4_ONLY
bool "Optimize for POWER4"
default n
@@ -234,6 +268,10 @@ config HMT
This option enables hardware multithreading on RS64 cpus.
pSeries systems p620 and p660 have such a cpu type.
+config NUMA
+ bool "NUMA support"
+ default y if SMP && PPC_PSERIES
+
config ARCH_SELECT_MEMORY_MODEL
def_bool y
@@ -249,9 +287,6 @@ config ARCH_DISCONTIGMEM_DEFAULT
def_bool y
depends on ARCH_DISCONTIGMEM_ENABLE
-config ARCH_FLATMEM_ENABLE
- def_bool y
-
config ARCH_SPARSEMEM_ENABLE
def_bool y
depends on ARCH_DISCONTIGMEM_ENABLE
@@ -262,6 +297,10 @@ config HAVE_ARCH_EARLY_PFN_TO_NID
def_bool y
depends on NEED_MULTIPLE_NODES
+config ARCH_MEMORY_PROBE
+ def_bool y
+ depends on MEMORY_HOTPLUG
+
# Some NUMA nodes have memory ranges that span
# other nodes. Even though a pfn is valid and
# between a node's start and end pfns, it may not
@@ -274,9 +313,14 @@ config NODES_SPAN_OTHER_NODES
def_bool y
depends on NEED_MULTIPLE_NODES
-config NUMA
- bool "NUMA support"
- default y if DISCONTIGMEM || SPARSEMEM
+config PPC_64K_PAGES
+ bool "64k page size"
+ help
+ This option changes the kernel logical page size to 64k. On machines
+ without processor support for 64k pages, the kernel will simulate
+ them by loading each individual 4k page on demand transparently,
+ while on hardware with such support, it will be used to map
+ normal application pages.
config SCHED_SMT
bool "SMT (Hyperthreading) scheduler support"
@@ -307,6 +351,11 @@ config PPC_RTAS
depends on PPC_PSERIES || PPC_BPA
default y
+config RTAS_ERROR_LOGGING
+ bool
+ depends on PPC_RTAS
+ default y
+
config RTAS_PROC
bool "Proc interface to RTAS"
depends on PPC_RTAS
@@ -357,7 +406,6 @@ config HOTPLUG_CPU
config PROC_DEVICETREE
bool "Support for Open Firmware device tree in /proc"
- depends on !PPC_ISERIES
help
This option adds a device-tree directory under /proc which contains
an image of the device tree that the kernel copies from Open
@@ -461,7 +509,7 @@ config VIOPATH
depends on VIOCONS || VIODASD || VIOCD || VIOTAPE || VETH
default y
-source "arch/ppc64/oprofile/Kconfig"
+source "arch/powerpc/oprofile/Kconfig"
source "arch/ppc64/Kconfig.debug"
diff --git a/arch/ppc64/Kconfig.debug b/arch/ppc64/Kconfig.debug
index f16a5030527b..b258c9314a1b 100644
--- a/arch/ppc64/Kconfig.debug
+++ b/arch/ppc64/Kconfig.debug
@@ -55,10 +55,6 @@ config XMON_DEFAULT
xmon is normally disabled unless booted with 'xmon=on'.
Use 'xmon=off' to disable xmon init during runtime.
-config PPCDBG
- bool "Include PPCDBG realtime debugging"
- depends on DEBUG_KERNEL
-
config IRQSTACKS
bool "Use separate kernel stacks when processing interrupts"
help
diff --git a/arch/ppc64/Makefile b/arch/ppc64/Makefile
index 521c2a5a2862..a55a82d145d4 100644
--- a/arch/ppc64/Makefile
+++ b/arch/ppc64/Makefile
@@ -75,17 +75,24 @@ else
CFLAGS += $(call cc-option,-mtune=power4)
endif
+# No AltiVec instruction when building kernel
+CFLAGS += $(call cc-option, -mno-altivec)
+
# Enable unit-at-a-time mode when possible. It shrinks the
# kernel considerably.
CFLAGS += $(call cc-option,-funit-at-a-time)
head-y := arch/ppc64/kernel/head.o
+head-y += arch/powerpc/kernel/fpu.o
+head-y += arch/powerpc/kernel/entry_64.o
-libs-y += arch/ppc64/lib/
-core-y += arch/ppc64/kernel/
-core-y += arch/ppc64/mm/
-core-$(CONFIG_XMON) += arch/ppc64/xmon/
-drivers-$(CONFIG_OPROFILE) += arch/ppc64/oprofile/
+core-y += arch/ppc64/kernel/ arch/powerpc/kernel/
+core-y += arch/powerpc/mm/
+core-y += arch/powerpc/sysdev/
+core-y += arch/powerpc/platforms/
+core-y += arch/powerpc/lib/
+core-$(CONFIG_XMON) += arch/powerpc/xmon/
+drivers-$(CONFIG_OPROFILE) += arch/powerpc/oprofile/
boot := arch/ppc64/boot
@@ -100,7 +107,7 @@ $(boottargets-y): vmlinux
bootimage-$(CONFIG_PPC_PSERIES) := $(boot)/zImage
bootimage-$(CONFIG_PPC_PMAC) := vmlinux
bootimage-$(CONFIG_PPC_MAPLE) := $(boot)/zImage
-bootimage-$(CONFIG_PPC_BPA) := zImage
+bootimage-$(CONFIG_PPC_BPA) := $(boot)/zImage
bootimage-$(CONFIG_PPC_ISERIES) := vmlinux
BOOTIMAGE := $(bootimage-y)
install: vmlinux
diff --git a/arch/ppc64/boot/Makefile b/arch/ppc64/boot/Makefile
index 33fdc8710891..301bc1536c49 100644
--- a/arch/ppc64/boot/Makefile
+++ b/arch/ppc64/boot/Makefile
@@ -22,15 +22,46 @@
HOSTCC := gcc
-BOOTCFLAGS := $(HOSTCFLAGS) -fno-builtin -nostdinc -isystem $(shell $(CROSS32CC) -print-file-name=include)
+BOOTCFLAGS := $(HOSTCFLAGS) -fno-builtin -nostdinc -isystem $(shell $(CROSS32CC) -print-file-name=include) -fPIC
BOOTAFLAGS := -D__ASSEMBLY__ $(BOOTCFLAGS) -traditional -nostdinc
-BOOTLFLAGS := -Ttext 0x00400000 -e _start -T $(srctree)/$(src)/zImage.lds
+BOOTLFLAGS := -T $(srctree)/$(src)/zImage.lds
OBJCOPYFLAGS := contents,alloc,load,readonly,data
-src-boot := crt0.S string.S prom.c main.c zlib.c imagesize.c div64.S
+zlib := infblock.c infcodes.c inffast.c inflate.c inftrees.c infutil.c
+zlibheader := infblock.h infcodes.h inffast.h inftrees.h infutil.h
+zliblinuxheader := zlib.h zconf.h zutil.h
+
+$(addprefix $(obj)/,$(zlib) main.o): $(addprefix $(obj)/,$(zliblinuxheader)) $(addprefix $(obj)/,$(zlibheader))
+#$(addprefix $(obj)/,main.o): $(addprefix $(obj)/,zlib.h)
+
+src-boot := string.S prom.c main.c div64.S crt0.S
+src-boot += $(zlib)
src-boot := $(addprefix $(obj)/, $(src-boot))
obj-boot := $(addsuffix .o, $(basename $(src-boot)))
+BOOTCFLAGS += -I$(obj) -I$(srctree)/$(obj)
+
+quiet_cmd_copy_zlib = COPY $@
+ cmd_copy_zlib = sed "s@__attribute_used__@@;s@<linux/\([^>]\+\).*@\"\1\"@" $< > $@
+
+quiet_cmd_copy_zlibheader = COPY $@
+ cmd_copy_zlibheader = sed "s@<linux/\([^>]\+\).*@\"\1\"@" $< > $@
+# stddef.h for NULL
+quiet_cmd_copy_zliblinuxheader = COPY $@
+ cmd_copy_zliblinuxheader = sed "s@<linux/string.h>@\"string.h\"@;s@<linux/kernel.h>@<stddef.h>@;s@<linux/\([^>]\+\).*@\"\1\"@" $< > $@
+
+$(addprefix $(obj)/,$(zlib)): $(obj)/%: $(srctree)/lib/zlib_inflate/%
+ $(call cmd,copy_zlib)
+
+$(addprefix $(obj)/,$(zlibheader)): $(obj)/%: $(srctree)/lib/zlib_inflate/%
+ $(call cmd,copy_zlibheader)
+
+$(addprefix $(obj)/,$(zliblinuxheader)): $(obj)/%: $(srctree)/include/linux/%
+ $(call cmd,copy_zliblinuxheader)
+
+clean-files := $(zlib) $(zlibheader) $(zliblinuxheader)
+
+
quiet_cmd_bootcc = BOOTCC $@
cmd_bootcc = $(CROSS32CC) -Wp,-MD,$(depfile) $(BOOTCFLAGS) -c -o $@ $<
@@ -56,7 +87,7 @@ src-sec = $(foreach section, $(1), $(patsubst %,$(obj)/kernel-%.c, $(section)))
gz-sec = $(foreach section, $(1), $(patsubst %,$(obj)/kernel-%.gz, $(section)))
hostprogs-y := addnote addRamDisk
-targets += zImage.vmode zImage.initrd.vmode zImage zImage.initrd imagesize.c \
+targets += zImage.vmode zImage.initrd.vmode zImage zImage.initrd \
$(patsubst $(obj)/%,%, $(call obj-sec, $(required) $(initrd))) \
$(patsubst $(obj)/%,%, $(call src-sec, $(required) $(initrd))) \
$(patsubst $(obj)/%,%, $(call gz-sec, $(required) $(initrd))) \
@@ -69,9 +100,9 @@ quiet_cmd_ramdisk = RAMDISK $@
quiet_cmd_stripvm = STRIP $@
cmd_stripvm = $(STRIP) -s $< -o $@
-vmlinux.strip: vmlinux FORCE
+vmlinux.strip: vmlinux
$(call if_changed,stripvm)
-$(obj)/vmlinux.initrd: vmlinux.strip $(obj)/addRamDisk $(obj)/ramdisk.image.gz FORCE
+$(obj)/vmlinux.initrd: vmlinux.strip $(obj)/addRamDisk $(obj)/ramdisk.image.gz
$(call if_changed,ramdisk)
quiet_cmd_addsection = ADDSEC $@
@@ -79,48 +110,38 @@ quiet_cmd_addsection = ADDSEC $@
--add-section=.kernel:$(strip $(patsubst $(obj)/kernel-%.o,%, $@))=$(patsubst %.o,%.gz, $@) \
--set-section-flags=.kernel:$(strip $(patsubst $(obj)/kernel-%.o,%, $@))=$(OBJCOPYFLAGS)
-quiet_cmd_imagesize = GENSIZE $@
- cmd_imagesize = ls -l vmlinux.strip | \
- awk '{printf "/* generated -- do not edit! */\n" "unsigned long vmlinux_filesize = %d;\n", $$5}' \
- > $(obj)/imagesize.c && \
- $(CROSS_COMPILE)nm -n vmlinux | tail -n 1 | \
- awk '{printf "unsigned long vmlinux_memsize = 0x%s;\n", substr($$1,8)}' >> $(obj)/imagesize.c
-
quiet_cmd_addnote = ADDNOTE $@
cmd_addnote = $(obj)/addnote $@
-$(call gz-sec, $(required)): $(obj)/kernel-%.gz: % FORCE
+$(call gz-sec, $(required)): $(obj)/kernel-%.gz: %
$(call if_changed,gzip)
$(obj)/kernel-initrd.gz: $(obj)/ramdisk.image.gz
cp -f $(obj)/ramdisk.image.gz $@
-$(call src-sec, $(required) $(initrd)): $(obj)/kernel-%.c: $(obj)/kernel-%.gz FORCE
+$(call src-sec, $(required) $(initrd)): $(obj)/kernel-%.c: $(obj)/kernel-%.gz
@touch $@
-$(call obj-sec, $(required) $(initrd)): $(obj)/kernel-%.o: $(obj)/kernel-%.c FORCE
+$(call obj-sec, $(required) $(initrd)): $(obj)/kernel-%.o: $(obj)/kernel-%.c
$(call if_changed_dep,bootcc)
$(call cmd,addsection)
$(obj)/zImage.vmode: obj-boot += $(call obj-sec, $(required))
-$(obj)/zImage.vmode: $(call obj-sec, $(required)) $(obj-boot) FORCE
+$(obj)/zImage.vmode: $(call obj-sec, $(required)) $(obj-boot) $(srctree)/$(src)/zImage.lds
$(call cmd,bootld,$(obj-boot))
$(obj)/zImage.initrd.vmode: obj-boot += $(call obj-sec, $(required) $(initrd))
-$(obj)/zImage.initrd.vmode: $(call obj-sec, $(required) $(initrd)) $(obj-boot) FORCE
+$(obj)/zImage.initrd.vmode: $(call obj-sec, $(required) $(initrd)) $(obj-boot) $(srctree)/$(src)/zImage.lds
$(call cmd,bootld,$(obj-boot))
-$(obj)/zImage: $(obj)/zImage.vmode $(obj)/addnote FORCE
+$(obj)/zImage: $(obj)/zImage.vmode $(obj)/addnote
@cp -f $< $@
$(call if_changed,addnote)
-$(obj)/zImage.initrd: $(obj)/zImage.initrd.vmode $(obj)/addnote FORCE
+$(obj)/zImage.initrd: $(obj)/zImage.initrd.vmode $(obj)/addnote
@cp -f $< $@
$(call if_changed,addnote)
-$(obj)/imagesize.c: vmlinux.strip
- $(call cmd,imagesize)
-
install: $(CONFIGURE) $(BOOTIMAGE)
sh -x $(srctree)/$(src)/install.sh "$(KERNELRELEASE)" vmlinux System.map "$(INSTALL_PATH)" "$(BOOTIMAGE)"
diff --git a/arch/ppc64/boot/addRamDisk.c b/arch/ppc64/boot/addRamDisk.c
index 7f2c09473394..c02a99952be7 100644
--- a/arch/ppc64/boot/addRamDisk.c
+++ b/arch/ppc64/boot/addRamDisk.c
@@ -5,11 +5,59 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
+#include <elf.h>
#define ElfHeaderSize (64 * 1024)
#define ElfPages (ElfHeaderSize / 4096)
#define KERNELBASE (0xc000000000000000)
+#define _ALIGN_UP(addr,size) (((addr)+((size)-1))&(~((size)-1)))
+struct addr_range {
+ unsigned long long addr;
+ unsigned long memsize;
+ unsigned long offset;
+};
+
+static int check_elf64(void *p, int size, struct addr_range *r)
+{
+ Elf64_Ehdr *elf64 = p;
+ Elf64_Phdr *elf64ph;
+
+ if (elf64->e_ident[EI_MAG0] != ELFMAG0 ||
+ elf64->e_ident[EI_MAG1] != ELFMAG1 ||
+ elf64->e_ident[EI_MAG2] != ELFMAG2 ||
+ elf64->e_ident[EI_MAG3] != ELFMAG3 ||
+ elf64->e_ident[EI_CLASS] != ELFCLASS64 ||
+ elf64->e_ident[EI_DATA] != ELFDATA2MSB ||
+ elf64->e_type != ET_EXEC || elf64->e_machine != EM_PPC64)
+ return 0;
+
+ if ((elf64->e_phoff + sizeof(Elf64_Phdr)) > size)
+ return 0;
+
+ elf64ph = (Elf64_Phdr *) ((unsigned long)elf64 +
+ (unsigned long)elf64->e_phoff);
+
+ r->memsize = (unsigned long)elf64ph->p_memsz;
+ r->offset = (unsigned long)elf64ph->p_offset;
+ r->addr = (unsigned long long)elf64ph->p_vaddr;
+
+#ifdef DEBUG
+ printf("PPC64 ELF file, ph:\n");
+ printf("p_type 0x%08x\n", elf64ph->p_type);
+ printf("p_flags 0x%08x\n", elf64ph->p_flags);
+ printf("p_offset 0x%016llx\n", elf64ph->p_offset);
+ printf("p_vaddr 0x%016llx\n", elf64ph->p_vaddr);
+ printf("p_paddr 0x%016llx\n", elf64ph->p_paddr);
+ printf("p_filesz 0x%016llx\n", elf64ph->p_filesz);
+ printf("p_memsz 0x%016llx\n", elf64ph->p_memsz);
+ printf("p_align 0x%016llx\n", elf64ph->p_align);
+ printf("... skipping 0x%08lx bytes of ELF header\n",
+ (unsigned long)elf64ph->p_offset);
+#endif
+
+ return 64;
+}
void get4k(FILE *file, char *buf )
{
unsigned j;
@@ -34,97 +82,92 @@ void death(const char *msg, FILE *fdesc, const char *fname)
int main(int argc, char **argv)
{
char inbuf[4096];
- FILE *ramDisk = NULL;
- FILE *sysmap = NULL;
- FILE *inputVmlinux = NULL;
- FILE *outputVmlinux = NULL;
-
- unsigned i = 0;
- unsigned long ramFileLen = 0;
- unsigned long ramLen = 0;
- unsigned long roundR = 0;
-
- unsigned long sysmapFileLen = 0;
- unsigned long sysmapLen = 0;
- unsigned long sysmapPages = 0;
- char* ptr_end = NULL;
- unsigned long offset_end = 0;
-
- unsigned long kernelLen = 0;
- unsigned long actualKernelLen = 0;
- unsigned long round = 0;
- unsigned long roundedKernelLen = 0;
- unsigned long ramStartOffs = 0;
- unsigned long ramPages = 0;
- unsigned long roundedKernelPages = 0;
- unsigned long hvReleaseData = 0;
+ struct addr_range vmlinux;
+ FILE *ramDisk;
+ FILE *inputVmlinux;
+ FILE *outputVmlinux;
+
+ char *rd_name, *lx_name, *out_name;
+
+ size_t i;
+ unsigned long ramFileLen;
+ unsigned long ramLen;
+ unsigned long roundR;
+ unsigned long offset_end;
+
+ unsigned long kernelLen;
+ unsigned long actualKernelLen;
+ unsigned long round;
+ unsigned long roundedKernelLen;
+ unsigned long ramStartOffs;
+ unsigned long ramPages;
+ unsigned long roundedKernelPages;
+ unsigned long hvReleaseData;
u_int32_t eyeCatcher = 0xc8a5d9c4;
- unsigned long naca = 0;
- unsigned long xRamDisk = 0;
- unsigned long xRamDiskSize = 0;
- long padPages = 0;
+ unsigned long naca;
+ unsigned long xRamDisk;
+ unsigned long xRamDiskSize;
+ long padPages;
if (argc < 2) {
fprintf(stderr, "Name of RAM disk file missing.\n");
exit(1);
}
+ rd_name = argv[1];
if (argc < 3) {
- fprintf(stderr, "Name of System Map input file is missing.\n");
- exit(1);
- }
-
- if (argc < 4) {
fprintf(stderr, "Name of vmlinux file missing.\n");
exit(1);
}
+ lx_name = argv[2];
- if (argc < 5) {
+ if (argc < 4) {
fprintf(stderr, "Name of vmlinux output file missing.\n");
exit(1);
}
+ out_name = argv[3];
- ramDisk = fopen(argv[1], "r");
+ ramDisk = fopen(rd_name, "r");
if ( ! ramDisk ) {
- fprintf(stderr, "RAM disk file \"%s\" failed to open.\n", argv[1]);
+ fprintf(stderr, "RAM disk file \"%s\" failed to open.\n", rd_name);
exit(1);
}
- sysmap = fopen(argv[2], "r");
- if ( ! sysmap ) {
- fprintf(stderr, "System Map file \"%s\" failed to open.\n", argv[2]);
- exit(1);
- }
-
- inputVmlinux = fopen(argv[3], "r");
+ inputVmlinux = fopen(lx_name, "r");
if ( ! inputVmlinux ) {
- fprintf(stderr, "vmlinux file \"%s\" failed to open.\n", argv[3]);
+ fprintf(stderr, "vmlinux file \"%s\" failed to open.\n", lx_name);
exit(1);
}
- outputVmlinux = fopen(argv[4], "w+");
+ outputVmlinux = fopen(out_name, "w+");
if ( ! outputVmlinux ) {
- fprintf(stderr, "output vmlinux file \"%s\" failed to open.\n", argv[4]);
+ fprintf(stderr, "output vmlinux file \"%s\" failed to open.\n", out_name);
exit(1);
}
-
-
-
+
+ i = fread(inbuf, 1, sizeof(inbuf), inputVmlinux);
+ if (i != sizeof(inbuf)) {
+ fprintf(stderr, "can not read vmlinux file %s: %u\n", lx_name, i);
+ exit(1);
+ }
+
+ i = check_elf64(inbuf, sizeof(inbuf), &vmlinux);
+ if (i == 0) {
+ fprintf(stderr, "You must have a linux kernel specified as argv[2]\n");
+ exit(1);
+ }
+
/* Input Vmlinux file */
fseek(inputVmlinux, 0, SEEK_END);
kernelLen = ftell(inputVmlinux);
fseek(inputVmlinux, 0, SEEK_SET);
- printf("kernel file size = %d\n", kernelLen);
- if ( kernelLen == 0 ) {
- fprintf(stderr, "You must have a linux kernel specified as argv[3]\n");
- exit(1);
- }
+ printf("kernel file size = %lu\n", kernelLen);
actualKernelLen = kernelLen - ElfHeaderSize;
- printf("actual kernel length (minus ELF header) = %d\n", actualKernelLen);
+ printf("actual kernel length (minus ELF header) = %lu\n", actualKernelLen);
round = actualKernelLen % 4096;
roundedKernelLen = actualKernelLen;
@@ -134,39 +177,7 @@ int main(int argc, char **argv)
roundedKernelPages = roundedKernelLen / 4096;
printf("Vmlinux pages to copy = %ld/0x%lx \n", roundedKernelPages, roundedKernelPages);
-
-
- /* Input System Map file */
- /* (needs to be processed simply to determine if we need to add pad pages due to the static variables not being included in the vmlinux) */
- fseek(sysmap, 0, SEEK_END);
- sysmapFileLen = ftell(sysmap);
- fseek(sysmap, 0, SEEK_SET);
- printf("%s file size = %ld/0x%lx \n", argv[2], sysmapFileLen, sysmapFileLen);
-
- sysmapLen = sysmapFileLen;
-
- roundR = 4096 - (sysmapLen % 4096);
- if (roundR) {
- printf("Rounding System Map file up to a multiple of 4096, adding %ld/0x%lx \n", roundR, roundR);
- sysmapLen += roundR;
- }
- printf("Rounded System Map size is %ld/0x%lx \n", sysmapLen, sysmapLen);
-
- /* Process the Sysmap file to determine where _end is */
- sysmapPages = sysmapLen / 4096;
- /* read the whole file line by line, expect that it doesn't fail */
- while ( fgets(inbuf, 4096, sysmap) ) ;
- /* search for _end in the last page of the system map */
- ptr_end = strstr(inbuf, " _end");
- if (!ptr_end) {
- fprintf(stderr, "Unable to find _end in the sysmap file \n");
- fprintf(stderr, "inbuf: \n");
- fprintf(stderr, "%s \n", inbuf);
- exit(1);
- }
- printf("Found _end in the last page of the sysmap - backing up 10 characters it looks like %s", ptr_end-10);
- /* convert address of _end in system map to hex offset. */
- offset_end = (unsigned int)strtol(ptr_end-10, NULL, 16);
+ offset_end = _ALIGN_UP(vmlinux.memsize, 4096);
/* calc how many pages we need to insert between the vmlinux and the start of the ram disk */
padPages = offset_end/4096 - roundedKernelPages;
@@ -194,7 +205,7 @@ int main(int argc, char **argv)
fseek(ramDisk, 0, SEEK_END);
ramFileLen = ftell(ramDisk);
fseek(ramDisk, 0, SEEK_SET);
- printf("%s file size = %ld/0x%lx \n", argv[1], ramFileLen, ramFileLen);
+ printf("%s file size = %ld/0x%lx \n", rd_name, ramFileLen, ramFileLen);
ramLen = ramFileLen;
@@ -248,19 +259,19 @@ int main(int argc, char **argv)
/* fseek to the hvReleaseData pointer */
fseek(outputVmlinux, ElfHeaderSize + 0x24, SEEK_SET);
if (fread(&hvReleaseData, 4, 1, outputVmlinux) != 1) {
- death("Could not read hvReleaseData pointer\n", outputVmlinux, argv[4]);
+ death("Could not read hvReleaseData pointer\n", outputVmlinux, out_name);
}
hvReleaseData = ntohl(hvReleaseData); /* Convert to native int */
- printf("hvReleaseData is at %08x\n", hvReleaseData);
+ printf("hvReleaseData is at %08lx\n", hvReleaseData);
/* fseek to the hvReleaseData */
fseek(outputVmlinux, ElfHeaderSize + hvReleaseData, SEEK_SET);
if (fread(inbuf, 0x40, 1, outputVmlinux) != 1) {
- death("Could not read hvReleaseData\n", outputVmlinux, argv[4]);
+ death("Could not read hvReleaseData\n", outputVmlinux, out_name);
}
/* Check hvReleaseData sanity */
if (memcmp(inbuf, &eyeCatcher, 4) != 0) {
- death("hvReleaseData is invalid\n", outputVmlinux, argv[4]);
+ death("hvReleaseData is invalid\n", outputVmlinux, out_name);
}
/* Get the naca pointer */
naca = ntohl(*((u_int32_t*) &inbuf[0x0C])) - KERNELBASE;
@@ -269,13 +280,13 @@ int main(int argc, char **argv)
/* fseek to the naca */
fseek(outputVmlinux, ElfHeaderSize + naca, SEEK_SET);
if (fread(inbuf, 0x18, 1, outputVmlinux) != 1) {
- death("Could not read naca\n", outputVmlinux, argv[4]);
+ death("Could not read naca\n", outputVmlinux, out_name);
}
xRamDisk = ntohl(*((u_int32_t *) &inbuf[0x0c]));
xRamDiskSize = ntohl(*((u_int32_t *) &inbuf[0x14]));
/* Make sure a RAM disk isn't already present */
if ((xRamDisk != 0) || (xRamDiskSize != 0)) {
- death("RAM disk is already attached to this kernel\n", outputVmlinux, argv[4]);
+ death("RAM disk is already attached to this kernel\n", outputVmlinux, out_name);
}
/* Fill in the values */
*((u_int32_t *) &inbuf[0x0c]) = htonl(ramStartOffs);
@@ -285,15 +296,15 @@ int main(int argc, char **argv)
fflush(outputVmlinux);
fseek(outputVmlinux, ElfHeaderSize + naca, SEEK_SET);
if (fwrite(inbuf, 0x18, 1, outputVmlinux) != 1) {
- death("Could not write naca\n", outputVmlinux, argv[4]);
+ death("Could not write naca\n", outputVmlinux, out_name);
}
- printf("Ram Disk of 0x%lx pages is attached to the kernel at offset 0x%08x\n",
+ printf("Ram Disk of 0x%lx pages is attached to the kernel at offset 0x%08lx\n",
ramPages, ramStartOffs);
/* Done */
fclose(outputVmlinux);
/* Set permission to executable */
- chmod(argv[4], S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH);
+ chmod(out_name, S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH);
return 0;
}
diff --git a/arch/ppc64/boot/crt0.S b/arch/ppc64/boot/crt0.S
index 3861e7f9cf19..9cc442263939 100644
--- a/arch/ppc64/boot/crt0.S
+++ b/arch/ppc64/boot/crt0.S
@@ -12,11 +12,40 @@
#include "ppc_asm.h"
.text
- .globl _start
-_start:
+ .globl _zimage_start
+_zimage_start:
+ bl reloc_offset
+
+reloc_offset:
+ mflr r0
+ lis r9,reloc_offset@ha
+ addi r9,r9,reloc_offset@l
+ subf. r0,r9,r0
+ beq clear_caches
+
+reloc_got2:
+ lis r9,__got2_start@ha
+ addi r9,r9,__got2_start@l
+ lis r8,__got2_end@ha
+ addi r8,r8,__got2_end@l
+ subf. r8,r9,r8
+ beq clear_caches
+ srwi. r8,r8,2
+ mtctr r8
+ add r9,r0,r9
+reloc_got2_loop:
+ lwz r8,0(r9)
+ add r8,r8,r0
+ stw r8,0(r9)
+ addi r9,r9,4
+ bdnz reloc_got2_loop
+
+clear_caches:
lis r9,_start@h
+ add r9,r0,r9
lis r8,_etext@ha
addi r8,r8,_etext@l
+ add r8,r0,r8
1: dcbf r0,r9
icbi r0,r9
addi r9,r9,0x20
@@ -25,24 +54,6 @@ _start:
sync
isync
- ## Clear out the BSS as per ANSI C requirements
-
- lis r7,_end@ha
- addi r7,r7,_end@l # r7 = &_end
- lis r8,__bss_start@ha #
- addi r8,r8,__bss_start@l # r8 = &_bss_start
-
- ## Determine how large an area, in number of words, to clear
-
- subf r7,r8,r7 # r7 = &_end - &_bss_start + 1
- addi r7,r7,3 # r7 += 3
- srwi. r7,r7,2 # r7 = size in words.
- beq 3f # If the size is zero, don't bother
- addi r8,r8,-4 # r8 -= 4
- mtctr r7 # SPRN_CTR = number of words to clear
- li r0,0 # r0 = 0
-2: stwu r0,4(r8) # Clear out a word
- bdnz 2b # Keep clearing until done
-3:
+ mr r6,r1
b start
diff --git a/arch/ppc64/boot/install.sh b/arch/ppc64/boot/install.sh
index cb2d6626b555..eacce9590816 100644
--- a/arch/ppc64/boot/install.sh
+++ b/arch/ppc64/boot/install.sh
@@ -28,7 +28,7 @@ if [ -x /sbin/${CROSS_COMPILE}installkernel ]; then exec /sbin/${CROSS_COMPILE}i
# Default install
# this should work for both the pSeries zImage and the iSeries vmlinux.sm
-image_name=`basename $5`
+image_name=`basename $2`
if [ -f $4/$image_name ]; then
mv $4/$image_name $4/$image_name.old
diff --git a/arch/ppc64/boot/main.c b/arch/ppc64/boot/main.c
index f7ec19a2d0b0..e0dde24a72ce 100644
--- a/arch/ppc64/boot/main.c
+++ b/arch/ppc64/boot/main.c
@@ -17,7 +17,6 @@
#include "prom.h"
#include "zlib.h"
-static void gunzip(void *, int, unsigned char *, int *);
extern void flush_cache(void *, unsigned long);
@@ -26,31 +25,26 @@ extern void flush_cache(void *, unsigned long);
#define RAM_END (512<<20) // Fixme: use OF */
#define ONE_MB 0x100000
-static char *avail_ram;
-static char *begin_avail, *end_avail;
-static char *avail_high;
-static unsigned int heap_use;
-static unsigned int heap_max;
-
extern char _start[];
+extern char __bss_start[];
extern char _end[];
extern char _vmlinux_start[];
extern char _vmlinux_end[];
extern char _initrd_start[];
extern char _initrd_end[];
-extern unsigned long vmlinux_filesize;
-extern unsigned long vmlinux_memsize;
struct addr_range {
unsigned long addr;
unsigned long size;
unsigned long memsize;
};
-static struct addr_range vmlinux = {0, 0, 0};
-static struct addr_range vmlinuz = {0, 0, 0};
-static struct addr_range initrd = {0, 0, 0};
+static struct addr_range vmlinux;
+static struct addr_range vmlinuz;
+static struct addr_range initrd;
+
+static char scratch[46912]; /* scratch space for gunzip, from zlib_inflate_workspacesize() */
+static char elfheader[256];
-static char scratch[128<<10]; /* 128kB of scratch space for gunzip */
typedef void (*kernel_entry_t)( unsigned long,
unsigned long,
@@ -62,6 +56,63 @@ typedef void (*kernel_entry_t)( unsigned long,
static unsigned long claim_base;
+#define HEAD_CRC 2
+#define EXTRA_FIELD 4
+#define ORIG_NAME 8
+#define COMMENT 0x10
+#define RESERVED 0xe0
+
+static void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp)
+{
+ z_stream s;
+ int r, i, flags;
+
+ /* skip header */
+ i = 10;
+ flags = src[3];
+ if (src[2] != Z_DEFLATED || (flags & RESERVED) != 0) {
+ printf("bad gzipped data\n\r");
+ exit();
+ }
+ if ((flags & EXTRA_FIELD) != 0)
+ i = 12 + src[10] + (src[11] << 8);
+ if ((flags & ORIG_NAME) != 0)
+ while (src[i++] != 0)
+ ;
+ if ((flags & COMMENT) != 0)
+ while (src[i++] != 0)
+ ;
+ if ((flags & HEAD_CRC) != 0)
+ i += 2;
+ if (i >= *lenp) {
+ printf("gunzip: ran out of data in header\n\r");
+ exit();
+ }
+
+ if (zlib_inflate_workspacesize() > sizeof(scratch)) {
+ printf("gunzip needs more mem\n");
+ exit();
+ }
+ memset(&s, 0, sizeof(s));
+ s.workspace = scratch;
+ r = zlib_inflateInit2(&s, -MAX_WBITS);
+ if (r != Z_OK) {
+ printf("inflateInit2 returned %d\n\r", r);
+ exit();
+ }
+ s.next_in = src + i;
+ s.avail_in = *lenp - i;
+ s.next_out = dst;
+ s.avail_out = dstlen;
+ r = zlib_inflate(&s, Z_FULL_FLUSH);
+ if (r != Z_OK && r != Z_STREAM_END) {
+ printf("inflate returned %d msg: %s\n\r", r, s.msg);
+ exit();
+ }
+ *lenp = s.next_out - (unsigned char *) dst;
+ zlib_inflateEnd(&s);
+}
+
static unsigned long try_claim(unsigned long size)
{
unsigned long addr = 0;
@@ -80,13 +131,16 @@ static unsigned long try_claim(unsigned long size)
return addr;
}
-void start(unsigned long a1, unsigned long a2, void *promptr)
+void start(unsigned long a1, unsigned long a2, void *promptr, void *sp)
{
unsigned long i;
+ int len;
kernel_entry_t kernel_entry;
Elf64_Ehdr *elf64;
Elf64_Phdr *elf64ph;
+ memset(__bss_start, 0, _end - __bss_start);
+
prom = (int (*)(void *)) promptr;
chosen_handle = finddevice("/chosen");
if (chosen_handle == (void *) -1)
@@ -97,7 +151,7 @@ void start(unsigned long a1, unsigned long a2, void *promptr)
if (getprop(chosen_handle, "stdin", &stdin, sizeof(stdin)) != 4)
exit();
- printf("\n\rzImage starting: loaded at 0x%lx\n\r", (unsigned long) _start);
+ printf("\n\rzImage starting: loaded at 0x%p (sp: 0x%p)\n\r", _start, sp);
/*
* The first available claim_base must be above the end of the
@@ -118,25 +172,52 @@ void start(unsigned long a1, unsigned long a2, void *promptr)
claim_base = PROG_START;
#endif
- /*
- * Now we try to claim some memory for the kernel itself
- * our "vmlinux_memsize" is the memory footprint in RAM, _HOWEVER_, what
- * our Makefile stuffs in is an image containing all sort of junk including
- * an ELF header. We need to do some calculations here to find the right
- * size... In practice we add 1Mb, that is enough, but we should really
- * consider fixing the Makefile to put a _raw_ kernel in there !
+ vmlinuz.addr = (unsigned long)_vmlinux_start;
+ vmlinuz.size = (unsigned long)(_vmlinux_end - _vmlinux_start);
+
+ /* gunzip the ELF header of the kernel */
+ if (*(unsigned short *)vmlinuz.addr == 0x1f8b) {
+ len = vmlinuz.size;
+ gunzip(elfheader, sizeof(elfheader),
+ (unsigned char *)vmlinuz.addr, &len);
+ } else
+ memcpy(elfheader, (const void *)vmlinuz.addr, sizeof(elfheader));
+
+ elf64 = (Elf64_Ehdr *)elfheader;
+ if ( elf64->e_ident[EI_MAG0] != ELFMAG0 ||
+ elf64->e_ident[EI_MAG1] != ELFMAG1 ||
+ elf64->e_ident[EI_MAG2] != ELFMAG2 ||
+ elf64->e_ident[EI_MAG3] != ELFMAG3 ||
+ elf64->e_ident[EI_CLASS] != ELFCLASS64 ||
+ elf64->e_ident[EI_DATA] != ELFDATA2MSB ||
+ elf64->e_type != ET_EXEC ||
+ elf64->e_machine != EM_PPC64 )
+ {
+ printf("Error: not a valid PPC64 ELF file!\n\r");
+ exit();
+ }
+
+ elf64ph = (Elf64_Phdr *)((unsigned long)elf64 +
+ (unsigned long)elf64->e_phoff);
+ for(i=0; i < (unsigned int)elf64->e_phnum ;i++,elf64ph++) {
+ if (elf64ph->p_type == PT_LOAD && elf64ph->p_offset != 0)
+ break;
+ }
+ vmlinux.size = (unsigned long)elf64ph->p_filesz +
+ (unsigned long)elf64ph->p_offset;
+ /* We need to claim the memsize plus the file offset since gzip
+ * will expand the header (file offset), then the kernel, then
+ * possible rubbish we don't care about. But the kernel bss must
+ * be claimed (it will be zero'd by the kernel itself)
*/
- vmlinux_memsize += ONE_MB;
- printf("Allocating 0x%lx bytes for kernel ...\n\r", vmlinux_memsize);
- vmlinux.addr = try_claim(vmlinux_memsize);
+ vmlinux.memsize = (unsigned long)elf64ph->p_memsz +
+ (unsigned long)elf64ph->p_offset;
+ printf("Allocating 0x%lx bytes for kernel ...\n\r", vmlinux.memsize);
+ vmlinux.addr = try_claim(vmlinux.memsize);
if (vmlinux.addr == 0) {
printf("Can't allocate memory for kernel image !\n\r");
exit();
}
- vmlinuz.addr = (unsigned long)_vmlinux_start;
- vmlinuz.size = (unsigned long)(_vmlinux_end - _vmlinux_start);
- vmlinux.size = PAGE_ALIGN(vmlinux_filesize);
- vmlinux.memsize = vmlinux_memsize;
/*
* Now we try to claim memory for the initrd (and copy it there)
@@ -160,49 +241,22 @@ void start(unsigned long a1, unsigned long a2, void *promptr)
/* Eventually gunzip the kernel */
if (*(unsigned short *)vmlinuz.addr == 0x1f8b) {
- int len;
- avail_ram = scratch;
- begin_avail = avail_high = avail_ram;
- end_avail = scratch + sizeof(scratch);
printf("gunzipping (0x%lx <- 0x%lx:0x%0lx)...",
vmlinux.addr, vmlinuz.addr, vmlinuz.addr+vmlinuz.size);
len = vmlinuz.size;
- gunzip((void *)vmlinux.addr, vmlinux.size,
+ gunzip((void *)vmlinux.addr, vmlinux.memsize,
(unsigned char *)vmlinuz.addr, &len);
printf("done 0x%lx bytes\n\r", len);
- printf("0x%x bytes of heap consumed, max in use 0x%x\n\r",
- (unsigned)(avail_high - begin_avail), heap_max);
} else {
memmove((void *)vmlinux.addr,(void *)vmlinuz.addr,vmlinuz.size);
}
/* Skip over the ELF header */
- elf64 = (Elf64_Ehdr *)vmlinux.addr;
- if ( elf64->e_ident[EI_MAG0] != ELFMAG0 ||
- elf64->e_ident[EI_MAG1] != ELFMAG1 ||
- elf64->e_ident[EI_MAG2] != ELFMAG2 ||
- elf64->e_ident[EI_MAG3] != ELFMAG3 ||
- elf64->e_ident[EI_CLASS] != ELFCLASS64 ||
- elf64->e_ident[EI_DATA] != ELFDATA2MSB ||
- elf64->e_type != ET_EXEC ||
- elf64->e_machine != EM_PPC64 )
- {
- printf("Error: not a valid PPC64 ELF file!\n\r");
- exit();
- }
-
- elf64ph = (Elf64_Phdr *)((unsigned long)elf64 +
- (unsigned long)elf64->e_phoff);
- for(i=0; i < (unsigned int)elf64->e_phnum ;i++,elf64ph++) {
- if (elf64ph->p_type == PT_LOAD && elf64ph->p_offset != 0)
- break;
- }
#ifdef DEBUG
printf("... skipping 0x%lx bytes of ELF header\n\r",
(unsigned long)elf64ph->p_offset);
#endif
vmlinux.addr += (unsigned long)elf64ph->p_offset;
- vmlinux.size -= (unsigned long)elf64ph->p_offset;
flush_cache((void *)vmlinux.addr, vmlinux.size);
@@ -225,108 +279,3 @@ void start(unsigned long a1, unsigned long a2, void *promptr)
exit();
}
-struct memchunk {
- unsigned int size;
- unsigned int pad;
- struct memchunk *next;
-};
-
-static struct memchunk *freechunks;
-
-void *zalloc(void *x, unsigned items, unsigned size)
-{
- void *p;
- struct memchunk **mpp, *mp;
-
- size *= items;
- size = _ALIGN(size, sizeof(struct memchunk));
- heap_use += size;
- if (heap_use > heap_max)
- heap_max = heap_use;
- for (mpp = &freechunks; (mp = *mpp) != 0; mpp = &mp->next) {
- if (mp->size == size) {
- *mpp = mp->next;
- return mp;
- }
- }
- p = avail_ram;
- avail_ram += size;
- if (avail_ram > avail_high)
- avail_high = avail_ram;
- if (avail_ram > end_avail) {
- printf("oops... out of memory\n\r");
- pause();
- }
- return p;
-}
-
-void zfree(void *x, void *addr, unsigned nb)
-{
- struct memchunk *mp = addr;
-
- nb = _ALIGN(nb, sizeof(struct memchunk));
- heap_use -= nb;
- if (avail_ram == addr + nb) {
- avail_ram = addr;
- return;
- }
- mp->size = nb;
- mp->next = freechunks;
- freechunks = mp;
-}
-
-#define HEAD_CRC 2
-#define EXTRA_FIELD 4
-#define ORIG_NAME 8
-#define COMMENT 0x10
-#define RESERVED 0xe0
-
-#define DEFLATED 8
-
-static void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp)
-{
- z_stream s;
- int r, i, flags;
-
- /* skip header */
- i = 10;
- flags = src[3];
- if (src[2] != DEFLATED || (flags & RESERVED) != 0) {
- printf("bad gzipped data\n\r");
- exit();
- }
- if ((flags & EXTRA_FIELD) != 0)
- i = 12 + src[10] + (src[11] << 8);
- if ((flags & ORIG_NAME) != 0)
- while (src[i++] != 0)
- ;
- if ((flags & COMMENT) != 0)
- while (src[i++] != 0)
- ;
- if ((flags & HEAD_CRC) != 0)
- i += 2;
- if (i >= *lenp) {
- printf("gunzip: ran out of data in header\n\r");
- exit();
- }
-
- s.zalloc = zalloc;
- s.zfree = zfree;
- r = inflateInit2(&s, -MAX_WBITS);
- if (r != Z_OK) {
- printf("inflateInit2 returned %d\n\r", r);
- exit();
- }
- s.next_in = src + i;
- s.avail_in = *lenp - i;
- s.next_out = dst;
- s.avail_out = dstlen;
- r = inflate(&s, Z_FINISH);
- if (r != Z_OK && r != Z_STREAM_END) {
- printf("inflate returned %d msg: %s\n\r", r, s.msg);
- exit();
- }
- *lenp = s.next_out - (unsigned char *) dst;
- inflateEnd(&s);
-}
-
diff --git a/arch/ppc64/boot/string.S b/arch/ppc64/boot/string.S
index 7ade87ae7718..b1eeaed7db17 100644
--- a/arch/ppc64/boot/string.S
+++ b/arch/ppc64/boot/string.S
@@ -104,7 +104,7 @@ memmove:
.globl memcpy
memcpy:
- rlwinm. r7,r5,32-3,3,31 /* r0 = r5 >> 3 */
+ rlwinm. r7,r5,32-3,3,31 /* r7 = r5 >> 3 */
addi r6,r3,-4
addi r4,r4,-4
beq 2f /* if less than 8 bytes to do */
@@ -146,7 +146,7 @@ memcpy:
.globl backwards_memcpy
backwards_memcpy:
- rlwinm. r7,r5,32-3,3,31 /* r0 = r5 >> 3 */
+ rlwinm. r7,r5,32-3,3,31 /* r7 = r5 >> 3 */
add r6,r3,r5
add r4,r4,r5
beq 2f
diff --git a/arch/ppc64/boot/string.h b/arch/ppc64/boot/string.h
index 9289258bcbd6..9fdff1cc0d70 100644
--- a/arch/ppc64/boot/string.h
+++ b/arch/ppc64/boot/string.h
@@ -1,5 +1,6 @@
#ifndef _PPC_BOOT_STRING_H_
#define _PPC_BOOT_STRING_H_
+#include <stddef.h>
extern char *strcpy(char *dest, const char *src);
extern char *strncpy(char *dest, const char *src, size_t n);
diff --git a/arch/ppc64/boot/zImage.lds b/arch/ppc64/boot/zImage.lds
index 8fe5e7071f54..4b6bb3ffe3dc 100644
--- a/arch/ppc64/boot/zImage.lds
+++ b/arch/ppc64/boot/zImage.lds
@@ -1,62 +1,24 @@
OUTPUT_ARCH(powerpc:common)
-SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib);
-/* Do we need any of these for elf?
- __DYNAMIC = 0; */
+ENTRY(_zimage_start)
SECTIONS
{
- /* Read-only sections, merged into text segment: */
- . = + SIZEOF_HEADERS;
- .interp : { *(.interp) }
- .hash : { *(.hash) }
- .dynsym : { *(.dynsym) }
- .dynstr : { *(.dynstr) }
- .rel.text : { *(.rel.text) }
- .rela.text : { *(.rela.text) }
- .rel.data : { *(.rel.data) }
- .rela.data : { *(.rela.data) }
- .rel.rodata : { *(.rel.rodata) }
- .rela.rodata : { *(.rela.rodata) }
- .rel.got : { *(.rel.got) }
- .rela.got : { *(.rela.got) }
- .rel.ctors : { *(.rel.ctors) }
- .rela.ctors : { *(.rela.ctors) }
- .rel.dtors : { *(.rel.dtors) }
- .rela.dtors : { *(.rela.dtors) }
- .rel.bss : { *(.rel.bss) }
- .rela.bss : { *(.rela.bss) }
- .rel.plt : { *(.rel.plt) }
- .rela.plt : { *(.rela.plt) }
- .plt : { *(.plt) }
+ . = (4*1024*1024);
+ _start = .;
.text :
{
*(.text)
*(.fixup)
- *(.got1)
}
- . = ALIGN(4096);
_etext = .;
- PROVIDE (etext = .);
- .rodata :
- {
- *(.rodata)
- *(.rodata1)
- }
- .kstrtab : { *(.kstrtab) }
- __vermagic : { *(__vermagic) }
- .fini : { *(.fini) } =0
- .ctors : { *(.ctors) }
- .dtors : { *(.dtors) }
- /* Read-write section, merged into data segment: */
. = ALIGN(4096);
.data :
{
- *(.data)
- *(.data1)
- *(.sdata)
- *(.sdata2)
- *(.got.plt) *(.got)
- *(.dynamic)
- CONSTRUCTORS
+ *(.rodata*)
+ *(.data*)
+ *(.sdata*)
+ __got2_start = .;
+ *(.got2)
+ __got2_end = .;
}
. = ALIGN(4096);
@@ -71,20 +33,14 @@ SECTIONS
. = ALIGN(4096);
_edata = .;
- PROVIDE (edata = .);
-
- .fixup : { *(.fixup) }
. = ALIGN(4096);
__bss_start = .;
.bss :
{
- *(.sbss) *(.scommon)
- *(.dynbss)
+ *(.sbss)
*(.bss)
- *(COMMON)
}
. = ALIGN(4096);
_end = . ;
- PROVIDE (end = .);
}
diff --git a/arch/ppc64/boot/zlib.c b/arch/ppc64/boot/zlib.c
deleted file mode 100644
index 0d910cd2079d..000000000000
--- a/arch/ppc64/boot/zlib.c
+++ /dev/null
@@ -1,2195 +0,0 @@
-/*
- * This file is derived from various .h and .c files from the zlib-0.95
- * distribution by Jean-loup Gailly and Mark Adler, with some additions
- * by Paul Mackerras to aid in implementing Deflate compression and
- * decompression for PPP packets. See zlib.h for conditions of
- * distribution and use.
- *
- * Changes that have been made include:
- * - changed functions not used outside this file to "local"
- * - added minCompression parameter to deflateInit2
- * - added Z_PACKET_FLUSH (see zlib.h for details)
- * - added inflateIncomp
- *
- Copyright (C) 1995 Jean-loup Gailly and Mark Adler
-
- This software is provided 'as-is', without any express or implied
- warranty. In no event will the authors be held liable for any damages
- arising from the use of this software.
-
- Permission is granted to anyone to use this software for any purpose,
- including commercial applications, and to alter it and redistribute it
- freely, subject to the following restrictions:
-
- 1. The origin of this software must not be misrepresented; you must not
- claim that you wrote the original software. If you use this software
- in a product, an acknowledgment in the product documentation would be
- appreciated but is not required.
- 2. Altered source versions must be plainly marked as such, and must not be
- misrepresented as being the original software.
- 3. This notice may not be removed or altered from any source distribution.
-
- Jean-loup Gailly Mark Adler
- gzip@prep.ai.mit.edu madler@alumni.caltech.edu
-
- *
- *
- */
-
-/*+++++*/
-/* zutil.h -- internal interface and configuration of the compression library
- * Copyright (C) 1995 Jean-loup Gailly.
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* WARNING: this file should *not* be used by applications. It is
- part of the implementation of the compression library and is
- subject to change. Applications should only use zlib.h.
- */
-
-/* From: zutil.h,v 1.9 1995/05/03 17:27:12 jloup Exp */
-
-#define _Z_UTIL_H
-
-#include "zlib.h"
-
-#ifndef local
-# define local static
-#endif
-/* compile with -Dlocal if your debugger can't find static symbols */
-
-#define FAR
-
-typedef unsigned char uch;
-typedef uch FAR uchf;
-typedef unsigned short ush;
-typedef ush FAR ushf;
-typedef unsigned long ulg;
-
-extern char *z_errmsg[]; /* indexed by 1-zlib_error */
-
-#define ERR_RETURN(strm,err) return (strm->msg=z_errmsg[1-err], err)
-/* To be used only when the state is known to be valid */
-
-#ifndef NULL
-#define NULL ((void *) 0)
-#endif
-
- /* common constants */
-
-#define DEFLATED 8
-
-#ifndef DEF_WBITS
-# define DEF_WBITS MAX_WBITS
-#endif
-/* default windowBits for decompression. MAX_WBITS is for compression only */
-
-#if MAX_MEM_LEVEL >= 8
-# define DEF_MEM_LEVEL 8
-#else
-# define DEF_MEM_LEVEL MAX_MEM_LEVEL
-#endif
-/* default memLevel */
-
-#define STORED_BLOCK 0
-#define STATIC_TREES 1
-#define DYN_TREES 2
-/* The three kinds of block type */
-
-#define MIN_MATCH 3
-#define MAX_MATCH 258
-/* The minimum and maximum match lengths */
-
- /* functions */
-
-extern void *memcpy(void *, const void *, unsigned long);
-#define zmemcpy memcpy
-
-/* Diagnostic functions */
-#ifdef DEBUG_ZLIB
-# include "stdio.h"
-# ifndef verbose
-# define verbose 0
-# endif
-# define Assert(cond,msg) {if(!(cond)) z_error(msg);}
-# 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 ;}
-#else
-# define Assert(cond,msg)
-# define Trace(x)
-# define Tracev(x)
-# define Tracevv(x)
-# define Tracec(c,x)
-# define Tracecv(c,x)
-#endif
-
-
-typedef uLong (*check_func) OF((uLong check, Bytef *buf, uInt len));
-
-/* voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size)); */
-/* void zcfree OF((voidpf opaque, voidpf ptr)); */
-
-#define ZALLOC(strm, items, size) \
- (*((strm)->zalloc))((strm)->opaque, (items), (size))
-#define ZFREE(strm, addr, size) \
- (*((strm)->zfree))((strm)->opaque, (voidpf)(addr), (size))
-#define TRY_FREE(s, p, n) {if (p) ZFREE(s, p, n);}
-
-/* deflate.h -- internal compression state
- * Copyright (C) 1995 Jean-loup Gailly
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* WARNING: this file should *not* be used by applications. It is
- part of the implementation of the compression library and is
- subject to change. Applications should only use zlib.h.
- */
-
-/*+++++*/
-/* infblock.h -- header to use infblock.c
- * Copyright (C) 1995 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* WARNING: this file should *not* be used by applications. It is
- part of the implementation of the compression library and is
- subject to change. Applications should only use zlib.h.
- */
-
-struct inflate_blocks_state;
-typedef struct inflate_blocks_state FAR inflate_blocks_statef;
-
-local inflate_blocks_statef * inflate_blocks_new OF((
- z_stream *z,
- check_func c, /* check function */
- uInt w)); /* window size */
-
-local int inflate_blocks OF((
- inflate_blocks_statef *,
- z_stream *,
- int)); /* initial return code */
-
-local void inflate_blocks_reset OF((
- inflate_blocks_statef *,
- z_stream *,
- uLongf *)); /* check value on output */
-
-local int inflate_blocks_free OF((
- inflate_blocks_statef *,
- z_stream *,
- uLongf *)); /* check value on output */
-
-local int inflate_addhistory OF((
- inflate_blocks_statef *,
- z_stream *));
-
-local int inflate_packet_flush OF((
- inflate_blocks_statef *));
-
-/*+++++*/
-/* inftrees.h -- header to use inftrees.c
- * Copyright (C) 1995 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* WARNING: this file should *not* be used by applications. It is
- part of the implementation of the compression library and is
- subject to change. Applications should only use zlib.h.
- */
-
-/* Huffman code lookup table entry--this entry is four bytes for machines
- that have 16-bit pointers (e.g. PC's in the small or medium model). */
-
-typedef struct inflate_huft_s FAR inflate_huft;
-
-struct inflate_huft_s {
- union {
- struct {
- Byte Exop; /* number of extra bits or operation */
- Byte Bits; /* number of bits in this code or subcode */
- } what;
- uInt Nalloc; /* number of these allocated here */
- Bytef *pad; /* pad structure to a power of 2 (4 bytes for */
- } word; /* 16-bit, 8 bytes for 32-bit machines) */
- union {
- uInt Base; /* literal, length base, or distance base */
- inflate_huft *Next; /* pointer to next level of table */
- } more;
-};
-
-#ifdef DEBUG_ZLIB
- local uInt inflate_hufts;
-#endif
-
-local int inflate_trees_bits OF((
- uIntf *, /* 19 code lengths */
- uIntf *, /* bits tree desired/actual depth */
- inflate_huft * FAR *, /* bits tree result */
- z_stream *)); /* for zalloc, zfree functions */
-
-local int inflate_trees_dynamic OF((
- uInt, /* number of literal/length codes */
- uInt, /* number of distance codes */
- uIntf *, /* that many (total) code lengths */
- uIntf *, /* literal desired/actual bit depth */
- uIntf *, /* distance desired/actual bit depth */
- inflate_huft * FAR *, /* literal/length tree result */
- inflate_huft * FAR *, /* distance tree result */
- z_stream *)); /* for zalloc, zfree functions */
-
-local int inflate_trees_fixed OF((
- uIntf *, /* literal desired/actual bit depth */
- uIntf *, /* distance desired/actual bit depth */
- inflate_huft * FAR *, /* literal/length tree result */
- inflate_huft * FAR *)); /* distance tree result */
-
-local int inflate_trees_free OF((
- inflate_huft *, /* tables to free */
- z_stream *)); /* for zfree function */
-
-
-/*+++++*/
-/* infcodes.h -- header to use infcodes.c
- * Copyright (C) 1995 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* WARNING: this file should *not* be used by applications. It is
- part of the implementation of the compression library and is
- subject to change. Applications should only use zlib.h.
- */
-
-struct inflate_codes_state;
-typedef struct inflate_codes_state FAR inflate_codes_statef;
-
-local inflate_codes_statef *inflate_codes_new OF((
- uInt, uInt,
- inflate_huft *, inflate_huft *,
- z_stream *));
-
-local int inflate_codes OF((
- inflate_blocks_statef *,
- z_stream *,
- int));
-
-local void inflate_codes_free OF((
- inflate_codes_statef *,
- z_stream *));
-
-
-/*+++++*/
-/* inflate.c -- zlib interface to inflate modules
- * Copyright (C) 1995 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* inflate private state */
-struct internal_state {
-
- /* mode */
- enum {
- METHOD, /* waiting for method byte */
- FLAG, /* waiting for flag byte */
- BLOCKS, /* decompressing blocks */
- CHECK4, /* four check bytes to go */
- CHECK3, /* three check bytes to go */
- CHECK2, /* two check bytes to go */
- CHECK1, /* one check byte to go */
- DONE, /* finished check, done */
- BAD} /* got an error--stay here */
- mode; /* current inflate mode */
-
- /* mode dependent information */
- union {
- uInt method; /* if FLAGS, method byte */
- struct {
- uLong was; /* computed check value */
- uLong need; /* stream check value */
- } check; /* if CHECK, check values to compare */
- uInt marker; /* if BAD, inflateSync's marker bytes count */
- } sub; /* submode */
-
- /* mode independent information */
- int nowrap; /* flag for no wrapper */
- uInt wbits; /* log2(window size) (8..15, defaults to 15) */
- inflate_blocks_statef
- *blocks; /* current inflate_blocks state */
-
-};
-
-
-int inflateReset(
- z_stream *z
-)
-{
- uLong c;
-
- if (z == Z_NULL || z->state == Z_NULL)
- return Z_STREAM_ERROR;
- z->total_in = z->total_out = 0;
- z->msg = Z_NULL;
- z->state->mode = z->state->nowrap ? BLOCKS : METHOD;
- inflate_blocks_reset(z->state->blocks, z, &c);
- Trace((stderr, "inflate: reset\n"));
- return Z_OK;
-}
-
-
-int inflateEnd(
- z_stream *z
-)
-{
- uLong c;
-
- if (z == Z_NULL || z->state == Z_NULL || z->zfree == Z_NULL)
- return Z_STREAM_ERROR;
- if (z->state->blocks != Z_NULL)
- inflate_blocks_free(z->state->blocks, z, &c);
- ZFREE(z, z->state, sizeof(struct internal_state));
- z->state = Z_NULL;
- Trace((stderr, "inflate: end\n"));
- return Z_OK;
-}
-
-
-int inflateInit2(
- z_stream *z,
- int w
-)
-{
- /* initialize state */
- if (z == Z_NULL)
- return Z_STREAM_ERROR;
-/* if (z->zalloc == Z_NULL) z->zalloc = zcalloc; */
-/* if (z->zfree == Z_NULL) z->zfree = zcfree; */
- if ((z->state = (struct internal_state FAR *)
- ZALLOC(z,1,sizeof(struct internal_state))) == Z_NULL)
- return Z_MEM_ERROR;
- z->state->blocks = Z_NULL;
-
- /* handle undocumented nowrap option (no zlib header or check) */
- z->state->nowrap = 0;
- if (w < 0)
- {
- w = - w;
- z->state->nowrap = 1;
- }
-
- /* set window size */
- if (w < 8 || w > 15)
- {
- inflateEnd(z);
- return Z_STREAM_ERROR;
- }
- z->state->wbits = (uInt)w;
-
- /* create inflate_blocks state */
- if ((z->state->blocks =
- inflate_blocks_new(z, z->state->nowrap ? Z_NULL : adler32, 1 << w))
- == Z_NULL)
- {
- inflateEnd(z);
- return Z_MEM_ERROR;
- }
- Trace((stderr, "inflate: allocated\n"));
-
- /* reset state */
- inflateReset(z);
- return Z_OK;
-}
-
-
-int inflateInit(
- z_stream *z
-)
-{
- return inflateInit2(z, DEF_WBITS);
-}
-
-
-#define NEEDBYTE {if(z->avail_in==0)goto empty;r=Z_OK;}
-#define NEXTBYTE (z->avail_in--,z->total_in++,*z->next_in++)
-
-int inflate(
- z_stream *z,
- int f
-)
-{
- int r;
- uInt b;
-
- if (z == Z_NULL || z->next_in == Z_NULL)
- return Z_STREAM_ERROR;
- r = Z_BUF_ERROR;
- while (1) switch (z->state->mode)
- {
- case METHOD:
- NEEDBYTE
- if (((z->state->sub.method = NEXTBYTE) & 0xf) != DEFLATED)
- {
- z->state->mode = BAD;
- z->msg = "unknown compression method";
- z->state->sub.marker = 5; /* can't try inflateSync */
- break;
- }
- if ((z->state->sub.method >> 4) + 8 > z->state->wbits)
- {
- z->state->mode = BAD;
- z->msg = "invalid window size";
- z->state->sub.marker = 5; /* can't try inflateSync */
- break;
- }
- z->state->mode = FLAG;
- case FLAG:
- NEEDBYTE
- if ((b = NEXTBYTE) & 0x20)
- {
- z->state->mode = BAD;
- z->msg = "invalid reserved bit";
- z->state->sub.marker = 5; /* can't try inflateSync */
- break;
- }
- if (((z->state->sub.method << 8) + b) % 31)
- {
- z->state->mode = BAD;
- z->msg = "incorrect header check";
- z->state->sub.marker = 5; /* can't try inflateSync */
- break;
- }
- Trace((stderr, "inflate: zlib header ok\n"));
- z->state->mode = BLOCKS;
- case BLOCKS:
- r = inflate_blocks(z->state->blocks, z, r);
- if (f == Z_PACKET_FLUSH && z->avail_in == 0 && z->avail_out != 0)
- r = inflate_packet_flush(z->state->blocks);
- if (r == Z_DATA_ERROR)
- {
- z->state->mode = BAD;
- z->state->sub.marker = 0; /* can try inflateSync */
- break;
- }
- if (r != Z_STREAM_END)
- return r;
- r = Z_OK;
- inflate_blocks_reset(z->state->blocks, z, &z->state->sub.check.was);
- if (z->state->nowrap)
- {
- z->state->mode = DONE;
- break;
- }
- z->state->mode = CHECK4;
- case CHECK4:
- NEEDBYTE
- z->state->sub.check.need = (uLong)NEXTBYTE << 24;
- z->state->mode = CHECK3;
- case CHECK3:
- NEEDBYTE
- z->state->sub.check.need += (uLong)NEXTBYTE << 16;
- z->state->mode = CHECK2;
- case CHECK2:
- NEEDBYTE
- z->state->sub.check.need += (uLong)NEXTBYTE << 8;
- z->state->mode = CHECK1;
- case CHECK1:
- NEEDBYTE
- z->state->sub.check.need += (uLong)NEXTBYTE;
-
- if (z->state->sub.check.was != z->state->sub.check.need)
- {
- z->state->mode = BAD;
- z->msg = "incorrect data check";
- z->state->sub.marker = 5; /* can't try inflateSync */
- break;
- }
- Trace((stderr, "inflate: zlib check ok\n"));
- z->state->mode = DONE;
- case DONE:
- return Z_STREAM_END;
- case BAD:
- return Z_DATA_ERROR;
- default:
- return Z_STREAM_ERROR;
- }
-
- empty:
- if (f != Z_PACKET_FLUSH)
- return r;
- z->state->mode = BAD;
- z->state->sub.marker = 0; /* can try inflateSync */
- return Z_DATA_ERROR;
-}
-
-/*
- * This subroutine adds the data at next_in/avail_in to the output history
- * without performing any output. The output buffer must be "caught up";
- * i.e. no pending output (hence s->read equals s->write), and the state must
- * be BLOCKS (i.e. we should be willing to see the start of a series of
- * BLOCKS). On exit, the output will also be caught up, and the checksum
- * will have been updated if need be.
- */
-
-int inflateIncomp(
- z_stream *z
-)
-{
- if (z->state->mode != BLOCKS)
- return Z_DATA_ERROR;
- return inflate_addhistory(z->state->blocks, z);
-}
-
-
-int inflateSync(
- z_stream *z
-)
-{
- uInt n; /* number of bytes to look at */
- Bytef *p; /* pointer to bytes */
- uInt m; /* number of marker bytes found in a row */
- uLong r, w; /* temporaries to save total_in and total_out */
-
- /* set up */
- if (z == Z_NULL || z->state == Z_NULL)
- return Z_STREAM_ERROR;
- if (z->state->mode != BAD)
- {
- z->state->mode = BAD;
- z->state->sub.marker = 0;
- }
- if ((n = z->avail_in) == 0)
- return Z_BUF_ERROR;
- p = z->next_in;
- m = z->state->sub.marker;
-
- /* search */
- while (n && m < 4)
- {
- if (*p == (Byte)(m < 2 ? 0 : 0xff))
- m++;
- else if (*p)
- m = 0;
- else
- m = 4 - m;
- p++, n--;
- }
-
- /* restore */
- z->total_in += p - z->next_in;
- z->next_in = p;
- z->avail_in = n;
- z->state->sub.marker = m;
-
- /* return no joy or set up to restart on a new block */
- if (m != 4)
- return Z_DATA_ERROR;
- r = z->total_in; w = z->total_out;
- inflateReset(z);
- z->total_in = r; z->total_out = w;
- z->state->mode = BLOCKS;
- return Z_OK;
-}
-
-#undef NEEDBYTE
-#undef NEXTBYTE
-
-/*+++++*/
-/* infutil.h -- types and macros common to blocks and codes
- * Copyright (C) 1995 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* WARNING: this file should *not* be used by applications. It is
- part of the implementation of the compression library and is
- subject to change. Applications should only use zlib.h.
- */
-
-/* inflate blocks semi-private state */
-struct inflate_blocks_state {
-
- /* mode */
- enum {
- TYPE, /* get type bits (3, including end bit) */
- LENS, /* get lengths for stored */
- STORED, /* processing stored block */
- TABLE, /* get table lengths */
- BTREE, /* get bit lengths tree for a dynamic block */
- DTREE, /* get length, distance trees for a dynamic block */
- CODES, /* processing fixed or dynamic block */
- DRY, /* output remaining window bytes */
- DONEB, /* finished last block, done */
- BADB} /* got a data error--stuck here */
- mode; /* current inflate_block mode */
-
- /* mode dependent information */
- union {
- uInt left; /* if STORED, bytes left to copy */
- struct {
- uInt table; /* table lengths (14 bits) */
- uInt index; /* index into blens (or border) */
- uIntf *blens; /* bit lengths of codes */
- uInt bb; /* bit length tree depth */
- inflate_huft *tb; /* bit length decoding tree */
- int nblens; /* # elements allocated at blens */
- } trees; /* if DTREE, decoding info for trees */
- struct {
- inflate_huft *tl, *td; /* trees to free */
- inflate_codes_statef
- *codes;
- } decode; /* if CODES, current state */
- } sub; /* submode */
- uInt last; /* true if this block is the last block */
-
- /* mode independent information */
- uInt bitk; /* bits in bit buffer */
- uLong bitb; /* bit buffer */
- Bytef *window; /* sliding window */
- Bytef *end; /* one byte after sliding window */
- Bytef *read; /* window read pointer */
- Bytef *write; /* window write pointer */
- check_func checkfn; /* check function */
- uLong check; /* check on output */
-
-};
-
-
-/* defines for inflate input/output */
-/* update pointers and return */
-#define UPDBITS {s->bitb=b;s->bitk=k;}
-#define UPDIN {z->avail_in=n;z->total_in+=p-z->next_in;z->next_in=p;}
-#define UPDOUT {s->write=q;}
-#define UPDATE {UPDBITS UPDIN UPDOUT}
-#define LEAVE {UPDATE return inflate_flush(s,z,r);}
-/* get bytes and bits */
-#define LOADIN {p=z->next_in;n=z->avail_in;b=s->bitb;k=s->bitk;}
-#define NEEDBYTE {if(n)r=Z_OK;else LEAVE}
-#define NEXTBYTE (n--,*p++)
-#define NEEDBITS(j) {while(k<(j)){NEEDBYTE;b|=((uLong)NEXTBYTE)<<k;k+=8;}}
-#define DUMPBITS(j) {b>>=(j);k-=(j);}
-/* output bytes */
-#define WAVAIL (q<s->read?s->read-q-1:s->end-q)
-#define LOADOUT {q=s->write;m=WAVAIL;}
-#define WRAP {if(q==s->end&&s->read!=s->window){q=s->window;m=WAVAIL;}}
-#define FLUSH {UPDOUT r=inflate_flush(s,z,r); LOADOUT}
-#define NEEDOUT {if(m==0){WRAP if(m==0){FLUSH WRAP if(m==0) LEAVE}}r=Z_OK;}
-#define OUTBYTE(a) {*q++=(Byte)(a);m--;}
-/* load local pointers */
-#define LOAD {LOADIN LOADOUT}
-
-/* And'ing with mask[n] masks the lower n bits */
-local uInt inflate_mask[] = {
- 0x0000,
- 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff,
- 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff
-};
-
-/* copy as much as possible from the sliding window to the output area */
-local int inflate_flush OF((
- inflate_blocks_statef *,
- z_stream *,
- int));
-
-/*+++++*/
-/* inffast.h -- header to use inffast.c
- * Copyright (C) 1995 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* WARNING: this file should *not* be used by applications. It is
- part of the implementation of the compression library and is
- subject to change. Applications should only use zlib.h.
- */
-
-local int inflate_fast OF((
- uInt,
- uInt,
- inflate_huft *,
- inflate_huft *,
- inflate_blocks_statef *,
- z_stream *));
-
-
-/*+++++*/
-/* infblock.c -- interpret and process block types to last block
- * Copyright (C) 1995 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* Table for deflate from PKZIP's appnote.txt. */
-local uInt border[] = { /* Order of the bit length code lengths */
- 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
-
-/*
- Notes beyond the 1.93a appnote.txt:
-
- 1. Distance pointers never point before the beginning of the output
- stream.
- 2. Distance pointers can point back across blocks, up to 32k away.
- 3. There is an implied maximum of 7 bits for the bit length table and
- 15 bits for the actual data.
- 4. If only one code exists, then it is encoded using one bit. (Zero
- would be more efficient, but perhaps a little confusing.) If two
- codes exist, they are coded using one bit each (0 and 1).
- 5. There is no way of sending zero distance codes--a dummy must be
- sent if there are none. (History: a pre 2.0 version of PKZIP would
- store blocks with no distance codes, but this was discovered to be
- too harsh a criterion.) Valid only for 1.93a. 2.04c does allow
- zero distance codes, which is sent as one code of zero bits in
- length.
- 6. There are up to 286 literal/length codes. Code 256 represents the
- end-of-block. Note however that the static length tree defines
- 288 codes just to fill out the Huffman codes. Codes 286 and 287
- cannot be used though, since there is no length base or extra bits
- defined for them. Similarily, there are up to 30 distance codes.
- However, static trees define 32 codes (all 5 bits) to fill out the
- Huffman codes, but the last two had better not show up in the data.
- 7. Unzip can check dynamic Huffman blocks for complete code sets.
- The exception is that a single code would not be complete (see #4).
- 8. The five bits following the block type is really the number of
- literal codes sent minus 257.
- 9. Length codes 8,16,16 are interpreted as 13 length codes of 8 bits
- (1+6+6). Therefore, to output three times the length, you output
- three codes (1+1+1), whereas to output four times the same length,
- you only need two codes (1+3). Hmm.
- 10. In the tree reconstruction algorithm, Code = Code + Increment
- only if BitLength(i) is not zero. (Pretty obvious.)
- 11. Correction: 4 Bits: # of Bit Length codes - 4 (4 - 19)
- 12. Note: length code 284 can represent 227-258, but length code 285
- really is 258. The last length deserves its own, short code
- since it gets used a lot in very redundant files. The length
- 258 is special since 258 - 3 (the min match length) is 255.
- 13. The literal/length and distance code bit lengths are read as a
- single stream of lengths. It is possible (and advantageous) for
- a repeat code (16, 17, or 18) to go across the boundary between
- the two sets of lengths.
- */
-
-
-local void inflate_blocks_reset(
- inflate_blocks_statef *s,
- z_stream *z,
- uLongf *c
-)
-{
- if (s->checkfn != Z_NULL)
- *c = s->check;
- if (s->mode == BTREE || s->mode == DTREE)
- ZFREE(z, s->sub.trees.blens, s->sub.trees.nblens * sizeof(uInt));
- if (s->mode == CODES)
- {
- inflate_codes_free(s->sub.decode.codes, z);
- inflate_trees_free(s->sub.decode.td, z);
- inflate_trees_free(s->sub.decode.tl, z);
- }
- s->mode = TYPE;
- s->bitk = 0;
- s->bitb = 0;
- s->read = s->write = s->window;
- if (s->checkfn != Z_NULL)
- s->check = (*s->checkfn)(0L, Z_NULL, 0);
- Trace((stderr, "inflate: blocks reset\n"));
-}
-
-
-local inflate_blocks_statef *inflate_blocks_new(
- z_stream *z,
- check_func c,
- uInt w
-)
-{
- inflate_blocks_statef *s;
-
- if ((s = (inflate_blocks_statef *)ZALLOC
- (z,1,sizeof(struct inflate_blocks_state))) == Z_NULL)
- return s;
- if ((s->window = (Bytef *)ZALLOC(z, 1, w)) == Z_NULL)
- {
- ZFREE(z, s, sizeof(struct inflate_blocks_state));
- return Z_NULL;
- }
- s->end = s->window + w;
- s->checkfn = c;
- s->mode = TYPE;
- Trace((stderr, "inflate: blocks allocated\n"));
- inflate_blocks_reset(s, z, &s->check);
- return s;
-}
-
-
-local int inflate_blocks(
- inflate_blocks_statef *s,
- z_stream *z,
- int r
-)
-{
- uInt t; /* temporary storage */
- uLong b; /* bit buffer */
- uInt k; /* bits in bit buffer */
- Bytef *p; /* input data pointer */
- uInt n; /* bytes available there */
- Bytef *q; /* output window write pointer */
- uInt m; /* bytes to end of window or read pointer */
-
- /* copy input/output information to locals (UPDATE macro restores) */
- LOAD
-
- /* process input based on current state */
- while (1) switch (s->mode)
- {
- case TYPE:
- NEEDBITS(3)
- t = (uInt)b & 7;
- s->last = t & 1;
- switch (t >> 1)
- {
- case 0: /* stored */
- Trace((stderr, "inflate: stored block%s\n",
- s->last ? " (last)" : ""));
- DUMPBITS(3)
- t = k & 7; /* go to byte boundary */
- DUMPBITS(t)
- s->mode = LENS; /* get length of stored block */
- break;
- case 1: /* fixed */
- Trace((stderr, "inflate: fixed codes block%s\n",
- s->last ? " (last)" : ""));
- {
- uInt bl, bd;
- inflate_huft *tl, *td;
-
- inflate_trees_fixed(&bl, &bd, &tl, &td);
- s->sub.decode.codes = inflate_codes_new(bl, bd, tl, td, z);
- if (s->sub.decode.codes == Z_NULL)
- {
- r = Z_MEM_ERROR;
- LEAVE
- }
- s->sub.decode.tl = Z_NULL; /* don't try to free these */
- s->sub.decode.td = Z_NULL;
- }
- DUMPBITS(3)
- s->mode = CODES;
- break;
- case 2: /* dynamic */
- Trace((stderr, "inflate: dynamic codes block%s\n",
- s->last ? " (last)" : ""));
- DUMPBITS(3)
- s->mode = TABLE;
- break;
- case 3: /* illegal */
- DUMPBITS(3)
- s->mode = BADB;
- z->msg = "invalid block type";
- r = Z_DATA_ERROR;
- LEAVE
- }
- break;
- case LENS:
- NEEDBITS(32)
- if (((~b) >> 16) != (b & 0xffff))
- {
- s->mode = BADB;
- z->msg = "invalid stored block lengths";
- r = Z_DATA_ERROR;
- LEAVE
- }
- s->sub.left = (uInt)b & 0xffff;
- b = k = 0; /* dump bits */
- Tracev((stderr, "inflate: stored length %u\n", s->sub.left));
- s->mode = s->sub.left ? STORED : TYPE;
- break;
- case STORED:
- if (n == 0)
- LEAVE
- NEEDOUT
- t = s->sub.left;
- if (t > n) t = n;
- if (t > m) t = m;
- zmemcpy(q, p, t);
- p += t; n -= t;
- q += t; m -= t;
- if ((s->sub.left -= t) != 0)
- break;
- Tracev((stderr, "inflate: stored end, %lu total out\n",
- z->total_out + (q >= s->read ? q - s->read :
- (s->end - s->read) + (q - s->window))));
- s->mode = s->last ? DRY : TYPE;
- break;
- case TABLE:
- NEEDBITS(14)
- s->sub.trees.table = t = (uInt)b & 0x3fff;
-#ifndef PKZIP_BUG_WORKAROUND
- if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29)
- {
- s->mode = BADB;
- z->msg = "too many length or distance symbols";
- r = Z_DATA_ERROR;
- LEAVE
- }
-#endif
- t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f);
- if (t < 19)
- t = 19;
- if ((s->sub.trees.blens = (uIntf*)ZALLOC(z, t, sizeof(uInt))) == Z_NULL)
- {
- r = Z_MEM_ERROR;
- LEAVE
- }
- s->sub.trees.nblens = t;
- DUMPBITS(14)
- s->sub.trees.index = 0;
- Tracev((stderr, "inflate: table sizes ok\n"));
- s->mode = BTREE;
- case BTREE:
- while (s->sub.trees.index < 4 + (s->sub.trees.table >> 10))
- {
- NEEDBITS(3)
- s->sub.trees.blens[border[s->sub.trees.index++]] = (uInt)b & 7;
- DUMPBITS(3)
- }
- while (s->sub.trees.index < 19)
- s->sub.trees.blens[border[s->sub.trees.index++]] = 0;
- s->sub.trees.bb = 7;
- t = inflate_trees_bits(s->sub.trees.blens, &s->sub.trees.bb,
- &s->sub.trees.tb, z);
- if (t != Z_OK)
- {
- r = t;
- if (r == Z_DATA_ERROR)
- s->mode = BADB;
- LEAVE
- }
- s->sub.trees.index = 0;
- Tracev((stderr, "inflate: bits tree ok\n"));
- s->mode = DTREE;
- case DTREE:
- while (t = s->sub.trees.table,
- s->sub.trees.index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f))
- {
- inflate_huft *h;
- uInt i, j, c;
-
- t = s->sub.trees.bb;
- NEEDBITS(t)
- h = s->sub.trees.tb + ((uInt)b & inflate_mask[t]);
- t = h->word.what.Bits;
- c = h->more.Base;
- if (c < 16)
- {
- DUMPBITS(t)
- s->sub.trees.blens[s->sub.trees.index++] = c;
- }
- else /* c == 16..18 */
- {
- i = c == 18 ? 7 : c - 14;
- j = c == 18 ? 11 : 3;
- NEEDBITS(t + i)
- DUMPBITS(t)
- j += (uInt)b & inflate_mask[i];
- DUMPBITS(i)
- i = s->sub.trees.index;
- t = s->sub.trees.table;
- if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) ||
- (c == 16 && i < 1))
- {
- s->mode = BADB;
- z->msg = "invalid bit length repeat";
- r = Z_DATA_ERROR;
- LEAVE
- }
- c = c == 16 ? s->sub.trees.blens[i - 1] : 0;
- do {
- s->sub.trees.blens[i++] = c;
- } while (--j);
- s->sub.trees.index = i;
- }
- }
- inflate_trees_free(s->sub.trees.tb, z);
- s->sub.trees.tb = Z_NULL;
- {
- uInt bl, bd;
- inflate_huft *tl, *td;
- inflate_codes_statef *c;
-
- bl = 9; /* must be <= 9 for lookahead assumptions */
- bd = 6; /* must be <= 9 for lookahead assumptions */
- t = s->sub.trees.table;
- t = inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f),
- s->sub.trees.blens, &bl, &bd, &tl, &td, z);
- if (t != Z_OK)
- {
- if (t == (uInt)Z_DATA_ERROR)
- s->mode = BADB;
- r = t;
- LEAVE
- }
- Tracev((stderr, "inflate: trees ok\n"));
- if ((c = inflate_codes_new(bl, bd, tl, td, z)) == Z_NULL)
- {
- inflate_trees_free(td, z);
- inflate_trees_free(tl, z);
- r = Z_MEM_ERROR;
- LEAVE
- }
- ZFREE(z, s->sub.trees.blens, s->sub.trees.nblens * sizeof(uInt));
- s->sub.decode.codes = c;
- s->sub.decode.tl = tl;
- s->sub.decode.td = td;
- }
- s->mode = CODES;
- case CODES:
- UPDATE
- if ((r = inflate_codes(s, z, r)) != Z_STREAM_END)
- return inflate_flush(s, z, r);
- r = Z_OK;
- inflate_codes_free(s->sub.decode.codes, z);
- inflate_trees_free(s->sub.decode.td, z);
- inflate_trees_free(s->sub.decode.tl, z);
- LOAD
- Tracev((stderr, "inflate: codes end, %lu total out\n",
- z->total_out + (q >= s->read ? q - s->read :
- (s->end - s->read) + (q - s->window))));
- if (!s->last)
- {
- s->mode = TYPE;
- break;
- }
- if (k > 7) /* return unused byte, if any */
- {
- Assert(k < 16, "inflate_codes grabbed too many bytes")
- k -= 8;
- n++;
- p--; /* can always return one */
- }
- s->mode = DRY;
- case DRY:
- FLUSH
- if (s->read != s->write)
- LEAVE
- s->mode = DONEB;
- case DONEB:
- r = Z_STREAM_END;
- LEAVE
- case BADB:
- r = Z_DATA_ERROR;
- LEAVE
- default:
- r = Z_STREAM_ERROR;
- LEAVE
- }
-}
-
-
-local int inflate_blocks_free(
- inflate_blocks_statef *s,
- z_stream *z,
- uLongf *c
-)
-{
- inflate_blocks_reset(s, z, c);
- ZFREE(z, s->window, s->end - s->window);
- ZFREE(z, s, sizeof(struct inflate_blocks_state));
- Trace((stderr, "inflate: blocks freed\n"));
- return Z_OK;
-}
-
-/*
- * This subroutine adds the data at next_in/avail_in to the output history
- * without performing any output. The output buffer must be "caught up";
- * i.e. no pending output (hence s->read equals s->write), and the state must
- * be BLOCKS (i.e. we should be willing to see the start of a series of
- * BLOCKS). On exit, the output will also be caught up, and the checksum
- * will have been updated if need be.
- */
-local int inflate_addhistory(
- inflate_blocks_statef *s,
- z_stream *z
-)
-{
- uLong b; /* bit buffer */ /* NOT USED HERE */
- uInt k; /* bits in bit buffer */ /* NOT USED HERE */
- uInt t; /* temporary storage */
- Bytef *p; /* input data pointer */
- uInt n; /* bytes available there */
- Bytef *q; /* output window write pointer */
- uInt m; /* bytes to end of window or read pointer */
-
- if (s->read != s->write)
- return Z_STREAM_ERROR;
- if (s->mode != TYPE)
- return Z_DATA_ERROR;
-
- /* we're ready to rock */
- LOAD
- /* while there is input ready, copy to output buffer, moving
- * pointers as needed.
- */
- while (n) {
- t = n; /* how many to do */
- /* is there room until end of buffer? */
- if (t > m) t = m;
- /* update check information */
- if (s->checkfn != Z_NULL)
- s->check = (*s->checkfn)(s->check, q, t);
- zmemcpy(q, p, t);
- q += t;
- p += t;
- n -= t;
- z->total_out += t;
- s->read = q; /* drag read pointer forward */
-/* WRAP */ /* expand WRAP macro by hand to handle s->read */
- if (q == s->end) {
- s->read = q = s->window;
- m = WAVAIL;
- }
- }
- UPDATE
- return Z_OK;
-}
-
-
-/*
- * At the end of a Deflate-compressed PPP packet, we expect to have seen
- * a `stored' block type value but not the (zero) length bytes.
- */
-local int inflate_packet_flush(
- inflate_blocks_statef *s
-)
-{
- if (s->mode != LENS)
- return Z_DATA_ERROR;
- s->mode = TYPE;
- return Z_OK;
-}
-
-
-/*+++++*/
-/* inftrees.c -- generate Huffman trees for efficient decoding
- * Copyright (C) 1995 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* simplify the use of the inflate_huft type with some defines */
-#define base more.Base
-#define next more.Next
-#define exop word.what.Exop
-#define bits word.what.Bits
-
-
-local int huft_build OF((
- uIntf *, /* code lengths in bits */
- uInt, /* number of codes */
- uInt, /* number of "simple" codes */
- uIntf *, /* list of base values for non-simple codes */
- uIntf *, /* list of extra bits for non-simple codes */
- inflate_huft * FAR*,/* result: starting table */
- uIntf *, /* maximum lookup bits (returns actual) */
- z_stream *)); /* for zalloc function */
-
-local voidpf falloc OF((
- voidpf, /* opaque pointer (not used) */
- uInt, /* number of items */
- uInt)); /* size of item */
-
-local void ffree OF((
- voidpf q, /* opaque pointer (not used) */
- voidpf p, /* what to free (not used) */
- uInt n)); /* number of bytes (not used) */
-
-/* Tables for deflate from PKZIP's appnote.txt. */
-local uInt cplens[] = { /* Copy lengths for literal codes 257..285 */
- 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
- 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
- /* actually lengths - 2; also see note #13 above about 258 */
-local uInt cplext[] = { /* Extra bits for literal codes 257..285 */
- 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
- 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 192, 192}; /* 192==invalid */
-local uInt cpdist[] = { /* Copy offsets for distance codes 0..29 */
- 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
- 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
- 8193, 12289, 16385, 24577};
-local uInt cpdext[] = { /* Extra bits for distance codes */
- 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
- 7, 7, 8, 8, 9, 9, 10, 10, 11, 11,
- 12, 12, 13, 13};
-
-/*
- Huffman code decoding is performed using a multi-level table lookup.
- The fastest way to decode is to simply build a lookup table whose
- size is determined by the longest code. However, the time it takes
- to build this table can also be a factor if the data being decoded
- is not very long. The most common codes are necessarily the
- shortest codes, so those codes dominate the decoding time, and hence
- the speed. The idea is you can have a shorter table that decodes the
- shorter, more probable codes, and then point to subsidiary tables for
- the longer codes. The time it costs to decode the longer codes is
- then traded against the time it takes to make longer tables.
-
- This results of this trade are in the variables lbits and dbits
- below. lbits is the number of bits the first level table for literal/
- length codes can decode in one step, and dbits is the same thing for
- the distance codes. Subsequent tables are also less than or equal to
- those sizes. These values may be adjusted either when all of the
- codes are shorter than that, in which case the longest code length in
- bits is used, or when the shortest code is *longer* than the requested
- table size, in which case the length of the shortest code in bits is
- used.
-
- There are two different values for the two tables, since they code a
- different number of possibilities each. The literal/length table
- codes 286 possible values, or in a flat code, a little over eight
- bits. The distance table codes 30 possible values, or a little less
- than five bits, flat. The optimum values for speed end up being
- about one bit more than those, so lbits is 8+1 and dbits is 5+1.
- The optimum values may differ though from machine to machine, and
- possibly even between compilers. Your mileage may vary.
- */
-
-
-/* If BMAX needs to be larger than 16, then h and x[] should be uLong. */
-#define BMAX 15 /* maximum bit length of any code */
-#define N_MAX 288 /* maximum number of codes in any set */
-
-#ifdef DEBUG_ZLIB
- uInt inflate_hufts;
-#endif
-
-local int huft_build(
- uIntf *b, /* code lengths in bits (all assumed <= BMAX) */
- uInt n, /* number of codes (assumed <= N_MAX) */
- uInt s, /* number of simple-valued codes (0..s-1) */
- uIntf *d, /* list of base values for non-simple codes */
- uIntf *e, /* list of extra bits for non-simple codes */
- inflate_huft * FAR *t, /* result: starting table */
- uIntf *m, /* maximum lookup bits, returns actual */
- z_stream *zs /* for zalloc function */
-)
-/* Given a list of code lengths and a maximum table size, make a set of
- tables to decode that set of codes. Return Z_OK on success, Z_BUF_ERROR
- if the given code set is incomplete (the tables are still built in this
- case), Z_DATA_ERROR if the input is invalid (all zero length codes or an
- over-subscribed set of lengths), or Z_MEM_ERROR if not enough memory. */
-{
-
- uInt a; /* counter for codes of length k */
- uInt c[BMAX+1]; /* bit length count table */
- uInt f; /* i repeats in table every f entries */
- int g; /* maximum code length */
- int h; /* table level */
- register uInt i; /* counter, current code */
- register uInt j; /* counter */
- register int k; /* number of bits in current code */
- int l; /* bits per table (returned in m) */
- register uIntf *p; /* pointer into c[], b[], or v[] */
- inflate_huft *q; /* points to current table */
- struct inflate_huft_s r; /* table entry for structure assignment */
- inflate_huft *u[BMAX]; /* table stack */
- uInt v[N_MAX]; /* values in order of bit length */
- register int w; /* bits before this table == (l * h) */
- uInt x[BMAX+1]; /* bit offsets, then code stack */
- uIntf *xp; /* pointer into x */
- int y; /* number of dummy codes added */
- uInt z; /* number of entries in current table */
-
-
- /* Generate counts for each bit length */
- p = c;
-#define C0 *p++ = 0;
-#define C2 C0 C0 C0 C0
-#define C4 C2 C2 C2 C2
- C4 /* clear c[]--assume BMAX+1 is 16 */
- p = b; i = n;
- do {
- c[*p++]++; /* assume all entries <= BMAX */
- } while (--i);
- if (c[0] == n) /* null input--all zero length codes */
- {
- *t = (inflate_huft *)Z_NULL;
- *m = 0;
- return Z_DATA_ERROR;
- }
-
-
- /* Find minimum and maximum length, bound *m by those */
- l = *m;
- for (j = 1; j <= BMAX; j++)
- if (c[j])
- break;
- k = j; /* minimum code length */
- if ((uInt)l < j)
- l = j;
- for (i = BMAX; i; i--)
- if (c[i])
- break;
- g = i; /* maximum code length */
- if ((uInt)l > i)
- l = i;
- *m = l;
-
-
- /* Adjust last length count to fill out codes, if needed */
- for (y = 1 << j; j < i; j++, y <<= 1)
- if ((y -= c[j]) < 0)
- return Z_DATA_ERROR;
- if ((y -= c[i]) < 0)
- return Z_DATA_ERROR;
- c[i] += y;
-
-
- /* Generate starting offsets into the value table for each length */
- x[1] = j = 0;
- p = c + 1; xp = x + 2;
- while (--i) { /* note that i == g from above */
- *xp++ = (j += *p++);
- }
-
-
- /* Make a table of values in order of bit lengths */
- p = b; i = 0;
- do {
- if ((j = *p++) != 0)
- v[x[j]++] = i;
- } while (++i < n);
- n = x[g]; /* set n to length of v */
-
-
- /* Generate the Huffman codes and for each, make the table entries */
- x[0] = i = 0; /* first Huffman code is zero */
- p = v; /* grab values in bit order */
- h = -1; /* no tables yet--level -1 */
- w = -l; /* bits decoded == (l * h) */
- u[0] = (inflate_huft *)Z_NULL; /* just to keep compilers happy */
- q = (inflate_huft *)Z_NULL; /* ditto */
- z = 0; /* ditto */
-
- /* go through the bit lengths (k already is bits in shortest code) */
- for (; k <= g; k++)
- {
- a = c[k];
- while (a--)
- {
- /* here i is the Huffman code of length k bits for value *p */
- /* make tables up to required level */
- while (k > w + l)
- {
- h++;
- w += l; /* previous table always l bits */
-
- /* compute minimum size table less than or equal to l bits */
- z = (z = g - w) > (uInt)l ? l : z; /* table size upper limit */
- if ((f = 1 << (j = k - w)) > a + 1) /* try a k-w bit table */
- { /* too few codes for k-w bit table */
- f -= a + 1; /* deduct codes from patterns left */
- xp = c + k;
- if (j < z)
- while (++j < z) /* try smaller tables up to z bits */
- {
- if ((f <<= 1) <= *++xp)
- break; /* enough codes to use up j bits */
- f -= *xp; /* else deduct codes from patterns */
- }
- }
- z = 1 << j; /* table entries for j-bit table */
-
- /* allocate and link in new table */
- if ((q = (inflate_huft *)ZALLOC
- (zs,z + 1,sizeof(inflate_huft))) == Z_NULL)
- {
- if (h)
- inflate_trees_free(u[0], zs);
- return Z_MEM_ERROR; /* not enough memory */
- }
- q->word.Nalloc = z + 1;
-#ifdef DEBUG_ZLIB
- inflate_hufts += z + 1;
-#endif
- *t = q + 1; /* link to list for huft_free() */
- *(t = &(q->next)) = Z_NULL;
- u[h] = ++q; /* table starts after link */
-
- /* connect to last table, if there is one */
- if (h)
- {
- x[h] = i; /* save pattern for backing up */
- r.bits = (Byte)l; /* bits to dump before this table */
- r.exop = (Byte)j; /* bits in this table */
- r.next = q; /* pointer to this table */
- j = i >> (w - l); /* (get around Turbo C bug) */
- u[h-1][j] = r; /* connect to last table */
- }
- }
-
- /* set up table entry in r */
- r.bits = (Byte)(k - w);
- if (p >= v + n)
- r.exop = 128 + 64; /* out of values--invalid code */
- else if (*p < s)
- {
- r.exop = (Byte)(*p < 256 ? 0 : 32 + 64); /* 256 is end-of-block */
- r.base = *p++; /* simple code is just the value */
- }
- else
- {
- r.exop = (Byte)e[*p - s] + 16 + 64; /* non-simple--look up in lists */
- r.base = d[*p++ - s];
- }
-
- /* fill code-like entries with r */
- f = 1 << (k - w);
- for (j = i >> w; j < z; j += f)
- q[j] = r;
-
- /* backwards increment the k-bit code i */
- for (j = 1 << (k - 1); i & j; j >>= 1)
- i ^= j;
- i ^= j;
-
- /* backup over finished tables */
- while ((i & ((1 << w) - 1)) != x[h])
- {
- h--; /* don't need to update q */
- w -= l;
- }
- }
- }
-
-
- /* Return Z_BUF_ERROR if we were given an incomplete table */
- return y != 0 && g != 1 ? Z_BUF_ERROR : Z_OK;
-}
-
-
-local int inflate_trees_bits(
- uIntf *c, /* 19 code lengths */
- uIntf *bb, /* bits tree desired/actual depth */
- inflate_huft * FAR *tb, /* bits tree result */
- z_stream *z /* for zfree function */
-)
-{
- int r;
-
- r = huft_build(c, 19, 19, (uIntf*)Z_NULL, (uIntf*)Z_NULL, tb, bb, z);
- if (r == Z_DATA_ERROR)
- z->msg = "oversubscribed dynamic bit lengths tree";
- else if (r == Z_BUF_ERROR)
- {
- inflate_trees_free(*tb, z);
- z->msg = "incomplete dynamic bit lengths tree";
- r = Z_DATA_ERROR;
- }
- return r;
-}
-
-
-local int inflate_trees_dynamic(
- uInt nl, /* number of literal/length codes */
- uInt nd, /* number of distance codes */
- uIntf *c, /* that many (total) code lengths */
- uIntf *bl, /* literal desired/actual bit depth */
- uIntf *bd, /* distance desired/actual bit depth */
- inflate_huft * FAR *tl, /* literal/length tree result */
- inflate_huft * FAR *td, /* distance tree result */
- z_stream *z /* for zfree function */
-)
-{
- int r;
-
- /* build literal/length tree */
- if ((r = huft_build(c, nl, 257, cplens, cplext, tl, bl, z)) != Z_OK)
- {
- if (r == Z_DATA_ERROR)
- z->msg = "oversubscribed literal/length tree";
- else if (r == Z_BUF_ERROR)
- {
- inflate_trees_free(*tl, z);
- z->msg = "incomplete literal/length tree";
- r = Z_DATA_ERROR;
- }
- return r;
- }
-
- /* build distance tree */
- if ((r = huft_build(c + nl, nd, 0, cpdist, cpdext, td, bd, z)) != Z_OK)
- {
- if (r == Z_DATA_ERROR)
- z->msg = "oversubscribed literal/length tree";
- else if (r == Z_BUF_ERROR) {
-#ifdef PKZIP_BUG_WORKAROUND
- r = Z_OK;
- }
-#else
- inflate_trees_free(*td, z);
- z->msg = "incomplete literal/length tree";
- r = Z_DATA_ERROR;
- }
- inflate_trees_free(*tl, z);
- return r;
-#endif
- }
-
- /* done */
- return Z_OK;
-}
-
-
-/* build fixed tables only once--keep them here */
-local int fixed_lock = 0;
-local int fixed_built = 0;
-#define FIXEDH 530 /* number of hufts used by fixed tables */
-local uInt fixed_left = FIXEDH;
-local inflate_huft fixed_mem[FIXEDH];
-local uInt fixed_bl;
-local uInt fixed_bd;
-local inflate_huft *fixed_tl;
-local inflate_huft *fixed_td;
-
-
-local voidpf falloc(
- voidpf q, /* opaque pointer (not used) */
- uInt n, /* number of items */
- uInt s /* size of item */
-)
-{
- Assert(s == sizeof(inflate_huft) && n <= fixed_left,
- "inflate_trees falloc overflow");
- if (q) s++; /* to make some compilers happy */
- fixed_left -= n;
- return (voidpf)(fixed_mem + fixed_left);
-}
-
-
-local void ffree(
- voidpf q,
- voidpf p,
- uInt n
-)
-{
- Assert(0, "inflate_trees ffree called!");
- if (q) q = p; /* to make some compilers happy */
-}
-
-
-local int inflate_trees_fixed(
- uIntf *bl, /* literal desired/actual bit depth */
- uIntf *bd, /* distance desired/actual bit depth */
- inflate_huft * FAR *tl, /* literal/length tree result */
- inflate_huft * FAR *td /* distance tree result */
-)
-{
- /* build fixed tables if not built already--lock out other instances */
- while (++fixed_lock > 1)
- fixed_lock--;
- if (!fixed_built)
- {
- int k; /* temporary variable */
- unsigned c[288]; /* length list for huft_build */
- z_stream z; /* for falloc function */
-
- /* set up fake z_stream for memory routines */
- z.zalloc = falloc;
- z.zfree = ffree;
- z.opaque = Z_NULL;
-
- /* literal table */
- for (k = 0; k < 144; k++)
- c[k] = 8;
- for (; k < 256; k++)
- c[k] = 9;
- for (; k < 280; k++)
- c[k] = 7;
- for (; k < 288; k++)
- c[k] = 8;
- fixed_bl = 7;
- huft_build(c, 288, 257, cplens, cplext, &fixed_tl, &fixed_bl, &z);
-
- /* distance table */
- for (k = 0; k < 30; k++)
- c[k] = 5;
- fixed_bd = 5;
- huft_build(c, 30, 0, cpdist, cpdext, &fixed_td, &fixed_bd, &z);
-
- /* done */
- fixed_built = 1;
- }
- fixed_lock--;
- *bl = fixed_bl;
- *bd = fixed_bd;
- *tl = fixed_tl;
- *td = fixed_td;
- return Z_OK;
-}
-
-
-local int inflate_trees_free(
- inflate_huft *t, /* table to free */
- z_stream *z /* for zfree function */
-)
-/* Free the malloc'ed tables built by huft_build(), which makes a linked
- list of the tables it made, with the links in a dummy first entry of
- each table. */
-{
- register inflate_huft *p, *q;
-
- /* Go through linked list, freeing from the malloced (t[-1]) address. */
- p = t;
- while (p != Z_NULL)
- {
- q = (--p)->next;
- ZFREE(z, p, p->word.Nalloc * sizeof(inflate_huft));
- p = q;
- }
- return Z_OK;
-}
-
-/*+++++*/
-/* infcodes.c -- process literals and length/distance pairs
- * Copyright (C) 1995 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* simplify the use of the inflate_huft type with some defines */
-#define base more.Base
-#define next more.Next
-#define exop word.what.Exop
-#define bits word.what.Bits
-
-/* inflate codes private state */
-struct inflate_codes_state {
-
- /* mode */
- enum { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */
- START, /* x: set up for LEN */
- LEN, /* i: get length/literal/eob next */
- LENEXT, /* i: getting length extra (have base) */
- DIST, /* i: get distance next */
- DISTEXT, /* i: getting distance extra */
- COPY, /* o: copying bytes in window, waiting for space */
- LIT, /* o: got literal, waiting for output space */
- WASH, /* o: got eob, possibly still output waiting */
- END, /* x: got eob and all data flushed */
- BADCODE} /* x: got error */
- mode; /* current inflate_codes mode */
-
- /* mode dependent information */
- uInt len;
- union {
- struct {
- inflate_huft *tree; /* pointer into tree */
- uInt need; /* bits needed */
- } code; /* if LEN or DIST, where in tree */
- uInt lit; /* if LIT, literal */
- struct {
- uInt get; /* bits to get for extra */
- uInt dist; /* distance back to copy from */
- } copy; /* if EXT or COPY, where and how much */
- } sub; /* submode */
-
- /* mode independent information */
- Byte lbits; /* ltree bits decoded per branch */
- Byte dbits; /* dtree bits decoder per branch */
- inflate_huft *ltree; /* literal/length/eob tree */
- inflate_huft *dtree; /* distance tree */
-
-};
-
-
-local inflate_codes_statef *inflate_codes_new(
- uInt bl,
- uInt bd,
- inflate_huft *tl,
- inflate_huft *td,
- z_stream *z
-)
-{
- inflate_codes_statef *c;
-
- if ((c = (inflate_codes_statef *)
- ZALLOC(z,1,sizeof(struct inflate_codes_state))) != Z_NULL)
- {
- c->mode = START;
- c->lbits = (Byte)bl;
- c->dbits = (Byte)bd;
- c->ltree = tl;
- c->dtree = td;
- Tracev((stderr, "inflate: codes new\n"));
- }
- return c;
-}
-
-
-local int inflate_codes(
- inflate_blocks_statef *s,
- z_stream *z,
- int r
-)
-{
- uInt j; /* temporary storage */
- inflate_huft *t; /* temporary pointer */
- uInt e; /* extra bits or operation */
- uLong b; /* bit buffer */
- uInt k; /* bits in bit buffer */
- Bytef *p; /* input data pointer */
- uInt n; /* bytes available there */
- Bytef *q; /* output window write pointer */
- uInt m; /* bytes to end of window or read pointer */
- Bytef *f; /* pointer to copy strings from */
- inflate_codes_statef *c = s->sub.decode.codes; /* codes state */
-
- /* copy input/output information to locals (UPDATE macro restores) */
- LOAD
-
- /* process input and output based on current state */
- while (1) switch (c->mode)
- { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */
- case START: /* x: set up for LEN */
-#ifndef SLOW
- if (m >= 258 && n >= 10)
- {
- UPDATE
- r = inflate_fast(c->lbits, c->dbits, c->ltree, c->dtree, s, z);
- LOAD
- if (r != Z_OK)
- {
- c->mode = r == Z_STREAM_END ? WASH : BADCODE;
- break;
- }
- }
-#endif /* !SLOW */
- c->sub.code.need = c->lbits;
- c->sub.code.tree = c->ltree;
- c->mode = LEN;
- case LEN: /* i: get length/literal/eob next */
- j = c->sub.code.need;
- NEEDBITS(j)
- t = c->sub.code.tree + ((uInt)b & inflate_mask[j]);
- DUMPBITS(t->bits)
- e = (uInt)(t->exop);
- if (e == 0) /* literal */
- {
- c->sub.lit = t->base;
- Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
- "inflate: literal '%c'\n" :
- "inflate: literal 0x%02x\n", t->base));
- c->mode = LIT;
- break;
- }
- if (e & 16) /* length */
- {
- c->sub.copy.get = e & 15;
- c->len = t->base;
- c->mode = LENEXT;
- break;
- }
- if ((e & 64) == 0) /* next table */
- {
- c->sub.code.need = e;
- c->sub.code.tree = t->next;
- break;
- }
- if (e & 32) /* end of block */
- {
- Tracevv((stderr, "inflate: end of block\n"));
- c->mode = WASH;
- break;
- }
- c->mode = BADCODE; /* invalid code */
- z->msg = "invalid literal/length code";
- r = Z_DATA_ERROR;
- LEAVE
- case LENEXT: /* i: getting length extra (have base) */
- j = c->sub.copy.get;
- NEEDBITS(j)
- c->len += (uInt)b & inflate_mask[j];
- DUMPBITS(j)
- c->sub.code.need = c->dbits;
- c->sub.code.tree = c->dtree;
- Tracevv((stderr, "inflate: length %u\n", c->len));
- c->mode = DIST;
- case DIST: /* i: get distance next */
- j = c->sub.code.need;
- NEEDBITS(j)
- t = c->sub.code.tree + ((uInt)b & inflate_mask[j]);
- DUMPBITS(t->bits)
- e = (uInt)(t->exop);
- if (e & 16) /* distance */
- {
- c->sub.copy.get = e & 15;
- c->sub.copy.dist = t->base;
- c->mode = DISTEXT;
- break;
- }
- if ((e & 64) == 0) /* next table */
- {
- c->sub.code.need = e;
- c->sub.code.tree = t->next;
- break;
- }
- c->mode = BADCODE; /* invalid code */
- z->msg = "invalid distance code";
- r = Z_DATA_ERROR;
- LEAVE
- case DISTEXT: /* i: getting distance extra */
- j = c->sub.copy.get;
- NEEDBITS(j)
- c->sub.copy.dist += (uInt)b & inflate_mask[j];
- DUMPBITS(j)
- Tracevv((stderr, "inflate: distance %u\n", c->sub.copy.dist));
- c->mode = COPY;
- case COPY: /* o: copying bytes in window, waiting for space */
-#ifndef __TURBOC__ /* Turbo C bug for following expression */
- f = (uInt)(q - s->window) < c->sub.copy.dist ?
- s->end - (c->sub.copy.dist - (q - s->window)) :
- q - c->sub.copy.dist;
-#else
- f = q - c->sub.copy.dist;
- if ((uInt)(q - s->window) < c->sub.copy.dist)
- f = s->end - (c->sub.copy.dist - (q - s->window));
-#endif
- while (c->len)
- {
- NEEDOUT
- OUTBYTE(*f++)
- if (f == s->end)
- f = s->window;
- c->len--;
- }
- c->mode = START;
- break;
- case LIT: /* o: got literal, waiting for output space */
- NEEDOUT
- OUTBYTE(c->sub.lit)
- c->mode = START;
- break;
- case WASH: /* o: got eob, possibly more output */
- FLUSH
- if (s->read != s->write)
- LEAVE
- c->mode = END;
- case END:
- r = Z_STREAM_END;
- LEAVE
- case BADCODE: /* x: got error */
- r = Z_DATA_ERROR;
- LEAVE
- default:
- r = Z_STREAM_ERROR;
- LEAVE
- }
-}
-
-
-local void inflate_codes_free(
- inflate_codes_statef *c,
- z_stream *z
-)
-{
- ZFREE(z, c, sizeof(struct inflate_codes_state));
- Tracev((stderr, "inflate: codes free\n"));
-}
-
-/*+++++*/
-/* inflate_util.c -- data and routines common to blocks and codes
- * Copyright (C) 1995 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* copy as much as possible from the sliding window to the output area */
-local int inflate_flush(
- inflate_blocks_statef *s,
- z_stream *z,
- int r
-)
-{
- uInt n;
- Bytef *p, *q;
-
- /* local copies of source and destination pointers */
- p = z->next_out;
- q = s->read;
-
- /* compute number of bytes to copy as far as end of window */
- n = (uInt)((q <= s->write ? s->write : s->end) - q);
- if (n > z->avail_out) n = z->avail_out;
- if (n && r == Z_BUF_ERROR) r = Z_OK;
-
- /* update counters */
- z->avail_out -= n;
- z->total_out += n;
-
- /* update check information */
- if (s->checkfn != Z_NULL)
- s->check = (*s->checkfn)(s->check, q, n);
-
- /* copy as far as end of window */
- zmemcpy(p, q, n);
- p += n;
- q += n;
-
- /* see if more to copy at beginning of window */
- if (q == s->end)
- {
- /* wrap pointers */
- q = s->window;
- if (s->write == s->end)
- s->write = s->window;
-
- /* compute bytes to copy */
- n = (uInt)(s->write - q);
- if (n > z->avail_out) n = z->avail_out;
- if (n && r == Z_BUF_ERROR) r = Z_OK;
-
- /* update counters */
- z->avail_out -= n;
- z->total_out += n;
-
- /* update check information */
- if (s->checkfn != Z_NULL)
- s->check = (*s->checkfn)(s->check, q, n);
-
- /* copy */
- zmemcpy(p, q, n);
- p += n;
- q += n;
- }
-
- /* update pointers */
- z->next_out = p;
- s->read = q;
-
- /* done */
- return r;
-}
-
-
-/*+++++*/
-/* inffast.c -- process literals and length/distance pairs fast
- * Copyright (C) 1995 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* simplify the use of the inflate_huft type with some defines */
-#define base more.Base
-#define next more.Next
-#define exop word.what.Exop
-#define bits word.what.Bits
-
-/* macros for bit input with no checking and for returning unused bytes */
-#define GRABBITS(j) {while(k<(j)){b|=((uLong)NEXTBYTE)<<k;k+=8;}}
-#define UNGRAB {n+=(c=k>>3);p-=c;k&=7;}
-
-/* Called with number of bytes left to write in window at least 258
- (the maximum string length) and number of input bytes available
- at least ten. The ten bytes are six bytes for the longest length/
- distance pair plus four bytes for overloading the bit buffer. */
-
-local int inflate_fast(
- uInt bl,
- uInt bd,
- inflate_huft *tl,
- inflate_huft *td,
- inflate_blocks_statef *s,
- z_stream *z
-)
-{
- inflate_huft *t; /* temporary pointer */
- uInt e; /* extra bits or operation */
- uLong b; /* bit buffer */
- uInt k; /* bits in bit buffer */
- Bytef *p; /* input data pointer */
- uInt n; /* bytes available there */
- Bytef *q; /* output window write pointer */
- uInt m; /* bytes to end of window or read pointer */
- uInt ml; /* mask for literal/length tree */
- uInt md; /* mask for distance tree */
- uInt c; /* bytes to copy */
- uInt d; /* distance back to copy from */
- Bytef *r; /* copy source pointer */
-
- /* load input, output, bit values */
- LOAD
-
- /* initialize masks */
- ml = inflate_mask[bl];
- md = inflate_mask[bd];
-
- /* do until not enough input or output space for fast loop */
- do { /* assume called with m >= 258 && n >= 10 */
- /* get literal/length code */
- GRABBITS(20) /* max bits for literal/length code */
- if ((e = (t = tl + ((uInt)b & ml))->exop) == 0)
- {
- DUMPBITS(t->bits)
- Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
- "inflate: * literal '%c'\n" :
- "inflate: * literal 0x%02x\n", t->base));
- *q++ = (Byte)t->base;
- m--;
- continue;
- }
- do {
- DUMPBITS(t->bits)
- if (e & 16)
- {
- /* get extra bits for length */
- e &= 15;
- c = t->base + ((uInt)b & inflate_mask[e]);
- DUMPBITS(e)
- Tracevv((stderr, "inflate: * length %u\n", c));
-
- /* decode distance base of block to copy */
- GRABBITS(15); /* max bits for distance code */
- e = (t = td + ((uInt)b & md))->exop;
- do {
- DUMPBITS(t->bits)
- if (e & 16)
- {
- /* get extra bits to add to distance base */
- e &= 15;
- GRABBITS(e) /* get extra bits (up to 13) */
- d = t->base + ((uInt)b & inflate_mask[e]);
- DUMPBITS(e)
- Tracevv((stderr, "inflate: * distance %u\n", d));
-
- /* do the copy */
- m -= c;
- if ((uInt)(q - s->window) >= d) /* offset before dest */
- { /* just copy */
- r = q - d;
- *q++ = *r++; c--; /* minimum count is three, */
- *q++ = *r++; c--; /* so unroll loop a little */
- }
- else /* else offset after destination */
- {
- e = d - (q - s->window); /* bytes from offset to end */
- r = s->end - e; /* pointer to offset */
- if (c > e) /* if source crosses, */
- {
- c -= e; /* copy to end of window */
- do {
- *q++ = *r++;
- } while (--e);
- r = s->window; /* copy rest from start of window */
- }
- }
- do { /* copy all or what's left */
- *q++ = *r++;
- } while (--c);
- break;
- }
- else if ((e & 64) == 0)
- e = (t = t->next + ((uInt)b & inflate_mask[e]))->exop;
- else
- {
- z->msg = "invalid distance code";
- UNGRAB
- UPDATE
- return Z_DATA_ERROR;
- }
- } while (1);
- break;
- }
- if ((e & 64) == 0)
- {
- if ((e = (t = t->next + ((uInt)b & inflate_mask[e]))->exop) == 0)
- {
- DUMPBITS(t->bits)
- Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
- "inflate: * literal '%c'\n" :
- "inflate: * literal 0x%02x\n", t->base));
- *q++ = (Byte)t->base;
- m--;
- break;
- }
- }
- else if (e & 32)
- {
- Tracevv((stderr, "inflate: * end of block\n"));
- UNGRAB
- UPDATE
- return Z_STREAM_END;
- }
- else
- {
- z->msg = "invalid literal/length code";
- UNGRAB
- UPDATE
- return Z_DATA_ERROR;
- }
- } while (1);
- } while (m >= 258 && n >= 10);
-
- /* not enough input or output--restore pointers and return */
- UNGRAB
- UPDATE
- return Z_OK;
-}
-
-
-/*+++++*/
-/* zutil.c -- target dependent utility functions for the compression library
- * Copyright (C) 1995 Jean-loup Gailly.
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* From: zutil.c,v 1.8 1995/05/03 17:27:12 jloup Exp */
-
-char *zlib_version = ZLIB_VERSION;
-
-char *z_errmsg[] = {
-"stream end", /* Z_STREAM_END 1 */
-"", /* Z_OK 0 */
-"file error", /* Z_ERRNO (-1) */
-"stream error", /* Z_STREAM_ERROR (-2) */
-"data error", /* Z_DATA_ERROR (-3) */
-"insufficient memory", /* Z_MEM_ERROR (-4) */
-"buffer error", /* Z_BUF_ERROR (-5) */
-""};
-
-
-/*+++++*/
-/* adler32.c -- compute the Adler-32 checksum of a data stream
- * Copyright (C) 1995 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* From: adler32.c,v 1.6 1995/05/03 17:27:08 jloup Exp */
-
-#define BASE 65521L /* largest prime smaller than 65536 */
-#define NMAX 5552
-/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
-
-#define DO1(buf) {s1 += *buf++; s2 += s1;}
-#define DO2(buf) DO1(buf); DO1(buf);
-#define DO4(buf) DO2(buf); DO2(buf);
-#define DO8(buf) DO4(buf); DO4(buf);
-#define DO16(buf) DO8(buf); DO8(buf);
-
-/* ========================================================================= */
-uLong adler32(
- uLong adler,
- Bytef *buf,
- uInt len
-)
-{
- unsigned long s1 = adler & 0xffff;
- unsigned long s2 = (adler >> 16) & 0xffff;
- int k;
-
- if (buf == Z_NULL) return 1L;
-
- while (len > 0) {
- k = len < NMAX ? len : NMAX;
- len -= k;
- while (k >= 16) {
- DO16(buf);
- k -= 16;
- }
- if (k != 0) do {
- DO1(buf);
- } while (--k);
- s1 %= BASE;
- s2 %= BASE;
- }
- return (s2 << 16) | s1;
-}
diff --git a/arch/ppc64/boot/zlib.h b/arch/ppc64/boot/zlib.h
deleted file mode 100644
index f0b996c6864f..000000000000
--- a/arch/ppc64/boot/zlib.h
+++ /dev/null
@@ -1,432 +0,0 @@
-/* */
-
-/*
- * This file is derived from zlib.h and zconf.h from the zlib-0.95
- * distribution by Jean-loup Gailly and Mark Adler, with some additions
- * by Paul Mackerras to aid in implementing Deflate compression and
- * decompression for PPP packets.
- */
-
-/*
- * ==FILEVERSION 960122==
- *
- * This marker is used by the Linux installation script to determine
- * whether an up-to-date version of this file is already installed.
- */
-
-/* zlib.h -- interface of the 'zlib' general purpose compression library
- version 0.95, Aug 16th, 1995.
-
- Copyright (C) 1995 Jean-loup Gailly and Mark Adler
-
- This software is provided 'as-is', without any express or implied
- warranty. In no event will the authors be held liable for any damages
- arising from the use of this software.
-
- Permission is granted to anyone to use this software for any purpose,
- including commercial applications, and to alter it and redistribute it
- freely, subject to the following restrictions:
-
- 1. The origin of this software must not be misrepresented; you must not
- claim that you wrote the original software. If you use this software
- in a product, an acknowledgment in the product documentation would be
- appreciated but is not required.
- 2. Altered source versions must be plainly marked as such, and must not be
- misrepresented as being the original software.
- 3. This notice may not be removed or altered from any source distribution.
-
- Jean-loup Gailly Mark Adler
- gzip@prep.ai.mit.edu madler@alumni.caltech.edu
- */
-
-#ifndef _ZLIB_H
-#define _ZLIB_H
-
-/* #include "zconf.h" */ /* included directly here */
-
-/* zconf.h -- configuration of the zlib compression library
- * Copyright (C) 1995 Jean-loup Gailly.
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* From: zconf.h,v 1.12 1995/05/03 17:27:12 jloup Exp */
-
-/*
- The library does not install any signal handler. It is recommended to
- add at least a handler for SIGSEGV when decompressing; the library checks
- the consistency of the input data whenever possible but may go nuts
- for some forms of corrupted input.
- */
-
-/*
- * Compile with -DMAXSEG_64K if the alloc function cannot allocate more
- * than 64k bytes at a time (needed on systems with 16-bit int).
- * Compile with -DUNALIGNED_OK if it is OK to access shorts or ints
- * at addresses which are not a multiple of their size.
- * Under DOS, -DFAR=far or -DFAR=__far may be needed.
- */
-
-#ifndef STDC
-# if defined(MSDOS) || defined(__STDC__) || defined(__cplusplus)
-# define STDC
-# endif
-#endif
-
-#ifdef __MWERKS__ /* Metrowerks CodeWarrior declares fileno() in unix.h */
-# include <unix.h>
-#endif
-
-/* Maximum value for memLevel in deflateInit2 */
-#ifndef MAX_MEM_LEVEL
-# ifdef MAXSEG_64K
-# define MAX_MEM_LEVEL 8
-# else
-# define MAX_MEM_LEVEL 9
-# endif
-#endif
-
-#ifndef FAR
-# define FAR
-#endif
-
-/* Maximum value for windowBits in deflateInit2 and inflateInit2 */
-#ifndef MAX_WBITS
-# define MAX_WBITS 15 /* 32K LZ77 window */
-#endif
-
-/* The memory requirements for deflate are (in bytes):
- 1 << (windowBits+2) + 1 << (memLevel+9)
- that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values)
- plus a few kilobytes for small objects. For example, if you want to reduce
- the default memory requirements from 256K to 128K, compile with
- make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
- Of course this will generally degrade compression (there's no free lunch).
-
- The memory requirements for inflate are (in bytes) 1 << windowBits
- that is, 32K for windowBits=15 (default value) plus a few kilobytes
- for small objects.
-*/
-
- /* Type declarations */
-
-#ifndef OF /* function prototypes */
-# ifdef STDC
-# define OF(args) args
-# else
-# define OF(args) ()
-# endif
-#endif
-
-typedef unsigned char Byte; /* 8 bits */
-typedef unsigned int uInt; /* 16 bits or more */
-typedef unsigned long uLong; /* 32 bits or more */
-
-typedef Byte FAR Bytef;
-typedef char FAR charf;
-typedef int FAR intf;
-typedef uInt FAR uIntf;
-typedef uLong FAR uLongf;
-
-#ifdef STDC
- typedef void FAR *voidpf;
- typedef void *voidp;
-#else
- typedef Byte FAR *voidpf;
- typedef Byte *voidp;
-#endif
-
-/* end of original zconf.h */
-
-#define ZLIB_VERSION "0.95P"
-
-/*
- The 'zlib' compression library provides in-memory compression and
- decompression functions, including integrity checks of the uncompressed
- data. This version of the library supports only one compression method
- (deflation) but other algorithms may be added later and will have the same
- stream interface.
-
- For compression the application must provide the output buffer and
- may optionally provide the input buffer for optimization. For decompression,
- the application must provide the input buffer and may optionally provide
- the output buffer for optimization.
-
- Compression can be done in a single step if the buffers are large
- enough (for example if an input file is mmap'ed), or can be done by
- repeated calls of the compression function. In the latter case, the
- application must provide more input and/or consume the output
- (providing more output space) before each call.
-*/
-
-typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size));
-typedef void (*free_func) OF((voidpf opaque, voidpf address, uInt nbytes));
-
-struct internal_state;
-
-typedef struct z_stream_s {
- Bytef *next_in; /* next input byte */
- uInt avail_in; /* number of bytes available at next_in */
- uLong total_in; /* total nb of input bytes read so far */
-
- Bytef *next_out; /* next output byte should be put there */
- uInt avail_out; /* remaining free space at next_out */
- uLong total_out; /* total nb of bytes output so far */
-
- char *msg; /* last error message, NULL if no error */
- struct internal_state FAR *state; /* not visible by applications */
-
- alloc_func zalloc; /* used to allocate the internal state */
- free_func zfree; /* used to free the internal state */
- voidp opaque; /* private data object passed to zalloc and zfree */
-
- Byte data_type; /* best guess about the data type: ascii or binary */
-
-} z_stream;
-
-/*
- The application must update next_in and avail_in when avail_in has
- dropped to zero. It must update next_out and avail_out when avail_out
- has dropped to zero. The application must initialize zalloc, zfree and
- opaque before calling the init function. All other fields are set by the
- compression library and must not be updated by the application.
-
- The opaque value provided by the application will be passed as the first
- parameter for calls of zalloc and zfree. This can be useful for custom
- memory management. The compression library attaches no meaning to the
- opaque value.
-
- zalloc must return Z_NULL if there is not enough memory for the object.
- On 16-bit systems, the functions zalloc and zfree must be able to allocate
- exactly 65536 bytes, but will not be required to allocate more than this
- if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS,
- pointers returned by zalloc for objects of exactly 65536 bytes *must*
- have their offset normalized to zero. The default allocation function
- provided by this library ensures this (see zutil.c). To reduce memory
- requirements and avoid any allocation of 64K objects, at the expense of
- compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h).
-
- The fields total_in and total_out can be used for statistics or
- progress reports. After compression, total_in holds the total size of
- the uncompressed data and may be saved for use in the decompressor
- (particularly if the decompressor wants to decompress everything in
- a single step).
-*/
-
- /* constants */
-
-#define Z_NO_FLUSH 0
-#define Z_PARTIAL_FLUSH 1
-#define Z_FULL_FLUSH 2
-#define Z_SYNC_FLUSH 3 /* experimental: partial_flush + byte align */
-#define Z_FINISH 4
-#define Z_PACKET_FLUSH 5
-/* See deflate() below for the usage of these constants */
-
-#define Z_OK 0
-#define Z_STREAM_END 1
-#define Z_ERRNO (-1)
-#define Z_STREAM_ERROR (-2)
-#define Z_DATA_ERROR (-3)
-#define Z_MEM_ERROR (-4)
-#define Z_BUF_ERROR (-5)
-/* error codes for the compression/decompression functions */
-
-#define Z_BEST_SPEED 1
-#define Z_BEST_COMPRESSION 9
-#define Z_DEFAULT_COMPRESSION (-1)
-/* compression levels */
-
-#define Z_FILTERED 1
-#define Z_HUFFMAN_ONLY 2
-#define Z_DEFAULT_STRATEGY 0
-
-#define Z_BINARY 0
-#define Z_ASCII 1
-#define Z_UNKNOWN 2
-/* Used to set the data_type field */
-
-#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */
-
-extern char *zlib_version;
-/* The application can compare zlib_version and ZLIB_VERSION for consistency.
- If the first character differs, the library code actually used is
- not compatible with the zlib.h header file used by the application.
- */
-
- /* basic functions */
-
-extern int inflateInit OF((z_stream *strm));
-/*
- Initializes the internal stream state for decompression. The fields
- zalloc and zfree must be initialized before by the caller. If zalloc and
- zfree are set to Z_NULL, inflateInit updates them to use default allocation
- functions.
-
- inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not
- enough memory. msg is set to null if there is no error message.
- inflateInit does not perform any decompression: this will be done by
- inflate().
-*/
-
-
-extern int inflate OF((z_stream *strm, int flush));
-/*
- Performs one or both of the following actions:
-
- - Decompress more input starting at next_in and update next_in and avail_in
- accordingly. If not all input can be processed (because there is not
- enough room in the output buffer), next_in is updated and processing
- will resume at this point for the next call of inflate().
-
- - Provide more output starting at next_out and update next_out and avail_out
- accordingly. inflate() always provides as much output as possible
- (until there is no more input data or no more space in the output buffer).
-
- Before the call of inflate(), the application should ensure that at least
- one of the actions is possible, by providing more input and/or consuming
- more output, and updating the next_* and avail_* values accordingly.
- The application can consume the uncompressed output when it wants, for
- example when the output buffer is full (avail_out == 0), or after each
- call of inflate().
-
- If the parameter flush is set to Z_PARTIAL_FLUSH or Z_PACKET_FLUSH,
- inflate flushes as much output as possible to the output buffer. The
- flushing behavior of inflate is not specified for values of the flush
- parameter other than Z_PARTIAL_FLUSH, Z_PACKET_FLUSH or Z_FINISH, but the
- current implementation actually flushes as much output as possible
- anyway. For Z_PACKET_FLUSH, inflate checks that once all the input data
- has been consumed, it is expecting to see the length field of a stored
- block; if not, it returns Z_DATA_ERROR.
-
- inflate() should normally be called until it returns Z_STREAM_END or an
- error. However if all decompression is to be performed in a single step
- (a single call of inflate), the parameter flush should be set to
- Z_FINISH. In this case all pending input is processed and all pending
- output is flushed; avail_out must be large enough to hold all the
- uncompressed data. (The size of the uncompressed data may have been saved
- by the compressor for this purpose.) The next operation on this stream must
- be inflateEnd to deallocate the decompression state. The use of Z_FINISH
- is never required, but can be used to inform inflate that a faster routine
- may be used for the single inflate() call.
-
- inflate() returns Z_OK if some progress has been made (more input
- processed or more output produced), Z_STREAM_END if the end of the
- compressed data has been reached and all uncompressed output has been
- produced, Z_DATA_ERROR if the input data was corrupted, Z_STREAM_ERROR if
- the stream structure was inconsistent (for example if next_in or next_out
- was NULL), Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR if no
- progress is possible or if there was not enough room in the output buffer
- when Z_FINISH is used. In the Z_DATA_ERROR case, the application may then
- call inflateSync to look for a good compression block. */
-
-
-extern int inflateEnd OF((z_stream *strm));
-/*
- All dynamically allocated data structures for this stream are freed.
- This function discards any unprocessed input and does not flush any
- pending output.
-
- inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state
- was inconsistent. In the error case, msg may be set but then points to a
- static string (which must not be deallocated).
-*/
-
- /* advanced functions */
-
-extern int inflateInit2 OF((z_stream *strm,
- int windowBits));
-/*
- This is another version of inflateInit with more compression options. The
- fields next_out, zalloc and zfree must be initialized before by the caller.
-
- The windowBits parameter is the base two logarithm of the maximum window
- size (the size of the history buffer). It should be in the range 8..15 for
- this version of the library (the value 16 will be allowed soon). The
- default value is 15 if inflateInit is used instead. If a compressed stream
- with a larger window size is given as input, inflate() will return with
- the error code Z_DATA_ERROR instead of trying to allocate a larger window.
-
- If next_out is not null, the library will use this buffer for the history
- buffer; the buffer must either be large enough to hold the entire output
- data, or have at least 1<<windowBits bytes. If next_out is null, the
- library will allocate its own buffer (and leave next_out null). next_in
- need not be provided here but must be provided by the application for the
- next call of inflate().
-
- If the history buffer is provided by the application, next_out must
- never be changed by the application since the decompressor maintains
- history information inside this buffer from call to call; the application
- can only reset next_out to the beginning of the history buffer when
- avail_out is zero and all output has been consumed.
-
- inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was
- not enough memory, Z_STREAM_ERROR if a parameter is invalid (such as
- windowBits < 8). msg is set to null if there is no error message.
- inflateInit2 does not perform any decompression: this will be done by
- inflate().
-*/
-
-extern int inflateSync OF((z_stream *strm));
-/*
- Skips invalid compressed data until the special marker (see deflate()
- above) can be found, or until all available input is skipped. No output
- is provided.
-
- inflateSync returns Z_OK if the special marker has been found, Z_BUF_ERROR
- if no more input was provided, Z_DATA_ERROR if no marker has been found,
- or Z_STREAM_ERROR if the stream structure was inconsistent. In the success
- case, the application may save the current current value of total_in which
- indicates where valid compressed data was found. In the error case, the
- application may repeatedly call inflateSync, providing more input each time,
- until success or end of the input data.
-*/
-
-extern int inflateReset OF((z_stream *strm));
-/*
- This function is equivalent to inflateEnd followed by inflateInit,
- but does not free and reallocate all the internal decompression state.
- The stream will keep attributes that may have been set by inflateInit2.
-
- inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
- stream state was inconsistent (such as zalloc or state being NULL).
-*/
-
-extern int inflateIncomp OF((z_stream *strm));
-/*
- This function adds the data at next_in (avail_in bytes) to the output
- history without performing any output. There must be no pending output,
- and the decompressor must be expecting to see the start of a block.
- Calling this function is equivalent to decompressing a stored block
- containing the data at next_in (except that the data is not output).
-*/
-
- /* checksum functions */
-
-/*
- This function is not related to compression but is exported
- anyway because it might be useful in applications using the
- compression library.
-*/
-
-extern uLong adler32 OF((uLong adler, Bytef *buf, uInt len));
-
-/*
- Update a running Adler-32 checksum with the bytes buf[0..len-1] and
- return the updated checksum. If buf is NULL, this function returns
- the required initial value for the checksum.
- An Adler-32 checksum is almost as reliable as a CRC32 but can be computed
- much faster. Usage example:
-
- uLong adler = adler32(0L, Z_NULL, 0);
-
- while (read_buffer(buffer, length) != EOF) {
- adler = adler32(adler, buffer, length);
- }
- if (adler != original_adler) error();
-*/
-
-#ifndef _Z_UTIL_H
- struct internal_state {int dummy;}; /* hack for buggy compilers */
-#endif
-
-#endif /* _ZLIB_H */
diff --git a/arch/ppc64/defconfig b/arch/ppc64/defconfig
index 37c157c93cef..e79fd60bc122 100644
--- a/arch/ppc64/defconfig
+++ b/arch/ppc64/defconfig
@@ -1318,7 +1318,7 @@ CONFIG_MSDOS_PARTITION=y
#
CONFIG_NLS=y
CONFIG_NLS_DEFAULT="iso8859-1"
-CONFIG_NLS_CODEPAGE_437=m
+CONFIG_NLS_CODEPAGE_437=y
CONFIG_NLS_CODEPAGE_737=m
CONFIG_NLS_CODEPAGE_775=m
CONFIG_NLS_CODEPAGE_850=m
@@ -1342,7 +1342,7 @@ CONFIG_NLS_ISO8859_8=m
CONFIG_NLS_CODEPAGE_1250=m
CONFIG_NLS_CODEPAGE_1251=m
CONFIG_NLS_ASCII=m
-CONFIG_NLS_ISO8859_1=m
+CONFIG_NLS_ISO8859_1=y
CONFIG_NLS_ISO8859_2=m
CONFIG_NLS_ISO8859_3=m
CONFIG_NLS_ISO8859_4=m
diff --git a/arch/ppc64/kernel/HvLpEvent.c b/arch/ppc64/kernel/HvLpEvent.c
deleted file mode 100644
index 90032b138902..000000000000
--- a/arch/ppc64/kernel/HvLpEvent.c
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright 2001 Mike Corrigan IBM Corp
- *
- * 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/stddef.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <asm/system.h>
-#include <asm/iSeries/HvLpEvent.h>
-#include <asm/iSeries/HvCallEvent.h>
-#include <asm/iSeries/ItLpNaca.h>
-
-/* Array of LpEvent handler functions */
-LpEventHandler lpEventHandler[HvLpEvent_Type_NumTypes];
-unsigned lpEventHandlerPaths[HvLpEvent_Type_NumTypes];
-
-/* Register a handler for an LpEvent type */
-
-int HvLpEvent_registerHandler( HvLpEvent_Type eventType, LpEventHandler handler )
-{
- int rc = 1;
- if ( eventType < HvLpEvent_Type_NumTypes ) {
- lpEventHandler[eventType] = handler;
- rc = 0;
- }
- return rc;
-
-}
-
-int HvLpEvent_unregisterHandler( HvLpEvent_Type eventType )
-{
- int rc = 1;
-
- might_sleep();
-
- if ( eventType < HvLpEvent_Type_NumTypes ) {
- if ( !lpEventHandlerPaths[eventType] ) {
- lpEventHandler[eventType] = NULL;
- rc = 0;
-
- /* We now sleep until all other CPUs have scheduled. This ensures that
- * the deletion is seen by all other CPUs, and that the deleted handler
- * isn't still running on another CPU when we return. */
- synchronize_rcu();
- }
- }
- return rc;
-}
-EXPORT_SYMBOL(HvLpEvent_registerHandler);
-EXPORT_SYMBOL(HvLpEvent_unregisterHandler);
-
-/* (lpIndex is the partition index of the target partition.
- * needed only for VirtualIo, VirtualLan and SessionMgr. Zero
- * indicates to use our partition index - for the other types)
- */
-int HvLpEvent_openPath( HvLpEvent_Type eventType, HvLpIndex lpIndex )
-{
- int rc = 1;
- if ( eventType < HvLpEvent_Type_NumTypes &&
- lpEventHandler[eventType] ) {
- if ( lpIndex == 0 )
- lpIndex = itLpNaca.xLpIndex;
- HvCallEvent_openLpEventPath( lpIndex, eventType );
- ++lpEventHandlerPaths[eventType];
- rc = 0;
- }
- return rc;
-}
-
-int HvLpEvent_closePath( HvLpEvent_Type eventType, HvLpIndex lpIndex )
-{
- int rc = 1;
- if ( eventType < HvLpEvent_Type_NumTypes &&
- lpEventHandler[eventType] &&
- lpEventHandlerPaths[eventType] ) {
- if ( lpIndex == 0 )
- lpIndex = itLpNaca.xLpIndex;
- HvCallEvent_closeLpEventPath( lpIndex, eventType );
- --lpEventHandlerPaths[eventType];
- rc = 0;
- }
- return rc;
-}
-
diff --git a/arch/ppc64/kernel/Makefile b/arch/ppc64/kernel/Makefile
index ae60eb1193c6..58b19f107656 100644
--- a/arch/ppc64/kernel/Makefile
+++ b/arch/ppc64/kernel/Makefile
@@ -2,84 +2,53 @@
# Makefile for the linux ppc64 kernel.
#
+ifneq ($(CONFIG_PPC_MERGE),y)
+
EXTRA_CFLAGS += -mno-minimal-toc
extra-y := head.o vmlinux.lds
-obj-y := setup.o entry.o traps.o irq.o idle.o dma.o \
- time.o process.o signal.o syscalls.o misc.o ptrace.o \
- align.o semaphore.o bitops.o pacaData.o \
- udbg.o binfmt_elf32.o sys_ppc32.o ioctl32.o \
- ptrace32.o signal32.o rtc.o init_task.o \
- lmb.o cputable.o cpu_setup_power4.o idle_power4.o \
- iommu.o sysfs.o vdso.o pmc.o firmware.o
-obj-y += vdso32/ vdso64/
+obj-y := misc.o prom.o
+
+endif
-obj-$(CONFIG_PPC_OF) += of_device.o
+obj-y += idle.o dma.o \
+ align.o \
+ udbg.o \
+ rtc.o \
+ iommu.o vdso.o
+obj-y += vdso32/ vdso64/
-pci-obj-$(CONFIG_PPC_ISERIES) += iSeries_pci.o iSeries_irq.o \
- iSeries_VpdInfo.o
pci-obj-$(CONFIG_PPC_MULTIPLATFORM) += pci_dn.o pci_direct_iommu.o
obj-$(CONFIG_PCI) += pci.o pci_iommu.o iomap.o $(pci-obj-y)
-obj-$(CONFIG_PPC_ISERIES) += HvCall.o HvLpConfig.o LparData.o \
- iSeries_setup.o ItLpQueue.o hvCall.o \
- mf.o HvLpEvent.o iSeries_proc.o iSeries_htab.o \
- iSeries_iommu.o
-
-obj-$(CONFIG_PPC_MULTIPLATFORM) += nvram.o i8259.o prom_init.o prom.o
-
-obj-$(CONFIG_PPC_PSERIES) += pSeries_pci.o pSeries_lpar.o pSeries_hvCall.o \
- pSeries_nvram.o rtasd.o ras.o pSeries_reconfig.o \
- pSeries_setup.o pSeries_iommu.o udbg_16550.o
+obj-$(CONFIG_PPC_MULTIPLATFORM) += nvram.o
+ifneq ($(CONFIG_PPC_MERGE),y)
+obj-$(CONFIG_PPC_MULTIPLATFORM) += prom_init.o
+endif
-obj-$(CONFIG_PPC_BPA) += bpa_setup.o bpa_iommu.o bpa_nvram.o \
- bpa_iic.o spider-pic.o
+obj-$(CONFIG_PPC_PSERIES) += udbg_16550.o
obj-$(CONFIG_KEXEC) += machine_kexec.o
-obj-$(CONFIG_EEH) += eeh.o
-obj-$(CONFIG_PROC_FS) += proc_ppc64.o
-obj-$(CONFIG_RTAS_FLASH) += rtas_flash.o
-obj-$(CONFIG_SMP) += smp.o
-obj-$(CONFIG_MODULES) += module.o ppc_ksyms.o
-obj-$(CONFIG_PPC_RTAS) += rtas.o rtas_pci.o
-obj-$(CONFIG_RTAS_PROC) += rtas-proc.o
-obj-$(CONFIG_SCANLOG) += scanlog.o
-obj-$(CONFIG_VIOPATH) += viopath.o
-obj-$(CONFIG_LPARCFG) += lparcfg.o
+obj-$(CONFIG_MODULES) += module.o
+ifneq ($(CONFIG_PPC_MERGE),y)
+obj-$(CONFIG_MODULES) += ppc_ksyms.o
+endif
obj-$(CONFIG_HVC_CONSOLE) += hvconsole.o
+ifneq ($(CONFIG_PPC_MERGE),y)
obj-$(CONFIG_BOOTX_TEXT) += btext.o
+endif
obj-$(CONFIG_HVCS) += hvcserver.o
-vio-obj-$(CONFIG_PPC_PSERIES) += pSeries_vio.o
-vio-obj-$(CONFIG_PPC_ISERIES) += iSeries_vio.o
-obj-$(CONFIG_IBMVIO) += vio.o $(vio-obj-y)
-obj-$(CONFIG_XICS) += xics.o
-obj-$(CONFIG_MPIC) += mpic.o
-
-obj-$(CONFIG_PPC_PMAC) += pmac_setup.o pmac_feature.o pmac_pci.o \
- pmac_time.o pmac_nvram.o pmac_low_i2c.o \
- udbg_scc.o
-
-obj-$(CONFIG_PPC_MAPLE) += maple_setup.o maple_pci.o maple_time.o \
- udbg_16550.o
+obj-$(CONFIG_PPC_PMAC) += udbg_scc.o
-obj-$(CONFIG_U3_DART) += u3_iommu.o
+obj-$(CONFIG_PPC_MAPLE) += udbg_16550.o
-ifdef CONFIG_SMP
-obj-$(CONFIG_PPC_PMAC) += pmac_smp.o smp-tbsync.o
-obj-$(CONFIG_PPC_ISERIES) += iSeries_smp.o
-obj-$(CONFIG_PPC_PSERIES) += pSeries_smp.o
-obj-$(CONFIG_PPC_BPA) += pSeries_smp.o
-obj-$(CONFIG_PPC_MAPLE) += smp-tbsync.o
-endif
-
-obj-$(CONFIG_ALTIVEC) += vecemu.o vector.o
obj-$(CONFIG_KPROBES) += kprobes.o
-CFLAGS_ioctl32.o += -Ifs/
-
+ifneq ($(CONFIG_PPC_MERGE),y)
ifeq ($(CONFIG_PPC_ISERIES),y)
-arch/ppc64/kernel/head.o: arch/ppc64/kernel/lparmap.s
-AFLAGS_head.o += -Iarch/ppc64/kernel
+arch/ppc64/kernel/head.o: arch/powerpc/kernel/lparmap.s
+AFLAGS_head.o += -Iarch/powerpc/kernel
+endif
endif
diff --git a/arch/ppc64/kernel/align.c b/arch/ppc64/kernel/align.c
index 330e7ef81427..256d5b592aa1 100644
--- a/arch/ppc64/kernel/align.c
+++ b/arch/ppc64/kernel/align.c
@@ -313,7 +313,7 @@ fix_alignment(struct pt_regs *regs)
/* Doing stfs, have to convert to single */
preempt_disable();
enable_kernel_fp();
- cvt_df(&current->thread.fpr[reg], (float *)&data.v[4], &current->thread.fpscr);
+ cvt_df(&current->thread.fpr[reg], (float *)&data.v[4], &current->thread);
disable_kernel_fp();
preempt_enable();
}
@@ -349,7 +349,7 @@ fix_alignment(struct pt_regs *regs)
/* Doing lfs, have to convert to double */
preempt_disable();
enable_kernel_fp();
- cvt_fd((float *)&data.v[4], &current->thread.fpr[reg], &current->thread.fpscr);
+ cvt_fd((float *)&data.v[4], &current->thread.fpr[reg], &current->thread);
disable_kernel_fp();
preempt_enable();
}
diff --git a/arch/ppc64/kernel/asm-offsets.c b/arch/ppc64/kernel/asm-offsets.c
index 1ff4fa05a973..84ab5c18ef52 100644
--- a/arch/ppc64/kernel/asm-offsets.c
+++ b/arch/ppc64/kernel/asm-offsets.c
@@ -31,7 +31,7 @@
#include <asm/paca.h>
#include <asm/lppaca.h>
-#include <asm/iSeries/HvLpEvent.h>
+#include <asm/iseries/hv_lp_event.h>
#include <asm/rtas.h>
#include <asm/cputable.h>
#include <asm/cache.h>
@@ -46,8 +46,6 @@
int main(void)
{
/* thread struct on stack */
- DEFINE(THREAD_SHIFT, THREAD_SHIFT);
- DEFINE(THREAD_SIZE, THREAD_SIZE);
DEFINE(TI_FLAGS, offsetof(struct thread_info, flags));
DEFINE(TI_PREEMPT, offsetof(struct thread_info, preempt_count));
DEFINE(TI_SC_NOERR, offsetof(struct thread_info, syscall_noerror));
@@ -76,7 +74,7 @@ int main(void)
DEFINE(ICACHEL1LINESIZE, offsetof(struct ppc64_caches, iline_size));
DEFINE(ICACHEL1LOGLINESIZE, offsetof(struct ppc64_caches, log_iline_size));
DEFINE(ICACHEL1LINESPERPAGE, offsetof(struct ppc64_caches, ilines_per_page));
- DEFINE(PLATFORM, offsetof(struct systemcfg, platform));
+ DEFINE(PLATFORM_LPAR, PLATFORM_LPAR);
/* paca */
DEFINE(PACA_SIZE, sizeof(struct paca_struct));
@@ -94,6 +92,9 @@ int main(void)
DEFINE(PACASLBCACHE, offsetof(struct paca_struct, slb_cache));
DEFINE(PACASLBCACHEPTR, offsetof(struct paca_struct, slb_cache_ptr));
DEFINE(PACACONTEXTID, offsetof(struct paca_struct, context.id));
+#ifdef CONFIG_PPC_64K_PAGES
+ DEFINE(PACAPGDIR, offsetof(struct paca_struct, pgdir));
+#endif
#ifdef CONFIG_HUGETLB_PAGE
DEFINE(PACALOWHTLBAREAS, offsetof(struct paca_struct, context.low_htlb_areas));
DEFINE(PACAHIGHHTLBAREAS, offsetof(struct paca_struct, context.high_htlb_areas));
diff --git a/arch/ppc64/kernel/btext.c b/arch/ppc64/kernel/btext.c
index b6fbfbe9032d..506a37885c5c 100644
--- a/arch/ppc64/kernel/btext.c
+++ b/arch/ppc64/kernel/btext.c
@@ -18,6 +18,7 @@
#include <asm/io.h>
#include <asm/lmb.h>
#include <asm/processor.h>
+#include <asm/udbg.h>
#undef NO_SCROLL
@@ -131,6 +132,47 @@ int btext_initialize(struct device_node *np)
return 0;
}
+static void btext_putc(unsigned char c)
+{
+ btext_drawchar(c);
+}
+
+void __init init_boot_display(void)
+{
+ char *name;
+ struct device_node *np = NULL;
+ int rc = -ENODEV;
+
+ printk("trying to initialize btext ...\n");
+
+ name = (char *)get_property(of_chosen, "linux,stdout-path", NULL);
+ if (name != NULL) {
+ np = of_find_node_by_path(name);
+ if (np != NULL) {
+ if (strcmp(np->type, "display") != 0) {
+ printk("boot stdout isn't a display !\n");
+ of_node_put(np);
+ np = NULL;
+ }
+ }
+ }
+ if (np)
+ rc = btext_initialize(np);
+ if (rc) {
+ for (np = NULL; (np = of_find_node_by_type(np, "display"));) {
+ if (get_property(np, "linux,opened", NULL)) {
+ printk("trying %s ...\n", np->full_name);
+ rc = btext_initialize(np);
+ printk("result: %d\n", rc);
+ }
+ if (rc == 0)
+ break;
+ }
+ }
+ if (rc == 0 && udbg_putc == NULL)
+ udbg_putc = btext_putc;
+}
+
/* Calc the base address of a given point (x,y) */
static unsigned char * calc_base(int x, int y)
diff --git a/arch/ppc64/kernel/cputable.c b/arch/ppc64/kernel/cputable.c
deleted file mode 100644
index 8831a28c3c4e..000000000000
--- a/arch/ppc64/kernel/cputable.c
+++ /dev/null
@@ -1,308 +0,0 @@
-/*
- * arch/ppc64/kernel/cputable.c
- *
- * Copyright (C) 2001 Ben. Herrenschmidt (benh@kernel.crashing.org)
- *
- * Modifications for ppc64:
- * Copyright (C) 2003 Dave Engebretsen <engebret@us.ibm.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-
-#include <linux/config.h>
-#include <linux/string.h>
-#include <linux/sched.h>
-#include <linux/threads.h>
-#include <linux/init.h>
-#include <linux/module.h>
-
-#include <asm/oprofile_impl.h>
-#include <asm/cputable.h>
-
-struct cpu_spec* cur_cpu_spec = NULL;
-EXPORT_SYMBOL(cur_cpu_spec);
-
-/* NOTE:
- * Unlike ppc32, ppc64 will only call this once for the boot CPU, it's
- * the responsibility of the appropriate CPU save/restore functions to
- * eventually copy these settings over. Those save/restore aren't yet
- * part of the cputable though. That has to be fixed for both ppc32
- * and ppc64
- */
-extern void __setup_cpu_power3(unsigned long offset, struct cpu_spec* spec);
-extern void __setup_cpu_power4(unsigned long offset, struct cpu_spec* spec);
-extern void __setup_cpu_ppc970(unsigned long offset, struct cpu_spec* spec);
-extern void __setup_cpu_be(unsigned long offset, struct cpu_spec* spec);
-
-
-/* We only set the altivec features if the kernel was compiled with altivec
- * support
- */
-#ifdef CONFIG_ALTIVEC
-#define CPU_FTR_ALTIVEC_COMP CPU_FTR_ALTIVEC
-#define PPC_FEATURE_HAS_ALTIVEC_COMP PPC_FEATURE_HAS_ALTIVEC
-#else
-#define CPU_FTR_ALTIVEC_COMP 0
-#define PPC_FEATURE_HAS_ALTIVEC_COMP 0
-#endif
-
-struct cpu_spec cpu_specs[] = {
- { /* Power3 */
- .pvr_mask = 0xffff0000,
- .pvr_value = 0x00400000,
- .cpu_name = "POWER3 (630)",
- .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
- CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | CPU_FTR_IABR,
- .cpu_user_features = COMMON_USER_PPC64,
- .icache_bsize = 128,
- .dcache_bsize = 128,
- .num_pmcs = 8,
- .cpu_setup = __setup_cpu_power3,
-#ifdef CONFIG_OPROFILE
- .oprofile_cpu_type = "ppc64/power3",
- .oprofile_model = &op_model_rs64,
-#endif
- },
- { /* Power3+ */
- .pvr_mask = 0xffff0000,
- .pvr_value = 0x00410000,
- .cpu_name = "POWER3 (630+)",
- .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
- CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | CPU_FTR_IABR,
- .cpu_user_features = COMMON_USER_PPC64,
- .icache_bsize = 128,
- .dcache_bsize = 128,
- .num_pmcs = 8,
- .cpu_setup = __setup_cpu_power3,
-#ifdef CONFIG_OPROFILE
- .oprofile_cpu_type = "ppc64/power3",
- .oprofile_model = &op_model_rs64,
-#endif
- },
- { /* Northstar */
- .pvr_mask = 0xffff0000,
- .pvr_value = 0x00330000,
- .cpu_name = "RS64-II (northstar)",
- .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
- CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | CPU_FTR_IABR |
- CPU_FTR_MMCRA | CPU_FTR_CTRL,
- .cpu_user_features = COMMON_USER_PPC64,
- .icache_bsize = 128,
- .dcache_bsize = 128,
- .num_pmcs = 8,
- .cpu_setup = __setup_cpu_power3,
-#ifdef CONFIG_OPROFILE
- .oprofile_cpu_type = "ppc64/rs64",
- .oprofile_model = &op_model_rs64,
-#endif
- },
- { /* Pulsar */
- .pvr_mask = 0xffff0000,
- .pvr_value = 0x00340000,
- .cpu_name = "RS64-III (pulsar)",
- .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
- CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | CPU_FTR_IABR |
- CPU_FTR_MMCRA | CPU_FTR_CTRL,
- .cpu_user_features = COMMON_USER_PPC64,
- .icache_bsize = 128,
- .dcache_bsize = 128,
- .num_pmcs = 8,
- .cpu_setup = __setup_cpu_power3,
-#ifdef CONFIG_OPROFILE
- .oprofile_cpu_type = "ppc64/rs64",
- .oprofile_model = &op_model_rs64,
-#endif
- },
- { /* I-star */
- .pvr_mask = 0xffff0000,
- .pvr_value = 0x00360000,
- .cpu_name = "RS64-III (icestar)",
- .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
- CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | CPU_FTR_IABR |
- CPU_FTR_MMCRA | CPU_FTR_CTRL,
- .cpu_user_features = COMMON_USER_PPC64,
- .icache_bsize = 128,
- .dcache_bsize = 128,
- .num_pmcs = 8,
- .cpu_setup = __setup_cpu_power3,
-#ifdef CONFIG_OPROFILE
- .oprofile_cpu_type = "ppc64/rs64",
- .oprofile_model = &op_model_rs64,
-#endif
- },
- { /* S-star */
- .pvr_mask = 0xffff0000,
- .pvr_value = 0x00370000,
- .cpu_name = "RS64-IV (sstar)",
- .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
- CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | CPU_FTR_IABR |
- CPU_FTR_MMCRA | CPU_FTR_CTRL,
- .cpu_user_features = COMMON_USER_PPC64,
- .icache_bsize = 128,
- .dcache_bsize = 128,
- .num_pmcs = 8,
- .cpu_setup = __setup_cpu_power3,
-#ifdef CONFIG_OPROFILE
- .oprofile_cpu_type = "ppc64/rs64",
- .oprofile_model = &op_model_rs64,
-#endif
- },
- { /* Power4 */
- .pvr_mask = 0xffff0000,
- .pvr_value = 0x00350000,
- .cpu_name = "POWER4 (gp)",
- .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
- CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE |
- CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_MMCRA,
- .cpu_user_features = COMMON_USER_PPC64,
- .icache_bsize = 128,
- .dcache_bsize = 128,
- .num_pmcs = 8,
- .cpu_setup = __setup_cpu_power4,
-#ifdef CONFIG_OPROFILE
- .oprofile_cpu_type = "ppc64/power4",
- .oprofile_model = &op_model_rs64,
-#endif
- },
- { /* Power4+ */
- .pvr_mask = 0xffff0000,
- .pvr_value = 0x00380000,
- .cpu_name = "POWER4+ (gq)",
- .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
- CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE |
- CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_MMCRA,
- .cpu_user_features = COMMON_USER_PPC64,
- .icache_bsize = 128,
- .dcache_bsize = 128,
- .num_pmcs = 8,
- .cpu_setup = __setup_cpu_power4,
-#ifdef CONFIG_OPROFILE
- .oprofile_cpu_type = "ppc64/power4",
- .oprofile_model = &op_model_power4,
-#endif
- },
- { /* PPC970 */
- .pvr_mask = 0xffff0000,
- .pvr_value = 0x00390000,
- .cpu_name = "PPC970",
- .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
- CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE |
- CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_ALTIVEC_COMP |
- CPU_FTR_CAN_NAP | CPU_FTR_MMCRA,
- .cpu_user_features = COMMON_USER_PPC64 |
- PPC_FEATURE_HAS_ALTIVEC_COMP,
- .icache_bsize = 128,
- .dcache_bsize = 128,
- .num_pmcs = 8,
- .cpu_setup = __setup_cpu_ppc970,
-#ifdef CONFIG_OPROFILE
- .oprofile_cpu_type = "ppc64/970",
- .oprofile_model = &op_model_power4,
-#endif
- },
- { /* PPC970FX */
- .pvr_mask = 0xffff0000,
- .pvr_value = 0x003c0000,
- .cpu_name = "PPC970FX",
- .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
- CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE |
- CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_ALTIVEC_COMP |
- CPU_FTR_CAN_NAP | CPU_FTR_MMCRA,
- .cpu_user_features = COMMON_USER_PPC64 |
- PPC_FEATURE_HAS_ALTIVEC_COMP,
- .icache_bsize = 128,
- .dcache_bsize = 128,
- .num_pmcs = 8,
- .cpu_setup = __setup_cpu_ppc970,
-#ifdef CONFIG_OPROFILE
- .oprofile_cpu_type = "ppc64/970",
- .oprofile_model = &op_model_power4,
-#endif
- },
- { /* PPC970MP */
- .pvr_mask = 0xffff0000,
- .pvr_value = 0x00440000,
- .cpu_name = "PPC970MP",
- .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
- CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE |
- CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_ALTIVEC_COMP |
- CPU_FTR_CAN_NAP | CPU_FTR_MMCRA,
- .cpu_user_features = COMMON_USER_PPC64 |
- PPC_FEATURE_HAS_ALTIVEC_COMP,
- .icache_bsize = 128,
- .dcache_bsize = 128,
- .cpu_setup = __setup_cpu_ppc970,
-#ifdef CONFIG_OPROFILE
- .oprofile_cpu_type = "ppc64/970",
- .oprofile_model = &op_model_power4,
-#endif
- },
- { /* Power5 */
- .pvr_mask = 0xffff0000,
- .pvr_value = 0x003a0000,
- .cpu_name = "POWER5 (gr)",
- .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
- CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE |
- CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_MMCRA | CPU_FTR_SMT |
- CPU_FTR_COHERENT_ICACHE | CPU_FTR_LOCKLESS_TLBIE |
- CPU_FTR_MMCRA_SIHV,
- .cpu_user_features = COMMON_USER_PPC64,
- .icache_bsize = 128,
- .dcache_bsize = 128,
- .num_pmcs = 6,
- .cpu_setup = __setup_cpu_power4,
-#ifdef CONFIG_OPROFILE
- .oprofile_cpu_type = "ppc64/power5",
- .oprofile_model = &op_model_power4,
-#endif
- },
- { /* Power5 */
- .pvr_mask = 0xffff0000,
- .pvr_value = 0x003b0000,
- .cpu_name = "POWER5 (gs)",
- .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
- CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE |
- CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_MMCRA | CPU_FTR_SMT |
- CPU_FTR_COHERENT_ICACHE | CPU_FTR_LOCKLESS_TLBIE |
- CPU_FTR_MMCRA_SIHV,
- .cpu_user_features = COMMON_USER_PPC64,
- .icache_bsize = 128,
- .dcache_bsize = 128,
- .num_pmcs = 6,
- .cpu_setup = __setup_cpu_power4,
-#ifdef CONFIG_OPROFILE
- .oprofile_cpu_type = "ppc64/power5",
- .oprofile_model = &op_model_power4,
-#endif
- },
- { /* BE DD1.x */
- .pvr_mask = 0xffff0000,
- .pvr_value = 0x00700000,
- .cpu_name = "Broadband Engine",
- .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
- CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE |
- CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_ALTIVEC_COMP |
- CPU_FTR_SMT,
- .cpu_user_features = COMMON_USER_PPC64 |
- PPC_FEATURE_HAS_ALTIVEC_COMP,
- .icache_bsize = 128,
- .dcache_bsize = 128,
- .cpu_setup = __setup_cpu_be,
- },
- { /* default match */
- .pvr_mask = 0x00000000,
- .pvr_value = 0x00000000,
- .cpu_name = "POWER4 (compatible)",
- .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
- CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE |
- CPU_FTR_PPCAS_ARCH_V2,
- .cpu_user_features = COMMON_USER_PPC64,
- .icache_bsize = 128,
- .dcache_bsize = 128,
- .num_pmcs = 6,
- .cpu_setup = __setup_cpu_power4,
- }
-};
diff --git a/arch/ppc64/kernel/head.S b/arch/ppc64/kernel/head.S
index 72c61041151a..1c869ea72d28 100644
--- a/arch/ppc64/kernel/head.S
+++ b/arch/ppc64/kernel/head.S
@@ -28,14 +28,14 @@
#include <asm/processor.h>
#include <asm/page.h>
#include <asm/mmu.h>
-#include <asm/systemcfg.h>
#include <asm/ppc_asm.h>
#include <asm/asm-offsets.h>
#include <asm/bug.h>
#include <asm/cputable.h>
#include <asm/setup.h>
#include <asm/hvcall.h>
-#include <asm/iSeries/LparMap.h>
+#include <asm/iseries/lpar_map.h>
+#include <asm/thread_info.h>
#ifdef CONFIG_PPC_ISERIES
#define DO_SOFT_DISABLE
@@ -80,7 +80,7 @@ _stext:
_GLOBAL(__start)
/* NOP this out unconditionally */
BEGIN_FTR_SECTION
- b .__start_initialization_multiplatform
+ b .__start_initialization_multiplatform
END_FTR_SECTION(0, 1)
#endif /* CONFIG_PPC_MULTIPLATFORM */
@@ -194,29 +194,29 @@ exception_marker:
#define EX_R12 24
#define EX_R13 32
#define EX_SRR0 40
-#define EX_R3 40 /* SLB miss saves R3, but not SRR0 */
#define EX_DAR 48
-#define EX_LR 48 /* SLB miss saves LR, but not DAR */
#define EX_DSISR 56
#define EX_CCR 60
+#define EX_R3 64
+#define EX_LR 72
#define EXCEPTION_PROLOG_PSERIES(area, label) \
- mfspr r13,SPRG3; /* get paca address into r13 */ \
+ mfspr r13,SPRN_SPRG3; /* get paca address into r13 */ \
std r9,area+EX_R9(r13); /* save r9 - r12 */ \
std r10,area+EX_R10(r13); \
std r11,area+EX_R11(r13); \
std r12,area+EX_R12(r13); \
- mfspr r9,SPRG1; \
+ mfspr r9,SPRN_SPRG1; \
std r9,area+EX_R13(r13); \
mfcr r9; \
clrrdi r12,r13,32; /* get high part of &label */ \
mfmsr r10; \
- mfspr r11,SRR0; /* save SRR0 */ \
+ mfspr r11,SPRN_SRR0; /* save SRR0 */ \
ori r12,r12,(label)@l; /* virt addr of handler */ \
ori r10,r10,MSR_IR|MSR_DR|MSR_RI; \
- mtspr SRR0,r12; \
- mfspr r12,SRR1; /* and SRR1 */ \
- mtspr SRR1,r10; \
+ mtspr SPRN_SRR0,r12; \
+ mfspr r12,SPRN_SRR1; /* and SRR1 */ \
+ mtspr SPRN_SRR1,r10; \
rfid; \
b . /* prevent speculative execution */
@@ -225,12 +225,12 @@ exception_marker:
* This code runs with relocation on.
*/
#define EXCEPTION_PROLOG_ISERIES_1(area) \
- mfspr r13,SPRG3; /* get paca address into r13 */ \
+ mfspr r13,SPRN_SPRG3; /* get paca address into r13 */ \
std r9,area+EX_R9(r13); /* save r9 - r12 */ \
std r10,area+EX_R10(r13); \
std r11,area+EX_R11(r13); \
std r12,area+EX_R12(r13); \
- mfspr r9,SPRG1; \
+ mfspr r9,SPRN_SPRG1; \
std r9,area+EX_R13(r13); \
mfcr r9
@@ -283,7 +283,7 @@ exception_marker:
std r9,_LINK(r1); \
mfctr r10; /* save CTR in stackframe */ \
std r10,_CTR(r1); \
- mfspr r11,XER; /* save XER in stackframe */ \
+ mfspr r11,SPRN_XER; /* save XER in stackframe */ \
std r11,_XER(r1); \
li r9,(n)+1; \
std r9,_TRAP(r1); /* set trap number */ \
@@ -300,7 +300,7 @@ exception_marker:
.globl label##_pSeries; \
label##_pSeries: \
HMT_MEDIUM; \
- mtspr SPRG1,r13; /* save r13 */ \
+ mtspr SPRN_SPRG1,r13; /* save r13 */ \
RUNLATCH_ON(r13); \
EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common)
@@ -308,7 +308,7 @@ label##_pSeries: \
.globl label##_iSeries; \
label##_iSeries: \
HMT_MEDIUM; \
- mtspr SPRG1,r13; /* save r13 */ \
+ mtspr SPRN_SPRG1,r13; /* save r13 */ \
RUNLATCH_ON(r13); \
EXCEPTION_PROLOG_ISERIES_1(area); \
EXCEPTION_PROLOG_ISERIES_2; \
@@ -318,7 +318,7 @@ label##_iSeries: \
.globl label##_iSeries; \
label##_iSeries: \
HMT_MEDIUM; \
- mtspr SPRG1,r13; /* save r13 */ \
+ mtspr SPRN_SPRG1,r13; /* save r13 */ \
RUNLATCH_ON(r13); \
EXCEPTION_PROLOG_ISERIES_1(PACA_EXGEN); \
lbz r10,PACAPROCENABLED(r13); \
@@ -388,7 +388,7 @@ __start_interrupts:
. = 0x200
_machine_check_pSeries:
HMT_MEDIUM
- mtspr SPRG1,r13 /* save r13 */
+ mtspr SPRN_SPRG1,r13 /* save r13 */
RUNLATCH_ON(r13)
EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common)
@@ -396,18 +396,18 @@ _machine_check_pSeries:
.globl data_access_pSeries
data_access_pSeries:
HMT_MEDIUM
- mtspr SPRG1,r13
+ mtspr SPRN_SPRG1,r13
BEGIN_FTR_SECTION
- mtspr SPRG2,r12
- mfspr r13,DAR
- mfspr r12,DSISR
+ mtspr SPRN_SPRG2,r12
+ mfspr r13,SPRN_DAR
+ mfspr r12,SPRN_DSISR
srdi r13,r13,60
rlwimi r13,r12,16,0x20
mfcr r12
cmpwi r13,0x2c
beq .do_stab_bolted_pSeries
mtcrf 0x80,r12
- mfspr r12,SPRG2
+ mfspr r12,SPRN_SPRG2
END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, data_access_common)
@@ -415,20 +415,25 @@ END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
.globl data_access_slb_pSeries
data_access_slb_pSeries:
HMT_MEDIUM
- mtspr SPRG1,r13
+ mtspr SPRN_SPRG1,r13
RUNLATCH_ON(r13)
- mfspr r13,SPRG3 /* get paca address into r13 */
+ mfspr r13,SPRN_SPRG3 /* get paca address into r13 */
+ std r3,PACA_EXSLB+EX_R3(r13)
+ mfspr r3,SPRN_DAR
std r9,PACA_EXSLB+EX_R9(r13) /* save r9 - r12 */
+ mfcr r9
+#ifdef __DISABLED__
+ /* Keep that around for when we re-implement dynamic VSIDs */
+ cmpdi r3,0
+ bge slb_miss_user_pseries
+#endif /* __DISABLED__ */
std r10,PACA_EXSLB+EX_R10(r13)
std r11,PACA_EXSLB+EX_R11(r13)
std r12,PACA_EXSLB+EX_R12(r13)
- std r3,PACA_EXSLB+EX_R3(r13)
- mfspr r9,SPRG1
- std r9,PACA_EXSLB+EX_R13(r13)
- mfcr r9
- mfspr r12,SRR1 /* and SRR1 */
- mfspr r3,DAR
- b .do_slb_miss /* Rel. branch works in real mode */
+ mfspr r10,SPRN_SPRG1
+ std r10,PACA_EXSLB+EX_R13(r13)
+ mfspr r12,SPRN_SRR1 /* and SRR1 */
+ b .slb_miss_realmode /* Rel. branch works in real mode */
STD_EXCEPTION_PSERIES(0x400, instruction_access)
@@ -436,20 +441,25 @@ data_access_slb_pSeries:
.globl instruction_access_slb_pSeries
instruction_access_slb_pSeries:
HMT_MEDIUM
- mtspr SPRG1,r13
+ mtspr SPRN_SPRG1,r13
RUNLATCH_ON(r13)
- mfspr r13,SPRG3 /* get paca address into r13 */
+ mfspr r13,SPRN_SPRG3 /* get paca address into r13 */
+ std r3,PACA_EXSLB+EX_R3(r13)
+ mfspr r3,SPRN_SRR0 /* SRR0 is faulting address */
std r9,PACA_EXSLB+EX_R9(r13) /* save r9 - r12 */
+ mfcr r9
+#ifdef __DISABLED__
+ /* Keep that around for when we re-implement dynamic VSIDs */
+ cmpdi r3,0
+ bge slb_miss_user_pseries
+#endif /* __DISABLED__ */
std r10,PACA_EXSLB+EX_R10(r13)
std r11,PACA_EXSLB+EX_R11(r13)
std r12,PACA_EXSLB+EX_R12(r13)
- std r3,PACA_EXSLB+EX_R3(r13)
- mfspr r9,SPRG1
- std r9,PACA_EXSLB+EX_R13(r13)
- mfcr r9
- mfspr r12,SRR1 /* and SRR1 */
- mfspr r3,SRR0 /* SRR0 is faulting address */
- b .do_slb_miss /* Rel. branch works in real mode */
+ mfspr r10,SPRN_SPRG1
+ std r10,PACA_EXSLB+EX_R13(r13)
+ mfspr r12,SPRN_SRR1 /* and SRR1 */
+ b .slb_miss_realmode /* Rel. branch works in real mode */
STD_EXCEPTION_PSERIES(0x500, hardware_interrupt)
STD_EXCEPTION_PSERIES(0x600, alignment)
@@ -466,15 +476,15 @@ system_call_pSeries:
RUNLATCH_ON(r9)
mr r9,r13
mfmsr r10
- mfspr r13,SPRG3
- mfspr r11,SRR0
+ mfspr r13,SPRN_SPRG3
+ mfspr r11,SPRN_SRR0
clrrdi r12,r13,32
oris r12,r12,system_call_common@h
ori r12,r12,system_call_common@l
- mtspr SRR0,r12
+ mtspr SPRN_SRR0,r12
ori r10,r10,MSR_IR|MSR_DR|MSR_RI
- mfspr r12,SRR1
- mtspr SRR1,r10
+ mfspr r12,SPRN_SRR1
+ mtspr SPRN_SRR1,r10
rfid
b . /* prevent speculative execution */
@@ -504,25 +514,57 @@ system_call_pSeries:
.align 7
_GLOBAL(do_stab_bolted_pSeries)
mtcrf 0x80,r12
- mfspr r12,SPRG2
+ mfspr r12,SPRN_SPRG2
EXCEPTION_PROLOG_PSERIES(PACA_EXSLB, .do_stab_bolted)
/*
+ * We have some room here we use that to put
+ * the peries slb miss user trampoline code so it's reasonably
+ * away from slb_miss_user_common to avoid problems with rfid
+ *
+ * This is used for when the SLB miss handler has to go virtual,
+ * which doesn't happen for now anymore but will once we re-implement
+ * dynamic VSIDs for shared page tables
+ */
+#ifdef __DISABLED__
+slb_miss_user_pseries:
+ std r10,PACA_EXGEN+EX_R10(r13)
+ std r11,PACA_EXGEN+EX_R11(r13)
+ std r12,PACA_EXGEN+EX_R12(r13)
+ mfspr r10,SPRG1
+ ld r11,PACA_EXSLB+EX_R9(r13)
+ ld r12,PACA_EXSLB+EX_R3(r13)
+ std r10,PACA_EXGEN+EX_R13(r13)
+ std r11,PACA_EXGEN+EX_R9(r13)
+ std r12,PACA_EXGEN+EX_R3(r13)
+ clrrdi r12,r13,32
+ mfmsr r10
+ mfspr r11,SRR0 /* save SRR0 */
+ ori r12,r12,slb_miss_user_common@l /* virt addr of handler */
+ ori r10,r10,MSR_IR|MSR_DR|MSR_RI
+ mtspr SRR0,r12
+ mfspr r12,SRR1 /* and SRR1 */
+ mtspr SRR1,r10
+ rfid
+ b . /* prevent spec. execution */
+#endif /* __DISABLED__ */
+
+/*
* Vectors for the FWNMI option. Share common code.
*/
- .globl system_reset_fwnmi
+ .globl system_reset_fwnmi
system_reset_fwnmi:
- HMT_MEDIUM
- mtspr SPRG1,r13 /* save r13 */
- RUNLATCH_ON(r13)
- EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, system_reset_common)
+ HMT_MEDIUM
+ mtspr SPRN_SPRG1,r13 /* save r13 */
+ RUNLATCH_ON(r13)
+ EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, system_reset_common)
- .globl machine_check_fwnmi
+ .globl machine_check_fwnmi
machine_check_fwnmi:
- HMT_MEDIUM
- mtspr SPRG1,r13 /* save r13 */
- RUNLATCH_ON(r13)
- EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common)
+ HMT_MEDIUM
+ mtspr SPRN_SPRG1,r13 /* save r13 */
+ RUNLATCH_ON(r13)
+ EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common)
#ifdef CONFIG_PPC_ISERIES
/*** ISeries-LPAR interrupt handlers ***/
@@ -531,18 +573,18 @@ machine_check_fwnmi:
.globl data_access_iSeries
data_access_iSeries:
- mtspr SPRG1,r13
+ mtspr SPRN_SPRG1,r13
BEGIN_FTR_SECTION
- mtspr SPRG2,r12
- mfspr r13,DAR
- mfspr r12,DSISR
+ mtspr SPRN_SPRG2,r12
+ mfspr r13,SPRN_DAR
+ mfspr r12,SPRN_DSISR
srdi r13,r13,60
rlwimi r13,r12,16,0x20
mfcr r12
cmpwi r13,0x2c
beq .do_stab_bolted_iSeries
mtcrf 0x80,r12
- mfspr r12,SPRG2
+ mfspr r12,SPRN_SPRG2
END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
EXCEPTION_PROLOG_ISERIES_1(PACA_EXGEN)
EXCEPTION_PROLOG_ISERIES_2
@@ -550,30 +592,67 @@ END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
.do_stab_bolted_iSeries:
mtcrf 0x80,r12
- mfspr r12,SPRG2
+ mfspr r12,SPRN_SPRG2
EXCEPTION_PROLOG_ISERIES_1(PACA_EXSLB)
EXCEPTION_PROLOG_ISERIES_2
b .do_stab_bolted
.globl data_access_slb_iSeries
data_access_slb_iSeries:
- mtspr SPRG1,r13 /* save r13 */
- EXCEPTION_PROLOG_ISERIES_1(PACA_EXSLB)
+ mtspr SPRN_SPRG1,r13 /* save r13 */
+ mfspr r13,SPRN_SPRG3 /* get paca address into r13 */
std r3,PACA_EXSLB+EX_R3(r13)
- ld r12,PACALPPACA+LPPACASRR1(r13)
- mfspr r3,DAR
- b .do_slb_miss
+ mfspr r3,SPRN_DAR
+ std r9,PACA_EXSLB+EX_R9(r13)
+ mfcr r9
+#ifdef __DISABLED__
+ cmpdi r3,0
+ bge slb_miss_user_iseries
+#endif
+ std r10,PACA_EXSLB+EX_R10(r13)
+ std r11,PACA_EXSLB+EX_R11(r13)
+ std r12,PACA_EXSLB+EX_R12(r13)
+ mfspr r10,SPRN_SPRG1
+ std r10,PACA_EXSLB+EX_R13(r13)
+ ld r12,PACALPPACA+LPPACASRR1(r13);
+ b .slb_miss_realmode
STD_EXCEPTION_ISERIES(0x400, instruction_access, PACA_EXGEN)
.globl instruction_access_slb_iSeries
instruction_access_slb_iSeries:
- mtspr SPRG1,r13 /* save r13 */
- EXCEPTION_PROLOG_ISERIES_1(PACA_EXSLB)
+ mtspr SPRN_SPRG1,r13 /* save r13 */
+ mfspr r13,SPRN_SPRG3 /* get paca address into r13 */
std r3,PACA_EXSLB+EX_R3(r13)
- ld r12,PACALPPACA+LPPACASRR1(r13)
- ld r3,PACALPPACA+LPPACASRR0(r13)
- b .do_slb_miss
+ ld r3,PACALPPACA+LPPACASRR0(r13) /* get SRR0 value */
+ std r9,PACA_EXSLB+EX_R9(r13)
+ mfcr r9
+#ifdef __DISABLED__
+ cmpdi r3,0
+ bge .slb_miss_user_iseries
+#endif
+ std r10,PACA_EXSLB+EX_R10(r13)
+ std r11,PACA_EXSLB+EX_R11(r13)
+ std r12,PACA_EXSLB+EX_R12(r13)
+ mfspr r10,SPRN_SPRG1
+ std r10,PACA_EXSLB+EX_R13(r13)
+ ld r12,PACALPPACA+LPPACASRR1(r13);
+ b .slb_miss_realmode
+
+#ifdef __DISABLED__
+slb_miss_user_iseries:
+ std r10,PACA_EXGEN+EX_R10(r13)
+ std r11,PACA_EXGEN+EX_R11(r13)
+ std r12,PACA_EXGEN+EX_R12(r13)
+ mfspr r10,SPRG1
+ ld r11,PACA_EXSLB+EX_R9(r13)
+ ld r12,PACA_EXSLB+EX_R3(r13)
+ std r10,PACA_EXGEN+EX_R13(r13)
+ std r11,PACA_EXGEN+EX_R9(r13)
+ std r12,PACA_EXGEN+EX_R3(r13)
+ EXCEPTION_PROLOG_ISERIES_2
+ b slb_miss_user_common
+#endif
MASKABLE_EXCEPTION_ISERIES(0x500, hardware_interrupt)
STD_EXCEPTION_ISERIES(0x600, alignment, PACA_EXGEN)
@@ -586,7 +665,7 @@ instruction_access_slb_iSeries:
.globl system_call_iSeries
system_call_iSeries:
mr r9,r13
- mfspr r13,SPRG3
+ mfspr r13,SPRN_SPRG3
EXCEPTION_PROLOG_ISERIES_2
b system_call_common
@@ -596,7 +675,7 @@ system_call_iSeries:
.globl system_reset_iSeries
system_reset_iSeries:
- mfspr r13,SPRG3 /* Get paca address */
+ mfspr r13,SPRN_SPRG3 /* Get paca address */
mfmsr r24
ori r24,r24,MSR_RI
mtmsrd r24 /* RI on */
@@ -639,7 +718,7 @@ iSeries_secondary_smp_loop:
#endif /* CONFIG_SMP */
li r0,-1 /* r0=-1 indicates a Hypervisor call */
sc /* Invoke the hypervisor via a system call */
- mfspr r13,SPRG3 /* Put r13 back ???? */
+ mfspr r13,SPRN_SPRG3 /* Put r13 back ???? */
b 1b /* If SMP not configured, secondaries
* loop forever */
@@ -656,8 +735,8 @@ hardware_interrupt_iSeries_masked:
mtcrf 0x80,r9 /* Restore regs */
ld r11,PACALPPACA+LPPACASRR0(r13)
ld r12,PACALPPACA+LPPACASRR1(r13)
- mtspr SRR0,r11
- mtspr SRR1,r12
+ mtspr SPRN_SRR0,r11
+ mtspr SPRN_SRR1,r12
ld r9,PACA_EXGEN+EX_R9(r13)
ld r10,PACA_EXGEN+EX_R10(r13)
ld r11,PACA_EXGEN+EX_R11(r13)
@@ -713,8 +792,8 @@ bad_stack:
std r10,GPR1(r1)
std r11,_NIP(r1)
std r12,_MSR(r1)
- mfspr r11,DAR
- mfspr r12,DSISR
+ mfspr r11,SPRN_DAR
+ mfspr r12,SPRN_DSISR
std r11,_DAR(r1)
std r12,_DSISR(r1)
mflr r10
@@ -746,6 +825,7 @@ bad_stack:
* any task or sent any task a signal, you should use
* ret_from_except or ret_from_except_lite instead of this.
*/
+ .globl fast_exception_return
fast_exception_return:
ld r12,_MSR(r1)
ld r11,_NIP(r1)
@@ -766,8 +846,8 @@ fast_exception_return:
clrrdi r10,r10,2 /* clear RI (LE is 0 already) */
mtmsrd r10,1
- mtspr SRR1,r12
- mtspr SRR0,r11
+ mtspr SPRN_SRR1,r12
+ mtspr SPRN_SRR0,r11
REST_4GPRS(10, r1)
ld r1,GPR1(r1)
rfid
@@ -788,9 +868,9 @@ unrecov_fer:
.globl data_access_common
data_access_common:
RUNLATCH_ON(r10) /* It wont fit in the 0x300 handler */
- mfspr r10,DAR
+ mfspr r10,SPRN_DAR
std r10,PACA_EXGEN+EX_DAR(r13)
- mfspr r10,DSISR
+ mfspr r10,SPRN_DSISR
stw r10,PACA_EXGEN+EX_DSISR(r13)
EXCEPTION_PROLOG_COMMON(0x300, PACA_EXGEN)
ld r3,PACA_EXGEN+EX_DAR(r13)
@@ -807,6 +887,126 @@ instruction_access_common:
li r5,0x400
b .do_hash_page /* Try to handle as hpte fault */
+/*
+ * Here is the common SLB miss user that is used when going to virtual
+ * mode for SLB misses, that is currently not used
+ */
+#ifdef __DISABLED__
+ .align 7
+ .globl slb_miss_user_common
+slb_miss_user_common:
+ mflr r10
+ std r3,PACA_EXGEN+EX_DAR(r13)
+ stw r9,PACA_EXGEN+EX_CCR(r13)
+ std r10,PACA_EXGEN+EX_LR(r13)
+ std r11,PACA_EXGEN+EX_SRR0(r13)
+ bl .slb_allocate_user
+
+ ld r10,PACA_EXGEN+EX_LR(r13)
+ ld r3,PACA_EXGEN+EX_R3(r13)
+ lwz r9,PACA_EXGEN+EX_CCR(r13)
+ ld r11,PACA_EXGEN+EX_SRR0(r13)
+ mtlr r10
+ beq- slb_miss_fault
+
+ andi. r10,r12,MSR_RI /* check for unrecoverable exception */
+ beq- unrecov_user_slb
+ mfmsr r10
+
+.machine push
+.machine "power4"
+ mtcrf 0x80,r9
+.machine pop
+
+ clrrdi r10,r10,2 /* clear RI before setting SRR0/1 */
+ mtmsrd r10,1
+
+ mtspr SRR0,r11
+ mtspr SRR1,r12
+
+ ld r9,PACA_EXGEN+EX_R9(r13)
+ ld r10,PACA_EXGEN+EX_R10(r13)
+ ld r11,PACA_EXGEN+EX_R11(r13)
+ ld r12,PACA_EXGEN+EX_R12(r13)
+ ld r13,PACA_EXGEN+EX_R13(r13)
+ rfid
+ b .
+
+slb_miss_fault:
+ EXCEPTION_PROLOG_COMMON(0x380, PACA_EXGEN)
+ ld r4,PACA_EXGEN+EX_DAR(r13)
+ li r5,0
+ std r4,_DAR(r1)
+ std r5,_DSISR(r1)
+ b .handle_page_fault
+
+unrecov_user_slb:
+ EXCEPTION_PROLOG_COMMON(0x4200, PACA_EXGEN)
+ DISABLE_INTS
+ bl .save_nvgprs
+1: addi r3,r1,STACK_FRAME_OVERHEAD
+ bl .unrecoverable_exception
+ b 1b
+
+#endif /* __DISABLED__ */
+
+
+/*
+ * r13 points to the PACA, r9 contains the saved CR,
+ * r12 contain the saved SRR1, SRR0 is still ready for return
+ * r3 has the faulting address
+ * r9 - r13 are saved in paca->exslb.
+ * r3 is saved in paca->slb_r3
+ * We assume we aren't going to take any exceptions during this procedure.
+ */
+_GLOBAL(slb_miss_realmode)
+ mflr r10
+
+ stw r9,PACA_EXSLB+EX_CCR(r13) /* save CR in exc. frame */
+ std r10,PACA_EXSLB+EX_LR(r13) /* save LR */
+
+ bl .slb_allocate_realmode
+
+ /* All done -- return from exception. */
+
+ ld r10,PACA_EXSLB+EX_LR(r13)
+ ld r3,PACA_EXSLB+EX_R3(r13)
+ lwz r9,PACA_EXSLB+EX_CCR(r13) /* get saved CR */
+#ifdef CONFIG_PPC_ISERIES
+ ld r11,PACALPPACA+LPPACASRR0(r13) /* get SRR0 value */
+#endif /* CONFIG_PPC_ISERIES */
+
+ mtlr r10
+
+ andi. r10,r12,MSR_RI /* check for unrecoverable exception */
+ beq- unrecov_slb
+
+.machine push
+.machine "power4"
+ mtcrf 0x80,r9
+ mtcrf 0x01,r9 /* slb_allocate uses cr0 and cr7 */
+.machine pop
+
+#ifdef CONFIG_PPC_ISERIES
+ mtspr SPRN_SRR0,r11
+ mtspr SPRN_SRR1,r12
+#endif /* CONFIG_PPC_ISERIES */
+ ld r9,PACA_EXSLB+EX_R9(r13)
+ ld r10,PACA_EXSLB+EX_R10(r13)
+ ld r11,PACA_EXSLB+EX_R11(r13)
+ ld r12,PACA_EXSLB+EX_R12(r13)
+ ld r13,PACA_EXSLB+EX_R13(r13)
+ rfid
+ b . /* prevent speculative execution */
+
+unrecov_slb:
+ EXCEPTION_PROLOG_COMMON(0x4100, PACA_EXSLB)
+ DISABLE_INTS
+ bl .save_nvgprs
+1: addi r3,r1,STACK_FRAME_OVERHEAD
+ bl .unrecoverable_exception
+ b 1b
+
.align 7
.globl hardware_interrupt_common
.globl hardware_interrupt_entry
@@ -821,9 +1021,9 @@ hardware_interrupt_entry:
.align 7
.globl alignment_common
alignment_common:
- mfspr r10,DAR
+ mfspr r10,SPRN_DAR
std r10,PACA_EXGEN+EX_DAR(r13)
- mfspr r10,DSISR
+ mfspr r10,SPRN_DSISR
stw r10,PACA_EXGEN+EX_DSISR(r13)
EXCEPTION_PROLOG_COMMON(0x600, PACA_EXGEN)
ld r3,PACA_EXGEN+EX_DAR(r13)
@@ -857,62 +1057,6 @@ fp_unavailable_common:
bl .kernel_fp_unavailable_exception
BUG_OPCODE
-/*
- * load_up_fpu(unused, unused, tsk)
- * Disable FP for the task which had the FPU previously,
- * and save its floating-point registers in its thread_struct.
- * Enables the FPU for use in the kernel on return.
- * On SMP we know the fpu is free, since we give it up every
- * switch (ie, no lazy save of the FP registers).
- * On entry: r13 == 'current' && last_task_used_math != 'current'
- */
-_STATIC(load_up_fpu)
- mfmsr r5 /* grab the current MSR */
- ori r5,r5,MSR_FP
- mtmsrd r5 /* enable use of fpu now */
- isync
-/*
- * For SMP, we don't do lazy FPU switching because it just gets too
- * horrendously complex, especially when a task switches from one CPU
- * to another. Instead we call giveup_fpu in switch_to.
- *
- */
-#ifndef CONFIG_SMP
- ld r3,last_task_used_math@got(r2)
- ld r4,0(r3)
- cmpdi 0,r4,0
- beq 1f
- /* Save FP state to last_task_used_math's THREAD struct */
- addi r4,r4,THREAD
- SAVE_32FPRS(0, r4)
- mffs fr0
- stfd fr0,THREAD_FPSCR(r4)
- /* Disable FP for last_task_used_math */
- ld r5,PT_REGS(r4)
- ld r4,_MSR-STACK_FRAME_OVERHEAD(r5)
- li r6,MSR_FP|MSR_FE0|MSR_FE1
- andc r4,r4,r6
- std r4,_MSR-STACK_FRAME_OVERHEAD(r5)
-1:
-#endif /* CONFIG_SMP */
- /* enable use of FP after return */
- ld r4,PACACURRENT(r13)
- addi r5,r4,THREAD /* Get THREAD */
- ld r4,THREAD_FPEXC_MODE(r5)
- ori r12,r12,MSR_FP
- or r12,r12,r4
- std r12,_MSR(r1)
- lfd fr0,THREAD_FPSCR(r5)
- mtfsf 0xff,fr0
- REST_32FPRS(0, r5)
-#ifndef CONFIG_SMP
- /* Update last_task_used_math to 'current' */
- subi r4,r5,THREAD /* Back to 'current' */
- std r4,0(r3)
-#endif /* CONFIG_SMP */
- /* restore registers and return */
- b fast_exception_return
-
.align 7
.globl altivec_unavailable_common
altivec_unavailable_common:
@@ -1120,7 +1264,7 @@ _GLOBAL(do_stab_bolted)
/* Hash to the primary group */
ld r10,PACASTABVIRT(r13)
- mfspr r11,DAR
+ mfspr r11,SPRN_DAR
srdi r11,r11,28
rldimi r10,r11,7,52 /* r10 = first ste of the group */
@@ -1162,7 +1306,7 @@ _GLOBAL(do_stab_bolted)
2: std r9,8(r10) /* Store the vsid part of the ste */
eieio
- mfspr r11,DAR /* Get the new esid */
+ mfspr r11,SPRN_DAR /* Get the new esid */
clrrdi r11,r11,28 /* Permits a full 32b of ESID */
ori r11,r11,0x90 /* Turn on valid and kp */
std r11,0(r10) /* Put new entry back into the stab */
@@ -1182,56 +1326,8 @@ _GLOBAL(do_stab_bolted)
clrrdi r10,r10,2
mtmsrd r10,1
- mtspr SRR0,r11
- mtspr SRR1,r12
- ld r9,PACA_EXSLB+EX_R9(r13)
- ld r10,PACA_EXSLB+EX_R10(r13)
- ld r11,PACA_EXSLB+EX_R11(r13)
- ld r12,PACA_EXSLB+EX_R12(r13)
- ld r13,PACA_EXSLB+EX_R13(r13)
- rfid
- b . /* prevent speculative execution */
-
-/*
- * r13 points to the PACA, r9 contains the saved CR,
- * r11 and r12 contain the saved SRR0 and SRR1.
- * r3 has the faulting address
- * r9 - r13 are saved in paca->exslb.
- * r3 is saved in paca->slb_r3
- * We assume we aren't going to take any exceptions during this procedure.
- */
-_GLOBAL(do_slb_miss)
- mflr r10
-
- stw r9,PACA_EXSLB+EX_CCR(r13) /* save CR in exc. frame */
- std r10,PACA_EXSLB+EX_LR(r13) /* save LR */
-
- bl .slb_allocate /* handle it */
-
- /* All done -- return from exception. */
-
- ld r10,PACA_EXSLB+EX_LR(r13)
- ld r3,PACA_EXSLB+EX_R3(r13)
- lwz r9,PACA_EXSLB+EX_CCR(r13) /* get saved CR */
-#ifdef CONFIG_PPC_ISERIES
- ld r11,PACALPPACA+LPPACASRR0(r13) /* get SRR0 value */
-#endif /* CONFIG_PPC_ISERIES */
-
- mtlr r10
-
- andi. r10,r12,MSR_RI /* check for unrecoverable exception */
- beq- unrecov_slb
-
-.machine push
-.machine "power4"
- mtcrf 0x80,r9
- mtcrf 0x01,r9 /* slb_allocate uses cr0 and cr7 */
-.machine pop
-
-#ifdef CONFIG_PPC_ISERIES
- mtspr SRR0,r11
- mtspr SRR1,r12
-#endif /* CONFIG_PPC_ISERIES */
+ mtspr SPRN_SRR0,r11
+ mtspr SPRN_SRR1,r12
ld r9,PACA_EXSLB+EX_R9(r13)
ld r10,PACA_EXSLB+EX_R10(r13)
ld r11,PACA_EXSLB+EX_R11(r13)
@@ -1240,20 +1336,12 @@ _GLOBAL(do_slb_miss)
rfid
b . /* prevent speculative execution */
-unrecov_slb:
- EXCEPTION_PROLOG_COMMON(0x4100, PACA_EXSLB)
- DISABLE_INTS
- bl .save_nvgprs
-1: addi r3,r1,STACK_FRAME_OVERHEAD
- bl .unrecoverable_exception
- b 1b
-
/*
* Space for CPU0's segment table.
*
* On iSeries, the hypervisor must fill in at least one entry before
* we get control (with relocate on). The address is give to the hv
- * as a page number (see xLparMap in LparData.c), so this must be at a
+ * as a page number (see xLparMap in lpardata.c), so this must be at a
* fixed address (the linker can't compute (u64)&initial_stab >>
* PAGE_SHIFT).
*/
@@ -1316,7 +1404,7 @@ _GLOBAL(pSeries_secondary_smp_init)
mr r3,r24 /* not found, copy phys to r3 */
b .kexec_wait /* next kernel might do better */
-2: mtspr SPRG3,r13 /* Save vaddr of paca in SPRG3 */
+2: mtspr SPRN_SPRG3,r13 /* Save vaddr of paca in SPRG3 */
/* From now on, r24 is expected to be logical cpuid */
mr r24,r5
3: HMT_LOW
@@ -1364,6 +1452,7 @@ _STATIC(__start_initialization_iSeries)
addi r2,r2,0x4000
bl .iSeries_early_setup
+ bl .early_setup
/* relocation is on at this point */
@@ -1554,20 +1643,17 @@ copy_to_here:
.section ".text";
.align 2 ;
- .globl pmac_secondary_start_1
-pmac_secondary_start_1:
- li r24, 1
- b .pmac_secondary_start
-
- .globl pmac_secondary_start_2
-pmac_secondary_start_2:
- li r24, 2
- b .pmac_secondary_start
-
- .globl pmac_secondary_start_3
-pmac_secondary_start_3:
- li r24, 3
- b .pmac_secondary_start
+ .globl __secondary_start_pmac_0
+__secondary_start_pmac_0:
+ /* NB the entries for cpus 0, 1, 2 must each occupy 8 bytes. */
+ li r24,0
+ b 1f
+ li r24,1
+ b 1f
+ li r24,2
+ b 1f
+ li r24,3
+1:
_GLOBAL(pmac_secondary_start)
/* turn on 64-bit mode */
@@ -1586,7 +1672,7 @@ _GLOBAL(pmac_secondary_start)
LOADADDR(r4, paca) /* Get base vaddr of paca array */
mulli r13,r24,PACA_SIZE /* Calculate vaddr of right paca */
add r13,r13,r4 /* for this processor. */
- mtspr SPRG3,r13 /* Save vaddr of paca in SPRG3 */
+ mtspr SPRN_SPRG3,r13 /* Save vaddr of paca in SPRG3 */
/* Create a temp kernel stack for use before relocation is on. */
ld r1,PACAEMERGSP(r13)
@@ -1614,18 +1700,9 @@ _GLOBAL(__secondary_start)
HMT_MEDIUM /* Set thread priority to MEDIUM */
ld r2,PACATOC(r13)
- li r6,0
- stb r6,PACAPROCENABLED(r13)
-
-#ifndef CONFIG_PPC_ISERIES
- /* Initialize the page table pointer register. */
- LOADADDR(r6,_SDR1)
- ld r6,0(r6) /* get the value of _SDR1 */
- mtspr SDR1,r6 /* set the htab location */
-#endif
- /* Initialize the first segment table (or SLB) entry */
- ld r3,PACASTABVIRT(r13) /* get addr of segment table */
- bl .stab_initialize
+
+ /* Do early setup for that CPU */
+ bl .early_setup_secondary
/* Initialize the kernel stack. Just a repeat for iSeries. */
LOADADDR(r3,current_set)
@@ -1634,37 +1711,6 @@ _GLOBAL(__secondary_start)
addi r1,r1,THREAD_SIZE-STACK_FRAME_OVERHEAD
std r1,PACAKSAVE(r13)
- ld r3,PACASTABREAL(r13) /* get raddr of segment table */
- ori r4,r3,1 /* turn on valid bit */
-
-#ifdef CONFIG_PPC_ISERIES
- li r0,-1 /* hypervisor call */
- li r3,1
- sldi r3,r3,63 /* 0x8000000000000000 */
- ori r3,r3,4 /* 0x8000000000000004 */
- sc /* HvCall_setASR */
-#else
- /* set the ASR */
- ld r3,systemcfg@got(r2) /* r3 = ptr to systemcfg */
- ld r3,0(r3)
- lwz r3,PLATFORM(r3) /* r3 = platform flags */
- andi. r3,r3,PLATFORM_LPAR /* Test if bit 0 is set (LPAR bit) */
- beq 98f /* branch if result is 0 */
- mfspr r3,PVR
- srwi r3,r3,16
- cmpwi r3,0x37 /* SStar */
- beq 97f
- cmpwi r3,0x36 /* IStar */
- beq 97f
- cmpwi r3,0x34 /* Pulsar */
- bne 98f
-97: li r3,H_SET_ASR /* hcall = H_SET_ASR */
- HVSC /* Invoking hcall */
- b 99f
-98: /* !(rpa hypervisor) || !(star) */
- mtasr r4 /* set the stab location */
-99:
-#endif
li r7,0
mtlr r7
@@ -1674,8 +1720,8 @@ _GLOBAL(__secondary_start)
#ifdef DO_SOFT_DISABLE
ori r4,r4,MSR_EE
#endif
- mtspr SRR0,r3
- mtspr SRR1,r4
+ mtspr SPRN_SRR0,r3
+ mtspr SPRN_SRR1,r4
rfid
b . /* prevent speculative execution */
@@ -1737,7 +1783,7 @@ _STATIC(start_here_multiplatform)
#ifdef CONFIG_HMT
/* Start up the second thread on cpu 0 */
- mfspr r3,PVR
+ mfspr r3,SPRN_PVR
srwi r3,r3,16
cmpwi r3,0x34 /* Pulsar */
beq 90f
@@ -1797,7 +1843,7 @@ _STATIC(start_here_multiplatform)
mulli r13,r27,PACA_SIZE /* Calculate vaddr of right paca */
add r13,r13,r24 /* for this processor. */
sub r13,r13,r26 /* convert to physical addr */
- mtspr SPRG3,r13 /* PPPBBB: Temp... -Peter */
+ mtspr SPRN_SPRG3,r13 /* PPPBBB: Temp... -Peter */
/* Do very early kernel initializations, including initial hash table,
* stab and slb setup before we turn on relocation. */
@@ -1806,44 +1852,10 @@ _STATIC(start_here_multiplatform)
mr r3,r31
bl .early_setup
- /* set the ASR */
- ld r3,PACASTABREAL(r13)
- ori r4,r3,1 /* turn on valid bit */
- ld r3,systemcfg@got(r2) /* r3 = ptr to systemcfg */
- ld r3,0(r3)
- lwz r3,PLATFORM(r3) /* r3 = platform flags */
- andi. r3,r3,PLATFORM_LPAR /* Test if bit 0 is set (LPAR bit) */
- beq 98f /* branch if result is 0 */
- mfspr r3,PVR
- srwi r3,r3,16
- cmpwi r3,0x37 /* SStar */
- beq 97f
- cmpwi r3,0x36 /* IStar */
- beq 97f
- cmpwi r3,0x34 /* Pulsar */
- bne 98f
-97: li r3,H_SET_ASR /* hcall = H_SET_ASR */
- HVSC /* Invoking hcall */
- b 99f
-98: /* !(rpa hypervisor) || !(star) */
- mtasr r4 /* set the stab location */
-99:
- /* Set SDR1 (hash table pointer) */
- ld r3,systemcfg@got(r2) /* r3 = ptr to systemcfg */
- ld r3,0(r3)
- lwz r3,PLATFORM(r3) /* r3 = platform flags */
- /* Test if bit 0 is set (LPAR bit) */
- andi. r3,r3,PLATFORM_LPAR
- bne 98f /* branch if result is !0 */
- LOADADDR(r6,_SDR1) /* Only if NOT LPAR */
- sub r6,r6,r26
- ld r6,0(r6) /* get the value of _SDR1 */
- mtspr SDR1,r6 /* set the htab location */
-98:
LOADADDR(r3,.start_here_common)
SET_REG_TO_CONST(r4, MSR_KERNEL)
- mtspr SRR0,r3
- mtspr SRR1,r4
+ mtspr SPRN_SRR0,r3
+ mtspr SPRN_SRR1,r4
rfid
b . /* prevent speculative execution */
#endif /* CONFIG_PPC_MULTIPLATFORM */
@@ -1874,7 +1886,7 @@ _STATIC(start_here_common)
LOADADDR(r24, paca) /* Get base vaddr of paca array */
mulli r13,r26,PACA_SIZE /* Calculate vaddr of right paca */
add r13,r13,r24 /* for this processor. */
- mtspr SPRG3,r13
+ mtspr SPRN_SPRG3,r13
/* ptr to current */
LOADADDR(r4,init_task)
@@ -1901,7 +1913,7 @@ _STATIC(start_here_common)
_GLOBAL(hmt_init)
#ifdef CONFIG_HMT
LOADADDR(r5, hmt_thread_data)
- mfspr r7,PVR
+ mfspr r7,SPRN_PVR
srwi r7,r7,16
cmpwi r7,0x34 /* Pulsar */
beq 90f
@@ -1910,10 +1922,10 @@ _GLOBAL(hmt_init)
cmpwi r7,0x37 /* SStar */
beq 91f
b 101f
-90: mfspr r6,PIR
+90: mfspr r6,SPRN_PIR
andi. r6,r6,0x1f
b 92f
-91: mfspr r6,PIR
+91: mfspr r6,SPRN_PIR
andi. r6,r6,0x3ff
92: sldi r4,r24,3
stwx r6,r5,r4
@@ -1924,8 +1936,8 @@ __hmt_secondary_hold:
LOADADDR(r5, hmt_thread_data)
clrldi r5,r5,4
li r7,0
- mfspr r6,PIR
- mfspr r8,PVR
+ mfspr r6,SPRN_PIR
+ mfspr r8,SPRN_PVR
srwi r8,r8,16
cmpwi r8,0x34
bne 93f
@@ -1951,48 +1963,32 @@ __hmt_secondary_hold:
_GLOBAL(hmt_start_secondary)
LOADADDR(r4,__hmt_secondary_hold)
clrldi r4,r4,4
- mtspr NIADORM, r4
- mfspr r4, MSRDORM
+ mtspr SPRN_NIADORM, r4
+ mfspr r4, SPRN_MSRDORM
li r5, -65
and r4, r4, r5
- mtspr MSRDORM, r4
+ mtspr SPRN_MSRDORM, r4
lis r4,0xffef
ori r4,r4,0x7403
- mtspr TSC, r4
+ mtspr SPRN_TSC, r4
li r4,0x1f4
- mtspr TST, r4
- mfspr r4, HID0
+ mtspr SPRN_TST, r4
+ mfspr r4, SPRN_HID0
ori r4, r4, 0x1
- mtspr HID0, r4
+ mtspr SPRN_HID0, r4
mfspr r4, SPRN_CTRLF
oris r4, r4, 0x40
mtspr SPRN_CTRLT, r4
blr
#endif
-#if defined(CONFIG_KEXEC) || (defined(CONFIG_SMP) && !defined(CONFIG_PPC_ISERIES))
-_GLOBAL(smp_release_cpus)
- /* All secondary cpus are spinning on a common
- * spinloop, release them all now so they can start
- * to spin on their individual paca spinloops.
- * For non SMP kernels, the secondary cpus never
- * get out of the common spinloop.
- */
- li r3,1
- LOADADDR(r5,__secondary_hold_spinloop)
- std r3,0(r5)
- sync
- blr
-#endif /* CONFIG_SMP && !CONFIG_PPC_ISERIES */
-
-
/*
* We put a few things here that have to be page-aligned.
* This stuff goes at the beginning of the bss, which is page-aligned.
*/
.section ".bss"
- .align 12
+ .align PAGE_SHIFT
.globl empty_zero_page
empty_zero_page:
diff --git a/arch/ppc64/kernel/hvcserver.c b/arch/ppc64/kernel/hvcserver.c
index bde8f42da854..4d584172055a 100644
--- a/arch/ppc64/kernel/hvcserver.c
+++ b/arch/ppc64/kernel/hvcserver.c
@@ -22,6 +22,8 @@
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/module.h>
+#include <linux/slab.h>
+
#include <asm/hvcall.h>
#include <asm/hvcserver.h>
#include <asm/io.h>
diff --git a/arch/ppc64/kernel/i8259.c b/arch/ppc64/kernel/i8259.c
deleted file mode 100644
index 74dcfd68fc75..000000000000
--- a/arch/ppc64/kernel/i8259.c
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- * c 2001 PPC64 Team, IBM Corp
- *
- * 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/stddef.h>
-#include <linux/init.h>
-#include <linux/sched.h>
-#include <linux/signal.h>
-#include <linux/cache.h>
-#include <linux/irq.h>
-#include <linux/interrupt.h>
-#include <asm/io.h>
-#include <asm/ppcdebug.h>
-#include "i8259.h"
-
-unsigned char cached_8259[2] = { 0xff, 0xff };
-#define cached_A1 (cached_8259[0])
-#define cached_21 (cached_8259[1])
-
-static __cacheline_aligned_in_smp DEFINE_SPINLOCK(i8259_lock);
-
-static int i8259_pic_irq_offset;
-static int i8259_present;
-
-int i8259_irq(int cpu)
-{
- int irq;
-
- spin_lock/*_irqsave*/(&i8259_lock/*, flags*/);
- /*
- * Perform an interrupt acknowledge cycle on controller 1
- */
- outb(0x0C, 0x20);
- irq = inb(0x20) & 7;
- if (irq == 2)
- {
- /*
- * Interrupt is cascaded so perform interrupt
- * acknowledge on controller 2
- */
- outb(0x0C, 0xA0);
- irq = (inb(0xA0) & 7) + 8;
- }
- else if (irq==7)
- {
- /*
- * This may be a spurious interrupt
- *
- * Read the interrupt status register. If the most
- * significant bit is not set then there is no valid
- * interrupt
- */
- outb(0x0b, 0x20);
- if(~inb(0x20)&0x80) {
- spin_unlock/*_irqrestore*/(&i8259_lock/*, flags*/);
- return -1;
- }
- }
- spin_unlock/*_irqrestore*/(&i8259_lock/*, flags*/);
- return irq;
-}
-
-static void i8259_mask_and_ack_irq(unsigned int irq_nr)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&i8259_lock, flags);
- if ( irq_nr >= i8259_pic_irq_offset )
- irq_nr -= i8259_pic_irq_offset;
-
- if (irq_nr > 7) {
- cached_A1 |= 1 << (irq_nr-8);
- inb(0xA1); /* DUMMY */
- outb(cached_A1,0xA1);
- outb(0x20,0xA0); /* Non-specific EOI */
- outb(0x20,0x20); /* Non-specific EOI to cascade */
- } else {
- cached_21 |= 1 << irq_nr;
- inb(0x21); /* DUMMY */
- outb(cached_21,0x21);
- outb(0x20,0x20); /* Non-specific EOI */
- }
- spin_unlock_irqrestore(&i8259_lock, flags);
-}
-
-static void i8259_set_irq_mask(int irq_nr)
-{
- outb(cached_A1,0xA1);
- outb(cached_21,0x21);
-}
-
-static void i8259_mask_irq(unsigned int irq_nr)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&i8259_lock, flags);
- if ( irq_nr >= i8259_pic_irq_offset )
- irq_nr -= i8259_pic_irq_offset;
- if ( irq_nr < 8 )
- cached_21 |= 1 << irq_nr;
- else
- cached_A1 |= 1 << (irq_nr-8);
- i8259_set_irq_mask(irq_nr);
- spin_unlock_irqrestore(&i8259_lock, flags);
-}
-
-static void i8259_unmask_irq(unsigned int irq_nr)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&i8259_lock, flags);
- if ( irq_nr >= i8259_pic_irq_offset )
- irq_nr -= i8259_pic_irq_offset;
- if ( irq_nr < 8 )
- cached_21 &= ~(1 << irq_nr);
- else
- cached_A1 &= ~(1 << (irq_nr-8));
- i8259_set_irq_mask(irq_nr);
- spin_unlock_irqrestore(&i8259_lock, flags);
-}
-
-static void i8259_end_irq(unsigned int irq)
-{
- if (!(get_irq_desc(irq)->status & (IRQ_DISABLED|IRQ_INPROGRESS)) &&
- get_irq_desc(irq)->action)
- i8259_unmask_irq(irq);
-}
-
-struct hw_interrupt_type i8259_pic = {
- .typename = " i8259 ",
- .enable = i8259_unmask_irq,
- .disable = i8259_mask_irq,
- .ack = i8259_mask_and_ack_irq,
- .end = i8259_end_irq,
-};
-
-void __init i8259_init(int offset)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&i8259_lock, flags);
- i8259_pic_irq_offset = offset;
- i8259_present = 1;
- /* init master interrupt controller */
- outb(0x11, 0x20); /* Start init sequence */
- outb(0x00, 0x21); /* Vector base */
- outb(0x04, 0x21); /* edge tiggered, Cascade (slave) on IRQ2 */
- outb(0x01, 0x21); /* Select 8086 mode */
- outb(0xFF, 0x21); /* Mask all */
- /* init slave interrupt controller */
- outb(0x11, 0xA0); /* Start init sequence */
- outb(0x08, 0xA1); /* Vector base */
- outb(0x02, 0xA1); /* edge triggered, Cascade (slave) on IRQ2 */
- outb(0x01, 0xA1); /* Select 8086 mode */
- outb(0xFF, 0xA1); /* Mask all */
- outb(cached_A1, 0xA1);
- outb(cached_21, 0x21);
- spin_unlock_irqrestore(&i8259_lock, flags);
-
-}
-
-static int i8259_request_cascade(void)
-{
- if (!i8259_present)
- return -ENODEV;
-
- request_irq( i8259_pic_irq_offset + 2, no_action, SA_INTERRUPT,
- "82c59 secondary cascade", NULL );
-
- return 0;
-}
-
-arch_initcall(i8259_request_cascade);
diff --git a/arch/ppc64/kernel/i8259.h b/arch/ppc64/kernel/i8259.h
deleted file mode 100644
index f74764ba0bfa..000000000000
--- a/arch/ppc64/kernel/i8259.h
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
- * c 2001 PPC 64 Team, IBM Corp
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-#ifndef _PPC_KERNEL_i8259_H
-#define _PPC_KERNEL_i8259_H
-
-extern struct hw_interrupt_type i8259_pic;
-
-extern void i8259_init(int offset);
-extern int i8259_irq(int);
-
-#endif /* _PPC_KERNEL_i8259_H */
diff --git a/arch/ppc64/kernel/idle.c b/arch/ppc64/kernel/idle.c
index 954395d42636..b879d3057ef8 100644
--- a/arch/ppc64/kernel/idle.c
+++ b/arch/ppc64/kernel/idle.c
@@ -26,22 +26,18 @@
#include <asm/processor.h>
#include <asm/cputable.h>
#include <asm/time.h>
-#include <asm/systemcfg.h>
#include <asm/machdep.h>
+#include <asm/smp.h>
extern void power4_idle(void);
-int default_idle(void)
+void default_idle(void)
{
- long oldval;
unsigned int cpu = smp_processor_id();
+ set_thread_flag(TIF_POLLING_NRFLAG);
while (1) {
- oldval = test_and_clear_thread_flag(TIF_NEED_RESCHED);
-
- if (!oldval) {
- set_thread_flag(TIF_POLLING_NRFLAG);
-
+ if (!need_resched()) {
while (!need_resched() && !cpu_is_offline(cpu)) {
ppc64_runlatch_off();
@@ -54,21 +50,18 @@ int default_idle(void)
}
HMT_medium();
- clear_thread_flag(TIF_POLLING_NRFLAG);
- } else {
- set_need_resched();
}
ppc64_runlatch_on();
+ preempt_enable_no_resched();
schedule();
+ preempt_disable();
if (cpu_is_offline(cpu) && system_state == SYSTEM_RUNNING)
cpu_die();
}
-
- return 0;
}
-int native_idle(void)
+void native_idle(void)
{
while (1) {
ppc64_runlatch_off();
@@ -78,15 +71,15 @@ int native_idle(void)
if (need_resched()) {
ppc64_runlatch_on();
+ preempt_enable_no_resched();
schedule();
+ preempt_disable();
}
if (cpu_is_offline(smp_processor_id()) &&
system_state == SYSTEM_RUNNING)
cpu_die();
}
-
- return 0;
}
void cpu_idle(void)
diff --git a/arch/ppc64/kernel/kprobes.c b/arch/ppc64/kernel/kprobes.c
index 9c6facc24f70..511af54e6230 100644
--- a/arch/ppc64/kernel/kprobes.c
+++ b/arch/ppc64/kernel/kprobes.c
@@ -30,19 +30,14 @@
#include <linux/config.h>
#include <linux/kprobes.h>
#include <linux/ptrace.h>
-#include <linux/spinlock.h>
#include <linux/preempt.h>
#include <asm/cacheflush.h>
#include <asm/kdebug.h>
#include <asm/sstep.h>
static DECLARE_MUTEX(kprobe_mutex);
-
-static struct kprobe *current_kprobe;
-static unsigned long kprobe_status, kprobe_saved_msr;
-static struct kprobe *kprobe_prev;
-static unsigned long kprobe_status_prev, kprobe_saved_msr_prev;
-static struct pt_regs jprobe_saved_regs;
+DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
+DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
int __kprobes arch_prepare_kprobe(struct kprobe *p)
{
@@ -108,20 +103,28 @@ static inline void prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
regs->nip = (unsigned long)p->ainsn.insn;
}
-static inline void save_previous_kprobe(void)
+static inline void save_previous_kprobe(struct kprobe_ctlblk *kcb)
+{
+ kcb->prev_kprobe.kp = kprobe_running();
+ kcb->prev_kprobe.status = kcb->kprobe_status;
+ kcb->prev_kprobe.saved_msr = kcb->kprobe_saved_msr;
+}
+
+static inline void restore_previous_kprobe(struct kprobe_ctlblk *kcb)
{
- kprobe_prev = current_kprobe;
- kprobe_status_prev = kprobe_status;
- kprobe_saved_msr_prev = kprobe_saved_msr;
+ __get_cpu_var(current_kprobe) = kcb->prev_kprobe.kp;
+ kcb->kprobe_status = kcb->prev_kprobe.status;
+ kcb->kprobe_saved_msr = kcb->prev_kprobe.saved_msr;
}
-static inline void restore_previous_kprobe(void)
+static inline void set_current_kprobe(struct kprobe *p, struct pt_regs *regs,
+ struct kprobe_ctlblk *kcb)
{
- current_kprobe = kprobe_prev;
- kprobe_status = kprobe_status_prev;
- kprobe_saved_msr = kprobe_saved_msr_prev;
+ __get_cpu_var(current_kprobe) = p;
+ kcb->kprobe_saved_msr = regs->msr;
}
+/* Called with kretprobe_lock held */
void __kprobes arch_prepare_kretprobe(struct kretprobe *rp,
struct pt_regs *regs)
{
@@ -145,19 +148,24 @@ static inline int kprobe_handler(struct pt_regs *regs)
struct kprobe *p;
int ret = 0;
unsigned int *addr = (unsigned int *)regs->nip;
+ struct kprobe_ctlblk *kcb;
+
+ /*
+ * We don't want to be preempted for the entire
+ * duration of kprobe processing
+ */
+ preempt_disable();
+ kcb = get_kprobe_ctlblk();
/* Check we're not actually recursing */
if (kprobe_running()) {
- /* We *are* holding lock here, so this is safe.
- Disarm the probe we just hit, and ignore it. */
p = get_kprobe(addr);
if (p) {
kprobe_opcode_t insn = *p->ainsn.insn;
- if (kprobe_status == KPROBE_HIT_SS &&
+ if (kcb->kprobe_status == KPROBE_HIT_SS &&
is_trap(insn)) {
regs->msr &= ~MSR_SE;
- regs->msr |= kprobe_saved_msr;
- unlock_kprobes();
+ regs->msr |= kcb->kprobe_saved_msr;
goto no_kprobe;
}
/* We have reentered the kprobe_handler(), since
@@ -166,27 +174,24 @@ static inline int kprobe_handler(struct pt_regs *regs)
* just single step on the instruction of the new probe
* without calling any user handlers.
*/
- save_previous_kprobe();
- current_kprobe = p;
- kprobe_saved_msr = regs->msr;
+ save_previous_kprobe(kcb);
+ set_current_kprobe(p, regs, kcb);
+ kcb->kprobe_saved_msr = regs->msr;
p->nmissed++;
prepare_singlestep(p, regs);
- kprobe_status = KPROBE_REENTER;
+ kcb->kprobe_status = KPROBE_REENTER;
return 1;
} else {
- p = current_kprobe;
+ p = __get_cpu_var(current_kprobe);
if (p->break_handler && p->break_handler(p, regs)) {
goto ss_probe;
}
}
- /* If it's not ours, can't be delete race, (we hold lock). */
goto no_kprobe;
}
- lock_kprobes();
p = get_kprobe(addr);
if (!p) {
- unlock_kprobes();
if (*addr != BREAKPOINT_INSTRUCTION) {
/*
* PowerPC has multiple variants of the "trap"
@@ -209,24 +214,19 @@ static inline int kprobe_handler(struct pt_regs *regs)
goto no_kprobe;
}
- kprobe_status = KPROBE_HIT_ACTIVE;
- current_kprobe = p;
- kprobe_saved_msr = regs->msr;
+ kcb->kprobe_status = KPROBE_HIT_ACTIVE;
+ set_current_kprobe(p, regs, kcb);
if (p->pre_handler && p->pre_handler(p, regs))
/* handler has already set things up, so skip ss setup */
return 1;
ss_probe:
prepare_singlestep(p, regs);
- kprobe_status = KPROBE_HIT_SS;
- /*
- * This preempt_disable() matches the preempt_enable_no_resched()
- * in post_kprobe_handler().
- */
- preempt_disable();
+ kcb->kprobe_status = KPROBE_HIT_SS;
return 1;
no_kprobe:
+ preempt_enable_no_resched();
return ret;
}
@@ -251,9 +251,10 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
struct kretprobe_instance *ri = NULL;
struct hlist_head *head;
struct hlist_node *node, *tmp;
- unsigned long orig_ret_address = 0;
+ unsigned long flags, orig_ret_address = 0;
unsigned long trampoline_address =(unsigned long)&kretprobe_trampoline;
+ spin_lock_irqsave(&kretprobe_lock, flags);
head = kretprobe_inst_table_head(current);
/*
@@ -292,12 +293,14 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
BUG_ON(!orig_ret_address || (orig_ret_address == trampoline_address));
regs->nip = orig_ret_address;
- unlock_kprobes();
+ reset_current_kprobe();
+ spin_unlock_irqrestore(&kretprobe_lock, flags);
+ preempt_enable_no_resched();
/*
* By returning a non-zero value, we are telling
- * kprobe_handler() that we have handled unlocking
- * and re-enabling preemption.
+ * kprobe_handler() that we don't want the post_handler
+ * to run (and have re-enabled preemption)
*/
return 1;
}
@@ -323,23 +326,26 @@ static void __kprobes resume_execution(struct kprobe *p, struct pt_regs *regs)
static inline int post_kprobe_handler(struct pt_regs *regs)
{
- if (!kprobe_running())
+ struct kprobe *cur = kprobe_running();
+ struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
+
+ if (!cur)
return 0;
- if ((kprobe_status != KPROBE_REENTER) && current_kprobe->post_handler) {
- kprobe_status = KPROBE_HIT_SSDONE;
- current_kprobe->post_handler(current_kprobe, regs, 0);
+ if ((kcb->kprobe_status != KPROBE_REENTER) && cur->post_handler) {
+ kcb->kprobe_status = KPROBE_HIT_SSDONE;
+ cur->post_handler(cur, regs, 0);
}
- resume_execution(current_kprobe, regs);
- regs->msr |= kprobe_saved_msr;
+ resume_execution(cur, regs);
+ regs->msr |= kcb->kprobe_saved_msr;
/*Restore back the original saved kprobes variables and continue. */
- if (kprobe_status == KPROBE_REENTER) {
- restore_previous_kprobe();
+ if (kcb->kprobe_status == KPROBE_REENTER) {
+ restore_previous_kprobe(kcb);
goto out;
}
- unlock_kprobes();
+ reset_current_kprobe();
out:
preempt_enable_no_resched();
@@ -354,19 +360,20 @@ out:
return 1;
}
-/* Interrupts disabled, kprobe_lock held. */
static inline int kprobe_fault_handler(struct pt_regs *regs, int trapnr)
{
- if (current_kprobe->fault_handler
- && current_kprobe->fault_handler(current_kprobe, regs, trapnr))
+ struct kprobe *cur = kprobe_running();
+ struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
+
+ if (cur->fault_handler && cur->fault_handler(cur, regs, trapnr))
return 1;
- if (kprobe_status & KPROBE_HIT_SS) {
- resume_execution(current_kprobe, regs);
+ if (kcb->kprobe_status & KPROBE_HIT_SS) {
+ resume_execution(cur, regs);
regs->msr &= ~MSR_SE;
- regs->msr |= kprobe_saved_msr;
+ regs->msr |= kcb->kprobe_saved_msr;
- unlock_kprobes();
+ reset_current_kprobe();
preempt_enable_no_resched();
}
return 0;
@@ -381,11 +388,6 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
struct die_args *args = (struct die_args *)data;
int ret = NOTIFY_DONE;
- /*
- * Interrupts are not disabled here. We need to disable
- * preemption, because kprobe_running() uses smp_processor_id().
- */
- preempt_disable();
switch (val) {
case DIE_BPT:
if (kprobe_handler(args->regs))
@@ -395,24 +397,26 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
if (post_kprobe_handler(args->regs))
ret = NOTIFY_STOP;
break;
- case DIE_GPF:
case DIE_PAGE_FAULT:
+ /* kprobe_running() needs smp_processor_id() */
+ preempt_disable();
if (kprobe_running() &&
kprobe_fault_handler(args->regs, args->trapnr))
ret = NOTIFY_STOP;
+ preempt_enable();
break;
default:
break;
}
- preempt_enable_no_resched();
return ret;
}
int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
{
struct jprobe *jp = container_of(p, struct jprobe, kp);
+ struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
- memcpy(&jprobe_saved_regs, regs, sizeof(struct pt_regs));
+ memcpy(&kcb->jprobe_saved_regs, regs, sizeof(struct pt_regs));
/* setup return addr to the jprobe handler routine */
regs->nip = (unsigned long)(((func_descr_t *)jp->entry)->entry);
@@ -432,12 +436,15 @@ void __kprobes jprobe_return_end(void)
int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
{
+ struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
+
/*
* FIXME - we should ideally be validating that we got here 'cos
* of the "trap" in jprobe_return() above, before restoring the
* saved regs...
*/
- memcpy(regs, &jprobe_saved_regs, sizeof(struct pt_regs));
+ memcpy(regs, &kcb->jprobe_saved_regs, sizeof(struct pt_regs));
+ preempt_enable_no_resched();
return 1;
}
diff --git a/arch/ppc64/kernel/machine_kexec.c b/arch/ppc64/kernel/machine_kexec.c
index bf7cc4f8210f..07ea03598c00 100644
--- a/arch/ppc64/kernel/machine_kexec.c
+++ b/arch/ppc64/kernel/machine_kexec.c
@@ -24,6 +24,7 @@
#include <asm/mmu.h>
#include <asm/sections.h> /* _end */
#include <asm/prom.h>
+#include <asm/smp.h>
#define HASH_GROUP_SIZE 0x80 /* size of each hash group, asm/mmu.h */
@@ -244,7 +245,6 @@ static void kexec_prepare_cpus(void)
static void kexec_prepare_cpus(void)
{
- extern void smp_release_cpus(void);
/*
* move the secondarys to us so that we can copy
* the new kernel 0-0x100 safely
diff --git a/arch/ppc64/kernel/misc.S b/arch/ppc64/kernel/misc.S
index e7241ad80a08..492bca6137eb 100644
--- a/arch/ppc64/kernel/misc.S
+++ b/arch/ppc64/kernel/misc.S
@@ -28,6 +28,7 @@
#include <asm/ppc_asm.h>
#include <asm/asm-offsets.h>
#include <asm/cputable.h>
+#include <asm/thread_info.h>
.text
@@ -64,44 +65,6 @@ _GLOBAL(get_srr1)
_GLOBAL(get_sp)
mr r3,r1
blr
-
-#ifdef CONFIG_PPC_ISERIES
-/* unsigned long local_save_flags(void) */
-_GLOBAL(local_get_flags)
- lbz r3,PACAPROCENABLED(r13)
- blr
-
-/* unsigned long local_irq_disable(void) */
-_GLOBAL(local_irq_disable)
- lbz r3,PACAPROCENABLED(r13)
- li r4,0
- stb r4,PACAPROCENABLED(r13)
- blr /* Done */
-
-/* void local_irq_restore(unsigned long flags) */
-_GLOBAL(local_irq_restore)
- lbz r5,PACAPROCENABLED(r13)
- /* Check if things are setup the way we want _already_. */
- cmpw 0,r3,r5
- beqlr
- /* are we enabling interrupts? */
- cmpdi 0,r3,0
- stb r3,PACAPROCENABLED(r13)
- beqlr
- /* Check pending interrupts */
- /* A decrementer, IPI or PMC interrupt may have occurred
- * while we were in the hypervisor (which enables) */
- ld r4,PACALPPACA+LPPACAANYINT(r13)
- cmpdi r4,0
- beqlr
-
- /*
- * Handle pending interrupts in interrupt context
- */
- li r0,0x5555
- sc
- blr
-#endif /* CONFIG_PPC_ISERIES */
#ifdef CONFIG_IRQSTACKS
_GLOBAL(call_do_softirq)
@@ -115,12 +78,12 @@ _GLOBAL(call_do_softirq)
mtlr r0
blr
-_GLOBAL(call_handle_IRQ_event)
+_GLOBAL(call___do_IRQ)
mflr r0
std r0,16(r1)
- stdu r1,THREAD_SIZE-112(r6)
- mr r1,r6
- bl .handle_IRQ_event
+ stdu r1,THREAD_SIZE-112(r5)
+ mr r1,r5
+ bl .__do_IRQ
ld r1,0(r1)
ld r0,16(r1)
mtlr r0
@@ -329,7 +292,7 @@ _GLOBAL(__flush_dcache_icache)
/* Flush the dcache */
ld r7,PPC64_CACHES@toc(r2)
- clrrdi r3,r3,12 /* Page align */
+ clrrdi r3,r3,PAGE_SHIFT /* Page align */
lwz r4,DCACHEL1LINESPERPAGE(r7) /* Get # dcache lines per page */
lwz r5,DCACHEL1LINESIZE(r7) /* Get dcache line size */
mr r6,r3
@@ -488,25 +451,6 @@ _GLOBAL(_outsl_ns)
sync
blr
-
-_GLOBAL(cvt_fd)
- lfd 0,0(r5) /* load up fpscr value */
- mtfsf 0xff,0
- lfs 0,0(r3)
- stfd 0,0(r4)
- mffs 0 /* save new fpscr value */
- stfd 0,0(r5)
- blr
-
-_GLOBAL(cvt_df)
- lfd 0,0(r5) /* load up fpscr value */
- mtfsf 0xff,0
- lfd 0,0(r3)
- stfs 0,0(r4)
- mffs 0 /* save new fpscr value */
- stfd 0,0(r5)
- blr
-
/*
* identify_cpu and calls setup_cpu
* In: r3 = base of the cpu_specs array
@@ -616,7 +560,7 @@ _GLOBAL(real_readb)
isync
blr
- /*
+/*
* Do an IO access in real mode
*/
_GLOBAL(real_writeb)
@@ -649,6 +593,76 @@ _GLOBAL(real_writeb)
#endif /* defined(CONFIG_PPC_PMAC) || defined(CONFIG_PPC_MAPLE) */
/*
+ * SCOM access functions for 970 (FX only for now)
+ *
+ * unsigned long scom970_read(unsigned int address);
+ * void scom970_write(unsigned int address, unsigned long value);
+ *
+ * The address passed in is the 24 bits register address. This code
+ * is 970 specific and will not check the status bits, so you should
+ * know what you are doing.
+ */
+_GLOBAL(scom970_read)
+ /* interrupts off */
+ mfmsr r4
+ ori r0,r4,MSR_EE
+ xori r0,r0,MSR_EE
+ mtmsrd r0,1
+
+ /* rotate 24 bits SCOM address 8 bits left and mask out it's low 8 bits
+ * (including parity). On current CPUs they must be 0'd,
+ * and finally or in RW bit
+ */
+ rlwinm r3,r3,8,0,15
+ ori r3,r3,0x8000
+
+ /* do the actual scom read */
+ sync
+ mtspr SPRN_SCOMC,r3
+ isync
+ mfspr r3,SPRN_SCOMD
+ isync
+ mfspr r0,SPRN_SCOMC
+ isync
+
+ /* XXX: fixup result on some buggy 970's (ouch ! we lost a bit, bah
+ * that's the best we can do). Not implemented yet as we don't use
+ * the scom on any of the bogus CPUs yet, but may have to be done
+ * ultimately
+ */
+
+ /* restore interrupts */
+ mtmsrd r4,1
+ blr
+
+
+_GLOBAL(scom970_write)
+ /* interrupts off */
+ mfmsr r5
+ ori r0,r5,MSR_EE
+ xori r0,r0,MSR_EE
+ mtmsrd r0,1
+
+ /* rotate 24 bits SCOM address 8 bits left and mask out it's low 8 bits
+ * (including parity). On current CPUs they must be 0'd.
+ */
+
+ rlwinm r3,r3,8,0,15
+
+ sync
+ mtspr SPRN_SCOMD,r4 /* write data */
+ isync
+ mtspr SPRN_SCOMC,r3 /* write command */
+ isync
+ mfspr 3,SPRN_SCOMC
+ isync
+
+ /* restore interrupts */
+ mtmsrd r5,1
+ blr
+
+
+/*
* Create a kernel thread
* kernel_thread(fn, arg, flags)
*/
@@ -692,38 +706,6 @@ _GLOBAL(disable_kernel_fp)
isync
blr
-/*
- * giveup_fpu(tsk)
- * Disable FP for the task given as the argument,
- * and save the floating-point registers in its thread_struct.
- * Enables the FPU for use in the kernel on return.
- */
-_GLOBAL(giveup_fpu)
- mfmsr r5
- ori r5,r5,MSR_FP
- mtmsrd r5 /* enable use of fpu now */
- isync
- cmpdi 0,r3,0
- beqlr- /* if no previous owner, done */
- addi r3,r3,THREAD /* want THREAD of task */
- ld r5,PT_REGS(r3)
- cmpdi 0,r5,0
- SAVE_32FPRS(0, r3)
- mffs fr0
- stfd fr0,THREAD_FPSCR(r3)
- beq 1f
- ld r4,_MSR-STACK_FRAME_OVERHEAD(r5)
- li r3,MSR_FP|MSR_FE0|MSR_FE1
- andc r4,r4,r3 /* disable FP for previous task */
- std r4,_MSR-STACK_FRAME_OVERHEAD(r5)
-1:
-#ifndef CONFIG_SMP
- li r5,0
- ld r4,last_task_used_math@got(r2)
- std r5,0(r4)
-#endif /* CONFIG_SMP */
- blr
-
#ifdef CONFIG_ALTIVEC
#if 0 /* this has no callers for now */
@@ -778,6 +760,13 @@ _GLOBAL(giveup_altivec)
_GLOBAL(__setup_cpu_power3)
blr
+_GLOBAL(execve)
+ li r0,__NR_execve
+ sc
+ bnslr
+ neg r3,r3
+ blr
+
/* kexec_wait(phys_cpu)
*
* wait for the flag to change, indicating this kernel is going away but
@@ -948,566 +937,3 @@ _GLOBAL(kexec_sequence)
li r5,0
blr /* image->start(physid, image->start, 0); */
#endif /* CONFIG_KEXEC */
-
-/* Why isn't this a) automatic, b) written in 'C'? */
- .balign 8
-_GLOBAL(sys_call_table32)
- .llong .sys_restart_syscall /* 0 */
- .llong .sys_exit
- .llong .ppc_fork
- .llong .sys_read
- .llong .sys_write
- .llong .compat_sys_open /* 5 */
- .llong .sys_close
- .llong .sys32_waitpid
- .llong .sys32_creat
- .llong .sys_link
- .llong .sys_unlink /* 10 */
- .llong .sys32_execve
- .llong .sys_chdir
- .llong .compat_sys_time
- .llong .sys_mknod
- .llong .sys_chmod /* 15 */
- .llong .sys_lchown
- .llong .sys_ni_syscall /* old break syscall */
- .llong .sys_ni_syscall /* old stat syscall */
- .llong .ppc32_lseek
- .llong .sys_getpid /* 20 */
- .llong .compat_sys_mount
- .llong .sys_oldumount
- .llong .sys_setuid
- .llong .sys_getuid
- .llong .compat_sys_stime /* 25 */
- .llong .sys32_ptrace
- .llong .sys_alarm
- .llong .sys_ni_syscall /* old fstat syscall */
- .llong .sys32_pause
- .llong .compat_sys_utime /* 30 */
- .llong .sys_ni_syscall /* old stty syscall */
- .llong .sys_ni_syscall /* old gtty syscall */
- .llong .sys32_access
- .llong .sys32_nice
- .llong .sys_ni_syscall /* 35 - old ftime syscall */
- .llong .sys_sync
- .llong .sys32_kill
- .llong .sys_rename
- .llong .sys32_mkdir
- .llong .sys_rmdir /* 40 */
- .llong .sys_dup
- .llong .sys_pipe
- .llong .compat_sys_times
- .llong .sys_ni_syscall /* old prof syscall */
- .llong .sys_brk /* 45 */
- .llong .sys_setgid
- .llong .sys_getgid
- .llong .sys_signal
- .llong .sys_geteuid
- .llong .sys_getegid /* 50 */
- .llong .sys_acct
- .llong .sys_umount
- .llong .sys_ni_syscall /* old lock syscall */
- .llong .compat_sys_ioctl
- .llong .compat_sys_fcntl /* 55 */
- .llong .sys_ni_syscall /* old mpx syscall */
- .llong .sys32_setpgid
- .llong .sys_ni_syscall /* old ulimit syscall */
- .llong .sys32_olduname
- .llong .sys32_umask /* 60 */
- .llong .sys_chroot
- .llong .sys_ustat
- .llong .sys_dup2
- .llong .sys_getppid
- .llong .sys_getpgrp /* 65 */
- .llong .sys_setsid
- .llong .sys32_sigaction
- .llong .sys_sgetmask
- .llong .sys32_ssetmask
- .llong .sys_setreuid /* 70 */
- .llong .sys_setregid
- .llong .ppc32_sigsuspend
- .llong .compat_sys_sigpending
- .llong .sys32_sethostname
- .llong .compat_sys_setrlimit /* 75 */
- .llong .compat_sys_old_getrlimit
- .llong .compat_sys_getrusage
- .llong .sys32_gettimeofday
- .llong .sys32_settimeofday
- .llong .sys32_getgroups /* 80 */
- .llong .sys32_setgroups
- .llong .sys_ni_syscall /* old select syscall */
- .llong .sys_symlink
- .llong .sys_ni_syscall /* old lstat syscall */
- .llong .sys32_readlink /* 85 */
- .llong .sys_uselib
- .llong .sys_swapon
- .llong .sys_reboot
- .llong .old32_readdir
- .llong .sys_mmap /* 90 */
- .llong .sys_munmap
- .llong .sys_truncate
- .llong .sys_ftruncate
- .llong .sys_fchmod
- .llong .sys_fchown /* 95 */
- .llong .sys32_getpriority
- .llong .sys32_setpriority
- .llong .sys_ni_syscall /* old profil syscall */
- .llong .compat_sys_statfs
- .llong .compat_sys_fstatfs /* 100 */
- .llong .sys_ni_syscall /* old ioperm syscall */
- .llong .compat_sys_socketcall
- .llong .sys32_syslog
- .llong .compat_sys_setitimer
- .llong .compat_sys_getitimer /* 105 */
- .llong .compat_sys_newstat
- .llong .compat_sys_newlstat
- .llong .compat_sys_newfstat
- .llong .sys32_uname
- .llong .sys_ni_syscall /* 110 old iopl syscall */
- .llong .sys_vhangup
- .llong .sys_ni_syscall /* old idle syscall */
- .llong .sys_ni_syscall /* old vm86 syscall */
- .llong .compat_sys_wait4
- .llong .sys_swapoff /* 115 */
- .llong .sys32_sysinfo
- .llong .sys32_ipc
- .llong .sys_fsync
- .llong .ppc32_sigreturn
- .llong .ppc_clone /* 120 */
- .llong .sys32_setdomainname
- .llong .ppc64_newuname
- .llong .sys_ni_syscall /* old modify_ldt syscall */
- .llong .sys32_adjtimex
- .llong .sys_mprotect /* 125 */
- .llong .compat_sys_sigprocmask
- .llong .sys_ni_syscall /* old create_module syscall */
- .llong .sys_init_module
- .llong .sys_delete_module
- .llong .sys_ni_syscall /* 130 old get_kernel_syms syscall */
- .llong .sys_quotactl
- .llong .sys32_getpgid
- .llong .sys_fchdir
- .llong .sys_bdflush
- .llong .sys32_sysfs /* 135 */
- .llong .ppc64_personality
- .llong .sys_ni_syscall /* for afs_syscall */
- .llong .sys_setfsuid
- .llong .sys_setfsgid
- .llong .sys_llseek /* 140 */
- .llong .sys32_getdents
- .llong .ppc32_select
- .llong .sys_flock
- .llong .sys_msync
- .llong .compat_sys_readv /* 145 */
- .llong .compat_sys_writev
- .llong .sys32_getsid
- .llong .sys_fdatasync
- .llong .sys32_sysctl
- .llong .sys_mlock /* 150 */
- .llong .sys_munlock
- .llong .sys_mlockall
- .llong .sys_munlockall
- .llong .sys32_sched_setparam
- .llong .sys32_sched_getparam /* 155 */
- .llong .sys32_sched_setscheduler
- .llong .sys32_sched_getscheduler
- .llong .sys_sched_yield
- .llong .sys32_sched_get_priority_max
- .llong .sys32_sched_get_priority_min /* 160 */
- .llong .sys32_sched_rr_get_interval
- .llong .compat_sys_nanosleep
- .llong .sys_mremap
- .llong .sys_setresuid
- .llong .sys_getresuid /* 165 */
- .llong .sys_ni_syscall /* old query_module syscall */
- .llong .sys_poll
- .llong .compat_sys_nfsservctl
- .llong .sys_setresgid
- .llong .sys_getresgid /* 170 */
- .llong .sys32_prctl
- .llong .ppc32_rt_sigreturn
- .llong .sys32_rt_sigaction
- .llong .sys32_rt_sigprocmask
- .llong .sys32_rt_sigpending /* 175 */
- .llong .compat_sys_rt_sigtimedwait
- .llong .sys32_rt_sigqueueinfo
- .llong .ppc32_rt_sigsuspend
- .llong .sys32_pread64
- .llong .sys32_pwrite64 /* 180 */
- .llong .sys_chown
- .llong .sys_getcwd
- .llong .sys_capget
- .llong .sys_capset
- .llong .sys32_sigaltstack /* 185 */
- .llong .sys32_sendfile
- .llong .sys_ni_syscall /* reserved for streams1 */
- .llong .sys_ni_syscall /* reserved for streams2 */
- .llong .ppc_vfork
- .llong .compat_sys_getrlimit /* 190 */
- .llong .sys32_readahead
- .llong .sys32_mmap2
- .llong .sys32_truncate64
- .llong .sys32_ftruncate64
- .llong .sys_stat64 /* 195 */
- .llong .sys_lstat64
- .llong .sys_fstat64
- .llong .sys32_pciconfig_read
- .llong .sys32_pciconfig_write
- .llong .sys32_pciconfig_iobase /* 200 - pciconfig_iobase */
- .llong .sys_ni_syscall /* reserved for MacOnLinux */
- .llong .sys_getdents64
- .llong .sys_pivot_root
- .llong .compat_sys_fcntl64
- .llong .sys_madvise /* 205 */
- .llong .sys_mincore
- .llong .sys_gettid
- .llong .sys_tkill
- .llong .sys_setxattr
- .llong .sys_lsetxattr /* 210 */
- .llong .sys_fsetxattr
- .llong .sys_getxattr
- .llong .sys_lgetxattr
- .llong .sys_fgetxattr
- .llong .sys_listxattr /* 215 */
- .llong .sys_llistxattr
- .llong .sys_flistxattr
- .llong .sys_removexattr
- .llong .sys_lremovexattr
- .llong .sys_fremovexattr /* 220 */
- .llong .compat_sys_futex
- .llong .compat_sys_sched_setaffinity
- .llong .compat_sys_sched_getaffinity
- .llong .sys_ni_syscall
- .llong .sys_ni_syscall /* 225 - reserved for tux */
- .llong .sys32_sendfile64
- .llong .compat_sys_io_setup
- .llong .sys_io_destroy
- .llong .compat_sys_io_getevents
- .llong .compat_sys_io_submit
- .llong .sys_io_cancel
- .llong .sys_set_tid_address
- .llong .ppc32_fadvise64
- .llong .sys_exit_group
- .llong .ppc32_lookup_dcookie /* 235 */
- .llong .sys_epoll_create
- .llong .sys_epoll_ctl
- .llong .sys_epoll_wait
- .llong .sys_remap_file_pages
- .llong .ppc32_timer_create /* 240 */
- .llong .compat_sys_timer_settime
- .llong .compat_sys_timer_gettime
- .llong .sys_timer_getoverrun
- .llong .sys_timer_delete
- .llong .compat_sys_clock_settime /* 245 */
- .llong .compat_sys_clock_gettime
- .llong .compat_sys_clock_getres
- .llong .compat_sys_clock_nanosleep
- .llong .ppc32_swapcontext
- .llong .sys32_tgkill /* 250 */
- .llong .sys32_utimes
- .llong .compat_sys_statfs64
- .llong .compat_sys_fstatfs64
- .llong .ppc32_fadvise64_64 /* 32bit only fadvise64_64 */
- .llong .ppc_rtas /* 255 */
- .llong .sys_ni_syscall /* 256 reserved for sys_debug_setcontext */
- .llong .sys_ni_syscall /* 257 reserved for vserver */
- .llong .sys_ni_syscall /* 258 reserved for new sys_remap_file_pages */
- .llong .compat_sys_mbind
- .llong .compat_sys_get_mempolicy /* 260 */
- .llong .compat_sys_set_mempolicy
- .llong .compat_sys_mq_open
- .llong .sys_mq_unlink
- .llong .compat_sys_mq_timedsend
- .llong .compat_sys_mq_timedreceive /* 265 */
- .llong .compat_sys_mq_notify
- .llong .compat_sys_mq_getsetattr
- .llong .compat_sys_kexec_load
- .llong .sys32_add_key
- .llong .sys32_request_key /* 270 */
- .llong .compat_sys_keyctl
- .llong .compat_sys_waitid
- .llong .sys32_ioprio_set
- .llong .sys32_ioprio_get
- .llong .sys_inotify_init /* 275 */
- .llong .sys_inotify_add_watch
- .llong .sys_inotify_rm_watch
-
- .balign 8
-_GLOBAL(sys_call_table)
- .llong .sys_restart_syscall /* 0 */
- .llong .sys_exit
- .llong .ppc_fork
- .llong .sys_read
- .llong .sys_write
- .llong .sys_open /* 5 */
- .llong .sys_close
- .llong .sys_waitpid
- .llong .sys_creat
- .llong .sys_link
- .llong .sys_unlink /* 10 */
- .llong .sys_execve
- .llong .sys_chdir
- .llong .sys64_time
- .llong .sys_mknod
- .llong .sys_chmod /* 15 */
- .llong .sys_lchown
- .llong .sys_ni_syscall /* old break syscall */
- .llong .sys_ni_syscall /* old stat syscall */
- .llong .sys_lseek
- .llong .sys_getpid /* 20 */
- .llong .sys_mount
- .llong .sys_ni_syscall /* old umount syscall */
- .llong .sys_setuid
- .llong .sys_getuid
- .llong .sys_stime /* 25 */
- .llong .sys_ptrace
- .llong .sys_alarm
- .llong .sys_ni_syscall /* old fstat syscall */
- .llong .sys_pause
- .llong .sys_utime /* 30 */
- .llong .sys_ni_syscall /* old stty syscall */
- .llong .sys_ni_syscall /* old gtty syscall */
- .llong .sys_access
- .llong .sys_nice
- .llong .sys_ni_syscall /* 35 - old ftime syscall */
- .llong .sys_sync
- .llong .sys_kill
- .llong .sys_rename
- .llong .sys_mkdir
- .llong .sys_rmdir /* 40 */
- .llong .sys_dup
- .llong .sys_pipe
- .llong .sys_times
- .llong .sys_ni_syscall /* old prof syscall */
- .llong .sys_brk /* 45 */
- .llong .sys_setgid
- .llong .sys_getgid
- .llong .sys_signal
- .llong .sys_geteuid
- .llong .sys_getegid /* 50 */
- .llong .sys_acct
- .llong .sys_umount
- .llong .sys_ni_syscall /* old lock syscall */
- .llong .sys_ioctl
- .llong .sys_fcntl /* 55 */
- .llong .sys_ni_syscall /* old mpx syscall */
- .llong .sys_setpgid
- .llong .sys_ni_syscall /* old ulimit syscall */
- .llong .sys_ni_syscall /* old uname syscall */
- .llong .sys_umask /* 60 */
- .llong .sys_chroot
- .llong .sys_ustat
- .llong .sys_dup2
- .llong .sys_getppid
- .llong .sys_getpgrp /* 65 */
- .llong .sys_setsid
- .llong .sys_ni_syscall
- .llong .sys_sgetmask
- .llong .sys_ssetmask
- .llong .sys_setreuid /* 70 */
- .llong .sys_setregid
- .llong .sys_ni_syscall
- .llong .sys_ni_syscall
- .llong .sys_sethostname
- .llong .sys_setrlimit /* 75 */
- .llong .sys_ni_syscall /* old getrlimit syscall */
- .llong .sys_getrusage
- .llong .sys_gettimeofday
- .llong .sys_settimeofday
- .llong .sys_getgroups /* 80 */
- .llong .sys_setgroups
- .llong .sys_ni_syscall /* old select syscall */
- .llong .sys_symlink
- .llong .sys_ni_syscall /* old lstat syscall */
- .llong .sys_readlink /* 85 */
- .llong .sys_uselib
- .llong .sys_swapon
- .llong .sys_reboot
- .llong .sys_ni_syscall /* old readdir syscall */
- .llong .sys_mmap /* 90 */
- .llong .sys_munmap
- .llong .sys_truncate
- .llong .sys_ftruncate
- .llong .sys_fchmod
- .llong .sys_fchown /* 95 */
- .llong .sys_getpriority
- .llong .sys_setpriority
- .llong .sys_ni_syscall /* old profil syscall holder */
- .llong .sys_statfs
- .llong .sys_fstatfs /* 100 */
- .llong .sys_ni_syscall /* old ioperm syscall */
- .llong .sys_socketcall
- .llong .sys_syslog
- .llong .sys_setitimer
- .llong .sys_getitimer /* 105 */
- .llong .sys_newstat
- .llong .sys_newlstat
- .llong .sys_newfstat
- .llong .sys_ni_syscall /* old uname syscall */
- .llong .sys_ni_syscall /* 110 old iopl syscall */
- .llong .sys_vhangup
- .llong .sys_ni_syscall /* old idle syscall */
- .llong .sys_ni_syscall /* old vm86 syscall */
- .llong .sys_wait4
- .llong .sys_swapoff /* 115 */
- .llong .sys_sysinfo
- .llong .sys_ipc
- .llong .sys_fsync
- .llong .sys_ni_syscall
- .llong .ppc_clone /* 120 */
- .llong .sys_setdomainname
- .llong .ppc64_newuname
- .llong .sys_ni_syscall /* old modify_ldt syscall */
- .llong .sys_adjtimex
- .llong .sys_mprotect /* 125 */
- .llong .sys_ni_syscall
- .llong .sys_ni_syscall /* old create_module syscall */
- .llong .sys_init_module
- .llong .sys_delete_module
- .llong .sys_ni_syscall /* 130 old get_kernel_syms syscall */
- .llong .sys_quotactl
- .llong .sys_getpgid
- .llong .sys_fchdir
- .llong .sys_bdflush
- .llong .sys_sysfs /* 135 */
- .llong .ppc64_personality
- .llong .sys_ni_syscall /* for afs_syscall */
- .llong .sys_setfsuid
- .llong .sys_setfsgid
- .llong .sys_llseek /* 140 */
- .llong .sys_getdents
- .llong .sys_select
- .llong .sys_flock
- .llong .sys_msync
- .llong .sys_readv /* 145 */
- .llong .sys_writev
- .llong .sys_getsid
- .llong .sys_fdatasync
- .llong .sys_sysctl
- .llong .sys_mlock /* 150 */
- .llong .sys_munlock
- .llong .sys_mlockall
- .llong .sys_munlockall
- .llong .sys_sched_setparam
- .llong .sys_sched_getparam /* 155 */
- .llong .sys_sched_setscheduler
- .llong .sys_sched_getscheduler
- .llong .sys_sched_yield
- .llong .sys_sched_get_priority_max
- .llong .sys_sched_get_priority_min /* 160 */
- .llong .sys_sched_rr_get_interval
- .llong .sys_nanosleep
- .llong .sys_mremap
- .llong .sys_setresuid
- .llong .sys_getresuid /* 165 */
- .llong .sys_ni_syscall /* old query_module syscall */
- .llong .sys_poll
- .llong .sys_nfsservctl
- .llong .sys_setresgid
- .llong .sys_getresgid /* 170 */
- .llong .sys_prctl
- .llong .ppc64_rt_sigreturn
- .llong .sys_rt_sigaction
- .llong .sys_rt_sigprocmask
- .llong .sys_rt_sigpending /* 175 */
- .llong .sys_rt_sigtimedwait
- .llong .sys_rt_sigqueueinfo
- .llong .ppc64_rt_sigsuspend
- .llong .sys_pread64
- .llong .sys_pwrite64 /* 180 */
- .llong .sys_chown
- .llong .sys_getcwd
- .llong .sys_capget
- .llong .sys_capset
- .llong .sys_sigaltstack /* 185 */
- .llong .sys_sendfile64
- .llong .sys_ni_syscall /* reserved for streams1 */
- .llong .sys_ni_syscall /* reserved for streams2 */
- .llong .ppc_vfork
- .llong .sys_getrlimit /* 190 */
- .llong .sys_readahead
- .llong .sys_ni_syscall /* 32bit only mmap2 */
- .llong .sys_ni_syscall /* 32bit only truncate64 */
- .llong .sys_ni_syscall /* 32bit only ftruncate64 */
- .llong .sys_ni_syscall /* 195 - 32bit only stat64 */
- .llong .sys_ni_syscall /* 32bit only lstat64 */
- .llong .sys_ni_syscall /* 32bit only fstat64 */
- .llong .sys_pciconfig_read
- .llong .sys_pciconfig_write
- .llong .sys_pciconfig_iobase /* 200 - pciconfig_iobase */
- .llong .sys_ni_syscall /* reserved for MacOnLinux */
- .llong .sys_getdents64
- .llong .sys_pivot_root
- .llong .sys_ni_syscall /* 32bit only fcntl64 */
- .llong .sys_madvise /* 205 */
- .llong .sys_mincore
- .llong .sys_gettid
- .llong .sys_tkill
- .llong .sys_setxattr
- .llong .sys_lsetxattr /* 210 */
- .llong .sys_fsetxattr
- .llong .sys_getxattr
- .llong .sys_lgetxattr
- .llong .sys_fgetxattr
- .llong .sys_listxattr /* 215 */
- .llong .sys_llistxattr
- .llong .sys_flistxattr
- .llong .sys_removexattr
- .llong .sys_lremovexattr
- .llong .sys_fremovexattr /* 220 */
- .llong .sys_futex
- .llong .sys_sched_setaffinity
- .llong .sys_sched_getaffinity
- .llong .sys_ni_syscall
- .llong .sys_ni_syscall /* 225 - reserved for tux */
- .llong .sys_ni_syscall /* 32bit only sendfile64 */
- .llong .sys_io_setup
- .llong .sys_io_destroy
- .llong .sys_io_getevents
- .llong .sys_io_submit /* 230 */
- .llong .sys_io_cancel
- .llong .sys_set_tid_address
- .llong .sys_fadvise64
- .llong .sys_exit_group
- .llong .sys_lookup_dcookie /* 235 */
- .llong .sys_epoll_create
- .llong .sys_epoll_ctl
- .llong .sys_epoll_wait
- .llong .sys_remap_file_pages
- .llong .sys_timer_create /* 240 */
- .llong .sys_timer_settime
- .llong .sys_timer_gettime
- .llong .sys_timer_getoverrun
- .llong .sys_timer_delete
- .llong .sys_clock_settime /* 245 */
- .llong .sys_clock_gettime
- .llong .sys_clock_getres
- .llong .sys_clock_nanosleep
- .llong .ppc64_swapcontext
- .llong .sys_tgkill /* 250 */
- .llong .sys_utimes
- .llong .sys_statfs64
- .llong .sys_fstatfs64
- .llong .sys_ni_syscall /* 32bit only fadvise64_64 */
- .llong .ppc_rtas /* 255 */
- .llong .sys_ni_syscall /* 256 reserved for sys_debug_setcontext */
- .llong .sys_ni_syscall /* 257 reserved for vserver */
- .llong .sys_ni_syscall /* 258 reserved for new sys_remap_file_pages */
- .llong .sys_mbind
- .llong .sys_get_mempolicy /* 260 */
- .llong .sys_set_mempolicy
- .llong .sys_mq_open
- .llong .sys_mq_unlink
- .llong .sys_mq_timedsend
- .llong .sys_mq_timedreceive /* 265 */
- .llong .sys_mq_notify
- .llong .sys_mq_getsetattr
- .llong .sys_kexec_load
- .llong .sys_add_key
- .llong .sys_request_key /* 270 */
- .llong .sys_keyctl
- .llong .sys_waitid
- .llong .sys_ioprio_set
- .llong .sys_ioprio_get
- .llong .sys_inotify_init /* 275 */
- .llong .sys_inotify_add_watch
- .llong .sys_inotify_rm_watch
diff --git a/arch/ppc64/kernel/nvram.c b/arch/ppc64/kernel/nvram.c
index 4fb1a9f5060d..c0fcd29918ce 100644
--- a/arch/ppc64/kernel/nvram.c
+++ b/arch/ppc64/kernel/nvram.c
@@ -31,7 +31,6 @@
#include <asm/rtas.h>
#include <asm/prom.h>
#include <asm/machdep.h>
-#include <asm/systemcfg.h>
#undef DEBUG_NVRAM
@@ -167,7 +166,7 @@ static int dev_nvram_ioctl(struct inode *inode, struct file *file,
case IOC_NVRAM_GET_OFFSET: {
int part, offset;
- if (systemcfg->platform != PLATFORM_POWERMAC)
+ if (_machine != PLATFORM_POWERMAC)
return -EINVAL;
if (copy_from_user(&part, (void __user*)arg, sizeof(part)) != 0)
return -EFAULT;
@@ -450,7 +449,7 @@ static int nvram_setup_partition(void)
* in our nvram, as Apple defined partitions use pretty much
* all of the space
*/
- if (systemcfg->platform == PLATFORM_POWERMAC)
+ if (_machine == PLATFORM_POWERMAC)
return -ENOSPC;
/* see if we have an OS partition that meets our needs.
diff --git a/arch/ppc64/kernel/pci.c b/arch/ppc64/kernel/pci.c
index ff4be1da69d5..3cef1b8f57f0 100644
--- a/arch/ppc64/kernel/pci.c
+++ b/arch/ppc64/kernel/pci.c
@@ -31,8 +31,7 @@
#include <asm/irq.h>
#include <asm/machdep.h>
#include <asm/udbg.h>
-
-#include "pci.h"
+#include <asm/ppc-pci.h>
#ifdef DEBUG
#define DBG(fmt...) udbg_printf(fmt)
@@ -296,8 +295,8 @@ static void pci_parse_of_addrs(struct device_node *node, struct pci_dev *dev)
}
}
-static struct pci_dev *of_create_pci_dev(struct device_node *node,
- struct pci_bus *bus, int devfn)
+struct pci_dev *of_create_pci_dev(struct device_node *node,
+ struct pci_bus *bus, int devfn)
{
struct pci_dev *dev;
const char *type;
@@ -355,10 +354,9 @@ static struct pci_dev *of_create_pci_dev(struct device_node *node,
return dev;
}
+EXPORT_SYMBOL(of_create_pci_dev);
-static void of_scan_pci_bridge(struct device_node *node, struct pci_dev *dev);
-
-static void __devinit of_scan_bus(struct device_node *node,
+void __devinit of_scan_bus(struct device_node *node,
struct pci_bus *bus)
{
struct device_node *child = NULL;
@@ -382,9 +380,10 @@ static void __devinit of_scan_bus(struct device_node *node,
do_bus_setup(bus);
}
+EXPORT_SYMBOL(of_scan_bus);
-static void __devinit of_scan_pci_bridge(struct device_node *node,
- struct pci_dev *dev)
+void __devinit of_scan_pci_bridge(struct device_node *node,
+ struct pci_dev *dev)
{
struct pci_bus *bus;
u32 *busrange, *ranges;
@@ -465,9 +464,10 @@ static void __devinit of_scan_pci_bridge(struct device_node *node,
else if (mode == PCI_PROBE_NORMAL)
pci_scan_child_bus(bus);
}
+EXPORT_SYMBOL(of_scan_pci_bridge);
#endif /* CONFIG_PPC_MULTIPLATFORM */
-static void __devinit scan_phb(struct pci_controller *hose)
+void __devinit scan_phb(struct pci_controller *hose)
{
struct pci_bus *bus;
struct device_node *node = hose->arch_data;
@@ -548,6 +548,11 @@ static int __init pcibios_init(void)
if (ppc64_isabridge_dev != NULL)
printk("ISA bridge at %s\n", pci_name(ppc64_isabridge_dev));
+#ifdef CONFIG_PPC_MULTIPLATFORM
+ /* map in PCI I/O space */
+ phbs_remap_io();
+#endif
+
printk("PCI: Probing PCI hardware done\n");
return 0;
@@ -727,16 +732,17 @@ static pgprot_t __pci_mmap_set_pgprot(struct pci_dev *dev, struct resource *rp,
* above routine
*/
pgprot_t pci_phys_mem_access_prot(struct file *file,
- unsigned long offset,
+ unsigned long pfn,
unsigned long size,
pgprot_t protection)
{
struct pci_dev *pdev = NULL;
struct resource *found = NULL;
unsigned long prot = pgprot_val(protection);
+ unsigned long offset = pfn << PAGE_SHIFT;
int i;
- if (page_is_ram(offset >> PAGE_SHIFT))
+ if (page_is_ram(pfn))
return __pgprot(prot);
prot |= _PAGE_NO_CACHE | _PAGE_GUARDED;
@@ -881,9 +887,9 @@ static void __devinit pci_process_ISA_OF_ranges(struct device_node *isa_node,
}
void __devinit pci_process_bridge_OF_ranges(struct pci_controller *hose,
- struct device_node *dev)
+ struct device_node *dev, int prim)
{
- unsigned int *ranges;
+ unsigned int *ranges, pci_space;
unsigned long size;
int rlen = 0;
int memno = 0;
@@ -906,16 +912,39 @@ void __devinit pci_process_bridge_OF_ranges(struct pci_controller *hose,
ranges = (unsigned int *) get_property(dev, "ranges", &rlen);
while ((rlen -= np * sizeof(unsigned int)) >= 0) {
res = NULL;
- pci_addr = (unsigned long)ranges[1] << 32 | ranges[2];
+ pci_space = ranges[0];
+ pci_addr = ((unsigned long)ranges[1] << 32) | ranges[2];
cpu_phys_addr = ranges[3];
- if (na == 2)
- cpu_phys_addr = cpu_phys_addr << 32 | ranges[4];
+ if (na >= 2)
+ cpu_phys_addr = (cpu_phys_addr << 32) | ranges[4];
- size = (unsigned long)ranges[na+3] << 32 | ranges[na+4];
+ size = ((unsigned long)ranges[na+3] << 32) | ranges[na+4];
+ ranges += np;
if (size == 0)
continue;
- switch ((ranges[0] >> 24) & 0x3) {
+
+ /* Now consume following elements while they are contiguous */
+ while (rlen >= np * sizeof(unsigned int)) {
+ unsigned long addr, phys;
+
+ if (ranges[0] != pci_space)
+ break;
+ addr = ((unsigned long)ranges[1] << 32) | ranges[2];
+ phys = ranges[3];
+ if (na >= 2)
+ phys = (phys << 32) | ranges[4];
+ if (addr != pci_addr + size ||
+ phys != cpu_phys_addr + size)
+ break;
+
+ size += ((unsigned long)ranges[na+3] << 32)
+ | ranges[na+4];
+ ranges += np;
+ rlen -= np * sizeof(unsigned int);
+ }
+
+ switch ((pci_space >> 24) & 0x3) {
case 1: /* I/O space */
hose->io_base_phys = cpu_phys_addr;
hose->pci_io_size = size;
@@ -949,7 +978,6 @@ void __devinit pci_process_bridge_OF_ranges(struct pci_controller *hose,
res->sibling = NULL;
res->child = NULL;
}
- ranges += np;
}
}
@@ -1254,12 +1282,9 @@ long sys_pciconfig_iobase(long which, unsigned long in_bus,
* G5 machines... So when something asks for bus 0 io base
* (bus 0 is HT root), we return the AGP one instead.
*/
-#ifdef CONFIG_PPC_PMAC
- if (systemcfg->platform == PLATFORM_POWERMAC &&
- machine_is_compatible("MacRISC4"))
+ if (machine_is_compatible("MacRISC4"))
if (in_bus == 0)
in_bus = 0xf0;
-#endif /* CONFIG_PPC_PMAC */
/* That syscall isn't quite compatible with PCI domains, but it's
* used on pre-domains setup. We return the first match
diff --git a/arch/ppc64/kernel/pci.h b/arch/ppc64/kernel/pci.h
deleted file mode 100644
index 5eb2cc320566..000000000000
--- a/arch/ppc64/kernel/pci.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * c 2001 PPC 64 Team, IBM Corp
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-#ifndef __PPC_KERNEL_PCI_H__
-#define __PPC_KERNEL_PCI_H__
-
-#include <linux/pci.h>
-#include <asm/pci-bridge.h>
-
-extern unsigned long isa_io_base;
-
-extern void pci_setup_pci_controller(struct pci_controller *hose);
-extern void pci_setup_phb_io(struct pci_controller *hose, int primary);
-extern void pci_setup_phb_io_dynamic(struct pci_controller *hose, int primary);
-
-
-extern struct list_head hose_list;
-extern int global_phb_number;
-
-extern unsigned long find_and_init_phbs(void);
-
-extern struct pci_dev *ppc64_isabridge_dev; /* may be NULL if no ISA bus */
-
-/* PCI device_node operations */
-struct device_node;
-typedef void *(*traverse_func)(struct device_node *me, void *data);
-void *traverse_pci_devices(struct device_node *start, traverse_func pre,
- void *data);
-
-void pci_devs_phb_init(void);
-void pci_devs_phb_init_dynamic(struct pci_controller *phb);
-
-/* PCI address cache management routines */
-void pci_addr_cache_insert_device(struct pci_dev *dev);
-void pci_addr_cache_remove_device(struct pci_dev *dev);
-
-/* From rtas_pci.h */
-void init_pci_config_tokens (void);
-unsigned long get_phb_buid (struct device_node *);
-
-/* From pSeries_pci.h */
-extern void pSeries_final_fixup(void);
-extern void pSeries_irq_bus_setup(struct pci_bus *bus);
-
-extern unsigned long pci_probe_only;
-extern unsigned long pci_assign_all_buses;
-extern int pci_read_irq_line(struct pci_dev *pci_dev);
-
-#endif /* __PPC_KERNEL_PCI_H__ */
diff --git a/arch/ppc64/kernel/pci_direct_iommu.c b/arch/ppc64/kernel/pci_direct_iommu.c
index 54055c81017a..e1a32f802c0b 100644
--- a/arch/ppc64/kernel/pci_direct_iommu.c
+++ b/arch/ppc64/kernel/pci_direct_iommu.c
@@ -27,8 +27,7 @@
#include <asm/machdep.h>
#include <asm/pmac_feature.h>
#include <asm/abs_addr.h>
-
-#include "pci.h"
+#include <asm/ppc-pci.h>
static void *pci_direct_alloc_coherent(struct device *hwdev, size_t size,
dma_addr_t *dma_handle, gfp_t flag)
diff --git a/arch/ppc64/kernel/pci_dn.c b/arch/ppc64/kernel/pci_dn.c
index a86389d07d57..12c4c9e9bbc7 100644
--- a/arch/ppc64/kernel/pci_dn.c
+++ b/arch/ppc64/kernel/pci_dn.c
@@ -30,8 +30,7 @@
#include <asm/prom.h>
#include <asm/pci-bridge.h>
#include <asm/pSeries_reconfig.h>
-
-#include "pci.h"
+#include <asm/ppc-pci.h>
/*
* Traverse_func that inits the PCI fields of the device node.
@@ -44,7 +43,7 @@ static void * __devinit update_dn_pci_info(struct device_node *dn, void *data)
u32 *regs;
struct pci_dn *pdn;
- if (phb->is_dynamic)
+ if (mem_init_done)
pdn = kmalloc(sizeof(*pdn), GFP_KERNEL);
else
pdn = alloc_bootmem(sizeof(*pdn));
@@ -121,6 +120,14 @@ void *traverse_pci_devices(struct device_node *start, traverse_func pre,
return NULL;
}
+/**
+ * pci_devs_phb_init_dynamic - setup pci devices under this PHB
+ * phb: pci-to-host bridge (top-level bridge connecting to cpu)
+ *
+ * This routine is called both during boot, (before the memory
+ * subsystem is set up, before kmalloc is valid) and during the
+ * dynamic lpar operation of adding a PHB to a running system.
+ */
void __devinit pci_devs_phb_init_dynamic(struct pci_controller *phb)
{
struct device_node * dn = (struct device_node *) phb->arch_data;
@@ -182,13 +189,14 @@ EXPORT_SYMBOL(fetch_dev_dn);
static int pci_dn_reconfig_notifier(struct notifier_block *nb, unsigned long action, void *node)
{
struct device_node *np = node;
- struct pci_dn *pci;
+ struct pci_dn *pci = NULL;
int err = NOTIFY_OK;
switch (action) {
case PSERIES_RECONFIG_ADD:
pci = np->parent->data;
- update_dn_pci_info(np, pci->phb);
+ if (pci)
+ update_dn_pci_info(np, pci->phb);
break;
default:
err = NOTIFY_DONE;
@@ -201,9 +209,14 @@ static struct notifier_block pci_dn_reconfig_nb = {
.notifier_call = pci_dn_reconfig_notifier,
};
-/*
- * Actually initialize the phbs.
- * The buswalk on this phb has not happened yet.
+/**
+ * pci_devs_phb_init - Initialize phbs and pci devs under them.
+ *
+ * This routine walks over all phb's (pci-host bridges) on the
+ * system, and sets up assorted pci-related structures
+ * (including pci info in the device node structs) for each
+ * pci device found underneath. This routine runs once,
+ * early in the boot sequence.
*/
void __init pci_devs_phb_init(void)
{
diff --git a/arch/ppc64/kernel/pci_iommu.c b/arch/ppc64/kernel/pci_iommu.c
index d9e33b7d4203..bdf15dbbf4f0 100644
--- a/arch/ppc64/kernel/pci_iommu.c
+++ b/arch/ppc64/kernel/pci_iommu.c
@@ -1,8 +1,8 @@
/*
* arch/ppc64/kernel/pci_iommu.c
* Copyright (C) 2001 Mike Corrigan & Dave Engebretsen, IBM Corporation
- *
- * Rewrite, cleanup, new allocation schemes:
+ *
+ * Rewrite, cleanup, new allocation schemes:
* Copyright (C) 2004 Olof Johansson, IBM Corporation
*
* Dynamic DMA mapping support, platform-independent parts.
@@ -11,19 +11,18 @@
* 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/config.h>
#include <linux/init.h>
#include <linux/types.h>
#include <linux/slab.h>
@@ -37,11 +36,7 @@
#include <asm/iommu.h>
#include <asm/pci-bridge.h>
#include <asm/machdep.h>
-#include "pci.h"
-
-#ifdef CONFIG_PPC_ISERIES
-#include <asm/iSeries/iSeries_pci.h>
-#endif /* CONFIG_PPC_ISERIES */
+#include <asm/ppc-pci.h>
/*
* We can use ->sysdata directly and avoid the extra work in
@@ -61,13 +56,7 @@ static inline struct iommu_table *devnode_table(struct device *dev)
} else
pdev = to_pci_dev(dev);
-#ifdef CONFIG_PPC_ISERIES
- return ISERIES_DEVNODE(pdev)->iommu_table;
-#endif /* CONFIG_PPC_ISERIES */
-
-#ifdef CONFIG_PPC_MULTIPLATFORM
return PCI_DN(PCI_GET_DN(pdev))->iommu_table;
-#endif /* CONFIG_PPC_MULTIPLATFORM */
}
diff --git a/arch/ppc64/kernel/pmac.h b/arch/ppc64/kernel/pmac.h
deleted file mode 100644
index 40e1c5030f74..000000000000
--- a/arch/ppc64/kernel/pmac.h
+++ /dev/null
@@ -1,31 +0,0 @@
-#ifndef __PMAC_H__
-#define __PMAC_H__
-
-#include <linux/pci.h>
-#include <linux/ide.h>
-
-/*
- * Declaration for the various functions exported by the
- * pmac_* files. Mostly for use by pmac_setup
- */
-
-extern void pmac_get_boot_time(struct rtc_time *tm);
-extern void pmac_get_rtc_time(struct rtc_time *tm);
-extern int pmac_set_rtc_time(struct rtc_time *tm);
-extern void pmac_read_rtc_time(void);
-extern void pmac_calibrate_decr(void);
-
-extern void pmac_pcibios_fixup(void);
-extern void pmac_pci_init(void);
-extern void pmac_setup_pci_dma(void);
-extern void pmac_check_ht_link(void);
-
-extern void pmac_setup_smp(void);
-
-extern unsigned long pmac_ide_get_base(int index);
-extern void pmac_ide_init_hwif_ports(hw_regs_t *hw,
- unsigned long data_port, unsigned long ctrl_port, int *irq);
-
-extern void pmac_nvram_init(void);
-
-#endif /* __PMAC_H__ */
diff --git a/arch/ppc64/kernel/pmac_feature.c b/arch/ppc64/kernel/pmac_feature.c
deleted file mode 100644
index eb4e6c3f694d..000000000000
--- a/arch/ppc64/kernel/pmac_feature.c
+++ /dev/null
@@ -1,767 +0,0 @@
-/*
- * arch/ppc/platforms/pmac_feature.c
- *
- * Copyright (C) 1996-2001 Paul Mackerras (paulus@cs.anu.edu.au)
- * Ben. Herrenschmidt (benh@kernel.crashing.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.
- *
- * TODO:
- *
- * - Replace mdelay with some schedule loop if possible
- * - Shorten some obfuscated delays on some routines (like modem
- * power)
- * - Refcount some clocks (see darwin)
- * - Split split split...
- *
- */
-#include <linux/config.h>
-#include <linux/types.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/spinlock.h>
-#include <linux/adb.h>
-#include <linux/pmu.h>
-#include <linux/ioport.h>
-#include <linux/pci.h>
-#include <asm/sections.h>
-#include <asm/errno.h>
-#include <asm/keylargo.h>
-#include <asm/uninorth.h>
-#include <asm/io.h>
-#include <asm/prom.h>
-#include <asm/machdep.h>
-#include <asm/pmac_feature.h>
-#include <asm/dbdma.h>
-#include <asm/pci-bridge.h>
-#include <asm/pmac_low_i2c.h>
-
-#undef DEBUG_FEATURE
-
-#ifdef DEBUG_FEATURE
-#define DBG(fmt...) printk(KERN_DEBUG fmt)
-#else
-#define DBG(fmt...)
-#endif
-
-/*
- * We use a single global lock to protect accesses. Each driver has
- * to take care of its own locking
- */
-static DEFINE_SPINLOCK(feature_lock __pmacdata);
-
-#define LOCK(flags) spin_lock_irqsave(&feature_lock, flags);
-#define UNLOCK(flags) spin_unlock_irqrestore(&feature_lock, flags);
-
-
-/*
- * Instance of some macio stuffs
- */
-struct macio_chip macio_chips[MAX_MACIO_CHIPS] __pmacdata;
-
-struct macio_chip* __pmac macio_find(struct device_node* child, int type)
-{
- while(child) {
- int i;
-
- for (i=0; i < MAX_MACIO_CHIPS && macio_chips[i].of_node; i++)
- if (child == macio_chips[i].of_node &&
- (!type || macio_chips[i].type == type))
- return &macio_chips[i];
- child = child->parent;
- }
- return NULL;
-}
-EXPORT_SYMBOL_GPL(macio_find);
-
-static const char* macio_names[] __pmacdata =
-{
- "Unknown",
- "Grand Central",
- "OHare",
- "OHareII",
- "Heathrow",
- "Gatwick",
- "Paddington",
- "Keylargo",
- "Pangea",
- "Intrepid",
- "K2"
-};
-
-
-
-/*
- * Uninorth reg. access. Note that Uni-N regs are big endian
- */
-
-#define UN_REG(r) (uninorth_base + ((r) >> 2))
-#define UN_IN(r) (in_be32(UN_REG(r)))
-#define UN_OUT(r,v) (out_be32(UN_REG(r), (v)))
-#define UN_BIS(r,v) (UN_OUT((r), UN_IN(r) | (v)))
-#define UN_BIC(r,v) (UN_OUT((r), UN_IN(r) & ~(v)))
-
-static struct device_node* uninorth_node __pmacdata;
-static u32* uninorth_base __pmacdata;
-static u32 uninorth_rev __pmacdata;
-static void *u3_ht;
-
-extern struct device_node *k2_skiplist[2];
-
-/*
- * For each motherboard family, we have a table of functions pointers
- * that handle the various features.
- */
-
-typedef long (*feature_call)(struct device_node* node, long param, long value);
-
-struct feature_table_entry {
- unsigned int selector;
- feature_call function;
-};
-
-struct pmac_mb_def
-{
- const char* model_string;
- const char* model_name;
- int model_id;
- struct feature_table_entry* features;
- unsigned long board_flags;
-};
-static struct pmac_mb_def pmac_mb __pmacdata;
-
-/*
- * Here are the chip specific feature functions
- */
-
-
-static long __pmac g5_read_gpio(struct device_node* node, long param, long value)
-{
- struct macio_chip* macio = &macio_chips[0];
-
- return MACIO_IN8(param);
-}
-
-
-static long __pmac g5_write_gpio(struct device_node* node, long param, long value)
-{
- struct macio_chip* macio = &macio_chips[0];
-
- MACIO_OUT8(param, (u8)(value & 0xff));
- return 0;
-}
-
-static long __pmac g5_gmac_enable(struct device_node* node, long param, long value)
-{
- struct macio_chip* macio = &macio_chips[0];
- unsigned long flags;
-
- if (node == NULL)
- return -ENODEV;
-
- LOCK(flags);
- if (value) {
- MACIO_BIS(KEYLARGO_FCR1, K2_FCR1_GMAC_CLK_ENABLE);
- mb();
- k2_skiplist[0] = NULL;
- } else {
- k2_skiplist[0] = node;
- mb();
- MACIO_BIC(KEYLARGO_FCR1, K2_FCR1_GMAC_CLK_ENABLE);
- }
-
- UNLOCK(flags);
- mdelay(1);
-
- return 0;
-}
-
-static long __pmac g5_fw_enable(struct device_node* node, long param, long value)
-{
- struct macio_chip* macio = &macio_chips[0];
- unsigned long flags;
-
- if (node == NULL)
- return -ENODEV;
-
- LOCK(flags);
- if (value) {
- MACIO_BIS(KEYLARGO_FCR1, K2_FCR1_FW_CLK_ENABLE);
- mb();
- k2_skiplist[1] = NULL;
- } else {
- k2_skiplist[1] = node;
- mb();
- MACIO_BIC(KEYLARGO_FCR1, K2_FCR1_FW_CLK_ENABLE);
- }
-
- UNLOCK(flags);
- mdelay(1);
-
- return 0;
-}
-
-static long __pmac g5_mpic_enable(struct device_node* node, long param, long value)
-{
- unsigned long flags;
-
- if (node->parent == NULL || strcmp(node->parent->name, "u3"))
- return 0;
-
- LOCK(flags);
- UN_BIS(U3_TOGGLE_REG, U3_MPIC_RESET | U3_MPIC_OUTPUT_ENABLE);
- UNLOCK(flags);
-
- return 0;
-}
-
-static long __pmac g5_eth_phy_reset(struct device_node* node, long param, long value)
-{
- struct macio_chip* macio = &macio_chips[0];
- struct device_node *phy;
- int need_reset;
-
- /*
- * We must not reset the combo PHYs, only the BCM5221 found in
- * the iMac G5.
- */
- phy = of_get_next_child(node, NULL);
- if (!phy)
- return -ENODEV;
- need_reset = device_is_compatible(phy, "B5221");
- of_node_put(phy);
- if (!need_reset)
- return 0;
-
- /* PHY reset is GPIO 29, not in device-tree unfortunately */
- MACIO_OUT8(K2_GPIO_EXTINT_0 + 29,
- KEYLARGO_GPIO_OUTPUT_ENABLE | KEYLARGO_GPIO_OUTOUT_DATA);
- /* Thankfully, this is now always called at a time when we can
- * schedule by sungem.
- */
- msleep(10);
- MACIO_OUT8(K2_GPIO_EXTINT_0 + 29, 0);
-
- return 0;
-}
-
-static long __pmac g5_i2s_enable(struct device_node *node, long param, long value)
-{
- /* Very crude implementation for now */
- struct macio_chip* macio = &macio_chips[0];
- unsigned long flags;
-
- if (value == 0)
- return 0; /* don't disable yet */
-
- LOCK(flags);
- MACIO_BIS(KEYLARGO_FCR3, KL3_CLK45_ENABLE | KL3_CLK49_ENABLE |
- KL3_I2S0_CLK18_ENABLE);
- udelay(10);
- MACIO_BIS(KEYLARGO_FCR1, K2_FCR1_I2S0_CELL_ENABLE |
- K2_FCR1_I2S0_CLK_ENABLE_BIT | K2_FCR1_I2S0_ENABLE);
- udelay(10);
- MACIO_BIC(KEYLARGO_FCR1, K2_FCR1_I2S0_RESET);
- UNLOCK(flags);
- udelay(10);
-
- return 0;
-}
-
-
-#ifdef CONFIG_SMP
-static long __pmac g5_reset_cpu(struct device_node* node, long param, long value)
-{
- unsigned int reset_io = 0;
- unsigned long flags;
- struct macio_chip* macio;
- struct device_node* np;
-
- macio = &macio_chips[0];
- if (macio->type != macio_keylargo2)
- return -ENODEV;
-
- np = find_path_device("/cpus");
- if (np == NULL)
- return -ENODEV;
- for (np = np->child; np != NULL; np = np->sibling) {
- u32* num = (u32 *)get_property(np, "reg", NULL);
- u32* rst = (u32 *)get_property(np, "soft-reset", NULL);
- if (num == NULL || rst == NULL)
- continue;
- if (param == *num) {
- reset_io = *rst;
- break;
- }
- }
- if (np == NULL || reset_io == 0)
- return -ENODEV;
-
- LOCK(flags);
- MACIO_OUT8(reset_io, KEYLARGO_GPIO_OUTPUT_ENABLE);
- (void)MACIO_IN8(reset_io);
- udelay(1);
- MACIO_OUT8(reset_io, 0);
- (void)MACIO_IN8(reset_io);
- UNLOCK(flags);
-
- return 0;
-}
-#endif /* CONFIG_SMP */
-
-/*
- * This can be called from pmac_smp so isn't static
- *
- * This takes the second CPU off the bus on dual CPU machines
- * running UP
- */
-void __pmac g5_phy_disable_cpu1(void)
-{
- UN_OUT(U3_API_PHY_CONFIG_1, 0);
-}
-
-static long __pmac generic_get_mb_info(struct device_node* node, long param, long value)
-{
- switch(param) {
- case PMAC_MB_INFO_MODEL:
- return pmac_mb.model_id;
- case PMAC_MB_INFO_FLAGS:
- return pmac_mb.board_flags;
- case PMAC_MB_INFO_NAME:
- /* hack hack hack... but should work */
- *((const char **)value) = pmac_mb.model_name;
- return 0;
- }
- return -EINVAL;
-}
-
-
-/*
- * Table definitions
- */
-
-/* Used on any machine
- */
-static struct feature_table_entry any_features[] __pmacdata = {
- { PMAC_FTR_GET_MB_INFO, generic_get_mb_info },
- { 0, NULL }
-};
-
-/* G5 features
- */
-static struct feature_table_entry g5_features[] __pmacdata = {
- { PMAC_FTR_GMAC_ENABLE, g5_gmac_enable },
- { PMAC_FTR_1394_ENABLE, g5_fw_enable },
- { PMAC_FTR_ENABLE_MPIC, g5_mpic_enable },
- { PMAC_FTR_READ_GPIO, g5_read_gpio },
- { PMAC_FTR_WRITE_GPIO, g5_write_gpio },
- { PMAC_FTR_GMAC_PHY_RESET, g5_eth_phy_reset },
- { PMAC_FTR_SOUND_CHIP_ENABLE, g5_i2s_enable },
-#ifdef CONFIG_SMP
- { PMAC_FTR_RESET_CPU, g5_reset_cpu },
-#endif /* CONFIG_SMP */
- { 0, NULL }
-};
-
-static struct pmac_mb_def pmac_mb_defs[] __pmacdata = {
- { "PowerMac7,2", "PowerMac G5",
- PMAC_TYPE_POWERMAC_G5, g5_features,
- 0,
- },
- { "PowerMac7,3", "PowerMac G5",
- PMAC_TYPE_POWERMAC_G5, g5_features,
- 0,
- },
- { "PowerMac8,1", "iMac G5",
- PMAC_TYPE_IMAC_G5, g5_features,
- 0,
- },
- { "PowerMac9,1", "PowerMac G5",
- PMAC_TYPE_POWERMAC_G5_U3L, g5_features,
- 0,
- },
- { "RackMac3,1", "XServe G5",
- PMAC_TYPE_XSERVE_G5, g5_features,
- 0,
- },
-};
-
-/*
- * The toplevel feature_call callback
- */
-long __pmac pmac_do_feature_call(unsigned int selector, ...)
-{
- struct device_node* node;
- long param, value;
- int i;
- feature_call func = NULL;
- va_list args;
-
- if (pmac_mb.features)
- for (i=0; pmac_mb.features[i].function; i++)
- if (pmac_mb.features[i].selector == selector) {
- func = pmac_mb.features[i].function;
- break;
- }
- if (!func)
- for (i=0; any_features[i].function; i++)
- if (any_features[i].selector == selector) {
- func = any_features[i].function;
- break;
- }
- if (!func)
- return -ENODEV;
-
- va_start(args, selector);
- node = (struct device_node*)va_arg(args, void*);
- param = va_arg(args, long);
- value = va_arg(args, long);
- va_end(args);
-
- return func(node, param, value);
-}
-
-static int __init probe_motherboard(void)
-{
- int i;
- struct macio_chip* macio = &macio_chips[0];
- const char* model = NULL;
- struct device_node *dt;
-
- /* Lookup known motherboard type in device-tree. First try an
- * exact match on the "model" property, then try a "compatible"
- * match is none is found.
- */
- dt = find_devices("device-tree");
- if (dt != NULL)
- model = (const char *) get_property(dt, "model", NULL);
- for(i=0; model && i<(sizeof(pmac_mb_defs)/sizeof(struct pmac_mb_def)); i++) {
- if (strcmp(model, pmac_mb_defs[i].model_string) == 0) {
- pmac_mb = pmac_mb_defs[i];
- goto found;
- }
- }
- for(i=0; i<(sizeof(pmac_mb_defs)/sizeof(struct pmac_mb_def)); i++) {
- if (machine_is_compatible(pmac_mb_defs[i].model_string)) {
- pmac_mb = pmac_mb_defs[i];
- goto found;
- }
- }
-
- /* Fallback to selection depending on mac-io chip type */
- switch(macio->type) {
- case macio_keylargo2:
- pmac_mb.model_id = PMAC_TYPE_UNKNOWN_K2;
- pmac_mb.model_name = "Unknown K2-based";
- pmac_mb.features = g5_features;
-
- default:
- return -ENODEV;
- }
-found:
- /* Check for "mobile" machine */
- if (model && (strncmp(model, "PowerBook", 9) == 0
- || strncmp(model, "iBook", 5) == 0))
- pmac_mb.board_flags |= PMAC_MB_MOBILE;
-
-
- printk(KERN_INFO "PowerMac motherboard: %s\n", pmac_mb.model_name);
- return 0;
-}
-
-/* Initialize the Core99 UniNorth host bridge and memory controller
- */
-static void __init probe_uninorth(void)
-{
- uninorth_node = of_find_node_by_name(NULL, "u3");
- if (uninorth_node && uninorth_node->n_addrs > 0) {
- /* Small hack until I figure out if parsing in prom.c is correct. I should
- * get rid of those pre-parsed junk anyway
- */
- unsigned long address = uninorth_node->addrs[0].address;
- uninorth_base = ioremap(address, 0x40000);
- uninorth_rev = in_be32(UN_REG(UNI_N_VERSION));
- u3_ht = ioremap(address + U3_HT_CONFIG_BASE, 0x1000);
- } else
- uninorth_node = NULL;
-
- if (!uninorth_node)
- return;
-
- printk(KERN_INFO "Found U3 memory controller & host bridge, revision: %d\n",
- uninorth_rev);
- printk(KERN_INFO "Mapped at 0x%08lx\n", (unsigned long)uninorth_base);
-
-}
-
-static void __init probe_one_macio(const char* name, const char* compat, int type)
-{
- struct device_node* node;
- int i;
- volatile u32* base;
- u32* revp;
-
- node = find_devices(name);
- if (!node || !node->n_addrs)
- return;
- if (compat)
- do {
- if (device_is_compatible(node, compat))
- break;
- node = node->next;
- } while (node);
- if (!node)
- return;
- for(i=0; i<MAX_MACIO_CHIPS; i++) {
- if (!macio_chips[i].of_node)
- break;
- if (macio_chips[i].of_node == node)
- return;
- }
- if (i >= MAX_MACIO_CHIPS) {
- printk(KERN_ERR "pmac_feature: Please increase MAX_MACIO_CHIPS !\n");
- printk(KERN_ERR "pmac_feature: %s skipped\n", node->full_name);
- return;
- }
- base = (volatile u32*)ioremap(node->addrs[0].address, node->addrs[0].size);
- if (!base) {
- printk(KERN_ERR "pmac_feature: Can't map mac-io chip !\n");
- return;
- }
- if (type == macio_keylargo) {
- u32* did = (u32 *)get_property(node, "device-id", NULL);
- if (*did == 0x00000025)
- type = macio_pangea;
- if (*did == 0x0000003e)
- type = macio_intrepid;
- }
- macio_chips[i].of_node = node;
- macio_chips[i].type = type;
- macio_chips[i].base = base;
- macio_chips[i].flags = MACIO_FLAG_SCCB_ON | MACIO_FLAG_SCCB_ON;
- macio_chips[i].name = macio_names[type];
- revp = (u32 *)get_property(node, "revision-id", NULL);
- if (revp)
- macio_chips[i].rev = *revp;
- printk(KERN_INFO "Found a %s mac-io controller, rev: %d, mapped at 0x%p\n",
- macio_names[type], macio_chips[i].rev, macio_chips[i].base);
-}
-
-static int __init
-probe_macios(void)
-{
- probe_one_macio("mac-io", "K2-Keylargo", macio_keylargo2);
-
- macio_chips[0].lbus.index = 0;
- macio_chips[1].lbus.index = 1;
-
- return (macio_chips[0].of_node == NULL) ? -ENODEV : 0;
-}
-
-static void __init
-set_initial_features(void)
-{
- struct device_node *np;
-
- if (macio_chips[0].type == macio_keylargo2) {
-#ifndef CONFIG_SMP
- /* On SMP machines running UP, we have the second CPU eating
- * bus cycles. We need to take it off the bus. This is done
- * from pmac_smp for SMP kernels running on one CPU
- */
- np = of_find_node_by_type(NULL, "cpu");
- if (np != NULL)
- np = of_find_node_by_type(np, "cpu");
- if (np != NULL) {
- g5_phy_disable_cpu1();
- of_node_put(np);
- }
-#endif /* CONFIG_SMP */
- /* Enable GMAC for now for PCI probing. It will be disabled
- * later on after PCI probe
- */
- np = of_find_node_by_name(NULL, "ethernet");
- while(np) {
- if (device_is_compatible(np, "K2-GMAC"))
- g5_gmac_enable(np, 0, 1);
- np = of_find_node_by_name(np, "ethernet");
- }
-
- /* Enable FW before PCI probe. Will be disabled later on
- * Note: We should have a batter way to check that we are
- * dealing with uninorth internal cell and not a PCI cell
- * on the external PCI. The code below works though.
- */
- np = of_find_node_by_name(NULL, "firewire");
- while(np) {
- if (device_is_compatible(np, "pci106b,5811")) {
- macio_chips[0].flags |= MACIO_FLAG_FW_SUPPORTED;
- g5_fw_enable(np, 0, 1);
- }
- np = of_find_node_by_name(np, "firewire");
- }
- }
-}
-
-void __init
-pmac_feature_init(void)
-{
- /* Detect the UniNorth memory controller */
- probe_uninorth();
-
- /* Probe mac-io controllers */
- if (probe_macios()) {
- printk(KERN_WARNING "No mac-io chip found\n");
- return;
- }
-
- /* Setup low-level i2c stuffs */
- pmac_init_low_i2c();
-
- /* Probe machine type */
- if (probe_motherboard())
- printk(KERN_WARNING "Unknown PowerMac !\n");
-
- /* Set some initial features (turn off some chips that will
- * be later turned on)
- */
- set_initial_features();
-}
-
-int __init pmac_feature_late_init(void)
-{
-#if 0
- struct device_node* np;
-
- /* Request some resources late */
- if (uninorth_node)
- request_OF_resource(uninorth_node, 0, NULL);
- np = find_devices("hammerhead");
- if (np)
- request_OF_resource(np, 0, NULL);
- np = find_devices("interrupt-controller");
- if (np)
- request_OF_resource(np, 0, NULL);
-#endif
- return 0;
-}
-
-device_initcall(pmac_feature_late_init);
-
-#if 0
-static void dump_HT_speeds(char *name, u32 cfg, u32 frq)
-{
- int freqs[16] = { 200,300,400,500,600,800,1000,0,0,0,0,0,0,0,0,0 };
- int bits[8] = { 8,16,0,32,2,4,0,0 };
- int freq = (frq >> 8) & 0xf;
-
- if (freqs[freq] == 0)
- printk("%s: Unknown HT link frequency %x\n", name, freq);
- else
- printk("%s: %d MHz on main link, (%d in / %d out) bits width\n",
- name, freqs[freq],
- bits[(cfg >> 28) & 0x7], bits[(cfg >> 24) & 0x7]);
-}
-#endif
-
-void __init pmac_check_ht_link(void)
-{
-#if 0 /* Disabled for now */
- u32 ufreq, freq, ucfg, cfg;
- struct device_node *pcix_node;
- struct pci_dn *pdn;
- u8 px_bus, px_devfn;
- struct pci_controller *px_hose;
-
- (void)in_be32(u3_ht + U3_HT_LINK_COMMAND);
- ucfg = cfg = in_be32(u3_ht + U3_HT_LINK_CONFIG);
- ufreq = freq = in_be32(u3_ht + U3_HT_LINK_FREQ);
- dump_HT_speeds("U3 HyperTransport", cfg, freq);
-
- pcix_node = of_find_compatible_node(NULL, "pci", "pci-x");
- if (pcix_node == NULL) {
- printk("No PCI-X bridge found\n");
- return;
- }
- pdn = pcix_node->data;
- px_hose = pdn->phb;
- px_bus = pdn->busno;
- px_devfn = pdn->devfn;
-
- early_read_config_dword(px_hose, px_bus, px_devfn, 0xc4, &cfg);
- early_read_config_dword(px_hose, px_bus, px_devfn, 0xcc, &freq);
- dump_HT_speeds("PCI-X HT Uplink", cfg, freq);
- early_read_config_dword(px_hose, px_bus, px_devfn, 0xc8, &cfg);
- early_read_config_dword(px_hose, px_bus, px_devfn, 0xd0, &freq);
- dump_HT_speeds("PCI-X HT Downlink", cfg, freq);
-#endif
-}
-
-/*
- * Early video resume hook
- */
-
-static void (*pmac_early_vresume_proc)(void *data) __pmacdata;
-static void *pmac_early_vresume_data __pmacdata;
-
-void pmac_set_early_video_resume(void (*proc)(void *data), void *data)
-{
- if (_machine != _MACH_Pmac)
- return;
- preempt_disable();
- pmac_early_vresume_proc = proc;
- pmac_early_vresume_data = data;
- preempt_enable();
-}
-EXPORT_SYMBOL(pmac_set_early_video_resume);
-
-
-/*
- * AGP related suspend/resume code
- */
-
-static struct pci_dev *pmac_agp_bridge __pmacdata;
-static int (*pmac_agp_suspend)(struct pci_dev *bridge) __pmacdata;
-static int (*pmac_agp_resume)(struct pci_dev *bridge) __pmacdata;
-
-void __pmac pmac_register_agp_pm(struct pci_dev *bridge,
- int (*suspend)(struct pci_dev *bridge),
- int (*resume)(struct pci_dev *bridge))
-{
- if (suspend || resume) {
- pmac_agp_bridge = bridge;
- pmac_agp_suspend = suspend;
- pmac_agp_resume = resume;
- return;
- }
- if (bridge != pmac_agp_bridge)
- return;
- pmac_agp_suspend = pmac_agp_resume = NULL;
- return;
-}
-EXPORT_SYMBOL(pmac_register_agp_pm);
-
-void __pmac pmac_suspend_agp_for_card(struct pci_dev *dev)
-{
- if (pmac_agp_bridge == NULL || pmac_agp_suspend == NULL)
- return;
- if (pmac_agp_bridge->bus != dev->bus)
- return;
- pmac_agp_suspend(pmac_agp_bridge);
-}
-EXPORT_SYMBOL(pmac_suspend_agp_for_card);
-
-void __pmac pmac_resume_agp_for_card(struct pci_dev *dev)
-{
- if (pmac_agp_bridge == NULL || pmac_agp_resume == NULL)
- return;
- if (pmac_agp_bridge->bus != dev->bus)
- return;
- pmac_agp_resume(pmac_agp_bridge);
-}
-EXPORT_SYMBOL(pmac_resume_agp_for_card);
diff --git a/arch/ppc64/kernel/pmac_pci.c b/arch/ppc64/kernel/pmac_pci.c
deleted file mode 100644
index dc40a0cad0b4..000000000000
--- a/arch/ppc64/kernel/pmac_pci.c
+++ /dev/null
@@ -1,793 +0,0 @@
-/*
- * Support for PCI bridges found on Power Macintoshes.
- * At present the "bandit" and "chaos" bridges are supported.
- * Fortunately you access configuration space in the same
- * way with either bridge.
- *
- * Copyright (C) 2003 Benjamin Herrenschmuidt (benh@kernel.crashing.org)
- * Copyright (C) 1997 Paul Mackerras (paulus@samba.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/pci.h>
-#include <linux/delay.h>
-#include <linux/string.h>
-#include <linux/init.h>
-#include <linux/bootmem.h>
-
-#include <asm/sections.h>
-#include <asm/io.h>
-#include <asm/prom.h>
-#include <asm/pci-bridge.h>
-#include <asm/machdep.h>
-#include <asm/pmac_feature.h>
-#include <asm/iommu.h>
-
-#include "pci.h"
-#include "pmac.h"
-
-#define DEBUG
-
-#ifdef DEBUG
-#define DBG(x...) printk(x)
-#else
-#define DBG(x...)
-#endif
-
-/* XXX Could be per-controller, but I don't think we risk anything by
- * assuming we won't have both UniNorth and Bandit */
-static int has_uninorth;
-static struct pci_controller *u3_agp;
-struct device_node *k2_skiplist[2];
-
-static int __init fixup_one_level_bus_range(struct device_node *node, int higher)
-{
- for (; node != 0;node = node->sibling) {
- int * bus_range;
- unsigned int *class_code;
- int len;
-
- /* For PCI<->PCI bridges or CardBus bridges, we go down */
- class_code = (unsigned int *) get_property(node, "class-code", NULL);
- if (!class_code || ((*class_code >> 8) != PCI_CLASS_BRIDGE_PCI &&
- (*class_code >> 8) != PCI_CLASS_BRIDGE_CARDBUS))
- continue;
- bus_range = (int *) get_property(node, "bus-range", &len);
- if (bus_range != NULL && len > 2 * sizeof(int)) {
- if (bus_range[1] > higher)
- higher = bus_range[1];
- }
- higher = fixup_one_level_bus_range(node->child, higher);
- }
- return higher;
-}
-
-/* This routine fixes the "bus-range" property of all bridges in the
- * system since they tend to have their "last" member wrong on macs
- *
- * Note that the bus numbers manipulated here are OF bus numbers, they
- * are not Linux bus numbers.
- */
-static void __init fixup_bus_range(struct device_node *bridge)
-{
- int * bus_range;
- int len;
-
- /* Lookup the "bus-range" property for the hose */
- bus_range = (int *) get_property(bridge, "bus-range", &len);
- if (bus_range == NULL || len < 2 * sizeof(int)) {
- printk(KERN_WARNING "Can't get bus-range for %s\n",
- bridge->full_name);
- return;
- }
- bus_range[1] = fixup_one_level_bus_range(bridge->child, bus_range[1]);
-}
-
-/*
- * Apple MacRISC (U3, UniNorth, Bandit, Chaos) PCI controllers.
- *
- * The "Bandit" version is present in all early PCI PowerMacs,
- * and up to the first ones using Grackle. Some machines may
- * have 2 bandit controllers (2 PCI busses).
- *
- * "Chaos" is used in some "Bandit"-type machines as a bridge
- * for the separate display bus. It is accessed the same
- * way as bandit, but cannot be probed for devices. It therefore
- * has its own config access functions.
- *
- * The "UniNorth" version is present in all Core99 machines
- * (iBook, G4, new IMacs, and all the recent Apple machines).
- * It contains 3 controllers in one ASIC.
- *
- * The U3 is the bridge used on G5 machines. It contains on
- * AGP bus which is dealt with the old UniNorth access routines
- * and an HyperTransport bus which uses its own set of access
- * functions.
- */
-
-#define MACRISC_CFA0(devfn, off) \
- ((1 << (unsigned long)PCI_SLOT(dev_fn)) \
- | (((unsigned long)PCI_FUNC(dev_fn)) << 8) \
- | (((unsigned long)(off)) & 0xFCUL))
-
-#define MACRISC_CFA1(bus, devfn, off) \
- ((((unsigned long)(bus)) << 16) \
- |(((unsigned long)(devfn)) << 8) \
- |(((unsigned long)(off)) & 0xFCUL) \
- |1UL)
-
-static unsigned long __pmac macrisc_cfg_access(struct pci_controller* hose,
- u8 bus, u8 dev_fn, u8 offset)
-{
- unsigned int caddr;
-
- if (bus == hose->first_busno) {
- if (dev_fn < (11 << 3))
- return 0;
- caddr = MACRISC_CFA0(dev_fn, offset);
- } else
- caddr = MACRISC_CFA1(bus, dev_fn, offset);
-
- /* Uninorth will return garbage if we don't read back the value ! */
- do {
- out_le32(hose->cfg_addr, caddr);
- } while (in_le32(hose->cfg_addr) != caddr);
-
- offset &= has_uninorth ? 0x07 : 0x03;
- return ((unsigned long)hose->cfg_data) + offset;
-}
-
-static int __pmac macrisc_read_config(struct pci_bus *bus, unsigned int devfn,
- int offset, int len, u32 *val)
-{
- struct pci_controller *hose;
- unsigned long addr;
-
- hose = pci_bus_to_host(bus);
- if (hose == NULL)
- return PCIBIOS_DEVICE_NOT_FOUND;
-
- addr = macrisc_cfg_access(hose, bus->number, devfn, offset);
- if (!addr)
- return PCIBIOS_DEVICE_NOT_FOUND;
- /*
- * Note: the caller has already checked that offset is
- * suitably aligned and that len is 1, 2 or 4.
- */
- switch (len) {
- case 1:
- *val = in_8((u8 *)addr);
- break;
- case 2:
- *val = in_le16((u16 *)addr);
- break;
- default:
- *val = in_le32((u32 *)addr);
- break;
- }
- return PCIBIOS_SUCCESSFUL;
-}
-
-static int __pmac macrisc_write_config(struct pci_bus *bus, unsigned int devfn,
- int offset, int len, u32 val)
-{
- struct pci_controller *hose;
- unsigned long addr;
-
- hose = pci_bus_to_host(bus);
- if (hose == NULL)
- return PCIBIOS_DEVICE_NOT_FOUND;
-
- addr = macrisc_cfg_access(hose, bus->number, devfn, offset);
- if (!addr)
- return PCIBIOS_DEVICE_NOT_FOUND;
- /*
- * Note: the caller has already checked that offset is
- * suitably aligned and that len is 1, 2 or 4.
- */
- switch (len) {
- case 1:
- out_8((u8 *)addr, val);
- (void) in_8((u8 *)addr);
- break;
- case 2:
- out_le16((u16 *)addr, val);
- (void) in_le16((u16 *)addr);
- break;
- default:
- out_le32((u32 *)addr, val);
- (void) in_le32((u32 *)addr);
- break;
- }
- return PCIBIOS_SUCCESSFUL;
-}
-
-static struct pci_ops macrisc_pci_ops =
-{
- macrisc_read_config,
- macrisc_write_config
-};
-
-/*
- * These versions of U3 HyperTransport config space access ops do not
- * implement self-view of the HT host yet
- */
-
-/*
- * This function deals with some "special cases" devices.
- *
- * 0 -> No special case
- * 1 -> Skip the device but act as if the access was successfull
- * (return 0xff's on reads, eventually, cache config space
- * accesses in a later version)
- * -1 -> Hide the device (unsuccessful acess)
- */
-static int u3_ht_skip_device(struct pci_controller *hose,
- struct pci_bus *bus, unsigned int devfn)
-{
- struct device_node *busdn, *dn;
- int i;
-
- /* We only allow config cycles to devices that are in OF device-tree
- * as we are apparently having some weird things going on with some
- * revs of K2 on recent G5s
- */
- if (bus->self)
- busdn = pci_device_to_OF_node(bus->self);
- else
- busdn = hose->arch_data;
- for (dn = busdn->child; dn; dn = dn->sibling)
- if (dn->data && PCI_DN(dn)->devfn == devfn)
- break;
- if (dn == NULL)
- return -1;
-
- /*
- * When a device in K2 is powered down, we die on config
- * cycle accesses. Fix that here.
- */
- for (i=0; i<2; i++)
- if (k2_skiplist[i] == dn)
- return 1;
-
- return 0;
-}
-
-#define U3_HT_CFA0(devfn, off) \
- ((((unsigned long)devfn) << 8) | offset)
-#define U3_HT_CFA1(bus, devfn, off) \
- (U3_HT_CFA0(devfn, off) \
- + (((unsigned long)bus) << 16) \
- + 0x01000000UL)
-
-static unsigned long __pmac u3_ht_cfg_access(struct pci_controller* hose,
- u8 bus, u8 devfn, u8 offset)
-{
- if (bus == hose->first_busno) {
- /* For now, we don't self probe U3 HT bridge */
- if (PCI_SLOT(devfn) == 0)
- return 0;
- return ((unsigned long)hose->cfg_data) + U3_HT_CFA0(devfn, offset);
- } else
- return ((unsigned long)hose->cfg_data) + U3_HT_CFA1(bus, devfn, offset);
-}
-
-static int __pmac u3_ht_read_config(struct pci_bus *bus, unsigned int devfn,
- int offset, int len, u32 *val)
-{
- struct pci_controller *hose;
- unsigned long addr;
-
-
- hose = pci_bus_to_host(bus);
- if (hose == NULL)
- return PCIBIOS_DEVICE_NOT_FOUND;
-
- addr = u3_ht_cfg_access(hose, bus->number, devfn, offset);
- if (!addr)
- return PCIBIOS_DEVICE_NOT_FOUND;
-
- switch (u3_ht_skip_device(hose, bus, devfn)) {
- case 0:
- break;
- case 1:
- switch (len) {
- case 1:
- *val = 0xff; break;
- case 2:
- *val = 0xffff; break;
- default:
- *val = 0xfffffffful; break;
- }
- return PCIBIOS_SUCCESSFUL;
- default:
- return PCIBIOS_DEVICE_NOT_FOUND;
- }
-
- /*
- * Note: the caller has already checked that offset is
- * suitably aligned and that len is 1, 2 or 4.
- */
- switch (len) {
- case 1:
- *val = in_8((u8 *)addr);
- break;
- case 2:
- *val = in_le16((u16 *)addr);
- break;
- default:
- *val = in_le32((u32 *)addr);
- break;
- }
- return PCIBIOS_SUCCESSFUL;
-}
-
-static int __pmac u3_ht_write_config(struct pci_bus *bus, unsigned int devfn,
- int offset, int len, u32 val)
-{
- struct pci_controller *hose;
- unsigned long addr;
-
- hose = pci_bus_to_host(bus);
- if (hose == NULL)
- return PCIBIOS_DEVICE_NOT_FOUND;
-
- addr = u3_ht_cfg_access(hose, bus->number, devfn, offset);
- if (!addr)
- return PCIBIOS_DEVICE_NOT_FOUND;
-
- switch (u3_ht_skip_device(hose, bus, devfn)) {
- case 0:
- break;
- case 1:
- return PCIBIOS_SUCCESSFUL;
- default:
- return PCIBIOS_DEVICE_NOT_FOUND;
- }
-
- /*
- * Note: the caller has already checked that offset is
- * suitably aligned and that len is 1, 2 or 4.
- */
- switch (len) {
- case 1:
- out_8((u8 *)addr, val);
- (void) in_8((u8 *)addr);
- break;
- case 2:
- out_le16((u16 *)addr, val);
- (void) in_le16((u16 *)addr);
- break;
- default:
- out_le32((u32 *)addr, val);
- (void) in_le32((u32 *)addr);
- break;
- }
- return PCIBIOS_SUCCESSFUL;
-}
-
-static struct pci_ops u3_ht_pci_ops =
-{
- u3_ht_read_config,
- u3_ht_write_config
-};
-
-static void __init setup_u3_agp(struct pci_controller* hose)
-{
- /* On G5, we move AGP up to high bus number so we don't need
- * to reassign bus numbers for HT. If we ever have P2P bridges
- * on AGP, we'll have to move pci_assign_all_busses to the
- * pci_controller structure so we enable it for AGP and not for
- * HT childs.
- * We hard code the address because of the different size of
- * the reg address cell, we shall fix that by killing struct
- * reg_property and using some accessor functions instead
- */
- hose->first_busno = 0xf0;
- hose->last_busno = 0xff;
- has_uninorth = 1;
- hose->ops = &macrisc_pci_ops;
- hose->cfg_addr = ioremap(0xf0000000 + 0x800000, 0x1000);
- hose->cfg_data = ioremap(0xf0000000 + 0xc00000, 0x1000);
-
- u3_agp = hose;
-}
-
-static void __init setup_u3_ht(struct pci_controller* hose)
-{
- struct device_node *np = (struct device_node *)hose->arch_data;
- int i, cur;
-
- hose->ops = &u3_ht_pci_ops;
-
- /* We hard code the address because of the different size of
- * the reg address cell, we shall fix that by killing struct
- * reg_property and using some accessor functions instead
- */
- hose->cfg_data = (volatile unsigned char *)ioremap(0xf2000000, 0x02000000);
-
- /*
- * /ht node doesn't expose a "ranges" property, so we "remove" regions that
- * have been allocated to AGP. So far, this version of the code doesn't assign
- * any of the 0xfxxxxxxx "fine" memory regions to /ht.
- * We need to fix that sooner or later by either parsing all child "ranges"
- * properties or figuring out the U3 address space decoding logic and
- * then read it's configuration register (if any).
- */
- hose->io_base_phys = 0xf4000000;
- hose->io_base_virt = ioremap(hose->io_base_phys, 0x00400000);
- isa_io_base = pci_io_base = (unsigned long) hose->io_base_virt;
- hose->io_resource.name = np->full_name;
- hose->io_resource.start = 0;
- hose->io_resource.end = 0x003fffff;
- hose->io_resource.flags = IORESOURCE_IO;
- hose->pci_mem_offset = 0;
- hose->first_busno = 0;
- hose->last_busno = 0xef;
- hose->mem_resources[0].name = np->full_name;
- hose->mem_resources[0].start = 0x80000000;
- hose->mem_resources[0].end = 0xefffffff;
- hose->mem_resources[0].flags = IORESOURCE_MEM;
-
- if (u3_agp == NULL) {
- DBG("U3 has no AGP, using full resource range\n");
- return;
- }
-
- /* We "remove" the AGP resources from the resources allocated to HT, that
- * is we create "holes". However, that code does assumptions that so far
- * happen to be true (cross fingers...), typically that resources in the
- * AGP node are properly ordered
- */
- cur = 0;
- for (i=0; i<3; i++) {
- struct resource *res = &u3_agp->mem_resources[i];
- if (res->flags != IORESOURCE_MEM)
- continue;
- /* We don't care about "fine" resources */
- if (res->start >= 0xf0000000)
- continue;
- /* Check if it's just a matter of "shrinking" us in one direction */
- if (hose->mem_resources[cur].start == res->start) {
- DBG("U3/HT: shrink start of %d, %08lx -> %08lx\n",
- cur, hose->mem_resources[cur].start, res->end + 1);
- hose->mem_resources[cur].start = res->end + 1;
- continue;
- }
- if (hose->mem_resources[cur].end == res->end) {
- DBG("U3/HT: shrink end of %d, %08lx -> %08lx\n",
- cur, hose->mem_resources[cur].end, res->start - 1);
- hose->mem_resources[cur].end = res->start - 1;
- continue;
- }
- /* No, it's not the case, we need a hole */
- if (cur == 2) {
- /* not enough resources for a hole, we drop part of the range */
- printk(KERN_WARNING "Running out of resources for /ht host !\n");
- hose->mem_resources[cur].end = res->start - 1;
- continue;
- }
- cur++;
- DBG("U3/HT: hole, %d end at %08lx, %d start at %08lx\n",
- cur-1, res->start - 1, cur, res->end + 1);
- hose->mem_resources[cur].name = np->full_name;
- hose->mem_resources[cur].flags = IORESOURCE_MEM;
- hose->mem_resources[cur].start = res->end + 1;
- hose->mem_resources[cur].end = hose->mem_resources[cur-1].end;
- hose->mem_resources[cur-1].end = res->start - 1;
- }
-}
-
-static void __init pmac_process_bridge_OF_ranges(struct pci_controller *hose,
- struct device_node *dev, int primary)
-{
- static unsigned int static_lc_ranges[2024];
- unsigned int *dt_ranges, *lc_ranges, *ranges, *prev;
- unsigned int size;
- int rlen = 0, orig_rlen;
- int memno = 0;
- struct resource *res;
- int np, na = prom_n_addr_cells(dev);
-
- np = na + 5;
-
- /* First we try to merge ranges to fix a problem with some pmacs
- * that can have more than 3 ranges, fortunately using contiguous
- * addresses -- BenH
- */
- dt_ranges = (unsigned int *) get_property(dev, "ranges", &rlen);
- if (!dt_ranges)
- return;
- /* lc_ranges = alloc_bootmem(rlen);*/
- lc_ranges = static_lc_ranges;
- if (!lc_ranges)
- return; /* what can we do here ? */
- memcpy(lc_ranges, dt_ranges, rlen);
- orig_rlen = rlen;
-
- /* Let's work on a copy of the "ranges" property instead of damaging
- * the device-tree image in memory
- */
- ranges = lc_ranges;
- prev = NULL;
- while ((rlen -= np * sizeof(unsigned int)) >= 0) {
- if (prev) {
- if (prev[0] == ranges[0] && prev[1] == ranges[1] &&
- (prev[2] + prev[na+4]) == ranges[2] &&
- (prev[na+2] + prev[na+4]) == ranges[na+2]) {
- prev[na+4] += ranges[na+4];
- ranges[0] = 0;
- ranges += np;
- continue;
- }
- }
- prev = ranges;
- ranges += np;
- }
-
- /*
- * The ranges property is laid out as an array of elements,
- * each of which comprises:
- * cells 0 - 2: a PCI address
- * cells 3 or 3+4: a CPU physical address
- * (size depending on dev->n_addr_cells)
- * cells 4+5 or 5+6: the size of the range
- */
- ranges = lc_ranges;
- rlen = orig_rlen;
- while (ranges && (rlen -= np * sizeof(unsigned int)) >= 0) {
- res = NULL;
- size = ranges[na+4];
- switch (ranges[0] >> 24) {
- case 1: /* I/O space */
- if (ranges[2] != 0)
- break;
- hose->io_base_phys = ranges[na+2];
- /* limit I/O space to 16MB */
- if (size > 0x01000000)
- size = 0x01000000;
- hose->io_base_virt = ioremap(ranges[na+2], size);
- if (primary)
- isa_io_base = (unsigned long) hose->io_base_virt;
- res = &hose->io_resource;
- res->flags = IORESOURCE_IO;
- res->start = ranges[2];
- break;
- case 2: /* memory space */
- memno = 0;
- if (ranges[1] == 0 && ranges[2] == 0
- && ranges[na+4] <= (16 << 20)) {
- /* 1st 16MB, i.e. ISA memory area */
-#if 0
- if (primary)
- isa_mem_base = ranges[na+2];
-#endif
- memno = 1;
- }
- while (memno < 3 && hose->mem_resources[memno].flags)
- ++memno;
- if (memno == 0)
- hose->pci_mem_offset = ranges[na+2] - ranges[2];
- if (memno < 3) {
- res = &hose->mem_resources[memno];
- res->flags = IORESOURCE_MEM;
- res->start = ranges[na+2];
- }
- break;
- }
- if (res != NULL) {
- res->name = dev->full_name;
- res->end = res->start + size - 1;
- res->parent = NULL;
- res->sibling = NULL;
- res->child = NULL;
- }
- ranges += np;
- }
-}
-
-/*
- * We assume that if we have a G3 powermac, we have one bridge called
- * "pci" (a MPC106) and no bandit or chaos bridges, and contrariwise,
- * if we have one or more bandit or chaos bridges, we don't have a MPC106.
- */
-static int __init add_bridge(struct device_node *dev)
-{
- int len;
- struct pci_controller *hose;
- char* disp_name;
- int *bus_range;
- int primary = 1;
- struct property *of_prop;
-
- DBG("Adding PCI host bridge %s\n", dev->full_name);
-
- bus_range = (int *) get_property(dev, "bus-range", &len);
- if (bus_range == NULL || len < 2 * sizeof(int)) {
- printk(KERN_WARNING "Can't get bus-range for %s, assume bus 0\n",
- dev->full_name);
- }
-
- hose = alloc_bootmem(sizeof(struct pci_controller));
- if (hose == NULL)
- return -ENOMEM;
- pci_setup_pci_controller(hose);
-
- hose->arch_data = dev;
- hose->first_busno = bus_range ? bus_range[0] : 0;
- hose->last_busno = bus_range ? bus_range[1] : 0xff;
-
- of_prop = alloc_bootmem(sizeof(struct property) +
- sizeof(hose->global_number));
- if (of_prop) {
- memset(of_prop, 0, sizeof(struct property));
- of_prop->name = "linux,pci-domain";
- of_prop->length = sizeof(hose->global_number);
- of_prop->value = (unsigned char *)&of_prop[1];
- memcpy(of_prop->value, &hose->global_number, sizeof(hose->global_number));
- prom_add_property(dev, of_prop);
- }
-
- disp_name = NULL;
- if (device_is_compatible(dev, "u3-agp")) {
- setup_u3_agp(hose);
- disp_name = "U3-AGP";
- primary = 0;
- } else if (device_is_compatible(dev, "u3-ht")) {
- setup_u3_ht(hose);
- disp_name = "U3-HT";
- primary = 1;
- }
- printk(KERN_INFO "Found %s PCI host bridge. Firmware bus number: %d->%d\n",
- disp_name, hose->first_busno, hose->last_busno);
-
- /* Interpret the "ranges" property */
- /* This also maps the I/O region and sets isa_io/mem_base */
- pmac_process_bridge_OF_ranges(hose, dev, primary);
-
- /* Fixup "bus-range" OF property */
- fixup_bus_range(dev);
-
- return 0;
-}
-
-/*
- * We use our own read_irq_line here because PCI_INTERRUPT_PIN is
- * crap on some of Apple ASICs. We unconditionally use the Open Firmware
- * interrupt number as this is always right.
- */
-static int pmac_pci_read_irq_line(struct pci_dev *pci_dev)
-{
- struct device_node *node;
-
- node = pci_device_to_OF_node(pci_dev);
- if (node == NULL)
- return -1;
- if (node->n_intrs == 0)
- return -1;
- pci_dev->irq = node->intrs[0].line;
- pci_write_config_byte(pci_dev, PCI_INTERRUPT_LINE, pci_dev->irq);
-
- return 0;
-}
-
-void __init pmac_pcibios_fixup(void)
-{
- struct pci_dev *dev = NULL;
-
- for_each_pci_dev(dev)
- pmac_pci_read_irq_line(dev);
-}
-
-static void __init pmac_fixup_phb_resources(void)
-{
- struct pci_controller *hose, *tmp;
-
- list_for_each_entry_safe(hose, tmp, &hose_list, list_node) {
- unsigned long offset = (unsigned long)hose->io_base_virt - pci_io_base;
- hose->io_resource.start += offset;
- hose->io_resource.end += offset;
- printk(KERN_INFO "PCI Host %d, io start: %lx; io end: %lx\n",
- hose->global_number,
- hose->io_resource.start, hose->io_resource.end);
- }
-}
-
-void __init pmac_pci_init(void)
-{
- struct device_node *np, *root;
- struct device_node *ht = NULL;
-
- /* Probe root PCI hosts, that is on U3 the AGP host and the
- * HyperTransport host. That one is actually "kept" around
- * and actually added last as it's resource management relies
- * on the AGP resources to have been setup first
- */
- root = of_find_node_by_path("/");
- if (root == NULL) {
- printk(KERN_CRIT "pmac_find_bridges: can't find root of device tree\n");
- return;
- }
- for (np = NULL; (np = of_get_next_child(root, np)) != NULL;) {
- if (np->name == NULL)
- continue;
- if (strcmp(np->name, "pci") == 0) {
- if (add_bridge(np) == 0)
- of_node_get(np);
- }
- if (strcmp(np->name, "ht") == 0) {
- of_node_get(np);
- ht = np;
- }
- }
- of_node_put(root);
-
- /* Now setup the HyperTransport host if we found any
- */
- if (ht && add_bridge(ht) != 0)
- of_node_put(ht);
-
- /* Fixup the IO resources on our host bridges as the common code
- * does it only for childs of the host bridges
- */
- pmac_fixup_phb_resources();
-
- /* Setup the linkage between OF nodes and PHBs */
- pci_devs_phb_init();
-
- /* Fixup the PCI<->OF mapping for U3 AGP due to bus renumbering. We
- * assume there is no P2P bridge on the AGP bus, which should be a
- * safe assumptions hopefully.
- */
- if (u3_agp) {
- struct device_node *np = u3_agp->arch_data;
- PCI_DN(np)->busno = 0xf0;
- for (np = np->child; np; np = np->sibling)
- PCI_DN(np)->busno = 0xf0;
- }
-
- pmac_check_ht_link();
-
- /* Tell pci.c to not use the common resource allocation mecanism */
- pci_probe_only = 1;
-
- /* Allow all IO */
- io_page_mask = -1;
-}
-
-/*
- * Disable second function on K2-SATA, it's broken
- * and disable IO BARs on first one
- */
-static void fixup_k2_sata(struct pci_dev* dev)
-{
- int i;
- u16 cmd;
-
- if (PCI_FUNC(dev->devfn) > 0) {
- pci_read_config_word(dev, PCI_COMMAND, &cmd);
- cmd &= ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY);
- pci_write_config_word(dev, PCI_COMMAND, cmd);
- for (i = 0; i < 6; i++) {
- dev->resource[i].start = dev->resource[i].end = 0;
- dev->resource[i].flags = 0;
- pci_write_config_dword(dev, PCI_BASE_ADDRESS_0 + 4 * i, 0);
- }
- } else {
- pci_read_config_word(dev, PCI_COMMAND, &cmd);
- cmd &= ~PCI_COMMAND_IO;
- pci_write_config_word(dev, PCI_COMMAND, cmd);
- for (i = 0; i < 5; i++) {
- dev->resource[i].start = dev->resource[i].end = 0;
- dev->resource[i].flags = 0;
- pci_write_config_dword(dev, PCI_BASE_ADDRESS_0 + 4 * i, 0);
- }
- }
-}
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SERVERWORKS, 0x0240, fixup_k2_sata);
-
diff --git a/arch/ppc64/kernel/pmac_setup.c b/arch/ppc64/kernel/pmac_setup.c
deleted file mode 100644
index fa8121d53b89..000000000000
--- a/arch/ppc64/kernel/pmac_setup.c
+++ /dev/null
@@ -1,525 +0,0 @@
-/*
- * arch/ppc/platforms/setup.c
- *
- * PowerPC version
- * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
- *
- * Adapted for Power Macintosh by Paul Mackerras
- * Copyright (C) 1996 Paul Mackerras (paulus@cs.anu.edu.au)
- *
- * Derived from "arch/alpha/kernel/setup.c"
- * Copyright (C) 1995 Linus Torvalds
- *
- * Maintained by Benjamin Herrenschmidt (benh@kernel.crashing.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.
- *
- */
-
-/*
- * bootup setup stuff..
- */
-
-#undef DEBUG
-
-#include <linux/config.h>
-#include <linux/init.h>
-#include <linux/errno.h>
-#include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/stddef.h>
-#include <linux/unistd.h>
-#include <linux/ptrace.h>
-#include <linux/slab.h>
-#include <linux/user.h>
-#include <linux/a.out.h>
-#include <linux/tty.h>
-#include <linux/string.h>
-#include <linux/delay.h>
-#include <linux/ioport.h>
-#include <linux/major.h>
-#include <linux/initrd.h>
-#include <linux/vt_kern.h>
-#include <linux/console.h>
-#include <linux/ide.h>
-#include <linux/pci.h>
-#include <linux/adb.h>
-#include <linux/cuda.h>
-#include <linux/pmu.h>
-#include <linux/irq.h>
-#include <linux/seq_file.h>
-#include <linux/root_dev.h>
-#include <linux/bitops.h>
-
-#include <asm/processor.h>
-#include <asm/sections.h>
-#include <asm/prom.h>
-#include <asm/system.h>
-#include <asm/io.h>
-#include <asm/pci-bridge.h>
-#include <asm/iommu.h>
-#include <asm/machdep.h>
-#include <asm/dma.h>
-#include <asm/btext.h>
-#include <asm/cputable.h>
-#include <asm/pmac_feature.h>
-#include <asm/time.h>
-#include <asm/of_device.h>
-#include <asm/lmb.h>
-#include <asm/smu.h>
-#include <asm/pmc.h>
-
-#include "pmac.h"
-#include "mpic.h"
-
-#ifdef DEBUG
-#define DBG(fmt...) udbg_printf(fmt)
-#else
-#define DBG(fmt...)
-#endif
-
-static int current_root_goodness = -1;
-#define DEFAULT_ROOT_DEVICE Root_SDA1 /* sda1 - slightly silly choice */
-
-extern int powersave_nap;
-int sccdbg;
-
-sys_ctrler_t sys_ctrler;
-EXPORT_SYMBOL(sys_ctrler);
-
-#ifdef CONFIG_PMAC_SMU
-unsigned long smu_cmdbuf_abs;
-EXPORT_SYMBOL(smu_cmdbuf_abs);
-#endif
-
-extern void udbg_init_scc(struct device_node *np);
-
-static void __pmac pmac_show_cpuinfo(struct seq_file *m)
-{
- struct device_node *np;
- char *pp;
- int plen;
- char* mbname;
- int mbmodel = pmac_call_feature(PMAC_FTR_GET_MB_INFO, NULL,
- PMAC_MB_INFO_MODEL, 0);
- unsigned int mbflags = pmac_call_feature(PMAC_FTR_GET_MB_INFO, NULL,
- PMAC_MB_INFO_FLAGS, 0);
-
- if (pmac_call_feature(PMAC_FTR_GET_MB_INFO, NULL, PMAC_MB_INFO_NAME,
- (long)&mbname) != 0)
- mbname = "Unknown";
-
- /* find motherboard type */
- seq_printf(m, "machine\t\t: ");
- np = of_find_node_by_path("/");
- if (np != NULL) {
- pp = (char *) get_property(np, "model", NULL);
- if (pp != NULL)
- seq_printf(m, "%s\n", pp);
- else
- seq_printf(m, "PowerMac\n");
- pp = (char *) get_property(np, "compatible", &plen);
- if (pp != NULL) {
- seq_printf(m, "motherboard\t:");
- while (plen > 0) {
- int l = strlen(pp) + 1;
- seq_printf(m, " %s", pp);
- plen -= l;
- pp += l;
- }
- seq_printf(m, "\n");
- }
- of_node_put(np);
- } else
- seq_printf(m, "PowerMac\n");
-
- /* print parsed model */
- seq_printf(m, "detected as\t: %d (%s)\n", mbmodel, mbname);
- seq_printf(m, "pmac flags\t: %08x\n", mbflags);
-
- /* Indicate newworld */
- seq_printf(m, "pmac-generation\t: NewWorld\n");
-}
-
-
-static void __init pmac_setup_arch(void)
-{
- /* init to some ~sane value until calibrate_delay() runs */
- loops_per_jiffy = 50000000;
-
- /* Probe motherboard chipset */
- pmac_feature_init();
-#if 0
- /* Lock-enable the SCC channel used for debug */
- if (sccdbg) {
- np = of_find_node_by_name(NULL, "escc");
- if (np)
- pmac_call_feature(PMAC_FTR_SCC_ENABLE, np,
- PMAC_SCC_ASYNC | PMAC_SCC_FLAG_XMON, 1);
- }
-#endif
- /* We can NAP */
- powersave_nap = 1;
-
-#ifdef CONFIG_ADB_PMU
- /* Initialize the PMU if any */
- find_via_pmu();
-#endif
-#ifdef CONFIG_PMAC_SMU
- /* Initialize the SMU if any */
- smu_init();
-#endif
-
- /* Init NVRAM access */
- pmac_nvram_init();
-
- /* Setup SMP callback */
-#ifdef CONFIG_SMP
- pmac_setup_smp();
-#endif
-
- /* Lookup PCI hosts */
- pmac_pci_init();
-
-#ifdef CONFIG_DUMMY_CONSOLE
- conswitchp = &dummy_con;
-#endif
-
- printk(KERN_INFO "Using native/NAP idle loop\n");
-}
-
-#ifdef CONFIG_SCSI
-void note_scsi_host(struct device_node *node, void *host)
-{
- /* Obsolete */
-}
-#endif
-
-
-static int initializing = 1;
-
-static int pmac_late_init(void)
-{
- initializing = 0;
- return 0;
-}
-
-late_initcall(pmac_late_init);
-
-/* can't be __init - can be called whenever a disk is first accessed */
-void __pmac note_bootable_part(dev_t dev, int part, int goodness)
-{
- extern dev_t boot_dev;
- char *p;
-
- if (!initializing)
- return;
- if ((goodness <= current_root_goodness) &&
- ROOT_DEV != DEFAULT_ROOT_DEVICE)
- return;
- p = strstr(saved_command_line, "root=");
- if (p != NULL && (p == saved_command_line || p[-1] == ' '))
- return;
-
- if (!boot_dev || dev == boot_dev) {
- ROOT_DEV = dev + part;
- boot_dev = 0;
- current_root_goodness = goodness;
- }
-}
-
-static void __pmac pmac_restart(char *cmd)
-{
- switch(sys_ctrler) {
-#ifdef CONFIG_ADB_PMU
- case SYS_CTRLER_PMU:
- pmu_restart();
- break;
-#endif
-
-#ifdef CONFIG_PMAC_SMU
- case SYS_CTRLER_SMU:
- smu_restart();
- break;
-#endif
- default:
- ;
- }
-}
-
-static void __pmac pmac_power_off(void)
-{
- switch(sys_ctrler) {
-#ifdef CONFIG_ADB_PMU
- case SYS_CTRLER_PMU:
- pmu_shutdown();
- break;
-#endif
-#ifdef CONFIG_PMAC_SMU
- case SYS_CTRLER_SMU:
- smu_shutdown();
- break;
-#endif
- default:
- ;
- }
-}
-
-static void __pmac pmac_halt(void)
-{
- pmac_power_off();
-}
-
-#ifdef CONFIG_BOOTX_TEXT
-static void btext_putc(unsigned char c)
-{
- btext_drawchar(c);
-}
-
-static void __init init_boot_display(void)
-{
- char *name;
- struct device_node *np = NULL;
- int rc = -ENODEV;
-
- printk("trying to initialize btext ...\n");
-
- name = (char *)get_property(of_chosen, "linux,stdout-path", NULL);
- if (name != NULL) {
- np = of_find_node_by_path(name);
- if (np != NULL) {
- if (strcmp(np->type, "display") != 0) {
- printk("boot stdout isn't a display !\n");
- of_node_put(np);
- np = NULL;
- }
- }
- }
- if (np)
- rc = btext_initialize(np);
- if (rc == 0)
- return;
-
- for (np = NULL; (np = of_find_node_by_type(np, "display"));) {
- if (get_property(np, "linux,opened", NULL)) {
- printk("trying %s ...\n", np->full_name);
- rc = btext_initialize(np);
- printk("result: %d\n", rc);
- }
- if (rc == 0)
- return;
- }
-}
-#endif /* CONFIG_BOOTX_TEXT */
-
-/*
- * Early initialization.
- */
-static void __init pmac_init_early(void)
-{
- DBG(" -> pmac_init_early\n");
-
- /* Initialize hash table, from now on, we can take hash faults
- * and call ioremap
- */
- hpte_init_native();
-
- /* Init SCC */
- if (strstr(cmd_line, "sccdbg")) {
- sccdbg = 1;
- udbg_init_scc(NULL);
- }
-#ifdef CONFIG_BOOTX_TEXT
- else {
- init_boot_display();
-
- udbg_putc = btext_putc;
- }
-#endif /* CONFIG_BOOTX_TEXT */
-
- /* Setup interrupt mapping options */
- ppc64_interrupt_controller = IC_OPEN_PIC;
-
- iommu_init_early_u3();
-
- DBG(" <- pmac_init_early\n");
-}
-
-static int pmac_u3_cascade(struct pt_regs *regs, void *data)
-{
- return mpic_get_one_irq((struct mpic *)data, regs);
-}
-
-static __init void pmac_init_IRQ(void)
-{
- struct device_node *irqctrler = NULL;
- struct device_node *irqctrler2 = NULL;
- struct device_node *np = NULL;
- struct mpic *mpic1, *mpic2;
-
- /* We first try to detect Apple's new Core99 chipset, since mac-io
- * is quite different on those machines and contains an IBM MPIC2.
- */
- while ((np = of_find_node_by_type(np, "open-pic")) != NULL) {
- struct device_node *parent = of_get_parent(np);
- if (parent && !strcmp(parent->name, "u3"))
- irqctrler2 = of_node_get(np);
- else
- irqctrler = of_node_get(np);
- of_node_put(parent);
- }
- if (irqctrler != NULL && irqctrler->n_addrs > 0) {
- unsigned char senses[128];
-
- printk(KERN_INFO "PowerMac using OpenPIC irq controller at 0x%08x\n",
- (unsigned int)irqctrler->addrs[0].address);
-
- prom_get_irq_senses(senses, 0, 128);
- mpic1 = mpic_alloc(irqctrler->addrs[0].address,
- MPIC_PRIMARY | MPIC_WANTS_RESET,
- 0, 0, 128, 256, senses, 128, " K2-MPIC ");
- BUG_ON(mpic1 == NULL);
- mpic_init(mpic1);
-
- if (irqctrler2 != NULL && irqctrler2->n_intrs > 0 &&
- irqctrler2->n_addrs > 0) {
- printk(KERN_INFO "Slave OpenPIC at 0x%08x hooked on IRQ %d\n",
- (u32)irqctrler2->addrs[0].address,
- irqctrler2->intrs[0].line);
-
- pmac_call_feature(PMAC_FTR_ENABLE_MPIC, irqctrler2, 0, 0);
- prom_get_irq_senses(senses, 128, 128 + 128);
-
- /* We don't need to set MPIC_BROKEN_U3 here since we don't have
- * hypertransport interrupts routed to it
- */
- mpic2 = mpic_alloc(irqctrler2->addrs[0].address,
- MPIC_BIG_ENDIAN | MPIC_WANTS_RESET,
- 0, 128, 128, 0, senses, 128, " U3-MPIC ");
- BUG_ON(mpic2 == NULL);
- mpic_init(mpic2);
- mpic_setup_cascade(irqctrler2->intrs[0].line,
- pmac_u3_cascade, mpic2);
- }
- }
- of_node_put(irqctrler);
- of_node_put(irqctrler2);
-}
-
-static void __init pmac_progress(char *s, unsigned short hex)
-{
- if (sccdbg) {
- udbg_puts(s);
- udbg_puts("\n");
- }
-#ifdef CONFIG_BOOTX_TEXT
- else if (boot_text_mapped) {
- btext_drawstring(s);
- btext_drawstring("\n");
- }
-#endif /* CONFIG_BOOTX_TEXT */
-}
-
-/*
- * pmac has no legacy IO, anything calling this function has to
- * fail or bad things will happen
- */
-static int pmac_check_legacy_ioport(unsigned int baseport)
-{
- return -ENODEV;
-}
-
-static int __init pmac_declare_of_platform_devices(void)
-{
- struct device_node *np, *npp;
-
- npp = of_find_node_by_name(NULL, "u3");
- if (npp) {
- for (np = NULL; (np = of_get_next_child(npp, np)) != NULL;) {
- if (strncmp(np->name, "i2c", 3) == 0) {
- of_platform_device_create(np, "u3-i2c", NULL);
- of_node_put(np);
- break;
- }
- }
- of_node_put(npp);
- }
- npp = of_find_node_by_type(NULL, "smu");
- if (npp) {
- of_platform_device_create(npp, "smu", NULL);
- of_node_put(npp);
- }
-
- return 0;
-}
-
-device_initcall(pmac_declare_of_platform_devices);
-
-/*
- * Called very early, MMU is off, device-tree isn't unflattened
- */
-static int __init pmac_probe(int platform)
-{
- if (platform != PLATFORM_POWERMAC)
- return 0;
- /*
- * On U3, the DART (iommu) must be allocated now since it
- * has an impact on htab_initialize (due to the large page it
- * occupies having to be broken up so the DART itself is not
- * part of the cacheable linar mapping
- */
- alloc_u3_dart_table();
-
-#ifdef CONFIG_PMAC_SMU
- /*
- * SMU based G5s need some memory below 2Gb, at least the current
- * driver needs that. We have to allocate it now. We allocate 4k
- * (1 small page) for now.
- */
- smu_cmdbuf_abs = lmb_alloc_base(4096, 4096, 0x80000000UL);
-#endif /* CONFIG_PMAC_SMU */
-
- return 1;
-}
-
-static int pmac_probe_mode(struct pci_bus *bus)
-{
- struct device_node *node = bus->sysdata;
-
- /* We need to use normal PCI probing for the AGP bus,
- since the device for the AGP bridge isn't in the tree. */
- if (bus->self == NULL && device_is_compatible(node, "u3-agp"))
- return PCI_PROBE_NORMAL;
-
- return PCI_PROBE_DEVTREE;
-}
-
-struct machdep_calls __initdata pmac_md = {
-#ifdef CONFIG_HOTPLUG_CPU
- .cpu_die = generic_mach_cpu_die,
-#endif
- .probe = pmac_probe,
- .setup_arch = pmac_setup_arch,
- .init_early = pmac_init_early,
- .get_cpuinfo = pmac_show_cpuinfo,
- .init_IRQ = pmac_init_IRQ,
- .get_irq = mpic_get_irq,
- .pcibios_fixup = pmac_pcibios_fixup,
- .pci_probe_mode = pmac_probe_mode,
- .restart = pmac_restart,
- .power_off = pmac_power_off,
- .halt = pmac_halt,
- .get_boot_time = pmac_get_boot_time,
- .set_rtc_time = pmac_set_rtc_time,
- .get_rtc_time = pmac_get_rtc_time,
- .calibrate_decr = pmac_calibrate_decr,
- .feature_call = pmac_do_feature_call,
- .progress = pmac_progress,
- .check_legacy_ioport = pmac_check_legacy_ioport,
- .idle_loop = native_idle,
- .enable_pmcs = power4_enable_pmcs,
-};
diff --git a/arch/ppc64/kernel/pmac_smp.c b/arch/ppc64/kernel/pmac_smp.c
deleted file mode 100644
index a23de37227bf..000000000000
--- a/arch/ppc64/kernel/pmac_smp.c
+++ /dev/null
@@ -1,330 +0,0 @@
-/*
- * SMP support for power macintosh.
- *
- * We support both the old "powersurge" SMP architecture
- * and the current Core99 (G4 PowerMac) machines.
- *
- * Note that we don't support the very first rev. of
- * Apple/DayStar 2 CPUs board, the one with the funky
- * watchdog. Hopefully, none of these should be there except
- * maybe internally to Apple. I should probably still add some
- * code to detect this card though and disable SMP. --BenH.
- *
- * Support Macintosh G4 SMP by Troy Benjegerdes (hozer@drgw.net)
- * and Ben Herrenschmidt <benh@kernel.crashing.org>.
- *
- * Support for DayStar quad CPU cards
- * Copyright (C) XLR8, Inc. 1994-2000
- *
- * 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.
- */
-
-#undef DEBUG
-
-#include <linux/config.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/smp.h>
-#include <linux/smp_lock.h>
-#include <linux/interrupt.h>
-#include <linux/kernel_stat.h>
-#include <linux/init.h>
-#include <linux/spinlock.h>
-#include <linux/errno.h>
-#include <linux/irq.h>
-
-#include <asm/ptrace.h>
-#include <asm/atomic.h>
-#include <asm/irq.h>
-#include <asm/page.h>
-#include <asm/pgtable.h>
-#include <asm/sections.h>
-#include <asm/io.h>
-#include <asm/prom.h>
-#include <asm/smp.h>
-#include <asm/machdep.h>
-#include <asm/pmac_feature.h>
-#include <asm/time.h>
-#include <asm/cacheflush.h>
-#include <asm/keylargo.h>
-#include <asm/pmac_low_i2c.h>
-
-#include "mpic.h"
-
-#ifdef DEBUG
-#define DBG(fmt...) udbg_printf(fmt)
-#else
-#define DBG(fmt...)
-#endif
-
-extern void pmac_secondary_start_1(void);
-extern void pmac_secondary_start_2(void);
-extern void pmac_secondary_start_3(void);
-
-extern struct smp_ops_t *smp_ops;
-
-static void (*pmac_tb_freeze)(int freeze);
-static struct device_node *pmac_tb_clock_chip_host;
-static u8 pmac_tb_pulsar_addr;
-static DEFINE_SPINLOCK(timebase_lock);
-static unsigned long timebase;
-
-static void smp_core99_cypress_tb_freeze(int freeze)
-{
- u8 data;
- int rc;
-
- /* Strangely, the device-tree says address is 0xd2, but darwin
- * accesses 0xd0 ...
- */
- pmac_low_i2c_setmode(pmac_tb_clock_chip_host, pmac_low_i2c_mode_combined);
- rc = pmac_low_i2c_xfer(pmac_tb_clock_chip_host,
- 0xd0 | pmac_low_i2c_read,
- 0x81, &data, 1);
- if (rc != 0)
- goto bail;
-
- data = (data & 0xf3) | (freeze ? 0x00 : 0x0c);
-
- pmac_low_i2c_setmode(pmac_tb_clock_chip_host, pmac_low_i2c_mode_stdsub);
- rc = pmac_low_i2c_xfer(pmac_tb_clock_chip_host,
- 0xd0 | pmac_low_i2c_write,
- 0x81, &data, 1);
-
- bail:
- if (rc != 0) {
- printk("Cypress Timebase %s rc: %d\n",
- freeze ? "freeze" : "unfreeze", rc);
- panic("Timebase freeze failed !\n");
- }
-}
-
-static void smp_core99_pulsar_tb_freeze(int freeze)
-{
- u8 data;
- int rc;
-
- pmac_low_i2c_setmode(pmac_tb_clock_chip_host, pmac_low_i2c_mode_combined);
- rc = pmac_low_i2c_xfer(pmac_tb_clock_chip_host,
- pmac_tb_pulsar_addr | pmac_low_i2c_read,
- 0x2e, &data, 1);
- if (rc != 0)
- goto bail;
-
- data = (data & 0x88) | (freeze ? 0x11 : 0x22);
-
- pmac_low_i2c_setmode(pmac_tb_clock_chip_host, pmac_low_i2c_mode_stdsub);
- rc = pmac_low_i2c_xfer(pmac_tb_clock_chip_host,
- pmac_tb_pulsar_addr | pmac_low_i2c_write,
- 0x2e, &data, 1);
- bail:
- if (rc != 0) {
- printk(KERN_ERR "Pulsar Timebase %s rc: %d\n",
- freeze ? "freeze" : "unfreeze", rc);
- panic("Timebase freeze failed !\n");
- }
-}
-
-
-static void smp_core99_give_timebase(void)
-{
- /* Open i2c bus for synchronous access */
- if (pmac_low_i2c_open(pmac_tb_clock_chip_host, 0))
- panic("Can't open i2c for TB sync !\n");
-
- spin_lock(&timebase_lock);
- (*pmac_tb_freeze)(1);
- mb();
- timebase = get_tb();
- spin_unlock(&timebase_lock);
-
- while (timebase)
- barrier();
-
- spin_lock(&timebase_lock);
- (*pmac_tb_freeze)(0);
- spin_unlock(&timebase_lock);
-
- /* Close i2c bus */
- pmac_low_i2c_close(pmac_tb_clock_chip_host);
-}
-
-
-static void __devinit smp_core99_take_timebase(void)
-{
- while (!timebase)
- barrier();
- spin_lock(&timebase_lock);
- set_tb(timebase >> 32, timebase & 0xffffffff);
- timebase = 0;
- spin_unlock(&timebase_lock);
-}
-
-
-static int __init smp_core99_probe(void)
-{
- struct device_node *cpus;
- struct device_node *cc;
- int ncpus = 0;
-
- /* Maybe use systemconfiguration here ? */
- if (ppc_md.progress) ppc_md.progress("smp_core99_probe", 0x345);
-
- /* Count CPUs in the device-tree */
- for (cpus = NULL; (cpus = of_find_node_by_type(cpus, "cpu")) != NULL;)
- ++ncpus;
-
- printk(KERN_INFO "PowerMac SMP probe found %d cpus\n", ncpus);
-
- /* Nothing more to do if less than 2 of them */
- if (ncpus <= 1)
- return 1;
-
- /* HW sync only on these platforms */
- if (!machine_is_compatible("PowerMac7,2") &&
- !machine_is_compatible("PowerMac7,3") &&
- !machine_is_compatible("RackMac3,1"))
- goto nohwsync;
-
- /* Look for the clock chip */
- for (cc = NULL; (cc = of_find_node_by_name(cc, "i2c-hwclock")) != NULL;) {
- struct device_node *p = of_get_parent(cc);
- u32 *reg;
- int ok;
- ok = p && device_is_compatible(p, "uni-n-i2c");
- if (!ok)
- goto next;
- reg = (u32 *)get_property(cc, "reg", NULL);
- if (reg == NULL)
- goto next;
- switch (*reg) {
- case 0xd2:
- if (device_is_compatible(cc, "pulsar-legacy-slewing")) {
- pmac_tb_freeze = smp_core99_pulsar_tb_freeze;
- pmac_tb_pulsar_addr = 0xd2;
- printk(KERN_INFO "Timebase clock is Pulsar chip\n");
- } else if (device_is_compatible(cc, "cy28508")) {
- pmac_tb_freeze = smp_core99_cypress_tb_freeze;
- printk(KERN_INFO "Timebase clock is Cypress chip\n");
- }
- break;
- case 0xd4:
- pmac_tb_freeze = smp_core99_pulsar_tb_freeze;
- pmac_tb_pulsar_addr = 0xd4;
- printk(KERN_INFO "Timebase clock is Pulsar chip\n");
- break;
- }
- if (pmac_tb_freeze != NULL) {
- pmac_tb_clock_chip_host = p;
- smp_ops->give_timebase = smp_core99_give_timebase;
- smp_ops->take_timebase = smp_core99_take_timebase;
- of_node_put(cc);
- of_node_put(p);
- break;
- }
- next:
- of_node_put(p);
- }
-
- nohwsync:
- mpic_request_ipis();
-
- return ncpus;
-}
-
-static void __init smp_core99_kick_cpu(int nr)
-{
- int save_vector, j;
- unsigned long new_vector;
- unsigned long flags;
- volatile unsigned int *vector
- = ((volatile unsigned int *)(KERNELBASE+0x100));
-
- if (nr < 1 || nr > 3)
- return;
- if (ppc_md.progress) ppc_md.progress("smp_core99_kick_cpu", 0x346);
-
- local_irq_save(flags);
- local_irq_disable();
-
- /* Save reset vector */
- save_vector = *vector;
-
- /* Setup fake reset vector that does
- * b .pmac_secondary_start - KERNELBASE
- */
- switch(nr) {
- case 1:
- new_vector = (unsigned long)pmac_secondary_start_1;
- break;
- case 2:
- new_vector = (unsigned long)pmac_secondary_start_2;
- break;
- case 3:
- default:
- new_vector = (unsigned long)pmac_secondary_start_3;
- break;
- }
- *vector = 0x48000002 + (new_vector - KERNELBASE);
-
- /* flush data cache and inval instruction cache */
- flush_icache_range((unsigned long) vector, (unsigned long) vector + 4);
-
- /* Put some life in our friend */
- pmac_call_feature(PMAC_FTR_RESET_CPU, NULL, nr, 0);
- paca[nr].cpu_start = 1;
-
- /* FIXME: We wait a bit for the CPU to take the exception, I should
- * instead wait for the entry code to set something for me. Well,
- * ideally, all that crap will be done in prom.c and the CPU left
- * in a RAM-based wait loop like CHRP.
- */
- for (j = 1; j < 1000000; j++)
- mb();
-
- /* Restore our exception vector */
- *vector = save_vector;
- flush_icache_range((unsigned long) vector, (unsigned long) vector + 4);
-
- local_irq_restore(flags);
- if (ppc_md.progress) ppc_md.progress("smp_core99_kick_cpu done", 0x347);
-}
-
-static void __init smp_core99_setup_cpu(int cpu_nr)
-{
- /* Setup MPIC */
- mpic_setup_this_cpu();
-
- if (cpu_nr == 0) {
- extern void g5_phy_disable_cpu1(void);
-
- /* If we didn't start the second CPU, we must take
- * it off the bus
- */
- if (num_online_cpus() < 2)
- g5_phy_disable_cpu1();
- if (ppc_md.progress) ppc_md.progress("smp_core99_setup_cpu 0 done", 0x349);
- }
-}
-
-struct smp_ops_t core99_smp_ops __pmacdata = {
- .message_pass = smp_mpic_message_pass,
- .probe = smp_core99_probe,
- .kick_cpu = smp_core99_kick_cpu,
- .setup_cpu = smp_core99_setup_cpu,
- .give_timebase = smp_generic_give_timebase,
- .take_timebase = smp_generic_take_timebase,
-};
-
-void __init pmac_setup_smp(void)
-{
- smp_ops = &core99_smp_ops;
-#ifdef CONFIG_HOTPLUG_CPU
- smp_ops->cpu_enable = generic_cpu_enable;
- smp_ops->cpu_disable = generic_cpu_disable;
- smp_ops->cpu_die = generic_cpu_die;
-#endif
-}
diff --git a/arch/ppc64/kernel/pmac_time.c b/arch/ppc64/kernel/pmac_time.c
deleted file mode 100644
index 41bbb8c59697..000000000000
--- a/arch/ppc64/kernel/pmac_time.c
+++ /dev/null
@@ -1,195 +0,0 @@
-/*
- * Support for periodic interrupts (100 per second) and for getting
- * the current time from the RTC on Power Macintoshes.
- *
- * We use the decrementer register for our periodic interrupts.
- *
- * Paul Mackerras August 1996.
- * Copyright (C) 1996 Paul Mackerras.
- * Copyright (C) 2003-2005 Benjamin Herrenschmidt.
- *
- */
-#include <linux/config.h>
-#include <linux/errno.h>
-#include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/param.h>
-#include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/init.h>
-#include <linux/time.h>
-#include <linux/adb.h>
-#include <linux/pmu.h>
-#include <linux/interrupt.h>
-
-#include <asm/sections.h>
-#include <asm/prom.h>
-#include <asm/system.h>
-#include <asm/io.h>
-#include <asm/pgtable.h>
-#include <asm/machdep.h>
-#include <asm/time.h>
-#include <asm/nvram.h>
-#include <asm/smu.h>
-
-#undef DEBUG
-
-#ifdef DEBUG
-#define DBG(x...) printk(x)
-#else
-#define DBG(x...)
-#endif
-
-/* Apparently the RTC stores seconds since 1 Jan 1904 */
-#define RTC_OFFSET 2082844800
-
-/*
- * Calibrate the decrementer frequency with the VIA timer 1.
- */
-#define VIA_TIMER_FREQ_6 4700000 /* time 1 frequency * 6 */
-
-extern struct timezone sys_tz;
-extern void to_tm(int tim, struct rtc_time * tm);
-
-void __pmac pmac_get_rtc_time(struct rtc_time *tm)
-{
- switch(sys_ctrler) {
-#ifdef CONFIG_ADB_PMU
- case SYS_CTRLER_PMU: {
- /* TODO: Move that to a function in the PMU driver */
- struct adb_request req;
- unsigned int now;
-
- if (pmu_request(&req, NULL, 1, PMU_READ_RTC) < 0)
- return;
- pmu_wait_complete(&req);
- if (req.reply_len != 4)
- printk(KERN_ERR "pmac_get_rtc_time: PMU returned a %d"
- " bytes reply\n", req.reply_len);
- now = (req.reply[0] << 24) + (req.reply[1] << 16)
- + (req.reply[2] << 8) + req.reply[3];
- DBG("get: %u -> %u\n", (int)now, (int)(now - RTC_OFFSET));
- now -= RTC_OFFSET;
-
- to_tm(now, tm);
- tm->tm_year -= 1900;
- tm->tm_mon -= 1;
-
- DBG("-> tm_mday: %d, tm_mon: %d, tm_year: %d, %d:%02d:%02d\n",
- tm->tm_mday, tm->tm_mon, tm->tm_year,
- tm->tm_hour, tm->tm_min, tm->tm_sec);
- break;
- }
-#endif /* CONFIG_ADB_PMU */
-
-#ifdef CONFIG_PMAC_SMU
- case SYS_CTRLER_SMU:
- smu_get_rtc_time(tm, 1);
- break;
-#endif /* CONFIG_PMAC_SMU */
- default:
- ;
- }
-}
-
-int __pmac pmac_set_rtc_time(struct rtc_time *tm)
-{
- switch(sys_ctrler) {
-#ifdef CONFIG_ADB_PMU
- case SYS_CTRLER_PMU: {
- /* TODO: Move that to a function in the PMU driver */
- struct adb_request req;
- unsigned int nowtime;
-
- DBG("set: tm_mday: %d, tm_mon: %d, tm_year: %d,"
- " %d:%02d:%02d\n",
- tm->tm_mday, tm->tm_mon, tm->tm_year,
- tm->tm_hour, tm->tm_min, tm->tm_sec);
-
- nowtime = mktime(tm->tm_year + 1900, tm->tm_mon + 1,
- tm->tm_mday, tm->tm_hour, tm->tm_min,
- tm->tm_sec);
-
- DBG("-> %u -> %u\n", (int)nowtime,
- (int)(nowtime + RTC_OFFSET));
- nowtime += RTC_OFFSET;
-
- if (pmu_request(&req, NULL, 5, PMU_SET_RTC,
- nowtime >> 24, nowtime >> 16,
- nowtime >> 8, nowtime) < 0)
- return -ENXIO;
- pmu_wait_complete(&req);
- if (req.reply_len != 0)
- printk(KERN_ERR "pmac_set_rtc_time: PMU returned a %d"
- " bytes reply\n", req.reply_len);
- return 0;
- }
-#endif /* CONFIG_ADB_PMU */
-
-#ifdef CONFIG_PMAC_SMU
- case SYS_CTRLER_SMU:
- return smu_set_rtc_time(tm, 1);
-#endif /* CONFIG_PMAC_SMU */
- default:
- return -ENODEV;
- }
-}
-
-void __init pmac_get_boot_time(struct rtc_time *tm)
-{
- pmac_get_rtc_time(tm);
-
-#ifdef disabled__CONFIG_NVRAM
- s32 delta = 0;
- int dst;
-
- delta = ((s32)pmac_xpram_read(PMAC_XPRAM_MACHINE_LOC + 0x9)) << 16;
- delta |= ((s32)pmac_xpram_read(PMAC_XPRAM_MACHINE_LOC + 0xa)) << 8;
- delta |= pmac_xpram_read(PMAC_XPRAM_MACHINE_LOC + 0xb);
- if (delta & 0x00800000UL)
- delta |= 0xFF000000UL;
- dst = ((pmac_xpram_read(PMAC_XPRAM_MACHINE_LOC + 0x8) & 0x80) != 0);
- printk("GMT Delta read from XPRAM: %d minutes, DST: %s\n", delta/60,
- dst ? "on" : "off");
-#endif
-}
-
-/*
- * Query the OF and get the decr frequency.
- * FIXME: merge this with generic_calibrate_decr
- */
-void __init pmac_calibrate_decr(void)
-{
- struct device_node *cpu;
- unsigned int freq, *fp;
- struct div_result divres;
-
- /*
- * The cpu node should have a timebase-frequency property
- * to tell us the rate at which the decrementer counts.
- */
- cpu = find_type_devices("cpu");
- if (cpu == 0)
- panic("can't find cpu node in time_init");
- fp = (unsigned int *) get_property(cpu, "timebase-frequency", NULL);
- if (fp == 0)
- panic("can't get cpu timebase frequency");
- freq = *fp;
- printk("time_init: decrementer frequency = %u.%.6u MHz\n",
- freq/1000000, freq%1000000);
- tb_ticks_per_jiffy = freq / HZ;
- tb_ticks_per_sec = tb_ticks_per_jiffy * HZ;
- tb_ticks_per_usec = freq / 1000000;
- tb_to_us = mulhwu_scale_factor(freq, 1000000);
- div128_by_32( 1024*1024, 0, tb_ticks_per_sec, &divres );
- tb_to_xs = divres.result_low;
- ppc_tb_freq = freq;
-
- fp = (unsigned int *)get_property(cpu, "clock-frequency", NULL);
- if (fp == 0)
- panic("can't get cpu processor frequency");
- ppc_proc_freq = *fp;
-
- setup_default_decr();
-}
-
diff --git a/arch/ppc64/kernel/ppc_ksyms.c b/arch/ppc64/kernel/ppc_ksyms.c
index 705742f4eec6..84006e26342c 100644
--- a/arch/ppc64/kernel/ppc_ksyms.c
+++ b/arch/ppc64/kernel/ppc_ksyms.c
@@ -19,7 +19,6 @@
#include <asm/hw_irq.h>
#include <asm/abs_addr.h>
#include <asm/cacheflush.h>
-#include <asm/iSeries/HvCallSc.h>
EXPORT_SYMBOL(strcpy);
EXPORT_SYMBOL(strncpy);
@@ -46,17 +45,6 @@ EXPORT_SYMBOL(__strnlen_user);
EXPORT_SYMBOL(reloc_offset);
-#ifdef CONFIG_PPC_ISERIES
-EXPORT_SYMBOL(HvCall0);
-EXPORT_SYMBOL(HvCall1);
-EXPORT_SYMBOL(HvCall2);
-EXPORT_SYMBOL(HvCall3);
-EXPORT_SYMBOL(HvCall4);
-EXPORT_SYMBOL(HvCall5);
-EXPORT_SYMBOL(HvCall6);
-EXPORT_SYMBOL(HvCall7);
-#endif
-
EXPORT_SYMBOL(_insb);
EXPORT_SYMBOL(_outsb);
EXPORT_SYMBOL(_insw);
@@ -77,14 +65,6 @@ EXPORT_SYMBOL(giveup_altivec);
EXPORT_SYMBOL(__flush_icache_range);
EXPORT_SYMBOL(flush_dcache_range);
-#ifdef CONFIG_SMP
-#ifdef CONFIG_PPC_ISERIES
-EXPORT_SYMBOL(local_get_flags);
-EXPORT_SYMBOL(local_irq_disable);
-EXPORT_SYMBOL(local_irq_restore);
-#endif
-#endif
-
EXPORT_SYMBOL(memcpy);
EXPORT_SYMBOL(memset);
EXPORT_SYMBOL(memmove);
diff --git a/arch/ppc64/kernel/prom.c b/arch/ppc64/kernel/prom.c
index 7035deb6de92..fbad2c360784 100644
--- a/arch/ppc64/kernel/prom.c
+++ b/arch/ppc64/kernel/prom.c
@@ -31,6 +31,7 @@
#include <linux/initrd.h>
#include <linux/bitops.h>
#include <linux/module.h>
+#include <linux/module.h>
#include <asm/prom.h>
#include <asm/rtas.h>
@@ -46,8 +47,6 @@
#include <asm/pgtable.h>
#include <asm/pci.h>
#include <asm/iommu.h>
-#include <asm/bootinfo.h>
-#include <asm/ppcdebug.h>
#include <asm/btext.h>
#include <asm/sections.h>
#include <asm/machdep.h>
@@ -78,11 +77,14 @@ typedef int interpret_func(struct device_node *, unsigned long *,
extern struct rtas_t rtas;
extern struct lmb lmb;
extern unsigned long klimit;
+extern unsigned long memory_limit;
static int __initdata dt_root_addr_cells;
static int __initdata dt_root_size_cells;
static int __initdata iommu_is_off;
int __initdata iommu_force_on;
+unsigned long tce_alloc_start, tce_alloc_end;
+
typedef u32 cell_t;
#if 0
@@ -316,7 +318,7 @@ static int __devinit finish_node_interrupts(struct device_node *np,
}
/* We offset irq numbers for the u3 MPIC by 128 in PowerMac */
- if (systemcfg->platform == PLATFORM_POWERMAC && ic && ic->parent) {
+ if (_machine == PLATFORM_POWERMAC && ic && ic->parent) {
char *name = get_property(ic->parent, "name", NULL);
if (name && !strcmp(name, "u3"))
np->intrs[intrcount].line += 128;
@@ -633,10 +635,10 @@ static inline char *find_flat_dt_string(u32 offset)
* used to extract the memory informations at boot before we can
* unflatten the tree
*/
-static int __init scan_flat_dt(int (*it)(unsigned long node,
- const char *uname, int depth,
- void *data),
- void *data)
+int __init of_scan_flat_dt(int (*it)(unsigned long node,
+ const char *uname, int depth,
+ void *data),
+ void *data)
{
unsigned long p = ((unsigned long)initial_boot_params) +
initial_boot_params->off_dt_struct;
@@ -693,8 +695,8 @@ static int __init scan_flat_dt(int (*it)(unsigned long node,
* This function can be used within scan_flattened_dt callback to get
* access to properties
*/
-static void* __init get_flat_dt_prop(unsigned long node, const char *name,
- unsigned long *size)
+void* __init of_get_flat_dt_prop(unsigned long node, const char *name,
+ unsigned long *size)
{
unsigned long p = node;
@@ -994,7 +996,7 @@ void __init unflatten_device_tree(void)
static int __init early_init_dt_scan_cpus(unsigned long node,
const char *uname, int depth, void *data)
{
- char *type = get_flat_dt_prop(node, "device_type", NULL);
+ char *type = of_get_flat_dt_prop(node, "device_type", NULL);
u32 *prop;
unsigned long size;
@@ -1002,17 +1004,6 @@ static int __init early_init_dt_scan_cpus(unsigned long node,
if (type == NULL || strcmp(type, "cpu") != 0)
return 0;
- /* On LPAR, look for the first ibm,pft-size property for the hash table size
- */
- if (systemcfg->platform == PLATFORM_PSERIES_LPAR && ppc64_pft_size == 0) {
- u32 *pft_size;
- pft_size = (u32 *)get_flat_dt_prop(node, "ibm,pft-size", NULL);
- if (pft_size != NULL) {
- /* pft_size[0] is the NUMA CEC cookie */
- ppc64_pft_size = pft_size[1];
- }
- }
-
if (initial_boot_params && initial_boot_params->version >= 2) {
/* version 2 of the kexec param format adds the phys cpuid
* of booted proc.
@@ -1021,8 +1012,9 @@ static int __init early_init_dt_scan_cpus(unsigned long node,
boot_cpuid = 0;
} else {
/* Check if it's the boot-cpu, set it's hw index in paca now */
- if (get_flat_dt_prop(node, "linux,boot-cpu", NULL) != NULL) {
- u32 *prop = get_flat_dt_prop(node, "reg", NULL);
+ if (of_get_flat_dt_prop(node, "linux,boot-cpu", NULL)
+ != NULL) {
+ u32 *prop = of_get_flat_dt_prop(node, "reg", NULL);
set_hard_smp_processor_id(0, prop == NULL ? 0 : *prop);
boot_cpuid_phys = get_hard_smp_processor_id(0);
}
@@ -1030,14 +1022,14 @@ static int __init early_init_dt_scan_cpus(unsigned long node,
#ifdef CONFIG_ALTIVEC
/* Check if we have a VMX and eventually update CPU features */
- prop = (u32 *)get_flat_dt_prop(node, "ibm,vmx", NULL);
+ prop = (u32 *)of_get_flat_dt_prop(node, "ibm,vmx", NULL);
if (prop && (*prop) > 0) {
cur_cpu_spec->cpu_features |= CPU_FTR_ALTIVEC;
cur_cpu_spec->cpu_user_features |= PPC_FEATURE_HAS_ALTIVEC;
}
/* Same goes for Apple's "altivec" property */
- prop = (u32 *)get_flat_dt_prop(node, "altivec", NULL);
+ prop = (u32 *)of_get_flat_dt_prop(node, "altivec", NULL);
if (prop) {
cur_cpu_spec->cpu_features |= CPU_FTR_ALTIVEC;
cur_cpu_spec->cpu_user_features |= PPC_FEATURE_HAS_ALTIVEC;
@@ -1049,7 +1041,7 @@ static int __init early_init_dt_scan_cpus(unsigned long node,
* this by looking at the size of the ibm,ppc-interrupt-server#s
* property
*/
- prop = (u32 *)get_flat_dt_prop(node, "ibm,ppc-interrupt-server#s",
+ prop = (u32 *)of_get_flat_dt_prop(node, "ibm,ppc-interrupt-server#s",
&size);
cur_cpu_spec->cpu_features &= ~CPU_FTR_SMT;
if (prop && ((size / sizeof(u32)) > 1))
@@ -1063,7 +1055,6 @@ static int __init early_init_dt_scan_chosen(unsigned long node,
{
u32 *prop;
u64 *prop64;
- extern unsigned long memory_limit, tce_alloc_start, tce_alloc_end;
DBG("search \"chosen\", depth: %d, uname: %s\n", depth, uname);
@@ -1071,26 +1062,26 @@ static int __init early_init_dt_scan_chosen(unsigned long node,
return 0;
/* get platform type */
- prop = (u32 *)get_flat_dt_prop(node, "linux,platform", NULL);
+ prop = (u32 *)of_get_flat_dt_prop(node, "linux,platform", NULL);
if (prop == NULL)
return 0;
- systemcfg->platform = *prop;
+ _machine = *prop;
/* check if iommu is forced on or off */
- if (get_flat_dt_prop(node, "linux,iommu-off", NULL) != NULL)
+ if (of_get_flat_dt_prop(node, "linux,iommu-off", NULL) != NULL)
iommu_is_off = 1;
- if (get_flat_dt_prop(node, "linux,iommu-force-on", NULL) != NULL)
+ if (of_get_flat_dt_prop(node, "linux,iommu-force-on", NULL) != NULL)
iommu_force_on = 1;
- prop64 = (u64*)get_flat_dt_prop(node, "linux,memory-limit", NULL);
+ prop64 = (u64*)of_get_flat_dt_prop(node, "linux,memory-limit", NULL);
if (prop64)
memory_limit = *prop64;
- prop64 = (u64*)get_flat_dt_prop(node, "linux,tce-alloc-start", NULL);
+ prop64 = (u64*)of_get_flat_dt_prop(node, "linux,tce-alloc-start",NULL);
if (prop64)
tce_alloc_start = *prop64;
- prop64 = (u64*)get_flat_dt_prop(node, "linux,tce-alloc-end", NULL);
+ prop64 = (u64*)of_get_flat_dt_prop(node, "linux,tce-alloc-end", NULL);
if (prop64)
tce_alloc_end = *prop64;
@@ -1101,9 +1092,12 @@ static int __init early_init_dt_scan_chosen(unsigned long node,
{
u64 *basep, *entryp;
- basep = (u64*)get_flat_dt_prop(node, "linux,rtas-base", NULL);
- entryp = (u64*)get_flat_dt_prop(node, "linux,rtas-entry", NULL);
- prop = (u32*)get_flat_dt_prop(node, "linux,rtas-size", NULL);
+ basep = (u64*)of_get_flat_dt_prop(node,
+ "linux,rtas-base", NULL);
+ entryp = (u64*)of_get_flat_dt_prop(node,
+ "linux,rtas-entry", NULL);
+ prop = (u32*)of_get_flat_dt_prop(node,
+ "linux,rtas-size", NULL);
if (basep && entryp && prop) {
rtas.base = *basep;
rtas.entry = *entryp;
@@ -1124,11 +1118,11 @@ static int __init early_init_dt_scan_root(unsigned long node,
if (depth != 0)
return 0;
- prop = (u32 *)get_flat_dt_prop(node, "#size-cells", NULL);
+ prop = (u32 *)of_get_flat_dt_prop(node, "#size-cells", NULL);
dt_root_size_cells = (prop == NULL) ? 1 : *prop;
DBG("dt_root_size_cells = %x\n", dt_root_size_cells);
- prop = (u32 *)get_flat_dt_prop(node, "#address-cells", NULL);
+ prop = (u32 *)of_get_flat_dt_prop(node, "#address-cells", NULL);
dt_root_addr_cells = (prop == NULL) ? 2 : *prop;
DBG("dt_root_addr_cells = %x\n", dt_root_addr_cells);
@@ -1160,7 +1154,7 @@ static unsigned long __init dt_mem_next_cell(int s, cell_t **cellp)
static int __init early_init_dt_scan_memory(unsigned long node,
const char *uname, int depth, void *data)
{
- char *type = get_flat_dt_prop(node, "device_type", NULL);
+ char *type = of_get_flat_dt_prop(node, "device_type", NULL);
cell_t *reg, *endp;
unsigned long l;
@@ -1168,7 +1162,7 @@ static int __init early_init_dt_scan_memory(unsigned long node,
if (type == NULL || strcmp(type, "memory") != 0)
return 0;
- reg = (cell_t *)get_flat_dt_prop(node, "reg", &l);
+ reg = (cell_t *)of_get_flat_dt_prop(node, "reg", &l);
if (reg == NULL)
return 0;
@@ -1224,26 +1218,20 @@ void __init early_init_devtree(void *params)
/* Setup flat device-tree pointer */
initial_boot_params = params;
- /* By default, hash size is not set */
- ppc64_pft_size = 0;
-
/* Retreive various informations from the /chosen node of the
* device-tree, including the platform type, initrd location and
* size, TCE reserve, and more ...
*/
- scan_flat_dt(early_init_dt_scan_chosen, NULL);
+ of_scan_flat_dt(early_init_dt_scan_chosen, NULL);
/* Scan memory nodes and rebuild LMBs */
lmb_init();
- scan_flat_dt(early_init_dt_scan_root, NULL);
- scan_flat_dt(early_init_dt_scan_memory, NULL);
- lmb_enforce_memory_limit();
+ of_scan_flat_dt(early_init_dt_scan_root, NULL);
+ of_scan_flat_dt(early_init_dt_scan_memory, NULL);
+ lmb_enforce_memory_limit(memory_limit);
lmb_analyze();
- systemcfg->physicalMemorySize = lmb_phys_mem_size();
lmb_reserve(0, __pa(klimit));
- DBG("Phys. mem: %lx\n", systemcfg->physicalMemorySize);
-
/* Reserve LMB regions used by kernel, initrd, dt, etc... */
early_reserve_mem();
@@ -1252,26 +1240,8 @@ void __init early_init_devtree(void *params)
/* Retreive hash table size from flattened tree plus other
* CPU related informations (altivec support, boot CPU ID, ...)
*/
- scan_flat_dt(early_init_dt_scan_cpus, NULL);
-
- /* If hash size wasn't obtained above, we calculate it now based on
- * the total RAM size
- */
- if (ppc64_pft_size == 0) {
- unsigned long rnd_mem_size, pteg_count;
-
- /* round mem_size up to next power of 2 */
- rnd_mem_size = 1UL << __ilog2(systemcfg->physicalMemorySize);
- if (rnd_mem_size < systemcfg->physicalMemorySize)
- rnd_mem_size <<= 1;
-
- /* # pages / 2 */
- pteg_count = max(rnd_mem_size >> (12 + 1), 1UL << 11);
+ of_scan_flat_dt(early_init_dt_scan_cpus, NULL);
- ppc64_pft_size = __ilog2(pteg_count << 7);
- }
-
- DBG("Hash pftSize: %x\n", (int)ppc64_pft_size);
DBG(" <- early_init_devtree()\n");
}
@@ -1780,7 +1750,7 @@ static int of_finish_dynamic_node(struct device_node *node,
/* We don't support that function on PowerMac, at least
* not yet
*/
- if (systemcfg->platform == PLATFORM_POWERMAC)
+ if (_machine == PLATFORM_POWERMAC)
return -ENODEV;
/* fix up new node's linux_phandle field */
@@ -1893,17 +1863,32 @@ get_property(struct device_node *np, const char *name, int *lenp)
EXPORT_SYMBOL(get_property);
/*
- * Add a property to a node
+ * Add a property to a node.
*/
-void
+int
prom_add_property(struct device_node* np, struct property* prop)
{
- struct property **next = &np->properties;
+ struct property **next;
prop->next = NULL;
- while (*next)
+ write_lock(&devtree_lock);
+ next = &np->properties;
+ while (*next) {
+ if (strcmp(prop->name, (*next)->name) == 0) {
+ /* duplicate ! don't insert it */
+ write_unlock(&devtree_lock);
+ return -1;
+ }
next = &(*next)->next;
+ }
*next = prop;
+ write_unlock(&devtree_lock);
+
+ /* try to add to proc as well if it was initialized */
+ if (np->pde)
+ proc_device_tree_add_prop(np->pde, prop);
+
+ return 0;
}
#if 0
diff --git a/arch/ppc64/kernel/prom_init.c b/arch/ppc64/kernel/prom_init.c
index f252670874a4..6375f40b23db 100644
--- a/arch/ppc64/kernel/prom_init.c
+++ b/arch/ppc64/kernel/prom_init.c
@@ -44,8 +44,6 @@
#include <asm/pgtable.h>
#include <asm/pci.h>
#include <asm/iommu.h>
-#include <asm/bootinfo.h>
-#include <asm/ppcdebug.h>
#include <asm/btext.h>
#include <asm/sections.h>
#include <asm/machdep.h>
@@ -1826,7 +1824,7 @@ static void __init fixup_device_tree(void)
if (prom_getprop(u3, "device-rev", &u3_rev, sizeof(u3_rev))
== PROM_ERROR)
return;
- if (u3_rev != 0x35 && u3_rev != 0x37)
+ if (u3_rev < 0x35 || u3_rev > 0x39)
return;
/* does it need fixup ? */
if (prom_getproplen(i2c, "interrupts") > 0)
@@ -1936,13 +1934,14 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4, unsigned long
/*
* On pSeries, inform the firmware about our capabilities
*/
- if (RELOC(of_platform) & PLATFORM_PSERIES)
+ if (RELOC(of_platform) == PLATFORM_PSERIES ||
+ RELOC(of_platform) == PLATFORM_PSERIES_LPAR)
prom_send_capabilities();
/*
- * On pSeries and BPA, copy the CPU hold code
+ * On pSeries and Cell, copy the CPU hold code
*/
- if (RELOC(of_platform) & (PLATFORM_PSERIES | PLATFORM_BPA))
+ if (RELOC(of_platform) & (PLATFORM_PSERIES | PLATFORM_CELL))
copy_and_flush(0, KERNELBASE - offset, 0x100, 0);
/*
diff --git a/arch/ppc64/kernel/ptrace.c b/arch/ppc64/kernel/ptrace.c
deleted file mode 100644
index b1c044ca5756..000000000000
--- a/arch/ppc64/kernel/ptrace.c
+++ /dev/null
@@ -1,363 +0,0 @@
-/*
- * linux/arch/ppc64/kernel/ptrace.c
- *
- * PowerPC version
- * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
- *
- * Derived from "arch/m68k/kernel/ptrace.c"
- * Copyright (C) 1994 by Hamish Macdonald
- * Taken from linux/kernel/ptrace.c and modified for M680x0.
- * linux/kernel/ptrace.c is by Ross Biro 1/23/92, edited by Linus Torvalds
- *
- * Modified by Cort Dougan (cort@hq.fsmlabs.com)
- * and Paul Mackerras (paulus@linuxcare.com.au).
- *
- * This file is subject to the terms and conditions of the GNU General
- * Public License. See the file README.legal in the main directory of
- * this archive for more details.
- */
-
-#include <linux/config.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/mm.h>
-#include <linux/smp.h>
-#include <linux/smp_lock.h>
-#include <linux/errno.h>
-#include <linux/ptrace.h>
-#include <linux/user.h>
-#include <linux/security.h>
-#include <linux/audit.h>
-#include <linux/seccomp.h>
-#include <linux/signal.h>
-
-#include <asm/uaccess.h>
-#include <asm/page.h>
-#include <asm/pgtable.h>
-#include <asm/system.h>
-#include <asm/ptrace-common.h>
-
-/*
- * does not yet catch signals sent when the child dies.
- * in exit.c or in signal.c.
- */
-
-/*
- * Called by kernel/ptrace.c when detaching..
- *
- * Make sure single step bits etc are not set.
- */
-void ptrace_disable(struct task_struct *child)
-{
- /* make sure the single step bit is not set. */
- clear_single_step(child);
-}
-
-int sys_ptrace(long request, long pid, long addr, long data)
-{
- struct task_struct *child;
- int ret = -EPERM;
-
- lock_kernel();
- if (request == PTRACE_TRACEME) {
- /* are we already being traced? */
- if (current->ptrace & PT_PTRACED)
- goto out;
- ret = security_ptrace(current->parent, current);
- if (ret)
- goto out;
- /* set the ptrace bit in the process flags. */
- current->ptrace |= PT_PTRACED;
- ret = 0;
- goto out;
- }
- ret = -ESRCH;
- read_lock(&tasklist_lock);
- child = find_task_by_pid(pid);
- if (child)
- get_task_struct(child);
- read_unlock(&tasklist_lock);
- if (!child)
- goto out;
-
- ret = -EPERM;
- if (pid == 1) /* you may not mess with init */
- goto out_tsk;
-
- if (request == PTRACE_ATTACH) {
- ret = ptrace_attach(child);
- goto out_tsk;
- }
-
- ret = ptrace_check_attach(child, request == PTRACE_KILL);
- if (ret < 0)
- goto out_tsk;
-
- switch (request) {
- /* when I and D space are separate, these will need to be fixed. */
- case PTRACE_PEEKTEXT: /* read word at location addr. */
- case PTRACE_PEEKDATA: {
- unsigned long tmp;
- int copied;
-
- copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
- ret = -EIO;
- if (copied != sizeof(tmp))
- break;
- ret = put_user(tmp,(unsigned long __user *) data);
- break;
- }
-
- /* read the word at location addr in the USER area. */
- case PTRACE_PEEKUSR: {
- unsigned long index;
- unsigned long tmp;
-
- ret = -EIO;
- /* convert to index and check */
- index = (unsigned long) addr >> 3;
- if ((addr & 7) || (index > PT_FPSCR))
- break;
-
- if (index < PT_FPR0) {
- tmp = get_reg(child, (int)index);
- } else {
- flush_fp_to_thread(child);
- tmp = ((unsigned long *)child->thread.fpr)[index - PT_FPR0];
- }
- ret = put_user(tmp,(unsigned long __user *) data);
- break;
- }
-
- /* If I and D space are separate, this will have to be fixed. */
- case PTRACE_POKETEXT: /* write the word at location addr. */
- case PTRACE_POKEDATA:
- ret = 0;
- if (access_process_vm(child, addr, &data, sizeof(data), 1)
- == sizeof(data))
- break;
- ret = -EIO;
- break;
-
- /* write the word at location addr in the USER area */
- case PTRACE_POKEUSR: {
- unsigned long index;
-
- ret = -EIO;
- /* convert to index and check */
- index = (unsigned long) addr >> 3;
- if ((addr & 7) || (index > PT_FPSCR))
- break;
-
- if (index == PT_ORIG_R3)
- break;
- if (index < PT_FPR0) {
- ret = put_reg(child, index, data);
- } else {
- flush_fp_to_thread(child);
- ((unsigned long *)child->thread.fpr)[index - PT_FPR0] = data;
- ret = 0;
- }
- break;
- }
-
- case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
- case PTRACE_CONT: { /* restart after signal. */
- ret = -EIO;
- if (!valid_signal(data))
- break;
- if (request == PTRACE_SYSCALL)
- set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
- else
- clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
- child->exit_code = data;
- /* make sure the single step bit is not set. */
- clear_single_step(child);
- wake_up_process(child);
- ret = 0;
- break;
- }
-
- /*
- * make the child exit. Best I can do is send it a sigkill.
- * perhaps it should be put in the status that it wants to
- * exit.
- */
- case PTRACE_KILL: {
- ret = 0;
- if (child->exit_state == EXIT_ZOMBIE) /* already dead */
- break;
- child->exit_code = SIGKILL;
- /* make sure the single step bit is not set. */
- clear_single_step(child);
- wake_up_process(child);
- break;
- }
-
- case PTRACE_SINGLESTEP: { /* set the trap flag. */
- ret = -EIO;
- if (!valid_signal(data))
- break;
- clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
- set_single_step(child);
- child->exit_code = data;
- /* give it a chance to run. */
- wake_up_process(child);
- ret = 0;
- break;
- }
-
- case PTRACE_GET_DEBUGREG: {
- ret = -EINVAL;
- /* We only support one DABR and no IABRS at the moment */
- if (addr > 0)
- break;
- ret = put_user(child->thread.dabr,
- (unsigned long __user *)data);
- break;
- }
-
- case PTRACE_SET_DEBUGREG:
- ret = ptrace_set_debugreg(child, addr, data);
- break;
-
- case PTRACE_DETACH:
- ret = ptrace_detach(child, data);
- break;
-
- case PPC_PTRACE_GETREGS: { /* Get GPRs 0 - 31. */
- int i;
- unsigned long *reg = &((unsigned long *)child->thread.regs)[0];
- unsigned long __user *tmp = (unsigned long __user *)addr;
-
- for (i = 0; i < 32; i++) {
- ret = put_user(*reg, tmp);
- if (ret)
- break;
- reg++;
- tmp++;
- }
- break;
- }
-
- case PPC_PTRACE_SETREGS: { /* Set GPRs 0 - 31. */
- int i;
- unsigned long *reg = &((unsigned long *)child->thread.regs)[0];
- unsigned long __user *tmp = (unsigned long __user *)addr;
-
- for (i = 0; i < 32; i++) {
- ret = get_user(*reg, tmp);
- if (ret)
- break;
- reg++;
- tmp++;
- }
- break;
- }
-
- case PPC_PTRACE_GETFPREGS: { /* Get FPRs 0 - 31. */
- int i;
- unsigned long *reg = &((unsigned long *)child->thread.fpr)[0];
- unsigned long __user *tmp = (unsigned long __user *)addr;
-
- flush_fp_to_thread(child);
-
- for (i = 0; i < 32; i++) {
- ret = put_user(*reg, tmp);
- if (ret)
- break;
- reg++;
- tmp++;
- }
- break;
- }
-
- case PPC_PTRACE_SETFPREGS: { /* Get FPRs 0 - 31. */
- int i;
- unsigned long *reg = &((unsigned long *)child->thread.fpr)[0];
- unsigned long __user *tmp = (unsigned long __user *)addr;
-
- flush_fp_to_thread(child);
-
- for (i = 0; i < 32; i++) {
- ret = get_user(*reg, tmp);
- if (ret)
- break;
- reg++;
- tmp++;
- }
- break;
- }
-
-#ifdef CONFIG_ALTIVEC
- case PTRACE_GETVRREGS:
- /* Get the child altivec register state. */
- flush_altivec_to_thread(child);
- ret = get_vrregs((unsigned long __user *)data, child);
- break;
-
- case PTRACE_SETVRREGS:
- /* Set the child altivec register state. */
- flush_altivec_to_thread(child);
- ret = set_vrregs(child, (unsigned long __user *)data);
- break;
-#endif
-
- default:
- ret = ptrace_request(child, request, addr, data);
- break;
- }
-out_tsk:
- put_task_struct(child);
-out:
- unlock_kernel();
- return ret;
-}
-
-static void do_syscall_trace(void)
-{
- /* the 0x80 provides a way for the tracing parent to distinguish
- between a syscall stop and SIGTRAP delivery */
- ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
- ? 0x80 : 0));
-
- /*
- * this isn't the same as continuing with a signal, but it will do
- * for normal use. strace only continues with a signal if the
- * stopping signal is not SIGTRAP. -brl
- */
- if (current->exit_code) {
- send_sig(current->exit_code, current, 1);
- current->exit_code = 0;
- }
-}
-
-void do_syscall_trace_enter(struct pt_regs *regs)
-{
- secure_computing(regs->gpr[0]);
-
- if (test_thread_flag(TIF_SYSCALL_TRACE)
- && (current->ptrace & PT_PTRACED))
- do_syscall_trace();
-
- if (unlikely(current->audit_context))
- audit_syscall_entry(current,
- test_thread_flag(TIF_32BIT)?AUDIT_ARCH_PPC:AUDIT_ARCH_PPC64,
- regs->gpr[0],
- regs->gpr[3], regs->gpr[4],
- regs->gpr[5], regs->gpr[6]);
-
-}
-
-void do_syscall_trace_leave(struct pt_regs *regs)
-{
- if (unlikely(current->audit_context))
- audit_syscall_exit(current,
- (regs->ccr&0x1000)?AUDITSC_FAILURE:AUDITSC_SUCCESS,
- regs->result);
-
- if ((test_thread_flag(TIF_SYSCALL_TRACE)
- || test_thread_flag(TIF_SINGLESTEP))
- && (current->ptrace & PT_PTRACED))
- do_syscall_trace();
-}
diff --git a/arch/ppc64/kernel/rtc.c b/arch/ppc64/kernel/rtc.c
index 6ff52bc61325..79e7ed2858dd 100644
--- a/arch/ppc64/kernel/rtc.c
+++ b/arch/ppc64/kernel/rtc.c
@@ -43,11 +43,8 @@
#include <asm/time.h>
#include <asm/rtas.h>
-#include <asm/iSeries/mf.h>
#include <asm/machdep.h>
-extern int piranha_simulator;
-
/*
* We sponge a minor off of the misc major. No need slurping
* up another valuable major dev number for this. If you add
@@ -265,44 +262,10 @@ static int rtc_read_proc(char *page, char **start, off_t off,
return len;
}
-#ifdef CONFIG_PPC_ISERIES
-/*
- * Get the RTC from the virtual service processor
- * This requires flowing LpEvents to the primary partition
- */
-void iSeries_get_rtc_time(struct rtc_time *rtc_tm)
-{
- if (piranha_simulator)
- return;
-
- mf_get_rtc(rtc_tm);
- rtc_tm->tm_mon--;
-}
-
-/*
- * Set the RTC in the virtual service processor
- * This requires flowing LpEvents to the primary partition
- */
-int iSeries_set_rtc_time(struct rtc_time *tm)
-{
- mf_set_rtc(tm);
- return 0;
-}
-
-void iSeries_get_boot_time(struct rtc_time *tm)
-{
- if ( piranha_simulator )
- return;
-
- mf_get_boot_rtc(tm);
- tm->tm_mon -= 1;
-}
-#endif
-
#ifdef CONFIG_PPC_RTAS
#define MAX_RTC_WAIT 5000 /* 5 sec */
#define RTAS_CLOCK_BUSY (-2)
-void rtas_get_boot_time(struct rtc_time *rtc_tm)
+unsigned long rtas_get_boot_time(void)
{
int ret[8];
int error, wait_time;
@@ -322,15 +285,10 @@ void rtas_get_boot_time(struct rtc_time *rtc_tm)
if (error != 0 && printk_ratelimit()) {
printk(KERN_WARNING "error: reading the clock failed (%d)\n",
error);
- return;
+ return 0;
}
- rtc_tm->tm_sec = ret[5];
- rtc_tm->tm_min = ret[4];
- rtc_tm->tm_hour = ret[3];
- rtc_tm->tm_mday = ret[2];
- rtc_tm->tm_mon = ret[1] - 1;
- rtc_tm->tm_year = ret[0] - 1900;
+ return mktime(ret[0], ret[1], ret[2], ret[3], ret[4], ret[5]);
}
/* NOTE: get_rtc_time will get an error if executed in interrupt context
diff --git a/arch/ppc64/kernel/traps.c b/arch/ppc64/kernel/traps.c
deleted file mode 100644
index 7467ae508e6e..000000000000
--- a/arch/ppc64/kernel/traps.c
+++ /dev/null
@@ -1,568 +0,0 @@
-/*
- * linux/arch/ppc64/kernel/traps.c
- *
- * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.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 by Cort Dougan (cort@cs.nmt.edu)
- * and Paul Mackerras (paulus@cs.anu.edu.au)
- */
-
-/*
- * This file handles the architecture-dependent parts of hardware exceptions
- */
-
-#include <linux/config.h>
-#include <linux/errno.h>
-#include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/stddef.h>
-#include <linux/unistd.h>
-#include <linux/slab.h>
-#include <linux/user.h>
-#include <linux/a.out.h>
-#include <linux/interrupt.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/kprobes.h>
-#include <asm/kdebug.h>
-
-#include <asm/pgtable.h>
-#include <asm/uaccess.h>
-#include <asm/system.h>
-#include <asm/io.h>
-#include <asm/processor.h>
-#include <asm/ppcdebug.h>
-#include <asm/rtas.h>
-#include <asm/systemcfg.h>
-#include <asm/machdep.h>
-#include <asm/pmc.h>
-
-#ifdef CONFIG_DEBUGGER
-int (*__debugger)(struct pt_regs *regs);
-int (*__debugger_ipi)(struct pt_regs *regs);
-int (*__debugger_bpt)(struct pt_regs *regs);
-int (*__debugger_sstep)(struct pt_regs *regs);
-int (*__debugger_iabr_match)(struct pt_regs *regs);
-int (*__debugger_dabr_match)(struct pt_regs *regs);
-int (*__debugger_fault_handler)(struct pt_regs *regs);
-
-EXPORT_SYMBOL(__debugger);
-EXPORT_SYMBOL(__debugger_ipi);
-EXPORT_SYMBOL(__debugger_bpt);
-EXPORT_SYMBOL(__debugger_sstep);
-EXPORT_SYMBOL(__debugger_iabr_match);
-EXPORT_SYMBOL(__debugger_dabr_match);
-EXPORT_SYMBOL(__debugger_fault_handler);
-#endif
-
-struct notifier_block *ppc64_die_chain;
-static DEFINE_SPINLOCK(die_notifier_lock);
-
-int register_die_notifier(struct notifier_block *nb)
-{
- int err = 0;
- unsigned long flags;
-
- spin_lock_irqsave(&die_notifier_lock, flags);
- err = notifier_chain_register(&ppc64_die_chain, nb);
- spin_unlock_irqrestore(&die_notifier_lock, flags);
- return err;
-}
-
-/*
- * Trap & Exception support
- */
-
-static DEFINE_SPINLOCK(die_lock);
-
-int die(const char *str, struct pt_regs *regs, long err)
-{
- static int die_counter;
- int nl = 0;
-
- if (debugger(regs))
- return 1;
-
- console_verbose();
- spin_lock_irq(&die_lock);
- bust_spinlocks(1);
- printk("Oops: %s, sig: %ld [#%d]\n", str, err, ++die_counter);
-#ifdef CONFIG_PREEMPT
- printk("PREEMPT ");
- nl = 1;
-#endif
-#ifdef CONFIG_SMP
- printk("SMP NR_CPUS=%d ", NR_CPUS);
- nl = 1;
-#endif
-#ifdef CONFIG_DEBUG_PAGEALLOC
- printk("DEBUG_PAGEALLOC ");
- nl = 1;
-#endif
-#ifdef CONFIG_NUMA
- printk("NUMA ");
- nl = 1;
-#endif
- switch(systemcfg->platform) {
- case PLATFORM_PSERIES:
- printk("PSERIES ");
- nl = 1;
- break;
- case PLATFORM_PSERIES_LPAR:
- printk("PSERIES LPAR ");
- nl = 1;
- break;
- case PLATFORM_ISERIES_LPAR:
- printk("ISERIES LPAR ");
- nl = 1;
- break;
- case PLATFORM_POWERMAC:
- printk("POWERMAC ");
- nl = 1;
- break;
- case PLATFORM_BPA:
- printk("BPA ");
- nl = 1;
- break;
- }
- if (nl)
- printk("\n");
- print_modules();
- show_regs(regs);
- bust_spinlocks(0);
- spin_unlock_irq(&die_lock);
-
- if (in_interrupt())
- panic("Fatal exception in interrupt");
-
- if (panic_on_oops) {
- printk(KERN_EMERG "Fatal exception: panic in 5 seconds\n");
- ssleep(5);
- panic("Fatal exception");
- }
- do_exit(SIGSEGV);
-
- return 0;
-}
-
-void _exception(int signr, struct pt_regs *regs, int code, unsigned long addr)
-{
- siginfo_t info;
-
- if (!user_mode(regs)) {
- if (die("Exception in kernel mode", regs, signr))
- return;
- }
-
- memset(&info, 0, sizeof(info));
- info.si_signo = signr;
- info.si_code = code;
- info.si_addr = (void __user *) addr;
- force_sig_info(signr, &info, current);
-}
-
-void system_reset_exception(struct pt_regs *regs)
-{
- /* See if any machine dependent calls */
- if (ppc_md.system_reset_exception)
- ppc_md.system_reset_exception(regs);
-
- die("System Reset", regs, 0);
-
- /* Must die if the interrupt is not recoverable */
- if (!(regs->msr & MSR_RI))
- panic("Unrecoverable System Reset");
-
- /* What should we do here? We could issue a shutdown or hard reset. */
-}
-
-void machine_check_exception(struct pt_regs *regs)
-{
- int recover = 0;
-
- /* See if any machine dependent calls */
- if (ppc_md.machine_check_exception)
- recover = ppc_md.machine_check_exception(regs);
-
- if (recover)
- return;
-
- if (debugger_fault_handler(regs))
- return;
- die("Machine check", regs, 0);
-
- /* Must die if the interrupt is not recoverable */
- if (!(regs->msr & MSR_RI))
- panic("Unrecoverable Machine check");
-}
-
-void unknown_exception(struct pt_regs *regs)
-{
- printk("Bad trap at PC: %lx, SR: %lx, vector=%lx\n",
- regs->nip, regs->msr, regs->trap);
-
- _exception(SIGTRAP, regs, 0, 0);
-}
-
-void instruction_breakpoint_exception(struct pt_regs *regs)
-{
- if (notify_die(DIE_IABR_MATCH, "iabr_match", regs, 5,
- 5, SIGTRAP) == NOTIFY_STOP)
- return;
- if (debugger_iabr_match(regs))
- return;
- _exception(SIGTRAP, regs, TRAP_BRKPT, regs->nip);
-}
-
-void __kprobes single_step_exception(struct pt_regs *regs)
-{
- regs->msr &= ~MSR_SE; /* Turn off 'trace' bit */
-
- if (notify_die(DIE_SSTEP, "single_step", regs, 5,
- 5, SIGTRAP) == NOTIFY_STOP)
- return;
- if (debugger_sstep(regs))
- return;
-
- _exception(SIGTRAP, regs, TRAP_TRACE, regs->nip);
-}
-
-/*
- * After we have successfully emulated an instruction, we have to
- * check if the instruction was being single-stepped, and if so,
- * pretend we got a single-step exception. This was pointed out
- * by Kumar Gala. -- paulus
- */
-static inline void emulate_single_step(struct pt_regs *regs)
-{
- if (regs->msr & MSR_SE)
- single_step_exception(regs);
-}
-
-static void parse_fpe(struct pt_regs *regs)
-{
- int code = 0;
- unsigned long fpscr;
-
- flush_fp_to_thread(current);
-
- fpscr = current->thread.fpscr;
-
- /* Invalid operation */
- if ((fpscr & FPSCR_VE) && (fpscr & FPSCR_VX))
- code = FPE_FLTINV;
-
- /* Overflow */
- else if ((fpscr & FPSCR_OE) && (fpscr & FPSCR_OX))
- code = FPE_FLTOVF;
-
- /* Underflow */
- else if ((fpscr & FPSCR_UE) && (fpscr & FPSCR_UX))
- code = FPE_FLTUND;
-
- /* Divide by zero */
- else if ((fpscr & FPSCR_ZE) && (fpscr & FPSCR_ZX))
- code = FPE_FLTDIV;
-
- /* Inexact result */
- else if ((fpscr & FPSCR_XE) && (fpscr & FPSCR_XX))
- code = FPE_FLTRES;
-
- _exception(SIGFPE, regs, code, regs->nip);
-}
-
-/*
- * Illegal instruction emulation support. Return non-zero if we can't
- * emulate, or -EFAULT if the associated memory access caused an access
- * fault. Return zero on success.
- */
-
-#define INST_MFSPR_PVR 0x7c1f42a6
-#define INST_MFSPR_PVR_MASK 0xfc1fffff
-
-#define INST_DCBA 0x7c0005ec
-#define INST_DCBA_MASK 0x7c0007fe
-
-#define INST_MCRXR 0x7c000400
-#define INST_MCRXR_MASK 0x7c0007fe
-
-static int emulate_instruction(struct pt_regs *regs)
-{
- unsigned int instword;
-
- if (!user_mode(regs))
- return -EINVAL;
-
- CHECK_FULL_REGS(regs);
-
- if (get_user(instword, (unsigned int __user *)(regs->nip)))
- return -EFAULT;
-
- /* Emulate the mfspr rD, PVR. */
- if ((instword & INST_MFSPR_PVR_MASK) == INST_MFSPR_PVR) {
- unsigned int rd;
-
- rd = (instword >> 21) & 0x1f;
- regs->gpr[rd] = mfspr(SPRN_PVR);
- return 0;
- }
-
- /* Emulating the dcba insn is just a no-op. */
- if ((instword & INST_DCBA_MASK) == INST_DCBA) {
- static int warned;
-
- if (!warned) {
- printk(KERN_WARNING
- "process %d (%s) uses obsolete 'dcba' insn\n",
- current->pid, current->comm);
- warned = 1;
- }
- return 0;
- }
-
- /* Emulate the mcrxr insn. */
- if ((instword & INST_MCRXR_MASK) == INST_MCRXR) {
- static int warned;
- unsigned int shift;
-
- if (!warned) {
- printk(KERN_WARNING
- "process %d (%s) uses obsolete 'mcrxr' insn\n",
- current->pid, current->comm);
- warned = 1;
- }
-
- shift = (instword >> 21) & 0x1c;
- regs->ccr &= ~(0xf0000000 >> shift);
- regs->ccr |= (regs->xer & 0xf0000000) >> shift;
- regs->xer &= ~0xf0000000;
- return 0;
- }
-
- return -EINVAL;
-}
-
-/*
- * Look through the list of trap instructions that are used for BUG(),
- * BUG_ON() and WARN_ON() and see if we hit one. At this point we know
- * that the exception was caused by a trap instruction of some kind.
- * Returns 1 if we should continue (i.e. it was a WARN_ON) or 0
- * otherwise.
- */
-extern struct bug_entry __start___bug_table[], __stop___bug_table[];
-
-#ifndef CONFIG_MODULES
-#define module_find_bug(x) NULL
-#endif
-
-struct bug_entry *find_bug(unsigned long bugaddr)
-{
- struct bug_entry *bug;
-
- for (bug = __start___bug_table; bug < __stop___bug_table; ++bug)
- if (bugaddr == bug->bug_addr)
- return bug;
- return module_find_bug(bugaddr);
-}
-
-static int
-check_bug_trap(struct pt_regs *regs)
-{
- struct bug_entry *bug;
- unsigned long addr;
-
- if (regs->msr & MSR_PR)
- return 0; /* not in kernel */
- addr = regs->nip; /* address of trap instruction */
- if (addr < PAGE_OFFSET)
- return 0;
- bug = find_bug(regs->nip);
- if (bug == NULL)
- return 0;
- if (bug->line & BUG_WARNING_TRAP) {
- /* this is a WARN_ON rather than BUG/BUG_ON */
- printk(KERN_ERR "Badness in %s at %s:%d\n",
- bug->function, bug->file,
- (unsigned int)bug->line & ~BUG_WARNING_TRAP);
- show_stack(current, (void *)regs->gpr[1]);
- return 1;
- }
- printk(KERN_CRIT "kernel BUG in %s at %s:%d!\n",
- bug->function, bug->file, (unsigned int)bug->line);
- return 0;
-}
-
-void __kprobes program_check_exception(struct pt_regs *regs)
-{
- if (debugger_fault_handler(regs))
- return;
-
- if (regs->msr & 0x100000) {
- /* IEEE FP exception */
- parse_fpe(regs);
- } else if (regs->msr & 0x20000) {
- /* trap exception */
-
- if (notify_die(DIE_BPT, "breakpoint", regs, 5,
- 5, SIGTRAP) == NOTIFY_STOP)
- return;
- if (debugger_bpt(regs))
- return;
-
- if (check_bug_trap(regs)) {
- regs->nip += 4;
- return;
- }
- _exception(SIGTRAP, regs, TRAP_BRKPT, regs->nip);
-
- } else {
- /* Privileged or illegal instruction; try to emulate it. */
- switch (emulate_instruction(regs)) {
- case 0:
- regs->nip += 4;
- emulate_single_step(regs);
- break;
-
- case -EFAULT:
- _exception(SIGSEGV, regs, SEGV_MAPERR, regs->nip);
- break;
-
- default:
- if (regs->msr & 0x40000)
- /* priveleged */
- _exception(SIGILL, regs, ILL_PRVOPC, regs->nip);
- else
- /* illegal */
- _exception(SIGILL, regs, ILL_ILLOPC, regs->nip);
- break;
- }
- }
-}
-
-void kernel_fp_unavailable_exception(struct pt_regs *regs)
-{
- printk(KERN_EMERG "Unrecoverable FP Unavailable Exception "
- "%lx at %lx\n", regs->trap, regs->nip);
- die("Unrecoverable FP Unavailable Exception", regs, SIGABRT);
-}
-
-void altivec_unavailable_exception(struct pt_regs *regs)
-{
- if (user_mode(regs)) {
- /* A user program has executed an altivec instruction,
- but this kernel doesn't support altivec. */
- _exception(SIGILL, regs, ILL_ILLOPC, regs->nip);
- return;
- }
- printk(KERN_EMERG "Unrecoverable VMX/Altivec Unavailable Exception "
- "%lx at %lx\n", regs->trap, regs->nip);
- die("Unrecoverable VMX/Altivec Unavailable Exception", regs, SIGABRT);
-}
-
-extern perf_irq_t perf_irq;
-
-void performance_monitor_exception(struct pt_regs *regs)
-{
- perf_irq(regs);
-}
-
-void alignment_exception(struct pt_regs *regs)
-{
- int fixed;
-
- fixed = fix_alignment(regs);
-
- if (fixed == 1) {
- regs->nip += 4; /* skip over emulated instruction */
- emulate_single_step(regs);
- return;
- }
-
- /* Operand address was bad */
- if (fixed == -EFAULT) {
- if (user_mode(regs)) {
- _exception(SIGSEGV, regs, SEGV_MAPERR, regs->dar);
- } else {
- /* Search exception table */
- bad_page_fault(regs, regs->dar, SIGSEGV);
- }
-
- return;
- }
-
- _exception(SIGBUS, regs, BUS_ADRALN, regs->nip);
-}
-
-#ifdef CONFIG_ALTIVEC
-void altivec_assist_exception(struct pt_regs *regs)
-{
- int err;
- siginfo_t info;
-
- if (!user_mode(regs)) {
- printk(KERN_EMERG "VMX/Altivec assist exception in kernel mode"
- " at %lx\n", regs->nip);
- die("Kernel VMX/Altivec assist exception", regs, SIGILL);
- }
-
- flush_altivec_to_thread(current);
-
- err = emulate_altivec(regs);
- if (err == 0) {
- regs->nip += 4; /* skip emulated instruction */
- emulate_single_step(regs);
- return;
- }
-
- if (err == -EFAULT) {
- /* got an error reading the instruction */
- info.si_signo = SIGSEGV;
- info.si_errno = 0;
- info.si_code = SEGV_MAPERR;
- info.si_addr = (void __user *) regs->nip;
- force_sig_info(SIGSEGV, &info, current);
- } else {
- /* didn't recognize the instruction */
- /* XXX quick hack for now: set the non-Java bit in the VSCR */
- if (printk_ratelimit())
- printk(KERN_ERR "Unrecognized altivec instruction "
- "in %s at %lx\n", current->comm, regs->nip);
- current->thread.vscr.u[3] |= 0x10000;
- }
-}
-#endif /* CONFIG_ALTIVEC */
-
-/*
- * We enter here if we get an unrecoverable exception, that is, one
- * that happened at a point where the RI (recoverable interrupt) bit
- * in the MSR is 0. This indicates that SRR0/1 are live, and that
- * we therefore lost state by taking this exception.
- */
-void unrecoverable_exception(struct pt_regs *regs)
-{
- printk(KERN_EMERG "Unrecoverable exception %lx at %lx\n",
- regs->trap, regs->nip);
- die("Unrecoverable exception", regs, SIGABRT);
-}
-
-/*
- * We enter here if we discover during exception entry that we are
- * running in supervisor mode with a userspace value in the stack pointer.
- */
-void kernel_bad_stack(struct pt_regs *regs)
-{
- printk(KERN_EMERG "Bad kernel stack pointer %lx at %lx\n",
- regs->gpr[1], regs->nip);
- die("Bad kernel stack pointer", regs, SIGABRT);
-}
-
-void __init trap_init(void)
-{
-}
diff --git a/arch/ppc64/kernel/udbg.c b/arch/ppc64/kernel/udbg.c
index d49c3613c8ec..0d878e72fc44 100644
--- a/arch/ppc64/kernel/udbg.c
+++ b/arch/ppc64/kernel/udbg.c
@@ -10,12 +10,10 @@
*/
#include <stdarg.h>
-#define WANT_PPCDBG_TAB /* Only defined here */
#include <linux/config.h>
#include <linux/types.h>
#include <linux/sched.h>
#include <linux/console.h>
-#include <asm/ppcdebug.h>
#include <asm/processor.h>
void (*udbg_putc)(unsigned char c);
@@ -89,59 +87,6 @@ void udbg_printf(const char *fmt, ...)
va_end(args);
}
-/* PPCDBG stuff */
-
-u64 ppc64_debug_switch;
-
-/* Special print used by PPCDBG() macro */
-void udbg_ppcdbg(unsigned long debug_flags, const char *fmt, ...)
-{
- unsigned long active_debugs = debug_flags & ppc64_debug_switch;
-
- if (active_debugs) {
- va_list ap;
- unsigned char buf[UDBG_BUFSIZE];
- unsigned long i, len = 0;
-
- for (i=0; i < PPCDBG_NUM_FLAGS; i++) {
- if (((1U << i) & active_debugs) &&
- trace_names[i]) {
- len += strlen(trace_names[i]);
- udbg_puts(trace_names[i]);
- break;
- }
- }
-
- snprintf(buf, UDBG_BUFSIZE, " [%s]: ", current->comm);
- len += strlen(buf);
- udbg_puts(buf);
-
- while (len < 18) {
- udbg_puts(" ");
- len++;
- }
-
- va_start(ap, fmt);
- vsnprintf(buf, UDBG_BUFSIZE, fmt, ap);
- udbg_puts(buf);
- va_end(ap);
- }
-}
-
-unsigned long udbg_ifdebug(unsigned long flags)
-{
- return (flags & ppc64_debug_switch);
-}
-
-/*
- * Initialize the PPCDBG state. Called before relocation has been enabled.
- */
-void __init ppcdbg_initialize(void)
-{
- ppc64_debug_switch = PPC_DEBUG_DEFAULT; /* | PPCDBG_BUSWALK | */
- /* PPCDBG_PHBINIT | PPCDBG_MM | PPCDBG_MMINIT | PPCDBG_TCEINIT | PPCDBG_TCE */;
-}
-
/*
* Early boot console based on udbg
*/
diff --git a/arch/ppc64/kernel/udbg_scc.c b/arch/ppc64/kernel/udbg_scc.c
index c47fd6c63531..820c53551507 100644
--- a/arch/ppc64/kernel/udbg_scc.c
+++ b/arch/ppc64/kernel/udbg_scc.c
@@ -12,7 +12,6 @@
#include <linux/types.h>
#include <asm/udbg.h>
#include <asm/processor.h>
-#include <asm/naca.h>
#include <asm/io.h>
#include <asm/prom.h>
#include <asm/pmac_feature.h>
diff --git a/arch/ppc64/kernel/vdso.c b/arch/ppc64/kernel/vdso.c
index efa985f05aca..1bbacac44988 100644
--- a/arch/ppc64/kernel/vdso.c
+++ b/arch/ppc64/kernel/vdso.c
@@ -34,6 +34,7 @@
#include <asm/machdep.h>
#include <asm/cputable.h>
#include <asm/sections.h>
+#include <asm/systemcfg.h>
#include <asm/vdso.h>
#undef DEBUG
@@ -176,13 +177,13 @@ static struct page * vdso_vma_nopage(struct vm_area_struct * vma,
return NOPAGE_SIGBUS;
/*
- * Last page is systemcfg, special handling here, no get_page() a
- * this is a reserved page
+ * Last page is systemcfg.
*/
if ((vma->vm_end - address) <= PAGE_SIZE)
- return virt_to_page(systemcfg);
+ pg = virt_to_page(_systemcfg);
+ else
+ pg = virt_to_page(vbase + offset);
- pg = virt_to_page(vbase + offset);
get_page(pg);
DBG(" ->page count: %d\n", page_count(pg));
@@ -259,7 +260,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int executable_stack)
* gettimeofday will be totally dead. It's fine to use that for setting
* breakpoints in the vDSO code pages though
*/
- vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC;
+ vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC | VM_RESERVED;
vma->vm_flags |= mm->def_flags;
vma->vm_page_prot = protection_map[vma->vm_flags & 0x7];
vma->vm_ops = &vdso_vmops;
@@ -603,6 +604,8 @@ void __init vdso_init(void)
ClearPageReserved(pg);
get_page(pg);
}
+
+ get_page(virt_to_page(_systemcfg));
}
int in_gate_area_no_task(unsigned long addr)
diff --git a/arch/ppc64/kernel/vdso64/sigtramp.S b/arch/ppc64/kernel/vdso64/sigtramp.S
index 8ae8f205e470..31b604ab56de 100644
--- a/arch/ppc64/kernel/vdso64/sigtramp.S
+++ b/arch/ppc64/kernel/vdso64/sigtramp.S
@@ -15,6 +15,7 @@
#include <asm/ppc_asm.h>
#include <asm/unistd.h>
#include <asm/vdso.h>
+#include <asm/ptrace.h> /* XXX for __SIGNAL_FRAMESIZE */
.text
diff --git a/arch/ppc64/kernel/vecemu.c b/arch/ppc64/kernel/vecemu.c
deleted file mode 100644
index cb207629f21f..000000000000
--- a/arch/ppc64/kernel/vecemu.c
+++ /dev/null
@@ -1,346 +0,0 @@
-/*
- * Routines to emulate some Altivec/VMX instructions, specifically
- * those that can trap when given denormalized operands in Java mode.
- */
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/sched.h>
-#include <asm/ptrace.h>
-#include <asm/processor.h>
-#include <asm/uaccess.h>
-
-/* Functions in vector.S */
-extern void vaddfp(vector128 *dst, vector128 *a, vector128 *b);
-extern void vsubfp(vector128 *dst, vector128 *a, vector128 *b);
-extern void vmaddfp(vector128 *dst, vector128 *a, vector128 *b, vector128 *c);
-extern void vnmsubfp(vector128 *dst, vector128 *a, vector128 *b, vector128 *c);
-extern void vrefp(vector128 *dst, vector128 *src);
-extern void vrsqrtefp(vector128 *dst, vector128 *src);
-extern void vexptep(vector128 *dst, vector128 *src);
-
-static unsigned int exp2s[8] = {
- 0x800000,
- 0x8b95c2,
- 0x9837f0,
- 0xa5fed7,
- 0xb504f3,
- 0xc5672a,
- 0xd744fd,
- 0xeac0c7
-};
-
-/*
- * Computes an estimate of 2^x. The `s' argument is the 32-bit
- * single-precision floating-point representation of x.
- */
-static unsigned int eexp2(unsigned int s)
-{
- int exp, pwr;
- unsigned int mant, frac;
-
- /* extract exponent field from input */
- exp = ((s >> 23) & 0xff) - 127;
- if (exp > 7) {
- /* check for NaN input */
- if (exp == 128 && (s & 0x7fffff) != 0)
- return s | 0x400000; /* return QNaN */
- /* 2^-big = 0, 2^+big = +Inf */
- return (s & 0x80000000)? 0: 0x7f800000; /* 0 or +Inf */
- }
- if (exp < -23)
- return 0x3f800000; /* 1.0 */
-
- /* convert to fixed point integer in 9.23 representation */
- pwr = (s & 0x7fffff) | 0x800000;
- if (exp > 0)
- pwr <<= exp;
- else
- pwr >>= -exp;
- if (s & 0x80000000)
- pwr = -pwr;
-
- /* extract integer part, which becomes exponent part of result */
- exp = (pwr >> 23) + 126;
- if (exp >= 254)
- return 0x7f800000;
- if (exp < -23)
- return 0;
-
- /* table lookup on top 3 bits of fraction to get mantissa */
- mant = exp2s[(pwr >> 20) & 7];
-
- /* linear interpolation using remaining 20 bits of fraction */
- asm("mulhwu %0,%1,%2" : "=r" (frac)
- : "r" (pwr << 12), "r" (0x172b83ff));
- asm("mulhwu %0,%1,%2" : "=r" (frac) : "r" (frac), "r" (mant));
- mant += frac;
-
- if (exp >= 0)
- return mant + (exp << 23);
-
- /* denormalized result */
- exp = -exp;
- mant += 1 << (exp - 1);
- return mant >> exp;
-}
-
-/*
- * Computes an estimate of log_2(x). The `s' argument is the 32-bit
- * single-precision floating-point representation of x.
- */
-static unsigned int elog2(unsigned int s)
-{
- int exp, mant, lz, frac;
-
- exp = s & 0x7f800000;
- mant = s & 0x7fffff;
- if (exp == 0x7f800000) { /* Inf or NaN */
- if (mant != 0)
- s |= 0x400000; /* turn NaN into QNaN */
- return s;
- }
- if ((exp | mant) == 0) /* +0 or -0 */
- return 0xff800000; /* return -Inf */
-
- if (exp == 0) {
- /* denormalized */
- asm("cntlzw %0,%1" : "=r" (lz) : "r" (mant));
- mant <<= lz - 8;
- exp = (-118 - lz) << 23;
- } else {
- mant |= 0x800000;
- exp -= 127 << 23;
- }
-
- if (mant >= 0xb504f3) { /* 2^0.5 * 2^23 */
- exp |= 0x400000; /* 0.5 * 2^23 */
- asm("mulhwu %0,%1,%2" : "=r" (mant)
- : "r" (mant), "r" (0xb504f334)); /* 2^-0.5 * 2^32 */
- }
- if (mant >= 0x9837f0) { /* 2^0.25 * 2^23 */
- exp |= 0x200000; /* 0.25 * 2^23 */
- asm("mulhwu %0,%1,%2" : "=r" (mant)
- : "r" (mant), "r" (0xd744fccb)); /* 2^-0.25 * 2^32 */
- }
- if (mant >= 0x8b95c2) { /* 2^0.125 * 2^23 */
- exp |= 0x100000; /* 0.125 * 2^23 */
- asm("mulhwu %0,%1,%2" : "=r" (mant)
- : "r" (mant), "r" (0xeac0c6e8)); /* 2^-0.125 * 2^32 */
- }
- if (mant > 0x800000) { /* 1.0 * 2^23 */
- /* calculate (mant - 1) * 1.381097463 */
- /* 1.381097463 == 0.125 / (2^0.125 - 1) */
- asm("mulhwu %0,%1,%2" : "=r" (frac)
- : "r" ((mant - 0x800000) << 1), "r" (0xb0c7cd3a));
- exp += frac;
- }
- s = exp & 0x80000000;
- if (exp != 0) {
- if (s)
- exp = -exp;
- asm("cntlzw %0,%1" : "=r" (lz) : "r" (exp));
- lz = 8 - lz;
- if (lz > 0)
- exp >>= lz;
- else if (lz < 0)
- exp <<= -lz;
- s += ((lz + 126) << 23) + exp;
- }
- return s;
-}
-
-#define VSCR_SAT 1
-
-static int ctsxs(unsigned int x, int scale, unsigned int *vscrp)
-{
- int exp, mant;
-
- exp = (x >> 23) & 0xff;
- mant = x & 0x7fffff;
- if (exp == 255 && mant != 0)
- return 0; /* NaN -> 0 */
- exp = exp - 127 + scale;
- if (exp < 0)
- return 0; /* round towards zero */
- if (exp >= 31) {
- /* saturate, unless the result would be -2^31 */
- if (x + (scale << 23) != 0xcf000000)
- *vscrp |= VSCR_SAT;
- return (x & 0x80000000)? 0x80000000: 0x7fffffff;
- }
- mant |= 0x800000;
- mant = (mant << 7) >> (30 - exp);
- return (x & 0x80000000)? -mant: mant;
-}
-
-static unsigned int ctuxs(unsigned int x, int scale, unsigned int *vscrp)
-{
- int exp;
- unsigned int mant;
-
- exp = (x >> 23) & 0xff;
- mant = x & 0x7fffff;
- if (exp == 255 && mant != 0)
- return 0; /* NaN -> 0 */
- exp = exp - 127 + scale;
- if (exp < 0)
- return 0; /* round towards zero */
- if (x & 0x80000000) {
- /* negative => saturate to 0 */
- *vscrp |= VSCR_SAT;
- return 0;
- }
- if (exp >= 32) {
- /* saturate */
- *vscrp |= VSCR_SAT;
- return 0xffffffff;
- }
- mant |= 0x800000;
- mant = (mant << 8) >> (31 - exp);
- return mant;
-}
-
-/* Round to floating integer, towards 0 */
-static unsigned int rfiz(unsigned int x)
-{
- int exp;
-
- exp = ((x >> 23) & 0xff) - 127;
- if (exp == 128 && (x & 0x7fffff) != 0)
- return x | 0x400000; /* NaN -> make it a QNaN */
- if (exp >= 23)
- return x; /* it's an integer already (or Inf) */
- if (exp < 0)
- return x & 0x80000000; /* |x| < 1.0 rounds to 0 */
- return x & ~(0x7fffff >> exp);
-}
-
-/* Round to floating integer, towards +/- Inf */
-static unsigned int rfii(unsigned int x)
-{
- int exp, mask;
-
- exp = ((x >> 23) & 0xff) - 127;
- if (exp == 128 && (x & 0x7fffff) != 0)
- return x | 0x400000; /* NaN -> make it a QNaN */
- if (exp >= 23)
- return x; /* it's an integer already (or Inf) */
- if ((x & 0x7fffffff) == 0)
- return x; /* +/-0 -> +/-0 */
- if (exp < 0)
- /* 0 < |x| < 1.0 rounds to +/- 1.0 */
- return (x & 0x80000000) | 0x3f800000;
- mask = 0x7fffff >> exp;
- /* mantissa overflows into exponent - that's OK,
- it can't overflow into the sign bit */
- return (x + mask) & ~mask;
-}
-
-/* Round to floating integer, to nearest */
-static unsigned int rfin(unsigned int x)
-{
- int exp, half;
-
- exp = ((x >> 23) & 0xff) - 127;
- if (exp == 128 && (x & 0x7fffff) != 0)
- return x | 0x400000; /* NaN -> make it a QNaN */
- if (exp >= 23)
- return x; /* it's an integer already (or Inf) */
- if (exp < -1)
- return x & 0x80000000; /* |x| < 0.5 -> +/-0 */
- if (exp == -1)
- /* 0.5 <= |x| < 1.0 rounds to +/- 1.0 */
- return (x & 0x80000000) | 0x3f800000;
- half = 0x400000 >> exp;
- /* add 0.5 to the magnitude and chop off the fraction bits */
- return (x + half) & ~(0x7fffff >> exp);
-}
-
-int
-emulate_altivec(struct pt_regs *regs)
-{
- unsigned int instr, i;
- unsigned int va, vb, vc, vd;
- vector128 *vrs;
-
- if (get_user(instr, (unsigned int __user *) regs->nip))
- return -EFAULT;
- if ((instr >> 26) != 4)
- return -EINVAL; /* not an altivec instruction */
- vd = (instr >> 21) & 0x1f;
- va = (instr >> 16) & 0x1f;
- vb = (instr >> 11) & 0x1f;
- vc = (instr >> 6) & 0x1f;
-
- vrs = current->thread.vr;
- switch (instr & 0x3f) {
- case 10:
- switch (vc) {
- case 0: /* vaddfp */
- vaddfp(&vrs[vd], &vrs[va], &vrs[vb]);
- break;
- case 1: /* vsubfp */
- vsubfp(&vrs[vd], &vrs[va], &vrs[vb]);
- break;
- case 4: /* vrefp */
- vrefp(&vrs[vd], &vrs[vb]);
- break;
- case 5: /* vrsqrtefp */
- vrsqrtefp(&vrs[vd], &vrs[vb]);
- break;
- case 6: /* vexptefp */
- for (i = 0; i < 4; ++i)
- vrs[vd].u[i] = eexp2(vrs[vb].u[i]);
- break;
- case 7: /* vlogefp */
- for (i = 0; i < 4; ++i)
- vrs[vd].u[i] = elog2(vrs[vb].u[i]);
- break;
- case 8: /* vrfin */
- for (i = 0; i < 4; ++i)
- vrs[vd].u[i] = rfin(vrs[vb].u[i]);
- break;
- case 9: /* vrfiz */
- for (i = 0; i < 4; ++i)
- vrs[vd].u[i] = rfiz(vrs[vb].u[i]);
- break;
- case 10: /* vrfip */
- for (i = 0; i < 4; ++i) {
- u32 x = vrs[vb].u[i];
- x = (x & 0x80000000)? rfiz(x): rfii(x);
- vrs[vd].u[i] = x;
- }
- break;
- case 11: /* vrfim */
- for (i = 0; i < 4; ++i) {
- u32 x = vrs[vb].u[i];
- x = (x & 0x80000000)? rfii(x): rfiz(x);
- vrs[vd].u[i] = x;
- }
- break;
- case 14: /* vctuxs */
- for (i = 0; i < 4; ++i)
- vrs[vd].u[i] = ctuxs(vrs[vb].u[i], va,
- &current->thread.vscr.u[3]);
- break;
- case 15: /* vctsxs */
- for (i = 0; i < 4; ++i)
- vrs[vd].u[i] = ctsxs(vrs[vb].u[i], va,
- &current->thread.vscr.u[3]);
- break;
- default:
- return -EINVAL;
- }
- break;
- case 46: /* vmaddfp */
- vmaddfp(&vrs[vd], &vrs[va], &vrs[vb], &vrs[vc]);
- break;
- case 47: /* vnmsubfp */
- vnmsubfp(&vrs[vd], &vrs[va], &vrs[vb], &vrs[vc]);
- break;
- default:
- return -EINVAL;
- }
-
- return 0;
-}
diff --git a/arch/ppc64/kernel/vmlinux.lds.S b/arch/ppc64/kernel/vmlinux.lds.S
index 0306510bc4ff..022f220e772f 100644
--- a/arch/ppc64/kernel/vmlinux.lds.S
+++ b/arch/ppc64/kernel/vmlinux.lds.S
@@ -1,3 +1,4 @@
+#include <asm/page.h>
#include <asm-generic/vmlinux.lds.h>
OUTPUT_ARCH(powerpc:common64)
@@ -17,7 +18,7 @@ SECTIONS
LOCK_TEXT
KPROBES_TEXT
*(.fixup)
- . = ALIGN(4096);
+ . = ALIGN(PAGE_SIZE);
_etext = .;
}
@@ -43,7 +44,7 @@ SECTIONS
/* will be freed after init */
- . = ALIGN(4096);
+ . = ALIGN(PAGE_SIZE);
__init_begin = .;
.init.text : {
@@ -83,7 +84,7 @@ SECTIONS
SECURITY_INIT
- . = ALIGN(4096);
+ . = ALIGN(PAGE_SIZE);
.init.ramfs : {
__initramfs_start = .;
*(.init.ramfs)
@@ -96,18 +97,22 @@ SECTIONS
__per_cpu_end = .;
}
+ . = ALIGN(PAGE_SIZE);
. = ALIGN(16384);
__init_end = .;
/* freed after init ends here */
/* Read/write sections */
+ . = ALIGN(PAGE_SIZE);
. = ALIGN(16384);
+ _sdata = .;
/* The initial task and kernel stack */
.data.init_task : {
*(.data.init_task)
}
+ . = ALIGN(PAGE_SIZE);
.data.page_aligned : {
*(.data.page_aligned)
}
@@ -129,18 +134,18 @@ SECTIONS
__toc_start = .;
*(.got)
*(.toc)
- . = ALIGN(4096);
+ . = ALIGN(PAGE_SIZE);
_edata = .;
}
- . = ALIGN(4096);
+ . = ALIGN(PAGE_SIZE);
.bss : {
__bss_start = .;
*(.bss)
__bss_stop = .;
}
- . = ALIGN(4096);
+ . = ALIGN(PAGE_SIZE);
_end = . ;
}
diff --git a/arch/ppc64/lib/Makefile b/arch/ppc64/lib/Makefile
deleted file mode 100644
index 0b6e967de948..000000000000
--- a/arch/ppc64/lib/Makefile
+++ /dev/null
@@ -1,18 +0,0 @@
-#
-# Makefile for ppc64-specific library files..
-#
-
-lib-y := checksum.o string.o strcase.o
-lib-y += copypage.o memcpy.o copyuser.o usercopy.o
-
-# Lock primitives are defined as no-ops in include/linux/spinlock.h
-# for non-SMP configs. Don't build the real versions.
-
-lib-$(CONFIG_SMP) += locks.o
-
-# e2a provides EBCDIC to ASCII conversions.
-ifdef CONFIG_PPC_ISERIES
-obj-y += e2a.o
-endif
-
-lib-$(CONFIG_DEBUG_KERNEL) += sstep.o
diff --git a/arch/ppc64/mm/Makefile b/arch/ppc64/mm/Makefile
deleted file mode 100644
index 3695d00d347f..000000000000
--- a/arch/ppc64/mm/Makefile
+++ /dev/null
@@ -1,11 +0,0 @@
-#
-# Makefile for the linux ppc-specific parts of the memory manager.
-#
-
-EXTRA_CFLAGS += -mno-minimal-toc
-
-obj-y := fault.o init.o imalloc.o hash_utils.o hash_low.o tlb.o \
- slb_low.o slb.o stab.o mmap.o
-obj-$(CONFIG_NEED_MULTIPLE_NODES) += numa.o
-obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
-obj-$(CONFIG_PPC_MULTIPLATFORM) += hash_native.o
diff --git a/arch/ppc64/mm/hash_low.S b/arch/ppc64/mm/hash_low.S
deleted file mode 100644
index ee5a5d36bfa8..000000000000
--- a/arch/ppc64/mm/hash_low.S
+++ /dev/null
@@ -1,288 +0,0 @@
-/*
- * ppc64 MMU hashtable management routines
- *
- * (c) Copyright IBM Corp. 2003
- *
- * Maintained by: Benjamin Herrenschmidt
- * <benh@kernel.crashing.org>
- *
- * This file is covered by the GNU Public Licence v2 as
- * described in the kernel's COPYING file.
- */
-
-#include <asm/processor.h>
-#include <asm/pgtable.h>
-#include <asm/mmu.h>
-#include <asm/page.h>
-#include <asm/types.h>
-#include <asm/ppc_asm.h>
-#include <asm/asm-offsets.h>
-#include <asm/cputable.h>
-
- .text
-
-/*
- * Stackframe:
- *
- * +-> Back chain (SP + 256)
- * | General register save area (SP + 112)
- * | Parameter save area (SP + 48)
- * | TOC save area (SP + 40)
- * | link editor doubleword (SP + 32)
- * | compiler doubleword (SP + 24)
- * | LR save area (SP + 16)
- * | CR save area (SP + 8)
- * SP ---> +-- Back chain (SP + 0)
- */
-#define STACKFRAMESIZE 256
-
-/* Save parameters offsets */
-#define STK_PARM(i) (STACKFRAMESIZE + 48 + ((i)-3)*8)
-
-/* Save non-volatile offsets */
-#define STK_REG(i) (112 + ((i)-14)*8)
-
-/*
- * _hash_page(unsigned long ea, unsigned long access, unsigned long vsid,
- * pte_t *ptep, unsigned long trap, int local)
- *
- * Adds a page to the hash table. This is the non-LPAR version for now
- */
-
-_GLOBAL(__hash_page)
- mflr r0
- std r0,16(r1)
- stdu r1,-STACKFRAMESIZE(r1)
- /* Save all params that we need after a function call */
- std r6,STK_PARM(r6)(r1)
- std r8,STK_PARM(r8)(r1)
-
- /* Add _PAGE_PRESENT to access */
- ori r4,r4,_PAGE_PRESENT
-
- /* Save non-volatile registers.
- * r31 will hold "old PTE"
- * r30 is "new PTE"
- * r29 is "va"
- * r28 is a hash value
- * r27 is hashtab mask (maybe dynamic patched instead ?)
- */
- std r27,STK_REG(r27)(r1)
- std r28,STK_REG(r28)(r1)
- std r29,STK_REG(r29)(r1)
- std r30,STK_REG(r30)(r1)
- std r31,STK_REG(r31)(r1)
-
- /* Step 1:
- *
- * Check permissions, atomically mark the linux PTE busy
- * and hashed.
- */
-1:
- ldarx r31,0,r6
- /* Check access rights (access & ~(pte_val(*ptep))) */
- andc. r0,r4,r31
- bne- htab_wrong_access
- /* Check if PTE is busy */
- andi. r0,r31,_PAGE_BUSY
- /* If so, just bail out and refault if needed. Someone else
- * is changing this PTE anyway and might hash it.
- */
- bne- bail_ok
- /* Prepare new PTE value (turn access RW into DIRTY, then
- * add BUSY,HASHPTE and ACCESSED)
- */
- rlwinm r30,r4,32-9+7,31-7,31-7 /* _PAGE_RW -> _PAGE_DIRTY */
- or r30,r30,r31
- ori r30,r30,_PAGE_BUSY | _PAGE_ACCESSED | _PAGE_HASHPTE
- /* Write the linux PTE atomically (setting busy) */
- stdcx. r30,0,r6
- bne- 1b
- isync
-
- /* Step 2:
- *
- * Insert/Update the HPTE in the hash table. At this point,
- * r4 (access) is re-useable, we use it for the new HPTE flags
- */
-
- /* Calc va and put it in r29 */
- rldicr r29,r5,28,63-28
- rldicl r3,r3,0,36
- or r29,r3,r29
-
- /* Calculate hash value for primary slot and store it in r28 */
- rldicl r5,r5,0,25 /* vsid & 0x0000007fffffffff */
- rldicl r0,r3,64-12,48 /* (ea >> 12) & 0xffff */
- xor r28,r5,r0
-
- /* Convert linux PTE bits into HW equivalents */
- andi. r3,r30,0x1fe /* Get basic set of flags */
- xori r3,r3,HW_NO_EXEC /* _PAGE_EXEC -> NOEXEC */
- rlwinm r0,r30,32-9+1,30,30 /* _PAGE_RW -> _PAGE_USER (r0) */
- rlwinm r4,r30,32-7+1,30,30 /* _PAGE_DIRTY -> _PAGE_USER (r4) */
- and r0,r0,r4 /* _PAGE_RW & _PAGE_DIRTY -> r0 bit 30 */
- andc r0,r30,r0 /* r0 = pte & ~r0 */
- rlwimi r3,r0,32-1,31,31 /* Insert result into PP lsb */
-
- /* We eventually do the icache sync here (maybe inline that
- * code rather than call a C function...)
- */
-BEGIN_FTR_SECTION
- mr r4,r30
- mr r5,r7
- bl .hash_page_do_lazy_icache
-END_FTR_SECTION(CPU_FTR_NOEXECUTE|CPU_FTR_COHERENT_ICACHE, CPU_FTR_NOEXECUTE)
-
- /* At this point, r3 contains new PP bits, save them in
- * place of "access" in the param area (sic)
- */
- std r3,STK_PARM(r4)(r1)
-
- /* Get htab_hash_mask */
- ld r4,htab_hash_mask@got(2)
- ld r27,0(r4) /* htab_hash_mask -> r27 */
-
- /* Check if we may already be in the hashtable, in this case, we
- * go to out-of-line code to try to modify the HPTE
- */
- andi. r0,r31,_PAGE_HASHPTE
- bne htab_modify_pte
-
-htab_insert_pte:
- /* Clear hpte bits in new pte (we also clear BUSY btw) and
- * add _PAGE_HASHPTE
- */
- lis r0,_PAGE_HPTEFLAGS@h
- ori r0,r0,_PAGE_HPTEFLAGS@l
- andc r30,r30,r0
- ori r30,r30,_PAGE_HASHPTE
-
- /* page number in r5 */
- rldicl r5,r31,64-PTE_SHIFT,PTE_SHIFT
-
- /* Calculate primary group hash */
- and r0,r28,r27
- rldicr r3,r0,3,63-3 /* r0 = (hash & mask) << 3 */
-
- /* Call ppc_md.hpte_insert */
- ld r7,STK_PARM(r4)(r1) /* Retreive new pp bits */
- mr r4,r29 /* Retreive va */
- li r6,0 /* no vflags */
-_GLOBAL(htab_call_hpte_insert1)
- bl . /* Will be patched by htab_finish_init() */
- cmpdi 0,r3,0
- bge htab_pte_insert_ok /* Insertion successful */
- cmpdi 0,r3,-2 /* Critical failure */
- beq- htab_pte_insert_failure
-
- /* Now try secondary slot */
-
- /* page number in r5 */
- rldicl r5,r31,64-PTE_SHIFT,PTE_SHIFT
-
- /* Calculate secondary group hash */
- andc r0,r27,r28
- rldicr r3,r0,3,63-3 /* r0 = (~hash & mask) << 3 */
-
- /* Call ppc_md.hpte_insert */
- ld r7,STK_PARM(r4)(r1) /* Retreive new pp bits */
- mr r4,r29 /* Retreive va */
- li r6,HPTE_V_SECONDARY@l /* secondary slot */
-_GLOBAL(htab_call_hpte_insert2)
- bl . /* Will be patched by htab_finish_init() */
- cmpdi 0,r3,0
- bge+ htab_pte_insert_ok /* Insertion successful */
- cmpdi 0,r3,-2 /* Critical failure */
- beq- htab_pte_insert_failure
-
- /* Both are full, we need to evict something */
- mftb r0
- /* Pick a random group based on TB */
- andi. r0,r0,1
- mr r5,r28
- bne 2f
- not r5,r5
-2: and r0,r5,r27
- rldicr r3,r0,3,63-3 /* r0 = (hash & mask) << 3 */
- /* Call ppc_md.hpte_remove */
-_GLOBAL(htab_call_hpte_remove)
- bl . /* Will be patched by htab_finish_init() */
-
- /* Try all again */
- b htab_insert_pte
-
-bail_ok:
- li r3,0
- b bail
-
-htab_pte_insert_ok:
- /* Insert slot number & secondary bit in PTE */
- rldimi r30,r3,12,63-15
-
- /* Write out the PTE with a normal write
- * (maybe add eieio may be good still ?)
- */
-htab_write_out_pte:
- ld r6,STK_PARM(r6)(r1)
- std r30,0(r6)
- li r3, 0
-bail:
- ld r27,STK_REG(r27)(r1)
- ld r28,STK_REG(r28)(r1)
- ld r29,STK_REG(r29)(r1)
- ld r30,STK_REG(r30)(r1)
- ld r31,STK_REG(r31)(r1)
- addi r1,r1,STACKFRAMESIZE
- ld r0,16(r1)
- mtlr r0
- blr
-
-htab_modify_pte:
- /* Keep PP bits in r4 and slot idx from the PTE around in r3 */
- mr r4,r3
- rlwinm r3,r31,32-12,29,31
-
- /* Secondary group ? if yes, get a inverted hash value */
- mr r5,r28
- andi. r0,r31,_PAGE_SECONDARY
- beq 1f
- not r5,r5
-1:
- /* Calculate proper slot value for ppc_md.hpte_updatepp */
- and r0,r5,r27
- rldicr r0,r0,3,63-3 /* r0 = (hash & mask) << 3 */
- add r3,r0,r3 /* add slot idx */
-
- /* Call ppc_md.hpte_updatepp */
- mr r5,r29 /* va */
- li r6,0 /* large is 0 */
- ld r7,STK_PARM(r8)(r1) /* get "local" param */
-_GLOBAL(htab_call_hpte_updatepp)
- bl . /* Will be patched by htab_finish_init() */
-
- /* if we failed because typically the HPTE wasn't really here
- * we try an insertion.
- */
- cmpdi 0,r3,-1
- beq- htab_insert_pte
-
- /* Clear the BUSY bit and Write out the PTE */
- li r0,_PAGE_BUSY
- andc r30,r30,r0
- b htab_write_out_pte
-
-htab_wrong_access:
- /* Bail out clearing reservation */
- stdcx. r31,0,r6
- li r3,1
- b bail
-
-htab_pte_insert_failure:
- /* Bail out restoring old PTE */
- ld r6,STK_PARM(r6)(r1)
- std r31,0(r6)
- li r3,-1
- b bail
-
-
diff --git a/arch/ppc64/mm/hash_utils.c b/arch/ppc64/mm/hash_utils.c
deleted file mode 100644
index 09475c8edf7c..000000000000
--- a/arch/ppc64/mm/hash_utils.c
+++ /dev/null
@@ -1,438 +0,0 @@
-/*
- * PowerPC64 port by Mike Corrigan and Dave Engebretsen
- * {mikejc|engebret}@us.ibm.com
- *
- * Copyright (c) 2000 Mike Corrigan <mikejc@us.ibm.com>
- *
- * SMP scalability work:
- * Copyright (C) 2001 Anton Blanchard <anton@au.ibm.com>, IBM
- *
- * Module name: htab.c
- *
- * Description:
- * PowerPC Hashed Page Table functions
- *
- * 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.
- */
-
-#undef DEBUG
-
-#include <linux/config.h>
-#include <linux/spinlock.h>
-#include <linux/errno.h>
-#include <linux/sched.h>
-#include <linux/proc_fs.h>
-#include <linux/stat.h>
-#include <linux/sysctl.h>
-#include <linux/ctype.h>
-#include <linux/cache.h>
-#include <linux/init.h>
-#include <linux/signal.h>
-
-#include <asm/ppcdebug.h>
-#include <asm/processor.h>
-#include <asm/pgtable.h>
-#include <asm/mmu.h>
-#include <asm/mmu_context.h>
-#include <asm/page.h>
-#include <asm/types.h>
-#include <asm/system.h>
-#include <asm/uaccess.h>
-#include <asm/machdep.h>
-#include <asm/lmb.h>
-#include <asm/abs_addr.h>
-#include <asm/tlbflush.h>
-#include <asm/io.h>
-#include <asm/eeh.h>
-#include <asm/tlb.h>
-#include <asm/cacheflush.h>
-#include <asm/cputable.h>
-#include <asm/abs_addr.h>
-#include <asm/sections.h>
-
-#ifdef DEBUG
-#define DBG(fmt...) udbg_printf(fmt)
-#else
-#define DBG(fmt...)
-#endif
-
-/*
- * Note: pte --> Linux PTE
- * HPTE --> PowerPC Hashed Page Table Entry
- *
- * Execution context:
- * htab_initialize is called with the MMU off (of course), but
- * the kernel has been copied down to zero so it can directly
- * reference global data. At this point it is very difficult
- * to print debug info.
- *
- */
-
-#ifdef CONFIG_U3_DART
-extern unsigned long dart_tablebase;
-#endif /* CONFIG_U3_DART */
-
-hpte_t *htab_address;
-unsigned long htab_hash_mask;
-
-extern unsigned long _SDR1;
-
-#define KB (1024)
-#define MB (1024*KB)
-
-static inline void loop_forever(void)
-{
- volatile unsigned long x = 1;
- for(;x;x|=1)
- ;
-}
-
-#ifdef CONFIG_PPC_MULTIPLATFORM
-static inline void create_pte_mapping(unsigned long start, unsigned long end,
- unsigned long mode, int large)
-{
- unsigned long addr;
- unsigned int step;
- unsigned long tmp_mode;
- unsigned long vflags;
-
- if (large) {
- step = 16*MB;
- vflags = HPTE_V_BOLTED | HPTE_V_LARGE;
- } else {
- step = 4*KB;
- vflags = HPTE_V_BOLTED;
- }
-
- for (addr = start; addr < end; addr += step) {
- unsigned long vpn, hash, hpteg;
- unsigned long vsid = get_kernel_vsid(addr);
- unsigned long va = (vsid << 28) | (addr & 0xfffffff);
- int ret;
-
- if (large)
- vpn = va >> HPAGE_SHIFT;
- else
- vpn = va >> PAGE_SHIFT;
-
-
- tmp_mode = mode;
-
- /* Make non-kernel text non-executable */
- if (!in_kernel_text(addr))
- tmp_mode = mode | HW_NO_EXEC;
-
- hash = hpt_hash(vpn, large);
-
- hpteg = ((hash & htab_hash_mask) * HPTES_PER_GROUP);
-
-#ifdef CONFIG_PPC_PSERIES
- if (systemcfg->platform & PLATFORM_LPAR)
- ret = pSeries_lpar_hpte_insert(hpteg, va,
- virt_to_abs(addr) >> PAGE_SHIFT,
- vflags, tmp_mode);
- else
-#endif /* CONFIG_PPC_PSERIES */
- ret = native_hpte_insert(hpteg, va,
- virt_to_abs(addr) >> PAGE_SHIFT,
- vflags, tmp_mode);
-
- if (ret == -1) {
- ppc64_terminate_msg(0x20, "create_pte_mapping");
- loop_forever();
- }
- }
-}
-
-void __init htab_initialize(void)
-{
- unsigned long table, htab_size_bytes;
- unsigned long pteg_count;
- unsigned long mode_rw;
- int i, use_largepages = 0;
- unsigned long base = 0, size = 0;
- extern unsigned long tce_alloc_start, tce_alloc_end;
-
- DBG(" -> htab_initialize()\n");
-
- /*
- * Calculate the required size of the htab. We want the number of
- * PTEGs to equal one half the number of real pages.
- */
- htab_size_bytes = 1UL << ppc64_pft_size;
- pteg_count = htab_size_bytes >> 7;
-
- /* For debug, make the HTAB 1/8 as big as it normally would be. */
- ifppcdebug(PPCDBG_HTABSIZE) {
- pteg_count >>= 3;
- htab_size_bytes = pteg_count << 7;
- }
-
- htab_hash_mask = pteg_count - 1;
-
- if (systemcfg->platform & PLATFORM_LPAR) {
- /* Using a hypervisor which owns the htab */
- htab_address = NULL;
- _SDR1 = 0;
- } else {
- /* Find storage for the HPT. Must be contiguous in
- * the absolute address space.
- */
- table = lmb_alloc(htab_size_bytes, htab_size_bytes);
-
- DBG("Hash table allocated at %lx, size: %lx\n", table,
- htab_size_bytes);
-
- if ( !table ) {
- ppc64_terminate_msg(0x20, "hpt space");
- loop_forever();
- }
- htab_address = abs_to_virt(table);
-
- /* htab absolute addr + encoded htabsize */
- _SDR1 = table + __ilog2(pteg_count) - 11;
-
- /* Initialize the HPT with no entries */
- memset((void *)table, 0, htab_size_bytes);
- }
-
- mode_rw = _PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_COHERENT | PP_RWXX;
-
- /* On U3 based machines, we need to reserve the DART area and
- * _NOT_ map it to avoid cache paradoxes as it's remapped non
- * cacheable later on
- */
- if (cpu_has_feature(CPU_FTR_16M_PAGE))
- use_largepages = 1;
-
- /* create bolted the linear mapping in the hash table */
- for (i=0; i < lmb.memory.cnt; i++) {
- base = lmb.memory.region[i].base + KERNELBASE;
- size = lmb.memory.region[i].size;
-
- DBG("creating mapping for region: %lx : %lx\n", base, size);
-
-#ifdef CONFIG_U3_DART
- /* Do not map the DART space. Fortunately, it will be aligned
- * in such a way that it will not cross two lmb regions and will
- * fit within a single 16Mb page.
- * The DART space is assumed to be a full 16Mb region even if we
- * only use 2Mb of that space. We will use more of it later for
- * AGP GART. We have to use a full 16Mb large page.
- */
- DBG("DART base: %lx\n", dart_tablebase);
-
- if (dart_tablebase != 0 && dart_tablebase >= base
- && dart_tablebase < (base + size)) {
- if (base != dart_tablebase)
- create_pte_mapping(base, dart_tablebase, mode_rw,
- use_largepages);
- if ((base + size) > (dart_tablebase + 16*MB))
- create_pte_mapping(dart_tablebase + 16*MB, base + size,
- mode_rw, use_largepages);
- continue;
- }
-#endif /* CONFIG_U3_DART */
- create_pte_mapping(base, base + size, mode_rw, use_largepages);
- }
-
- /*
- * If we have a memory_limit and we've allocated TCEs then we need to
- * explicitly map the TCE area at the top of RAM. We also cope with the
- * case that the TCEs start below memory_limit.
- * tce_alloc_start/end are 16MB aligned so the mapping should work
- * for either 4K or 16MB pages.
- */
- if (tce_alloc_start) {
- tce_alloc_start += KERNELBASE;
- tce_alloc_end += KERNELBASE;
-
- if (base + size >= tce_alloc_start)
- tce_alloc_start = base + size + 1;
-
- create_pte_mapping(tce_alloc_start, tce_alloc_end,
- mode_rw, use_largepages);
- }
-
- DBG(" <- htab_initialize()\n");
-}
-#undef KB
-#undef MB
-#endif /* CONFIG_PPC_MULTIPLATFORM */
-
-/*
- * Called by asm hashtable.S for doing lazy icache flush
- */
-unsigned int hash_page_do_lazy_icache(unsigned int pp, pte_t pte, int trap)
-{
- struct page *page;
-
- if (!pfn_valid(pte_pfn(pte)))
- return pp;
-
- page = pte_page(pte);
-
- /* page is dirty */
- if (!test_bit(PG_arch_1, &page->flags) && !PageReserved(page)) {
- if (trap == 0x400) {
- __flush_dcache_icache(page_address(page));
- set_bit(PG_arch_1, &page->flags);
- } else
- pp |= HW_NO_EXEC;
- }
- return pp;
-}
-
-/* Result code is:
- * 0 - handled
- * 1 - normal page fault
- * -1 - critical hash insertion error
- */
-int hash_page(unsigned long ea, unsigned long access, unsigned long trap)
-{
- void *pgdir;
- unsigned long vsid;
- struct mm_struct *mm;
- pte_t *ptep;
- int ret;
- int user_region = 0;
- int local = 0;
- cpumask_t tmp;
-
- if ((ea & ~REGION_MASK) >= PGTABLE_RANGE)
- return 1;
-
- switch (REGION_ID(ea)) {
- case USER_REGION_ID:
- user_region = 1;
- mm = current->mm;
- if (! mm)
- return 1;
-
- vsid = get_vsid(mm->context.id, ea);
- break;
- case VMALLOC_REGION_ID:
- mm = &init_mm;
- vsid = get_kernel_vsid(ea);
- break;
-#if 0
- case KERNEL_REGION_ID:
- /*
- * Should never get here - entire 0xC0... region is bolted.
- * Send the problem up to do_page_fault
- */
-#endif
- default:
- /* Not a valid range
- * Send the problem up to do_page_fault
- */
- return 1;
- break;
- }
-
- pgdir = mm->pgd;
-
- if (pgdir == NULL)
- return 1;
-
- tmp = cpumask_of_cpu(smp_processor_id());
- if (user_region && cpus_equal(mm->cpu_vm_mask, tmp))
- local = 1;
-
- /* Is this a huge page ? */
- if (unlikely(in_hugepage_area(mm->context, ea)))
- ret = hash_huge_page(mm, access, ea, vsid, local);
- else {
- ptep = find_linux_pte(pgdir, ea);
- if (ptep == NULL)
- return 1;
- ret = __hash_page(ea, access, vsid, ptep, trap, local);
- }
-
- return ret;
-}
-
-void flush_hash_page(unsigned long context, unsigned long ea, pte_t pte,
- int local)
-{
- unsigned long vsid, vpn, va, hash, secondary, slot;
- unsigned long huge = pte_huge(pte);
-
- if (ea < KERNELBASE)
- vsid = get_vsid(context, ea);
- else
- vsid = get_kernel_vsid(ea);
-
- va = (vsid << 28) | (ea & 0x0fffffff);
- if (huge)
- vpn = va >> HPAGE_SHIFT;
- else
- vpn = va >> PAGE_SHIFT;
- hash = hpt_hash(vpn, huge);
- secondary = (pte_val(pte) & _PAGE_SECONDARY) >> 15;
- if (secondary)
- hash = ~hash;
- slot = (hash & htab_hash_mask) * HPTES_PER_GROUP;
- slot += (pte_val(pte) & _PAGE_GROUP_IX) >> 12;
-
- ppc_md.hpte_invalidate(slot, va, huge, local);
-}
-
-void flush_hash_range(unsigned long context, unsigned long number, int local)
-{
- if (ppc_md.flush_hash_range) {
- ppc_md.flush_hash_range(context, number, local);
- } else {
- int i;
- struct ppc64_tlb_batch *batch = &__get_cpu_var(ppc64_tlb_batch);
-
- for (i = 0; i < number; i++)
- flush_hash_page(context, batch->addr[i], batch->pte[i],
- local);
- }
-}
-
-static inline void make_bl(unsigned int *insn_addr, void *func)
-{
- unsigned long funcp = *((unsigned long *)func);
- int offset = funcp - (unsigned long)insn_addr;
-
- *insn_addr = (unsigned int)(0x48000001 | (offset & 0x03fffffc));
- flush_icache_range((unsigned long)insn_addr, 4+
- (unsigned long)insn_addr);
-}
-
-/*
- * low_hash_fault is called when we the low level hash code failed
- * to instert a PTE due to an hypervisor error
- */
-void low_hash_fault(struct pt_regs *regs, unsigned long address)
-{
- if (user_mode(regs)) {
- siginfo_t info;
-
- info.si_signo = SIGBUS;
- info.si_errno = 0;
- info.si_code = BUS_ADRERR;
- info.si_addr = (void __user *)address;
- force_sig_info(SIGBUS, &info, current);
- return;
- }
- bad_page_fault(regs, address, SIGBUS);
-}
-
-void __init htab_finish_init(void)
-{
- extern unsigned int *htab_call_hpte_insert1;
- extern unsigned int *htab_call_hpte_insert2;
- extern unsigned int *htab_call_hpte_remove;
- extern unsigned int *htab_call_hpte_updatepp;
-
- make_bl(htab_call_hpte_insert1, ppc_md.hpte_insert);
- make_bl(htab_call_hpte_insert2, ppc_md.hpte_insert);
- make_bl(htab_call_hpte_remove, ppc_md.hpte_remove);
- make_bl(htab_call_hpte_updatepp, ppc_md.hpte_updatepp);
-}
diff --git a/arch/ppc64/mm/init.c b/arch/ppc64/mm/init.c
deleted file mode 100644
index be64b157afce..000000000000
--- a/arch/ppc64/mm/init.c
+++ /dev/null
@@ -1,869 +0,0 @@
-/*
- * PowerPC version
- * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
- *
- * Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au)
- * and Cort Dougan (PReP) (cort@cs.nmt.edu)
- * Copyright (C) 1996 Paul Mackerras
- * Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk).
- *
- * Derived from "arch/i386/mm/init.c"
- * Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds
- *
- * Dave Engebretsen <engebret@us.ibm.com>
- * Rework for PPC64 port.
- *
- * 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/config.h>
-#include <linux/signal.h>
-#include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/string.h>
-#include <linux/types.h>
-#include <linux/mman.h>
-#include <linux/mm.h>
-#include <linux/swap.h>
-#include <linux/stddef.h>
-#include <linux/vmalloc.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/bootmem.h>
-#include <linux/highmem.h>
-#include <linux/idr.h>
-#include <linux/nodemask.h>
-#include <linux/module.h>
-
-#include <asm/pgalloc.h>
-#include <asm/page.h>
-#include <asm/prom.h>
-#include <asm/lmb.h>
-#include <asm/rtas.h>
-#include <asm/io.h>
-#include <asm/mmu_context.h>
-#include <asm/pgtable.h>
-#include <asm/mmu.h>
-#include <asm/uaccess.h>
-#include <asm/smp.h>
-#include <asm/machdep.h>
-#include <asm/tlb.h>
-#include <asm/eeh.h>
-#include <asm/processor.h>
-#include <asm/mmzone.h>
-#include <asm/cputable.h>
-#include <asm/ppcdebug.h>
-#include <asm/sections.h>
-#include <asm/system.h>
-#include <asm/iommu.h>
-#include <asm/abs_addr.h>
-#include <asm/vdso.h>
-#include <asm/imalloc.h>
-
-#if PGTABLE_RANGE > USER_VSID_RANGE
-#warning Limited user VSID range means pagetable space is wasted
-#endif
-
-#if (TASK_SIZE_USER64 < PGTABLE_RANGE) && (TASK_SIZE_USER64 < USER_VSID_RANGE)
-#warning TASK_SIZE is smaller than it needs to be.
-#endif
-
-int mem_init_done;
-unsigned long ioremap_bot = IMALLOC_BASE;
-static unsigned long phbs_io_bot = PHBS_IO_BASE;
-
-extern pgd_t swapper_pg_dir[];
-extern struct task_struct *current_set[NR_CPUS];
-
-unsigned long klimit = (unsigned long)_end;
-
-unsigned long _SDR1=0;
-unsigned long _ASR=0;
-
-/* max amount of RAM to use */
-unsigned long __max_memory;
-
-/* info on what we think the IO hole is */
-unsigned long io_hole_start;
-unsigned long io_hole_size;
-
-void show_mem(void)
-{
- unsigned long total = 0, reserved = 0;
- unsigned long shared = 0, cached = 0;
- struct page *page;
- pg_data_t *pgdat;
- unsigned long i;
-
- printk("Mem-info:\n");
- show_free_areas();
- printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10));
- for_each_pgdat(pgdat) {
- for (i = 0; i < pgdat->node_spanned_pages; i++) {
- page = pgdat_page_nr(pgdat, i);
- total++;
- if (PageReserved(page))
- reserved++;
- else if (PageSwapCache(page))
- cached++;
- else if (page_count(page))
- shared += page_count(page) - 1;
- }
- }
- printk("%ld pages of RAM\n", total);
- printk("%ld reserved pages\n", reserved);
- printk("%ld pages shared\n", shared);
- printk("%ld pages swap cached\n", cached);
-}
-
-#ifdef CONFIG_PPC_ISERIES
-
-void __iomem *ioremap(unsigned long addr, unsigned long size)
-{
- return (void __iomem *)addr;
-}
-
-extern void __iomem *__ioremap(unsigned long addr, unsigned long size,
- unsigned long flags)
-{
- return (void __iomem *)addr;
-}
-
-void iounmap(volatile void __iomem *addr)
-{
- return;
-}
-
-#else
-
-/*
- * map_io_page currently only called by __ioremap
- * map_io_page adds an entry to the ioremap page table
- * and adds an entry to the HPT, possibly bolting it
- */
-static int map_io_page(unsigned long ea, unsigned long pa, int flags)
-{
- pgd_t *pgdp;
- pud_t *pudp;
- pmd_t *pmdp;
- pte_t *ptep;
- unsigned long vsid;
-
- if (mem_init_done) {
- spin_lock(&init_mm.page_table_lock);
- pgdp = pgd_offset_k(ea);
- pudp = pud_alloc(&init_mm, pgdp, ea);
- if (!pudp)
- return -ENOMEM;
- pmdp = pmd_alloc(&init_mm, pudp, ea);
- if (!pmdp)
- return -ENOMEM;
- ptep = pte_alloc_kernel(&init_mm, pmdp, ea);
- if (!ptep)
- return -ENOMEM;
- set_pte_at(&init_mm, ea, ptep, pfn_pte(pa >> PAGE_SHIFT,
- __pgprot(flags)));
- spin_unlock(&init_mm.page_table_lock);
- } else {
- unsigned long va, vpn, hash, hpteg;
-
- /*
- * If the mm subsystem is not fully up, we cannot create a
- * linux page table entry for this mapping. Simply bolt an
- * entry in the hardware page table.
- */
- vsid = get_kernel_vsid(ea);
- va = (vsid << 28) | (ea & 0xFFFFFFF);
- vpn = va >> PAGE_SHIFT;
-
- hash = hpt_hash(vpn, 0);
-
- hpteg = ((hash & htab_hash_mask) * HPTES_PER_GROUP);
-
- /* Panic if a pte grpup is full */
- if (ppc_md.hpte_insert(hpteg, va, pa >> PAGE_SHIFT,
- HPTE_V_BOLTED,
- _PAGE_NO_CACHE|_PAGE_GUARDED|PP_RWXX)
- == -1) {
- panic("map_io_page: could not insert mapping");
- }
- }
- return 0;
-}
-
-
-static void __iomem * __ioremap_com(unsigned long addr, unsigned long pa,
- unsigned long ea, unsigned long size,
- unsigned long flags)
-{
- unsigned long i;
-
- if ((flags & _PAGE_PRESENT) == 0)
- flags |= pgprot_val(PAGE_KERNEL);
-
- for (i = 0; i < size; i += PAGE_SIZE)
- if (map_io_page(ea+i, pa+i, flags))
- return NULL;
-
- return (void __iomem *) (ea + (addr & ~PAGE_MASK));
-}
-
-
-void __iomem *
-ioremap(unsigned long addr, unsigned long size)
-{
- return __ioremap(addr, size, _PAGE_NO_CACHE | _PAGE_GUARDED);
-}
-
-void __iomem * __ioremap(unsigned long addr, unsigned long size,
- unsigned long flags)
-{
- unsigned long pa, ea;
- void __iomem *ret;
-
- /*
- * Choose an address to map it to.
- * Once the imalloc system is running, we use it.
- * Before that, we map using addresses going
- * up from ioremap_bot. imalloc will use
- * the addresses from ioremap_bot through
- * IMALLOC_END
- *
- */
- pa = addr & PAGE_MASK;
- size = PAGE_ALIGN(addr + size) - pa;
-
- if (size == 0)
- return NULL;
-
- if (mem_init_done) {
- struct vm_struct *area;
- area = im_get_free_area(size);
- if (area == NULL)
- return NULL;
- ea = (unsigned long)(area->addr);
- ret = __ioremap_com(addr, pa, ea, size, flags);
- if (!ret)
- im_free(area->addr);
- } else {
- ea = ioremap_bot;
- ret = __ioremap_com(addr, pa, ea, size, flags);
- if (ret)
- ioremap_bot += size;
- }
- return ret;
-}
-
-#define IS_PAGE_ALIGNED(_val) ((_val) == ((_val) & PAGE_MASK))
-
-int __ioremap_explicit(unsigned long pa, unsigned long ea,
- unsigned long size, unsigned long flags)
-{
- struct vm_struct *area;
- void __iomem *ret;
-
- /* For now, require page-aligned values for pa, ea, and size */
- if (!IS_PAGE_ALIGNED(pa) || !IS_PAGE_ALIGNED(ea) ||
- !IS_PAGE_ALIGNED(size)) {
- printk(KERN_ERR "unaligned value in %s\n", __FUNCTION__);
- return 1;
- }
-
- if (!mem_init_done) {
- /* Two things to consider in this case:
- * 1) No records will be kept (imalloc, etc) that the region
- * has been remapped
- * 2) It won't be easy to iounmap() the region later (because
- * of 1)
- */
- ;
- } else {
- area = im_get_area(ea, size,
- IM_REGION_UNUSED|IM_REGION_SUBSET|IM_REGION_EXISTS);
- if (area == NULL) {
- /* Expected when PHB-dlpar is in play */
- return 1;
- }
- if (ea != (unsigned long) area->addr) {
- printk(KERN_ERR "unexpected addr return from "
- "im_get_area\n");
- return 1;
- }
- }
-
- ret = __ioremap_com(pa, pa, ea, size, flags);
- if (ret == NULL) {
- printk(KERN_ERR "ioremap_explicit() allocation failure !\n");
- return 1;
- }
- if (ret != (void *) ea) {
- printk(KERN_ERR "__ioremap_com() returned unexpected addr\n");
- return 1;
- }
-
- return 0;
-}
-
-/*
- * Unmap an IO region and remove it from imalloc'd list.
- * Access to IO memory should be serialized by driver.
- * This code is modeled after vmalloc code - unmap_vm_area()
- *
- * XXX what about calls before mem_init_done (ie python_countermeasures())
- */
-void iounmap(volatile void __iomem *token)
-{
- void *addr;
-
- if (!mem_init_done)
- return;
-
- addr = (void *) ((unsigned long __force) token & PAGE_MASK);
-
- im_free(addr);
-}
-
-static int iounmap_subset_regions(unsigned long addr, unsigned long size)
-{
- struct vm_struct *area;
-
- /* Check whether subsets of this region exist */
- area = im_get_area(addr, size, IM_REGION_SUPERSET);
- if (area == NULL)
- return 1;
-
- while (area) {
- iounmap((void __iomem *) area->addr);
- area = im_get_area(addr, size,
- IM_REGION_SUPERSET);
- }
-
- return 0;
-}
-
-int iounmap_explicit(volatile void __iomem *start, unsigned long size)
-{
- struct vm_struct *area;
- unsigned long addr;
- int rc;
-
- addr = (unsigned long __force) start & PAGE_MASK;
-
- /* Verify that the region either exists or is a subset of an existing
- * region. In the latter case, split the parent region to create
- * the exact region
- */
- area = im_get_area(addr, size,
- IM_REGION_EXISTS | IM_REGION_SUBSET);
- if (area == NULL) {
- /* Determine whether subset regions exist. If so, unmap */
- rc = iounmap_subset_regions(addr, size);
- if (rc) {
- printk(KERN_ERR
- "%s() cannot unmap nonexistent range 0x%lx\n",
- __FUNCTION__, addr);
- return 1;
- }
- } else {
- iounmap((void __iomem *) area->addr);
- }
- /*
- * FIXME! This can't be right:
- iounmap(area->addr);
- * Maybe it should be "iounmap(area);"
- */
- return 0;
-}
-
-#endif
-
-EXPORT_SYMBOL(ioremap);
-EXPORT_SYMBOL(__ioremap);
-EXPORT_SYMBOL(iounmap);
-
-void free_initmem(void)
-{
- unsigned long addr;
-
- addr = (unsigned long)__init_begin;
- for (; addr < (unsigned long)__init_end; addr += PAGE_SIZE) {
- memset((void *)addr, 0xcc, PAGE_SIZE);
- ClearPageReserved(virt_to_page(addr));
- set_page_count(virt_to_page(addr), 1);
- free_page(addr);
- totalram_pages++;
- }
- printk ("Freeing unused kernel memory: %luk freed\n",
- ((unsigned long)__init_end - (unsigned long)__init_begin) >> 10);
-}
-
-#ifdef CONFIG_BLK_DEV_INITRD
-void free_initrd_mem(unsigned long start, unsigned long end)
-{
- if (start < end)
- printk ("Freeing initrd memory: %ldk freed\n", (end - start) >> 10);
- for (; start < end; start += PAGE_SIZE) {
- ClearPageReserved(virt_to_page(start));
- set_page_count(virt_to_page(start), 1);
- free_page(start);
- totalram_pages++;
- }
-}
-#endif
-
-static DEFINE_SPINLOCK(mmu_context_lock);
-static DEFINE_IDR(mmu_context_idr);
-
-int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
-{
- int index;
- int err;
-
-again:
- if (!idr_pre_get(&mmu_context_idr, GFP_KERNEL))
- return -ENOMEM;
-
- spin_lock(&mmu_context_lock);
- err = idr_get_new_above(&mmu_context_idr, NULL, 1, &index);
- spin_unlock(&mmu_context_lock);
-
- if (err == -EAGAIN)
- goto again;
- else if (err)
- return err;
-
- if (index > MAX_CONTEXT) {
- idr_remove(&mmu_context_idr, index);
- return -ENOMEM;
- }
-
- mm->context.id = index;
-
- return 0;
-}
-
-void destroy_context(struct mm_struct *mm)
-{
- spin_lock(&mmu_context_lock);
- idr_remove(&mmu_context_idr, mm->context.id);
- spin_unlock(&mmu_context_lock);
-
- mm->context.id = NO_CONTEXT;
-}
-
-/*
- * Do very early mm setup.
- */
-void __init mm_init_ppc64(void)
-{
-#ifndef CONFIG_PPC_ISERIES
- unsigned long i;
-#endif
-
- ppc64_boot_msg(0x100, "MM Init");
-
- /* This is the story of the IO hole... please, keep seated,
- * unfortunately, we are out of oxygen masks at the moment.
- * So we need some rough way to tell where your big IO hole
- * is. On pmac, it's between 2G and 4G, on POWER3, it's around
- * that area as well, on POWER4 we don't have one, etc...
- * We need that as a "hint" when sizing the TCE table on POWER3
- * So far, the simplest way that seem work well enough for us it
- * to just assume that the first discontinuity in our physical
- * RAM layout is the IO hole. That may not be correct in the future
- * (and isn't on iSeries but then we don't care ;)
- */
-
-#ifndef CONFIG_PPC_ISERIES
- for (i = 1; i < lmb.memory.cnt; i++) {
- unsigned long base, prevbase, prevsize;
-
- prevbase = lmb.memory.region[i-1].base;
- prevsize = lmb.memory.region[i-1].size;
- base = lmb.memory.region[i].base;
- if (base > (prevbase + prevsize)) {
- io_hole_start = prevbase + prevsize;
- io_hole_size = base - (prevbase + prevsize);
- break;
- }
- }
-#endif /* CONFIG_PPC_ISERIES */
- if (io_hole_start)
- printk("IO Hole assumed to be %lx -> %lx\n",
- io_hole_start, io_hole_start + io_hole_size - 1);
-
- ppc64_boot_msg(0x100, "MM Init Done");
-}
-
-/*
- * This is called by /dev/mem to know if a given address has to
- * be mapped non-cacheable or not
- */
-int page_is_ram(unsigned long pfn)
-{
- int i;
- unsigned long paddr = (pfn << PAGE_SHIFT);
-
- for (i=0; i < lmb.memory.cnt; i++) {
- unsigned long base;
-
- base = lmb.memory.region[i].base;
-
- if ((paddr >= base) &&
- (paddr < (base + lmb.memory.region[i].size))) {
- return 1;
- }
- }
-
- return 0;
-}
-EXPORT_SYMBOL(page_is_ram);
-
-/*
- * Initialize the bootmem system and give it all the memory we
- * have available.
- */
-#ifndef CONFIG_NEED_MULTIPLE_NODES
-void __init do_init_bootmem(void)
-{
- unsigned long i;
- unsigned long start, bootmap_pages;
- unsigned long total_pages = lmb_end_of_DRAM() >> PAGE_SHIFT;
- int boot_mapsize;
-
- /*
- * Find an area to use for the bootmem bitmap. Calculate the size of
- * bitmap required as (Total Memory) / PAGE_SIZE / BITS_PER_BYTE.
- * Add 1 additional page in case the address isn't page-aligned.
- */
- bootmap_pages = bootmem_bootmap_pages(total_pages);
-
- start = lmb_alloc(bootmap_pages<<PAGE_SHIFT, PAGE_SIZE);
- BUG_ON(!start);
-
- boot_mapsize = init_bootmem(start >> PAGE_SHIFT, total_pages);
-
- max_pfn = max_low_pfn;
-
- /* Add all physical memory to the bootmem map, mark each area
- * present.
- */
- for (i=0; i < lmb.memory.cnt; i++)
- free_bootmem(lmb.memory.region[i].base,
- lmb_size_bytes(&lmb.memory, i));
-
- /* reserve the sections we're already using */
- for (i=0; i < lmb.reserved.cnt; i++)
- reserve_bootmem(lmb.reserved.region[i].base,
- lmb_size_bytes(&lmb.reserved, i));
-
- for (i=0; i < lmb.memory.cnt; i++)
- memory_present(0, lmb_start_pfn(&lmb.memory, i),
- lmb_end_pfn(&lmb.memory, i));
-}
-
-/*
- * paging_init() sets up the page tables - in fact we've already done this.
- */
-void __init paging_init(void)
-{
- unsigned long zones_size[MAX_NR_ZONES];
- unsigned long zholes_size[MAX_NR_ZONES];
- unsigned long total_ram = lmb_phys_mem_size();
- unsigned long top_of_ram = lmb_end_of_DRAM();
-
- printk(KERN_INFO "Top of RAM: 0x%lx, Total RAM: 0x%lx\n",
- top_of_ram, total_ram);
- printk(KERN_INFO "Memory hole size: %ldMB\n",
- (top_of_ram - total_ram) >> 20);
- /*
- * All pages are DMA-able so we put them all in the DMA zone.
- */
- memset(zones_size, 0, sizeof(zones_size));
- memset(zholes_size, 0, sizeof(zholes_size));
-
- zones_size[ZONE_DMA] = top_of_ram >> PAGE_SHIFT;
- zholes_size[ZONE_DMA] = (top_of_ram - total_ram) >> PAGE_SHIFT;
-
- free_area_init_node(0, NODE_DATA(0), zones_size,
- __pa(PAGE_OFFSET) >> PAGE_SHIFT, zholes_size);
-}
-#endif /* ! CONFIG_NEED_MULTIPLE_NODES */
-
-static struct kcore_list kcore_vmem;
-
-static int __init setup_kcore(void)
-{
- int i;
-
- for (i=0; i < lmb.memory.cnt; i++) {
- unsigned long base, size;
- struct kcore_list *kcore_mem;
-
- base = lmb.memory.region[i].base;
- size = lmb.memory.region[i].size;
-
- /* GFP_ATOMIC to avoid might_sleep warnings during boot */
- kcore_mem = kmalloc(sizeof(struct kcore_list), GFP_ATOMIC);
- if (!kcore_mem)
- panic("mem_init: kmalloc failed\n");
-
- kclist_add(kcore_mem, __va(base), size);
- }
-
- kclist_add(&kcore_vmem, (void *)VMALLOC_START, VMALLOC_END-VMALLOC_START);
-
- return 0;
-}
-module_init(setup_kcore);
-
-void __init mem_init(void)
-{
-#ifdef CONFIG_NEED_MULTIPLE_NODES
- int nid;
-#endif
- pg_data_t *pgdat;
- unsigned long i;
- struct page *page;
- unsigned long reservedpages = 0, codesize, initsize, datasize, bsssize;
-
- num_physpages = max_low_pfn; /* RAM is assumed contiguous */
- high_memory = (void *) __va(max_low_pfn * PAGE_SIZE);
-
-#ifdef CONFIG_NEED_MULTIPLE_NODES
- for_each_online_node(nid) {
- if (NODE_DATA(nid)->node_spanned_pages != 0) {
- printk("freeing bootmem node %x\n", nid);
- totalram_pages +=
- free_all_bootmem_node(NODE_DATA(nid));
- }
- }
-#else
- max_mapnr = num_physpages;
- totalram_pages += free_all_bootmem();
-#endif
-
- for_each_pgdat(pgdat) {
- for (i = 0; i < pgdat->node_spanned_pages; i++) {
- page = pgdat_page_nr(pgdat, i);
- if (PageReserved(page))
- reservedpages++;
- }
- }
-
- codesize = (unsigned long)&_etext - (unsigned long)&_stext;
- initsize = (unsigned long)&__init_end - (unsigned long)&__init_begin;
- datasize = (unsigned long)&_edata - (unsigned long)&__init_end;
- bsssize = (unsigned long)&__bss_stop - (unsigned long)&__bss_start;
-
- printk(KERN_INFO "Memory: %luk/%luk available (%luk kernel code, "
- "%luk reserved, %luk data, %luk bss, %luk init)\n",
- (unsigned long)nr_free_pages() << (PAGE_SHIFT-10),
- num_physpages << (PAGE_SHIFT-10),
- codesize >> 10,
- reservedpages << (PAGE_SHIFT-10),
- datasize >> 10,
- bsssize >> 10,
- initsize >> 10);
-
- mem_init_done = 1;
-
- /* Initialize the vDSO */
- vdso_init();
-}
-
-/*
- * This is called when a page has been modified by the kernel.
- * It just marks the page as not i-cache clean. We do the i-cache
- * flush later when the page is given to a user process, if necessary.
- */
-void flush_dcache_page(struct page *page)
-{
- if (cpu_has_feature(CPU_FTR_COHERENT_ICACHE))
- return;
- /* avoid an atomic op if possible */
- if (test_bit(PG_arch_1, &page->flags))
- clear_bit(PG_arch_1, &page->flags);
-}
-EXPORT_SYMBOL(flush_dcache_page);
-
-void clear_user_page(void *page, unsigned long vaddr, struct page *pg)
-{
- clear_page(page);
-
- if (cpu_has_feature(CPU_FTR_COHERENT_ICACHE))
- return;
- /*
- * We shouldnt have to do this, but some versions of glibc
- * require it (ld.so assumes zero filled pages are icache clean)
- * - Anton
- */
-
- /* avoid an atomic op if possible */
- if (test_bit(PG_arch_1, &pg->flags))
- clear_bit(PG_arch_1, &pg->flags);
-}
-EXPORT_SYMBOL(clear_user_page);
-
-void copy_user_page(void *vto, void *vfrom, unsigned long vaddr,
- struct page *pg)
-{
- copy_page(vto, vfrom);
-
- /*
- * We should be able to use the following optimisation, however
- * there are two problems.
- * Firstly a bug in some versions of binutils meant PLT sections
- * were not marked executable.
- * Secondly the first word in the GOT section is blrl, used
- * to establish the GOT address. Until recently the GOT was
- * not marked executable.
- * - Anton
- */
-#if 0
- if (!vma->vm_file && ((vma->vm_flags & VM_EXEC) == 0))
- return;
-#endif
-
- if (cpu_has_feature(CPU_FTR_COHERENT_ICACHE))
- return;
-
- /* avoid an atomic op if possible */
- if (test_bit(PG_arch_1, &pg->flags))
- clear_bit(PG_arch_1, &pg->flags);
-}
-
-void flush_icache_user_range(struct vm_area_struct *vma, struct page *page,
- unsigned long addr, int len)
-{
- unsigned long maddr;
-
- maddr = (unsigned long)page_address(page) + (addr & ~PAGE_MASK);
- flush_icache_range(maddr, maddr + len);
-}
-EXPORT_SYMBOL(flush_icache_user_range);
-
-/*
- * This is called at the end of handling a user page fault, when the
- * fault has been handled by updating a PTE in the linux page tables.
- * We use it to preload an HPTE into the hash table corresponding to
- * the updated linux PTE.
- *
- * This must always be called with the mm->page_table_lock held
- */
-void update_mmu_cache(struct vm_area_struct *vma, unsigned long ea,
- pte_t pte)
-{
- unsigned long vsid;
- void *pgdir;
- pte_t *ptep;
- int local = 0;
- cpumask_t tmp;
- unsigned long flags;
-
- /* handle i-cache coherency */
- if (!cpu_has_feature(CPU_FTR_COHERENT_ICACHE) &&
- !cpu_has_feature(CPU_FTR_NOEXECUTE)) {
- unsigned long pfn = pte_pfn(pte);
- if (pfn_valid(pfn)) {
- struct page *page = pfn_to_page(pfn);
- if (!PageReserved(page)
- && !test_bit(PG_arch_1, &page->flags)) {
- __flush_dcache_icache(page_address(page));
- set_bit(PG_arch_1, &page->flags);
- }
- }
- }
-
- /* We only want HPTEs for linux PTEs that have _PAGE_ACCESSED set */
- if (!pte_young(pte))
- return;
-
- pgdir = vma->vm_mm->pgd;
- if (pgdir == NULL)
- return;
-
- ptep = find_linux_pte(pgdir, ea);
- if (!ptep)
- return;
-
- vsid = get_vsid(vma->vm_mm->context.id, ea);
-
- local_irq_save(flags);
- tmp = cpumask_of_cpu(smp_processor_id());
- if (cpus_equal(vma->vm_mm->cpu_vm_mask, tmp))
- local = 1;
-
- __hash_page(ea, 0, vsid, ptep, 0x300, local);
- local_irq_restore(flags);
-}
-
-void __iomem * reserve_phb_iospace(unsigned long size)
-{
- void __iomem *virt_addr;
-
- if (phbs_io_bot >= IMALLOC_BASE)
- panic("reserve_phb_iospace(): phb io space overflow\n");
-
- virt_addr = (void __iomem *) phbs_io_bot;
- phbs_io_bot += size;
-
- return virt_addr;
-}
-
-static void zero_ctor(void *addr, kmem_cache_t *cache, unsigned long flags)
-{
- memset(addr, 0, kmem_cache_size(cache));
-}
-
-static const int pgtable_cache_size[2] = {
- PTE_TABLE_SIZE, PMD_TABLE_SIZE
-};
-static const char *pgtable_cache_name[ARRAY_SIZE(pgtable_cache_size)] = {
- "pgd_pte_cache", "pud_pmd_cache",
-};
-
-kmem_cache_t *pgtable_cache[ARRAY_SIZE(pgtable_cache_size)];
-
-void pgtable_cache_init(void)
-{
- int i;
-
- BUILD_BUG_ON(PTE_TABLE_SIZE != pgtable_cache_size[PTE_CACHE_NUM]);
- BUILD_BUG_ON(PMD_TABLE_SIZE != pgtable_cache_size[PMD_CACHE_NUM]);
- BUILD_BUG_ON(PUD_TABLE_SIZE != pgtable_cache_size[PUD_CACHE_NUM]);
- BUILD_BUG_ON(PGD_TABLE_SIZE != pgtable_cache_size[PGD_CACHE_NUM]);
-
- for (i = 0; i < ARRAY_SIZE(pgtable_cache_size); i++) {
- int size = pgtable_cache_size[i];
- const char *name = pgtable_cache_name[i];
-
- pgtable_cache[i] = kmem_cache_create(name,
- size, size,
- SLAB_HWCACHE_ALIGN
- | SLAB_MUST_HWCACHE_ALIGN,
- zero_ctor,
- NULL);
- if (! pgtable_cache[i])
- panic("pgtable_cache_init(): could not create %s!\n",
- name);
- }
-}
-
-pgprot_t phys_mem_access_prot(struct file *file, unsigned long addr,
- unsigned long size, pgprot_t vma_prot)
-{
- if (ppc_md.phys_mem_access_prot)
- return ppc_md.phys_mem_access_prot(file, addr, size, vma_prot);
-
- if (!page_is_ram(addr >> PAGE_SHIFT))
- vma_prot = __pgprot(pgprot_val(vma_prot)
- | _PAGE_GUARDED | _PAGE_NO_CACHE);
- return vma_prot;
-}
-EXPORT_SYMBOL(phys_mem_access_prot);
diff --git a/arch/ppc64/mm/slb_low.S b/arch/ppc64/mm/slb_low.S
deleted file mode 100644
index a3a03da503bc..000000000000
--- a/arch/ppc64/mm/slb_low.S
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * arch/ppc64/mm/slb_low.S
- *
- * Low-level SLB routines
- *
- * Copyright (C) 2004 David Gibson <dwg@au.ibm.com>, IBM
- *
- * Based on earlier C version:
- * Dave Engebretsen and Mike Corrigan {engebret|mikejc}@us.ibm.com
- * Copyright (c) 2001 Dave Engebretsen
- * Copyright (C) 2002 Anton Blanchard <anton@au.ibm.com>, IBM
- *
- * 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/config.h>
-#include <asm/processor.h>
-#include <asm/page.h>
-#include <asm/mmu.h>
-#include <asm/ppc_asm.h>
-#include <asm/asm-offsets.h>
-#include <asm/cputable.h>
-
-/* void slb_allocate(unsigned long ea);
- *
- * Create an SLB entry for the given EA (user or kernel).
- * r3 = faulting address, r13 = PACA
- * r9, r10, r11 are clobbered by this function
- * No other registers are examined or changed.
- */
-_GLOBAL(slb_allocate)
- /*
- * First find a slot, round robin. Previously we tried to find
- * a free slot first but that took too long. Unfortunately we
- * dont have any LRU information to help us choose a slot.
- */
-#ifdef CONFIG_PPC_ISERIES
- /*
- * On iSeries, the "bolted" stack segment can be cast out on
- * shared processor switch so we need to check for a miss on
- * it and restore it to the right slot.
- */
- ld r9,PACAKSAVE(r13)
- clrrdi r9,r9,28
- clrrdi r11,r3,28
- li r10,SLB_NUM_BOLTED-1 /* Stack goes in last bolted slot */
- cmpld r9,r11
- beq 3f
-#endif /* CONFIG_PPC_ISERIES */
-
- ld r10,PACASTABRR(r13)
- addi r10,r10,1
- /* use a cpu feature mask if we ever change our slb size */
- cmpldi r10,SLB_NUM_ENTRIES
-
- blt+ 4f
- li r10,SLB_NUM_BOLTED
-
-4:
- std r10,PACASTABRR(r13)
-3:
- /* r3 = faulting address, r10 = entry */
-
- srdi r9,r3,60 /* get region */
- srdi r3,r3,28 /* get esid */
- cmpldi cr7,r9,0xc /* cmp KERNELBASE for later use */
-
- rldimi r10,r3,28,0 /* r10= ESID<<28 | entry */
- oris r10,r10,SLB_ESID_V@h /* r10 |= SLB_ESID_V */
-
- /* r3 = esid, r10 = esid_data, cr7 = <>KERNELBASE */
-
- blt cr7,0f /* user or kernel? */
-
- /* kernel address: proto-VSID = ESID */
- /* WARNING - MAGIC: we don't use the VSID 0xfffffffff, but
- * this code will generate the protoVSID 0xfffffffff for the
- * top segment. That's ok, the scramble below will translate
- * it to VSID 0, which is reserved as a bad VSID - one which
- * will never have any pages in it. */
- li r11,SLB_VSID_KERNEL
-BEGIN_FTR_SECTION
- bne cr7,9f
- li r11,(SLB_VSID_KERNEL|SLB_VSID_L)
-END_FTR_SECTION_IFSET(CPU_FTR_16M_PAGE)
- b 9f
-
-0: /* user address: proto-VSID = context<<15 | ESID */
- srdi. r9,r3,USER_ESID_BITS
- bne- 8f /* invalid ea bits set */
-
-#ifdef CONFIG_HUGETLB_PAGE
-BEGIN_FTR_SECTION
- lhz r9,PACAHIGHHTLBAREAS(r13)
- srdi r11,r3,(HTLB_AREA_SHIFT-SID_SHIFT)
- srd r9,r9,r11
- lhz r11,PACALOWHTLBAREAS(r13)
- srd r11,r11,r3
- or r9,r9,r11
-END_FTR_SECTION_IFSET(CPU_FTR_16M_PAGE)
-#endif /* CONFIG_HUGETLB_PAGE */
-
- li r11,SLB_VSID_USER
-
-#ifdef CONFIG_HUGETLB_PAGE
-BEGIN_FTR_SECTION
- rldimi r11,r9,8,55 /* shift masked bit into SLB_VSID_L */
-END_FTR_SECTION_IFSET(CPU_FTR_16M_PAGE)
-#endif /* CONFIG_HUGETLB_PAGE */
-
- ld r9,PACACONTEXTID(r13)
- rldimi r3,r9,USER_ESID_BITS,0
-
-9: /* r3 = protovsid, r11 = flags, r10 = esid_data, cr7 = <>KERNELBASE */
- ASM_VSID_SCRAMBLE(r3,r9)
-
- rldimi r11,r3,SLB_VSID_SHIFT,16 /* combine VSID and flags */
-
- /*
- * No need for an isync before or after this slbmte. The exception
- * we enter with and the rfid we exit with are context synchronizing.
- */
- slbmte r11,r10
-
- bgelr cr7 /* we're done for kernel addresses */
-
- /* Update the slb cache */
- lhz r3,PACASLBCACHEPTR(r13) /* offset = paca->slb_cache_ptr */
- cmpldi r3,SLB_CACHE_ENTRIES
- bge 1f
-
- /* still room in the slb cache */
- sldi r11,r3,1 /* r11 = offset * sizeof(u16) */
- rldicl r10,r10,36,28 /* get low 16 bits of the ESID */
- add r11,r11,r13 /* r11 = (u16 *)paca + offset */
- sth r10,PACASLBCACHE(r11) /* paca->slb_cache[offset] = esid */
- addi r3,r3,1 /* offset++ */
- b 2f
-1: /* offset >= SLB_CACHE_ENTRIES */
- li r3,SLB_CACHE_ENTRIES+1
-2:
- sth r3,PACASLBCACHEPTR(r13) /* paca->slb_cache_ptr = offset */
- blr
-
-8: /* invalid EA */
- li r3,0 /* BAD_VSID */
- li r11,SLB_VSID_USER /* flags don't much matter */
- b 9b
diff --git a/arch/ppc64/oprofile/Kconfig b/arch/ppc64/oprofile/Kconfig
deleted file mode 100644
index 5ade19801b97..000000000000
--- a/arch/ppc64/oprofile/Kconfig
+++ /dev/null
@@ -1,23 +0,0 @@
-
-menu "Profiling support"
- depends on EXPERIMENTAL
-
-config PROFILING
- bool "Profiling support (EXPERIMENTAL)"
- help
- Say Y here to enable the extended profiling support mechanisms used
- by profilers such as OProfile.
-
-
-config OPROFILE
- tristate "OProfile system profiling (EXPERIMENTAL)"
- depends on PROFILING
- help
- OProfile is a profiling system capable of profiling the
- whole system, include the kernel, kernel modules, libraries,
- and applications.
-
- If unsure, say N.
-
-endmenu
-
diff --git a/arch/ppc64/oprofile/Makefile b/arch/ppc64/oprofile/Makefile
deleted file mode 100644
index 162dbf06c142..000000000000
--- a/arch/ppc64/oprofile/Makefile
+++ /dev/null
@@ -1,9 +0,0 @@
-obj-$(CONFIG_OPROFILE) += oprofile.o
-
-DRIVER_OBJS := $(addprefix ../../../drivers/oprofile/, \
- oprof.o cpu_buffer.o buffer_sync.o \
- event_buffer.o oprofile_files.o \
- oprofilefs.o oprofile_stats.o \
- timer_int.o )
-
-oprofile-y := $(DRIVER_OBJS) common.o op_model_rs64.o op_model_power4.o
diff --git a/arch/ppc64/xmon/Makefile b/arch/ppc64/xmon/Makefile
deleted file mode 100644
index fb21a7088d3e..000000000000
--- a/arch/ppc64/xmon/Makefile
+++ /dev/null
@@ -1,5 +0,0 @@
-# Makefile for xmon
-
-EXTRA_CFLAGS += -mno-minimal-toc
-
-obj-y := start.o xmon.o ppc-dis.o ppc-opc.o subr_prf.o setjmp.o
diff --git a/arch/ppc64/xmon/nonstdio.h b/arch/ppc64/xmon/nonstdio.h
deleted file mode 100644
index 84211a21c6f4..000000000000
--- a/arch/ppc64/xmon/nonstdio.h
+++ /dev/null
@@ -1,22 +0,0 @@
-typedef int FILE;
-extern FILE *xmon_stdin, *xmon_stdout;
-#define EOF (-1)
-#define stdin xmon_stdin
-#define stdout xmon_stdout
-#define printf xmon_printf
-#define fprintf xmon_fprintf
-#define fputs xmon_fputs
-#define fgets xmon_fgets
-#define putchar xmon_putchar
-#define getchar xmon_getchar
-#define putc xmon_putc
-#define getc xmon_getc
-#define fopen(n, m) NULL
-#define fflush(f) do {} while (0)
-#define fclose(f) do {} while (0)
-extern char *fgets(char *, int, void *);
-extern void xmon_printf(const char *, ...);
-extern void xmon_fprintf(void *, const char *, ...);
-extern void xmon_sprintf(char *, const char *, ...);
-
-#define perror(s) printf("%s: no files!\n", (s))
diff --git a/arch/ppc64/xmon/setjmp.S b/arch/ppc64/xmon/setjmp.S
deleted file mode 100644
index 30ee643d557c..000000000000
--- a/arch/ppc64/xmon/setjmp.S
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 1996 Paul Mackerras.
- *
- * 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.
- *
- * NOTE: assert(sizeof(buf) > 184)
- */
-#include <asm/processor.h>
-#include <asm/ppc_asm.h>
-
-_GLOBAL(xmon_setjmp)
- mflr r0
- std r0,0(r3)
- std r1,8(r3)
- std r2,16(r3)
- mfcr r0
- std r0,24(r3)
- std r13,32(r3)
- std r14,40(r3)
- std r15,48(r3)
- std r16,56(r3)
- std r17,64(r3)
- std r18,72(r3)
- std r19,80(r3)
- std r20,88(r3)
- std r21,96(r3)
- std r22,104(r3)
- std r23,112(r3)
- std r24,120(r3)
- std r25,128(r3)
- std r26,136(r3)
- std r27,144(r3)
- std r28,152(r3)
- std r29,160(r3)
- std r30,168(r3)
- std r31,176(r3)
- li r3,0
- blr
-
-_GLOBAL(xmon_longjmp)
- cmpdi r4,0
- bne 1f
- li r4,1
-1: ld r13,32(r3)
- ld r14,40(r3)
- ld r15,48(r3)
- ld r16,56(r3)
- ld r17,64(r3)
- ld r18,72(r3)
- ld r19,80(r3)
- ld r20,88(r3)
- ld r21,96(r3)
- ld r22,104(r3)
- ld r23,112(r3)
- ld r24,120(r3)
- ld r25,128(r3)
- ld r26,136(r3)
- ld r27,144(r3)
- ld r28,152(r3)
- ld r29,160(r3)
- ld r30,168(r3)
- ld r31,176(r3)
- ld r0,24(r3)
- mtcrf 56,r0
- ld r0,0(r3)
- ld r1,8(r3)
- ld r2,16(r3)
- mtlr r0
- mr r3,r4
- blr
diff --git a/arch/ppc64/xmon/start.c b/arch/ppc64/xmon/start.c
deleted file mode 100644
index e50c158191e1..000000000000
--- a/arch/ppc64/xmon/start.c
+++ /dev/null
@@ -1,187 +0,0 @@
-/*
- * Copyright (C) 1996 Paul Mackerras.
- *
- * 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/config.h>
-#include <linux/string.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/sysrq.h>
-#include <linux/init.h>
-#include <asm/machdep.h>
-#include <asm/io.h>
-#include <asm/page.h>
-#include <asm/prom.h>
-#include <asm/processor.h>
-#include <asm/udbg.h>
-#include <asm/system.h>
-#include "nonstdio.h"
-
-#ifdef CONFIG_MAGIC_SYSRQ
-
-static void sysrq_handle_xmon(int key, struct pt_regs *pt_regs,
- struct tty_struct *tty)
-{
- /* ensure xmon is enabled */
- xmon_init(1);
- debugger(pt_regs);
-}
-
-static struct sysrq_key_op sysrq_xmon_op =
-{
- .handler = sysrq_handle_xmon,
- .help_msg = "Xmon",
- .action_msg = "Entering xmon",
-};
-
-static int __init setup_xmon_sysrq(void)
-{
- register_sysrq_key('x', &sysrq_xmon_op);
- return 0;
-}
-__initcall(setup_xmon_sysrq);
-#endif /* CONFIG_MAGIC_SYSRQ */
-
-int
-xmon_write(void *handle, void *ptr, int nb)
-{
- return udbg_write(ptr, nb);
-}
-
-int
-xmon_read(void *handle, void *ptr, int nb)
-{
- return udbg_read(ptr, nb);
-}
-
-int
-xmon_read_poll(void)
-{
- if (udbg_getc_poll)
- return udbg_getc_poll();
- return -1;
-}
-
-FILE *xmon_stdin;
-FILE *xmon_stdout;
-
-int
-xmon_putc(int c, void *f)
-{
- char ch = c;
-
- if (c == '\n')
- xmon_putc('\r', f);
- return xmon_write(f, &ch, 1) == 1? c: -1;
-}
-
-int
-xmon_putchar(int c)
-{
- return xmon_putc(c, xmon_stdout);
-}
-
-int
-xmon_fputs(char *str, void *f)
-{
- int n = strlen(str);
-
- return xmon_write(f, str, n) == n? 0: -1;
-}
-
-int
-xmon_readchar(void)
-{
- char ch;
-
- for (;;) {
- switch (xmon_read(xmon_stdin, &ch, 1)) {
- case 1:
- return ch;
- case -1:
- xmon_printf("read(stdin) returned -1\r\n", 0, 0);
- return -1;
- }
- }
-}
-
-static char line[256];
-static char *lineptr;
-static int lineleft;
-
-int
-xmon_getchar(void)
-{
- int c;
-
- if (lineleft == 0) {
- lineptr = line;
- for (;;) {
- c = xmon_readchar();
- if (c == -1 || c == 4)
- break;
- if (c == '\r' || c == '\n') {
- *lineptr++ = '\n';
- xmon_putchar('\n');
- break;
- }
- switch (c) {
- case 0177:
- case '\b':
- if (lineptr > line) {
- xmon_putchar('\b');
- xmon_putchar(' ');
- xmon_putchar('\b');
- --lineptr;
- }
- break;
- case 'U' & 0x1F:
- while (lineptr > line) {
- xmon_putchar('\b');
- xmon_putchar(' ');
- xmon_putchar('\b');
- --lineptr;
- }
- break;
- default:
- if (lineptr >= &line[sizeof(line) - 1])
- xmon_putchar('\a');
- else {
- xmon_putchar(c);
- *lineptr++ = c;
- }
- }
- }
- lineleft = lineptr - line;
- lineptr = line;
- }
- if (lineleft == 0)
- return -1;
- --lineleft;
- return *lineptr++;
-}
-
-char *
-xmon_fgets(char *str, int nb, void *f)
-{
- char *p;
- int c;
-
- for (p = str; p < str + nb - 1; ) {
- c = xmon_getchar();
- if (c == -1) {
- if (p == str)
- return NULL;
- break;
- }
- *p++ = c;
- if (c == '\n')
- break;
- }
- *p = 0;
- return str;
-}
diff --git a/arch/ppc64/xmon/subr_prf.c b/arch/ppc64/xmon/subr_prf.c
deleted file mode 100644
index 5242bd7d0959..000000000000
--- a/arch/ppc64/xmon/subr_prf.c
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Written by Cort Dougan to replace the version originally used
- * by Paul Mackerras, which came from NetBSD and thus had copyright
- * conflicts with Linux.
- *
- * This file makes liberal use of the standard linux utility
- * routines to reduce the size of the binary. We assume we can
- * trust some parts of Linux inside the debugger.
- * -- Cort (cort@cs.nmt.edu)
- *
- * Copyright (C) 1999 Cort Dougan.
- *
- * 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/string.h>
-#include <stdarg.h>
-#include "nonstdio.h"
-
-extern int xmon_write(void *, void *, int);
-
-void
-xmon_vfprintf(void *f, const char *fmt, va_list ap)
-{
- static char xmon_buf[2048];
- int n;
-
- n = vsprintf(xmon_buf, fmt, ap);
- xmon_write(f, xmon_buf, n);
-}
-
-void
-xmon_printf(const char *fmt, ...)
-{
- va_list ap;
-
- va_start(ap, fmt);
- xmon_vfprintf(stdout, fmt, ap);
- va_end(ap);
-}
-
-void
-xmon_fprintf(void *f, const char *fmt, ...)
-{
- va_list ap;
-
- va_start(ap, fmt);
- xmon_vfprintf(f, fmt, ap);
- va_end(ap);
-}
-
diff --git a/arch/s390/Makefile b/arch/s390/Makefile
index 98db30481d97..73a09a6ee6c8 100644
--- a/arch/s390/Makefile
+++ b/arch/s390/Makefile
@@ -76,9 +76,7 @@ AFLAGS += $(aflags-y)
OBJCOPYFLAGS := -O binary
LDFLAGS_vmlinux := -e start
-head-$(CONFIG_ARCH_S390_31) += arch/$(ARCH)/kernel/head.o
-head-$(CONFIG_ARCH_S390X) += arch/$(ARCH)/kernel/head64.o
-head-y += arch/$(ARCH)/kernel/init_task.o
+head-y := arch/$(ARCH)/kernel/head.o arch/$(ARCH)/kernel/init_task.o
core-y += arch/$(ARCH)/mm/ arch/$(ARCH)/kernel/ arch/$(ARCH)/crypto/ \
arch/$(ARCH)/appldata/
diff --git a/arch/s390/appldata/appldata_base.c b/arch/s390/appldata/appldata_base.c
index c9f2f60cfa58..dee6ab54984d 100644
--- a/arch/s390/appldata/appldata_base.c
+++ b/arch/s390/appldata/appldata_base.c
@@ -592,12 +592,15 @@ int appldata_register_ops(struct appldata_ops *ops)
*/
void appldata_unregister_ops(struct appldata_ops *ops)
{
+ void *table;
spin_lock(&appldata_ops_lock);
- unregister_sysctl_table(ops->sysctl_header);
list_del(&ops->list);
- kfree(ops->ctl_table);
+ /* at that point any incoming access will fail */
+ table = ops->ctl_table;
ops->ctl_table = NULL;
spin_unlock(&appldata_ops_lock);
+ unregister_sysctl_table(ops->sysctl_header);
+ kfree(table);
P_INFO("%s-ops unregistered!\n", ops->name);
}
/********************** module-ops management <END> **************************/
diff --git a/arch/s390/kernel/Makefile b/arch/s390/kernel/Makefile
index 8584dd823218..7434c32bc631 100644
--- a/arch/s390/kernel/Makefile
+++ b/arch/s390/kernel/Makefile
@@ -8,9 +8,7 @@ obj-y := bitmap.o traps.o time.o process.o \
setup.o sys_s390.o ptrace.o signal.o cpcmd.o ebcdic.o \
semaphore.o s390_ext.o debug.o profile.o irq.o reipl_diag.o
-extra-$(CONFIG_ARCH_S390_31) += head.o
-extra-$(CONFIG_ARCH_S390X) += head64.o
-extra-y += init_task.o vmlinux.lds
+extra-y += head.o init_task.o vmlinux.lds
obj-$(CONFIG_MODULES) += s390_ksyms.o module.o
obj-$(CONFIG_SMP) += smp.o
diff --git a/arch/s390/kernel/compat_ioctl.c b/arch/s390/kernel/compat_ioctl.c
index 24a1e9f069a7..6504c4e69986 100644
--- a/arch/s390/kernel/compat_ioctl.c
+++ b/arch/s390/kernel/compat_ioctl.c
@@ -18,6 +18,8 @@
#include <asm/dasd.h>
#include <asm/cmb.h>
#include <asm/tape390.h>
+#include <asm/ccwdev.h>
+#include "../../../drivers/s390/char/raw3270.h"
static int do_ioctl32_pointer(unsigned int fd, unsigned int cmd,
unsigned long arg, struct file *f)
@@ -62,6 +64,13 @@ COMPATIBLE_IOCTL(BIODASDCMFENABLE)
COMPATIBLE_IOCTL(BIODASDCMFDISABLE)
COMPATIBLE_IOCTL(BIODASDREADALLCMB)
+COMPATIBLE_IOCTL(TUBICMD)
+COMPATIBLE_IOCTL(TUBOCMD)
+COMPATIBLE_IOCTL(TUBGETI)
+COMPATIBLE_IOCTL(TUBGETO)
+COMPATIBLE_IOCTL(TUBSETMOD)
+COMPATIBLE_IOCTL(TUBGETMOD)
+
COMPATIBLE_IOCTL(TAPE390_DISPLAY)
/* s390 doesn't need handlers here */
diff --git a/arch/s390/kernel/debug.c b/arch/s390/kernel/debug.c
index bc59282da762..896d39d0e4ce 100644
--- a/arch/s390/kernel/debug.c
+++ b/arch/s390/kernel/debug.c
@@ -486,7 +486,7 @@ out:
* - goto next entry in p_info
*/
-extern inline int
+static inline int
debug_next_entry(file_private_info_t *p_info)
{
debug_info_t *id;
@@ -800,7 +800,7 @@ debug_set_level(debug_info_t* id, int new_level)
* - set active entry to next in the ring buffer
*/
-extern inline void
+static inline void
proceed_active_entry(debug_info_t * id)
{
if ((id->active_entries[id->active_area] += id->entry_size)
@@ -817,7 +817,7 @@ proceed_active_entry(debug_info_t * id)
* - set active area to next in the ring buffer
*/
-extern inline void
+static inline void
proceed_active_area(debug_info_t * id)
{
id->active_area++;
@@ -828,7 +828,7 @@ proceed_active_area(debug_info_t * id)
* get_active_entry:
*/
-extern inline debug_entry_t*
+static inline debug_entry_t*
get_active_entry(debug_info_t * id)
{
return (debug_entry_t *) (((char *) id->areas[id->active_area]
@@ -841,7 +841,7 @@ get_active_entry(debug_info_t * id)
* - set timestamp, caller address, cpu number etc.
*/
-extern inline void
+static inline void
debug_finish_entry(debug_info_t * id, debug_entry_t* active, int level,
int exception)
{
@@ -971,7 +971,7 @@ debug_entry_t
* counts arguments in format string for sprintf view
*/
-extern inline int
+static inline int
debug_count_numargs(char *string)
{
int numargs=0;
diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S
index 9b30f4cf32c4..27b07730b7b8 100644
--- a/arch/s390/kernel/entry.S
+++ b/arch/s390/kernel/entry.S
@@ -288,7 +288,7 @@ sysc_sigpending:
bo BASED(sysc_restart)
tm __TI_flags+3(%r9),_TIF_SINGLE_STEP
bo BASED(sysc_singlestep)
- b BASED(sysc_leave) # out of here, do NOT recheck
+ b BASED(sysc_work_loop)
#
# _TIF_RESTART_SVC is set, set up registers and restart svc
@@ -645,7 +645,7 @@ io_sigpending:
l %r1,BASED(.Ldo_signal)
basr %r14,%r1 # call do_signal
stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts
- b BASED(io_leave) # out of here, do NOT recheck
+ b BASED(io_work_loop)
/*
* External interrupt handler routine
diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S
index 7b9b4a2ba1d7..4eb71ffcf484 100644
--- a/arch/s390/kernel/entry64.S
+++ b/arch/s390/kernel/entry64.S
@@ -283,7 +283,7 @@ sysc_sigpending:
jo sysc_restart
tm __TI_flags+7(%r9),_TIF_SINGLE_STEP
jo sysc_singlestep
- j sysc_leave # out of here, do NOT recheck
+ j sysc_work_loop
#
# _TIF_RESTART_SVC is set, set up registers and restart svc
@@ -684,7 +684,7 @@ io_sigpending:
slgr %r3,%r3 # clear *oldset
brasl %r14,do_signal # call do_signal
stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts
- j sysc_leave # out of here, do NOT recheck
+ j io_work_loop
/*
* External interrupt handler routine
diff --git a/arch/s390/kernel/head.S b/arch/s390/kernel/head.S
index 55654b6e16dc..d31a97c89f68 100644
--- a/arch/s390/kernel/head.S
+++ b/arch/s390/kernel/head.S
@@ -1,11 +1,12 @@
/*
* arch/s390/kernel/head.S
*
- * S390 version
- * Copyright (C) 1999,2000 IBM Deutschland Entwicklung GmbH, IBM Corporation
- * Author(s): Hartmut Penner (hp@de.ibm.com),
- * Martin Schwidefsky (schwidefsky@de.ibm.com),
- * Rob van der Heij (rvdhei@iae.nl)
+ * (C) Copyright IBM Corp. 1999, 2005
+ *
+ * Author(s): Hartmut Penner <hp@de.ibm.com>
+ * Martin Schwidefsky <schwidefsky@de.ibm.com>
+ * Rob van der Heij <rvdhei@iae.nl>
+ * Heiko Carstens <heiko.carstens@de.ibm.com>
*
* There are 5 different IPL methods
* 1) load the image directly into ram at address 0 and do an PSW restart
@@ -19,12 +20,7 @@
* 5) direct call of start by the SALIPL loader
* We use the cpuid to distinguish between VM and native ipl
* params for kernel are pushed to 0x10400 (see setup.h)
-
- Changes:
- Okt 25 2000 <rvdheij@iae.nl>
- added code to skip HDR and EOF to allow SL tape IPL (5 retries)
- changed first CCW from rewind to backspace block
-
+ *
*/
#include <linux/config.h>
@@ -34,6 +30,12 @@
#include <asm/thread_info.h>
#include <asm/page.h>
+#ifdef CONFIG_ARCH_S390X
+#define ARCH_OFFSET 4
+#else
+#define ARCH_OFFSET 0
+#endif
+
#ifndef CONFIG_IPL
.org 0
.long 0x00080000,0x80000000+startup # Just a restart PSW
@@ -201,7 +203,7 @@
ssch 0(%r3) # load chunk of 1600 bytes
bnz .Llderr
.Lwait4irq:
- mvc __LC_IO_NEW_PSW(8),.Lnewpsw # set up IO interrupt psw
+ mvc 0x78(8),.Lnewpsw # set up IO interrupt psw
lpsw .Lwaitpsw
.Lioint:
c %r1,0xb8 # compare subchannel number
@@ -265,13 +267,13 @@ iplstart:
la %r2,IPL_BS # load start address
bas %r14,.Lloader # load rest of ipl image
l %r12,.Lparm # pointer to parameter area
- st %r1,IPL_DEVICE-PARMAREA(%r12) # store ipl device number
+ st %r1,IPL_DEVICE+ARCH_OFFSET-PARMAREA(%r12) # save ipl device number
#
# load parameter file from ipl device
#
.Lagain1:
- l %r2,INITRD_START-PARMAREA(%r12) # use ramdisk location as temp
+ l %r2,INITRD_START+ARCH_OFFSET-PARMAREA(%r12) # ramdisk loc. is temp
bas %r14,.Lloader # load parameter file
ltr %r2,%r2 # got anything ?
bz .Lnopf
@@ -279,7 +281,7 @@ iplstart:
bnh .Lnotrunc
la %r2,895
.Lnotrunc:
- l %r4,INITRD_START-PARMAREA(%r12)
+ l %r4,INITRD_START+ARCH_OFFSET-PARMAREA(%r12)
clc 0(3,%r4),.L_hdr # if it is HDRx
bz .Lagain1 # skip dataset header
clc 0(3,%r4),.L_eof # if it is EOFx
@@ -322,14 +324,14 @@ iplstart:
# load ramdisk from ipl device
#
.Lagain2:
- l %r2,INITRD_START-PARMAREA(%r12) # load adr. of ramdisk
+ l %r2,INITRD_START+ARCH_OFFSET-PARMAREA(%r12) # addr of ramdisk
bas %r14,.Lloader # load ramdisk
- st %r2,INITRD_SIZE-PARMAREA(%r12) # store size of ramdisk
+ st %r2,INITRD_SIZE+ARCH_OFFSET-PARMAREA(%r12) # store size of ramdisk
ltr %r2,%r2
bnz .Lrdcont
- st %r2,INITRD_START-PARMAREA(%r12) # no ramdisk found, null it
+ st %r2,INITRD_START+ARCH_OFFSET-PARMAREA(%r12) # no ramdisk found
.Lrdcont:
- l %r2,INITRD_START-PARMAREA(%r12)
+ l %r2,INITRD_START+ARCH_OFFSET-PARMAREA(%r12)
clc 0(3,%r2),.L_hdr # skip HDRx and EOFx
bz .Lagain2
@@ -432,10 +434,10 @@ start:
la %r3,1(%r3)
.done:
l %r1,.memsize
- st %r3,0(%r1)
+ st %r3,ARCH_OFFSET(%r1)
slr %r0,%r0
- st %r0,INITRD_SIZE-PARMAREA(%r11)
- st %r0,INITRD_START-PARMAREA(%r11)
+ st %r0,INITRD_SIZE+ARCH_OFFSET-PARMAREA(%r11)
+ st %r0,INITRD_START+ARCH_OFFSET-PARMAREA(%r11)
j startup # continue with startup
.tbl: .long _ebcasc # translate table
.cmd: .long COMMAND_LINE # address of command line buffer
@@ -478,322 +480,67 @@ start:
.byte 0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7
.byte 0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfe,0xff
-#
-# startup-code at 0x10000, running in real mode
-# this is called either by the ipl loader or directly by PSW restart
-# or linload or SALIPL
-#
- .org 0x10000
-startup:basr %r13,0 # get base
-.LPG1: lctl %c0,%c15,.Lctl-.LPG1(%r13) # load control registers
- la %r12,_pstart-.LPG1(%r13) # pointer to parameter area
- # move IPL device to lowcore
- mvc __LC_IPLDEV(4),IPL_DEVICE-PARMAREA(%r12)
-
-#
-# clear bss memory
-#
- l %r2,.Lbss_bgn-.LPG1(%r13) # start of bss
- l %r3,.Lbss_end-.LPG1(%r13) # end of bss
- sr %r3,%r2 # length of bss
- sr %r4,%r4 #
- sr %r5,%r5 # set src,length and pad to zero
- sr %r0,%r0 #
- mvcle %r2,%r4,0 # clear mem
- jo .-4 # branch back, if not finish
-
- l %r2,.Lrcp-.LPG1(%r13) # Read SCP forced command word
-.Lservicecall:
- stosm .Lpmask-.LPG1(%r13),0x01 # authorize ext interrupts
-
- stctl %r0, %r0,.Lcr-.LPG1(%r13) # get cr0
- la %r1,0x200 # set bit 22
- o %r1,.Lcr-.LPG1(%r13) # or old cr0 with r1
- st %r1,.Lcr-.LPG1(%r13)
- lctl %r0, %r0,.Lcr-.LPG1(%r13) # load modified cr0
-
- mvc __LC_EXT_NEW_PSW(8),.Lpcext-.LPG1(%r13) # set postcall psw
- la %r1, .Lsclph-.LPG1(%r13)
- a %r1,__LC_EXT_NEW_PSW+4 # set handler
- st %r1,__LC_EXT_NEW_PSW+4
-
- la %r4,_pstart-.LPG1(%r13) # %r4 is our index for sccb stuff
- la %r1, .Lsccb-PARMAREA(%r4) # our sccb
- .insn rre,0xb2200000,%r2,%r1 # service call
- ipm %r1
- srl %r1,28 # get cc code
- xr %r3, %r3
- chi %r1,3
- be .Lfchunk-.LPG1(%r13) # leave
- chi %r1,2
- be .Lservicecall-.LPG1(%r13)
- lpsw .Lwaitsclp-.LPG1(%r13)
-.Lsclph:
- lh %r1,.Lsccbr-PARMAREA(%r4)
- chi %r1,0x10 # 0x0010 is the sucess code
- je .Lprocsccb # let's process the sccb
- chi %r1,0x1f0
- bne .Lfchunk-.LPG1(%r13) # unhandled error code
- c %r2, .Lrcp-.LPG1(%r13) # Did we try Read SCP forced
- bne .Lfchunk-.LPG1(%r13) # if no, give up
- l %r2, .Lrcp2-.LPG1(%r13) # try with Read SCP
- b .Lservicecall-.LPG1(%r13)
-.Lprocsccb:
- lhi %r1,0
- icm %r1,3,.Lscpincr1-PARMAREA(%r4) # use this one if != 0
- jnz .Lscnd
- lhi %r1,0x800 # otherwise report 2GB
-.Lscnd:
- lhi %r3,0x800 # limit reported memory size to 2GB
- cr %r1,%r3
- jl .Lno2gb
- lr %r1,%r3
-.Lno2gb:
- xr %r3,%r3 # same logic
- ic %r3,.Lscpa1-PARMAREA(%r4)
- chi %r3,0x00
- jne .Lcompmem
- l %r3,.Lscpa2-PARMAREA(%r13)
-.Lcompmem:
- mr %r2,%r1 # mem in MB on 128-bit
- l %r1,.Lonemb-.LPG1(%r13)
- mr %r2,%r1 # mem size in bytes in %r3
- b .Lfchunk-.LPG1(%r13)
-
-.Lpmask:
- .byte 0
-.align 8
-.Lpcext:.long 0x00080000,0x80000000
-.Lcr:
- .long 0x00 # place holder for cr0
-.Lwaitsclp:
- .long 0x020A0000
- .long .Lsclph
-.Lrcp:
- .int 0x00120001 # Read SCP forced code
-.Lrcp2:
- .int 0x00020001 # Read SCP code
-.Lonemb:
- .int 0x100000
-.Lfchunk:
-
-#
-# find memory chunks.
-#
- lr %r9,%r3 # end of mem
- mvc __LC_PGM_NEW_PSW(8),.Lpcmem-.LPG1(%r13)
- la %r1,1 # test in increments of 128KB
- sll %r1,17
- l %r3,.Lmchunk-.LPG1(%r13) # get pointer to memory_chunk array
- slr %r4,%r4 # set start of chunk to zero
- slr %r5,%r5 # set end of chunk to zero
- slr %r6,%r6 # set access code to zero
- la %r10, MEMORY_CHUNKS # number of chunks
-.Lloop:
- tprot 0(%r5),0 # test protection of first byte
- ipm %r7
- srl %r7,28
- clr %r6,%r7 # compare cc with last access code
- be .Lsame-.LPG1(%r13)
- b .Lchkmem-.LPG1(%r13)
-.Lsame:
- ar %r5,%r1 # add 128KB to end of chunk
- bno .Lloop-.LPG1(%r13) # r1 < 0x80000000 -> loop
-.Lchkmem: # > 2GB or tprot got a program check
- clr %r4,%r5 # chunk size > 0?
- be .Lchkloop-.LPG1(%r13)
- st %r4,0(%r3) # store start address of chunk
- lr %r0,%r5
- slr %r0,%r4
- st %r0,4(%r3) # store size of chunk
- st %r6,8(%r3) # store type of chunk
- la %r3,12(%r3)
- l %r4,.Lmemsize-.LPG1(%r13) # address of variable memory_size
- st %r5,0(%r4) # store last end to memory size
- ahi %r10,-1 # update chunk number
-.Lchkloop:
- lr %r6,%r7 # set access code to last cc
- # we got an exception or we're starting a new
- # chunk , we must check if we should
- # still try to find valid memory (if we detected
- # the amount of available storage), and if we
- # have chunks left
- xr %r0,%r0
- clr %r0,%r9 # did we detect memory?
- je .Ldonemem # if not, leave
- chi %r10,0 # do we have chunks left?
- je .Ldonemem
- alr %r5,%r1 # add 128KB to end of chunk
- lr %r4,%r5 # potential new chunk
- clr %r5,%r9 # should we go on?
- jl .Lloop
-.Ldonemem:
- l %r12,.Lmflags-.LPG1(%r13) # get address of machine_flags
-#
-# find out if we are running under VM
-#
- stidp __LC_CPUID # store cpuid
- tm __LC_CPUID,0xff # running under VM ?
- bno .Lnovm-.LPG1(%r13)
- oi 3(%r12),1 # set VM flag
-.Lnovm:
- lh %r0,__LC_CPUID+4 # get cpu version
- chi %r0,0x7490 # running on a P/390 ?
- bne .Lnop390-.LPG1(%r13)
- oi 3(%r12),4 # set P/390 flag
-.Lnop390:
-
-#
-# find out if we have an IEEE fpu
-#
- mvc __LC_PGM_NEW_PSW(8),.Lpcfpu-.LPG1(%r13)
- efpc %r0,0 # test IEEE extract fpc instruction
- oi 3(%r12),2 # set IEEE fpu flag
-.Lchkfpu:
-
-#
-# find out if we have the CSP instruction
-#
- mvc __LC_PGM_NEW_PSW(8),.Lpccsp-.LPG1(%r13)
- la %r0,0
- lr %r1,%r0
- la %r2,4
- csp %r0,%r2 # Test CSP instruction
- oi 3(%r12),8 # set CSP flag
-.Lchkcsp:
-
-#
-# find out if we have the MVPG instruction
-#
- mvc __LC_PGM_NEW_PSW(8),.Lpcmvpg-.LPG1(%r13)
- sr %r0,%r0
- la %r1,0
- la %r2,0
- mvpg %r1,%r2 # Test CSP instruction
- oi 3(%r12),16 # set MVPG flag
-.Lchkmvpg:
-
-#
-# find out if we have the IDTE instruction
-#
- mvc __LC_PGM_NEW_PSW(8),.Lpcidte-.LPG1(%r13)
- .long 0xb2b10000 # store facility list
- tm 0xc8,0x08 # check bit for clearing-by-ASCE
- bno .Lchkidte-.LPG1(%r13)
- lhi %r1,2094
- lhi %r2,0
- .long 0xb98e2001
- oi 3(%r12),0x80 # set IDTE flag
-.Lchkidte:
-
- lpsw .Lentry-.LPG1(13) # jump to _stext in primary-space,
- # virtual and never return ...
- .align 8
-.Lentry:.long 0x00080000,0x80000000 + _stext
-.Lctl: .long 0x04b50002 # cr0: various things
- .long 0 # cr1: primary space segment table
- .long .Lduct # cr2: dispatchable unit control table
- .long 0 # cr3: instruction authorization
- .long 0 # cr4: instruction authorization
- .long 0xffffffff # cr5: primary-aste origin
- .long 0 # cr6: I/O interrupts
- .long 0 # cr7: secondary space segment table
- .long 0 # cr8: access registers translation
- .long 0 # cr9: tracing off
- .long 0 # cr10: tracing off
- .long 0 # cr11: tracing off
- .long 0 # cr12: tracing off
- .long 0 # cr13: home space segment table
- .long 0xc0000000 # cr14: machine check handling off
- .long 0 # cr15: linkage stack operations
-.Lpcmem:.long 0x00080000,0x80000000 + .Lchkmem
-.Lpcfpu:.long 0x00080000,0x80000000 + .Lchkfpu
-.Lpccsp:.long 0x00080000,0x80000000 + .Lchkcsp
-.Lpcmvpg:.long 0x00080000,0x80000000 + .Lchkmvpg
-.Lpcidte:.long 0x00080000,0x80000000 + .Lchkidte
-.Lmemsize:.long memory_size
-.Lmchunk:.long memory_chunk
-.Lmflags:.long machine_flags
-.Lbss_bgn: .long __bss_start
-.Lbss_end: .long _end
-
- .org PARMAREA-64
-.Lduct: .long 0,0,0,0,0,0,0,0
- .long 0,0,0,0,0,0,0,0
-
-#
-# params at 10400 (setup.h)
-#
- .org PARMAREA
- .global _pstart
-_pstart:
- .long 0,0 # IPL_DEVICE
- .long 0,RAMDISK_ORIGIN # INITRD_START
- .long 0,RAMDISK_SIZE # INITRD_SIZE
-
- .org COMMAND_LINE
- .byte "root=/dev/ram0 ro"
- .byte 0
- .org 0x11000
-.Lsccb:
- .hword 0x1000 # length, one page
- .byte 0x00,0x00,0x00
- .byte 0x80 # variable response bit set
-.Lsccbr:
- .hword 0x00 # response code
-.Lscpincr1:
- .hword 0x00
-.Lscpa1:
- .byte 0x00
- .fill 89,1,0
-.Lscpa2:
- .int 0x00
-.Lscpincr2:
- .quad 0x00
- .fill 3984,1,0
- .org 0x12000
- .global _pend
-_pend:
-
-#ifdef CONFIG_SHARED_KERNEL
- .org 0x100000
+.macro GET_IPL_DEVICE
+.Lget_ipl_device:
+ basr %r12,0
+.LGID: l %r1,0xb8 # get sid
+ sll %r1,15 # test if subchannel is enabled
+ srl %r1,31
+ ltr %r1,%r1
+ bz 0(%r14) # subchannel disabled
+ l %r1,0xb8
+ la %r5,.Lipl_schib-.LGID(%r12)
+ stsch 0(%r5) # get schib of subchannel
+ bnz 0(%r14) # schib not available
+ tm 5(%r5),0x01 # devno valid?
+ bno 0(%r14)
+ la %r6,ipl_parameter_flags-.LGID(%r12)
+ oi 3(%r6),0x01 # set flag
+ la %r2,ipl_devno-.LGID(%r12)
+ mvc 0(2,%r2),6(%r5) # store devno
+ tm 4(%r5),0x80 # qdio capable device?
+ bno 0(%r14)
+ oi 3(%r6),0x02 # set flag
+
+ # copy ipl parameters
+
+ lhi %r0,4096
+ l %r2,20(%r0) # get address of parameter list
+ lhi %r3,IPL_PARMBLOCK_ORIGIN
+ st %r3,20(%r0)
+ lhi %r4,1
+ cr %r2,%r3 # start parameters < destination ?
+ jl 0f
+ lhi %r1,1 # copy direction is upwards
+ j 1f
+0: lhi %r1,-1 # copy direction is downwards
+ ar %r2,%r0
+ ar %r3,%r0
+ ar %r2,%r1
+ ar %r3,%r1
+1: mvc 0(1,%r3),0(%r2) # finally copy ipl parameters
+ ar %r3,%r1
+ ar %r2,%r1
+ sr %r0,%r4
+ jne 1b
+ b 0(%r14)
+
+ .align 4
+.Lipl_schib:
+ .rept 13
+ .long 0
+ .endr
+
+ .globl ipl_parameter_flags
+ipl_parameter_flags:
+ .long 0
+ .globl ipl_devno
+ipl_devno:
+ .word 0
+.endm
+
+#ifdef CONFIG_ARCH_S390X
+#include "head64.S"
+#else
+#include "head31.S"
#endif
-
-#
-# startup-code, running in virtual mode
-#
- .globl _stext
-_stext: basr %r13,0 # get base
-.LPG2:
-#
-# Setup stack
-#
- l %r15,.Linittu-.LPG2(%r13)
- mvc __LC_CURRENT(4),__TI_task(%r15)
- ahi %r15,1<<(PAGE_SHIFT+THREAD_ORDER) # init_task_union + THREAD_SIZE
- st %r15,__LC_KERNEL_STACK # set end of kernel stack
- ahi %r15,-96
- xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15) # clear backchain
-
-# check control registers
- stctl %c0,%c15,0(%r15)
- oi 2(%r15),0x40 # enable sigp emergency signal
- oi 0(%r15),0x10 # switch on low address protection
- lctl %c0,%c15,0(%r15)
-
-#
- lam 0,15,.Laregs-.LPG2(%r13) # load access regs needed by uaccess
- l %r14,.Lstart-.LPG2(%r13)
- basr %r14,%r14 # call start_kernel
-#
-# We returned from start_kernel ?!? PANIK
-#
- basr %r13,0
- lpsw .Ldw-.(%r13) # load disabled wait psw
-#
- .align 8
-.Ldw: .long 0x000a0000,0x00000000
-.Linittu: .long init_thread_union
-.Lstart: .long start_kernel
-.Laregs: .long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
-
diff --git a/arch/s390/kernel/head31.S b/arch/s390/kernel/head31.S
new file mode 100644
index 000000000000..2d3b089bfb83
--- /dev/null
+++ b/arch/s390/kernel/head31.S
@@ -0,0 +1,336 @@
+/*
+ * arch/s390/kernel/head31.S
+ *
+ * (C) Copyright IBM Corp. 2005
+ *
+ * Author(s): Hartmut Penner <hp@de.ibm.com>
+ * Martin Schwidefsky <schwidefsky@de.ibm.com>
+ * Rob van der Heij <rvdhei@iae.nl>
+ * Heiko Carstens <heiko.carstens@de.ibm.com>
+ *
+ */
+
+#
+# startup-code at 0x10000, running in absolute addressing mode
+# this is called either by the ipl loader or directly by PSW restart
+# or linload or SALIPL
+#
+ .org 0x10000
+startup:basr %r13,0 # get base
+.LPG1: l %r1, .Lget_ipl_device_addr-.LPG1(%r13)
+ basr %r14, %r1
+ lctl %c0,%c15,.Lctl-.LPG1(%r13) # load control registers
+ la %r12,_pstart-.LPG1(%r13) # pointer to parameter area
+ # move IPL device to lowcore
+ mvc __LC_IPLDEV(4),IPL_DEVICE-PARMAREA(%r12)
+
+#
+# clear bss memory
+#
+ l %r2,.Lbss_bgn-.LPG1(%r13) # start of bss
+ l %r3,.Lbss_end-.LPG1(%r13) # end of bss
+ sr %r3,%r2 # length of bss
+ sr %r4,%r4
+ sr %r5,%r5 # set src,length and pad to zero
+ sr %r0,%r0
+ mvcle %r2,%r4,0 # clear mem
+ jo .-4 # branch back, if not finish
+
+ l %r2,.Lrcp-.LPG1(%r13) # Read SCP forced command word
+.Lservicecall:
+ stosm .Lpmask-.LPG1(%r13),0x01 # authorize ext interrupts
+
+ stctl %r0, %r0,.Lcr-.LPG1(%r13) # get cr0
+ la %r1,0x200 # set bit 22
+ o %r1,.Lcr-.LPG1(%r13) # or old cr0 with r1
+ st %r1,.Lcr-.LPG1(%r13)
+ lctl %r0, %r0,.Lcr-.LPG1(%r13) # load modified cr0
+
+ mvc __LC_EXT_NEW_PSW(8),.Lpcext-.LPG1(%r13) # set postcall psw
+ la %r1, .Lsclph-.LPG1(%r13)
+ a %r1,__LC_EXT_NEW_PSW+4 # set handler
+ st %r1,__LC_EXT_NEW_PSW+4
+
+ la %r4,_pstart-.LPG1(%r13) # %r4 is our index for sccb stuff
+ la %r1, .Lsccb-PARMAREA(%r4) # our sccb
+ .insn rre,0xb2200000,%r2,%r1 # service call
+ ipm %r1
+ srl %r1,28 # get cc code
+ xr %r3, %r3
+ chi %r1,3
+ be .Lfchunk-.LPG1(%r13) # leave
+ chi %r1,2
+ be .Lservicecall-.LPG1(%r13)
+ lpsw .Lwaitsclp-.LPG1(%r13)
+.Lsclph:
+ lh %r1,.Lsccbr-PARMAREA(%r4)
+ chi %r1,0x10 # 0x0010 is the sucess code
+ je .Lprocsccb # let's process the sccb
+ chi %r1,0x1f0
+ bne .Lfchunk-.LPG1(%r13) # unhandled error code
+ c %r2, .Lrcp-.LPG1(%r13) # Did we try Read SCP forced
+ bne .Lfchunk-.LPG1(%r13) # if no, give up
+ l %r2, .Lrcp2-.LPG1(%r13) # try with Read SCP
+ b .Lservicecall-.LPG1(%r13)
+.Lprocsccb:
+ lhi %r1,0
+ icm %r1,3,.Lscpincr1-PARMAREA(%r4) # use this one if != 0
+ jnz .Lscnd
+ lhi %r1,0x800 # otherwise report 2GB
+.Lscnd:
+ lhi %r3,0x800 # limit reported memory size to 2GB
+ cr %r1,%r3
+ jl .Lno2gb
+ lr %r1,%r3
+.Lno2gb:
+ xr %r3,%r3 # same logic
+ ic %r3,.Lscpa1-PARMAREA(%r4)
+ chi %r3,0x00
+ jne .Lcompmem
+ l %r3,.Lscpa2-PARMAREA(%r13)
+.Lcompmem:
+ mr %r2,%r1 # mem in MB on 128-bit
+ l %r1,.Lonemb-.LPG1(%r13)
+ mr %r2,%r1 # mem size in bytes in %r3
+ b .Lfchunk-.LPG1(%r13)
+
+ .align 4
+.Lget_ipl_device_addr:
+ .long .Lget_ipl_device
+.Lpmask:
+ .byte 0
+.align 8
+.Lpcext:.long 0x00080000,0x80000000
+.Lcr:
+ .long 0x00 # place holder for cr0
+.Lwaitsclp:
+ .long 0x010a0000,0x80000000 + .Lsclph
+.Lrcp:
+ .int 0x00120001 # Read SCP forced code
+.Lrcp2:
+ .int 0x00020001 # Read SCP code
+.Lonemb:
+ .int 0x100000
+.Lfchunk:
+
+#
+# find memory chunks.
+#
+ lr %r9,%r3 # end of mem
+ mvc __LC_PGM_NEW_PSW(8),.Lpcmem-.LPG1(%r13)
+ la %r1,1 # test in increments of 128KB
+ sll %r1,17
+ l %r3,.Lmchunk-.LPG1(%r13) # get pointer to memory_chunk array
+ slr %r4,%r4 # set start of chunk to zero
+ slr %r5,%r5 # set end of chunk to zero
+ slr %r6,%r6 # set access code to zero
+ la %r10, MEMORY_CHUNKS # number of chunks
+.Lloop:
+ tprot 0(%r5),0 # test protection of first byte
+ ipm %r7
+ srl %r7,28
+ clr %r6,%r7 # compare cc with last access code
+ be .Lsame-.LPG1(%r13)
+ b .Lchkmem-.LPG1(%r13)
+.Lsame:
+ ar %r5,%r1 # add 128KB to end of chunk
+ bno .Lloop-.LPG1(%r13) # r1 < 0x80000000 -> loop
+.Lchkmem: # > 2GB or tprot got a program check
+ clr %r4,%r5 # chunk size > 0?
+ be .Lchkloop-.LPG1(%r13)
+ st %r4,0(%r3) # store start address of chunk
+ lr %r0,%r5
+ slr %r0,%r4
+ st %r0,4(%r3) # store size of chunk
+ st %r6,8(%r3) # store type of chunk
+ la %r3,12(%r3)
+ l %r4,.Lmemsize-.LPG1(%r13) # address of variable memory_size
+ st %r5,0(%r4) # store last end to memory size
+ ahi %r10,-1 # update chunk number
+.Lchkloop:
+ lr %r6,%r7 # set access code to last cc
+ # we got an exception or we're starting a new
+ # chunk , we must check if we should
+ # still try to find valid memory (if we detected
+ # the amount of available storage), and if we
+ # have chunks left
+ xr %r0,%r0
+ clr %r0,%r9 # did we detect memory?
+ je .Ldonemem # if not, leave
+ chi %r10,0 # do we have chunks left?
+ je .Ldonemem
+ alr %r5,%r1 # add 128KB to end of chunk
+ lr %r4,%r5 # potential new chunk
+ clr %r5,%r9 # should we go on?
+ jl .Lloop
+.Ldonemem:
+ l %r12,.Lmflags-.LPG1(%r13) # get address of machine_flags
+#
+# find out if we are running under VM
+#
+ stidp __LC_CPUID # store cpuid
+ tm __LC_CPUID,0xff # running under VM ?
+ bno .Lnovm-.LPG1(%r13)
+ oi 3(%r12),1 # set VM flag
+.Lnovm:
+ lh %r0,__LC_CPUID+4 # get cpu version
+ chi %r0,0x7490 # running on a P/390 ?
+ bne .Lnop390-.LPG1(%r13)
+ oi 3(%r12),4 # set P/390 flag
+.Lnop390:
+
+#
+# find out if we have an IEEE fpu
+#
+ mvc __LC_PGM_NEW_PSW(8),.Lpcfpu-.LPG1(%r13)
+ efpc %r0,0 # test IEEE extract fpc instruction
+ oi 3(%r12),2 # set IEEE fpu flag
+.Lchkfpu:
+
+#
+# find out if we have the CSP instruction
+#
+ mvc __LC_PGM_NEW_PSW(8),.Lpccsp-.LPG1(%r13)
+ la %r0,0
+ lr %r1,%r0
+ la %r2,4
+ csp %r0,%r2 # Test CSP instruction
+ oi 3(%r12),8 # set CSP flag
+.Lchkcsp:
+
+#
+# find out if we have the MVPG instruction
+#
+ mvc __LC_PGM_NEW_PSW(8),.Lpcmvpg-.LPG1(%r13)
+ sr %r0,%r0
+ la %r1,0
+ la %r2,0
+ mvpg %r1,%r2 # Test CSP instruction
+ oi 3(%r12),16 # set MVPG flag
+.Lchkmvpg:
+
+#
+# find out if we have the IDTE instruction
+#
+ mvc __LC_PGM_NEW_PSW(8),.Lpcidte-.LPG1(%r13)
+ .long 0xb2b10000 # store facility list
+ tm 0xc8,0x08 # check bit for clearing-by-ASCE
+ bno .Lchkidte-.LPG1(%r13)
+ lhi %r1,2094
+ lhi %r2,0
+ .long 0xb98e2001
+ oi 3(%r12),0x80 # set IDTE flag
+.Lchkidte:
+
+ lpsw .Lentry-.LPG1(13) # jump to _stext in primary-space,
+ # virtual and never return ...
+ .align 8
+.Lentry:.long 0x00080000,0x80000000 + _stext
+.Lctl: .long 0x04b50002 # cr0: various things
+ .long 0 # cr1: primary space segment table
+ .long .Lduct # cr2: dispatchable unit control table
+ .long 0 # cr3: instruction authorization
+ .long 0 # cr4: instruction authorization
+ .long 0xffffffff # cr5: primary-aste origin
+ .long 0 # cr6: I/O interrupts
+ .long 0 # cr7: secondary space segment table
+ .long 0 # cr8: access registers translation
+ .long 0 # cr9: tracing off
+ .long 0 # cr10: tracing off
+ .long 0 # cr11: tracing off
+ .long 0 # cr12: tracing off
+ .long 0 # cr13: home space segment table
+ .long 0xc0000000 # cr14: machine check handling off
+ .long 0 # cr15: linkage stack operations
+.Lpcmem:.long 0x00080000,0x80000000 + .Lchkmem
+.Lpcfpu:.long 0x00080000,0x80000000 + .Lchkfpu
+.Lpccsp:.long 0x00080000,0x80000000 + .Lchkcsp
+.Lpcmvpg:.long 0x00080000,0x80000000 + .Lchkmvpg
+.Lpcidte:.long 0x00080000,0x80000000 + .Lchkidte
+.Lmemsize:.long memory_size
+.Lmchunk:.long memory_chunk
+.Lmflags:.long machine_flags
+.Lbss_bgn: .long __bss_start
+.Lbss_end: .long _end
+
+ .org PARMAREA-64
+.Lduct: .long 0,0,0,0,0,0,0,0
+ .long 0,0,0,0,0,0,0,0
+
+#
+# params at 10400 (setup.h)
+#
+ .org PARMAREA
+ .global _pstart
+_pstart:
+ .long 0,0 # IPL_DEVICE
+ .long 0,RAMDISK_ORIGIN # INITRD_START
+ .long 0,RAMDISK_SIZE # INITRD_SIZE
+
+ .org COMMAND_LINE
+ .byte "root=/dev/ram0 ro"
+ .byte 0
+ .org 0x11000
+.Lsccb:
+ .hword 0x1000 # length, one page
+ .byte 0x00,0x00,0x00
+ .byte 0x80 # variable response bit set
+.Lsccbr:
+ .hword 0x00 # response code
+.Lscpincr1:
+ .hword 0x00
+.Lscpa1:
+ .byte 0x00
+ .fill 89,1,0
+.Lscpa2:
+ .int 0x00
+.Lscpincr2:
+ .quad 0x00
+ .fill 3984,1,0
+ .org 0x12000
+ .global _pend
+_pend:
+
+ GET_IPL_DEVICE
+
+#ifdef CONFIG_SHARED_KERNEL
+ .org 0x100000
+#endif
+
+#
+# startup-code, running in virtual mode
+#
+ .globl _stext
+_stext: basr %r13,0 # get base
+.LPG3:
+#
+# Setup stack
+#
+ l %r15,.Linittu-.LPG3(%r13)
+ mvc __LC_CURRENT(4),__TI_task(%r15)
+ ahi %r15,1<<(PAGE_SHIFT+THREAD_ORDER) # init_task_union+THREAD_SIZE
+ st %r15,__LC_KERNEL_STACK # set end of kernel stack
+ ahi %r15,-96
+ xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15) # clear backchain
+
+# check control registers
+ stctl %c0,%c15,0(%r15)
+ oi 2(%r15),0x40 # enable sigp emergency signal
+ oi 0(%r15),0x10 # switch on low address protection
+ lctl %c0,%c15,0(%r15)
+
+#
+ lam 0,15,.Laregs-.LPG3(%r13) # load access regs needed by uaccess
+ l %r14,.Lstart-.LPG3(%r13)
+ basr %r14,%r14 # call start_kernel
+#
+# We returned from start_kernel ?!? PANIK
+#
+ basr %r13,0
+ lpsw .Ldw-.(%r13) # load disabled wait psw
+#
+ .align 8
+.Ldw: .long 0x000a0000,0x00000000
+.Linittu:.long init_thread_union
+.Lstart:.long start_kernel
+.Laregs:.long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
diff --git a/arch/s390/kernel/head64.S b/arch/s390/kernel/head64.S
index c9ff0404c875..f08c06f45d5c 100644
--- a/arch/s390/kernel/head64.S
+++ b/arch/s390/kernel/head64.S
@@ -1,482 +1,17 @@
/*
- * arch/s390/kernel/head.S
+ * arch/s390/kernel/head64.S
*
- * S390 version
- * Copyright (C) 1999,2000 IBM Deutschland Entwicklung GmbH, IBM Corporation
- * Author(s): Hartmut Penner (hp@de.ibm.com),
- * Martin Schwidefsky (schwidefsky@de.ibm.com),
- * Rob van der Heij (rvdhei@iae.nl)
+ * (C) Copyright IBM Corp. 1999,2005
+ *
+ * Author(s): Hartmut Penner <hp@de.ibm.com>
+ * Martin Schwidefsky <schwidefsky@de.ibm.com>
+ * Rob van der Heij <rvdhei@iae.nl>
+ * Heiko Carstens <heiko.carstens@de.ibm.com>
*
- * There are 5 different IPL methods
- * 1) load the image directly into ram at address 0 and do an PSW restart
- * 2) linload will load the image from address 0x10000 to memory 0x10000
- * and start the code thru LPSW 0x0008000080010000 (VM only, deprecated)
- * 3) generate the tape ipl header, store the generated image on a tape
- * and ipl from it
- * In case of SL tape you need to IPL 5 times to get past VOL1 etc
- * 4) generate the vm reader ipl header, move the generated image to the
- * VM reader (use option NOH!) and do a ipl from reader (VM only)
- * 5) direct call of start by the SALIPL loader
- * We use the cpuid to distinguish between VM and native ipl
- * params for kernel are pushed to 0x10400 (see setup.h)
-
- Changes:
- Okt 25 2000 <rvdheij@iae.nl>
- added code to skip HDR and EOF to allow SL tape IPL (5 retries)
- changed first CCW from rewind to backspace block
-
*/
-#include <linux/config.h>
-#include <asm/setup.h>
-#include <asm/lowcore.h>
-#include <asm/asm-offsets.h>
-#include <asm/thread_info.h>
-#include <asm/page.h>
-
-#ifndef CONFIG_IPL
- .org 0
- .long 0x00080000,0x80000000+startup # Just a restart PSW
-#else
-#ifdef CONFIG_IPL_TAPE
-#define IPL_BS 1024
- .org 0
- .long 0x00080000,0x80000000+iplstart # The first 24 bytes are loaded
- .long 0x27000000,0x60000001 # by ipl to addresses 0-23.
- .long 0x02000000,0x20000000+IPL_BS # (a PSW and two CCWs).
- .long 0x00000000,0x00000000 # external old psw
- .long 0x00000000,0x00000000 # svc old psw
- .long 0x00000000,0x00000000 # program check old psw
- .long 0x00000000,0x00000000 # machine check old psw
- .long 0x00000000,0x00000000 # io old psw
- .long 0x00000000,0x00000000
- .long 0x00000000,0x00000000
- .long 0x00000000,0x00000000
- .long 0x000a0000,0x00000058 # external new psw
- .long 0x000a0000,0x00000060 # svc new psw
- .long 0x000a0000,0x00000068 # program check new psw
- .long 0x000a0000,0x00000070 # machine check new psw
- .long 0x00080000,0x80000000+.Lioint # io new psw
-
- .org 0x100
-#
-# subroutine for loading from tape
-# Paramters:
-# R1 = device number
-# R2 = load address
-.Lloader:
- st %r14,.Lldret
- la %r3,.Lorbread # r3 = address of orb
- la %r5,.Lirb # r5 = address of irb
- st %r2,.Lccwread+4 # initialize CCW data addresses
- lctl %c6,%c6,.Lcr6
- slr %r2,%r2
-.Lldlp:
- la %r6,3 # 3 retries
-.Lssch:
- ssch 0(%r3) # load chunk of IPL_BS bytes
- bnz .Llderr
-.Lw4end:
- bas %r14,.Lwait4io
- tm 8(%r5),0x82 # do we have a problem ?
- bnz .Lrecov
- slr %r7,%r7
- icm %r7,3,10(%r5) # get residual count
- lcr %r7,%r7
- la %r7,IPL_BS(%r7) # IPL_BS-residual=#bytes read
- ar %r2,%r7 # add to total size
- tm 8(%r5),0x01 # found a tape mark ?
- bnz .Ldone
- l %r0,.Lccwread+4 # update CCW data addresses
- ar %r0,%r7
- st %r0,.Lccwread+4
- b .Lldlp
-.Ldone:
- l %r14,.Lldret
- br %r14 # r2 contains the total size
-.Lrecov:
- bas %r14,.Lsense # do the sensing
- bct %r6,.Lssch # dec. retry count & branch
- b .Llderr
-#
-# Sense subroutine
#
-.Lsense:
- st %r14,.Lsnsret
- la %r7,.Lorbsense
- ssch 0(%r7) # start sense command
- bnz .Llderr
- bas %r14,.Lwait4io
- l %r14,.Lsnsret
- tm 8(%r5),0x82 # do we have a problem ?
- bnz .Llderr
- br %r14
-#
-# Wait for interrupt subroutine
-#
-.Lwait4io:
- lpsw .Lwaitpsw
-.Lioint:
- c %r1,0xb8 # compare subchannel number
- bne .Lwait4io
- tsch 0(%r5)
- slr %r0,%r0
- tm 8(%r5),0x82 # do we have a problem ?
- bnz .Lwtexit
- tm 8(%r5),0x04 # got device end ?
- bz .Lwait4io
-.Lwtexit:
- br %r14
-.Llderr:
- lpsw .Lcrash
-
- .align 8
-.Lorbread:
- .long 0x00000000,0x0080ff00,.Lccwread
- .align 8
-.Lorbsense:
- .long 0x00000000,0x0080ff00,.Lccwsense
- .align 8
-.Lccwread:
- .long 0x02200000+IPL_BS,0x00000000
-.Lccwsense:
- .long 0x04200001,0x00000000
-.Lwaitpsw:
- .long 0x020a0000,0x80000000+.Lioint
-
-.Lirb: .long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
-.Lcr6: .long 0xff000000
- .align 8
-.Lcrash:.long 0x000a0000,0x00000000
-.Lldret:.long 0
-.Lsnsret: .long 0
-#endif /* CONFIG_IPL_TAPE */
-
-#ifdef CONFIG_IPL_VM
-#define IPL_BS 0x730
- .org 0
- .long 0x00080000,0x80000000+iplstart # The first 24 bytes are loaded
- .long 0x02000018,0x60000050 # by ipl to addresses 0-23.
- .long 0x02000068,0x60000050 # (a PSW and two CCWs).
- .fill 80-24,1,0x40 # bytes 24-79 are discarded !!
- .long 0x020000f0,0x60000050 # The next 160 byte are loaded
- .long 0x02000140,0x60000050 # to addresses 0x18-0xb7
- .long 0x02000190,0x60000050 # They form the continuation
- .long 0x020001e0,0x60000050 # of the CCW program started
- .long 0x02000230,0x60000050 # by ipl and load the range
- .long 0x02000280,0x60000050 # 0x0f0-0x730 from the image
- .long 0x020002d0,0x60000050 # to the range 0x0f0-0x730
- .long 0x02000320,0x60000050 # in memory. At the end of
- .long 0x02000370,0x60000050 # the channel program the PSW
- .long 0x020003c0,0x60000050 # at location 0 is loaded.
- .long 0x02000410,0x60000050 # Initial processing starts
- .long 0x02000460,0x60000050 # at 0xf0 = iplstart.
- .long 0x020004b0,0x60000050
- .long 0x02000500,0x60000050
- .long 0x02000550,0x60000050
- .long 0x020005a0,0x60000050
- .long 0x020005f0,0x60000050
- .long 0x02000640,0x60000050
- .long 0x02000690,0x60000050
- .long 0x020006e0,0x20000050
-
- .org 0xf0
-#
-# subroutine for loading cards from the reader
-#
-.Lloader:
- la %r3,.Lorb # r2 = address of orb into r2
- la %r5,.Lirb # r4 = address of irb
- la %r6,.Lccws
- la %r7,20
-.Linit:
- st %r2,4(%r6) # initialize CCW data addresses
- la %r2,0x50(%r2)
- la %r6,8(%r6)
- bct 7,.Linit
-
- lctl %c6,%c6,.Lcr6 # set IO subclass mask
- slr %r2,%r2
-.Lldlp:
- ssch 0(%r3) # load chunk of 1600 bytes
- bnz .Llderr
-.Lwait4irq:
- mvc 0x78(8),.Lnewpsw # set up IO interrupt psw
- lpsw .Lwaitpsw
-.Lioint:
- c %r1,0xb8 # compare subchannel number
- bne .Lwait4irq
- tsch 0(%r5)
-
- slr %r0,%r0
- ic %r0,8(%r5) # get device status
- chi %r0,8 # channel end ?
- be .Lcont
- chi %r0,12 # channel end + device end ?
- be .Lcont
-
- l %r0,4(%r5)
- s %r0,8(%r3) # r0/8 = number of ccws executed
- mhi %r0,10 # *10 = number of bytes in ccws
- lh %r3,10(%r5) # get residual count
- sr %r0,%r3 # #ccws*80-residual=#bytes read
- ar %r2,%r0
-
- br %r14 # r2 contains the total size
-
-.Lcont:
- ahi %r2,0x640 # add 0x640 to total size
- la %r6,.Lccws
- la %r7,20
-.Lincr:
- l %r0,4(%r6) # update CCW data addresses
- ahi %r0,0x640
- st %r0,4(%r6)
- ahi %r6,8
- bct 7,.Lincr
-
- b .Lldlp
-.Llderr:
- lpsw .Lcrash
-
- .align 8
-.Lorb: .long 0x00000000,0x0080ff00,.Lccws
-.Lirb: .long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
-.Lcr6: .long 0xff000000
-.Lloadp:.long 0,0
- .align 8
-.Lcrash:.long 0x000a0000,0x00000000
-.Lnewpsw:
- .long 0x00080000,0x80000000+.Lioint
-.Lwaitpsw:
- .long 0x020a0000,0x80000000+.Lioint
-
- .align 8
-.Lccws: .rept 19
- .long 0x02600050,0x00000000
- .endr
- .long 0x02200050,0x00000000
-#endif /* CONFIG_IPL_VM */
-
-iplstart:
- lh %r1,0xb8 # test if subchannel number
- bct %r1,.Lnoload # is valid
- l %r1,0xb8 # load ipl subchannel number
- la %r2,IPL_BS # load start address
- bas %r14,.Lloader # load rest of ipl image
- larl %r12,_pstart # pointer to parameter area
- st %r1,IPL_DEVICE+4-PARMAREA(%r12) # store ipl device number
-
-#
-# load parameter file from ipl device
-#
-.Lagain1:
- l %r2,INITRD_START+4-PARMAREA(%r12)# use ramdisk location as temp
- bas %r14,.Lloader # load parameter file
- ltr %r2,%r2 # got anything ?
- bz .Lnopf
- chi %r2,895
- bnh .Lnotrunc
- la %r2,895
-.Lnotrunc:
- l %r4,INITRD_START+4-PARMAREA(%r12)
- clc 0(3,%r4),.L_hdr # if it is HDRx
- bz .Lagain1 # skip dataset header
- clc 0(3,%r4),.L_eof # if it is EOFx
- bz .Lagain1 # skip dateset trailer
- la %r5,0(%r4,%r2)
- lr %r3,%r2
-.Lidebc:
- tm 0(%r5),0x80 # high order bit set ?
- bo .Ldocv # yes -> convert from EBCDIC
- ahi %r5,-1
- bct %r3,.Lidebc
- b .Lnocv
-.Ldocv:
- l %r3,.Lcvtab
- tr 0(256,%r4),0(%r3) # convert parameters to ascii
- tr 256(256,%r4),0(%r3)
- tr 512(256,%r4),0(%r3)
- tr 768(122,%r4),0(%r3)
-.Lnocv: la %r3,COMMAND_LINE-PARMAREA(%r12) # load adr. of command line
- mvc 0(256,%r3),0(%r4)
- mvc 256(256,%r3),256(%r4)
- mvc 512(256,%r3),512(%r4)
- mvc 768(122,%r3),768(%r4)
- slr %r0,%r0
- b .Lcntlp
-.Ldelspc:
- ic %r0,0(%r2,%r3)
- chi %r0,0x20 # is it a space ?
- be .Lcntlp
- ahi %r2,1
- b .Leolp
-.Lcntlp:
- brct %r2,.Ldelspc
-.Leolp:
- slr %r0,%r0
- stc %r0,0(%r2,%r3) # terminate buffer
-.Lnopf:
-
-#
-# load ramdisk from ipl device
-#
-.Lagain2:
- l %r2,INITRD_START+4-PARMAREA(%r12)# load adr. of ramdisk
- bas %r14,.Lloader # load ramdisk
- st %r2,INITRD_SIZE+4-PARMAREA(%r12) # store size of ramdisk
- ltr %r2,%r2
- bnz .Lrdcont
- st %r2,INITRD_START+4-PARMAREA(%r12)# no ramdisk found, null it
-.Lrdcont:
- l %r2,INITRD_START+4-PARMAREA(%r12)
- clc 0(3,%r2),.L_hdr # skip HDRx and EOFx
- bz .Lagain2
- clc 0(3,%r2),.L_eof
- bz .Lagain2
-
-#ifdef CONFIG_IPL_VM
-#
-# reset files in VM reader
-#
- stidp __LC_CPUID # store cpuid
- tm __LC_CPUID,0xff # running VM ?
- bno .Lnoreset
- la %r2,.Lreset
- lhi %r3,26
- diag %r2,%r3,8
- la %r5,.Lirb
- stsch 0(%r5) # check if irq is pending
- tm 30(%r5),0x0f # by verifying if any of the
- bnz .Lwaitforirq # activity or status control
- tm 31(%r5),0xff # bits is set in the schib
- bz .Lnoreset
-.Lwaitforirq:
- mvc 0x78(8),.Lrdrnewpsw # set up IO interrupt psw
-.Lwaitrdrirq:
- lpsw .Lrdrwaitpsw
-.Lrdrint:
- c %r1,0xb8 # compare subchannel number
- bne .Lwaitrdrirq
- la %r5,.Lirb
- tsch 0(%r5)
-.Lnoreset:
- b .Lnoload
-
- .align 8
-.Lrdrnewpsw:
- .long 0x00080000,0x80000000+.Lrdrint
-.Lrdrwaitpsw:
- .long 0x020a0000,0x80000000+.Lrdrint
-#endif
-
-#
-# everything loaded, go for it
-#
-.Lnoload:
- l %r1,.Lstartup
- br %r1
-
-.Lstartup: .long startup
-.Lcvtab:.long _ebcasc # ebcdic to ascii table
-.Lreset:.byte 0xc3,0xc8,0xc1,0xd5,0xc7,0xc5,0x40,0xd9,0xc4,0xd9,0x40
- .byte 0xc1,0xd3,0xd3,0x40,0xd2,0xc5,0xc5,0xd7,0x40,0xd5,0xd6
- .byte 0xc8,0xd6,0xd3,0xc4 # "change rdr all keep nohold"
-.L_eof: .long 0xc5d6c600 /* C'EOF' */
-.L_hdr: .long 0xc8c4d900 /* C'HDR' */
-#endif /* CONFIG_IPL */
-
-#
-# SALIPL loader support. Based on a patch by Rob van der Heij.
-# This entry point is called directly from the SALIPL loader and
-# doesn't need a builtin ipl record.
-#
- .org 0x800
- .globl start
-start:
- stm %r0,%r15,0x07b0 # store registers
- basr %r12,%r0
-.base:
- l %r11,.parm
- l %r8,.cmd # pointer to command buffer
-
- ltr %r9,%r9 # do we have SALIPL parameters?
- bp .sk8x8
-
- mvc 0(64,%r8),0x00b0 # copy saved registers
- xc 64(240-64,%r8),0(%r8) # remainder of buffer
- tr 0(64,%r8),.lowcase
- b .gotr
-.sk8x8:
- mvc 0(240,%r8),0(%r9) # copy iplparms into buffer
-.gotr:
- l %r10,.tbl # EBCDIC to ASCII table
- tr 0(240,%r8),0(%r10)
- stidp __LC_CPUID # Are we running on VM maybe
- cli __LC_CPUID,0xff
- bnz .test
- .long 0x83300060 # diag 3,0,x'0060' - storage size
- b .done
-.test:
- mvc 0x68(8),.pgmnw # set up pgm check handler
- l %r2,.fourmeg
- lr %r3,%r2
- bctr %r3,%r0 # 4M-1
-.loop: iske %r0,%r3
- ar %r3,%r2
-.pgmx:
- sr %r3,%r2
- la %r3,1(%r3)
-.done:
- l %r1,.memsize
- st %r3,4(%r1)
- slr %r0,%r0
- st %r0,INITRD_SIZE+4-PARMAREA(%r11)
- st %r0,INITRD_START+4-PARMAREA(%r11)
- j startup # continue with startup
-.tbl: .long _ebcasc # translate table
-.cmd: .long COMMAND_LINE # address of command line buffer
-.parm: .long PARMAREA
-.fourmeg: .long 0x00400000 # 4M
-.pgmnw: .long 0x00080000,.pgmx
-.memsize: .long memory_size
-.lowcase:
- .byte 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07
- .byte 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f
- .byte 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17
- .byte 0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f
- .byte 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27
- .byte 0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f
- .byte 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37
- .byte 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f
- .byte 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47
- .byte 0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f
- .byte 0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57
- .byte 0x58,0x59,0x5a,0x5b,0x5c,0x5d,0x5e,0x5f
- .byte 0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67
- .byte 0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f
- .byte 0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77
- .byte 0x78,0x79,0x7a,0x7b,0x7c,0x7d,0x7e,0x7f
-
- .byte 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87
- .byte 0x88,0x89,0x8a,0x8b,0x8c,0x8d,0x8e,0x8f
- .byte 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97
- .byte 0x98,0x99,0x9a,0x9b,0x9c,0x9d,0x9e,0x9f
- .byte 0xa0,0xa1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7
- .byte 0xa8,0xa9,0xaa,0xab,0xac,0xad,0xae,0xaf
- .byte 0xb0,0xb1,0xb2,0xb3,0xb4,0xb5,0xb6,0xb7
- .byte 0xb8,0xb9,0xba,0xbb,0xbc,0xbd,0xbe,0xbf
- .byte 0xc0,0x81,0x82,0x83,0x84,0x85,0x86,0x87 # .abcdefg
- .byte 0x88,0x89,0xca,0xcb,0xcc,0xcd,0xce,0xcf # hi
- .byte 0xd0,0x91,0x92,0x93,0x94,0x95,0x96,0x97 # .jklmnop
- .byte 0x98,0x99,0xda,0xdb,0xdc,0xdd,0xde,0xdf # qr
- .byte 0xe0,0xe1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7 # ..stuvwx
- .byte 0xa8,0xa9,0xea,0xeb,0xec,0xed,0xee,0xef # yz
- .byte 0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7
- .byte 0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfe,0xff
-
-#
-# startup-code at 0x10000, running in real mode
+# startup-code at 0x10000, running in absolute addressing mode
# this is called either by the ipl loader or directly by PSW restart
# or linload or SALIPL
#
@@ -484,6 +19,8 @@ start:
startup:basr %r13,0 # get base
.LPG1: sll %r13,1 # remove high order bit
srl %r13,1
+ l %r1,.Lget_ipl_device_addr-.LPG1(%r13)
+ basr %r14,%r1
lhi %r1,1 # mode 1 = esame
slr %r0,%r0 # set cpuid to zero
sigp %r1,%r0,0x12 # switch to esame mode
@@ -528,7 +65,7 @@ startup:basr %r13,0 # get base
be .Lfchunk-.LPG1(%r13) # leave
chi %r1,2
be .Lservicecall-.LPG1(%r13)
- lpsw .Lwaitsclp-.LPG1(%r13)
+ lpswe .Lwaitsclp-.LPG1(%r13)
.Lsclph:
lh %r1,.Lsccbr-PARMAREA(%r4)
chi %r1,0x10 # 0x0010 is the sucess code
@@ -556,14 +93,16 @@ startup:basr %r13,0 # get base
mlgr %r2,%r1 # mem size in bytes in %r3
b .Lfchunk-.LPG1(%r13)
+ .align 4
+.Lget_ipl_device_addr:
+ .long .Lget_ipl_device
.Lpmask:
.byte 0
.align 8
.Lcr:
.quad 0x00 # place holder for cr0
.Lwaitsclp:
- .long 0x020A0000
- .quad .Lsclph
+ .quad 0x0102000180000000,.Lsclph
.Lrcp:
.int 0x00120001 # Read SCP forced code
.Lrcp2:
@@ -746,6 +285,8 @@ _pstart:
.global _pend
_pend:
+ GET_IPL_DEVICE
+
#ifdef CONFIG_SHARED_KERNEL
.org 0x100000
#endif
@@ -755,7 +296,7 @@ _pend:
#
.globl _stext
_stext: basr %r13,0 # get base
-.LPG2:
+.LPG3:
#
# Setup stack
#
@@ -774,7 +315,7 @@ _stext: basr %r13,0 # get base
lctlg %c0,%c15,0(%r15)
#
- lam 0,15,.Laregs-.LPG2(%r13) # load access regs needed by uaccess
+ lam 0,15,.Laregs-.LPG3(%r13) # load access regs needed by uaccess
brasl %r14,start_kernel # go to C code
#
# We returned from start_kernel ?!? PANIK
diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c
index 9f3dff6c0b72..78b64fe5e7c2 100644
--- a/arch/s390/kernel/process.c
+++ b/arch/s390/kernel/process.c
@@ -99,15 +99,15 @@ void default_idle(void)
{
int cpu, rc;
+ /* CPU is going idle. */
+ cpu = smp_processor_id();
+
local_irq_disable();
- if (need_resched()) {
+ if (need_resched()) {
local_irq_enable();
- schedule();
- return;
- }
+ return;
+ }
- /* CPU is going idle. */
- cpu = smp_processor_id();
rc = notifier_call_chain(&idle_chain, CPU_IDLE, (void *)(long) cpu);
if (rc != NOTIFY_OK && rc != NOTIFY_DONE)
BUG();
@@ -120,7 +120,7 @@ void default_idle(void)
__ctl_set_bit(8, 15);
#ifdef CONFIG_HOTPLUG_CPU
- if (cpu_is_offline(smp_processor_id()))
+ if (cpu_is_offline(cpu))
cpu_die();
#endif
@@ -139,8 +139,14 @@ void default_idle(void)
void cpu_idle(void)
{
- for (;;)
- default_idle();
+ for (;;) {
+ while (!need_resched())
+ default_idle();
+
+ preempt_enable_no_resched();
+ schedule();
+ preempt_disable();
+ }
}
void show_regs(struct pt_regs *regs)
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c
index 5204778b8e5e..31e7b19348b7 100644
--- a/arch/s390/kernel/setup.c
+++ b/arch/s390/kernel/setup.c
@@ -36,6 +36,7 @@
#include <linux/console.h>
#include <linux/seq_file.h>
#include <linux/kernel_stat.h>
+#include <linux/device.h>
#include <asm/uaccess.h>
#include <asm/system.h>
@@ -685,3 +686,188 @@ struct seq_operations cpuinfo_op = {
.show = show_cpuinfo,
};
+#define DEFINE_IPL_ATTR(_name, _format, _value) \
+static ssize_t ipl_##_name##_show(struct subsystem *subsys, \
+ char *page) \
+{ \
+ return sprintf(page, _format, _value); \
+} \
+static struct subsys_attribute ipl_##_name##_attr = \
+ __ATTR(_name, S_IRUGO, ipl_##_name##_show, NULL);
+
+DEFINE_IPL_ATTR(wwpn, "0x%016llx\n", (unsigned long long)
+ IPL_PARMBLOCK_START->fcp.wwpn);
+DEFINE_IPL_ATTR(lun, "0x%016llx\n", (unsigned long long)
+ IPL_PARMBLOCK_START->fcp.lun);
+DEFINE_IPL_ATTR(bootprog, "%lld\n", (unsigned long long)
+ IPL_PARMBLOCK_START->fcp.bootprog);
+DEFINE_IPL_ATTR(br_lba, "%lld\n", (unsigned long long)
+ IPL_PARMBLOCK_START->fcp.br_lba);
+
+enum ipl_type_type {
+ ipl_type_unknown,
+ ipl_type_ccw,
+ ipl_type_fcp,
+};
+
+static enum ipl_type_type
+get_ipl_type(void)
+{
+ struct ipl_parameter_block *ipl = IPL_PARMBLOCK_START;
+
+ if (!IPL_DEVNO_VALID)
+ return ipl_type_unknown;
+ if (!IPL_PARMBLOCK_VALID)
+ return ipl_type_ccw;
+ if (ipl->hdr.header.version > IPL_MAX_SUPPORTED_VERSION)
+ return ipl_type_unknown;
+ if (ipl->fcp.pbt != IPL_TYPE_FCP)
+ return ipl_type_unknown;
+ return ipl_type_fcp;
+}
+
+static ssize_t
+ipl_type_show(struct subsystem *subsys, char *page)
+{
+ switch (get_ipl_type()) {
+ case ipl_type_ccw:
+ return sprintf(page, "ccw\n");
+ case ipl_type_fcp:
+ return sprintf(page, "fcp\n");
+ default:
+ return sprintf(page, "unknown\n");
+ }
+}
+
+static struct subsys_attribute ipl_type_attr = __ATTR_RO(ipl_type);
+
+static ssize_t
+ipl_device_show(struct subsystem *subsys, char *page)
+{
+ struct ipl_parameter_block *ipl = IPL_PARMBLOCK_START;
+
+ switch (get_ipl_type()) {
+ case ipl_type_ccw:
+ return sprintf(page, "0.0.%04x\n", ipl_devno);
+ case ipl_type_fcp:
+ return sprintf(page, "0.0.%04x\n", ipl->fcp.devno);
+ default:
+ return 0;
+ }
+}
+
+static struct subsys_attribute ipl_device_attr =
+ __ATTR(device, S_IRUGO, ipl_device_show, NULL);
+
+static struct attribute *ipl_fcp_attrs[] = {
+ &ipl_type_attr.attr,
+ &ipl_device_attr.attr,
+ &ipl_wwpn_attr.attr,
+ &ipl_lun_attr.attr,
+ &ipl_bootprog_attr.attr,
+ &ipl_br_lba_attr.attr,
+ NULL,
+};
+
+static struct attribute_group ipl_fcp_attr_group = {
+ .attrs = ipl_fcp_attrs,
+};
+
+static struct attribute *ipl_ccw_attrs[] = {
+ &ipl_type_attr.attr,
+ &ipl_device_attr.attr,
+ NULL,
+};
+
+static struct attribute_group ipl_ccw_attr_group = {
+ .attrs = ipl_ccw_attrs,
+};
+
+static struct attribute *ipl_unknown_attrs[] = {
+ &ipl_type_attr.attr,
+ NULL,
+};
+
+static struct attribute_group ipl_unknown_attr_group = {
+ .attrs = ipl_unknown_attrs,
+};
+
+static ssize_t
+ipl_parameter_read(struct kobject *kobj, char *buf, loff_t off, size_t count)
+{
+ unsigned int size = IPL_PARMBLOCK_SIZE;
+
+ if (off > size)
+ return 0;
+ if (off + count > size)
+ count = size - off;
+
+ memcpy(buf, (void *) IPL_PARMBLOCK_START + off, count);
+ return count;
+}
+
+static struct bin_attribute ipl_parameter_attr = {
+ .attr = {
+ .name = "binary_parameter",
+ .mode = S_IRUGO,
+ .owner = THIS_MODULE,
+ },
+ .size = PAGE_SIZE,
+ .read = &ipl_parameter_read,
+};
+
+static ssize_t
+ipl_scp_data_read(struct kobject *kobj, char *buf, loff_t off, size_t count)
+{
+ unsigned int size = IPL_PARMBLOCK_START->fcp.scp_data_len;
+ void *scp_data = &IPL_PARMBLOCK_START->fcp.scp_data;
+
+ if (off > size)
+ return 0;
+ if (off + count > size)
+ count = size - off;
+
+ memcpy(buf, scp_data + off, count);
+ return count;
+}
+
+static struct bin_attribute ipl_scp_data_attr = {
+ .attr = {
+ .name = "scp_data",
+ .mode = S_IRUGO,
+ .owner = THIS_MODULE,
+ },
+ .size = PAGE_SIZE,
+ .read = &ipl_scp_data_read,
+};
+
+static decl_subsys(ipl, NULL, NULL);
+
+static int __init
+ipl_device_sysfs_register(void) {
+ int rc;
+
+ rc = firmware_register(&ipl_subsys);
+ if (rc)
+ return rc;
+
+ switch (get_ipl_type()) {
+ case ipl_type_ccw:
+ sysfs_create_group(&ipl_subsys.kset.kobj, &ipl_ccw_attr_group);
+ break;
+ case ipl_type_fcp:
+ sysfs_create_group(&ipl_subsys.kset.kobj, &ipl_fcp_attr_group);
+ sysfs_create_bin_file(&ipl_subsys.kset.kobj,
+ &ipl_parameter_attr);
+ sysfs_create_bin_file(&ipl_subsys.kset.kobj,
+ &ipl_scp_data_attr);
+ break;
+ default:
+ sysfs_create_group(&ipl_subsys.kset.kobj,
+ &ipl_unknown_attr_group);
+ break;
+ }
+ return 0;
+}
+
+__initcall(ipl_device_sysfs_register);
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c
index e13c87b446b2..5856b3fda6bf 100644
--- a/arch/s390/kernel/smp.c
+++ b/arch/s390/kernel/smp.c
@@ -533,6 +533,7 @@ int __devinit start_secondary(void *cpuvoid)
{
/* Setup the cpu */
cpu_init();
+ preempt_disable();
/* init per CPU timer */
init_cpu_timer();
#ifdef CONFIG_VIRT_TIMER
diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c
index 2fd75da15495..c36353e8c140 100644
--- a/arch/s390/kernel/time.c
+++ b/arch/s390/kernel/time.c
@@ -49,10 +49,6 @@
#define TICK_SIZE tick
-u64 jiffies_64 = INITIAL_JIFFIES;
-
-EXPORT_SYMBOL(jiffies_64);
-
static ext_int_info_t ext_int_info_cc;
static u64 init_timer_cc;
static u64 jiffies_timer_cc;
@@ -241,6 +237,8 @@ int sysctl_hz_timer = 1;
*/
static inline void stop_hz_timer(void)
{
+ unsigned long flags;
+ unsigned long seq, next;
__u64 timer, todval;
if (sysctl_hz_timer != 0)
@@ -261,7 +259,11 @@ static inline void stop_hz_timer(void)
* This cpu is going really idle. Set up the clock comparator
* for the next event.
*/
- timer = (__u64) (next_timer_interrupt() - jiffies) + jiffies_64;
+ next = next_timer_interrupt();
+ do {
+ seq = read_seqbegin_irqsave(&xtime_lock, flags);
+ timer = (__u64)(next - jiffies) + jiffies_64;
+ } while (read_seqretry_irqrestore(&xtime_lock, seq, flags));
todval = -1ULL;
/* Be careful about overflows. */
if (timer < (-1ULL / CLK_TICKS_PER_JIFFY)) {
diff --git a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c
index 6b8703ec2ae6..c5bd36fae56b 100644
--- a/arch/s390/kernel/traps.c
+++ b/arch/s390/kernel/traps.c
@@ -57,7 +57,6 @@ int sysctl_userprocess_debug = 0;
extern pgm_check_handler_t do_protection_exception;
extern pgm_check_handler_t do_dat_exception;
-extern pgm_check_handler_t do_pseudo_page_fault;
#ifdef CONFIG_PFAULT
extern int pfault_init(void);
extern void pfault_fini(void);
@@ -676,20 +675,6 @@ asmlinkage void kernel_stack_overflow(struct pt_regs * regs)
panic("Corrupt kernel stack, can't continue.");
}
-#ifndef CONFIG_ARCH_S390X
-static int
-pagex_reboot_event(struct notifier_block *this, unsigned long event, void *ptr)
-{
- if (MACHINE_IS_VM)
- cpcmd("SET PAGEX OFF", NULL, 0, NULL);
- return NOTIFY_DONE;
-}
-
-static struct notifier_block pagex_reboot_notifier = {
- .notifier_call = &pagex_reboot_event,
-};
-#endif
-
/* init is done in lowcore.S and head.S */
void __init trap_init(void)
@@ -717,9 +702,7 @@ void __init trap_init(void)
pgm_check_table[0x11] = &do_dat_exception;
pgm_check_table[0x12] = &translation_exception;
pgm_check_table[0x13] = &special_op_exception;
-#ifndef CONFIG_ARCH_S390X
- pgm_check_table[0x14] = &do_pseudo_page_fault;
-#else /* CONFIG_ARCH_S390X */
+#ifdef CONFIG_ARCH_S390X
pgm_check_table[0x38] = &do_dat_exception;
pgm_check_table[0x39] = &do_dat_exception;
pgm_check_table[0x3A] = &do_dat_exception;
@@ -731,12 +714,10 @@ void __init trap_init(void)
pgm_check_table[0x40] = &do_monitor_call;
if (MACHINE_IS_VM) {
+#ifdef CONFIG_PFAULT
/*
- * First try to get pfault pseudo page faults going.
- * If this isn't available turn on pagex page faults.
+ * Try to get pfault pseudo page faults going.
*/
-#ifdef CONFIG_PFAULT
- /* request the 0x2603 external interrupt */
if (register_early_external_interrupt(0x2603, pfault_interrupt,
&ext_int_pfault) != 0)
panic("Couldn't request external interrupt 0x2603");
@@ -748,9 +729,5 @@ void __init trap_init(void)
unregister_early_external_interrupt(0x2603, pfault_interrupt,
&ext_int_pfault);
#endif
-#ifndef CONFIG_ARCH_S390X
- register_reboot_notifier(&pagex_reboot_notifier);
- cpcmd("SET PAGEX ON", NULL, 0, NULL);
-#endif
}
}
diff --git a/arch/s390/kernel/vtime.c b/arch/s390/kernel/vtime.c
index fa0726507b3d..22a895ecb7a4 100644
--- a/arch/s390/kernel/vtime.c
+++ b/arch/s390/kernel/vtime.c
@@ -24,7 +24,6 @@
#include <asm/s390_ext.h>
#include <asm/timer.h>
-#define VTIMER_MAGIC (TIMER_MAGIC + 1)
static ext_int_info_t ext_int_info_timer;
DEFINE_PER_CPU(struct vtimer_queue, virt_cpu_timer);
@@ -277,20 +276,12 @@ static void do_cpu_timer_interrupt(struct pt_regs *regs, __u16 error_code)
void init_virt_timer(struct vtimer_list *timer)
{
- timer->magic = VTIMER_MAGIC;
timer->function = NULL;
INIT_LIST_HEAD(&timer->entry);
spin_lock_init(&timer->lock);
}
EXPORT_SYMBOL(init_virt_timer);
-static inline int check_vtimer(struct vtimer_list *timer)
-{
- if (timer->magic != VTIMER_MAGIC)
- return -EINVAL;
- return 0;
-}
-
static inline int vtimer_pending(struct vtimer_list *timer)
{
return (!list_empty(&timer->entry));
@@ -346,7 +337,7 @@ static void internal_add_vtimer(struct vtimer_list *timer)
static inline int prepare_vtimer(struct vtimer_list *timer)
{
- if (check_vtimer(timer) || !timer->function) {
+ if (!timer->function) {
printk("add_virt_timer: uninitialized timer\n");
return -EINVAL;
}
@@ -414,7 +405,7 @@ int mod_virt_timer(struct vtimer_list *timer, __u64 expires)
unsigned long flags;
int cpu;
- if (check_vtimer(timer) || !timer->function) {
+ if (!timer->function) {
printk("mod_virt_timer: uninitialized timer\n");
return -EINVAL;
}
@@ -481,11 +472,6 @@ int del_virt_timer(struct vtimer_list *timer)
unsigned long flags;
struct vtimer_queue *vt_list;
- if (check_vtimer(timer)) {
- printk("del_virt_timer: timer not initialized\n");
- return -EINVAL;
- }
-
/* check if timer is pending */
if (!vtimer_pending(timer))
return 0;
diff --git a/arch/s390/mm/extmem.c b/arch/s390/mm/extmem.c
index c5348108ca3c..506a33b51e4f 100644
--- a/arch/s390/mm/extmem.c
+++ b/arch/s390/mm/extmem.c
@@ -234,8 +234,8 @@ query_segment_type (struct dcss_segment *seg)
rc = 0;
out_free:
- if (qin) kfree(qin);
- if (qout) kfree(qout);
+ kfree(qin);
+ kfree(qout);
return rc;
}
@@ -394,7 +394,7 @@ __segment_load (char *name, int do_nonshared, unsigned long *addr, unsigned long
segtype_string[seg->vm_segtype]);
goto out;
out_free:
- kfree (seg);
+ kfree(seg);
out:
return rc;
}
@@ -505,7 +505,7 @@ segment_modify_shared (char *name, int do_nonshared)
list_del(&seg->list);
dcss_diag(DCSS_PURGESEG, seg->dcss_name,
&dummy, &dummy);
- kfree (seg);
+ kfree(seg);
out_unlock:
spin_unlock(&dcss_lock);
return rc;
diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c
index 856a971759b1..fb2607c369ed 100644
--- a/arch/s390/mm/fault.c
+++ b/arch/s390/mm/fault.c
@@ -160,7 +160,7 @@ static void do_sigsegv(struct pt_regs *regs, unsigned long error_code,
* 11 Page translation -> Not present (nullification)
* 3b Region third trans. -> Not present (nullification)
*/
-extern inline void
+static inline void
do_exception(struct pt_regs *regs, unsigned long error_code, int is_protection)
{
struct task_struct *tsk;
@@ -352,115 +352,6 @@ void do_dat_exception(struct pt_regs *regs, unsigned long error_code)
do_exception(regs, error_code & 0xff, 0);
}
-#ifndef CONFIG_ARCH_S390X
-
-typedef struct _pseudo_wait_t {
- struct _pseudo_wait_t *next;
- wait_queue_head_t queue;
- unsigned long address;
- int resolved;
-} pseudo_wait_t;
-
-static pseudo_wait_t *pseudo_lock_queue = NULL;
-static spinlock_t pseudo_wait_spinlock; /* spinlock to protect lock queue */
-
-/*
- * This routine handles 'pagex' pseudo page faults.
- */
-asmlinkage void
-do_pseudo_page_fault(struct pt_regs *regs, unsigned long error_code)
-{
- pseudo_wait_t wait_struct;
- pseudo_wait_t *ptr, *last, *next;
- unsigned long address;
-
- /*
- * get the failing address
- * more specific the segment and page table portion of
- * the address
- */
- address = S390_lowcore.trans_exc_code & 0xfffff000;
-
- if (address & 0x80000000) {
- /* high bit set -> a page has been swapped in by VM */
- address &= 0x7fffffff;
- spin_lock(&pseudo_wait_spinlock);
- last = NULL;
- ptr = pseudo_lock_queue;
- while (ptr != NULL) {
- next = ptr->next;
- if (address == ptr->address) {
- /*
- * This is one of the processes waiting
- * for the page. Unchain from the queue.
- * There can be more than one process
- * waiting for the same page. VM presents
- * an initial and a completion interrupt for
- * every process that tries to access a
- * page swapped out by VM.
- */
- if (last == NULL)
- pseudo_lock_queue = next;
- else
- last->next = next;
- /* now wake up the process */
- ptr->resolved = 1;
- wake_up(&ptr->queue);
- } else
- last = ptr;
- ptr = next;
- }
- spin_unlock(&pseudo_wait_spinlock);
- } else {
- /* Pseudo page faults in kernel mode is a bad idea */
- if (!(regs->psw.mask & PSW_MASK_PSTATE)) {
- /*
- * VM presents pseudo page faults if the interrupted
- * state was not disabled for interrupts. So we can
- * get pseudo page fault interrupts while running
- * in kernel mode. We simply access the page here
- * while we are running disabled. VM will then swap
- * in the page synchronously.
- */
- if (check_user_space(regs, error_code) == 0)
- /* dereference a virtual kernel address */
- __asm__ __volatile__ (
- " ic 0,0(%0)"
- : : "a" (address) : "0");
- else
- /* dereference a virtual user address */
- __asm__ __volatile__ (
- " la 2,0(%0)\n"
- " sacf 512\n"
- " ic 2,0(2)\n"
- "0:sacf 0\n"
- ".section __ex_table,\"a\"\n"
- " .align 4\n"
- " .long 0b,0b\n"
- ".previous"
- : : "a" (address) : "2" );
-
- return;
- }
- /* initialize and add element to pseudo_lock_queue */
- init_waitqueue_head (&wait_struct.queue);
- wait_struct.address = address;
- wait_struct.resolved = 0;
- spin_lock(&pseudo_wait_spinlock);
- wait_struct.next = pseudo_lock_queue;
- pseudo_lock_queue = &wait_struct;
- spin_unlock(&pseudo_wait_spinlock);
- /*
- * The instruction that caused the program check will
- * be repeated. Don't signal single step via SIGTRAP.
- */
- clear_tsk_thread_flag(current, TIF_SINGLE_STEP);
- /* go to sleep */
- wait_event(wait_struct.queue, wait_struct.resolved);
- }
-}
-#endif /* CONFIG_ARCH_S390X */
-
#ifdef CONFIG_PFAULT
/*
* 'pfault' pseudo page faults routines.
@@ -508,7 +399,7 @@ int pfault_init(void)
" .quad 0b,1b\n"
#endif /* CONFIG_ARCH_S390X */
".previous"
- : "=d" (rc) : "a" (&refbk) : "cc" );
+ : "=d" (rc) : "a" (&refbk), "m" (refbk) : "cc" );
__ctl_set_bit(0, 9);
return rc;
}
@@ -532,7 +423,7 @@ void pfault_fini(void)
" .quad 0b,0b\n"
#endif /* CONFIG_ARCH_S390X */
".previous"
- : : "a" (&refbk) : "cc" );
+ : : "a" (&refbk), "m" (refbk) : "cc" );
}
asmlinkage void
diff --git a/arch/s390/mm/ioremap.c b/arch/s390/mm/ioremap.c
index c6c39d868bc8..0f6e9ecbefe2 100644
--- a/arch/s390/mm/ioremap.c
+++ b/arch/s390/mm/ioremap.c
@@ -58,7 +58,7 @@ static inline int remap_area_pmd(pmd_t * pmd, unsigned long address, unsigned lo
if (address >= end)
BUG();
do {
- pte_t * pte = pte_alloc_kernel(&init_mm, pmd, address);
+ pte_t * pte = pte_alloc_kernel(pmd, address);
if (!pte)
return -ENOMEM;
remap_area_pte(pte, address, end - address, address + phys_addr, flags);
@@ -80,7 +80,6 @@ static int remap_area_pages(unsigned long address, unsigned long phys_addr,
flush_cache_all();
if (address >= end)
BUG();
- spin_lock(&init_mm.page_table_lock);
do {
pmd_t *pmd;
pmd = pmd_alloc(&init_mm, dir, address);
@@ -94,7 +93,6 @@ static int remap_area_pages(unsigned long address, unsigned long phys_addr,
address = (address + PGDIR_SIZE) & PGDIR_MASK;
dir++;
} while (address && (address < end));
- spin_unlock(&init_mm.page_table_lock);
flush_tlb_all();
return 0;
}
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig
index 3e804c736e64..64f5ae0ff96d 100644
--- a/arch/sh/Kconfig
+++ b/arch/sh/Kconfig
@@ -490,16 +490,6 @@ config CPU_SUBTYPE_ST40
depends on CPU_SUBTYPE_ST40STB1 || CPU_SUBTYPE_ST40GX1
default y
-config ARCH_DISCONTIGMEM_ENABLE
- bool
- depends on SH_HP690
- default y
- help
- Say Y to upport efficient handling of discontiguous physical memory,
- for architectures which are either NUMA (Non-Uniform Memory Access)
- or have huge holes in the physical address space for other reasons.
- See <file:Documentation/vm/numa> for more.
-
source "mm/Kconfig"
config ZERO_PAGE_OFFSET
@@ -770,24 +760,6 @@ source "fs/Kconfig.binfmt"
endmenu
-menu "SH initrd options"
- depends on BLK_DEV_INITRD
-
-config EMBEDDED_RAMDISK
- bool "Embed root filesystem ramdisk into the kernel"
-
-config EMBEDDED_RAMDISK_IMAGE
- string "Filename of gziped ramdisk image"
- depends on EMBEDDED_RAMDISK
- default "ramdisk.gz"
- help
- This is the filename of the ramdisk image to be built into the
- kernel. Relative pathnames are relative to arch/sh/ramdisk/.
- The ramdisk image is not part of the kernel distribution; you must
- provide one yourself.
-
-endmenu
-
source "net/Kconfig"
source "drivers/Kconfig"
diff --git a/arch/sh/Makefile b/arch/sh/Makefile
index 4a3049080b41..67192d6b00d8 100644
--- a/arch/sh/Makefile
+++ b/arch/sh/Makefile
@@ -60,14 +60,6 @@ LIBGCC := $(shell $(CC) $(CFLAGS) -print-libgcc-file-name)
core-y += arch/sh/kernel/ arch/sh/mm/
-#
-# ramdisk/initrd support
-# You need a compressed ramdisk image, named
-# CONFIG_EMBEDDED_RAMDISK_IMAGE. Relative pathnames
-# are relative to arch/sh/ramdisk/.
-#
-core-$(CONFIG_EMBEDDED_RAMDISK) += arch/sh/ramdisk/
-
# Boards
machdir-$(CONFIG_SH_SOLUTION_ENGINE) := se/770x
machdir-$(CONFIG_SH_7751_SOLUTION_ENGINE) := se/7751
diff --git a/arch/sh/boards/renesas/rts7751r2d/mach.c b/arch/sh/boards/renesas/rts7751r2d/mach.c
index 1efc18e786d5..610740512d56 100644
--- a/arch/sh/boards/renesas/rts7751r2d/mach.c
+++ b/arch/sh/boards/renesas/rts7751r2d/mach.c
@@ -23,7 +23,7 @@ extern void init_rts7751r2d_IRQ(void);
extern void *rts7751r2d_ioremap(unsigned long, unsigned long);
extern int rts7751r2d_irq_demux(int irq);
-extern void *voyagergx_consistent_alloc(struct device *, size_t, dma_addr_t *, int);
+extern void *voyagergx_consistent_alloc(struct device *, size_t, dma_addr_t *, gfp_t);
extern int voyagergx_consistent_free(struct device *, size_t, void *, dma_addr_t);
/*
diff --git a/arch/sh/boards/superh/microdev/setup.c b/arch/sh/boards/superh/microdev/setup.c
index c18919941ec0..1c1d65fb12df 100644
--- a/arch/sh/boards/superh/microdev/setup.c
+++ b/arch/sh/boards/superh/microdev/setup.c
@@ -13,7 +13,7 @@
#include <linux/config.h>
#include <linux/init.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <linux/ioport.h>
#include <asm/io.h>
#include <asm/mach/irq.h>
diff --git a/arch/sh/cchips/voyagergx/consistent.c b/arch/sh/cchips/voyagergx/consistent.c
index 5b92585a38d2..3d9a02c093a3 100644
--- a/arch/sh/cchips/voyagergx/consistent.c
+++ b/arch/sh/cchips/voyagergx/consistent.c
@@ -31,7 +31,7 @@ static LIST_HEAD(voya_alloc_list);
#define OHCI_SRAM_SIZE 0x10000
void *voyagergx_consistent_alloc(struct device *dev, size_t size,
- dma_addr_t *handle, int flag)
+ dma_addr_t *handle, gfp_t flag)
{
struct list_head *list = &voya_alloc_list;
struct voya_alloc_entry *entry;
diff --git a/arch/sh/drivers/Makefile b/arch/sh/drivers/Makefile
index bd6726cde398..338c3729d270 100644
--- a/arch/sh/drivers/Makefile
+++ b/arch/sh/drivers/Makefile
@@ -2,6 +2,7 @@
# Makefile for the Linux SuperH-specific device drivers.
#
-obj-$(CONFIG_PCI) += pci/
-obj-$(CONFIG_SH_DMA) += dma/
+obj-$(CONFIG_PCI) += pci/
+obj-$(CONFIG_SH_DMA) += dma/
+obj-$(CONFIG_SUPERHYWAY) += superhyway/
diff --git a/arch/sh/drivers/dma/dma-sysfs.c b/arch/sh/drivers/dma/dma-sysfs.c
index 71a6d4e7809f..6e3b58bd8795 100644
--- a/arch/sh/drivers/dma/dma-sysfs.c
+++ b/arch/sh/drivers/dma/dma-sysfs.c
@@ -13,6 +13,7 @@
#include <linux/init.h>
#include <linux/sysdev.h>
#include <linux/module.h>
+#include <linux/string.h>
#include <asm/dma.h>
static struct sysdev_class dma_sysclass = {
diff --git a/arch/sh/drivers/pci/dma-dreamcast.c b/arch/sh/drivers/pci/dma-dreamcast.c
index 83de7ef4e7df..e12418bb1fa5 100644
--- a/arch/sh/drivers/pci/dma-dreamcast.c
+++ b/arch/sh/drivers/pci/dma-dreamcast.c
@@ -33,7 +33,7 @@
static int gapspci_dma_used = 0;
void *dreamcast_consistent_alloc(struct device *dev, size_t size,
- dma_addr_t *dma_handle, int flag)
+ dma_addr_t *dma_handle, gfp_t flag)
{
unsigned long buf;
diff --git a/arch/sh/drivers/superhyway/Makefile b/arch/sh/drivers/superhyway/Makefile
new file mode 100644
index 000000000000..5b8e0c7ca3a5
--- /dev/null
+++ b/arch/sh/drivers/superhyway/Makefile
@@ -0,0 +1,6 @@
+#
+# Makefile for the SuperHyway specific kernel interface routines under Linux.
+#
+
+obj-$(CONFIG_CPU_SUBTYPE_SH4_202) += ops-sh4-202.o
+
diff --git a/arch/sh/drivers/superhyway/ops-sh4-202.c b/arch/sh/drivers/superhyway/ops-sh4-202.c
new file mode 100644
index 000000000000..a55c98a9052b
--- /dev/null
+++ b/arch/sh/drivers/superhyway/ops-sh4-202.c
@@ -0,0 +1,171 @@
+/*
+ * arch/sh/drivers/superhyway/ops-sh4-202.c
+ *
+ * SuperHyway bus support for SH4-202
+ *
+ * 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/superhyway.h>
+#include <linux/string.h>
+#include <asm/addrspace.h>
+#include <asm/io.h>
+
+#define PHYS_EMI_CBLOCK P4SEGADDR(0x1ec00000)
+#define PHYS_EMI_DBLOCK P4SEGADDR(0x08000000)
+#define PHYS_FEMI_CBLOCK P4SEGADDR(0x1f800000)
+#define PHYS_FEMI_DBLOCK P4SEGADDR(0x00000000)
+
+#define PHYS_EPBR_BLOCK P4SEGADDR(0x1de00000)
+#define PHYS_DMAC_BLOCK P4SEGADDR(0x1fa00000)
+#define PHYS_PBR_BLOCK P4SEGADDR(0x1fc00000)
+
+static struct resource emi_resources[] = {
+ [0] = {
+ .start = PHYS_EMI_CBLOCK,
+ .end = PHYS_EMI_CBLOCK + 0x00300000 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = PHYS_EMI_DBLOCK,
+ .end = PHYS_EMI_DBLOCK + 0x08000000 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct superhyway_device emi_device = {
+ .name = "emi",
+ .num_resources = ARRAY_SIZE(emi_resources),
+ .resource = emi_resources,
+};
+
+static struct resource femi_resources[] = {
+ [0] = {
+ .start = PHYS_FEMI_CBLOCK,
+ .end = PHYS_FEMI_CBLOCK + 0x00100000 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = PHYS_FEMI_DBLOCK,
+ .end = PHYS_FEMI_DBLOCK + 0x08000000 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct superhyway_device femi_device = {
+ .name = "femi",
+ .num_resources = ARRAY_SIZE(femi_resources),
+ .resource = femi_resources,
+};
+
+static struct resource epbr_resources[] = {
+ [0] = {
+ .start = P4SEGADDR(0x1e7ffff8),
+ .end = P4SEGADDR(0x1e7ffff8 + (sizeof(u32) * 2) - 1),
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = PHYS_EPBR_BLOCK,
+ .end = PHYS_EPBR_BLOCK + 0x00a00000 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct superhyway_device epbr_device = {
+ .name = "epbr",
+ .num_resources = ARRAY_SIZE(epbr_resources),
+ .resource = epbr_resources,
+};
+
+static struct resource dmac_resource = {
+ .start = PHYS_DMAC_BLOCK,
+ .end = PHYS_DMAC_BLOCK + 0x00100000 - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct superhyway_device dmac_device = {
+ .name = "dmac",
+ .num_resources = 1,
+ .resource = &dmac_resource,
+};
+
+static struct resource pbr_resources[] = {
+ [0] = {
+ .start = P4SEGADDR(0x1ffffff8),
+ .end = P4SEGADDR(0x1ffffff8 + (sizeof(u32) * 2) - 1),
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = PHYS_PBR_BLOCK,
+ .end = PHYS_PBR_BLOCK + 0x00400000 - (sizeof(u32) * 2) - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct superhyway_device pbr_device = {
+ .name = "pbr",
+ .num_resources = ARRAY_SIZE(pbr_resources),
+ .resource = pbr_resources,
+};
+
+static struct superhyway_device *sh4202_devices[] __initdata = {
+ &emi_device, &femi_device, &epbr_device, &dmac_device, &pbr_device,
+};
+
+static int sh4202_read_vcr(unsigned long base, struct superhyway_vcr_info *vcr)
+{
+ u32 vcrh, vcrl;
+ u64 tmp;
+
+ /*
+ * XXX: Even though the SH4-202 Evaluation Device documentation
+ * indicates that VCRL is mapped first with VCRH at a + 0x04
+ * offset, the opposite seems to be true.
+ *
+ * Some modules (PBR and ePBR for instance) also appear to have
+ * VCRL/VCRH flipped in the documentation, but on the SH4-202
+ * itself it appears that these are all consistently mapped with
+ * VCRH preceeding VCRL.
+ *
+ * Do not trust the documentation, for it is evil.
+ */
+ vcrh = ctrl_inl(base);
+ vcrl = ctrl_inl(base + sizeof(u32));
+
+ tmp = ((u64)vcrh << 32) | vcrl;
+ memcpy(vcr, &tmp, sizeof(u64));
+
+ return 0;
+}
+
+static int sh4202_write_vcr(unsigned long base, struct superhyway_vcr_info vcr)
+{
+ u64 tmp = *(u64 *)&vcr;
+
+ ctrl_outl((tmp >> 32) & 0xffffffff, base);
+ ctrl_outl(tmp & 0xffffffff, base + sizeof(u32));
+
+ return 0;
+}
+
+static struct superhyway_ops sh4202_superhyway_ops = {
+ .read_vcr = sh4202_read_vcr,
+ .write_vcr = sh4202_write_vcr,
+};
+
+struct superhyway_bus superhyway_channels[] = {
+ { &sh4202_superhyway_ops, },
+ { 0, },
+};
+
+int __init superhyway_scan_bus(struct superhyway_bus *bus)
+{
+ return superhyway_add_devices(bus, sh4202_devices,
+ ARRAY_SIZE(sh4202_devices));
+}
+
diff --git a/arch/sh/kernel/cpufreq.c b/arch/sh/kernel/cpufreq.c
index e0b384bef55f..47abf6e49dfb 100644
--- a/arch/sh/kernel/cpufreq.c
+++ b/arch/sh/kernel/cpufreq.c
@@ -20,6 +20,7 @@
#include <linux/delay.h>
#include <linux/cpumask.h>
#include <linux/smp.h>
+#include <linux/sched.h> /* set_cpus_allowed() */
#include <asm/processor.h>
#include <asm/watchdog.h>
diff --git a/arch/sh/kernel/process.c b/arch/sh/kernel/process.c
index 6dce9d0b81f8..fd4f240b833d 100644
--- a/arch/sh/kernel/process.c
+++ b/arch/sh/kernel/process.c
@@ -51,28 +51,24 @@ void enable_hlt(void)
EXPORT_SYMBOL(enable_hlt);
-void default_idle(void)
+void cpu_idle(void)
{
/* endless idle loop with no priority at all */
while (1) {
if (hlt_counter) {
- while (1)
- if (need_resched())
- break;
+ while (!need_resched())
+ cpu_relax();
} else {
while (!need_resched())
cpu_sleep();
}
+ preempt_enable_no_resched();
schedule();
+ preempt_disable();
}
}
-void cpu_idle(void)
-{
- default_idle();
-}
-
void machine_restart(char * __unused)
{
/* SR.BL=1 and invoke address error to let CPU reset (manual reset) */
diff --git a/arch/sh/kernel/ptrace.c b/arch/sh/kernel/ptrace.c
index b28919b65682..1a8be06519ec 100644
--- a/arch/sh/kernel/ptrace.c
+++ b/arch/sh/kernel/ptrace.c
@@ -80,48 +80,11 @@ void ptrace_disable(struct task_struct *child)
/* nothing to do.. */
}
-asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request, long addr, long data)
{
- struct task_struct *child;
struct user * dummy = NULL;
int ret;
- lock_kernel();
- ret = -EPERM;
- if (request == PTRACE_TRACEME) {
- /* are we already being traced? */
- if (current->ptrace & PT_PTRACED)
- goto out;
- ret = security_ptrace(current->parent, current);
- if (ret)
- goto out;
- /* set the ptrace bit in the process flags. */
- current->ptrace |= PT_PTRACED;
- ret = 0;
- goto out;
- }
- ret = -ESRCH;
- read_lock(&tasklist_lock);
- child = find_task_by_pid(pid);
- if (child)
- get_task_struct(child);
- read_unlock(&tasklist_lock);
- if (!child)
- goto out;
-
- ret = -EPERM;
- if (pid == 1) /* you may not mess with init */
- goto out_tsk;
-
- if (request == PTRACE_ATTACH) {
- ret = ptrace_attach(child);
- goto out_tsk;
- }
-
- ret = ptrace_check_attach(child, request == PTRACE_KILL);
- if (ret < 0)
- goto out_tsk;
-
switch (request) {
/* when I and D space are separate, these will need to be fixed. */
case PTRACE_PEEKTEXT: /* read word at location addr. */
@@ -289,10 +252,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
ret = ptrace_request(child, request, addr, data);
break;
}
-out_tsk:
- put_task_struct(child);
-out:
- unlock_kernel();
+
return ret;
}
diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c
index 25b9d9ebe858..036050b377cd 100644
--- a/arch/sh/kernel/setup.c
+++ b/arch/sh/kernel/setup.c
@@ -83,9 +83,9 @@ static struct sh_machine_vector* __init get_mv_byname(const char* name);
/* ... */
#define COMMAND_LINE ((char *) (PARAM+0x100))
-#define RAMDISK_IMAGE_START_MASK 0x07FF
+#define RAMDISK_IMAGE_START_MASK 0x07FF
#define RAMDISK_PROMPT_FLAG 0x8000
-#define RAMDISK_LOAD_FLAG 0x4000
+#define RAMDISK_LOAD_FLAG 0x4000
static char command_line[COMMAND_LINE_SIZE] = { 0, };
@@ -284,18 +284,6 @@ void __init setup_arch(char **cmdline_p)
#define PFN_DOWN(x) ((x) >> PAGE_SHIFT)
#define PFN_PHYS(x) ((x) << PAGE_SHIFT)
-#ifdef CONFIG_DISCONTIGMEM
- NODE_DATA(0)->bdata = &discontig_node_bdata[0];
- NODE_DATA(1)->bdata = &discontig_node_bdata[1];
-
- bootmap_size = init_bootmem_node(NODE_DATA(1),
- PFN_UP(__MEMORY_START_2ND),
- PFN_UP(__MEMORY_START_2ND),
- PFN_DOWN(__MEMORY_START_2ND+__MEMORY_SIZE_2ND));
- free_bootmem_node(NODE_DATA(1), __MEMORY_START_2ND, __MEMORY_SIZE_2ND);
- reserve_bootmem_node(NODE_DATA(1), __MEMORY_START_2ND, bootmap_size);
-#endif
-
/*
* Find the highest page frame number we have available
*/
@@ -306,10 +294,10 @@ void __init setup_arch(char **cmdline_p)
*/
max_low_pfn = max_pfn;
- /*
+ /*
* Partially used pages are not usable - thus
* we are rounding upwards:
- */
+ */
start_pfn = PFN_UP(__pa(_end));
/*
@@ -360,12 +348,12 @@ void __init setup_arch(char **cmdline_p)
reserve_bootmem_node(NODE_DATA(0), __MEMORY_START, PAGE_SIZE);
#ifdef CONFIG_BLK_DEV_INITRD
- ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0);
- if (&__rd_start != &__rd_end) {
+ ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0);
+ if (&__rd_start != &__rd_end) {
LOADER_TYPE = 1;
INITRD_START = PHYSADDR((unsigned long)&__rd_start) - __MEMORY_START;
INITRD_SIZE = (unsigned long)&__rd_end - (unsigned long)&__rd_start;
- }
+ }
if (LOADER_TYPE && INITRD_START) {
if (INITRD_START + INITRD_SIZE <= (max_low_pfn << PAGE_SHIFT)) {
diff --git a/arch/sh/kernel/smp.c b/arch/sh/kernel/smp.c
index 5ecefc02896a..59e49b18252c 100644
--- a/arch/sh/kernel/smp.c
+++ b/arch/sh/kernel/smp.c
@@ -112,7 +112,9 @@ int __cpu_up(unsigned int cpu)
int start_secondary(void *unused)
{
- unsigned int cpu = smp_processor_id();
+ unsigned int cpu;
+
+ cpu = smp_processor_id();
atomic_inc(&init_mm.mm_count);
current->active_mm = &init_mm;
@@ -120,6 +122,7 @@ int start_secondary(void *unused)
smp_store_cpu_info(cpu);
__smp_slave_init(cpu);
+ preempt_disable();
per_cpu_trap_init();
atomic_inc(&cpus_booted);
diff --git a/arch/sh/kernel/time.c b/arch/sh/kernel/time.c
index 02ca69918d7c..671b876416bf 100644
--- a/arch/sh/kernel/time.c
+++ b/arch/sh/kernel/time.c
@@ -56,10 +56,6 @@ extern unsigned long wall_jiffies;
#define TICK_SIZE (tick_nsec / 1000)
DEFINE_SPINLOCK(tmu0_lock);
-u64 jiffies_64 = INITIAL_JIFFIES;
-
-EXPORT_SYMBOL(jiffies_64);
-
/* XXX: Can we initialize this in a routine somewhere? Dreamcast doesn't want
* these routines anywhere... */
#ifdef CONFIG_SH_RTC
diff --git a/arch/sh/mm/consistent.c b/arch/sh/mm/consistent.c
index 1f7af0c73cf4..df3a9e452cc5 100644
--- a/arch/sh/mm/consistent.c
+++ b/arch/sh/mm/consistent.c
@@ -11,7 +11,7 @@
#include <linux/dma-mapping.h>
#include <asm/io.h>
-void *consistent_alloc(int gfp, size_t size, dma_addr_t *handle)
+void *consistent_alloc(gfp_t gfp, size_t size, dma_addr_t *handle)
{
struct page *page, *end, *free;
void *ret;
diff --git a/arch/sh/mm/fault.c b/arch/sh/mm/fault.c
index 7abba2161da6..775f86cd3fe8 100644
--- a/arch/sh/mm/fault.c
+++ b/arch/sh/mm/fault.c
@@ -194,10 +194,13 @@ asmlinkage int __do_page_fault(struct pt_regs *regs, unsigned long writeaccess,
unsigned long address)
{
unsigned long addrmax = P4SEG;
- pgd_t *dir;
+ pgd_t *pgd;
pmd_t *pmd;
pte_t *pte;
pte_t entry;
+ struct mm_struct *mm;
+ spinlock_t *ptl;
+ int ret = 1;
#ifdef CONFIG_SH_KGDB
if (kgdb_nofault && kgdb_bus_err_hook)
@@ -208,28 +211,28 @@ asmlinkage int __do_page_fault(struct pt_regs *regs, unsigned long writeaccess,
addrmax = P4SEG_STORE_QUE + 0x04000000;
#endif
- if (address >= P3SEG && address < addrmax)
- dir = pgd_offset_k(address);
- else if (address >= TASK_SIZE)
+ if (address >= P3SEG && address < addrmax) {
+ pgd = pgd_offset_k(address);
+ mm = NULL;
+ } else if (address >= TASK_SIZE)
return 1;
- else if (!current->mm)
+ else if (!(mm = current->mm))
return 1;
else
- dir = pgd_offset(current->mm, address);
+ pgd = pgd_offset(mm, address);
- pmd = pmd_offset(dir, address);
- if (pmd_none(*pmd))
- return 1;
- if (pmd_bad(*pmd)) {
- pmd_ERROR(*pmd);
- pmd_clear(pmd);
+ pmd = pmd_offset(pgd, address);
+ if (pmd_none_or_clear_bad(pmd))
return 1;
- }
- pte = pte_offset_kernel(pmd, address);
+ if (mm)
+ pte = pte_offset_map_lock(mm, pmd, address, &ptl);
+ else
+ pte = pte_offset_kernel(pmd, address);
+
entry = *pte;
if (pte_none(entry) || pte_not_present(entry)
|| (writeaccess && !pte_write(entry)))
- return 1;
+ goto unlock;
if (writeaccess)
entry = pte_mkdirty(entry);
@@ -251,8 +254,11 @@ asmlinkage int __do_page_fault(struct pt_regs *regs, unsigned long writeaccess,
set_pte(pte, entry);
update_mmu_cache(NULL, address, entry);
-
- return 0;
+ ret = 0;
+unlock:
+ if (mm)
+ pte_unmap_unlock(pte, ptl);
+ return ret;
}
void flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
diff --git a/arch/sh/mm/hugetlbpage.c b/arch/sh/mm/hugetlbpage.c
index 95bb1a6c6060..6b7a7688c98e 100644
--- a/arch/sh/mm/hugetlbpage.c
+++ b/arch/sh/mm/hugetlbpage.c
@@ -54,8 +54,6 @@ pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr)
return pte;
}
-#define mk_pte_huge(entry) do { pte_val(entry) |= _PAGE_SZHUGE; } while (0)
-
void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
pte_t *ptep, pte_t entry)
{
diff --git a/arch/sh/mm/init.c b/arch/sh/mm/init.c
index 4e9c854845a4..e342565f75fb 100644
--- a/arch/sh/mm/init.c
+++ b/arch/sh/mm/init.c
@@ -51,11 +51,6 @@ unsigned long mmu_context_cache = NO_CONTEXT;
#define MAX_LOW_PFN (NODE_DATA(0)->bdata->node_low_pfn)
#endif
-#ifdef CONFIG_DISCONTIGMEM
-pg_data_t discontig_page_data[MAX_NUMNODES];
-bootmem_data_t discontig_node_bdata[MAX_NUMNODES];
-#endif
-
void (*copy_page)(void *from, void *to);
void (*clear_page)(void *to);
@@ -216,15 +211,6 @@ void __init paging_init(void)
#endif
NODE_DATA(0)->node_mem_map = NULL;
free_area_init_node(0, NODE_DATA(0), zones_size, __MEMORY_START >> PAGE_SHIFT, 0);
-
-#ifdef CONFIG_DISCONTIGMEM
- /*
- * And for discontig, do some more fixups on the zone sizes..
- */
- zones_size[ZONE_DMA] = __MEMORY_SIZE_2ND >> PAGE_SHIFT;
- zones_size[ZONE_NORMAL] = 0;
- free_area_init_node(1, NODE_DATA(1), zones_size, __MEMORY_START_2ND >> PAGE_SHIFT, 0);
-#endif
}
void __init mem_init(void)
@@ -248,7 +234,7 @@ void __init mem_init(void)
memset(empty_zero_page, 0, PAGE_SIZE);
__flush_wback_region(empty_zero_page, PAGE_SIZE);
- /*
+ /*
* Setup wrappers for copy/clear_page(), these will get overridden
* later in the boot process if a better method is available.
*/
@@ -257,9 +243,6 @@ void __init mem_init(void)
/* this will put all low memory onto the freelists */
totalram_pages += free_all_bootmem_node(NODE_DATA(0));
-#ifdef CONFIG_DISCONTIGMEM
- totalram_pages += free_all_bootmem_node(NODE_DATA(1));
-#endif
reservedpages = 0;
for (tmp = 0; tmp < num_physpages; tmp++)
/*
@@ -286,7 +269,7 @@ void __init mem_init(void)
void free_initmem(void)
{
unsigned long addr;
-
+
addr = (unsigned long)(&__init_begin);
for (; addr < (unsigned long)(&__init_end); addr += PAGE_SIZE) {
ClearPageReserved(virt_to_page(addr));
diff --git a/arch/sh/mm/ioremap.c b/arch/sh/mm/ioremap.c
index 9f490c2742f0..e794e27a72f1 100644
--- a/arch/sh/mm/ioremap.c
+++ b/arch/sh/mm/ioremap.c
@@ -57,7 +57,7 @@ static inline int remap_area_pmd(pmd_t * pmd, unsigned long address,
if (address >= end)
BUG();
do {
- pte_t * pte = pte_alloc_kernel(&init_mm, pmd, address);
+ pte_t * pte = pte_alloc_kernel(pmd, address);
if (!pte)
return -ENOMEM;
remap_area_pte(pte, address, end - address, address + phys_addr, flags);
@@ -79,7 +79,6 @@ int remap_area_pages(unsigned long address, unsigned long phys_addr,
flush_cache_all();
if (address >= end)
BUG();
- spin_lock(&init_mm.page_table_lock);
do {
pmd_t *pmd;
pmd = pmd_alloc(&init_mm, dir, address);
@@ -93,7 +92,6 @@ int remap_area_pages(unsigned long address, unsigned long phys_addr,
address = (address + PGDIR_SIZE) & PGDIR_MASK;
dir++;
} while (address && (address < end));
- spin_unlock(&init_mm.page_table_lock);
flush_tlb_all();
return error;
}
diff --git a/arch/sh/mm/tlb-sh3.c b/arch/sh/mm/tlb-sh3.c
index 7a0d5c10bf20..46b09e26e082 100644
--- a/arch/sh/mm/tlb-sh3.c
+++ b/arch/sh/mm/tlb-sh3.c
@@ -40,12 +40,17 @@ void update_mmu_cache(struct vm_area_struct * vma,
return;
#if defined(CONFIG_SH7705_CACHE_32KB)
- struct page *page;
- page = pte_page(pte);
- if (VALID_PAGE(page) && !test_bit(PG_mapped, &page->flags)) {
- unsigned long phys = pte_val(pte) & PTE_PHYS_MASK;
- __flush_wback_region((void *)P1SEGADDR(phys), PAGE_SIZE);
- __set_bit(PG_mapped, &page->flags);
+ {
+ struct page *page = pte_page(pte);
+ unsigned long pfn = pte_pfn(pte);
+
+ if (pfn_valid(pfn) && !test_bit(PG_mapped, &page->flags)) {
+ unsigned long phys = pte_val(pte) & PTE_PHYS_MASK;
+
+ __flush_wback_region((void *)P1SEGADDR(phys),
+ PAGE_SIZE);
+ __set_bit(PG_mapped, &page->flags);
+ }
}
#endif
@@ -80,7 +85,7 @@ void __flush_tlb_page(unsigned long asid, unsigned long page)
*/
addr = MMU_TLB_ADDRESS_ARRAY | (page & 0x1F000);
data = (page & 0xfffe0000) | asid; /* VALID bit is off */
-
+
if ((cpu_data->flags & CPU_HAS_MMU_PAGE_ASSOC)) {
addr |= MMU_PAGE_ASSOC_BIT;
ways = 1; /* we already know the way .. */
diff --git a/arch/sh/ramdisk/Makefile b/arch/sh/ramdisk/Makefile
deleted file mode 100644
index 99e1c68673cf..000000000000
--- a/arch/sh/ramdisk/Makefile
+++ /dev/null
@@ -1,20 +0,0 @@
-#
-# Makefile for a ramdisk image
-#
-
-obj-y += ramdisk.o
-
-
-O_FORMAT = $(shell $(OBJDUMP) -i | head -n 2 | grep elf32)
-img := $(subst ",,$(CONFIG_EMBEDDED_RAMDISK_IMAGE))
-# add $(src) when $(img) is relative
-img := $(subst $(src)//,/,$(src)/$(img))
-
-quiet_cmd_ramdisk = LD $@
-define cmd_ramdisk
- $(LD) -T $(srctree)/$(src)/ld.script -b binary --oformat $(O_FORMAT) \
- -o $@ $(img)
-endef
-
-$(obj)/ramdisk.o: $(img) $(srctree)/$(src)/ld.script
- $(call cmd,ramdisk)
diff --git a/arch/sh/ramdisk/ld.script b/arch/sh/ramdisk/ld.script
deleted file mode 100644
index 94beee248c04..000000000000
--- a/arch/sh/ramdisk/ld.script
+++ /dev/null
@@ -1,9 +0,0 @@
-OUTPUT_ARCH(sh)
-SECTIONS
-{
- .initrd :
- {
- *(.data)
- }
-}
-
diff --git a/arch/sh64/kernel/process.c b/arch/sh64/kernel/process.c
index efde41c0cd66..b95d04141855 100644
--- a/arch/sh64/kernel/process.c
+++ b/arch/sh64/kernel/process.c
@@ -307,23 +307,19 @@ __setup("hlt", hlt_setup);
static inline void hlt(void)
{
- if (hlt_counter)
- return;
-
__asm__ __volatile__ ("sleep" : : : "memory");
}
/*
* The idle loop on a uniprocessor SH..
*/
-void default_idle(void)
+void cpu_idle(void)
{
/* endless idle loop with no priority at all */
while (1) {
if (hlt_counter) {
- while (1)
- if (need_resched())
- break;
+ while (!need_resched())
+ cpu_relax();
} else {
local_irq_disable();
while (!need_resched()) {
@@ -334,13 +330,11 @@ void default_idle(void)
}
local_irq_enable();
}
+ preempt_enable_no_resched();
schedule();
+ preempt_disable();
}
-}
-void cpu_idle(void)
-{
- default_idle();
}
void machine_restart(char * __unused)
diff --git a/arch/sh64/kernel/ptrace.c b/arch/sh64/kernel/ptrace.c
index fd2000956dae..cd22e9471316 100644
--- a/arch/sh64/kernel/ptrace.c
+++ b/arch/sh64/kernel/ptrace.c
@@ -28,6 +28,7 @@
#include <linux/ptrace.h>
#include <linux/user.h>
#include <linux/signal.h>
+#include <linux/syscalls.h>
#include <asm/io.h>
#include <asm/uaccess.h>
@@ -121,61 +122,11 @@ put_fpu_long(struct task_struct *task, unsigned long addr, unsigned long data)
return 0;
}
-asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
+
+long arch_ptrace(struct task_struct *child, long request, long addr, long data)
{
- struct task_struct *child;
- extern void poke_real_address_q(unsigned long long addr, unsigned long long data);
-#define WPC_DBRMODE 0x0d104008
- static int first_call = 1;
int ret;
- lock_kernel();
-
- if (first_call) {
- /* Set WPC.DBRMODE to 0. This makes all debug events get
- * delivered through RESVEC, i.e. into the handlers in entry.S.
- * (If the kernel was downloaded using a remote gdb, WPC.DBRMODE
- * would normally be left set to 1, which makes debug events get
- * delivered through DBRVEC, i.e. into the remote gdb's
- * handlers. This prevents ptrace getting them, and confuses
- * the remote gdb.) */
- printk("DBRMODE set to 0 to permit native debugging\n");
- poke_real_address_q(WPC_DBRMODE, 0);
- first_call = 0;
- }
-
- ret = -EPERM;
- if (request == PTRACE_TRACEME) {
- /* are we already being traced? */
- if (current->ptrace & PT_PTRACED)
- goto out;
- /* set the ptrace bit in the process flags. */
- current->ptrace |= PT_PTRACED;
- ret = 0;
- goto out;
- }
- ret = -ESRCH;
- read_lock(&tasklist_lock);
- child = find_task_by_pid(pid);
- if (child)
- get_task_struct(child);
- read_unlock(&tasklist_lock);
- if (!child)
- goto out;
-
- ret = -EPERM;
- if (pid == 1) /* you may not mess with init */
- goto out_tsk;
-
- if (request == PTRACE_ATTACH) {
- ret = ptrace_attach(child);
- goto out_tsk;
- }
-
- ret = ptrace_check_attach(child, request == PTRACE_KILL);
- if (ret < 0)
- goto out_tsk;
-
switch (request) {
/* when I and D space are separate, these will need to be fixed. */
case PTRACE_PEEKTEXT: /* read word at location addr. */
@@ -313,13 +264,33 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
ret = ptrace_request(child, request, addr, data);
break;
}
-out_tsk:
- put_task_struct(child);
-out:
- unlock_kernel();
return ret;
}
+asmlinkage int sh64_ptrace(long request, long pid, long addr, long data)
+{
+ extern void poke_real_address_q(unsigned long long addr, unsigned long long data);
+#define WPC_DBRMODE 0x0d104008
+ static int first_call = 1;
+
+ lock_kernel();
+ if (first_call) {
+ /* Set WPC.DBRMODE to 0. This makes all debug events get
+ * delivered through RESVEC, i.e. into the handlers in entry.S.
+ * (If the kernel was downloaded using a remote gdb, WPC.DBRMODE
+ * would normally be left set to 1, which makes debug events get
+ * delivered through DBRVEC, i.e. into the remote gdb's
+ * handlers. This prevents ptrace getting them, and confuses
+ * the remote gdb.) */
+ printk("DBRMODE set to 0 to permit native debugging\n");
+ poke_real_address_q(WPC_DBRMODE, 0);
+ first_call = 0;
+ }
+ unlock_kernel();
+
+ return sys_ptrace(request, pid, addr, data);
+}
+
asmlinkage void syscall_trace(void)
{
struct task_struct *tsk = current;
diff --git a/arch/sh64/kernel/syscalls.S b/arch/sh64/kernel/syscalls.S
index a3d037805f1c..c0079d54c850 100644
--- a/arch/sh64/kernel/syscalls.S
+++ b/arch/sh64/kernel/syscalls.S
@@ -46,7 +46,7 @@ sys_call_table:
.long sys_setuid16
.long sys_getuid16
.long sys_stime /* 25 */
- .long sys_ptrace
+ .long sh64_ptrace
.long sys_alarm
.long sys_fstat
.long sys_pause
diff --git a/arch/sh64/kernel/time.c b/arch/sh64/kernel/time.c
index f4a62a10053c..870fe5327e09 100644
--- a/arch/sh64/kernel/time.c
+++ b/arch/sh64/kernel/time.c
@@ -116,8 +116,6 @@
extern unsigned long wall_jiffies;
-u64 jiffies_64 = INITIAL_JIFFIES;
-
static unsigned long tmu_base, rtc_base;
unsigned long cprc_base;
@@ -253,6 +251,7 @@ int do_settimeofday(struct timespec *tv)
return 0;
}
+EXPORT_SYMBOL(do_settimeofday);
static int set_rtc_time(unsigned long nowtime)
{
diff --git a/arch/sh64/mm/cache.c b/arch/sh64/mm/cache.c
index 3b87e25ea773..c0c1b21350d8 100644
--- a/arch/sh64/mm/cache.c
+++ b/arch/sh64/mm/cache.c
@@ -584,32 +584,36 @@ static void sh64_dcache_purge_phy_page(unsigned long paddr)
}
}
-static void sh64_dcache_purge_user_page(struct mm_struct *mm, unsigned long eaddr)
+static void sh64_dcache_purge_user_pages(struct mm_struct *mm,
+ unsigned long addr, unsigned long end)
{
pgd_t *pgd;
pmd_t *pmd;
pte_t *pte;
pte_t entry;
+ spinlock_t *ptl;
unsigned long paddr;
- /* NOTE : all the callers of this have mm->page_table_lock held, so the
- following page table traversal is safe even on SMP/pre-emptible. */
-
- if (!mm) return; /* No way to find physical address of page */
- pgd = pgd_offset(mm, eaddr);
- if (pgd_bad(*pgd)) return;
-
- pmd = pmd_offset(pgd, eaddr);
- if (pmd_none(*pmd) || pmd_bad(*pmd)) return;
-
- pte = pte_offset_kernel(pmd, eaddr);
- entry = *pte;
- if (pte_none(entry) || !pte_present(entry)) return;
-
- paddr = pte_val(entry) & PAGE_MASK;
-
- sh64_dcache_purge_coloured_phy_page(paddr, eaddr);
-
+ if (!mm)
+ return; /* No way to find physical address of page */
+
+ pgd = pgd_offset(mm, addr);
+ if (pgd_bad(*pgd))
+ return;
+
+ pmd = pmd_offset(pgd, addr);
+ if (pmd_none(*pmd) || pmd_bad(*pmd))
+ return;
+
+ pte = pte_offset_map_lock(mm, pmd, addr, &ptl);
+ do {
+ entry = *pte;
+ if (pte_none(entry) || !pte_present(entry))
+ continue;
+ paddr = pte_val(entry) & PAGE_MASK;
+ sh64_dcache_purge_coloured_phy_page(paddr, addr);
+ } while (pte++, addr += PAGE_SIZE, addr != end);
+ pte_unmap_unlock(pte - 1, ptl);
}
/****************************************************************************/
@@ -668,7 +672,7 @@ static void sh64_dcache_purge_user_range(struct mm_struct *mm,
int n_pages;
n_pages = ((end - start) >> PAGE_SHIFT);
- if (n_pages >= 64) {
+ if (n_pages >= 64 || ((start ^ (end - 1)) & PMD_MASK)) {
#if 1
sh64_dcache_purge_all();
#else
@@ -707,20 +711,10 @@ static void sh64_dcache_purge_user_range(struct mm_struct *mm,
}
#endif
} else {
- /* 'Small' range */
- unsigned long aligned_start;
- unsigned long eaddr;
- unsigned long last_page_start;
-
- aligned_start = start & PAGE_MASK;
- /* 'end' is 1 byte beyond the end of the range */
- last_page_start = (end - 1) & PAGE_MASK;
-
- eaddr = aligned_start;
- while (eaddr <= last_page_start) {
- sh64_dcache_purge_user_page(mm, eaddr);
- eaddr += PAGE_SIZE;
- }
+ /* Small range, covered by a single page table page */
+ start &= PAGE_MASK; /* should already be so */
+ end = PAGE_ALIGN(end); /* should already be so */
+ sh64_dcache_purge_user_pages(mm, start, end);
}
return;
}
@@ -880,9 +874,7 @@ void flush_cache_range(struct vm_area_struct *vma, unsigned long start,
addresses from the user address space specified by mm, after writing
back any dirty data.
- Note(1), 'end' is 1 byte beyond the end of the range to flush.
-
- Note(2), this is called with mm->page_table_lock held.*/
+ Note, 'end' is 1 byte beyond the end of the range to flush. */
sh64_dcache_purge_user_range(mm, start, end);
sh64_icache_inv_user_page_range(mm, start, end);
@@ -898,7 +890,7 @@ void flush_cache_page(struct vm_area_struct *vma, unsigned long eaddr, unsigned
the I-cache must be searched too in case the page in question is
both writable and being executed from (e.g. stack trampolines.)
- Note(1), this is called with mm->page_table_lock held.
+ Note, this is called with pte lock held.
*/
sh64_dcache_purge_phy_page(pfn << PAGE_SHIFT);
diff --git a/arch/sh64/mm/hugetlbpage.c b/arch/sh64/mm/hugetlbpage.c
index dcd9c8a8baf8..ed6a505b3ee2 100644
--- a/arch/sh64/mm/hugetlbpage.c
+++ b/arch/sh64/mm/hugetlbpage.c
@@ -54,41 +54,31 @@ pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr)
return pte;
}
-#define mk_pte_huge(entry) do { pte_val(entry) |= _PAGE_SZHUGE; } while (0)
-
-static void set_huge_pte(struct mm_struct *mm, struct vm_area_struct *vma,
- struct page *page, pte_t * page_table, int write_access)
+void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
+ pte_t *ptep, pte_t entry)
{
- unsigned long i;
- pte_t entry;
-
- add_mm_counter(mm, rss, HPAGE_SIZE / PAGE_SIZE);
-
- if (write_access)
- entry = pte_mkwrite(pte_mkdirty(mk_pte(page,
- vma->vm_page_prot)));
- else
- entry = pte_wrprotect(mk_pte(page, vma->vm_page_prot));
- entry = pte_mkyoung(entry);
- mk_pte_huge(entry);
+ int i;
for (i = 0; i < (1 << HUGETLB_PAGE_ORDER); i++) {
- set_pte(page_table, entry);
- page_table++;
-
+ set_pte_at(mm, addr, ptep, entry);
+ ptep++;
+ addr += PAGE_SIZE;
pte_val(entry) += PAGE_SIZE;
}
}
-pte_t huge_ptep_get_and_clear(pte_t *ptep)
+pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr,
+ pte_t *ptep)
{
pte_t entry;
+ int i;
entry = *ptep;
for (i = 0; i < (1 << HUGETLB_PAGE_ORDER); i++) {
- pte_clear(pte);
- pte++;
+ pte_clear(mm, addr, ptep);
+ addr += PAGE_SIZE;
+ ptep++;
}
return entry;
@@ -106,79 +96,6 @@ int is_aligned_hugepage_range(unsigned long addr, unsigned long len)
return 0;
}
-int copy_hugetlb_page_range(struct mm_struct *dst, struct mm_struct *src,
- struct vm_area_struct *vma)
-{
- pte_t *src_pte, *dst_pte, entry;
- struct page *ptepage;
- unsigned long addr = vma->vm_start;
- unsigned long end = vma->vm_end;
- int i;
-
- while (addr < end) {
- dst_pte = huge_pte_alloc(dst, addr);
- if (!dst_pte)
- goto nomem;
- src_pte = huge_pte_offset(src, addr);
- BUG_ON(!src_pte || pte_none(*src_pte));
- entry = *src_pte;
- ptepage = pte_page(entry);
- get_page(ptepage);
- for (i = 0; i < (1 << HUGETLB_PAGE_ORDER); i++) {
- set_pte(dst_pte, entry);
- pte_val(entry) += PAGE_SIZE;
- dst_pte++;
- }
- add_mm_counter(dst, rss, HPAGE_SIZE / PAGE_SIZE);
- addr += HPAGE_SIZE;
- }
- return 0;
-
-nomem:
- return -ENOMEM;
-}
-
-int follow_hugetlb_page(struct mm_struct *mm, struct vm_area_struct *vma,
- struct page **pages, struct vm_area_struct **vmas,
- unsigned long *position, int *length, int i)
-{
- unsigned long vaddr = *position;
- int remainder = *length;
-
- WARN_ON(!is_vm_hugetlb_page(vma));
-
- while (vaddr < vma->vm_end && remainder) {
- if (pages) {
- pte_t *pte;
- struct page *page;
-
- pte = huge_pte_offset(mm, vaddr);
-
- /* hugetlb should be locked, and hence, prefaulted */
- BUG_ON(!pte || pte_none(*pte));
-
- page = pte_page(*pte);
-
- WARN_ON(!PageCompound(page));
-
- get_page(page);
- pages[i] = page;
- }
-
- if (vmas)
- vmas[i] = vma;
-
- vaddr += PAGE_SIZE;
- --remainder;
- ++i;
- }
-
- *length = remainder;
- *position = vaddr;
-
- return i;
-}
-
struct page *follow_huge_addr(struct mm_struct *mm,
unsigned long address, int write)
{
@@ -195,84 +112,3 @@ struct page *follow_huge_pmd(struct mm_struct *mm, unsigned long address,
{
return NULL;
}
-
-void unmap_hugepage_range(struct vm_area_struct *vma,
- unsigned long start, unsigned long end)
-{
- struct mm_struct *mm = vma->vm_mm;
- unsigned long address;
- pte_t *pte;
- struct page *page;
- int i;
-
- BUG_ON(start & (HPAGE_SIZE - 1));
- BUG_ON(end & (HPAGE_SIZE - 1));
-
- for (address = start; address < end; address += HPAGE_SIZE) {
- pte = huge_pte_offset(mm, address);
- BUG_ON(!pte);
- if (pte_none(*pte))
- continue;
- page = pte_page(*pte);
- put_page(page);
- for (i = 0; i < (1 << HUGETLB_PAGE_ORDER); i++) {
- pte_clear(mm, address+(i*PAGE_SIZE), pte);
- pte++;
- }
- }
- add_mm_counter(mm, rss, -((end - start) >> PAGE_SHIFT));
- flush_tlb_range(vma, start, end);
-}
-
-int hugetlb_prefault(struct address_space *mapping, struct vm_area_struct *vma)
-{
- struct mm_struct *mm = current->mm;
- unsigned long addr;
- int ret = 0;
-
- BUG_ON(vma->vm_start & ~HPAGE_MASK);
- BUG_ON(vma->vm_end & ~HPAGE_MASK);
-
- spin_lock(&mm->page_table_lock);
- for (addr = vma->vm_start; addr < vma->vm_end; addr += HPAGE_SIZE) {
- unsigned long idx;
- pte_t *pte = huge_pte_alloc(mm, addr);
- struct page *page;
-
- if (!pte) {
- ret = -ENOMEM;
- goto out;
- }
- if (!pte_none(*pte))
- continue;
-
- idx = ((addr - vma->vm_start) >> HPAGE_SHIFT)
- + (vma->vm_pgoff >> (HPAGE_SHIFT - PAGE_SHIFT));
- page = find_get_page(mapping, idx);
- if (!page) {
- /* charge the fs quota first */
- if (hugetlb_get_quota(mapping)) {
- ret = -ENOMEM;
- goto out;
- }
- page = alloc_huge_page();
- if (!page) {
- hugetlb_put_quota(mapping);
- ret = -ENOMEM;
- goto out;
- }
- ret = add_to_page_cache(page, mapping, idx, GFP_ATOMIC);
- if (! ret) {
- unlock_page(page);
- } else {
- hugetlb_put_quota(mapping);
- free_huge_page(page);
- goto out;
- }
- }
- set_huge_pte(mm, vma, page, pte, vma->vm_flags & VM_WRITE);
- }
-out:
- spin_unlock(&mm->page_table_lock);
- return ret;
-}
diff --git a/arch/sh64/mm/ioremap.c b/arch/sh64/mm/ioremap.c
index f4003da556bc..fb1866fa2c9d 100644
--- a/arch/sh64/mm/ioremap.c
+++ b/arch/sh64/mm/ioremap.c
@@ -79,7 +79,7 @@ static inline int remap_area_pmd(pmd_t * pmd, unsigned long address, unsigned lo
BUG();
do {
- pte_t * pte = pte_alloc_kernel(&init_mm, pmd, address);
+ pte_t * pte = pte_alloc_kernel(pmd, address);
if (!pte)
return -ENOMEM;
remap_area_pte(pte, address, end - address, address + phys_addr, flags);
@@ -101,7 +101,6 @@ static int remap_area_pages(unsigned long address, unsigned long phys_addr,
flush_cache_all();
if (address >= end)
BUG();
- spin_lock(&init_mm.page_table_lock);
do {
pmd_t *pmd = pmd_alloc(&init_mm, dir, address);
error = -ENOMEM;
@@ -115,7 +114,6 @@ static int remap_area_pages(unsigned long address, unsigned long phys_addr,
address = (address + PGDIR_SIZE) & PGDIR_MASK;
dir++;
} while (address && (address < end));
- spin_unlock(&init_mm.page_table_lock);
flush_tlb_all();
return 0;
}
diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig
index 6537445dac0e..3cfb8be3ff6d 100644
--- a/arch/sparc/Kconfig
+++ b/arch/sparc/Kconfig
@@ -201,6 +201,14 @@ config SUN_OPENPROMFS
Only choose N if you know in advance that you will not need to modify
OpenPROM settings on the running system.
+config SPARC_LED
+ tristate "Sun4m LED driver"
+ help
+ This driver toggles the front-panel LED on sun4m systems
+ in a user-specifyable manner. It's state can be probed
+ by reading /proc/led and it's blinking mode can be changed
+ via writes to /proc/led
+
source "fs/Kconfig.binfmt"
config SUNOS_EMUL
diff --git a/arch/sparc/kernel/Makefile b/arch/sparc/kernel/Makefile
index 3d22ba2af01c..1b83e21841b5 100644
--- a/arch/sparc/kernel/Makefile
+++ b/arch/sparc/kernel/Makefile
@@ -21,6 +21,7 @@ obj-$(CONFIG_SUN_AUXIO) += auxio.o
obj-$(CONFIG_PCI) += ebus.o
obj-$(CONFIG_SUN_PM) += apc.o pmc.o
obj-$(CONFIG_MODULES) += module.o sparc_ksyms.o
+obj-$(CONFIG_SPARC_LED) += led.o
ifdef CONFIG_SUNOS_EMUL
obj-y += sys_sunos.o sunos_ioctl.o
diff --git a/arch/sparc/kernel/cpu.c b/arch/sparc/kernel/cpu.c
index 6a4ebc62193e..d7bfc61d2879 100644
--- a/arch/sparc/kernel/cpu.c
+++ b/arch/sparc/kernel/cpu.c
@@ -75,7 +75,7 @@ struct cpu_fp_info linux_sparc_fpu[] = {
{ 9, 3, "Fujitsu or Weitek on-chip FPU"},
};
-#define NSPARCFPU (sizeof(linux_sparc_fpu)/sizeof(struct cpu_fp_info))
+#define NSPARCFPU ARRAY_SIZE(linux_sparc_fpu)
struct cpu_iu_info linux_sparc_chips[] = {
/* Sun4/100, 4/200, SLC */
@@ -120,7 +120,7 @@ struct cpu_iu_info linux_sparc_chips[] = {
{ 0xf, 0, "UNKNOWN CPU-VENDOR/TYPE"},
};
-#define NSPARCCHIPS (sizeof(linux_sparc_chips)/sizeof(struct cpu_iu_info))
+#define NSPARCCHIPS ARRAY_SIZE(linux_sparc_chips)
char *sparc_cpu_type;
char *sparc_fpu_type;
diff --git a/arch/sparc/kernel/led.c b/arch/sparc/kernel/led.c
new file mode 100644
index 000000000000..2a3afca453c9
--- /dev/null
+++ b/arch/sparc/kernel/led.c
@@ -0,0 +1,139 @@
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/proc_fs.h>
+#include <linux/string.h>
+
+#include <asm/auxio.h>
+
+#define LED_MAX_LENGTH 8 /* maximum chars written to proc file */
+
+static inline void led_toggle(void)
+{
+ unsigned char val = get_auxio();
+ unsigned char on, off;
+
+ if (val & AUXIO_LED) {
+ on = 0;
+ off = AUXIO_LED;
+ } else {
+ on = AUXIO_LED;
+ off = 0;
+ }
+
+ set_auxio(on, off);
+}
+
+static struct timer_list led_blink_timer;
+
+static void led_blink(unsigned long timeout)
+{
+ led_toggle();
+
+ /* reschedule */
+ if (!timeout) { /* blink according to load */
+ led_blink_timer.expires = jiffies +
+ ((1 + (avenrun[0] >> FSHIFT)) * HZ);
+ led_blink_timer.data = 0;
+ } else { /* blink at user specified interval */
+ led_blink_timer.expires = jiffies + (timeout * HZ);
+ led_blink_timer.data = timeout;
+ }
+ add_timer(&led_blink_timer);
+}
+
+static int led_read_proc(char *buf, char **start, off_t offset, int count,
+ int *eof, void *data)
+{
+ int len = 0;
+
+ if (get_auxio() & AUXIO_LED)
+ len = sprintf(buf, "on\n");
+ else
+ len = sprintf(buf, "off\n");
+
+ return len;
+}
+
+static int led_write_proc(struct file *file, const char *buffer,
+ unsigned long count, void *data)
+{
+ char *buf = NULL;
+
+ if (count > LED_MAX_LENGTH)
+ count = LED_MAX_LENGTH;
+
+ buf = kmalloc(sizeof(char) * (count + 1), GFP_KERNEL);
+ if (!buf)
+ return -ENOMEM;
+
+ if (copy_from_user(buf, buffer, count)) {
+ kfree(buf);
+ return -EFAULT;
+ }
+
+ buf[count] = '\0';
+
+ /* work around \n when echo'ing into proc */
+ if (buf[count - 1] == '\n')
+ buf[count - 1] = '\0';
+
+ /* before we change anything we want to stop any running timers,
+ * otherwise calls such as on will have no persistent effect
+ */
+ del_timer_sync(&led_blink_timer);
+
+ if (!strcmp(buf, "on")) {
+ auxio_set_led(AUXIO_LED_ON);
+ } else if (!strcmp(buf, "toggle")) {
+ led_toggle();
+ } else if ((*buf > '0') && (*buf <= '9')) {
+ led_blink(simple_strtoul(buf, NULL, 10));
+ } else if (!strcmp(buf, "load")) {
+ led_blink(0);
+ } else {
+ auxio_set_led(AUXIO_LED_OFF);
+ }
+
+ kfree(buf);
+
+ return count;
+}
+
+static struct proc_dir_entry *led;
+
+#define LED_VERSION "0.1"
+
+static int __init led_init(void)
+{
+ init_timer(&led_blink_timer);
+ led_blink_timer.function = led_blink;
+
+ led = create_proc_entry("led", 0, NULL);
+ if (!led)
+ return -ENOMEM;
+
+ led->read_proc = led_read_proc; /* reader function */
+ led->write_proc = led_write_proc; /* writer function */
+ led->owner = THIS_MODULE;
+
+ printk(KERN_INFO
+ "led: version %s, Lars Kotthoff <metalhead@metalhead.ws>\n",
+ LED_VERSION);
+
+ return 0;
+}
+
+static void __exit led_exit(void)
+{
+ remove_proc_entry("led", NULL);
+ del_timer_sync(&led_blink_timer);
+}
+
+module_init(led_init);
+module_exit(led_exit);
+
+MODULE_AUTHOR("Lars Kotthoff <metalhead@metalhead.ws>");
+MODULE_DESCRIPTION("Provides control of the front LED on SPARC systems.");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(LED_VERSION);
diff --git a/arch/sparc/kernel/pcic.c b/arch/sparc/kernel/pcic.c
index 36a40697b8d6..cccfc12802ed 100644
--- a/arch/sparc/kernel/pcic.c
+++ b/arch/sparc/kernel/pcic.c
@@ -143,7 +143,7 @@ static struct pcic_ca2irq pcic_i_jk[] = {
* as several PROMs may be installed on the same physical board.
*/
#define SN2L_INIT(name, map) \
- { name, map, sizeof(map)/sizeof(struct pcic_ca2irq) }
+ { name, map, ARRAY_SIZE(map) }
static struct pcic_sn2list pcic_known_sysnames[] = {
SN2L_INIT("SUNW,JavaEngine1", pcic_i_je1a), /* JE1, PROM 2.32 */
@@ -497,8 +497,8 @@ static void pcic_map_pci_device(struct linux_pcic *pcic,
* CheerIO makes a similar conversion.
* See ebus.c for details.
*
- * Note that check_region()/request_region()
- * work for these devices.
+ * Note that request_region()
+ * works for these devices.
*
* XXX Neat trick, but it's a *bad* idea
* to shit into regions like that.
diff --git a/arch/sparc/kernel/process.c b/arch/sparc/kernel/process.c
index 29e72b57d4fd..ea8647411462 100644
--- a/arch/sparc/kernel/process.c
+++ b/arch/sparc/kernel/process.c
@@ -67,13 +67,6 @@ extern void fpsave(unsigned long *, unsigned long *, void *, unsigned long *);
struct task_struct *last_task_used_math = NULL;
struct thread_info *current_set[NR_CPUS];
-/*
- * default_idle is new in 2.5. XXX Review, currently stolen from sparc64.
- */
-void default_idle(void)
-{
-}
-
#ifndef CONFIG_SMP
#define SUN4C_FAULT_HIGH 100
@@ -92,12 +85,11 @@ void cpu_idle(void)
static unsigned long fps;
unsigned long now;
unsigned long faults;
- unsigned long flags;
extern unsigned long sun4c_kernel_faults;
extern void sun4c_grow_kernel_ring(void);
- local_irq_save(flags);
+ local_irq_disable();
now = jiffies;
count -= (now - last_jiffies);
last_jiffies = now;
@@ -113,14 +105,19 @@ void cpu_idle(void)
sun4c_grow_kernel_ring();
}
}
- local_irq_restore(flags);
+ local_irq_enable();
}
- while((!need_resched()) && pm_idle) {
- (*pm_idle)();
+ if (pm_idle) {
+ while (!need_resched())
+ (*pm_idle)();
+ } else {
+ while (!need_resched())
+ cpu_relax();
}
-
+ preempt_enable_no_resched();
schedule();
+ preempt_disable();
check_pgt_cache();
}
}
@@ -130,13 +127,15 @@ void cpu_idle(void)
/* This is being executed in task 0 'user space'. */
void cpu_idle(void)
{
+ set_thread_flag(TIF_POLLING_NRFLAG);
/* endless idle loop with no priority at all */
while(1) {
- if(need_resched()) {
- schedule();
- check_pgt_cache();
- }
- barrier(); /* or else gcc optimizes... */
+ while (!need_resched())
+ cpu_relax();
+ preempt_enable_no_resched();
+ schedule();
+ preempt_disable();
+ check_pgt_cache();
}
}
diff --git a/arch/sparc/kernel/sunos_ioctl.c b/arch/sparc/kernel/sunos_ioctl.c
index df1c0b31a930..a6ba3d26222c 100644
--- a/arch/sparc/kernel/sunos_ioctl.c
+++ b/arch/sparc/kernel/sunos_ioctl.c
@@ -23,7 +23,6 @@
#include <linux/smp_lock.h>
#include <linux/syscalls.h>
#include <linux/file.h>
-#include <asm/kbio.h>
#if 0
extern char sunkbd_type;
diff --git a/arch/sparc/kernel/time.c b/arch/sparc/kernel/time.c
index 279a62627c10..24814d58f9e1 100644
--- a/arch/sparc/kernel/time.c
+++ b/arch/sparc/kernel/time.c
@@ -45,10 +45,6 @@
extern unsigned long wall_jiffies;
-u64 jiffies_64 = INITIAL_JIFFIES;
-
-EXPORT_SYMBOL(jiffies_64);
-
DEFINE_SPINLOCK(rtc_lock);
enum sparc_clock_type sp_clock_typ;
DEFINE_SPINLOCK(mostek_lock);
diff --git a/arch/sparc/mm/fault.c b/arch/sparc/mm/fault.c
index 2bbd53f3cafb..9eeed3347df3 100644
--- a/arch/sparc/mm/fault.c
+++ b/arch/sparc/mm/fault.c
@@ -33,8 +33,6 @@
#include <asm/kdebug.h>
#include <asm/uaccess.h>
-#define ELEMENTS(arr) (sizeof (arr)/sizeof (arr[0]))
-
extern int prom_node_root;
/* At boot time we determine these two values necessary for setting
diff --git a/arch/sparc/mm/generic.c b/arch/sparc/mm/generic.c
index 20ccb957fb77..9604893ffdbd 100644
--- a/arch/sparc/mm/generic.c
+++ b/arch/sparc/mm/generic.c
@@ -73,14 +73,16 @@ int io_remap_pfn_range(struct vm_area_struct *vma, unsigned long from,
int space = GET_IOSPACE(pfn);
unsigned long offset = GET_PFN(pfn) << PAGE_SHIFT;
+ /* See comment in mm/memory.c remap_pfn_range */
+ vma->vm_flags |= VM_IO | VM_RESERVED;
+
prot = __pgprot(pg_iobits);
offset -= from;
dir = pgd_offset(mm, from);
flush_cache_range(vma, beg, end);
- spin_lock(&mm->page_table_lock);
while (from < end) {
- pmd_t *pmd = pmd_alloc(current->mm, dir, from);
+ pmd_t *pmd = pmd_alloc(mm, dir, from);
error = -ENOMEM;
if (!pmd)
break;
@@ -90,7 +92,6 @@ int io_remap_pfn_range(struct vm_area_struct *vma, unsigned long from,
from = (from + PGDIR_SIZE) & PGDIR_MASK;
dir++;
}
- spin_unlock(&mm->page_table_lock);
flush_tlb_range(vma, beg, end);
return error;
diff --git a/arch/sparc64/Kconfig b/arch/sparc64/Kconfig
index 1e9d8638a28a..3fded69b1922 100644
--- a/arch/sparc64/Kconfig
+++ b/arch/sparc64/Kconfig
@@ -377,8 +377,21 @@ source "drivers/fc4/Kconfig"
source "fs/Kconfig"
+menu "Instrumentation Support"
+ depends on EXPERIMENTAL
+
source "arch/sparc64/oprofile/Kconfig"
+config KPROBES
+ bool "Kprobes (EXPERIMENTAL)"
+ help
+ Kprobes allows you to trap at almost any kernel address and
+ execute a callback function. register_kprobe() establishes
+ a probepoint and specifies the callback. Kprobes is useful
+ for kernel debugging, non-intrusive instrumentation and testing.
+ If in doubt, say "N".
+endmenu
+
source "arch/sparc64/Kconfig.debug"
source "security/Kconfig"
diff --git a/arch/sparc64/Kconfig.debug b/arch/sparc64/Kconfig.debug
index fa06ea04837b..3e31be494e54 100644
--- a/arch/sparc64/Kconfig.debug
+++ b/arch/sparc64/Kconfig.debug
@@ -11,16 +11,6 @@ config DEBUG_STACK_USAGE
This option will slow down process creation somewhat.
-config KPROBES
- bool "Kprobes"
- depends on DEBUG_KERNEL
- help
- Kprobes allows you to trap at almost any kernel address and
- execute a callback function. register_kprobe() establishes
- a probepoint and specifies the callback. Kprobes is useful
- for kernel debugging, non-intrusive instrumentation and testing.
- If in doubt, say "N".
-
config DEBUG_DCFLUSH
bool "D-cache flush debugging"
depends on DEBUG_KERNEL
diff --git a/arch/sparc64/kernel/binfmt_aout32.c b/arch/sparc64/kernel/binfmt_aout32.c
index b2854ef221d0..edf52d06b280 100644
--- a/arch/sparc64/kernel/binfmt_aout32.c
+++ b/arch/sparc64/kernel/binfmt_aout32.c
@@ -241,7 +241,6 @@ static int load_aout32_binary(struct linux_binprm * bprm, struct pt_regs * regs)
current->mm->brk = ex.a_bss +
(current->mm->start_brk = N_BSSADDR(ex));
- set_mm_counter(current->mm, rss, 0);
current->mm->mmap = NULL;
compute_creds(bprm);
current->flags &= ~PF_FORKNOEXEC;
diff --git a/arch/sparc64/kernel/cpu.c b/arch/sparc64/kernel/cpu.c
index 77ef5df4e5a7..00eed88ef2e8 100644
--- a/arch/sparc64/kernel/cpu.c
+++ b/arch/sparc64/kernel/cpu.c
@@ -43,7 +43,7 @@ struct cpu_fp_info linux_sparc_fpu[] = {
{ 0x3e, 0x22, 0, "UltraSparc IIIi+ integrated FPU"},
};
-#define NSPARCFPU (sizeof(linux_sparc_fpu)/sizeof(struct cpu_fp_info))
+#define NSPARCFPU ARRAY_SIZE(linux_sparc_fpu)
struct cpu_iu_info linux_sparc_chips[] = {
{ 0x17, 0x10, "TI UltraSparc I (SpitFire)"},
@@ -59,7 +59,7 @@ struct cpu_iu_info linux_sparc_chips[] = {
{ 0x3e, 0x22, "TI UltraSparc IIIi+ (Serrano)"},
};
-#define NSPARCCHIPS (sizeof(linux_sparc_chips)/sizeof(struct cpu_iu_info))
+#define NSPARCCHIPS ARRAY_SIZE(linux_sparc_chips)
char *sparc_cpu_type = "cpu-oops";
char *sparc_fpu_type = "fpu-oops";
diff --git a/arch/sparc64/kernel/ioctl32.c b/arch/sparc64/kernel/ioctl32.c
index 43fc3173d480..e62214354bb5 100644
--- a/arch/sparc64/kernel/ioctl32.c
+++ b/arch/sparc64/kernel/ioctl32.c
@@ -11,33 +11,14 @@
#define INCLUDES
#include "compat_ioctl.c"
-#include <linux/ncp_fs.h>
#include <linux/syscalls.h>
#include <asm/fbio.h>
-#include <asm/kbio.h>
-#include <asm/vuid_event.h>
-#include <asm/envctrl.h>
-#include <asm/display7seg.h>
-#include <asm/openpromio.h>
-#include <asm/audioio.h>
-#include <asm/watchdog.h>
/* Use this to get at 32-bit user passed pointers.
* See sys_sparc32.c for description about it.
*/
#define A(__x) compat_ptr(__x)
-static __inline__ void *alloc_user_space(long len)
-{
- struct pt_regs *regs = current_thread_info()->kregs;
- unsigned long usp = regs->u_regs[UREG_I6];
-
- if (!(test_thread_flag(TIF_32BIT)))
- usp += STACK_BIAS;
-
- return (void *) (usp - len);
-}
-
#define CODE
#include "compat_ioctl.c"
@@ -111,361 +92,8 @@ static int fbiogscursor(unsigned int fd, unsigned int cmd, unsigned long arg)
return sys_ioctl (fd, FBIOSCURSOR, (unsigned long)p);
}
-#if defined(CONFIG_DRM) || defined(CONFIG_DRM_MODULE)
-/* This really belongs in include/linux/drm.h -DaveM */
-#include "../../../drivers/char/drm/drm.h"
-
-typedef struct drm32_version {
- int version_major; /* Major version */
- int version_minor; /* Minor version */
- int version_patchlevel;/* Patch level */
- int name_len; /* Length of name buffer */
- u32 name; /* Name of driver */
- int date_len; /* Length of date buffer */
- u32 date; /* User-space buffer to hold date */
- int desc_len; /* Length of desc buffer */
- u32 desc; /* User-space buffer to hold desc */
-} drm32_version_t;
-#define DRM32_IOCTL_VERSION DRM_IOWR(0x00, drm32_version_t)
-
-static int drm32_version(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- drm32_version_t __user *uversion = (drm32_version_t __user *)arg;
- drm_version_t __user *p = compat_alloc_user_space(sizeof(*p));
- compat_uptr_t addr;
- int n;
- int ret;
-
- if (clear_user(p, 3 * sizeof(int)) ||
- get_user(n, &uversion->name_len) ||
- put_user(n, &p->name_len) ||
- get_user(addr, &uversion->name) ||
- put_user(compat_ptr(addr), &p->name) ||
- get_user(n, &uversion->date_len) ||
- put_user(n, &p->date_len) ||
- get_user(addr, &uversion->date) ||
- put_user(compat_ptr(addr), &p->date) ||
- get_user(n, &uversion->desc_len) ||
- put_user(n, &p->desc_len) ||
- get_user(addr, &uversion->desc) ||
- put_user(compat_ptr(addr), &p->desc))
- return -EFAULT;
-
- ret = sys_ioctl(fd, DRM_IOCTL_VERSION, (unsigned long)p);
- if (ret)
- return ret;
-
- if (copy_in_user(uversion, p, 3 * sizeof(int)) ||
- get_user(n, &p->name_len) ||
- put_user(n, &uversion->name_len) ||
- get_user(n, &p->date_len) ||
- put_user(n, &uversion->date_len) ||
- get_user(n, &p->desc_len) ||
- put_user(n, &uversion->desc_len))
- return -EFAULT;
-
- return 0;
-}
-
-typedef struct drm32_unique {
- int unique_len; /* Length of unique */
- u32 unique; /* Unique name for driver instantiation */
-} drm32_unique_t;
-#define DRM32_IOCTL_GET_UNIQUE DRM_IOWR(0x01, drm32_unique_t)
-#define DRM32_IOCTL_SET_UNIQUE DRM_IOW( 0x10, drm32_unique_t)
-
-static int drm32_getsetunique(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- drm32_unique_t __user *uarg = (drm32_unique_t __user *)arg;
- drm_unique_t __user *p = compat_alloc_user_space(sizeof(*p));
- compat_uptr_t addr;
- int n;
- int ret;
-
- if (get_user(n, &uarg->unique_len) ||
- put_user(n, &p->unique_len) ||
- get_user(addr, &uarg->unique) ||
- put_user(compat_ptr(addr), &p->unique))
- return -EFAULT;
-
- if (cmd == DRM32_IOCTL_GET_UNIQUE)
- ret = sys_ioctl (fd, DRM_IOCTL_GET_UNIQUE, (unsigned long)p);
- else
- ret = sys_ioctl (fd, DRM_IOCTL_SET_UNIQUE, (unsigned long)p);
-
- if (ret)
- return ret;
-
- if (get_user(n, &p->unique_len) || put_user(n, &uarg->unique_len))
- return -EFAULT;
-
- return 0;
-}
-
-typedef struct drm32_map {
- u32 offset; /* Requested physical address (0 for SAREA)*/
- u32 size; /* Requested physical size (bytes) */
- drm_map_type_t type; /* Type of memory to map */
- drm_map_flags_t flags; /* Flags */
- u32 handle; /* User-space: "Handle" to pass to mmap */
- /* Kernel-space: kernel-virtual address */
- int mtrr; /* MTRR slot used */
- /* Private data */
-} drm32_map_t;
-#define DRM32_IOCTL_ADD_MAP DRM_IOWR(0x15, drm32_map_t)
-
-static int drm32_addmap(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- drm32_map_t __user *uarg = (drm32_map_t __user *) arg;
- drm_map_t karg;
- mm_segment_t old_fs;
- u32 tmp;
- int ret;
-
- ret = get_user(karg.offset, &uarg->offset);
- ret |= get_user(karg.size, &uarg->size);
- ret |= get_user(karg.type, &uarg->type);
- ret |= get_user(karg.flags, &uarg->flags);
- ret |= get_user(tmp, &uarg->handle);
- ret |= get_user(karg.mtrr, &uarg->mtrr);
- if (ret)
- return -EFAULT;
-
- karg.handle = (void *) (unsigned long) tmp;
-
- old_fs = get_fs();
- set_fs(KERNEL_DS);
- ret = sys_ioctl(fd, DRM_IOCTL_ADD_MAP, (unsigned long) &karg);
- set_fs(old_fs);
-
- if (!ret) {
- ret = put_user(karg.offset, &uarg->offset);
- ret |= put_user(karg.size, &uarg->size);
- ret |= put_user(karg.type, &uarg->type);
- ret |= put_user(karg.flags, &uarg->flags);
- tmp = (u32) (long)karg.handle;
- ret |= put_user(tmp, &uarg->handle);
- ret |= put_user(karg.mtrr, &uarg->mtrr);
- if (ret)
- ret = -EFAULT;
- }
-
- return ret;
-}
-
-typedef struct drm32_buf_info {
- int count; /* Entries in list */
- u32 list; /* (drm_buf_desc_t *) */
-} drm32_buf_info_t;
-#define DRM32_IOCTL_INFO_BUFS DRM_IOWR(0x18, drm32_buf_info_t)
-
-static int drm32_info_bufs(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- drm32_buf_info_t __user *uarg = (drm32_buf_info_t __user *)arg;
- drm_buf_info_t __user *p = compat_alloc_user_space(sizeof(*p));
- compat_uptr_t addr;
- int n;
- int ret;
-
- if (get_user(n, &uarg->count) || put_user(n, &p->count) ||
- get_user(addr, &uarg->list) || put_user(compat_ptr(addr), &p->list))
- return -EFAULT;
-
- ret = sys_ioctl(fd, DRM_IOCTL_INFO_BUFS, (unsigned long)p);
- if (ret)
- return ret;
-
- if (get_user(n, &p->count) || put_user(n, &uarg->count))
- return -EFAULT;
-
- return 0;
-}
-
-typedef struct drm32_buf_free {
- int count;
- u32 list; /* (int *) */
-} drm32_buf_free_t;
-#define DRM32_IOCTL_FREE_BUFS DRM_IOW( 0x1a, drm32_buf_free_t)
-
-static int drm32_free_bufs(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- drm32_buf_free_t __user *uarg = (drm32_buf_free_t __user *)arg;
- drm_buf_free_t __user *p = compat_alloc_user_space(sizeof(*p));
- compat_uptr_t addr;
- int n;
-
- if (get_user(n, &uarg->count) || put_user(n, &p->count) ||
- get_user(addr, &uarg->list) || put_user(compat_ptr(addr), &p->list))
- return -EFAULT;
-
- return sys_ioctl(fd, DRM_IOCTL_FREE_BUFS, (unsigned long)p);
-}
-
-typedef struct drm32_buf_pub {
- int idx; /* Index into master buflist */
- int total; /* Buffer size */
- int used; /* Amount of buffer in use (for DMA) */
- u32 address; /* Address of buffer (void *) */
-} drm32_buf_pub_t;
-
-typedef struct drm32_buf_map {
- int count; /* Length of buflist */
- u32 virtual; /* Mmaped area in user-virtual (void *) */
- u32 list; /* Buffer information (drm_buf_pub_t *) */
-} drm32_buf_map_t;
-#define DRM32_IOCTL_MAP_BUFS DRM_IOWR(0x19, drm32_buf_map_t)
-
-static int drm32_map_bufs(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- drm32_buf_map_t __user *uarg = (drm32_buf_map_t __user *)arg;
- drm32_buf_pub_t __user *ulist;
- drm_buf_map_t __user *arg64;
- drm_buf_pub_t __user *list;
- int orig_count, ret, i;
- int n;
- compat_uptr_t addr;
-
- if (get_user(orig_count, &uarg->count))
- return -EFAULT;
-
- arg64 = compat_alloc_user_space(sizeof(drm_buf_map_t) +
- (size_t)orig_count * sizeof(drm_buf_pub_t));
- list = (void __user *)(arg64 + 1);
-
- if (put_user(orig_count, &arg64->count) ||
- put_user(list, &arg64->list) ||
- get_user(addr, &uarg->virtual) ||
- put_user(compat_ptr(addr), &arg64->virtual) ||
- get_user(addr, &uarg->list))
- return -EFAULT;
-
- ulist = compat_ptr(addr);
-
- for (i = 0; i < orig_count; i++) {
- if (get_user(n, &ulist[i].idx) ||
- put_user(n, &list[i].idx) ||
- get_user(n, &ulist[i].total) ||
- put_user(n, &list[i].total) ||
- get_user(n, &ulist[i].used) ||
- put_user(n, &list[i].used) ||
- get_user(addr, &ulist[i].address) ||
- put_user(compat_ptr(addr), &list[i].address))
- return -EFAULT;
- }
-
- ret = sys_ioctl(fd, DRM_IOCTL_MAP_BUFS, (unsigned long) arg64);
- if (ret)
- return ret;
-
- for (i = 0; i < orig_count; i++) {
- void __user *p;
- if (get_user(n, &list[i].idx) ||
- put_user(n, &ulist[i].idx) ||
- get_user(n, &list[i].total) ||
- put_user(n, &ulist[i].total) ||
- get_user(n, &list[i].used) ||
- put_user(n, &ulist[i].used) ||
- get_user(p, &list[i].address) ||
- put_user((unsigned long)p, &ulist[i].address))
- return -EFAULT;
- }
-
- if (get_user(n, &arg64->count) || put_user(n, &uarg->count))
- return -EFAULT;
-
- return 0;
-}
-
-typedef struct drm32_dma {
- /* Indices here refer to the offset into
- buflist in drm_buf_get_t. */
- int context; /* Context handle */
- int send_count; /* Number of buffers to send */
- u32 send_indices; /* List of handles to buffers (int *) */
- u32 send_sizes; /* Lengths of data to send (int *) */
- drm_dma_flags_t flags; /* Flags */
- int request_count; /* Number of buffers requested */
- int request_size; /* Desired size for buffers */
- u32 request_indices; /* Buffer information (int *) */
- u32 request_sizes; /* (int *) */
- int granted_count; /* Number of buffers granted */
-} drm32_dma_t;
-#define DRM32_IOCTL_DMA DRM_IOWR(0x29, drm32_dma_t)
-
-/* RED PEN The DRM layer blindly dereferences the send/request
- * index/size arrays even though they are userland
- * pointers. -DaveM
- */
-static int drm32_dma(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- drm32_dma_t __user *uarg = (drm32_dma_t __user *) arg;
- drm_dma_t __user *p = compat_alloc_user_space(sizeof(*p));
- compat_uptr_t addr;
- int ret;
-
- if (copy_in_user(p, uarg, 2 * sizeof(int)) ||
- get_user(addr, &uarg->send_indices) ||
- put_user(compat_ptr(addr), &p->send_indices) ||
- get_user(addr, &uarg->send_sizes) ||
- put_user(compat_ptr(addr), &p->send_sizes) ||
- copy_in_user(&p->flags, &uarg->flags, sizeof(drm_dma_flags_t)) ||
- copy_in_user(&p->request_count, &uarg->request_count, sizeof(int))||
- copy_in_user(&p->request_size, &uarg->request_size, sizeof(int)) ||
- get_user(addr, &uarg->request_indices) ||
- put_user(compat_ptr(addr), &p->request_indices) ||
- get_user(addr, &uarg->request_sizes) ||
- put_user(compat_ptr(addr), &p->request_sizes) ||
- copy_in_user(&p->granted_count, &uarg->granted_count, sizeof(int)))
- return -EFAULT;
-
- ret = sys_ioctl(fd, DRM_IOCTL_DMA, (unsigned long)p);
- if (ret)
- return ret;
-
- if (copy_in_user(uarg, p, 2 * sizeof(int)) ||
- copy_in_user(&uarg->flags, &p->flags, sizeof(drm_dma_flags_t)) ||
- copy_in_user(&uarg->request_count, &p->request_count, sizeof(int))||
- copy_in_user(&uarg->request_size, &p->request_size, sizeof(int)) ||
- copy_in_user(&uarg->granted_count, &p->granted_count, sizeof(int)))
- return -EFAULT;
-
- return 0;
-}
-
-typedef struct drm32_ctx_res {
- int count;
- u32 contexts; /* (drm_ctx_t *) */
-} drm32_ctx_res_t;
-#define DRM32_IOCTL_RES_CTX DRM_IOWR(0x26, drm32_ctx_res_t)
-
-static int drm32_res_ctx(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- drm32_ctx_res_t __user *uarg = (drm32_ctx_res_t __user *) arg;
- drm_ctx_res_t __user *p = compat_alloc_user_space(sizeof(*p));
- compat_uptr_t addr;
- int ret;
-
- if (copy_in_user(p, uarg, sizeof(int)) ||
- get_user(addr, &uarg->contexts) ||
- put_user(compat_ptr(addr), &p->contexts))
- return -EFAULT;
-
- ret = sys_ioctl(fd, DRM_IOCTL_RES_CTX, (unsigned long)p);
- if (ret)
- return ret;
-
- if (copy_in_user(uarg, p, sizeof(int)))
- return -EFAULT;
-
- return 0;
-}
-
-#endif
-
-typedef int (* ioctl32_handler_t)(unsigned int, unsigned int, unsigned long, struct file *);
-
#define COMPATIBLE_IOCTL(cmd) HANDLE_IOCTL((cmd),sys_ioctl)
-#define HANDLE_IOCTL(cmd,handler) { (cmd), (ioctl32_handler_t)(handler), NULL },
+#define HANDLE_IOCTL(cmd,handler) { (cmd), (ioctl_trans_handler_t)(handler), NULL },
#define IOCTL_TABLE_START \
struct ioctl_trans ioctl_start[] = {
#define IOCTL_TABLE_END \
@@ -475,9 +103,6 @@ IOCTL_TABLE_START
#include <linux/compat_ioctl.h>
#define DECLARES
#include "compat_ioctl.c"
-COMPATIBLE_IOCTL(TIOCSTART)
-COMPATIBLE_IOCTL(TIOCSTOP)
-COMPATIBLE_IOCTL(TIOCSLTC)
COMPATIBLE_IOCTL(FBIOGTYPE)
COMPATIBLE_IOCTL(FBIOSATTR)
COMPATIBLE_IOCTL(FBIOGATTR)
@@ -488,103 +113,12 @@ COMPATIBLE_IOCTL(FBIOSCURPOS)
COMPATIBLE_IOCTL(FBIOGCURPOS)
COMPATIBLE_IOCTL(FBIOGCURMAX)
/* Little k */
-COMPATIBLE_IOCTL(KIOCTYPE)
-COMPATIBLE_IOCTL(KIOCLAYOUT)
-COMPATIBLE_IOCTL(KIOCGTRANS)
-COMPATIBLE_IOCTL(KIOCTRANS)
-COMPATIBLE_IOCTL(KIOCCMD)
-COMPATIBLE_IOCTL(KIOCSDIRECT)
-COMPATIBLE_IOCTL(KIOCSLED)
-COMPATIBLE_IOCTL(KIOCGLED)
-COMPATIBLE_IOCTL(KIOCSRATE)
-COMPATIBLE_IOCTL(KIOCGRATE)
-COMPATIBLE_IOCTL(VUIDSFORMAT)
-COMPATIBLE_IOCTL(VUIDGFORMAT)
/* Little v, the video4linux ioctls */
-COMPATIBLE_IOCTL(_IOR('p', 20, int[7])) /* RTCGET */
-COMPATIBLE_IOCTL(_IOW('p', 21, int[7])) /* RTCSET */
-COMPATIBLE_IOCTL(ENVCTRL_RD_WARNING_TEMPERATURE)
-COMPATIBLE_IOCTL(ENVCTRL_RD_SHUTDOWN_TEMPERATURE)
-COMPATIBLE_IOCTL(ENVCTRL_RD_CPU_TEMPERATURE)
-COMPATIBLE_IOCTL(ENVCTRL_RD_FAN_STATUS)
-COMPATIBLE_IOCTL(ENVCTRL_RD_VOLTAGE_STATUS)
-COMPATIBLE_IOCTL(ENVCTRL_RD_SCSI_TEMPERATURE)
-COMPATIBLE_IOCTL(ENVCTRL_RD_ETHERNET_TEMPERATURE)
-COMPATIBLE_IOCTL(ENVCTRL_RD_MTHRBD_TEMPERATURE)
-COMPATIBLE_IOCTL(ENVCTRL_RD_CPU_VOLTAGE)
-COMPATIBLE_IOCTL(ENVCTRL_RD_GLOBALADDRESS)
-/* COMPATIBLE_IOCTL(D7SIOCRD) same value as ENVCTRL_RD_VOLTAGE_STATUS */
-COMPATIBLE_IOCTL(D7SIOCWR)
-COMPATIBLE_IOCTL(D7SIOCTM)
-/* OPENPROMIO, SunOS/Solaris only, the NetBSD one's have
- * embedded pointers in the arg which we'd need to clean up...
- */
-COMPATIBLE_IOCTL(OPROMGETOPT)
-COMPATIBLE_IOCTL(OPROMSETOPT)
-COMPATIBLE_IOCTL(OPROMNXTOPT)
-COMPATIBLE_IOCTL(OPROMSETOPT2)
-COMPATIBLE_IOCTL(OPROMNEXT)
-COMPATIBLE_IOCTL(OPROMCHILD)
-COMPATIBLE_IOCTL(OPROMGETPROP)
-COMPATIBLE_IOCTL(OPROMNXTPROP)
-COMPATIBLE_IOCTL(OPROMU2P)
-COMPATIBLE_IOCTL(OPROMGETCONS)
-COMPATIBLE_IOCTL(OPROMGETFBNAME)
-COMPATIBLE_IOCTL(OPROMGETBOOTARGS)
-COMPATIBLE_IOCTL(OPROMSETCUR)
-COMPATIBLE_IOCTL(OPROMPCI2NODE)
-COMPATIBLE_IOCTL(OPROMPATH2NODE)
-/* Big L */
-COMPATIBLE_IOCTL(LOOP_SET_STATUS64)
-COMPATIBLE_IOCTL(LOOP_GET_STATUS64)
-/* Big A */
-COMPATIBLE_IOCTL(AUDIO_GETINFO)
-COMPATIBLE_IOCTL(AUDIO_SETINFO)
-COMPATIBLE_IOCTL(AUDIO_DRAIN)
-COMPATIBLE_IOCTL(AUDIO_GETDEV)
-COMPATIBLE_IOCTL(AUDIO_GETDEV_SUNOS)
-COMPATIBLE_IOCTL(AUDIO_FLUSH)
-COMPATIBLE_IOCTL(AUTOFS_IOC_EXPIRE_MULTI)
-#if defined(CONFIG_DRM) || defined(CONFIG_DRM_MODULE)
-COMPATIBLE_IOCTL(DRM_IOCTL_GET_MAGIC)
-COMPATIBLE_IOCTL(DRM_IOCTL_IRQ_BUSID)
-COMPATIBLE_IOCTL(DRM_IOCTL_AUTH_MAGIC)
-COMPATIBLE_IOCTL(DRM_IOCTL_BLOCK)
-COMPATIBLE_IOCTL(DRM_IOCTL_UNBLOCK)
-COMPATIBLE_IOCTL(DRM_IOCTL_CONTROL)
-COMPATIBLE_IOCTL(DRM_IOCTL_ADD_BUFS)
-COMPATIBLE_IOCTL(DRM_IOCTL_MARK_BUFS)
-COMPATIBLE_IOCTL(DRM_IOCTL_ADD_CTX)
-COMPATIBLE_IOCTL(DRM_IOCTL_RM_CTX)
-COMPATIBLE_IOCTL(DRM_IOCTL_MOD_CTX)
-COMPATIBLE_IOCTL(DRM_IOCTL_GET_CTX)
-COMPATIBLE_IOCTL(DRM_IOCTL_SWITCH_CTX)
-COMPATIBLE_IOCTL(DRM_IOCTL_NEW_CTX)
-COMPATIBLE_IOCTL(DRM_IOCTL_ADD_DRAW)
-COMPATIBLE_IOCTL(DRM_IOCTL_RM_DRAW)
-COMPATIBLE_IOCTL(DRM_IOCTL_LOCK)
-COMPATIBLE_IOCTL(DRM_IOCTL_UNLOCK)
-COMPATIBLE_IOCTL(DRM_IOCTL_FINISH)
-#endif /* DRM */
-COMPATIBLE_IOCTL(WIOCSTART)
-COMPATIBLE_IOCTL(WIOCSTOP)
-COMPATIBLE_IOCTL(WIOCGSTAT)
/* And these ioctls need translation */
/* Note SIOCRTMSG is no longer, so this is safe and * the user would have seen just an -EINVAL anyways. */
HANDLE_IOCTL(FBIOPUTCMAP32, fbiogetputcmap)
HANDLE_IOCTL(FBIOGETCMAP32, fbiogetputcmap)
HANDLE_IOCTL(FBIOSCURSOR32, fbiogscursor)
-#if defined(CONFIG_DRM) || defined(CONFIG_DRM_MODULE)
-HANDLE_IOCTL(DRM32_IOCTL_VERSION, drm32_version)
-HANDLE_IOCTL(DRM32_IOCTL_GET_UNIQUE, drm32_getsetunique)
-HANDLE_IOCTL(DRM32_IOCTL_SET_UNIQUE, drm32_getsetunique)
-HANDLE_IOCTL(DRM32_IOCTL_ADD_MAP, drm32_addmap)
-HANDLE_IOCTL(DRM32_IOCTL_INFO_BUFS, drm32_info_bufs)
-HANDLE_IOCTL(DRM32_IOCTL_FREE_BUFS, drm32_free_bufs)
-HANDLE_IOCTL(DRM32_IOCTL_MAP_BUFS, drm32_map_bufs)
-HANDLE_IOCTL(DRM32_IOCTL_DMA, drm32_dma)
-HANDLE_IOCTL(DRM32_IOCTL_RES_CTX, drm32_res_ctx)
-#endif /* DRM */
#if 0
HANDLE_IOCTL(RTC32_IRQP_READ, do_rtc_ioctl)
HANDLE_IOCTL(RTC32_IRQP_SET, do_rtc_ioctl)
diff --git a/arch/sparc64/kernel/kprobes.c b/arch/sparc64/kernel/kprobes.c
index 0d66d07c8c6e..96bd09b098f4 100644
--- a/arch/sparc64/kernel/kprobes.c
+++ b/arch/sparc64/kernel/kprobes.c
@@ -38,6 +38,9 @@
* - Mark that we are no longer actively in a kprobe.
*/
+DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
+DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
+
int __kprobes arch_prepare_kprobe(struct kprobe *p)
{
return 0;
@@ -66,46 +69,39 @@ void __kprobes arch_remove_kprobe(struct kprobe *p)
{
}
-static struct kprobe *current_kprobe;
-static unsigned long current_kprobe_orig_tnpc;
-static unsigned long current_kprobe_orig_tstate_pil;
-static unsigned int kprobe_status;
-static struct kprobe *kprobe_prev;
-static unsigned long kprobe_orig_tnpc_prev;
-static unsigned long kprobe_orig_tstate_pil_prev;
-static unsigned int kprobe_status_prev;
-
-static inline void save_previous_kprobe(void)
+static inline void save_previous_kprobe(struct kprobe_ctlblk *kcb)
{
- kprobe_status_prev = kprobe_status;
- kprobe_orig_tnpc_prev = current_kprobe_orig_tnpc;
- kprobe_orig_tstate_pil_prev = current_kprobe_orig_tstate_pil;
- kprobe_prev = current_kprobe;
+ kcb->prev_kprobe.kp = kprobe_running();
+ kcb->prev_kprobe.status = kcb->kprobe_status;
+ kcb->prev_kprobe.orig_tnpc = kcb->kprobe_orig_tnpc;
+ kcb->prev_kprobe.orig_tstate_pil = kcb->kprobe_orig_tstate_pil;
}
-static inline void restore_previous_kprobe(void)
+static inline void restore_previous_kprobe(struct kprobe_ctlblk *kcb)
{
- kprobe_status = kprobe_status_prev;
- current_kprobe_orig_tnpc = kprobe_orig_tnpc_prev;
- current_kprobe_orig_tstate_pil = kprobe_orig_tstate_pil_prev;
- current_kprobe = kprobe_prev;
+ __get_cpu_var(current_kprobe) = kcb->prev_kprobe.kp;
+ kcb->kprobe_status = kcb->prev_kprobe.status;
+ kcb->kprobe_orig_tnpc = kcb->prev_kprobe.orig_tnpc;
+ kcb->kprobe_orig_tstate_pil = kcb->prev_kprobe.orig_tstate_pil;
}
-static inline void set_current_kprobe(struct kprobe *p, struct pt_regs *regs)
+static inline void set_current_kprobe(struct kprobe *p, struct pt_regs *regs,
+ struct kprobe_ctlblk *kcb)
{
- current_kprobe_orig_tnpc = regs->tnpc;
- current_kprobe_orig_tstate_pil = (regs->tstate & TSTATE_PIL);
- current_kprobe = p;
+ __get_cpu_var(current_kprobe) = p;
+ kcb->kprobe_orig_tnpc = regs->tnpc;
+ kcb->kprobe_orig_tstate_pil = (regs->tstate & TSTATE_PIL);
}
-static inline void prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
+static inline void prepare_singlestep(struct kprobe *p, struct pt_regs *regs,
+ struct kprobe_ctlblk *kcb)
{
regs->tstate |= TSTATE_PIL;
/*single step inline, if it a breakpoint instruction*/
if (p->opcode == BREAKPOINT_INSTRUCTION) {
regs->tpc = (unsigned long) p->addr;
- regs->tnpc = current_kprobe_orig_tnpc;
+ regs->tnpc = kcb->kprobe_orig_tnpc;
} else {
regs->tpc = (unsigned long) &p->ainsn.insn[0];
regs->tnpc = (unsigned long) &p->ainsn.insn[1];
@@ -117,19 +113,21 @@ static int __kprobes kprobe_handler(struct pt_regs *regs)
struct kprobe *p;
void *addr = (void *) regs->tpc;
int ret = 0;
+ struct kprobe_ctlblk *kcb;
+ /*
+ * We don't want to be preempted for the entire
+ * duration of kprobe processing
+ */
preempt_disable();
+ kcb = get_kprobe_ctlblk();
if (kprobe_running()) {
- /* We *are* holding lock here, so this is safe.
- * Disarm the probe we just hit, and ignore it.
- */
p = get_kprobe(addr);
if (p) {
- if (kprobe_status == KPROBE_HIT_SS) {
+ if (kcb->kprobe_status == KPROBE_HIT_SS) {
regs->tstate = ((regs->tstate & ~TSTATE_PIL) |
- current_kprobe_orig_tstate_pil);
- unlock_kprobes();
+ kcb->kprobe_orig_tstate_pil);
goto no_kprobe;
}
/* We have reentered the kprobe_handler(), since
@@ -138,25 +136,22 @@ static int __kprobes kprobe_handler(struct pt_regs *regs)
* just single step on the instruction of the new probe
* without calling any user handlers.
*/
- save_previous_kprobe();
- set_current_kprobe(p, regs);
+ save_previous_kprobe(kcb);
+ set_current_kprobe(p, regs, kcb);
p->nmissed++;
- kprobe_status = KPROBE_REENTER;
- prepare_singlestep(p, regs);
+ kcb->kprobe_status = KPROBE_REENTER;
+ prepare_singlestep(p, regs, kcb);
return 1;
} else {
- p = current_kprobe;
+ p = __get_cpu_var(current_kprobe);
if (p->break_handler && p->break_handler(p, regs))
goto ss_probe;
}
- /* If it's not ours, can't be delete race, (we hold lock). */
goto no_kprobe;
}
- lock_kprobes();
p = get_kprobe(addr);
if (!p) {
- unlock_kprobes();
if (*(u32 *)addr != BREAKPOINT_INSTRUCTION) {
/*
* The breakpoint instruction was removed right
@@ -171,14 +166,14 @@ static int __kprobes kprobe_handler(struct pt_regs *regs)
goto no_kprobe;
}
- set_current_kprobe(p, regs);
- kprobe_status = KPROBE_HIT_ACTIVE;
+ set_current_kprobe(p, regs, kcb);
+ kcb->kprobe_status = KPROBE_HIT_ACTIVE;
if (p->pre_handler && p->pre_handler(p, regs))
return 1;
ss_probe:
- prepare_singlestep(p, regs);
- kprobe_status = KPROBE_HIT_SS;
+ prepare_singlestep(p, regs, kcb);
+ kcb->kprobe_status = KPROBE_HIT_SS;
return 1;
no_kprobe:
@@ -260,11 +255,12 @@ static void __kprobes retpc_fixup(struct pt_regs *regs, u32 insn,
* This function prepares to return from the post-single-step
* breakpoint trap.
*/
-static void __kprobes resume_execution(struct kprobe *p, struct pt_regs *regs)
+static void __kprobes resume_execution(struct kprobe *p,
+ struct pt_regs *regs, struct kprobe_ctlblk *kcb)
{
u32 insn = p->ainsn.insn[0];
- regs->tpc = current_kprobe_orig_tnpc;
+ regs->tpc = kcb->kprobe_orig_tnpc;
regs->tnpc = relbranch_fixup(insn,
(unsigned long) p->addr,
(unsigned long) &p->ainsn.insn[0],
@@ -272,44 +268,48 @@ static void __kprobes resume_execution(struct kprobe *p, struct pt_regs *regs)
retpc_fixup(regs, insn, (unsigned long) p->addr);
regs->tstate = ((regs->tstate & ~TSTATE_PIL) |
- current_kprobe_orig_tstate_pil);
+ kcb->kprobe_orig_tstate_pil);
}
static inline int post_kprobe_handler(struct pt_regs *regs)
{
- if (!kprobe_running())
+ struct kprobe *cur = kprobe_running();
+ struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
+
+ if (!cur)
return 0;
- if ((kprobe_status != KPROBE_REENTER) && current_kprobe->post_handler) {
- kprobe_status = KPROBE_HIT_SSDONE;
- current_kprobe->post_handler(current_kprobe, regs, 0);
+ if ((kcb->kprobe_status != KPROBE_REENTER) && cur->post_handler) {
+ kcb->kprobe_status = KPROBE_HIT_SSDONE;
+ cur->post_handler(cur, regs, 0);
}
- resume_execution(current_kprobe, regs);
+ resume_execution(cur, regs, kcb);
/*Restore back the original saved kprobes variables and continue. */
- if (kprobe_status == KPROBE_REENTER) {
- restore_previous_kprobe();
+ if (kcb->kprobe_status == KPROBE_REENTER) {
+ restore_previous_kprobe(kcb);
goto out;
}
- unlock_kprobes();
+ reset_current_kprobe();
out:
preempt_enable_no_resched();
return 1;
}
-/* Interrupts disabled, kprobe_lock held. */
static inline int kprobe_fault_handler(struct pt_regs *regs, int trapnr)
{
- if (current_kprobe->fault_handler
- && current_kprobe->fault_handler(current_kprobe, regs, trapnr))
+ struct kprobe *cur = kprobe_running();
+ struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
+
+ if (cur->fault_handler && cur->fault_handler(cur, regs, trapnr))
return 1;
- if (kprobe_status & KPROBE_HIT_SS) {
- resume_execution(current_kprobe, regs);
+ if (kcb->kprobe_status & KPROBE_HIT_SS) {
+ resume_execution(cur, regs, kcb);
- unlock_kprobes();
+ reset_current_kprobe();
preempt_enable_no_resched();
}
return 0;
@@ -322,29 +322,30 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
unsigned long val, void *data)
{
struct die_args *args = (struct die_args *)data;
+ int ret = NOTIFY_DONE;
+
switch (val) {
case DIE_DEBUG:
if (kprobe_handler(args->regs))
- return NOTIFY_STOP;
+ ret = NOTIFY_STOP;
break;
case DIE_DEBUG_2:
if (post_kprobe_handler(args->regs))
- return NOTIFY_STOP;
+ ret = NOTIFY_STOP;
break;
case DIE_GPF:
- if (kprobe_running() &&
- kprobe_fault_handler(args->regs, args->trapnr))
- return NOTIFY_STOP;
- break;
case DIE_PAGE_FAULT:
+ /* kprobe_running() needs smp_processor_id() */
+ preempt_disable();
if (kprobe_running() &&
kprobe_fault_handler(args->regs, args->trapnr))
- return NOTIFY_STOP;
+ ret = NOTIFY_STOP;
+ preempt_enable();
break;
default:
break;
}
- return NOTIFY_DONE;
+ return ret;
}
asmlinkage void __kprobes kprobe_trap(unsigned long trap_level,
@@ -368,24 +369,21 @@ asmlinkage void __kprobes kprobe_trap(unsigned long trap_level,
}
/* Jprobes support. */
-static struct pt_regs jprobe_saved_regs;
-static struct pt_regs *jprobe_saved_regs_location;
-static struct sparc_stackf jprobe_saved_stack;
-
int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
{
struct jprobe *jp = container_of(p, struct jprobe, kp);
+ struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
- jprobe_saved_regs_location = regs;
- memcpy(&jprobe_saved_regs, regs, sizeof(*regs));
+ kcb->jprobe_saved_regs_location = regs;
+ memcpy(&(kcb->jprobe_saved_regs), regs, sizeof(*regs));
/* Save a whole stack frame, this gets arguments
* pushed onto the stack after using up all the
* arg registers.
*/
- memcpy(&jprobe_saved_stack,
+ memcpy(&(kcb->jprobe_saved_stack),
(char *) (regs->u_regs[UREG_FP] + STACK_BIAS),
- sizeof(jprobe_saved_stack));
+ sizeof(kcb->jprobe_saved_stack));
regs->tpc = (unsigned long) jp->entry;
regs->tnpc = ((unsigned long) jp->entry) + 0x4UL;
@@ -396,7 +394,6 @@ int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
void __kprobes jprobe_return(void)
{
- preempt_enable_no_resched();
__asm__ __volatile__(
".globl jprobe_return_trap_instruction\n"
"jprobe_return_trap_instruction:\n\t"
@@ -410,14 +407,15 @@ extern void __show_regs(struct pt_regs * regs);
int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
{
u32 *addr = (u32 *) regs->tpc;
+ struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
if (addr == (u32 *) jprobe_return_trap_instruction) {
- if (jprobe_saved_regs_location != regs) {
+ if (kcb->jprobe_saved_regs_location != regs) {
printk("JPROBE: Current regs (%p) does not match "
"saved regs (%p).\n",
- regs, jprobe_saved_regs_location);
+ regs, kcb->jprobe_saved_regs_location);
printk("JPROBE: Saved registers\n");
- __show_regs(jprobe_saved_regs_location);
+ __show_regs(kcb->jprobe_saved_regs_location);
printk("JPROBE: Current registers\n");
__show_regs(regs);
BUG();
@@ -426,12 +424,13 @@ int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
* first so that UREG_FP is the original one for
* the stack frame restore.
*/
- memcpy(regs, &jprobe_saved_regs, sizeof(*regs));
+ memcpy(regs, &(kcb->jprobe_saved_regs), sizeof(*regs));
memcpy((char *) (regs->u_regs[UREG_FP] + STACK_BIAS),
- &jprobe_saved_stack,
- sizeof(jprobe_saved_stack));
+ &(kcb->jprobe_saved_stack),
+ sizeof(kcb->jprobe_saved_stack));
+ preempt_enable_no_resched();
return 1;
}
return 0;
diff --git a/arch/sparc64/kernel/process.c b/arch/sparc64/kernel/process.c
index 7d10b0397091..02f9dec1d459 100644
--- a/arch/sparc64/kernel/process.c
+++ b/arch/sparc64/kernel/process.c
@@ -74,7 +74,9 @@ void cpu_idle(void)
while (!need_resched())
barrier();
+ preempt_enable_no_resched();
schedule();
+ preempt_disable();
check_pgt_cache();
}
}
@@ -83,21 +85,31 @@ void cpu_idle(void)
/*
* the idle loop on a UltraMultiPenguin...
+ *
+ * TIF_POLLING_NRFLAG is set because we do not sleep the cpu
+ * inside of the idler task, so an interrupt is not needed
+ * to get a clean fast response.
+ *
+ * XXX Reverify this assumption... -DaveM
+ *
+ * Addendum: We do want it to do something for the signal
+ * delivery case, we detect that by just seeing
+ * if we are trying to send this to an idler or not.
*/
-#define idle_me_harder() (cpu_data(smp_processor_id()).idle_volume += 1)
-#define unidle_me() (cpu_data(smp_processor_id()).idle_volume = 0)
void cpu_idle(void)
{
+ cpuinfo_sparc *cpuinfo = &local_cpu_data();
set_thread_flag(TIF_POLLING_NRFLAG);
+
while(1) {
if (need_resched()) {
- unidle_me();
- clear_thread_flag(TIF_POLLING_NRFLAG);
+ cpuinfo->idle_volume = 0;
+ preempt_enable_no_resched();
schedule();
- set_thread_flag(TIF_POLLING_NRFLAG);
+ preempt_disable();
check_pgt_cache();
}
- idle_me_harder();
+ cpuinfo->idle_volume++;
/* The store ordering is so that IRQ handlers on
* other cpus see our increasing idleness for the buddy
diff --git a/arch/sparc64/kernel/sbus.c b/arch/sparc64/kernel/sbus.c
index e09ddf927655..96b825055668 100644
--- a/arch/sparc64/kernel/sbus.c
+++ b/arch/sparc64/kernel/sbus.c
@@ -790,7 +790,7 @@ static unsigned long sysio_irq_offsets[] = {
#undef bogon
-#define NUM_SYSIO_OFFSETS (sizeof(sysio_irq_offsets) / sizeof(sysio_irq_offsets[0]))
+#define NUM_SYSIO_OFFSETS ARRAY_SIZE(sysio_irq_offsets)
/* Convert Interrupt Mapping register pointer to associated
* Interrupt Clear register pointer, SYSIO specific version.
diff --git a/arch/sparc64/kernel/setup.c b/arch/sparc64/kernel/setup.c
index c1f34237cdf2..bf1849dd9c49 100644
--- a/arch/sparc64/kernel/setup.c
+++ b/arch/sparc64/kernel/setup.c
@@ -154,6 +154,7 @@ int prom_callback(long *args)
pud_t *pudp;
pmd_t *pmdp;
pte_t *ptep;
+ pte_t pte;
for_each_process(p) {
mm = p->mm;
@@ -178,8 +179,9 @@ int prom_callback(long *args)
* being called from inside OBP.
*/
ptep = pte_offset_map(pmdp, va);
- if (pte_present(*ptep)) {
- tte = pte_val(*ptep);
+ pte = *ptep;
+ if (pte_present(pte)) {
+ tte = pte_val(pte);
res = PROM_TRUE;
}
pte_unmap(ptep);
@@ -218,6 +220,7 @@ int prom_callback(long *args)
pud_t *pudp;
pmd_t *pmdp;
pte_t *ptep;
+ pte_t pte;
int error;
if ((va >= LOW_OBP_ADDRESS) && (va < HI_OBP_ADDRESS)) {
@@ -240,8 +243,9 @@ int prom_callback(long *args)
* being called from inside OBP.
*/
ptep = pte_offset_kernel(pmdp, va);
- if (pte_present(*ptep)) {
- tte = pte_val(*ptep);
+ pte = *ptep;
+ if (pte_present(pte)) {
+ tte = pte_val(pte);
res = PROM_TRUE;
}
goto done;
diff --git a/arch/sparc64/kernel/signal32.c b/arch/sparc64/kernel/signal32.c
index aecccd0df1d1..009a86e5ded4 100644
--- a/arch/sparc64/kernel/signal32.c
+++ b/arch/sparc64/kernel/signal32.c
@@ -863,6 +863,7 @@ static void new_setup_frame32(struct k_sigaction *ka, struct pt_regs *regs,
pud_t *pudp = pud_offset(pgdp, address);
pmd_t *pmdp = pmd_offset(pudp, address);
pte_t *ptep;
+ pte_t pte;
regs->u_regs[UREG_I7] = (unsigned long) (&(sf->insns[0]) - 2);
@@ -873,9 +874,10 @@ static void new_setup_frame32(struct k_sigaction *ka, struct pt_regs *regs,
preempt_disable();
ptep = pte_offset_map(pmdp, address);
- if (pte_present(*ptep)) {
+ pte = *ptep;
+ if (pte_present(pte)) {
unsigned long page = (unsigned long)
- page_address(pte_page(*ptep));
+ page_address(pte_page(pte));
wmb();
__asm__ __volatile__("flush %0 + %1"
diff --git a/arch/sparc64/kernel/smp.c b/arch/sparc64/kernel/smp.c
index b137fd63f5e1..797a65493fb8 100644
--- a/arch/sparc64/kernel/smp.c
+++ b/arch/sparc64/kernel/smp.c
@@ -168,6 +168,9 @@ void __init smp_callin(void)
rmb();
cpu_set(cpuid, cpu_online_map);
+
+ /* idle thread is expected to have preempt disabled */
+ preempt_disable();
}
void cpu_panic(void)
@@ -839,43 +842,29 @@ void smp_flush_tlb_all(void)
* questionable (in theory the big win for threads is the massive sharing of
* address space state across processors).
*/
+
+/* This currently is only used by the hugetlb arch pre-fault
+ * hook on UltraSPARC-III+ and later when changing the pagesize
+ * bits of the context register for an address space.
+ */
void smp_flush_tlb_mm(struct mm_struct *mm)
{
- /*
- * This code is called from two places, dup_mmap and exit_mmap. In the
- * former case, we really need a flush. In the later case, the callers
- * are single threaded exec_mmap (really need a flush), multithreaded
- * exec_mmap case (do not need to flush, since the caller gets a new
- * context via activate_mm), and all other callers of mmput() whence
- * the flush can be optimized since the associated threads are dead and
- * the mm is being torn down (__exit_mm and other mmput callers) or the
- * owning thread is dissociating itself from the mm. The
- * (atomic_read(&mm->mm_users) == 0) check ensures real work is done
- * for single thread exec and dup_mmap cases. An alternate check might
- * have been (current->mm != mm).
- * Kanoj Sarcar
- */
- if (atomic_read(&mm->mm_users) == 0)
- return;
-
- {
- u32 ctx = CTX_HWBITS(mm->context);
- int cpu = get_cpu();
+ u32 ctx = CTX_HWBITS(mm->context);
+ int cpu = get_cpu();
- if (atomic_read(&mm->mm_users) == 1) {
- mm->cpu_vm_mask = cpumask_of_cpu(cpu);
- goto local_flush_and_out;
- }
+ if (atomic_read(&mm->mm_users) == 1) {
+ mm->cpu_vm_mask = cpumask_of_cpu(cpu);
+ goto local_flush_and_out;
+ }
- smp_cross_call_masked(&xcall_flush_tlb_mm,
- ctx, 0, 0,
- mm->cpu_vm_mask);
+ smp_cross_call_masked(&xcall_flush_tlb_mm,
+ ctx, 0, 0,
+ mm->cpu_vm_mask);
- local_flush_and_out:
- __flush_tlb_mm(ctx, SECONDARY_CONTEXT);
+local_flush_and_out:
+ __flush_tlb_mm(ctx, SECONDARY_CONTEXT);
- put_cpu();
- }
+ put_cpu();
}
void smp_flush_tlb_pending(struct mm_struct *mm, unsigned long nr, unsigned long *vaddrs)
@@ -883,34 +872,13 @@ void smp_flush_tlb_pending(struct mm_struct *mm, unsigned long nr, unsigned long
u32 ctx = CTX_HWBITS(mm->context);
int cpu = get_cpu();
- if (mm == current->active_mm && atomic_read(&mm->mm_users) == 1) {
+ if (mm == current->active_mm && atomic_read(&mm->mm_users) == 1)
mm->cpu_vm_mask = cpumask_of_cpu(cpu);
- goto local_flush_and_out;
- } else {
- /* This optimization is not valid. Normally
- * we will be holding the page_table_lock, but
- * there is an exception which is copy_page_range()
- * when forking. The lock is held during the individual
- * page table updates in the parent, but not at the
- * top level, which is where we are invoked.
- */
- if (0) {
- cpumask_t this_cpu_mask = cpumask_of_cpu(cpu);
-
- /* By virtue of running under the mm->page_table_lock,
- * and mmu_context.h:switch_mm doing the same, the
- * following operation is safe.
- */
- if (cpus_equal(mm->cpu_vm_mask, this_cpu_mask))
- goto local_flush_and_out;
- }
- }
-
- smp_cross_call_masked(&xcall_flush_tlb_pending,
- ctx, nr, (unsigned long) vaddrs,
- mm->cpu_vm_mask);
+ else
+ smp_cross_call_masked(&xcall_flush_tlb_pending,
+ ctx, nr, (unsigned long) vaddrs,
+ mm->cpu_vm_mask);
-local_flush_and_out:
__flush_tlb_pending(ctx, nr, vaddrs);
put_cpu();
@@ -1184,20 +1152,9 @@ void __init smp_cpus_done(unsigned int max_cpus)
(bogosum/(5000/HZ))%100);
}
-/* This needn't do anything as we do not sleep the cpu
- * inside of the idler task, so an interrupt is not needed
- * to get a clean fast response.
- *
- * XXX Reverify this assumption... -DaveM
- *
- * Addendum: We do want it to do something for the signal
- * delivery case, we detect that by just seeing
- * if we are trying to send this to an idler or not.
- */
void smp_send_reschedule(int cpu)
{
- if (cpu_data(cpu).idle_volume == 0)
- smp_receive_signal(cpu);
+ smp_receive_signal(cpu);
}
/* This is a nop because we capture all other cpus
diff --git a/arch/sparc64/kernel/sunos_ioctl32.c b/arch/sparc64/kernel/sunos_ioctl32.c
index 7654b8a7f03a..3f619ead22cc 100644
--- a/arch/sparc64/kernel/sunos_ioctl32.c
+++ b/arch/sparc64/kernel/sunos_ioctl32.c
@@ -24,7 +24,6 @@
#include <linux/smp_lock.h>
#include <linux/syscalls.h>
#include <linux/compat.h>
-#include <asm/kbio.h>
#define SUNOS_NR_OPEN 256
diff --git a/arch/sparc64/kernel/time.c b/arch/sparc64/kernel/time.c
index 3f08a32f51a1..459c8fbe02b4 100644
--- a/arch/sparc64/kernel/time.c
+++ b/arch/sparc64/kernel/time.c
@@ -55,26 +55,11 @@ unsigned long ds1287_regs = 0UL;
extern unsigned long wall_jiffies;
-u64 jiffies_64 = INITIAL_JIFFIES;
-
-EXPORT_SYMBOL(jiffies_64);
-
static void __iomem *mstk48t08_regs;
static void __iomem *mstk48t59_regs;
static int set_rtc_mmss(unsigned long);
-static __init unsigned long dummy_get_tick(void)
-{
- return 0;
-}
-
-static __initdata struct sparc64_tick_ops dummy_tick_ops = {
- .get_tick = dummy_get_tick,
-};
-
-struct sparc64_tick_ops *tick_ops __read_mostly = &dummy_tick_ops;
-
#define TICK_PRIV_BIT (1UL << 63)
#ifdef CONFIG_SMP
@@ -204,6 +189,8 @@ static struct sparc64_tick_ops tick_operations __read_mostly = {
.softint_mask = 1UL << 0,
};
+struct sparc64_tick_ops *tick_ops __read_mostly = &tick_operations;
+
static void stick_init_tick(unsigned long offset)
{
tick_disable_protection();
diff --git a/arch/sparc64/kernel/us2e_cpufreq.c b/arch/sparc64/kernel/us2e_cpufreq.c
index 686e526bec04..b35dc8dc995a 100644
--- a/arch/sparc64/kernel/us2e_cpufreq.c
+++ b/arch/sparc64/kernel/us2e_cpufreq.c
@@ -388,10 +388,8 @@ err_out:
kfree(driver);
cpufreq_us2e_driver = NULL;
}
- if (us2e_freq_table) {
- kfree(us2e_freq_table);
- us2e_freq_table = NULL;
- }
+ kfree(us2e_freq_table);
+ us2e_freq_table = NULL;
return ret;
}
@@ -402,7 +400,6 @@ static void __exit us2e_freq_exit(void)
{
if (cpufreq_us2e_driver) {
cpufreq_unregister_driver(cpufreq_us2e_driver);
-
kfree(cpufreq_us2e_driver);
cpufreq_us2e_driver = NULL;
kfree(us2e_freq_table);
diff --git a/arch/sparc64/kernel/us3_cpufreq.c b/arch/sparc64/kernel/us3_cpufreq.c
index 0340041f6143..6d1f9a3c464f 100644
--- a/arch/sparc64/kernel/us3_cpufreq.c
+++ b/arch/sparc64/kernel/us3_cpufreq.c
@@ -249,10 +249,8 @@ err_out:
kfree(driver);
cpufreq_us3_driver = NULL;
}
- if (us3_freq_table) {
- kfree(us3_freq_table);
- us3_freq_table = NULL;
- }
+ kfree(us3_freq_table);
+ us3_freq_table = NULL;
return ret;
}
@@ -263,7 +261,6 @@ static void __exit us3_freq_exit(void)
{
if (cpufreq_us3_driver) {
cpufreq_unregister_driver(cpufreq_us3_driver);
-
kfree(cpufreq_us3_driver);
cpufreq_us3_driver = NULL;
kfree(us3_freq_table);
diff --git a/arch/sparc64/mm/fault.c b/arch/sparc64/mm/fault.c
index 31fbc67719a1..6f0539aa44d0 100644
--- a/arch/sparc64/mm/fault.c
+++ b/arch/sparc64/mm/fault.c
@@ -30,8 +30,6 @@
#include <asm/sections.h>
#include <asm/kdebug.h>
-#define ELEMENTS(arr) (sizeof (arr)/sizeof (arr[0]))
-
/*
* To debug kernel to catch accesses to certain virtual/physical addresses.
* Mode = 0 selects physical watchpoints, mode = 1 selects virtual watchpoints.
@@ -109,7 +107,7 @@ static void bad_kernel_pc(struct pt_regs *regs)
* this. Additionally, to prevent kswapd from ripping ptes from
* under us, raise interrupts around the time that we look at the
* pte, kswapd will have to wait to get his smp ipi response from
- * us. This saves us having to get page_table_lock.
+ * us. vmtruncate likewise. This saves us having to get pte lock.
*/
static unsigned int get_user_insn(unsigned long tpc)
{
diff --git a/arch/sparc64/mm/generic.c b/arch/sparc64/mm/generic.c
index c954d91f01d0..112c316e7cd2 100644
--- a/arch/sparc64/mm/generic.c
+++ b/arch/sparc64/mm/generic.c
@@ -127,14 +127,16 @@ int io_remap_pfn_range(struct vm_area_struct *vma, unsigned long from,
int space = GET_IOSPACE(pfn);
unsigned long offset = GET_PFN(pfn) << PAGE_SHIFT;
+ /* See comment in mm/memory.c remap_pfn_range */
+ vma->vm_flags |= VM_IO | VM_RESERVED;
+
prot = __pgprot(pg_iobits);
offset -= from;
dir = pgd_offset(mm, from);
flush_cache_range(vma, beg, end);
- spin_lock(&mm->page_table_lock);
while (from < end) {
- pud_t *pud = pud_alloc(current->mm, dir, from);
+ pud_t *pud = pud_alloc(mm, dir, from);
error = -ENOMEM;
if (!pud)
break;
@@ -144,8 +146,7 @@ int io_remap_pfn_range(struct vm_area_struct *vma, unsigned long from,
from = (from + PGDIR_SIZE) & PGDIR_MASK;
dir++;
}
- flush_tlb_range(vma, beg, end);
- spin_unlock(&mm->page_table_lock);
+ flush_tlb_range(vma, beg, end);
return error;
}
diff --git a/arch/sparc64/mm/tlb.c b/arch/sparc64/mm/tlb.c
index 90ca99d0b89c..8b104be4662b 100644
--- a/arch/sparc64/mm/tlb.c
+++ b/arch/sparc64/mm/tlb.c
@@ -18,8 +18,7 @@
/* Heavily inspired by the ppc64 code. */
-DEFINE_PER_CPU(struct mmu_gather, mmu_gathers) =
- { NULL, 0, 0, 0, 0, 0, { 0 }, { NULL }, };
+DEFINE_PER_CPU(struct mmu_gather, mmu_gathers) = { 0, };
void flush_tlb_pending(void)
{
@@ -72,7 +71,7 @@ void tlb_batch_add(struct mm_struct *mm, unsigned long vaddr, pte_t *ptep, pte_t
no_cache_flush:
- if (mp->tlb_frozen)
+ if (mp->fullmm)
return;
nr = mp->tlb_nr;
@@ -97,7 +96,7 @@ void flush_tlb_pgtables(struct mm_struct *mm, unsigned long start, unsigned long
unsigned long nr = mp->tlb_nr;
long s = start, e = end, vpte_base;
- if (mp->tlb_frozen)
+ if (mp->fullmm)
return;
/* If start is greater than end, that is a real problem. */
diff --git a/arch/sparc64/oprofile/Kconfig b/arch/sparc64/oprofile/Kconfig
index 5ade19801b97..d8a84088471a 100644
--- a/arch/sparc64/oprofile/Kconfig
+++ b/arch/sparc64/oprofile/Kconfig
@@ -1,7 +1,3 @@
-
-menu "Profiling support"
- depends on EXPERIMENTAL
-
config PROFILING
bool "Profiling support (EXPERIMENTAL)"
help
@@ -19,5 +15,3 @@ config OPROFILE
If unsure, say N.
-endmenu
-
diff --git a/arch/sparc64/solaris/socksys.c b/arch/sparc64/solaris/socksys.c
index d7c1c76582cc..fc6669e8dde1 100644
--- a/arch/sparc64/solaris/socksys.c
+++ b/arch/sparc64/solaris/socksys.c
@@ -49,7 +49,7 @@ IPPROTO_EGP, IPPROTO_PUP, IPPROTO_UDP, IPPROTO_IDP, IPPROTO_RAW,
#else
-extern void * mykmalloc(size_t s, int gfp);
+extern void * mykmalloc(size_t s, gfp_t gfp);
extern void mykfree(void *);
#endif
diff --git a/arch/sparc64/solaris/timod.c b/arch/sparc64/solaris/timod.c
index aaad29c35c83..b84e5456b025 100644
--- a/arch/sparc64/solaris/timod.c
+++ b/arch/sparc64/solaris/timod.c
@@ -39,7 +39,7 @@ static char * page = NULL ;
#else
-void * mykmalloc(size_t s, int gfp)
+void * mykmalloc(size_t s, gfp_t gfp)
{
static char * page;
static size_t free;
diff --git a/arch/um/Kconfig b/arch/um/Kconfig
index 684e1f8b2755..3b5f47c46907 100644
--- a/arch/um/Kconfig
+++ b/arch/um/Kconfig
@@ -27,10 +27,6 @@ config UID16
bool
default y
-config RWSEM_GENERIC_SPINLOCK
- bool
- default y
-
config GENERIC_CALIBRATE_DELAY
bool
default y
@@ -40,6 +36,12 @@ config IRQ_RELEASE_METHOD
bool
default y
+menu "Host processor type and features"
+
+source "arch/i386/Kconfig.cpu"
+
+endmenu
+
menu "UML-specific options"
config MODE_TT
@@ -63,6 +65,30 @@ config STATIC_LINK
chroot, and you disable CONFIG_MODE_TT, you probably want to say Y
here.
+config HOST_2G_2G
+ bool "2G/2G host address space split"
+ default n
+ depends on MODE_TT
+ help
+ This is needed when the host on which you run has a 2G/2G memory
+ split, instead of the customary 3G/1G.
+
+ Note that to enable such a host
+ configuration, which makes sense only in some cases, you need special
+ host patches.
+
+ So, if you do not know what to do here, say 'N'.
+
+config KERNEL_HALF_GIGS
+ int "Kernel address space size (in .5G units)"
+ default "1"
+ depends on MODE_TT
+ help
+ This determines the amount of address space that UML will allocate for
+ its own, measured in half Gigabyte units. The default is 1.
+ Change this only if you need to boot UML with an unusually large amount
+ of physical memory.
+
config MODE_SKAS
bool "Separate Kernel Address Space support"
default y
@@ -180,19 +206,6 @@ config MAGIC_SYSRQ
The keys are documented in <file:Documentation/sysrq.txt>. Don't say Y
unless you really know what this hack does.
-config HOST_2G_2G
- bool "2G/2G host address space split"
- default n
- help
- This is needed when the host on which you run has a 2G/2G memory
- split, instead of the customary 3G/1G.
-
- Note that to enable such a host
- configuration, which makes sense only in some cases, you need special
- host patches.
-
- So, if you do not know what to do here, say 'N'.
-
config SMP
bool "Symmetric multi-processing support (EXPERIMENTAL)"
default n
@@ -239,15 +252,6 @@ config NEST_LEVEL
set to the host's CONFIG_NEST_LEVEL + CONFIG_KERNEL_HALF_GIGS.
Only change this if you are running nested UMLs.
-config KERNEL_HALF_GIGS
- int "Kernel address space size (in .5G units)"
- default "1"
- help
- This determines the amount of address space that UML will allocate for
- its own, measured in half Gigabyte units. The default is 1.
- Change this only if you need to boot UML with an unusually large amount
- of physical memory.
-
config HIGHMEM
bool "Highmem support"
depends on !64BIT
diff --git a/arch/um/Kconfig.x86_64 b/arch/um/Kconfig.x86_64
index bd35e59419c8..aae19bc4b06a 100644
--- a/arch/um/Kconfig.x86_64
+++ b/arch/um/Kconfig.x86_64
@@ -6,6 +6,11 @@ config 64BIT
bool
default y
+#XXX: this is so in the underlying arch, but it's wrong!!!
+config RWSEM_GENERIC_SPINLOCK
+ bool
+ default y
+
config SEMAPHORE_SLEEPERS
bool
default y
diff --git a/arch/um/Makefile b/arch/um/Makefile
index e1ffad224605..e55d32e903bc 100644
--- a/arch/um/Makefile
+++ b/arch/um/Makefile
@@ -60,7 +60,7 @@ AFLAGS += $(ARCH_INCLUDE)
USER_CFLAGS := $(patsubst -I%,,$(CFLAGS))
USER_CFLAGS := $(patsubst -D__KERNEL__,,$(USER_CFLAGS)) $(ARCH_INCLUDE) \
- $(MODE_INCLUDE)
+ $(MODE_INCLUDE) -D_FILE_OFFSET_BITS=64
# -Derrno=kernel_errno - This turns all kernel references to errno into
# kernel_errno to separate them from the libc errno. This allows -fno-common
diff --git a/arch/um/Makefile-i386 b/arch/um/Makefile-i386
index 2ee8a2858117..1f7dcb064aee 100644
--- a/arch/um/Makefile-i386
+++ b/arch/um/Makefile-i386
@@ -17,8 +17,6 @@ ifeq ("$(origin SUBARCH)", "command line")
ifneq ("$(shell uname -m | sed -e s/i.86/i386/)", "$(SUBARCH)")
CFLAGS += $(call cc-option,-m32)
USER_CFLAGS += $(call cc-option,-m32)
-HOSTCFLAGS += $(call cc-option,-m32)
-HOSTLDFLAGS += $(call cc-option,-m32)
AFLAGS += $(call cc-option,-m32)
LINK-y += $(call cc-option,-m32)
UML_OBJCOPYFLAGS += -F $(ELF_FORMAT)
@@ -29,6 +27,12 @@ endif
CFLAGS += -U__$(SUBARCH)__ -U$(SUBARCH)
-ifneq ($(CONFIG_GPROF),y)
-ARCH_CFLAGS += -DUM_FASTCALL
-endif
+# First of all, tune CFLAGS for the specific CPU. This actually sets cflags-y.
+include $(srctree)/arch/i386/Makefile.cpu
+
+# prevent gcc from keeping the stack 16 byte aligned. Taken from i386.
+cflags-y += $(call cc-option,-mpreferred-stack-boundary=2)
+
+CFLAGS += $(cflags-y)
+USER_CFLAGS += $(cflags-y)
+
diff --git a/arch/um/drivers/chan_user.c b/arch/um/drivers/chan_user.c
index de3bce71aeb3..1c55d5802489 100644
--- a/arch/um/drivers/chan_user.c
+++ b/arch/um/drivers/chan_user.c
@@ -16,7 +16,6 @@
#include "user_util.h"
#include "chan_user.h"
#include "user.h"
-#include "helper.h"
#include "os.h"
#include "choose-mode.h"
#include "mode.h"
diff --git a/arch/um/drivers/harddog_kern.c b/arch/um/drivers/harddog_kern.c
index 147ec19f6bb9..49acb2badf32 100644
--- a/arch/um/drivers/harddog_kern.c
+++ b/arch/um/drivers/harddog_kern.c
@@ -46,7 +46,6 @@
#include <linux/smp_lock.h>
#include <linux/init.h>
#include <asm/uaccess.h>
-#include "helper.h"
#include "mconsole.h"
MODULE_LICENSE("GPL");
diff --git a/arch/um/drivers/harddog_user.c b/arch/um/drivers/harddog_user.c
index d934181b8d4c..def013b5a3c7 100644
--- a/arch/um/drivers/harddog_user.c
+++ b/arch/um/drivers/harddog_user.c
@@ -8,7 +8,6 @@
#include <errno.h>
#include "user_util.h"
#include "user.h"
-#include "helper.h"
#include "mconsole.h"
#include "os.h"
#include "choose-mode.h"
diff --git a/arch/um/drivers/net_kern.c b/arch/um/drivers/net_kern.c
index 1495007bf6c0..4cf31a2ae19c 100644
--- a/arch/um/drivers/net_kern.c
+++ b/arch/um/drivers/net_kern.c
@@ -20,6 +20,7 @@
#include "linux/ctype.h"
#include "linux/bootmem.h"
#include "linux/ethtool.h"
+#include "linux/platform_device.h"
#include "asm/uaccess.h"
#include "user_util.h"
#include "kern_util.h"
@@ -95,7 +96,6 @@ irqreturn_t uml_net_interrupt(int irq, void *dev_id, struct pt_regs *regs)
static int uml_net_open(struct net_device *dev)
{
struct uml_net_private *lp = dev->priv;
- char addr[sizeof("255.255.255.255\0")];
int err;
spin_lock(&lp->lock);
@@ -106,7 +106,7 @@ static int uml_net_open(struct net_device *dev)
}
if(!lp->have_mac){
- dev_ip_addr(dev, addr, &lp->mac[2]);
+ dev_ip_addr(dev, &lp->mac[2]);
set_ether_mac(dev, lp->mac);
}
@@ -243,34 +243,18 @@ static int uml_net_change_mtu(struct net_device *dev, int new_mtu)
return err;
}
-static int uml_net_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
-{
- static const struct ethtool_drvinfo info = {
- .cmd = ETHTOOL_GDRVINFO,
- .driver = DRIVER_NAME,
- .version = "42",
- };
- void *useraddr;
- u32 ethcmd;
-
- switch (cmd) {
- case SIOCETHTOOL:
- useraddr = ifr->ifr_data;
- if (copy_from_user(&ethcmd, useraddr, sizeof(ethcmd)))
- return -EFAULT;
- switch (ethcmd) {
- case ETHTOOL_GDRVINFO:
- if (copy_to_user(useraddr, &info, sizeof(info)))
- return -EFAULT;
- return 0;
- default:
- return -EOPNOTSUPP;
- }
- default:
- return -EINVAL;
- }
+static void uml_net_get_drvinfo(struct net_device *dev,
+ struct ethtool_drvinfo *info)
+{
+ strcpy(info->driver, DRIVER_NAME);
+ strcpy(info->version, "42");
}
+static struct ethtool_ops uml_net_ethtool_ops = {
+ .get_drvinfo = uml_net_get_drvinfo,
+ .get_link = ethtool_op_get_link,
+};
+
void uml_net_user_timer_expire(unsigned long _conn)
{
#ifdef undef
@@ -359,7 +343,7 @@ static int eth_configure(int n, void *init, char *mac,
dev->tx_timeout = uml_net_tx_timeout;
dev->set_mac_address = uml_net_set_mac;
dev->change_mtu = uml_net_change_mtu;
- dev->do_ioctl = uml_net_ioctl;
+ dev->ethtool_ops = &uml_net_ethtool_ops;
dev->watchdog_timeo = (HZ >> 1);
dev->irq = UM_ETH_IRQ;
@@ -663,8 +647,6 @@ static int uml_inetaddr_event(struct notifier_block *this, unsigned long event,
void *ptr)
{
struct in_ifaddr *ifa = ptr;
- u32 addr = ifa->ifa_address;
- u32 netmask = ifa->ifa_mask;
struct net_device *dev = ifa->ifa_dev->dev;
struct uml_net_private *lp;
void (*proc)(unsigned char *, unsigned char *, void *);
@@ -684,14 +666,8 @@ static int uml_inetaddr_event(struct notifier_block *this, unsigned long event,
break;
}
if(proc != NULL){
- addr_buf[0] = addr & 0xff;
- addr_buf[1] = (addr >> 8) & 0xff;
- addr_buf[2] = (addr >> 16) & 0xff;
- addr_buf[3] = addr >> 24;
- netmask_buf[0] = netmask & 0xff;
- netmask_buf[1] = (netmask >> 8) & 0xff;
- netmask_buf[2] = (netmask >> 16) & 0xff;
- netmask_buf[3] = netmask >> 24;
+ memcpy(addr_buf, &ifa->ifa_address, sizeof(addr_buf));
+ memcpy(netmask_buf, &ifa->ifa_mask, sizeof(netmask_buf));
(*proc)(addr_buf, netmask_buf, &lp->user);
}
return(NOTIFY_DONE);
@@ -773,27 +749,18 @@ int setup_etheraddr(char *str, unsigned char *addr)
return(1);
}
-void dev_ip_addr(void *d, char *buf, char *bin_buf)
+void dev_ip_addr(void *d, unsigned char *bin_buf)
{
struct net_device *dev = d;
struct in_device *ip = dev->ip_ptr;
struct in_ifaddr *in;
- u32 addr;
if((ip == NULL) || ((in = ip->ifa_list) == NULL)){
printk(KERN_WARNING "dev_ip_addr - device not assigned an "
"IP address\n");
return;
}
- addr = in->ifa_address;
- sprintf(buf, "%d.%d.%d.%d", addr & 0xff, (addr >> 8) & 0xff,
- (addr >> 16) & 0xff, addr >> 24);
- if(bin_buf){
- bin_buf[0] = addr & 0xff;
- bin_buf[1] = (addr >> 8) & 0xff;
- bin_buf[2] = (addr >> 16) & 0xff;
- bin_buf[3] = addr >> 24;
- }
+ memcpy(bin_buf, &in->ifa_address, sizeof(in->ifa_address));
}
void set_ether_mac(void *d, unsigned char *addr)
@@ -828,14 +795,8 @@ void iter_addresses(void *d, void (*cb)(unsigned char *, unsigned char *,
if(ip == NULL) return;
in = ip->ifa_list;
while(in != NULL){
- address[0] = in->ifa_address & 0xff;
- address[1] = (in->ifa_address >> 8) & 0xff;
- address[2] = (in->ifa_address >> 16) & 0xff;
- address[3] = in->ifa_address >> 24;
- netmask[0] = in->ifa_mask & 0xff;
- netmask[1] = (in->ifa_mask >> 8) & 0xff;
- netmask[2] = (in->ifa_mask >> 16) & 0xff;
- netmask[3] = in->ifa_mask >> 24;
+ memcpy(address, &in->ifa_address, sizeof(address));
+ memcpy(netmask, &in->ifa_mask, sizeof(netmask));
(*cb)(address, netmask, arg);
in = in->ifa_next;
}
diff --git a/arch/um/drivers/net_user.c b/arch/um/drivers/net_user.c
index 3730d4f12713..098fa65981ab 100644
--- a/arch/um/drivers/net_user.c
+++ b/arch/um/drivers/net_user.c
@@ -16,7 +16,6 @@
#include "user_util.h"
#include "kern_util.h"
#include "net_user.h"
-#include "helper.h"
#include "os.h"
int tap_open_common(void *dev, char *gate_addr)
diff --git a/arch/um/drivers/port_user.c b/arch/um/drivers/port_user.c
index 14dd2002d2da..ed4a1a6c5d83 100644
--- a/arch/um/drivers/port_user.c
+++ b/arch/um/drivers/port_user.c
@@ -18,7 +18,6 @@
#include "user.h"
#include "chan_user.h"
#include "port.h"
-#include "helper.h"
#include "os.h"
struct port_chan {
diff --git a/arch/um/drivers/random.c b/arch/um/drivers/random.c
index f9e22198e011..ba471f5864a6 100644
--- a/arch/um/drivers/random.c
+++ b/arch/um/drivers/random.c
@@ -58,10 +58,8 @@ static ssize_t rng_dev_read (struct file *filp, char __user *buf, size_t size,
if (filp->f_flags & O_NONBLOCK)
return ret ? : -EAGAIN;
- if(need_resched()){
- current->state = TASK_INTERRUPTIBLE;
- schedule_timeout(1);
- }
+ if(need_resched())
+ schedule_timeout_interruptible(1);
}
else return n;
if (signal_pending (current))
diff --git a/arch/um/drivers/slip_user.c b/arch/um/drivers/slip_user.c
index 71af444e591f..89fbec185cc1 100644
--- a/arch/um/drivers/slip_user.c
+++ b/arch/um/drivers/slip_user.c
@@ -14,7 +14,6 @@
#include "net_user.h"
#include "slip.h"
#include "slip_common.h"
-#include "helper.h"
#include "os.h"
void slip_user_init(void *data, void *dev)
diff --git a/arch/um/drivers/slirp_user.c b/arch/um/drivers/slirp_user.c
index 8d91f663d82c..b94c66114bc8 100644
--- a/arch/um/drivers/slirp_user.c
+++ b/arch/um/drivers/slirp_user.c
@@ -13,7 +13,6 @@
#include "net_user.h"
#include "slirp.h"
#include "slip_common.h"
-#include "helper.h"
#include "os.h"
void slirp_user_init(void *data, void *dev)
diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c
index f73134333f64..b2c86257b0f8 100644
--- a/arch/um/drivers/ubd_kern.c
+++ b/arch/um/drivers/ubd_kern.c
@@ -35,6 +35,7 @@
#include "linux/blkpg.h"
#include "linux/genhd.h"
#include "linux/spinlock.h"
+#include "linux/platform_device.h"
#include "asm/segment.h"
#include "asm/uaccess.h"
#include "asm/irq.h"
diff --git a/arch/um/drivers/xterm.c b/arch/um/drivers/xterm.c
index 90e0e5ff451e..b530f1a6540d 100644
--- a/arch/um/drivers/xterm.c
+++ b/arch/um/drivers/xterm.c
@@ -14,7 +14,6 @@
#include <sys/socket.h>
#include "kern_util.h"
#include "chan_user.h"
-#include "helper.h"
#include "user_util.h"
#include "user.h"
#include "os.h"
diff --git a/arch/um/include/helper.h b/arch/um/include/helper.h
deleted file mode 100644
index 162ac31192fd..000000000000
--- a/arch/um/include/helper.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
- * Licensed under the GPL
- */
-
-#ifndef __HELPER_H__
-#define __HELPER_H__
-
-extern int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv,
- unsigned long *stack_out);
-extern int run_helper_thread(int (*proc)(void *), void *arg,
- unsigned int flags, unsigned long *stack_out,
- int stack_order);
-extern int helper_wait(int pid);
-
-#endif
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/include/mem_user.h b/arch/um/include/mem_user.h
index 9fef4123a65a..a1064c5823bf 100644
--- a/arch/um/include/mem_user.h
+++ b/arch/um/include/mem_user.h
@@ -57,7 +57,7 @@ extern int init_maps(unsigned long physmem, unsigned long iomem,
unsigned long highmem);
extern unsigned long get_vm(unsigned long len);
extern void setup_physmem(unsigned long start, unsigned long usable,
- unsigned long len, unsigned long highmem);
+ unsigned long len, unsigned long long highmem);
extern void add_iomem(char *name, int fd, unsigned long size);
extern unsigned long phys_offset(unsigned long phys);
extern void unmap_physmem(void);
diff --git a/arch/um/include/net_kern.h b/arch/um/include/net_kern.h
index 1c07949a13d6..f7de6df60dd7 100644
--- a/arch/um/include/net_kern.h
+++ b/arch/um/include/net_kern.h
@@ -6,10 +6,11 @@
#ifndef __UM_NET_KERN_H
#define __UM_NET_KERN_H
-#include "linux/netdevice.h"
-#include "linux/skbuff.h"
-#include "linux/socket.h"
-#include "linux/list.h"
+#include <linux/netdevice.h>
+#include <linux/platform_device.h>
+#include <linux/skbuff.h>
+#include <linux/socket.h>
+#include <linux/list.h>
struct uml_net {
struct list_head list;
diff --git a/arch/um/include/net_user.h b/arch/um/include/net_user.h
index 89885a77a771..800c403920bc 100644
--- a/arch/um/include/net_user.h
+++ b/arch/um/include/net_user.h
@@ -25,7 +25,7 @@ struct net_user_info {
};
extern void ether_user_init(void *data, void *dev);
-extern void dev_ip_addr(void *d, char *buf, char *bin_buf);
+extern void dev_ip_addr(void *d, unsigned char *bin_buf);
extern void set_ether_mac(void *d, unsigned char *addr);
extern void iter_addresses(void *d, void (*cb)(unsigned char *,
unsigned char *, void *),
diff --git a/arch/um/include/os.h b/arch/um/include/os.h
index 2e58e304b8be..2cccfa5b8ab5 100644
--- a/arch/um/include/os.h
+++ b/arch/um/include/os.h
@@ -167,7 +167,7 @@ extern int can_do_skas(void);
#endif
/* mem.c */
-extern int create_mem_file(unsigned long len);
+extern int create_mem_file(unsigned long long len);
/* process.c */
extern unsigned long os_process_pc(int pid);
@@ -199,6 +199,20 @@ extern void forward_pending_sigio(int target);
extern int start_fork_tramp(void *arg, unsigned long temp_stack,
int clone_flags, int (*tramp)(void *));
+/* uaccess.c */
+extern unsigned long __do_user_copy(void *to, const void *from, int n,
+ void **fault_addr, void **fault_catcher,
+ void (*op)(void *to, const void *from,
+ int n), int *faulted_out);
+
+/* helper.c */
+extern int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv,
+ unsigned long *stack_out);
+extern int run_helper_thread(int (*proc)(void *), void *arg,
+ unsigned int flags, unsigned long *stack_out,
+ int stack_order);
+extern int helper_wait(int pid);
+
#endif
/*
diff --git a/arch/um/include/sysdep-i386/stub.h b/arch/um/include/sysdep-i386/stub.h
index d3699fe1c613..a49ceb199ee5 100644
--- a/arch/um/include/sysdep-i386/stub.h
+++ b/arch/um/include/sysdep-i386/stub.h
@@ -16,45 +16,69 @@ extern void stub_clone_handler(void);
#define STUB_MMAP_NR __NR_mmap2
#define MMAP_OFFSET(o) ((o) >> PAGE_SHIFT)
+static inline long stub_syscall1(long syscall, long arg1)
+{
+ long ret;
+
+ __asm__ volatile ("int $0x80" : "=a" (ret) : "0" (syscall), "b" (arg1));
+
+ return ret;
+}
+
static inline long stub_syscall2(long syscall, long arg1, long arg2)
{
long ret;
- __asm__("movl %0, %%ecx; " : : "g" (arg2) : "%ecx");
- __asm__("movl %0, %%ebx; " : : "g" (arg1) : "%ebx");
- __asm__("movl %0, %%eax; " : : "g" (syscall) : "%eax");
- __asm__("int $0x80;" : : : "%eax");
- __asm__ __volatile__("movl %%eax, %0; " : "=g" (ret) :);
- return(ret);
+ __asm__ volatile ("int $0x80" : "=a" (ret) : "0" (syscall), "b" (arg1),
+ "c" (arg2));
+
+ return ret;
}
static inline long stub_syscall3(long syscall, long arg1, long arg2, long arg3)
{
- __asm__("movl %0, %%edx; " : : "g" (arg3) : "%edx");
- return(stub_syscall2(syscall, arg1, arg2));
+ long ret;
+
+ __asm__ volatile ("int $0x80" : "=a" (ret) : "0" (syscall), "b" (arg1),
+ "c" (arg2), "d" (arg3));
+
+ return ret;
}
static inline long stub_syscall4(long syscall, long arg1, long arg2, long arg3,
long arg4)
{
- __asm__("movl %0, %%esi; " : : "g" (arg4) : "%esi");
- return(stub_syscall3(syscall, arg1, arg2, arg3));
+ long ret;
+
+ __asm__ volatile ("int $0x80" : "=a" (ret) : "0" (syscall), "b" (arg1),
+ "c" (arg2), "d" (arg3), "S" (arg4));
+
+ return ret;
+}
+
+static inline long stub_syscall5(long syscall, long arg1, long arg2, long arg3,
+ long arg4, long arg5)
+{
+ long ret;
+
+ __asm__ volatile ("int $0x80" : "=a" (ret) : "0" (syscall), "b" (arg1),
+ "c" (arg2), "d" (arg3), "S" (arg4), "D" (arg5));
+
+ return ret;
}
static inline long stub_syscall6(long syscall, long arg1, long arg2, long arg3,
long arg4, long arg5, long arg6)
{
long ret;
- __asm__("movl %0, %%eax; " : : "g" (syscall) : "%eax");
- __asm__("movl %0, %%ebx; " : : "g" (arg1) : "%ebx");
- __asm__("movl %0, %%ecx; " : : "g" (arg2) : "%ecx");
- __asm__("movl %0, %%edx; " : : "g" (arg3) : "%edx");
- __asm__("movl %0, %%esi; " : : "g" (arg4) : "%esi");
- __asm__("movl %0, %%edi; " : : "g" (arg5) : "%edi");
- __asm__ __volatile__("pushl %%ebp ; movl %1, %%ebp; "
- "int $0x80; popl %%ebp ; "
- "movl %%eax, %0; " : "=g" (ret) : "g" (arg6) : "%eax");
- return(ret);
+
+ __asm__ volatile ("push %%ebp ; movl %%eax,%%ebp ; movl %1,%%eax ; "
+ "int $0x80 ; pop %%ebp"
+ : "=a" (ret)
+ : "g" (syscall), "b" (arg1), "c" (arg2), "d" (arg3),
+ "S" (arg4), "D" (arg5), "0" (arg6));
+
+ return ret;
}
static inline void trap_myself(void)
diff --git a/arch/um/include/sysdep-i386/syscalls.h b/arch/um/include/sysdep-i386/syscalls.h
index a0d5b74d3731..57bd79efbee3 100644
--- a/arch/um/include/sysdep-i386/syscalls.h
+++ b/arch/um/include/sysdep-i386/syscalls.h
@@ -11,7 +11,6 @@ typedef long syscall_handler_t(struct pt_regs);
/* Not declared on x86, incompatible declarations on x86_64, so these have
* to go here rather than in sys_call_table.c
*/
-extern syscall_handler_t sys_ptrace;
extern syscall_handler_t sys_rt_sigaction;
extern syscall_handler_t old_mmap_i386;
diff --git a/arch/um/include/sysdep-x86_64/stub.h b/arch/um/include/sysdep-x86_64/stub.h
index f599058d8263..2bd6e7a97286 100644
--- a/arch/um/include/sysdep-x86_64/stub.h
+++ b/arch/um/include/sysdep-x86_64/stub.h
@@ -17,37 +17,72 @@ extern void stub_clone_handler(void);
#define STUB_MMAP_NR __NR_mmap
#define MMAP_OFFSET(o) (o)
+#define __syscall_clobber "r11","rcx","memory"
+#define __syscall "syscall"
+
static inline long stub_syscall2(long syscall, long arg1, long arg2)
{
long ret;
- __asm__("movq %0, %%rsi; " : : "g" (arg2) : "%rsi");
- __asm__("movq %0, %%rdi; " : : "g" (arg1) : "%rdi");
- __asm__("movq %0, %%rax; " : : "g" (syscall) : "%rax");
- __asm__("syscall;" : : : "%rax", "%r11", "%rcx");
- __asm__ __volatile__("movq %%rax, %0; " : "=g" (ret) :);
- return(ret);
+ __asm__ volatile (__syscall
+ : "=a" (ret)
+ : "0" (syscall), "D" (arg1), "S" (arg2) : __syscall_clobber );
+
+ return ret;
}
static inline long stub_syscall3(long syscall, long arg1, long arg2, long arg3)
{
- __asm__("movq %0, %%rdx; " : : "g" (arg3) : "%rdx");
- return(stub_syscall2(syscall, arg1, arg2));
+ long ret;
+
+ __asm__ volatile (__syscall
+ : "=a" (ret)
+ : "0" (syscall), "D" (arg1), "S" (arg2), "d" (arg3)
+ : __syscall_clobber );
+
+ return ret;
}
static inline long stub_syscall4(long syscall, long arg1, long arg2, long arg3,
long arg4)
{
- __asm__("movq %0, %%r10; " : : "g" (arg4) : "%r10");
- return(stub_syscall3(syscall, arg1, arg2, arg3));
+ long ret;
+
+ __asm__ volatile ("movq %5,%%r10 ; " __syscall
+ : "=a" (ret)
+ : "0" (syscall), "D" (arg1), "S" (arg2), "d" (arg3),
+ "g" (arg4)
+ : __syscall_clobber, "r10" );
+
+ return ret;
+}
+
+static inline long stub_syscall5(long syscall, long arg1, long arg2, long arg3,
+ long arg4, long arg5)
+{
+ long ret;
+
+ __asm__ volatile ("movq %5,%%r10 ; movq %6,%%r8 ; " __syscall
+ : "=a" (ret)
+ : "0" (syscall), "D" (arg1), "S" (arg2), "d" (arg3),
+ "g" (arg4), "g" (arg5)
+ : __syscall_clobber, "r10", "r8" );
+
+ return ret;
}
static inline long stub_syscall6(long syscall, long arg1, long arg2, long arg3,
long arg4, long arg5, long arg6)
{
- __asm__("movq %0, %%r9; " : : "g" (arg6) : "%r9");
- __asm__("movq %0, %%r8; " : : "g" (arg5) : "%r8");
- return(stub_syscall4(syscall, arg1, arg2, arg3, arg4));
+ long ret;
+
+ __asm__ volatile ("movq %5,%%r10 ; movq %6,%%r8 ; "
+ "movq %7, %%r9; " __syscall : "=a" (ret)
+ : "0" (syscall), "D" (arg1), "S" (arg2), "d" (arg3),
+ "g" (arg4), "g" (arg5), "g" (arg6)
+ : __syscall_clobber, "r10", "r8", "r9" );
+
+ return ret;
}
static inline void trap_myself(void)
diff --git a/arch/um/include/tlb.h b/arch/um/include/tlb.h
index 45d7da6c3b2c..8efc1e0f1b84 100644
--- a/arch/um/include/tlb.h
+++ b/arch/um/include/tlb.h
@@ -34,7 +34,6 @@ struct host_vm_op {
} u;
};
-extern void mprotect_kernel_vm(int w);
extern void force_flush_all(void);
extern void fix_range_common(struct mm_struct *mm, unsigned long start_addr,
unsigned long end_addr, int force,
diff --git a/arch/um/include/uml_uaccess.h b/arch/um/include/uml_uaccess.h
index f77eb6428453..c0df11d06f5e 100644
--- a/arch/um/include/uml_uaccess.h
+++ b/arch/um/include/uml_uaccess.h
@@ -8,10 +8,6 @@
extern int __do_copy_to_user(void *to, const void *from, int n,
void **fault_addr, void **fault_catcher);
-extern unsigned long __do_user_copy(void *to, const void *from, int n,
- void **fault_addr, void **fault_catcher,
- void (*op)(void *to, const void *from,
- int n), int *faulted_out);
void __do_copy(void *to, const void *from, int n);
#endif
diff --git a/arch/um/kernel/Makefile b/arch/um/kernel/Makefile
index 1a0001b3850c..3de9d21e36bf 100644
--- a/arch/um/kernel/Makefile
+++ b/arch/um/kernel/Makefile
@@ -7,10 +7,10 @@ extra-y := vmlinux.lds
clean-files :=
obj-y = config.o exec_kern.o exitcode.o \
- helper.o init_task.o irq.o irq_user.o ksyms.o main.o mem.o physmem.o \
+ init_task.o irq.o irq_user.o ksyms.o mem.o physmem.o \
process_kern.o ptrace.o reboot.o resource.o sigio_user.o sigio_kern.o \
signal_kern.o signal_user.o smp.o syscall_kern.o sysrq.o time.o \
- time_kern.o tlb.o trap_kern.o trap_user.o uaccess_user.o um_arch.o \
+ time_kern.o tlb.o trap_kern.o trap_user.o uaccess.o um_arch.o \
umid.o user_util.o
obj-$(CONFIG_BLK_DEV_INITRD) += initrd.o
@@ -24,8 +24,7 @@ obj-$(CONFIG_MODE_SKAS) += skas/
user-objs-$(CONFIG_TTY_LOG) += tty_log.o
-USER_OBJS := $(user-objs-y) config.o helper.o main.o time.o tty_log.o umid.o \
- user_util.o
+USER_OBJS := $(user-objs-y) config.o time.o tty_log.o umid.o user_util.o
include arch/um/scripts/Makefile.rules
diff --git a/arch/um/kernel/ksyms.c b/arch/um/kernel/ksyms.c
index a97a72e516aa..7713e7a6f476 100644
--- a/arch/um/kernel/ksyms.c
+++ b/arch/um/kernel/ksyms.c
@@ -20,7 +20,6 @@
#include "user_util.h"
#include "mem_user.h"
#include "os.h"
-#include "helper.h"
EXPORT_SYMBOL(stop);
EXPORT_SYMBOL(uml_physmem);
diff --git a/arch/um/kernel/mem.c b/arch/um/kernel/mem.c
index ea008b031a8f..fa4f915be5c5 100644
--- a/arch/um/kernel/mem.c
+++ b/arch/um/kernel/mem.c
@@ -234,8 +234,8 @@ void paging_init(void)
empty_bad_page = (unsigned long *) alloc_bootmem_low_pages(PAGE_SIZE);
for(i=0;i<sizeof(zones_size)/sizeof(zones_size[0]);i++)
zones_size[i] = 0;
- zones_size[0] = (end_iomem >> PAGE_SHIFT) - (uml_physmem >> PAGE_SHIFT);
- zones_size[2] = highmem >> PAGE_SHIFT;
+ zones_size[ZONE_DMA] = (end_iomem >> PAGE_SHIFT) - (uml_physmem >> PAGE_SHIFT);
+ zones_size[ZONE_HIGHMEM] = highmem >> PAGE_SHIFT;
free_area_init(zones_size);
/*
@@ -252,7 +252,7 @@ void paging_init(void)
#endif
}
-struct page *arch_validate(struct page *page, int mask, int order)
+struct page *arch_validate(struct page *page, gfp_t mask, int order)
{
unsigned long addr, zero = 0;
int i;
diff --git a/arch/um/kernel/physmem.c b/arch/um/kernel/physmem.c
index ea670fcc8af5..f3b583a878a6 100644
--- a/arch/um/kernel/physmem.c
+++ b/arch/um/kernel/physmem.c
@@ -246,7 +246,7 @@ int is_remapped(void *virt)
/* Changed during early boot */
unsigned long high_physmem;
-extern unsigned long physmem_size;
+extern unsigned long long physmem_size;
int init_maps(unsigned long physmem, unsigned long iomem, unsigned long highmem)
{
@@ -321,7 +321,7 @@ void map_memory(unsigned long virt, unsigned long phys, unsigned long len,
extern int __syscall_stub_start, __binary_start;
void setup_physmem(unsigned long start, unsigned long reserve_end,
- unsigned long len, unsigned long highmem)
+ unsigned long len, unsigned long long highmem)
{
unsigned long reserve = reserve_end - start;
int pfn = PFN_UP(__pa(reserve_end));
diff --git a/arch/um/kernel/process_kern.c b/arch/um/kernel/process_kern.c
index ea65db679e9c..34b54a3e2132 100644
--- a/arch/um/kernel/process_kern.c
+++ b/arch/um/kernel/process_kern.c
@@ -80,7 +80,7 @@ void free_stack(unsigned long stack, int order)
unsigned long alloc_stack(int order, int atomic)
{
unsigned long page;
- int flags = GFP_KERNEL;
+ gfp_t flags = GFP_KERNEL;
if (atomic)
flags = GFP_ATOMIC;
@@ -222,6 +222,7 @@ void *um_virt_to_phys(struct task_struct *task, unsigned long addr,
pud_t *pud;
pmd_t *pmd;
pte_t *pte;
+ pte_t ptent;
if(task->mm == NULL)
return(ERR_PTR(-EINVAL));
@@ -238,12 +239,13 @@ void *um_virt_to_phys(struct task_struct *task, unsigned long addr,
return(ERR_PTR(-EINVAL));
pte = pte_offset_kernel(pmd, addr);
- if(!pte_present(*pte))
+ ptent = *pte;
+ if(!pte_present(ptent))
return(ERR_PTR(-EINVAL));
if(pte_out != NULL)
- *pte_out = *pte;
- return((void *) (pte_val(*pte) & PAGE_MASK) + (addr & ~PAGE_MASK));
+ *pte_out = ptent;
+ return((void *) (pte_val(ptent) & PAGE_MASK) + (addr & ~PAGE_MASK));
}
char *current_cmd(void)
diff --git a/arch/um/kernel/ptrace.c b/arch/um/kernel/ptrace.c
index 71af4d503899..98e09395c093 100644
--- a/arch/um/kernel/ptrace.c
+++ b/arch/um/kernel/ptrace.c
@@ -43,53 +43,10 @@ void ptrace_disable(struct task_struct *child)
extern int peek_user(struct task_struct * child, long addr, long data);
extern int poke_user(struct task_struct * child, long addr, long data);
-long sys_ptrace(long request, long pid, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request, long addr, long data)
{
- struct task_struct *child;
int i, ret;
- lock_kernel();
- ret = -EPERM;
- if (request == PTRACE_TRACEME) {
- /* are we already being traced? */
- if (current->ptrace & PT_PTRACED)
- goto out;
-
- ret = security_ptrace(current->parent, current);
- if (ret)
- goto out;
-
- /* set the ptrace bit in the process flags. */
- current->ptrace |= PT_PTRACED;
- ret = 0;
- goto out;
- }
- ret = -ESRCH;
- read_lock(&tasklist_lock);
- child = find_task_by_pid(pid);
- if (child)
- get_task_struct(child);
- read_unlock(&tasklist_lock);
- if (!child)
- goto out;
-
- ret = -EPERM;
- if (pid == 1) /* you may not mess with init */
- goto out_tsk;
-
- if (request == PTRACE_ATTACH) {
- ret = ptrace_attach(child);
- goto out_tsk;
- }
-
-#ifdef SUBACH_PTRACE_SPECIAL
- SUBARCH_PTRACE_SPECIAL(child,request,addr,data);
-#endif
-
- ret = ptrace_check_attach(child, request == PTRACE_KILL);
- if (ret < 0)
- goto out_tsk;
-
switch (request) {
/* when I and D space are separate, these will need to be fixed. */
case PTRACE_PEEKTEXT: /* read word at location addr. */
@@ -282,10 +239,7 @@ long sys_ptrace(long request, long pid, long addr, long data)
ret = ptrace_request(child, request, addr, data);
break;
}
- out_tsk:
- put_task_struct(child);
- out:
- unlock_kernel();
+
return ret;
}
diff --git a/arch/um/kernel/sigio_user.c b/arch/um/kernel/sigio_user.c
index a52751108aa1..48b1f644b9a6 100644
--- a/arch/um/kernel/sigio_user.c
+++ b/arch/um/kernel/sigio_user.c
@@ -18,7 +18,6 @@
#include "kern_util.h"
#include "user_util.h"
#include "sigio.h"
-#include "helper.h"
#include "os.h"
/* Changed during early boot */
@@ -225,7 +224,7 @@ static int need_poll(int n)
next_poll.used = n;
return(0);
}
- if(next_poll.poll != NULL) kfree(next_poll.poll);
+ kfree(next_poll.poll);
next_poll.poll = um_kmalloc_atomic(n * sizeof(struct pollfd));
if(next_poll.poll == NULL){
printk("need_poll : failed to allocate new pollfds\n");
diff --git a/arch/um/kernel/skas/include/mmu-skas.h b/arch/um/kernel/skas/include/mmu-skas.h
index 09536f81ee42..44110c521e49 100644
--- a/arch/um/kernel/skas/include/mmu-skas.h
+++ b/arch/um/kernel/skas/include/mmu-skas.h
@@ -8,6 +8,7 @@
#include "linux/config.h"
#include "mm_id.h"
+#include "asm/ldt.h"
struct mmu_context_skas {
struct mm_id id;
@@ -15,6 +16,7 @@ struct mmu_context_skas {
#ifdef CONFIG_3_LEVEL_PGTABLES
unsigned long last_pmd;
#endif
+ uml_ldt_t ldt;
};
extern void switch_mm_skas(struct mm_id * mm_idp);
diff --git a/arch/um/kernel/skas/include/skas.h b/arch/um/kernel/skas/include/skas.h
index 060934740f9f..daa2f85b684c 100644
--- a/arch/um/kernel/skas/include/skas.h
+++ b/arch/um/kernel/skas/include/skas.h
@@ -10,7 +10,8 @@
#include "sysdep/ptrace.h"
extern int userspace_pid[];
-extern int proc_mm, ptrace_faultinfo;
+extern int proc_mm, ptrace_faultinfo, ptrace_ldt;
+extern int skas_needs_stub;
extern void switch_threads(void *me, void *next);
extern void thread_wait(void *sw, void *fb);
diff --git a/arch/um/kernel/skas/mem.c b/arch/um/kernel/skas/mem.c
index 147466d7ff4f..88ab96c609ce 100644
--- a/arch/um/kernel/skas/mem.c
+++ b/arch/um/kernel/skas/mem.c
@@ -20,7 +20,7 @@ unsigned long set_task_sizes_skas(int arg, unsigned long *host_size_out,
*task_size_out = CONFIG_HOST_TASK_SIZE;
#else
*host_size_out = top;
- if (proc_mm && ptrace_faultinfo)
+ if (!skas_needs_stub)
*task_size_out = top;
else *task_size_out = CONFIG_STUB_START & PGDIR_MASK;
#endif
diff --git a/arch/um/kernel/skas/mmu.c b/arch/um/kernel/skas/mmu.c
index 240143b616a2..677871f1b37c 100644
--- a/arch/um/kernel/skas/mmu.c
+++ b/arch/um/kernel/skas/mmu.c
@@ -15,6 +15,7 @@
#include "asm/mmu.h"
#include "asm/pgalloc.h"
#include "asm/pgtable.h"
+#include "asm/ldt.h"
#include "os.h"
#include "skas.h"
@@ -28,7 +29,6 @@ static int init_stub_pte(struct mm_struct *mm, unsigned long proc,
pmd_t *pmd;
pte_t *pte;
- spin_lock(&mm->page_table_lock);
pgd = pgd_offset(mm, proc);
pud = pud_alloc(mm, pgd, proc);
if (!pud)
@@ -63,7 +63,6 @@ static int init_stub_pte(struct mm_struct *mm, unsigned long proc,
*pte = mk_pte(virt_to_page(kernel), __pgprot(_PAGE_PRESENT));
*pte = pte_mkexec(*pte);
*pte = pte_wrprotect(*pte);
- spin_unlock(&mm->page_table_lock);
return(0);
out_pmd:
@@ -71,19 +70,17 @@ static int init_stub_pte(struct mm_struct *mm, unsigned long proc,
out_pte:
pmd_free(pmd);
out:
- spin_unlock(&mm->page_table_lock);
return(-ENOMEM);
}
int init_new_context_skas(struct task_struct *task, struct mm_struct *mm)
{
- struct mm_struct *cur_mm = current->mm;
- struct mm_id *cur_mm_id = &cur_mm->context.skas.id;
- struct mm_id *mm_id = &mm->context.skas.id;
+ struct mmu_context_skas *from_mm = NULL;
+ struct mmu_context_skas *to_mm = &mm->context.skas;
unsigned long stack = 0;
- int from, ret = -ENOMEM;
+ int from_fd, ret = -ENOMEM;
- if(!proc_mm || !ptrace_faultinfo){
+ if(skas_needs_stub){
stack = get_zeroed_page(GFP_KERNEL);
if(stack == 0)
goto out;
@@ -105,33 +102,43 @@ int init_new_context_skas(struct task_struct *task, struct mm_struct *mm)
mm->nr_ptes--;
}
- mm_id->stack = stack;
+
+ to_mm->id.stack = stack;
+ if(current->mm != NULL && current->mm != &init_mm)
+ from_mm = &current->mm->context.skas;
if(proc_mm){
- if((cur_mm != NULL) && (cur_mm != &init_mm))
- from = cur_mm_id->u.mm_fd;
- else from = -1;
+ if(from_mm)
+ from_fd = from_mm->id.u.mm_fd;
+ else from_fd = -1;
- ret = new_mm(from, stack);
+ ret = new_mm(from_fd, stack);
if(ret < 0){
printk("init_new_context_skas - new_mm failed, "
"errno = %d\n", ret);
goto out_free;
}
- mm_id->u.mm_fd = ret;
+ to_mm->id.u.mm_fd = ret;
}
else {
- if((cur_mm != NULL) && (cur_mm != &init_mm))
- mm_id->u.pid = copy_context_skas0(stack,
- cur_mm_id->u.pid);
- else mm_id->u.pid = start_userspace(stack);
+ if(from_mm)
+ to_mm->id.u.pid = copy_context_skas0(stack,
+ from_mm->id.u.pid);
+ else to_mm->id.u.pid = start_userspace(stack);
+ }
+
+ ret = init_new_ldt(to_mm, from_mm);
+ if(ret < 0){
+ printk("init_new_context_skas - init_ldt"
+ " failed, errno = %d\n", ret);
+ goto out_free;
}
return 0;
out_free:
- if(mm_id->stack != 0)
- free_page(mm_id->stack);
+ if(to_mm->id.stack != 0)
+ free_page(to_mm->id.stack);
out:
return ret;
}
@@ -147,6 +154,7 @@ void destroy_context_skas(struct mm_struct *mm)
if(!proc_mm || !ptrace_faultinfo){
free_page(mmu->id.stack);
+ pte_lock_deinit(virt_to_page(mmu->last_page_table));
pte_free_kernel((pte_t *) mmu->last_page_table);
dec_page_state(nr_page_table_pages);
#ifdef CONFIG_3_LEVEL_PGTABLES
diff --git a/arch/um/kernel/skas/process.c b/arch/um/kernel/skas/process.c
index 5cd0e9929789..599d679bd4fc 100644
--- a/arch/um/kernel/skas/process.c
+++ b/arch/um/kernel/skas/process.c
@@ -69,6 +69,17 @@ void wait_stub_done(int pid, int sig, char * fname)
if((n < 0) || !WIFSTOPPED(status) ||
(WSTOPSIG(status) != SIGUSR1 && WSTOPSIG(status) != SIGTRAP)){
+ unsigned long regs[FRAME_SIZE];
+ if(ptrace(PTRACE_GETREGS, pid, 0, regs) < 0)
+ printk("Failed to get registers from stub, "
+ "errno = %d\n", errno);
+ else {
+ int i;
+
+ printk("Stub registers -\n");
+ for(i = 0; i < FRAME_SIZE; i++)
+ printk("\t%d - %lx\n", i, regs[i]);
+ }
panic("%s : failed to wait for SIGUSR1/SIGTRAP, "
"pid = %d, n = %d, errno = %d, status = 0x%x\n",
fname, pid, n, errno, status);
@@ -370,9 +381,9 @@ int copy_context_skas0(unsigned long new_stack, int pid)
}
/*
- * This is used only, if proc_mm is available, while PTRACE_FAULTINFO
- * isn't. Opening /proc/mm creates a new mm_context, which lacks the stub-pages
- * Thus, we map them using /proc/mm-fd
+ * This is used only, if stub pages are needed, while proc_mm is
+ * availabl. Opening /proc/mm creates a new mm_context, which lacks
+ * the stub-pages. Thus, we map them using /proc/mm-fd
*/
void map_stub_pages(int fd, unsigned long code,
unsigned long data, unsigned long stack)
diff --git a/arch/um/kernel/skas/process_kern.c b/arch/um/kernel/skas/process_kern.c
index efe92e8aa2a9..9c990253966c 100644
--- a/arch/um/kernel/skas/process_kern.c
+++ b/arch/um/kernel/skas/process_kern.c
@@ -145,7 +145,7 @@ int new_mm(int from, unsigned long stack)
"err = %d\n", -n);
}
- if(!ptrace_faultinfo)
+ if(skas_needs_stub)
map_stub_pages(fd, CONFIG_STUB_CODE, CONFIG_STUB_DATA, stack);
return(fd);
diff --git a/arch/um/kernel/time_kern.c b/arch/um/kernel/time_kern.c
index 4e08f7545d63..020ca79b8d33 100644
--- a/arch/um/kernel/time_kern.c
+++ b/arch/um/kernel/time_kern.c
@@ -22,10 +22,6 @@
#include "mode.h"
#include "os.h"
-u64 jiffies_64 = INITIAL_JIFFIES;
-
-EXPORT_SYMBOL(jiffies_64);
-
int hz(void)
{
return(HZ);
diff --git a/arch/um/kernel/tt/tlb.c b/arch/um/kernel/tt/tlb.c
index f1d85dbb45b9..ae6217c86135 100644
--- a/arch/um/kernel/tt/tlb.c
+++ b/arch/um/kernel/tt/tlb.c
@@ -74,42 +74,6 @@ void flush_tlb_kernel_range_tt(unsigned long start, unsigned long end)
atomic_inc(&vmchange_seq);
}
-static void protect_vm_page(unsigned long addr, int w, int must_succeed)
-{
- int err;
-
- err = protect_memory(addr, PAGE_SIZE, 1, w, 1, must_succeed);
- if(err == 0) return;
- else if((err == -EFAULT) || (err == -ENOMEM)){
- flush_tlb_kernel_range(addr, addr + PAGE_SIZE);
- protect_vm_page(addr, w, 1);
- }
- else panic("protect_vm_page : protect failed, errno = %d\n", err);
-}
-
-void mprotect_kernel_vm(int w)
-{
- struct mm_struct *mm;
- pgd_t *pgd;
- pud_t *pud;
- pmd_t *pmd;
- pte_t *pte;
- unsigned long addr;
-
- mm = &init_mm;
- for(addr = start_vm; addr < end_vm;){
- pgd = pgd_offset(mm, addr);
- pud = pud_offset(pgd, addr);
- pmd = pmd_offset(pud, addr);
- if(pmd_present(*pmd)){
- pte = pte_offset_kernel(pmd, addr);
- if(pte_present(*pte)) protect_vm_page(addr, w, 0);
- addr += PAGE_SIZE;
- }
- else addr += PMD_SIZE;
- }
-}
-
void flush_tlb_kernel_vm_tt(void)
{
flush_tlb_kernel_range(start_vm, end_vm);
diff --git a/arch/um/kernel/tt/uaccess_user.c b/arch/um/kernel/tt/uaccess_user.c
index 8c220f054b61..6c92bbccb49c 100644
--- a/arch/um/kernel/tt/uaccess_user.c
+++ b/arch/um/kernel/tt/uaccess_user.c
@@ -10,6 +10,7 @@
#include "uml_uaccess.h"
#include "task.h"
#include "kern_util.h"
+#include "os.h"
int __do_copy_from_user(void *to, const void *from, int n,
void **fault_addr, void **fault_catcher)
diff --git a/arch/um/kernel/uaccess.c b/arch/um/kernel/uaccess.c
new file mode 100644
index 000000000000..054e3de0784e
--- /dev/null
+++ b/arch/um/kernel/uaccess.c
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2001 Chris Emerson (cemerson@chiark.greenend.org.uk)
+ * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
+ * Licensed under the GPL
+ */
+
+/* These are here rather than tt/uaccess.c because skas mode needs them in
+ * order to do SIGBUS recovery when a tmpfs mount runs out of room.
+ */
+
+#include <linux/string.h>
+#include "os.h"
+
+void __do_copy(void *to, const void *from, int n)
+{
+ memcpy(to, from, n);
+}
+
+
+int __do_copy_to_user(void *to, const void *from, int n,
+ void **fault_addr, void **fault_catcher)
+{
+ unsigned long fault;
+ int faulted;
+
+ fault = __do_user_copy(to, from, n, fault_addr, fault_catcher,
+ __do_copy, &faulted);
+ if(!faulted) return(0);
+ else return(n - (fault - (unsigned long) to));
+}
diff --git a/arch/um/kernel/uaccess_user.c b/arch/um/kernel/uaccess_user.c
deleted file mode 100644
index d035257ed0af..000000000000
--- a/arch/um/kernel/uaccess_user.c
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2001 Chris Emerson (cemerson@chiark.greenend.org.uk)
- * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
- * Licensed under the GPL
- */
-
-#include <setjmp.h>
-#include <string.h>
-
-/* These are here rather than tt/uaccess.c because skas mode needs them in
- * order to do SIGBUS recovery when a tmpfs mount runs out of room.
- */
-
-unsigned long __do_user_copy(void *to, const void *from, int n,
- void **fault_addr, void **fault_catcher,
- void (*op)(void *to, const void *from,
- int n), int *faulted_out)
-{
- unsigned long *faddrp = (unsigned long *) fault_addr, ret;
-
- sigjmp_buf jbuf;
- *fault_catcher = &jbuf;
- if(sigsetjmp(jbuf, 1) == 0){
- (*op)(to, from, n);
- ret = 0;
- *faulted_out = 0;
- }
- else {
- ret = *faddrp;
- *faulted_out = 1;
- }
- *fault_addr = NULL;
- *fault_catcher = NULL;
- return ret;
-}
-
-void __do_copy(void *to, const void *from, int n)
-{
- memcpy(to, from, n);
-}
-
-
-int __do_copy_to_user(void *to, const void *from, int n,
- void **fault_addr, void **fault_catcher)
-{
- unsigned long fault;
- int faulted;
-
- fault = __do_user_copy(to, from, n, fault_addr, fault_catcher,
- __do_copy, &faulted);
- if(!faulted) return(0);
- else return(n - (fault - (unsigned long) to));
-}
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c
index 93dc782dc1cc..142a9493912b 100644
--- a/arch/um/kernel/um_arch.c
+++ b/arch/um/kernel/um_arch.c
@@ -137,7 +137,7 @@ static char *argv1_end = NULL;
/* Set in early boot */
static int have_root __initdata = 0;
-long physmem_size = 32 * 1024 * 1024;
+long long physmem_size = 32 * 1024 * 1024;
void set_cmdline(char *cmd)
{
@@ -402,7 +402,7 @@ int linux_main(int argc, char **argv)
#ifndef CONFIG_HIGHMEM
highmem = 0;
printf("CONFIG_HIGHMEM not enabled - physical memory shrunk "
- "to %ld bytes\n", physmem_size);
+ "to %lu bytes\n", physmem_size);
#endif
}
@@ -414,8 +414,8 @@ int linux_main(int argc, char **argv)
setup_physmem(uml_physmem, uml_reserved, physmem_size, highmem);
if(init_maps(physmem_size, iomem_size, highmem)){
- printf("Failed to allocate mem_map for %ld bytes of physical "
- "memory and %ld bytes of highmem\n", physmem_size,
+ printf("Failed to allocate mem_map for %lu bytes of physical "
+ "memory and %lu bytes of highmem\n", physmem_size,
highmem);
exit(1);
}
@@ -426,7 +426,7 @@ int linux_main(int argc, char **argv)
end_vm = start_vm + virtmem_size;
if(virtmem_size < physmem_size)
- printf("Kernel virtual memory size shrunk to %ld bytes\n",
+ printf("Kernel virtual memory size shrunk to %lu bytes\n",
virtmem_size);
uml_postsetup();
diff --git a/arch/um/kernel/user_util.c b/arch/um/kernel/user_util.c
index 41d17c71511c..4c231161f257 100644
--- a/arch/um/kernel/user_util.c
+++ b/arch/um/kernel/user_util.c
@@ -27,7 +27,6 @@
#include "user.h"
#include "mem_user.h"
#include "init.h"
-#include "helper.h"
#include "ptrace_user.h"
#include "uml-config.h"
diff --git a/arch/um/os-Linux/Makefile b/arch/um/os-Linux/Makefile
index d15ec2af6a22..b83ac8e21c35 100644
--- a/arch/um/os-Linux/Makefile
+++ b/arch/um/os-Linux/Makefile
@@ -3,11 +3,12 @@
# Licensed under the GPL
#
-obj-y = aio.o elf_aux.o file.o mem.o process.o signal.o start_up.o time.o \
- tt.o tty.o user_syms.o drivers/ sys-$(SUBARCH)/
+obj-y = aio.o elf_aux.o file.o helper.o main.o mem.o process.o signal.o \
+ start_up.o time.o tt.o tty.o uaccess.o user_syms.o drivers/ \
+ sys-$(SUBARCH)/
-USER_OBJS := aio.o elf_aux.o file.o mem.o process.o signal.o start_up.o \
- time.o tt.o tty.o
+USER_OBJS := aio.o elf_aux.o file.o helper.o main.o mem.o process.o signal.o \
+ start_up.o time.o tt.o tty.o uaccess.o
elf_aux.o: $(ARCH_DIR)/kernel-offsets.h
CFLAGS_elf_aux.o += -I$(objtree)/arch/um
diff --git a/arch/um/os-Linux/aio.c b/arch/um/os-Linux/aio.c
index 41cfb0944201..ffa759addd3c 100644
--- a/arch/um/os-Linux/aio.c
+++ b/arch/um/os-Linux/aio.c
@@ -10,7 +10,6 @@
#include <sched.h>
#include <sys/syscall.h>
#include "os.h"
-#include "helper.h"
#include "aio.h"
#include "init.h"
#include "user.h"
diff --git a/arch/um/os-Linux/drivers/ethertap_user.c b/arch/um/os-Linux/drivers/ethertap_user.c
index cd4d6544da71..901b85e8a1c6 100644
--- a/arch/um/os-Linux/drivers/ethertap_user.c
+++ b/arch/um/os-Linux/drivers/ethertap_user.c
@@ -19,7 +19,6 @@
#include "user_util.h"
#include "net_user.h"
#include "etap.h"
-#include "helper.h"
#include "os.h"
#define MAX_PACKET ETH_MAX_PACKET
diff --git a/arch/um/os-Linux/drivers/tuntap_user.c b/arch/um/os-Linux/drivers/tuntap_user.c
index 4ba9b17adf13..52945338b64d 100644
--- a/arch/um/os-Linux/drivers/tuntap_user.c
+++ b/arch/um/os-Linux/drivers/tuntap_user.c
@@ -20,7 +20,6 @@
#include "kern_util.h"
#include "user_util.h"
#include "user.h"
-#include "helper.h"
#include "os.h"
#define MAX_PACKET ETH_MAX_PACKET
diff --git a/arch/um/kernel/helper.c b/arch/um/os-Linux/helper.c
index 33fb0bd3b11a..36cc8475bcda 100644
--- a/arch/um/kernel/helper.c
+++ b/arch/um/os-Linux/helper.c
@@ -1,4 +1,4 @@
-/*
+/*
* Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
* Licensed under the GPL
*/
@@ -13,7 +13,6 @@
#include "user.h"
#include "kern_util.h"
#include "user_util.h"
-#include "helper.h"
#include "os.h"
struct helper_data {
@@ -46,7 +45,7 @@ static int helper_child(void *arg)
errval = errno;
printk("execvp of '%s' failed - errno = %d\n", argv[0], errno);
os_write_file(data->fd, &errval, sizeof(errval));
- os_kill_process(os_getpid(), 0);
+ kill(os_getpid(), SIGKILL);
return(0);
}
@@ -90,7 +89,7 @@ int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv,
goto out_close;
}
- os_close_file(fds[1]);
+ close(fds[1]);
fds[1] = -1;
/*Read the errno value from the child.*/
@@ -98,7 +97,8 @@ int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv,
if(n < 0){
printk("run_helper : read on pipe failed, ret = %d\n", -n);
ret = n;
- os_kill_process(pid, 1);
+ kill(pid, SIGKILL);
+ CATCH_EINTR(waitpid(pid, NULL, 0));
}
else if(n != 0){
CATCH_EINTR(n = waitpid(pid, NULL, 0));
@@ -109,8 +109,8 @@ int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv,
out_close:
if (fds[1] != -1)
- os_close_file(fds[1]);
- os_close_file(fds[0]);
+ close(fds[1]);
+ close(fds[0]);
out_free:
if(stack_out == NULL)
free_stack(stack, 0);
@@ -118,7 +118,7 @@ out_free:
return(ret);
}
-int run_helper_thread(int (*proc)(void *), void *arg, unsigned int flags,
+int run_helper_thread(int (*proc)(void *), void *arg, unsigned int flags,
unsigned long *stack_out, int stack_order)
{
unsigned long stack, sp;
@@ -131,7 +131,7 @@ int run_helper_thread(int (*proc)(void *), void *arg, unsigned int flags,
pid = clone(proc, (void *) sp, flags | SIGCHLD, arg);
if(pid < 0){
err = -errno;
- printk("run_helper_thread : clone failed, errno = %d\n",
+ printk("run_helper_thread : clone failed, errno = %d\n",
errno);
return err;
}
diff --git a/arch/um/kernel/main.c b/arch/um/os-Linux/main.c
index d31027f0fe39..23da27d22569 100644
--- a/arch/um/kernel/main.c
+++ b/arch/um/os-Linux/main.c
@@ -157,25 +157,25 @@ int main(int argc, char **argv, char **envp)
*/
change_sig(SIGPROF, 0);
- /* This signal stuff used to be in the reboot case. However,
- * sometimes a SIGVTALRM can come in when we're halting (reproducably
- * when writing out gcov information, presumably because that takes
- * some time) and cause a segfault.
- */
-
- /* stop timers and set SIG*ALRM to be ignored */
- disable_timer();
-
- /* disable SIGIO for the fds and set SIGIO to be ignored */
- err = deactivate_all_fds();
- if(err)
- printf("deactivate_all_fds failed, errno = %d\n", -err);
-
- /* Let any pending signals fire now. This ensures
- * that they won't be delivered after the exec, when
- * they are definitely not expected.
- */
- unblock_signals();
+ /* This signal stuff used to be in the reboot case. However,
+ * sometimes a SIGVTALRM can come in when we're halting (reproducably
+ * when writing out gcov information, presumably because that takes
+ * some time) and cause a segfault.
+ */
+
+ /* stop timers and set SIG*ALRM to be ignored */
+ disable_timer();
+
+ /* disable SIGIO for the fds and set SIGIO to be ignored */
+ err = deactivate_all_fds();
+ if(err)
+ printf("deactivate_all_fds failed, errno = %d\n", -err);
+
+ /* Let any pending signals fire now. This ensures
+ * that they won't be delivered after the exec, when
+ * they are definitely not expected.
+ */
+ unblock_signals();
/* Reboot */
if(ret){
@@ -257,14 +257,3 @@ void __wrap_free(void *ptr)
}
else __real_free(ptr);
}
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/os-Linux/mem.c b/arch/um/os-Linux/mem.c
index 8e71edaaf80b..9d7d69a523bb 100644
--- a/arch/um/os-Linux/mem.c
+++ b/arch/um/os-Linux/mem.c
@@ -88,7 +88,7 @@ int make_tempfile(const char *template, char **out_tempname, int do_unlink)
* This proc is used in start_up.c
* So it isn't 'static'.
*/
-int create_tmp_file(unsigned long len)
+int create_tmp_file(unsigned long long len)
{
int fd, err;
char zero;
@@ -121,7 +121,7 @@ int create_tmp_file(unsigned long len)
return(fd);
}
-static int create_anon_file(unsigned long len)
+static int create_anon_file(unsigned long long len)
{
void *addr;
int fd;
@@ -144,7 +144,7 @@ static int create_anon_file(unsigned long len)
extern int have_devanon;
-int create_mem_file(unsigned long len)
+int create_mem_file(unsigned long long len)
{
int err, fd;
diff --git a/arch/um/os-Linux/start_up.c b/arch/um/os-Linux/start_up.c
index b99ab414542f..37517d49c4ae 100644
--- a/arch/um/os-Linux/start_up.c
+++ b/arch/um/os-Linux/start_up.c
@@ -135,7 +135,9 @@ static int stop_ptraced_child(int pid, void *stack, int exitcode,
}
int ptrace_faultinfo = 1;
+int ptrace_ldt = 1;
int proc_mm = 1;
+int skas_needs_stub = 0;
static int __init skas0_cmd_param(char *str, int* add)
{
@@ -294,7 +296,7 @@ static void __init check_ptrace(void)
check_sysemu();
}
-extern int create_tmp_file(unsigned long len);
+extern int create_tmp_file(unsigned long long len);
static void check_tmpexec(void)
{
@@ -352,14 +354,26 @@ __uml_setup("noptracefaultinfo", noptracefaultinfo_cmd_param,
" it. To support PTRACE_FAULTINFO, the host needs to be patched\n"
" using the current skas3 patch.\n\n");
+static int __init noptraceldt_cmd_param(char *str, int* add)
+{
+ ptrace_ldt = 0;
+ return 0;
+}
+
+__uml_setup("noptraceldt", noptraceldt_cmd_param,
+"noptraceldt\n"
+" Turns off usage of PTRACE_LDT, even if host supports it.\n"
+" To support PTRACE_LDT, the host needs to be patched using\n"
+" the current skas3 patch.\n\n");
+
#ifdef UML_CONFIG_MODE_SKAS
-static inline void check_skas3_ptrace_support(void)
+static inline void check_skas3_ptrace_faultinfo(void)
{
struct ptrace_faultinfo fi;
void *stack;
int pid, n;
- printf("Checking for the skas3 patch in the host...");
+ printf(" - PTRACE_FAULTINFO...");
pid = start_ptraced_child(&stack);
n = ptrace(PTRACE_FAULTINFO, pid, 0, &fi);
@@ -381,9 +395,49 @@ static inline void check_skas3_ptrace_support(void)
stop_ptraced_child(pid, stack, 1, 1);
}
-int can_do_skas(void)
+static inline void check_skas3_ptrace_ldt(void)
+{
+#ifdef PTRACE_LDT
+ void *stack;
+ int pid, n;
+ unsigned char ldtbuf[40];
+ struct ptrace_ldt ldt_op = (struct ptrace_ldt) {
+ .func = 2, /* read default ldt */
+ .ptr = ldtbuf,
+ .bytecount = sizeof(ldtbuf)};
+
+ printf(" - PTRACE_LDT...");
+ pid = start_ptraced_child(&stack);
+
+ n = ptrace(PTRACE_LDT, pid, 0, (unsigned long) &ldt_op);
+ if (n < 0) {
+ if(errno == EIO)
+ printf("not found\n");
+ else {
+ perror("not found");
+ }
+ ptrace_ldt = 0;
+ }
+ else {
+ if(ptrace_ldt)
+ printf("found\n");
+ else
+ printf("found, but use is disabled\n");
+ }
+
+ stop_ptraced_child(pid, stack, 1, 1);
+#else
+ /* PTRACE_LDT might be disabled via cmdline option.
+ * We want to override this, else we might use the stub
+ * without real need
+ */
+ ptrace_ldt = 1;
+#endif
+}
+
+static inline void check_skas3_proc_mm(void)
{
- printf("Checking for /proc/mm...");
+ printf(" - /proc/mm...");
if (os_access("/proc/mm", OS_ACC_W_OK) < 0) {
proc_mm = 0;
printf("not found\n");
@@ -394,8 +448,19 @@ int can_do_skas(void)
else
printf("found\n");
}
+}
+
+int can_do_skas(void)
+{
+ printf("Checking for the skas3 patch in the host:\n");
+
+ check_skas3_proc_mm();
+ check_skas3_ptrace_faultinfo();
+ check_skas3_ptrace_ldt();
+
+ if(!proc_mm || !ptrace_faultinfo || !ptrace_ldt)
+ skas_needs_stub = 1;
- check_skas3_ptrace_support();
return 1;
}
#else
diff --git a/arch/um/os-Linux/uaccess.c b/arch/um/os-Linux/uaccess.c
new file mode 100644
index 000000000000..38d710158c3d
--- /dev/null
+++ b/arch/um/os-Linux/uaccess.c
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2001 Chris Emerson (cemerson@chiark.greenend.org.uk)
+ * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
+ * Licensed under the GPL
+ */
+
+#include <setjmp.h>
+#include <string.h>
+
+unsigned long __do_user_copy(void *to, const void *from, int n,
+ void **fault_addr, void **fault_catcher,
+ void (*op)(void *to, const void *from,
+ int n), int *faulted_out)
+{
+ unsigned long *faddrp = (unsigned long *) fault_addr, ret;
+
+ sigjmp_buf jbuf;
+ *fault_catcher = &jbuf;
+ if(sigsetjmp(jbuf, 1) == 0){
+ (*op)(to, from, n);
+ ret = 0;
+ *faulted_out = 0;
+ }
+ else {
+ ret = *faddrp;
+ *faulted_out = 1;
+ }
+ *fault_addr = NULL;
+ *fault_catcher = NULL;
+ return ret;
+}
+
diff --git a/arch/um/scripts/Makefile.rules b/arch/um/scripts/Makefile.rules
index 651d9d88b656..b3fbf125709b 100644
--- a/arch/um/scripts/Makefile.rules
+++ b/arch/um/scripts/Makefile.rules
@@ -26,8 +26,13 @@ define unprofile
$(patsubst -pg,,$(patsubst -fprofile-arcs -ftest-coverage,,$(1)))
endef
+# cmd_make_link checks to see if the $(foo-dir) variable starts with a /. If
+# so, it's considered to be a path relative to $(srcdir) rather than
+# $(srcdir)/arch/$(SUBARCH). This is because x86_64 wants to get ldt.c from
+# arch/um/sys-i386 rather than arch/i386 like the other borrowed files. So,
+# it sets $(ldt.c-dir) to /arch/um/sys-i386.
quiet_cmd_make_link = SYMLINK $@
-cmd_make_link = ln -sf $(srctree)/arch/$(SUBARCH)/$($(notdir $@)-dir)/$(notdir $@) $@
+cmd_make_link = rm -f $@; ln -sf $(srctree)$(if $(filter-out /%,$($(notdir $@)-dir)),/arch/$(SUBARCH))/$($(notdir $@)-dir)/$(notdir $@) $@
# this needs to be before the foreach, because targets does not accept
# complete paths like $(obj)/$(f). To make sure this works, use a := assignment
diff --git a/arch/um/sys-i386/ldt.c b/arch/um/sys-i386/ldt.c
index 36b5c2c13289..6360f1c958d0 100644
--- a/arch/um/sys-i386/ldt.c
+++ b/arch/um/sys-i386/ldt.c
@@ -3,53 +3,26 @@
* Licensed under the GPL
*/
+#include "linux/stddef.h"
#include "linux/config.h"
#include "linux/sched.h"
#include "linux/slab.h"
#include "linux/types.h"
+#include "linux/errno.h"
#include "asm/uaccess.h"
-#include "asm/ptrace.h"
#include "asm/smp.h"
#include "asm/ldt.h"
+#include "asm/unistd.h"
#include "choose-mode.h"
#include "kern.h"
#include "mode_kern.h"
-#ifdef CONFIG_MODE_TT
-
extern int modify_ldt(int func, void *ptr, unsigned long bytecount);
-static int do_modify_ldt_tt(int func, void *ptr, unsigned long bytecount)
-{
- return modify_ldt(func, ptr, bytecount);
-}
-
-#endif
-
-#ifdef CONFIG_MODE_SKAS
-
-#include "skas.h"
-#include "skas_ptrace.h"
-
-static int do_modify_ldt_skas(int func, void *ptr, unsigned long bytecount)
-{
- struct ptrace_ldt ldt;
- u32 cpu;
- int res;
-
- ldt = ((struct ptrace_ldt) { .func = func,
- .ptr = ptr,
- .bytecount = bytecount });
-
- cpu = get_cpu();
- res = ptrace(PTRACE_LDT, userspace_pid[cpu], 0, (unsigned long) &ldt);
- put_cpu();
-
- return res;
-}
-#endif
+#ifdef CONFIG_MODE_TT
-int sys_modify_ldt(int func, void __user *ptr, unsigned long bytecount)
+static long do_modify_ldt_tt(int func, void __user *ptr,
+ unsigned long bytecount)
{
struct user_desc info;
int res = 0;
@@ -89,8 +62,7 @@ int sys_modify_ldt(int func, void __user *ptr, unsigned long bytecount)
goto out;
}
- res = CHOOSE_MODE_PROC(do_modify_ldt_tt, do_modify_ldt_skas, func,
- p, bytecount);
+ res = modify_ldt(func, p, bytecount);
if(res < 0)
goto out;
@@ -108,3 +80,467 @@ out:
kfree(buf);
return res;
}
+
+#endif
+
+#ifdef CONFIG_MODE_SKAS
+
+#include "skas.h"
+#include "skas_ptrace.h"
+#include "asm/mmu_context.h"
+
+long write_ldt_entry(struct mm_id * mm_idp, int func, struct user_desc * desc,
+ void **addr, int done)
+{
+ long res;
+
+ if(proc_mm){
+ /* This is a special handling for the case, that the mm to
+ * modify isn't current->active_mm.
+ * If this is called directly by modify_ldt,
+ * (current->active_mm->context.skas.u == mm_idp)
+ * will be true. So no call to switch_mm_skas(mm_idp) is done.
+ * If this is called in case of init_new_ldt or PTRACE_LDT,
+ * mm_idp won't belong to current->active_mm, but child->mm.
+ * So we need to switch child's mm into our userspace, then
+ * later switch back.
+ *
+ * Note: I'm unshure: should interrupts be disabled here?
+ */
+ if(!current->active_mm || current->active_mm == &init_mm ||
+ mm_idp != &current->active_mm->context.skas.id)
+ switch_mm_skas(mm_idp);
+ }
+
+ if(ptrace_ldt) {
+ struct ptrace_ldt ldt_op = (struct ptrace_ldt) {
+ .func = func,
+ .ptr = desc,
+ .bytecount = sizeof(*desc)};
+ u32 cpu;
+ int pid;
+
+ if(!proc_mm)
+ pid = mm_idp->u.pid;
+ else {
+ cpu = get_cpu();
+ pid = userspace_pid[cpu];
+ }
+
+ res = ptrace(PTRACE_LDT, pid, 0, (unsigned long) &ldt_op);
+ if(res)
+ res = errno;
+
+ if(proc_mm)
+ put_cpu();
+ }
+ else {
+ void *stub_addr;
+ res = syscall_stub_data(mm_idp, (unsigned long *)desc,
+ (sizeof(*desc) + sizeof(long) - 1) &
+ ~(sizeof(long) - 1),
+ addr, &stub_addr);
+ if(!res){
+ unsigned long args[] = { func,
+ (unsigned long)stub_addr,
+ sizeof(*desc),
+ 0, 0, 0 };
+ res = run_syscall_stub(mm_idp, __NR_modify_ldt, args,
+ 0, addr, done);
+ }
+ }
+
+ if(proc_mm){
+ /* This is the second part of special handling, that makes
+ * PTRACE_LDT possible to implement.
+ */
+ if(current->active_mm && current->active_mm != &init_mm &&
+ mm_idp != &current->active_mm->context.skas.id)
+ switch_mm_skas(&current->active_mm->context.skas.id);
+ }
+
+ return res;
+}
+
+static long read_ldt_from_host(void __user * ptr, unsigned long bytecount)
+{
+ int res, n;
+ struct ptrace_ldt ptrace_ldt = (struct ptrace_ldt) {
+ .func = 0,
+ .bytecount = bytecount,
+ .ptr = (void *)kmalloc(bytecount, GFP_KERNEL)};
+ u32 cpu;
+
+ if(ptrace_ldt.ptr == NULL)
+ return -ENOMEM;
+
+ /* This is called from sys_modify_ldt only, so userspace_pid gives
+ * us the right number
+ */
+
+ cpu = get_cpu();
+ res = ptrace(PTRACE_LDT, userspace_pid[cpu], 0,
+ (unsigned long) &ptrace_ldt);
+ put_cpu();
+ if(res < 0)
+ goto out;
+
+ n = copy_to_user(ptr, ptrace_ldt.ptr, res);
+ if(n != 0)
+ res = -EFAULT;
+
+ out:
+ kfree(ptrace_ldt.ptr);
+
+ return res;
+}
+
+/*
+ * In skas mode, we hold our own ldt data in UML.
+ * Thus, the code implementing sys_modify_ldt_skas
+ * is very similar to (and mostly stolen from) sys_modify_ldt
+ * for arch/i386/kernel/ldt.c
+ * The routines copied and modified in part are:
+ * - read_ldt
+ * - read_default_ldt
+ * - write_ldt
+ * - sys_modify_ldt_skas
+ */
+
+static int read_ldt(void __user * ptr, unsigned long bytecount)
+{
+ int i, err = 0;
+ unsigned long size;
+ uml_ldt_t * ldt = &current->mm->context.skas.ldt;
+
+ if(!ldt->entry_count)
+ goto out;
+ if(bytecount > LDT_ENTRY_SIZE*LDT_ENTRIES)
+ bytecount = LDT_ENTRY_SIZE*LDT_ENTRIES;
+ err = bytecount;
+
+ if(ptrace_ldt){
+ return read_ldt_from_host(ptr, bytecount);
+ }
+
+ down(&ldt->semaphore);
+ if(ldt->entry_count <= LDT_DIRECT_ENTRIES){
+ size = LDT_ENTRY_SIZE*LDT_DIRECT_ENTRIES;
+ if(size > bytecount)
+ size = bytecount;
+ if(copy_to_user(ptr, ldt->entries, size))
+ err = -EFAULT;
+ bytecount -= size;
+ ptr += size;
+ }
+ else {
+ for(i=0; i<ldt->entry_count/LDT_ENTRIES_PER_PAGE && bytecount;
+ i++){
+ size = PAGE_SIZE;
+ if(size > bytecount)
+ size = bytecount;
+ if(copy_to_user(ptr, ldt->pages[i], size)){
+ err = -EFAULT;
+ break;
+ }
+ bytecount -= size;
+ ptr += size;
+ }
+ }
+ up(&ldt->semaphore);
+
+ if(bytecount == 0 || err == -EFAULT)
+ goto out;
+
+ if(clear_user(ptr, bytecount))
+ err = -EFAULT;
+
+out:
+ return err;
+}
+
+static int read_default_ldt(void __user * ptr, unsigned long bytecount)
+{
+ int err;
+
+ if(bytecount > 5*LDT_ENTRY_SIZE)
+ bytecount = 5*LDT_ENTRY_SIZE;
+
+ err = bytecount;
+ /* UML doesn't support lcall7 and lcall27.
+ * So, we don't really have a default ldt, but emulate
+ * an empty ldt of common host default ldt size.
+ */
+ if(clear_user(ptr, bytecount))
+ err = -EFAULT;
+
+ return err;
+}
+
+static int write_ldt(void __user * ptr, unsigned long bytecount, int func)
+{
+ uml_ldt_t * ldt = &current->mm->context.skas.ldt;
+ struct mm_id * mm_idp = &current->mm->context.skas.id;
+ int i, err;
+ struct user_desc ldt_info;
+ struct ldt_entry entry0, *ldt_p;
+ void *addr = NULL;
+
+ err = -EINVAL;
+ if(bytecount != sizeof(ldt_info))
+ goto out;
+ err = -EFAULT;
+ if(copy_from_user(&ldt_info, ptr, sizeof(ldt_info)))
+ goto out;
+
+ err = -EINVAL;
+ if(ldt_info.entry_number >= LDT_ENTRIES)
+ goto out;
+ if(ldt_info.contents == 3){
+ if (func == 1)
+ goto out;
+ if (ldt_info.seg_not_present == 0)
+ goto out;
+ }
+
+ if(!ptrace_ldt)
+ down(&ldt->semaphore);
+
+ err = write_ldt_entry(mm_idp, func, &ldt_info, &addr, 1);
+ if(err)
+ goto out_unlock;
+ else if(ptrace_ldt) {
+ /* With PTRACE_LDT available, this is used as a flag only */
+ ldt->entry_count = 1;
+ goto out;
+ }
+
+ if(ldt_info.entry_number >= ldt->entry_count &&
+ ldt_info.entry_number >= LDT_DIRECT_ENTRIES){
+ for(i=ldt->entry_count/LDT_ENTRIES_PER_PAGE;
+ i*LDT_ENTRIES_PER_PAGE <= ldt_info.entry_number;
+ i++){
+ if(i == 0)
+ memcpy(&entry0, ldt->entries, sizeof(entry0));
+ ldt->pages[i] = (struct ldt_entry *)
+ __get_free_page(GFP_KERNEL|__GFP_ZERO);
+ if(!ldt->pages[i]){
+ err = -ENOMEM;
+ /* Undo the change in host */
+ memset(&ldt_info, 0, sizeof(ldt_info));
+ write_ldt_entry(mm_idp, 1, &ldt_info, &addr, 1);
+ goto out_unlock;
+ }
+ if(i == 0) {
+ memcpy(ldt->pages[0], &entry0, sizeof(entry0));
+ memcpy(ldt->pages[0]+1, ldt->entries+1,
+ sizeof(entry0)*(LDT_DIRECT_ENTRIES-1));
+ }
+ ldt->entry_count = (i + 1) * LDT_ENTRIES_PER_PAGE;
+ }
+ }
+ if(ldt->entry_count <= ldt_info.entry_number)
+ ldt->entry_count = ldt_info.entry_number + 1;
+
+ if(ldt->entry_count <= LDT_DIRECT_ENTRIES)
+ ldt_p = ldt->entries + ldt_info.entry_number;
+ else
+ ldt_p = ldt->pages[ldt_info.entry_number/LDT_ENTRIES_PER_PAGE] +
+ ldt_info.entry_number%LDT_ENTRIES_PER_PAGE;
+
+ if(ldt_info.base_addr == 0 && ldt_info.limit == 0 &&
+ (func == 1 || LDT_empty(&ldt_info))){
+ ldt_p->a = 0;
+ ldt_p->b = 0;
+ }
+ else{
+ if (func == 1)
+ ldt_info.useable = 0;
+ ldt_p->a = LDT_entry_a(&ldt_info);
+ ldt_p->b = LDT_entry_b(&ldt_info);
+ }
+ err = 0;
+
+out_unlock:
+ up(&ldt->semaphore);
+out:
+ return err;
+}
+
+static long do_modify_ldt_skas(int func, void __user *ptr,
+ unsigned long bytecount)
+{
+ int ret = -ENOSYS;
+
+ switch (func) {
+ case 0:
+ ret = read_ldt(ptr, bytecount);
+ break;
+ case 1:
+ case 0x11:
+ ret = write_ldt(ptr, bytecount, func);
+ break;
+ case 2:
+ ret = read_default_ldt(ptr, bytecount);
+ break;
+ }
+ return ret;
+}
+
+short dummy_list[9] = {0, -1};
+short * host_ldt_entries = NULL;
+
+void ldt_get_host_info(void)
+{
+ long ret;
+ struct ldt_entry * ldt;
+ int i, size, k, order;
+
+ host_ldt_entries = dummy_list+1;
+
+ for(i = LDT_PAGES_MAX-1, order=0; i; i>>=1, order++);
+
+ ldt = (struct ldt_entry *)
+ __get_free_pages(GFP_KERNEL|__GFP_ZERO, order);
+ if(ldt == NULL) {
+ printk("ldt_get_host_info: couldn't allocate buffer for host ldt\n");
+ return;
+ }
+
+ ret = modify_ldt(0, ldt, (1<<order)*PAGE_SIZE);
+ if(ret < 0) {
+ printk("ldt_get_host_info: couldn't read host ldt\n");
+ goto out_free;
+ }
+ if(ret == 0) {
+ /* default_ldt is active, simply write an empty entry 0 */
+ host_ldt_entries = dummy_list;
+ goto out_free;
+ }
+
+ for(i=0, size=0; i<ret/LDT_ENTRY_SIZE; i++){
+ if(ldt[i].a != 0 || ldt[i].b != 0)
+ size++;
+ }
+
+ if(size < sizeof(dummy_list)/sizeof(dummy_list[0])) {
+ host_ldt_entries = dummy_list;
+ }
+ else {
+ size = (size + 1) * sizeof(dummy_list[0]);
+ host_ldt_entries = (short *)kmalloc(size, GFP_KERNEL);
+ if(host_ldt_entries == NULL) {
+ printk("ldt_get_host_info: couldn't allocate host ldt list\n");
+ goto out_free;
+ }
+ }
+
+ for(i=0, k=0; i<ret/LDT_ENTRY_SIZE; i++){
+ if(ldt[i].a != 0 || ldt[i].b != 0) {
+ host_ldt_entries[k++] = i;
+ }
+ }
+ host_ldt_entries[k] = -1;
+
+out_free:
+ free_pages((unsigned long)ldt, order);
+}
+
+long init_new_ldt(struct mmu_context_skas * new_mm,
+ struct mmu_context_skas * from_mm)
+{
+ struct user_desc desc;
+ short * num_p;
+ int i;
+ long page, err=0;
+ void *addr = NULL;
+
+ memset(&desc, 0, sizeof(desc));
+
+ if(!ptrace_ldt)
+ init_MUTEX(&new_mm->ldt.semaphore);
+
+ if(!from_mm){
+ /*
+ * We have to initialize a clean ldt.
+ */
+ if(proc_mm) {
+ /*
+ * If the new mm was created using proc_mm, host's
+ * default-ldt currently is assigned, which normally
+ * contains the call-gates for lcall7 and lcall27.
+ * To remove these gates, we simply write an empty
+ * entry as number 0 to the host.
+ */
+ err = write_ldt_entry(&new_mm->id, 1, &desc,
+ &addr, 1);
+ }
+ else{
+ /*
+ * Now we try to retrieve info about the ldt, we
+ * inherited from the host. All ldt-entries found
+ * will be reset in the following loop
+ */
+ if(host_ldt_entries == NULL)
+ ldt_get_host_info();
+ for(num_p=host_ldt_entries; *num_p != -1; num_p++){
+ desc.entry_number = *num_p;
+ err = write_ldt_entry(&new_mm->id, 1, &desc,
+ &addr, *(num_p + 1) == -1);
+ if(err)
+ break;
+ }
+ }
+ new_mm->ldt.entry_count = 0;
+ }
+ else if (!ptrace_ldt) {
+ /* Our local LDT is used to supply the data for
+ * modify_ldt(READLDT), if PTRACE_LDT isn't available,
+ * i.e., we have to use the stub for modify_ldt, which
+ * can't handle the big read buffer of up to 64kB.
+ */
+ down(&from_mm->ldt.semaphore);
+ if(from_mm->ldt.entry_count <= LDT_DIRECT_ENTRIES){
+ memcpy(new_mm->ldt.entries, from_mm->ldt.entries,
+ sizeof(new_mm->ldt.entries));
+ }
+ else{
+ i = from_mm->ldt.entry_count / LDT_ENTRIES_PER_PAGE;
+ while(i-->0){
+ page = __get_free_page(GFP_KERNEL|__GFP_ZERO);
+ if (!page){
+ err = -ENOMEM;
+ break;
+ }
+ new_mm->ldt.pages[i] = (struct ldt_entry*)page;
+ memcpy(new_mm->ldt.pages[i],
+ from_mm->ldt.pages[i], PAGE_SIZE);
+ }
+ }
+ new_mm->ldt.entry_count = from_mm->ldt.entry_count;
+ up(&from_mm->ldt.semaphore);
+ }
+
+ return err;
+}
+
+
+void free_ldt(struct mmu_context_skas * mm)
+{
+ int i;
+
+ if(!ptrace_ldt && mm->ldt.entry_count > LDT_DIRECT_ENTRIES){
+ i = mm->ldt.entry_count / LDT_ENTRIES_PER_PAGE;
+ while(i-- > 0){
+ free_page((long )mm->ldt.pages[i]);
+ }
+ }
+ mm->ldt.entry_count = 0;
+}
+#endif
+
+int sys_modify_ldt(int func, void __user *ptr, unsigned long bytecount)
+{
+ return(CHOOSE_MODE_PROC(do_modify_ldt_tt, do_modify_ldt_skas, func,
+ ptr, bytecount));
+}
diff --git a/arch/um/sys-x86_64/Makefile b/arch/um/sys-x86_64/Makefile
index 06c3633457a2..ea977df395a1 100644
--- a/arch/um/sys-x86_64/Makefile
+++ b/arch/um/sys-x86_64/Makefile
@@ -5,7 +5,7 @@
#
#XXX: why into lib-y?
-lib-y = bitops.o bugs.o csum-partial.o delay.o fault.o mem.o memcpy.o \
+lib-y = bitops.o bugs.o csum-partial.o delay.o fault.o ldt.o mem.o memcpy.o \
ptrace.o ptrace_user.o sigcontext.o signal.o stub.o \
stub_segv.o syscalls.o syscall_table.o sysrq.o thunk.o
@@ -14,7 +14,7 @@ obj-$(CONFIG_MODULES) += module.o um_module.o
USER_OBJS := ptrace_user.o sigcontext.o
-SYMLINKS = bitops.c csum-copy.S csum-partial.c csum-wrappers.c memcpy.S \
+SYMLINKS = bitops.c csum-copy.S csum-partial.c csum-wrappers.c ldt.c memcpy.S \
thunk.S module.c
include arch/um/scripts/Makefile.rules
@@ -23,6 +23,7 @@ bitops.c-dir = lib
csum-copy.S-dir = lib
csum-partial.c-dir = lib
csum-wrappers.c-dir = lib
+ldt.c-dir = /arch/um/sys-i386
memcpy.S-dir = lib
thunk.S-dir = lib
module.c-dir = kernel
diff --git a/arch/um/sys-x86_64/syscalls.c b/arch/um/sys-x86_64/syscalls.c
index 3259a4db4534..6acee5c4ada6 100644
--- a/arch/um/sys-x86_64/syscalls.c
+++ b/arch/um/sys-x86_64/syscalls.c
@@ -29,81 +29,6 @@ asmlinkage long sys_uname64(struct new_utsname __user * name)
}
#ifdef CONFIG_MODE_TT
-extern int modify_ldt(int func, void *ptr, unsigned long bytecount);
-
-long sys_modify_ldt_tt(int func, void *ptr, unsigned long bytecount)
-{
- /* XXX This should check VERIFY_WRITE depending on func, check this
- * in i386 as well.
- */
- if (!access_ok(VERIFY_READ, ptr, bytecount))
- return -EFAULT;
- return(modify_ldt(func, ptr, bytecount));
-}
-#endif
-
-#ifdef CONFIG_MODE_SKAS
-extern int userspace_pid[];
-
-#include "skas_ptrace.h"
-
-long sys_modify_ldt_skas(int func, void *ptr, unsigned long bytecount)
-{
- struct ptrace_ldt ldt;
- void *buf;
- int res, n;
-
- buf = kmalloc(bytecount, GFP_KERNEL);
- if(buf == NULL)
- return(-ENOMEM);
-
- res = 0;
-
- switch(func){
- case 1:
- case 0x11:
- res = copy_from_user(buf, ptr, bytecount);
- break;
- }
-
- if(res != 0){
- res = -EFAULT;
- goto out;
- }
-
- ldt = ((struct ptrace_ldt) { .func = func,
- .ptr = buf,
- .bytecount = bytecount });
-#warning Need to look up userspace_pid by cpu
- res = ptrace(PTRACE_LDT, userspace_pid[0], 0, (unsigned long) &ldt);
- if(res < 0)
- goto out;
-
- switch(func){
- case 0:
- case 2:
- n = res;
- res = copy_to_user(ptr, buf, n);
- if(res != 0)
- res = -EFAULT;
- else
- res = n;
- break;
- }
-
- out:
- kfree(buf);
- return(res);
-}
-#endif
-
-long sys_modify_ldt(int func, void *ptr, unsigned long bytecount)
-{
- return(CHOOSE_MODE_PROC(sys_modify_ldt_tt, sys_modify_ldt_skas, func,
- ptr, bytecount));
-}
-
-#ifdef CONFIG_MODE_TT
extern long arch_prctl(int code, unsigned long addr);
static long arch_prctl_tt(int code, unsigned long addr)
diff --git a/arch/v850/kernel/process.c b/arch/v850/kernel/process.c
index 9c708c32c1f0..39cf247cdae4 100644
--- a/arch/v850/kernel/process.c
+++ b/arch/v850/kernel/process.c
@@ -36,11 +36,8 @@ extern void ret_from_fork (void);
/* The idle loop. */
void default_idle (void)
{
- while (1) {
- while (! need_resched ())
- asm ("halt; nop; nop; nop; nop; nop" ::: "cc");
- schedule ();
- }
+ while (! need_resched ())
+ asm ("halt; nop; nop; nop; nop; nop" ::: "cc");
}
void (*idle)(void) = default_idle;
@@ -54,7 +51,14 @@ void (*idle)(void) = default_idle;
void cpu_idle (void)
{
/* endless idle loop with no priority at all */
- (*idle) ();
+ while (1) {
+ while (!need_resched())
+ (*idle) ();
+
+ preempt_enable_no_resched();
+ schedule();
+ preempt_disable();
+ }
}
/*
diff --git a/arch/v850/kernel/ptrace.c b/arch/v850/kernel/ptrace.c
index 4726b87f5e5a..18492d02aaf6 100644
--- a/arch/v850/kernel/ptrace.c
+++ b/arch/v850/kernel/ptrace.c
@@ -113,45 +113,10 @@ static int set_single_step (struct task_struct *t, int val)
return 1;
}
-int sys_ptrace(long request, long pid, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request, long addr, long data)
{
- struct task_struct *child;
int rval;
- lock_kernel();
-
- if (request == PTRACE_TRACEME) {
- /* are we already being traced? */
- if (current->ptrace & PT_PTRACED) {
- rval = -EPERM;
- goto out;
- }
- /* set the ptrace bit in the process flags. */
- current->ptrace |= PT_PTRACED;
- rval = 0;
- goto out;
- }
- rval = -ESRCH;
- read_lock(&tasklist_lock);
- child = find_task_by_pid(pid);
- if (child)
- get_task_struct(child);
- read_unlock(&tasklist_lock);
- if (!child)
- goto out;
-
- rval = -EPERM;
- if (pid == 1) /* you may not mess with init */
- goto out_tsk;
-
- if (request == PTRACE_ATTACH) {
- rval = ptrace_attach(child);
- goto out_tsk;
- }
- rval = ptrace_check_attach(child, request == PTRACE_KILL);
- if (rval < 0)
- goto out_tsk;
-
switch (request) {
unsigned long val, copied;
@@ -248,11 +213,7 @@ int sys_ptrace(long request, long pid, long addr, long data)
rval = -EIO;
goto out;
}
-
-out_tsk:
- put_task_struct(child);
-out:
- unlock_kernel();
+ out:
return rval;
}
diff --git a/arch/v850/kernel/time.c b/arch/v850/kernel/time.c
index ea3fd8844ff0..c1e85c2aef65 100644
--- a/arch/v850/kernel/time.c
+++ b/arch/v850/kernel/time.c
@@ -26,10 +26,6 @@
#include "mach.h"
-u64 jiffies_64 = INITIAL_JIFFIES;
-
-EXPORT_SYMBOL(jiffies_64);
-
#define TICK_SIZE (tick_nsec / 1000)
/*
diff --git a/arch/x86_64/Kconfig b/arch/x86_64/Kconfig
index 21afa69a086d..4cce2f6f170c 100644
--- a/arch/x86_64/Kconfig
+++ b/arch/x86_64/Kconfig
@@ -532,8 +532,21 @@ source "drivers/firmware/Kconfig"
source fs/Kconfig
+menu "Instrumentation Support"
+ depends on EXPERIMENTAL
+
source "arch/x86_64/oprofile/Kconfig"
+config KPROBES
+ bool "Kprobes (EXPERIMENTAL)"
+ help
+ Kprobes allows you to trap at almost any kernel address and
+ execute a callback function. register_kprobe() establishes
+ a probepoint and specifies the callback. Kprobes is useful
+ for kernel debugging, non-intrusive instrumentation and testing.
+ If in doubt, say "N".
+endmenu
+
source "arch/x86_64/Kconfig.debug"
source "security/Kconfig"
diff --git a/arch/x86_64/Kconfig.debug b/arch/x86_64/Kconfig.debug
index 9cf1410d2f5a..d584ecc27ea1 100644
--- a/arch/x86_64/Kconfig.debug
+++ b/arch/x86_64/Kconfig.debug
@@ -33,16 +33,6 @@ config IOMMU_DEBUG
options. See Documentation/x86_64/boot-options.txt for more
details.
-config KPROBES
- bool "Kprobes"
- depends on DEBUG_KERNEL
- help
- Kprobes allows you to trap at almost any kernel address and
- execute a callback function. register_kprobe() establishes
- a probepoint and specifies the callback. Kprobes is useful
- for kernel debugging, non-intrusive instrumentation and testing.
- If in doubt, say "N".
-
config IOMMU_LEAK
bool "IOMMU leak tracing"
depends on DEBUG_KERNEL
diff --git a/arch/x86_64/ia32/ia32_aout.c b/arch/x86_64/ia32/ia32_aout.c
index 3e6780fa0186..93c60f4aa47a 100644
--- a/arch/x86_64/ia32/ia32_aout.c
+++ b/arch/x86_64/ia32/ia32_aout.c
@@ -314,7 +314,6 @@ static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs)
current->mm->free_area_cache = TASK_UNMAPPED_BASE;
current->mm->cached_hole_size = 0;
- set_mm_counter(current->mm, rss, 0);
current->mm->mmap = NULL;
compute_creds(bprm);
current->flags &= ~PF_FORKNOEXEC;
diff --git a/arch/x86_64/ia32/ia32_ioctl.c b/arch/x86_64/ia32/ia32_ioctl.c
index 419758f19ca4..e335bd0b637d 100644
--- a/arch/x86_64/ia32/ia32_ioctl.c
+++ b/arch/x86_64/ia32/ia32_ioctl.c
@@ -12,40 +12,11 @@
#define INCLUDES
#include <linux/syscalls.h>
#include "compat_ioctl.c"
-#include <asm/mtrr.h>
#include <asm/ia32.h>
#define CODE
#include "compat_ioctl.c"
-#ifndef TIOCGDEV
-#define TIOCGDEV _IOR('T',0x32, unsigned int)
-#endif
-static int tiocgdev(unsigned fd, unsigned cmd, unsigned int __user *ptr)
-{
-
- struct file *file;
- struct tty_struct *real_tty;
- int fput_needed, ret;
-
- file = fget_light(fd, &fput_needed);
- if (!file)
- return -EBADF;
-
- ret = -EINVAL;
- if (file->f_op->ioctl != tty_ioctl)
- goto out;
- real_tty = (struct tty_struct *)file->private_data;
- if (!real_tty)
- goto out;
-
- ret = put_user(new_encode_dev(tty_devnum(real_tty)), ptr);
-
-out:
- fput_light(file, fput_needed);
- return ret;
-}
-
#define RTC_IRQP_READ32 _IOR('p', 0x0b, unsigned int) /* Read IRQ rate */
#define RTC_IRQP_SET32 _IOW('p', 0x0c, unsigned int) /* Set IRQ rate */
#define RTC_EPOCH_READ32 _IOR('p', 0x0d, unsigned) /* Read epoch */
@@ -85,90 +56,6 @@ static int rtc32_ioctl(unsigned fd, unsigned cmd, unsigned long arg)
return sys_ioctl(fd,cmd,arg);
}
-/* /proc/mtrr ioctls */
-
-
-struct mtrr_sentry32
-{
- compat_ulong_t base; /* Base address */
- compat_uint_t size; /* Size of region */
- compat_uint_t type; /* Type of region */
-};
-
-struct mtrr_gentry32
-{
- compat_ulong_t regnum; /* Register number */
- compat_uint_t base; /* Base address */
- compat_uint_t size; /* Size of region */
- compat_uint_t type; /* Type of region */
-};
-
-#define MTRR_IOCTL_BASE 'M'
-
-#define MTRRIOC32_ADD_ENTRY _IOW(MTRR_IOCTL_BASE, 0, struct mtrr_sentry32)
-#define MTRRIOC32_SET_ENTRY _IOW(MTRR_IOCTL_BASE, 1, struct mtrr_sentry32)
-#define MTRRIOC32_DEL_ENTRY _IOW(MTRR_IOCTL_BASE, 2, struct mtrr_sentry32)
-#define MTRRIOC32_GET_ENTRY _IOWR(MTRR_IOCTL_BASE, 3, struct mtrr_gentry32)
-#define MTRRIOC32_KILL_ENTRY _IOW(MTRR_IOCTL_BASE, 4, struct mtrr_sentry32)
-#define MTRRIOC32_ADD_PAGE_ENTRY _IOW(MTRR_IOCTL_BASE, 5, struct mtrr_sentry32)
-#define MTRRIOC32_SET_PAGE_ENTRY _IOW(MTRR_IOCTL_BASE, 6, struct mtrr_sentry32)
-#define MTRRIOC32_DEL_PAGE_ENTRY _IOW(MTRR_IOCTL_BASE, 7, struct mtrr_sentry32)
-#define MTRRIOC32_GET_PAGE_ENTRY _IOWR(MTRR_IOCTL_BASE, 8, struct mtrr_gentry32)
-#define MTRRIOC32_KILL_PAGE_ENTRY _IOW(MTRR_IOCTL_BASE, 9, struct mtrr_sentry32)
-
-
-static int mtrr_ioctl32(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- struct mtrr_gentry g;
- struct mtrr_sentry s;
- int get = 0, err = 0;
- struct mtrr_gentry32 __user *g32 = (struct mtrr_gentry32 __user *)arg;
- mm_segment_t oldfs = get_fs();
-
- switch (cmd) {
-#define SET(x) case MTRRIOC32_ ## x ## _ENTRY: cmd = MTRRIOC_ ## x ## _ENTRY; break
-#define GET(x) case MTRRIOC32_ ## x ## _ENTRY: cmd = MTRRIOC_ ## x ## _ENTRY; get=1; break
- SET(ADD);
- SET(SET);
- SET(DEL);
- GET(GET);
- SET(KILL);
- SET(ADD_PAGE);
- SET(SET_PAGE);
- SET(DEL_PAGE);
- GET(GET_PAGE);
- SET(KILL_PAGE);
- }
-
- if (get) {
- err = get_user(g.regnum, &g32->regnum);
- err |= get_user(g.base, &g32->base);
- err |= get_user(g.size, &g32->size);
- err |= get_user(g.type, &g32->type);
-
- arg = (unsigned long)&g;
- } else {
- struct mtrr_sentry32 __user *s32 = (struct mtrr_sentry32 __user *)arg;
- err = get_user(s.base, &s32->base);
- err |= get_user(s.size, &s32->size);
- err |= get_user(s.type, &s32->type);
-
- arg = (unsigned long)&s;
- }
- if (err) return err;
-
- set_fs(KERNEL_DS);
- err = sys_ioctl(fd, cmd, arg);
- set_fs(oldfs);
-
- if (!err && get) {
- err = put_user(g.base, &g32->base);
- err |= put_user(g.size, &g32->size);
- err |= put_user(g.regnum, &g32->regnum);
- err |= put_user(g.type, &g32->type);
- }
- return err;
-}
#define HANDLE_IOCTL(cmd,handler) { (cmd), (ioctl_trans_handler_t)(handler) },
#define COMPATIBLE_IOCTL(cmd) HANDLE_IOCTL(cmd,sys_ioctl)
@@ -177,15 +64,8 @@ struct ioctl_trans ioctl_start[] = {
#include <linux/compat_ioctl.h>
#define DECLARES
#include "compat_ioctl.c"
-COMPATIBLE_IOCTL(HDIO_SET_KEEPSETTINGS)
-COMPATIBLE_IOCTL(HDIO_SCAN_HWIF)
-COMPATIBLE_IOCTL(BLKRASET)
-COMPATIBLE_IOCTL(0x4B50) /* KDGHWCLK - not in the kernel, but don't complain */
-COMPATIBLE_IOCTL(0x4B51) /* KDSHWCLK - not in the kernel, but don't complain */
-COMPATIBLE_IOCTL(FIOQSIZE)
/* And these ioctls need translation */
-HANDLE_IOCTL(TIOCGDEV, tiocgdev)
/* realtime device */
HANDLE_IOCTL(RTC_IRQP_READ, rtc32_ioctl)
HANDLE_IOCTL(RTC_IRQP_READ32,rtc32_ioctl)
@@ -193,17 +73,6 @@ HANDLE_IOCTL(RTC_IRQP_SET32, rtc32_ioctl)
HANDLE_IOCTL(RTC_EPOCH_READ32, rtc32_ioctl)
HANDLE_IOCTL(RTC_EPOCH_SET32, rtc32_ioctl)
/* take care of sizeof(sizeof()) breakage */
-/* mtrr */
-HANDLE_IOCTL(MTRRIOC32_ADD_ENTRY, mtrr_ioctl32)
-HANDLE_IOCTL(MTRRIOC32_SET_ENTRY, mtrr_ioctl32)
-HANDLE_IOCTL(MTRRIOC32_DEL_ENTRY, mtrr_ioctl32)
-HANDLE_IOCTL(MTRRIOC32_GET_ENTRY, mtrr_ioctl32)
-HANDLE_IOCTL(MTRRIOC32_KILL_ENTRY, mtrr_ioctl32)
-HANDLE_IOCTL(MTRRIOC32_ADD_PAGE_ENTRY, mtrr_ioctl32)
-HANDLE_IOCTL(MTRRIOC32_SET_PAGE_ENTRY, mtrr_ioctl32)
-HANDLE_IOCTL(MTRRIOC32_DEL_PAGE_ENTRY, mtrr_ioctl32)
-HANDLE_IOCTL(MTRRIOC32_GET_PAGE_ENTRY, mtrr_ioctl32)
-HANDLE_IOCTL(MTRRIOC32_KILL_PAGE_ENTRY, mtrr_ioctl32)
};
int ioctl_table_size = ARRAY_SIZE(ioctl_start);
diff --git a/arch/x86_64/kernel/Makefile b/arch/x86_64/kernel/Makefile
index bcdd0a805fe7..14328cab5d3a 100644
--- a/arch/x86_64/kernel/Makefile
+++ b/arch/x86_64/kernel/Makefile
@@ -27,7 +27,6 @@ obj-$(CONFIG_CPU_FREQ) += cpufreq/
obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
obj-$(CONFIG_GART_IOMMU) += pci-gart.o aperture.o
obj-$(CONFIG_DUMMY_IOMMU) += pci-nommu.o pci-dma.o
-obj-$(CONFIG_SWIOTLB) += swiotlb.o
obj-$(CONFIG_KPROBES) += kprobes.o
obj-$(CONFIG_X86_PM_TIMER) += pmtimer.o
@@ -41,7 +40,6 @@ CFLAGS_vsyscall.o := $(PROFILING) -g0
bootflag-y += ../../i386/kernel/bootflag.o
cpuid-$(subst m,y,$(CONFIG_X86_CPUID)) += ../../i386/kernel/cpuid.o
topology-y += ../../i386/mach-default/topology.o
-swiotlb-$(CONFIG_SWIOTLB) += ../../ia64/lib/swiotlb.o
microcode-$(subst m,y,$(CONFIG_MICROCODE)) += ../../i386/kernel/microcode.o
intel_cacheinfo-y += ../../i386/kernel/cpu/intel_cacheinfo.o
quirks-y += ../../i386/kernel/quirks.o
diff --git a/arch/x86_64/kernel/i8259.c b/arch/x86_64/kernel/i8259.c
index b2a238b5a17e..c6c9791d77c1 100644
--- a/arch/x86_64/kernel/i8259.c
+++ b/arch/x86_64/kernel/i8259.c
@@ -494,7 +494,7 @@ void invalidate_interrupt7(void);
void thermal_interrupt(void);
void i8254_timer_resume(void);
-static void setup_timer(void)
+static void setup_timer_hardware(void)
{
outb_p(0x34,0x43); /* binary, mode 2, LSB/MSB, ch 0 */
udelay(10);
@@ -505,13 +505,13 @@ static void setup_timer(void)
static int timer_resume(struct sys_device *dev)
{
- setup_timer();
+ setup_timer_hardware();
return 0;
}
void i8254_timer_resume(void)
{
- setup_timer();
+ setup_timer_hardware();
}
static struct sysdev_class timer_sysclass = {
@@ -594,7 +594,7 @@ void __init init_IRQ(void)
* Set the clock to HZ Hz, we already have a valid
* vector now:
*/
- setup_timer();
+ setup_timer_hardware();
if (!acpi_ioapic)
setup_irq(2, &irq2);
diff --git a/arch/x86_64/kernel/kprobes.c b/arch/x86_64/kernel/kprobes.c
index 76a28b007be9..dddeb678b440 100644
--- a/arch/x86_64/kernel/kprobes.c
+++ b/arch/x86_64/kernel/kprobes.c
@@ -34,7 +34,6 @@
#include <linux/config.h>
#include <linux/kprobes.h>
#include <linux/ptrace.h>
-#include <linux/spinlock.h>
#include <linux/string.h>
#include <linux/slab.h>
#include <linux/preempt.h>
@@ -44,17 +43,10 @@
#include <asm/kdebug.h>
static DECLARE_MUTEX(kprobe_mutex);
-
-static struct kprobe *current_kprobe;
-static unsigned long kprobe_status, kprobe_old_rflags, kprobe_saved_rflags;
-static struct kprobe *kprobe_prev;
-static unsigned long kprobe_status_prev, kprobe_old_rflags_prev, kprobe_saved_rflags_prev;
-static struct pt_regs jprobe_saved_regs;
-static long *jprobe_saved_rsp;
void jprobe_return_end(void);
-/* copy of the kernel stack at the probe fire time */
-static kprobe_opcode_t jprobes_stack[MAX_STACK_SIZE];
+DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
+DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
/*
* returns non-zero if opcode modifies the interrupt flag.
@@ -236,29 +228,30 @@ void __kprobes arch_remove_kprobe(struct kprobe *p)
up(&kprobe_mutex);
}
-static inline void save_previous_kprobe(void)
+static inline void save_previous_kprobe(struct kprobe_ctlblk *kcb)
{
- kprobe_prev = current_kprobe;
- kprobe_status_prev = kprobe_status;
- kprobe_old_rflags_prev = kprobe_old_rflags;
- kprobe_saved_rflags_prev = kprobe_saved_rflags;
+ kcb->prev_kprobe.kp = kprobe_running();
+ kcb->prev_kprobe.status = kcb->kprobe_status;
+ kcb->prev_kprobe.old_rflags = kcb->kprobe_old_rflags;
+ kcb->prev_kprobe.saved_rflags = kcb->kprobe_saved_rflags;
}
-static inline void restore_previous_kprobe(void)
+static inline void restore_previous_kprobe(struct kprobe_ctlblk *kcb)
{
- current_kprobe = kprobe_prev;
- kprobe_status = kprobe_status_prev;
- kprobe_old_rflags = kprobe_old_rflags_prev;
- kprobe_saved_rflags = kprobe_saved_rflags_prev;
+ __get_cpu_var(current_kprobe) = kcb->prev_kprobe.kp;
+ kcb->kprobe_status = kcb->prev_kprobe.status;
+ kcb->kprobe_old_rflags = kcb->prev_kprobe.old_rflags;
+ kcb->kprobe_saved_rflags = kcb->prev_kprobe.saved_rflags;
}
-static inline void set_current_kprobe(struct kprobe *p, struct pt_regs *regs)
+static inline void set_current_kprobe(struct kprobe *p, struct pt_regs *regs,
+ struct kprobe_ctlblk *kcb)
{
- current_kprobe = p;
- kprobe_saved_rflags = kprobe_old_rflags
+ __get_cpu_var(current_kprobe) = p;
+ kcb->kprobe_saved_rflags = kcb->kprobe_old_rflags
= (regs->eflags & (TF_MASK | IF_MASK));
if (is_IF_modifier(p->ainsn.insn))
- kprobe_saved_rflags &= ~IF_MASK;
+ kcb->kprobe_saved_rflags &= ~IF_MASK;
}
static void __kprobes prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
@@ -272,6 +265,7 @@ static void __kprobes prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
regs->rip = (unsigned long)p->ainsn.insn;
}
+/* Called with kretprobe_lock held */
void __kprobes arch_prepare_kretprobe(struct kretprobe *rp,
struct pt_regs *regs)
{
@@ -292,32 +286,30 @@ void __kprobes arch_prepare_kretprobe(struct kretprobe *rp,
}
}
-/*
- * Interrupts are disabled on entry as trap3 is an interrupt gate and they
- * remain disabled thorough out this function.
- */
int __kprobes kprobe_handler(struct pt_regs *regs)
{
struct kprobe *p;
int ret = 0;
kprobe_opcode_t *addr = (kprobe_opcode_t *)(regs->rip - sizeof(kprobe_opcode_t));
+ struct kprobe_ctlblk *kcb;
- /* We're in an interrupt, but this is clear and BUG()-safe. */
+ /*
+ * We don't want to be preempted for the entire
+ * duration of kprobe processing
+ */
preempt_disable();
+ kcb = get_kprobe_ctlblk();
/* Check we're not actually recursing */
if (kprobe_running()) {
- /* We *are* holding lock here, so this is safe.
- Disarm the probe we just hit, and ignore it. */
p = get_kprobe(addr);
if (p) {
- if (kprobe_status == KPROBE_HIT_SS &&
+ if (kcb->kprobe_status == KPROBE_HIT_SS &&
*p->ainsn.insn == BREAKPOINT_INSTRUCTION) {
regs->eflags &= ~TF_MASK;
- regs->eflags |= kprobe_saved_rflags;
- unlock_kprobes();
+ regs->eflags |= kcb->kprobe_saved_rflags;
goto no_kprobe;
- } else if (kprobe_status == KPROBE_HIT_SSDONE) {
+ } else if (kcb->kprobe_status == KPROBE_HIT_SSDONE) {
/* TODO: Provide re-entrancy from
* post_kprobes_handler() and avoid exception
* stack corruption while single-stepping on
@@ -325,6 +317,7 @@ int __kprobes kprobe_handler(struct pt_regs *regs)
*/
arch_disarm_kprobe(p);
regs->rip = (unsigned long)p->addr;
+ reset_current_kprobe();
ret = 1;
} else {
/* We have reentered the kprobe_handler(), since
@@ -334,27 +327,24 @@ int __kprobes kprobe_handler(struct pt_regs *regs)
* of the new probe without calling any user
* handlers.
*/
- save_previous_kprobe();
- set_current_kprobe(p, regs);
+ save_previous_kprobe(kcb);
+ set_current_kprobe(p, regs, kcb);
p->nmissed++;
prepare_singlestep(p, regs);
- kprobe_status = KPROBE_REENTER;
+ kcb->kprobe_status = KPROBE_REENTER;
return 1;
}
} else {
- p = current_kprobe;
+ p = __get_cpu_var(current_kprobe);
if (p->break_handler && p->break_handler(p, regs)) {
goto ss_probe;
}
}
- /* If it's not ours, can't be delete race, (we hold lock). */
goto no_kprobe;
}
- lock_kprobes();
p = get_kprobe(addr);
if (!p) {
- unlock_kprobes();
if (*addr != BREAKPOINT_INSTRUCTION) {
/*
* The breakpoint instruction was removed right
@@ -372,8 +362,8 @@ int __kprobes kprobe_handler(struct pt_regs *regs)
goto no_kprobe;
}
- kprobe_status = KPROBE_HIT_ACTIVE;
- set_current_kprobe(p, regs);
+ set_current_kprobe(p, regs, kcb);
+ kcb->kprobe_status = KPROBE_HIT_ACTIVE;
if (p->pre_handler && p->pre_handler(p, regs))
/* handler has already set things up, so skip ss setup */
@@ -381,7 +371,7 @@ int __kprobes kprobe_handler(struct pt_regs *regs)
ss_probe:
prepare_singlestep(p, regs);
- kprobe_status = KPROBE_HIT_SS;
+ kcb->kprobe_status = KPROBE_HIT_SS;
return 1;
no_kprobe:
@@ -409,9 +399,10 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
struct kretprobe_instance *ri = NULL;
struct hlist_head *head;
struct hlist_node *node, *tmp;
- unsigned long orig_ret_address = 0;
+ unsigned long flags, orig_ret_address = 0;
unsigned long trampoline_address =(unsigned long)&kretprobe_trampoline;
+ spin_lock_irqsave(&kretprobe_lock, flags);
head = kretprobe_inst_table_head(current);
/*
@@ -450,13 +441,14 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
BUG_ON(!orig_ret_address || (orig_ret_address == trampoline_address));
regs->rip = orig_ret_address;
- unlock_kprobes();
+ reset_current_kprobe();
+ spin_unlock_irqrestore(&kretprobe_lock, flags);
preempt_enable_no_resched();
/*
* By returning a non-zero value, we are telling
- * kprobe_handler() that we have handled unlocking
- * and re-enabling preemption.
+ * kprobe_handler() that we don't want the post_handler
+ * to run (and have re-enabled preemption)
*/
return 1;
}
@@ -483,7 +475,8 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
* that is atop the stack is the address following the copied instruction.
* We need to make it the address following the original instruction.
*/
-static void __kprobes resume_execution(struct kprobe *p, struct pt_regs *regs)
+static void __kprobes resume_execution(struct kprobe *p,
+ struct pt_regs *regs, struct kprobe_ctlblk *kcb)
{
unsigned long *tos = (unsigned long *)regs->rsp;
unsigned long next_rip = 0;
@@ -498,7 +491,7 @@ static void __kprobes resume_execution(struct kprobe *p, struct pt_regs *regs)
switch (*insn) {
case 0x9c: /* pushfl */
*tos &= ~(TF_MASK | IF_MASK);
- *tos |= kprobe_old_rflags;
+ *tos |= kcb->kprobe_old_rflags;
break;
case 0xc3: /* ret/lret */
case 0xcb:
@@ -537,30 +530,28 @@ static void __kprobes resume_execution(struct kprobe *p, struct pt_regs *regs)
}
}
-/*
- * Interrupts are disabled on entry as trap1 is an interrupt gate and they
- * remain disabled thoroughout this function. And we hold kprobe lock.
- */
int __kprobes post_kprobe_handler(struct pt_regs *regs)
{
- if (!kprobe_running())
+ struct kprobe *cur = kprobe_running();
+ struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
+
+ if (!cur)
return 0;
- if ((kprobe_status != KPROBE_REENTER) && current_kprobe->post_handler) {
- kprobe_status = KPROBE_HIT_SSDONE;
- current_kprobe->post_handler(current_kprobe, regs, 0);
+ if ((kcb->kprobe_status != KPROBE_REENTER) && cur->post_handler) {
+ kcb->kprobe_status = KPROBE_HIT_SSDONE;
+ cur->post_handler(cur, regs, 0);
}
- resume_execution(current_kprobe, regs);
- regs->eflags |= kprobe_saved_rflags;
+ resume_execution(cur, regs, kcb);
+ regs->eflags |= kcb->kprobe_saved_rflags;
/* Restore the original saved kprobes variables and continue. */
- if (kprobe_status == KPROBE_REENTER) {
- restore_previous_kprobe();
+ if (kcb->kprobe_status == KPROBE_REENTER) {
+ restore_previous_kprobe(kcb);
goto out;
- } else {
- unlock_kprobes();
}
+ reset_current_kprobe();
out:
preempt_enable_no_resched();
@@ -575,18 +566,19 @@ out:
return 1;
}
-/* Interrupts disabled, kprobe_lock held. */
int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr)
{
- if (current_kprobe->fault_handler
- && current_kprobe->fault_handler(current_kprobe, regs, trapnr))
+ struct kprobe *cur = kprobe_running();
+ struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
+
+ if (cur->fault_handler && cur->fault_handler(cur, regs, trapnr))
return 1;
- if (kprobe_status & KPROBE_HIT_SS) {
- resume_execution(current_kprobe, regs);
- regs->eflags |= kprobe_old_rflags;
+ if (kcb->kprobe_status & KPROBE_HIT_SS) {
+ resume_execution(cur, regs, kcb);
+ regs->eflags |= kcb->kprobe_old_rflags;
- unlock_kprobes();
+ reset_current_kprobe();
preempt_enable_no_resched();
}
return 0;
@@ -599,39 +591,41 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
unsigned long val, void *data)
{
struct die_args *args = (struct die_args *)data;
+ int ret = NOTIFY_DONE;
+
switch (val) {
case DIE_INT3:
if (kprobe_handler(args->regs))
- return NOTIFY_STOP;
+ ret = NOTIFY_STOP;
break;
case DIE_DEBUG:
if (post_kprobe_handler(args->regs))
- return NOTIFY_STOP;
+ ret = NOTIFY_STOP;
break;
case DIE_GPF:
- if (kprobe_running() &&
- kprobe_fault_handler(args->regs, args->trapnr))
- return NOTIFY_STOP;
- break;
case DIE_PAGE_FAULT:
+ /* kprobe_running() needs smp_processor_id() */
+ preempt_disable();
if (kprobe_running() &&
kprobe_fault_handler(args->regs, args->trapnr))
- return NOTIFY_STOP;
+ ret = NOTIFY_STOP;
+ preempt_enable();
break;
default:
break;
}
- return NOTIFY_DONE;
+ return ret;
}
int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
{
struct jprobe *jp = container_of(p, struct jprobe, kp);
unsigned long addr;
+ struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
- jprobe_saved_regs = *regs;
- jprobe_saved_rsp = (long *) regs->rsp;
- addr = (unsigned long)jprobe_saved_rsp;
+ kcb->jprobe_saved_regs = *regs;
+ kcb->jprobe_saved_rsp = (long *) regs->rsp;
+ addr = (unsigned long)(kcb->jprobe_saved_rsp);
/*
* As Linus pointed out, gcc assumes that the callee
* owns the argument space and could overwrite it, e.g.
@@ -639,7 +633,8 @@ int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
* we also save and restore enough stack bytes to cover
* the argument area.
*/
- memcpy(jprobes_stack, (kprobe_opcode_t *) addr, MIN_STACK_SIZE(addr));
+ memcpy(kcb->jprobes_stack, (kprobe_opcode_t *)addr,
+ MIN_STACK_SIZE(addr));
regs->eflags &= ~IF_MASK;
regs->rip = (unsigned long)(jp->entry);
return 1;
@@ -647,36 +642,40 @@ int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
void __kprobes jprobe_return(void)
{
- preempt_enable_no_resched();
+ struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
+
asm volatile (" xchg %%rbx,%%rsp \n"
" int3 \n"
" .globl jprobe_return_end \n"
" jprobe_return_end: \n"
" nop \n"::"b"
- (jprobe_saved_rsp):"memory");
+ (kcb->jprobe_saved_rsp):"memory");
}
int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
{
+ struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
u8 *addr = (u8 *) (regs->rip - 1);
- unsigned long stack_addr = (unsigned long)jprobe_saved_rsp;
+ unsigned long stack_addr = (unsigned long)(kcb->jprobe_saved_rsp);
struct jprobe *jp = container_of(p, struct jprobe, kp);
if ((addr > (u8 *) jprobe_return) && (addr < (u8 *) jprobe_return_end)) {
- if ((long *)regs->rsp != jprobe_saved_rsp) {
+ if ((long *)regs->rsp != kcb->jprobe_saved_rsp) {
struct pt_regs *saved_regs =
- container_of(jprobe_saved_rsp, struct pt_regs, rsp);
+ container_of(kcb->jprobe_saved_rsp,
+ struct pt_regs, rsp);
printk("current rsp %p does not match saved rsp %p\n",
- (long *)regs->rsp, jprobe_saved_rsp);
+ (long *)regs->rsp, kcb->jprobe_saved_rsp);
printk("Saved registers for jprobe %p\n", jp);
show_registers(saved_regs);
printk("Current registers\n");
show_registers(regs);
BUG();
}
- *regs = jprobe_saved_regs;
- memcpy((kprobe_opcode_t *) stack_addr, jprobes_stack,
+ *regs = kcb->jprobe_saved_regs;
+ memcpy((kprobe_opcode_t *) stack_addr, kcb->jprobes_stack,
MIN_STACK_SIZE(stack_addr));
+ preempt_enable_no_resched();
return 1;
}
return 0;
diff --git a/arch/x86_64/kernel/pci-gart.c b/arch/x86_64/kernel/pci-gart.c
index cf0a0315d586..88be97c96987 100644
--- a/arch/x86_64/kernel/pci-gart.c
+++ b/arch/x86_64/kernel/pci-gart.c
@@ -187,7 +187,7 @@ static void flush_gart(struct device *dev)
/* Allocate DMA memory on node near device */
noinline
-static void *dma_alloc_pages(struct device *dev, unsigned gfp, unsigned order)
+static void *dma_alloc_pages(struct device *dev, gfp_t gfp, unsigned order)
{
struct page *page;
int node;
@@ -204,7 +204,7 @@ static void *dma_alloc_pages(struct device *dev, unsigned gfp, unsigned order)
*/
void *
dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle,
- unsigned gfp)
+ gfp_t gfp)
{
void *memory;
unsigned long dma_mask = 0;
diff --git a/arch/x86_64/kernel/pci-nommu.c b/arch/x86_64/kernel/pci-nommu.c
index 67d90b89af0b..5a981dca87ff 100644
--- a/arch/x86_64/kernel/pci-nommu.c
+++ b/arch/x86_64/kernel/pci-nommu.c
@@ -24,7 +24,7 @@ EXPORT_SYMBOL(iommu_sac_force);
*/
void *dma_alloc_coherent(struct device *hwdev, size_t size,
- dma_addr_t *dma_handle, unsigned gfp)
+ dma_addr_t *dma_handle, gfp_t gfp)
{
void *ret;
u64 mask;
diff --git a/arch/x86_64/kernel/process.c b/arch/x86_64/kernel/process.c
index b5a89c0bdf59..59be85d9a4bc 100644
--- a/arch/x86_64/kernel/process.c
+++ b/arch/x86_64/kernel/process.c
@@ -86,12 +86,22 @@ EXPORT_SYMBOL(enable_hlt);
*/
void default_idle(void)
{
+ local_irq_enable();
+
if (!atomic_read(&hlt_counter)) {
- local_irq_disable();
- if (!need_resched())
- safe_halt();
- else
- local_irq_enable();
+ clear_thread_flag(TIF_POLLING_NRFLAG);
+ smp_mb__after_clear_bit();
+ while (!need_resched()) {
+ local_irq_disable();
+ if (!need_resched())
+ safe_halt();
+ else
+ local_irq_enable();
+ }
+ set_thread_flag(TIF_POLLING_NRFLAG);
+ } else {
+ while (!need_resched())
+ cpu_relax();
}
}
@@ -102,30 +112,16 @@ void default_idle(void)
*/
static void poll_idle (void)
{
- int oldval;
-
local_irq_enable();
- /*
- * Deal with another CPU just having chosen a thread to
- * run here:
- */
- oldval = test_and_clear_thread_flag(TIF_NEED_RESCHED);
-
- if (!oldval) {
- set_thread_flag(TIF_POLLING_NRFLAG);
- asm volatile(
- "2:"
- "testl %0,%1;"
- "rep; nop;"
- "je 2b;"
- : :
- "i" (_TIF_NEED_RESCHED),
- "m" (current_thread_info()->flags));
- clear_thread_flag(TIF_POLLING_NRFLAG);
- } else {
- set_need_resched();
- }
+ asm volatile(
+ "2:"
+ "testl %0,%1;"
+ "rep; nop;"
+ "je 2b;"
+ : :
+ "i" (_TIF_NEED_RESCHED),
+ "m" (current_thread_info()->flags));
}
void cpu_idle_wait(void)
@@ -187,6 +183,8 @@ static inline void play_dead(void)
*/
void cpu_idle (void)
{
+ set_thread_flag(TIF_POLLING_NRFLAG);
+
/* endless idle loop with no priority at all */
while (1) {
while (!need_resched()) {
@@ -204,7 +202,9 @@ void cpu_idle (void)
idle();
}
+ preempt_enable_no_resched();
schedule();
+ preempt_disable();
}
}
@@ -219,15 +219,12 @@ static void mwait_idle(void)
{
local_irq_enable();
- if (!need_resched()) {
- set_thread_flag(TIF_POLLING_NRFLAG);
- do {
- __monitor((void *)&current_thread_info()->flags, 0, 0);
- if (need_resched())
- break;
- __mwait(0, 0);
- } while (!need_resched());
- clear_thread_flag(TIF_POLLING_NRFLAG);
+ while (!need_resched()) {
+ __monitor((void *)&current_thread_info()->flags, 0, 0);
+ smp_mb();
+ if (need_resched())
+ break;
+ __mwait(0, 0);
}
}
diff --git a/arch/x86_64/kernel/ptrace.c b/arch/x86_64/kernel/ptrace.c
index bbf64b59a21e..a87b6cebe80f 100644
--- a/arch/x86_64/kernel/ptrace.c
+++ b/arch/x86_64/kernel/ptrace.c
@@ -313,48 +313,11 @@ static unsigned long getreg(struct task_struct *child, unsigned long regno)
}
-asmlinkage long sys_ptrace(long request, long pid, unsigned long addr, long data)
+long arch_ptrace(struct task_struct *child, long request, long addr, long data)
{
- struct task_struct *child;
long i, ret;
unsigned ui;
- /* This lock_kernel fixes a subtle race with suid exec */
- lock_kernel();
- ret = -EPERM;
- if (request == PTRACE_TRACEME) {
- /* are we already being traced? */
- if (current->ptrace & PT_PTRACED)
- goto out;
- ret = security_ptrace(current->parent, current);
- if (ret)
- goto out;
- /* set the ptrace bit in the process flags. */
- current->ptrace |= PT_PTRACED;
- ret = 0;
- goto out;
- }
- ret = -ESRCH;
- read_lock(&tasklist_lock);
- child = find_task_by_pid(pid);
- if (child)
- get_task_struct(child);
- read_unlock(&tasklist_lock);
- if (!child)
- goto out;
-
- ret = -EPERM;
- if (pid == 1) /* you may not mess with init */
- goto out_tsk;
-
- if (request == PTRACE_ATTACH) {
- ret = ptrace_attach(child);
- goto out_tsk;
- }
- ret = ptrace_check_attach(child, request == PTRACE_KILL);
- if (ret < 0)
- goto out_tsk;
-
switch (request) {
/* when I and D space are separate, these will need to be fixed. */
case PTRACE_PEEKTEXT: /* read word at location addr. */
@@ -608,10 +571,6 @@ asmlinkage long sys_ptrace(long request, long pid, unsigned long addr, long data
ret = ptrace_request(child, request, addr, data);
break;
}
-out_tsk:
- put_task_struct(child);
-out:
- unlock_kernel();
return ret;
}
diff --git a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c
index cb28df14ff6f..da0bc3e7bdf5 100644
--- a/arch/x86_64/kernel/setup.c
+++ b/arch/x86_64/kernel/setup.c
@@ -1213,7 +1213,7 @@ static int show_cpuinfo(struct seq_file *m, void *v)
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/* Intel-defined (#2) */
- "pni", NULL, NULL, "monitor", "ds_cpl", NULL, NULL, "est",
+ "pni", NULL, NULL, "monitor", "ds_cpl", "vmx", NULL, "est",
"tm2", NULL, "cid", NULL, NULL, "cx16", "xtpr", NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
diff --git a/arch/x86_64/kernel/smpboot.c b/arch/x86_64/kernel/smpboot.c
index 658a81b33f3b..c4e59bbdc187 100644
--- a/arch/x86_64/kernel/smpboot.c
+++ b/arch/x86_64/kernel/smpboot.c
@@ -65,8 +65,6 @@ int smp_num_siblings = 1;
/* Package ID of each logical CPU */
u8 phys_proc_id[NR_CPUS] __read_mostly = { [0 ... NR_CPUS-1] = BAD_APICID };
u8 cpu_core_id[NR_CPUS] __read_mostly = { [0 ... NR_CPUS-1] = BAD_APICID };
-EXPORT_SYMBOL(phys_proc_id);
-EXPORT_SYMBOL(cpu_core_id);
/* Bitmask of currently online CPUs */
cpumask_t cpu_online_map __read_mostly;
@@ -474,6 +472,7 @@ void __cpuinit start_secondary(void)
* things done here to the most necessary things.
*/
cpu_init();
+ preempt_disable();
smp_callin();
/* otherwise gcc will move up the smp_processor_id before the cpu_init */
diff --git a/arch/x86_64/kernel/suspend.c b/arch/x86_64/kernel/suspend.c
index f066c6ab3618..fd2bef780882 100644
--- a/arch/x86_64/kernel/suspend.c
+++ b/arch/x86_64/kernel/suspend.c
@@ -63,13 +63,12 @@ void save_processor_state(void)
__save_processor_state(&saved_context);
}
-static void
-do_fpu_end(void)
+static void do_fpu_end(void)
{
- /* restore FPU regs if necessary */
- /* Do it out of line so that gcc does not move cr0 load to some stupid place */
- kernel_fpu_end();
- mxcsr_feature_mask_init();
+ /*
+ * Restore FPU regs if necessary
+ */
+ kernel_fpu_end();
}
void __restore_processor_state(struct saved_context *ctxt)
@@ -148,57 +147,7 @@ extern int restore_image(void);
pgd_t *temp_level4_pgt;
-static void **pages;
-
-static inline void *__add_page(void)
-{
- void **c;
-
- c = (void **)get_usable_page(GFP_ATOMIC);
- if (c) {
- *c = pages;
- pages = c;
- }
- return c;
-}
-
-static inline void *__next_page(void)
-{
- void **c;
-
- c = pages;
- if (c) {
- pages = *c;
- *c = NULL;
- }
- return c;
-}
-
-/*
- * Try to allocate as many usable pages as needed and daisy chain them.
- * If one allocation fails, free the pages allocated so far
- */
-static int alloc_usable_pages(unsigned long n)
-{
- void *p;
-
- pages = NULL;
- do
- if (!__add_page())
- break;
- while (--n);
- if (n) {
- p = __next_page();
- while (p) {
- free_page((unsigned long)p);
- p = __next_page();
- }
- return -ENOMEM;
- }
- return 0;
-}
-
-static void res_phys_pud_init(pud_t *pud, unsigned long address, unsigned long end)
+static int res_phys_pud_init(pud_t *pud, unsigned long address, unsigned long end)
{
long i, j;
@@ -212,7 +161,9 @@ static void res_phys_pud_init(pud_t *pud, unsigned long address, unsigned long e
if (paddr >= end)
break;
- pmd = (pmd_t *)__next_page();
+ pmd = (pmd_t *)get_safe_page(GFP_ATOMIC);
+ if (!pmd)
+ return -ENOMEM;
set_pud(pud, __pud(__pa(pmd) | _KERNPG_TABLE));
for (j = 0; j < PTRS_PER_PMD; pmd++, j++, paddr += PMD_SIZE) {
unsigned long pe;
@@ -224,13 +175,17 @@ static void res_phys_pud_init(pud_t *pud, unsigned long address, unsigned long e
set_pmd(pmd, __pmd(pe));
}
}
+ return 0;
}
-static void set_up_temporary_mappings(void)
+static int set_up_temporary_mappings(void)
{
unsigned long start, end, next;
+ int error;
- temp_level4_pgt = (pgd_t *)__next_page();
+ temp_level4_pgt = (pgd_t *)get_safe_page(GFP_ATOMIC);
+ if (!temp_level4_pgt)
+ return -ENOMEM;
/* It is safe to reuse the original kernel mapping */
set_pgd(temp_level4_pgt + pgd_index(__START_KERNEL_map),
@@ -241,29 +196,27 @@ static void set_up_temporary_mappings(void)
end = (unsigned long)pfn_to_kaddr(end_pfn);
for (; start < end; start = next) {
- pud_t *pud = (pud_t *)__next_page();
+ pud_t *pud = (pud_t *)get_safe_page(GFP_ATOMIC);
+ if (!pud)
+ return -ENOMEM;
next = start + PGDIR_SIZE;
if (next > end)
next = end;
- res_phys_pud_init(pud, __pa(start), __pa(next));
+ if ((error = res_phys_pud_init(pud, __pa(start), __pa(next))))
+ return error;
set_pgd(temp_level4_pgt + pgd_index(start),
mk_kernel_pgd(__pa(pud)));
}
+ return 0;
}
int swsusp_arch_resume(void)
{
- unsigned long n;
+ int error;
- n = ((end_pfn << PAGE_SHIFT) + PUD_SIZE - 1) >> PUD_SHIFT;
- n += (n + PTRS_PER_PUD - 1) / PTRS_PER_PUD + 1;
- pr_debug("swsusp_arch_resume(): pages needed = %lu\n", n);
- if (alloc_usable_pages(n)) {
- free_eaten_memory();
- return -ENOMEM;
- }
/* We have got enough memory and from now on we cannot recover */
- set_up_temporary_mappings();
+ if ((error = set_up_temporary_mappings()))
+ return error;
restore_image();
return 0;
}
diff --git a/arch/x86_64/kernel/time.c b/arch/x86_64/kernel/time.c
index 703acde2a1a5..fdaddc4e5284 100644
--- a/arch/x86_64/kernel/time.c
+++ b/arch/x86_64/kernel/time.c
@@ -42,10 +42,6 @@
#include <asm/apic.h>
#endif
-u64 jiffies_64 = INITIAL_JIFFIES;
-
-EXPORT_SYMBOL(jiffies_64);
-
#ifdef CONFIG_CPU_FREQ
static void cpufreq_delayed_get(void);
#endif
@@ -481,9 +477,9 @@ static irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
static unsigned int cyc2ns_scale;
#define CYC2NS_SCALE_FACTOR 10 /* 2^10, carefully chosen */
-static inline void set_cyc2ns_scale(unsigned long cpu_mhz)
+static inline void set_cyc2ns_scale(unsigned long cpu_khz)
{
- cyc2ns_scale = (1000 << CYC2NS_SCALE_FACTOR)/cpu_mhz;
+ cyc2ns_scale = (1000000 << CYC2NS_SCALE_FACTOR)/cpu_khz;
}
static inline unsigned long long cycles_2_ns(unsigned long long cyc)
@@ -655,7 +651,7 @@ static int time_cpufreq_notifier(struct notifier_block *nb, unsigned long val,
vxtime.tsc_quot = (1000L << 32) / cpu_khz;
}
- set_cyc2ns_scale(cpu_khz_ref / 1000);
+ set_cyc2ns_scale(cpu_khz_ref);
return 0;
}
@@ -939,7 +935,7 @@ void __init time_init(void)
rdtscll_sync(&vxtime.last_tsc);
setup_irq(0, &irq0);
- set_cyc2ns_scale(cpu_khz / 1000);
+ set_cyc2ns_scale(cpu_khz);
#ifndef CONFIG_SMP
time_init_gtod();
@@ -1093,6 +1089,7 @@ static unsigned long PIE_freq = DEFAULT_RTC_INT_FREQ;
static unsigned long PIE_count;
static unsigned long hpet_rtc_int_freq; /* RTC interrupt frequency */
+static unsigned int hpet_t1_cmp; /* cached comparator register */
int is_hpet_enabled(void)
{
@@ -1129,10 +1126,12 @@ int hpet_rtc_timer_init(void)
cnt = hpet_readl(HPET_COUNTER);
cnt += ((hpet_tick*HZ)/hpet_rtc_int_freq);
hpet_writel(cnt, HPET_T1_CMP);
+ hpet_t1_cmp = cnt;
local_irq_restore(flags);
cfg = hpet_readl(HPET_T1_CFG);
- cfg |= HPET_TN_ENABLE | HPET_TN_SETVAL | HPET_TN_32BIT;
+ cfg &= ~HPET_TN_PERIODIC;
+ cfg |= HPET_TN_ENABLE | HPET_TN_32BIT;
hpet_writel(cfg, HPET_T1_CFG);
return 1;
@@ -1142,8 +1141,12 @@ static void hpet_rtc_timer_reinit(void)
{
unsigned int cfg, cnt;
- if (!(PIE_on | AIE_on | UIE_on))
+ if (unlikely(!(PIE_on | AIE_on | UIE_on))) {
+ cfg = hpet_readl(HPET_T1_CFG);
+ cfg &= ~HPET_TN_ENABLE;
+ hpet_writel(cfg, HPET_T1_CFG);
return;
+ }
if (PIE_on && (PIE_freq > DEFAULT_RTC_INT_FREQ))
hpet_rtc_int_freq = PIE_freq;
@@ -1151,15 +1154,10 @@ static void hpet_rtc_timer_reinit(void)
hpet_rtc_int_freq = DEFAULT_RTC_INT_FREQ;
/* It is more accurate to use the comparator value than current count.*/
- cnt = hpet_readl(HPET_T1_CMP);
+ cnt = hpet_t1_cmp;
cnt += hpet_tick*HZ/hpet_rtc_int_freq;
hpet_writel(cnt, HPET_T1_CMP);
-
- cfg = hpet_readl(HPET_T1_CFG);
- cfg |= HPET_TN_ENABLE | HPET_TN_SETVAL | HPET_TN_32BIT;
- hpet_writel(cfg, HPET_T1_CFG);
-
- return;
+ hpet_t1_cmp = cnt;
}
/*
diff --git a/arch/x86_64/lib/bitops.c b/arch/x86_64/lib/bitops.c
index a29fb75b33ac..95b6d9639fba 100644
--- a/arch/x86_64/lib/bitops.c
+++ b/arch/x86_64/lib/bitops.c
@@ -5,19 +5,23 @@
#undef find_first_bit
#undef find_next_bit
-/**
- * find_first_zero_bit - find the first zero bit in a memory region
- * @addr: The address to start the search at
- * @size: The maximum size to search
- *
- * Returns the bit-number of the first zero bit, not the number of the byte
- * containing a bit.
- */
-inline long find_first_zero_bit(const unsigned long * addr, unsigned long size)
+static inline long
+__find_first_zero_bit(const unsigned long * addr, unsigned long size)
{
long d0, d1, d2;
long res;
+ /*
+ * We must test the size in words, not in bits, because
+ * otherwise incoming sizes in the range -63..-1 will not run
+ * any scasq instructions, and then the flags used by the je
+ * instruction will have whatever random value was in place
+ * before. Nobody should call us like that, but
+ * find_next_zero_bit() does when offset and size are at the
+ * same word and it fails to find a zero itself.
+ */
+ size += 63;
+ size >>= 6;
if (!size)
return 0;
asm volatile(
@@ -30,12 +34,30 @@ inline long find_first_zero_bit(const unsigned long * addr, unsigned long size)
" shlq $3,%%rdi\n"
" addq %%rdi,%%rdx"
:"=d" (res), "=&c" (d0), "=&D" (d1), "=&a" (d2)
- :"0" (0ULL), "1" ((size + 63) >> 6), "2" (addr), "3" (-1ULL),
- [addr] "r" (addr) : "memory");
+ :"0" (0ULL), "1" (size), "2" (addr), "3" (-1ULL),
+ [addr] "S" (addr) : "memory");
+ /*
+ * Any register would do for [addr] above, but GCC tends to
+ * prefer rbx over rsi, even though rsi is readily available
+ * and doesn't have to be saved.
+ */
return res;
}
/**
+ * find_first_zero_bit - find the first zero bit in a memory region
+ * @addr: The address to start the search at
+ * @size: The maximum size to search
+ *
+ * Returns the bit-number of the first zero bit, not the number of the byte
+ * containing a bit.
+ */
+long find_first_zero_bit(const unsigned long * addr, unsigned long size)
+{
+ return __find_first_zero_bit (addr, size);
+}
+
+/**
* find_next_zero_bit - find the first zero bit in a memory region
* @addr: The address to base the search on
* @offset: The bitnumber to start searching at
@@ -43,7 +65,7 @@ inline long find_first_zero_bit(const unsigned long * addr, unsigned long size)
*/
long find_next_zero_bit (const unsigned long * addr, long size, long offset)
{
- unsigned long * p = ((unsigned long *) addr) + (offset >> 6);
+ const unsigned long * p = addr + (offset >> 6);
unsigned long set = 0;
unsigned long res, bit = offset&63;
@@ -63,8 +85,8 @@ long find_next_zero_bit (const unsigned long * addr, long size, long offset)
/*
* No zero yet, search remaining full words for a zero
*/
- res = find_first_zero_bit ((const unsigned long *)p,
- size - 64 * (p - (unsigned long *) addr));
+ res = __find_first_zero_bit (p, size - 64 * (p - addr));
+
return (offset + set + res);
}
@@ -74,6 +96,19 @@ __find_first_bit(const unsigned long * addr, unsigned long size)
long d0, d1;
long res;
+ /*
+ * We must test the size in words, not in bits, because
+ * otherwise incoming sizes in the range -63..-1 will not run
+ * any scasq instructions, and then the flags used by the jz
+ * instruction will have whatever random value was in place
+ * before. Nobody should call us like that, but
+ * find_next_bit() does when offset and size are at the same
+ * word and it fails to find a one itself.
+ */
+ size += 63;
+ size >>= 6;
+ if (!size)
+ return 0;
asm volatile(
" repe; scasq\n"
" jz 1f\n"
@@ -83,8 +118,7 @@ __find_first_bit(const unsigned long * addr, unsigned long size)
" shlq $3,%%rdi\n"
" addq %%rdi,%%rax"
:"=a" (res), "=&c" (d0), "=&D" (d1)
- :"0" (0ULL),
- "1" ((size + 63) >> 6), "2" (addr),
+ :"0" (0ULL), "1" (size), "2" (addr),
[addr] "r" (addr) : "memory");
return res;
}
diff --git a/arch/x86_64/mm/ioremap.c b/arch/x86_64/mm/ioremap.c
index 6972df480d2b..ecf7acb5db9b 100644
--- a/arch/x86_64/mm/ioremap.c
+++ b/arch/x86_64/mm/ioremap.c
@@ -60,7 +60,7 @@ static inline int remap_area_pmd(pmd_t * pmd, unsigned long address, unsigned lo
if (address >= end)
BUG();
do {
- pte_t * pte = pte_alloc_kernel(&init_mm, pmd, address);
+ pte_t * pte = pte_alloc_kernel(pmd, address);
if (!pte)
return -ENOMEM;
remap_area_pte(pte, address, end - address, address + phys_addr, flags);
@@ -105,7 +105,6 @@ static int remap_area_pages(unsigned long address, unsigned long phys_addr,
flush_cache_all();
if (address >= end)
BUG();
- spin_lock(&init_mm.page_table_lock);
do {
pud_t *pud;
pud = pud_alloc(&init_mm, pgd, address);
@@ -119,7 +118,6 @@ static int remap_area_pages(unsigned long address, unsigned long phys_addr,
address = (address + PGDIR_SIZE) & PGDIR_MASK;
pgd++;
} while (address && (address < end));
- spin_unlock(&init_mm.page_table_lock);
flush_tlb_all();
return error;
}
diff --git a/arch/x86_64/oprofile/Kconfig b/arch/x86_64/oprofile/Kconfig
index 5ade19801b97..d8a84088471a 100644
--- a/arch/x86_64/oprofile/Kconfig
+++ b/arch/x86_64/oprofile/Kconfig
@@ -1,7 +1,3 @@
-
-menu "Profiling support"
- depends on EXPERIMENTAL
-
config PROFILING
bool "Profiling support (EXPERIMENTAL)"
help
@@ -19,5 +15,3 @@ config OPROFILE
If unsure, say N.
-endmenu
-
diff --git a/arch/xtensa/kernel/pci-dma.c b/arch/xtensa/kernel/pci-dma.c
index 84fde258cf85..1ff82268e8ea 100644
--- a/arch/xtensa/kernel/pci-dma.c
+++ b/arch/xtensa/kernel/pci-dma.c
@@ -29,7 +29,7 @@
*/
void *
-dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *handle, int gfp)
+dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp)
{
void *ret;
diff --git a/arch/xtensa/kernel/platform.c b/arch/xtensa/kernel/platform.c
index 03674daabc66..a17930747f20 100644
--- a/arch/xtensa/kernel/platform.c
+++ b/arch/xtensa/kernel/platform.c
@@ -18,6 +18,7 @@
#include <linux/time.h>
#include <asm/platform.h>
#include <asm/timex.h>
+#include <asm/param.h> /* HZ */
#define _F(r,f,a,b) \
r __platform_##f a b; \
diff --git a/arch/xtensa/kernel/process.c b/arch/xtensa/kernel/process.c
index 08ef6d82ee51..6a44b54ae817 100644
--- a/arch/xtensa/kernel/process.c
+++ b/arch/xtensa/kernel/process.c
@@ -96,8 +96,9 @@ void cpu_idle(void)
while (1) {
while (!need_resched())
platform_idle();
- preempt_enable();
+ preempt_enable_no_resched();
schedule();
+ preempt_disable();
}
}
diff --git a/arch/xtensa/kernel/ptrace.c b/arch/xtensa/kernel/ptrace.c
index 2659efdd4e99..ab5c4c65b5c4 100644
--- a/arch/xtensa/kernel/ptrace.c
+++ b/arch/xtensa/kernel/ptrace.c
@@ -45,58 +45,10 @@ void ptrace_disable(struct task_struct *child)
/* Nothing to do.. */
}
-int sys_ptrace(long request, long pid, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request, long addr, long data)
{
- struct task_struct *child;
int ret = -EPERM;
- lock_kernel();
-
-#if 0
- if ((int)request != 1)
- printk("ptrace(r=%d,pid=%d,addr=%08lx,data=%08lx)\n",
- (int) request, (int) pid, (unsigned long) addr,
- (unsigned long) data);
-#endif
-
- if (request == PTRACE_TRACEME) {
-
- /* Are we already being traced? */
-
- if (current->ptrace & PT_PTRACED)
- goto out;
-
- if ((ret = security_ptrace(current->parent, current)))
- goto out;
-
- /* Set the ptrace bit in the process flags. */
-
- current->ptrace |= PT_PTRACED;
- ret = 0;
- goto out;
- }
-
- ret = -ESRCH;
- read_lock(&tasklist_lock);
- child = find_task_by_pid(pid);
- if (child)
- get_task_struct(child);
- read_unlock(&tasklist_lock);
- if (!child)
- goto out;
-
- ret = -EPERM;
- if (pid == 1) /* you may not mess with init */
- goto out;
-
- if (request == PTRACE_ATTACH) {
- ret = ptrace_attach(child);
- goto out_tsk;
- }
-
- if ((ret = ptrace_check_attach(child, request == PTRACE_KILL)) < 0)
- goto out_tsk;
-
switch (request) {
case PTRACE_PEEKTEXT: /* read word at location addr. */
case PTRACE_PEEKDATA:
@@ -375,10 +327,7 @@ int sys_ptrace(long request, long pid, long addr, long data)
ret = ptrace_request(child, request, addr, data);
goto out;
}
-out_tsk:
- put_task_struct(child);
-out:
- unlock_kernel();
+ out:
return ret;
}
diff --git a/arch/xtensa/kernel/time.c b/arch/xtensa/kernel/time.c
index 8e423d1335ce..cb6e38ed2b1d 100644
--- a/arch/xtensa/kernel/time.c
+++ b/arch/xtensa/kernel/time.c
@@ -29,9 +29,6 @@
extern volatile unsigned long wall_jiffies;
-u64 jiffies_64 = INITIAL_JIFFIES;
-EXPORT_SYMBOL(jiffies_64);
-
spinlock_t rtc_lock = SPIN_LOCK_UNLOCKED;
EXPORT_SYMBOL(rtc_lock);
diff --git a/arch/xtensa/platform-iss/network.c b/arch/xtensa/platform-iss/network.c
index 498d7dced1f4..96b9bb4a478d 100644
--- a/arch/xtensa/platform-iss/network.c
+++ b/arch/xtensa/platform-iss/network.c
@@ -33,6 +33,7 @@
#include <linux/ethtool.h>
#include <linux/rtnetlink.h>
#include <linux/timer.h>
+#include <linux/platform_device.h>
#include <xtensa/simcall.h>
@@ -610,38 +611,6 @@ static int iss_net_change_mtu(struct net_device *dev, int new_mtu)
return -EINVAL;
}
-static int iss_net_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
-{
-#if 0
- static const struct ethtool_drvinfo info = {
- .cmd = ETHTOOL_GDRVINFO,
- .driver = DRIVER_NAME,
- .version = "42",
- };
- void *useraddr;
- u32 ethcmd;
-
- switch (cmd) {
- case SIOCETHTOOL:
- useraddr = ifr->ifr_data;
- if (copy_from_user(&ethcmd, useraddr, sizeof(ethcmd)))
- return -EFAULT;
-
- switch (ethcmd) {
- case ETHTOOL_GDRVINFO:
- if (copy_to_user(useraddr, &info, sizeof(info)))
- return -EFAULT;
- return 0;
- default:
- return -EOPNOTSUPP;
- }
- default:
- return -EINVAL;
- }
-#endif
- return -EINVAL;
-}
-
void iss_net_user_timer_expire(unsigned long _conn)
{
}
@@ -729,7 +698,6 @@ static int iss_net_configure(int index, char *init)
dev->tx_timeout = iss_net_tx_timeout;
dev->set_mac_address = iss_net_set_mac;
dev->change_mtu = iss_net_change_mtu;
- dev->do_ioctl = iss_net_ioctl;
dev->watchdog_timeo = (HZ >> 1);
dev->irq = -1;
diff --git a/block/Kconfig b/block/Kconfig
new file mode 100644
index 000000000000..eb48edb80c1d
--- /dev/null
+++ b/block/Kconfig
@@ -0,0 +1,14 @@
+#
+# Block layer core configuration
+#
+#XXX - it makes sense to enable this only for 32-bit subarch's, not for x86_64
+#for instance.
+config LBD
+ bool "Support for Large Block Devices"
+ depends on X86 || (MIPS && 32BIT) || PPC32 || ARCH_S390_31 || SUPERH || UML
+ help
+ Say Y here if you want to attach large (bigger than 2TB) discs to
+ your machine, or if you want to have a raid or loopback device
+ bigger than 2TB. Otherwise say N.
+
+source block/Kconfig.iosched
diff --git a/drivers/block/Kconfig.iosched b/block/Kconfig.iosched
index 6070a480600b..f3b7753aac99 100644
--- a/drivers/block/Kconfig.iosched
+++ b/block/Kconfig.iosched
@@ -38,4 +38,32 @@ config IOSCHED_CFQ
among all processes in the system. It should provide a fair
working environment, suitable for desktop systems.
+choice
+ prompt "Default I/O scheduler"
+ default DEFAULT_AS
+ help
+ Select the I/O scheduler which will be used by default for all
+ block devices.
+
+ config DEFAULT_AS
+ bool "Anticipatory" if IOSCHED_AS=y
+
+ config DEFAULT_DEADLINE
+ bool "Deadline" if IOSCHED_DEADLINE=y
+
+ config DEFAULT_CFQ
+ bool "CFQ" if IOSCHED_CFQ=y
+
+ config DEFAULT_NOOP
+ bool "No-op"
+
+endchoice
+
+config DEFAULT_IOSCHED
+ string
+ default "anticipatory" if DEFAULT_AS
+ default "deadline" if DEFAULT_DEADLINE
+ default "cfq" if DEFAULT_CFQ
+ default "noop" if DEFAULT_NOOP
+
endmenu
diff --git a/block/Makefile b/block/Makefile
new file mode 100644
index 000000000000..7e4f93e2b44e
--- /dev/null
+++ b/block/Makefile
@@ -0,0 +1,10 @@
+#
+# Makefile for the kernel block layer
+#
+
+obj-y := elevator.o ll_rw_blk.o ioctl.o genhd.o scsi_ioctl.o
+
+obj-$(CONFIG_IOSCHED_NOOP) += noop-iosched.o
+obj-$(CONFIG_IOSCHED_AS) += as-iosched.o
+obj-$(CONFIG_IOSCHED_DEADLINE) += deadline-iosched.o
+obj-$(CONFIG_IOSCHED_CFQ) += cfq-iosched.o
diff --git a/drivers/block/as-iosched.c b/block/as-iosched.c
index 95c0a3690b0f..a78e160b59a3 100644
--- a/drivers/block/as-iosched.c
+++ b/block/as-iosched.c
@@ -4,7 +4,7 @@
* Anticipatory & deadline i/o scheduler.
*
* Copyright (C) 2002 Jens Axboe <axboe@suse.de>
- * Nick Piggin <piggin@cyberone.com.au>
+ * Nick Piggin <nickpiggin@yahoo.com.au>
*
*/
#include <linux/kernel.h>
@@ -69,7 +69,7 @@
/* Bits in as_io_context.state */
enum as_io_states {
- AS_TASK_RUNNING=0, /* Process has not exitted */
+ AS_TASK_RUNNING=0, /* Process has not exited */
AS_TASK_IOSTARTED, /* Process has started some IO */
AS_TASK_IORUNNING, /* Process has completed some IO */
};
@@ -98,11 +98,13 @@ struct as_data {
struct as_rq *next_arq[2]; /* next in sort order */
sector_t last_sector[2]; /* last REQ_SYNC & REQ_ASYNC sectors */
- struct list_head *dispatch; /* driver dispatch queue */
struct list_head *hash; /* request hash */
unsigned long exit_prob; /* probability a task will exit while
being waited on */
+ unsigned long exit_no_coop; /* probablility an exited task will
+ not be part of a later cooperating
+ request */
unsigned long new_ttime_total; /* mean thinktime on new proc */
unsigned long new_ttime_mean;
u64 new_seek_total; /* mean seek on new proc */
@@ -239,6 +241,25 @@ static struct io_context *as_get_io_context(void)
return ioc;
}
+static void as_put_io_context(struct as_rq *arq)
+{
+ struct as_io_context *aic;
+
+ if (unlikely(!arq->io_context))
+ return;
+
+ aic = arq->io_context->aic;
+
+ if (arq->is_sync == REQ_SYNC && aic) {
+ spin_lock(&aic->lock);
+ set_bit(AS_TASK_IORUNNING, &aic->state);
+ aic->last_end_request = jiffies;
+ spin_unlock(&aic->lock);
+ }
+
+ put_io_context(arq->io_context);
+}
+
/*
* the back merge hash support functions
*/
@@ -261,14 +282,6 @@ static inline void as_del_arq_hash(struct as_rq *arq)
__as_del_arq_hash(arq);
}
-static void as_remove_merge_hints(request_queue_t *q, struct as_rq *arq)
-{
- as_del_arq_hash(arq);
-
- if (q->last_merge == arq->request)
- q->last_merge = NULL;
-}
-
static void as_add_arq_hash(struct as_data *ad, struct as_rq *arq)
{
struct request *rq = arq->request;
@@ -312,7 +325,7 @@ static struct request *as_find_arq_hash(struct as_data *ad, sector_t offset)
BUG_ON(!arq->on_hash);
if (!rq_mergeable(__rq)) {
- as_remove_merge_hints(ad->q, arq);
+ as_del_arq_hash(arq);
continue;
}
@@ -626,37 +639,152 @@ static void as_antic_timeout(unsigned long data)
kblockd_schedule_work(&ad->antic_work);
if (aic->ttime_samples == 0) {
- /* process anticipated on has exitted or timed out*/
+ /* process anticipated on has exited or timed out*/
ad->exit_prob = (7*ad->exit_prob + 256)/8;
}
+ if (!test_bit(AS_TASK_RUNNING, &aic->state)) {
+ /* process not "saved" by a cooperating request */
+ ad->exit_no_coop = (7*ad->exit_no_coop + 256)/8;
+ }
}
spin_unlock_irqrestore(q->queue_lock, flags);
}
+static void as_update_thinktime(struct as_data *ad, struct as_io_context *aic,
+ unsigned long ttime)
+{
+ /* fixed point: 1.0 == 1<<8 */
+ if (aic->ttime_samples == 0) {
+ ad->new_ttime_total = (7*ad->new_ttime_total + 256*ttime) / 8;
+ ad->new_ttime_mean = ad->new_ttime_total / 256;
+
+ ad->exit_prob = (7*ad->exit_prob)/8;
+ }
+ aic->ttime_samples = (7*aic->ttime_samples + 256) / 8;
+ aic->ttime_total = (7*aic->ttime_total + 256*ttime) / 8;
+ aic->ttime_mean = (aic->ttime_total + 128) / aic->ttime_samples;
+}
+
+static void as_update_seekdist(struct as_data *ad, struct as_io_context *aic,
+ sector_t sdist)
+{
+ u64 total;
+
+ if (aic->seek_samples == 0) {
+ ad->new_seek_total = (7*ad->new_seek_total + 256*(u64)sdist)/8;
+ ad->new_seek_mean = ad->new_seek_total / 256;
+ }
+
+ /*
+ * Don't allow the seek distance to get too large from the
+ * odd fragment, pagein, etc
+ */
+ if (aic->seek_samples <= 60) /* second&third seek */
+ sdist = min(sdist, (aic->seek_mean * 4) + 2*1024*1024);
+ else
+ sdist = min(sdist, (aic->seek_mean * 4) + 2*1024*64);
+
+ aic->seek_samples = (7*aic->seek_samples + 256) / 8;
+ aic->seek_total = (7*aic->seek_total + (u64)256*sdist) / 8;
+ total = aic->seek_total + (aic->seek_samples/2);
+ do_div(total, aic->seek_samples);
+ aic->seek_mean = (sector_t)total;
+}
+
+/*
+ * as_update_iohist keeps a decaying histogram of IO thinktimes, and
+ * updates @aic->ttime_mean based on that. It is called when a new
+ * request is queued.
+ */
+static void as_update_iohist(struct as_data *ad, struct as_io_context *aic,
+ struct request *rq)
+{
+ struct as_rq *arq = RQ_DATA(rq);
+ int data_dir = arq->is_sync;
+ unsigned long thinktime = 0;
+ sector_t seek_dist;
+
+ if (aic == NULL)
+ return;
+
+ if (data_dir == REQ_SYNC) {
+ unsigned long in_flight = atomic_read(&aic->nr_queued)
+ + atomic_read(&aic->nr_dispatched);
+ spin_lock(&aic->lock);
+ if (test_bit(AS_TASK_IORUNNING, &aic->state) ||
+ test_bit(AS_TASK_IOSTARTED, &aic->state)) {
+ /* Calculate read -> read thinktime */
+ if (test_bit(AS_TASK_IORUNNING, &aic->state)
+ && in_flight == 0) {
+ thinktime = jiffies - aic->last_end_request;
+ thinktime = min(thinktime, MAX_THINKTIME-1);
+ }
+ 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;
+ else
+ seek_dist = aic->last_request_pos - rq->sector;
+ as_update_seekdist(ad, aic, seek_dist);
+ }
+ aic->last_request_pos = rq->sector + rq->nr_sectors;
+ set_bit(AS_TASK_IOSTARTED, &aic->state);
+ spin_unlock(&aic->lock);
+ }
+}
+
/*
* as_close_req decides if one request is considered "close" to the
* previous one issued.
*/
-static int as_close_req(struct as_data *ad, struct as_rq *arq)
+static int as_close_req(struct as_data *ad, struct as_io_context *aic,
+ struct as_rq *arq)
{
unsigned long delay; /* milliseconds */
sector_t last = ad->last_sector[ad->batch_data_dir];
sector_t next = arq->request->sector;
sector_t delta; /* acceptable close offset (in sectors) */
+ sector_t s;
if (ad->antic_status == ANTIC_OFF || !ad->ioc_finished)
delay = 0;
else
delay = ((jiffies - ad->antic_start) * 1000) / HZ;
- if (delay <= 1)
- delta = 64;
+ if (delay == 0)
+ delta = 8192;
else if (delay <= 20 && delay <= ad->antic_expire)
- delta = 64 << (delay-1);
+ delta = 8192 << delay;
else
return 1;
- return (last - (delta>>1) <= next) && (next <= last + delta);
+ if ((last <= next + (delta>>1)) && (next <= last + delta))
+ return 1;
+
+ if (last < next)
+ s = next - last;
+ else
+ s = last - next;
+
+ if (aic->seek_samples == 0) {
+ /*
+ * Process has just started IO. Use past statistics to
+ * gauge success possibility
+ */
+ if (ad->new_seek_mean > s) {
+ /* this request is better than what we're expecting */
+ return 1;
+ }
+
+ } else {
+ if (aic->seek_mean > s) {
+ /* this request is better than what we're expecting */
+ return 1;
+ }
+ }
+
+ return 0;
}
/*
@@ -668,7 +796,7 @@ static int as_close_req(struct as_data *ad, struct as_rq *arq)
* dispatch it ASAP, because we know that application will not be submitting
* any new reads.
*
- * If the task which has submitted the request has exitted, break anticipation.
+ * If the task which has submitted the request has exited, break anticipation.
*
* If this task has queued some other IO, do not enter enticipation.
*/
@@ -676,7 +804,6 @@ static int as_can_break_anticipation(struct as_data *ad, struct as_rq *arq)
{
struct io_context *ioc;
struct as_io_context *aic;
- sector_t s;
ioc = ad->io_context;
BUG_ON(!ioc);
@@ -698,13 +825,6 @@ static int as_can_break_anticipation(struct as_data *ad, struct as_rq *arq)
if (!aic)
return 0;
- if (!test_bit(AS_TASK_RUNNING, &aic->state)) {
- /* process anticipated on has exitted */
- if (aic->ttime_samples == 0)
- ad->exit_prob = (7*ad->exit_prob + 256)/8;
- return 1;
- }
-
if (atomic_read(&aic->nr_queued) > 0) {
/* process has more requests queued */
return 1;
@@ -715,57 +835,45 @@ static int as_can_break_anticipation(struct as_data *ad, struct as_rq *arq)
return 1;
}
- if (arq && arq->is_sync == REQ_SYNC && as_close_req(ad, arq)) {
+ if (arq && arq->is_sync == REQ_SYNC && as_close_req(ad, aic, arq)) {
/*
* Found a close request that is not one of ours.
*
- * This makes close requests from another process reset
- * our thinktime delay. Is generally useful when there are
+ * This makes close requests from another process update
+ * our IO history. Is generally useful when there are
* two or more cooperating processes working in the same
* area.
*/
- spin_lock(&aic->lock);
- aic->last_end_request = jiffies;
- spin_unlock(&aic->lock);
+ if (!test_bit(AS_TASK_RUNNING, &aic->state)) {
+ if (aic->ttime_samples == 0)
+ ad->exit_prob = (7*ad->exit_prob + 256)/8;
+
+ ad->exit_no_coop = (7*ad->exit_no_coop)/8;
+ }
+
+ as_update_iohist(ad, aic, arq->request);
return 1;
}
+ if (!test_bit(AS_TASK_RUNNING, &aic->state)) {
+ /* process anticipated on has exited */
+ if (aic->ttime_samples == 0)
+ ad->exit_prob = (7*ad->exit_prob + 256)/8;
+
+ if (ad->exit_no_coop > 128)
+ return 1;
+ }
if (aic->ttime_samples == 0) {
if (ad->new_ttime_mean > ad->antic_expire)
return 1;
- if (ad->exit_prob > 128)
+ if (ad->exit_prob * ad->exit_no_coop > 128*256)
return 1;
} else if (aic->ttime_mean > ad->antic_expire) {
/* the process thinks too much between requests */
return 1;
}
- if (!arq)
- return 0;
-
- if (ad->last_sector[REQ_SYNC] < arq->request->sector)
- s = arq->request->sector - ad->last_sector[REQ_SYNC];
- else
- s = ad->last_sector[REQ_SYNC] - arq->request->sector;
-
- if (aic->seek_samples == 0) {
- /*
- * Process has just started IO. Use past statistics to
- * guage success possibility
- */
- if (ad->new_seek_mean > s) {
- /* this request is better than what we're expecting */
- return 1;
- }
-
- } else {
- if (aic->seek_mean > s) {
- /* this request is better than what we're expecting */
- return 1;
- }
- }
-
return 0;
}
@@ -799,94 +907,11 @@ static int as_can_anticipate(struct as_data *ad, struct as_rq *arq)
* Status is either ANTIC_OFF so start waiting,
* ANTIC_WAIT_REQ so continue waiting for request to finish
* or ANTIC_WAIT_NEXT so continue waiting for an acceptable request.
- *
*/
return 1;
}
-static void as_update_thinktime(struct as_data *ad, struct as_io_context *aic, unsigned long ttime)
-{
- /* fixed point: 1.0 == 1<<8 */
- if (aic->ttime_samples == 0) {
- ad->new_ttime_total = (7*ad->new_ttime_total + 256*ttime) / 8;
- ad->new_ttime_mean = ad->new_ttime_total / 256;
-
- ad->exit_prob = (7*ad->exit_prob)/8;
- }
- aic->ttime_samples = (7*aic->ttime_samples + 256) / 8;
- aic->ttime_total = (7*aic->ttime_total + 256*ttime) / 8;
- aic->ttime_mean = (aic->ttime_total + 128) / aic->ttime_samples;
-}
-
-static void as_update_seekdist(struct as_data *ad, struct as_io_context *aic, sector_t sdist)
-{
- u64 total;
-
- if (aic->seek_samples == 0) {
- ad->new_seek_total = (7*ad->new_seek_total + 256*(u64)sdist)/8;
- ad->new_seek_mean = ad->new_seek_total / 256;
- }
-
- /*
- * Don't allow the seek distance to get too large from the
- * odd fragment, pagein, etc
- */
- if (aic->seek_samples <= 60) /* second&third seek */
- sdist = min(sdist, (aic->seek_mean * 4) + 2*1024*1024);
- else
- sdist = min(sdist, (aic->seek_mean * 4) + 2*1024*64);
-
- aic->seek_samples = (7*aic->seek_samples + 256) / 8;
- aic->seek_total = (7*aic->seek_total + (u64)256*sdist) / 8;
- total = aic->seek_total + (aic->seek_samples/2);
- do_div(total, aic->seek_samples);
- aic->seek_mean = (sector_t)total;
-}
-
-/*
- * as_update_iohist keeps a decaying histogram of IO thinktimes, and
- * updates @aic->ttime_mean based on that. It is called when a new
- * request is queued.
- */
-static void as_update_iohist(struct as_data *ad, struct as_io_context *aic, struct request *rq)
-{
- struct as_rq *arq = RQ_DATA(rq);
- int data_dir = arq->is_sync;
- unsigned long thinktime;
- sector_t seek_dist;
-
- if (aic == NULL)
- return;
-
- if (data_dir == REQ_SYNC) {
- unsigned long in_flight = atomic_read(&aic->nr_queued)
- + atomic_read(&aic->nr_dispatched);
- spin_lock(&aic->lock);
- if (test_bit(AS_TASK_IORUNNING, &aic->state) ||
- test_bit(AS_TASK_IOSTARTED, &aic->state)) {
- /* Calculate read -> read thinktime */
- if (test_bit(AS_TASK_IORUNNING, &aic->state)
- && in_flight == 0) {
- thinktime = jiffies - aic->last_end_request;
- thinktime = min(thinktime, MAX_THINKTIME-1);
- } else
- thinktime = 0;
- 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;
- else
- seek_dist = aic->last_request_pos - rq->sector;
- as_update_seekdist(ad, aic, seek_dist);
- }
- aic->last_request_pos = rq->sector + rq->nr_sectors;
- set_bit(AS_TASK_IOSTARTED, &aic->state);
- spin_unlock(&aic->lock);
- }
-}
-
/*
* as_update_arq must be called whenever a request (arq) is added to
* the sort_list. This function keeps caches up to date, and checks if the
@@ -950,23 +975,12 @@ static void as_completed_request(request_queue_t *q, struct request *rq)
WARN_ON(!list_empty(&rq->queuelist));
- if (arq->state == AS_RQ_PRESCHED) {
- WARN_ON(arq->io_context);
- goto out;
- }
-
- if (arq->state == AS_RQ_MERGED)
- goto out_ioc;
-
if (arq->state != AS_RQ_REMOVED) {
printk("arq->state %d\n", arq->state);
WARN_ON(1);
goto out;
}
- if (!blk_fs_request(rq))
- goto out;
-
if (ad->changed_batch && ad->nr_dispatched == 1) {
kblockd_schedule_work(&ad->antic_work);
ad->changed_batch = 0;
@@ -1001,21 +1015,7 @@ static void as_completed_request(request_queue_t *q, struct request *rq)
}
}
-out_ioc:
- if (!arq->io_context)
- goto out;
-
- if (arq->is_sync == REQ_SYNC) {
- struct as_io_context *aic = arq->io_context->aic;
- if (aic) {
- spin_lock(&aic->lock);
- set_bit(AS_TASK_IORUNNING, &aic->state);
- aic->last_end_request = jiffies;
- spin_unlock(&aic->lock);
- }
- }
-
- put_io_context(arq->io_context);
+ as_put_io_context(arq);
out:
arq->state = AS_RQ_POSTSCHED;
}
@@ -1047,73 +1047,11 @@ static void as_remove_queued_request(request_queue_t *q, struct request *rq)
ad->next_arq[data_dir] = as_find_next_arq(ad, arq);
list_del_init(&arq->fifo);
- as_remove_merge_hints(q, arq);
+ as_del_arq_hash(arq);
as_del_arq_rb(ad, arq);
}
/*
- * as_remove_dispatched_request is called to remove a request which has gone
- * to the dispatch list.
- */
-static void as_remove_dispatched_request(request_queue_t *q, struct request *rq)
-{
- struct as_rq *arq = RQ_DATA(rq);
- struct as_io_context *aic;
-
- if (!arq) {
- WARN_ON(1);
- return;
- }
-
- WARN_ON(arq->state != AS_RQ_DISPATCHED);
- WARN_ON(ON_RB(&arq->rb_node));
- if (arq->io_context && arq->io_context->aic) {
- aic = arq->io_context->aic;
- if (aic) {
- WARN_ON(!atomic_read(&aic->nr_dispatched));
- atomic_dec(&aic->nr_dispatched);
- }
- }
-}
-
-/*
- * as_remove_request is called when a driver has finished with a request.
- * This should be only called for dispatched requests, but for some reason
- * a POWER4 box running hwscan it does not.
- */
-static void as_remove_request(request_queue_t *q, struct request *rq)
-{
- struct as_rq *arq = RQ_DATA(rq);
-
- if (unlikely(arq->state == AS_RQ_NEW))
- goto out;
-
- if (ON_RB(&arq->rb_node)) {
- if (arq->state != AS_RQ_QUEUED) {
- printk("arq->state %d\n", arq->state);
- WARN_ON(1);
- goto out;
- }
- /*
- * We'll lose the aliased request(s) here. I don't think this
- * will ever happen, but if it does, hopefully someone will
- * report it.
- */
- WARN_ON(!list_empty(&rq->queuelist));
- as_remove_queued_request(q, rq);
- } else {
- if (arq->state != AS_RQ_DISPATCHED) {
- printk("arq->state %d\n", arq->state);
- WARN_ON(1);
- goto out;
- }
- as_remove_dispatched_request(q, rq);
- }
-out:
- arq->state = AS_RQ_REMOVED;
-}
-
-/*
* as_fifo_expired returns 0 if there are no expired reads on the fifo,
* 1 otherwise. It is ratelimited so that we only perform the check once per
* `fifo_expire' interval. Otherwise a large number of expired requests
@@ -1165,7 +1103,6 @@ static inline int as_batch_expired(struct as_data *ad)
static void as_move_to_dispatch(struct as_data *ad, struct as_rq *arq)
{
struct request *rq = arq->request;
- struct list_head *insert;
const int data_dir = arq->is_sync;
BUG_ON(!ON_RB(&arq->rb_node));
@@ -1198,13 +1135,13 @@ static void as_move_to_dispatch(struct as_data *ad, struct as_rq *arq)
/*
* take it off the sort and fifo list, add to dispatch queue
*/
- insert = ad->dispatch->prev;
-
while (!list_empty(&rq->queuelist)) {
struct request *__rq = list_entry_rq(rq->queuelist.next);
struct as_rq *__arq = RQ_DATA(__rq);
- list_move_tail(&__rq->queuelist, ad->dispatch);
+ list_del(&__rq->queuelist);
+
+ elv_dispatch_add_tail(ad->q, __rq);
if (__arq->io_context && __arq->io_context->aic)
atomic_inc(&__arq->io_context->aic->nr_dispatched);
@@ -1218,7 +1155,8 @@ static void as_move_to_dispatch(struct as_data *ad, struct as_rq *arq)
as_remove_queued_request(ad->q, rq);
WARN_ON(arq->state != AS_RQ_QUEUED);
- list_add(&rq->queuelist, insert);
+ elv_dispatch_sort(ad->q, rq);
+
arq->state = AS_RQ_DISPATCHED;
if (arq->io_context && arq->io_context->aic)
atomic_inc(&arq->io_context->aic->nr_dispatched);
@@ -1230,12 +1168,42 @@ static void as_move_to_dispatch(struct as_data *ad, struct as_rq *arq)
* read/write expire, batch expire, etc, and moves it to the dispatch
* queue. Returns 1 if a request was found, 0 otherwise.
*/
-static int as_dispatch_request(struct as_data *ad)
+static int as_dispatch_request(request_queue_t *q, int force)
{
+ struct as_data *ad = q->elevator->elevator_data;
struct as_rq *arq;
const int reads = !list_empty(&ad->fifo_list[REQ_SYNC]);
const int writes = !list_empty(&ad->fifo_list[REQ_ASYNC]);
+ if (unlikely(force)) {
+ /*
+ * Forced dispatch, accounting is useless. Reset
+ * accounting states and dump fifo_lists. Note that
+ * batch_data_dir is reset to REQ_SYNC to avoid
+ * screwing write batch accounting as write batch
+ * accounting occurs on W->R transition.
+ */
+ int dispatched = 0;
+
+ ad->batch_data_dir = REQ_SYNC;
+ ad->changed_batch = 0;
+ ad->new_batch = 0;
+
+ while (ad->next_arq[REQ_SYNC]) {
+ as_move_to_dispatch(ad, ad->next_arq[REQ_SYNC]);
+ dispatched++;
+ }
+ ad->last_check_fifo[REQ_SYNC] = jiffies;
+
+ while (ad->next_arq[REQ_ASYNC]) {
+ as_move_to_dispatch(ad, ad->next_arq[REQ_ASYNC]);
+ dispatched++;
+ }
+ ad->last_check_fifo[REQ_ASYNC] = jiffies;
+
+ return dispatched;
+ }
+
/* Signal that the write batch was uncontended, so we can't time it */
if (ad->batch_data_dir == REQ_ASYNC && !reads) {
if (ad->current_write_count == 0 || !writes)
@@ -1248,7 +1216,7 @@ static int as_dispatch_request(struct as_data *ad)
|| ad->changed_batch)
return 0;
- if (!(reads && writes && as_batch_expired(ad)) ) {
+ if (!(reads && writes && as_batch_expired(ad))) {
/*
* batch is still running or no reads or no writes
*/
@@ -1359,25 +1327,12 @@ fifo_expired:
return 1;
}
-static struct request *as_next_request(request_queue_t *q)
-{
- struct as_data *ad = q->elevator->elevator_data;
- struct request *rq = NULL;
-
- /*
- * if there are still requests on the dispatch queue, grab the first
- */
- if (!list_empty(ad->dispatch) || as_dispatch_request(ad))
- rq = list_entry_rq(ad->dispatch->next);
-
- return rq;
-}
-
/*
* Add arq to a list behind alias
*/
static inline void
-as_add_aliased_request(struct as_data *ad, struct as_rq *arq, struct as_rq *alias)
+as_add_aliased_request(struct as_data *ad, struct as_rq *arq,
+ struct as_rq *alias)
{
struct request *req = arq->request;
struct list_head *insert = alias->request->queuelist.prev;
@@ -1404,17 +1359,26 @@ as_add_aliased_request(struct as_data *ad, struct as_rq *arq, struct as_rq *alia
/*
* Don't want to have to handle merges.
*/
- as_remove_merge_hints(ad->q, arq);
+ as_del_arq_hash(arq);
+ arq->request->flags |= REQ_NOMERGE;
}
/*
* add arq to rbtree and fifo
*/
-static void as_add_request(struct as_data *ad, struct as_rq *arq)
+static void as_add_request(request_queue_t *q, struct request *rq)
{
+ struct as_data *ad = q->elevator->elevator_data;
+ struct as_rq *arq = RQ_DATA(rq);
struct as_rq *alias;
int data_dir;
+ if (arq->state != AS_RQ_PRESCHED) {
+ printk("arq->state: %d\n", arq->state);
+ WARN_ON(1);
+ }
+ arq->state = AS_RQ_NEW;
+
if (rq_data_dir(arq->request) == READ
|| current->flags&PF_SYNCWRITE)
arq->is_sync = 1;
@@ -1437,12 +1401,8 @@ static void as_add_request(struct as_data *ad, struct as_rq *arq)
arq->expires = jiffies + ad->fifo_expire[data_dir];
list_add_tail(&arq->fifo, &ad->fifo_list[data_dir]);
- if (rq_mergeable(arq->request)) {
+ if (rq_mergeable(arq->request))
as_add_arq_hash(ad, arq);
-
- if (!ad->q->last_merge)
- ad->q->last_merge = arq->request;
- }
as_update_arq(ad, arq); /* keep state machine up to date */
} else {
@@ -1463,96 +1423,24 @@ static void as_add_request(struct as_data *ad, struct as_rq *arq)
arq->state = AS_RQ_QUEUED;
}
-static void as_deactivate_request(request_queue_t *q, struct request *rq)
+static void as_activate_request(request_queue_t *q, struct request *rq)
{
- struct as_data *ad = q->elevator->elevator_data;
struct as_rq *arq = RQ_DATA(rq);
- if (arq) {
- if (arq->state == AS_RQ_REMOVED) {
- arq->state = AS_RQ_DISPATCHED;
- if (arq->io_context && arq->io_context->aic)
- atomic_inc(&arq->io_context->aic->nr_dispatched);
- }
- } else
- WARN_ON(blk_fs_request(rq)
- && (!(rq->flags & (REQ_HARDBARRIER|REQ_SOFTBARRIER))) );
-
- /* Stop anticipating - let this request get through */
- as_antic_stop(ad);
-}
-
-/*
- * requeue the request. The request has not been completed, nor is it a
- * new request, so don't touch accounting.
- */
-static void as_requeue_request(request_queue_t *q, struct request *rq)
-{
- as_deactivate_request(q, rq);
- list_add(&rq->queuelist, &q->queue_head);
-}
-
-/*
- * Account a request that is inserted directly onto the dispatch queue.
- * arq->io_context->aic->nr_dispatched should not need to be incremented
- * because only new requests should come through here: requeues go through
- * our explicit requeue handler.
- */
-static void as_account_queued_request(struct as_data *ad, struct request *rq)
-{
- if (blk_fs_request(rq)) {
- struct as_rq *arq = RQ_DATA(rq);
- arq->state = AS_RQ_DISPATCHED;
- ad->nr_dispatched++;
- }
+ WARN_ON(arq->state != AS_RQ_DISPATCHED);
+ arq->state = AS_RQ_REMOVED;
+ if (arq->io_context && arq->io_context->aic)
+ atomic_dec(&arq->io_context->aic->nr_dispatched);
}
-static void
-as_insert_request(request_queue_t *q, struct request *rq, int where)
+static void as_deactivate_request(request_queue_t *q, struct request *rq)
{
- struct as_data *ad = q->elevator->elevator_data;
struct as_rq *arq = RQ_DATA(rq);
- if (arq) {
- if (arq->state != AS_RQ_PRESCHED) {
- printk("arq->state: %d\n", arq->state);
- WARN_ON(1);
- }
- arq->state = AS_RQ_NEW;
- }
-
- /* barriers must flush the reorder queue */
- if (unlikely(rq->flags & (REQ_SOFTBARRIER | REQ_HARDBARRIER)
- && where == ELEVATOR_INSERT_SORT)) {
- WARN_ON(1);
- where = ELEVATOR_INSERT_BACK;
- }
-
- switch (where) {
- case ELEVATOR_INSERT_BACK:
- while (ad->next_arq[REQ_SYNC])
- as_move_to_dispatch(ad, ad->next_arq[REQ_SYNC]);
-
- while (ad->next_arq[REQ_ASYNC])
- as_move_to_dispatch(ad, ad->next_arq[REQ_ASYNC]);
-
- list_add_tail(&rq->queuelist, ad->dispatch);
- as_account_queued_request(ad, rq);
- as_antic_stop(ad);
- break;
- case ELEVATOR_INSERT_FRONT:
- list_add(&rq->queuelist, ad->dispatch);
- as_account_queued_request(ad, rq);
- as_antic_stop(ad);
- break;
- case ELEVATOR_INSERT_SORT:
- BUG_ON(!blk_fs_request(rq));
- as_add_request(ad, arq);
- break;
- default:
- BUG();
- return;
- }
+ WARN_ON(arq->state != AS_RQ_REMOVED);
+ arq->state = AS_RQ_DISPATCHED;
+ if (arq->io_context && arq->io_context->aic)
+ atomic_inc(&arq->io_context->aic->nr_dispatched);
}
/*
@@ -1565,16 +1453,12 @@ static int as_queue_empty(request_queue_t *q)
{
struct as_data *ad = q->elevator->elevator_data;
- if (!list_empty(&ad->fifo_list[REQ_ASYNC])
- || !list_empty(&ad->fifo_list[REQ_SYNC])
- || !list_empty(ad->dispatch))
- return 0;
-
- return 1;
+ return list_empty(&ad->fifo_list[REQ_ASYNC])
+ && list_empty(&ad->fifo_list[REQ_SYNC]);
}
-static struct request *
-as_former_request(request_queue_t *q, struct request *rq)
+static struct request *as_former_request(request_queue_t *q,
+ struct request *rq)
{
struct as_rq *arq = RQ_DATA(rq);
struct rb_node *rbprev = rb_prev(&arq->rb_node);
@@ -1586,8 +1470,8 @@ as_former_request(request_queue_t *q, struct request *rq)
return ret;
}
-static struct request *
-as_latter_request(request_queue_t *q, struct request *rq)
+static struct request *as_latter_request(request_queue_t *q,
+ struct request *rq)
{
struct as_rq *arq = RQ_DATA(rq);
struct rb_node *rbnext = rb_next(&arq->rb_node);
@@ -1608,15 +1492,6 @@ as_merge(request_queue_t *q, struct request **req, struct bio *bio)
int ret;
/*
- * try last_merge to avoid going to hash
- */
- ret = elv_try_last_merge(q, bio);
- if (ret != ELEVATOR_NO_MERGE) {
- __rq = q->last_merge;
- goto out_insert;
- }
-
- /*
* see if the merge hash can satisfy a back merge
*/
__rq = as_find_arq_hash(ad, bio->bi_sector);
@@ -1644,9 +1519,6 @@ as_merge(request_queue_t *q, struct request **req, struct bio *bio)
return ELEVATOR_NO_MERGE;
out:
- if (rq_mergeable(__rq))
- q->last_merge = __rq;
-out_insert:
if (ret) {
if (rq_mergeable(__rq))
as_hot_arq_hash(ad, RQ_DATA(__rq));
@@ -1681,7 +1553,7 @@ static void as_merged_request(request_queue_t *q, struct request *req)
* currently don't bother. Ditto the next function.
*/
as_del_arq_rb(ad, arq);
- if ((alias = as_add_arq_rb(ad, arq)) ) {
+ if ((alias = as_add_arq_rb(ad, arq))) {
list_del_init(&arq->fifo);
as_add_aliased_request(ad, arq, alias);
if (next_arq)
@@ -1693,14 +1565,10 @@ static void as_merged_request(request_queue_t *q, struct request *req)
* behind the disk head. We currently don't bother adjusting.
*/
}
-
- if (arq->on_hash)
- q->last_merge = req;
}
-static void
-as_merged_requests(request_queue_t *q, struct request *req,
- struct request *next)
+static void as_merged_requests(request_queue_t *q, struct request *req,
+ struct request *next)
{
struct as_data *ad = q->elevator->elevator_data;
struct as_rq *arq = RQ_DATA(req);
@@ -1723,7 +1591,7 @@ as_merged_requests(request_queue_t *q, struct request *req,
next_arq = as_find_next_arq(ad, arq);
as_del_arq_rb(ad, arq);
- if ((alias = as_add_arq_rb(ad, arq)) ) {
+ if ((alias = as_add_arq_rb(ad, arq))) {
list_del_init(&arq->fifo);
as_add_aliased_request(ad, arq, alias);
if (next_arq)
@@ -1763,6 +1631,7 @@ as_merged_requests(request_queue_t *q, struct request *req,
* kill knowledge of next, this one is a goner
*/
as_remove_queued_request(q, next);
+ as_put_io_context(anext);
anext->state = AS_RQ_MERGED;
}
@@ -1782,7 +1651,7 @@ static void as_work_handler(void *data)
unsigned long flags;
spin_lock_irqsave(q->queue_lock, flags);
- if (as_next_request(q))
+ if (!as_queue_empty(q))
q->request_fn(q);
spin_unlock_irqrestore(q->queue_lock, flags);
}
@@ -1797,7 +1666,9 @@ static void as_put_request(request_queue_t *q, struct request *rq)
return;
}
- if (arq->state != AS_RQ_POSTSCHED && arq->state != AS_RQ_PRESCHED) {
+ if (unlikely(arq->state != AS_RQ_POSTSCHED &&
+ arq->state != AS_RQ_PRESCHED &&
+ arq->state != AS_RQ_MERGED)) {
printk("arq->state %d\n", arq->state);
WARN_ON(1);
}
@@ -1807,7 +1678,7 @@ static void as_put_request(request_queue_t *q, struct request *rq)
}
static int as_set_request(request_queue_t *q, struct request *rq,
- struct bio *bio, int gfp_mask)
+ struct bio *bio, gfp_t gfp_mask)
{
struct as_data *ad = q->elevator->elevator_data;
struct as_rq *arq = mempool_alloc(ad->arq_pool, gfp_mask);
@@ -1907,7 +1778,6 @@ static int as_init_queue(request_queue_t *q, elevator_t *e)
INIT_LIST_HEAD(&ad->fifo_list[REQ_ASYNC]);
ad->sort_list[REQ_SYNC] = RB_ROOT;
ad->sort_list[REQ_ASYNC] = RB_ROOT;
- ad->dispatch = &q->queue_head;
ad->fifo_expire[REQ_SYNC] = default_read_expire;
ad->fifo_expire[REQ_ASYNC] = default_write_expire;
ad->antic_expire = default_antic_expire;
@@ -1951,9 +1821,14 @@ static ssize_t as_est_show(struct as_data *ad, char *page)
{
int pos = 0;
- pos += sprintf(page+pos, "%lu %% exit probability\n", 100*ad->exit_prob/256);
+ pos += sprintf(page+pos, "%lu %% exit probability\n",
+ 100*ad->exit_prob/256);
+ pos += sprintf(page+pos, "%lu %% probability of exiting without a "
+ "cooperating process submitting IO\n",
+ 100*ad->exit_no_coop/256);
pos += sprintf(page+pos, "%lu ms new thinktime\n", ad->new_ttime_mean);
- pos += sprintf(page+pos, "%llu sectors new seek distance\n", (unsigned long long)ad->new_seek_mean);
+ pos += sprintf(page+pos, "%llu sectors new seek distance\n",
+ (unsigned long long)ad->new_seek_mean);
return pos;
}
@@ -2072,10 +1947,9 @@ static struct elevator_type iosched_as = {
.elevator_merge_fn = as_merge,
.elevator_merged_fn = as_merged_request,
.elevator_merge_req_fn = as_merged_requests,
- .elevator_next_req_fn = as_next_request,
- .elevator_add_req_fn = as_insert_request,
- .elevator_remove_req_fn = as_remove_request,
- .elevator_requeue_req_fn = as_requeue_request,
+ .elevator_dispatch_fn = as_dispatch_request,
+ .elevator_add_req_fn = as_add_request,
+ .elevator_activate_req_fn = as_activate_request,
.elevator_deactivate_req_fn = as_deactivate_request,
.elevator_queue_empty_fn = as_queue_empty,
.elevator_completed_req_fn = as_completed_request,
@@ -2119,8 +1993,8 @@ static int __init as_init(void)
static void __exit as_exit(void)
{
- kmem_cache_destroy(arq_pool);
elv_unregister(&iosched_as);
+ kmem_cache_destroy(arq_pool);
}
module_init(as_init);
diff --git a/drivers/block/cfq-iosched.c b/block/cfq-iosched.c
index cd056e7e64ec..ecacca9c877e 100644
--- a/drivers/block/cfq-iosched.c
+++ b/block/cfq-iosched.c
@@ -84,7 +84,6 @@ static int cfq_max_depth = 2;
(node)->rb_left = NULL; \
} while (0)
#define RB_CLEAR_ROOT(root) ((root)->rb_node = NULL)
-#define ON_RB(node) ((node)->rb_color != RB_NONE)
#define rb_entry_crq(node) rb_entry((node), struct cfq_rq, rb_node)
#define rq_rb_key(rq) (rq)->sector
@@ -271,10 +270,7 @@ CFQ_CFQQ_FNS(expired);
#undef CFQ_CFQQ_FNS
enum cfq_rq_state_flags {
- CFQ_CRQ_FLAG_in_flight = 0,
- CFQ_CRQ_FLAG_in_driver,
- CFQ_CRQ_FLAG_is_sync,
- CFQ_CRQ_FLAG_requeued,
+ CFQ_CRQ_FLAG_is_sync = 0,
};
#define CFQ_CRQ_FNS(name) \
@@ -291,14 +287,11 @@ static inline int cfq_crq_##name(const struct cfq_rq *crq) \
return (crq->crq_flags & (1 << CFQ_CRQ_FLAG_##name)) != 0; \
}
-CFQ_CRQ_FNS(in_flight);
-CFQ_CRQ_FNS(in_driver);
CFQ_CRQ_FNS(is_sync);
-CFQ_CRQ_FNS(requeued);
#undef CFQ_CRQ_FNS
static struct cfq_queue *cfq_find_cfq_hash(struct cfq_data *, unsigned int, unsigned short);
-static void cfq_dispatch_sort(request_queue_t *, struct cfq_rq *);
+static void cfq_dispatch_insert(request_queue_t *, struct cfq_rq *);
static void cfq_put_cfqd(struct cfq_data *cfqd);
#define process_sync(tsk) ((tsk)->flags & PF_SYNCWRITE)
@@ -311,14 +304,6 @@ static inline void cfq_del_crq_hash(struct cfq_rq *crq)
hlist_del_init(&crq->hash);
}
-static void cfq_remove_merge_hints(request_queue_t *q, struct cfq_rq *crq)
-{
- cfq_del_crq_hash(crq);
-
- if (q->last_merge == crq->request)
- q->last_merge = NULL;
-}
-
static inline void cfq_add_crq_hash(struct cfq_data *cfqd, struct cfq_rq *crq)
{
const int hash_idx = CFQ_MHASH_FN(rq_hash_key(crq->request));
@@ -347,18 +332,13 @@ static struct request *cfq_find_rq_hash(struct cfq_data *cfqd, sector_t offset)
return NULL;
}
-static inline int cfq_pending_requests(struct cfq_data *cfqd)
-{
- return !list_empty(&cfqd->queue->queue_head) || cfqd->busy_queues;
-}
-
/*
* scheduler run of queue, if there are requests pending and no one in the
* driver that will restart queueing
*/
static inline void cfq_schedule_dispatch(struct cfq_data *cfqd)
{
- if (!cfqd->rq_in_driver && cfq_pending_requests(cfqd))
+ if (!cfqd->rq_in_driver && cfqd->busy_queues)
kblockd_schedule_work(&cfqd->unplug_work);
}
@@ -366,7 +346,7 @@ static int cfq_queue_empty(request_queue_t *q)
{
struct cfq_data *cfqd = q->elevator->elevator_data;
- return !cfq_pending_requests(cfqd);
+ return !cfqd->busy_queues;
}
/*
@@ -386,11 +366,6 @@ cfq_choose_req(struct cfq_data *cfqd, struct cfq_rq *crq1, struct cfq_rq *crq2)
if (crq2 == NULL)
return crq1;
- if (cfq_crq_requeued(crq1) && !cfq_crq_requeued(crq2))
- return crq1;
- else if (cfq_crq_requeued(crq2) && !cfq_crq_requeued(crq1))
- return crq2;
-
if (cfq_crq_is_sync(crq1) && !cfq_crq_is_sync(crq2))
return crq1;
else if (cfq_crq_is_sync(crq2) && !cfq_crq_is_sync(crq1))
@@ -461,10 +436,7 @@ cfq_find_next_crq(struct cfq_data *cfqd, struct cfq_queue *cfqq,
struct cfq_rq *crq_next = NULL, *crq_prev = NULL;
struct rb_node *rbnext, *rbprev;
- rbnext = NULL;
- if (ON_RB(&last->rb_node))
- rbnext = rb_next(&last->rb_node);
- if (!rbnext) {
+ if (!(rbnext = rb_next(&last->rb_node))) {
rbnext = rb_first(&cfqq->sort_list);
if (rbnext == &last->rb_node)
rbnext = NULL;
@@ -545,13 +517,13 @@ static void cfq_resort_rr_list(struct cfq_queue *cfqq, int preempted)
* the pending list according to last request service
*/
static inline void
-cfq_add_cfqq_rr(struct cfq_data *cfqd, struct cfq_queue *cfqq, int requeue)
+cfq_add_cfqq_rr(struct cfq_data *cfqd, struct cfq_queue *cfqq)
{
BUG_ON(cfq_cfqq_on_rr(cfqq));
cfq_mark_cfqq_on_rr(cfqq);
cfqd->busy_queues++;
- cfq_resort_rr_list(cfqq, requeue);
+ cfq_resort_rr_list(cfqq, 0);
}
static inline void
@@ -571,22 +543,19 @@ cfq_del_cfqq_rr(struct cfq_data *cfqd, struct cfq_queue *cfqq)
static inline void cfq_del_crq_rb(struct cfq_rq *crq)
{
struct cfq_queue *cfqq = crq->cfq_queue;
+ struct cfq_data *cfqd = cfqq->cfqd;
+ const int sync = cfq_crq_is_sync(crq);
- if (ON_RB(&crq->rb_node)) {
- struct cfq_data *cfqd = cfqq->cfqd;
- const int sync = cfq_crq_is_sync(crq);
-
- BUG_ON(!cfqq->queued[sync]);
- cfqq->queued[sync]--;
+ BUG_ON(!cfqq->queued[sync]);
+ cfqq->queued[sync]--;
- cfq_update_next_crq(crq);
+ cfq_update_next_crq(crq);
- rb_erase(&crq->rb_node, &cfqq->sort_list);
- RB_CLEAR_COLOR(&crq->rb_node);
+ rb_erase(&crq->rb_node, &cfqq->sort_list);
+ RB_CLEAR_COLOR(&crq->rb_node);
- if (cfq_cfqq_on_rr(cfqq) && RB_EMPTY(&cfqq->sort_list))
- cfq_del_cfqq_rr(cfqd, cfqq);
- }
+ if (cfq_cfqq_on_rr(cfqq) && RB_EMPTY(&cfqq->sort_list))
+ cfq_del_cfqq_rr(cfqd, cfqq);
}
static struct cfq_rq *
@@ -627,12 +596,12 @@ static void cfq_add_crq_rb(struct cfq_rq *crq)
* if that happens, put the alias on the dispatch list
*/
while ((__alias = __cfq_add_crq_rb(crq)) != NULL)
- cfq_dispatch_sort(cfqd->queue, __alias);
+ cfq_dispatch_insert(cfqd->queue, __alias);
rb_insert_color(&crq->rb_node, &cfqq->sort_list);
if (!cfq_cfqq_on_rr(cfqq))
- cfq_add_cfqq_rr(cfqd, cfqq, cfq_crq_requeued(crq));
+ cfq_add_cfqq_rr(cfqd, cfqq);
/*
* check if this request is a better next-serve candidate
@@ -643,10 +612,8 @@ static void cfq_add_crq_rb(struct cfq_rq *crq)
static inline void
cfq_reposition_crq_rb(struct cfq_queue *cfqq, struct cfq_rq *crq)
{
- if (ON_RB(&crq->rb_node)) {
- rb_erase(&crq->rb_node, &cfqq->sort_list);
- cfqq->queued[cfq_crq_is_sync(crq)]--;
- }
+ rb_erase(&crq->rb_node, &cfqq->sort_list);
+ cfqq->queued[cfq_crq_is_sync(crq)]--;
cfq_add_crq_rb(crq);
}
@@ -676,49 +643,28 @@ out:
return NULL;
}
-static void cfq_deactivate_request(request_queue_t *q, struct request *rq)
+static void cfq_activate_request(request_queue_t *q, struct request *rq)
{
struct cfq_data *cfqd = q->elevator->elevator_data;
- struct cfq_rq *crq = RQ_DATA(rq);
- if (crq) {
- struct cfq_queue *cfqq = crq->cfq_queue;
-
- if (cfq_crq_in_driver(crq)) {
- cfq_clear_crq_in_driver(crq);
- WARN_ON(!cfqd->rq_in_driver);
- cfqd->rq_in_driver--;
- }
- if (cfq_crq_in_flight(crq)) {
- const int sync = cfq_crq_is_sync(crq);
-
- cfq_clear_crq_in_flight(crq);
- WARN_ON(!cfqq->on_dispatch[sync]);
- cfqq->on_dispatch[sync]--;
- }
- cfq_mark_crq_requeued(crq);
- }
+ cfqd->rq_in_driver++;
}
-/*
- * make sure the service time gets corrected on reissue of this request
- */
-static void cfq_requeue_request(request_queue_t *q, struct request *rq)
+static void cfq_deactivate_request(request_queue_t *q, struct request *rq)
{
- cfq_deactivate_request(q, rq);
- list_add(&rq->queuelist, &q->queue_head);
+ struct cfq_data *cfqd = q->elevator->elevator_data;
+
+ WARN_ON(!cfqd->rq_in_driver);
+ cfqd->rq_in_driver--;
}
-static void cfq_remove_request(request_queue_t *q, struct request *rq)
+static void cfq_remove_request(struct request *rq)
{
struct cfq_rq *crq = RQ_DATA(rq);
- if (crq) {
- list_del_init(&rq->queuelist);
- cfq_del_crq_rb(crq);
- cfq_remove_merge_hints(q, crq);
-
- }
+ list_del_init(&rq->queuelist);
+ cfq_del_crq_rb(crq);
+ cfq_del_crq_hash(crq);
}
static int
@@ -728,12 +674,6 @@ cfq_merge(request_queue_t *q, struct request **req, struct bio *bio)
struct request *__rq;
int ret;
- ret = elv_try_last_merge(q, bio);
- if (ret != ELEVATOR_NO_MERGE) {
- __rq = q->last_merge;
- goto out_insert;
- }
-
__rq = cfq_find_rq_hash(cfqd, bio->bi_sector);
if (__rq && elv_rq_merge_ok(__rq, bio)) {
ret = ELEVATOR_BACK_MERGE;
@@ -748,8 +688,6 @@ cfq_merge(request_queue_t *q, struct request **req, struct bio *bio)
return ELEVATOR_NO_MERGE;
out:
- q->last_merge = __rq;
-out_insert:
*req = __rq;
return ret;
}
@@ -762,14 +700,12 @@ static void cfq_merged_request(request_queue_t *q, struct request *req)
cfq_del_crq_hash(crq);
cfq_add_crq_hash(cfqd, crq);
- if (ON_RB(&crq->rb_node) && (rq_rb_key(req) != crq->rb_key)) {
+ if (rq_rb_key(req) != crq->rb_key) {
struct cfq_queue *cfqq = crq->cfq_queue;
cfq_update_next_crq(crq);
cfq_reposition_crq_rb(cfqq, crq);
}
-
- q->last_merge = req;
}
static void
@@ -785,7 +721,7 @@ cfq_merged_requests(request_queue_t *q, struct request *rq,
time_before(next->start_time, rq->start_time))
list_move(&rq->queuelist, &next->queuelist);
- cfq_remove_request(q, next);
+ cfq_remove_request(next);
}
static inline void
@@ -992,53 +928,15 @@ static int cfq_arm_slice_timer(struct cfq_data *cfqd, struct cfq_queue *cfqq)
return 1;
}
-/*
- * we dispatch cfqd->cfq_quantum requests in total from the rr_list queues,
- * this function sector sorts the selected request to minimize seeks. we start
- * at cfqd->last_sector, not 0.
- */
-static void cfq_dispatch_sort(request_queue_t *q, struct cfq_rq *crq)
+static void cfq_dispatch_insert(request_queue_t *q, struct cfq_rq *crq)
{
struct cfq_data *cfqd = q->elevator->elevator_data;
struct cfq_queue *cfqq = crq->cfq_queue;
- struct list_head *head = &q->queue_head, *entry = head;
- struct request *__rq;
- sector_t last;
-
- list_del(&crq->request->queuelist);
-
- last = cfqd->last_sector;
- list_for_each_entry_reverse(__rq, head, queuelist) {
- struct cfq_rq *__crq = RQ_DATA(__rq);
-
- if (blk_barrier_rq(__rq))
- break;
- if (!blk_fs_request(__rq))
- break;
- if (cfq_crq_requeued(__crq))
- break;
-
- if (__rq->sector <= crq->request->sector)
- break;
- if (__rq->sector > last && crq->request->sector < last) {
- last = crq->request->sector + crq->request->nr_sectors;
- break;
- }
- entry = &__rq->queuelist;
- }
-
- cfqd->last_sector = last;
cfqq->next_crq = cfq_find_next_crq(cfqd, cfqq, crq);
-
- cfq_del_crq_rb(crq);
- cfq_remove_merge_hints(q, crq);
-
- cfq_mark_crq_in_flight(crq);
- cfq_clear_crq_requeued(crq);
-
+ cfq_remove_request(crq->request);
cfqq->on_dispatch[cfq_crq_is_sync(crq)]++;
- list_add_tail(&crq->request->queuelist, entry);
+ elv_dispatch_sort(q, crq->request);
}
/*
@@ -1159,7 +1057,7 @@ __cfq_dispatch_requests(struct cfq_data *cfqd, struct cfq_queue *cfqq,
/*
* finally, insert request into driver dispatch list
*/
- cfq_dispatch_sort(cfqd->queue, crq);
+ cfq_dispatch_insert(cfqd->queue, crq);
cfqd->dispatch_slice++;
dispatched++;
@@ -1194,7 +1092,7 @@ __cfq_dispatch_requests(struct cfq_data *cfqd, struct cfq_queue *cfqq,
}
static int
-cfq_dispatch_requests(request_queue_t *q, int max_dispatch, int force)
+cfq_dispatch_requests(request_queue_t *q, int force)
{
struct cfq_data *cfqd = q->elevator->elevator_data;
struct cfq_queue *cfqq;
@@ -1204,12 +1102,25 @@ cfq_dispatch_requests(request_queue_t *q, int max_dispatch, int force)
cfqq = cfq_select_queue(cfqd, force);
if (cfqq) {
+ int max_dispatch;
+
+ /*
+ * if idle window is disabled, allow queue buildup
+ */
+ if (!cfq_cfqq_idle_window(cfqq) &&
+ cfqd->rq_in_driver >= cfqd->cfq_max_depth)
+ return 0;
+
cfq_clear_cfqq_must_dispatch(cfqq);
cfq_clear_cfqq_wait_request(cfqq);
del_timer(&cfqd->idle_slice_timer);
- if (cfq_class_idle(cfqq))
- max_dispatch = 1;
+ if (!force) {
+ max_dispatch = cfqd->cfq_quantum;
+ if (cfq_class_idle(cfqq))
+ max_dispatch = 1;
+ } else
+ max_dispatch = INT_MAX;
return __cfq_dispatch_requests(cfqd, cfqq, max_dispatch);
}
@@ -1217,93 +1128,6 @@ cfq_dispatch_requests(request_queue_t *q, int max_dispatch, int force)
return 0;
}
-static inline void cfq_account_dispatch(struct cfq_rq *crq)
-{
- struct cfq_queue *cfqq = crq->cfq_queue;
- struct cfq_data *cfqd = cfqq->cfqd;
-
- if (unlikely(!blk_fs_request(crq->request)))
- return;
-
- /*
- * accounted bit is necessary since some drivers will call
- * elv_next_request() many times for the same request (eg ide)
- */
- if (cfq_crq_in_driver(crq))
- return;
-
- cfq_mark_crq_in_driver(crq);
- cfqd->rq_in_driver++;
-}
-
-static inline void
-cfq_account_completion(struct cfq_queue *cfqq, struct cfq_rq *crq)
-{
- struct cfq_data *cfqd = cfqq->cfqd;
- unsigned long now;
-
- if (!cfq_crq_in_driver(crq))
- return;
-
- now = jiffies;
-
- WARN_ON(!cfqd->rq_in_driver);
- cfqd->rq_in_driver--;
-
- if (!cfq_class_idle(cfqq))
- cfqd->last_end_request = now;
-
- if (!cfq_cfqq_dispatched(cfqq)) {
- if (cfq_cfqq_on_rr(cfqq)) {
- cfqq->service_last = now;
- cfq_resort_rr_list(cfqq, 0);
- }
- if (cfq_cfqq_expired(cfqq)) {
- __cfq_slice_expired(cfqd, cfqq, 0);
- cfq_schedule_dispatch(cfqd);
- }
- }
-
- if (cfq_crq_is_sync(crq))
- crq->io_context->last_end_request = now;
-}
-
-static struct request *cfq_next_request(request_queue_t *q)
-{
- struct cfq_data *cfqd = q->elevator->elevator_data;
- struct request *rq;
-
- if (!list_empty(&q->queue_head)) {
- struct cfq_rq *crq;
-dispatch:
- rq = list_entry_rq(q->queue_head.next);
-
- crq = RQ_DATA(rq);
- if (crq) {
- struct cfq_queue *cfqq = crq->cfq_queue;
-
- /*
- * if idle window is disabled, allow queue buildup
- */
- if (!cfq_crq_in_driver(crq) &&
- !cfq_cfqq_idle_window(cfqq) &&
- !blk_barrier_rq(rq) &&
- cfqd->rq_in_driver >= cfqd->cfq_max_depth)
- return NULL;
-
- cfq_remove_merge_hints(q, crq);
- cfq_account_dispatch(crq);
- }
-
- return rq;
- }
-
- if (cfq_dispatch_requests(q, cfqd->cfq_quantum, 0))
- goto dispatch;
-
- return NULL;
-}
-
/*
* task holds one reference to the queue, dropped when task exits. each crq
* in-flight on this queue also holds a reference, dropped when crq is freed.
@@ -1422,7 +1246,7 @@ static void cfq_exit_io_context(struct cfq_io_context *cic)
}
static struct cfq_io_context *
-cfq_alloc_io_context(struct cfq_data *cfqd, int gfp_mask)
+cfq_alloc_io_context(struct cfq_data *cfqd, gfp_t gfp_mask)
{
struct cfq_io_context *cic = kmem_cache_alloc(cfq_ioc_pool, gfp_mask);
@@ -1517,7 +1341,7 @@ static int cfq_ioc_set_ioprio(struct io_context *ioc, unsigned int ioprio)
static struct cfq_queue *
cfq_get_queue(struct cfq_data *cfqd, unsigned int key, unsigned short ioprio,
- int gfp_mask)
+ gfp_t gfp_mask)
{
const int hashval = hash_long(key, CFQ_QHASH_SHIFT);
struct cfq_queue *cfqq, *new_cfqq = NULL;
@@ -1578,7 +1402,7 @@ out:
* cfqq, so we don't need to worry about it disappearing
*/
static struct cfq_io_context *
-cfq_get_io_context(struct cfq_data *cfqd, pid_t pid, int gfp_mask)
+cfq_get_io_context(struct cfq_data *cfqd, pid_t pid, gfp_t gfp_mask)
{
struct io_context *ioc = NULL;
struct cfq_io_context *cic;
@@ -1816,8 +1640,9 @@ cfq_crq_enqueued(struct cfq_data *cfqd, struct cfq_queue *cfqq,
}
}
-static void cfq_enqueue(struct cfq_data *cfqd, struct request *rq)
+static void cfq_insert_request(request_queue_t *q, struct request *rq)
{
+ struct cfq_data *cfqd = q->elevator->elevator_data;
struct cfq_rq *crq = RQ_DATA(rq);
struct cfq_queue *cfqq = crq->cfq_queue;
@@ -1827,66 +1652,43 @@ static void cfq_enqueue(struct cfq_data *cfqd, struct request *rq)
list_add_tail(&rq->queuelist, &cfqq->fifo);
- if (rq_mergeable(rq)) {
+ if (rq_mergeable(rq))
cfq_add_crq_hash(cfqd, crq);
- if (!cfqd->queue->last_merge)
- cfqd->queue->last_merge = rq;
- }
-
cfq_crq_enqueued(cfqd, cfqq, crq);
}
-static void
-cfq_insert_request(request_queue_t *q, struct request *rq, int where)
-{
- struct cfq_data *cfqd = q->elevator->elevator_data;
-
- switch (where) {
- case ELEVATOR_INSERT_BACK:
- while (cfq_dispatch_requests(q, INT_MAX, 1))
- ;
- list_add_tail(&rq->queuelist, &q->queue_head);
- /*
- * If we were idling with pending requests on
- * inactive cfqqs, force dispatching will
- * remove the idle timer and the queue won't
- * be kicked by __make_request() afterward.
- * Kick it here.
- */
- cfq_schedule_dispatch(cfqd);
- break;
- case ELEVATOR_INSERT_FRONT:
- list_add(&rq->queuelist, &q->queue_head);
- break;
- case ELEVATOR_INSERT_SORT:
- BUG_ON(!blk_fs_request(rq));
- cfq_enqueue(cfqd, rq);
- break;
- default:
- printk("%s: bad insert point %d\n", __FUNCTION__,where);
- return;
- }
-}
-
static void cfq_completed_request(request_queue_t *q, struct request *rq)
{
struct cfq_rq *crq = RQ_DATA(rq);
- struct cfq_queue *cfqq;
+ struct cfq_queue *cfqq = crq->cfq_queue;
+ struct cfq_data *cfqd = cfqq->cfqd;
+ const int sync = cfq_crq_is_sync(crq);
+ unsigned long now;
- if (unlikely(!blk_fs_request(rq)))
- return;
+ now = jiffies;
- cfqq = crq->cfq_queue;
+ WARN_ON(!cfqd->rq_in_driver);
+ WARN_ON(!cfqq->on_dispatch[sync]);
+ cfqd->rq_in_driver--;
+ cfqq->on_dispatch[sync]--;
- if (cfq_crq_in_flight(crq)) {
- const int sync = cfq_crq_is_sync(crq);
+ if (!cfq_class_idle(cfqq))
+ cfqd->last_end_request = now;
- WARN_ON(!cfqq->on_dispatch[sync]);
- cfqq->on_dispatch[sync]--;
+ if (!cfq_cfqq_dispatched(cfqq)) {
+ if (cfq_cfqq_on_rr(cfqq)) {
+ cfqq->service_last = now;
+ cfq_resort_rr_list(cfqq, 0);
+ }
+ if (cfq_cfqq_expired(cfqq)) {
+ __cfq_slice_expired(cfqd, cfqq, 0);
+ cfq_schedule_dispatch(cfqd);
+ }
}
- cfq_account_completion(cfqq, crq);
+ if (cfq_crq_is_sync(crq))
+ crq->io_context->last_end_request = now;
}
static struct request *
@@ -2075,7 +1877,7 @@ static void cfq_put_request(request_queue_t *q, struct request *rq)
*/
static int
cfq_set_request(request_queue_t *q, struct request *rq, struct bio *bio,
- int gfp_mask)
+ gfp_t gfp_mask)
{
struct cfq_data *cfqd = q->elevator->elevator_data;
struct task_struct *tsk = current;
@@ -2118,9 +1920,6 @@ cfq_set_request(request_queue_t *q, struct request *rq, struct bio *bio,
INIT_HLIST_NODE(&crq->hash);
crq->cfq_queue = cfqq;
crq->io_context = cic;
- cfq_clear_crq_in_flight(crq);
- cfq_clear_crq_in_driver(crq);
- cfq_clear_crq_requeued(crq);
if (rw == READ || process_sync(tsk))
cfq_mark_crq_is_sync(crq);
@@ -2201,7 +2000,7 @@ static void cfq_idle_slice_timer(unsigned long data)
* only expire and reinvoke request handler, if there are
* other queues with pending requests
*/
- if (!cfq_pending_requests(cfqd)) {
+ if (!cfqd->busy_queues) {
cfqd->idle_slice_timer.expires = min(now + cfqd->cfq_slice_idle, cfqq->slice_end);
add_timer(&cfqd->idle_slice_timer);
goto out_cont;
@@ -2260,10 +2059,8 @@ static void cfq_put_cfqd(struct cfq_data *cfqd)
if (!atomic_dec_and_test(&cfqd->ref))
return;
- blk_put_queue(q);
-
cfq_shutdown_timer_wq(cfqd);
- q->elevator->elevator_data = NULL;
+ blk_put_queue(q);
mempool_destroy(cfqd->crq_pool);
kfree(cfqd->crq_hash);
@@ -2576,10 +2373,9 @@ static struct elevator_type iosched_cfq = {
.elevator_merge_fn = cfq_merge,
.elevator_merged_fn = cfq_merged_request,
.elevator_merge_req_fn = cfq_merged_requests,
- .elevator_next_req_fn = cfq_next_request,
+ .elevator_dispatch_fn = cfq_dispatch_requests,
.elevator_add_req_fn = cfq_insert_request,
- .elevator_remove_req_fn = cfq_remove_request,
- .elevator_requeue_req_fn = cfq_requeue_request,
+ .elevator_activate_req_fn = cfq_activate_request,
.elevator_deactivate_req_fn = cfq_deactivate_request,
.elevator_queue_empty_fn = cfq_queue_empty,
.elevator_completed_req_fn = cfq_completed_request,
@@ -2620,28 +2416,8 @@ static int __init cfq_init(void)
static void __exit cfq_exit(void)
{
- struct task_struct *g, *p;
- unsigned long flags;
-
- read_lock_irqsave(&tasklist_lock, flags);
-
- /*
- * iterate each process in the system, removing our io_context
- */
- do_each_thread(g, p) {
- struct io_context *ioc = p->io_context;
-
- if (ioc && ioc->cic) {
- ioc->cic->exit(ioc->cic);
- cfq_free_io_context(ioc->cic);
- ioc->cic = NULL;
- }
- } while_each_thread(g, p);
-
- read_unlock_irqrestore(&tasklist_lock, flags);
-
- cfq_slab_kill();
elv_unregister(&iosched_cfq);
+ cfq_slab_kill();
}
module_init(cfq_init);
diff --git a/drivers/block/deadline-iosched.c b/block/deadline-iosched.c
index 52a3ae5289a0..7929471d7df7 100644
--- a/drivers/block/deadline-iosched.c
+++ b/block/deadline-iosched.c
@@ -50,7 +50,6 @@ struct deadline_data {
* next in sort order. read, write or both are NULL
*/
struct deadline_rq *next_drq[2];
- struct list_head *dispatch; /* driver dispatch queue */
struct list_head *hash; /* request hash */
unsigned int batching; /* number of sequential requests made */
sector_t last_sector; /* head position */
@@ -113,15 +112,6 @@ static inline void deadline_del_drq_hash(struct deadline_rq *drq)
__deadline_del_drq_hash(drq);
}
-static void
-deadline_remove_merge_hints(request_queue_t *q, struct deadline_rq *drq)
-{
- deadline_del_drq_hash(drq);
-
- if (q->last_merge == drq->request)
- q->last_merge = NULL;
-}
-
static inline void
deadline_add_drq_hash(struct deadline_data *dd, struct deadline_rq *drq)
{
@@ -239,10 +229,9 @@ deadline_del_drq_rb(struct deadline_data *dd, struct deadline_rq *drq)
dd->next_drq[data_dir] = rb_entry_drq(rbnext);
}
- if (ON_RB(&drq->rb_node)) {
- rb_erase(&drq->rb_node, DRQ_RB_ROOT(dd, drq));
- RB_CLEAR(&drq->rb_node);
- }
+ BUG_ON(!ON_RB(&drq->rb_node));
+ rb_erase(&drq->rb_node, DRQ_RB_ROOT(dd, drq));
+ RB_CLEAR(&drq->rb_node);
}
static struct request *
@@ -286,7 +275,7 @@ deadline_find_first_drq(struct deadline_data *dd, int data_dir)
/*
* add drq to rbtree and fifo
*/
-static inline void
+static void
deadline_add_request(struct request_queue *q, struct request *rq)
{
struct deadline_data *dd = q->elevator->elevator_data;
@@ -301,12 +290,8 @@ deadline_add_request(struct request_queue *q, struct request *rq)
drq->expires = jiffies + dd->fifo_expire[data_dir];
list_add_tail(&drq->fifo, &dd->fifo_list[data_dir]);
- if (rq_mergeable(rq)) {
+ if (rq_mergeable(rq))
deadline_add_drq_hash(dd, drq);
-
- if (!q->last_merge)
- q->last_merge = rq;
- }
}
/*
@@ -315,14 +300,11 @@ deadline_add_request(struct request_queue *q, struct request *rq)
static void deadline_remove_request(request_queue_t *q, struct request *rq)
{
struct deadline_rq *drq = RQ_DATA(rq);
+ struct deadline_data *dd = q->elevator->elevator_data;
- if (drq) {
- struct deadline_data *dd = q->elevator->elevator_data;
-
- list_del_init(&drq->fifo);
- deadline_remove_merge_hints(q, drq);
- deadline_del_drq_rb(dd, drq);
- }
+ list_del_init(&drq->fifo);
+ deadline_del_drq_rb(dd, drq);
+ deadline_del_drq_hash(drq);
}
static int
@@ -333,15 +315,6 @@ deadline_merge(request_queue_t *q, struct request **req, struct bio *bio)
int ret;
/*
- * try last_merge to avoid going to hash
- */
- ret = elv_try_last_merge(q, bio);
- if (ret != ELEVATOR_NO_MERGE) {
- __rq = q->last_merge;
- goto out_insert;
- }
-
- /*
* see if the merge hash can satisfy a back merge
*/
__rq = deadline_find_drq_hash(dd, bio->bi_sector);
@@ -373,8 +346,6 @@ deadline_merge(request_queue_t *q, struct request **req, struct bio *bio)
return ELEVATOR_NO_MERGE;
out:
- q->last_merge = __rq;
-out_insert:
if (ret)
deadline_hot_drq_hash(dd, RQ_DATA(__rq));
*req = __rq;
@@ -399,8 +370,6 @@ static void deadline_merged_request(request_queue_t *q, struct request *req)
deadline_del_drq_rb(dd, drq);
deadline_add_drq_rb(dd, drq);
}
-
- q->last_merge = req;
}
static void
@@ -452,7 +421,7 @@ deadline_move_to_dispatch(struct deadline_data *dd, struct deadline_rq *drq)
request_queue_t *q = drq->request->q;
deadline_remove_request(q, drq->request);
- list_add_tail(&drq->request->queuelist, dd->dispatch);
+ elv_dispatch_add_tail(q, drq->request);
}
/*
@@ -502,8 +471,9 @@ static inline int deadline_check_fifo(struct deadline_data *dd, int ddir)
* deadline_dispatch_requests selects the best request according to
* read/write expire, fifo_batch, etc
*/
-static int deadline_dispatch_requests(struct deadline_data *dd)
+static int deadline_dispatch_requests(request_queue_t *q, int force)
{
+ struct deadline_data *dd = q->elevator->elevator_data;
const int reads = !list_empty(&dd->fifo_list[READ]);
const int writes = !list_empty(&dd->fifo_list[WRITE]);
struct deadline_rq *drq;
@@ -597,65 +567,12 @@ dispatch_request:
return 1;
}
-static struct request *deadline_next_request(request_queue_t *q)
-{
- struct deadline_data *dd = q->elevator->elevator_data;
- struct request *rq;
-
- /*
- * if there are still requests on the dispatch queue, grab the first one
- */
- if (!list_empty(dd->dispatch)) {
-dispatch:
- rq = list_entry_rq(dd->dispatch->next);
- return rq;
- }
-
- if (deadline_dispatch_requests(dd))
- goto dispatch;
-
- return NULL;
-}
-
-static void
-deadline_insert_request(request_queue_t *q, struct request *rq, int where)
-{
- struct deadline_data *dd = q->elevator->elevator_data;
-
- /* barriers must flush the reorder queue */
- if (unlikely(rq->flags & (REQ_SOFTBARRIER | REQ_HARDBARRIER)
- && where == ELEVATOR_INSERT_SORT))
- where = ELEVATOR_INSERT_BACK;
-
- switch (where) {
- case ELEVATOR_INSERT_BACK:
- while (deadline_dispatch_requests(dd))
- ;
- list_add_tail(&rq->queuelist, dd->dispatch);
- break;
- case ELEVATOR_INSERT_FRONT:
- list_add(&rq->queuelist, dd->dispatch);
- break;
- case ELEVATOR_INSERT_SORT:
- BUG_ON(!blk_fs_request(rq));
- deadline_add_request(q, rq);
- break;
- default:
- printk("%s: bad insert point %d\n", __FUNCTION__,where);
- return;
- }
-}
-
static int deadline_queue_empty(request_queue_t *q)
{
struct deadline_data *dd = q->elevator->elevator_data;
- if (!list_empty(&dd->fifo_list[WRITE])
- || !list_empty(&dd->fifo_list[READ])
- || !list_empty(dd->dispatch))
- return 0;
-
- return 1;
+ return list_empty(&dd->fifo_list[WRITE])
+ && list_empty(&dd->fifo_list[READ]);
}
static struct request *
@@ -733,7 +650,6 @@ static int deadline_init_queue(request_queue_t *q, elevator_t *e)
INIT_LIST_HEAD(&dd->fifo_list[WRITE]);
dd->sort_list[READ] = RB_ROOT;
dd->sort_list[WRITE] = RB_ROOT;
- dd->dispatch = &q->queue_head;
dd->fifo_expire[READ] = read_expire;
dd->fifo_expire[WRITE] = write_expire;
dd->writes_starved = writes_starved;
@@ -748,15 +664,13 @@ static void deadline_put_request(request_queue_t *q, struct request *rq)
struct deadline_data *dd = q->elevator->elevator_data;
struct deadline_rq *drq = RQ_DATA(rq);
- if (drq) {
- mempool_free(drq, dd->drq_pool);
- rq->elevator_private = NULL;
- }
+ mempool_free(drq, dd->drq_pool);
+ rq->elevator_private = NULL;
}
static int
deadline_set_request(request_queue_t *q, struct request *rq, struct bio *bio,
- int gfp_mask)
+ gfp_t gfp_mask)
{
struct deadline_data *dd = q->elevator->elevator_data;
struct deadline_rq *drq;
@@ -917,9 +831,8 @@ static struct elevator_type iosched_deadline = {
.elevator_merge_fn = deadline_merge,
.elevator_merged_fn = deadline_merged_request,
.elevator_merge_req_fn = deadline_merged_requests,
- .elevator_next_req_fn = deadline_next_request,
- .elevator_add_req_fn = deadline_insert_request,
- .elevator_remove_req_fn = deadline_remove_request,
+ .elevator_dispatch_fn = deadline_dispatch_requests,
+ .elevator_add_req_fn = deadline_add_request,
.elevator_queue_empty_fn = deadline_queue_empty,
.elevator_former_req_fn = deadline_former_request,
.elevator_latter_req_fn = deadline_latter_request,
diff --git a/drivers/block/elevator.c b/block/elevator.c
index 98f0126a2deb..d4a49a3df829 100644
--- a/drivers/block/elevator.c
+++ b/block/elevator.c
@@ -34,6 +34,7 @@
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/compiler.h>
+#include <linux/delay.h>
#include <asm/uaccess.h>
@@ -83,21 +84,11 @@ inline int elv_try_merge(struct request *__rq, struct bio *bio)
}
EXPORT_SYMBOL(elv_try_merge);
-inline int elv_try_last_merge(request_queue_t *q, struct bio *bio)
-{
- if (q->last_merge)
- return elv_try_merge(q->last_merge, bio);
-
- return ELEVATOR_NO_MERGE;
-}
-EXPORT_SYMBOL(elv_try_last_merge);
-
static struct elevator_type *elevator_find(const char *name)
{
struct elevator_type *e = NULL;
struct list_head *entry;
- spin_lock_irq(&elv_list_lock);
list_for_each(entry, &elv_list) {
struct elevator_type *__e;
@@ -108,7 +99,6 @@ static struct elevator_type *elevator_find(const char *name)
break;
}
}
- spin_unlock_irq(&elv_list_lock);
return e;
}
@@ -120,12 +110,15 @@ static void elevator_put(struct elevator_type *e)
static struct elevator_type *elevator_get(const char *name)
{
- struct elevator_type *e = elevator_find(name);
+ struct elevator_type *e;
- if (!e)
- return NULL;
- if (!try_module_get(e->elevator_owner))
- return NULL;
+ spin_lock_irq(&elv_list_lock);
+
+ e = elevator_find(name);
+ if (e && !try_module_get(e->elevator_owner))
+ e = NULL;
+
+ spin_unlock_irq(&elv_list_lock);
return e;
}
@@ -139,8 +132,6 @@ static int elevator_attach(request_queue_t *q, struct elevator_type *e,
eq->ops = &e->ops;
eq->elevator_type = e;
- INIT_LIST_HEAD(&q->queue_head);
- q->last_merge = NULL;
q->elevator = eq;
if (eq->ops->elevator_init_fn)
@@ -153,23 +144,20 @@ static char chosen_elevator[16];
static void elevator_setup_default(void)
{
+ struct elevator_type *e;
+
/*
- * check if default is set and exists
+ * If default has not been set, use the compiled-in selection.
*/
- if (chosen_elevator[0] && elevator_find(chosen_elevator))
- return;
-
-#if defined(CONFIG_IOSCHED_AS)
- strcpy(chosen_elevator, "anticipatory");
-#elif defined(CONFIG_IOSCHED_DEADLINE)
- strcpy(chosen_elevator, "deadline");
-#elif defined(CONFIG_IOSCHED_CFQ)
- strcpy(chosen_elevator, "cfq");
-#elif defined(CONFIG_IOSCHED_NOOP)
- strcpy(chosen_elevator, "noop");
-#else
-#error "You must build at least 1 IO scheduler into the kernel"
-#endif
+ if (!chosen_elevator[0])
+ strcpy(chosen_elevator, CONFIG_DEFAULT_IOSCHED);
+
+ /*
+ * If the given scheduler is not available, fall back to no-op.
+ */
+ if (!(e = elevator_find(chosen_elevator)))
+ strcpy(chosen_elevator, "noop");
+ elevator_put(e);
}
static int __init elevator_setup(char *str)
@@ -186,6 +174,11 @@ int elevator_init(request_queue_t *q, char *name)
struct elevator_queue *eq;
int ret = 0;
+ INIT_LIST_HEAD(&q->queue_head);
+ q->last_merge = NULL;
+ q->end_sector = 0;
+ q->boundary_rq = NULL;
+
elevator_setup_default();
if (!name)
@@ -220,9 +213,52 @@ void elevator_exit(elevator_t *e)
kfree(e);
}
+/*
+ * Insert rq into dispatch queue of q. Queue lock must be held on
+ * entry. If sort != 0, rq is sort-inserted; otherwise, rq will be
+ * appended to the dispatch queue. To be used by specific elevators.
+ */
+void elv_dispatch_sort(request_queue_t *q, struct request *rq)
+{
+ sector_t boundary;
+ struct list_head *entry;
+
+ if (q->last_merge == rq)
+ q->last_merge = NULL;
+
+ boundary = q->end_sector;
+
+ list_for_each_prev(entry, &q->queue_head) {
+ struct request *pos = list_entry_rq(entry);
+
+ if (pos->flags & (REQ_SOFTBARRIER|REQ_HARDBARRIER|REQ_STARTED))
+ break;
+ if (rq->sector >= boundary) {
+ if (pos->sector < boundary)
+ continue;
+ } else {
+ if (pos->sector >= boundary)
+ break;
+ }
+ if (rq->sector >= pos->sector)
+ break;
+ }
+
+ list_add(&rq->queuelist, entry);
+}
+
int elv_merge(request_queue_t *q, struct request **req, struct bio *bio)
{
elevator_t *e = q->elevator;
+ int ret;
+
+ if (q->last_merge) {
+ ret = elv_try_merge(q->last_merge, bio);
+ if (ret != ELEVATOR_NO_MERGE) {
+ *req = q->last_merge;
+ return ret;
+ }
+ }
if (e->ops->elevator_merge_fn)
return e->ops->elevator_merge_fn(q, req, bio);
@@ -236,6 +272,8 @@ void elv_merged_request(request_queue_t *q, struct request *rq)
if (e->ops->elevator_merged_fn)
e->ops->elevator_merged_fn(q, rq);
+
+ q->last_merge = rq;
}
void elv_merge_requests(request_queue_t *q, struct request *rq,
@@ -243,20 +281,13 @@ void elv_merge_requests(request_queue_t *q, struct request *rq,
{
elevator_t *e = q->elevator;
- if (q->last_merge == next)
- q->last_merge = NULL;
-
if (e->ops->elevator_merge_req_fn)
e->ops->elevator_merge_req_fn(q, rq, next);
+
+ q->last_merge = rq;
}
-/*
- * For careful internal use by the block layer. Essentially the same as
- * a requeue in that it tells the io scheduler that this request is not
- * active in the driver or hardware anymore, but we don't want the request
- * added back to the scheduler. Function is not exported.
- */
-void elv_deactivate_request(request_queue_t *q, struct request *rq)
+void elv_requeue_request(request_queue_t *q, struct request *rq)
{
elevator_t *e = q->elevator;
@@ -264,19 +295,14 @@ void elv_deactivate_request(request_queue_t *q, struct request *rq)
* it already went through dequeue, we need to decrement the
* in_flight count again
*/
- if (blk_account_rq(rq))
+ if (blk_account_rq(rq)) {
q->in_flight--;
+ if (blk_sorted_rq(rq) && e->ops->elevator_deactivate_req_fn)
+ e->ops->elevator_deactivate_req_fn(q, rq);
+ }
rq->flags &= ~REQ_STARTED;
- if (e->ops->elevator_deactivate_req_fn)
- e->ops->elevator_deactivate_req_fn(q, rq);
-}
-
-void elv_requeue_request(request_queue_t *q, struct request *rq)
-{
- elv_deactivate_request(q, rq);
-
/*
* if this is the flush, requeue the original instead and drop the flush
*/
@@ -285,31 +311,27 @@ void elv_requeue_request(request_queue_t *q, struct request *rq)
rq = rq->end_io_data;
}
- /*
- * the request is prepped and may have some resources allocated.
- * allowing unprepped requests to pass this one may cause resource
- * deadlock. turn on softbarrier.
- */
- rq->flags |= REQ_SOFTBARRIER;
-
- /*
- * if iosched has an explicit requeue hook, then use that. otherwise
- * just put the request at the front of the queue
- */
- if (q->elevator->ops->elevator_requeue_req_fn)
- q->elevator->ops->elevator_requeue_req_fn(q, rq);
- else
- __elv_add_request(q, rq, ELEVATOR_INSERT_FRONT, 0);
+ __elv_add_request(q, rq, ELEVATOR_INSERT_FRONT, 0);
}
void __elv_add_request(request_queue_t *q, struct request *rq, int where,
int plug)
{
- /*
- * barriers implicitly indicate back insertion
- */
- if (rq->flags & (REQ_SOFTBARRIER | REQ_HARDBARRIER) &&
- where == ELEVATOR_INSERT_SORT)
+ if (rq->flags & (REQ_SOFTBARRIER | REQ_HARDBARRIER)) {
+ /*
+ * barriers implicitly indicate back insertion
+ */
+ if (where == ELEVATOR_INSERT_SORT)
+ where = ELEVATOR_INSERT_BACK;
+
+ /*
+ * this request is scheduling boundary, update end_sector
+ */
+ if (blk_fs_request(rq)) {
+ q->end_sector = rq_end_sector(rq);
+ q->boundary_rq = rq;
+ }
+ } else if (!(rq->flags & REQ_ELVPRIV) && where == ELEVATOR_INSERT_SORT)
where = ELEVATOR_INSERT_BACK;
if (plug)
@@ -317,23 +339,59 @@ void __elv_add_request(request_queue_t *q, struct request *rq, int where,
rq->q = q;
- if (!test_bit(QUEUE_FLAG_DRAIN, &q->queue_flags)) {
- q->elevator->ops->elevator_add_req_fn(q, rq, where);
+ switch (where) {
+ case ELEVATOR_INSERT_FRONT:
+ rq->flags |= REQ_SOFTBARRIER;
- if (blk_queue_plugged(q)) {
- int nrq = q->rq.count[READ] + q->rq.count[WRITE]
- - q->in_flight;
+ list_add(&rq->queuelist, &q->queue_head);
+ break;
- if (nrq >= q->unplug_thresh)
- __generic_unplug_device(q);
- }
- } else
+ case ELEVATOR_INSERT_BACK:
+ rq->flags |= REQ_SOFTBARRIER;
+
+ while (q->elevator->ops->elevator_dispatch_fn(q, 1))
+ ;
+ list_add_tail(&rq->queuelist, &q->queue_head);
+ /*
+ * We kick the queue here for the following reasons.
+ * - The elevator might have returned NULL previously
+ * to delay requests and returned them now. As the
+ * queue wasn't empty before this request, ll_rw_blk
+ * won't run the queue on return, resulting in hang.
+ * - Usually, back inserted requests won't be merged
+ * with anything. There's no point in delaying queue
+ * processing.
+ */
+ blk_remove_plug(q);
+ q->request_fn(q);
+ break;
+
+ case ELEVATOR_INSERT_SORT:
+ BUG_ON(!blk_fs_request(rq));
+ rq->flags |= REQ_SORTED;
+ if (q->last_merge == NULL && rq_mergeable(rq))
+ q->last_merge = rq;
/*
- * if drain is set, store the request "locally". when the drain
- * is finished, the requests will be handed ordered to the io
- * scheduler
+ * Some ioscheds (cfq) run q->request_fn directly, so
+ * rq cannot be accessed after calling
+ * elevator_add_req_fn.
*/
- list_add_tail(&rq->queuelist, &q->drain_list);
+ q->elevator->ops->elevator_add_req_fn(q, rq);
+ break;
+
+ default:
+ printk(KERN_ERR "%s: bad insertion point %d\n",
+ __FUNCTION__, where);
+ BUG();
+ }
+
+ if (blk_queue_plugged(q)) {
+ int nrq = q->rq.count[READ] + q->rq.count[WRITE]
+ - q->in_flight;
+
+ if (nrq >= q->unplug_thresh)
+ __generic_unplug_device(q);
+ }
}
void elv_add_request(request_queue_t *q, struct request *rq, int where,
@@ -348,13 +406,19 @@ void elv_add_request(request_queue_t *q, struct request *rq, int where,
static inline struct request *__elv_next_request(request_queue_t *q)
{
- struct request *rq = q->elevator->ops->elevator_next_req_fn(q);
+ struct request *rq;
+
+ if (unlikely(list_empty(&q->queue_head) &&
+ !q->elevator->ops->elevator_dispatch_fn(q, 0)))
+ return NULL;
+
+ rq = list_entry_rq(q->queue_head.next);
/*
* if this is a barrier write and the device has to issue a
* flush sequence to support it, check how far we are
*/
- if (rq && blk_fs_request(rq) && blk_barrier_rq(rq)) {
+ if (blk_fs_request(rq) && blk_barrier_rq(rq)) {
BUG_ON(q->ordered == QUEUE_ORDERED_NONE);
if (q->ordered == QUEUE_ORDERED_FLUSH &&
@@ -371,15 +435,30 @@ struct request *elv_next_request(request_queue_t *q)
int ret;
while ((rq = __elv_next_request(q)) != NULL) {
- /*
- * 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->flags |= REQ_STARTED;
+ if (!(rq->flags & REQ_STARTED)) {
+ elevator_t *e = q->elevator;
- if (rq == q->last_merge)
- q->last_merge = NULL;
+ /*
+ * This is the first time the device driver
+ * sees this request (possibly after
+ * requeueing). Notify IO scheduler.
+ */
+ if (blk_sorted_rq(rq) &&
+ e->ops->elevator_activate_req_fn)
+ e->ops->elevator_activate_req_fn(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->flags |= REQ_STARTED;
+ }
+
+ if (!q->boundary_rq || q->boundary_rq == rq) {
+ q->end_sector = rq_end_sector(rq);
+ q->boundary_rq = NULL;
+ }
if ((rq->flags & REQ_DONTPREP) || !q->prep_rq_fn)
break;
@@ -391,9 +470,9 @@ struct request *elv_next_request(request_queue_t *q)
/*
* the request may have been (partially) prepped.
* we need to keep this request in the front to
- * avoid resource deadlock. turn on softbarrier.
+ * avoid resource deadlock. REQ_STARTED will
+ * prevent other fs requests from passing this one.
*/
- rq->flags |= REQ_SOFTBARRIER;
rq = NULL;
break;
} else if (ret == BLKPREP_KILL) {
@@ -416,42 +495,32 @@ struct request *elv_next_request(request_queue_t *q)
return rq;
}
-void elv_remove_request(request_queue_t *q, struct request *rq)
+void elv_dequeue_request(request_queue_t *q, struct request *rq)
{
- elevator_t *e = q->elevator;
+ BUG_ON(list_empty(&rq->queuelist));
+
+ 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. note that we only account requests that the
- * driver has seen (REQ_STARTED set), to avoid false accounting
- * for request-request merges
+ * the driver side.
*/
if (blk_account_rq(rq))
q->in_flight++;
-
- /*
- * the main clearing point for q->last_merge is on retrieval of
- * request by driver (it calls elv_next_request()), but it _can_
- * also happen here if a request is added to the queue but later
- * deleted without ever being given to driver (merged with another
- * request).
- */
- if (rq == q->last_merge)
- q->last_merge = NULL;
-
- if (e->ops->elevator_remove_req_fn)
- e->ops->elevator_remove_req_fn(q, rq);
}
int elv_queue_empty(request_queue_t *q)
{
elevator_t *e = q->elevator;
+ if (!list_empty(&q->queue_head))
+ return 0;
+
if (e->ops->elevator_queue_empty_fn)
return e->ops->elevator_queue_empty_fn(q);
- return list_empty(&q->queue_head);
+ return 1;
}
struct request *elv_latter_request(request_queue_t *q, struct request *rq)
@@ -487,7 +556,7 @@ struct request *elv_former_request(request_queue_t *q, struct request *rq)
}
int elv_set_request(request_queue_t *q, struct request *rq, struct bio *bio,
- int gfp_mask)
+ gfp_t gfp_mask)
{
elevator_t *e = q->elevator;
@@ -523,11 +592,11 @@ void elv_completed_request(request_queue_t *q, struct request *rq)
/*
* request is released from the driver, io must be done
*/
- if (blk_account_rq(rq))
+ if (blk_account_rq(rq)) {
q->in_flight--;
-
- if (e->ops->elevator_completed_req_fn)
- e->ops->elevator_completed_req_fn(q, rq);
+ if (blk_sorted_rq(rq) && e->ops->elevator_completed_req_fn)
+ e->ops->elevator_completed_req_fn(q, rq);
+ }
}
int elv_register_queue(struct request_queue *q)
@@ -555,10 +624,9 @@ void elv_unregister_queue(struct request_queue *q)
int elv_register(struct elevator_type *e)
{
+ spin_lock_irq(&elv_list_lock);
if (elevator_find(e->elevator_name))
BUG();
-
- spin_lock_irq(&elv_list_lock);
list_add_tail(&e->list, &elv_list);
spin_unlock_irq(&elv_list_lock);
@@ -572,6 +640,27 @@ EXPORT_SYMBOL_GPL(elv_register);
void elv_unregister(struct elevator_type *e)
{
+ struct task_struct *g, *p;
+
+ /*
+ * Iterate every thread in the process to remove the io contexts.
+ */
+ read_lock(&tasklist_lock);
+ do_each_thread(g, p) {
+ struct io_context *ioc = p->io_context;
+ if (ioc && ioc->cic) {
+ ioc->cic->exit(ioc->cic);
+ ioc->cic->dtor(ioc->cic);
+ ioc->cic = NULL;
+ }
+ if (ioc && ioc->aic) {
+ ioc->aic->exit(ioc->aic);
+ ioc->aic->dtor(ioc->aic);
+ ioc->aic = NULL;
+ }
+ } while_each_thread(g, p);
+ read_unlock(&tasklist_lock);
+
spin_lock_irq(&elv_list_lock);
list_del_init(&e->list);
spin_unlock_irq(&elv_list_lock);
@@ -582,25 +671,36 @@ EXPORT_SYMBOL_GPL(elv_unregister);
* switch to new_e io scheduler. be careful not to introduce deadlocks -
* we don't free the old io scheduler, before we have allocated what we
* need for the new one. this way we have a chance of going back to the old
- * one, if the new one fails init for some reason. we also do an intermediate
- * switch to noop to ensure safety with stack-allocated requests, since they
- * don't originate from the block layer allocator. noop is safe here, because
- * it never needs to touch the elevator itself for completion events. DRAIN
- * flags will make sure we don't touch it for additions either.
+ * one, if the new one fails init for some reason.
*/
static void elevator_switch(request_queue_t *q, struct elevator_type *new_e)
{
- elevator_t *e = kmalloc(sizeof(elevator_t), GFP_KERNEL);
- struct elevator_type *noop_elevator = NULL;
- elevator_t *old_elevator;
+ elevator_t *old_elevator, *e;
+ /*
+ * Allocate new elevator
+ */
+ e = kmalloc(sizeof(elevator_t), GFP_KERNEL);
if (!e)
goto error;
/*
- * first step, drain requests from the block freelist
+ * Turn on BYPASS and drain all requests w/ elevator private data
*/
- blk_wait_queue_drained(q, 0);
+ spin_lock_irq(q->queue_lock);
+
+ set_bit(QUEUE_FLAG_ELVSWITCH, &q->queue_flags);
+
+ while (q->elevator->ops->elevator_dispatch_fn(q, 1))
+ ;
+
+ while (q->rq.elvpriv) {
+ spin_unlock_irq(q->queue_lock);
+ msleep(10);
+ spin_lock_irq(q->queue_lock);
+ }
+
+ spin_unlock_irq(q->queue_lock);
/*
* unregister old elevator data
@@ -609,18 +709,6 @@ static void elevator_switch(request_queue_t *q, struct elevator_type *new_e)
old_elevator = q->elevator;
/*
- * next step, switch to noop since it uses no private rq structures
- * and doesn't allocate any memory for anything. then wait for any
- * non-fs requests in-flight
- */
- noop_elevator = elevator_get("noop");
- spin_lock_irq(q->queue_lock);
- elevator_attach(q, noop_elevator, e);
- spin_unlock_irq(q->queue_lock);
-
- blk_wait_queue_drained(q, 1);
-
- /*
* attach and start new elevator
*/
if (elevator_attach(q, new_e, e))
@@ -630,11 +718,10 @@ static void elevator_switch(request_queue_t *q, struct elevator_type *new_e)
goto fail_register;
/*
- * finally exit old elevator and start queue again
+ * finally exit old elevator and turn off BYPASS.
*/
elevator_exit(old_elevator);
- blk_finish_queue_drain(q);
- elevator_put(noop_elevator);
+ clear_bit(QUEUE_FLAG_ELVSWITCH, &q->queue_flags);
return;
fail_register:
@@ -643,13 +730,13 @@ fail_register:
* one again (along with re-adding the sysfs dir)
*/
elevator_exit(e);
+ e = NULL;
fail:
q->elevator = old_elevator;
elv_register_queue(q);
- blk_finish_queue_drain(q);
+ clear_bit(QUEUE_FLAG_ELVSWITCH, &q->queue_flags);
+ kfree(e);
error:
- if (noop_elevator)
- elevator_put(noop_elevator);
elevator_put(new_e);
printk(KERN_ERR "elevator: switch to %s failed\n",new_e->elevator_name);
}
@@ -671,8 +758,10 @@ ssize_t elv_iosched_store(request_queue_t *q, const char *name, size_t count)
return -EINVAL;
}
- if (!strcmp(elevator_name, q->elevator->elevator_type->elevator_name))
+ if (!strcmp(elevator_name, q->elevator->elevator_type->elevator_name)) {
+ elevator_put(e);
return count;
+ }
elevator_switch(q, e);
return count;
@@ -701,11 +790,12 @@ ssize_t elv_iosched_show(request_queue_t *q, char *name)
return len;
}
+EXPORT_SYMBOL(elv_dispatch_sort);
EXPORT_SYMBOL(elv_add_request);
EXPORT_SYMBOL(__elv_add_request);
EXPORT_SYMBOL(elv_requeue_request);
EXPORT_SYMBOL(elv_next_request);
-EXPORT_SYMBOL(elv_remove_request);
+EXPORT_SYMBOL(elv_dequeue_request);
EXPORT_SYMBOL(elv_queue_empty);
EXPORT_SYMBOL(elv_completed_request);
EXPORT_SYMBOL(elevator_exit);
diff --git a/drivers/block/genhd.c b/block/genhd.c
index d42840cc0d1d..54aec4a1ae13 100644
--- a/drivers/block/genhd.c
+++ b/block/genhd.c
@@ -337,10 +337,30 @@ static ssize_t disk_attr_show(struct kobject *kobj, struct attribute *attr,
return ret;
}
+static ssize_t disk_attr_store(struct kobject * kobj, struct attribute * attr,
+ const char *page, size_t count)
+{
+ struct gendisk *disk = to_disk(kobj);
+ struct disk_attribute *disk_attr =
+ container_of(attr,struct disk_attribute,attr);
+ ssize_t ret = 0;
+
+ if (disk_attr->store)
+ ret = disk_attr->store(disk, page, count);
+ return ret;
+}
+
static struct sysfs_ops disk_sysfs_ops = {
.show = &disk_attr_show,
+ .store = &disk_attr_store,
};
+static ssize_t disk_uevent_store(struct gendisk * disk,
+ const char *buf, size_t count)
+{
+ kobject_hotplug(&disk->kobj, KOBJ_ADD);
+ return count;
+}
static ssize_t disk_dev_read(struct gendisk * disk, char *page)
{
dev_t base = MKDEV(disk->major, disk->first_minor);
@@ -371,17 +391,20 @@ static ssize_t disk_stats_read(struct gendisk * disk, char *page)
"%8u %8u %8llu %8u "
"%8u %8u %8u"
"\n",
- disk_stat_read(disk, reads), disk_stat_read(disk, read_merges),
- (unsigned long long)disk_stat_read(disk, read_sectors),
- jiffies_to_msecs(disk_stat_read(disk, read_ticks)),
- disk_stat_read(disk, writes),
- disk_stat_read(disk, write_merges),
- (unsigned long long)disk_stat_read(disk, write_sectors),
- jiffies_to_msecs(disk_stat_read(disk, write_ticks)),
+ disk_stat_read(disk, ios[0]), disk_stat_read(disk, merges[0]),
+ (unsigned long long)disk_stat_read(disk, sectors[0]),
+ jiffies_to_msecs(disk_stat_read(disk, ticks[0])),
+ disk_stat_read(disk, ios[1]), disk_stat_read(disk, merges[1]),
+ (unsigned long long)disk_stat_read(disk, sectors[1]),
+ jiffies_to_msecs(disk_stat_read(disk, ticks[1])),
disk->in_flight,
jiffies_to_msecs(disk_stat_read(disk, io_ticks)),
jiffies_to_msecs(disk_stat_read(disk, time_in_queue)));
}
+static struct disk_attribute disk_attr_uevent = {
+ .attr = {.name = "uevent", .mode = S_IWUSR },
+ .store = disk_uevent_store
+};
static struct disk_attribute disk_attr_dev = {
.attr = {.name = "dev", .mode = S_IRUGO },
.show = disk_dev_read
@@ -404,6 +427,7 @@ static struct disk_attribute disk_attr_stat = {
};
static struct attribute * default_attrs[] = {
+ &disk_attr_uevent.attr,
&disk_attr_dev.attr,
&disk_attr_range.attr,
&disk_attr_removable.attr,
@@ -558,12 +582,12 @@ static int diskstats_show(struct seq_file *s, void *v)
preempt_enable();
seq_printf(s, "%4d %4d %s %u %u %llu %u %u %u %llu %u %u %u %u\n",
gp->major, n + gp->first_minor, disk_name(gp, n, buf),
- disk_stat_read(gp, reads), disk_stat_read(gp, read_merges),
- (unsigned long long)disk_stat_read(gp, read_sectors),
- jiffies_to_msecs(disk_stat_read(gp, read_ticks)),
- disk_stat_read(gp, writes), disk_stat_read(gp, write_merges),
- (unsigned long long)disk_stat_read(gp, write_sectors),
- jiffies_to_msecs(disk_stat_read(gp, write_ticks)),
+ disk_stat_read(gp, ios[0]), disk_stat_read(gp, merges[0]),
+ (unsigned long long)disk_stat_read(gp, sectors[0]),
+ jiffies_to_msecs(disk_stat_read(gp, ticks[0])),
+ disk_stat_read(gp, ios[1]), disk_stat_read(gp, merges[1]),
+ (unsigned long long)disk_stat_read(gp, sectors[1]),
+ jiffies_to_msecs(disk_stat_read(gp, ticks[1])),
gp->in_flight,
jiffies_to_msecs(disk_stat_read(gp, io_ticks)),
jiffies_to_msecs(disk_stat_read(gp, time_in_queue)));
@@ -576,8 +600,8 @@ static int diskstats_show(struct seq_file *s, void *v)
seq_printf(s, "%4d %4d %s %u %u %u %u\n",
gp->major, n + gp->first_minor + 1,
disk_name(gp, n + 1, buf),
- hd->reads, hd->read_sectors,
- hd->writes, hd->write_sectors);
+ hd->ios[0], hd->sectors[0],
+ hd->ios[1], hd->sectors[1]);
}
return 0;
diff --git a/drivers/block/ioctl.c b/block/ioctl.c
index 6e278474f9a8..6e278474f9a8 100644
--- a/drivers/block/ioctl.c
+++ b/block/ioctl.c
diff --git a/drivers/block/ll_rw_blk.c b/block/ll_rw_blk.c
index baedac522945..5f52e30b43f8 100644
--- a/drivers/block/ll_rw_blk.c
+++ b/block/ll_rw_blk.c
@@ -263,8 +263,6 @@ void blk_queue_make_request(request_queue_t * q, make_request_fn * mfn)
blk_queue_bounce_limit(q, BLK_BOUNCE_HIGH);
blk_queue_activity_fn(q, NULL, NULL);
-
- INIT_LIST_HEAD(&q->drain_list);
}
EXPORT_SYMBOL(blk_queue_make_request);
@@ -353,6 +351,8 @@ static void blk_pre_flush_end_io(struct request *flush_rq)
struct request *rq = flush_rq->end_io_data;
request_queue_t *q = rq->q;
+ elv_completed_request(q, flush_rq);
+
rq->flags |= REQ_BAR_PREFLUSH;
if (!flush_rq->errors)
@@ -369,6 +369,8 @@ static void blk_post_flush_end_io(struct request *flush_rq)
struct request *rq = flush_rq->end_io_data;
request_queue_t *q = rq->q;
+ elv_completed_request(q, flush_rq);
+
rq->flags |= REQ_BAR_POSTFLUSH;
q->end_flush_fn(q, flush_rq);
@@ -408,8 +410,6 @@ struct request *blk_start_pre_flush(request_queue_t *q, struct request *rq)
if (!list_empty(&rq->queuelist))
blkdev_dequeue_request(rq);
- elv_deactivate_request(q, rq);
-
flush_rq->end_io_data = rq;
flush_rq->end_io = blk_pre_flush_end_io;
@@ -706,7 +706,6 @@ EXPORT_SYMBOL(blk_queue_dma_alignment);
/**
* blk_queue_find_tag - find a request by its tag and queue
- *
* @q: The request queue for the device
* @tag: The tag of the request
*
@@ -1040,6 +1039,7 @@ EXPORT_SYMBOL(blk_queue_invalidate_tags);
static char *rq_flags[] = {
"REQ_RW",
"REQ_FAILFAST",
+ "REQ_SORTED",
"REQ_SOFTBARRIER",
"REQ_HARDBARRIER",
"REQ_CMD",
@@ -1047,6 +1047,7 @@ static char *rq_flags[] = {
"REQ_STARTED",
"REQ_DONTPREP",
"REQ_QUEUED",
+ "REQ_ELVPRIV",
"REQ_PC",
"REQ_BLOCK_PC",
"REQ_SENSE",
@@ -1637,9 +1638,9 @@ static int blk_init_free_list(request_queue_t *q)
rl->count[READ] = rl->count[WRITE] = 0;
rl->starved[READ] = rl->starved[WRITE] = 0;
+ rl->elvpriv = 0;
init_waitqueue_head(&rl->wait[READ]);
init_waitqueue_head(&rl->wait[WRITE]);
- init_waitqueue_head(&rl->drain);
rl->rq_pool = mempool_create_node(BLKDEV_MIN_RQ, mempool_alloc_slab,
mempool_free_slab, request_cachep, q->node);
@@ -1652,13 +1653,13 @@ static int blk_init_free_list(request_queue_t *q)
static int __make_request(request_queue_t *, struct bio *);
-request_queue_t *blk_alloc_queue(int gfp_mask)
+request_queue_t *blk_alloc_queue(gfp_t gfp_mask)
{
return blk_alloc_queue_node(gfp_mask, -1);
}
EXPORT_SYMBOL(blk_alloc_queue);
-request_queue_t *blk_alloc_queue_node(int gfp_mask, int node_id)
+request_queue_t *blk_alloc_queue_node(gfp_t gfp_mask, int node_id)
{
request_queue_t *q;
@@ -1782,12 +1783,14 @@ EXPORT_SYMBOL(blk_get_queue);
static inline void blk_free_request(request_queue_t *q, struct request *rq)
{
- elv_put_request(q, rq);
+ if (rq->flags & REQ_ELVPRIV)
+ elv_put_request(q, rq);
mempool_free(rq, q->rq.rq_pool);
}
static inline struct request *
-blk_alloc_request(request_queue_t *q, int rw, struct bio *bio, int gfp_mask)
+blk_alloc_request(request_queue_t *q, int rw, struct bio *bio,
+ int priv, gfp_t gfp_mask)
{
struct request *rq = mempool_alloc(q->rq.rq_pool, gfp_mask);
@@ -1800,11 +1803,15 @@ blk_alloc_request(request_queue_t *q, int rw, struct bio *bio, int gfp_mask)
*/
rq->flags = rw;
- if (!elv_set_request(q, rq, bio, gfp_mask))
- return rq;
+ if (priv) {
+ if (unlikely(elv_set_request(q, rq, bio, gfp_mask))) {
+ mempool_free(rq, q->rq.rq_pool);
+ return NULL;
+ }
+ rq->flags |= REQ_ELVPRIV;
+ }
- mempool_free(rq, q->rq.rq_pool);
- return NULL;
+ return rq;
}
/*
@@ -1860,22 +1867,18 @@ static void __freed_request(request_queue_t *q, int rw)
* A request has just been released. Account for it, update the full and
* congestion status, wake up any waiters. Called under q->queue_lock.
*/
-static void freed_request(request_queue_t *q, int rw)
+static void freed_request(request_queue_t *q, int rw, int priv)
{
struct request_list *rl = &q->rq;
rl->count[rw]--;
+ if (priv)
+ rl->elvpriv--;
__freed_request(q, rw);
if (unlikely(rl->starved[rw ^ 1]))
__freed_request(q, rw ^ 1);
-
- if (!rl->count[READ] && !rl->count[WRITE]) {
- smp_mb();
- if (unlikely(waitqueue_active(&rl->drain)))
- wake_up(&rl->drain);
- }
}
#define blkdev_free_rq(list) list_entry((list)->next, struct request, queuelist)
@@ -1885,14 +1888,12 @@ static void freed_request(request_queue_t *q, int rw)
* Returns !NULL on success, with queue_lock *not held*.
*/
static struct request *get_request(request_queue_t *q, int rw, struct bio *bio,
- int gfp_mask)
+ gfp_t gfp_mask)
{
struct request *rq = NULL;
struct request_list *rl = &q->rq;
struct io_context *ioc = current_io_context(GFP_ATOMIC);
-
- if (unlikely(test_bit(QUEUE_FLAG_DRAIN, &q->queue_flags)))
- goto out;
+ int priv;
if (rl->count[rw]+1 >= q->nr_requests) {
/*
@@ -1937,9 +1938,14 @@ get_rq:
rl->starved[rw] = 0;
if (rl->count[rw] >= queue_congestion_on_threshold(q))
set_queue_congested(q, rw);
+
+ priv = !test_bit(QUEUE_FLAG_ELVSWITCH, &q->queue_flags);
+ if (priv)
+ rl->elvpriv++;
+
spin_unlock_irq(q->queue_lock);
- rq = blk_alloc_request(q, rw, bio, gfp_mask);
+ rq = blk_alloc_request(q, rw, bio, priv, gfp_mask);
if (!rq) {
/*
* Allocation failed presumably due to memory. Undo anything
@@ -1949,7 +1955,7 @@ get_rq:
* wait queue, but this is pretty rare.
*/
spin_lock_irq(q->queue_lock);
- freed_request(q, rw);
+ freed_request(q, rw, priv);
/*
* in the very unlikely event that allocation failed and no
@@ -2019,7 +2025,7 @@ static struct request *get_request_wait(request_queue_t *q, int rw,
return rq;
}
-struct request *blk_get_request(request_queue_t *q, int rw, int gfp_mask)
+struct request *blk_get_request(request_queue_t *q, int rw, gfp_t gfp_mask)
{
struct request *rq;
@@ -2251,7 +2257,7 @@ EXPORT_SYMBOL(blk_rq_unmap_user);
* @gfp_mask: memory allocation flags
*/
int blk_rq_map_kern(request_queue_t *q, struct request *rq, void *kbuf,
- unsigned int len, unsigned int gfp_mask)
+ unsigned int len, gfp_t gfp_mask)
{
struct bio *bio;
@@ -2380,16 +2386,9 @@ static void drive_stat_acct(struct request *rq, int nr_sectors, int new_io)
if (!blk_fs_request(rq) || !rq->rq_disk)
return;
- if (rw == READ) {
- __disk_stat_add(rq->rq_disk, read_sectors, nr_sectors);
- if (!new_io)
- __disk_stat_inc(rq->rq_disk, read_merges);
- } else if (rw == WRITE) {
- __disk_stat_add(rq->rq_disk, write_sectors, nr_sectors);
- if (!new_io)
- __disk_stat_inc(rq->rq_disk, write_merges);
- }
- if (new_io) {
+ if (!new_io) {
+ __disk_stat_inc(rq->rq_disk, merges[rw]);
+ } else {
disk_round_stats(rq->rq_disk);
rq->rq_disk->in_flight++;
}
@@ -2433,13 +2432,15 @@ void disk_round_stats(struct gendisk *disk)
{
unsigned long now = jiffies;
- __disk_stat_add(disk, time_in_queue,
- disk->in_flight * (now - disk->stamp));
- disk->stamp = now;
+ if (now == disk->stamp)
+ return;
- if (disk->in_flight)
- __disk_stat_add(disk, io_ticks, (now - disk->stamp_idle));
- disk->stamp_idle = now;
+ if (disk->in_flight) {
+ __disk_stat_add(disk, time_in_queue,
+ disk->in_flight * (now - disk->stamp));
+ __disk_stat_add(disk, io_ticks, (now - disk->stamp));
+ }
+ disk->stamp = now;
}
/*
@@ -2454,6 +2455,8 @@ static void __blk_put_request(request_queue_t *q, struct request *req)
if (unlikely(--req->ref_count))
return;
+ elv_completed_request(q, req);
+
req->rq_status = RQ_INACTIVE;
req->rl = NULL;
@@ -2463,26 +2466,25 @@ static void __blk_put_request(request_queue_t *q, struct request *req)
*/
if (rl) {
int rw = rq_data_dir(req);
-
- elv_completed_request(q, req);
+ int priv = req->flags & REQ_ELVPRIV;
BUG_ON(!list_empty(&req->queuelist));
blk_free_request(q, req);
- freed_request(q, rw);
+ freed_request(q, rw, priv);
}
}
void blk_put_request(struct request *req)
{
+ unsigned long flags;
+ request_queue_t *q = req->q;
+
/*
- * if req->rl isn't set, this request didnt originate from the
- * block layer, so it's safe to just disregard it
+ * Gee, IDE calls in w/ NULL q. Fix IDE and remove the
+ * following if (q) test.
*/
- if (req->rl) {
- unsigned long flags;
- request_queue_t *q = req->q;
-
+ if (q) {
spin_lock_irqsave(q->queue_lock, flags);
__blk_put_request(q, req);
spin_unlock_irqrestore(q->queue_lock, flags);
@@ -2781,113 +2783,16 @@ static inline void blk_partition_remap(struct bio *bio)
if (bdev != bdev->bd_contains) {
struct hd_struct *p = bdev->bd_part;
+ const int rw = bio_data_dir(bio);
+
+ p->sectors[rw] += bio_sectors(bio);
+ p->ios[rw]++;
- switch (bio_data_dir(bio)) {
- case READ:
- p->read_sectors += bio_sectors(bio);
- p->reads++;
- break;
- case WRITE:
- p->write_sectors += bio_sectors(bio);
- p->writes++;
- break;
- }
bio->bi_sector += p->start_sect;
bio->bi_bdev = bdev->bd_contains;
}
}
-void blk_finish_queue_drain(request_queue_t *q)
-{
- struct request_list *rl = &q->rq;
- struct request *rq;
- int requeued = 0;
-
- spin_lock_irq(q->queue_lock);
- clear_bit(QUEUE_FLAG_DRAIN, &q->queue_flags);
-
- while (!list_empty(&q->drain_list)) {
- rq = list_entry_rq(q->drain_list.next);
-
- list_del_init(&rq->queuelist);
- elv_requeue_request(q, rq);
- requeued++;
- }
-
- if (requeued)
- q->request_fn(q);
-
- spin_unlock_irq(q->queue_lock);
-
- wake_up(&rl->wait[0]);
- wake_up(&rl->wait[1]);
- wake_up(&rl->drain);
-}
-
-static int wait_drain(request_queue_t *q, struct request_list *rl, int dispatch)
-{
- int wait = rl->count[READ] + rl->count[WRITE];
-
- if (dispatch)
- wait += !list_empty(&q->queue_head);
-
- return wait;
-}
-
-/*
- * We rely on the fact that only requests allocated through blk_alloc_request()
- * have io scheduler private data structures associated with them. Any other
- * type of request (allocated on stack or through kmalloc()) should not go
- * to the io scheduler core, but be attached to the queue head instead.
- */
-void blk_wait_queue_drained(request_queue_t *q, int wait_dispatch)
-{
- struct request_list *rl = &q->rq;
- DEFINE_WAIT(wait);
-
- spin_lock_irq(q->queue_lock);
- set_bit(QUEUE_FLAG_DRAIN, &q->queue_flags);
-
- while (wait_drain(q, rl, wait_dispatch)) {
- prepare_to_wait(&rl->drain, &wait, TASK_UNINTERRUPTIBLE);
-
- if (wait_drain(q, rl, wait_dispatch)) {
- __generic_unplug_device(q);
- spin_unlock_irq(q->queue_lock);
- io_schedule();
- spin_lock_irq(q->queue_lock);
- }
-
- finish_wait(&rl->drain, &wait);
- }
-
- spin_unlock_irq(q->queue_lock);
-}
-
-/*
- * block waiting for the io scheduler being started again.
- */
-static inline void block_wait_queue_running(request_queue_t *q)
-{
- DEFINE_WAIT(wait);
-
- while (unlikely(test_bit(QUEUE_FLAG_DRAIN, &q->queue_flags))) {
- struct request_list *rl = &q->rq;
-
- prepare_to_wait_exclusive(&rl->drain, &wait,
- TASK_UNINTERRUPTIBLE);
-
- /*
- * re-check the condition. avoids using prepare_to_wait()
- * in the fast path (queue is running)
- */
- if (test_bit(QUEUE_FLAG_DRAIN, &q->queue_flags))
- io_schedule();
-
- finish_wait(&rl->drain, &wait);
- }
-}
-
static void handle_bad_sector(struct bio *bio)
{
char b[BDEVNAME_SIZE];
@@ -2983,8 +2888,6 @@ end_io:
if (unlikely(test_bit(QUEUE_FLAG_DEAD, &q->queue_flags)))
goto end_io;
- block_wait_queue_running(q);
-
/*
* If this device has partitions, remap block n
* of partition p to block n+start(p) of the disk.
@@ -3131,6 +3034,12 @@ static int __end_that_request_first(struct request *req, int uptodate,
(unsigned long long)req->sector);
}
+ if (blk_fs_request(req) && req->rq_disk) {
+ const int rw = rq_data_dir(req);
+
+ __disk_stat_add(req->rq_disk, sectors[rw], nr_bytes >> 9);
+ }
+
total_bytes = bio_nbytes = 0;
while ((bio = req->bio) != NULL) {
int nbytes;
@@ -3259,16 +3168,10 @@ void end_that_request_last(struct request *req)
if (disk && blk_fs_request(req)) {
unsigned long duration = jiffies - req->start_time;
- switch (rq_data_dir(req)) {
- case WRITE:
- __disk_stat_inc(disk, writes);
- __disk_stat_add(disk, write_ticks, duration);
- break;
- case READ:
- __disk_stat_inc(disk, reads);
- __disk_stat_add(disk, read_ticks, duration);
- break;
- }
+ const int rw = rq_data_dir(req);
+
+ __disk_stat_inc(disk, ios[rw]);
+ __disk_stat_add(disk, ticks[rw], duration);
disk_round_stats(disk);
disk->in_flight--;
}
@@ -3393,7 +3296,7 @@ void exit_io_context(void)
* but since the current task itself holds a reference, the context can be
* used in general code, so long as it stays within `current` context.
*/
-struct io_context *current_io_context(int gfp_flags)
+struct io_context *current_io_context(gfp_t gfp_flags)
{
struct task_struct *tsk = current;
struct io_context *ret;
@@ -3424,7 +3327,7 @@ EXPORT_SYMBOL(current_io_context);
*
* This is always called in the context of the task which submitted the I/O.
*/
-struct io_context *get_io_context(int gfp_flags)
+struct io_context *get_io_context(gfp_t gfp_flags)
{
struct io_context *ret;
ret = current_io_context(gfp_flags);
diff --git a/block/noop-iosched.c b/block/noop-iosched.c
new file mode 100644
index 000000000000..e54f006e7e60
--- /dev/null
+++ b/block/noop-iosched.c
@@ -0,0 +1,46 @@
+/*
+ * elevator noop
+ */
+#include <linux/blkdev.h>
+#include <linux/elevator.h>
+#include <linux/bio.h>
+#include <linux/module.h>
+#include <linux/init.h>
+
+static void elevator_noop_add_request(request_queue_t *q, struct request *rq)
+{
+ rq->flags |= REQ_NOMERGE;
+ elv_dispatch_add_tail(q, rq);
+}
+
+static int elevator_noop_dispatch(request_queue_t *q, int force)
+{
+ return 0;
+}
+
+static struct elevator_type elevator_noop = {
+ .ops = {
+ .elevator_dispatch_fn = elevator_noop_dispatch,
+ .elevator_add_req_fn = elevator_noop_add_request,
+ },
+ .elevator_name = "noop",
+ .elevator_owner = THIS_MODULE,
+};
+
+static int __init noop_init(void)
+{
+ return elv_register(&elevator_noop);
+}
+
+static void __exit noop_exit(void)
+{
+ elv_unregister(&elevator_noop);
+}
+
+module_init(noop_init);
+module_exit(noop_exit);
+
+
+MODULE_AUTHOR("Jens Axboe");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("No-op IO scheduler");
diff --git a/drivers/block/scsi_ioctl.c b/block/scsi_ioctl.c
index 382dea7b224c..382dea7b224c 100644
--- a/drivers/block/scsi_ioctl.c
+++ b/block/scsi_ioctl.c
diff --git a/crypto/api.c b/crypto/api.c
index 959c4e5f264f..40ae42e9b6a6 100644
--- a/crypto/api.c
+++ b/crypto/api.c
@@ -215,7 +215,10 @@ int crypto_register_alg(struct crypto_alg *alg)
if (alg->cra_alignmask & (alg->cra_alignmask + 1))
return -EINVAL;
- if (alg->cra_alignmask > PAGE_SIZE)
+ if (alg->cra_alignmask & alg->cra_blocksize)
+ return -EINVAL;
+
+ if (alg->cra_blocksize > PAGE_SIZE)
return -EINVAL;
down_write(&crypto_alg_sem);
diff --git a/crypto/hmac.c b/crypto/hmac.c
index da0456b37109..46120dee5ada 100644
--- a/crypto/hmac.c
+++ b/crypto/hmac.c
@@ -18,18 +18,15 @@
#include <linux/mm.h>
#include <linux/highmem.h>
#include <linux/slab.h>
-#include <asm/scatterlist.h>
+#include <linux/scatterlist.h>
#include "internal.h"
static void hash_key(struct crypto_tfm *tfm, u8 *key, unsigned int keylen)
{
struct scatterlist tmp;
- tmp.page = virt_to_page(key);
- tmp.offset = offset_in_page(key);
- tmp.length = keylen;
+ sg_set_buf(&tmp, key, keylen);
crypto_digest_digest(tfm, &tmp, 1, key);
-
}
int crypto_alloc_hmac_block(struct crypto_tfm *tfm)
@@ -69,9 +66,7 @@ void crypto_hmac_init(struct crypto_tfm *tfm, u8 *key, unsigned int *keylen)
for (i = 0; i < crypto_tfm_alg_blocksize(tfm); i++)
ipad[i] ^= 0x36;
- tmp.page = virt_to_page(ipad);
- tmp.offset = offset_in_page(ipad);
- tmp.length = crypto_tfm_alg_blocksize(tfm);
+ sg_set_buf(&tmp, ipad, crypto_tfm_alg_blocksize(tfm));
crypto_digest_init(tfm);
crypto_digest_update(tfm, &tmp, 1);
@@ -103,16 +98,12 @@ void crypto_hmac_final(struct crypto_tfm *tfm, u8 *key,
for (i = 0; i < crypto_tfm_alg_blocksize(tfm); i++)
opad[i] ^= 0x5c;
- tmp.page = virt_to_page(opad);
- tmp.offset = offset_in_page(opad);
- tmp.length = crypto_tfm_alg_blocksize(tfm);
+ sg_set_buf(&tmp, opad, crypto_tfm_alg_blocksize(tfm));
crypto_digest_init(tfm);
crypto_digest_update(tfm, &tmp, 1);
- tmp.page = virt_to_page(out);
- tmp.offset = offset_in_page(out);
- tmp.length = crypto_tfm_alg_digestsize(tfm);
+ sg_set_buf(&tmp, out, crypto_tfm_alg_digestsize(tfm));
crypto_digest_update(tfm, &tmp, 1);
crypto_digest_final(tfm, out);
diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c
index 68639419c5bd..53f4ee804bdb 100644
--- a/crypto/tcrypt.c
+++ b/crypto/tcrypt.c
@@ -21,7 +21,7 @@
#include <linux/module.h>
#include <linux/mm.h>
#include <linux/slab.h>
-#include <asm/scatterlist.h>
+#include <linux/scatterlist.h>
#include <linux/string.h>
#include <linux/crypto.h>
#include <linux/highmem.h>
@@ -86,7 +86,6 @@ static void hexdump(unsigned char *buf, unsigned int len)
static void test_hash(char *algo, struct hash_testvec *template,
unsigned int tcount)
{
- char *p;
unsigned int i, j, k, temp;
struct scatterlist sg[8];
char result[64];
@@ -116,10 +115,7 @@ static void test_hash(char *algo, struct hash_testvec *template,
printk("test %u:\n", i + 1);
memset(result, 0, 64);
- p = hash_tv[i].plaintext;
- sg[0].page = virt_to_page(p);
- sg[0].offset = offset_in_page(p);
- sg[0].length = hash_tv[i].psize;
+ sg_set_buf(&sg[0], hash_tv[i].plaintext, hash_tv[i].psize);
crypto_digest_init(tfm);
if (tfm->crt_u.digest.dit_setkey) {
@@ -154,10 +150,8 @@ static void test_hash(char *algo, struct hash_testvec *template,
hash_tv[i].plaintext + temp,
hash_tv[i].tap[k]);
temp += hash_tv[i].tap[k];
- p = &xbuf[IDX[k]];
- sg[k].page = virt_to_page(p);
- sg[k].offset = offset_in_page(p);
- sg[k].length = hash_tv[i].tap[k];
+ sg_set_buf(&sg[k], &xbuf[IDX[k]],
+ hash_tv[i].tap[k]);
}
crypto_digest_digest(tfm, sg, hash_tv[i].np, result);
@@ -179,7 +173,6 @@ static void test_hash(char *algo, struct hash_testvec *template,
static void test_hmac(char *algo, struct hmac_testvec *template,
unsigned int tcount)
{
- char *p;
unsigned int i, j, k, temp;
struct scatterlist sg[8];
char result[64];
@@ -210,11 +203,8 @@ static void test_hmac(char *algo, struct hmac_testvec *template,
printk("test %u:\n", i + 1);
memset(result, 0, sizeof (result));
- p = hmac_tv[i].plaintext;
klen = hmac_tv[i].ksize;
- sg[0].page = virt_to_page(p);
- sg[0].offset = offset_in_page(p);
- sg[0].length = hmac_tv[i].psize;
+ sg_set_buf(&sg[0], hmac_tv[i].plaintext, hmac_tv[i].psize);
crypto_hmac(tfm, hmac_tv[i].key, &klen, sg, 1, result);
@@ -243,10 +233,8 @@ static void test_hmac(char *algo, struct hmac_testvec *template,
hmac_tv[i].plaintext + temp,
hmac_tv[i].tap[k]);
temp += hmac_tv[i].tap[k];
- p = &xbuf[IDX[k]];
- sg[k].page = virt_to_page(p);
- sg[k].offset = offset_in_page(p);
- sg[k].length = hmac_tv[i].tap[k];
+ sg_set_buf(&sg[k], &xbuf[IDX[k]],
+ hmac_tv[i].tap[k]);
}
crypto_hmac(tfm, hmac_tv[i].key, &klen, sg,
@@ -270,7 +258,7 @@ static void test_cipher(char *algo, int mode, int enc,
{
unsigned int ret, i, j, k, temp;
unsigned int tsize;
- char *p, *q;
+ char *q;
struct crypto_tfm *tfm;
char *key;
struct cipher_testvec *cipher_tv;
@@ -330,10 +318,8 @@ static void test_cipher(char *algo, int mode, int enc,
goto out;
}
- p = cipher_tv[i].input;
- sg[0].page = virt_to_page(p);
- sg[0].offset = offset_in_page(p);
- sg[0].length = cipher_tv[i].ilen;
+ sg_set_buf(&sg[0], cipher_tv[i].input,
+ cipher_tv[i].ilen);
if (!mode) {
crypto_cipher_set_iv(tfm, cipher_tv[i].iv,
@@ -389,10 +375,8 @@ static void test_cipher(char *algo, int mode, int enc,
cipher_tv[i].input + temp,
cipher_tv[i].tap[k]);
temp += cipher_tv[i].tap[k];
- p = &xbuf[IDX[k]];
- sg[k].page = virt_to_page(p);
- sg[k].offset = offset_in_page(p);
- sg[k].length = cipher_tv[i].tap[k];
+ sg_set_buf(&sg[k], &xbuf[IDX[k]],
+ cipher_tv[i].tap[k]);
}
if (!mode) {
@@ -431,14 +415,12 @@ out:
static int test_cipher_jiffies(struct crypto_tfm *tfm, int enc, char *p,
int blen, int sec)
{
- struct scatterlist sg[8];
+ struct scatterlist sg[1];
unsigned long start, end;
int bcount;
int ret;
- sg[0].page = virt_to_page(p);
- sg[0].offset = offset_in_page(p);
- sg[0].length = blen;
+ sg_set_buf(sg, p, blen);
for (start = jiffies, end = start + sec * HZ, bcount = 0;
time_before(jiffies, end); bcount++) {
@@ -459,14 +441,12 @@ static int test_cipher_jiffies(struct crypto_tfm *tfm, int enc, char *p,
static int test_cipher_cycles(struct crypto_tfm *tfm, int enc, char *p,
int blen)
{
- struct scatterlist sg[8];
+ struct scatterlist sg[1];
unsigned long cycles = 0;
int ret = 0;
int i;
- sg[0].page = virt_to_page(p);
- sg[0].offset = offset_in_page(p);
- sg[0].length = blen;
+ sg_set_buf(sg, p, blen);
local_bh_disable();
local_irq_disable();
@@ -709,9 +689,7 @@ static void test_crc32c(void)
for (i = 0; i < NUMVEC; i++) {
for (j = 0; j < VECSIZE; j++)
test_vec[i][j] = ++b;
- sg[i].page = virt_to_page(test_vec[i]);
- sg[i].offset = offset_in_page(test_vec[i]);
- sg[i].length = VECSIZE;
+ sg_set_buf(&sg[i], test_vec[i], VECSIZE);
}
seed = SEEDTESTVAL;
diff --git a/drivers/Makefile b/drivers/Makefile
index 1a109a6dd953..fac1e1603097 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -5,8 +5,9 @@
# Rewritten to use lists instead of if-statements.
#
-obj-$(CONFIG_PCI) += pci/
+obj-$(CONFIG_PCI) += pci/ usb/
obj-$(CONFIG_PARISC) += parisc/
+obj-$(CONFIG_RAPIDIO) += rapidio/
obj-y += video/
obj-$(CONFIG_ACPI) += acpi/
# PnP must come after ACPI since it will eventually need to check if acpi
@@ -67,3 +68,4 @@ obj-$(CONFIG_INFINIBAND) += infiniband/
obj-$(CONFIG_SGI_IOC4) += sn/
obj-y += firmware/
obj-$(CONFIG_CRYPTO) += crypto/
+obj-$(CONFIG_SUPERH) += sh/
diff --git a/drivers/acorn/char/pcf8583.c b/drivers/acorn/char/pcf8583.c
index 2b850e5860a0..e26f007a1417 100644
--- a/drivers/acorn/char/pcf8583.c
+++ b/drivers/acorn/char/pcf8583.c
@@ -9,6 +9,7 @@
*
* Driver for PCF8583 RTC & RAM chip
*/
+#include <linux/module.h>
#include <linux/i2c.h>
#include <linux/slab.h>
#include <linux/string.h>
@@ -32,7 +33,8 @@ static struct i2c_client_address_data addr_data = {
.forces = forces,
};
-#define DAT(x) ((unsigned int)(x->dev.driver_data))
+#define set_ctrl(x, v) i2c_set_clientdata(x, (void *)(unsigned int)(v))
+#define get_ctrl(x) ((unsigned int)i2c_get_clientdata(x))
static int
pcf8583_attach(struct i2c_adapter *adap, int addr, int kind)
@@ -40,8 +42,17 @@ pcf8583_attach(struct i2c_adapter *adap, int addr, int kind)
struct i2c_client *c;
unsigned char buf[1], ad[1] = { 0 };
struct i2c_msg msgs[2] = {
- { addr, 0, 1, ad },
- { addr, I2C_M_RD, 1, buf }
+ {
+ .addr = addr,
+ .flags = 0,
+ .len = 1,
+ .buf = ad,
+ }, {
+ .addr = addr,
+ .flags = I2C_M_RD,
+ .len = 1,
+ .buf = buf,
+ }
};
c = kmalloc(sizeof(*c), GFP_KERNEL);
@@ -54,7 +65,7 @@ pcf8583_attach(struct i2c_adapter *adap, int addr, int kind)
c->driver = &pcf8583_driver;
if (i2c_transfer(c->adapter, msgs, 2) == 2)
- DAT(c) = buf[0];
+ set_ctrl(c, buf[0]);
return i2c_attach_client(c);
}
@@ -78,8 +89,17 @@ pcf8583_get_datetime(struct i2c_client *client, struct rtc_tm *dt)
{
unsigned char buf[8], addr[1] = { 1 };
struct i2c_msg msgs[2] = {
- { client->addr, 0, 1, addr },
- { client->addr, I2C_M_RD, 6, buf }
+ {
+ .addr = client->addr,
+ .flags = 0,
+ .len = 1,
+ .buf = addr,
+ }, {
+ .addr = client->addr,
+ .flags = I2C_M_RD,
+ .len = 6,
+ .buf = buf,
+ }
};
int ret = -EIO;
@@ -113,7 +133,7 @@ pcf8583_set_datetime(struct i2c_client *client, struct rtc_tm *dt, int datetoo)
int ret, len = 6;
buf[0] = 0;
- buf[1] = DAT(client) | 0x80;
+ buf[1] = get_ctrl(client) | 0x80;
buf[2] = BIN_TO_BCD(dt->cs);
buf[3] = BIN_TO_BCD(dt->secs);
buf[4] = BIN_TO_BCD(dt->mins);
@@ -129,7 +149,7 @@ pcf8583_set_datetime(struct i2c_client *client, struct rtc_tm *dt, int datetoo)
if (ret == len)
ret = 0;
- buf[1] = DAT(client);
+ buf[1] = get_ctrl(client);
i2c_master_send(client, (char *)buf, 2);
return ret;
@@ -138,7 +158,7 @@ pcf8583_set_datetime(struct i2c_client *client, struct rtc_tm *dt, int datetoo)
static int
pcf8583_get_ctrl(struct i2c_client *client, unsigned char *ctrl)
{
- *ctrl = DAT(client);
+ *ctrl = get_ctrl(client);
return 0;
}
@@ -149,7 +169,7 @@ pcf8583_set_ctrl(struct i2c_client *client, unsigned char *ctrl)
buf[0] = 0;
buf[1] = *ctrl;
- DAT(client) = *ctrl;
+ set_ctrl(client, *ctrl);
return i2c_master_send(client, (char *)buf, 2);
}
@@ -159,15 +179,23 @@ pcf8583_read_mem(struct i2c_client *client, struct mem *mem)
{
unsigned char addr[1];
struct i2c_msg msgs[2] = {
- { client->addr, 0, 1, addr },
- { client->addr, I2C_M_RD, 0, mem->data }
+ {
+ .addr = client->addr,
+ .flags = 0,
+ .len = 1,
+ .buf = addr,
+ }, {
+ .addr = client->addr,
+ .flags = I2C_M_RD,
+ .len = mem->nr,
+ .buf = mem->data,
+ }
};
if (mem->loc < 8)
return -EINVAL;
addr[0] = mem->loc;
- msgs[1].len = mem->nr;
return i2c_transfer(client->adapter, msgs, 2) == 2 ? 0 : -EIO;
}
@@ -177,15 +205,23 @@ pcf8583_write_mem(struct i2c_client *client, struct mem *mem)
{
unsigned char addr[1];
struct i2c_msg msgs[2] = {
- { client->addr, 0, 1, addr },
- { client->addr, 0, 0, mem->data }
+ {
+ .addr = client->addr,
+ .flags = 0,
+ .len = 1,
+ .buf = addr,
+ }, {
+ .addr = client->addr,
+ .flags = I2C_M_NOSTART,
+ .len = mem->nr,
+ .buf = mem->data,
+ }
};
if (mem->loc < 8)
return -EINVAL;
addr[0] = mem->loc;
- msgs[1].len = mem->nr;
return i2c_transfer(client->adapter, msgs, 2) == 2 ? 0 : -EIO;
}
@@ -234,4 +270,14 @@ static __init int pcf8583_init(void)
return i2c_add_driver(&pcf8583_driver);
}
-__initcall(pcf8583_init);
+static __exit void pcf8583_exit(void)
+{
+ i2c_del_driver(&pcf8583_driver);
+}
+
+module_init(pcf8583_init);
+module_exit(pcf8583_exit);
+
+MODULE_AUTHOR("Russell King");
+MODULE_DESCRIPTION("PCF8583 I2C RTC driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/acpi/acpi_memhotplug.c b/drivers/acpi/acpi_memhotplug.c
index 01a1bd239263..2143609d2936 100644
--- a/drivers/acpi/acpi_memhotplug.c
+++ b/drivers/acpi/acpi_memhotplug.c
@@ -200,8 +200,7 @@ static int acpi_memory_enable_device(struct acpi_memory_device *mem_device)
* Note: Assume that this function returns zero on success
*/
result = add_memory(mem_device->start_addr,
- (mem_device->end_addr - mem_device->start_addr) + 1,
- mem_device->read_write_attribute);
+ (mem_device->end_addr - mem_device->start_addr) + 1);
if (result) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "\nadd_memory failed\n"));
mem_device->state = MEMORY_INVALID_STATE;
@@ -259,7 +258,7 @@ static int acpi_memory_disable_device(struct acpi_memory_device *mem_device)
* Ask the VM to offline this memory range.
* Note: Assume that this function returns zero on success
*/
- result = remove_memory(start, len, attr);
+ result = remove_memory(start, len);
if (result) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Hot-Remove failed.\n"));
return_VALUE(result);
diff --git a/drivers/acpi/container.c b/drivers/acpi/container.c
index 10dd695a1dd9..27ec12c1fab0 100644
--- a/drivers/acpi/container.c
+++ b/drivers/acpi/container.c
@@ -118,11 +118,9 @@ static int acpi_container_remove(struct acpi_device *device, int type)
{
acpi_status status = AE_OK;
struct acpi_container *pc = NULL;
- pc = (struct acpi_container *)acpi_driver_data(device);
-
- if (pc)
- kfree(pc);
+ pc = (struct acpi_container *)acpi_driver_data(device);
+ kfree(pc);
return status;
}
diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c
index 3937adf4e5e5..aa993715d644 100644
--- a/drivers/acpi/glue.c
+++ b/drivers/acpi/glue.c
@@ -203,6 +203,7 @@ acpi_handle acpi_get_pci_rootbridge_handle(unsigned int seg, unsigned int bus)
acpi_get_devices(PCI_ROOT_HID_STRING, find_pci_rootbridge, &find, NULL);
return find.handle;
}
+EXPORT_SYMBOL_GPL(acpi_get_pci_rootbridge_handle);
/* Get device's handler per its address under its parent */
struct acpi_find_child {
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index d528c750a380..e3cd0b16031a 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -313,8 +313,7 @@ acpi_status acpi_os_remove_interrupt_handler(u32 irq, acpi_osd_handler handler)
void acpi_os_sleep(acpi_integer ms)
{
- current->state = TASK_INTERRUPTIBLE;
- schedule_timeout(((signed long)ms * HZ) / 1000);
+ schedule_timeout_interruptible(msecs_to_jiffies(ms));
}
EXPORT_SYMBOL(acpi_os_sleep);
@@ -838,8 +837,7 @@ acpi_status acpi_os_wait_semaphore(acpi_handle handle, u32 units, u16 timeout)
ret = down_trylock(sem);
for (i = timeout; (i > 0 && ret < 0); i -= quantum_ms) {
- current->state = TASK_INTERRUPTIBLE;
- schedule_timeout(1);
+ schedule_timeout_interruptible(1);
ret = down_trylock(sem);
}
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index 26a3a4016115..573b6a97bb1f 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -37,6 +37,7 @@
#include <linux/acpi.h>
#include <linux/dmi.h>
#include <linux/moduleparam.h>
+#include <linux/sched.h> /* need_resched() */
#include <asm/io.h>
#include <asm/uaccess.h>
@@ -166,6 +167,19 @@ acpi_processor_power_activate(struct acpi_processor *pr,
return;
}
+static void acpi_safe_halt(void)
+{
+ int polling = test_thread_flag(TIF_POLLING_NRFLAG);
+ if (polling) {
+ clear_thread_flag(TIF_POLLING_NRFLAG);
+ smp_mb__after_clear_bit();
+ }
+ if (!need_resched())
+ safe_halt();
+ if (polling)
+ set_thread_flag(TIF_POLLING_NRFLAG);
+}
+
static atomic_t c3_cpu_count;
static void acpi_processor_idle(void)
@@ -176,7 +190,7 @@ static void acpi_processor_idle(void)
int sleep_ticks = 0;
u32 t1, t2 = 0;
- pr = processors[raw_smp_processor_id()];
+ pr = processors[smp_processor_id()];
if (!pr)
return;
@@ -196,8 +210,13 @@ static void acpi_processor_idle(void)
}
cx = pr->power.state;
- if (!cx)
- goto easy_out;
+ if (!cx) {
+ if (pm_idle_save)
+ pm_idle_save();
+ else
+ acpi_safe_halt();
+ return;
+ }
/*
* Check BM Activity
@@ -277,7 +296,8 @@ static void acpi_processor_idle(void)
if (pm_idle_save)
pm_idle_save();
else
- safe_halt();
+ acpi_safe_halt();
+
/*
* TBD: Can't get time duration while in C1, as resumes
* go to an ISR rather than here. Need to instrument
@@ -413,16 +433,6 @@ static void acpi_processor_idle(void)
*/
if (next_state != pr->power.state)
acpi_processor_power_activate(pr, next_state);
-
- return;
-
- easy_out:
- /* do C1 instead of busy loop */
- if (pm_idle_save)
- pm_idle_save();
- else
- safe_halt();
- return;
}
static int acpi_processor_set_power_policy(struct acpi_processor *pr)
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index c6db591479de..23e2c6968a11 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -28,8 +28,7 @@ static int acpi_bus_trim(struct acpi_device *start, int rmdevice);
static void acpi_device_release(struct kobject *kobj)
{
struct acpi_device *dev = container_of(kobj, struct acpi_device, kobj);
- if (dev->pnp.cid_list)
- kfree(dev->pnp.cid_list);
+ kfree(dev->pnp.cid_list);
kfree(dev);
}
@@ -1117,8 +1116,7 @@ acpi_add_single_object(struct acpi_device **child,
if (!result)
*child = device;
else {
- if (device->pnp.cid_list)
- kfree(device->pnp.cid_list);
+ kfree(device->pnp.cid_list);
kfree(device);
}
diff --git a/drivers/acpi/sleep/main.c b/drivers/acpi/sleep/main.c
index aee50b453265..930427fc0c4b 100644
--- a/drivers/acpi/sleep/main.c
+++ b/drivers/acpi/sleep/main.c
@@ -158,7 +158,15 @@ int acpi_suspend(u32 acpi_state)
return -EINVAL;
}
+static int acpi_pm_state_valid(suspend_state_t pm_state)
+{
+ u32 acpi_state = acpi_suspend_states[pm_state];
+
+ return sleep_states[acpi_state];
+}
+
static struct pm_ops acpi_pm_ops = {
+ .valid = acpi_pm_state_valid,
.prepare = acpi_pm_prepare,
.enter = acpi_pm_enter,
.finish = acpi_pm_finish,
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
index e383d6109ae1..f051b151580d 100644
--- a/drivers/acpi/video.c
+++ b/drivers/acpi/video.c
@@ -334,8 +334,7 @@ acpi_video_device_lcd_query_levels(struct acpi_video_device *device,
return_VALUE(0);
err:
- if (buffer.pointer)
- kfree(buffer.pointer);
+ kfree(buffer.pointer);
return_VALUE(status);
}
@@ -1488,8 +1487,7 @@ static int acpi_video_device_enumerate(struct acpi_video_bus *video)
}
active_device_list[count].value.int_val = ACPI_VIDEO_HEAD_END;
- if (video->attached_array)
- kfree(video->attached_array);
+ kfree(video->attached_array);
video->attached_array = active_device_list;
video->attached_count = count;
@@ -1645,8 +1643,7 @@ static int acpi_video_bus_put_devices(struct acpi_video_bus *video)
printk(KERN_WARNING PREFIX
"hhuuhhuu bug in acpi video driver.\n");
- if (data->brightness)
- kfree(data->brightness);
+ kfree(data->brightness);
kfree(data);
}
@@ -1831,8 +1828,7 @@ static int acpi_video_bus_remove(struct acpi_device *device, int type)
acpi_video_bus_put_devices(video);
acpi_video_bus_remove_fs(device);
- if (video->attached_array)
- kfree(video->attached_array);
+ kfree(video->attached_array);
kfree(video);
return_VALUE(0);
diff --git a/drivers/atm/horizon.c b/drivers/atm/horizon.c
index 0cded0468003..821c81e8cd38 100644
--- a/drivers/atm/horizon.c
+++ b/drivers/atm/horizon.c
@@ -1511,8 +1511,8 @@ static inline short setup_idle_tx_channel (hrz_dev * dev, hrz_vcc * vcc) {
// a.k.a. prepare the channel and remember that we have done so.
tx_ch_desc * tx_desc = &memmap->tx_descs[tx_channel];
- u16 rd_ptr;
- u16 wr_ptr;
+ u32 rd_ptr;
+ u32 wr_ptr;
u16 channel = vcc->channel;
unsigned long flags;
diff --git a/drivers/base/Makefile b/drivers/base/Makefile
index 66d9c4643fc1..f12898d53078 100644
--- a/drivers/base/Makefile
+++ b/drivers/base/Makefile
@@ -7,6 +7,7 @@ obj-y := core.o sys.o bus.o dd.o \
obj-y += power/
obj-$(CONFIG_FW_LOADER) += firmware_class.o
obj-$(CONFIG_NUMA) += node.o
+obj-$(CONFIG_MEMORY_HOTPLUG) += memory.o
ifeq ($(CONFIG_DEBUG_DRIVER),y)
EXTRA_CFLAGS += -DDEBUG
diff --git a/drivers/base/attribute_container.c b/drivers/base/attribute_container.c
index 6b2eb6f39b4d..2a7d7ae83e1e 100644
--- a/drivers/base/attribute_container.c
+++ b/drivers/base/attribute_container.c
@@ -19,6 +19,8 @@
#include <linux/list.h>
#include <linux/module.h>
+#include "base.h"
+
/* This is a private structure used to tie the classdev and the
* container .. it should never be visible outside this file */
struct internal_container {
diff --git a/drivers/base/base.h b/drivers/base/base.h
index 783752b68a9a..e3b548d46cff 100644
--- a/drivers/base/base.h
+++ b/drivers/base/base.h
@@ -1,3 +1,15 @@
+
+/* initialisation functions */
+
+extern int devices_init(void);
+extern int buses_init(void);
+extern int classes_init(void);
+extern int firmware_init(void);
+extern int platform_bus_init(void);
+extern int system_bus_init(void);
+extern int cpu_dev_init(void);
+extern int attribute_container_init(void);
+
extern int bus_add_device(struct device * dev);
extern void bus_remove_device(struct device * dev);
diff --git a/drivers/base/class.c b/drivers/base/class.c
index ce23dc8c18c5..db65fd0babe9 100644
--- a/drivers/base/class.c
+++ b/drivers/base/class.c
@@ -17,6 +17,7 @@
#include <linux/string.h>
#include <linux/kdev_t.h>
#include <linux/err.h>
+#include <linux/slab.h>
#include "base.h"
#define to_class_attr(_attr) container_of(_attr, struct class_attribute, attr)
@@ -99,7 +100,8 @@ struct class * class_get(struct class * cls)
void class_put(struct class * cls)
{
- subsys_put(&cls->subsys);
+ if (cls)
+ subsys_put(&cls->subsys);
}
@@ -165,14 +167,25 @@ void class_unregister(struct class * cls)
static void class_create_release(struct class *cls)
{
+ pr_debug("%s called for %s\n", __FUNCTION__, cls->name);
kfree(cls);
}
static void class_device_create_release(struct class_device *class_dev)
{
+ pr_debug("%s called for %s\n", __FUNCTION__, class_dev->class_id);
kfree(class_dev);
}
+/* needed to allow these devices to have parent class devices */
+static int class_device_create_hotplug(struct class_device *class_dev,
+ char **envp, int num_envp,
+ char *buffer, int buffer_size)
+{
+ pr_debug("%s called for %s\n", __FUNCTION__, class_dev->class_id);
+ return 0;
+}
+
/**
* class_create - create a struct class structure
* @owner: pointer to the module that is to "own" this struct class
@@ -301,10 +314,12 @@ static void class_dev_release(struct kobject * kobj)
kfree(cd->devt_attr);
cd->devt_attr = NULL;
- if (cls->release)
+ if (cd->release)
+ cd->release(cd);
+ else if (cls->release)
cls->release(cd);
else {
- printk(KERN_ERR "Device class '%s' does not have a release() function, "
+ printk(KERN_ERR "Class Device '%s' does not have a release() function, "
"it is broken and must be fixed.\n",
cd->class_id);
WARN_ON(1);
@@ -382,14 +397,18 @@ static int class_hotplug(struct kset *kset, struct kobject *kobj, char **envp,
buffer = &buffer[length];
buffer_size -= length;
- if (class_dev->class->hotplug) {
- /* have the bus specific function add its stuff */
- retval = class_dev->class->hotplug (class_dev, envp, num_envp,
- buffer, buffer_size);
- if (retval) {
- pr_debug ("%s - hotplug() returned %d\n",
- __FUNCTION__, retval);
- }
+ if (class_dev->hotplug) {
+ /* have the class device specific function add its stuff */
+ retval = class_dev->hotplug(class_dev, envp, num_envp,
+ buffer, buffer_size);
+ if (retval)
+ pr_debug("class_dev->hotplug() returned %d\n", retval);
+ } else if (class_dev->class->hotplug) {
+ /* have the class specific function add its stuff */
+ retval = class_dev->class->hotplug(class_dev, envp, num_envp,
+ buffer, buffer_size);
+ if (retval)
+ pr_debug("class->hotplug() returned %d\n", retval);
}
return retval;
@@ -442,6 +461,13 @@ static ssize_t show_dev(struct class_device *class_dev, char *buf)
return print_dev_t(buf, class_dev->devt);
}
+static ssize_t store_uevent(struct class_device *class_dev,
+ const char *buf, size_t count)
+{
+ kobject_hotplug(&class_dev->kobj, KOBJ_ADD);
+ return count;
+}
+
void class_device_initialize(struct class_device *class_dev)
{
kobj_set_kset_s(class_dev, class_obj_subsys);
@@ -469,34 +495,45 @@ static char *make_class_name(struct class_device *class_dev)
int class_device_add(struct class_device *class_dev)
{
- struct class * parent = NULL;
- struct class_interface * class_intf;
+ struct class *parent_class = NULL;
+ struct class_device *parent_class_dev = NULL;
+ struct class_interface *class_intf;
char *class_name = NULL;
- int error;
+ int error = -EINVAL;
class_dev = class_device_get(class_dev);
if (!class_dev)
return -EINVAL;
- if (!strlen(class_dev->class_id)) {
- error = -EINVAL;
+ if (!strlen(class_dev->class_id))
goto register_done;
- }
- parent = class_get(class_dev->class);
+ parent_class = class_get(class_dev->class);
+ if (!parent_class)
+ goto register_done;
+ parent_class_dev = class_device_get(class_dev->parent);
pr_debug("CLASS: registering class device: ID = '%s'\n",
class_dev->class_id);
/* first, register with generic layer. */
kobject_set_name(&class_dev->kobj, "%s", class_dev->class_id);
- if (parent)
- class_dev->kobj.parent = &parent->subsys.kset.kobj;
+ if (parent_class_dev)
+ class_dev->kobj.parent = &parent_class_dev->kobj;
+ else
+ class_dev->kobj.parent = &parent_class->subsys.kset.kobj;
- if ((error = kobject_add(&class_dev->kobj)))
+ error = kobject_add(&class_dev->kobj);
+ if (error)
goto register_done;
/* add the needed attributes to this device */
+ class_dev->uevent_attr.attr.name = "uevent";
+ class_dev->uevent_attr.attr.mode = S_IWUSR;
+ class_dev->uevent_attr.attr.owner = parent_class->owner;
+ class_dev->uevent_attr.store = store_uevent;
+ class_device_create_file(class_dev, &class_dev->uevent_attr);
+
if (MAJOR(class_dev->devt)) {
struct class_device_attribute *attr;
attr = kzalloc(sizeof(*attr), GFP_KERNEL);
@@ -505,12 +542,10 @@ int class_device_add(struct class_device *class_dev)
kobject_del(&class_dev->kobj);
goto register_done;
}
-
attr->attr.name = "dev";
attr->attr.mode = S_IRUGO;
- attr->attr.owner = parent->owner;
+ attr->attr.owner = parent_class->owner;
attr->show = show_dev;
- attr->store = NULL;
class_device_create_file(class_dev, attr);
class_dev->devt_attr = attr;
}
@@ -524,20 +559,23 @@ int class_device_add(struct class_device *class_dev)
class_name);
}
+ kobject_hotplug(&class_dev->kobj, KOBJ_ADD);
+
/* notify any interfaces this device is now here */
- if (parent) {
- down(&parent->sem);
- list_add_tail(&class_dev->node, &parent->children);
- list_for_each_entry(class_intf, &parent->interfaces, node)
+ if (parent_class) {
+ down(&parent_class->sem);
+ list_add_tail(&class_dev->node, &parent_class->children);
+ list_for_each_entry(class_intf, &parent_class->interfaces, node)
if (class_intf->add)
- class_intf->add(class_dev);
- up(&parent->sem);
+ class_intf->add(class_dev, class_intf);
+ up(&parent_class->sem);
}
- kobject_hotplug(&class_dev->kobj, KOBJ_ADD);
register_done:
- if (error && parent)
- class_put(parent);
+ if (error) {
+ class_put(parent_class);
+ class_device_put(parent_class_dev);
+ }
class_device_put(class_dev);
kfree(class_name);
return error;
@@ -552,21 +590,28 @@ int class_device_register(struct class_device *class_dev)
/**
* class_device_create - creates a class device and registers it with sysfs
* @cs: pointer to the struct class that this device should be registered to.
+ * @parent: pointer to the parent struct class_device of this new device, if any.
* @dev: the dev_t for the char device to be added.
* @device: a pointer to a struct device that is assiociated with this class device.
* @fmt: string for the class device's name
*
* This function can be used by char device classes. A struct
* class_device will be created in sysfs, registered to the specified
- * class. A "dev" file will be created, showing the dev_t for the
- * device. The pointer to the struct class_device will be returned from
- * the call. Any further sysfs files that might be required can be
- * created using this pointer.
+ * class.
+ * A "dev" file will be created, showing the dev_t for the device, if
+ * the dev_t is not 0,0.
+ * If a pointer to a parent struct class_device is passed in, the newly
+ * created struct class_device will be a child of that device in sysfs.
+ * The pointer to the struct class_device will be returned from the
+ * call. Any further sysfs files that might be required can be created
+ * using this pointer.
*
* Note: the struct class passed to this function must have previously
* been created with a call to class_create().
*/
-struct class_device *class_device_create(struct class *cls, dev_t devt,
+struct class_device *class_device_create(struct class *cls,
+ struct class_device *parent,
+ dev_t devt,
struct device *device, char *fmt, ...)
{
va_list args;
@@ -585,6 +630,9 @@ struct class_device *class_device_create(struct class *cls, dev_t devt,
class_dev->devt = devt;
class_dev->dev = device;
class_dev->class = cls;
+ class_dev->parent = parent;
+ class_dev->release = class_device_create_release;
+ class_dev->hotplug = class_device_create_hotplug;
va_start(args, fmt);
vsnprintf(class_dev->class_id, BUS_ID_SIZE, fmt, args);
@@ -602,17 +650,18 @@ error:
void class_device_del(struct class_device *class_dev)
{
- struct class * parent = class_dev->class;
- struct class_interface * class_intf;
+ struct class *parent_class = class_dev->class;
+ struct class_device *parent_device = class_dev->parent;
+ struct class_interface *class_intf;
char *class_name = NULL;
- if (parent) {
- down(&parent->sem);
+ if (parent_class) {
+ down(&parent_class->sem);
list_del_init(&class_dev->node);
- list_for_each_entry(class_intf, &parent->interfaces, node)
+ list_for_each_entry(class_intf, &parent_class->interfaces, node)
if (class_intf->remove)
- class_intf->remove(class_dev);
- up(&parent->sem);
+ class_intf->remove(class_dev, class_intf);
+ up(&parent_class->sem);
}
if (class_dev->dev) {
@@ -620,6 +669,7 @@ void class_device_del(struct class_device *class_dev)
sysfs_remove_link(&class_dev->kobj, "device");
sysfs_remove_link(&class_dev->dev->kobj, class_name);
}
+ class_device_remove_file(class_dev, &class_dev->uevent_attr);
if (class_dev->devt_attr)
class_device_remove_file(class_dev, class_dev->devt_attr);
class_device_remove_attrs(class_dev);
@@ -627,8 +677,8 @@ void class_device_del(struct class_device *class_dev)
kobject_hotplug(&class_dev->kobj, KOBJ_REMOVE);
kobject_del(&class_dev->kobj);
- if (parent)
- class_put(parent);
+ class_device_put(parent_device);
+ class_put(parent_class);
kfree(class_name);
}
@@ -708,7 +758,8 @@ struct class_device * class_device_get(struct class_device *class_dev)
void class_device_put(struct class_device *class_dev)
{
- kobject_put(&class_dev->kobj);
+ if (class_dev)
+ kobject_put(&class_dev->kobj);
}
@@ -728,7 +779,7 @@ int class_interface_register(struct class_interface *class_intf)
list_add_tail(&class_intf->node, &parent->interfaces);
if (class_intf->add) {
list_for_each_entry(class_dev, &parent->children, node)
- class_intf->add(class_dev);
+ class_intf->add(class_dev, class_intf);
}
up(&parent->sem);
@@ -747,7 +798,7 @@ void class_interface_unregister(struct class_interface *class_intf)
list_del_init(&class_intf->node);
if (class_intf->remove) {
list_for_each_entry(class_dev, &parent->children, node)
- class_intf->remove(class_dev);
+ class_intf->remove(class_dev, class_intf);
}
up(&parent->sem);
diff --git a/drivers/base/core.c b/drivers/base/core.c
index 6ab73f5c799a..8615b42b517a 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -154,6 +154,13 @@ static struct kset_hotplug_ops device_hotplug_ops = {
.hotplug = dev_hotplug,
};
+static ssize_t store_uevent(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ kobject_hotplug(&dev->kobj, KOBJ_ADD);
+ return count;
+}
+
/**
* device_subsys - structure to be registered with kobject core.
*/
@@ -225,6 +232,7 @@ void device_initialize(struct device *dev)
klist_children_put);
INIT_LIST_HEAD(&dev->dma_pools);
init_MUTEX(&dev->sem);
+ device_init_wakeup(dev, 0);
}
/**
@@ -258,6 +266,14 @@ int device_add(struct device *dev)
if ((error = kobject_add(&dev->kobj)))
goto Error;
+
+ dev->uevent_attr.attr.name = "uevent";
+ dev->uevent_attr.attr.mode = S_IWUSR;
+ if (dev->driver)
+ dev->uevent_attr.attr.owner = dev->driver->owner;
+ dev->uevent_attr.store = store_uevent;
+ device_create_file(dev, &dev->uevent_attr);
+
kobject_hotplug(&dev->kobj, KOBJ_ADD);
if ((error = device_pm_add(dev)))
goto PMError;
@@ -349,6 +365,7 @@ void device_del(struct device * dev)
if (parent)
klist_del(&dev->knode_parent);
+ device_remove_file(dev, &dev->uevent_attr);
/* Notify the platform of the removal, in case they
* need to do anything...
@@ -390,11 +407,11 @@ static struct device * next_device(struct klist_iter * i)
/**
* device_for_each_child - device child iterator.
- * @dev: parent struct device.
+ * @parent: parent struct device.
* @data: data for the callback.
* @fn: function to be called for each device.
*
- * Iterate over @dev's child devices, and call @fn for each,
+ * Iterate over @parent's child devices, and call @fn for each,
* passing it @data.
*
* We check the return of @fn each time. If it returns anything
diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c
index b79badd0f158..a95844790f7b 100644
--- a/drivers/base/cpu.c
+++ b/drivers/base/cpu.c
@@ -9,12 +9,15 @@
#include <linux/topology.h>
#include <linux/device.h>
+#include "base.h"
struct sysdev_class cpu_sysdev_class = {
set_kset_name("cpu"),
};
EXPORT_SYMBOL(cpu_sysdev_class);
+static struct sys_device *cpu_sys_devices[NR_CPUS];
+
#ifdef CONFIG_HOTPLUG_CPU
int __attribute__((weak)) smp_prepare_cpu (int cpu)
{
@@ -63,6 +66,7 @@ static void __devinit register_cpu_control(struct cpu *cpu)
}
void unregister_cpu(struct cpu *cpu, struct node *root)
{
+ int logical_cpu = cpu->sysdev.id;
if (root)
sysfs_remove_link(&root->sysdev.kobj,
@@ -70,7 +74,7 @@ void unregister_cpu(struct cpu *cpu, struct node *root)
sysdev_remove_file(&cpu->sysdev, &attr_online);
sysdev_unregister(&cpu->sysdev);
-
+ cpu_sys_devices[logical_cpu] = NULL;
return;
}
#else /* ... !CONFIG_HOTPLUG_CPU */
@@ -102,10 +106,19 @@ int __devinit register_cpu(struct cpu *cpu, int num, struct node *root)
kobject_name(&cpu->sysdev.kobj));
if (!error && !cpu->no_control)
register_cpu_control(cpu);
+ if (!error)
+ cpu_sys_devices[num] = &cpu->sysdev;
return error;
}
-
+struct sys_device *get_cpu_sysdev(int cpu)
+{
+ if (cpu < NR_CPUS)
+ return cpu_sys_devices[cpu];
+ else
+ return NULL;
+}
+EXPORT_SYMBOL_GPL(get_cpu_sysdev);
int __init cpu_dev_init(void)
{
diff --git a/drivers/base/driver.c b/drivers/base/driver.c
index ef3fe513e398..161f3a390d90 100644
--- a/drivers/base/driver.c
+++ b/drivers/base/driver.c
@@ -28,6 +28,7 @@ static struct device * next_device(struct klist_iter * i)
/**
* driver_for_each_device - Iterator for devices bound to a driver.
* @drv: Driver we're iterating.
+ * @start: Device to begin with
* @data: Data to pass to the callback.
* @fn: Function to call for each device.
*
@@ -57,7 +58,7 @@ EXPORT_SYMBOL_GPL(driver_for_each_device);
/**
* driver_find_device - device iterator for locating a particular device.
- * @driver: The device's driver
+ * @drv: The device's driver
* @start: Device to begin with
* @data: Data to pass to match function
* @match: Callback function to check device
diff --git a/drivers/base/firmware.c b/drivers/base/firmware.c
index 88ab044932f2..cb1b98ae0d58 100644
--- a/drivers/base/firmware.c
+++ b/drivers/base/firmware.c
@@ -11,6 +11,9 @@
#include <linux/kobject.h>
#include <linux/module.h>
#include <linux/init.h>
+#include <linux/device.h>
+
+#include "base.h"
static decl_subsys(firmware, NULL, NULL);
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c
index 4acb2c5733c3..98f6c02d6790 100644
--- a/drivers/base/firmware_class.c
+++ b/drivers/base/firmware_class.c
@@ -62,14 +62,16 @@ firmware_timeout_show(struct class *class, char *buf)
}
/**
- * firmware_timeout_store:
- * Description:
+ * firmware_timeout_store - set number of seconds to wait for firmware
+ * @class: device class pointer
+ * @buf: buffer to scan for timeout value
+ * @count: number of bytes in @buf
+ *
* Sets the number of seconds to wait for the firmware. Once
- * this expires an error will be return to the driver and no
+ * this expires an error will be returned to the driver and no
* firmware will be provided.
*
- * Note: zero means 'wait for ever'
- *
+ * Note: zero means 'wait forever'.
**/
static ssize_t
firmware_timeout_store(struct class *class, const char *buf, size_t count)
@@ -123,12 +125,15 @@ firmware_loading_show(struct class_device *class_dev, char *buf)
}
/**
- * firmware_loading_store: - loading control file
- * Description:
+ * firmware_loading_store - set value in the 'loading' control file
+ * @class_dev: class_device pointer
+ * @buf: buffer to scan for loading control value
+ * @count: number of bytes in @buf
+ *
* The relevant values are:
*
* 1: Start a load, discarding any previous partial load.
- * 0: Conclude the load and handle the data to the driver code.
+ * 0: Conclude the load and hand the data to the driver code.
* -1: Conclude the load with an error and discard any written data.
**/
static ssize_t
@@ -201,6 +206,7 @@ out:
up(&fw_lock);
return ret_count;
}
+
static int
fw_realloc_buffer(struct firmware_priv *fw_priv, int min_size)
{
@@ -227,11 +233,13 @@ fw_realloc_buffer(struct firmware_priv *fw_priv, int min_size)
}
/**
- * firmware_data_write:
+ * firmware_data_write - write method for firmware
+ * @kobj: kobject for the class_device
+ * @buffer: buffer being written
+ * @offset: buffer offset for write in total data store area
+ * @count: buffer size
*
- * Description:
- *
- * Data written to the 'data' attribute will be later handled to
+ * Data written to the 'data' attribute will be later handed to
* the driver as a firmware image.
**/
static ssize_t
@@ -264,6 +272,7 @@ out:
up(&fw_lock);
return retval;
}
+
static struct bin_attribute firmware_attr_data_tmpl = {
.attr = {.name = "data", .mode = 0644, .owner = THIS_MODULE},
.size = 0,
@@ -448,13 +457,16 @@ out:
/**
* request_firmware: - request firmware to hotplug and wait for it
- * Description:
- * @firmware will be used to return a firmware image by the name
+ * @firmware_p: pointer to firmware image
+ * @name: name of firmware file
+ * @device: device for which firmware is being loaded
+ *
+ * @firmware_p will be used to return a firmware image by the name
* of @name for device @device.
*
* Should be called from user context where sleeping is allowed.
*
- * @name will be use as $FIRMWARE in the hotplug environment and
+ * @name will be used as $FIRMWARE in the hotplug environment and
* should be distinctive enough not to be confused with any other
* firmware image for this or any other device.
**/
@@ -468,6 +480,7 @@ request_firmware(const struct firmware **firmware_p, const char *name,
/**
* release_firmware: - release the resource associated with a firmware image
+ * @fw: firmware resource to release
**/
void
release_firmware(const struct firmware *fw)
@@ -480,8 +493,10 @@ release_firmware(const struct firmware *fw)
/**
* register_firmware: - provide a firmware image for later usage
+ * @name: name of firmware image file
+ * @data: buffer pointer for the firmware image
+ * @size: size of the data buffer area
*
- * Description:
* Make sure that @data will be available by requesting firmware @name.
*
* Note: This will not be possible until some kind of persistence
@@ -526,21 +541,19 @@ request_firmware_work_func(void *arg)
}
/**
- * request_firmware_nowait:
+ * request_firmware_nowait: asynchronous version of request_firmware
+ * @module: module requesting the firmware
+ * @hotplug: invokes hotplug event to copy the firmware image if this flag
+ * is non-zero else the firmware copy must be done manually.
+ * @name: name of firmware file
+ * @device: device for which firmware is being loaded
+ * @context: will be passed over to @cont, and
+ * @fw may be %NULL if firmware request fails.
+ * @cont: function will be called asynchronously when the firmware
+ * request is over.
*
- * Description:
* Asynchronous variant of request_firmware() for contexts where
* it is not possible to sleep.
- *
- * @hotplug invokes hotplug event to copy the firmware image if this flag
- * is non-zero else the firmware copy must be done manually.
- *
- * @cont will be called asynchronously when the firmware request is over.
- *
- * @context will be passed over to @cont.
- *
- * @fw may be %NULL if firmware request fails.
- *
**/
int
request_firmware_nowait(
diff --git a/drivers/base/init.c b/drivers/base/init.c
index a76ae5a221f3..c648914b9cde 100644
--- a/drivers/base/init.c
+++ b/drivers/base/init.c
@@ -9,15 +9,10 @@
#include <linux/device.h>
#include <linux/init.h>
+#include <linux/memory.h>
+
+#include "base.h"
-extern int devices_init(void);
-extern int buses_init(void);
-extern int classes_init(void);
-extern int firmware_init(void);
-extern int platform_bus_init(void);
-extern int system_bus_init(void);
-extern int cpu_dev_init(void);
-extern int attribute_container_init(void);
/**
* driver_init - initialize driver model.
*
@@ -39,5 +34,6 @@ void __init driver_init(void)
platform_bus_init();
system_bus_init();
cpu_dev_init();
+ memory_dev_init();
attribute_container_init();
}
diff --git a/drivers/base/memory.c b/drivers/base/memory.c
new file mode 100644
index 000000000000..b7ddd651d664
--- /dev/null
+++ b/drivers/base/memory.c
@@ -0,0 +1,452 @@
+/*
+ * drivers/base/memory.c - basic Memory class support
+ *
+ * Written by Matt Tolentino <matthew.e.tolentino@intel.com>
+ * Dave Hansen <haveblue@us.ibm.com>
+ *
+ * This file provides the necessary infrastructure to represent
+ * a SPARSEMEM-memory-model system's physical memory in /sysfs.
+ * All arch-independent code that assumes MEMORY_HOTPLUG requires
+ * SPARSEMEM should be contained here, or in mm/memory_hotplug.c.
+ */
+
+#include <linux/sysdev.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/sched.h> /* capable() */
+#include <linux/topology.h>
+#include <linux/device.h>
+#include <linux/memory.h>
+#include <linux/kobject.h>
+#include <linux/memory_hotplug.h>
+#include <linux/mm.h>
+#include <asm/atomic.h>
+#include <asm/uaccess.h>
+
+#define MEMORY_CLASS_NAME "memory"
+
+static struct sysdev_class memory_sysdev_class = {
+ set_kset_name(MEMORY_CLASS_NAME),
+};
+EXPORT_SYMBOL(memory_sysdev_class);
+
+static char *memory_hotplug_name(struct kset *kset, struct kobject *kobj)
+{
+ return MEMORY_CLASS_NAME;
+}
+
+static int memory_hotplug(struct kset *kset, struct kobject *kobj, char **envp,
+ int num_envp, char *buffer, int buffer_size)
+{
+ int retval = 0;
+
+ return retval;
+}
+
+static struct kset_hotplug_ops memory_hotplug_ops = {
+ .name = memory_hotplug_name,
+ .hotplug = memory_hotplug,
+};
+
+static struct notifier_block *memory_chain;
+
+static int register_memory_notifier(struct notifier_block *nb)
+{
+ return notifier_chain_register(&memory_chain, nb);
+}
+
+static void unregister_memory_notifier(struct notifier_block *nb)
+{
+ notifier_chain_unregister(&memory_chain, nb);
+}
+
+/*
+ * register_memory - Setup a sysfs device for a memory block
+ */
+static int
+register_memory(struct memory_block *memory, struct mem_section *section,
+ struct node *root)
+{
+ int error;
+
+ memory->sysdev.cls = &memory_sysdev_class;
+ memory->sysdev.id = __section_nr(section);
+
+ error = sysdev_register(&memory->sysdev);
+
+ if (root && !error)
+ error = sysfs_create_link(&root->sysdev.kobj,
+ &memory->sysdev.kobj,
+ kobject_name(&memory->sysdev.kobj));
+
+ return error;
+}
+
+static void
+unregister_memory(struct memory_block *memory, struct mem_section *section,
+ struct node *root)
+{
+ BUG_ON(memory->sysdev.cls != &memory_sysdev_class);
+ BUG_ON(memory->sysdev.id != __section_nr(section));
+
+ sysdev_unregister(&memory->sysdev);
+ if (root)
+ sysfs_remove_link(&root->sysdev.kobj,
+ kobject_name(&memory->sysdev.kobj));
+}
+
+/*
+ * use this as the physical section index that this memsection
+ * uses.
+ */
+
+static ssize_t show_mem_phys_index(struct sys_device *dev, char *buf)
+{
+ struct memory_block *mem =
+ container_of(dev, struct memory_block, sysdev);
+ return sprintf(buf, "%08lx\n", mem->phys_index);
+}
+
+/*
+ * online, offline, going offline, etc.
+ */
+static ssize_t show_mem_state(struct sys_device *dev, char *buf)
+{
+ struct memory_block *mem =
+ container_of(dev, struct memory_block, sysdev);
+ ssize_t len = 0;
+
+ /*
+ * We can probably put these states in a nice little array
+ * so that they're not open-coded
+ */
+ switch (mem->state) {
+ case MEM_ONLINE:
+ len = sprintf(buf, "online\n");
+ break;
+ case MEM_OFFLINE:
+ len = sprintf(buf, "offline\n");
+ break;
+ case MEM_GOING_OFFLINE:
+ len = sprintf(buf, "going-offline\n");
+ break;
+ default:
+ len = sprintf(buf, "ERROR-UNKNOWN-%ld\n",
+ mem->state);
+ WARN_ON(1);
+ break;
+ }
+
+ return len;
+}
+
+static inline int memory_notify(unsigned long val, void *v)
+{
+ return notifier_call_chain(&memory_chain, val, v);
+}
+
+/*
+ * MEMORY_HOTPLUG depends on SPARSEMEM in mm/Kconfig, so it is
+ * OK to have direct references to sparsemem variables in here.
+ */
+static int
+memory_block_action(struct memory_block *mem, unsigned long action)
+{
+ int i;
+ unsigned long psection;
+ unsigned long start_pfn, start_paddr;
+ struct page *first_page;
+ int ret;
+ int old_state = mem->state;
+
+ psection = mem->phys_index;
+ first_page = pfn_to_page(psection << PFN_SECTION_SHIFT);
+
+ /*
+ * The probe routines leave the pages reserved, just
+ * as the bootmem code does. Make sure they're still
+ * that way.
+ */
+ if (action == MEM_ONLINE) {
+ for (i = 0; i < PAGES_PER_SECTION; i++) {
+ if (PageReserved(first_page+i))
+ continue;
+
+ printk(KERN_WARNING "section number %ld page number %d "
+ "not reserved, was it already online? \n",
+ psection, i);
+ return -EBUSY;
+ }
+ }
+
+ switch (action) {
+ case MEM_ONLINE:
+ start_pfn = page_to_pfn(first_page);
+ ret = online_pages(start_pfn, PAGES_PER_SECTION);
+ break;
+ case MEM_OFFLINE:
+ mem->state = MEM_GOING_OFFLINE;
+ memory_notify(MEM_GOING_OFFLINE, NULL);
+ start_paddr = page_to_pfn(first_page) << PAGE_SHIFT;
+ ret = remove_memory(start_paddr,
+ PAGES_PER_SECTION << PAGE_SHIFT);
+ if (ret) {
+ mem->state = old_state;
+ break;
+ }
+ memory_notify(MEM_MAPPING_INVALID, NULL);
+ break;
+ default:
+ printk(KERN_WARNING "%s(%p, %ld) unknown action: %ld\n",
+ __FUNCTION__, mem, action, action);
+ WARN_ON(1);
+ ret = -EINVAL;
+ }
+ /*
+ * For now, only notify on successful memory operations
+ */
+ if (!ret)
+ memory_notify(action, NULL);
+
+ return ret;
+}
+
+static int memory_block_change_state(struct memory_block *mem,
+ unsigned long to_state, unsigned long from_state_req)
+{
+ int ret = 0;
+ down(&mem->state_sem);
+
+ if (mem->state != from_state_req) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ ret = memory_block_action(mem, to_state);
+ if (!ret)
+ mem->state = to_state;
+
+out:
+ up(&mem->state_sem);
+ return ret;
+}
+
+static ssize_t
+store_mem_state(struct sys_device *dev, const char *buf, size_t count)
+{
+ struct memory_block *mem;
+ unsigned int phys_section_nr;
+ int ret = -EINVAL;
+
+ mem = container_of(dev, struct memory_block, sysdev);
+ phys_section_nr = mem->phys_index;
+
+ if (!valid_section_nr(phys_section_nr))
+ goto out;
+
+ if (!strncmp(buf, "online", min((int)count, 6)))
+ ret = memory_block_change_state(mem, MEM_ONLINE, MEM_OFFLINE);
+ else if(!strncmp(buf, "offline", min((int)count, 7)))
+ ret = memory_block_change_state(mem, MEM_OFFLINE, MEM_ONLINE);
+out:
+ if (ret)
+ return ret;
+ return count;
+}
+
+/*
+ * phys_device is a bad name for this. What I really want
+ * is a way to differentiate between memory ranges that
+ * are part of physical devices that constitute
+ * a complete removable unit or fru.
+ * i.e. do these ranges belong to the same physical device,
+ * s.t. if I offline all of these sections I can then
+ * remove the physical device?
+ */
+static ssize_t show_phys_device(struct sys_device *dev, char *buf)
+{
+ struct memory_block *mem =
+ container_of(dev, struct memory_block, sysdev);
+ return sprintf(buf, "%d\n", mem->phys_device);
+}
+
+static SYSDEV_ATTR(phys_index, 0444, show_mem_phys_index, NULL);
+static SYSDEV_ATTR(state, 0644, show_mem_state, store_mem_state);
+static SYSDEV_ATTR(phys_device, 0444, show_phys_device, NULL);
+
+#define mem_create_simple_file(mem, attr_name) \
+ sysdev_create_file(&mem->sysdev, &attr_##attr_name)
+#define mem_remove_simple_file(mem, attr_name) \
+ sysdev_remove_file(&mem->sysdev, &attr_##attr_name)
+
+/*
+ * Block size attribute stuff
+ */
+static ssize_t
+print_block_size(struct class *class, char *buf)
+{
+ return sprintf(buf, "%lx\n", (unsigned long)PAGES_PER_SECTION * PAGE_SIZE);
+}
+
+static CLASS_ATTR(block_size_bytes, 0444, print_block_size, NULL);
+
+static int block_size_init(void)
+{
+ sysfs_create_file(&memory_sysdev_class.kset.kobj,
+ &class_attr_block_size_bytes.attr);
+ return 0;
+}
+
+/*
+ * Some architectures will have custom drivers to do this, and
+ * will not need to do it from userspace. The fake hot-add code
+ * as well as ppc64 will do all of their discovery in userspace
+ * and will require this interface.
+ */
+#ifdef CONFIG_ARCH_MEMORY_PROBE
+static ssize_t
+memory_probe_store(struct class *class, const char __user *buf, size_t count)
+{
+ u64 phys_addr;
+ int ret;
+
+ phys_addr = simple_strtoull(buf, NULL, 0);
+
+ ret = add_memory(phys_addr, PAGES_PER_SECTION << PAGE_SHIFT);
+
+ if (ret)
+ count = ret;
+
+ return count;
+}
+static CLASS_ATTR(probe, 0700, NULL, memory_probe_store);
+
+static int memory_probe_init(void)
+{
+ sysfs_create_file(&memory_sysdev_class.kset.kobj,
+ &class_attr_probe.attr);
+ return 0;
+}
+#else
+#define memory_probe_init(...) do {} while (0)
+#endif
+
+/*
+ * Note that phys_device is optional. It is here to allow for
+ * differentiation between which *physical* devices each
+ * section belongs to...
+ */
+
+static int add_memory_block(unsigned long node_id, struct mem_section *section,
+ unsigned long state, int phys_device)
+{
+ struct memory_block *mem = kzalloc(sizeof(*mem), GFP_KERNEL);
+ int ret = 0;
+
+ if (!mem)
+ return -ENOMEM;
+
+ mem->phys_index = __section_nr(section);
+ mem->state = state;
+ init_MUTEX(&mem->state_sem);
+ mem->phys_device = phys_device;
+
+ ret = register_memory(mem, section, NULL);
+ if (!ret)
+ ret = mem_create_simple_file(mem, phys_index);
+ if (!ret)
+ ret = mem_create_simple_file(mem, state);
+ if (!ret)
+ ret = mem_create_simple_file(mem, phys_device);
+
+ return ret;
+}
+
+/*
+ * For now, we have a linear search to go find the appropriate
+ * memory_block corresponding to a particular phys_index. If
+ * this gets to be a real problem, we can always use a radix
+ * tree or something here.
+ *
+ * This could be made generic for all sysdev classes.
+ */
+static struct memory_block *find_memory_block(struct mem_section *section)
+{
+ struct kobject *kobj;
+ struct sys_device *sysdev;
+ struct memory_block *mem;
+ char name[sizeof(MEMORY_CLASS_NAME) + 9 + 1];
+
+ /*
+ * This only works because we know that section == sysdev->id
+ * slightly redundant with sysdev_register()
+ */
+ sprintf(&name[0], "%s%d", MEMORY_CLASS_NAME, __section_nr(section));
+
+ kobj = kset_find_obj(&memory_sysdev_class.kset, name);
+ if (!kobj)
+ return NULL;
+
+ sysdev = container_of(kobj, struct sys_device, kobj);
+ mem = container_of(sysdev, struct memory_block, sysdev);
+
+ return mem;
+}
+
+int remove_memory_block(unsigned long node_id, struct mem_section *section,
+ int phys_device)
+{
+ struct memory_block *mem;
+
+ mem = find_memory_block(section);
+ mem_remove_simple_file(mem, phys_index);
+ mem_remove_simple_file(mem, state);
+ mem_remove_simple_file(mem, phys_device);
+ unregister_memory(mem, section, NULL);
+
+ return 0;
+}
+
+/*
+ * need an interface for the VM to add new memory regions,
+ * but without onlining it.
+ */
+int register_new_memory(struct mem_section *section)
+{
+ return add_memory_block(0, section, MEM_OFFLINE, 0);
+}
+
+int unregister_memory_section(struct mem_section *section)
+{
+ if (!valid_section(section))
+ return -EINVAL;
+
+ return remove_memory_block(0, section, 0);
+}
+
+/*
+ * Initialize the sysfs support for memory devices...
+ */
+int __init memory_dev_init(void)
+{
+ unsigned int i;
+ int ret;
+
+ memory_sysdev_class.kset.hotplug_ops = &memory_hotplug_ops;
+ ret = sysdev_class_register(&memory_sysdev_class);
+
+ /*
+ * Create entries for memory sections that were found
+ * during boot and have been initialized
+ */
+ for (i = 0; i < NR_MEM_SECTIONS; i++) {
+ if (!valid_section_nr(i))
+ continue;
+ add_memory_block(0, __nr_to_section(i), MEM_ONLINE, 0);
+ }
+
+ memory_probe_init();
+ block_size_init();
+
+ return ret;
+}
diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index 361e204209eb..6d4736e89f1a 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -10,12 +10,15 @@
* information.
*/
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/dma-mapping.h>
#include <linux/bootmem.h>
#include <linux/err.h>
+#include <linux/slab.h>
+
+#include "base.h"
struct device platform_bus = {
.bus_id = "platform",
@@ -113,12 +116,115 @@ int platform_add_devices(struct platform_device **devs, int num)
return ret;
}
+struct platform_object {
+ struct platform_device pdev;
+ char name[1];
+};
+
/**
- * platform_device_register - add a platform-level device
+ * platform_device_put
+ * @pdev: platform device to free
+ *
+ * Free all memory associated with a platform device. This function
+ * must _only_ be externally called in error cases. All other usage
+ * is a bug.
+ */
+void platform_device_put(struct platform_device *pdev)
+{
+ if (pdev)
+ put_device(&pdev->dev);
+}
+EXPORT_SYMBOL_GPL(platform_device_put);
+
+static void platform_device_release(struct device *dev)
+{
+ struct platform_object *pa = container_of(dev, struct platform_object, pdev.dev);
+
+ kfree(pa->pdev.dev.platform_data);
+ kfree(pa->pdev.resource);
+ kfree(pa);
+}
+
+/**
+ * platform_device_alloc
+ * @name: base name of the device we're adding
+ * @id: instance id
+ *
+ * Create a platform device object which can have other objects attached
+ * to it, and which will have attached objects freed when it is released.
+ */
+struct platform_device *platform_device_alloc(const char *name, unsigned int id)
+{
+ struct platform_object *pa;
+
+ pa = kzalloc(sizeof(struct platform_object) + strlen(name), GFP_KERNEL);
+ if (pa) {
+ strcpy(pa->name, name);
+ pa->pdev.name = pa->name;
+ pa->pdev.id = id;
+ device_initialize(&pa->pdev.dev);
+ pa->pdev.dev.release = platform_device_release;
+ }
+
+ return pa ? &pa->pdev : NULL;
+}
+EXPORT_SYMBOL_GPL(platform_device_alloc);
+
+/**
+ * platform_device_add_resources
+ * @pdev: platform device allocated by platform_device_alloc to add resources to
+ * @res: set of resources that needs to be allocated for the device
+ * @num: number of resources
+ *
+ * Add a copy of the resources to the platform device. The memory
+ * associated with the resources will be freed when the platform
+ * device is released.
+ */
+int platform_device_add_resources(struct platform_device *pdev, struct resource *res, unsigned int num)
+{
+ struct resource *r;
+
+ r = kmalloc(sizeof(struct resource) * num, GFP_KERNEL);
+ if (r) {
+ memcpy(r, res, sizeof(struct resource) * num);
+ pdev->resource = r;
+ pdev->num_resources = num;
+ }
+ return r ? 0 : -ENOMEM;
+}
+EXPORT_SYMBOL_GPL(platform_device_add_resources);
+
+/**
+ * platform_device_add_data
+ * @pdev: platform device allocated by platform_device_alloc to add resources to
+ * @data: platform specific data for this platform device
+ * @size: size of platform specific data
+ *
+ * Add a copy of platform specific data to the platform device's platform_data
+ * pointer. The memory associated with the platform data will be freed
+ * when the platform device is released.
+ */
+int platform_device_add_data(struct platform_device *pdev, void *data, size_t size)
+{
+ void *d;
+
+ d = kmalloc(size, GFP_KERNEL);
+ if (d) {
+ memcpy(d, data, size);
+ pdev->dev.platform_data = d;
+ }
+ return d ? 0 : -ENOMEM;
+}
+EXPORT_SYMBOL_GPL(platform_device_add_data);
+
+/**
+ * platform_device_add - add a platform device to device hierarchy
* @pdev: platform device we're adding
*
+ * This is part 2 of platform_device_register(), though may be called
+ * separately _iff_ pdev was allocated by platform_device_alloc().
*/
-int platform_device_register(struct platform_device * pdev)
+int platform_device_add(struct platform_device *pdev)
{
int i, ret = 0;
@@ -171,6 +277,18 @@ int platform_device_register(struct platform_device * pdev)
release_resource(&pdev->resource[i]);
return ret;
}
+EXPORT_SYMBOL_GPL(platform_device_add);
+
+/**
+ * platform_device_register - add a platform-level device
+ * @pdev: platform device we're adding
+ *
+ */
+int platform_device_register(struct platform_device * pdev)
+{
+ device_initialize(&pdev->dev);
+ return platform_device_add(pdev);
+}
/**
* platform_device_unregister - remove a platform-level device
@@ -194,18 +312,6 @@ void platform_device_unregister(struct platform_device * pdev)
}
}
-struct platform_object {
- struct platform_device pdev;
- struct resource resources[0];
-};
-
-static void platform_device_release_simple(struct device *dev)
-{
- struct platform_device *pdev = to_platform_device(dev);
-
- kfree(container_of(pdev, struct platform_object, pdev));
-}
-
/**
* platform_device_register_simple
* @name: base name of the device we're adding
@@ -222,33 +328,29 @@ static void platform_device_release_simple(struct device *dev)
struct platform_device *platform_device_register_simple(char *name, unsigned int id,
struct resource *res, unsigned int num)
{
- struct platform_object *pobj;
+ struct platform_device *pdev;
int retval;
- pobj = kzalloc(sizeof(*pobj) + sizeof(struct resource) * num, GFP_KERNEL);
- if (!pobj) {
+ pdev = platform_device_alloc(name, id);
+ if (!pdev) {
retval = -ENOMEM;
goto error;
}
- pobj->pdev.name = name;
- pobj->pdev.id = id;
- pobj->pdev.dev.release = platform_device_release_simple;
-
if (num) {
- memcpy(pobj->resources, res, sizeof(struct resource) * num);
- pobj->pdev.resource = pobj->resources;
- pobj->pdev.num_resources = num;
+ retval = platform_device_add_resources(pdev, res, num);
+ if (retval)
+ goto error;
}
- retval = platform_device_register(&pobj->pdev);
+ retval = platform_device_add(pdev);
if (retval)
goto error;
- return &pobj->pdev;
+ return pdev;
error:
- kfree(pobj);
+ platform_device_put(pdev);
return ERR_PTR(retval);
}
@@ -279,13 +381,9 @@ static int platform_suspend(struct device * dev, pm_message_t state)
{
int ret = 0;
- if (dev->driver && dev->driver->suspend) {
- ret = dev->driver->suspend(dev, state, SUSPEND_DISABLE);
- if (ret == 0)
- ret = dev->driver->suspend(dev, state, SUSPEND_SAVE_STATE);
- if (ret == 0)
- ret = dev->driver->suspend(dev, state, SUSPEND_POWER_DOWN);
- }
+ if (dev->driver && dev->driver->suspend)
+ ret = dev->driver->suspend(dev, state);
+
return ret;
}
@@ -293,13 +391,9 @@ static int platform_resume(struct device * dev)
{
int ret = 0;
- if (dev->driver && dev->driver->resume) {
- ret = dev->driver->resume(dev, RESUME_POWER_ON);
- if (ret == 0)
- ret = dev->driver->resume(dev, RESUME_RESTORE_STATE);
- if (ret == 0)
- ret = dev->driver->resume(dev, RESUME_ENABLE);
- }
+ if (dev->driver && dev->driver->resume)
+ ret = dev->driver->resume(dev);
+
return ret;
}
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
index 15e6a8f951f1..0d2e101e4f15 100644
--- a/drivers/base/power/main.c
+++ b/drivers/base/power/main.c
@@ -30,23 +30,6 @@ LIST_HEAD(dpm_off_irq);
DECLARE_MUTEX(dpm_sem);
DECLARE_MUTEX(dpm_list_sem);
-/*
- * PM Reference Counting.
- */
-
-static inline void device_pm_hold(struct device * dev)
-{
- if (dev)
- atomic_inc(&dev->power.pm_users);
-}
-
-static inline void device_pm_release(struct device * dev)
-{
- if (dev)
- atomic_dec(&dev->power.pm_users);
-}
-
-
/**
* device_pm_set_parent - Specify power dependency.
* @dev: Device who needs power.
@@ -62,10 +45,8 @@ static inline void device_pm_release(struct device * dev)
void device_pm_set_parent(struct device * dev, struct device * parent)
{
- struct device * old_parent = dev->power.pm_parent;
- device_pm_release(old_parent);
- dev->power.pm_parent = parent;
- device_pm_hold(parent);
+ put_device(dev->power.pm_parent);
+ dev->power.pm_parent = get_device(parent);
}
EXPORT_SYMBOL_GPL(device_pm_set_parent);
@@ -75,7 +56,6 @@ int device_pm_add(struct device * dev)
pr_debug("PM: Adding info for %s:%s\n",
dev->bus ? dev->bus->name : "No Bus", dev->kobj.name);
- atomic_set(&dev->power.pm_users, 0);
down(&dpm_list_sem);
list_add_tail(&dev->power.entry, &dpm_active);
device_pm_set_parent(dev, dev->parent);
@@ -91,7 +71,7 @@ void device_pm_remove(struct device * dev)
dev->bus ? dev->bus->name : "No Bus", dev->kobj.name);
down(&dpm_list_sem);
dpm_sysfs_remove(dev);
- device_pm_release(dev->power.pm_parent);
+ put_device(dev->power.pm_parent);
list_del_init(&dev->power.entry);
up(&dpm_list_sem);
}
diff --git a/drivers/base/power/power.h b/drivers/base/power/power.h
index 2e700d795cf1..fb3d35a9e101 100644
--- a/drivers/base/power/power.h
+++ b/drivers/base/power/power.h
@@ -67,9 +67,6 @@ extern int suspend_device(struct device *, pm_message_t);
* runtime.c
*/
-extern int dpm_runtime_suspend(struct device *, pm_message_t);
-extern void dpm_runtime_resume(struct device *);
-
#else /* CONFIG_PM */
@@ -82,14 +79,4 @@ static inline void device_pm_remove(struct device * dev)
}
-static inline int dpm_runtime_suspend(struct device * dev, pm_message_t state)
-{
- return 0;
-}
-
-static inline void dpm_runtime_resume(struct device * dev)
-{
-
-}
-
#endif
diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c
index e8f0519f5dfa..adbc3148c039 100644
--- a/drivers/base/power/runtime.c
+++ b/drivers/base/power/runtime.c
@@ -36,6 +36,7 @@ void dpm_runtime_resume(struct device * dev)
runtime_resume(dev);
up(&dpm_sem);
}
+EXPORT_SYMBOL(dpm_runtime_resume);
/**
diff --git a/drivers/base/power/sysfs.c b/drivers/base/power/sysfs.c
index 8d04fb435c17..f3a0c562bcb5 100644
--- a/drivers/base/power/sysfs.c
+++ b/drivers/base/power/sysfs.c
@@ -3,6 +3,7 @@
*/
#include <linux/device.h>
+#include <linux/string.h>
#include "power.h"
@@ -48,8 +49,81 @@ static ssize_t state_store(struct device * dev, struct device_attribute *attr, c
static DEVICE_ATTR(state, 0644, state_show, state_store);
+/*
+ * wakeup - Report/change current wakeup option for device
+ *
+ * Some devices support "wakeup" events, which are hardware signals
+ * used to activate devices from suspended or low power states. Such
+ * devices have one of three values for the sysfs power/wakeup file:
+ *
+ * + "enabled\n" to issue the events;
+ * + "disabled\n" not to do so; or
+ * + "\n" for temporary or permanent inability to issue wakeup.
+ *
+ * (For example, unconfigured USB devices can't issue wakeups.)
+ *
+ * Familiar examples of devices that can issue wakeup events include
+ * keyboards and mice (both PS2 and USB styles), power buttons, modems,
+ * "Wake-On-LAN" Ethernet links, GPIO lines, and more. Some events
+ * will wake the entire system from a suspend state; others may just
+ * wake up the device (if the system as a whole is already active).
+ * Some wakeup events use normal IRQ lines; other use special out
+ * of band signaling.
+ *
+ * It is the responsibility of device drivers to enable (or disable)
+ * wakeup signaling as part of changing device power states, respecting
+ * the policy choices provided through the driver model.
+ *
+ * Devices may not be able to generate wakeup events from all power
+ * states. Also, the events may be ignored in some configurations;
+ * for example, they might need help from other devices that aren't
+ * active, or which may have wakeup disabled. Some drivers rely on
+ * wakeup events internally (unless they are disabled), keeping
+ * their hardware in low power modes whenever they're unused. This
+ * saves runtime power, without requiring system-wide sleep states.
+ */
+
+static const char enabled[] = "enabled";
+static const char disabled[] = "disabled";
+
+static ssize_t
+wake_show(struct device * dev, struct device_attribute *attr, char * buf)
+{
+ return sprintf(buf, "%s\n", device_can_wakeup(dev)
+ ? (device_may_wakeup(dev) ? enabled : disabled)
+ : "");
+}
+
+static ssize_t
+wake_store(struct device * dev, struct device_attribute *attr,
+ const char * buf, size_t n)
+{
+ char *cp;
+ int len = n;
+
+ if (!device_can_wakeup(dev))
+ return -EINVAL;
+
+ cp = memchr(buf, '\n', n);
+ if (cp)
+ len = cp - buf;
+ if (len == sizeof enabled - 1
+ && strncmp(buf, enabled, sizeof enabled - 1) == 0)
+ device_set_wakeup_enable(dev, 1);
+ else if (len == sizeof disabled - 1
+ && strncmp(buf, disabled, sizeof disabled - 1) == 0)
+ device_set_wakeup_enable(dev, 0);
+ else
+ return -EINVAL;
+ return n;
+}
+
+static DEVICE_ATTR(wakeup, 0644, wake_show, wake_store);
+
+
static struct attribute * power_attrs[] = {
&dev_attr_state.attr,
+ &dev_attr_wakeup.attr,
NULL,
};
static struct attribute_group pm_attr_group = {
diff --git a/drivers/base/sys.c b/drivers/base/sys.c
index 3431eb6004c3..66ed8f2fece5 100644
--- a/drivers/base/sys.c
+++ b/drivers/base/sys.c
@@ -21,6 +21,7 @@
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/pm.h>
+#include <asm/semaphore.h>
extern struct subsystem devices_subsys;
diff --git a/drivers/block/DAC960.c b/drivers/block/DAC960.c
index 3760edfdc65c..70eaa5c7ac08 100644
--- a/drivers/block/DAC960.c
+++ b/drivers/block/DAC960.c
@@ -417,14 +417,12 @@ static void DAC960_DestroyAuxiliaryStructures(DAC960_Controller_T *Controller)
* Remember the beginning of the group, but don't free it
* until we've reached the beginning of the next group.
*/
- if (CommandGroup != NULL)
- kfree(CommandGroup);
- CommandGroup = Command;
+ kfree(CommandGroup);
+ CommandGroup = Command;
}
Controller->Commands[i] = NULL;
}
- if (CommandGroup != NULL)
- kfree(CommandGroup);
+ kfree(CommandGroup);
if (Controller->CombinedStatusBuffer != NULL)
{
@@ -435,30 +433,23 @@ static void DAC960_DestroyAuxiliaryStructures(DAC960_Controller_T *Controller)
if (ScatterGatherPool != NULL)
pci_pool_destroy(ScatterGatherPool);
- if (Controller->FirmwareType == DAC960_V1_Controller) return;
+ if (Controller->FirmwareType == DAC960_V1_Controller)
+ return;
if (RequestSensePool != NULL)
pci_pool_destroy(RequestSensePool);
- for (i = 0; i < DAC960_MaxLogicalDrives; i++)
- if (Controller->V2.LogicalDeviceInformation[i] != NULL)
- {
+ for (i = 0; i < DAC960_MaxLogicalDrives; i++) {
kfree(Controller->V2.LogicalDeviceInformation[i]);
Controller->V2.LogicalDeviceInformation[i] = NULL;
- }
+ }
for (i = 0; i < DAC960_V2_MaxPhysicalDevices; i++)
{
- if (Controller->V2.PhysicalDeviceInformation[i] != NULL)
- {
- kfree(Controller->V2.PhysicalDeviceInformation[i]);
- Controller->V2.PhysicalDeviceInformation[i] = NULL;
- }
- if (Controller->V2.InquiryUnitSerialNumber[i] != NULL)
- {
- kfree(Controller->V2.InquiryUnitSerialNumber[i]);
- Controller->V2.InquiryUnitSerialNumber[i] = NULL;
- }
+ kfree(Controller->V2.PhysicalDeviceInformation[i]);
+ Controller->V2.PhysicalDeviceInformation[i] = NULL;
+ kfree(Controller->V2.InquiryUnitSerialNumber[i]);
+ Controller->V2.InquiryUnitSerialNumber[i] = NULL;
}
}
diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig
index 51b0af1cebee..7b1cd93892be 100644
--- a/drivers/block/Kconfig
+++ b/drivers/block/Kconfig
@@ -409,16 +409,6 @@ config BLK_DEV_INITRD
for details.
-#XXX - it makes sense to enable this only for 32-bit subarch's, not for x86_64
-#for instance.
-config LBD
- bool "Support for Large Block Devices"
- depends on X86 || (MIPS && 32BIT) || PPC32 || ARCH_S390_31 || SUPERH || UML
- help
- Say Y here if you want to attach large (bigger than 2TB) discs to
- your machine, or if you want to have a raid or loopback device
- bigger than 2TB. Otherwise say N.
-
config CDROM_PKTCDVD
tristate "Packet writing on CD/DVD media"
depends on !UML
@@ -455,8 +445,6 @@ config CDROM_PKTCDVD_WCACHE
source "drivers/s390/block/Kconfig"
-source "drivers/block/Kconfig.iosched"
-
config ATA_OVER_ETH
tristate "ATA over Ethernet support"
depends on NET
diff --git a/drivers/block/Makefile b/drivers/block/Makefile
index 1cf09a1c065b..3ec1f8df87b1 100644
--- a/drivers/block/Makefile
+++ b/drivers/block/Makefile
@@ -4,21 +4,7 @@
# 12 June 2000, Christoph Hellwig <hch@infradead.org>
# Rewritten to use lists instead of if-statements.
#
-# Note : at this point, these files are compiled on all systems.
-# In the future, some of these should be built conditionally.
-#
-
-#
-# NOTE that ll_rw_blk.c must come early in linkage order - it starts the
-# kblockd threads
-#
-
-obj-y := elevator.o ll_rw_blk.o ioctl.o genhd.o scsi_ioctl.o
-obj-$(CONFIG_IOSCHED_NOOP) += noop-iosched.o
-obj-$(CONFIG_IOSCHED_AS) += as-iosched.o
-obj-$(CONFIG_IOSCHED_DEADLINE) += deadline-iosched.o
-obj-$(CONFIG_IOSCHED_CFQ) += cfq-iosched.o
obj-$(CONFIG_MAC_FLOPPY) += swim3.o
obj-$(CONFIG_BLK_DEV_FD) += floppy.o
obj-$(CONFIG_BLK_DEV_FD98) += floppy98.o
diff --git a/drivers/block/amiflop.c b/drivers/block/amiflop.c
index 1468e8cf712d..0acbfff8ad28 100644
--- a/drivers/block/amiflop.c
+++ b/drivers/block/amiflop.c
@@ -1816,7 +1816,6 @@ out_blkdev:
}
#ifdef MODULE
-#include <linux/version.h>
int init_module(void)
{
diff --git a/drivers/block/aoe/aoe.h b/drivers/block/aoe/aoe.h
index 0e9e586e9ba3..881c48d941b7 100644
--- a/drivers/block/aoe/aoe.h
+++ b/drivers/block/aoe/aoe.h
@@ -1,5 +1,5 @@
/* Copyright (c) 2004 Coraid, Inc. See COPYING for GPL terms. */
-#define VERSION "12"
+#define VERSION "14"
#define AOE_MAJOR 152
#define DEVICE_NAME "aoe"
diff --git a/drivers/block/aoe/aoechr.c b/drivers/block/aoe/aoechr.c
index 45a243096187..41ae0ede619a 100644
--- a/drivers/block/aoe/aoechr.c
+++ b/drivers/block/aoe/aoechr.c
@@ -224,7 +224,7 @@ aoechr_init(void)
return PTR_ERR(aoe_class);
}
for (i = 0; i < ARRAY_SIZE(chardevs); ++i)
- class_device_create(aoe_class,
+ class_device_create(aoe_class, NULL,
MKDEV(AOE_MAJOR, chardevs[i].minor),
NULL, chardevs[i].name);
diff --git a/drivers/block/aoe/aoecmd.c b/drivers/block/aoe/aoecmd.c
index b5be4b7d7b5b..326ca3876b68 100644
--- a/drivers/block/aoe/aoecmd.c
+++ b/drivers/block/aoe/aoecmd.c
@@ -8,6 +8,7 @@
#include <linux/blkdev.h>
#include <linux/skbuff.h>
#include <linux/netdevice.h>
+#include <asm/unaligned.h>
#include "aoe.h"
#define TIMERTICK (HZ / 10)
@@ -311,16 +312,16 @@ ataid_complete(struct aoedev *d, unsigned char *id)
u16 n;
/* word 83: command set supported */
- n = le16_to_cpup((__le16 *) &id[83<<1]);
+ n = le16_to_cpu(get_unaligned((__le16 *) &id[83<<1]));
/* word 86: command set/feature enabled */
- n |= le16_to_cpup((__le16 *) &id[86<<1]);
+ n |= le16_to_cpu(get_unaligned((__le16 *) &id[86<<1]));
if (n & (1<<10)) { /* bit 10: LBA 48 */
d->flags |= DEVFL_EXT;
/* word 100: number lba48 sectors */
- ssize = le64_to_cpup((__le64 *) &id[100<<1]);
+ ssize = le64_to_cpu(get_unaligned((__le64 *) &id[100<<1]));
/* set as in ide-disk.c:init_idedisk_capacity */
d->geo.cylinders = ssize;
@@ -331,12 +332,12 @@ ataid_complete(struct aoedev *d, unsigned char *id)
d->flags &= ~DEVFL_EXT;
/* number lba28 sectors */
- ssize = le32_to_cpup((__le32 *) &id[60<<1]);
+ ssize = le32_to_cpu(get_unaligned((__le32 *) &id[60<<1]));
/* NOTE: obsolete in ATA 6 */
- d->geo.cylinders = le16_to_cpup((__le16 *) &id[54<<1]);
- d->geo.heads = le16_to_cpup((__le16 *) &id[55<<1]);
- d->geo.sectors = le16_to_cpup((__le16 *) &id[56<<1]);
+ d->geo.cylinders = le16_to_cpu(get_unaligned((__le16 *) &id[54<<1]));
+ d->geo.heads = le16_to_cpu(get_unaligned((__le16 *) &id[55<<1]));
+ d->geo.sectors = le16_to_cpu(get_unaligned((__le16 *) &id[56<<1]));
}
d->ssize = ssize;
d->geo.start = 0;
@@ -467,16 +468,11 @@ aoecmd_ata_rsp(struct sk_buff *skb)
unsigned long duration = jiffies - buf->start_time;
unsigned long n_sect = buf->bio->bi_size >> 9;
struct gendisk *disk = d->gd;
+ const int rw = bio_data_dir(buf->bio);
- if (bio_data_dir(buf->bio) == WRITE) {
- disk_stat_inc(disk, writes);
- disk_stat_add(disk, write_ticks, duration);
- disk_stat_add(disk, write_sectors, n_sect);
- } else {
- disk_stat_inc(disk, reads);
- disk_stat_add(disk, read_ticks, duration);
- disk_stat_add(disk, read_sectors, n_sect);
- }
+ disk_stat_inc(disk, ios[rw]);
+ disk_stat_add(disk, ticks[rw], duration);
+ disk_stat_add(disk, sectors[rw], n_sect);
disk_stat_add(disk, io_ticks, duration);
n = (buf->flags & BUFFL_FAIL) ? -EIO : 0;
bio_endio(buf->bio, buf->bio->bi_size, n);
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c
index 486b6e1c7dfb..a97c80b57737 100644
--- a/drivers/block/cciss.c
+++ b/drivers/block/cciss.c
@@ -1096,14 +1096,11 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
cleanup1:
if (buff) {
for(i=0; i<sg_used; i++)
- if(buff[i] != NULL)
- kfree(buff[i]);
+ kfree(buff[i]);
kfree(buff);
}
- if (buff_size)
- kfree(buff_size);
- if (ioc)
- kfree(ioc);
+ kfree(buff_size);
+ kfree(ioc);
return(status);
}
default:
@@ -3034,8 +3031,7 @@ static int __devinit cciss_init_one(struct pci_dev *pdev,
return(1);
clean4:
- if(hba[i]->cmd_pool_bits)
- kfree(hba[i]->cmd_pool_bits);
+ kfree(hba[i]->cmd_pool_bits);
if(hba[i]->cmd_pool)
pci_free_consistent(hba[i]->pdev,
NR_CMDS * sizeof(CommandList_struct),
diff --git a/drivers/block/cciss_scsi.c b/drivers/block/cciss_scsi.c
index e183a3ef7839..ec27976a57da 100644
--- a/drivers/block/cciss_scsi.c
+++ b/drivers/block/cciss_scsi.c
@@ -28,13 +28,17 @@
through the array controller. Note in particular, neither
physical nor logical disks are presented through the scsi layer. */
+#include <linux/timer.h>
+#include <linux/completion.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+
+#include <asm/atomic.h>
+
#include <scsi/scsi.h>
#include <scsi/scsi_cmnd.h>
#include <scsi/scsi_device.h>
#include <scsi/scsi_host.h>
-#include <asm/atomic.h>
-#include <linux/timer.h>
-#include <linux/completion.h>
#include "cciss_scsi.h"
diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c
index 00895477155e..28002de783b6 100644
--- a/drivers/block/floppy.c
+++ b/drivers/block/floppy.c
@@ -177,7 +177,7 @@ static int print_unex = 1;
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/devfs_fs_kernel.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <linux/buffer_head.h> /* for invalidate_buffers() */
/*
@@ -3714,6 +3714,12 @@ static int floppy_open(struct inode *inode, struct file *filp)
USETF(FD_VERIFY);
}
+ /* set underlying gendisk policy to reflect real ro/rw status */
+ if (UTESTF(FD_DISK_WRITABLE))
+ inode->i_bdev->bd_disk->policy = 0;
+ else
+ inode->i_bdev->bd_disk->policy = 1;
+
if (UDRS->fd_ref == -1 || (UDRS->fd_ref && (filp->f_flags & O_EXCL)))
goto out2;
@@ -3770,8 +3776,7 @@ static int floppy_open(struct inode *inode, struct file *filp)
/* Allow ioctls if we have write-permissions even if read-only open.
* Needed so that programs such as fdrawcmd still can work on write
* protected disks */
- if (filp->f_mode & 2
- || permission(filp->f_dentry->d_inode, 2, NULL) == 0)
+ if ((filp->f_mode & FMODE_WRITE) || !file_permission(filp, MAY_WRITE))
filp->private_data = (void *)8;
if (UFDCS->rawcmd == 1)
diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index b35e08876dd4..96c664af8d06 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -881,7 +881,7 @@ loop_init_xfer(struct loop_device *lo, struct loop_func_table *xfer,
static int loop_clr_fd(struct loop_device *lo, struct block_device *bdev)
{
struct file *filp = lo->lo_backing_file;
- int gfp = lo->old_gfp_mask;
+ gfp_t gfp = lo->old_gfp_mask;
if (lo->lo_state != Lo_bound)
return -ENXIO;
diff --git a/drivers/block/noop-iosched.c b/drivers/block/noop-iosched.c
deleted file mode 100644
index b1730b62c37e..000000000000
--- a/drivers/block/noop-iosched.c
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * elevator noop
- */
-#include <linux/blkdev.h>
-#include <linux/elevator.h>
-#include <linux/bio.h>
-#include <linux/module.h>
-#include <linux/init.h>
-
-/*
- * See if we can find a request that this buffer can be coalesced with.
- */
-static int elevator_noop_merge(request_queue_t *q, struct request **req,
- struct bio *bio)
-{
- int ret;
-
- ret = elv_try_last_merge(q, bio);
- if (ret != ELEVATOR_NO_MERGE)
- *req = q->last_merge;
-
- return ret;
-}
-
-static void elevator_noop_merge_requests(request_queue_t *q, struct request *req,
- struct request *next)
-{
- list_del_init(&next->queuelist);
-}
-
-static void elevator_noop_add_request(request_queue_t *q, struct request *rq,
- int where)
-{
- if (where == ELEVATOR_INSERT_FRONT)
- list_add(&rq->queuelist, &q->queue_head);
- else
- list_add_tail(&rq->queuelist, &q->queue_head);
-
- /*
- * new merges must not precede this barrier
- */
- if (rq->flags & REQ_HARDBARRIER)
- q->last_merge = NULL;
- else if (!q->last_merge)
- q->last_merge = rq;
-}
-
-static struct request *elevator_noop_next_request(request_queue_t *q)
-{
- if (!list_empty(&q->queue_head))
- return list_entry_rq(q->queue_head.next);
-
- return NULL;
-}
-
-static struct elevator_type elevator_noop = {
- .ops = {
- .elevator_merge_fn = elevator_noop_merge,
- .elevator_merge_req_fn = elevator_noop_merge_requests,
- .elevator_next_req_fn = elevator_noop_next_request,
- .elevator_add_req_fn = elevator_noop_add_request,
- },
- .elevator_name = "noop",
- .elevator_owner = THIS_MODULE,
-};
-
-static int __init noop_init(void)
-{
- return elv_register(&elevator_noop);
-}
-
-static void __exit noop_exit(void)
-{
- elv_unregister(&elevator_noop);
-}
-
-module_init(noop_init);
-module_exit(noop_exit);
-
-
-MODULE_AUTHOR("Jens Axboe");
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("No-op IO scheduler");
diff --git a/drivers/block/paride/paride.c b/drivers/block/paride/paride.c
index 1fef136c0e41..ce94aa11f6a7 100644
--- a/drivers/block/paride/paride.c
+++ b/drivers/block/paride/paride.c
@@ -29,6 +29,7 @@
#include <linux/string.h>
#include <linux/spinlock.h>
#include <linux/wait.h>
+#include <linux/sched.h> /* TASK_* */
#ifdef CONFIG_PARPORT_MODULE
#define CONFIG_PARPORT
diff --git a/drivers/block/paride/pf.c b/drivers/block/paride/pf.c
index 94af920465b5..e9746af29b9f 100644
--- a/drivers/block/paride/pf.c
+++ b/drivers/block/paride/pf.c
@@ -807,10 +807,6 @@ static int pf_next_buf(void)
return 1;
spin_lock_irqsave(&pf_spin_lock, saved_flags);
pf_end_request(1);
- if (pf_req) {
- pf_count = pf_req->current_nr_sectors;
- pf_buf = pf_req->buffer;
- }
spin_unlock_irqrestore(&pf_spin_lock, saved_flags);
return 1;
}
diff --git a/drivers/block/paride/pg.c b/drivers/block/paride/pg.c
index b3982395f22b..6f5df0fad703 100644
--- a/drivers/block/paride/pg.c
+++ b/drivers/block/paride/pg.c
@@ -162,6 +162,8 @@ enum {D_PRT, D_PRO, D_UNI, D_MOD, D_SLV, D_DLY};
#include <linux/mtio.h>
#include <linux/pg.h>
#include <linux/device.h>
+#include <linux/sched.h> /* current, TASK_* */
+#include <linux/jiffies.h>
#include <asm/uaccess.h>
@@ -674,7 +676,7 @@ static int __init pg_init(void)
for (unit = 0; unit < PG_UNITS; unit++) {
struct pg *dev = &devices[unit];
if (dev->present) {
- class_device_create(pg_class, MKDEV(major, unit),
+ class_device_create(pg_class, NULL, MKDEV(major, unit),
NULL, "pg%u", unit);
err = devfs_mk_cdev(MKDEV(major, unit),
S_IFCHR | S_IRUSR | S_IWUSR, "pg/%u",
diff --git a/drivers/block/paride/pt.c b/drivers/block/paride/pt.c
index d8d35233cf49..715ae5dc88fb 100644
--- a/drivers/block/paride/pt.c
+++ b/drivers/block/paride/pt.c
@@ -146,6 +146,7 @@ static int (*drives[4])[6] = {&drive0, &drive1, &drive2, &drive3};
#include <linux/slab.h>
#include <linux/mtio.h>
#include <linux/device.h>
+#include <linux/sched.h> /* current, TASK_*, schedule_timeout() */
#include <asm/uaccess.h>
@@ -971,7 +972,7 @@ static int __init pt_init(void)
devfs_mk_dir("pt");
for (unit = 0; unit < PT_UNITS; unit++)
if (pt[unit].present) {
- class_device_create(pt_class, MKDEV(major, unit),
+ class_device_create(pt_class, NULL, MKDEV(major, unit),
NULL, "pt%d", unit);
err = devfs_mk_cdev(MKDEV(major, unit),
S_IFCHR | S_IRUSR | S_IWUSR,
@@ -980,7 +981,7 @@ static int __init pt_init(void)
class_device_destroy(pt_class, MKDEV(major, unit));
goto out_class;
}
- class_device_create(pt_class, MKDEV(major, unit + 128),
+ class_device_create(pt_class, NULL, MKDEV(major, unit + 128),
NULL, "pt%dn", unit);
err = devfs_mk_cdev(MKDEV(major, unit + 128),
S_IFCHR | S_IRUSR | S_IWUSR,
diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c
index a280e679b1ca..59e5982a5db3 100644
--- a/drivers/block/pktcdvd.c
+++ b/drivers/block/pktcdvd.c
@@ -511,14 +511,11 @@ static void pkt_queue_bio(struct pktcdvd_device *pd, struct bio *bio)
*/
static void pkt_iosched_process_queue(struct pktcdvd_device *pd)
{
- request_queue_t *q;
if (atomic_read(&pd->iosched.attention) == 0)
return;
atomic_set(&pd->iosched.attention, 0);
- q = bdev_get_queue(pd->bdev);
-
for (;;) {
struct bio *bio;
int reads_queued, writes_queued;
diff --git a/drivers/block/rd.c b/drivers/block/rd.c
index 145c1fbffe01..68c60a5bcdab 100644
--- a/drivers/block/rd.c
+++ b/drivers/block/rd.c
@@ -348,7 +348,7 @@ static int rd_open(struct inode *inode, struct file *filp)
struct block_device *bdev = inode->i_bdev;
struct address_space *mapping;
unsigned bsize;
- int gfp_mask;
+ gfp_t gfp_mask;
inode = igrab(bdev->bd_inode);
rd_bdev[unit] = bdev;
diff --git a/drivers/block/swim3.c b/drivers/block/swim3.c
index e425ad3eebba..af7cb2bfd670 100644
--- a/drivers/block/swim3.c
+++ b/drivers/block/swim3.c
@@ -28,6 +28,7 @@
#include <linux/devfs_fs_kernel.h>
#include <linux/interrupt.h>
#include <linux/module.h>
+#include <linux/spinlock.h>
#include <asm/io.h>
#include <asm/dbdma.h>
#include <asm/prom.h>
@@ -176,6 +177,7 @@ struct swim3 {
struct floppy_state {
enum swim_state state;
+ spinlock_t lock;
struct swim3 __iomem *swim3; /* hardware registers */
struct dbdma_regs __iomem *dma; /* DMA controller registers */
int swim3_intr; /* interrupt number for SWIM3 */
@@ -304,7 +306,6 @@ static void do_fd_request(request_queue_t * q)
#endif /* CONFIG_PMAC_MEDIABAY */
start_request(&floppy_states[i]);
}
- sti();
}
static void start_request(struct floppy_state *fs)
@@ -370,7 +371,7 @@ static void set_timeout(struct floppy_state *fs, int nticks,
{
unsigned long flags;
- save_flags(flags); cli();
+ spin_lock_irqsave(&fs->lock, flags);
if (fs->timeout_pending)
del_timer(&fs->timeout);
fs->timeout.expires = jiffies + nticks;
@@ -378,7 +379,7 @@ static void set_timeout(struct floppy_state *fs, int nticks,
fs->timeout.data = (unsigned long) fs;
add_timer(&fs->timeout);
fs->timeout_pending = 1;
- restore_flags(flags);
+ spin_unlock_irqrestore(&fs->lock, flags);
}
static inline void scan_track(struct floppy_state *fs)
@@ -790,14 +791,13 @@ static int grab_drive(struct floppy_state *fs, enum swim_state state,
{
unsigned long flags;
- save_flags(flags);
- cli();
+ spin_lock_irqsave(&fs->lock, flags);
if (fs->state != idle) {
++fs->wanted;
while (fs->state != available) {
if (interruptible && signal_pending(current)) {
--fs->wanted;
- restore_flags(flags);
+ spin_unlock_irqrestore(&fs->lock, flags);
return -EINTR;
}
interruptible_sleep_on(&fs->wait);
@@ -805,7 +805,7 @@ static int grab_drive(struct floppy_state *fs, enum swim_state state,
--fs->wanted;
}
fs->state = state;
- restore_flags(flags);
+ spin_unlock_irqrestore(&fs->lock, flags);
return 0;
}
@@ -813,11 +813,10 @@ static void release_drive(struct floppy_state *fs)
{
unsigned long flags;
- save_flags(flags);
- cli();
+ spin_lock_irqsave(&fs->lock, flags);
fs->state = idle;
start_request(fs);
- restore_flags(flags);
+ spin_unlock_irqrestore(&fs->lock, flags);
}
static int fd_eject(struct floppy_state *fs)
@@ -1109,6 +1108,7 @@ static int swim3_add_device(struct device_node *swim)
pmac_call_feature(PMAC_FTR_SWIM3_ENABLE, swim, 0, 1);
memset(fs, 0, sizeof(*fs));
+ spin_lock_init(&fs->lock);
fs->state = idle;
fs->swim3 = (struct swim3 __iomem *)
ioremap(swim->addrs[0].address, 0x200);
diff --git a/drivers/block/sx8.c b/drivers/block/sx8.c
index d57007b92f77..1ded3b433459 100644
--- a/drivers/block/sx8.c
+++ b/drivers/block/sx8.c
@@ -1,7 +1,7 @@
/*
* sx8.c: Driver for Promise SATA SX8 looks-like-I2O hardware
*
- * Copyright 2004 Red Hat, Inc.
+ * Copyright 2004-2005 Red Hat, Inc.
*
* Author/maintainer: Jeff Garzik <jgarzik@pobox.com>
*
@@ -31,10 +31,6 @@
#include <asm/semaphore.h>
#include <asm/uaccess.h>
-MODULE_AUTHOR("Jeff Garzik");
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("Promise SATA SX8 block driver");
-
#if 0
#define CARM_DEBUG
#define CARM_VERBOSE_DEBUG
@@ -45,9 +41,35 @@ MODULE_DESCRIPTION("Promise SATA SX8 block driver");
#undef CARM_NDEBUG
#define DRV_NAME "sx8"
-#define DRV_VERSION "0.8"
+#define DRV_VERSION "1.0"
#define PFX DRV_NAME ": "
+MODULE_AUTHOR("Jeff Garzik");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Promise SATA SX8 block driver");
+MODULE_VERSION(DRV_VERSION);
+
+/*
+ * SX8 hardware has a single message queue for all ATA ports.
+ * When this driver was written, the hardware (firmware?) would
+ * corrupt data eventually, if more than one request was outstanding.
+ * As one can imagine, having 8 ports bottlenecking on a single
+ * command hurts performance.
+ *
+ * Based on user reports, later versions of the hardware (firmware?)
+ * seem to be able to survive with more than one command queued.
+ *
+ * Therefore, we default to the safe option -- 1 command -- but
+ * allow the user to increase this.
+ *
+ * SX8 should be able to support up to ~60 queued commands (CARM_MAX_REQ),
+ * but problems seem to occur when you exceed ~30, even on newer hardware.
+ */
+static int max_queue = 1;
+module_param(max_queue, int, 0444);
+MODULE_PARM_DESC(max_queue, "Maximum number of queued commands. (min==1, max==30, safe==1)");
+
+
#define NEXT_RESP(idx) ((idx + 1) % RMSG_Q_LEN)
/* 0xf is just arbitrary, non-zero noise; this is sorta like poisoning */
@@ -90,12 +112,10 @@ enum {
/* command message queue limits */
CARM_MAX_REQ = 64, /* max command msgs per host */
- CARM_MAX_Q = 1, /* one command at a time */
CARM_MSG_LOW_WATER = (CARM_MAX_REQ / 4), /* refill mark */
/* S/G limits, host-wide and per-request */
CARM_MAX_REQ_SG = 32, /* max s/g entries per request */
- CARM_SG_BOUNDARY = 0xffffUL, /* s/g segment boundary */
CARM_MAX_HOST_SG = 600, /* max s/g entries per host */
CARM_SG_LOW_WATER = (CARM_MAX_HOST_SG / 4), /* re-fill mark */
@@ -181,6 +201,10 @@ enum {
FL_DYN_MAJOR = (1 << 17),
};
+enum {
+ CARM_SG_BOUNDARY = 0xffffUL, /* s/g segment boundary */
+};
+
enum scatter_gather_types {
SGT_32BIT = 0,
SGT_64BIT = 1,
@@ -218,7 +242,6 @@ static const char *state_name[] = {
struct carm_port {
unsigned int port_no;
- unsigned int n_queued;
struct gendisk *disk;
struct carm_host *host;
@@ -448,7 +471,7 @@ static inline int carm_lookup_bucket(u32 msg_size)
for (i = 0; i < ARRAY_SIZE(msg_sizes); i++)
if (msg_size <= msg_sizes[i])
return i;
-
+
return -ENOENT;
}
@@ -509,7 +532,7 @@ static struct carm_request *carm_get_request(struct carm_host *host)
if (host->hw_sg_used >= (CARM_MAX_HOST_SG - CARM_MAX_REQ_SG))
return NULL;
- for (i = 0; i < CARM_MAX_Q; i++)
+ for (i = 0; i < max_queue; i++)
if ((host->msg_alloc & (1ULL << i)) == 0) {
struct carm_request *crq = &host->req[i];
crq->port = NULL;
@@ -521,14 +544,14 @@ static struct carm_request *carm_get_request(struct carm_host *host)
assert(host->n_msgs <= CARM_MAX_REQ);
return crq;
}
-
+
DPRINTK("no request available, returning NULL\n");
return NULL;
}
static int carm_put_request(struct carm_host *host, struct carm_request *crq)
{
- assert(crq->tag < CARM_MAX_Q);
+ assert(crq->tag < max_queue);
if (unlikely((host->msg_alloc & (1ULL << crq->tag)) == 0))
return -EINVAL; /* tried to clear a tag that was not active */
@@ -791,7 +814,7 @@ static inline void carm_end_rq(struct carm_host *host, struct carm_request *crq,
int is_ok)
{
carm_end_request_queued(host, crq, is_ok);
- if (CARM_MAX_Q == 1)
+ if (max_queue == 1)
carm_round_robin(host);
else if ((host->n_msgs <= CARM_MSG_LOW_WATER) &&
(host->hw_sg_used <= CARM_SG_LOW_WATER)) {
diff --git a/drivers/block/ub.c b/drivers/block/ub.c
index ed4d5006fe62..bfb23d543ff7 100644
--- a/drivers/block/ub.c
+++ b/drivers/block/ub.c
@@ -1512,7 +1512,7 @@ static void ub_state_sense(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
scmd->nsg = 1;
sg = &scmd->sgv[0];
sg->page = virt_to_page(sc->top_sense);
- sg->offset = (unsigned int)sc->top_sense & (PAGE_SIZE-1);
+ sg->offset = (unsigned long)sc->top_sense & (PAGE_SIZE-1);
sg->length = UB_SENSE_SIZE;
scmd->len = UB_SENSE_SIZE;
scmd->lun = cmd->lun;
@@ -1891,7 +1891,7 @@ static int ub_sync_read_cap(struct ub_dev *sc, struct ub_lun *lun,
cmd->nsg = 1;
sg = &cmd->sgv[0];
sg->page = virt_to_page(p);
- sg->offset = (unsigned int)p & (PAGE_SIZE-1);
+ sg->offset = (unsigned long)p & (PAGE_SIZE-1);
sg->length = 8;
cmd->len = 8;
cmd->lun = lun;
diff --git a/drivers/block/viodasd.c b/drivers/block/viodasd.c
index e46ecd23b3ac..2d518aa2720a 100644
--- a/drivers/block/viodasd.c
+++ b/drivers/block/viodasd.c
@@ -45,10 +45,10 @@
#include <asm/uaccess.h>
#include <asm/vio.h>
-#include <asm/iSeries/HvTypes.h>
-#include <asm/iSeries/HvLpEvent.h>
-#include <asm/iSeries/HvLpConfig.h>
-#include <asm/iSeries/vio.h>
+#include <asm/iseries/hv_types.h>
+#include <asm/iseries/hv_lp_event.h>
+#include <asm/iseries/hv_lp_config.h>
+#include <asm/iseries/vio.h>
MODULE_DESCRIPTION("iSeries Virtual DASD");
MODULE_AUTHOR("Dave Boutcher");
@@ -778,13 +778,16 @@ static struct vio_device_id viodasd_device_table[] __devinitdata = {
{ "viodasd", "" },
{ "", "" }
};
-
MODULE_DEVICE_TABLE(vio, viodasd_device_table);
+
static struct vio_driver viodasd_driver = {
- .name = "viodasd",
.id_table = viodasd_device_table,
.probe = viodasd_probe,
- .remove = viodasd_remove
+ .remove = viodasd_remove,
+ .driver = {
+ .name = "viodasd",
+ .owner = THIS_MODULE,
+ }
};
/*
diff --git a/drivers/bluetooth/Kconfig b/drivers/bluetooth/Kconfig
index 543f93e0f23f..b9fbe6e7f9ae 100644
--- a/drivers/bluetooth/Kconfig
+++ b/drivers/bluetooth/Kconfig
@@ -55,14 +55,6 @@ config BT_HCIUART_BCSP
Say Y here to compile support for HCI BCSP protocol.
-config BT_HCIUART_BCSP_TXCRC
- bool "Transmit CRC with every BCSP packet"
- depends on BT_HCIUART_BCSP
- help
- If you say Y here, a 16-bit CRC checksum will be transmitted along with
- every BCSP (BlueCore Serial Protocol) packet sent to the Bluetooth chip.
- This increases reliability, but slightly reduces efficiency.
-
config BT_HCIBCM203X
tristate "HCI BCM203x USB driver"
depends on USB
diff --git a/drivers/bluetooth/bcm203x.c b/drivers/bluetooth/bcm203x.c
index 5fd3e4cb7525..8e7fb3551775 100644
--- a/drivers/bluetooth/bcm203x.c
+++ b/drivers/bluetooth/bcm203x.c
@@ -179,14 +179,12 @@ static int bcm203x_probe(struct usb_interface *intf, const struct usb_device_id
if (ignore || (intf->cur_altsetting->desc.bInterfaceNumber != 0))
return -ENODEV;
- data = kmalloc(sizeof(*data), GFP_KERNEL);
+ data = kzalloc(sizeof(*data), GFP_KERNEL);
if (!data) {
BT_ERR("Can't allocate memory for data structure");
return -ENOMEM;
}
- memset(data, 0, sizeof(*data));
-
data->udev = udev;
data->state = BCM203X_LOAD_MINIDRV;
diff --git a/drivers/bluetooth/bfusb.c b/drivers/bluetooth/bfusb.c
index 1e9db0156ea7..067e27893e4a 100644
--- a/drivers/bluetooth/bfusb.c
+++ b/drivers/bluetooth/bfusb.c
@@ -673,13 +673,11 @@ static int bfusb_probe(struct usb_interface *intf, const struct usb_device_id *i
}
/* Initialize control structure and load firmware */
- if (!(bfusb = kmalloc(sizeof(struct bfusb), GFP_KERNEL))) {
+ if (!(bfusb = kzalloc(sizeof(struct bfusb), GFP_KERNEL))) {
BT_ERR("Can't allocate memory for control structure");
goto done;
}
- memset(bfusb, 0, sizeof(struct bfusb));
-
bfusb->udev = udev;
bfusb->bulk_in_ep = bulk_in_ep->desc.bEndpointAddress;
bfusb->bulk_out_ep = bulk_out_ep->desc.bEndpointAddress;
diff --git a/drivers/bluetooth/bluecard_cs.c b/drivers/bluetooth/bluecard_cs.c
index 26fe9c0e1d20..f36c563d72c4 100644
--- a/drivers/bluetooth/bluecard_cs.c
+++ b/drivers/bluetooth/bluecard_cs.c
@@ -870,10 +870,9 @@ static dev_link_t *bluecard_attach(void)
int ret;
/* Create new info device */
- info = kmalloc(sizeof(*info), GFP_KERNEL);
+ info = kzalloc(sizeof(*info), GFP_KERNEL);
if (!info)
return NULL;
- memset(info, 0, sizeof(*info));
link = &info->link;
link->priv = info;
diff --git a/drivers/bluetooth/bpa10x.c b/drivers/bluetooth/bpa10x.c
index 4fa85234d8b5..394796315adc 100644
--- a/drivers/bluetooth/bpa10x.c
+++ b/drivers/bluetooth/bpa10x.c
@@ -84,8 +84,8 @@ struct bpa10x_data {
struct hci_vendor_hdr {
__u8 type;
- __u16 snum;
- __u16 dlen;
+ __le16 snum;
+ __le16 dlen;
} __attribute__ ((packed));
static void bpa10x_recv_bulk(struct bpa10x_data *data, unsigned char *buf, int count)
@@ -550,14 +550,15 @@ static int bpa10x_probe(struct usb_interface *intf, const struct usb_device_id *
if (ignore)
return -ENODEV;
- data = kmalloc(sizeof(*data), GFP_KERNEL);
+ if (intf->cur_altsetting->desc.bInterfaceNumber > 0)
+ return -ENODEV;
+
+ data = kzalloc(sizeof(*data), GFP_KERNEL);
if (!data) {
BT_ERR("Can't allocate data structure");
return -ENOMEM;
}
- memset(data, 0, sizeof(*data));
-
data->udev = udev;
rwlock_init(&data->lock);
diff --git a/drivers/bluetooth/bt3c_cs.c b/drivers/bluetooth/bt3c_cs.c
index 2e0338d80f32..d2a0add19cc8 100644
--- a/drivers/bluetooth/bt3c_cs.c
+++ b/drivers/bluetooth/bt3c_cs.c
@@ -671,10 +671,9 @@ static dev_link_t *bt3c_attach(void)
int ret;
/* Create new info device */
- info = kmalloc(sizeof(*info), GFP_KERNEL);
+ info = kzalloc(sizeof(*info), GFP_KERNEL);
if (!info)
return NULL;
- memset(info, 0, sizeof(*info));
link = &info->link;
link->priv = info;
diff --git a/drivers/bluetooth/btuart_cs.c b/drivers/bluetooth/btuart_cs.c
index 89486ea7a021..529a28a3209d 100644
--- a/drivers/bluetooth/btuart_cs.c
+++ b/drivers/bluetooth/btuart_cs.c
@@ -590,10 +590,9 @@ static dev_link_t *btuart_attach(void)
int ret;
/* Create new info device */
- info = kmalloc(sizeof(*info), GFP_KERNEL);
+ info = kzalloc(sizeof(*info), GFP_KERNEL);
if (!info)
return NULL;
- memset(info, 0, sizeof(*info));
link = &info->link;
link->priv = info;
diff --git a/drivers/bluetooth/dtl1_cs.c b/drivers/bluetooth/dtl1_cs.c
index 84c1f8839422..dec5980a1cd6 100644
--- a/drivers/bluetooth/dtl1_cs.c
+++ b/drivers/bluetooth/dtl1_cs.c
@@ -569,10 +569,9 @@ static dev_link_t *dtl1_attach(void)
int ret;
/* Create new info device */
- info = kmalloc(sizeof(*info), GFP_KERNEL);
+ info = kzalloc(sizeof(*info), GFP_KERNEL);
if (!info)
return NULL;
- memset(info, 0, sizeof(*info));
link = &info->link;
link->priv = info;
diff --git a/drivers/bluetooth/hci_bcsp.c b/drivers/bluetooth/hci_bcsp.c
index 0ee324e1265d..8fddfdfd0fbd 100644
--- a/drivers/bluetooth/hci_bcsp.c
+++ b/drivers/bluetooth/hci_bcsp.c
@@ -1,35 +1,27 @@
-/*
- BlueCore Serial Protocol (BCSP) for Linux Bluetooth stack (BlueZ).
- Copyright 2002 by Fabrizio Gennari <fabrizio.gennari@philips.com>
-
- Based on
- hci_h4.c by Maxim Krasnyansky <maxk@qualcomm.com>
- ABCSP by Carl Orsborn <cjo@csr.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;
-
- 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 OF THIRD PARTY RIGHTS.
- IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
- CLAIM, OR ANY SPECIAL 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.
-
- ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
- COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
- SOFTWARE IS DISCLAIMED.
-*/
-
/*
- * $Id: hci_bcsp.c,v 1.2 2002/09/26 05:05:14 maxk Exp $
+ *
+ * Bluetooth HCI UART driver
+ *
+ * Copyright (C) 2002-2003 Fabrizio Gennari <fabrizio.gennari@philips.com>
+ * Copyright (C) 2004-2005 Marcel Holtmann <marcel@holtmann.org>
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
*/
-#define VERSION "0.2"
-
#include <linux/config.h>
#include <linux/module.h>
@@ -52,16 +44,56 @@
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>
+
#include "hci_uart.h"
-#include "hci_bcsp.h"
#ifndef CONFIG_BT_HCIUART_DEBUG
#undef BT_DBG
#define BT_DBG( A... )
#endif
+#define VERSION "0.3"
+
+static int txcrc = 1;
static int hciextn = 1;
+#define BCSP_TXWINSIZE 4
+
+#define BCSP_ACK_PKT 0x05
+#define BCSP_LE_PKT 0x06
+
+struct bcsp_struct {
+ struct sk_buff_head unack; /* Unack'ed packets queue */
+ struct sk_buff_head rel; /* Reliable packets queue */
+ struct sk_buff_head unrel; /* Unreliable packets queue */
+
+ unsigned long rx_count;
+ struct sk_buff *rx_skb;
+ u8 rxseq_txack; /* rxseq == txack. */
+ u8 rxack; /* Last packet sent by us that the peer ack'ed */
+ struct timer_list tbcsp;
+
+ enum {
+ BCSP_W4_PKT_DELIMITER,
+ BCSP_W4_PKT_START,
+ BCSP_W4_BCSP_HDR,
+ BCSP_W4_DATA,
+ BCSP_W4_CRC
+ } rx_state;
+
+ enum {
+ BCSP_ESCSTATE_NOESC,
+ BCSP_ESCSTATE_ESC
+ } rx_esc_state;
+
+ u8 use_crc;
+ u16 message_crc;
+ u8 txack_req; /* Do we need to send ack's to the peer? */
+
+ /* Reliable packet sequence number - used to assign seq to each rel pkt. */
+ u8 msgq_txseq;
+};
+
/* ---- BCSP CRC calculation ---- */
/* Table for calculating CRC for polynomial 0x1021, LSB processed first,
@@ -111,6 +143,7 @@ static u16 bcsp_crc_reverse(u16 crc)
rev |= (crc & 1);
crc = crc >> 1;
}
+
return (rev);
}
@@ -119,6 +152,7 @@ static u16 bcsp_crc_reverse(u16 crc)
static void bcsp_slip_msgdelim(struct sk_buff *skb)
{
const char pkt_delim = 0xc0;
+
memcpy(skb_put(skb, 1), &pkt_delim, 1);
}
@@ -173,11 +207,8 @@ static struct sk_buff *bcsp_prepare_pkt(struct bcsp_struct *bcsp, u8 *data,
{
struct sk_buff *nskb;
u8 hdr[4], chan;
- int rel, i;
-
-#ifdef CONFIG_BT_HCIUART_BCSP_TXCRC
u16 BCSP_CRC_INIT(bcsp_txmsg_crc);
-#endif
+ int rel, i;
switch (pkt_type) {
case HCI_ACLDATA_PKT:
@@ -240,9 +271,9 @@ static struct sk_buff *bcsp_prepare_pkt(struct bcsp_struct *bcsp, u8 *data,
BT_DBG("Sending packet with seqno %u", bcsp->msgq_txseq);
bcsp->msgq_txseq = ++(bcsp->msgq_txseq) & 0x07;
}
-#ifdef CONFIG_BT_HCIUART_BCSP_TXCRC
- hdr[0] |= 0x40;
-#endif
+
+ if (bcsp->use_crc)
+ hdr[0] |= 0x40;
hdr[1] = ((len << 4) & 0xff) | chan;
hdr[2] = len >> 4;
@@ -251,25 +282,25 @@ static struct sk_buff *bcsp_prepare_pkt(struct bcsp_struct *bcsp, u8 *data,
/* Put BCSP header */
for (i = 0; i < 4; i++) {
bcsp_slip_one_byte(nskb, hdr[i]);
-#ifdef CONFIG_BT_HCIUART_BCSP_TXCRC
- bcsp_crc_update(&bcsp_txmsg_crc, hdr[i]);
-#endif
+
+ if (bcsp->use_crc)
+ bcsp_crc_update(&bcsp_txmsg_crc, hdr[i]);
}
/* Put payload */
for (i = 0; i < len; i++) {
bcsp_slip_one_byte(nskb, data[i]);
-#ifdef CONFIG_BT_HCIUART_BCSP_TXCRC
- bcsp_crc_update(&bcsp_txmsg_crc, data[i]);
-#endif
+
+ if (bcsp->use_crc)
+ bcsp_crc_update(&bcsp_txmsg_crc, data[i]);
}
-#ifdef CONFIG_BT_HCIUART_BCSP_TXCRC
/* Put CRC */
- bcsp_txmsg_crc = bcsp_crc_reverse(bcsp_txmsg_crc);
- bcsp_slip_one_byte(nskb, (u8) ((bcsp_txmsg_crc >> 8) & 0x00ff));
- bcsp_slip_one_byte(nskb, (u8) (bcsp_txmsg_crc & 0x00ff));
-#endif
+ if (bcsp->use_crc) {
+ bcsp_txmsg_crc = bcsp_crc_reverse(bcsp_txmsg_crc);
+ bcsp_slip_one_byte(nskb, (u8) ((bcsp_txmsg_crc >> 8) & 0x00ff));
+ bcsp_slip_one_byte(nskb, (u8) (bcsp_txmsg_crc & 0x00ff));
+ }
bcsp_slip_msgdelim(nskb);
return nskb;
@@ -317,7 +348,6 @@ static struct sk_buff *bcsp_dequeue(struct hci_uart *hu)
spin_unlock_irqrestore(&bcsp->unack.lock, flags);
-
/* We could not send a reliable packet, either because there are
none or because there are too many unack'ed pkts. Did we receive
any packets we have not acknowledged yet ? */
@@ -363,7 +393,7 @@ static void bcsp_pkt_cull(struct bcsp_struct *bcsp)
BT_ERR("Peer acked invalid packet");
BT_DBG("Removing %u pkts out of %u, up to seqno %u",
- pkts_to_be_removed, bcsp->unack.qlen, (seqno - 1) & 0x07);
+ pkts_to_be_removed, bcsp->unack.qlen, (seqno - 1) & 0x07);
for (i = 0, skb = ((struct sk_buff *) &bcsp->unack)->next; i < pkts_to_be_removed
&& skb != (struct sk_buff *) &bcsp->unack; i++) {
@@ -374,8 +404,10 @@ static void bcsp_pkt_cull(struct bcsp_struct *bcsp)
kfree_skb(skb);
skb = nskb;
}
+
if (bcsp->unack.qlen == 0)
del_timer(&bcsp->tbcsp);
+
spin_unlock_irqrestore(&bcsp->unack.lock, flags);
if (i != pkts_to_be_removed)
@@ -530,6 +562,7 @@ static inline void bcsp_complete_rx_pkt(struct hci_uart *hu)
hci_recv_frame(bcsp->rx_skb);
}
+
bcsp->rx_state = BCSP_W4_PKT_DELIMITER;
bcsp->rx_skb = NULL;
}
@@ -598,8 +631,8 @@ static int bcsp_recv(struct hci_uart *hu, void *data, int count)
BT_ERR ("Checksum failed: computed %04x received %04x",
bcsp_crc_reverse(bcsp->message_crc),
- (bcsp->rx_skb-> data[bcsp->rx_skb->len - 2] << 8) +
- bcsp->rx_skb->data[bcsp->rx_skb->len - 1]);
+ (bcsp->rx_skb-> data[bcsp->rx_skb->len - 2] << 8) +
+ bcsp->rx_skb->data[bcsp->rx_skb->len - 1]);
kfree_skb(bcsp->rx_skb);
bcsp->rx_state = BCSP_W4_PKT_DELIMITER;
@@ -633,7 +666,7 @@ static int bcsp_recv(struct hci_uart *hu, void *data, int count)
bcsp->rx_count = 4;
bcsp->rx_esc_state = BCSP_ESCSTATE_NOESC;
BCSP_CRC_INIT(bcsp->message_crc);
-
+
/* Do not increment ptr or decrement count
* Allocate packet. Max len of a BCSP pkt=
* 0xFFF (payload) +4 (header) +2 (crc) */
@@ -682,10 +715,9 @@ static int bcsp_open(struct hci_uart *hu)
BT_DBG("hu %p", hu);
- bcsp = kmalloc(sizeof(*bcsp), GFP_ATOMIC);
+ bcsp = kzalloc(sizeof(*bcsp), GFP_ATOMIC);
if (!bcsp)
return -ENOMEM;
- memset(bcsp, 0, sizeof(*bcsp));
hu->priv = bcsp;
skb_queue_head_init(&bcsp->unack);
@@ -698,6 +730,9 @@ static int bcsp_open(struct hci_uart *hu)
bcsp->rx_state = BCSP_W4_PKT_DELIMITER;
+ if (txcrc)
+ bcsp->use_crc = 1;
+
return 0;
}
@@ -718,18 +753,19 @@ static int bcsp_close(struct hci_uart *hu)
}
static struct hci_uart_proto bcsp = {
- .id = HCI_UART_BCSP,
- .open = bcsp_open,
- .close = bcsp_close,
- .enqueue = bcsp_enqueue,
- .dequeue = bcsp_dequeue,
- .recv = bcsp_recv,
- .flush = bcsp_flush
+ .id = HCI_UART_BCSP,
+ .open = bcsp_open,
+ .close = bcsp_close,
+ .enqueue = bcsp_enqueue,
+ .dequeue = bcsp_dequeue,
+ .recv = bcsp_recv,
+ .flush = bcsp_flush
};
int bcsp_init(void)
{
int err = hci_uart_register_proto(&bcsp);
+
if (!err)
BT_INFO("HCI BCSP protocol initialized");
else
@@ -743,5 +779,8 @@ int bcsp_deinit(void)
return hci_uart_unregister_proto(&bcsp);
}
+module_param(txcrc, bool, 0644);
+MODULE_PARM_DESC(txcrc, "Transmit CRC with every BCSP packet");
+
module_param(hciextn, bool, 0644);
MODULE_PARM_DESC(hciextn, "Convert HCI Extensions into BCSP packets");
diff --git a/drivers/bluetooth/hci_bcsp.h b/drivers/bluetooth/hci_bcsp.h
deleted file mode 100644
index a2b3bb92274b..000000000000
--- a/drivers/bluetooth/hci_bcsp.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- BlueCore Serial Protocol (BCSP) for Linux Bluetooth stack (BlueZ).
- Copyright 2002 by Fabrizio Gennari <fabrizio.gennari@philips.com>
-
- Based on
- hci_h4.c by Maxim Krasnyansky <maxk@qualcomm.com>
- ABCSP by Carl Orsborn <cjo@csr.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;
-
- 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 OF THIRD PARTY RIGHTS.
- IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
- CLAIM, OR ANY SPECIAL 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.
-
- ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
- COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
- SOFTWARE IS DISCLAIMED.
-*/
-
-/*
- * $Id: hci_bcsp.h,v 1.2 2002/09/26 05:05:14 maxk Exp $
- */
-
-#ifndef __HCI_BCSP_H__
-#define __HCI_BCSP_H__
-
-#define BCSP_TXWINSIZE 4
-
-#define BCSP_ACK_PKT 0x05
-#define BCSP_LE_PKT 0x06
-
-struct bcsp_struct {
- struct sk_buff_head unack; /* Unack'ed packets queue */
- struct sk_buff_head rel; /* Reliable packets queue */
- struct sk_buff_head unrel; /* Unreliable packets queue */
-
- unsigned long rx_count;
- struct sk_buff *rx_skb;
- u8 rxseq_txack; /* rxseq == txack. */
- u8 rxack; /* Last packet sent by us that the peer ack'ed */
- struct timer_list tbcsp;
-
- enum {
- BCSP_W4_PKT_DELIMITER,
- BCSP_W4_PKT_START,
- BCSP_W4_BCSP_HDR,
- BCSP_W4_DATA,
- BCSP_W4_CRC
- } rx_state;
-
- enum {
- BCSP_ESCSTATE_NOESC,
- BCSP_ESCSTATE_ESC
- } rx_esc_state;
-
- u16 message_crc;
- u8 txack_req; /* Do we need to send ack's to the peer? */
-
- /* Reliable packet sequence number - used to assign seq to each rel pkt. */
- u8 msgq_txseq;
-};
-
-#endif /* __HCI_BCSP_H__ */
diff --git a/drivers/bluetooth/hci_h4.c b/drivers/bluetooth/hci_h4.c
index cf8a22d58d96..4804d474dc87 100644
--- a/drivers/bluetooth/hci_h4.c
+++ b/drivers/bluetooth/hci_h4.c
@@ -1,33 +1,27 @@
-/*
- BlueZ - Bluetooth protocol stack for Linux
- Copyright (C) 2000-2001 Qualcomm Incorporated
-
- Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.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;
-
- 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 OF THIRD PARTY RIGHTS.
- IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
- CLAIM, OR ANY SPECIAL 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.
-
- ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
- COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
- SOFTWARE IS DISCLAIMED.
-*/
-
/*
- * Bluetooth HCI UART(H4) protocol.
*
- * $Id: hci_h4.c,v 1.3 2002/09/09 01:17:32 maxk Exp $
+ * Bluetooth HCI UART driver
+ *
+ * Copyright (C) 2000-2001 Qualcomm Incorporated
+ * Copyright (C) 2002-2003 Maxim Krasnyansky <maxk@qualcomm.com>
+ * Copyright (C) 2004-2005 Marcel Holtmann <marcel@holtmann.org>
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
*/
-#define VERSION "1.2"
#include <linux/config.h>
#include <linux/module.h>
@@ -51,25 +45,40 @@
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>
+
#include "hci_uart.h"
-#include "hci_h4.h"
#ifndef CONFIG_BT_HCIUART_DEBUG
#undef BT_DBG
#define BT_DBG( A... )
#endif
+#define VERSION "1.2"
+
+struct h4_struct {
+ unsigned long rx_state;
+ unsigned long rx_count;
+ struct sk_buff *rx_skb;
+ struct sk_buff_head txq;
+};
+
+/* H4 receiver States */
+#define H4_W4_PACKET_TYPE 0
+#define H4_W4_EVENT_HDR 1
+#define H4_W4_ACL_HDR 2
+#define H4_W4_SCO_HDR 3
+#define H4_W4_DATA 4
+
/* Initialize protocol */
static int h4_open(struct hci_uart *hu)
{
struct h4_struct *h4;
-
+
BT_DBG("hu %p", hu);
-
- h4 = kmalloc(sizeof(*h4), GFP_ATOMIC);
+
+ h4 = kzalloc(sizeof(*h4), GFP_ATOMIC);
if (!h4)
return -ENOMEM;
- memset(h4, 0, sizeof(*h4));
skb_queue_head_init(&h4->txq);
@@ -83,7 +92,9 @@ static int h4_flush(struct hci_uart *hu)
struct h4_struct *h4 = hu->priv;
BT_DBG("hu %p", hu);
+
skb_queue_purge(&h4->txq);
+
return 0;
}
@@ -91,16 +102,19 @@ static int h4_flush(struct hci_uart *hu)
static int h4_close(struct hci_uart *hu)
{
struct h4_struct *h4 = hu->priv;
+
hu->priv = NULL;
BT_DBG("hu %p", hu);
skb_queue_purge(&h4->txq);
+
if (h4->rx_skb)
kfree_skb(h4->rx_skb);
hu->priv = NULL;
kfree(h4);
+
return 0;
}
@@ -114,6 +128,7 @@ static int h4_enqueue(struct hci_uart *hu, struct sk_buff *skb)
/* Prepend skb with frame type */
memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1);
skb_queue_tail(&h4->txq, skb);
+
return 0;
}
@@ -122,6 +137,7 @@ static inline int h4_check_data_len(struct h4_struct *h4, int len)
register int room = skb_tailroom(h4->rx_skb);
BT_DBG("len %d room %d", len, room);
+
if (!len) {
hci_recv_frame(h4->rx_skb);
} else if (len > room) {
@@ -136,6 +152,7 @@ static inline int h4_check_data_len(struct h4_struct *h4, int len)
h4->rx_state = H4_W4_PACKET_TYPE;
h4->rx_skb = NULL;
h4->rx_count = 0;
+
return 0;
}
@@ -228,6 +245,7 @@ static int h4_recv(struct hci_uart *hu, void *data, int count)
ptr++; count--;
continue;
};
+
ptr++; count--;
/* Allocate packet */
@@ -238,9 +256,11 @@ static int h4_recv(struct hci_uart *hu, void *data, int count)
h4->rx_count = 0;
return 0;
}
+
h4->rx_skb->dev = (void *) hu->hdev;
bt_cb(h4->rx_skb)->pkt_type = type;
}
+
return count;
}
@@ -251,23 +271,24 @@ static struct sk_buff *h4_dequeue(struct hci_uart *hu)
}
static struct hci_uart_proto h4p = {
- .id = HCI_UART_H4,
- .open = h4_open,
- .close = h4_close,
- .recv = h4_recv,
- .enqueue = h4_enqueue,
- .dequeue = h4_dequeue,
- .flush = h4_flush,
+ .id = HCI_UART_H4,
+ .open = h4_open,
+ .close = h4_close,
+ .recv = h4_recv,
+ .enqueue = h4_enqueue,
+ .dequeue = h4_dequeue,
+ .flush = h4_flush,
};
-
+
int h4_init(void)
{
int err = hci_uart_register_proto(&h4p);
+
if (!err)
BT_INFO("HCI H4 protocol initialized");
else
BT_ERR("HCI H4 protocol registration failed");
-
+
return err;
}
diff --git a/drivers/bluetooth/hci_h4.h b/drivers/bluetooth/hci_h4.h
deleted file mode 100644
index b95ff54bfd47..000000000000
--- a/drivers/bluetooth/hci_h4.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- BlueZ - Bluetooth protocol stack for Linux
- Copyright (C) 2000-2001 Qualcomm Incorporated
-
- Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.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;
-
- 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 OF THIRD PARTY RIGHTS.
- IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
- CLAIM, OR ANY SPECIAL 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.
-
- ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
- COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
- SOFTWARE IS DISCLAIMED.
-*/
-
-/*
- * $Id: hci_h4.h,v 1.2 2002/09/09 01:17:32 maxk Exp $
- */
-
-#ifdef __KERNEL__
-struct h4_struct {
- unsigned long rx_state;
- unsigned long rx_count;
- struct sk_buff *rx_skb;
- struct sk_buff_head txq;
-};
-
-/* H4 receiver States */
-#define H4_W4_PACKET_TYPE 0
-#define H4_W4_EVENT_HDR 1
-#define H4_W4_ACL_HDR 2
-#define H4_W4_SCO_HDR 3
-#define H4_W4_DATA 4
-
-#endif /* __KERNEL__ */
diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c
index aed80cc22890..573ff6c1be5f 100644
--- a/drivers/bluetooth/hci_ldisc.c
+++ b/drivers/bluetooth/hci_ldisc.c
@@ -1,33 +1,27 @@
-/*
- BlueZ - Bluetooth protocol stack for Linux
- Copyright (C) 2000-2001 Qualcomm Incorporated
-
- Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.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;
-
- 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 OF THIRD PARTY RIGHTS.
- IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
- CLAIM, OR ANY SPECIAL 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.
-
- ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
- COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
- SOFTWARE IS DISCLAIMED.
-*/
-
/*
- * Bluetooth HCI UART driver.
*
- * $Id: hci_ldisc.c,v 1.5 2002/10/02 18:37:20 maxk Exp $
+ * Bluetooth HCI UART driver
+ *
+ * Copyright (C) 2000-2001 Qualcomm Incorporated
+ * Copyright (C) 2002-2003 Maxim Krasnyansky <maxk@qualcomm.com>
+ * Copyright (C) 2004-2005 Marcel Holtmann <marcel@holtmann.org>
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
*/
-#define VERSION "2.1"
#include <linux/config.h>
#include <linux/module.h>
@@ -59,6 +53,8 @@
#define BT_DBG( A... )
#endif
+#define VERSION "2.2"
+
static int reset = 0;
static struct hci_uart_proto *hup[HCI_UART_MAX_PROTO];
@@ -72,6 +68,7 @@ int hci_uart_register_proto(struct hci_uart_proto *p)
return -EEXIST;
hup[p->id] = p;
+
return 0;
}
@@ -84,6 +81,7 @@ int hci_uart_unregister_proto(struct hci_uart_proto *p)
return -EINVAL;
hup[p->id] = NULL;
+
return 0;
}
@@ -91,13 +89,14 @@ static struct hci_uart_proto *hci_uart_get_proto(unsigned int id)
{
if (id >= HCI_UART_MAX_PROTO)
return NULL;
+
return hup[id];
}
static inline void hci_uart_tx_complete(struct hci_uart *hu, int pkt_type)
{
struct hci_dev *hdev = hu->hdev;
-
+
/* Update HCI stat counters */
switch (pkt_type) {
case HCI_COMMAND_PKT:
@@ -117,10 +116,12 @@ static inline void hci_uart_tx_complete(struct hci_uart *hu, int pkt_type)
static inline struct sk_buff *hci_uart_dequeue(struct hci_uart *hu)
{
struct sk_buff *skb = hu->tx_skb;
+
if (!skb)
skb = hu->proto->dequeue(hu);
else
hu->tx_skb = NULL;
+
return skb;
}
@@ -129,7 +130,7 @@ int hci_uart_tx_wakeup(struct hci_uart *hu)
struct tty_struct *tty = hu->tty;
struct hci_dev *hdev = hu->hdev;
struct sk_buff *skb;
-
+
if (test_and_set_bit(HCI_UART_SENDING, &hu->tx_state)) {
set_bit(HCI_UART_TX_WAKEUP, &hu->tx_state);
return 0;
@@ -142,7 +143,7 @@ restart:
while ((skb = hci_uart_dequeue(hu))) {
int len;
-
+
set_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
len = tty->driver->write(tty, skb->data, skb->len);
hdev->stat.byte_tx += len;
@@ -152,11 +153,11 @@ restart:
hu->tx_skb = skb;
break;
}
-
+
hci_uart_tx_complete(hu, bt_cb(skb)->pkt_type);
kfree_skb(skb);
- }
-
+ }
+
if (test_bit(HCI_UART_TX_WAKEUP, &hu->tx_state))
goto restart;
@@ -173,6 +174,7 @@ static int hci_uart_open(struct hci_dev *hdev)
/* Nothing to do for UART driver */
set_bit(HCI_RUNNING, &hdev->flags);
+
return 0;
}
@@ -234,6 +236,7 @@ static int hci_uart_send_frame(struct sk_buff *skb)
hu->proto->enqueue(hu, skb);
hci_uart_tx_wakeup(hu);
+
return 0;
}
@@ -241,7 +244,8 @@ static void hci_uart_destruct(struct hci_dev *hdev)
{
struct hci_uart *hu;
- if (!hdev) return;
+ if (!hdev)
+ return;
BT_DBG("%s", hdev->name);
@@ -268,11 +272,10 @@ static int hci_uart_tty_open(struct tty_struct *tty)
if (hu)
return -EEXIST;
- if (!(hu = kmalloc(sizeof(struct hci_uart), GFP_KERNEL))) {
+ if (!(hu = kzalloc(sizeof(struct hci_uart), GFP_KERNEL))) {
BT_ERR("Can't allocate controll structure");
return -ENFILE;
}
- memset(hu, 0, sizeof(struct hci_uart));
tty->disc_data = hu;
hu->tty = tty;
@@ -280,8 +283,10 @@ static int hci_uart_tty_open(struct tty_struct *tty)
spin_lock_init(&hu->rx_lock);
/* Flush any pending characters in the driver and line discipline. */
+
/* FIXME: why is this needed. Note don't use ldisc_ref here as the
open path is before the ldisc is referencable */
+
if (tty->ldisc.flush_buffer)
tty->ldisc.flush_buffer(tty);
@@ -372,13 +377,13 @@ static int hci_uart_tty_room (struct tty_struct *tty)
static void hci_uart_tty_receive(struct tty_struct *tty, const __u8 *data, char *flags, int count)
{
struct hci_uart *hu = (void *)tty->disc_data;
-
+
if (!hu || tty != hu->tty)
return;
if (!test_bit(HCI_UART_PROTO_SET, &hu->flags))
return;
-
+
spin_lock(&hu->rx_lock);
hu->proto->recv(hu, (void *) data, count);
hu->hdev->stat.byte_rx += count;
@@ -429,8 +434,8 @@ static int hci_uart_register_dev(struct hci_uart *hu)
static int hci_uart_set_proto(struct hci_uart *hu, int id)
{
struct hci_uart_proto *p;
- int err;
-
+ int err;
+
p = hci_uart_get_proto(id);
if (!p)
return -EPROTONOSUPPORT;
@@ -446,6 +451,7 @@ static int hci_uart_set_proto(struct hci_uart *hu, int id)
p->close(hu);
return err;
}
+
return 0;
}
@@ -463,7 +469,7 @@ static int hci_uart_set_proto(struct hci_uart *hu, int id)
* Return Value: Command dependent
*/
static int hci_uart_tty_ioctl(struct tty_struct *tty, struct file * file,
- unsigned int cmd, unsigned long arg)
+ unsigned int cmd, unsigned long arg)
{
struct hci_uart *hu = (void *)tty->disc_data;
int err = 0;
@@ -483,14 +489,14 @@ static int hci_uart_tty_ioctl(struct tty_struct *tty, struct file * file,
return err;
}
tty->low_latency = 1;
- } else
+ } else
return -EBUSY;
case HCIUARTGETPROTO:
if (test_bit(HCI_UART_PROTO_SET, &hu->flags))
return hu->proto->id;
return -EUNATCH;
-
+
default:
err = n_tty_ioctl(tty, file, cmd, arg);
break;
@@ -502,28 +508,24 @@ static int hci_uart_tty_ioctl(struct tty_struct *tty, struct file * file,
/*
* We don't provide read/write/poll interface for user space.
*/
-static ssize_t hci_uart_tty_read(struct tty_struct *tty, struct file *file, unsigned char __user *buf, size_t nr)
+static ssize_t hci_uart_tty_read(struct tty_struct *tty, struct file *file,
+ unsigned char __user *buf, size_t nr)
{
return 0;
}
-static ssize_t hci_uart_tty_write(struct tty_struct *tty, struct file *file, const unsigned char *data, size_t count)
+
+static ssize_t hci_uart_tty_write(struct tty_struct *tty, struct file *file,
+ const unsigned char *data, size_t count)
{
return 0;
}
-static unsigned int hci_uart_tty_poll(struct tty_struct *tty, struct file *filp, poll_table *wait)
+
+static unsigned int hci_uart_tty_poll(struct tty_struct *tty,
+ struct file *filp, poll_table *wait)
{
return 0;
}
-#ifdef CONFIG_BT_HCIUART_H4
-int h4_init(void);
-int h4_deinit(void);
-#endif
-#ifdef CONFIG_BT_HCIUART_BCSP
-int bcsp_init(void);
-int bcsp_deinit(void);
-#endif
-
static int __init hci_uart_init(void)
{
static struct tty_ldisc hci_uart_ldisc;
@@ -534,18 +536,18 @@ static int __init hci_uart_init(void)
/* Register the tty discipline */
memset(&hci_uart_ldisc, 0, sizeof (hci_uart_ldisc));
- hci_uart_ldisc.magic = TTY_LDISC_MAGIC;
- hci_uart_ldisc.name = "n_hci";
- hci_uart_ldisc.open = hci_uart_tty_open;
- hci_uart_ldisc.close = hci_uart_tty_close;
- hci_uart_ldisc.read = hci_uart_tty_read;
- hci_uart_ldisc.write = hci_uart_tty_write;
- hci_uart_ldisc.ioctl = hci_uart_tty_ioctl;
- hci_uart_ldisc.poll = hci_uart_tty_poll;
- hci_uart_ldisc.receive_room= hci_uart_tty_room;
- hci_uart_ldisc.receive_buf = hci_uart_tty_receive;
- hci_uart_ldisc.write_wakeup= hci_uart_tty_wakeup;
- hci_uart_ldisc.owner = THIS_MODULE;
+ hci_uart_ldisc.magic = TTY_LDISC_MAGIC;
+ hci_uart_ldisc.name = "n_hci";
+ hci_uart_ldisc.open = hci_uart_tty_open;
+ hci_uart_ldisc.close = hci_uart_tty_close;
+ hci_uart_ldisc.read = hci_uart_tty_read;
+ hci_uart_ldisc.write = hci_uart_tty_write;
+ hci_uart_ldisc.ioctl = hci_uart_tty_ioctl;
+ hci_uart_ldisc.poll = hci_uart_tty_poll;
+ hci_uart_ldisc.receive_room = hci_uart_tty_room;
+ hci_uart_ldisc.receive_buf = hci_uart_tty_receive;
+ hci_uart_ldisc.write_wakeup = hci_uart_tty_wakeup;
+ hci_uart_ldisc.owner = THIS_MODULE;
if ((err = tty_register_ldisc(N_HCI, &hci_uart_ldisc))) {
BT_ERR("HCI line discipline registration failed. (%d)", err);
diff --git a/drivers/bluetooth/hci_uart.h b/drivers/bluetooth/hci_uart.h
index 0a57d72790ec..b250e6789dee 100644
--- a/drivers/bluetooth/hci_uart.h
+++ b/drivers/bluetooth/hci_uart.h
@@ -1,32 +1,29 @@
-/*
- BlueZ - Bluetooth protocol stack for Linux
- Copyright (C) 2000-2001 Qualcomm Incorporated
-
- Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.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;
-
- 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 OF THIRD PARTY RIGHTS.
- IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
- CLAIM, OR ANY SPECIAL 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.
-
- ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
- COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
- SOFTWARE IS DISCLAIMED.
-*/
-
/*
- * $Id: hci_uart.h,v 1.2 2002/09/09 01:17:32 maxk Exp $
+ *
+ * Bluetooth HCI UART driver
+ *
+ * Copyright (C) 2000-2001 Qualcomm Incorporated
+ * Copyright (C) 2002-2003 Maxim Krasnyansky <maxk@qualcomm.com>
+ * Copyright (C) 2004-2005 Marcel Holtmann <marcel@holtmann.org>
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
*/
-#ifndef N_HCI
+#ifndef N_HCI
#define N_HCI 15
#endif
@@ -42,7 +39,6 @@
#define HCI_UART_3WIRE 2
#define HCI_UART_H4DS 3
-#ifdef __KERNEL__
struct hci_uart;
struct hci_uart_proto {
@@ -56,27 +52,35 @@ struct hci_uart_proto {
};
struct hci_uart {
- struct tty_struct *tty;
- struct hci_dev *hdev;
- unsigned long flags;
+ struct tty_struct *tty;
+ struct hci_dev *hdev;
+ unsigned long flags;
- struct hci_uart_proto *proto;
- void *priv;
-
- struct sk_buff *tx_skb;
- unsigned long tx_state;
- spinlock_t rx_lock;
+ struct hci_uart_proto *proto;
+ void *priv;
+
+ struct sk_buff *tx_skb;
+ unsigned long tx_state;
+ spinlock_t rx_lock;
};
/* HCI_UART flag bits */
-#define HCI_UART_PROTO_SET 0
+#define HCI_UART_PROTO_SET 0
/* TX states */
-#define HCI_UART_SENDING 1
-#define HCI_UART_TX_WAKEUP 2
+#define HCI_UART_SENDING 1
+#define HCI_UART_TX_WAKEUP 2
int hci_uart_register_proto(struct hci_uart_proto *p);
int hci_uart_unregister_proto(struct hci_uart_proto *p);
int hci_uart_tx_wakeup(struct hci_uart *hu);
-#endif /* __KERNEL__ */
+#ifdef CONFIG_BT_HCIUART_H4
+int h4_init(void);
+int h4_deinit(void);
+#endif
+
+#ifdef CONFIG_BT_HCIUART_BCSP
+int bcsp_init(void);
+int bcsp_deinit(void);
+#endif
diff --git a/drivers/bluetooth/hci_usb.c b/drivers/bluetooth/hci_usb.c
index 6756cb20b753..057cb2b6e6d1 100644
--- a/drivers/bluetooth/hci_usb.c
+++ b/drivers/bluetooth/hci_usb.c
@@ -65,6 +65,7 @@
#endif
static int ignore = 0;
+static int ignore_dga = 0;
static int ignore_csr = 0;
static int ignore_sniffer = 0;
static int reset = 0;
@@ -841,6 +842,9 @@ static int hci_usb_probe(struct usb_interface *intf, const struct usb_device_id
if (ignore || id->driver_info & HCI_IGNORE)
return -ENODEV;
+ if (ignore_dga && id->driver_info & HCI_DIGIANSWER)
+ return -ENODEV;
+
if (ignore_csr && id->driver_info & HCI_CSR)
return -ENODEV;
@@ -875,13 +879,11 @@ static int hci_usb_probe(struct usb_interface *intf, const struct usb_device_id
goto done;
}
- if (!(husb = kmalloc(sizeof(struct hci_usb), GFP_KERNEL))) {
+ if (!(husb = kzalloc(sizeof(struct hci_usb), GFP_KERNEL))) {
BT_ERR("Can't allocate: control structure");
goto done;
}
- memset(husb, 0, sizeof(struct hci_usb));
-
husb->udev = udev;
husb->bulk_out_ep = bulk_out_ep;
husb->bulk_in_ep = bulk_in_ep;
@@ -1072,6 +1074,9 @@ module_exit(hci_usb_exit);
module_param(ignore, bool, 0644);
MODULE_PARM_DESC(ignore, "Ignore devices from the matching table");
+module_param(ignore_dga, bool, 0644);
+MODULE_PARM_DESC(ignore_dga, "Ignore devices with id 08fd:0001");
+
module_param(ignore_csr, bool, 0644);
MODULE_PARM_DESC(ignore_csr, "Ignore devices with id 0a12:0001");
diff --git a/drivers/bluetooth/hci_vhci.c b/drivers/bluetooth/hci_vhci.c
index 52cbd45c308f..85738223ff0c 100644
--- a/drivers/bluetooth/hci_vhci.c
+++ b/drivers/bluetooth/hci_vhci.c
@@ -261,12 +261,10 @@ static int vhci_open(struct inode *inode, struct file *file)
struct vhci_data *vhci;
struct hci_dev *hdev;
- vhci = kmalloc(sizeof(struct vhci_data), GFP_KERNEL);
+ vhci = kzalloc(sizeof(struct vhci_data), GFP_KERNEL);
if (!vhci)
return -ENOMEM;
- memset(vhci, 0, sizeof(struct vhci_data));
-
skb_queue_head_init(&vhci->readq);
init_waitqueue_head(&vhci->read_wait);
diff --git a/drivers/cdrom/mcdx.c b/drivers/cdrom/mcdx.c
index b89420e6d704..a0b580c22d80 100644
--- a/drivers/cdrom/mcdx.c
+++ b/drivers/cdrom/mcdx.c
@@ -1085,7 +1085,7 @@ static int __init mcdx_init_drive(int drive)
xtrace(INIT, "kmalloc space for stuffpt's\n");
xtrace(MALLOC, "init() malloc %d bytes\n", size);
- if (!(stuffp = kmalloc(size, GFP_KERNEL))) {
+ if (!(stuffp = kzalloc(size, GFP_KERNEL))) {
xwarn("init() malloc failed\n");
return 1;
}
@@ -1101,8 +1101,6 @@ static int __init mcdx_init_drive(int drive)
sizeof(*stuffp), stuffp);
/* set default values */
- memset(stuffp, 0, sizeof(*stuffp));
-
stuffp->present = 0; /* this should be 0 already */
stuffp->toc = NULL; /* this should be NULL already */
diff --git a/drivers/cdrom/viocd.c b/drivers/cdrom/viocd.c
index 0829db58462f..b5191780ecca 100644
--- a/drivers/cdrom/viocd.c
+++ b/drivers/cdrom/viocd.c
@@ -46,9 +46,9 @@
#include <asm/vio.h>
#include <asm/scatterlist.h>
-#include <asm/iSeries/HvTypes.h>
-#include <asm/iSeries/HvLpEvent.h>
-#include <asm/iSeries/vio.h>
+#include <asm/iseries/hv_types.h>
+#include <asm/iseries/hv_lp_event.h>
+#include <asm/iseries/vio.h>
#define VIOCD_DEVICE "iseries/vcd"
#define VIOCD_DEVICE_DEVFS "iseries/vcd"
@@ -736,13 +736,16 @@ static struct vio_device_id viocd_device_table[] __devinitdata = {
{ "viocd", "" },
{ "", "" }
};
-
MODULE_DEVICE_TABLE(vio, viocd_device_table);
+
static struct vio_driver viocd_driver = {
- .name = "viocd",
.id_table = viocd_device_table,
.probe = viocd_probe,
- .remove = viocd_remove
+ .remove = viocd_remove,
+ .driver = {
+ .name = "viocd",
+ .owner = THIS_MODULE,
+ }
};
static int __init viocd_init(void)
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index c29365d5b524..fdf4370db994 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -661,7 +661,7 @@ config HW_RANDOM
config NVRAM
tristate "/dev/nvram support"
- depends on ATARI || X86 || X86_64 || ARM || GENERIC_NVRAM
+ depends on ATARI || X86 || ARM || GENERIC_NVRAM
---help---
If you say Y here and create a character special file /dev/nvram
with major number 10 and minor number 144 using mknod ("man mknod"),
@@ -985,7 +985,7 @@ config MAX_RAW_DEVS
config HANGCHECK_TIMER
tristate "Hangcheck timer"
- depends on X86_64 || X86 || IA64 || PPC64 || ARCH_S390
+ depends on X86 || IA64 || PPC64 || ARCH_S390
help
The hangcheck-timer module detects when the system has gone
out to lunch past a certain margin. It can reboot the system
@@ -1001,5 +1001,17 @@ config MMTIMER
source "drivers/char/tpm/Kconfig"
+config TELCLOCK
+ tristate "Telecom clock driver for MPBL0010 ATCA SBC"
+ depends on EXPERIMENTAL
+ default n
+ help
+ The telecom clock device is specific to the MPBL0010 ATCA computer and
+ allows direct userspace access to the configuration of the telecom clock
+ configuration settings. This device is used for hardware synchronization
+ across the ATCA backplane fabric. Upon loading, the driver exports a
+ sysfs directory, /sys/devices/platform/telco_clock, with a number of
+ files for controlling the behavior of this hardware.
+
endmenu
diff --git a/drivers/char/Makefile b/drivers/char/Makefile
index 08f69287ea36..4aeae687e88a 100644
--- a/drivers/char/Makefile
+++ b/drivers/char/Makefile
@@ -82,6 +82,7 @@ obj-$(CONFIG_NWFLASH) += nwflash.o
obj-$(CONFIG_SCx200_GPIO) += scx200_gpio.o
obj-$(CONFIG_GPIO_VR41XX) += vr41xx_giu.o
obj-$(CONFIG_TANBAC_TB0219) += tb0219.o
+obj-$(CONFIG_TELCLOCK) += tlclk.o
obj-$(CONFIG_WATCHDOG) += watchdog/
obj-$(CONFIG_MWAVE) += mwave/
diff --git a/drivers/char/agp/Kconfig b/drivers/char/agp/Kconfig
index 7f8c1b53b754..486ed8a11b59 100644
--- a/drivers/char/agp/Kconfig
+++ b/drivers/char/agp/Kconfig
@@ -27,7 +27,7 @@ config AGP
config AGP_ALI
tristate "ALI chipset support"
- depends on AGP && X86 && !X86_64
+ depends on AGP && X86_32
---help---
This option gives you AGP support for the GLX component of
XFree86 4.x on the following ALi chipsets. The supported chipsets
@@ -45,7 +45,7 @@ config AGP_ALI
config AGP_ATI
tristate "ATI chipset support"
- depends on AGP && X86 && !X86_64
+ depends on AGP && X86_32
---help---
This option gives you AGP support for the GLX component of
XFree86 4.x on the ATI RadeonIGP family of chipsets.
@@ -55,7 +55,7 @@ config AGP_ATI
config AGP_AMD
tristate "AMD Irongate, 761, and 762 chipset support"
- depends on AGP && X86 && !X86_64
+ depends on AGP && X86_32
help
This option gives you AGP support for the GLX component of
XFree86 4.x on AMD Irongate, 761, and 762 chipsets.
@@ -91,7 +91,7 @@ config AGP_INTEL
config AGP_NVIDIA
tristate "NVIDIA nForce/nForce2 chipset support"
- depends on AGP && X86 && !X86_64
+ depends on AGP && X86_32
help
This option gives you AGP support for the GLX component of
XFree86 4.x on the following NVIDIA chipsets. The supported chipsets
@@ -99,7 +99,7 @@ config AGP_NVIDIA
config AGP_SIS
tristate "SiS chipset support"
- depends on AGP && X86 && !X86_64
+ depends on AGP && X86_32
help
This option gives you AGP support for the GLX component of
XFree86 4.x on Silicon Integrated Systems [SiS] chipsets.
@@ -111,14 +111,14 @@ config AGP_SIS
config AGP_SWORKS
tristate "Serverworks LE/HE chipset support"
- depends on AGP && X86 && !X86_64
+ depends on AGP && X86_32
help
Say Y here to support the Serverworks AGP card. See
<http://www.serverworks.com/> for product descriptions and images.
config AGP_VIA
tristate "VIA chipset support"
- depends on AGP && X86 && !X86_64
+ depends on AGP && X86_32
help
This option gives you AGP support for the GLX component of
XFree86 4.x on VIA MVP3/Apollo Pro chipsets.
@@ -154,7 +154,7 @@ config AGP_UNINORTH
config AGP_EFFICEON
tristate "Transmeta Efficeon support"
- depends on AGP && X86 && !X86_64
+ depends on AGP && X86_32
help
This option gives you AGP support for the Transmeta Efficeon
series processors with integrated northbridges.
diff --git a/drivers/char/agp/ali-agp.c b/drivers/char/agp/ali-agp.c
index 9c9c9c2247ce..b02fc2267159 100644
--- a/drivers/char/agp/ali-agp.c
+++ b/drivers/char/agp/ali-agp.c
@@ -7,6 +7,7 @@
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/agp_backend.h>
+#include <asm/page.h> /* PAGE_SIZE */
#include "agp.h"
#define ALI_AGPCTRL 0xb8
diff --git a/drivers/char/agp/amd-k7-agp.c b/drivers/char/agp/amd-k7-agp.c
index 3a41672e4d66..1f776651ac64 100644
--- a/drivers/char/agp/amd-k7-agp.c
+++ b/drivers/char/agp/amd-k7-agp.c
@@ -94,19 +94,16 @@ static int amd_create_gatt_pages(int nr_tables)
int retval = 0;
int i;
- tables = kmalloc((nr_tables + 1) * sizeof(struct amd_page_map *),
- GFP_KERNEL);
+ tables = kzalloc((nr_tables + 1) * sizeof(struct amd_page_map *),GFP_KERNEL);
if (tables == NULL)
return -ENOMEM;
- memset (tables, 0, sizeof(struct amd_page_map *) * (nr_tables + 1));
for (i = 0; i < nr_tables; i++) {
- entry = kmalloc(sizeof(struct amd_page_map), GFP_KERNEL);
+ entry = kzalloc(sizeof(struct amd_page_map), GFP_KERNEL);
if (entry == NULL) {
retval = -ENOMEM;
break;
}
- memset (entry, 0, sizeof(struct amd_page_map));
tables[i] = entry;
retval = amd_create_page_map(entry);
if (retval != 0)
diff --git a/drivers/char/agp/amd64-agp.c b/drivers/char/agp/amd64-agp.c
index 0a7624a9b1c1..78ce98a69f37 100644
--- a/drivers/char/agp/amd64-agp.c
+++ b/drivers/char/agp/amd64-agp.c
@@ -13,6 +13,8 @@
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/agp_backend.h>
+#include <linux/mmzone.h>
+#include <asm/page.h> /* PAGE_SIZE */
#include "agp.h"
/* Will need to be increased if AMD64 ever goes >8-way. */
diff --git a/drivers/char/agp/ati-agp.c b/drivers/char/agp/ati-agp.c
index e572ced9100a..53372a83b675 100644
--- a/drivers/char/agp/ati-agp.c
+++ b/drivers/char/agp/ati-agp.c
@@ -6,6 +6,8 @@
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/init.h>
+#include <linux/string.h>
+#include <linux/slab.h>
#include <linux/agp_backend.h>
#include <asm/agp.h>
#include "agp.h"
@@ -116,14 +118,12 @@ static int ati_create_gatt_pages(int nr_tables)
int retval = 0;
int i;
- tables = kmalloc((nr_tables + 1) * sizeof(ati_page_map *),
- GFP_KERNEL);
+ tables = kzalloc((nr_tables + 1) * sizeof(ati_page_map *),GFP_KERNEL);
if (tables == NULL)
return -ENOMEM;
- memset(tables, 0, sizeof(ati_page_map *) * (nr_tables + 1));
for (i = 0; i < nr_tables; i++) {
- entry = kmalloc(sizeof(ati_page_map), GFP_KERNEL);
+ entry = kzalloc(sizeof(ati_page_map), GFP_KERNEL);
if (entry == NULL) {
while (i>0) {
kfree (tables[i-1]);
@@ -134,7 +134,6 @@ static int ati_create_gatt_pages(int nr_tables)
retval = -ENOMEM;
break;
}
- memset(entry, 0, sizeof(ati_page_map));
tables[i] = entry;
retval = ati_create_page_map(entry);
if (retval != 0) break;
diff --git a/drivers/char/agp/backend.c b/drivers/char/agp/backend.c
index 82b43c541c8d..27bca34b4a65 100644
--- a/drivers/char/agp/backend.c
+++ b/drivers/char/agp/backend.c
@@ -147,6 +147,7 @@ static int agp_backend_initialize(struct agp_bridge_data *bridge)
printk(KERN_ERR PFX "unable to get memory for scratch page.\n");
return -ENOMEM;
}
+ flush_agp_mappings();
bridge->scratch_page_real = virt_to_gart(addr);
bridge->scratch_page =
@@ -187,9 +188,11 @@ static int agp_backend_initialize(struct agp_bridge_data *bridge)
return 0;
err_out:
- if (bridge->driver->needs_scratch_page)
+ if (bridge->driver->needs_scratch_page) {
bridge->driver->agp_destroy_page(
gart_to_virt(bridge->scratch_page_real));
+ flush_agp_mappings();
+ }
if (got_gatt)
bridge->driver->free_gatt_table(bridge);
if (got_keylist) {
@@ -211,9 +214,11 @@ static void agp_backend_cleanup(struct agp_bridge_data *bridge)
bridge->key_list = NULL;
if (bridge->driver->agp_destroy_page &&
- bridge->driver->needs_scratch_page)
+ bridge->driver->needs_scratch_page) {
bridge->driver->agp_destroy_page(
gart_to_virt(bridge->scratch_page_real));
+ flush_agp_mappings();
+ }
}
/* When we remove the global variable agp_bridge from all drivers
@@ -222,12 +227,12 @@ static void agp_backend_cleanup(struct agp_bridge_data *bridge)
struct agp_bridge_data *agp_alloc_bridge(void)
{
- struct agp_bridge_data *bridge = kmalloc(sizeof(*bridge), GFP_KERNEL);
-
+ struct agp_bridge_data *bridge;
+
+ bridge = kzalloc(sizeof(*bridge), GFP_KERNEL);
if (!bridge)
return NULL;
- memset(bridge, 0, sizeof(*bridge));
atomic_set(&bridge->agp_in_use, 0);
atomic_set(&bridge->current_memory_agp, 0);
diff --git a/drivers/char/agp/efficeon-agp.c b/drivers/char/agp/efficeon-agp.c
index ac19fdcd21c1..e7aea77a60f9 100644
--- a/drivers/char/agp/efficeon-agp.c
+++ b/drivers/char/agp/efficeon-agp.c
@@ -219,7 +219,7 @@ static int efficeon_create_gatt_table(struct agp_bridge_data *bridge)
efficeon_private.l1_table[index] = page;
- value = virt_to_gart(page) | pati | present | index;
+ value = virt_to_gart((unsigned long *)page) | pati | present | index;
pci_write_config_dword(agp_bridge->dev,
EFFICEON_ATTPAGE, value);
diff --git a/drivers/char/agp/frontend.c b/drivers/char/agp/frontend.c
index 3dfb6648547b..17f520c9d471 100644
--- a/drivers/char/agp/frontend.c
+++ b/drivers/char/agp/frontend.c
@@ -189,13 +189,12 @@ static int agp_create_segment(struct agp_client *client, struct agp_region *regi
struct agp_segment *user_seg;
size_t i;
- seg = kmalloc((sizeof(struct agp_segment_priv) * region->seg_count), GFP_KERNEL);
+ seg = kzalloc((sizeof(struct agp_segment_priv) * region->seg_count), GFP_KERNEL);
if (seg == NULL) {
kfree(region->seg_list);
region->seg_list = NULL;
return -ENOMEM;
}
- memset(seg, 0, (sizeof(struct agp_segment_priv) * region->seg_count));
user_seg = region->seg_list;
for (i = 0; i < region->seg_count; i++) {
@@ -332,14 +331,11 @@ static struct agp_controller *agp_create_controller(pid_t id)
{
struct agp_controller *controller;
- controller = kmalloc(sizeof(struct agp_controller), GFP_KERNEL);
-
+ controller = kzalloc(sizeof(struct agp_controller), GFP_KERNEL);
if (controller == NULL)
return NULL;
- memset(controller, 0, sizeof(struct agp_controller));
controller->pid = id;
-
return controller;
}
@@ -540,12 +536,10 @@ static struct agp_client *agp_create_client(pid_t id)
{
struct agp_client *new_client;
- new_client = kmalloc(sizeof(struct agp_client), GFP_KERNEL);
-
+ new_client = kzalloc(sizeof(struct agp_client), GFP_KERNEL);
if (new_client == NULL)
return NULL;
- memset(new_client, 0, sizeof(struct agp_client));
new_client->pid = id;
agp_insert_client(new_client);
return new_client;
@@ -709,11 +703,10 @@ static int agp_open(struct inode *inode, struct file *file)
if (minor != AGPGART_MINOR)
goto err_out;
- priv = kmalloc(sizeof(struct agp_file_private), GFP_KERNEL);
+ priv = kzalloc(sizeof(struct agp_file_private), GFP_KERNEL);
if (priv == NULL)
goto err_out_nomem;
- memset(priv, 0, sizeof(struct agp_file_private));
set_bit(AGP_FF_ALLOW_CLIENT, &priv->access_flags);
priv->my_pid = current->pid;
diff --git a/drivers/char/agp/generic.c b/drivers/char/agp/generic.c
index ac9da0ca36b7..5567ce8d72b0 100644
--- a/drivers/char/agp/generic.c
+++ b/drivers/char/agp/generic.c
@@ -57,7 +57,8 @@ int map_page_into_agp(struct page *page)
{
int i;
i = change_page_attr(page, 1, PAGE_KERNEL_NOCACHE);
- global_flush_tlb();
+ /* Caller's responsibility to call global_flush_tlb() for
+ * performance reasons */
return i;
}
EXPORT_SYMBOL_GPL(map_page_into_agp);
@@ -66,7 +67,8 @@ int unmap_page_from_agp(struct page *page)
{
int i;
i = change_page_attr(page, 1, PAGE_KERNEL);
- global_flush_tlb();
+ /* Caller's responsibility to call global_flush_tlb() for
+ * performance reasons */
return i;
}
EXPORT_SYMBOL_GPL(unmap_page_from_agp);
@@ -105,12 +107,10 @@ struct agp_memory *agp_create_memory(int scratch_pages)
{
struct agp_memory *new;
- new = kmalloc(sizeof(struct agp_memory), GFP_KERNEL);
-
+ new = kzalloc(sizeof(struct agp_memory), GFP_KERNEL);
if (new == NULL)
return NULL;
- memset(new, 0, sizeof(struct agp_memory));
new->key = agp_get_key();
if (new->key < 0) {
@@ -155,6 +155,7 @@ void agp_free_memory(struct agp_memory *curr)
for (i = 0; i < curr->page_count; i++) {
curr->bridge->driver->agp_destroy_page(gart_to_virt(curr->memory[i]));
}
+ flush_agp_mappings();
}
agp_free_key(curr->key);
vfree(curr->memory);
@@ -212,7 +213,7 @@ struct agp_memory *agp_allocate_memory(struct agp_bridge_data *bridge,
new->memory[i] = virt_to_gart(addr);
new->page_count++;
}
- new->bridge = bridge;
+ new->bridge = bridge;
flush_agp_mappings();
@@ -414,7 +415,8 @@ static void agp_v2_parse_one(u32 *requested_mode, u32 *bridge_agpstat, u32 *vga_
u32 tmp;
if (*requested_mode & AGP2_RESERVED_MASK) {
- printk(KERN_INFO PFX "reserved bits set in mode 0x%x. Fixed.\n", *requested_mode);
+ printk(KERN_INFO PFX "reserved bits set (%x) in mode 0x%x. Fixed.\n",
+ *requested_mode & AGP2_RESERVED_MASK, *requested_mode);
*requested_mode &= ~AGP2_RESERVED_MASK;
}
@@ -492,7 +494,8 @@ static void agp_v3_parse_one(u32 *requested_mode, u32 *bridge_agpstat, u32 *vga_
u32 tmp;
if (*requested_mode & AGP3_RESERVED_MASK) {
- printk(KERN_INFO PFX "reserved bits set in mode 0x%x. Fixed.\n", *requested_mode);
+ printk(KERN_INFO PFX "reserved bits set (%x) in mode 0x%x. Fixed.\n",
+ *requested_mode & AGP3_RESERVED_MASK, *requested_mode);
*requested_mode &= ~AGP3_RESERVED_MASK;
}
diff --git a/drivers/char/agp/i460-agp.c b/drivers/char/agp/i460-agp.c
index 94943298c03e..8ee19a4a6bce 100644
--- a/drivers/char/agp/i460-agp.c
+++ b/drivers/char/agp/i460-agp.c
@@ -10,6 +10,8 @@
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/init.h>
+#include <linux/string.h>
+#include <linux/slab.h>
#include <linux/agp_backend.h>
#include "agp.h"
@@ -109,8 +111,10 @@ static int i460_fetch_size (void)
if (i460.io_page_shift != I460_IO_PAGE_SHIFT) {
printk(KERN_ERR PFX
- "I/O (GART) page-size %ZuKB doesn't match expected size %ZuKB\n",
- 1UL << (i460.io_page_shift - 10), 1UL << (I460_IO_PAGE_SHIFT));
+ "I/O (GART) page-size %luKB doesn't match expected "
+ "size %luKB\n",
+ 1UL << (i460.io_page_shift - 10),
+ 1UL << (I460_IO_PAGE_SHIFT));
return 0;
}
@@ -225,10 +229,9 @@ static int i460_configure (void)
*/
if (I460_IO_PAGE_SHIFT > PAGE_SHIFT) {
size = current_size->num_entries * sizeof(i460.lp_desc[0]);
- i460.lp_desc = kmalloc(size, GFP_KERNEL);
+ i460.lp_desc = kzalloc(size, GFP_KERNEL);
if (!i460.lp_desc)
return -ENOMEM;
- memset(i460.lp_desc, 0, size);
}
return 0;
}
@@ -364,13 +367,12 @@ static int i460_alloc_large_page (struct lp_desc *lp)
}
map_size = ((I460_KPAGES_PER_IOPAGE + BITS_PER_LONG - 1) & -BITS_PER_LONG)/8;
- lp->alloced_map = kmalloc(map_size, GFP_KERNEL);
+ lp->alloced_map = kzalloc(map_size, GFP_KERNEL);
if (!lp->alloced_map) {
free_pages((unsigned long) lpage, order);
printk(KERN_ERR PFX "Out of memory, we're in trouble...\n");
return -ENOMEM;
}
- memset(lp->alloced_map, 0, map_size);
lp->paddr = virt_to_gart(lpage);
lp->refcount = 0;
@@ -514,9 +516,10 @@ static void *i460_alloc_page (struct agp_bridge_data *bridge)
{
void *page;
- if (I460_IO_PAGE_SHIFT <= PAGE_SHIFT)
+ if (I460_IO_PAGE_SHIFT <= PAGE_SHIFT) {
page = agp_generic_alloc_page(agp_bridge);
- else
+ global_flush_tlb();
+ } else
/* Returning NULL would cause problems */
/* AK: really dubious code. */
page = (void *)~0UL;
@@ -525,8 +528,10 @@ static void *i460_alloc_page (struct agp_bridge_data *bridge)
static void i460_destroy_page (void *page)
{
- if (I460_IO_PAGE_SHIFT <= PAGE_SHIFT)
+ if (I460_IO_PAGE_SHIFT <= PAGE_SHIFT) {
agp_generic_destroy_page(page);
+ global_flush_tlb();
+ }
}
#endif /* I460_LARGE_IO_PAGES */
@@ -536,7 +541,7 @@ static unsigned long i460_mask_memory (struct agp_bridge_data *bridge,
{
/* Make sure the returned address is a valid GATT entry */
return bridge->driver->masks[0].mask
- | (((addr & ~((1 << I460_IO_PAGE_SHIFT) - 1)) & 0xffffff000) >> 12);
+ | (((addr & ~((1 << I460_IO_PAGE_SHIFT) - 1)) & 0xfffff000) >> 12);
}
struct agp_bridge_driver intel_i460_driver = {
diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c
index 1f7d415f432c..e7bed5047dcc 100644
--- a/drivers/char/agp/intel-agp.c
+++ b/drivers/char/agp/intel-agp.c
@@ -270,6 +270,7 @@ static struct agp_memory *alloc_agpphysmem_i8xx(size_t pg_count, int type)
switch (pg_count) {
case 1: addr = agp_bridge->driver->agp_alloc_page(agp_bridge);
+ global_flush_tlb();
break;
case 4:
/* kludge to get 4 physical pages for ARGB cursor */
@@ -330,9 +331,11 @@ static void intel_i810_free_by_type(struct agp_memory *curr)
if(curr->type == AGP_PHYS_MEMORY) {
if (curr->page_count == 4)
i8xx_destroy_pages(gart_to_virt(curr->memory[0]));
- else
+ else {
agp_bridge->driver->agp_destroy_page(
gart_to_virt(curr->memory[0]));
+ global_flush_tlb();
+ }
vfree(curr->memory);
}
kfree(curr);
diff --git a/drivers/char/agp/isoch.c b/drivers/char/agp/isoch.c
index c9ac731504f2..40083241804e 100644
--- a/drivers/char/agp/isoch.c
+++ b/drivers/char/agp/isoch.c
@@ -6,6 +6,7 @@
#include <linux/pci.h>
#include <linux/agp_backend.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include "agp.h"
diff --git a/drivers/char/agp/sgi-agp.c b/drivers/char/agp/sgi-agp.c
index d3aa159c9dec..4df7734b51c2 100644
--- a/drivers/char/agp/sgi-agp.c
+++ b/drivers/char/agp/sgi-agp.c
@@ -17,6 +17,7 @@
#include <linux/init.h>
#include <linux/agp_backend.h>
#include <asm/sn/addrs.h>
+#include <asm/sn/io.h>
#include <asm/sn/pcidev.h>
#include <asm/sn/pcibus_provider_defs.h>
#include <asm/sn/tioca_provider.h>
@@ -288,6 +289,8 @@ static int __devinit agp_sgi_init(void)
j = 0;
list_for_each_entry(info, &tioca_list, ca_list) {
struct list_head *tmp;
+ if (list_empty(info->ca_devices))
+ continue;
list_for_each(tmp, info->ca_devices) {
u8 cap_ptr;
pdev = pci_dev_b(tmp);
diff --git a/drivers/char/agp/sworks-agp.c b/drivers/char/agp/sworks-agp.c
index a9fb12c20eb7..3f8f7fa6b0ff 100644
--- a/drivers/char/agp/sworks-agp.c
+++ b/drivers/char/agp/sworks-agp.c
@@ -5,6 +5,8 @@
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/init.h>
+#include <linux/string.h>
+#include <linux/slab.h>
#include <linux/agp_backend.h>
#include "agp.h"
@@ -100,19 +102,17 @@ static int serverworks_create_gatt_pages(int nr_tables)
int retval = 0;
int i;
- tables = kmalloc((nr_tables + 1) * sizeof(struct serverworks_page_map *),
+ tables = kzalloc((nr_tables + 1) * sizeof(struct serverworks_page_map *),
GFP_KERNEL);
- if (tables == NULL) {
+ if (tables == NULL)
return -ENOMEM;
- }
- memset(tables, 0, sizeof(struct serverworks_page_map *) * (nr_tables + 1));
+
for (i = 0; i < nr_tables; i++) {
- entry = kmalloc(sizeof(struct serverworks_page_map), GFP_KERNEL);
+ entry = kzalloc(sizeof(struct serverworks_page_map), GFP_KERNEL);
if (entry == NULL) {
retval = -ENOMEM;
break;
}
- memset(entry, 0, sizeof(struct serverworks_page_map));
tables[i] = entry;
retval = serverworks_create_page_map(entry);
if (retval != 0) break;
@@ -242,13 +242,27 @@ static int serverworks_fetch_size(void)
*/
static void serverworks_tlbflush(struct agp_memory *temp)
{
+ unsigned long timeout;
+
writeb(1, serverworks_private.registers+SVWRKS_POSTFLUSH);
- while (readb(serverworks_private.registers+SVWRKS_POSTFLUSH) == 1)
+ timeout = jiffies + 3*HZ;
+ while (readb(serverworks_private.registers+SVWRKS_POSTFLUSH) == 1) {
cpu_relax();
+ if (time_after(jiffies, timeout)) {
+ printk(KERN_ERR PFX "TLB post flush took more than 3 seconds\n");
+ break;
+ }
+ }
writel(1, serverworks_private.registers+SVWRKS_DIRFLUSH);
- while(readl(serverworks_private.registers+SVWRKS_DIRFLUSH) == 1)
+ timeout = jiffies + 3*HZ;
+ while (readl(serverworks_private.registers+SVWRKS_DIRFLUSH) == 1) {
cpu_relax();
+ if (time_after(jiffies, timeout)) {
+ printk(KERN_ERR PFX "TLB Dir flush took more than 3 seconds\n");
+ break;
+ }
+ }
}
static int serverworks_configure(void)
diff --git a/drivers/char/consolemap.c b/drivers/char/consolemap.c
index 406dea914635..c85a4fa60da7 100644
--- a/drivers/char/consolemap.c
+++ b/drivers/char/consolemap.c
@@ -345,17 +345,15 @@ static void con_release_unimap(struct uni_pagedir *p)
for (i = 0; i < 32; i++) {
if ((p1 = p->uni_pgdir[i]) != NULL) {
for (j = 0; j < 32; j++)
- if (p1[j])
- kfree(p1[j]);
+ kfree(p1[j]);
kfree(p1);
}
p->uni_pgdir[i] = NULL;
}
- for (i = 0; i < 4; i++)
- if (p->inverse_translations[i]) {
- kfree(p->inverse_translations[i]);
- p->inverse_translations[i] = NULL;
- }
+ for (i = 0; i < 4; i++) {
+ kfree(p->inverse_translations[i]);
+ p->inverse_translations[i] = NULL;
+ }
}
void con_free_unimap(struct vc_data *vc)
diff --git a/drivers/char/cyclades.c b/drivers/char/cyclades.c
index cf4c3648463d..c7f818cd7b02 100644
--- a/drivers/char/cyclades.c
+++ b/drivers/char/cyclades.c
@@ -281,7 +281,7 @@ static char rcsid[] =
* make sure "cyc" appears in all kernel messages; all soft interrupts
* handled by same routine; recognize out-of-band reception; comment
* out some diagnostic messages; leave RTS/CTS flow control to hardware;
- * fix race condition in -Z buffer management; only -Y needs to explictly
+ * fix race condition in -Z buffer management; only -Y needs to explicitly
* flush chars; tidy up some startup messages;
*
* Revision 1.36.4.18 1996/07/25 18:57:31 bentson
diff --git a/drivers/char/drm/ati_pcigart.c b/drivers/char/drm/ati_pcigart.c
index 0aec5ef481b8..efff0eec618c 100644
--- a/drivers/char/drm/ati_pcigart.c
+++ b/drivers/char/drm/ati_pcigart.c
@@ -1,5 +1,5 @@
/**
- * \file ati_pcigart.h
+ * \file ati_pcigart.c
* ATI PCI GART support
*
* \author Gareth Hughes <gareth@valinux.com>
@@ -52,85 +52,91 @@
# define ATI_MAX_PCIGART_PAGES 8192 /**< 32 MB aperture, 4K pages */
# define ATI_PCIGART_PAGE_SIZE 4096 /**< PCI GART page size */
-static unsigned long drm_ati_alloc_pcigart_table( void )
+static unsigned long drm_ati_alloc_pcigart_table(void)
{
unsigned long address;
struct page *page;
int i;
- DRM_DEBUG( "%s\n", __FUNCTION__ );
+ DRM_DEBUG("%s\n", __FUNCTION__);
- address = __get_free_pages( GFP_KERNEL, ATI_PCIGART_TABLE_ORDER );
- if ( address == 0UL ) {
+ address = __get_free_pages(GFP_KERNEL, ATI_PCIGART_TABLE_ORDER);
+ if (address == 0UL) {
return 0;
}
- page = virt_to_page( address );
+ page = virt_to_page(address);
- for ( i = 0 ; i < ATI_PCIGART_TABLE_PAGES ; i++, page++ ) {
+ for (i = 0; i < ATI_PCIGART_TABLE_PAGES; i++, page++) {
get_page(page);
- SetPageReserved( page );
+ SetPageReserved(page);
}
- DRM_DEBUG( "%s: returning 0x%08lx\n", __FUNCTION__, address );
+ DRM_DEBUG("%s: returning 0x%08lx\n", __FUNCTION__, address);
return address;
}
-static void drm_ati_free_pcigart_table( unsigned long address )
+static void drm_ati_free_pcigart_table(unsigned long address)
{
struct page *page;
int i;
- DRM_DEBUG( "%s\n", __FUNCTION__ );
+ DRM_DEBUG("%s\n", __FUNCTION__);
- page = virt_to_page( address );
+ page = virt_to_page(address);
- for ( i = 0 ; i < ATI_PCIGART_TABLE_PAGES ; i++, page++ ) {
+ for (i = 0; i < ATI_PCIGART_TABLE_PAGES; i++, page++) {
__put_page(page);
- ClearPageReserved( page );
+ ClearPageReserved(page);
}
- free_pages( address, ATI_PCIGART_TABLE_ORDER );
+ free_pages(address, ATI_PCIGART_TABLE_ORDER);
}
-int drm_ati_pcigart_cleanup( drm_device_t *dev,
- unsigned long addr,
- dma_addr_t bus_addr)
+int drm_ati_pcigart_cleanup(drm_device_t * dev,
+ drm_ati_pcigart_info * gart_info)
{
drm_sg_mem_t *entry = dev->sg;
unsigned long pages;
int i;
/* we need to support large memory configurations */
- if ( !entry ) {
- DRM_ERROR( "no scatter/gather memory!\n" );
+ if (!entry) {
+ DRM_ERROR("no scatter/gather memory!\n");
return 0;
}
- if ( bus_addr ) {
- pci_unmap_single(dev->pdev, bus_addr,
- ATI_PCIGART_TABLE_PAGES * PAGE_SIZE,
- PCI_DMA_TODEVICE);
+ if (gart_info->bus_addr) {
+ if (gart_info->gart_table_location == DRM_ATI_GART_MAIN) {
+ pci_unmap_single(dev->pdev, gart_info->bus_addr,
+ ATI_PCIGART_TABLE_PAGES * PAGE_SIZE,
+ PCI_DMA_TODEVICE);
+ }
- pages = ( entry->pages <= ATI_MAX_PCIGART_PAGES )
- ? entry->pages : ATI_MAX_PCIGART_PAGES;
+ pages = (entry->pages <= ATI_MAX_PCIGART_PAGES)
+ ? entry->pages : ATI_MAX_PCIGART_PAGES;
- for ( i = 0 ; i < pages ; i++ ) {
- if ( !entry->busaddr[i] ) break;
+ for (i = 0; i < pages; i++) {
+ if (!entry->busaddr[i])
+ break;
pci_unmap_single(dev->pdev, entry->busaddr[i],
PAGE_SIZE, PCI_DMA_TODEVICE);
}
+
+ if (gart_info->gart_table_location == DRM_ATI_GART_MAIN)
+ gart_info->bus_addr = 0;
}
- if ( addr ) {
- drm_ati_free_pcigart_table( addr );
+ if (gart_info->gart_table_location == DRM_ATI_GART_MAIN
+ && gart_info->addr) {
+ drm_ati_free_pcigart_table(gart_info->addr);
+ gart_info->addr = 0;
}
return 1;
}
+
EXPORT_SYMBOL(drm_ati_pcigart_cleanup);
-int drm_ati_pcigart_init( drm_device_t *dev,
- unsigned long *addr,
- dma_addr_t *bus_addr)
+int drm_ati_pcigart_init(drm_device_t * dev, drm_ati_pcigart_info * gart_info)
{
drm_sg_mem_t *entry = dev->sg;
unsigned long address = 0;
@@ -138,48 +144,57 @@ int drm_ati_pcigart_init( drm_device_t *dev,
u32 *pci_gart, page_base, bus_address = 0;
int i, j, ret = 0;
- if ( !entry ) {
- DRM_ERROR( "no scatter/gather memory!\n" );
+ if (!entry) {
+ DRM_ERROR("no scatter/gather memory!\n");
goto done;
}
- address = drm_ati_alloc_pcigart_table();
- if ( !address ) {
- DRM_ERROR( "cannot allocate PCI GART page!\n" );
- goto done;
- }
+ if (gart_info->gart_table_location == DRM_ATI_GART_MAIN) {
+ DRM_DEBUG("PCI: no table in VRAM: using normal RAM\n");
- if ( !dev->pdev ) {
- DRM_ERROR( "PCI device unknown!\n" );
- goto done;
- }
+ address = drm_ati_alloc_pcigart_table();
+ if (!address) {
+ DRM_ERROR("cannot allocate PCI GART page!\n");
+ goto done;
+ }
- bus_address = pci_map_single(dev->pdev, (void *)address,
- ATI_PCIGART_TABLE_PAGES * PAGE_SIZE,
- PCI_DMA_TODEVICE);
- if (bus_address == 0) {
- DRM_ERROR( "unable to map PCIGART pages!\n" );
- drm_ati_free_pcigart_table( address );
- address = 0;
- goto done;
+ if (!dev->pdev) {
+ DRM_ERROR("PCI device unknown!\n");
+ goto done;
+ }
+
+ bus_address = pci_map_single(dev->pdev, (void *)address,
+ ATI_PCIGART_TABLE_PAGES *
+ PAGE_SIZE, PCI_DMA_TODEVICE);
+ if (bus_address == 0) {
+ DRM_ERROR("unable to map PCIGART pages!\n");
+ drm_ati_free_pcigart_table(address);
+ address = 0;
+ goto done;
+ }
+ } else {
+ address = gart_info->addr;
+ bus_address = gart_info->bus_addr;
+ DRM_DEBUG("PCI: Gart Table: VRAM %08X mapped at %08lX\n",
+ bus_address, address);
}
- pci_gart = (u32 *)address;
+ pci_gart = (u32 *) address;
- pages = ( entry->pages <= ATI_MAX_PCIGART_PAGES )
- ? entry->pages : ATI_MAX_PCIGART_PAGES;
+ pages = (entry->pages <= ATI_MAX_PCIGART_PAGES)
+ ? entry->pages : ATI_MAX_PCIGART_PAGES;
- memset( pci_gart, 0, ATI_MAX_PCIGART_PAGES * sizeof(u32) );
+ memset(pci_gart, 0, ATI_MAX_PCIGART_PAGES * sizeof(u32));
- for ( i = 0 ; i < pages ; i++ ) {
+ for (i = 0; i < pages; i++) {
/* we need to support large memory configurations */
entry->busaddr[i] = pci_map_single(dev->pdev,
- page_address( entry->pagelist[i] ),
- PAGE_SIZE,
- PCI_DMA_TODEVICE);
+ page_address(entry->
+ pagelist[i]),
+ PAGE_SIZE, PCI_DMA_TODEVICE);
if (entry->busaddr[i] == 0) {
- DRM_ERROR( "unable to map PCIGART pages!\n" );
- drm_ati_pcigart_cleanup( dev, address, bus_address );
+ DRM_ERROR("unable to map PCIGART pages!\n");
+ drm_ati_pcigart_cleanup(dev, gart_info);
address = 0;
bus_address = 0;
goto done;
@@ -187,7 +202,11 @@ int drm_ati_pcigart_init( drm_device_t *dev,
page_base = (u32) entry->busaddr[i];
for (j = 0; j < (PAGE_SIZE / ATI_PCIGART_PAGE_SIZE); j++) {
- *pci_gart++ = cpu_to_le32( page_base );
+ if (gart_info->is_pcie)
+ *pci_gart = cpu_to_le32((page_base >> 8) | 0xc);
+ else
+ *pci_gart = cpu_to_le32(page_base);
+ pci_gart++;
page_base += ATI_PCIGART_PAGE_SIZE;
}
}
@@ -200,9 +219,10 @@ int drm_ati_pcigart_init( drm_device_t *dev,
mb();
#endif
-done:
- *addr = address;
- *bus_addr = bus_address;
+ done:
+ gart_info->addr = address;
+ gart_info->bus_addr = bus_address;
return ret;
}
+
EXPORT_SYMBOL(drm_ati_pcigart_init);
diff --git a/drivers/char/drm/drm.h b/drivers/char/drm/drm.h
index fc6598a81acd..64d6237fdd0b 100644
--- a/drivers/char/drm/drm.h
+++ b/drivers/char/drm/drm.h
@@ -1,7 +1,7 @@
/**
- * \file drm.h
+ * \file drm.h
* Header for the Direct Rendering Manager
- *
+ *
* \author Rickard E. (Rik) Faith <faith@valinux.com>
*
* \par Acknowledgments:
@@ -33,7 +33,6 @@
* OTHER DEALINGS IN THE SOFTWARE.
*/
-
#ifndef _DRM_H_
#define _DRM_H_
@@ -56,7 +55,7 @@
#define ioctl(a,b,c) xf86ioctl(a,b,c)
#else
#include <sys/ioccom.h>
-#endif /* __FreeBSD__ && xf86ioctl */
+#endif /* __FreeBSD__ && xf86ioctl */
#define DRM_IOCTL_NR(n) ((n) & 0xff)
#define DRM_IOC_VOID IOC_VOID
#define DRM_IOC_READ IOC_OUT
@@ -97,16 +96,14 @@
#define _DRM_LOCK_IS_CONT(lock) ((lock) & _DRM_LOCK_CONT)
#define _DRM_LOCKING_CONTEXT(lock) ((lock) & ~(_DRM_LOCK_HELD|_DRM_LOCK_CONT))
-
-typedef unsigned int drm_handle_t;
-typedef unsigned int drm_context_t;
-typedef unsigned int drm_drawable_t;
-typedef unsigned int drm_magic_t;
-
+typedef unsigned int drm_handle_t;
+typedef unsigned int drm_context_t;
+typedef unsigned int drm_drawable_t;
+typedef unsigned int drm_magic_t;
/**
* Cliprect.
- *
+ *
* \warning: If you change this structure, make sure you change
* XF86DRIClipRectRec in the server as well
*
@@ -114,22 +111,21 @@ typedef unsigned int drm_magic_t;
* backwards-compatibility reasons.
*/
typedef struct drm_clip_rect {
- unsigned short x1;
- unsigned short y1;
- unsigned short x2;
- unsigned short y2;
+ unsigned short x1;
+ unsigned short y1;
+ unsigned short x2;
+ unsigned short y2;
} drm_clip_rect_t;
-
/**
* Texture region,
*/
typedef struct drm_tex_region {
- unsigned char next;
- unsigned char prev;
- unsigned char in_use;
- unsigned char padding;
- unsigned int age;
+ unsigned char next;
+ unsigned char prev;
+ unsigned char in_use;
+ unsigned char padding;
+ unsigned int age;
} drm_tex_region_t;
/**
@@ -141,28 +137,26 @@ typedef struct drm_tex_region {
*/
typedef struct drm_hw_lock {
__volatile__ unsigned int lock; /**< lock variable */
- char padding[60]; /**< Pad to cache line */
+ char padding[60]; /**< Pad to cache line */
} drm_hw_lock_t;
-
/**
* DRM_IOCTL_VERSION ioctl argument type.
- *
+ *
* \sa drmGetVersion().
*/
typedef struct drm_version {
- int version_major; /**< Major version */
- int version_minor; /**< Minor version */
- int version_patchlevel;/**< Patch level */
+ int version_major; /**< Major version */
+ int version_minor; /**< Minor version */
+ int version_patchlevel; /**< Patch level */
size_t name_len; /**< Length of name buffer */
- char __user *name; /**< Name of driver */
+ char __user *name; /**< Name of driver */
size_t date_len; /**< Length of date buffer */
- char __user *date; /**< User-space buffer to hold date */
+ char __user *date; /**< User-space buffer to hold date */
size_t desc_len; /**< Length of desc buffer */
- char __user *desc; /**< User-space buffer to hold desc */
+ char __user *desc; /**< User-space buffer to hold desc */
} drm_version_t;
-
/**
* DRM_IOCTL_GET_UNIQUE ioctl argument type.
*
@@ -170,21 +164,18 @@ typedef struct drm_version {
*/
typedef struct drm_unique {
size_t unique_len; /**< Length of unique */
- char __user *unique; /**< Unique name for driver instantiation */
+ char __user *unique; /**< Unique name for driver instantiation */
} drm_unique_t;
-
typedef struct drm_list {
- int count; /**< Length of user-space structures */
- drm_version_t __user *version;
+ int count; /**< Length of user-space structures */
+ drm_version_t __user *version;
} drm_list_t;
-
typedef struct drm_block {
- int unused;
+ int unused;
} drm_block_t;
-
/**
* DRM_IOCTL_CONTROL ioctl argument type.
*
@@ -196,44 +187,40 @@ typedef struct drm_control {
DRM_RM_COMMAND,
DRM_INST_HANDLER,
DRM_UNINST_HANDLER
- } func;
- int irq;
+ } func;
+ int irq;
} drm_control_t;
-
/**
* Type of memory to map.
*/
typedef enum drm_map_type {
- _DRM_FRAME_BUFFER = 0, /**< WC (no caching), no core dump */
- _DRM_REGISTERS = 1, /**< no caching, no core dump */
- _DRM_SHM = 2, /**< shared, cached */
- _DRM_AGP = 3, /**< AGP/GART */
+ _DRM_FRAME_BUFFER = 0, /**< WC (no caching), no core dump */
+ _DRM_REGISTERS = 1, /**< no caching, no core dump */
+ _DRM_SHM = 2, /**< shared, cached */
+ _DRM_AGP = 3, /**< AGP/GART */
_DRM_SCATTER_GATHER = 4, /**< Scatter/gather memory for PCI DMA */
- _DRM_CONSISTENT = 5, /**< Consistent memory for PCI DMA */
+ _DRM_CONSISTENT = 5, /**< Consistent memory for PCI DMA */
} drm_map_type_t;
-
/**
* Memory mapping flags.
*/
typedef enum drm_map_flags {
- _DRM_RESTRICTED = 0x01, /**< Cannot be mapped to user-virtual */
- _DRM_READ_ONLY = 0x02,
- _DRM_LOCKED = 0x04, /**< shared, cached, locked */
- _DRM_KERNEL = 0x08, /**< kernel requires access */
+ _DRM_RESTRICTED = 0x01, /**< Cannot be mapped to user-virtual */
+ _DRM_READ_ONLY = 0x02,
+ _DRM_LOCKED = 0x04, /**< shared, cached, locked */
+ _DRM_KERNEL = 0x08, /**< kernel requires access */
_DRM_WRITE_COMBINING = 0x10, /**< use write-combining if available */
- _DRM_CONTAINS_LOCK = 0x20, /**< SHM page that contains lock */
- _DRM_REMOVABLE = 0x40 /**< Removable mapping */
+ _DRM_CONTAINS_LOCK = 0x20, /**< SHM page that contains lock */
+ _DRM_REMOVABLE = 0x40 /**< Removable mapping */
} drm_map_flags_t;
-
typedef struct drm_ctx_priv_map {
- unsigned int ctx_id; /**< Context requesting private mapping */
- void *handle; /**< Handle of map */
+ unsigned int ctx_id; /**< Context requesting private mapping */
+ void *handle; /**< Handle of map */
} drm_ctx_priv_map_t;
-
/**
* DRM_IOCTL_GET_MAP, DRM_IOCTL_ADD_MAP and DRM_IOCTL_RM_MAP ioctls
* argument type.
@@ -241,30 +228,28 @@ typedef struct drm_ctx_priv_map {
* \sa drmAddMap().
*/
typedef struct drm_map {
- unsigned long offset; /**< Requested physical address (0 for SAREA)*/
- unsigned long size; /**< Requested physical size (bytes) */
- drm_map_type_t type; /**< Type of memory to map */
+ unsigned long offset; /**< Requested physical address (0 for SAREA)*/
+ unsigned long size; /**< Requested physical size (bytes) */
+ drm_map_type_t type; /**< Type of memory to map */
drm_map_flags_t flags; /**< Flags */
- void *handle; /**< User-space: "Handle" to pass to mmap() */
+ void *handle; /**< User-space: "Handle" to pass to mmap() */
/**< Kernel-space: kernel-virtual address */
- int mtrr; /**< MTRR slot used */
- /* Private data */
+ int mtrr; /**< MTRR slot used */
+ /* Private data */
} drm_map_t;
-
/**
* DRM_IOCTL_GET_CLIENT ioctl argument type.
*/
typedef struct drm_client {
- int idx; /**< Which client desired? */
- int auth; /**< Is client authenticated? */
- unsigned long pid; /**< Process ID */
- unsigned long uid; /**< User ID */
- unsigned long magic; /**< Magic */
- unsigned long iocs; /**< Ioctl count */
+ int idx; /**< Which client desired? */
+ int auth; /**< Is client authenticated? */
+ unsigned long pid; /**< Process ID */
+ unsigned long uid; /**< User ID */
+ unsigned long magic; /**< Magic */
+ unsigned long iocs; /**< Ioctl count */
} drm_client_t;
-
typedef enum {
_DRM_STAT_LOCK,
_DRM_STAT_OPENS,
@@ -282,63 +267,58 @@ typedef enum {
_DRM_STAT_DMA, /**< DMA */
_DRM_STAT_SPECIAL, /**< Special DMA (e.g., priority or polled) */
_DRM_STAT_MISSED /**< Missed DMA opportunity */
-
- /* Add to the *END* of the list */
+ /* Add to the *END* of the list */
} drm_stat_type_t;
-
/**
* DRM_IOCTL_GET_STATS ioctl argument type.
*/
typedef struct drm_stats {
unsigned long count;
struct {
- unsigned long value;
+ unsigned long value;
drm_stat_type_t type;
} data[15];
} drm_stats_t;
-
/**
* Hardware locking flags.
*/
typedef enum drm_lock_flags {
- _DRM_LOCK_READY = 0x01, /**< Wait until hardware is ready for DMA */
- _DRM_LOCK_QUIESCENT = 0x02, /**< Wait until hardware quiescent */
- _DRM_LOCK_FLUSH = 0x04, /**< Flush this context's DMA queue first */
- _DRM_LOCK_FLUSH_ALL = 0x08, /**< Flush all DMA queues first */
- /* These *HALT* flags aren't supported yet
- -- they will be used to support the
- full-screen DGA-like mode. */
+ _DRM_LOCK_READY = 0x01, /**< Wait until hardware is ready for DMA */
+ _DRM_LOCK_QUIESCENT = 0x02, /**< Wait until hardware quiescent */
+ _DRM_LOCK_FLUSH = 0x04, /**< Flush this context's DMA queue first */
+ _DRM_LOCK_FLUSH_ALL = 0x08, /**< Flush all DMA queues first */
+ /* These *HALT* flags aren't supported yet
+ -- they will be used to support the
+ full-screen DGA-like mode. */
_DRM_HALT_ALL_QUEUES = 0x10, /**< Halt all current and future queues */
_DRM_HALT_CUR_QUEUES = 0x20 /**< Halt all current queues */
} drm_lock_flags_t;
-
/**
* DRM_IOCTL_LOCK, DRM_IOCTL_UNLOCK and DRM_IOCTL_FINISH ioctl argument type.
- *
+ *
* \sa drmGetLock() and drmUnlock().
*/
typedef struct drm_lock {
- int context;
+ int context;
drm_lock_flags_t flags;
} drm_lock_t;
-
/**
* DMA flags
*
- * \warning
+ * \warning
* These values \e must match xf86drm.h.
*
* \sa drm_dma.
*/
-typedef enum drm_dma_flags {
- /* Flags for DMA buffer dispatch */
- _DRM_DMA_BLOCK = 0x01, /**<
+typedef enum drm_dma_flags {
+ /* Flags for DMA buffer dispatch */
+ _DRM_DMA_BLOCK = 0x01, /**<
* Block until buffer dispatched.
- *
+ *
* \note The buffer may not yet have
* been processed by the hardware --
* getting a hardware lock with the
@@ -347,79 +327,73 @@ typedef enum drm_dma_flags {
* processed.
*/
_DRM_DMA_WHILE_LOCKED = 0x02, /**< Dispatch while lock held */
- _DRM_DMA_PRIORITY = 0x04, /**< High priority dispatch */
+ _DRM_DMA_PRIORITY = 0x04, /**< High priority dispatch */
- /* Flags for DMA buffer request */
- _DRM_DMA_WAIT = 0x10, /**< Wait for free buffers */
- _DRM_DMA_SMALLER_OK = 0x20, /**< Smaller-than-requested buffers OK */
- _DRM_DMA_LARGER_OK = 0x40 /**< Larger-than-requested buffers OK */
+ /* Flags for DMA buffer request */
+ _DRM_DMA_WAIT = 0x10, /**< Wait for free buffers */
+ _DRM_DMA_SMALLER_OK = 0x20, /**< Smaller-than-requested buffers OK */
+ _DRM_DMA_LARGER_OK = 0x40 /**< Larger-than-requested buffers OK */
} drm_dma_flags_t;
-
/**
* DRM_IOCTL_ADD_BUFS and DRM_IOCTL_MARK_BUFS ioctl argument type.
*
* \sa drmAddBufs().
*/
typedef struct drm_buf_desc {
- int count; /**< Number of buffers of this size */
- int size; /**< Size in bytes */
- int low_mark; /**< Low water mark */
- int high_mark; /**< High water mark */
+ int count; /**< Number of buffers of this size */
+ int size; /**< Size in bytes */
+ int low_mark; /**< Low water mark */
+ int high_mark; /**< High water mark */
enum {
- _DRM_PAGE_ALIGN = 0x01, /**< Align on page boundaries for DMA */
- _DRM_AGP_BUFFER = 0x02, /**< Buffer is in AGP space */
- _DRM_SG_BUFFER = 0x04, /**< Scatter/gather memory buffer */
- _DRM_FB_BUFFER = 0x08 /**< Buffer is in frame buffer */
- } flags;
- unsigned long agp_start; /**<
+ _DRM_PAGE_ALIGN = 0x01, /**< Align on page boundaries for DMA */
+ _DRM_AGP_BUFFER = 0x02, /**< Buffer is in AGP space */
+ _DRM_SG_BUFFER = 0x04, /**< Scatter/gather memory buffer */
+ _DRM_FB_BUFFER = 0x08 /**< Buffer is in frame buffer */
+ } flags;
+ unsigned long agp_start; /**<
* Start address of where the AGP buffers are
* in the AGP aperture
*/
} drm_buf_desc_t;
-
/**
* DRM_IOCTL_INFO_BUFS ioctl argument type.
*/
typedef struct drm_buf_info {
- int count; /**< Entries in list */
+ int count; /**< Entries in list */
drm_buf_desc_t __user *list;
} drm_buf_info_t;
-
/**
* DRM_IOCTL_FREE_BUFS ioctl argument type.
*/
typedef struct drm_buf_free {
- int count;
- int __user *list;
+ int count;
+ int __user *list;
} drm_buf_free_t;
-
/**
* Buffer information
*
* \sa drm_buf_map.
*/
typedef struct drm_buf_pub {
- int idx; /**< Index into the master buffer list */
- int total; /**< Buffer size */
- int used; /**< Amount of buffer in use (for DMA) */
- void __user *address; /**< Address of buffer */
+ int idx; /**< Index into the master buffer list */
+ int total; /**< Buffer size */
+ int used; /**< Amount of buffer in use (for DMA) */
+ void __user *address; /**< Address of buffer */
} drm_buf_pub_t;
-
/**
* DRM_IOCTL_MAP_BUFS ioctl argument type.
*/
typedef struct drm_buf_map {
- int count; /**< Length of the buffer list */
- void __user *virtual; /**< Mmap'd area in user-virtual */
+ int count; /**< Length of the buffer list */
+ void __user *virtual; /**< Mmap'd area in user-virtual */
drm_buf_pub_t __user *list; /**< Buffer information */
} drm_buf_map_t;
-
/**
* DRM_IOCTL_DMA ioctl argument type.
*
@@ -428,61 +402,55 @@ typedef struct drm_buf_map {
* \sa drmDMA().
*/
typedef struct drm_dma {
- int context; /**< Context handle */
- int send_count; /**< Number of buffers to send */
- int __user *send_indices; /**< List of handles to buffers */
- int __user *send_sizes; /**< Lengths of data to send */
+ int context; /**< Context handle */
+ int send_count; /**< Number of buffers to send */
+ int __user *send_indices; /**< List of handles to buffers */
+ int __user *send_sizes; /**< Lengths of data to send */
drm_dma_flags_t flags; /**< Flags */
- int request_count; /**< Number of buffers requested */
- int request_size; /**< Desired size for buffers */
- int __user *request_indices; /**< Buffer information */
- int __user *request_sizes;
- int granted_count; /**< Number of buffers granted */
+ int request_count; /**< Number of buffers requested */
+ int request_size; /**< Desired size for buffers */
+ int __user *request_indices; /**< Buffer information */
+ int __user *request_sizes;
+ int granted_count; /**< Number of buffers granted */
} drm_dma_t;
-
typedef enum {
_DRM_CONTEXT_PRESERVED = 0x01,
- _DRM_CONTEXT_2DONLY = 0x02
+ _DRM_CONTEXT_2DONLY = 0x02
} drm_ctx_flags_t;
-
/**
* DRM_IOCTL_ADD_CTX ioctl argument type.
*
* \sa drmCreateContext() and drmDestroyContext().
*/
typedef struct drm_ctx {
- drm_context_t handle;
+ drm_context_t handle;
drm_ctx_flags_t flags;
} drm_ctx_t;
-
/**
* DRM_IOCTL_RES_CTX ioctl argument type.
*/
typedef struct drm_ctx_res {
- int count;
- drm_ctx_t __user *contexts;
+ int count;
+ drm_ctx_t __user *contexts;
} drm_ctx_res_t;
-
/**
* DRM_IOCTL_ADD_DRAW and DRM_IOCTL_RM_DRAW ioctl argument type.
*/
typedef struct drm_draw {
- drm_drawable_t handle;
+ drm_drawable_t handle;
} drm_draw_t;
-
/**
* DRM_IOCTL_GET_MAGIC and DRM_IOCTL_AUTH_MAGIC ioctl argument type.
*/
typedef struct drm_auth {
- drm_magic_t magic;
+ drm_magic_t magic;
} drm_auth_t;
-
/**
* DRM_IOCTL_IRQ_BUSID ioctl argument type.
*
@@ -495,24 +463,20 @@ typedef struct drm_irq_busid {
int funcnum; /**< function number */
} drm_irq_busid_t;
-
typedef enum {
- _DRM_VBLANK_ABSOLUTE = 0x0, /**< Wait for specific vblank sequence number */
- _DRM_VBLANK_RELATIVE = 0x1, /**< Wait for given number of vblanks */
- _DRM_VBLANK_SIGNAL = 0x40000000 /**< Send signal instead of blocking */
+ _DRM_VBLANK_ABSOLUTE = 0x0, /**< Wait for specific vblank sequence number */
+ _DRM_VBLANK_RELATIVE = 0x1, /**< Wait for given number of vblanks */
+ _DRM_VBLANK_SIGNAL = 0x40000000 /**< Send signal instead of blocking */
} drm_vblank_seq_type_t;
-
#define _DRM_VBLANK_FLAGS_MASK _DRM_VBLANK_SIGNAL
-
struct drm_wait_vblank_request {
drm_vblank_seq_type_t type;
unsigned int sequence;
unsigned long signal;
};
-
struct drm_wait_vblank_reply {
drm_vblank_seq_type_t type;
unsigned int sequence;
@@ -520,7 +484,6 @@ struct drm_wait_vblank_reply {
long tval_usec;
};
-
/**
* DRM_IOCTL_WAIT_VBLANK ioctl argument type.
*
@@ -531,7 +494,6 @@ typedef union drm_wait_vblank {
struct drm_wait_vblank_reply reply;
} drm_wait_vblank_t;
-
/**
* DRM_IOCTL_AGP_ENABLE ioctl argument type.
*
@@ -541,7 +503,6 @@ typedef struct drm_agp_mode {
unsigned long mode; /**< AGP mode */
} drm_agp_mode_t;
-
/**
* DRM_IOCTL_AGP_ALLOC and DRM_IOCTL_AGP_FREE ioctls argument type.
*
@@ -550,22 +511,20 @@ typedef struct drm_agp_mode {
typedef struct drm_agp_buffer {
unsigned long size; /**< In bytes -- will round to page boundary */
unsigned long handle; /**< Used for binding / unbinding */
- unsigned long type; /**< Type of memory to allocate */
- unsigned long physical; /**< Physical used by i810 */
+ unsigned long type; /**< Type of memory to allocate */
+ unsigned long physical; /**< Physical used by i810 */
} drm_agp_buffer_t;
-
/**
* DRM_IOCTL_AGP_BIND and DRM_IOCTL_AGP_UNBIND ioctls argument type.
*
* \sa drmAgpBind() and drmAgpUnbind().
*/
typedef struct drm_agp_binding {
- unsigned long handle; /**< From drm_agp_buffer */
+ unsigned long handle; /**< From drm_agp_buffer */
unsigned long offset; /**< In bytes -- will round to page boundary */
} drm_agp_binding_t;
-
/**
* DRM_IOCTL_AGP_INFO ioctl argument type.
*
@@ -574,20 +533,19 @@ typedef struct drm_agp_binding {
* drmAgpVendorId() and drmAgpDeviceId().
*/
typedef struct drm_agp_info {
- int agp_version_major;
- int agp_version_minor;
- unsigned long mode;
- unsigned long aperture_base; /* physical address */
- unsigned long aperture_size; /* bytes */
- unsigned long memory_allowed; /* bytes */
- unsigned long memory_used;
-
- /* PCI information */
+ int agp_version_major;
+ int agp_version_minor;
+ unsigned long mode;
+ unsigned long aperture_base; /* physical address */
+ unsigned long aperture_size; /* bytes */
+ unsigned long memory_allowed; /* bytes */
+ unsigned long memory_used;
+
+ /* PCI information */
unsigned short id_vendor;
unsigned short id_device;
} drm_agp_info_t;
-
/**
* DRM_IOCTL_SG_ALLOC ioctl argument type.
*/
@@ -606,7 +564,6 @@ typedef struct drm_set_version {
int drm_dd_minor;
} drm_set_version_t;
-
#define DRM_IOCTL_BASE 'd'
#define DRM_IO(nr) _IO(DRM_IOCTL_BASE,nr)
#define DRM_IOR(nr,type) _IOR(DRM_IOCTL_BASE,nr,type)
diff --git a/drivers/char/drm/drmP.h b/drivers/char/drm/drmP.h
index 121cc85f347e..3dc3c9d79ae4 100644
--- a/drivers/char/drm/drmP.h
+++ b/drivers/char/drm/drmP.h
@@ -1,7 +1,7 @@
/**
- * \file drmP.h
+ * \file drmP.h
* Private header for Direct Rendering Manager
- *
+ *
* \author Rickard E. (Rik) Faith <faith@valinux.com>
* \author Gareth Hughes <gareth@valinux.com>
*/
@@ -43,7 +43,7 @@
* before static inline funcs in wait.h. Doing this so we
* can build the DRM (part of PI DRI). 4/21/2000 S + B */
#include <asm/current.h>
-#endif /* __alpha__ */
+#endif /* __alpha__ */
#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
@@ -58,7 +58,7 @@
#include <linux/mm.h>
#include <linux/cdev.h>
#if defined(__alpha__) || defined(__powerpc__)
-#include <asm/pgtable.h> /* For pte_wrprotect */
+#include <asm/pgtable.h> /* For pte_wrprotect */
#endif
#include <asm/io.h>
#include <asm/mman.h>
@@ -108,7 +108,6 @@
#define DRM_KERNEL_CONTEXT 0 /**< Change drm_resctx if changed */
#define DRM_RESERVED_CONTEXTS 1 /**< Change drm_resctx if changed */
#define DRM_LOOPING_LIMIT 5000000
-#define DRM_BSZ 1024 /**< Buffer size for /dev/drm? output */
#define DRM_TIME_SLICE (HZ/20) /**< Time slice for GLXContexts */
#define DRM_LOCK_SLICE 1 /**< Time slice for lock, in jiffies */
@@ -138,16 +137,15 @@
#define DRM_MEM_CTXLIST 21
#define DRM_MAX_CTXBITMAP (PAGE_SIZE * 8)
-
-/*@}*/
+/*@}*/
/***********************************************************************/
/** \name Backward compatibility section */
/*@{*/
#ifndef MODULE_LICENSE
-#define MODULE_LICENSE(x)
+#define MODULE_LICENSE(x)
#endif
#ifndef preempt_disable
@@ -155,7 +153,7 @@
#define preempt_enable()
#endif
-#ifndef pte_offset_map
+#ifndef pte_offset_map
#define pte_offset_map pte_offset
#define pte_unmap(pte)
#endif
@@ -166,7 +164,6 @@
/*@}*/
-
/***********************************************************************/
/** \name Macros to make printk easier */
/*@{*/
@@ -195,7 +192,7 @@
/**
* Debug output.
- *
+ *
* \param fmt printf() like format string.
* \param arg arguments
*/
@@ -223,14 +220,13 @@
/*@}*/
-
/***********************************************************************/
/** \name Internal types and structures */
/*@{*/
-#define DRM_ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
-#define DRM_MIN(a,b) ((a)<(b)?(a):(b))
-#define DRM_MAX(a,b) ((a)>(b)?(a):(b))
+#define DRM_ARRAY_SIZE(x) ARRAY_SIZE(x)
+#define DRM_MIN(a,b) min(a,b)
+#define DRM_MAX(a,b) max(a,b)
#define DRM_LEFTCOUNT(x) (((x)->rp + (x)->count - (x)->wp) % ((x)->count + 1))
#define DRM_BUFCOUNT(x) ((x)->count - DRM_LEFTCOUNT(x))
@@ -275,7 +271,7 @@ do { \
if ( copy_to_user( name, value, len ) ) \
return -EFAULT; \
}
-
+
/**
* Ioctl function type.
*
@@ -284,25 +280,25 @@ do { \
* \param cmd command.
* \param arg argument.
*/
-typedef int drm_ioctl_t( struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg );
+typedef int drm_ioctl_t(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg);
typedef int drm_ioctl_compat_t(struct file *filp, unsigned int cmd,
unsigned long arg);
typedef struct drm_ioctl_desc {
- drm_ioctl_t *func;
- int auth_needed;
- int root_only;
+ drm_ioctl_t *func;
+ int auth_needed;
+ int root_only;
} drm_ioctl_desc_t;
typedef struct drm_devstate {
- pid_t owner; /**< X server pid holding x_lock */
+ pid_t owner; /**< X server pid holding x_lock */
} drm_devstate_t;
typedef struct drm_magic_entry {
- drm_magic_t magic;
- struct drm_file *priv;
+ drm_magic_t magic;
+ struct drm_file *priv;
struct drm_magic_entry *next;
} drm_magic_entry_t;
@@ -313,111 +309,110 @@ typedef struct drm_magic_head {
typedef struct drm_vma_entry {
struct vm_area_struct *vma;
- struct drm_vma_entry *next;
- pid_t pid;
+ struct drm_vma_entry *next;
+ pid_t pid;
} drm_vma_entry_t;
/**
* DMA buffer.
*/
typedef struct drm_buf {
- int idx; /**< Index into master buflist */
- int total; /**< Buffer size */
- int order; /**< log-base-2(total) */
- int used; /**< Amount of buffer in use (for DMA) */
- unsigned long offset; /**< Byte offset (used internally) */
- void *address; /**< Address of buffer */
- unsigned long bus_address; /**< Bus address of buffer */
- struct drm_buf *next; /**< Kernel-only: used for free list */
- __volatile__ int waiting; /**< On kernel DMA queue */
- __volatile__ int pending; /**< On hardware DMA queue */
+ int idx; /**< Index into master buflist */
+ int total; /**< Buffer size */
+ int order; /**< log-base-2(total) */
+ int used; /**< Amount of buffer in use (for DMA) */
+ unsigned long offset; /**< Byte offset (used internally) */
+ void *address; /**< Address of buffer */
+ unsigned long bus_address; /**< Bus address of buffer */
+ struct drm_buf *next; /**< Kernel-only: used for free list */
+ __volatile__ int waiting; /**< On kernel DMA queue */
+ __volatile__ int pending; /**< On hardware DMA queue */
wait_queue_head_t dma_wait; /**< Processes waiting */
- struct file *filp; /**< Pointer to holding file descr */
- int context; /**< Kernel queue for this buffer */
- int while_locked;/**< Dispatch this buffer while locked */
+ struct file *filp; /**< Pointer to holding file descr */
+ int context; /**< Kernel queue for this buffer */
+ int while_locked; /**< Dispatch this buffer while locked */
enum {
- DRM_LIST_NONE = 0,
- DRM_LIST_FREE = 1,
- DRM_LIST_WAIT = 2,
- DRM_LIST_PEND = 3,
- DRM_LIST_PRIO = 4,
+ DRM_LIST_NONE = 0,
+ DRM_LIST_FREE = 1,
+ DRM_LIST_WAIT = 2,
+ DRM_LIST_PEND = 3,
+ DRM_LIST_PRIO = 4,
DRM_LIST_RECLAIM = 5
- } list; /**< Which list we're on */
+ } list; /**< Which list we're on */
- int dev_priv_size; /**< Size of buffer private storage */
- void *dev_private; /**< Per-buffer private storage */
+ int dev_priv_size; /**< Size of buffer private storage */
+ void *dev_private; /**< Per-buffer private storage */
} drm_buf_t;
-
/** bufs is one longer than it has to be */
typedef struct drm_waitlist {
- int count; /**< Number of possible buffers */
- drm_buf_t **bufs; /**< List of pointers to buffers */
- drm_buf_t **rp; /**< Read pointer */
- drm_buf_t **wp; /**< Write pointer */
- drm_buf_t **end; /**< End pointer */
- spinlock_t read_lock;
- spinlock_t write_lock;
+ int count; /**< Number of possible buffers */
+ drm_buf_t **bufs; /**< List of pointers to buffers */
+ drm_buf_t **rp; /**< Read pointer */
+ drm_buf_t **wp; /**< Write pointer */
+ drm_buf_t **end; /**< End pointer */
+ spinlock_t read_lock;
+ spinlock_t write_lock;
} drm_waitlist_t;
typedef struct drm_freelist {
- int initialized; /**< Freelist in use */
- atomic_t count; /**< Number of free buffers */
- drm_buf_t *next; /**< End pointer */
+ int initialized; /**< Freelist in use */
+ atomic_t count; /**< Number of free buffers */
+ drm_buf_t *next; /**< End pointer */
wait_queue_head_t waiting; /**< Processes waiting on free bufs */
- int low_mark; /**< Low water mark */
- int high_mark; /**< High water mark */
- atomic_t wfh; /**< If waiting for high mark */
- spinlock_t lock;
+ int low_mark; /**< Low water mark */
+ int high_mark; /**< High water mark */
+ atomic_t wfh; /**< If waiting for high mark */
+ spinlock_t lock;
} drm_freelist_t;
/**
* Buffer entry. There is one of this for each buffer size order.
*/
typedef struct drm_buf_entry {
- int buf_size; /**< size */
- int buf_count; /**< number of buffers */
- drm_buf_t *buflist; /**< buffer list */
- int seg_count;
- int page_order;
- unsigned long *seglist;
-
- drm_freelist_t freelist;
+ int buf_size; /**< size */
+ int buf_count; /**< number of buffers */
+ drm_buf_t *buflist; /**< buffer list */
+ int seg_count;
+ int page_order;
+ unsigned long *seglist;
+
+ drm_freelist_t freelist;
} drm_buf_entry_t;
/** File private data */
typedef struct drm_file {
- int authenticated;
- int minor;
- pid_t pid;
- uid_t uid;
- drm_magic_t magic;
- unsigned long ioctl_count;
- struct drm_file *next;
- struct drm_file *prev;
- struct drm_head *head;
- int remove_auth_on_close;
- unsigned long lock_count;
- void *driver_priv;
+ int authenticated;
+ int minor;
+ pid_t pid;
+ uid_t uid;
+ drm_magic_t magic;
+ unsigned long ioctl_count;
+ struct drm_file *next;
+ struct drm_file *prev;
+ struct drm_head *head;
+ int remove_auth_on_close;
+ unsigned long lock_count;
+ void *driver_priv;
} drm_file_t;
/** Wait queue */
typedef struct drm_queue {
- atomic_t use_count; /**< Outstanding uses (+1) */
- atomic_t finalization; /**< Finalization in progress */
- atomic_t block_count; /**< Count of processes waiting */
- atomic_t block_read; /**< Queue blocked for reads */
+ atomic_t use_count; /**< Outstanding uses (+1) */
+ atomic_t finalization; /**< Finalization in progress */
+ atomic_t block_count; /**< Count of processes waiting */
+ atomic_t block_read; /**< Queue blocked for reads */
wait_queue_head_t read_queue; /**< Processes waiting on block_read */
- atomic_t block_write; /**< Queue blocked for writes */
+ atomic_t block_write; /**< Queue blocked for writes */
wait_queue_head_t write_queue; /**< Processes waiting on block_write */
#if 1
- atomic_t total_queued; /**< Total queued statistic */
- atomic_t total_flushed;/**< Total flushes statistic */
- atomic_t total_locks; /**< Total locks statistics */
+ atomic_t total_queued; /**< Total queued statistic */
+ atomic_t total_flushed; /**< Total flushes statistic */
+ atomic_t total_locks; /**< Total locks statistics */
#endif
- drm_ctx_flags_t flags; /**< Context preserving and 2D-only */
- drm_waitlist_t waitlist; /**< Pending buffers */
+ drm_ctx_flags_t flags; /**< Context preserving and 2D-only */
+ drm_waitlist_t waitlist; /**< Pending buffers */
wait_queue_head_t flush_queue; /**< Processes waiting until flush */
} drm_queue_t;
@@ -425,10 +420,10 @@ typedef struct drm_queue {
* Lock data.
*/
typedef struct drm_lock_data {
- drm_hw_lock_t *hw_lock; /**< Hardware lock */
- struct file *filp; /**< File descr of lock holder (0=kernel) */
+ drm_hw_lock_t *hw_lock; /**< Hardware lock */
+ struct file *filp; /**< File descr of lock holder (0=kernel) */
wait_queue_head_t lock_queue; /**< Queue of blocked processes */
- unsigned long lock_time; /**< Time of last lock in jiffies */
+ unsigned long lock_time; /**< Time of last lock in jiffies */
} drm_lock_data_t;
/**
@@ -436,29 +431,29 @@ typedef struct drm_lock_data {
*/
typedef struct drm_device_dma {
- drm_buf_entry_t bufs[DRM_MAX_ORDER+1]; /**< buffers, grouped by their size order */
- int buf_count; /**< total number of buffers */
- drm_buf_t **buflist; /**< Vector of pointers into drm_device_dma::bufs */
- int seg_count;
- int page_count; /**< number of pages */
- unsigned long *pagelist; /**< page list */
- unsigned long byte_count;
+ drm_buf_entry_t bufs[DRM_MAX_ORDER + 1]; /**< buffers, grouped by their size order */
+ int buf_count; /**< total number of buffers */
+ drm_buf_t **buflist; /**< Vector of pointers into drm_device_dma::bufs */
+ int seg_count;
+ int page_count; /**< number of pages */
+ unsigned long *pagelist; /**< page list */
+ unsigned long byte_count;
enum {
_DRM_DMA_USE_AGP = 0x01,
- _DRM_DMA_USE_SG = 0x02,
- _DRM_DMA_USE_FB = 0x04
+ _DRM_DMA_USE_SG = 0x02,
+ _DRM_DMA_USE_FB = 0x04
} flags;
} drm_device_dma_t;
-/**
+/**
* AGP memory entry. Stored as a doubly linked list.
*/
typedef struct drm_agp_mem {
- unsigned long handle; /**< handle */
- DRM_AGP_MEM *memory;
- unsigned long bound; /**< address */
- int pages;
+ unsigned long handle; /**< handle */
+ DRM_AGP_MEM *memory;
+ unsigned long bound; /**< address */
+ int pages;
struct drm_agp_mem *prev; /**< previous entry */
struct drm_agp_mem *next; /**< next entry */
} drm_agp_mem_t;
@@ -469,31 +464,31 @@ typedef struct drm_agp_mem {
* \sa drm_agp_init() and drm_device::agp.
*/
typedef struct drm_agp_head {
- DRM_AGP_KERN agp_info; /**< AGP device information */
- drm_agp_mem_t *memory; /**< memory entries */
- unsigned long mode; /**< AGP mode */
- struct agp_bridge_data *bridge;
- int enabled; /**< whether the AGP bus as been enabled */
- int acquired; /**< whether the AGP device has been acquired */
- unsigned long base;
- int agp_mtrr;
- int cant_use_aperture;
- unsigned long page_mask;
+ DRM_AGP_KERN agp_info; /**< AGP device information */
+ drm_agp_mem_t *memory; /**< memory entries */
+ unsigned long mode; /**< AGP mode */
+ struct agp_bridge_data *bridge;
+ int enabled; /**< whether the AGP bus as been enabled */
+ int acquired; /**< whether the AGP device has been acquired */
+ unsigned long base;
+ int agp_mtrr;
+ int cant_use_aperture;
+ unsigned long page_mask;
} drm_agp_head_t;
/**
* Scatter-gather memory.
*/
typedef struct drm_sg_mem {
- unsigned long handle;
- void *virtual;
- int pages;
- struct page **pagelist;
- dma_addr_t *busaddr;
+ unsigned long handle;
+ void *virtual;
+ int pages;
+ struct page **pagelist;
+ dma_addr_t *busaddr;
} drm_sg_mem_t;
typedef struct drm_sigdata {
- int context;
+ int context;
drm_hw_lock_t *lock;
} drm_sigdata_t;
@@ -507,8 +502,8 @@ typedef struct drm_dma_handle {
* Mappings list
*/
typedef struct drm_map_list {
- struct list_head head; /**< list head */
- drm_map_t *map; /**< mapping */
+ struct list_head head; /**< list head */
+ drm_map_t *map; /**< mapping */
unsigned int user_token;
} drm_map_list_t;
@@ -518,19 +513,28 @@ typedef drm_map_t drm_local_map_t;
* Context handle list
*/
typedef struct drm_ctx_list {
- struct list_head head; /**< list head */
- drm_context_t handle; /**< context handle */
- drm_file_t *tag; /**< associated fd private data */
+ struct list_head head; /**< list head */
+ drm_context_t handle; /**< context handle */
+ drm_file_t *tag; /**< associated fd private data */
} drm_ctx_list_t;
-
typedef struct drm_vbl_sig {
- struct list_head head;
- unsigned int sequence;
- struct siginfo info;
- struct task_struct *task;
+ struct list_head head;
+ unsigned int sequence;
+ struct siginfo info;
+ struct task_struct *task;
} drm_vbl_sig_t;
+/* location of GART table */
+#define DRM_ATI_GART_MAIN 1
+#define DRM_ATI_GART_FB 2
+
+typedef struct ati_pcigart_info {
+ int gart_table_location;
+ int is_pcie;
+ unsigned long addr;
+ dma_addr_t bus_addr;
+} drm_ati_pcigart_info;
/**
* DRM driver structure. This structure represent the common code for
@@ -540,24 +544,26 @@ typedef struct drm_vbl_sig {
struct drm_device;
struct drm_driver {
- int (*preinit)(struct drm_device *, unsigned long flags);
- void (*prerelease)(struct drm_device *, struct file *filp);
- void (*pretakedown)(struct drm_device *);
- int (*postcleanup)(struct drm_device *);
- int (*presetup)(struct drm_device *);
- int (*postsetup)(struct drm_device *);
- int (*dma_ioctl)( DRM_IOCTL_ARGS );
- int (*open_helper)(struct drm_device *, drm_file_t *);
- void (*free_filp_priv)(struct drm_device *, drm_file_t *);
- void (*release)(struct drm_device *, struct file *filp);
- void (*dma_ready)(struct drm_device *);
- int (*dma_quiescent)(struct drm_device *);
- int (*context_ctor)(struct drm_device *dev, int context);
- int (*context_dtor)(struct drm_device *dev, int context);
- int (*kernel_context_switch)(struct drm_device *dev, int old, int new);
- void (*kernel_context_switch_unlock)(struct drm_device *dev, drm_lock_t *lock);
- int (*vblank_wait)(struct drm_device *dev, unsigned int *sequence);
-
+ int (*preinit) (struct drm_device *, unsigned long flags);
+ void (*prerelease) (struct drm_device *, struct file * filp);
+ void (*pretakedown) (struct drm_device *);
+ int (*postcleanup) (struct drm_device *);
+ int (*presetup) (struct drm_device *);
+ int (*postsetup) (struct drm_device *);
+ int (*dma_ioctl) (DRM_IOCTL_ARGS);
+ int (*open_helper) (struct drm_device *, drm_file_t *);
+ void (*free_filp_priv) (struct drm_device *, drm_file_t *);
+ void (*release) (struct drm_device *, struct file * filp);
+ void (*dma_ready) (struct drm_device *);
+ int (*dma_quiescent) (struct drm_device *);
+ int (*context_ctor) (struct drm_device * dev, int context);
+ int (*context_dtor) (struct drm_device * dev, int context);
+ int (*kernel_context_switch) (struct drm_device * dev, int old,
+ int new);
+ void (*kernel_context_switch_unlock) (struct drm_device * dev,
+ drm_lock_t * lock);
+ int (*vblank_wait) (struct drm_device * dev, unsigned int *sequence);
+
/**
* Called by \c drm_device_is_agp. Typically used to determine if a
* card is really attached to AGP or not.
@@ -572,17 +578,17 @@ struct drm_driver {
int (*device_is_agp) (struct drm_device * dev);
/* these have to be filled in */
-
- int (*postinit)(struct drm_device *, unsigned long flags);
- irqreturn_t (*irq_handler)( DRM_IRQ_ARGS );
- void (*irq_preinstall)(struct drm_device *dev);
- void (*irq_postinstall)(struct drm_device *dev);
- void (*irq_uninstall)(struct drm_device *dev);
- void (*reclaim_buffers)(struct drm_device *dev, struct file *filp);
- unsigned long (*get_map_ofs)(drm_map_t *map);
- unsigned long (*get_reg_ofs)(struct drm_device *dev);
- void (*set_version)(struct drm_device *dev, drm_set_version_t *sv);
- int (*version)(drm_version_t *version);
+
+ int (*postinit) (struct drm_device *, unsigned long flags);
+ irqreturn_t(*irq_handler) (DRM_IRQ_ARGS);
+ void (*irq_preinstall) (struct drm_device * dev);
+ void (*irq_postinstall) (struct drm_device * dev);
+ void (*irq_uninstall) (struct drm_device * dev);
+ void (*reclaim_buffers) (struct drm_device * dev, struct file * filp);
+ unsigned long (*get_map_ofs) (drm_map_t * map);
+ unsigned long (*get_reg_ofs) (struct drm_device * dev);
+ void (*set_version) (struct drm_device * dev, drm_set_version_t * sv);
+ int (*version) (drm_version_t * version);
u32 driver_features;
int dev_priv_size;
drm_ioctl_desc_t *ioctls;
@@ -609,128 +615,125 @@ typedef struct drm_head {
* may contain multiple heads.
*/
typedef struct drm_device {
- char *unique; /**< Unique identifier: e.g., busid */
- int unique_len; /**< Length of unique field */
- char *devname; /**< For /proc/interrupts */
- int if_version; /**< Highest interface version set */
+ char *unique; /**< Unique identifier: e.g., busid */
+ int unique_len; /**< Length of unique field */
+ char *devname; /**< For /proc/interrupts */
+ int if_version; /**< Highest interface version set */
- int blocked; /**< Blocked due to VC switch? */
+ int blocked; /**< Blocked due to VC switch? */
/** \name Locks */
- /*@{*/
- spinlock_t count_lock; /**< For inuse, drm_device::open_count, drm_device::buf_use */
- struct semaphore struct_sem; /**< For others */
- /*@}*/
+ /*@{ */
+ spinlock_t count_lock; /**< For inuse, drm_device::open_count, drm_device::buf_use */
+ struct semaphore struct_sem; /**< For others */
+ /*@} */
/** \name Usage Counters */
- /*@{*/
- int open_count; /**< Outstanding files open */
- atomic_t ioctl_count; /**< Outstanding IOCTLs pending */
- atomic_t vma_count; /**< Outstanding vma areas open */
- int buf_use; /**< Buffers in use -- cannot alloc */
- atomic_t buf_alloc; /**< Buffer allocation in progress */
- /*@}*/
+ /*@{ */
+ int open_count; /**< Outstanding files open */
+ atomic_t ioctl_count; /**< Outstanding IOCTLs pending */
+ atomic_t vma_count; /**< Outstanding vma areas open */
+ int buf_use; /**< Buffers in use -- cannot alloc */
+ atomic_t buf_alloc; /**< Buffer allocation in progress */
+ /*@} */
/** \name Performance counters */
- /*@{*/
- unsigned long counters;
- drm_stat_type_t types[15];
- atomic_t counts[15];
- /*@}*/
+ /*@{ */
+ unsigned long counters;
+ drm_stat_type_t types[15];
+ atomic_t counts[15];
+ /*@} */
/** \name Authentication */
- /*@{*/
- drm_file_t *file_first; /**< file list head */
- drm_file_t *file_last; /**< file list tail */
- drm_magic_head_t magiclist[DRM_HASH_SIZE]; /**< magic hash table */
- /*@}*/
+ /*@{ */
+ drm_file_t *file_first; /**< file list head */
+ drm_file_t *file_last; /**< file list tail */
+ drm_magic_head_t magiclist[DRM_HASH_SIZE]; /**< magic hash table */
+ /*@} */
/** \name Memory management */
- /*@{*/
- drm_map_list_t *maplist; /**< Linked list of regions */
- int map_count; /**< Number of mappable regions */
+ /*@{ */
+ drm_map_list_t *maplist; /**< Linked list of regions */
+ int map_count; /**< Number of mappable regions */
/** \name Context handle management */
- /*@{*/
- drm_ctx_list_t *ctxlist; /**< Linked list of context handles */
- int ctx_count; /**< Number of context handles */
- struct semaphore ctxlist_sem; /**< For ctxlist */
+ /*@{ */
+ drm_ctx_list_t *ctxlist; /**< Linked list of context handles */
+ int ctx_count; /**< Number of context handles */
+ struct semaphore ctxlist_sem; /**< For ctxlist */
- drm_map_t **context_sareas; /**< per-context SAREA's */
- int max_context;
+ drm_map_t **context_sareas; /**< per-context SAREA's */
+ int max_context;
- drm_vma_entry_t *vmalist; /**< List of vmas (for debugging) */
- drm_lock_data_t lock; /**< Information on hardware lock */
- /*@}*/
+ drm_vma_entry_t *vmalist; /**< List of vmas (for debugging) */
+ drm_lock_data_t lock; /**< Information on hardware lock */
+ /*@} */
/** \name DMA queues (contexts) */
- /*@{*/
- int queue_count; /**< Number of active DMA queues */
- int queue_reserved; /**< Number of reserved DMA queues */
- int queue_slots; /**< Actual length of queuelist */
- drm_queue_t **queuelist; /**< Vector of pointers to DMA queues */
- drm_device_dma_t *dma; /**< Optional pointer for DMA support */
- /*@}*/
+ /*@{ */
+ int queue_count; /**< Number of active DMA queues */
+ int queue_reserved; /**< Number of reserved DMA queues */
+ int queue_slots; /**< Actual length of queuelist */
+ drm_queue_t **queuelist; /**< Vector of pointers to DMA queues */
+ drm_device_dma_t *dma; /**< Optional pointer for DMA support */
+ /*@} */
/** \name Context support */
- /*@{*/
- int irq; /**< Interrupt used by board */
- int irq_enabled; /**< True if irq handler is enabled */
+ /*@{ */
+ int irq; /**< Interrupt used by board */
+ int irq_enabled; /**< True if irq handler is enabled */
__volatile__ long context_flag; /**< Context swapping flag */
__volatile__ long interrupt_flag; /**< Interruption handler flag */
__volatile__ long dma_flag; /**< DMA dispatch flag */
struct timer_list timer; /**< Timer for delaying ctx switch */
- wait_queue_head_t context_wait; /**< Processes waiting on ctx switch */
- int last_checked; /**< Last context checked for DMA */
- int last_context; /**< Last current context */
- unsigned long last_switch; /**< jiffies at last context switch */
- /*@}*/
-
- struct work_struct work;
+ wait_queue_head_t context_wait; /**< Processes waiting on ctx switch */
+ int last_checked; /**< Last context checked for DMA */
+ int last_context; /**< Last current context */
+ unsigned long last_switch; /**< jiffies at last context switch */
+ /*@} */
+
+ struct work_struct work;
/** \name VBLANK IRQ support */
- /*@{*/
-
- wait_queue_head_t vbl_queue; /**< VBLANK wait queue */
- atomic_t vbl_received;
- spinlock_t vbl_lock;
- drm_vbl_sig_t vbl_sigs; /**< signal list to send on VBLANK */
- unsigned int vbl_pending;
-
- /*@}*/
- cycles_t ctx_start;
- cycles_t lck_start;
-
- char buf[DRM_BSZ]; /**< Output buffer */
- char *buf_rp; /**< Read pointer */
- char *buf_wp; /**< Write pointer */
- char *buf_end; /**< End pointer */
+ /*@{ */
+
+ wait_queue_head_t vbl_queue; /**< VBLANK wait queue */
+ atomic_t vbl_received;
+ spinlock_t vbl_lock;
+ drm_vbl_sig_t vbl_sigs; /**< signal list to send on VBLANK */
+ unsigned int vbl_pending;
+
+ /*@} */
+ cycles_t ctx_start;
+ cycles_t lck_start;
+
struct fasync_struct *buf_async;/**< Processes waiting for SIGIO */
wait_queue_head_t buf_readers; /**< Processes waiting to read */
wait_queue_head_t buf_writers; /**< Processes waiting to ctx switch */
- drm_agp_head_t *agp; /**< AGP data */
+ drm_agp_head_t *agp; /**< AGP data */
- struct pci_dev *pdev; /**< PCI device structure */
- int pci_domain; /**< PCI bus domain number */
- int pci_bus; /**< PCI bus number */
- int pci_slot; /**< PCI slot number */
- int pci_func; /**< PCI function number */
+ struct pci_dev *pdev; /**< PCI device structure */
+ int pci_domain; /**< PCI bus domain number */
+ int pci_bus; /**< PCI bus number */
+ int pci_slot; /**< PCI slot number */
+ int pci_func; /**< PCI function number */
#ifdef __alpha__
struct pci_controller *hose;
#endif
- drm_sg_mem_t *sg; /**< Scatter gather memory */
- unsigned long *ctx_bitmap; /**< context bitmap */
- void *dev_private; /**< device private data */
- drm_sigdata_t sigdata; /**< For block_all_signals */
- sigset_t sigmask;
-
- struct drm_driver *driver;
- drm_local_map_t *agp_buffer_map;
+ drm_sg_mem_t *sg; /**< Scatter gather memory */
+ unsigned long *ctx_bitmap; /**< context bitmap */
+ void *dev_private; /**< device private data */
+ drm_sigdata_t sigdata; /**< For block_all_signals */
+ sigset_t sigmask;
+
+ struct drm_driver *driver;
+ drm_local_map_t *agp_buffer_map;
unsigned int agp_buffer_token;
drm_head_t primary; /**< primary screen head */
} drm_device_t;
-static __inline__ int drm_core_check_feature(struct drm_device *dev, int feature)
+static __inline__ int drm_core_check_feature(struct drm_device *dev,
+ int feature)
{
return ((dev->driver->driver_features & feature) ? 1 : 0);
}
@@ -738,7 +741,7 @@ static __inline__ int drm_core_check_feature(struct drm_device *dev, int feature
#if __OS_HAS_AGP
static inline int drm_core_has_AGP(struct drm_device *dev)
{
- return drm_core_check_feature(dev, DRIVER_USE_AGP);
+ return drm_core_check_feature(dev, DRIVER_USE_AGP);
}
#else
#define drm_core_has_AGP(dev) (0)
@@ -747,7 +750,7 @@ static inline int drm_core_has_AGP(struct drm_device *dev)
#if __OS_HAS_MTRR
static inline int drm_core_has_MTRR(struct drm_device *dev)
{
- return drm_core_check_feature(dev, DRIVER_USE_MTRR);
+ return drm_core_check_feature(dev, DRIVER_USE_MTRR);
}
#else
#define drm_core_has_MTRR(dev) (0)
@@ -758,234 +761,229 @@ static inline int drm_core_has_MTRR(struct drm_device *dev)
/*@{*/
/* Misc. support (drm_init.h) */
-extern int drm_flags;
-extern void drm_parse_options( char *s );
-extern int drm_cpu_valid( void );
+extern int drm_flags;
+extern void drm_parse_options(char *s);
+extern int drm_cpu_valid(void);
/* Driver support (drm_drv.h) */
-extern int drm_init(struct drm_driver *driver);
-extern void drm_exit(struct drm_driver *driver);
-extern int drm_ioctl(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
-extern long drm_compat_ioctl(struct file *filp,
- unsigned int cmd, unsigned long arg);
-extern int drm_takedown(drm_device_t * dev);
+extern int drm_init(struct drm_driver *driver);
+extern void drm_exit(struct drm_driver *driver);
+extern int drm_ioctl(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg);
+extern long drm_compat_ioctl(struct file *filp,
+ unsigned int cmd, unsigned long arg);
+extern int drm_takedown(drm_device_t * dev);
/* Device support (drm_fops.h) */
-extern int drm_open(struct inode *inode, struct file *filp);
-extern int drm_stub_open(struct inode *inode, struct file *filp);
-extern int drm_flush(struct file *filp);
-extern int drm_fasync(int fd, struct file *filp, int on);
-extern int drm_release(struct inode *inode, struct file *filp);
+extern int drm_open(struct inode *inode, struct file *filp);
+extern int drm_stub_open(struct inode *inode, struct file *filp);
+extern int drm_flush(struct file *filp);
+extern int drm_fasync(int fd, struct file *filp, int on);
+extern int drm_release(struct inode *inode, struct file *filp);
/* Mapping support (drm_vm.h) */
-extern int drm_mmap(struct file *filp, struct vm_area_struct *vma);
-extern unsigned int drm_poll(struct file *filp, struct poll_table_struct *wait);
+extern int drm_mmap(struct file *filp, struct vm_area_struct *vma);
+extern unsigned int drm_poll(struct file *filp, struct poll_table_struct *wait);
/* Memory management support (drm_memory.h) */
#include "drm_memory.h"
-extern void drm_mem_init(void);
-extern int drm_mem_info(char *buf, char **start, off_t offset,
- int request, int *eof, void *data);
-extern void *drm_realloc(void *oldpt, size_t oldsize, size_t size,
- int area);
+extern void drm_mem_init(void);
+extern int drm_mem_info(char *buf, char **start, off_t offset,
+ int request, int *eof, void *data);
+extern void *drm_realloc(void *oldpt, size_t oldsize, size_t size, int area);
extern unsigned long drm_alloc_pages(int order, int area);
-extern void drm_free_pages(unsigned long address, int order,
- int area);
-extern void *drm_ioremap(unsigned long offset, unsigned long size, drm_device_t *dev);
-extern void *drm_ioremap_nocache(unsigned long offset, unsigned long size,
- drm_device_t *dev);
-extern void drm_ioremapfree(void *pt, unsigned long size, drm_device_t *dev);
-
-extern DRM_AGP_MEM *drm_alloc_agp(drm_device_t *dev, int pages, u32 type);
-extern int drm_free_agp(DRM_AGP_MEM *handle, int pages);
-extern int drm_bind_agp(DRM_AGP_MEM *handle, unsigned int start);
-extern int drm_unbind_agp(DRM_AGP_MEM *handle);
+extern void drm_free_pages(unsigned long address, int order, int area);
+extern void *drm_ioremap(unsigned long offset, unsigned long size,
+ drm_device_t * dev);
+extern void *drm_ioremap_nocache(unsigned long offset, unsigned long size,
+ drm_device_t * dev);
+extern void drm_ioremapfree(void *pt, unsigned long size, drm_device_t * dev);
+
+extern DRM_AGP_MEM *drm_alloc_agp(drm_device_t * dev, int pages, u32 type);
+extern int drm_free_agp(DRM_AGP_MEM * handle, int pages);
+extern int drm_bind_agp(DRM_AGP_MEM * handle, unsigned int start);
+extern int drm_unbind_agp(DRM_AGP_MEM * handle);
/* Misc. IOCTL support (drm_ioctl.h) */
-extern int drm_irq_by_busid(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
-extern int drm_getunique(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
-extern int drm_setunique(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
-extern int drm_getmap(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
-extern int drm_getclient(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
-extern int drm_getstats(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
-extern int drm_setversion(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
+extern int drm_irq_by_busid(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg);
+extern int drm_getunique(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg);
+extern int drm_setunique(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg);
+extern int drm_getmap(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg);
+extern int drm_getclient(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg);
+extern int drm_getstats(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg);
+extern int drm_setversion(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg);
/* Context IOCTL support (drm_context.h) */
-extern int drm_resctx( struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg );
-extern int drm_addctx( struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg );
-extern int drm_modctx( struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg );
-extern int drm_getctx( struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg );
-extern int drm_switchctx( struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg );
-extern int drm_newctx( struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg );
-extern int drm_rmctx( struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg );
-
-extern int drm_ctxbitmap_init( drm_device_t *dev );
-extern void drm_ctxbitmap_cleanup( drm_device_t *dev );
-extern void drm_ctxbitmap_free( drm_device_t *dev, int ctx_handle );
-
-extern int drm_setsareactx( struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg );
-extern int drm_getsareactx( struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg );
+extern int drm_resctx(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg);
+extern int drm_addctx(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg);
+extern int drm_modctx(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg);
+extern int drm_getctx(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg);
+extern int drm_switchctx(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg);
+extern int drm_newctx(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg);
+extern int drm_rmctx(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg);
+
+extern int drm_ctxbitmap_init(drm_device_t * dev);
+extern void drm_ctxbitmap_cleanup(drm_device_t * dev);
+extern void drm_ctxbitmap_free(drm_device_t * dev, int ctx_handle);
+
+extern int drm_setsareactx(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg);
+extern int drm_getsareactx(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg);
/* Drawable IOCTL support (drm_drawable.h) */
-extern int drm_adddraw(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
-extern int drm_rmdraw(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
-
+extern int drm_adddraw(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg);
+extern int drm_rmdraw(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg);
/* Authentication IOCTL support (drm_auth.h) */
-extern int drm_getmagic(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
-extern int drm_authmagic(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
+extern int drm_getmagic(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg);
+extern int drm_authmagic(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg);
- /* Placeholder for ioctls past */
-extern int drm_noop(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
+ /* Placeholder for ioctls past */
+extern int drm_noop(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg);
/* Locking IOCTL support (drm_lock.h) */
-extern int drm_lock(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
-extern int drm_unlock(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
-extern int drm_lock_take(__volatile__ unsigned int *lock,
- unsigned int context);
-extern int drm_lock_free(drm_device_t *dev,
- __volatile__ unsigned int *lock,
- unsigned int context);
+extern int drm_lock(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg);
+extern int drm_unlock(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg);
+extern int drm_lock_take(__volatile__ unsigned int *lock, unsigned int context);
+extern int drm_lock_free(drm_device_t * dev,
+ __volatile__ unsigned int *lock, unsigned int context);
/* Buffer management support (drm_bufs.h) */
-extern int drm_addbufs_agp(drm_device_t *dev, drm_buf_desc_t *request);
-extern int drm_addbufs_pci(drm_device_t *dev, drm_buf_desc_t *request);
-extern int drm_addmap(drm_device_t *dev, unsigned int offset,
+extern int drm_addbufs_agp(drm_device_t * dev, drm_buf_desc_t * request);
+extern int drm_addbufs_pci(drm_device_t * dev, drm_buf_desc_t * request);
+extern int drm_addmap(drm_device_t * dev, unsigned int offset,
unsigned int size, drm_map_type_t type,
- drm_map_flags_t flags, drm_local_map_t **map_ptr);
+ drm_map_flags_t flags, drm_local_map_t ** map_ptr);
extern int drm_addmap_ioctl(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
-extern int drm_rmmap(drm_device_t *dev, drm_local_map_t *map);
-extern int drm_rmmap_locked(drm_device_t *dev, drm_local_map_t *map);
+extern int drm_rmmap(drm_device_t * dev, drm_local_map_t * map);
+extern int drm_rmmap_locked(drm_device_t * dev, drm_local_map_t * map);
extern int drm_rmmap_ioctl(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
-extern int drm_order( unsigned long size );
-extern int drm_addbufs( struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg );
-extern int drm_infobufs( struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg );
-extern int drm_markbufs( struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg );
-extern int drm_freebufs( struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg );
-extern int drm_mapbufs( struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg );
-extern unsigned long drm_get_resource_start(drm_device_t *dev,
+extern int drm_order(unsigned long size);
+extern int drm_addbufs(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg);
+extern int drm_infobufs(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg);
+extern int drm_markbufs(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg);
+extern int drm_freebufs(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg);
+extern int drm_mapbufs(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg);
+extern unsigned long drm_get_resource_start(drm_device_t * dev,
unsigned int resource);
-extern unsigned long drm_get_resource_len(drm_device_t *dev,
+extern unsigned long drm_get_resource_len(drm_device_t * dev,
unsigned int resource);
/* DMA support (drm_dma.h) */
-extern int drm_dma_setup(drm_device_t *dev);
-extern void drm_dma_takedown(drm_device_t *dev);
-extern void drm_free_buffer(drm_device_t *dev, drm_buf_t *buf);
-extern void drm_core_reclaim_buffers(drm_device_t *dev, struct file *filp);
+extern int drm_dma_setup(drm_device_t * dev);
+extern void drm_dma_takedown(drm_device_t * dev);
+extern void drm_free_buffer(drm_device_t * dev, drm_buf_t * buf);
+extern void drm_core_reclaim_buffers(drm_device_t * dev, struct file *filp);
/* IRQ support (drm_irq.h) */
-extern int drm_control( struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg );
-extern int drm_irq_uninstall( drm_device_t *dev );
-extern irqreturn_t drm_irq_handler( DRM_IRQ_ARGS );
-extern void drm_driver_irq_preinstall( drm_device_t *dev );
-extern void drm_driver_irq_postinstall( drm_device_t *dev );
-extern void drm_driver_irq_uninstall( drm_device_t *dev );
-
-extern int drm_wait_vblank(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
-extern int drm_vblank_wait(drm_device_t *dev, unsigned int *vbl_seq);
-extern void drm_vbl_send_signals( drm_device_t *dev );
+extern int drm_control(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg);
+extern int drm_irq_uninstall(drm_device_t * dev);
+extern irqreturn_t drm_irq_handler(DRM_IRQ_ARGS);
+extern void drm_driver_irq_preinstall(drm_device_t * dev);
+extern void drm_driver_irq_postinstall(drm_device_t * dev);
+extern void drm_driver_irq_uninstall(drm_device_t * dev);
+
+extern int drm_wait_vblank(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg);
+extern int drm_vblank_wait(drm_device_t * dev, unsigned int *vbl_seq);
+extern void drm_vbl_send_signals(drm_device_t * dev);
/* AGP/GART support (drm_agpsupport.h) */
-extern drm_agp_head_t *drm_agp_init(drm_device_t *dev);
+extern drm_agp_head_t *drm_agp_init(drm_device_t * dev);
extern int drm_agp_acquire(drm_device_t * dev);
extern int drm_agp_acquire_ioctl(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
-extern int drm_agp_release(drm_device_t *dev);
+ unsigned int cmd, unsigned long arg);
+extern int drm_agp_release(drm_device_t * dev);
extern int drm_agp_release_ioctl(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
-extern int drm_agp_enable(drm_device_t *dev, drm_agp_mode_t mode);
+ unsigned int cmd, unsigned long arg);
+extern int drm_agp_enable(drm_device_t * dev, drm_agp_mode_t mode);
extern int drm_agp_enable_ioctl(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
-extern int drm_agp_info(drm_device_t * dev, drm_agp_info_t *info);
+ unsigned int cmd, unsigned long arg);
+extern int drm_agp_info(drm_device_t * dev, drm_agp_info_t * info);
extern int drm_agp_info_ioctl(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg);
+extern int drm_agp_alloc(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg);
+extern int drm_agp_free(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg);
+extern int drm_agp_unbind(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg);
+extern int drm_agp_bind(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
-extern int drm_agp_alloc(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
-extern int drm_agp_free(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
-extern int drm_agp_unbind(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
-extern int drm_agp_bind(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
-extern DRM_AGP_MEM *drm_agp_allocate_memory(struct agp_bridge_data *bridge, size_t pages, u32 type);
-extern int drm_agp_free_memory(DRM_AGP_MEM *handle);
-extern int drm_agp_bind_memory(DRM_AGP_MEM *handle, off_t start);
-extern int drm_agp_unbind_memory(DRM_AGP_MEM *handle);
+extern DRM_AGP_MEM *drm_agp_allocate_memory(struct agp_bridge_data *bridge,
+ size_t pages, u32 type);
+extern int drm_agp_free_memory(DRM_AGP_MEM * handle);
+extern int drm_agp_bind_memory(DRM_AGP_MEM * handle, off_t start);
+extern int drm_agp_unbind_memory(DRM_AGP_MEM * handle);
/* Stub support (drm_stub.h) */
extern int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent,
- struct drm_driver *driver);
+ struct drm_driver *driver);
extern int drm_put_dev(drm_device_t * dev);
extern int drm_put_head(drm_head_t * head);
-extern unsigned int drm_debug;
-extern unsigned int drm_cards_limit;
+extern unsigned int drm_debug;
+extern unsigned int drm_cards_limit;
extern drm_head_t **drm_heads;
extern struct drm_sysfs_class *drm_class;
extern struct proc_dir_entry *drm_proc_root;
/* Proc support (drm_proc.h) */
-extern int drm_proc_init(drm_device_t *dev,
- int minor,
- struct proc_dir_entry *root,
- struct proc_dir_entry **dev_root);
-extern int drm_proc_cleanup(int minor,
- struct proc_dir_entry *root,
- struct proc_dir_entry *dev_root);
+extern int drm_proc_init(drm_device_t * dev,
+ int minor,
+ struct proc_dir_entry *root,
+ struct proc_dir_entry **dev_root);
+extern int drm_proc_cleanup(int minor,
+ struct proc_dir_entry *root,
+ struct proc_dir_entry *dev_root);
/* Scatter Gather Support (drm_scatter.h) */
-extern void drm_sg_cleanup(drm_sg_mem_t *entry);
-extern int drm_sg_alloc(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
-extern int drm_sg_free(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
-
- /* ATI PCIGART support (ati_pcigart.h) */
-extern int drm_ati_pcigart_init(drm_device_t *dev,
- unsigned long *addr,
- dma_addr_t *bus_addr);
-extern int drm_ati_pcigart_cleanup(drm_device_t *dev,
- unsigned long addr,
- dma_addr_t bus_addr);
-
-extern drm_dma_handle_t *drm_pci_alloc(drm_device_t *dev, size_t size,
+extern void drm_sg_cleanup(drm_sg_mem_t * entry);
+extern int drm_sg_alloc(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg);
+extern int drm_sg_free(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg);
+
+ /* ATI PCIGART support (ati_pcigart.h) */
+extern int drm_ati_pcigart_init(drm_device_t * dev,
+ drm_ati_pcigart_info * gart_info);
+extern int drm_ati_pcigart_cleanup(drm_device_t * dev,
+ drm_ati_pcigart_info * gart_info);
+
+extern drm_dma_handle_t *drm_pci_alloc(drm_device_t * dev, size_t size,
size_t align, dma_addr_t maxaddr);
-extern void __drm_pci_free(drm_device_t *dev, drm_dma_handle_t *dmah);
-extern void drm_pci_free(drm_device_t *dev, drm_dma_handle_t *dmah);
+extern void __drm_pci_free(drm_device_t * dev, drm_dma_handle_t * dmah);
+extern void drm_pci_free(drm_device_t * dev, drm_dma_handle_t * dmah);
/* sysfs support (drm_sysfs.c) */
struct drm_sysfs_class;
@@ -998,38 +996,41 @@ extern struct class_device *drm_sysfs_device_add(struct drm_sysfs_class *cs,
const char *fmt, ...);
extern void drm_sysfs_device_remove(dev_t dev);
-
/* Inline replacements for DRM_IOREMAP macros */
-static __inline__ void drm_core_ioremap(struct drm_map *map, struct drm_device *dev)
+static __inline__ void drm_core_ioremap(struct drm_map *map,
+ struct drm_device *dev)
{
- map->handle = drm_ioremap( map->offset, map->size, dev );
+ map->handle = drm_ioremap(map->offset, map->size, dev);
}
-static __inline__ void drm_core_ioremap_nocache(struct drm_map *map, struct drm_device *dev)
+static __inline__ void drm_core_ioremap_nocache(struct drm_map *map,
+ struct drm_device *dev)
{
map->handle = drm_ioremap_nocache(map->offset, map->size, dev);
}
-static __inline__ void drm_core_ioremapfree(struct drm_map *map, struct drm_device *dev)
+static __inline__ void drm_core_ioremapfree(struct drm_map *map,
+ struct drm_device *dev)
{
- if ( map->handle && map->size )
- drm_ioremapfree( map->handle, map->size, dev );
+ if (map->handle && map->size)
+ drm_ioremapfree(map->handle, map->size, dev);
}
-static __inline__ struct drm_map *drm_core_findmap(struct drm_device *dev, unsigned int token)
+static __inline__ struct drm_map *drm_core_findmap(struct drm_device *dev,
+ unsigned int token)
{
drm_map_list_t *_entry;
list_for_each_entry(_entry, &dev->maplist->head, head)
- if (_entry->user_token == token)
- return _entry->map;
+ if (_entry->user_token == token)
+ return _entry->map;
return NULL;
}
-static __inline__ int drm_device_is_agp(drm_device_t *dev)
+static __inline__ int drm_device_is_agp(drm_device_t * dev)
{
- if ( dev->driver->device_is_agp != NULL ) {
- int err = (*dev->driver->device_is_agp)( dev );
-
+ if (dev->driver->device_is_agp != NULL) {
+ int err = (*dev->driver->device_is_agp) (dev);
+
if (err != 2) {
return err;
}
@@ -1038,6 +1039,11 @@ static __inline__ int drm_device_is_agp(drm_device_t *dev)
return pci_find_capability(dev->pdev, PCI_CAP_ID_AGP);
}
+static __inline__ int drm_device_is_pcie(drm_device_t * dev)
+{
+ return pci_find_capability(dev->pdev, PCI_CAP_ID_EXP);
+}
+
static __inline__ void drm_core_dropmap(struct drm_map *map)
{
}
@@ -1068,12 +1074,12 @@ extern void *drm_calloc(size_t nmemb, size_t size, int area);
/*@}*/
-extern unsigned long drm_core_get_map_ofs(drm_map_t *map);
+extern unsigned long drm_core_get_map_ofs(drm_map_t * map);
extern unsigned long drm_core_get_reg_ofs(struct drm_device *dev);
#ifndef pci_pretty_name
#define pci_pretty_name(dev) ""
#endif
-#endif /* __KERNEL__ */
+#endif /* __KERNEL__ */
#endif
diff --git a/drivers/char/drm/drm_agpsupport.c b/drivers/char/drm/drm_agpsupport.c
index 8c215adcb4b2..2b6453a9ffce 100644
--- a/drivers/char/drm/drm_agpsupport.c
+++ b/drivers/char/drm/drm_agpsupport.c
@@ -1,7 +1,7 @@
/**
- * \file drm_agpsupport.h
+ * \file drm_agpsupport.h
* DRM support for AGP/GART backend
- *
+ *
* \author Rickard E. (Rik) Faith <faith@valinux.com>
* \author Gareth Hughes <gareth@valinux.com>
*/
@@ -48,30 +48,31 @@
* Verifies the AGP device has been initialized and acquired and fills in the
* drm_agp_info structure with the information in drm_agp_head::agp_info.
*/
-int drm_agp_info(drm_device_t *dev, drm_agp_info_t *info)
+int drm_agp_info(drm_device_t * dev, drm_agp_info_t * info)
{
- DRM_AGP_KERN *kern;
+ DRM_AGP_KERN *kern;
if (!dev->agp || !dev->agp->acquired)
return -EINVAL;
- kern = &dev->agp->agp_info;
+ kern = &dev->agp->agp_info;
info->agp_version_major = kern->version.major;
info->agp_version_minor = kern->version.minor;
- info->mode = kern->mode;
- info->aperture_base = kern->aper_base;
- info->aperture_size = kern->aper_size * 1024 * 1024;
- info->memory_allowed = kern->max_memory << PAGE_SHIFT;
- info->memory_used = kern->current_memory << PAGE_SHIFT;
- info->id_vendor = kern->device->vendor;
- info->id_device = kern->device->device;
+ info->mode = kern->mode;
+ info->aperture_base = kern->aper_base;
+ info->aperture_size = kern->aper_size * 1024 * 1024;
+ info->memory_allowed = kern->max_memory << PAGE_SHIFT;
+ info->memory_used = kern->current_memory << PAGE_SHIFT;
+ info->id_vendor = kern->device->vendor;
+ info->id_device = kern->device->device;
return 0;
}
+
EXPORT_SYMBOL(drm_agp_info);
int drm_agp_info_ioctl(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg)
+ unsigned int cmd, unsigned long arg)
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->head->dev;
@@ -81,7 +82,7 @@ int drm_agp_info_ioctl(struct inode *inode, struct file *filp,
err = drm_agp_info(dev, &info);
if (err)
return err;
-
+
if (copy_to_user((drm_agp_info_t __user *) arg, &info, sizeof(info)))
return -EFAULT;
return 0;
@@ -91,12 +92,12 @@ int drm_agp_info_ioctl(struct inode *inode, struct file *filp,
* Acquire the AGP device.
*
* \param dev DRM device that is to acquire AGP
- * \return zero on success or a negative number on failure.
+ * \return zero on success or a negative number on failure.
*
* Verifies the AGP device hasn't been acquired before and calls
* \c agp_backend_acquire.
*/
-int drm_agp_acquire(drm_device_t *dev)
+int drm_agp_acquire(drm_device_t * dev)
{
if (!dev->agp)
return -ENODEV;
@@ -107,6 +108,7 @@ int drm_agp_acquire(drm_device_t *dev)
dev->agp->acquired = 1;
return 0;
}
+
EXPORT_SYMBOL(drm_agp_acquire);
/**
@@ -125,8 +127,8 @@ int drm_agp_acquire_ioctl(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg)
{
drm_file_t *priv = filp->private_data;
-
- return drm_agp_acquire( (drm_device_t *) priv->head->dev );
+
+ return drm_agp_acquire((drm_device_t *) priv->head->dev);
}
/**
@@ -137,7 +139,7 @@ int drm_agp_acquire_ioctl(struct inode *inode, struct file *filp,
*
* Verifies the AGP device has been acquired and calls \c agp_backend_release.
*/
-int drm_agp_release(drm_device_t *dev)
+int drm_agp_release(drm_device_t * dev)
{
if (!dev->agp || !dev->agp->acquired)
return -EINVAL;
@@ -145,6 +147,7 @@ int drm_agp_release(drm_device_t *dev)
dev->agp->acquired = 0;
return 0;
}
+
EXPORT_SYMBOL(drm_agp_release);
int drm_agp_release_ioctl(struct inode *inode, struct file *filp,
@@ -152,13 +155,13 @@ int drm_agp_release_ioctl(struct inode *inode, struct file *filp,
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->head->dev;
-
+
return drm_agp_release(dev);
}
/**
* Enable the AGP bus.
- *
+ *
* \param dev DRM device that has previously acquired AGP.
* \param mode Requested AGP mode.
* \return zero on success or a negative number on failure.
@@ -166,27 +169,27 @@ int drm_agp_release_ioctl(struct inode *inode, struct file *filp,
* Verifies the AGP device has been acquired but not enabled, and calls
* \c agp_enable.
*/
-int drm_agp_enable(drm_device_t *dev, drm_agp_mode_t mode)
+int drm_agp_enable(drm_device_t * dev, drm_agp_mode_t mode)
{
if (!dev->agp || !dev->agp->acquired)
return -EINVAL;
- dev->agp->mode = mode.mode;
+ dev->agp->mode = mode.mode;
agp_enable(dev->agp->bridge, mode.mode);
- dev->agp->base = dev->agp->agp_info.aper_base;
+ dev->agp->base = dev->agp->agp_info.aper_base;
dev->agp->enabled = 1;
return 0;
}
+
EXPORT_SYMBOL(drm_agp_enable);
int drm_agp_enable_ioctl(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg)
+ unsigned int cmd, unsigned long arg)
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->head->dev;
drm_agp_mode_t mode;
-
if (copy_from_user(&mode, (drm_agp_mode_t __user *) arg, sizeof(mode)))
return -EFAULT;
@@ -201,20 +204,20 @@ int drm_agp_enable_ioctl(struct inode *inode, struct file *filp,
* \param cmd command.
* \param arg pointer to a drm_agp_buffer structure.
* \return zero on success or a negative number on failure.
- *
+ *
* Verifies the AGP device is present and has been acquired, allocates the
* memory via alloc_agp() and creates a drm_agp_mem entry for it.
*/
int drm_agp_alloc(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg)
+ unsigned int cmd, unsigned long arg)
{
- drm_file_t *priv = filp->private_data;
- drm_device_t *dev = priv->head->dev;
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->head->dev;
drm_agp_buffer_t request;
- drm_agp_mem_t *entry;
- DRM_AGP_MEM *memory;
- unsigned long pages;
- u32 type;
+ drm_agp_mem_t *entry;
+ DRM_AGP_MEM *memory;
+ unsigned long pages;
+ u32 type;
drm_agp_buffer_t __user *argp = (void __user *)arg;
if (!dev->agp || !dev->agp->acquired)
@@ -224,7 +227,7 @@ int drm_agp_alloc(struct inode *inode, struct file *filp,
if (!(entry = drm_alloc(sizeof(*entry), DRM_MEM_AGPLISTS)))
return -ENOMEM;
- memset(entry, 0, sizeof(*entry));
+ memset(entry, 0, sizeof(*entry));
pages = (request.size + PAGE_SIZE - 1) / PAGE_SIZE;
type = (u32) request.type;
@@ -234,21 +237,21 @@ int drm_agp_alloc(struct inode *inode, struct file *filp,
return -ENOMEM;
}
- entry->handle = (unsigned long)memory->key + 1;
- entry->memory = memory;
- entry->bound = 0;
- entry->pages = pages;
- entry->prev = NULL;
- entry->next = dev->agp->memory;
+ entry->handle = (unsigned long)memory->key + 1;
+ entry->memory = memory;
+ entry->bound = 0;
+ entry->pages = pages;
+ entry->prev = NULL;
+ entry->next = dev->agp->memory;
if (dev->agp->memory)
dev->agp->memory->prev = entry;
dev->agp->memory = entry;
- request.handle = entry->handle;
+ request.handle = entry->handle;
request.physical = memory->physical;
if (copy_to_user(argp, &request, sizeof(request))) {
- dev->agp->memory = entry->next;
+ dev->agp->memory = entry->next;
dev->agp->memory->prev = NULL;
drm_free_agp(memory, pages);
drm_free(entry, sizeof(*entry), DRM_MEM_AGPLISTS);
@@ -263,11 +266,11 @@ int drm_agp_alloc(struct inode *inode, struct file *filp,
* \param dev DRM device structure.
* \param handle AGP memory handle.
* \return pointer to the drm_agp_mem structure associated with \p handle.
- *
+ *
* Walks through drm_agp_head::memory until finding a matching handle.
*/
-static drm_agp_mem_t *drm_agp_lookup_entry(drm_device_t *dev,
- unsigned long handle)
+static drm_agp_mem_t *drm_agp_lookup_entry(drm_device_t * dev,
+ unsigned long handle)
{
drm_agp_mem_t *entry;
@@ -291,17 +294,18 @@ static drm_agp_mem_t *drm_agp_lookup_entry(drm_device_t *dev,
* entry and passes it to the unbind_agp() function.
*/
int drm_agp_unbind(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg)
+ unsigned int cmd, unsigned long arg)
{
- drm_file_t *priv = filp->private_data;
- drm_device_t *dev = priv->head->dev;
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->head->dev;
drm_agp_binding_t request;
- drm_agp_mem_t *entry;
+ drm_agp_mem_t *entry;
int ret;
if (!dev->agp || !dev->agp->acquired)
return -EINVAL;
- if (copy_from_user(&request, (drm_agp_binding_t __user *)arg, sizeof(request)))
+ if (copy_from_user
+ (&request, (drm_agp_binding_t __user *) arg, sizeof(request)))
return -EFAULT;
if (!(entry = drm_agp_lookup_entry(dev, request.handle)))
return -EINVAL;
@@ -309,7 +313,7 @@ int drm_agp_unbind(struct inode *inode, struct file *filp,
return -EINVAL;
ret = drm_unbind_agp(entry->memory);
if (ret == 0)
- entry->bound = 0;
+ entry->bound = 0;
return ret;
}
@@ -327,18 +331,19 @@ int drm_agp_unbind(struct inode *inode, struct file *filp,
* it to bind_agp() function.
*/
int drm_agp_bind(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg)
+ unsigned int cmd, unsigned long arg)
{
- drm_file_t *priv = filp->private_data;
- drm_device_t *dev = priv->head->dev;
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->head->dev;
drm_agp_binding_t request;
- drm_agp_mem_t *entry;
- int retcode;
- int page;
+ drm_agp_mem_t *entry;
+ int retcode;
+ int page;
if (!dev->agp || !dev->agp->acquired)
return -EINVAL;
- if (copy_from_user(&request, (drm_agp_binding_t __user *)arg, sizeof(request)))
+ if (copy_from_user
+ (&request, (drm_agp_binding_t __user *) arg, sizeof(request)))
return -EFAULT;
if (!(entry = drm_agp_lookup_entry(dev, request.handle)))
return -EINVAL;
@@ -368,16 +373,17 @@ int drm_agp_bind(struct inode *inode, struct file *filp,
* and unlinks from the doubly linked list it's inserted in.
*/
int drm_agp_free(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg)
+ unsigned int cmd, unsigned long arg)
{
- drm_file_t *priv = filp->private_data;
- drm_device_t *dev = priv->head->dev;
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->head->dev;
drm_agp_buffer_t request;
- drm_agp_mem_t *entry;
+ drm_agp_mem_t *entry;
if (!dev->agp || !dev->agp->acquired)
return -EINVAL;
- if (copy_from_user(&request, (drm_agp_buffer_t __user *)arg, sizeof(request)))
+ if (copy_from_user
+ (&request, (drm_agp_buffer_t __user *) arg, sizeof(request)))
return -EFAULT;
if (!(entry = drm_agp_lookup_entry(dev, request.handle)))
return -EINVAL;
@@ -403,9 +409,9 @@ int drm_agp_free(struct inode *inode, struct file *filp,
* \return pointer to a drm_agp_head structure.
*
*/
-drm_agp_head_t *drm_agp_init(drm_device_t *dev)
+drm_agp_head_t *drm_agp_init(drm_device_t * dev)
{
- drm_agp_head_t *head = NULL;
+ drm_agp_head_t *head = NULL;
if (!(head = drm_alloc(sizeof(*head), DRM_MEM_AGPLISTS)))
return NULL;
@@ -433,13 +439,14 @@ drm_agp_head_t *drm_agp_init(drm_device_t *dev)
}
/** Calls agp_allocate_memory() */
-DRM_AGP_MEM *drm_agp_allocate_memory(struct agp_bridge_data *bridge, size_t pages, u32 type)
+DRM_AGP_MEM *drm_agp_allocate_memory(struct agp_bridge_data * bridge,
+ size_t pages, u32 type)
{
return agp_allocate_memory(bridge, pages, type);
}
/** Calls agp_free_memory() */
-int drm_agp_free_memory(DRM_AGP_MEM *handle)
+int drm_agp_free_memory(DRM_AGP_MEM * handle)
{
if (!handle)
return 0;
@@ -448,20 +455,21 @@ int drm_agp_free_memory(DRM_AGP_MEM *handle)
}
/** Calls agp_bind_memory() */
-int drm_agp_bind_memory(DRM_AGP_MEM *handle, off_t start)
+int drm_agp_bind_memory(DRM_AGP_MEM * handle, off_t start)
{
if (!handle)
return -EINVAL;
return agp_bind_memory(handle, start);
}
+
EXPORT_SYMBOL(drm_agp_bind_memory);
/** Calls agp_unbind_memory() */
-int drm_agp_unbind_memory(DRM_AGP_MEM *handle)
+int drm_agp_unbind_memory(DRM_AGP_MEM * handle)
{
if (!handle)
return -EINVAL;
return agp_unbind_memory(handle);
}
-#endif /* __OS_HAS_AGP */
+#endif /* __OS_HAS_AGP */
diff --git a/drivers/char/drm/drm_auth.c b/drivers/char/drm/drm_auth.c
index dd140bca8f71..a47b502bc7cc 100644
--- a/drivers/char/drm/drm_auth.c
+++ b/drivers/char/drm/drm_auth.c
@@ -1,5 +1,5 @@
/**
- * \file drm_auth.h
+ * \file drm_auth.c
* IOCTLs for authentication
*
* \author Rickard E. (Rik) Faith <faith@valinux.com>
@@ -46,7 +46,7 @@
*/
static int drm_hash_magic(drm_magic_t magic)
{
- return magic & (DRM_HASH_SIZE-1);
+ return magic & (DRM_HASH_SIZE - 1);
}
/**
@@ -59,11 +59,11 @@ static int drm_hash_magic(drm_magic_t magic)
* the one with matching magic number, while holding the drm_device::struct_sem
* lock.
*/
-static drm_file_t *drm_find_file(drm_device_t *dev, drm_magic_t magic)
+static drm_file_t *drm_find_file(drm_device_t * dev, drm_magic_t magic)
{
- drm_file_t *retval = NULL;
+ drm_file_t *retval = NULL;
drm_magic_entry_t *pt;
- int hash = drm_hash_magic(magic);
+ int hash = drm_hash_magic(magic);
down(&dev->struct_sem);
for (pt = dev->magiclist[hash].head; pt; pt = pt->next) {
@@ -78,7 +78,7 @@ static drm_file_t *drm_find_file(drm_device_t *dev, drm_magic_t magic)
/**
* Adds a magic number.
- *
+ *
* \param dev DRM device.
* \param priv file private data.
* \param magic magic number.
@@ -87,28 +87,30 @@ static drm_file_t *drm_find_file(drm_device_t *dev, drm_magic_t magic)
* associated the magic number hash key in drm_device::magiclist, while holding
* the drm_device::struct_sem lock.
*/
-static int drm_add_magic(drm_device_t *dev, drm_file_t *priv, drm_magic_t magic)
+static int drm_add_magic(drm_device_t * dev, drm_file_t * priv,
+ drm_magic_t magic)
{
- int hash;
+ int hash;
drm_magic_entry_t *entry;
DRM_DEBUG("%d\n", magic);
- hash = drm_hash_magic(magic);
- entry = drm_alloc(sizeof(*entry), DRM_MEM_MAGIC);
- if (!entry) return -ENOMEM;
+ hash = drm_hash_magic(magic);
+ entry = drm_alloc(sizeof(*entry), DRM_MEM_MAGIC);
+ if (!entry)
+ return -ENOMEM;
memset(entry, 0, sizeof(*entry));
entry->magic = magic;
- entry->priv = priv;
- entry->next = NULL;
+ entry->priv = priv;
+ entry->next = NULL;
down(&dev->struct_sem);
if (dev->magiclist[hash].tail) {
dev->magiclist[hash].tail->next = entry;
- dev->magiclist[hash].tail = entry;
+ dev->magiclist[hash].tail = entry;
} else {
- dev->magiclist[hash].head = entry;
- dev->magiclist[hash].tail = entry;
+ dev->magiclist[hash].head = entry;
+ dev->magiclist[hash].tail = entry;
}
up(&dev->struct_sem);
@@ -117,19 +119,18 @@ static int drm_add_magic(drm_device_t *dev, drm_file_t *priv, drm_magic_t magic)
/**
* Remove a magic number.
- *
+ *
* \param dev DRM device.
* \param magic magic number.
*
* Searches and unlinks the entry in drm_device::magiclist with the magic
* number hash key, while holding the drm_device::struct_sem lock.
*/
-static int drm_remove_magic(drm_device_t *dev, drm_magic_t magic)
+static int drm_remove_magic(drm_device_t * dev, drm_magic_t magic)
{
drm_magic_entry_t *prev = NULL;
drm_magic_entry_t *pt;
- int hash;
-
+ int hash;
DRM_DEBUG("%d\n", magic);
hash = drm_hash_magic(magic);
@@ -171,21 +172,22 @@ static int drm_remove_magic(drm_device_t *dev, drm_magic_t magic)
* filp.
*/
int drm_getmagic(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg)
+ unsigned int cmd, unsigned long arg)
{
static drm_magic_t sequence = 0;
static DEFINE_SPINLOCK(lock);
- drm_file_t *priv = filp->private_data;
- drm_device_t *dev = priv->head->dev;
- drm_auth_t auth;
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->head->dev;
+ drm_auth_t auth;
- /* Find unique magic */
+ /* Find unique magic */
if (priv->magic) {
auth.magic = priv->magic;
} else {
do {
spin_lock(&lock);
- if (!sequence) ++sequence; /* reserve 0 */
+ if (!sequence)
+ ++sequence; /* reserve 0 */
auth.magic = sequence++;
spin_unlock(&lock);
} while (drm_find_file(dev, auth.magic));
@@ -194,7 +196,7 @@ int drm_getmagic(struct inode *inode, struct file *filp,
}
DRM_DEBUG("%u\n", auth.magic);
- if (copy_to_user((drm_auth_t __user *)arg, &auth, sizeof(auth)))
+ if (copy_to_user((drm_auth_t __user *) arg, &auth, sizeof(auth)))
return -EFAULT;
return 0;
}
@@ -211,14 +213,14 @@ int drm_getmagic(struct inode *inode, struct file *filp,
* Checks if \p filp is associated with the magic number passed in \arg.
*/
int drm_authmagic(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg)
+ unsigned int cmd, unsigned long arg)
{
- drm_file_t *priv = filp->private_data;
- drm_device_t *dev = priv->head->dev;
- drm_auth_t auth;
- drm_file_t *file;
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->head->dev;
+ drm_auth_t auth;
+ drm_file_t *file;
- if (copy_from_user(&auth, (drm_auth_t __user *)arg, sizeof(auth)))
+ if (copy_from_user(&auth, (drm_auth_t __user *) arg, sizeof(auth)))
return -EFAULT;
DRM_DEBUG("%u\n", auth.magic);
if ((file = drm_find_file(dev, auth.magic))) {
diff --git a/drivers/char/drm/drm_bufs.c b/drivers/char/drm/drm_bufs.c
index f28e70ae6606..319bdea8de8a 100644
--- a/drivers/char/drm/drm_bufs.c
+++ b/drivers/char/drm/drm_bufs.c
@@ -1,7 +1,7 @@
/**
- * \file drm_bufs.h
+ * \file drm_bufs.c
* Generic buffer template
- *
+ *
* \author Rickard E. (Rik) Faith <faith@valinux.com>
* \author Gareth Hughes <gareth@valinux.com>
*/
@@ -36,20 +36,22 @@
#include <linux/vmalloc.h>
#include "drmP.h"
-unsigned long drm_get_resource_start(drm_device_t *dev, unsigned int resource)
+unsigned long drm_get_resource_start(drm_device_t * dev, unsigned int resource)
{
return pci_resource_start(dev->pdev, resource);
}
+
EXPORT_SYMBOL(drm_get_resource_start);
-unsigned long drm_get_resource_len(drm_device_t *dev, unsigned int resource)
+unsigned long drm_get_resource_len(drm_device_t * dev, unsigned int resource)
{
return pci_resource_len(dev->pdev, resource);
}
+
EXPORT_SYMBOL(drm_get_resource_len);
-static drm_map_list_t *drm_find_matching_map(drm_device_t *dev,
- drm_local_map_t *map)
+static drm_map_list_t *drm_find_matching_map(drm_device_t * dev,
+ drm_local_map_t * map)
{
struct list_head *list;
@@ -71,7 +73,8 @@ static drm_map_list_t *drm_find_matching_map(drm_device_t *dev,
#define END_RANGE 0x40000000
#ifdef _LP64
-static __inline__ unsigned int HandleID(unsigned long lhandle, drm_device_t *dev)
+static __inline__ unsigned int HandleID(unsigned long lhandle,
+ drm_device_t * dev)
{
static unsigned int map32_handle = START_RANGE;
unsigned int hash;
@@ -81,12 +84,12 @@ static __inline__ unsigned int HandleID(unsigned long lhandle, drm_device_t *dev
map32_handle += PAGE_SIZE;
if (map32_handle > END_RANGE)
map32_handle = START_RANGE;
- } else
+ } else
hash = lhandle;
while (1) {
drm_map_list_t *_entry;
- list_for_each_entry(_entry, &dev->maplist->head,head) {
+ list_for_each_entry(_entry, &dev->maplist->head, head) {
if (_entry->user_token == hash)
break;
}
@@ -114,16 +117,16 @@ static __inline__ unsigned int HandleID(unsigned long lhandle, drm_device_t *dev
* type. Adds the map to the map list drm_device::maplist. Adds MTRR's where
* applicable and if supported by the kernel.
*/
-int drm_addmap_core(drm_device_t * dev, unsigned int offset,
- unsigned int size, drm_map_type_t type,
- drm_map_flags_t flags, drm_map_list_t **maplist)
+static int drm_addmap_core(drm_device_t * dev, unsigned int offset,
+ unsigned int size, drm_map_type_t type,
+ drm_map_flags_t flags, drm_map_list_t ** maplist)
{
drm_map_t *map;
drm_map_list_t *list;
drm_dma_handle_t *dmah;
- map = drm_alloc( sizeof(*map), DRM_MEM_MAPS );
- if ( !map )
+ map = drm_alloc(sizeof(*map), DRM_MEM_MAPS);
+ if (!map)
return -ENOMEM;
map->offset = offset;
@@ -135,26 +138,26 @@ int drm_addmap_core(drm_device_t * dev, unsigned int offset,
* book keeping information about shared memory to allow for removal
* when processes fork.
*/
- if ( (map->flags & _DRM_REMOVABLE) && map->type != _DRM_SHM ) {
- drm_free( map, sizeof(*map), DRM_MEM_MAPS );
+ if ((map->flags & _DRM_REMOVABLE) && map->type != _DRM_SHM) {
+ drm_free(map, sizeof(*map), DRM_MEM_MAPS);
return -EINVAL;
}
- DRM_DEBUG( "offset = 0x%08lx, size = 0x%08lx, type = %d\n",
- map->offset, map->size, map->type );
- if ( (map->offset & (~PAGE_MASK)) || (map->size & (~PAGE_MASK)) ) {
- drm_free( map, sizeof(*map), DRM_MEM_MAPS );
+ DRM_DEBUG("offset = 0x%08lx, size = 0x%08lx, type = %d\n",
+ map->offset, map->size, map->type);
+ if ((map->offset & (~PAGE_MASK)) || (map->size & (~PAGE_MASK))) {
+ drm_free(map, sizeof(*map), DRM_MEM_MAPS);
return -EINVAL;
}
- map->mtrr = -1;
+ map->mtrr = -1;
map->handle = NULL;
- switch ( map->type ) {
+ switch (map->type) {
case _DRM_REGISTERS:
case _DRM_FRAME_BUFFER:
#if !defined(__sparc__) && !defined(__alpha__) && !defined(__ia64__) && !defined(__powerpc64__) && !defined(__x86_64__)
- if ( map->offset + map->size < map->offset ||
- map->offset < virt_to_phys(high_memory) ) {
- drm_free( map, sizeof(*map), DRM_MEM_MAPS );
+ if (map->offset + map->size < map->offset ||
+ map->offset < virt_to_phys(high_memory)) {
+ drm_free(map, sizeof(*map), DRM_MEM_MAPS);
return -EINVAL;
}
#endif
@@ -169,8 +172,9 @@ int drm_addmap_core(drm_device_t * dev, unsigned int offset,
if (list != NULL) {
if (list->map->size != map->size) {
DRM_DEBUG("Matching maps of type %d with "
- "mismatched sizes, (%ld vs %ld)\n",
- map->type, map->size, list->map->size);
+ "mismatched sizes, (%ld vs %ld)\n",
+ map->type, map->size,
+ list->map->size);
list->map->size = map->size;
}
@@ -180,35 +184,33 @@ int drm_addmap_core(drm_device_t * dev, unsigned int offset,
}
if (drm_core_has_MTRR(dev)) {
- if ( map->type == _DRM_FRAME_BUFFER ||
- (map->flags & _DRM_WRITE_COMBINING) ) {
- map->mtrr = mtrr_add( map->offset, map->size,
- MTRR_TYPE_WRCOMB, 1 );
+ if (map->type == _DRM_FRAME_BUFFER ||
+ (map->flags & _DRM_WRITE_COMBINING)) {
+ map->mtrr = mtrr_add(map->offset, map->size,
+ MTRR_TYPE_WRCOMB, 1);
}
}
if (map->type == _DRM_REGISTERS)
- map->handle = drm_ioremap( map->offset, map->size,
- dev );
+ map->handle = drm_ioremap(map->offset, map->size, dev);
break;
case _DRM_SHM:
map->handle = vmalloc_32(map->size);
- DRM_DEBUG( "%lu %d %p\n",
- map->size, drm_order( map->size ), map->handle );
- if ( !map->handle ) {
- drm_free( map, sizeof(*map), DRM_MEM_MAPS );
+ DRM_DEBUG("%lu %d %p\n",
+ map->size, drm_order(map->size), map->handle);
+ if (!map->handle) {
+ drm_free(map, sizeof(*map), DRM_MEM_MAPS);
return -ENOMEM;
}
map->offset = (unsigned long)map->handle;
- if ( map->flags & _DRM_CONTAINS_LOCK ) {
+ if (map->flags & _DRM_CONTAINS_LOCK) {
/* Prevent a 2nd X Server from creating a 2nd lock */
if (dev->lock.hw_lock != NULL) {
- vfree( map->handle );
- drm_free( map, sizeof(*map), DRM_MEM_MAPS );
+ vfree(map->handle);
+ drm_free(map, sizeof(*map), DRM_MEM_MAPS);
return -EBUSY;
}
- dev->sigdata.lock =
- dev->lock.hw_lock = map->handle; /* Pointer to lock */
+ dev->sigdata.lock = dev->lock.hw_lock = map->handle; /* Pointer to lock */
}
break;
case _DRM_AGP:
@@ -217,7 +219,7 @@ int drm_addmap_core(drm_device_t * dev, unsigned int offset,
map->offset += dev->hose->mem_space->start;
#endif
map->offset += dev->agp->base;
- map->mtrr = dev->agp->agp_mtrr; /* for getmap */
+ map->mtrr = dev->agp->agp_mtrr; /* for getmap */
}
break;
case _DRM_SCATTER_GATHER:
@@ -227,7 +229,7 @@ int drm_addmap_core(drm_device_t * dev, unsigned int offset,
}
map->offset += (unsigned long)dev->sg->virtual;
break;
- case _DRM_CONSISTENT:
+ case _DRM_CONSISTENT:
/* dma_addr_t is 64bit on i386 with CONFIG_HIGHMEM64G,
* As we're limiting the address to 2^32-1 (or less),
* casting it down to 32 bits is no problem, but we
@@ -242,12 +244,12 @@ int drm_addmap_core(drm_device_t * dev, unsigned int offset,
kfree(dmah);
break;
default:
- drm_free( map, sizeof(*map), DRM_MEM_MAPS );
+ drm_free(map, sizeof(*map), DRM_MEM_MAPS);
return -EINVAL;
}
list = drm_alloc(sizeof(*list), DRM_MEM_MAPS);
- if(!list) {
+ if (!list) {
drm_free(map, sizeof(*map), DRM_MEM_MAPS);
return -EINVAL;
}
@@ -258,18 +260,18 @@ int drm_addmap_core(drm_device_t * dev, unsigned int offset,
list_add(&list->head, &dev->maplist->head);
/* Assign a 32-bit handle */
/* We do it here so that dev->struct_sem protects the increment */
- list->user_token = HandleID(map->type==_DRM_SHM
+ list->user_token = HandleID(map->type == _DRM_SHM
? (unsigned long)map->handle
: map->offset, dev);
- up(&dev->struct_sem);
+ up(&dev->struct_sem);
*maplist = list;
return 0;
}
-int drm_addmap(drm_device_t *dev, unsigned int offset,
+int drm_addmap(drm_device_t * dev, unsigned int offset,
unsigned int size, drm_map_type_t type,
- drm_map_flags_t flags, drm_local_map_t **map_ptr)
+ drm_map_flags_t flags, drm_local_map_t ** map_ptr)
{
drm_map_list_t *list;
int rc;
@@ -279,6 +281,7 @@ int drm_addmap(drm_device_t *dev, unsigned int offset,
*map_ptr = list->map;
return rc;
}
+
EXPORT_SYMBOL(drm_addmap);
int drm_addmap_ioctl(struct inode *inode, struct file *filp,
@@ -294,24 +297,25 @@ int drm_addmap_ioctl(struct inode *inode, struct file *filp,
if (!(filp->f_mode & 3))
return -EACCES; /* Require read/write */
- if (copy_from_user(& map, argp, sizeof(map))) {
+ if (copy_from_user(&map, argp, sizeof(map))) {
return -EFAULT;
}
err = drm_addmap_core(dev, map.offset, map.size, map.type, map.flags,
&maplist);
- if (err)
+ if (err)
return err;
if (copy_to_user(argp, maplist->map, sizeof(drm_map_t)))
return -EFAULT;
- if (put_user(maplist->user_token, &argp->handle))
+
+ /* avoid a warning on 64-bit, this casting isn't very nice, but the API is set so too late */
+ if (put_user((void *)(unsigned long)maplist->user_token, &argp->handle))
return -EFAULT;
return 0;
}
-
/**
* Remove a map private from list and deallocate resources if the mapping
* isn't in use.
@@ -328,7 +332,7 @@ int drm_addmap_ioctl(struct inode *inode, struct file *filp,
*
* \sa drm_addmap
*/
-int drm_rmmap_locked(drm_device_t *dev, drm_local_map_t *map)
+int drm_rmmap_locked(drm_device_t * dev, drm_local_map_t * map)
{
struct list_head *list;
drm_map_list_t *r_list = NULL;
@@ -359,9 +363,8 @@ int drm_rmmap_locked(drm_device_t *dev, drm_local_map_t *map)
case _DRM_FRAME_BUFFER:
if (drm_core_has_MTRR(dev) && map->mtrr >= 0) {
int retcode;
- retcode = mtrr_del(map->mtrr, map->offset,
- map->size);
- DRM_DEBUG ("mtrr_del=%d\n", retcode);
+ retcode = mtrr_del(map->mtrr, map->offset, map->size);
+ DRM_DEBUG("mtrr_del=%d\n", retcode);
}
break;
case _DRM_SHM:
@@ -381,9 +384,10 @@ int drm_rmmap_locked(drm_device_t *dev, drm_local_map_t *map)
return 0;
}
+
EXPORT_SYMBOL(drm_rmmap_locked);
-int drm_rmmap(drm_device_t *dev, drm_local_map_t *map)
+int drm_rmmap(drm_device_t * dev, drm_local_map_t * map)
{
int ret;
@@ -393,6 +397,7 @@ int drm_rmmap(drm_device_t *dev, drm_local_map_t *map)
return ret;
}
+
EXPORT_SYMBOL(drm_rmmap);
/* The rmmap ioctl appears to be unnecessary. All mappings are torn down on
@@ -414,7 +419,7 @@ int drm_rmmap_ioctl(struct inode *inode, struct file *filp,
struct list_head *list;
int ret;
- if (copy_from_user(&request, (drm_map_t __user *)arg, sizeof(request))) {
+ if (copy_from_user(&request, (drm_map_t __user *) arg, sizeof(request))) {
return -EFAULT;
}
@@ -423,7 +428,7 @@ int drm_rmmap_ioctl(struct inode *inode, struct file *filp,
drm_map_list_t *r_list = list_entry(list, drm_map_list_t, head);
if (r_list->map &&
- r_list->user_token == (unsigned long) request.handle &&
+ r_list->user_token == (unsigned long)request.handle &&
r_list->map->flags & _DRM_REMOVABLE) {
map = r_list->map;
break;
@@ -462,7 +467,7 @@ int drm_rmmap_ioctl(struct inode *inode, struct file *filp,
*
* Frees any pages and buffers associated with the given entry.
*/
-static void drm_cleanup_buf_error(drm_device_t *dev, drm_buf_entry_t *entry)
+static void drm_cleanup_buf_error(drm_device_t * dev, drm_buf_entry_t * entry)
{
int i;
@@ -470,30 +475,27 @@ static void drm_cleanup_buf_error(drm_device_t *dev, drm_buf_entry_t *entry)
for (i = 0; i < entry->seg_count; i++) {
if (entry->seglist[i]) {
drm_free_pages(entry->seglist[i],
- entry->page_order,
- DRM_MEM_DMA);
+ entry->page_order, DRM_MEM_DMA);
}
}
drm_free(entry->seglist,
- entry->seg_count *
- sizeof(*entry->seglist),
- DRM_MEM_SEGS);
+ entry->seg_count *
+ sizeof(*entry->seglist), DRM_MEM_SEGS);
entry->seg_count = 0;
}
- if (entry->buf_count) {
- for (i = 0; i < entry->buf_count; i++) {
+ if (entry->buf_count) {
+ for (i = 0; i < entry->buf_count; i++) {
if (entry->buflist[i].dev_private) {
drm_free(entry->buflist[i].dev_private,
- entry->buflist[i].dev_priv_size,
- DRM_MEM_BUFS);
+ entry->buflist[i].dev_priv_size,
+ DRM_MEM_BUFS);
}
}
drm_free(entry->buflist,
- entry->buf_count *
- sizeof(*entry->buflist),
- DRM_MEM_BUFS);
+ entry->buf_count *
+ sizeof(*entry->buflist), DRM_MEM_BUFS);
entry->buf_count = 0;
}
@@ -506,12 +508,12 @@ static void drm_cleanup_buf_error(drm_device_t *dev, drm_buf_entry_t *entry)
* \param dev drm_device_t to which the buffers are to be added.
* \param request pointer to a drm_buf_desc_t describing the request.
* \return zero on success or a negative number on failure.
- *
+ *
* After some sanity checks creates a drm_buf structure for each buffer and
* reallocates the buffer list of the same size order to accommodate the new
* buffers.
*/
-int drm_addbufs_agp(drm_device_t *dev, drm_buf_desc_t *request)
+int drm_addbufs_agp(drm_device_t * dev, drm_buf_desc_t * request)
{
drm_device_dma_t *dma = dev->dma;
drm_buf_entry_t *entry;
@@ -528,144 +530,145 @@ int drm_addbufs_agp(drm_device_t *dev, drm_buf_desc_t *request)
int i;
drm_buf_t **temp_buflist;
- if ( !dma ) return -EINVAL;
+ if (!dma)
+ return -EINVAL;
count = request->count;
order = drm_order(request->size);
size = 1 << order;
- alignment = (request->flags & _DRM_PAGE_ALIGN)
- ? PAGE_ALIGN(size) : size;
+ alignment = (request->flags & _DRM_PAGE_ALIGN)
+ ? PAGE_ALIGN(size) : size;
page_order = order - PAGE_SHIFT > 0 ? order - PAGE_SHIFT : 0;
total = PAGE_SIZE << page_order;
byte_count = 0;
agp_offset = dev->agp->base + request->agp_start;
- DRM_DEBUG( "count: %d\n", count );
- DRM_DEBUG( "order: %d\n", order );
- DRM_DEBUG( "size: %d\n", size );
- DRM_DEBUG( "agp_offset: %lu\n", agp_offset );
- DRM_DEBUG( "alignment: %d\n", alignment );
- DRM_DEBUG( "page_order: %d\n", page_order );
- DRM_DEBUG( "total: %d\n", total );
+ DRM_DEBUG("count: %d\n", count);
+ DRM_DEBUG("order: %d\n", order);
+ DRM_DEBUG("size: %d\n", size);
+ DRM_DEBUG("agp_offset: %lu\n", agp_offset);
+ DRM_DEBUG("alignment: %d\n", alignment);
+ DRM_DEBUG("page_order: %d\n", page_order);
+ DRM_DEBUG("total: %d\n", total);
- if ( order < DRM_MIN_ORDER || order > DRM_MAX_ORDER ) return -EINVAL;
- if ( dev->queue_count ) return -EBUSY; /* Not while in use */
+ if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER)
+ return -EINVAL;
+ if (dev->queue_count)
+ return -EBUSY; /* Not while in use */
- spin_lock( &dev->count_lock );
- if ( dev->buf_use ) {
- spin_unlock( &dev->count_lock );
+ spin_lock(&dev->count_lock);
+ if (dev->buf_use) {
+ spin_unlock(&dev->count_lock);
return -EBUSY;
}
- atomic_inc( &dev->buf_alloc );
- spin_unlock( &dev->count_lock );
+ atomic_inc(&dev->buf_alloc);
+ spin_unlock(&dev->count_lock);
- down( &dev->struct_sem );
+ down(&dev->struct_sem);
entry = &dma->bufs[order];
- if ( entry->buf_count ) {
- up( &dev->struct_sem );
- atomic_dec( &dev->buf_alloc );
- return -ENOMEM; /* May only call once for each order */
+ if (entry->buf_count) {
+ up(&dev->struct_sem);
+ atomic_dec(&dev->buf_alloc);
+ return -ENOMEM; /* May only call once for each order */
}
if (count < 0 || count > 4096) {
- up( &dev->struct_sem );
- atomic_dec( &dev->buf_alloc );
+ up(&dev->struct_sem);
+ atomic_dec(&dev->buf_alloc);
return -EINVAL;
}
- entry->buflist = drm_alloc( count * sizeof(*entry->buflist),
- DRM_MEM_BUFS );
- if ( !entry->buflist ) {
- up( &dev->struct_sem );
- atomic_dec( &dev->buf_alloc );
+ entry->buflist = drm_alloc(count * sizeof(*entry->buflist),
+ DRM_MEM_BUFS);
+ if (!entry->buflist) {
+ up(&dev->struct_sem);
+ atomic_dec(&dev->buf_alloc);
return -ENOMEM;
}
- memset( entry->buflist, 0, count * sizeof(*entry->buflist) );
+ memset(entry->buflist, 0, count * sizeof(*entry->buflist));
entry->buf_size = size;
entry->page_order = page_order;
offset = 0;
- while ( entry->buf_count < count ) {
- buf = &entry->buflist[entry->buf_count];
- buf->idx = dma->buf_count + entry->buf_count;
- buf->total = alignment;
- buf->order = order;
- buf->used = 0;
+ while (entry->buf_count < count) {
+ buf = &entry->buflist[entry->buf_count];
+ buf->idx = dma->buf_count + entry->buf_count;
+ buf->total = alignment;
+ buf->order = order;
+ buf->used = 0;
- buf->offset = (dma->byte_count + offset);
+ buf->offset = (dma->byte_count + offset);
buf->bus_address = agp_offset + offset;
buf->address = (void *)(agp_offset + offset);
- buf->next = NULL;
+ buf->next = NULL;
buf->waiting = 0;
buf->pending = 0;
- init_waitqueue_head( &buf->dma_wait );
- buf->filp = NULL;
+ init_waitqueue_head(&buf->dma_wait);
+ buf->filp = NULL;
buf->dev_priv_size = dev->driver->dev_priv_size;
- buf->dev_private = drm_alloc( buf->dev_priv_size,
- DRM_MEM_BUFS );
- if(!buf->dev_private) {
+ buf->dev_private = drm_alloc(buf->dev_priv_size, DRM_MEM_BUFS);
+ if (!buf->dev_private) {
/* Set count correctly so we free the proper amount. */
entry->buf_count = count;
- drm_cleanup_buf_error(dev,entry);
- up( &dev->struct_sem );
- atomic_dec( &dev->buf_alloc );
+ drm_cleanup_buf_error(dev, entry);
+ up(&dev->struct_sem);
+ atomic_dec(&dev->buf_alloc);
return -ENOMEM;
}
- memset( buf->dev_private, 0, buf->dev_priv_size );
+ memset(buf->dev_private, 0, buf->dev_priv_size);
- DRM_DEBUG( "buffer %d @ %p\n",
- entry->buf_count, buf->address );
+ DRM_DEBUG("buffer %d @ %p\n", entry->buf_count, buf->address);
offset += alignment;
entry->buf_count++;
byte_count += PAGE_SIZE << page_order;
}
- DRM_DEBUG( "byte_count: %d\n", byte_count );
+ DRM_DEBUG("byte_count: %d\n", byte_count);
- temp_buflist = drm_realloc( dma->buflist,
- dma->buf_count * sizeof(*dma->buflist),
- (dma->buf_count + entry->buf_count)
- * sizeof(*dma->buflist),
- DRM_MEM_BUFS );
- if(!temp_buflist) {
+ temp_buflist = drm_realloc(dma->buflist,
+ dma->buf_count * sizeof(*dma->buflist),
+ (dma->buf_count + entry->buf_count)
+ * sizeof(*dma->buflist), DRM_MEM_BUFS);
+ if (!temp_buflist) {
/* Free the entry because it isn't valid */
- drm_cleanup_buf_error(dev,entry);
- up( &dev->struct_sem );
- atomic_dec( &dev->buf_alloc );
+ drm_cleanup_buf_error(dev, entry);
+ up(&dev->struct_sem);
+ atomic_dec(&dev->buf_alloc);
return -ENOMEM;
}
dma->buflist = temp_buflist;
- for ( i = 0 ; i < entry->buf_count ; i++ ) {
+ for (i = 0; i < entry->buf_count; i++) {
dma->buflist[i + dma->buf_count] = &entry->buflist[i];
}
dma->buf_count += entry->buf_count;
dma->byte_count += byte_count;
- DRM_DEBUG( "dma->buf_count : %d\n", dma->buf_count );
- DRM_DEBUG( "entry->buf_count : %d\n", entry->buf_count );
+ DRM_DEBUG("dma->buf_count : %d\n", dma->buf_count);
+ DRM_DEBUG("entry->buf_count : %d\n", entry->buf_count);
- up( &dev->struct_sem );
+ up(&dev->struct_sem);
request->count = entry->buf_count;
request->size = size;
dma->flags = _DRM_DMA_USE_AGP;
- atomic_dec( &dev->buf_alloc );
+ atomic_dec(&dev->buf_alloc);
return 0;
}
+
EXPORT_SYMBOL(drm_addbufs_agp);
-#endif /* __OS_HAS_AGP */
+#endif /* __OS_HAS_AGP */
-int drm_addbufs_pci(drm_device_t *dev, drm_buf_desc_t *request)
+int drm_addbufs_pci(drm_device_t * dev, drm_buf_desc_t * request)
{
drm_device_dma_t *dma = dev->dma;
int count;
@@ -684,178 +687,174 @@ int drm_addbufs_pci(drm_device_t *dev, drm_buf_desc_t *request)
unsigned long *temp_pagelist;
drm_buf_t **temp_buflist;
- if (!drm_core_check_feature(dev, DRIVER_PCI_DMA)) return -EINVAL;
- if ( !dma ) return -EINVAL;
+ if (!drm_core_check_feature(dev, DRIVER_PCI_DMA))
+ return -EINVAL;
+ if (!dma)
+ return -EINVAL;
count = request->count;
order = drm_order(request->size);
size = 1 << order;
- DRM_DEBUG( "count=%d, size=%d (%d), order=%d, queue_count=%d\n",
- request->count, request->size, size,
- order, dev->queue_count );
+ DRM_DEBUG("count=%d, size=%d (%d), order=%d, queue_count=%d\n",
+ request->count, request->size, size, order, dev->queue_count);
- if ( order < DRM_MIN_ORDER || order > DRM_MAX_ORDER ) return -EINVAL;
- if ( dev->queue_count ) return -EBUSY; /* Not while in use */
+ if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER)
+ return -EINVAL;
+ if (dev->queue_count)
+ return -EBUSY; /* Not while in use */
alignment = (request->flags & _DRM_PAGE_ALIGN)
- ? PAGE_ALIGN(size) : size;
+ ? PAGE_ALIGN(size) : size;
page_order = order - PAGE_SHIFT > 0 ? order - PAGE_SHIFT : 0;
total = PAGE_SIZE << page_order;
- spin_lock( &dev->count_lock );
- if ( dev->buf_use ) {
- spin_unlock( &dev->count_lock );
+ spin_lock(&dev->count_lock);
+ if (dev->buf_use) {
+ spin_unlock(&dev->count_lock);
return -EBUSY;
}
- atomic_inc( &dev->buf_alloc );
- spin_unlock( &dev->count_lock );
+ atomic_inc(&dev->buf_alloc);
+ spin_unlock(&dev->count_lock);
- down( &dev->struct_sem );
+ down(&dev->struct_sem);
entry = &dma->bufs[order];
- if ( entry->buf_count ) {
- up( &dev->struct_sem );
- atomic_dec( &dev->buf_alloc );
+ if (entry->buf_count) {
+ up(&dev->struct_sem);
+ atomic_dec(&dev->buf_alloc);
return -ENOMEM; /* May only call once for each order */
}
if (count < 0 || count > 4096) {
- up( &dev->struct_sem );
- atomic_dec( &dev->buf_alloc );
+ up(&dev->struct_sem);
+ atomic_dec(&dev->buf_alloc);
return -EINVAL;
}
- entry->buflist = drm_alloc( count * sizeof(*entry->buflist),
- DRM_MEM_BUFS );
- if ( !entry->buflist ) {
- up( &dev->struct_sem );
- atomic_dec( &dev->buf_alloc );
+ entry->buflist = drm_alloc(count * sizeof(*entry->buflist),
+ DRM_MEM_BUFS);
+ if (!entry->buflist) {
+ up(&dev->struct_sem);
+ atomic_dec(&dev->buf_alloc);
return -ENOMEM;
}
- memset( entry->buflist, 0, count * sizeof(*entry->buflist) );
-
- entry->seglist = drm_alloc( count * sizeof(*entry->seglist),
- DRM_MEM_SEGS );
- if ( !entry->seglist ) {
- drm_free( entry->buflist,
- count * sizeof(*entry->buflist),
- DRM_MEM_BUFS );
- up( &dev->struct_sem );
- atomic_dec( &dev->buf_alloc );
+ memset(entry->buflist, 0, count * sizeof(*entry->buflist));
+
+ entry->seglist = drm_alloc(count * sizeof(*entry->seglist),
+ DRM_MEM_SEGS);
+ if (!entry->seglist) {
+ drm_free(entry->buflist,
+ count * sizeof(*entry->buflist), DRM_MEM_BUFS);
+ up(&dev->struct_sem);
+ atomic_dec(&dev->buf_alloc);
return -ENOMEM;
}
- memset( entry->seglist, 0, count * sizeof(*entry->seglist) );
+ memset(entry->seglist, 0, count * sizeof(*entry->seglist));
/* Keep the original pagelist until we know all the allocations
* have succeeded
*/
- temp_pagelist = drm_alloc( (dma->page_count + (count << page_order))
- * sizeof(*dma->pagelist),
- DRM_MEM_PAGES );
+ temp_pagelist = drm_alloc((dma->page_count + (count << page_order))
+ * sizeof(*dma->pagelist), DRM_MEM_PAGES);
if (!temp_pagelist) {
- drm_free( entry->buflist,
- count * sizeof(*entry->buflist),
- DRM_MEM_BUFS );
- drm_free( entry->seglist,
- count * sizeof(*entry->seglist),
- DRM_MEM_SEGS );
- up( &dev->struct_sem );
- atomic_dec( &dev->buf_alloc );
+ drm_free(entry->buflist,
+ count * sizeof(*entry->buflist), DRM_MEM_BUFS);
+ drm_free(entry->seglist,
+ count * sizeof(*entry->seglist), DRM_MEM_SEGS);
+ up(&dev->struct_sem);
+ atomic_dec(&dev->buf_alloc);
return -ENOMEM;
}
memcpy(temp_pagelist,
- dma->pagelist,
- dma->page_count * sizeof(*dma->pagelist));
- DRM_DEBUG( "pagelist: %d entries\n",
- dma->page_count + (count << page_order) );
+ dma->pagelist, dma->page_count * sizeof(*dma->pagelist));
+ DRM_DEBUG("pagelist: %d entries\n",
+ dma->page_count + (count << page_order));
- entry->buf_size = size;
+ entry->buf_size = size;
entry->page_order = page_order;
byte_count = 0;
page_count = 0;
- while ( entry->buf_count < count ) {
- page = drm_alloc_pages( page_order, DRM_MEM_DMA );
- if ( !page ) {
+ while (entry->buf_count < count) {
+ page = drm_alloc_pages(page_order, DRM_MEM_DMA);
+ if (!page) {
/* Set count correctly so we free the proper amount. */
entry->buf_count = count;
entry->seg_count = count;
drm_cleanup_buf_error(dev, entry);
- drm_free( temp_pagelist,
- (dma->page_count + (count << page_order))
- * sizeof(*dma->pagelist),
- DRM_MEM_PAGES );
- up( &dev->struct_sem );
- atomic_dec( &dev->buf_alloc );
+ drm_free(temp_pagelist,
+ (dma->page_count + (count << page_order))
+ * sizeof(*dma->pagelist), DRM_MEM_PAGES);
+ up(&dev->struct_sem);
+ atomic_dec(&dev->buf_alloc);
return -ENOMEM;
}
entry->seglist[entry->seg_count++] = page;
- for ( i = 0 ; i < (1 << page_order) ; i++ ) {
- DRM_DEBUG( "page %d @ 0x%08lx\n",
- dma->page_count + page_count,
- page + PAGE_SIZE * i );
+ for (i = 0; i < (1 << page_order); i++) {
+ DRM_DEBUG("page %d @ 0x%08lx\n",
+ dma->page_count + page_count,
+ page + PAGE_SIZE * i);
temp_pagelist[dma->page_count + page_count++]
- = page + PAGE_SIZE * i;
+ = page + PAGE_SIZE * i;
}
- for ( offset = 0 ;
- offset + size <= total && entry->buf_count < count ;
- offset += alignment, ++entry->buf_count ) {
- buf = &entry->buflist[entry->buf_count];
- buf->idx = dma->buf_count + entry->buf_count;
- buf->total = alignment;
- buf->order = order;
- buf->used = 0;
- buf->offset = (dma->byte_count + byte_count + offset);
+ for (offset = 0;
+ offset + size <= total && entry->buf_count < count;
+ offset += alignment, ++entry->buf_count) {
+ buf = &entry->buflist[entry->buf_count];
+ buf->idx = dma->buf_count + entry->buf_count;
+ buf->total = alignment;
+ buf->order = order;
+ buf->used = 0;
+ buf->offset = (dma->byte_count + byte_count + offset);
buf->address = (void *)(page + offset);
- buf->next = NULL;
+ buf->next = NULL;
buf->waiting = 0;
buf->pending = 0;
- init_waitqueue_head( &buf->dma_wait );
- buf->filp = NULL;
+ init_waitqueue_head(&buf->dma_wait);
+ buf->filp = NULL;
buf->dev_priv_size = dev->driver->dev_priv_size;
- buf->dev_private = drm_alloc( buf->dev_priv_size,
- DRM_MEM_BUFS );
- if(!buf->dev_private) {
+ buf->dev_private = drm_alloc(buf->dev_priv_size,
+ DRM_MEM_BUFS);
+ if (!buf->dev_private) {
/* Set count correctly so we free the proper amount. */
entry->buf_count = count;
entry->seg_count = count;
- drm_cleanup_buf_error(dev,entry);
- drm_free( temp_pagelist,
- (dma->page_count + (count << page_order))
- * sizeof(*dma->pagelist),
- DRM_MEM_PAGES );
- up( &dev->struct_sem );
- atomic_dec( &dev->buf_alloc );
+ drm_cleanup_buf_error(dev, entry);
+ drm_free(temp_pagelist,
+ (dma->page_count +
+ (count << page_order))
+ * sizeof(*dma->pagelist),
+ DRM_MEM_PAGES);
+ up(&dev->struct_sem);
+ atomic_dec(&dev->buf_alloc);
return -ENOMEM;
}
- memset( buf->dev_private, 0, buf->dev_priv_size );
+ memset(buf->dev_private, 0, buf->dev_priv_size);
- DRM_DEBUG( "buffer %d @ %p\n",
- entry->buf_count, buf->address );
+ DRM_DEBUG("buffer %d @ %p\n",
+ entry->buf_count, buf->address);
}
byte_count += PAGE_SIZE << page_order;
}
- temp_buflist = drm_realloc( dma->buflist,
- dma->buf_count * sizeof(*dma->buflist),
- (dma->buf_count + entry->buf_count)
- * sizeof(*dma->buflist),
- DRM_MEM_BUFS );
+ temp_buflist = drm_realloc(dma->buflist,
+ dma->buf_count * sizeof(*dma->buflist),
+ (dma->buf_count + entry->buf_count)
+ * sizeof(*dma->buflist), DRM_MEM_BUFS);
if (!temp_buflist) {
/* Free the entry because it isn't valid */
- drm_cleanup_buf_error(dev,entry);
- drm_free( temp_pagelist,
- (dma->page_count + (count << page_order))
- * sizeof(*dma->pagelist),
- DRM_MEM_PAGES );
- up( &dev->struct_sem );
- atomic_dec( &dev->buf_alloc );
+ drm_cleanup_buf_error(dev, entry);
+ drm_free(temp_pagelist,
+ (dma->page_count + (count << page_order))
+ * sizeof(*dma->pagelist), DRM_MEM_PAGES);
+ up(&dev->struct_sem);
+ atomic_dec(&dev->buf_alloc);
return -ENOMEM;
}
dma->buflist = temp_buflist;
- for ( i = 0 ; i < entry->buf_count ; i++ ) {
+ for (i = 0; i < entry->buf_count; i++) {
dma->buflist[i + dma->buf_count] = &entry->buflist[i];
}
@@ -864,8 +863,8 @@ int drm_addbufs_pci(drm_device_t *dev, drm_buf_desc_t *request)
*/
if (dma->page_count) {
drm_free(dma->pagelist,
- dma->page_count * sizeof(*dma->pagelist),
- DRM_MEM_PAGES);
+ dma->page_count * sizeof(*dma->pagelist),
+ DRM_MEM_PAGES);
}
dma->pagelist = temp_pagelist;
@@ -874,18 +873,19 @@ int drm_addbufs_pci(drm_device_t *dev, drm_buf_desc_t *request)
dma->page_count += entry->seg_count << page_order;
dma->byte_count += PAGE_SIZE * (entry->seg_count << page_order);
- up( &dev->struct_sem );
+ up(&dev->struct_sem);
request->count = entry->buf_count;
request->size = size;
- atomic_dec( &dev->buf_alloc );
+ atomic_dec(&dev->buf_alloc);
return 0;
}
+
EXPORT_SYMBOL(drm_addbufs_pci);
-static int drm_addbufs_sg(drm_device_t *dev, drm_buf_desc_t *request)
+static int drm_addbufs_sg(drm_device_t * dev, drm_buf_desc_t * request)
{
drm_device_dma_t *dma = dev->dma;
drm_buf_entry_t *entry;
@@ -902,146 +902,147 @@ static int drm_addbufs_sg(drm_device_t *dev, drm_buf_desc_t *request)
int i;
drm_buf_t **temp_buflist;
- if (!drm_core_check_feature(dev, DRIVER_SG)) return -EINVAL;
-
- if ( !dma ) return -EINVAL;
+ if (!drm_core_check_feature(dev, DRIVER_SG))
+ return -EINVAL;
+
+ if (!dma)
+ return -EINVAL;
count = request->count;
order = drm_order(request->size);
size = 1 << order;
- alignment = (request->flags & _DRM_PAGE_ALIGN)
- ? PAGE_ALIGN(size) : size;
+ alignment = (request->flags & _DRM_PAGE_ALIGN)
+ ? PAGE_ALIGN(size) : size;
page_order = order - PAGE_SHIFT > 0 ? order - PAGE_SHIFT : 0;
total = PAGE_SIZE << page_order;
byte_count = 0;
agp_offset = request->agp_start;
- DRM_DEBUG( "count: %d\n", count );
- DRM_DEBUG( "order: %d\n", order );
- DRM_DEBUG( "size: %d\n", size );
- DRM_DEBUG( "agp_offset: %lu\n", agp_offset );
- DRM_DEBUG( "alignment: %d\n", alignment );
- DRM_DEBUG( "page_order: %d\n", page_order );
- DRM_DEBUG( "total: %d\n", total );
+ DRM_DEBUG("count: %d\n", count);
+ DRM_DEBUG("order: %d\n", order);
+ DRM_DEBUG("size: %d\n", size);
+ DRM_DEBUG("agp_offset: %lu\n", agp_offset);
+ DRM_DEBUG("alignment: %d\n", alignment);
+ DRM_DEBUG("page_order: %d\n", page_order);
+ DRM_DEBUG("total: %d\n", total);
- if ( order < DRM_MIN_ORDER || order > DRM_MAX_ORDER ) return -EINVAL;
- if ( dev->queue_count ) return -EBUSY; /* Not while in use */
+ if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER)
+ return -EINVAL;
+ if (dev->queue_count)
+ return -EBUSY; /* Not while in use */
- spin_lock( &dev->count_lock );
- if ( dev->buf_use ) {
- spin_unlock( &dev->count_lock );
+ spin_lock(&dev->count_lock);
+ if (dev->buf_use) {
+ spin_unlock(&dev->count_lock);
return -EBUSY;
}
- atomic_inc( &dev->buf_alloc );
- spin_unlock( &dev->count_lock );
+ atomic_inc(&dev->buf_alloc);
+ spin_unlock(&dev->count_lock);
- down( &dev->struct_sem );
+ down(&dev->struct_sem);
entry = &dma->bufs[order];
- if ( entry->buf_count ) {
- up( &dev->struct_sem );
- atomic_dec( &dev->buf_alloc );
- return -ENOMEM; /* May only call once for each order */
+ if (entry->buf_count) {
+ up(&dev->struct_sem);
+ atomic_dec(&dev->buf_alloc);
+ return -ENOMEM; /* May only call once for each order */
}
if (count < 0 || count > 4096) {
- up( &dev->struct_sem );
- atomic_dec( &dev->buf_alloc );
+ up(&dev->struct_sem);
+ atomic_dec(&dev->buf_alloc);
return -EINVAL;
}
- entry->buflist = drm_alloc( count * sizeof(*entry->buflist),
- DRM_MEM_BUFS );
- if ( !entry->buflist ) {
- up( &dev->struct_sem );
- atomic_dec( &dev->buf_alloc );
+ entry->buflist = drm_alloc(count * sizeof(*entry->buflist),
+ DRM_MEM_BUFS);
+ if (!entry->buflist) {
+ up(&dev->struct_sem);
+ atomic_dec(&dev->buf_alloc);
return -ENOMEM;
}
- memset( entry->buflist, 0, count * sizeof(*entry->buflist) );
+ memset(entry->buflist, 0, count * sizeof(*entry->buflist));
entry->buf_size = size;
entry->page_order = page_order;
offset = 0;
- while ( entry->buf_count < count ) {
- buf = &entry->buflist[entry->buf_count];
- buf->idx = dma->buf_count + entry->buf_count;
- buf->total = alignment;
- buf->order = order;
- buf->used = 0;
+ while (entry->buf_count < count) {
+ buf = &entry->buflist[entry->buf_count];
+ buf->idx = dma->buf_count + entry->buf_count;
+ buf->total = alignment;
+ buf->order = order;
+ buf->used = 0;
- buf->offset = (dma->byte_count + offset);
+ buf->offset = (dma->byte_count + offset);
buf->bus_address = agp_offset + offset;
- buf->address = (void *)(agp_offset + offset
+ buf->address = (void *)(agp_offset + offset
+ (unsigned long)dev->sg->virtual);
- buf->next = NULL;
+ buf->next = NULL;
buf->waiting = 0;
buf->pending = 0;
- init_waitqueue_head( &buf->dma_wait );
- buf->filp = NULL;
+ init_waitqueue_head(&buf->dma_wait);
+ buf->filp = NULL;
buf->dev_priv_size = dev->driver->dev_priv_size;
- buf->dev_private = drm_alloc( buf->dev_priv_size,
- DRM_MEM_BUFS );
- if(!buf->dev_private) {
+ buf->dev_private = drm_alloc(buf->dev_priv_size, DRM_MEM_BUFS);
+ if (!buf->dev_private) {
/* Set count correctly so we free the proper amount. */
entry->buf_count = count;
- drm_cleanup_buf_error(dev,entry);
- up( &dev->struct_sem );
- atomic_dec( &dev->buf_alloc );
+ drm_cleanup_buf_error(dev, entry);
+ up(&dev->struct_sem);
+ atomic_dec(&dev->buf_alloc);
return -ENOMEM;
}
- memset( buf->dev_private, 0, buf->dev_priv_size );
+ memset(buf->dev_private, 0, buf->dev_priv_size);
- DRM_DEBUG( "buffer %d @ %p\n",
- entry->buf_count, buf->address );
+ DRM_DEBUG("buffer %d @ %p\n", entry->buf_count, buf->address);
offset += alignment;
entry->buf_count++;
byte_count += PAGE_SIZE << page_order;
}
- DRM_DEBUG( "byte_count: %d\n", byte_count );
+ DRM_DEBUG("byte_count: %d\n", byte_count);
- temp_buflist = drm_realloc( dma->buflist,
- dma->buf_count * sizeof(*dma->buflist),
- (dma->buf_count + entry->buf_count)
- * sizeof(*dma->buflist),
- DRM_MEM_BUFS );
- if(!temp_buflist) {
+ temp_buflist = drm_realloc(dma->buflist,
+ dma->buf_count * sizeof(*dma->buflist),
+ (dma->buf_count + entry->buf_count)
+ * sizeof(*dma->buflist), DRM_MEM_BUFS);
+ if (!temp_buflist) {
/* Free the entry because it isn't valid */
- drm_cleanup_buf_error(dev,entry);
- up( &dev->struct_sem );
- atomic_dec( &dev->buf_alloc );
+ drm_cleanup_buf_error(dev, entry);
+ up(&dev->struct_sem);
+ atomic_dec(&dev->buf_alloc);
return -ENOMEM;
}
dma->buflist = temp_buflist;
- for ( i = 0 ; i < entry->buf_count ; i++ ) {
+ for (i = 0; i < entry->buf_count; i++) {
dma->buflist[i + dma->buf_count] = &entry->buflist[i];
}
dma->buf_count += entry->buf_count;
dma->byte_count += byte_count;
- DRM_DEBUG( "dma->buf_count : %d\n", dma->buf_count );
- DRM_DEBUG( "entry->buf_count : %d\n", entry->buf_count );
+ DRM_DEBUG("dma->buf_count : %d\n", dma->buf_count);
+ DRM_DEBUG("entry->buf_count : %d\n", entry->buf_count);
- up( &dev->struct_sem );
+ up(&dev->struct_sem);
request->count = entry->buf_count;
request->size = size;
dma->flags = _DRM_DMA_USE_SG;
- atomic_dec( &dev->buf_alloc );
+ atomic_dec(&dev->buf_alloc);
return 0;
}
-static int drm_addbufs_fb(drm_device_t *dev, drm_buf_desc_t *request)
+static int drm_addbufs_fb(drm_device_t * dev, drm_buf_desc_t * request)
{
drm_device_dma_t *dma = dev->dma;
drm_buf_entry_t *entry;
@@ -1060,7 +1061,7 @@ static int drm_addbufs_fb(drm_device_t *dev, drm_buf_desc_t *request)
if (!drm_core_check_feature(dev, DRIVER_FB_DMA))
return -EINVAL;
-
+
if (!dma)
return -EINVAL;
@@ -1210,43 +1211,41 @@ static int drm_addbufs_fb(drm_device_t *dev, drm_buf_desc_t *request)
* addbufs_sg() or addbufs_pci() for AGP, scatter-gather or consistent
* PCI memory respectively.
*/
-int drm_addbufs( struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg )
+int drm_addbufs(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg)
{
drm_buf_desc_t request;
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->head->dev;
int ret;
-
+
if (!drm_core_check_feature(dev, DRIVER_HAVE_DMA))
return -EINVAL;
- if ( copy_from_user( &request, (drm_buf_desc_t __user *)arg,
- sizeof(request) ) )
+ if (copy_from_user(&request, (drm_buf_desc_t __user *) arg,
+ sizeof(request)))
return -EFAULT;
#if __OS_HAS_AGP
- if ( request.flags & _DRM_AGP_BUFFER )
- ret=drm_addbufs_agp(dev, &request);
+ if (request.flags & _DRM_AGP_BUFFER)
+ ret = drm_addbufs_agp(dev, &request);
else
#endif
- if ( request.flags & _DRM_SG_BUFFER )
- ret=drm_addbufs_sg(dev, &request);
- else if ( request.flags & _DRM_FB_BUFFER)
- ret=drm_addbufs_fb(dev, &request);
+ if (request.flags & _DRM_SG_BUFFER)
+ ret = drm_addbufs_sg(dev, &request);
+ else if (request.flags & _DRM_FB_BUFFER)
+ ret = drm_addbufs_fb(dev, &request);
else
- ret=drm_addbufs_pci(dev, &request);
+ ret = drm_addbufs_pci(dev, &request);
- if (ret==0) {
- if (copy_to_user((void __user *)arg, &request,
- sizeof(request))) {
+ if (ret == 0) {
+ if (copy_to_user((void __user *)arg, &request, sizeof(request))) {
ret = -EFAULT;
}
}
return ret;
}
-
/**
* Get information about the buffer mappings.
*
@@ -1264,8 +1263,8 @@ int drm_addbufs( struct inode *inode, struct file *filp,
* lock, preventing of allocating more buffers after this call. Information
* about each requested buffer is then copied into user space.
*/
-int drm_infobufs( struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg )
+int drm_infobufs(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg)
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->head->dev;
@@ -1278,58 +1277,61 @@ int drm_infobufs( struct inode *inode, struct file *filp,
if (!drm_core_check_feature(dev, DRIVER_HAVE_DMA))
return -EINVAL;
- if ( !dma ) return -EINVAL;
+ if (!dma)
+ return -EINVAL;
- spin_lock( &dev->count_lock );
- if ( atomic_read( &dev->buf_alloc ) ) {
- spin_unlock( &dev->count_lock );
+ spin_lock(&dev->count_lock);
+ if (atomic_read(&dev->buf_alloc)) {
+ spin_unlock(&dev->count_lock);
return -EBUSY;
}
++dev->buf_use; /* Can't allocate more after this call */
- spin_unlock( &dev->count_lock );
+ spin_unlock(&dev->count_lock);
- if ( copy_from_user( &request, argp, sizeof(request) ) )
+ if (copy_from_user(&request, argp, sizeof(request)))
return -EFAULT;
- for ( i = 0, count = 0 ; i < DRM_MAX_ORDER + 1 ; i++ ) {
- if ( dma->bufs[i].buf_count ) ++count;
+ for (i = 0, count = 0; i < DRM_MAX_ORDER + 1; i++) {
+ if (dma->bufs[i].buf_count)
+ ++count;
}
- DRM_DEBUG( "count = %d\n", count );
+ DRM_DEBUG("count = %d\n", count);
- if ( request.count >= count ) {
- for ( i = 0, count = 0 ; i < DRM_MAX_ORDER + 1 ; i++ ) {
- if ( dma->bufs[i].buf_count ) {
- drm_buf_desc_t __user *to = &request.list[count];
+ if (request.count >= count) {
+ for (i = 0, count = 0; i < DRM_MAX_ORDER + 1; i++) {
+ if (dma->bufs[i].buf_count) {
+ drm_buf_desc_t __user *to =
+ &request.list[count];
drm_buf_entry_t *from = &dma->bufs[i];
drm_freelist_t *list = &dma->bufs[i].freelist;
- if ( copy_to_user( &to->count,
- &from->buf_count,
- sizeof(from->buf_count) ) ||
- copy_to_user( &to->size,
- &from->buf_size,
- sizeof(from->buf_size) ) ||
- copy_to_user( &to->low_mark,
- &list->low_mark,
- sizeof(list->low_mark) ) ||
- copy_to_user( &to->high_mark,
- &list->high_mark,
- sizeof(list->high_mark) ) )
+ if (copy_to_user(&to->count,
+ &from->buf_count,
+ sizeof(from->buf_count)) ||
+ copy_to_user(&to->size,
+ &from->buf_size,
+ sizeof(from->buf_size)) ||
+ copy_to_user(&to->low_mark,
+ &list->low_mark,
+ sizeof(list->low_mark)) ||
+ copy_to_user(&to->high_mark,
+ &list->high_mark,
+ sizeof(list->high_mark)))
return -EFAULT;
- DRM_DEBUG( "%d %d %d %d %d\n",
- i,
- dma->bufs[i].buf_count,
- dma->bufs[i].buf_size,
- dma->bufs[i].freelist.low_mark,
- dma->bufs[i].freelist.high_mark );
+ DRM_DEBUG("%d %d %d %d %d\n",
+ i,
+ dma->bufs[i].buf_count,
+ dma->bufs[i].buf_size,
+ dma->bufs[i].freelist.low_mark,
+ dma->bufs[i].freelist.high_mark);
++count;
}
}
}
request.count = count;
- if ( copy_to_user( argp, &request, sizeof(request) ) )
+ if (copy_to_user(argp, &request, sizeof(request)))
return -EFAULT;
return 0;
@@ -1349,8 +1351,8 @@ int drm_infobufs( struct inode *inode, struct file *filp,
*
* \note This ioctl is deprecated and mostly never used.
*/
-int drm_markbufs( struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg )
+int drm_markbufs(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg)
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->head->dev;
@@ -1362,44 +1364,45 @@ int drm_markbufs( struct inode *inode, struct file *filp,
if (!drm_core_check_feature(dev, DRIVER_HAVE_DMA))
return -EINVAL;
- if ( !dma ) return -EINVAL;
+ if (!dma)
+ return -EINVAL;
- if ( copy_from_user( &request,
- (drm_buf_desc_t __user *)arg,
- sizeof(request) ) )
+ if (copy_from_user(&request,
+ (drm_buf_desc_t __user *) arg, sizeof(request)))
return -EFAULT;
- DRM_DEBUG( "%d, %d, %d\n",
- request.size, request.low_mark, request.high_mark );
- order = drm_order( request.size );
- if ( order < DRM_MIN_ORDER || order > DRM_MAX_ORDER ) return -EINVAL;
+ DRM_DEBUG("%d, %d, %d\n",
+ request.size, request.low_mark, request.high_mark);
+ order = drm_order(request.size);
+ if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER)
+ return -EINVAL;
entry = &dma->bufs[order];
- if ( request.low_mark < 0 || request.low_mark > entry->buf_count )
+ if (request.low_mark < 0 || request.low_mark > entry->buf_count)
return -EINVAL;
- if ( request.high_mark < 0 || request.high_mark > entry->buf_count )
+ if (request.high_mark < 0 || request.high_mark > entry->buf_count)
return -EINVAL;
- entry->freelist.low_mark = request.low_mark;
+ entry->freelist.low_mark = request.low_mark;
entry->freelist.high_mark = request.high_mark;
return 0;
}
/**
- * Unreserve the buffers in list, previously reserved using drmDMA.
+ * Unreserve the buffers in list, previously reserved using drmDMA.
*
* \param inode device inode.
* \param filp file pointer.
* \param cmd command.
* \param arg pointer to a drm_buf_free structure.
* \return zero on success or a negative number on failure.
- *
+ *
* Calls free_buffer() for each used buffer.
* This function is primarily used for debugging.
*/
-int drm_freebufs( struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg )
+int drm_freebufs(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg)
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->head->dev;
@@ -1412,31 +1415,29 @@ int drm_freebufs( struct inode *inode, struct file *filp,
if (!drm_core_check_feature(dev, DRIVER_HAVE_DMA))
return -EINVAL;
- if ( !dma ) return -EINVAL;
+ if (!dma)
+ return -EINVAL;
- if ( copy_from_user( &request,
- (drm_buf_free_t __user *)arg,
- sizeof(request) ) )
+ if (copy_from_user(&request,
+ (drm_buf_free_t __user *) arg, sizeof(request)))
return -EFAULT;
- DRM_DEBUG( "%d\n", request.count );
- for ( i = 0 ; i < request.count ; i++ ) {
- if ( copy_from_user( &idx,
- &request.list[i],
- sizeof(idx) ) )
+ DRM_DEBUG("%d\n", request.count);
+ for (i = 0; i < request.count; i++) {
+ if (copy_from_user(&idx, &request.list[i], sizeof(idx)))
return -EFAULT;
- if ( idx < 0 || idx >= dma->buf_count ) {
- DRM_ERROR( "Index %d (of %d max)\n",
- idx, dma->buf_count - 1 );
+ if (idx < 0 || idx >= dma->buf_count) {
+ DRM_ERROR("Index %d (of %d max)\n",
+ idx, dma->buf_count - 1);
return -EINVAL;
}
buf = dma->buflist[idx];
- if ( buf->filp != filp ) {
- DRM_ERROR( "Process %d freeing buffer not owned\n",
- current->pid );
+ if (buf->filp != filp) {
+ DRM_ERROR("Process %d freeing buffer not owned\n",
+ current->pid);
return -EINVAL;
}
- drm_free_buffer( dev, buf );
+ drm_free_buffer(dev, buf);
}
return 0;
@@ -1455,8 +1456,8 @@ int drm_freebufs( struct inode *inode, struct file *filp,
* about each buffer into user space. The PCI buffers are already mapped on the
* addbufs_pci() call.
*/
-int drm_mapbufs( struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg )
+int drm_mapbufs(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg)
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->head->dev;
@@ -1472,86 +1473,84 @@ int drm_mapbufs( struct inode *inode, struct file *filp,
if (!drm_core_check_feature(dev, DRIVER_HAVE_DMA))
return -EINVAL;
- if ( !dma ) return -EINVAL;
+ if (!dma)
+ return -EINVAL;
- spin_lock( &dev->count_lock );
- if ( atomic_read( &dev->buf_alloc ) ) {
- spin_unlock( &dev->count_lock );
+ spin_lock(&dev->count_lock);
+ if (atomic_read(&dev->buf_alloc)) {
+ spin_unlock(&dev->count_lock);
return -EBUSY;
}
dev->buf_use++; /* Can't allocate more after this call */
- spin_unlock( &dev->count_lock );
+ spin_unlock(&dev->count_lock);
- if ( copy_from_user( &request, argp, sizeof(request) ) )
+ if (copy_from_user(&request, argp, sizeof(request)))
return -EFAULT;
- if ( request.count >= dma->buf_count ) {
+ if (request.count >= dma->buf_count) {
if ((drm_core_has_AGP(dev) && (dma->flags & _DRM_DMA_USE_AGP))
- || (drm_core_check_feature(dev, DRIVER_SG)
+ || (drm_core_check_feature(dev, DRIVER_SG)
&& (dma->flags & _DRM_DMA_USE_SG))
|| (drm_core_check_feature(dev, DRIVER_FB_DMA)
&& (dma->flags & _DRM_DMA_USE_FB))) {
drm_map_t *map = dev->agp_buffer_map;
unsigned long token = dev->agp_buffer_token;
- if ( !map ) {
+ if (!map) {
retcode = -EINVAL;
goto done;
}
- down_write( &current->mm->mmap_sem );
- virtual = do_mmap( filp, 0, map->size,
- PROT_READ | PROT_WRITE,
- MAP_SHARED,
- token );
- up_write( &current->mm->mmap_sem );
+ down_write(&current->mm->mmap_sem);
+ virtual = do_mmap(filp, 0, map->size,
+ PROT_READ | PROT_WRITE,
+ MAP_SHARED, token);
+ up_write(&current->mm->mmap_sem);
} else {
- down_write( &current->mm->mmap_sem );
- virtual = do_mmap( filp, 0, dma->byte_count,
- PROT_READ | PROT_WRITE,
- MAP_SHARED, 0 );
- up_write( &current->mm->mmap_sem );
+ down_write(&current->mm->mmap_sem);
+ virtual = do_mmap(filp, 0, dma->byte_count,
+ PROT_READ | PROT_WRITE,
+ MAP_SHARED, 0);
+ up_write(&current->mm->mmap_sem);
}
- if ( virtual > -1024UL ) {
+ if (virtual > -1024UL) {
/* Real error */
retcode = (signed long)virtual;
goto done;
}
request.virtual = (void __user *)virtual;
- for ( i = 0 ; i < dma->buf_count ; i++ ) {
- if ( copy_to_user( &request.list[i].idx,
- &dma->buflist[i]->idx,
- sizeof(request.list[0].idx) ) ) {
+ for (i = 0; i < dma->buf_count; i++) {
+ if (copy_to_user(&request.list[i].idx,
+ &dma->buflist[i]->idx,
+ sizeof(request.list[0].idx))) {
retcode = -EFAULT;
goto done;
}
- if ( copy_to_user( &request.list[i].total,
- &dma->buflist[i]->total,
- sizeof(request.list[0].total) ) ) {
+ if (copy_to_user(&request.list[i].total,
+ &dma->buflist[i]->total,
+ sizeof(request.list[0].total))) {
retcode = -EFAULT;
goto done;
}
- if ( copy_to_user( &request.list[i].used,
- &zero,
- sizeof(zero) ) ) {
+ if (copy_to_user(&request.list[i].used,
+ &zero, sizeof(zero))) {
retcode = -EFAULT;
goto done;
}
- address = virtual + dma->buflist[i]->offset; /* *** */
- if ( copy_to_user( &request.list[i].address,
- &address,
- sizeof(address) ) ) {
+ address = virtual + dma->buflist[i]->offset; /* *** */
+ if (copy_to_user(&request.list[i].address,
+ &address, sizeof(address))) {
retcode = -EFAULT;
goto done;
}
}
}
- done:
+ done:
request.count = dma->buf_count;
- DRM_DEBUG( "%d buffers, retcode = %d\n", request.count, retcode );
+ DRM_DEBUG("%d buffers, retcode = %d\n", request.count, retcode);
- if ( copy_to_user( argp, &request, sizeof(request) ) )
+ if (copy_to_user(argp, &request, sizeof(request)))
return -EFAULT;
return retcode;
@@ -1560,23 +1559,23 @@ int drm_mapbufs( struct inode *inode, struct file *filp,
/**
* Compute size order. Returns the exponent of the smaller power of two which
* is greater or equal to given number.
- *
+ *
* \param size size.
* \return order.
*
* \todo Can be made faster.
*/
-int drm_order( unsigned long size )
+int drm_order(unsigned long size)
{
int order;
unsigned long tmp;
- for (order = 0, tmp = size >> 1; tmp; tmp >>= 1, order++)
- ;
+ for (order = 0, tmp = size >> 1; tmp; tmp >>= 1, order++) ;
if (size & (size - 1))
++order;
return order;
}
+
EXPORT_SYMBOL(drm_order);
diff --git a/drivers/char/drm/drm_context.c b/drivers/char/drm/drm_context.c
index 502892794c16..bdd168d88f49 100644
--- a/drivers/char/drm/drm_context.c
+++ b/drivers/char/drm/drm_context.c
@@ -1,7 +1,7 @@
/**
- * \file drm_context.h
+ * \file drm_context.c
* IOCTLs for generic contexts
- *
+ *
* \author Rickard E. (Rik) Faith <faith@valinux.com>
* \author Gareth Hughes <gareth@valinux.com>
*/
@@ -56,25 +56,26 @@
* in drm_device::context_sareas, while holding the drm_device::struct_sem
* lock.
*/
-void drm_ctxbitmap_free( drm_device_t *dev, int ctx_handle )
+void drm_ctxbitmap_free(drm_device_t * dev, int ctx_handle)
{
- if ( ctx_handle < 0 ) goto failed;
- if ( !dev->ctx_bitmap ) goto failed;
+ if (ctx_handle < 0)
+ goto failed;
+ if (!dev->ctx_bitmap)
+ goto failed;
- if ( ctx_handle < DRM_MAX_CTXBITMAP ) {
+ if (ctx_handle < DRM_MAX_CTXBITMAP) {
down(&dev->struct_sem);
- clear_bit( ctx_handle, dev->ctx_bitmap );
+ clear_bit(ctx_handle, dev->ctx_bitmap);
dev->context_sareas[ctx_handle] = NULL;
up(&dev->struct_sem);
return;
}
-failed:
- DRM_ERROR( "Attempt to free invalid context handle: %d\n",
- ctx_handle );
- return;
+ failed:
+ DRM_ERROR("Attempt to free invalid context handle: %d\n", ctx_handle);
+ return;
}
-/**
+/**
* Context bitmap allocation.
*
* \param dev DRM device.
@@ -84,29 +85,33 @@ failed:
* drm_device::context_sareas to accommodate the new entry while holding the
* drm_device::struct_sem lock.
*/
-static int drm_ctxbitmap_next( drm_device_t *dev )
+static int drm_ctxbitmap_next(drm_device_t * dev)
{
int bit;
- if(!dev->ctx_bitmap) return -1;
+ if (!dev->ctx_bitmap)
+ return -1;
down(&dev->struct_sem);
- bit = find_first_zero_bit( dev->ctx_bitmap, DRM_MAX_CTXBITMAP );
- if ( bit < DRM_MAX_CTXBITMAP ) {
- set_bit( bit, dev->ctx_bitmap );
- DRM_DEBUG( "drm_ctxbitmap_next bit : %d\n", bit );
- if((bit+1) > dev->max_context) {
- dev->max_context = (bit+1);
- if(dev->context_sareas) {
+ bit = find_first_zero_bit(dev->ctx_bitmap, DRM_MAX_CTXBITMAP);
+ if (bit < DRM_MAX_CTXBITMAP) {
+ set_bit(bit, dev->ctx_bitmap);
+ DRM_DEBUG("drm_ctxbitmap_next bit : %d\n", bit);
+ if ((bit + 1) > dev->max_context) {
+ dev->max_context = (bit + 1);
+ if (dev->context_sareas) {
drm_map_t **ctx_sareas;
ctx_sareas = drm_realloc(dev->context_sareas,
- (dev->max_context - 1) *
- sizeof(*dev->context_sareas),
- dev->max_context *
- sizeof(*dev->context_sareas),
- DRM_MEM_MAPS);
- if(!ctx_sareas) {
+ (dev->max_context -
+ 1) *
+ sizeof(*dev->
+ context_sareas),
+ dev->max_context *
+ sizeof(*dev->
+ context_sareas),
+ DRM_MEM_MAPS);
+ if (!ctx_sareas) {
clear_bit(bit, dev->ctx_bitmap);
up(&dev->struct_sem);
return -1;
@@ -115,11 +120,11 @@ static int drm_ctxbitmap_next( drm_device_t *dev )
dev->context_sareas[bit] = NULL;
} else {
/* max_context == 1 at this point */
- dev->context_sareas = drm_alloc(
- dev->max_context *
- sizeof(*dev->context_sareas),
- DRM_MEM_MAPS);
- if(!dev->context_sareas) {
+ dev->context_sareas =
+ drm_alloc(dev->max_context *
+ sizeof(*dev->context_sareas),
+ DRM_MEM_MAPS);
+ if (!dev->context_sareas) {
clear_bit(bit, dev->ctx_bitmap);
up(&dev->struct_sem);
return -1;
@@ -142,26 +147,26 @@ static int drm_ctxbitmap_next( drm_device_t *dev )
* Allocates and initialize drm_device::ctx_bitmap and drm_device::context_sareas, while holding
* the drm_device::struct_sem lock.
*/
-int drm_ctxbitmap_init( drm_device_t *dev )
+int drm_ctxbitmap_init(drm_device_t * dev)
{
int i;
- int temp;
+ int temp;
down(&dev->struct_sem);
- dev->ctx_bitmap = (unsigned long *) drm_alloc( PAGE_SIZE,
- DRM_MEM_CTXBITMAP );
- if ( dev->ctx_bitmap == NULL ) {
+ dev->ctx_bitmap = (unsigned long *)drm_alloc(PAGE_SIZE,
+ DRM_MEM_CTXBITMAP);
+ if (dev->ctx_bitmap == NULL) {
up(&dev->struct_sem);
return -ENOMEM;
}
- memset( (void *)dev->ctx_bitmap, 0, PAGE_SIZE );
+ memset((void *)dev->ctx_bitmap, 0, PAGE_SIZE);
dev->context_sareas = NULL;
dev->max_context = -1;
up(&dev->struct_sem);
- for ( i = 0 ; i < DRM_RESERVED_CONTEXTS ; i++ ) {
- temp = drm_ctxbitmap_next( dev );
- DRM_DEBUG( "drm_ctxbitmap_init : %d\n", temp );
+ for (i = 0; i < DRM_RESERVED_CONTEXTS; i++) {
+ temp = drm_ctxbitmap_next(dev);
+ DRM_DEBUG("drm_ctxbitmap_init : %d\n", temp);
}
return 0;
@@ -175,14 +180,14 @@ int drm_ctxbitmap_init( drm_device_t *dev )
* Frees drm_device::ctx_bitmap and drm_device::context_sareas, while holding
* the drm_device::struct_sem lock.
*/
-void drm_ctxbitmap_cleanup( drm_device_t *dev )
+void drm_ctxbitmap_cleanup(drm_device_t * dev)
{
down(&dev->struct_sem);
- if( dev->context_sareas ) drm_free( dev->context_sareas,
- sizeof(*dev->context_sareas) *
- dev->max_context,
- DRM_MEM_MAPS );
- drm_free( (void *)dev->ctx_bitmap, PAGE_SIZE, DRM_MEM_CTXBITMAP );
+ if (dev->context_sareas)
+ drm_free(dev->context_sareas,
+ sizeof(*dev->context_sareas) *
+ dev->max_context, DRM_MEM_MAPS);
+ drm_free((void *)dev->ctx_bitmap, PAGE_SIZE, DRM_MEM_CTXBITMAP);
up(&dev->struct_sem);
}
@@ -194,7 +199,7 @@ void drm_ctxbitmap_cleanup( drm_device_t *dev )
/**
* Get per-context SAREA.
- *
+ *
* \param inode device inode.
* \param filp file pointer.
* \param cmd command.
@@ -205,10 +210,10 @@ void drm_ctxbitmap_cleanup( drm_device_t *dev )
* returns its handle.
*/
int drm_getsareactx(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg)
+ unsigned int cmd, unsigned long arg)
{
- drm_file_t *priv = filp->private_data;
- drm_device_t *dev = priv->head->dev;
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->head->dev;
drm_ctx_priv_map_t __user *argp = (void __user *)arg;
drm_ctx_priv_map_t request;
drm_map_t *map;
@@ -218,7 +223,8 @@ int drm_getsareactx(struct inode *inode, struct file *filp,
return -EFAULT;
down(&dev->struct_sem);
- if (dev->max_context < 0 || request.ctx_id >= (unsigned) dev->max_context) {
+ if (dev->max_context < 0
+ || request.ctx_id >= (unsigned)dev->max_context) {
up(&dev->struct_sem);
return -EINVAL;
}
@@ -226,17 +232,17 @@ int drm_getsareactx(struct inode *inode, struct file *filp,
map = dev->context_sareas[request.ctx_id];
up(&dev->struct_sem);
- request.handle = 0;
- list_for_each_entry(_entry, &dev->maplist->head,head) {
+ request.handle = NULL;
+ list_for_each_entry(_entry, &dev->maplist->head, head) {
if (_entry->map == map) {
- request.handle = (void *)(unsigned long)_entry->user_token;
+ request.handle =
+ (void *)(unsigned long)_entry->user_token;
break;
}
}
- if (request.handle == 0)
+ if (request.handle == NULL)
return -EINVAL;
-
if (copy_to_user(argp, &request, sizeof(request)))
return -EFAULT;
return 0;
@@ -244,7 +250,7 @@ int drm_getsareactx(struct inode *inode, struct file *filp,
/**
* Set per-context SAREA.
- *
+ *
* \param inode device inode.
* \param filp file pointer.
* \param cmd command.
@@ -255,37 +261,37 @@ int drm_getsareactx(struct inode *inode, struct file *filp,
* drm_device::context_sareas with it.
*/
int drm_setsareactx(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg)
+ unsigned int cmd, unsigned long arg)
{
- drm_file_t *priv = filp->private_data;
- drm_device_t *dev = priv->head->dev;
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->head->dev;
drm_ctx_priv_map_t request;
drm_map_t *map = NULL;
drm_map_list_t *r_list = NULL;
struct list_head *list;
if (copy_from_user(&request,
- (drm_ctx_priv_map_t __user *)arg,
- sizeof(request)))
+ (drm_ctx_priv_map_t __user *) arg, sizeof(request)))
return -EFAULT;
down(&dev->struct_sem);
list_for_each(list, &dev->maplist->head) {
r_list = list_entry(list, drm_map_list_t, head);
if (r_list->map
- && r_list->user_token == (unsigned long) request.handle)
+ && r_list->user_token == (unsigned long)request.handle)
goto found;
}
-bad:
+ bad:
up(&dev->struct_sem);
return -EINVAL;
-found:
+ found:
map = r_list->map;
- if (!map) goto bad;
+ if (!map)
+ goto bad;
if (dev->max_context < 0)
goto bad;
- if (request.ctx_id >= (unsigned) dev->max_context)
+ if (request.ctx_id >= (unsigned)dev->max_context)
goto bad;
dev->context_sareas[request.ctx_id] = map;
up(&dev->struct_sem);
@@ -308,22 +314,21 @@ found:
*
* Attempt to set drm_device::context_flag.
*/
-static int drm_context_switch( drm_device_t *dev, int old, int new )
+static int drm_context_switch(drm_device_t * dev, int old, int new)
{
- if ( test_and_set_bit( 0, &dev->context_flag ) ) {
- DRM_ERROR( "Reentering -- FIXME\n" );
- return -EBUSY;
- }
-
+ if (test_and_set_bit(0, &dev->context_flag)) {
+ DRM_ERROR("Reentering -- FIXME\n");
+ return -EBUSY;
+ }
- DRM_DEBUG( "Context switch from %d to %d\n", old, new );
+ DRM_DEBUG("Context switch from %d to %d\n", old, new);
- if ( new == dev->last_context ) {
- clear_bit( 0, &dev->context_flag );
- return 0;
- }
+ if (new == dev->last_context) {
+ clear_bit(0, &dev->context_flag);
+ return 0;
+ }
- return 0;
+ return 0;
}
/**
@@ -337,22 +342,22 @@ static int drm_context_switch( drm_device_t *dev, int old, int new )
* hardware lock is held, clears the drm_device::context_flag and wakes up
* drm_device::context_wait.
*/
-static int drm_context_switch_complete( drm_device_t *dev, int new )
+static int drm_context_switch_complete(drm_device_t * dev, int new)
{
- dev->last_context = new; /* PRE/POST: This is the _only_ writer. */
- dev->last_switch = jiffies;
+ dev->last_context = new; /* PRE/POST: This is the _only_ writer. */
+ dev->last_switch = jiffies;
- if ( !_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) ) {
- DRM_ERROR( "Lock isn't held after context switch\n" );
- }
+ if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
+ DRM_ERROR("Lock isn't held after context switch\n");
+ }
- /* If a context switch is ever initiated
- when the kernel holds the lock, release
- that lock here. */
- clear_bit( 0, &dev->context_flag );
- wake_up( &dev->context_wait );
+ /* If a context switch is ever initiated
+ when the kernel holds the lock, release
+ that lock here. */
+ clear_bit(0, &dev->context_flag);
+ wake_up(&dev->context_wait);
- return 0;
+ return 0;
}
/**
@@ -364,29 +369,28 @@ static int drm_context_switch_complete( drm_device_t *dev, int new )
* \param arg user argument pointing to a drm_ctx_res structure.
* \return zero on success or a negative number on failure.
*/
-int drm_resctx( struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg )
+int drm_resctx(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg)
{
drm_ctx_res_t res;
drm_ctx_t __user *argp = (void __user *)arg;
drm_ctx_t ctx;
int i;
- if ( copy_from_user( &res, argp, sizeof(res) ) )
+ if (copy_from_user(&res, argp, sizeof(res)))
return -EFAULT;
- if ( res.count >= DRM_RESERVED_CONTEXTS ) {
- memset( &ctx, 0, sizeof(ctx) );
- for ( i = 0 ; i < DRM_RESERVED_CONTEXTS ; i++ ) {
+ if (res.count >= DRM_RESERVED_CONTEXTS) {
+ memset(&ctx, 0, sizeof(ctx));
+ for (i = 0; i < DRM_RESERVED_CONTEXTS; i++) {
ctx.handle = i;
- if ( copy_to_user( &res.contexts[i],
- &ctx, sizeof(ctx) ) )
+ if (copy_to_user(&res.contexts[i], &ctx, sizeof(ctx)))
return -EFAULT;
}
}
res.count = DRM_RESERVED_CONTEXTS;
- if ( copy_to_user( argp, &res, sizeof(res) ) )
+ if (copy_to_user(argp, &res, sizeof(res)))
return -EFAULT;
return 0;
}
@@ -402,58 +406,57 @@ int drm_resctx( struct inode *inode, struct file *filp,
*
* Get a new handle for the context and copy to userspace.
*/
-int drm_addctx( struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg )
+int drm_addctx(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg)
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->head->dev;
- drm_ctx_list_t * ctx_entry;
+ drm_ctx_list_t *ctx_entry;
drm_ctx_t __user *argp = (void __user *)arg;
drm_ctx_t ctx;
- if ( copy_from_user( &ctx, argp, sizeof(ctx) ) )
+ if (copy_from_user(&ctx, argp, sizeof(ctx)))
return -EFAULT;
- ctx.handle = drm_ctxbitmap_next( dev );
- if ( ctx.handle == DRM_KERNEL_CONTEXT ) {
- /* Skip kernel's context and get a new one. */
- ctx.handle = drm_ctxbitmap_next( dev );
+ ctx.handle = drm_ctxbitmap_next(dev);
+ if (ctx.handle == DRM_KERNEL_CONTEXT) {
+ /* Skip kernel's context and get a new one. */
+ ctx.handle = drm_ctxbitmap_next(dev);
}
- DRM_DEBUG( "%d\n", ctx.handle );
- if ( ctx.handle == -1 ) {
- DRM_DEBUG( "Not enough free contexts.\n" );
- /* Should this return -EBUSY instead? */
+ DRM_DEBUG("%d\n", ctx.handle);
+ if (ctx.handle == -1) {
+ DRM_DEBUG("Not enough free contexts.\n");
+ /* Should this return -EBUSY instead? */
return -ENOMEM;
}
- if ( ctx.handle != DRM_KERNEL_CONTEXT )
- {
+ if (ctx.handle != DRM_KERNEL_CONTEXT) {
if (dev->driver->context_ctor)
dev->driver->context_ctor(dev, ctx.handle);
}
- ctx_entry = drm_alloc( sizeof(*ctx_entry), DRM_MEM_CTXLIST );
- if ( !ctx_entry ) {
+ ctx_entry = drm_alloc(sizeof(*ctx_entry), DRM_MEM_CTXLIST);
+ if (!ctx_entry) {
DRM_DEBUG("out of memory\n");
return -ENOMEM;
}
- INIT_LIST_HEAD( &ctx_entry->head );
+ INIT_LIST_HEAD(&ctx_entry->head);
ctx_entry->handle = ctx.handle;
ctx_entry->tag = priv;
- down( &dev->ctxlist_sem );
- list_add( &ctx_entry->head, &dev->ctxlist->head );
+ down(&dev->ctxlist_sem);
+ list_add(&ctx_entry->head, &dev->ctxlist->head);
++dev->ctx_count;
- up( &dev->ctxlist_sem );
+ up(&dev->ctxlist_sem);
- if ( copy_to_user( argp, &ctx, sizeof(ctx) ) )
+ if (copy_to_user(argp, &ctx, sizeof(ctx)))
return -EFAULT;
return 0;
}
-int drm_modctx( struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg )
+int drm_modctx(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg)
{
/* This does nothing */
return 0;
@@ -468,19 +471,19 @@ int drm_modctx( struct inode *inode, struct file *filp,
* \param arg user argument pointing to a drm_ctx structure.
* \return zero on success or a negative number on failure.
*/
-int drm_getctx( struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg )
+int drm_getctx(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg)
{
drm_ctx_t __user *argp = (void __user *)arg;
drm_ctx_t ctx;
- if ( copy_from_user( &ctx, argp, sizeof(ctx) ) )
+ if (copy_from_user(&ctx, argp, sizeof(ctx)))
return -EFAULT;
/* This is 0, because we don't handle any context flags */
ctx.flags = 0;
- if ( copy_to_user( argp, &ctx, sizeof(ctx) ) )
+ if (copy_to_user(argp, &ctx, sizeof(ctx)))
return -EFAULT;
return 0;
}
@@ -496,18 +499,18 @@ int drm_getctx( struct inode *inode, struct file *filp,
*
* Calls context_switch().
*/
-int drm_switchctx( struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg )
+int drm_switchctx(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg)
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->head->dev;
drm_ctx_t ctx;
- if ( copy_from_user( &ctx, (drm_ctx_t __user *)arg, sizeof(ctx) ) )
+ if (copy_from_user(&ctx, (drm_ctx_t __user *) arg, sizeof(ctx)))
return -EFAULT;
- DRM_DEBUG( "%d\n", ctx.handle );
- return drm_context_switch( dev, dev->last_context, ctx.handle );
+ DRM_DEBUG("%d\n", ctx.handle);
+ return drm_context_switch(dev, dev->last_context, ctx.handle);
}
/**
@@ -521,18 +524,18 @@ int drm_switchctx( struct inode *inode, struct file *filp,
*
* Calls context_switch_complete().
*/
-int drm_newctx( struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg )
+int drm_newctx(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg)
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->head->dev;
drm_ctx_t ctx;
- if ( copy_from_user( &ctx, (drm_ctx_t __user *)arg, sizeof(ctx) ) )
+ if (copy_from_user(&ctx, (drm_ctx_t __user *) arg, sizeof(ctx)))
return -EFAULT;
- DRM_DEBUG( "%d\n", ctx.handle );
- drm_context_switch_complete( dev, ctx.handle );
+ DRM_DEBUG("%d\n", ctx.handle);
+ drm_context_switch_complete(dev, ctx.handle);
return 0;
}
@@ -548,42 +551,41 @@ int drm_newctx( struct inode *inode, struct file *filp,
*
* If not the special kernel context, calls ctxbitmap_free() to free the specified context.
*/
-int drm_rmctx( struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg )
+int drm_rmctx(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg)
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->head->dev;
drm_ctx_t ctx;
- if ( copy_from_user( &ctx, (drm_ctx_t __user *)arg, sizeof(ctx) ) )
+ if (copy_from_user(&ctx, (drm_ctx_t __user *) arg, sizeof(ctx)))
return -EFAULT;
- DRM_DEBUG( "%d\n", ctx.handle );
- if ( ctx.handle == DRM_KERNEL_CONTEXT + 1 ) {
+ DRM_DEBUG("%d\n", ctx.handle);
+ if (ctx.handle == DRM_KERNEL_CONTEXT + 1) {
priv->remove_auth_on_close = 1;
}
- if ( ctx.handle != DRM_KERNEL_CONTEXT ) {
+ if (ctx.handle != DRM_KERNEL_CONTEXT) {
if (dev->driver->context_dtor)
dev->driver->context_dtor(dev, ctx.handle);
- drm_ctxbitmap_free( dev, ctx.handle );
+ drm_ctxbitmap_free(dev, ctx.handle);
}
- down( &dev->ctxlist_sem );
- if ( !list_empty( &dev->ctxlist->head ) ) {
+ down(&dev->ctxlist_sem);
+ if (!list_empty(&dev->ctxlist->head)) {
drm_ctx_list_t *pos, *n;
- list_for_each_entry_safe( pos, n, &dev->ctxlist->head, head ) {
- if ( pos->handle == ctx.handle ) {
- list_del( &pos->head );
- drm_free( pos, sizeof(*pos), DRM_MEM_CTXLIST );
+ list_for_each_entry_safe(pos, n, &dev->ctxlist->head, head) {
+ if (pos->handle == ctx.handle) {
+ list_del(&pos->head);
+ drm_free(pos, sizeof(*pos), DRM_MEM_CTXLIST);
--dev->ctx_count;
}
}
}
- up( &dev->ctxlist_sem );
+ up(&dev->ctxlist_sem);
return 0;
}
/*@}*/
-
diff --git a/drivers/char/drm/drm_dma.c b/drivers/char/drm/drm_dma.c
index 4a28c053c98b..2afab95ca036 100644
--- a/drivers/char/drm/drm_dma.c
+++ b/drivers/char/drm/drm_dma.c
@@ -1,5 +1,5 @@
/**
- * \file drm_dma.h
+ * \file drm_dma.c
* DMA IOCTL and function support
*
* \author Rickard E. (Rik) Faith <faith@valinux.com>
@@ -37,23 +37,23 @@
/**
* Initialize the DMA data.
- *
+ *
* \param dev DRM device.
* \return zero on success or a negative value on failure.
*
* Allocate and initialize a drm_device_dma structure.
*/
-int drm_dma_setup( drm_device_t *dev )
+int drm_dma_setup(drm_device_t * dev)
{
int i;
- dev->dma = drm_alloc( sizeof(*dev->dma), DRM_MEM_DRIVER );
- if ( !dev->dma )
+ dev->dma = drm_alloc(sizeof(*dev->dma), DRM_MEM_DRIVER);
+ if (!dev->dma)
return -ENOMEM;
- memset( dev->dma, 0, sizeof(*dev->dma) );
+ memset(dev->dma, 0, sizeof(*dev->dma));
- for ( i = 0 ; i <= DRM_MAX_ORDER ; i++ )
+ for (i = 0; i <= DRM_MAX_ORDER; i++)
memset(&dev->dma->bufs[i], 0, sizeof(dev->dma->bufs[0]));
return 0;
@@ -67,14 +67,15 @@ int drm_dma_setup( drm_device_t *dev )
* Free all pages associated with DMA buffers, the buffers and pages lists, and
* finally the the drm_device::dma structure itself.
*/
-void drm_dma_takedown(drm_device_t *dev)
+void drm_dma_takedown(drm_device_t * dev)
{
- drm_device_dma_t *dma = dev->dma;
- int i, j;
+ drm_device_dma_t *dma = dev->dma;
+ int i, j;
- if (!dma) return;
+ if (!dma)
+ return;
- /* Clear dma buffers */
+ /* Clear dma buffers */
for (i = 0; i <= DRM_MAX_ORDER; i++) {
if (dma->bufs[i].seg_count) {
DRM_DEBUG("order %d: buf_count = %d,"
@@ -85,64 +86,63 @@ void drm_dma_takedown(drm_device_t *dev)
for (j = 0; j < dma->bufs[i].seg_count; j++) {
if (dma->bufs[i].seglist[j]) {
drm_free_pages(dma->bufs[i].seglist[j],
- dma->bufs[i].page_order,
- DRM_MEM_DMA);
+ dma->bufs[i].page_order,
+ DRM_MEM_DMA);
}
}
drm_free(dma->bufs[i].seglist,
- dma->bufs[i].seg_count
- * sizeof(*dma->bufs[0].seglist),
- DRM_MEM_SEGS);
+ dma->bufs[i].seg_count
+ * sizeof(*dma->bufs[0].seglist), DRM_MEM_SEGS);
}
- if (dma->bufs[i].buf_count) {
- for (j = 0; j < dma->bufs[i].buf_count; j++) {
+ if (dma->bufs[i].buf_count) {
+ for (j = 0; j < dma->bufs[i].buf_count; j++) {
if (dma->bufs[i].buflist[j].dev_private) {
- drm_free(dma->bufs[i].buflist[j].dev_private,
- dma->bufs[i].buflist[j].dev_priv_size,
- DRM_MEM_BUFS);
+ drm_free(dma->bufs[i].buflist[j].
+ dev_private,
+ dma->bufs[i].buflist[j].
+ dev_priv_size, DRM_MEM_BUFS);
}
}
- drm_free(dma->bufs[i].buflist,
- dma->bufs[i].buf_count *
- sizeof(*dma->bufs[0].buflist),
- DRM_MEM_BUFS);
+ drm_free(dma->bufs[i].buflist,
+ dma->bufs[i].buf_count *
+ sizeof(*dma->bufs[0].buflist), DRM_MEM_BUFS);
}
}
if (dma->buflist) {
drm_free(dma->buflist,
- dma->buf_count * sizeof(*dma->buflist),
- DRM_MEM_BUFS);
+ dma->buf_count * sizeof(*dma->buflist), DRM_MEM_BUFS);
}
if (dma->pagelist) {
drm_free(dma->pagelist,
- dma->page_count * sizeof(*dma->pagelist),
- DRM_MEM_PAGES);
+ dma->page_count * sizeof(*dma->pagelist),
+ DRM_MEM_PAGES);
}
drm_free(dev->dma, sizeof(*dev->dma), DRM_MEM_DRIVER);
dev->dma = NULL;
}
-
/**
* Free a buffer.
*
* \param dev DRM device.
* \param buf buffer to free.
- *
+ *
* Resets the fields of \p buf.
*/
-void drm_free_buffer(drm_device_t *dev, drm_buf_t *buf)
+void drm_free_buffer(drm_device_t * dev, drm_buf_t * buf)
{
- if (!buf) return;
+ if (!buf)
+ return;
- buf->waiting = 0;
- buf->pending = 0;
- buf->filp = NULL;
- buf->used = 0;
+ buf->waiting = 0;
+ buf->pending = 0;
+ buf->filp = NULL;
+ buf->used = 0;
- if (drm_core_check_feature(dev, DRIVER_DMA_QUEUE) && waitqueue_active(&buf->dma_wait)) {
+ if (drm_core_check_feature(dev, DRIVER_DMA_QUEUE)
+ && waitqueue_active(&buf->dma_wait)) {
wake_up_interruptible(&buf->dma_wait);
}
}
@@ -154,12 +154,13 @@ void drm_free_buffer(drm_device_t *dev, drm_buf_t *buf)
*
* Frees each buffer associated with \p filp not already on the hardware.
*/
-void drm_core_reclaim_buffers(drm_device_t *dev, struct file *filp)
+void drm_core_reclaim_buffers(drm_device_t * dev, struct file *filp)
{
drm_device_dma_t *dma = dev->dma;
- int i;
+ int i;
- if (!dma) return;
+ if (!dma)
+ return;
for (i = 0; i < dma->buf_count; i++) {
if (dma->buflist[i]->filp == filp) {
switch (dma->buflist[i]->list) {
@@ -176,5 +177,5 @@ void drm_core_reclaim_buffers(drm_device_t *dev, struct file *filp)
}
}
}
-EXPORT_SYMBOL(drm_core_reclaim_buffers);
+EXPORT_SYMBOL(drm_core_reclaim_buffers);
diff --git a/drivers/char/drm/drm_drawable.c b/drivers/char/drm/drm_drawable.c
index e8e8e42be4c7..7857453c4f48 100644
--- a/drivers/char/drm/drm_drawable.c
+++ b/drivers/char/drm/drm_drawable.c
@@ -1,5 +1,5 @@
/**
- * \file drm_drawable.h
+ * \file drm_drawable.c
* IOCTLs for drawables
*
* \author Rickard E. (Rik) Faith <faith@valinux.com>
@@ -37,20 +37,20 @@
/** No-op. */
int drm_adddraw(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg)
+ unsigned int cmd, unsigned long arg)
{
drm_draw_t draw;
draw.handle = 0; /* NOOP */
DRM_DEBUG("%d\n", draw.handle);
- if (copy_to_user((drm_draw_t __user *)arg, &draw, sizeof(draw)))
+ if (copy_to_user((drm_draw_t __user *) arg, &draw, sizeof(draw)))
return -EFAULT;
return 0;
}
/** No-op. */
int drm_rmdraw(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg)
+ unsigned int cmd, unsigned long arg)
{
return 0; /* NOOP */
}
diff --git a/drivers/char/drm/drm_drv.c b/drivers/char/drm/drm_drv.c
index 041bb47b5c39..4dff7554eb08 100644
--- a/drivers/char/drm/drm_drv.c
+++ b/drivers/char/drm/drm_drv.c
@@ -1,5 +1,5 @@
/**
- * \file drm_drv.h
+ * \file drm_drv.c
* Generic driver template
*
* \author Rickard E. (Rik) Faith <faith@valinux.com>
@@ -55,67 +55,67 @@ static int drm_version(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
/** Ioctl table */
-static drm_ioctl_desc_t drm_ioctls[] = {
- [DRM_IOCTL_NR(DRM_IOCTL_VERSION)] = { drm_version, 0, 0 },
- [DRM_IOCTL_NR(DRM_IOCTL_GET_UNIQUE)] = { drm_getunique, 0, 0 },
- [DRM_IOCTL_NR(DRM_IOCTL_GET_MAGIC)] = { drm_getmagic, 0, 0 },
- [DRM_IOCTL_NR(DRM_IOCTL_IRQ_BUSID)] = { drm_irq_by_busid, 0, 1 },
- [DRM_IOCTL_NR(DRM_IOCTL_GET_MAP)] = { drm_getmap, 0, 0 },
- [DRM_IOCTL_NR(DRM_IOCTL_GET_CLIENT)] = { drm_getclient, 0, 0 },
- [DRM_IOCTL_NR(DRM_IOCTL_GET_STATS)] = { drm_getstats, 0, 0 },
- [DRM_IOCTL_NR(DRM_IOCTL_SET_VERSION)] = { drm_setversion, 0, 1 },
-
- [DRM_IOCTL_NR(DRM_IOCTL_SET_UNIQUE)] = { drm_setunique, 1, 1 },
- [DRM_IOCTL_NR(DRM_IOCTL_BLOCK)] = { drm_noop, 1, 1 },
- [DRM_IOCTL_NR(DRM_IOCTL_UNBLOCK)] = { drm_noop, 1, 1 },
- [DRM_IOCTL_NR(DRM_IOCTL_AUTH_MAGIC)] = { drm_authmagic, 1, 1 },
-
- [DRM_IOCTL_NR(DRM_IOCTL_ADD_MAP)] = { drm_addmap_ioctl,1, 1 },
- [DRM_IOCTL_NR(DRM_IOCTL_RM_MAP)] = { drm_rmmap_ioctl, 1, 0 },
-
- [DRM_IOCTL_NR(DRM_IOCTL_SET_SAREA_CTX)] = { drm_setsareactx, 1, 1 },
- [DRM_IOCTL_NR(DRM_IOCTL_GET_SAREA_CTX)] = { drm_getsareactx, 1, 0 },
-
- [DRM_IOCTL_NR(DRM_IOCTL_ADD_CTX)] = { drm_addctx, 1, 1 },
- [DRM_IOCTL_NR(DRM_IOCTL_RM_CTX)] = { drm_rmctx, 1, 1 },
- [DRM_IOCTL_NR(DRM_IOCTL_MOD_CTX)] = { drm_modctx, 1, 1 },
- [DRM_IOCTL_NR(DRM_IOCTL_GET_CTX)] = { drm_getctx, 1, 0 },
- [DRM_IOCTL_NR(DRM_IOCTL_SWITCH_CTX)] = { drm_switchctx, 1, 1 },
- [DRM_IOCTL_NR(DRM_IOCTL_NEW_CTX)] = { drm_newctx, 1, 1 },
- [DRM_IOCTL_NR(DRM_IOCTL_RES_CTX)] = { drm_resctx, 1, 0 },
-
- [DRM_IOCTL_NR(DRM_IOCTL_ADD_DRAW)] = { drm_adddraw, 1, 1 },
- [DRM_IOCTL_NR(DRM_IOCTL_RM_DRAW)] = { drm_rmdraw, 1, 1 },
-
- [DRM_IOCTL_NR(DRM_IOCTL_LOCK)] = { drm_lock, 1, 0 },
- [DRM_IOCTL_NR(DRM_IOCTL_UNLOCK)] = { drm_unlock, 1, 0 },
-
- [DRM_IOCTL_NR(DRM_IOCTL_FINISH)] = { drm_noop, 1, 0 },
-
- [DRM_IOCTL_NR(DRM_IOCTL_ADD_BUFS)] = { drm_addbufs, 1, 1 },
- [DRM_IOCTL_NR(DRM_IOCTL_MARK_BUFS)] = { drm_markbufs, 1, 1 },
- [DRM_IOCTL_NR(DRM_IOCTL_INFO_BUFS)] = { drm_infobufs, 1, 0 },
- [DRM_IOCTL_NR(DRM_IOCTL_MAP_BUFS)] = { drm_mapbufs, 1, 0 },
- [DRM_IOCTL_NR(DRM_IOCTL_FREE_BUFS)] = { drm_freebufs, 1, 0 },
+static drm_ioctl_desc_t drm_ioctls[] = {
+ [DRM_IOCTL_NR(DRM_IOCTL_VERSION)] = {drm_version, 0, 0},
+ [DRM_IOCTL_NR(DRM_IOCTL_GET_UNIQUE)] = {drm_getunique, 0, 0},
+ [DRM_IOCTL_NR(DRM_IOCTL_GET_MAGIC)] = {drm_getmagic, 0, 0},
+ [DRM_IOCTL_NR(DRM_IOCTL_IRQ_BUSID)] = {drm_irq_by_busid, 0, 1},
+ [DRM_IOCTL_NR(DRM_IOCTL_GET_MAP)] = {drm_getmap, 0, 0},
+ [DRM_IOCTL_NR(DRM_IOCTL_GET_CLIENT)] = {drm_getclient, 0, 0},
+ [DRM_IOCTL_NR(DRM_IOCTL_GET_STATS)] = {drm_getstats, 0, 0},
+ [DRM_IOCTL_NR(DRM_IOCTL_SET_VERSION)] = {drm_setversion, 0, 1},
+
+ [DRM_IOCTL_NR(DRM_IOCTL_SET_UNIQUE)] = {drm_setunique, 1, 1},
+ [DRM_IOCTL_NR(DRM_IOCTL_BLOCK)] = {drm_noop, 1, 1},
+ [DRM_IOCTL_NR(DRM_IOCTL_UNBLOCK)] = {drm_noop, 1, 1},
+ [DRM_IOCTL_NR(DRM_IOCTL_AUTH_MAGIC)] = {drm_authmagic, 1, 1},
+
+ [DRM_IOCTL_NR(DRM_IOCTL_ADD_MAP)] = {drm_addmap_ioctl, 1, 1},
+ [DRM_IOCTL_NR(DRM_IOCTL_RM_MAP)] = {drm_rmmap_ioctl, 1, 0},
+
+ [DRM_IOCTL_NR(DRM_IOCTL_SET_SAREA_CTX)] = {drm_setsareactx, 1, 1},
+ [DRM_IOCTL_NR(DRM_IOCTL_GET_SAREA_CTX)] = {drm_getsareactx, 1, 0},
+
+ [DRM_IOCTL_NR(DRM_IOCTL_ADD_CTX)] = {drm_addctx, 1, 1},
+ [DRM_IOCTL_NR(DRM_IOCTL_RM_CTX)] = {drm_rmctx, 1, 1},
+ [DRM_IOCTL_NR(DRM_IOCTL_MOD_CTX)] = {drm_modctx, 1, 1},
+ [DRM_IOCTL_NR(DRM_IOCTL_GET_CTX)] = {drm_getctx, 1, 0},
+ [DRM_IOCTL_NR(DRM_IOCTL_SWITCH_CTX)] = {drm_switchctx, 1, 1},
+ [DRM_IOCTL_NR(DRM_IOCTL_NEW_CTX)] = {drm_newctx, 1, 1},
+ [DRM_IOCTL_NR(DRM_IOCTL_RES_CTX)] = {drm_resctx, 1, 0},
+
+ [DRM_IOCTL_NR(DRM_IOCTL_ADD_DRAW)] = {drm_adddraw, 1, 1},
+ [DRM_IOCTL_NR(DRM_IOCTL_RM_DRAW)] = {drm_rmdraw, 1, 1},
+
+ [DRM_IOCTL_NR(DRM_IOCTL_LOCK)] = {drm_lock, 1, 0},
+ [DRM_IOCTL_NR(DRM_IOCTL_UNLOCK)] = {drm_unlock, 1, 0},
+
+ [DRM_IOCTL_NR(DRM_IOCTL_FINISH)] = {drm_noop, 1, 0},
+
+ [DRM_IOCTL_NR(DRM_IOCTL_ADD_BUFS)] = {drm_addbufs, 1, 1},
+ [DRM_IOCTL_NR(DRM_IOCTL_MARK_BUFS)] = {drm_markbufs, 1, 1},
+ [DRM_IOCTL_NR(DRM_IOCTL_INFO_BUFS)] = {drm_infobufs, 1, 0},
+ [DRM_IOCTL_NR(DRM_IOCTL_MAP_BUFS)] = {drm_mapbufs, 1, 0},
+ [DRM_IOCTL_NR(DRM_IOCTL_FREE_BUFS)] = {drm_freebufs, 1, 0},
/* The DRM_IOCTL_DMA ioctl should be defined by the driver. */
- [DRM_IOCTL_NR(DRM_IOCTL_CONTROL)] = { drm_control, 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_CONTROL)] = {drm_control, 1, 1},
#if __OS_HAS_AGP
- [DRM_IOCTL_NR(DRM_IOCTL_AGP_ACQUIRE)] = { drm_agp_acquire_ioctl, 1, 1 },
- [DRM_IOCTL_NR(DRM_IOCTL_AGP_RELEASE)] = { drm_agp_release_ioctl, 1, 1 },
- [DRM_IOCTL_NR(DRM_IOCTL_AGP_ENABLE)] = { drm_agp_enable_ioctl, 1, 1 },
- [DRM_IOCTL_NR(DRM_IOCTL_AGP_INFO)] = { drm_agp_info_ioctl, 1, 0 },
- [DRM_IOCTL_NR(DRM_IOCTL_AGP_ALLOC)] = { drm_agp_alloc, 1, 1 },
- [DRM_IOCTL_NR(DRM_IOCTL_AGP_FREE)] = { drm_agp_free, 1, 1 },
- [DRM_IOCTL_NR(DRM_IOCTL_AGP_BIND)] = { drm_agp_bind, 1, 1 },
- [DRM_IOCTL_NR(DRM_IOCTL_AGP_UNBIND)] = { drm_agp_unbind, 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_AGP_ACQUIRE)] = {drm_agp_acquire_ioctl, 1, 1},
+ [DRM_IOCTL_NR(DRM_IOCTL_AGP_RELEASE)] = {drm_agp_release_ioctl, 1, 1},
+ [DRM_IOCTL_NR(DRM_IOCTL_AGP_ENABLE)] = {drm_agp_enable_ioctl, 1, 1},
+ [DRM_IOCTL_NR(DRM_IOCTL_AGP_INFO)] = {drm_agp_info_ioctl, 1, 0},
+ [DRM_IOCTL_NR(DRM_IOCTL_AGP_ALLOC)] = {drm_agp_alloc, 1, 1},
+ [DRM_IOCTL_NR(DRM_IOCTL_AGP_FREE)] = {drm_agp_free, 1, 1},
+ [DRM_IOCTL_NR(DRM_IOCTL_AGP_BIND)] = {drm_agp_bind, 1, 1},
+ [DRM_IOCTL_NR(DRM_IOCTL_AGP_UNBIND)] = {drm_agp_unbind, 1, 1},
#endif
- [DRM_IOCTL_NR(DRM_IOCTL_SG_ALLOC)] = { drm_sg_alloc, 1, 1 },
- [DRM_IOCTL_NR(DRM_IOCTL_SG_FREE)] = { drm_sg_free, 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_SG_ALLOC)] = {drm_sg_alloc, 1, 1},
+ [DRM_IOCTL_NR(DRM_IOCTL_SG_FREE)] = {drm_sg_free, 1, 1},
- [DRM_IOCTL_NR(DRM_IOCTL_WAIT_VBLANK)] = { drm_wait_vblank, 0, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_WAIT_VBLANK)] = {drm_wait_vblank, 0, 0},
};
#define DRIVER_IOCTL_COUNT DRM_ARRAY_SIZE( drm_ioctls )
@@ -129,17 +129,17 @@ static drm_ioctl_desc_t drm_ioctls[] = {
*
* \sa drm_device
*/
-int drm_takedown( drm_device_t *dev )
+int drm_takedown(drm_device_t * dev)
{
drm_magic_entry_t *pt, *next;
drm_map_list_t *r_list;
drm_vma_entry_t *vma, *vma_next;
int i;
- DRM_DEBUG( "\n" );
+ DRM_DEBUG("\n");
if (dev->driver->pretakedown)
- dev->driver->pretakedown(dev);
+ dev->driver->pretakedown(dev);
DRM_DEBUG("driver pretakedown completed\n");
if (dev->unique) {
@@ -148,95 +148,95 @@ int drm_takedown( drm_device_t *dev )
dev->unique_len = 0;
}
- if ( dev->irq_enabled ) drm_irq_uninstall( dev );
+ if (dev->irq_enabled)
+ drm_irq_uninstall(dev);
- down( &dev->struct_sem );
- del_timer( &dev->timer );
+ down(&dev->struct_sem);
+ del_timer(&dev->timer);
- /* Clear pid list */
- for ( i = 0 ; i < DRM_HASH_SIZE ; i++ ) {
- for ( pt = dev->magiclist[i].head ; pt ; pt = next ) {
+ /* Clear pid list */
+ for (i = 0; i < DRM_HASH_SIZE; i++) {
+ for (pt = dev->magiclist[i].head; pt; pt = next) {
next = pt->next;
- drm_free( pt, sizeof(*pt), DRM_MEM_MAGIC );
+ drm_free(pt, sizeof(*pt), DRM_MEM_MAGIC);
}
dev->magiclist[i].head = dev->magiclist[i].tail = NULL;
}
- /* Clear AGP information */
+ /* Clear AGP information */
if (drm_core_has_AGP(dev) && dev->agp) {
drm_agp_mem_t *entry;
drm_agp_mem_t *nexte;
- /* Remove AGP resources, but leave dev->agp
- intact until drv_cleanup is called. */
- for ( entry = dev->agp->memory ; entry ; entry = nexte ) {
+ /* Remove AGP resources, but leave dev->agp
+ intact until drv_cleanup is called. */
+ for (entry = dev->agp->memory; entry; entry = nexte) {
nexte = entry->next;
- if ( entry->bound ) drm_unbind_agp( entry->memory );
- drm_free_agp( entry->memory, entry->pages );
- drm_free( entry, sizeof(*entry), DRM_MEM_AGPLISTS );
+ if (entry->bound)
+ drm_unbind_agp(entry->memory);
+ drm_free_agp(entry->memory, entry->pages);
+ drm_free(entry, sizeof(*entry), DRM_MEM_AGPLISTS);
}
dev->agp->memory = NULL;
if (dev->agp->acquired)
- drm_agp_release(dev);
+ drm_agp_release(dev);
dev->agp->acquired = 0;
- dev->agp->enabled = 0;
+ dev->agp->enabled = 0;
}
if (drm_core_check_feature(dev, DRIVER_SG) && dev->sg) {
drm_sg_cleanup(dev->sg);
dev->sg = NULL;
}
- /* Clear vma list (only built for debugging) */
- if ( dev->vmalist ) {
- for ( vma = dev->vmalist ; vma ; vma = vma_next ) {
+ /* Clear vma list (only built for debugging) */
+ if (dev->vmalist) {
+ for (vma = dev->vmalist; vma; vma = vma_next) {
vma_next = vma->next;
- drm_free( vma, sizeof(*vma), DRM_MEM_VMAS );
+ drm_free(vma, sizeof(*vma), DRM_MEM_VMAS);
}
dev->vmalist = NULL;
}
- if( dev->maplist ) {
+ if (dev->maplist) {
while (!list_empty(&dev->maplist->head)) {
struct list_head *list = dev->maplist->head.next;
r_list = list_entry(list, drm_map_list_t, head);
drm_rmmap_locked(dev, r_list->map);
}
- }
-
- if (drm_core_check_feature(dev, DRIVER_DMA_QUEUE) && dev->queuelist ) {
- for ( i = 0 ; i < dev->queue_count ; i++ ) {
- if ( dev->queuelist[i] ) {
- drm_free( dev->queuelist[i],
- sizeof(*dev->queuelist[0]),
- DRM_MEM_QUEUES );
+ }
+
+ if (drm_core_check_feature(dev, DRIVER_DMA_QUEUE) && dev->queuelist) {
+ for (i = 0; i < dev->queue_count; i++) {
+ if (dev->queuelist[i]) {
+ drm_free(dev->queuelist[i],
+ sizeof(*dev->queuelist[0]),
+ DRM_MEM_QUEUES);
dev->queuelist[i] = NULL;
}
}
- drm_free( dev->queuelist,
- dev->queue_slots * sizeof(*dev->queuelist),
- DRM_MEM_QUEUES );
+ drm_free(dev->queuelist,
+ dev->queue_slots * sizeof(*dev->queuelist),
+ DRM_MEM_QUEUES);
dev->queuelist = NULL;
}
dev->queue_count = 0;
if (drm_core_check_feature(dev, DRIVER_HAVE_DMA))
- drm_dma_takedown( dev );
+ drm_dma_takedown(dev);
- if ( dev->lock.hw_lock ) {
- dev->sigdata.lock = dev->lock.hw_lock = NULL; /* SHM removed */
+ if (dev->lock.hw_lock) {
+ dev->sigdata.lock = dev->lock.hw_lock = NULL; /* SHM removed */
dev->lock.filp = NULL;
- wake_up_interruptible( &dev->lock.lock_queue );
+ wake_up_interruptible(&dev->lock.lock_queue);
}
- up( &dev->struct_sem );
+ up(&dev->struct_sem);
DRM_DEBUG("takedown completed\n");
return 0;
}
-
-
/**
* Module initialization. Called via init_module at module load time, or via
* linux/init/main.c (this is not currently supported).
@@ -246,26 +246,28 @@ int drm_takedown( drm_device_t *dev )
* Initializes an array of drm_device structures, and attempts to
* initialize all available devices, using consecutive minors, registering the
* stubs and initializing the AGP device.
- *
+ *
* Expands the \c DRIVER_PREINIT and \c DRIVER_POST_INIT macros before and
* after the initialization for driver customization.
*/
-int drm_init( struct drm_driver *driver )
+int drm_init(struct drm_driver *driver)
{
struct pci_dev *pdev = NULL;
struct pci_device_id *pid;
int i;
- DRM_DEBUG( "\n" );
+ DRM_DEBUG("\n");
drm_mem_init();
- for (i=0; driver->pci_driver.id_table[i].vendor != 0; i++) {
+ for (i = 0; driver->pci_driver.id_table[i].vendor != 0; i++) {
pid = (struct pci_device_id *)&driver->pci_driver.id_table[i];
-
- pdev=NULL;
- /* pass back in pdev to account for multiple identical cards */
- while ((pdev = pci_get_subsys(pid->vendor, pid->device, pid->subvendor, pid->subdevice, pdev)) != NULL) {
+
+ pdev = NULL;
+ /* pass back in pdev to account for multiple identical cards */
+ while ((pdev =
+ pci_get_subsys(pid->vendor, pid->device, pid->subvendor,
+ pid->subdevice, pdev)) != NULL) {
/* stealth mode requires a manual probe */
pci_dev_get(pdev);
drm_get_dev(pdev, pid, driver);
@@ -273,62 +275,63 @@ int drm_init( struct drm_driver *driver )
}
return 0;
}
+
EXPORT_SYMBOL(drm_init);
/**
* Called via cleanup_module() at module unload time.
*
* Cleans up all DRM device, calling takedown().
- *
+ *
* \sa drm_init
*/
-static void drm_cleanup( drm_device_t *dev )
+static void drm_cleanup(drm_device_t * dev)
{
- DRM_DEBUG( "\n" );
+ DRM_DEBUG("\n");
if (!dev) {
DRM_ERROR("cleanup called no dev\n");
return;
}
- drm_takedown( dev );
+ drm_takedown(dev);
if (dev->maplist) {
drm_free(dev->maplist, sizeof(*dev->maplist), DRM_MEM_MAPS);
dev->maplist = NULL;
}
- drm_ctxbitmap_cleanup( dev );
-
+ drm_ctxbitmap_cleanup(dev);
+
if (drm_core_has_MTRR(dev) && drm_core_has_AGP(dev) &&
dev->agp && dev->agp->agp_mtrr >= 0) {
int retval;
- retval = mtrr_del( dev->agp->agp_mtrr,
- dev->agp->agp_info.aper_base,
- dev->agp->agp_info.aper_size*1024*1024 );
- DRM_DEBUG( "mtrr_del=%d\n", retval );
+ retval = mtrr_del(dev->agp->agp_mtrr,
+ dev->agp->agp_info.aper_base,
+ dev->agp->agp_info.aper_size * 1024 * 1024);
+ DRM_DEBUG("mtrr_del=%d\n", retval);
}
-
- if (drm_core_has_AGP(dev) && dev->agp ) {
- drm_free( dev->agp, sizeof(*dev->agp), DRM_MEM_AGPLISTS );
+
+ if (drm_core_has_AGP(dev) && dev->agp) {
+ drm_free(dev->agp, sizeof(*dev->agp), DRM_MEM_AGPLISTS);
dev->agp = NULL;
}
if (dev->driver->postcleanup)
dev->driver->postcleanup(dev);
-
+
drm_put_head(&dev->primary);
- if ( drm_put_dev(dev) )
- DRM_ERROR( "Cannot unload module\n" );
+ if (drm_put_dev(dev))
+ DRM_ERROR("Cannot unload module\n");
}
-void drm_exit (struct drm_driver *driver)
+void drm_exit(struct drm_driver *driver)
{
int i;
drm_device_t *dev = NULL;
drm_head_t *head;
-
- DRM_DEBUG( "\n" );
+
+ DRM_DEBUG("\n");
for (i = 0; i < drm_cards_limit; i++) {
head = drm_heads[i];
@@ -336,9 +339,9 @@ void drm_exit (struct drm_driver *driver)
continue;
if (!head->dev)
continue;
- if (head->dev->driver!=driver)
+ if (head->dev->driver != driver)
continue;
- dev=head->dev;
+ dev = head->dev;
}
if (dev) {
/* release the pci driver */
@@ -346,32 +349,35 @@ void drm_exit (struct drm_driver *driver)
pci_dev_put(dev->pdev);
drm_cleanup(dev);
}
- DRM_INFO( "Module unloaded\n" );
+ DRM_INFO("Module unloaded\n");
}
+
EXPORT_SYMBOL(drm_exit);
/** File operations structure */
static struct file_operations drm_stub_fops = {
.owner = THIS_MODULE,
- .open = drm_stub_open
+ .open = drm_stub_open
};
static int __init drm_core_init(void)
{
int ret = -ENOMEM;
-
- drm_cards_limit = (drm_cards_limit < DRM_MAX_MINOR + 1 ? drm_cards_limit : DRM_MAX_MINOR + 1);
- drm_heads = drm_calloc(drm_cards_limit,
- sizeof(*drm_heads), DRM_MEM_STUB);
- if(!drm_heads)
+
+ drm_cards_limit =
+ (drm_cards_limit <
+ DRM_MAX_MINOR + 1 ? drm_cards_limit : DRM_MAX_MINOR + 1);
+ drm_heads =
+ drm_calloc(drm_cards_limit, sizeof(*drm_heads), DRM_MEM_STUB);
+ if (!drm_heads)
goto err_p1;
-
+
if (register_chrdev(DRM_MAJOR, "drm", &drm_stub_fops))
goto err_p1;
-
+
drm_class = drm_sysfs_create(THIS_MODULE, "drm");
if (IS_ERR(drm_class)) {
- printk (KERN_ERR "DRM: Error creating drm class.\n");
+ printk(KERN_ERR "DRM: Error creating drm class.\n");
ret = PTR_ERR(drm_class);
goto err_p2;
}
@@ -382,35 +388,31 @@ static int __init drm_core_init(void)
ret = -1;
goto err_p3;
}
-
- DRM_INFO( "Initialized %s %d.%d.%d %s\n",
- CORE_NAME, CORE_MAJOR, CORE_MINOR, CORE_PATCHLEVEL,
- CORE_DATE);
+
+ DRM_INFO("Initialized %s %d.%d.%d %s\n",
+ CORE_NAME, CORE_MAJOR, CORE_MINOR, CORE_PATCHLEVEL, CORE_DATE);
return 0;
-err_p3:
+ err_p3:
drm_sysfs_destroy(drm_class);
-err_p2:
+ err_p2:
unregister_chrdev(DRM_MAJOR, "drm");
drm_free(drm_heads, sizeof(*drm_heads) * drm_cards_limit, DRM_MEM_STUB);
-err_p1:
+ err_p1:
return ret;
}
-static void __exit drm_core_exit (void)
+static void __exit drm_core_exit(void)
{
remove_proc_entry("dri", NULL);
drm_sysfs_destroy(drm_class);
unregister_chrdev(DRM_MAJOR, "drm");
- drm_free(drm_heads, sizeof(*drm_heads) *
- drm_cards_limit, DRM_MEM_STUB);
+ drm_free(drm_heads, sizeof(*drm_heads) * drm_cards_limit, DRM_MEM_STUB);
}
-
-module_init( drm_core_init );
-module_exit( drm_core_exit );
-
+module_init(drm_core_init);
+module_exit(drm_core_exit);
/**
* Get version information
@@ -423,8 +425,8 @@ module_exit( drm_core_exit );
*
* Fills in the version information in \p arg.
*/
-static int drm_version( struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg )
+static int drm_version(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg)
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->head->dev;
@@ -432,21 +434,19 @@ static int drm_version( struct inode *inode, struct file *filp,
drm_version_t version;
int ret;
- if ( copy_from_user( &version, argp, sizeof(version) ) )
+ if (copy_from_user(&version, argp, sizeof(version)))
return -EFAULT;
/* version is a required function to return the personality module version */
if ((ret = dev->driver->version(&version)))
return ret;
-
- if ( copy_to_user( argp, &version, sizeof(version) ) )
+
+ if (copy_to_user(argp, &version, sizeof(version)))
return -EFAULT;
return 0;
}
-
-
-/**
+/**
* Called whenever a process performs an ioctl on /dev/drm.
*
* \param inode device inode.
@@ -458,8 +458,8 @@ static int drm_version( struct inode *inode, struct file *filp,
* Looks up the ioctl function in the ::ioctls table, checking for root
* previleges if so required, and dispatches to the respective function.
*/
-int drm_ioctl( struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg )
+int drm_ioctl(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg)
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->head->dev;
@@ -468,40 +468,43 @@ int drm_ioctl( struct inode *inode, struct file *filp,
unsigned int nr = DRM_IOCTL_NR(cmd);
int retcode = -EINVAL;
- atomic_inc( &dev->ioctl_count );
- atomic_inc( &dev->counts[_DRM_STAT_IOCTLS] );
+ atomic_inc(&dev->ioctl_count);
+ atomic_inc(&dev->counts[_DRM_STAT_IOCTLS]);
++priv->ioctl_count;
- DRM_DEBUG( "pid=%d, cmd=0x%02x, nr=0x%02x, dev 0x%lx, auth=%d\n",
- current->pid, cmd, nr, (long)old_encode_dev(priv->head->device),
- priv->authenticated );
-
+ DRM_DEBUG("pid=%d, cmd=0x%02x, nr=0x%02x, dev 0x%lx, auth=%d\n",
+ current->pid, cmd, nr,
+ (long)old_encode_dev(priv->head->device),
+ priv->authenticated);
+
if (nr < DRIVER_IOCTL_COUNT)
ioctl = &drm_ioctls[nr];
- else if ((nr >= DRM_COMMAND_BASE) && (nr < DRM_COMMAND_BASE + dev->driver->num_ioctls))
+ else if ((nr >= DRM_COMMAND_BASE)
+ && (nr < DRM_COMMAND_BASE + dev->driver->num_ioctls))
ioctl = &dev->driver->ioctls[nr - DRM_COMMAND_BASE];
else
goto err_i1;
-
+
func = ioctl->func;
/* is there a local override? */
if ((nr == DRM_IOCTL_NR(DRM_IOCTL_DMA)) && dev->driver->dma_ioctl)
func = dev->driver->dma_ioctl;
-
- if ( !func ) {
- DRM_DEBUG( "no function\n" );
+
+ if (!func) {
+ DRM_DEBUG("no function\n");
retcode = -EINVAL;
- } else if ( ( ioctl->root_only && !capable( CAP_SYS_ADMIN ) )||
- ( ioctl->auth_needed && !priv->authenticated ) ) {
+ } else if ((ioctl->root_only && !capable(CAP_SYS_ADMIN)) ||
+ (ioctl->auth_needed && !priv->authenticated)) {
retcode = -EACCES;
} else {
- retcode = func( inode, filp, cmd, arg );
+ retcode = func(inode, filp, cmd, arg);
}
-
-err_i1:
- atomic_dec( &dev->ioctl_count );
- if (retcode) DRM_DEBUG( "ret = %x\n", retcode);
+
+ err_i1:
+ atomic_dec(&dev->ioctl_count);
+ if (retcode)
+ DRM_DEBUG("ret = %x\n", retcode);
return retcode;
}
-EXPORT_SYMBOL(drm_ioctl);
+EXPORT_SYMBOL(drm_ioctl);
diff --git a/drivers/char/drm/drm_fops.c b/drivers/char/drm/drm_fops.c
index a1f4e9cd64ed..bf0a740122bf 100644
--- a/drivers/char/drm/drm_fops.c
+++ b/drivers/char/drm/drm_fops.c
@@ -1,7 +1,7 @@
/**
- * \file drm_fops.h
+ * \file drm_fops.c
* File operations for DRM
- *
+ *
* \author Rickard E. (Rik) Faith <faith@valinux.com>
* \author Daryll Strauss <daryll@valinux.com>
* \author Gareth Hughes <gareth@valinux.com>
@@ -37,49 +37,48 @@
#include "drmP.h"
#include <linux/poll.h>
-static int drm_open_helper(struct inode *inode, struct file *filp, drm_device_t *dev);
+static int drm_open_helper(struct inode *inode, struct file *filp,
+ drm_device_t * dev);
-static int drm_setup( drm_device_t *dev )
+static int drm_setup(drm_device_t * dev)
{
int i;
int ret;
- if (dev->driver->presetup)
- {
- ret=dev->driver->presetup(dev);
- if (ret!=0)
+ if (dev->driver->presetup) {
+ ret = dev->driver->presetup(dev);
+ if (ret != 0)
return ret;
}
- atomic_set( &dev->ioctl_count, 0 );
- atomic_set( &dev->vma_count, 0 );
+ atomic_set(&dev->ioctl_count, 0);
+ atomic_set(&dev->vma_count, 0);
dev->buf_use = 0;
- atomic_set( &dev->buf_alloc, 0 );
+ atomic_set(&dev->buf_alloc, 0);
- if (drm_core_check_feature(dev, DRIVER_HAVE_DMA))
- {
- i = drm_dma_setup( dev );
- if ( i < 0 )
+ if (drm_core_check_feature(dev, DRIVER_HAVE_DMA)) {
+ i = drm_dma_setup(dev);
+ if (i < 0)
return i;
}
- for ( i = 0 ; i < DRM_ARRAY_SIZE(dev->counts) ; i++ )
- atomic_set( &dev->counts[i], 0 );
+ for (i = 0; i < DRM_ARRAY_SIZE(dev->counts); i++)
+ atomic_set(&dev->counts[i], 0);
- for ( i = 0 ; i < DRM_HASH_SIZE ; i++ ) {
+ for (i = 0; i < DRM_HASH_SIZE; i++) {
dev->magiclist[i].head = NULL;
dev->magiclist[i].tail = NULL;
}
- dev->ctxlist = drm_alloc(sizeof(*dev->ctxlist),
- DRM_MEM_CTXLIST);
- if(dev->ctxlist == NULL) return -ENOMEM;
+ dev->ctxlist = drm_alloc(sizeof(*dev->ctxlist), DRM_MEM_CTXLIST);
+ if (dev->ctxlist == NULL)
+ return -ENOMEM;
memset(dev->ctxlist, 0, sizeof(*dev->ctxlist));
INIT_LIST_HEAD(&dev->ctxlist->head);
dev->vmalist = NULL;
dev->sigdata.lock = dev->lock.hw_lock = NULL;
- init_waitqueue_head( &dev->lock.lock_queue );
+ init_waitqueue_head(&dev->lock.lock_queue);
dev->queue_count = 0;
dev->queue_reserved = 0;
dev->queue_slots = 0;
@@ -91,24 +90,21 @@ static int drm_setup( drm_device_t *dev )
dev->last_context = 0;
dev->last_switch = 0;
dev->last_checked = 0;
- init_waitqueue_head( &dev->context_wait );
+ init_waitqueue_head(&dev->context_wait);
dev->if_version = 0;
dev->ctx_start = 0;
dev->lck_start = 0;
- dev->buf_rp = dev->buf;
- dev->buf_wp = dev->buf;
- dev->buf_end = dev->buf + DRM_BSZ;
dev->buf_async = NULL;
- init_waitqueue_head( &dev->buf_readers );
- init_waitqueue_head( &dev->buf_writers );
+ init_waitqueue_head(&dev->buf_readers);
+ init_waitqueue_head(&dev->buf_writers);
- DRM_DEBUG( "\n" );
+ DRM_DEBUG("\n");
/*
* The kernel's context could be created here, but is now created
- * in drm_dma_enqueue. This is more resource-efficient for
+ * in drm_dma_enqueue. This is more resource-efficient for
* hardware that does not do DMA, but may mean that
* drm_select_queue fails between the time the interrupt is
* initialized and the time the queues are initialized.
@@ -121,7 +117,7 @@ static int drm_setup( drm_device_t *dev )
/**
* Open file.
- *
+ *
* \param inode device inode
* \param filp file pointer.
* \return zero on success or a negative number on failure.
@@ -130,7 +126,7 @@ static int drm_setup( drm_device_t *dev )
* increments the device open count. If the open count was previous at zero,
* i.e., it's the first that the device is open, then calls setup().
*/
-int drm_open( struct inode *inode, struct file *filp )
+int drm_open(struct inode *inode, struct file *filp)
{
drm_device_t *dev = NULL;
int minor = iminor(inode);
@@ -138,26 +134,27 @@ int drm_open( struct inode *inode, struct file *filp )
if (!((minor >= 0) && (minor < drm_cards_limit)))
return -ENODEV;
-
+
if (!drm_heads[minor])
return -ENODEV;
if (!(dev = drm_heads[minor]->dev))
return -ENODEV;
-
- retcode = drm_open_helper( inode, filp, dev );
- if ( !retcode ) {
- atomic_inc( &dev->counts[_DRM_STAT_OPENS] );
- spin_lock( &dev->count_lock );
- if ( !dev->open_count++ ) {
- spin_unlock( &dev->count_lock );
- return drm_setup( dev );
+
+ retcode = drm_open_helper(inode, filp, dev);
+ if (!retcode) {
+ atomic_inc(&dev->counts[_DRM_STAT_OPENS]);
+ spin_lock(&dev->count_lock);
+ if (!dev->open_count++) {
+ spin_unlock(&dev->count_lock);
+ return drm_setup(dev);
}
- spin_unlock( &dev->count_lock );
+ spin_unlock(&dev->count_lock);
}
return retcode;
}
+
EXPORT_SYMBOL(drm_open);
/**
@@ -172,7 +169,7 @@ EXPORT_SYMBOL(drm_open);
* data from its list and free it. Decreases the open count and if it reaches
* zero calls takedown().
*/
-int drm_release( struct inode *inode, struct file *filp )
+int drm_release(struct inode *inode, struct file *filp)
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev;
@@ -181,7 +178,7 @@ int drm_release( struct inode *inode, struct file *filp )
lock_kernel();
dev = priv->head->dev;
- DRM_DEBUG( "open_count = %d\n", dev->open_count );
+ DRM_DEBUG("open_count = %d\n", dev->open_count);
if (dev->driver->prerelease)
dev->driver->prerelease(dev, filp);
@@ -190,194 +187,199 @@ int drm_release( struct inode *inode, struct file *filp )
* Begin inline drm_release
*/
- DRM_DEBUG( "pid = %d, device = 0x%lx, open_count = %d\n",
- current->pid, (long)old_encode_dev(priv->head->device), dev->open_count );
+ DRM_DEBUG("pid = %d, device = 0x%lx, open_count = %d\n",
+ current->pid, (long)old_encode_dev(priv->head->device),
+ dev->open_count);
+
+ if (priv->lock_count && dev->lock.hw_lock &&
+ _DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) &&
+ dev->lock.filp == filp) {
+ DRM_DEBUG("File %p released, freeing lock for context %d\n",
+ filp, _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock));
- if ( priv->lock_count && dev->lock.hw_lock &&
- _DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) &&
- dev->lock.filp == filp ) {
- DRM_DEBUG( "File %p released, freeing lock for context %d\n",
- filp,
- _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock) );
-
if (dev->driver->release)
dev->driver->release(dev, filp);
- drm_lock_free( dev, &dev->lock.hw_lock->lock,
- _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock) );
+ drm_lock_free(dev, &dev->lock.hw_lock->lock,
+ _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock));
- /* FIXME: may require heavy-handed reset of
- hardware at this point, possibly
- processed via a callback to the X
- server. */
- }
- else if ( dev->driver->release && priv->lock_count && dev->lock.hw_lock ) {
+ /* FIXME: may require heavy-handed reset of
+ hardware at this point, possibly
+ processed via a callback to the X
+ server. */
+ } else if (dev->driver->release && priv->lock_count
+ && dev->lock.hw_lock) {
/* The lock is required to reclaim buffers */
- DECLARE_WAITQUEUE( entry, current );
+ DECLARE_WAITQUEUE(entry, current);
- add_wait_queue( &dev->lock.lock_queue, &entry );
+ add_wait_queue(&dev->lock.lock_queue, &entry);
for (;;) {
__set_current_state(TASK_INTERRUPTIBLE);
- if ( !dev->lock.hw_lock ) {
+ if (!dev->lock.hw_lock) {
/* Device has been unregistered */
retcode = -EINTR;
break;
}
- if ( drm_lock_take( &dev->lock.hw_lock->lock,
- DRM_KERNEL_CONTEXT ) ) {
- dev->lock.filp = filp;
+ if (drm_lock_take(&dev->lock.hw_lock->lock,
+ DRM_KERNEL_CONTEXT)) {
+ dev->lock.filp = filp;
dev->lock.lock_time = jiffies;
- atomic_inc( &dev->counts[_DRM_STAT_LOCKS] );
+ atomic_inc(&dev->counts[_DRM_STAT_LOCKS]);
break; /* Got lock */
}
- /* Contention */
+ /* Contention */
schedule();
- if ( signal_pending( current ) ) {
+ if (signal_pending(current)) {
retcode = -ERESTARTSYS;
break;
}
}
__set_current_state(TASK_RUNNING);
- remove_wait_queue( &dev->lock.lock_queue, &entry );
- if( !retcode ) {
+ remove_wait_queue(&dev->lock.lock_queue, &entry);
+ if (!retcode) {
if (dev->driver->release)
dev->driver->release(dev, filp);
- drm_lock_free( dev, &dev->lock.hw_lock->lock,
- DRM_KERNEL_CONTEXT );
+ drm_lock_free(dev, &dev->lock.hw_lock->lock,
+ DRM_KERNEL_CONTEXT);
}
}
-
- if (drm_core_check_feature(dev, DRIVER_HAVE_DMA) && !dev->driver->release)
- {
+
+ if (drm_core_check_feature(dev, DRIVER_HAVE_DMA)
+ && !dev->driver->release) {
dev->driver->reclaim_buffers(dev, filp);
}
- drm_fasync( -1, filp, 0 );
+ drm_fasync(-1, filp, 0);
- down( &dev->ctxlist_sem );
- if ( dev->ctxlist && (!list_empty(&dev->ctxlist->head))) {
+ down(&dev->ctxlist_sem);
+ if (dev->ctxlist && (!list_empty(&dev->ctxlist->head))) {
drm_ctx_list_t *pos, *n;
- list_for_each_entry_safe( pos, n, &dev->ctxlist->head, head ) {
- if ( pos->tag == priv &&
- pos->handle != DRM_KERNEL_CONTEXT ) {
+ list_for_each_entry_safe(pos, n, &dev->ctxlist->head, head) {
+ if (pos->tag == priv &&
+ pos->handle != DRM_KERNEL_CONTEXT) {
if (dev->driver->context_dtor)
- dev->driver->context_dtor(dev, pos->handle);
+ dev->driver->context_dtor(dev,
+ pos->handle);
- drm_ctxbitmap_free( dev, pos->handle );
+ drm_ctxbitmap_free(dev, pos->handle);
- list_del( &pos->head );
- drm_free( pos, sizeof(*pos), DRM_MEM_CTXLIST );
+ list_del(&pos->head);
+ drm_free(pos, sizeof(*pos), DRM_MEM_CTXLIST);
--dev->ctx_count;
}
}
}
- up( &dev->ctxlist_sem );
+ up(&dev->ctxlist_sem);
- down( &dev->struct_sem );
- if ( priv->remove_auth_on_close == 1 ) {
+ down(&dev->struct_sem);
+ if (priv->remove_auth_on_close == 1) {
drm_file_t *temp = dev->file_first;
- while ( temp ) {
+ while (temp) {
temp->authenticated = 0;
temp = temp->next;
}
}
- if ( priv->prev ) {
+ if (priv->prev) {
priv->prev->next = priv->next;
} else {
- dev->file_first = priv->next;
+ dev->file_first = priv->next;
}
- if ( priv->next ) {
+ if (priv->next) {
priv->next->prev = priv->prev;
} else {
- dev->file_last = priv->prev;
+ dev->file_last = priv->prev;
}
- up( &dev->struct_sem );
-
+ up(&dev->struct_sem);
+
if (dev->driver->free_filp_priv)
dev->driver->free_filp_priv(dev, priv);
- drm_free( priv, sizeof(*priv), DRM_MEM_FILES );
+ drm_free(priv, sizeof(*priv), DRM_MEM_FILES);
/* ========================================================
* End inline drm_release
*/
- atomic_inc( &dev->counts[_DRM_STAT_CLOSES] );
- spin_lock( &dev->count_lock );
- if ( !--dev->open_count ) {
- if ( atomic_read( &dev->ioctl_count ) || dev->blocked ) {
- DRM_ERROR( "Device busy: %d %d\n",
- atomic_read( &dev->ioctl_count ),
- dev->blocked );
- spin_unlock( &dev->count_lock );
+ atomic_inc(&dev->counts[_DRM_STAT_CLOSES]);
+ spin_lock(&dev->count_lock);
+ if (!--dev->open_count) {
+ if (atomic_read(&dev->ioctl_count) || dev->blocked) {
+ DRM_ERROR("Device busy: %d %d\n",
+ atomic_read(&dev->ioctl_count), dev->blocked);
+ spin_unlock(&dev->count_lock);
unlock_kernel();
return -EBUSY;
}
- spin_unlock( &dev->count_lock );
+ spin_unlock(&dev->count_lock);
unlock_kernel();
- return drm_takedown( dev );
+ return drm_takedown(dev);
}
- spin_unlock( &dev->count_lock );
+ spin_unlock(&dev->count_lock);
unlock_kernel();
return retcode;
}
+
EXPORT_SYMBOL(drm_release);
/**
- * Called whenever a process opens /dev/drm.
+ * Called whenever a process opens /dev/drm.
*
* \param inode device inode.
* \param filp file pointer.
* \param dev device.
* \return zero on success or a negative number on failure.
- *
+ *
* Creates and initializes a drm_file structure for the file private data in \p
* filp and add it into the double linked list in \p dev.
*/
-static int drm_open_helper(struct inode *inode, struct file *filp, drm_device_t *dev)
+static int drm_open_helper(struct inode *inode, struct file *filp,
+ drm_device_t * dev)
{
- int minor = iminor(inode);
- drm_file_t *priv;
+ int minor = iminor(inode);
+ drm_file_t *priv;
int ret;
- if (filp->f_flags & O_EXCL) return -EBUSY; /* No exclusive opens */
- if (!drm_cpu_valid()) return -EINVAL;
+ if (filp->f_flags & O_EXCL)
+ return -EBUSY; /* No exclusive opens */
+ if (!drm_cpu_valid())
+ return -EINVAL;
DRM_DEBUG("pid = %d, minor = %d\n", current->pid, minor);
- priv = drm_alloc(sizeof(*priv), DRM_MEM_FILES);
- if(!priv) return -ENOMEM;
+ priv = drm_alloc(sizeof(*priv), DRM_MEM_FILES);
+ if (!priv)
+ return -ENOMEM;
memset(priv, 0, sizeof(*priv));
- filp->private_data = priv;
- priv->uid = current->euid;
- priv->pid = current->pid;
- priv->minor = minor;
- priv->head = drm_heads[minor];
- priv->ioctl_count = 0;
+ filp->private_data = priv;
+ priv->uid = current->euid;
+ priv->pid = current->pid;
+ priv->minor = minor;
+ priv->head = drm_heads[minor];
+ priv->ioctl_count = 0;
priv->authenticated = capable(CAP_SYS_ADMIN);
- priv->lock_count = 0;
+ priv->lock_count = 0;
if (dev->driver->open_helper) {
- ret=dev->driver->open_helper(dev, priv);
+ ret = dev->driver->open_helper(dev, priv);
if (ret < 0)
goto out_free;
}
down(&dev->struct_sem);
if (!dev->file_last) {
- priv->next = NULL;
- priv->prev = NULL;
+ priv->next = NULL;
+ priv->prev = NULL;
dev->file_first = priv;
- dev->file_last = priv;
+ dev->file_last = priv;
} else {
- priv->next = NULL;
- priv->prev = dev->file_last;
+ priv->next = NULL;
+ priv->prev = dev->file_last;
dev->file_last->next = priv;
- dev->file_last = priv;
+ dev->file_last = priv;
}
up(&dev->struct_sem);
@@ -394,42 +396,48 @@ static int drm_open_helper(struct inode *inode, struct file *filp, drm_device_t
}
if (!dev->hose) {
struct pci_bus *b = pci_bus_b(pci_root_buses.next);
- if (b) dev->hose = b->sysdata;
+ if (b)
+ dev->hose = b->sysdata;
}
}
#endif
return 0;
-out_free:
+ out_free:
drm_free(priv, sizeof(*priv), DRM_MEM_FILES);
- filp->private_data=NULL;
+ filp->private_data = NULL;
return ret;
}
/** No-op. */
int drm_flush(struct file *filp)
{
- drm_file_t *priv = filp->private_data;
- drm_device_t *dev = priv->head->dev;
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->head->dev;
DRM_DEBUG("pid = %d, device = 0x%lx, open_count = %d\n",
- current->pid, (long)old_encode_dev(priv->head->device), dev->open_count);
+ current->pid, (long)old_encode_dev(priv->head->device),
+ dev->open_count);
return 0;
}
+
EXPORT_SYMBOL(drm_flush);
/** No-op. */
int drm_fasync(int fd, struct file *filp, int on)
{
- drm_file_t *priv = filp->private_data;
- drm_device_t *dev = priv->head->dev;
- int retcode;
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->head->dev;
+ int retcode;
- DRM_DEBUG("fd = %d, device = 0x%lx\n", fd, (long)old_encode_dev(priv->head->device));
+ DRM_DEBUG("fd = %d, device = 0x%lx\n", fd,
+ (long)old_encode_dev(priv->head->device));
retcode = fasync_helper(fd, filp, on, &dev->buf_async);
- if (retcode < 0) return retcode;
+ if (retcode < 0)
+ return retcode;
return 0;
}
+
EXPORT_SYMBOL(drm_fasync);
/** No-op. */
@@ -437,5 +445,5 @@ unsigned int drm_poll(struct file *filp, struct poll_table_struct *wait)
{
return 0;
}
-EXPORT_SYMBOL(drm_poll);
+EXPORT_SYMBOL(drm_poll);
diff --git a/drivers/char/drm/drm_init.c b/drivers/char/drm/drm_init.c
index 62883b749e97..754b934715c4 100644
--- a/drivers/char/drm/drm_init.c
+++ b/drivers/char/drm/drm_init.c
@@ -1,5 +1,5 @@
/**
- * \file drm_init.h
+ * \file drm_init.c
* Setup/Cleanup for DRM
*
* \author Rickard E. (Rik) Faith <faith@valinux.com>
@@ -43,10 +43,11 @@
int drm_cpu_valid(void)
{
#if defined(__i386__)
- if (boot_cpu_data.x86 == 3) return 0; /* No cmpxchg on a 386 */
+ if (boot_cpu_data.x86 == 3)
+ return 0; /* No cmpxchg on a 386 */
#endif
#if defined(__sparc__) && !defined(__sparc_v9__)
- return 0; /* No cmpxchg before v9 sparc. */
+ return 0; /* No cmpxchg before v9 sparc. */
#endif
return 1;
}
diff --git a/drivers/char/drm/drm_ioc32.c b/drivers/char/drm/drm_ioc32.c
index 8087a9636399..dd91ff6b474c 100644
--- a/drivers/char/drm/drm_ioc32.c
+++ b/drivers/char/drm/drm_ioc32.c
@@ -68,15 +68,15 @@
#define DRM_IOCTL_WAIT_VBLANK32 DRM_IOWR(0x3a, drm_wait_vblank32_t)
typedef struct drm_version_32 {
- int version_major; /**< Major version */
- int version_minor; /**< Minor version */
- int version_patchlevel;/**< Patch level */
- u32 name_len; /**< Length of name buffer */
- u32 name; /**< Name of driver */
- u32 date_len; /**< Length of date buffer */
- u32 date; /**< User-space buffer to hold date */
- u32 desc_len; /**< Length of desc buffer */
- u32 desc; /**< User-space buffer to hold desc */
+ int version_major; /**< Major version */
+ int version_minor; /**< Minor version */
+ int version_patchlevel; /**< Patch level */
+ u32 name_len; /**< Length of name buffer */
+ u32 name; /**< Name of driver */
+ u32 date_len; /**< Length of date buffer */
+ u32 date; /**< User-space buffer to hold date */
+ u32 desc_len; /**< Length of desc buffer */
+ u32 desc; /**< User-space buffer to hold desc */
} drm_version32_t;
static int compat_drm_version(struct file *file, unsigned int cmd,
@@ -86,7 +86,7 @@ static int compat_drm_version(struct file *file, unsigned int cmd,
drm_version_t __user *version;
int err;
- if (copy_from_user(&v32, (void __user *) arg, sizeof(v32)))
+ if (copy_from_user(&v32, (void __user *)arg, sizeof(v32)))
return -EFAULT;
version = compat_alloc_user_space(sizeof(*version));
@@ -104,7 +104,7 @@ static int compat_drm_version(struct file *file, unsigned int cmd,
return -EFAULT;
err = drm_ioctl(file->f_dentry->d_inode, file,
- DRM_IOCTL_VERSION, (unsigned long) version);
+ DRM_IOCTL_VERSION, (unsigned long)version);
if (err)
return err;
@@ -116,7 +116,7 @@ static int compat_drm_version(struct file *file, unsigned int cmd,
|| __get_user(v32.desc_len, &version->desc_len))
return -EFAULT;
- if (copy_to_user((void __user *) arg, &v32, sizeof(v32)))
+ if (copy_to_user((void __user *)arg, &v32, sizeof(v32)))
return -EFAULT;
return 0;
}
@@ -133,25 +133,25 @@ static int compat_drm_getunique(struct file *file, unsigned int cmd,
drm_unique_t __user *u;
int err;
- if (copy_from_user(&uq32, (void __user *) arg, sizeof(uq32)))
+ if (copy_from_user(&uq32, (void __user *)arg, sizeof(uq32)))
return -EFAULT;
u = compat_alloc_user_space(sizeof(*u));
if (!access_ok(VERIFY_WRITE, u, sizeof(*u)))
return -EFAULT;
if (__put_user(uq32.unique_len, &u->unique_len)
- || __put_user((void __user *)(unsigned long) uq32.unique,
+ || __put_user((void __user *)(unsigned long)uq32.unique,
&u->unique))
return -EFAULT;
err = drm_ioctl(file->f_dentry->d_inode, file,
- DRM_IOCTL_GET_UNIQUE, (unsigned long) u);
+ DRM_IOCTL_GET_UNIQUE, (unsigned long)u);
if (err)
return err;
if (__get_user(uq32.unique_len, &u->unique_len))
return -EFAULT;
- if (copy_to_user((void __user *) arg, &uq32, sizeof(uq32)))
+ if (copy_to_user((void __user *)arg, &uq32, sizeof(uq32)))
return -EFAULT;
return 0;
}
@@ -162,28 +162,28 @@ static int compat_drm_setunique(struct file *file, unsigned int cmd,
drm_unique32_t uq32;
drm_unique_t __user *u;
- if (copy_from_user(&uq32, (void __user *) arg, sizeof(uq32)))
+ if (copy_from_user(&uq32, (void __user *)arg, sizeof(uq32)))
return -EFAULT;
u = compat_alloc_user_space(sizeof(*u));
if (!access_ok(VERIFY_WRITE, u, sizeof(*u)))
return -EFAULT;
if (__put_user(uq32.unique_len, &u->unique_len)
- || __put_user((void __user *)(unsigned long) uq32.unique,
+ || __put_user((void __user *)(unsigned long)uq32.unique,
&u->unique))
return -EFAULT;
return drm_ioctl(file->f_dentry->d_inode, file,
- DRM_IOCTL_SET_UNIQUE, (unsigned long) u);
+ DRM_IOCTL_SET_UNIQUE, (unsigned long)u);
}
typedef struct drm_map32 {
- u32 offset; /**< Requested physical address (0 for SAREA)*/
- u32 size; /**< Requested physical size (bytes) */
- drm_map_type_t type; /**< Type of memory to map */
+ u32 offset; /**< Requested physical address (0 for SAREA)*/
+ u32 size; /**< Requested physical size (bytes) */
+ drm_map_type_t type; /**< Type of memory to map */
drm_map_flags_t flags; /**< Flags */
- u32 handle; /**< User-space: "Handle" to pass to mmap() */
- int mtrr; /**< MTRR slot used */
+ u32 handle; /**< User-space: "Handle" to pass to mmap() */
+ int mtrr; /**< MTRR slot used */
} drm_map32_t;
static int compat_drm_getmap(struct file *file, unsigned int cmd,
@@ -205,7 +205,7 @@ static int compat_drm_getmap(struct file *file, unsigned int cmd,
return -EFAULT;
err = drm_ioctl(file->f_dentry->d_inode, file,
- DRM_IOCTL_GET_MAP, (unsigned long) map);
+ DRM_IOCTL_GET_MAP, (unsigned long)map);
if (err)
return err;
@@ -217,7 +217,7 @@ static int compat_drm_getmap(struct file *file, unsigned int cmd,
|| __get_user(m32.mtrr, &map->mtrr))
return -EFAULT;
- m32.handle = (unsigned long) handle;
+ m32.handle = (unsigned long)handle;
if (copy_to_user(argp, &m32, sizeof(m32)))
return -EFAULT;
return 0;
@@ -246,7 +246,7 @@ static int compat_drm_addmap(struct file *file, unsigned int cmd,
return -EFAULT;
err = drm_ioctl(file->f_dentry->d_inode, file,
- DRM_IOCTL_ADD_MAP, (unsigned long) map);
+ DRM_IOCTL_ADD_MAP, (unsigned long)map);
if (err)
return err;
@@ -255,8 +255,8 @@ static int compat_drm_addmap(struct file *file, unsigned int cmd,
|| __get_user(handle, &map->handle))
return -EFAULT;
- m32.handle = (unsigned long) handle;
- if (m32.handle != (unsigned long) handle && printk_ratelimit())
+ m32.handle = (unsigned long)handle;
+ if (m32.handle != (unsigned long)handle && printk_ratelimit())
printk(KERN_ERR "compat_drm_addmap truncated handle"
" %p for type %d offset %x\n",
handle, m32.type, m32.offset);
@@ -280,20 +280,20 @@ static int compat_drm_rmmap(struct file *file, unsigned int cmd,
map = compat_alloc_user_space(sizeof(*map));
if (!access_ok(VERIFY_WRITE, map, sizeof(*map)))
return -EFAULT;
- if (__put_user((void *)(unsigned long) handle, &map->handle))
+ if (__put_user((void *)(unsigned long)handle, &map->handle))
return -EFAULT;
return drm_ioctl(file->f_dentry->d_inode, file,
- DRM_IOCTL_RM_MAP, (unsigned long) map);
+ DRM_IOCTL_RM_MAP, (unsigned long)map);
}
typedef struct drm_client32 {
- int idx; /**< Which client desired? */
- int auth; /**< Is client authenticated? */
- u32 pid; /**< Process ID */
- u32 uid; /**< User ID */
- u32 magic; /**< Magic */
- u32 iocs; /**< Ioctl count */
+ int idx; /**< Which client desired? */
+ int auth; /**< Is client authenticated? */
+ u32 pid; /**< Process ID */
+ u32 uid; /**< User ID */
+ u32 magic; /**< Magic */
+ u32 iocs; /**< Ioctl count */
} drm_client32_t;
static int compat_drm_getclient(struct file *file, unsigned int cmd,
@@ -314,7 +314,7 @@ static int compat_drm_getclient(struct file *file, unsigned int cmd,
return -EFAULT;
err = drm_ioctl(file->f_dentry->d_inode, file,
- DRM_IOCTL_GET_CLIENT, (unsigned long) client);
+ DRM_IOCTL_GET_CLIENT, (unsigned long)client);
if (err)
return err;
@@ -351,7 +351,7 @@ static int compat_drm_getstats(struct file *file, unsigned int cmd,
return -EFAULT;
err = drm_ioctl(file->f_dentry->d_inode, file,
- DRM_IOCTL_GET_STATS, (unsigned long) stats);
+ DRM_IOCTL_GET_STATS, (unsigned long)stats);
if (err)
return err;
@@ -368,12 +368,12 @@ static int compat_drm_getstats(struct file *file, unsigned int cmd,
}
typedef struct drm_buf_desc32 {
- int count; /**< Number of buffers of this size */
- int size; /**< Size in bytes */
- int low_mark; /**< Low water mark */
- int high_mark; /**< High water mark */
- int flags;
- u32 agp_start; /**< Start address in the AGP aperture */
+ int count; /**< Number of buffers of this size */
+ int size; /**< Size in bytes */
+ int low_mark; /**< Low water mark */
+ int high_mark; /**< High water mark */
+ int flags;
+ u32 agp_start; /**< Start address in the AGP aperture */
} drm_buf_desc32_t;
static int compat_drm_addbufs(struct file *file, unsigned int cmd,
@@ -395,7 +395,7 @@ static int compat_drm_addbufs(struct file *file, unsigned int cmd,
return -EFAULT;
err = drm_ioctl(file->f_dentry->d_inode, file,
- DRM_IOCTL_ADD_BUFS, (unsigned long) buf);
+ DRM_IOCTL_ADD_BUFS, (unsigned long)buf);
if (err)
return err;
@@ -427,12 +427,12 @@ static int compat_drm_markbufs(struct file *file, unsigned int cmd,
return -EFAULT;
return drm_ioctl(file->f_dentry->d_inode, file,
- DRM_IOCTL_MARK_BUFS, (unsigned long) buf);
+ DRM_IOCTL_MARK_BUFS, (unsigned long)buf);
}
typedef struct drm_buf_info32 {
- int count; /**< Entries in list */
- u32 list;
+ int count; /**< Entries in list */
+ u32 list;
} drm_buf_info32_t;
static int compat_drm_infobufs(struct file *file, unsigned int cmd,
@@ -451,7 +451,7 @@ static int compat_drm_infobufs(struct file *file, unsigned int cmd,
return -EFAULT;
count = req32.count;
- to = (drm_buf_desc32_t __user *)(unsigned long) req32.list;
+ to = (drm_buf_desc32_t __user *) (unsigned long)req32.list;
if (count < 0)
count = 0;
if (count > 0
@@ -469,7 +469,7 @@ static int compat_drm_infobufs(struct file *file, unsigned int cmd,
return -EFAULT;
err = drm_ioctl(file->f_dentry->d_inode, file,
- DRM_IOCTL_INFO_BUFS, (unsigned long) request);
+ DRM_IOCTL_INFO_BUFS, (unsigned long)request);
if (err)
return err;
@@ -488,16 +488,16 @@ static int compat_drm_infobufs(struct file *file, unsigned int cmd,
}
typedef struct drm_buf_pub32 {
- int idx; /**< Index into the master buffer list */
- int total; /**< Buffer size */
- int used; /**< Amount of buffer in use (for DMA) */
- u32 address; /**< Address of buffer */
+ int idx; /**< Index into the master buffer list */
+ int total; /**< Buffer size */
+ int used; /**< Amount of buffer in use (for DMA) */
+ u32 address; /**< Address of buffer */
} drm_buf_pub32_t;
typedef struct drm_buf_map32 {
- int count; /**< Length of the buffer list */
- u32 virtual; /**< Mmap'd area in user-virtual */
- u32 list; /**< Buffer information */
+ int count; /**< Length of the buffer list */
+ u32 virtual; /**< Mmap'd area in user-virtual */
+ u32 list; /**< Buffer information */
} drm_buf_map32_t;
static int compat_drm_mapbufs(struct file *file, unsigned int cmd,
@@ -531,7 +531,7 @@ static int compat_drm_mapbufs(struct file *file, unsigned int cmd,
return -EFAULT;
err = drm_ioctl(file->f_dentry->d_inode, file,
- DRM_IOCTL_MAP_BUFS, (unsigned long) request);
+ DRM_IOCTL_MAP_BUFS, (unsigned long)request);
if (err)
return err;
@@ -542,21 +542,21 @@ static int compat_drm_mapbufs(struct file *file, unsigned int cmd,
if (__copy_in_user(&list32[i], &list[i],
offsetof(drm_buf_pub_t, address))
|| __get_user(addr, &list[i].address)
- || __put_user((unsigned long) addr,
+ || __put_user((unsigned long)addr,
&list32[i].address))
return -EFAULT;
if (__put_user(actual, &argp->count)
|| __get_user(addr, &request->virtual)
- || __put_user((unsigned long) addr, &argp->virtual))
+ || __put_user((unsigned long)addr, &argp->virtual))
return -EFAULT;
return 0;
}
typedef struct drm_buf_free32 {
- int count;
- u32 list;
+ int count;
+ u32 list;
} drm_buf_free32_t;
static int compat_drm_freebufs(struct file *file, unsigned int cmd,
@@ -573,17 +573,17 @@ static int compat_drm_freebufs(struct file *file, unsigned int cmd,
if (!access_ok(VERIFY_WRITE, request, sizeof(*request)))
return -EFAULT;
if (__put_user(req32.count, &request->count)
- || __put_user((int __user *)(unsigned long) req32.list,
+ || __put_user((int __user *)(unsigned long)req32.list,
&request->list))
return -EFAULT;
return drm_ioctl(file->f_dentry->d_inode, file,
- DRM_IOCTL_FREE_BUFS, (unsigned long) request);
+ DRM_IOCTL_FREE_BUFS, (unsigned long)request);
}
typedef struct drm_ctx_priv_map32 {
- unsigned int ctx_id; /**< Context requesting private mapping */
- u32 handle; /**< Handle of map */
+ unsigned int ctx_id; /**< Context requesting private mapping */
+ u32 handle; /**< Handle of map */
} drm_ctx_priv_map32_t;
static int compat_drm_setsareactx(struct file *file, unsigned int cmd,
@@ -600,12 +600,12 @@ static int compat_drm_setsareactx(struct file *file, unsigned int cmd,
if (!access_ok(VERIFY_WRITE, request, sizeof(*request)))
return -EFAULT;
if (__put_user(req32.ctx_id, &request->ctx_id)
- || __put_user((void *)(unsigned long) req32.handle,
+ || __put_user((void *)(unsigned long)req32.handle,
&request->handle))
return -EFAULT;
return drm_ioctl(file->f_dentry->d_inode, file,
- DRM_IOCTL_SET_SAREA_CTX, (unsigned long) request);
+ DRM_IOCTL_SET_SAREA_CTX, (unsigned long)request);
}
static int compat_drm_getsareactx(struct file *file, unsigned int cmd,
@@ -628,20 +628,20 @@ static int compat_drm_getsareactx(struct file *file, unsigned int cmd,
return -EFAULT;
err = drm_ioctl(file->f_dentry->d_inode, file,
- DRM_IOCTL_GET_SAREA_CTX, (unsigned long) request);
+ DRM_IOCTL_GET_SAREA_CTX, (unsigned long)request);
if (err)
return err;
if (__get_user(handle, &request->handle)
- || __put_user((unsigned long) handle, &argp->handle))
+ || __put_user((unsigned long)handle, &argp->handle))
return -EFAULT;
return 0;
}
typedef struct drm_ctx_res32 {
- int count;
- u32 contexts;
+ int count;
+ u32 contexts;
} drm_ctx_res32_t;
static int compat_drm_resctx(struct file *file, unsigned int cmd,
@@ -659,12 +659,12 @@ static int compat_drm_resctx(struct file *file, unsigned int cmd,
if (!access_ok(VERIFY_WRITE, res, sizeof(*res)))
return -EFAULT;
if (__put_user(res32.count, &res->count)
- || __put_user((drm_ctx_t __user *)(unsigned long) res32.contexts,
+ || __put_user((drm_ctx_t __user *) (unsigned long)res32.contexts,
&res->contexts))
return -EFAULT;
err = drm_ioctl(file->f_dentry->d_inode, file,
- DRM_IOCTL_RES_CTX, (unsigned long) res);
+ DRM_IOCTL_RES_CTX, (unsigned long)res);
if (err)
return err;
@@ -676,23 +676,23 @@ static int compat_drm_resctx(struct file *file, unsigned int cmd,
}
typedef struct drm_dma32 {
- int context; /**< Context handle */
- int send_count; /**< Number of buffers to send */
- u32 send_indices; /**< List of handles to buffers */
- u32 send_sizes; /**< Lengths of data to send */
+ int context; /**< Context handle */
+ int send_count; /**< Number of buffers to send */
+ u32 send_indices; /**< List of handles to buffers */
+ u32 send_sizes; /**< Lengths of data to send */
drm_dma_flags_t flags; /**< Flags */
- int request_count; /**< Number of buffers requested */
- int request_size; /**< Desired size for buffers */
- u32 request_indices; /**< Buffer information */
- u32 request_sizes;
- int granted_count; /**< Number of buffers granted */
+ int request_count; /**< Number of buffers requested */
+ int request_size; /**< Desired size for buffers */
+ u32 request_indices; /**< Buffer information */
+ u32 request_sizes;
+ int granted_count; /**< Number of buffers granted */
} drm_dma32_t;
static int compat_drm_dma(struct file *file, unsigned int cmd,
unsigned long arg)
{
drm_dma32_t d32;
- drm_dma32_t __user *argp = (void __user *) arg;
+ drm_dma32_t __user *argp = (void __user *)arg;
drm_dma_t __user *d;
int err;
@@ -705,20 +705,20 @@ static int compat_drm_dma(struct file *file, unsigned int cmd,
if (__put_user(d32.context, &d->context)
|| __put_user(d32.send_count, &d->send_count)
- || __put_user((int __user *)(unsigned long) d32.send_indices,
+ || __put_user((int __user *)(unsigned long)d32.send_indices,
&d->send_indices)
- || __put_user((int __user *)(unsigned long) d32.send_sizes,
+ || __put_user((int __user *)(unsigned long)d32.send_sizes,
&d->send_sizes)
|| __put_user(d32.flags, &d->flags)
|| __put_user(d32.request_count, &d->request_count)
- || __put_user((int __user *)(unsigned long) d32.request_indices,
+ || __put_user((int __user *)(unsigned long)d32.request_indices,
&d->request_indices)
- || __put_user((int __user *)(unsigned long) d32.request_sizes,
+ || __put_user((int __user *)(unsigned long)d32.request_sizes,
&d->request_sizes))
return -EFAULT;
err = drm_ioctl(file->f_dentry->d_inode, file,
- DRM_IOCTL_DMA, (unsigned long) d);
+ DRM_IOCTL_DMA, (unsigned long)d);
if (err)
return err;
@@ -751,19 +751,19 @@ static int compat_drm_agp_enable(struct file *file, unsigned int cmd,
return -EFAULT;
return drm_ioctl(file->f_dentry->d_inode, file,
- DRM_IOCTL_AGP_ENABLE, (unsigned long) mode);
+ DRM_IOCTL_AGP_ENABLE, (unsigned long)mode);
}
typedef struct drm_agp_info32 {
- int agp_version_major;
- int agp_version_minor;
- u32 mode;
- u32 aperture_base; /* physical address */
- u32 aperture_size; /* bytes */
- u32 memory_allowed; /* bytes */
- u32 memory_used;
-
- /* PCI information */
+ int agp_version_major;
+ int agp_version_minor;
+ u32 mode;
+ u32 aperture_base; /* physical address */
+ u32 aperture_size; /* bytes */
+ u32 memory_allowed; /* bytes */
+ u32 memory_used;
+
+ /* PCI information */
unsigned short id_vendor;
unsigned short id_device;
} drm_agp_info32_t;
@@ -781,7 +781,7 @@ static int compat_drm_agp_info(struct file *file, unsigned int cmd,
return -EFAULT;
err = drm_ioctl(file->f_dentry->d_inode, file,
- DRM_IOCTL_AGP_INFO, (unsigned long) info);
+ DRM_IOCTL_AGP_INFO, (unsigned long)info);
if (err)
return err;
@@ -806,7 +806,7 @@ typedef struct drm_agp_buffer32 {
u32 size; /**< In bytes -- will round to page boundary */
u32 handle; /**< Used for binding / unbinding */
u32 type; /**< Type of memory to allocate */
- u32 physical; /**< Physical used by i810 */
+ u32 physical; /**< Physical used by i810 */
} drm_agp_buffer32_t;
static int compat_drm_agp_alloc(struct file *file, unsigned int cmd,
@@ -827,7 +827,7 @@ static int compat_drm_agp_alloc(struct file *file, unsigned int cmd,
return -EFAULT;
err = drm_ioctl(file->f_dentry->d_inode, file,
- DRM_IOCTL_AGP_ALLOC, (unsigned long) request);
+ DRM_IOCTL_AGP_ALLOC, (unsigned long)request);
if (err)
return err;
@@ -835,7 +835,7 @@ static int compat_drm_agp_alloc(struct file *file, unsigned int cmd,
|| __get_user(req32.physical, &request->physical)
|| copy_to_user(argp, &req32, sizeof(req32))) {
drm_ioctl(file->f_dentry->d_inode, file,
- DRM_IOCTL_AGP_FREE, (unsigned long) request);
+ DRM_IOCTL_AGP_FREE, (unsigned long)request);
return -EFAULT;
}
@@ -856,7 +856,7 @@ static int compat_drm_agp_free(struct file *file, unsigned int cmd,
return -EFAULT;
return drm_ioctl(file->f_dentry->d_inode, file,
- DRM_IOCTL_AGP_FREE, (unsigned long) request);
+ DRM_IOCTL_AGP_FREE, (unsigned long)request);
}
typedef struct drm_agp_binding32 {
@@ -881,7 +881,7 @@ static int compat_drm_agp_bind(struct file *file, unsigned int cmd,
return -EFAULT;
return drm_ioctl(file->f_dentry->d_inode, file,
- DRM_IOCTL_AGP_BIND, (unsigned long) request);
+ DRM_IOCTL_AGP_BIND, (unsigned long)request);
}
static int compat_drm_agp_unbind(struct file *file, unsigned int cmd,
@@ -898,9 +898,9 @@ static int compat_drm_agp_unbind(struct file *file, unsigned int cmd,
return -EFAULT;
return drm_ioctl(file->f_dentry->d_inode, file,
- DRM_IOCTL_AGP_UNBIND, (unsigned long) request);
+ DRM_IOCTL_AGP_UNBIND, (unsigned long)request);
}
-#endif /* __OS_HAS_AGP */
+#endif /* __OS_HAS_AGP */
typedef struct drm_scatter_gather32 {
u32 size; /**< In bytes -- will round to page boundary */
@@ -923,7 +923,7 @@ static int compat_drm_sg_alloc(struct file *file, unsigned int cmd,
return -EFAULT;
err = drm_ioctl(file->f_dentry->d_inode, file,
- DRM_IOCTL_SG_ALLOC, (unsigned long) request);
+ DRM_IOCTL_SG_ALLOC, (unsigned long)request);
if (err)
return err;
@@ -950,7 +950,7 @@ static int compat_drm_sg_free(struct file *file, unsigned int cmd,
return -EFAULT;
return drm_ioctl(file->f_dentry->d_inode, file,
- DRM_IOCTL_SG_FREE, (unsigned long) request);
+ DRM_IOCTL_SG_FREE, (unsigned long)request);
}
struct drm_wait_vblank_request32 {
@@ -990,7 +990,7 @@ static int compat_drm_wait_vblank(struct file *file, unsigned int cmd,
return -EFAULT;
err = drm_ioctl(file->f_dentry->d_inode, file,
- DRM_IOCTL_WAIT_VBLANK, (unsigned long) request);
+ DRM_IOCTL_WAIT_VBLANK, (unsigned long)request);
if (err)
return err;
@@ -1059,11 +1059,12 @@ long drm_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
lock_kernel(); /* XXX for now */
if (fn != NULL)
- ret = (*fn)(filp, cmd, arg);
+ ret = (*fn) (filp, cmd, arg);
else
ret = drm_ioctl(filp->f_dentry->d_inode, filp, cmd, arg);
unlock_kernel();
return ret;
}
+
EXPORT_SYMBOL(drm_compat_ioctl);
diff --git a/drivers/char/drm/drm_ioctl.c b/drivers/char/drm/drm_ioctl.c
index d2ed3ba5aca9..9b0feba6b063 100644
--- a/drivers/char/drm/drm_ioctl.c
+++ b/drivers/char/drm/drm_ioctl.c
@@ -1,5 +1,5 @@
/**
- * \file drm_ioctl.h
+ * \file drm_ioctl.c
* IOCTL processing for DRM
*
* \author Rickard E. (Rik) Faith <faith@valinux.com>
@@ -40,7 +40,7 @@
/**
* Get the bus id.
- *
+ *
* \param inode device inode.
* \param filp file pointer.
* \param cmd command.
@@ -50,12 +50,12 @@
* Copies the bus id from drm_device::unique into user space.
*/
int drm_getunique(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg)
+ unsigned int cmd, unsigned long arg)
{
- drm_file_t *priv = filp->private_data;
- drm_device_t *dev = priv->head->dev;
- drm_unique_t __user *argp = (void __user *)arg;
- drm_unique_t u;
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->head->dev;
+ drm_unique_t __user *argp = (void __user *)arg;
+ drm_unique_t u;
if (copy_from_user(&u, argp, sizeof(u)))
return -EFAULT;
@@ -71,7 +71,7 @@ int drm_getunique(struct inode *inode, struct file *filp,
/**
* Set the bus id.
- *
+ *
* \param inode device inode.
* \param filp file pointer.
* \param cmd command.
@@ -84,34 +84,39 @@ int drm_getunique(struct inode *inode, struct file *filp,
* version 1.1 or greater.
*/
int drm_setunique(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg)
+ unsigned int cmd, unsigned long arg)
{
- drm_file_t *priv = filp->private_data;
- drm_device_t *dev = priv->head->dev;
- drm_unique_t u;
- int domain, bus, slot, func, ret;
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->head->dev;
+ drm_unique_t u;
+ int domain, bus, slot, func, ret;
- if (dev->unique_len || dev->unique) return -EBUSY;
+ if (dev->unique_len || dev->unique)
+ return -EBUSY;
- if (copy_from_user(&u, (drm_unique_t __user *)arg, sizeof(u)))
+ if (copy_from_user(&u, (drm_unique_t __user *) arg, sizeof(u)))
return -EFAULT;
- if (!u.unique_len || u.unique_len > 1024) return -EINVAL;
+ if (!u.unique_len || u.unique_len > 1024)
+ return -EINVAL;
dev->unique_len = u.unique_len;
- dev->unique = drm_alloc(u.unique_len + 1, DRM_MEM_DRIVER);
- if(!dev->unique) return -ENOMEM;
+ dev->unique = drm_alloc(u.unique_len + 1, DRM_MEM_DRIVER);
+ if (!dev->unique)
+ return -ENOMEM;
if (copy_from_user(dev->unique, u.unique, dev->unique_len))
return -EFAULT;
dev->unique[dev->unique_len] = '\0';
- dev->devname = drm_alloc(strlen(dev->driver->pci_driver.name) + strlen(dev->unique) + 2,
- DRM_MEM_DRIVER);
+ dev->devname =
+ drm_alloc(strlen(dev->driver->pci_driver.name) +
+ strlen(dev->unique) + 2, DRM_MEM_DRIVER);
if (!dev->devname)
return -ENOMEM;
- sprintf(dev->devname, "%s@%s", dev->driver->pci_driver.name, dev->unique);
+ sprintf(dev->devname, "%s@%s", dev->driver->pci_driver.name,
+ dev->unique);
/* Return error if the busid submitted doesn't match the device's actual
* busid.
@@ -121,18 +126,16 @@ int drm_setunique(struct inode *inode, struct file *filp,
return DRM_ERR(EINVAL);
domain = bus >> 8;
bus &= 0xff;
-
+
if ((domain != dev->pci_domain) ||
(bus != dev->pci_bus) ||
- (slot != dev->pci_slot) ||
- (func != dev->pci_func))
+ (slot != dev->pci_slot) || (func != dev->pci_func))
return -EINVAL;
return 0;
}
-static int
-drm_set_busid(drm_device_t *dev)
+static int drm_set_busid(drm_device_t * dev)
{
if (dev->unique != NULL)
return EBUSY;
@@ -143,19 +146,20 @@ drm_set_busid(drm_device_t *dev)
return ENOMEM;
snprintf(dev->unique, dev->unique_len, "pci:%04x:%02x:%02x.%d",
- dev->pci_domain, dev->pci_bus, dev->pci_slot, dev->pci_func);
+ dev->pci_domain, dev->pci_bus, dev->pci_slot, dev->pci_func);
- dev->devname = drm_alloc(strlen(dev->driver->pci_driver.name) + dev->unique_len + 2,
- DRM_MEM_DRIVER);
+ dev->devname =
+ drm_alloc(strlen(dev->driver->pci_driver.name) + dev->unique_len +
+ 2, DRM_MEM_DRIVER);
if (dev->devname == NULL)
return ENOMEM;
- sprintf(dev->devname, "%s@%s", dev->driver->pci_driver.name, dev->unique);
+ sprintf(dev->devname, "%s@%s", dev->driver->pci_driver.name,
+ dev->unique);
return 0;
}
-
/**
* Get a mapping information.
*
@@ -163,23 +167,23 @@ drm_set_busid(drm_device_t *dev)
* \param filp file pointer.
* \param cmd command.
* \param arg user argument, pointing to a drm_map structure.
- *
+ *
* \return zero on success or a negative number on failure.
*
* Searches for the mapping with the specified offset and copies its information
* into userspace
*/
-int drm_getmap( struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg )
+int drm_getmap(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg)
{
- drm_file_t *priv = filp->private_data;
- drm_device_t *dev = priv->head->dev;
- drm_map_t __user *argp = (void __user *)arg;
- drm_map_t map;
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->head->dev;
+ drm_map_t __user *argp = (void __user *)arg;
+ drm_map_t map;
drm_map_list_t *r_list = NULL;
struct list_head *list;
- int idx;
- int i;
+ int idx;
+ int i;
if (copy_from_user(&map, argp, sizeof(map)))
return -EFAULT;
@@ -193,26 +197,27 @@ int drm_getmap( struct inode *inode, struct file *filp,
i = 0;
list_for_each(list, &dev->maplist->head) {
- if(i == idx) {
+ if (i == idx) {
r_list = list_entry(list, drm_map_list_t, head);
break;
}
i++;
}
- if(!r_list || !r_list->map) {
+ if (!r_list || !r_list->map) {
up(&dev->struct_sem);
return -EINVAL;
}
map.offset = r_list->map->offset;
- map.size = r_list->map->size;
- map.type = r_list->map->type;
- map.flags = r_list->map->flags;
- map.handle = (void *)(unsigned long) r_list->user_token;
- map.mtrr = r_list->map->mtrr;
+ map.size = r_list->map->size;
+ map.type = r_list->map->type;
+ map.flags = r_list->map->flags;
+ map.handle = (void *)(unsigned long)r_list->user_token;
+ map.mtrr = r_list->map->mtrr;
up(&dev->struct_sem);
- if (copy_to_user(argp, &map, sizeof(map))) return -EFAULT;
+ if (copy_to_user(argp, &map, sizeof(map)))
+ return -EFAULT;
return 0;
}
@@ -223,83 +228,81 @@ int drm_getmap( struct inode *inode, struct file *filp,
* \param filp file pointer.
* \param cmd command.
* \param arg user argument, pointing to a drm_client structure.
- *
+ *
* \return zero on success or a negative number on failure.
*
* Searches for the client with the specified index and copies its information
* into userspace
*/
-int drm_getclient( struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg )
+int drm_getclient(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg)
{
- drm_file_t *priv = filp->private_data;
- drm_device_t *dev = priv->head->dev;
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->head->dev;
drm_client_t __user *argp = (void __user *)arg;
drm_client_t client;
- drm_file_t *pt;
- int idx;
- int i;
+ drm_file_t *pt;
+ int idx;
+ int i;
if (copy_from_user(&client, argp, sizeof(client)))
return -EFAULT;
idx = client.idx;
down(&dev->struct_sem);
- for (i = 0, pt = dev->file_first; i < idx && pt; i++, pt = pt->next)
- ;
+ for (i = 0, pt = dev->file_first; i < idx && pt; i++, pt = pt->next) ;
if (!pt) {
up(&dev->struct_sem);
return -EINVAL;
}
- client.auth = pt->authenticated;
- client.pid = pt->pid;
- client.uid = pt->uid;
+ client.auth = pt->authenticated;
+ client.pid = pt->pid;
+ client.uid = pt->uid;
client.magic = pt->magic;
- client.iocs = pt->ioctl_count;
+ client.iocs = pt->ioctl_count;
up(&dev->struct_sem);
- if (copy_to_user((drm_client_t __user *)arg, &client, sizeof(client)))
+ if (copy_to_user((drm_client_t __user *) arg, &client, sizeof(client)))
return -EFAULT;
return 0;
}
-/**
- * Get statistics information.
- *
+/**
+ * Get statistics information.
+ *
* \param inode device inode.
* \param filp file pointer.
* \param cmd command.
* \param arg user argument, pointing to a drm_stats structure.
- *
+ *
* \return zero on success or a negative number on failure.
*/
-int drm_getstats( struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg )
+int drm_getstats(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg)
{
- drm_file_t *priv = filp->private_data;
- drm_device_t *dev = priv->head->dev;
- drm_stats_t stats;
- int i;
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->head->dev;
+ drm_stats_t stats;
+ int i;
memset(&stats, 0, sizeof(stats));
-
+
down(&dev->struct_sem);
for (i = 0; i < dev->counters; i++) {
if (dev->types[i] == _DRM_STAT_LOCK)
stats.data[i].value
- = (dev->lock.hw_lock
- ? dev->lock.hw_lock->lock : 0);
- else
+ = (dev->lock.hw_lock ? dev->lock.hw_lock->lock : 0);
+ else
stats.data[i].value = atomic_read(&dev->counts[i]);
- stats.data[i].type = dev->types[i];
+ stats.data[i].type = dev->types[i];
}
-
+
stats.count = dev->counters;
up(&dev->struct_sem);
- if (copy_to_user((drm_stats_t __user *)arg, &stats, sizeof(stats)))
+ if (copy_to_user((drm_stats_t __user *) arg, &stats, sizeof(stats)))
return -EFAULT;
return 0;
}
@@ -352,7 +355,8 @@ int drm_setversion(DRM_IOCTL_ARGS)
if (sv.drm_dd_major != -1) {
if (sv.drm_dd_major != version.version_major ||
- sv.drm_dd_minor < 0 || sv.drm_dd_minor > version.version_minor)
+ sv.drm_dd_minor < 0
+ || sv.drm_dd_minor > version.version_minor)
return EINVAL;
if (dev->driver->set_version)
@@ -363,7 +367,7 @@ int drm_setversion(DRM_IOCTL_ARGS)
/** No-op ioctl. */
int drm_noop(struct inode *inode, struct file *filp, unsigned int cmd,
- unsigned long arg)
+ unsigned long arg)
{
DRM_DEBUG("\n");
return 0;
diff --git a/drivers/char/drm/drm_irq.c b/drivers/char/drm/drm_irq.c
index cdd4aecd25e2..b0d4b236e837 100644
--- a/drivers/char/drm/drm_irq.c
+++ b/drivers/char/drm/drm_irq.c
@@ -1,5 +1,5 @@
/**
- * \file drm_irq.h
+ * \file drm_irq.c
* IRQ support
*
* \author Rickard E. (Rik) Faith <faith@valinux.com>
@@ -39,19 +39,19 @@
/**
* Get interrupt from bus id.
- *
+ *
* \param inode device inode.
* \param filp file pointer.
* \param cmd command.
* \param arg user argument, pointing to a drm_irq_busid structure.
* \return zero on success or a negative number on failure.
- *
+ *
* Finds the PCI device with the specified bus id and gets its IRQ number.
* This IOCTL is deprecated, and will now return EINVAL for any busid not equal
* to that of the device that this DRM instance attached to.
*/
int drm_irq_by_busid(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg)
+ unsigned int cmd, unsigned long arg)
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->head->dev;
@@ -66,14 +66,12 @@ int drm_irq_by_busid(struct inode *inode, struct file *filp,
if ((p.busnum >> 8) != dev->pci_domain ||
(p.busnum & 0xff) != dev->pci_bus ||
- p.devnum != dev->pci_slot ||
- p.funcnum != dev->pci_func)
+ p.devnum != dev->pci_slot || p.funcnum != dev->pci_func)
return -EINVAL;
p.irq = dev->irq;
- DRM_DEBUG("%d:%d:%d => IRQ %d\n",
- p.busnum, p.devnum, p.funcnum, p.irq);
+ DRM_DEBUG("%d:%d:%d => IRQ %d\n", p.busnum, p.devnum, p.funcnum, p.irq);
if (copy_to_user(argp, &p, sizeof(p)))
return -EFAULT;
return 0;
@@ -89,61 +87,61 @@ int drm_irq_by_busid(struct inode *inode, struct file *filp,
* \c drm_driver_irq_preinstall() and \c drm_driver_irq_postinstall() functions
* before and after the installation.
*/
-static int drm_irq_install( drm_device_t *dev )
+static int drm_irq_install(drm_device_t * dev)
{
int ret;
- unsigned long sh_flags=0;
+ unsigned long sh_flags = 0;
if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
return -EINVAL;
- if ( dev->irq == 0 )
+ if (dev->irq == 0)
return -EINVAL;
- down( &dev->struct_sem );
+ down(&dev->struct_sem);
/* Driver must have been initialized */
- if ( !dev->dev_private ) {
- up( &dev->struct_sem );
+ if (!dev->dev_private) {
+ up(&dev->struct_sem);
return -EINVAL;
}
- if ( dev->irq_enabled ) {
- up( &dev->struct_sem );
+ if (dev->irq_enabled) {
+ up(&dev->struct_sem);
return -EBUSY;
}
dev->irq_enabled = 1;
- up( &dev->struct_sem );
+ up(&dev->struct_sem);
- DRM_DEBUG( "%s: irq=%d\n", __FUNCTION__, dev->irq );
+ DRM_DEBUG("%s: irq=%d\n", __FUNCTION__, dev->irq);
if (drm_core_check_feature(dev, DRIVER_IRQ_VBL)) {
init_waitqueue_head(&dev->vbl_queue);
-
- spin_lock_init( &dev->vbl_lock );
-
- INIT_LIST_HEAD( &dev->vbl_sigs.head );
-
+
+ spin_lock_init(&dev->vbl_lock);
+
+ INIT_LIST_HEAD(&dev->vbl_sigs.head);
+
dev->vbl_pending = 0;
}
- /* Before installing handler */
+ /* Before installing handler */
dev->driver->irq_preinstall(dev);
- /* Install handler */
+ /* Install handler */
if (drm_core_check_feature(dev, DRIVER_IRQ_SHARED))
sh_flags = SA_SHIRQ;
-
- ret = request_irq( dev->irq, dev->driver->irq_handler,
- sh_flags, dev->devname, dev );
- if ( ret < 0 ) {
- down( &dev->struct_sem );
+
+ ret = request_irq(dev->irq, dev->driver->irq_handler,
+ sh_flags, dev->devname, dev);
+ if (ret < 0) {
+ down(&dev->struct_sem);
dev->irq_enabled = 0;
- up( &dev->struct_sem );
+ up(&dev->struct_sem);
return ret;
}
- /* After installing handler */
+ /* After installing handler */
dev->driver->irq_postinstall(dev);
return 0;
@@ -156,29 +154,30 @@ static int drm_irq_install( drm_device_t *dev )
*
* Calls the driver's \c drm_driver_irq_uninstall() function, and stops the irq.
*/
-int drm_irq_uninstall( drm_device_t *dev )
+int drm_irq_uninstall(drm_device_t * dev)
{
int irq_enabled;
if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
return -EINVAL;
- down( &dev->struct_sem );
+ down(&dev->struct_sem);
irq_enabled = dev->irq_enabled;
dev->irq_enabled = 0;
- up( &dev->struct_sem );
+ up(&dev->struct_sem);
- if ( !irq_enabled )
+ if (!irq_enabled)
return -EINVAL;
- DRM_DEBUG( "%s: irq=%d\n", __FUNCTION__, dev->irq );
+ DRM_DEBUG("%s: irq=%d\n", __FUNCTION__, dev->irq);
dev->driver->irq_uninstall(dev);
- free_irq( dev->irq, dev );
+ free_irq(dev->irq, dev);
return 0;
}
+
EXPORT_SYMBOL(drm_irq_uninstall);
/**
@@ -192,30 +191,30 @@ EXPORT_SYMBOL(drm_irq_uninstall);
*
* Calls irq_install() or irq_uninstall() according to \p arg.
*/
-int drm_control( struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg )
+int drm_control(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg)
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->head->dev;
drm_control_t ctl;
-
+
/* if we haven't irq we fallback for compatibility reasons - this used to be a separate function in drm_dma.h */
- if ( copy_from_user( &ctl, (drm_control_t __user *)arg, sizeof(ctl) ) )
+ if (copy_from_user(&ctl, (drm_control_t __user *) arg, sizeof(ctl)))
return -EFAULT;
- switch ( ctl.func ) {
+ switch (ctl.func) {
case DRM_INST_HANDLER:
if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
return 0;
if (dev->if_version < DRM_IF_VERSION(1, 2) &&
ctl.irq != dev->irq)
return -EINVAL;
- return drm_irq_install( dev );
+ return drm_irq_install(dev);
case DRM_UNINST_HANDLER:
if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
return 0;
- return drm_irq_uninstall( dev );
+ return drm_irq_uninstall(dev);
default:
return -EINVAL;
}
@@ -230,7 +229,7 @@ int drm_control( struct inode *inode, struct file *filp,
* \param data user argument, pointing to a drm_wait_vblank structure.
* \return zero on success or a negative number on failure.
*
- * Verifies the IRQ is installed.
+ * Verifies the IRQ is installed.
*
* If a signal is requested checks if this task has already scheduled the same signal
* for the same vblank sequence number - nothing to be done in
@@ -240,7 +239,7 @@ int drm_control( struct inode *inode, struct file *filp,
*
* If a signal is not requested, then calls vblank_wait().
*/
-int drm_wait_vblank( DRM_IOCTL_ARGS )
+int drm_wait_vblank(DRM_IOCTL_ARGS)
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->head->dev;
@@ -256,11 +255,11 @@ int drm_wait_vblank( DRM_IOCTL_ARGS )
if (!dev->irq)
return -EINVAL;
- DRM_COPY_FROM_USER_IOCTL( vblwait, argp, sizeof(vblwait) );
+ DRM_COPY_FROM_USER_IOCTL(vblwait, argp, sizeof(vblwait));
- switch ( vblwait.request.type & ~_DRM_VBLANK_FLAGS_MASK ) {
+ switch (vblwait.request.type & ~_DRM_VBLANK_FLAGS_MASK) {
case _DRM_VBLANK_RELATIVE:
- vblwait.request.sequence += atomic_read( &dev->vbl_received );
+ vblwait.request.sequence += atomic_read(&dev->vbl_received);
vblwait.request.type &= ~_DRM_VBLANK_RELATIVE;
case _DRM_VBLANK_ABSOLUTE:
break;
@@ -269,64 +268,68 @@ int drm_wait_vblank( DRM_IOCTL_ARGS )
}
flags = vblwait.request.type & _DRM_VBLANK_FLAGS_MASK;
-
- if ( flags & _DRM_VBLANK_SIGNAL ) {
+
+ if (flags & _DRM_VBLANK_SIGNAL) {
unsigned long irqflags;
drm_vbl_sig_t *vbl_sig;
-
- vblwait.reply.sequence = atomic_read( &dev->vbl_received );
- spin_lock_irqsave( &dev->vbl_lock, irqflags );
+ vblwait.reply.sequence = atomic_read(&dev->vbl_received);
+
+ spin_lock_irqsave(&dev->vbl_lock, irqflags);
/* Check if this task has already scheduled the same signal
* for the same vblank sequence number; nothing to be done in
* that case
*/
- list_for_each_entry( vbl_sig, &dev->vbl_sigs.head, head ) {
+ list_for_each_entry(vbl_sig, &dev->vbl_sigs.head, head) {
if (vbl_sig->sequence == vblwait.request.sequence
&& vbl_sig->info.si_signo == vblwait.request.signal
- && vbl_sig->task == current)
- {
- spin_unlock_irqrestore( &dev->vbl_lock, irqflags );
+ && vbl_sig->task == current) {
+ spin_unlock_irqrestore(&dev->vbl_lock,
+ irqflags);
goto done;
}
}
- if ( dev->vbl_pending >= 100 ) {
- spin_unlock_irqrestore( &dev->vbl_lock, irqflags );
+ if (dev->vbl_pending >= 100) {
+ spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
return -EBUSY;
}
dev->vbl_pending++;
- spin_unlock_irqrestore( &dev->vbl_lock, irqflags );
+ spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
- if ( !( vbl_sig = drm_alloc( sizeof( drm_vbl_sig_t ), DRM_MEM_DRIVER ) ) ) {
+ if (!
+ (vbl_sig =
+ drm_alloc(sizeof(drm_vbl_sig_t), DRM_MEM_DRIVER))) {
return -ENOMEM;
}
- memset( (void *)vbl_sig, 0, sizeof(*vbl_sig) );
+ memset((void *)vbl_sig, 0, sizeof(*vbl_sig));
vbl_sig->sequence = vblwait.request.sequence;
vbl_sig->info.si_signo = vblwait.request.signal;
vbl_sig->task = current;
- spin_lock_irqsave( &dev->vbl_lock, irqflags );
+ spin_lock_irqsave(&dev->vbl_lock, irqflags);
- list_add_tail( (struct list_head *) vbl_sig, &dev->vbl_sigs.head );
+ list_add_tail((struct list_head *)vbl_sig, &dev->vbl_sigs.head);
- spin_unlock_irqrestore( &dev->vbl_lock, irqflags );
+ spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
} else {
if (dev->driver->vblank_wait)
- ret = dev->driver->vblank_wait( dev, &vblwait.request.sequence );
+ ret =
+ dev->driver->vblank_wait(dev,
+ &vblwait.request.sequence);
- do_gettimeofday( &now );
+ do_gettimeofday(&now);
vblwait.reply.tval_sec = now.tv_sec;
vblwait.reply.tval_usec = now.tv_usec;
}
-done:
- DRM_COPY_TO_USER_IOCTL( argp, vblwait, sizeof(vblwait) );
+ done:
+ DRM_COPY_TO_USER_IOCTL(argp, vblwait, sizeof(vblwait));
return ret;
}
@@ -340,31 +343,31 @@ done:
*
* If a signal is not requested, then calls vblank_wait().
*/
-void drm_vbl_send_signals( drm_device_t *dev )
+void drm_vbl_send_signals(drm_device_t * dev)
{
struct list_head *list, *tmp;
drm_vbl_sig_t *vbl_sig;
- unsigned int vbl_seq = atomic_read( &dev->vbl_received );
+ unsigned int vbl_seq = atomic_read(&dev->vbl_received);
unsigned long flags;
- spin_lock_irqsave( &dev->vbl_lock, flags );
+ spin_lock_irqsave(&dev->vbl_lock, flags);
- list_for_each_safe( list, tmp, &dev->vbl_sigs.head ) {
- vbl_sig = list_entry( list, drm_vbl_sig_t, head );
- if ( ( vbl_seq - vbl_sig->sequence ) <= (1<<23) ) {
+ list_for_each_safe(list, tmp, &dev->vbl_sigs.head) {
+ vbl_sig = list_entry(list, drm_vbl_sig_t, head);
+ if ((vbl_seq - vbl_sig->sequence) <= (1 << 23)) {
vbl_sig->info.si_code = vbl_seq;
- send_sig_info( vbl_sig->info.si_signo, &vbl_sig->info, vbl_sig->task );
+ send_sig_info(vbl_sig->info.si_signo, &vbl_sig->info,
+ vbl_sig->task);
- list_del( list );
+ list_del(list);
- drm_free( vbl_sig, sizeof(*vbl_sig), DRM_MEM_DRIVER );
+ drm_free(vbl_sig, sizeof(*vbl_sig), DRM_MEM_DRIVER);
dev->vbl_pending--;
}
}
- spin_unlock_irqrestore( &dev->vbl_lock, flags );
+ spin_unlock_irqrestore(&dev->vbl_lock, flags);
}
-EXPORT_SYMBOL(drm_vbl_send_signals);
-
+EXPORT_SYMBOL(drm_vbl_send_signals);
diff --git a/drivers/char/drm/drm_lock.c b/drivers/char/drm/drm_lock.c
index 4702d863bcc6..b276ae8a6633 100644
--- a/drivers/char/drm/drm_lock.c
+++ b/drivers/char/drm/drm_lock.c
@@ -1,7 +1,7 @@
/**
- * \file drm_lock.h
+ * \file drm_lock.c
* IOCTLs for locking
- *
+ *
* \author Rickard E. (Rik) Faith <faith@valinux.com>
* \author Gareth Hughes <gareth@valinux.com>
*/
@@ -35,12 +35,12 @@
#include "drmP.h"
-static int drm_lock_transfer(drm_device_t *dev,
+static int drm_lock_transfer(drm_device_t * dev,
__volatile__ unsigned int *lock,
unsigned int context);
static int drm_notifier(void *priv);
-/**
+/**
* Lock ioctl.
*
* \param inode device inode.
@@ -51,91 +51,89 @@ static int drm_notifier(void *priv);
*
* Add the current task to the lock wait queue, and attempt to take to lock.
*/
-int drm_lock( struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg )
+int drm_lock(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg)
{
- drm_file_t *priv = filp->private_data;
- drm_device_t *dev = priv->head->dev;
- DECLARE_WAITQUEUE( entry, current );
- drm_lock_t lock;
- int ret = 0;
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->head->dev;
+ DECLARE_WAITQUEUE(entry, current);
+ drm_lock_t lock;
+ int ret = 0;
++priv->lock_count;
- if ( copy_from_user( &lock, (drm_lock_t __user *)arg, sizeof(lock) ) )
+ if (copy_from_user(&lock, (drm_lock_t __user *) arg, sizeof(lock)))
return -EFAULT;
- if ( lock.context == DRM_KERNEL_CONTEXT ) {
- DRM_ERROR( "Process %d using kernel context %d\n",
- current->pid, lock.context );
- return -EINVAL;
- }
+ if (lock.context == DRM_KERNEL_CONTEXT) {
+ DRM_ERROR("Process %d using kernel context %d\n",
+ current->pid, lock.context);
+ return -EINVAL;
+ }
- DRM_DEBUG( "%d (pid %d) requests lock (0x%08x), flags = 0x%08x\n",
- lock.context, current->pid,
- dev->lock.hw_lock->lock, lock.flags );
+ DRM_DEBUG("%d (pid %d) requests lock (0x%08x), flags = 0x%08x\n",
+ lock.context, current->pid,
+ dev->lock.hw_lock->lock, lock.flags);
if (drm_core_check_feature(dev, DRIVER_DMA_QUEUE))
- if ( lock.context < 0 )
+ if (lock.context < 0)
return -EINVAL;
- add_wait_queue( &dev->lock.lock_queue, &entry );
+ add_wait_queue(&dev->lock.lock_queue, &entry);
for (;;) {
__set_current_state(TASK_INTERRUPTIBLE);
- if ( !dev->lock.hw_lock ) {
+ if (!dev->lock.hw_lock) {
/* Device has been unregistered */
ret = -EINTR;
break;
}
- if ( drm_lock_take( &dev->lock.hw_lock->lock,
- lock.context ) ) {
- dev->lock.filp = filp;
+ if (drm_lock_take(&dev->lock.hw_lock->lock, lock.context)) {
+ dev->lock.filp = filp;
dev->lock.lock_time = jiffies;
- atomic_inc( &dev->counts[_DRM_STAT_LOCKS] );
- break; /* Got lock */
+ atomic_inc(&dev->counts[_DRM_STAT_LOCKS]);
+ break; /* Got lock */
}
-
+
/* Contention */
schedule();
- if ( signal_pending( current ) ) {
+ if (signal_pending(current)) {
ret = -ERESTARTSYS;
break;
}
}
__set_current_state(TASK_RUNNING);
- remove_wait_queue( &dev->lock.lock_queue, &entry );
+ remove_wait_queue(&dev->lock.lock_queue, &entry);
- sigemptyset( &dev->sigmask );
- sigaddset( &dev->sigmask, SIGSTOP );
- sigaddset( &dev->sigmask, SIGTSTP );
- sigaddset( &dev->sigmask, SIGTTIN );
- sigaddset( &dev->sigmask, SIGTTOU );
+ sigemptyset(&dev->sigmask);
+ sigaddset(&dev->sigmask, SIGSTOP);
+ sigaddset(&dev->sigmask, SIGTSTP);
+ sigaddset(&dev->sigmask, SIGTTIN);
+ sigaddset(&dev->sigmask, SIGTTOU);
dev->sigdata.context = lock.context;
- dev->sigdata.lock = dev->lock.hw_lock;
- block_all_signals( drm_notifier,
- &dev->sigdata, &dev->sigmask );
-
+ dev->sigdata.lock = dev->lock.hw_lock;
+ block_all_signals(drm_notifier, &dev->sigdata, &dev->sigmask);
+
if (dev->driver->dma_ready && (lock.flags & _DRM_LOCK_READY))
dev->driver->dma_ready(dev);
-
- if ( dev->driver->dma_quiescent && (lock.flags & _DRM_LOCK_QUIESCENT ))
+
+ if (dev->driver->dma_quiescent && (lock.flags & _DRM_LOCK_QUIESCENT))
return dev->driver->dma_quiescent(dev);
-
- /* dev->driver->kernel_context_switch isn't used by any of the x86
+
+ /* dev->driver->kernel_context_switch isn't used by any of the x86
* drivers but is used by the Sparc driver.
*/
-
- if (dev->driver->kernel_context_switch &&
+
+ if (dev->driver->kernel_context_switch &&
dev->last_context != lock.context) {
- dev->driver->kernel_context_switch(dev, dev->last_context,
- lock.context);
+ dev->driver->kernel_context_switch(dev, dev->last_context,
+ lock.context);
}
- DRM_DEBUG( "%d %s\n", lock.context, ret ? "interrupted" : "has lock" );
+ DRM_DEBUG("%d %s\n", lock.context, ret ? "interrupted" : "has lock");
- return ret;
+ return ret;
}
-/**
+/**
* Unlock ioctl.
*
* \param inode device inode.
@@ -146,23 +144,23 @@ int drm_lock( struct inode *inode, struct file *filp,
*
* Transfer and free the lock.
*/
-int drm_unlock( struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg )
+int drm_unlock(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg)
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->head->dev;
drm_lock_t lock;
- if ( copy_from_user( &lock, (drm_lock_t __user *)arg, sizeof(lock) ) )
+ if (copy_from_user(&lock, (drm_lock_t __user *) arg, sizeof(lock)))
return -EFAULT;
- if ( lock.context == DRM_KERNEL_CONTEXT ) {
- DRM_ERROR( "Process %d using kernel context %d\n",
- current->pid, lock.context );
+ if (lock.context == DRM_KERNEL_CONTEXT) {
+ DRM_ERROR("Process %d using kernel context %d\n",
+ current->pid, lock.context);
return -EINVAL;
}
- atomic_inc( &dev->counts[_DRM_STAT_UNLOCKS] );
+ atomic_inc(&dev->counts[_DRM_STAT_UNLOCKS]);
/* kernel_context_switch isn't used by any of the x86 drm
* modules but is required by the Sparc driver.
@@ -170,12 +168,12 @@ int drm_unlock( struct inode *inode, struct file *filp,
if (dev->driver->kernel_context_switch_unlock)
dev->driver->kernel_context_switch_unlock(dev, &lock);
else {
- drm_lock_transfer( dev, &dev->lock.hw_lock->lock,
- DRM_KERNEL_CONTEXT );
-
- if ( drm_lock_free( dev, &dev->lock.hw_lock->lock,
- DRM_KERNEL_CONTEXT ) ) {
- DRM_ERROR( "\n" );
+ drm_lock_transfer(dev, &dev->lock.hw_lock->lock,
+ DRM_KERNEL_CONTEXT);
+
+ if (drm_lock_free(dev, &dev->lock.hw_lock->lock,
+ DRM_KERNEL_CONTEXT)) {
+ DRM_ERROR("\n");
}
}
@@ -198,8 +196,10 @@ int drm_lock_take(__volatile__ unsigned int *lock, unsigned int context)
do {
old = *lock;
- if (old & _DRM_LOCK_HELD) new = old | _DRM_LOCK_CONT;
- else new = context | _DRM_LOCK_HELD;
+ if (old & _DRM_LOCK_HELD)
+ new = old | _DRM_LOCK_CONT;
+ else
+ new = context | _DRM_LOCK_HELD;
prev = cmpxchg(lock, old, new);
} while (prev != old);
if (_DRM_LOCKING_CONTEXT(old) == context) {
@@ -212,7 +212,7 @@ int drm_lock_take(__volatile__ unsigned int *lock, unsigned int context)
}
}
if (new == (context | _DRM_LOCK_HELD)) {
- /* Have lock */
+ /* Have lock */
return 1;
}
return 0;
@@ -220,8 +220,8 @@ int drm_lock_take(__volatile__ unsigned int *lock, unsigned int context)
/**
* This takes a lock forcibly and hands it to context. Should ONLY be used
- * inside *_unlock to give lock to kernel before calling *_dma_schedule.
- *
+ * inside *_unlock to give lock to kernel before calling *_dma_schedule.
+ *
* \param dev DRM device.
* \param lock lock pointer.
* \param context locking context.
@@ -230,7 +230,7 @@ int drm_lock_take(__volatile__ unsigned int *lock, unsigned int context)
* Resets the lock file pointer.
* Marks the lock as held by the given context, via the \p cmpxchg instruction.
*/
-static int drm_lock_transfer(drm_device_t *dev,
+static int drm_lock_transfer(drm_device_t * dev,
__volatile__ unsigned int *lock,
unsigned int context)
{
@@ -238,8 +238,8 @@ static int drm_lock_transfer(drm_device_t *dev,
dev->lock.filp = NULL;
do {
- old = *lock;
- new = context | _DRM_LOCK_HELD;
+ old = *lock;
+ new = context | _DRM_LOCK_HELD;
prev = cmpxchg(lock, old, new);
} while (prev != old);
return 1;
@@ -247,30 +247,29 @@ static int drm_lock_transfer(drm_device_t *dev,
/**
* Free lock.
- *
+ *
* \param dev DRM device.
* \param lock lock.
* \param context context.
- *
+ *
* Resets the lock file pointer.
* Marks the lock as not held, via the \p cmpxchg instruction. Wakes any task
* waiting on the lock queue.
*/
-int drm_lock_free(drm_device_t *dev,
- __volatile__ unsigned int *lock, unsigned int context)
+int drm_lock_free(drm_device_t * dev,
+ __volatile__ unsigned int *lock, unsigned int context)
{
unsigned int old, new, prev;
dev->lock.filp = NULL;
do {
- old = *lock;
- new = 0;
+ old = *lock;
+ new = 0;
prev = cmpxchg(lock, old, new);
} while (prev != old);
if (_DRM_LOCK_IS_HELD(old) && _DRM_LOCKING_CONTEXT(old) != context) {
DRM_ERROR("%d freed heavyweight lock held by %d\n",
- context,
- _DRM_LOCKING_CONTEXT(old));
+ context, _DRM_LOCKING_CONTEXT(old));
return 1;
}
wake_up_interruptible(&dev->lock.lock_queue);
@@ -290,19 +289,19 @@ int drm_lock_free(drm_device_t *dev,
*/
static int drm_notifier(void *priv)
{
- drm_sigdata_t *s = (drm_sigdata_t *)priv;
- unsigned int old, new, prev;
-
+ drm_sigdata_t *s = (drm_sigdata_t *) priv;
+ unsigned int old, new, prev;
- /* Allow signal delivery if lock isn't held */
+ /* Allow signal delivery if lock isn't held */
if (!s->lock || !_DRM_LOCK_IS_HELD(s->lock->lock)
- || _DRM_LOCKING_CONTEXT(s->lock->lock) != s->context) return 1;
+ || _DRM_LOCKING_CONTEXT(s->lock->lock) != s->context)
+ return 1;
- /* Otherwise, set flag to force call to
- drmUnlock */
+ /* Otherwise, set flag to force call to
+ drmUnlock */
do {
- old = s->lock->lock;
- new = old | _DRM_LOCK_CONT;
+ old = s->lock->lock;
+ new = old | _DRM_LOCK_CONT;
prev = cmpxchg(&s->lock->lock, old, new);
} while (prev != old);
return 0;
diff --git a/drivers/char/drm/drm_memory.c b/drivers/char/drm/drm_memory.c
index ff483fb418aa..2c74155aa84f 100644
--- a/drivers/char/drm/drm_memory.c
+++ b/drivers/char/drm/drm_memory.c
@@ -1,12 +1,12 @@
-/**
- * \file drm_memory.h
+/**
+ * \file drm_memory.c
* Memory management wrappers for DRM
*
* \author Rickard E. (Rik) Faith <faith@valinux.com>
* \author Gareth Hughes <gareth@valinux.com>
*/
-/*
+/*
* Created: Thu Feb 4 14:00:34 1999 by faith@valinux.com
*
* Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
@@ -48,7 +48,7 @@ void drm_mem_init(void)
/**
* Called when "/proc/dri/%dev%/mem" is read.
- *
+ *
* \param buf output buffer.
* \param start start of output data.
* \param offset requested start offset.
@@ -57,10 +57,10 @@ void drm_mem_init(void)
* \param data private data.
* \return number of written bytes.
*
- * No-op.
+ * No-op.
*/
int drm_mem_info(char *buf, char **start, off_t offset,
- int len, int *eof, void *data)
+ int len, int *eof, void *data)
{
return 0;
}
@@ -70,7 +70,8 @@ void *drm_realloc(void *oldpt, size_t oldsize, size_t size, int area)
{
void *pt;
- if (!(pt = kmalloc(size, GFP_KERNEL))) return NULL;
+ if (!(pt = kmalloc(size, GFP_KERNEL)))
+ return NULL;
if (oldpt && oldsize) {
memcpy(pt, oldpt, oldsize);
kfree(oldpt);
@@ -90,21 +91,20 @@ void *drm_realloc(void *oldpt, size_t oldsize, size_t size, int area)
unsigned long drm_alloc_pages(int order, int area)
{
unsigned long address;
- unsigned long bytes = PAGE_SIZE << order;
+ unsigned long bytes = PAGE_SIZE << order;
unsigned long addr;
- unsigned int sz;
+ unsigned int sz;
address = __get_free_pages(GFP_KERNEL, order);
- if (!address)
+ if (!address)
return 0;
- /* Zero */
+ /* Zero */
memset((void *)address, 0, bytes);
- /* Reserve */
+ /* Reserve */
for (addr = address, sz = bytes;
- sz > 0;
- addr += PAGE_SIZE, sz -= PAGE_SIZE) {
+ sz > 0; addr += PAGE_SIZE, sz -= PAGE_SIZE) {
SetPageReserved(virt_to_page(addr));
}
@@ -113,7 +113,7 @@ unsigned long drm_alloc_pages(int order, int area)
/**
* Free pages.
- *
+ *
* \param address address of the pages to free.
* \param order size order.
* \param area memory area. (Not used.)
@@ -124,49 +124,51 @@ void drm_free_pages(unsigned long address, int order, int area)
{
unsigned long bytes = PAGE_SIZE << order;
unsigned long addr;
- unsigned int sz;
+ unsigned int sz;
- if (!address)
+ if (!address)
return;
/* Unreserve */
for (addr = address, sz = bytes;
- sz > 0;
- addr += PAGE_SIZE, sz -= PAGE_SIZE) {
+ sz > 0; addr += PAGE_SIZE, sz -= PAGE_SIZE) {
ClearPageReserved(virt_to_page(addr));
}
free_pages(address, order);
}
-
#if __OS_HAS_AGP
/** Wrapper around agp_allocate_memory() */
-DRM_AGP_MEM *drm_alloc_agp(drm_device_t *dev, int pages, u32 type)
+DRM_AGP_MEM *drm_alloc_agp(drm_device_t * dev, int pages, u32 type)
{
return drm_agp_allocate_memory(dev->agp->bridge, pages, type);
}
+
EXPORT_SYMBOL(drm_alloc_agp);
/** Wrapper around agp_free_memory() */
-int drm_free_agp(DRM_AGP_MEM *handle, int pages)
+int drm_free_agp(DRM_AGP_MEM * handle, int pages)
{
return drm_agp_free_memory(handle) ? 0 : -EINVAL;
}
+
EXPORT_SYMBOL(drm_free_agp);
/** Wrapper around agp_bind_memory() */
-int drm_bind_agp(DRM_AGP_MEM *handle, unsigned int start)
+int drm_bind_agp(DRM_AGP_MEM * handle, unsigned int start)
{
return drm_agp_bind_memory(handle, start);
}
+
EXPORT_SYMBOL(drm_bind_agp);
/** Wrapper around agp_unbind_memory() */
-int drm_unbind_agp(DRM_AGP_MEM *handle)
+int drm_unbind_agp(DRM_AGP_MEM * handle)
{
return drm_agp_unbind_memory(handle);
}
+
EXPORT_SYMBOL(drm_unbind_agp);
-#endif /* agp */
-#endif /* debug_memory */
+#endif /* agp */
+#endif /* debug_memory */
diff --git a/drivers/char/drm/drm_memory.h b/drivers/char/drm/drm_memory.h
index 422b94268709..3732a61c3762 100644
--- a/drivers/char/drm/drm_memory.h
+++ b/drivers/char/drm/drm_memory.h
@@ -1,12 +1,12 @@
-/**
- * \file drm_memory.h
+/**
+ * \file drm_memory.h
* Memory management wrappers for DRM
*
* \author Rickard E. (Rik) Faith <faith@valinux.com>
* \author Gareth Hughes <gareth@valinux.com>
*/
-/*
+/*
* Created: Thu Feb 4 14:00:34 1999 by faith@valinux.com
*
* Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
@@ -40,7 +40,7 @@
/**
* Cut down version of drm_memory_debug.h, which used to be called
- * drm_memory.h.
+ * drm_memory.h.
*/
#if __OS_HAS_AGP
@@ -60,8 +60,8 @@
/*
* Find the drm_map that covers the range [offset, offset+size).
*/
-static inline drm_map_t *
-drm_lookup_map (unsigned long offset, unsigned long size, drm_device_t *dev)
+static inline drm_map_t *drm_lookup_map(unsigned long offset,
+ unsigned long size, drm_device_t * dev)
{
struct list_head *list;
drm_map_list_t *r_list;
@@ -72,16 +72,18 @@ drm_lookup_map (unsigned long offset, unsigned long size, drm_device_t *dev)
map = r_list->map;
if (!map)
continue;
- if (map->offset <= offset && (offset + size) <= (map->offset + map->size))
+ if (map->offset <= offset
+ && (offset + size) <= (map->offset + map->size))
return map;
}
return NULL;
}
-static inline void *
-agp_remap (unsigned long offset, unsigned long size, drm_device_t *dev)
+static inline void *agp_remap(unsigned long offset, unsigned long size,
+ drm_device_t * dev)
{
- unsigned long *phys_addr_map, i, num_pages = PAGE_ALIGN(size) / PAGE_SIZE;
+ unsigned long *phys_addr_map, i, num_pages =
+ PAGE_ALIGN(size) / PAGE_SIZE;
struct drm_agp_mem *agpmem;
struct page **page_map;
void *addr;
@@ -94,7 +96,8 @@ agp_remap (unsigned long offset, unsigned long size, drm_device_t *dev)
for (agpmem = dev->agp->memory; agpmem; agpmem = agpmem->next)
if (agpmem->bound <= offset
- && (agpmem->bound + (agpmem->pages << PAGE_SHIFT)) >= (offset + size))
+ && (agpmem->bound + (agpmem->pages << PAGE_SHIFT)) >=
+ (offset + size))
break;
if (!agpmem)
return NULL;
@@ -109,7 +112,8 @@ agp_remap (unsigned long offset, unsigned long size, drm_device_t *dev)
if (!page_map)
return NULL;
- phys_addr_map = agpmem->memory->memory + (offset - agpmem->bound) / PAGE_SIZE;
+ phys_addr_map =
+ agpmem->memory->memory + (offset - agpmem->bound) / PAGE_SIZE;
for (i = 0; i < num_pages; ++i)
page_map[i] = pfn_to_page(phys_addr_map[i] >> PAGE_SHIFT);
addr = vmap(page_map, num_pages, VM_IOREMAP, PAGE_AGP);
@@ -118,36 +122,38 @@ agp_remap (unsigned long offset, unsigned long size, drm_device_t *dev)
return addr;
}
-static inline unsigned long
-drm_follow_page (void *vaddr)
+static inline unsigned long drm_follow_page(void *vaddr)
{
- pgd_t *pgd = pgd_offset_k((unsigned long) vaddr);
- pud_t *pud = pud_offset(pgd, (unsigned long) vaddr);
- pmd_t *pmd = pmd_offset(pud, (unsigned long) vaddr);
- pte_t *ptep = pte_offset_kernel(pmd, (unsigned long) vaddr);
+ pgd_t *pgd = pgd_offset_k((unsigned long)vaddr);
+ pud_t *pud = pud_offset(pgd, (unsigned long)vaddr);
+ pmd_t *pmd = pmd_offset(pud, (unsigned long)vaddr);
+ pte_t *ptep = pte_offset_kernel(pmd, (unsigned long)vaddr);
return pte_pfn(*ptep) << PAGE_SHIFT;
}
-#else /* __OS_HAS_AGP */
+#else /* __OS_HAS_AGP */
-static inline drm_map_t *drm_lookup_map(unsigned long offset, unsigned long size, drm_device_t *dev)
+static inline drm_map_t *drm_lookup_map(unsigned long offset,
+ unsigned long size, drm_device_t * dev)
{
- return NULL;
+ return NULL;
}
-static inline void *agp_remap(unsigned long offset, unsigned long size, drm_device_t *dev)
+static inline void *agp_remap(unsigned long offset, unsigned long size,
+ drm_device_t * dev)
{
- return NULL;
+ return NULL;
}
-static inline unsigned long drm_follow_page (void *vaddr)
+static inline unsigned long drm_follow_page(void *vaddr)
{
- return 0;
+ return 0;
}
#endif
-static inline void *drm_ioremap(unsigned long offset, unsigned long size, drm_device_t *dev)
+static inline void *drm_ioremap(unsigned long offset, unsigned long size,
+ drm_device_t * dev)
{
if (drm_core_has_AGP(dev) && dev->agp && dev->agp->cant_use_aperture) {
drm_map_t *map = drm_lookup_map(offset, size, dev);
@@ -158,8 +164,8 @@ static inline void *drm_ioremap(unsigned long offset, unsigned long size, drm_de
return ioremap(offset, size);
}
-static inline void *drm_ioremap_nocache(unsigned long offset, unsigned long size,
- drm_device_t *dev)
+static inline void *drm_ioremap_nocache(unsigned long offset,
+ unsigned long size, drm_device_t * dev)
{
if (drm_core_has_AGP(dev) && dev->agp && dev->agp->cant_use_aperture) {
drm_map_t *map = drm_lookup_map(offset, size, dev);
@@ -170,7 +176,8 @@ static inline void *drm_ioremap_nocache(unsigned long offset, unsigned long size
return ioremap_nocache(offset, size);
}
-static inline void drm_ioremapfree(void *pt, unsigned long size, drm_device_t *dev)
+static inline void drm_ioremapfree(void *pt, unsigned long size,
+ drm_device_t * dev)
{
/*
* This is a bit ugly. It would be much cleaner if the DRM API would use separate
@@ -178,12 +185,12 @@ static inline void drm_ioremapfree(void *pt, unsigned long size, drm_device_t *d
* a future revision of the interface...
*/
if (drm_core_has_AGP(dev) && dev->agp && dev->agp->cant_use_aperture
- && ((unsigned long) pt >= VMALLOC_START && (unsigned long) pt < VMALLOC_END))
- {
+ && ((unsigned long)pt >= VMALLOC_START
+ && (unsigned long)pt < VMALLOC_END)) {
unsigned long offset;
drm_map_t *map;
- offset = drm_follow_page(pt) | ((unsigned long) pt & ~PAGE_MASK);
+ offset = drm_follow_page(pt) | ((unsigned long)pt & ~PAGE_MASK);
map = drm_lookup_map(offset, size, dev);
if (map && map->type == _DRM_AGP) {
vunmap(pt);
@@ -193,5 +200,3 @@ static inline void drm_ioremapfree(void *pt, unsigned long size, drm_device_t *d
iounmap(pt);
}
-
-
diff --git a/drivers/char/drm/drm_memory_debug.h b/drivers/char/drm/drm_memory_debug.h
index 2c82e69a7fd2..4542353195bd 100644
--- a/drivers/char/drm/drm_memory_debug.h
+++ b/drivers/char/drm/drm_memory_debug.h
@@ -1,5 +1,5 @@
/**
- * \file drm_memory.h
+ * \file drm_memory.h
* Memory management wrappers for DRM.
*
* \author Rickard E. (Rik) Faith <faith@valinux.com>
@@ -35,75 +35,75 @@
#include "drmP.h"
typedef struct drm_mem_stats {
- const char *name;
- int succeed_count;
- int free_count;
- int fail_count;
- unsigned long bytes_allocated;
- unsigned long bytes_freed;
+ const char *name;
+ int succeed_count;
+ int free_count;
+ int fail_count;
+ unsigned long bytes_allocated;
+ unsigned long bytes_freed;
} drm_mem_stats_t;
static DEFINE_SPINLOCK(DRM(mem_lock));
-static unsigned long DRM(ram_available) = 0; /* In pages */
-static unsigned long DRM(ram_used) = 0;
-static drm_mem_stats_t DRM(mem_stats)[] = {
- [DRM_MEM_DMA] = { "dmabufs" },
- [DRM_MEM_SAREA] = { "sareas" },
- [DRM_MEM_DRIVER] = { "driver" },
- [DRM_MEM_MAGIC] = { "magic" },
- [DRM_MEM_IOCTLS] = { "ioctltab" },
- [DRM_MEM_MAPS] = { "maplist" },
- [DRM_MEM_VMAS] = { "vmalist" },
- [DRM_MEM_BUFS] = { "buflist" },
- [DRM_MEM_SEGS] = { "seglist" },
- [DRM_MEM_PAGES] = { "pagelist" },
- [DRM_MEM_FILES] = { "files" },
- [DRM_MEM_QUEUES] = { "queues" },
- [DRM_MEM_CMDS] = { "commands" },
- [DRM_MEM_MAPPINGS] = { "mappings" },
- [DRM_MEM_BUFLISTS] = { "buflists" },
- [DRM_MEM_AGPLISTS] = { "agplist" },
- [DRM_MEM_SGLISTS] = { "sglist" },
- [DRM_MEM_TOTALAGP] = { "totalagp" },
- [DRM_MEM_BOUNDAGP] = { "boundagp" },
- [DRM_MEM_CTXBITMAP] = { "ctxbitmap"},
- [DRM_MEM_CTXLIST] = { "ctxlist" },
- [DRM_MEM_STUB] = { "stub" },
- { NULL, 0, } /* Last entry must be null */
+static unsigned long DRM(ram_available) = 0; /* In pages */
+static unsigned long DRM(ram_used) = 0;
+static drm_mem_stats_t DRM(mem_stats)[] =
+{
+ [DRM_MEM_DMA] = {
+ "dmabufs"},[DRM_MEM_SAREA] = {
+ "sareas"},[DRM_MEM_DRIVER] = {
+ "driver"},[DRM_MEM_MAGIC] = {
+ "magic"},[DRM_MEM_IOCTLS] = {
+ "ioctltab"},[DRM_MEM_MAPS] = {
+ "maplist"},[DRM_MEM_VMAS] = {
+ "vmalist"},[DRM_MEM_BUFS] = {
+ "buflist"},[DRM_MEM_SEGS] = {
+ "seglist"},[DRM_MEM_PAGES] = {
+ "pagelist"},[DRM_MEM_FILES] = {
+ "files"},[DRM_MEM_QUEUES] = {
+ "queues"},[DRM_MEM_CMDS] = {
+ "commands"},[DRM_MEM_MAPPINGS] = {
+ "mappings"},[DRM_MEM_BUFLISTS] = {
+ "buflists"},[DRM_MEM_AGPLISTS] = {
+ "agplist"},[DRM_MEM_SGLISTS] = {
+ "sglist"},[DRM_MEM_TOTALAGP] = {
+ "totalagp"},[DRM_MEM_BOUNDAGP] = {
+ "boundagp"},[DRM_MEM_CTXBITMAP] = {
+ "ctxbitmap"},[DRM_MEM_CTXLIST] = {
+ "ctxlist"},[DRM_MEM_STUB] = {
+ "stub"}, {
+ NULL, 0,} /* Last entry must be null */
};
-void DRM(mem_init)(void)
-{
+void DRM(mem_init) (void) {
drm_mem_stats_t *mem;
- struct sysinfo si;
+ struct sysinfo si;
for (mem = DRM(mem_stats); mem->name; ++mem) {
- mem->succeed_count = 0;
- mem->free_count = 0;
- mem->fail_count = 0;
+ mem->succeed_count = 0;
+ mem->free_count = 0;
+ mem->fail_count = 0;
mem->bytes_allocated = 0;
- mem->bytes_freed = 0;
+ mem->bytes_freed = 0;
}
si_meminfo(&si);
DRM(ram_available) = si.totalram;
- DRM(ram_used) = 0;
+ DRM(ram_used) = 0;
}
/* drm_mem_info is called whenever a process reads /dev/drm/mem. */
-static int DRM(_mem_info)(char *buf, char **start, off_t offset,
- int request, int *eof, void *data)
-{
+static int DRM(_mem_info) (char *buf, char **start, off_t offset,
+ int request, int *eof, void *data) {
drm_mem_stats_t *pt;
- int len = 0;
+ int len = 0;
if (offset > DRM_PROC_LIMIT) {
*eof = 1;
return 0;
}
- *eof = 0;
+ *eof = 0;
*start = &buf[offset];
DRM_PROC_PRINT(" total counts "
@@ -129,24 +129,23 @@ static int DRM(_mem_info)(char *buf, char **start, off_t offset,
- (long)pt->bytes_freed);
}
- if (len > request + offset) return request;
+ if (len > request + offset)
+ return request;
*eof = 1;
return len - offset;
}
-int DRM(mem_info)(char *buf, char **start, off_t offset,
- int len, int *eof, void *data)
-{
+int DRM(mem_info) (char *buf, char **start, off_t offset,
+ int len, int *eof, void *data) {
int ret;
spin_lock(&DRM(mem_lock));
- ret = DRM(_mem_info)(buf, start, offset, len, eof, data);
+ ret = DRM(_mem_info) (buf, start, offset, len, eof, data);
spin_unlock(&DRM(mem_lock));
return ret;
}
-void *DRM(alloc)(size_t size, int area)
-{
+void *DRM(alloc) (size_t size, int area) {
void *pt;
if (!size) {
@@ -167,40 +166,40 @@ void *DRM(alloc)(size_t size, int area)
return pt;
}
-void *DRM(calloc)(size_t nmemb, size_t size, int area)
-{
+void *DRM(calloc) (size_t nmemb, size_t size, int area) {
void *addr;
- addr = DRM(alloc)(nmemb * size, area);
+ addr = DRM(alloc) (nmemb * size, area);
if (addr != NULL)
memset((void *)addr, 0, size * nmemb);
return addr;
}
-void *DRM(realloc)(void *oldpt, size_t oldsize, size_t size, int area)
-{
+void *DRM(realloc) (void *oldpt, size_t oldsize, size_t size, int area) {
void *pt;
- if (!(pt = DRM(alloc)(size, area))) return NULL;
+ if (!(pt = DRM(alloc) (size, area)))
+ return NULL;
if (oldpt && oldsize) {
memcpy(pt, oldpt, oldsize);
- DRM(free)(oldpt, oldsize, area);
+ DRM(free) (oldpt, oldsize, area);
}
return pt;
}
-void DRM(free)(void *pt, size_t size, int area)
-{
+void DRM(free) (void *pt, size_t size, int area) {
int alloc_count;
int free_count;
- if (!pt) DRM_MEM_ERROR(area, "Attempt to free NULL pointer\n");
- else kfree(pt);
+ if (!pt)
+ DRM_MEM_ERROR(area, "Attempt to free NULL pointer\n");
+ else
+ kfree(pt);
spin_lock(&DRM(mem_lock));
DRM(mem_stats)[area].bytes_freed += size;
- free_count = ++DRM(mem_stats)[area].free_count;
- alloc_count = DRM(mem_stats)[area].succeed_count;
+ free_count = ++DRM(mem_stats)[area].free_count;
+ alloc_count = DRM(mem_stats)[area].succeed_count;
spin_unlock(&DRM(mem_lock));
if (free_count > alloc_count) {
DRM_MEM_ERROR(area, "Excess frees: %d frees, %d allocs\n",
@@ -208,12 +207,11 @@ void DRM(free)(void *pt, size_t size, int area)
}
}
-unsigned long DRM(alloc_pages)(int order, int area)
-{
+unsigned long DRM(alloc_pages) (int order, int area) {
unsigned long address;
- unsigned long bytes = PAGE_SIZE << order;
+ unsigned long bytes = PAGE_SIZE << order;
unsigned long addr;
- unsigned int sz;
+ unsigned int sz;
spin_lock(&DRM(mem_lock));
if ((DRM(ram_used) >> PAGE_SHIFT)
@@ -233,48 +231,44 @@ unsigned long DRM(alloc_pages)(int order, int area)
spin_lock(&DRM(mem_lock));
++DRM(mem_stats)[area].succeed_count;
DRM(mem_stats)[area].bytes_allocated += bytes;
- DRM(ram_used) += bytes;
+ DRM(ram_used) += bytes;
spin_unlock(&DRM(mem_lock));
-
- /* Zero outside the lock */
+ /* Zero outside the lock */
memset((void *)address, 0, bytes);
- /* Reserve */
+ /* Reserve */
for (addr = address, sz = bytes;
- sz > 0;
- addr += PAGE_SIZE, sz -= PAGE_SIZE) {
+ sz > 0; addr += PAGE_SIZE, sz -= PAGE_SIZE) {
SetPageReserved(virt_to_page(addr));
}
return address;
}
-void DRM(free_pages)(unsigned long address, int order, int area)
-{
+void DRM(free_pages) (unsigned long address, int order, int area) {
unsigned long bytes = PAGE_SIZE << order;
- int alloc_count;
- int free_count;
+ int alloc_count;
+ int free_count;
unsigned long addr;
- unsigned int sz;
+ unsigned int sz;
if (!address) {
DRM_MEM_ERROR(area, "Attempt to free address 0\n");
} else {
- /* Unreserve */
+ /* Unreserve */
for (addr = address, sz = bytes;
- sz > 0;
- addr += PAGE_SIZE, sz -= PAGE_SIZE) {
+ sz > 0; addr += PAGE_SIZE, sz -= PAGE_SIZE) {
ClearPageReserved(virt_to_page(addr));
}
free_pages(address, order);
}
spin_lock(&DRM(mem_lock));
- free_count = ++DRM(mem_stats)[area].free_count;
- alloc_count = DRM(mem_stats)[area].succeed_count;
+ free_count = ++DRM(mem_stats)[area].free_count;
+ alloc_count = DRM(mem_stats)[area].succeed_count;
DRM(mem_stats)[area].bytes_freed += bytes;
- DRM(ram_used) -= bytes;
+ DRM(ram_used) -= bytes;
spin_unlock(&DRM(mem_lock));
if (free_count > alloc_count) {
DRM_MEM_ERROR(area,
@@ -283,8 +277,8 @@ void DRM(free_pages)(unsigned long address, int order, int area)
}
}
-void *DRM(ioremap)(unsigned long offset, unsigned long size, drm_device_t *dev)
-{
+void *DRM(ioremap) (unsigned long offset, unsigned long size,
+ drm_device_t * dev) {
void *pt;
if (!size) {
@@ -306,8 +300,8 @@ void *DRM(ioremap)(unsigned long offset, unsigned long size, drm_device_t *dev)
return pt;
}
-void *DRM(ioremap_nocache)(unsigned long offset, unsigned long size, drm_device_t *dev)
-{
+void *DRM(ioremap_nocache) (unsigned long offset, unsigned long size,
+ drm_device_t * dev) {
void *pt;
if (!size) {
@@ -329,8 +323,7 @@ void *DRM(ioremap_nocache)(unsigned long offset, unsigned long size, drm_device_
return pt;
}
-void DRM(ioremapfree)(void *pt, unsigned long size, drm_device_t *dev)
-{
+void DRM(ioremapfree) (void *pt, unsigned long size, drm_device_t * dev) {
int alloc_count;
int free_count;
@@ -342,8 +335,8 @@ void DRM(ioremapfree)(void *pt, unsigned long size, drm_device_t *dev)
spin_lock(&DRM(mem_lock));
DRM(mem_stats)[DRM_MEM_MAPPINGS].bytes_freed += size;
- free_count = ++DRM(mem_stats)[DRM_MEM_MAPPINGS].free_count;
- alloc_count = DRM(mem_stats)[DRM_MEM_MAPPINGS].succeed_count;
+ free_count = ++DRM(mem_stats)[DRM_MEM_MAPPINGS].free_count;
+ alloc_count = DRM(mem_stats)[DRM_MEM_MAPPINGS].succeed_count;
spin_unlock(&DRM(mem_lock));
if (free_count > alloc_count) {
DRM_MEM_ERROR(DRM_MEM_MAPPINGS,
@@ -354,8 +347,7 @@ void DRM(ioremapfree)(void *pt, unsigned long size, drm_device_t *dev)
#if __OS_HAS_AGP
-DRM_AGP_MEM *DRM(alloc_agp)(int pages, u32 type)
-{
+DRM_AGP_MEM *DRM(alloc_agp) (int pages, u32 type) {
DRM_AGP_MEM *handle;
if (!pages) {
@@ -363,11 +355,11 @@ DRM_AGP_MEM *DRM(alloc_agp)(int pages, u32 type)
return NULL;
}
- if ((handle = DRM(agp_allocate_memory)(pages, type))) {
+ if ((handle = DRM(agp_allocate_memory) (pages, type))) {
spin_lock(&DRM(mem_lock));
++DRM(mem_stats)[DRM_MEM_TOTALAGP].succeed_count;
DRM(mem_stats)[DRM_MEM_TOTALAGP].bytes_allocated
- += pages << PAGE_SHIFT;
+ += pages << PAGE_SHIFT;
spin_unlock(&DRM(mem_lock));
return handle;
}
@@ -377,11 +369,10 @@ DRM_AGP_MEM *DRM(alloc_agp)(int pages, u32 type)
return NULL;
}
-int DRM(free_agp)(DRM_AGP_MEM *handle, int pages)
-{
- int alloc_count;
- int free_count;
- int retval = -EINVAL;
+int DRM(free_agp) (DRM_AGP_MEM * handle, int pages) {
+ int alloc_count;
+ int free_count;
+ int retval = -EINVAL;
if (!handle) {
DRM_MEM_ERROR(DRM_MEM_TOTALAGP,
@@ -389,12 +380,12 @@ int DRM(free_agp)(DRM_AGP_MEM *handle, int pages)
return retval;
}
- if (DRM(agp_free_memory)(handle)) {
+ if (DRM(agp_free_memory) (handle)) {
spin_lock(&DRM(mem_lock));
- free_count = ++DRM(mem_stats)[DRM_MEM_TOTALAGP].free_count;
- alloc_count = DRM(mem_stats)[DRM_MEM_TOTALAGP].succeed_count;
+ free_count = ++DRM(mem_stats)[DRM_MEM_TOTALAGP].free_count;
+ alloc_count = DRM(mem_stats)[DRM_MEM_TOTALAGP].succeed_count;
DRM(mem_stats)[DRM_MEM_TOTALAGP].bytes_freed
- += pages << PAGE_SHIFT;
+ += pages << PAGE_SHIFT;
spin_unlock(&DRM(mem_lock));
if (free_count > alloc_count) {
DRM_MEM_ERROR(DRM_MEM_TOTALAGP,
@@ -406,8 +397,7 @@ int DRM(free_agp)(DRM_AGP_MEM *handle, int pages)
return retval;
}
-int DRM(bind_agp)(DRM_AGP_MEM *handle, unsigned int start)
-{
+int DRM(bind_agp) (DRM_AGP_MEM * handle, unsigned int start) {
int retcode = -EINVAL;
if (!handle) {
@@ -416,11 +406,11 @@ int DRM(bind_agp)(DRM_AGP_MEM *handle, unsigned int start)
return retcode;
}
- if (!(retcode = DRM(agp_bind_memory)(handle, start))) {
+ if (!(retcode = DRM(agp_bind_memory) (handle, start))) {
spin_lock(&DRM(mem_lock));
++DRM(mem_stats)[DRM_MEM_BOUNDAGP].succeed_count;
DRM(mem_stats)[DRM_MEM_BOUNDAGP].bytes_allocated
- += handle->page_count << PAGE_SHIFT;
+ += handle->page_count << PAGE_SHIFT;
spin_unlock(&DRM(mem_lock));
return retcode;
}
@@ -430,8 +420,7 @@ int DRM(bind_agp)(DRM_AGP_MEM *handle, unsigned int start)
return retcode;
}
-int DRM(unbind_agp)(DRM_AGP_MEM *handle)
-{
+int DRM(unbind_agp) (DRM_AGP_MEM * handle) {
int alloc_count;
int free_count;
int retcode = -EINVAL;
@@ -442,12 +431,13 @@ int DRM(unbind_agp)(DRM_AGP_MEM *handle)
return retcode;
}
- if ((retcode = DRM(agp_unbind_memory)(handle))) return retcode;
+ if ((retcode = DRM(agp_unbind_memory) (handle)))
+ return retcode;
spin_lock(&DRM(mem_lock));
- free_count = ++DRM(mem_stats)[DRM_MEM_BOUNDAGP].free_count;
+ free_count = ++DRM(mem_stats)[DRM_MEM_BOUNDAGP].free_count;
alloc_count = DRM(mem_stats)[DRM_MEM_BOUNDAGP].succeed_count;
DRM(mem_stats)[DRM_MEM_BOUNDAGP].bytes_freed
- += handle->page_count << PAGE_SHIFT;
+ += handle->page_count << PAGE_SHIFT;
spin_unlock(&DRM(mem_lock));
if (free_count > alloc_count) {
DRM_MEM_ERROR(DRM_MEM_BOUNDAGP,
diff --git a/drivers/char/drm/drm_os_linux.h b/drivers/char/drm/drm_os_linux.h
index b14cd370dea5..d51aeb4966f4 100644
--- a/drivers/char/drm/drm_os_linux.h
+++ b/drivers/char/drm/drm_os_linux.h
@@ -3,7 +3,6 @@
* OS abstraction macros.
*/
-
#include <linux/interrupt.h> /* For task queue support */
#include <linux/delay.h>
@@ -47,25 +46,25 @@
#else
/* define some dummy types for non AGP supporting kernels */
struct no_agp_kern {
- unsigned long aper_base;
- unsigned long aper_size;
+ unsigned long aper_base;
+ unsigned long aper_size;
};
#define DRM_AGP_MEM int
#define DRM_AGP_KERN struct no_agp_kern
#endif
#if !(__OS_HAS_MTRR)
-static __inline__ int mtrr_add (unsigned long base, unsigned long size,
- unsigned int type, char increment)
+static __inline__ int mtrr_add(unsigned long base, unsigned long size,
+ unsigned int type, char increment)
{
return -ENODEV;
}
-static __inline__ int mtrr_del (int reg, unsigned long base,
- unsigned long size)
+static __inline__ int mtrr_del(int reg, unsigned long base, unsigned long size)
{
return -ENODEV;
}
+
#define MTRR_TYPE_WRCOMB 1
#endif
@@ -99,7 +98,7 @@ static __inline__ int mtrr_del (int reg, unsigned long base,
#define DRM_GET_PRIV_WITH_RETURN(_priv, _filp) _priv = _filp->private_data
-/**
+/**
* Get the pointer to the SAREA.
*
* Searches the SAREA on the mapping lists and points drm_device::sarea to it.
@@ -143,7 +142,5 @@ do { \
remove_wait_queue(&(queue), &entry); \
} while (0)
-
#define DRM_WAKEUP( queue ) wake_up_interruptible( queue )
#define DRM_INIT_WAITQUEUE( queue ) init_waitqueue_head( queue )
-
diff --git a/drivers/char/drm/drm_pci.c b/drivers/char/drm/drm_pci.c
index 09ed712c1a7f..1fd7ff164817 100644
--- a/drivers/char/drm/drm_pci.c
+++ b/drivers/char/drm/drm_pci.c
@@ -77,7 +77,7 @@ drm_dma_handle_t *drm_pci_alloc(drm_device_t * dev, size_t size, size_t align,
dmah = kmalloc(sizeof(drm_dma_handle_t), GFP_KERNEL);
if (!dmah)
return NULL;
-
+
dmah->size = size;
dmah->vaddr = pci_alloc_consistent(dev->pdev, size, &dmah->busaddr);
@@ -106,6 +106,7 @@ drm_dma_handle_t *drm_pci_alloc(drm_device_t * dev, size_t size, size_t align,
return dmah;
}
+
EXPORT_SYMBOL(drm_pci_alloc);
/**
@@ -113,8 +114,7 @@ EXPORT_SYMBOL(drm_pci_alloc);
*
* This function is for internal use in the Linux-specific DRM core code.
*/
-void
-__drm_pci_free(drm_device_t * dev, drm_dma_handle_t *dmah)
+void __drm_pci_free(drm_device_t * dev, drm_dma_handle_t * dmah)
{
#ifdef DRM_DEBUG_MEMORY
int area = DRM_MEM_DMA;
@@ -150,12 +150,12 @@ __drm_pci_free(drm_device_t * dev, drm_dma_handle_t *dmah)
/**
* \brief Free a PCI consistent memory block
*/
-void
-drm_pci_free(drm_device_t *dev, drm_dma_handle_t *dmah)
+void drm_pci_free(drm_device_t * dev, drm_dma_handle_t * dmah)
{
__drm_pci_free(dev, dmah);
kfree(dmah);
}
+
EXPORT_SYMBOL(drm_pci_free);
/*@}*/
diff --git a/drivers/char/drm/drm_pciids.h b/drivers/char/drm/drm_pciids.h
index 58b1747cd440..d66dc55e29a0 100644
--- a/drivers/char/drm/drm_pciids.h
+++ b/drivers/char/drm/drm_pciids.h
@@ -234,4 +234,3 @@
{0x8086, 0x2592, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x8086, 0x2772, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0, 0, 0}
-
diff --git a/drivers/char/drm/drm_proc.c b/drivers/char/drm/drm_proc.c
index 977961002488..3f452f763f0f 100644
--- a/drivers/char/drm/drm_proc.c
+++ b/drivers/char/drm/drm_proc.c
@@ -1,5 +1,5 @@
/**
- * \file drm_proc.h
+ * \file drm_proc.c
* /proc support for DRM
*
* \author Rickard E. (Rik) Faith <faith@valinux.com>
@@ -39,19 +39,19 @@
#include "drmP.h"
-static int drm_name_info(char *buf, char **start, off_t offset,
- int request, int *eof, void *data);
-static int drm_vm_info(char *buf, char **start, off_t offset,
- int request, int *eof, void *data);
-static int drm_clients_info(char *buf, char **start, off_t offset,
- int request, int *eof, void *data);
-static int drm_queues_info(char *buf, char **start, off_t offset,
- int request, int *eof, void *data);
-static int drm_bufs_info(char *buf, char **start, off_t offset,
- int request, int *eof, void *data);
+static int drm_name_info(char *buf, char **start, off_t offset,
+ int request, int *eof, void *data);
+static int drm_vm_info(char *buf, char **start, off_t offset,
+ int request, int *eof, void *data);
+static int drm_clients_info(char *buf, char **start, off_t offset,
+ int request, int *eof, void *data);
+static int drm_queues_info(char *buf, char **start, off_t offset,
+ int request, int *eof, void *data);
+static int drm_bufs_info(char *buf, char **start, off_t offset,
+ int request, int *eof, void *data);
#if DRM_DEBUG_CODE
-static int drm_vma_info(char *buf, char **start, off_t offset,
- int request, int *eof, void *data);
+static int drm_vma_info(char *buf, char **start, off_t offset,
+ int request, int *eof, void *data);
#endif
/**
@@ -59,18 +59,21 @@ static int drm_vma_info(char *buf, char **start, off_t offset,
*/
static struct drm_proc_list {
const char *name; /**< file name */
- int (*f)(char *, char **, off_t, int, int *, void *); /**< proc callback*/
+ int (*f) (char *, char **, off_t, int, int *, void *); /**< proc callback*/
} drm_proc_list[] = {
- { "name", drm_name_info },
- { "mem", drm_mem_info },
- { "vm", drm_vm_info },
- { "clients", drm_clients_info },
- { "queues", drm_queues_info },
- { "bufs", drm_bufs_info },
+ {
+ "name", drm_name_info}, {
+ "mem", drm_mem_info}, {
+ "vm", drm_vm_info}, {
+ "clients", drm_clients_info}, {
+ "queues", drm_queues_info}, {
+ "bufs", drm_bufs_info},
#if DRM_DEBUG_CODE
- { "vma", drm_vma_info },
+ {
+ "vma", drm_vma_info},
#endif
};
+
#define DRM_PROC_ENTRIES (sizeof(drm_proc_list)/sizeof(drm_proc_list[0]))
/**
@@ -81,18 +84,17 @@ static struct drm_proc_list {
* \param root DRI proc dir entry.
* \param dev_root resulting DRI device proc dir entry.
* \return root entry pointer on success, or NULL on failure.
- *
+ *
* Create the DRI proc root entry "/proc/dri", the device proc root entry
* "/proc/dri/%minor%/", and each entry in proc_list as
* "/proc/dri/%minor%/%name%".
*/
-int drm_proc_init(drm_device_t *dev, int minor,
- struct proc_dir_entry *root,
- struct proc_dir_entry **dev_root)
+int drm_proc_init(drm_device_t * dev, int minor,
+ struct proc_dir_entry *root, struct proc_dir_entry **dev_root)
{
struct proc_dir_entry *ent;
- int i, j;
- char name[64];
+ int i, j;
+ char name[64];
sprintf(name, "%d", minor);
*dev_root = proc_mkdir(name, root);
@@ -103,7 +105,7 @@ int drm_proc_init(drm_device_t *dev, int minor,
for (i = 0; i < DRM_PROC_ENTRIES; i++) {
ent = create_proc_entry(drm_proc_list[i].name,
- S_IFREG|S_IRUGO, *dev_root);
+ S_IFREG | S_IRUGO, *dev_root);
if (!ent) {
DRM_ERROR("Cannot create /proc/dri/%s/%s\n",
name, drm_proc_list[i].name);
@@ -114,13 +116,12 @@ int drm_proc_init(drm_device_t *dev, int minor,
return -1;
}
ent->read_proc = drm_proc_list[i].f;
- ent->data = dev;
+ ent->data = dev;
}
return 0;
}
-
/**
* Cleanup the proc filesystem resources.
*
@@ -132,12 +133,13 @@ int drm_proc_init(drm_device_t *dev, int minor,
* Remove all proc entries created by proc_init().
*/
int drm_proc_cleanup(int minor, struct proc_dir_entry *root,
- struct proc_dir_entry *dev_root)
+ struct proc_dir_entry *dev_root)
{
- int i;
+ int i;
char name[64];
- if (!root || !dev_root) return 0;
+ if (!root || !dev_root)
+ return 0;
for (i = 0; i < DRM_PROC_ENTRIES; i++)
remove_proc_entry(drm_proc_list[i].name, dev_root);
@@ -149,7 +151,7 @@ int drm_proc_cleanup(int minor, struct proc_dir_entry *root,
/**
* Called when "/proc/dri/.../name" is read.
- *
+ *
* \param buf output buffer.
* \param start start of output data.
* \param offset requested start offset.
@@ -157,14 +159,14 @@ int drm_proc_cleanup(int minor, struct proc_dir_entry *root,
* \param eof whether there is no more data to return.
* \param data private data.
* \return number of written bytes.
- *
+ *
* Prints the device name together with the bus id if available.
*/
static int drm_name_info(char *buf, char **start, off_t offset, int request,
- int *eof, void *data)
+ int *eof, void *data)
{
- drm_device_t *dev = (drm_device_t *)data;
- int len = 0;
+ drm_device_t *dev = (drm_device_t *) data;
+ int len = 0;
if (offset > DRM_PROC_LIMIT) {
*eof = 1;
@@ -172,23 +174,26 @@ static int drm_name_info(char *buf, char **start, off_t offset, int request,
}
*start = &buf[offset];
- *eof = 0;
+ *eof = 0;
if (dev->unique) {
DRM_PROC_PRINT("%s %s %s\n",
- dev->driver->pci_driver.name, pci_name(dev->pdev), dev->unique);
+ dev->driver->pci_driver.name,
+ pci_name(dev->pdev), dev->unique);
} else {
- DRM_PROC_PRINT("%s %s\n", dev->driver->pci_driver.name, pci_name(dev->pdev));
+ DRM_PROC_PRINT("%s %s\n", dev->driver->pci_driver.name,
+ pci_name(dev->pdev));
}
- if (len > request + offset) return request;
+ if (len > request + offset)
+ return request;
*eof = 1;
return len - offset;
}
/**
* Called when "/proc/dri/.../vm" is read.
- *
+ *
* \param buf output buffer.
* \param start start of output data.
* \param offset requested start offset.
@@ -196,24 +201,24 @@ static int drm_name_info(char *buf, char **start, off_t offset, int request,
* \param eof whether there is no more data to return.
* \param data private data.
* \return number of written bytes.
- *
+ *
* Prints information about all mappings in drm_device::maplist.
*/
static int drm__vm_info(char *buf, char **start, off_t offset, int request,
- int *eof, void *data)
+ int *eof, void *data)
{
- drm_device_t *dev = (drm_device_t *)data;
- int len = 0;
- drm_map_t *map;
+ drm_device_t *dev = (drm_device_t *) data;
+ int len = 0;
+ drm_map_t *map;
drm_map_list_t *r_list;
struct list_head *list;
- /* Hardcoded from _DRM_FRAME_BUFFER,
- _DRM_REGISTERS, _DRM_SHM, _DRM_AGP, and
- _DRM_SCATTER_GATHER and _DRM_CONSISTENT */
- const char *types[] = { "FB", "REG", "SHM", "AGP", "SG", "PCI" };
- const char *type;
- int i;
+ /* Hardcoded from _DRM_FRAME_BUFFER,
+ _DRM_REGISTERS, _DRM_SHM, _DRM_AGP, and
+ _DRM_SCATTER_GATHER and _DRM_CONSISTENT */
+ const char *types[] = { "FB", "REG", "SHM", "AGP", "SG", "PCI" };
+ const char *type;
+ int i;
if (offset > DRM_PROC_LIMIT) {
*eof = 1;
@@ -221,36 +226,35 @@ static int drm__vm_info(char *buf, char **start, off_t offset, int request,
}
*start = &buf[offset];
- *eof = 0;
+ *eof = 0;
DRM_PROC_PRINT("slot offset size type flags "
"address mtrr\n\n");
i = 0;
- if (dev->maplist != NULL) list_for_each(list, &dev->maplist->head) {
+ if (dev->maplist != NULL)
+ list_for_each(list, &dev->maplist->head) {
r_list = list_entry(list, drm_map_list_t, head);
map = r_list->map;
- if(!map)
+ if (!map)
continue;
if (map->type < 0 || map->type > 5)
type = "??";
- else
+ else
type = types[map->type];
DRM_PROC_PRINT("%4d 0x%08lx 0x%08lx %4.4s 0x%02x 0x%08x ",
i,
map->offset,
- map->size,
- type,
- map->flags,
- r_list->user_token);
+ map->size, type, map->flags, r_list->user_token);
if (map->mtrr < 0) {
DRM_PROC_PRINT("none\n");
} else {
DRM_PROC_PRINT("%4d\n", map->mtrr);
}
i++;
- }
+ }
- if (len > request + offset) return request;
+ if (len > request + offset)
+ return request;
*eof = 1;
return len - offset;
}
@@ -259,10 +263,10 @@ static int drm__vm_info(char *buf, char **start, off_t offset, int request,
* Simply calls _vm_info() while holding the drm_device::struct_sem lock.
*/
static int drm_vm_info(char *buf, char **start, off_t offset, int request,
- int *eof, void *data)
+ int *eof, void *data)
{
- drm_device_t *dev = (drm_device_t *)data;
- int ret;
+ drm_device_t *dev = (drm_device_t *) data;
+ int ret;
down(&dev->struct_sem);
ret = drm__vm_info(buf, start, offset, request, eof, data);
@@ -272,7 +276,7 @@ static int drm_vm_info(char *buf, char **start, off_t offset, int request,
/**
* Called when "/proc/dri/.../queues" is read.
- *
+ *
* \param buf output buffer.
* \param start start of output data.
* \param offset requested start offset.
@@ -282,12 +286,12 @@ static int drm_vm_info(char *buf, char **start, off_t offset, int request,
* \return number of written bytes.
*/
static int drm__queues_info(char *buf, char **start, off_t offset,
- int request, int *eof, void *data)
+ int request, int *eof, void *data)
{
- drm_device_t *dev = (drm_device_t *)data;
- int len = 0;
- int i;
- drm_queue_t *q;
+ drm_device_t *dev = (drm_device_t *) data;
+ int len = 0;
+ int i;
+ drm_queue_t *q;
if (offset > DRM_PROC_LIMIT) {
*eof = 1;
@@ -295,7 +299,7 @@ static int drm__queues_info(char *buf, char **start, off_t offset,
}
*start = &buf[offset];
- *eof = 0;
+ *eof = 0;
DRM_PROC_PRINT(" ctx/flags use fin"
" blk/rw/rwf wait flushed queued"
@@ -313,14 +317,17 @@ static int drm__queues_info(char *buf, char **start, off_t offset,
atomic_read(&q->block_count),
atomic_read(&q->block_read) ? 'r' : '-',
atomic_read(&q->block_write) ? 'w' : '-',
- waitqueue_active(&q->read_queue) ? 'r':'-',
- waitqueue_active(&q->write_queue) ? 'w':'-',
- waitqueue_active(&q->flush_queue) ? 'f':'-',
+ waitqueue_active(&q->read_queue) ? 'r' : '-',
+ waitqueue_active(&q->
+ write_queue) ? 'w' : '-',
+ waitqueue_active(&q->
+ flush_queue) ? 'f' : '-',
DRM_BUFCOUNT(&q->waitlist));
atomic_dec(&q->use_count);
}
- if (len > request + offset) return request;
+ if (len > request + offset)
+ return request;
*eof = 1;
return len - offset;
}
@@ -329,10 +336,10 @@ static int drm__queues_info(char *buf, char **start, off_t offset,
* Simply calls _queues_info() while holding the drm_device::struct_sem lock.
*/
static int drm_queues_info(char *buf, char **start, off_t offset, int request,
- int *eof, void *data)
+ int *eof, void *data)
{
- drm_device_t *dev = (drm_device_t *)data;
- int ret;
+ drm_device_t *dev = (drm_device_t *) data;
+ int ret;
down(&dev->struct_sem);
ret = drm__queues_info(buf, start, offset, request, eof, data);
@@ -342,7 +349,7 @@ static int drm_queues_info(char *buf, char **start, off_t offset, int request,
/**
* Called when "/proc/dri/.../bufs" is read.
- *
+ *
* \param buf output buffer.
* \param start start of output data.
* \param offset requested start offset.
@@ -352,12 +359,12 @@ static int drm_queues_info(char *buf, char **start, off_t offset, int request,
* \return number of written bytes.
*/
static int drm__bufs_info(char *buf, char **start, off_t offset, int request,
- int *eof, void *data)
+ int *eof, void *data)
{
- drm_device_t *dev = (drm_device_t *)data;
- int len = 0;
+ drm_device_t *dev = (drm_device_t *) data;
+ int len = 0;
drm_device_dma_t *dma = dev->dma;
- int i;
+ int i;
if (!dma || offset > DRM_PROC_LIMIT) {
*eof = 1;
@@ -365,7 +372,7 @@ static int drm__bufs_info(char *buf, char **start, off_t offset, int request,
}
*start = &buf[offset];
- *eof = 0;
+ *eof = 0;
DRM_PROC_PRINT(" o size count free segs pages kB\n\n");
for (i = 0; i <= DRM_MAX_ORDER; i++) {
@@ -378,19 +385,21 @@ static int drm__bufs_info(char *buf, char **start, off_t offset, int request,
.freelist.count),
dma->bufs[i].seg_count,
dma->bufs[i].seg_count
- *(1 << dma->bufs[i].page_order),
+ * (1 << dma->bufs[i].page_order),
(dma->bufs[i].seg_count
* (1 << dma->bufs[i].page_order))
* PAGE_SIZE / 1024);
}
DRM_PROC_PRINT("\n");
for (i = 0; i < dma->buf_count; i++) {
- if (i && !(i%32)) DRM_PROC_PRINT("\n");
+ if (i && !(i % 32))
+ DRM_PROC_PRINT("\n");
DRM_PROC_PRINT(" %d", dma->buflist[i]->list);
}
DRM_PROC_PRINT("\n");
- if (len > request + offset) return request;
+ if (len > request + offset)
+ return request;
*eof = 1;
return len - offset;
}
@@ -399,10 +408,10 @@ static int drm__bufs_info(char *buf, char **start, off_t offset, int request,
* Simply calls _bufs_info() while holding the drm_device::struct_sem lock.
*/
static int drm_bufs_info(char *buf, char **start, off_t offset, int request,
- int *eof, void *data)
+ int *eof, void *data)
{
- drm_device_t *dev = (drm_device_t *)data;
- int ret;
+ drm_device_t *dev = (drm_device_t *) data;
+ int ret;
down(&dev->struct_sem);
ret = drm__bufs_info(buf, start, offset, request, eof, data);
@@ -412,7 +421,7 @@ static int drm_bufs_info(char *buf, char **start, off_t offset, int request,
/**
* Called when "/proc/dri/.../clients" is read.
- *
+ *
* \param buf output buffer.
* \param start start of output data.
* \param offset requested start offset.
@@ -422,11 +431,11 @@ static int drm_bufs_info(char *buf, char **start, off_t offset, int request,
* \return number of written bytes.
*/
static int drm__clients_info(char *buf, char **start, off_t offset,
- int request, int *eof, void *data)
+ int request, int *eof, void *data)
{
- drm_device_t *dev = (drm_device_t *)data;
- int len = 0;
- drm_file_t *priv;
+ drm_device_t *dev = (drm_device_t *) data;
+ int len = 0;
+ drm_file_t *priv;
if (offset > DRM_PROC_LIMIT) {
*eof = 1;
@@ -434,7 +443,7 @@ static int drm__clients_info(char *buf, char **start, off_t offset,
}
*start = &buf[offset];
- *eof = 0;
+ *eof = 0;
DRM_PROC_PRINT("a dev pid uid magic ioctls\n\n");
for (priv = dev->file_first; priv; priv = priv->next) {
@@ -442,12 +451,11 @@ static int drm__clients_info(char *buf, char **start, off_t offset,
priv->authenticated ? 'y' : 'n',
priv->minor,
priv->pid,
- priv->uid,
- priv->magic,
- priv->ioctl_count);
+ priv->uid, priv->magic, priv->ioctl_count);
}
- if (len > request + offset) return request;
+ if (len > request + offset)
+ return request;
*eof = 1;
return len - offset;
}
@@ -456,10 +464,10 @@ static int drm__clients_info(char *buf, char **start, off_t offset,
* Simply calls _clients_info() while holding the drm_device::struct_sem lock.
*/
static int drm_clients_info(char *buf, char **start, off_t offset,
- int request, int *eof, void *data)
+ int request, int *eof, void *data)
{
- drm_device_t *dev = (drm_device_t *)data;
- int ret;
+ drm_device_t *dev = (drm_device_t *) data;
+ int ret;
down(&dev->struct_sem);
ret = drm__clients_info(buf, start, offset, request, eof, data);
@@ -470,14 +478,14 @@ static int drm_clients_info(char *buf, char **start, off_t offset,
#if DRM_DEBUG_CODE
static int drm__vma_info(char *buf, char **start, off_t offset, int request,
- int *eof, void *data)
+ int *eof, void *data)
{
- drm_device_t *dev = (drm_device_t *)data;
- int len = 0;
- drm_vma_entry_t *pt;
+ drm_device_t *dev = (drm_device_t *) data;
+ int len = 0;
+ drm_vma_entry_t *pt;
struct vm_area_struct *vma;
#if defined(__i386__)
- unsigned int pgprot;
+ unsigned int pgprot;
#endif
if (offset > DRM_PROC_LIMIT) {
@@ -486,51 +494,53 @@ static int drm__vma_info(char *buf, char **start, off_t offset, int request,
}
*start = &buf[offset];
- *eof = 0;
+ *eof = 0;
DRM_PROC_PRINT("vma use count: %d, high_memory = %p, 0x%08lx\n",
atomic_read(&dev->vma_count),
high_memory, virt_to_phys(high_memory));
for (pt = dev->vmalist; pt; pt = pt->next) {
- if (!(vma = pt->vma)) continue;
+ if (!(vma = pt->vma))
+ continue;
DRM_PROC_PRINT("\n%5d 0x%08lx-0x%08lx %c%c%c%c%c%c 0x%08lx",
pt->pid,
vma->vm_start,
vma->vm_end,
- vma->vm_flags & VM_READ ? 'r' : '-',
- vma->vm_flags & VM_WRITE ? 'w' : '-',
- vma->vm_flags & VM_EXEC ? 'x' : '-',
+ vma->vm_flags & VM_READ ? 'r' : '-',
+ vma->vm_flags & VM_WRITE ? 'w' : '-',
+ vma->vm_flags & VM_EXEC ? 'x' : '-',
vma->vm_flags & VM_MAYSHARE ? 's' : 'p',
- vma->vm_flags & VM_LOCKED ? 'l' : '-',
- vma->vm_flags & VM_IO ? 'i' : '-',
+ vma->vm_flags & VM_LOCKED ? 'l' : '-',
+ vma->vm_flags & VM_IO ? 'i' : '-',
VM_OFFSET(vma));
#if defined(__i386__)
pgprot = pgprot_val(vma->vm_page_prot);
DRM_PROC_PRINT(" %c%c%c%c%c%c%c%c%c",
- pgprot & _PAGE_PRESENT ? 'p' : '-',
- pgprot & _PAGE_RW ? 'w' : 'r',
- pgprot & _PAGE_USER ? 'u' : 's',
- pgprot & _PAGE_PWT ? 't' : 'b',
- pgprot & _PAGE_PCD ? 'u' : 'c',
+ pgprot & _PAGE_PRESENT ? 'p' : '-',
+ pgprot & _PAGE_RW ? 'w' : 'r',
+ pgprot & _PAGE_USER ? 'u' : 's',
+ pgprot & _PAGE_PWT ? 't' : 'b',
+ pgprot & _PAGE_PCD ? 'u' : 'c',
pgprot & _PAGE_ACCESSED ? 'a' : '-',
- pgprot & _PAGE_DIRTY ? 'd' : '-',
- pgprot & _PAGE_PSE ? 'm' : 'k',
- pgprot & _PAGE_GLOBAL ? 'g' : 'l' );
+ pgprot & _PAGE_DIRTY ? 'd' : '-',
+ pgprot & _PAGE_PSE ? 'm' : 'k',
+ pgprot & _PAGE_GLOBAL ? 'g' : 'l');
#endif
DRM_PROC_PRINT("\n");
}
- if (len > request + offset) return request;
+ if (len > request + offset)
+ return request;
*eof = 1;
return len - offset;
}
static int drm_vma_info(char *buf, char **start, off_t offset, int request,
- int *eof, void *data)
+ int *eof, void *data)
{
- drm_device_t *dev = (drm_device_t *)data;
- int ret;
+ drm_device_t *dev = (drm_device_t *) data;
+ int ret;
down(&dev->struct_sem);
ret = drm__vma_info(buf, start, offset, request, eof, data);
@@ -538,5 +548,3 @@ static int drm_vma_info(char *buf, char **start, off_t offset, int request,
return ret;
}
#endif
-
-
diff --git a/drivers/char/drm/drm_sarea.h b/drivers/char/drm/drm_sarea.h
index de782ed2f03a..e94297b751b8 100644
--- a/drivers/char/drm/drm_sarea.h
+++ b/drivers/char/drm/drm_sarea.h
@@ -1,5 +1,5 @@
/**
- * \file drm_sarea.h
+ * \file drm_sarea.h
* \brief SAREA definitions
*
* \author Michel Dänzer <michel@daenzer.net>
@@ -38,7 +38,7 @@
#if defined(__alpha__)
#define SAREA_MAX 0x2000
#elif defined(__ia64__)
-#define SAREA_MAX 0x10000 /* 64kB */
+#define SAREA_MAX 0x10000 /* 64kB */
#else
/* Intel 830M driver needs at least 8k SAREA */
#define SAREA_MAX 0x2000
@@ -51,28 +51,28 @@
/** SAREA drawable */
typedef struct drm_sarea_drawable {
- unsigned int stamp;
- unsigned int flags;
+ unsigned int stamp;
+ unsigned int flags;
} drm_sarea_drawable_t;
/** SAREA frame */
typedef struct drm_sarea_frame {
- unsigned int x;
- unsigned int y;
- unsigned int width;
- unsigned int height;
- unsigned int fullscreen;
+ unsigned int x;
+ unsigned int y;
+ unsigned int width;
+ unsigned int height;
+ unsigned int fullscreen;
} drm_sarea_frame_t;
/** SAREA */
typedef struct drm_sarea {
/** first thing is always the DRM locking structure */
- drm_hw_lock_t lock;
+ drm_hw_lock_t lock;
/** \todo Use readers/writer lock for drm_sarea::drawable_lock */
- drm_hw_lock_t drawable_lock;
- drm_sarea_drawable_t drawableTable[SAREA_MAX_DRAWABLES]; /**< drawables */
- drm_sarea_frame_t frame; /**< frame */
- drm_context_t dummy_context;
+ drm_hw_lock_t drawable_lock;
+ drm_sarea_drawable_t drawableTable[SAREA_MAX_DRAWABLES]; /**< drawables */
+ drm_sarea_frame_t frame; /**< frame */
+ drm_context_t dummy_context;
} drm_sarea_t;
-#endif /* _DRM_SAREA_H_ */
+#endif /* _DRM_SAREA_H_ */
diff --git a/drivers/char/drm/drm_scatter.c b/drivers/char/drm/drm_scatter.c
index ed267d49bc6a..ce81bf248200 100644
--- a/drivers/char/drm/drm_scatter.c
+++ b/drivers/char/drm/drm_scatter.c
@@ -1,5 +1,5 @@
/**
- * \file drm_scatter.h
+ * \file drm_scatter.c
* IOCTLs to manage scatter/gather memory
*
* \author Gareth Hughes <gareth@valinux.com>
@@ -37,28 +37,24 @@
#define DEBUG_SCATTER 0
-void drm_sg_cleanup( drm_sg_mem_t *entry )
+void drm_sg_cleanup(drm_sg_mem_t * entry)
{
struct page *page;
int i;
- for ( i = 0 ; i < entry->pages ; i++ ) {
+ for (i = 0; i < entry->pages; i++) {
page = entry->pagelist[i];
- if ( page )
- ClearPageReserved( page );
+ if (page)
+ ClearPageReserved(page);
}
- vfree( entry->virtual );
-
- drm_free( entry->busaddr,
- entry->pages * sizeof(*entry->busaddr),
- DRM_MEM_PAGES );
- drm_free( entry->pagelist,
- entry->pages * sizeof(*entry->pagelist),
- DRM_MEM_PAGES );
- drm_free( entry,
- sizeof(*entry),
- DRM_MEM_SGLISTS );
+ vfree(entry->virtual);
+
+ drm_free(entry->busaddr,
+ entry->pages * sizeof(*entry->busaddr), DRM_MEM_PAGES);
+ drm_free(entry->pagelist,
+ entry->pages * sizeof(*entry->pagelist), DRM_MEM_PAGES);
+ drm_free(entry, sizeof(*entry), DRM_MEM_SGLISTS);
}
#ifdef _LP64
@@ -67,8 +63,8 @@ void drm_sg_cleanup( drm_sg_mem_t *entry )
# define ScatterHandle(x) (unsigned int)(x)
#endif
-int drm_sg_alloc( struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg )
+int drm_sg_alloc(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg)
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->head->dev;
@@ -77,75 +73,70 @@ int drm_sg_alloc( struct inode *inode, struct file *filp,
drm_sg_mem_t *entry;
unsigned long pages, i, j;
- DRM_DEBUG( "%s\n", __FUNCTION__ );
+ DRM_DEBUG("%s\n", __FUNCTION__);
if (!drm_core_check_feature(dev, DRIVER_SG))
return -EINVAL;
- if ( dev->sg )
+ if (dev->sg)
return -EINVAL;
- if ( copy_from_user( &request, argp, sizeof(request) ) )
+ if (copy_from_user(&request, argp, sizeof(request)))
return -EFAULT;
- entry = drm_alloc( sizeof(*entry), DRM_MEM_SGLISTS );
- if ( !entry )
+ entry = drm_alloc(sizeof(*entry), DRM_MEM_SGLISTS);
+ if (!entry)
return -ENOMEM;
- memset( entry, 0, sizeof(*entry) );
+ memset(entry, 0, sizeof(*entry));
pages = (request.size + PAGE_SIZE - 1) / PAGE_SIZE;
- DRM_DEBUG( "sg size=%ld pages=%ld\n", request.size, pages );
+ DRM_DEBUG("sg size=%ld pages=%ld\n", request.size, pages);
entry->pages = pages;
- entry->pagelist = drm_alloc( pages * sizeof(*entry->pagelist),
- DRM_MEM_PAGES );
- if ( !entry->pagelist ) {
- drm_free( entry, sizeof(*entry), DRM_MEM_SGLISTS );
+ entry->pagelist = drm_alloc(pages * sizeof(*entry->pagelist),
+ DRM_MEM_PAGES);
+ if (!entry->pagelist) {
+ drm_free(entry, sizeof(*entry), DRM_MEM_SGLISTS);
return -ENOMEM;
}
memset(entry->pagelist, 0, pages * sizeof(*entry->pagelist));
- entry->busaddr = drm_alloc( pages * sizeof(*entry->busaddr),
- DRM_MEM_PAGES );
- if ( !entry->busaddr ) {
- drm_free( entry->pagelist,
- entry->pages * sizeof(*entry->pagelist),
- DRM_MEM_PAGES );
- drm_free( entry,
- sizeof(*entry),
- DRM_MEM_SGLISTS );
+ entry->busaddr = drm_alloc(pages * sizeof(*entry->busaddr),
+ DRM_MEM_PAGES);
+ if (!entry->busaddr) {
+ drm_free(entry->pagelist,
+ entry->pages * sizeof(*entry->pagelist),
+ DRM_MEM_PAGES);
+ drm_free(entry, sizeof(*entry), DRM_MEM_SGLISTS);
return -ENOMEM;
}
- memset( (void *)entry->busaddr, 0, pages * sizeof(*entry->busaddr) );
-
- entry->virtual = vmalloc_32( pages << PAGE_SHIFT );
- if ( !entry->virtual ) {
- drm_free( entry->busaddr,
- entry->pages * sizeof(*entry->busaddr),
- DRM_MEM_PAGES );
- drm_free( entry->pagelist,
- entry->pages * sizeof(*entry->pagelist),
- DRM_MEM_PAGES );
- drm_free( entry,
- sizeof(*entry),
- DRM_MEM_SGLISTS );
+ memset((void *)entry->busaddr, 0, pages * sizeof(*entry->busaddr));
+
+ entry->virtual = vmalloc_32(pages << PAGE_SHIFT);
+ if (!entry->virtual) {
+ drm_free(entry->busaddr,
+ entry->pages * sizeof(*entry->busaddr), DRM_MEM_PAGES);
+ drm_free(entry->pagelist,
+ entry->pages * sizeof(*entry->pagelist),
+ DRM_MEM_PAGES);
+ drm_free(entry, sizeof(*entry), DRM_MEM_SGLISTS);
return -ENOMEM;
}
/* This also forces the mapping of COW pages, so our page list
* will be valid. Please don't remove it...
*/
- memset( entry->virtual, 0, pages << PAGE_SHIFT );
+ memset(entry->virtual, 0, pages << PAGE_SHIFT);
entry->handle = ScatterHandle((unsigned long)entry->virtual);
- DRM_DEBUG( "sg alloc handle = %08lx\n", entry->handle );
- DRM_DEBUG( "sg alloc virtual = %p\n", entry->virtual );
+ DRM_DEBUG("sg alloc handle = %08lx\n", entry->handle);
+ DRM_DEBUG("sg alloc virtual = %p\n", entry->virtual);
- for (i = (unsigned long)entry->virtual, j = 0; j < pages;
- i += PAGE_SIZE, j++) {
+ for (i = (unsigned long)entry->virtual, j = 0; j < pages;
+ i += PAGE_SIZE, j++) {
entry->pagelist[j] = vmalloc_to_page((void *)i);
if (!entry->pagelist[j])
goto failed;
@@ -154,8 +145,8 @@ int drm_sg_alloc( struct inode *inode, struct file *filp,
request.handle = entry->handle;
- if ( copy_to_user( argp, &request, sizeof(request) ) ) {
- drm_sg_cleanup( entry );
+ if (copy_to_user(argp, &request, sizeof(request))) {
+ drm_sg_cleanup(entry);
return -EFAULT;
}
@@ -166,50 +157,50 @@ int drm_sg_alloc( struct inode *inode, struct file *filp,
* versa.
*/
{
- int error = 0;
+ int error = 0;
- for ( i = 0 ; i < pages ; i++ ) {
- unsigned long *tmp;
+ for (i = 0; i < pages; i++) {
+ unsigned long *tmp;
- tmp = page_address( entry->pagelist[i] );
- for ( j = 0 ;
- j < PAGE_SIZE / sizeof(unsigned long) ;
- j++, tmp++ ) {
- *tmp = 0xcafebabe;
- }
- tmp = (unsigned long *)((u8 *)entry->virtual +
- (PAGE_SIZE * i));
- for( j = 0 ;
- j < PAGE_SIZE / sizeof(unsigned long) ;
- j++, tmp++ ) {
- if ( *tmp != 0xcafebabe && error == 0 ) {
- error = 1;
- DRM_ERROR( "Scatter allocation error, "
- "pagelist does not match "
- "virtual mapping\n" );
+ tmp = page_address(entry->pagelist[i]);
+ for (j = 0;
+ j < PAGE_SIZE / sizeof(unsigned long);
+ j++, tmp++) {
+ *tmp = 0xcafebabe;
+ }
+ tmp = (unsigned long *)((u8 *) entry->virtual +
+ (PAGE_SIZE * i));
+ for (j = 0;
+ j < PAGE_SIZE / sizeof(unsigned long);
+ j++, tmp++) {
+ if (*tmp != 0xcafebabe && error == 0) {
+ error = 1;
+ DRM_ERROR("Scatter allocation error, "
+ "pagelist does not match "
+ "virtual mapping\n");
+ }
+ }
+ tmp = page_address(entry->pagelist[i]);
+ for (j = 0;
+ j < PAGE_SIZE / sizeof(unsigned long);
+ j++, tmp++) {
+ *tmp = 0;
}
}
- tmp = page_address( entry->pagelist[i] );
- for(j = 0 ;
- j < PAGE_SIZE / sizeof(unsigned long) ;
- j++, tmp++) {
- *tmp = 0;
- }
- }
- if (error == 0)
- DRM_ERROR( "Scatter allocation matches pagelist\n" );
+ if (error == 0)
+ DRM_ERROR("Scatter allocation matches pagelist\n");
}
#endif
return 0;
- failed:
- drm_sg_cleanup( entry );
+ failed:
+ drm_sg_cleanup(entry);
return -ENOMEM;
}
-int drm_sg_free( struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg )
+int drm_sg_free(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg)
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->head->dev;
@@ -219,20 +210,20 @@ int drm_sg_free( struct inode *inode, struct file *filp,
if (!drm_core_check_feature(dev, DRIVER_SG))
return -EINVAL;
- if ( copy_from_user( &request,
- (drm_scatter_gather_t __user *)arg,
- sizeof(request) ) )
+ if (copy_from_user(&request,
+ (drm_scatter_gather_t __user *) arg,
+ sizeof(request)))
return -EFAULT;
entry = dev->sg;
dev->sg = NULL;
- if ( !entry || entry->handle != request.handle )
+ if (!entry || entry->handle != request.handle)
return -EINVAL;
- DRM_DEBUG( "sg free virtual = %p\n", entry->virtual );
+ DRM_DEBUG("sg free virtual = %p\n", entry->virtual);
- drm_sg_cleanup( entry );
+ drm_sg_cleanup(entry);
return 0;
}
diff --git a/drivers/char/drm/drm_stub.c b/drivers/char/drm/drm_stub.c
index 70458cb061c6..60b6f8e8bf69 100644
--- a/drivers/char/drm/drm_stub.c
+++ b/drivers/char/drm/drm_stub.c
@@ -37,11 +37,11 @@
#include "drm_core.h"
unsigned int drm_cards_limit = 16; /* Enough for one machine */
-unsigned int drm_debug = 0; /* 1 to enable debug output */
+unsigned int drm_debug = 0; /* 1 to enable debug output */
EXPORT_SYMBOL(drm_debug);
-MODULE_AUTHOR( CORE_AUTHOR );
-MODULE_DESCRIPTION( CORE_DESC );
+MODULE_AUTHOR(CORE_AUTHOR);
+MODULE_DESCRIPTION(CORE_DESC);
MODULE_LICENSE("GPL and additional rights");
MODULE_PARM_DESC(cards_limit, "Maximum number of graphics cards");
MODULE_PARM_DESC(debug, "Enable debug output");
@@ -53,19 +53,21 @@ drm_head_t **drm_heads;
struct drm_sysfs_class *drm_class;
struct proc_dir_entry *drm_proc_root;
-static int drm_fill_in_dev(drm_device_t *dev, struct pci_dev *pdev, const struct pci_device_id *ent, struct drm_driver *driver)
+static int drm_fill_in_dev(drm_device_t * dev, struct pci_dev *pdev,
+ const struct pci_device_id *ent,
+ struct drm_driver *driver)
{
int retcode;
spin_lock_init(&dev->count_lock);
- init_timer( &dev->timer );
- sema_init( &dev->struct_sem, 1 );
- sema_init( &dev->ctxlist_sem, 1 );
+ init_timer(&dev->timer);
+ sema_init(&dev->struct_sem, 1);
+ sema_init(&dev->ctxlist_sem, 1);
- dev->pdev = pdev;
+ dev->pdev = pdev;
#ifdef __alpha__
- dev->hose = pdev->sysdata;
+ dev->hose = pdev->sysdata;
dev->pci_domain = dev->hose->bus->number;
#else
dev->pci_domain = 0;
@@ -82,15 +84,15 @@ static int drm_fill_in_dev(drm_device_t *dev, struct pci_dev *pdev, const struct
/* the DRM has 6 basic counters */
dev->counters = 6;
- dev->types[0] = _DRM_STAT_LOCK;
- dev->types[1] = _DRM_STAT_OPENS;
- dev->types[2] = _DRM_STAT_CLOSES;
- dev->types[3] = _DRM_STAT_IOCTLS;
- dev->types[4] = _DRM_STAT_LOCKS;
- dev->types[5] = _DRM_STAT_UNLOCKS;
+ dev->types[0] = _DRM_STAT_LOCK;
+ dev->types[1] = _DRM_STAT_OPENS;
+ dev->types[2] = _DRM_STAT_CLOSES;
+ dev->types[3] = _DRM_STAT_IOCTLS;
+ dev->types[4] = _DRM_STAT_LOCKS;
+ dev->types[5] = _DRM_STAT_UNLOCKS;
dev->driver = driver;
-
+
if (dev->driver->preinit)
if ((retcode = dev->driver->preinit(dev, ent->driver_data)))
goto error_out_unreg;
@@ -98,29 +100,30 @@ static int drm_fill_in_dev(drm_device_t *dev, struct pci_dev *pdev, const struct
if (drm_core_has_AGP(dev)) {
if (drm_device_is_agp(dev))
dev->agp = drm_agp_init(dev);
- if (drm_core_check_feature(dev, DRIVER_REQUIRE_AGP) && (dev->agp == NULL)) {
- DRM_ERROR( "Cannot initialize the agpgart module.\n" );
+ if (drm_core_check_feature(dev, DRIVER_REQUIRE_AGP)
+ && (dev->agp == NULL)) {
+ DRM_ERROR("Cannot initialize the agpgart module.\n");
retcode = -EINVAL;
goto error_out_unreg;
}
if (drm_core_has_MTRR(dev)) {
if (dev->agp)
- dev->agp->agp_mtrr = mtrr_add( dev->agp->agp_info.aper_base,
- dev->agp->agp_info.aper_size*1024*1024,
- MTRR_TYPE_WRCOMB,
- 1 );
+ dev->agp->agp_mtrr =
+ mtrr_add(dev->agp->agp_info.aper_base,
+ dev->agp->agp_info.aper_size *
+ 1024 * 1024, MTRR_TYPE_WRCOMB, 1);
}
}
- retcode = drm_ctxbitmap_init( dev );
- if( retcode ) {
- DRM_ERROR( "Cannot allocate memory for context bitmap.\n" );
+ retcode = drm_ctxbitmap_init(dev);
+ if (retcode) {
+ DRM_ERROR("Cannot allocate memory for context bitmap.\n");
goto error_out_unreg;
}
return 0;
-
-error_out_unreg:
+
+ error_out_unreg:
drm_takedown(dev);
return retcode;
}
@@ -140,7 +143,7 @@ int drm_stub_open(struct inode *inode, struct file *filp)
int minor = iminor(inode);
int err = -ENODEV;
struct file_operations *old_fops;
-
+
DRM_DEBUG("\n");
if (!((minor >= 0) && (minor < drm_cards_limit)))
@@ -148,7 +151,7 @@ int drm_stub_open(struct inode *inode, struct file *filp)
if (!drm_heads[minor])
return -ENODEV;
-
+
if (!(dev = drm_heads[minor]->dev))
return -ENODEV;
@@ -174,7 +177,7 @@ int drm_stub_open(struct inode *inode, struct file *filp)
* create the proc init entry via proc_init(). This routines assigns
* minor numbers to secondary heads of multi-headed cards
*/
-static int drm_get_head(drm_device_t *dev, drm_head_t *head)
+static int drm_get_head(drm_device_t * dev, drm_head_t * head)
{
drm_head_t **heads = drm_heads;
int ret;
@@ -184,26 +187,27 @@ static int drm_get_head(drm_device_t *dev, drm_head_t *head)
for (minor = 0; minor < drm_cards_limit; minor++, heads++) {
if (!*heads) {
-
+
*head = (drm_head_t) {
- .dev = dev,
- .device = MKDEV(DRM_MAJOR, minor),
- .minor = minor,
- };
-
- if ((ret = drm_proc_init(dev, minor, drm_proc_root, &head->dev_root))) {
- printk (KERN_ERR "DRM: Failed to initialize /proc/dri.\n");
+ .dev = dev,.device =
+ MKDEV(DRM_MAJOR, minor),.minor = minor,};
+
+ if ((ret =
+ drm_proc_init(dev, minor, drm_proc_root,
+ &head->dev_root))) {
+ printk(KERN_ERR
+ "DRM: Failed to initialize /proc/dri.\n");
goto err_g1;
}
-
head->dev_class = drm_sysfs_device_add(drm_class,
MKDEV(DRM_MAJOR,
minor),
&dev->pdev->dev,
"card%d", minor);
if (IS_ERR(head->dev_class)) {
- printk(KERN_ERR "DRM: Error sysfs_device_add.\n");
+ printk(KERN_ERR
+ "DRM: Error sysfs_device_add.\n");
ret = PTR_ERR(head->dev_class);
goto err_g2;
}
@@ -215,13 +219,14 @@ static int drm_get_head(drm_device_t *dev, drm_head_t *head)
}
DRM_ERROR("out of minors\n");
return -ENOMEM;
-err_g2:
+ err_g2:
drm_proc_cleanup(minor, drm_proc_root, head->dev_root);
-err_g1:
- *head = (drm_head_t) {.dev = NULL};
+ err_g1:
+ *head = (drm_head_t) {
+ .dev = NULL};
return ret;
}
-
+
/**
* Register.
*
@@ -234,7 +239,7 @@ err_g1:
* Try and register, if we fail to register, backout previous work.
*/
int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent,
- struct drm_driver *driver)
+ struct drm_driver *driver)
{
drm_device_t *dev;
int ret;
@@ -261,10 +266,11 @@ int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent,
return 0;
-err_g1:
+ err_g1:
drm_free(dev, sizeof(*dev), DRM_MEM_STUB);
return ret;
}
+
EXPORT_SYMBOL(drm_get_dev);
/**
@@ -305,19 +311,19 @@ int drm_put_dev(drm_device_t * dev)
* last minor released.
*
*/
-int drm_put_head(drm_head_t *head)
+int drm_put_head(drm_head_t * head)
{
int minor = head->minor;
-
+
DRM_DEBUG("release secondary minor %d\n", minor);
-
+
drm_proc_cleanup(minor, drm_proc_root, head->dev_root);
drm_sysfs_device_remove(MKDEV(DRM_MAJOR, head->minor));
-
- *head = (drm_head_t){.dev = NULL};
+
+ *head = (drm_head_t) {
+ .dev = NULL};
drm_heads[minor] = NULL;
-
+
return 0;
}
-
diff --git a/drivers/char/drm/drm_sysfs.c b/drivers/char/drm/drm_sysfs.c
index 475cc5e555e1..6d3449761914 100644
--- a/drivers/char/drm/drm_sysfs.c
+++ b/drivers/char/drm/drm_sysfs.c
@@ -15,6 +15,8 @@
#include <linux/device.h>
#include <linux/kdev_t.h>
#include <linux/err.h>
+#include <linux/slab.h>
+#include <linux/string.h>
#include "drm_core.h"
#include "drmP.h"
diff --git a/drivers/char/drm/drm_vm.c b/drivers/char/drm/drm_vm.c
index 39ea96e42c5b..3f73aa774c80 100644
--- a/drivers/char/drm/drm_vm.c
+++ b/drivers/char/drm/drm_vm.c
@@ -1,7 +1,7 @@
/**
- * \file drm_vm.h
+ * \file drm_vm.c
* Memory mapping for DRM
- *
+ *
* \author Rickard E. (Rik) Faith <faith@valinux.com>
* \author Gareth Hughes <gareth@valinux.com>
*/
@@ -47,32 +47,34 @@ static void drm_vm_close(struct vm_area_struct *vma);
* \param vma virtual memory area.
* \param address access address.
* \return pointer to the page structure.
- *
+ *
* Find the right map and if it's AGP memory find the real physical page to
* map, get the page, increment the use count and return it.
*/
#if __OS_HAS_AGP
static __inline__ struct page *drm_do_vm_nopage(struct vm_area_struct *vma,
- unsigned long address)
+ unsigned long address)
{
- drm_file_t *priv = vma->vm_file->private_data;
+ drm_file_t *priv = vma->vm_file->private_data;
drm_device_t *dev = priv->head->dev;
- drm_map_t *map = NULL;
- drm_map_list_t *r_list;
+ drm_map_t *map = NULL;
+ drm_map_list_t *r_list;
struct list_head *list;
/*
- * Find the right map
- */
+ * Find the right map
+ */
if (!drm_core_has_AGP(dev))
goto vm_nopage_error;
- if(!dev->agp || !dev->agp->cant_use_aperture) goto vm_nopage_error;
+ if (!dev->agp || !dev->agp->cant_use_aperture)
+ goto vm_nopage_error;
list_for_each(list, &dev->maplist->head) {
r_list = list_entry(list, drm_map_list_t, head);
map = r_list->map;
- if (!map) continue;
+ if (!map)
+ continue;
if (r_list->user_token == VM_OFFSET(vma))
break;
}
@@ -85,45 +87,47 @@ static __inline__ struct page *drm_do_vm_nopage(struct vm_area_struct *vma,
#ifdef __alpha__
/*
- * Adjust to a bus-relative address
- */
+ * Adjust to a bus-relative address
+ */
baddr -= dev->hose->mem_space->start;
#endif
/*
- * It's AGP memory - find the real physical page to map
- */
- for(agpmem = dev->agp->memory; agpmem; agpmem = agpmem->next) {
+ * It's AGP memory - find the real physical page to map
+ */
+ for (agpmem = dev->agp->memory; agpmem; agpmem = agpmem->next) {
if (agpmem->bound <= baddr &&
- agpmem->bound + agpmem->pages * PAGE_SIZE > baddr)
+ agpmem->bound + agpmem->pages * PAGE_SIZE > baddr)
break;
}
- if (!agpmem) goto vm_nopage_error;
+ if (!agpmem)
+ goto vm_nopage_error;
/*
- * Get the page, inc the use count, and return it
- */
+ * Get the page, inc the use count, and return it
+ */
offset = (baddr - agpmem->bound) >> PAGE_SHIFT;
page = virt_to_page(__va(agpmem->memory->memory[offset]));
get_page(page);
- DRM_DEBUG("baddr = 0x%lx page = 0x%p, offset = 0x%lx, count=%d\n",
- baddr, __va(agpmem->memory->memory[offset]), offset,
- page_count(page));
+ DRM_DEBUG
+ ("baddr = 0x%lx page = 0x%p, offset = 0x%lx, count=%d\n",
+ baddr, __va(agpmem->memory->memory[offset]), offset,
+ page_count(page));
return page;
- }
-vm_nopage_error:
- return NOPAGE_SIGBUS; /* Disallow mremap */
+ }
+ vm_nopage_error:
+ return NOPAGE_SIGBUS; /* Disallow mremap */
}
-#else /* __OS_HAS_AGP */
+#else /* __OS_HAS_AGP */
static __inline__ struct page *drm_do_vm_nopage(struct vm_area_struct *vma,
- unsigned long address)
+ unsigned long address)
{
return NOPAGE_SIGBUS;
}
-#endif /* __OS_HAS_AGP */
+#endif /* __OS_HAS_AGP */
/**
* \c nopage method for shared virtual memory.
@@ -131,22 +135,24 @@ static __inline__ struct page *drm_do_vm_nopage(struct vm_area_struct *vma,
* \param vma virtual memory area.
* \param address access address.
* \return pointer to the page structure.
- *
+ *
* Get the the mapping, find the real physical page to map, get the page, and
* return it.
*/
static __inline__ struct page *drm_do_vm_shm_nopage(struct vm_area_struct *vma,
- unsigned long address)
+ unsigned long address)
{
- drm_map_t *map = (drm_map_t *)vma->vm_private_data;
- unsigned long offset;
- unsigned long i;
- struct page *page;
+ drm_map_t *map = (drm_map_t *) vma->vm_private_data;
+ unsigned long offset;
+ unsigned long i;
+ struct page *page;
- if (address > vma->vm_end) return NOPAGE_SIGBUS; /* Disallow mremap */
- if (!map) return NOPAGE_OOM; /* Nothing allocated */
+ if (address > vma->vm_end)
+ return NOPAGE_SIGBUS; /* Disallow mremap */
+ if (!map)
+ return NOPAGE_OOM; /* Nothing allocated */
- offset = address - vma->vm_start;
+ offset = address - vma->vm_start;
i = (unsigned long)map->handle + offset;
page = (map->type == _DRM_CONSISTENT) ?
virt_to_page((void *)i) : vmalloc_to_page((void *)i);
@@ -158,19 +164,18 @@ static __inline__ struct page *drm_do_vm_shm_nopage(struct vm_area_struct *vma,
return page;
}
-
/**
* \c close method for shared virtual memory.
- *
+ *
* \param vma virtual memory area.
- *
+ *
* Deletes map information if we are the last
* person to close a mapping and it's not in the global maplist.
*/
static void drm_vm_shm_close(struct vm_area_struct *vma)
{
- drm_file_t *priv = vma->vm_file->private_data;
- drm_device_t *dev = priv->head->dev;
+ drm_file_t *priv = vma->vm_file->private_data;
+ drm_device_t *dev = priv->head->dev;
drm_vma_entry_t *pt, *prev, *next;
drm_map_t *map;
drm_map_list_t *r_list;
@@ -186,7 +191,8 @@ static void drm_vm_shm_close(struct vm_area_struct *vma)
down(&dev->struct_sem);
for (pt = dev->vmalist, prev = NULL; pt; pt = next) {
next = pt->next;
- if (pt->vma->vm_private_data == map) found_maps++;
+ if (pt->vma->vm_private_data == map)
+ found_maps++;
if (pt->vma == vma) {
if (prev) {
prev->next = pt->next;
@@ -199,8 +205,7 @@ static void drm_vm_shm_close(struct vm_area_struct *vma)
}
}
/* We were the only map that was found */
- if(found_maps == 1 &&
- map->flags & _DRM_REMOVABLE) {
+ if (found_maps == 1 && map->flags & _DRM_REMOVABLE) {
/* Check to see if we are in the maplist, if we are not, then
* we delete this mappings information.
*/
@@ -208,10 +213,11 @@ static void drm_vm_shm_close(struct vm_area_struct *vma)
list = &dev->maplist->head;
list_for_each(list, &dev->maplist->head) {
r_list = list_entry(list, drm_map_list_t, head);
- if (r_list->map == map) found_maps++;
+ if (r_list->map == map)
+ found_maps++;
}
- if(!found_maps) {
+ if (!found_maps) {
drm_dma_handle_t dmah;
switch (map->type) {
@@ -251,27 +257,29 @@ static void drm_vm_shm_close(struct vm_area_struct *vma)
* \param vma virtual memory area.
* \param address access address.
* \return pointer to the page structure.
- *
+ *
* Determine the page number from the page offset and get it from drm_device_dma::pagelist.
*/
static __inline__ struct page *drm_do_vm_dma_nopage(struct vm_area_struct *vma,
- unsigned long address)
+ unsigned long address)
{
- drm_file_t *priv = vma->vm_file->private_data;
- drm_device_t *dev = priv->head->dev;
- drm_device_dma_t *dma = dev->dma;
- unsigned long offset;
- unsigned long page_nr;
- struct page *page;
-
- if (!dma) return NOPAGE_SIGBUS; /* Error */
- if (address > vma->vm_end) return NOPAGE_SIGBUS; /* Disallow mremap */
- if (!dma->pagelist) return NOPAGE_OOM ; /* Nothing allocated */
-
- offset = address - vma->vm_start; /* vm_[pg]off[set] should be 0 */
- page_nr = offset >> PAGE_SHIFT;
- page = virt_to_page((dma->pagelist[page_nr] +
- (offset & (~PAGE_MASK))));
+ drm_file_t *priv = vma->vm_file->private_data;
+ drm_device_t *dev = priv->head->dev;
+ drm_device_dma_t *dma = dev->dma;
+ unsigned long offset;
+ unsigned long page_nr;
+ struct page *page;
+
+ if (!dma)
+ return NOPAGE_SIGBUS; /* Error */
+ if (address > vma->vm_end)
+ return NOPAGE_SIGBUS; /* Disallow mremap */
+ if (!dma->pagelist)
+ return NOPAGE_OOM; /* Nothing allocated */
+
+ offset = address - vma->vm_start; /* vm_[pg]off[set] should be 0 */
+ page_nr = offset >> PAGE_SHIFT;
+ page = virt_to_page((dma->pagelist[page_nr] + (offset & (~PAGE_MASK))));
get_page(page);
@@ -285,13 +293,13 @@ static __inline__ struct page *drm_do_vm_dma_nopage(struct vm_area_struct *vma,
* \param vma virtual memory area.
* \param address access address.
* \return pointer to the page structure.
- *
+ *
* Determine the map offset from the page offset and get it from drm_sg_mem::pagelist.
*/
static __inline__ struct page *drm_do_vm_sg_nopage(struct vm_area_struct *vma,
- unsigned long address)
+ unsigned long address)
{
- drm_map_t *map = (drm_map_t *)vma->vm_private_data;
+ drm_map_t *map = (drm_map_t *) vma->vm_private_data;
drm_file_t *priv = vma->vm_file->private_data;
drm_device_t *dev = priv->head->dev;
drm_sg_mem_t *entry = dev->sg;
@@ -300,10 +308,12 @@ static __inline__ struct page *drm_do_vm_sg_nopage(struct vm_area_struct *vma,
unsigned long page_offset;
struct page *page;
- if (!entry) return NOPAGE_SIGBUS; /* Error */
- if (address > vma->vm_end) return NOPAGE_SIGBUS; /* Disallow mremap */
- if (!entry->pagelist) return NOPAGE_OOM ; /* Nothing allocated */
-
+ if (!entry)
+ return NOPAGE_SIGBUS; /* Error */
+ if (address > vma->vm_end)
+ return NOPAGE_SIGBUS; /* Disallow mremap */
+ if (!entry->pagelist)
+ return NOPAGE_OOM; /* Nothing allocated */
offset = address - vma->vm_start;
map_offset = map->offset - (unsigned long)dev->sg->virtual;
@@ -314,76 +324,78 @@ static __inline__ struct page *drm_do_vm_sg_nopage(struct vm_area_struct *vma,
return page;
}
-
static struct page *drm_vm_nopage(struct vm_area_struct *vma,
- unsigned long address,
- int *type) {
- if (type) *type = VM_FAULT_MINOR;
+ unsigned long address, int *type)
+{
+ if (type)
+ *type = VM_FAULT_MINOR;
return drm_do_vm_nopage(vma, address);
}
static struct page *drm_vm_shm_nopage(struct vm_area_struct *vma,
- unsigned long address,
- int *type) {
- if (type) *type = VM_FAULT_MINOR;
+ unsigned long address, int *type)
+{
+ if (type)
+ *type = VM_FAULT_MINOR;
return drm_do_vm_shm_nopage(vma, address);
}
static struct page *drm_vm_dma_nopage(struct vm_area_struct *vma,
- unsigned long address,
- int *type) {
- if (type) *type = VM_FAULT_MINOR;
+ unsigned long address, int *type)
+{
+ if (type)
+ *type = VM_FAULT_MINOR;
return drm_do_vm_dma_nopage(vma, address);
}
static struct page *drm_vm_sg_nopage(struct vm_area_struct *vma,
- unsigned long address,
- int *type) {
- if (type) *type = VM_FAULT_MINOR;
+ unsigned long address, int *type)
+{
+ if (type)
+ *type = VM_FAULT_MINOR;
return drm_do_vm_sg_nopage(vma, address);
}
/** AGP virtual memory operations */
-static struct vm_operations_struct drm_vm_ops = {
+static struct vm_operations_struct drm_vm_ops = {
.nopage = drm_vm_nopage,
- .open = drm_vm_open,
- .close = drm_vm_close,
+ .open = drm_vm_open,
+ .close = drm_vm_close,
};
/** Shared virtual memory operations */
-static struct vm_operations_struct drm_vm_shm_ops = {
+static struct vm_operations_struct drm_vm_shm_ops = {
.nopage = drm_vm_shm_nopage,
- .open = drm_vm_open,
- .close = drm_vm_shm_close,
+ .open = drm_vm_open,
+ .close = drm_vm_shm_close,
};
/** DMA virtual memory operations */
-static struct vm_operations_struct drm_vm_dma_ops = {
+static struct vm_operations_struct drm_vm_dma_ops = {
.nopage = drm_vm_dma_nopage,
- .open = drm_vm_open,
- .close = drm_vm_close,
+ .open = drm_vm_open,
+ .close = drm_vm_close,
};
/** Scatter-gather virtual memory operations */
-static struct vm_operations_struct drm_vm_sg_ops = {
+static struct vm_operations_struct drm_vm_sg_ops = {
.nopage = drm_vm_sg_nopage,
- .open = drm_vm_open,
- .close = drm_vm_close,
+ .open = drm_vm_open,
+ .close = drm_vm_close,
};
-
/**
* \c open method for shared virtual memory.
- *
+ *
* \param vma virtual memory area.
- *
+ *
* Create a new drm_vma_entry structure as the \p vma private data entry and
* add it to drm_device::vmalist.
*/
static void drm_vm_open(struct vm_area_struct *vma)
{
- drm_file_t *priv = vma->vm_file->private_data;
- drm_device_t *dev = priv->head->dev;
+ drm_file_t *priv = vma->vm_file->private_data;
+ drm_device_t *dev = priv->head->dev;
drm_vma_entry_t *vma_entry;
DRM_DEBUG("0x%08lx,0x%08lx\n",
@@ -393,26 +405,26 @@ static void drm_vm_open(struct vm_area_struct *vma)
vma_entry = drm_alloc(sizeof(*vma_entry), DRM_MEM_VMAS);
if (vma_entry) {
down(&dev->struct_sem);
- vma_entry->vma = vma;
+ vma_entry->vma = vma;
vma_entry->next = dev->vmalist;
- vma_entry->pid = current->pid;
- dev->vmalist = vma_entry;
+ vma_entry->pid = current->pid;
+ dev->vmalist = vma_entry;
up(&dev->struct_sem);
}
}
/**
* \c close method for all virtual memory types.
- *
+ *
* \param vma virtual memory area.
- *
+ *
* Search the \p vma private data entry in drm_device::vmalist, unlink it, and
* free it.
*/
static void drm_vm_close(struct vm_area_struct *vma)
{
- drm_file_t *priv = vma->vm_file->private_data;
- drm_device_t *dev = priv->head->dev;
+ drm_file_t *priv = vma->vm_file->private_data;
+ drm_device_t *dev = priv->head->dev;
drm_vma_entry_t *pt, *prev;
DRM_DEBUG("0x%08lx,0x%08lx\n",
@@ -440,43 +452,44 @@ static void drm_vm_close(struct vm_area_struct *vma)
* \param filp file pointer.
* \param vma virtual memory area.
* \return zero on success or a negative number on failure.
- *
+ *
* Sets the virtual memory area operations structure to vm_dma_ops, the file
* pointer, and calls vm_open().
*/
static int drm_mmap_dma(struct file *filp, struct vm_area_struct *vma)
{
- drm_file_t *priv = filp->private_data;
- drm_device_t *dev;
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev;
drm_device_dma_t *dma;
- unsigned long length = vma->vm_end - vma->vm_start;
+ unsigned long length = vma->vm_end - vma->vm_start;
lock_kernel();
- dev = priv->head->dev;
- dma = dev->dma;
+ dev = priv->head->dev;
+ dma = dev->dma;
DRM_DEBUG("start = 0x%lx, end = 0x%lx, offset = 0x%lx\n",
vma->vm_start, vma->vm_end, VM_OFFSET(vma));
- /* Length must match exact page count */
+ /* Length must match exact page count */
if (!dma || (length >> PAGE_SHIFT) != dma->page_count) {
unlock_kernel();
return -EINVAL;
}
unlock_kernel();
- vma->vm_ops = &drm_vm_dma_ops;
+ vma->vm_ops = &drm_vm_dma_ops;
- vma->vm_flags |= VM_RESERVED; /* Don't swap */
+ vma->vm_flags |= VM_RESERVED; /* Don't swap */
- vma->vm_file = filp; /* Needed for drm_vm_open() */
+ vma->vm_file = filp; /* Needed for drm_vm_open() */
drm_vm_open(vma);
return 0;
}
-unsigned long drm_core_get_map_ofs(drm_map_t *map)
+unsigned long drm_core_get_map_ofs(drm_map_t * map)
{
return map->offset;
}
+
EXPORT_SYMBOL(drm_core_get_map_ofs);
unsigned long drm_core_get_reg_ofs(struct drm_device *dev)
@@ -487,6 +500,7 @@ unsigned long drm_core_get_reg_ofs(struct drm_device *dev)
return 0;
#endif
}
+
EXPORT_SYMBOL(drm_core_get_reg_ofs);
/**
@@ -495,7 +509,7 @@ EXPORT_SYMBOL(drm_core_get_reg_ofs);
* \param filp file pointer.
* \param vma virtual memory area.
* \return zero on success or a negative number on failure.
- *
+ *
* If the virtual memory area has no offset associated with it then it's a DMA
* area, so calls mmap_dma(). Otherwise searches the map in drm_device::maplist,
* checks that the restricted flag is not set, sets the virtual memory operations
@@ -504,17 +518,18 @@ EXPORT_SYMBOL(drm_core_get_reg_ofs);
*/
int drm_mmap(struct file *filp, struct vm_area_struct *vma)
{
- drm_file_t *priv = filp->private_data;
- drm_device_t *dev = priv->head->dev;
- drm_map_t *map = NULL;
- drm_map_list_t *r_list;
- unsigned long offset = 0;
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->head->dev;
+ drm_map_t *map = NULL;
+ drm_map_list_t *r_list;
+ unsigned long offset = 0;
struct list_head *list;
DRM_DEBUG("start = 0x%lx, end = 0x%lx, offset = 0x%lx\n",
vma->vm_start, vma->vm_end, VM_OFFSET(vma));
- if ( !priv->authenticated ) return -EACCES;
+ if (!priv->authenticated)
+ return -EACCES;
/* We check for "dma". On Apple's UniNorth, it's valid to have
* the AGP mapped at physical address 0
@@ -522,61 +537,66 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma)
*/
if (!VM_OFFSET(vma)
#if __OS_HAS_AGP
- && (!dev->agp || dev->agp->agp_info.device->vendor != PCI_VENDOR_ID_APPLE)
+ && (!dev->agp
+ || dev->agp->agp_info.device->vendor != PCI_VENDOR_ID_APPLE)
#endif
)
return drm_mmap_dma(filp, vma);
- /* A sequential search of a linked list is
- fine here because: 1) there will only be
- about 5-10 entries in the list and, 2) a
- DRI client only has to do this mapping
- once, so it doesn't have to be optimized
- for performance, even if the list was a
- bit longer. */
+ /* A sequential search of a linked list is
+ fine here because: 1) there will only be
+ about 5-10 entries in the list and, 2) a
+ DRI client only has to do this mapping
+ once, so it doesn't have to be optimized
+ for performance, even if the list was a
+ bit longer. */
list_for_each(list, &dev->maplist->head) {
r_list = list_entry(list, drm_map_list_t, head);
map = r_list->map;
- if (!map) continue;
+ if (!map)
+ continue;
if (r_list->user_token == VM_OFFSET(vma))
break;
}
- if (!map || ((map->flags&_DRM_RESTRICTED) && !capable(CAP_SYS_ADMIN)))
+ if (!map || ((map->flags & _DRM_RESTRICTED) && !capable(CAP_SYS_ADMIN)))
return -EPERM;
- /* Check for valid size. */
- if (map->size != vma->vm_end - vma->vm_start) return -EINVAL;
+ /* Check for valid size. */
+ if (map->size != vma->vm_end - vma->vm_start)
+ return -EINVAL;
if (!capable(CAP_SYS_ADMIN) && (map->flags & _DRM_READ_ONLY)) {
vma->vm_flags &= ~(VM_WRITE | VM_MAYWRITE);
#if defined(__i386__) || defined(__x86_64__)
pgprot_val(vma->vm_page_prot) &= ~_PAGE_RW;
#else
- /* Ye gads this is ugly. With more thought
- we could move this up higher and use
- `protection_map' instead. */
- vma->vm_page_prot = __pgprot(pte_val(pte_wrprotect(
- __pte(pgprot_val(vma->vm_page_prot)))));
+ /* Ye gads this is ugly. With more thought
+ we could move this up higher and use
+ `protection_map' instead. */
+ vma->vm_page_prot =
+ __pgprot(pte_val
+ (pte_wrprotect
+ (__pte(pgprot_val(vma->vm_page_prot)))));
#endif
}
switch (map->type) {
- case _DRM_AGP:
- if (drm_core_has_AGP(dev) && dev->agp->cant_use_aperture) {
- /*
- * On some platforms we can't talk to bus dma address from the CPU, so for
- * memory of type DRM_AGP, we'll deal with sorting out the real physical
- * pages and mappings in nopage()
- */
+ case _DRM_AGP:
+ if (drm_core_has_AGP(dev) && dev->agp->cant_use_aperture) {
+ /*
+ * On some platforms we can't talk to bus dma address from the CPU, so for
+ * memory of type DRM_AGP, we'll deal with sorting out the real physical
+ * pages and mappings in nopage()
+ */
#if defined(__powerpc__)
- pgprot_val(vma->vm_page_prot) |= _PAGE_NO_CACHE;
+ pgprot_val(vma->vm_page_prot) |= _PAGE_NO_CACHE;
#endif
- vma->vm_ops = &drm_vm_ops;
- break;
- }
- /* fall through to _DRM_FRAME_BUFFER... */
+ vma->vm_ops = &drm_vm_ops;
+ break;
+ }
+ /* fall through to _DRM_FRAME_BUFFER... */
case _DRM_FRAME_BUFFER:
case _DRM_REGISTERS:
#if defined(__i386__) || defined(__x86_64__)
@@ -591,27 +611,25 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma)
#endif
vma->vm_flags |= VM_IO; /* not in core dump */
#if defined(__ia64__)
- if (efi_range_is_wc(vma->vm_start, vma->vm_end -
- vma->vm_start))
+ if (efi_range_is_wc(vma->vm_start, vma->vm_end - vma->vm_start))
vma->vm_page_prot =
- pgprot_writecombine(vma->vm_page_prot);
+ pgprot_writecombine(vma->vm_page_prot);
else
- vma->vm_page_prot =
- pgprot_noncached(vma->vm_page_prot);
+ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
#endif
offset = dev->driver->get_reg_ofs(dev);
#ifdef __sparc__
if (io_remap_pfn_range(DRM_RPR_ARG(vma) vma->vm_start,
- (map->offset + offset) >> PAGE_SHIFT,
- vma->vm_end - vma->vm_start,
- vma->vm_page_prot))
+ (map->offset + offset) >> PAGE_SHIFT,
+ vma->vm_end - vma->vm_start,
+ vma->vm_page_prot))
#else
if (io_remap_pfn_range(vma, vma->vm_start,
- (map->offset + offset) >> PAGE_SHIFT,
- vma->vm_end - vma->vm_start,
- vma->vm_page_prot))
+ (map->offset + offset) >> PAGE_SHIFT,
+ vma->vm_end - vma->vm_start,
+ vma->vm_page_prot))
#endif
- return -EAGAIN;
+ return -EAGAIN;
DRM_DEBUG(" Type = %d; start = 0x%lx, end = 0x%lx,"
" offset = 0x%lx\n",
map->type,
@@ -624,22 +642,23 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma)
* allocate in a different way */
vma->vm_ops = &drm_vm_shm_ops;
vma->vm_private_data = (void *)map;
- /* Don't let this area swap. Change when
- DRM_KERNEL advisory is supported. */
+ /* Don't let this area swap. Change when
+ DRM_KERNEL advisory is supported. */
vma->vm_flags |= VM_RESERVED;
break;
case _DRM_SCATTER_GATHER:
vma->vm_ops = &drm_vm_sg_ops;
vma->vm_private_data = (void *)map;
vma->vm_flags |= VM_RESERVED;
- break;
+ break;
default:
return -EINVAL; /* This should never happen. */
}
- vma->vm_flags |= VM_RESERVED; /* Don't swap */
+ vma->vm_flags |= VM_RESERVED; /* Don't swap */
- vma->vm_file = filp; /* Needed for drm_vm_open() */
+ vma->vm_file = filp; /* Needed for drm_vm_open() */
drm_vm_open(vma);
return 0;
}
+
EXPORT_SYMBOL(drm_mmap);
diff --git a/drivers/char/drm/ffb_context.c b/drivers/char/drm/ffb_context.c
index f51812078010..1383727b443a 100644
--- a/drivers/char/drm/ffb_context.c
+++ b/drivers/char/drm/ffb_context.c
@@ -15,8 +15,7 @@
#include "ffb_drv.h"
-static int DRM(alloc_queue)(drm_device_t *dev, int is_2d_only)
-{
+static int DRM(alloc_queue) (drm_device_t * dev, int is_2d_only) {
ffb_dev_priv_t *fpriv = (ffb_dev_priv_t *) dev->dev_private;
int i;
@@ -37,7 +36,7 @@ static int DRM(alloc_queue)(drm_device_t *dev, int is_2d_only)
return i + 1;
}
-static void ffb_save_context(ffb_dev_priv_t *fpriv, int idx)
+static void ffb_save_context(ffb_dev_priv_t * fpriv, int idx)
{
ffb_fbcPtr ffb = fpriv->regs;
struct ffb_hw_context *ctx;
@@ -94,36 +93,36 @@ static void ffb_save_context(ffb_dev_priv_t *fpriv, int idx)
/* Capture rendering attributes. */
- ctx->ppc = upa_readl(&ffb->ppc); /* Pixel Processor Control */
- ctx->wid = upa_readl(&ffb->wid); /* Current WID */
- ctx->fg = upa_readl(&ffb->fg); /* Constant FG color */
- ctx->bg = upa_readl(&ffb->bg); /* Constant BG color */
- ctx->consty = upa_readl(&ffb->consty); /* Constant Y */
- ctx->constz = upa_readl(&ffb->constz); /* Constant Z */
- ctx->xclip = upa_readl(&ffb->xclip); /* X plane clip */
- ctx->dcss = upa_readl(&ffb->dcss); /* Depth Cue Scale Slope */
+ ctx->ppc = upa_readl(&ffb->ppc); /* Pixel Processor Control */
+ ctx->wid = upa_readl(&ffb->wid); /* Current WID */
+ ctx->fg = upa_readl(&ffb->fg); /* Constant FG color */
+ ctx->bg = upa_readl(&ffb->bg); /* Constant BG color */
+ ctx->consty = upa_readl(&ffb->consty); /* Constant Y */
+ ctx->constz = upa_readl(&ffb->constz); /* Constant Z */
+ ctx->xclip = upa_readl(&ffb->xclip); /* X plane clip */
+ ctx->dcss = upa_readl(&ffb->dcss); /* Depth Cue Scale Slope */
ctx->vclipmin = upa_readl(&ffb->vclipmin); /* Primary XY clip, minimum */
ctx->vclipmax = upa_readl(&ffb->vclipmax); /* Primary XY clip, maximum */
ctx->vclipzmin = upa_readl(&ffb->vclipzmin); /* Primary Z clip, minimum */
ctx->vclipzmax = upa_readl(&ffb->vclipzmax); /* Primary Z clip, maximum */
- ctx->dcsf = upa_readl(&ffb->dcsf); /* Depth Cue Scale Front Bound */
- ctx->dcsb = upa_readl(&ffb->dcsb); /* Depth Cue Scale Back Bound */
- ctx->dczf = upa_readl(&ffb->dczf); /* Depth Cue Scale Z Front */
- ctx->dczb = upa_readl(&ffb->dczb); /* Depth Cue Scale Z Back */
- ctx->blendc = upa_readl(&ffb->blendc); /* Alpha Blend Control */
+ ctx->dcsf = upa_readl(&ffb->dcsf); /* Depth Cue Scale Front Bound */
+ ctx->dcsb = upa_readl(&ffb->dcsb); /* Depth Cue Scale Back Bound */
+ ctx->dczf = upa_readl(&ffb->dczf); /* Depth Cue Scale Z Front */
+ ctx->dczb = upa_readl(&ffb->dczb); /* Depth Cue Scale Z Back */
+ ctx->blendc = upa_readl(&ffb->blendc); /* Alpha Blend Control */
ctx->blendc1 = upa_readl(&ffb->blendc1); /* Alpha Blend Color 1 */
ctx->blendc2 = upa_readl(&ffb->blendc2); /* Alpha Blend Color 2 */
- ctx->fbc = upa_readl(&ffb->fbc); /* Frame Buffer Control */
- ctx->rop = upa_readl(&ffb->rop); /* Raster Operation */
- ctx->cmp = upa_readl(&ffb->cmp); /* Compare Controls */
+ ctx->fbc = upa_readl(&ffb->fbc); /* Frame Buffer Control */
+ ctx->rop = upa_readl(&ffb->rop); /* Raster Operation */
+ ctx->cmp = upa_readl(&ffb->cmp); /* Compare Controls */
ctx->matchab = upa_readl(&ffb->matchab); /* Buffer A/B Match Ops */
- ctx->matchc = upa_readl(&ffb->matchc); /* Buffer C Match Ops */
- ctx->magnab = upa_readl(&ffb->magnab); /* Buffer A/B Magnitude Ops */
- ctx->magnc = upa_readl(&ffb->magnc); /* Buffer C Magnitude Ops */
- ctx->pmask = upa_readl(&ffb->pmask); /* RGB Plane Mask */
- ctx->xpmask = upa_readl(&ffb->xpmask); /* X Plane Mask */
- ctx->ypmask = upa_readl(&ffb->ypmask); /* Y Plane Mask */
- ctx->zpmask = upa_readl(&ffb->zpmask); /* Z Plane Mask */
+ ctx->matchc = upa_readl(&ffb->matchc); /* Buffer C Match Ops */
+ ctx->magnab = upa_readl(&ffb->magnab); /* Buffer A/B Magnitude Ops */
+ ctx->magnc = upa_readl(&ffb->magnc); /* Buffer C Magnitude Ops */
+ ctx->pmask = upa_readl(&ffb->pmask); /* RGB Plane Mask */
+ ctx->xpmask = upa_readl(&ffb->xpmask); /* X Plane Mask */
+ ctx->ypmask = upa_readl(&ffb->ypmask); /* Y Plane Mask */
+ ctx->zpmask = upa_readl(&ffb->zpmask); /* Z Plane Mask */
/* Auxiliary Clips. */
ctx->auxclip0min = upa_readl(&ffb->auxclip[0].min);
@@ -135,9 +134,9 @@ static void ffb_save_context(ffb_dev_priv_t *fpriv, int idx)
ctx->auxclip3min = upa_readl(&ffb->auxclip[3].min);
ctx->auxclip3max = upa_readl(&ffb->auxclip[3].max);
- ctx->lpat = upa_readl(&ffb->lpat); /* Line Pattern */
- ctx->fontxy = upa_readl(&ffb->fontxy); /* XY Font Coordinate */
- ctx->fontw = upa_readl(&ffb->fontw); /* Font Width */
+ ctx->lpat = upa_readl(&ffb->lpat); /* Line Pattern */
+ ctx->fontxy = upa_readl(&ffb->fontxy); /* XY Font Coordinate */
+ ctx->fontw = upa_readl(&ffb->fontw); /* Font Width */
ctx->fontinc = upa_readl(&ffb->fontinc); /* Font X/Y Increment */
/* These registers/features only exist on FFB2 and later chips. */
@@ -145,12 +144,12 @@ static void ffb_save_context(ffb_dev_priv_t *fpriv, int idx)
ctx->dcss1 = upa_readl(&ffb->dcss1); /* Depth Cue Scale Slope 1 */
ctx->dcss2 = upa_readl(&ffb->dcss2); /* Depth Cue Scale Slope 2 */
ctx->dcss2 = upa_readl(&ffb->dcss3); /* Depth Cue Scale Slope 3 */
- ctx->dcs2 = upa_readl(&ffb->dcs2); /* Depth Cue Scale 2 */
- ctx->dcs3 = upa_readl(&ffb->dcs3); /* Depth Cue Scale 3 */
- ctx->dcs4 = upa_readl(&ffb->dcs4); /* Depth Cue Scale 4 */
- ctx->dcd2 = upa_readl(&ffb->dcd2); /* Depth Cue Depth 2 */
- ctx->dcd3 = upa_readl(&ffb->dcd3); /* Depth Cue Depth 3 */
- ctx->dcd4 = upa_readl(&ffb->dcd4); /* Depth Cue Depth 4 */
+ ctx->dcs2 = upa_readl(&ffb->dcs2); /* Depth Cue Scale 2 */
+ ctx->dcs3 = upa_readl(&ffb->dcs3); /* Depth Cue Scale 3 */
+ ctx->dcs4 = upa_readl(&ffb->dcs4); /* Depth Cue Scale 4 */
+ ctx->dcd2 = upa_readl(&ffb->dcd2); /* Depth Cue Depth 2 */
+ ctx->dcd3 = upa_readl(&ffb->dcd3); /* Depth Cue Depth 3 */
+ ctx->dcd4 = upa_readl(&ffb->dcd4); /* Depth Cue Depth 4 */
/* And stencil/stencilctl only exists on FFB2+ and later
* due to the introduction of 3DRAM-III.
@@ -170,7 +169,7 @@ static void ffb_save_context(ffb_dev_priv_t *fpriv, int idx)
ctx->ucsr = upa_readl(&ffb->ucsr);
}
-static void ffb_restore_context(ffb_dev_priv_t *fpriv, int old, int idx)
+static void ffb_restore_context(ffb_dev_priv_t * fpriv, int old, int idx)
{
ffb_fbcPtr ffb = fpriv->regs;
struct ffb_hw_context *ctx;
@@ -193,7 +192,7 @@ static void ffb_restore_context(ffb_dev_priv_t *fpriv, int old, int idx)
upa_writel(ctx->ppc, &ffb->ppc);
upa_writel(ctx->wid, &ffb->wid);
- upa_writel(ctx->fg, &ffb->fg);
+ upa_writel(ctx->fg, &ffb->fg);
upa_writel(ctx->bg, &ffb->bg);
upa_writel(ctx->xclip, &ffb->xclip);
upa_writel(ctx->fbc, &ffb->fbc);
@@ -237,36 +236,36 @@ static void ffb_restore_context(ffb_dev_priv_t *fpriv, int old, int idx)
/* Restore rendering attributes. */
- upa_writel(ctx->ppc, &ffb->ppc); /* Pixel Processor Control */
- upa_writel(ctx->wid, &ffb->wid); /* Current WID */
- upa_writel(ctx->fg, &ffb->fg); /* Constant FG color */
- upa_writel(ctx->bg, &ffb->bg); /* Constant BG color */
- upa_writel(ctx->consty, &ffb->consty); /* Constant Y */
- upa_writel(ctx->constz, &ffb->constz); /* Constant Z */
- upa_writel(ctx->xclip, &ffb->xclip); /* X plane clip */
- upa_writel(ctx->dcss, &ffb->dcss); /* Depth Cue Scale Slope */
+ upa_writel(ctx->ppc, &ffb->ppc); /* Pixel Processor Control */
+ upa_writel(ctx->wid, &ffb->wid); /* Current WID */
+ upa_writel(ctx->fg, &ffb->fg); /* Constant FG color */
+ upa_writel(ctx->bg, &ffb->bg); /* Constant BG color */
+ upa_writel(ctx->consty, &ffb->consty); /* Constant Y */
+ upa_writel(ctx->constz, &ffb->constz); /* Constant Z */
+ upa_writel(ctx->xclip, &ffb->xclip); /* X plane clip */
+ upa_writel(ctx->dcss, &ffb->dcss); /* Depth Cue Scale Slope */
upa_writel(ctx->vclipmin, &ffb->vclipmin); /* Primary XY clip, minimum */
upa_writel(ctx->vclipmax, &ffb->vclipmax); /* Primary XY clip, maximum */
upa_writel(ctx->vclipzmin, &ffb->vclipzmin); /* Primary Z clip, minimum */
upa_writel(ctx->vclipzmax, &ffb->vclipzmax); /* Primary Z clip, maximum */
- upa_writel(ctx->dcsf, &ffb->dcsf); /* Depth Cue Scale Front Bound */
- upa_writel(ctx->dcsb, &ffb->dcsb); /* Depth Cue Scale Back Bound */
- upa_writel(ctx->dczf, &ffb->dczf); /* Depth Cue Scale Z Front */
- upa_writel(ctx->dczb, &ffb->dczb); /* Depth Cue Scale Z Back */
- upa_writel(ctx->blendc, &ffb->blendc); /* Alpha Blend Control */
+ upa_writel(ctx->dcsf, &ffb->dcsf); /* Depth Cue Scale Front Bound */
+ upa_writel(ctx->dcsb, &ffb->dcsb); /* Depth Cue Scale Back Bound */
+ upa_writel(ctx->dczf, &ffb->dczf); /* Depth Cue Scale Z Front */
+ upa_writel(ctx->dczb, &ffb->dczb); /* Depth Cue Scale Z Back */
+ upa_writel(ctx->blendc, &ffb->blendc); /* Alpha Blend Control */
upa_writel(ctx->blendc1, &ffb->blendc1); /* Alpha Blend Color 1 */
upa_writel(ctx->blendc2, &ffb->blendc2); /* Alpha Blend Color 2 */
- upa_writel(ctx->fbc, &ffb->fbc); /* Frame Buffer Control */
- upa_writel(ctx->rop, &ffb->rop); /* Raster Operation */
- upa_writel(ctx->cmp, &ffb->cmp); /* Compare Controls */
+ upa_writel(ctx->fbc, &ffb->fbc); /* Frame Buffer Control */
+ upa_writel(ctx->rop, &ffb->rop); /* Raster Operation */
+ upa_writel(ctx->cmp, &ffb->cmp); /* Compare Controls */
upa_writel(ctx->matchab, &ffb->matchab); /* Buffer A/B Match Ops */
- upa_writel(ctx->matchc, &ffb->matchc); /* Buffer C Match Ops */
- upa_writel(ctx->magnab, &ffb->magnab); /* Buffer A/B Magnitude Ops */
- upa_writel(ctx->magnc, &ffb->magnc); /* Buffer C Magnitude Ops */
- upa_writel(ctx->pmask, &ffb->pmask); /* RGB Plane Mask */
- upa_writel(ctx->xpmask, &ffb->xpmask); /* X Plane Mask */
- upa_writel(ctx->ypmask, &ffb->ypmask); /* Y Plane Mask */
- upa_writel(ctx->zpmask, &ffb->zpmask); /* Z Plane Mask */
+ upa_writel(ctx->matchc, &ffb->matchc); /* Buffer C Match Ops */
+ upa_writel(ctx->magnab, &ffb->magnab); /* Buffer A/B Magnitude Ops */
+ upa_writel(ctx->magnc, &ffb->magnc); /* Buffer C Magnitude Ops */
+ upa_writel(ctx->pmask, &ffb->pmask); /* RGB Plane Mask */
+ upa_writel(ctx->xpmask, &ffb->xpmask); /* X Plane Mask */
+ upa_writel(ctx->ypmask, &ffb->ypmask); /* Y Plane Mask */
+ upa_writel(ctx->zpmask, &ffb->zpmask); /* Z Plane Mask */
/* Auxiliary Clips. */
upa_writel(ctx->auxclip0min, &ffb->auxclip[0].min);
@@ -278,9 +277,9 @@ static void ffb_restore_context(ffb_dev_priv_t *fpriv, int old, int idx)
upa_writel(ctx->auxclip3min, &ffb->auxclip[3].min);
upa_writel(ctx->auxclip3max, &ffb->auxclip[3].max);
- upa_writel(ctx->lpat, &ffb->lpat); /* Line Pattern */
- upa_writel(ctx->fontxy, &ffb->fontxy); /* XY Font Coordinate */
- upa_writel(ctx->fontw, &ffb->fontw); /* Font Width */
+ upa_writel(ctx->lpat, &ffb->lpat); /* Line Pattern */
+ upa_writel(ctx->fontxy, &ffb->fontxy); /* XY Font Coordinate */
+ upa_writel(ctx->fontw, &ffb->fontw); /* Font Width */
upa_writel(ctx->fontinc, &ffb->fontinc); /* Font X/Y Increment */
/* These registers/features only exist on FFB2 and later chips. */
@@ -354,91 +353,87 @@ static void FFBWait(ffb_fbcPtr ffb)
} while (--limit);
}
-int ffb_driver_context_switch(drm_device_t *dev, int old, int new)
+int ffb_driver_context_switch(drm_device_t * dev, int old, int new)
{
ffb_dev_priv_t *fpriv = (ffb_dev_priv_t *) dev->dev_private;
#ifdef DRM_DMA_HISTOGRAM
- dev->ctx_start = get_cycles();
+ dev->ctx_start = get_cycles();
#endif
-
- DRM_DEBUG("Context switch from %d to %d\n", old, new);
- if (new == dev->last_context ||
- dev->last_context == 0) {
+ DRM_DEBUG("Context switch from %d to %d\n", old, new);
+
+ if (new == dev->last_context || dev->last_context == 0) {
dev->last_context = new;
- return 0;
+ return 0;
}
-
+
FFBWait(fpriv->regs);
ffb_save_context(fpriv, old);
ffb_restore_context(fpriv, old, new);
FFBWait(fpriv->regs);
-
+
dev->last_context = new;
- return 0;
+ return 0;
}
int ffb_driver_resctx(struct inode *inode, struct file *filp, unsigned int cmd,
- unsigned long arg)
+ unsigned long arg)
{
- drm_ctx_res_t res;
- drm_ctx_t ctx;
- int i;
+ drm_ctx_res_t res;
+ drm_ctx_t ctx;
+ int i;
DRM_DEBUG("%d\n", DRM_RESERVED_CONTEXTS);
- if (copy_from_user(&res, (drm_ctx_res_t __user *)arg, sizeof(res)))
+ if (copy_from_user(&res, (drm_ctx_res_t __user *) arg, sizeof(res)))
return -EFAULT;
if (res.count >= DRM_RESERVED_CONTEXTS) {
memset(&ctx, 0, sizeof(ctx));
for (i = 0; i < DRM_RESERVED_CONTEXTS; i++) {
ctx.handle = i;
- if (copy_to_user(&res.contexts[i],
- &i,
- sizeof(i)))
+ if (copy_to_user(&res.contexts[i], &i, sizeof(i)))
return -EFAULT;
}
}
res.count = DRM_RESERVED_CONTEXTS;
- if (copy_to_user((drm_ctx_res_t __user *)arg, &res, sizeof(res)))
+ if (copy_to_user((drm_ctx_res_t __user *) arg, &res, sizeof(res)))
return -EFAULT;
return 0;
}
-
int ffb_driver_addctx(struct inode *inode, struct file *filp, unsigned int cmd,
- unsigned long arg)
+ unsigned long arg)
{
- drm_file_t *priv = filp->private_data;
- drm_device_t *dev = priv->dev;
- drm_ctx_t ctx;
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->dev;
+ drm_ctx_t ctx;
int idx;
- if (copy_from_user(&ctx, (drm_ctx_t __user *)arg, sizeof(ctx)))
+ if (copy_from_user(&ctx, (drm_ctx_t __user *) arg, sizeof(ctx)))
return -EFAULT;
- idx = DRM(alloc_queue)(dev, (ctx.flags & _DRM_CONTEXT_2DONLY));
+ idx = DRM(alloc_queue) (dev, (ctx.flags & _DRM_CONTEXT_2DONLY));
if (idx < 0)
return -ENFILE;
DRM_DEBUG("%d\n", ctx.handle);
ctx.handle = idx;
- if (copy_to_user((drm_ctx_t __user *)arg, &ctx, sizeof(ctx)))
+ if (copy_to_user((drm_ctx_t __user *) arg, &ctx, sizeof(ctx)))
return -EFAULT;
return 0;
}
int ffb_driver_modctx(struct inode *inode, struct file *filp, unsigned int cmd,
- unsigned long arg)
+ unsigned long arg)
{
- drm_file_t *priv = filp->private_data;
- drm_device_t *dev = priv->dev;
- ffb_dev_priv_t *fpriv = (ffb_dev_priv_t *) dev->dev_private;
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->dev;
+ ffb_dev_priv_t *fpriv = (ffb_dev_priv_t *) dev->dev_private;
struct ffb_hw_context *hwctx;
drm_ctx_t ctx;
int idx;
- if (copy_from_user(&ctx, (drm_ctx_t __user *)arg, sizeof(ctx)))
+ if (copy_from_user(&ctx, (drm_ctx_t __user *) arg, sizeof(ctx)))
return -EFAULT;
idx = ctx.handle;
@@ -458,16 +453,16 @@ int ffb_driver_modctx(struct inode *inode, struct file *filp, unsigned int cmd,
}
int ffb_driver_getctx(struct inode *inode, struct file *filp, unsigned int cmd,
- unsigned long arg)
+ unsigned long arg)
{
- drm_file_t *priv = filp->private_data;
- drm_device_t *dev = priv->dev;
- ffb_dev_priv_t *fpriv = (ffb_dev_priv_t *) dev->dev_private;
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->dev;
+ ffb_dev_priv_t *fpriv = (ffb_dev_priv_t *) dev->dev_private;
struct ffb_hw_context *hwctx;
drm_ctx_t ctx;
int idx;
- if (copy_from_user(&ctx, (drm_ctx_t __user *)arg, sizeof(ctx)))
+ if (copy_from_user(&ctx, (drm_ctx_t __user *) arg, sizeof(ctx)))
return -EFAULT;
idx = ctx.handle;
@@ -483,31 +478,31 @@ int ffb_driver_getctx(struct inode *inode, struct file *filp, unsigned int cmd,
else
ctx.flags = 0;
- if (copy_to_user((drm_ctx_t __user *)arg, &ctx, sizeof(ctx)))
+ if (copy_to_user((drm_ctx_t __user *) arg, &ctx, sizeof(ctx)))
return -EFAULT;
return 0;
}
-int ffb_driver_switchctx(struct inode *inode, struct file *filp, unsigned int cmd,
- unsigned long arg)
+int ffb_driver_switchctx(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg)
{
- drm_file_t *priv = filp->private_data;
- drm_device_t *dev = priv->dev;
- drm_ctx_t ctx;
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->dev;
+ drm_ctx_t ctx;
- if (copy_from_user(&ctx, (drm_ctx_t __user *)arg, sizeof(ctx)))
+ if (copy_from_user(&ctx, (drm_ctx_t __user *) arg, sizeof(ctx)))
return -EFAULT;
DRM_DEBUG("%d\n", ctx.handle);
return ffb_driver_context_switch(dev, dev->last_context, ctx.handle);
}
int ffb_driver_newctx(struct inode *inode, struct file *filp, unsigned int cmd,
- unsigned long arg)
+ unsigned long arg)
{
- drm_ctx_t ctx;
+ drm_ctx_t ctx;
- if (copy_from_user(&ctx, (drm_ctx_t __user *)arg, sizeof(ctx)))
+ if (copy_from_user(&ctx, (drm_ctx_t __user *) arg, sizeof(ctx)))
return -EFAULT;
DRM_DEBUG("%d\n", ctx.handle);
@@ -515,15 +510,15 @@ int ffb_driver_newctx(struct inode *inode, struct file *filp, unsigned int cmd,
}
int ffb_driver_rmctx(struct inode *inode, struct file *filp, unsigned int cmd,
- unsigned long arg)
+ unsigned long arg)
{
- drm_ctx_t ctx;
- drm_file_t *priv = filp->private_data;
- drm_device_t *dev = priv->dev;
- ffb_dev_priv_t *fpriv = (ffb_dev_priv_t *) dev->dev_private;
+ drm_ctx_t ctx;
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->dev;
+ ffb_dev_priv_t *fpriv = (ffb_dev_priv_t *) dev->dev_private;
int idx;
- if (copy_from_user(&ctx, (drm_ctx_t __user *)arg, sizeof(ctx)))
+ if (copy_from_user(&ctx, (drm_ctx_t __user *) arg, sizeof(ctx)))
return -EFAULT;
DRM_DEBUG("%d\n", ctx.handle);
@@ -531,10 +526,8 @@ int ffb_driver_rmctx(struct inode *inode, struct file *filp, unsigned int cmd,
if (idx < 0 || idx >= FFB_MAX_CTXS)
return -EINVAL;
- if (fpriv->hw_state[idx] != NULL) {
- kfree(fpriv->hw_state[idx]);
- fpriv->hw_state[idx] = NULL;
- }
+ kfree(fpriv->hw_state[idx]);
+ fpriv->hw_state[idx] = NULL;
return 0;
}
@@ -544,7 +537,8 @@ void ffb_set_context_ioctls(void)
DRM(ioctls)[DRM_IOCTL_NR(DRM_IOCTL_RM_CTX)].func = ffb_driver_rmctx;
DRM(ioctls)[DRM_IOCTL_NR(DRM_IOCTL_MOD_CTX)].func = ffb_driver_modctx;
DRM(ioctls)[DRM_IOCTL_NR(DRM_IOCTL_GET_CTX)].func = ffb_driver_getctx;
- DRM(ioctls)[DRM_IOCTL_NR(DRM_IOCTL_SWITCH_CTX)].func = ffb_driver_switchctx;
+ DRM(ioctls)[DRM_IOCTL_NR(DRM_IOCTL_SWITCH_CTX)].func =
+ ffb_driver_switchctx;
DRM(ioctls)[DRM_IOCTL_NR(DRM_IOCTL_NEW_CTX)].func = ffb_driver_newctx;
DRM(ioctls)[DRM_IOCTL_NR(DRM_IOCTL_RES_CTX)].func = ffb_driver_resctx;
diff --git a/drivers/char/drm/ffb_drv.c b/drivers/char/drm/ffb_drv.c
index 1bd0d55ee0f0..c13f9abb41e9 100644
--- a/drivers/char/drm/ffb_drv.c
+++ b/drivers/char/drm/ffb_drv.c
@@ -33,13 +33,13 @@ typedef struct _ffb_position_t {
static ffb_position_t *ffb_position;
-static void get_ffb_type(ffb_dev_priv_t *ffb_priv, int instance)
+static void get_ffb_type(ffb_dev_priv_t * ffb_priv, int instance)
{
volatile unsigned char *strap_bits;
unsigned char val;
strap_bits = (volatile unsigned char *)
- (ffb_priv->card_phys_base + 0x00200000UL);
+ (ffb_priv->card_phys_base + 0x00200000UL);
/* Don't ask, you have to read the value twice for whatever
* reason to get correct contents.
@@ -61,7 +61,8 @@ static void get_ffb_type(ffb_dev_priv_t *ffb_priv, int instance)
break;
case (0x1 << 5) | (0x0 << 3):
ffb_priv->ffb_type = ffb2_prototype;
- printk("ffb%d: Detected FFB2/vertical pre-FCS prototype\n", instance);
+ printk("ffb%d: Detected FFB2/vertical pre-FCS prototype\n",
+ instance);
break;
case (0x1 << 5) | (0x1 << 3):
ffb_priv->ffb_type = ffb2_vertical;
@@ -81,12 +82,13 @@ static void get_ffb_type(ffb_dev_priv_t *ffb_priv, int instance)
break;
default:
ffb_priv->ffb_type = ffb2_vertical;
- printk("ffb%d: Unknown boardID[%08x], assuming FFB2\n", instance, val);
+ printk("ffb%d: Unknown boardID[%08x], assuming FFB2\n",
+ instance, val);
break;
};
}
-static void ffb_apply_upa_parent_ranges(int parent,
+static void ffb_apply_upa_parent_ranges(int parent,
struct linux_prom64_registers *regs)
{
struct linux_prom64_ranges ranges[PROMREG_MAX];
@@ -97,7 +99,8 @@ static void ffb_apply_upa_parent_ranges(int parent,
if (strcmp(name, "upa") != 0)
return;
- len = prom_getproperty(parent, "ranges", (void *) ranges, sizeof(ranges));
+ len =
+ prom_getproperty(parent, "ranges", (void *)ranges, sizeof(ranges));
if (len <= 0)
return;
@@ -117,11 +120,11 @@ static void ffb_apply_upa_parent_ranges(int parent,
return;
}
-static int ffb_init_one(drm_device_t *dev, int prom_node, int parent_node,
+static int ffb_init_one(drm_device_t * dev, int prom_node, int parent_node,
int instance)
{
- struct linux_prom64_registers regs[2*PROMREG_MAX];
- ffb_dev_priv_t *ffb_priv = (ffb_dev_priv_t *)dev->dev_private;
+ struct linux_prom64_registers regs[2 * PROMREG_MAX];
+ ffb_dev_priv_t *ffb_priv = (ffb_dev_priv_t *) dev->dev_private;
int i;
ffb_priv->prom_node = prom_node;
@@ -132,27 +135,27 @@ static int ffb_init_one(drm_device_t *dev, int prom_node, int parent_node,
ffb_apply_upa_parent_ranges(parent_node, &regs[0]);
ffb_priv->card_phys_base = regs[0].phys_addr;
ffb_priv->regs = (ffb_fbcPtr)
- (regs[0].phys_addr + 0x00600000UL);
+ (regs[0].phys_addr + 0x00600000UL);
get_ffb_type(ffb_priv, instance);
for (i = 0; i < FFB_MAX_CTXS; i++)
ffb_priv->hw_state[i] = NULL;
-
+
return 0;
}
static drm_map_t *ffb_find_map(struct file *filp, unsigned long off)
{
- drm_file_t *priv = filp->private_data;
- drm_device_t *dev;
- drm_map_list_t *r_list;
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev;
+ drm_map_list_t *r_list;
struct list_head *list;
- drm_map_t *map;
+ drm_map_t *map;
if (!priv || (dev = priv->dev) == NULL)
return NULL;
list_for_each(list, &dev->maplist->head) {
- r_list = (drm_map_list_t *)list;
+ r_list = (drm_map_list_t *) list;
map = r_list->map;
if (!map)
continue;
@@ -166,8 +169,7 @@ static drm_map_t *ffb_find_map(struct file *filp, unsigned long off)
unsigned long ffb_get_unmapped_area(struct file *filp,
unsigned long hint,
unsigned long len,
- unsigned long pgoff,
- unsigned long flags)
+ unsigned long pgoff, unsigned long flags)
{
drm_map_t *map = ffb_find_map(filp, pgoff << PAGE_SHIFT);
unsigned long addr = -ENOMEM;
@@ -175,8 +177,7 @@ unsigned long ffb_get_unmapped_area(struct file *filp,
if (!map)
return get_unmapped_area(NULL, hint, len, pgoff, flags);
- if (map->type == _DRM_FRAME_BUFFER ||
- map->type == _DRM_REGISTERS) {
+ if (map->type == _DRM_FRAME_BUFFER || map->type == _DRM_REGISTERS) {
#ifdef HAVE_ARCH_FB_UNMAPPED_AREA
addr = get_fb_unmapped_area(filp, hint, len, pgoff, flags);
#else
@@ -187,7 +188,7 @@ unsigned long ffb_get_unmapped_area(struct file *filp,
addr = get_unmapped_area(NULL, hint, len + slack, pgoff, flags);
if (!(addr & ~PAGE_MASK)) {
- unsigned long kvirt = (unsigned long) map->handle;
+ unsigned long kvirt = (unsigned long)map->handle;
if ((kvirt & (SHMLBA - 1)) != (addr & (SHMLBA - 1))) {
unsigned long koff, aoff;
@@ -207,9 +208,9 @@ unsigned long ffb_get_unmapped_area(struct file *filp,
return addr;
}
-static int ffb_presetup(drm_device_t *dev)
+static int ffb_presetup(drm_device_t * dev)
{
- ffb_dev_priv_t *ffb_priv;
+ ffb_dev_priv_t *ffb_priv;
int ret = 0;
int i = 0;
@@ -224,14 +225,11 @@ static int ffb_presetup(drm_device_t *dev)
memset(ffb_priv, 0, sizeof(*ffb_priv));
dev->dev_private = ffb_priv;
- ret = ffb_init_one(dev,
- ffb_position[i].node,
- ffb_position[i].root,
- i);
+ ret = ffb_init_one(dev, ffb_position[i].node, ffb_position[i].root, i);
return ret;
}
-static void ffb_driver_release(drm_device_t *dev, struct file *filp)
+static void ffb_driver_release(drm_device_t * dev, struct file *filp)
{
ffb_dev_priv_t *fpriv = (ffb_dev_priv_t *) dev->dev_private;
int context = _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock);
@@ -239,84 +237,80 @@ static void ffb_driver_release(drm_device_t *dev, struct file *filp)
idx = context - 1;
if (fpriv &&
- context != DRM_KERNEL_CONTEXT &&
- fpriv->hw_state[idx] != NULL) {
+ context != DRM_KERNEL_CONTEXT && fpriv->hw_state[idx] != NULL) {
kfree(fpriv->hw_state[idx]);
fpriv->hw_state[idx] = NULL;
- }
+ }
}
-static void ffb_driver_pretakedown(drm_device_t *dev)
+static void ffb_driver_pretakedown(drm_device_t * dev)
{
- if (dev->dev_private) kfree(dev->dev_private);
+ kfree(dev->dev_private);
}
-static int ffb_driver_postcleanup(drm_device_t *dev)
+static int ffb_driver_postcleanup(drm_device_t * dev)
{
- if (ffb_position != NULL) kfree(ffb_position);
+ kfree(ffb_position);
return 0;
}
-static void ffb_driver_kernel_context_switch_unlock(struct drm_device *dev, drm_lock_t *lock)
+static void ffb_driver_kernel_context_switch_unlock(struct drm_device *dev,
+ drm_lock_t * lock)
{
dev->lock.filp = 0;
{
__volatile__ unsigned int *plock = &dev->lock.hw_lock->lock;
unsigned int old, new, prev, ctx;
-
+
ctx = lock->context;
do {
- old = *plock;
- new = ctx;
+ old = *plock;
+ new = ctx;
prev = cmpxchg(plock, old, new);
} while (prev != old);
}
wake_up_interruptible(&dev->lock.lock_queue);
}
-static unsigned long ffb_driver_get_map_ofs(drm_map_t *map)
+static unsigned long ffb_driver_get_map_ofs(drm_map_t * map)
{
return (map->offset & 0xffffffff);
}
-static unsigned long ffb_driver_get_reg_ofs(drm_device_t *dev)
+static unsigned long ffb_driver_get_reg_ofs(drm_device_t * dev)
{
- ffb_dev_priv_t *ffb_priv = (ffb_dev_priv_t *)dev->dev_private;
-
- if (ffb_priv)
- return ffb_priv->card_phys_base;
-
- return 0;
+ ffb_dev_priv_t *ffb_priv = (ffb_dev_priv_t *) dev->dev_private;
+
+ if (ffb_priv)
+ return ffb_priv->card_phys_base;
+
+ return 0;
}
-static int postinit( struct drm_device *dev, unsigned long flags )
+static int postinit(struct drm_device *dev, unsigned long flags)
{
- DRM_INFO( "Initialized %s %d.%d.%d %s on minor %d\n",
- DRIVER_NAME,
- DRIVER_MAJOR,
- DRIVER_MINOR,
- DRIVER_PATCHLEVEL,
- DRIVER_DATE,
- dev->minor
- );
+ DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n",
+ DRIVER_NAME,
+ DRIVER_MAJOR,
+ DRIVER_MINOR, DRIVER_PATCHLEVEL, DRIVER_DATE, dev->minor);
return 0;
}
-static int version( drm_version_t *version )
+static int version(drm_version_t * version)
{
int len;
version->version_major = DRIVER_MAJOR;
version->version_minor = DRIVER_MINOR;
version->version_patchlevel = DRIVER_PATCHLEVEL;
- DRM_COPY( version->name, DRIVER_NAME );
- DRM_COPY( version->date, DRIVER_DATE );
- DRM_COPY( version->desc, DRIVER_DESC );
+ DRM_COPY(version->name, DRIVER_NAME);
+ DRM_COPY(version->date, DRIVER_DATE);
+ DRM_COPY(version->desc, DRIVER_DESC);
return 0;
}
static drm_ioctl_desc_t ioctls[] = {
-
+
};
static struct drm_driver driver = {
@@ -335,14 +329,15 @@ static struct drm_driver driver = {
.ioctls = ioctls,
.num_ioctls = DRM_ARRAY_SIZE(ioctls),
.fops = {
- .owner = THIS_MODULE,
- .open = drm_open,
- .release = drm_release,
- .ioctl = drm_ioctl,
- .mmap = drm_mmap,
- .poll = drm_poll,
- .fasync = drm_fasync,
- },
+ .owner = THIS_MODULE,
+ .open = drm_open,
+ .release = drm_release,
+ .ioctl = drm_ioctl,
+ .mmap = drm_mmap,
+ .poll = drm_poll,
+ .fasync = drm_fasync,
+ }
+ ,
};
static int __init ffb_init(void)
@@ -357,6 +352,6 @@ static void __exit ffb_exit(void)
module_init(ffb_init);
module_exit(ffb_exit);
-MODULE_AUTHOR( DRIVER_AUTHOR );
-MODULE_DESCRIPTION( DRIVER_DESC );
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL and additional rights");
diff --git a/drivers/char/drm/ffb_drv.h b/drivers/char/drm/ffb_drv.h
index 8bf7f1e143f1..582afa6dd2b4 100644
--- a/drivers/char/drm/ffb_drv.h
+++ b/drivers/char/drm/ffb_drv.h
@@ -5,7 +5,7 @@
*/
/* Auxilliary clips. */
-typedef struct {
+typedef struct {
volatile unsigned int min;
volatile unsigned int max;
} ffb_auxclip, *ffb_auxclipPtr;
@@ -15,172 +15,265 @@ typedef struct _ffb_fbc {
/* Next vertex registers, on the right we list which drawops
* use said register and the logical name the register has in
* that context.
- */ /* DESCRIPTION DRAWOP(NAME) */
-/*0x00*/unsigned int pad1[3]; /* Reserved */
-/*0x0c*/volatile unsigned int alpha; /* ALPHA Transparency */
-/*0x10*/volatile unsigned int red; /* RED */
-/*0x14*/volatile unsigned int green; /* GREEN */
-/*0x18*/volatile unsigned int blue; /* BLUE */
-/*0x1c*/volatile unsigned int z; /* DEPTH */
-/*0x20*/volatile unsigned int y; /* Y triangle(DOYF) */
- /* aadot(DYF) */
- /* ddline(DYF) */
- /* aaline(DYF) */
-/*0x24*/volatile unsigned int x; /* X triangle(DOXF) */
- /* aadot(DXF) */
- /* ddline(DXF) */
- /* aaline(DXF) */
-/*0x28*/unsigned int pad2[2]; /* Reserved */
-/*0x30*/volatile unsigned int ryf; /* Y (alias to DOYF) ddline(RYF) */
- /* aaline(RYF) */
- /* triangle(RYF) */
-/*0x34*/volatile unsigned int rxf; /* X ddline(RXF) */
- /* aaline(RXF) */
- /* triangle(RXF) */
-/*0x38*/unsigned int pad3[2]; /* Reserved */
-/*0x40*/volatile unsigned int dmyf; /* Y (alias to DOYF) triangle(DMYF) */
-/*0x44*/volatile unsigned int dmxf; /* X triangle(DMXF) */
-/*0x48*/unsigned int pad4[2]; /* Reserved */
-/*0x50*/volatile unsigned int ebyi; /* Y (alias to RYI) polygon(EBYI) */
-/*0x54*/volatile unsigned int ebxi; /* X polygon(EBXI) */
-/*0x58*/unsigned int pad5[2]; /* Reserved */
-/*0x60*/volatile unsigned int by; /* Y brline(RYI) */
- /* fastfill(OP) */
- /* polygon(YI) */
- /* rectangle(YI) */
- /* bcopy(SRCY) */
- /* vscroll(SRCY) */
-/*0x64*/volatile unsigned int bx; /* X brline(RXI) */
- /* polygon(XI) */
- /* rectangle(XI) */
- /* bcopy(SRCX) */
- /* vscroll(SRCX) */
- /* fastfill(GO) */
-/*0x68*/volatile unsigned int dy; /* destination Y fastfill(DSTY) */
- /* bcopy(DSRY) */
- /* vscroll(DSRY) */
-/*0x6c*/volatile unsigned int dx; /* destination X fastfill(DSTX) */
- /* bcopy(DSTX) */
- /* vscroll(DSTX) */
-/*0x70*/volatile unsigned int bh; /* Y (alias to RYI) brline(DYI) */
- /* dot(DYI) */
- /* polygon(ETYI) */
- /* Height fastfill(H) */
- /* bcopy(H) */
- /* vscroll(H) */
- /* Y count fastfill(NY) */
-/*0x74*/volatile unsigned int bw; /* X dot(DXI) */
- /* brline(DXI) */
- /* polygon(ETXI) */
- /* fastfill(W) */
- /* bcopy(W) */
- /* vscroll(W) */
- /* fastfill(NX) */
-/*0x78*/unsigned int pad6[2]; /* Reserved */
-/*0x80*/unsigned int pad7[32]; /* Reserved */
-
+ *//* DESCRIPTION DRAWOP(NAME) */
+ /*0x00*/ unsigned int pad1[3];
+ /* Reserved */
+ /*0x0c*/ volatile unsigned int alpha;
+ /* ALPHA Transparency */
+ /*0x10*/ volatile unsigned int red;
+ /* RED */
+ /*0x14*/ volatile unsigned int green;
+ /* GREEN */
+ /*0x18*/ volatile unsigned int blue;
+ /* BLUE */
+ /*0x1c*/ volatile unsigned int z;
+ /* DEPTH */
+ /*0x20*/ volatile unsigned int y;
+ /* Y triangle(DOYF) */
+ /* aadot(DYF) */
+ /* ddline(DYF) */
+ /* aaline(DYF) */
+ /*0x24*/ volatile unsigned int x;
+ /* X triangle(DOXF) */
+ /* aadot(DXF) */
+ /* ddline(DXF) */
+ /* aaline(DXF) */
+ /*0x28*/ unsigned int pad2[2];
+ /* Reserved */
+ /*0x30*/ volatile unsigned int ryf;
+ /* Y (alias to DOYF) ddline(RYF) */
+ /* aaline(RYF) */
+ /* triangle(RYF) */
+ /*0x34*/ volatile unsigned int rxf;
+ /* X ddline(RXF) */
+ /* aaline(RXF) */
+ /* triangle(RXF) */
+ /*0x38*/ unsigned int pad3[2];
+ /* Reserved */
+ /*0x40*/ volatile unsigned int dmyf;
+ /* Y (alias to DOYF) triangle(DMYF) */
+ /*0x44*/ volatile unsigned int dmxf;
+ /* X triangle(DMXF) */
+ /*0x48*/ unsigned int pad4[2];
+ /* Reserved */
+ /*0x50*/ volatile unsigned int ebyi;
+ /* Y (alias to RYI) polygon(EBYI) */
+ /*0x54*/ volatile unsigned int ebxi;
+ /* X polygon(EBXI) */
+ /*0x58*/ unsigned int pad5[2];
+ /* Reserved */
+ /*0x60*/ volatile unsigned int by;
+ /* Y brline(RYI) */
+ /* fastfill(OP) */
+ /* polygon(YI) */
+ /* rectangle(YI) */
+ /* bcopy(SRCY) */
+ /* vscroll(SRCY) */
+ /*0x64*/ volatile unsigned int bx;
+ /* X brline(RXI) */
+ /* polygon(XI) */
+ /* rectangle(XI) */
+ /* bcopy(SRCX) */
+ /* vscroll(SRCX) */
+ /* fastfill(GO) */
+ /*0x68*/ volatile unsigned int dy;
+ /* destination Y fastfill(DSTY) */
+ /* bcopy(DSRY) */
+ /* vscroll(DSRY) */
+ /*0x6c*/ volatile unsigned int dx;
+ /* destination X fastfill(DSTX) */
+ /* bcopy(DSTX) */
+ /* vscroll(DSTX) */
+ /*0x70*/ volatile unsigned int bh;
+ /* Y (alias to RYI) brline(DYI) */
+ /* dot(DYI) */
+ /* polygon(ETYI) */
+ /* Height fastfill(H) */
+ /* bcopy(H) */
+ /* vscroll(H) */
+ /* Y count fastfill(NY) */
+ /*0x74*/ volatile unsigned int bw;
+ /* X dot(DXI) */
+ /* brline(DXI) */
+ /* polygon(ETXI) */
+ /* fastfill(W) */
+ /* bcopy(W) */
+ /* vscroll(W) */
+ /* fastfill(NX) */
+ /*0x78*/ unsigned int pad6[2];
+ /* Reserved */
+ /*0x80*/ unsigned int pad7[32];
+ /* Reserved */
+
/* Setup Unit's vertex state register */
-/*100*/ volatile unsigned int suvtx;
-/*104*/ unsigned int pad8[63]; /* Reserved */
-
+/*100*/ volatile unsigned int suvtx;
+ /*104*/ unsigned int pad8[63];
+ /* Reserved */
+
/* Frame Buffer Control Registers */
-/*200*/ volatile unsigned int ppc; /* Pixel Processor Control */
-/*204*/ volatile unsigned int wid; /* Current WID */
-/*208*/ volatile unsigned int fg; /* FG data */
-/*20c*/ volatile unsigned int bg; /* BG data */
-/*210*/ volatile unsigned int consty; /* Constant Y */
-/*214*/ volatile unsigned int constz; /* Constant Z */
-/*218*/ volatile unsigned int xclip; /* X Clip */
-/*21c*/ volatile unsigned int dcss; /* Depth Cue Scale Slope */
-/*220*/ volatile unsigned int vclipmin; /* Viewclip XY Min Bounds */
-/*224*/ volatile unsigned int vclipmax; /* Viewclip XY Max Bounds */
-/*228*/ volatile unsigned int vclipzmin; /* Viewclip Z Min Bounds */
-/*22c*/ volatile unsigned int vclipzmax; /* Viewclip Z Max Bounds */
-/*230*/ volatile unsigned int dcsf; /* Depth Cue Scale Front Bound */
-/*234*/ volatile unsigned int dcsb; /* Depth Cue Scale Back Bound */
-/*238*/ volatile unsigned int dczf; /* Depth Cue Z Front */
-/*23c*/ volatile unsigned int dczb; /* Depth Cue Z Back */
-/*240*/ unsigned int pad9; /* Reserved */
-/*244*/ volatile unsigned int blendc; /* Alpha Blend Control */
-/*248*/ volatile unsigned int blendc1; /* Alpha Blend Color 1 */
-/*24c*/ volatile unsigned int blendc2; /* Alpha Blend Color 2 */
-/*250*/ volatile unsigned int fbramitc; /* FB RAM Interleave Test Control */
-/*254*/ volatile unsigned int fbc; /* Frame Buffer Control */
-/*258*/ volatile unsigned int rop; /* Raster OPeration */
-/*25c*/ volatile unsigned int cmp; /* Frame Buffer Compare */
-/*260*/ volatile unsigned int matchab; /* Buffer AB Match Mask */
-/*264*/ volatile unsigned int matchc; /* Buffer C(YZ) Match Mask */
-/*268*/ volatile unsigned int magnab; /* Buffer AB Magnitude Mask */
-/*26c*/ volatile unsigned int magnc; /* Buffer C(YZ) Magnitude Mask */
-/*270*/ volatile unsigned int fbcfg0; /* Frame Buffer Config 0 */
-/*274*/ volatile unsigned int fbcfg1; /* Frame Buffer Config 1 */
-/*278*/ volatile unsigned int fbcfg2; /* Frame Buffer Config 2 */
-/*27c*/ volatile unsigned int fbcfg3; /* Frame Buffer Config 3 */
-/*280*/ volatile unsigned int ppcfg; /* Pixel Processor Config */
-/*284*/ volatile unsigned int pick; /* Picking Control */
-/*288*/ volatile unsigned int fillmode; /* FillMode */
-/*28c*/ volatile unsigned int fbramwac; /* FB RAM Write Address Control */
-/*290*/ volatile unsigned int pmask; /* RGB PlaneMask */
-/*294*/ volatile unsigned int xpmask; /* X PlaneMask */
-/*298*/ volatile unsigned int ypmask; /* Y PlaneMask */
-/*29c*/ volatile unsigned int zpmask; /* Z PlaneMask */
-/*2a0*/ ffb_auxclip auxclip[4]; /* Auxilliary Viewport Clip */
-
+ /*200*/ volatile unsigned int ppc;
+ /* Pixel Processor Control */
+ /*204*/ volatile unsigned int wid;
+ /* Current WID */
+ /*208*/ volatile unsigned int fg;
+ /* FG data */
+ /*20c*/ volatile unsigned int bg;
+ /* BG data */
+ /*210*/ volatile unsigned int consty;
+ /* Constant Y */
+ /*214*/ volatile unsigned int constz;
+ /* Constant Z */
+ /*218*/ volatile unsigned int xclip;
+ /* X Clip */
+ /*21c*/ volatile unsigned int dcss;
+ /* Depth Cue Scale Slope */
+ /*220*/ volatile unsigned int vclipmin;
+ /* Viewclip XY Min Bounds */
+ /*224*/ volatile unsigned int vclipmax;
+ /* Viewclip XY Max Bounds */
+ /*228*/ volatile unsigned int vclipzmin;
+ /* Viewclip Z Min Bounds */
+ /*22c*/ volatile unsigned int vclipzmax;
+ /* Viewclip Z Max Bounds */
+ /*230*/ volatile unsigned int dcsf;
+ /* Depth Cue Scale Front Bound */
+ /*234*/ volatile unsigned int dcsb;
+ /* Depth Cue Scale Back Bound */
+ /*238*/ volatile unsigned int dczf;
+ /* Depth Cue Z Front */
+ /*23c*/ volatile unsigned int dczb;
+ /* Depth Cue Z Back */
+ /*240*/ unsigned int pad9;
+ /* Reserved */
+ /*244*/ volatile unsigned int blendc;
+ /* Alpha Blend Control */
+ /*248*/ volatile unsigned int blendc1;
+ /* Alpha Blend Color 1 */
+ /*24c*/ volatile unsigned int blendc2;
+ /* Alpha Blend Color 2 */
+ /*250*/ volatile unsigned int fbramitc;
+ /* FB RAM Interleave Test Control */
+ /*254*/ volatile unsigned int fbc;
+ /* Frame Buffer Control */
+ /*258*/ volatile unsigned int rop;
+ /* Raster OPeration */
+ /*25c*/ volatile unsigned int cmp;
+ /* Frame Buffer Compare */
+ /*260*/ volatile unsigned int matchab;
+ /* Buffer AB Match Mask */
+ /*264*/ volatile unsigned int matchc;
+ /* Buffer C(YZ) Match Mask */
+ /*268*/ volatile unsigned int magnab;
+ /* Buffer AB Magnitude Mask */
+ /*26c*/ volatile unsigned int magnc;
+ /* Buffer C(YZ) Magnitude Mask */
+ /*270*/ volatile unsigned int fbcfg0;
+ /* Frame Buffer Config 0 */
+ /*274*/ volatile unsigned int fbcfg1;
+ /* Frame Buffer Config 1 */
+ /*278*/ volatile unsigned int fbcfg2;
+ /* Frame Buffer Config 2 */
+ /*27c*/ volatile unsigned int fbcfg3;
+ /* Frame Buffer Config 3 */
+ /*280*/ volatile unsigned int ppcfg;
+ /* Pixel Processor Config */
+ /*284*/ volatile unsigned int pick;
+ /* Picking Control */
+ /*288*/ volatile unsigned int fillmode;
+ /* FillMode */
+ /*28c*/ volatile unsigned int fbramwac;
+ /* FB RAM Write Address Control */
+ /*290*/ volatile unsigned int pmask;
+ /* RGB PlaneMask */
+ /*294*/ volatile unsigned int xpmask;
+ /* X PlaneMask */
+ /*298*/ volatile unsigned int ypmask;
+ /* Y PlaneMask */
+ /*29c*/ volatile unsigned int zpmask;
+ /* Z PlaneMask */
+ /*2a0*/ ffb_auxclip auxclip[4];
+ /* Auxilliary Viewport Clip */
+
/* New 3dRAM III support regs */
-/*2c0*/ volatile unsigned int rawblend2;
-/*2c4*/ volatile unsigned int rawpreblend;
-/*2c8*/ volatile unsigned int rawstencil;
-/*2cc*/ volatile unsigned int rawstencilctl;
-/*2d0*/ volatile unsigned int threedram1;
-/*2d4*/ volatile unsigned int threedram2;
-/*2d8*/ volatile unsigned int passin;
-/*2dc*/ volatile unsigned int rawclrdepth;
-/*2e0*/ volatile unsigned int rawpmask;
-/*2e4*/ volatile unsigned int rawcsrc;
-/*2e8*/ volatile unsigned int rawmatch;
-/*2ec*/ volatile unsigned int rawmagn;
-/*2f0*/ volatile unsigned int rawropblend;
-/*2f4*/ volatile unsigned int rawcmp;
-/*2f8*/ volatile unsigned int rawwac;
-/*2fc*/ volatile unsigned int fbramid;
-
-/*300*/ volatile unsigned int drawop; /* Draw OPeration */
-/*304*/ unsigned int pad10[2]; /* Reserved */
-/*30c*/ volatile unsigned int lpat; /* Line Pattern control */
-/*310*/ unsigned int pad11; /* Reserved */
-/*314*/ volatile unsigned int fontxy; /* XY Font coordinate */
-/*318*/ volatile unsigned int fontw; /* Font Width */
-/*31c*/ volatile unsigned int fontinc; /* Font Increment */
-/*320*/ volatile unsigned int font; /* Font bits */
-/*324*/ unsigned int pad12[3]; /* Reserved */
-/*330*/ volatile unsigned int blend2;
-/*334*/ volatile unsigned int preblend;
-/*338*/ volatile unsigned int stencil;
-/*33c*/ volatile unsigned int stencilctl;
+/*2c0*/ volatile unsigned int rawblend2;
+/*2c4*/ volatile unsigned int rawpreblend;
+/*2c8*/ volatile unsigned int rawstencil;
+/*2cc*/ volatile unsigned int rawstencilctl;
+/*2d0*/ volatile unsigned int threedram1;
+/*2d4*/ volatile unsigned int threedram2;
+/*2d8*/ volatile unsigned int passin;
+/*2dc*/ volatile unsigned int rawclrdepth;
+/*2e0*/ volatile unsigned int rawpmask;
+/*2e4*/ volatile unsigned int rawcsrc;
+/*2e8*/ volatile unsigned int rawmatch;
+/*2ec*/ volatile unsigned int rawmagn;
+/*2f0*/ volatile unsigned int rawropblend;
+/*2f4*/ volatile unsigned int rawcmp;
+/*2f8*/ volatile unsigned int rawwac;
+/*2fc*/ volatile unsigned int fbramid;
+
+ /*300*/ volatile unsigned int drawop;
+ /* Draw OPeration */
+ /*304*/ unsigned int pad10[2];
+ /* Reserved */
+ /*30c*/ volatile unsigned int lpat;
+ /* Line Pattern control */
+ /*310*/ unsigned int pad11;
+ /* Reserved */
+ /*314*/ volatile unsigned int fontxy;
+ /* XY Font coordinate */
+ /*318*/ volatile unsigned int fontw;
+ /* Font Width */
+ /*31c*/ volatile unsigned int fontinc;
+ /* Font Increment */
+ /*320*/ volatile unsigned int font;
+ /* Font bits */
+ /*324*/ unsigned int pad12[3];
+ /* Reserved */
+/*330*/ volatile unsigned int blend2;
+/*334*/ volatile unsigned int preblend;
+/*338*/ volatile unsigned int stencil;
+/*33c*/ volatile unsigned int stencilctl;
-/*340*/ unsigned int pad13[4]; /* Reserved */
-/*350*/ volatile unsigned int dcss1; /* Depth Cue Scale Slope 1 */
-/*354*/ volatile unsigned int dcss2; /* Depth Cue Scale Slope 2 */
-/*358*/ volatile unsigned int dcss3; /* Depth Cue Scale Slope 3 */
-/*35c*/ volatile unsigned int widpmask;
-/*360*/ volatile unsigned int dcs2;
-/*364*/ volatile unsigned int dcs3;
-/*368*/ volatile unsigned int dcs4;
-/*36c*/ unsigned int pad14; /* Reserved */
-/*370*/ volatile unsigned int dcd2;
-/*374*/ volatile unsigned int dcd3;
-/*378*/ volatile unsigned int dcd4;
-/*37c*/ unsigned int pad15; /* Reserved */
-/*380*/ volatile unsigned int pattern[32]; /* area Pattern */
-/*400*/ unsigned int pad16[8]; /* Reserved */
-/*420*/ volatile unsigned int reset; /* chip RESET */
-/*424*/ unsigned int pad17[247]; /* Reserved */
-/*800*/ volatile unsigned int devid; /* Device ID */
-/*804*/ unsigned int pad18[63]; /* Reserved */
-/*900*/ volatile unsigned int ucsr; /* User Control & Status Register */
-/*904*/ unsigned int pad19[31]; /* Reserved */
-/*980*/ volatile unsigned int mer; /* Mode Enable Register */
-/*984*/ unsigned int pad20[1439]; /* Reserved */
+ /*340*/ unsigned int pad13[4];
+ /* Reserved */
+ /*350*/ volatile unsigned int dcss1;
+ /* Depth Cue Scale Slope 1 */
+ /*354*/ volatile unsigned int dcss2;
+ /* Depth Cue Scale Slope 2 */
+ /*358*/ volatile unsigned int dcss3;
+ /* Depth Cue Scale Slope 3 */
+/*35c*/ volatile unsigned int widpmask;
+/*360*/ volatile unsigned int dcs2;
+/*364*/ volatile unsigned int dcs3;
+/*368*/ volatile unsigned int dcs4;
+ /*36c*/ unsigned int pad14;
+ /* Reserved */
+/*370*/ volatile unsigned int dcd2;
+/*374*/ volatile unsigned int dcd3;
+/*378*/ volatile unsigned int dcd4;
+ /*37c*/ unsigned int pad15;
+ /* Reserved */
+ /*380*/ volatile unsigned int pattern[32];
+ /* area Pattern */
+ /*400*/ unsigned int pad16[8];
+ /* Reserved */
+ /*420*/ volatile unsigned int reset;
+ /* chip RESET */
+ /*424*/ unsigned int pad17[247];
+ /* Reserved */
+ /*800*/ volatile unsigned int devid;
+ /* Device ID */
+ /*804*/ unsigned int pad18[63];
+ /* Reserved */
+ /*900*/ volatile unsigned int ucsr;
+ /* User Control & Status Register */
+ /*904*/ unsigned int pad19[31];
+ /* Reserved */
+ /*980*/ volatile unsigned int mer;
+ /* Mode Enable Register */
+ /*984*/ unsigned int pad20[1439];
+ /* Reserved */
} ffb_fbc, *ffb_fbcPtr;
struct ffb_hw_context {
@@ -263,16 +356,16 @@ enum ffb_chip_type {
typedef struct ffb_dev_priv {
/* Misc software state. */
- int prom_node;
- enum ffb_chip_type ffb_type;
- u64 card_phys_base;
- struct miscdevice miscdev;
+ int prom_node;
+ enum ffb_chip_type ffb_type;
+ u64 card_phys_base;
+ struct miscdevice miscdev;
/* Controller registers. */
- ffb_fbcPtr regs;
+ ffb_fbcPtr regs;
/* Context table. */
- struct ffb_hw_context *hw_state[FFB_MAX_CTXS];
+ struct ffb_hw_context *hw_state[FFB_MAX_CTXS];
} ffb_dev_priv_t;
extern unsigned long ffb_get_unmapped_area(struct file *filp,
@@ -283,4 +376,4 @@ extern unsigned long ffb_get_unmapped_area(struct file *filp,
extern void ffb_set_context_ioctls(void);
extern drm_ioctl_desc_t DRM(ioctls)[];
-extern int ffb_driver_context_switch(drm_device_t *dev, int old, int new);
+extern int ffb_driver_context_switch(drm_device_t * dev, int old, int new);
diff --git a/drivers/char/drm/i810_dma.c b/drivers/char/drm/i810_dma.c
index 2f1659b96fd1..dba502373da1 100644
--- a/drivers/char/drm/i810_dma.c
+++ b/drivers/char/drm/i810_dma.c
@@ -45,102 +45,101 @@
#define I810_BUF_UNMAPPED 0
#define I810_BUF_MAPPED 1
-static drm_buf_t *i810_freelist_get(drm_device_t *dev)
+static drm_buf_t *i810_freelist_get(drm_device_t * dev)
{
- drm_device_dma_t *dma = dev->dma;
- int i;
- int used;
+ drm_device_dma_t *dma = dev->dma;
+ int i;
+ int used;
/* Linear search might not be the best solution */
- for (i = 0; i < dma->buf_count; i++) {
- drm_buf_t *buf = dma->buflist[ i ];
- drm_i810_buf_priv_t *buf_priv = buf->dev_private;
+ for (i = 0; i < dma->buf_count; i++) {
+ drm_buf_t *buf = dma->buflist[i];
+ drm_i810_buf_priv_t *buf_priv = buf->dev_private;
/* In use is already a pointer */
- used = cmpxchg(buf_priv->in_use, I810_BUF_FREE,
+ used = cmpxchg(buf_priv->in_use, I810_BUF_FREE,
I810_BUF_CLIENT);
if (used == I810_BUF_FREE) {
return buf;
}
}
- return NULL;
+ return NULL;
}
/* This should only be called if the buffer is not sent to the hardware
* yet, the hardware updates in use for us once its on the ring buffer.
*/
-static int i810_freelist_put(drm_device_t *dev, drm_buf_t *buf)
+static int i810_freelist_put(drm_device_t * dev, drm_buf_t * buf)
{
- drm_i810_buf_priv_t *buf_priv = buf->dev_private;
- int used;
+ drm_i810_buf_priv_t *buf_priv = buf->dev_private;
+ int used;
- /* In use is already a pointer */
- used = cmpxchg(buf_priv->in_use, I810_BUF_CLIENT, I810_BUF_FREE);
+ /* In use is already a pointer */
+ used = cmpxchg(buf_priv->in_use, I810_BUF_CLIENT, I810_BUF_FREE);
if (used != I810_BUF_CLIENT) {
- DRM_ERROR("Freeing buffer thats not in use : %d\n", buf->idx);
- return -EINVAL;
+ DRM_ERROR("Freeing buffer thats not in use : %d\n", buf->idx);
+ return -EINVAL;
}
- return 0;
+ return 0;
}
static int i810_mmap_buffers(struct file *filp, struct vm_area_struct *vma)
{
- drm_file_t *priv = filp->private_data;
- drm_device_t *dev;
- drm_i810_private_t *dev_priv;
- drm_buf_t *buf;
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev;
+ drm_i810_private_t *dev_priv;
+ drm_buf_t *buf;
drm_i810_buf_priv_t *buf_priv;
lock_kernel();
- dev = priv->head->dev;
+ dev = priv->head->dev;
dev_priv = dev->dev_private;
- buf = dev_priv->mmap_buffer;
+ buf = dev_priv->mmap_buffer;
buf_priv = buf->dev_private;
vma->vm_flags |= (VM_IO | VM_DONTCOPY);
vma->vm_file = filp;
- buf_priv->currently_mapped = I810_BUF_MAPPED;
+ buf_priv->currently_mapped = I810_BUF_MAPPED;
unlock_kernel();
if (io_remap_pfn_range(vma, vma->vm_start,
- VM_OFFSET(vma) >> PAGE_SHIFT,
- vma->vm_end - vma->vm_start,
- vma->vm_page_prot)) return -EAGAIN;
+ VM_OFFSET(vma) >> PAGE_SHIFT,
+ vma->vm_end - vma->vm_start, vma->vm_page_prot))
+ return -EAGAIN;
return 0;
}
static struct file_operations i810_buffer_fops = {
- .open = drm_open,
- .flush = drm_flush,
+ .open = drm_open,
+ .flush = drm_flush,
.release = drm_release,
- .ioctl = drm_ioctl,
- .mmap = i810_mmap_buffers,
- .fasync = drm_fasync,
+ .ioctl = drm_ioctl,
+ .mmap = i810_mmap_buffers,
+ .fasync = drm_fasync,
};
-static int i810_map_buffer(drm_buf_t *buf, struct file *filp)
+static int i810_map_buffer(drm_buf_t * buf, struct file *filp)
{
- drm_file_t *priv = filp->private_data;
- drm_device_t *dev = priv->head->dev;
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->head->dev;
drm_i810_buf_priv_t *buf_priv = buf->dev_private;
- drm_i810_private_t *dev_priv = dev->dev_private;
- struct file_operations *old_fops;
+ drm_i810_private_t *dev_priv = dev->dev_private;
+ struct file_operations *old_fops;
int retcode = 0;
- if (buf_priv->currently_mapped == I810_BUF_MAPPED)
+ if (buf_priv->currently_mapped == I810_BUF_MAPPED)
return -EINVAL;
- down_write( &current->mm->mmap_sem );
+ down_write(&current->mm->mmap_sem);
old_fops = filp->f_op;
filp->f_op = &i810_buffer_fops;
dev_priv->mmap_buffer = buf;
buf_priv->virtual = (void *)do_mmap(filp, 0, buf->total,
- PROT_READ|PROT_WRITE,
- MAP_SHARED,
- buf->bus_address);
+ PROT_READ | PROT_WRITE,
+ MAP_SHARED, buf->bus_address);
dev_priv->mmap_buffer = NULL;
filp->f_op = old_fops;
if ((unsigned long)buf_priv->virtual > -1024UL) {
@@ -149,12 +148,12 @@ static int i810_map_buffer(drm_buf_t *buf, struct file *filp)
retcode = (signed int)buf_priv->virtual;
buf_priv->virtual = NULL;
}
- up_write( &current->mm->mmap_sem );
+ up_write(&current->mm->mmap_sem);
return retcode;
}
-static int i810_unmap_buffer(drm_buf_t *buf)
+static int i810_unmap_buffer(drm_buf_t * buf)
{
drm_i810_buf_priv_t *buf_priv = buf->dev_private;
int retcode = 0;
@@ -168,43 +167,43 @@ static int i810_unmap_buffer(drm_buf_t *buf)
(size_t) buf->total);
up_write(&current->mm->mmap_sem);
- buf_priv->currently_mapped = I810_BUF_UNMAPPED;
- buf_priv->virtual = NULL;
+ buf_priv->currently_mapped = I810_BUF_UNMAPPED;
+ buf_priv->virtual = NULL;
return retcode;
}
-static int i810_dma_get_buffer(drm_device_t *dev, drm_i810_dma_t *d,
+static int i810_dma_get_buffer(drm_device_t * dev, drm_i810_dma_t * d,
struct file *filp)
{
- drm_buf_t *buf;
+ drm_buf_t *buf;
drm_i810_buf_priv_t *buf_priv;
int retcode = 0;
buf = i810_freelist_get(dev);
if (!buf) {
retcode = -ENOMEM;
- DRM_DEBUG("retcode=%d\n", retcode);
+ DRM_DEBUG("retcode=%d\n", retcode);
return retcode;
}
retcode = i810_map_buffer(buf, filp);
if (retcode) {
i810_freelist_put(dev, buf);
- DRM_ERROR("mapbuf failed, retcode %d\n", retcode);
+ DRM_ERROR("mapbuf failed, retcode %d\n", retcode);
return retcode;
}
buf->filp = filp;
buf_priv = buf->dev_private;
d->granted = 1;
- d->request_idx = buf->idx;
- d->request_size = buf->total;
- d->virtual = buf_priv->virtual;
+ d->request_idx = buf->idx;
+ d->request_size = buf->total;
+ d->virtual = buf_priv->virtual;
return retcode;
}
-static int i810_dma_cleanup(drm_device_t *dev)
+static int i810_dma_cleanup(drm_device_t * dev)
{
drm_device_dma_t *dma = dev->dma;
@@ -217,165 +216,167 @@ static int i810_dma_cleanup(drm_device_t *dev)
if (dev->dev_private) {
int i;
- drm_i810_private_t *dev_priv =
- (drm_i810_private_t *) dev->dev_private;
+ drm_i810_private_t *dev_priv =
+ (drm_i810_private_t *) dev->dev_private;
if (dev_priv->ring.virtual_start) {
- drm_ioremapfree((void *) dev_priv->ring.virtual_start,
- dev_priv->ring.Size, dev);
+ drm_ioremapfree((void *)dev_priv->ring.virtual_start,
+ dev_priv->ring.Size, dev);
}
- if (dev_priv->hw_status_page) {
- pci_free_consistent(dev->pdev, PAGE_SIZE,
+ if (dev_priv->hw_status_page) {
+ pci_free_consistent(dev->pdev, PAGE_SIZE,
dev_priv->hw_status_page,
dev_priv->dma_status_page);
- /* Need to rewrite hardware status page */
- I810_WRITE(0x02080, 0x1ffff000);
+ /* Need to rewrite hardware status page */
+ I810_WRITE(0x02080, 0x1ffff000);
}
- drm_free(dev->dev_private, sizeof(drm_i810_private_t),
+ drm_free(dev->dev_private, sizeof(drm_i810_private_t),
DRM_MEM_DRIVER);
- dev->dev_private = NULL;
+ dev->dev_private = NULL;
for (i = 0; i < dma->buf_count; i++) {
- drm_buf_t *buf = dma->buflist[ i ];
+ drm_buf_t *buf = dma->buflist[i];
drm_i810_buf_priv_t *buf_priv = buf->dev_private;
- if ( buf_priv->kernel_virtual && buf->total )
- drm_ioremapfree(buf_priv->kernel_virtual, buf->total, dev);
+ if (buf_priv->kernel_virtual && buf->total)
+ drm_ioremapfree(buf_priv->kernel_virtual,
+ buf->total, dev);
}
}
- return 0;
+ return 0;
}
-static int i810_wait_ring(drm_device_t *dev, int n)
+static int i810_wait_ring(drm_device_t * dev, int n)
{
- drm_i810_private_t *dev_priv = dev->dev_private;
- drm_i810_ring_buffer_t *ring = &(dev_priv->ring);
- int iters = 0;
- unsigned long end;
+ drm_i810_private_t *dev_priv = dev->dev_private;
+ drm_i810_ring_buffer_t *ring = &(dev_priv->ring);
+ int iters = 0;
+ unsigned long end;
unsigned int last_head = I810_READ(LP_RING + RING_HEAD) & HEAD_ADDR;
- end = jiffies + (HZ*3);
- while (ring->space < n) {
- ring->head = I810_READ(LP_RING + RING_HEAD) & HEAD_ADDR;
- ring->space = ring->head - (ring->tail+8);
- if (ring->space < 0) ring->space += ring->Size;
-
+ end = jiffies + (HZ * 3);
+ while (ring->space < n) {
+ ring->head = I810_READ(LP_RING + RING_HEAD) & HEAD_ADDR;
+ ring->space = ring->head - (ring->tail + 8);
+ if (ring->space < 0)
+ ring->space += ring->Size;
+
if (ring->head != last_head) {
- end = jiffies + (HZ*3);
+ end = jiffies + (HZ * 3);
last_head = ring->head;
}
-
- iters++;
+
+ iters++;
if (time_before(end, jiffies)) {
- DRM_ERROR("space: %d wanted %d\n", ring->space, n);
- DRM_ERROR("lockup\n");
- goto out_wait_ring;
+ DRM_ERROR("space: %d wanted %d\n", ring->space, n);
+ DRM_ERROR("lockup\n");
+ goto out_wait_ring;
}
udelay(1);
}
-out_wait_ring:
- return iters;
+ out_wait_ring:
+ return iters;
}
-static void i810_kernel_lost_context(drm_device_t *dev)
+static void i810_kernel_lost_context(drm_device_t * dev)
{
- drm_i810_private_t *dev_priv = dev->dev_private;
- drm_i810_ring_buffer_t *ring = &(dev_priv->ring);
+ drm_i810_private_t *dev_priv = dev->dev_private;
+ drm_i810_ring_buffer_t *ring = &(dev_priv->ring);
- ring->head = I810_READ(LP_RING + RING_HEAD) & HEAD_ADDR;
- ring->tail = I810_READ(LP_RING + RING_TAIL);
- ring->space = ring->head - (ring->tail+8);
- if (ring->space < 0) ring->space += ring->Size;
+ ring->head = I810_READ(LP_RING + RING_HEAD) & HEAD_ADDR;
+ ring->tail = I810_READ(LP_RING + RING_TAIL);
+ ring->space = ring->head - (ring->tail + 8);
+ if (ring->space < 0)
+ ring->space += ring->Size;
}
-static int i810_freelist_init(drm_device_t *dev, drm_i810_private_t *dev_priv)
+static int i810_freelist_init(drm_device_t * dev, drm_i810_private_t * dev_priv)
{
- drm_device_dma_t *dma = dev->dma;
- int my_idx = 24;
- u32 *hw_status = (u32 *)(dev_priv->hw_status_page + my_idx);
- int i;
+ drm_device_dma_t *dma = dev->dma;
+ int my_idx = 24;
+ u32 *hw_status = (u32 *) (dev_priv->hw_status_page + my_idx);
+ int i;
if (dma->buf_count > 1019) {
- /* Not enough space in the status page for the freelist */
- return -EINVAL;
+ /* Not enough space in the status page for the freelist */
+ return -EINVAL;
}
- for (i = 0; i < dma->buf_count; i++) {
- drm_buf_t *buf = dma->buflist[ i ];
- drm_i810_buf_priv_t *buf_priv = buf->dev_private;
+ for (i = 0; i < dma->buf_count; i++) {
+ drm_buf_t *buf = dma->buflist[i];
+ drm_i810_buf_priv_t *buf_priv = buf->dev_private;
- buf_priv->in_use = hw_status++;
- buf_priv->my_use_idx = my_idx;
- my_idx += 4;
+ buf_priv->in_use = hw_status++;
+ buf_priv->my_use_idx = my_idx;
+ my_idx += 4;
- *buf_priv->in_use = I810_BUF_FREE;
+ *buf_priv->in_use = I810_BUF_FREE;
buf_priv->kernel_virtual = drm_ioremap(buf->bus_address,
- buf->total, dev);
+ buf->total, dev);
}
return 0;
}
-static int i810_dma_initialize(drm_device_t *dev,
- drm_i810_private_t *dev_priv,
- drm_i810_init_t *init)
+static int i810_dma_initialize(drm_device_t * dev,
+ drm_i810_private_t * dev_priv,
+ drm_i810_init_t * init)
{
struct list_head *list;
- memset(dev_priv, 0, sizeof(drm_i810_private_t));
+ memset(dev_priv, 0, sizeof(drm_i810_private_t));
list_for_each(list, &dev->maplist->head) {
drm_map_list_t *r_list = list_entry(list, drm_map_list_t, head);
if (r_list->map &&
r_list->map->type == _DRM_SHM &&
- r_list->map->flags & _DRM_CONTAINS_LOCK ) {
+ r_list->map->flags & _DRM_CONTAINS_LOCK) {
dev_priv->sarea_map = r_list->map;
- break;
- }
- }
+ break;
+ }
+ }
if (!dev_priv->sarea_map) {
dev->dev_private = (void *)dev_priv;
- i810_dma_cleanup(dev);
- DRM_ERROR("can not find sarea!\n");
- return -EINVAL;
+ i810_dma_cleanup(dev);
+ DRM_ERROR("can not find sarea!\n");
+ return -EINVAL;
}
dev_priv->mmio_map = drm_core_findmap(dev, init->mmio_offset);
if (!dev_priv->mmio_map) {
dev->dev_private = (void *)dev_priv;
- i810_dma_cleanup(dev);
- DRM_ERROR("can not find mmio map!\n");
- return -EINVAL;
+ i810_dma_cleanup(dev);
+ DRM_ERROR("can not find mmio map!\n");
+ return -EINVAL;
}
dev->agp_buffer_token = init->buffers_offset;
dev->agp_buffer_map = drm_core_findmap(dev, init->buffers_offset);
if (!dev->agp_buffer_map) {
dev->dev_private = (void *)dev_priv;
- i810_dma_cleanup(dev);
- DRM_ERROR("can not find dma buffer map!\n");
- return -EINVAL;
+ i810_dma_cleanup(dev);
+ DRM_ERROR("can not find dma buffer map!\n");
+ return -EINVAL;
}
dev_priv->sarea_priv = (drm_i810_sarea_t *)
- ((u8 *)dev_priv->sarea_map->handle +
- init->sarea_priv_offset);
+ ((u8 *) dev_priv->sarea_map->handle + init->sarea_priv_offset);
- dev_priv->ring.Start = init->ring_start;
- dev_priv->ring.End = init->ring_end;
- dev_priv->ring.Size = init->ring_size;
+ dev_priv->ring.Start = init->ring_start;
+ dev_priv->ring.End = init->ring_end;
+ dev_priv->ring.Size = init->ring_size;
- dev_priv->ring.virtual_start = drm_ioremap(dev->agp->base +
- init->ring_start,
- init->ring_size, dev);
+ dev_priv->ring.virtual_start = drm_ioremap(dev->agp->base +
+ init->ring_start,
+ init->ring_size, dev);
- if (dev_priv->ring.virtual_start == NULL) {
- dev->dev_private = (void *) dev_priv;
- i810_dma_cleanup(dev);
- DRM_ERROR("can not ioremap virtual address for"
+ if (dev_priv->ring.virtual_start == NULL) {
+ dev->dev_private = (void *)dev_priv;
+ i810_dma_cleanup(dev);
+ DRM_ERROR("can not ioremap virtual address for"
" ring buffer\n");
- return -ENOMEM;
+ return -ENOMEM;
}
- dev_priv->ring.tail_mask = dev_priv->ring.Size - 1;
+ dev_priv->ring.tail_mask = dev_priv->ring.Size - 1;
dev_priv->w = init->w;
dev_priv->h = init->h;
@@ -391,33 +392,33 @@ static int i810_dma_initialize(drm_device_t *dev,
dev_priv->back_di1 = init->back_offset | init->pitch_bits;
dev_priv->zi1 = init->depth_offset | init->pitch_bits;
- /* Program Hardware Status Page */
- dev_priv->hw_status_page =
- pci_alloc_consistent(dev->pdev, PAGE_SIZE,
- &dev_priv->dma_status_page);
- if (!dev_priv->hw_status_page) {
+ /* Program Hardware Status Page */
+ dev_priv->hw_status_page =
+ pci_alloc_consistent(dev->pdev, PAGE_SIZE,
+ &dev_priv->dma_status_page);
+ if (!dev_priv->hw_status_page) {
dev->dev_private = (void *)dev_priv;
i810_dma_cleanup(dev);
DRM_ERROR("Can not allocate hardware status page\n");
return -ENOMEM;
}
- memset(dev_priv->hw_status_page, 0, PAGE_SIZE);
- DRM_DEBUG("hw status page @ %p\n", dev_priv->hw_status_page);
+ memset(dev_priv->hw_status_page, 0, PAGE_SIZE);
+ DRM_DEBUG("hw status page @ %p\n", dev_priv->hw_status_page);
I810_WRITE(0x02080, dev_priv->dma_status_page);
- DRM_DEBUG("Enabled hardware status page\n");
+ DRM_DEBUG("Enabled hardware status page\n");
- /* Now we need to init our freelist */
+ /* Now we need to init our freelist */
if (i810_freelist_init(dev, dev_priv) != 0) {
dev->dev_private = (void *)dev_priv;
- i810_dma_cleanup(dev);
- DRM_ERROR("Not enough space in the status page for"
+ i810_dma_cleanup(dev);
+ DRM_ERROR("Not enough space in the status page for"
" the freelist\n");
- return -ENOMEM;
+ return -ENOMEM;
}
dev->dev_private = (void *)dev_priv;
- return 0;
+ return 0;
}
/* i810 DRM version 1.1 used a smaller init structure with different
@@ -431,12 +432,12 @@ static int i810_dma_initialize(drm_device_t *dev,
* If it isn't then we have a v1.1 client. Fix up params.
* If it is, then we have a 1.2 client... get the rest of the data.
*/
-static int i810_dma_init_compat(drm_i810_init_t *init, unsigned long arg)
+static int i810_dma_init_compat(drm_i810_init_t * init, unsigned long arg)
{
/* Get v1.1 init data */
- if (copy_from_user(init, (drm_i810_pre12_init_t __user *)arg,
- sizeof(drm_i810_pre12_init_t))) {
+ if (copy_from_user(init, (drm_i810_pre12_init_t __user *) arg,
+ sizeof(drm_i810_pre12_init_t))) {
return -EFAULT;
}
@@ -444,7 +445,7 @@ static int i810_dma_init_compat(drm_i810_init_t *init, unsigned long arg)
/* This is a v1.2 client, just get the v1.2 init data */
DRM_INFO("Using POST v1.2 init.\n");
- if (copy_from_user(init, (drm_i810_init_t __user *)arg,
+ if (copy_from_user(init, (drm_i810_init_t __user *) arg,
sizeof(drm_i810_init_t))) {
return -EFAULT;
}
@@ -452,246 +453,239 @@ static int i810_dma_init_compat(drm_i810_init_t *init, unsigned long arg)
/* This is a v1.1 client, fix the params */
DRM_INFO("Using PRE v1.2 init.\n");
- init->pitch_bits = init->h;
- init->pitch = init->w;
- init->h = init->overlay_physical;
- init->w = init->overlay_offset;
- init->overlay_physical = 0;
- init->overlay_offset = 0;
+ init->pitch_bits = init->h;
+ init->pitch = init->w;
+ init->h = init->overlay_physical;
+ init->w = init->overlay_offset;
+ init->overlay_physical = 0;
+ init->overlay_offset = 0;
}
return 0;
}
static int i810_dma_init(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg)
+ unsigned int cmd, unsigned long arg)
{
- drm_file_t *priv = filp->private_data;
- drm_device_t *dev = priv->head->dev;
- drm_i810_private_t *dev_priv;
- drm_i810_init_t init;
- int retcode = 0;
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->head->dev;
+ drm_i810_private_t *dev_priv;
+ drm_i810_init_t init;
+ int retcode = 0;
/* Get only the init func */
- if (copy_from_user(&init, (void __user *)arg, sizeof(drm_i810_init_func_t)))
+ if (copy_from_user
+ (&init, (void __user *)arg, sizeof(drm_i810_init_func_t)))
return -EFAULT;
- switch(init.func) {
- case I810_INIT_DMA:
- /* This case is for backward compatibility. It
- * handles XFree 4.1.0 and 4.2.0, and has to
- * do some parameter checking as described below.
- * It will someday go away.
- */
- retcode = i810_dma_init_compat(&init, arg);
- if (retcode)
- return retcode;
-
- dev_priv = drm_alloc(sizeof(drm_i810_private_t),
- DRM_MEM_DRIVER);
- if (dev_priv == NULL)
- return -ENOMEM;
- retcode = i810_dma_initialize(dev, dev_priv, &init);
- break;
-
- default:
- case I810_INIT_DMA_1_4:
- DRM_INFO("Using v1.4 init.\n");
- if (copy_from_user(&init, (drm_i810_init_t __user *)arg,
- sizeof(drm_i810_init_t))) {
- return -EFAULT;
- }
- dev_priv = drm_alloc(sizeof(drm_i810_private_t),
- DRM_MEM_DRIVER);
- if (dev_priv == NULL)
- return -ENOMEM;
- retcode = i810_dma_initialize(dev, dev_priv, &init);
- break;
-
- case I810_CLEANUP_DMA:
- DRM_INFO("DMA Cleanup\n");
- retcode = i810_dma_cleanup(dev);
- break;
+ switch (init.func) {
+ case I810_INIT_DMA:
+ /* This case is for backward compatibility. It
+ * handles XFree 4.1.0 and 4.2.0, and has to
+ * do some parameter checking as described below.
+ * It will someday go away.
+ */
+ retcode = i810_dma_init_compat(&init, arg);
+ if (retcode)
+ return retcode;
+
+ dev_priv = drm_alloc(sizeof(drm_i810_private_t),
+ DRM_MEM_DRIVER);
+ if (dev_priv == NULL)
+ return -ENOMEM;
+ retcode = i810_dma_initialize(dev, dev_priv, &init);
+ break;
+
+ default:
+ case I810_INIT_DMA_1_4:
+ DRM_INFO("Using v1.4 init.\n");
+ if (copy_from_user(&init, (drm_i810_init_t __user *) arg,
+ sizeof(drm_i810_init_t))) {
+ return -EFAULT;
+ }
+ dev_priv = drm_alloc(sizeof(drm_i810_private_t),
+ DRM_MEM_DRIVER);
+ if (dev_priv == NULL)
+ return -ENOMEM;
+ retcode = i810_dma_initialize(dev, dev_priv, &init);
+ break;
+
+ case I810_CLEANUP_DMA:
+ DRM_INFO("DMA Cleanup\n");
+ retcode = i810_dma_cleanup(dev);
+ break;
}
- return retcode;
+ return retcode;
}
-
-
/* Most efficient way to verify state for the i810 is as it is
* emitted. Non-conformant state is silently dropped.
*
* Use 'volatile' & local var tmp to force the emitted values to be
* identical to the verified ones.
*/
-static void i810EmitContextVerified( drm_device_t *dev,
- volatile unsigned int *code )
+static void i810EmitContextVerified(drm_device_t * dev,
+ volatile unsigned int *code)
{
- drm_i810_private_t *dev_priv = dev->dev_private;
+ drm_i810_private_t *dev_priv = dev->dev_private;
int i, j = 0;
unsigned int tmp;
RING_LOCALS;
- BEGIN_LP_RING( I810_CTX_SETUP_SIZE );
+ BEGIN_LP_RING(I810_CTX_SETUP_SIZE);
- OUT_RING( GFX_OP_COLOR_FACTOR );
- OUT_RING( code[I810_CTXREG_CF1] );
+ OUT_RING(GFX_OP_COLOR_FACTOR);
+ OUT_RING(code[I810_CTXREG_CF1]);
- OUT_RING( GFX_OP_STIPPLE );
- OUT_RING( code[I810_CTXREG_ST1] );
+ OUT_RING(GFX_OP_STIPPLE);
+ OUT_RING(code[I810_CTXREG_ST1]);
- for ( i = 4 ; i < I810_CTX_SETUP_SIZE ; i++ ) {
+ for (i = 4; i < I810_CTX_SETUP_SIZE; i++) {
tmp = code[i];
- if ((tmp & (7<<29)) == (3<<29) &&
- (tmp & (0x1f<<24)) < (0x1d<<24))
- {
- OUT_RING( tmp );
+ if ((tmp & (7 << 29)) == (3 << 29) &&
+ (tmp & (0x1f << 24)) < (0x1d << 24)) {
+ OUT_RING(tmp);
j++;
- }
- else printk("constext state dropped!!!\n");
+ } else
+ printk("constext state dropped!!!\n");
}
if (j & 1)
- OUT_RING( 0 );
+ OUT_RING(0);
ADVANCE_LP_RING();
}
-static void i810EmitTexVerified( drm_device_t *dev,
- volatile unsigned int *code )
+static void i810EmitTexVerified(drm_device_t * dev, volatile unsigned int *code)
{
- drm_i810_private_t *dev_priv = dev->dev_private;
+ drm_i810_private_t *dev_priv = dev->dev_private;
int i, j = 0;
unsigned int tmp;
RING_LOCALS;
- BEGIN_LP_RING( I810_TEX_SETUP_SIZE );
+ BEGIN_LP_RING(I810_TEX_SETUP_SIZE);
- OUT_RING( GFX_OP_MAP_INFO );
- OUT_RING( code[I810_TEXREG_MI1] );
- OUT_RING( code[I810_TEXREG_MI2] );
- OUT_RING( code[I810_TEXREG_MI3] );
+ OUT_RING(GFX_OP_MAP_INFO);
+ OUT_RING(code[I810_TEXREG_MI1]);
+ OUT_RING(code[I810_TEXREG_MI2]);
+ OUT_RING(code[I810_TEXREG_MI3]);
- for ( i = 4 ; i < I810_TEX_SETUP_SIZE ; i++ ) {
+ for (i = 4; i < I810_TEX_SETUP_SIZE; i++) {
tmp = code[i];
- if ((tmp & (7<<29)) == (3<<29) &&
- (tmp & (0x1f<<24)) < (0x1d<<24))
- {
- OUT_RING( tmp );
+ if ((tmp & (7 << 29)) == (3 << 29) &&
+ (tmp & (0x1f << 24)) < (0x1d << 24)) {
+ OUT_RING(tmp);
j++;
- }
- else printk("texture state dropped!!!\n");
+ } else
+ printk("texture state dropped!!!\n");
}
if (j & 1)
- OUT_RING( 0 );
+ OUT_RING(0);
ADVANCE_LP_RING();
}
-
/* Need to do some additional checking when setting the dest buffer.
*/
-static void i810EmitDestVerified( drm_device_t *dev,
- volatile unsigned int *code )
+static void i810EmitDestVerified(drm_device_t * dev,
+ volatile unsigned int *code)
{
- drm_i810_private_t *dev_priv = dev->dev_private;
+ drm_i810_private_t *dev_priv = dev->dev_private;
unsigned int tmp;
RING_LOCALS;
- BEGIN_LP_RING( I810_DEST_SETUP_SIZE + 2 );
+ BEGIN_LP_RING(I810_DEST_SETUP_SIZE + 2);
tmp = code[I810_DESTREG_DI1];
if (tmp == dev_priv->front_di1 || tmp == dev_priv->back_di1) {
- OUT_RING( CMD_OP_DESTBUFFER_INFO );
- OUT_RING( tmp );
+ OUT_RING(CMD_OP_DESTBUFFER_INFO);
+ OUT_RING(tmp);
} else
- DRM_DEBUG("bad di1 %x (allow %x or %x)\n",
- tmp, dev_priv->front_di1, dev_priv->back_di1);
+ DRM_DEBUG("bad di1 %x (allow %x or %x)\n",
+ tmp, dev_priv->front_di1, dev_priv->back_di1);
/* invarient:
*/
- OUT_RING( CMD_OP_Z_BUFFER_INFO );
- OUT_RING( dev_priv->zi1 );
+ OUT_RING(CMD_OP_Z_BUFFER_INFO);
+ OUT_RING(dev_priv->zi1);
- OUT_RING( GFX_OP_DESTBUFFER_VARS );
- OUT_RING( code[I810_DESTREG_DV1] );
+ OUT_RING(GFX_OP_DESTBUFFER_VARS);
+ OUT_RING(code[I810_DESTREG_DV1]);
- OUT_RING( GFX_OP_DRAWRECT_INFO );
- OUT_RING( code[I810_DESTREG_DR1] );
- OUT_RING( code[I810_DESTREG_DR2] );
- OUT_RING( code[I810_DESTREG_DR3] );
- OUT_RING( code[I810_DESTREG_DR4] );
- OUT_RING( 0 );
+ OUT_RING(GFX_OP_DRAWRECT_INFO);
+ OUT_RING(code[I810_DESTREG_DR1]);
+ OUT_RING(code[I810_DESTREG_DR2]);
+ OUT_RING(code[I810_DESTREG_DR3]);
+ OUT_RING(code[I810_DESTREG_DR4]);
+ OUT_RING(0);
ADVANCE_LP_RING();
}
-
-
-static void i810EmitState( drm_device_t *dev )
+static void i810EmitState(drm_device_t * dev)
{
- drm_i810_private_t *dev_priv = dev->dev_private;
- drm_i810_sarea_t *sarea_priv = dev_priv->sarea_priv;
+ drm_i810_private_t *dev_priv = dev->dev_private;
+ drm_i810_sarea_t *sarea_priv = dev_priv->sarea_priv;
unsigned int dirty = sarea_priv->dirty;
-
+
DRM_DEBUG("%s %x\n", __FUNCTION__, dirty);
if (dirty & I810_UPLOAD_BUFFERS) {
- i810EmitDestVerified( dev, sarea_priv->BufferState );
+ i810EmitDestVerified(dev, sarea_priv->BufferState);
sarea_priv->dirty &= ~I810_UPLOAD_BUFFERS;
}
if (dirty & I810_UPLOAD_CTX) {
- i810EmitContextVerified( dev, sarea_priv->ContextState );
+ i810EmitContextVerified(dev, sarea_priv->ContextState);
sarea_priv->dirty &= ~I810_UPLOAD_CTX;
}
if (dirty & I810_UPLOAD_TEX0) {
- i810EmitTexVerified( dev, sarea_priv->TexState[0] );
+ i810EmitTexVerified(dev, sarea_priv->TexState[0]);
sarea_priv->dirty &= ~I810_UPLOAD_TEX0;
}
if (dirty & I810_UPLOAD_TEX1) {
- i810EmitTexVerified( dev, sarea_priv->TexState[1] );
+ i810EmitTexVerified(dev, sarea_priv->TexState[1]);
sarea_priv->dirty &= ~I810_UPLOAD_TEX1;
}
}
-
-
/* need to verify
*/
-static void i810_dma_dispatch_clear( drm_device_t *dev, int flags,
- unsigned int clear_color,
- unsigned int clear_zval )
+static void i810_dma_dispatch_clear(drm_device_t * dev, int flags,
+ unsigned int clear_color,
+ unsigned int clear_zval)
{
- drm_i810_private_t *dev_priv = dev->dev_private;
- drm_i810_sarea_t *sarea_priv = dev_priv->sarea_priv;
+ drm_i810_private_t *dev_priv = dev->dev_private;
+ drm_i810_sarea_t *sarea_priv = dev_priv->sarea_priv;
int nbox = sarea_priv->nbox;
drm_clip_rect_t *pbox = sarea_priv->boxes;
int pitch = dev_priv->pitch;
int cpp = 2;
int i;
RING_LOCALS;
-
- if ( dev_priv->current_page == 1 ) {
- unsigned int tmp = flags;
-
+
+ if (dev_priv->current_page == 1) {
+ unsigned int tmp = flags;
+
flags &= ~(I810_FRONT | I810_BACK);
- if (tmp & I810_FRONT) flags |= I810_BACK;
- if (tmp & I810_BACK) flags |= I810_FRONT;
+ if (tmp & I810_FRONT)
+ flags |= I810_BACK;
+ if (tmp & I810_BACK)
+ flags |= I810_FRONT;
}
- i810_kernel_lost_context(dev);
+ i810_kernel_lost_context(dev);
- if (nbox > I810_NR_SAREA_CLIPRECTS)
- nbox = I810_NR_SAREA_CLIPRECTS;
+ if (nbox > I810_NR_SAREA_CLIPRECTS)
+ nbox = I810_NR_SAREA_CLIPRECTS;
- for (i = 0 ; i < nbox ; i++, pbox++) {
+ for (i = 0; i < nbox; i++, pbox++) {
unsigned int x = pbox->x1;
unsigned int y = pbox->y1;
unsigned int width = (pbox->x2 - x) * cpp;
@@ -700,52 +694,48 @@ static void i810_dma_dispatch_clear( drm_device_t *dev, int flags,
if (pbox->x1 > pbox->x2 ||
pbox->y1 > pbox->y2 ||
- pbox->x2 > dev_priv->w ||
- pbox->y2 > dev_priv->h)
+ pbox->x2 > dev_priv->w || pbox->y2 > dev_priv->h)
continue;
- if ( flags & I810_FRONT ) {
- BEGIN_LP_RING( 6 );
- OUT_RING( BR00_BITBLT_CLIENT |
- BR00_OP_COLOR_BLT | 0x3 );
- OUT_RING( BR13_SOLID_PATTERN | (0xF0 << 16) | pitch );
- OUT_RING( (height << 16) | width );
- OUT_RING( start );
- OUT_RING( clear_color );
- OUT_RING( 0 );
+ if (flags & I810_FRONT) {
+ BEGIN_LP_RING(6);
+ OUT_RING(BR00_BITBLT_CLIENT | BR00_OP_COLOR_BLT | 0x3);
+ OUT_RING(BR13_SOLID_PATTERN | (0xF0 << 16) | pitch);
+ OUT_RING((height << 16) | width);
+ OUT_RING(start);
+ OUT_RING(clear_color);
+ OUT_RING(0);
ADVANCE_LP_RING();
}
- if ( flags & I810_BACK ) {
- BEGIN_LP_RING( 6 );
- OUT_RING( BR00_BITBLT_CLIENT |
- BR00_OP_COLOR_BLT | 0x3 );
- OUT_RING( BR13_SOLID_PATTERN | (0xF0 << 16) | pitch );
- OUT_RING( (height << 16) | width );
- OUT_RING( dev_priv->back_offset + start );
- OUT_RING( clear_color );
- OUT_RING( 0 );
+ if (flags & I810_BACK) {
+ BEGIN_LP_RING(6);
+ OUT_RING(BR00_BITBLT_CLIENT | BR00_OP_COLOR_BLT | 0x3);
+ OUT_RING(BR13_SOLID_PATTERN | (0xF0 << 16) | pitch);
+ OUT_RING((height << 16) | width);
+ OUT_RING(dev_priv->back_offset + start);
+ OUT_RING(clear_color);
+ OUT_RING(0);
ADVANCE_LP_RING();
}
- if ( flags & I810_DEPTH ) {
- BEGIN_LP_RING( 6 );
- OUT_RING( BR00_BITBLT_CLIENT |
- BR00_OP_COLOR_BLT | 0x3 );
- OUT_RING( BR13_SOLID_PATTERN | (0xF0 << 16) | pitch );
- OUT_RING( (height << 16) | width );
- OUT_RING( dev_priv->depth_offset + start );
- OUT_RING( clear_zval );
- OUT_RING( 0 );
+ if (flags & I810_DEPTH) {
+ BEGIN_LP_RING(6);
+ OUT_RING(BR00_BITBLT_CLIENT | BR00_OP_COLOR_BLT | 0x3);
+ OUT_RING(BR13_SOLID_PATTERN | (0xF0 << 16) | pitch);
+ OUT_RING((height << 16) | width);
+ OUT_RING(dev_priv->depth_offset + start);
+ OUT_RING(clear_zval);
+ OUT_RING(0);
ADVANCE_LP_RING();
}
}
}
-static void i810_dma_dispatch_swap( drm_device_t *dev )
+static void i810_dma_dispatch_swap(drm_device_t * dev)
{
- drm_i810_private_t *dev_priv = dev->dev_private;
- drm_i810_sarea_t *sarea_priv = dev_priv->sarea_priv;
+ drm_i810_private_t *dev_priv = dev->dev_private;
+ drm_i810_sarea_t *sarea_priv = dev_priv->sarea_priv;
int nbox = sarea_priv->nbox;
drm_clip_rect_t *pbox = sarea_priv->boxes;
int pitch = dev_priv->pitch;
@@ -755,75 +745,71 @@ static void i810_dma_dispatch_swap( drm_device_t *dev )
DRM_DEBUG("swapbuffers\n");
- i810_kernel_lost_context(dev);
+ i810_kernel_lost_context(dev);
- if (nbox > I810_NR_SAREA_CLIPRECTS)
- nbox = I810_NR_SAREA_CLIPRECTS;
+ if (nbox > I810_NR_SAREA_CLIPRECTS)
+ nbox = I810_NR_SAREA_CLIPRECTS;
- for (i = 0 ; i < nbox; i++, pbox++)
- {
+ for (i = 0; i < nbox; i++, pbox++) {
unsigned int w = pbox->x2 - pbox->x1;
unsigned int h = pbox->y2 - pbox->y1;
- unsigned int dst = pbox->x1*cpp + pbox->y1*pitch;
+ unsigned int dst = pbox->x1 * cpp + pbox->y1 * pitch;
unsigned int start = dst;
if (pbox->x1 > pbox->x2 ||
pbox->y1 > pbox->y2 ||
- pbox->x2 > dev_priv->w ||
- pbox->y2 > dev_priv->h)
+ pbox->x2 > dev_priv->w || pbox->y2 > dev_priv->h)
continue;
- BEGIN_LP_RING( 6 );
- OUT_RING( BR00_BITBLT_CLIENT | BR00_OP_SRC_COPY_BLT | 0x4 );
- OUT_RING( pitch | (0xCC << 16));
- OUT_RING( (h << 16) | (w * cpp));
+ BEGIN_LP_RING(6);
+ OUT_RING(BR00_BITBLT_CLIENT | BR00_OP_SRC_COPY_BLT | 0x4);
+ OUT_RING(pitch | (0xCC << 16));
+ OUT_RING((h << 16) | (w * cpp));
if (dev_priv->current_page == 0)
- OUT_RING(dev_priv->front_offset + start);
+ OUT_RING(dev_priv->front_offset + start);
else
- OUT_RING(dev_priv->back_offset + start);
- OUT_RING( pitch );
+ OUT_RING(dev_priv->back_offset + start);
+ OUT_RING(pitch);
if (dev_priv->current_page == 0)
- OUT_RING(dev_priv->back_offset + start);
+ OUT_RING(dev_priv->back_offset + start);
else
- OUT_RING(dev_priv->front_offset + start);
+ OUT_RING(dev_priv->front_offset + start);
ADVANCE_LP_RING();
}
}
-
-static void i810_dma_dispatch_vertex(drm_device_t *dev,
- drm_buf_t *buf,
- int discard,
- int used)
+static void i810_dma_dispatch_vertex(drm_device_t * dev,
+ drm_buf_t * buf, int discard, int used)
{
- drm_i810_private_t *dev_priv = dev->dev_private;
+ drm_i810_private_t *dev_priv = dev->dev_private;
drm_i810_buf_priv_t *buf_priv = buf->dev_private;
- drm_i810_sarea_t *sarea_priv = dev_priv->sarea_priv;
- drm_clip_rect_t *box = sarea_priv->boxes;
- int nbox = sarea_priv->nbox;
+ drm_i810_sarea_t *sarea_priv = dev_priv->sarea_priv;
+ drm_clip_rect_t *box = sarea_priv->boxes;
+ int nbox = sarea_priv->nbox;
unsigned long address = (unsigned long)buf->bus_address;
unsigned long start = address - dev->agp->base;
int i = 0;
- RING_LOCALS;
+ RING_LOCALS;
- i810_kernel_lost_context(dev);
+ i810_kernel_lost_context(dev);
- if (nbox > I810_NR_SAREA_CLIPRECTS)
+ if (nbox > I810_NR_SAREA_CLIPRECTS)
nbox = I810_NR_SAREA_CLIPRECTS;
- if (used > 4*1024)
+ if (used > 4 * 1024)
used = 0;
if (sarea_priv->dirty)
- i810EmitState( dev );
+ i810EmitState(dev);
if (buf_priv->currently_mapped == I810_BUF_MAPPED) {
unsigned int prim = (sarea_priv->vertex_prim & PR_MASK);
- *(u32 *)buf_priv->kernel_virtual = ((GFX_OP_PRIMITIVE | prim | ((used/4)-2)));
+ *(u32 *) buf_priv->kernel_virtual =
+ ((GFX_OP_PRIMITIVE | prim | ((used / 4) - 2)));
if (used & 4) {
- *(u32 *)((u32)buf_priv->kernel_virtual + used) = 0;
+ *(u32 *) ((u32) buf_priv->kernel_virtual + used) = 0;
used += 4;
}
@@ -834,19 +820,20 @@ static void i810_dma_dispatch_vertex(drm_device_t *dev,
do {
if (i < nbox) {
BEGIN_LP_RING(4);
- OUT_RING( GFX_OP_SCISSOR | SC_UPDATE_SCISSOR |
- SC_ENABLE );
- OUT_RING( GFX_OP_SCISSOR_INFO );
- OUT_RING( box[i].x1 | (box[i].y1<<16) );
- OUT_RING( (box[i].x2-1) | ((box[i].y2-1)<<16) );
+ OUT_RING(GFX_OP_SCISSOR | SC_UPDATE_SCISSOR |
+ SC_ENABLE);
+ OUT_RING(GFX_OP_SCISSOR_INFO);
+ OUT_RING(box[i].x1 | (box[i].y1 << 16));
+ OUT_RING((box[i].x2 -
+ 1) | ((box[i].y2 - 1) << 16));
ADVANCE_LP_RING();
}
BEGIN_LP_RING(4);
- OUT_RING( CMD_OP_BATCH_BUFFER );
- OUT_RING( start | BB1_PROTECTED );
- OUT_RING( start + used - 4 );
- OUT_RING( 0 );
+ OUT_RING(CMD_OP_BATCH_BUFFER);
+ OUT_RING(start | BB1_PROTECTED);
+ OUT_RING(start + used - 4);
+ OUT_RING(0);
ADVANCE_LP_RING();
} while (++i < nbox);
@@ -855,59 +842,59 @@ static void i810_dma_dispatch_vertex(drm_device_t *dev,
if (discard) {
dev_priv->counter++;
- (void) cmpxchg(buf_priv->in_use, I810_BUF_CLIENT,
- I810_BUF_HARDWARE);
+ (void)cmpxchg(buf_priv->in_use, I810_BUF_CLIENT,
+ I810_BUF_HARDWARE);
BEGIN_LP_RING(8);
- OUT_RING( CMD_STORE_DWORD_IDX );
- OUT_RING( 20 );
- OUT_RING( dev_priv->counter );
- OUT_RING( CMD_STORE_DWORD_IDX );
- OUT_RING( buf_priv->my_use_idx );
- OUT_RING( I810_BUF_FREE );
- OUT_RING( CMD_REPORT_HEAD );
- OUT_RING( 0 );
+ OUT_RING(CMD_STORE_DWORD_IDX);
+ OUT_RING(20);
+ OUT_RING(dev_priv->counter);
+ OUT_RING(CMD_STORE_DWORD_IDX);
+ OUT_RING(buf_priv->my_use_idx);
+ OUT_RING(I810_BUF_FREE);
+ OUT_RING(CMD_REPORT_HEAD);
+ OUT_RING(0);
ADVANCE_LP_RING();
}
}
-static void i810_dma_dispatch_flip( drm_device_t *dev )
+static void i810_dma_dispatch_flip(drm_device_t * dev)
{
- drm_i810_private_t *dev_priv = dev->dev_private;
+ drm_i810_private_t *dev_priv = dev->dev_private;
int pitch = dev_priv->pitch;
RING_LOCALS;
- DRM_DEBUG( "%s: page=%d pfCurrentPage=%d\n",
- __FUNCTION__,
- dev_priv->current_page,
- dev_priv->sarea_priv->pf_current_page);
-
- i810_kernel_lost_context(dev);
+ DRM_DEBUG("%s: page=%d pfCurrentPage=%d\n",
+ __FUNCTION__,
+ dev_priv->current_page,
+ dev_priv->sarea_priv->pf_current_page);
+
+ i810_kernel_lost_context(dev);
- BEGIN_LP_RING( 2 );
- OUT_RING( INST_PARSER_CLIENT | INST_OP_FLUSH | INST_FLUSH_MAP_CACHE );
- OUT_RING( 0 );
+ BEGIN_LP_RING(2);
+ OUT_RING(INST_PARSER_CLIENT | INST_OP_FLUSH | INST_FLUSH_MAP_CACHE);
+ OUT_RING(0);
ADVANCE_LP_RING();
- BEGIN_LP_RING( I810_DEST_SETUP_SIZE + 2 );
+ BEGIN_LP_RING(I810_DEST_SETUP_SIZE + 2);
/* On i815 at least ASYNC is buggy */
/* pitch<<5 is from 11.2.8 p158,
its the pitch / 8 then left shifted 8,
so (pitch >> 3) << 8 */
- OUT_RING( CMD_OP_FRONTBUFFER_INFO | (pitch<<5) /*| ASYNC_FLIP */ );
- if ( dev_priv->current_page == 0 ) {
- OUT_RING( dev_priv->back_offset );
+ OUT_RING(CMD_OP_FRONTBUFFER_INFO | (pitch << 5) /*| ASYNC_FLIP */ );
+ if (dev_priv->current_page == 0) {
+ OUT_RING(dev_priv->back_offset);
dev_priv->current_page = 1;
} else {
- OUT_RING( dev_priv->front_offset );
+ OUT_RING(dev_priv->front_offset);
dev_priv->current_page = 0;
}
OUT_RING(0);
ADVANCE_LP_RING();
BEGIN_LP_RING(2);
- OUT_RING( CMD_OP_WAIT_FOR_EVENT | WAIT_FOR_PLANE_A_FLIP );
- OUT_RING( 0 );
+ OUT_RING(CMD_OP_WAIT_FOR_EVENT | WAIT_FOR_PLANE_A_FLIP);
+ OUT_RING(0);
ADVANCE_LP_RING();
/* Increment the frame counter. The client-side 3D driver must
@@ -918,46 +905,46 @@ static void i810_dma_dispatch_flip( drm_device_t *dev )
}
-static void i810_dma_quiescent(drm_device_t *dev)
+static void i810_dma_quiescent(drm_device_t * dev)
{
- drm_i810_private_t *dev_priv = dev->dev_private;
- RING_LOCALS;
+ drm_i810_private_t *dev_priv = dev->dev_private;
+ RING_LOCALS;
/* printk("%s\n", __FUNCTION__); */
- i810_kernel_lost_context(dev);
+ i810_kernel_lost_context(dev);
- BEGIN_LP_RING(4);
- OUT_RING( INST_PARSER_CLIENT | INST_OP_FLUSH | INST_FLUSH_MAP_CACHE );
- OUT_RING( CMD_REPORT_HEAD );
- OUT_RING( 0 );
- OUT_RING( 0 );
- ADVANCE_LP_RING();
+ BEGIN_LP_RING(4);
+ OUT_RING(INST_PARSER_CLIENT | INST_OP_FLUSH | INST_FLUSH_MAP_CACHE);
+ OUT_RING(CMD_REPORT_HEAD);
+ OUT_RING(0);
+ OUT_RING(0);
+ ADVANCE_LP_RING();
- i810_wait_ring( dev, dev_priv->ring.Size - 8 );
+ i810_wait_ring(dev, dev_priv->ring.Size - 8);
}
-static int i810_flush_queue(drm_device_t *dev)
+static int i810_flush_queue(drm_device_t * dev)
{
- drm_i810_private_t *dev_priv = dev->dev_private;
+ drm_i810_private_t *dev_priv = dev->dev_private;
drm_device_dma_t *dma = dev->dma;
- int i, ret = 0;
- RING_LOCALS;
-
+ int i, ret = 0;
+ RING_LOCALS;
+
/* printk("%s\n", __FUNCTION__); */
- i810_kernel_lost_context(dev);
+ i810_kernel_lost_context(dev);
- BEGIN_LP_RING(2);
- OUT_RING( CMD_REPORT_HEAD );
- OUT_RING( 0 );
- ADVANCE_LP_RING();
+ BEGIN_LP_RING(2);
+ OUT_RING(CMD_REPORT_HEAD);
+ OUT_RING(0);
+ ADVANCE_LP_RING();
- i810_wait_ring( dev, dev_priv->ring.Size - 8 );
+ i810_wait_ring(dev, dev_priv->ring.Size - 8);
- for (i = 0; i < dma->buf_count; i++) {
- drm_buf_t *buf = dma->buflist[ i ];
- drm_i810_buf_priv_t *buf_priv = buf->dev_private;
+ for (i = 0; i < dma->buf_count; i++) {
+ drm_buf_t *buf = dma->buflist[i];
+ drm_i810_buf_priv_t *buf_priv = buf->dev_private;
int used = cmpxchg(buf_priv->in_use, I810_BUF_HARDWARE,
I810_BUF_FREE);
@@ -968,24 +955,27 @@ static int i810_flush_queue(drm_device_t *dev)
DRM_DEBUG("still on client\n");
}
- return ret;
+ return ret;
}
/* Must be called with the lock held */
-void i810_reclaim_buffers(drm_device_t *dev, struct file *filp)
+void i810_reclaim_buffers(drm_device_t * dev, struct file *filp)
{
drm_device_dma_t *dma = dev->dma;
- int i;
+ int i;
- if (!dma) return;
- if (!dev->dev_private) return;
- if (!dma->buflist) return;
+ if (!dma)
+ return;
+ if (!dev->dev_private)
+ return;
+ if (!dma->buflist)
+ return;
- i810_flush_queue(dev);
+ i810_flush_queue(dev);
for (i = 0; i < dma->buf_count; i++) {
- drm_buf_t *buf = dma->buflist[ i ];
- drm_i810_buf_priv_t *buf_priv = buf->dev_private;
+ drm_buf_t *buf = dma->buflist[i];
+ drm_i810_buf_priv_t *buf_priv = buf->dev_private;
if (buf->filp == filp && buf_priv) {
int used = cmpxchg(buf_priv->in_use, I810_BUF_CLIENT,
@@ -994,7 +984,7 @@ void i810_reclaim_buffers(drm_device_t *dev, struct file *filp)
if (used == I810_BUF_CLIENT)
DRM_DEBUG("reclaimed from client\n");
if (buf_priv->currently_mapped == I810_BUF_MAPPED)
- buf_priv->currently_mapped = I810_BUF_UNMAPPED;
+ buf_priv->currently_mapped = I810_BUF_UNMAPPED;
}
}
}
@@ -1002,29 +992,29 @@ void i810_reclaim_buffers(drm_device_t *dev, struct file *filp)
static int i810_flush_ioctl(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg)
{
- drm_file_t *priv = filp->private_data;
- drm_device_t *dev = priv->head->dev;
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->head->dev;
LOCK_TEST_WITH_RETURN(dev, filp);
- i810_flush_queue(dev);
- return 0;
+ i810_flush_queue(dev);
+ return 0;
}
-
static int i810_dma_vertex(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg)
+ unsigned int cmd, unsigned long arg)
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->head->dev;
drm_device_dma_t *dma = dev->dma;
- drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private;
- u32 *hw_status = dev_priv->hw_status_page;
- drm_i810_sarea_t *sarea_priv = (drm_i810_sarea_t *)
- dev_priv->sarea_priv;
+ drm_i810_private_t *dev_priv = (drm_i810_private_t *) dev->dev_private;
+ u32 *hw_status = dev_priv->hw_status_page;
+ drm_i810_sarea_t *sarea_priv = (drm_i810_sarea_t *)
+ dev_priv->sarea_priv;
drm_i810_vertex_t vertex;
- if (copy_from_user(&vertex, (drm_i810_vertex_t __user *)arg, sizeof(vertex)))
+ if (copy_from_user
+ (&vertex, (drm_i810_vertex_t __user *) arg, sizeof(vertex)))
return -EFAULT;
LOCK_TEST_WITH_RETURN(dev, filp);
@@ -1032,48 +1022,46 @@ static int i810_dma_vertex(struct inode *inode, struct file *filp,
DRM_DEBUG("i810 dma vertex, idx %d used %d discard %d\n",
vertex.idx, vertex.used, vertex.discard);
- if (vertex.idx < 0 || vertex.idx > dma->buf_count)
+ if (vertex.idx < 0 || vertex.idx > dma->buf_count)
return -EINVAL;
- i810_dma_dispatch_vertex( dev,
- dma->buflist[ vertex.idx ],
- vertex.discard, vertex.used );
+ i810_dma_dispatch_vertex(dev,
+ dma->buflist[vertex.idx],
+ vertex.discard, vertex.used);
- atomic_add(vertex.used, &dev->counts[_DRM_STAT_SECONDARY]);
+ atomic_add(vertex.used, &dev->counts[_DRM_STAT_SECONDARY]);
atomic_inc(&dev->counts[_DRM_STAT_DMA]);
- sarea_priv->last_enqueue = dev_priv->counter-1;
- sarea_priv->last_dispatch = (int) hw_status[5];
+ sarea_priv->last_enqueue = dev_priv->counter - 1;
+ sarea_priv->last_dispatch = (int)hw_status[5];
return 0;
}
-
-
static int i810_clear_bufs(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg)
+ unsigned int cmd, unsigned long arg)
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->head->dev;
drm_i810_clear_t clear;
- if (copy_from_user(&clear, (drm_i810_clear_t __user *)arg, sizeof(clear)))
+ if (copy_from_user
+ (&clear, (drm_i810_clear_t __user *) arg, sizeof(clear)))
return -EFAULT;
LOCK_TEST_WITH_RETURN(dev, filp);
- /* GH: Someone's doing nasty things... */
- if (!dev->dev_private) {
- return -EINVAL;
- }
+ /* GH: Someone's doing nasty things... */
+ if (!dev->dev_private) {
+ return -EINVAL;
+ }
- i810_dma_dispatch_clear( dev, clear.flags,
- clear.clear_color,
- clear.clear_depth );
- return 0;
+ i810_dma_dispatch_clear(dev, clear.flags,
+ clear.clear_color, clear.clear_depth);
+ return 0;
}
static int i810_swap_bufs(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg)
+ unsigned int cmd, unsigned long arg)
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->head->dev;
@@ -1082,37 +1070,37 @@ static int i810_swap_bufs(struct inode *inode, struct file *filp,
LOCK_TEST_WITH_RETURN(dev, filp);
- i810_dma_dispatch_swap( dev );
- return 0;
+ i810_dma_dispatch_swap(dev);
+ return 0;
}
static int i810_getage(struct inode *inode, struct file *filp, unsigned int cmd,
- unsigned long arg)
+ unsigned long arg)
{
- drm_file_t *priv = filp->private_data;
- drm_device_t *dev = priv->head->dev;
- drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private;
- u32 *hw_status = dev_priv->hw_status_page;
- drm_i810_sarea_t *sarea_priv = (drm_i810_sarea_t *)
- dev_priv->sarea_priv;
-
- sarea_priv->last_dispatch = (int) hw_status[5];
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->head->dev;
+ drm_i810_private_t *dev_priv = (drm_i810_private_t *) dev->dev_private;
+ u32 *hw_status = dev_priv->hw_status_page;
+ drm_i810_sarea_t *sarea_priv = (drm_i810_sarea_t *)
+ dev_priv->sarea_priv;
+
+ sarea_priv->last_dispatch = (int)hw_status[5];
return 0;
}
static int i810_getbuf(struct inode *inode, struct file *filp, unsigned int cmd,
- unsigned long arg)
+ unsigned long arg)
{
- drm_file_t *priv = filp->private_data;
- drm_device_t *dev = priv->head->dev;
- int retcode = 0;
- drm_i810_dma_t d;
- drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private;
- u32 *hw_status = dev_priv->hw_status_page;
- drm_i810_sarea_t *sarea_priv = (drm_i810_sarea_t *)
- dev_priv->sarea_priv;
-
- if (copy_from_user(&d, (drm_i810_dma_t __user *)arg, sizeof(d)))
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->head->dev;
+ int retcode = 0;
+ drm_i810_dma_t d;
+ drm_i810_private_t *dev_priv = (drm_i810_private_t *) dev->dev_private;
+ u32 *hw_status = dev_priv->hw_status_page;
+ drm_i810_sarea_t *sarea_priv = (drm_i810_sarea_t *)
+ dev_priv->sarea_priv;
+
+ if (copy_from_user(&d, (drm_i810_dma_t __user *) arg, sizeof(d)))
return -EFAULT;
LOCK_TEST_WITH_RETURN(dev, filp);
@@ -1124,29 +1112,29 @@ static int i810_getbuf(struct inode *inode, struct file *filp, unsigned int cmd,
DRM_DEBUG("i810_dma: %d returning %d, granted = %d\n",
current->pid, retcode, d.granted);
- if (copy_to_user((drm_dma_t __user *)arg, &d, sizeof(d)))
+ if (copy_to_user((drm_dma_t __user *) arg, &d, sizeof(d)))
return -EFAULT;
- sarea_priv->last_dispatch = (int) hw_status[5];
+ sarea_priv->last_dispatch = (int)hw_status[5];
return retcode;
}
static int i810_copybuf(struct inode *inode,
- struct file *filp, unsigned int cmd, unsigned long arg)
+ struct file *filp, unsigned int cmd, unsigned long arg)
{
/* Never copy - 2.4.x doesn't need it */
return 0;
}
static int i810_docopy(struct inode *inode, struct file *filp, unsigned int cmd,
- unsigned long arg)
+ unsigned long arg)
{
/* Never copy - 2.4.x doesn't need it */
return 0;
}
-static void i810_dma_dispatch_mc(drm_device_t *dev, drm_buf_t *buf, int used,
- unsigned int last_render)
+static void i810_dma_dispatch_mc(drm_device_t * dev, drm_buf_t * buf, int used,
+ unsigned int last_render)
{
drm_i810_private_t *dev_priv = dev->dev_private;
drm_i810_buf_priv_t *buf_priv = buf->dev_private;
@@ -1158,19 +1146,17 @@ static void i810_dma_dispatch_mc(drm_device_t *dev, drm_buf_t *buf, int used,
i810_kernel_lost_context(dev);
- u = cmpxchg(buf_priv->in_use, I810_BUF_CLIENT,
- I810_BUF_HARDWARE);
+ u = cmpxchg(buf_priv->in_use, I810_BUF_CLIENT, I810_BUF_HARDWARE);
if (u != I810_BUF_CLIENT) {
DRM_DEBUG("MC found buffer that isn't mine!\n");
}
- if (used > 4*1024)
+ if (used > 4 * 1024)
used = 0;
sarea_priv->dirty = 0x7f;
- DRM_DEBUG("dispatch mc addr 0x%lx, used 0x%x\n",
- address, used);
+ DRM_DEBUG("dispatch mc addr 0x%lx, used 0x%x\n", address, used);
dev_priv->counter++;
DRM_DEBUG("dispatch counter : %ld\n", dev_priv->counter);
@@ -1181,46 +1167,45 @@ static void i810_dma_dispatch_mc(drm_device_t *dev, drm_buf_t *buf, int used,
if (buf_priv->currently_mapped == I810_BUF_MAPPED) {
if (used & 4) {
- *(u32 *)((u32)buf_priv->virtual + used) = 0;
+ *(u32 *) ((u32) buf_priv->virtual + used) = 0;
used += 4;
}
i810_unmap_buffer(buf);
}
BEGIN_LP_RING(4);
- OUT_RING( CMD_OP_BATCH_BUFFER );
- OUT_RING( start | BB1_PROTECTED );
- OUT_RING( start + used - 4 );
- OUT_RING( 0 );
+ OUT_RING(CMD_OP_BATCH_BUFFER);
+ OUT_RING(start | BB1_PROTECTED);
+ OUT_RING(start + used - 4);
+ OUT_RING(0);
ADVANCE_LP_RING();
-
BEGIN_LP_RING(8);
- OUT_RING( CMD_STORE_DWORD_IDX );
- OUT_RING( buf_priv->my_use_idx );
- OUT_RING( I810_BUF_FREE );
- OUT_RING( 0 );
-
- OUT_RING( CMD_STORE_DWORD_IDX );
- OUT_RING( 16 );
- OUT_RING( last_render );
- OUT_RING( 0 );
+ OUT_RING(CMD_STORE_DWORD_IDX);
+ OUT_RING(buf_priv->my_use_idx);
+ OUT_RING(I810_BUF_FREE);
+ OUT_RING(0);
+
+ OUT_RING(CMD_STORE_DWORD_IDX);
+ OUT_RING(16);
+ OUT_RING(last_render);
+ OUT_RING(0);
ADVANCE_LP_RING();
}
static int i810_dma_mc(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg)
+ unsigned int cmd, unsigned long arg)
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->head->dev;
drm_device_dma_t *dma = dev->dma;
- drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private;
+ drm_i810_private_t *dev_priv = (drm_i810_private_t *) dev->dev_private;
u32 *hw_status = dev_priv->hw_status_page;
drm_i810_sarea_t *sarea_priv = (drm_i810_sarea_t *)
- dev_priv->sarea_priv;
+ dev_priv->sarea_priv;
drm_i810_mc_t mc;
- if (copy_from_user(&mc, (drm_i810_mc_t __user *)arg, sizeof(mc)))
+ if (copy_from_user(&mc, (drm_i810_mc_t __user *) arg, sizeof(mc)))
return -EFAULT;
LOCK_TEST_WITH_RETURN(dev, filp);
@@ -1229,12 +1214,12 @@ static int i810_dma_mc(struct inode *inode, struct file *filp,
return -EINVAL;
i810_dma_dispatch_mc(dev, dma->buflist[mc.idx], mc.used,
- mc.last_render );
+ mc.last_render);
atomic_add(mc.used, &dev->counts[_DRM_STAT_SECONDARY]);
atomic_inc(&dev->counts[_DRM_STAT_DMA]);
- sarea_priv->last_enqueue = dev_priv->counter-1;
- sarea_priv->last_dispatch = (int) hw_status[5];
+ sarea_priv->last_enqueue = dev_priv->counter - 1;
+ sarea_priv->last_dispatch = (int)hw_status[5];
return 0;
}
@@ -1244,22 +1229,23 @@ static int i810_rstatus(struct inode *inode, struct file *filp,
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->head->dev;
- drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private;
+ drm_i810_private_t *dev_priv = (drm_i810_private_t *) dev->dev_private;
- return (int)(((u32 *)(dev_priv->hw_status_page))[4]);
+ return (int)(((u32 *) (dev_priv->hw_status_page))[4]);
}
static int i810_ov0_info(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg)
+ unsigned int cmd, unsigned long arg)
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->head->dev;
- drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private;
+ drm_i810_private_t *dev_priv = (drm_i810_private_t *) dev->dev_private;
drm_i810_overlay_t data;
data.offset = dev_priv->overlay_offset;
data.physical = dev_priv->overlay_physical;
- if (copy_to_user((drm_i810_overlay_t __user *)arg,&data,sizeof(data)))
+ if (copy_to_user
+ ((drm_i810_overlay_t __user *) arg, &data, sizeof(data)))
return -EFAULT;
return 0;
}
@@ -1269,7 +1255,7 @@ static int i810_fstatus(struct inode *inode, struct file *filp,
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->head->dev;
- drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private;
+ drm_i810_private_t *dev_priv = (drm_i810_private_t *) dev->dev_private;
LOCK_TEST_WITH_RETURN(dev, filp);
@@ -1277,47 +1263,46 @@ static int i810_fstatus(struct inode *inode, struct file *filp,
}
static int i810_ov0_flip(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg)
+ unsigned int cmd, unsigned long arg)
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->head->dev;
- drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private;
+ drm_i810_private_t *dev_priv = (drm_i810_private_t *) dev->dev_private;
LOCK_TEST_WITH_RETURN(dev, filp);
//Tell the overlay to update
- I810_WRITE(0x30000,dev_priv->overlay_physical | 0x80000000);
+ I810_WRITE(0x30000, dev_priv->overlay_physical | 0x80000000);
return 0;
}
-
/* Not sure why this isn't set all the time:
- */
-static void i810_do_init_pageflip( drm_device_t *dev )
+ */
+static void i810_do_init_pageflip(drm_device_t * dev)
{
drm_i810_private_t *dev_priv = dev->dev_private;
-
+
DRM_DEBUG("%s\n", __FUNCTION__);
dev_priv->page_flipping = 1;
dev_priv->current_page = 0;
dev_priv->sarea_priv->pf_current_page = dev_priv->current_page;
}
-static int i810_do_cleanup_pageflip( drm_device_t *dev )
+static int i810_do_cleanup_pageflip(drm_device_t * dev)
{
drm_i810_private_t *dev_priv = dev->dev_private;
DRM_DEBUG("%s\n", __FUNCTION__);
if (dev_priv->current_page != 0)
- i810_dma_dispatch_flip( dev );
+ i810_dma_dispatch_flip(dev);
dev_priv->page_flipping = 0;
return 0;
}
static int i810_flip_bufs(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg)
+ unsigned int cmd, unsigned long arg)
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->head->dev;
@@ -1327,19 +1312,19 @@ static int i810_flip_bufs(struct inode *inode, struct file *filp,
LOCK_TEST_WITH_RETURN(dev, filp);
- if (!dev_priv->page_flipping)
- i810_do_init_pageflip( dev );
+ if (!dev_priv->page_flipping)
+ i810_do_init_pageflip(dev);
- i810_dma_dispatch_flip( dev );
- return 0;
+ i810_dma_dispatch_flip(dev);
+ return 0;
}
-void i810_driver_pretakedown(drm_device_t *dev)
+void i810_driver_pretakedown(drm_device_t * dev)
{
- i810_dma_cleanup( dev );
+ i810_dma_cleanup(dev);
}
-void i810_driver_prerelease(drm_device_t *dev, DRMFILE filp)
+void i810_driver_prerelease(drm_device_t * dev, DRMFILE filp)
{
if (dev->dev_private) {
drm_i810_private_t *dev_priv = dev->dev_private;
@@ -1349,33 +1334,33 @@ void i810_driver_prerelease(drm_device_t *dev, DRMFILE filp)
}
}
-void i810_driver_release(drm_device_t *dev, struct file *filp)
+void i810_driver_release(drm_device_t * dev, struct file *filp)
{
i810_reclaim_buffers(dev, filp);
}
-int i810_driver_dma_quiescent(drm_device_t *dev)
+int i810_driver_dma_quiescent(drm_device_t * dev)
{
- i810_dma_quiescent( dev );
+ i810_dma_quiescent(dev);
return 0;
}
drm_ioctl_desc_t i810_ioctls[] = {
- [DRM_IOCTL_NR(DRM_I810_INIT)] = { i810_dma_init, 1, 1 },
- [DRM_IOCTL_NR(DRM_I810_VERTEX)] = { i810_dma_vertex, 1, 0 },
- [DRM_IOCTL_NR(DRM_I810_CLEAR)] = { i810_clear_bufs, 1, 0 },
- [DRM_IOCTL_NR(DRM_I810_FLUSH)] = { i810_flush_ioctl, 1, 0 },
- [DRM_IOCTL_NR(DRM_I810_GETAGE)] = { i810_getage, 1, 0 },
- [DRM_IOCTL_NR(DRM_I810_GETBUF)] = { i810_getbuf, 1, 0 },
- [DRM_IOCTL_NR(DRM_I810_SWAP)] = { i810_swap_bufs, 1, 0 },
- [DRM_IOCTL_NR(DRM_I810_COPY)] = { i810_copybuf, 1, 0 },
- [DRM_IOCTL_NR(DRM_I810_DOCOPY)] = { i810_docopy, 1, 0 },
- [DRM_IOCTL_NR(DRM_I810_OV0INFO)] = { i810_ov0_info, 1, 0 },
- [DRM_IOCTL_NR(DRM_I810_FSTATUS)] = { i810_fstatus, 1, 0 },
- [DRM_IOCTL_NR(DRM_I810_OV0FLIP)] = { i810_ov0_flip, 1, 0 },
- [DRM_IOCTL_NR(DRM_I810_MC)] = { i810_dma_mc, 1, 1 },
- [DRM_IOCTL_NR(DRM_I810_RSTATUS)] = { i810_rstatus, 1, 0 },
- [DRM_IOCTL_NR(DRM_I810_FLIP)] = { i810_flip_bufs, 1, 0 }
+ [DRM_IOCTL_NR(DRM_I810_INIT)] = {i810_dma_init, 1, 1},
+ [DRM_IOCTL_NR(DRM_I810_VERTEX)] = {i810_dma_vertex, 1, 0},
+ [DRM_IOCTL_NR(DRM_I810_CLEAR)] = {i810_clear_bufs, 1, 0},
+ [DRM_IOCTL_NR(DRM_I810_FLUSH)] = {i810_flush_ioctl, 1, 0},
+ [DRM_IOCTL_NR(DRM_I810_GETAGE)] = {i810_getage, 1, 0},
+ [DRM_IOCTL_NR(DRM_I810_GETBUF)] = {i810_getbuf, 1, 0},
+ [DRM_IOCTL_NR(DRM_I810_SWAP)] = {i810_swap_bufs, 1, 0},
+ [DRM_IOCTL_NR(DRM_I810_COPY)] = {i810_copybuf, 1, 0},
+ [DRM_IOCTL_NR(DRM_I810_DOCOPY)] = {i810_docopy, 1, 0},
+ [DRM_IOCTL_NR(DRM_I810_OV0INFO)] = {i810_ov0_info, 1, 0},
+ [DRM_IOCTL_NR(DRM_I810_FSTATUS)] = {i810_fstatus, 1, 0},
+ [DRM_IOCTL_NR(DRM_I810_OV0FLIP)] = {i810_ov0_flip, 1, 0},
+ [DRM_IOCTL_NR(DRM_I810_MC)] = {i810_dma_mc, 1, 1},
+ [DRM_IOCTL_NR(DRM_I810_RSTATUS)] = {i810_rstatus, 1, 0},
+ [DRM_IOCTL_NR(DRM_I810_FLIP)] = {i810_flip_bufs, 1, 0}
};
int i810_max_ioctl = DRM_ARRAY_SIZE(i810_ioctls);
diff --git a/drivers/char/drm/i810_drm.h b/drivers/char/drm/i810_drm.h
index 73ac40563b1d..2deb925a94f3 100644
--- a/drivers/char/drm/i810_drm.h
+++ b/drivers/char/drm/i810_drm.h
@@ -19,21 +19,20 @@
#define I810_LOG_MIN_TEX_REGION_SIZE 16
#endif
-#define I810_UPLOAD_TEX0IMAGE 0x1 /* handled clientside */
-#define I810_UPLOAD_TEX1IMAGE 0x2 /* handled clientside */
+#define I810_UPLOAD_TEX0IMAGE 0x1 /* handled clientside */
+#define I810_UPLOAD_TEX1IMAGE 0x2 /* handled clientside */
#define I810_UPLOAD_CTX 0x4
#define I810_UPLOAD_BUFFERS 0x8
#define I810_UPLOAD_TEX0 0x10
#define I810_UPLOAD_TEX1 0x20
#define I810_UPLOAD_CLIPRECTS 0x40
-
/* Indices into buf.Setup where various bits of state are mirrored per
* context and per buffer. These can be fired at the card as a unit,
* or in a piecewise fashion as required.
*/
-/* Destbuffer state
+/* Destbuffer state
* - backbuffer linear offset and pitch -- invarient in the current dri
* - zbuffer linear offset and pitch -- also invarient
* - drawing origin in back and depth buffers.
@@ -55,13 +54,13 @@
/* Context state
*/
#define I810_CTXREG_CF0 0 /* GFX_OP_COLOR_FACTOR */
-#define I810_CTXREG_CF1 1
-#define I810_CTXREG_ST0 2 /* GFX_OP_STIPPLE */
+#define I810_CTXREG_CF1 1
+#define I810_CTXREG_ST0 2 /* GFX_OP_STIPPLE */
#define I810_CTXREG_ST1 3
#define I810_CTXREG_VF 4 /* GFX_OP_VERTEX_FMT */
#define I810_CTXREG_MT 5 /* GFX_OP_MAP_TEXELS */
#define I810_CTXREG_MC0 6 /* GFX_OP_MAP_COLOR_STAGES - stage 0 */
-#define I810_CTXREG_MC1 7 /* GFX_OP_MAP_COLOR_STAGES - stage 1 */
+#define I810_CTXREG_MC1 7 /* GFX_OP_MAP_COLOR_STAGES - stage 1 */
#define I810_CTXREG_MC2 8 /* GFX_OP_MAP_COLOR_STAGES - stage 2 */
#define I810_CTXREG_MA0 9 /* GFX_OP_MAP_ALPHA_STAGES - stage 0 */
#define I810_CTXREG_MA1 10 /* GFX_OP_MAP_ALPHA_STAGES - stage 1 */
@@ -74,14 +73,14 @@
#define I810_CTXREG_PV 17 /* GFX_OP_PV_RULE -- Invarient! */
#define I810_CTXREG_ZA 18 /* GFX_OP_ZBIAS_ALPHAFUNC */
#define I810_CTXREG_AA 19 /* GFX_OP_ANTIALIAS */
-#define I810_CTX_SETUP_SIZE 20
+#define I810_CTX_SETUP_SIZE 20
/* Texture state (per tex unit)
*/
#define I810_TEXREG_MI0 0 /* GFX_OP_MAP_INFO (4 dwords) */
-#define I810_TEXREG_MI1 1
-#define I810_TEXREG_MI2 2
-#define I810_TEXREG_MI3 3
+#define I810_TEXREG_MI1 1
+#define I810_TEXREG_MI2 2
+#define I810_TEXREG_MI3 3
#define I810_TEXREG_MF 4 /* GFX_OP_MAP_FILTER */
#define I810_TEXREG_MLC 5 /* GFX_OP_MAP_LOD_CTL */
#define I810_TEXREG_MLL 6 /* GFX_OP_MAP_LOD_LIMITS */
@@ -98,7 +97,7 @@ typedef enum _drm_i810_init_func {
I810_INIT_DMA = 0x01,
I810_CLEANUP_DMA = 0x02,
I810_INIT_DMA_1_4 = 0x03
- } drm_i810_init_func_t;
+} drm_i810_init_func_t;
/* This is the init structure after v1.2 */
typedef struct _drm_i810_init {
@@ -122,7 +121,7 @@ typedef struct _drm_i810_init {
unsigned int w;
unsigned int h;
unsigned int pitch;
- unsigned int pitch_bits;
+ unsigned int pitch_bits;
} drm_i810_init_t;
/* This is the init structure prior to v1.2 */
@@ -140,23 +139,23 @@ typedef struct _drm_i810_pre12_init {
unsigned int w;
unsigned int h;
unsigned int pitch;
- unsigned int pitch_bits;
+ unsigned int pitch_bits;
} drm_i810_pre12_init_t;
/* Warning: If you change the SAREA structure you must change the Xserver
* structure as well */
typedef struct _drm_i810_tex_region {
- unsigned char next, prev; /* indices to form a circular LRU */
+ unsigned char next, prev; /* indices to form a circular LRU */
unsigned char in_use; /* owned by a client, or free? */
int age; /* tracked by clients to update local LRU's */
} drm_i810_tex_region_t;
typedef struct _drm_i810_sarea {
- unsigned int ContextState[I810_CTX_SETUP_SIZE];
- unsigned int BufferState[I810_DEST_SETUP_SIZE];
- unsigned int TexState[2][I810_TEX_SETUP_SIZE];
- unsigned int dirty;
+ unsigned int ContextState[I810_CTX_SETUP_SIZE];
+ unsigned int BufferState[I810_DEST_SETUP_SIZE];
+ unsigned int TexState[2][I810_TEX_SETUP_SIZE];
+ unsigned int dirty;
unsigned int nbox;
drm_clip_rect_t boxes[I810_NR_SAREA_CLIPRECTS];
@@ -174,22 +173,22 @@ typedef struct _drm_i810_sarea {
* texture space, and can make informed decisions as to which
* areas to kick out. There is no need to choose whether to
* kick out your own texture or someone else's - simply eject
- * them all in LRU order.
+ * them all in LRU order.
*/
-
- drm_i810_tex_region_t texList[I810_NR_TEX_REGIONS+1];
- /* Last elt is sentinal */
- int texAge; /* last time texture was uploaded */
- int last_enqueue; /* last time a buffer was enqueued */
+
+ drm_i810_tex_region_t texList[I810_NR_TEX_REGIONS + 1];
+ /* Last elt is sentinal */
+ int texAge; /* last time texture was uploaded */
+ int last_enqueue; /* last time a buffer was enqueued */
int last_dispatch; /* age of the most recently dispatched buffer */
- int last_quiescent; /* */
+ int last_quiescent; /* */
int ctxOwner; /* last context to upload state */
int vertex_prim;
- int pf_enabled; /* is pageflipping allowed? */
+ int pf_enabled; /* is pageflipping allowed? */
int pf_active;
- int pf_current_page; /* which buffer is being displayed? */
+ int pf_current_page; /* which buffer is being displayed? */
} drm_i810_sarea_t;
/* WARNING: If you change any of these defines, make sure to change the
@@ -243,13 +242,13 @@ typedef struct _drm_i810_clear {
* new set of cliprects.
*/
typedef struct _drm_i810_vertex {
- int idx; /* buffer index */
+ int idx; /* buffer index */
int used; /* nr bytes in use */
int discard; /* client is finished with the buffer? */
} drm_i810_vertex_t;
typedef struct _drm_i810_copy_t {
- int idx; /* buffer index */
+ int idx; /* buffer index */
int used; /* nr bytes in use */
void *address; /* Address to copy from */
} drm_i810_copy_t;
@@ -264,7 +263,6 @@ typedef struct _drm_i810_copy_t {
#define PR_RECTS (0x7<<18)
#define PR_MASK (0x7<<18)
-
typedef struct drm_i810_dma {
void *virtual;
int request_idx;
@@ -273,17 +271,16 @@ typedef struct drm_i810_dma {
} drm_i810_dma_t;
typedef struct _drm_i810_overlay_t {
- unsigned int offset; /* Address of the Overlay Regs */
+ unsigned int offset; /* Address of the Overlay Regs */
unsigned int physical;
} drm_i810_overlay_t;
typedef struct _drm_i810_mc {
- int idx; /* buffer index */
- int used; /* nr bytes in use */
- int num_blocks; /* number of GFXBlocks */
- int *length; /* List of lengths for GFXBlocks (FUTURE)*/
- unsigned int last_render; /* Last Render Request */
+ int idx; /* buffer index */
+ int used; /* nr bytes in use */
+ int num_blocks; /* number of GFXBlocks */
+ int *length; /* List of lengths for GFXBlocks (FUTURE) */
+ unsigned int last_render; /* Last Render Request */
} drm_i810_mc_t;
-
-#endif /* _I810_DRM_H_ */
+#endif /* _I810_DRM_H_ */
diff --git a/drivers/char/drm/i810_drv.c b/drivers/char/drm/i810_drv.c
index 00609329d578..070cef6c2b46 100644
--- a/drivers/char/drm/i810_drv.c
+++ b/drivers/char/drm/i810_drv.c
@@ -38,7 +38,7 @@
#include "drm_pciids.h"
-static int postinit( struct drm_device *dev, unsigned long flags )
+static int postinit(struct drm_device *dev, unsigned long flags)
{
/* i810 has 4 more counters */
dev->counters += 4;
@@ -46,29 +46,27 @@ static int postinit( struct drm_device *dev, unsigned long flags )
dev->types[7] = _DRM_STAT_PRIMARY;
dev->types[8] = _DRM_STAT_SECONDARY;
dev->types[9] = _DRM_STAT_DMA;
-
- DRM_INFO( "Initialized %s %d.%d.%d %s on minor %d: %s\n",
- DRIVER_NAME,
- DRIVER_MAJOR,
- DRIVER_MINOR,
- DRIVER_PATCHLEVEL,
- DRIVER_DATE,
- dev->primary.minor,
- pci_pretty_name(dev->pdev)
- );
+
+ DRM_INFO("Initialized %s %d.%d.%d %s on minor %d: %s\n",
+ DRIVER_NAME,
+ DRIVER_MAJOR,
+ DRIVER_MINOR,
+ DRIVER_PATCHLEVEL,
+ DRIVER_DATE, dev->primary.minor, pci_pretty_name(dev->pdev)
+ );
return 0;
}
-static int version( drm_version_t *version )
+static int version(drm_version_t * version)
{
int len;
version->version_major = DRIVER_MAJOR;
version->version_minor = DRIVER_MINOR;
version->version_patchlevel = DRIVER_PATCHLEVEL;
- DRM_COPY( version->name, DRIVER_NAME );
- DRM_COPY( version->date, DRIVER_DATE );
- DRM_COPY( version->desc, DRIVER_DESC );
+ DRM_COPY(version->name, DRIVER_NAME);
+ DRM_COPY(version->date, DRIVER_DATE);
+ DRM_COPY(version->desc, DRIVER_DESC);
return 0;
}
@@ -76,11 +74,10 @@ static struct pci_device_id pciidlist[] = {
i810_PCI_IDS
};
-extern drm_ioctl_desc_t i810_ioctls[];
-extern int i810_max_ioctl;
-
static struct drm_driver driver = {
- .driver_features = DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | DRIVER_USE_MTRR | DRIVER_HAVE_DMA | DRIVER_DMA_QUEUE,
+ .driver_features =
+ DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | DRIVER_USE_MTRR |
+ DRIVER_HAVE_DMA | DRIVER_DMA_QUEUE,
.dev_priv_size = sizeof(drm_i810_buf_priv_t),
.pretakedown = i810_driver_pretakedown,
.prerelease = i810_driver_prerelease,
@@ -94,18 +91,20 @@ static struct drm_driver driver = {
.version = version,
.ioctls = i810_ioctls,
.fops = {
- .owner = THIS_MODULE,
- .open = drm_open,
- .release = drm_release,
- .ioctl = drm_ioctl,
- .mmap = drm_mmap,
- .poll = drm_poll,
- .fasync = drm_fasync,
- },
+ .owner = THIS_MODULE,
+ .open = drm_open,
+ .release = drm_release,
+ .ioctl = drm_ioctl,
+ .mmap = drm_mmap,
+ .poll = drm_poll,
+ .fasync = drm_fasync,
+ }
+ ,
.pci_driver = {
- .name = DRIVER_NAME,
- .id_table = pciidlist,
- },
+ .name = DRIVER_NAME,
+ .id_table = pciidlist,
+ }
+ ,
};
static int __init i810_init(void)
@@ -122,6 +121,6 @@ static void __exit i810_exit(void)
module_init(i810_init);
module_exit(i810_exit);
-MODULE_AUTHOR( DRIVER_AUTHOR );
-MODULE_DESCRIPTION( DRIVER_DESC );
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL and additional rights");
diff --git a/drivers/char/drm/i810_drv.h b/drivers/char/drm/i810_drv.h
index 62ee4f58c59a..c78f36aaa2f0 100644
--- a/drivers/char/drm/i810_drv.h
+++ b/drivers/char/drm/i810_drv.h
@@ -56,14 +56,14 @@
#define DRIVER_PATCHLEVEL 0
typedef struct drm_i810_buf_priv {
- u32 *in_use;
- int my_use_idx;
+ u32 *in_use;
+ int my_use_idx;
int currently_mapped;
void *virtual;
void *kernel_virtual;
} drm_i810_buf_priv_t;
-typedef struct _drm_i810_ring_buffer{
+typedef struct _drm_i810_ring_buffer {
int tail_mask;
unsigned long Start;
unsigned long End;
@@ -79,16 +79,15 @@ typedef struct drm_i810_private {
drm_map_t *mmio_map;
drm_i810_sarea_t *sarea_priv;
- drm_i810_ring_buffer_t ring;
+ drm_i810_ring_buffer_t ring;
- void *hw_status_page;
- unsigned long counter;
+ void *hw_status_page;
+ unsigned long counter;
dma_addr_t dma_status_page;
drm_buf_t *mmap_buffer;
-
u32 front_di1, back_di1, zi1;
int back_offset;
@@ -97,7 +96,7 @@ typedef struct drm_i810_private {
int overlay_physical;
int w, h;
int pitch;
- int back_pitch;
+ int back_pitch;
int depth_pitch;
int do_boxes;
@@ -107,21 +106,24 @@ typedef struct drm_i810_private {
int page_flipping;
wait_queue_head_t irq_queue;
- atomic_t irq_received;
- atomic_t irq_emitted;
-
- int front_offset;
+ atomic_t irq_received;
+ atomic_t irq_emitted;
+
+ int front_offset;
} drm_i810_private_t;
/* i810_dma.c */
-extern void i810_reclaim_buffers(drm_device_t *dev, struct file *filp);
+extern void i810_reclaim_buffers(drm_device_t * dev, struct file *filp);
-extern int i810_driver_dma_quiescent(drm_device_t *dev);
-extern void i810_driver_release(drm_device_t *dev, struct file *filp);
-extern void i810_driver_pretakedown(drm_device_t *dev);
-extern void i810_driver_prerelease(drm_device_t *dev, DRMFILE filp);
+extern int i810_driver_dma_quiescent(drm_device_t * dev);
+extern void i810_driver_release(drm_device_t * dev, struct file *filp);
+extern void i810_driver_pretakedown(drm_device_t * dev);
+extern void i810_driver_prerelease(drm_device_t * dev, DRMFILE filp);
extern int i810_driver_device_is_agp(drm_device_t * dev);
+extern drm_ioctl_desc_t i810_ioctls[];
+extern int i810_max_ioctl;
+
#define I810_BASE(reg) ((unsigned long) \
dev_priv->mmio_map->handle)
#define I810_ADDR(reg) (I810_BASE(reg) + reg)
@@ -170,7 +172,6 @@ extern int i810_driver_device_is_agp(drm_device_t * dev);
#define INST_OP_FLUSH 0x02000000
#define INST_FLUSH_MAP_CACHE 0x00000001
-
#define BB1_START_ADDR_MASK (~0x7)
#define BB1_PROTECTED (1<<0)
#define BB1_UNPROTECTED (0<<0)
@@ -229,8 +230,8 @@ extern int i810_driver_device_is_agp(drm_device_t * dev);
#define BR00_OP_SRC_COPY_BLT 0x10C00000
#define BR13_SOLID_PATTERN 0x80000000
-#define WAIT_FOR_PLANE_A_SCANLINES (1<<1)
-#define WAIT_FOR_PLANE_A_FLIP (1<<2)
+#define WAIT_FOR_PLANE_A_SCANLINES (1<<1)
+#define WAIT_FOR_PLANE_A_FLIP (1<<2)
#define WAIT_FOR_VBLANK (1<<3)
#endif
diff --git a/drivers/char/drm/i830_dma.c b/drivers/char/drm/i830_dma.c
index 6f89d5796ef3..dc94f1914425 100644
--- a/drivers/char/drm/i830_dma.c
+++ b/drivers/char/drm/i830_dma.c
@@ -11,11 +11,11 @@
* 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 (including the next
* paragraph) 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
@@ -47,103 +47,104 @@
#define I830_BUF_UNMAPPED 0
#define I830_BUF_MAPPED 1
-static drm_buf_t *i830_freelist_get(drm_device_t *dev)
+static drm_buf_t *i830_freelist_get(drm_device_t * dev)
{
- drm_device_dma_t *dma = dev->dma;
- int i;
- int used;
-
+ drm_device_dma_t *dma = dev->dma;
+ int i;
+ int used;
+
/* Linear search might not be the best solution */
- for (i = 0; i < dma->buf_count; i++) {
- drm_buf_t *buf = dma->buflist[ i ];
- drm_i830_buf_priv_t *buf_priv = buf->dev_private;
+ for (i = 0; i < dma->buf_count; i++) {
+ drm_buf_t *buf = dma->buflist[i];
+ drm_i830_buf_priv_t *buf_priv = buf->dev_private;
/* In use is already a pointer */
- used = cmpxchg(buf_priv->in_use, I830_BUF_FREE,
+ used = cmpxchg(buf_priv->in_use, I830_BUF_FREE,
I830_BUF_CLIENT);
- if(used == I830_BUF_FREE) {
+ if (used == I830_BUF_FREE) {
return buf;
}
}
- return NULL;
+ return NULL;
}
/* This should only be called if the buffer is not sent to the hardware
* yet, the hardware updates in use for us once its on the ring buffer.
*/
-static int i830_freelist_put(drm_device_t *dev, drm_buf_t *buf)
+static int i830_freelist_put(drm_device_t * dev, drm_buf_t * buf)
{
- drm_i830_buf_priv_t *buf_priv = buf->dev_private;
- int used;
-
- /* In use is already a pointer */
- used = cmpxchg(buf_priv->in_use, I830_BUF_CLIENT, I830_BUF_FREE);
- if(used != I830_BUF_CLIENT) {
- DRM_ERROR("Freeing buffer thats not in use : %d\n", buf->idx);
- return -EINVAL;
+ drm_i830_buf_priv_t *buf_priv = buf->dev_private;
+ int used;
+
+ /* In use is already a pointer */
+ used = cmpxchg(buf_priv->in_use, I830_BUF_CLIENT, I830_BUF_FREE);
+ if (used != I830_BUF_CLIENT) {
+ DRM_ERROR("Freeing buffer thats not in use : %d\n", buf->idx);
+ return -EINVAL;
}
-
- return 0;
+
+ return 0;
}
static int i830_mmap_buffers(struct file *filp, struct vm_area_struct *vma)
{
- drm_file_t *priv = filp->private_data;
- drm_device_t *dev;
- drm_i830_private_t *dev_priv;
- drm_buf_t *buf;
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev;
+ drm_i830_private_t *dev_priv;
+ drm_buf_t *buf;
drm_i830_buf_priv_t *buf_priv;
lock_kernel();
- dev = priv->head->dev;
+ dev = priv->head->dev;
dev_priv = dev->dev_private;
- buf = dev_priv->mmap_buffer;
+ buf = dev_priv->mmap_buffer;
buf_priv = buf->dev_private;
-
+
vma->vm_flags |= (VM_IO | VM_DONTCOPY);
vma->vm_file = filp;
-
- buf_priv->currently_mapped = I830_BUF_MAPPED;
+
+ buf_priv->currently_mapped = I830_BUF_MAPPED;
unlock_kernel();
if (io_remap_pfn_range(vma, vma->vm_start,
- VM_OFFSET(vma) >> PAGE_SHIFT,
- vma->vm_end - vma->vm_start,
- vma->vm_page_prot)) return -EAGAIN;
+ VM_OFFSET(vma) >> PAGE_SHIFT,
+ vma->vm_end - vma->vm_start, vma->vm_page_prot))
+ return -EAGAIN;
return 0;
}
static struct file_operations i830_buffer_fops = {
- .open = drm_open,
- .flush = drm_flush,
+ .open = drm_open,
+ .flush = drm_flush,
.release = drm_release,
- .ioctl = drm_ioctl,
- .mmap = i830_mmap_buffers,
- .fasync = drm_fasync,
+ .ioctl = drm_ioctl,
+ .mmap = i830_mmap_buffers,
+ .fasync = drm_fasync,
};
-static int i830_map_buffer(drm_buf_t *buf, struct file *filp)
+static int i830_map_buffer(drm_buf_t * buf, struct file *filp)
{
- drm_file_t *priv = filp->private_data;
- drm_device_t *dev = priv->head->dev;
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->head->dev;
drm_i830_buf_priv_t *buf_priv = buf->dev_private;
- drm_i830_private_t *dev_priv = dev->dev_private;
- struct file_operations *old_fops;
+ drm_i830_private_t *dev_priv = dev->dev_private;
+ struct file_operations *old_fops;
unsigned long virtual;
int retcode = 0;
- if(buf_priv->currently_mapped == I830_BUF_MAPPED) return -EINVAL;
+ if (buf_priv->currently_mapped == I830_BUF_MAPPED)
+ return -EINVAL;
- down_write( &current->mm->mmap_sem );
+ down_write(&current->mm->mmap_sem);
old_fops = filp->f_op;
filp->f_op = &i830_buffer_fops;
dev_priv->mmap_buffer = buf;
- virtual = do_mmap(filp, 0, buf->total, PROT_READ|PROT_WRITE,
- MAP_SHARED, buf->bus_address);
+ virtual = do_mmap(filp, 0, buf->total, PROT_READ | PROT_WRITE,
+ MAP_SHARED, buf->bus_address);
dev_priv->mmap_buffer = NULL;
filp->f_op = old_fops;
- if (IS_ERR((void *)virtual)) { /* ugh */
+ if (IS_ERR((void *)virtual)) { /* ugh */
/* Real error */
DRM_ERROR("mmap error\n");
retcode = virtual;
@@ -151,17 +152,17 @@ static int i830_map_buffer(drm_buf_t *buf, struct file *filp)
} else {
buf_priv->virtual = (void __user *)virtual;
}
- up_write( &current->mm->mmap_sem );
+ up_write(&current->mm->mmap_sem);
return retcode;
}
-static int i830_unmap_buffer(drm_buf_t *buf)
+static int i830_unmap_buffer(drm_buf_t * buf)
{
drm_i830_buf_priv_t *buf_priv = buf->dev_private;
int retcode = 0;
- if(buf_priv->currently_mapped != I830_BUF_MAPPED)
+ if (buf_priv->currently_mapped != I830_BUF_MAPPED)
return -EINVAL;
down_write(&current->mm->mmap_sem);
@@ -170,43 +171,43 @@ static int i830_unmap_buffer(drm_buf_t *buf)
(size_t) buf->total);
up_write(&current->mm->mmap_sem);
- buf_priv->currently_mapped = I830_BUF_UNMAPPED;
- buf_priv->virtual = NULL;
+ buf_priv->currently_mapped = I830_BUF_UNMAPPED;
+ buf_priv->virtual = NULL;
return retcode;
}
-static int i830_dma_get_buffer(drm_device_t *dev, drm_i830_dma_t *d,
+static int i830_dma_get_buffer(drm_device_t * dev, drm_i830_dma_t * d,
struct file *filp)
{
- drm_buf_t *buf;
+ drm_buf_t *buf;
drm_i830_buf_priv_t *buf_priv;
int retcode = 0;
buf = i830_freelist_get(dev);
if (!buf) {
retcode = -ENOMEM;
- DRM_DEBUG("retcode=%d\n", retcode);
+ DRM_DEBUG("retcode=%d\n", retcode);
return retcode;
}
-
+
retcode = i830_map_buffer(buf, filp);
- if(retcode) {
+ if (retcode) {
i830_freelist_put(dev, buf);
- DRM_ERROR("mapbuf failed, retcode %d\n", retcode);
+ DRM_ERROR("mapbuf failed, retcode %d\n", retcode);
return retcode;
}
buf->filp = filp;
- buf_priv = buf->dev_private;
+ buf_priv = buf->dev_private;
d->granted = 1;
- d->request_idx = buf->idx;
- d->request_size = buf->total;
- d->virtual = buf_priv->virtual;
+ d->request_idx = buf->idx;
+ d->request_size = buf->total;
+ d->virtual = buf_priv->virtual;
return retcode;
}
-static int i830_dma_cleanup(drm_device_t *dev)
+static int i830_dma_cleanup(drm_device_t * dev)
{
drm_device_dma_t *dma = dev->dma;
@@ -214,140 +215,144 @@ static int i830_dma_cleanup(drm_device_t *dev)
* may not have been called from userspace and after dev_private
* is freed, it's too late.
*/
- if ( dev->irq_enabled ) drm_irq_uninstall(dev);
+ if (dev->irq_enabled)
+ drm_irq_uninstall(dev);
if (dev->dev_private) {
int i;
- drm_i830_private_t *dev_priv =
- (drm_i830_private_t *) dev->dev_private;
-
- if (dev_priv->ring.virtual_start) {
- drm_ioremapfree((void *) dev_priv->ring.virtual_start,
- dev_priv->ring.Size, dev);
+ drm_i830_private_t *dev_priv =
+ (drm_i830_private_t *) dev->dev_private;
+
+ if (dev_priv->ring.virtual_start) {
+ drm_ioremapfree((void *)dev_priv->ring.virtual_start,
+ dev_priv->ring.Size, dev);
}
- if (dev_priv->hw_status_page) {
+ if (dev_priv->hw_status_page) {
pci_free_consistent(dev->pdev, PAGE_SIZE,
dev_priv->hw_status_page,
dev_priv->dma_status_page);
- /* Need to rewrite hardware status page */
- I830_WRITE(0x02080, 0x1ffff000);
+ /* Need to rewrite hardware status page */
+ I830_WRITE(0x02080, 0x1ffff000);
}
- drm_free(dev->dev_private, sizeof(drm_i830_private_t),
+ drm_free(dev->dev_private, sizeof(drm_i830_private_t),
DRM_MEM_DRIVER);
- dev->dev_private = NULL;
+ dev->dev_private = NULL;
for (i = 0; i < dma->buf_count; i++) {
- drm_buf_t *buf = dma->buflist[ i ];
+ drm_buf_t *buf = dma->buflist[i];
drm_i830_buf_priv_t *buf_priv = buf->dev_private;
- if ( buf_priv->kernel_virtual && buf->total )
- drm_ioremapfree(buf_priv->kernel_virtual, buf->total, dev);
+ if (buf_priv->kernel_virtual && buf->total)
+ drm_ioremapfree(buf_priv->kernel_virtual,
+ buf->total, dev);
}
}
- return 0;
+ return 0;
}
-int i830_wait_ring(drm_device_t *dev, int n, const char *caller)
+int i830_wait_ring(drm_device_t * dev, int n, const char *caller)
{
- drm_i830_private_t *dev_priv = dev->dev_private;
- drm_i830_ring_buffer_t *ring = &(dev_priv->ring);
- int iters = 0;
- unsigned long end;
+ drm_i830_private_t *dev_priv = dev->dev_private;
+ drm_i830_ring_buffer_t *ring = &(dev_priv->ring);
+ int iters = 0;
+ unsigned long end;
unsigned int last_head = I830_READ(LP_RING + RING_HEAD) & HEAD_ADDR;
- end = jiffies + (HZ*3);
- while (ring->space < n) {
- ring->head = I830_READ(LP_RING + RING_HEAD) & HEAD_ADDR;
- ring->space = ring->head - (ring->tail+8);
- if (ring->space < 0) ring->space += ring->Size;
-
+ end = jiffies + (HZ * 3);
+ while (ring->space < n) {
+ ring->head = I830_READ(LP_RING + RING_HEAD) & HEAD_ADDR;
+ ring->space = ring->head - (ring->tail + 8);
+ if (ring->space < 0)
+ ring->space += ring->Size;
+
if (ring->head != last_head) {
- end = jiffies + (HZ*3);
+ end = jiffies + (HZ * 3);
last_head = ring->head;
}
-
- iters++;
- if(time_before(end, jiffies)) {
- DRM_ERROR("space: %d wanted %d\n", ring->space, n);
- DRM_ERROR("lockup\n");
- goto out_wait_ring;
+
+ iters++;
+ if (time_before(end, jiffies)) {
+ DRM_ERROR("space: %d wanted %d\n", ring->space, n);
+ DRM_ERROR("lockup\n");
+ goto out_wait_ring;
}
udelay(1);
dev_priv->sarea_priv->perf_boxes |= I830_BOX_WAIT;
}
-out_wait_ring:
- return iters;
+ out_wait_ring:
+ return iters;
}
-static void i830_kernel_lost_context(drm_device_t *dev)
+static void i830_kernel_lost_context(drm_device_t * dev)
{
- drm_i830_private_t *dev_priv = dev->dev_private;
- drm_i830_ring_buffer_t *ring = &(dev_priv->ring);
-
- ring->head = I830_READ(LP_RING + RING_HEAD) & HEAD_ADDR;
- ring->tail = I830_READ(LP_RING + RING_TAIL) & TAIL_ADDR;
- ring->space = ring->head - (ring->tail+8);
- if (ring->space < 0) ring->space += ring->Size;
+ drm_i830_private_t *dev_priv = dev->dev_private;
+ drm_i830_ring_buffer_t *ring = &(dev_priv->ring);
+
+ ring->head = I830_READ(LP_RING + RING_HEAD) & HEAD_ADDR;
+ ring->tail = I830_READ(LP_RING + RING_TAIL) & TAIL_ADDR;
+ ring->space = ring->head - (ring->tail + 8);
+ if (ring->space < 0)
+ ring->space += ring->Size;
if (ring->head == ring->tail)
dev_priv->sarea_priv->perf_boxes |= I830_BOX_RING_EMPTY;
}
-static int i830_freelist_init(drm_device_t *dev, drm_i830_private_t *dev_priv)
+static int i830_freelist_init(drm_device_t * dev, drm_i830_private_t * dev_priv)
{
- drm_device_dma_t *dma = dev->dma;
- int my_idx = 36;
- u32 *hw_status = (u32 *)(dev_priv->hw_status_page + my_idx);
- int i;
-
- if(dma->buf_count > 1019) {
- /* Not enough space in the status page for the freelist */
- return -EINVAL;
+ drm_device_dma_t *dma = dev->dma;
+ int my_idx = 36;
+ u32 *hw_status = (u32 *) (dev_priv->hw_status_page + my_idx);
+ int i;
+
+ if (dma->buf_count > 1019) {
+ /* Not enough space in the status page for the freelist */
+ return -EINVAL;
}
- for (i = 0; i < dma->buf_count; i++) {
- drm_buf_t *buf = dma->buflist[ i ];
- drm_i830_buf_priv_t *buf_priv = buf->dev_private;
+ for (i = 0; i < dma->buf_count; i++) {
+ drm_buf_t *buf = dma->buflist[i];
+ drm_i830_buf_priv_t *buf_priv = buf->dev_private;
- buf_priv->in_use = hw_status++;
- buf_priv->my_use_idx = my_idx;
- my_idx += 4;
+ buf_priv->in_use = hw_status++;
+ buf_priv->my_use_idx = my_idx;
+ my_idx += 4;
- *buf_priv->in_use = I830_BUF_FREE;
+ *buf_priv->in_use = I830_BUF_FREE;
- buf_priv->kernel_virtual = drm_ioremap(buf->bus_address,
- buf->total, dev);
+ buf_priv->kernel_virtual = drm_ioremap(buf->bus_address,
+ buf->total, dev);
}
return 0;
}
-static int i830_dma_initialize(drm_device_t *dev,
- drm_i830_private_t *dev_priv,
- drm_i830_init_t *init)
+static int i830_dma_initialize(drm_device_t * dev,
+ drm_i830_private_t * dev_priv,
+ drm_i830_init_t * init)
{
struct list_head *list;
- memset(dev_priv, 0, sizeof(drm_i830_private_t));
+ memset(dev_priv, 0, sizeof(drm_i830_private_t));
list_for_each(list, &dev->maplist->head) {
drm_map_list_t *r_list = list_entry(list, drm_map_list_t, head);
- if( r_list->map &&
+ if (r_list->map &&
r_list->map->type == _DRM_SHM &&
- r_list->map->flags & _DRM_CONTAINS_LOCK ) {
+ r_list->map->flags & _DRM_CONTAINS_LOCK) {
dev_priv->sarea_map = r_list->map;
- break;
- }
- }
+ break;
+ }
+ }
- if(!dev_priv->sarea_map) {
+ if (!dev_priv->sarea_map) {
dev->dev_private = (void *)dev_priv;
i830_dma_cleanup(dev);
DRM_ERROR("can not find sarea!\n");
return -EINVAL;
}
dev_priv->mmio_map = drm_core_findmap(dev, init->mmio_offset);
- if(!dev_priv->mmio_map) {
+ if (!dev_priv->mmio_map) {
dev->dev_private = (void *)dev_priv;
i830_dma_cleanup(dev);
DRM_ERROR("can not find mmio map!\n");
@@ -355,7 +360,7 @@ static int i830_dma_initialize(drm_device_t *dev,
}
dev->agp_buffer_token = init->buffers_offset;
dev->agp_buffer_map = drm_core_findmap(dev, init->buffers_offset);
- if(!dev->agp_buffer_map) {
+ if (!dev->agp_buffer_map) {
dev->dev_private = (void *)dev_priv;
i830_dma_cleanup(dev);
DRM_ERROR("can not find dma buffer map!\n");
@@ -363,27 +368,26 @@ static int i830_dma_initialize(drm_device_t *dev,
}
dev_priv->sarea_priv = (drm_i830_sarea_t *)
- ((u8 *)dev_priv->sarea_map->handle +
- init->sarea_priv_offset);
+ ((u8 *) dev_priv->sarea_map->handle + init->sarea_priv_offset);
- dev_priv->ring.Start = init->ring_start;
- dev_priv->ring.End = init->ring_end;
- dev_priv->ring.Size = init->ring_size;
+ dev_priv->ring.Start = init->ring_start;
+ dev_priv->ring.End = init->ring_end;
+ dev_priv->ring.Size = init->ring_size;
- dev_priv->ring.virtual_start = drm_ioremap(dev->agp->base +
- init->ring_start,
- init->ring_size, dev);
+ dev_priv->ring.virtual_start = drm_ioremap(dev->agp->base +
+ init->ring_start,
+ init->ring_size, dev);
- if (dev_priv->ring.virtual_start == NULL) {
- dev->dev_private = (void *) dev_priv;
- i830_dma_cleanup(dev);
- DRM_ERROR("can not ioremap virtual address for"
+ if (dev_priv->ring.virtual_start == NULL) {
+ dev->dev_private = (void *)dev_priv;
+ i830_dma_cleanup(dev);
+ DRM_ERROR("can not ioremap virtual address for"
" ring buffer\n");
- return -ENOMEM;
+ return -ENOMEM;
}
- dev_priv->ring.tail_mask = dev_priv->ring.Size - 1;
-
+ dev_priv->ring.tail_mask = dev_priv->ring.Size - 1;
+
dev_priv->w = init->w;
dev_priv->h = init->h;
dev_priv->pitch = init->pitch;
@@ -395,10 +399,10 @@ static int i830_dma_initialize(drm_device_t *dev,
dev_priv->back_di1 = init->back_offset | init->pitch_bits;
dev_priv->zi1 = init->depth_offset | init->pitch_bits;
- DRM_DEBUG("front_di1 %x\n", dev_priv->front_di1);
+ DRM_DEBUG("front_di1 %x\n", dev_priv->front_di1);
DRM_DEBUG("back_offset %x\n", dev_priv->back_offset);
- DRM_DEBUG("back_di1 %x\n", dev_priv->back_di1);
- DRM_DEBUG("pitch_bits %x\n", init->pitch_bits);
+ DRM_DEBUG("back_di1 %x\n", dev_priv->back_di1);
+ DRM_DEBUG("pitch_bits %x\n", init->pitch_bits);
dev_priv->cpp = init->cpp;
/* We are using separate values as placeholders for mechanisms for
@@ -410,63 +414,64 @@ static int i830_dma_initialize(drm_device_t *dev,
dev_priv->do_boxes = 0;
dev_priv->use_mi_batchbuffer_start = 0;
- /* Program Hardware Status Page */
- dev_priv->hw_status_page =
- pci_alloc_consistent(dev->pdev, PAGE_SIZE,
- &dev_priv->dma_status_page);
- if (!dev_priv->hw_status_page) {
+ /* Program Hardware Status Page */
+ dev_priv->hw_status_page =
+ pci_alloc_consistent(dev->pdev, PAGE_SIZE,
+ &dev_priv->dma_status_page);
+ if (!dev_priv->hw_status_page) {
dev->dev_private = (void *)dev_priv;
i830_dma_cleanup(dev);
DRM_ERROR("Can not allocate hardware status page\n");
return -ENOMEM;
}
- memset(dev_priv->hw_status_page, 0, PAGE_SIZE);
+ memset(dev_priv->hw_status_page, 0, PAGE_SIZE);
DRM_DEBUG("hw status page @ %p\n", dev_priv->hw_status_page);
-
- I830_WRITE(0x02080, dev_priv->dma_status_page);
+
+ I830_WRITE(0x02080, dev_priv->dma_status_page);
DRM_DEBUG("Enabled hardware status page\n");
-
- /* Now we need to init our freelist */
- if(i830_freelist_init(dev, dev_priv) != 0) {
+
+ /* Now we need to init our freelist */
+ if (i830_freelist_init(dev, dev_priv) != 0) {
dev->dev_private = (void *)dev_priv;
- i830_dma_cleanup(dev);
- DRM_ERROR("Not enough space in the status page for"
+ i830_dma_cleanup(dev);
+ DRM_ERROR("Not enough space in the status page for"
" the freelist\n");
- return -ENOMEM;
+ return -ENOMEM;
}
dev->dev_private = (void *)dev_priv;
- return 0;
+ return 0;
}
static int i830_dma_init(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg)
+ unsigned int cmd, unsigned long arg)
{
- drm_file_t *priv = filp->private_data;
- drm_device_t *dev = priv->head->dev;
- drm_i830_private_t *dev_priv;
- drm_i830_init_t init;
- int retcode = 0;
-
- if (copy_from_user(&init, (void * __user) arg, sizeof(init)))
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->head->dev;
+ drm_i830_private_t *dev_priv;
+ drm_i830_init_t init;
+ int retcode = 0;
+
+ if (copy_from_user(&init, (void *__user)arg, sizeof(init)))
return -EFAULT;
-
- switch(init.func) {
- case I830_INIT_DMA:
- dev_priv = drm_alloc(sizeof(drm_i830_private_t),
- DRM_MEM_DRIVER);
- if(dev_priv == NULL) return -ENOMEM;
- retcode = i830_dma_initialize(dev, dev_priv, &init);
- break;
- case I830_CLEANUP_DMA:
- retcode = i830_dma_cleanup(dev);
- break;
- default:
- retcode = -EINVAL;
- break;
+
+ switch (init.func) {
+ case I830_INIT_DMA:
+ dev_priv = drm_alloc(sizeof(drm_i830_private_t),
+ DRM_MEM_DRIVER);
+ if (dev_priv == NULL)
+ return -ENOMEM;
+ retcode = i830_dma_initialize(dev, dev_priv, &init);
+ break;
+ case I830_CLEANUP_DMA:
+ retcode = i830_dma_cleanup(dev);
+ break;
+ default:
+ retcode = -EINVAL;
+ break;
}
-
- return retcode;
+
+ return retcode;
}
#define GFX_OP_STIPPLE ((0x3<<29)|(0x1d<<24)|(0x83<<16))
@@ -476,92 +481,89 @@ static int i830_dma_init(struct inode *inode, struct file *filp,
/* Most efficient way to verify state for the i830 is as it is
* emitted. Non-conformant state is silently dropped.
*/
-static void i830EmitContextVerified( drm_device_t *dev,
- unsigned int *code )
+static void i830EmitContextVerified(drm_device_t * dev, unsigned int *code)
{
- drm_i830_private_t *dev_priv = dev->dev_private;
+ drm_i830_private_t *dev_priv = dev->dev_private;
int i, j = 0;
unsigned int tmp;
RING_LOCALS;
- BEGIN_LP_RING( I830_CTX_SETUP_SIZE + 4 );
+ BEGIN_LP_RING(I830_CTX_SETUP_SIZE + 4);
- for ( i = 0 ; i < I830_CTXREG_BLENDCOLR0 ; i++ ) {
+ for (i = 0; i < I830_CTXREG_BLENDCOLR0; i++) {
tmp = code[i];
- if ((tmp & (7<<29)) == CMD_3D &&
- (tmp & (0x1f<<24)) < (0x1d<<24)) {
- OUT_RING( tmp );
+ if ((tmp & (7 << 29)) == CMD_3D &&
+ (tmp & (0x1f << 24)) < (0x1d << 24)) {
+ OUT_RING(tmp);
j++;
} else {
DRM_ERROR("Skipping %d\n", i);
}
}
- OUT_RING( STATE3D_CONST_BLEND_COLOR_CMD );
- OUT_RING( code[I830_CTXREG_BLENDCOLR] );
+ OUT_RING(STATE3D_CONST_BLEND_COLOR_CMD);
+ OUT_RING(code[I830_CTXREG_BLENDCOLR]);
j += 2;
- for ( i = I830_CTXREG_VF ; i < I830_CTXREG_MCSB0 ; i++ ) {
+ for (i = I830_CTXREG_VF; i < I830_CTXREG_MCSB0; i++) {
tmp = code[i];
- if ((tmp & (7<<29)) == CMD_3D &&
- (tmp & (0x1f<<24)) < (0x1d<<24)) {
- OUT_RING( tmp );
+ if ((tmp & (7 << 29)) == CMD_3D &&
+ (tmp & (0x1f << 24)) < (0x1d << 24)) {
+ OUT_RING(tmp);
j++;
} else {
DRM_ERROR("Skipping %d\n", i);
}
}
- OUT_RING( STATE3D_MAP_COORD_SETBIND_CMD );
- OUT_RING( code[I830_CTXREG_MCSB1] );
+ OUT_RING(STATE3D_MAP_COORD_SETBIND_CMD);
+ OUT_RING(code[I830_CTXREG_MCSB1]);
j += 2;
- if (j & 1)
- OUT_RING( 0 );
+ if (j & 1)
+ OUT_RING(0);
ADVANCE_LP_RING();
}
-static void i830EmitTexVerified( drm_device_t *dev, unsigned int *code )
+static void i830EmitTexVerified(drm_device_t * dev, unsigned int *code)
{
- drm_i830_private_t *dev_priv = dev->dev_private;
+ drm_i830_private_t *dev_priv = dev->dev_private;
int i, j = 0;
unsigned int tmp;
RING_LOCALS;
if (code[I830_TEXREG_MI0] == GFX_OP_MAP_INFO ||
- (code[I830_TEXREG_MI0] & ~(0xf*LOAD_TEXTURE_MAP0)) ==
- (STATE3D_LOAD_STATE_IMMEDIATE_2|4)) {
-
- BEGIN_LP_RING( I830_TEX_SETUP_SIZE );
-
- OUT_RING( code[I830_TEXREG_MI0] ); /* TM0LI */
- OUT_RING( code[I830_TEXREG_MI1] ); /* TM0S0 */
- OUT_RING( code[I830_TEXREG_MI2] ); /* TM0S1 */
- OUT_RING( code[I830_TEXREG_MI3] ); /* TM0S2 */
- OUT_RING( code[I830_TEXREG_MI4] ); /* TM0S3 */
- OUT_RING( code[I830_TEXREG_MI5] ); /* TM0S4 */
-
- for ( i = 6 ; i < I830_TEX_SETUP_SIZE ; i++ ) {
+ (code[I830_TEXREG_MI0] & ~(0xf * LOAD_TEXTURE_MAP0)) ==
+ (STATE3D_LOAD_STATE_IMMEDIATE_2 | 4)) {
+
+ BEGIN_LP_RING(I830_TEX_SETUP_SIZE);
+
+ OUT_RING(code[I830_TEXREG_MI0]); /* TM0LI */
+ OUT_RING(code[I830_TEXREG_MI1]); /* TM0S0 */
+ OUT_RING(code[I830_TEXREG_MI2]); /* TM0S1 */
+ OUT_RING(code[I830_TEXREG_MI3]); /* TM0S2 */
+ OUT_RING(code[I830_TEXREG_MI4]); /* TM0S3 */
+ OUT_RING(code[I830_TEXREG_MI5]); /* TM0S4 */
+
+ for (i = 6; i < I830_TEX_SETUP_SIZE; i++) {
tmp = code[i];
- OUT_RING( tmp );
+ OUT_RING(tmp);
j++;
- }
+ }
- if (j & 1)
- OUT_RING( 0 );
+ if (j & 1)
+ OUT_RING(0);
ADVANCE_LP_RING();
- }
- else
+ } else
printk("rejected packet %x\n", code[0]);
}
-static void i830EmitTexBlendVerified( drm_device_t *dev,
- unsigned int *code,
- unsigned int num)
+static void i830EmitTexBlendVerified(drm_device_t * dev,
+ unsigned int *code, unsigned int num)
{
- drm_i830_private_t *dev_priv = dev->dev_private;
+ drm_i830_private_t *dev_priv = dev->dev_private;
int i, j = 0;
unsigned int tmp;
RING_LOCALS;
@@ -569,59 +571,54 @@ static void i830EmitTexBlendVerified( drm_device_t *dev,
if (!num)
return;
- BEGIN_LP_RING( num + 1 );
+ BEGIN_LP_RING(num + 1);
- for ( i = 0 ; i < num ; i++ ) {
+ for (i = 0; i < num; i++) {
tmp = code[i];
- OUT_RING( tmp );
+ OUT_RING(tmp);
j++;
}
- if (j & 1)
- OUT_RING( 0 );
+ if (j & 1)
+ OUT_RING(0);
ADVANCE_LP_RING();
}
-static void i830EmitTexPalette( drm_device_t *dev,
- unsigned int *palette,
- int number,
- int is_shared )
+static void i830EmitTexPalette(drm_device_t * dev,
+ unsigned int *palette, int number, int is_shared)
{
- drm_i830_private_t *dev_priv = dev->dev_private;
+ drm_i830_private_t *dev_priv = dev->dev_private;
int i;
RING_LOCALS;
return;
- BEGIN_LP_RING( 258 );
+ BEGIN_LP_RING(258);
- if(is_shared == 1) {
+ if (is_shared == 1) {
OUT_RING(CMD_OP_MAP_PALETTE_LOAD |
- MAP_PALETTE_NUM(0) |
- MAP_PALETTE_BOTH);
+ MAP_PALETTE_NUM(0) | MAP_PALETTE_BOTH);
} else {
OUT_RING(CMD_OP_MAP_PALETTE_LOAD | MAP_PALETTE_NUM(number));
}
- for(i = 0; i < 256; i++) {
+ for (i = 0; i < 256; i++) {
OUT_RING(palette[i]);
}
OUT_RING(0);
- /* KW: WHERE IS THE ADVANCE_LP_RING? This is effectively a noop!
+ /* KW: WHERE IS THE ADVANCE_LP_RING? This is effectively a noop!
*/
}
/* Need to do some additional checking when setting the dest buffer.
*/
-static void i830EmitDestVerified( drm_device_t *dev,
- unsigned int *code )
-{
- drm_i830_private_t *dev_priv = dev->dev_private;
+static void i830EmitDestVerified(drm_device_t * dev, unsigned int *code)
+{
+ drm_i830_private_t *dev_priv = dev->dev_private;
unsigned int tmp;
RING_LOCALS;
- BEGIN_LP_RING( I830_DEST_SETUP_SIZE + 10 );
-
+ BEGIN_LP_RING(I830_DEST_SETUP_SIZE + 10);
tmp = code[I830_DESTREG_CBUFADDR];
if (tmp == dev_priv->front_di1 || tmp == dev_priv->back_di1) {
@@ -630,18 +627,18 @@ static void i830EmitDestVerified( drm_device_t *dev,
OUT_RING(0);
}
- OUT_RING( CMD_OP_DESTBUFFER_INFO );
- OUT_RING( BUF_3D_ID_COLOR_BACK |
- BUF_3D_PITCH(dev_priv->back_pitch * dev_priv->cpp) |
- BUF_3D_USE_FENCE);
- OUT_RING( tmp );
- OUT_RING( 0 );
-
- OUT_RING( CMD_OP_DESTBUFFER_INFO );
- OUT_RING( BUF_3D_ID_DEPTH | BUF_3D_USE_FENCE |
- BUF_3D_PITCH(dev_priv->depth_pitch * dev_priv->cpp));
- OUT_RING( dev_priv->zi1 );
- OUT_RING( 0 );
+ OUT_RING(CMD_OP_DESTBUFFER_INFO);
+ OUT_RING(BUF_3D_ID_COLOR_BACK |
+ BUF_3D_PITCH(dev_priv->back_pitch * dev_priv->cpp) |
+ BUF_3D_USE_FENCE);
+ OUT_RING(tmp);
+ OUT_RING(0);
+
+ OUT_RING(CMD_OP_DESTBUFFER_INFO);
+ OUT_RING(BUF_3D_ID_DEPTH | BUF_3D_USE_FENCE |
+ BUF_3D_PITCH(dev_priv->depth_pitch * dev_priv->cpp));
+ OUT_RING(dev_priv->zi1);
+ OUT_RING(0);
} else {
DRM_ERROR("bad di1 %x (allow %x or %x)\n",
tmp, dev_priv->front_di1, dev_priv->back_di1);
@@ -650,83 +647,80 @@ static void i830EmitDestVerified( drm_device_t *dev,
/* invarient:
*/
+ OUT_RING(GFX_OP_DESTBUFFER_VARS);
+ OUT_RING(code[I830_DESTREG_DV1]);
- OUT_RING( GFX_OP_DESTBUFFER_VARS );
- OUT_RING( code[I830_DESTREG_DV1] );
-
- OUT_RING( GFX_OP_DRAWRECT_INFO );
- OUT_RING( code[I830_DESTREG_DR1] );
- OUT_RING( code[I830_DESTREG_DR2] );
- OUT_RING( code[I830_DESTREG_DR3] );
- OUT_RING( code[I830_DESTREG_DR4] );
+ OUT_RING(GFX_OP_DRAWRECT_INFO);
+ OUT_RING(code[I830_DESTREG_DR1]);
+ OUT_RING(code[I830_DESTREG_DR2]);
+ OUT_RING(code[I830_DESTREG_DR3]);
+ OUT_RING(code[I830_DESTREG_DR4]);
/* Need to verify this */
tmp = code[I830_DESTREG_SENABLE];
- if((tmp & ~0x3) == GFX_OP_SCISSOR_ENABLE) {
- OUT_RING( tmp );
+ if ((tmp & ~0x3) == GFX_OP_SCISSOR_ENABLE) {
+ OUT_RING(tmp);
} else {
DRM_ERROR("bad scissor enable\n");
- OUT_RING( 0 );
+ OUT_RING(0);
}
- OUT_RING( GFX_OP_SCISSOR_RECT );
- OUT_RING( code[I830_DESTREG_SR1] );
- OUT_RING( code[I830_DESTREG_SR2] );
- OUT_RING( 0 );
+ OUT_RING(GFX_OP_SCISSOR_RECT);
+ OUT_RING(code[I830_DESTREG_SR1]);
+ OUT_RING(code[I830_DESTREG_SR2]);
+ OUT_RING(0);
ADVANCE_LP_RING();
}
-static void i830EmitStippleVerified( drm_device_t *dev,
- unsigned int *code )
+static void i830EmitStippleVerified(drm_device_t * dev, unsigned int *code)
{
- drm_i830_private_t *dev_priv = dev->dev_private;
+ drm_i830_private_t *dev_priv = dev->dev_private;
RING_LOCALS;
- BEGIN_LP_RING( 2 );
- OUT_RING( GFX_OP_STIPPLE );
- OUT_RING( code[1] );
- ADVANCE_LP_RING();
+ BEGIN_LP_RING(2);
+ OUT_RING(GFX_OP_STIPPLE);
+ OUT_RING(code[1]);
+ ADVANCE_LP_RING();
}
-
-static void i830EmitState( drm_device_t *dev )
+static void i830EmitState(drm_device_t * dev)
{
- drm_i830_private_t *dev_priv = dev->dev_private;
- drm_i830_sarea_t *sarea_priv = dev_priv->sarea_priv;
+ drm_i830_private_t *dev_priv = dev->dev_private;
+ drm_i830_sarea_t *sarea_priv = dev_priv->sarea_priv;
unsigned int dirty = sarea_priv->dirty;
DRM_DEBUG("%s %x\n", __FUNCTION__, dirty);
if (dirty & I830_UPLOAD_BUFFERS) {
- i830EmitDestVerified( dev, sarea_priv->BufferState );
+ i830EmitDestVerified(dev, sarea_priv->BufferState);
sarea_priv->dirty &= ~I830_UPLOAD_BUFFERS;
}
if (dirty & I830_UPLOAD_CTX) {
- i830EmitContextVerified( dev, sarea_priv->ContextState );
+ i830EmitContextVerified(dev, sarea_priv->ContextState);
sarea_priv->dirty &= ~I830_UPLOAD_CTX;
}
if (dirty & I830_UPLOAD_TEX0) {
- i830EmitTexVerified( dev, sarea_priv->TexState[0] );
+ i830EmitTexVerified(dev, sarea_priv->TexState[0]);
sarea_priv->dirty &= ~I830_UPLOAD_TEX0;
}
if (dirty & I830_UPLOAD_TEX1) {
- i830EmitTexVerified( dev, sarea_priv->TexState[1] );
+ i830EmitTexVerified(dev, sarea_priv->TexState[1]);
sarea_priv->dirty &= ~I830_UPLOAD_TEX1;
}
if (dirty & I830_UPLOAD_TEXBLEND0) {
- i830EmitTexBlendVerified( dev, sarea_priv->TexBlendState[0],
- sarea_priv->TexBlendStateWordsUsed[0]);
+ i830EmitTexBlendVerified(dev, sarea_priv->TexBlendState[0],
+ sarea_priv->TexBlendStateWordsUsed[0]);
sarea_priv->dirty &= ~I830_UPLOAD_TEXBLEND0;
}
if (dirty & I830_UPLOAD_TEXBLEND1) {
- i830EmitTexBlendVerified( dev, sarea_priv->TexBlendState[1],
- sarea_priv->TexBlendStateWordsUsed[1]);
+ i830EmitTexBlendVerified(dev, sarea_priv->TexBlendState[1],
+ sarea_priv->TexBlendStateWordsUsed[1]);
sarea_priv->dirty &= ~I830_UPLOAD_TEXBLEND1;
}
@@ -759,36 +753,32 @@ static void i830EmitState( drm_device_t *dev )
/* 1.3:
*/
if (dirty & I830_UPLOAD_STIPPLE) {
- i830EmitStippleVerified( dev,
- sarea_priv->StippleState);
+ i830EmitStippleVerified(dev, sarea_priv->StippleState);
sarea_priv->dirty &= ~I830_UPLOAD_STIPPLE;
}
if (dirty & I830_UPLOAD_TEX2) {
- i830EmitTexVerified( dev, sarea_priv->TexState2 );
+ i830EmitTexVerified(dev, sarea_priv->TexState2);
sarea_priv->dirty &= ~I830_UPLOAD_TEX2;
}
if (dirty & I830_UPLOAD_TEX3) {
- i830EmitTexVerified( dev, sarea_priv->TexState3 );
+ i830EmitTexVerified(dev, sarea_priv->TexState3);
sarea_priv->dirty &= ~I830_UPLOAD_TEX3;
}
-
if (dirty & I830_UPLOAD_TEXBLEND2) {
- i830EmitTexBlendVerified(
- dev,
- sarea_priv->TexBlendState2,
- sarea_priv->TexBlendStateWordsUsed2);
+ i830EmitTexBlendVerified(dev,
+ sarea_priv->TexBlendState2,
+ sarea_priv->TexBlendStateWordsUsed2);
sarea_priv->dirty &= ~I830_UPLOAD_TEXBLEND2;
}
if (dirty & I830_UPLOAD_TEXBLEND3) {
- i830EmitTexBlendVerified(
- dev,
- sarea_priv->TexBlendState3,
- sarea_priv->TexBlendStateWordsUsed3);
+ i830EmitTexBlendVerified(dev,
+ sarea_priv->TexBlendState3,
+ sarea_priv->TexBlendStateWordsUsed3);
sarea_priv->dirty &= ~I830_UPLOAD_TEXBLEND3;
}
}
@@ -797,97 +787,96 @@ static void i830EmitState( drm_device_t *dev )
* Performance monitoring functions
*/
-static void i830_fill_box( drm_device_t *dev,
- int x, int y, int w, int h,
- int r, int g, int b )
+static void i830_fill_box(drm_device_t * dev,
+ int x, int y, int w, int h, int r, int g, int b)
{
- drm_i830_private_t *dev_priv = dev->dev_private;
+ drm_i830_private_t *dev_priv = dev->dev_private;
u32 color;
unsigned int BR13, CMD;
RING_LOCALS;
- BR13 = (0xF0 << 16) | (dev_priv->pitch * dev_priv->cpp) | (1<<24);
+ BR13 = (0xF0 << 16) | (dev_priv->pitch * dev_priv->cpp) | (1 << 24);
CMD = XY_COLOR_BLT_CMD;
x += dev_priv->sarea_priv->boxes[0].x1;
y += dev_priv->sarea_priv->boxes[0].y1;
if (dev_priv->cpp == 4) {
- BR13 |= (1<<25);
+ BR13 |= (1 << 25);
CMD |= (XY_COLOR_BLT_WRITE_ALPHA | XY_COLOR_BLT_WRITE_RGB);
- color = (((0xff) << 24) | (r << 16) | (g << 8) | b);
+ color = (((0xff) << 24) | (r << 16) | (g << 8) | b);
} else {
color = (((r & 0xf8) << 8) |
- ((g & 0xfc) << 3) |
- ((b & 0xf8) >> 3));
+ ((g & 0xfc) << 3) | ((b & 0xf8) >> 3));
}
- BEGIN_LP_RING( 6 );
- OUT_RING( CMD );
- OUT_RING( BR13 );
- OUT_RING( (y << 16) | x );
- OUT_RING( ((y+h) << 16) | (x+w) );
+ BEGIN_LP_RING(6);
+ OUT_RING(CMD);
+ OUT_RING(BR13);
+ OUT_RING((y << 16) | x);
+ OUT_RING(((y + h) << 16) | (x + w));
- if ( dev_priv->current_page == 1 ) {
- OUT_RING( dev_priv->front_offset );
- } else {
- OUT_RING( dev_priv->back_offset );
- }
+ if (dev_priv->current_page == 1) {
+ OUT_RING(dev_priv->front_offset);
+ } else {
+ OUT_RING(dev_priv->back_offset);
+ }
- OUT_RING( color );
+ OUT_RING(color);
ADVANCE_LP_RING();
}
-static void i830_cp_performance_boxes( drm_device_t *dev )
+static void i830_cp_performance_boxes(drm_device_t * dev)
{
- drm_i830_private_t *dev_priv = dev->dev_private;
+ drm_i830_private_t *dev_priv = dev->dev_private;
/* Purple box for page flipping
*/
- if ( dev_priv->sarea_priv->perf_boxes & I830_BOX_FLIP )
- i830_fill_box( dev, 4, 4, 8, 8, 255, 0, 255 );
+ if (dev_priv->sarea_priv->perf_boxes & I830_BOX_FLIP)
+ i830_fill_box(dev, 4, 4, 8, 8, 255, 0, 255);
/* Red box if we have to wait for idle at any point
*/
- if ( dev_priv->sarea_priv->perf_boxes & I830_BOX_WAIT )
- i830_fill_box( dev, 16, 4, 8, 8, 255, 0, 0 );
+ if (dev_priv->sarea_priv->perf_boxes & I830_BOX_WAIT)
+ i830_fill_box(dev, 16, 4, 8, 8, 255, 0, 0);
/* Blue box: lost context?
*/
- if ( dev_priv->sarea_priv->perf_boxes & I830_BOX_LOST_CONTEXT )
- i830_fill_box( dev, 28, 4, 8, 8, 0, 0, 255 );
+ if (dev_priv->sarea_priv->perf_boxes & I830_BOX_LOST_CONTEXT)
+ i830_fill_box(dev, 28, 4, 8, 8, 0, 0, 255);
/* Yellow box for texture swaps
*/
- if ( dev_priv->sarea_priv->perf_boxes & I830_BOX_TEXTURE_LOAD )
- i830_fill_box( dev, 40, 4, 8, 8, 255, 255, 0 );
+ if (dev_priv->sarea_priv->perf_boxes & I830_BOX_TEXTURE_LOAD)
+ i830_fill_box(dev, 40, 4, 8, 8, 255, 255, 0);
/* Green box if hardware never idles (as far as we can tell)
*/
- if ( !(dev_priv->sarea_priv->perf_boxes & I830_BOX_RING_EMPTY) )
- i830_fill_box( dev, 64, 4, 8, 8, 0, 255, 0 );
-
+ if (!(dev_priv->sarea_priv->perf_boxes & I830_BOX_RING_EMPTY))
+ i830_fill_box(dev, 64, 4, 8, 8, 0, 255, 0);
- /* Draw bars indicating number of buffers allocated
+ /* Draw bars indicating number of buffers allocated
* (not a great measure, easily confused)
*/
if (dev_priv->dma_used) {
int bar = dev_priv->dma_used / 10240;
- if (bar > 100) bar = 100;
- if (bar < 1) bar = 1;
- i830_fill_box( dev, 4, 16, bar, 4, 196, 128, 128 );
+ if (bar > 100)
+ bar = 100;
+ if (bar < 1)
+ bar = 1;
+ i830_fill_box(dev, 4, 16, bar, 4, 196, 128, 128);
dev_priv->dma_used = 0;
}
dev_priv->sarea_priv->perf_boxes = 0;
}
-static void i830_dma_dispatch_clear( drm_device_t *dev, int flags,
+static void i830_dma_dispatch_clear(drm_device_t * dev, int flags,
unsigned int clear_color,
unsigned int clear_zval,
unsigned int clear_depthmask)
{
- drm_i830_private_t *dev_priv = dev->dev_private;
- drm_i830_sarea_t *sarea_priv = dev_priv->sarea_priv;
+ drm_i830_private_t *dev_priv = dev->dev_private;
+ drm_i830_sarea_t *sarea_priv = dev_priv->sarea_priv;
int nbox = sarea_priv->nbox;
drm_clip_rect_t *pbox = sarea_priv->boxes;
int pitch = dev_priv->pitch;
@@ -896,90 +885,90 @@ static void i830_dma_dispatch_clear( drm_device_t *dev, int flags,
unsigned int BR13, CMD, D_CMD;
RING_LOCALS;
-
- if ( dev_priv->current_page == 1 ) {
+ if (dev_priv->current_page == 1) {
unsigned int tmp = flags;
flags &= ~(I830_FRONT | I830_BACK);
- if ( tmp & I830_FRONT ) flags |= I830_BACK;
- if ( tmp & I830_BACK ) flags |= I830_FRONT;
+ if (tmp & I830_FRONT)
+ flags |= I830_BACK;
+ if (tmp & I830_BACK)
+ flags |= I830_FRONT;
}
- i830_kernel_lost_context(dev);
+ i830_kernel_lost_context(dev);
- switch(cpp) {
- case 2:
- BR13 = (0xF0 << 16) | (pitch * cpp) | (1<<24);
+ switch (cpp) {
+ case 2:
+ BR13 = (0xF0 << 16) | (pitch * cpp) | (1 << 24);
D_CMD = CMD = XY_COLOR_BLT_CMD;
break;
case 4:
- BR13 = (0xF0 << 16) | (pitch * cpp) | (1<<24) | (1<<25);
- CMD = (XY_COLOR_BLT_CMD | XY_COLOR_BLT_WRITE_ALPHA |
+ BR13 = (0xF0 << 16) | (pitch * cpp) | (1 << 24) | (1 << 25);
+ CMD = (XY_COLOR_BLT_CMD | XY_COLOR_BLT_WRITE_ALPHA |
XY_COLOR_BLT_WRITE_RGB);
D_CMD = XY_COLOR_BLT_CMD;
- if(clear_depthmask & 0x00ffffff)
+ if (clear_depthmask & 0x00ffffff)
D_CMD |= XY_COLOR_BLT_WRITE_RGB;
- if(clear_depthmask & 0xff000000)
+ if (clear_depthmask & 0xff000000)
D_CMD |= XY_COLOR_BLT_WRITE_ALPHA;
break;
default:
- BR13 = (0xF0 << 16) | (pitch * cpp) | (1<<24);
+ BR13 = (0xF0 << 16) | (pitch * cpp) | (1 << 24);
D_CMD = CMD = XY_COLOR_BLT_CMD;
break;
}
- if (nbox > I830_NR_SAREA_CLIPRECTS)
- nbox = I830_NR_SAREA_CLIPRECTS;
+ if (nbox > I830_NR_SAREA_CLIPRECTS)
+ nbox = I830_NR_SAREA_CLIPRECTS;
- for (i = 0 ; i < nbox ; i++, pbox++) {
+ for (i = 0; i < nbox; i++, pbox++) {
if (pbox->x1 > pbox->x2 ||
pbox->y1 > pbox->y2 ||
- pbox->x2 > dev_priv->w ||
- pbox->y2 > dev_priv->h)
+ pbox->x2 > dev_priv->w || pbox->y2 > dev_priv->h)
continue;
- if ( flags & I830_FRONT ) {
- DRM_DEBUG("clear front\n");
- BEGIN_LP_RING( 6 );
- OUT_RING( CMD );
- OUT_RING( BR13 );
- OUT_RING( (pbox->y1 << 16) | pbox->x1 );
- OUT_RING( (pbox->y2 << 16) | pbox->x2 );
- OUT_RING( dev_priv->front_offset );
- OUT_RING( clear_color );
+ if (flags & I830_FRONT) {
+ DRM_DEBUG("clear front\n");
+ BEGIN_LP_RING(6);
+ OUT_RING(CMD);
+ OUT_RING(BR13);
+ OUT_RING((pbox->y1 << 16) | pbox->x1);
+ OUT_RING((pbox->y2 << 16) | pbox->x2);
+ OUT_RING(dev_priv->front_offset);
+ OUT_RING(clear_color);
ADVANCE_LP_RING();
}
- if ( flags & I830_BACK ) {
+ if (flags & I830_BACK) {
DRM_DEBUG("clear back\n");
- BEGIN_LP_RING( 6 );
- OUT_RING( CMD );
- OUT_RING( BR13 );
- OUT_RING( (pbox->y1 << 16) | pbox->x1 );
- OUT_RING( (pbox->y2 << 16) | pbox->x2 );
- OUT_RING( dev_priv->back_offset );
- OUT_RING( clear_color );
+ BEGIN_LP_RING(6);
+ OUT_RING(CMD);
+ OUT_RING(BR13);
+ OUT_RING((pbox->y1 << 16) | pbox->x1);
+ OUT_RING((pbox->y2 << 16) | pbox->x2);
+ OUT_RING(dev_priv->back_offset);
+ OUT_RING(clear_color);
ADVANCE_LP_RING();
}
- if ( flags & I830_DEPTH ) {
+ if (flags & I830_DEPTH) {
DRM_DEBUG("clear depth\n");
- BEGIN_LP_RING( 6 );
- OUT_RING( D_CMD );
- OUT_RING( BR13 );
- OUT_RING( (pbox->y1 << 16) | pbox->x1 );
- OUT_RING( (pbox->y2 << 16) | pbox->x2 );
- OUT_RING( dev_priv->depth_offset );
- OUT_RING( clear_zval );
+ BEGIN_LP_RING(6);
+ OUT_RING(D_CMD);
+ OUT_RING(BR13);
+ OUT_RING((pbox->y1 << 16) | pbox->x1);
+ OUT_RING((pbox->y2 << 16) | pbox->x2);
+ OUT_RING(dev_priv->depth_offset);
+ OUT_RING(clear_zval);
ADVANCE_LP_RING();
}
}
}
-static void i830_dma_dispatch_swap( drm_device_t *dev )
+static void i830_dma_dispatch_swap(drm_device_t * dev)
{
- drm_i830_private_t *dev_priv = dev->dev_private;
- drm_i830_sarea_t *sarea_priv = dev_priv->sarea_priv;
+ drm_i830_private_t *dev_priv = dev->dev_private;
+ drm_i830_sarea_t *sarea_priv = dev_priv->sarea_priv;
int nbox = sarea_priv->nbox;
drm_clip_rect_t *pbox = sarea_priv->boxes;
int pitch = dev_priv->pitch;
@@ -990,202 +979,192 @@ static void i830_dma_dispatch_swap( drm_device_t *dev )
DRM_DEBUG("swapbuffers\n");
- i830_kernel_lost_context(dev);
+ i830_kernel_lost_context(dev);
if (dev_priv->do_boxes)
- i830_cp_performance_boxes( dev );
+ i830_cp_performance_boxes(dev);
- switch(cpp) {
- case 2:
- BR13 = (pitch * cpp) | (0xCC << 16) | (1<<24);
+ switch (cpp) {
+ case 2:
+ BR13 = (pitch * cpp) | (0xCC << 16) | (1 << 24);
CMD = XY_SRC_COPY_BLT_CMD;
break;
case 4:
- BR13 = (pitch * cpp) | (0xCC << 16) | (1<<24) | (1<<25);
+ BR13 = (pitch * cpp) | (0xCC << 16) | (1 << 24) | (1 << 25);
CMD = (XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA |
XY_SRC_COPY_BLT_WRITE_RGB);
break;
default:
- BR13 = (pitch * cpp) | (0xCC << 16) | (1<<24);
+ BR13 = (pitch * cpp) | (0xCC << 16) | (1 << 24);
CMD = XY_SRC_COPY_BLT_CMD;
break;
}
+ if (nbox > I830_NR_SAREA_CLIPRECTS)
+ nbox = I830_NR_SAREA_CLIPRECTS;
- if (nbox > I830_NR_SAREA_CLIPRECTS)
- nbox = I830_NR_SAREA_CLIPRECTS;
-
- for (i = 0 ; i < nbox; i++, pbox++)
- {
+ for (i = 0; i < nbox; i++, pbox++) {
if (pbox->x1 > pbox->x2 ||
pbox->y1 > pbox->y2 ||
- pbox->x2 > dev_priv->w ||
- pbox->y2 > dev_priv->h)
+ pbox->x2 > dev_priv->w || pbox->y2 > dev_priv->h)
continue;
-
+
DRM_DEBUG("dispatch swap %d,%d-%d,%d!\n",
- pbox->x1, pbox->y1,
- pbox->x2, pbox->y2);
+ pbox->x1, pbox->y1, pbox->x2, pbox->y2);
- BEGIN_LP_RING( 8 );
- OUT_RING( CMD );
- OUT_RING( BR13 );
- OUT_RING( (pbox->y1 << 16) | pbox->x1 );
- OUT_RING( (pbox->y2 << 16) | pbox->x2 );
+ BEGIN_LP_RING(8);
+ OUT_RING(CMD);
+ OUT_RING(BR13);
+ OUT_RING((pbox->y1 << 16) | pbox->x1);
+ OUT_RING((pbox->y2 << 16) | pbox->x2);
- if (dev_priv->current_page == 0)
- OUT_RING( dev_priv->front_offset );
+ if (dev_priv->current_page == 0)
+ OUT_RING(dev_priv->front_offset);
else
- OUT_RING( dev_priv->back_offset );
+ OUT_RING(dev_priv->back_offset);
- OUT_RING( (pbox->y1 << 16) | pbox->x1 );
- OUT_RING( BR13 & 0xffff );
+ OUT_RING((pbox->y1 << 16) | pbox->x1);
+ OUT_RING(BR13 & 0xffff);
- if (dev_priv->current_page == 0)
- OUT_RING( dev_priv->back_offset );
+ if (dev_priv->current_page == 0)
+ OUT_RING(dev_priv->back_offset);
else
- OUT_RING( dev_priv->front_offset );
+ OUT_RING(dev_priv->front_offset);
ADVANCE_LP_RING();
}
}
-static void i830_dma_dispatch_flip( drm_device_t *dev )
+static void i830_dma_dispatch_flip(drm_device_t * dev)
{
- drm_i830_private_t *dev_priv = dev->dev_private;
+ drm_i830_private_t *dev_priv = dev->dev_private;
RING_LOCALS;
- DRM_DEBUG( "%s: page=%d pfCurrentPage=%d\n",
- __FUNCTION__,
- dev_priv->current_page,
- dev_priv->sarea_priv->pf_current_page);
+ DRM_DEBUG("%s: page=%d pfCurrentPage=%d\n",
+ __FUNCTION__,
+ dev_priv->current_page,
+ dev_priv->sarea_priv->pf_current_page);
- i830_kernel_lost_context(dev);
+ i830_kernel_lost_context(dev);
if (dev_priv->do_boxes) {
dev_priv->sarea_priv->perf_boxes |= I830_BOX_FLIP;
- i830_cp_performance_boxes( dev );
+ i830_cp_performance_boxes(dev);
}
-
- BEGIN_LP_RING( 2 );
- OUT_RING( INST_PARSER_CLIENT | INST_OP_FLUSH | INST_FLUSH_MAP_CACHE );
- OUT_RING( 0 );
+ BEGIN_LP_RING(2);
+ OUT_RING(INST_PARSER_CLIENT | INST_OP_FLUSH | INST_FLUSH_MAP_CACHE);
+ OUT_RING(0);
ADVANCE_LP_RING();
- BEGIN_LP_RING( 6 );
- OUT_RING( CMD_OP_DISPLAYBUFFER_INFO | ASYNC_FLIP );
- OUT_RING( 0 );
- if ( dev_priv->current_page == 0 ) {
- OUT_RING( dev_priv->back_offset );
+ BEGIN_LP_RING(6);
+ OUT_RING(CMD_OP_DISPLAYBUFFER_INFO | ASYNC_FLIP);
+ OUT_RING(0);
+ if (dev_priv->current_page == 0) {
+ OUT_RING(dev_priv->back_offset);
dev_priv->current_page = 1;
} else {
- OUT_RING( dev_priv->front_offset );
+ OUT_RING(dev_priv->front_offset);
dev_priv->current_page = 0;
}
OUT_RING(0);
ADVANCE_LP_RING();
-
- BEGIN_LP_RING( 2 );
- OUT_RING( MI_WAIT_FOR_EVENT |
- MI_WAIT_FOR_PLANE_A_FLIP );
- OUT_RING( 0 );
+ BEGIN_LP_RING(2);
+ OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_PLANE_A_FLIP);
+ OUT_RING(0);
ADVANCE_LP_RING();
-
dev_priv->sarea_priv->pf_current_page = dev_priv->current_page;
}
-static void i830_dma_dispatch_vertex(drm_device_t *dev,
- drm_buf_t *buf,
- int discard,
- int used)
+static void i830_dma_dispatch_vertex(drm_device_t * dev,
+ drm_buf_t * buf, int discard, int used)
{
- drm_i830_private_t *dev_priv = dev->dev_private;
+ drm_i830_private_t *dev_priv = dev->dev_private;
drm_i830_buf_priv_t *buf_priv = buf->dev_private;
- drm_i830_sarea_t *sarea_priv = dev_priv->sarea_priv;
- drm_clip_rect_t *box = sarea_priv->boxes;
- int nbox = sarea_priv->nbox;
+ drm_i830_sarea_t *sarea_priv = dev_priv->sarea_priv;
+ drm_clip_rect_t *box = sarea_priv->boxes;
+ int nbox = sarea_priv->nbox;
unsigned long address = (unsigned long)buf->bus_address;
- unsigned long start = address - dev->agp->base;
+ unsigned long start = address - dev->agp->base;
int i = 0, u;
- RING_LOCALS;
+ RING_LOCALS;
- i830_kernel_lost_context(dev);
+ i830_kernel_lost_context(dev);
- if (nbox > I830_NR_SAREA_CLIPRECTS)
+ if (nbox > I830_NR_SAREA_CLIPRECTS)
nbox = I830_NR_SAREA_CLIPRECTS;
if (discard) {
- u = cmpxchg(buf_priv->in_use, I830_BUF_CLIENT,
+ u = cmpxchg(buf_priv->in_use, I830_BUF_CLIENT,
I830_BUF_HARDWARE);
- if(u != I830_BUF_CLIENT) {
+ if (u != I830_BUF_CLIENT) {
DRM_DEBUG("xxxx 2\n");
}
}
- if (used > 4*1023)
+ if (used > 4 * 1023)
used = 0;
if (sarea_priv->dirty)
- i830EmitState( dev );
+ i830EmitState(dev);
- DRM_DEBUG("dispatch vertex addr 0x%lx, used 0x%x nbox %d\n",
+ DRM_DEBUG("dispatch vertex addr 0x%lx, used 0x%x nbox %d\n",
address, used, nbox);
- dev_priv->counter++;
- DRM_DEBUG( "dispatch counter : %ld\n", dev_priv->counter);
- DRM_DEBUG( "i830_dma_dispatch\n");
- DRM_DEBUG( "start : %lx\n", start);
- DRM_DEBUG( "used : %d\n", used);
- DRM_DEBUG( "start + used - 4 : %ld\n", start + used - 4);
+ dev_priv->counter++;
+ DRM_DEBUG("dispatch counter : %ld\n", dev_priv->counter);
+ DRM_DEBUG("i830_dma_dispatch\n");
+ DRM_DEBUG("start : %lx\n", start);
+ DRM_DEBUG("used : %d\n", used);
+ DRM_DEBUG("start + used - 4 : %ld\n", start + used - 4);
if (buf_priv->currently_mapped == I830_BUF_MAPPED) {
u32 *vp = buf_priv->kernel_virtual;
vp[0] = (GFX_OP_PRIMITIVE |
- sarea_priv->vertex_prim |
- ((used/4)-2));
+ sarea_priv->vertex_prim | ((used / 4) - 2));
if (dev_priv->use_mi_batchbuffer_start) {
- vp[used/4] = MI_BATCH_BUFFER_END;
- used += 4;
+ vp[used / 4] = MI_BATCH_BUFFER_END;
+ used += 4;
}
-
+
if (used & 4) {
- vp[used/4] = 0;
+ vp[used / 4] = 0;
used += 4;
}
i830_unmap_buffer(buf);
}
-
+
if (used) {
do {
if (i < nbox) {
BEGIN_LP_RING(6);
- OUT_RING( GFX_OP_DRAWRECT_INFO );
- OUT_RING( sarea_priv->BufferState[I830_DESTREG_DR1] );
- OUT_RING( box[i].x1 | (box[i].y1<<16) );
- OUT_RING( box[i].x2 | (box[i].y2<<16) );
- OUT_RING( sarea_priv->BufferState[I830_DESTREG_DR4] );
- OUT_RING( 0 );
+ OUT_RING(GFX_OP_DRAWRECT_INFO);
+ OUT_RING(sarea_priv->
+ BufferState[I830_DESTREG_DR1]);
+ OUT_RING(box[i].x1 | (box[i].y1 << 16));
+ OUT_RING(box[i].x2 | (box[i].y2 << 16));
+ OUT_RING(sarea_priv->
+ BufferState[I830_DESTREG_DR4]);
+ OUT_RING(0);
ADVANCE_LP_RING();
}
if (dev_priv->use_mi_batchbuffer_start) {
BEGIN_LP_RING(2);
- OUT_RING( MI_BATCH_BUFFER_START | (2<<6) );
- OUT_RING( start | MI_BATCH_NON_SECURE );
+ OUT_RING(MI_BATCH_BUFFER_START | (2 << 6));
+ OUT_RING(start | MI_BATCH_NON_SECURE);
ADVANCE_LP_RING();
- }
- else {
+ } else {
BEGIN_LP_RING(4);
- OUT_RING( MI_BATCH_BUFFER );
- OUT_RING( start | MI_BATCH_NON_SECURE );
- OUT_RING( start + used - 4 );
- OUT_RING( 0 );
+ OUT_RING(MI_BATCH_BUFFER);
+ OUT_RING(start | MI_BATCH_NON_SECURE);
+ OUT_RING(start + used - 4);
+ OUT_RING(0);
ADVANCE_LP_RING();
}
@@ -1195,61 +1174,60 @@ static void i830_dma_dispatch_vertex(drm_device_t *dev,
if (discard) {
dev_priv->counter++;
- (void) cmpxchg(buf_priv->in_use, I830_BUF_CLIENT,
- I830_BUF_HARDWARE);
+ (void)cmpxchg(buf_priv->in_use, I830_BUF_CLIENT,
+ I830_BUF_HARDWARE);
BEGIN_LP_RING(8);
- OUT_RING( CMD_STORE_DWORD_IDX );
- OUT_RING( 20 );
- OUT_RING( dev_priv->counter );
- OUT_RING( CMD_STORE_DWORD_IDX );
- OUT_RING( buf_priv->my_use_idx );
- OUT_RING( I830_BUF_FREE );
- OUT_RING( CMD_REPORT_HEAD );
- OUT_RING( 0 );
+ OUT_RING(CMD_STORE_DWORD_IDX);
+ OUT_RING(20);
+ OUT_RING(dev_priv->counter);
+ OUT_RING(CMD_STORE_DWORD_IDX);
+ OUT_RING(buf_priv->my_use_idx);
+ OUT_RING(I830_BUF_FREE);
+ OUT_RING(CMD_REPORT_HEAD);
+ OUT_RING(0);
ADVANCE_LP_RING();
}
}
-
-static void i830_dma_quiescent(drm_device_t *dev)
+static void i830_dma_quiescent(drm_device_t * dev)
{
- drm_i830_private_t *dev_priv = dev->dev_private;
- RING_LOCALS;
+ drm_i830_private_t *dev_priv = dev->dev_private;
+ RING_LOCALS;
- i830_kernel_lost_context(dev);
+ i830_kernel_lost_context(dev);
- BEGIN_LP_RING(4);
- OUT_RING( INST_PARSER_CLIENT | INST_OP_FLUSH | INST_FLUSH_MAP_CACHE );
- OUT_RING( CMD_REPORT_HEAD );
- OUT_RING( 0 );
- OUT_RING( 0 );
- ADVANCE_LP_RING();
+ BEGIN_LP_RING(4);
+ OUT_RING(INST_PARSER_CLIENT | INST_OP_FLUSH | INST_FLUSH_MAP_CACHE);
+ OUT_RING(CMD_REPORT_HEAD);
+ OUT_RING(0);
+ OUT_RING(0);
+ ADVANCE_LP_RING();
- i830_wait_ring( dev, dev_priv->ring.Size - 8, __FUNCTION__ );
+ i830_wait_ring(dev, dev_priv->ring.Size - 8, __FUNCTION__);
}
-static int i830_flush_queue(drm_device_t *dev)
+static int i830_flush_queue(drm_device_t * dev)
{
- drm_i830_private_t *dev_priv = dev->dev_private;
+ drm_i830_private_t *dev_priv = dev->dev_private;
drm_device_dma_t *dma = dev->dma;
- int i, ret = 0;
- RING_LOCALS;
-
- i830_kernel_lost_context(dev);
-
- BEGIN_LP_RING(2);
- OUT_RING( CMD_REPORT_HEAD );
- OUT_RING( 0 );
- ADVANCE_LP_RING();
-
- i830_wait_ring( dev, dev_priv->ring.Size - 8, __FUNCTION__ );
-
- for (i = 0; i < dma->buf_count; i++) {
- drm_buf_t *buf = dma->buflist[ i ];
- drm_i830_buf_priv_t *buf_priv = buf->dev_private;
-
- int used = cmpxchg(buf_priv->in_use, I830_BUF_HARDWARE,
+ int i, ret = 0;
+ RING_LOCALS;
+
+ i830_kernel_lost_context(dev);
+
+ BEGIN_LP_RING(2);
+ OUT_RING(CMD_REPORT_HEAD);
+ OUT_RING(0);
+ ADVANCE_LP_RING();
+
+ i830_wait_ring(dev, dev_priv->ring.Size - 8, __FUNCTION__);
+
+ for (i = 0; i < dma->buf_count; i++) {
+ drm_buf_t *buf = dma->buflist[i];
+ drm_i830_buf_priv_t *buf_priv = buf->dev_private;
+
+ int used = cmpxchg(buf_priv->in_use, I830_BUF_HARDWARE,
I830_BUF_FREE);
if (used == I830_BUF_HARDWARE)
@@ -1258,62 +1236,66 @@ static int i830_flush_queue(drm_device_t *dev)
DRM_DEBUG("still on client\n");
}
- return ret;
+ return ret;
}
/* Must be called with the lock held */
-void i830_reclaim_buffers(drm_device_t *dev, struct file *filp)
+void i830_reclaim_buffers(drm_device_t * dev, struct file *filp)
{
drm_device_dma_t *dma = dev->dma;
- int i;
+ int i;
- if (!dma) return;
- if (!dev->dev_private) return;
- if (!dma->buflist) return;
+ if (!dma)
+ return;
+ if (!dev->dev_private)
+ return;
+ if (!dma->buflist)
+ return;
- i830_flush_queue(dev);
+ i830_flush_queue(dev);
for (i = 0; i < dma->buf_count; i++) {
- drm_buf_t *buf = dma->buflist[ i ];
- drm_i830_buf_priv_t *buf_priv = buf->dev_private;
-
+ drm_buf_t *buf = dma->buflist[i];
+ drm_i830_buf_priv_t *buf_priv = buf->dev_private;
+
if (buf->filp == filp && buf_priv) {
- int used = cmpxchg(buf_priv->in_use, I830_BUF_CLIENT,
+ int used = cmpxchg(buf_priv->in_use, I830_BUF_CLIENT,
I830_BUF_FREE);
if (used == I830_BUF_CLIENT)
DRM_DEBUG("reclaimed from client\n");
- if(buf_priv->currently_mapped == I830_BUF_MAPPED)
- buf_priv->currently_mapped = I830_BUF_UNMAPPED;
+ if (buf_priv->currently_mapped == I830_BUF_MAPPED)
+ buf_priv->currently_mapped = I830_BUF_UNMAPPED;
}
}
}
-static int i830_flush_ioctl(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg)
+static int i830_flush_ioctl(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg)
{
- drm_file_t *priv = filp->private_data;
- drm_device_t *dev = priv->head->dev;
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->head->dev;
LOCK_TEST_WITH_RETURN(dev, filp);
- i830_flush_queue(dev);
- return 0;
+ i830_flush_queue(dev);
+ return 0;
}
static int i830_dma_vertex(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg)
+ unsigned int cmd, unsigned long arg)
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->head->dev;
drm_device_dma_t *dma = dev->dma;
- drm_i830_private_t *dev_priv = (drm_i830_private_t *)dev->dev_private;
- u32 *hw_status = dev_priv->hw_status_page;
- drm_i830_sarea_t *sarea_priv = (drm_i830_sarea_t *)
- dev_priv->sarea_priv;
+ drm_i830_private_t *dev_priv = (drm_i830_private_t *) dev->dev_private;
+ u32 *hw_status = dev_priv->hw_status_page;
+ drm_i830_sarea_t *sarea_priv = (drm_i830_sarea_t *)
+ dev_priv->sarea_priv;
drm_i830_vertex_t vertex;
- if (copy_from_user(&vertex, (drm_i830_vertex_t __user *)arg, sizeof(vertex)))
+ if (copy_from_user
+ (&vertex, (drm_i830_vertex_t __user *) arg, sizeof(vertex)))
return -EFAULT;
LOCK_TEST_WITH_RETURN(dev, filp);
@@ -1321,15 +1303,16 @@ static int i830_dma_vertex(struct inode *inode, struct file *filp,
DRM_DEBUG("i830 dma vertex, idx %d used %d discard %d\n",
vertex.idx, vertex.used, vertex.discard);
- if(vertex.idx < 0 || vertex.idx > dma->buf_count) return -EINVAL;
+ if (vertex.idx < 0 || vertex.idx > dma->buf_count)
+ return -EINVAL;
- i830_dma_dispatch_vertex( dev,
- dma->buflist[ vertex.idx ],
- vertex.discard, vertex.used );
+ i830_dma_dispatch_vertex(dev,
+ dma->buflist[vertex.idx],
+ vertex.discard, vertex.used);
+
+ sarea_priv->last_enqueue = dev_priv->counter - 1;
+ sarea_priv->last_dispatch = (int)hw_status[5];
- sarea_priv->last_enqueue = dev_priv->counter-1;
- sarea_priv->last_dispatch = (int) hw_status[5];
-
return 0;
}
@@ -1340,9 +1323,10 @@ static int i830_clear_bufs(struct inode *inode, struct file *filp,
drm_device_t *dev = priv->head->dev;
drm_i830_clear_t clear;
- if (copy_from_user(&clear, (drm_i830_clear_t __user *)arg, sizeof(clear)))
+ if (copy_from_user
+ (&clear, (drm_i830_clear_t __user *) arg, sizeof(clear)))
return -EFAULT;
-
+
LOCK_TEST_WITH_RETURN(dev, filp);
/* GH: Someone's doing nasty things... */
@@ -1350,11 +1334,10 @@ static int i830_clear_bufs(struct inode *inode, struct file *filp,
return -EINVAL;
}
- i830_dma_dispatch_clear( dev, clear.flags,
- clear.clear_color,
- clear.clear_depth,
- clear.clear_depthmask);
- return 0;
+ i830_dma_dispatch_clear(dev, clear.flags,
+ clear.clear_color,
+ clear.clear_depth, clear.clear_depthmask);
+ return 0;
}
static int i830_swap_bufs(struct inode *inode, struct file *filp,
@@ -1362,20 +1345,18 @@ static int i830_swap_bufs(struct inode *inode, struct file *filp,
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->head->dev;
-
+
DRM_DEBUG("i830_swap_bufs\n");
LOCK_TEST_WITH_RETURN(dev, filp);
- i830_dma_dispatch_swap( dev );
- return 0;
+ i830_dma_dispatch_swap(dev);
+ return 0;
}
-
-
/* Not sure why this isn't set all the time:
- */
-static void i830_do_init_pageflip( drm_device_t *dev )
+ */
+static void i830_do_init_pageflip(drm_device_t * dev)
{
drm_i830_private_t *dev_priv = dev->dev_private;
@@ -1385,20 +1366,20 @@ static void i830_do_init_pageflip( drm_device_t *dev )
dev_priv->sarea_priv->pf_current_page = dev_priv->current_page;
}
-static int i830_do_cleanup_pageflip( drm_device_t *dev )
+static int i830_do_cleanup_pageflip(drm_device_t * dev)
{
drm_i830_private_t *dev_priv = dev->dev_private;
DRM_DEBUG("%s\n", __FUNCTION__);
if (dev_priv->current_page != 0)
- i830_dma_dispatch_flip( dev );
+ i830_dma_dispatch_flip(dev);
dev_priv->page_flipping = 0;
return 0;
}
static int i830_flip_bufs(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg)
+ unsigned int cmd, unsigned long arg)
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->head->dev;
@@ -1408,45 +1389,45 @@ static int i830_flip_bufs(struct inode *inode, struct file *filp,
LOCK_TEST_WITH_RETURN(dev, filp);
- if (!dev_priv->page_flipping)
- i830_do_init_pageflip( dev );
+ if (!dev_priv->page_flipping)
+ i830_do_init_pageflip(dev);
- i830_dma_dispatch_flip( dev );
- return 0;
+ i830_dma_dispatch_flip(dev);
+ return 0;
}
static int i830_getage(struct inode *inode, struct file *filp, unsigned int cmd,
- unsigned long arg)
+ unsigned long arg)
{
- drm_file_t *priv = filp->private_data;
- drm_device_t *dev = priv->head->dev;
- drm_i830_private_t *dev_priv = (drm_i830_private_t *)dev->dev_private;
- u32 *hw_status = dev_priv->hw_status_page;
- drm_i830_sarea_t *sarea_priv = (drm_i830_sarea_t *)
- dev_priv->sarea_priv;
-
- sarea_priv->last_dispatch = (int) hw_status[5];
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->head->dev;
+ drm_i830_private_t *dev_priv = (drm_i830_private_t *) dev->dev_private;
+ u32 *hw_status = dev_priv->hw_status_page;
+ drm_i830_sarea_t *sarea_priv = (drm_i830_sarea_t *)
+ dev_priv->sarea_priv;
+
+ sarea_priv->last_dispatch = (int)hw_status[5];
return 0;
}
static int i830_getbuf(struct inode *inode, struct file *filp, unsigned int cmd,
- unsigned long arg)
+ unsigned long arg)
{
- drm_file_t *priv = filp->private_data;
- drm_device_t *dev = priv->head->dev;
- int retcode = 0;
- drm_i830_dma_t d;
- drm_i830_private_t *dev_priv = (drm_i830_private_t *)dev->dev_private;
- u32 *hw_status = dev_priv->hw_status_page;
- drm_i830_sarea_t *sarea_priv = (drm_i830_sarea_t *)
- dev_priv->sarea_priv;
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->head->dev;
+ int retcode = 0;
+ drm_i830_dma_t d;
+ drm_i830_private_t *dev_priv = (drm_i830_private_t *) dev->dev_private;
+ u32 *hw_status = dev_priv->hw_status_page;
+ drm_i830_sarea_t *sarea_priv = (drm_i830_sarea_t *)
+ dev_priv->sarea_priv;
DRM_DEBUG("getbuf\n");
- if (copy_from_user(&d, (drm_i830_dma_t __user *)arg, sizeof(d)))
+ if (copy_from_user(&d, (drm_i830_dma_t __user *) arg, sizeof(d)))
return -EFAULT;
-
+
LOCK_TEST_WITH_RETURN(dev, filp);
-
+
d.granted = 0;
retcode = i830_dma_get_buffer(dev, &d, filp);
@@ -1454,46 +1435,45 @@ static int i830_getbuf(struct inode *inode, struct file *filp, unsigned int cmd,
DRM_DEBUG("i830_dma: %d returning %d, granted = %d\n",
current->pid, retcode, d.granted);
- if (copy_to_user((drm_dma_t __user *)arg, &d, sizeof(d)))
+ if (copy_to_user((drm_dma_t __user *) arg, &d, sizeof(d)))
return -EFAULT;
- sarea_priv->last_dispatch = (int) hw_status[5];
+ sarea_priv->last_dispatch = (int)hw_status[5];
return retcode;
}
static int i830_copybuf(struct inode *inode,
- struct file *filp, unsigned int cmd, unsigned long arg)
+ struct file *filp, unsigned int cmd, unsigned long arg)
{
/* Never copy - 2.4.x doesn't need it */
return 0;
}
static int i830_docopy(struct inode *inode, struct file *filp, unsigned int cmd,
- unsigned long arg)
+ unsigned long arg)
{
return 0;
}
-
-
-static int i830_getparam( struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg )
+static int i830_getparam(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg)
{
- drm_file_t *priv = filp->private_data;
- drm_device_t *dev = priv->head->dev;
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->head->dev;
drm_i830_private_t *dev_priv = dev->dev_private;
drm_i830_getparam_t param;
int value;
- if ( !dev_priv ) {
- DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
+ if (!dev_priv) {
+ DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
return -EINVAL;
}
- if (copy_from_user(&param, (drm_i830_getparam_t __user *)arg, sizeof(param) ))
+ if (copy_from_user
+ (&param, (drm_i830_getparam_t __user *) arg, sizeof(param)))
return -EFAULT;
- switch( param.param ) {
+ switch (param.param) {
case I830_PARAM_IRQ_ACTIVE:
value = dev->irq_enabled;
break;
@@ -1501,32 +1481,32 @@ static int i830_getparam( struct inode *inode, struct file *filp,
return -EINVAL;
}
- if ( copy_to_user( param.value, &value, sizeof(int) ) ) {
- DRM_ERROR( "copy_to_user\n" );
+ if (copy_to_user(param.value, &value, sizeof(int))) {
+ DRM_ERROR("copy_to_user\n");
return -EFAULT;
}
-
+
return 0;
}
-
-static int i830_setparam( struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg )
+static int i830_setparam(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg)
{
- drm_file_t *priv = filp->private_data;
- drm_device_t *dev = priv->head->dev;
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->head->dev;
drm_i830_private_t *dev_priv = dev->dev_private;
drm_i830_setparam_t param;
- if ( !dev_priv ) {
- DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
+ if (!dev_priv) {
+ DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
return -EINVAL;
}
- if (copy_from_user(&param, (drm_i830_setparam_t __user *)arg, sizeof(param) ))
+ if (copy_from_user
+ (&param, (drm_i830_setparam_t __user *) arg, sizeof(param)))
return -EFAULT;
- switch( param.param ) {
+ switch (param.param) {
case I830_SETPARAM_USE_MI_BATCHBUFFER_START:
dev_priv->use_mi_batchbuffer_start = param.value;
break;
@@ -1537,13 +1517,12 @@ static int i830_setparam( struct inode *inode, struct file *filp,
return 0;
}
-
-void i830_driver_pretakedown(drm_device_t *dev)
+void i830_driver_pretakedown(drm_device_t * dev)
{
- i830_dma_cleanup( dev );
+ i830_dma_cleanup(dev);
}
-void i830_driver_prerelease(drm_device_t *dev, DRMFILE filp)
+void i830_driver_prerelease(drm_device_t * dev, DRMFILE filp)
{
if (dev->dev_private) {
drm_i830_private_t *dev_priv = dev->dev_private;
@@ -1553,32 +1532,32 @@ void i830_driver_prerelease(drm_device_t *dev, DRMFILE filp)
}
}
-void i830_driver_release(drm_device_t *dev, struct file *filp)
+void i830_driver_release(drm_device_t * dev, struct file *filp)
{
i830_reclaim_buffers(dev, filp);
}
-int i830_driver_dma_quiescent(drm_device_t *dev)
+int i830_driver_dma_quiescent(drm_device_t * dev)
{
- i830_dma_quiescent( dev );
+ i830_dma_quiescent(dev);
return 0;
}
drm_ioctl_desc_t i830_ioctls[] = {
- [DRM_IOCTL_NR(DRM_I830_INIT)] = { i830_dma_init, 1, 1 },
- [DRM_IOCTL_NR(DRM_I830_VERTEX)] = { i830_dma_vertex, 1, 0 },
- [DRM_IOCTL_NR(DRM_I830_CLEAR)] = { i830_clear_bufs, 1, 0 },
- [DRM_IOCTL_NR(DRM_I830_FLUSH)] = { i830_flush_ioctl, 1, 0 },
- [DRM_IOCTL_NR(DRM_I830_GETAGE)] = { i830_getage, 1, 0 },
- [DRM_IOCTL_NR(DRM_I830_GETBUF)] = { i830_getbuf, 1, 0 },
- [DRM_IOCTL_NR(DRM_I830_SWAP)] = { i830_swap_bufs, 1, 0 },
- [DRM_IOCTL_NR(DRM_I830_COPY)] = { i830_copybuf, 1, 0 },
- [DRM_IOCTL_NR(DRM_I830_DOCOPY)] = { i830_docopy, 1, 0 },
- [DRM_IOCTL_NR(DRM_I830_FLIP)] = { i830_flip_bufs, 1, 0 },
- [DRM_IOCTL_NR(DRM_I830_IRQ_EMIT)] = { i830_irq_emit, 1, 0 },
- [DRM_IOCTL_NR(DRM_I830_IRQ_WAIT)] = { i830_irq_wait, 1, 0 },
- [DRM_IOCTL_NR(DRM_I830_GETPARAM)] = { i830_getparam, 1, 0 },
- [DRM_IOCTL_NR(DRM_I830_SETPARAM)] = { i830_setparam, 1, 0 }
+ [DRM_IOCTL_NR(DRM_I830_INIT)] = {i830_dma_init, 1, 1},
+ [DRM_IOCTL_NR(DRM_I830_VERTEX)] = {i830_dma_vertex, 1, 0},
+ [DRM_IOCTL_NR(DRM_I830_CLEAR)] = {i830_clear_bufs, 1, 0},
+ [DRM_IOCTL_NR(DRM_I830_FLUSH)] = {i830_flush_ioctl, 1, 0},
+ [DRM_IOCTL_NR(DRM_I830_GETAGE)] = {i830_getage, 1, 0},
+ [DRM_IOCTL_NR(DRM_I830_GETBUF)] = {i830_getbuf, 1, 0},
+ [DRM_IOCTL_NR(DRM_I830_SWAP)] = {i830_swap_bufs, 1, 0},
+ [DRM_IOCTL_NR(DRM_I830_COPY)] = {i830_copybuf, 1, 0},
+ [DRM_IOCTL_NR(DRM_I830_DOCOPY)] = {i830_docopy, 1, 0},
+ [DRM_IOCTL_NR(DRM_I830_FLIP)] = {i830_flip_bufs, 1, 0},
+ [DRM_IOCTL_NR(DRM_I830_IRQ_EMIT)] = {i830_irq_emit, 1, 0},
+ [DRM_IOCTL_NR(DRM_I830_IRQ_WAIT)] = {i830_irq_wait, 1, 0},
+ [DRM_IOCTL_NR(DRM_I830_GETPARAM)] = {i830_getparam, 1, 0},
+ [DRM_IOCTL_NR(DRM_I830_SETPARAM)] = {i830_setparam, 1, 0}
};
int i830_max_ioctl = DRM_ARRAY_SIZE(i830_ioctls);
diff --git a/drivers/char/drm/i830_drm.h b/drivers/char/drm/i830_drm.h
index 03382c0beee3..66dd75027967 100644
--- a/drivers/char/drm/i830_drm.h
+++ b/drivers/char/drm/i830_drm.h
@@ -33,14 +33,14 @@
#define I830_UPLOAD_CTX 0x1
#define I830_UPLOAD_BUFFERS 0x2
#define I830_UPLOAD_CLIPRECTS 0x4
-#define I830_UPLOAD_TEX0_IMAGE 0x100 /* handled clientside */
-#define I830_UPLOAD_TEX0_CUBE 0x200 /* handled clientside */
-#define I830_UPLOAD_TEX1_IMAGE 0x400 /* handled clientside */
-#define I830_UPLOAD_TEX1_CUBE 0x800 /* handled clientside */
-#define I830_UPLOAD_TEX2_IMAGE 0x1000 /* handled clientside */
-#define I830_UPLOAD_TEX2_CUBE 0x2000 /* handled clientside */
-#define I830_UPLOAD_TEX3_IMAGE 0x4000 /* handled clientside */
-#define I830_UPLOAD_TEX3_CUBE 0x8000 /* handled clientside */
+#define I830_UPLOAD_TEX0_IMAGE 0x100 /* handled clientside */
+#define I830_UPLOAD_TEX0_CUBE 0x200 /* handled clientside */
+#define I830_UPLOAD_TEX1_IMAGE 0x400 /* handled clientside */
+#define I830_UPLOAD_TEX1_CUBE 0x800 /* handled clientside */
+#define I830_UPLOAD_TEX2_IMAGE 0x1000 /* handled clientside */
+#define I830_UPLOAD_TEX2_CUBE 0x2000 /* handled clientside */
+#define I830_UPLOAD_TEX3_IMAGE 0x4000 /* handled clientside */
+#define I830_UPLOAD_TEX3_CUBE 0x8000 /* handled clientside */
#define I830_UPLOAD_TEX_N_IMAGE(n) (0x100 << (n * 2))
#define I830_UPLOAD_TEX_N_CUBE(n) (0x200 << (n * 2))
#define I830_UPLOAD_TEXIMAGE_MASK 0xff00
@@ -65,7 +65,7 @@
* or in a piecewise fashion as required.
*/
-/* Destbuffer state
+/* Destbuffer state
* - backbuffer linear offset and pitch -- invarient in the current dri
* - zbuffer linear offset and pitch -- also invarient
* - drawing origin in back and depth buffers.
@@ -103,7 +103,7 @@
#define I830_CTXREG_AA 9
#define I830_CTXREG_FOGCOLOR 10
#define I830_CTXREG_BLENDCOLR0 11
-#define I830_CTXREG_BLENDCOLR 12 /* Dword 1 of 2 dword command */
+#define I830_CTXREG_BLENDCOLR 12 /* Dword 1 of 2 dword command */
#define I830_CTXREG_VF 13
#define I830_CTXREG_VF2 14
#define I830_CTXREG_MCSB0 15
@@ -111,12 +111,11 @@
#define I830_CTX_SETUP_SIZE 17
/* 1.3: Stipple state
- */
+ */
#define I830_STPREG_ST0 0
#define I830_STPREG_ST1 1
#define I830_STP_SETUP_SIZE 2
-
/* Texture state (per tex unit)
*/
@@ -132,23 +131,23 @@
#define I830_TEXREG_MCS 9 /* GFX_OP_MAP_COORD_SETS */
#define I830_TEX_SETUP_SIZE 10
-#define I830_TEXREG_TM0LI 0 /* load immediate 2 texture map n */
+#define I830_TEXREG_TM0LI 0 /* load immediate 2 texture map n */
#define I830_TEXREG_TM0S0 1
#define I830_TEXREG_TM0S1 2
#define I830_TEXREG_TM0S2 3
#define I830_TEXREG_TM0S3 4
#define I830_TEXREG_TM0S4 5
-#define I830_TEXREG_NOP0 6 /* noop */
-#define I830_TEXREG_NOP1 7 /* noop */
-#define I830_TEXREG_NOP2 8 /* noop */
-#define __I830_TEXREG_MCS 9 /* GFX_OP_MAP_COORD_SETS -- shared */
+#define I830_TEXREG_NOP0 6 /* noop */
+#define I830_TEXREG_NOP1 7 /* noop */
+#define I830_TEXREG_NOP2 8 /* noop */
+#define __I830_TEXREG_MCS 9 /* GFX_OP_MAP_COORD_SETS -- shared */
#define __I830_TEX_SETUP_SIZE 10
#define I830_FRONT 0x1
#define I830_BACK 0x2
#define I830_DEPTH 0x4
-#endif /* _I830_DEFINES_ */
+#endif /* _I830_DEFINES_ */
typedef struct _drm_i830_init {
enum {
@@ -177,19 +176,19 @@ typedef struct _drm_i830_init {
* structure as well */
typedef struct _drm_i830_tex_region {
- unsigned char next, prev; /* indices to form a circular LRU */
+ unsigned char next, prev; /* indices to form a circular LRU */
unsigned char in_use; /* owned by a client, or free? */
int age; /* tracked by clients to update local LRU's */
} drm_i830_tex_region_t;
typedef struct _drm_i830_sarea {
unsigned int ContextState[I830_CTX_SETUP_SIZE];
- unsigned int BufferState[I830_DEST_SETUP_SIZE];
+ unsigned int BufferState[I830_DEST_SETUP_SIZE];
unsigned int TexState[I830_TEXTURE_COUNT][I830_TEX_SETUP_SIZE];
unsigned int TexBlendState[I830_TEXBLEND_COUNT][I830_TEXBLEND_SIZE];
unsigned int TexBlendStateWordsUsed[I830_TEXBLEND_COUNT];
unsigned int Palette[2][256];
- unsigned int dirty;
+ unsigned int dirty;
unsigned int nbox;
drm_clip_rect_t boxes[I830_NR_SAREA_CLIPRECTS];
@@ -207,26 +206,26 @@ typedef struct _drm_i830_sarea {
* texture space, and can make informed decisions as to which
* areas to kick out. There is no need to choose whether to
* kick out your own texture or someone else's - simply eject
- * them all in LRU order.
+ * them all in LRU order.
*/
- drm_i830_tex_region_t texList[I830_NR_TEX_REGIONS+1];
- /* Last elt is sentinal */
- int texAge; /* last time texture was uploaded */
- int last_enqueue; /* last time a buffer was enqueued */
+ drm_i830_tex_region_t texList[I830_NR_TEX_REGIONS + 1];
+ /* Last elt is sentinal */
+ int texAge; /* last time texture was uploaded */
+ int last_enqueue; /* last time a buffer was enqueued */
int last_dispatch; /* age of the most recently dispatched buffer */
- int last_quiescent; /* */
+ int last_quiescent; /* */
int ctxOwner; /* last context to upload state */
int vertex_prim;
- int pf_enabled; /* is pageflipping allowed? */
- int pf_active;
- int pf_current_page; /* which buffer is being displayed? */
+ int pf_enabled; /* is pageflipping allowed? */
+ int pf_active;
+ int pf_current_page; /* which buffer is being displayed? */
+
+ int perf_boxes; /* performance boxes to be displayed */
- int perf_boxes; /* performance boxes to be displayed */
-
- /* Here's the state for texunits 2,3:
+ /* Here's the state for texunits 2,3:
*/
unsigned int TexState2[I830_TEX_SETUP_SIZE];
unsigned int TexBlendState2[I830_TEXBLEND_SIZE];
@@ -241,12 +240,11 @@ typedef struct _drm_i830_sarea {
/* Flags for perf_boxes
*/
-#define I830_BOX_RING_EMPTY 0x1 /* populated by kernel */
-#define I830_BOX_FLIP 0x2 /* populated by kernel */
-#define I830_BOX_WAIT 0x4 /* populated by kernel & client */
-#define I830_BOX_TEXTURE_LOAD 0x8 /* populated by kernel */
-#define I830_BOX_LOST_CONTEXT 0x10 /* populated by client */
-
+#define I830_BOX_RING_EMPTY 0x1 /* populated by kernel */
+#define I830_BOX_FLIP 0x2 /* populated by kernel */
+#define I830_BOX_WAIT 0x4 /* populated by kernel & client */
+#define I830_BOX_TEXTURE_LOAD 0x8 /* populated by kernel */
+#define I830_BOX_LOST_CONTEXT 0x10 /* populated by client */
/* I830 specific ioctls
* The device specific ioctl range is 0x40 to 0x79.
@@ -289,23 +287,21 @@ typedef struct _drm_i830_clear {
unsigned int clear_depthmask;
} drm_i830_clear_t;
-
-
/* These may be placeholders if we have more cliprects than
* I830_NR_SAREA_CLIPRECTS. In that case, the client sets discard to
* false, indicating that the buffer will be dispatched again with a
* new set of cliprects.
*/
typedef struct _drm_i830_vertex {
- int idx; /* buffer index */
+ int idx; /* buffer index */
int used; /* nr bytes in use */
int discard; /* client is finished with the buffer? */
} drm_i830_vertex_t;
typedef struct _drm_i830_copy_t {
- int idx; /* buffer index */
+ int idx; /* buffer index */
int used; /* nr bytes in use */
- void __user *address; /* Address to copy from */
+ void __user *address; /* Address to copy from */
} drm_i830_copy_t;
typedef struct drm_i830_dma {
@@ -315,7 +311,6 @@ typedef struct drm_i830_dma {
int granted;
} drm_i830_dma_t;
-
/* 1.3: Userspace can request & wait on irq's:
*/
typedef struct drm_i830_irq_emit {
@@ -326,7 +321,6 @@ typedef struct drm_i830_irq_wait {
int irq_seq;
} drm_i830_irq_wait_t;
-
/* 1.3: New ioctl to query kernel params:
*/
#define I830_PARAM_IRQ_ACTIVE 1
@@ -336,7 +330,6 @@ typedef struct drm_i830_getparam {
int __user *value;
} drm_i830_getparam_t;
-
/* 1.3: New ioctl to set kernel params:
*/
#define I830_SETPARAM_USE_MI_BATCHBUFFER_START 1
@@ -346,5 +339,4 @@ typedef struct drm_i830_setparam {
int value;
} drm_i830_setparam_t;
-
-#endif /* _I830_DRM_H_ */
+#endif /* _I830_DRM_H_ */
diff --git a/drivers/char/drm/i830_drv.c b/drivers/char/drm/i830_drv.c
index 0da9cd19919e..acd821e8fe4d 100644
--- a/drivers/char/drm/i830_drv.c
+++ b/drivers/char/drm/i830_drv.c
@@ -40,36 +40,34 @@
#include "drm_pciids.h"
-static int postinit( struct drm_device *dev, unsigned long flags )
+static int postinit(struct drm_device *dev, unsigned long flags)
{
dev->counters += 4;
dev->types[6] = _DRM_STAT_IRQ;
dev->types[7] = _DRM_STAT_PRIMARY;
dev->types[8] = _DRM_STAT_SECONDARY;
dev->types[9] = _DRM_STAT_DMA;
-
- DRM_INFO( "Initialized %s %d.%d.%d %s on minor %d: %s\n",
- DRIVER_NAME,
- DRIVER_MAJOR,
- DRIVER_MINOR,
- DRIVER_PATCHLEVEL,
- DRIVER_DATE,
- dev->primary.minor,
- pci_pretty_name(dev->pdev)
- );
+
+ DRM_INFO("Initialized %s %d.%d.%d %s on minor %d: %s\n",
+ DRIVER_NAME,
+ DRIVER_MAJOR,
+ DRIVER_MINOR,
+ DRIVER_PATCHLEVEL,
+ DRIVER_DATE, dev->primary.minor, pci_pretty_name(dev->pdev)
+ );
return 0;
}
-static int version( drm_version_t *version )
+static int version(drm_version_t * version)
{
int len;
version->version_major = DRIVER_MAJOR;
version->version_minor = DRIVER_MINOR;
version->version_patchlevel = DRIVER_PATCHLEVEL;
- DRM_COPY( version->name, DRIVER_NAME );
- DRM_COPY( version->date, DRIVER_DATE );
- DRM_COPY( version->desc, DRIVER_DESC );
+ DRM_COPY(version->name, DRIVER_NAME);
+ DRM_COPY(version->date, DRIVER_DATE);
+ DRM_COPY(version->desc, DRIVER_DESC);
return 0;
}
@@ -77,11 +75,10 @@ static struct pci_device_id pciidlist[] = {
i830_PCI_IDS
};
-extern drm_ioctl_desc_t i830_ioctls[];
-extern int i830_max_ioctl;
-
static struct drm_driver driver = {
- .driver_features = DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | DRIVER_USE_MTRR | DRIVER_HAVE_DMA | DRIVER_DMA_QUEUE,
+ .driver_features =
+ DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | DRIVER_USE_MTRR |
+ DRIVER_HAVE_DMA | DRIVER_DMA_QUEUE,
#if USE_IRQS
.driver_features |= DRIVER_HAVE_IRQ | DRIVER_SHARED_IRQ,
#endif
@@ -104,18 +101,19 @@ static struct drm_driver driver = {
.version = version,
.ioctls = i830_ioctls,
.fops = {
- .owner = THIS_MODULE,
- .open = drm_open,
- .release = drm_release,
- .ioctl = drm_ioctl,
- .mmap = drm_mmap,
- .poll = drm_poll,
- .fasync = drm_fasync,
- },
+ .owner = THIS_MODULE,
+ .open = drm_open,
+ .release = drm_release,
+ .ioctl = drm_ioctl,
+ .mmap = drm_mmap,
+ .poll = drm_poll,
+ .fasync = drm_fasync,
+ }
+ ,
.pci_driver = {
- .name = DRIVER_NAME,
- .id_table = pciidlist,
- }
+ .name = DRIVER_NAME,
+ .id_table = pciidlist,
+ }
};
@@ -133,6 +131,6 @@ static void __exit i830_exit(void)
module_init(i830_init);
module_exit(i830_exit);
-MODULE_AUTHOR( DRIVER_AUTHOR );
-MODULE_DESCRIPTION( DRIVER_DESC );
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL and additional rights");
diff --git a/drivers/char/drm/i830_drv.h b/drivers/char/drm/i830_drv.h
index 63f96a8b6a4a..bc4bd49fb0cc 100644
--- a/drivers/char/drm/i830_drv.h
+++ b/drivers/char/drm/i830_drv.h
@@ -11,11 +11,11 @@
* 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 (including the next
* paragraph) 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
@@ -63,14 +63,14 @@
#define USE_IRQS 0
typedef struct drm_i830_buf_priv {
- u32 *in_use;
- int my_use_idx;
+ u32 *in_use;
+ int my_use_idx;
int currently_mapped;
void __user *virtual;
void *kernel_virtual;
} drm_i830_buf_priv_t;
-typedef struct _drm_i830_ring_buffer{
+typedef struct _drm_i830_ring_buffer {
int tail_mask;
unsigned long Start;
unsigned long End;
@@ -86,17 +86,17 @@ typedef struct drm_i830_private {
drm_map_t *mmio_map;
drm_i830_sarea_t *sarea_priv;
- drm_i830_ring_buffer_t ring;
+ drm_i830_ring_buffer_t ring;
- void * hw_status_page;
- unsigned long counter;
+ void *hw_status_page;
+ unsigned long counter;
dma_addr_t dma_status_page;
drm_buf_t *mmap_buffer;
-
+
u32 front_di1, back_di1, zi1;
-
+
int back_offset;
int depth_offset;
int front_offset;
@@ -113,43 +113,39 @@ typedef struct drm_i830_private {
int page_flipping;
wait_queue_head_t irq_queue;
- atomic_t irq_received;
- atomic_t irq_emitted;
+ atomic_t irq_received;
+ atomic_t irq_emitted;
int use_mi_batchbuffer_start;
} drm_i830_private_t;
+extern drm_ioctl_desc_t i830_ioctls[];
+extern int i830_max_ioctl;
+
/* i830_dma.c */
-extern void i830_reclaim_buffers(drm_device_t *dev, struct file *filp);
+extern void i830_reclaim_buffers(drm_device_t * dev, struct file *filp);
/* i830_irq.c */
-extern int i830_irq_emit( struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg );
-extern int i830_irq_wait( struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg );
-
-extern irqreturn_t i830_driver_irq_handler( DRM_IRQ_ARGS );
-extern void i830_driver_irq_preinstall( drm_device_t *dev );
-extern void i830_driver_irq_postinstall( drm_device_t *dev );
-extern void i830_driver_irq_uninstall( drm_device_t *dev );
-extern void i830_driver_pretakedown(drm_device_t *dev);
-extern void i830_driver_release(drm_device_t *dev, struct file *filp);
-extern int i830_driver_dma_quiescent(drm_device_t *dev);
-extern void i830_driver_prerelease(drm_device_t *dev, DRMFILE filp);
+extern int i830_irq_emit(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg);
+extern int i830_irq_wait(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg);
+
+extern irqreturn_t i830_driver_irq_handler(DRM_IRQ_ARGS);
+extern void i830_driver_irq_preinstall(drm_device_t * dev);
+extern void i830_driver_irq_postinstall(drm_device_t * dev);
+extern void i830_driver_irq_uninstall(drm_device_t * dev);
+extern void i830_driver_pretakedown(drm_device_t * dev);
+extern void i830_driver_release(drm_device_t * dev, struct file *filp);
+extern int i830_driver_dma_quiescent(drm_device_t * dev);
+extern void i830_driver_prerelease(drm_device_t * dev, DRMFILE filp);
extern int i830_driver_device_is_agp(drm_device_t * dev);
-#define I830_BASE(reg) ((unsigned long) \
- dev_priv->mmio_map->handle)
-#define I830_ADDR(reg) (I830_BASE(reg) + reg)
-#define I830_DEREF(reg) *(__volatile__ unsigned int *)I830_ADDR(reg)
-#define I830_READ(reg) readl((volatile u32 *)I830_ADDR(reg))
-#define I830_WRITE(reg,val) writel(val, (volatile u32 *)I830_ADDR(reg))
-#define I830_DEREF16(reg) *(__volatile__ u16 *)I830_ADDR(reg)
-#define I830_READ16(reg) I830_DEREF16(reg)
-#define I830_WRITE16(reg,val) do { I830_DEREF16(reg) = val; } while (0)
-
-
+#define I830_READ(reg) DRM_READ32(dev_priv->mmio_map, reg)
+#define I830_WRITE(reg,val) DRM_WRITE32(dev_priv->mmio_map, reg, val)
+#define I830_READ16(reg) DRM_READ16(dev_priv->mmio_map, reg)
+#define I830_WRITE16(reg,val) DRM_WRITE16(dev_priv->mmio_map, reg, val)
#define I830_VERBOSE 0
@@ -168,7 +164,6 @@ extern int i830_driver_device_is_agp(drm_device_t * dev);
virt = dev_priv->ring.virtual_start; \
} while (0)
-
#define OUT_RING(n) do { \
if (I830_VERBOSE) printk(" OUT_RING %x\n", (int)(n)); \
*(volatile unsigned int *)(virt + outring) = n; \
@@ -184,8 +179,7 @@ extern int i830_driver_device_is_agp(drm_device_t * dev);
I830_WRITE(LP_RING + RING_TAIL, outring); \
} while(0)
-extern int i830_wait_ring(drm_device_t *dev, int n, const char *caller);
-
+extern int i830_wait_ring(drm_device_t * dev, int n, const char *caller);
#define GFX_OP_USER_INTERRUPT ((0<<29)|(2<<23))
#define GFX_OP_BREAKPOINT_INTERRUPT ((0<<29)|(1<<23))
@@ -200,7 +194,6 @@ extern int i830_wait_ring(drm_device_t *dev, int n, const char *caller);
#define INST_OP_FLUSH 0x02000000
#define INST_FLUSH_MAP_CACHE 0x00000001
-
#define BB1_START_ADDR_MASK (~0x7)
#define BB1_PROTECTED (1<<0)
#define BB1_UNPROTECTED (0<<0)
@@ -213,7 +206,6 @@ extern int i830_wait_ring(drm_device_t *dev, int n, const char *caller);
#define I830_IRQ_RESERVED ((1<<13)|(3<<2))
-
#define LP_RING 0x2030
#define HP_RING 0x2040
#define RING_TAIL 0x00
@@ -225,7 +217,7 @@ extern int i830_wait_ring(drm_device_t *dev, int n, const char *caller);
#define RING_START 0x08
#define START_ADDR 0x0xFFFFF000
#define RING_LEN 0x0C
-#define RING_NR_PAGES 0x001FF000
+#define RING_NR_PAGES 0x001FF000
#define RING_REPORT_MASK 0x00000006
#define RING_REPORT_64K 0x00000002
#define RING_REPORT_128K 0x00000004
@@ -291,10 +283,9 @@ extern int i830_wait_ring(drm_device_t *dev, int n, const char *caller);
#define MI_BATCH_NON_SECURE (1)
#define MI_WAIT_FOR_EVENT ((0x3<<23))
-#define MI_WAIT_FOR_PLANE_A_FLIP (1<<2)
-#define MI_WAIT_FOR_PLANE_A_SCANLINES (1<<1)
+#define MI_WAIT_FOR_PLANE_A_FLIP (1<<2)
+#define MI_WAIT_FOR_PLANE_A_SCANLINES (1<<1)
#define MI_LOAD_SCAN_LINES_INCL ((0x12<<23))
#endif
-
diff --git a/drivers/char/drm/i830_irq.c b/drivers/char/drm/i830_irq.c
index a5923e5d0a77..5841f7674956 100644
--- a/drivers/char/drm/i830_irq.c
+++ b/drivers/char/drm/i830_irq.c
@@ -9,11 +9,11 @@
* 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 (including the next
* paragraph) 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
@@ -33,28 +33,27 @@
#include <linux/interrupt.h> /* For task queue support */
#include <linux/delay.h>
-
-irqreturn_t i830_driver_irq_handler( DRM_IRQ_ARGS )
+irqreturn_t i830_driver_irq_handler(DRM_IRQ_ARGS)
{
- drm_device_t *dev = (drm_device_t *)arg;
- drm_i830_private_t *dev_priv = (drm_i830_private_t *)dev->dev_private;
- u16 temp;
+ drm_device_t *dev = (drm_device_t *) arg;
+ drm_i830_private_t *dev_priv = (drm_i830_private_t *) dev->dev_private;
+ u16 temp;
- temp = I830_READ16(I830REG_INT_IDENTITY_R);
+ temp = I830_READ16(I830REG_INT_IDENTITY_R);
DRM_DEBUG("%x\n", temp);
- if ( !( temp & 2 ) )
+ if (!(temp & 2))
return IRQ_NONE;
- I830_WRITE16(I830REG_INT_IDENTITY_R, temp);
+ I830_WRITE16(I830REG_INT_IDENTITY_R, temp);
atomic_inc(&dev_priv->irq_received);
- wake_up_interruptible(&dev_priv->irq_queue);
+ wake_up_interruptible(&dev_priv->irq_queue);
return IRQ_HANDLED;
}
-static int i830_emit_irq(drm_device_t *dev)
+static int i830_emit_irq(drm_device_t * dev)
{
drm_i830_private_t *dev_priv = dev->dev_private;
RING_LOCALS;
@@ -63,27 +62,25 @@ static int i830_emit_irq(drm_device_t *dev)
atomic_inc(&dev_priv->irq_emitted);
- BEGIN_LP_RING(2);
- OUT_RING( 0 );
- OUT_RING( GFX_OP_USER_INTERRUPT );
- ADVANCE_LP_RING();
+ BEGIN_LP_RING(2);
+ OUT_RING(0);
+ OUT_RING(GFX_OP_USER_INTERRUPT);
+ ADVANCE_LP_RING();
return atomic_read(&dev_priv->irq_emitted);
}
-
-static int i830_wait_irq(drm_device_t *dev, int irq_nr)
+static int i830_wait_irq(drm_device_t * dev, int irq_nr)
{
- drm_i830_private_t *dev_priv =
- (drm_i830_private_t *)dev->dev_private;
+ drm_i830_private_t *dev_priv = (drm_i830_private_t *) dev->dev_private;
DECLARE_WAITQUEUE(entry, current);
- unsigned long end = jiffies + HZ*3;
+ unsigned long end = jiffies + HZ * 3;
int ret = 0;
DRM_DEBUG("%s\n", __FUNCTION__);
- if (atomic_read(&dev_priv->irq_received) >= irq_nr)
- return 0;
+ if (atomic_read(&dev_priv->irq_received) >= irq_nr)
+ return 0;
dev_priv->sarea_priv->perf_boxes |= I830_BOX_WAIT;
@@ -91,21 +88,21 @@ static int i830_wait_irq(drm_device_t *dev, int irq_nr)
for (;;) {
__set_current_state(TASK_INTERRUPTIBLE);
- if (atomic_read(&dev_priv->irq_received) >= irq_nr)
- break;
- if((signed)(end - jiffies) <= 0) {
+ if (atomic_read(&dev_priv->irq_received) >= irq_nr)
+ break;
+ if ((signed)(end - jiffies) <= 0) {
DRM_ERROR("timeout iir %x imr %x ier %x hwstam %x\n",
- I830_READ16( I830REG_INT_IDENTITY_R ),
- I830_READ16( I830REG_INT_MASK_R ),
- I830_READ16( I830REG_INT_ENABLE_R ),
- I830_READ16( I830REG_HWSTAM ));
+ I830_READ16(I830REG_INT_IDENTITY_R),
+ I830_READ16(I830REG_INT_MASK_R),
+ I830_READ16(I830REG_INT_ENABLE_R),
+ I830_READ16(I830REG_HWSTAM));
- ret = -EBUSY; /* Lockup? Missed irq? */
+ ret = -EBUSY; /* Lockup? Missed irq? */
break;
}
- schedule_timeout(HZ*3);
- if (signal_pending(current)) {
- ret = -EINTR;
+ schedule_timeout(HZ * 3);
+ if (signal_pending(current)) {
+ ret = -EINTR;
break;
}
}
@@ -115,89 +112,87 @@ static int i830_wait_irq(drm_device_t *dev, int irq_nr)
return ret;
}
-
/* Needs the lock as it touches the ring.
*/
-int i830_irq_emit( struct inode *inode, struct file *filp, unsigned int cmd,
- unsigned long arg )
+int i830_irq_emit(struct inode *inode, struct file *filp, unsigned int cmd,
+ unsigned long arg)
{
- drm_file_t *priv = filp->private_data;
- drm_device_t *dev = priv->head->dev;
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->head->dev;
drm_i830_private_t *dev_priv = dev->dev_private;
drm_i830_irq_emit_t emit;
int result;
LOCK_TEST_WITH_RETURN(dev, filp);
- if ( !dev_priv ) {
- DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
+ if (!dev_priv) {
+ DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
return -EINVAL;
}
- if (copy_from_user( &emit, (drm_i830_irq_emit_t __user *)arg, sizeof(emit) ))
+ if (copy_from_user
+ (&emit, (drm_i830_irq_emit_t __user *) arg, sizeof(emit)))
return -EFAULT;
- result = i830_emit_irq( dev );
+ result = i830_emit_irq(dev);
- if ( copy_to_user( emit.irq_seq, &result, sizeof(int) ) ) {
- DRM_ERROR( "copy_to_user\n" );
+ if (copy_to_user(emit.irq_seq, &result, sizeof(int))) {
+ DRM_ERROR("copy_to_user\n");
return -EFAULT;
}
return 0;
}
-
/* Doesn't need the hardware lock.
*/
-int i830_irq_wait( struct inode *inode, struct file *filp, unsigned int cmd,
- unsigned long arg )
+int i830_irq_wait(struct inode *inode, struct file *filp, unsigned int cmd,
+ unsigned long arg)
{
- drm_file_t *priv = filp->private_data;
- drm_device_t *dev = priv->head->dev;
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->head->dev;
drm_i830_private_t *dev_priv = dev->dev_private;
drm_i830_irq_wait_t irqwait;
- if ( !dev_priv ) {
- DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
+ if (!dev_priv) {
+ DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
return -EINVAL;
}
- if (copy_from_user( &irqwait, (drm_i830_irq_wait_t __user *)arg,
- sizeof(irqwait) ))
+ if (copy_from_user(&irqwait, (drm_i830_irq_wait_t __user *) arg,
+ sizeof(irqwait)))
return -EFAULT;
- return i830_wait_irq( dev, irqwait.irq_seq );
+ return i830_wait_irq(dev, irqwait.irq_seq);
}
-
/* drm_dma.h hooks
*/
-void i830_driver_irq_preinstall( drm_device_t *dev ) {
- drm_i830_private_t *dev_priv =
- (drm_i830_private_t *)dev->dev_private;
+void i830_driver_irq_preinstall(drm_device_t * dev)
+{
+ drm_i830_private_t *dev_priv = (drm_i830_private_t *) dev->dev_private;
- I830_WRITE16( I830REG_HWSTAM, 0xffff );
- I830_WRITE16( I830REG_INT_MASK_R, 0x0 );
- I830_WRITE16( I830REG_INT_ENABLE_R, 0x0 );
+ I830_WRITE16(I830REG_HWSTAM, 0xffff);
+ I830_WRITE16(I830REG_INT_MASK_R, 0x0);
+ I830_WRITE16(I830REG_INT_ENABLE_R, 0x0);
atomic_set(&dev_priv->irq_received, 0);
atomic_set(&dev_priv->irq_emitted, 0);
init_waitqueue_head(&dev_priv->irq_queue);
}
-void i830_driver_irq_postinstall( drm_device_t *dev ) {
- drm_i830_private_t *dev_priv =
- (drm_i830_private_t *)dev->dev_private;
+void i830_driver_irq_postinstall(drm_device_t * dev)
+{
+ drm_i830_private_t *dev_priv = (drm_i830_private_t *) dev->dev_private;
- I830_WRITE16( I830REG_INT_ENABLE_R, 0x2 );
+ I830_WRITE16(I830REG_INT_ENABLE_R, 0x2);
}
-void i830_driver_irq_uninstall( drm_device_t *dev ) {
- drm_i830_private_t *dev_priv =
- (drm_i830_private_t *)dev->dev_private;
+void i830_driver_irq_uninstall(drm_device_t * dev)
+{
+ drm_i830_private_t *dev_priv = (drm_i830_private_t *) dev->dev_private;
if (!dev_priv)
return;
- I830_WRITE16( I830REG_INT_MASK_R, 0xffff );
- I830_WRITE16( I830REG_INT_ENABLE_R, 0x0 );
+ I830_WRITE16(I830REG_INT_MASK_R, 0xffff);
+ I830_WRITE16(I830REG_INT_ENABLE_R, 0x0);
}
diff --git a/drivers/char/drm/i915_dma.c b/drivers/char/drm/i915_dma.c
index 34f552f90c4a..f3aa0c370127 100644
--- a/drivers/char/drm/i915_dma.c
+++ b/drivers/char/drm/i915_dma.c
@@ -85,14 +85,14 @@ static int i915_dma_cleanup(drm_device_t * dev)
* is freed, it's too late.
*/
if (dev->irq)
- drm_irq_uninstall (dev);
+ drm_irq_uninstall(dev);
if (dev->dev_private) {
drm_i915_private_t *dev_priv =
(drm_i915_private_t *) dev->dev_private;
if (dev_priv->ring.virtual_start) {
- drm_core_ioremapfree( &dev_priv->ring.map, dev);
+ drm_core_ioremapfree(&dev_priv->ring.map, dev);
}
if (dev_priv->status_page_dmah) {
@@ -101,8 +101,8 @@ static int i915_dma_cleanup(drm_device_t * dev)
I915_WRITE(0x02080, 0x1ffff000);
}
- drm_free (dev->dev_private, sizeof(drm_i915_private_t),
- DRM_MEM_DRIVER);
+ drm_free(dev->dev_private, sizeof(drm_i915_private_t),
+ DRM_MEM_DRIVER);
dev->dev_private = NULL;
}
@@ -146,7 +146,7 @@ static int i915_initialize(drm_device_t * dev,
dev_priv->ring.map.flags = 0;
dev_priv->ring.map.mtrr = 0;
- drm_core_ioremap( &dev_priv->ring.map, dev );
+ drm_core_ioremap(&dev_priv->ring.map, dev);
if (dev_priv->ring.map.handle == NULL) {
dev->dev_private = (void *)dev_priv;
@@ -243,8 +243,8 @@ static int i915_dma_init(DRM_IOCTL_ARGS)
switch (init.func) {
case I915_INIT_DMA:
- dev_priv = drm_alloc (sizeof(drm_i915_private_t),
- DRM_MEM_DRIVER);
+ dev_priv = drm_alloc(sizeof(drm_i915_private_t),
+ DRM_MEM_DRIVER);
if (dev_priv == NULL)
return DRM_ERR(ENOMEM);
retcode = i915_initialize(dev, dev_priv, &init);
@@ -297,7 +297,7 @@ static int do_validate_cmd(int cmd)
case 0x1c:
return 1;
case 0x1d:
- switch ((cmd>>16)&0xff) {
+ switch ((cmd >> 16) & 0xff) {
case 0x3:
return (cmd & 0x1f) + 2;
case 0x4:
@@ -699,20 +699,20 @@ static int i915_setparam(DRM_IOCTL_ARGS)
return 0;
}
-void i915_driver_pretakedown(drm_device_t *dev)
+void i915_driver_pretakedown(drm_device_t * dev)
{
- if ( dev->dev_private ) {
+ if (dev->dev_private) {
drm_i915_private_t *dev_priv = dev->dev_private;
- i915_mem_takedown( &(dev_priv->agp_heap) );
- }
- i915_dma_cleanup( dev );
+ i915_mem_takedown(&(dev_priv->agp_heap));
+ }
+ i915_dma_cleanup(dev);
}
-void i915_driver_prerelease(drm_device_t *dev, DRMFILE filp)
+void i915_driver_prerelease(drm_device_t * dev, DRMFILE filp)
{
- if ( dev->dev_private ) {
+ if (dev->dev_private) {
drm_i915_private_t *dev_priv = dev->dev_private;
- i915_mem_release( dev, filp, dev_priv->agp_heap );
+ i915_mem_release(dev, filp, dev_priv->agp_heap);
}
}
diff --git a/drivers/char/drm/i915_drv.c b/drivers/char/drm/i915_drv.c
index 106b9ec02213..0508240f4e3b 100644
--- a/drivers/char/drm/i915_drv.c
+++ b/drivers/char/drm/i915_drv.c
@@ -34,36 +34,34 @@
#include "drm_pciids.h"
-static int postinit( struct drm_device *dev, unsigned long flags )
+static int postinit(struct drm_device *dev, unsigned long flags)
{
dev->counters += 4;
dev->types[6] = _DRM_STAT_IRQ;
dev->types[7] = _DRM_STAT_PRIMARY;
dev->types[8] = _DRM_STAT_SECONDARY;
dev->types[9] = _DRM_STAT_DMA;
-
- DRM_INFO( "Initialized %s %d.%d.%d %s on minor %d: %s\n",
- DRIVER_NAME,
- DRIVER_MAJOR,
- DRIVER_MINOR,
- DRIVER_PATCHLEVEL,
- DRIVER_DATE,
- dev->primary.minor,
- pci_pretty_name(dev->pdev)
- );
+
+ DRM_INFO("Initialized %s %d.%d.%d %s on minor %d: %s\n",
+ DRIVER_NAME,
+ DRIVER_MAJOR,
+ DRIVER_MINOR,
+ DRIVER_PATCHLEVEL,
+ DRIVER_DATE, dev->primary.minor, pci_pretty_name(dev->pdev)
+ );
return 0;
}
-static int version( drm_version_t *version )
+static int version(drm_version_t * version)
{
int len;
version->version_major = DRIVER_MAJOR;
version->version_minor = DRIVER_MINOR;
version->version_patchlevel = DRIVER_PATCHLEVEL;
- DRM_COPY( version->name, DRIVER_NAME );
- DRM_COPY( version->date, DRIVER_DATE );
- DRM_COPY( version->desc, DRIVER_DESC );
+ DRM_COPY(version->name, DRIVER_NAME);
+ DRM_COPY(version->date, DRIVER_DATE);
+ DRM_COPY(version->desc, DRIVER_DESC);
return 0;
}
@@ -71,12 +69,10 @@ static struct pci_device_id pciidlist[] = {
i915_PCI_IDS
};
-extern drm_ioctl_desc_t i915_ioctls[];
-extern int i915_max_ioctl;
-
static struct drm_driver driver = {
- .driver_features = DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | DRIVER_USE_MTRR |
- DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED,
+ .driver_features =
+ DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | DRIVER_USE_MTRR |
+ DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED,
.pretakedown = i915_driver_pretakedown,
.prerelease = i915_driver_prerelease,
.device_is_agp = i915_driver_device_is_agp,
@@ -91,21 +87,21 @@ static struct drm_driver driver = {
.version = version,
.ioctls = i915_ioctls,
.fops = {
- .owner = THIS_MODULE,
- .open = drm_open,
- .release = drm_release,
- .ioctl = drm_ioctl,
- .mmap = drm_mmap,
- .poll = drm_poll,
- .fasync = drm_fasync,
+ .owner = THIS_MODULE,
+ .open = drm_open,
+ .release = drm_release,
+ .ioctl = drm_ioctl,
+ .mmap = drm_mmap,
+ .poll = drm_poll,
+ .fasync = drm_fasync,
#ifdef CONFIG_COMPAT
- .compat_ioctl = i915_compat_ioctl,
+ .compat_ioctl = i915_compat_ioctl,
#endif
- },
+ },
.pci_driver = {
- .name = DRIVER_NAME,
- .id_table = pciidlist,
- }
+ .name = DRIVER_NAME,
+ .id_table = pciidlist,
+ }
};
static int __init i915_init(void)
@@ -122,6 +118,6 @@ static void __exit i915_exit(void)
module_init(i915_init);
module_exit(i915_exit);
-MODULE_AUTHOR( DRIVER_AUTHOR );
-MODULE_DESCRIPTION( DRIVER_DESC );
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL and additional rights");
diff --git a/drivers/char/drm/i915_drv.h b/drivers/char/drm/i915_drv.h
index 70ed4e68eac8..17e457c73dc7 100644
--- a/drivers/char/drm/i915_drv.h
+++ b/drivers/char/drm/i915_drv.h
@@ -99,20 +99,23 @@ typedef struct drm_i915_private {
struct mem_block *agp_heap;
} drm_i915_private_t;
+extern drm_ioctl_desc_t i915_ioctls[];
+extern int i915_max_ioctl;
+
/* i915_dma.c */
extern void i915_kernel_lost_context(drm_device_t * dev);
-extern void i915_driver_pretakedown(drm_device_t *dev);
-extern void i915_driver_prerelease(drm_device_t *dev, DRMFILE filp);
-extern int i915_driver_device_is_agp(drm_device_t *dev);
+extern void i915_driver_pretakedown(drm_device_t * dev);
+extern void i915_driver_prerelease(drm_device_t * dev, DRMFILE filp);
+extern int i915_driver_device_is_agp(drm_device_t * dev);
/* i915_irq.c */
extern int i915_irq_emit(DRM_IOCTL_ARGS);
extern int i915_irq_wait(DRM_IOCTL_ARGS);
extern irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS);
-extern void i915_driver_irq_preinstall(drm_device_t *dev);
-extern void i915_driver_irq_postinstall(drm_device_t *dev);
-extern void i915_driver_irq_uninstall(drm_device_t *dev);
+extern void i915_driver_irq_preinstall(drm_device_t * dev);
+extern void i915_driver_irq_postinstall(drm_device_t * dev);
+extern void i915_driver_irq_uninstall(drm_device_t * dev);
/* i915_mem.c */
extern int i915_mem_alloc(DRM_IOCTL_ARGS);
@@ -125,7 +128,6 @@ extern void i915_mem_release(drm_device_t * dev,
extern long i915_compat_ioctl(struct file *filp, unsigned int cmd,
unsigned long arg);
-
#define I915_READ(reg) DRM_READ32(dev_priv->mmio_map, reg)
#define I915_WRITE(reg,val) DRM_WRITE32(dev_priv->mmio_map, reg, val)
#define I915_READ16(reg) DRM_READ16(dev_priv->mmio_map, reg)
diff --git a/drivers/char/drm/i915_ioc32.c b/drivers/char/drm/i915_ioc32.c
index fe009e1b3a3f..2218a946ec87 100644
--- a/drivers/char/drm/i915_ioc32.c
+++ b/drivers/char/drm/i915_ioc32.c
@@ -3,7 +3,7 @@
*
* 32-bit ioctl compatibility routines for the i915 DRM.
*
- * \author Alan Hourihane <alanh@fairlite.demon.co.uk>
+ * \author Alan Hourihane <alanh@fairlite.demon.co.uk>
*
*
* Copyright (C) Paul Mackerras 2005
@@ -42,51 +42,55 @@ typedef struct _drm_i915_batchbuffer32 {
int DR1; /* hw flags for GFX_OP_DRAWRECT_INFO */
int DR4; /* window origin for GFX_OP_DRAWRECT_INFO */
int num_cliprects; /* mulitpass with multiple cliprects? */
- u32 cliprects; /* pointer to userspace cliprects */
+ u32 cliprects; /* pointer to userspace cliprects */
} drm_i915_batchbuffer32_t;
static int compat_i915_batchbuffer(struct file *file, unsigned int cmd,
- unsigned long arg)
+ unsigned long arg)
{
drm_i915_batchbuffer32_t batchbuffer32;
drm_i915_batchbuffer_t __user *batchbuffer;
-
- if (copy_from_user(&batchbuffer32, (void __user *)arg, sizeof(batchbuffer32)))
+
+ if (copy_from_user
+ (&batchbuffer32, (void __user *)arg, sizeof(batchbuffer32)))
return -EFAULT;
-
+
batchbuffer = compat_alloc_user_space(sizeof(*batchbuffer));
if (!access_ok(VERIFY_WRITE, batchbuffer, sizeof(*batchbuffer))
|| __put_user(batchbuffer32.start, &batchbuffer->start)
|| __put_user(batchbuffer32.used, &batchbuffer->used)
|| __put_user(batchbuffer32.DR1, &batchbuffer->DR1)
|| __put_user(batchbuffer32.DR4, &batchbuffer->DR4)
- || __put_user(batchbuffer32.num_cliprects, &batchbuffer->num_cliprects)
+ || __put_user(batchbuffer32.num_cliprects,
+ &batchbuffer->num_cliprects)
|| __put_user((int __user *)(unsigned long)batchbuffer32.cliprects,
&batchbuffer->cliprects))
return -EFAULT;
-
+
return drm_ioctl(file->f_dentry->d_inode, file,
- DRM_IOCTL_I915_BATCHBUFFER, (unsigned long) batchbuffer);
+ DRM_IOCTL_I915_BATCHBUFFER,
+ (unsigned long)batchbuffer);
}
typedef struct _drm_i915_cmdbuffer32 {
- u32 buf; /* pointer to userspace command buffer */
+ u32 buf; /* pointer to userspace command buffer */
int sz; /* nr bytes in buf */
int DR1; /* hw flags for GFX_OP_DRAWRECT_INFO */
int DR4; /* window origin for GFX_OP_DRAWRECT_INFO */
int num_cliprects; /* mulitpass with multiple cliprects? */
- u32 cliprects; /* pointer to userspace cliprects */
+ u32 cliprects; /* pointer to userspace cliprects */
} drm_i915_cmdbuffer32_t;
static int compat_i915_cmdbuffer(struct file *file, unsigned int cmd,
- unsigned long arg)
+ unsigned long arg)
{
drm_i915_cmdbuffer32_t cmdbuffer32;
drm_i915_cmdbuffer_t __user *cmdbuffer;
-
- if (copy_from_user(&cmdbuffer32, (void __user *)arg, sizeof(cmdbuffer32)))
+
+ if (copy_from_user
+ (&cmdbuffer32, (void __user *)arg, sizeof(cmdbuffer32)))
return -EFAULT;
-
+
cmdbuffer = compat_alloc_user_space(sizeof(*cmdbuffer));
if (!access_ok(VERIFY_WRITE, cmdbuffer, sizeof(*cmdbuffer))
|| __put_user((int __user *)(unsigned long)cmdbuffer32.buf,
@@ -98,9 +102,9 @@ static int compat_i915_cmdbuffer(struct file *file, unsigned int cmd,
|| __put_user((int __user *)(unsigned long)cmdbuffer32.cliprects,
&cmdbuffer->cliprects))
return -EFAULT;
-
+
return drm_ioctl(file->f_dentry->d_inode, file,
- DRM_IOCTL_I915_CMDBUFFER, (unsigned long) cmdbuffer);
+ DRM_IOCTL_I915_CMDBUFFER, (unsigned long)cmdbuffer);
}
typedef struct drm_i915_irq_emit32 {
@@ -108,12 +112,12 @@ typedef struct drm_i915_irq_emit32 {
} drm_i915_irq_emit32_t;
static int compat_i915_irq_emit(struct file *file, unsigned int cmd,
- unsigned long arg)
+ unsigned long arg)
{
drm_i915_irq_emit32_t req32;
drm_i915_irq_emit_t __user *request;
- if (copy_from_user(&req32, (void __user *) arg, sizeof(req32)))
+ if (copy_from_user(&req32, (void __user *)arg, sizeof(req32)))
return -EFAULT;
request = compat_alloc_user_space(sizeof(*request));
@@ -123,7 +127,7 @@ static int compat_i915_irq_emit(struct file *file, unsigned int cmd,
return -EFAULT;
return drm_ioctl(file->f_dentry->d_inode, file,
- DRM_IOCTL_I915_IRQ_EMIT, (unsigned long) request);
+ DRM_IOCTL_I915_IRQ_EMIT, (unsigned long)request);
}
typedef struct drm_i915_getparam32 {
int param;
@@ -131,12 +135,12 @@ typedef struct drm_i915_getparam32 {
} drm_i915_getparam32_t;
static int compat_i915_getparam(struct file *file, unsigned int cmd,
- unsigned long arg)
+ unsigned long arg)
{
drm_i915_getparam32_t req32;
drm_i915_getparam_t __user *request;
- if (copy_from_user(&req32, (void __user *) arg, sizeof(req32)))
+ if (copy_from_user(&req32, (void __user *)arg, sizeof(req32)))
return -EFAULT;
request = compat_alloc_user_space(sizeof(*request));
@@ -147,7 +151,7 @@ static int compat_i915_getparam(struct file *file, unsigned int cmd,
return -EFAULT;
return drm_ioctl(file->f_dentry->d_inode, file,
- DRM_IOCTL_I915_GETPARAM, (unsigned long) request);
+ DRM_IOCTL_I915_GETPARAM, (unsigned long)request);
}
typedef struct drm_i915_mem_alloc32 {
@@ -158,12 +162,12 @@ typedef struct drm_i915_mem_alloc32 {
} drm_i915_mem_alloc32_t;
static int compat_i915_alloc(struct file *file, unsigned int cmd,
- unsigned long arg)
+ unsigned long arg)
{
drm_i915_mem_alloc32_t req32;
drm_i915_mem_alloc_t __user *request;
- if (copy_from_user(&req32, (void __user *) arg, sizeof(req32)))
+ if (copy_from_user(&req32, (void __user *)arg, sizeof(req32)))
return -EFAULT;
request = compat_alloc_user_space(sizeof(*request));
@@ -176,10 +180,9 @@ static int compat_i915_alloc(struct file *file, unsigned int cmd,
return -EFAULT;
return drm_ioctl(file->f_dentry->d_inode, file,
- DRM_IOCTL_I915_ALLOC, (unsigned long) request);
+ DRM_IOCTL_I915_ALLOC, (unsigned long)request);
}
-
drm_ioctl_compat_t *i915_compat_ioctls[] = {
[DRM_I915_BATCHBUFFER] = compat_i915_batchbuffer,
[DRM_I915_CMDBUFFER] = compat_i915_cmdbuffer,
@@ -197,8 +200,7 @@ drm_ioctl_compat_t *i915_compat_ioctls[] = {
* \param arg user argument.
* \return zero on success or negative number on failure.
*/
-long i915_compat_ioctl(struct file *filp, unsigned int cmd,
- unsigned long arg)
+long i915_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
unsigned int nr = DRM_IOCTL_NR(cmd);
drm_ioctl_compat_t *fn = NULL;
@@ -206,13 +208,13 @@ long i915_compat_ioctl(struct file *filp, unsigned int cmd,
if (nr < DRM_COMMAND_BASE)
return drm_compat_ioctl(filp, cmd, arg);
-
+
if (nr < DRM_COMMAND_BASE + DRM_ARRAY_SIZE(i915_compat_ioctls))
fn = i915_compat_ioctls[nr - DRM_COMMAND_BASE];
lock_kernel(); /* XXX for now */
if (fn != NULL)
- ret = (*fn)(filp, cmd, arg);
+ ret = (*fn) (filp, cmd, arg);
else
ret = drm_ioctl(filp->f_dentry->d_inode, filp, cmd, arg);
unlock_kernel();
diff --git a/drivers/char/drm/i915_mem.c b/drivers/char/drm/i915_mem.c
index 9b1698f521be..13176d136a99 100644
--- a/drivers/char/drm/i915_mem.c
+++ b/drivers/char/drm/i915_mem.c
@@ -86,7 +86,7 @@ static void mark_block(drm_device_t * dev, struct mem_block *p, int in_use)
}
/* Very simple allocator for agp memory, working on a static range
- * already mapped into each client's address space.
+ * already mapped into each client's address space.
*/
static struct mem_block *split_block(struct mem_block *p, int start, int size,
@@ -94,7 +94,8 @@ static struct mem_block *split_block(struct mem_block *p, int start, int size,
{
/* Maybe cut off the start of an existing block */
if (start > p->start) {
- struct mem_block *newblock = drm_alloc(sizeof(*newblock), DRM_MEM_BUFLISTS);
+ struct mem_block *newblock =
+ drm_alloc(sizeof(*newblock), DRM_MEM_BUFLISTS);
if (!newblock)
goto out;
newblock->start = start;
@@ -110,7 +111,8 @@ static struct mem_block *split_block(struct mem_block *p, int start, int size,
/* Maybe cut off the end of an existing block */
if (size < p->size) {
- struct mem_block *newblock = drm_alloc(sizeof(*newblock), DRM_MEM_BUFLISTS);
+ struct mem_block *newblock =
+ drm_alloc(sizeof(*newblock), DRM_MEM_BUFLISTS);
if (!newblock)
goto out;
newblock->start = start + size;
diff --git a/drivers/char/drm/mga_dma.c b/drivers/char/drm/mga_dma.c
index c8e1b6c83636..70dc7f64b7b9 100644
--- a/drivers/char/drm/mga_dma.c
+++ b/drivers/char/drm/mga_dma.c
@@ -28,7 +28,7 @@
/**
* \file mga_dma.c
* DMA support for MGA G200 / G400.
- *
+ *
* \author Rickard E. (Rik) Faith <faith@valinux.com>
* \author Jeff Hartmann <jhartmann@valinux.com>
* \author Keith Whitwell <keith@tungstengraphics.com>
@@ -44,40 +44,40 @@
#define MGA_DEFAULT_USEC_TIMEOUT 10000
#define MGA_FREELIST_DEBUG 0
-static int mga_do_cleanup_dma( drm_device_t *dev );
+static int mga_do_cleanup_dma(drm_device_t * dev);
/* ================================================================
* Engine control
*/
-int mga_do_wait_for_idle( drm_mga_private_t *dev_priv )
+int mga_do_wait_for_idle(drm_mga_private_t * dev_priv)
{
u32 status = 0;
int i;
- DRM_DEBUG( "\n" );
+ DRM_DEBUG("\n");
- for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) {
- status = MGA_READ( MGA_STATUS ) & MGA_ENGINE_IDLE_MASK;
- if ( status == MGA_ENDPRDMASTS ) {
- MGA_WRITE8( MGA_CRTC_INDEX, 0 );
+ for (i = 0; i < dev_priv->usec_timeout; i++) {
+ status = MGA_READ(MGA_STATUS) & MGA_ENGINE_IDLE_MASK;
+ if (status == MGA_ENDPRDMASTS) {
+ MGA_WRITE8(MGA_CRTC_INDEX, 0);
return 0;
}
- DRM_UDELAY( 1 );
+ DRM_UDELAY(1);
}
#if MGA_DMA_DEBUG
- DRM_ERROR( "failed!\n" );
- DRM_INFO( " status=0x%08x\n", status );
+ DRM_ERROR("failed!\n");
+ DRM_INFO(" status=0x%08x\n", status);
#endif
return DRM_ERR(EBUSY);
}
-static int mga_do_dma_reset( drm_mga_private_t *dev_priv )
+static int mga_do_dma_reset(drm_mga_private_t * dev_priv)
{
drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
drm_mga_primary_buffer_t *primary = &dev_priv->prim;
- DRM_DEBUG( "\n" );
+ DRM_DEBUG("\n");
/* The primary DMA stream should look like new right about now.
*/
@@ -100,24 +100,25 @@ static int mga_do_dma_reset( drm_mga_private_t *dev_priv )
* Primary DMA stream
*/
-void mga_do_dma_flush( drm_mga_private_t *dev_priv )
+void mga_do_dma_flush(drm_mga_private_t * dev_priv)
{
drm_mga_primary_buffer_t *primary = &dev_priv->prim;
u32 head, tail;
u32 status = 0;
int i;
- DMA_LOCALS;
- DRM_DEBUG( "\n" );
-
- /* We need to wait so that we can do an safe flush */
- for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) {
- status = MGA_READ( MGA_STATUS ) & MGA_ENGINE_IDLE_MASK;
- if ( status == MGA_ENDPRDMASTS ) break;
- DRM_UDELAY( 1 );
+ DMA_LOCALS;
+ DRM_DEBUG("\n");
+
+ /* We need to wait so that we can do an safe flush */
+ for (i = 0; i < dev_priv->usec_timeout; i++) {
+ status = MGA_READ(MGA_STATUS) & MGA_ENGINE_IDLE_MASK;
+ if (status == MGA_ENDPRDMASTS)
+ break;
+ DRM_UDELAY(1);
}
- if ( primary->tail == primary->last_flush ) {
- DRM_DEBUG( " bailing out...\n" );
+ if (primary->tail == primary->last_flush) {
+ DRM_DEBUG(" bailing out...\n");
return;
}
@@ -127,48 +128,46 @@ void mga_do_dma_flush( drm_mga_private_t *dev_priv )
* actually (partially?) reads the first of these commands.
* See page 4-16 in the G400 manual, middle of the page or so.
*/
- BEGIN_DMA( 1 );
+ BEGIN_DMA(1);
- DMA_BLOCK( MGA_DMAPAD, 0x00000000,
- MGA_DMAPAD, 0x00000000,
- MGA_DMAPAD, 0x00000000,
- MGA_DMAPAD, 0x00000000 );
+ DMA_BLOCK(MGA_DMAPAD, 0x00000000,
+ MGA_DMAPAD, 0x00000000,
+ MGA_DMAPAD, 0x00000000, MGA_DMAPAD, 0x00000000);
ADVANCE_DMA();
primary->last_flush = primary->tail;
- head = MGA_READ( MGA_PRIMADDRESS );
+ head = MGA_READ(MGA_PRIMADDRESS);
- if ( head <= tail ) {
+ if (head <= tail) {
primary->space = primary->size - primary->tail;
} else {
primary->space = head - tail;
}
- DRM_DEBUG( " head = 0x%06lx\n", head - dev_priv->primary->offset );
- DRM_DEBUG( " tail = 0x%06lx\n", tail - dev_priv->primary->offset );
- DRM_DEBUG( " space = 0x%06x\n", primary->space );
+ DRM_DEBUG(" head = 0x%06lx\n", head - dev_priv->primary->offset);
+ DRM_DEBUG(" tail = 0x%06lx\n", tail - dev_priv->primary->offset);
+ DRM_DEBUG(" space = 0x%06x\n", primary->space);
mga_flush_write_combine();
MGA_WRITE(MGA_PRIMEND, tail | dev_priv->dma_access);
- DRM_DEBUG( "done.\n" );
+ DRM_DEBUG("done.\n");
}
-void mga_do_dma_wrap_start( drm_mga_private_t *dev_priv )
+void mga_do_dma_wrap_start(drm_mga_private_t * dev_priv)
{
drm_mga_primary_buffer_t *primary = &dev_priv->prim;
u32 head, tail;
DMA_LOCALS;
- DRM_DEBUG( "\n" );
+ DRM_DEBUG("\n");
BEGIN_DMA_WRAP();
- DMA_BLOCK( MGA_DMAPAD, 0x00000000,
- MGA_DMAPAD, 0x00000000,
- MGA_DMAPAD, 0x00000000,
- MGA_DMAPAD, 0x00000000 );
+ DMA_BLOCK(MGA_DMAPAD, 0x00000000,
+ MGA_DMAPAD, 0x00000000,
+ MGA_DMAPAD, 0x00000000, MGA_DMAPAD, 0x00000000);
ADVANCE_DMA();
@@ -178,45 +177,43 @@ void mga_do_dma_wrap_start( drm_mga_private_t *dev_priv )
primary->last_flush = 0;
primary->last_wrap++;
- head = MGA_READ( MGA_PRIMADDRESS );
+ head = MGA_READ(MGA_PRIMADDRESS);
- if ( head == dev_priv->primary->offset ) {
+ if (head == dev_priv->primary->offset) {
primary->space = primary->size;
} else {
primary->space = head - dev_priv->primary->offset;
}
- DRM_DEBUG( " head = 0x%06lx\n",
- head - dev_priv->primary->offset );
- DRM_DEBUG( " tail = 0x%06x\n", primary->tail );
- DRM_DEBUG( " wrap = %d\n", primary->last_wrap );
- DRM_DEBUG( " space = 0x%06x\n", primary->space );
+ DRM_DEBUG(" head = 0x%06lx\n", head - dev_priv->primary->offset);
+ DRM_DEBUG(" tail = 0x%06x\n", primary->tail);
+ DRM_DEBUG(" wrap = %d\n", primary->last_wrap);
+ DRM_DEBUG(" space = 0x%06x\n", primary->space);
mga_flush_write_combine();
MGA_WRITE(MGA_PRIMEND, tail | dev_priv->dma_access);
- set_bit( 0, &primary->wrapped );
- DRM_DEBUG( "done.\n" );
+ set_bit(0, &primary->wrapped);
+ DRM_DEBUG("done.\n");
}
-void mga_do_dma_wrap_end( drm_mga_private_t *dev_priv )
+void mga_do_dma_wrap_end(drm_mga_private_t * dev_priv)
{
drm_mga_primary_buffer_t *primary = &dev_priv->prim;
drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
u32 head = dev_priv->primary->offset;
- DRM_DEBUG( "\n" );
+ DRM_DEBUG("\n");
sarea_priv->last_wrap++;
- DRM_DEBUG( " wrap = %d\n", sarea_priv->last_wrap );
+ DRM_DEBUG(" wrap = %d\n", sarea_priv->last_wrap);
mga_flush_write_combine();
- MGA_WRITE( MGA_PRIMADDRESS, head | MGA_DMA_GENERAL );
+ MGA_WRITE(MGA_PRIMADDRESS, head | MGA_DMA_GENERAL);
- clear_bit( 0, &primary->wrapped );
- DRM_DEBUG( "done.\n" );
+ clear_bit(0, &primary->wrapped);
+ DRM_DEBUG("done.\n");
}
-
/* ================================================================
* Freelist management
*/
@@ -225,63 +222,61 @@ void mga_do_dma_wrap_end( drm_mga_private_t *dev_priv )
#define MGA_BUFFER_FREE 0
#if MGA_FREELIST_DEBUG
-static void mga_freelist_print( drm_device_t *dev )
+static void mga_freelist_print(drm_device_t * dev)
{
drm_mga_private_t *dev_priv = dev->dev_private;
drm_mga_freelist_t *entry;
- DRM_INFO( "\n" );
- DRM_INFO( "current dispatch: last=0x%x done=0x%x\n",
- dev_priv->sarea_priv->last_dispatch,
- (unsigned int)(MGA_READ( MGA_PRIMADDRESS ) -
- dev_priv->primary->offset) );
- DRM_INFO( "current freelist:\n" );
-
- for ( entry = dev_priv->head->next ; entry ; entry = entry->next ) {
- DRM_INFO( " %p idx=%2d age=0x%x 0x%06lx\n",
- entry, entry->buf->idx, entry->age.head,
- entry->age.head - dev_priv->primary->offset );
+ DRM_INFO("\n");
+ DRM_INFO("current dispatch: last=0x%x done=0x%x\n",
+ dev_priv->sarea_priv->last_dispatch,
+ (unsigned int)(MGA_READ(MGA_PRIMADDRESS) -
+ dev_priv->primary->offset));
+ DRM_INFO("current freelist:\n");
+
+ for (entry = dev_priv->head->next; entry; entry = entry->next) {
+ DRM_INFO(" %p idx=%2d age=0x%x 0x%06lx\n",
+ entry, entry->buf->idx, entry->age.head,
+ entry->age.head - dev_priv->primary->offset);
}
- DRM_INFO( "\n" );
+ DRM_INFO("\n");
}
#endif
-static int mga_freelist_init( drm_device_t *dev, drm_mga_private_t *dev_priv )
+static int mga_freelist_init(drm_device_t * dev, drm_mga_private_t * dev_priv)
{
drm_device_dma_t *dma = dev->dma;
drm_buf_t *buf;
drm_mga_buf_priv_t *buf_priv;
drm_mga_freelist_t *entry;
int i;
- DRM_DEBUG( "count=%d\n", dma->buf_count );
+ DRM_DEBUG("count=%d\n", dma->buf_count);
- dev_priv->head = drm_alloc( sizeof(drm_mga_freelist_t),
- DRM_MEM_DRIVER );
- if ( dev_priv->head == NULL )
+ dev_priv->head = drm_alloc(sizeof(drm_mga_freelist_t), DRM_MEM_DRIVER);
+ if (dev_priv->head == NULL)
return DRM_ERR(ENOMEM);
- memset( dev_priv->head, 0, sizeof(drm_mga_freelist_t) );
- SET_AGE( &dev_priv->head->age, MGA_BUFFER_USED, 0 );
+ memset(dev_priv->head, 0, sizeof(drm_mga_freelist_t));
+ SET_AGE(&dev_priv->head->age, MGA_BUFFER_USED, 0);
- for ( i = 0 ; i < dma->buf_count ; i++ ) {
+ for (i = 0; i < dma->buf_count; i++) {
buf = dma->buflist[i];
- buf_priv = buf->dev_private;
+ buf_priv = buf->dev_private;
- entry = drm_alloc( sizeof(drm_mga_freelist_t),
- DRM_MEM_DRIVER );
- if ( entry == NULL )
+ entry = drm_alloc(sizeof(drm_mga_freelist_t), DRM_MEM_DRIVER);
+ if (entry == NULL)
return DRM_ERR(ENOMEM);
- memset( entry, 0, sizeof(drm_mga_freelist_t) );
+ memset(entry, 0, sizeof(drm_mga_freelist_t));
entry->next = dev_priv->head->next;
entry->prev = dev_priv->head;
- SET_AGE( &entry->age, MGA_BUFFER_FREE, 0 );
+ SET_AGE(&entry->age, MGA_BUFFER_FREE, 0);
entry->buf = buf;
- if ( dev_priv->head->next != NULL )
+ if (dev_priv->head->next != NULL)
dev_priv->head->next->prev = entry;
- if ( entry->next == NULL )
+ if (entry->next == NULL)
dev_priv->tail = entry;
buf_priv->list_entry = entry;
@@ -294,17 +289,17 @@ static int mga_freelist_init( drm_device_t *dev, drm_mga_private_t *dev_priv )
return 0;
}
-static void mga_freelist_cleanup( drm_device_t *dev )
+static void mga_freelist_cleanup(drm_device_t * dev)
{
drm_mga_private_t *dev_priv = dev->dev_private;
drm_mga_freelist_t *entry;
drm_mga_freelist_t *next;
- DRM_DEBUG( "\n" );
+ DRM_DEBUG("\n");
entry = dev_priv->head;
- while ( entry ) {
+ while (entry) {
next = entry->next;
- drm_free( entry, sizeof(drm_mga_freelist_t), DRM_MEM_DRIVER );
+ drm_free(entry, sizeof(drm_mga_freelist_t), DRM_MEM_DRIVER);
entry = next;
}
@@ -314,71 +309,69 @@ static void mga_freelist_cleanup( drm_device_t *dev )
#if 0
/* FIXME: Still needed?
*/
-static void mga_freelist_reset( drm_device_t *dev )
+static void mga_freelist_reset(drm_device_t * dev)
{
drm_device_dma_t *dma = dev->dma;
drm_buf_t *buf;
drm_mga_buf_priv_t *buf_priv;
int i;
- for ( i = 0 ; i < dma->buf_count ; i++ ) {
+ for (i = 0; i < dma->buf_count; i++) {
buf = dma->buflist[i];
- buf_priv = buf->dev_private;
- SET_AGE( &buf_priv->list_entry->age,
- MGA_BUFFER_FREE, 0 );
+ buf_priv = buf->dev_private;
+ SET_AGE(&buf_priv->list_entry->age, MGA_BUFFER_FREE, 0);
}
}
#endif
-static drm_buf_t *mga_freelist_get( drm_device_t *dev )
+static drm_buf_t *mga_freelist_get(drm_device_t * dev)
{
drm_mga_private_t *dev_priv = dev->dev_private;
drm_mga_freelist_t *next;
drm_mga_freelist_t *prev;
drm_mga_freelist_t *tail = dev_priv->tail;
u32 head, wrap;
- DRM_DEBUG( "\n" );
+ DRM_DEBUG("\n");
- head = MGA_READ( MGA_PRIMADDRESS );
+ head = MGA_READ(MGA_PRIMADDRESS);
wrap = dev_priv->sarea_priv->last_wrap;
- DRM_DEBUG( " tail=0x%06lx %d\n",
- tail->age.head ?
- tail->age.head - dev_priv->primary->offset : 0,
- tail->age.wrap );
- DRM_DEBUG( " head=0x%06lx %d\n",
- head - dev_priv->primary->offset, wrap );
+ DRM_DEBUG(" tail=0x%06lx %d\n",
+ tail->age.head ?
+ tail->age.head - dev_priv->primary->offset : 0,
+ tail->age.wrap);
+ DRM_DEBUG(" head=0x%06lx %d\n",
+ head - dev_priv->primary->offset, wrap);
- if ( TEST_AGE( &tail->age, head, wrap ) ) {
+ if (TEST_AGE(&tail->age, head, wrap)) {
prev = dev_priv->tail->prev;
next = dev_priv->tail;
prev->next = NULL;
next->prev = next->next = NULL;
dev_priv->tail = prev;
- SET_AGE( &next->age, MGA_BUFFER_USED, 0 );
+ SET_AGE(&next->age, MGA_BUFFER_USED, 0);
return next->buf;
}
- DRM_DEBUG( "returning NULL!\n" );
+ DRM_DEBUG("returning NULL!\n");
return NULL;
}
-int mga_freelist_put( drm_device_t *dev, drm_buf_t *buf )
+int mga_freelist_put(drm_device_t * dev, drm_buf_t * buf)
{
drm_mga_private_t *dev_priv = dev->dev_private;
drm_mga_buf_priv_t *buf_priv = buf->dev_private;
drm_mga_freelist_t *head, *entry, *prev;
- DRM_DEBUG( "age=0x%06lx wrap=%d\n",
- buf_priv->list_entry->age.head -
- dev_priv->primary->offset,
- buf_priv->list_entry->age.wrap );
+ DRM_DEBUG("age=0x%06lx wrap=%d\n",
+ buf_priv->list_entry->age.head -
+ dev_priv->primary->offset, buf_priv->list_entry->age.wrap);
entry = buf_priv->list_entry;
head = dev_priv->head;
- if ( buf_priv->list_entry->age.head == MGA_BUFFER_USED ) {
- SET_AGE( &entry->age, MGA_BUFFER_FREE, 0 );
+ if (buf_priv->list_entry->age.head == MGA_BUFFER_USED) {
+ SET_AGE(&entry->age, MGA_BUFFER_FREE, 0);
prev = dev_priv->tail;
prev->next = entry;
entry->prev = prev;
@@ -394,15 +387,13 @@ int mga_freelist_put( drm_device_t *dev, drm_buf_t *buf )
return 0;
}
-
/* ================================================================
* DMA initialization, cleanup
*/
-
-int mga_driver_preinit(drm_device_t *dev, unsigned long flags)
+int mga_driver_preinit(drm_device_t * dev, unsigned long flags)
{
- drm_mga_private_t * dev_priv;
+ drm_mga_private_t *dev_priv;
dev_priv = drm_alloc(sizeof(drm_mga_private_t), DRM_MEM_DRIVER);
if (!dev_priv)
@@ -420,7 +411,7 @@ int mga_driver_preinit(drm_device_t *dev, unsigned long flags)
#if __OS_HAS_AGP
/**
* Bootstrap the driver for AGP DMA.
- *
+ *
* \todo
* Investigate whether there is any benifit to storing the WARP microcode in
* AGP memory. If not, the microcode may as well always be put in PCI
@@ -436,18 +427,18 @@ int mga_driver_preinit(drm_device_t *dev, unsigned long flags)
static int mga_do_agp_dma_bootstrap(drm_device_t * dev,
drm_mga_dma_bootstrap_t * dma_bs)
{
- drm_mga_private_t * const dev_priv = (drm_mga_private_t *) dev->dev_private;
+ drm_mga_private_t *const dev_priv =
+ (drm_mga_private_t *) dev->dev_private;
unsigned int warp_size = mga_warp_microcode_size(dev_priv);
int err;
- unsigned offset;
+ unsigned offset;
const unsigned secondary_size = dma_bs->secondary_bin_count
- * dma_bs->secondary_bin_size;
+ * dma_bs->secondary_bin_size;
const unsigned agp_size = (dma_bs->agp_size << 20);
drm_buf_desc_t req;
drm_agp_mode_t mode;
drm_agp_info_t info;
-
/* Acquire AGP. */
err = drm_agp_acquire(dev);
if (err) {
@@ -468,7 +459,6 @@ static int mga_do_agp_dma_bootstrap(drm_device_t * dev,
return err;
}
-
/* In addition to the usual AGP mode configuration, the G200 AGP cards
* need to have the AGP mode "manually" set.
*/
@@ -476,24 +466,22 @@ static int mga_do_agp_dma_bootstrap(drm_device_t * dev,
if (dev_priv->chipset == MGA_CARD_TYPE_G200) {
if (mode.mode & 0x02) {
MGA_WRITE(MGA_AGP_PLL, MGA_AGP2XPLL_ENABLE);
- }
- else {
+ } else {
MGA_WRITE(MGA_AGP_PLL, MGA_AGP2XPLL_DISABLE);
}
}
-
/* Allocate and bind AGP memory. */
dev_priv->agp_pages = agp_size / PAGE_SIZE;
- dev_priv->agp_mem = drm_alloc_agp( dev, dev_priv->agp_pages, 0 );
+ dev_priv->agp_mem = drm_alloc_agp(dev, dev_priv->agp_pages, 0);
if (dev_priv->agp_mem == NULL) {
dev_priv->agp_pages = 0;
DRM_ERROR("Unable to allocate %uMB AGP memory\n",
dma_bs->agp_size);
return DRM_ERR(ENOMEM);
}
-
- err = drm_bind_agp( dev_priv->agp_mem, 0 );
+
+ err = drm_bind_agp(dev_priv->agp_mem, 0);
if (err) {
DRM_ERROR("Unable to bind AGP memory\n");
return err;
@@ -506,44 +494,44 @@ static int mga_do_agp_dma_bootstrap(drm_device_t * dev,
warp_size = PAGE_SIZE;
offset = 0;
- err = drm_addmap( dev, offset, warp_size,
- _DRM_AGP, _DRM_READ_ONLY, & dev_priv->warp );
+ err = drm_addmap(dev, offset, warp_size,
+ _DRM_AGP, _DRM_READ_ONLY, &dev_priv->warp);
if (err) {
DRM_ERROR("Unable to map WARP microcode\n");
return err;
}
offset += warp_size;
- err = drm_addmap( dev, offset, dma_bs->primary_size,
- _DRM_AGP, _DRM_READ_ONLY, & dev_priv->primary );
+ err = drm_addmap(dev, offset, dma_bs->primary_size,
+ _DRM_AGP, _DRM_READ_ONLY, &dev_priv->primary);
if (err) {
DRM_ERROR("Unable to map primary DMA region\n");
return err;
}
offset += dma_bs->primary_size;
- err = drm_addmap( dev, offset, secondary_size,
- _DRM_AGP, 0, & dev->agp_buffer_map );
+ err = drm_addmap(dev, offset, secondary_size,
+ _DRM_AGP, 0, &dev->agp_buffer_map);
if (err) {
DRM_ERROR("Unable to map secondary DMA region\n");
return err;
}
- (void) memset( &req, 0, sizeof(req) );
+ (void)memset(&req, 0, sizeof(req));
req.count = dma_bs->secondary_bin_count;
req.size = dma_bs->secondary_bin_size;
req.flags = _DRM_AGP_BUFFER;
req.agp_start = offset;
- err = drm_addbufs_agp( dev, & req );
+ err = drm_addbufs_agp(dev, &req);
if (err) {
DRM_ERROR("Unable to add secondary DMA buffers\n");
return err;
}
offset += secondary_size;
- err = drm_addmap( dev, offset, agp_size - offset,
- _DRM_AGP, 0, & dev_priv->agp_textures );
+ err = drm_addmap(dev, offset, agp_size - offset,
+ _DRM_AGP, 0, &dev_priv->agp_textures);
if (err) {
DRM_ERROR("Unable to map AGP texture region\n");
return err;
@@ -577,7 +565,7 @@ static int mga_do_agp_dma_bootstrap(drm_device_t * dev,
/**
* Bootstrap the driver for PCI DMA.
- *
+ *
* \todo
* The algorithm for decreasing the size of the primary DMA buffer could be
* better. The size should be rounded up to the nearest page size, then
@@ -586,20 +574,20 @@ static int mga_do_agp_dma_bootstrap(drm_device_t * dev,
* \todo
* Determine whether the maximum address passed to drm_pci_alloc is correct.
* The same goes for drm_addbufs_pci.
- *
+ *
* \sa mga_do_dma_bootstrap, mga_do_agp_dma_bootstrap
*/
static int mga_do_pci_dma_bootstrap(drm_device_t * dev,
drm_mga_dma_bootstrap_t * dma_bs)
{
- drm_mga_private_t * const dev_priv = (drm_mga_private_t *) dev->dev_private;
+ drm_mga_private_t *const dev_priv =
+ (drm_mga_private_t *) dev->dev_private;
unsigned int warp_size = mga_warp_microcode_size(dev_priv);
unsigned int primary_size;
unsigned int bin_count;
int err;
drm_buf_desc_t req;
-
if (dev->dma == NULL) {
DRM_ERROR("dev->dma is NULL\n");
return DRM_ERR(EFAULT);
@@ -624,9 +612,8 @@ static int mga_do_pci_dma_bootstrap(drm_device_t * dev,
* alignment of the primary or secondary DMA buffers.
*/
- for ( primary_size = dma_bs->primary_size
- ; primary_size != 0
- ; primary_size >>= 1 ) {
+ for (primary_size = dma_bs->primary_size; primary_size != 0;
+ primary_size >>= 1) {
/* The proper alignment for this mapping is 0x04 */
err = drm_addmap(dev, 0, primary_size, _DRM_CONSISTENT,
_DRM_READ_ONLY, &dev_priv->primary);
@@ -641,24 +628,23 @@ static int mga_do_pci_dma_bootstrap(drm_device_t * dev,
if (dev_priv->primary->size != dma_bs->primary_size) {
DRM_INFO("Primary DMA buffer size reduced from %u to %u.\n",
- dma_bs->primary_size,
- (unsigned) dev_priv->primary->size);
+ dma_bs->primary_size,
+ (unsigned)dev_priv->primary->size);
dma_bs->primary_size = dev_priv->primary->size;
}
- for ( bin_count = dma_bs->secondary_bin_count
- ; bin_count > 0
- ; bin_count-- ) {
- (void) memset( &req, 0, sizeof(req) );
+ for (bin_count = dma_bs->secondary_bin_count; bin_count > 0;
+ bin_count--) {
+ (void)memset(&req, 0, sizeof(req));
req.count = bin_count;
req.size = dma_bs->secondary_bin_size;
- err = drm_addbufs_pci( dev, & req );
+ err = drm_addbufs_pci(dev, &req);
if (!err) {
break;
}
}
-
+
if (bin_count == 0) {
DRM_ERROR("Unable to add secondary DMA buffers\n");
return err;
@@ -680,38 +666,34 @@ static int mga_do_pci_dma_bootstrap(drm_device_t * dev,
return 0;
}
-
static int mga_do_dma_bootstrap(drm_device_t * dev,
drm_mga_dma_bootstrap_t * dma_bs)
{
const int is_agp = (dma_bs->agp_mode != 0) && drm_device_is_agp(dev);
int err;
- drm_mga_private_t * const dev_priv =
- (drm_mga_private_t *) dev->dev_private;
-
+ drm_mga_private_t *const dev_priv =
+ (drm_mga_private_t *) dev->dev_private;
dev_priv->used_new_dma_init = 1;
/* The first steps are the same for both PCI and AGP based DMA. Map
* the cards MMIO registers and map a status page.
*/
- err = drm_addmap( dev, dev_priv->mmio_base, dev_priv->mmio_size,
- _DRM_REGISTERS, _DRM_READ_ONLY, & dev_priv->mmio );
+ err = drm_addmap(dev, dev_priv->mmio_base, dev_priv->mmio_size,
+ _DRM_REGISTERS, _DRM_READ_ONLY, &dev_priv->mmio);
if (err) {
DRM_ERROR("Unable to map MMIO region\n");
return err;
}
-
- err = drm_addmap( dev, 0, SAREA_MAX, _DRM_SHM,
- _DRM_READ_ONLY | _DRM_LOCKED | _DRM_KERNEL,
- & dev_priv->status );
+ err = drm_addmap(dev, 0, SAREA_MAX, _DRM_SHM,
+ _DRM_READ_ONLY | _DRM_LOCKED | _DRM_KERNEL,
+ &dev_priv->status);
if (err) {
DRM_ERROR("Unable to map status region\n");
return err;
}
-
/* The DMA initialization procedure is slightly different for PCI and
* AGP cards. AGP cards just allocate a large block of AGP memory and
* carve off portions of it for internal uses. The remaining memory
@@ -720,7 +702,7 @@ static int mga_do_dma_bootstrap(drm_device_t * dev,
if (is_agp) {
err = mga_do_agp_dma_bootstrap(dev, dma_bs);
}
-
+
/* If we attempted to initialize the card for AGP DMA but failed,
* clean-up any mess that may have been created.
*/
@@ -729,7 +711,6 @@ static int mga_do_dma_bootstrap(drm_device_t * dev,
mga_do_cleanup_dma(dev);
}
-
/* Not only do we want to try and initialized PCI cards for PCI DMA,
* but we also try to initialized AGP cards that could not be
* initialized for AGP DMA. This covers the case where we have an AGP
@@ -742,7 +723,6 @@ static int mga_do_dma_bootstrap(drm_device_t * dev,
err = mga_do_pci_dma_bootstrap(dev, dma_bs);
}
-
return err;
}
@@ -752,45 +732,42 @@ int mga_dma_bootstrap(DRM_IOCTL_ARGS)
drm_mga_dma_bootstrap_t bootstrap;
int err;
-
DRM_COPY_FROM_USER_IOCTL(bootstrap,
(drm_mga_dma_bootstrap_t __user *) data,
sizeof(bootstrap));
- err = mga_do_dma_bootstrap(dev, & bootstrap);
- if (! err) {
+ err = mga_do_dma_bootstrap(dev, &bootstrap);
+ if (!err) {
static const int modes[] = { 0, 1, 2, 2, 4, 4, 4, 4 };
- const drm_mga_private_t * const dev_priv =
- (drm_mga_private_t *) dev->dev_private;
+ const drm_mga_private_t *const dev_priv =
+ (drm_mga_private_t *) dev->dev_private;
if (dev_priv->agp_textures != NULL) {
- bootstrap.texture_handle = dev_priv->agp_textures->offset;
+ bootstrap.texture_handle =
+ dev_priv->agp_textures->offset;
bootstrap.texture_size = dev_priv->agp_textures->size;
- }
- else {
+ } else {
bootstrap.texture_handle = 0;
bootstrap.texture_size = 0;
}
- bootstrap.agp_mode = modes[ bootstrap.agp_mode & 0x07 ];
- if (DRM_COPY_TO_USER( (void __user *) data, & bootstrap,
+ bootstrap.agp_mode = modes[bootstrap.agp_mode & 0x07];
+ if (DRM_COPY_TO_USER((void __user *)data, &bootstrap,
sizeof(bootstrap))) {
err = DRM_ERR(EFAULT);
}
- }
- else {
+ } else {
mga_do_cleanup_dma(dev);
}
return err;
}
-static int mga_do_init_dma( drm_device_t *dev, drm_mga_init_t *init )
+static int mga_do_init_dma(drm_device_t * dev, drm_mga_init_t * init)
{
drm_mga_private_t *dev_priv;
int ret;
- DRM_DEBUG( "\n" );
-
+ DRM_DEBUG("\n");
dev_priv = dev->dev_private;
@@ -799,17 +776,17 @@ static int mga_do_init_dma( drm_device_t *dev, drm_mga_init_t *init )
} else {
dev_priv->clear_cmd = MGA_DWGCTL_CLEAR | MGA_ATYPE_RSTR;
}
- dev_priv->maccess = init->maccess;
+ dev_priv->maccess = init->maccess;
- dev_priv->fb_cpp = init->fb_cpp;
- dev_priv->front_offset = init->front_offset;
- dev_priv->front_pitch = init->front_pitch;
- dev_priv->back_offset = init->back_offset;
- dev_priv->back_pitch = init->back_pitch;
+ dev_priv->fb_cpp = init->fb_cpp;
+ dev_priv->front_offset = init->front_offset;
+ dev_priv->front_pitch = init->front_pitch;
+ dev_priv->back_offset = init->back_offset;
+ dev_priv->back_pitch = init->back_pitch;
- dev_priv->depth_cpp = init->depth_cpp;
- dev_priv->depth_offset = init->depth_offset;
- dev_priv->depth_pitch = init->depth_pitch;
+ dev_priv->depth_cpp = init->depth_cpp;
+ dev_priv->depth_offset = init->depth_offset;
+ dev_priv->depth_pitch = init->depth_pitch;
/* FIXME: Need to support AGP textures...
*/
@@ -823,7 +800,7 @@ static int mga_do_init_dma( drm_device_t *dev, drm_mga_init_t *init )
return DRM_ERR(EINVAL);
}
- if (! dev_priv->used_new_dma_init) {
+ if (!dev_priv->used_new_dma_init) {
dev_priv->dma_access = MGA_PAGPXFER;
dev_priv->wagp_enable = MGA_WAGP_ENABLE;
@@ -849,7 +826,8 @@ static int mga_do_init_dma( drm_device_t *dev, drm_mga_init_t *init )
return DRM_ERR(EINVAL);
}
dev->agp_buffer_token = init->buffers_offset;
- dev->agp_buffer_map = drm_core_findmap(dev, init->buffers_offset);
+ dev->agp_buffer_map =
+ drm_core_findmap(dev, init->buffers_offset);
if (!dev->agp_buffer_map) {
DRM_ERROR("failed to find dma buffer region!\n");
return DRM_ERR(EINVAL);
@@ -861,8 +839,8 @@ static int mga_do_init_dma( drm_device_t *dev, drm_mga_init_t *init )
}
dev_priv->sarea_priv =
- (drm_mga_sarea_t *)((u8 *)dev_priv->sarea->handle +
- init->sarea_priv_offset);
+ (drm_mga_sarea_t *) ((u8 *) dev_priv->sarea->handle +
+ init->sarea_priv_offset);
if (!dev_priv->warp->handle ||
!dev_priv->primary->handle ||
@@ -885,23 +863,20 @@ static int mga_do_init_dma( drm_device_t *dev, drm_mga_init_t *init )
return ret;
}
- dev_priv->prim.status = (u32 *)dev_priv->status->handle;
+ dev_priv->prim.status = (u32 *) dev_priv->status->handle;
- mga_do_wait_for_idle( dev_priv );
+ mga_do_wait_for_idle(dev_priv);
/* Init the primary DMA registers.
*/
- MGA_WRITE( MGA_PRIMADDRESS,
- dev_priv->primary->offset | MGA_DMA_GENERAL );
+ MGA_WRITE(MGA_PRIMADDRESS, dev_priv->primary->offset | MGA_DMA_GENERAL);
#if 0
- MGA_WRITE( MGA_PRIMPTR,
- virt_to_bus((void *)dev_priv->prim.status) |
- MGA_PRIMPTREN0 | /* Soft trap, SECEND, SETUPEND */
- MGA_PRIMPTREN1 ); /* DWGSYNC */
+ MGA_WRITE(MGA_PRIMPTR, virt_to_bus((void *)dev_priv->prim.status) | MGA_PRIMPTREN0 | /* Soft trap, SECEND, SETUPEND */
+ MGA_PRIMPTREN1); /* DWGSYNC */
#endif
- dev_priv->prim.start = (u8 *)dev_priv->primary->handle;
- dev_priv->prim.end = ((u8 *)dev_priv->primary->handle
+ dev_priv->prim.start = (u8 *) dev_priv->primary->handle;
+ dev_priv->prim.end = ((u8 *) dev_priv->primary->handle
+ dev_priv->primary->size);
dev_priv->prim.size = dev_priv->primary->size;
@@ -929,7 +904,7 @@ static int mga_do_init_dma( drm_device_t *dev, drm_mga_init_t *init )
return 0;
}
-static int mga_do_cleanup_dma( drm_device_t *dev )
+static int mga_do_cleanup_dma(drm_device_t * dev)
{
int err = 0;
DRM_DEBUG("\n");
@@ -938,16 +913,17 @@ static int mga_do_cleanup_dma( drm_device_t *dev )
* may not have been called from userspace and after dev_private
* is freed, it's too late.
*/
- if ( dev->irq_enabled ) drm_irq_uninstall(dev);
+ if (dev->irq_enabled)
+ drm_irq_uninstall(dev);
- if ( dev->dev_private ) {
+ if (dev->dev_private) {
drm_mga_private_t *dev_priv = dev->dev_private;
- if ((dev_priv->warp != NULL)
+ if ((dev_priv->warp != NULL)
&& (dev_priv->warp->type != _DRM_CONSISTENT))
drm_core_ioremapfree(dev_priv->warp, dev);
- if ((dev_priv->primary != NULL)
+ if ((dev_priv->primary != NULL)
&& (dev_priv->primary->type != _DRM_CONSISTENT))
drm_core_ioremapfree(dev_priv->primary, dev);
@@ -960,7 +936,8 @@ static int mga_do_cleanup_dma( drm_device_t *dev )
dev_priv->agp_textures = NULL;
drm_unbind_agp(dev_priv->agp_mem);
- drm_free_agp(dev_priv->agp_mem, dev_priv->agp_pages);
+ drm_free_agp(dev_priv->agp_mem,
+ dev_priv->agp_pages);
dev_priv->agp_pages = 0;
dev_priv->agp_mem = NULL;
}
@@ -982,7 +959,8 @@ static int mga_do_cleanup_dma( drm_device_t *dev )
memset(&dev_priv->prim, 0, sizeof(dev_priv->prim));
dev_priv->warp_pipe = 0;
- memset(dev_priv->warp_pipe_phys, 0, sizeof(dev_priv->warp_pipe_phys));
+ memset(dev_priv->warp_pipe_phys, 0,
+ sizeof(dev_priv->warp_pipe_phys));
if (dev_priv->head != NULL) {
mga_freelist_cleanup(dev);
@@ -992,103 +970,102 @@ static int mga_do_cleanup_dma( drm_device_t *dev )
return err;
}
-int mga_dma_init( DRM_IOCTL_ARGS )
+int mga_dma_init(DRM_IOCTL_ARGS)
{
DRM_DEVICE;
drm_mga_init_t init;
int err;
- LOCK_TEST_WITH_RETURN( dev, filp );
+ LOCK_TEST_WITH_RETURN(dev, filp);
DRM_COPY_FROM_USER_IOCTL(init, (drm_mga_init_t __user *) data,
sizeof(init));
- switch ( init.func ) {
+ switch (init.func) {
case MGA_INIT_DMA:
err = mga_do_init_dma(dev, &init);
if (err) {
- (void) mga_do_cleanup_dma(dev);
+ (void)mga_do_cleanup_dma(dev);
}
return err;
case MGA_CLEANUP_DMA:
- return mga_do_cleanup_dma( dev );
+ return mga_do_cleanup_dma(dev);
}
return DRM_ERR(EINVAL);
}
-
/* ================================================================
* Primary DMA stream management
*/
-int mga_dma_flush( DRM_IOCTL_ARGS )
+int mga_dma_flush(DRM_IOCTL_ARGS)
{
DRM_DEVICE;
- drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
+ drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private;
drm_lock_t lock;
- LOCK_TEST_WITH_RETURN( dev, filp );
+ LOCK_TEST_WITH_RETURN(dev, filp);
- DRM_COPY_FROM_USER_IOCTL( lock, (drm_lock_t __user *)data, sizeof(lock) );
+ DRM_COPY_FROM_USER_IOCTL(lock, (drm_lock_t __user *) data,
+ sizeof(lock));
- DRM_DEBUG( "%s%s%s\n",
- (lock.flags & _DRM_LOCK_FLUSH) ? "flush, " : "",
- (lock.flags & _DRM_LOCK_FLUSH_ALL) ? "flush all, " : "",
- (lock.flags & _DRM_LOCK_QUIESCENT) ? "idle, " : "" );
+ DRM_DEBUG("%s%s%s\n",
+ (lock.flags & _DRM_LOCK_FLUSH) ? "flush, " : "",
+ (lock.flags & _DRM_LOCK_FLUSH_ALL) ? "flush all, " : "",
+ (lock.flags & _DRM_LOCK_QUIESCENT) ? "idle, " : "");
- WRAP_WAIT_WITH_RETURN( dev_priv );
+ WRAP_WAIT_WITH_RETURN(dev_priv);
- if ( lock.flags & (_DRM_LOCK_FLUSH | _DRM_LOCK_FLUSH_ALL) ) {
- mga_do_dma_flush( dev_priv );
+ if (lock.flags & (_DRM_LOCK_FLUSH | _DRM_LOCK_FLUSH_ALL)) {
+ mga_do_dma_flush(dev_priv);
}
- if ( lock.flags & _DRM_LOCK_QUIESCENT ) {
+ if (lock.flags & _DRM_LOCK_QUIESCENT) {
#if MGA_DMA_DEBUG
- int ret = mga_do_wait_for_idle( dev_priv );
- if ( ret < 0 )
- DRM_INFO( "%s: -EBUSY\n", __FUNCTION__ );
+ int ret = mga_do_wait_for_idle(dev_priv);
+ if (ret < 0)
+ DRM_INFO("%s: -EBUSY\n", __FUNCTION__);
return ret;
#else
- return mga_do_wait_for_idle( dev_priv );
+ return mga_do_wait_for_idle(dev_priv);
#endif
} else {
return 0;
}
}
-int mga_dma_reset( DRM_IOCTL_ARGS )
+int mga_dma_reset(DRM_IOCTL_ARGS)
{
DRM_DEVICE;
- drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
+ drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private;
- LOCK_TEST_WITH_RETURN( dev, filp );
+ LOCK_TEST_WITH_RETURN(dev, filp);
- return mga_do_dma_reset( dev_priv );
+ return mga_do_dma_reset(dev_priv);
}
-
/* ================================================================
* DMA buffer management
*/
-static int mga_dma_get_buffers( DRMFILE filp,
- drm_device_t *dev, drm_dma_t *d )
+static int mga_dma_get_buffers(DRMFILE filp, drm_device_t * dev, drm_dma_t * d)
{
drm_buf_t *buf;
int i;
- for ( i = d->granted_count ; i < d->request_count ; i++ ) {
- buf = mga_freelist_get( dev );
- if ( !buf ) return DRM_ERR(EAGAIN);
+ for (i = d->granted_count; i < d->request_count; i++) {
+ buf = mga_freelist_get(dev);
+ if (!buf)
+ return DRM_ERR(EAGAIN);
buf->filp = filp;
- if ( DRM_COPY_TO_USER( &d->request_indices[i],
- &buf->idx, sizeof(buf->idx) ) )
+ if (DRM_COPY_TO_USER(&d->request_indices[i],
+ &buf->idx, sizeof(buf->idx)))
return DRM_ERR(EFAULT);
- if ( DRM_COPY_TO_USER( &d->request_sizes[i],
- &buf->total, sizeof(buf->total) ) )
+ if (DRM_COPY_TO_USER(&d->request_sizes[i],
+ &buf->total, sizeof(buf->total)))
return DRM_ERR(EFAULT);
d->granted_count++;
@@ -1096,44 +1073,44 @@ static int mga_dma_get_buffers( DRMFILE filp,
return 0;
}
-int mga_dma_buffers( DRM_IOCTL_ARGS )
+int mga_dma_buffers(DRM_IOCTL_ARGS)
{
DRM_DEVICE;
drm_device_dma_t *dma = dev->dma;
- drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
+ drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private;
drm_dma_t __user *argp = (void __user *)data;
drm_dma_t d;
int ret = 0;
- LOCK_TEST_WITH_RETURN( dev, filp );
+ LOCK_TEST_WITH_RETURN(dev, filp);
- DRM_COPY_FROM_USER_IOCTL( d, argp, sizeof(d) );
+ DRM_COPY_FROM_USER_IOCTL(d, argp, sizeof(d));
/* Please don't send us buffers.
*/
- if ( d.send_count != 0 ) {
- DRM_ERROR( "Process %d trying to send %d buffers via drmDMA\n",
- DRM_CURRENTPID, d.send_count );
+ if (d.send_count != 0) {
+ DRM_ERROR("Process %d trying to send %d buffers via drmDMA\n",
+ DRM_CURRENTPID, d.send_count);
return DRM_ERR(EINVAL);
}
/* We'll send you buffers.
*/
- if ( d.request_count < 0 || d.request_count > dma->buf_count ) {
- DRM_ERROR( "Process %d trying to get %d buffers (of %d max)\n",
- DRM_CURRENTPID, d.request_count, dma->buf_count );
+ if (d.request_count < 0 || d.request_count > dma->buf_count) {
+ DRM_ERROR("Process %d trying to get %d buffers (of %d max)\n",
+ DRM_CURRENTPID, d.request_count, dma->buf_count);
return DRM_ERR(EINVAL);
}
- WRAP_TEST_WITH_RETURN( dev_priv );
+ WRAP_TEST_WITH_RETURN(dev_priv);
d.granted_count = 0;
- if ( d.request_count ) {
- ret = mga_dma_get_buffers( filp, dev, &d );
+ if (d.request_count) {
+ ret = mga_dma_get_buffers(filp, dev, &d);
}
- DRM_COPY_TO_USER_IOCTL( argp, d, sizeof(d) );
+ DRM_COPY_TO_USER_IOCTL(argp, d, sizeof(d));
return ret;
}
@@ -1154,11 +1131,11 @@ int mga_driver_postcleanup(drm_device_t * dev)
*/
void mga_driver_pretakedown(drm_device_t * dev)
{
- mga_do_cleanup_dma( dev );
+ mga_do_cleanup_dma(dev);
}
-int mga_driver_dma_quiescent(drm_device_t *dev)
+int mga_driver_dma_quiescent(drm_device_t * dev)
{
drm_mga_private_t *dev_priv = dev->dev_private;
- return mga_do_wait_for_idle( dev_priv );
+ return mga_do_wait_for_idle(dev_priv);
}
diff --git a/drivers/char/drm/mga_drm.h b/drivers/char/drm/mga_drm.h
index d20aab3bd57b..44d1293e2947 100644
--- a/drivers/char/drm/mga_drm.h
+++ b/drivers/char/drm/mga_drm.h
@@ -44,10 +44,10 @@
/* WARP pipe flags
*/
-#define MGA_F 0x1 /* fog */
-#define MGA_A 0x2 /* alpha */
-#define MGA_S 0x4 /* specular */
-#define MGA_T2 0x8 /* multitexture */
+#define MGA_F 0x1 /* fog */
+#define MGA_A 0x2 /* alpha */
+#define MGA_S 0x4 /* specular */
+#define MGA_T2 0x8 /* multitexture */
#define MGA_WARP_TGZ 0
#define MGA_WARP_TGZF (MGA_F)
@@ -66,14 +66,14 @@
#define MGA_WARP_T2GZSA (MGA_T2|MGA_S|MGA_A)
#define MGA_WARP_T2GZSAF (MGA_T2|MGA_S|MGA_F|MGA_A)
-#define MGA_MAX_G200_PIPES 8 /* no multitex */
+#define MGA_MAX_G200_PIPES 8 /* no multitex */
#define MGA_MAX_G400_PIPES 16
#define MGA_MAX_WARP_PIPES MGA_MAX_G400_PIPES
-#define MGA_WARP_UCODE_SIZE 32768 /* in bytes */
+#define MGA_WARP_UCODE_SIZE 32768 /* in bytes */
#define MGA_CARD_TYPE_G200 1
#define MGA_CARD_TYPE_G400 2
-#define MGA_CARD_TYPE_G450 3 /* not currently used */
+#define MGA_CARD_TYPE_G450 3 /* not currently used */
#define MGA_CARD_TYPE_G550 4
#define MGA_FRONT 0x1
@@ -86,14 +86,14 @@
#define MGA_UPLOAD_TEX0 0x2
#define MGA_UPLOAD_TEX1 0x4
#define MGA_UPLOAD_PIPE 0x8
-#define MGA_UPLOAD_TEX0IMAGE 0x10 /* handled client-side */
-#define MGA_UPLOAD_TEX1IMAGE 0x20 /* handled client-side */
+#define MGA_UPLOAD_TEX0IMAGE 0x10 /* handled client-side */
+#define MGA_UPLOAD_TEX1IMAGE 0x20 /* handled client-side */
#define MGA_UPLOAD_2D 0x40
-#define MGA_WAIT_AGE 0x80 /* handled client-side */
-#define MGA_UPLOAD_CLIPRECTS 0x100 /* handled client-side */
+#define MGA_WAIT_AGE 0x80 /* handled client-side */
+#define MGA_UPLOAD_CLIPRECTS 0x100 /* handled client-side */
#if 0
-#define MGA_DMA_FLUSH 0x200 /* set when someone gets the lock
- quiescent */
+#define MGA_DMA_FLUSH 0x200 /* set when someone gets the lock
+ quiescent */
#endif
/* 32 buffers of 64k each, total 2 meg.
@@ -120,8 +120,7 @@
#define DRM_MGA_IDLE_RETRY 2048
-#endif /* __MGA_SAREA_DEFINES__ */
-
+#endif /* __MGA_SAREA_DEFINES__ */
/* Setup registers for 3D context
*/
@@ -165,25 +164,25 @@ typedef struct {
/* General aging mechanism
*/
typedef struct {
- unsigned int head; /* Position of head pointer */
- unsigned int wrap; /* Primary DMA wrap count */
+ unsigned int head; /* Position of head pointer */
+ unsigned int wrap; /* Primary DMA wrap count */
} drm_mga_age_t;
typedef struct _drm_mga_sarea {
/* The channel for communication of state information to the kernel
* on firing a vertex dma buffer.
*/
- drm_mga_context_regs_t context_state;
- drm_mga_server_regs_t server_state;
- drm_mga_texture_regs_t tex_state[2];
- unsigned int warp_pipe;
- unsigned int dirty;
- unsigned int vertsize;
+ drm_mga_context_regs_t context_state;
+ drm_mga_server_regs_t server_state;
+ drm_mga_texture_regs_t tex_state[2];
+ unsigned int warp_pipe;
+ unsigned int dirty;
+ unsigned int vertsize;
/* The current cliprects, or a subset thereof.
*/
- drm_clip_rect_t boxes[MGA_NR_SAREA_CLIPRECTS];
- unsigned int nbox;
+ drm_clip_rect_t boxes[MGA_NR_SAREA_CLIPRECTS];
+ unsigned int nbox;
/* Information about the most recently used 3d drawable. The
* client fills in the req_* fields, the server fills in the
@@ -192,18 +191,18 @@ typedef struct _drm_mga_sarea {
* The client clears the exported_drawable field before
* clobbering the boxes data.
*/
- unsigned int req_drawable; /* the X drawable id */
- unsigned int req_draw_buffer; /* MGA_FRONT or MGA_BACK */
+ unsigned int req_drawable; /* the X drawable id */
+ unsigned int req_draw_buffer; /* MGA_FRONT or MGA_BACK */
- unsigned int exported_drawable;
+ unsigned int exported_drawable;
unsigned int exported_index;
- unsigned int exported_stamp;
- unsigned int exported_buffers;
- unsigned int exported_nfront;
- unsigned int exported_nback;
+ unsigned int exported_stamp;
+ unsigned int exported_buffers;
+ unsigned int exported_nfront;
+ unsigned int exported_nback;
int exported_back_x, exported_front_x, exported_w;
int exported_back_y, exported_front_y, exported_h;
- drm_clip_rect_t exported_boxes[MGA_NR_SAREA_CLIPRECTS];
+ drm_clip_rect_t exported_boxes[MGA_NR_SAREA_CLIPRECTS];
/* Counters for aging textures and for client-side throttling.
*/
@@ -211,21 +210,20 @@ typedef struct _drm_mga_sarea {
unsigned int last_wrap;
drm_mga_age_t last_frame;
- unsigned int last_enqueue; /* last time a buffer was enqueued */
+ unsigned int last_enqueue; /* last time a buffer was enqueued */
unsigned int last_dispatch; /* age of the most recently dispatched buffer */
- unsigned int last_quiescent; /* */
+ unsigned int last_quiescent; /* */
/* LRU lists for texture memory in agp space and on the card.
*/
- drm_tex_region_t texList[MGA_NR_TEX_HEAPS][MGA_NR_TEX_REGIONS+1];
+ drm_tex_region_t texList[MGA_NR_TEX_HEAPS][MGA_NR_TEX_REGIONS + 1];
unsigned int texAge[MGA_NR_TEX_HEAPS];
/* Mechanism to validate card state.
*/
- int ctxOwner;
+ int ctxOwner;
} drm_mga_sarea_t;
-
/* MGA specific ioctls
* The device specific ioctl range is 0x40 to 0x79.
*/
@@ -247,7 +245,6 @@ typedef struct _drm_mga_sarea {
#define DRM_MGA_WAIT_FENCE 0x0b
#define DRM_MGA_DMA_BOOTSTRAP 0x0c
-
#define DRM_IOCTL_MGA_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_MGA_INIT, drm_mga_init_t)
#define DRM_IOCTL_MGA_FLUSH DRM_IOW( DRM_COMMAND_BASE + DRM_MGA_FLUSH, drm_lock_t)
#define DRM_IOCTL_MGA_RESET DRM_IO( DRM_COMMAND_BASE + DRM_MGA_RESET)
@@ -263,33 +260,33 @@ typedef struct _drm_mga_sarea {
#define DRM_IOCTL_MGA_DMA_BOOTSTRAP DRM_IOWR(DRM_COMMAND_BASE + DRM_MGA_DMA_BOOTSTRAP, drm_mga_dma_bootstrap_t)
typedef struct _drm_mga_warp_index {
- int installed;
- unsigned long phys_addr;
- int size;
+ int installed;
+ unsigned long phys_addr;
+ int size;
} drm_mga_warp_index_t;
typedef struct drm_mga_init {
- enum {
- MGA_INIT_DMA = 0x01,
- MGA_CLEANUP_DMA = 0x02
+ enum {
+ MGA_INIT_DMA = 0x01,
+ MGA_CLEANUP_DMA = 0x02
} func;
- unsigned long sarea_priv_offset;
+ unsigned long sarea_priv_offset;
int chipset;
- int sgram;
+ int sgram;
unsigned int maccess;
- unsigned int fb_cpp;
+ unsigned int fb_cpp;
unsigned int front_offset, front_pitch;
- unsigned int back_offset, back_pitch;
+ unsigned int back_offset, back_pitch;
- unsigned int depth_cpp;
- unsigned int depth_offset, depth_pitch;
+ unsigned int depth_cpp;
+ unsigned int depth_offset, depth_pitch;
- unsigned int texture_offset[MGA_NR_TEX_HEAPS];
- unsigned int texture_size[MGA_NR_TEX_HEAPS];
+ unsigned int texture_offset[MGA_NR_TEX_HEAPS];
+ unsigned int texture_size[MGA_NR_TEX_HEAPS];
unsigned long fb_offset;
unsigned long mmio_offset;
@@ -302,64 +299,59 @@ typedef struct drm_mga_init {
typedef struct drm_mga_dma_bootstrap {
/**
* \name AGP texture region
- *
+ *
* On return from the DRM_MGA_DMA_BOOTSTRAP ioctl, these fields will
* be filled in with the actual AGP texture settings.
- *
+ *
* \warning
* If these fields are non-zero, but dma_mga_dma_bootstrap::agp_mode
* is zero, it means that PCI memory (most likely through the use of
* an IOMMU) is being used for "AGP" textures.
*/
- /*@{*/
+ /*@{ */
unsigned long texture_handle; /**< Handle used to map AGP textures. */
- uint32_t texture_size; /**< Size of the AGP texture region. */
- /*@}*/
-
+ uint32_t texture_size; /**< Size of the AGP texture region. */
+ /*@} */
/**
* Requested size of the primary DMA region.
- *
+ *
* On return from the DRM_MGA_DMA_BOOTSTRAP ioctl, this field will be
* filled in with the actual AGP mode. If AGP was not available
*/
uint32_t primary_size;
-
/**
* Requested number of secondary DMA buffers.
- *
+ *
* On return from the DRM_MGA_DMA_BOOTSTRAP ioctl, this field will be
* filled in with the actual number of secondary DMA buffers
* allocated. Particularly when PCI DMA is used, this may be
* (subtantially) less than the number requested.
*/
uint32_t secondary_bin_count;
-
-
+
/**
* Requested size of each secondary DMA buffer.
- *
+ *
* While the kernel \b is free to reduce
* dma_mga_dma_bootstrap::secondary_bin_count, it is \b not allowed
* to reduce dma_mga_dma_bootstrap::secondary_bin_size.
*/
uint32_t secondary_bin_size;
-
/**
* Bit-wise mask of AGPSTAT2_* values. Currently only \c AGPSTAT2_1X,
* \c AGPSTAT2_2X, and \c AGPSTAT2_4X are supported. If this value is
* zero, it means that PCI DMA should be used, even if AGP is
* possible.
- *
+ *
* On return from the DRM_MGA_DMA_BOOTSTRAP ioctl, this field will be
* filled in with the actual AGP mode. If AGP was not available
* (i.e., PCI DMA was used), this value will be zero.
*/
uint32_t agp_mode;
-
/**
* Desired AGP GART size, measured in megabytes.
*/
@@ -375,16 +367,16 @@ typedef struct drm_mga_clear {
} drm_mga_clear_t;
typedef struct drm_mga_vertex {
- int idx; /* buffer to queue */
- int used; /* bytes in use */
- int discard; /* client finished with buffer? */
+ int idx; /* buffer to queue */
+ int used; /* bytes in use */
+ int discard; /* client finished with buffer? */
} drm_mga_vertex_t;
typedef struct drm_mga_indices {
- int idx; /* buffer to queue */
+ int idx; /* buffer to queue */
unsigned int start;
unsigned int end;
- int discard; /* client finished with buffer? */
+ int discard; /* client finished with buffer? */
} drm_mga_indices_t;
typedef struct drm_mga_iload {
@@ -400,12 +392,12 @@ typedef struct _drm_mga_blit {
int src_pitch, dst_pitch;
int delta_sx, delta_sy;
int delta_dx, delta_dy;
- int height, ydir; /* flip image vertically */
+ int height, ydir; /* flip image vertically */
int source_pitch, dest_pitch;
} drm_mga_blit_t;
/* 3.1: An ioctl to get parameters that aren't available to the 3d
- * client any other way.
+ * client any other way.
*/
#define MGA_PARAM_IRQ_NR 1
diff --git a/drivers/char/drm/mga_drv.c b/drivers/char/drm/mga_drv.c
index daabbba3b297..0cc7c305a7f6 100644
--- a/drivers/char/drm/mga_drv.c
+++ b/drivers/char/drm/mga_drv.c
@@ -35,14 +35,13 @@
#include "mga_drm.h"
#include "mga_drv.h"
-
#include "drm_pciids.h"
static int mga_driver_device_is_agp(drm_device_t * dev);
-static int postinit( struct drm_device *dev, unsigned long flags )
+static int postinit(struct drm_device *dev, unsigned long flags)
{
- drm_mga_private_t * const dev_priv =
- (drm_mga_private_t *) dev->dev_private;
+ drm_mga_private_t *const dev_priv =
+ (drm_mga_private_t *) dev->dev_private;
dev_priv->mmio_base = pci_resource_start(dev->pdev, 1);
dev_priv->mmio_size = pci_resource_len(dev->pdev, 1);
@@ -52,28 +51,26 @@ static int postinit( struct drm_device *dev, unsigned long flags )
dev->types[7] = _DRM_STAT_PRIMARY;
dev->types[8] = _DRM_STAT_SECONDARY;
- DRM_INFO( "Initialized %s %d.%d.%d %s on minor %d: %s\n",
- DRIVER_NAME,
- DRIVER_MAJOR,
- DRIVER_MINOR,
- DRIVER_PATCHLEVEL,
- DRIVER_DATE,
- dev->primary.minor,
- pci_pretty_name(dev->pdev)
- );
+ DRM_INFO("Initialized %s %d.%d.%d %s on minor %d: %s\n",
+ DRIVER_NAME,
+ DRIVER_MAJOR,
+ DRIVER_MINOR,
+ DRIVER_PATCHLEVEL,
+ DRIVER_DATE, dev->primary.minor, pci_pretty_name(dev->pdev)
+ );
return 0;
}
-static int version( drm_version_t *version )
+static int version(drm_version_t * version)
{
int len;
version->version_major = DRIVER_MAJOR;
version->version_minor = DRIVER_MINOR;
version->version_patchlevel = DRIVER_PATCHLEVEL;
- DRM_COPY( version->name, DRIVER_NAME );
- DRM_COPY( version->date, DRIVER_DATE );
- DRM_COPY( version->desc, DRIVER_DESC );
+ DRM_COPY(version->name, DRIVER_NAME);
+ DRM_COPY(version->date, DRIVER_DATE);
+ DRM_COPY(version->desc, DRIVER_DESC);
return 0;
}
@@ -81,11 +78,11 @@ static struct pci_device_id pciidlist[] = {
mga_PCI_IDS
};
-extern drm_ioctl_desc_t mga_ioctls[];
-extern int mga_max_ioctl;
-
static struct drm_driver driver = {
- .driver_features = DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | DRIVER_USE_MTRR | DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_IRQ_VBL,
+ .driver_features =
+ DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | DRIVER_USE_MTRR |
+ DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED |
+ DRIVER_IRQ_VBL,
.preinit = mga_driver_preinit,
.postcleanup = mga_driver_postcleanup,
.pretakedown = mga_driver_pretakedown,
@@ -104,21 +101,21 @@ static struct drm_driver driver = {
.ioctls = mga_ioctls,
.dma_ioctl = mga_dma_buffers,
.fops = {
- .owner = THIS_MODULE,
- .open = drm_open,
- .release = drm_release,
- .ioctl = drm_ioctl,
- .mmap = drm_mmap,
- .poll = drm_poll,
- .fasync = drm_fasync,
+ .owner = THIS_MODULE,
+ .open = drm_open,
+ .release = drm_release,
+ .ioctl = drm_ioctl,
+ .mmap = drm_mmap,
+ .poll = drm_poll,
+ .fasync = drm_fasync,
#ifdef CONFIG_COMPAT
- .compat_ioctl = mga_compat_ioctl,
+ .compat_ioctl = mga_compat_ioctl,
#endif
- },
+ },
.pci_driver = {
- .name = DRIVER_NAME,
- .id_table = pciidlist,
- }
+ .name = DRIVER_NAME,
+ .id_table = pciidlist,
+ }
};
static int __init mga_init(void)
@@ -135,8 +132,8 @@ static void __exit mga_exit(void)
module_init(mga_init);
module_exit(mga_exit);
-MODULE_AUTHOR( DRIVER_AUTHOR );
-MODULE_DESCRIPTION( DRIVER_DESC );
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL and additional rights");
/**
@@ -151,10 +148,9 @@ MODULE_LICENSE("GPL and additional rights");
* \returns
* If the device is a PCI G450, zero is returned. Otherwise 2 is returned.
*/
-int mga_driver_device_is_agp(drm_device_t * dev)
+static int mga_driver_device_is_agp(drm_device_t * dev)
{
- const struct pci_dev * const pdev = dev->pdev;
-
+ const struct pci_dev *const pdev = dev->pdev;
/* There are PCI versions of the G450. These cards have the
* same PCI ID as the AGP G450, but have an additional PCI-to-PCI
@@ -164,10 +160,10 @@ int mga_driver_device_is_agp(drm_device_t * dev)
* device is 0x0021 (HB6 Universal PCI-PCI bridge), we reject the
* device.
*/
-
- if ( (pdev->device == 0x0525)
- && (pdev->bus->self->vendor == 0x3388)
- && (pdev->bus->self->device == 0x0021) ) {
+
+ if ((pdev->device == 0x0525)
+ && (pdev->bus->self->vendor == 0x3388)
+ && (pdev->bus->self->device == 0x0021)) {
return 0;
}
diff --git a/drivers/char/drm/mga_drv.h b/drivers/char/drm/mga_drv.h
index 6059c5a5b105..461728e6a58a 100644
--- a/drivers/char/drm/mga_drv.h
+++ b/drivers/char/drm/mga_drv.h
@@ -62,14 +62,14 @@ typedef struct drm_mga_primary_buffer {
} drm_mga_primary_buffer_t;
typedef struct drm_mga_freelist {
- struct drm_mga_freelist *next;
- struct drm_mga_freelist *prev;
+ struct drm_mga_freelist *next;
+ struct drm_mga_freelist *prev;
drm_mga_age_t age;
- drm_buf_t *buf;
+ drm_buf_t *buf;
} drm_mga_freelist_t;
typedef struct {
- drm_mga_freelist_t *list_entry;
+ drm_mga_freelist_t *list_entry;
int discard;
int dispatched;
} drm_mga_buf_priv_t;
@@ -78,8 +78,8 @@ typedef struct drm_mga_private {
drm_mga_primary_buffer_t prim;
drm_mga_sarea_t *sarea_priv;
- drm_mga_freelist_t *head;
- drm_mga_freelist_t *tail;
+ drm_mga_freelist_t *head;
+ drm_mga_freelist_t *tail;
unsigned int warp_pipe;
unsigned long warp_pipe_phys[MGA_MAX_WARP_PIPES];
@@ -109,13 +109,13 @@ typedef struct drm_mga_private {
/**
* \name MMIO region parameters.
- *
+ *
* \sa drm_mga_private_t::mmio
*/
- /*@{*/
- u32 mmio_base; /**< Bus address of base of MMIO. */
- u32 mmio_size; /**< Size of the MMIO region. */
- /*@}*/
+ /*@{ */
+ u32 mmio_base; /**< Bus address of base of MMIO. */
+ u32 mmio_size; /**< Size of the MMIO region. */
+ /*@} */
u32 clear_cmd;
u32 maccess;
@@ -143,11 +143,14 @@ typedef struct drm_mga_private {
drm_local_map_t *warp;
drm_local_map_t *primary;
drm_local_map_t *agp_textures;
-
+
DRM_AGP_MEM *agp_mem;
unsigned int agp_pages;
} drm_mga_private_t;
+extern drm_ioctl_desc_t mga_ioctls[];
+extern int mga_max_ioctl;
+
/* mga_dma.c */
extern int mga_driver_preinit(drm_device_t * dev, unsigned long flags);
extern int mga_dma_bootstrap(DRM_IOCTL_ARGS);
@@ -165,7 +168,7 @@ extern void mga_do_dma_flush(drm_mga_private_t * dev_priv);
extern void mga_do_dma_wrap_start(drm_mga_private_t * dev_priv);
extern void mga_do_dma_wrap_end(drm_mga_private_t * dev_priv);
-extern int mga_freelist_put( drm_device_t *dev, drm_buf_t *buf );
+extern int mga_freelist_put(drm_device_t * dev, drm_buf_t * buf);
/* mga_warp.c */
extern unsigned int mga_warp_microcode_size(const drm_mga_private_t * dev_priv);
@@ -196,7 +199,7 @@ extern long mga_compat_ioctl(struct file *filp, unsigned int cmd,
#define MGA_WRITE( reg, val ) do { DRM_WRITEMEMORYBARRIER(); MGA_DEREF( reg ) = val; } while (0)
#define MGA_WRITE8( reg, val ) do { DRM_WRITEMEMORYBARRIER(); MGA_DEREF8( reg ) = val; } while (0)
-static inline u32 _MGA_READ(u32 *addr)
+static inline u32 _MGA_READ(u32 * addr)
{
DRM_MEMORYBARRIER();
return *(volatile u32 *)addr;
@@ -218,8 +221,6 @@ static inline u32 _MGA_READ(u32 *addr)
#define DMAREG1(r) (u8)(((r - DWGREG1) >> 2) | 0x80)
#define DMAREG(r) (ISREG0(r) ? DMAREG0(r) : DMAREG1(r))
-
-
/* ================================================================
* Helper macross...
*/
@@ -261,7 +262,6 @@ do { \
} \
} while (0)
-
/* ================================================================
* Primary DMA command stream
*/
@@ -346,7 +346,6 @@ do { \
write += DMA_BLOCK_SIZE; \
} while (0)
-
/* Buffer aging via primary DMA stream head pointer.
*/
@@ -373,7 +372,6 @@ do { \
} \
} while (0)
-
#define MGA_ENGINE_IDLE_MASK (MGA_SOFTRAPEN | \
MGA_DWGENGSTS | \
MGA_ENDPRDMASTS)
@@ -382,8 +380,6 @@ do { \
#define MGA_DMA_DEBUG 0
-
-
/* A reduced set of the mga registers.
*/
#define MGA_CRTC_INDEX 0x1fd4
@@ -644,7 +640,6 @@ do { \
# define MGA_G400_WR_MAGIC (1 << 6)
# define MGA_G400_WR56_MAGIC 0x46480000 /* 12800.0f */
-
#define MGA_ILOAD_ALIGN 64
#define MGA_ILOAD_MASK (MGA_ILOAD_ALIGN - 1)
@@ -679,10 +674,10 @@ do { \
/* Simple idle test.
*/
-static __inline__ int mga_is_idle( drm_mga_private_t *dev_priv )
+static __inline__ int mga_is_idle(drm_mga_private_t * dev_priv)
{
- u32 status = MGA_READ( MGA_STATUS ) & MGA_ENGINE_IDLE_MASK;
- return ( status == MGA_ENDPRDMASTS );
+ u32 status = MGA_READ(MGA_STATUS) & MGA_ENGINE_IDLE_MASK;
+ return (status == MGA_ENDPRDMASTS);
}
#endif
diff --git a/drivers/char/drm/mga_ioc32.c b/drivers/char/drm/mga_ioc32.c
index 77d738e75a4d..24a9d4e86af0 100644
--- a/drivers/char/drm/mga_ioc32.c
+++ b/drivers/char/drm/mga_ioc32.c
@@ -39,17 +39,17 @@
typedef struct drm32_mga_init {
int func;
- u32 sarea_priv_offset;
+ u32 sarea_priv_offset;
int chipset;
- int sgram;
+ int sgram;
unsigned int maccess;
- unsigned int fb_cpp;
+ unsigned int fb_cpp;
unsigned int front_offset, front_pitch;
- unsigned int back_offset, back_pitch;
- unsigned int depth_cpp;
- unsigned int depth_offset, depth_pitch;
- unsigned int texture_offset[MGA_NR_TEX_HEAPS];
- unsigned int texture_size[MGA_NR_TEX_HEAPS];
+ unsigned int back_offset, back_pitch;
+ unsigned int depth_cpp;
+ unsigned int depth_offset, depth_pitch;
+ unsigned int texture_offset[MGA_NR_TEX_HEAPS];
+ unsigned int texture_size[MGA_NR_TEX_HEAPS];
u32 fb_offset;
u32 mmio_offset;
u32 status_offset;
@@ -64,10 +64,10 @@ static int compat_mga_init(struct file *file, unsigned int cmd,
drm_mga_init32_t init32;
drm_mga_init_t __user *init;
int err = 0, i;
-
+
if (copy_from_user(&init32, (void __user *)arg, sizeof(init32)))
return -EFAULT;
-
+
init = compat_alloc_user_space(sizeof(*init));
if (!access_ok(VERIFY_WRITE, init, sizeof(*init))
|| __put_user(init32.func, &init->func)
@@ -90,42 +90,43 @@ static int compat_mga_init(struct file *file, unsigned int cmd,
|| __put_user(init32.primary_offset, &init->primary_offset)
|| __put_user(init32.buffers_offset, &init->buffers_offset))
return -EFAULT;
-
- for (i=0; i<MGA_NR_TEX_HEAPS; i++)
- {
- err |= __put_user(init32.texture_offset[i], &init->texture_offset[i]);
- err |= __put_user(init32.texture_size[i], &init->texture_size[i]);
+
+ for (i = 0; i < MGA_NR_TEX_HEAPS; i++) {
+ err |=
+ __put_user(init32.texture_offset[i],
+ &init->texture_offset[i]);
+ err |=
+ __put_user(init32.texture_size[i], &init->texture_size[i]);
}
if (err)
return -EFAULT;
-
+
return drm_ioctl(file->f_dentry->d_inode, file,
- DRM_IOCTL_MGA_INIT, (unsigned long) init);
+ DRM_IOCTL_MGA_INIT, (unsigned long)init);
}
-
typedef struct drm_mga_getparam32 {
int param;
u32 value;
} drm_mga_getparam32_t;
-
static int compat_mga_getparam(struct file *file, unsigned int cmd,
unsigned long arg)
{
drm_mga_getparam32_t getparam32;
drm_mga_getparam_t __user *getparam;
-
+
if (copy_from_user(&getparam32, (void __user *)arg, sizeof(getparam32)))
return -EFAULT;
getparam = compat_alloc_user_space(sizeof(*getparam));
if (!access_ok(VERIFY_WRITE, getparam, sizeof(*getparam))
|| __put_user(getparam32.param, &getparam->param)
- || __put_user((void __user *)(unsigned long)getparam32.value, &getparam->value))
+ || __put_user((void __user *)(unsigned long)getparam32.value,
+ &getparam->value))
return -EFAULT;
- return drm_ioctl(file->f_dentry->d_inode, file,
+ return drm_ioctl(file->f_dentry->d_inode, file,
DRM_IOCTL_MGA_GETPARAM, (unsigned long)getparam);
}
@@ -182,14 +183,12 @@ static int compat_mga_dma_bootstrap(struct file *file, unsigned int cmd,
&dma_bootstrap->secondary_bin_count)
|| __get_user(dma_bootstrap32.secondary_bin_size,
&dma_bootstrap->secondary_bin_size)
- || __get_user(dma_bootstrap32.agp_mode,
- &dma_bootstrap->agp_mode)
- || __get_user(dma_bootstrap32.agp_size,
- &dma_bootstrap->agp_size))
+ || __get_user(dma_bootstrap32.agp_mode, &dma_bootstrap->agp_mode)
+ || __get_user(dma_bootstrap32.agp_size, &dma_bootstrap->agp_size))
return -EFAULT;
if (copy_to_user((void __user *)arg, &dma_bootstrap32,
- sizeof(dma_bootstrap32)))
+ sizeof(dma_bootstrap32)))
return -EFAULT;
return 0;
@@ -210,8 +209,7 @@ drm_ioctl_compat_t *mga_compat_ioctls[] = {
* \param arg user argument.
* \return zero on success or negative number on failure.
*/
-long mga_compat_ioctl(struct file *filp, unsigned int cmd,
- unsigned long arg)
+long mga_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
unsigned int nr = DRM_IOCTL_NR(cmd);
drm_ioctl_compat_t *fn = NULL;
@@ -219,13 +217,13 @@ long mga_compat_ioctl(struct file *filp, unsigned int cmd,
if (nr < DRM_COMMAND_BASE)
return drm_compat_ioctl(filp, cmd, arg);
-
+
if (nr < DRM_COMMAND_BASE + DRM_ARRAY_SIZE(mga_compat_ioctls))
fn = mga_compat_ioctls[nr - DRM_COMMAND_BASE];
lock_kernel(); /* XXX for now */
if (fn != NULL)
- ret = (*fn)(filp, cmd, arg);
+ ret = (*fn) (filp, cmd, arg);
else
ret = drm_ioctl(filp->f_dentry->d_inode, filp, cmd, arg);
unlock_kernel();
diff --git a/drivers/char/drm/mga_irq.c b/drivers/char/drm/mga_irq.c
index 52eaa4e788f9..eb9644024172 100644
--- a/drivers/char/drm/mga_irq.c
+++ b/drivers/char/drm/mga_irq.c
@@ -1,7 +1,7 @@
/* mga_irq.c -- IRQ handling for radeon -*- linux-c -*-
*
* Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
- *
+ *
* The Weather Channel (TM) funded Tungsten Graphics to develop the
* initial release of the Radeon 8500 driver under the XFree86 license.
* This notice must be preserved.
@@ -35,19 +35,18 @@
#include "mga_drm.h"
#include "mga_drv.h"
-irqreturn_t mga_driver_irq_handler( DRM_IRQ_ARGS )
+irqreturn_t mga_driver_irq_handler(DRM_IRQ_ARGS)
{
drm_device_t *dev = (drm_device_t *) arg;
- drm_mga_private_t *dev_priv =
- (drm_mga_private_t *)dev->dev_private;
+ drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private;
int status;
int handled = 0;
status = MGA_READ(MGA_STATUS);
/* VBLANK interrupt */
- if ( status & MGA_VLINEPEN ) {
- MGA_WRITE( MGA_ICLEAR, MGA_VLINEICLR );
+ if (status & MGA_VLINEPEN) {
+ MGA_WRITE(MGA_ICLEAR, MGA_VLINEICLR);
atomic_inc(&dev->vbl_received);
DRM_WAKEUP(&dev->vbl_queue);
drm_vbl_send_signals(dev);
@@ -57,15 +56,14 @@ irqreturn_t mga_driver_irq_handler( DRM_IRQ_ARGS )
/* SOFTRAP interrupt */
if (status & MGA_SOFTRAPEN) {
const u32 prim_start = MGA_READ(MGA_PRIMADDRESS);
- const u32 prim_end = MGA_READ(MGA_PRIMEND);
-
+ const u32 prim_end = MGA_READ(MGA_PRIMEND);
MGA_WRITE(MGA_ICLEAR, MGA_SOFTRAPICLR);
/* In addition to clearing the interrupt-pending bit, we
* have to write to MGA_PRIMEND to re-start the DMA operation.
*/
- if ( (prim_start & ~0x03) != (prim_end & ~0x03) ) {
+ if ((prim_start & ~0x03) != (prim_end & ~0x03)) {
MGA_WRITE(MGA_PRIMEND, prim_end);
}
@@ -74,24 +72,24 @@ irqreturn_t mga_driver_irq_handler( DRM_IRQ_ARGS )
handled = 1;
}
- if ( handled ) {
+ if (handled) {
return IRQ_HANDLED;
}
return IRQ_NONE;
}
-int mga_driver_vblank_wait(drm_device_t *dev, unsigned int *sequence)
+int mga_driver_vblank_wait(drm_device_t * dev, unsigned int *sequence)
{
unsigned int cur_vblank;
int ret = 0;
/* Assume that the user has missed the current sequence number
* by about a day rather than she wants to wait for years
- * using vertical blanks...
+ * using vertical blanks...
*/
- DRM_WAIT_ON( ret, dev->vbl_queue, 3*DRM_HZ,
- ( ( ( cur_vblank = atomic_read(&dev->vbl_received ) )
- - *sequence ) <= (1<<23) ) );
+ DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ,
+ (((cur_vblank = atomic_read(&dev->vbl_received))
+ - *sequence) <= (1 << 23)));
*sequence = cur_vblank;
@@ -122,29 +120,29 @@ void mga_driver_irq_preinstall(drm_device_t * dev)
drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private;
/* Disable *all* interrupts */
- MGA_WRITE( MGA_IEN, 0 );
+ MGA_WRITE(MGA_IEN, 0);
/* Clear bits if they're already high */
- MGA_WRITE( MGA_ICLEAR, ~0 );
+ MGA_WRITE(MGA_ICLEAR, ~0);
}
void mga_driver_irq_postinstall(drm_device_t * dev)
{
drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private;
- DRM_INIT_WAITQUEUE( &dev_priv->fence_queue );
+ DRM_INIT_WAITQUEUE(&dev_priv->fence_queue);
/* Turn on vertical blank interrupt and soft trap interrupt. */
MGA_WRITE(MGA_IEN, MGA_VLINEIEN | MGA_SOFTRAPEN);
}
-void mga_driver_irq_uninstall( drm_device_t *dev ) {
- drm_mga_private_t *dev_priv =
- (drm_mga_private_t *)dev->dev_private;
+void mga_driver_irq_uninstall(drm_device_t * dev)
+{
+ drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private;
if (!dev_priv)
return;
/* Disable *all* interrupts */
MGA_WRITE(MGA_IEN, 0);
-
+
dev->irq_enabled = 0;
}
diff --git a/drivers/char/drm/mga_state.c b/drivers/char/drm/mga_state.c
index 6ac5e006226f..47f54b5ae956 100644
--- a/drivers/char/drm/mga_state.c
+++ b/drivers/char/drm/mga_state.c
@@ -41,15 +41,15 @@
* DMA hardware state programming functions
*/
-static void mga_emit_clip_rect( drm_mga_private_t *dev_priv,
- drm_clip_rect_t *box )
+static void mga_emit_clip_rect(drm_mga_private_t * dev_priv,
+ drm_clip_rect_t * box)
{
drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
drm_mga_context_regs_t *ctx = &sarea_priv->context_state;
unsigned int pitch = dev_priv->front_pitch;
DMA_LOCALS;
- BEGIN_DMA( 2 );
+ BEGIN_DMA(2);
/* Force reset of DWGCTL on G400 (eliminates clip disable bit).
*/
@@ -61,101 +61,90 @@ static void mga_emit_clip_rect( drm_mga_private_t *dev_priv,
}
DMA_BLOCK(MGA_DMAPAD, 0x00000000,
MGA_CXBNDRY, ((box->x2 - 1) << 16) | box->x1,
- MGA_YTOP, box->y1 * pitch,
- MGA_YBOT, (box->y2 - 1) * pitch);
+ MGA_YTOP, box->y1 * pitch, MGA_YBOT, (box->y2 - 1) * pitch);
ADVANCE_DMA();
}
-static __inline__ void mga_g200_emit_context( drm_mga_private_t *dev_priv )
+static __inline__ void mga_g200_emit_context(drm_mga_private_t * dev_priv)
{
drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
drm_mga_context_regs_t *ctx = &sarea_priv->context_state;
DMA_LOCALS;
- BEGIN_DMA( 3 );
+ BEGIN_DMA(3);
- DMA_BLOCK( MGA_DSTORG, ctx->dstorg,
- MGA_MACCESS, ctx->maccess,
- MGA_PLNWT, ctx->plnwt,
- MGA_DWGCTL, ctx->dwgctl );
+ DMA_BLOCK(MGA_DSTORG, ctx->dstorg,
+ MGA_MACCESS, ctx->maccess,
+ MGA_PLNWT, ctx->plnwt, MGA_DWGCTL, ctx->dwgctl);
- DMA_BLOCK( MGA_ALPHACTRL, ctx->alphactrl,
- MGA_FOGCOL, ctx->fogcolor,
- MGA_WFLAG, ctx->wflag,
- MGA_ZORG, dev_priv->depth_offset );
+ DMA_BLOCK(MGA_ALPHACTRL, ctx->alphactrl,
+ MGA_FOGCOL, ctx->fogcolor,
+ MGA_WFLAG, ctx->wflag, MGA_ZORG, dev_priv->depth_offset);
- DMA_BLOCK( MGA_FCOL, ctx->fcol,
- MGA_DMAPAD, 0x00000000,
- MGA_DMAPAD, 0x00000000,
- MGA_DMAPAD, 0x00000000 );
+ DMA_BLOCK(MGA_FCOL, ctx->fcol,
+ MGA_DMAPAD, 0x00000000,
+ MGA_DMAPAD, 0x00000000, MGA_DMAPAD, 0x00000000);
ADVANCE_DMA();
}
-static __inline__ void mga_g400_emit_context( drm_mga_private_t *dev_priv )
+static __inline__ void mga_g400_emit_context(drm_mga_private_t * dev_priv)
{
drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
drm_mga_context_regs_t *ctx = &sarea_priv->context_state;
DMA_LOCALS;
- BEGIN_DMA( 4 );
+ BEGIN_DMA(4);
- DMA_BLOCK( MGA_DSTORG, ctx->dstorg,
- MGA_MACCESS, ctx->maccess,
- MGA_PLNWT, ctx->plnwt,
- MGA_DWGCTL, ctx->dwgctl );
+ DMA_BLOCK(MGA_DSTORG, ctx->dstorg,
+ MGA_MACCESS, ctx->maccess,
+ MGA_PLNWT, ctx->plnwt, MGA_DWGCTL, ctx->dwgctl);
- DMA_BLOCK( MGA_ALPHACTRL, ctx->alphactrl,
- MGA_FOGCOL, ctx->fogcolor,
- MGA_WFLAG, ctx->wflag,
- MGA_ZORG, dev_priv->depth_offset );
+ DMA_BLOCK(MGA_ALPHACTRL, ctx->alphactrl,
+ MGA_FOGCOL, ctx->fogcolor,
+ MGA_WFLAG, ctx->wflag, MGA_ZORG, dev_priv->depth_offset);
- DMA_BLOCK( MGA_WFLAG1, ctx->wflag,
- MGA_TDUALSTAGE0, ctx->tdualstage0,
- MGA_TDUALSTAGE1, ctx->tdualstage1,
- MGA_FCOL, ctx->fcol );
+ DMA_BLOCK(MGA_WFLAG1, ctx->wflag,
+ MGA_TDUALSTAGE0, ctx->tdualstage0,
+ MGA_TDUALSTAGE1, ctx->tdualstage1, MGA_FCOL, ctx->fcol);
- DMA_BLOCK( MGA_STENCIL, ctx->stencil,
- MGA_STENCILCTL, ctx->stencilctl,
- MGA_DMAPAD, 0x00000000,
- MGA_DMAPAD, 0x00000000 );
+ DMA_BLOCK(MGA_STENCIL, ctx->stencil,
+ MGA_STENCILCTL, ctx->stencilctl,
+ MGA_DMAPAD, 0x00000000, MGA_DMAPAD, 0x00000000);
ADVANCE_DMA();
}
-static __inline__ void mga_g200_emit_tex0( drm_mga_private_t *dev_priv )
+static __inline__ void mga_g200_emit_tex0(drm_mga_private_t * dev_priv)
{
drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
drm_mga_texture_regs_t *tex = &sarea_priv->tex_state[0];
DMA_LOCALS;
- BEGIN_DMA( 4 );
+ BEGIN_DMA(4);
- DMA_BLOCK( MGA_TEXCTL2, tex->texctl2,
- MGA_TEXCTL, tex->texctl,
- MGA_TEXFILTER, tex->texfilter,
- MGA_TEXBORDERCOL, tex->texbordercol );
+ DMA_BLOCK(MGA_TEXCTL2, tex->texctl2,
+ MGA_TEXCTL, tex->texctl,
+ MGA_TEXFILTER, tex->texfilter,
+ MGA_TEXBORDERCOL, tex->texbordercol);
- DMA_BLOCK( MGA_TEXORG, tex->texorg,
- MGA_TEXORG1, tex->texorg1,
- MGA_TEXORG2, tex->texorg2,
- MGA_TEXORG3, tex->texorg3 );
+ DMA_BLOCK(MGA_TEXORG, tex->texorg,
+ MGA_TEXORG1, tex->texorg1,
+ MGA_TEXORG2, tex->texorg2, MGA_TEXORG3, tex->texorg3);
- DMA_BLOCK( MGA_TEXORG4, tex->texorg4,
- MGA_TEXWIDTH, tex->texwidth,
- MGA_TEXHEIGHT, tex->texheight,
- MGA_WR24, tex->texwidth );
+ DMA_BLOCK(MGA_TEXORG4, tex->texorg4,
+ MGA_TEXWIDTH, tex->texwidth,
+ MGA_TEXHEIGHT, tex->texheight, MGA_WR24, tex->texwidth);
- DMA_BLOCK( MGA_WR34, tex->texheight,
- MGA_TEXTRANS, 0x0000ffff,
- MGA_TEXTRANSHIGH, 0x0000ffff,
- MGA_DMAPAD, 0x00000000 );
+ DMA_BLOCK(MGA_WR34, tex->texheight,
+ MGA_TEXTRANS, 0x0000ffff,
+ MGA_TEXTRANSHIGH, 0x0000ffff, MGA_DMAPAD, 0x00000000);
ADVANCE_DMA();
}
-static __inline__ void mga_g400_emit_tex0( drm_mga_private_t *dev_priv )
+static __inline__ void mga_g400_emit_tex0(drm_mga_private_t * dev_priv)
{
drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
drm_mga_texture_regs_t *tex = &sarea_priv->tex_state[0];
@@ -164,42 +153,38 @@ static __inline__ void mga_g400_emit_tex0( drm_mga_private_t *dev_priv )
/* printk("mga_g400_emit_tex0 %x %x %x\n", tex->texorg, */
/* tex->texctl, tex->texctl2); */
- BEGIN_DMA( 6 );
+ BEGIN_DMA(6);
- DMA_BLOCK( MGA_TEXCTL2, tex->texctl2 | MGA_G400_TC2_MAGIC,
- MGA_TEXCTL, tex->texctl,
- MGA_TEXFILTER, tex->texfilter,
- MGA_TEXBORDERCOL, tex->texbordercol );
+ DMA_BLOCK(MGA_TEXCTL2, tex->texctl2 | MGA_G400_TC2_MAGIC,
+ MGA_TEXCTL, tex->texctl,
+ MGA_TEXFILTER, tex->texfilter,
+ MGA_TEXBORDERCOL, tex->texbordercol);
- DMA_BLOCK( MGA_TEXORG, tex->texorg,
- MGA_TEXORG1, tex->texorg1,
- MGA_TEXORG2, tex->texorg2,
- MGA_TEXORG3, tex->texorg3 );
+ DMA_BLOCK(MGA_TEXORG, tex->texorg,
+ MGA_TEXORG1, tex->texorg1,
+ MGA_TEXORG2, tex->texorg2, MGA_TEXORG3, tex->texorg3);
- DMA_BLOCK( MGA_TEXORG4, tex->texorg4,
- MGA_TEXWIDTH, tex->texwidth,
- MGA_TEXHEIGHT, tex->texheight,
- MGA_WR49, 0x00000000 );
+ DMA_BLOCK(MGA_TEXORG4, tex->texorg4,
+ MGA_TEXWIDTH, tex->texwidth,
+ MGA_TEXHEIGHT, tex->texheight, MGA_WR49, 0x00000000);
- DMA_BLOCK( MGA_WR57, 0x00000000,
- MGA_WR53, 0x00000000,
- MGA_WR61, 0x00000000,
- MGA_WR52, MGA_G400_WR_MAGIC );
+ DMA_BLOCK(MGA_WR57, 0x00000000,
+ MGA_WR53, 0x00000000,
+ MGA_WR61, 0x00000000, MGA_WR52, MGA_G400_WR_MAGIC);
- DMA_BLOCK( MGA_WR60, MGA_G400_WR_MAGIC,
- MGA_WR54, tex->texwidth | MGA_G400_WR_MAGIC,
- MGA_WR62, tex->texheight | MGA_G400_WR_MAGIC,
- MGA_DMAPAD, 0x00000000 );
+ DMA_BLOCK(MGA_WR60, MGA_G400_WR_MAGIC,
+ MGA_WR54, tex->texwidth | MGA_G400_WR_MAGIC,
+ MGA_WR62, tex->texheight | MGA_G400_WR_MAGIC,
+ MGA_DMAPAD, 0x00000000);
- DMA_BLOCK( MGA_DMAPAD, 0x00000000,
- MGA_DMAPAD, 0x00000000,
- MGA_TEXTRANS, 0x0000ffff,
- MGA_TEXTRANSHIGH, 0x0000ffff );
+ DMA_BLOCK(MGA_DMAPAD, 0x00000000,
+ MGA_DMAPAD, 0x00000000,
+ MGA_TEXTRANS, 0x0000ffff, MGA_TEXTRANSHIGH, 0x0000ffff);
ADVANCE_DMA();
}
-static __inline__ void mga_g400_emit_tex1( drm_mga_private_t *dev_priv )
+static __inline__ void mga_g400_emit_tex1(drm_mga_private_t * dev_priv)
{
drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
drm_mga_texture_regs_t *tex = &sarea_priv->tex_state[1];
@@ -208,55 +193,51 @@ static __inline__ void mga_g400_emit_tex1( drm_mga_private_t *dev_priv )
/* printk("mga_g400_emit_tex1 %x %x %x\n", tex->texorg, */
/* tex->texctl, tex->texctl2); */
- BEGIN_DMA( 5 );
+ BEGIN_DMA(5);
- DMA_BLOCK( MGA_TEXCTL2, (tex->texctl2 |
- MGA_MAP1_ENABLE |
- MGA_G400_TC2_MAGIC),
- MGA_TEXCTL, tex->texctl,
- MGA_TEXFILTER, tex->texfilter,
- MGA_TEXBORDERCOL, tex->texbordercol );
+ DMA_BLOCK(MGA_TEXCTL2, (tex->texctl2 |
+ MGA_MAP1_ENABLE |
+ MGA_G400_TC2_MAGIC),
+ MGA_TEXCTL, tex->texctl,
+ MGA_TEXFILTER, tex->texfilter,
+ MGA_TEXBORDERCOL, tex->texbordercol);
- DMA_BLOCK( MGA_TEXORG, tex->texorg,
- MGA_TEXORG1, tex->texorg1,
- MGA_TEXORG2, tex->texorg2,
- MGA_TEXORG3, tex->texorg3 );
+ DMA_BLOCK(MGA_TEXORG, tex->texorg,
+ MGA_TEXORG1, tex->texorg1,
+ MGA_TEXORG2, tex->texorg2, MGA_TEXORG3, tex->texorg3);
- DMA_BLOCK( MGA_TEXORG4, tex->texorg4,
- MGA_TEXWIDTH, tex->texwidth,
- MGA_TEXHEIGHT, tex->texheight,
- MGA_WR49, 0x00000000 );
+ DMA_BLOCK(MGA_TEXORG4, tex->texorg4,
+ MGA_TEXWIDTH, tex->texwidth,
+ MGA_TEXHEIGHT, tex->texheight, MGA_WR49, 0x00000000);
- DMA_BLOCK( MGA_WR57, 0x00000000,
- MGA_WR53, 0x00000000,
- MGA_WR61, 0x00000000,
- MGA_WR52, tex->texwidth | MGA_G400_WR_MAGIC );
+ DMA_BLOCK(MGA_WR57, 0x00000000,
+ MGA_WR53, 0x00000000,
+ MGA_WR61, 0x00000000,
+ MGA_WR52, tex->texwidth | MGA_G400_WR_MAGIC);
- DMA_BLOCK( MGA_WR60, tex->texheight | MGA_G400_WR_MAGIC,
- MGA_TEXTRANS, 0x0000ffff,
- MGA_TEXTRANSHIGH, 0x0000ffff,
- MGA_TEXCTL2, tex->texctl2 | MGA_G400_TC2_MAGIC );
+ DMA_BLOCK(MGA_WR60, tex->texheight | MGA_G400_WR_MAGIC,
+ MGA_TEXTRANS, 0x0000ffff,
+ MGA_TEXTRANSHIGH, 0x0000ffff,
+ MGA_TEXCTL2, tex->texctl2 | MGA_G400_TC2_MAGIC);
ADVANCE_DMA();
}
-static __inline__ void mga_g200_emit_pipe( drm_mga_private_t *dev_priv )
+static __inline__ void mga_g200_emit_pipe(drm_mga_private_t * dev_priv)
{
drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
unsigned int pipe = sarea_priv->warp_pipe;
DMA_LOCALS;
- BEGIN_DMA( 3 );
+ BEGIN_DMA(3);
- DMA_BLOCK( MGA_WIADDR, MGA_WMODE_SUSPEND,
- MGA_WVRTXSZ, 0x00000007,
- MGA_WFLAG, 0x00000000,
- MGA_WR24, 0x00000000 );
+ DMA_BLOCK(MGA_WIADDR, MGA_WMODE_SUSPEND,
+ MGA_WVRTXSZ, 0x00000007,
+ MGA_WFLAG, 0x00000000, MGA_WR24, 0x00000000);
- DMA_BLOCK( MGA_WR25, 0x00000100,
- MGA_WR34, 0x00000000,
- MGA_WR42, 0x0000ffff,
- MGA_WR60, 0x0000ffff );
+ DMA_BLOCK(MGA_WR25, 0x00000100,
+ MGA_WR34, 0x00000000,
+ MGA_WR42, 0x0000ffff, MGA_WR60, 0x0000ffff);
/* Padding required to to hardware bug.
*/
@@ -269,7 +250,7 @@ static __inline__ void mga_g200_emit_pipe( drm_mga_private_t *dev_priv )
ADVANCE_DMA();
}
-static __inline__ void mga_g400_emit_pipe( drm_mga_private_t *dev_priv )
+static __inline__ void mga_g400_emit_pipe(drm_mga_private_t * dev_priv)
{
drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
unsigned int pipe = sarea_priv->warp_pipe;
@@ -277,68 +258,64 @@ static __inline__ void mga_g400_emit_pipe( drm_mga_private_t *dev_priv )
/* printk("mga_g400_emit_pipe %x\n", pipe); */
- BEGIN_DMA( 10 );
+ BEGIN_DMA(10);
- DMA_BLOCK( MGA_WIADDR2, MGA_WMODE_SUSPEND,
- MGA_DMAPAD, 0x00000000,
- MGA_DMAPAD, 0x00000000,
- MGA_DMAPAD, 0x00000000 );
+ DMA_BLOCK(MGA_WIADDR2, MGA_WMODE_SUSPEND,
+ MGA_DMAPAD, 0x00000000,
+ MGA_DMAPAD, 0x00000000, MGA_DMAPAD, 0x00000000);
- if ( pipe & MGA_T2 ) {
- DMA_BLOCK( MGA_WVRTXSZ, 0x00001e09,
- MGA_DMAPAD, 0x00000000,
- MGA_DMAPAD, 0x00000000,
- MGA_DMAPAD, 0x00000000 );
+ if (pipe & MGA_T2) {
+ DMA_BLOCK(MGA_WVRTXSZ, 0x00001e09,
+ MGA_DMAPAD, 0x00000000,
+ MGA_DMAPAD, 0x00000000, MGA_DMAPAD, 0x00000000);
- DMA_BLOCK( MGA_WACCEPTSEQ, 0x00000000,
- MGA_WACCEPTSEQ, 0x00000000,
- MGA_WACCEPTSEQ, 0x00000000,
- MGA_WACCEPTSEQ, 0x1e000000 );
+ DMA_BLOCK(MGA_WACCEPTSEQ, 0x00000000,
+ MGA_WACCEPTSEQ, 0x00000000,
+ MGA_WACCEPTSEQ, 0x00000000,
+ MGA_WACCEPTSEQ, 0x1e000000);
} else {
- if ( dev_priv->warp_pipe & MGA_T2 ) {
+ if (dev_priv->warp_pipe & MGA_T2) {
/* Flush the WARP pipe */
- DMA_BLOCK( MGA_YDST, 0x00000000,
- MGA_FXLEFT, 0x00000000,
- MGA_FXRIGHT, 0x00000001,
- MGA_DWGCTL, MGA_DWGCTL_FLUSH );
-
- DMA_BLOCK( MGA_LEN + MGA_EXEC, 0x00000001,
- MGA_DWGSYNC, 0x00007000,
- MGA_TEXCTL2, MGA_G400_TC2_MAGIC,
- MGA_LEN + MGA_EXEC, 0x00000000 );
-
- DMA_BLOCK( MGA_TEXCTL2, (MGA_DUALTEX |
- MGA_G400_TC2_MAGIC),
- MGA_LEN + MGA_EXEC, 0x00000000,
- MGA_TEXCTL2, MGA_G400_TC2_MAGIC,
- MGA_DMAPAD, 0x00000000 );
+ DMA_BLOCK(MGA_YDST, 0x00000000,
+ MGA_FXLEFT, 0x00000000,
+ MGA_FXRIGHT, 0x00000001,
+ MGA_DWGCTL, MGA_DWGCTL_FLUSH);
+
+ DMA_BLOCK(MGA_LEN + MGA_EXEC, 0x00000001,
+ MGA_DWGSYNC, 0x00007000,
+ MGA_TEXCTL2, MGA_G400_TC2_MAGIC,
+ MGA_LEN + MGA_EXEC, 0x00000000);
+
+ DMA_BLOCK(MGA_TEXCTL2, (MGA_DUALTEX |
+ MGA_G400_TC2_MAGIC),
+ MGA_LEN + MGA_EXEC, 0x00000000,
+ MGA_TEXCTL2, MGA_G400_TC2_MAGIC,
+ MGA_DMAPAD, 0x00000000);
}
- DMA_BLOCK( MGA_WVRTXSZ, 0x00001807,
- MGA_DMAPAD, 0x00000000,
- MGA_DMAPAD, 0x00000000,
- MGA_DMAPAD, 0x00000000 );
+ DMA_BLOCK(MGA_WVRTXSZ, 0x00001807,
+ MGA_DMAPAD, 0x00000000,
+ MGA_DMAPAD, 0x00000000, MGA_DMAPAD, 0x00000000);
- DMA_BLOCK( MGA_WACCEPTSEQ, 0x00000000,
- MGA_WACCEPTSEQ, 0x00000000,
- MGA_WACCEPTSEQ, 0x00000000,
- MGA_WACCEPTSEQ, 0x18000000 );
+ DMA_BLOCK(MGA_WACCEPTSEQ, 0x00000000,
+ MGA_WACCEPTSEQ, 0x00000000,
+ MGA_WACCEPTSEQ, 0x00000000,
+ MGA_WACCEPTSEQ, 0x18000000);
}
- DMA_BLOCK( MGA_WFLAG, 0x00000000,
- MGA_WFLAG1, 0x00000000,
- MGA_WR56, MGA_G400_WR56_MAGIC,
- MGA_DMAPAD, 0x00000000 );
+ DMA_BLOCK(MGA_WFLAG, 0x00000000,
+ MGA_WFLAG1, 0x00000000,
+ MGA_WR56, MGA_G400_WR56_MAGIC, MGA_DMAPAD, 0x00000000);
- DMA_BLOCK( MGA_WR49, 0x00000000, /* tex0 */
- MGA_WR57, 0x00000000, /* tex0 */
- MGA_WR53, 0x00000000, /* tex1 */
- MGA_WR61, 0x00000000 ); /* tex1 */
+ DMA_BLOCK(MGA_WR49, 0x00000000, /* tex0 */
+ MGA_WR57, 0x00000000, /* tex0 */
+ MGA_WR53, 0x00000000, /* tex1 */
+ MGA_WR61, 0x00000000); /* tex1 */
- DMA_BLOCK( MGA_WR54, MGA_G400_WR_MAGIC, /* tex0 width */
- MGA_WR62, MGA_G400_WR_MAGIC, /* tex0 height */
- MGA_WR52, MGA_G400_WR_MAGIC, /* tex1 width */
- MGA_WR60, MGA_G400_WR_MAGIC ); /* tex1 height */
+ DMA_BLOCK(MGA_WR54, MGA_G400_WR_MAGIC, /* tex0 width */
+ MGA_WR62, MGA_G400_WR_MAGIC, /* tex0 height */
+ MGA_WR52, MGA_G400_WR_MAGIC, /* tex1 width */
+ MGA_WR60, MGA_G400_WR_MAGIC); /* tex1 height */
/* Padding required to to hardware bug */
DMA_BLOCK(MGA_DMAPAD, 0xffffffff,
@@ -350,71 +327,70 @@ static __inline__ void mga_g400_emit_pipe( drm_mga_private_t *dev_priv )
ADVANCE_DMA();
}
-static void mga_g200_emit_state( drm_mga_private_t *dev_priv )
+static void mga_g200_emit_state(drm_mga_private_t * dev_priv)
{
drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
unsigned int dirty = sarea_priv->dirty;
- if ( sarea_priv->warp_pipe != dev_priv->warp_pipe ) {
- mga_g200_emit_pipe( dev_priv );
+ if (sarea_priv->warp_pipe != dev_priv->warp_pipe) {
+ mga_g200_emit_pipe(dev_priv);
dev_priv->warp_pipe = sarea_priv->warp_pipe;
}
- if ( dirty & MGA_UPLOAD_CONTEXT ) {
- mga_g200_emit_context( dev_priv );
+ if (dirty & MGA_UPLOAD_CONTEXT) {
+ mga_g200_emit_context(dev_priv);
sarea_priv->dirty &= ~MGA_UPLOAD_CONTEXT;
}
- if ( dirty & MGA_UPLOAD_TEX0 ) {
- mga_g200_emit_tex0( dev_priv );
+ if (dirty & MGA_UPLOAD_TEX0) {
+ mga_g200_emit_tex0(dev_priv);
sarea_priv->dirty &= ~MGA_UPLOAD_TEX0;
}
}
-static void mga_g400_emit_state( drm_mga_private_t *dev_priv )
+static void mga_g400_emit_state(drm_mga_private_t * dev_priv)
{
drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
unsigned int dirty = sarea_priv->dirty;
int multitex = sarea_priv->warp_pipe & MGA_T2;
- if ( sarea_priv->warp_pipe != dev_priv->warp_pipe ) {
- mga_g400_emit_pipe( dev_priv );
+ if (sarea_priv->warp_pipe != dev_priv->warp_pipe) {
+ mga_g400_emit_pipe(dev_priv);
dev_priv->warp_pipe = sarea_priv->warp_pipe;
}
- if ( dirty & MGA_UPLOAD_CONTEXT ) {
- mga_g400_emit_context( dev_priv );
+ if (dirty & MGA_UPLOAD_CONTEXT) {
+ mga_g400_emit_context(dev_priv);
sarea_priv->dirty &= ~MGA_UPLOAD_CONTEXT;
}
- if ( dirty & MGA_UPLOAD_TEX0 ) {
- mga_g400_emit_tex0( dev_priv );
+ if (dirty & MGA_UPLOAD_TEX0) {
+ mga_g400_emit_tex0(dev_priv);
sarea_priv->dirty &= ~MGA_UPLOAD_TEX0;
}
- if ( (dirty & MGA_UPLOAD_TEX1) && multitex ) {
- mga_g400_emit_tex1( dev_priv );
+ if ((dirty & MGA_UPLOAD_TEX1) && multitex) {
+ mga_g400_emit_tex1(dev_priv);
sarea_priv->dirty &= ~MGA_UPLOAD_TEX1;
}
}
-
/* ================================================================
* SAREA state verification
*/
/* Disallow all write destinations except the front and backbuffer.
*/
-static int mga_verify_context( drm_mga_private_t *dev_priv )
+static int mga_verify_context(drm_mga_private_t * dev_priv)
{
drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
drm_mga_context_regs_t *ctx = &sarea_priv->context_state;
- if ( ctx->dstorg != dev_priv->front_offset &&
- ctx->dstorg != dev_priv->back_offset ) {
- DRM_ERROR( "*** bad DSTORG: %x (front %x, back %x)\n\n",
- ctx->dstorg, dev_priv->front_offset,
- dev_priv->back_offset );
+ if (ctx->dstorg != dev_priv->front_offset &&
+ ctx->dstorg != dev_priv->back_offset) {
+ DRM_ERROR("*** bad DSTORG: %x (front %x, back %x)\n\n",
+ ctx->dstorg, dev_priv->front_offset,
+ dev_priv->back_offset);
ctx->dstorg = 0;
return DRM_ERR(EINVAL);
}
@@ -424,7 +400,7 @@ static int mga_verify_context( drm_mga_private_t *dev_priv )
/* Disallow texture reads from PCI space.
*/
-static int mga_verify_tex( drm_mga_private_t *dev_priv, int unit )
+static int mga_verify_tex(drm_mga_private_t * dev_priv, int unit)
{
drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
drm_mga_texture_regs_t *tex = &sarea_priv->tex_state[unit];
@@ -432,9 +408,8 @@ static int mga_verify_tex( drm_mga_private_t *dev_priv, int unit )
org = tex->texorg & (MGA_TEXORGMAP_MASK | MGA_TEXORGACC_MASK);
- if ( org == (MGA_TEXORGMAP_SYSMEM | MGA_TEXORGACC_PCI) ) {
- DRM_ERROR( "*** bad TEXORG: 0x%x, unit %d\n",
- tex->texorg, unit );
+ if (org == (MGA_TEXORGMAP_SYSMEM | MGA_TEXORGACC_PCI)) {
+ DRM_ERROR("*** bad TEXORG: 0x%x, unit %d\n", tex->texorg, unit);
tex->texorg = 0;
return DRM_ERR(EINVAL);
}
@@ -442,73 +417,70 @@ static int mga_verify_tex( drm_mga_private_t *dev_priv, int unit )
return 0;
}
-static int mga_verify_state( drm_mga_private_t *dev_priv )
+static int mga_verify_state(drm_mga_private_t * dev_priv)
{
drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
unsigned int dirty = sarea_priv->dirty;
int ret = 0;
- if ( sarea_priv->nbox > MGA_NR_SAREA_CLIPRECTS )
+ if (sarea_priv->nbox > MGA_NR_SAREA_CLIPRECTS)
sarea_priv->nbox = MGA_NR_SAREA_CLIPRECTS;
- if ( dirty & MGA_UPLOAD_CONTEXT )
- ret |= mga_verify_context( dev_priv );
+ if (dirty & MGA_UPLOAD_CONTEXT)
+ ret |= mga_verify_context(dev_priv);
- if ( dirty & MGA_UPLOAD_TEX0 )
- ret |= mga_verify_tex( dev_priv, 0 );
+ if (dirty & MGA_UPLOAD_TEX0)
+ ret |= mga_verify_tex(dev_priv, 0);
if (dev_priv->chipset >= MGA_CARD_TYPE_G400) {
if (dirty & MGA_UPLOAD_TEX1)
ret |= mga_verify_tex(dev_priv, 1);
- if ( dirty & MGA_UPLOAD_PIPE )
- ret |= ( sarea_priv->warp_pipe > MGA_MAX_G400_PIPES );
+ if (dirty & MGA_UPLOAD_PIPE)
+ ret |= (sarea_priv->warp_pipe > MGA_MAX_G400_PIPES);
} else {
- if ( dirty & MGA_UPLOAD_PIPE )
- ret |= ( sarea_priv->warp_pipe > MGA_MAX_G200_PIPES );
+ if (dirty & MGA_UPLOAD_PIPE)
+ ret |= (sarea_priv->warp_pipe > MGA_MAX_G200_PIPES);
}
- return ( ret == 0 );
+ return (ret == 0);
}
-static int mga_verify_iload( drm_mga_private_t *dev_priv,
- unsigned int dstorg, unsigned int length )
+static int mga_verify_iload(drm_mga_private_t * dev_priv,
+ unsigned int dstorg, unsigned int length)
{
- if ( dstorg < dev_priv->texture_offset ||
- dstorg + length > (dev_priv->texture_offset +
- dev_priv->texture_size) ) {
- DRM_ERROR( "*** bad iload DSTORG: 0x%x\n", dstorg );
+ if (dstorg < dev_priv->texture_offset ||
+ dstorg + length > (dev_priv->texture_offset +
+ dev_priv->texture_size)) {
+ DRM_ERROR("*** bad iload DSTORG: 0x%x\n", dstorg);
return DRM_ERR(EINVAL);
}
- if ( length & MGA_ILOAD_MASK ) {
- DRM_ERROR( "*** bad iload length: 0x%x\n",
- length & MGA_ILOAD_MASK );
+ if (length & MGA_ILOAD_MASK) {
+ DRM_ERROR("*** bad iload length: 0x%x\n",
+ length & MGA_ILOAD_MASK);
return DRM_ERR(EINVAL);
}
return 0;
}
-static int mga_verify_blit( drm_mga_private_t *dev_priv,
- unsigned int srcorg, unsigned int dstorg )
+static int mga_verify_blit(drm_mga_private_t * dev_priv,
+ unsigned int srcorg, unsigned int dstorg)
{
- if ( (srcorg & 0x3) == (MGA_SRCACC_PCI | MGA_SRCMAP_SYSMEM) ||
- (dstorg & 0x3) == (MGA_SRCACC_PCI | MGA_SRCMAP_SYSMEM) ) {
- DRM_ERROR( "*** bad blit: src=0x%x dst=0x%x\n",
- srcorg, dstorg );
+ if ((srcorg & 0x3) == (MGA_SRCACC_PCI | MGA_SRCMAP_SYSMEM) ||
+ (dstorg & 0x3) == (MGA_SRCACC_PCI | MGA_SRCMAP_SYSMEM)) {
+ DRM_ERROR("*** bad blit: src=0x%x dst=0x%x\n", srcorg, dstorg);
return DRM_ERR(EINVAL);
}
return 0;
}
-
/* ================================================================
*
*/
-static void mga_dma_dispatch_clear( drm_device_t *dev,
- drm_mga_clear_t *clear )
+static void mga_dma_dispatch_clear(drm_device_t * dev, drm_mga_clear_t * clear)
{
drm_mga_private_t *dev_priv = dev->dev_private;
drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
@@ -517,92 +489,86 @@ static void mga_dma_dispatch_clear( drm_device_t *dev,
int nbox = sarea_priv->nbox;
int i;
DMA_LOCALS;
- DRM_DEBUG( "\n" );
+ DRM_DEBUG("\n");
- BEGIN_DMA( 1 );
+ BEGIN_DMA(1);
- DMA_BLOCK( MGA_DMAPAD, 0x00000000,
- MGA_DMAPAD, 0x00000000,
- MGA_DWGSYNC, 0x00007100,
- MGA_DWGSYNC, 0x00007000 );
+ DMA_BLOCK(MGA_DMAPAD, 0x00000000,
+ MGA_DMAPAD, 0x00000000,
+ MGA_DWGSYNC, 0x00007100, MGA_DWGSYNC, 0x00007000);
ADVANCE_DMA();
- for ( i = 0 ; i < nbox ; i++ ) {
+ for (i = 0; i < nbox; i++) {
drm_clip_rect_t *box = &pbox[i];
u32 height = box->y2 - box->y1;
- DRM_DEBUG( " from=%d,%d to=%d,%d\n",
- box->x1, box->y1, box->x2, box->y2 );
+ DRM_DEBUG(" from=%d,%d to=%d,%d\n",
+ box->x1, box->y1, box->x2, box->y2);
- if ( clear->flags & MGA_FRONT ) {
- BEGIN_DMA( 2 );
+ if (clear->flags & MGA_FRONT) {
+ BEGIN_DMA(2);
- DMA_BLOCK( MGA_DMAPAD, 0x00000000,
- MGA_PLNWT, clear->color_mask,
- MGA_YDSTLEN, (box->y1 << 16) | height,
- MGA_FXBNDRY, (box->x2 << 16) | box->x1 );
+ DMA_BLOCK(MGA_DMAPAD, 0x00000000,
+ MGA_PLNWT, clear->color_mask,
+ MGA_YDSTLEN, (box->y1 << 16) | height,
+ MGA_FXBNDRY, (box->x2 << 16) | box->x1);
- DMA_BLOCK( MGA_DMAPAD, 0x00000000,
- MGA_FCOL, clear->clear_color,
- MGA_DSTORG, dev_priv->front_offset,
- MGA_DWGCTL + MGA_EXEC,
- dev_priv->clear_cmd );
+ DMA_BLOCK(MGA_DMAPAD, 0x00000000,
+ MGA_FCOL, clear->clear_color,
+ MGA_DSTORG, dev_priv->front_offset,
+ MGA_DWGCTL + MGA_EXEC, dev_priv->clear_cmd);
ADVANCE_DMA();
}
+ if (clear->flags & MGA_BACK) {
+ BEGIN_DMA(2);
- if ( clear->flags & MGA_BACK ) {
- BEGIN_DMA( 2 );
-
- DMA_BLOCK( MGA_DMAPAD, 0x00000000,
- MGA_PLNWT, clear->color_mask,
- MGA_YDSTLEN, (box->y1 << 16) | height,
- MGA_FXBNDRY, (box->x2 << 16) | box->x1 );
+ DMA_BLOCK(MGA_DMAPAD, 0x00000000,
+ MGA_PLNWT, clear->color_mask,
+ MGA_YDSTLEN, (box->y1 << 16) | height,
+ MGA_FXBNDRY, (box->x2 << 16) | box->x1);
- DMA_BLOCK( MGA_DMAPAD, 0x00000000,
- MGA_FCOL, clear->clear_color,
- MGA_DSTORG, dev_priv->back_offset,
- MGA_DWGCTL + MGA_EXEC,
- dev_priv->clear_cmd );
+ DMA_BLOCK(MGA_DMAPAD, 0x00000000,
+ MGA_FCOL, clear->clear_color,
+ MGA_DSTORG, dev_priv->back_offset,
+ MGA_DWGCTL + MGA_EXEC, dev_priv->clear_cmd);
ADVANCE_DMA();
}
- if ( clear->flags & MGA_DEPTH ) {
- BEGIN_DMA( 2 );
+ if (clear->flags & MGA_DEPTH) {
+ BEGIN_DMA(2);
- DMA_BLOCK( MGA_DMAPAD, 0x00000000,
- MGA_PLNWT, clear->depth_mask,
- MGA_YDSTLEN, (box->y1 << 16) | height,
- MGA_FXBNDRY, (box->x2 << 16) | box->x1 );
+ DMA_BLOCK(MGA_DMAPAD, 0x00000000,
+ MGA_PLNWT, clear->depth_mask,
+ MGA_YDSTLEN, (box->y1 << 16) | height,
+ MGA_FXBNDRY, (box->x2 << 16) | box->x1);
- DMA_BLOCK( MGA_DMAPAD, 0x00000000,
- MGA_FCOL, clear->clear_depth,
- MGA_DSTORG, dev_priv->depth_offset,
- MGA_DWGCTL + MGA_EXEC,
- dev_priv->clear_cmd );
+ DMA_BLOCK(MGA_DMAPAD, 0x00000000,
+ MGA_FCOL, clear->clear_depth,
+ MGA_DSTORG, dev_priv->depth_offset,
+ MGA_DWGCTL + MGA_EXEC, dev_priv->clear_cmd);
ADVANCE_DMA();
}
}
- BEGIN_DMA( 1 );
+ BEGIN_DMA(1);
/* Force reset of DWGCTL */
- DMA_BLOCK( MGA_DMAPAD, 0x00000000,
- MGA_DMAPAD, 0x00000000,
- MGA_PLNWT, ctx->plnwt,
- MGA_DWGCTL, ctx->dwgctl );
+ DMA_BLOCK(MGA_DMAPAD, 0x00000000,
+ MGA_DMAPAD, 0x00000000,
+ MGA_PLNWT, ctx->plnwt, MGA_DWGCTL, ctx->dwgctl);
ADVANCE_DMA();
FLUSH_DMA();
}
-static void mga_dma_dispatch_swap( drm_device_t *dev )
+static void mga_dma_dispatch_swap(drm_device_t * dev)
{
drm_mga_private_t *dev_priv = dev->dev_private;
drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
@@ -611,56 +577,52 @@ static void mga_dma_dispatch_swap( drm_device_t *dev )
int nbox = sarea_priv->nbox;
int i;
DMA_LOCALS;
- DRM_DEBUG( "\n" );
+ DRM_DEBUG("\n");
sarea_priv->last_frame.head = dev_priv->prim.tail;
sarea_priv->last_frame.wrap = dev_priv->prim.last_wrap;
- BEGIN_DMA( 4 + nbox );
+ BEGIN_DMA(4 + nbox);
- DMA_BLOCK( MGA_DMAPAD, 0x00000000,
- MGA_DMAPAD, 0x00000000,
- MGA_DWGSYNC, 0x00007100,
- MGA_DWGSYNC, 0x00007000 );
+ DMA_BLOCK(MGA_DMAPAD, 0x00000000,
+ MGA_DMAPAD, 0x00000000,
+ MGA_DWGSYNC, 0x00007100, MGA_DWGSYNC, 0x00007000);
- DMA_BLOCK( MGA_DSTORG, dev_priv->front_offset,
- MGA_MACCESS, dev_priv->maccess,
- MGA_SRCORG, dev_priv->back_offset,
- MGA_AR5, dev_priv->front_pitch );
+ DMA_BLOCK(MGA_DSTORG, dev_priv->front_offset,
+ MGA_MACCESS, dev_priv->maccess,
+ MGA_SRCORG, dev_priv->back_offset,
+ MGA_AR5, dev_priv->front_pitch);
- DMA_BLOCK( MGA_DMAPAD, 0x00000000,
- MGA_DMAPAD, 0x00000000,
- MGA_PLNWT, 0xffffffff,
- MGA_DWGCTL, MGA_DWGCTL_COPY );
+ DMA_BLOCK(MGA_DMAPAD, 0x00000000,
+ MGA_DMAPAD, 0x00000000,
+ MGA_PLNWT, 0xffffffff, MGA_DWGCTL, MGA_DWGCTL_COPY);
- for ( i = 0 ; i < nbox ; i++ ) {
+ for (i = 0; i < nbox; i++) {
drm_clip_rect_t *box = &pbox[i];
u32 height = box->y2 - box->y1;
u32 start = box->y1 * dev_priv->front_pitch;
- DRM_DEBUG( " from=%d,%d to=%d,%d\n",
- box->x1, box->y1, box->x2, box->y2 );
+ DRM_DEBUG(" from=%d,%d to=%d,%d\n",
+ box->x1, box->y1, box->x2, box->y2);
- DMA_BLOCK( MGA_AR0, start + box->x2 - 1,
- MGA_AR3, start + box->x1,
- MGA_FXBNDRY, ((box->x2 - 1) << 16) | box->x1,
- MGA_YDSTLEN + MGA_EXEC,
- (box->y1 << 16) | height );
+ DMA_BLOCK(MGA_AR0, start + box->x2 - 1,
+ MGA_AR3, start + box->x1,
+ MGA_FXBNDRY, ((box->x2 - 1) << 16) | box->x1,
+ MGA_YDSTLEN + MGA_EXEC, (box->y1 << 16) | height);
}
- DMA_BLOCK( MGA_DMAPAD, 0x00000000,
- MGA_PLNWT, ctx->plnwt,
- MGA_SRCORG, dev_priv->front_offset,
- MGA_DWGCTL, ctx->dwgctl );
+ DMA_BLOCK(MGA_DMAPAD, 0x00000000,
+ MGA_PLNWT, ctx->plnwt,
+ MGA_SRCORG, dev_priv->front_offset, MGA_DWGCTL, ctx->dwgctl);
ADVANCE_DMA();
FLUSH_DMA();
- DRM_DEBUG( "%s... done.\n", __FUNCTION__ );
+ DRM_DEBUG("%s... done.\n", __FUNCTION__);
}
-static void mga_dma_dispatch_vertex( drm_device_t *dev, drm_buf_t *buf )
+static void mga_dma_dispatch_vertex(drm_device_t * dev, drm_buf_t * buf)
{
drm_mga_private_t *dev_priv = dev->dev_private;
drm_mga_buf_priv_t *buf_priv = buf->dev_private;
@@ -669,20 +631,20 @@ static void mga_dma_dispatch_vertex( drm_device_t *dev, drm_buf_t *buf )
u32 length = (u32) buf->used;
int i = 0;
DMA_LOCALS;
- DRM_DEBUG( "vertex: buf=%d used=%d\n", buf->idx, buf->used );
+ DRM_DEBUG("vertex: buf=%d used=%d\n", buf->idx, buf->used);
- if ( buf->used ) {
+ if (buf->used) {
buf_priv->dispatched = 1;
- MGA_EMIT_STATE( dev_priv, sarea_priv->dirty );
+ MGA_EMIT_STATE(dev_priv, sarea_priv->dirty);
do {
- if ( i < sarea_priv->nbox ) {
- mga_emit_clip_rect( dev_priv,
- &sarea_priv->boxes[i] );
+ if (i < sarea_priv->nbox) {
+ mga_emit_clip_rect(dev_priv,
+ &sarea_priv->boxes[i]);
}
- BEGIN_DMA( 1 );
+ BEGIN_DMA(1);
DMA_BLOCK(MGA_DMAPAD, 0x00000000,
MGA_DMAPAD, 0x00000000,
@@ -692,23 +654,23 @@ static void mga_dma_dispatch_vertex( drm_device_t *dev, drm_buf_t *buf )
dev_priv->dma_access));
ADVANCE_DMA();
- } while ( ++i < sarea_priv->nbox );
+ } while (++i < sarea_priv->nbox);
}
- if ( buf_priv->discard ) {
- AGE_BUFFER( buf_priv );
+ if (buf_priv->discard) {
+ AGE_BUFFER(buf_priv);
buf->pending = 0;
buf->used = 0;
buf_priv->dispatched = 0;
- mga_freelist_put( dev, buf );
+ mga_freelist_put(dev, buf);
}
FLUSH_DMA();
}
-static void mga_dma_dispatch_indices( drm_device_t *dev, drm_buf_t *buf,
- unsigned int start, unsigned int end )
+static void mga_dma_dispatch_indices(drm_device_t * dev, drm_buf_t * buf,
+ unsigned int start, unsigned int end)
{
drm_mga_private_t *dev_priv = dev->dev_private;
drm_mga_buf_priv_t *buf_priv = buf->dev_private;
@@ -716,20 +678,20 @@ static void mga_dma_dispatch_indices( drm_device_t *dev, drm_buf_t *buf,
u32 address = (u32) buf->bus_address;
int i = 0;
DMA_LOCALS;
- DRM_DEBUG( "indices: buf=%d start=%d end=%d\n", buf->idx, start, end );
+ DRM_DEBUG("indices: buf=%d start=%d end=%d\n", buf->idx, start, end);
- if ( start != end ) {
+ if (start != end) {
buf_priv->dispatched = 1;
- MGA_EMIT_STATE( dev_priv, sarea_priv->dirty );
+ MGA_EMIT_STATE(dev_priv, sarea_priv->dirty);
do {
- if ( i < sarea_priv->nbox ) {
- mga_emit_clip_rect( dev_priv,
- &sarea_priv->boxes[i] );
+ if (i < sarea_priv->nbox) {
+ mga_emit_clip_rect(dev_priv,
+ &sarea_priv->boxes[i]);
}
- BEGIN_DMA( 1 );
+ BEGIN_DMA(1);
DMA_BLOCK(MGA_DMAPAD, 0x00000000,
MGA_DMAPAD, 0x00000000,
@@ -738,16 +700,16 @@ static void mga_dma_dispatch_indices( drm_device_t *dev, drm_buf_t *buf,
dev_priv->dma_access));
ADVANCE_DMA();
- } while ( ++i < sarea_priv->nbox );
+ } while (++i < sarea_priv->nbox);
}
- if ( buf_priv->discard ) {
- AGE_BUFFER( buf_priv );
+ if (buf_priv->discard) {
+ AGE_BUFFER(buf_priv);
buf->pending = 0;
buf->used = 0;
buf_priv->dispatched = 0;
- mga_freelist_put( dev, buf );
+ mga_freelist_put(dev, buf);
}
FLUSH_DMA();
@@ -756,61 +718,55 @@ static void mga_dma_dispatch_indices( drm_device_t *dev, drm_buf_t *buf,
/* This copies a 64 byte aligned agp region to the frambuffer with a
* standard blit, the ioctl needs to do checking.
*/
-static void mga_dma_dispatch_iload( drm_device_t *dev, drm_buf_t *buf,
- unsigned int dstorg, unsigned int length )
+static void mga_dma_dispatch_iload(drm_device_t * dev, drm_buf_t * buf,
+ unsigned int dstorg, unsigned int length)
{
drm_mga_private_t *dev_priv = dev->dev_private;
drm_mga_buf_priv_t *buf_priv = buf->dev_private;
drm_mga_context_regs_t *ctx = &dev_priv->sarea_priv->context_state;
- u32 srcorg = buf->bus_address | dev_priv->dma_access | MGA_SRCMAP_SYSMEM;
+ u32 srcorg =
+ buf->bus_address | dev_priv->dma_access | MGA_SRCMAP_SYSMEM;
u32 y2;
DMA_LOCALS;
- DRM_DEBUG( "buf=%d used=%d\n", buf->idx, buf->used );
+ DRM_DEBUG("buf=%d used=%d\n", buf->idx, buf->used);
y2 = length / 64;
- BEGIN_DMA( 5 );
+ BEGIN_DMA(5);
- DMA_BLOCK( MGA_DMAPAD, 0x00000000,
- MGA_DMAPAD, 0x00000000,
- MGA_DWGSYNC, 0x00007100,
- MGA_DWGSYNC, 0x00007000 );
+ DMA_BLOCK(MGA_DMAPAD, 0x00000000,
+ MGA_DMAPAD, 0x00000000,
+ MGA_DWGSYNC, 0x00007100, MGA_DWGSYNC, 0x00007000);
- DMA_BLOCK( MGA_DSTORG, dstorg,
- MGA_MACCESS, 0x00000000,
- MGA_SRCORG, srcorg,
- MGA_AR5, 64 );
+ DMA_BLOCK(MGA_DSTORG, dstorg,
+ MGA_MACCESS, 0x00000000, MGA_SRCORG, srcorg, MGA_AR5, 64);
- DMA_BLOCK( MGA_PITCH, 64,
- MGA_PLNWT, 0xffffffff,
- MGA_DMAPAD, 0x00000000,
- MGA_DWGCTL, MGA_DWGCTL_COPY );
+ DMA_BLOCK(MGA_PITCH, 64,
+ MGA_PLNWT, 0xffffffff,
+ MGA_DMAPAD, 0x00000000, MGA_DWGCTL, MGA_DWGCTL_COPY);
- DMA_BLOCK( MGA_AR0, 63,
- MGA_AR3, 0,
- MGA_FXBNDRY, (63 << 16) | 0,
- MGA_YDSTLEN + MGA_EXEC, y2 );
+ DMA_BLOCK(MGA_AR0, 63,
+ MGA_AR3, 0,
+ MGA_FXBNDRY, (63 << 16) | 0, MGA_YDSTLEN + MGA_EXEC, y2);
- DMA_BLOCK( MGA_PLNWT, ctx->plnwt,
- MGA_SRCORG, dev_priv->front_offset,
- MGA_PITCH, dev_priv->front_pitch,
- MGA_DWGSYNC, 0x00007000 );
+ DMA_BLOCK(MGA_PLNWT, ctx->plnwt,
+ MGA_SRCORG, dev_priv->front_offset,
+ MGA_PITCH, dev_priv->front_pitch, MGA_DWGSYNC, 0x00007000);
ADVANCE_DMA();
- AGE_BUFFER( buf_priv );
+ AGE_BUFFER(buf_priv);
buf->pending = 0;
buf->used = 0;
buf_priv->dispatched = 0;
- mga_freelist_put( dev, buf );
+ mga_freelist_put(dev, buf);
FLUSH_DMA();
}
-static void mga_dma_dispatch_blit( drm_device_t *dev,
- drm_mga_blit_t *blit )
+static void mga_dma_dispatch_blit(drm_device_t * dev, drm_mga_blit_t * blit)
{
drm_mga_private_t *dev_priv = dev->dev_private;
drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
@@ -819,26 +775,24 @@ static void mga_dma_dispatch_blit( drm_device_t *dev,
int nbox = sarea_priv->nbox;
u32 scandir = 0, i;
DMA_LOCALS;
- DRM_DEBUG( "\n" );
+ DRM_DEBUG("\n");
- BEGIN_DMA( 4 + nbox );
+ BEGIN_DMA(4 + nbox);
- DMA_BLOCK( MGA_DMAPAD, 0x00000000,
- MGA_DMAPAD, 0x00000000,
- MGA_DWGSYNC, 0x00007100,
- MGA_DWGSYNC, 0x00007000 );
+ DMA_BLOCK(MGA_DMAPAD, 0x00000000,
+ MGA_DMAPAD, 0x00000000,
+ MGA_DWGSYNC, 0x00007100, MGA_DWGSYNC, 0x00007000);
- DMA_BLOCK( MGA_DWGCTL, MGA_DWGCTL_COPY,
- MGA_PLNWT, blit->planemask,
- MGA_SRCORG, blit->srcorg,
- MGA_DSTORG, blit->dstorg );
+ DMA_BLOCK(MGA_DWGCTL, MGA_DWGCTL_COPY,
+ MGA_PLNWT, blit->planemask,
+ MGA_SRCORG, blit->srcorg, MGA_DSTORG, blit->dstorg);
- DMA_BLOCK( MGA_SGN, scandir,
- MGA_MACCESS, dev_priv->maccess,
- MGA_AR5, blit->ydir * blit->src_pitch,
- MGA_PITCH, blit->dst_pitch );
+ DMA_BLOCK(MGA_SGN, scandir,
+ MGA_MACCESS, dev_priv->maccess,
+ MGA_AR5, blit->ydir * blit->src_pitch,
+ MGA_PITCH, blit->dst_pitch);
- for ( i = 0 ; i < nbox ; i++ ) {
+ for (i = 0; i < nbox; i++) {
int srcx = pbox[i].x1 + blit->delta_sx;
int srcy = pbox[i].y1 + blit->delta_sy;
int dstx = pbox[i].x1 + blit->delta_dx;
@@ -847,52 +801,51 @@ static void mga_dma_dispatch_blit( drm_device_t *dev,
int w = pbox[i].x2 - pbox[i].x1 - 1;
int start;
- if ( blit->ydir == -1 ) {
+ if (blit->ydir == -1) {
srcy = blit->height - srcy - 1;
}
start = srcy * blit->src_pitch + srcx;
- DMA_BLOCK( MGA_AR0, start + w,
- MGA_AR3, start,
- MGA_FXBNDRY, ((dstx + w) << 16) | (dstx & 0xffff),
- MGA_YDSTLEN + MGA_EXEC, (dsty << 16) | h );
+ DMA_BLOCK(MGA_AR0, start + w,
+ MGA_AR3, start,
+ MGA_FXBNDRY, ((dstx + w) << 16) | (dstx & 0xffff),
+ MGA_YDSTLEN + MGA_EXEC, (dsty << 16) | h);
}
/* Do something to flush AGP?
*/
/* Force reset of DWGCTL */
- DMA_BLOCK( MGA_DMAPAD, 0x00000000,
- MGA_PLNWT, ctx->plnwt,
- MGA_PITCH, dev_priv->front_pitch,
- MGA_DWGCTL, ctx->dwgctl );
+ DMA_BLOCK(MGA_DMAPAD, 0x00000000,
+ MGA_PLNWT, ctx->plnwt,
+ MGA_PITCH, dev_priv->front_pitch, MGA_DWGCTL, ctx->dwgctl);
ADVANCE_DMA();
}
-
/* ================================================================
*
*/
-static int mga_dma_clear( DRM_IOCTL_ARGS )
+static int mga_dma_clear(DRM_IOCTL_ARGS)
{
DRM_DEVICE;
drm_mga_private_t *dev_priv = dev->dev_private;
drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
drm_mga_clear_t clear;
- LOCK_TEST_WITH_RETURN( dev, filp );
+ LOCK_TEST_WITH_RETURN(dev, filp);
- DRM_COPY_FROM_USER_IOCTL( clear, (drm_mga_clear_t __user *)data, sizeof(clear) );
+ DRM_COPY_FROM_USER_IOCTL(clear, (drm_mga_clear_t __user *) data,
+ sizeof(clear));
- if ( sarea_priv->nbox > MGA_NR_SAREA_CLIPRECTS )
+ if (sarea_priv->nbox > MGA_NR_SAREA_CLIPRECTS)
sarea_priv->nbox = MGA_NR_SAREA_CLIPRECTS;
- WRAP_TEST_WITH_RETURN( dev_priv );
+ WRAP_TEST_WITH_RETURN(dev_priv);
- mga_dma_dispatch_clear( dev, &clear );
+ mga_dma_dispatch_clear(dev, &clear);
/* Make sure we restore the 3D state next time.
*/
@@ -901,20 +854,20 @@ static int mga_dma_clear( DRM_IOCTL_ARGS )
return 0;
}
-static int mga_dma_swap( DRM_IOCTL_ARGS )
+static int mga_dma_swap(DRM_IOCTL_ARGS)
{
DRM_DEVICE;
drm_mga_private_t *dev_priv = dev->dev_private;
drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
- LOCK_TEST_WITH_RETURN( dev, filp );
+ LOCK_TEST_WITH_RETURN(dev, filp);
- if ( sarea_priv->nbox > MGA_NR_SAREA_CLIPRECTS )
+ if (sarea_priv->nbox > MGA_NR_SAREA_CLIPRECTS)
sarea_priv->nbox = MGA_NR_SAREA_CLIPRECTS;
- WRAP_TEST_WITH_RETURN( dev_priv );
+ WRAP_TEST_WITH_RETURN(dev_priv);
- mga_dma_dispatch_swap( dev );
+ mga_dma_dispatch_swap(dev);
/* Make sure we restore the 3D state next time.
*/
@@ -923,7 +876,7 @@ static int mga_dma_swap( DRM_IOCTL_ARGS )
return 0;
}
-static int mga_dma_vertex( DRM_IOCTL_ARGS )
+static int mga_dma_vertex(DRM_IOCTL_ARGS)
{
DRM_DEVICE;
drm_mga_private_t *dev_priv = dev->dev_private;
@@ -932,37 +885,38 @@ static int mga_dma_vertex( DRM_IOCTL_ARGS )
drm_mga_buf_priv_t *buf_priv;
drm_mga_vertex_t vertex;
- LOCK_TEST_WITH_RETURN( dev, filp );
+ LOCK_TEST_WITH_RETURN(dev, filp);
- DRM_COPY_FROM_USER_IOCTL( vertex,
- (drm_mga_vertex_t __user *)data,
- sizeof(vertex) );
+ DRM_COPY_FROM_USER_IOCTL(vertex,
+ (drm_mga_vertex_t __user *) data,
+ sizeof(vertex));
- if(vertex.idx < 0 || vertex.idx > dma->buf_count) return DRM_ERR(EINVAL);
+ if (vertex.idx < 0 || vertex.idx > dma->buf_count)
+ return DRM_ERR(EINVAL);
buf = dma->buflist[vertex.idx];
buf_priv = buf->dev_private;
buf->used = vertex.used;
buf_priv->discard = vertex.discard;
- if ( !mga_verify_state( dev_priv ) ) {
- if ( vertex.discard ) {
- if ( buf_priv->dispatched == 1 )
- AGE_BUFFER( buf_priv );
+ if (!mga_verify_state(dev_priv)) {
+ if (vertex.discard) {
+ if (buf_priv->dispatched == 1)
+ AGE_BUFFER(buf_priv);
buf_priv->dispatched = 0;
- mga_freelist_put( dev, buf );
+ mga_freelist_put(dev, buf);
}
return DRM_ERR(EINVAL);
}
- WRAP_TEST_WITH_RETURN( dev_priv );
+ WRAP_TEST_WITH_RETURN(dev_priv);
- mga_dma_dispatch_vertex( dev, buf );
+ mga_dma_dispatch_vertex(dev, buf);
return 0;
}
-static int mga_dma_indices( DRM_IOCTL_ARGS )
+static int mga_dma_indices(DRM_IOCTL_ARGS)
{
DRM_DEVICE;
drm_mga_private_t *dev_priv = dev->dev_private;
@@ -971,37 +925,38 @@ static int mga_dma_indices( DRM_IOCTL_ARGS )
drm_mga_buf_priv_t *buf_priv;
drm_mga_indices_t indices;
- LOCK_TEST_WITH_RETURN( dev, filp );
+ LOCK_TEST_WITH_RETURN(dev, filp);
- DRM_COPY_FROM_USER_IOCTL( indices,
- (drm_mga_indices_t __user *)data,
- sizeof(indices) );
+ DRM_COPY_FROM_USER_IOCTL(indices,
+ (drm_mga_indices_t __user *) data,
+ sizeof(indices));
- if(indices.idx < 0 || indices.idx > dma->buf_count) return DRM_ERR(EINVAL);
+ if (indices.idx < 0 || indices.idx > dma->buf_count)
+ return DRM_ERR(EINVAL);
buf = dma->buflist[indices.idx];
buf_priv = buf->dev_private;
buf_priv->discard = indices.discard;
- if ( !mga_verify_state( dev_priv ) ) {
- if ( indices.discard ) {
- if ( buf_priv->dispatched == 1 )
- AGE_BUFFER( buf_priv );
+ if (!mga_verify_state(dev_priv)) {
+ if (indices.discard) {
+ if (buf_priv->dispatched == 1)
+ AGE_BUFFER(buf_priv);
buf_priv->dispatched = 0;
- mga_freelist_put( dev, buf );
+ mga_freelist_put(dev, buf);
}
return DRM_ERR(EINVAL);
}
- WRAP_TEST_WITH_RETURN( dev_priv );
+ WRAP_TEST_WITH_RETURN(dev_priv);
- mga_dma_dispatch_indices( dev, buf, indices.start, indices.end );
+ mga_dma_dispatch_indices(dev, buf, indices.start, indices.end);
return 0;
}
-static int mga_dma_iload( DRM_IOCTL_ARGS )
+static int mga_dma_iload(DRM_IOCTL_ARGS)
{
DRM_DEVICE;
drm_device_dma_t *dma = dev->dma;
@@ -1009,32 +964,34 @@ static int mga_dma_iload( DRM_IOCTL_ARGS )
drm_buf_t *buf;
drm_mga_buf_priv_t *buf_priv;
drm_mga_iload_t iload;
- DRM_DEBUG( "\n" );
+ DRM_DEBUG("\n");
- LOCK_TEST_WITH_RETURN( dev, filp );
+ LOCK_TEST_WITH_RETURN(dev, filp);
- DRM_COPY_FROM_USER_IOCTL( iload, (drm_mga_iload_t __user *)data, sizeof(iload) );
+ DRM_COPY_FROM_USER_IOCTL(iload, (drm_mga_iload_t __user *) data,
+ sizeof(iload));
#if 0
- if ( mga_do_wait_for_idle( dev_priv ) < 0 ) {
- if ( MGA_DMA_DEBUG )
- DRM_INFO( "%s: -EBUSY\n", __FUNCTION__ );
+ if (mga_do_wait_for_idle(dev_priv) < 0) {
+ if (MGA_DMA_DEBUG)
+ DRM_INFO("%s: -EBUSY\n", __FUNCTION__);
return DRM_ERR(EBUSY);
}
#endif
- if(iload.idx < 0 || iload.idx > dma->buf_count) return DRM_ERR(EINVAL);
+ if (iload.idx < 0 || iload.idx > dma->buf_count)
+ return DRM_ERR(EINVAL);
buf = dma->buflist[iload.idx];
buf_priv = buf->dev_private;
- if ( mga_verify_iload( dev_priv, iload.dstorg, iload.length ) ) {
- mga_freelist_put( dev, buf );
+ if (mga_verify_iload(dev_priv, iload.dstorg, iload.length)) {
+ mga_freelist_put(dev, buf);
return DRM_ERR(EINVAL);
}
- WRAP_TEST_WITH_RETURN( dev_priv );
+ WRAP_TEST_WITH_RETURN(dev_priv);
- mga_dma_dispatch_iload( dev, buf, iload.dstorg, iload.length );
+ mga_dma_dispatch_iload(dev, buf, iload.dstorg, iload.length);
/* Make sure we restore the 3D state next time.
*/
@@ -1043,27 +1000,28 @@ static int mga_dma_iload( DRM_IOCTL_ARGS )
return 0;
}
-static int mga_dma_blit( DRM_IOCTL_ARGS )
+static int mga_dma_blit(DRM_IOCTL_ARGS)
{
DRM_DEVICE;
drm_mga_private_t *dev_priv = dev->dev_private;
drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
drm_mga_blit_t blit;
- DRM_DEBUG( "\n" );
+ DRM_DEBUG("\n");
- LOCK_TEST_WITH_RETURN( dev, filp );
+ LOCK_TEST_WITH_RETURN(dev, filp);
- DRM_COPY_FROM_USER_IOCTL( blit, (drm_mga_blit_t __user *)data, sizeof(blit) );
+ DRM_COPY_FROM_USER_IOCTL(blit, (drm_mga_blit_t __user *) data,
+ sizeof(blit));
- if ( sarea_priv->nbox > MGA_NR_SAREA_CLIPRECTS )
+ if (sarea_priv->nbox > MGA_NR_SAREA_CLIPRECTS)
sarea_priv->nbox = MGA_NR_SAREA_CLIPRECTS;
- if ( mga_verify_blit( dev_priv, blit.srcorg, blit.dstorg ) )
+ if (mga_verify_blit(dev_priv, blit.srcorg, blit.dstorg))
return DRM_ERR(EINVAL);
- WRAP_TEST_WITH_RETURN( dev_priv );
+ WRAP_TEST_WITH_RETURN(dev_priv);
- mga_dma_dispatch_blit( dev, &blit );
+ mga_dma_dispatch_blit(dev, &blit);
/* Make sure we restore the 3D state next time.
*/
@@ -1072,24 +1030,24 @@ static int mga_dma_blit( DRM_IOCTL_ARGS )
return 0;
}
-static int mga_getparam( DRM_IOCTL_ARGS )
+static int mga_getparam(DRM_IOCTL_ARGS)
{
DRM_DEVICE;
drm_mga_private_t *dev_priv = dev->dev_private;
drm_mga_getparam_t param;
int value;
- if ( !dev_priv ) {
- DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
+ if (!dev_priv) {
+ DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
return DRM_ERR(EINVAL);
}
- DRM_COPY_FROM_USER_IOCTL( param, (drm_mga_getparam_t __user *)data,
- sizeof(param) );
+ DRM_COPY_FROM_USER_IOCTL(param, (drm_mga_getparam_t __user *) data,
+ sizeof(param));
- DRM_DEBUG( "pid=%d\n", DRM_CURRENTPID );
+ DRM_DEBUG("pid=%d\n", DRM_CURRENTPID);
- switch( param.param ) {
+ switch (param.param) {
case MGA_PARAM_IRQ_NR:
value = dev->irq;
break;
@@ -1100,11 +1058,11 @@ static int mga_getparam( DRM_IOCTL_ARGS )
return DRM_ERR(EINVAL);
}
- if ( DRM_COPY_TO_USER( param.value, &value, sizeof(int) ) ) {
- DRM_ERROR( "copy_to_user\n" );
+ if (DRM_COPY_TO_USER(param.value, &value, sizeof(int))) {
+ DRM_ERROR("copy_to_user\n");
return DRM_ERR(EFAULT);
}
-
+
return 0;
}
@@ -1132,11 +1090,10 @@ static int mga_set_fence(DRM_IOCTL_ARGS)
BEGIN_DMA(1);
DMA_BLOCK(MGA_DMAPAD, 0x00000000,
MGA_DMAPAD, 0x00000000,
- MGA_DMAPAD, 0x00000000,
- MGA_SOFTRAP, 0x00000000);
+ MGA_DMAPAD, 0x00000000, MGA_SOFTRAP, 0x00000000);
ADVANCE_DMA();
- if (DRM_COPY_TO_USER( (u32 __user *) data, & temp, sizeof(u32))) {
+ if (DRM_COPY_TO_USER((u32 __user *) data, &temp, sizeof(u32))) {
DRM_ERROR("copy_to_user\n");
return DRM_ERR(EFAULT);
}
@@ -1159,9 +1116,9 @@ static int mga_wait_fence(DRM_IOCTL_ARGS)
DRM_DEBUG("pid=%d\n", DRM_CURRENTPID);
- mga_driver_fence_wait(dev, & fence);
+ mga_driver_fence_wait(dev, &fence);
- if (DRM_COPY_TO_USER( (u32 __user *) data, & fence, sizeof(u32))) {
+ if (DRM_COPY_TO_USER((u32 __user *) data, &fence, sizeof(u32))) {
DRM_ERROR("copy_to_user\n");
return DRM_ERR(EFAULT);
}
@@ -1183,7 +1140,6 @@ drm_ioctl_desc_t mga_ioctls[] = {
[DRM_IOCTL_NR(DRM_MGA_SET_FENCE)] = {mga_set_fence, 1, 0},
[DRM_IOCTL_NR(DRM_MGA_WAIT_FENCE)] = {mga_wait_fence, 1, 0},
[DRM_IOCTL_NR(DRM_MGA_DMA_BOOTSTRAP)] = {mga_dma_bootstrap, 1, 1},
-
};
int mga_max_ioctl = DRM_ARRAY_SIZE(mga_ioctls);
diff --git a/drivers/char/drm/mga_ucode.h b/drivers/char/drm/mga_ucode.h
index fa0f82ec9fa0..b611e27470e1 100644
--- a/drivers/char/drm/mga_ucode.h
+++ b/drivers/char/drm/mga_ucode.h
@@ -40,11606 +40,11606 @@
static unsigned char warp_g200_tgz[] = {
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x98, 0xA0, 0xE9,
-0x40, 0x40, 0xD8, 0xEC,
+ 0x00, 0x98, 0xA0, 0xE9,
+ 0x40, 0x40, 0xD8, 0xEC,
-0xFF, 0x80, 0xC0, 0xE9,
-0x00, 0x80, 0x00, 0xE8,
+ 0xFF, 0x80, 0xC0, 0xE9,
+ 0x00, 0x80, 0x00, 0xE8,
-0x1F, 0xD7, 0x18, 0xBD,
-0x3F, 0xD7, 0x22, 0xBD,
+ 0x1F, 0xD7, 0x18, 0xBD,
+ 0x3F, 0xD7, 0x22, 0xBD,
-0x81, 0x04,
-0x89, 0x04,
-0x01, 0x04,
-0x09, 0x04,
+ 0x81, 0x04,
+ 0x89, 0x04,
+ 0x01, 0x04,
+ 0x09, 0x04,
-0xC9, 0x41, 0xC0, 0xEC,
-0x11, 0x04,
-0x00, 0xE0,
+ 0xC9, 0x41, 0xC0, 0xEC,
+ 0x11, 0x04,
+ 0x00, 0xE0,
-0x41, 0xCC, 0x41, 0xCD,
-0x49, 0xCC, 0x49, 0xCD,
+ 0x41, 0xCC, 0x41, 0xCD,
+ 0x49, 0xCC, 0x49, 0xCD,
-0xD1, 0x41, 0xC0, 0xEC,
-0x51, 0xCC, 0x51, 0xCD,
+ 0xD1, 0x41, 0xC0, 0xEC,
+ 0x51, 0xCC, 0x51, 0xCD,
-0x80, 0x04,
-0x10, 0x04,
-0x08, 0x04,
-0x00, 0xE0,
+ 0x80, 0x04,
+ 0x10, 0x04,
+ 0x08, 0x04,
+ 0x00, 0xE0,
-0x00, 0xCC, 0xC0, 0xCD,
-0xD1, 0x49, 0xC0, 0xEC,
+ 0x00, 0xCC, 0xC0, 0xCD,
+ 0xD1, 0x49, 0xC0, 0xEC,
-0x8A, 0x1F, 0x20, 0xE9,
-0x8B, 0x3F, 0x20, 0xE9,
+ 0x8A, 0x1F, 0x20, 0xE9,
+ 0x8B, 0x3F, 0x20, 0xE9,
-0x41, 0x3C, 0x41, 0xAD,
-0x49, 0x3C, 0x49, 0xAD,
+ 0x41, 0x3C, 0x41, 0xAD,
+ 0x49, 0x3C, 0x49, 0xAD,
-0x10, 0xCC, 0x10, 0xCD,
-0x08, 0xCC, 0x08, 0xCD,
+ 0x10, 0xCC, 0x10, 0xCD,
+ 0x08, 0xCC, 0x08, 0xCD,
-0xB9, 0x41, 0x49, 0xBB,
-0x1F, 0xF0, 0x41, 0xCD,
+ 0xB9, 0x41, 0x49, 0xBB,
+ 0x1F, 0xF0, 0x41, 0xCD,
-0x51, 0x3C, 0x51, 0xAD,
-0x00, 0x98, 0x80, 0xE9,
+ 0x51, 0x3C, 0x51, 0xAD,
+ 0x00, 0x98, 0x80, 0xE9,
-0x72, 0x80, 0x07, 0xEA,
-0x24, 0x1F, 0x20, 0xE9,
+ 0x72, 0x80, 0x07, 0xEA,
+ 0x24, 0x1F, 0x20, 0xE9,
-0x15, 0x41, 0x49, 0xBD,
-0x1D, 0x41, 0x51, 0xBD,
+ 0x15, 0x41, 0x49, 0xBD,
+ 0x1D, 0x41, 0x51, 0xBD,
-0x2E, 0x41, 0x2A, 0xB8,
-0x34, 0x53, 0xA0, 0xE8,
+ 0x2E, 0x41, 0x2A, 0xB8,
+ 0x34, 0x53, 0xA0, 0xE8,
-0x15, 0x30,
-0x1D, 0x30,
-0x58, 0xE3,
-0x00, 0xE0,
+ 0x15, 0x30,
+ 0x1D, 0x30,
+ 0x58, 0xE3,
+ 0x00, 0xE0,
-0xB5, 0x40, 0x48, 0xBD,
-0x3D, 0x40, 0x50, 0xBD,
+ 0xB5, 0x40, 0x48, 0xBD,
+ 0x3D, 0x40, 0x50, 0xBD,
-0x24, 0x43, 0xA0, 0xE8,
-0x2C, 0x4B, 0xA0, 0xE8,
+ 0x24, 0x43, 0xA0, 0xE8,
+ 0x2C, 0x4B, 0xA0, 0xE8,
-0x15, 0x72,
-0x09, 0xE3,
-0x00, 0xE0,
-0x1D, 0x72,
+ 0x15, 0x72,
+ 0x09, 0xE3,
+ 0x00, 0xE0,
+ 0x1D, 0x72,
-0x35, 0x30,
-0xB5, 0x30,
-0xBD, 0x30,
-0x3D, 0x30,
+ 0x35, 0x30,
+ 0xB5, 0x30,
+ 0xBD, 0x30,
+ 0x3D, 0x30,
-0x9C, 0x97, 0x57, 0x9F,
-0x00, 0x80, 0x00, 0xE8,
+ 0x9C, 0x97, 0x57, 0x9F,
+ 0x00, 0x80, 0x00, 0xE8,
-0x6C, 0x64, 0xC8, 0xEC,
-0x98, 0xE1,
-0xB5, 0x05,
+ 0x6C, 0x64, 0xC8, 0xEC,
+ 0x98, 0xE1,
+ 0xB5, 0x05,
-0xBD, 0x05,
-0x2E, 0x30,
-0x32, 0xC0, 0xA0, 0xE8,
+ 0xBD, 0x05,
+ 0x2E, 0x30,
+ 0x32, 0xC0, 0xA0, 0xE8,
-0x33, 0xC0, 0xA0, 0xE8,
-0x74, 0x64, 0xC8, 0xEC,
+ 0x33, 0xC0, 0xA0, 0xE8,
+ 0x74, 0x64, 0xC8, 0xEC,
-0x40, 0x3C, 0x40, 0xAD,
-0x32, 0x6A,
-0x2A, 0x30,
+ 0x40, 0x3C, 0x40, 0xAD,
+ 0x32, 0x6A,
+ 0x2A, 0x30,
-0x20, 0x73,
-0x33, 0x6A,
-0x00, 0xE0,
-0x28, 0x73,
+ 0x20, 0x73,
+ 0x33, 0x6A,
+ 0x00, 0xE0,
+ 0x28, 0x73,
-0x1C, 0x72,
-0x83, 0xE2,
-0x60, 0x80, 0x15, 0xEA,
+ 0x1C, 0x72,
+ 0x83, 0xE2,
+ 0x60, 0x80, 0x15, 0xEA,
-0xB8, 0x3D, 0x28, 0xDF,
-0x30, 0x35, 0x20, 0xDF,
+ 0xB8, 0x3D, 0x28, 0xDF,
+ 0x30, 0x35, 0x20, 0xDF,
-0x40, 0x30,
-0x00, 0xE0,
-0xCC, 0xE2,
-0x64, 0x72,
+ 0x40, 0x30,
+ 0x00, 0xE0,
+ 0xCC, 0xE2,
+ 0x64, 0x72,
-0x25, 0x42, 0x52, 0xBF,
-0x2D, 0x42, 0x4A, 0xBF,
+ 0x25, 0x42, 0x52, 0xBF,
+ 0x2D, 0x42, 0x4A, 0xBF,
-0x30, 0x2E, 0x30, 0xDF,
-0x38, 0x2E, 0x38, 0xDF,
+ 0x30, 0x2E, 0x30, 0xDF,
+ 0x38, 0x2E, 0x38, 0xDF,
-0x18, 0x1D, 0x45, 0xE9,
-0x1E, 0x15, 0x45, 0xE9,
+ 0x18, 0x1D, 0x45, 0xE9,
+ 0x1E, 0x15, 0x45, 0xE9,
-0x2B, 0x49, 0x51, 0xBD,
-0x00, 0xE0,
-0x1F, 0x73,
+ 0x2B, 0x49, 0x51, 0xBD,
+ 0x00, 0xE0,
+ 0x1F, 0x73,
-0x38, 0x38, 0x40, 0xAF,
-0x30, 0x30, 0x40, 0xAF,
+ 0x38, 0x38, 0x40, 0xAF,
+ 0x30, 0x30, 0x40, 0xAF,
-0x24, 0x1F, 0x24, 0xDF,
-0x1D, 0x32, 0x20, 0xE9,
+ 0x24, 0x1F, 0x24, 0xDF,
+ 0x1D, 0x32, 0x20, 0xE9,
-0x2C, 0x1F, 0x2C, 0xDF,
-0x1A, 0x33, 0x20, 0xE9,
+ 0x2C, 0x1F, 0x2C, 0xDF,
+ 0x1A, 0x33, 0x20, 0xE9,
-0xB0, 0x10,
-0x08, 0xE3,
-0x40, 0x10,
-0xB8, 0x10,
+ 0xB0, 0x10,
+ 0x08, 0xE3,
+ 0x40, 0x10,
+ 0xB8, 0x10,
-0x26, 0xF0, 0x30, 0xCD,
-0x2F, 0xF0, 0x38, 0xCD,
+ 0x26, 0xF0, 0x30, 0xCD,
+ 0x2F, 0xF0, 0x38, 0xCD,
-0x2B, 0x80, 0x20, 0xE9,
-0x2A, 0x80, 0x20, 0xE9,
+ 0x2B, 0x80, 0x20, 0xE9,
+ 0x2A, 0x80, 0x20, 0xE9,
-0xA6, 0x20,
-0x88, 0xE2,
-0x00, 0xE0,
-0xAF, 0x20,
+ 0xA6, 0x20,
+ 0x88, 0xE2,
+ 0x00, 0xE0,
+ 0xAF, 0x20,
-0x28, 0x2A, 0x26, 0xAF,
-0x20, 0x2A, 0xC0, 0xAF,
+ 0x28, 0x2A, 0x26, 0xAF,
+ 0x20, 0x2A, 0xC0, 0xAF,
-0x34, 0x1F, 0x34, 0xDF,
-0x46, 0x24, 0x46, 0xDF,
+ 0x34, 0x1F, 0x34, 0xDF,
+ 0x46, 0x24, 0x46, 0xDF,
-0x28, 0x30, 0x80, 0xBF,
-0x20, 0x38, 0x80, 0xBF,
+ 0x28, 0x30, 0x80, 0xBF,
+ 0x20, 0x38, 0x80, 0xBF,
-0x47, 0x24, 0x47, 0xDF,
-0x4E, 0x2C, 0x4E, 0xDF,
+ 0x47, 0x24, 0x47, 0xDF,
+ 0x4E, 0x2C, 0x4E, 0xDF,
-0x4F, 0x2C, 0x4F, 0xDF,
-0x56, 0x34, 0x56, 0xDF,
+ 0x4F, 0x2C, 0x4F, 0xDF,
+ 0x56, 0x34, 0x56, 0xDF,
-0x28, 0x15, 0x28, 0xDF,
-0x20, 0x1D, 0x20, 0xDF,
+ 0x28, 0x15, 0x28, 0xDF,
+ 0x20, 0x1D, 0x20, 0xDF,
-0x57, 0x34, 0x57, 0xDF,
-0x00, 0xE0,
-0x1D, 0x05,
+ 0x57, 0x34, 0x57, 0xDF,
+ 0x00, 0xE0,
+ 0x1D, 0x05,
-0x04, 0x80, 0x10, 0xEA,
-0x89, 0xE2,
-0x2B, 0x30,
+ 0x04, 0x80, 0x10, 0xEA,
+ 0x89, 0xE2,
+ 0x2B, 0x30,
-0x3F, 0xC1, 0x1D, 0xBD,
-0x00, 0x80, 0x00, 0xE8,
+ 0x3F, 0xC1, 0x1D, 0xBD,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0xA0, 0x68,
-0xBF, 0x25,
-0x00, 0x80, 0x00, 0xE8,
+ 0xA0, 0x68,
+ 0xBF, 0x25,
+ 0x00, 0x80, 0x00, 0xE8,
-0x20, 0xC0, 0x20, 0xAF,
-0x28, 0x05,
-0x97, 0x74,
+ 0x20, 0xC0, 0x20, 0xAF,
+ 0x28, 0x05,
+ 0x97, 0x74,
-0x00, 0xE0,
-0x2A, 0x10,
-0x16, 0xC0, 0x20, 0xE9,
+ 0x00, 0xE0,
+ 0x2A, 0x10,
+ 0x16, 0xC0, 0x20, 0xE9,
-0x04, 0x80, 0x10, 0xEA,
-0x8C, 0xE2,
-0x95, 0x05,
+ 0x04, 0x80, 0x10, 0xEA,
+ 0x8C, 0xE2,
+ 0x95, 0x05,
-0x28, 0xC1, 0x28, 0xAD,
-0x1F, 0xC1, 0x15, 0xBD,
+ 0x28, 0xC1, 0x28, 0xAD,
+ 0x1F, 0xC1, 0x15, 0xBD,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0xA8, 0x67,
-0x9F, 0x6B,
-0x00, 0x80, 0x00, 0xE8,
+ 0xA8, 0x67,
+ 0x9F, 0x6B,
+ 0x00, 0x80, 0x00, 0xE8,
-0x28, 0xC0, 0x28, 0xAD,
-0x1D, 0x25,
-0x20, 0x05,
+ 0x28, 0xC0, 0x28, 0xAD,
+ 0x1D, 0x25,
+ 0x20, 0x05,
-0x28, 0x32, 0x80, 0xAD,
-0x40, 0x2A, 0x40, 0xBD,
+ 0x28, 0x32, 0x80, 0xAD,
+ 0x40, 0x2A, 0x40, 0xBD,
-0x1C, 0x80, 0x20, 0xE9,
-0x20, 0x33, 0x20, 0xAD,
+ 0x1C, 0x80, 0x20, 0xE9,
+ 0x20, 0x33, 0x20, 0xAD,
-0x20, 0x73,
-0x00, 0xE0,
-0xB6, 0x49, 0x51, 0xBB,
+ 0x20, 0x73,
+ 0x00, 0xE0,
+ 0xB6, 0x49, 0x51, 0xBB,
-0x26, 0x2F, 0xB0, 0xE8,
-0x19, 0x20, 0x20, 0xE9,
+ 0x26, 0x2F, 0xB0, 0xE8,
+ 0x19, 0x20, 0x20, 0xE9,
-0x35, 0x20, 0x35, 0xDF,
-0x3D, 0x20, 0x3D, 0xDF,
+ 0x35, 0x20, 0x35, 0xDF,
+ 0x3D, 0x20, 0x3D, 0xDF,
-0x15, 0x20, 0x15, 0xDF,
-0x1D, 0x20, 0x1D, 0xDF,
+ 0x15, 0x20, 0x15, 0xDF,
+ 0x1D, 0x20, 0x1D, 0xDF,
-0x26, 0xD0, 0x26, 0xCD,
-0x29, 0x49, 0x2A, 0xB8,
+ 0x26, 0xD0, 0x26, 0xCD,
+ 0x29, 0x49, 0x2A, 0xB8,
-0x26, 0x40, 0x80, 0xBD,
-0x3B, 0x48, 0x50, 0xBD,
+ 0x26, 0x40, 0x80, 0xBD,
+ 0x3B, 0x48, 0x50, 0xBD,
-0x3E, 0x54, 0x57, 0x9F,
-0x00, 0xE0,
-0x82, 0xE1,
+ 0x3E, 0x54, 0x57, 0x9F,
+ 0x00, 0xE0,
+ 0x82, 0xE1,
-0x1E, 0xAF, 0x59, 0x9F,
-0x00, 0x80, 0x00, 0xE8,
+ 0x1E, 0xAF, 0x59, 0x9F,
+ 0x00, 0x80, 0x00, 0xE8,
-0x26, 0x30,
-0x29, 0x30,
-0x48, 0x3C, 0x48, 0xAD,
+ 0x26, 0x30,
+ 0x29, 0x30,
+ 0x48, 0x3C, 0x48, 0xAD,
-0x2B, 0x72,
-0xC2, 0xE1,
-0x2C, 0xC0, 0x44, 0xC2,
+ 0x2B, 0x72,
+ 0xC2, 0xE1,
+ 0x2C, 0xC0, 0x44, 0xC2,
-0x05, 0x24, 0x34, 0xBF,
-0x0D, 0x24, 0x2C, 0xBF,
+ 0x05, 0x24, 0x34, 0xBF,
+ 0x0D, 0x24, 0x2C, 0xBF,
-0x2D, 0x46, 0x4E, 0xBF,
-0x25, 0x46, 0x56, 0xBF,
+ 0x2D, 0x46, 0x4E, 0xBF,
+ 0x25, 0x46, 0x56, 0xBF,
-0x20, 0x1D, 0x6F, 0x8F,
-0x32, 0x3E, 0x5F, 0xE9,
+ 0x20, 0x1D, 0x6F, 0x8F,
+ 0x32, 0x3E, 0x5F, 0xE9,
-0x3E, 0x50, 0x56, 0x9F,
-0x00, 0xE0,
-0x3B, 0x30,
+ 0x3E, 0x50, 0x56, 0x9F,
+ 0x00, 0xE0,
+ 0x3B, 0x30,
-0x1E, 0x8F, 0x51, 0x9F,
-0x33, 0x1E, 0x5F, 0xE9,
+ 0x1E, 0x8F, 0x51, 0x9F,
+ 0x33, 0x1E, 0x5F, 0xE9,
-0x05, 0x44, 0x54, 0xB2,
-0x0D, 0x44, 0x4C, 0xB2,
+ 0x05, 0x44, 0x54, 0xB2,
+ 0x0D, 0x44, 0x4C, 0xB2,
-0x19, 0xC0, 0xB0, 0xE8,
-0x34, 0xC0, 0x44, 0xC4,
+ 0x19, 0xC0, 0xB0, 0xE8,
+ 0x34, 0xC0, 0x44, 0xC4,
-0x33, 0x73,
-0x00, 0xE0,
-0x3E, 0x62, 0x57, 0x9F,
+ 0x33, 0x73,
+ 0x00, 0xE0,
+ 0x3E, 0x62, 0x57, 0x9F,
-0x1E, 0xAF, 0x59, 0x9F,
-0x00, 0xE0,
-0x0D, 0x20,
+ 0x1E, 0xAF, 0x59, 0x9F,
+ 0x00, 0xE0,
+ 0x0D, 0x20,
-0x84, 0x3E, 0x58, 0xE9,
-0x28, 0x1D, 0x6F, 0x8F,
+ 0x84, 0x3E, 0x58, 0xE9,
+ 0x28, 0x1D, 0x6F, 0x8F,
-0x05, 0x20,
-0x00, 0xE0,
-0x85, 0x1E, 0x58, 0xE9,
+ 0x05, 0x20,
+ 0x00, 0xE0,
+ 0x85, 0x1E, 0x58, 0xE9,
-0x9B, 0x3B, 0x33, 0xDF,
-0x20, 0x20, 0x42, 0xAF,
+ 0x9B, 0x3B, 0x33, 0xDF,
+ 0x20, 0x20, 0x42, 0xAF,
-0x30, 0x42, 0x56, 0x9F,
-0x80, 0x3E, 0x57, 0xE9,
+ 0x30, 0x42, 0x56, 0x9F,
+ 0x80, 0x3E, 0x57, 0xE9,
-0x3F, 0x8F, 0x51, 0x9F,
-0x30, 0x80, 0x5F, 0xE9,
+ 0x3F, 0x8F, 0x51, 0x9F,
+ 0x30, 0x80, 0x5F, 0xE9,
-0x28, 0x28, 0x24, 0xAF,
-0x81, 0x1E, 0x57, 0xE9,
+ 0x28, 0x28, 0x24, 0xAF,
+ 0x81, 0x1E, 0x57, 0xE9,
-0x05, 0x47, 0x57, 0xBF,
-0x0D, 0x47, 0x4F, 0xBF,
+ 0x05, 0x47, 0x57, 0xBF,
+ 0x0D, 0x47, 0x4F, 0xBF,
-0x88, 0x80, 0x58, 0xE9,
-0x1B, 0x29, 0x1B, 0xDF,
+ 0x88, 0x80, 0x58, 0xE9,
+ 0x1B, 0x29, 0x1B, 0xDF,
-0x30, 0x1D, 0x6F, 0x8F,
-0x3A, 0x30, 0x4F, 0xE9,
+ 0x30, 0x1D, 0x6F, 0x8F,
+ 0x3A, 0x30, 0x4F, 0xE9,
-0x1C, 0x30, 0x26, 0xDF,
-0x09, 0xE3,
-0x3B, 0x05,
+ 0x1C, 0x30, 0x26, 0xDF,
+ 0x09, 0xE3,
+ 0x3B, 0x05,
-0x3E, 0x50, 0x56, 0x9F,
-0x3B, 0x3F, 0x4F, 0xE9,
+ 0x3E, 0x50, 0x56, 0x9F,
+ 0x3B, 0x3F, 0x4F, 0xE9,
-0x1E, 0x8F, 0x51, 0x9F,
-0x00, 0xE0,
-0xAC, 0x20,
+ 0x1E, 0x8F, 0x51, 0x9F,
+ 0x00, 0xE0,
+ 0xAC, 0x20,
-0x2D, 0x44, 0x4C, 0xB4,
-0x2C, 0x1C, 0xC0, 0xAF,
+ 0x2D, 0x44, 0x4C, 0xB4,
+ 0x2C, 0x1C, 0xC0, 0xAF,
-0x25, 0x44, 0x54, 0xB4,
-0x00, 0xE0,
-0xC8, 0x30,
+ 0x25, 0x44, 0x54, 0xB4,
+ 0x00, 0xE0,
+ 0xC8, 0x30,
-0x30, 0x46, 0x30, 0xAF,
-0x1B, 0x1B, 0x48, 0xAF,
+ 0x30, 0x46, 0x30, 0xAF,
+ 0x1B, 0x1B, 0x48, 0xAF,
-0x00, 0xE0,
-0x25, 0x20,
-0x38, 0x2C, 0x4F, 0xE9,
+ 0x00, 0xE0,
+ 0x25, 0x20,
+ 0x38, 0x2C, 0x4F, 0xE9,
-0x86, 0x80, 0x57, 0xE9,
-0x38, 0x1D, 0x6F, 0x8F,
+ 0x86, 0x80, 0x57, 0xE9,
+ 0x38, 0x1D, 0x6F, 0x8F,
-0x28, 0x74,
-0x00, 0xE0,
-0x0D, 0x44, 0x4C, 0xB0,
+ 0x28, 0x74,
+ 0x00, 0xE0,
+ 0x0D, 0x44, 0x4C, 0xB0,
-0x05, 0x44, 0x54, 0xB0,
-0x2D, 0x20,
-0x9B, 0x10,
+ 0x05, 0x44, 0x54, 0xB0,
+ 0x2D, 0x20,
+ 0x9B, 0x10,
-0x82, 0x3E, 0x57, 0xE9,
-0x32, 0xF0, 0x1B, 0xCD,
+ 0x82, 0x3E, 0x57, 0xE9,
+ 0x32, 0xF0, 0x1B, 0xCD,
-0x1E, 0xBD, 0x59, 0x9F,
-0x83, 0x1E, 0x57, 0xE9,
+ 0x1E, 0xBD, 0x59, 0x9F,
+ 0x83, 0x1E, 0x57, 0xE9,
-0x38, 0x47, 0x38, 0xAF,
-0x34, 0x20,
-0x2A, 0x30,
+ 0x38, 0x47, 0x38, 0xAF,
+ 0x34, 0x20,
+ 0x2A, 0x30,
-0x00, 0xE0,
-0x0D, 0x20,
-0x32, 0x20,
-0x05, 0x20,
+ 0x00, 0xE0,
+ 0x0D, 0x20,
+ 0x32, 0x20,
+ 0x05, 0x20,
-0x87, 0x80, 0x57, 0xE9,
-0x1F, 0x54, 0x57, 0x9F,
+ 0x87, 0x80, 0x57, 0xE9,
+ 0x1F, 0x54, 0x57, 0x9F,
-0x17, 0x42, 0x56, 0x9F,
-0x00, 0xE0,
-0x3B, 0x6A,
+ 0x17, 0x42, 0x56, 0x9F,
+ 0x00, 0xE0,
+ 0x3B, 0x6A,
-0x3F, 0x8F, 0x51, 0x9F,
-0x37, 0x1E, 0x4F, 0xE9,
+ 0x3F, 0x8F, 0x51, 0x9F,
+ 0x37, 0x1E, 0x4F, 0xE9,
-0x37, 0x32, 0x2A, 0xAF,
-0x00, 0xE0,
-0x32, 0x00,
+ 0x37, 0x32, 0x2A, 0xAF,
+ 0x00, 0xE0,
+ 0x32, 0x00,
-0x00, 0x80, 0x00, 0xE8,
-0x27, 0xC0, 0x44, 0xC0,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x27, 0xC0, 0x44, 0xC0,
-0x36, 0x1F, 0x4F, 0xE9,
-0x1F, 0x1F, 0x26, 0xDF,
+ 0x36, 0x1F, 0x4F, 0xE9,
+ 0x1F, 0x1F, 0x26, 0xDF,
-0x37, 0x1B, 0x37, 0xBF,
-0x17, 0x26, 0x17, 0xDF,
+ 0x37, 0x1B, 0x37, 0xBF,
+ 0x17, 0x26, 0x17, 0xDF,
-0x3E, 0x17, 0x4F, 0xE9,
-0x3F, 0x3F, 0x4F, 0xE9,
+ 0x3E, 0x17, 0x4F, 0xE9,
+ 0x3F, 0x3F, 0x4F, 0xE9,
-0x34, 0x1F, 0x34, 0xAF,
-0x2B, 0x05,
-0xA7, 0x20,
+ 0x34, 0x1F, 0x34, 0xAF,
+ 0x2B, 0x05,
+ 0xA7, 0x20,
-0x33, 0x2B, 0x37, 0xDF,
-0x27, 0x17, 0xC0, 0xAF,
+ 0x33, 0x2B, 0x37, 0xDF,
+ 0x27, 0x17, 0xC0, 0xAF,
-0x34, 0x80, 0x4F, 0xE9,
-0x00, 0x80, 0x00, 0xE8,
+ 0x34, 0x80, 0x4F, 0xE9,
+ 0x00, 0x80, 0x00, 0xE8,
-0x03, 0x80, 0x0A, 0xEA,
-0x17, 0xC1, 0x2B, 0xBD,
+ 0x03, 0x80, 0x0A, 0xEA,
+ 0x17, 0xC1, 0x2B, 0xBD,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0xB3, 0x68,
-0x97, 0x25,
-0x00, 0x80, 0x00, 0xE8,
+ 0xB3, 0x68,
+ 0x97, 0x25,
+ 0x00, 0x80, 0x00, 0xE8,
-0x33, 0xC0, 0x33, 0xAF,
-0x3C, 0x27, 0x4F, 0xE9,
+ 0x33, 0xC0, 0x33, 0xAF,
+ 0x3C, 0x27, 0x4F, 0xE9,
-0x57, 0x39, 0x20, 0xE9,
-0x28, 0x19, 0x60, 0xEC,
+ 0x57, 0x39, 0x20, 0xE9,
+ 0x28, 0x19, 0x60, 0xEC,
-0x2B, 0x32, 0x20, 0xE9,
-0x1D, 0x3B, 0x20, 0xE9,
+ 0x2B, 0x32, 0x20, 0xE9,
+ 0x1D, 0x3B, 0x20, 0xE9,
-0xB3, 0x05,
-0x00, 0xE0,
-0x16, 0x28, 0x20, 0xE9,
+ 0xB3, 0x05,
+ 0x00, 0xE0,
+ 0x16, 0x28, 0x20, 0xE9,
-0x23, 0x3B, 0x33, 0xAD,
-0x1E, 0x2B, 0x20, 0xE9,
+ 0x23, 0x3B, 0x33, 0xAD,
+ 0x1E, 0x2B, 0x20, 0xE9,
-0x1C, 0x80, 0x20, 0xE9,
-0x57, 0x36, 0x20, 0xE9,
+ 0x1C, 0x80, 0x20, 0xE9,
+ 0x57, 0x36, 0x20, 0xE9,
-0x00, 0x80, 0xA0, 0xE9,
-0x40, 0x40, 0xD8, 0xEC,
+ 0x00, 0x80, 0xA0, 0xE9,
+ 0x40, 0x40, 0xD8, 0xEC,
-0xFF, 0x80, 0xC0, 0xE9,
-0x90, 0xE2,
-0x00, 0xE0,
+ 0xFF, 0x80, 0xC0, 0xE9,
+ 0x90, 0xE2,
+ 0x00, 0xE0,
-0x85, 0xFF, 0x20, 0xEA,
-0x19, 0xC8, 0xC1, 0xCD,
+ 0x85, 0xFF, 0x20, 0xEA,
+ 0x19, 0xC8, 0xC1, 0xCD,
-0x1F, 0xD7, 0x18, 0xBD,
-0x3F, 0xD7, 0x22, 0xBD,
+ 0x1F, 0xD7, 0x18, 0xBD,
+ 0x3F, 0xD7, 0x22, 0xBD,
-0x9F, 0x41, 0x49, 0xBD,
-0x00, 0x80, 0x00, 0xE8,
+ 0x9F, 0x41, 0x49, 0xBD,
+ 0x00, 0x80, 0x00, 0xE8,
-0x25, 0x41, 0x49, 0xBD,
-0x2D, 0x41, 0x51, 0xBD,
+ 0x25, 0x41, 0x49, 0xBD,
+ 0x2D, 0x41, 0x51, 0xBD,
-0x0D, 0x80, 0x07, 0xEA,
-0x00, 0x80, 0x00, 0xE8,
+ 0x0D, 0x80, 0x07, 0xEA,
+ 0x00, 0x80, 0x00, 0xE8,
-0x35, 0x40, 0x48, 0xBD,
-0x3D, 0x40, 0x50, 0xBD,
+ 0x35, 0x40, 0x48, 0xBD,
+ 0x3D, 0x40, 0x50, 0xBD,
-0x00, 0x80, 0x00, 0xE8,
-0x25, 0x30,
-0x2D, 0x30,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x25, 0x30,
+ 0x2D, 0x30,
-0x35, 0x30,
-0xB5, 0x30,
-0xBD, 0x30,
-0x3D, 0x30,
+ 0x35, 0x30,
+ 0xB5, 0x30,
+ 0xBD, 0x30,
+ 0x3D, 0x30,
-0x9C, 0xA7, 0x5B, 0x9F,
-0x00, 0x80, 0x00, 0xE8,
+ 0x9C, 0xA7, 0x5B, 0x9F,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x84, 0xFF, 0x0A, 0xEA,
-0x00, 0x80, 0x00, 0xE8,
+ 0x84, 0xFF, 0x0A, 0xEA,
+ 0x00, 0x80, 0x00, 0xE8,
-0xC9, 0x41, 0xC8, 0xEC,
-0x42, 0xE1,
-0x00, 0xE0,
+ 0xC9, 0x41, 0xC8, 0xEC,
+ 0x42, 0xE1,
+ 0x00, 0xE0,
-0x82, 0xFF, 0x20, 0xEA,
-0x00, 0x80, 0x00, 0xE8,
+ 0x82, 0xFF, 0x20, 0xEA,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0xC8, 0x40, 0xC0, 0xEC,
-0x00, 0x80, 0x00, 0xE8,
+ 0xC8, 0x40, 0xC0, 0xEC,
+ 0x00, 0x80, 0x00, 0xE8,
-0x7F, 0xFF, 0x20, 0xEA,
-0x00, 0x80, 0x00, 0xE8,
+ 0x7F, 0xFF, 0x20, 0xEA,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
};
static unsigned char warp_g200_tgza[] = {
-0x00, 0x98, 0xA0, 0xE9,
-0x40, 0x40, 0xD8, 0xEC,
+ 0x00, 0x98, 0xA0, 0xE9,
+ 0x40, 0x40, 0xD8, 0xEC,
-0xFF, 0x80, 0xC0, 0xE9,
-0x00, 0x80, 0x00, 0xE8,
+ 0xFF, 0x80, 0xC0, 0xE9,
+ 0x00, 0x80, 0x00, 0xE8,
-0x1F, 0xD7, 0x18, 0xBD,
-0x3F, 0xD7, 0x22, 0xBD,
+ 0x1F, 0xD7, 0x18, 0xBD,
+ 0x3F, 0xD7, 0x22, 0xBD,
-0x81, 0x04,
-0x89, 0x04,
-0x01, 0x04,
-0x09, 0x04,
+ 0x81, 0x04,
+ 0x89, 0x04,
+ 0x01, 0x04,
+ 0x09, 0x04,
-0xC9, 0x41, 0xC0, 0xEC,
-0x11, 0x04,
-0x00, 0xE0,
+ 0xC9, 0x41, 0xC0, 0xEC,
+ 0x11, 0x04,
+ 0x00, 0xE0,
-0x41, 0xCC, 0x41, 0xCD,
-0x49, 0xCC, 0x49, 0xCD,
+ 0x41, 0xCC, 0x41, 0xCD,
+ 0x49, 0xCC, 0x49, 0xCD,
-0xD1, 0x41, 0xC0, 0xEC,
-0x51, 0xCC, 0x51, 0xCD,
+ 0xD1, 0x41, 0xC0, 0xEC,
+ 0x51, 0xCC, 0x51, 0xCD,
-0x80, 0x04,
-0x10, 0x04,
-0x08, 0x04,
-0x00, 0xE0,
+ 0x80, 0x04,
+ 0x10, 0x04,
+ 0x08, 0x04,
+ 0x00, 0xE0,
-0x00, 0xCC, 0xC0, 0xCD,
-0xD1, 0x49, 0xC0, 0xEC,
+ 0x00, 0xCC, 0xC0, 0xCD,
+ 0xD1, 0x49, 0xC0, 0xEC,
-0x8A, 0x1F, 0x20, 0xE9,
-0x8B, 0x3F, 0x20, 0xE9,
+ 0x8A, 0x1F, 0x20, 0xE9,
+ 0x8B, 0x3F, 0x20, 0xE9,
-0x41, 0x3C, 0x41, 0xAD,
-0x49, 0x3C, 0x49, 0xAD,
+ 0x41, 0x3C, 0x41, 0xAD,
+ 0x49, 0x3C, 0x49, 0xAD,
-0x10, 0xCC, 0x10, 0xCD,
-0x08, 0xCC, 0x08, 0xCD,
+ 0x10, 0xCC, 0x10, 0xCD,
+ 0x08, 0xCC, 0x08, 0xCD,
-0xB9, 0x41, 0x49, 0xBB,
-0x1F, 0xF0, 0x41, 0xCD,
+ 0xB9, 0x41, 0x49, 0xBB,
+ 0x1F, 0xF0, 0x41, 0xCD,
-0x51, 0x3C, 0x51, 0xAD,
-0x00, 0x98, 0x80, 0xE9,
+ 0x51, 0x3C, 0x51, 0xAD,
+ 0x00, 0x98, 0x80, 0xE9,
-0x7D, 0x80, 0x07, 0xEA,
-0x24, 0x1F, 0x20, 0xE9,
+ 0x7D, 0x80, 0x07, 0xEA,
+ 0x24, 0x1F, 0x20, 0xE9,
-0x15, 0x41, 0x49, 0xBD,
-0x1D, 0x41, 0x51, 0xBD,
+ 0x15, 0x41, 0x49, 0xBD,
+ 0x1D, 0x41, 0x51, 0xBD,
-0x2E, 0x41, 0x2A, 0xB8,
-0x34, 0x53, 0xA0, 0xE8,
+ 0x2E, 0x41, 0x2A, 0xB8,
+ 0x34, 0x53, 0xA0, 0xE8,
-0x15, 0x30,
-0x1D, 0x30,
-0x58, 0xE3,
-0x00, 0xE0,
+ 0x15, 0x30,
+ 0x1D, 0x30,
+ 0x58, 0xE3,
+ 0x00, 0xE0,
-0xB5, 0x40, 0x48, 0xBD,
-0x3D, 0x40, 0x50, 0xBD,
+ 0xB5, 0x40, 0x48, 0xBD,
+ 0x3D, 0x40, 0x50, 0xBD,
-0x24, 0x43, 0xA0, 0xE8,
-0x2C, 0x4B, 0xA0, 0xE8,
+ 0x24, 0x43, 0xA0, 0xE8,
+ 0x2C, 0x4B, 0xA0, 0xE8,
-0x15, 0x72,
-0x09, 0xE3,
-0x00, 0xE0,
-0x1D, 0x72,
+ 0x15, 0x72,
+ 0x09, 0xE3,
+ 0x00, 0xE0,
+ 0x1D, 0x72,
-0x35, 0x30,
-0xB5, 0x30,
-0xBD, 0x30,
-0x3D, 0x30,
+ 0x35, 0x30,
+ 0xB5, 0x30,
+ 0xBD, 0x30,
+ 0x3D, 0x30,
-0x9C, 0x97, 0x57, 0x9F,
-0x00, 0x80, 0x00, 0xE8,
+ 0x9C, 0x97, 0x57, 0x9F,
+ 0x00, 0x80, 0x00, 0xE8,
-0x6C, 0x64, 0xC8, 0xEC,
-0x98, 0xE1,
-0xB5, 0x05,
+ 0x6C, 0x64, 0xC8, 0xEC,
+ 0x98, 0xE1,
+ 0xB5, 0x05,
-0xBD, 0x05,
-0x2E, 0x30,
-0x32, 0xC0, 0xA0, 0xE8,
+ 0xBD, 0x05,
+ 0x2E, 0x30,
+ 0x32, 0xC0, 0xA0, 0xE8,
-0x33, 0xC0, 0xA0, 0xE8,
-0x74, 0x64, 0xC8, 0xEC,
+ 0x33, 0xC0, 0xA0, 0xE8,
+ 0x74, 0x64, 0xC8, 0xEC,
-0x40, 0x3C, 0x40, 0xAD,
-0x32, 0x6A,
-0x2A, 0x30,
+ 0x40, 0x3C, 0x40, 0xAD,
+ 0x32, 0x6A,
+ 0x2A, 0x30,
-0x20, 0x73,
-0x33, 0x6A,
-0x00, 0xE0,
-0x28, 0x73,
+ 0x20, 0x73,
+ 0x33, 0x6A,
+ 0x00, 0xE0,
+ 0x28, 0x73,
-0x1C, 0x72,
-0x83, 0xE2,
-0x6B, 0x80, 0x15, 0xEA,
+ 0x1C, 0x72,
+ 0x83, 0xE2,
+ 0x6B, 0x80, 0x15, 0xEA,
-0xB8, 0x3D, 0x28, 0xDF,
-0x30, 0x35, 0x20, 0xDF,
+ 0xB8, 0x3D, 0x28, 0xDF,
+ 0x30, 0x35, 0x20, 0xDF,
-0x40, 0x30,
-0x00, 0xE0,
-0xCC, 0xE2,
-0x64, 0x72,
+ 0x40, 0x30,
+ 0x00, 0xE0,
+ 0xCC, 0xE2,
+ 0x64, 0x72,
-0x25, 0x42, 0x52, 0xBF,
-0x2D, 0x42, 0x4A, 0xBF,
+ 0x25, 0x42, 0x52, 0xBF,
+ 0x2D, 0x42, 0x4A, 0xBF,
-0x30, 0x2E, 0x30, 0xDF,
-0x38, 0x2E, 0x38, 0xDF,
+ 0x30, 0x2E, 0x30, 0xDF,
+ 0x38, 0x2E, 0x38, 0xDF,
-0x18, 0x1D, 0x45, 0xE9,
-0x1E, 0x15, 0x45, 0xE9,
+ 0x18, 0x1D, 0x45, 0xE9,
+ 0x1E, 0x15, 0x45, 0xE9,
-0x2B, 0x49, 0x51, 0xBD,
-0x00, 0xE0,
-0x1F, 0x73,
+ 0x2B, 0x49, 0x51, 0xBD,
+ 0x00, 0xE0,
+ 0x1F, 0x73,
-0x38, 0x38, 0x40, 0xAF,
-0x30, 0x30, 0x40, 0xAF,
+ 0x38, 0x38, 0x40, 0xAF,
+ 0x30, 0x30, 0x40, 0xAF,
-0x24, 0x1F, 0x24, 0xDF,
-0x1D, 0x32, 0x20, 0xE9,
+ 0x24, 0x1F, 0x24, 0xDF,
+ 0x1D, 0x32, 0x20, 0xE9,
-0x2C, 0x1F, 0x2C, 0xDF,
-0x1A, 0x33, 0x20, 0xE9,
+ 0x2C, 0x1F, 0x2C, 0xDF,
+ 0x1A, 0x33, 0x20, 0xE9,
-0xB0, 0x10,
-0x08, 0xE3,
-0x40, 0x10,
-0xB8, 0x10,
+ 0xB0, 0x10,
+ 0x08, 0xE3,
+ 0x40, 0x10,
+ 0xB8, 0x10,
-0x26, 0xF0, 0x30, 0xCD,
-0x2F, 0xF0, 0x38, 0xCD,
+ 0x26, 0xF0, 0x30, 0xCD,
+ 0x2F, 0xF0, 0x38, 0xCD,
-0x2B, 0x80, 0x20, 0xE9,
-0x2A, 0x80, 0x20, 0xE9,
+ 0x2B, 0x80, 0x20, 0xE9,
+ 0x2A, 0x80, 0x20, 0xE9,
-0xA6, 0x20,
-0x88, 0xE2,
-0x00, 0xE0,
-0xAF, 0x20,
+ 0xA6, 0x20,
+ 0x88, 0xE2,
+ 0x00, 0xE0,
+ 0xAF, 0x20,
-0x28, 0x2A, 0x26, 0xAF,
-0x20, 0x2A, 0xC0, 0xAF,
+ 0x28, 0x2A, 0x26, 0xAF,
+ 0x20, 0x2A, 0xC0, 0xAF,
-0x34, 0x1F, 0x34, 0xDF,
-0x46, 0x24, 0x46, 0xDF,
+ 0x34, 0x1F, 0x34, 0xDF,
+ 0x46, 0x24, 0x46, 0xDF,
-0x28, 0x30, 0x80, 0xBF,
-0x20, 0x38, 0x80, 0xBF,
+ 0x28, 0x30, 0x80, 0xBF,
+ 0x20, 0x38, 0x80, 0xBF,
-0x47, 0x24, 0x47, 0xDF,
-0x4E, 0x2C, 0x4E, 0xDF,
+ 0x47, 0x24, 0x47, 0xDF,
+ 0x4E, 0x2C, 0x4E, 0xDF,
-0x4F, 0x2C, 0x4F, 0xDF,
-0x56, 0x34, 0x56, 0xDF,
+ 0x4F, 0x2C, 0x4F, 0xDF,
+ 0x56, 0x34, 0x56, 0xDF,
-0x28, 0x15, 0x28, 0xDF,
-0x20, 0x1D, 0x20, 0xDF,
+ 0x28, 0x15, 0x28, 0xDF,
+ 0x20, 0x1D, 0x20, 0xDF,
-0x57, 0x34, 0x57, 0xDF,
-0x00, 0xE0,
-0x1D, 0x05,
+ 0x57, 0x34, 0x57, 0xDF,
+ 0x00, 0xE0,
+ 0x1D, 0x05,
-0x04, 0x80, 0x10, 0xEA,
-0x89, 0xE2,
-0x2B, 0x30,
+ 0x04, 0x80, 0x10, 0xEA,
+ 0x89, 0xE2,
+ 0x2B, 0x30,
-0x3F, 0xC1, 0x1D, 0xBD,
-0x00, 0x80, 0x00, 0xE8,
+ 0x3F, 0xC1, 0x1D, 0xBD,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0xA0, 0x68,
-0xBF, 0x25,
-0x00, 0x80, 0x00, 0xE8,
+ 0xA0, 0x68,
+ 0xBF, 0x25,
+ 0x00, 0x80, 0x00, 0xE8,
-0x20, 0xC0, 0x20, 0xAF,
-0x28, 0x05,
-0x97, 0x74,
+ 0x20, 0xC0, 0x20, 0xAF,
+ 0x28, 0x05,
+ 0x97, 0x74,
-0x00, 0xE0,
-0x2A, 0x10,
-0x16, 0xC0, 0x20, 0xE9,
+ 0x00, 0xE0,
+ 0x2A, 0x10,
+ 0x16, 0xC0, 0x20, 0xE9,
-0x04, 0x80, 0x10, 0xEA,
-0x8C, 0xE2,
-0x95, 0x05,
+ 0x04, 0x80, 0x10, 0xEA,
+ 0x8C, 0xE2,
+ 0x95, 0x05,
-0x28, 0xC1, 0x28, 0xAD,
-0x1F, 0xC1, 0x15, 0xBD,
+ 0x28, 0xC1, 0x28, 0xAD,
+ 0x1F, 0xC1, 0x15, 0xBD,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0xA8, 0x67,
-0x9F, 0x6B,
-0x00, 0x80, 0x00, 0xE8,
+ 0xA8, 0x67,
+ 0x9F, 0x6B,
+ 0x00, 0x80, 0x00, 0xE8,
-0x28, 0xC0, 0x28, 0xAD,
-0x1D, 0x25,
-0x20, 0x05,
+ 0x28, 0xC0, 0x28, 0xAD,
+ 0x1D, 0x25,
+ 0x20, 0x05,
-0x28, 0x32, 0x80, 0xAD,
-0x40, 0x2A, 0x40, 0xBD,
+ 0x28, 0x32, 0x80, 0xAD,
+ 0x40, 0x2A, 0x40, 0xBD,
-0x1C, 0x80, 0x20, 0xE9,
-0x20, 0x33, 0x20, 0xAD,
+ 0x1C, 0x80, 0x20, 0xE9,
+ 0x20, 0x33, 0x20, 0xAD,
-0x20, 0x73,
-0x00, 0xE0,
-0xB6, 0x49, 0x51, 0xBB,
+ 0x20, 0x73,
+ 0x00, 0xE0,
+ 0xB6, 0x49, 0x51, 0xBB,
-0x26, 0x2F, 0xB0, 0xE8,
-0x19, 0x20, 0x20, 0xE9,
+ 0x26, 0x2F, 0xB0, 0xE8,
+ 0x19, 0x20, 0x20, 0xE9,
-0x35, 0x20, 0x35, 0xDF,
-0x3D, 0x20, 0x3D, 0xDF,
+ 0x35, 0x20, 0x35, 0xDF,
+ 0x3D, 0x20, 0x3D, 0xDF,
-0x15, 0x20, 0x15, 0xDF,
-0x1D, 0x20, 0x1D, 0xDF,
+ 0x15, 0x20, 0x15, 0xDF,
+ 0x1D, 0x20, 0x1D, 0xDF,
-0x26, 0xD0, 0x26, 0xCD,
-0x29, 0x49, 0x2A, 0xB8,
+ 0x26, 0xD0, 0x26, 0xCD,
+ 0x29, 0x49, 0x2A, 0xB8,
-0x26, 0x40, 0x80, 0xBD,
-0x3B, 0x48, 0x50, 0xBD,
+ 0x26, 0x40, 0x80, 0xBD,
+ 0x3B, 0x48, 0x50, 0xBD,
-0x3E, 0x54, 0x57, 0x9F,
-0x00, 0xE0,
-0x82, 0xE1,
+ 0x3E, 0x54, 0x57, 0x9F,
+ 0x00, 0xE0,
+ 0x82, 0xE1,
-0x1E, 0xAF, 0x59, 0x9F,
-0x00, 0x80, 0x00, 0xE8,
+ 0x1E, 0xAF, 0x59, 0x9F,
+ 0x00, 0x80, 0x00, 0xE8,
-0x26, 0x30,
-0x29, 0x30,
-0x48, 0x3C, 0x48, 0xAD,
+ 0x26, 0x30,
+ 0x29, 0x30,
+ 0x48, 0x3C, 0x48, 0xAD,
-0x2B, 0x72,
-0xC2, 0xE1,
-0x2C, 0xC0, 0x44, 0xC2,
+ 0x2B, 0x72,
+ 0xC2, 0xE1,
+ 0x2C, 0xC0, 0x44, 0xC2,
-0x05, 0x24, 0x34, 0xBF,
-0x0D, 0x24, 0x2C, 0xBF,
+ 0x05, 0x24, 0x34, 0xBF,
+ 0x0D, 0x24, 0x2C, 0xBF,
-0x2D, 0x46, 0x4E, 0xBF,
-0x25, 0x46, 0x56, 0xBF,
+ 0x2D, 0x46, 0x4E, 0xBF,
+ 0x25, 0x46, 0x56, 0xBF,
-0x20, 0x1D, 0x6F, 0x8F,
-0x32, 0x3E, 0x5F, 0xE9,
+ 0x20, 0x1D, 0x6F, 0x8F,
+ 0x32, 0x3E, 0x5F, 0xE9,
-0x3E, 0x50, 0x56, 0x9F,
-0x00, 0xE0,
-0x3B, 0x30,
+ 0x3E, 0x50, 0x56, 0x9F,
+ 0x00, 0xE0,
+ 0x3B, 0x30,
-0x1E, 0x8F, 0x51, 0x9F,
-0x33, 0x1E, 0x5F, 0xE9,
+ 0x1E, 0x8F, 0x51, 0x9F,
+ 0x33, 0x1E, 0x5F, 0xE9,
-0x05, 0x44, 0x54, 0xB2,
-0x0D, 0x44, 0x4C, 0xB2,
+ 0x05, 0x44, 0x54, 0xB2,
+ 0x0D, 0x44, 0x4C, 0xB2,
-0x19, 0xC0, 0xB0, 0xE8,
-0x34, 0xC0, 0x44, 0xC4,
+ 0x19, 0xC0, 0xB0, 0xE8,
+ 0x34, 0xC0, 0x44, 0xC4,
-0x33, 0x73,
-0x00, 0xE0,
-0x3E, 0x62, 0x57, 0x9F,
+ 0x33, 0x73,
+ 0x00, 0xE0,
+ 0x3E, 0x62, 0x57, 0x9F,
-0x1E, 0xAF, 0x59, 0x9F,
-0x00, 0xE0,
-0x0D, 0x20,
+ 0x1E, 0xAF, 0x59, 0x9F,
+ 0x00, 0xE0,
+ 0x0D, 0x20,
-0x84, 0x3E, 0x58, 0xE9,
-0x28, 0x1D, 0x6F, 0x8F,
+ 0x84, 0x3E, 0x58, 0xE9,
+ 0x28, 0x1D, 0x6F, 0x8F,
-0x05, 0x20,
-0x00, 0xE0,
-0x85, 0x1E, 0x58, 0xE9,
+ 0x05, 0x20,
+ 0x00, 0xE0,
+ 0x85, 0x1E, 0x58, 0xE9,
-0x9B, 0x3B, 0x33, 0xDF,
-0x20, 0x20, 0x42, 0xAF,
+ 0x9B, 0x3B, 0x33, 0xDF,
+ 0x20, 0x20, 0x42, 0xAF,
-0x30, 0x42, 0x56, 0x9F,
-0x80, 0x3E, 0x57, 0xE9,
+ 0x30, 0x42, 0x56, 0x9F,
+ 0x80, 0x3E, 0x57, 0xE9,
-0x3F, 0x8F, 0x51, 0x9F,
-0x30, 0x80, 0x5F, 0xE9,
+ 0x3F, 0x8F, 0x51, 0x9F,
+ 0x30, 0x80, 0x5F, 0xE9,
-0x28, 0x28, 0x24, 0xAF,
-0x81, 0x1E, 0x57, 0xE9,
+ 0x28, 0x28, 0x24, 0xAF,
+ 0x81, 0x1E, 0x57, 0xE9,
-0x05, 0x47, 0x57, 0xBF,
-0x0D, 0x47, 0x4F, 0xBF,
+ 0x05, 0x47, 0x57, 0xBF,
+ 0x0D, 0x47, 0x4F, 0xBF,
-0x88, 0x80, 0x58, 0xE9,
-0x1B, 0x29, 0x1B, 0xDF,
+ 0x88, 0x80, 0x58, 0xE9,
+ 0x1B, 0x29, 0x1B, 0xDF,
-0x30, 0x1D, 0x6F, 0x8F,
-0x3A, 0x30, 0x4F, 0xE9,
+ 0x30, 0x1D, 0x6F, 0x8F,
+ 0x3A, 0x30, 0x4F, 0xE9,
-0x1C, 0x30, 0x26, 0xDF,
-0x09, 0xE3,
-0x3B, 0x05,
+ 0x1C, 0x30, 0x26, 0xDF,
+ 0x09, 0xE3,
+ 0x3B, 0x05,
-0x3E, 0x50, 0x56, 0x9F,
-0x3B, 0x3F, 0x4F, 0xE9,
+ 0x3E, 0x50, 0x56, 0x9F,
+ 0x3B, 0x3F, 0x4F, 0xE9,
-0x1E, 0x8F, 0x51, 0x9F,
-0x00, 0xE0,
-0xAC, 0x20,
+ 0x1E, 0x8F, 0x51, 0x9F,
+ 0x00, 0xE0,
+ 0xAC, 0x20,
-0x2D, 0x44, 0x4C, 0xB4,
-0x2C, 0x1C, 0xC0, 0xAF,
+ 0x2D, 0x44, 0x4C, 0xB4,
+ 0x2C, 0x1C, 0xC0, 0xAF,
-0x25, 0x44, 0x54, 0xB4,
-0x00, 0xE0,
-0xC8, 0x30,
+ 0x25, 0x44, 0x54, 0xB4,
+ 0x00, 0xE0,
+ 0xC8, 0x30,
-0x30, 0x46, 0x30, 0xAF,
-0x1B, 0x1B, 0x48, 0xAF,
+ 0x30, 0x46, 0x30, 0xAF,
+ 0x1B, 0x1B, 0x48, 0xAF,
-0x00, 0xE0,
-0x25, 0x20,
-0x38, 0x2C, 0x4F, 0xE9,
+ 0x00, 0xE0,
+ 0x25, 0x20,
+ 0x38, 0x2C, 0x4F, 0xE9,
-0x86, 0x80, 0x57, 0xE9,
-0x38, 0x1D, 0x6F, 0x8F,
+ 0x86, 0x80, 0x57, 0xE9,
+ 0x38, 0x1D, 0x6F, 0x8F,
-0x28, 0x74,
-0x00, 0xE0,
-0x0D, 0x44, 0x4C, 0xB0,
+ 0x28, 0x74,
+ 0x00, 0xE0,
+ 0x0D, 0x44, 0x4C, 0xB0,
-0x05, 0x44, 0x54, 0xB0,
-0x2D, 0x20,
-0x9B, 0x10,
+ 0x05, 0x44, 0x54, 0xB0,
+ 0x2D, 0x20,
+ 0x9B, 0x10,
-0x82, 0x3E, 0x57, 0xE9,
-0x32, 0xF0, 0x1B, 0xCD,
+ 0x82, 0x3E, 0x57, 0xE9,
+ 0x32, 0xF0, 0x1B, 0xCD,
-0x1E, 0xBD, 0x59, 0x9F,
-0x83, 0x1E, 0x57, 0xE9,
+ 0x1E, 0xBD, 0x59, 0x9F,
+ 0x83, 0x1E, 0x57, 0xE9,
-0x38, 0x47, 0x38, 0xAF,
-0x34, 0x20,
-0x2A, 0x30,
+ 0x38, 0x47, 0x38, 0xAF,
+ 0x34, 0x20,
+ 0x2A, 0x30,
-0x00, 0xE0,
-0x0D, 0x20,
-0x32, 0x20,
-0x05, 0x20,
+ 0x00, 0xE0,
+ 0x0D, 0x20,
+ 0x32, 0x20,
+ 0x05, 0x20,
-0x87, 0x80, 0x57, 0xE9,
-0x1F, 0x54, 0x57, 0x9F,
+ 0x87, 0x80, 0x57, 0xE9,
+ 0x1F, 0x54, 0x57, 0x9F,
-0x17, 0x42, 0x56, 0x9F,
-0x00, 0xE0,
-0x3B, 0x6A,
+ 0x17, 0x42, 0x56, 0x9F,
+ 0x00, 0xE0,
+ 0x3B, 0x6A,
-0x3F, 0x8F, 0x51, 0x9F,
-0x37, 0x1E, 0x4F, 0xE9,
+ 0x3F, 0x8F, 0x51, 0x9F,
+ 0x37, 0x1E, 0x4F, 0xE9,
-0x37, 0x32, 0x2A, 0xAF,
-0x00, 0xE0,
-0x32, 0x00,
+ 0x37, 0x32, 0x2A, 0xAF,
+ 0x00, 0xE0,
+ 0x32, 0x00,
-0x00, 0x80, 0x00, 0xE8,
-0x27, 0xC0, 0x44, 0xC0,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x27, 0xC0, 0x44, 0xC0,
-0x36, 0x1F, 0x4F, 0xE9,
-0x1F, 0x1F, 0x26, 0xDF,
+ 0x36, 0x1F, 0x4F, 0xE9,
+ 0x1F, 0x1F, 0x26, 0xDF,
-0x37, 0x1B, 0x37, 0xBF,
-0x17, 0x26, 0x17, 0xDF,
+ 0x37, 0x1B, 0x37, 0xBF,
+ 0x17, 0x26, 0x17, 0xDF,
-0x3E, 0x17, 0x4F, 0xE9,
-0x3F, 0x3F, 0x4F, 0xE9,
+ 0x3E, 0x17, 0x4F, 0xE9,
+ 0x3F, 0x3F, 0x4F, 0xE9,
-0x34, 0x1F, 0x34, 0xAF,
-0x2B, 0x05,
-0xA7, 0x20,
+ 0x34, 0x1F, 0x34, 0xAF,
+ 0x2B, 0x05,
+ 0xA7, 0x20,
-0x33, 0x2B, 0x37, 0xDF,
-0x27, 0x17, 0xC0, 0xAF,
+ 0x33, 0x2B, 0x37, 0xDF,
+ 0x27, 0x17, 0xC0, 0xAF,
-0x34, 0x80, 0x4F, 0xE9,
-0x00, 0x80, 0x00, 0xE8,
+ 0x34, 0x80, 0x4F, 0xE9,
+ 0x00, 0x80, 0x00, 0xE8,
-0x2D, 0x44, 0x4C, 0xB6,
-0x25, 0x44, 0x54, 0xB6,
+ 0x2D, 0x44, 0x4C, 0xB6,
+ 0x25, 0x44, 0x54, 0xB6,
-0x03, 0x80, 0x2A, 0xEA,
-0x17, 0xC1, 0x2B, 0xBD,
+ 0x03, 0x80, 0x2A, 0xEA,
+ 0x17, 0xC1, 0x2B, 0xBD,
-0x2D, 0x20,
-0x25, 0x20,
-0x07, 0xC0, 0x44, 0xC6,
+ 0x2D, 0x20,
+ 0x25, 0x20,
+ 0x07, 0xC0, 0x44, 0xC6,
-0xB3, 0x68,
-0x97, 0x25,
-0x00, 0x80, 0x00, 0xE8,
+ 0xB3, 0x68,
+ 0x97, 0x25,
+ 0x00, 0x80, 0x00, 0xE8,
-0x33, 0xC0, 0x33, 0xAF,
-0x3C, 0x27, 0x4F, 0xE9,
+ 0x33, 0xC0, 0x33, 0xAF,
+ 0x3C, 0x27, 0x4F, 0xE9,
-0x1F, 0x62, 0x57, 0x9F,
-0x00, 0x80, 0x00, 0xE8,
+ 0x1F, 0x62, 0x57, 0x9F,
+ 0x00, 0x80, 0x00, 0xE8,
-0x3F, 0x3D, 0x5D, 0x9F,
-0x00, 0xE0,
-0x07, 0x20,
+ 0x3F, 0x3D, 0x5D, 0x9F,
+ 0x00, 0xE0,
+ 0x07, 0x20,
-0x00, 0x80, 0x00, 0xE8,
-0x28, 0x19, 0x60, 0xEC,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x28, 0x19, 0x60, 0xEC,
-0xB3, 0x05,
-0x00, 0xE0,
-0x00, 0x80, 0x00, 0xE8,
+ 0xB3, 0x05,
+ 0x00, 0xE0,
+ 0x00, 0x80, 0x00, 0xE8,
-0x23, 0x3B, 0x33, 0xAD,
-0x00, 0x80, 0x00, 0xE8,
+ 0x23, 0x3B, 0x33, 0xAD,
+ 0x00, 0x80, 0x00, 0xE8,
-0x1F, 0x26, 0x1F, 0xDF,
-0x9D, 0x1F, 0x4F, 0xE9,
+ 0x1F, 0x26, 0x1F, 0xDF,
+ 0x9D, 0x1F, 0x4F, 0xE9,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x9E, 0x3F, 0x4F, 0xE9,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x9E, 0x3F, 0x4F, 0xE9,
-0x07, 0x07, 0x1F, 0xAF,
-0x00, 0x80, 0x00, 0xE8,
+ 0x07, 0x07, 0x1F, 0xAF,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x9C, 0x80, 0x4F, 0xE9,
-0x00, 0x80, 0x00, 0xE8,
+ 0x9C, 0x80, 0x4F, 0xE9,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x57, 0x39, 0x20, 0xE9,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x57, 0x39, 0x20, 0xE9,
-0x16, 0x28, 0x20, 0xE9,
-0x1D, 0x3B, 0x20, 0xE9,
+ 0x16, 0x28, 0x20, 0xE9,
+ 0x1D, 0x3B, 0x20, 0xE9,
-0x1E, 0x2B, 0x20, 0xE9,
-0x2B, 0x32, 0x20, 0xE9,
+ 0x1E, 0x2B, 0x20, 0xE9,
+ 0x2B, 0x32, 0x20, 0xE9,
-0x1C, 0x23, 0x20, 0xE9,
-0x57, 0x36, 0x20, 0xE9,
+ 0x1C, 0x23, 0x20, 0xE9,
+ 0x57, 0x36, 0x20, 0xE9,
-0x00, 0x80, 0xA0, 0xE9,
-0x40, 0x40, 0xD8, 0xEC,
+ 0x00, 0x80, 0xA0, 0xE9,
+ 0x40, 0x40, 0xD8, 0xEC,
-0xFF, 0x80, 0xC0, 0xE9,
-0x90, 0xE2,
-0x00, 0xE0,
+ 0xFF, 0x80, 0xC0, 0xE9,
+ 0x90, 0xE2,
+ 0x00, 0xE0,
-0x7A, 0xFF, 0x20, 0xEA,
-0x19, 0xC8, 0xC1, 0xCD,
+ 0x7A, 0xFF, 0x20, 0xEA,
+ 0x19, 0xC8, 0xC1, 0xCD,
-0x1F, 0xD7, 0x18, 0xBD,
-0x3F, 0xD7, 0x22, 0xBD,
+ 0x1F, 0xD7, 0x18, 0xBD,
+ 0x3F, 0xD7, 0x22, 0xBD,
-0x9F, 0x41, 0x49, 0xBD,
-0x00, 0x80, 0x00, 0xE8,
+ 0x9F, 0x41, 0x49, 0xBD,
+ 0x00, 0x80, 0x00, 0xE8,
-0x25, 0x41, 0x49, 0xBD,
-0x2D, 0x41, 0x51, 0xBD,
+ 0x25, 0x41, 0x49, 0xBD,
+ 0x2D, 0x41, 0x51, 0xBD,
-0x0D, 0x80, 0x07, 0xEA,
-0x00, 0x80, 0x00, 0xE8,
+ 0x0D, 0x80, 0x07, 0xEA,
+ 0x00, 0x80, 0x00, 0xE8,
-0x35, 0x40, 0x48, 0xBD,
-0x3D, 0x40, 0x50, 0xBD,
+ 0x35, 0x40, 0x48, 0xBD,
+ 0x3D, 0x40, 0x50, 0xBD,
-0x00, 0x80, 0x00, 0xE8,
-0x25, 0x30,
-0x2D, 0x30,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x25, 0x30,
+ 0x2D, 0x30,
-0x35, 0x30,
-0xB5, 0x30,
-0xBD, 0x30,
-0x3D, 0x30,
+ 0x35, 0x30,
+ 0xB5, 0x30,
+ 0xBD, 0x30,
+ 0x3D, 0x30,
-0x9C, 0xA7, 0x5B, 0x9F,
-0x00, 0x80, 0x00, 0xE8,
+ 0x9C, 0xA7, 0x5B, 0x9F,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x79, 0xFF, 0x0A, 0xEA,
-0x00, 0x80, 0x00, 0xE8,
+ 0x79, 0xFF, 0x0A, 0xEA,
+ 0x00, 0x80, 0x00, 0xE8,
-0xC9, 0x41, 0xC8, 0xEC,
-0x42, 0xE1,
-0x00, 0xE0,
+ 0xC9, 0x41, 0xC8, 0xEC,
+ 0x42, 0xE1,
+ 0x00, 0xE0,
-0x77, 0xFF, 0x20, 0xEA,
-0x00, 0x80, 0x00, 0xE8,
+ 0x77, 0xFF, 0x20, 0xEA,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0xC8, 0x40, 0xC0, 0xEC,
-0x00, 0x80, 0x00, 0xE8,
+ 0xC8, 0x40, 0xC0, 0xEC,
+ 0x00, 0x80, 0x00, 0xE8,
-0x74, 0xFF, 0x20, 0xEA,
-0x00, 0x80, 0x00, 0xE8,
+ 0x74, 0xFF, 0x20, 0xEA,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
};
static unsigned char warp_g200_tgzaf[] = {
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x98, 0xA0, 0xE9,
-0x40, 0x40, 0xD8, 0xEC,
+ 0x00, 0x98, 0xA0, 0xE9,
+ 0x40, 0x40, 0xD8, 0xEC,
-0xFF, 0x80, 0xC0, 0xE9,
-0x00, 0x80, 0x00, 0xE8,
+ 0xFF, 0x80, 0xC0, 0xE9,
+ 0x00, 0x80, 0x00, 0xE8,
-0x1F, 0xD7, 0x18, 0xBD,
-0x3F, 0xD7, 0x22, 0xBD,
+ 0x1F, 0xD7, 0x18, 0xBD,
+ 0x3F, 0xD7, 0x22, 0xBD,
-0x81, 0x04,
-0x89, 0x04,
-0x01, 0x04,
-0x09, 0x04,
+ 0x81, 0x04,
+ 0x89, 0x04,
+ 0x01, 0x04,
+ 0x09, 0x04,
-0xC9, 0x41, 0xC0, 0xEC,
-0x11, 0x04,
-0x00, 0xE0,
+ 0xC9, 0x41, 0xC0, 0xEC,
+ 0x11, 0x04,
+ 0x00, 0xE0,
-0x41, 0xCC, 0x41, 0xCD,
-0x49, 0xCC, 0x49, 0xCD,
+ 0x41, 0xCC, 0x41, 0xCD,
+ 0x49, 0xCC, 0x49, 0xCD,
-0xD1, 0x41, 0xC0, 0xEC,
-0x51, 0xCC, 0x51, 0xCD,
+ 0xD1, 0x41, 0xC0, 0xEC,
+ 0x51, 0xCC, 0x51, 0xCD,
-0x80, 0x04,
-0x10, 0x04,
-0x08, 0x04,
-0x00, 0xE0,
+ 0x80, 0x04,
+ 0x10, 0x04,
+ 0x08, 0x04,
+ 0x00, 0xE0,
-0x00, 0xCC, 0xC0, 0xCD,
-0xD1, 0x49, 0xC0, 0xEC,
+ 0x00, 0xCC, 0xC0, 0xCD,
+ 0xD1, 0x49, 0xC0, 0xEC,
-0x8A, 0x1F, 0x20, 0xE9,
-0x8B, 0x3F, 0x20, 0xE9,
+ 0x8A, 0x1F, 0x20, 0xE9,
+ 0x8B, 0x3F, 0x20, 0xE9,
-0x41, 0x3C, 0x41, 0xAD,
-0x49, 0x3C, 0x49, 0xAD,
+ 0x41, 0x3C, 0x41, 0xAD,
+ 0x49, 0x3C, 0x49, 0xAD,
-0x10, 0xCC, 0x10, 0xCD,
-0x08, 0xCC, 0x08, 0xCD,
+ 0x10, 0xCC, 0x10, 0xCD,
+ 0x08, 0xCC, 0x08, 0xCD,
-0xB9, 0x41, 0x49, 0xBB,
-0x1F, 0xF0, 0x41, 0xCD,
+ 0xB9, 0x41, 0x49, 0xBB,
+ 0x1F, 0xF0, 0x41, 0xCD,
-0x51, 0x3C, 0x51, 0xAD,
-0x00, 0x98, 0x80, 0xE9,
+ 0x51, 0x3C, 0x51, 0xAD,
+ 0x00, 0x98, 0x80, 0xE9,
-0x83, 0x80, 0x07, 0xEA,
-0x24, 0x1F, 0x20, 0xE9,
+ 0x83, 0x80, 0x07, 0xEA,
+ 0x24, 0x1F, 0x20, 0xE9,
-0x21, 0x45, 0x80, 0xE8,
-0x1A, 0x4D, 0x80, 0xE8,
+ 0x21, 0x45, 0x80, 0xE8,
+ 0x1A, 0x4D, 0x80, 0xE8,
-0x31, 0x55, 0x80, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x31, 0x55, 0x80, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x15, 0x41, 0x49, 0xBD,
-0x1D, 0x41, 0x51, 0xBD,
+ 0x15, 0x41, 0x49, 0xBD,
+ 0x1D, 0x41, 0x51, 0xBD,
-0x2E, 0x41, 0x2A, 0xB8,
-0x34, 0x53, 0xA0, 0xE8,
+ 0x2E, 0x41, 0x2A, 0xB8,
+ 0x34, 0x53, 0xA0, 0xE8,
-0x15, 0x30,
-0x1D, 0x30,
-0x58, 0xE3,
-0x00, 0xE0,
+ 0x15, 0x30,
+ 0x1D, 0x30,
+ 0x58, 0xE3,
+ 0x00, 0xE0,
-0xB5, 0x40, 0x48, 0xBD,
-0x3D, 0x40, 0x50, 0xBD,
+ 0xB5, 0x40, 0x48, 0xBD,
+ 0x3D, 0x40, 0x50, 0xBD,
-0x24, 0x43, 0xA0, 0xE8,
-0x2C, 0x4B, 0xA0, 0xE8,
+ 0x24, 0x43, 0xA0, 0xE8,
+ 0x2C, 0x4B, 0xA0, 0xE8,
-0x15, 0x72,
-0x09, 0xE3,
-0x00, 0xE0,
-0x1D, 0x72,
+ 0x15, 0x72,
+ 0x09, 0xE3,
+ 0x00, 0xE0,
+ 0x1D, 0x72,
-0x35, 0x30,
-0xB5, 0x30,
-0xBD, 0x30,
-0x3D, 0x30,
+ 0x35, 0x30,
+ 0xB5, 0x30,
+ 0xBD, 0x30,
+ 0x3D, 0x30,
-0x9C, 0x97, 0x57, 0x9F,
-0x00, 0x80, 0x00, 0xE8,
+ 0x9C, 0x97, 0x57, 0x9F,
+ 0x00, 0x80, 0x00, 0xE8,
-0x6C, 0x64, 0xC8, 0xEC,
-0x98, 0xE1,
-0xB5, 0x05,
+ 0x6C, 0x64, 0xC8, 0xEC,
+ 0x98, 0xE1,
+ 0xB5, 0x05,
-0xBD, 0x05,
-0x2E, 0x30,
-0x32, 0xC0, 0xA0, 0xE8,
+ 0xBD, 0x05,
+ 0x2E, 0x30,
+ 0x32, 0xC0, 0xA0, 0xE8,
-0x33, 0xC0, 0xA0, 0xE8,
-0x74, 0x64, 0xC8, 0xEC,
+ 0x33, 0xC0, 0xA0, 0xE8,
+ 0x74, 0x64, 0xC8, 0xEC,
-0x40, 0x3C, 0x40, 0xAD,
-0x32, 0x6A,
-0x2A, 0x30,
+ 0x40, 0x3C, 0x40, 0xAD,
+ 0x32, 0x6A,
+ 0x2A, 0x30,
-0x20, 0x73,
-0x33, 0x6A,
-0x00, 0xE0,
-0x28, 0x73,
+ 0x20, 0x73,
+ 0x33, 0x6A,
+ 0x00, 0xE0,
+ 0x28, 0x73,
-0x1C, 0x72,
-0x83, 0xE2,
-0x6F, 0x80, 0x15, 0xEA,
+ 0x1C, 0x72,
+ 0x83, 0xE2,
+ 0x6F, 0x80, 0x15, 0xEA,
-0xB8, 0x3D, 0x28, 0xDF,
-0x30, 0x35, 0x20, 0xDF,
+ 0xB8, 0x3D, 0x28, 0xDF,
+ 0x30, 0x35, 0x20, 0xDF,
-0x40, 0x30,
-0x00, 0xE0,
-0xCC, 0xE2,
-0x64, 0x72,
+ 0x40, 0x30,
+ 0x00, 0xE0,
+ 0xCC, 0xE2,
+ 0x64, 0x72,
-0x25, 0x42, 0x52, 0xBF,
-0x2D, 0x42, 0x4A, 0xBF,
+ 0x25, 0x42, 0x52, 0xBF,
+ 0x2D, 0x42, 0x4A, 0xBF,
-0x30, 0x2E, 0x30, 0xDF,
-0x38, 0x2E, 0x38, 0xDF,
+ 0x30, 0x2E, 0x30, 0xDF,
+ 0x38, 0x2E, 0x38, 0xDF,
-0x18, 0x1D, 0x45, 0xE9,
-0x1E, 0x15, 0x45, 0xE9,
+ 0x18, 0x1D, 0x45, 0xE9,
+ 0x1E, 0x15, 0x45, 0xE9,
-0x2B, 0x49, 0x51, 0xBD,
-0x00, 0xE0,
-0x1F, 0x73,
+ 0x2B, 0x49, 0x51, 0xBD,
+ 0x00, 0xE0,
+ 0x1F, 0x73,
-0x38, 0x38, 0x40, 0xAF,
-0x30, 0x30, 0x40, 0xAF,
+ 0x38, 0x38, 0x40, 0xAF,
+ 0x30, 0x30, 0x40, 0xAF,
-0x24, 0x1F, 0x24, 0xDF,
-0x1D, 0x32, 0x20, 0xE9,
+ 0x24, 0x1F, 0x24, 0xDF,
+ 0x1D, 0x32, 0x20, 0xE9,
-0x2C, 0x1F, 0x2C, 0xDF,
-0x1A, 0x33, 0x20, 0xE9,
+ 0x2C, 0x1F, 0x2C, 0xDF,
+ 0x1A, 0x33, 0x20, 0xE9,
-0xB0, 0x10,
-0x08, 0xE3,
-0x40, 0x10,
-0xB8, 0x10,
+ 0xB0, 0x10,
+ 0x08, 0xE3,
+ 0x40, 0x10,
+ 0xB8, 0x10,
-0x26, 0xF0, 0x30, 0xCD,
-0x2F, 0xF0, 0x38, 0xCD,
+ 0x26, 0xF0, 0x30, 0xCD,
+ 0x2F, 0xF0, 0x38, 0xCD,
-0x2B, 0x80, 0x20, 0xE9,
-0x2A, 0x80, 0x20, 0xE9,
+ 0x2B, 0x80, 0x20, 0xE9,
+ 0x2A, 0x80, 0x20, 0xE9,
-0xA6, 0x20,
-0x88, 0xE2,
-0x00, 0xE0,
-0xAF, 0x20,
+ 0xA6, 0x20,
+ 0x88, 0xE2,
+ 0x00, 0xE0,
+ 0xAF, 0x20,
-0x28, 0x2A, 0x26, 0xAF,
-0x20, 0x2A, 0xC0, 0xAF,
+ 0x28, 0x2A, 0x26, 0xAF,
+ 0x20, 0x2A, 0xC0, 0xAF,
-0x34, 0x1F, 0x34, 0xDF,
-0x46, 0x24, 0x46, 0xDF,
+ 0x34, 0x1F, 0x34, 0xDF,
+ 0x46, 0x24, 0x46, 0xDF,
-0x28, 0x30, 0x80, 0xBF,
-0x20, 0x38, 0x80, 0xBF,
+ 0x28, 0x30, 0x80, 0xBF,
+ 0x20, 0x38, 0x80, 0xBF,
-0x47, 0x24, 0x47, 0xDF,
-0x4E, 0x2C, 0x4E, 0xDF,
+ 0x47, 0x24, 0x47, 0xDF,
+ 0x4E, 0x2C, 0x4E, 0xDF,
-0x4F, 0x2C, 0x4F, 0xDF,
-0x56, 0x34, 0x56, 0xDF,
+ 0x4F, 0x2C, 0x4F, 0xDF,
+ 0x56, 0x34, 0x56, 0xDF,
-0x28, 0x15, 0x28, 0xDF,
-0x20, 0x1D, 0x20, 0xDF,
+ 0x28, 0x15, 0x28, 0xDF,
+ 0x20, 0x1D, 0x20, 0xDF,
-0x57, 0x34, 0x57, 0xDF,
-0x00, 0xE0,
-0x1D, 0x05,
+ 0x57, 0x34, 0x57, 0xDF,
+ 0x00, 0xE0,
+ 0x1D, 0x05,
-0x04, 0x80, 0x10, 0xEA,
-0x89, 0xE2,
-0x2B, 0x30,
+ 0x04, 0x80, 0x10, 0xEA,
+ 0x89, 0xE2,
+ 0x2B, 0x30,
-0x3F, 0xC1, 0x1D, 0xBD,
-0x00, 0x80, 0x00, 0xE8,
+ 0x3F, 0xC1, 0x1D, 0xBD,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0xA0, 0x68,
-0xBF, 0x25,
-0x00, 0x80, 0x00, 0xE8,
+ 0xA0, 0x68,
+ 0xBF, 0x25,
+ 0x00, 0x80, 0x00, 0xE8,
-0x20, 0xC0, 0x20, 0xAF,
-0x28, 0x05,
-0x97, 0x74,
+ 0x20, 0xC0, 0x20, 0xAF,
+ 0x28, 0x05,
+ 0x97, 0x74,
-0x00, 0xE0,
-0x2A, 0x10,
-0x16, 0xC0, 0x20, 0xE9,
+ 0x00, 0xE0,
+ 0x2A, 0x10,
+ 0x16, 0xC0, 0x20, 0xE9,
-0x04, 0x80, 0x10, 0xEA,
-0x8C, 0xE2,
-0x95, 0x05,
+ 0x04, 0x80, 0x10, 0xEA,
+ 0x8C, 0xE2,
+ 0x95, 0x05,
-0x28, 0xC1, 0x28, 0xAD,
-0x1F, 0xC1, 0x15, 0xBD,
+ 0x28, 0xC1, 0x28, 0xAD,
+ 0x1F, 0xC1, 0x15, 0xBD,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0xA8, 0x67,
-0x9F, 0x6B,
-0x00, 0x80, 0x00, 0xE8,
+ 0xA8, 0x67,
+ 0x9F, 0x6B,
+ 0x00, 0x80, 0x00, 0xE8,
-0x28, 0xC0, 0x28, 0xAD,
-0x1D, 0x25,
-0x20, 0x05,
+ 0x28, 0xC0, 0x28, 0xAD,
+ 0x1D, 0x25,
+ 0x20, 0x05,
-0x28, 0x32, 0x80, 0xAD,
-0x40, 0x2A, 0x40, 0xBD,
+ 0x28, 0x32, 0x80, 0xAD,
+ 0x40, 0x2A, 0x40, 0xBD,
-0x1C, 0x80, 0x20, 0xE9,
-0x20, 0x33, 0x20, 0xAD,
+ 0x1C, 0x80, 0x20, 0xE9,
+ 0x20, 0x33, 0x20, 0xAD,
-0x20, 0x73,
-0x00, 0xE0,
-0xB6, 0x49, 0x51, 0xBB,
+ 0x20, 0x73,
+ 0x00, 0xE0,
+ 0xB6, 0x49, 0x51, 0xBB,
-0x26, 0x2F, 0xB0, 0xE8,
-0x19, 0x20, 0x20, 0xE9,
+ 0x26, 0x2F, 0xB0, 0xE8,
+ 0x19, 0x20, 0x20, 0xE9,
-0x35, 0x20, 0x35, 0xDF,
-0x3D, 0x20, 0x3D, 0xDF,
+ 0x35, 0x20, 0x35, 0xDF,
+ 0x3D, 0x20, 0x3D, 0xDF,
-0x15, 0x20, 0x15, 0xDF,
-0x1D, 0x20, 0x1D, 0xDF,
+ 0x15, 0x20, 0x15, 0xDF,
+ 0x1D, 0x20, 0x1D, 0xDF,
-0x26, 0xD0, 0x26, 0xCD,
-0x29, 0x49, 0x2A, 0xB8,
+ 0x26, 0xD0, 0x26, 0xCD,
+ 0x29, 0x49, 0x2A, 0xB8,
-0x26, 0x40, 0x80, 0xBD,
-0x3B, 0x48, 0x50, 0xBD,
+ 0x26, 0x40, 0x80, 0xBD,
+ 0x3B, 0x48, 0x50, 0xBD,
-0x3E, 0x54, 0x57, 0x9F,
-0x00, 0xE0,
-0x82, 0xE1,
+ 0x3E, 0x54, 0x57, 0x9F,
+ 0x00, 0xE0,
+ 0x82, 0xE1,
-0x1E, 0xAF, 0x59, 0x9F,
-0x00, 0x80, 0x00, 0xE8,
+ 0x1E, 0xAF, 0x59, 0x9F,
+ 0x00, 0x80, 0x00, 0xE8,
-0x26, 0x30,
-0x29, 0x30,
-0x48, 0x3C, 0x48, 0xAD,
+ 0x26, 0x30,
+ 0x29, 0x30,
+ 0x48, 0x3C, 0x48, 0xAD,
-0x2B, 0x72,
-0xC2, 0xE1,
-0x2C, 0xC0, 0x44, 0xC2,
+ 0x2B, 0x72,
+ 0xC2, 0xE1,
+ 0x2C, 0xC0, 0x44, 0xC2,
-0x05, 0x24, 0x34, 0xBF,
-0x0D, 0x24, 0x2C, 0xBF,
+ 0x05, 0x24, 0x34, 0xBF,
+ 0x0D, 0x24, 0x2C, 0xBF,
-0x2D, 0x46, 0x4E, 0xBF,
-0x25, 0x46, 0x56, 0xBF,
+ 0x2D, 0x46, 0x4E, 0xBF,
+ 0x25, 0x46, 0x56, 0xBF,
-0x20, 0x1D, 0x6F, 0x8F,
-0x32, 0x3E, 0x5F, 0xE9,
+ 0x20, 0x1D, 0x6F, 0x8F,
+ 0x32, 0x3E, 0x5F, 0xE9,
-0x3E, 0x50, 0x56, 0x9F,
-0x00, 0xE0,
-0x3B, 0x30,
+ 0x3E, 0x50, 0x56, 0x9F,
+ 0x00, 0xE0,
+ 0x3B, 0x30,
-0x1E, 0x8F, 0x51, 0x9F,
-0x33, 0x1E, 0x5F, 0xE9,
+ 0x1E, 0x8F, 0x51, 0x9F,
+ 0x33, 0x1E, 0x5F, 0xE9,
-0x05, 0x44, 0x54, 0xB2,
-0x0D, 0x44, 0x4C, 0xB2,
+ 0x05, 0x44, 0x54, 0xB2,
+ 0x0D, 0x44, 0x4C, 0xB2,
-0x19, 0xC0, 0xB0, 0xE8,
-0x34, 0xC0, 0x44, 0xC4,
+ 0x19, 0xC0, 0xB0, 0xE8,
+ 0x34, 0xC0, 0x44, 0xC4,
-0x33, 0x73,
-0x00, 0xE0,
-0x3E, 0x62, 0x57, 0x9F,
+ 0x33, 0x73,
+ 0x00, 0xE0,
+ 0x3E, 0x62, 0x57, 0x9F,
-0x1E, 0xAF, 0x59, 0x9F,
-0x00, 0xE0,
-0x0D, 0x20,
+ 0x1E, 0xAF, 0x59, 0x9F,
+ 0x00, 0xE0,
+ 0x0D, 0x20,
-0x84, 0x3E, 0x58, 0xE9,
-0x28, 0x1D, 0x6F, 0x8F,
+ 0x84, 0x3E, 0x58, 0xE9,
+ 0x28, 0x1D, 0x6F, 0x8F,
-0x05, 0x20,
-0x00, 0xE0,
-0x85, 0x1E, 0x58, 0xE9,
+ 0x05, 0x20,
+ 0x00, 0xE0,
+ 0x85, 0x1E, 0x58, 0xE9,
-0x9B, 0x3B, 0x33, 0xDF,
-0x20, 0x20, 0x42, 0xAF,
+ 0x9B, 0x3B, 0x33, 0xDF,
+ 0x20, 0x20, 0x42, 0xAF,
-0x30, 0x42, 0x56, 0x9F,
-0x80, 0x3E, 0x57, 0xE9,
+ 0x30, 0x42, 0x56, 0x9F,
+ 0x80, 0x3E, 0x57, 0xE9,
-0x3F, 0x8F, 0x51, 0x9F,
-0x30, 0x80, 0x5F, 0xE9,
+ 0x3F, 0x8F, 0x51, 0x9F,
+ 0x30, 0x80, 0x5F, 0xE9,
-0x28, 0x28, 0x24, 0xAF,
-0x81, 0x1E, 0x57, 0xE9,
+ 0x28, 0x28, 0x24, 0xAF,
+ 0x81, 0x1E, 0x57, 0xE9,
-0x05, 0x47, 0x57, 0xBF,
-0x0D, 0x47, 0x4F, 0xBF,
+ 0x05, 0x47, 0x57, 0xBF,
+ 0x0D, 0x47, 0x4F, 0xBF,
-0x88, 0x80, 0x58, 0xE9,
-0x1B, 0x29, 0x1B, 0xDF,
+ 0x88, 0x80, 0x58, 0xE9,
+ 0x1B, 0x29, 0x1B, 0xDF,
-0x30, 0x1D, 0x6F, 0x8F,
-0x3A, 0x30, 0x4F, 0xE9,
+ 0x30, 0x1D, 0x6F, 0x8F,
+ 0x3A, 0x30, 0x4F, 0xE9,
-0x1C, 0x30, 0x26, 0xDF,
-0x09, 0xE3,
-0x3B, 0x05,
+ 0x1C, 0x30, 0x26, 0xDF,
+ 0x09, 0xE3,
+ 0x3B, 0x05,
-0x3E, 0x50, 0x56, 0x9F,
-0x3B, 0x3F, 0x4F, 0xE9,
+ 0x3E, 0x50, 0x56, 0x9F,
+ 0x3B, 0x3F, 0x4F, 0xE9,
-0x1E, 0x8F, 0x51, 0x9F,
-0x00, 0xE0,
-0xAC, 0x20,
+ 0x1E, 0x8F, 0x51, 0x9F,
+ 0x00, 0xE0,
+ 0xAC, 0x20,
-0x2D, 0x44, 0x4C, 0xB4,
-0x2C, 0x1C, 0xC0, 0xAF,
+ 0x2D, 0x44, 0x4C, 0xB4,
+ 0x2C, 0x1C, 0xC0, 0xAF,
-0x25, 0x44, 0x54, 0xB4,
-0x00, 0xE0,
-0xC8, 0x30,
+ 0x25, 0x44, 0x54, 0xB4,
+ 0x00, 0xE0,
+ 0xC8, 0x30,
-0x30, 0x46, 0x30, 0xAF,
-0x1B, 0x1B, 0x48, 0xAF,
+ 0x30, 0x46, 0x30, 0xAF,
+ 0x1B, 0x1B, 0x48, 0xAF,
-0x00, 0xE0,
-0x25, 0x20,
-0x38, 0x2C, 0x4F, 0xE9,
+ 0x00, 0xE0,
+ 0x25, 0x20,
+ 0x38, 0x2C, 0x4F, 0xE9,
-0x86, 0x80, 0x57, 0xE9,
-0x38, 0x1D, 0x6F, 0x8F,
+ 0x86, 0x80, 0x57, 0xE9,
+ 0x38, 0x1D, 0x6F, 0x8F,
-0x28, 0x74,
-0x00, 0xE0,
-0x0D, 0x44, 0x4C, 0xB0,
+ 0x28, 0x74,
+ 0x00, 0xE0,
+ 0x0D, 0x44, 0x4C, 0xB0,
-0x05, 0x44, 0x54, 0xB0,
-0x2D, 0x20,
-0x9B, 0x10,
+ 0x05, 0x44, 0x54, 0xB0,
+ 0x2D, 0x20,
+ 0x9B, 0x10,
-0x82, 0x3E, 0x57, 0xE9,
-0x32, 0xF0, 0x1B, 0xCD,
+ 0x82, 0x3E, 0x57, 0xE9,
+ 0x32, 0xF0, 0x1B, 0xCD,
-0x1E, 0xBD, 0x59, 0x9F,
-0x83, 0x1E, 0x57, 0xE9,
+ 0x1E, 0xBD, 0x59, 0x9F,
+ 0x83, 0x1E, 0x57, 0xE9,
-0x38, 0x47, 0x38, 0xAF,
-0x34, 0x20,
-0x2A, 0x30,
+ 0x38, 0x47, 0x38, 0xAF,
+ 0x34, 0x20,
+ 0x2A, 0x30,
-0x00, 0xE0,
-0x0D, 0x20,
-0x32, 0x20,
-0x05, 0x20,
+ 0x00, 0xE0,
+ 0x0D, 0x20,
+ 0x32, 0x20,
+ 0x05, 0x20,
-0x87, 0x80, 0x57, 0xE9,
-0x1F, 0x54, 0x57, 0x9F,
+ 0x87, 0x80, 0x57, 0xE9,
+ 0x1F, 0x54, 0x57, 0x9F,
-0x17, 0x42, 0x56, 0x9F,
-0x00, 0xE0,
-0x3B, 0x6A,
+ 0x17, 0x42, 0x56, 0x9F,
+ 0x00, 0xE0,
+ 0x3B, 0x6A,
-0x3F, 0x8F, 0x51, 0x9F,
-0x37, 0x1E, 0x4F, 0xE9,
+ 0x3F, 0x8F, 0x51, 0x9F,
+ 0x37, 0x1E, 0x4F, 0xE9,
-0x37, 0x32, 0x2A, 0xAF,
-0x00, 0xE0,
-0x32, 0x00,
+ 0x37, 0x32, 0x2A, 0xAF,
+ 0x00, 0xE0,
+ 0x32, 0x00,
-0x00, 0x80, 0x00, 0xE8,
-0x27, 0xC0, 0x44, 0xC0,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x27, 0xC0, 0x44, 0xC0,
-0x36, 0x1F, 0x4F, 0xE9,
-0x1F, 0x1F, 0x26, 0xDF,
+ 0x36, 0x1F, 0x4F, 0xE9,
+ 0x1F, 0x1F, 0x26, 0xDF,
-0x37, 0x1B, 0x37, 0xBF,
-0x17, 0x26, 0x17, 0xDF,
+ 0x37, 0x1B, 0x37, 0xBF,
+ 0x17, 0x26, 0x17, 0xDF,
-0x3E, 0x17, 0x4F, 0xE9,
-0x3F, 0x3F, 0x4F, 0xE9,
+ 0x3E, 0x17, 0x4F, 0xE9,
+ 0x3F, 0x3F, 0x4F, 0xE9,
-0x34, 0x1F, 0x34, 0xAF,
-0x2B, 0x05,
-0xA7, 0x20,
+ 0x34, 0x1F, 0x34, 0xAF,
+ 0x2B, 0x05,
+ 0xA7, 0x20,
-0x33, 0x2B, 0x37, 0xDF,
-0x27, 0x17, 0xC0, 0xAF,
+ 0x33, 0x2B, 0x37, 0xDF,
+ 0x27, 0x17, 0xC0, 0xAF,
-0x34, 0x80, 0x4F, 0xE9,
-0x00, 0x80, 0x00, 0xE8,
+ 0x34, 0x80, 0x4F, 0xE9,
+ 0x00, 0x80, 0x00, 0xE8,
-0x0D, 0x21, 0x1A, 0xB6,
-0x05, 0x21, 0x31, 0xB6,
+ 0x0D, 0x21, 0x1A, 0xB6,
+ 0x05, 0x21, 0x31, 0xB6,
-0x2D, 0x44, 0x4C, 0xB6,
-0x25, 0x44, 0x54, 0xB6,
+ 0x2D, 0x44, 0x4C, 0xB6,
+ 0x25, 0x44, 0x54, 0xB6,
-0x03, 0x80, 0x2A, 0xEA,
-0x17, 0xC1, 0x2B, 0xBD,
+ 0x03, 0x80, 0x2A, 0xEA,
+ 0x17, 0xC1, 0x2B, 0xBD,
-0x0D, 0x20,
-0x05, 0x20,
-0x2F, 0xC0, 0x21, 0xC6,
+ 0x0D, 0x20,
+ 0x05, 0x20,
+ 0x2F, 0xC0, 0x21, 0xC6,
-0xB3, 0x68,
-0x97, 0x25,
-0x00, 0x80, 0x00, 0xE8,
+ 0xB3, 0x68,
+ 0x97, 0x25,
+ 0x00, 0x80, 0x00, 0xE8,
-0x33, 0xC0, 0x33, 0xAF,
-0x3C, 0x27, 0x4F, 0xE9,
+ 0x33, 0xC0, 0x33, 0xAF,
+ 0x3C, 0x27, 0x4F, 0xE9,
-0x00, 0xE0,
-0x25, 0x20,
-0x07, 0xC0, 0x44, 0xC6,
+ 0x00, 0xE0,
+ 0x25, 0x20,
+ 0x07, 0xC0, 0x44, 0xC6,
-0x17, 0x50, 0x56, 0x9F,
-0x00, 0xE0,
-0x2D, 0x20,
+ 0x17, 0x50, 0x56, 0x9F,
+ 0x00, 0xE0,
+ 0x2D, 0x20,
-0x37, 0x0F, 0x5C, 0x9F,
-0x00, 0xE0,
-0x2F, 0x20,
+ 0x37, 0x0F, 0x5C, 0x9F,
+ 0x00, 0xE0,
+ 0x2F, 0x20,
-0x1F, 0x62, 0x57, 0x9F,
-0x00, 0xE0,
-0x07, 0x20,
+ 0x1F, 0x62, 0x57, 0x9F,
+ 0x00, 0xE0,
+ 0x07, 0x20,
-0x3F, 0x3D, 0x5D, 0x9F,
-0x00, 0x80, 0x00, 0xE8,
+ 0x3F, 0x3D, 0x5D, 0x9F,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x28, 0x19, 0x60, 0xEC,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x28, 0x19, 0x60, 0xEC,
-0xB3, 0x05,
-0x00, 0xE0,
-0x17, 0x26, 0x17, 0xDF,
+ 0xB3, 0x05,
+ 0x00, 0xE0,
+ 0x17, 0x26, 0x17, 0xDF,
-0x23, 0x3B, 0x33, 0xAD,
-0x35, 0x17, 0x4F, 0xE9,
+ 0x23, 0x3B, 0x33, 0xAD,
+ 0x35, 0x17, 0x4F, 0xE9,
-0x1F, 0x26, 0x1F, 0xDF,
-0x9D, 0x1F, 0x4F, 0xE9,
+ 0x1F, 0x26, 0x1F, 0xDF,
+ 0x9D, 0x1F, 0x4F, 0xE9,
-0x9E, 0x3F, 0x4F, 0xE9,
-0x39, 0x37, 0x4F, 0xE9,
+ 0x9E, 0x3F, 0x4F, 0xE9,
+ 0x39, 0x37, 0x4F, 0xE9,
-0x2F, 0x2F, 0x17, 0xAF,
-0x00, 0x80, 0x00, 0xE8,
+ 0x2F, 0x2F, 0x17, 0xAF,
+ 0x00, 0x80, 0x00, 0xE8,
-0x07, 0x07, 0x1F, 0xAF,
-0x00, 0x80, 0x00, 0xE8,
+ 0x07, 0x07, 0x1F, 0xAF,
+ 0x00, 0x80, 0x00, 0xE8,
-0x31, 0x80, 0x4F, 0xE9,
-0x00, 0x80, 0x00, 0xE8,
+ 0x31, 0x80, 0x4F, 0xE9,
+ 0x00, 0x80, 0x00, 0xE8,
-0x9C, 0x80, 0x4F, 0xE9,
-0x00, 0x80, 0x00, 0xE8,
+ 0x9C, 0x80, 0x4F, 0xE9,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x57, 0x39, 0x20, 0xE9,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x57, 0x39, 0x20, 0xE9,
-0x16, 0x28, 0x20, 0xE9,
-0x1D, 0x3B, 0x20, 0xE9,
+ 0x16, 0x28, 0x20, 0xE9,
+ 0x1D, 0x3B, 0x20, 0xE9,
-0x1E, 0x2B, 0x20, 0xE9,
-0x2B, 0x32, 0x20, 0xE9,
+ 0x1E, 0x2B, 0x20, 0xE9,
+ 0x2B, 0x32, 0x20, 0xE9,
-0x1C, 0x23, 0x20, 0xE9,
-0x57, 0x36, 0x20, 0xE9,
+ 0x1C, 0x23, 0x20, 0xE9,
+ 0x57, 0x36, 0x20, 0xE9,
-0x00, 0x80, 0xA0, 0xE9,
-0x40, 0x40, 0xD8, 0xEC,
+ 0x00, 0x80, 0xA0, 0xE9,
+ 0x40, 0x40, 0xD8, 0xEC,
-0xFF, 0x80, 0xC0, 0xE9,
-0x90, 0xE2,
-0x00, 0xE0,
+ 0xFF, 0x80, 0xC0, 0xE9,
+ 0x90, 0xE2,
+ 0x00, 0xE0,
-0x74, 0xFF, 0x20, 0xEA,
-0x19, 0xC8, 0xC1, 0xCD,
+ 0x74, 0xFF, 0x20, 0xEA,
+ 0x19, 0xC8, 0xC1, 0xCD,
-0x1F, 0xD7, 0x18, 0xBD,
-0x3F, 0xD7, 0x22, 0xBD,
+ 0x1F, 0xD7, 0x18, 0xBD,
+ 0x3F, 0xD7, 0x22, 0xBD,
-0x9F, 0x41, 0x49, 0xBD,
-0x00, 0x80, 0x00, 0xE8,
+ 0x9F, 0x41, 0x49, 0xBD,
+ 0x00, 0x80, 0x00, 0xE8,
-0x25, 0x41, 0x49, 0xBD,
-0x2D, 0x41, 0x51, 0xBD,
+ 0x25, 0x41, 0x49, 0xBD,
+ 0x2D, 0x41, 0x51, 0xBD,
-0x0D, 0x80, 0x07, 0xEA,
-0x00, 0x80, 0x00, 0xE8,
+ 0x0D, 0x80, 0x07, 0xEA,
+ 0x00, 0x80, 0x00, 0xE8,
-0x35, 0x40, 0x48, 0xBD,
-0x3D, 0x40, 0x50, 0xBD,
+ 0x35, 0x40, 0x48, 0xBD,
+ 0x3D, 0x40, 0x50, 0xBD,
-0x00, 0x80, 0x00, 0xE8,
-0x25, 0x30,
-0x2D, 0x30,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x25, 0x30,
+ 0x2D, 0x30,
-0x35, 0x30,
-0xB5, 0x30,
-0xBD, 0x30,
-0x3D, 0x30,
+ 0x35, 0x30,
+ 0xB5, 0x30,
+ 0xBD, 0x30,
+ 0x3D, 0x30,
-0x9C, 0xA7, 0x5B, 0x9F,
-0x00, 0x80, 0x00, 0xE8,
+ 0x9C, 0xA7, 0x5B, 0x9F,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x73, 0xFF, 0x0A, 0xEA,
-0x00, 0x80, 0x00, 0xE8,
+ 0x73, 0xFF, 0x0A, 0xEA,
+ 0x00, 0x80, 0x00, 0xE8,
-0xC9, 0x41, 0xC8, 0xEC,
-0x42, 0xE1,
-0x00, 0xE0,
+ 0xC9, 0x41, 0xC8, 0xEC,
+ 0x42, 0xE1,
+ 0x00, 0xE0,
-0x71, 0xFF, 0x20, 0xEA,
-0x00, 0x80, 0x00, 0xE8,
+ 0x71, 0xFF, 0x20, 0xEA,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0xC8, 0x40, 0xC0, 0xEC,
-0x00, 0x80, 0x00, 0xE8,
+ 0xC8, 0x40, 0xC0, 0xEC,
+ 0x00, 0x80, 0x00, 0xE8,
-0x6E, 0xFF, 0x20, 0xEA,
-0x00, 0x80, 0x00, 0xE8,
+ 0x6E, 0xFF, 0x20, 0xEA,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
};
static unsigned char warp_g200_tgzf[] = {
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x98, 0xA0, 0xE9,
-0x40, 0x40, 0xD8, 0xEC,
+ 0x00, 0x98, 0xA0, 0xE9,
+ 0x40, 0x40, 0xD8, 0xEC,
-0xFF, 0x80, 0xC0, 0xE9,
-0x00, 0x80, 0x00, 0xE8,
+ 0xFF, 0x80, 0xC0, 0xE9,
+ 0x00, 0x80, 0x00, 0xE8,
-0x1F, 0xD7, 0x18, 0xBD,
-0x3F, 0xD7, 0x22, 0xBD,
+ 0x1F, 0xD7, 0x18, 0xBD,
+ 0x3F, 0xD7, 0x22, 0xBD,
-0x81, 0x04,
-0x89, 0x04,
-0x01, 0x04,
-0x09, 0x04,
+ 0x81, 0x04,
+ 0x89, 0x04,
+ 0x01, 0x04,
+ 0x09, 0x04,
-0xC9, 0x41, 0xC0, 0xEC,
-0x11, 0x04,
-0x00, 0xE0,
+ 0xC9, 0x41, 0xC0, 0xEC,
+ 0x11, 0x04,
+ 0x00, 0xE0,
-0x41, 0xCC, 0x41, 0xCD,
-0x49, 0xCC, 0x49, 0xCD,
+ 0x41, 0xCC, 0x41, 0xCD,
+ 0x49, 0xCC, 0x49, 0xCD,
-0xD1, 0x41, 0xC0, 0xEC,
-0x51, 0xCC, 0x51, 0xCD,
+ 0xD1, 0x41, 0xC0, 0xEC,
+ 0x51, 0xCC, 0x51, 0xCD,
-0x80, 0x04,
-0x10, 0x04,
-0x08, 0x04,
-0x00, 0xE0,
+ 0x80, 0x04,
+ 0x10, 0x04,
+ 0x08, 0x04,
+ 0x00, 0xE0,
-0x00, 0xCC, 0xC0, 0xCD,
-0xD1, 0x49, 0xC0, 0xEC,
+ 0x00, 0xCC, 0xC0, 0xCD,
+ 0xD1, 0x49, 0xC0, 0xEC,
-0x8A, 0x1F, 0x20, 0xE9,
-0x8B, 0x3F, 0x20, 0xE9,
+ 0x8A, 0x1F, 0x20, 0xE9,
+ 0x8B, 0x3F, 0x20, 0xE9,
-0x41, 0x3C, 0x41, 0xAD,
-0x49, 0x3C, 0x49, 0xAD,
+ 0x41, 0x3C, 0x41, 0xAD,
+ 0x49, 0x3C, 0x49, 0xAD,
-0x10, 0xCC, 0x10, 0xCD,
-0x08, 0xCC, 0x08, 0xCD,
+ 0x10, 0xCC, 0x10, 0xCD,
+ 0x08, 0xCC, 0x08, 0xCD,
-0xB9, 0x41, 0x49, 0xBB,
-0x1F, 0xF0, 0x41, 0xCD,
+ 0xB9, 0x41, 0x49, 0xBB,
+ 0x1F, 0xF0, 0x41, 0xCD,
-0x51, 0x3C, 0x51, 0xAD,
-0x00, 0x98, 0x80, 0xE9,
+ 0x51, 0x3C, 0x51, 0xAD,
+ 0x00, 0x98, 0x80, 0xE9,
-0x7F, 0x80, 0x07, 0xEA,
-0x24, 0x1F, 0x20, 0xE9,
+ 0x7F, 0x80, 0x07, 0xEA,
+ 0x24, 0x1F, 0x20, 0xE9,
-0x21, 0x45, 0x80, 0xE8,
-0x1A, 0x4D, 0x80, 0xE8,
+ 0x21, 0x45, 0x80, 0xE8,
+ 0x1A, 0x4D, 0x80, 0xE8,
-0x31, 0x55, 0x80, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x31, 0x55, 0x80, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x15, 0x41, 0x49, 0xBD,
-0x1D, 0x41, 0x51, 0xBD,
+ 0x15, 0x41, 0x49, 0xBD,
+ 0x1D, 0x41, 0x51, 0xBD,
-0x2E, 0x41, 0x2A, 0xB8,
-0x34, 0x53, 0xA0, 0xE8,
+ 0x2E, 0x41, 0x2A, 0xB8,
+ 0x34, 0x53, 0xA0, 0xE8,
-0x15, 0x30,
-0x1D, 0x30,
-0x58, 0xE3,
-0x00, 0xE0,
+ 0x15, 0x30,
+ 0x1D, 0x30,
+ 0x58, 0xE3,
+ 0x00, 0xE0,
-0xB5, 0x40, 0x48, 0xBD,
-0x3D, 0x40, 0x50, 0xBD,
+ 0xB5, 0x40, 0x48, 0xBD,
+ 0x3D, 0x40, 0x50, 0xBD,
-0x24, 0x43, 0xA0, 0xE8,
-0x2C, 0x4B, 0xA0, 0xE8,
+ 0x24, 0x43, 0xA0, 0xE8,
+ 0x2C, 0x4B, 0xA0, 0xE8,
-0x15, 0x72,
-0x09, 0xE3,
-0x00, 0xE0,
-0x1D, 0x72,
+ 0x15, 0x72,
+ 0x09, 0xE3,
+ 0x00, 0xE0,
+ 0x1D, 0x72,
-0x35, 0x30,
-0xB5, 0x30,
-0xBD, 0x30,
-0x3D, 0x30,
+ 0x35, 0x30,
+ 0xB5, 0x30,
+ 0xBD, 0x30,
+ 0x3D, 0x30,
-0x9C, 0x97, 0x57, 0x9F,
-0x00, 0x80, 0x00, 0xE8,
+ 0x9C, 0x97, 0x57, 0x9F,
+ 0x00, 0x80, 0x00, 0xE8,
-0x6C, 0x64, 0xC8, 0xEC,
-0x98, 0xE1,
-0xB5, 0x05,
+ 0x6C, 0x64, 0xC8, 0xEC,
+ 0x98, 0xE1,
+ 0xB5, 0x05,
-0xBD, 0x05,
-0x2E, 0x30,
-0x32, 0xC0, 0xA0, 0xE8,
+ 0xBD, 0x05,
+ 0x2E, 0x30,
+ 0x32, 0xC0, 0xA0, 0xE8,
-0x33, 0xC0, 0xA0, 0xE8,
-0x74, 0x64, 0xC8, 0xEC,
+ 0x33, 0xC0, 0xA0, 0xE8,
+ 0x74, 0x64, 0xC8, 0xEC,
-0x40, 0x3C, 0x40, 0xAD,
-0x32, 0x6A,
-0x2A, 0x30,
+ 0x40, 0x3C, 0x40, 0xAD,
+ 0x32, 0x6A,
+ 0x2A, 0x30,
-0x20, 0x73,
-0x33, 0x6A,
-0x00, 0xE0,
-0x28, 0x73,
+ 0x20, 0x73,
+ 0x33, 0x6A,
+ 0x00, 0xE0,
+ 0x28, 0x73,
-0x1C, 0x72,
-0x83, 0xE2,
-0x6B, 0x80, 0x15, 0xEA,
+ 0x1C, 0x72,
+ 0x83, 0xE2,
+ 0x6B, 0x80, 0x15, 0xEA,
-0xB8, 0x3D, 0x28, 0xDF,
-0x30, 0x35, 0x20, 0xDF,
+ 0xB8, 0x3D, 0x28, 0xDF,
+ 0x30, 0x35, 0x20, 0xDF,
-0x40, 0x30,
-0x00, 0xE0,
-0xCC, 0xE2,
-0x64, 0x72,
+ 0x40, 0x30,
+ 0x00, 0xE0,
+ 0xCC, 0xE2,
+ 0x64, 0x72,
-0x25, 0x42, 0x52, 0xBF,
-0x2D, 0x42, 0x4A, 0xBF,
+ 0x25, 0x42, 0x52, 0xBF,
+ 0x2D, 0x42, 0x4A, 0xBF,
-0x30, 0x2E, 0x30, 0xDF,
-0x38, 0x2E, 0x38, 0xDF,
+ 0x30, 0x2E, 0x30, 0xDF,
+ 0x38, 0x2E, 0x38, 0xDF,
-0x18, 0x1D, 0x45, 0xE9,
-0x1E, 0x15, 0x45, 0xE9,
+ 0x18, 0x1D, 0x45, 0xE9,
+ 0x1E, 0x15, 0x45, 0xE9,
-0x2B, 0x49, 0x51, 0xBD,
-0x00, 0xE0,
-0x1F, 0x73,
+ 0x2B, 0x49, 0x51, 0xBD,
+ 0x00, 0xE0,
+ 0x1F, 0x73,
-0x38, 0x38, 0x40, 0xAF,
-0x30, 0x30, 0x40, 0xAF,
+ 0x38, 0x38, 0x40, 0xAF,
+ 0x30, 0x30, 0x40, 0xAF,
-0x24, 0x1F, 0x24, 0xDF,
-0x1D, 0x32, 0x20, 0xE9,
+ 0x24, 0x1F, 0x24, 0xDF,
+ 0x1D, 0x32, 0x20, 0xE9,
-0x2C, 0x1F, 0x2C, 0xDF,
-0x1A, 0x33, 0x20, 0xE9,
+ 0x2C, 0x1F, 0x2C, 0xDF,
+ 0x1A, 0x33, 0x20, 0xE9,
-0xB0, 0x10,
-0x08, 0xE3,
-0x40, 0x10,
-0xB8, 0x10,
+ 0xB0, 0x10,
+ 0x08, 0xE3,
+ 0x40, 0x10,
+ 0xB8, 0x10,
-0x26, 0xF0, 0x30, 0xCD,
-0x2F, 0xF0, 0x38, 0xCD,
+ 0x26, 0xF0, 0x30, 0xCD,
+ 0x2F, 0xF0, 0x38, 0xCD,
-0x2B, 0x80, 0x20, 0xE9,
-0x2A, 0x80, 0x20, 0xE9,
+ 0x2B, 0x80, 0x20, 0xE9,
+ 0x2A, 0x80, 0x20, 0xE9,
-0xA6, 0x20,
-0x88, 0xE2,
-0x00, 0xE0,
-0xAF, 0x20,
+ 0xA6, 0x20,
+ 0x88, 0xE2,
+ 0x00, 0xE0,
+ 0xAF, 0x20,
-0x28, 0x2A, 0x26, 0xAF,
-0x20, 0x2A, 0xC0, 0xAF,
+ 0x28, 0x2A, 0x26, 0xAF,
+ 0x20, 0x2A, 0xC0, 0xAF,
-0x34, 0x1F, 0x34, 0xDF,
-0x46, 0x24, 0x46, 0xDF,
+ 0x34, 0x1F, 0x34, 0xDF,
+ 0x46, 0x24, 0x46, 0xDF,
-0x28, 0x30, 0x80, 0xBF,
-0x20, 0x38, 0x80, 0xBF,
+ 0x28, 0x30, 0x80, 0xBF,
+ 0x20, 0x38, 0x80, 0xBF,
-0x47, 0x24, 0x47, 0xDF,
-0x4E, 0x2C, 0x4E, 0xDF,
+ 0x47, 0x24, 0x47, 0xDF,
+ 0x4E, 0x2C, 0x4E, 0xDF,
-0x4F, 0x2C, 0x4F, 0xDF,
-0x56, 0x34, 0x56, 0xDF,
+ 0x4F, 0x2C, 0x4F, 0xDF,
+ 0x56, 0x34, 0x56, 0xDF,
-0x28, 0x15, 0x28, 0xDF,
-0x20, 0x1D, 0x20, 0xDF,
+ 0x28, 0x15, 0x28, 0xDF,
+ 0x20, 0x1D, 0x20, 0xDF,
-0x57, 0x34, 0x57, 0xDF,
-0x00, 0xE0,
-0x1D, 0x05,
+ 0x57, 0x34, 0x57, 0xDF,
+ 0x00, 0xE0,
+ 0x1D, 0x05,
-0x04, 0x80, 0x10, 0xEA,
-0x89, 0xE2,
-0x2B, 0x30,
+ 0x04, 0x80, 0x10, 0xEA,
+ 0x89, 0xE2,
+ 0x2B, 0x30,
-0x3F, 0xC1, 0x1D, 0xBD,
-0x00, 0x80, 0x00, 0xE8,
+ 0x3F, 0xC1, 0x1D, 0xBD,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0xA0, 0x68,
-0xBF, 0x25,
-0x00, 0x80, 0x00, 0xE8,
+ 0xA0, 0x68,
+ 0xBF, 0x25,
+ 0x00, 0x80, 0x00, 0xE8,
-0x20, 0xC0, 0x20, 0xAF,
-0x28, 0x05,
-0x97, 0x74,
+ 0x20, 0xC0, 0x20, 0xAF,
+ 0x28, 0x05,
+ 0x97, 0x74,
-0x00, 0xE0,
-0x2A, 0x10,
-0x16, 0xC0, 0x20, 0xE9,
+ 0x00, 0xE0,
+ 0x2A, 0x10,
+ 0x16, 0xC0, 0x20, 0xE9,
-0x04, 0x80, 0x10, 0xEA,
-0x8C, 0xE2,
-0x95, 0x05,
+ 0x04, 0x80, 0x10, 0xEA,
+ 0x8C, 0xE2,
+ 0x95, 0x05,
-0x28, 0xC1, 0x28, 0xAD,
-0x1F, 0xC1, 0x15, 0xBD,
+ 0x28, 0xC1, 0x28, 0xAD,
+ 0x1F, 0xC1, 0x15, 0xBD,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0xA8, 0x67,
-0x9F, 0x6B,
-0x00, 0x80, 0x00, 0xE8,
+ 0xA8, 0x67,
+ 0x9F, 0x6B,
+ 0x00, 0x80, 0x00, 0xE8,
-0x28, 0xC0, 0x28, 0xAD,
-0x1D, 0x25,
-0x20, 0x05,
+ 0x28, 0xC0, 0x28, 0xAD,
+ 0x1D, 0x25,
+ 0x20, 0x05,
-0x28, 0x32, 0x80, 0xAD,
-0x40, 0x2A, 0x40, 0xBD,
+ 0x28, 0x32, 0x80, 0xAD,
+ 0x40, 0x2A, 0x40, 0xBD,
-0x1C, 0x80, 0x20, 0xE9,
-0x20, 0x33, 0x20, 0xAD,
+ 0x1C, 0x80, 0x20, 0xE9,
+ 0x20, 0x33, 0x20, 0xAD,
-0x20, 0x73,
-0x00, 0xE0,
-0xB6, 0x49, 0x51, 0xBB,
+ 0x20, 0x73,
+ 0x00, 0xE0,
+ 0xB6, 0x49, 0x51, 0xBB,
-0x26, 0x2F, 0xB0, 0xE8,
-0x19, 0x20, 0x20, 0xE9,
+ 0x26, 0x2F, 0xB0, 0xE8,
+ 0x19, 0x20, 0x20, 0xE9,
-0x35, 0x20, 0x35, 0xDF,
-0x3D, 0x20, 0x3D, 0xDF,
+ 0x35, 0x20, 0x35, 0xDF,
+ 0x3D, 0x20, 0x3D, 0xDF,
-0x15, 0x20, 0x15, 0xDF,
-0x1D, 0x20, 0x1D, 0xDF,
+ 0x15, 0x20, 0x15, 0xDF,
+ 0x1D, 0x20, 0x1D, 0xDF,
-0x26, 0xD0, 0x26, 0xCD,
-0x29, 0x49, 0x2A, 0xB8,
+ 0x26, 0xD0, 0x26, 0xCD,
+ 0x29, 0x49, 0x2A, 0xB8,
-0x26, 0x40, 0x80, 0xBD,
-0x3B, 0x48, 0x50, 0xBD,
+ 0x26, 0x40, 0x80, 0xBD,
+ 0x3B, 0x48, 0x50, 0xBD,
-0x3E, 0x54, 0x57, 0x9F,
-0x00, 0xE0,
-0x82, 0xE1,
+ 0x3E, 0x54, 0x57, 0x9F,
+ 0x00, 0xE0,
+ 0x82, 0xE1,
-0x1E, 0xAF, 0x59, 0x9F,
-0x00, 0x80, 0x00, 0xE8,
+ 0x1E, 0xAF, 0x59, 0x9F,
+ 0x00, 0x80, 0x00, 0xE8,
-0x26, 0x30,
-0x29, 0x30,
-0x48, 0x3C, 0x48, 0xAD,
+ 0x26, 0x30,
+ 0x29, 0x30,
+ 0x48, 0x3C, 0x48, 0xAD,
-0x2B, 0x72,
-0xC2, 0xE1,
-0x2C, 0xC0, 0x44, 0xC2,
+ 0x2B, 0x72,
+ 0xC2, 0xE1,
+ 0x2C, 0xC0, 0x44, 0xC2,
-0x05, 0x24, 0x34, 0xBF,
-0x0D, 0x24, 0x2C, 0xBF,
+ 0x05, 0x24, 0x34, 0xBF,
+ 0x0D, 0x24, 0x2C, 0xBF,
-0x2D, 0x46, 0x4E, 0xBF,
-0x25, 0x46, 0x56, 0xBF,
+ 0x2D, 0x46, 0x4E, 0xBF,
+ 0x25, 0x46, 0x56, 0xBF,
-0x20, 0x1D, 0x6F, 0x8F,
-0x32, 0x3E, 0x5F, 0xE9,
+ 0x20, 0x1D, 0x6F, 0x8F,
+ 0x32, 0x3E, 0x5F, 0xE9,
-0x3E, 0x50, 0x56, 0x9F,
-0x00, 0xE0,
-0x3B, 0x30,
+ 0x3E, 0x50, 0x56, 0x9F,
+ 0x00, 0xE0,
+ 0x3B, 0x30,
-0x1E, 0x8F, 0x51, 0x9F,
-0x33, 0x1E, 0x5F, 0xE9,
+ 0x1E, 0x8F, 0x51, 0x9F,
+ 0x33, 0x1E, 0x5F, 0xE9,
-0x05, 0x44, 0x54, 0xB2,
-0x0D, 0x44, 0x4C, 0xB2,
+ 0x05, 0x44, 0x54, 0xB2,
+ 0x0D, 0x44, 0x4C, 0xB2,
-0x19, 0xC0, 0xB0, 0xE8,
-0x34, 0xC0, 0x44, 0xC4,
+ 0x19, 0xC0, 0xB0, 0xE8,
+ 0x34, 0xC0, 0x44, 0xC4,
-0x33, 0x73,
-0x00, 0xE0,
-0x3E, 0x62, 0x57, 0x9F,
+ 0x33, 0x73,
+ 0x00, 0xE0,
+ 0x3E, 0x62, 0x57, 0x9F,
-0x1E, 0xAF, 0x59, 0x9F,
-0x00, 0xE0,
-0x0D, 0x20,
+ 0x1E, 0xAF, 0x59, 0x9F,
+ 0x00, 0xE0,
+ 0x0D, 0x20,
-0x84, 0x3E, 0x58, 0xE9,
-0x28, 0x1D, 0x6F, 0x8F,
+ 0x84, 0x3E, 0x58, 0xE9,
+ 0x28, 0x1D, 0x6F, 0x8F,
-0x05, 0x20,
-0x00, 0xE0,
-0x85, 0x1E, 0x58, 0xE9,
+ 0x05, 0x20,
+ 0x00, 0xE0,
+ 0x85, 0x1E, 0x58, 0xE9,
-0x9B, 0x3B, 0x33, 0xDF,
-0x20, 0x20, 0x42, 0xAF,
+ 0x9B, 0x3B, 0x33, 0xDF,
+ 0x20, 0x20, 0x42, 0xAF,
-0x30, 0x42, 0x56, 0x9F,
-0x80, 0x3E, 0x57, 0xE9,
+ 0x30, 0x42, 0x56, 0x9F,
+ 0x80, 0x3E, 0x57, 0xE9,
-0x3F, 0x8F, 0x51, 0x9F,
-0x30, 0x80, 0x5F, 0xE9,
+ 0x3F, 0x8F, 0x51, 0x9F,
+ 0x30, 0x80, 0x5F, 0xE9,
-0x28, 0x28, 0x24, 0xAF,
-0x81, 0x1E, 0x57, 0xE9,
+ 0x28, 0x28, 0x24, 0xAF,
+ 0x81, 0x1E, 0x57, 0xE9,
-0x05, 0x47, 0x57, 0xBF,
-0x0D, 0x47, 0x4F, 0xBF,
+ 0x05, 0x47, 0x57, 0xBF,
+ 0x0D, 0x47, 0x4F, 0xBF,
-0x88, 0x80, 0x58, 0xE9,
-0x1B, 0x29, 0x1B, 0xDF,
+ 0x88, 0x80, 0x58, 0xE9,
+ 0x1B, 0x29, 0x1B, 0xDF,
-0x30, 0x1D, 0x6F, 0x8F,
-0x3A, 0x30, 0x4F, 0xE9,
+ 0x30, 0x1D, 0x6F, 0x8F,
+ 0x3A, 0x30, 0x4F, 0xE9,
-0x1C, 0x30, 0x26, 0xDF,
-0x09, 0xE3,
-0x3B, 0x05,
+ 0x1C, 0x30, 0x26, 0xDF,
+ 0x09, 0xE3,
+ 0x3B, 0x05,
-0x3E, 0x50, 0x56, 0x9F,
-0x3B, 0x3F, 0x4F, 0xE9,
+ 0x3E, 0x50, 0x56, 0x9F,
+ 0x3B, 0x3F, 0x4F, 0xE9,
-0x1E, 0x8F, 0x51, 0x9F,
-0x00, 0xE0,
-0xAC, 0x20,
+ 0x1E, 0x8F, 0x51, 0x9F,
+ 0x00, 0xE0,
+ 0xAC, 0x20,
-0x2D, 0x44, 0x4C, 0xB4,
-0x2C, 0x1C, 0xC0, 0xAF,
+ 0x2D, 0x44, 0x4C, 0xB4,
+ 0x2C, 0x1C, 0xC0, 0xAF,
-0x25, 0x44, 0x54, 0xB4,
-0x00, 0xE0,
-0xC8, 0x30,
+ 0x25, 0x44, 0x54, 0xB4,
+ 0x00, 0xE0,
+ 0xC8, 0x30,
-0x30, 0x46, 0x30, 0xAF,
-0x1B, 0x1B, 0x48, 0xAF,
+ 0x30, 0x46, 0x30, 0xAF,
+ 0x1B, 0x1B, 0x48, 0xAF,
-0x00, 0xE0,
-0x25, 0x20,
-0x38, 0x2C, 0x4F, 0xE9,
+ 0x00, 0xE0,
+ 0x25, 0x20,
+ 0x38, 0x2C, 0x4F, 0xE9,
-0x86, 0x80, 0x57, 0xE9,
-0x38, 0x1D, 0x6F, 0x8F,
+ 0x86, 0x80, 0x57, 0xE9,
+ 0x38, 0x1D, 0x6F, 0x8F,
-0x28, 0x74,
-0x00, 0xE0,
-0x0D, 0x44, 0x4C, 0xB0,
+ 0x28, 0x74,
+ 0x00, 0xE0,
+ 0x0D, 0x44, 0x4C, 0xB0,
-0x05, 0x44, 0x54, 0xB0,
-0x2D, 0x20,
-0x9B, 0x10,
+ 0x05, 0x44, 0x54, 0xB0,
+ 0x2D, 0x20,
+ 0x9B, 0x10,
-0x82, 0x3E, 0x57, 0xE9,
-0x32, 0xF0, 0x1B, 0xCD,
+ 0x82, 0x3E, 0x57, 0xE9,
+ 0x32, 0xF0, 0x1B, 0xCD,
-0x1E, 0xBD, 0x59, 0x9F,
-0x83, 0x1E, 0x57, 0xE9,
+ 0x1E, 0xBD, 0x59, 0x9F,
+ 0x83, 0x1E, 0x57, 0xE9,
-0x38, 0x47, 0x38, 0xAF,
-0x34, 0x20,
-0x2A, 0x30,
+ 0x38, 0x47, 0x38, 0xAF,
+ 0x34, 0x20,
+ 0x2A, 0x30,
-0x00, 0xE0,
-0x0D, 0x20,
-0x32, 0x20,
-0x05, 0x20,
+ 0x00, 0xE0,
+ 0x0D, 0x20,
+ 0x32, 0x20,
+ 0x05, 0x20,
-0x87, 0x80, 0x57, 0xE9,
-0x1F, 0x54, 0x57, 0x9F,
+ 0x87, 0x80, 0x57, 0xE9,
+ 0x1F, 0x54, 0x57, 0x9F,
-0x17, 0x42, 0x56, 0x9F,
-0x00, 0xE0,
-0x3B, 0x6A,
+ 0x17, 0x42, 0x56, 0x9F,
+ 0x00, 0xE0,
+ 0x3B, 0x6A,
-0x3F, 0x8F, 0x51, 0x9F,
-0x37, 0x1E, 0x4F, 0xE9,
+ 0x3F, 0x8F, 0x51, 0x9F,
+ 0x37, 0x1E, 0x4F, 0xE9,
-0x37, 0x32, 0x2A, 0xAF,
-0x00, 0xE0,
-0x32, 0x00,
+ 0x37, 0x32, 0x2A, 0xAF,
+ 0x00, 0xE0,
+ 0x32, 0x00,
-0x00, 0x80, 0x00, 0xE8,
-0x27, 0xC0, 0x44, 0xC0,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x27, 0xC0, 0x44, 0xC0,
-0x36, 0x1F, 0x4F, 0xE9,
-0x1F, 0x1F, 0x26, 0xDF,
+ 0x36, 0x1F, 0x4F, 0xE9,
+ 0x1F, 0x1F, 0x26, 0xDF,
-0x37, 0x1B, 0x37, 0xBF,
-0x17, 0x26, 0x17, 0xDF,
+ 0x37, 0x1B, 0x37, 0xBF,
+ 0x17, 0x26, 0x17, 0xDF,
-0x3E, 0x17, 0x4F, 0xE9,
-0x3F, 0x3F, 0x4F, 0xE9,
+ 0x3E, 0x17, 0x4F, 0xE9,
+ 0x3F, 0x3F, 0x4F, 0xE9,
-0x34, 0x1F, 0x34, 0xAF,
-0x2B, 0x05,
-0xA7, 0x20,
+ 0x34, 0x1F, 0x34, 0xAF,
+ 0x2B, 0x05,
+ 0xA7, 0x20,
-0x33, 0x2B, 0x37, 0xDF,
-0x27, 0x17, 0xC0, 0xAF,
+ 0x33, 0x2B, 0x37, 0xDF,
+ 0x27, 0x17, 0xC0, 0xAF,
-0x34, 0x80, 0x4F, 0xE9,
-0x00, 0x80, 0x00, 0xE8,
+ 0x34, 0x80, 0x4F, 0xE9,
+ 0x00, 0x80, 0x00, 0xE8,
-0x0D, 0x21, 0x1A, 0xB6,
-0x05, 0x21, 0x31, 0xB6,
+ 0x0D, 0x21, 0x1A, 0xB6,
+ 0x05, 0x21, 0x31, 0xB6,
-0x03, 0x80, 0x2A, 0xEA,
-0x17, 0xC1, 0x2B, 0xBD,
+ 0x03, 0x80, 0x2A, 0xEA,
+ 0x17, 0xC1, 0x2B, 0xBD,
-0x0D, 0x20,
-0x05, 0x20,
-0x2F, 0xC0, 0x21, 0xC6,
+ 0x0D, 0x20,
+ 0x05, 0x20,
+ 0x2F, 0xC0, 0x21, 0xC6,
-0xB3, 0x68,
-0x97, 0x25,
-0x00, 0x80, 0x00, 0xE8,
+ 0xB3, 0x68,
+ 0x97, 0x25,
+ 0x00, 0x80, 0x00, 0xE8,
-0x33, 0xC0, 0x33, 0xAF,
-0x3C, 0x27, 0x4F, 0xE9,
+ 0x33, 0xC0, 0x33, 0xAF,
+ 0x3C, 0x27, 0x4F, 0xE9,
-0x17, 0x50, 0x56, 0x9F,
-0x00, 0x80, 0x00, 0xE8,
+ 0x17, 0x50, 0x56, 0x9F,
+ 0x00, 0x80, 0x00, 0xE8,
-0x37, 0x0F, 0x5C, 0x9F,
-0x00, 0xE0,
-0x2F, 0x20,
+ 0x37, 0x0F, 0x5C, 0x9F,
+ 0x00, 0xE0,
+ 0x2F, 0x20,
-0x00, 0x80, 0x00, 0xE8,
-0x28, 0x19, 0x60, 0xEC,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x28, 0x19, 0x60, 0xEC,
-0xB3, 0x05,
-0x00, 0xE0,
-0x00, 0x80, 0x00, 0xE8,
+ 0xB3, 0x05,
+ 0x00, 0xE0,
+ 0x00, 0x80, 0x00, 0xE8,
-0x23, 0x3B, 0x33, 0xAD,
-0x00, 0x80, 0x00, 0xE8,
+ 0x23, 0x3B, 0x33, 0xAD,
+ 0x00, 0x80, 0x00, 0xE8,
-0x17, 0x26, 0x17, 0xDF,
-0x35, 0x17, 0x4F, 0xE9,
+ 0x17, 0x26, 0x17, 0xDF,
+ 0x35, 0x17, 0x4F, 0xE9,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x39, 0x37, 0x4F, 0xE9,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x39, 0x37, 0x4F, 0xE9,
-0x2F, 0x2F, 0x17, 0xAF,
-0x00, 0x80, 0x00, 0xE8,
+ 0x2F, 0x2F, 0x17, 0xAF,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x31, 0x80, 0x4F, 0xE9,
-0x00, 0x80, 0x00, 0xE8,
+ 0x31, 0x80, 0x4F, 0xE9,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x57, 0x39, 0x20, 0xE9,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x57, 0x39, 0x20, 0xE9,
-0x16, 0x28, 0x20, 0xE9,
-0x1D, 0x3B, 0x20, 0xE9,
+ 0x16, 0x28, 0x20, 0xE9,
+ 0x1D, 0x3B, 0x20, 0xE9,
-0x1E, 0x2B, 0x20, 0xE9,
-0x2B, 0x32, 0x20, 0xE9,
+ 0x1E, 0x2B, 0x20, 0xE9,
+ 0x2B, 0x32, 0x20, 0xE9,
-0x1C, 0x23, 0x20, 0xE9,
-0x57, 0x36, 0x20, 0xE9,
+ 0x1C, 0x23, 0x20, 0xE9,
+ 0x57, 0x36, 0x20, 0xE9,
-0x00, 0x80, 0xA0, 0xE9,
-0x40, 0x40, 0xD8, 0xEC,
+ 0x00, 0x80, 0xA0, 0xE9,
+ 0x40, 0x40, 0xD8, 0xEC,
-0xFF, 0x80, 0xC0, 0xE9,
-0x90, 0xE2,
-0x00, 0xE0,
+ 0xFF, 0x80, 0xC0, 0xE9,
+ 0x90, 0xE2,
+ 0x00, 0xE0,
-0x78, 0xFF, 0x20, 0xEA,
-0x19, 0xC8, 0xC1, 0xCD,
+ 0x78, 0xFF, 0x20, 0xEA,
+ 0x19, 0xC8, 0xC1, 0xCD,
-0x1F, 0xD7, 0x18, 0xBD,
-0x3F, 0xD7, 0x22, 0xBD,
+ 0x1F, 0xD7, 0x18, 0xBD,
+ 0x3F, 0xD7, 0x22, 0xBD,
-0x9F, 0x41, 0x49, 0xBD,
-0x00, 0x80, 0x00, 0xE8,
+ 0x9F, 0x41, 0x49, 0xBD,
+ 0x00, 0x80, 0x00, 0xE8,
-0x25, 0x41, 0x49, 0xBD,
-0x2D, 0x41, 0x51, 0xBD,
+ 0x25, 0x41, 0x49, 0xBD,
+ 0x2D, 0x41, 0x51, 0xBD,
-0x0D, 0x80, 0x07, 0xEA,
-0x00, 0x80, 0x00, 0xE8,
+ 0x0D, 0x80, 0x07, 0xEA,
+ 0x00, 0x80, 0x00, 0xE8,
-0x35, 0x40, 0x48, 0xBD,
-0x3D, 0x40, 0x50, 0xBD,
+ 0x35, 0x40, 0x48, 0xBD,
+ 0x3D, 0x40, 0x50, 0xBD,
-0x00, 0x80, 0x00, 0xE8,
-0x25, 0x30,
-0x2D, 0x30,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x25, 0x30,
+ 0x2D, 0x30,
-0x35, 0x30,
-0xB5, 0x30,
-0xBD, 0x30,
-0x3D, 0x30,
+ 0x35, 0x30,
+ 0xB5, 0x30,
+ 0xBD, 0x30,
+ 0x3D, 0x30,
-0x9C, 0xA7, 0x5B, 0x9F,
-0x00, 0x80, 0x00, 0xE8,
+ 0x9C, 0xA7, 0x5B, 0x9F,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x77, 0xFF, 0x0A, 0xEA,
-0x00, 0x80, 0x00, 0xE8,
+ 0x77, 0xFF, 0x0A, 0xEA,
+ 0x00, 0x80, 0x00, 0xE8,
-0xC9, 0x41, 0xC8, 0xEC,
-0x42, 0xE1,
-0x00, 0xE0,
+ 0xC9, 0x41, 0xC8, 0xEC,
+ 0x42, 0xE1,
+ 0x00, 0xE0,
-0x75, 0xFF, 0x20, 0xEA,
-0x00, 0x80, 0x00, 0xE8,
+ 0x75, 0xFF, 0x20, 0xEA,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0xC8, 0x40, 0xC0, 0xEC,
-0x00, 0x80, 0x00, 0xE8,
+ 0xC8, 0x40, 0xC0, 0xEC,
+ 0x00, 0x80, 0x00, 0xE8,
-0x72, 0xFF, 0x20, 0xEA,
-0x00, 0x80, 0x00, 0xE8,
+ 0x72, 0xFF, 0x20, 0xEA,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
};
static unsigned char warp_g200_tgzs[] = {
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x98, 0xA0, 0xE9,
-0x40, 0x40, 0xD8, 0xEC,
+ 0x00, 0x98, 0xA0, 0xE9,
+ 0x40, 0x40, 0xD8, 0xEC,
-0xFF, 0x80, 0xC0, 0xE9,
-0x00, 0x80, 0x00, 0xE8,
+ 0xFF, 0x80, 0xC0, 0xE9,
+ 0x00, 0x80, 0x00, 0xE8,
-0x1F, 0xD7, 0x18, 0xBD,
-0x3F, 0xD7, 0x22, 0xBD,
+ 0x1F, 0xD7, 0x18, 0xBD,
+ 0x3F, 0xD7, 0x22, 0xBD,
-0x81, 0x04,
-0x89, 0x04,
-0x01, 0x04,
-0x09, 0x04,
+ 0x81, 0x04,
+ 0x89, 0x04,
+ 0x01, 0x04,
+ 0x09, 0x04,
-0xC9, 0x41, 0xC0, 0xEC,
-0x11, 0x04,
-0x00, 0xE0,
+ 0xC9, 0x41, 0xC0, 0xEC,
+ 0x11, 0x04,
+ 0x00, 0xE0,
-0x41, 0xCC, 0x41, 0xCD,
-0x49, 0xCC, 0x49, 0xCD,
+ 0x41, 0xCC, 0x41, 0xCD,
+ 0x49, 0xCC, 0x49, 0xCD,
-0xD1, 0x41, 0xC0, 0xEC,
-0x51, 0xCC, 0x51, 0xCD,
+ 0xD1, 0x41, 0xC0, 0xEC,
+ 0x51, 0xCC, 0x51, 0xCD,
-0x80, 0x04,
-0x10, 0x04,
-0x08, 0x04,
-0x00, 0xE0,
+ 0x80, 0x04,
+ 0x10, 0x04,
+ 0x08, 0x04,
+ 0x00, 0xE0,
-0x00, 0xCC, 0xC0, 0xCD,
-0xD1, 0x49, 0xC0, 0xEC,
+ 0x00, 0xCC, 0xC0, 0xCD,
+ 0xD1, 0x49, 0xC0, 0xEC,
-0x8A, 0x1F, 0x20, 0xE9,
-0x8B, 0x3F, 0x20, 0xE9,
+ 0x8A, 0x1F, 0x20, 0xE9,
+ 0x8B, 0x3F, 0x20, 0xE9,
-0x41, 0x3C, 0x41, 0xAD,
-0x49, 0x3C, 0x49, 0xAD,
+ 0x41, 0x3C, 0x41, 0xAD,
+ 0x49, 0x3C, 0x49, 0xAD,
-0x10, 0xCC, 0x10, 0xCD,
-0x08, 0xCC, 0x08, 0xCD,
+ 0x10, 0xCC, 0x10, 0xCD,
+ 0x08, 0xCC, 0x08, 0xCD,
-0xB9, 0x41, 0x49, 0xBB,
-0x1F, 0xF0, 0x41, 0xCD,
+ 0xB9, 0x41, 0x49, 0xBB,
+ 0x1F, 0xF0, 0x41, 0xCD,
-0x51, 0x3C, 0x51, 0xAD,
-0x00, 0x98, 0x80, 0xE9,
+ 0x51, 0x3C, 0x51, 0xAD,
+ 0x00, 0x98, 0x80, 0xE9,
-0x8B, 0x80, 0x07, 0xEA,
-0x24, 0x1F, 0x20, 0xE9,
+ 0x8B, 0x80, 0x07, 0xEA,
+ 0x24, 0x1F, 0x20, 0xE9,
-0x21, 0x45, 0x80, 0xE8,
-0x1A, 0x4D, 0x80, 0xE8,
+ 0x21, 0x45, 0x80, 0xE8,
+ 0x1A, 0x4D, 0x80, 0xE8,
-0x31, 0x55, 0x80, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x31, 0x55, 0x80, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x15, 0x41, 0x49, 0xBD,
-0x1D, 0x41, 0x51, 0xBD,
+ 0x15, 0x41, 0x49, 0xBD,
+ 0x1D, 0x41, 0x51, 0xBD,
-0x2E, 0x41, 0x2A, 0xB8,
-0x34, 0x53, 0xA0, 0xE8,
+ 0x2E, 0x41, 0x2A, 0xB8,
+ 0x34, 0x53, 0xA0, 0xE8,
-0x15, 0x30,
-0x1D, 0x30,
-0x58, 0xE3,
-0x00, 0xE0,
+ 0x15, 0x30,
+ 0x1D, 0x30,
+ 0x58, 0xE3,
+ 0x00, 0xE0,
-0xB5, 0x40, 0x48, 0xBD,
-0x3D, 0x40, 0x50, 0xBD,
+ 0xB5, 0x40, 0x48, 0xBD,
+ 0x3D, 0x40, 0x50, 0xBD,
-0x24, 0x43, 0xA0, 0xE8,
-0x2C, 0x4B, 0xA0, 0xE8,
+ 0x24, 0x43, 0xA0, 0xE8,
+ 0x2C, 0x4B, 0xA0, 0xE8,
-0x15, 0x72,
-0x09, 0xE3,
-0x00, 0xE0,
-0x1D, 0x72,
+ 0x15, 0x72,
+ 0x09, 0xE3,
+ 0x00, 0xE0,
+ 0x1D, 0x72,
-0x35, 0x30,
-0xB5, 0x30,
-0xBD, 0x30,
-0x3D, 0x30,
+ 0x35, 0x30,
+ 0xB5, 0x30,
+ 0xBD, 0x30,
+ 0x3D, 0x30,
-0x9C, 0x97, 0x57, 0x9F,
-0x00, 0x80, 0x00, 0xE8,
+ 0x9C, 0x97, 0x57, 0x9F,
+ 0x00, 0x80, 0x00, 0xE8,
-0x6C, 0x64, 0xC8, 0xEC,
-0x98, 0xE1,
-0xB5, 0x05,
+ 0x6C, 0x64, 0xC8, 0xEC,
+ 0x98, 0xE1,
+ 0xB5, 0x05,
-0xBD, 0x05,
-0x2E, 0x30,
-0x32, 0xC0, 0xA0, 0xE8,
+ 0xBD, 0x05,
+ 0x2E, 0x30,
+ 0x32, 0xC0, 0xA0, 0xE8,
-0x33, 0xC0, 0xA0, 0xE8,
-0x74, 0x64, 0xC8, 0xEC,
+ 0x33, 0xC0, 0xA0, 0xE8,
+ 0x74, 0x64, 0xC8, 0xEC,
-0x40, 0x3C, 0x40, 0xAD,
-0x32, 0x6A,
-0x2A, 0x30,
+ 0x40, 0x3C, 0x40, 0xAD,
+ 0x32, 0x6A,
+ 0x2A, 0x30,
-0x20, 0x73,
-0x33, 0x6A,
-0x00, 0xE0,
-0x28, 0x73,
+ 0x20, 0x73,
+ 0x33, 0x6A,
+ 0x00, 0xE0,
+ 0x28, 0x73,
-0x1C, 0x72,
-0x83, 0xE2,
-0x77, 0x80, 0x15, 0xEA,
+ 0x1C, 0x72,
+ 0x83, 0xE2,
+ 0x77, 0x80, 0x15, 0xEA,
-0xB8, 0x3D, 0x28, 0xDF,
-0x30, 0x35, 0x20, 0xDF,
+ 0xB8, 0x3D, 0x28, 0xDF,
+ 0x30, 0x35, 0x20, 0xDF,
-0x40, 0x30,
-0x00, 0xE0,
-0xCC, 0xE2,
-0x64, 0x72,
+ 0x40, 0x30,
+ 0x00, 0xE0,
+ 0xCC, 0xE2,
+ 0x64, 0x72,
-0x25, 0x42, 0x52, 0xBF,
-0x2D, 0x42, 0x4A, 0xBF,
+ 0x25, 0x42, 0x52, 0xBF,
+ 0x2D, 0x42, 0x4A, 0xBF,
-0x30, 0x2E, 0x30, 0xDF,
-0x38, 0x2E, 0x38, 0xDF,
+ 0x30, 0x2E, 0x30, 0xDF,
+ 0x38, 0x2E, 0x38, 0xDF,
-0x18, 0x1D, 0x45, 0xE9,
-0x1E, 0x15, 0x45, 0xE9,
+ 0x18, 0x1D, 0x45, 0xE9,
+ 0x1E, 0x15, 0x45, 0xE9,
-0x2B, 0x49, 0x51, 0xBD,
-0x00, 0xE0,
-0x1F, 0x73,
+ 0x2B, 0x49, 0x51, 0xBD,
+ 0x00, 0xE0,
+ 0x1F, 0x73,
-0x38, 0x38, 0x40, 0xAF,
-0x30, 0x30, 0x40, 0xAF,
+ 0x38, 0x38, 0x40, 0xAF,
+ 0x30, 0x30, 0x40, 0xAF,
-0x24, 0x1F, 0x24, 0xDF,
-0x1D, 0x32, 0x20, 0xE9,
+ 0x24, 0x1F, 0x24, 0xDF,
+ 0x1D, 0x32, 0x20, 0xE9,
-0x2C, 0x1F, 0x2C, 0xDF,
-0x1A, 0x33, 0x20, 0xE9,
+ 0x2C, 0x1F, 0x2C, 0xDF,
+ 0x1A, 0x33, 0x20, 0xE9,
-0xB0, 0x10,
-0x08, 0xE3,
-0x40, 0x10,
-0xB8, 0x10,
+ 0xB0, 0x10,
+ 0x08, 0xE3,
+ 0x40, 0x10,
+ 0xB8, 0x10,
-0x26, 0xF0, 0x30, 0xCD,
-0x2F, 0xF0, 0x38, 0xCD,
+ 0x26, 0xF0, 0x30, 0xCD,
+ 0x2F, 0xF0, 0x38, 0xCD,
-0x2B, 0x80, 0x20, 0xE9,
-0x2A, 0x80, 0x20, 0xE9,
+ 0x2B, 0x80, 0x20, 0xE9,
+ 0x2A, 0x80, 0x20, 0xE9,
-0xA6, 0x20,
-0x88, 0xE2,
-0x00, 0xE0,
-0xAF, 0x20,
+ 0xA6, 0x20,
+ 0x88, 0xE2,
+ 0x00, 0xE0,
+ 0xAF, 0x20,
-0x28, 0x2A, 0x26, 0xAF,
-0x20, 0x2A, 0xC0, 0xAF,
+ 0x28, 0x2A, 0x26, 0xAF,
+ 0x20, 0x2A, 0xC0, 0xAF,
-0x34, 0x1F, 0x34, 0xDF,
-0x46, 0x24, 0x46, 0xDF,
+ 0x34, 0x1F, 0x34, 0xDF,
+ 0x46, 0x24, 0x46, 0xDF,
-0x28, 0x30, 0x80, 0xBF,
-0x20, 0x38, 0x80, 0xBF,
+ 0x28, 0x30, 0x80, 0xBF,
+ 0x20, 0x38, 0x80, 0xBF,
-0x47, 0x24, 0x47, 0xDF,
-0x4E, 0x2C, 0x4E, 0xDF,
+ 0x47, 0x24, 0x47, 0xDF,
+ 0x4E, 0x2C, 0x4E, 0xDF,
-0x4F, 0x2C, 0x4F, 0xDF,
-0x56, 0x34, 0x56, 0xDF,
+ 0x4F, 0x2C, 0x4F, 0xDF,
+ 0x56, 0x34, 0x56, 0xDF,
-0x28, 0x15, 0x28, 0xDF,
-0x20, 0x1D, 0x20, 0xDF,
+ 0x28, 0x15, 0x28, 0xDF,
+ 0x20, 0x1D, 0x20, 0xDF,
-0x57, 0x34, 0x57, 0xDF,
-0x00, 0xE0,
-0x1D, 0x05,
+ 0x57, 0x34, 0x57, 0xDF,
+ 0x00, 0xE0,
+ 0x1D, 0x05,
-0x04, 0x80, 0x10, 0xEA,
-0x89, 0xE2,
-0x2B, 0x30,
+ 0x04, 0x80, 0x10, 0xEA,
+ 0x89, 0xE2,
+ 0x2B, 0x30,
-0x3F, 0xC1, 0x1D, 0xBD,
-0x00, 0x80, 0x00, 0xE8,
+ 0x3F, 0xC1, 0x1D, 0xBD,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0xA0, 0x68,
-0xBF, 0x25,
-0x00, 0x80, 0x00, 0xE8,
+ 0xA0, 0x68,
+ 0xBF, 0x25,
+ 0x00, 0x80, 0x00, 0xE8,
-0x20, 0xC0, 0x20, 0xAF,
-0x28, 0x05,
-0x97, 0x74,
+ 0x20, 0xC0, 0x20, 0xAF,
+ 0x28, 0x05,
+ 0x97, 0x74,
-0x00, 0xE0,
-0x2A, 0x10,
-0x16, 0xC0, 0x20, 0xE9,
+ 0x00, 0xE0,
+ 0x2A, 0x10,
+ 0x16, 0xC0, 0x20, 0xE9,
-0x04, 0x80, 0x10, 0xEA,
-0x8C, 0xE2,
-0x95, 0x05,
+ 0x04, 0x80, 0x10, 0xEA,
+ 0x8C, 0xE2,
+ 0x95, 0x05,
-0x28, 0xC1, 0x28, 0xAD,
-0x1F, 0xC1, 0x15, 0xBD,
+ 0x28, 0xC1, 0x28, 0xAD,
+ 0x1F, 0xC1, 0x15, 0xBD,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0xA8, 0x67,
-0x9F, 0x6B,
-0x00, 0x80, 0x00, 0xE8,
+ 0xA8, 0x67,
+ 0x9F, 0x6B,
+ 0x00, 0x80, 0x00, 0xE8,
-0x28, 0xC0, 0x28, 0xAD,
-0x1D, 0x25,
-0x20, 0x05,
+ 0x28, 0xC0, 0x28, 0xAD,
+ 0x1D, 0x25,
+ 0x20, 0x05,
-0x28, 0x32, 0x80, 0xAD,
-0x40, 0x2A, 0x40, 0xBD,
+ 0x28, 0x32, 0x80, 0xAD,
+ 0x40, 0x2A, 0x40, 0xBD,
-0x1C, 0x80, 0x20, 0xE9,
-0x20, 0x33, 0x20, 0xAD,
+ 0x1C, 0x80, 0x20, 0xE9,
+ 0x20, 0x33, 0x20, 0xAD,
-0x20, 0x73,
-0x00, 0xE0,
-0xB6, 0x49, 0x51, 0xBB,
+ 0x20, 0x73,
+ 0x00, 0xE0,
+ 0xB6, 0x49, 0x51, 0xBB,
-0x26, 0x2F, 0xB0, 0xE8,
-0x19, 0x20, 0x20, 0xE9,
+ 0x26, 0x2F, 0xB0, 0xE8,
+ 0x19, 0x20, 0x20, 0xE9,
-0x35, 0x20, 0x35, 0xDF,
-0x3D, 0x20, 0x3D, 0xDF,
+ 0x35, 0x20, 0x35, 0xDF,
+ 0x3D, 0x20, 0x3D, 0xDF,
-0x15, 0x20, 0x15, 0xDF,
-0x1D, 0x20, 0x1D, 0xDF,
+ 0x15, 0x20, 0x15, 0xDF,
+ 0x1D, 0x20, 0x1D, 0xDF,
-0x26, 0xD0, 0x26, 0xCD,
-0x29, 0x49, 0x2A, 0xB8,
+ 0x26, 0xD0, 0x26, 0xCD,
+ 0x29, 0x49, 0x2A, 0xB8,
-0x26, 0x40, 0x80, 0xBD,
-0x3B, 0x48, 0x50, 0xBD,
+ 0x26, 0x40, 0x80, 0xBD,
+ 0x3B, 0x48, 0x50, 0xBD,
-0x3E, 0x54, 0x57, 0x9F,
-0x00, 0xE0,
-0x82, 0xE1,
+ 0x3E, 0x54, 0x57, 0x9F,
+ 0x00, 0xE0,
+ 0x82, 0xE1,
-0x1E, 0xAF, 0x59, 0x9F,
-0x00, 0x80, 0x00, 0xE8,
+ 0x1E, 0xAF, 0x59, 0x9F,
+ 0x00, 0x80, 0x00, 0xE8,
-0x26, 0x30,
-0x29, 0x30,
-0x48, 0x3C, 0x48, 0xAD,
+ 0x26, 0x30,
+ 0x29, 0x30,
+ 0x48, 0x3C, 0x48, 0xAD,
-0x2B, 0x72,
-0xC2, 0xE1,
-0x2C, 0xC0, 0x44, 0xC2,
+ 0x2B, 0x72,
+ 0xC2, 0xE1,
+ 0x2C, 0xC0, 0x44, 0xC2,
-0x05, 0x24, 0x34, 0xBF,
-0x0D, 0x24, 0x2C, 0xBF,
+ 0x05, 0x24, 0x34, 0xBF,
+ 0x0D, 0x24, 0x2C, 0xBF,
-0x2D, 0x46, 0x4E, 0xBF,
-0x25, 0x46, 0x56, 0xBF,
+ 0x2D, 0x46, 0x4E, 0xBF,
+ 0x25, 0x46, 0x56, 0xBF,
-0x20, 0x1D, 0x6F, 0x8F,
-0x32, 0x3E, 0x5F, 0xE9,
+ 0x20, 0x1D, 0x6F, 0x8F,
+ 0x32, 0x3E, 0x5F, 0xE9,
-0x3E, 0x50, 0x56, 0x9F,
-0x00, 0xE0,
-0x3B, 0x30,
+ 0x3E, 0x50, 0x56, 0x9F,
+ 0x00, 0xE0,
+ 0x3B, 0x30,
-0x1E, 0x8F, 0x51, 0x9F,
-0x33, 0x1E, 0x5F, 0xE9,
+ 0x1E, 0x8F, 0x51, 0x9F,
+ 0x33, 0x1E, 0x5F, 0xE9,
-0x05, 0x44, 0x54, 0xB2,
-0x0D, 0x44, 0x4C, 0xB2,
+ 0x05, 0x44, 0x54, 0xB2,
+ 0x0D, 0x44, 0x4C, 0xB2,
-0x19, 0xC0, 0xB0, 0xE8,
-0x34, 0xC0, 0x44, 0xC4,
+ 0x19, 0xC0, 0xB0, 0xE8,
+ 0x34, 0xC0, 0x44, 0xC4,
-0x33, 0x73,
-0x00, 0xE0,
-0x3E, 0x62, 0x57, 0x9F,
+ 0x33, 0x73,
+ 0x00, 0xE0,
+ 0x3E, 0x62, 0x57, 0x9F,
-0x1E, 0xAF, 0x59, 0x9F,
-0x00, 0xE0,
-0x0D, 0x20,
+ 0x1E, 0xAF, 0x59, 0x9F,
+ 0x00, 0xE0,
+ 0x0D, 0x20,
-0x84, 0x3E, 0x58, 0xE9,
-0x28, 0x1D, 0x6F, 0x8F,
+ 0x84, 0x3E, 0x58, 0xE9,
+ 0x28, 0x1D, 0x6F, 0x8F,
-0x05, 0x20,
-0x00, 0xE0,
-0x85, 0x1E, 0x58, 0xE9,
+ 0x05, 0x20,
+ 0x00, 0xE0,
+ 0x85, 0x1E, 0x58, 0xE9,
-0x9B, 0x3B, 0x33, 0xDF,
-0x20, 0x20, 0x42, 0xAF,
+ 0x9B, 0x3B, 0x33, 0xDF,
+ 0x20, 0x20, 0x42, 0xAF,
-0x30, 0x42, 0x56, 0x9F,
-0x80, 0x3E, 0x57, 0xE9,
+ 0x30, 0x42, 0x56, 0x9F,
+ 0x80, 0x3E, 0x57, 0xE9,
-0x3F, 0x8F, 0x51, 0x9F,
-0x30, 0x80, 0x5F, 0xE9,
+ 0x3F, 0x8F, 0x51, 0x9F,
+ 0x30, 0x80, 0x5F, 0xE9,
-0x28, 0x28, 0x24, 0xAF,
-0x81, 0x1E, 0x57, 0xE9,
+ 0x28, 0x28, 0x24, 0xAF,
+ 0x81, 0x1E, 0x57, 0xE9,
-0x05, 0x47, 0x57, 0xBF,
-0x0D, 0x47, 0x4F, 0xBF,
+ 0x05, 0x47, 0x57, 0xBF,
+ 0x0D, 0x47, 0x4F, 0xBF,
-0x88, 0x80, 0x58, 0xE9,
-0x1B, 0x29, 0x1B, 0xDF,
+ 0x88, 0x80, 0x58, 0xE9,
+ 0x1B, 0x29, 0x1B, 0xDF,
-0x30, 0x1D, 0x6F, 0x8F,
-0x3A, 0x30, 0x4F, 0xE9,
+ 0x30, 0x1D, 0x6F, 0x8F,
+ 0x3A, 0x30, 0x4F, 0xE9,
-0x1C, 0x30, 0x26, 0xDF,
-0x09, 0xE3,
-0x3B, 0x05,
+ 0x1C, 0x30, 0x26, 0xDF,
+ 0x09, 0xE3,
+ 0x3B, 0x05,
-0x3E, 0x50, 0x56, 0x9F,
-0x3B, 0x3F, 0x4F, 0xE9,
+ 0x3E, 0x50, 0x56, 0x9F,
+ 0x3B, 0x3F, 0x4F, 0xE9,
-0x1E, 0x8F, 0x51, 0x9F,
-0x00, 0xE0,
-0xAC, 0x20,
+ 0x1E, 0x8F, 0x51, 0x9F,
+ 0x00, 0xE0,
+ 0xAC, 0x20,
-0x2D, 0x44, 0x4C, 0xB4,
-0x2C, 0x1C, 0xC0, 0xAF,
+ 0x2D, 0x44, 0x4C, 0xB4,
+ 0x2C, 0x1C, 0xC0, 0xAF,
-0x25, 0x44, 0x54, 0xB4,
-0x00, 0xE0,
-0xC8, 0x30,
+ 0x25, 0x44, 0x54, 0xB4,
+ 0x00, 0xE0,
+ 0xC8, 0x30,
-0x30, 0x46, 0x30, 0xAF,
-0x1B, 0x1B, 0x48, 0xAF,
+ 0x30, 0x46, 0x30, 0xAF,
+ 0x1B, 0x1B, 0x48, 0xAF,
-0x00, 0xE0,
-0x25, 0x20,
-0x38, 0x2C, 0x4F, 0xE9,
+ 0x00, 0xE0,
+ 0x25, 0x20,
+ 0x38, 0x2C, 0x4F, 0xE9,
-0x86, 0x80, 0x57, 0xE9,
-0x38, 0x1D, 0x6F, 0x8F,
+ 0x86, 0x80, 0x57, 0xE9,
+ 0x38, 0x1D, 0x6F, 0x8F,
-0x28, 0x74,
-0x00, 0xE0,
-0x0D, 0x44, 0x4C, 0xB0,
+ 0x28, 0x74,
+ 0x00, 0xE0,
+ 0x0D, 0x44, 0x4C, 0xB0,
-0x05, 0x44, 0x54, 0xB0,
-0x2D, 0x20,
-0x9B, 0x10,
+ 0x05, 0x44, 0x54, 0xB0,
+ 0x2D, 0x20,
+ 0x9B, 0x10,
-0x82, 0x3E, 0x57, 0xE9,
-0x32, 0xF0, 0x1B, 0xCD,
+ 0x82, 0x3E, 0x57, 0xE9,
+ 0x32, 0xF0, 0x1B, 0xCD,
-0x1E, 0xBD, 0x59, 0x9F,
-0x83, 0x1E, 0x57, 0xE9,
+ 0x1E, 0xBD, 0x59, 0x9F,
+ 0x83, 0x1E, 0x57, 0xE9,
-0x38, 0x47, 0x38, 0xAF,
-0x34, 0x20,
-0x2A, 0x30,
+ 0x38, 0x47, 0x38, 0xAF,
+ 0x34, 0x20,
+ 0x2A, 0x30,
-0x00, 0xE0,
-0x0D, 0x20,
-0x32, 0x20,
-0x05, 0x20,
+ 0x00, 0xE0,
+ 0x0D, 0x20,
+ 0x32, 0x20,
+ 0x05, 0x20,
-0x87, 0x80, 0x57, 0xE9,
-0x1F, 0x54, 0x57, 0x9F,
+ 0x87, 0x80, 0x57, 0xE9,
+ 0x1F, 0x54, 0x57, 0x9F,
-0x17, 0x42, 0x56, 0x9F,
-0x00, 0xE0,
-0x3B, 0x6A,
+ 0x17, 0x42, 0x56, 0x9F,
+ 0x00, 0xE0,
+ 0x3B, 0x6A,
-0x3F, 0x8F, 0x51, 0x9F,
-0x37, 0x1E, 0x4F, 0xE9,
+ 0x3F, 0x8F, 0x51, 0x9F,
+ 0x37, 0x1E, 0x4F, 0xE9,
-0x37, 0x32, 0x2A, 0xAF,
-0x00, 0xE0,
-0x32, 0x00,
+ 0x37, 0x32, 0x2A, 0xAF,
+ 0x00, 0xE0,
+ 0x32, 0x00,
-0x00, 0x80, 0x00, 0xE8,
-0x27, 0xC0, 0x44, 0xC0,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x27, 0xC0, 0x44, 0xC0,
-0x36, 0x1F, 0x4F, 0xE9,
-0x1F, 0x1F, 0x26, 0xDF,
+ 0x36, 0x1F, 0x4F, 0xE9,
+ 0x1F, 0x1F, 0x26, 0xDF,
-0x37, 0x1B, 0x37, 0xBF,
-0x17, 0x26, 0x17, 0xDF,
+ 0x37, 0x1B, 0x37, 0xBF,
+ 0x17, 0x26, 0x17, 0xDF,
-0x3E, 0x17, 0x4F, 0xE9,
-0x3F, 0x3F, 0x4F, 0xE9,
+ 0x3E, 0x17, 0x4F, 0xE9,
+ 0x3F, 0x3F, 0x4F, 0xE9,
-0x34, 0x1F, 0x34, 0xAF,
-0x2B, 0x05,
-0xA7, 0x20,
+ 0x34, 0x1F, 0x34, 0xAF,
+ 0x2B, 0x05,
+ 0xA7, 0x20,
-0x33, 0x2B, 0x37, 0xDF,
-0x27, 0x17, 0xC0, 0xAF,
+ 0x33, 0x2B, 0x37, 0xDF,
+ 0x27, 0x17, 0xC0, 0xAF,
-0x34, 0x80, 0x4F, 0xE9,
-0x00, 0x80, 0x00, 0xE8,
+ 0x34, 0x80, 0x4F, 0xE9,
+ 0x00, 0x80, 0x00, 0xE8,
-0x2D, 0x21, 0x1A, 0xB0,
-0x25, 0x21, 0x31, 0xB0,
+ 0x2D, 0x21, 0x1A, 0xB0,
+ 0x25, 0x21, 0x31, 0xB0,
-0x0D, 0x21, 0x1A, 0xB2,
-0x05, 0x21, 0x31, 0xB2,
+ 0x0D, 0x21, 0x1A, 0xB2,
+ 0x05, 0x21, 0x31, 0xB2,
-0x03, 0x80, 0x2A, 0xEA,
-0x17, 0xC1, 0x2B, 0xBD,
+ 0x03, 0x80, 0x2A, 0xEA,
+ 0x17, 0xC1, 0x2B, 0xBD,
-0x2D, 0x20,
-0x25, 0x20,
-0x05, 0x20,
-0x0D, 0x20,
+ 0x2D, 0x20,
+ 0x25, 0x20,
+ 0x05, 0x20,
+ 0x0D, 0x20,
-0xB3, 0x68,
-0x97, 0x25,
-0x00, 0x80, 0x00, 0xE8,
+ 0xB3, 0x68,
+ 0x97, 0x25,
+ 0x00, 0x80, 0x00, 0xE8,
-0x33, 0xC0, 0x33, 0xAF,
-0x2F, 0xC0, 0x21, 0xC0,
+ 0x33, 0xC0, 0x33, 0xAF,
+ 0x2F, 0xC0, 0x21, 0xC0,
-0x16, 0x42, 0x56, 0x9F,
-0x3C, 0x27, 0x4F, 0xE9,
+ 0x16, 0x42, 0x56, 0x9F,
+ 0x3C, 0x27, 0x4F, 0xE9,
-0x1E, 0x62, 0x57, 0x9F,
-0x00, 0x80, 0x00, 0xE8,
+ 0x1E, 0x62, 0x57, 0x9F,
+ 0x00, 0x80, 0x00, 0xE8,
-0x25, 0x21, 0x31, 0xB4,
-0x2D, 0x21, 0x1A, 0xB4,
+ 0x25, 0x21, 0x31, 0xB4,
+ 0x2D, 0x21, 0x1A, 0xB4,
-0x3F, 0x2F, 0x5D, 0x9F,
-0x00, 0x80, 0x00, 0xE8,
+ 0x3F, 0x2F, 0x5D, 0x9F,
+ 0x00, 0x80, 0x00, 0xE8,
-0x33, 0x05,
-0x00, 0xE0,
-0x28, 0x19, 0x60, 0xEC,
+ 0x33, 0x05,
+ 0x00, 0xE0,
+ 0x28, 0x19, 0x60, 0xEC,
-0x37, 0x0F, 0x5C, 0x9F,
-0x00, 0xE0,
-0x2F, 0x20,
+ 0x37, 0x0F, 0x5C, 0x9F,
+ 0x00, 0xE0,
+ 0x2F, 0x20,
-0x23, 0x3B, 0x33, 0xAD,
-0x1E, 0x26, 0x1E, 0xDF,
+ 0x23, 0x3B, 0x33, 0xAD,
+ 0x1E, 0x26, 0x1E, 0xDF,
-0xA7, 0x1E, 0x4F, 0xE9,
-0x17, 0x26, 0x16, 0xDF,
+ 0xA7, 0x1E, 0x4F, 0xE9,
+ 0x17, 0x26, 0x16, 0xDF,
-0x2D, 0x20,
-0x00, 0xE0,
-0xA8, 0x3F, 0x4F, 0xE9,
+ 0x2D, 0x20,
+ 0x00, 0xE0,
+ 0xA8, 0x3F, 0x4F, 0xE9,
-0x2F, 0x2F, 0x1E, 0xAF,
-0x25, 0x20,
-0x00, 0xE0,
+ 0x2F, 0x2F, 0x1E, 0xAF,
+ 0x25, 0x20,
+ 0x00, 0xE0,
-0xA4, 0x16, 0x4F, 0xE9,
-0x0F, 0xC0, 0x21, 0xC2,
+ 0xA4, 0x16, 0x4F, 0xE9,
+ 0x0F, 0xC0, 0x21, 0xC2,
-0xA6, 0x80, 0x4F, 0xE9,
-0x1F, 0x62, 0x57, 0x9F,
+ 0xA6, 0x80, 0x4F, 0xE9,
+ 0x1F, 0x62, 0x57, 0x9F,
-0x3F, 0x2F, 0x5D, 0x9F,
-0x00, 0xE0,
-0x8F, 0x20,
+ 0x3F, 0x2F, 0x5D, 0x9F,
+ 0x00, 0xE0,
+ 0x8F, 0x20,
-0xA5, 0x37, 0x4F, 0xE9,
-0x0F, 0x17, 0x0F, 0xAF,
+ 0xA5, 0x37, 0x4F, 0xE9,
+ 0x0F, 0x17, 0x0F, 0xAF,
-0x06, 0xC0, 0x21, 0xC4,
-0x00, 0x80, 0x00, 0xE8,
+ 0x06, 0xC0, 0x21, 0xC4,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0xA3, 0x80, 0x4F, 0xE9,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0xA3, 0x80, 0x4F, 0xE9,
-0x06, 0x20,
-0x00, 0xE0,
-0x1F, 0x26, 0x1F, 0xDF,
+ 0x06, 0x20,
+ 0x00, 0xE0,
+ 0x1F, 0x26, 0x1F, 0xDF,
-0xA1, 0x1F, 0x4F, 0xE9,
-0xA2, 0x3F, 0x4F, 0xE9,
+ 0xA1, 0x1F, 0x4F, 0xE9,
+ 0xA2, 0x3F, 0x4F, 0xE9,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x06, 0x06, 0x1F, 0xAF,
-0x00, 0x80, 0x00, 0xE8,
+ 0x06, 0x06, 0x1F, 0xAF,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0xA0, 0x80, 0x4F, 0xE9,
-0x00, 0x80, 0x00, 0xE8,
+ 0xA0, 0x80, 0x4F, 0xE9,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x57, 0x39, 0x20, 0xE9,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x57, 0x39, 0x20, 0xE9,
-0x16, 0x28, 0x20, 0xE9,
-0x1D, 0x3B, 0x20, 0xE9,
+ 0x16, 0x28, 0x20, 0xE9,
+ 0x1D, 0x3B, 0x20, 0xE9,
-0x1E, 0x2B, 0x20, 0xE9,
-0x2B, 0x32, 0x20, 0xE9,
+ 0x1E, 0x2B, 0x20, 0xE9,
+ 0x2B, 0x32, 0x20, 0xE9,
-0x1C, 0x23, 0x20, 0xE9,
-0x57, 0x36, 0x20, 0xE9,
+ 0x1C, 0x23, 0x20, 0xE9,
+ 0x57, 0x36, 0x20, 0xE9,
-0x00, 0x80, 0xA0, 0xE9,
-0x40, 0x40, 0xD8, 0xEC,
+ 0x00, 0x80, 0xA0, 0xE9,
+ 0x40, 0x40, 0xD8, 0xEC,
-0xFF, 0x80, 0xC0, 0xE9,
-0x90, 0xE2,
-0x00, 0xE0,
+ 0xFF, 0x80, 0xC0, 0xE9,
+ 0x90, 0xE2,
+ 0x00, 0xE0,
-0x6C, 0xFF, 0x20, 0xEA,
-0x19, 0xC8, 0xC1, 0xCD,
+ 0x6C, 0xFF, 0x20, 0xEA,
+ 0x19, 0xC8, 0xC1, 0xCD,
-0x1F, 0xD7, 0x18, 0xBD,
-0x3F, 0xD7, 0x22, 0xBD,
+ 0x1F, 0xD7, 0x18, 0xBD,
+ 0x3F, 0xD7, 0x22, 0xBD,
-0x9F, 0x41, 0x49, 0xBD,
-0x00, 0x80, 0x00, 0xE8,
+ 0x9F, 0x41, 0x49, 0xBD,
+ 0x00, 0x80, 0x00, 0xE8,
-0x25, 0x41, 0x49, 0xBD,
-0x2D, 0x41, 0x51, 0xBD,
+ 0x25, 0x41, 0x49, 0xBD,
+ 0x2D, 0x41, 0x51, 0xBD,
-0x0D, 0x80, 0x07, 0xEA,
-0x00, 0x80, 0x00, 0xE8,
+ 0x0D, 0x80, 0x07, 0xEA,
+ 0x00, 0x80, 0x00, 0xE8,
-0x35, 0x40, 0x48, 0xBD,
-0x3D, 0x40, 0x50, 0xBD,
+ 0x35, 0x40, 0x48, 0xBD,
+ 0x3D, 0x40, 0x50, 0xBD,
-0x00, 0x80, 0x00, 0xE8,
-0x25, 0x30,
-0x2D, 0x30,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x25, 0x30,
+ 0x2D, 0x30,
-0x35, 0x30,
-0xB5, 0x30,
-0xBD, 0x30,
-0x3D, 0x30,
+ 0x35, 0x30,
+ 0xB5, 0x30,
+ 0xBD, 0x30,
+ 0x3D, 0x30,
-0x9C, 0xA7, 0x5B, 0x9F,
-0x00, 0x80, 0x00, 0xE8,
+ 0x9C, 0xA7, 0x5B, 0x9F,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x6B, 0xFF, 0x0A, 0xEA,
-0x00, 0x80, 0x00, 0xE8,
+ 0x6B, 0xFF, 0x0A, 0xEA,
+ 0x00, 0x80, 0x00, 0xE8,
-0xC9, 0x41, 0xC8, 0xEC,
-0x42, 0xE1,
-0x00, 0xE0,
+ 0xC9, 0x41, 0xC8, 0xEC,
+ 0x42, 0xE1,
+ 0x00, 0xE0,
-0x69, 0xFF, 0x20, 0xEA,
-0x00, 0x80, 0x00, 0xE8,
+ 0x69, 0xFF, 0x20, 0xEA,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0xC8, 0x40, 0xC0, 0xEC,
-0x00, 0x80, 0x00, 0xE8,
+ 0xC8, 0x40, 0xC0, 0xEC,
+ 0x00, 0x80, 0x00, 0xE8,
-0x66, 0xFF, 0x20, 0xEA,
-0x00, 0x80, 0x00, 0xE8,
+ 0x66, 0xFF, 0x20, 0xEA,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
};
static unsigned char warp_g200_tgzsa[] = {
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x98, 0xA0, 0xE9,
-0x40, 0x40, 0xD8, 0xEC,
+ 0x00, 0x98, 0xA0, 0xE9,
+ 0x40, 0x40, 0xD8, 0xEC,
-0xFF, 0x80, 0xC0, 0xE9,
-0x00, 0x80, 0x00, 0xE8,
+ 0xFF, 0x80, 0xC0, 0xE9,
+ 0x00, 0x80, 0x00, 0xE8,
-0x1F, 0xD7, 0x18, 0xBD,
-0x3F, 0xD7, 0x22, 0xBD,
+ 0x1F, 0xD7, 0x18, 0xBD,
+ 0x3F, 0xD7, 0x22, 0xBD,
-0x81, 0x04,
-0x89, 0x04,
-0x01, 0x04,
-0x09, 0x04,
+ 0x81, 0x04,
+ 0x89, 0x04,
+ 0x01, 0x04,
+ 0x09, 0x04,
-0xC9, 0x41, 0xC0, 0xEC,
-0x11, 0x04,
-0x00, 0xE0,
+ 0xC9, 0x41, 0xC0, 0xEC,
+ 0x11, 0x04,
+ 0x00, 0xE0,
-0x41, 0xCC, 0x41, 0xCD,
-0x49, 0xCC, 0x49, 0xCD,
+ 0x41, 0xCC, 0x41, 0xCD,
+ 0x49, 0xCC, 0x49, 0xCD,
-0xD1, 0x41, 0xC0, 0xEC,
-0x51, 0xCC, 0x51, 0xCD,
+ 0xD1, 0x41, 0xC0, 0xEC,
+ 0x51, 0xCC, 0x51, 0xCD,
-0x80, 0x04,
-0x10, 0x04,
-0x08, 0x04,
-0x00, 0xE0,
+ 0x80, 0x04,
+ 0x10, 0x04,
+ 0x08, 0x04,
+ 0x00, 0xE0,
-0x00, 0xCC, 0xC0, 0xCD,
-0xD1, 0x49, 0xC0, 0xEC,
+ 0x00, 0xCC, 0xC0, 0xCD,
+ 0xD1, 0x49, 0xC0, 0xEC,
-0x8A, 0x1F, 0x20, 0xE9,
-0x8B, 0x3F, 0x20, 0xE9,
+ 0x8A, 0x1F, 0x20, 0xE9,
+ 0x8B, 0x3F, 0x20, 0xE9,
-0x41, 0x3C, 0x41, 0xAD,
-0x49, 0x3C, 0x49, 0xAD,
+ 0x41, 0x3C, 0x41, 0xAD,
+ 0x49, 0x3C, 0x49, 0xAD,
-0x10, 0xCC, 0x10, 0xCD,
-0x08, 0xCC, 0x08, 0xCD,
+ 0x10, 0xCC, 0x10, 0xCD,
+ 0x08, 0xCC, 0x08, 0xCD,
-0xB9, 0x41, 0x49, 0xBB,
-0x1F, 0xF0, 0x41, 0xCD,
+ 0xB9, 0x41, 0x49, 0xBB,
+ 0x1F, 0xF0, 0x41, 0xCD,
-0x51, 0x3C, 0x51, 0xAD,
-0x00, 0x98, 0x80, 0xE9,
+ 0x51, 0x3C, 0x51, 0xAD,
+ 0x00, 0x98, 0x80, 0xE9,
-0x8F, 0x80, 0x07, 0xEA,
-0x24, 0x1F, 0x20, 0xE9,
+ 0x8F, 0x80, 0x07, 0xEA,
+ 0x24, 0x1F, 0x20, 0xE9,
-0x21, 0x45, 0x80, 0xE8,
-0x1A, 0x4D, 0x80, 0xE8,
+ 0x21, 0x45, 0x80, 0xE8,
+ 0x1A, 0x4D, 0x80, 0xE8,
-0x31, 0x55, 0x80, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x31, 0x55, 0x80, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x15, 0x41, 0x49, 0xBD,
-0x1D, 0x41, 0x51, 0xBD,
+ 0x15, 0x41, 0x49, 0xBD,
+ 0x1D, 0x41, 0x51, 0xBD,
-0x2E, 0x41, 0x2A, 0xB8,
-0x34, 0x53, 0xA0, 0xE8,
+ 0x2E, 0x41, 0x2A, 0xB8,
+ 0x34, 0x53, 0xA0, 0xE8,
-0x15, 0x30,
-0x1D, 0x30,
-0x58, 0xE3,
-0x00, 0xE0,
+ 0x15, 0x30,
+ 0x1D, 0x30,
+ 0x58, 0xE3,
+ 0x00, 0xE0,
-0xB5, 0x40, 0x48, 0xBD,
-0x3D, 0x40, 0x50, 0xBD,
+ 0xB5, 0x40, 0x48, 0xBD,
+ 0x3D, 0x40, 0x50, 0xBD,
-0x24, 0x43, 0xA0, 0xE8,
-0x2C, 0x4B, 0xA0, 0xE8,
+ 0x24, 0x43, 0xA0, 0xE8,
+ 0x2C, 0x4B, 0xA0, 0xE8,
-0x15, 0x72,
-0x09, 0xE3,
-0x00, 0xE0,
-0x1D, 0x72,
+ 0x15, 0x72,
+ 0x09, 0xE3,
+ 0x00, 0xE0,
+ 0x1D, 0x72,
-0x35, 0x30,
-0xB5, 0x30,
-0xBD, 0x30,
-0x3D, 0x30,
+ 0x35, 0x30,
+ 0xB5, 0x30,
+ 0xBD, 0x30,
+ 0x3D, 0x30,
-0x9C, 0x97, 0x57, 0x9F,
-0x00, 0x80, 0x00, 0xE8,
+ 0x9C, 0x97, 0x57, 0x9F,
+ 0x00, 0x80, 0x00, 0xE8,
-0x6C, 0x64, 0xC8, 0xEC,
-0x98, 0xE1,
-0xB5, 0x05,
+ 0x6C, 0x64, 0xC8, 0xEC,
+ 0x98, 0xE1,
+ 0xB5, 0x05,
-0xBD, 0x05,
-0x2E, 0x30,
-0x32, 0xC0, 0xA0, 0xE8,
+ 0xBD, 0x05,
+ 0x2E, 0x30,
+ 0x32, 0xC0, 0xA0, 0xE8,
-0x33, 0xC0, 0xA0, 0xE8,
-0x74, 0x64, 0xC8, 0xEC,
+ 0x33, 0xC0, 0xA0, 0xE8,
+ 0x74, 0x64, 0xC8, 0xEC,
-0x40, 0x3C, 0x40, 0xAD,
-0x32, 0x6A,
-0x2A, 0x30,
+ 0x40, 0x3C, 0x40, 0xAD,
+ 0x32, 0x6A,
+ 0x2A, 0x30,
-0x20, 0x73,
-0x33, 0x6A,
-0x00, 0xE0,
-0x28, 0x73,
+ 0x20, 0x73,
+ 0x33, 0x6A,
+ 0x00, 0xE0,
+ 0x28, 0x73,
-0x1C, 0x72,
-0x83, 0xE2,
-0x7B, 0x80, 0x15, 0xEA,
+ 0x1C, 0x72,
+ 0x83, 0xE2,
+ 0x7B, 0x80, 0x15, 0xEA,
-0xB8, 0x3D, 0x28, 0xDF,
-0x30, 0x35, 0x20, 0xDF,
+ 0xB8, 0x3D, 0x28, 0xDF,
+ 0x30, 0x35, 0x20, 0xDF,
-0x40, 0x30,
-0x00, 0xE0,
-0xCC, 0xE2,
-0x64, 0x72,
+ 0x40, 0x30,
+ 0x00, 0xE0,
+ 0xCC, 0xE2,
+ 0x64, 0x72,
-0x25, 0x42, 0x52, 0xBF,
-0x2D, 0x42, 0x4A, 0xBF,
+ 0x25, 0x42, 0x52, 0xBF,
+ 0x2D, 0x42, 0x4A, 0xBF,
-0x30, 0x2E, 0x30, 0xDF,
-0x38, 0x2E, 0x38, 0xDF,
+ 0x30, 0x2E, 0x30, 0xDF,
+ 0x38, 0x2E, 0x38, 0xDF,
-0x18, 0x1D, 0x45, 0xE9,
-0x1E, 0x15, 0x45, 0xE9,
+ 0x18, 0x1D, 0x45, 0xE9,
+ 0x1E, 0x15, 0x45, 0xE9,
-0x2B, 0x49, 0x51, 0xBD,
-0x00, 0xE0,
-0x1F, 0x73,
+ 0x2B, 0x49, 0x51, 0xBD,
+ 0x00, 0xE0,
+ 0x1F, 0x73,
-0x38, 0x38, 0x40, 0xAF,
-0x30, 0x30, 0x40, 0xAF,
+ 0x38, 0x38, 0x40, 0xAF,
+ 0x30, 0x30, 0x40, 0xAF,
-0x24, 0x1F, 0x24, 0xDF,
-0x1D, 0x32, 0x20, 0xE9,
+ 0x24, 0x1F, 0x24, 0xDF,
+ 0x1D, 0x32, 0x20, 0xE9,
-0x2C, 0x1F, 0x2C, 0xDF,
-0x1A, 0x33, 0x20, 0xE9,
+ 0x2C, 0x1F, 0x2C, 0xDF,
+ 0x1A, 0x33, 0x20, 0xE9,
-0xB0, 0x10,
-0x08, 0xE3,
-0x40, 0x10,
-0xB8, 0x10,
+ 0xB0, 0x10,
+ 0x08, 0xE3,
+ 0x40, 0x10,
+ 0xB8, 0x10,
-0x26, 0xF0, 0x30, 0xCD,
-0x2F, 0xF0, 0x38, 0xCD,
+ 0x26, 0xF0, 0x30, 0xCD,
+ 0x2F, 0xF0, 0x38, 0xCD,
-0x2B, 0x80, 0x20, 0xE9,
-0x2A, 0x80, 0x20, 0xE9,
+ 0x2B, 0x80, 0x20, 0xE9,
+ 0x2A, 0x80, 0x20, 0xE9,
-0xA6, 0x20,
-0x88, 0xE2,
-0x00, 0xE0,
-0xAF, 0x20,
+ 0xA6, 0x20,
+ 0x88, 0xE2,
+ 0x00, 0xE0,
+ 0xAF, 0x20,
-0x28, 0x2A, 0x26, 0xAF,
-0x20, 0x2A, 0xC0, 0xAF,
+ 0x28, 0x2A, 0x26, 0xAF,
+ 0x20, 0x2A, 0xC0, 0xAF,
-0x34, 0x1F, 0x34, 0xDF,
-0x46, 0x24, 0x46, 0xDF,
+ 0x34, 0x1F, 0x34, 0xDF,
+ 0x46, 0x24, 0x46, 0xDF,
-0x28, 0x30, 0x80, 0xBF,
-0x20, 0x38, 0x80, 0xBF,
+ 0x28, 0x30, 0x80, 0xBF,
+ 0x20, 0x38, 0x80, 0xBF,
-0x47, 0x24, 0x47, 0xDF,
-0x4E, 0x2C, 0x4E, 0xDF,
+ 0x47, 0x24, 0x47, 0xDF,
+ 0x4E, 0x2C, 0x4E, 0xDF,
-0x4F, 0x2C, 0x4F, 0xDF,
-0x56, 0x34, 0x56, 0xDF,
+ 0x4F, 0x2C, 0x4F, 0xDF,
+ 0x56, 0x34, 0x56, 0xDF,
-0x28, 0x15, 0x28, 0xDF,
-0x20, 0x1D, 0x20, 0xDF,
+ 0x28, 0x15, 0x28, 0xDF,
+ 0x20, 0x1D, 0x20, 0xDF,
-0x57, 0x34, 0x57, 0xDF,
-0x00, 0xE0,
-0x1D, 0x05,
+ 0x57, 0x34, 0x57, 0xDF,
+ 0x00, 0xE0,
+ 0x1D, 0x05,
-0x04, 0x80, 0x10, 0xEA,
-0x89, 0xE2,
-0x2B, 0x30,
+ 0x04, 0x80, 0x10, 0xEA,
+ 0x89, 0xE2,
+ 0x2B, 0x30,
-0x3F, 0xC1, 0x1D, 0xBD,
-0x00, 0x80, 0x00, 0xE8,
+ 0x3F, 0xC1, 0x1D, 0xBD,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0xA0, 0x68,
-0xBF, 0x25,
-0x00, 0x80, 0x00, 0xE8,
+ 0xA0, 0x68,
+ 0xBF, 0x25,
+ 0x00, 0x80, 0x00, 0xE8,
-0x20, 0xC0, 0x20, 0xAF,
-0x28, 0x05,
-0x97, 0x74,
+ 0x20, 0xC0, 0x20, 0xAF,
+ 0x28, 0x05,
+ 0x97, 0x74,
-0x00, 0xE0,
-0x2A, 0x10,
-0x16, 0xC0, 0x20, 0xE9,
+ 0x00, 0xE0,
+ 0x2A, 0x10,
+ 0x16, 0xC0, 0x20, 0xE9,
-0x04, 0x80, 0x10, 0xEA,
-0x8C, 0xE2,
-0x95, 0x05,
+ 0x04, 0x80, 0x10, 0xEA,
+ 0x8C, 0xE2,
+ 0x95, 0x05,
-0x28, 0xC1, 0x28, 0xAD,
-0x1F, 0xC1, 0x15, 0xBD,
+ 0x28, 0xC1, 0x28, 0xAD,
+ 0x1F, 0xC1, 0x15, 0xBD,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0xA8, 0x67,
-0x9F, 0x6B,
-0x00, 0x80, 0x00, 0xE8,
+ 0xA8, 0x67,
+ 0x9F, 0x6B,
+ 0x00, 0x80, 0x00, 0xE8,
-0x28, 0xC0, 0x28, 0xAD,
-0x1D, 0x25,
-0x20, 0x05,
+ 0x28, 0xC0, 0x28, 0xAD,
+ 0x1D, 0x25,
+ 0x20, 0x05,
-0x28, 0x32, 0x80, 0xAD,
-0x40, 0x2A, 0x40, 0xBD,
+ 0x28, 0x32, 0x80, 0xAD,
+ 0x40, 0x2A, 0x40, 0xBD,
-0x1C, 0x80, 0x20, 0xE9,
-0x20, 0x33, 0x20, 0xAD,
+ 0x1C, 0x80, 0x20, 0xE9,
+ 0x20, 0x33, 0x20, 0xAD,
-0x20, 0x73,
-0x00, 0xE0,
-0xB6, 0x49, 0x51, 0xBB,
+ 0x20, 0x73,
+ 0x00, 0xE0,
+ 0xB6, 0x49, 0x51, 0xBB,
-0x26, 0x2F, 0xB0, 0xE8,
-0x19, 0x20, 0x20, 0xE9,
+ 0x26, 0x2F, 0xB0, 0xE8,
+ 0x19, 0x20, 0x20, 0xE9,
-0x35, 0x20, 0x35, 0xDF,
-0x3D, 0x20, 0x3D, 0xDF,
+ 0x35, 0x20, 0x35, 0xDF,
+ 0x3D, 0x20, 0x3D, 0xDF,
-0x15, 0x20, 0x15, 0xDF,
-0x1D, 0x20, 0x1D, 0xDF,
+ 0x15, 0x20, 0x15, 0xDF,
+ 0x1D, 0x20, 0x1D, 0xDF,
-0x26, 0xD0, 0x26, 0xCD,
-0x29, 0x49, 0x2A, 0xB8,
+ 0x26, 0xD0, 0x26, 0xCD,
+ 0x29, 0x49, 0x2A, 0xB8,
-0x26, 0x40, 0x80, 0xBD,
-0x3B, 0x48, 0x50, 0xBD,
+ 0x26, 0x40, 0x80, 0xBD,
+ 0x3B, 0x48, 0x50, 0xBD,
-0x3E, 0x54, 0x57, 0x9F,
-0x00, 0xE0,
-0x82, 0xE1,
+ 0x3E, 0x54, 0x57, 0x9F,
+ 0x00, 0xE0,
+ 0x82, 0xE1,
-0x1E, 0xAF, 0x59, 0x9F,
-0x00, 0x80, 0x00, 0xE8,
+ 0x1E, 0xAF, 0x59, 0x9F,
+ 0x00, 0x80, 0x00, 0xE8,
-0x26, 0x30,
-0x29, 0x30,
-0x48, 0x3C, 0x48, 0xAD,
+ 0x26, 0x30,
+ 0x29, 0x30,
+ 0x48, 0x3C, 0x48, 0xAD,
-0x2B, 0x72,
-0xC2, 0xE1,
-0x2C, 0xC0, 0x44, 0xC2,
+ 0x2B, 0x72,
+ 0xC2, 0xE1,
+ 0x2C, 0xC0, 0x44, 0xC2,
-0x05, 0x24, 0x34, 0xBF,
-0x0D, 0x24, 0x2C, 0xBF,
+ 0x05, 0x24, 0x34, 0xBF,
+ 0x0D, 0x24, 0x2C, 0xBF,
-0x2D, 0x46, 0x4E, 0xBF,
-0x25, 0x46, 0x56, 0xBF,
+ 0x2D, 0x46, 0x4E, 0xBF,
+ 0x25, 0x46, 0x56, 0xBF,
-0x20, 0x1D, 0x6F, 0x8F,
-0x32, 0x3E, 0x5F, 0xE9,
+ 0x20, 0x1D, 0x6F, 0x8F,
+ 0x32, 0x3E, 0x5F, 0xE9,
-0x3E, 0x50, 0x56, 0x9F,
-0x00, 0xE0,
-0x3B, 0x30,
+ 0x3E, 0x50, 0x56, 0x9F,
+ 0x00, 0xE0,
+ 0x3B, 0x30,
-0x1E, 0x8F, 0x51, 0x9F,
-0x33, 0x1E, 0x5F, 0xE9,
+ 0x1E, 0x8F, 0x51, 0x9F,
+ 0x33, 0x1E, 0x5F, 0xE9,
-0x05, 0x44, 0x54, 0xB2,
-0x0D, 0x44, 0x4C, 0xB2,
+ 0x05, 0x44, 0x54, 0xB2,
+ 0x0D, 0x44, 0x4C, 0xB2,
-0x19, 0xC0, 0xB0, 0xE8,
-0x34, 0xC0, 0x44, 0xC4,
+ 0x19, 0xC0, 0xB0, 0xE8,
+ 0x34, 0xC0, 0x44, 0xC4,
-0x33, 0x73,
-0x00, 0xE0,
-0x3E, 0x62, 0x57, 0x9F,
+ 0x33, 0x73,
+ 0x00, 0xE0,
+ 0x3E, 0x62, 0x57, 0x9F,
-0x1E, 0xAF, 0x59, 0x9F,
-0x00, 0xE0,
-0x0D, 0x20,
+ 0x1E, 0xAF, 0x59, 0x9F,
+ 0x00, 0xE0,
+ 0x0D, 0x20,
-0x84, 0x3E, 0x58, 0xE9,
-0x28, 0x1D, 0x6F, 0x8F,
+ 0x84, 0x3E, 0x58, 0xE9,
+ 0x28, 0x1D, 0x6F, 0x8F,
-0x05, 0x20,
-0x00, 0xE0,
-0x85, 0x1E, 0x58, 0xE9,
+ 0x05, 0x20,
+ 0x00, 0xE0,
+ 0x85, 0x1E, 0x58, 0xE9,
-0x9B, 0x3B, 0x33, 0xDF,
-0x20, 0x20, 0x42, 0xAF,
+ 0x9B, 0x3B, 0x33, 0xDF,
+ 0x20, 0x20, 0x42, 0xAF,
-0x30, 0x42, 0x56, 0x9F,
-0x80, 0x3E, 0x57, 0xE9,
+ 0x30, 0x42, 0x56, 0x9F,
+ 0x80, 0x3E, 0x57, 0xE9,
-0x3F, 0x8F, 0x51, 0x9F,
-0x30, 0x80, 0x5F, 0xE9,
+ 0x3F, 0x8F, 0x51, 0x9F,
+ 0x30, 0x80, 0x5F, 0xE9,
-0x28, 0x28, 0x24, 0xAF,
-0x81, 0x1E, 0x57, 0xE9,
+ 0x28, 0x28, 0x24, 0xAF,
+ 0x81, 0x1E, 0x57, 0xE9,
-0x05, 0x47, 0x57, 0xBF,
-0x0D, 0x47, 0x4F, 0xBF,
+ 0x05, 0x47, 0x57, 0xBF,
+ 0x0D, 0x47, 0x4F, 0xBF,
-0x88, 0x80, 0x58, 0xE9,
-0x1B, 0x29, 0x1B, 0xDF,
+ 0x88, 0x80, 0x58, 0xE9,
+ 0x1B, 0x29, 0x1B, 0xDF,
-0x30, 0x1D, 0x6F, 0x8F,
-0x3A, 0x30, 0x4F, 0xE9,
+ 0x30, 0x1D, 0x6F, 0x8F,
+ 0x3A, 0x30, 0x4F, 0xE9,
-0x1C, 0x30, 0x26, 0xDF,
-0x09, 0xE3,
-0x3B, 0x05,
+ 0x1C, 0x30, 0x26, 0xDF,
+ 0x09, 0xE3,
+ 0x3B, 0x05,
-0x3E, 0x50, 0x56, 0x9F,
-0x3B, 0x3F, 0x4F, 0xE9,
+ 0x3E, 0x50, 0x56, 0x9F,
+ 0x3B, 0x3F, 0x4F, 0xE9,
-0x1E, 0x8F, 0x51, 0x9F,
-0x00, 0xE0,
-0xAC, 0x20,
+ 0x1E, 0x8F, 0x51, 0x9F,
+ 0x00, 0xE0,
+ 0xAC, 0x20,
-0x2D, 0x44, 0x4C, 0xB4,
-0x2C, 0x1C, 0xC0, 0xAF,
+ 0x2D, 0x44, 0x4C, 0xB4,
+ 0x2C, 0x1C, 0xC0, 0xAF,
-0x25, 0x44, 0x54, 0xB4,
-0x00, 0xE0,
-0xC8, 0x30,
+ 0x25, 0x44, 0x54, 0xB4,
+ 0x00, 0xE0,
+ 0xC8, 0x30,
-0x30, 0x46, 0x30, 0xAF,
-0x1B, 0x1B, 0x48, 0xAF,
+ 0x30, 0x46, 0x30, 0xAF,
+ 0x1B, 0x1B, 0x48, 0xAF,
-0x00, 0xE0,
-0x25, 0x20,
-0x38, 0x2C, 0x4F, 0xE9,
+ 0x00, 0xE0,
+ 0x25, 0x20,
+ 0x38, 0x2C, 0x4F, 0xE9,
-0x86, 0x80, 0x57, 0xE9,
-0x38, 0x1D, 0x6F, 0x8F,
+ 0x86, 0x80, 0x57, 0xE9,
+ 0x38, 0x1D, 0x6F, 0x8F,
-0x28, 0x74,
-0x00, 0xE0,
-0x0D, 0x44, 0x4C, 0xB0,
+ 0x28, 0x74,
+ 0x00, 0xE0,
+ 0x0D, 0x44, 0x4C, 0xB0,
-0x05, 0x44, 0x54, 0xB0,
-0x2D, 0x20,
-0x9B, 0x10,
+ 0x05, 0x44, 0x54, 0xB0,
+ 0x2D, 0x20,
+ 0x9B, 0x10,
-0x82, 0x3E, 0x57, 0xE9,
-0x32, 0xF0, 0x1B, 0xCD,
+ 0x82, 0x3E, 0x57, 0xE9,
+ 0x32, 0xF0, 0x1B, 0xCD,
-0x1E, 0xBD, 0x59, 0x9F,
-0x83, 0x1E, 0x57, 0xE9,
+ 0x1E, 0xBD, 0x59, 0x9F,
+ 0x83, 0x1E, 0x57, 0xE9,
-0x38, 0x47, 0x38, 0xAF,
-0x34, 0x20,
-0x2A, 0x30,
+ 0x38, 0x47, 0x38, 0xAF,
+ 0x34, 0x20,
+ 0x2A, 0x30,
-0x00, 0xE0,
-0x0D, 0x20,
-0x32, 0x20,
-0x05, 0x20,
+ 0x00, 0xE0,
+ 0x0D, 0x20,
+ 0x32, 0x20,
+ 0x05, 0x20,
-0x87, 0x80, 0x57, 0xE9,
-0x1F, 0x54, 0x57, 0x9F,
+ 0x87, 0x80, 0x57, 0xE9,
+ 0x1F, 0x54, 0x57, 0x9F,
-0x17, 0x42, 0x56, 0x9F,
-0x00, 0xE0,
-0x3B, 0x6A,
+ 0x17, 0x42, 0x56, 0x9F,
+ 0x00, 0xE0,
+ 0x3B, 0x6A,
-0x3F, 0x8F, 0x51, 0x9F,
-0x37, 0x1E, 0x4F, 0xE9,
+ 0x3F, 0x8F, 0x51, 0x9F,
+ 0x37, 0x1E, 0x4F, 0xE9,
-0x37, 0x32, 0x2A, 0xAF,
-0x00, 0xE0,
-0x32, 0x00,
+ 0x37, 0x32, 0x2A, 0xAF,
+ 0x00, 0xE0,
+ 0x32, 0x00,
-0x00, 0x80, 0x00, 0xE8,
-0x27, 0xC0, 0x44, 0xC0,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x27, 0xC0, 0x44, 0xC0,
-0x36, 0x1F, 0x4F, 0xE9,
-0x1F, 0x1F, 0x26, 0xDF,
+ 0x36, 0x1F, 0x4F, 0xE9,
+ 0x1F, 0x1F, 0x26, 0xDF,
-0x37, 0x1B, 0x37, 0xBF,
-0x17, 0x26, 0x17, 0xDF,
+ 0x37, 0x1B, 0x37, 0xBF,
+ 0x17, 0x26, 0x17, 0xDF,
-0x3E, 0x17, 0x4F, 0xE9,
-0x3F, 0x3F, 0x4F, 0xE9,
+ 0x3E, 0x17, 0x4F, 0xE9,
+ 0x3F, 0x3F, 0x4F, 0xE9,
-0x34, 0x1F, 0x34, 0xAF,
-0x2B, 0x05,
-0xA7, 0x20,
+ 0x34, 0x1F, 0x34, 0xAF,
+ 0x2B, 0x05,
+ 0xA7, 0x20,
-0x33, 0x2B, 0x37, 0xDF,
-0x27, 0x17, 0xC0, 0xAF,
+ 0x33, 0x2B, 0x37, 0xDF,
+ 0x27, 0x17, 0xC0, 0xAF,
-0x34, 0x80, 0x4F, 0xE9,
-0x00, 0x80, 0x00, 0xE8,
+ 0x34, 0x80, 0x4F, 0xE9,
+ 0x00, 0x80, 0x00, 0xE8,
-0x2D, 0x21, 0x1A, 0xB0,
-0x25, 0x21, 0x31, 0xB0,
+ 0x2D, 0x21, 0x1A, 0xB0,
+ 0x25, 0x21, 0x31, 0xB0,
-0x0D, 0x21, 0x1A, 0xB2,
-0x05, 0x21, 0x31, 0xB2,
+ 0x0D, 0x21, 0x1A, 0xB2,
+ 0x05, 0x21, 0x31, 0xB2,
-0x03, 0x80, 0x2A, 0xEA,
-0x17, 0xC1, 0x2B, 0xBD,
+ 0x03, 0x80, 0x2A, 0xEA,
+ 0x17, 0xC1, 0x2B, 0xBD,
-0x2D, 0x20,
-0x25, 0x20,
-0x05, 0x20,
-0x0D, 0x20,
+ 0x2D, 0x20,
+ 0x25, 0x20,
+ 0x05, 0x20,
+ 0x0D, 0x20,
-0xB3, 0x68,
-0x97, 0x25,
-0x00, 0x80, 0x00, 0xE8,
+ 0xB3, 0x68,
+ 0x97, 0x25,
+ 0x00, 0x80, 0x00, 0xE8,
-0x33, 0xC0, 0x33, 0xAF,
-0x2F, 0xC0, 0x21, 0xC0,
+ 0x33, 0xC0, 0x33, 0xAF,
+ 0x2F, 0xC0, 0x21, 0xC0,
-0x16, 0x42, 0x56, 0x9F,
-0x3C, 0x27, 0x4F, 0xE9,
+ 0x16, 0x42, 0x56, 0x9F,
+ 0x3C, 0x27, 0x4F, 0xE9,
-0x1E, 0x62, 0x57, 0x9F,
-0x00, 0x80, 0x00, 0xE8,
+ 0x1E, 0x62, 0x57, 0x9F,
+ 0x00, 0x80, 0x00, 0xE8,
-0x25, 0x21, 0x31, 0xB4,
-0x2D, 0x21, 0x1A, 0xB4,
+ 0x25, 0x21, 0x31, 0xB4,
+ 0x2D, 0x21, 0x1A, 0xB4,
-0x3F, 0x2F, 0x5D, 0x9F,
-0x00, 0x80, 0x00, 0xE8,
+ 0x3F, 0x2F, 0x5D, 0x9F,
+ 0x00, 0x80, 0x00, 0xE8,
-0x33, 0x05,
-0x00, 0xE0,
-0x28, 0x19, 0x60, 0xEC,
+ 0x33, 0x05,
+ 0x00, 0xE0,
+ 0x28, 0x19, 0x60, 0xEC,
-0x0D, 0x44, 0x4C, 0xB6,
-0x05, 0x44, 0x54, 0xB6,
+ 0x0D, 0x44, 0x4C, 0xB6,
+ 0x05, 0x44, 0x54, 0xB6,
-0x37, 0x0F, 0x5C, 0x9F,
-0x00, 0xE0,
-0x2F, 0x20,
+ 0x37, 0x0F, 0x5C, 0x9F,
+ 0x00, 0xE0,
+ 0x2F, 0x20,
-0x23, 0x3B, 0x33, 0xAD,
-0x1E, 0x26, 0x1E, 0xDF,
+ 0x23, 0x3B, 0x33, 0xAD,
+ 0x1E, 0x26, 0x1E, 0xDF,
-0xA7, 0x1E, 0x4F, 0xE9,
-0x17, 0x26, 0x16, 0xDF,
+ 0xA7, 0x1E, 0x4F, 0xE9,
+ 0x17, 0x26, 0x16, 0xDF,
-0x2D, 0x20,
-0x00, 0xE0,
-0xA8, 0x3F, 0x4F, 0xE9,
+ 0x2D, 0x20,
+ 0x00, 0xE0,
+ 0xA8, 0x3F, 0x4F, 0xE9,
-0x2F, 0x2F, 0x1E, 0xAF,
-0x25, 0x20,
-0x00, 0xE0,
+ 0x2F, 0x2F, 0x1E, 0xAF,
+ 0x25, 0x20,
+ 0x00, 0xE0,
-0xA4, 0x16, 0x4F, 0xE9,
-0x0F, 0xC0, 0x21, 0xC2,
+ 0xA4, 0x16, 0x4F, 0xE9,
+ 0x0F, 0xC0, 0x21, 0xC2,
-0xA6, 0x80, 0x4F, 0xE9,
-0x1F, 0x62, 0x57, 0x9F,
+ 0xA6, 0x80, 0x4F, 0xE9,
+ 0x1F, 0x62, 0x57, 0x9F,
-0x0D, 0x20,
-0x05, 0x20,
-0x00, 0x80, 0x00, 0xE8,
+ 0x0D, 0x20,
+ 0x05, 0x20,
+ 0x00, 0x80, 0x00, 0xE8,
-0x3F, 0x2F, 0x5D, 0x9F,
-0x00, 0xE0,
-0x0F, 0x20,
+ 0x3F, 0x2F, 0x5D, 0x9F,
+ 0x00, 0xE0,
+ 0x0F, 0x20,
-0x17, 0x50, 0x56, 0x9F,
-0xA5, 0x37, 0x4F, 0xE9,
+ 0x17, 0x50, 0x56, 0x9F,
+ 0xA5, 0x37, 0x4F, 0xE9,
-0x06, 0xC0, 0x21, 0xC4,
-0x0F, 0x17, 0x0F, 0xAF,
+ 0x06, 0xC0, 0x21, 0xC4,
+ 0x0F, 0x17, 0x0F, 0xAF,
-0x37, 0x0F, 0x5C, 0x9F,
-0x00, 0x80, 0x00, 0xE8,
+ 0x37, 0x0F, 0x5C, 0x9F,
+ 0x00, 0x80, 0x00, 0xE8,
-0x2F, 0xC0, 0x44, 0xC6,
-0xA3, 0x80, 0x4F, 0xE9,
+ 0x2F, 0xC0, 0x44, 0xC6,
+ 0xA3, 0x80, 0x4F, 0xE9,
-0x06, 0x20,
-0x00, 0xE0,
-0x1F, 0x26, 0x1F, 0xDF,
+ 0x06, 0x20,
+ 0x00, 0xE0,
+ 0x1F, 0x26, 0x1F, 0xDF,
-0x17, 0x26, 0x17, 0xDF,
-0x9D, 0x17, 0x4F, 0xE9,
+ 0x17, 0x26, 0x17, 0xDF,
+ 0x9D, 0x17, 0x4F, 0xE9,
-0xA1, 0x1F, 0x4F, 0xE9,
-0xA2, 0x3F, 0x4F, 0xE9,
+ 0xA1, 0x1F, 0x4F, 0xE9,
+ 0xA2, 0x3F, 0x4F, 0xE9,
-0x06, 0x06, 0x1F, 0xAF,
-0x00, 0xE0,
-0xAF, 0x20,
+ 0x06, 0x06, 0x1F, 0xAF,
+ 0x00, 0xE0,
+ 0xAF, 0x20,
-0x9E, 0x37, 0x4F, 0xE9,
-0x2F, 0x17, 0x2F, 0xAF,
+ 0x9E, 0x37, 0x4F, 0xE9,
+ 0x2F, 0x17, 0x2F, 0xAF,
-0xA0, 0x80, 0x4F, 0xE9,
-0x00, 0x80, 0x00, 0xE8,
+ 0xA0, 0x80, 0x4F, 0xE9,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x9C, 0x80, 0x4F, 0xE9,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x9C, 0x80, 0x4F, 0xE9,
-0x00, 0x80, 0x00, 0xE8,
-0x57, 0x39, 0x20, 0xE9,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x57, 0x39, 0x20, 0xE9,
-0x16, 0x28, 0x20, 0xE9,
-0x1D, 0x3B, 0x20, 0xE9,
+ 0x16, 0x28, 0x20, 0xE9,
+ 0x1D, 0x3B, 0x20, 0xE9,
-0x1E, 0x2B, 0x20, 0xE9,
-0x2B, 0x32, 0x20, 0xE9,
+ 0x1E, 0x2B, 0x20, 0xE9,
+ 0x2B, 0x32, 0x20, 0xE9,
-0x1C, 0x23, 0x20, 0xE9,
-0x57, 0x36, 0x20, 0xE9,
+ 0x1C, 0x23, 0x20, 0xE9,
+ 0x57, 0x36, 0x20, 0xE9,
-0x00, 0x80, 0xA0, 0xE9,
-0x40, 0x40, 0xD8, 0xEC,
+ 0x00, 0x80, 0xA0, 0xE9,
+ 0x40, 0x40, 0xD8, 0xEC,
-0xFF, 0x80, 0xC0, 0xE9,
-0x90, 0xE2,
-0x00, 0xE0,
+ 0xFF, 0x80, 0xC0, 0xE9,
+ 0x90, 0xE2,
+ 0x00, 0xE0,
-0x68, 0xFF, 0x20, 0xEA,
-0x19, 0xC8, 0xC1, 0xCD,
+ 0x68, 0xFF, 0x20, 0xEA,
+ 0x19, 0xC8, 0xC1, 0xCD,
-0x1F, 0xD7, 0x18, 0xBD,
-0x3F, 0xD7, 0x22, 0xBD,
+ 0x1F, 0xD7, 0x18, 0xBD,
+ 0x3F, 0xD7, 0x22, 0xBD,
-0x9F, 0x41, 0x49, 0xBD,
-0x00, 0x80, 0x00, 0xE8,
+ 0x9F, 0x41, 0x49, 0xBD,
+ 0x00, 0x80, 0x00, 0xE8,
-0x25, 0x41, 0x49, 0xBD,
-0x2D, 0x41, 0x51, 0xBD,
+ 0x25, 0x41, 0x49, 0xBD,
+ 0x2D, 0x41, 0x51, 0xBD,
-0x0D, 0x80, 0x07, 0xEA,
-0x00, 0x80, 0x00, 0xE8,
+ 0x0D, 0x80, 0x07, 0xEA,
+ 0x00, 0x80, 0x00, 0xE8,
-0x35, 0x40, 0x48, 0xBD,
-0x3D, 0x40, 0x50, 0xBD,
+ 0x35, 0x40, 0x48, 0xBD,
+ 0x3D, 0x40, 0x50, 0xBD,
-0x00, 0x80, 0x00, 0xE8,
-0x25, 0x30,
-0x2D, 0x30,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x25, 0x30,
+ 0x2D, 0x30,
-0x35, 0x30,
-0xB5, 0x30,
-0xBD, 0x30,
-0x3D, 0x30,
+ 0x35, 0x30,
+ 0xB5, 0x30,
+ 0xBD, 0x30,
+ 0x3D, 0x30,
-0x9C, 0xA7, 0x5B, 0x9F,
-0x00, 0x80, 0x00, 0xE8,
+ 0x9C, 0xA7, 0x5B, 0x9F,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x67, 0xFF, 0x0A, 0xEA,
-0x00, 0x80, 0x00, 0xE8,
+ 0x67, 0xFF, 0x0A, 0xEA,
+ 0x00, 0x80, 0x00, 0xE8,
-0xC9, 0x41, 0xC8, 0xEC,
-0x42, 0xE1,
-0x00, 0xE0,
+ 0xC9, 0x41, 0xC8, 0xEC,
+ 0x42, 0xE1,
+ 0x00, 0xE0,
-0x65, 0xFF, 0x20, 0xEA,
-0x00, 0x80, 0x00, 0xE8,
+ 0x65, 0xFF, 0x20, 0xEA,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0xC8, 0x40, 0xC0, 0xEC,
-0x00, 0x80, 0x00, 0xE8,
+ 0xC8, 0x40, 0xC0, 0xEC,
+ 0x00, 0x80, 0x00, 0xE8,
-0x62, 0xFF, 0x20, 0xEA,
-0x00, 0x80, 0x00, 0xE8,
+ 0x62, 0xFF, 0x20, 0xEA,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
};
static unsigned char warp_g200_tgzsaf[] = {
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x98, 0xA0, 0xE9,
-0x40, 0x40, 0xD8, 0xEC,
+ 0x00, 0x98, 0xA0, 0xE9,
+ 0x40, 0x40, 0xD8, 0xEC,
-0xFF, 0x80, 0xC0, 0xE9,
-0x00, 0x80, 0x00, 0xE8,
+ 0xFF, 0x80, 0xC0, 0xE9,
+ 0x00, 0x80, 0x00, 0xE8,
-0x1F, 0xD7, 0x18, 0xBD,
-0x3F, 0xD7, 0x22, 0xBD,
+ 0x1F, 0xD7, 0x18, 0xBD,
+ 0x3F, 0xD7, 0x22, 0xBD,
-0x81, 0x04,
-0x89, 0x04,
-0x01, 0x04,
-0x09, 0x04,
+ 0x81, 0x04,
+ 0x89, 0x04,
+ 0x01, 0x04,
+ 0x09, 0x04,
-0xC9, 0x41, 0xC0, 0xEC,
-0x11, 0x04,
-0x00, 0xE0,
+ 0xC9, 0x41, 0xC0, 0xEC,
+ 0x11, 0x04,
+ 0x00, 0xE0,
-0x41, 0xCC, 0x41, 0xCD,
-0x49, 0xCC, 0x49, 0xCD,
+ 0x41, 0xCC, 0x41, 0xCD,
+ 0x49, 0xCC, 0x49, 0xCD,
-0xD1, 0x41, 0xC0, 0xEC,
-0x51, 0xCC, 0x51, 0xCD,
+ 0xD1, 0x41, 0xC0, 0xEC,
+ 0x51, 0xCC, 0x51, 0xCD,
-0x80, 0x04,
-0x10, 0x04,
-0x08, 0x04,
-0x00, 0xE0,
+ 0x80, 0x04,
+ 0x10, 0x04,
+ 0x08, 0x04,
+ 0x00, 0xE0,
-0x00, 0xCC, 0xC0, 0xCD,
-0xD1, 0x49, 0xC0, 0xEC,
+ 0x00, 0xCC, 0xC0, 0xCD,
+ 0xD1, 0x49, 0xC0, 0xEC,
-0x8A, 0x1F, 0x20, 0xE9,
-0x8B, 0x3F, 0x20, 0xE9,
+ 0x8A, 0x1F, 0x20, 0xE9,
+ 0x8B, 0x3F, 0x20, 0xE9,
-0x41, 0x3C, 0x41, 0xAD,
-0x49, 0x3C, 0x49, 0xAD,
+ 0x41, 0x3C, 0x41, 0xAD,
+ 0x49, 0x3C, 0x49, 0xAD,
-0x10, 0xCC, 0x10, 0xCD,
-0x08, 0xCC, 0x08, 0xCD,
+ 0x10, 0xCC, 0x10, 0xCD,
+ 0x08, 0xCC, 0x08, 0xCD,
-0xB9, 0x41, 0x49, 0xBB,
-0x1F, 0xF0, 0x41, 0xCD,
+ 0xB9, 0x41, 0x49, 0xBB,
+ 0x1F, 0xF0, 0x41, 0xCD,
-0x51, 0x3C, 0x51, 0xAD,
-0x00, 0x98, 0x80, 0xE9,
+ 0x51, 0x3C, 0x51, 0xAD,
+ 0x00, 0x98, 0x80, 0xE9,
-0x94, 0x80, 0x07, 0xEA,
-0x24, 0x1F, 0x20, 0xE9,
+ 0x94, 0x80, 0x07, 0xEA,
+ 0x24, 0x1F, 0x20, 0xE9,
-0x21, 0x45, 0x80, 0xE8,
-0x1A, 0x4D, 0x80, 0xE8,
+ 0x21, 0x45, 0x80, 0xE8,
+ 0x1A, 0x4D, 0x80, 0xE8,
-0x31, 0x55, 0x80, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x31, 0x55, 0x80, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x15, 0x41, 0x49, 0xBD,
-0x1D, 0x41, 0x51, 0xBD,
+ 0x15, 0x41, 0x49, 0xBD,
+ 0x1D, 0x41, 0x51, 0xBD,
-0x2E, 0x41, 0x2A, 0xB8,
-0x34, 0x53, 0xA0, 0xE8,
+ 0x2E, 0x41, 0x2A, 0xB8,
+ 0x34, 0x53, 0xA0, 0xE8,
-0x15, 0x30,
-0x1D, 0x30,
-0x58, 0xE3,
-0x00, 0xE0,
+ 0x15, 0x30,
+ 0x1D, 0x30,
+ 0x58, 0xE3,
+ 0x00, 0xE0,
-0xB5, 0x40, 0x48, 0xBD,
-0x3D, 0x40, 0x50, 0xBD,
+ 0xB5, 0x40, 0x48, 0xBD,
+ 0x3D, 0x40, 0x50, 0xBD,
-0x24, 0x43, 0xA0, 0xE8,
-0x2C, 0x4B, 0xA0, 0xE8,
+ 0x24, 0x43, 0xA0, 0xE8,
+ 0x2C, 0x4B, 0xA0, 0xE8,
-0x15, 0x72,
-0x09, 0xE3,
-0x00, 0xE0,
-0x1D, 0x72,
+ 0x15, 0x72,
+ 0x09, 0xE3,
+ 0x00, 0xE0,
+ 0x1D, 0x72,
-0x35, 0x30,
-0xB5, 0x30,
-0xBD, 0x30,
-0x3D, 0x30,
+ 0x35, 0x30,
+ 0xB5, 0x30,
+ 0xBD, 0x30,
+ 0x3D, 0x30,
-0x9C, 0x97, 0x57, 0x9F,
-0x00, 0x80, 0x00, 0xE8,
+ 0x9C, 0x97, 0x57, 0x9F,
+ 0x00, 0x80, 0x00, 0xE8,
-0x6C, 0x64, 0xC8, 0xEC,
-0x98, 0xE1,
-0xB5, 0x05,
+ 0x6C, 0x64, 0xC8, 0xEC,
+ 0x98, 0xE1,
+ 0xB5, 0x05,
-0xBD, 0x05,
-0x2E, 0x30,
-0x32, 0xC0, 0xA0, 0xE8,
+ 0xBD, 0x05,
+ 0x2E, 0x30,
+ 0x32, 0xC0, 0xA0, 0xE8,
-0x33, 0xC0, 0xA0, 0xE8,
-0x74, 0x64, 0xC8, 0xEC,
+ 0x33, 0xC0, 0xA0, 0xE8,
+ 0x74, 0x64, 0xC8, 0xEC,
-0x40, 0x3C, 0x40, 0xAD,
-0x32, 0x6A,
-0x2A, 0x30,
+ 0x40, 0x3C, 0x40, 0xAD,
+ 0x32, 0x6A,
+ 0x2A, 0x30,
-0x20, 0x73,
-0x33, 0x6A,
-0x00, 0xE0,
-0x28, 0x73,
+ 0x20, 0x73,
+ 0x33, 0x6A,
+ 0x00, 0xE0,
+ 0x28, 0x73,
-0x1C, 0x72,
-0x83, 0xE2,
-0x80, 0x80, 0x15, 0xEA,
+ 0x1C, 0x72,
+ 0x83, 0xE2,
+ 0x80, 0x80, 0x15, 0xEA,
-0xB8, 0x3D, 0x28, 0xDF,
-0x30, 0x35, 0x20, 0xDF,
+ 0xB8, 0x3D, 0x28, 0xDF,
+ 0x30, 0x35, 0x20, 0xDF,
-0x40, 0x30,
-0x00, 0xE0,
-0xCC, 0xE2,
-0x64, 0x72,
+ 0x40, 0x30,
+ 0x00, 0xE0,
+ 0xCC, 0xE2,
+ 0x64, 0x72,
-0x25, 0x42, 0x52, 0xBF,
-0x2D, 0x42, 0x4A, 0xBF,
+ 0x25, 0x42, 0x52, 0xBF,
+ 0x2D, 0x42, 0x4A, 0xBF,
-0x30, 0x2E, 0x30, 0xDF,
-0x38, 0x2E, 0x38, 0xDF,
+ 0x30, 0x2E, 0x30, 0xDF,
+ 0x38, 0x2E, 0x38, 0xDF,
-0x18, 0x1D, 0x45, 0xE9,
-0x1E, 0x15, 0x45, 0xE9,
+ 0x18, 0x1D, 0x45, 0xE9,
+ 0x1E, 0x15, 0x45, 0xE9,
-0x2B, 0x49, 0x51, 0xBD,
-0x00, 0xE0,
-0x1F, 0x73,
+ 0x2B, 0x49, 0x51, 0xBD,
+ 0x00, 0xE0,
+ 0x1F, 0x73,
-0x38, 0x38, 0x40, 0xAF,
-0x30, 0x30, 0x40, 0xAF,
+ 0x38, 0x38, 0x40, 0xAF,
+ 0x30, 0x30, 0x40, 0xAF,
-0x24, 0x1F, 0x24, 0xDF,
-0x1D, 0x32, 0x20, 0xE9,
+ 0x24, 0x1F, 0x24, 0xDF,
+ 0x1D, 0x32, 0x20, 0xE9,
-0x2C, 0x1F, 0x2C, 0xDF,
-0x1A, 0x33, 0x20, 0xE9,
+ 0x2C, 0x1F, 0x2C, 0xDF,
+ 0x1A, 0x33, 0x20, 0xE9,
-0xB0, 0x10,
-0x08, 0xE3,
-0x40, 0x10,
-0xB8, 0x10,
+ 0xB0, 0x10,
+ 0x08, 0xE3,
+ 0x40, 0x10,
+ 0xB8, 0x10,
-0x26, 0xF0, 0x30, 0xCD,
-0x2F, 0xF0, 0x38, 0xCD,
+ 0x26, 0xF0, 0x30, 0xCD,
+ 0x2F, 0xF0, 0x38, 0xCD,
-0x2B, 0x80, 0x20, 0xE9,
-0x2A, 0x80, 0x20, 0xE9,
+ 0x2B, 0x80, 0x20, 0xE9,
+ 0x2A, 0x80, 0x20, 0xE9,
-0xA6, 0x20,
-0x88, 0xE2,
-0x00, 0xE0,
-0xAF, 0x20,
+ 0xA6, 0x20,
+ 0x88, 0xE2,
+ 0x00, 0xE0,
+ 0xAF, 0x20,
-0x28, 0x2A, 0x26, 0xAF,
-0x20, 0x2A, 0xC0, 0xAF,
+ 0x28, 0x2A, 0x26, 0xAF,
+ 0x20, 0x2A, 0xC0, 0xAF,
-0x34, 0x1F, 0x34, 0xDF,
-0x46, 0x24, 0x46, 0xDF,
+ 0x34, 0x1F, 0x34, 0xDF,
+ 0x46, 0x24, 0x46, 0xDF,
-0x28, 0x30, 0x80, 0xBF,
-0x20, 0x38, 0x80, 0xBF,
+ 0x28, 0x30, 0x80, 0xBF,
+ 0x20, 0x38, 0x80, 0xBF,
-0x47, 0x24, 0x47, 0xDF,
-0x4E, 0x2C, 0x4E, 0xDF,
+ 0x47, 0x24, 0x47, 0xDF,
+ 0x4E, 0x2C, 0x4E, 0xDF,
-0x4F, 0x2C, 0x4F, 0xDF,
-0x56, 0x34, 0x56, 0xDF,
+ 0x4F, 0x2C, 0x4F, 0xDF,
+ 0x56, 0x34, 0x56, 0xDF,
-0x28, 0x15, 0x28, 0xDF,
-0x20, 0x1D, 0x20, 0xDF,
+ 0x28, 0x15, 0x28, 0xDF,
+ 0x20, 0x1D, 0x20, 0xDF,
-0x57, 0x34, 0x57, 0xDF,
-0x00, 0xE0,
-0x1D, 0x05,
+ 0x57, 0x34, 0x57, 0xDF,
+ 0x00, 0xE0,
+ 0x1D, 0x05,
-0x04, 0x80, 0x10, 0xEA,
-0x89, 0xE2,
-0x2B, 0x30,
+ 0x04, 0x80, 0x10, 0xEA,
+ 0x89, 0xE2,
+ 0x2B, 0x30,
-0x3F, 0xC1, 0x1D, 0xBD,
-0x00, 0x80, 0x00, 0xE8,
+ 0x3F, 0xC1, 0x1D, 0xBD,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0xA0, 0x68,
-0xBF, 0x25,
-0x00, 0x80, 0x00, 0xE8,
+ 0xA0, 0x68,
+ 0xBF, 0x25,
+ 0x00, 0x80, 0x00, 0xE8,
-0x20, 0xC0, 0x20, 0xAF,
-0x28, 0x05,
-0x97, 0x74,
+ 0x20, 0xC0, 0x20, 0xAF,
+ 0x28, 0x05,
+ 0x97, 0x74,
-0x00, 0xE0,
-0x2A, 0x10,
-0x16, 0xC0, 0x20, 0xE9,
+ 0x00, 0xE0,
+ 0x2A, 0x10,
+ 0x16, 0xC0, 0x20, 0xE9,
-0x04, 0x80, 0x10, 0xEA,
-0x8C, 0xE2,
-0x95, 0x05,
+ 0x04, 0x80, 0x10, 0xEA,
+ 0x8C, 0xE2,
+ 0x95, 0x05,
-0x28, 0xC1, 0x28, 0xAD,
-0x1F, 0xC1, 0x15, 0xBD,
+ 0x28, 0xC1, 0x28, 0xAD,
+ 0x1F, 0xC1, 0x15, 0xBD,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0xA8, 0x67,
-0x9F, 0x6B,
-0x00, 0x80, 0x00, 0xE8,
+ 0xA8, 0x67,
+ 0x9F, 0x6B,
+ 0x00, 0x80, 0x00, 0xE8,
-0x28, 0xC0, 0x28, 0xAD,
-0x1D, 0x25,
-0x20, 0x05,
+ 0x28, 0xC0, 0x28, 0xAD,
+ 0x1D, 0x25,
+ 0x20, 0x05,
-0x28, 0x32, 0x80, 0xAD,
-0x40, 0x2A, 0x40, 0xBD,
+ 0x28, 0x32, 0x80, 0xAD,
+ 0x40, 0x2A, 0x40, 0xBD,
-0x1C, 0x80, 0x20, 0xE9,
-0x20, 0x33, 0x20, 0xAD,
+ 0x1C, 0x80, 0x20, 0xE9,
+ 0x20, 0x33, 0x20, 0xAD,
-0x20, 0x73,
-0x00, 0xE0,
-0xB6, 0x49, 0x51, 0xBB,
+ 0x20, 0x73,
+ 0x00, 0xE0,
+ 0xB6, 0x49, 0x51, 0xBB,
-0x26, 0x2F, 0xB0, 0xE8,
-0x19, 0x20, 0x20, 0xE9,
+ 0x26, 0x2F, 0xB0, 0xE8,
+ 0x19, 0x20, 0x20, 0xE9,
-0x35, 0x20, 0x35, 0xDF,
-0x3D, 0x20, 0x3D, 0xDF,
+ 0x35, 0x20, 0x35, 0xDF,
+ 0x3D, 0x20, 0x3D, 0xDF,
-0x15, 0x20, 0x15, 0xDF,
-0x1D, 0x20, 0x1D, 0xDF,
+ 0x15, 0x20, 0x15, 0xDF,
+ 0x1D, 0x20, 0x1D, 0xDF,
-0x26, 0xD0, 0x26, 0xCD,
-0x29, 0x49, 0x2A, 0xB8,
+ 0x26, 0xD0, 0x26, 0xCD,
+ 0x29, 0x49, 0x2A, 0xB8,
-0x26, 0x40, 0x80, 0xBD,
-0x3B, 0x48, 0x50, 0xBD,
+ 0x26, 0x40, 0x80, 0xBD,
+ 0x3B, 0x48, 0x50, 0xBD,
-0x3E, 0x54, 0x57, 0x9F,
-0x00, 0xE0,
-0x82, 0xE1,
+ 0x3E, 0x54, 0x57, 0x9F,
+ 0x00, 0xE0,
+ 0x82, 0xE1,
-0x1E, 0xAF, 0x59, 0x9F,
-0x00, 0x80, 0x00, 0xE8,
+ 0x1E, 0xAF, 0x59, 0x9F,
+ 0x00, 0x80, 0x00, 0xE8,
-0x26, 0x30,
-0x29, 0x30,
-0x48, 0x3C, 0x48, 0xAD,
+ 0x26, 0x30,
+ 0x29, 0x30,
+ 0x48, 0x3C, 0x48, 0xAD,
-0x2B, 0x72,
-0xC2, 0xE1,
-0x2C, 0xC0, 0x44, 0xC2,
+ 0x2B, 0x72,
+ 0xC2, 0xE1,
+ 0x2C, 0xC0, 0x44, 0xC2,
-0x05, 0x24, 0x34, 0xBF,
-0x0D, 0x24, 0x2C, 0xBF,
+ 0x05, 0x24, 0x34, 0xBF,
+ 0x0D, 0x24, 0x2C, 0xBF,
-0x2D, 0x46, 0x4E, 0xBF,
-0x25, 0x46, 0x56, 0xBF,
+ 0x2D, 0x46, 0x4E, 0xBF,
+ 0x25, 0x46, 0x56, 0xBF,
-0x20, 0x1D, 0x6F, 0x8F,
-0x32, 0x3E, 0x5F, 0xE9,
+ 0x20, 0x1D, 0x6F, 0x8F,
+ 0x32, 0x3E, 0x5F, 0xE9,
-0x3E, 0x50, 0x56, 0x9F,
-0x00, 0xE0,
-0x3B, 0x30,
+ 0x3E, 0x50, 0x56, 0x9F,
+ 0x00, 0xE0,
+ 0x3B, 0x30,
-0x1E, 0x8F, 0x51, 0x9F,
-0x33, 0x1E, 0x5F, 0xE9,
+ 0x1E, 0x8F, 0x51, 0x9F,
+ 0x33, 0x1E, 0x5F, 0xE9,
-0x05, 0x44, 0x54, 0xB2,
-0x0D, 0x44, 0x4C, 0xB2,
+ 0x05, 0x44, 0x54, 0xB2,
+ 0x0D, 0x44, 0x4C, 0xB2,
-0x19, 0xC0, 0xB0, 0xE8,
-0x34, 0xC0, 0x44, 0xC4,
+ 0x19, 0xC0, 0xB0, 0xE8,
+ 0x34, 0xC0, 0x44, 0xC4,
-0x33, 0x73,
-0x00, 0xE0,
-0x3E, 0x62, 0x57, 0x9F,
+ 0x33, 0x73,
+ 0x00, 0xE0,
+ 0x3E, 0x62, 0x57, 0x9F,
-0x1E, 0xAF, 0x59, 0x9F,
-0x00, 0xE0,
-0x0D, 0x20,
+ 0x1E, 0xAF, 0x59, 0x9F,
+ 0x00, 0xE0,
+ 0x0D, 0x20,
-0x84, 0x3E, 0x58, 0xE9,
-0x28, 0x1D, 0x6F, 0x8F,
+ 0x84, 0x3E, 0x58, 0xE9,
+ 0x28, 0x1D, 0x6F, 0x8F,
-0x05, 0x20,
-0x00, 0xE0,
-0x85, 0x1E, 0x58, 0xE9,
+ 0x05, 0x20,
+ 0x00, 0xE0,
+ 0x85, 0x1E, 0x58, 0xE9,
-0x9B, 0x3B, 0x33, 0xDF,
-0x20, 0x20, 0x42, 0xAF,
+ 0x9B, 0x3B, 0x33, 0xDF,
+ 0x20, 0x20, 0x42, 0xAF,
-0x30, 0x42, 0x56, 0x9F,
-0x80, 0x3E, 0x57, 0xE9,
+ 0x30, 0x42, 0x56, 0x9F,
+ 0x80, 0x3E, 0x57, 0xE9,
-0x3F, 0x8F, 0x51, 0x9F,
-0x30, 0x80, 0x5F, 0xE9,
+ 0x3F, 0x8F, 0x51, 0x9F,
+ 0x30, 0x80, 0x5F, 0xE9,
-0x28, 0x28, 0x24, 0xAF,
-0x81, 0x1E, 0x57, 0xE9,
+ 0x28, 0x28, 0x24, 0xAF,
+ 0x81, 0x1E, 0x57, 0xE9,
-0x05, 0x47, 0x57, 0xBF,
-0x0D, 0x47, 0x4F, 0xBF,
+ 0x05, 0x47, 0x57, 0xBF,
+ 0x0D, 0x47, 0x4F, 0xBF,
-0x88, 0x80, 0x58, 0xE9,
-0x1B, 0x29, 0x1B, 0xDF,
+ 0x88, 0x80, 0x58, 0xE9,
+ 0x1B, 0x29, 0x1B, 0xDF,
-0x30, 0x1D, 0x6F, 0x8F,
-0x3A, 0x30, 0x4F, 0xE9,
+ 0x30, 0x1D, 0x6F, 0x8F,
+ 0x3A, 0x30, 0x4F, 0xE9,
-0x1C, 0x30, 0x26, 0xDF,
-0x09, 0xE3,
-0x3B, 0x05,
+ 0x1C, 0x30, 0x26, 0xDF,
+ 0x09, 0xE3,
+ 0x3B, 0x05,
-0x3E, 0x50, 0x56, 0x9F,
-0x3B, 0x3F, 0x4F, 0xE9,
+ 0x3E, 0x50, 0x56, 0x9F,
+ 0x3B, 0x3F, 0x4F, 0xE9,
-0x1E, 0x8F, 0x51, 0x9F,
-0x00, 0xE0,
-0xAC, 0x20,
+ 0x1E, 0x8F, 0x51, 0x9F,
+ 0x00, 0xE0,
+ 0xAC, 0x20,
-0x2D, 0x44, 0x4C, 0xB4,
-0x2C, 0x1C, 0xC0, 0xAF,
+ 0x2D, 0x44, 0x4C, 0xB4,
+ 0x2C, 0x1C, 0xC0, 0xAF,
-0x25, 0x44, 0x54, 0xB4,
-0x00, 0xE0,
-0xC8, 0x30,
+ 0x25, 0x44, 0x54, 0xB4,
+ 0x00, 0xE0,
+ 0xC8, 0x30,
-0x30, 0x46, 0x30, 0xAF,
-0x1B, 0x1B, 0x48, 0xAF,
+ 0x30, 0x46, 0x30, 0xAF,
+ 0x1B, 0x1B, 0x48, 0xAF,
-0x00, 0xE0,
-0x25, 0x20,
-0x38, 0x2C, 0x4F, 0xE9,
+ 0x00, 0xE0,
+ 0x25, 0x20,
+ 0x38, 0x2C, 0x4F, 0xE9,
-0x86, 0x80, 0x57, 0xE9,
-0x38, 0x1D, 0x6F, 0x8F,
+ 0x86, 0x80, 0x57, 0xE9,
+ 0x38, 0x1D, 0x6F, 0x8F,
-0x28, 0x74,
-0x00, 0xE0,
-0x0D, 0x44, 0x4C, 0xB0,
+ 0x28, 0x74,
+ 0x00, 0xE0,
+ 0x0D, 0x44, 0x4C, 0xB0,
-0x05, 0x44, 0x54, 0xB0,
-0x2D, 0x20,
-0x9B, 0x10,
+ 0x05, 0x44, 0x54, 0xB0,
+ 0x2D, 0x20,
+ 0x9B, 0x10,
-0x82, 0x3E, 0x57, 0xE9,
-0x32, 0xF0, 0x1B, 0xCD,
+ 0x82, 0x3E, 0x57, 0xE9,
+ 0x32, 0xF0, 0x1B, 0xCD,
-0x1E, 0xBD, 0x59, 0x9F,
-0x83, 0x1E, 0x57, 0xE9,
+ 0x1E, 0xBD, 0x59, 0x9F,
+ 0x83, 0x1E, 0x57, 0xE9,
-0x38, 0x47, 0x38, 0xAF,
-0x34, 0x20,
-0x2A, 0x30,
+ 0x38, 0x47, 0x38, 0xAF,
+ 0x34, 0x20,
+ 0x2A, 0x30,
-0x00, 0xE0,
-0x0D, 0x20,
-0x32, 0x20,
-0x05, 0x20,
+ 0x00, 0xE0,
+ 0x0D, 0x20,
+ 0x32, 0x20,
+ 0x05, 0x20,
-0x87, 0x80, 0x57, 0xE9,
-0x1F, 0x54, 0x57, 0x9F,
+ 0x87, 0x80, 0x57, 0xE9,
+ 0x1F, 0x54, 0x57, 0x9F,
-0x17, 0x42, 0x56, 0x9F,
-0x00, 0xE0,
-0x3B, 0x6A,
+ 0x17, 0x42, 0x56, 0x9F,
+ 0x00, 0xE0,
+ 0x3B, 0x6A,
-0x3F, 0x8F, 0x51, 0x9F,
-0x37, 0x1E, 0x4F, 0xE9,
+ 0x3F, 0x8F, 0x51, 0x9F,
+ 0x37, 0x1E, 0x4F, 0xE9,
-0x37, 0x32, 0x2A, 0xAF,
-0x00, 0xE0,
-0x32, 0x00,
+ 0x37, 0x32, 0x2A, 0xAF,
+ 0x00, 0xE0,
+ 0x32, 0x00,
-0x00, 0x80, 0x00, 0xE8,
-0x27, 0xC0, 0x44, 0xC0,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x27, 0xC0, 0x44, 0xC0,
-0x36, 0x1F, 0x4F, 0xE9,
-0x1F, 0x1F, 0x26, 0xDF,
+ 0x36, 0x1F, 0x4F, 0xE9,
+ 0x1F, 0x1F, 0x26, 0xDF,
-0x37, 0x1B, 0x37, 0xBF,
-0x17, 0x26, 0x17, 0xDF,
+ 0x37, 0x1B, 0x37, 0xBF,
+ 0x17, 0x26, 0x17, 0xDF,
-0x3E, 0x17, 0x4F, 0xE9,
-0x3F, 0x3F, 0x4F, 0xE9,
+ 0x3E, 0x17, 0x4F, 0xE9,
+ 0x3F, 0x3F, 0x4F, 0xE9,
-0x34, 0x1F, 0x34, 0xAF,
-0x2B, 0x05,
-0xA7, 0x20,
+ 0x34, 0x1F, 0x34, 0xAF,
+ 0x2B, 0x05,
+ 0xA7, 0x20,
-0x33, 0x2B, 0x37, 0xDF,
-0x27, 0x17, 0xC0, 0xAF,
+ 0x33, 0x2B, 0x37, 0xDF,
+ 0x27, 0x17, 0xC0, 0xAF,
-0x34, 0x80, 0x4F, 0xE9,
-0x00, 0x80, 0x00, 0xE8,
+ 0x34, 0x80, 0x4F, 0xE9,
+ 0x00, 0x80, 0x00, 0xE8,
-0x2D, 0x21, 0x1A, 0xB0,
-0x25, 0x21, 0x31, 0xB0,
+ 0x2D, 0x21, 0x1A, 0xB0,
+ 0x25, 0x21, 0x31, 0xB0,
-0x0D, 0x21, 0x1A, 0xB2,
-0x05, 0x21, 0x31, 0xB2,
+ 0x0D, 0x21, 0x1A, 0xB2,
+ 0x05, 0x21, 0x31, 0xB2,
-0x03, 0x80, 0x2A, 0xEA,
-0x17, 0xC1, 0x2B, 0xBD,
+ 0x03, 0x80, 0x2A, 0xEA,
+ 0x17, 0xC1, 0x2B, 0xBD,
-0x2D, 0x20,
-0x25, 0x20,
-0x05, 0x20,
-0x0D, 0x20,
+ 0x2D, 0x20,
+ 0x25, 0x20,
+ 0x05, 0x20,
+ 0x0D, 0x20,
-0xB3, 0x68,
-0x97, 0x25,
-0x00, 0x80, 0x00, 0xE8,
+ 0xB3, 0x68,
+ 0x97, 0x25,
+ 0x00, 0x80, 0x00, 0xE8,
-0x33, 0xC0, 0x33, 0xAF,
-0x2F, 0xC0, 0x21, 0xC0,
+ 0x33, 0xC0, 0x33, 0xAF,
+ 0x2F, 0xC0, 0x21, 0xC0,
-0x16, 0x42, 0x56, 0x9F,
-0x3C, 0x27, 0x4F, 0xE9,
+ 0x16, 0x42, 0x56, 0x9F,
+ 0x3C, 0x27, 0x4F, 0xE9,
-0x1E, 0x62, 0x57, 0x9F,
-0x00, 0x80, 0x00, 0xE8,
+ 0x1E, 0x62, 0x57, 0x9F,
+ 0x00, 0x80, 0x00, 0xE8,
-0x25, 0x21, 0x31, 0xB4,
-0x2D, 0x21, 0x1A, 0xB4,
+ 0x25, 0x21, 0x31, 0xB4,
+ 0x2D, 0x21, 0x1A, 0xB4,
-0x3F, 0x2F, 0x5D, 0x9F,
-0x00, 0x80, 0x00, 0xE8,
+ 0x3F, 0x2F, 0x5D, 0x9F,
+ 0x00, 0x80, 0x00, 0xE8,
-0x33, 0x05,
-0x00, 0xE0,
-0x28, 0x19, 0x60, 0xEC,
+ 0x33, 0x05,
+ 0x00, 0xE0,
+ 0x28, 0x19, 0x60, 0xEC,
-0x0D, 0x21, 0x1A, 0xB6,
-0x05, 0x21, 0x31, 0xB6,
+ 0x0D, 0x21, 0x1A, 0xB6,
+ 0x05, 0x21, 0x31, 0xB6,
-0x37, 0x0F, 0x5C, 0x9F,
-0x00, 0xE0,
-0x2F, 0x20,
+ 0x37, 0x0F, 0x5C, 0x9F,
+ 0x00, 0xE0,
+ 0x2F, 0x20,
-0x23, 0x3B, 0x33, 0xAD,
-0x1E, 0x26, 0x1E, 0xDF,
+ 0x23, 0x3B, 0x33, 0xAD,
+ 0x1E, 0x26, 0x1E, 0xDF,
-0xA7, 0x1E, 0x4F, 0xE9,
-0x17, 0x26, 0x16, 0xDF,
+ 0xA7, 0x1E, 0x4F, 0xE9,
+ 0x17, 0x26, 0x16, 0xDF,
-0x2D, 0x20,
-0x00, 0xE0,
-0xA8, 0x3F, 0x4F, 0xE9,
+ 0x2D, 0x20,
+ 0x00, 0xE0,
+ 0xA8, 0x3F, 0x4F, 0xE9,
-0x2F, 0x2F, 0x1E, 0xAF,
-0x25, 0x20,
-0x00, 0xE0,
+ 0x2F, 0x2F, 0x1E, 0xAF,
+ 0x25, 0x20,
+ 0x00, 0xE0,
-0xA4, 0x16, 0x4F, 0xE9,
-0x0F, 0xC0, 0x21, 0xC2,
+ 0xA4, 0x16, 0x4F, 0xE9,
+ 0x0F, 0xC0, 0x21, 0xC2,
-0xA6, 0x80, 0x4F, 0xE9,
-0x1F, 0x62, 0x57, 0x9F,
+ 0xA6, 0x80, 0x4F, 0xE9,
+ 0x1F, 0x62, 0x57, 0x9F,
-0x0D, 0x20,
-0x05, 0x20,
-0x2F, 0xC0, 0x21, 0xC6,
+ 0x0D, 0x20,
+ 0x05, 0x20,
+ 0x2F, 0xC0, 0x21, 0xC6,
-0x2D, 0x44, 0x4C, 0xB6,
-0x25, 0x44, 0x54, 0xB6,
+ 0x2D, 0x44, 0x4C, 0xB6,
+ 0x25, 0x44, 0x54, 0xB6,
-0x3F, 0x2F, 0x5D, 0x9F,
-0x00, 0xE0,
-0x0F, 0x20,
+ 0x3F, 0x2F, 0x5D, 0x9F,
+ 0x00, 0xE0,
+ 0x0F, 0x20,
-0x2D, 0x20,
-0x25, 0x20,
-0x07, 0xC0, 0x44, 0xC6,
+ 0x2D, 0x20,
+ 0x25, 0x20,
+ 0x07, 0xC0, 0x44, 0xC6,
-0x17, 0x50, 0x56, 0x9F,
-0xA5, 0x37, 0x4F, 0xE9,
+ 0x17, 0x50, 0x56, 0x9F,
+ 0xA5, 0x37, 0x4F, 0xE9,
-0x06, 0xC0, 0x21, 0xC4,
-0x0F, 0x17, 0x0F, 0xAF,
+ 0x06, 0xC0, 0x21, 0xC4,
+ 0x0F, 0x17, 0x0F, 0xAF,
-0x37, 0x0F, 0x5C, 0x9F,
-0x00, 0x80, 0x00, 0xE8,
+ 0x37, 0x0F, 0x5C, 0x9F,
+ 0x00, 0x80, 0x00, 0xE8,
-0x1E, 0x62, 0x57, 0x9F,
-0x00, 0x80, 0x00, 0xE8,
+ 0x1E, 0x62, 0x57, 0x9F,
+ 0x00, 0x80, 0x00, 0xE8,
-0x3E, 0x3D, 0x5D, 0x9F,
-0x00, 0xE0,
-0x07, 0x20,
+ 0x3E, 0x3D, 0x5D, 0x9F,
+ 0x00, 0xE0,
+ 0x07, 0x20,
-0x2F, 0x20,
-0x00, 0xE0,
-0xA3, 0x0F, 0x4F, 0xE9,
+ 0x2F, 0x20,
+ 0x00, 0xE0,
+ 0xA3, 0x0F, 0x4F, 0xE9,
-0x06, 0x20,
-0x00, 0xE0,
-0x1F, 0x26, 0x1F, 0xDF,
+ 0x06, 0x20,
+ 0x00, 0xE0,
+ 0x1F, 0x26, 0x1F, 0xDF,
-0x17, 0x26, 0x17, 0xDF,
-0xA1, 0x1F, 0x4F, 0xE9,
+ 0x17, 0x26, 0x17, 0xDF,
+ 0xA1, 0x1F, 0x4F, 0xE9,
-0x1E, 0x26, 0x1E, 0xDF,
-0x9D, 0x1E, 0x4F, 0xE9,
+ 0x1E, 0x26, 0x1E, 0xDF,
+ 0x9D, 0x1E, 0x4F, 0xE9,
-0x35, 0x17, 0x4F, 0xE9,
-0xA2, 0x3F, 0x4F, 0xE9,
+ 0x35, 0x17, 0x4F, 0xE9,
+ 0xA2, 0x3F, 0x4F, 0xE9,
-0x06, 0x06, 0x1F, 0xAF,
-0x39, 0x37, 0x4F, 0xE9,
+ 0x06, 0x06, 0x1F, 0xAF,
+ 0x39, 0x37, 0x4F, 0xE9,
-0x2F, 0x2F, 0x17, 0xAF,
-0x07, 0x07, 0x1E, 0xAF,
+ 0x2F, 0x2F, 0x17, 0xAF,
+ 0x07, 0x07, 0x1E, 0xAF,
-0xA0, 0x80, 0x4F, 0xE9,
-0x9E, 0x3E, 0x4F, 0xE9,
+ 0xA0, 0x80, 0x4F, 0xE9,
+ 0x9E, 0x3E, 0x4F, 0xE9,
-0x31, 0x80, 0x4F, 0xE9,
-0x9C, 0x80, 0x4F, 0xE9,
+ 0x31, 0x80, 0x4F, 0xE9,
+ 0x9C, 0x80, 0x4F, 0xE9,
-0x00, 0x80, 0x00, 0xE8,
-0x57, 0x39, 0x20, 0xE9,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x57, 0x39, 0x20, 0xE9,
-0x16, 0x28, 0x20, 0xE9,
-0x1D, 0x3B, 0x20, 0xE9,
+ 0x16, 0x28, 0x20, 0xE9,
+ 0x1D, 0x3B, 0x20, 0xE9,
-0x1E, 0x2B, 0x20, 0xE9,
-0x2B, 0x32, 0x20, 0xE9,
+ 0x1E, 0x2B, 0x20, 0xE9,
+ 0x2B, 0x32, 0x20, 0xE9,
-0x1C, 0x23, 0x20, 0xE9,
-0x57, 0x36, 0x20, 0xE9,
+ 0x1C, 0x23, 0x20, 0xE9,
+ 0x57, 0x36, 0x20, 0xE9,
-0x00, 0x80, 0xA0, 0xE9,
-0x40, 0x40, 0xD8, 0xEC,
+ 0x00, 0x80, 0xA0, 0xE9,
+ 0x40, 0x40, 0xD8, 0xEC,
-0xFF, 0x80, 0xC0, 0xE9,
-0x90, 0xE2,
-0x00, 0xE0,
+ 0xFF, 0x80, 0xC0, 0xE9,
+ 0x90, 0xE2,
+ 0x00, 0xE0,
-0x63, 0xFF, 0x20, 0xEA,
-0x19, 0xC8, 0xC1, 0xCD,
+ 0x63, 0xFF, 0x20, 0xEA,
+ 0x19, 0xC8, 0xC1, 0xCD,
-0x1F, 0xD7, 0x18, 0xBD,
-0x3F, 0xD7, 0x22, 0xBD,
+ 0x1F, 0xD7, 0x18, 0xBD,
+ 0x3F, 0xD7, 0x22, 0xBD,
-0x9F, 0x41, 0x49, 0xBD,
-0x00, 0x80, 0x00, 0xE8,
+ 0x9F, 0x41, 0x49, 0xBD,
+ 0x00, 0x80, 0x00, 0xE8,
-0x25, 0x41, 0x49, 0xBD,
-0x2D, 0x41, 0x51, 0xBD,
+ 0x25, 0x41, 0x49, 0xBD,
+ 0x2D, 0x41, 0x51, 0xBD,
-0x0D, 0x80, 0x07, 0xEA,
-0x00, 0x80, 0x00, 0xE8,
+ 0x0D, 0x80, 0x07, 0xEA,
+ 0x00, 0x80, 0x00, 0xE8,
-0x35, 0x40, 0x48, 0xBD,
-0x3D, 0x40, 0x50, 0xBD,
+ 0x35, 0x40, 0x48, 0xBD,
+ 0x3D, 0x40, 0x50, 0xBD,
-0x00, 0x80, 0x00, 0xE8,
-0x25, 0x30,
-0x2D, 0x30,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x25, 0x30,
+ 0x2D, 0x30,
-0x35, 0x30,
-0xB5, 0x30,
-0xBD, 0x30,
-0x3D, 0x30,
+ 0x35, 0x30,
+ 0xB5, 0x30,
+ 0xBD, 0x30,
+ 0x3D, 0x30,
-0x9C, 0xA7, 0x5B, 0x9F,
-0x00, 0x80, 0x00, 0xE8,
+ 0x9C, 0xA7, 0x5B, 0x9F,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x62, 0xFF, 0x0A, 0xEA,
-0x00, 0x80, 0x00, 0xE8,
+ 0x62, 0xFF, 0x0A, 0xEA,
+ 0x00, 0x80, 0x00, 0xE8,
-0xC9, 0x41, 0xC8, 0xEC,
-0x42, 0xE1,
-0x00, 0xE0,
+ 0xC9, 0x41, 0xC8, 0xEC,
+ 0x42, 0xE1,
+ 0x00, 0xE0,
-0x60, 0xFF, 0x20, 0xEA,
-0x00, 0x80, 0x00, 0xE8,
+ 0x60, 0xFF, 0x20, 0xEA,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0xC8, 0x40, 0xC0, 0xEC,
-0x00, 0x80, 0x00, 0xE8,
+ 0xC8, 0x40, 0xC0, 0xEC,
+ 0x00, 0x80, 0x00, 0xE8,
-0x5D, 0xFF, 0x20, 0xEA,
-0x00, 0x80, 0x00, 0xE8,
+ 0x5D, 0xFF, 0x20, 0xEA,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
};
static unsigned char warp_g200_tgzsf[] = {
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x98, 0xA0, 0xE9,
-0x40, 0x40, 0xD8, 0xEC,
+ 0x00, 0x98, 0xA0, 0xE9,
+ 0x40, 0x40, 0xD8, 0xEC,
-0xFF, 0x80, 0xC0, 0xE9,
-0x00, 0x80, 0x00, 0xE8,
+ 0xFF, 0x80, 0xC0, 0xE9,
+ 0x00, 0x80, 0x00, 0xE8,
-0x1F, 0xD7, 0x18, 0xBD,
-0x3F, 0xD7, 0x22, 0xBD,
+ 0x1F, 0xD7, 0x18, 0xBD,
+ 0x3F, 0xD7, 0x22, 0xBD,
-0x81, 0x04,
-0x89, 0x04,
-0x01, 0x04,
-0x09, 0x04,
+ 0x81, 0x04,
+ 0x89, 0x04,
+ 0x01, 0x04,
+ 0x09, 0x04,
-0xC9, 0x41, 0xC0, 0xEC,
-0x11, 0x04,
-0x00, 0xE0,
+ 0xC9, 0x41, 0xC0, 0xEC,
+ 0x11, 0x04,
+ 0x00, 0xE0,
-0x41, 0xCC, 0x41, 0xCD,
-0x49, 0xCC, 0x49, 0xCD,
+ 0x41, 0xCC, 0x41, 0xCD,
+ 0x49, 0xCC, 0x49, 0xCD,
-0xD1, 0x41, 0xC0, 0xEC,
-0x51, 0xCC, 0x51, 0xCD,
+ 0xD1, 0x41, 0xC0, 0xEC,
+ 0x51, 0xCC, 0x51, 0xCD,
-0x80, 0x04,
-0x10, 0x04,
-0x08, 0x04,
-0x00, 0xE0,
+ 0x80, 0x04,
+ 0x10, 0x04,
+ 0x08, 0x04,
+ 0x00, 0xE0,
-0x00, 0xCC, 0xC0, 0xCD,
-0xD1, 0x49, 0xC0, 0xEC,
+ 0x00, 0xCC, 0xC0, 0xCD,
+ 0xD1, 0x49, 0xC0, 0xEC,
-0x8A, 0x1F, 0x20, 0xE9,
-0x8B, 0x3F, 0x20, 0xE9,
+ 0x8A, 0x1F, 0x20, 0xE9,
+ 0x8B, 0x3F, 0x20, 0xE9,
-0x41, 0x3C, 0x41, 0xAD,
-0x49, 0x3C, 0x49, 0xAD,
+ 0x41, 0x3C, 0x41, 0xAD,
+ 0x49, 0x3C, 0x49, 0xAD,
-0x10, 0xCC, 0x10, 0xCD,
-0x08, 0xCC, 0x08, 0xCD,
+ 0x10, 0xCC, 0x10, 0xCD,
+ 0x08, 0xCC, 0x08, 0xCD,
-0xB9, 0x41, 0x49, 0xBB,
-0x1F, 0xF0, 0x41, 0xCD,
+ 0xB9, 0x41, 0x49, 0xBB,
+ 0x1F, 0xF0, 0x41, 0xCD,
-0x51, 0x3C, 0x51, 0xAD,
-0x00, 0x98, 0x80, 0xE9,
+ 0x51, 0x3C, 0x51, 0xAD,
+ 0x00, 0x98, 0x80, 0xE9,
-0x8F, 0x80, 0x07, 0xEA,
-0x24, 0x1F, 0x20, 0xE9,
+ 0x8F, 0x80, 0x07, 0xEA,
+ 0x24, 0x1F, 0x20, 0xE9,
-0x21, 0x45, 0x80, 0xE8,
-0x1A, 0x4D, 0x80, 0xE8,
+ 0x21, 0x45, 0x80, 0xE8,
+ 0x1A, 0x4D, 0x80, 0xE8,
-0x31, 0x55, 0x80, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x31, 0x55, 0x80, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x15, 0x41, 0x49, 0xBD,
-0x1D, 0x41, 0x51, 0xBD,
+ 0x15, 0x41, 0x49, 0xBD,
+ 0x1D, 0x41, 0x51, 0xBD,
-0x2E, 0x41, 0x2A, 0xB8,
-0x34, 0x53, 0xA0, 0xE8,
+ 0x2E, 0x41, 0x2A, 0xB8,
+ 0x34, 0x53, 0xA0, 0xE8,
-0x15, 0x30,
-0x1D, 0x30,
-0x58, 0xE3,
-0x00, 0xE0,
+ 0x15, 0x30,
+ 0x1D, 0x30,
+ 0x58, 0xE3,
+ 0x00, 0xE0,
-0xB5, 0x40, 0x48, 0xBD,
-0x3D, 0x40, 0x50, 0xBD,
+ 0xB5, 0x40, 0x48, 0xBD,
+ 0x3D, 0x40, 0x50, 0xBD,
-0x24, 0x43, 0xA0, 0xE8,
-0x2C, 0x4B, 0xA0, 0xE8,
+ 0x24, 0x43, 0xA0, 0xE8,
+ 0x2C, 0x4B, 0xA0, 0xE8,
-0x15, 0x72,
-0x09, 0xE3,
-0x00, 0xE0,
-0x1D, 0x72,
+ 0x15, 0x72,
+ 0x09, 0xE3,
+ 0x00, 0xE0,
+ 0x1D, 0x72,
-0x35, 0x30,
-0xB5, 0x30,
-0xBD, 0x30,
-0x3D, 0x30,
+ 0x35, 0x30,
+ 0xB5, 0x30,
+ 0xBD, 0x30,
+ 0x3D, 0x30,
-0x9C, 0x97, 0x57, 0x9F,
-0x00, 0x80, 0x00, 0xE8,
+ 0x9C, 0x97, 0x57, 0x9F,
+ 0x00, 0x80, 0x00, 0xE8,
-0x6C, 0x64, 0xC8, 0xEC,
-0x98, 0xE1,
-0xB5, 0x05,
+ 0x6C, 0x64, 0xC8, 0xEC,
+ 0x98, 0xE1,
+ 0xB5, 0x05,
-0xBD, 0x05,
-0x2E, 0x30,
-0x32, 0xC0, 0xA0, 0xE8,
+ 0xBD, 0x05,
+ 0x2E, 0x30,
+ 0x32, 0xC0, 0xA0, 0xE8,
-0x33, 0xC0, 0xA0, 0xE8,
-0x74, 0x64, 0xC8, 0xEC,
+ 0x33, 0xC0, 0xA0, 0xE8,
+ 0x74, 0x64, 0xC8, 0xEC,
-0x40, 0x3C, 0x40, 0xAD,
-0x32, 0x6A,
-0x2A, 0x30,
+ 0x40, 0x3C, 0x40, 0xAD,
+ 0x32, 0x6A,
+ 0x2A, 0x30,
-0x20, 0x73,
-0x33, 0x6A,
-0x00, 0xE0,
-0x28, 0x73,
+ 0x20, 0x73,
+ 0x33, 0x6A,
+ 0x00, 0xE0,
+ 0x28, 0x73,
-0x1C, 0x72,
-0x83, 0xE2,
-0x7B, 0x80, 0x15, 0xEA,
+ 0x1C, 0x72,
+ 0x83, 0xE2,
+ 0x7B, 0x80, 0x15, 0xEA,
-0xB8, 0x3D, 0x28, 0xDF,
-0x30, 0x35, 0x20, 0xDF,
+ 0xB8, 0x3D, 0x28, 0xDF,
+ 0x30, 0x35, 0x20, 0xDF,
-0x40, 0x30,
-0x00, 0xE0,
-0xCC, 0xE2,
-0x64, 0x72,
+ 0x40, 0x30,
+ 0x00, 0xE0,
+ 0xCC, 0xE2,
+ 0x64, 0x72,
-0x25, 0x42, 0x52, 0xBF,
-0x2D, 0x42, 0x4A, 0xBF,
+ 0x25, 0x42, 0x52, 0xBF,
+ 0x2D, 0x42, 0x4A, 0xBF,
-0x30, 0x2E, 0x30, 0xDF,
-0x38, 0x2E, 0x38, 0xDF,
+ 0x30, 0x2E, 0x30, 0xDF,
+ 0x38, 0x2E, 0x38, 0xDF,
-0x18, 0x1D, 0x45, 0xE9,
-0x1E, 0x15, 0x45, 0xE9,
+ 0x18, 0x1D, 0x45, 0xE9,
+ 0x1E, 0x15, 0x45, 0xE9,
-0x2B, 0x49, 0x51, 0xBD,
-0x00, 0xE0,
-0x1F, 0x73,
+ 0x2B, 0x49, 0x51, 0xBD,
+ 0x00, 0xE0,
+ 0x1F, 0x73,
-0x38, 0x38, 0x40, 0xAF,
-0x30, 0x30, 0x40, 0xAF,
+ 0x38, 0x38, 0x40, 0xAF,
+ 0x30, 0x30, 0x40, 0xAF,
-0x24, 0x1F, 0x24, 0xDF,
-0x1D, 0x32, 0x20, 0xE9,
+ 0x24, 0x1F, 0x24, 0xDF,
+ 0x1D, 0x32, 0x20, 0xE9,
-0x2C, 0x1F, 0x2C, 0xDF,
-0x1A, 0x33, 0x20, 0xE9,
+ 0x2C, 0x1F, 0x2C, 0xDF,
+ 0x1A, 0x33, 0x20, 0xE9,
-0xB0, 0x10,
-0x08, 0xE3,
-0x40, 0x10,
-0xB8, 0x10,
+ 0xB0, 0x10,
+ 0x08, 0xE3,
+ 0x40, 0x10,
+ 0xB8, 0x10,
-0x26, 0xF0, 0x30, 0xCD,
-0x2F, 0xF0, 0x38, 0xCD,
+ 0x26, 0xF0, 0x30, 0xCD,
+ 0x2F, 0xF0, 0x38, 0xCD,
-0x2B, 0x80, 0x20, 0xE9,
-0x2A, 0x80, 0x20, 0xE9,
+ 0x2B, 0x80, 0x20, 0xE9,
+ 0x2A, 0x80, 0x20, 0xE9,
-0xA6, 0x20,
-0x88, 0xE2,
-0x00, 0xE0,
-0xAF, 0x20,
+ 0xA6, 0x20,
+ 0x88, 0xE2,
+ 0x00, 0xE0,
+ 0xAF, 0x20,
-0x28, 0x2A, 0x26, 0xAF,
-0x20, 0x2A, 0xC0, 0xAF,
+ 0x28, 0x2A, 0x26, 0xAF,
+ 0x20, 0x2A, 0xC0, 0xAF,
-0x34, 0x1F, 0x34, 0xDF,
-0x46, 0x24, 0x46, 0xDF,
+ 0x34, 0x1F, 0x34, 0xDF,
+ 0x46, 0x24, 0x46, 0xDF,
-0x28, 0x30, 0x80, 0xBF,
-0x20, 0x38, 0x80, 0xBF,
+ 0x28, 0x30, 0x80, 0xBF,
+ 0x20, 0x38, 0x80, 0xBF,
-0x47, 0x24, 0x47, 0xDF,
-0x4E, 0x2C, 0x4E, 0xDF,
+ 0x47, 0x24, 0x47, 0xDF,
+ 0x4E, 0x2C, 0x4E, 0xDF,
-0x4F, 0x2C, 0x4F, 0xDF,
-0x56, 0x34, 0x56, 0xDF,
+ 0x4F, 0x2C, 0x4F, 0xDF,
+ 0x56, 0x34, 0x56, 0xDF,
-0x28, 0x15, 0x28, 0xDF,
-0x20, 0x1D, 0x20, 0xDF,
+ 0x28, 0x15, 0x28, 0xDF,
+ 0x20, 0x1D, 0x20, 0xDF,
-0x57, 0x34, 0x57, 0xDF,
-0x00, 0xE0,
-0x1D, 0x05,
+ 0x57, 0x34, 0x57, 0xDF,
+ 0x00, 0xE0,
+ 0x1D, 0x05,
-0x04, 0x80, 0x10, 0xEA,
-0x89, 0xE2,
-0x2B, 0x30,
+ 0x04, 0x80, 0x10, 0xEA,
+ 0x89, 0xE2,
+ 0x2B, 0x30,
-0x3F, 0xC1, 0x1D, 0xBD,
-0x00, 0x80, 0x00, 0xE8,
+ 0x3F, 0xC1, 0x1D, 0xBD,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0xA0, 0x68,
-0xBF, 0x25,
-0x00, 0x80, 0x00, 0xE8,
+ 0xA0, 0x68,
+ 0xBF, 0x25,
+ 0x00, 0x80, 0x00, 0xE8,
-0x20, 0xC0, 0x20, 0xAF,
-0x28, 0x05,
-0x97, 0x74,
+ 0x20, 0xC0, 0x20, 0xAF,
+ 0x28, 0x05,
+ 0x97, 0x74,
-0x00, 0xE0,
-0x2A, 0x10,
-0x16, 0xC0, 0x20, 0xE9,
+ 0x00, 0xE0,
+ 0x2A, 0x10,
+ 0x16, 0xC0, 0x20, 0xE9,
-0x04, 0x80, 0x10, 0xEA,
-0x8C, 0xE2,
-0x95, 0x05,
+ 0x04, 0x80, 0x10, 0xEA,
+ 0x8C, 0xE2,
+ 0x95, 0x05,
-0x28, 0xC1, 0x28, 0xAD,
-0x1F, 0xC1, 0x15, 0xBD,
+ 0x28, 0xC1, 0x28, 0xAD,
+ 0x1F, 0xC1, 0x15, 0xBD,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0xA8, 0x67,
-0x9F, 0x6B,
-0x00, 0x80, 0x00, 0xE8,
+ 0xA8, 0x67,
+ 0x9F, 0x6B,
+ 0x00, 0x80, 0x00, 0xE8,
-0x28, 0xC0, 0x28, 0xAD,
-0x1D, 0x25,
-0x20, 0x05,
+ 0x28, 0xC0, 0x28, 0xAD,
+ 0x1D, 0x25,
+ 0x20, 0x05,
-0x28, 0x32, 0x80, 0xAD,
-0x40, 0x2A, 0x40, 0xBD,
+ 0x28, 0x32, 0x80, 0xAD,
+ 0x40, 0x2A, 0x40, 0xBD,
-0x1C, 0x80, 0x20, 0xE9,
-0x20, 0x33, 0x20, 0xAD,
+ 0x1C, 0x80, 0x20, 0xE9,
+ 0x20, 0x33, 0x20, 0xAD,
-0x20, 0x73,
-0x00, 0xE0,
-0xB6, 0x49, 0x51, 0xBB,
+ 0x20, 0x73,
+ 0x00, 0xE0,
+ 0xB6, 0x49, 0x51, 0xBB,
-0x26, 0x2F, 0xB0, 0xE8,
-0x19, 0x20, 0x20, 0xE9,
+ 0x26, 0x2F, 0xB0, 0xE8,
+ 0x19, 0x20, 0x20, 0xE9,
-0x35, 0x20, 0x35, 0xDF,
-0x3D, 0x20, 0x3D, 0xDF,
+ 0x35, 0x20, 0x35, 0xDF,
+ 0x3D, 0x20, 0x3D, 0xDF,
-0x15, 0x20, 0x15, 0xDF,
-0x1D, 0x20, 0x1D, 0xDF,
+ 0x15, 0x20, 0x15, 0xDF,
+ 0x1D, 0x20, 0x1D, 0xDF,
-0x26, 0xD0, 0x26, 0xCD,
-0x29, 0x49, 0x2A, 0xB8,
+ 0x26, 0xD0, 0x26, 0xCD,
+ 0x29, 0x49, 0x2A, 0xB8,
-0x26, 0x40, 0x80, 0xBD,
-0x3B, 0x48, 0x50, 0xBD,
+ 0x26, 0x40, 0x80, 0xBD,
+ 0x3B, 0x48, 0x50, 0xBD,
-0x3E, 0x54, 0x57, 0x9F,
-0x00, 0xE0,
-0x82, 0xE1,
+ 0x3E, 0x54, 0x57, 0x9F,
+ 0x00, 0xE0,
+ 0x82, 0xE1,
-0x1E, 0xAF, 0x59, 0x9F,
-0x00, 0x80, 0x00, 0xE8,
+ 0x1E, 0xAF, 0x59, 0x9F,
+ 0x00, 0x80, 0x00, 0xE8,
-0x26, 0x30,
-0x29, 0x30,
-0x48, 0x3C, 0x48, 0xAD,
+ 0x26, 0x30,
+ 0x29, 0x30,
+ 0x48, 0x3C, 0x48, 0xAD,
-0x2B, 0x72,
-0xC2, 0xE1,
-0x2C, 0xC0, 0x44, 0xC2,
+ 0x2B, 0x72,
+ 0xC2, 0xE1,
+ 0x2C, 0xC0, 0x44, 0xC2,
-0x05, 0x24, 0x34, 0xBF,
-0x0D, 0x24, 0x2C, 0xBF,
+ 0x05, 0x24, 0x34, 0xBF,
+ 0x0D, 0x24, 0x2C, 0xBF,
-0x2D, 0x46, 0x4E, 0xBF,
-0x25, 0x46, 0x56, 0xBF,
+ 0x2D, 0x46, 0x4E, 0xBF,
+ 0x25, 0x46, 0x56, 0xBF,
-0x20, 0x1D, 0x6F, 0x8F,
-0x32, 0x3E, 0x5F, 0xE9,
+ 0x20, 0x1D, 0x6F, 0x8F,
+ 0x32, 0x3E, 0x5F, 0xE9,
-0x3E, 0x50, 0x56, 0x9F,
-0x00, 0xE0,
-0x3B, 0x30,
+ 0x3E, 0x50, 0x56, 0x9F,
+ 0x00, 0xE0,
+ 0x3B, 0x30,
-0x1E, 0x8F, 0x51, 0x9F,
-0x33, 0x1E, 0x5F, 0xE9,
+ 0x1E, 0x8F, 0x51, 0x9F,
+ 0x33, 0x1E, 0x5F, 0xE9,
-0x05, 0x44, 0x54, 0xB2,
-0x0D, 0x44, 0x4C, 0xB2,
+ 0x05, 0x44, 0x54, 0xB2,
+ 0x0D, 0x44, 0x4C, 0xB2,
-0x19, 0xC0, 0xB0, 0xE8,
-0x34, 0xC0, 0x44, 0xC4,
+ 0x19, 0xC0, 0xB0, 0xE8,
+ 0x34, 0xC0, 0x44, 0xC4,
-0x33, 0x73,
-0x00, 0xE0,
-0x3E, 0x62, 0x57, 0x9F,
+ 0x33, 0x73,
+ 0x00, 0xE0,
+ 0x3E, 0x62, 0x57, 0x9F,
-0x1E, 0xAF, 0x59, 0x9F,
-0x00, 0xE0,
-0x0D, 0x20,
+ 0x1E, 0xAF, 0x59, 0x9F,
+ 0x00, 0xE0,
+ 0x0D, 0x20,
-0x84, 0x3E, 0x58, 0xE9,
-0x28, 0x1D, 0x6F, 0x8F,
+ 0x84, 0x3E, 0x58, 0xE9,
+ 0x28, 0x1D, 0x6F, 0x8F,
-0x05, 0x20,
-0x00, 0xE0,
-0x85, 0x1E, 0x58, 0xE9,
+ 0x05, 0x20,
+ 0x00, 0xE0,
+ 0x85, 0x1E, 0x58, 0xE9,
-0x9B, 0x3B, 0x33, 0xDF,
-0x20, 0x20, 0x42, 0xAF,
+ 0x9B, 0x3B, 0x33, 0xDF,
+ 0x20, 0x20, 0x42, 0xAF,
-0x30, 0x42, 0x56, 0x9F,
-0x80, 0x3E, 0x57, 0xE9,
+ 0x30, 0x42, 0x56, 0x9F,
+ 0x80, 0x3E, 0x57, 0xE9,
-0x3F, 0x8F, 0x51, 0x9F,
-0x30, 0x80, 0x5F, 0xE9,
+ 0x3F, 0x8F, 0x51, 0x9F,
+ 0x30, 0x80, 0x5F, 0xE9,
-0x28, 0x28, 0x24, 0xAF,
-0x81, 0x1E, 0x57, 0xE9,
+ 0x28, 0x28, 0x24, 0xAF,
+ 0x81, 0x1E, 0x57, 0xE9,
-0x05, 0x47, 0x57, 0xBF,
-0x0D, 0x47, 0x4F, 0xBF,
+ 0x05, 0x47, 0x57, 0xBF,
+ 0x0D, 0x47, 0x4F, 0xBF,
-0x88, 0x80, 0x58, 0xE9,
-0x1B, 0x29, 0x1B, 0xDF,
+ 0x88, 0x80, 0x58, 0xE9,
+ 0x1B, 0x29, 0x1B, 0xDF,
-0x30, 0x1D, 0x6F, 0x8F,
-0x3A, 0x30, 0x4F, 0xE9,
+ 0x30, 0x1D, 0x6F, 0x8F,
+ 0x3A, 0x30, 0x4F, 0xE9,
-0x1C, 0x30, 0x26, 0xDF,
-0x09, 0xE3,
-0x3B, 0x05,
+ 0x1C, 0x30, 0x26, 0xDF,
+ 0x09, 0xE3,
+ 0x3B, 0x05,
-0x3E, 0x50, 0x56, 0x9F,
-0x3B, 0x3F, 0x4F, 0xE9,
+ 0x3E, 0x50, 0x56, 0x9F,
+ 0x3B, 0x3F, 0x4F, 0xE9,
-0x1E, 0x8F, 0x51, 0x9F,
-0x00, 0xE0,
-0xAC, 0x20,
+ 0x1E, 0x8F, 0x51, 0x9F,
+ 0x00, 0xE0,
+ 0xAC, 0x20,
-0x2D, 0x44, 0x4C, 0xB4,
-0x2C, 0x1C, 0xC0, 0xAF,
+ 0x2D, 0x44, 0x4C, 0xB4,
+ 0x2C, 0x1C, 0xC0, 0xAF,
-0x25, 0x44, 0x54, 0xB4,
-0x00, 0xE0,
-0xC8, 0x30,
+ 0x25, 0x44, 0x54, 0xB4,
+ 0x00, 0xE0,
+ 0xC8, 0x30,
-0x30, 0x46, 0x30, 0xAF,
-0x1B, 0x1B, 0x48, 0xAF,
+ 0x30, 0x46, 0x30, 0xAF,
+ 0x1B, 0x1B, 0x48, 0xAF,
-0x00, 0xE0,
-0x25, 0x20,
-0x38, 0x2C, 0x4F, 0xE9,
+ 0x00, 0xE0,
+ 0x25, 0x20,
+ 0x38, 0x2C, 0x4F, 0xE9,
-0x86, 0x80, 0x57, 0xE9,
-0x38, 0x1D, 0x6F, 0x8F,
+ 0x86, 0x80, 0x57, 0xE9,
+ 0x38, 0x1D, 0x6F, 0x8F,
-0x28, 0x74,
-0x00, 0xE0,
-0x0D, 0x44, 0x4C, 0xB0,
+ 0x28, 0x74,
+ 0x00, 0xE0,
+ 0x0D, 0x44, 0x4C, 0xB0,
-0x05, 0x44, 0x54, 0xB0,
-0x2D, 0x20,
-0x9B, 0x10,
+ 0x05, 0x44, 0x54, 0xB0,
+ 0x2D, 0x20,
+ 0x9B, 0x10,
-0x82, 0x3E, 0x57, 0xE9,
-0x32, 0xF0, 0x1B, 0xCD,
+ 0x82, 0x3E, 0x57, 0xE9,
+ 0x32, 0xF0, 0x1B, 0xCD,
-0x1E, 0xBD, 0x59, 0x9F,
-0x83, 0x1E, 0x57, 0xE9,
+ 0x1E, 0xBD, 0x59, 0x9F,
+ 0x83, 0x1E, 0x57, 0xE9,
-0x38, 0x47, 0x38, 0xAF,
-0x34, 0x20,
-0x2A, 0x30,
+ 0x38, 0x47, 0x38, 0xAF,
+ 0x34, 0x20,
+ 0x2A, 0x30,
-0x00, 0xE0,
-0x0D, 0x20,
-0x32, 0x20,
-0x05, 0x20,
+ 0x00, 0xE0,
+ 0x0D, 0x20,
+ 0x32, 0x20,
+ 0x05, 0x20,
-0x87, 0x80, 0x57, 0xE9,
-0x1F, 0x54, 0x57, 0x9F,
+ 0x87, 0x80, 0x57, 0xE9,
+ 0x1F, 0x54, 0x57, 0x9F,
-0x17, 0x42, 0x56, 0x9F,
-0x00, 0xE0,
-0x3B, 0x6A,
+ 0x17, 0x42, 0x56, 0x9F,
+ 0x00, 0xE0,
+ 0x3B, 0x6A,
-0x3F, 0x8F, 0x51, 0x9F,
-0x37, 0x1E, 0x4F, 0xE9,
+ 0x3F, 0x8F, 0x51, 0x9F,
+ 0x37, 0x1E, 0x4F, 0xE9,
-0x37, 0x32, 0x2A, 0xAF,
-0x00, 0xE0,
-0x32, 0x00,
+ 0x37, 0x32, 0x2A, 0xAF,
+ 0x00, 0xE0,
+ 0x32, 0x00,
-0x00, 0x80, 0x00, 0xE8,
-0x27, 0xC0, 0x44, 0xC0,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x27, 0xC0, 0x44, 0xC0,
-0x36, 0x1F, 0x4F, 0xE9,
-0x1F, 0x1F, 0x26, 0xDF,
+ 0x36, 0x1F, 0x4F, 0xE9,
+ 0x1F, 0x1F, 0x26, 0xDF,
-0x37, 0x1B, 0x37, 0xBF,
-0x17, 0x26, 0x17, 0xDF,
+ 0x37, 0x1B, 0x37, 0xBF,
+ 0x17, 0x26, 0x17, 0xDF,
-0x3E, 0x17, 0x4F, 0xE9,
-0x3F, 0x3F, 0x4F, 0xE9,
+ 0x3E, 0x17, 0x4F, 0xE9,
+ 0x3F, 0x3F, 0x4F, 0xE9,
-0x34, 0x1F, 0x34, 0xAF,
-0x2B, 0x05,
-0xA7, 0x20,
+ 0x34, 0x1F, 0x34, 0xAF,
+ 0x2B, 0x05,
+ 0xA7, 0x20,
-0x33, 0x2B, 0x37, 0xDF,
-0x27, 0x17, 0xC0, 0xAF,
+ 0x33, 0x2B, 0x37, 0xDF,
+ 0x27, 0x17, 0xC0, 0xAF,
-0x34, 0x80, 0x4F, 0xE9,
-0x00, 0x80, 0x00, 0xE8,
+ 0x34, 0x80, 0x4F, 0xE9,
+ 0x00, 0x80, 0x00, 0xE8,
-0x2D, 0x21, 0x1A, 0xB0,
-0x25, 0x21, 0x31, 0xB0,
+ 0x2D, 0x21, 0x1A, 0xB0,
+ 0x25, 0x21, 0x31, 0xB0,
-0x0D, 0x21, 0x1A, 0xB2,
-0x05, 0x21, 0x31, 0xB2,
+ 0x0D, 0x21, 0x1A, 0xB2,
+ 0x05, 0x21, 0x31, 0xB2,
-0x03, 0x80, 0x2A, 0xEA,
-0x17, 0xC1, 0x2B, 0xBD,
+ 0x03, 0x80, 0x2A, 0xEA,
+ 0x17, 0xC1, 0x2B, 0xBD,
-0x2D, 0x20,
-0x25, 0x20,
-0x05, 0x20,
-0x0D, 0x20,
+ 0x2D, 0x20,
+ 0x25, 0x20,
+ 0x05, 0x20,
+ 0x0D, 0x20,
-0xB3, 0x68,
-0x97, 0x25,
-0x00, 0x80, 0x00, 0xE8,
+ 0xB3, 0x68,
+ 0x97, 0x25,
+ 0x00, 0x80, 0x00, 0xE8,
-0x33, 0xC0, 0x33, 0xAF,
-0x2F, 0xC0, 0x21, 0xC0,
+ 0x33, 0xC0, 0x33, 0xAF,
+ 0x2F, 0xC0, 0x21, 0xC0,
-0x16, 0x42, 0x56, 0x9F,
-0x3C, 0x27, 0x4F, 0xE9,
+ 0x16, 0x42, 0x56, 0x9F,
+ 0x3C, 0x27, 0x4F, 0xE9,
-0x1E, 0x62, 0x57, 0x9F,
-0x00, 0x80, 0x00, 0xE8,
+ 0x1E, 0x62, 0x57, 0x9F,
+ 0x00, 0x80, 0x00, 0xE8,
-0x25, 0x21, 0x31, 0xB4,
-0x2D, 0x21, 0x1A, 0xB4,
+ 0x25, 0x21, 0x31, 0xB4,
+ 0x2D, 0x21, 0x1A, 0xB4,
-0x3F, 0x2F, 0x5D, 0x9F,
-0x00, 0x80, 0x00, 0xE8,
+ 0x3F, 0x2F, 0x5D, 0x9F,
+ 0x00, 0x80, 0x00, 0xE8,
-0x33, 0x05,
-0x00, 0xE0,
-0x28, 0x19, 0x60, 0xEC,
+ 0x33, 0x05,
+ 0x00, 0xE0,
+ 0x28, 0x19, 0x60, 0xEC,
-0x0D, 0x21, 0x1A, 0xB6,
-0x05, 0x21, 0x31, 0xB6,
+ 0x0D, 0x21, 0x1A, 0xB6,
+ 0x05, 0x21, 0x31, 0xB6,
-0x37, 0x0F, 0x5C, 0x9F,
-0x00, 0xE0,
-0x2F, 0x20,
+ 0x37, 0x0F, 0x5C, 0x9F,
+ 0x00, 0xE0,
+ 0x2F, 0x20,
-0x23, 0x3B, 0x33, 0xAD,
-0x1E, 0x26, 0x1E, 0xDF,
+ 0x23, 0x3B, 0x33, 0xAD,
+ 0x1E, 0x26, 0x1E, 0xDF,
-0xA7, 0x1E, 0x4F, 0xE9,
-0x17, 0x26, 0x16, 0xDF,
+ 0xA7, 0x1E, 0x4F, 0xE9,
+ 0x17, 0x26, 0x16, 0xDF,
-0x2D, 0x20,
-0x00, 0xE0,
-0xA8, 0x3F, 0x4F, 0xE9,
+ 0x2D, 0x20,
+ 0x00, 0xE0,
+ 0xA8, 0x3F, 0x4F, 0xE9,
-0x2F, 0x2F, 0x1E, 0xAF,
-0x25, 0x20,
-0x00, 0xE0,
+ 0x2F, 0x2F, 0x1E, 0xAF,
+ 0x25, 0x20,
+ 0x00, 0xE0,
-0xA4, 0x16, 0x4F, 0xE9,
-0x0F, 0xC0, 0x21, 0xC2,
+ 0xA4, 0x16, 0x4F, 0xE9,
+ 0x0F, 0xC0, 0x21, 0xC2,
-0xA6, 0x80, 0x4F, 0xE9,
-0x1F, 0x62, 0x57, 0x9F,
+ 0xA6, 0x80, 0x4F, 0xE9,
+ 0x1F, 0x62, 0x57, 0x9F,
-0x0D, 0x20,
-0x05, 0x20,
-0x2F, 0xC0, 0x21, 0xC6,
+ 0x0D, 0x20,
+ 0x05, 0x20,
+ 0x2F, 0xC0, 0x21, 0xC6,
-0x3F, 0x2F, 0x5D, 0x9F,
-0x00, 0xE0,
-0x0F, 0x20,
+ 0x3F, 0x2F, 0x5D, 0x9F,
+ 0x00, 0xE0,
+ 0x0F, 0x20,
-0x17, 0x50, 0x56, 0x9F,
-0xA5, 0x37, 0x4F, 0xE9,
+ 0x17, 0x50, 0x56, 0x9F,
+ 0xA5, 0x37, 0x4F, 0xE9,
-0x06, 0xC0, 0x21, 0xC4,
-0x0F, 0x17, 0x0F, 0xAF,
+ 0x06, 0xC0, 0x21, 0xC4,
+ 0x0F, 0x17, 0x0F, 0xAF,
-0x37, 0x0F, 0x5C, 0x9F,
-0x00, 0x80, 0x00, 0xE8,
+ 0x37, 0x0F, 0x5C, 0x9F,
+ 0x00, 0x80, 0x00, 0xE8,
-0x2F, 0x20,
-0x00, 0xE0,
-0xA3, 0x80, 0x4F, 0xE9,
+ 0x2F, 0x20,
+ 0x00, 0xE0,
+ 0xA3, 0x80, 0x4F, 0xE9,
-0x06, 0x20,
-0x00, 0xE0,
-0x1F, 0x26, 0x1F, 0xDF,
+ 0x06, 0x20,
+ 0x00, 0xE0,
+ 0x1F, 0x26, 0x1F, 0xDF,
-0x17, 0x26, 0x17, 0xDF,
-0x35, 0x17, 0x4F, 0xE9,
+ 0x17, 0x26, 0x17, 0xDF,
+ 0x35, 0x17, 0x4F, 0xE9,
-0xA1, 0x1F, 0x4F, 0xE9,
-0xA2, 0x3F, 0x4F, 0xE9,
+ 0xA1, 0x1F, 0x4F, 0xE9,
+ 0xA2, 0x3F, 0x4F, 0xE9,
-0x06, 0x06, 0x1F, 0xAF,
-0x39, 0x37, 0x4F, 0xE9,
+ 0x06, 0x06, 0x1F, 0xAF,
+ 0x39, 0x37, 0x4F, 0xE9,
-0x2F, 0x2F, 0x17, 0xAF,
-0x00, 0x80, 0x00, 0xE8,
+ 0x2F, 0x2F, 0x17, 0xAF,
+ 0x00, 0x80, 0x00, 0xE8,
-0xA0, 0x80, 0x4F, 0xE9,
-0x00, 0x80, 0x00, 0xE8,
+ 0xA0, 0x80, 0x4F, 0xE9,
+ 0x00, 0x80, 0x00, 0xE8,
-0x31, 0x80, 0x4F, 0xE9,
-0x00, 0x80, 0x00, 0xE8,
+ 0x31, 0x80, 0x4F, 0xE9,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x57, 0x39, 0x20, 0xE9,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x57, 0x39, 0x20, 0xE9,
-0x16, 0x28, 0x20, 0xE9,
-0x1D, 0x3B, 0x20, 0xE9,
+ 0x16, 0x28, 0x20, 0xE9,
+ 0x1D, 0x3B, 0x20, 0xE9,
-0x1E, 0x2B, 0x20, 0xE9,
-0x2B, 0x32, 0x20, 0xE9,
+ 0x1E, 0x2B, 0x20, 0xE9,
+ 0x2B, 0x32, 0x20, 0xE9,
-0x1C, 0x23, 0x20, 0xE9,
-0x57, 0x36, 0x20, 0xE9,
+ 0x1C, 0x23, 0x20, 0xE9,
+ 0x57, 0x36, 0x20, 0xE9,
-0x00, 0x80, 0xA0, 0xE9,
-0x40, 0x40, 0xD8, 0xEC,
+ 0x00, 0x80, 0xA0, 0xE9,
+ 0x40, 0x40, 0xD8, 0xEC,
-0xFF, 0x80, 0xC0, 0xE9,
-0x90, 0xE2,
-0x00, 0xE0,
+ 0xFF, 0x80, 0xC0, 0xE9,
+ 0x90, 0xE2,
+ 0x00, 0xE0,
-0x68, 0xFF, 0x20, 0xEA,
-0x19, 0xC8, 0xC1, 0xCD,
+ 0x68, 0xFF, 0x20, 0xEA,
+ 0x19, 0xC8, 0xC1, 0xCD,
-0x1F, 0xD7, 0x18, 0xBD,
-0x3F, 0xD7, 0x22, 0xBD,
+ 0x1F, 0xD7, 0x18, 0xBD,
+ 0x3F, 0xD7, 0x22, 0xBD,
-0x9F, 0x41, 0x49, 0xBD,
-0x00, 0x80, 0x00, 0xE8,
+ 0x9F, 0x41, 0x49, 0xBD,
+ 0x00, 0x80, 0x00, 0xE8,
-0x25, 0x41, 0x49, 0xBD,
-0x2D, 0x41, 0x51, 0xBD,
+ 0x25, 0x41, 0x49, 0xBD,
+ 0x2D, 0x41, 0x51, 0xBD,
-0x0D, 0x80, 0x07, 0xEA,
-0x00, 0x80, 0x00, 0xE8,
+ 0x0D, 0x80, 0x07, 0xEA,
+ 0x00, 0x80, 0x00, 0xE8,
-0x35, 0x40, 0x48, 0xBD,
-0x3D, 0x40, 0x50, 0xBD,
+ 0x35, 0x40, 0x48, 0xBD,
+ 0x3D, 0x40, 0x50, 0xBD,
-0x00, 0x80, 0x00, 0xE8,
-0x25, 0x30,
-0x2D, 0x30,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x25, 0x30,
+ 0x2D, 0x30,
-0x35, 0x30,
-0xB5, 0x30,
-0xBD, 0x30,
-0x3D, 0x30,
+ 0x35, 0x30,
+ 0xB5, 0x30,
+ 0xBD, 0x30,
+ 0x3D, 0x30,
-0x9C, 0xA7, 0x5B, 0x9F,
-0x00, 0x80, 0x00, 0xE8,
+ 0x9C, 0xA7, 0x5B, 0x9F,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x67, 0xFF, 0x0A, 0xEA,
-0x00, 0x80, 0x00, 0xE8,
+ 0x67, 0xFF, 0x0A, 0xEA,
+ 0x00, 0x80, 0x00, 0xE8,
-0xC9, 0x41, 0xC8, 0xEC,
-0x42, 0xE1,
-0x00, 0xE0,
+ 0xC9, 0x41, 0xC8, 0xEC,
+ 0x42, 0xE1,
+ 0x00, 0xE0,
-0x65, 0xFF, 0x20, 0xEA,
-0x00, 0x80, 0x00, 0xE8,
+ 0x65, 0xFF, 0x20, 0xEA,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0xC8, 0x40, 0xC0, 0xEC,
-0x00, 0x80, 0x00, 0xE8,
+ 0xC8, 0x40, 0xC0, 0xEC,
+ 0x00, 0x80, 0x00, 0xE8,
-0x62, 0xFF, 0x20, 0xEA,
-0x00, 0x80, 0x00, 0xE8,
+ 0x62, 0xFF, 0x20, 0xEA,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
};
static unsigned char warp_g400_t2gz[] = {
-0x00, 0x8A, 0x98, 0xE9,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x8A, 0x98, 0xE9,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0xA0, 0xE9,
-0x00, 0x00, 0xD8, 0xEC,
+ 0x00, 0x80, 0xA0, 0xE9,
+ 0x00, 0x00, 0xD8, 0xEC,
-0xFF, 0x80, 0xC0, 0xE9,
-0x00, 0x80, 0x00, 0xE8,
+ 0xFF, 0x80, 0xC0, 0xE9,
+ 0x00, 0x80, 0x00, 0xE8,
-0x0A, 0x40, 0x50, 0xBF,
-0x2A, 0x40, 0x60, 0xBF,
+ 0x0A, 0x40, 0x50, 0xBF,
+ 0x2A, 0x40, 0x60, 0xBF,
-0x32, 0x41, 0x51, 0xBF,
-0x3A, 0x41, 0x61, 0xBF,
+ 0x32, 0x41, 0x51, 0xBF,
+ 0x3A, 0x41, 0x61, 0xBF,
-0xC3, 0x6B,
-0xD3, 0x6B,
-0x00, 0x8A, 0x98, 0xE9,
+ 0xC3, 0x6B,
+ 0xD3, 0x6B,
+ 0x00, 0x8A, 0x98, 0xE9,
-0x73, 0x7B, 0xC8, 0xEC,
-0x96, 0xE2,
-0x41, 0x04,
+ 0x73, 0x7B, 0xC8, 0xEC,
+ 0x96, 0xE2,
+ 0x41, 0x04,
-0x7B, 0x43, 0xA0, 0xE8,
-0x73, 0x53, 0xA0, 0xE8,
+ 0x7B, 0x43, 0xA0, 0xE8,
+ 0x73, 0x53, 0xA0, 0xE8,
-0xAD, 0xEE, 0x23, 0x9F,
-0x00, 0xE0,
-0x51, 0x04,
+ 0xAD, 0xEE, 0x23, 0x9F,
+ 0x00, 0xE0,
+ 0x51, 0x04,
-0x90, 0xE2,
-0x61, 0x04,
-0x31, 0x46, 0xB1, 0xE8,
+ 0x90, 0xE2,
+ 0x61, 0x04,
+ 0x31, 0x46, 0xB1, 0xE8,
-0x51, 0x41, 0xE0, 0xEC,
-0x39, 0x67, 0xB1, 0xE8,
+ 0x51, 0x41, 0xE0, 0xEC,
+ 0x39, 0x67, 0xB1, 0xE8,
-0x00, 0x04,
-0x46, 0xE2,
-0x73, 0x63, 0xA0, 0xE8,
+ 0x00, 0x04,
+ 0x46, 0xE2,
+ 0x73, 0x63, 0xA0, 0xE8,
-0x61, 0x41, 0xE0, 0xEC,
-0x31, 0x00,
-0x39, 0x00,
+ 0x61, 0x41, 0xE0, 0xEC,
+ 0x31, 0x00,
+ 0x39, 0x00,
-0x78, 0x80, 0x15, 0xEA,
-0x10, 0x04,
-0x20, 0x04,
+ 0x78, 0x80, 0x15, 0xEA,
+ 0x10, 0x04,
+ 0x20, 0x04,
-0x61, 0x51, 0xE0, 0xEC,
-0x2F, 0x41, 0x60, 0xEA,
+ 0x61, 0x51, 0xE0, 0xEC,
+ 0x2F, 0x41, 0x60, 0xEA,
-0x31, 0x20,
-0x39, 0x20,
-0x1F, 0x42, 0xA0, 0xE8,
+ 0x31, 0x20,
+ 0x39, 0x20,
+ 0x1F, 0x42, 0xA0, 0xE8,
-0x2A, 0x42, 0x52, 0xBF,
-0x0F, 0x52, 0xA0, 0xE8,
+ 0x2A, 0x42, 0x52, 0xBF,
+ 0x0F, 0x52, 0xA0, 0xE8,
-0x1A, 0x42, 0x62, 0xBF,
-0x1E, 0x51, 0x60, 0xEA,
+ 0x1A, 0x42, 0x62, 0xBF,
+ 0x1E, 0x51, 0x60, 0xEA,
-0x73, 0x7B, 0xC8, 0xEC,
-0x0E, 0x61, 0x60, 0xEA,
+ 0x73, 0x7B, 0xC8, 0xEC,
+ 0x0E, 0x61, 0x60, 0xEA,
-0x32, 0x40, 0x50, 0xBD,
-0x22, 0x40, 0x60, 0xBD,
+ 0x32, 0x40, 0x50, 0xBD,
+ 0x22, 0x40, 0x60, 0xBD,
-0x12, 0x41, 0x51, 0xBD,
-0x3A, 0x41, 0x61, 0xBD,
+ 0x12, 0x41, 0x51, 0xBD,
+ 0x3A, 0x41, 0x61, 0xBD,
-0xBF, 0x2F, 0x0E, 0xBD,
-0x97, 0xE2,
-0x7B, 0x72,
+ 0xBF, 0x2F, 0x0E, 0xBD,
+ 0x97, 0xE2,
+ 0x7B, 0x72,
-0x32, 0x20,
-0x22, 0x20,
-0x12, 0x20,
-0x3A, 0x20,
+ 0x32, 0x20,
+ 0x22, 0x20,
+ 0x12, 0x20,
+ 0x3A, 0x20,
-0x35, 0x48, 0xB1, 0xE8,
-0x3D, 0x59, 0xB1, 0xE8,
+ 0x35, 0x48, 0xB1, 0xE8,
+ 0x3D, 0x59, 0xB1, 0xE8,
-0x46, 0x31, 0x46, 0xBF,
-0x56, 0x31, 0x56, 0xBF,
+ 0x46, 0x31, 0x46, 0xBF,
+ 0x56, 0x31, 0x56, 0xBF,
-0xB3, 0xE2, 0x2D, 0x9F,
-0x00, 0x80, 0x00, 0xE8,
+ 0xB3, 0xE2, 0x2D, 0x9F,
+ 0x00, 0x80, 0x00, 0xE8,
-0x66, 0x31, 0x66, 0xBF,
-0x47, 0x39, 0x47, 0xBF,
+ 0x66, 0x31, 0x66, 0xBF,
+ 0x47, 0x39, 0x47, 0xBF,
-0x57, 0x39, 0x57, 0xBF,
-0x67, 0x39, 0x67, 0xBF,
+ 0x57, 0x39, 0x57, 0xBF,
+ 0x67, 0x39, 0x67, 0xBF,
-0x69, 0x80, 0x07, 0xEA,
-0x24, 0x41, 0x20, 0xE9,
+ 0x69, 0x80, 0x07, 0xEA,
+ 0x24, 0x41, 0x20, 0xE9,
-0x35, 0x00,
-0x3D, 0x00,
-0x00, 0xE0,
-0x2D, 0x73,
+ 0x35, 0x00,
+ 0x3D, 0x00,
+ 0x00, 0xE0,
+ 0x2D, 0x73,
-0x33, 0x72,
-0x0C, 0xE3,
-0x8D, 0x2F, 0x1E, 0xBD,
+ 0x33, 0x72,
+ 0x0C, 0xE3,
+ 0x8D, 0x2F, 0x1E, 0xBD,
-0x43, 0x75, 0xF8, 0xEC,
-0x35, 0x20,
-0x3D, 0x20,
+ 0x43, 0x75, 0xF8, 0xEC,
+ 0x35, 0x20,
+ 0x3D, 0x20,
-0x43, 0x43, 0x2D, 0xDF,
-0x53, 0x53, 0x2D, 0xDF,
+ 0x43, 0x43, 0x2D, 0xDF,
+ 0x53, 0x53, 0x2D, 0xDF,
-0xAE, 0x1E, 0x0E, 0xBD,
-0x58, 0xE3,
-0x33, 0x66,
+ 0xAE, 0x1E, 0x0E, 0xBD,
+ 0x58, 0xE3,
+ 0x33, 0x66,
-0x48, 0x35, 0x48, 0xBF,
-0x58, 0x35, 0x58, 0xBF,
+ 0x48, 0x35, 0x48, 0xBF,
+ 0x58, 0x35, 0x58, 0xBF,
-0x68, 0x35, 0x68, 0xBF,
-0x49, 0x3D, 0x49, 0xBF,
+ 0x68, 0x35, 0x68, 0xBF,
+ 0x49, 0x3D, 0x49, 0xBF,
-0x59, 0x3D, 0x59, 0xBF,
-0x69, 0x3D, 0x69, 0xBF,
+ 0x59, 0x3D, 0x59, 0xBF,
+ 0x69, 0x3D, 0x69, 0xBF,
-0x63, 0x63, 0x2D, 0xDF,
-0x4D, 0x7D, 0xF8, 0xEC,
+ 0x63, 0x63, 0x2D, 0xDF,
+ 0x4D, 0x7D, 0xF8, 0xEC,
-0x59, 0xE3,
-0x00, 0xE0,
-0xB8, 0x38, 0x33, 0xBF,
+ 0x59, 0xE3,
+ 0x00, 0xE0,
+ 0xB8, 0x38, 0x33, 0xBF,
-0x2D, 0x73,
-0x30, 0x76,
-0x18, 0x3A, 0x41, 0xE9,
+ 0x2D, 0x73,
+ 0x30, 0x76,
+ 0x18, 0x3A, 0x41, 0xE9,
-0x3F, 0x53, 0xA0, 0xE8,
-0x05, 0x80, 0x3D, 0xEA,
+ 0x3F, 0x53, 0xA0, 0xE8,
+ 0x05, 0x80, 0x3D, 0xEA,
-0x37, 0x43, 0xA0, 0xE8,
-0x3D, 0x63, 0xA0, 0xE8,
+ 0x37, 0x43, 0xA0, 0xE8,
+ 0x3D, 0x63, 0xA0, 0xE8,
-0x50, 0x70, 0xF8, 0xEC,
-0x2B, 0x50, 0x3C, 0xE9,
+ 0x50, 0x70, 0xF8, 0xEC,
+ 0x2B, 0x50, 0x3C, 0xE9,
-0x1F, 0x0F, 0xBC, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x1F, 0x0F, 0xBC, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x59, 0x78, 0xF8, 0xEC,
-0x00, 0x80, 0x00, 0xE8,
+ 0x59, 0x78, 0xF8, 0xEC,
+ 0x00, 0x80, 0x00, 0xE8,
-0x15, 0xC0, 0x20, 0xE9,
-0x15, 0xC0, 0x20, 0xE9,
+ 0x15, 0xC0, 0x20, 0xE9,
+ 0x15, 0xC0, 0x20, 0xE9,
-0x15, 0xC0, 0x20, 0xE9,
-0x15, 0xC0, 0x20, 0xE9,
+ 0x15, 0xC0, 0x20, 0xE9,
+ 0x15, 0xC0, 0x20, 0xE9,
-0x1E, 0x12, 0x41, 0xE9,
-0x1A, 0x22, 0x41, 0xE9,
+ 0x1E, 0x12, 0x41, 0xE9,
+ 0x1A, 0x22, 0x41, 0xE9,
-0x46, 0x37, 0x46, 0xDF,
-0x56, 0x3F, 0x56, 0xDF,
+ 0x46, 0x37, 0x46, 0xDF,
+ 0x56, 0x3F, 0x56, 0xDF,
-0x2B, 0x40, 0x3D, 0xE9,
-0x66, 0x3D, 0x66, 0xDF,
+ 0x2B, 0x40, 0x3D, 0xE9,
+ 0x66, 0x3D, 0x66, 0xDF,
-0x1D, 0x32, 0x41, 0xE9,
-0x67, 0x3D, 0x67, 0xDF,
+ 0x1D, 0x32, 0x41, 0xE9,
+ 0x67, 0x3D, 0x67, 0xDF,
-0x47, 0x37, 0x47, 0xDF,
-0x57, 0x3F, 0x57, 0xDF,
+ 0x47, 0x37, 0x47, 0xDF,
+ 0x57, 0x3F, 0x57, 0xDF,
-0x2A, 0x40, 0x20, 0xE9,
-0x59, 0x3F, 0x59, 0xDF,
+ 0x2A, 0x40, 0x20, 0xE9,
+ 0x59, 0x3F, 0x59, 0xDF,
-0x16, 0x30, 0x20, 0xE9,
-0x69, 0x3D, 0x69, 0xDF,
+ 0x16, 0x30, 0x20, 0xE9,
+ 0x69, 0x3D, 0x69, 0xDF,
-0x48, 0x37, 0x48, 0xDF,
-0x58, 0x3F, 0x58, 0xDF,
+ 0x48, 0x37, 0x48, 0xDF,
+ 0x58, 0x3F, 0x58, 0xDF,
-0x12, 0x12, 0x2D, 0xDF,
-0x22, 0x22, 0x2D, 0xDF,
+ 0x12, 0x12, 0x2D, 0xDF,
+ 0x22, 0x22, 0x2D, 0xDF,
-0x32, 0x32, 0x2D, 0xDF,
-0x3A, 0x3A, 0x2D, 0xDF,
+ 0x32, 0x32, 0x2D, 0xDF,
+ 0x3A, 0x3A, 0x2D, 0xDF,
-0x68, 0x3D, 0x68, 0xDF,
-0x49, 0x37, 0x49, 0xDF,
+ 0x68, 0x3D, 0x68, 0xDF,
+ 0x49, 0x37, 0x49, 0xDF,
-0x3D, 0xCF, 0x74, 0xC0,
-0x37, 0xCF, 0x74, 0xC4,
+ 0x3D, 0xCF, 0x74, 0xC0,
+ 0x37, 0xCF, 0x74, 0xC4,
-0x31, 0x53, 0x2F, 0x9F,
-0x34, 0x80, 0x20, 0xE9,
+ 0x31, 0x53, 0x2F, 0x9F,
+ 0x34, 0x80, 0x20, 0xE9,
-0x39, 0xE5, 0x2C, 0x9F,
-0x3C, 0x3D, 0x20, 0xE9,
+ 0x39, 0xE5, 0x2C, 0x9F,
+ 0x3C, 0x3D, 0x20, 0xE9,
-0x0A, 0x44, 0x54, 0xB0,
-0x02, 0x44, 0x64, 0xB0,
+ 0x0A, 0x44, 0x54, 0xB0,
+ 0x02, 0x44, 0x64, 0xB0,
-0x2A, 0x44, 0x54, 0xB2,
-0x1A, 0x44, 0x64, 0xB2,
+ 0x2A, 0x44, 0x54, 0xB2,
+ 0x1A, 0x44, 0x64, 0xB2,
-0x25, 0x80, 0x3A, 0xEA,
-0x0A, 0x20,
-0x02, 0x20,
+ 0x25, 0x80, 0x3A, 0xEA,
+ 0x0A, 0x20,
+ 0x02, 0x20,
-0x3D, 0xCF, 0x74, 0xC2,
-0x2A, 0x20,
-0x1A, 0x20,
+ 0x3D, 0xCF, 0x74, 0xC2,
+ 0x2A, 0x20,
+ 0x1A, 0x20,
-0x30, 0x50, 0x2E, 0x9F,
-0x32, 0x31, 0x5F, 0xE9,
+ 0x30, 0x50, 0x2E, 0x9F,
+ 0x32, 0x31, 0x5F, 0xE9,
-0x38, 0x21, 0x2C, 0x9F,
-0x33, 0x39, 0x5F, 0xE9,
+ 0x38, 0x21, 0x2C, 0x9F,
+ 0x33, 0x39, 0x5F, 0xE9,
-0x31, 0x53, 0x2F, 0x9F,
-0x00, 0x80, 0x00, 0xE8,
+ 0x31, 0x53, 0x2F, 0x9F,
+ 0x00, 0x80, 0x00, 0xE8,
-0x2A, 0x44, 0x54, 0xB4,
-0x1A, 0x44, 0x64, 0xB4,
+ 0x2A, 0x44, 0x54, 0xB4,
+ 0x1A, 0x44, 0x64, 0xB4,
-0x39, 0xE5, 0x2C, 0x9F,
-0x38, 0x3D, 0x20, 0xE9,
+ 0x39, 0xE5, 0x2C, 0x9F,
+ 0x38, 0x3D, 0x20, 0xE9,
-0x88, 0x73, 0x5E, 0xE9,
-0x2A, 0x20,
-0x1A, 0x20,
+ 0x88, 0x73, 0x5E, 0xE9,
+ 0x2A, 0x20,
+ 0x1A, 0x20,
-0x2A, 0x46, 0x56, 0xBF,
-0x1A, 0x46, 0x66, 0xBF,
+ 0x2A, 0x46, 0x56, 0xBF,
+ 0x1A, 0x46, 0x66, 0xBF,
-0x31, 0x53, 0x2F, 0x9F,
-0x3E, 0x30, 0x4F, 0xE9,
+ 0x31, 0x53, 0x2F, 0x9F,
+ 0x3E, 0x30, 0x4F, 0xE9,
-0x39, 0xE5, 0x2C, 0x9F,
-0x3F, 0x38, 0x4F, 0xE9,
+ 0x39, 0xE5, 0x2C, 0x9F,
+ 0x3F, 0x38, 0x4F, 0xE9,
-0x0A, 0x47, 0x57, 0xBF,
-0x02, 0x47, 0x67, 0xBF,
+ 0x0A, 0x47, 0x57, 0xBF,
+ 0x02, 0x47, 0x67, 0xBF,
-0x31, 0x53, 0x2F, 0x9F,
-0x3A, 0x31, 0x4F, 0xE9,
+ 0x31, 0x53, 0x2F, 0x9F,
+ 0x3A, 0x31, 0x4F, 0xE9,
-0x39, 0xE5, 0x2C, 0x9F,
-0x3B, 0x39, 0x4F, 0xE9,
+ 0x39, 0xE5, 0x2C, 0x9F,
+ 0x3B, 0x39, 0x4F, 0xE9,
-0x2A, 0x43, 0x53, 0xBF,
-0x1A, 0x43, 0x63, 0xBF,
+ 0x2A, 0x43, 0x53, 0xBF,
+ 0x1A, 0x43, 0x63, 0xBF,
-0x30, 0x50, 0x2E, 0x9F,
-0x36, 0x31, 0x4F, 0xE9,
+ 0x30, 0x50, 0x2E, 0x9F,
+ 0x36, 0x31, 0x4F, 0xE9,
-0x38, 0x21, 0x2C, 0x9F,
-0x37, 0x39, 0x4F, 0xE9,
+ 0x38, 0x21, 0x2C, 0x9F,
+ 0x37, 0x39, 0x4F, 0xE9,
-0x0A, 0x48, 0x58, 0xBF,
-0x02, 0x48, 0x68, 0xBF,
+ 0x0A, 0x48, 0x58, 0xBF,
+ 0x02, 0x48, 0x68, 0xBF,
-0x31, 0x53, 0x2F, 0x9F,
-0x80, 0x31, 0x57, 0xE9,
+ 0x31, 0x53, 0x2F, 0x9F,
+ 0x80, 0x31, 0x57, 0xE9,
-0x39, 0xE5, 0x2C, 0x9F,
-0x81, 0x39, 0x57, 0xE9,
+ 0x39, 0xE5, 0x2C, 0x9F,
+ 0x81, 0x39, 0x57, 0xE9,
-0x2A, 0x49, 0x59, 0xBF,
-0x1A, 0x49, 0x69, 0xBF,
+ 0x2A, 0x49, 0x59, 0xBF,
+ 0x1A, 0x49, 0x69, 0xBF,
-0x30, 0x50, 0x2E, 0x9F,
-0x82, 0x30, 0x57, 0xE9,
+ 0x30, 0x50, 0x2E, 0x9F,
+ 0x82, 0x30, 0x57, 0xE9,
-0x38, 0x21, 0x2C, 0x9F,
-0x83, 0x38, 0x57, 0xE9,
+ 0x38, 0x21, 0x2C, 0x9F,
+ 0x83, 0x38, 0x57, 0xE9,
-0x31, 0x53, 0x2F, 0x9F,
-0x84, 0x31, 0x5E, 0xE9,
+ 0x31, 0x53, 0x2F, 0x9F,
+ 0x84, 0x31, 0x5E, 0xE9,
-0x39, 0xE5, 0x2C, 0x9F,
-0x85, 0x39, 0x5E, 0xE9,
+ 0x39, 0xE5, 0x2C, 0x9F,
+ 0x85, 0x39, 0x5E, 0xE9,
-0x86, 0x76, 0x57, 0xE9,
-0x8A, 0x36, 0x20, 0xE9,
+ 0x86, 0x76, 0x57, 0xE9,
+ 0x8A, 0x36, 0x20, 0xE9,
-0x87, 0x77, 0x57, 0xE9,
-0x8B, 0x3E, 0xBF, 0xEA,
+ 0x87, 0x77, 0x57, 0xE9,
+ 0x8B, 0x3E, 0xBF, 0xEA,
-0x80, 0x30, 0x57, 0xE9,
-0x81, 0x38, 0x57, 0xE9,
+ 0x80, 0x30, 0x57, 0xE9,
+ 0x81, 0x38, 0x57, 0xE9,
-0x82, 0x31, 0x57, 0xE9,
-0x86, 0x78, 0x57, 0xE9,
+ 0x82, 0x31, 0x57, 0xE9,
+ 0x86, 0x78, 0x57, 0xE9,
-0x83, 0x39, 0x57, 0xE9,
-0x87, 0x79, 0x57, 0xE9,
+ 0x83, 0x39, 0x57, 0xE9,
+ 0x87, 0x79, 0x57, 0xE9,
-0x30, 0x1F, 0x5F, 0xE9,
-0x8A, 0x34, 0x20, 0xE9,
+ 0x30, 0x1F, 0x5F, 0xE9,
+ 0x8A, 0x34, 0x20, 0xE9,
-0x8B, 0x3C, 0x20, 0xE9,
-0x37, 0x50, 0x60, 0xBD,
+ 0x8B, 0x3C, 0x20, 0xE9,
+ 0x37, 0x50, 0x60, 0xBD,
-0x57, 0x0D, 0x20, 0xE9,
-0x35, 0x51, 0x61, 0xBD,
+ 0x57, 0x0D, 0x20, 0xE9,
+ 0x35, 0x51, 0x61, 0xBD,
-0x2B, 0x50, 0x20, 0xE9,
-0x1D, 0x37, 0xE1, 0xEA,
+ 0x2B, 0x50, 0x20, 0xE9,
+ 0x1D, 0x37, 0xE1, 0xEA,
-0x1E, 0x35, 0xE1, 0xEA,
-0x00, 0xE0,
-0x0E, 0x77,
+ 0x1E, 0x35, 0xE1, 0xEA,
+ 0x00, 0xE0,
+ 0x0E, 0x77,
-0x24, 0x51, 0x20, 0xE9,
-0x9F, 0xFF, 0x20, 0xEA,
+ 0x24, 0x51, 0x20, 0xE9,
+ 0x9F, 0xFF, 0x20, 0xEA,
-0x16, 0x0E, 0x20, 0xE9,
-0x57, 0x2E, 0xBF, 0xEA,
+ 0x16, 0x0E, 0x20, 0xE9,
+ 0x57, 0x2E, 0xBF, 0xEA,
-0x0B, 0x46, 0xA0, 0xE8,
-0x1B, 0x56, 0xA0, 0xE8,
+ 0x0B, 0x46, 0xA0, 0xE8,
+ 0x1B, 0x56, 0xA0, 0xE8,
-0x2B, 0x66, 0xA0, 0xE8,
-0x0C, 0x47, 0xA0, 0xE8,
+ 0x2B, 0x66, 0xA0, 0xE8,
+ 0x0C, 0x47, 0xA0, 0xE8,
-0x1C, 0x57, 0xA0, 0xE8,
-0x2C, 0x67, 0xA0, 0xE8,
+ 0x1C, 0x57, 0xA0, 0xE8,
+ 0x2C, 0x67, 0xA0, 0xE8,
-0x0B, 0x00,
-0x1B, 0x00,
-0x2B, 0x00,
-0x00, 0xE0,
+ 0x0B, 0x00,
+ 0x1B, 0x00,
+ 0x2B, 0x00,
+ 0x00, 0xE0,
-0x0C, 0x00,
-0x1C, 0x00,
-0x2C, 0x00,
-0x00, 0xE0,
+ 0x0C, 0x00,
+ 0x1C, 0x00,
+ 0x2C, 0x00,
+ 0x00, 0xE0,
-0x0B, 0x65,
-0x1B, 0x65,
-0x2B, 0x65,
-0x00, 0xE0,
+ 0x0B, 0x65,
+ 0x1B, 0x65,
+ 0x2B, 0x65,
+ 0x00, 0xE0,
-0x0C, 0x65,
-0x1C, 0x65,
-0x2C, 0x65,
-0x00, 0xE0,
+ 0x0C, 0x65,
+ 0x1C, 0x65,
+ 0x2C, 0x65,
+ 0x00, 0xE0,
-0x0B, 0x1B, 0x60, 0xEC,
-0x36, 0xD7, 0x36, 0xAD,
+ 0x0B, 0x1B, 0x60, 0xEC,
+ 0x36, 0xD7, 0x36, 0xAD,
-0x2B, 0x80, 0x60, 0xEC,
-0x0C, 0x1C, 0x60, 0xEC,
+ 0x2B, 0x80, 0x60, 0xEC,
+ 0x0C, 0x1C, 0x60, 0xEC,
-0x3E, 0xD7, 0x3E, 0xAD,
-0x2C, 0x80, 0x60, 0xEC,
+ 0x3E, 0xD7, 0x3E, 0xAD,
+ 0x2C, 0x80, 0x60, 0xEC,
-0x0B, 0x2B, 0xDE, 0xE8,
-0x1B, 0x80, 0xDE, 0xE8,
+ 0x0B, 0x2B, 0xDE, 0xE8,
+ 0x1B, 0x80, 0xDE, 0xE8,
-0x36, 0x80, 0x36, 0xBD,
-0x3E, 0x80, 0x3E, 0xBD,
+ 0x36, 0x80, 0x36, 0xBD,
+ 0x3E, 0x80, 0x3E, 0xBD,
-0x33, 0xD7, 0x0B, 0xBD,
-0x3B, 0xD7, 0x1B, 0xBD,
+ 0x33, 0xD7, 0x0B, 0xBD,
+ 0x3B, 0xD7, 0x1B, 0xBD,
-0x46, 0x80, 0x46, 0xCF,
-0x57, 0x80, 0x57, 0xCF,
+ 0x46, 0x80, 0x46, 0xCF,
+ 0x57, 0x80, 0x57, 0xCF,
-0x66, 0x33, 0x66, 0xCF,
-0x47, 0x3B, 0x47, 0xCF,
+ 0x66, 0x33, 0x66, 0xCF,
+ 0x47, 0x3B, 0x47, 0xCF,
-0x56, 0x33, 0x56, 0xCF,
-0x67, 0x3B, 0x67, 0xCF,
+ 0x56, 0x33, 0x56, 0xCF,
+ 0x67, 0x3B, 0x67, 0xCF,
-0x0B, 0x48, 0xA0, 0xE8,
-0x1B, 0x58, 0xA0, 0xE8,
+ 0x0B, 0x48, 0xA0, 0xE8,
+ 0x1B, 0x58, 0xA0, 0xE8,
-0x2B, 0x68, 0xA0, 0xE8,
-0x0C, 0x49, 0xA0, 0xE8,
+ 0x2B, 0x68, 0xA0, 0xE8,
+ 0x0C, 0x49, 0xA0, 0xE8,
-0x1C, 0x59, 0xA0, 0xE8,
-0x2C, 0x69, 0xA0, 0xE8,
+ 0x1C, 0x59, 0xA0, 0xE8,
+ 0x2C, 0x69, 0xA0, 0xE8,
-0x0B, 0x00,
-0x1B, 0x00,
-0x2B, 0x00,
-0x00, 0xE0,
+ 0x0B, 0x00,
+ 0x1B, 0x00,
+ 0x2B, 0x00,
+ 0x00, 0xE0,
-0x0C, 0x00,
-0x1C, 0x00,
-0x2C, 0x00,
-0x00, 0xE0,
+ 0x0C, 0x00,
+ 0x1C, 0x00,
+ 0x2C, 0x00,
+ 0x00, 0xE0,
-0x0B, 0x65,
-0x1B, 0x65,
-0x2B, 0x65,
-0x00, 0xE0,
+ 0x0B, 0x65,
+ 0x1B, 0x65,
+ 0x2B, 0x65,
+ 0x00, 0xE0,
-0x0C, 0x65,
-0x1C, 0x65,
-0x2C, 0x65,
-0x00, 0xE0,
+ 0x0C, 0x65,
+ 0x1C, 0x65,
+ 0x2C, 0x65,
+ 0x00, 0xE0,
-0x0B, 0x1B, 0x60, 0xEC,
-0x34, 0xD7, 0x34, 0xAD,
+ 0x0B, 0x1B, 0x60, 0xEC,
+ 0x34, 0xD7, 0x34, 0xAD,
-0x2B, 0x80, 0x60, 0xEC,
-0x0C, 0x1C, 0x60, 0xEC,
+ 0x2B, 0x80, 0x60, 0xEC,
+ 0x0C, 0x1C, 0x60, 0xEC,
-0x3C, 0xD7, 0x3C, 0xAD,
-0x2C, 0x80, 0x60, 0xEC,
+ 0x3C, 0xD7, 0x3C, 0xAD,
+ 0x2C, 0x80, 0x60, 0xEC,
-0x0B, 0x2B, 0xDE, 0xE8,
-0x1B, 0x80, 0xDE, 0xE8,
+ 0x0B, 0x2B, 0xDE, 0xE8,
+ 0x1B, 0x80, 0xDE, 0xE8,
-0x34, 0x80, 0x34, 0xBD,
-0x3C, 0x80, 0x3C, 0xBD,
+ 0x34, 0x80, 0x34, 0xBD,
+ 0x3C, 0x80, 0x3C, 0xBD,
-0x33, 0xD7, 0x0B, 0xBD,
-0x3B, 0xD7, 0x1B, 0xBD,
+ 0x33, 0xD7, 0x0B, 0xBD,
+ 0x3B, 0xD7, 0x1B, 0xBD,
-0x48, 0x80, 0x48, 0xCF,
-0x59, 0x80, 0x59, 0xCF,
+ 0x48, 0x80, 0x48, 0xCF,
+ 0x59, 0x80, 0x59, 0xCF,
-0x68, 0x33, 0x68, 0xCF,
-0x49, 0x3B, 0x49, 0xCF,
+ 0x68, 0x33, 0x68, 0xCF,
+ 0x49, 0x3B, 0x49, 0xCF,
-0xBE, 0xFF, 0x20, 0xEA,
-0x00, 0x80, 0x00, 0xE8,
+ 0xBE, 0xFF, 0x20, 0xEA,
+ 0x00, 0x80, 0x00, 0xE8,
-0x58, 0x33, 0x58, 0xCF,
-0x69, 0x3B, 0x69, 0xCF,
+ 0x58, 0x33, 0x58, 0xCF,
+ 0x69, 0x3B, 0x69, 0xCF,
-0x7D, 0xFF, 0x20, 0xEA,
-0x57, 0xC0, 0xBF, 0xEA,
+ 0x7D, 0xFF, 0x20, 0xEA,
+ 0x57, 0xC0, 0xBF, 0xEA,
-0x00, 0x80, 0xA0, 0xE9,
-0x00, 0x00, 0xD8, 0xEC,
+ 0x00, 0x80, 0xA0, 0xE9,
+ 0x00, 0x00, 0xD8, 0xEC,
};
static unsigned char warp_g400_t2gza[] = {
-0x00, 0x8A, 0x98, 0xE9,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x8A, 0x98, 0xE9,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0xA0, 0xE9,
-0x00, 0x00, 0xD8, 0xEC,
+ 0x00, 0x80, 0xA0, 0xE9,
+ 0x00, 0x00, 0xD8, 0xEC,
-0xFF, 0x80, 0xC0, 0xE9,
-0x00, 0x80, 0x00, 0xE8,
+ 0xFF, 0x80, 0xC0, 0xE9,
+ 0x00, 0x80, 0x00, 0xE8,
-0x0A, 0x40, 0x50, 0xBF,
-0x2A, 0x40, 0x60, 0xBF,
+ 0x0A, 0x40, 0x50, 0xBF,
+ 0x2A, 0x40, 0x60, 0xBF,
-0x32, 0x41, 0x51, 0xBF,
-0x3A, 0x41, 0x61, 0xBF,
+ 0x32, 0x41, 0x51, 0xBF,
+ 0x3A, 0x41, 0x61, 0xBF,
-0xC3, 0x6B,
-0xD3, 0x6B,
-0x00, 0x8A, 0x98, 0xE9,
+ 0xC3, 0x6B,
+ 0xD3, 0x6B,
+ 0x00, 0x8A, 0x98, 0xE9,
-0x73, 0x7B, 0xC8, 0xEC,
-0x96, 0xE2,
-0x41, 0x04,
+ 0x73, 0x7B, 0xC8, 0xEC,
+ 0x96, 0xE2,
+ 0x41, 0x04,
-0x7B, 0x43, 0xA0, 0xE8,
-0x73, 0x53, 0xA0, 0xE8,
+ 0x7B, 0x43, 0xA0, 0xE8,
+ 0x73, 0x53, 0xA0, 0xE8,
-0xAD, 0xEE, 0x23, 0x9F,
-0x00, 0xE0,
-0x51, 0x04,
+ 0xAD, 0xEE, 0x23, 0x9F,
+ 0x00, 0xE0,
+ 0x51, 0x04,
-0x90, 0xE2,
-0x61, 0x04,
-0x31, 0x46, 0xB1, 0xE8,
+ 0x90, 0xE2,
+ 0x61, 0x04,
+ 0x31, 0x46, 0xB1, 0xE8,
-0x51, 0x41, 0xE0, 0xEC,
-0x39, 0x67, 0xB1, 0xE8,
+ 0x51, 0x41, 0xE0, 0xEC,
+ 0x39, 0x67, 0xB1, 0xE8,
-0x00, 0x04,
-0x46, 0xE2,
-0x73, 0x63, 0xA0, 0xE8,
+ 0x00, 0x04,
+ 0x46, 0xE2,
+ 0x73, 0x63, 0xA0, 0xE8,
-0x61, 0x41, 0xE0, 0xEC,
-0x31, 0x00,
-0x39, 0x00,
+ 0x61, 0x41, 0xE0, 0xEC,
+ 0x31, 0x00,
+ 0x39, 0x00,
-0x7C, 0x80, 0x15, 0xEA,
-0x10, 0x04,
-0x20, 0x04,
+ 0x7C, 0x80, 0x15, 0xEA,
+ 0x10, 0x04,
+ 0x20, 0x04,
-0x61, 0x51, 0xE0, 0xEC,
-0x2F, 0x41, 0x60, 0xEA,
+ 0x61, 0x51, 0xE0, 0xEC,
+ 0x2F, 0x41, 0x60, 0xEA,
-0x31, 0x20,
-0x39, 0x20,
-0x1F, 0x42, 0xA0, 0xE8,
+ 0x31, 0x20,
+ 0x39, 0x20,
+ 0x1F, 0x42, 0xA0, 0xE8,
-0x2A, 0x42, 0x52, 0xBF,
-0x0F, 0x52, 0xA0, 0xE8,
+ 0x2A, 0x42, 0x52, 0xBF,
+ 0x0F, 0x52, 0xA0, 0xE8,
-0x1A, 0x42, 0x62, 0xBF,
-0x1E, 0x51, 0x60, 0xEA,
+ 0x1A, 0x42, 0x62, 0xBF,
+ 0x1E, 0x51, 0x60, 0xEA,
-0x73, 0x7B, 0xC8, 0xEC,
-0x0E, 0x61, 0x60, 0xEA,
+ 0x73, 0x7B, 0xC8, 0xEC,
+ 0x0E, 0x61, 0x60, 0xEA,
-0x32, 0x40, 0x50, 0xBD,
-0x22, 0x40, 0x60, 0xBD,
+ 0x32, 0x40, 0x50, 0xBD,
+ 0x22, 0x40, 0x60, 0xBD,
-0x12, 0x41, 0x51, 0xBD,
-0x3A, 0x41, 0x61, 0xBD,
+ 0x12, 0x41, 0x51, 0xBD,
+ 0x3A, 0x41, 0x61, 0xBD,
-0xBF, 0x2F, 0x0E, 0xBD,
-0x97, 0xE2,
-0x7B, 0x72,
+ 0xBF, 0x2F, 0x0E, 0xBD,
+ 0x97, 0xE2,
+ 0x7B, 0x72,
-0x32, 0x20,
-0x22, 0x20,
-0x12, 0x20,
-0x3A, 0x20,
+ 0x32, 0x20,
+ 0x22, 0x20,
+ 0x12, 0x20,
+ 0x3A, 0x20,
-0x35, 0x48, 0xB1, 0xE8,
-0x3D, 0x59, 0xB1, 0xE8,
+ 0x35, 0x48, 0xB1, 0xE8,
+ 0x3D, 0x59, 0xB1, 0xE8,
-0x46, 0x31, 0x46, 0xBF,
-0x56, 0x31, 0x56, 0xBF,
+ 0x46, 0x31, 0x46, 0xBF,
+ 0x56, 0x31, 0x56, 0xBF,
-0xB3, 0xE2, 0x2D, 0x9F,
-0x00, 0x80, 0x00, 0xE8,
+ 0xB3, 0xE2, 0x2D, 0x9F,
+ 0x00, 0x80, 0x00, 0xE8,
-0x66, 0x31, 0x66, 0xBF,
-0x47, 0x39, 0x47, 0xBF,
+ 0x66, 0x31, 0x66, 0xBF,
+ 0x47, 0x39, 0x47, 0xBF,
-0x57, 0x39, 0x57, 0xBF,
-0x67, 0x39, 0x67, 0xBF,
+ 0x57, 0x39, 0x57, 0xBF,
+ 0x67, 0x39, 0x67, 0xBF,
-0x6D, 0x80, 0x07, 0xEA,
-0x24, 0x41, 0x20, 0xE9,
+ 0x6D, 0x80, 0x07, 0xEA,
+ 0x24, 0x41, 0x20, 0xE9,
-0x35, 0x00,
-0x3D, 0x00,
-0x00, 0xE0,
-0x2D, 0x73,
+ 0x35, 0x00,
+ 0x3D, 0x00,
+ 0x00, 0xE0,
+ 0x2D, 0x73,
-0x33, 0x72,
-0x0C, 0xE3,
-0x8D, 0x2F, 0x1E, 0xBD,
+ 0x33, 0x72,
+ 0x0C, 0xE3,
+ 0x8D, 0x2F, 0x1E, 0xBD,
-0x43, 0x75, 0xF8, 0xEC,
-0x35, 0x20,
-0x3D, 0x20,
+ 0x43, 0x75, 0xF8, 0xEC,
+ 0x35, 0x20,
+ 0x3D, 0x20,
-0x43, 0x43, 0x2D, 0xDF,
-0x53, 0x53, 0x2D, 0xDF,
+ 0x43, 0x43, 0x2D, 0xDF,
+ 0x53, 0x53, 0x2D, 0xDF,
-0xAE, 0x1E, 0x0E, 0xBD,
-0x58, 0xE3,
-0x33, 0x66,
+ 0xAE, 0x1E, 0x0E, 0xBD,
+ 0x58, 0xE3,
+ 0x33, 0x66,
-0x48, 0x35, 0x48, 0xBF,
-0x58, 0x35, 0x58, 0xBF,
+ 0x48, 0x35, 0x48, 0xBF,
+ 0x58, 0x35, 0x58, 0xBF,
-0x68, 0x35, 0x68, 0xBF,
-0x49, 0x3D, 0x49, 0xBF,
+ 0x68, 0x35, 0x68, 0xBF,
+ 0x49, 0x3D, 0x49, 0xBF,
-0x59, 0x3D, 0x59, 0xBF,
-0x69, 0x3D, 0x69, 0xBF,
+ 0x59, 0x3D, 0x59, 0xBF,
+ 0x69, 0x3D, 0x69, 0xBF,
-0x63, 0x63, 0x2D, 0xDF,
-0x4D, 0x7D, 0xF8, 0xEC,
+ 0x63, 0x63, 0x2D, 0xDF,
+ 0x4D, 0x7D, 0xF8, 0xEC,
-0x59, 0xE3,
-0x00, 0xE0,
-0xB8, 0x38, 0x33, 0xBF,
+ 0x59, 0xE3,
+ 0x00, 0xE0,
+ 0xB8, 0x38, 0x33, 0xBF,
-0x2D, 0x73,
-0x30, 0x76,
-0x18, 0x3A, 0x41, 0xE9,
+ 0x2D, 0x73,
+ 0x30, 0x76,
+ 0x18, 0x3A, 0x41, 0xE9,
-0x3F, 0x53, 0xA0, 0xE8,
-0x05, 0x80, 0x3D, 0xEA,
+ 0x3F, 0x53, 0xA0, 0xE8,
+ 0x05, 0x80, 0x3D, 0xEA,
-0x37, 0x43, 0xA0, 0xE8,
-0x3D, 0x63, 0xA0, 0xE8,
+ 0x37, 0x43, 0xA0, 0xE8,
+ 0x3D, 0x63, 0xA0, 0xE8,
-0x50, 0x70, 0xF8, 0xEC,
-0x2B, 0x50, 0x3C, 0xE9,
+ 0x50, 0x70, 0xF8, 0xEC,
+ 0x2B, 0x50, 0x3C, 0xE9,
-0x1F, 0x0F, 0xBC, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x1F, 0x0F, 0xBC, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x59, 0x78, 0xF8, 0xEC,
-0x00, 0x80, 0x00, 0xE8,
+ 0x59, 0x78, 0xF8, 0xEC,
+ 0x00, 0x80, 0x00, 0xE8,
-0x15, 0xC0, 0x20, 0xE9,
-0x15, 0xC0, 0x20, 0xE9,
+ 0x15, 0xC0, 0x20, 0xE9,
+ 0x15, 0xC0, 0x20, 0xE9,
-0x15, 0xC0, 0x20, 0xE9,
-0x15, 0xC0, 0x20, 0xE9,
+ 0x15, 0xC0, 0x20, 0xE9,
+ 0x15, 0xC0, 0x20, 0xE9,
-0x1E, 0x12, 0x41, 0xE9,
-0x1A, 0x22, 0x41, 0xE9,
+ 0x1E, 0x12, 0x41, 0xE9,
+ 0x1A, 0x22, 0x41, 0xE9,
-0x46, 0x37, 0x46, 0xDF,
-0x56, 0x3F, 0x56, 0xDF,
+ 0x46, 0x37, 0x46, 0xDF,
+ 0x56, 0x3F, 0x56, 0xDF,
-0x2B, 0x40, 0x3D, 0xE9,
-0x66, 0x3D, 0x66, 0xDF,
+ 0x2B, 0x40, 0x3D, 0xE9,
+ 0x66, 0x3D, 0x66, 0xDF,
-0x1D, 0x32, 0x41, 0xE9,
-0x67, 0x3D, 0x67, 0xDF,
+ 0x1D, 0x32, 0x41, 0xE9,
+ 0x67, 0x3D, 0x67, 0xDF,
-0x47, 0x37, 0x47, 0xDF,
-0x57, 0x3F, 0x57, 0xDF,
+ 0x47, 0x37, 0x47, 0xDF,
+ 0x57, 0x3F, 0x57, 0xDF,
-0x2A, 0x40, 0x20, 0xE9,
-0x59, 0x3F, 0x59, 0xDF,
+ 0x2A, 0x40, 0x20, 0xE9,
+ 0x59, 0x3F, 0x59, 0xDF,
-0x16, 0x30, 0x20, 0xE9,
-0x69, 0x3D, 0x69, 0xDF,
+ 0x16, 0x30, 0x20, 0xE9,
+ 0x69, 0x3D, 0x69, 0xDF,
-0x48, 0x37, 0x48, 0xDF,
-0x58, 0x3F, 0x58, 0xDF,
+ 0x48, 0x37, 0x48, 0xDF,
+ 0x58, 0x3F, 0x58, 0xDF,
-0x12, 0x12, 0x2D, 0xDF,
-0x22, 0x22, 0x2D, 0xDF,
+ 0x12, 0x12, 0x2D, 0xDF,
+ 0x22, 0x22, 0x2D, 0xDF,
-0x32, 0x32, 0x2D, 0xDF,
-0x3A, 0x3A, 0x2D, 0xDF,
+ 0x32, 0x32, 0x2D, 0xDF,
+ 0x3A, 0x3A, 0x2D, 0xDF,
-0x68, 0x3D, 0x68, 0xDF,
-0x49, 0x37, 0x49, 0xDF,
+ 0x68, 0x3D, 0x68, 0xDF,
+ 0x49, 0x37, 0x49, 0xDF,
-0x3D, 0xCF, 0x74, 0xC0,
-0x37, 0xCF, 0x74, 0xC4,
+ 0x3D, 0xCF, 0x74, 0xC0,
+ 0x37, 0xCF, 0x74, 0xC4,
-0x31, 0x53, 0x2F, 0x9F,
-0x34, 0x80, 0x20, 0xE9,
+ 0x31, 0x53, 0x2F, 0x9F,
+ 0x34, 0x80, 0x20, 0xE9,
-0x39, 0xE5, 0x2C, 0x9F,
-0x3C, 0x3D, 0x20, 0xE9,
+ 0x39, 0xE5, 0x2C, 0x9F,
+ 0x3C, 0x3D, 0x20, 0xE9,
-0x0A, 0x44, 0x54, 0xB0,
-0x02, 0x44, 0x64, 0xB0,
+ 0x0A, 0x44, 0x54, 0xB0,
+ 0x02, 0x44, 0x64, 0xB0,
-0x2A, 0x44, 0x54, 0xB2,
-0x1A, 0x44, 0x64, 0xB2,
+ 0x2A, 0x44, 0x54, 0xB2,
+ 0x1A, 0x44, 0x64, 0xB2,
-0x29, 0x80, 0x3A, 0xEA,
-0x0A, 0x20,
-0x02, 0x20,
+ 0x29, 0x80, 0x3A, 0xEA,
+ 0x0A, 0x20,
+ 0x02, 0x20,
-0x0F, 0xCF, 0x74, 0xC6,
-0x3D, 0xCF, 0x74, 0xC2,
+ 0x0F, 0xCF, 0x74, 0xC6,
+ 0x3D, 0xCF, 0x74, 0xC2,
-0x88, 0x73, 0x5E, 0xE9,
-0x2A, 0x20,
-0x1A, 0x20,
+ 0x88, 0x73, 0x5E, 0xE9,
+ 0x2A, 0x20,
+ 0x1A, 0x20,
-0x30, 0x50, 0x2E, 0x9F,
-0x32, 0x31, 0x5F, 0xE9,
+ 0x30, 0x50, 0x2E, 0x9F,
+ 0x32, 0x31, 0x5F, 0xE9,
-0x38, 0x21, 0x2C, 0x9F,
-0x33, 0x39, 0x5F, 0xE9,
+ 0x38, 0x21, 0x2C, 0x9F,
+ 0x33, 0x39, 0x5F, 0xE9,
-0x31, 0x53, 0x2F, 0x9F,
-0x9C, 0x0F, 0x20, 0xE9,
+ 0x31, 0x53, 0x2F, 0x9F,
+ 0x9C, 0x0F, 0x20, 0xE9,
-0x0A, 0x44, 0x54, 0xB4,
-0x02, 0x44, 0x64, 0xB4,
+ 0x0A, 0x44, 0x54, 0xB4,
+ 0x02, 0x44, 0x64, 0xB4,
-0x2A, 0x44, 0x54, 0xB6,
-0x1A, 0x44, 0x64, 0xB6,
+ 0x2A, 0x44, 0x54, 0xB6,
+ 0x1A, 0x44, 0x64, 0xB6,
-0x39, 0xE5, 0x2C, 0x9F,
-0x38, 0x3D, 0x20, 0xE9,
+ 0x39, 0xE5, 0x2C, 0x9F,
+ 0x38, 0x3D, 0x20, 0xE9,
-0x0A, 0x20,
-0x02, 0x20,
-0x2A, 0x20,
-0x1A, 0x20,
+ 0x0A, 0x20,
+ 0x02, 0x20,
+ 0x2A, 0x20,
+ 0x1A, 0x20,
-0x0A, 0x47, 0x57, 0xBF,
-0x02, 0x47, 0x67, 0xBF,
+ 0x0A, 0x47, 0x57, 0xBF,
+ 0x02, 0x47, 0x67, 0xBF,
-0x30, 0x50, 0x2E, 0x9F,
-0x3E, 0x30, 0x4F, 0xE9,
+ 0x30, 0x50, 0x2E, 0x9F,
+ 0x3E, 0x30, 0x4F, 0xE9,
-0x38, 0x21, 0x2C, 0x9F,
-0x3F, 0x38, 0x4F, 0xE9,
+ 0x38, 0x21, 0x2C, 0x9F,
+ 0x3F, 0x38, 0x4F, 0xE9,
-0x2A, 0x46, 0x56, 0xBF,
-0x1A, 0x46, 0x66, 0xBF,
+ 0x2A, 0x46, 0x56, 0xBF,
+ 0x1A, 0x46, 0x66, 0xBF,
-0x31, 0x53, 0x2F, 0x9F,
-0x3A, 0x31, 0x4F, 0xE9,
+ 0x31, 0x53, 0x2F, 0x9F,
+ 0x3A, 0x31, 0x4F, 0xE9,
-0x39, 0xE5, 0x2C, 0x9F,
-0x3B, 0x39, 0x4F, 0xE9,
+ 0x39, 0xE5, 0x2C, 0x9F,
+ 0x3B, 0x39, 0x4F, 0xE9,
-0x31, 0x53, 0x2F, 0x9F,
-0x36, 0x30, 0x4F, 0xE9,
+ 0x31, 0x53, 0x2F, 0x9F,
+ 0x36, 0x30, 0x4F, 0xE9,
-0x39, 0xE5, 0x2C, 0x9F,
-0x37, 0x38, 0x4F, 0xE9,
+ 0x39, 0xE5, 0x2C, 0x9F,
+ 0x37, 0x38, 0x4F, 0xE9,
-0x2A, 0x43, 0x53, 0xBF,
-0x1A, 0x43, 0x63, 0xBF,
+ 0x2A, 0x43, 0x53, 0xBF,
+ 0x1A, 0x43, 0x63, 0xBF,
-0x30, 0x50, 0x2E, 0x9F,
-0x9D, 0x31, 0x4F, 0xE9,
+ 0x30, 0x50, 0x2E, 0x9F,
+ 0x9D, 0x31, 0x4F, 0xE9,
-0x38, 0x21, 0x2C, 0x9F,
-0x9E, 0x39, 0x4F, 0xE9,
+ 0x38, 0x21, 0x2C, 0x9F,
+ 0x9E, 0x39, 0x4F, 0xE9,
-0x0A, 0x48, 0x58, 0xBF,
-0x02, 0x48, 0x68, 0xBF,
+ 0x0A, 0x48, 0x58, 0xBF,
+ 0x02, 0x48, 0x68, 0xBF,
-0x31, 0x53, 0x2F, 0x9F,
-0x80, 0x31, 0x57, 0xE9,
+ 0x31, 0x53, 0x2F, 0x9F,
+ 0x80, 0x31, 0x57, 0xE9,
-0x39, 0xE5, 0x2C, 0x9F,
-0x81, 0x39, 0x57, 0xE9,
+ 0x39, 0xE5, 0x2C, 0x9F,
+ 0x81, 0x39, 0x57, 0xE9,
-0x2A, 0x49, 0x59, 0xBF,
-0x1A, 0x49, 0x69, 0xBF,
+ 0x2A, 0x49, 0x59, 0xBF,
+ 0x1A, 0x49, 0x69, 0xBF,
-0x30, 0x50, 0x2E, 0x9F,
-0x82, 0x30, 0x57, 0xE9,
+ 0x30, 0x50, 0x2E, 0x9F,
+ 0x82, 0x30, 0x57, 0xE9,
-0x38, 0x21, 0x2C, 0x9F,
-0x83, 0x38, 0x57, 0xE9,
+ 0x38, 0x21, 0x2C, 0x9F,
+ 0x83, 0x38, 0x57, 0xE9,
-0x31, 0x53, 0x2F, 0x9F,
-0x84, 0x31, 0x5E, 0xE9,
+ 0x31, 0x53, 0x2F, 0x9F,
+ 0x84, 0x31, 0x5E, 0xE9,
-0x39, 0xE5, 0x2C, 0x9F,
-0x85, 0x39, 0x5E, 0xE9,
+ 0x39, 0xE5, 0x2C, 0x9F,
+ 0x85, 0x39, 0x5E, 0xE9,
-0x86, 0x76, 0x57, 0xE9,
-0x8A, 0x36, 0x20, 0xE9,
+ 0x86, 0x76, 0x57, 0xE9,
+ 0x8A, 0x36, 0x20, 0xE9,
-0x87, 0x77, 0x57, 0xE9,
-0x8B, 0x3E, 0xBF, 0xEA,
+ 0x87, 0x77, 0x57, 0xE9,
+ 0x8B, 0x3E, 0xBF, 0xEA,
-0x80, 0x30, 0x57, 0xE9,
-0x81, 0x38, 0x57, 0xE9,
+ 0x80, 0x30, 0x57, 0xE9,
+ 0x81, 0x38, 0x57, 0xE9,
-0x82, 0x31, 0x57, 0xE9,
-0x86, 0x78, 0x57, 0xE9,
+ 0x82, 0x31, 0x57, 0xE9,
+ 0x86, 0x78, 0x57, 0xE9,
-0x83, 0x39, 0x57, 0xE9,
-0x87, 0x79, 0x57, 0xE9,
+ 0x83, 0x39, 0x57, 0xE9,
+ 0x87, 0x79, 0x57, 0xE9,
-0x30, 0x1F, 0x5F, 0xE9,
-0x8A, 0x34, 0x20, 0xE9,
+ 0x30, 0x1F, 0x5F, 0xE9,
+ 0x8A, 0x34, 0x20, 0xE9,
-0x8B, 0x3C, 0x20, 0xE9,
-0x37, 0x50, 0x60, 0xBD,
+ 0x8B, 0x3C, 0x20, 0xE9,
+ 0x37, 0x50, 0x60, 0xBD,
-0x57, 0x0D, 0x20, 0xE9,
-0x35, 0x51, 0x61, 0xBD,
+ 0x57, 0x0D, 0x20, 0xE9,
+ 0x35, 0x51, 0x61, 0xBD,
-0x2B, 0x50, 0x20, 0xE9,
-0x1D, 0x37, 0xE1, 0xEA,
+ 0x2B, 0x50, 0x20, 0xE9,
+ 0x1D, 0x37, 0xE1, 0xEA,
-0x1E, 0x35, 0xE1, 0xEA,
-0x00, 0xE0,
-0x0E, 0x77,
+ 0x1E, 0x35, 0xE1, 0xEA,
+ 0x00, 0xE0,
+ 0x0E, 0x77,
-0x24, 0x51, 0x20, 0xE9,
-0x9B, 0xFF, 0x20, 0xEA,
+ 0x24, 0x51, 0x20, 0xE9,
+ 0x9B, 0xFF, 0x20, 0xEA,
-0x16, 0x0E, 0x20, 0xE9,
-0x57, 0x2E, 0xBF, 0xEA,
+ 0x16, 0x0E, 0x20, 0xE9,
+ 0x57, 0x2E, 0xBF, 0xEA,
-0x0B, 0x46, 0xA0, 0xE8,
-0x1B, 0x56, 0xA0, 0xE8,
+ 0x0B, 0x46, 0xA0, 0xE8,
+ 0x1B, 0x56, 0xA0, 0xE8,
-0x2B, 0x66, 0xA0, 0xE8,
-0x0C, 0x47, 0xA0, 0xE8,
+ 0x2B, 0x66, 0xA0, 0xE8,
+ 0x0C, 0x47, 0xA0, 0xE8,
-0x1C, 0x57, 0xA0, 0xE8,
-0x2C, 0x67, 0xA0, 0xE8,
+ 0x1C, 0x57, 0xA0, 0xE8,
+ 0x2C, 0x67, 0xA0, 0xE8,
-0x0B, 0x00,
-0x1B, 0x00,
-0x2B, 0x00,
-0x00, 0xE0,
+ 0x0B, 0x00,
+ 0x1B, 0x00,
+ 0x2B, 0x00,
+ 0x00, 0xE0,
-0x0C, 0x00,
-0x1C, 0x00,
-0x2C, 0x00,
-0x00, 0xE0,
+ 0x0C, 0x00,
+ 0x1C, 0x00,
+ 0x2C, 0x00,
+ 0x00, 0xE0,
-0x0B, 0x65,
-0x1B, 0x65,
-0x2B, 0x65,
-0x00, 0xE0,
+ 0x0B, 0x65,
+ 0x1B, 0x65,
+ 0x2B, 0x65,
+ 0x00, 0xE0,
-0x0C, 0x65,
-0x1C, 0x65,
-0x2C, 0x65,
-0x00, 0xE0,
+ 0x0C, 0x65,
+ 0x1C, 0x65,
+ 0x2C, 0x65,
+ 0x00, 0xE0,
-0x0B, 0x1B, 0x60, 0xEC,
-0x36, 0xD7, 0x36, 0xAD,
+ 0x0B, 0x1B, 0x60, 0xEC,
+ 0x36, 0xD7, 0x36, 0xAD,
-0x2B, 0x80, 0x60, 0xEC,
-0x0C, 0x1C, 0x60, 0xEC,
+ 0x2B, 0x80, 0x60, 0xEC,
+ 0x0C, 0x1C, 0x60, 0xEC,
-0x3E, 0xD7, 0x3E, 0xAD,
-0x2C, 0x80, 0x60, 0xEC,
+ 0x3E, 0xD7, 0x3E, 0xAD,
+ 0x2C, 0x80, 0x60, 0xEC,
-0x0B, 0x2B, 0xDE, 0xE8,
-0x1B, 0x80, 0xDE, 0xE8,
+ 0x0B, 0x2B, 0xDE, 0xE8,
+ 0x1B, 0x80, 0xDE, 0xE8,
-0x36, 0x80, 0x36, 0xBD,
-0x3E, 0x80, 0x3E, 0xBD,
+ 0x36, 0x80, 0x36, 0xBD,
+ 0x3E, 0x80, 0x3E, 0xBD,
-0x33, 0xD7, 0x0B, 0xBD,
-0x3B, 0xD7, 0x1B, 0xBD,
+ 0x33, 0xD7, 0x0B, 0xBD,
+ 0x3B, 0xD7, 0x1B, 0xBD,
-0x46, 0x80, 0x46, 0xCF,
-0x57, 0x80, 0x57, 0xCF,
+ 0x46, 0x80, 0x46, 0xCF,
+ 0x57, 0x80, 0x57, 0xCF,
-0x66, 0x33, 0x66, 0xCF,
-0x47, 0x3B, 0x47, 0xCF,
+ 0x66, 0x33, 0x66, 0xCF,
+ 0x47, 0x3B, 0x47, 0xCF,
-0x56, 0x33, 0x56, 0xCF,
-0x67, 0x3B, 0x67, 0xCF,
+ 0x56, 0x33, 0x56, 0xCF,
+ 0x67, 0x3B, 0x67, 0xCF,
-0x0B, 0x48, 0xA0, 0xE8,
-0x1B, 0x58, 0xA0, 0xE8,
+ 0x0B, 0x48, 0xA0, 0xE8,
+ 0x1B, 0x58, 0xA0, 0xE8,
-0x2B, 0x68, 0xA0, 0xE8,
-0x0C, 0x49, 0xA0, 0xE8,
+ 0x2B, 0x68, 0xA0, 0xE8,
+ 0x0C, 0x49, 0xA0, 0xE8,
-0x1C, 0x59, 0xA0, 0xE8,
-0x2C, 0x69, 0xA0, 0xE8,
+ 0x1C, 0x59, 0xA0, 0xE8,
+ 0x2C, 0x69, 0xA0, 0xE8,
-0x0B, 0x00,
-0x1B, 0x00,
-0x2B, 0x00,
-0x00, 0xE0,
+ 0x0B, 0x00,
+ 0x1B, 0x00,
+ 0x2B, 0x00,
+ 0x00, 0xE0,
-0x0C, 0x00,
-0x1C, 0x00,
-0x2C, 0x00,
-0x00, 0xE0,
+ 0x0C, 0x00,
+ 0x1C, 0x00,
+ 0x2C, 0x00,
+ 0x00, 0xE0,
-0x0B, 0x65,
-0x1B, 0x65,
-0x2B, 0x65,
-0x00, 0xE0,
+ 0x0B, 0x65,
+ 0x1B, 0x65,
+ 0x2B, 0x65,
+ 0x00, 0xE0,
-0x0C, 0x65,
-0x1C, 0x65,
-0x2C, 0x65,
-0x00, 0xE0,
+ 0x0C, 0x65,
+ 0x1C, 0x65,
+ 0x2C, 0x65,
+ 0x00, 0xE0,
-0x0B, 0x1B, 0x60, 0xEC,
-0x34, 0xD7, 0x34, 0xAD,
+ 0x0B, 0x1B, 0x60, 0xEC,
+ 0x34, 0xD7, 0x34, 0xAD,
-0x2B, 0x80, 0x60, 0xEC,
-0x0C, 0x1C, 0x60, 0xEC,
+ 0x2B, 0x80, 0x60, 0xEC,
+ 0x0C, 0x1C, 0x60, 0xEC,
-0x3C, 0xD7, 0x3C, 0xAD,
-0x2C, 0x80, 0x60, 0xEC,
+ 0x3C, 0xD7, 0x3C, 0xAD,
+ 0x2C, 0x80, 0x60, 0xEC,
-0x0B, 0x2B, 0xDE, 0xE8,
-0x1B, 0x80, 0xDE, 0xE8,
+ 0x0B, 0x2B, 0xDE, 0xE8,
+ 0x1B, 0x80, 0xDE, 0xE8,
-0x34, 0x80, 0x34, 0xBD,
-0x3C, 0x80, 0x3C, 0xBD,
+ 0x34, 0x80, 0x34, 0xBD,
+ 0x3C, 0x80, 0x3C, 0xBD,
-0x33, 0xD7, 0x0B, 0xBD,
-0x3B, 0xD7, 0x1B, 0xBD,
+ 0x33, 0xD7, 0x0B, 0xBD,
+ 0x3B, 0xD7, 0x1B, 0xBD,
-0x48, 0x80, 0x48, 0xCF,
-0x59, 0x80, 0x59, 0xCF,
+ 0x48, 0x80, 0x48, 0xCF,
+ 0x59, 0x80, 0x59, 0xCF,
-0x68, 0x33, 0x68, 0xCF,
-0x49, 0x3B, 0x49, 0xCF,
+ 0x68, 0x33, 0x68, 0xCF,
+ 0x49, 0x3B, 0x49, 0xCF,
-0xBA, 0xFF, 0x20, 0xEA,
-0x00, 0x80, 0x00, 0xE8,
+ 0xBA, 0xFF, 0x20, 0xEA,
+ 0x00, 0x80, 0x00, 0xE8,
-0x58, 0x33, 0x58, 0xCF,
-0x69, 0x3B, 0x69, 0xCF,
+ 0x58, 0x33, 0x58, 0xCF,
+ 0x69, 0x3B, 0x69, 0xCF,
-0x79, 0xFF, 0x20, 0xEA,
-0x57, 0xC0, 0xBF, 0xEA,
+ 0x79, 0xFF, 0x20, 0xEA,
+ 0x57, 0xC0, 0xBF, 0xEA,
-0x00, 0x80, 0xA0, 0xE9,
-0x00, 0x00, 0xD8, 0xEC,
+ 0x00, 0x80, 0xA0, 0xE9,
+ 0x00, 0x00, 0xD8, 0xEC,
};
static unsigned char warp_g400_t2gzaf[] = {
-0x00, 0x8A, 0x98, 0xE9,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x8A, 0x98, 0xE9,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0xA0, 0xE9,
-0x00, 0x00, 0xD8, 0xEC,
+ 0x00, 0x80, 0xA0, 0xE9,
+ 0x00, 0x00, 0xD8, 0xEC,
-0xFF, 0x80, 0xC0, 0xE9,
-0x00, 0x80, 0x00, 0xE8,
+ 0xFF, 0x80, 0xC0, 0xE9,
+ 0x00, 0x80, 0x00, 0xE8,
-0x0A, 0x40, 0x50, 0xBF,
-0x2A, 0x40, 0x60, 0xBF,
+ 0x0A, 0x40, 0x50, 0xBF,
+ 0x2A, 0x40, 0x60, 0xBF,
-0x32, 0x41, 0x51, 0xBF,
-0x3A, 0x41, 0x61, 0xBF,
+ 0x32, 0x41, 0x51, 0xBF,
+ 0x3A, 0x41, 0x61, 0xBF,
-0xC3, 0x6B,
-0xD3, 0x6B,
-0x00, 0x8A, 0x98, 0xE9,
+ 0xC3, 0x6B,
+ 0xD3, 0x6B,
+ 0x00, 0x8A, 0x98, 0xE9,
-0x73, 0x7B, 0xC8, 0xEC,
-0x96, 0xE2,
-0x41, 0x04,
+ 0x73, 0x7B, 0xC8, 0xEC,
+ 0x96, 0xE2,
+ 0x41, 0x04,
-0x7B, 0x43, 0xA0, 0xE8,
-0x73, 0x53, 0xA0, 0xE8,
+ 0x7B, 0x43, 0xA0, 0xE8,
+ 0x73, 0x53, 0xA0, 0xE8,
-0xAD, 0xEE, 0x23, 0x9F,
-0x00, 0xE0,
-0x51, 0x04,
+ 0xAD, 0xEE, 0x23, 0x9F,
+ 0x00, 0xE0,
+ 0x51, 0x04,
-0x90, 0xE2,
-0x61, 0x04,
-0x31, 0x46, 0xB1, 0xE8,
+ 0x90, 0xE2,
+ 0x61, 0x04,
+ 0x31, 0x46, 0xB1, 0xE8,
-0x51, 0x41, 0xE0, 0xEC,
-0x39, 0x67, 0xB1, 0xE8,
+ 0x51, 0x41, 0xE0, 0xEC,
+ 0x39, 0x67, 0xB1, 0xE8,
-0x00, 0x04,
-0x46, 0xE2,
-0x73, 0x63, 0xA0, 0xE8,
+ 0x00, 0x04,
+ 0x46, 0xE2,
+ 0x73, 0x63, 0xA0, 0xE8,
-0x61, 0x41, 0xE0, 0xEC,
-0x31, 0x00,
-0x39, 0x00,
+ 0x61, 0x41, 0xE0, 0xEC,
+ 0x31, 0x00,
+ 0x39, 0x00,
-0x81, 0x80, 0x15, 0xEA,
-0x10, 0x04,
-0x20, 0x04,
+ 0x81, 0x80, 0x15, 0xEA,
+ 0x10, 0x04,
+ 0x20, 0x04,
-0x61, 0x51, 0xE0, 0xEC,
-0x2F, 0x41, 0x60, 0xEA,
+ 0x61, 0x51, 0xE0, 0xEC,
+ 0x2F, 0x41, 0x60, 0xEA,
-0x31, 0x20,
-0x39, 0x20,
-0x1F, 0x42, 0xA0, 0xE8,
+ 0x31, 0x20,
+ 0x39, 0x20,
+ 0x1F, 0x42, 0xA0, 0xE8,
-0x2A, 0x42, 0x52, 0xBF,
-0x0F, 0x52, 0xA0, 0xE8,
+ 0x2A, 0x42, 0x52, 0xBF,
+ 0x0F, 0x52, 0xA0, 0xE8,
-0x1A, 0x42, 0x62, 0xBF,
-0x1E, 0x51, 0x60, 0xEA,
+ 0x1A, 0x42, 0x62, 0xBF,
+ 0x1E, 0x51, 0x60, 0xEA,
-0x73, 0x7B, 0xC8, 0xEC,
-0x0E, 0x61, 0x60, 0xEA,
+ 0x73, 0x7B, 0xC8, 0xEC,
+ 0x0E, 0x61, 0x60, 0xEA,
-0x32, 0x40, 0x50, 0xBD,
-0x22, 0x40, 0x60, 0xBD,
+ 0x32, 0x40, 0x50, 0xBD,
+ 0x22, 0x40, 0x60, 0xBD,
-0x12, 0x41, 0x51, 0xBD,
-0x3A, 0x41, 0x61, 0xBD,
+ 0x12, 0x41, 0x51, 0xBD,
+ 0x3A, 0x41, 0x61, 0xBD,
-0xBF, 0x2F, 0x0E, 0xBD,
-0x97, 0xE2,
-0x7B, 0x72,
+ 0xBF, 0x2F, 0x0E, 0xBD,
+ 0x97, 0xE2,
+ 0x7B, 0x72,
-0x32, 0x20,
-0x22, 0x20,
-0x12, 0x20,
-0x3A, 0x20,
+ 0x32, 0x20,
+ 0x22, 0x20,
+ 0x12, 0x20,
+ 0x3A, 0x20,
-0x35, 0x48, 0xB1, 0xE8,
-0x3D, 0x59, 0xB1, 0xE8,
+ 0x35, 0x48, 0xB1, 0xE8,
+ 0x3D, 0x59, 0xB1, 0xE8,
-0x46, 0x31, 0x46, 0xBF,
-0x56, 0x31, 0x56, 0xBF,
+ 0x46, 0x31, 0x46, 0xBF,
+ 0x56, 0x31, 0x56, 0xBF,
-0xB3, 0xE2, 0x2D, 0x9F,
-0x00, 0x80, 0x00, 0xE8,
+ 0xB3, 0xE2, 0x2D, 0x9F,
+ 0x00, 0x80, 0x00, 0xE8,
-0x66, 0x31, 0x66, 0xBF,
-0x47, 0x39, 0x47, 0xBF,
+ 0x66, 0x31, 0x66, 0xBF,
+ 0x47, 0x39, 0x47, 0xBF,
-0x57, 0x39, 0x57, 0xBF,
-0x67, 0x39, 0x67, 0xBF,
+ 0x57, 0x39, 0x57, 0xBF,
+ 0x67, 0x39, 0x67, 0xBF,
-0x72, 0x80, 0x07, 0xEA,
-0x24, 0x41, 0x20, 0xE9,
+ 0x72, 0x80, 0x07, 0xEA,
+ 0x24, 0x41, 0x20, 0xE9,
-0x35, 0x00,
-0x3D, 0x00,
-0x00, 0xE0,
-0x2D, 0x73,
+ 0x35, 0x00,
+ 0x3D, 0x00,
+ 0x00, 0xE0,
+ 0x2D, 0x73,
-0x33, 0x72,
-0x0C, 0xE3,
-0x8D, 0x2F, 0x1E, 0xBD,
+ 0x33, 0x72,
+ 0x0C, 0xE3,
+ 0x8D, 0x2F, 0x1E, 0xBD,
-0x43, 0x75, 0xF8, 0xEC,
-0x35, 0x20,
-0x3D, 0x20,
+ 0x43, 0x75, 0xF8, 0xEC,
+ 0x35, 0x20,
+ 0x3D, 0x20,
-0x43, 0x43, 0x2D, 0xDF,
-0x53, 0x53, 0x2D, 0xDF,
+ 0x43, 0x43, 0x2D, 0xDF,
+ 0x53, 0x53, 0x2D, 0xDF,
-0xAE, 0x1E, 0x0E, 0xBD,
-0x58, 0xE3,
-0x33, 0x66,
+ 0xAE, 0x1E, 0x0E, 0xBD,
+ 0x58, 0xE3,
+ 0x33, 0x66,
-0x48, 0x35, 0x48, 0xBF,
-0x58, 0x35, 0x58, 0xBF,
+ 0x48, 0x35, 0x48, 0xBF,
+ 0x58, 0x35, 0x58, 0xBF,
-0x68, 0x35, 0x68, 0xBF,
-0x49, 0x3D, 0x49, 0xBF,
+ 0x68, 0x35, 0x68, 0xBF,
+ 0x49, 0x3D, 0x49, 0xBF,
-0x59, 0x3D, 0x59, 0xBF,
-0x69, 0x3D, 0x69, 0xBF,
+ 0x59, 0x3D, 0x59, 0xBF,
+ 0x69, 0x3D, 0x69, 0xBF,
-0x63, 0x63, 0x2D, 0xDF,
-0x4D, 0x7D, 0xF8, 0xEC,
+ 0x63, 0x63, 0x2D, 0xDF,
+ 0x4D, 0x7D, 0xF8, 0xEC,
-0x59, 0xE3,
-0x00, 0xE0,
-0xB8, 0x38, 0x33, 0xBF,
+ 0x59, 0xE3,
+ 0x00, 0xE0,
+ 0xB8, 0x38, 0x33, 0xBF,
-0x2D, 0x73,
-0x30, 0x76,
-0x18, 0x3A, 0x41, 0xE9,
+ 0x2D, 0x73,
+ 0x30, 0x76,
+ 0x18, 0x3A, 0x41, 0xE9,
-0x3F, 0x53, 0xA0, 0xE8,
-0x05, 0x80, 0x3D, 0xEA,
+ 0x3F, 0x53, 0xA0, 0xE8,
+ 0x05, 0x80, 0x3D, 0xEA,
-0x37, 0x43, 0xA0, 0xE8,
-0x3D, 0x63, 0xA0, 0xE8,
+ 0x37, 0x43, 0xA0, 0xE8,
+ 0x3D, 0x63, 0xA0, 0xE8,
-0x50, 0x70, 0xF8, 0xEC,
-0x2B, 0x50, 0x3C, 0xE9,
+ 0x50, 0x70, 0xF8, 0xEC,
+ 0x2B, 0x50, 0x3C, 0xE9,
-0x1F, 0x0F, 0xBC, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x1F, 0x0F, 0xBC, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x59, 0x78, 0xF8, 0xEC,
-0x00, 0x80, 0x00, 0xE8,
+ 0x59, 0x78, 0xF8, 0xEC,
+ 0x00, 0x80, 0x00, 0xE8,
-0x15, 0xC0, 0x20, 0xE9,
-0x15, 0xC0, 0x20, 0xE9,
+ 0x15, 0xC0, 0x20, 0xE9,
+ 0x15, 0xC0, 0x20, 0xE9,
-0x15, 0xC0, 0x20, 0xE9,
-0x15, 0xC0, 0x20, 0xE9,
+ 0x15, 0xC0, 0x20, 0xE9,
+ 0x15, 0xC0, 0x20, 0xE9,
-0x1E, 0x12, 0x41, 0xE9,
-0x1A, 0x22, 0x41, 0xE9,
+ 0x1E, 0x12, 0x41, 0xE9,
+ 0x1A, 0x22, 0x41, 0xE9,
-0x46, 0x37, 0x46, 0xDF,
-0x56, 0x3F, 0x56, 0xDF,
+ 0x46, 0x37, 0x46, 0xDF,
+ 0x56, 0x3F, 0x56, 0xDF,
-0x2B, 0x40, 0x3D, 0xE9,
-0x66, 0x3D, 0x66, 0xDF,
+ 0x2B, 0x40, 0x3D, 0xE9,
+ 0x66, 0x3D, 0x66, 0xDF,
-0x1D, 0x32, 0x41, 0xE9,
-0x67, 0x3D, 0x67, 0xDF,
+ 0x1D, 0x32, 0x41, 0xE9,
+ 0x67, 0x3D, 0x67, 0xDF,
-0x47, 0x37, 0x47, 0xDF,
-0x57, 0x3F, 0x57, 0xDF,
+ 0x47, 0x37, 0x47, 0xDF,
+ 0x57, 0x3F, 0x57, 0xDF,
-0x2A, 0x40, 0x20, 0xE9,
-0x59, 0x3F, 0x59, 0xDF,
+ 0x2A, 0x40, 0x20, 0xE9,
+ 0x59, 0x3F, 0x59, 0xDF,
-0x16, 0x30, 0x20, 0xE9,
-0x69, 0x3D, 0x69, 0xDF,
+ 0x16, 0x30, 0x20, 0xE9,
+ 0x69, 0x3D, 0x69, 0xDF,
-0x48, 0x37, 0x48, 0xDF,
-0x58, 0x3F, 0x58, 0xDF,
+ 0x48, 0x37, 0x48, 0xDF,
+ 0x58, 0x3F, 0x58, 0xDF,
-0x12, 0x12, 0x2D, 0xDF,
-0x22, 0x22, 0x2D, 0xDF,
+ 0x12, 0x12, 0x2D, 0xDF,
+ 0x22, 0x22, 0x2D, 0xDF,
-0x32, 0x32, 0x2D, 0xDF,
-0x3A, 0x3A, 0x2D, 0xDF,
+ 0x32, 0x32, 0x2D, 0xDF,
+ 0x3A, 0x3A, 0x2D, 0xDF,
-0x68, 0x3D, 0x68, 0xDF,
-0x49, 0x37, 0x49, 0xDF,
+ 0x68, 0x3D, 0x68, 0xDF,
+ 0x49, 0x37, 0x49, 0xDF,
-0x3D, 0xCF, 0x74, 0xC0,
-0x37, 0xCF, 0x74, 0xC4,
+ 0x3D, 0xCF, 0x74, 0xC0,
+ 0x37, 0xCF, 0x74, 0xC4,
-0x0A, 0x44, 0x54, 0xB0,
-0x02, 0x44, 0x64, 0xB0,
+ 0x0A, 0x44, 0x54, 0xB0,
+ 0x02, 0x44, 0x64, 0xB0,
-0x31, 0x53, 0x2F, 0x9F,
-0x34, 0x37, 0x20, 0xE9,
+ 0x31, 0x53, 0x2F, 0x9F,
+ 0x34, 0x37, 0x20, 0xE9,
-0x39, 0xE5, 0x2C, 0x9F,
-0x3C, 0x3D, 0x20, 0xE9,
+ 0x39, 0xE5, 0x2C, 0x9F,
+ 0x3C, 0x3D, 0x20, 0xE9,
-0x2A, 0x44, 0x54, 0xB2,
-0x1A, 0x44, 0x64, 0xB2,
+ 0x2A, 0x44, 0x54, 0xB2,
+ 0x1A, 0x44, 0x64, 0xB2,
-0x2E, 0x80, 0x3A, 0xEA,
-0x0A, 0x20,
-0x02, 0x20,
+ 0x2E, 0x80, 0x3A, 0xEA,
+ 0x0A, 0x20,
+ 0x02, 0x20,
-0x88, 0x73, 0x5E, 0xE9,
-0x2A, 0x20,
-0x1A, 0x20,
+ 0x88, 0x73, 0x5E, 0xE9,
+ 0x2A, 0x20,
+ 0x1A, 0x20,
-0x3D, 0xCF, 0x74, 0xC2,
-0x0F, 0xCF, 0x74, 0xC6,
+ 0x3D, 0xCF, 0x74, 0xC2,
+ 0x0F, 0xCF, 0x74, 0xC6,
-0x30, 0x50, 0x2E, 0x9F,
-0x32, 0x31, 0x5F, 0xE9,
+ 0x30, 0x50, 0x2E, 0x9F,
+ 0x32, 0x31, 0x5F, 0xE9,
-0x38, 0x21, 0x2C, 0x9F,
-0x33, 0x39, 0x5F, 0xE9,
+ 0x38, 0x21, 0x2C, 0x9F,
+ 0x33, 0x39, 0x5F, 0xE9,
-0x31, 0x53, 0x2F, 0x9F,
-0x9C, 0x0F, 0x20, 0xE9,
+ 0x31, 0x53, 0x2F, 0x9F,
+ 0x9C, 0x0F, 0x20, 0xE9,
-0x0A, 0x44, 0x54, 0xB4,
-0x02, 0x44, 0x64, 0xB4,
+ 0x0A, 0x44, 0x54, 0xB4,
+ 0x02, 0x44, 0x64, 0xB4,
-0x2A, 0x44, 0x54, 0xB6,
-0x1A, 0x44, 0x64, 0xB6,
+ 0x2A, 0x44, 0x54, 0xB6,
+ 0x1A, 0x44, 0x64, 0xB6,
-0x39, 0xE5, 0x2C, 0x9F,
-0x38, 0x3D, 0x20, 0xE9,
+ 0x39, 0xE5, 0x2C, 0x9F,
+ 0x38, 0x3D, 0x20, 0xE9,
-0x0A, 0x20,
-0x02, 0x20,
-0x2A, 0x20,
-0x1A, 0x20,
+ 0x0A, 0x20,
+ 0x02, 0x20,
+ 0x2A, 0x20,
+ 0x1A, 0x20,
-0x3D, 0xCF, 0x75, 0xC6,
-0x00, 0x80, 0x00, 0xE8,
+ 0x3D, 0xCF, 0x75, 0xC6,
+ 0x00, 0x80, 0x00, 0xE8,
-0x30, 0x50, 0x2E, 0x9F,
-0x3E, 0x30, 0x4F, 0xE9,
+ 0x30, 0x50, 0x2E, 0x9F,
+ 0x3E, 0x30, 0x4F, 0xE9,
-0x38, 0x21, 0x2C, 0x9F,
-0x3F, 0x38, 0x4F, 0xE9,
+ 0x38, 0x21, 0x2C, 0x9F,
+ 0x3F, 0x38, 0x4F, 0xE9,
-0x0A, 0x45, 0x55, 0xB6,
-0x02, 0x45, 0x65, 0xB6,
+ 0x0A, 0x45, 0x55, 0xB6,
+ 0x02, 0x45, 0x65, 0xB6,
-0x31, 0x53, 0x2F, 0x9F,
-0x3A, 0x31, 0x4F, 0xE9,
+ 0x31, 0x53, 0x2F, 0x9F,
+ 0x3A, 0x31, 0x4F, 0xE9,
-0x39, 0xE5, 0x2C, 0x9F,
-0x3B, 0x39, 0x4F, 0xE9,
+ 0x39, 0xE5, 0x2C, 0x9F,
+ 0x3B, 0x39, 0x4F, 0xE9,
-0x31, 0x3D, 0x20, 0xE9,
-0x0A, 0x20,
-0x02, 0x20,
+ 0x31, 0x3D, 0x20, 0xE9,
+ 0x0A, 0x20,
+ 0x02, 0x20,
-0x2A, 0x46, 0x56, 0xBF,
-0x1A, 0x46, 0x66, 0xBF,
+ 0x2A, 0x46, 0x56, 0xBF,
+ 0x1A, 0x46, 0x66, 0xBF,
-0x0A, 0x47, 0x57, 0xBF,
-0x02, 0x47, 0x67, 0xBF,
+ 0x0A, 0x47, 0x57, 0xBF,
+ 0x02, 0x47, 0x67, 0xBF,
-0x30, 0x50, 0x2E, 0x9F,
-0x36, 0x30, 0x4F, 0xE9,
+ 0x30, 0x50, 0x2E, 0x9F,
+ 0x36, 0x30, 0x4F, 0xE9,
-0x38, 0x21, 0x2C, 0x9F,
-0x37, 0x38, 0x4F, 0xE9,
+ 0x38, 0x21, 0x2C, 0x9F,
+ 0x37, 0x38, 0x4F, 0xE9,
-0x31, 0x53, 0x2F, 0x9F,
-0x9D, 0x31, 0x4F, 0xE9,
+ 0x31, 0x53, 0x2F, 0x9F,
+ 0x9D, 0x31, 0x4F, 0xE9,
-0x39, 0xE5, 0x2C, 0x9F,
-0x9E, 0x39, 0x4F, 0xE9,
+ 0x39, 0xE5, 0x2C, 0x9F,
+ 0x9E, 0x39, 0x4F, 0xE9,
-0x2A, 0x43, 0x53, 0xBF,
-0x1A, 0x43, 0x63, 0xBF,
+ 0x2A, 0x43, 0x53, 0xBF,
+ 0x1A, 0x43, 0x63, 0xBF,
-0x30, 0x50, 0x2E, 0x9F,
-0x35, 0x30, 0x4F, 0xE9,
+ 0x30, 0x50, 0x2E, 0x9F,
+ 0x35, 0x30, 0x4F, 0xE9,
-0x38, 0x21, 0x2C, 0x9F,
-0x39, 0x38, 0x4F, 0xE9,
+ 0x38, 0x21, 0x2C, 0x9F,
+ 0x39, 0x38, 0x4F, 0xE9,
-0x0A, 0x48, 0x58, 0xBF,
-0x02, 0x48, 0x68, 0xBF,
+ 0x0A, 0x48, 0x58, 0xBF,
+ 0x02, 0x48, 0x68, 0xBF,
-0x31, 0x53, 0x2F, 0x9F,
-0x80, 0x31, 0x57, 0xE9,
+ 0x31, 0x53, 0x2F, 0x9F,
+ 0x80, 0x31, 0x57, 0xE9,
-0x39, 0xE5, 0x2C, 0x9F,
-0x81, 0x39, 0x57, 0xE9,
+ 0x39, 0xE5, 0x2C, 0x9F,
+ 0x81, 0x39, 0x57, 0xE9,
-0x2A, 0x49, 0x59, 0xBF,
-0x1A, 0x49, 0x69, 0xBF,
+ 0x2A, 0x49, 0x59, 0xBF,
+ 0x1A, 0x49, 0x69, 0xBF,
-0x30, 0x50, 0x2E, 0x9F,
-0x82, 0x30, 0x57, 0xE9,
+ 0x30, 0x50, 0x2E, 0x9F,
+ 0x82, 0x30, 0x57, 0xE9,
-0x38, 0x21, 0x2C, 0x9F,
-0x83, 0x38, 0x57, 0xE9,
+ 0x38, 0x21, 0x2C, 0x9F,
+ 0x83, 0x38, 0x57, 0xE9,
-0x31, 0x53, 0x2F, 0x9F,
-0x84, 0x31, 0x5E, 0xE9,
+ 0x31, 0x53, 0x2F, 0x9F,
+ 0x84, 0x31, 0x5E, 0xE9,
-0x39, 0xE5, 0x2C, 0x9F,
-0x85, 0x39, 0x5E, 0xE9,
+ 0x39, 0xE5, 0x2C, 0x9F,
+ 0x85, 0x39, 0x5E, 0xE9,
-0x86, 0x76, 0x57, 0xE9,
-0x8A, 0x36, 0x20, 0xE9,
+ 0x86, 0x76, 0x57, 0xE9,
+ 0x8A, 0x36, 0x20, 0xE9,
-0x87, 0x77, 0x57, 0xE9,
-0x8B, 0x3E, 0xBF, 0xEA,
+ 0x87, 0x77, 0x57, 0xE9,
+ 0x8B, 0x3E, 0xBF, 0xEA,
-0x80, 0x30, 0x57, 0xE9,
-0x81, 0x38, 0x57, 0xE9,
+ 0x80, 0x30, 0x57, 0xE9,
+ 0x81, 0x38, 0x57, 0xE9,
-0x82, 0x31, 0x57, 0xE9,
-0x86, 0x78, 0x57, 0xE9,
+ 0x82, 0x31, 0x57, 0xE9,
+ 0x86, 0x78, 0x57, 0xE9,
-0x83, 0x39, 0x57, 0xE9,
-0x87, 0x79, 0x57, 0xE9,
+ 0x83, 0x39, 0x57, 0xE9,
+ 0x87, 0x79, 0x57, 0xE9,
-0x30, 0x1F, 0x5F, 0xE9,
-0x8A, 0x34, 0x20, 0xE9,
+ 0x30, 0x1F, 0x5F, 0xE9,
+ 0x8A, 0x34, 0x20, 0xE9,
-0x8B, 0x3C, 0x20, 0xE9,
-0x37, 0x50, 0x60, 0xBD,
+ 0x8B, 0x3C, 0x20, 0xE9,
+ 0x37, 0x50, 0x60, 0xBD,
-0x57, 0x0D, 0x20, 0xE9,
-0x35, 0x51, 0x61, 0xBD,
+ 0x57, 0x0D, 0x20, 0xE9,
+ 0x35, 0x51, 0x61, 0xBD,
-0x2B, 0x50, 0x20, 0xE9,
-0x1D, 0x37, 0xE1, 0xEA,
+ 0x2B, 0x50, 0x20, 0xE9,
+ 0x1D, 0x37, 0xE1, 0xEA,
-0x1E, 0x35, 0xE1, 0xEA,
-0x00, 0xE0,
-0x0E, 0x77,
+ 0x1E, 0x35, 0xE1, 0xEA,
+ 0x00, 0xE0,
+ 0x0E, 0x77,
-0x24, 0x51, 0x20, 0xE9,
-0x96, 0xFF, 0x20, 0xEA,
+ 0x24, 0x51, 0x20, 0xE9,
+ 0x96, 0xFF, 0x20, 0xEA,
-0x16, 0x0E, 0x20, 0xE9,
-0x57, 0x2E, 0xBF, 0xEA,
+ 0x16, 0x0E, 0x20, 0xE9,
+ 0x57, 0x2E, 0xBF, 0xEA,
-0x0B, 0x46, 0xA0, 0xE8,
-0x1B, 0x56, 0xA0, 0xE8,
+ 0x0B, 0x46, 0xA0, 0xE8,
+ 0x1B, 0x56, 0xA0, 0xE8,
-0x2B, 0x66, 0xA0, 0xE8,
-0x0C, 0x47, 0xA0, 0xE8,
+ 0x2B, 0x66, 0xA0, 0xE8,
+ 0x0C, 0x47, 0xA0, 0xE8,
-0x1C, 0x57, 0xA0, 0xE8,
-0x2C, 0x67, 0xA0, 0xE8,
+ 0x1C, 0x57, 0xA0, 0xE8,
+ 0x2C, 0x67, 0xA0, 0xE8,
-0x0B, 0x00,
-0x1B, 0x00,
-0x2B, 0x00,
-0x00, 0xE0,
+ 0x0B, 0x00,
+ 0x1B, 0x00,
+ 0x2B, 0x00,
+ 0x00, 0xE0,
-0x0C, 0x00,
-0x1C, 0x00,
-0x2C, 0x00,
-0x00, 0xE0,
+ 0x0C, 0x00,
+ 0x1C, 0x00,
+ 0x2C, 0x00,
+ 0x00, 0xE0,
-0x0B, 0x65,
-0x1B, 0x65,
-0x2B, 0x65,
-0x00, 0xE0,
+ 0x0B, 0x65,
+ 0x1B, 0x65,
+ 0x2B, 0x65,
+ 0x00, 0xE0,
-0x0C, 0x65,
-0x1C, 0x65,
-0x2C, 0x65,
-0x00, 0xE0,
+ 0x0C, 0x65,
+ 0x1C, 0x65,
+ 0x2C, 0x65,
+ 0x00, 0xE0,
-0x0B, 0x1B, 0x60, 0xEC,
-0x36, 0xD7, 0x36, 0xAD,
+ 0x0B, 0x1B, 0x60, 0xEC,
+ 0x36, 0xD7, 0x36, 0xAD,
-0x2B, 0x80, 0x60, 0xEC,
-0x0C, 0x1C, 0x60, 0xEC,
+ 0x2B, 0x80, 0x60, 0xEC,
+ 0x0C, 0x1C, 0x60, 0xEC,
-0x3E, 0xD7, 0x3E, 0xAD,
-0x2C, 0x80, 0x60, 0xEC,
+ 0x3E, 0xD7, 0x3E, 0xAD,
+ 0x2C, 0x80, 0x60, 0xEC,
-0x0B, 0x2B, 0xDE, 0xE8,
-0x1B, 0x80, 0xDE, 0xE8,
+ 0x0B, 0x2B, 0xDE, 0xE8,
+ 0x1B, 0x80, 0xDE, 0xE8,
-0x36, 0x80, 0x36, 0xBD,
-0x3E, 0x80, 0x3E, 0xBD,
+ 0x36, 0x80, 0x36, 0xBD,
+ 0x3E, 0x80, 0x3E, 0xBD,
-0x33, 0xD7, 0x0B, 0xBD,
-0x3B, 0xD7, 0x1B, 0xBD,
+ 0x33, 0xD7, 0x0B, 0xBD,
+ 0x3B, 0xD7, 0x1B, 0xBD,
-0x46, 0x80, 0x46, 0xCF,
-0x57, 0x80, 0x57, 0xCF,
+ 0x46, 0x80, 0x46, 0xCF,
+ 0x57, 0x80, 0x57, 0xCF,
-0x66, 0x33, 0x66, 0xCF,
-0x47, 0x3B, 0x47, 0xCF,
+ 0x66, 0x33, 0x66, 0xCF,
+ 0x47, 0x3B, 0x47, 0xCF,
-0x56, 0x33, 0x56, 0xCF,
-0x67, 0x3B, 0x67, 0xCF,
+ 0x56, 0x33, 0x56, 0xCF,
+ 0x67, 0x3B, 0x67, 0xCF,
-0x0B, 0x48, 0xA0, 0xE8,
-0x1B, 0x58, 0xA0, 0xE8,
+ 0x0B, 0x48, 0xA0, 0xE8,
+ 0x1B, 0x58, 0xA0, 0xE8,
-0x2B, 0x68, 0xA0, 0xE8,
-0x0C, 0x49, 0xA0, 0xE8,
+ 0x2B, 0x68, 0xA0, 0xE8,
+ 0x0C, 0x49, 0xA0, 0xE8,
-0x1C, 0x59, 0xA0, 0xE8,
-0x2C, 0x69, 0xA0, 0xE8,
+ 0x1C, 0x59, 0xA0, 0xE8,
+ 0x2C, 0x69, 0xA0, 0xE8,
-0x0B, 0x00,
-0x1B, 0x00,
-0x2B, 0x00,
-0x00, 0xE0,
+ 0x0B, 0x00,
+ 0x1B, 0x00,
+ 0x2B, 0x00,
+ 0x00, 0xE0,
-0x0C, 0x00,
-0x1C, 0x00,
-0x2C, 0x00,
-0x00, 0xE0,
+ 0x0C, 0x00,
+ 0x1C, 0x00,
+ 0x2C, 0x00,
+ 0x00, 0xE0,
-0x0B, 0x65,
-0x1B, 0x65,
-0x2B, 0x65,
-0x00, 0xE0,
+ 0x0B, 0x65,
+ 0x1B, 0x65,
+ 0x2B, 0x65,
+ 0x00, 0xE0,
-0x0C, 0x65,
-0x1C, 0x65,
-0x2C, 0x65,
-0x00, 0xE0,
+ 0x0C, 0x65,
+ 0x1C, 0x65,
+ 0x2C, 0x65,
+ 0x00, 0xE0,
-0x0B, 0x1B, 0x60, 0xEC,
-0x34, 0xD7, 0x34, 0xAD,
+ 0x0B, 0x1B, 0x60, 0xEC,
+ 0x34, 0xD7, 0x34, 0xAD,
-0x2B, 0x80, 0x60, 0xEC,
-0x0C, 0x1C, 0x60, 0xEC,
+ 0x2B, 0x80, 0x60, 0xEC,
+ 0x0C, 0x1C, 0x60, 0xEC,
-0x3C, 0xD7, 0x3C, 0xAD,
-0x2C, 0x80, 0x60, 0xEC,
+ 0x3C, 0xD7, 0x3C, 0xAD,
+ 0x2C, 0x80, 0x60, 0xEC,
-0x0B, 0x2B, 0xDE, 0xE8,
-0x1B, 0x80, 0xDE, 0xE8,
+ 0x0B, 0x2B, 0xDE, 0xE8,
+ 0x1B, 0x80, 0xDE, 0xE8,
-0x34, 0x80, 0x34, 0xBD,
-0x3C, 0x80, 0x3C, 0xBD,
+ 0x34, 0x80, 0x34, 0xBD,
+ 0x3C, 0x80, 0x3C, 0xBD,
-0x33, 0xD7, 0x0B, 0xBD,
-0x3B, 0xD7, 0x1B, 0xBD,
+ 0x33, 0xD7, 0x0B, 0xBD,
+ 0x3B, 0xD7, 0x1B, 0xBD,
-0x48, 0x80, 0x48, 0xCF,
-0x59, 0x80, 0x59, 0xCF,
+ 0x48, 0x80, 0x48, 0xCF,
+ 0x59, 0x80, 0x59, 0xCF,
-0x68, 0x33, 0x68, 0xCF,
-0x49, 0x3B, 0x49, 0xCF,
+ 0x68, 0x33, 0x68, 0xCF,
+ 0x49, 0x3B, 0x49, 0xCF,
-0xB5, 0xFF, 0x20, 0xEA,
-0x00, 0x80, 0x00, 0xE8,
+ 0xB5, 0xFF, 0x20, 0xEA,
+ 0x00, 0x80, 0x00, 0xE8,
-0x58, 0x33, 0x58, 0xCF,
-0x69, 0x3B, 0x69, 0xCF,
+ 0x58, 0x33, 0x58, 0xCF,
+ 0x69, 0x3B, 0x69, 0xCF,
-0x74, 0xFF, 0x20, 0xEA,
-0x57, 0xC0, 0xBF, 0xEA,
+ 0x74, 0xFF, 0x20, 0xEA,
+ 0x57, 0xC0, 0xBF, 0xEA,
-0x00, 0x80, 0xA0, 0xE9,
-0x00, 0x00, 0xD8, 0xEC,
+ 0x00, 0x80, 0xA0, 0xE9,
+ 0x00, 0x00, 0xD8, 0xEC,
};
static unsigned char warp_g400_t2gzf[] = {
-0x00, 0x8A, 0x98, 0xE9,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x8A, 0x98, 0xE9,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0xA0, 0xE9,
-0x00, 0x00, 0xD8, 0xEC,
+ 0x00, 0x80, 0xA0, 0xE9,
+ 0x00, 0x00, 0xD8, 0xEC,
-0xFF, 0x80, 0xC0, 0xE9,
-0x00, 0x80, 0x00, 0xE8,
+ 0xFF, 0x80, 0xC0, 0xE9,
+ 0x00, 0x80, 0x00, 0xE8,
-0x0A, 0x40, 0x50, 0xBF,
-0x2A, 0x40, 0x60, 0xBF,
+ 0x0A, 0x40, 0x50, 0xBF,
+ 0x2A, 0x40, 0x60, 0xBF,
-0x32, 0x41, 0x51, 0xBF,
-0x3A, 0x41, 0x61, 0xBF,
+ 0x32, 0x41, 0x51, 0xBF,
+ 0x3A, 0x41, 0x61, 0xBF,
-0xC3, 0x6B,
-0xD3, 0x6B,
-0x00, 0x8A, 0x98, 0xE9,
+ 0xC3, 0x6B,
+ 0xD3, 0x6B,
+ 0x00, 0x8A, 0x98, 0xE9,
-0x73, 0x7B, 0xC8, 0xEC,
-0x96, 0xE2,
-0x41, 0x04,
+ 0x73, 0x7B, 0xC8, 0xEC,
+ 0x96, 0xE2,
+ 0x41, 0x04,
-0x7B, 0x43, 0xA0, 0xE8,
-0x73, 0x53, 0xA0, 0xE8,
+ 0x7B, 0x43, 0xA0, 0xE8,
+ 0x73, 0x53, 0xA0, 0xE8,
-0xAD, 0xEE, 0x23, 0x9F,
-0x00, 0xE0,
-0x51, 0x04,
+ 0xAD, 0xEE, 0x23, 0x9F,
+ 0x00, 0xE0,
+ 0x51, 0x04,
-0x90, 0xE2,
-0x61, 0x04,
-0x31, 0x46, 0xB1, 0xE8,
+ 0x90, 0xE2,
+ 0x61, 0x04,
+ 0x31, 0x46, 0xB1, 0xE8,
-0x51, 0x41, 0xE0, 0xEC,
-0x39, 0x67, 0xB1, 0xE8,
+ 0x51, 0x41, 0xE0, 0xEC,
+ 0x39, 0x67, 0xB1, 0xE8,
-0x00, 0x04,
-0x46, 0xE2,
-0x73, 0x63, 0xA0, 0xE8,
+ 0x00, 0x04,
+ 0x46, 0xE2,
+ 0x73, 0x63, 0xA0, 0xE8,
-0x61, 0x41, 0xE0, 0xEC,
-0x31, 0x00,
-0x39, 0x00,
+ 0x61, 0x41, 0xE0, 0xEC,
+ 0x31, 0x00,
+ 0x39, 0x00,
-0x7D, 0x80, 0x15, 0xEA,
-0x10, 0x04,
-0x20, 0x04,
+ 0x7D, 0x80, 0x15, 0xEA,
+ 0x10, 0x04,
+ 0x20, 0x04,
-0x61, 0x51, 0xE0, 0xEC,
-0x2F, 0x41, 0x60, 0xEA,
+ 0x61, 0x51, 0xE0, 0xEC,
+ 0x2F, 0x41, 0x60, 0xEA,
-0x31, 0x20,
-0x39, 0x20,
-0x1F, 0x42, 0xA0, 0xE8,
+ 0x31, 0x20,
+ 0x39, 0x20,
+ 0x1F, 0x42, 0xA0, 0xE8,
-0x2A, 0x42, 0x52, 0xBF,
-0x0F, 0x52, 0xA0, 0xE8,
+ 0x2A, 0x42, 0x52, 0xBF,
+ 0x0F, 0x52, 0xA0, 0xE8,
-0x1A, 0x42, 0x62, 0xBF,
-0x1E, 0x51, 0x60, 0xEA,
+ 0x1A, 0x42, 0x62, 0xBF,
+ 0x1E, 0x51, 0x60, 0xEA,
-0x73, 0x7B, 0xC8, 0xEC,
-0x0E, 0x61, 0x60, 0xEA,
+ 0x73, 0x7B, 0xC8, 0xEC,
+ 0x0E, 0x61, 0x60, 0xEA,
-0x32, 0x40, 0x50, 0xBD,
-0x22, 0x40, 0x60, 0xBD,
+ 0x32, 0x40, 0x50, 0xBD,
+ 0x22, 0x40, 0x60, 0xBD,
-0x12, 0x41, 0x51, 0xBD,
-0x3A, 0x41, 0x61, 0xBD,
+ 0x12, 0x41, 0x51, 0xBD,
+ 0x3A, 0x41, 0x61, 0xBD,
-0xBF, 0x2F, 0x0E, 0xBD,
-0x97, 0xE2,
-0x7B, 0x72,
+ 0xBF, 0x2F, 0x0E, 0xBD,
+ 0x97, 0xE2,
+ 0x7B, 0x72,
-0x32, 0x20,
-0x22, 0x20,
-0x12, 0x20,
-0x3A, 0x20,
+ 0x32, 0x20,
+ 0x22, 0x20,
+ 0x12, 0x20,
+ 0x3A, 0x20,
-0x35, 0x48, 0xB1, 0xE8,
-0x3D, 0x59, 0xB1, 0xE8,
+ 0x35, 0x48, 0xB1, 0xE8,
+ 0x3D, 0x59, 0xB1, 0xE8,
-0x46, 0x31, 0x46, 0xBF,
-0x56, 0x31, 0x56, 0xBF,
+ 0x46, 0x31, 0x46, 0xBF,
+ 0x56, 0x31, 0x56, 0xBF,
-0xB3, 0xE2, 0x2D, 0x9F,
-0x00, 0x80, 0x00, 0xE8,
+ 0xB3, 0xE2, 0x2D, 0x9F,
+ 0x00, 0x80, 0x00, 0xE8,
-0x66, 0x31, 0x66, 0xBF,
-0x47, 0x39, 0x47, 0xBF,
+ 0x66, 0x31, 0x66, 0xBF,
+ 0x47, 0x39, 0x47, 0xBF,
-0x57, 0x39, 0x57, 0xBF,
-0x67, 0x39, 0x67, 0xBF,
+ 0x57, 0x39, 0x57, 0xBF,
+ 0x67, 0x39, 0x67, 0xBF,
-0x6E, 0x80, 0x07, 0xEA,
-0x24, 0x41, 0x20, 0xE9,
+ 0x6E, 0x80, 0x07, 0xEA,
+ 0x24, 0x41, 0x20, 0xE9,
-0x35, 0x00,
-0x3D, 0x00,
-0x00, 0xE0,
-0x2D, 0x73,
+ 0x35, 0x00,
+ 0x3D, 0x00,
+ 0x00, 0xE0,
+ 0x2D, 0x73,
-0x33, 0x72,
-0x0C, 0xE3,
-0x8D, 0x2F, 0x1E, 0xBD,
+ 0x33, 0x72,
+ 0x0C, 0xE3,
+ 0x8D, 0x2F, 0x1E, 0xBD,
-0x43, 0x75, 0xF8, 0xEC,
-0x35, 0x20,
-0x3D, 0x20,
+ 0x43, 0x75, 0xF8, 0xEC,
+ 0x35, 0x20,
+ 0x3D, 0x20,
-0x43, 0x43, 0x2D, 0xDF,
-0x53, 0x53, 0x2D, 0xDF,
+ 0x43, 0x43, 0x2D, 0xDF,
+ 0x53, 0x53, 0x2D, 0xDF,
-0xAE, 0x1E, 0x0E, 0xBD,
-0x58, 0xE3,
-0x33, 0x66,
+ 0xAE, 0x1E, 0x0E, 0xBD,
+ 0x58, 0xE3,
+ 0x33, 0x66,
-0x48, 0x35, 0x48, 0xBF,
-0x58, 0x35, 0x58, 0xBF,
+ 0x48, 0x35, 0x48, 0xBF,
+ 0x58, 0x35, 0x58, 0xBF,
-0x68, 0x35, 0x68, 0xBF,
-0x49, 0x3D, 0x49, 0xBF,
+ 0x68, 0x35, 0x68, 0xBF,
+ 0x49, 0x3D, 0x49, 0xBF,
-0x59, 0x3D, 0x59, 0xBF,
-0x69, 0x3D, 0x69, 0xBF,
+ 0x59, 0x3D, 0x59, 0xBF,
+ 0x69, 0x3D, 0x69, 0xBF,
-0x63, 0x63, 0x2D, 0xDF,
-0x4D, 0x7D, 0xF8, 0xEC,
+ 0x63, 0x63, 0x2D, 0xDF,
+ 0x4D, 0x7D, 0xF8, 0xEC,
-0x59, 0xE3,
-0x00, 0xE0,
-0xB8, 0x38, 0x33, 0xBF,
+ 0x59, 0xE3,
+ 0x00, 0xE0,
+ 0xB8, 0x38, 0x33, 0xBF,
-0x2D, 0x73,
-0x30, 0x76,
-0x18, 0x3A, 0x41, 0xE9,
+ 0x2D, 0x73,
+ 0x30, 0x76,
+ 0x18, 0x3A, 0x41, 0xE9,
-0x3F, 0x53, 0xA0, 0xE8,
-0x05, 0x80, 0x3D, 0xEA,
+ 0x3F, 0x53, 0xA0, 0xE8,
+ 0x05, 0x80, 0x3D, 0xEA,
-0x37, 0x43, 0xA0, 0xE8,
-0x3D, 0x63, 0xA0, 0xE8,
+ 0x37, 0x43, 0xA0, 0xE8,
+ 0x3D, 0x63, 0xA0, 0xE8,
-0x50, 0x70, 0xF8, 0xEC,
-0x2B, 0x50, 0x3C, 0xE9,
+ 0x50, 0x70, 0xF8, 0xEC,
+ 0x2B, 0x50, 0x3C, 0xE9,
-0x1F, 0x0F, 0xBC, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x1F, 0x0F, 0xBC, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x59, 0x78, 0xF8, 0xEC,
-0x00, 0x80, 0x00, 0xE8,
+ 0x59, 0x78, 0xF8, 0xEC,
+ 0x00, 0x80, 0x00, 0xE8,
-0x15, 0xC0, 0x20, 0xE9,
-0x15, 0xC0, 0x20, 0xE9,
+ 0x15, 0xC0, 0x20, 0xE9,
+ 0x15, 0xC0, 0x20, 0xE9,
-0x15, 0xC0, 0x20, 0xE9,
-0x15, 0xC0, 0x20, 0xE9,
+ 0x15, 0xC0, 0x20, 0xE9,
+ 0x15, 0xC0, 0x20, 0xE9,
-0x1E, 0x12, 0x41, 0xE9,
-0x1A, 0x22, 0x41, 0xE9,
+ 0x1E, 0x12, 0x41, 0xE9,
+ 0x1A, 0x22, 0x41, 0xE9,
-0x46, 0x37, 0x46, 0xDF,
-0x56, 0x3F, 0x56, 0xDF,
+ 0x46, 0x37, 0x46, 0xDF,
+ 0x56, 0x3F, 0x56, 0xDF,
-0x2B, 0x40, 0x3D, 0xE9,
-0x66, 0x3D, 0x66, 0xDF,
+ 0x2B, 0x40, 0x3D, 0xE9,
+ 0x66, 0x3D, 0x66, 0xDF,
-0x1D, 0x32, 0x41, 0xE9,
-0x67, 0x3D, 0x67, 0xDF,
+ 0x1D, 0x32, 0x41, 0xE9,
+ 0x67, 0x3D, 0x67, 0xDF,
-0x47, 0x37, 0x47, 0xDF,
-0x57, 0x3F, 0x57, 0xDF,
+ 0x47, 0x37, 0x47, 0xDF,
+ 0x57, 0x3F, 0x57, 0xDF,
-0x2A, 0x40, 0x20, 0xE9,
-0x59, 0x3F, 0x59, 0xDF,
+ 0x2A, 0x40, 0x20, 0xE9,
+ 0x59, 0x3F, 0x59, 0xDF,
-0x16, 0x30, 0x20, 0xE9,
-0x69, 0x3D, 0x69, 0xDF,
+ 0x16, 0x30, 0x20, 0xE9,
+ 0x69, 0x3D, 0x69, 0xDF,
-0x48, 0x37, 0x48, 0xDF,
-0x58, 0x3F, 0x58, 0xDF,
+ 0x48, 0x37, 0x48, 0xDF,
+ 0x58, 0x3F, 0x58, 0xDF,
-0x12, 0x12, 0x2D, 0xDF,
-0x22, 0x22, 0x2D, 0xDF,
+ 0x12, 0x12, 0x2D, 0xDF,
+ 0x22, 0x22, 0x2D, 0xDF,
-0x32, 0x32, 0x2D, 0xDF,
-0x3A, 0x3A, 0x2D, 0xDF,
+ 0x32, 0x32, 0x2D, 0xDF,
+ 0x3A, 0x3A, 0x2D, 0xDF,
-0x68, 0x3D, 0x68, 0xDF,
-0x49, 0x37, 0x49, 0xDF,
+ 0x68, 0x3D, 0x68, 0xDF,
+ 0x49, 0x37, 0x49, 0xDF,
-0x3D, 0xCF, 0x74, 0xC0,
-0x37, 0xCF, 0x74, 0xC4,
+ 0x3D, 0xCF, 0x74, 0xC0,
+ 0x37, 0xCF, 0x74, 0xC4,
-0x39, 0xE5, 0x2C, 0x9F,
-0x34, 0x80, 0x20, 0xE9,
+ 0x39, 0xE5, 0x2C, 0x9F,
+ 0x34, 0x80, 0x20, 0xE9,
-0x31, 0x53, 0x2F, 0x9F,
-0x00, 0x80, 0x00, 0xE8,
+ 0x31, 0x53, 0x2F, 0x9F,
+ 0x00, 0x80, 0x00, 0xE8,
-0x88, 0x73, 0x5E, 0xE9,
-0x00, 0x80, 0x00, 0xE8,
+ 0x88, 0x73, 0x5E, 0xE9,
+ 0x00, 0x80, 0x00, 0xE8,
-0x0F, 0xCF, 0x75, 0xC6,
-0x3C, 0x3D, 0x20, 0xE9,
+ 0x0F, 0xCF, 0x75, 0xC6,
+ 0x3C, 0x3D, 0x20, 0xE9,
-0x0A, 0x44, 0x54, 0xB0,
-0x02, 0x44, 0x64, 0xB0,
+ 0x0A, 0x44, 0x54, 0xB0,
+ 0x02, 0x44, 0x64, 0xB0,
-0x2A, 0x44, 0x54, 0xB2,
-0x1A, 0x44, 0x64, 0xB2,
+ 0x2A, 0x44, 0x54, 0xB2,
+ 0x1A, 0x44, 0x64, 0xB2,
-0x28, 0x80, 0x3A, 0xEA,
-0x0A, 0x20,
-0x02, 0x20,
+ 0x28, 0x80, 0x3A, 0xEA,
+ 0x0A, 0x20,
+ 0x02, 0x20,
-0x3D, 0xCF, 0x74, 0xC2,
-0x2A, 0x20,
-0x1A, 0x20,
+ 0x3D, 0xCF, 0x74, 0xC2,
+ 0x2A, 0x20,
+ 0x1A, 0x20,
-0x30, 0x50, 0x2E, 0x9F,
-0x32, 0x31, 0x5F, 0xE9,
+ 0x30, 0x50, 0x2E, 0x9F,
+ 0x32, 0x31, 0x5F, 0xE9,
-0x38, 0x21, 0x2C, 0x9F,
-0x33, 0x39, 0x5F, 0xE9,
+ 0x38, 0x21, 0x2C, 0x9F,
+ 0x33, 0x39, 0x5F, 0xE9,
-0x31, 0x53, 0x2F, 0x9F,
-0x31, 0x0F, 0x20, 0xE9,
+ 0x31, 0x53, 0x2F, 0x9F,
+ 0x31, 0x0F, 0x20, 0xE9,
-0x0A, 0x44, 0x54, 0xB4,
-0x02, 0x44, 0x64, 0xB4,
+ 0x0A, 0x44, 0x54, 0xB4,
+ 0x02, 0x44, 0x64, 0xB4,
-0x2A, 0x45, 0x55, 0xB6,
-0x1A, 0x45, 0x65, 0xB6,
+ 0x2A, 0x45, 0x55, 0xB6,
+ 0x1A, 0x45, 0x65, 0xB6,
-0x39, 0xE5, 0x2C, 0x9F,
-0x38, 0x3D, 0x20, 0xE9,
+ 0x39, 0xE5, 0x2C, 0x9F,
+ 0x38, 0x3D, 0x20, 0xE9,
-0x0A, 0x20,
-0x02, 0x20,
-0x2A, 0x20,
-0x1A, 0x20,
+ 0x0A, 0x20,
+ 0x02, 0x20,
+ 0x2A, 0x20,
+ 0x1A, 0x20,
-0x0A, 0x47, 0x57, 0xBF,
-0x02, 0x47, 0x67, 0xBF,
+ 0x0A, 0x47, 0x57, 0xBF,
+ 0x02, 0x47, 0x67, 0xBF,
-0x30, 0x50, 0x2E, 0x9F,
-0x3E, 0x30, 0x4F, 0xE9,
+ 0x30, 0x50, 0x2E, 0x9F,
+ 0x3E, 0x30, 0x4F, 0xE9,
-0x38, 0x21, 0x2C, 0x9F,
-0x3F, 0x38, 0x4F, 0xE9,
+ 0x38, 0x21, 0x2C, 0x9F,
+ 0x3F, 0x38, 0x4F, 0xE9,
-0x2A, 0x46, 0x56, 0xBF,
-0x1A, 0x46, 0x66, 0xBF,
+ 0x2A, 0x46, 0x56, 0xBF,
+ 0x1A, 0x46, 0x66, 0xBF,
-0x31, 0x53, 0x2F, 0x9F,
-0x3A, 0x31, 0x4F, 0xE9,
+ 0x31, 0x53, 0x2F, 0x9F,
+ 0x3A, 0x31, 0x4F, 0xE9,
-0x39, 0xE5, 0x2C, 0x9F,
-0x3B, 0x39, 0x4F, 0xE9,
+ 0x39, 0xE5, 0x2C, 0x9F,
+ 0x3B, 0x39, 0x4F, 0xE9,
-0x31, 0x53, 0x2F, 0x9F,
-0x36, 0x30, 0x4F, 0xE9,
+ 0x31, 0x53, 0x2F, 0x9F,
+ 0x36, 0x30, 0x4F, 0xE9,
-0x39, 0xE5, 0x2C, 0x9F,
-0x37, 0x38, 0x4F, 0xE9,
+ 0x39, 0xE5, 0x2C, 0x9F,
+ 0x37, 0x38, 0x4F, 0xE9,
-0x2A, 0x43, 0x53, 0xBF,
-0x1A, 0x43, 0x63, 0xBF,
+ 0x2A, 0x43, 0x53, 0xBF,
+ 0x1A, 0x43, 0x63, 0xBF,
-0x30, 0x50, 0x2E, 0x9F,
-0x35, 0x31, 0x4F, 0xE9,
+ 0x30, 0x50, 0x2E, 0x9F,
+ 0x35, 0x31, 0x4F, 0xE9,
-0x38, 0x21, 0x2C, 0x9F,
-0x39, 0x39, 0x4F, 0xE9,
+ 0x38, 0x21, 0x2C, 0x9F,
+ 0x39, 0x39, 0x4F, 0xE9,
-0x0A, 0x48, 0x58, 0xBF,
-0x02, 0x48, 0x68, 0xBF,
+ 0x0A, 0x48, 0x58, 0xBF,
+ 0x02, 0x48, 0x68, 0xBF,
-0x31, 0x53, 0x2F, 0x9F,
-0x80, 0x31, 0x57, 0xE9,
+ 0x31, 0x53, 0x2F, 0x9F,
+ 0x80, 0x31, 0x57, 0xE9,
-0x39, 0xE5, 0x2C, 0x9F,
-0x81, 0x39, 0x57, 0xE9,
+ 0x39, 0xE5, 0x2C, 0x9F,
+ 0x81, 0x39, 0x57, 0xE9,
-0x2A, 0x49, 0x59, 0xBF,
-0x1A, 0x49, 0x69, 0xBF,
+ 0x2A, 0x49, 0x59, 0xBF,
+ 0x1A, 0x49, 0x69, 0xBF,
-0x30, 0x50, 0x2E, 0x9F,
-0x82, 0x30, 0x57, 0xE9,
+ 0x30, 0x50, 0x2E, 0x9F,
+ 0x82, 0x30, 0x57, 0xE9,
-0x38, 0x21, 0x2C, 0x9F,
-0x83, 0x38, 0x57, 0xE9,
+ 0x38, 0x21, 0x2C, 0x9F,
+ 0x83, 0x38, 0x57, 0xE9,
-0x31, 0x53, 0x2F, 0x9F,
-0x84, 0x31, 0x5E, 0xE9,
+ 0x31, 0x53, 0x2F, 0x9F,
+ 0x84, 0x31, 0x5E, 0xE9,
-0x39, 0xE5, 0x2C, 0x9F,
-0x85, 0x39, 0x5E, 0xE9,
+ 0x39, 0xE5, 0x2C, 0x9F,
+ 0x85, 0x39, 0x5E, 0xE9,
-0x86, 0x76, 0x57, 0xE9,
-0x8A, 0x36, 0x20, 0xE9,
+ 0x86, 0x76, 0x57, 0xE9,
+ 0x8A, 0x36, 0x20, 0xE9,
-0x87, 0x77, 0x57, 0xE9,
-0x8B, 0x3E, 0xBF, 0xEA,
+ 0x87, 0x77, 0x57, 0xE9,
+ 0x8B, 0x3E, 0xBF, 0xEA,
-0x80, 0x30, 0x57, 0xE9,
-0x81, 0x38, 0x57, 0xE9,
+ 0x80, 0x30, 0x57, 0xE9,
+ 0x81, 0x38, 0x57, 0xE9,
-0x82, 0x31, 0x57, 0xE9,
-0x86, 0x78, 0x57, 0xE9,
+ 0x82, 0x31, 0x57, 0xE9,
+ 0x86, 0x78, 0x57, 0xE9,
-0x83, 0x39, 0x57, 0xE9,
-0x87, 0x79, 0x57, 0xE9,
+ 0x83, 0x39, 0x57, 0xE9,
+ 0x87, 0x79, 0x57, 0xE9,
-0x30, 0x1F, 0x5F, 0xE9,
-0x8A, 0x34, 0x20, 0xE9,
+ 0x30, 0x1F, 0x5F, 0xE9,
+ 0x8A, 0x34, 0x20, 0xE9,
-0x8B, 0x3C, 0x20, 0xE9,
-0x37, 0x50, 0x60, 0xBD,
+ 0x8B, 0x3C, 0x20, 0xE9,
+ 0x37, 0x50, 0x60, 0xBD,
-0x57, 0x0D, 0x20, 0xE9,
-0x35, 0x51, 0x61, 0xBD,
+ 0x57, 0x0D, 0x20, 0xE9,
+ 0x35, 0x51, 0x61, 0xBD,
-0x2B, 0x50, 0x20, 0xE9,
-0x1D, 0x37, 0xE1, 0xEA,
+ 0x2B, 0x50, 0x20, 0xE9,
+ 0x1D, 0x37, 0xE1, 0xEA,
-0x1E, 0x35, 0xE1, 0xEA,
-0x00, 0xE0,
-0x0E, 0x77,
+ 0x1E, 0x35, 0xE1, 0xEA,
+ 0x00, 0xE0,
+ 0x0E, 0x77,
-0x24, 0x51, 0x20, 0xE9,
-0x9A, 0xFF, 0x20, 0xEA,
+ 0x24, 0x51, 0x20, 0xE9,
+ 0x9A, 0xFF, 0x20, 0xEA,
-0x16, 0x0E, 0x20, 0xE9,
-0x57, 0x2E, 0xBF, 0xEA,
+ 0x16, 0x0E, 0x20, 0xE9,
+ 0x57, 0x2E, 0xBF, 0xEA,
-0x0B, 0x46, 0xA0, 0xE8,
-0x1B, 0x56, 0xA0, 0xE8,
+ 0x0B, 0x46, 0xA0, 0xE8,
+ 0x1B, 0x56, 0xA0, 0xE8,
-0x2B, 0x66, 0xA0, 0xE8,
-0x0C, 0x47, 0xA0, 0xE8,
+ 0x2B, 0x66, 0xA0, 0xE8,
+ 0x0C, 0x47, 0xA0, 0xE8,
-0x1C, 0x57, 0xA0, 0xE8,
-0x2C, 0x67, 0xA0, 0xE8,
+ 0x1C, 0x57, 0xA0, 0xE8,
+ 0x2C, 0x67, 0xA0, 0xE8,
-0x0B, 0x00,
-0x1B, 0x00,
-0x2B, 0x00,
-0x00, 0xE0,
+ 0x0B, 0x00,
+ 0x1B, 0x00,
+ 0x2B, 0x00,
+ 0x00, 0xE0,
-0x0C, 0x00,
-0x1C, 0x00,
-0x2C, 0x00,
-0x00, 0xE0,
+ 0x0C, 0x00,
+ 0x1C, 0x00,
+ 0x2C, 0x00,
+ 0x00, 0xE0,
-0x0B, 0x65,
-0x1B, 0x65,
-0x2B, 0x65,
-0x00, 0xE0,
+ 0x0B, 0x65,
+ 0x1B, 0x65,
+ 0x2B, 0x65,
+ 0x00, 0xE0,
-0x0C, 0x65,
-0x1C, 0x65,
-0x2C, 0x65,
-0x00, 0xE0,
+ 0x0C, 0x65,
+ 0x1C, 0x65,
+ 0x2C, 0x65,
+ 0x00, 0xE0,
-0x0B, 0x1B, 0x60, 0xEC,
-0x36, 0xD7, 0x36, 0xAD,
+ 0x0B, 0x1B, 0x60, 0xEC,
+ 0x36, 0xD7, 0x36, 0xAD,
-0x2B, 0x80, 0x60, 0xEC,
-0x0C, 0x1C, 0x60, 0xEC,
+ 0x2B, 0x80, 0x60, 0xEC,
+ 0x0C, 0x1C, 0x60, 0xEC,
-0x3E, 0xD7, 0x3E, 0xAD,
-0x2C, 0x80, 0x60, 0xEC,
+ 0x3E, 0xD7, 0x3E, 0xAD,
+ 0x2C, 0x80, 0x60, 0xEC,
-0x0B, 0x2B, 0xDE, 0xE8,
-0x1B, 0x80, 0xDE, 0xE8,
+ 0x0B, 0x2B, 0xDE, 0xE8,
+ 0x1B, 0x80, 0xDE, 0xE8,
-0x36, 0x80, 0x36, 0xBD,
-0x3E, 0x80, 0x3E, 0xBD,
+ 0x36, 0x80, 0x36, 0xBD,
+ 0x3E, 0x80, 0x3E, 0xBD,
-0x33, 0xD7, 0x0B, 0xBD,
-0x3B, 0xD7, 0x1B, 0xBD,
+ 0x33, 0xD7, 0x0B, 0xBD,
+ 0x3B, 0xD7, 0x1B, 0xBD,
-0x46, 0x80, 0x46, 0xCF,
-0x57, 0x80, 0x57, 0xCF,
+ 0x46, 0x80, 0x46, 0xCF,
+ 0x57, 0x80, 0x57, 0xCF,
-0x66, 0x33, 0x66, 0xCF,
-0x47, 0x3B, 0x47, 0xCF,
+ 0x66, 0x33, 0x66, 0xCF,
+ 0x47, 0x3B, 0x47, 0xCF,
-0x56, 0x33, 0x56, 0xCF,
-0x67, 0x3B, 0x67, 0xCF,
+ 0x56, 0x33, 0x56, 0xCF,
+ 0x67, 0x3B, 0x67, 0xCF,
-0x0B, 0x48, 0xA0, 0xE8,
-0x1B, 0x58, 0xA0, 0xE8,
+ 0x0B, 0x48, 0xA0, 0xE8,
+ 0x1B, 0x58, 0xA0, 0xE8,
-0x2B, 0x68, 0xA0, 0xE8,
-0x0C, 0x49, 0xA0, 0xE8,
+ 0x2B, 0x68, 0xA0, 0xE8,
+ 0x0C, 0x49, 0xA0, 0xE8,
-0x1C, 0x59, 0xA0, 0xE8,
-0x2C, 0x69, 0xA0, 0xE8,
+ 0x1C, 0x59, 0xA0, 0xE8,
+ 0x2C, 0x69, 0xA0, 0xE8,
-0x0B, 0x00,
-0x1B, 0x00,
-0x2B, 0x00,
-0x00, 0xE0,
+ 0x0B, 0x00,
+ 0x1B, 0x00,
+ 0x2B, 0x00,
+ 0x00, 0xE0,
-0x0C, 0x00,
-0x1C, 0x00,
-0x2C, 0x00,
-0x00, 0xE0,
+ 0x0C, 0x00,
+ 0x1C, 0x00,
+ 0x2C, 0x00,
+ 0x00, 0xE0,
-0x0B, 0x65,
-0x1B, 0x65,
-0x2B, 0x65,
-0x00, 0xE0,
+ 0x0B, 0x65,
+ 0x1B, 0x65,
+ 0x2B, 0x65,
+ 0x00, 0xE0,
-0x0C, 0x65,
-0x1C, 0x65,
-0x2C, 0x65,
-0x00, 0xE0,
+ 0x0C, 0x65,
+ 0x1C, 0x65,
+ 0x2C, 0x65,
+ 0x00, 0xE0,
-0x0B, 0x1B, 0x60, 0xEC,
-0x34, 0xD7, 0x34, 0xAD,
+ 0x0B, 0x1B, 0x60, 0xEC,
+ 0x34, 0xD7, 0x34, 0xAD,
-0x2B, 0x80, 0x60, 0xEC,
-0x0C, 0x1C, 0x60, 0xEC,
+ 0x2B, 0x80, 0x60, 0xEC,
+ 0x0C, 0x1C, 0x60, 0xEC,
-0x3C, 0xD7, 0x3C, 0xAD,
-0x2C, 0x80, 0x60, 0xEC,
+ 0x3C, 0xD7, 0x3C, 0xAD,
+ 0x2C, 0x80, 0x60, 0xEC,
-0x0B, 0x2B, 0xDE, 0xE8,
-0x1B, 0x80, 0xDE, 0xE8,
+ 0x0B, 0x2B, 0xDE, 0xE8,
+ 0x1B, 0x80, 0xDE, 0xE8,
-0x34, 0x80, 0x34, 0xBD,
-0x3C, 0x80, 0x3C, 0xBD,
+ 0x34, 0x80, 0x34, 0xBD,
+ 0x3C, 0x80, 0x3C, 0xBD,
-0x33, 0xD7, 0x0B, 0xBD,
-0x3B, 0xD7, 0x1B, 0xBD,
+ 0x33, 0xD7, 0x0B, 0xBD,
+ 0x3B, 0xD7, 0x1B, 0xBD,
-0x48, 0x80, 0x48, 0xCF,
-0x59, 0x80, 0x59, 0xCF,
+ 0x48, 0x80, 0x48, 0xCF,
+ 0x59, 0x80, 0x59, 0xCF,
-0x68, 0x33, 0x68, 0xCF,
-0x49, 0x3B, 0x49, 0xCF,
+ 0x68, 0x33, 0x68, 0xCF,
+ 0x49, 0x3B, 0x49, 0xCF,
-0xBB, 0xFF, 0x20, 0xEA,
-0x00, 0x80, 0x00, 0xE8,
+ 0xBB, 0xFF, 0x20, 0xEA,
+ 0x00, 0x80, 0x00, 0xE8,
-0x58, 0x33, 0x58, 0xCF,
-0x69, 0x3B, 0x69, 0xCF,
+ 0x58, 0x33, 0x58, 0xCF,
+ 0x69, 0x3B, 0x69, 0xCF,
-0x78, 0xFF, 0x20, 0xEA,
-0x57, 0xC0, 0xBF, 0xEA,
+ 0x78, 0xFF, 0x20, 0xEA,
+ 0x57, 0xC0, 0xBF, 0xEA,
-0x00, 0x80, 0xA0, 0xE9,
-0x00, 0x00, 0xD8, 0xEC,
+ 0x00, 0x80, 0xA0, 0xE9,
+ 0x00, 0x00, 0xD8, 0xEC,
};
static unsigned char warp_g400_t2gzs[] = {
-0x00, 0x8A, 0x98, 0xE9,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x8A, 0x98, 0xE9,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0xA0, 0xE9,
-0x00, 0x00, 0xD8, 0xEC,
+ 0x00, 0x80, 0xA0, 0xE9,
+ 0x00, 0x00, 0xD8, 0xEC,
-0xFF, 0x80, 0xC0, 0xE9,
-0x00, 0x80, 0x00, 0xE8,
+ 0xFF, 0x80, 0xC0, 0xE9,
+ 0x00, 0x80, 0x00, 0xE8,
-0x0A, 0x40, 0x50, 0xBF,
-0x2A, 0x40, 0x60, 0xBF,
+ 0x0A, 0x40, 0x50, 0xBF,
+ 0x2A, 0x40, 0x60, 0xBF,
-0x32, 0x41, 0x51, 0xBF,
-0x3A, 0x41, 0x61, 0xBF,
+ 0x32, 0x41, 0x51, 0xBF,
+ 0x3A, 0x41, 0x61, 0xBF,
-0xC3, 0x6B,
-0xD3, 0x6B,
-0x00, 0x8A, 0x98, 0xE9,
+ 0xC3, 0x6B,
+ 0xD3, 0x6B,
+ 0x00, 0x8A, 0x98, 0xE9,
-0x73, 0x7B, 0xC8, 0xEC,
-0x96, 0xE2,
-0x41, 0x04,
+ 0x73, 0x7B, 0xC8, 0xEC,
+ 0x96, 0xE2,
+ 0x41, 0x04,
-0x7B, 0x43, 0xA0, 0xE8,
-0x73, 0x53, 0xA0, 0xE8,
+ 0x7B, 0x43, 0xA0, 0xE8,
+ 0x73, 0x53, 0xA0, 0xE8,
-0xAD, 0xEE, 0x23, 0x9F,
-0x00, 0xE0,
-0x51, 0x04,
+ 0xAD, 0xEE, 0x23, 0x9F,
+ 0x00, 0xE0,
+ 0x51, 0x04,
-0x90, 0xE2,
-0x61, 0x04,
-0x31, 0x46, 0xB1, 0xE8,
+ 0x90, 0xE2,
+ 0x61, 0x04,
+ 0x31, 0x46, 0xB1, 0xE8,
-0x51, 0x41, 0xE0, 0xEC,
-0x39, 0x67, 0xB1, 0xE8,
+ 0x51, 0x41, 0xE0, 0xEC,
+ 0x39, 0x67, 0xB1, 0xE8,
-0x00, 0x04,
-0x46, 0xE2,
-0x73, 0x63, 0xA0, 0xE8,
+ 0x00, 0x04,
+ 0x46, 0xE2,
+ 0x73, 0x63, 0xA0, 0xE8,
-0x61, 0x41, 0xE0, 0xEC,
-0x31, 0x00,
-0x39, 0x00,
+ 0x61, 0x41, 0xE0, 0xEC,
+ 0x31, 0x00,
+ 0x39, 0x00,
-0x85, 0x80, 0x15, 0xEA,
-0x10, 0x04,
-0x20, 0x04,
+ 0x85, 0x80, 0x15, 0xEA,
+ 0x10, 0x04,
+ 0x20, 0x04,
-0x61, 0x51, 0xE0, 0xEC,
-0x2F, 0x41, 0x60, 0xEA,
+ 0x61, 0x51, 0xE0, 0xEC,
+ 0x2F, 0x41, 0x60, 0xEA,
-0x31, 0x20,
-0x39, 0x20,
-0x1F, 0x42, 0xA0, 0xE8,
+ 0x31, 0x20,
+ 0x39, 0x20,
+ 0x1F, 0x42, 0xA0, 0xE8,
-0x2A, 0x42, 0x52, 0xBF,
-0x0F, 0x52, 0xA0, 0xE8,
+ 0x2A, 0x42, 0x52, 0xBF,
+ 0x0F, 0x52, 0xA0, 0xE8,
-0x1A, 0x42, 0x62, 0xBF,
-0x1E, 0x51, 0x60, 0xEA,
+ 0x1A, 0x42, 0x62, 0xBF,
+ 0x1E, 0x51, 0x60, 0xEA,
-0x73, 0x7B, 0xC8, 0xEC,
-0x0E, 0x61, 0x60, 0xEA,
+ 0x73, 0x7B, 0xC8, 0xEC,
+ 0x0E, 0x61, 0x60, 0xEA,
-0x32, 0x40, 0x50, 0xBD,
-0x22, 0x40, 0x60, 0xBD,
+ 0x32, 0x40, 0x50, 0xBD,
+ 0x22, 0x40, 0x60, 0xBD,
-0x12, 0x41, 0x51, 0xBD,
-0x3A, 0x41, 0x61, 0xBD,
+ 0x12, 0x41, 0x51, 0xBD,
+ 0x3A, 0x41, 0x61, 0xBD,
-0xBF, 0x2F, 0x0E, 0xBD,
-0x97, 0xE2,
-0x7B, 0x72,
+ 0xBF, 0x2F, 0x0E, 0xBD,
+ 0x97, 0xE2,
+ 0x7B, 0x72,
-0x32, 0x20,
-0x22, 0x20,
-0x12, 0x20,
-0x3A, 0x20,
+ 0x32, 0x20,
+ 0x22, 0x20,
+ 0x12, 0x20,
+ 0x3A, 0x20,
-0x35, 0x48, 0xB1, 0xE8,
-0x3D, 0x59, 0xB1, 0xE8,
+ 0x35, 0x48, 0xB1, 0xE8,
+ 0x3D, 0x59, 0xB1, 0xE8,
-0x46, 0x31, 0x46, 0xBF,
-0x56, 0x31, 0x56, 0xBF,
+ 0x46, 0x31, 0x46, 0xBF,
+ 0x56, 0x31, 0x56, 0xBF,
-0xB3, 0xE2, 0x2D, 0x9F,
-0x00, 0x80, 0x00, 0xE8,
+ 0xB3, 0xE2, 0x2D, 0x9F,
+ 0x00, 0x80, 0x00, 0xE8,
-0x66, 0x31, 0x66, 0xBF,
-0x47, 0x39, 0x47, 0xBF,
+ 0x66, 0x31, 0x66, 0xBF,
+ 0x47, 0x39, 0x47, 0xBF,
-0x57, 0x39, 0x57, 0xBF,
-0x67, 0x39, 0x67, 0xBF,
+ 0x57, 0x39, 0x57, 0xBF,
+ 0x67, 0x39, 0x67, 0xBF,
-0x76, 0x80, 0x07, 0xEA,
-0x24, 0x41, 0x20, 0xE9,
+ 0x76, 0x80, 0x07, 0xEA,
+ 0x24, 0x41, 0x20, 0xE9,
-0x35, 0x00,
-0x3D, 0x00,
-0x00, 0xE0,
-0x2D, 0x73,
+ 0x35, 0x00,
+ 0x3D, 0x00,
+ 0x00, 0xE0,
+ 0x2D, 0x73,
-0x33, 0x72,
-0x0C, 0xE3,
-0x8D, 0x2F, 0x1E, 0xBD,
+ 0x33, 0x72,
+ 0x0C, 0xE3,
+ 0x8D, 0x2F, 0x1E, 0xBD,
-0x43, 0x75, 0xF8, 0xEC,
-0x35, 0x20,
-0x3D, 0x20,
+ 0x43, 0x75, 0xF8, 0xEC,
+ 0x35, 0x20,
+ 0x3D, 0x20,
-0x43, 0x43, 0x2D, 0xDF,
-0x53, 0x53, 0x2D, 0xDF,
+ 0x43, 0x43, 0x2D, 0xDF,
+ 0x53, 0x53, 0x2D, 0xDF,
-0xAE, 0x1E, 0x0E, 0xBD,
-0x58, 0xE3,
-0x33, 0x66,
+ 0xAE, 0x1E, 0x0E, 0xBD,
+ 0x58, 0xE3,
+ 0x33, 0x66,
-0x48, 0x35, 0x48, 0xBF,
-0x58, 0x35, 0x58, 0xBF,
+ 0x48, 0x35, 0x48, 0xBF,
+ 0x58, 0x35, 0x58, 0xBF,
-0x68, 0x35, 0x68, 0xBF,
-0x49, 0x3D, 0x49, 0xBF,
+ 0x68, 0x35, 0x68, 0xBF,
+ 0x49, 0x3D, 0x49, 0xBF,
-0x59, 0x3D, 0x59, 0xBF,
-0x69, 0x3D, 0x69, 0xBF,
+ 0x59, 0x3D, 0x59, 0xBF,
+ 0x69, 0x3D, 0x69, 0xBF,
-0x63, 0x63, 0x2D, 0xDF,
-0x4D, 0x7D, 0xF8, 0xEC,
+ 0x63, 0x63, 0x2D, 0xDF,
+ 0x4D, 0x7D, 0xF8, 0xEC,
-0x59, 0xE3,
-0x00, 0xE0,
-0xB8, 0x38, 0x33, 0xBF,
+ 0x59, 0xE3,
+ 0x00, 0xE0,
+ 0xB8, 0x38, 0x33, 0xBF,
-0x2D, 0x73,
-0x30, 0x76,
-0x18, 0x3A, 0x41, 0xE9,
+ 0x2D, 0x73,
+ 0x30, 0x76,
+ 0x18, 0x3A, 0x41, 0xE9,
-0x3F, 0x53, 0xA0, 0xE8,
-0x05, 0x80, 0x3D, 0xEA,
+ 0x3F, 0x53, 0xA0, 0xE8,
+ 0x05, 0x80, 0x3D, 0xEA,
-0x37, 0x43, 0xA0, 0xE8,
-0x3D, 0x63, 0xA0, 0xE8,
+ 0x37, 0x43, 0xA0, 0xE8,
+ 0x3D, 0x63, 0xA0, 0xE8,
-0x50, 0x70, 0xF8, 0xEC,
-0x2B, 0x50, 0x3C, 0xE9,
+ 0x50, 0x70, 0xF8, 0xEC,
+ 0x2B, 0x50, 0x3C, 0xE9,
-0x1F, 0x0F, 0xBC, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x1F, 0x0F, 0xBC, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x59, 0x78, 0xF8, 0xEC,
-0x00, 0x80, 0x00, 0xE8,
+ 0x59, 0x78, 0xF8, 0xEC,
+ 0x00, 0x80, 0x00, 0xE8,
-0x15, 0xC0, 0x20, 0xE9,
-0x15, 0xC0, 0x20, 0xE9,
+ 0x15, 0xC0, 0x20, 0xE9,
+ 0x15, 0xC0, 0x20, 0xE9,
-0x15, 0xC0, 0x20, 0xE9,
-0x15, 0xC0, 0x20, 0xE9,
+ 0x15, 0xC0, 0x20, 0xE9,
+ 0x15, 0xC0, 0x20, 0xE9,
-0x1E, 0x12, 0x41, 0xE9,
-0x1A, 0x22, 0x41, 0xE9,
+ 0x1E, 0x12, 0x41, 0xE9,
+ 0x1A, 0x22, 0x41, 0xE9,
-0x46, 0x37, 0x46, 0xDF,
-0x56, 0x3F, 0x56, 0xDF,
+ 0x46, 0x37, 0x46, 0xDF,
+ 0x56, 0x3F, 0x56, 0xDF,
-0x2B, 0x40, 0x3D, 0xE9,
-0x66, 0x3D, 0x66, 0xDF,
+ 0x2B, 0x40, 0x3D, 0xE9,
+ 0x66, 0x3D, 0x66, 0xDF,
-0x1D, 0x32, 0x41, 0xE9,
-0x67, 0x3D, 0x67, 0xDF,
+ 0x1D, 0x32, 0x41, 0xE9,
+ 0x67, 0x3D, 0x67, 0xDF,
-0x47, 0x37, 0x47, 0xDF,
-0x57, 0x3F, 0x57, 0xDF,
+ 0x47, 0x37, 0x47, 0xDF,
+ 0x57, 0x3F, 0x57, 0xDF,
-0x2A, 0x40, 0x20, 0xE9,
-0x59, 0x3F, 0x59, 0xDF,
+ 0x2A, 0x40, 0x20, 0xE9,
+ 0x59, 0x3F, 0x59, 0xDF,
-0x16, 0x30, 0x20, 0xE9,
-0x69, 0x3D, 0x69, 0xDF,
+ 0x16, 0x30, 0x20, 0xE9,
+ 0x69, 0x3D, 0x69, 0xDF,
-0x48, 0x37, 0x48, 0xDF,
-0x58, 0x3F, 0x58, 0xDF,
+ 0x48, 0x37, 0x48, 0xDF,
+ 0x58, 0x3F, 0x58, 0xDF,
-0x68, 0x3D, 0x68, 0xDF,
-0x49, 0x37, 0x49, 0xDF,
+ 0x68, 0x3D, 0x68, 0xDF,
+ 0x49, 0x37, 0x49, 0xDF,
-0x32, 0x32, 0x2D, 0xDF,
-0x22, 0x22, 0x2D, 0xDF,
+ 0x32, 0x32, 0x2D, 0xDF,
+ 0x22, 0x22, 0x2D, 0xDF,
-0x12, 0x12, 0x2D, 0xDF,
-0x3A, 0x3A, 0x2D, 0xDF,
+ 0x12, 0x12, 0x2D, 0xDF,
+ 0x3A, 0x3A, 0x2D, 0xDF,
-0x0F, 0xCF, 0x74, 0xC2,
-0x37, 0xCF, 0x74, 0xC4,
+ 0x0F, 0xCF, 0x74, 0xC2,
+ 0x37, 0xCF, 0x74, 0xC4,
-0x0A, 0x44, 0x54, 0xB0,
-0x02, 0x44, 0x64, 0xB0,
+ 0x0A, 0x44, 0x54, 0xB0,
+ 0x02, 0x44, 0x64, 0xB0,
-0x3D, 0xCF, 0x74, 0xC0,
-0x34, 0x37, 0x20, 0xE9,
+ 0x3D, 0xCF, 0x74, 0xC0,
+ 0x34, 0x37, 0x20, 0xE9,
-0x31, 0x53, 0x2F, 0x9F,
-0x38, 0x0F, 0x20, 0xE9,
+ 0x31, 0x53, 0x2F, 0x9F,
+ 0x38, 0x0F, 0x20, 0xE9,
-0x39, 0xE5, 0x2C, 0x9F,
-0x3C, 0x3D, 0x20, 0xE9,
+ 0x39, 0xE5, 0x2C, 0x9F,
+ 0x3C, 0x3D, 0x20, 0xE9,
-0x2A, 0x44, 0x54, 0xB2,
-0x1A, 0x44, 0x64, 0xB2,
+ 0x2A, 0x44, 0x54, 0xB2,
+ 0x1A, 0x44, 0x64, 0xB2,
-0x31, 0x80, 0x3A, 0xEA,
-0x0A, 0x20,
-0x02, 0x20,
+ 0x31, 0x80, 0x3A, 0xEA,
+ 0x0A, 0x20,
+ 0x02, 0x20,
-0x0F, 0xCF, 0x75, 0xC0,
-0x2A, 0x20,
-0x1A, 0x20,
+ 0x0F, 0xCF, 0x75, 0xC0,
+ 0x2A, 0x20,
+ 0x1A, 0x20,
-0x30, 0x50, 0x2E, 0x9F,
-0x32, 0x31, 0x5F, 0xE9,
+ 0x30, 0x50, 0x2E, 0x9F,
+ 0x32, 0x31, 0x5F, 0xE9,
-0x38, 0x21, 0x2C, 0x9F,
-0x33, 0x39, 0x5F, 0xE9,
+ 0x38, 0x21, 0x2C, 0x9F,
+ 0x33, 0x39, 0x5F, 0xE9,
-0x3D, 0xCF, 0x75, 0xC2,
-0x37, 0xCF, 0x75, 0xC4,
+ 0x3D, 0xCF, 0x75, 0xC2,
+ 0x37, 0xCF, 0x75, 0xC4,
-0x31, 0x53, 0x2F, 0x9F,
-0xA6, 0x0F, 0x20, 0xE9,
+ 0x31, 0x53, 0x2F, 0x9F,
+ 0xA6, 0x0F, 0x20, 0xE9,
-0x39, 0xE5, 0x2C, 0x9F,
-0xA3, 0x3D, 0x20, 0xE9,
+ 0x39, 0xE5, 0x2C, 0x9F,
+ 0xA3, 0x3D, 0x20, 0xE9,
-0x2A, 0x44, 0x54, 0xB4,
-0x1A, 0x44, 0x64, 0xB4,
+ 0x2A, 0x44, 0x54, 0xB4,
+ 0x1A, 0x44, 0x64, 0xB4,
-0x0A, 0x45, 0x55, 0xB0,
-0x02, 0x45, 0x65, 0xB0,
+ 0x0A, 0x45, 0x55, 0xB0,
+ 0x02, 0x45, 0x65, 0xB0,
-0x88, 0x73, 0x5E, 0xE9,
-0x2A, 0x20,
-0x1A, 0x20,
+ 0x88, 0x73, 0x5E, 0xE9,
+ 0x2A, 0x20,
+ 0x1A, 0x20,
-0xA0, 0x37, 0x20, 0xE9,
-0x0A, 0x20,
-0x02, 0x20,
+ 0xA0, 0x37, 0x20, 0xE9,
+ 0x0A, 0x20,
+ 0x02, 0x20,
-0x31, 0x53, 0x2F, 0x9F,
-0x3E, 0x30, 0x4F, 0xE9,
+ 0x31, 0x53, 0x2F, 0x9F,
+ 0x3E, 0x30, 0x4F, 0xE9,
-0x39, 0xE5, 0x2C, 0x9F,
-0x3F, 0x38, 0x4F, 0xE9,
+ 0x39, 0xE5, 0x2C, 0x9F,
+ 0x3F, 0x38, 0x4F, 0xE9,
-0x30, 0x50, 0x2E, 0x9F,
-0x3A, 0x31, 0x4F, 0xE9,
+ 0x30, 0x50, 0x2E, 0x9F,
+ 0x3A, 0x31, 0x4F, 0xE9,
-0x2A, 0x45, 0x55, 0xB2,
-0x1A, 0x45, 0x65, 0xB2,
+ 0x2A, 0x45, 0x55, 0xB2,
+ 0x1A, 0x45, 0x65, 0xB2,
-0x0A, 0x45, 0x55, 0xB4,
-0x02, 0x45, 0x65, 0xB4,
+ 0x0A, 0x45, 0x55, 0xB4,
+ 0x02, 0x45, 0x65, 0xB4,
-0x38, 0x21, 0x2C, 0x9F,
-0x3B, 0x39, 0x4F, 0xE9,
+ 0x38, 0x21, 0x2C, 0x9F,
+ 0x3B, 0x39, 0x4F, 0xE9,
-0x2A, 0x20,
-0x1A, 0x20,
-0x0A, 0x20,
-0x02, 0x20,
+ 0x2A, 0x20,
+ 0x1A, 0x20,
+ 0x0A, 0x20,
+ 0x02, 0x20,
-0x2A, 0x46, 0x56, 0xBF,
-0x1A, 0x46, 0x66, 0xBF,
+ 0x2A, 0x46, 0x56, 0xBF,
+ 0x1A, 0x46, 0x66, 0xBF,
-0x31, 0x53, 0x2F, 0x9F,
-0x36, 0x31, 0x4F, 0xE9,
+ 0x31, 0x53, 0x2F, 0x9F,
+ 0x36, 0x31, 0x4F, 0xE9,
-0x39, 0xE5, 0x2C, 0x9F,
-0x37, 0x39, 0x4F, 0xE9,
+ 0x39, 0xE5, 0x2C, 0x9F,
+ 0x37, 0x39, 0x4F, 0xE9,
-0x30, 0x50, 0x2E, 0x9F,
-0xA7, 0x30, 0x4F, 0xE9,
+ 0x30, 0x50, 0x2E, 0x9F,
+ 0xA7, 0x30, 0x4F, 0xE9,
-0x38, 0x21, 0x2C, 0x9F,
-0xA8, 0x38, 0x4F, 0xE9,
+ 0x38, 0x21, 0x2C, 0x9F,
+ 0xA8, 0x38, 0x4F, 0xE9,
-0x0A, 0x47, 0x57, 0xBF,
-0x02, 0x47, 0x67, 0xBF,
+ 0x0A, 0x47, 0x57, 0xBF,
+ 0x02, 0x47, 0x67, 0xBF,
-0x31, 0x53, 0x2F, 0x9F,
-0xA4, 0x31, 0x4F, 0xE9,
+ 0x31, 0x53, 0x2F, 0x9F,
+ 0xA4, 0x31, 0x4F, 0xE9,
-0x39, 0xE5, 0x2C, 0x9F,
-0xA5, 0x39, 0x4F, 0xE9,
+ 0x39, 0xE5, 0x2C, 0x9F,
+ 0xA5, 0x39, 0x4F, 0xE9,
-0x2A, 0x43, 0x53, 0xBF,
-0x1A, 0x43, 0x63, 0xBF,
+ 0x2A, 0x43, 0x53, 0xBF,
+ 0x1A, 0x43, 0x63, 0xBF,
-0x30, 0x50, 0x2E, 0x9F,
-0xA1, 0x30, 0x4F, 0xE9,
+ 0x30, 0x50, 0x2E, 0x9F,
+ 0xA1, 0x30, 0x4F, 0xE9,
-0x38, 0x21, 0x2C, 0x9F,
-0xA2, 0x38, 0x4F, 0xE9,
+ 0x38, 0x21, 0x2C, 0x9F,
+ 0xA2, 0x38, 0x4F, 0xE9,
-0x0A, 0x48, 0x58, 0xBF,
-0x02, 0x48, 0x68, 0xBF,
+ 0x0A, 0x48, 0x58, 0xBF,
+ 0x02, 0x48, 0x68, 0xBF,
-0x31, 0x53, 0x2F, 0x9F,
-0x80, 0x31, 0x57, 0xE9,
+ 0x31, 0x53, 0x2F, 0x9F,
+ 0x80, 0x31, 0x57, 0xE9,
-0x39, 0xE5, 0x2C, 0x9F,
-0x81, 0x39, 0x57, 0xE9,
+ 0x39, 0xE5, 0x2C, 0x9F,
+ 0x81, 0x39, 0x57, 0xE9,
-0x2A, 0x49, 0x59, 0xBF,
-0x1A, 0x49, 0x69, 0xBF,
+ 0x2A, 0x49, 0x59, 0xBF,
+ 0x1A, 0x49, 0x69, 0xBF,
-0x30, 0x50, 0x2E, 0x9F,
-0x82, 0x30, 0x57, 0xE9,
+ 0x30, 0x50, 0x2E, 0x9F,
+ 0x82, 0x30, 0x57, 0xE9,
-0x38, 0x21, 0x2C, 0x9F,
-0x83, 0x38, 0x57, 0xE9,
+ 0x38, 0x21, 0x2C, 0x9F,
+ 0x83, 0x38, 0x57, 0xE9,
-0x31, 0x53, 0x2F, 0x9F,
-0x84, 0x31, 0x5E, 0xE9,
+ 0x31, 0x53, 0x2F, 0x9F,
+ 0x84, 0x31, 0x5E, 0xE9,
-0x39, 0xE5, 0x2C, 0x9F,
-0x85, 0x39, 0x5E, 0xE9,
+ 0x39, 0xE5, 0x2C, 0x9F,
+ 0x85, 0x39, 0x5E, 0xE9,
-0x86, 0x76, 0x57, 0xE9,
-0x8A, 0x36, 0x20, 0xE9,
+ 0x86, 0x76, 0x57, 0xE9,
+ 0x8A, 0x36, 0x20, 0xE9,
-0x87, 0x77, 0x57, 0xE9,
-0x8B, 0x3E, 0xBF, 0xEA,
+ 0x87, 0x77, 0x57, 0xE9,
+ 0x8B, 0x3E, 0xBF, 0xEA,
-0x80, 0x30, 0x57, 0xE9,
-0x81, 0x38, 0x57, 0xE9,
+ 0x80, 0x30, 0x57, 0xE9,
+ 0x81, 0x38, 0x57, 0xE9,
-0x82, 0x31, 0x57, 0xE9,
-0x86, 0x78, 0x57, 0xE9,
+ 0x82, 0x31, 0x57, 0xE9,
+ 0x86, 0x78, 0x57, 0xE9,
-0x83, 0x39, 0x57, 0xE9,
-0x87, 0x79, 0x57, 0xE9,
+ 0x83, 0x39, 0x57, 0xE9,
+ 0x87, 0x79, 0x57, 0xE9,
-0x30, 0x1F, 0x5F, 0xE9,
-0x8A, 0x34, 0x20, 0xE9,
+ 0x30, 0x1F, 0x5F, 0xE9,
+ 0x8A, 0x34, 0x20, 0xE9,
-0x8B, 0x3C, 0x20, 0xE9,
-0x37, 0x50, 0x60, 0xBD,
+ 0x8B, 0x3C, 0x20, 0xE9,
+ 0x37, 0x50, 0x60, 0xBD,
-0x57, 0x0D, 0x20, 0xE9,
-0x35, 0x51, 0x61, 0xBD,
+ 0x57, 0x0D, 0x20, 0xE9,
+ 0x35, 0x51, 0x61, 0xBD,
-0x2B, 0x50, 0x20, 0xE9,
-0x1D, 0x37, 0xE1, 0xEA,
+ 0x2B, 0x50, 0x20, 0xE9,
+ 0x1D, 0x37, 0xE1, 0xEA,
-0x1E, 0x35, 0xE1, 0xEA,
-0x00, 0xE0,
-0x0E, 0x77,
+ 0x1E, 0x35, 0xE1, 0xEA,
+ 0x00, 0xE0,
+ 0x0E, 0x77,
-0x24, 0x51, 0x20, 0xE9,
-0x92, 0xFF, 0x20, 0xEA,
+ 0x24, 0x51, 0x20, 0xE9,
+ 0x92, 0xFF, 0x20, 0xEA,
-0x16, 0x0E, 0x20, 0xE9,
-0x57, 0x2E, 0xBF, 0xEA,
+ 0x16, 0x0E, 0x20, 0xE9,
+ 0x57, 0x2E, 0xBF, 0xEA,
-0x0B, 0x46, 0xA0, 0xE8,
-0x1B, 0x56, 0xA0, 0xE8,
+ 0x0B, 0x46, 0xA0, 0xE8,
+ 0x1B, 0x56, 0xA0, 0xE8,
-0x2B, 0x66, 0xA0, 0xE8,
-0x0C, 0x47, 0xA0, 0xE8,
+ 0x2B, 0x66, 0xA0, 0xE8,
+ 0x0C, 0x47, 0xA0, 0xE8,
-0x1C, 0x57, 0xA0, 0xE8,
-0x2C, 0x67, 0xA0, 0xE8,
+ 0x1C, 0x57, 0xA0, 0xE8,
+ 0x2C, 0x67, 0xA0, 0xE8,
-0x0B, 0x00,
-0x1B, 0x00,
-0x2B, 0x00,
-0x00, 0xE0,
+ 0x0B, 0x00,
+ 0x1B, 0x00,
+ 0x2B, 0x00,
+ 0x00, 0xE0,
-0x0C, 0x00,
-0x1C, 0x00,
-0x2C, 0x00,
-0x00, 0xE0,
+ 0x0C, 0x00,
+ 0x1C, 0x00,
+ 0x2C, 0x00,
+ 0x00, 0xE0,
-0x0B, 0x65,
-0x1B, 0x65,
-0x2B, 0x65,
-0x00, 0xE0,
+ 0x0B, 0x65,
+ 0x1B, 0x65,
+ 0x2B, 0x65,
+ 0x00, 0xE0,
-0x0C, 0x65,
-0x1C, 0x65,
-0x2C, 0x65,
-0x00, 0xE0,
+ 0x0C, 0x65,
+ 0x1C, 0x65,
+ 0x2C, 0x65,
+ 0x00, 0xE0,
-0x0B, 0x1B, 0x60, 0xEC,
-0x36, 0xD7, 0x36, 0xAD,
+ 0x0B, 0x1B, 0x60, 0xEC,
+ 0x36, 0xD7, 0x36, 0xAD,
-0x2B, 0x80, 0x60, 0xEC,
-0x0C, 0x1C, 0x60, 0xEC,
+ 0x2B, 0x80, 0x60, 0xEC,
+ 0x0C, 0x1C, 0x60, 0xEC,
-0x3E, 0xD7, 0x3E, 0xAD,
-0x2C, 0x80, 0x60, 0xEC,
+ 0x3E, 0xD7, 0x3E, 0xAD,
+ 0x2C, 0x80, 0x60, 0xEC,
-0x0B, 0x2B, 0xDE, 0xE8,
-0x1B, 0x80, 0xDE, 0xE8,
+ 0x0B, 0x2B, 0xDE, 0xE8,
+ 0x1B, 0x80, 0xDE, 0xE8,
-0x36, 0x80, 0x36, 0xBD,
-0x3E, 0x80, 0x3E, 0xBD,
+ 0x36, 0x80, 0x36, 0xBD,
+ 0x3E, 0x80, 0x3E, 0xBD,
-0x33, 0xD7, 0x0B, 0xBD,
-0x3B, 0xD7, 0x1B, 0xBD,
+ 0x33, 0xD7, 0x0B, 0xBD,
+ 0x3B, 0xD7, 0x1B, 0xBD,
-0x46, 0x80, 0x46, 0xCF,
-0x57, 0x80, 0x57, 0xCF,
+ 0x46, 0x80, 0x46, 0xCF,
+ 0x57, 0x80, 0x57, 0xCF,
-0x66, 0x33, 0x66, 0xCF,
-0x47, 0x3B, 0x47, 0xCF,
+ 0x66, 0x33, 0x66, 0xCF,
+ 0x47, 0x3B, 0x47, 0xCF,
-0x56, 0x33, 0x56, 0xCF,
-0x67, 0x3B, 0x67, 0xCF,
+ 0x56, 0x33, 0x56, 0xCF,
+ 0x67, 0x3B, 0x67, 0xCF,
-0x0B, 0x48, 0xA0, 0xE8,
-0x1B, 0x58, 0xA0, 0xE8,
+ 0x0B, 0x48, 0xA0, 0xE8,
+ 0x1B, 0x58, 0xA0, 0xE8,
-0x2B, 0x68, 0xA0, 0xE8,
-0x0C, 0x49, 0xA0, 0xE8,
+ 0x2B, 0x68, 0xA0, 0xE8,
+ 0x0C, 0x49, 0xA0, 0xE8,
-0x1C, 0x59, 0xA0, 0xE8,
-0x2C, 0x69, 0xA0, 0xE8,
+ 0x1C, 0x59, 0xA0, 0xE8,
+ 0x2C, 0x69, 0xA0, 0xE8,
-0x0B, 0x00,
-0x1B, 0x00,
-0x2B, 0x00,
-0x00, 0xE0,
+ 0x0B, 0x00,
+ 0x1B, 0x00,
+ 0x2B, 0x00,
+ 0x00, 0xE0,
-0x0C, 0x00,
-0x1C, 0x00,
-0x2C, 0x00,
-0x00, 0xE0,
+ 0x0C, 0x00,
+ 0x1C, 0x00,
+ 0x2C, 0x00,
+ 0x00, 0xE0,
-0x0B, 0x65,
-0x1B, 0x65,
-0x2B, 0x65,
-0x00, 0xE0,
+ 0x0B, 0x65,
+ 0x1B, 0x65,
+ 0x2B, 0x65,
+ 0x00, 0xE0,
-0x0C, 0x65,
-0x1C, 0x65,
-0x2C, 0x65,
-0x00, 0xE0,
+ 0x0C, 0x65,
+ 0x1C, 0x65,
+ 0x2C, 0x65,
+ 0x00, 0xE0,
-0x0B, 0x1B, 0x60, 0xEC,
-0x34, 0xD7, 0x34, 0xAD,
+ 0x0B, 0x1B, 0x60, 0xEC,
+ 0x34, 0xD7, 0x34, 0xAD,
-0x2B, 0x80, 0x60, 0xEC,
-0x0C, 0x1C, 0x60, 0xEC,
+ 0x2B, 0x80, 0x60, 0xEC,
+ 0x0C, 0x1C, 0x60, 0xEC,
-0x3C, 0xD7, 0x3C, 0xAD,
-0x2C, 0x80, 0x60, 0xEC,
+ 0x3C, 0xD7, 0x3C, 0xAD,
+ 0x2C, 0x80, 0x60, 0xEC,
-0x0B, 0x2B, 0xDE, 0xE8,
-0x1B, 0x80, 0xDE, 0xE8,
+ 0x0B, 0x2B, 0xDE, 0xE8,
+ 0x1B, 0x80, 0xDE, 0xE8,
-0x34, 0x80, 0x34, 0xBD,
-0x3C, 0x80, 0x3C, 0xBD,
+ 0x34, 0x80, 0x34, 0xBD,
+ 0x3C, 0x80, 0x3C, 0xBD,
-0x33, 0xD7, 0x0B, 0xBD,
-0x3B, 0xD7, 0x1B, 0xBD,
+ 0x33, 0xD7, 0x0B, 0xBD,
+ 0x3B, 0xD7, 0x1B, 0xBD,
-0x48, 0x80, 0x48, 0xCF,
-0x59, 0x80, 0x59, 0xCF,
+ 0x48, 0x80, 0x48, 0xCF,
+ 0x59, 0x80, 0x59, 0xCF,
-0x68, 0x33, 0x68, 0xCF,
-0x49, 0x3B, 0x49, 0xCF,
+ 0x68, 0x33, 0x68, 0xCF,
+ 0x49, 0x3B, 0x49, 0xCF,
-0xB2, 0xFF, 0x20, 0xEA,
-0x00, 0x80, 0x00, 0xE8,
+ 0xB2, 0xFF, 0x20, 0xEA,
+ 0x00, 0x80, 0x00, 0xE8,
-0x58, 0x33, 0x58, 0xCF,
-0x69, 0x3B, 0x69, 0xCF,
+ 0x58, 0x33, 0x58, 0xCF,
+ 0x69, 0x3B, 0x69, 0xCF,
-0x70, 0xFF, 0x20, 0xEA,
-0x57, 0xC0, 0xBF, 0xEA,
+ 0x70, 0xFF, 0x20, 0xEA,
+ 0x57, 0xC0, 0xBF, 0xEA,
-0x00, 0x80, 0xA0, 0xE9,
-0x00, 0x00, 0xD8, 0xEC,
+ 0x00, 0x80, 0xA0, 0xE9,
+ 0x00, 0x00, 0xD8, 0xEC,
};
static unsigned char warp_g400_t2gzsa[] = {
-0x00, 0x8A, 0x98, 0xE9,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x8A, 0x98, 0xE9,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0xA0, 0xE9,
-0x00, 0x00, 0xD8, 0xEC,
+ 0x00, 0x80, 0xA0, 0xE9,
+ 0x00, 0x00, 0xD8, 0xEC,
-0xFF, 0x80, 0xC0, 0xE9,
-0x00, 0x80, 0x00, 0xE8,
+ 0xFF, 0x80, 0xC0, 0xE9,
+ 0x00, 0x80, 0x00, 0xE8,
-0x0A, 0x40, 0x50, 0xBF,
-0x2A, 0x40, 0x60, 0xBF,
+ 0x0A, 0x40, 0x50, 0xBF,
+ 0x2A, 0x40, 0x60, 0xBF,
-0x32, 0x41, 0x51, 0xBF,
-0x3A, 0x41, 0x61, 0xBF,
+ 0x32, 0x41, 0x51, 0xBF,
+ 0x3A, 0x41, 0x61, 0xBF,
-0xC3, 0x6B,
-0xD3, 0x6B,
-0x00, 0x8A, 0x98, 0xE9,
+ 0xC3, 0x6B,
+ 0xD3, 0x6B,
+ 0x00, 0x8A, 0x98, 0xE9,
-0x73, 0x7B, 0xC8, 0xEC,
-0x96, 0xE2,
-0x41, 0x04,
+ 0x73, 0x7B, 0xC8, 0xEC,
+ 0x96, 0xE2,
+ 0x41, 0x04,
-0x7B, 0x43, 0xA0, 0xE8,
-0x73, 0x53, 0xA0, 0xE8,
+ 0x7B, 0x43, 0xA0, 0xE8,
+ 0x73, 0x53, 0xA0, 0xE8,
-0xAD, 0xEE, 0x23, 0x9F,
-0x00, 0xE0,
-0x51, 0x04,
+ 0xAD, 0xEE, 0x23, 0x9F,
+ 0x00, 0xE0,
+ 0x51, 0x04,
-0x90, 0xE2,
-0x61, 0x04,
-0x31, 0x46, 0xB1, 0xE8,
+ 0x90, 0xE2,
+ 0x61, 0x04,
+ 0x31, 0x46, 0xB1, 0xE8,
-0x51, 0x41, 0xE0, 0xEC,
-0x39, 0x67, 0xB1, 0xE8,
+ 0x51, 0x41, 0xE0, 0xEC,
+ 0x39, 0x67, 0xB1, 0xE8,
-0x00, 0x04,
-0x46, 0xE2,
-0x73, 0x63, 0xA0, 0xE8,
+ 0x00, 0x04,
+ 0x46, 0xE2,
+ 0x73, 0x63, 0xA0, 0xE8,
-0x61, 0x41, 0xE0, 0xEC,
-0x31, 0x00,
-0x39, 0x00,
+ 0x61, 0x41, 0xE0, 0xEC,
+ 0x31, 0x00,
+ 0x39, 0x00,
-0x8A, 0x80, 0x15, 0xEA,
-0x10, 0x04,
-0x20, 0x04,
+ 0x8A, 0x80, 0x15, 0xEA,
+ 0x10, 0x04,
+ 0x20, 0x04,
-0x61, 0x51, 0xE0, 0xEC,
-0x2F, 0x41, 0x60, 0xEA,
+ 0x61, 0x51, 0xE0, 0xEC,
+ 0x2F, 0x41, 0x60, 0xEA,
-0x31, 0x20,
-0x39, 0x20,
-0x1F, 0x42, 0xA0, 0xE8,
+ 0x31, 0x20,
+ 0x39, 0x20,
+ 0x1F, 0x42, 0xA0, 0xE8,
-0x2A, 0x42, 0x52, 0xBF,
-0x0F, 0x52, 0xA0, 0xE8,
+ 0x2A, 0x42, 0x52, 0xBF,
+ 0x0F, 0x52, 0xA0, 0xE8,
-0x1A, 0x42, 0x62, 0xBF,
-0x1E, 0x51, 0x60, 0xEA,
+ 0x1A, 0x42, 0x62, 0xBF,
+ 0x1E, 0x51, 0x60, 0xEA,
-0x73, 0x7B, 0xC8, 0xEC,
-0x0E, 0x61, 0x60, 0xEA,
+ 0x73, 0x7B, 0xC8, 0xEC,
+ 0x0E, 0x61, 0x60, 0xEA,
-0x32, 0x40, 0x50, 0xBD,
-0x22, 0x40, 0x60, 0xBD,
+ 0x32, 0x40, 0x50, 0xBD,
+ 0x22, 0x40, 0x60, 0xBD,
-0x12, 0x41, 0x51, 0xBD,
-0x3A, 0x41, 0x61, 0xBD,
+ 0x12, 0x41, 0x51, 0xBD,
+ 0x3A, 0x41, 0x61, 0xBD,
-0xBF, 0x2F, 0x0E, 0xBD,
-0x97, 0xE2,
-0x7B, 0x72,
+ 0xBF, 0x2F, 0x0E, 0xBD,
+ 0x97, 0xE2,
+ 0x7B, 0x72,
-0x32, 0x20,
-0x22, 0x20,
-0x12, 0x20,
-0x3A, 0x20,
+ 0x32, 0x20,
+ 0x22, 0x20,
+ 0x12, 0x20,
+ 0x3A, 0x20,
-0x35, 0x48, 0xB1, 0xE8,
-0x3D, 0x59, 0xB1, 0xE8,
+ 0x35, 0x48, 0xB1, 0xE8,
+ 0x3D, 0x59, 0xB1, 0xE8,
-0x46, 0x31, 0x46, 0xBF,
-0x56, 0x31, 0x56, 0xBF,
+ 0x46, 0x31, 0x46, 0xBF,
+ 0x56, 0x31, 0x56, 0xBF,
-0xB3, 0xE2, 0x2D, 0x9F,
-0x00, 0x80, 0x00, 0xE8,
+ 0xB3, 0xE2, 0x2D, 0x9F,
+ 0x00, 0x80, 0x00, 0xE8,
-0x66, 0x31, 0x66, 0xBF,
-0x47, 0x39, 0x47, 0xBF,
+ 0x66, 0x31, 0x66, 0xBF,
+ 0x47, 0x39, 0x47, 0xBF,
-0x57, 0x39, 0x57, 0xBF,
-0x67, 0x39, 0x67, 0xBF,
+ 0x57, 0x39, 0x57, 0xBF,
+ 0x67, 0x39, 0x67, 0xBF,
-0x7B, 0x80, 0x07, 0xEA,
-0x24, 0x41, 0x20, 0xE9,
+ 0x7B, 0x80, 0x07, 0xEA,
+ 0x24, 0x41, 0x20, 0xE9,
-0x35, 0x00,
-0x3D, 0x00,
-0x00, 0xE0,
-0x2D, 0x73,
+ 0x35, 0x00,
+ 0x3D, 0x00,
+ 0x00, 0xE0,
+ 0x2D, 0x73,
-0x33, 0x72,
-0x0C, 0xE3,
-0x8D, 0x2F, 0x1E, 0xBD,
+ 0x33, 0x72,
+ 0x0C, 0xE3,
+ 0x8D, 0x2F, 0x1E, 0xBD,
-0x43, 0x75, 0xF8, 0xEC,
-0x35, 0x20,
-0x3D, 0x20,
+ 0x43, 0x75, 0xF8, 0xEC,
+ 0x35, 0x20,
+ 0x3D, 0x20,
-0x43, 0x43, 0x2D, 0xDF,
-0x53, 0x53, 0x2D, 0xDF,
+ 0x43, 0x43, 0x2D, 0xDF,
+ 0x53, 0x53, 0x2D, 0xDF,
-0xAE, 0x1E, 0x0E, 0xBD,
-0x58, 0xE3,
-0x33, 0x66,
+ 0xAE, 0x1E, 0x0E, 0xBD,
+ 0x58, 0xE3,
+ 0x33, 0x66,
-0x48, 0x35, 0x48, 0xBF,
-0x58, 0x35, 0x58, 0xBF,
+ 0x48, 0x35, 0x48, 0xBF,
+ 0x58, 0x35, 0x58, 0xBF,
-0x68, 0x35, 0x68, 0xBF,
-0x49, 0x3D, 0x49, 0xBF,
+ 0x68, 0x35, 0x68, 0xBF,
+ 0x49, 0x3D, 0x49, 0xBF,
-0x59, 0x3D, 0x59, 0xBF,
-0x69, 0x3D, 0x69, 0xBF,
+ 0x59, 0x3D, 0x59, 0xBF,
+ 0x69, 0x3D, 0x69, 0xBF,
-0x63, 0x63, 0x2D, 0xDF,
-0x4D, 0x7D, 0xF8, 0xEC,
+ 0x63, 0x63, 0x2D, 0xDF,
+ 0x4D, 0x7D, 0xF8, 0xEC,
-0x59, 0xE3,
-0x00, 0xE0,
-0xB8, 0x38, 0x33, 0xBF,
+ 0x59, 0xE3,
+ 0x00, 0xE0,
+ 0xB8, 0x38, 0x33, 0xBF,
-0x2D, 0x73,
-0x30, 0x76,
-0x18, 0x3A, 0x41, 0xE9,
+ 0x2D, 0x73,
+ 0x30, 0x76,
+ 0x18, 0x3A, 0x41, 0xE9,
-0x3F, 0x53, 0xA0, 0xE8,
-0x05, 0x80, 0x3D, 0xEA,
+ 0x3F, 0x53, 0xA0, 0xE8,
+ 0x05, 0x80, 0x3D, 0xEA,
-0x37, 0x43, 0xA0, 0xE8,
-0x3D, 0x63, 0xA0, 0xE8,
+ 0x37, 0x43, 0xA0, 0xE8,
+ 0x3D, 0x63, 0xA0, 0xE8,
-0x50, 0x70, 0xF8, 0xEC,
-0x2B, 0x50, 0x3C, 0xE9,
+ 0x50, 0x70, 0xF8, 0xEC,
+ 0x2B, 0x50, 0x3C, 0xE9,
-0x1F, 0x0F, 0xBC, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x1F, 0x0F, 0xBC, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x59, 0x78, 0xF8, 0xEC,
-0x00, 0x80, 0x00, 0xE8,
+ 0x59, 0x78, 0xF8, 0xEC,
+ 0x00, 0x80, 0x00, 0xE8,
-0x15, 0xC0, 0x20, 0xE9,
-0x15, 0xC0, 0x20, 0xE9,
+ 0x15, 0xC0, 0x20, 0xE9,
+ 0x15, 0xC0, 0x20, 0xE9,
-0x15, 0xC0, 0x20, 0xE9,
-0x15, 0xC0, 0x20, 0xE9,
+ 0x15, 0xC0, 0x20, 0xE9,
+ 0x15, 0xC0, 0x20, 0xE9,
-0x1E, 0x12, 0x41, 0xE9,
-0x1A, 0x22, 0x41, 0xE9,
+ 0x1E, 0x12, 0x41, 0xE9,
+ 0x1A, 0x22, 0x41, 0xE9,
-0x46, 0x37, 0x46, 0xDF,
-0x56, 0x3F, 0x56, 0xDF,
+ 0x46, 0x37, 0x46, 0xDF,
+ 0x56, 0x3F, 0x56, 0xDF,
-0x2B, 0x40, 0x3D, 0xE9,
-0x66, 0x3D, 0x66, 0xDF,
+ 0x2B, 0x40, 0x3D, 0xE9,
+ 0x66, 0x3D, 0x66, 0xDF,
-0x1D, 0x32, 0x41, 0xE9,
-0x67, 0x3D, 0x67, 0xDF,
+ 0x1D, 0x32, 0x41, 0xE9,
+ 0x67, 0x3D, 0x67, 0xDF,
-0x47, 0x37, 0x47, 0xDF,
-0x57, 0x3F, 0x57, 0xDF,
+ 0x47, 0x37, 0x47, 0xDF,
+ 0x57, 0x3F, 0x57, 0xDF,
-0x2A, 0x40, 0x20, 0xE9,
-0x59, 0x3F, 0x59, 0xDF,
+ 0x2A, 0x40, 0x20, 0xE9,
+ 0x59, 0x3F, 0x59, 0xDF,
-0x16, 0x30, 0x20, 0xE9,
-0x69, 0x3D, 0x69, 0xDF,
+ 0x16, 0x30, 0x20, 0xE9,
+ 0x69, 0x3D, 0x69, 0xDF,
-0x48, 0x37, 0x48, 0xDF,
-0x58, 0x3F, 0x58, 0xDF,
+ 0x48, 0x37, 0x48, 0xDF,
+ 0x58, 0x3F, 0x58, 0xDF,
-0x68, 0x3D, 0x68, 0xDF,
-0x49, 0x37, 0x49, 0xDF,
+ 0x68, 0x3D, 0x68, 0xDF,
+ 0x49, 0x37, 0x49, 0xDF,
-0x32, 0x32, 0x2D, 0xDF,
-0x22, 0x22, 0x2D, 0xDF,
+ 0x32, 0x32, 0x2D, 0xDF,
+ 0x22, 0x22, 0x2D, 0xDF,
-0x12, 0x12, 0x2D, 0xDF,
-0x3A, 0x3A, 0x2D, 0xDF,
+ 0x12, 0x12, 0x2D, 0xDF,
+ 0x3A, 0x3A, 0x2D, 0xDF,
-0x0F, 0xCF, 0x74, 0xC2,
-0x37, 0xCF, 0x74, 0xC4,
+ 0x0F, 0xCF, 0x74, 0xC2,
+ 0x37, 0xCF, 0x74, 0xC4,
-0x0A, 0x44, 0x54, 0xB0,
-0x02, 0x44, 0x64, 0xB0,
+ 0x0A, 0x44, 0x54, 0xB0,
+ 0x02, 0x44, 0x64, 0xB0,
-0x3D, 0xCF, 0x74, 0xC0,
-0x34, 0x37, 0x20, 0xE9,
+ 0x3D, 0xCF, 0x74, 0xC0,
+ 0x34, 0x37, 0x20, 0xE9,
-0x31, 0x53, 0x2F, 0x9F,
-0x38, 0x0F, 0x20, 0xE9,
+ 0x31, 0x53, 0x2F, 0x9F,
+ 0x38, 0x0F, 0x20, 0xE9,
-0x39, 0xE5, 0x2C, 0x9F,
-0x3C, 0x3D, 0x20, 0xE9,
+ 0x39, 0xE5, 0x2C, 0x9F,
+ 0x3C, 0x3D, 0x20, 0xE9,
-0x2A, 0x44, 0x54, 0xB2,
-0x1A, 0x44, 0x64, 0xB2,
+ 0x2A, 0x44, 0x54, 0xB2,
+ 0x1A, 0x44, 0x64, 0xB2,
-0x36, 0x80, 0x3A, 0xEA,
-0x0A, 0x20,
-0x02, 0x20,
+ 0x36, 0x80, 0x3A, 0xEA,
+ 0x0A, 0x20,
+ 0x02, 0x20,
-0x0F, 0xCF, 0x75, 0xC0,
-0x2A, 0x20,
-0x1A, 0x20,
+ 0x0F, 0xCF, 0x75, 0xC0,
+ 0x2A, 0x20,
+ 0x1A, 0x20,
-0x30, 0x50, 0x2E, 0x9F,
-0x32, 0x31, 0x5F, 0xE9,
+ 0x30, 0x50, 0x2E, 0x9F,
+ 0x32, 0x31, 0x5F, 0xE9,
-0x38, 0x21, 0x2C, 0x9F,
-0x33, 0x39, 0x5F, 0xE9,
+ 0x38, 0x21, 0x2C, 0x9F,
+ 0x33, 0x39, 0x5F, 0xE9,
-0x3D, 0xCF, 0x75, 0xC2,
-0x37, 0xCF, 0x75, 0xC4,
+ 0x3D, 0xCF, 0x75, 0xC2,
+ 0x37, 0xCF, 0x75, 0xC4,
-0x31, 0x53, 0x2F, 0x9F,
-0xA6, 0x0F, 0x20, 0xE9,
+ 0x31, 0x53, 0x2F, 0x9F,
+ 0xA6, 0x0F, 0x20, 0xE9,
-0x39, 0xE5, 0x2C, 0x9F,
-0xA3, 0x3D, 0x20, 0xE9,
+ 0x39, 0xE5, 0x2C, 0x9F,
+ 0xA3, 0x3D, 0x20, 0xE9,
-0x2A, 0x44, 0x54, 0xB4,
-0x1A, 0x44, 0x64, 0xB4,
+ 0x2A, 0x44, 0x54, 0xB4,
+ 0x1A, 0x44, 0x64, 0xB4,
-0x0A, 0x45, 0x55, 0xB0,
-0x02, 0x45, 0x65, 0xB0,
+ 0x0A, 0x45, 0x55, 0xB0,
+ 0x02, 0x45, 0x65, 0xB0,
-0x88, 0x73, 0x5E, 0xE9,
-0x2A, 0x20,
-0x1A, 0x20,
+ 0x88, 0x73, 0x5E, 0xE9,
+ 0x2A, 0x20,
+ 0x1A, 0x20,
-0xA0, 0x37, 0x20, 0xE9,
-0x0A, 0x20,
-0x02, 0x20,
+ 0xA0, 0x37, 0x20, 0xE9,
+ 0x0A, 0x20,
+ 0x02, 0x20,
-0x31, 0x53, 0x2F, 0x9F,
-0x3E, 0x30, 0x4F, 0xE9,
+ 0x31, 0x53, 0x2F, 0x9F,
+ 0x3E, 0x30, 0x4F, 0xE9,
-0x39, 0xE5, 0x2C, 0x9F,
-0x3F, 0x38, 0x4F, 0xE9,
+ 0x39, 0xE5, 0x2C, 0x9F,
+ 0x3F, 0x38, 0x4F, 0xE9,
-0x30, 0x50, 0x2E, 0x9F,
-0x3A, 0x31, 0x4F, 0xE9,
+ 0x30, 0x50, 0x2E, 0x9F,
+ 0x3A, 0x31, 0x4F, 0xE9,
-0x38, 0x21, 0x2C, 0x9F,
-0x3B, 0x39, 0x4F, 0xE9,
+ 0x38, 0x21, 0x2C, 0x9F,
+ 0x3B, 0x39, 0x4F, 0xE9,
-0x2A, 0x45, 0x55, 0xB2,
-0x1A, 0x45, 0x65, 0xB2,
+ 0x2A, 0x45, 0x55, 0xB2,
+ 0x1A, 0x45, 0x65, 0xB2,
-0x0A, 0x45, 0x55, 0xB4,
-0x02, 0x45, 0x65, 0xB4,
+ 0x0A, 0x45, 0x55, 0xB4,
+ 0x02, 0x45, 0x65, 0xB4,
-0x0F, 0xCF, 0x74, 0xC6,
-0x2A, 0x20,
-0x1A, 0x20,
+ 0x0F, 0xCF, 0x74, 0xC6,
+ 0x2A, 0x20,
+ 0x1A, 0x20,
-0xA7, 0x30, 0x4F, 0xE9,
-0x0A, 0x20,
-0x02, 0x20,
+ 0xA7, 0x30, 0x4F, 0xE9,
+ 0x0A, 0x20,
+ 0x02, 0x20,
-0x31, 0x53, 0x2F, 0x9F,
-0x9C, 0x0F, 0x20, 0xE9,
+ 0x31, 0x53, 0x2F, 0x9F,
+ 0x9C, 0x0F, 0x20, 0xE9,
-0x39, 0xE5, 0x2C, 0x9F,
-0xA8, 0x38, 0x4F, 0xE9,
+ 0x39, 0xE5, 0x2C, 0x9F,
+ 0xA8, 0x38, 0x4F, 0xE9,
-0x2A, 0x44, 0x54, 0xB6,
-0x1A, 0x44, 0x64, 0xB6,
+ 0x2A, 0x44, 0x54, 0xB6,
+ 0x1A, 0x44, 0x64, 0xB6,
-0x30, 0x50, 0x2E, 0x9F,
-0x36, 0x31, 0x4F, 0xE9,
+ 0x30, 0x50, 0x2E, 0x9F,
+ 0x36, 0x31, 0x4F, 0xE9,
-0x38, 0x21, 0x2C, 0x9F,
-0x37, 0x39, 0x4F, 0xE9,
+ 0x38, 0x21, 0x2C, 0x9F,
+ 0x37, 0x39, 0x4F, 0xE9,
-0x00, 0x80, 0x00, 0xE8,
-0x2A, 0x20,
-0x1A, 0x20,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x2A, 0x20,
+ 0x1A, 0x20,
-0x2A, 0x46, 0x56, 0xBF,
-0x1A, 0x46, 0x66, 0xBF,
+ 0x2A, 0x46, 0x56, 0xBF,
+ 0x1A, 0x46, 0x66, 0xBF,
-0x31, 0x53, 0x2F, 0x9F,
-0xA4, 0x31, 0x4F, 0xE9,
+ 0x31, 0x53, 0x2F, 0x9F,
+ 0xA4, 0x31, 0x4F, 0xE9,
-0x39, 0xE5, 0x2C, 0x9F,
-0xA5, 0x39, 0x4F, 0xE9,
+ 0x39, 0xE5, 0x2C, 0x9F,
+ 0xA5, 0x39, 0x4F, 0xE9,
-0x0A, 0x47, 0x57, 0xBF,
-0x02, 0x47, 0x67, 0xBF,
+ 0x0A, 0x47, 0x57, 0xBF,
+ 0x02, 0x47, 0x67, 0xBF,
-0x31, 0x53, 0x2F, 0x9F,
-0xA1, 0x30, 0x4F, 0xE9,
+ 0x31, 0x53, 0x2F, 0x9F,
+ 0xA1, 0x30, 0x4F, 0xE9,
-0x39, 0xE5, 0x2C, 0x9F,
-0xA2, 0x38, 0x4F, 0xE9,
+ 0x39, 0xE5, 0x2C, 0x9F,
+ 0xA2, 0x38, 0x4F, 0xE9,
-0x2A, 0x43, 0x53, 0xBF,
-0x1A, 0x43, 0x63, 0xBF,
+ 0x2A, 0x43, 0x53, 0xBF,
+ 0x1A, 0x43, 0x63, 0xBF,
-0x30, 0x50, 0x2E, 0x9F,
-0x9D, 0x31, 0x4F, 0xE9,
+ 0x30, 0x50, 0x2E, 0x9F,
+ 0x9D, 0x31, 0x4F, 0xE9,
-0x38, 0x21, 0x2C, 0x9F,
-0x9E, 0x39, 0x4F, 0xE9,
+ 0x38, 0x21, 0x2C, 0x9F,
+ 0x9E, 0x39, 0x4F, 0xE9,
-0x0A, 0x48, 0x58, 0xBF,
-0x02, 0x48, 0x68, 0xBF,
+ 0x0A, 0x48, 0x58, 0xBF,
+ 0x02, 0x48, 0x68, 0xBF,
-0x31, 0x53, 0x2F, 0x9F,
-0x80, 0x31, 0x57, 0xE9,
+ 0x31, 0x53, 0x2F, 0x9F,
+ 0x80, 0x31, 0x57, 0xE9,
-0x39, 0xE5, 0x2C, 0x9F,
-0x81, 0x39, 0x57, 0xE9,
+ 0x39, 0xE5, 0x2C, 0x9F,
+ 0x81, 0x39, 0x57, 0xE9,
-0x2A, 0x49, 0x59, 0xBF,
-0x1A, 0x49, 0x69, 0xBF,
+ 0x2A, 0x49, 0x59, 0xBF,
+ 0x1A, 0x49, 0x69, 0xBF,
-0x30, 0x50, 0x2E, 0x9F,
-0x82, 0x30, 0x57, 0xE9,
+ 0x30, 0x50, 0x2E, 0x9F,
+ 0x82, 0x30, 0x57, 0xE9,
-0x38, 0x21, 0x2C, 0x9F,
-0x83, 0x38, 0x57, 0xE9,
+ 0x38, 0x21, 0x2C, 0x9F,
+ 0x83, 0x38, 0x57, 0xE9,
-0x31, 0x53, 0x2F, 0x9F,
-0x84, 0x31, 0x5E, 0xE9,
+ 0x31, 0x53, 0x2F, 0x9F,
+ 0x84, 0x31, 0x5E, 0xE9,
-0x39, 0xE5, 0x2C, 0x9F,
-0x85, 0x39, 0x5E, 0xE9,
+ 0x39, 0xE5, 0x2C, 0x9F,
+ 0x85, 0x39, 0x5E, 0xE9,
-0x86, 0x76, 0x57, 0xE9,
-0x8A, 0x36, 0x20, 0xE9,
+ 0x86, 0x76, 0x57, 0xE9,
+ 0x8A, 0x36, 0x20, 0xE9,
-0x87, 0x77, 0x57, 0xE9,
-0x8B, 0x3E, 0xBF, 0xEA,
+ 0x87, 0x77, 0x57, 0xE9,
+ 0x8B, 0x3E, 0xBF, 0xEA,
-0x80, 0x30, 0x57, 0xE9,
-0x81, 0x38, 0x57, 0xE9,
+ 0x80, 0x30, 0x57, 0xE9,
+ 0x81, 0x38, 0x57, 0xE9,
-0x82, 0x31, 0x57, 0xE9,
-0x86, 0x78, 0x57, 0xE9,
+ 0x82, 0x31, 0x57, 0xE9,
+ 0x86, 0x78, 0x57, 0xE9,
-0x83, 0x39, 0x57, 0xE9,
-0x87, 0x79, 0x57, 0xE9,
+ 0x83, 0x39, 0x57, 0xE9,
+ 0x87, 0x79, 0x57, 0xE9,
-0x30, 0x1F, 0x5F, 0xE9,
-0x8A, 0x34, 0x20, 0xE9,
+ 0x30, 0x1F, 0x5F, 0xE9,
+ 0x8A, 0x34, 0x20, 0xE9,
-0x8B, 0x3C, 0x20, 0xE9,
-0x37, 0x50, 0x60, 0xBD,
+ 0x8B, 0x3C, 0x20, 0xE9,
+ 0x37, 0x50, 0x60, 0xBD,
-0x57, 0x0D, 0x20, 0xE9,
-0x35, 0x51, 0x61, 0xBD,
+ 0x57, 0x0D, 0x20, 0xE9,
+ 0x35, 0x51, 0x61, 0xBD,
-0x2B, 0x50, 0x20, 0xE9,
-0x1D, 0x37, 0xE1, 0xEA,
+ 0x2B, 0x50, 0x20, 0xE9,
+ 0x1D, 0x37, 0xE1, 0xEA,
-0x1E, 0x35, 0xE1, 0xEA,
-0x00, 0xE0,
-0x0E, 0x77,
+ 0x1E, 0x35, 0xE1, 0xEA,
+ 0x00, 0xE0,
+ 0x0E, 0x77,
-0x24, 0x51, 0x20, 0xE9,
-0x8D, 0xFF, 0x20, 0xEA,
+ 0x24, 0x51, 0x20, 0xE9,
+ 0x8D, 0xFF, 0x20, 0xEA,
-0x16, 0x0E, 0x20, 0xE9,
-0x57, 0x2E, 0xBF, 0xEA,
+ 0x16, 0x0E, 0x20, 0xE9,
+ 0x57, 0x2E, 0xBF, 0xEA,
-0x0B, 0x46, 0xA0, 0xE8,
-0x1B, 0x56, 0xA0, 0xE8,
+ 0x0B, 0x46, 0xA0, 0xE8,
+ 0x1B, 0x56, 0xA0, 0xE8,
-0x2B, 0x66, 0xA0, 0xE8,
-0x0C, 0x47, 0xA0, 0xE8,
+ 0x2B, 0x66, 0xA0, 0xE8,
+ 0x0C, 0x47, 0xA0, 0xE8,
-0x1C, 0x57, 0xA0, 0xE8,
-0x2C, 0x67, 0xA0, 0xE8,
+ 0x1C, 0x57, 0xA0, 0xE8,
+ 0x2C, 0x67, 0xA0, 0xE8,
-0x0B, 0x00,
-0x1B, 0x00,
-0x2B, 0x00,
-0x00, 0xE0,
+ 0x0B, 0x00,
+ 0x1B, 0x00,
+ 0x2B, 0x00,
+ 0x00, 0xE0,
-0x0C, 0x00,
-0x1C, 0x00,
-0x2C, 0x00,
-0x00, 0xE0,
+ 0x0C, 0x00,
+ 0x1C, 0x00,
+ 0x2C, 0x00,
+ 0x00, 0xE0,
-0x0B, 0x65,
-0x1B, 0x65,
-0x2B, 0x65,
-0x00, 0xE0,
+ 0x0B, 0x65,
+ 0x1B, 0x65,
+ 0x2B, 0x65,
+ 0x00, 0xE0,
-0x0C, 0x65,
-0x1C, 0x65,
-0x2C, 0x65,
-0x00, 0xE0,
+ 0x0C, 0x65,
+ 0x1C, 0x65,
+ 0x2C, 0x65,
+ 0x00, 0xE0,
-0x0B, 0x1B, 0x60, 0xEC,
-0x36, 0xD7, 0x36, 0xAD,
+ 0x0B, 0x1B, 0x60, 0xEC,
+ 0x36, 0xD7, 0x36, 0xAD,
-0x2B, 0x80, 0x60, 0xEC,
-0x0C, 0x1C, 0x60, 0xEC,
+ 0x2B, 0x80, 0x60, 0xEC,
+ 0x0C, 0x1C, 0x60, 0xEC,
-0x3E, 0xD7, 0x3E, 0xAD,
-0x2C, 0x80, 0x60, 0xEC,
+ 0x3E, 0xD7, 0x3E, 0xAD,
+ 0x2C, 0x80, 0x60, 0xEC,
-0x0B, 0x2B, 0xDE, 0xE8,
-0x1B, 0x80, 0xDE, 0xE8,
+ 0x0B, 0x2B, 0xDE, 0xE8,
+ 0x1B, 0x80, 0xDE, 0xE8,
-0x36, 0x80, 0x36, 0xBD,
-0x3E, 0x80, 0x3E, 0xBD,
+ 0x36, 0x80, 0x36, 0xBD,
+ 0x3E, 0x80, 0x3E, 0xBD,
-0x33, 0xD7, 0x0B, 0xBD,
-0x3B, 0xD7, 0x1B, 0xBD,
+ 0x33, 0xD7, 0x0B, 0xBD,
+ 0x3B, 0xD7, 0x1B, 0xBD,
-0x46, 0x80, 0x46, 0xCF,
-0x57, 0x80, 0x57, 0xCF,
+ 0x46, 0x80, 0x46, 0xCF,
+ 0x57, 0x80, 0x57, 0xCF,
-0x66, 0x33, 0x66, 0xCF,
-0x47, 0x3B, 0x47, 0xCF,
+ 0x66, 0x33, 0x66, 0xCF,
+ 0x47, 0x3B, 0x47, 0xCF,
-0x56, 0x33, 0x56, 0xCF,
-0x67, 0x3B, 0x67, 0xCF,
+ 0x56, 0x33, 0x56, 0xCF,
+ 0x67, 0x3B, 0x67, 0xCF,
-0x0B, 0x48, 0xA0, 0xE8,
-0x1B, 0x58, 0xA0, 0xE8,
+ 0x0B, 0x48, 0xA0, 0xE8,
+ 0x1B, 0x58, 0xA0, 0xE8,
-0x2B, 0x68, 0xA0, 0xE8,
-0x0C, 0x49, 0xA0, 0xE8,
+ 0x2B, 0x68, 0xA0, 0xE8,
+ 0x0C, 0x49, 0xA0, 0xE8,
-0x1C, 0x59, 0xA0, 0xE8,
-0x2C, 0x69, 0xA0, 0xE8,
+ 0x1C, 0x59, 0xA0, 0xE8,
+ 0x2C, 0x69, 0xA0, 0xE8,
-0x0B, 0x00,
-0x1B, 0x00,
-0x2B, 0x00,
-0x00, 0xE0,
+ 0x0B, 0x00,
+ 0x1B, 0x00,
+ 0x2B, 0x00,
+ 0x00, 0xE0,
-0x0C, 0x00,
-0x1C, 0x00,
-0x2C, 0x00,
-0x00, 0xE0,
+ 0x0C, 0x00,
+ 0x1C, 0x00,
+ 0x2C, 0x00,
+ 0x00, 0xE0,
-0x0B, 0x65,
-0x1B, 0x65,
-0x2B, 0x65,
-0x00, 0xE0,
+ 0x0B, 0x65,
+ 0x1B, 0x65,
+ 0x2B, 0x65,
+ 0x00, 0xE0,
-0x0C, 0x65,
-0x1C, 0x65,
-0x2C, 0x65,
-0x00, 0xE0,
+ 0x0C, 0x65,
+ 0x1C, 0x65,
+ 0x2C, 0x65,
+ 0x00, 0xE0,
-0x0B, 0x1B, 0x60, 0xEC,
-0x34, 0xD7, 0x34, 0xAD,
+ 0x0B, 0x1B, 0x60, 0xEC,
+ 0x34, 0xD7, 0x34, 0xAD,
-0x2B, 0x80, 0x60, 0xEC,
-0x0C, 0x1C, 0x60, 0xEC,
+ 0x2B, 0x80, 0x60, 0xEC,
+ 0x0C, 0x1C, 0x60, 0xEC,
-0x3C, 0xD7, 0x3C, 0xAD,
-0x2C, 0x80, 0x60, 0xEC,
+ 0x3C, 0xD7, 0x3C, 0xAD,
+ 0x2C, 0x80, 0x60, 0xEC,
-0x0B, 0x2B, 0xDE, 0xE8,
-0x1B, 0x80, 0xDE, 0xE8,
+ 0x0B, 0x2B, 0xDE, 0xE8,
+ 0x1B, 0x80, 0xDE, 0xE8,
-0x34, 0x80, 0x34, 0xBD,
-0x3C, 0x80, 0x3C, 0xBD,
+ 0x34, 0x80, 0x34, 0xBD,
+ 0x3C, 0x80, 0x3C, 0xBD,
-0x33, 0xD7, 0x0B, 0xBD,
-0x3B, 0xD7, 0x1B, 0xBD,
+ 0x33, 0xD7, 0x0B, 0xBD,
+ 0x3B, 0xD7, 0x1B, 0xBD,
-0x48, 0x80, 0x48, 0xCF,
-0x59, 0x80, 0x59, 0xCF,
+ 0x48, 0x80, 0x48, 0xCF,
+ 0x59, 0x80, 0x59, 0xCF,
-0x68, 0x33, 0x68, 0xCF,
-0x49, 0x3B, 0x49, 0xCF,
+ 0x68, 0x33, 0x68, 0xCF,
+ 0x49, 0x3B, 0x49, 0xCF,
-0xAD, 0xFF, 0x20, 0xEA,
-0x00, 0x80, 0x00, 0xE8,
+ 0xAD, 0xFF, 0x20, 0xEA,
+ 0x00, 0x80, 0x00, 0xE8,
-0x58, 0x33, 0x58, 0xCF,
-0x69, 0x3B, 0x69, 0xCF,
+ 0x58, 0x33, 0x58, 0xCF,
+ 0x69, 0x3B, 0x69, 0xCF,
-0x6B, 0xFF, 0x20, 0xEA,
-0x57, 0xC0, 0xBF, 0xEA,
+ 0x6B, 0xFF, 0x20, 0xEA,
+ 0x57, 0xC0, 0xBF, 0xEA,
-0x00, 0x80, 0xA0, 0xE9,
-0x00, 0x00, 0xD8, 0xEC,
+ 0x00, 0x80, 0xA0, 0xE9,
+ 0x00, 0x00, 0xD8, 0xEC,
};
static unsigned char warp_g400_t2gzsaf[] = {
-0x00, 0x8A, 0x98, 0xE9,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x8A, 0x98, 0xE9,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0xA0, 0xE9,
-0x00, 0x00, 0xD8, 0xEC,
+ 0x00, 0x80, 0xA0, 0xE9,
+ 0x00, 0x00, 0xD8, 0xEC,
-0xFF, 0x80, 0xC0, 0xE9,
-0x00, 0x80, 0x00, 0xE8,
+ 0xFF, 0x80, 0xC0, 0xE9,
+ 0x00, 0x80, 0x00, 0xE8,
-0x0A, 0x40, 0x50, 0xBF,
-0x2A, 0x40, 0x60, 0xBF,
+ 0x0A, 0x40, 0x50, 0xBF,
+ 0x2A, 0x40, 0x60, 0xBF,
-0x32, 0x41, 0x51, 0xBF,
-0x3A, 0x41, 0x61, 0xBF,
+ 0x32, 0x41, 0x51, 0xBF,
+ 0x3A, 0x41, 0x61, 0xBF,
-0xC3, 0x6B,
-0xD3, 0x6B,
-0x00, 0x8A, 0x98, 0xE9,
+ 0xC3, 0x6B,
+ 0xD3, 0x6B,
+ 0x00, 0x8A, 0x98, 0xE9,
-0x73, 0x7B, 0xC8, 0xEC,
-0x96, 0xE2,
-0x41, 0x04,
+ 0x73, 0x7B, 0xC8, 0xEC,
+ 0x96, 0xE2,
+ 0x41, 0x04,
-0x7B, 0x43, 0xA0, 0xE8,
-0x73, 0x53, 0xA0, 0xE8,
+ 0x7B, 0x43, 0xA0, 0xE8,
+ 0x73, 0x53, 0xA0, 0xE8,
-0xAD, 0xEE, 0x23, 0x9F,
-0x00, 0xE0,
-0x51, 0x04,
+ 0xAD, 0xEE, 0x23, 0x9F,
+ 0x00, 0xE0,
+ 0x51, 0x04,
-0x90, 0xE2,
-0x61, 0x04,
-0x31, 0x46, 0xB1, 0xE8,
+ 0x90, 0xE2,
+ 0x61, 0x04,
+ 0x31, 0x46, 0xB1, 0xE8,
-0x51, 0x41, 0xE0, 0xEC,
-0x39, 0x67, 0xB1, 0xE8,
+ 0x51, 0x41, 0xE0, 0xEC,
+ 0x39, 0x67, 0xB1, 0xE8,
-0x00, 0x04,
-0x46, 0xE2,
-0x73, 0x63, 0xA0, 0xE8,
+ 0x00, 0x04,
+ 0x46, 0xE2,
+ 0x73, 0x63, 0xA0, 0xE8,
-0x61, 0x41, 0xE0, 0xEC,
-0x31, 0x00,
-0x39, 0x00,
+ 0x61, 0x41, 0xE0, 0xEC,
+ 0x31, 0x00,
+ 0x39, 0x00,
-0x8E, 0x80, 0x15, 0xEA,
-0x10, 0x04,
-0x20, 0x04,
+ 0x8E, 0x80, 0x15, 0xEA,
+ 0x10, 0x04,
+ 0x20, 0x04,
-0x61, 0x51, 0xE0, 0xEC,
-0x2F, 0x41, 0x60, 0xEA,
+ 0x61, 0x51, 0xE0, 0xEC,
+ 0x2F, 0x41, 0x60, 0xEA,
-0x31, 0x20,
-0x39, 0x20,
-0x1F, 0x42, 0xA0, 0xE8,
+ 0x31, 0x20,
+ 0x39, 0x20,
+ 0x1F, 0x42, 0xA0, 0xE8,
-0x2A, 0x42, 0x52, 0xBF,
-0x0F, 0x52, 0xA0, 0xE8,
+ 0x2A, 0x42, 0x52, 0xBF,
+ 0x0F, 0x52, 0xA0, 0xE8,
-0x1A, 0x42, 0x62, 0xBF,
-0x1E, 0x51, 0x60, 0xEA,
+ 0x1A, 0x42, 0x62, 0xBF,
+ 0x1E, 0x51, 0x60, 0xEA,
-0x73, 0x7B, 0xC8, 0xEC,
-0x0E, 0x61, 0x60, 0xEA,
+ 0x73, 0x7B, 0xC8, 0xEC,
+ 0x0E, 0x61, 0x60, 0xEA,
-0x32, 0x40, 0x50, 0xBD,
-0x22, 0x40, 0x60, 0xBD,
+ 0x32, 0x40, 0x50, 0xBD,
+ 0x22, 0x40, 0x60, 0xBD,
-0x12, 0x41, 0x51, 0xBD,
-0x3A, 0x41, 0x61, 0xBD,
+ 0x12, 0x41, 0x51, 0xBD,
+ 0x3A, 0x41, 0x61, 0xBD,
-0xBF, 0x2F, 0x0E, 0xBD,
-0x97, 0xE2,
-0x7B, 0x72,
+ 0xBF, 0x2F, 0x0E, 0xBD,
+ 0x97, 0xE2,
+ 0x7B, 0x72,
-0x32, 0x20,
-0x22, 0x20,
-0x12, 0x20,
-0x3A, 0x20,
+ 0x32, 0x20,
+ 0x22, 0x20,
+ 0x12, 0x20,
+ 0x3A, 0x20,
-0x35, 0x48, 0xB1, 0xE8,
-0x3D, 0x59, 0xB1, 0xE8,
+ 0x35, 0x48, 0xB1, 0xE8,
+ 0x3D, 0x59, 0xB1, 0xE8,
-0x46, 0x31, 0x46, 0xBF,
-0x56, 0x31, 0x56, 0xBF,
+ 0x46, 0x31, 0x46, 0xBF,
+ 0x56, 0x31, 0x56, 0xBF,
-0xB3, 0xE2, 0x2D, 0x9F,
-0x00, 0x80, 0x00, 0xE8,
+ 0xB3, 0xE2, 0x2D, 0x9F,
+ 0x00, 0x80, 0x00, 0xE8,
-0x66, 0x31, 0x66, 0xBF,
-0x47, 0x39, 0x47, 0xBF,
+ 0x66, 0x31, 0x66, 0xBF,
+ 0x47, 0x39, 0x47, 0xBF,
-0x57, 0x39, 0x57, 0xBF,
-0x67, 0x39, 0x67, 0xBF,
+ 0x57, 0x39, 0x57, 0xBF,
+ 0x67, 0x39, 0x67, 0xBF,
-0x7F, 0x80, 0x07, 0xEA,
-0x24, 0x41, 0x20, 0xE9,
+ 0x7F, 0x80, 0x07, 0xEA,
+ 0x24, 0x41, 0x20, 0xE9,
-0x35, 0x00,
-0x3D, 0x00,
-0x00, 0xE0,
-0x2D, 0x73,
+ 0x35, 0x00,
+ 0x3D, 0x00,
+ 0x00, 0xE0,
+ 0x2D, 0x73,
-0x33, 0x72,
-0x0C, 0xE3,
-0x8D, 0x2F, 0x1E, 0xBD,
+ 0x33, 0x72,
+ 0x0C, 0xE3,
+ 0x8D, 0x2F, 0x1E, 0xBD,
-0x43, 0x75, 0xF8, 0xEC,
-0x35, 0x20,
-0x3D, 0x20,
+ 0x43, 0x75, 0xF8, 0xEC,
+ 0x35, 0x20,
+ 0x3D, 0x20,
-0x43, 0x43, 0x2D, 0xDF,
-0x53, 0x53, 0x2D, 0xDF,
+ 0x43, 0x43, 0x2D, 0xDF,
+ 0x53, 0x53, 0x2D, 0xDF,
-0xAE, 0x1E, 0x0E, 0xBD,
-0x58, 0xE3,
-0x33, 0x66,
+ 0xAE, 0x1E, 0x0E, 0xBD,
+ 0x58, 0xE3,
+ 0x33, 0x66,
-0x48, 0x35, 0x48, 0xBF,
-0x58, 0x35, 0x58, 0xBF,
+ 0x48, 0x35, 0x48, 0xBF,
+ 0x58, 0x35, 0x58, 0xBF,
-0x68, 0x35, 0x68, 0xBF,
-0x49, 0x3D, 0x49, 0xBF,
+ 0x68, 0x35, 0x68, 0xBF,
+ 0x49, 0x3D, 0x49, 0xBF,
-0x59, 0x3D, 0x59, 0xBF,
-0x69, 0x3D, 0x69, 0xBF,
+ 0x59, 0x3D, 0x59, 0xBF,
+ 0x69, 0x3D, 0x69, 0xBF,
-0x63, 0x63, 0x2D, 0xDF,
-0x4D, 0x7D, 0xF8, 0xEC,
+ 0x63, 0x63, 0x2D, 0xDF,
+ 0x4D, 0x7D, 0xF8, 0xEC,
-0x59, 0xE3,
-0x00, 0xE0,
-0xB8, 0x38, 0x33, 0xBF,
+ 0x59, 0xE3,
+ 0x00, 0xE0,
+ 0xB8, 0x38, 0x33, 0xBF,
-0x2D, 0x73,
-0x30, 0x76,
-0x18, 0x3A, 0x41, 0xE9,
+ 0x2D, 0x73,
+ 0x30, 0x76,
+ 0x18, 0x3A, 0x41, 0xE9,
-0x3F, 0x53, 0xA0, 0xE8,
-0x05, 0x80, 0x3D, 0xEA,
+ 0x3F, 0x53, 0xA0, 0xE8,
+ 0x05, 0x80, 0x3D, 0xEA,
-0x37, 0x43, 0xA0, 0xE8,
-0x3D, 0x63, 0xA0, 0xE8,
+ 0x37, 0x43, 0xA0, 0xE8,
+ 0x3D, 0x63, 0xA0, 0xE8,
-0x50, 0x70, 0xF8, 0xEC,
-0x2B, 0x50, 0x3C, 0xE9,
+ 0x50, 0x70, 0xF8, 0xEC,
+ 0x2B, 0x50, 0x3C, 0xE9,
-0x1F, 0x0F, 0xBC, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x1F, 0x0F, 0xBC, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x59, 0x78, 0xF8, 0xEC,
-0x00, 0x80, 0x00, 0xE8,
+ 0x59, 0x78, 0xF8, 0xEC,
+ 0x00, 0x80, 0x00, 0xE8,
-0x15, 0xC0, 0x20, 0xE9,
-0x15, 0xC0, 0x20, 0xE9,
+ 0x15, 0xC0, 0x20, 0xE9,
+ 0x15, 0xC0, 0x20, 0xE9,
-0x15, 0xC0, 0x20, 0xE9,
-0x15, 0xC0, 0x20, 0xE9,
+ 0x15, 0xC0, 0x20, 0xE9,
+ 0x15, 0xC0, 0x20, 0xE9,
-0x1E, 0x12, 0x41, 0xE9,
-0x1A, 0x22, 0x41, 0xE9,
+ 0x1E, 0x12, 0x41, 0xE9,
+ 0x1A, 0x22, 0x41, 0xE9,
-0x46, 0x37, 0x46, 0xDF,
-0x56, 0x3F, 0x56, 0xDF,
+ 0x46, 0x37, 0x46, 0xDF,
+ 0x56, 0x3F, 0x56, 0xDF,
-0x2B, 0x40, 0x3D, 0xE9,
-0x66, 0x3D, 0x66, 0xDF,
+ 0x2B, 0x40, 0x3D, 0xE9,
+ 0x66, 0x3D, 0x66, 0xDF,
-0x1D, 0x32, 0x41, 0xE9,
-0x67, 0x3D, 0x67, 0xDF,
+ 0x1D, 0x32, 0x41, 0xE9,
+ 0x67, 0x3D, 0x67, 0xDF,
-0x47, 0x37, 0x47, 0xDF,
-0x57, 0x3F, 0x57, 0xDF,
+ 0x47, 0x37, 0x47, 0xDF,
+ 0x57, 0x3F, 0x57, 0xDF,
-0x2A, 0x40, 0x20, 0xE9,
-0x59, 0x3F, 0x59, 0xDF,
+ 0x2A, 0x40, 0x20, 0xE9,
+ 0x59, 0x3F, 0x59, 0xDF,
-0x16, 0x30, 0x20, 0xE9,
-0x69, 0x3D, 0x69, 0xDF,
+ 0x16, 0x30, 0x20, 0xE9,
+ 0x69, 0x3D, 0x69, 0xDF,
-0x48, 0x37, 0x48, 0xDF,
-0x58, 0x3F, 0x58, 0xDF,
+ 0x48, 0x37, 0x48, 0xDF,
+ 0x58, 0x3F, 0x58, 0xDF,
-0x68, 0x3D, 0x68, 0xDF,
-0x49, 0x37, 0x49, 0xDF,
+ 0x68, 0x3D, 0x68, 0xDF,
+ 0x49, 0x37, 0x49, 0xDF,
-0x32, 0x32, 0x2D, 0xDF,
-0x22, 0x22, 0x2D, 0xDF,
+ 0x32, 0x32, 0x2D, 0xDF,
+ 0x22, 0x22, 0x2D, 0xDF,
-0x12, 0x12, 0x2D, 0xDF,
-0x3A, 0x3A, 0x2D, 0xDF,
+ 0x12, 0x12, 0x2D, 0xDF,
+ 0x3A, 0x3A, 0x2D, 0xDF,
-0x0F, 0xCF, 0x74, 0xC2,
-0x37, 0xCF, 0x74, 0xC4,
+ 0x0F, 0xCF, 0x74, 0xC2,
+ 0x37, 0xCF, 0x74, 0xC4,
-0x0A, 0x44, 0x54, 0xB0,
-0x02, 0x44, 0x64, 0xB0,
+ 0x0A, 0x44, 0x54, 0xB0,
+ 0x02, 0x44, 0x64, 0xB0,
-0x3D, 0xCF, 0x74, 0xC0,
-0x34, 0x37, 0x20, 0xE9,
+ 0x3D, 0xCF, 0x74, 0xC0,
+ 0x34, 0x37, 0x20, 0xE9,
-0x31, 0x53, 0x2F, 0x9F,
-0x38, 0x0F, 0x20, 0xE9,
+ 0x31, 0x53, 0x2F, 0x9F,
+ 0x38, 0x0F, 0x20, 0xE9,
-0x39, 0xE5, 0x2C, 0x9F,
-0x3C, 0x3D, 0x20, 0xE9,
+ 0x39, 0xE5, 0x2C, 0x9F,
+ 0x3C, 0x3D, 0x20, 0xE9,
-0x2A, 0x44, 0x54, 0xB2,
-0x1A, 0x44, 0x64, 0xB2,
+ 0x2A, 0x44, 0x54, 0xB2,
+ 0x1A, 0x44, 0x64, 0xB2,
-0x3A, 0x80, 0x3A, 0xEA,
-0x0A, 0x20,
-0x02, 0x20,
+ 0x3A, 0x80, 0x3A, 0xEA,
+ 0x0A, 0x20,
+ 0x02, 0x20,
-0x0F, 0xCF, 0x75, 0xC0,
-0x2A, 0x20,
-0x1A, 0x20,
+ 0x0F, 0xCF, 0x75, 0xC0,
+ 0x2A, 0x20,
+ 0x1A, 0x20,
-0x30, 0x50, 0x2E, 0x9F,
-0x32, 0x31, 0x5F, 0xE9,
+ 0x30, 0x50, 0x2E, 0x9F,
+ 0x32, 0x31, 0x5F, 0xE9,
-0x38, 0x21, 0x2C, 0x9F,
-0x33, 0x39, 0x5F, 0xE9,
+ 0x38, 0x21, 0x2C, 0x9F,
+ 0x33, 0x39, 0x5F, 0xE9,
-0x3D, 0xCF, 0x75, 0xC2,
-0x37, 0xCF, 0x75, 0xC4,
+ 0x3D, 0xCF, 0x75, 0xC2,
+ 0x37, 0xCF, 0x75, 0xC4,
-0x31, 0x53, 0x2F, 0x9F,
-0xA6, 0x0F, 0x20, 0xE9,
+ 0x31, 0x53, 0x2F, 0x9F,
+ 0xA6, 0x0F, 0x20, 0xE9,
-0x39, 0xE5, 0x2C, 0x9F,
-0xA3, 0x3D, 0x20, 0xE9,
+ 0x39, 0xE5, 0x2C, 0x9F,
+ 0xA3, 0x3D, 0x20, 0xE9,
-0x2A, 0x44, 0x54, 0xB4,
-0x1A, 0x44, 0x64, 0xB4,
+ 0x2A, 0x44, 0x54, 0xB4,
+ 0x1A, 0x44, 0x64, 0xB4,
-0x0A, 0x45, 0x55, 0xB0,
-0x02, 0x45, 0x65, 0xB0,
+ 0x0A, 0x45, 0x55, 0xB0,
+ 0x02, 0x45, 0x65, 0xB0,
-0x88, 0x73, 0x5E, 0xE9,
-0x2A, 0x20,
-0x1A, 0x20,
+ 0x88, 0x73, 0x5E, 0xE9,
+ 0x2A, 0x20,
+ 0x1A, 0x20,
-0xA0, 0x37, 0x20, 0xE9,
-0x0A, 0x20,
-0x02, 0x20,
+ 0xA0, 0x37, 0x20, 0xE9,
+ 0x0A, 0x20,
+ 0x02, 0x20,
-0x31, 0x53, 0x2F, 0x9F,
-0x3E, 0x30, 0x4F, 0xE9,
+ 0x31, 0x53, 0x2F, 0x9F,
+ 0x3E, 0x30, 0x4F, 0xE9,
-0x39, 0xE5, 0x2C, 0x9F,
-0x3F, 0x38, 0x4F, 0xE9,
+ 0x39, 0xE5, 0x2C, 0x9F,
+ 0x3F, 0x38, 0x4F, 0xE9,
-0x30, 0x50, 0x2E, 0x9F,
-0x3A, 0x31, 0x4F, 0xE9,
+ 0x30, 0x50, 0x2E, 0x9F,
+ 0x3A, 0x31, 0x4F, 0xE9,
-0x38, 0x21, 0x2C, 0x9F,
-0x3B, 0x39, 0x4F, 0xE9,
+ 0x38, 0x21, 0x2C, 0x9F,
+ 0x3B, 0x39, 0x4F, 0xE9,
-0x2A, 0x45, 0x55, 0xB2,
-0x1A, 0x45, 0x65, 0xB2,
+ 0x2A, 0x45, 0x55, 0xB2,
+ 0x1A, 0x45, 0x65, 0xB2,
-0x0A, 0x45, 0x55, 0xB4,
-0x02, 0x45, 0x65, 0xB4,
+ 0x0A, 0x45, 0x55, 0xB4,
+ 0x02, 0x45, 0x65, 0xB4,
-0x0F, 0xCF, 0x74, 0xC6,
-0x2A, 0x20,
-0x1A, 0x20,
+ 0x0F, 0xCF, 0x74, 0xC6,
+ 0x2A, 0x20,
+ 0x1A, 0x20,
-0xA7, 0x30, 0x4F, 0xE9,
-0x0A, 0x20,
-0x02, 0x20,
+ 0xA7, 0x30, 0x4F, 0xE9,
+ 0x0A, 0x20,
+ 0x02, 0x20,
-0x31, 0x53, 0x2F, 0x9F,
-0x9C, 0x0F, 0x20, 0xE9,
+ 0x31, 0x53, 0x2F, 0x9F,
+ 0x9C, 0x0F, 0x20, 0xE9,
-0x39, 0xE5, 0x2C, 0x9F,
-0xA8, 0x38, 0x4F, 0xE9,
+ 0x39, 0xE5, 0x2C, 0x9F,
+ 0xA8, 0x38, 0x4F, 0xE9,
-0x2A, 0x44, 0x54, 0xB6,
-0x1A, 0x44, 0x64, 0xB6,
+ 0x2A, 0x44, 0x54, 0xB6,
+ 0x1A, 0x44, 0x64, 0xB6,
-0x30, 0x50, 0x2E, 0x9F,
-0x36, 0x31, 0x4F, 0xE9,
+ 0x30, 0x50, 0x2E, 0x9F,
+ 0x36, 0x31, 0x4F, 0xE9,
-0x38, 0x21, 0x2C, 0x9F,
-0x37, 0x39, 0x4F, 0xE9,
+ 0x38, 0x21, 0x2C, 0x9F,
+ 0x37, 0x39, 0x4F, 0xE9,
-0x0A, 0x45, 0x55, 0xB6,
-0x02, 0x45, 0x65, 0xB6,
+ 0x0A, 0x45, 0x55, 0xB6,
+ 0x02, 0x45, 0x65, 0xB6,
-0x3D, 0xCF, 0x75, 0xC6,
-0x2A, 0x20,
-0x1A, 0x20,
+ 0x3D, 0xCF, 0x75, 0xC6,
+ 0x2A, 0x20,
+ 0x1A, 0x20,
-0x2A, 0x46, 0x56, 0xBF,
-0x1A, 0x46, 0x66, 0xBF,
+ 0x2A, 0x46, 0x56, 0xBF,
+ 0x1A, 0x46, 0x66, 0xBF,
-0x31, 0x53, 0x2F, 0x9F,
-0xA4, 0x31, 0x4F, 0xE9,
+ 0x31, 0x53, 0x2F, 0x9F,
+ 0xA4, 0x31, 0x4F, 0xE9,
-0x39, 0xE5, 0x2C, 0x9F,
-0xA5, 0x39, 0x4F, 0xE9,
+ 0x39, 0xE5, 0x2C, 0x9F,
+ 0xA5, 0x39, 0x4F, 0xE9,
-0x31, 0x3D, 0x20, 0xE9,
-0x0A, 0x20,
-0x02, 0x20,
+ 0x31, 0x3D, 0x20, 0xE9,
+ 0x0A, 0x20,
+ 0x02, 0x20,
-0x0A, 0x47, 0x57, 0xBF,
-0x02, 0x47, 0x67, 0xBF,
+ 0x0A, 0x47, 0x57, 0xBF,
+ 0x02, 0x47, 0x67, 0xBF,
-0x30, 0x50, 0x2E, 0x9F,
-0xA1, 0x30, 0x4F, 0xE9,
+ 0x30, 0x50, 0x2E, 0x9F,
+ 0xA1, 0x30, 0x4F, 0xE9,
-0x38, 0x21, 0x2C, 0x9F,
-0xA2, 0x38, 0x4F, 0xE9,
+ 0x38, 0x21, 0x2C, 0x9F,
+ 0xA2, 0x38, 0x4F, 0xE9,
-0x31, 0x53, 0x2F, 0x9F,
-0x9D, 0x31, 0x4F, 0xE9,
+ 0x31, 0x53, 0x2F, 0x9F,
+ 0x9D, 0x31, 0x4F, 0xE9,
-0x39, 0xE5, 0x2C, 0x9F,
-0x9E, 0x39, 0x4F, 0xE9,
+ 0x39, 0xE5, 0x2C, 0x9F,
+ 0x9E, 0x39, 0x4F, 0xE9,
-0x2A, 0x43, 0x53, 0xBF,
-0x1A, 0x43, 0x63, 0xBF,
+ 0x2A, 0x43, 0x53, 0xBF,
+ 0x1A, 0x43, 0x63, 0xBF,
-0x30, 0x50, 0x2E, 0x9F,
-0x35, 0x30, 0x4F, 0xE9,
+ 0x30, 0x50, 0x2E, 0x9F,
+ 0x35, 0x30, 0x4F, 0xE9,
-0x38, 0x21, 0x2C, 0x9F,
-0x39, 0x38, 0x4F, 0xE9,
+ 0x38, 0x21, 0x2C, 0x9F,
+ 0x39, 0x38, 0x4F, 0xE9,
-0x0A, 0x48, 0x58, 0xBF,
-0x02, 0x48, 0x68, 0xBF,
+ 0x0A, 0x48, 0x58, 0xBF,
+ 0x02, 0x48, 0x68, 0xBF,
-0x31, 0x53, 0x2F, 0x9F,
-0x80, 0x31, 0x57, 0xE9,
+ 0x31, 0x53, 0x2F, 0x9F,
+ 0x80, 0x31, 0x57, 0xE9,
-0x39, 0xE5, 0x2C, 0x9F,
-0x81, 0x39, 0x57, 0xE9,
+ 0x39, 0xE5, 0x2C, 0x9F,
+ 0x81, 0x39, 0x57, 0xE9,
-0x2A, 0x49, 0x59, 0xBF,
-0x1A, 0x49, 0x69, 0xBF,
+ 0x2A, 0x49, 0x59, 0xBF,
+ 0x1A, 0x49, 0x69, 0xBF,
-0x30, 0x50, 0x2E, 0x9F,
-0x82, 0x30, 0x57, 0xE9,
+ 0x30, 0x50, 0x2E, 0x9F,
+ 0x82, 0x30, 0x57, 0xE9,
-0x38, 0x21, 0x2C, 0x9F,
-0x83, 0x38, 0x57, 0xE9,
+ 0x38, 0x21, 0x2C, 0x9F,
+ 0x83, 0x38, 0x57, 0xE9,
-0x31, 0x53, 0x2F, 0x9F,
-0x84, 0x31, 0x5E, 0xE9,
+ 0x31, 0x53, 0x2F, 0x9F,
+ 0x84, 0x31, 0x5E, 0xE9,
-0x39, 0xE5, 0x2C, 0x9F,
-0x85, 0x39, 0x5E, 0xE9,
+ 0x39, 0xE5, 0x2C, 0x9F,
+ 0x85, 0x39, 0x5E, 0xE9,
-0x86, 0x76, 0x57, 0xE9,
-0x8A, 0x36, 0x20, 0xE9,
+ 0x86, 0x76, 0x57, 0xE9,
+ 0x8A, 0x36, 0x20, 0xE9,
-0x87, 0x77, 0x57, 0xE9,
-0x8B, 0x3E, 0xBF, 0xEA,
+ 0x87, 0x77, 0x57, 0xE9,
+ 0x8B, 0x3E, 0xBF, 0xEA,
-0x80, 0x30, 0x57, 0xE9,
-0x81, 0x38, 0x57, 0xE9,
+ 0x80, 0x30, 0x57, 0xE9,
+ 0x81, 0x38, 0x57, 0xE9,
-0x82, 0x31, 0x57, 0xE9,
-0x86, 0x78, 0x57, 0xE9,
+ 0x82, 0x31, 0x57, 0xE9,
+ 0x86, 0x78, 0x57, 0xE9,
-0x83, 0x39, 0x57, 0xE9,
-0x87, 0x79, 0x57, 0xE9,
+ 0x83, 0x39, 0x57, 0xE9,
+ 0x87, 0x79, 0x57, 0xE9,
-0x30, 0x1F, 0x5F, 0xE9,
-0x8A, 0x34, 0x20, 0xE9,
+ 0x30, 0x1F, 0x5F, 0xE9,
+ 0x8A, 0x34, 0x20, 0xE9,
-0x8B, 0x3C, 0x20, 0xE9,
-0x37, 0x50, 0x60, 0xBD,
+ 0x8B, 0x3C, 0x20, 0xE9,
+ 0x37, 0x50, 0x60, 0xBD,
-0x57, 0x0D, 0x20, 0xE9,
-0x35, 0x51, 0x61, 0xBD,
+ 0x57, 0x0D, 0x20, 0xE9,
+ 0x35, 0x51, 0x61, 0xBD,
-0x2B, 0x50, 0x20, 0xE9,
-0x1D, 0x37, 0xE1, 0xEA,
+ 0x2B, 0x50, 0x20, 0xE9,
+ 0x1D, 0x37, 0xE1, 0xEA,
-0x1E, 0x35, 0xE1, 0xEA,
-0x00, 0xE0,
-0x0E, 0x77,
+ 0x1E, 0x35, 0xE1, 0xEA,
+ 0x00, 0xE0,
+ 0x0E, 0x77,
-0x24, 0x51, 0x20, 0xE9,
-0x89, 0xFF, 0x20, 0xEA,
+ 0x24, 0x51, 0x20, 0xE9,
+ 0x89, 0xFF, 0x20, 0xEA,
-0x16, 0x0E, 0x20, 0xE9,
-0x57, 0x2E, 0xBF, 0xEA,
+ 0x16, 0x0E, 0x20, 0xE9,
+ 0x57, 0x2E, 0xBF, 0xEA,
-0x0B, 0x46, 0xA0, 0xE8,
-0x1B, 0x56, 0xA0, 0xE8,
+ 0x0B, 0x46, 0xA0, 0xE8,
+ 0x1B, 0x56, 0xA0, 0xE8,
-0x2B, 0x66, 0xA0, 0xE8,
-0x0C, 0x47, 0xA0, 0xE8,
+ 0x2B, 0x66, 0xA0, 0xE8,
+ 0x0C, 0x47, 0xA0, 0xE8,
-0x1C, 0x57, 0xA0, 0xE8,
-0x2C, 0x67, 0xA0, 0xE8,
+ 0x1C, 0x57, 0xA0, 0xE8,
+ 0x2C, 0x67, 0xA0, 0xE8,
-0x0B, 0x00,
-0x1B, 0x00,
-0x2B, 0x00,
-0x00, 0xE0,
+ 0x0B, 0x00,
+ 0x1B, 0x00,
+ 0x2B, 0x00,
+ 0x00, 0xE0,
-0x0C, 0x00,
-0x1C, 0x00,
-0x2C, 0x00,
-0x00, 0xE0,
+ 0x0C, 0x00,
+ 0x1C, 0x00,
+ 0x2C, 0x00,
+ 0x00, 0xE0,
-0x0B, 0x65,
-0x1B, 0x65,
-0x2B, 0x65,
-0x00, 0xE0,
+ 0x0B, 0x65,
+ 0x1B, 0x65,
+ 0x2B, 0x65,
+ 0x00, 0xE0,
-0x0C, 0x65,
-0x1C, 0x65,
-0x2C, 0x65,
-0x00, 0xE0,
+ 0x0C, 0x65,
+ 0x1C, 0x65,
+ 0x2C, 0x65,
+ 0x00, 0xE0,
-0x0B, 0x1B, 0x60, 0xEC,
-0x36, 0xD7, 0x36, 0xAD,
+ 0x0B, 0x1B, 0x60, 0xEC,
+ 0x36, 0xD7, 0x36, 0xAD,
-0x2B, 0x80, 0x60, 0xEC,
-0x0C, 0x1C, 0x60, 0xEC,
+ 0x2B, 0x80, 0x60, 0xEC,
+ 0x0C, 0x1C, 0x60, 0xEC,
-0x3E, 0xD7, 0x3E, 0xAD,
-0x2C, 0x80, 0x60, 0xEC,
+ 0x3E, 0xD7, 0x3E, 0xAD,
+ 0x2C, 0x80, 0x60, 0xEC,
-0x0B, 0x2B, 0xDE, 0xE8,
-0x1B, 0x80, 0xDE, 0xE8,
+ 0x0B, 0x2B, 0xDE, 0xE8,
+ 0x1B, 0x80, 0xDE, 0xE8,
-0x36, 0x80, 0x36, 0xBD,
-0x3E, 0x80, 0x3E, 0xBD,
+ 0x36, 0x80, 0x36, 0xBD,
+ 0x3E, 0x80, 0x3E, 0xBD,
-0x33, 0xD7, 0x0B, 0xBD,
-0x3B, 0xD7, 0x1B, 0xBD,
+ 0x33, 0xD7, 0x0B, 0xBD,
+ 0x3B, 0xD7, 0x1B, 0xBD,
-0x46, 0x80, 0x46, 0xCF,
-0x57, 0x80, 0x57, 0xCF,
+ 0x46, 0x80, 0x46, 0xCF,
+ 0x57, 0x80, 0x57, 0xCF,
-0x66, 0x33, 0x66, 0xCF,
-0x47, 0x3B, 0x47, 0xCF,
+ 0x66, 0x33, 0x66, 0xCF,
+ 0x47, 0x3B, 0x47, 0xCF,
-0x56, 0x33, 0x56, 0xCF,
-0x67, 0x3B, 0x67, 0xCF,
+ 0x56, 0x33, 0x56, 0xCF,
+ 0x67, 0x3B, 0x67, 0xCF,
-0x0B, 0x48, 0xA0, 0xE8,
-0x1B, 0x58, 0xA0, 0xE8,
+ 0x0B, 0x48, 0xA0, 0xE8,
+ 0x1B, 0x58, 0xA0, 0xE8,
-0x2B, 0x68, 0xA0, 0xE8,
-0x0C, 0x49, 0xA0, 0xE8,
+ 0x2B, 0x68, 0xA0, 0xE8,
+ 0x0C, 0x49, 0xA0, 0xE8,
-0x1C, 0x59, 0xA0, 0xE8,
-0x2C, 0x69, 0xA0, 0xE8,
+ 0x1C, 0x59, 0xA0, 0xE8,
+ 0x2C, 0x69, 0xA0, 0xE8,
-0x0B, 0x00,
-0x1B, 0x00,
-0x2B, 0x00,
-0x00, 0xE0,
+ 0x0B, 0x00,
+ 0x1B, 0x00,
+ 0x2B, 0x00,
+ 0x00, 0xE0,
-0x0C, 0x00,
-0x1C, 0x00,
-0x2C, 0x00,
-0x00, 0xE0,
+ 0x0C, 0x00,
+ 0x1C, 0x00,
+ 0x2C, 0x00,
+ 0x00, 0xE0,
-0x0B, 0x65,
-0x1B, 0x65,
-0x2B, 0x65,
-0x00, 0xE0,
+ 0x0B, 0x65,
+ 0x1B, 0x65,
+ 0x2B, 0x65,
+ 0x00, 0xE0,
-0x0C, 0x65,
-0x1C, 0x65,
-0x2C, 0x65,
-0x00, 0xE0,
+ 0x0C, 0x65,
+ 0x1C, 0x65,
+ 0x2C, 0x65,
+ 0x00, 0xE0,
-0x0B, 0x1B, 0x60, 0xEC,
-0x34, 0xD7, 0x34, 0xAD,
+ 0x0B, 0x1B, 0x60, 0xEC,
+ 0x34, 0xD7, 0x34, 0xAD,
-0x2B, 0x80, 0x60, 0xEC,
-0x0C, 0x1C, 0x60, 0xEC,
+ 0x2B, 0x80, 0x60, 0xEC,
+ 0x0C, 0x1C, 0x60, 0xEC,
-0x3C, 0xD7, 0x3C, 0xAD,
-0x2C, 0x80, 0x60, 0xEC,
+ 0x3C, 0xD7, 0x3C, 0xAD,
+ 0x2C, 0x80, 0x60, 0xEC,
-0x0B, 0x2B, 0xDE, 0xE8,
-0x1B, 0x80, 0xDE, 0xE8,
+ 0x0B, 0x2B, 0xDE, 0xE8,
+ 0x1B, 0x80, 0xDE, 0xE8,
-0x34, 0x80, 0x34, 0xBD,
-0x3C, 0x80, 0x3C, 0xBD,
+ 0x34, 0x80, 0x34, 0xBD,
+ 0x3C, 0x80, 0x3C, 0xBD,
-0x33, 0xD7, 0x0B, 0xBD,
-0x3B, 0xD7, 0x1B, 0xBD,
+ 0x33, 0xD7, 0x0B, 0xBD,
+ 0x3B, 0xD7, 0x1B, 0xBD,
-0x48, 0x80, 0x48, 0xCF,
-0x59, 0x80, 0x59, 0xCF,
+ 0x48, 0x80, 0x48, 0xCF,
+ 0x59, 0x80, 0x59, 0xCF,
-0x68, 0x33, 0x68, 0xCF,
-0x49, 0x3B, 0x49, 0xCF,
+ 0x68, 0x33, 0x68, 0xCF,
+ 0x49, 0x3B, 0x49, 0xCF,
-0xA9, 0xFF, 0x20, 0xEA,
-0x00, 0x80, 0x00, 0xE8,
+ 0xA9, 0xFF, 0x20, 0xEA,
+ 0x00, 0x80, 0x00, 0xE8,
-0x58, 0x33, 0x58, 0xCF,
-0x69, 0x3B, 0x69, 0xCF,
+ 0x58, 0x33, 0x58, 0xCF,
+ 0x69, 0x3B, 0x69, 0xCF,
-0x67, 0xFF, 0x20, 0xEA,
-0x57, 0xC0, 0xBF, 0xEA,
+ 0x67, 0xFF, 0x20, 0xEA,
+ 0x57, 0xC0, 0xBF, 0xEA,
-0x00, 0x80, 0xA0, 0xE9,
-0x00, 0x00, 0xD8, 0xEC,
+ 0x00, 0x80, 0xA0, 0xE9,
+ 0x00, 0x00, 0xD8, 0xEC,
};
static unsigned char warp_g400_t2gzsf[] = {
-0x00, 0x8A, 0x98, 0xE9,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x8A, 0x98, 0xE9,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0xA0, 0xE9,
-0x00, 0x00, 0xD8, 0xEC,
+ 0x00, 0x80, 0xA0, 0xE9,
+ 0x00, 0x00, 0xD8, 0xEC,
-0xFF, 0x80, 0xC0, 0xE9,
-0x00, 0x80, 0x00, 0xE8,
+ 0xFF, 0x80, 0xC0, 0xE9,
+ 0x00, 0x80, 0x00, 0xE8,
-0x0A, 0x40, 0x50, 0xBF,
-0x2A, 0x40, 0x60, 0xBF,
+ 0x0A, 0x40, 0x50, 0xBF,
+ 0x2A, 0x40, 0x60, 0xBF,
-0x32, 0x41, 0x51, 0xBF,
-0x3A, 0x41, 0x61, 0xBF,
+ 0x32, 0x41, 0x51, 0xBF,
+ 0x3A, 0x41, 0x61, 0xBF,
-0xC3, 0x6B,
-0xD3, 0x6B,
-0x00, 0x8A, 0x98, 0xE9,
+ 0xC3, 0x6B,
+ 0xD3, 0x6B,
+ 0x00, 0x8A, 0x98, 0xE9,
-0x73, 0x7B, 0xC8, 0xEC,
-0x96, 0xE2,
-0x41, 0x04,
+ 0x73, 0x7B, 0xC8, 0xEC,
+ 0x96, 0xE2,
+ 0x41, 0x04,
-0x7B, 0x43, 0xA0, 0xE8,
-0x73, 0x53, 0xA0, 0xE8,
+ 0x7B, 0x43, 0xA0, 0xE8,
+ 0x73, 0x53, 0xA0, 0xE8,
-0xAD, 0xEE, 0x23, 0x9F,
-0x00, 0xE0,
-0x51, 0x04,
+ 0xAD, 0xEE, 0x23, 0x9F,
+ 0x00, 0xE0,
+ 0x51, 0x04,
-0x90, 0xE2,
-0x61, 0x04,
-0x31, 0x46, 0xB1, 0xE8,
+ 0x90, 0xE2,
+ 0x61, 0x04,
+ 0x31, 0x46, 0xB1, 0xE8,
-0x51, 0x41, 0xE0, 0xEC,
-0x39, 0x67, 0xB1, 0xE8,
+ 0x51, 0x41, 0xE0, 0xEC,
+ 0x39, 0x67, 0xB1, 0xE8,
-0x00, 0x04,
-0x46, 0xE2,
-0x73, 0x63, 0xA0, 0xE8,
+ 0x00, 0x04,
+ 0x46, 0xE2,
+ 0x73, 0x63, 0xA0, 0xE8,
-0x61, 0x41, 0xE0, 0xEC,
-0x31, 0x00,
-0x39, 0x00,
+ 0x61, 0x41, 0xE0, 0xEC,
+ 0x31, 0x00,
+ 0x39, 0x00,
-0x8A, 0x80, 0x15, 0xEA,
-0x10, 0x04,
-0x20, 0x04,
+ 0x8A, 0x80, 0x15, 0xEA,
+ 0x10, 0x04,
+ 0x20, 0x04,
-0x61, 0x51, 0xE0, 0xEC,
-0x2F, 0x41, 0x60, 0xEA,
+ 0x61, 0x51, 0xE0, 0xEC,
+ 0x2F, 0x41, 0x60, 0xEA,
-0x31, 0x20,
-0x39, 0x20,
-0x1F, 0x42, 0xA0, 0xE8,
+ 0x31, 0x20,
+ 0x39, 0x20,
+ 0x1F, 0x42, 0xA0, 0xE8,
-0x2A, 0x42, 0x52, 0xBF,
-0x0F, 0x52, 0xA0, 0xE8,
+ 0x2A, 0x42, 0x52, 0xBF,
+ 0x0F, 0x52, 0xA0, 0xE8,
-0x1A, 0x42, 0x62, 0xBF,
-0x1E, 0x51, 0x60, 0xEA,
+ 0x1A, 0x42, 0x62, 0xBF,
+ 0x1E, 0x51, 0x60, 0xEA,
-0x73, 0x7B, 0xC8, 0xEC,
-0x0E, 0x61, 0x60, 0xEA,
+ 0x73, 0x7B, 0xC8, 0xEC,
+ 0x0E, 0x61, 0x60, 0xEA,
-0x32, 0x40, 0x50, 0xBD,
-0x22, 0x40, 0x60, 0xBD,
+ 0x32, 0x40, 0x50, 0xBD,
+ 0x22, 0x40, 0x60, 0xBD,
-0x12, 0x41, 0x51, 0xBD,
-0x3A, 0x41, 0x61, 0xBD,
+ 0x12, 0x41, 0x51, 0xBD,
+ 0x3A, 0x41, 0x61, 0xBD,
-0xBF, 0x2F, 0x0E, 0xBD,
-0x97, 0xE2,
-0x7B, 0x72,
+ 0xBF, 0x2F, 0x0E, 0xBD,
+ 0x97, 0xE2,
+ 0x7B, 0x72,
-0x32, 0x20,
-0x22, 0x20,
-0x12, 0x20,
-0x3A, 0x20,
+ 0x32, 0x20,
+ 0x22, 0x20,
+ 0x12, 0x20,
+ 0x3A, 0x20,
-0x35, 0x48, 0xB1, 0xE8,
-0x3D, 0x59, 0xB1, 0xE8,
+ 0x35, 0x48, 0xB1, 0xE8,
+ 0x3D, 0x59, 0xB1, 0xE8,
-0x46, 0x31, 0x46, 0xBF,
-0x56, 0x31, 0x56, 0xBF,
+ 0x46, 0x31, 0x46, 0xBF,
+ 0x56, 0x31, 0x56, 0xBF,
-0xB3, 0xE2, 0x2D, 0x9F,
-0x00, 0x80, 0x00, 0xE8,
+ 0xB3, 0xE2, 0x2D, 0x9F,
+ 0x00, 0x80, 0x00, 0xE8,
-0x66, 0x31, 0x66, 0xBF,
-0x47, 0x39, 0x47, 0xBF,
+ 0x66, 0x31, 0x66, 0xBF,
+ 0x47, 0x39, 0x47, 0xBF,
-0x57, 0x39, 0x57, 0xBF,
-0x67, 0x39, 0x67, 0xBF,
+ 0x57, 0x39, 0x57, 0xBF,
+ 0x67, 0x39, 0x67, 0xBF,
-0x7B, 0x80, 0x07, 0xEA,
-0x24, 0x41, 0x20, 0xE9,
+ 0x7B, 0x80, 0x07, 0xEA,
+ 0x24, 0x41, 0x20, 0xE9,
-0x35, 0x00,
-0x3D, 0x00,
-0x00, 0xE0,
-0x2D, 0x73,
+ 0x35, 0x00,
+ 0x3D, 0x00,
+ 0x00, 0xE0,
+ 0x2D, 0x73,
-0x33, 0x72,
-0x0C, 0xE3,
-0x8D, 0x2F, 0x1E, 0xBD,
+ 0x33, 0x72,
+ 0x0C, 0xE3,
+ 0x8D, 0x2F, 0x1E, 0xBD,
-0x43, 0x75, 0xF8, 0xEC,
-0x35, 0x20,
-0x3D, 0x20,
+ 0x43, 0x75, 0xF8, 0xEC,
+ 0x35, 0x20,
+ 0x3D, 0x20,
-0x43, 0x43, 0x2D, 0xDF,
-0x53, 0x53, 0x2D, 0xDF,
+ 0x43, 0x43, 0x2D, 0xDF,
+ 0x53, 0x53, 0x2D, 0xDF,
-0xAE, 0x1E, 0x0E, 0xBD,
-0x58, 0xE3,
-0x33, 0x66,
+ 0xAE, 0x1E, 0x0E, 0xBD,
+ 0x58, 0xE3,
+ 0x33, 0x66,
-0x48, 0x35, 0x48, 0xBF,
-0x58, 0x35, 0x58, 0xBF,
+ 0x48, 0x35, 0x48, 0xBF,
+ 0x58, 0x35, 0x58, 0xBF,
-0x68, 0x35, 0x68, 0xBF,
-0x49, 0x3D, 0x49, 0xBF,
+ 0x68, 0x35, 0x68, 0xBF,
+ 0x49, 0x3D, 0x49, 0xBF,
-0x59, 0x3D, 0x59, 0xBF,
-0x69, 0x3D, 0x69, 0xBF,
+ 0x59, 0x3D, 0x59, 0xBF,
+ 0x69, 0x3D, 0x69, 0xBF,
-0x63, 0x63, 0x2D, 0xDF,
-0x4D, 0x7D, 0xF8, 0xEC,
+ 0x63, 0x63, 0x2D, 0xDF,
+ 0x4D, 0x7D, 0xF8, 0xEC,
-0x59, 0xE3,
-0x00, 0xE0,
-0xB8, 0x38, 0x33, 0xBF,
+ 0x59, 0xE3,
+ 0x00, 0xE0,
+ 0xB8, 0x38, 0x33, 0xBF,
-0x2D, 0x73,
-0x30, 0x76,
-0x18, 0x3A, 0x41, 0xE9,
+ 0x2D, 0x73,
+ 0x30, 0x76,
+ 0x18, 0x3A, 0x41, 0xE9,
-0x3F, 0x53, 0xA0, 0xE8,
-0x05, 0x80, 0x3D, 0xEA,
+ 0x3F, 0x53, 0xA0, 0xE8,
+ 0x05, 0x80, 0x3D, 0xEA,
-0x37, 0x43, 0xA0, 0xE8,
-0x3D, 0x63, 0xA0, 0xE8,
+ 0x37, 0x43, 0xA0, 0xE8,
+ 0x3D, 0x63, 0xA0, 0xE8,
-0x50, 0x70, 0xF8, 0xEC,
-0x2B, 0x50, 0x3C, 0xE9,
+ 0x50, 0x70, 0xF8, 0xEC,
+ 0x2B, 0x50, 0x3C, 0xE9,
-0x1F, 0x0F, 0xBC, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x1F, 0x0F, 0xBC, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x59, 0x78, 0xF8, 0xEC,
-0x00, 0x80, 0x00, 0xE8,
+ 0x59, 0x78, 0xF8, 0xEC,
+ 0x00, 0x80, 0x00, 0xE8,
-0x15, 0xC0, 0x20, 0xE9,
-0x15, 0xC0, 0x20, 0xE9,
+ 0x15, 0xC0, 0x20, 0xE9,
+ 0x15, 0xC0, 0x20, 0xE9,
-0x15, 0xC0, 0x20, 0xE9,
-0x15, 0xC0, 0x20, 0xE9,
+ 0x15, 0xC0, 0x20, 0xE9,
+ 0x15, 0xC0, 0x20, 0xE9,
-0x1E, 0x12, 0x41, 0xE9,
-0x1A, 0x22, 0x41, 0xE9,
+ 0x1E, 0x12, 0x41, 0xE9,
+ 0x1A, 0x22, 0x41, 0xE9,
-0x46, 0x37, 0x46, 0xDF,
-0x56, 0x3F, 0x56, 0xDF,
+ 0x46, 0x37, 0x46, 0xDF,
+ 0x56, 0x3F, 0x56, 0xDF,
-0x2B, 0x40, 0x3D, 0xE9,
-0x66, 0x3D, 0x66, 0xDF,
+ 0x2B, 0x40, 0x3D, 0xE9,
+ 0x66, 0x3D, 0x66, 0xDF,
-0x1D, 0x32, 0x41, 0xE9,
-0x67, 0x3D, 0x67, 0xDF,
+ 0x1D, 0x32, 0x41, 0xE9,
+ 0x67, 0x3D, 0x67, 0xDF,
-0x47, 0x37, 0x47, 0xDF,
-0x57, 0x3F, 0x57, 0xDF,
+ 0x47, 0x37, 0x47, 0xDF,
+ 0x57, 0x3F, 0x57, 0xDF,
-0x2A, 0x40, 0x20, 0xE9,
-0x59, 0x3F, 0x59, 0xDF,
+ 0x2A, 0x40, 0x20, 0xE9,
+ 0x59, 0x3F, 0x59, 0xDF,
-0x16, 0x30, 0x20, 0xE9,
-0x69, 0x3D, 0x69, 0xDF,
+ 0x16, 0x30, 0x20, 0xE9,
+ 0x69, 0x3D, 0x69, 0xDF,
-0x48, 0x37, 0x48, 0xDF,
-0x58, 0x3F, 0x58, 0xDF,
+ 0x48, 0x37, 0x48, 0xDF,
+ 0x58, 0x3F, 0x58, 0xDF,
-0x68, 0x3D, 0x68, 0xDF,
-0x49, 0x37, 0x49, 0xDF,
+ 0x68, 0x3D, 0x68, 0xDF,
+ 0x49, 0x37, 0x49, 0xDF,
-0x32, 0x32, 0x2D, 0xDF,
-0x22, 0x22, 0x2D, 0xDF,
+ 0x32, 0x32, 0x2D, 0xDF,
+ 0x22, 0x22, 0x2D, 0xDF,
-0x12, 0x12, 0x2D, 0xDF,
-0x3A, 0x3A, 0x2D, 0xDF,
+ 0x12, 0x12, 0x2D, 0xDF,
+ 0x3A, 0x3A, 0x2D, 0xDF,
-0x0F, 0xCF, 0x74, 0xC2,
-0x37, 0xCF, 0x74, 0xC4,
+ 0x0F, 0xCF, 0x74, 0xC2,
+ 0x37, 0xCF, 0x74, 0xC4,
-0x0A, 0x44, 0x54, 0xB0,
-0x02, 0x44, 0x64, 0xB0,
+ 0x0A, 0x44, 0x54, 0xB0,
+ 0x02, 0x44, 0x64, 0xB0,
-0x3D, 0xCF, 0x74, 0xC0,
-0x34, 0x37, 0x20, 0xE9,
+ 0x3D, 0xCF, 0x74, 0xC0,
+ 0x34, 0x37, 0x20, 0xE9,
-0x31, 0x53, 0x2F, 0x9F,
-0x38, 0x0F, 0x20, 0xE9,
+ 0x31, 0x53, 0x2F, 0x9F,
+ 0x38, 0x0F, 0x20, 0xE9,
-0x39, 0xE5, 0x2C, 0x9F,
-0x3C, 0x3D, 0x20, 0xE9,
+ 0x39, 0xE5, 0x2C, 0x9F,
+ 0x3C, 0x3D, 0x20, 0xE9,
-0x2A, 0x44, 0x54, 0xB2,
-0x1A, 0x44, 0x64, 0xB2,
+ 0x2A, 0x44, 0x54, 0xB2,
+ 0x1A, 0x44, 0x64, 0xB2,
-0x36, 0x80, 0x3A, 0xEA,
-0x0A, 0x20,
-0x02, 0x20,
+ 0x36, 0x80, 0x3A, 0xEA,
+ 0x0A, 0x20,
+ 0x02, 0x20,
-0x0F, 0xCF, 0x75, 0xC0,
-0x2A, 0x20,
-0x1A, 0x20,
+ 0x0F, 0xCF, 0x75, 0xC0,
+ 0x2A, 0x20,
+ 0x1A, 0x20,
-0x30, 0x50, 0x2E, 0x9F,
-0x32, 0x31, 0x5F, 0xE9,
+ 0x30, 0x50, 0x2E, 0x9F,
+ 0x32, 0x31, 0x5F, 0xE9,
-0x38, 0x21, 0x2C, 0x9F,
-0x33, 0x39, 0x5F, 0xE9,
+ 0x38, 0x21, 0x2C, 0x9F,
+ 0x33, 0x39, 0x5F, 0xE9,
-0x3D, 0xCF, 0x75, 0xC2,
-0x37, 0xCF, 0x75, 0xC4,
+ 0x3D, 0xCF, 0x75, 0xC2,
+ 0x37, 0xCF, 0x75, 0xC4,
-0x31, 0x53, 0x2F, 0x9F,
-0xA6, 0x0F, 0x20, 0xE9,
+ 0x31, 0x53, 0x2F, 0x9F,
+ 0xA6, 0x0F, 0x20, 0xE9,
-0x39, 0xE5, 0x2C, 0x9F,
-0xA3, 0x3D, 0x20, 0xE9,
+ 0x39, 0xE5, 0x2C, 0x9F,
+ 0xA3, 0x3D, 0x20, 0xE9,
-0x2A, 0x44, 0x54, 0xB4,
-0x1A, 0x44, 0x64, 0xB4,
+ 0x2A, 0x44, 0x54, 0xB4,
+ 0x1A, 0x44, 0x64, 0xB4,
-0x0A, 0x45, 0x55, 0xB0,
-0x02, 0x45, 0x65, 0xB0,
+ 0x0A, 0x45, 0x55, 0xB0,
+ 0x02, 0x45, 0x65, 0xB0,
-0x88, 0x73, 0x5E, 0xE9,
-0x2A, 0x20,
-0x1A, 0x20,
+ 0x88, 0x73, 0x5E, 0xE9,
+ 0x2A, 0x20,
+ 0x1A, 0x20,
-0xA0, 0x37, 0x20, 0xE9,
-0x0A, 0x20,
-0x02, 0x20,
+ 0xA0, 0x37, 0x20, 0xE9,
+ 0x0A, 0x20,
+ 0x02, 0x20,
-0x31, 0x53, 0x2F, 0x9F,
-0x3E, 0x30, 0x4F, 0xE9,
+ 0x31, 0x53, 0x2F, 0x9F,
+ 0x3E, 0x30, 0x4F, 0xE9,
-0x39, 0xE5, 0x2C, 0x9F,
-0x3F, 0x38, 0x4F, 0xE9,
+ 0x39, 0xE5, 0x2C, 0x9F,
+ 0x3F, 0x38, 0x4F, 0xE9,
-0x30, 0x50, 0x2E, 0x9F,
-0x3A, 0x31, 0x4F, 0xE9,
+ 0x30, 0x50, 0x2E, 0x9F,
+ 0x3A, 0x31, 0x4F, 0xE9,
-0x38, 0x21, 0x2C, 0x9F,
-0x3B, 0x39, 0x4F, 0xE9,
+ 0x38, 0x21, 0x2C, 0x9F,
+ 0x3B, 0x39, 0x4F, 0xE9,
-0x2A, 0x45, 0x55, 0xB2,
-0x1A, 0x45, 0x65, 0xB2,
+ 0x2A, 0x45, 0x55, 0xB2,
+ 0x1A, 0x45, 0x65, 0xB2,
-0x0A, 0x45, 0x55, 0xB4,
-0x02, 0x45, 0x65, 0xB4,
+ 0x0A, 0x45, 0x55, 0xB4,
+ 0x02, 0x45, 0x65, 0xB4,
-0x0F, 0xCF, 0x75, 0xC6,
-0x2A, 0x20,
-0x1A, 0x20,
+ 0x0F, 0xCF, 0x75, 0xC6,
+ 0x2A, 0x20,
+ 0x1A, 0x20,
-0xA7, 0x30, 0x4F, 0xE9,
-0x0A, 0x20,
-0x02, 0x20,
+ 0xA7, 0x30, 0x4F, 0xE9,
+ 0x0A, 0x20,
+ 0x02, 0x20,
-0x31, 0x53, 0x2F, 0x9F,
-0x31, 0x0F, 0x20, 0xE9,
+ 0x31, 0x53, 0x2F, 0x9F,
+ 0x31, 0x0F, 0x20, 0xE9,
-0x39, 0xE5, 0x2C, 0x9F,
-0xA8, 0x38, 0x4F, 0xE9,
+ 0x39, 0xE5, 0x2C, 0x9F,
+ 0xA8, 0x38, 0x4F, 0xE9,
-0x2A, 0x45, 0x55, 0xB6,
-0x1A, 0x45, 0x65, 0xB6,
+ 0x2A, 0x45, 0x55, 0xB6,
+ 0x1A, 0x45, 0x65, 0xB6,
-0x30, 0x50, 0x2E, 0x9F,
-0x36, 0x31, 0x4F, 0xE9,
+ 0x30, 0x50, 0x2E, 0x9F,
+ 0x36, 0x31, 0x4F, 0xE9,
-0x38, 0x21, 0x2C, 0x9F,
-0x37, 0x39, 0x4F, 0xE9,
+ 0x38, 0x21, 0x2C, 0x9F,
+ 0x37, 0x39, 0x4F, 0xE9,
-0x00, 0x80, 0x00, 0xE8,
-0x2A, 0x20,
-0x1A, 0x20,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x2A, 0x20,
+ 0x1A, 0x20,
-0x2A, 0x46, 0x56, 0xBF,
-0x1A, 0x46, 0x66, 0xBF,
+ 0x2A, 0x46, 0x56, 0xBF,
+ 0x1A, 0x46, 0x66, 0xBF,
-0x31, 0x53, 0x2F, 0x9F,
-0xA4, 0x31, 0x4F, 0xE9,
+ 0x31, 0x53, 0x2F, 0x9F,
+ 0xA4, 0x31, 0x4F, 0xE9,
-0x39, 0xE5, 0x2C, 0x9F,
-0xA5, 0x39, 0x4F, 0xE9,
+ 0x39, 0xE5, 0x2C, 0x9F,
+ 0xA5, 0x39, 0x4F, 0xE9,
-0x0A, 0x47, 0x57, 0xBF,
-0x02, 0x47, 0x67, 0xBF,
+ 0x0A, 0x47, 0x57, 0xBF,
+ 0x02, 0x47, 0x67, 0xBF,
-0x31, 0x53, 0x2F, 0x9F,
-0xA1, 0x30, 0x4F, 0xE9,
+ 0x31, 0x53, 0x2F, 0x9F,
+ 0xA1, 0x30, 0x4F, 0xE9,
-0x39, 0xE5, 0x2C, 0x9F,
-0xA2, 0x38, 0x4F, 0xE9,
+ 0x39, 0xE5, 0x2C, 0x9F,
+ 0xA2, 0x38, 0x4F, 0xE9,
-0x2A, 0x43, 0x53, 0xBF,
-0x1A, 0x43, 0x63, 0xBF,
+ 0x2A, 0x43, 0x53, 0xBF,
+ 0x1A, 0x43, 0x63, 0xBF,
-0x30, 0x50, 0x2E, 0x9F,
-0x35, 0x31, 0x4F, 0xE9,
+ 0x30, 0x50, 0x2E, 0x9F,
+ 0x35, 0x31, 0x4F, 0xE9,
-0x38, 0x21, 0x2C, 0x9F,
-0x39, 0x39, 0x4F, 0xE9,
+ 0x38, 0x21, 0x2C, 0x9F,
+ 0x39, 0x39, 0x4F, 0xE9,
-0x0A, 0x48, 0x58, 0xBF,
-0x02, 0x48, 0x68, 0xBF,
+ 0x0A, 0x48, 0x58, 0xBF,
+ 0x02, 0x48, 0x68, 0xBF,
-0x31, 0x53, 0x2F, 0x9F,
-0x80, 0x31, 0x57, 0xE9,
+ 0x31, 0x53, 0x2F, 0x9F,
+ 0x80, 0x31, 0x57, 0xE9,
-0x39, 0xE5, 0x2C, 0x9F,
-0x81, 0x39, 0x57, 0xE9,
+ 0x39, 0xE5, 0x2C, 0x9F,
+ 0x81, 0x39, 0x57, 0xE9,
-0x2A, 0x49, 0x59, 0xBF,
-0x1A, 0x49, 0x69, 0xBF,
+ 0x2A, 0x49, 0x59, 0xBF,
+ 0x1A, 0x49, 0x69, 0xBF,
-0x30, 0x50, 0x2E, 0x9F,
-0x82, 0x30, 0x57, 0xE9,
+ 0x30, 0x50, 0x2E, 0x9F,
+ 0x82, 0x30, 0x57, 0xE9,
-0x38, 0x21, 0x2C, 0x9F,
-0x83, 0x38, 0x57, 0xE9,
+ 0x38, 0x21, 0x2C, 0x9F,
+ 0x83, 0x38, 0x57, 0xE9,
-0x31, 0x53, 0x2F, 0x9F,
-0x84, 0x31, 0x5E, 0xE9,
+ 0x31, 0x53, 0x2F, 0x9F,
+ 0x84, 0x31, 0x5E, 0xE9,
-0x39, 0xE5, 0x2C, 0x9F,
-0x85, 0x39, 0x5E, 0xE9,
+ 0x39, 0xE5, 0x2C, 0x9F,
+ 0x85, 0x39, 0x5E, 0xE9,
-0x86, 0x76, 0x57, 0xE9,
-0x8A, 0x36, 0x20, 0xE9,
+ 0x86, 0x76, 0x57, 0xE9,
+ 0x8A, 0x36, 0x20, 0xE9,
-0x87, 0x77, 0x57, 0xE9,
-0x8B, 0x3E, 0xBF, 0xEA,
+ 0x87, 0x77, 0x57, 0xE9,
+ 0x8B, 0x3E, 0xBF, 0xEA,
-0x80, 0x30, 0x57, 0xE9,
-0x81, 0x38, 0x57, 0xE9,
+ 0x80, 0x30, 0x57, 0xE9,
+ 0x81, 0x38, 0x57, 0xE9,
-0x82, 0x31, 0x57, 0xE9,
-0x86, 0x78, 0x57, 0xE9,
+ 0x82, 0x31, 0x57, 0xE9,
+ 0x86, 0x78, 0x57, 0xE9,
-0x83, 0x39, 0x57, 0xE9,
-0x87, 0x79, 0x57, 0xE9,
+ 0x83, 0x39, 0x57, 0xE9,
+ 0x87, 0x79, 0x57, 0xE9,
-0x30, 0x1F, 0x5F, 0xE9,
-0x8A, 0x34, 0x20, 0xE9,
+ 0x30, 0x1F, 0x5F, 0xE9,
+ 0x8A, 0x34, 0x20, 0xE9,
-0x8B, 0x3C, 0x20, 0xE9,
-0x37, 0x50, 0x60, 0xBD,
+ 0x8B, 0x3C, 0x20, 0xE9,
+ 0x37, 0x50, 0x60, 0xBD,
-0x57, 0x0D, 0x20, 0xE9,
-0x35, 0x51, 0x61, 0xBD,
+ 0x57, 0x0D, 0x20, 0xE9,
+ 0x35, 0x51, 0x61, 0xBD,
-0x2B, 0x50, 0x20, 0xE9,
-0x1D, 0x37, 0xE1, 0xEA,
+ 0x2B, 0x50, 0x20, 0xE9,
+ 0x1D, 0x37, 0xE1, 0xEA,
-0x1E, 0x35, 0xE1, 0xEA,
-0x00, 0xE0,
-0x0E, 0x77,
+ 0x1E, 0x35, 0xE1, 0xEA,
+ 0x00, 0xE0,
+ 0x0E, 0x77,
-0x24, 0x51, 0x20, 0xE9,
-0x8D, 0xFF, 0x20, 0xEA,
+ 0x24, 0x51, 0x20, 0xE9,
+ 0x8D, 0xFF, 0x20, 0xEA,
-0x16, 0x0E, 0x20, 0xE9,
-0x57, 0x2E, 0xBF, 0xEA,
+ 0x16, 0x0E, 0x20, 0xE9,
+ 0x57, 0x2E, 0xBF, 0xEA,
-0x0B, 0x46, 0xA0, 0xE8,
-0x1B, 0x56, 0xA0, 0xE8,
+ 0x0B, 0x46, 0xA0, 0xE8,
+ 0x1B, 0x56, 0xA0, 0xE8,
-0x2B, 0x66, 0xA0, 0xE8,
-0x0C, 0x47, 0xA0, 0xE8,
+ 0x2B, 0x66, 0xA0, 0xE8,
+ 0x0C, 0x47, 0xA0, 0xE8,
-0x1C, 0x57, 0xA0, 0xE8,
-0x2C, 0x67, 0xA0, 0xE8,
+ 0x1C, 0x57, 0xA0, 0xE8,
+ 0x2C, 0x67, 0xA0, 0xE8,
-0x0B, 0x00,
-0x1B, 0x00,
-0x2B, 0x00,
-0x00, 0xE0,
+ 0x0B, 0x00,
+ 0x1B, 0x00,
+ 0x2B, 0x00,
+ 0x00, 0xE0,
-0x0C, 0x00,
-0x1C, 0x00,
-0x2C, 0x00,
-0x00, 0xE0,
+ 0x0C, 0x00,
+ 0x1C, 0x00,
+ 0x2C, 0x00,
+ 0x00, 0xE0,
-0x0B, 0x65,
-0x1B, 0x65,
-0x2B, 0x65,
-0x00, 0xE0,
+ 0x0B, 0x65,
+ 0x1B, 0x65,
+ 0x2B, 0x65,
+ 0x00, 0xE0,
-0x0C, 0x65,
-0x1C, 0x65,
-0x2C, 0x65,
-0x00, 0xE0,
+ 0x0C, 0x65,
+ 0x1C, 0x65,
+ 0x2C, 0x65,
+ 0x00, 0xE0,
-0x0B, 0x1B, 0x60, 0xEC,
-0x36, 0xD7, 0x36, 0xAD,
+ 0x0B, 0x1B, 0x60, 0xEC,
+ 0x36, 0xD7, 0x36, 0xAD,
-0x2B, 0x80, 0x60, 0xEC,
-0x0C, 0x1C, 0x60, 0xEC,
+ 0x2B, 0x80, 0x60, 0xEC,
+ 0x0C, 0x1C, 0x60, 0xEC,
-0x3E, 0xD7, 0x3E, 0xAD,
-0x2C, 0x80, 0x60, 0xEC,
+ 0x3E, 0xD7, 0x3E, 0xAD,
+ 0x2C, 0x80, 0x60, 0xEC,
-0x0B, 0x2B, 0xDE, 0xE8,
-0x1B, 0x80, 0xDE, 0xE8,
+ 0x0B, 0x2B, 0xDE, 0xE8,
+ 0x1B, 0x80, 0xDE, 0xE8,
-0x36, 0x80, 0x36, 0xBD,
-0x3E, 0x80, 0x3E, 0xBD,
+ 0x36, 0x80, 0x36, 0xBD,
+ 0x3E, 0x80, 0x3E, 0xBD,
-0x33, 0xD7, 0x0B, 0xBD,
-0x3B, 0xD7, 0x1B, 0xBD,
+ 0x33, 0xD7, 0x0B, 0xBD,
+ 0x3B, 0xD7, 0x1B, 0xBD,
-0x46, 0x80, 0x46, 0xCF,
-0x57, 0x80, 0x57, 0xCF,
+ 0x46, 0x80, 0x46, 0xCF,
+ 0x57, 0x80, 0x57, 0xCF,
-0x66, 0x33, 0x66, 0xCF,
-0x47, 0x3B, 0x47, 0xCF,
+ 0x66, 0x33, 0x66, 0xCF,
+ 0x47, 0x3B, 0x47, 0xCF,
-0x56, 0x33, 0x56, 0xCF,
-0x67, 0x3B, 0x67, 0xCF,
+ 0x56, 0x33, 0x56, 0xCF,
+ 0x67, 0x3B, 0x67, 0xCF,
-0x0B, 0x48, 0xA0, 0xE8,
-0x1B, 0x58, 0xA0, 0xE8,
+ 0x0B, 0x48, 0xA0, 0xE8,
+ 0x1B, 0x58, 0xA0, 0xE8,
-0x2B, 0x68, 0xA0, 0xE8,
-0x0C, 0x49, 0xA0, 0xE8,
+ 0x2B, 0x68, 0xA0, 0xE8,
+ 0x0C, 0x49, 0xA0, 0xE8,
-0x1C, 0x59, 0xA0, 0xE8,
-0x2C, 0x69, 0xA0, 0xE8,
+ 0x1C, 0x59, 0xA0, 0xE8,
+ 0x2C, 0x69, 0xA0, 0xE8,
-0x0B, 0x00,
-0x1B, 0x00,
-0x2B, 0x00,
-0x00, 0xE0,
+ 0x0B, 0x00,
+ 0x1B, 0x00,
+ 0x2B, 0x00,
+ 0x00, 0xE0,
-0x0C, 0x00,
-0x1C, 0x00,
-0x2C, 0x00,
-0x00, 0xE0,
+ 0x0C, 0x00,
+ 0x1C, 0x00,
+ 0x2C, 0x00,
+ 0x00, 0xE0,
-0x0B, 0x65,
-0x1B, 0x65,
-0x2B, 0x65,
-0x00, 0xE0,
+ 0x0B, 0x65,
+ 0x1B, 0x65,
+ 0x2B, 0x65,
+ 0x00, 0xE0,
-0x0C, 0x65,
-0x1C, 0x65,
-0x2C, 0x65,
-0x00, 0xE0,
+ 0x0C, 0x65,
+ 0x1C, 0x65,
+ 0x2C, 0x65,
+ 0x00, 0xE0,
-0x0B, 0x1B, 0x60, 0xEC,
-0x34, 0xD7, 0x34, 0xAD,
+ 0x0B, 0x1B, 0x60, 0xEC,
+ 0x34, 0xD7, 0x34, 0xAD,
-0x2B, 0x80, 0x60, 0xEC,
-0x0C, 0x1C, 0x60, 0xEC,
+ 0x2B, 0x80, 0x60, 0xEC,
+ 0x0C, 0x1C, 0x60, 0xEC,
-0x3C, 0xD7, 0x3C, 0xAD,
-0x2C, 0x80, 0x60, 0xEC,
+ 0x3C, 0xD7, 0x3C, 0xAD,
+ 0x2C, 0x80, 0x60, 0xEC,
-0x0B, 0x2B, 0xDE, 0xE8,
-0x1B, 0x80, 0xDE, 0xE8,
+ 0x0B, 0x2B, 0xDE, 0xE8,
+ 0x1B, 0x80, 0xDE, 0xE8,
-0x34, 0x80, 0x34, 0xBD,
-0x3C, 0x80, 0x3C, 0xBD,
+ 0x34, 0x80, 0x34, 0xBD,
+ 0x3C, 0x80, 0x3C, 0xBD,
-0x33, 0xD7, 0x0B, 0xBD,
-0x3B, 0xD7, 0x1B, 0xBD,
+ 0x33, 0xD7, 0x0B, 0xBD,
+ 0x3B, 0xD7, 0x1B, 0xBD,
-0x48, 0x80, 0x48, 0xCF,
-0x59, 0x80, 0x59, 0xCF,
+ 0x48, 0x80, 0x48, 0xCF,
+ 0x59, 0x80, 0x59, 0xCF,
-0x68, 0x33, 0x68, 0xCF,
-0x49, 0x3B, 0x49, 0xCF,
+ 0x68, 0x33, 0x68, 0xCF,
+ 0x49, 0x3B, 0x49, 0xCF,
-0xAD, 0xFF, 0x20, 0xEA,
-0x00, 0x80, 0x00, 0xE8,
+ 0xAD, 0xFF, 0x20, 0xEA,
+ 0x00, 0x80, 0x00, 0xE8,
-0x58, 0x33, 0x58, 0xCF,
-0x69, 0x3B, 0x69, 0xCF,
+ 0x58, 0x33, 0x58, 0xCF,
+ 0x69, 0x3B, 0x69, 0xCF,
-0x6B, 0xFF, 0x20, 0xEA,
-0x57, 0xC0, 0xBF, 0xEA,
+ 0x6B, 0xFF, 0x20, 0xEA,
+ 0x57, 0xC0, 0xBF, 0xEA,
-0x00, 0x80, 0xA0, 0xE9,
-0x00, 0x00, 0xD8, 0xEC,
+ 0x00, 0x80, 0xA0, 0xE9,
+ 0x00, 0x00, 0xD8, 0xEC,
};
static unsigned char warp_g400_tgz[] = {
-0x00, 0x88, 0x98, 0xE9,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x88, 0x98, 0xE9,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0xA0, 0xE9,
-0x00, 0x00, 0xD8, 0xEC,
+ 0x00, 0x80, 0xA0, 0xE9,
+ 0x00, 0x00, 0xD8, 0xEC,
-0xFF, 0x80, 0xC0, 0xE9,
-0x00, 0x80, 0x00, 0xE8,
+ 0xFF, 0x80, 0xC0, 0xE9,
+ 0x00, 0x80, 0x00, 0xE8,
-0x22, 0x40, 0x48, 0xBF,
-0x2A, 0x40, 0x50, 0xBF,
+ 0x22, 0x40, 0x48, 0xBF,
+ 0x2A, 0x40, 0x50, 0xBF,
-0x32, 0x41, 0x49, 0xBF,
-0x3A, 0x41, 0x51, 0xBF,
+ 0x32, 0x41, 0x49, 0xBF,
+ 0x3A, 0x41, 0x51, 0xBF,
-0xC3, 0x6B,
-0xCB, 0x6B,
-0x00, 0x88, 0x98, 0xE9,
+ 0xC3, 0x6B,
+ 0xCB, 0x6B,
+ 0x00, 0x88, 0x98, 0xE9,
-0x73, 0x7B, 0xC8, 0xEC,
-0x96, 0xE2,
-0x41, 0x04,
+ 0x73, 0x7B, 0xC8, 0xEC,
+ 0x96, 0xE2,
+ 0x41, 0x04,
-0x7B, 0x43, 0xA0, 0xE8,
-0x73, 0x4B, 0xA0, 0xE8,
+ 0x7B, 0x43, 0xA0, 0xE8,
+ 0x73, 0x4B, 0xA0, 0xE8,
-0xAD, 0xEE, 0x29, 0x9F,
-0x00, 0xE0,
-0x49, 0x04,
+ 0xAD, 0xEE, 0x29, 0x9F,
+ 0x00, 0xE0,
+ 0x49, 0x04,
-0x90, 0xE2,
-0x51, 0x04,
-0x31, 0x46, 0xB1, 0xE8,
+ 0x90, 0xE2,
+ 0x51, 0x04,
+ 0x31, 0x46, 0xB1, 0xE8,
-0x49, 0x41, 0xC0, 0xEC,
-0x39, 0x57, 0xB1, 0xE8,
+ 0x49, 0x41, 0xC0, 0xEC,
+ 0x39, 0x57, 0xB1, 0xE8,
-0x00, 0x04,
-0x46, 0xE2,
-0x73, 0x53, 0xA0, 0xE8,
+ 0x00, 0x04,
+ 0x46, 0xE2,
+ 0x73, 0x53, 0xA0, 0xE8,
-0x51, 0x41, 0xC0, 0xEC,
-0x31, 0x00,
-0x39, 0x00,
+ 0x51, 0x41, 0xC0, 0xEC,
+ 0x31, 0x00,
+ 0x39, 0x00,
-0x58, 0x80, 0x15, 0xEA,
-0x08, 0x04,
-0x10, 0x04,
+ 0x58, 0x80, 0x15, 0xEA,
+ 0x08, 0x04,
+ 0x10, 0x04,
-0x51, 0x49, 0xC0, 0xEC,
-0x2F, 0x41, 0x60, 0xEA,
+ 0x51, 0x49, 0xC0, 0xEC,
+ 0x2F, 0x41, 0x60, 0xEA,
-0x31, 0x20,
-0x39, 0x20,
-0x1F, 0x42, 0xA0, 0xE8,
+ 0x31, 0x20,
+ 0x39, 0x20,
+ 0x1F, 0x42, 0xA0, 0xE8,
-0x2A, 0x42, 0x4A, 0xBF,
-0x27, 0x4A, 0xA0, 0xE8,
+ 0x2A, 0x42, 0x4A, 0xBF,
+ 0x27, 0x4A, 0xA0, 0xE8,
-0x1A, 0x42, 0x52, 0xBF,
-0x1E, 0x49, 0x60, 0xEA,
+ 0x1A, 0x42, 0x52, 0xBF,
+ 0x1E, 0x49, 0x60, 0xEA,
-0x73, 0x7B, 0xC8, 0xEC,
-0x26, 0x51, 0x60, 0xEA,
+ 0x73, 0x7B, 0xC8, 0xEC,
+ 0x26, 0x51, 0x60, 0xEA,
-0x32, 0x40, 0x48, 0xBD,
-0x22, 0x40, 0x50, 0xBD,
+ 0x32, 0x40, 0x48, 0xBD,
+ 0x22, 0x40, 0x50, 0xBD,
-0x12, 0x41, 0x49, 0xBD,
-0x3A, 0x41, 0x51, 0xBD,
+ 0x12, 0x41, 0x49, 0xBD,
+ 0x3A, 0x41, 0x51, 0xBD,
-0xBF, 0x2F, 0x26, 0xBD,
-0x00, 0xE0,
-0x7B, 0x72,
+ 0xBF, 0x2F, 0x26, 0xBD,
+ 0x00, 0xE0,
+ 0x7B, 0x72,
-0x32, 0x20,
-0x22, 0x20,
-0x12, 0x20,
-0x3A, 0x20,
+ 0x32, 0x20,
+ 0x22, 0x20,
+ 0x12, 0x20,
+ 0x3A, 0x20,
-0x46, 0x31, 0x46, 0xBF,
-0x4E, 0x31, 0x4E, 0xBF,
+ 0x46, 0x31, 0x46, 0xBF,
+ 0x4E, 0x31, 0x4E, 0xBF,
-0xB3, 0xE2, 0x2D, 0x9F,
-0x00, 0x80, 0x00, 0xE8,
+ 0xB3, 0xE2, 0x2D, 0x9F,
+ 0x00, 0x80, 0x00, 0xE8,
-0x56, 0x31, 0x56, 0xBF,
-0x47, 0x39, 0x47, 0xBF,
+ 0x56, 0x31, 0x56, 0xBF,
+ 0x47, 0x39, 0x47, 0xBF,
-0x4F, 0x39, 0x4F, 0xBF,
-0x57, 0x39, 0x57, 0xBF,
+ 0x4F, 0x39, 0x4F, 0xBF,
+ 0x57, 0x39, 0x57, 0xBF,
-0x4A, 0x80, 0x07, 0xEA,
-0x24, 0x41, 0x20, 0xE9,
+ 0x4A, 0x80, 0x07, 0xEA,
+ 0x24, 0x41, 0x20, 0xE9,
-0x42, 0x73, 0xF8, 0xEC,
-0x00, 0xE0,
-0x2D, 0x73,
+ 0x42, 0x73, 0xF8, 0xEC,
+ 0x00, 0xE0,
+ 0x2D, 0x73,
-0x33, 0x72,
-0x0C, 0xE3,
-0xA5, 0x2F, 0x1E, 0xBD,
+ 0x33, 0x72,
+ 0x0C, 0xE3,
+ 0xA5, 0x2F, 0x1E, 0xBD,
-0x43, 0x43, 0x2D, 0xDF,
-0x4B, 0x4B, 0x2D, 0xDF,
+ 0x43, 0x43, 0x2D, 0xDF,
+ 0x4B, 0x4B, 0x2D, 0xDF,
-0xAE, 0x1E, 0x26, 0xBD,
-0x58, 0xE3,
-0x33, 0x66,
+ 0xAE, 0x1E, 0x26, 0xBD,
+ 0x58, 0xE3,
+ 0x33, 0x66,
-0x53, 0x53, 0x2D, 0xDF,
-0x00, 0x80, 0x00, 0xE8,
+ 0x53, 0x53, 0x2D, 0xDF,
+ 0x00, 0x80, 0x00, 0xE8,
-0xB8, 0x38, 0x33, 0xBF,
-0x00, 0xE0,
-0x59, 0xE3,
+ 0xB8, 0x38, 0x33, 0xBF,
+ 0x00, 0xE0,
+ 0x59, 0xE3,
-0x1E, 0x12, 0x41, 0xE9,
-0x1A, 0x22, 0x41, 0xE9,
+ 0x1E, 0x12, 0x41, 0xE9,
+ 0x1A, 0x22, 0x41, 0xE9,
-0x2B, 0x40, 0x3D, 0xE9,
-0x3F, 0x4B, 0xA0, 0xE8,
+ 0x2B, 0x40, 0x3D, 0xE9,
+ 0x3F, 0x4B, 0xA0, 0xE8,
-0x2D, 0x73,
-0x30, 0x76,
-0x05, 0x80, 0x3D, 0xEA,
+ 0x2D, 0x73,
+ 0x30, 0x76,
+ 0x05, 0x80, 0x3D, 0xEA,
-0x37, 0x43, 0xA0, 0xE8,
-0x3D, 0x53, 0xA0, 0xE8,
+ 0x37, 0x43, 0xA0, 0xE8,
+ 0x3D, 0x53, 0xA0, 0xE8,
-0x48, 0x70, 0xF8, 0xEC,
-0x2B, 0x48, 0x3C, 0xE9,
+ 0x48, 0x70, 0xF8, 0xEC,
+ 0x2B, 0x48, 0x3C, 0xE9,
-0x1F, 0x27, 0xBC, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x1F, 0x27, 0xBC, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x15, 0xC0, 0x20, 0xE9,
-0x15, 0xC0, 0x20, 0xE9,
+ 0x15, 0xC0, 0x20, 0xE9,
+ 0x15, 0xC0, 0x20, 0xE9,
-0x15, 0xC0, 0x20, 0xE9,
-0x15, 0xC0, 0x20, 0xE9,
+ 0x15, 0xC0, 0x20, 0xE9,
+ 0x15, 0xC0, 0x20, 0xE9,
-0x18, 0x3A, 0x41, 0xE9,
-0x1D, 0x32, 0x41, 0xE9,
+ 0x18, 0x3A, 0x41, 0xE9,
+ 0x1D, 0x32, 0x41, 0xE9,
-0x2A, 0x40, 0x20, 0xE9,
-0x56, 0x3D, 0x56, 0xDF,
+ 0x2A, 0x40, 0x20, 0xE9,
+ 0x56, 0x3D, 0x56, 0xDF,
-0x46, 0x37, 0x46, 0xDF,
-0x4E, 0x3F, 0x4E, 0xDF,
+ 0x46, 0x37, 0x46, 0xDF,
+ 0x4E, 0x3F, 0x4E, 0xDF,
-0x16, 0x30, 0x20, 0xE9,
-0x4F, 0x3F, 0x4F, 0xDF,
+ 0x16, 0x30, 0x20, 0xE9,
+ 0x4F, 0x3F, 0x4F, 0xDF,
-0x32, 0x32, 0x2D, 0xDF,
-0x22, 0x22, 0x2D, 0xDF,
+ 0x32, 0x32, 0x2D, 0xDF,
+ 0x22, 0x22, 0x2D, 0xDF,
-0x12, 0x12, 0x2D, 0xDF,
-0x3A, 0x3A, 0x2D, 0xDF,
+ 0x12, 0x12, 0x2D, 0xDF,
+ 0x3A, 0x3A, 0x2D, 0xDF,
-0x47, 0x37, 0x47, 0xDF,
-0x57, 0x3D, 0x57, 0xDF,
+ 0x47, 0x37, 0x47, 0xDF,
+ 0x57, 0x3D, 0x57, 0xDF,
-0x3D, 0xCF, 0x74, 0xC0,
-0x37, 0xCF, 0x74, 0xC4,
+ 0x3D, 0xCF, 0x74, 0xC0,
+ 0x37, 0xCF, 0x74, 0xC4,
-0x31, 0x53, 0x2F, 0x9F,
-0x34, 0x80, 0x20, 0xE9,
+ 0x31, 0x53, 0x2F, 0x9F,
+ 0x34, 0x80, 0x20, 0xE9,
-0x39, 0xE5, 0x2C, 0x9F,
-0x3C, 0x3D, 0x20, 0xE9,
+ 0x39, 0xE5, 0x2C, 0x9F,
+ 0x3C, 0x3D, 0x20, 0xE9,
-0x0A, 0x44, 0x4C, 0xB0,
-0x02, 0x44, 0x54, 0xB0,
+ 0x0A, 0x44, 0x4C, 0xB0,
+ 0x02, 0x44, 0x54, 0xB0,
-0x2A, 0x44, 0x4C, 0xB2,
-0x1A, 0x44, 0x54, 0xB2,
+ 0x2A, 0x44, 0x4C, 0xB2,
+ 0x1A, 0x44, 0x54, 0xB2,
-0x1D, 0x80, 0x3A, 0xEA,
-0x0A, 0x20,
-0x02, 0x20,
+ 0x1D, 0x80, 0x3A, 0xEA,
+ 0x0A, 0x20,
+ 0x02, 0x20,
-0x3D, 0xCF, 0x74, 0xC2,
-0x2A, 0x20,
-0x1A, 0x20,
+ 0x3D, 0xCF, 0x74, 0xC2,
+ 0x2A, 0x20,
+ 0x1A, 0x20,
-0x30, 0x50, 0x2E, 0x9F,
-0x32, 0x31, 0x5F, 0xE9,
+ 0x30, 0x50, 0x2E, 0x9F,
+ 0x32, 0x31, 0x5F, 0xE9,
-0x38, 0x21, 0x2C, 0x9F,
-0x33, 0x39, 0x5F, 0xE9,
+ 0x38, 0x21, 0x2C, 0x9F,
+ 0x33, 0x39, 0x5F, 0xE9,
-0x31, 0x53, 0x2F, 0x9F,
-0x00, 0x80, 0x00, 0xE8,
+ 0x31, 0x53, 0x2F, 0x9F,
+ 0x00, 0x80, 0x00, 0xE8,
-0x2A, 0x44, 0x4C, 0xB4,
-0x1A, 0x44, 0x54, 0xB4,
+ 0x2A, 0x44, 0x4C, 0xB4,
+ 0x1A, 0x44, 0x54, 0xB4,
-0x39, 0xE5, 0x2C, 0x9F,
-0x38, 0x3D, 0x20, 0xE9,
+ 0x39, 0xE5, 0x2C, 0x9F,
+ 0x38, 0x3D, 0x20, 0xE9,
-0x88, 0x73, 0x5E, 0xE9,
-0x2A, 0x20,
-0x1A, 0x20,
+ 0x88, 0x73, 0x5E, 0xE9,
+ 0x2A, 0x20,
+ 0x1A, 0x20,
-0x2A, 0x46, 0x4E, 0xBF,
-0x1A, 0x46, 0x56, 0xBF,
+ 0x2A, 0x46, 0x4E, 0xBF,
+ 0x1A, 0x46, 0x56, 0xBF,
-0x31, 0x53, 0x2F, 0x9F,
-0x3E, 0x30, 0x4F, 0xE9,
+ 0x31, 0x53, 0x2F, 0x9F,
+ 0x3E, 0x30, 0x4F, 0xE9,
-0x39, 0xE5, 0x2C, 0x9F,
-0x3F, 0x38, 0x4F, 0xE9,
+ 0x39, 0xE5, 0x2C, 0x9F,
+ 0x3F, 0x38, 0x4F, 0xE9,
-0x0A, 0x47, 0x4F, 0xBF,
-0x02, 0x47, 0x57, 0xBF,
+ 0x0A, 0x47, 0x4F, 0xBF,
+ 0x02, 0x47, 0x57, 0xBF,
-0x31, 0x53, 0x2F, 0x9F,
-0x3A, 0x31, 0x4F, 0xE9,
+ 0x31, 0x53, 0x2F, 0x9F,
+ 0x3A, 0x31, 0x4F, 0xE9,
-0x39, 0xE5, 0x2C, 0x9F,
-0x3B, 0x39, 0x4F, 0xE9,
+ 0x39, 0xE5, 0x2C, 0x9F,
+ 0x3B, 0x39, 0x4F, 0xE9,
-0x2A, 0x43, 0x4B, 0xBF,
-0x1A, 0x43, 0x53, 0xBF,
+ 0x2A, 0x43, 0x4B, 0xBF,
+ 0x1A, 0x43, 0x53, 0xBF,
-0x30, 0x50, 0x2E, 0x9F,
-0x36, 0x31, 0x4F, 0xE9,
+ 0x30, 0x50, 0x2E, 0x9F,
+ 0x36, 0x31, 0x4F, 0xE9,
-0x38, 0x21, 0x2C, 0x9F,
-0x37, 0x39, 0x4F, 0xE9,
+ 0x38, 0x21, 0x2C, 0x9F,
+ 0x37, 0x39, 0x4F, 0xE9,
-0x31, 0x53, 0x2F, 0x9F,
-0x80, 0x31, 0x57, 0xE9,
+ 0x31, 0x53, 0x2F, 0x9F,
+ 0x80, 0x31, 0x57, 0xE9,
-0x39, 0xE5, 0x2C, 0x9F,
-0x81, 0x39, 0x57, 0xE9,
+ 0x39, 0xE5, 0x2C, 0x9F,
+ 0x81, 0x39, 0x57, 0xE9,
-0x37, 0x48, 0x50, 0xBD,
-0x8A, 0x36, 0x20, 0xE9,
+ 0x37, 0x48, 0x50, 0xBD,
+ 0x8A, 0x36, 0x20, 0xE9,
-0x86, 0x76, 0x57, 0xE9,
-0x8B, 0x3E, 0x20, 0xE9,
+ 0x86, 0x76, 0x57, 0xE9,
+ 0x8B, 0x3E, 0x20, 0xE9,
-0x82, 0x30, 0x57, 0xE9,
-0x87, 0x77, 0x57, 0xE9,
+ 0x82, 0x30, 0x57, 0xE9,
+ 0x87, 0x77, 0x57, 0xE9,
-0x83, 0x38, 0x57, 0xE9,
-0x35, 0x49, 0x51, 0xBD,
+ 0x83, 0x38, 0x57, 0xE9,
+ 0x35, 0x49, 0x51, 0xBD,
-0x84, 0x31, 0x5E, 0xE9,
-0x30, 0x1F, 0x5F, 0xE9,
+ 0x84, 0x31, 0x5E, 0xE9,
+ 0x30, 0x1F, 0x5F, 0xE9,
-0x85, 0x39, 0x5E, 0xE9,
-0x57, 0x25, 0x20, 0xE9,
+ 0x85, 0x39, 0x5E, 0xE9,
+ 0x57, 0x25, 0x20, 0xE9,
-0x2B, 0x48, 0x20, 0xE9,
-0x1D, 0x37, 0xE1, 0xEA,
+ 0x2B, 0x48, 0x20, 0xE9,
+ 0x1D, 0x37, 0xE1, 0xEA,
-0x1E, 0x35, 0xE1, 0xEA,
-0x00, 0xE0,
-0x26, 0x77,
+ 0x1E, 0x35, 0xE1, 0xEA,
+ 0x00, 0xE0,
+ 0x26, 0x77,
-0x24, 0x49, 0x20, 0xE9,
-0xAF, 0xFF, 0x20, 0xEA,
+ 0x24, 0x49, 0x20, 0xE9,
+ 0xAF, 0xFF, 0x20, 0xEA,
-0x16, 0x26, 0x20, 0xE9,
-0x57, 0x2E, 0xBF, 0xEA,
+ 0x16, 0x26, 0x20, 0xE9,
+ 0x57, 0x2E, 0xBF, 0xEA,
-0x1C, 0x46, 0xA0, 0xE8,
-0x23, 0x4E, 0xA0, 0xE8,
+ 0x1C, 0x46, 0xA0, 0xE8,
+ 0x23, 0x4E, 0xA0, 0xE8,
-0x2B, 0x56, 0xA0, 0xE8,
-0x1D, 0x47, 0xA0, 0xE8,
+ 0x2B, 0x56, 0xA0, 0xE8,
+ 0x1D, 0x47, 0xA0, 0xE8,
-0x24, 0x4F, 0xA0, 0xE8,
-0x2C, 0x57, 0xA0, 0xE8,
+ 0x24, 0x4F, 0xA0, 0xE8,
+ 0x2C, 0x57, 0xA0, 0xE8,
-0x1C, 0x00,
-0x23, 0x00,
-0x2B, 0x00,
-0x00, 0xE0,
+ 0x1C, 0x00,
+ 0x23, 0x00,
+ 0x2B, 0x00,
+ 0x00, 0xE0,
-0x1D, 0x00,
-0x24, 0x00,
-0x2C, 0x00,
-0x00, 0xE0,
+ 0x1D, 0x00,
+ 0x24, 0x00,
+ 0x2C, 0x00,
+ 0x00, 0xE0,
-0x1C, 0x65,
-0x23, 0x65,
-0x2B, 0x65,
-0x00, 0xE0,
+ 0x1C, 0x65,
+ 0x23, 0x65,
+ 0x2B, 0x65,
+ 0x00, 0xE0,
-0x1D, 0x65,
-0x24, 0x65,
-0x2C, 0x65,
-0x00, 0xE0,
+ 0x1D, 0x65,
+ 0x24, 0x65,
+ 0x2C, 0x65,
+ 0x00, 0xE0,
-0x1C, 0x23, 0x60, 0xEC,
-0x36, 0xD7, 0x36, 0xAD,
+ 0x1C, 0x23, 0x60, 0xEC,
+ 0x36, 0xD7, 0x36, 0xAD,
-0x2B, 0x80, 0x60, 0xEC,
-0x1D, 0x24, 0x60, 0xEC,
+ 0x2B, 0x80, 0x60, 0xEC,
+ 0x1D, 0x24, 0x60, 0xEC,
-0x3E, 0xD7, 0x3E, 0xAD,
-0x2C, 0x80, 0x60, 0xEC,
+ 0x3E, 0xD7, 0x3E, 0xAD,
+ 0x2C, 0x80, 0x60, 0xEC,
-0x1C, 0x2B, 0xDE, 0xE8,
-0x23, 0x80, 0xDE, 0xE8,
+ 0x1C, 0x2B, 0xDE, 0xE8,
+ 0x23, 0x80, 0xDE, 0xE8,
-0x36, 0x80, 0x36, 0xBD,
-0x3E, 0x80, 0x3E, 0xBD,
+ 0x36, 0x80, 0x36, 0xBD,
+ 0x3E, 0x80, 0x3E, 0xBD,
-0x33, 0xD7, 0x1C, 0xBD,
-0x3B, 0xD7, 0x23, 0xBD,
+ 0x33, 0xD7, 0x1C, 0xBD,
+ 0x3B, 0xD7, 0x23, 0xBD,
-0x46, 0x80, 0x46, 0xCF,
-0x4F, 0x80, 0x4F, 0xCF,
+ 0x46, 0x80, 0x46, 0xCF,
+ 0x4F, 0x80, 0x4F, 0xCF,
-0x56, 0x33, 0x56, 0xCF,
-0x47, 0x3B, 0x47, 0xCF,
+ 0x56, 0x33, 0x56, 0xCF,
+ 0x47, 0x3B, 0x47, 0xCF,
-0xD6, 0xFF, 0x20, 0xEA,
-0x00, 0x80, 0x00, 0xE8,
+ 0xD6, 0xFF, 0x20, 0xEA,
+ 0x00, 0x80, 0x00, 0xE8,
-0x4E, 0x33, 0x4E, 0xCF,
-0x57, 0x3B, 0x57, 0xCF,
+ 0x4E, 0x33, 0x4E, 0xCF,
+ 0x57, 0x3B, 0x57, 0xCF,
-0x9D, 0xFF, 0x20, 0xEA,
-0x57, 0xC0, 0xBF, 0xEA,
+ 0x9D, 0xFF, 0x20, 0xEA,
+ 0x57, 0xC0, 0xBF, 0xEA,
-0x00, 0x80, 0xA0, 0xE9,
-0x00, 0x00, 0xD8, 0xEC,
+ 0x00, 0x80, 0xA0, 0xE9,
+ 0x00, 0x00, 0xD8, 0xEC,
};
static unsigned char warp_g400_tgza[] = {
-0x00, 0x88, 0x98, 0xE9,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x88, 0x98, 0xE9,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0xA0, 0xE9,
-0x00, 0x00, 0xD8, 0xEC,
+ 0x00, 0x80, 0xA0, 0xE9,
+ 0x00, 0x00, 0xD8, 0xEC,
-0xFF, 0x80, 0xC0, 0xE9,
-0x00, 0x80, 0x00, 0xE8,
+ 0xFF, 0x80, 0xC0, 0xE9,
+ 0x00, 0x80, 0x00, 0xE8,
-0x22, 0x40, 0x48, 0xBF,
-0x2A, 0x40, 0x50, 0xBF,
+ 0x22, 0x40, 0x48, 0xBF,
+ 0x2A, 0x40, 0x50, 0xBF,
-0x32, 0x41, 0x49, 0xBF,
-0x3A, 0x41, 0x51, 0xBF,
+ 0x32, 0x41, 0x49, 0xBF,
+ 0x3A, 0x41, 0x51, 0xBF,
-0xC3, 0x6B,
-0xCB, 0x6B,
-0x00, 0x88, 0x98, 0xE9,
+ 0xC3, 0x6B,
+ 0xCB, 0x6B,
+ 0x00, 0x88, 0x98, 0xE9,
-0x73, 0x7B, 0xC8, 0xEC,
-0x96, 0xE2,
-0x41, 0x04,
+ 0x73, 0x7B, 0xC8, 0xEC,
+ 0x96, 0xE2,
+ 0x41, 0x04,
-0x7B, 0x43, 0xA0, 0xE8,
-0x73, 0x4B, 0xA0, 0xE8,
+ 0x7B, 0x43, 0xA0, 0xE8,
+ 0x73, 0x4B, 0xA0, 0xE8,
-0xAD, 0xEE, 0x29, 0x9F,
-0x00, 0xE0,
-0x49, 0x04,
+ 0xAD, 0xEE, 0x29, 0x9F,
+ 0x00, 0xE0,
+ 0x49, 0x04,
-0x90, 0xE2,
-0x51, 0x04,
-0x31, 0x46, 0xB1, 0xE8,
+ 0x90, 0xE2,
+ 0x51, 0x04,
+ 0x31, 0x46, 0xB1, 0xE8,
-0x49, 0x41, 0xC0, 0xEC,
-0x39, 0x57, 0xB1, 0xE8,
+ 0x49, 0x41, 0xC0, 0xEC,
+ 0x39, 0x57, 0xB1, 0xE8,
-0x00, 0x04,
-0x46, 0xE2,
-0x73, 0x53, 0xA0, 0xE8,
+ 0x00, 0x04,
+ 0x46, 0xE2,
+ 0x73, 0x53, 0xA0, 0xE8,
-0x51, 0x41, 0xC0, 0xEC,
-0x31, 0x00,
-0x39, 0x00,
+ 0x51, 0x41, 0xC0, 0xEC,
+ 0x31, 0x00,
+ 0x39, 0x00,
-0x5C, 0x80, 0x15, 0xEA,
-0x08, 0x04,
-0x10, 0x04,
+ 0x5C, 0x80, 0x15, 0xEA,
+ 0x08, 0x04,
+ 0x10, 0x04,
-0x51, 0x49, 0xC0, 0xEC,
-0x2F, 0x41, 0x60, 0xEA,
+ 0x51, 0x49, 0xC0, 0xEC,
+ 0x2F, 0x41, 0x60, 0xEA,
-0x31, 0x20,
-0x39, 0x20,
-0x1F, 0x42, 0xA0, 0xE8,
+ 0x31, 0x20,
+ 0x39, 0x20,
+ 0x1F, 0x42, 0xA0, 0xE8,
-0x2A, 0x42, 0x4A, 0xBF,
-0x27, 0x4A, 0xA0, 0xE8,
+ 0x2A, 0x42, 0x4A, 0xBF,
+ 0x27, 0x4A, 0xA0, 0xE8,
-0x1A, 0x42, 0x52, 0xBF,
-0x1E, 0x49, 0x60, 0xEA,
+ 0x1A, 0x42, 0x52, 0xBF,
+ 0x1E, 0x49, 0x60, 0xEA,
-0x73, 0x7B, 0xC8, 0xEC,
-0x26, 0x51, 0x60, 0xEA,
+ 0x73, 0x7B, 0xC8, 0xEC,
+ 0x26, 0x51, 0x60, 0xEA,
-0x32, 0x40, 0x48, 0xBD,
-0x22, 0x40, 0x50, 0xBD,
+ 0x32, 0x40, 0x48, 0xBD,
+ 0x22, 0x40, 0x50, 0xBD,
-0x12, 0x41, 0x49, 0xBD,
-0x3A, 0x41, 0x51, 0xBD,
+ 0x12, 0x41, 0x49, 0xBD,
+ 0x3A, 0x41, 0x51, 0xBD,
-0xBF, 0x2F, 0x26, 0xBD,
-0x00, 0xE0,
-0x7B, 0x72,
+ 0xBF, 0x2F, 0x26, 0xBD,
+ 0x00, 0xE0,
+ 0x7B, 0x72,
-0x32, 0x20,
-0x22, 0x20,
-0x12, 0x20,
-0x3A, 0x20,
+ 0x32, 0x20,
+ 0x22, 0x20,
+ 0x12, 0x20,
+ 0x3A, 0x20,
-0x46, 0x31, 0x46, 0xBF,
-0x4E, 0x31, 0x4E, 0xBF,
+ 0x46, 0x31, 0x46, 0xBF,
+ 0x4E, 0x31, 0x4E, 0xBF,
-0xB3, 0xE2, 0x2D, 0x9F,
-0x00, 0x80, 0x00, 0xE8,
+ 0xB3, 0xE2, 0x2D, 0x9F,
+ 0x00, 0x80, 0x00, 0xE8,
-0x56, 0x31, 0x56, 0xBF,
-0x47, 0x39, 0x47, 0xBF,
+ 0x56, 0x31, 0x56, 0xBF,
+ 0x47, 0x39, 0x47, 0xBF,
-0x4F, 0x39, 0x4F, 0xBF,
-0x57, 0x39, 0x57, 0xBF,
+ 0x4F, 0x39, 0x4F, 0xBF,
+ 0x57, 0x39, 0x57, 0xBF,
-0x4E, 0x80, 0x07, 0xEA,
-0x24, 0x41, 0x20, 0xE9,
+ 0x4E, 0x80, 0x07, 0xEA,
+ 0x24, 0x41, 0x20, 0xE9,
-0x42, 0x73, 0xF8, 0xEC,
-0x00, 0xE0,
-0x2D, 0x73,
+ 0x42, 0x73, 0xF8, 0xEC,
+ 0x00, 0xE0,
+ 0x2D, 0x73,
-0x33, 0x72,
-0x0C, 0xE3,
-0xA5, 0x2F, 0x1E, 0xBD,
+ 0x33, 0x72,
+ 0x0C, 0xE3,
+ 0xA5, 0x2F, 0x1E, 0xBD,
-0x43, 0x43, 0x2D, 0xDF,
-0x4B, 0x4B, 0x2D, 0xDF,
+ 0x43, 0x43, 0x2D, 0xDF,
+ 0x4B, 0x4B, 0x2D, 0xDF,
-0xAE, 0x1E, 0x26, 0xBD,
-0x58, 0xE3,
-0x33, 0x66,
+ 0xAE, 0x1E, 0x26, 0xBD,
+ 0x58, 0xE3,
+ 0x33, 0x66,
-0x53, 0x53, 0x2D, 0xDF,
-0x00, 0x80, 0x00, 0xE8,
+ 0x53, 0x53, 0x2D, 0xDF,
+ 0x00, 0x80, 0x00, 0xE8,
-0xB8, 0x38, 0x33, 0xBF,
-0x00, 0xE0,
-0x59, 0xE3,
+ 0xB8, 0x38, 0x33, 0xBF,
+ 0x00, 0xE0,
+ 0x59, 0xE3,
-0x1E, 0x12, 0x41, 0xE9,
-0x1A, 0x22, 0x41, 0xE9,
+ 0x1E, 0x12, 0x41, 0xE9,
+ 0x1A, 0x22, 0x41, 0xE9,
-0x2B, 0x40, 0x3D, 0xE9,
-0x3F, 0x4B, 0xA0, 0xE8,
+ 0x2B, 0x40, 0x3D, 0xE9,
+ 0x3F, 0x4B, 0xA0, 0xE8,
-0x2D, 0x73,
-0x30, 0x76,
-0x05, 0x80, 0x3D, 0xEA,
+ 0x2D, 0x73,
+ 0x30, 0x76,
+ 0x05, 0x80, 0x3D, 0xEA,
-0x37, 0x43, 0xA0, 0xE8,
-0x3D, 0x53, 0xA0, 0xE8,
+ 0x37, 0x43, 0xA0, 0xE8,
+ 0x3D, 0x53, 0xA0, 0xE8,
-0x48, 0x70, 0xF8, 0xEC,
-0x2B, 0x48, 0x3C, 0xE9,
+ 0x48, 0x70, 0xF8, 0xEC,
+ 0x2B, 0x48, 0x3C, 0xE9,
-0x1F, 0x27, 0xBC, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x1F, 0x27, 0xBC, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x15, 0xC0, 0x20, 0xE9,
-0x15, 0xC0, 0x20, 0xE9,
+ 0x15, 0xC0, 0x20, 0xE9,
+ 0x15, 0xC0, 0x20, 0xE9,
-0x15, 0xC0, 0x20, 0xE9,
-0x15, 0xC0, 0x20, 0xE9,
+ 0x15, 0xC0, 0x20, 0xE9,
+ 0x15, 0xC0, 0x20, 0xE9,
-0x18, 0x3A, 0x41, 0xE9,
-0x1D, 0x32, 0x41, 0xE9,
+ 0x18, 0x3A, 0x41, 0xE9,
+ 0x1D, 0x32, 0x41, 0xE9,
-0x2A, 0x40, 0x20, 0xE9,
-0x56, 0x3D, 0x56, 0xDF,
+ 0x2A, 0x40, 0x20, 0xE9,
+ 0x56, 0x3D, 0x56, 0xDF,
-0x46, 0x37, 0x46, 0xDF,
-0x4E, 0x3F, 0x4E, 0xDF,
+ 0x46, 0x37, 0x46, 0xDF,
+ 0x4E, 0x3F, 0x4E, 0xDF,
-0x16, 0x30, 0x20, 0xE9,
-0x4F, 0x3F, 0x4F, 0xDF,
+ 0x16, 0x30, 0x20, 0xE9,
+ 0x4F, 0x3F, 0x4F, 0xDF,
-0x32, 0x32, 0x2D, 0xDF,
-0x22, 0x22, 0x2D, 0xDF,
+ 0x32, 0x32, 0x2D, 0xDF,
+ 0x22, 0x22, 0x2D, 0xDF,
-0x12, 0x12, 0x2D, 0xDF,
-0x3A, 0x3A, 0x2D, 0xDF,
+ 0x12, 0x12, 0x2D, 0xDF,
+ 0x3A, 0x3A, 0x2D, 0xDF,
-0x47, 0x37, 0x47, 0xDF,
-0x57, 0x3D, 0x57, 0xDF,
+ 0x47, 0x37, 0x47, 0xDF,
+ 0x57, 0x3D, 0x57, 0xDF,
-0x3D, 0xCF, 0x74, 0xC0,
-0x37, 0xCF, 0x74, 0xC4,
+ 0x3D, 0xCF, 0x74, 0xC0,
+ 0x37, 0xCF, 0x74, 0xC4,
-0x31, 0x53, 0x2F, 0x9F,
-0x34, 0x80, 0x20, 0xE9,
+ 0x31, 0x53, 0x2F, 0x9F,
+ 0x34, 0x80, 0x20, 0xE9,
-0x39, 0xE5, 0x2C, 0x9F,
-0x3C, 0x3D, 0x20, 0xE9,
+ 0x39, 0xE5, 0x2C, 0x9F,
+ 0x3C, 0x3D, 0x20, 0xE9,
-0x27, 0xCF, 0x74, 0xC6,
-0x3D, 0xCF, 0x74, 0xC2,
+ 0x27, 0xCF, 0x74, 0xC6,
+ 0x3D, 0xCF, 0x74, 0xC2,
-0x0A, 0x44, 0x4C, 0xB0,
-0x02, 0x44, 0x54, 0xB0,
+ 0x0A, 0x44, 0x4C, 0xB0,
+ 0x02, 0x44, 0x54, 0xB0,
-0x2A, 0x44, 0x4C, 0xB2,
-0x1A, 0x44, 0x54, 0xB2,
+ 0x2A, 0x44, 0x4C, 0xB2,
+ 0x1A, 0x44, 0x54, 0xB2,
-0x20, 0x80, 0x3A, 0xEA,
-0x0A, 0x20,
-0x02, 0x20,
+ 0x20, 0x80, 0x3A, 0xEA,
+ 0x0A, 0x20,
+ 0x02, 0x20,
-0x88, 0x73, 0x5E, 0xE9,
-0x2A, 0x20,
-0x1A, 0x20,
+ 0x88, 0x73, 0x5E, 0xE9,
+ 0x2A, 0x20,
+ 0x1A, 0x20,
-0x30, 0x50, 0x2E, 0x9F,
-0x32, 0x31, 0x5F, 0xE9,
+ 0x30, 0x50, 0x2E, 0x9F,
+ 0x32, 0x31, 0x5F, 0xE9,
-0x38, 0x21, 0x2C, 0x9F,
-0x33, 0x39, 0x5F, 0xE9,
+ 0x38, 0x21, 0x2C, 0x9F,
+ 0x33, 0x39, 0x5F, 0xE9,
-0x31, 0x53, 0x2F, 0x9F,
-0x9C, 0x27, 0x20, 0xE9,
+ 0x31, 0x53, 0x2F, 0x9F,
+ 0x9C, 0x27, 0x20, 0xE9,
-0x0A, 0x44, 0x4C, 0xB4,
-0x02, 0x44, 0x54, 0xB4,
+ 0x0A, 0x44, 0x4C, 0xB4,
+ 0x02, 0x44, 0x54, 0xB4,
-0x2A, 0x44, 0x4C, 0xB6,
-0x1A, 0x44, 0x54, 0xB6,
+ 0x2A, 0x44, 0x4C, 0xB6,
+ 0x1A, 0x44, 0x54, 0xB6,
-0x39, 0xE5, 0x2C, 0x9F,
-0x38, 0x3D, 0x20, 0xE9,
+ 0x39, 0xE5, 0x2C, 0x9F,
+ 0x38, 0x3D, 0x20, 0xE9,
-0x0A, 0x20,
-0x02, 0x20,
-0x2A, 0x20,
-0x1A, 0x20,
+ 0x0A, 0x20,
+ 0x02, 0x20,
+ 0x2A, 0x20,
+ 0x1A, 0x20,
-0x0A, 0x47, 0x4F, 0xBF,
-0x02, 0x47, 0x57, 0xBF,
+ 0x0A, 0x47, 0x4F, 0xBF,
+ 0x02, 0x47, 0x57, 0xBF,
-0x30, 0x50, 0x2E, 0x9F,
-0x3E, 0x30, 0x4F, 0xE9,
+ 0x30, 0x50, 0x2E, 0x9F,
+ 0x3E, 0x30, 0x4F, 0xE9,
-0x38, 0x21, 0x2C, 0x9F,
-0x3F, 0x38, 0x4F, 0xE9,
+ 0x38, 0x21, 0x2C, 0x9F,
+ 0x3F, 0x38, 0x4F, 0xE9,
-0x2A, 0x46, 0x4E, 0xBF,
-0x1A, 0x46, 0x56, 0xBF,
+ 0x2A, 0x46, 0x4E, 0xBF,
+ 0x1A, 0x46, 0x56, 0xBF,
-0x31, 0x53, 0x2F, 0x9F,
-0x3A, 0x31, 0x4F, 0xE9,
+ 0x31, 0x53, 0x2F, 0x9F,
+ 0x3A, 0x31, 0x4F, 0xE9,
-0x39, 0xE5, 0x2C, 0x9F,
-0x3B, 0x39, 0x4F, 0xE9,
+ 0x39, 0xE5, 0x2C, 0x9F,
+ 0x3B, 0x39, 0x4F, 0xE9,
-0x31, 0x53, 0x2F, 0x9F,
-0x36, 0x30, 0x4F, 0xE9,
+ 0x31, 0x53, 0x2F, 0x9F,
+ 0x36, 0x30, 0x4F, 0xE9,
-0x39, 0xE5, 0x2C, 0x9F,
-0x37, 0x38, 0x4F, 0xE9,
+ 0x39, 0xE5, 0x2C, 0x9F,
+ 0x37, 0x38, 0x4F, 0xE9,
-0x2A, 0x43, 0x4B, 0xBF,
-0x1A, 0x43, 0x53, 0xBF,
+ 0x2A, 0x43, 0x4B, 0xBF,
+ 0x1A, 0x43, 0x53, 0xBF,
-0x30, 0x50, 0x2E, 0x9F,
-0x9D, 0x31, 0x4F, 0xE9,
+ 0x30, 0x50, 0x2E, 0x9F,
+ 0x9D, 0x31, 0x4F, 0xE9,
-0x38, 0x21, 0x2C, 0x9F,
-0x9E, 0x39, 0x4F, 0xE9,
+ 0x38, 0x21, 0x2C, 0x9F,
+ 0x9E, 0x39, 0x4F, 0xE9,
-0x31, 0x53, 0x2F, 0x9F,
-0x80, 0x31, 0x57, 0xE9,
+ 0x31, 0x53, 0x2F, 0x9F,
+ 0x80, 0x31, 0x57, 0xE9,
-0x39, 0xE5, 0x2C, 0x9F,
-0x81, 0x39, 0x57, 0xE9,
+ 0x39, 0xE5, 0x2C, 0x9F,
+ 0x81, 0x39, 0x57, 0xE9,
-0x37, 0x48, 0x50, 0xBD,
-0x8A, 0x36, 0x20, 0xE9,
+ 0x37, 0x48, 0x50, 0xBD,
+ 0x8A, 0x36, 0x20, 0xE9,
-0x86, 0x76, 0x57, 0xE9,
-0x8B, 0x3E, 0x20, 0xE9,
+ 0x86, 0x76, 0x57, 0xE9,
+ 0x8B, 0x3E, 0x20, 0xE9,
-0x82, 0x30, 0x57, 0xE9,
-0x87, 0x77, 0x57, 0xE9,
+ 0x82, 0x30, 0x57, 0xE9,
+ 0x87, 0x77, 0x57, 0xE9,
-0x83, 0x38, 0x57, 0xE9,
-0x35, 0x49, 0x51, 0xBD,
+ 0x83, 0x38, 0x57, 0xE9,
+ 0x35, 0x49, 0x51, 0xBD,
-0x84, 0x31, 0x5E, 0xE9,
-0x30, 0x1F, 0x5F, 0xE9,
+ 0x84, 0x31, 0x5E, 0xE9,
+ 0x30, 0x1F, 0x5F, 0xE9,
-0x85, 0x39, 0x5E, 0xE9,
-0x57, 0x25, 0x20, 0xE9,
+ 0x85, 0x39, 0x5E, 0xE9,
+ 0x57, 0x25, 0x20, 0xE9,
-0x2B, 0x48, 0x20, 0xE9,
-0x1D, 0x37, 0xE1, 0xEA,
+ 0x2B, 0x48, 0x20, 0xE9,
+ 0x1D, 0x37, 0xE1, 0xEA,
-0x1E, 0x35, 0xE1, 0xEA,
-0x00, 0xE0,
-0x26, 0x77,
+ 0x1E, 0x35, 0xE1, 0xEA,
+ 0x00, 0xE0,
+ 0x26, 0x77,
-0x24, 0x49, 0x20, 0xE9,
-0xAB, 0xFF, 0x20, 0xEA,
+ 0x24, 0x49, 0x20, 0xE9,
+ 0xAB, 0xFF, 0x20, 0xEA,
-0x16, 0x26, 0x20, 0xE9,
-0x57, 0x2E, 0xBF, 0xEA,
+ 0x16, 0x26, 0x20, 0xE9,
+ 0x57, 0x2E, 0xBF, 0xEA,
-0x1C, 0x46, 0xA0, 0xE8,
-0x23, 0x4E, 0xA0, 0xE8,
+ 0x1C, 0x46, 0xA0, 0xE8,
+ 0x23, 0x4E, 0xA0, 0xE8,
-0x2B, 0x56, 0xA0, 0xE8,
-0x1D, 0x47, 0xA0, 0xE8,
+ 0x2B, 0x56, 0xA0, 0xE8,
+ 0x1D, 0x47, 0xA0, 0xE8,
-0x24, 0x4F, 0xA0, 0xE8,
-0x2C, 0x57, 0xA0, 0xE8,
+ 0x24, 0x4F, 0xA0, 0xE8,
+ 0x2C, 0x57, 0xA0, 0xE8,
-0x1C, 0x00,
-0x23, 0x00,
-0x2B, 0x00,
-0x00, 0xE0,
+ 0x1C, 0x00,
+ 0x23, 0x00,
+ 0x2B, 0x00,
+ 0x00, 0xE0,
-0x1D, 0x00,
-0x24, 0x00,
-0x2C, 0x00,
-0x00, 0xE0,
+ 0x1D, 0x00,
+ 0x24, 0x00,
+ 0x2C, 0x00,
+ 0x00, 0xE0,
-0x1C, 0x65,
-0x23, 0x65,
-0x2B, 0x65,
-0x00, 0xE0,
+ 0x1C, 0x65,
+ 0x23, 0x65,
+ 0x2B, 0x65,
+ 0x00, 0xE0,
-0x1D, 0x65,
-0x24, 0x65,
-0x2C, 0x65,
-0x00, 0xE0,
+ 0x1D, 0x65,
+ 0x24, 0x65,
+ 0x2C, 0x65,
+ 0x00, 0xE0,
-0x1C, 0x23, 0x60, 0xEC,
-0x36, 0xD7, 0x36, 0xAD,
+ 0x1C, 0x23, 0x60, 0xEC,
+ 0x36, 0xD7, 0x36, 0xAD,
-0x2B, 0x80, 0x60, 0xEC,
-0x1D, 0x24, 0x60, 0xEC,
+ 0x2B, 0x80, 0x60, 0xEC,
+ 0x1D, 0x24, 0x60, 0xEC,
-0x3E, 0xD7, 0x3E, 0xAD,
-0x2C, 0x80, 0x60, 0xEC,
+ 0x3E, 0xD7, 0x3E, 0xAD,
+ 0x2C, 0x80, 0x60, 0xEC,
-0x1C, 0x2B, 0xDE, 0xE8,
-0x23, 0x80, 0xDE, 0xE8,
+ 0x1C, 0x2B, 0xDE, 0xE8,
+ 0x23, 0x80, 0xDE, 0xE8,
-0x36, 0x80, 0x36, 0xBD,
-0x3E, 0x80, 0x3E, 0xBD,
+ 0x36, 0x80, 0x36, 0xBD,
+ 0x3E, 0x80, 0x3E, 0xBD,
-0x33, 0xD7, 0x1C, 0xBD,
-0x3B, 0xD7, 0x23, 0xBD,
+ 0x33, 0xD7, 0x1C, 0xBD,
+ 0x3B, 0xD7, 0x23, 0xBD,
-0x46, 0x80, 0x46, 0xCF,
-0x4F, 0x80, 0x4F, 0xCF,
+ 0x46, 0x80, 0x46, 0xCF,
+ 0x4F, 0x80, 0x4F, 0xCF,
-0x56, 0x33, 0x56, 0xCF,
-0x47, 0x3B, 0x47, 0xCF,
+ 0x56, 0x33, 0x56, 0xCF,
+ 0x47, 0x3B, 0x47, 0xCF,
-0xD3, 0xFF, 0x20, 0xEA,
-0x00, 0x80, 0x00, 0xE8,
+ 0xD3, 0xFF, 0x20, 0xEA,
+ 0x00, 0x80, 0x00, 0xE8,
-0x4E, 0x33, 0x4E, 0xCF,
-0x57, 0x3B, 0x57, 0xCF,
+ 0x4E, 0x33, 0x4E, 0xCF,
+ 0x57, 0x3B, 0x57, 0xCF,
-0x99, 0xFF, 0x20, 0xEA,
-0x57, 0xC0, 0xBF, 0xEA,
+ 0x99, 0xFF, 0x20, 0xEA,
+ 0x57, 0xC0, 0xBF, 0xEA,
-0x00, 0x80, 0xA0, 0xE9,
-0x00, 0x00, 0xD8, 0xEC,
+ 0x00, 0x80, 0xA0, 0xE9,
+ 0x00, 0x00, 0xD8, 0xEC,
};
static unsigned char warp_g400_tgzaf[] = {
-0x00, 0x88, 0x98, 0xE9,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x88, 0x98, 0xE9,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0xA0, 0xE9,
-0x00, 0x00, 0xD8, 0xEC,
+ 0x00, 0x80, 0xA0, 0xE9,
+ 0x00, 0x00, 0xD8, 0xEC,
-0xFF, 0x80, 0xC0, 0xE9,
-0x00, 0x80, 0x00, 0xE8,
+ 0xFF, 0x80, 0xC0, 0xE9,
+ 0x00, 0x80, 0x00, 0xE8,
-0x22, 0x40, 0x48, 0xBF,
-0x2A, 0x40, 0x50, 0xBF,
+ 0x22, 0x40, 0x48, 0xBF,
+ 0x2A, 0x40, 0x50, 0xBF,
-0x32, 0x41, 0x49, 0xBF,
-0x3A, 0x41, 0x51, 0xBF,
+ 0x32, 0x41, 0x49, 0xBF,
+ 0x3A, 0x41, 0x51, 0xBF,
-0xC3, 0x6B,
-0xCB, 0x6B,
-0x00, 0x88, 0x98, 0xE9,
+ 0xC3, 0x6B,
+ 0xCB, 0x6B,
+ 0x00, 0x88, 0x98, 0xE9,
-0x73, 0x7B, 0xC8, 0xEC,
-0x96, 0xE2,
-0x41, 0x04,
+ 0x73, 0x7B, 0xC8, 0xEC,
+ 0x96, 0xE2,
+ 0x41, 0x04,
-0x7B, 0x43, 0xA0, 0xE8,
-0x73, 0x4B, 0xA0, 0xE8,
+ 0x7B, 0x43, 0xA0, 0xE8,
+ 0x73, 0x4B, 0xA0, 0xE8,
-0xAD, 0xEE, 0x29, 0x9F,
-0x00, 0xE0,
-0x49, 0x04,
+ 0xAD, 0xEE, 0x29, 0x9F,
+ 0x00, 0xE0,
+ 0x49, 0x04,
-0x90, 0xE2,
-0x51, 0x04,
-0x31, 0x46, 0xB1, 0xE8,
+ 0x90, 0xE2,
+ 0x51, 0x04,
+ 0x31, 0x46, 0xB1, 0xE8,
-0x49, 0x41, 0xC0, 0xEC,
-0x39, 0x57, 0xB1, 0xE8,
+ 0x49, 0x41, 0xC0, 0xEC,
+ 0x39, 0x57, 0xB1, 0xE8,
-0x00, 0x04,
-0x46, 0xE2,
-0x73, 0x53, 0xA0, 0xE8,
+ 0x00, 0x04,
+ 0x46, 0xE2,
+ 0x73, 0x53, 0xA0, 0xE8,
-0x51, 0x41, 0xC0, 0xEC,
-0x31, 0x00,
-0x39, 0x00,
+ 0x51, 0x41, 0xC0, 0xEC,
+ 0x31, 0x00,
+ 0x39, 0x00,
-0x61, 0x80, 0x15, 0xEA,
-0x08, 0x04,
-0x10, 0x04,
+ 0x61, 0x80, 0x15, 0xEA,
+ 0x08, 0x04,
+ 0x10, 0x04,
-0x51, 0x49, 0xC0, 0xEC,
-0x2F, 0x41, 0x60, 0xEA,
+ 0x51, 0x49, 0xC0, 0xEC,
+ 0x2F, 0x41, 0x60, 0xEA,
-0x31, 0x20,
-0x39, 0x20,
-0x1F, 0x42, 0xA0, 0xE8,
+ 0x31, 0x20,
+ 0x39, 0x20,
+ 0x1F, 0x42, 0xA0, 0xE8,
-0x2A, 0x42, 0x4A, 0xBF,
-0x27, 0x4A, 0xA0, 0xE8,
+ 0x2A, 0x42, 0x4A, 0xBF,
+ 0x27, 0x4A, 0xA0, 0xE8,
-0x1A, 0x42, 0x52, 0xBF,
-0x1E, 0x49, 0x60, 0xEA,
+ 0x1A, 0x42, 0x52, 0xBF,
+ 0x1E, 0x49, 0x60, 0xEA,
-0x73, 0x7B, 0xC8, 0xEC,
-0x26, 0x51, 0x60, 0xEA,
+ 0x73, 0x7B, 0xC8, 0xEC,
+ 0x26, 0x51, 0x60, 0xEA,
-0x32, 0x40, 0x48, 0xBD,
-0x22, 0x40, 0x50, 0xBD,
+ 0x32, 0x40, 0x48, 0xBD,
+ 0x22, 0x40, 0x50, 0xBD,
-0x12, 0x41, 0x49, 0xBD,
-0x3A, 0x41, 0x51, 0xBD,
+ 0x12, 0x41, 0x49, 0xBD,
+ 0x3A, 0x41, 0x51, 0xBD,
-0xBF, 0x2F, 0x26, 0xBD,
-0x00, 0xE0,
-0x7B, 0x72,
+ 0xBF, 0x2F, 0x26, 0xBD,
+ 0x00, 0xE0,
+ 0x7B, 0x72,
-0x32, 0x20,
-0x22, 0x20,
-0x12, 0x20,
-0x3A, 0x20,
+ 0x32, 0x20,
+ 0x22, 0x20,
+ 0x12, 0x20,
+ 0x3A, 0x20,
-0x46, 0x31, 0x46, 0xBF,
-0x4E, 0x31, 0x4E, 0xBF,
+ 0x46, 0x31, 0x46, 0xBF,
+ 0x4E, 0x31, 0x4E, 0xBF,
-0xB3, 0xE2, 0x2D, 0x9F,
-0x00, 0x80, 0x00, 0xE8,
+ 0xB3, 0xE2, 0x2D, 0x9F,
+ 0x00, 0x80, 0x00, 0xE8,
-0x56, 0x31, 0x56, 0xBF,
-0x47, 0x39, 0x47, 0xBF,
+ 0x56, 0x31, 0x56, 0xBF,
+ 0x47, 0x39, 0x47, 0xBF,
-0x4F, 0x39, 0x4F, 0xBF,
-0x57, 0x39, 0x57, 0xBF,
+ 0x4F, 0x39, 0x4F, 0xBF,
+ 0x57, 0x39, 0x57, 0xBF,
-0x53, 0x80, 0x07, 0xEA,
-0x24, 0x41, 0x20, 0xE9,
+ 0x53, 0x80, 0x07, 0xEA,
+ 0x24, 0x41, 0x20, 0xE9,
-0x42, 0x73, 0xF8, 0xEC,
-0x00, 0xE0,
-0x2D, 0x73,
+ 0x42, 0x73, 0xF8, 0xEC,
+ 0x00, 0xE0,
+ 0x2D, 0x73,
-0x33, 0x72,
-0x0C, 0xE3,
-0xA5, 0x2F, 0x1E, 0xBD,
+ 0x33, 0x72,
+ 0x0C, 0xE3,
+ 0xA5, 0x2F, 0x1E, 0xBD,
-0x43, 0x43, 0x2D, 0xDF,
-0x4B, 0x4B, 0x2D, 0xDF,
+ 0x43, 0x43, 0x2D, 0xDF,
+ 0x4B, 0x4B, 0x2D, 0xDF,
-0xAE, 0x1E, 0x26, 0xBD,
-0x58, 0xE3,
-0x33, 0x66,
+ 0xAE, 0x1E, 0x26, 0xBD,
+ 0x58, 0xE3,
+ 0x33, 0x66,
-0x53, 0x53, 0x2D, 0xDF,
-0x00, 0x80, 0x00, 0xE8,
+ 0x53, 0x53, 0x2D, 0xDF,
+ 0x00, 0x80, 0x00, 0xE8,
-0xB8, 0x38, 0x33, 0xBF,
-0x00, 0xE0,
-0x59, 0xE3,
+ 0xB8, 0x38, 0x33, 0xBF,
+ 0x00, 0xE0,
+ 0x59, 0xE3,
-0x1E, 0x12, 0x41, 0xE9,
-0x1A, 0x22, 0x41, 0xE9,
+ 0x1E, 0x12, 0x41, 0xE9,
+ 0x1A, 0x22, 0x41, 0xE9,
-0x2B, 0x40, 0x3D, 0xE9,
-0x3F, 0x4B, 0xA0, 0xE8,
+ 0x2B, 0x40, 0x3D, 0xE9,
+ 0x3F, 0x4B, 0xA0, 0xE8,
-0x2D, 0x73,
-0x30, 0x76,
-0x05, 0x80, 0x3D, 0xEA,
+ 0x2D, 0x73,
+ 0x30, 0x76,
+ 0x05, 0x80, 0x3D, 0xEA,
-0x37, 0x43, 0xA0, 0xE8,
-0x3D, 0x53, 0xA0, 0xE8,
+ 0x37, 0x43, 0xA0, 0xE8,
+ 0x3D, 0x53, 0xA0, 0xE8,
-0x48, 0x70, 0xF8, 0xEC,
-0x2B, 0x48, 0x3C, 0xE9,
+ 0x48, 0x70, 0xF8, 0xEC,
+ 0x2B, 0x48, 0x3C, 0xE9,
-0x1F, 0x27, 0xBC, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x1F, 0x27, 0xBC, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x15, 0xC0, 0x20, 0xE9,
-0x15, 0xC0, 0x20, 0xE9,
+ 0x15, 0xC0, 0x20, 0xE9,
+ 0x15, 0xC0, 0x20, 0xE9,
-0x15, 0xC0, 0x20, 0xE9,
-0x15, 0xC0, 0x20, 0xE9,
+ 0x15, 0xC0, 0x20, 0xE9,
+ 0x15, 0xC0, 0x20, 0xE9,
-0x18, 0x3A, 0x41, 0xE9,
-0x1D, 0x32, 0x41, 0xE9,
+ 0x18, 0x3A, 0x41, 0xE9,
+ 0x1D, 0x32, 0x41, 0xE9,
-0x2A, 0x40, 0x20, 0xE9,
-0x56, 0x3D, 0x56, 0xDF,
+ 0x2A, 0x40, 0x20, 0xE9,
+ 0x56, 0x3D, 0x56, 0xDF,
-0x46, 0x37, 0x46, 0xDF,
-0x4E, 0x3F, 0x4E, 0xDF,
+ 0x46, 0x37, 0x46, 0xDF,
+ 0x4E, 0x3F, 0x4E, 0xDF,
-0x16, 0x30, 0x20, 0xE9,
-0x4F, 0x3F, 0x4F, 0xDF,
+ 0x16, 0x30, 0x20, 0xE9,
+ 0x4F, 0x3F, 0x4F, 0xDF,
-0x32, 0x32, 0x2D, 0xDF,
-0x22, 0x22, 0x2D, 0xDF,
+ 0x32, 0x32, 0x2D, 0xDF,
+ 0x22, 0x22, 0x2D, 0xDF,
-0x12, 0x12, 0x2D, 0xDF,
-0x3A, 0x3A, 0x2D, 0xDF,
+ 0x12, 0x12, 0x2D, 0xDF,
+ 0x3A, 0x3A, 0x2D, 0xDF,
-0x47, 0x37, 0x47, 0xDF,
-0x57, 0x3D, 0x57, 0xDF,
+ 0x47, 0x37, 0x47, 0xDF,
+ 0x57, 0x3D, 0x57, 0xDF,
-0x3D, 0xCF, 0x74, 0xC0,
-0x37, 0xCF, 0x74, 0xC4,
+ 0x3D, 0xCF, 0x74, 0xC0,
+ 0x37, 0xCF, 0x74, 0xC4,
-0x0A, 0x44, 0x4C, 0xB0,
-0x02, 0x44, 0x54, 0xB0,
+ 0x0A, 0x44, 0x4C, 0xB0,
+ 0x02, 0x44, 0x54, 0xB0,
-0x31, 0x53, 0x2F, 0x9F,
-0x34, 0x37, 0x20, 0xE9,
+ 0x31, 0x53, 0x2F, 0x9F,
+ 0x34, 0x37, 0x20, 0xE9,
-0x39, 0xE5, 0x2C, 0x9F,
-0x3C, 0x3D, 0x20, 0xE9,
+ 0x39, 0xE5, 0x2C, 0x9F,
+ 0x3C, 0x3D, 0x20, 0xE9,
-0x2A, 0x44, 0x4C, 0xB2,
-0x1A, 0x44, 0x54, 0xB2,
+ 0x2A, 0x44, 0x4C, 0xB2,
+ 0x1A, 0x44, 0x54, 0xB2,
-0x26, 0x80, 0x3A, 0xEA,
-0x0A, 0x20,
-0x02, 0x20,
+ 0x26, 0x80, 0x3A, 0xEA,
+ 0x0A, 0x20,
+ 0x02, 0x20,
-0x88, 0x73, 0x5E, 0xE9,
-0x2A, 0x20,
-0x1A, 0x20,
+ 0x88, 0x73, 0x5E, 0xE9,
+ 0x2A, 0x20,
+ 0x1A, 0x20,
-0x3D, 0xCF, 0x74, 0xC2,
-0x27, 0xCF, 0x74, 0xC6,
+ 0x3D, 0xCF, 0x74, 0xC2,
+ 0x27, 0xCF, 0x74, 0xC6,
-0x30, 0x50, 0x2E, 0x9F,
-0x32, 0x31, 0x5F, 0xE9,
+ 0x30, 0x50, 0x2E, 0x9F,
+ 0x32, 0x31, 0x5F, 0xE9,
-0x38, 0x21, 0x2C, 0x9F,
-0x33, 0x39, 0x5F, 0xE9,
+ 0x38, 0x21, 0x2C, 0x9F,
+ 0x33, 0x39, 0x5F, 0xE9,
-0x31, 0x53, 0x2F, 0x9F,
-0x9C, 0x27, 0x20, 0xE9,
+ 0x31, 0x53, 0x2F, 0x9F,
+ 0x9C, 0x27, 0x20, 0xE9,
-0x0A, 0x44, 0x4C, 0xB4,
-0x02, 0x44, 0x54, 0xB4,
+ 0x0A, 0x44, 0x4C, 0xB4,
+ 0x02, 0x44, 0x54, 0xB4,
-0x2A, 0x44, 0x4C, 0xB6,
-0x1A, 0x44, 0x54, 0xB6,
+ 0x2A, 0x44, 0x4C, 0xB6,
+ 0x1A, 0x44, 0x54, 0xB6,
-0x39, 0xE5, 0x2C, 0x9F,
-0x38, 0x3D, 0x20, 0xE9,
+ 0x39, 0xE5, 0x2C, 0x9F,
+ 0x38, 0x3D, 0x20, 0xE9,
-0x0A, 0x20,
-0x02, 0x20,
-0x2A, 0x20,
-0x1A, 0x20,
+ 0x0A, 0x20,
+ 0x02, 0x20,
+ 0x2A, 0x20,
+ 0x1A, 0x20,
-0x3D, 0xCF, 0x75, 0xC6,
-0x00, 0x80, 0x00, 0xE8,
+ 0x3D, 0xCF, 0x75, 0xC6,
+ 0x00, 0x80, 0x00, 0xE8,
-0x30, 0x50, 0x2E, 0x9F,
-0x3E, 0x30, 0x4F, 0xE9,
+ 0x30, 0x50, 0x2E, 0x9F,
+ 0x3E, 0x30, 0x4F, 0xE9,
-0x38, 0x21, 0x2C, 0x9F,
-0x3F, 0x38, 0x4F, 0xE9,
+ 0x38, 0x21, 0x2C, 0x9F,
+ 0x3F, 0x38, 0x4F, 0xE9,
-0x0A, 0x45, 0x4D, 0xB6,
-0x02, 0x45, 0x55, 0xB6,
+ 0x0A, 0x45, 0x4D, 0xB6,
+ 0x02, 0x45, 0x55, 0xB6,
-0x31, 0x53, 0x2F, 0x9F,
-0x3A, 0x31, 0x4F, 0xE9,
+ 0x31, 0x53, 0x2F, 0x9F,
+ 0x3A, 0x31, 0x4F, 0xE9,
-0x39, 0xE5, 0x2C, 0x9F,
-0x3B, 0x39, 0x4F, 0xE9,
+ 0x39, 0xE5, 0x2C, 0x9F,
+ 0x3B, 0x39, 0x4F, 0xE9,
-0x31, 0x3D, 0x20, 0xE9,
-0x0A, 0x20,
-0x02, 0x20,
+ 0x31, 0x3D, 0x20, 0xE9,
+ 0x0A, 0x20,
+ 0x02, 0x20,
-0x2A, 0x46, 0x4E, 0xBF,
-0x1A, 0x46, 0x56, 0xBF,
+ 0x2A, 0x46, 0x4E, 0xBF,
+ 0x1A, 0x46, 0x56, 0xBF,
-0x0A, 0x47, 0x4F, 0xBF,
-0x02, 0x47, 0x57, 0xBF,
+ 0x0A, 0x47, 0x4F, 0xBF,
+ 0x02, 0x47, 0x57, 0xBF,
-0x30, 0x50, 0x2E, 0x9F,
-0x36, 0x30, 0x4F, 0xE9,
+ 0x30, 0x50, 0x2E, 0x9F,
+ 0x36, 0x30, 0x4F, 0xE9,
-0x38, 0x21, 0x2C, 0x9F,
-0x37, 0x38, 0x4F, 0xE9,
+ 0x38, 0x21, 0x2C, 0x9F,
+ 0x37, 0x38, 0x4F, 0xE9,
-0x31, 0x53, 0x2F, 0x9F,
-0x9D, 0x31, 0x4F, 0xE9,
+ 0x31, 0x53, 0x2F, 0x9F,
+ 0x9D, 0x31, 0x4F, 0xE9,
-0x39, 0xE5, 0x2C, 0x9F,
-0x9E, 0x39, 0x4F, 0xE9,
+ 0x39, 0xE5, 0x2C, 0x9F,
+ 0x9E, 0x39, 0x4F, 0xE9,
-0x2A, 0x43, 0x4B, 0xBF,
-0x1A, 0x43, 0x53, 0xBF,
+ 0x2A, 0x43, 0x4B, 0xBF,
+ 0x1A, 0x43, 0x53, 0xBF,
-0x30, 0x50, 0x2E, 0x9F,
-0x35, 0x30, 0x4F, 0xE9,
+ 0x30, 0x50, 0x2E, 0x9F,
+ 0x35, 0x30, 0x4F, 0xE9,
-0x38, 0x21, 0x2C, 0x9F,
-0x39, 0x38, 0x4F, 0xE9,
+ 0x38, 0x21, 0x2C, 0x9F,
+ 0x39, 0x38, 0x4F, 0xE9,
-0x31, 0x53, 0x2F, 0x9F,
-0x80, 0x31, 0x57, 0xE9,
+ 0x31, 0x53, 0x2F, 0x9F,
+ 0x80, 0x31, 0x57, 0xE9,
-0x39, 0xE5, 0x2C, 0x9F,
-0x81, 0x39, 0x57, 0xE9,
+ 0x39, 0xE5, 0x2C, 0x9F,
+ 0x81, 0x39, 0x57, 0xE9,
-0x37, 0x48, 0x50, 0xBD,
-0x8A, 0x36, 0x20, 0xE9,
+ 0x37, 0x48, 0x50, 0xBD,
+ 0x8A, 0x36, 0x20, 0xE9,
-0x86, 0x76, 0x57, 0xE9,
-0x8B, 0x3E, 0x20, 0xE9,
+ 0x86, 0x76, 0x57, 0xE9,
+ 0x8B, 0x3E, 0x20, 0xE9,
-0x82, 0x30, 0x57, 0xE9,
-0x87, 0x77, 0x57, 0xE9,
+ 0x82, 0x30, 0x57, 0xE9,
+ 0x87, 0x77, 0x57, 0xE9,
-0x83, 0x38, 0x57, 0xE9,
-0x35, 0x49, 0x51, 0xBD,
+ 0x83, 0x38, 0x57, 0xE9,
+ 0x35, 0x49, 0x51, 0xBD,
-0x84, 0x31, 0x5E, 0xE9,
-0x30, 0x1F, 0x5F, 0xE9,
+ 0x84, 0x31, 0x5E, 0xE9,
+ 0x30, 0x1F, 0x5F, 0xE9,
-0x85, 0x39, 0x5E, 0xE9,
-0x57, 0x25, 0x20, 0xE9,
+ 0x85, 0x39, 0x5E, 0xE9,
+ 0x57, 0x25, 0x20, 0xE9,
-0x2B, 0x48, 0x20, 0xE9,
-0x1D, 0x37, 0xE1, 0xEA,
+ 0x2B, 0x48, 0x20, 0xE9,
+ 0x1D, 0x37, 0xE1, 0xEA,
-0x1E, 0x35, 0xE1, 0xEA,
-0x00, 0xE0,
-0x26, 0x77,
+ 0x1E, 0x35, 0xE1, 0xEA,
+ 0x00, 0xE0,
+ 0x26, 0x77,
-0x24, 0x49, 0x20, 0xE9,
-0xA6, 0xFF, 0x20, 0xEA,
+ 0x24, 0x49, 0x20, 0xE9,
+ 0xA6, 0xFF, 0x20, 0xEA,
-0x16, 0x26, 0x20, 0xE9,
-0x57, 0x2E, 0xBF, 0xEA,
+ 0x16, 0x26, 0x20, 0xE9,
+ 0x57, 0x2E, 0xBF, 0xEA,
-0x1C, 0x46, 0xA0, 0xE8,
-0x23, 0x4E, 0xA0, 0xE8,
+ 0x1C, 0x46, 0xA0, 0xE8,
+ 0x23, 0x4E, 0xA0, 0xE8,
-0x2B, 0x56, 0xA0, 0xE8,
-0x1D, 0x47, 0xA0, 0xE8,
+ 0x2B, 0x56, 0xA0, 0xE8,
+ 0x1D, 0x47, 0xA0, 0xE8,
-0x24, 0x4F, 0xA0, 0xE8,
-0x2C, 0x57, 0xA0, 0xE8,
+ 0x24, 0x4F, 0xA0, 0xE8,
+ 0x2C, 0x57, 0xA0, 0xE8,
-0x1C, 0x00,
-0x23, 0x00,
-0x2B, 0x00,
-0x00, 0xE0,
+ 0x1C, 0x00,
+ 0x23, 0x00,
+ 0x2B, 0x00,
+ 0x00, 0xE0,
-0x1D, 0x00,
-0x24, 0x00,
-0x2C, 0x00,
-0x00, 0xE0,
+ 0x1D, 0x00,
+ 0x24, 0x00,
+ 0x2C, 0x00,
+ 0x00, 0xE0,
-0x1C, 0x65,
-0x23, 0x65,
-0x2B, 0x65,
-0x00, 0xE0,
+ 0x1C, 0x65,
+ 0x23, 0x65,
+ 0x2B, 0x65,
+ 0x00, 0xE0,
-0x1D, 0x65,
-0x24, 0x65,
-0x2C, 0x65,
-0x00, 0xE0,
+ 0x1D, 0x65,
+ 0x24, 0x65,
+ 0x2C, 0x65,
+ 0x00, 0xE0,
-0x1C, 0x23, 0x60, 0xEC,
-0x36, 0xD7, 0x36, 0xAD,
+ 0x1C, 0x23, 0x60, 0xEC,
+ 0x36, 0xD7, 0x36, 0xAD,
-0x2B, 0x80, 0x60, 0xEC,
-0x1D, 0x24, 0x60, 0xEC,
+ 0x2B, 0x80, 0x60, 0xEC,
+ 0x1D, 0x24, 0x60, 0xEC,
-0x3E, 0xD7, 0x3E, 0xAD,
-0x2C, 0x80, 0x60, 0xEC,
+ 0x3E, 0xD7, 0x3E, 0xAD,
+ 0x2C, 0x80, 0x60, 0xEC,
-0x1C, 0x2B, 0xDE, 0xE8,
-0x23, 0x80, 0xDE, 0xE8,
+ 0x1C, 0x2B, 0xDE, 0xE8,
+ 0x23, 0x80, 0xDE, 0xE8,
-0x36, 0x80, 0x36, 0xBD,
-0x3E, 0x80, 0x3E, 0xBD,
+ 0x36, 0x80, 0x36, 0xBD,
+ 0x3E, 0x80, 0x3E, 0xBD,
-0x33, 0xD7, 0x1C, 0xBD,
-0x3B, 0xD7, 0x23, 0xBD,
+ 0x33, 0xD7, 0x1C, 0xBD,
+ 0x3B, 0xD7, 0x23, 0xBD,
-0x46, 0x80, 0x46, 0xCF,
-0x4F, 0x80, 0x4F, 0xCF,
+ 0x46, 0x80, 0x46, 0xCF,
+ 0x4F, 0x80, 0x4F, 0xCF,
-0x56, 0x33, 0x56, 0xCF,
-0x47, 0x3B, 0x47, 0xCF,
+ 0x56, 0x33, 0x56, 0xCF,
+ 0x47, 0x3B, 0x47, 0xCF,
-0xCD, 0xFF, 0x20, 0xEA,
-0x00, 0x80, 0x00, 0xE8,
+ 0xCD, 0xFF, 0x20, 0xEA,
+ 0x00, 0x80, 0x00, 0xE8,
-0x4E, 0x33, 0x4E, 0xCF,
-0x57, 0x3B, 0x57, 0xCF,
+ 0x4E, 0x33, 0x4E, 0xCF,
+ 0x57, 0x3B, 0x57, 0xCF,
-0x94, 0xFF, 0x20, 0xEA,
-0x57, 0xC0, 0xBF, 0xEA,
+ 0x94, 0xFF, 0x20, 0xEA,
+ 0x57, 0xC0, 0xBF, 0xEA,
-0x00, 0x80, 0xA0, 0xE9,
-0x00, 0x00, 0xD8, 0xEC,
+ 0x00, 0x80, 0xA0, 0xE9,
+ 0x00, 0x00, 0xD8, 0xEC,
};
static unsigned char warp_g400_tgzf[] = {
-0x00, 0x88, 0x98, 0xE9,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x88, 0x98, 0xE9,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0xA0, 0xE9,
-0x00, 0x00, 0xD8, 0xEC,
+ 0x00, 0x80, 0xA0, 0xE9,
+ 0x00, 0x00, 0xD8, 0xEC,
-0xFF, 0x80, 0xC0, 0xE9,
-0x00, 0x80, 0x00, 0xE8,
+ 0xFF, 0x80, 0xC0, 0xE9,
+ 0x00, 0x80, 0x00, 0xE8,
-0x22, 0x40, 0x48, 0xBF,
-0x2A, 0x40, 0x50, 0xBF,
+ 0x22, 0x40, 0x48, 0xBF,
+ 0x2A, 0x40, 0x50, 0xBF,
-0x32, 0x41, 0x49, 0xBF,
-0x3A, 0x41, 0x51, 0xBF,
+ 0x32, 0x41, 0x49, 0xBF,
+ 0x3A, 0x41, 0x51, 0xBF,
-0xC3, 0x6B,
-0xCB, 0x6B,
-0x00, 0x88, 0x98, 0xE9,
+ 0xC3, 0x6B,
+ 0xCB, 0x6B,
+ 0x00, 0x88, 0x98, 0xE9,
-0x73, 0x7B, 0xC8, 0xEC,
-0x96, 0xE2,
-0x41, 0x04,
+ 0x73, 0x7B, 0xC8, 0xEC,
+ 0x96, 0xE2,
+ 0x41, 0x04,
-0x7B, 0x43, 0xA0, 0xE8,
-0x73, 0x4B, 0xA0, 0xE8,
+ 0x7B, 0x43, 0xA0, 0xE8,
+ 0x73, 0x4B, 0xA0, 0xE8,
-0xAD, 0xEE, 0x29, 0x9F,
-0x00, 0xE0,
-0x49, 0x04,
+ 0xAD, 0xEE, 0x29, 0x9F,
+ 0x00, 0xE0,
+ 0x49, 0x04,
-0x90, 0xE2,
-0x51, 0x04,
-0x31, 0x46, 0xB1, 0xE8,
+ 0x90, 0xE2,
+ 0x51, 0x04,
+ 0x31, 0x46, 0xB1, 0xE8,
-0x49, 0x41, 0xC0, 0xEC,
-0x39, 0x57, 0xB1, 0xE8,
+ 0x49, 0x41, 0xC0, 0xEC,
+ 0x39, 0x57, 0xB1, 0xE8,
-0x00, 0x04,
-0x46, 0xE2,
-0x73, 0x53, 0xA0, 0xE8,
+ 0x00, 0x04,
+ 0x46, 0xE2,
+ 0x73, 0x53, 0xA0, 0xE8,
-0x51, 0x41, 0xC0, 0xEC,
-0x31, 0x00,
-0x39, 0x00,
+ 0x51, 0x41, 0xC0, 0xEC,
+ 0x31, 0x00,
+ 0x39, 0x00,
-0x5D, 0x80, 0x15, 0xEA,
-0x08, 0x04,
-0x10, 0x04,
+ 0x5D, 0x80, 0x15, 0xEA,
+ 0x08, 0x04,
+ 0x10, 0x04,
-0x51, 0x49, 0xC0, 0xEC,
-0x2F, 0x41, 0x60, 0xEA,
+ 0x51, 0x49, 0xC0, 0xEC,
+ 0x2F, 0x41, 0x60, 0xEA,
-0x31, 0x20,
-0x39, 0x20,
-0x1F, 0x42, 0xA0, 0xE8,
+ 0x31, 0x20,
+ 0x39, 0x20,
+ 0x1F, 0x42, 0xA0, 0xE8,
-0x2A, 0x42, 0x4A, 0xBF,
-0x27, 0x4A, 0xA0, 0xE8,
+ 0x2A, 0x42, 0x4A, 0xBF,
+ 0x27, 0x4A, 0xA0, 0xE8,
-0x1A, 0x42, 0x52, 0xBF,
-0x1E, 0x49, 0x60, 0xEA,
+ 0x1A, 0x42, 0x52, 0xBF,
+ 0x1E, 0x49, 0x60, 0xEA,
-0x73, 0x7B, 0xC8, 0xEC,
-0x26, 0x51, 0x60, 0xEA,
+ 0x73, 0x7B, 0xC8, 0xEC,
+ 0x26, 0x51, 0x60, 0xEA,
-0x32, 0x40, 0x48, 0xBD,
-0x22, 0x40, 0x50, 0xBD,
+ 0x32, 0x40, 0x48, 0xBD,
+ 0x22, 0x40, 0x50, 0xBD,
-0x12, 0x41, 0x49, 0xBD,
-0x3A, 0x41, 0x51, 0xBD,
+ 0x12, 0x41, 0x49, 0xBD,
+ 0x3A, 0x41, 0x51, 0xBD,
-0xBF, 0x2F, 0x26, 0xBD,
-0x00, 0xE0,
-0x7B, 0x72,
+ 0xBF, 0x2F, 0x26, 0xBD,
+ 0x00, 0xE0,
+ 0x7B, 0x72,
-0x32, 0x20,
-0x22, 0x20,
-0x12, 0x20,
-0x3A, 0x20,
+ 0x32, 0x20,
+ 0x22, 0x20,
+ 0x12, 0x20,
+ 0x3A, 0x20,
-0x46, 0x31, 0x46, 0xBF,
-0x4E, 0x31, 0x4E, 0xBF,
+ 0x46, 0x31, 0x46, 0xBF,
+ 0x4E, 0x31, 0x4E, 0xBF,
-0xB3, 0xE2, 0x2D, 0x9F,
-0x00, 0x80, 0x00, 0xE8,
+ 0xB3, 0xE2, 0x2D, 0x9F,
+ 0x00, 0x80, 0x00, 0xE8,
-0x56, 0x31, 0x56, 0xBF,
-0x47, 0x39, 0x47, 0xBF,
+ 0x56, 0x31, 0x56, 0xBF,
+ 0x47, 0x39, 0x47, 0xBF,
-0x4F, 0x39, 0x4F, 0xBF,
-0x57, 0x39, 0x57, 0xBF,
+ 0x4F, 0x39, 0x4F, 0xBF,
+ 0x57, 0x39, 0x57, 0xBF,
-0x4F, 0x80, 0x07, 0xEA,
-0x24, 0x41, 0x20, 0xE9,
+ 0x4F, 0x80, 0x07, 0xEA,
+ 0x24, 0x41, 0x20, 0xE9,
-0x42, 0x73, 0xF8, 0xEC,
-0x00, 0xE0,
-0x2D, 0x73,
+ 0x42, 0x73, 0xF8, 0xEC,
+ 0x00, 0xE0,
+ 0x2D, 0x73,
-0x33, 0x72,
-0x0C, 0xE3,
-0xA5, 0x2F, 0x1E, 0xBD,
+ 0x33, 0x72,
+ 0x0C, 0xE3,
+ 0xA5, 0x2F, 0x1E, 0xBD,
-0x43, 0x43, 0x2D, 0xDF,
-0x4B, 0x4B, 0x2D, 0xDF,
+ 0x43, 0x43, 0x2D, 0xDF,
+ 0x4B, 0x4B, 0x2D, 0xDF,
-0xAE, 0x1E, 0x26, 0xBD,
-0x58, 0xE3,
-0x33, 0x66,
+ 0xAE, 0x1E, 0x26, 0xBD,
+ 0x58, 0xE3,
+ 0x33, 0x66,
-0x53, 0x53, 0x2D, 0xDF,
-0x00, 0x80, 0x00, 0xE8,
+ 0x53, 0x53, 0x2D, 0xDF,
+ 0x00, 0x80, 0x00, 0xE8,
-0xB8, 0x38, 0x33, 0xBF,
-0x00, 0xE0,
-0x59, 0xE3,
+ 0xB8, 0x38, 0x33, 0xBF,
+ 0x00, 0xE0,
+ 0x59, 0xE3,
-0x1E, 0x12, 0x41, 0xE9,
-0x1A, 0x22, 0x41, 0xE9,
+ 0x1E, 0x12, 0x41, 0xE9,
+ 0x1A, 0x22, 0x41, 0xE9,
-0x2B, 0x40, 0x3D, 0xE9,
-0x3F, 0x4B, 0xA0, 0xE8,
+ 0x2B, 0x40, 0x3D, 0xE9,
+ 0x3F, 0x4B, 0xA0, 0xE8,
-0x2D, 0x73,
-0x30, 0x76,
-0x05, 0x80, 0x3D, 0xEA,
+ 0x2D, 0x73,
+ 0x30, 0x76,
+ 0x05, 0x80, 0x3D, 0xEA,
-0x37, 0x43, 0xA0, 0xE8,
-0x3D, 0x53, 0xA0, 0xE8,
+ 0x37, 0x43, 0xA0, 0xE8,
+ 0x3D, 0x53, 0xA0, 0xE8,
-0x48, 0x70, 0xF8, 0xEC,
-0x2B, 0x48, 0x3C, 0xE9,
+ 0x48, 0x70, 0xF8, 0xEC,
+ 0x2B, 0x48, 0x3C, 0xE9,
-0x1F, 0x27, 0xBC, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x1F, 0x27, 0xBC, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x15, 0xC0, 0x20, 0xE9,
-0x15, 0xC0, 0x20, 0xE9,
+ 0x15, 0xC0, 0x20, 0xE9,
+ 0x15, 0xC0, 0x20, 0xE9,
-0x15, 0xC0, 0x20, 0xE9,
-0x15, 0xC0, 0x20, 0xE9,
+ 0x15, 0xC0, 0x20, 0xE9,
+ 0x15, 0xC0, 0x20, 0xE9,
-0x18, 0x3A, 0x41, 0xE9,
-0x1D, 0x32, 0x41, 0xE9,
+ 0x18, 0x3A, 0x41, 0xE9,
+ 0x1D, 0x32, 0x41, 0xE9,
-0x2A, 0x40, 0x20, 0xE9,
-0x56, 0x3D, 0x56, 0xDF,
+ 0x2A, 0x40, 0x20, 0xE9,
+ 0x56, 0x3D, 0x56, 0xDF,
-0x46, 0x37, 0x46, 0xDF,
-0x4E, 0x3F, 0x4E, 0xDF,
+ 0x46, 0x37, 0x46, 0xDF,
+ 0x4E, 0x3F, 0x4E, 0xDF,
-0x16, 0x30, 0x20, 0xE9,
-0x4F, 0x3F, 0x4F, 0xDF,
+ 0x16, 0x30, 0x20, 0xE9,
+ 0x4F, 0x3F, 0x4F, 0xDF,
-0x32, 0x32, 0x2D, 0xDF,
-0x22, 0x22, 0x2D, 0xDF,
+ 0x32, 0x32, 0x2D, 0xDF,
+ 0x22, 0x22, 0x2D, 0xDF,
-0x12, 0x12, 0x2D, 0xDF,
-0x3A, 0x3A, 0x2D, 0xDF,
+ 0x12, 0x12, 0x2D, 0xDF,
+ 0x3A, 0x3A, 0x2D, 0xDF,
-0x47, 0x37, 0x47, 0xDF,
-0x57, 0x3D, 0x57, 0xDF,
+ 0x47, 0x37, 0x47, 0xDF,
+ 0x57, 0x3D, 0x57, 0xDF,
-0x3D, 0xCF, 0x74, 0xC0,
-0x37, 0xCF, 0x74, 0xC4,
+ 0x3D, 0xCF, 0x74, 0xC0,
+ 0x37, 0xCF, 0x74, 0xC4,
-0x39, 0xE5, 0x2C, 0x9F,
-0x34, 0x80, 0x20, 0xE9,
+ 0x39, 0xE5, 0x2C, 0x9F,
+ 0x34, 0x80, 0x20, 0xE9,
-0x31, 0x53, 0x2F, 0x9F,
-0x00, 0x80, 0x00, 0xE8,
+ 0x31, 0x53, 0x2F, 0x9F,
+ 0x00, 0x80, 0x00, 0xE8,
-0x88, 0x73, 0x5E, 0xE9,
-0x00, 0x80, 0x00, 0xE8,
+ 0x88, 0x73, 0x5E, 0xE9,
+ 0x00, 0x80, 0x00, 0xE8,
-0x27, 0xCF, 0x75, 0xC6,
-0x3C, 0x3D, 0x20, 0xE9,
+ 0x27, 0xCF, 0x75, 0xC6,
+ 0x3C, 0x3D, 0x20, 0xE9,
-0x0A, 0x44, 0x4C, 0xB0,
-0x02, 0x44, 0x54, 0xB0,
+ 0x0A, 0x44, 0x4C, 0xB0,
+ 0x02, 0x44, 0x54, 0xB0,
-0x2A, 0x44, 0x4C, 0xB2,
-0x1A, 0x44, 0x54, 0xB2,
+ 0x2A, 0x44, 0x4C, 0xB2,
+ 0x1A, 0x44, 0x54, 0xB2,
-0x20, 0x80, 0x3A, 0xEA,
-0x0A, 0x20,
-0x02, 0x20,
+ 0x20, 0x80, 0x3A, 0xEA,
+ 0x0A, 0x20,
+ 0x02, 0x20,
-0x3D, 0xCF, 0x74, 0xC2,
-0x2A, 0x20,
-0x1A, 0x20,
+ 0x3D, 0xCF, 0x74, 0xC2,
+ 0x2A, 0x20,
+ 0x1A, 0x20,
-0x30, 0x50, 0x2E, 0x9F,
-0x32, 0x31, 0x5F, 0xE9,
+ 0x30, 0x50, 0x2E, 0x9F,
+ 0x32, 0x31, 0x5F, 0xE9,
-0x38, 0x21, 0x2C, 0x9F,
-0x33, 0x39, 0x5F, 0xE9,
+ 0x38, 0x21, 0x2C, 0x9F,
+ 0x33, 0x39, 0x5F, 0xE9,
-0x31, 0x53, 0x2F, 0x9F,
-0x31, 0x27, 0x20, 0xE9,
+ 0x31, 0x53, 0x2F, 0x9F,
+ 0x31, 0x27, 0x20, 0xE9,
-0x0A, 0x44, 0x4C, 0xB4,
-0x02, 0x44, 0x54, 0xB4,
+ 0x0A, 0x44, 0x4C, 0xB4,
+ 0x02, 0x44, 0x54, 0xB4,
-0x2A, 0x45, 0x4D, 0xB6,
-0x1A, 0x45, 0x55, 0xB6,
+ 0x2A, 0x45, 0x4D, 0xB6,
+ 0x1A, 0x45, 0x55, 0xB6,
-0x39, 0xE5, 0x2C, 0x9F,
-0x38, 0x3D, 0x20, 0xE9,
+ 0x39, 0xE5, 0x2C, 0x9F,
+ 0x38, 0x3D, 0x20, 0xE9,
-0x0A, 0x20,
-0x02, 0x20,
-0x2A, 0x20,
-0x1A, 0x20,
+ 0x0A, 0x20,
+ 0x02, 0x20,
+ 0x2A, 0x20,
+ 0x1A, 0x20,
-0x0A, 0x47, 0x4F, 0xBF,
-0x02, 0x47, 0x57, 0xBF,
+ 0x0A, 0x47, 0x4F, 0xBF,
+ 0x02, 0x47, 0x57, 0xBF,
-0x30, 0x50, 0x2E, 0x9F,
-0x3E, 0x30, 0x4F, 0xE9,
+ 0x30, 0x50, 0x2E, 0x9F,
+ 0x3E, 0x30, 0x4F, 0xE9,
-0x38, 0x21, 0x2C, 0x9F,
-0x3F, 0x38, 0x4F, 0xE9,
+ 0x38, 0x21, 0x2C, 0x9F,
+ 0x3F, 0x38, 0x4F, 0xE9,
-0x2A, 0x46, 0x4E, 0xBF,
-0x1A, 0x46, 0x56, 0xBF,
+ 0x2A, 0x46, 0x4E, 0xBF,
+ 0x1A, 0x46, 0x56, 0xBF,
-0x31, 0x53, 0x2F, 0x9F,
-0x3A, 0x31, 0x4F, 0xE9,
+ 0x31, 0x53, 0x2F, 0x9F,
+ 0x3A, 0x31, 0x4F, 0xE9,
-0x39, 0xE5, 0x2C, 0x9F,
-0x3B, 0x39, 0x4F, 0xE9,
+ 0x39, 0xE5, 0x2C, 0x9F,
+ 0x3B, 0x39, 0x4F, 0xE9,
-0x31, 0x53, 0x2F, 0x9F,
-0x36, 0x30, 0x4F, 0xE9,
+ 0x31, 0x53, 0x2F, 0x9F,
+ 0x36, 0x30, 0x4F, 0xE9,
-0x39, 0xE5, 0x2C, 0x9F,
-0x37, 0x38, 0x4F, 0xE9,
+ 0x39, 0xE5, 0x2C, 0x9F,
+ 0x37, 0x38, 0x4F, 0xE9,
-0x2A, 0x43, 0x4B, 0xBF,
-0x1A, 0x43, 0x53, 0xBF,
+ 0x2A, 0x43, 0x4B, 0xBF,
+ 0x1A, 0x43, 0x53, 0xBF,
-0x30, 0x50, 0x2E, 0x9F,
-0x35, 0x31, 0x4F, 0xE9,
+ 0x30, 0x50, 0x2E, 0x9F,
+ 0x35, 0x31, 0x4F, 0xE9,
-0x38, 0x21, 0x2C, 0x9F,
-0x39, 0x39, 0x4F, 0xE9,
+ 0x38, 0x21, 0x2C, 0x9F,
+ 0x39, 0x39, 0x4F, 0xE9,
-0x31, 0x53, 0x2F, 0x9F,
-0x80, 0x31, 0x57, 0xE9,
+ 0x31, 0x53, 0x2F, 0x9F,
+ 0x80, 0x31, 0x57, 0xE9,
-0x39, 0xE5, 0x2C, 0x9F,
-0x81, 0x39, 0x57, 0xE9,
+ 0x39, 0xE5, 0x2C, 0x9F,
+ 0x81, 0x39, 0x57, 0xE9,
-0x37, 0x48, 0x50, 0xBD,
-0x8A, 0x36, 0x20, 0xE9,
+ 0x37, 0x48, 0x50, 0xBD,
+ 0x8A, 0x36, 0x20, 0xE9,
-0x86, 0x76, 0x57, 0xE9,
-0x8B, 0x3E, 0x20, 0xE9,
+ 0x86, 0x76, 0x57, 0xE9,
+ 0x8B, 0x3E, 0x20, 0xE9,
-0x82, 0x30, 0x57, 0xE9,
-0x87, 0x77, 0x57, 0xE9,
+ 0x82, 0x30, 0x57, 0xE9,
+ 0x87, 0x77, 0x57, 0xE9,
-0x83, 0x38, 0x57, 0xE9,
-0x35, 0x49, 0x51, 0xBD,
+ 0x83, 0x38, 0x57, 0xE9,
+ 0x35, 0x49, 0x51, 0xBD,
-0x84, 0x31, 0x5E, 0xE9,
-0x30, 0x1F, 0x5F, 0xE9,
+ 0x84, 0x31, 0x5E, 0xE9,
+ 0x30, 0x1F, 0x5F, 0xE9,
-0x85, 0x39, 0x5E, 0xE9,
-0x57, 0x25, 0x20, 0xE9,
+ 0x85, 0x39, 0x5E, 0xE9,
+ 0x57, 0x25, 0x20, 0xE9,
-0x2B, 0x48, 0x20, 0xE9,
-0x1D, 0x37, 0xE1, 0xEA,
+ 0x2B, 0x48, 0x20, 0xE9,
+ 0x1D, 0x37, 0xE1, 0xEA,
-0x1E, 0x35, 0xE1, 0xEA,
-0x00, 0xE0,
-0x26, 0x77,
+ 0x1E, 0x35, 0xE1, 0xEA,
+ 0x00, 0xE0,
+ 0x26, 0x77,
-0x24, 0x49, 0x20, 0xE9,
-0xAA, 0xFF, 0x20, 0xEA,
+ 0x24, 0x49, 0x20, 0xE9,
+ 0xAA, 0xFF, 0x20, 0xEA,
-0x16, 0x26, 0x20, 0xE9,
-0x57, 0x2E, 0xBF, 0xEA,
+ 0x16, 0x26, 0x20, 0xE9,
+ 0x57, 0x2E, 0xBF, 0xEA,
-0x1C, 0x46, 0xA0, 0xE8,
-0x23, 0x4E, 0xA0, 0xE8,
+ 0x1C, 0x46, 0xA0, 0xE8,
+ 0x23, 0x4E, 0xA0, 0xE8,
-0x2B, 0x56, 0xA0, 0xE8,
-0x1D, 0x47, 0xA0, 0xE8,
+ 0x2B, 0x56, 0xA0, 0xE8,
+ 0x1D, 0x47, 0xA0, 0xE8,
-0x24, 0x4F, 0xA0, 0xE8,
-0x2C, 0x57, 0xA0, 0xE8,
+ 0x24, 0x4F, 0xA0, 0xE8,
+ 0x2C, 0x57, 0xA0, 0xE8,
-0x1C, 0x00,
-0x23, 0x00,
-0x2B, 0x00,
-0x00, 0xE0,
+ 0x1C, 0x00,
+ 0x23, 0x00,
+ 0x2B, 0x00,
+ 0x00, 0xE0,
-0x1D, 0x00,
-0x24, 0x00,
-0x2C, 0x00,
-0x00, 0xE0,
+ 0x1D, 0x00,
+ 0x24, 0x00,
+ 0x2C, 0x00,
+ 0x00, 0xE0,
-0x1C, 0x65,
-0x23, 0x65,
-0x2B, 0x65,
-0x00, 0xE0,
+ 0x1C, 0x65,
+ 0x23, 0x65,
+ 0x2B, 0x65,
+ 0x00, 0xE0,
-0x1D, 0x65,
-0x24, 0x65,
-0x2C, 0x65,
-0x00, 0xE0,
+ 0x1D, 0x65,
+ 0x24, 0x65,
+ 0x2C, 0x65,
+ 0x00, 0xE0,
-0x1C, 0x23, 0x60, 0xEC,
-0x36, 0xD7, 0x36, 0xAD,
+ 0x1C, 0x23, 0x60, 0xEC,
+ 0x36, 0xD7, 0x36, 0xAD,
-0x2B, 0x80, 0x60, 0xEC,
-0x1D, 0x24, 0x60, 0xEC,
+ 0x2B, 0x80, 0x60, 0xEC,
+ 0x1D, 0x24, 0x60, 0xEC,
-0x3E, 0xD7, 0x3E, 0xAD,
-0x2C, 0x80, 0x60, 0xEC,
+ 0x3E, 0xD7, 0x3E, 0xAD,
+ 0x2C, 0x80, 0x60, 0xEC,
-0x1C, 0x2B, 0xDE, 0xE8,
-0x23, 0x80, 0xDE, 0xE8,
+ 0x1C, 0x2B, 0xDE, 0xE8,
+ 0x23, 0x80, 0xDE, 0xE8,
-0x36, 0x80, 0x36, 0xBD,
-0x3E, 0x80, 0x3E, 0xBD,
+ 0x36, 0x80, 0x36, 0xBD,
+ 0x3E, 0x80, 0x3E, 0xBD,
-0x33, 0xD7, 0x1C, 0xBD,
-0x3B, 0xD7, 0x23, 0xBD,
+ 0x33, 0xD7, 0x1C, 0xBD,
+ 0x3B, 0xD7, 0x23, 0xBD,
-0x46, 0x80, 0x46, 0xCF,
-0x4F, 0x80, 0x4F, 0xCF,
+ 0x46, 0x80, 0x46, 0xCF,
+ 0x4F, 0x80, 0x4F, 0xCF,
-0x56, 0x33, 0x56, 0xCF,
-0x47, 0x3B, 0x47, 0xCF,
+ 0x56, 0x33, 0x56, 0xCF,
+ 0x47, 0x3B, 0x47, 0xCF,
-0xD3, 0xFF, 0x20, 0xEA,
-0x00, 0x80, 0x00, 0xE8,
+ 0xD3, 0xFF, 0x20, 0xEA,
+ 0x00, 0x80, 0x00, 0xE8,
-0x4E, 0x33, 0x4E, 0xCF,
-0x57, 0x3B, 0x57, 0xCF,
+ 0x4E, 0x33, 0x4E, 0xCF,
+ 0x57, 0x3B, 0x57, 0xCF,
-0x98, 0xFF, 0x20, 0xEA,
-0x57, 0xC0, 0xBF, 0xEA,
+ 0x98, 0xFF, 0x20, 0xEA,
+ 0x57, 0xC0, 0xBF, 0xEA,
-0x00, 0x80, 0xA0, 0xE9,
-0x00, 0x00, 0xD8, 0xEC,
+ 0x00, 0x80, 0xA0, 0xE9,
+ 0x00, 0x00, 0xD8, 0xEC,
};
static unsigned char warp_g400_tgzs[] = {
-0x00, 0x88, 0x98, 0xE9,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x88, 0x98, 0xE9,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0xA0, 0xE9,
-0x00, 0x00, 0xD8, 0xEC,
+ 0x00, 0x80, 0xA0, 0xE9,
+ 0x00, 0x00, 0xD8, 0xEC,
-0xFF, 0x80, 0xC0, 0xE9,
-0x00, 0x80, 0x00, 0xE8,
+ 0xFF, 0x80, 0xC0, 0xE9,
+ 0x00, 0x80, 0x00, 0xE8,
-0x22, 0x40, 0x48, 0xBF,
-0x2A, 0x40, 0x50, 0xBF,
+ 0x22, 0x40, 0x48, 0xBF,
+ 0x2A, 0x40, 0x50, 0xBF,
-0x32, 0x41, 0x49, 0xBF,
-0x3A, 0x41, 0x51, 0xBF,
+ 0x32, 0x41, 0x49, 0xBF,
+ 0x3A, 0x41, 0x51, 0xBF,
-0xC3, 0x6B,
-0xCB, 0x6B,
-0x00, 0x88, 0x98, 0xE9,
+ 0xC3, 0x6B,
+ 0xCB, 0x6B,
+ 0x00, 0x88, 0x98, 0xE9,
-0x73, 0x7B, 0xC8, 0xEC,
-0x96, 0xE2,
-0x41, 0x04,
+ 0x73, 0x7B, 0xC8, 0xEC,
+ 0x96, 0xE2,
+ 0x41, 0x04,
-0x7B, 0x43, 0xA0, 0xE8,
-0x73, 0x4B, 0xA0, 0xE8,
+ 0x7B, 0x43, 0xA0, 0xE8,
+ 0x73, 0x4B, 0xA0, 0xE8,
-0xAD, 0xEE, 0x29, 0x9F,
-0x00, 0xE0,
-0x49, 0x04,
+ 0xAD, 0xEE, 0x29, 0x9F,
+ 0x00, 0xE0,
+ 0x49, 0x04,
-0x90, 0xE2,
-0x51, 0x04,
-0x31, 0x46, 0xB1, 0xE8,
+ 0x90, 0xE2,
+ 0x51, 0x04,
+ 0x31, 0x46, 0xB1, 0xE8,
-0x49, 0x41, 0xC0, 0xEC,
-0x39, 0x57, 0xB1, 0xE8,
+ 0x49, 0x41, 0xC0, 0xEC,
+ 0x39, 0x57, 0xB1, 0xE8,
-0x00, 0x04,
-0x46, 0xE2,
-0x73, 0x53, 0xA0, 0xE8,
+ 0x00, 0x04,
+ 0x46, 0xE2,
+ 0x73, 0x53, 0xA0, 0xE8,
-0x51, 0x41, 0xC0, 0xEC,
-0x31, 0x00,
-0x39, 0x00,
+ 0x51, 0x41, 0xC0, 0xEC,
+ 0x31, 0x00,
+ 0x39, 0x00,
-0x65, 0x80, 0x15, 0xEA,
-0x08, 0x04,
-0x10, 0x04,
+ 0x65, 0x80, 0x15, 0xEA,
+ 0x08, 0x04,
+ 0x10, 0x04,
-0x51, 0x49, 0xC0, 0xEC,
-0x2F, 0x41, 0x60, 0xEA,
+ 0x51, 0x49, 0xC0, 0xEC,
+ 0x2F, 0x41, 0x60, 0xEA,
-0x31, 0x20,
-0x39, 0x20,
-0x1F, 0x42, 0xA0, 0xE8,
+ 0x31, 0x20,
+ 0x39, 0x20,
+ 0x1F, 0x42, 0xA0, 0xE8,
-0x2A, 0x42, 0x4A, 0xBF,
-0x27, 0x4A, 0xA0, 0xE8,
+ 0x2A, 0x42, 0x4A, 0xBF,
+ 0x27, 0x4A, 0xA0, 0xE8,
-0x1A, 0x42, 0x52, 0xBF,
-0x1E, 0x49, 0x60, 0xEA,
+ 0x1A, 0x42, 0x52, 0xBF,
+ 0x1E, 0x49, 0x60, 0xEA,
-0x73, 0x7B, 0xC8, 0xEC,
-0x26, 0x51, 0x60, 0xEA,
+ 0x73, 0x7B, 0xC8, 0xEC,
+ 0x26, 0x51, 0x60, 0xEA,
-0x32, 0x40, 0x48, 0xBD,
-0x22, 0x40, 0x50, 0xBD,
+ 0x32, 0x40, 0x48, 0xBD,
+ 0x22, 0x40, 0x50, 0xBD,
-0x12, 0x41, 0x49, 0xBD,
-0x3A, 0x41, 0x51, 0xBD,
+ 0x12, 0x41, 0x49, 0xBD,
+ 0x3A, 0x41, 0x51, 0xBD,
-0xBF, 0x2F, 0x26, 0xBD,
-0x00, 0xE0,
-0x7B, 0x72,
+ 0xBF, 0x2F, 0x26, 0xBD,
+ 0x00, 0xE0,
+ 0x7B, 0x72,
-0x32, 0x20,
-0x22, 0x20,
-0x12, 0x20,
-0x3A, 0x20,
+ 0x32, 0x20,
+ 0x22, 0x20,
+ 0x12, 0x20,
+ 0x3A, 0x20,
-0x46, 0x31, 0x46, 0xBF,
-0x4E, 0x31, 0x4E, 0xBF,
+ 0x46, 0x31, 0x46, 0xBF,
+ 0x4E, 0x31, 0x4E, 0xBF,
-0xB3, 0xE2, 0x2D, 0x9F,
-0x00, 0x80, 0x00, 0xE8,
+ 0xB3, 0xE2, 0x2D, 0x9F,
+ 0x00, 0x80, 0x00, 0xE8,
-0x56, 0x31, 0x56, 0xBF,
-0x47, 0x39, 0x47, 0xBF,
+ 0x56, 0x31, 0x56, 0xBF,
+ 0x47, 0x39, 0x47, 0xBF,
-0x4F, 0x39, 0x4F, 0xBF,
-0x57, 0x39, 0x57, 0xBF,
+ 0x4F, 0x39, 0x4F, 0xBF,
+ 0x57, 0x39, 0x57, 0xBF,
-0x57, 0x80, 0x07, 0xEA,
-0x24, 0x41, 0x20, 0xE9,
+ 0x57, 0x80, 0x07, 0xEA,
+ 0x24, 0x41, 0x20, 0xE9,
-0x42, 0x73, 0xF8, 0xEC,
-0x00, 0xE0,
-0x2D, 0x73,
+ 0x42, 0x73, 0xF8, 0xEC,
+ 0x00, 0xE0,
+ 0x2D, 0x73,
-0x33, 0x72,
-0x0C, 0xE3,
-0xA5, 0x2F, 0x1E, 0xBD,
+ 0x33, 0x72,
+ 0x0C, 0xE3,
+ 0xA5, 0x2F, 0x1E, 0xBD,
-0x43, 0x43, 0x2D, 0xDF,
-0x4B, 0x4B, 0x2D, 0xDF,
+ 0x43, 0x43, 0x2D, 0xDF,
+ 0x4B, 0x4B, 0x2D, 0xDF,
-0xAE, 0x1E, 0x26, 0xBD,
-0x58, 0xE3,
-0x33, 0x66,
+ 0xAE, 0x1E, 0x26, 0xBD,
+ 0x58, 0xE3,
+ 0x33, 0x66,
-0x53, 0x53, 0x2D, 0xDF,
-0x00, 0x80, 0x00, 0xE8,
+ 0x53, 0x53, 0x2D, 0xDF,
+ 0x00, 0x80, 0x00, 0xE8,
-0xB8, 0x38, 0x33, 0xBF,
-0x00, 0xE0,
-0x59, 0xE3,
+ 0xB8, 0x38, 0x33, 0xBF,
+ 0x00, 0xE0,
+ 0x59, 0xE3,
-0x1E, 0x12, 0x41, 0xE9,
-0x1A, 0x22, 0x41, 0xE9,
+ 0x1E, 0x12, 0x41, 0xE9,
+ 0x1A, 0x22, 0x41, 0xE9,
-0x2B, 0x40, 0x3D, 0xE9,
-0x3F, 0x4B, 0xA0, 0xE8,
+ 0x2B, 0x40, 0x3D, 0xE9,
+ 0x3F, 0x4B, 0xA0, 0xE8,
-0x2D, 0x73,
-0x30, 0x76,
-0x05, 0x80, 0x3D, 0xEA,
+ 0x2D, 0x73,
+ 0x30, 0x76,
+ 0x05, 0x80, 0x3D, 0xEA,
-0x37, 0x43, 0xA0, 0xE8,
-0x3D, 0x53, 0xA0, 0xE8,
+ 0x37, 0x43, 0xA0, 0xE8,
+ 0x3D, 0x53, 0xA0, 0xE8,
-0x48, 0x70, 0xF8, 0xEC,
-0x2B, 0x48, 0x3C, 0xE9,
+ 0x48, 0x70, 0xF8, 0xEC,
+ 0x2B, 0x48, 0x3C, 0xE9,
-0x1F, 0x27, 0xBC, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x1F, 0x27, 0xBC, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x15, 0xC0, 0x20, 0xE9,
-0x15, 0xC0, 0x20, 0xE9,
+ 0x15, 0xC0, 0x20, 0xE9,
+ 0x15, 0xC0, 0x20, 0xE9,
-0x15, 0xC0, 0x20, 0xE9,
-0x15, 0xC0, 0x20, 0xE9,
+ 0x15, 0xC0, 0x20, 0xE9,
+ 0x15, 0xC0, 0x20, 0xE9,
-0x18, 0x3A, 0x41, 0xE9,
-0x1D, 0x32, 0x41, 0xE9,
+ 0x18, 0x3A, 0x41, 0xE9,
+ 0x1D, 0x32, 0x41, 0xE9,
-0x2A, 0x40, 0x20, 0xE9,
-0x56, 0x3D, 0x56, 0xDF,
+ 0x2A, 0x40, 0x20, 0xE9,
+ 0x56, 0x3D, 0x56, 0xDF,
-0x46, 0x37, 0x46, 0xDF,
-0x4E, 0x3F, 0x4E, 0xDF,
+ 0x46, 0x37, 0x46, 0xDF,
+ 0x4E, 0x3F, 0x4E, 0xDF,
-0x16, 0x30, 0x20, 0xE9,
-0x4F, 0x3F, 0x4F, 0xDF,
+ 0x16, 0x30, 0x20, 0xE9,
+ 0x4F, 0x3F, 0x4F, 0xDF,
-0x47, 0x37, 0x47, 0xDF,
-0x57, 0x3D, 0x57, 0xDF,
+ 0x47, 0x37, 0x47, 0xDF,
+ 0x57, 0x3D, 0x57, 0xDF,
-0x32, 0x32, 0x2D, 0xDF,
-0x22, 0x22, 0x2D, 0xDF,
+ 0x32, 0x32, 0x2D, 0xDF,
+ 0x22, 0x22, 0x2D, 0xDF,
-0x12, 0x12, 0x2D, 0xDF,
-0x3A, 0x3A, 0x2D, 0xDF,
+ 0x12, 0x12, 0x2D, 0xDF,
+ 0x3A, 0x3A, 0x2D, 0xDF,
-0x27, 0xCF, 0x74, 0xC2,
-0x37, 0xCF, 0x74, 0xC4,
+ 0x27, 0xCF, 0x74, 0xC2,
+ 0x37, 0xCF, 0x74, 0xC4,
-0x0A, 0x44, 0x4C, 0xB0,
-0x02, 0x44, 0x54, 0xB0,
+ 0x0A, 0x44, 0x4C, 0xB0,
+ 0x02, 0x44, 0x54, 0xB0,
-0x3D, 0xCF, 0x74, 0xC0,
-0x34, 0x37, 0x20, 0xE9,
+ 0x3D, 0xCF, 0x74, 0xC0,
+ 0x34, 0x37, 0x20, 0xE9,
-0x31, 0x53, 0x2F, 0x9F,
-0x38, 0x27, 0x20, 0xE9,
+ 0x31, 0x53, 0x2F, 0x9F,
+ 0x38, 0x27, 0x20, 0xE9,
-0x39, 0xE5, 0x2C, 0x9F,
-0x3C, 0x3D, 0x20, 0xE9,
+ 0x39, 0xE5, 0x2C, 0x9F,
+ 0x3C, 0x3D, 0x20, 0xE9,
-0x2A, 0x44, 0x4C, 0xB2,
-0x1A, 0x44, 0x54, 0xB2,
+ 0x2A, 0x44, 0x4C, 0xB2,
+ 0x1A, 0x44, 0x54, 0xB2,
-0x29, 0x80, 0x3A, 0xEA,
-0x0A, 0x20,
-0x02, 0x20,
+ 0x29, 0x80, 0x3A, 0xEA,
+ 0x0A, 0x20,
+ 0x02, 0x20,
-0x27, 0xCF, 0x75, 0xC0,
-0x2A, 0x20,
-0x1A, 0x20,
+ 0x27, 0xCF, 0x75, 0xC0,
+ 0x2A, 0x20,
+ 0x1A, 0x20,
-0x30, 0x50, 0x2E, 0x9F,
-0x32, 0x31, 0x5F, 0xE9,
+ 0x30, 0x50, 0x2E, 0x9F,
+ 0x32, 0x31, 0x5F, 0xE9,
-0x38, 0x21, 0x2C, 0x9F,
-0x33, 0x39, 0x5F, 0xE9,
+ 0x38, 0x21, 0x2C, 0x9F,
+ 0x33, 0x39, 0x5F, 0xE9,
-0x3D, 0xCF, 0x75, 0xC2,
-0x37, 0xCF, 0x75, 0xC4,
+ 0x3D, 0xCF, 0x75, 0xC2,
+ 0x37, 0xCF, 0x75, 0xC4,
-0x31, 0x53, 0x2F, 0x9F,
-0xA6, 0x27, 0x20, 0xE9,
+ 0x31, 0x53, 0x2F, 0x9F,
+ 0xA6, 0x27, 0x20, 0xE9,
-0x39, 0xE5, 0x2C, 0x9F,
-0xA3, 0x3D, 0x20, 0xE9,
+ 0x39, 0xE5, 0x2C, 0x9F,
+ 0xA3, 0x3D, 0x20, 0xE9,
-0x2A, 0x44, 0x4C, 0xB4,
-0x1A, 0x44, 0x54, 0xB4,
+ 0x2A, 0x44, 0x4C, 0xB4,
+ 0x1A, 0x44, 0x54, 0xB4,
-0x0A, 0x45, 0x4D, 0xB0,
-0x02, 0x45, 0x55, 0xB0,
+ 0x0A, 0x45, 0x4D, 0xB0,
+ 0x02, 0x45, 0x55, 0xB0,
-0x88, 0x73, 0x5E, 0xE9,
-0x2A, 0x20,
-0x1A, 0x20,
+ 0x88, 0x73, 0x5E, 0xE9,
+ 0x2A, 0x20,
+ 0x1A, 0x20,
-0xA0, 0x37, 0x20, 0xE9,
-0x0A, 0x20,
-0x02, 0x20,
+ 0xA0, 0x37, 0x20, 0xE9,
+ 0x0A, 0x20,
+ 0x02, 0x20,
-0x31, 0x53, 0x2F, 0x9F,
-0x3E, 0x30, 0x4F, 0xE9,
+ 0x31, 0x53, 0x2F, 0x9F,
+ 0x3E, 0x30, 0x4F, 0xE9,
-0x39, 0xE5, 0x2C, 0x9F,
-0x3F, 0x38, 0x4F, 0xE9,
+ 0x39, 0xE5, 0x2C, 0x9F,
+ 0x3F, 0x38, 0x4F, 0xE9,
-0x30, 0x50, 0x2E, 0x9F,
-0x3A, 0x31, 0x4F, 0xE9,
+ 0x30, 0x50, 0x2E, 0x9F,
+ 0x3A, 0x31, 0x4F, 0xE9,
-0x2A, 0x45, 0x4D, 0xB2,
-0x1A, 0x45, 0x55, 0xB2,
+ 0x2A, 0x45, 0x4D, 0xB2,
+ 0x1A, 0x45, 0x55, 0xB2,
-0x0A, 0x45, 0x4D, 0xB4,
-0x02, 0x45, 0x55, 0xB4,
+ 0x0A, 0x45, 0x4D, 0xB4,
+ 0x02, 0x45, 0x55, 0xB4,
-0x38, 0x21, 0x2C, 0x9F,
-0x3B, 0x39, 0x4F, 0xE9,
+ 0x38, 0x21, 0x2C, 0x9F,
+ 0x3B, 0x39, 0x4F, 0xE9,
-0x0A, 0x20,
-0x02, 0x20,
-0x2A, 0x20,
-0x1A, 0x20,
+ 0x0A, 0x20,
+ 0x02, 0x20,
+ 0x2A, 0x20,
+ 0x1A, 0x20,
-0x2A, 0x46, 0x4E, 0xBF,
-0x1A, 0x46, 0x56, 0xBF,
+ 0x2A, 0x46, 0x4E, 0xBF,
+ 0x1A, 0x46, 0x56, 0xBF,
-0x31, 0x53, 0x2F, 0x9F,
-0x36, 0x31, 0x4F, 0xE9,
+ 0x31, 0x53, 0x2F, 0x9F,
+ 0x36, 0x31, 0x4F, 0xE9,
-0x39, 0xE5, 0x2C, 0x9F,
-0x37, 0x39, 0x4F, 0xE9,
+ 0x39, 0xE5, 0x2C, 0x9F,
+ 0x37, 0x39, 0x4F, 0xE9,
-0x30, 0x50, 0x2E, 0x9F,
-0xA7, 0x30, 0x4F, 0xE9,
+ 0x30, 0x50, 0x2E, 0x9F,
+ 0xA7, 0x30, 0x4F, 0xE9,
-0x38, 0x21, 0x2C, 0x9F,
-0xA8, 0x38, 0x4F, 0xE9,
+ 0x38, 0x21, 0x2C, 0x9F,
+ 0xA8, 0x38, 0x4F, 0xE9,
-0x0A, 0x47, 0x4F, 0xBF,
-0x02, 0x47, 0x57, 0xBF,
+ 0x0A, 0x47, 0x4F, 0xBF,
+ 0x02, 0x47, 0x57, 0xBF,
-0x31, 0x53, 0x2F, 0x9F,
-0xA4, 0x31, 0x4F, 0xE9,
+ 0x31, 0x53, 0x2F, 0x9F,
+ 0xA4, 0x31, 0x4F, 0xE9,
-0x39, 0xE5, 0x2C, 0x9F,
-0xA5, 0x39, 0x4F, 0xE9,
+ 0x39, 0xE5, 0x2C, 0x9F,
+ 0xA5, 0x39, 0x4F, 0xE9,
-0x2A, 0x43, 0x4B, 0xBF,
-0x1A, 0x43, 0x53, 0xBF,
+ 0x2A, 0x43, 0x4B, 0xBF,
+ 0x1A, 0x43, 0x53, 0xBF,
-0x30, 0x50, 0x2E, 0x9F,
-0xA1, 0x30, 0x4F, 0xE9,
+ 0x30, 0x50, 0x2E, 0x9F,
+ 0xA1, 0x30, 0x4F, 0xE9,
-0x38, 0x21, 0x2C, 0x9F,
-0xA2, 0x38, 0x4F, 0xE9,
+ 0x38, 0x21, 0x2C, 0x9F,
+ 0xA2, 0x38, 0x4F, 0xE9,
-0x31, 0x53, 0x2F, 0x9F,
-0x80, 0x31, 0x57, 0xE9,
+ 0x31, 0x53, 0x2F, 0x9F,
+ 0x80, 0x31, 0x57, 0xE9,
-0x39, 0xE5, 0x2C, 0x9F,
-0x81, 0x39, 0x57, 0xE9,
+ 0x39, 0xE5, 0x2C, 0x9F,
+ 0x81, 0x39, 0x57, 0xE9,
-0x37, 0x48, 0x50, 0xBD,
-0x8A, 0x36, 0x20, 0xE9,
+ 0x37, 0x48, 0x50, 0xBD,
+ 0x8A, 0x36, 0x20, 0xE9,
-0x86, 0x76, 0x57, 0xE9,
-0x8B, 0x3E, 0x20, 0xE9,
+ 0x86, 0x76, 0x57, 0xE9,
+ 0x8B, 0x3E, 0x20, 0xE9,
-0x82, 0x30, 0x57, 0xE9,
-0x87, 0x77, 0x57, 0xE9,
+ 0x82, 0x30, 0x57, 0xE9,
+ 0x87, 0x77, 0x57, 0xE9,
-0x83, 0x38, 0x57, 0xE9,
-0x35, 0x49, 0x51, 0xBD,
+ 0x83, 0x38, 0x57, 0xE9,
+ 0x35, 0x49, 0x51, 0xBD,
-0x84, 0x31, 0x5E, 0xE9,
-0x30, 0x1F, 0x5F, 0xE9,
+ 0x84, 0x31, 0x5E, 0xE9,
+ 0x30, 0x1F, 0x5F, 0xE9,
-0x85, 0x39, 0x5E, 0xE9,
-0x57, 0x25, 0x20, 0xE9,
+ 0x85, 0x39, 0x5E, 0xE9,
+ 0x57, 0x25, 0x20, 0xE9,
-0x2B, 0x48, 0x20, 0xE9,
-0x1D, 0x37, 0xE1, 0xEA,
+ 0x2B, 0x48, 0x20, 0xE9,
+ 0x1D, 0x37, 0xE1, 0xEA,
-0x1E, 0x35, 0xE1, 0xEA,
-0x00, 0xE0,
-0x26, 0x77,
+ 0x1E, 0x35, 0xE1, 0xEA,
+ 0x00, 0xE0,
+ 0x26, 0x77,
-0x24, 0x49, 0x20, 0xE9,
-0xA2, 0xFF, 0x20, 0xEA,
+ 0x24, 0x49, 0x20, 0xE9,
+ 0xA2, 0xFF, 0x20, 0xEA,
-0x16, 0x26, 0x20, 0xE9,
-0x57, 0x2E, 0xBF, 0xEA,
+ 0x16, 0x26, 0x20, 0xE9,
+ 0x57, 0x2E, 0xBF, 0xEA,
-0x1C, 0x46, 0xA0, 0xE8,
-0x23, 0x4E, 0xA0, 0xE8,
+ 0x1C, 0x46, 0xA0, 0xE8,
+ 0x23, 0x4E, 0xA0, 0xE8,
-0x2B, 0x56, 0xA0, 0xE8,
-0x1D, 0x47, 0xA0, 0xE8,
+ 0x2B, 0x56, 0xA0, 0xE8,
+ 0x1D, 0x47, 0xA0, 0xE8,
-0x24, 0x4F, 0xA0, 0xE8,
-0x2C, 0x57, 0xA0, 0xE8,
+ 0x24, 0x4F, 0xA0, 0xE8,
+ 0x2C, 0x57, 0xA0, 0xE8,
-0x1C, 0x00,
-0x23, 0x00,
-0x2B, 0x00,
-0x00, 0xE0,
+ 0x1C, 0x00,
+ 0x23, 0x00,
+ 0x2B, 0x00,
+ 0x00, 0xE0,
-0x1D, 0x00,
-0x24, 0x00,
-0x2C, 0x00,
-0x00, 0xE0,
+ 0x1D, 0x00,
+ 0x24, 0x00,
+ 0x2C, 0x00,
+ 0x00, 0xE0,
-0x1C, 0x65,
-0x23, 0x65,
-0x2B, 0x65,
-0x00, 0xE0,
+ 0x1C, 0x65,
+ 0x23, 0x65,
+ 0x2B, 0x65,
+ 0x00, 0xE0,
-0x1D, 0x65,
-0x24, 0x65,
-0x2C, 0x65,
-0x00, 0xE0,
+ 0x1D, 0x65,
+ 0x24, 0x65,
+ 0x2C, 0x65,
+ 0x00, 0xE0,
-0x1C, 0x23, 0x60, 0xEC,
-0x36, 0xD7, 0x36, 0xAD,
+ 0x1C, 0x23, 0x60, 0xEC,
+ 0x36, 0xD7, 0x36, 0xAD,
-0x2B, 0x80, 0x60, 0xEC,
-0x1D, 0x24, 0x60, 0xEC,
+ 0x2B, 0x80, 0x60, 0xEC,
+ 0x1D, 0x24, 0x60, 0xEC,
-0x3E, 0xD7, 0x3E, 0xAD,
-0x2C, 0x80, 0x60, 0xEC,
+ 0x3E, 0xD7, 0x3E, 0xAD,
+ 0x2C, 0x80, 0x60, 0xEC,
-0x1C, 0x2B, 0xDE, 0xE8,
-0x23, 0x80, 0xDE, 0xE8,
+ 0x1C, 0x2B, 0xDE, 0xE8,
+ 0x23, 0x80, 0xDE, 0xE8,
-0x36, 0x80, 0x36, 0xBD,
-0x3E, 0x80, 0x3E, 0xBD,
+ 0x36, 0x80, 0x36, 0xBD,
+ 0x3E, 0x80, 0x3E, 0xBD,
-0x33, 0xD7, 0x1C, 0xBD,
-0x3B, 0xD7, 0x23, 0xBD,
+ 0x33, 0xD7, 0x1C, 0xBD,
+ 0x3B, 0xD7, 0x23, 0xBD,
-0x46, 0x80, 0x46, 0xCF,
-0x4F, 0x80, 0x4F, 0xCF,
+ 0x46, 0x80, 0x46, 0xCF,
+ 0x4F, 0x80, 0x4F, 0xCF,
-0x56, 0x33, 0x56, 0xCF,
-0x47, 0x3B, 0x47, 0xCF,
+ 0x56, 0x33, 0x56, 0xCF,
+ 0x47, 0x3B, 0x47, 0xCF,
-0xCA, 0xFF, 0x20, 0xEA,
-0x00, 0x80, 0x00, 0xE8,
+ 0xCA, 0xFF, 0x20, 0xEA,
+ 0x00, 0x80, 0x00, 0xE8,
-0x4E, 0x33, 0x4E, 0xCF,
-0x57, 0x3B, 0x57, 0xCF,
+ 0x4E, 0x33, 0x4E, 0xCF,
+ 0x57, 0x3B, 0x57, 0xCF,
-0x90, 0xFF, 0x20, 0xEA,
-0x57, 0xC0, 0xBF, 0xEA,
+ 0x90, 0xFF, 0x20, 0xEA,
+ 0x57, 0xC0, 0xBF, 0xEA,
-0x00, 0x80, 0xA0, 0xE9,
-0x00, 0x00, 0xD8, 0xEC,
+ 0x00, 0x80, 0xA0, 0xE9,
+ 0x00, 0x00, 0xD8, 0xEC,
};
static unsigned char warp_g400_tgzsa[] = {
-0x00, 0x88, 0x98, 0xE9,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x88, 0x98, 0xE9,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0xA0, 0xE9,
-0x00, 0x00, 0xD8, 0xEC,
+ 0x00, 0x80, 0xA0, 0xE9,
+ 0x00, 0x00, 0xD8, 0xEC,
-0xFF, 0x80, 0xC0, 0xE9,
-0x00, 0x80, 0x00, 0xE8,
+ 0xFF, 0x80, 0xC0, 0xE9,
+ 0x00, 0x80, 0x00, 0xE8,
-0x22, 0x40, 0x48, 0xBF,
-0x2A, 0x40, 0x50, 0xBF,
+ 0x22, 0x40, 0x48, 0xBF,
+ 0x2A, 0x40, 0x50, 0xBF,
-0x32, 0x41, 0x49, 0xBF,
-0x3A, 0x41, 0x51, 0xBF,
+ 0x32, 0x41, 0x49, 0xBF,
+ 0x3A, 0x41, 0x51, 0xBF,
-0xC3, 0x6B,
-0xCB, 0x6B,
-0x00, 0x88, 0x98, 0xE9,
+ 0xC3, 0x6B,
+ 0xCB, 0x6B,
+ 0x00, 0x88, 0x98, 0xE9,
-0x73, 0x7B, 0xC8, 0xEC,
-0x96, 0xE2,
-0x41, 0x04,
+ 0x73, 0x7B, 0xC8, 0xEC,
+ 0x96, 0xE2,
+ 0x41, 0x04,
-0x7B, 0x43, 0xA0, 0xE8,
-0x73, 0x4B, 0xA0, 0xE8,
+ 0x7B, 0x43, 0xA0, 0xE8,
+ 0x73, 0x4B, 0xA0, 0xE8,
-0xAD, 0xEE, 0x29, 0x9F,
-0x00, 0xE0,
-0x49, 0x04,
+ 0xAD, 0xEE, 0x29, 0x9F,
+ 0x00, 0xE0,
+ 0x49, 0x04,
-0x90, 0xE2,
-0x51, 0x04,
-0x31, 0x46, 0xB1, 0xE8,
+ 0x90, 0xE2,
+ 0x51, 0x04,
+ 0x31, 0x46, 0xB1, 0xE8,
-0x49, 0x41, 0xC0, 0xEC,
-0x39, 0x57, 0xB1, 0xE8,
+ 0x49, 0x41, 0xC0, 0xEC,
+ 0x39, 0x57, 0xB1, 0xE8,
-0x00, 0x04,
-0x46, 0xE2,
-0x73, 0x53, 0xA0, 0xE8,
+ 0x00, 0x04,
+ 0x46, 0xE2,
+ 0x73, 0x53, 0xA0, 0xE8,
-0x51, 0x41, 0xC0, 0xEC,
-0x31, 0x00,
-0x39, 0x00,
+ 0x51, 0x41, 0xC0, 0xEC,
+ 0x31, 0x00,
+ 0x39, 0x00,
-0x6A, 0x80, 0x15, 0xEA,
-0x08, 0x04,
-0x10, 0x04,
+ 0x6A, 0x80, 0x15, 0xEA,
+ 0x08, 0x04,
+ 0x10, 0x04,
-0x51, 0x49, 0xC0, 0xEC,
-0x2F, 0x41, 0x60, 0xEA,
+ 0x51, 0x49, 0xC0, 0xEC,
+ 0x2F, 0x41, 0x60, 0xEA,
-0x31, 0x20,
-0x39, 0x20,
-0x1F, 0x42, 0xA0, 0xE8,
+ 0x31, 0x20,
+ 0x39, 0x20,
+ 0x1F, 0x42, 0xA0, 0xE8,
-0x2A, 0x42, 0x4A, 0xBF,
-0x27, 0x4A, 0xA0, 0xE8,
+ 0x2A, 0x42, 0x4A, 0xBF,
+ 0x27, 0x4A, 0xA0, 0xE8,
-0x1A, 0x42, 0x52, 0xBF,
-0x1E, 0x49, 0x60, 0xEA,
+ 0x1A, 0x42, 0x52, 0xBF,
+ 0x1E, 0x49, 0x60, 0xEA,
-0x73, 0x7B, 0xC8, 0xEC,
-0x26, 0x51, 0x60, 0xEA,
+ 0x73, 0x7B, 0xC8, 0xEC,
+ 0x26, 0x51, 0x60, 0xEA,
-0x32, 0x40, 0x48, 0xBD,
-0x22, 0x40, 0x50, 0xBD,
+ 0x32, 0x40, 0x48, 0xBD,
+ 0x22, 0x40, 0x50, 0xBD,
-0x12, 0x41, 0x49, 0xBD,
-0x3A, 0x41, 0x51, 0xBD,
+ 0x12, 0x41, 0x49, 0xBD,
+ 0x3A, 0x41, 0x51, 0xBD,
-0xBF, 0x2F, 0x26, 0xBD,
-0x00, 0xE0,
-0x7B, 0x72,
+ 0xBF, 0x2F, 0x26, 0xBD,
+ 0x00, 0xE0,
+ 0x7B, 0x72,
-0x32, 0x20,
-0x22, 0x20,
-0x12, 0x20,
-0x3A, 0x20,
+ 0x32, 0x20,
+ 0x22, 0x20,
+ 0x12, 0x20,
+ 0x3A, 0x20,
-0x46, 0x31, 0x46, 0xBF,
-0x4E, 0x31, 0x4E, 0xBF,
+ 0x46, 0x31, 0x46, 0xBF,
+ 0x4E, 0x31, 0x4E, 0xBF,
-0xB3, 0xE2, 0x2D, 0x9F,
-0x00, 0x80, 0x00, 0xE8,
+ 0xB3, 0xE2, 0x2D, 0x9F,
+ 0x00, 0x80, 0x00, 0xE8,
-0x56, 0x31, 0x56, 0xBF,
-0x47, 0x39, 0x47, 0xBF,
+ 0x56, 0x31, 0x56, 0xBF,
+ 0x47, 0x39, 0x47, 0xBF,
-0x4F, 0x39, 0x4F, 0xBF,
-0x57, 0x39, 0x57, 0xBF,
+ 0x4F, 0x39, 0x4F, 0xBF,
+ 0x57, 0x39, 0x57, 0xBF,
-0x5C, 0x80, 0x07, 0xEA,
-0x24, 0x41, 0x20, 0xE9,
+ 0x5C, 0x80, 0x07, 0xEA,
+ 0x24, 0x41, 0x20, 0xE9,
-0x42, 0x73, 0xF8, 0xEC,
-0x00, 0xE0,
-0x2D, 0x73,
+ 0x42, 0x73, 0xF8, 0xEC,
+ 0x00, 0xE0,
+ 0x2D, 0x73,
-0x33, 0x72,
-0x0C, 0xE3,
-0xA5, 0x2F, 0x1E, 0xBD,
+ 0x33, 0x72,
+ 0x0C, 0xE3,
+ 0xA5, 0x2F, 0x1E, 0xBD,
-0x43, 0x43, 0x2D, 0xDF,
-0x4B, 0x4B, 0x2D, 0xDF,
+ 0x43, 0x43, 0x2D, 0xDF,
+ 0x4B, 0x4B, 0x2D, 0xDF,
-0xAE, 0x1E, 0x26, 0xBD,
-0x58, 0xE3,
-0x33, 0x66,
+ 0xAE, 0x1E, 0x26, 0xBD,
+ 0x58, 0xE3,
+ 0x33, 0x66,
-0x53, 0x53, 0x2D, 0xDF,
-0x00, 0x80, 0x00, 0xE8,
+ 0x53, 0x53, 0x2D, 0xDF,
+ 0x00, 0x80, 0x00, 0xE8,
-0xB8, 0x38, 0x33, 0xBF,
-0x00, 0xE0,
-0x59, 0xE3,
+ 0xB8, 0x38, 0x33, 0xBF,
+ 0x00, 0xE0,
+ 0x59, 0xE3,
-0x1E, 0x12, 0x41, 0xE9,
-0x1A, 0x22, 0x41, 0xE9,
+ 0x1E, 0x12, 0x41, 0xE9,
+ 0x1A, 0x22, 0x41, 0xE9,
-0x2B, 0x40, 0x3D, 0xE9,
-0x3F, 0x4B, 0xA0, 0xE8,
+ 0x2B, 0x40, 0x3D, 0xE9,
+ 0x3F, 0x4B, 0xA0, 0xE8,
-0x2D, 0x73,
-0x30, 0x76,
-0x05, 0x80, 0x3D, 0xEA,
+ 0x2D, 0x73,
+ 0x30, 0x76,
+ 0x05, 0x80, 0x3D, 0xEA,
-0x37, 0x43, 0xA0, 0xE8,
-0x3D, 0x53, 0xA0, 0xE8,
+ 0x37, 0x43, 0xA0, 0xE8,
+ 0x3D, 0x53, 0xA0, 0xE8,
-0x48, 0x70, 0xF8, 0xEC,
-0x2B, 0x48, 0x3C, 0xE9,
+ 0x48, 0x70, 0xF8, 0xEC,
+ 0x2B, 0x48, 0x3C, 0xE9,
-0x1F, 0x27, 0xBC, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x1F, 0x27, 0xBC, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x15, 0xC0, 0x20, 0xE9,
-0x15, 0xC0, 0x20, 0xE9,
+ 0x15, 0xC0, 0x20, 0xE9,
+ 0x15, 0xC0, 0x20, 0xE9,
-0x15, 0xC0, 0x20, 0xE9,
-0x15, 0xC0, 0x20, 0xE9,
+ 0x15, 0xC0, 0x20, 0xE9,
+ 0x15, 0xC0, 0x20, 0xE9,
-0x18, 0x3A, 0x41, 0xE9,
-0x1D, 0x32, 0x41, 0xE9,
+ 0x18, 0x3A, 0x41, 0xE9,
+ 0x1D, 0x32, 0x41, 0xE9,
-0x2A, 0x40, 0x20, 0xE9,
-0x56, 0x3D, 0x56, 0xDF,
+ 0x2A, 0x40, 0x20, 0xE9,
+ 0x56, 0x3D, 0x56, 0xDF,
-0x46, 0x37, 0x46, 0xDF,
-0x4E, 0x3F, 0x4E, 0xDF,
+ 0x46, 0x37, 0x46, 0xDF,
+ 0x4E, 0x3F, 0x4E, 0xDF,
-0x16, 0x30, 0x20, 0xE9,
-0x4F, 0x3F, 0x4F, 0xDF,
+ 0x16, 0x30, 0x20, 0xE9,
+ 0x4F, 0x3F, 0x4F, 0xDF,
-0x47, 0x37, 0x47, 0xDF,
-0x57, 0x3D, 0x57, 0xDF,
+ 0x47, 0x37, 0x47, 0xDF,
+ 0x57, 0x3D, 0x57, 0xDF,
-0x32, 0x32, 0x2D, 0xDF,
-0x22, 0x22, 0x2D, 0xDF,
+ 0x32, 0x32, 0x2D, 0xDF,
+ 0x22, 0x22, 0x2D, 0xDF,
-0x12, 0x12, 0x2D, 0xDF,
-0x3A, 0x3A, 0x2D, 0xDF,
+ 0x12, 0x12, 0x2D, 0xDF,
+ 0x3A, 0x3A, 0x2D, 0xDF,
-0x27, 0xCF, 0x74, 0xC2,
-0x37, 0xCF, 0x74, 0xC4,
+ 0x27, 0xCF, 0x74, 0xC2,
+ 0x37, 0xCF, 0x74, 0xC4,
-0x0A, 0x44, 0x4C, 0xB0,
-0x02, 0x44, 0x54, 0xB0,
+ 0x0A, 0x44, 0x4C, 0xB0,
+ 0x02, 0x44, 0x54, 0xB0,
-0x3D, 0xCF, 0x74, 0xC0,
-0x34, 0x37, 0x20, 0xE9,
+ 0x3D, 0xCF, 0x74, 0xC0,
+ 0x34, 0x37, 0x20, 0xE9,
-0x31, 0x53, 0x2F, 0x9F,
-0x38, 0x27, 0x20, 0xE9,
+ 0x31, 0x53, 0x2F, 0x9F,
+ 0x38, 0x27, 0x20, 0xE9,
-0x39, 0xE5, 0x2C, 0x9F,
-0x3C, 0x3D, 0x20, 0xE9,
+ 0x39, 0xE5, 0x2C, 0x9F,
+ 0x3C, 0x3D, 0x20, 0xE9,
-0x2A, 0x44, 0x4C, 0xB2,
-0x1A, 0x44, 0x54, 0xB2,
+ 0x2A, 0x44, 0x4C, 0xB2,
+ 0x1A, 0x44, 0x54, 0xB2,
-0x2E, 0x80, 0x3A, 0xEA,
-0x0A, 0x20,
-0x02, 0x20,
+ 0x2E, 0x80, 0x3A, 0xEA,
+ 0x0A, 0x20,
+ 0x02, 0x20,
-0x27, 0xCF, 0x75, 0xC0,
-0x2A, 0x20,
-0x1A, 0x20,
+ 0x27, 0xCF, 0x75, 0xC0,
+ 0x2A, 0x20,
+ 0x1A, 0x20,
-0x30, 0x50, 0x2E, 0x9F,
-0x32, 0x31, 0x5F, 0xE9,
+ 0x30, 0x50, 0x2E, 0x9F,
+ 0x32, 0x31, 0x5F, 0xE9,
-0x38, 0x21, 0x2C, 0x9F,
-0x33, 0x39, 0x5F, 0xE9,
+ 0x38, 0x21, 0x2C, 0x9F,
+ 0x33, 0x39, 0x5F, 0xE9,
-0x3D, 0xCF, 0x75, 0xC2,
-0x37, 0xCF, 0x75, 0xC4,
+ 0x3D, 0xCF, 0x75, 0xC2,
+ 0x37, 0xCF, 0x75, 0xC4,
-0x31, 0x53, 0x2F, 0x9F,
-0xA6, 0x27, 0x20, 0xE9,
+ 0x31, 0x53, 0x2F, 0x9F,
+ 0xA6, 0x27, 0x20, 0xE9,
-0x39, 0xE5, 0x2C, 0x9F,
-0xA3, 0x3D, 0x20, 0xE9,
+ 0x39, 0xE5, 0x2C, 0x9F,
+ 0xA3, 0x3D, 0x20, 0xE9,
-0x2A, 0x44, 0x4C, 0xB4,
-0x1A, 0x44, 0x54, 0xB4,
+ 0x2A, 0x44, 0x4C, 0xB4,
+ 0x1A, 0x44, 0x54, 0xB4,
-0x0A, 0x45, 0x4D, 0xB0,
-0x02, 0x45, 0x55, 0xB0,
+ 0x0A, 0x45, 0x4D, 0xB0,
+ 0x02, 0x45, 0x55, 0xB0,
-0x88, 0x73, 0x5E, 0xE9,
-0x2A, 0x20,
-0x1A, 0x20,
+ 0x88, 0x73, 0x5E, 0xE9,
+ 0x2A, 0x20,
+ 0x1A, 0x20,
-0xA0, 0x37, 0x20, 0xE9,
-0x0A, 0x20,
-0x02, 0x20,
+ 0xA0, 0x37, 0x20, 0xE9,
+ 0x0A, 0x20,
+ 0x02, 0x20,
-0x31, 0x53, 0x2F, 0x9F,
-0x3E, 0x30, 0x4F, 0xE9,
+ 0x31, 0x53, 0x2F, 0x9F,
+ 0x3E, 0x30, 0x4F, 0xE9,
-0x39, 0xE5, 0x2C, 0x9F,
-0x3F, 0x38, 0x4F, 0xE9,
+ 0x39, 0xE5, 0x2C, 0x9F,
+ 0x3F, 0x38, 0x4F, 0xE9,
-0x30, 0x50, 0x2E, 0x9F,
-0x3A, 0x31, 0x4F, 0xE9,
+ 0x30, 0x50, 0x2E, 0x9F,
+ 0x3A, 0x31, 0x4F, 0xE9,
-0x38, 0x21, 0x2C, 0x9F,
-0x3B, 0x39, 0x4F, 0xE9,
+ 0x38, 0x21, 0x2C, 0x9F,
+ 0x3B, 0x39, 0x4F, 0xE9,
-0x2A, 0x45, 0x4D, 0xB2,
-0x1A, 0x45, 0x55, 0xB2,
+ 0x2A, 0x45, 0x4D, 0xB2,
+ 0x1A, 0x45, 0x55, 0xB2,
-0x0A, 0x45, 0x4D, 0xB4,
-0x02, 0x45, 0x55, 0xB4,
+ 0x0A, 0x45, 0x4D, 0xB4,
+ 0x02, 0x45, 0x55, 0xB4,
-0x27, 0xCF, 0x74, 0xC6,
-0x2A, 0x20,
-0x1A, 0x20,
+ 0x27, 0xCF, 0x74, 0xC6,
+ 0x2A, 0x20,
+ 0x1A, 0x20,
-0xA7, 0x30, 0x4F, 0xE9,
-0x0A, 0x20,
-0x02, 0x20,
+ 0xA7, 0x30, 0x4F, 0xE9,
+ 0x0A, 0x20,
+ 0x02, 0x20,
-0x31, 0x53, 0x2F, 0x9F,
-0x9C, 0x27, 0x20, 0xE9,
+ 0x31, 0x53, 0x2F, 0x9F,
+ 0x9C, 0x27, 0x20, 0xE9,
-0x39, 0xE5, 0x2C, 0x9F,
-0xA8, 0x38, 0x4F, 0xE9,
+ 0x39, 0xE5, 0x2C, 0x9F,
+ 0xA8, 0x38, 0x4F, 0xE9,
-0x2A, 0x44, 0x4C, 0xB6,
-0x1A, 0x44, 0x54, 0xB6,
+ 0x2A, 0x44, 0x4C, 0xB6,
+ 0x1A, 0x44, 0x54, 0xB6,
-0x30, 0x50, 0x2E, 0x9F,
-0x36, 0x31, 0x4F, 0xE9,
+ 0x30, 0x50, 0x2E, 0x9F,
+ 0x36, 0x31, 0x4F, 0xE9,
-0x38, 0x21, 0x2C, 0x9F,
-0x37, 0x39, 0x4F, 0xE9,
+ 0x38, 0x21, 0x2C, 0x9F,
+ 0x37, 0x39, 0x4F, 0xE9,
-0x00, 0x80, 0x00, 0xE8,
-0x2A, 0x20,
-0x1A, 0x20,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x2A, 0x20,
+ 0x1A, 0x20,
-0x2A, 0x46, 0x4E, 0xBF,
-0x1A, 0x46, 0x56, 0xBF,
+ 0x2A, 0x46, 0x4E, 0xBF,
+ 0x1A, 0x46, 0x56, 0xBF,
-0x31, 0x53, 0x2F, 0x9F,
-0xA4, 0x31, 0x4F, 0xE9,
+ 0x31, 0x53, 0x2F, 0x9F,
+ 0xA4, 0x31, 0x4F, 0xE9,
-0x39, 0xE5, 0x2C, 0x9F,
-0xA5, 0x39, 0x4F, 0xE9,
+ 0x39, 0xE5, 0x2C, 0x9F,
+ 0xA5, 0x39, 0x4F, 0xE9,
-0x0A, 0x47, 0x4F, 0xBF,
-0x02, 0x47, 0x57, 0xBF,
+ 0x0A, 0x47, 0x4F, 0xBF,
+ 0x02, 0x47, 0x57, 0xBF,
-0x31, 0x53, 0x2F, 0x9F,
-0xA1, 0x30, 0x4F, 0xE9,
+ 0x31, 0x53, 0x2F, 0x9F,
+ 0xA1, 0x30, 0x4F, 0xE9,
-0x39, 0xE5, 0x2C, 0x9F,
-0xA2, 0x38, 0x4F, 0xE9,
+ 0x39, 0xE5, 0x2C, 0x9F,
+ 0xA2, 0x38, 0x4F, 0xE9,
-0x2A, 0x43, 0x4B, 0xBF,
-0x1A, 0x43, 0x53, 0xBF,
+ 0x2A, 0x43, 0x4B, 0xBF,
+ 0x1A, 0x43, 0x53, 0xBF,
-0x30, 0x50, 0x2E, 0x9F,
-0x9D, 0x31, 0x4F, 0xE9,
+ 0x30, 0x50, 0x2E, 0x9F,
+ 0x9D, 0x31, 0x4F, 0xE9,
-0x38, 0x21, 0x2C, 0x9F,
-0x9E, 0x39, 0x4F, 0xE9,
+ 0x38, 0x21, 0x2C, 0x9F,
+ 0x9E, 0x39, 0x4F, 0xE9,
-0x31, 0x53, 0x2F, 0x9F,
-0x80, 0x31, 0x57, 0xE9,
+ 0x31, 0x53, 0x2F, 0x9F,
+ 0x80, 0x31, 0x57, 0xE9,
-0x39, 0xE5, 0x2C, 0x9F,
-0x81, 0x39, 0x57, 0xE9,
+ 0x39, 0xE5, 0x2C, 0x9F,
+ 0x81, 0x39, 0x57, 0xE9,
-0x37, 0x48, 0x50, 0xBD,
-0x8A, 0x36, 0x20, 0xE9,
+ 0x37, 0x48, 0x50, 0xBD,
+ 0x8A, 0x36, 0x20, 0xE9,
-0x86, 0x76, 0x57, 0xE9,
-0x8B, 0x3E, 0x20, 0xE9,
+ 0x86, 0x76, 0x57, 0xE9,
+ 0x8B, 0x3E, 0x20, 0xE9,
-0x82, 0x30, 0x57, 0xE9,
-0x87, 0x77, 0x57, 0xE9,
+ 0x82, 0x30, 0x57, 0xE9,
+ 0x87, 0x77, 0x57, 0xE9,
-0x83, 0x38, 0x57, 0xE9,
-0x35, 0x49, 0x51, 0xBD,
+ 0x83, 0x38, 0x57, 0xE9,
+ 0x35, 0x49, 0x51, 0xBD,
-0x84, 0x31, 0x5E, 0xE9,
-0x30, 0x1F, 0x5F, 0xE9,
+ 0x84, 0x31, 0x5E, 0xE9,
+ 0x30, 0x1F, 0x5F, 0xE9,
-0x85, 0x39, 0x5E, 0xE9,
-0x57, 0x25, 0x20, 0xE9,
+ 0x85, 0x39, 0x5E, 0xE9,
+ 0x57, 0x25, 0x20, 0xE9,
-0x2B, 0x48, 0x20, 0xE9,
-0x1D, 0x37, 0xE1, 0xEA,
+ 0x2B, 0x48, 0x20, 0xE9,
+ 0x1D, 0x37, 0xE1, 0xEA,
-0x1E, 0x35, 0xE1, 0xEA,
-0x00, 0xE0,
-0x26, 0x77,
+ 0x1E, 0x35, 0xE1, 0xEA,
+ 0x00, 0xE0,
+ 0x26, 0x77,
-0x24, 0x49, 0x20, 0xE9,
-0x9D, 0xFF, 0x20, 0xEA,
+ 0x24, 0x49, 0x20, 0xE9,
+ 0x9D, 0xFF, 0x20, 0xEA,
-0x16, 0x26, 0x20, 0xE9,
-0x57, 0x2E, 0xBF, 0xEA,
+ 0x16, 0x26, 0x20, 0xE9,
+ 0x57, 0x2E, 0xBF, 0xEA,
-0x1C, 0x46, 0xA0, 0xE8,
-0x23, 0x4E, 0xA0, 0xE8,
+ 0x1C, 0x46, 0xA0, 0xE8,
+ 0x23, 0x4E, 0xA0, 0xE8,
-0x2B, 0x56, 0xA0, 0xE8,
-0x1D, 0x47, 0xA0, 0xE8,
+ 0x2B, 0x56, 0xA0, 0xE8,
+ 0x1D, 0x47, 0xA0, 0xE8,
-0x24, 0x4F, 0xA0, 0xE8,
-0x2C, 0x57, 0xA0, 0xE8,
+ 0x24, 0x4F, 0xA0, 0xE8,
+ 0x2C, 0x57, 0xA0, 0xE8,
-0x1C, 0x00,
-0x23, 0x00,
-0x2B, 0x00,
-0x00, 0xE0,
+ 0x1C, 0x00,
+ 0x23, 0x00,
+ 0x2B, 0x00,
+ 0x00, 0xE0,
-0x1D, 0x00,
-0x24, 0x00,
-0x2C, 0x00,
-0x00, 0xE0,
+ 0x1D, 0x00,
+ 0x24, 0x00,
+ 0x2C, 0x00,
+ 0x00, 0xE0,
-0x1C, 0x65,
-0x23, 0x65,
-0x2B, 0x65,
-0x00, 0xE0,
+ 0x1C, 0x65,
+ 0x23, 0x65,
+ 0x2B, 0x65,
+ 0x00, 0xE0,
-0x1D, 0x65,
-0x24, 0x65,
-0x2C, 0x65,
-0x00, 0xE0,
+ 0x1D, 0x65,
+ 0x24, 0x65,
+ 0x2C, 0x65,
+ 0x00, 0xE0,
-0x1C, 0x23, 0x60, 0xEC,
-0x36, 0xD7, 0x36, 0xAD,
+ 0x1C, 0x23, 0x60, 0xEC,
+ 0x36, 0xD7, 0x36, 0xAD,
-0x2B, 0x80, 0x60, 0xEC,
-0x1D, 0x24, 0x60, 0xEC,
+ 0x2B, 0x80, 0x60, 0xEC,
+ 0x1D, 0x24, 0x60, 0xEC,
-0x3E, 0xD7, 0x3E, 0xAD,
-0x2C, 0x80, 0x60, 0xEC,
+ 0x3E, 0xD7, 0x3E, 0xAD,
+ 0x2C, 0x80, 0x60, 0xEC,
-0x1C, 0x2B, 0xDE, 0xE8,
-0x23, 0x80, 0xDE, 0xE8,
+ 0x1C, 0x2B, 0xDE, 0xE8,
+ 0x23, 0x80, 0xDE, 0xE8,
-0x36, 0x80, 0x36, 0xBD,
-0x3E, 0x80, 0x3E, 0xBD,
+ 0x36, 0x80, 0x36, 0xBD,
+ 0x3E, 0x80, 0x3E, 0xBD,
-0x33, 0xD7, 0x1C, 0xBD,
-0x3B, 0xD7, 0x23, 0xBD,
+ 0x33, 0xD7, 0x1C, 0xBD,
+ 0x3B, 0xD7, 0x23, 0xBD,
-0x46, 0x80, 0x46, 0xCF,
-0x4F, 0x80, 0x4F, 0xCF,
+ 0x46, 0x80, 0x46, 0xCF,
+ 0x4F, 0x80, 0x4F, 0xCF,
-0x56, 0x33, 0x56, 0xCF,
-0x47, 0x3B, 0x47, 0xCF,
+ 0x56, 0x33, 0x56, 0xCF,
+ 0x47, 0x3B, 0x47, 0xCF,
-0xC5, 0xFF, 0x20, 0xEA,
-0x00, 0x80, 0x00, 0xE8,
+ 0xC5, 0xFF, 0x20, 0xEA,
+ 0x00, 0x80, 0x00, 0xE8,
-0x4E, 0x33, 0x4E, 0xCF,
-0x57, 0x3B, 0x57, 0xCF,
+ 0x4E, 0x33, 0x4E, 0xCF,
+ 0x57, 0x3B, 0x57, 0xCF,
-0x8B, 0xFF, 0x20, 0xEA,
-0x57, 0xC0, 0xBF, 0xEA,
+ 0x8B, 0xFF, 0x20, 0xEA,
+ 0x57, 0xC0, 0xBF, 0xEA,
-0x00, 0x80, 0xA0, 0xE9,
-0x00, 0x00, 0xD8, 0xEC,
+ 0x00, 0x80, 0xA0, 0xE9,
+ 0x00, 0x00, 0xD8, 0xEC,
};
static unsigned char warp_g400_tgzsaf[] = {
-0x00, 0x88, 0x98, 0xE9,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x88, 0x98, 0xE9,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0xA0, 0xE9,
-0x00, 0x00, 0xD8, 0xEC,
+ 0x00, 0x80, 0xA0, 0xE9,
+ 0x00, 0x00, 0xD8, 0xEC,
-0xFF, 0x80, 0xC0, 0xE9,
-0x00, 0x80, 0x00, 0xE8,
+ 0xFF, 0x80, 0xC0, 0xE9,
+ 0x00, 0x80, 0x00, 0xE8,
-0x22, 0x40, 0x48, 0xBF,
-0x2A, 0x40, 0x50, 0xBF,
+ 0x22, 0x40, 0x48, 0xBF,
+ 0x2A, 0x40, 0x50, 0xBF,
-0x32, 0x41, 0x49, 0xBF,
-0x3A, 0x41, 0x51, 0xBF,
+ 0x32, 0x41, 0x49, 0xBF,
+ 0x3A, 0x41, 0x51, 0xBF,
-0xC3, 0x6B,
-0xCB, 0x6B,
-0x00, 0x88, 0x98, 0xE9,
+ 0xC3, 0x6B,
+ 0xCB, 0x6B,
+ 0x00, 0x88, 0x98, 0xE9,
-0x73, 0x7B, 0xC8, 0xEC,
-0x96, 0xE2,
-0x41, 0x04,
+ 0x73, 0x7B, 0xC8, 0xEC,
+ 0x96, 0xE2,
+ 0x41, 0x04,
-0x7B, 0x43, 0xA0, 0xE8,
-0x73, 0x4B, 0xA0, 0xE8,
+ 0x7B, 0x43, 0xA0, 0xE8,
+ 0x73, 0x4B, 0xA0, 0xE8,
-0xAD, 0xEE, 0x29, 0x9F,
-0x00, 0xE0,
-0x49, 0x04,
+ 0xAD, 0xEE, 0x29, 0x9F,
+ 0x00, 0xE0,
+ 0x49, 0x04,
-0x90, 0xE2,
-0x51, 0x04,
-0x31, 0x46, 0xB1, 0xE8,
+ 0x90, 0xE2,
+ 0x51, 0x04,
+ 0x31, 0x46, 0xB1, 0xE8,
-0x49, 0x41, 0xC0, 0xEC,
-0x39, 0x57, 0xB1, 0xE8,
+ 0x49, 0x41, 0xC0, 0xEC,
+ 0x39, 0x57, 0xB1, 0xE8,
-0x00, 0x04,
-0x46, 0xE2,
-0x73, 0x53, 0xA0, 0xE8,
+ 0x00, 0x04,
+ 0x46, 0xE2,
+ 0x73, 0x53, 0xA0, 0xE8,
-0x51, 0x41, 0xC0, 0xEC,
-0x31, 0x00,
-0x39, 0x00,
+ 0x51, 0x41, 0xC0, 0xEC,
+ 0x31, 0x00,
+ 0x39, 0x00,
-0x6E, 0x80, 0x15, 0xEA,
-0x08, 0x04,
-0x10, 0x04,
+ 0x6E, 0x80, 0x15, 0xEA,
+ 0x08, 0x04,
+ 0x10, 0x04,
-0x51, 0x49, 0xC0, 0xEC,
-0x2F, 0x41, 0x60, 0xEA,
+ 0x51, 0x49, 0xC0, 0xEC,
+ 0x2F, 0x41, 0x60, 0xEA,
-0x31, 0x20,
-0x39, 0x20,
-0x1F, 0x42, 0xA0, 0xE8,
+ 0x31, 0x20,
+ 0x39, 0x20,
+ 0x1F, 0x42, 0xA0, 0xE8,
-0x2A, 0x42, 0x4A, 0xBF,
-0x27, 0x4A, 0xA0, 0xE8,
+ 0x2A, 0x42, 0x4A, 0xBF,
+ 0x27, 0x4A, 0xA0, 0xE8,
-0x1A, 0x42, 0x52, 0xBF,
-0x1E, 0x49, 0x60, 0xEA,
+ 0x1A, 0x42, 0x52, 0xBF,
+ 0x1E, 0x49, 0x60, 0xEA,
-0x73, 0x7B, 0xC8, 0xEC,
-0x26, 0x51, 0x60, 0xEA,
+ 0x73, 0x7B, 0xC8, 0xEC,
+ 0x26, 0x51, 0x60, 0xEA,
-0x32, 0x40, 0x48, 0xBD,
-0x22, 0x40, 0x50, 0xBD,
+ 0x32, 0x40, 0x48, 0xBD,
+ 0x22, 0x40, 0x50, 0xBD,
-0x12, 0x41, 0x49, 0xBD,
-0x3A, 0x41, 0x51, 0xBD,
+ 0x12, 0x41, 0x49, 0xBD,
+ 0x3A, 0x41, 0x51, 0xBD,
-0xBF, 0x2F, 0x26, 0xBD,
-0x00, 0xE0,
-0x7B, 0x72,
+ 0xBF, 0x2F, 0x26, 0xBD,
+ 0x00, 0xE0,
+ 0x7B, 0x72,
-0x32, 0x20,
-0x22, 0x20,
-0x12, 0x20,
-0x3A, 0x20,
+ 0x32, 0x20,
+ 0x22, 0x20,
+ 0x12, 0x20,
+ 0x3A, 0x20,
-0x46, 0x31, 0x46, 0xBF,
-0x4E, 0x31, 0x4E, 0xBF,
+ 0x46, 0x31, 0x46, 0xBF,
+ 0x4E, 0x31, 0x4E, 0xBF,
-0xB3, 0xE2, 0x2D, 0x9F,
-0x00, 0x80, 0x00, 0xE8,
+ 0xB3, 0xE2, 0x2D, 0x9F,
+ 0x00, 0x80, 0x00, 0xE8,
-0x56, 0x31, 0x56, 0xBF,
-0x47, 0x39, 0x47, 0xBF,
+ 0x56, 0x31, 0x56, 0xBF,
+ 0x47, 0x39, 0x47, 0xBF,
-0x4F, 0x39, 0x4F, 0xBF,
-0x57, 0x39, 0x57, 0xBF,
+ 0x4F, 0x39, 0x4F, 0xBF,
+ 0x57, 0x39, 0x57, 0xBF,
-0x60, 0x80, 0x07, 0xEA,
-0x24, 0x41, 0x20, 0xE9,
+ 0x60, 0x80, 0x07, 0xEA,
+ 0x24, 0x41, 0x20, 0xE9,
-0x42, 0x73, 0xF8, 0xEC,
-0x00, 0xE0,
-0x2D, 0x73,
+ 0x42, 0x73, 0xF8, 0xEC,
+ 0x00, 0xE0,
+ 0x2D, 0x73,
-0x33, 0x72,
-0x0C, 0xE3,
-0xA5, 0x2F, 0x1E, 0xBD,
+ 0x33, 0x72,
+ 0x0C, 0xE3,
+ 0xA5, 0x2F, 0x1E, 0xBD,
-0x43, 0x43, 0x2D, 0xDF,
-0x4B, 0x4B, 0x2D, 0xDF,
+ 0x43, 0x43, 0x2D, 0xDF,
+ 0x4B, 0x4B, 0x2D, 0xDF,
-0xAE, 0x1E, 0x26, 0xBD,
-0x58, 0xE3,
-0x33, 0x66,
+ 0xAE, 0x1E, 0x26, 0xBD,
+ 0x58, 0xE3,
+ 0x33, 0x66,
-0x53, 0x53, 0x2D, 0xDF,
-0x00, 0x80, 0x00, 0xE8,
+ 0x53, 0x53, 0x2D, 0xDF,
+ 0x00, 0x80, 0x00, 0xE8,
-0xB8, 0x38, 0x33, 0xBF,
-0x00, 0xE0,
-0x59, 0xE3,
+ 0xB8, 0x38, 0x33, 0xBF,
+ 0x00, 0xE0,
+ 0x59, 0xE3,
-0x1E, 0x12, 0x41, 0xE9,
-0x1A, 0x22, 0x41, 0xE9,
+ 0x1E, 0x12, 0x41, 0xE9,
+ 0x1A, 0x22, 0x41, 0xE9,
-0x2B, 0x40, 0x3D, 0xE9,
-0x3F, 0x4B, 0xA0, 0xE8,
+ 0x2B, 0x40, 0x3D, 0xE9,
+ 0x3F, 0x4B, 0xA0, 0xE8,
-0x2D, 0x73,
-0x30, 0x76,
-0x05, 0x80, 0x3D, 0xEA,
+ 0x2D, 0x73,
+ 0x30, 0x76,
+ 0x05, 0x80, 0x3D, 0xEA,
-0x37, 0x43, 0xA0, 0xE8,
-0x3D, 0x53, 0xA0, 0xE8,
+ 0x37, 0x43, 0xA0, 0xE8,
+ 0x3D, 0x53, 0xA0, 0xE8,
-0x48, 0x70, 0xF8, 0xEC,
-0x2B, 0x48, 0x3C, 0xE9,
+ 0x48, 0x70, 0xF8, 0xEC,
+ 0x2B, 0x48, 0x3C, 0xE9,
-0x1F, 0x27, 0xBC, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x1F, 0x27, 0xBC, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x15, 0xC0, 0x20, 0xE9,
-0x15, 0xC0, 0x20, 0xE9,
+ 0x15, 0xC0, 0x20, 0xE9,
+ 0x15, 0xC0, 0x20, 0xE9,
-0x15, 0xC0, 0x20, 0xE9,
-0x15, 0xC0, 0x20, 0xE9,
+ 0x15, 0xC0, 0x20, 0xE9,
+ 0x15, 0xC0, 0x20, 0xE9,
-0x18, 0x3A, 0x41, 0xE9,
-0x1D, 0x32, 0x41, 0xE9,
+ 0x18, 0x3A, 0x41, 0xE9,
+ 0x1D, 0x32, 0x41, 0xE9,
-0x2A, 0x40, 0x20, 0xE9,
-0x56, 0x3D, 0x56, 0xDF,
+ 0x2A, 0x40, 0x20, 0xE9,
+ 0x56, 0x3D, 0x56, 0xDF,
-0x46, 0x37, 0x46, 0xDF,
-0x4E, 0x3F, 0x4E, 0xDF,
+ 0x46, 0x37, 0x46, 0xDF,
+ 0x4E, 0x3F, 0x4E, 0xDF,
-0x16, 0x30, 0x20, 0xE9,
-0x4F, 0x3F, 0x4F, 0xDF,
+ 0x16, 0x30, 0x20, 0xE9,
+ 0x4F, 0x3F, 0x4F, 0xDF,
-0x47, 0x37, 0x47, 0xDF,
-0x57, 0x3D, 0x57, 0xDF,
+ 0x47, 0x37, 0x47, 0xDF,
+ 0x57, 0x3D, 0x57, 0xDF,
-0x32, 0x32, 0x2D, 0xDF,
-0x22, 0x22, 0x2D, 0xDF,
+ 0x32, 0x32, 0x2D, 0xDF,
+ 0x22, 0x22, 0x2D, 0xDF,
-0x12, 0x12, 0x2D, 0xDF,
-0x3A, 0x3A, 0x2D, 0xDF,
+ 0x12, 0x12, 0x2D, 0xDF,
+ 0x3A, 0x3A, 0x2D, 0xDF,
-0x27, 0xCF, 0x74, 0xC2,
-0x37, 0xCF, 0x74, 0xC4,
+ 0x27, 0xCF, 0x74, 0xC2,
+ 0x37, 0xCF, 0x74, 0xC4,
-0x0A, 0x44, 0x4C, 0xB0,
-0x02, 0x44, 0x54, 0xB0,
+ 0x0A, 0x44, 0x4C, 0xB0,
+ 0x02, 0x44, 0x54, 0xB0,
-0x3D, 0xCF, 0x74, 0xC0,
-0x34, 0x37, 0x20, 0xE9,
+ 0x3D, 0xCF, 0x74, 0xC0,
+ 0x34, 0x37, 0x20, 0xE9,
-0x31, 0x53, 0x2F, 0x9F,
-0x38, 0x27, 0x20, 0xE9,
+ 0x31, 0x53, 0x2F, 0x9F,
+ 0x38, 0x27, 0x20, 0xE9,
-0x39, 0xE5, 0x2C, 0x9F,
-0x3C, 0x3D, 0x20, 0xE9,
+ 0x39, 0xE5, 0x2C, 0x9F,
+ 0x3C, 0x3D, 0x20, 0xE9,
-0x2A, 0x44, 0x4C, 0xB2,
-0x1A, 0x44, 0x54, 0xB2,
+ 0x2A, 0x44, 0x4C, 0xB2,
+ 0x1A, 0x44, 0x54, 0xB2,
-0x32, 0x80, 0x3A, 0xEA,
-0x0A, 0x20,
-0x02, 0x20,
+ 0x32, 0x80, 0x3A, 0xEA,
+ 0x0A, 0x20,
+ 0x02, 0x20,
-0x27, 0xCF, 0x75, 0xC0,
-0x2A, 0x20,
-0x1A, 0x20,
+ 0x27, 0xCF, 0x75, 0xC0,
+ 0x2A, 0x20,
+ 0x1A, 0x20,
-0x30, 0x50, 0x2E, 0x9F,
-0x32, 0x31, 0x5F, 0xE9,
+ 0x30, 0x50, 0x2E, 0x9F,
+ 0x32, 0x31, 0x5F, 0xE9,
-0x38, 0x21, 0x2C, 0x9F,
-0x33, 0x39, 0x5F, 0xE9,
+ 0x38, 0x21, 0x2C, 0x9F,
+ 0x33, 0x39, 0x5F, 0xE9,
-0x3D, 0xCF, 0x75, 0xC2,
-0x37, 0xCF, 0x75, 0xC4,
+ 0x3D, 0xCF, 0x75, 0xC2,
+ 0x37, 0xCF, 0x75, 0xC4,
-0x31, 0x53, 0x2F, 0x9F,
-0xA6, 0x27, 0x20, 0xE9,
+ 0x31, 0x53, 0x2F, 0x9F,
+ 0xA6, 0x27, 0x20, 0xE9,
-0x39, 0xE5, 0x2C, 0x9F,
-0xA3, 0x3D, 0x20, 0xE9,
+ 0x39, 0xE5, 0x2C, 0x9F,
+ 0xA3, 0x3D, 0x20, 0xE9,
-0x2A, 0x44, 0x4C, 0xB4,
-0x1A, 0x44, 0x54, 0xB4,
+ 0x2A, 0x44, 0x4C, 0xB4,
+ 0x1A, 0x44, 0x54, 0xB4,
-0x0A, 0x45, 0x4D, 0xB0,
-0x02, 0x45, 0x55, 0xB0,
+ 0x0A, 0x45, 0x4D, 0xB0,
+ 0x02, 0x45, 0x55, 0xB0,
-0x88, 0x73, 0x5E, 0xE9,
-0x2A, 0x20,
-0x1A, 0x20,
+ 0x88, 0x73, 0x5E, 0xE9,
+ 0x2A, 0x20,
+ 0x1A, 0x20,
-0xA0, 0x37, 0x20, 0xE9,
-0x0A, 0x20,
-0x02, 0x20,
+ 0xA0, 0x37, 0x20, 0xE9,
+ 0x0A, 0x20,
+ 0x02, 0x20,
-0x31, 0x53, 0x2F, 0x9F,
-0x3E, 0x30, 0x4F, 0xE9,
+ 0x31, 0x53, 0x2F, 0x9F,
+ 0x3E, 0x30, 0x4F, 0xE9,
-0x39, 0xE5, 0x2C, 0x9F,
-0x3F, 0x38, 0x4F, 0xE9,
+ 0x39, 0xE5, 0x2C, 0x9F,
+ 0x3F, 0x38, 0x4F, 0xE9,
-0x30, 0x50, 0x2E, 0x9F,
-0x3A, 0x31, 0x4F, 0xE9,
+ 0x30, 0x50, 0x2E, 0x9F,
+ 0x3A, 0x31, 0x4F, 0xE9,
-0x38, 0x21, 0x2C, 0x9F,
-0x3B, 0x39, 0x4F, 0xE9,
+ 0x38, 0x21, 0x2C, 0x9F,
+ 0x3B, 0x39, 0x4F, 0xE9,
-0x2A, 0x45, 0x4D, 0xB2,
-0x1A, 0x45, 0x55, 0xB2,
+ 0x2A, 0x45, 0x4D, 0xB2,
+ 0x1A, 0x45, 0x55, 0xB2,
-0x0A, 0x45, 0x4D, 0xB4,
-0x02, 0x45, 0x55, 0xB4,
+ 0x0A, 0x45, 0x4D, 0xB4,
+ 0x02, 0x45, 0x55, 0xB4,
-0x27, 0xCF, 0x74, 0xC6,
-0x2A, 0x20,
-0x1A, 0x20,
+ 0x27, 0xCF, 0x74, 0xC6,
+ 0x2A, 0x20,
+ 0x1A, 0x20,
-0xA7, 0x30, 0x4F, 0xE9,
-0x0A, 0x20,
-0x02, 0x20,
+ 0xA7, 0x30, 0x4F, 0xE9,
+ 0x0A, 0x20,
+ 0x02, 0x20,
-0x31, 0x53, 0x2F, 0x9F,
-0x9C, 0x27, 0x20, 0xE9,
+ 0x31, 0x53, 0x2F, 0x9F,
+ 0x9C, 0x27, 0x20, 0xE9,
-0x39, 0xE5, 0x2C, 0x9F,
-0xA8, 0x38, 0x4F, 0xE9,
+ 0x39, 0xE5, 0x2C, 0x9F,
+ 0xA8, 0x38, 0x4F, 0xE9,
-0x2A, 0x44, 0x4C, 0xB6,
-0x1A, 0x44, 0x54, 0xB6,
+ 0x2A, 0x44, 0x4C, 0xB6,
+ 0x1A, 0x44, 0x54, 0xB6,
-0x30, 0x50, 0x2E, 0x9F,
-0x36, 0x31, 0x4F, 0xE9,
+ 0x30, 0x50, 0x2E, 0x9F,
+ 0x36, 0x31, 0x4F, 0xE9,
-0x38, 0x21, 0x2C, 0x9F,
-0x37, 0x39, 0x4F, 0xE9,
+ 0x38, 0x21, 0x2C, 0x9F,
+ 0x37, 0x39, 0x4F, 0xE9,
-0x0A, 0x45, 0x4D, 0xB6,
-0x02, 0x45, 0x55, 0xB6,
+ 0x0A, 0x45, 0x4D, 0xB6,
+ 0x02, 0x45, 0x55, 0xB6,
-0x3D, 0xCF, 0x75, 0xC6,
-0x2A, 0x20,
-0x1A, 0x20,
+ 0x3D, 0xCF, 0x75, 0xC6,
+ 0x2A, 0x20,
+ 0x1A, 0x20,
-0x2A, 0x46, 0x4E, 0xBF,
-0x1A, 0x46, 0x56, 0xBF,
+ 0x2A, 0x46, 0x4E, 0xBF,
+ 0x1A, 0x46, 0x56, 0xBF,
-0x31, 0x53, 0x2F, 0x9F,
-0xA4, 0x31, 0x4F, 0xE9,
+ 0x31, 0x53, 0x2F, 0x9F,
+ 0xA4, 0x31, 0x4F, 0xE9,
-0x39, 0xE5, 0x2C, 0x9F,
-0xA5, 0x39, 0x4F, 0xE9,
+ 0x39, 0xE5, 0x2C, 0x9F,
+ 0xA5, 0x39, 0x4F, 0xE9,
-0x31, 0x3D, 0x20, 0xE9,
-0x0A, 0x20,
-0x02, 0x20,
+ 0x31, 0x3D, 0x20, 0xE9,
+ 0x0A, 0x20,
+ 0x02, 0x20,
-0x0A, 0x47, 0x4F, 0xBF,
-0x02, 0x47, 0x57, 0xBF,
+ 0x0A, 0x47, 0x4F, 0xBF,
+ 0x02, 0x47, 0x57, 0xBF,
-0x30, 0x50, 0x2E, 0x9F,
-0xA1, 0x30, 0x4F, 0xE9,
+ 0x30, 0x50, 0x2E, 0x9F,
+ 0xA1, 0x30, 0x4F, 0xE9,
-0x38, 0x21, 0x2C, 0x9F,
-0xA2, 0x38, 0x4F, 0xE9,
+ 0x38, 0x21, 0x2C, 0x9F,
+ 0xA2, 0x38, 0x4F, 0xE9,
-0x31, 0x53, 0x2F, 0x9F,
-0x9D, 0x31, 0x4F, 0xE9,
+ 0x31, 0x53, 0x2F, 0x9F,
+ 0x9D, 0x31, 0x4F, 0xE9,
-0x39, 0xE5, 0x2C, 0x9F,
-0x9E, 0x39, 0x4F, 0xE9,
+ 0x39, 0xE5, 0x2C, 0x9F,
+ 0x9E, 0x39, 0x4F, 0xE9,
-0x2A, 0x43, 0x4B, 0xBF,
-0x1A, 0x43, 0x53, 0xBF,
+ 0x2A, 0x43, 0x4B, 0xBF,
+ 0x1A, 0x43, 0x53, 0xBF,
-0x30, 0x50, 0x2E, 0x9F,
-0x35, 0x30, 0x4F, 0xE9,
+ 0x30, 0x50, 0x2E, 0x9F,
+ 0x35, 0x30, 0x4F, 0xE9,
-0x38, 0x21, 0x2C, 0x9F,
-0x39, 0x38, 0x4F, 0xE9,
+ 0x38, 0x21, 0x2C, 0x9F,
+ 0x39, 0x38, 0x4F, 0xE9,
-0x31, 0x53, 0x2F, 0x9F,
-0x80, 0x31, 0x57, 0xE9,
+ 0x31, 0x53, 0x2F, 0x9F,
+ 0x80, 0x31, 0x57, 0xE9,
-0x39, 0xE5, 0x2C, 0x9F,
-0x81, 0x39, 0x57, 0xE9,
+ 0x39, 0xE5, 0x2C, 0x9F,
+ 0x81, 0x39, 0x57, 0xE9,
-0x37, 0x48, 0x50, 0xBD,
-0x8A, 0x36, 0x20, 0xE9,
+ 0x37, 0x48, 0x50, 0xBD,
+ 0x8A, 0x36, 0x20, 0xE9,
-0x86, 0x76, 0x57, 0xE9,
-0x8B, 0x3E, 0x20, 0xE9,
+ 0x86, 0x76, 0x57, 0xE9,
+ 0x8B, 0x3E, 0x20, 0xE9,
-0x82, 0x30, 0x57, 0xE9,
-0x87, 0x77, 0x57, 0xE9,
+ 0x82, 0x30, 0x57, 0xE9,
+ 0x87, 0x77, 0x57, 0xE9,
-0x83, 0x38, 0x57, 0xE9,
-0x35, 0x49, 0x51, 0xBD,
+ 0x83, 0x38, 0x57, 0xE9,
+ 0x35, 0x49, 0x51, 0xBD,
-0x84, 0x31, 0x5E, 0xE9,
-0x30, 0x1F, 0x5F, 0xE9,
+ 0x84, 0x31, 0x5E, 0xE9,
+ 0x30, 0x1F, 0x5F, 0xE9,
-0x85, 0x39, 0x5E, 0xE9,
-0x57, 0x25, 0x20, 0xE9,
+ 0x85, 0x39, 0x5E, 0xE9,
+ 0x57, 0x25, 0x20, 0xE9,
-0x2B, 0x48, 0x20, 0xE9,
-0x1D, 0x37, 0xE1, 0xEA,
+ 0x2B, 0x48, 0x20, 0xE9,
+ 0x1D, 0x37, 0xE1, 0xEA,
-0x1E, 0x35, 0xE1, 0xEA,
-0x00, 0xE0,
-0x26, 0x77,
+ 0x1E, 0x35, 0xE1, 0xEA,
+ 0x00, 0xE0,
+ 0x26, 0x77,
-0x24, 0x49, 0x20, 0xE9,
-0x99, 0xFF, 0x20, 0xEA,
+ 0x24, 0x49, 0x20, 0xE9,
+ 0x99, 0xFF, 0x20, 0xEA,
-0x16, 0x26, 0x20, 0xE9,
-0x57, 0x2E, 0xBF, 0xEA,
+ 0x16, 0x26, 0x20, 0xE9,
+ 0x57, 0x2E, 0xBF, 0xEA,
-0x1C, 0x46, 0xA0, 0xE8,
-0x23, 0x4E, 0xA0, 0xE8,
+ 0x1C, 0x46, 0xA0, 0xE8,
+ 0x23, 0x4E, 0xA0, 0xE8,
-0x2B, 0x56, 0xA0, 0xE8,
-0x1D, 0x47, 0xA0, 0xE8,
+ 0x2B, 0x56, 0xA0, 0xE8,
+ 0x1D, 0x47, 0xA0, 0xE8,
-0x24, 0x4F, 0xA0, 0xE8,
-0x2C, 0x57, 0xA0, 0xE8,
+ 0x24, 0x4F, 0xA0, 0xE8,
+ 0x2C, 0x57, 0xA0, 0xE8,
-0x1C, 0x00,
-0x23, 0x00,
-0x2B, 0x00,
-0x00, 0xE0,
+ 0x1C, 0x00,
+ 0x23, 0x00,
+ 0x2B, 0x00,
+ 0x00, 0xE0,
-0x1D, 0x00,
-0x24, 0x00,
-0x2C, 0x00,
-0x00, 0xE0,
+ 0x1D, 0x00,
+ 0x24, 0x00,
+ 0x2C, 0x00,
+ 0x00, 0xE0,
-0x1C, 0x65,
-0x23, 0x65,
-0x2B, 0x65,
-0x00, 0xE0,
+ 0x1C, 0x65,
+ 0x23, 0x65,
+ 0x2B, 0x65,
+ 0x00, 0xE0,
-0x1D, 0x65,
-0x24, 0x65,
-0x2C, 0x65,
-0x00, 0xE0,
+ 0x1D, 0x65,
+ 0x24, 0x65,
+ 0x2C, 0x65,
+ 0x00, 0xE0,
-0x1C, 0x23, 0x60, 0xEC,
-0x36, 0xD7, 0x36, 0xAD,
+ 0x1C, 0x23, 0x60, 0xEC,
+ 0x36, 0xD7, 0x36, 0xAD,
-0x2B, 0x80, 0x60, 0xEC,
-0x1D, 0x24, 0x60, 0xEC,
+ 0x2B, 0x80, 0x60, 0xEC,
+ 0x1D, 0x24, 0x60, 0xEC,
-0x3E, 0xD7, 0x3E, 0xAD,
-0x2C, 0x80, 0x60, 0xEC,
+ 0x3E, 0xD7, 0x3E, 0xAD,
+ 0x2C, 0x80, 0x60, 0xEC,
-0x1C, 0x2B, 0xDE, 0xE8,
-0x23, 0x80, 0xDE, 0xE8,
+ 0x1C, 0x2B, 0xDE, 0xE8,
+ 0x23, 0x80, 0xDE, 0xE8,
-0x36, 0x80, 0x36, 0xBD,
-0x3E, 0x80, 0x3E, 0xBD,
+ 0x36, 0x80, 0x36, 0xBD,
+ 0x3E, 0x80, 0x3E, 0xBD,
-0x33, 0xD7, 0x1C, 0xBD,
-0x3B, 0xD7, 0x23, 0xBD,
+ 0x33, 0xD7, 0x1C, 0xBD,
+ 0x3B, 0xD7, 0x23, 0xBD,
-0x46, 0x80, 0x46, 0xCF,
-0x4F, 0x80, 0x4F, 0xCF,
+ 0x46, 0x80, 0x46, 0xCF,
+ 0x4F, 0x80, 0x4F, 0xCF,
-0x56, 0x33, 0x56, 0xCF,
-0x47, 0x3B, 0x47, 0xCF,
+ 0x56, 0x33, 0x56, 0xCF,
+ 0x47, 0x3B, 0x47, 0xCF,
-0xC1, 0xFF, 0x20, 0xEA,
-0x00, 0x80, 0x00, 0xE8,
+ 0xC1, 0xFF, 0x20, 0xEA,
+ 0x00, 0x80, 0x00, 0xE8,
-0x4E, 0x33, 0x4E, 0xCF,
-0x57, 0x3B, 0x57, 0xCF,
+ 0x4E, 0x33, 0x4E, 0xCF,
+ 0x57, 0x3B, 0x57, 0xCF,
-0x87, 0xFF, 0x20, 0xEA,
-0x57, 0xC0, 0xBF, 0xEA,
+ 0x87, 0xFF, 0x20, 0xEA,
+ 0x57, 0xC0, 0xBF, 0xEA,
-0x00, 0x80, 0xA0, 0xE9,
-0x00, 0x00, 0xD8, 0xEC,
+ 0x00, 0x80, 0xA0, 0xE9,
+ 0x00, 0x00, 0xD8, 0xEC,
};
static unsigned char warp_g400_tgzsf[] = {
-0x00, 0x88, 0x98, 0xE9,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x88, 0x98, 0xE9,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0xA0, 0xE9,
-0x00, 0x00, 0xD8, 0xEC,
+ 0x00, 0x80, 0xA0, 0xE9,
+ 0x00, 0x00, 0xD8, 0xEC,
-0xFF, 0x80, 0xC0, 0xE9,
-0x00, 0x80, 0x00, 0xE8,
+ 0xFF, 0x80, 0xC0, 0xE9,
+ 0x00, 0x80, 0x00, 0xE8,
-0x22, 0x40, 0x48, 0xBF,
-0x2A, 0x40, 0x50, 0xBF,
+ 0x22, 0x40, 0x48, 0xBF,
+ 0x2A, 0x40, 0x50, 0xBF,
-0x32, 0x41, 0x49, 0xBF,
-0x3A, 0x41, 0x51, 0xBF,
+ 0x32, 0x41, 0x49, 0xBF,
+ 0x3A, 0x41, 0x51, 0xBF,
-0xC3, 0x6B,
-0xCB, 0x6B,
-0x00, 0x88, 0x98, 0xE9,
+ 0xC3, 0x6B,
+ 0xCB, 0x6B,
+ 0x00, 0x88, 0x98, 0xE9,
-0x73, 0x7B, 0xC8, 0xEC,
-0x96, 0xE2,
-0x41, 0x04,
+ 0x73, 0x7B, 0xC8, 0xEC,
+ 0x96, 0xE2,
+ 0x41, 0x04,
-0x7B, 0x43, 0xA0, 0xE8,
-0x73, 0x4B, 0xA0, 0xE8,
+ 0x7B, 0x43, 0xA0, 0xE8,
+ 0x73, 0x4B, 0xA0, 0xE8,
-0xAD, 0xEE, 0x29, 0x9F,
-0x00, 0xE0,
-0x49, 0x04,
+ 0xAD, 0xEE, 0x29, 0x9F,
+ 0x00, 0xE0,
+ 0x49, 0x04,
-0x90, 0xE2,
-0x51, 0x04,
-0x31, 0x46, 0xB1, 0xE8,
+ 0x90, 0xE2,
+ 0x51, 0x04,
+ 0x31, 0x46, 0xB1, 0xE8,
-0x49, 0x41, 0xC0, 0xEC,
-0x39, 0x57, 0xB1, 0xE8,
+ 0x49, 0x41, 0xC0, 0xEC,
+ 0x39, 0x57, 0xB1, 0xE8,
-0x00, 0x04,
-0x46, 0xE2,
-0x73, 0x53, 0xA0, 0xE8,
+ 0x00, 0x04,
+ 0x46, 0xE2,
+ 0x73, 0x53, 0xA0, 0xE8,
-0x51, 0x41, 0xC0, 0xEC,
-0x31, 0x00,
-0x39, 0x00,
+ 0x51, 0x41, 0xC0, 0xEC,
+ 0x31, 0x00,
+ 0x39, 0x00,
-0x6A, 0x80, 0x15, 0xEA,
-0x08, 0x04,
-0x10, 0x04,
+ 0x6A, 0x80, 0x15, 0xEA,
+ 0x08, 0x04,
+ 0x10, 0x04,
-0x51, 0x49, 0xC0, 0xEC,
-0x2F, 0x41, 0x60, 0xEA,
+ 0x51, 0x49, 0xC0, 0xEC,
+ 0x2F, 0x41, 0x60, 0xEA,
-0x31, 0x20,
-0x39, 0x20,
-0x1F, 0x42, 0xA0, 0xE8,
+ 0x31, 0x20,
+ 0x39, 0x20,
+ 0x1F, 0x42, 0xA0, 0xE8,
-0x2A, 0x42, 0x4A, 0xBF,
-0x27, 0x4A, 0xA0, 0xE8,
+ 0x2A, 0x42, 0x4A, 0xBF,
+ 0x27, 0x4A, 0xA0, 0xE8,
-0x1A, 0x42, 0x52, 0xBF,
-0x1E, 0x49, 0x60, 0xEA,
+ 0x1A, 0x42, 0x52, 0xBF,
+ 0x1E, 0x49, 0x60, 0xEA,
-0x73, 0x7B, 0xC8, 0xEC,
-0x26, 0x51, 0x60, 0xEA,
+ 0x73, 0x7B, 0xC8, 0xEC,
+ 0x26, 0x51, 0x60, 0xEA,
-0x32, 0x40, 0x48, 0xBD,
-0x22, 0x40, 0x50, 0xBD,
+ 0x32, 0x40, 0x48, 0xBD,
+ 0x22, 0x40, 0x50, 0xBD,
-0x12, 0x41, 0x49, 0xBD,
-0x3A, 0x41, 0x51, 0xBD,
+ 0x12, 0x41, 0x49, 0xBD,
+ 0x3A, 0x41, 0x51, 0xBD,
-0xBF, 0x2F, 0x26, 0xBD,
-0x00, 0xE0,
-0x7B, 0x72,
+ 0xBF, 0x2F, 0x26, 0xBD,
+ 0x00, 0xE0,
+ 0x7B, 0x72,
-0x32, 0x20,
-0x22, 0x20,
-0x12, 0x20,
-0x3A, 0x20,
+ 0x32, 0x20,
+ 0x22, 0x20,
+ 0x12, 0x20,
+ 0x3A, 0x20,
-0x46, 0x31, 0x46, 0xBF,
-0x4E, 0x31, 0x4E, 0xBF,
+ 0x46, 0x31, 0x46, 0xBF,
+ 0x4E, 0x31, 0x4E, 0xBF,
-0xB3, 0xE2, 0x2D, 0x9F,
-0x00, 0x80, 0x00, 0xE8,
+ 0xB3, 0xE2, 0x2D, 0x9F,
+ 0x00, 0x80, 0x00, 0xE8,
-0x56, 0x31, 0x56, 0xBF,
-0x47, 0x39, 0x47, 0xBF,
+ 0x56, 0x31, 0x56, 0xBF,
+ 0x47, 0x39, 0x47, 0xBF,
-0x4F, 0x39, 0x4F, 0xBF,
-0x57, 0x39, 0x57, 0xBF,
+ 0x4F, 0x39, 0x4F, 0xBF,
+ 0x57, 0x39, 0x57, 0xBF,
-0x5C, 0x80, 0x07, 0xEA,
-0x24, 0x41, 0x20, 0xE9,
+ 0x5C, 0x80, 0x07, 0xEA,
+ 0x24, 0x41, 0x20, 0xE9,
-0x42, 0x73, 0xF8, 0xEC,
-0x00, 0xE0,
-0x2D, 0x73,
+ 0x42, 0x73, 0xF8, 0xEC,
+ 0x00, 0xE0,
+ 0x2D, 0x73,
-0x33, 0x72,
-0x0C, 0xE3,
-0xA5, 0x2F, 0x1E, 0xBD,
+ 0x33, 0x72,
+ 0x0C, 0xE3,
+ 0xA5, 0x2F, 0x1E, 0xBD,
-0x43, 0x43, 0x2D, 0xDF,
-0x4B, 0x4B, 0x2D, 0xDF,
+ 0x43, 0x43, 0x2D, 0xDF,
+ 0x4B, 0x4B, 0x2D, 0xDF,
-0xAE, 0x1E, 0x26, 0xBD,
-0x58, 0xE3,
-0x33, 0x66,
+ 0xAE, 0x1E, 0x26, 0xBD,
+ 0x58, 0xE3,
+ 0x33, 0x66,
-0x53, 0x53, 0x2D, 0xDF,
-0x00, 0x80, 0x00, 0xE8,
+ 0x53, 0x53, 0x2D, 0xDF,
+ 0x00, 0x80, 0x00, 0xE8,
-0xB8, 0x38, 0x33, 0xBF,
-0x00, 0xE0,
-0x59, 0xE3,
+ 0xB8, 0x38, 0x33, 0xBF,
+ 0x00, 0xE0,
+ 0x59, 0xE3,
-0x1E, 0x12, 0x41, 0xE9,
-0x1A, 0x22, 0x41, 0xE9,
+ 0x1E, 0x12, 0x41, 0xE9,
+ 0x1A, 0x22, 0x41, 0xE9,
-0x2B, 0x40, 0x3D, 0xE9,
-0x3F, 0x4B, 0xA0, 0xE8,
+ 0x2B, 0x40, 0x3D, 0xE9,
+ 0x3F, 0x4B, 0xA0, 0xE8,
-0x2D, 0x73,
-0x30, 0x76,
-0x05, 0x80, 0x3D, 0xEA,
+ 0x2D, 0x73,
+ 0x30, 0x76,
+ 0x05, 0x80, 0x3D, 0xEA,
-0x37, 0x43, 0xA0, 0xE8,
-0x3D, 0x53, 0xA0, 0xE8,
+ 0x37, 0x43, 0xA0, 0xE8,
+ 0x3D, 0x53, 0xA0, 0xE8,
-0x48, 0x70, 0xF8, 0xEC,
-0x2B, 0x48, 0x3C, 0xE9,
+ 0x48, 0x70, 0xF8, 0xEC,
+ 0x2B, 0x48, 0x3C, 0xE9,
-0x1F, 0x27, 0xBC, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x1F, 0x27, 0xBC, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
-0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x00, 0x80, 0x00, 0xE8,
-0x15, 0xC0, 0x20, 0xE9,
-0x15, 0xC0, 0x20, 0xE9,
+ 0x15, 0xC0, 0x20, 0xE9,
+ 0x15, 0xC0, 0x20, 0xE9,
-0x15, 0xC0, 0x20, 0xE9,
-0x15, 0xC0, 0x20, 0xE9,
+ 0x15, 0xC0, 0x20, 0xE9,
+ 0x15, 0xC0, 0x20, 0xE9,
-0x18, 0x3A, 0x41, 0xE9,
-0x1D, 0x32, 0x41, 0xE9,
+ 0x18, 0x3A, 0x41, 0xE9,
+ 0x1D, 0x32, 0x41, 0xE9,
-0x2A, 0x40, 0x20, 0xE9,
-0x56, 0x3D, 0x56, 0xDF,
+ 0x2A, 0x40, 0x20, 0xE9,
+ 0x56, 0x3D, 0x56, 0xDF,
-0x46, 0x37, 0x46, 0xDF,
-0x4E, 0x3F, 0x4E, 0xDF,
+ 0x46, 0x37, 0x46, 0xDF,
+ 0x4E, 0x3F, 0x4E, 0xDF,
-0x16, 0x30, 0x20, 0xE9,
-0x4F, 0x3F, 0x4F, 0xDF,
+ 0x16, 0x30, 0x20, 0xE9,
+ 0x4F, 0x3F, 0x4F, 0xDF,
-0x47, 0x37, 0x47, 0xDF,
-0x57, 0x3D, 0x57, 0xDF,
+ 0x47, 0x37, 0x47, 0xDF,
+ 0x57, 0x3D, 0x57, 0xDF,
-0x32, 0x32, 0x2D, 0xDF,
-0x22, 0x22, 0x2D, 0xDF,
+ 0x32, 0x32, 0x2D, 0xDF,
+ 0x22, 0x22, 0x2D, 0xDF,
-0x12, 0x12, 0x2D, 0xDF,
-0x3A, 0x3A, 0x2D, 0xDF,
+ 0x12, 0x12, 0x2D, 0xDF,
+ 0x3A, 0x3A, 0x2D, 0xDF,
-0x27, 0xCF, 0x74, 0xC2,
-0x37, 0xCF, 0x74, 0xC4,
+ 0x27, 0xCF, 0x74, 0xC2,
+ 0x37, 0xCF, 0x74, 0xC4,
-0x0A, 0x44, 0x4C, 0xB0,
-0x02, 0x44, 0x54, 0xB0,
+ 0x0A, 0x44, 0x4C, 0xB0,
+ 0x02, 0x44, 0x54, 0xB0,
-0x3D, 0xCF, 0x74, 0xC0,
-0x34, 0x37, 0x20, 0xE9,
+ 0x3D, 0xCF, 0x74, 0xC0,
+ 0x34, 0x37, 0x20, 0xE9,
-0x31, 0x53, 0x2F, 0x9F,
-0x38, 0x27, 0x20, 0xE9,
+ 0x31, 0x53, 0x2F, 0x9F,
+ 0x38, 0x27, 0x20, 0xE9,
-0x39, 0xE5, 0x2C, 0x9F,
-0x3C, 0x3D, 0x20, 0xE9,
+ 0x39, 0xE5, 0x2C, 0x9F,
+ 0x3C, 0x3D, 0x20, 0xE9,
-0x2A, 0x44, 0x4C, 0xB2,
-0x1A, 0x44, 0x54, 0xB2,
+ 0x2A, 0x44, 0x4C, 0xB2,
+ 0x1A, 0x44, 0x54, 0xB2,
-0x2E, 0x80, 0x3A, 0xEA,
-0x0A, 0x20,
-0x02, 0x20,
+ 0x2E, 0x80, 0x3A, 0xEA,
+ 0x0A, 0x20,
+ 0x02, 0x20,
-0x27, 0xCF, 0x75, 0xC0,
-0x2A, 0x20,
-0x1A, 0x20,
+ 0x27, 0xCF, 0x75, 0xC0,
+ 0x2A, 0x20,
+ 0x1A, 0x20,
-0x30, 0x50, 0x2E, 0x9F,
-0x32, 0x31, 0x5F, 0xE9,
+ 0x30, 0x50, 0x2E, 0x9F,
+ 0x32, 0x31, 0x5F, 0xE9,
-0x38, 0x21, 0x2C, 0x9F,
-0x33, 0x39, 0x5F, 0xE9,
+ 0x38, 0x21, 0x2C, 0x9F,
+ 0x33, 0x39, 0x5F, 0xE9,
-0x3D, 0xCF, 0x75, 0xC2,
-0x37, 0xCF, 0x75, 0xC4,
+ 0x3D, 0xCF, 0x75, 0xC2,
+ 0x37, 0xCF, 0x75, 0xC4,
-0x31, 0x53, 0x2F, 0x9F,
-0xA6, 0x27, 0x20, 0xE9,
+ 0x31, 0x53, 0x2F, 0x9F,
+ 0xA6, 0x27, 0x20, 0xE9,
-0x39, 0xE5, 0x2C, 0x9F,
-0xA3, 0x3D, 0x20, 0xE9,
+ 0x39, 0xE5, 0x2C, 0x9F,
+ 0xA3, 0x3D, 0x20, 0xE9,
-0x2A, 0x44, 0x4C, 0xB4,
-0x1A, 0x44, 0x54, 0xB4,
+ 0x2A, 0x44, 0x4C, 0xB4,
+ 0x1A, 0x44, 0x54, 0xB4,
-0x0A, 0x45, 0x4D, 0xB0,
-0x02, 0x45, 0x55, 0xB0,
+ 0x0A, 0x45, 0x4D, 0xB0,
+ 0x02, 0x45, 0x55, 0xB0,
-0x88, 0x73, 0x5E, 0xE9,
-0x2A, 0x20,
-0x1A, 0x20,
+ 0x88, 0x73, 0x5E, 0xE9,
+ 0x2A, 0x20,
+ 0x1A, 0x20,
-0xA0, 0x37, 0x20, 0xE9,
-0x0A, 0x20,
-0x02, 0x20,
+ 0xA0, 0x37, 0x20, 0xE9,
+ 0x0A, 0x20,
+ 0x02, 0x20,
-0x31, 0x53, 0x2F, 0x9F,
-0x3E, 0x30, 0x4F, 0xE9,
+ 0x31, 0x53, 0x2F, 0x9F,
+ 0x3E, 0x30, 0x4F, 0xE9,
-0x39, 0xE5, 0x2C, 0x9F,
-0x3F, 0x38, 0x4F, 0xE9,
+ 0x39, 0xE5, 0x2C, 0x9F,
+ 0x3F, 0x38, 0x4F, 0xE9,
-0x30, 0x50, 0x2E, 0x9F,
-0x3A, 0x31, 0x4F, 0xE9,
+ 0x30, 0x50, 0x2E, 0x9F,
+ 0x3A, 0x31, 0x4F, 0xE9,
-0x38, 0x21, 0x2C, 0x9F,
-0x3B, 0x39, 0x4F, 0xE9,
+ 0x38, 0x21, 0x2C, 0x9F,
+ 0x3B, 0x39, 0x4F, 0xE9,
-0x2A, 0x45, 0x4D, 0xB2,
-0x1A, 0x45, 0x55, 0xB2,
+ 0x2A, 0x45, 0x4D, 0xB2,
+ 0x1A, 0x45, 0x55, 0xB2,
-0x0A, 0x45, 0x4D, 0xB4,
-0x02, 0x45, 0x55, 0xB4,
+ 0x0A, 0x45, 0x4D, 0xB4,
+ 0x02, 0x45, 0x55, 0xB4,
-0x27, 0xCF, 0x75, 0xC6,
-0x2A, 0x20,
-0x1A, 0x20,
+ 0x27, 0xCF, 0x75, 0xC6,
+ 0x2A, 0x20,
+ 0x1A, 0x20,
-0xA7, 0x30, 0x4F, 0xE9,
-0x0A, 0x20,
-0x02, 0x20,
+ 0xA7, 0x30, 0x4F, 0xE9,
+ 0x0A, 0x20,
+ 0x02, 0x20,
-0x31, 0x53, 0x2F, 0x9F,
-0x31, 0x27, 0x20, 0xE9,
+ 0x31, 0x53, 0x2F, 0x9F,
+ 0x31, 0x27, 0x20, 0xE9,
-0x39, 0xE5, 0x2C, 0x9F,
-0xA8, 0x38, 0x4F, 0xE9,
+ 0x39, 0xE5, 0x2C, 0x9F,
+ 0xA8, 0x38, 0x4F, 0xE9,
-0x2A, 0x45, 0x4D, 0xB6,
-0x1A, 0x45, 0x55, 0xB6,
+ 0x2A, 0x45, 0x4D, 0xB6,
+ 0x1A, 0x45, 0x55, 0xB6,
-0x30, 0x50, 0x2E, 0x9F,
-0x36, 0x31, 0x4F, 0xE9,
+ 0x30, 0x50, 0x2E, 0x9F,
+ 0x36, 0x31, 0x4F, 0xE9,
-0x38, 0x21, 0x2C, 0x9F,
-0x37, 0x39, 0x4F, 0xE9,
+ 0x38, 0x21, 0x2C, 0x9F,
+ 0x37, 0x39, 0x4F, 0xE9,
-0x00, 0x80, 0x00, 0xE8,
-0x2A, 0x20,
-0x1A, 0x20,
+ 0x00, 0x80, 0x00, 0xE8,
+ 0x2A, 0x20,
+ 0x1A, 0x20,
-0x2A, 0x46, 0x4E, 0xBF,
-0x1A, 0x46, 0x56, 0xBF,
+ 0x2A, 0x46, 0x4E, 0xBF,
+ 0x1A, 0x46, 0x56, 0xBF,
-0x31, 0x53, 0x2F, 0x9F,
-0xA4, 0x31, 0x4F, 0xE9,
+ 0x31, 0x53, 0x2F, 0x9F,
+ 0xA4, 0x31, 0x4F, 0xE9,
-0x39, 0xE5, 0x2C, 0x9F,
-0xA5, 0x39, 0x4F, 0xE9,
+ 0x39, 0xE5, 0x2C, 0x9F,
+ 0xA5, 0x39, 0x4F, 0xE9,
-0x0A, 0x47, 0x4F, 0xBF,
-0x02, 0x47, 0x57, 0xBF,
+ 0x0A, 0x47, 0x4F, 0xBF,
+ 0x02, 0x47, 0x57, 0xBF,
-0x31, 0x53, 0x2F, 0x9F,
-0xA1, 0x30, 0x4F, 0xE9,
+ 0x31, 0x53, 0x2F, 0x9F,
+ 0xA1, 0x30, 0x4F, 0xE9,
-0x39, 0xE5, 0x2C, 0x9F,
-0xA2, 0x38, 0x4F, 0xE9,
+ 0x39, 0xE5, 0x2C, 0x9F,
+ 0xA2, 0x38, 0x4F, 0xE9,
-0x2A, 0x43, 0x4B, 0xBF,
-0x1A, 0x43, 0x53, 0xBF,
+ 0x2A, 0x43, 0x4B, 0xBF,
+ 0x1A, 0x43, 0x53, 0xBF,
-0x30, 0x50, 0x2E, 0x9F,
-0x35, 0x31, 0x4F, 0xE9,
+ 0x30, 0x50, 0x2E, 0x9F,
+ 0x35, 0x31, 0x4F, 0xE9,
-0x38, 0x21, 0x2C, 0x9F,
-0x39, 0x39, 0x4F, 0xE9,
+ 0x38, 0x21, 0x2C, 0x9F,
+ 0x39, 0x39, 0x4F, 0xE9,
-0x31, 0x53, 0x2F, 0x9F,
-0x80, 0x31, 0x57, 0xE9,
+ 0x31, 0x53, 0x2F, 0x9F,
+ 0x80, 0x31, 0x57, 0xE9,
-0x39, 0xE5, 0x2C, 0x9F,
-0x81, 0x39, 0x57, 0xE9,
+ 0x39, 0xE5, 0x2C, 0x9F,
+ 0x81, 0x39, 0x57, 0xE9,
-0x37, 0x48, 0x50, 0xBD,
-0x8A, 0x36, 0x20, 0xE9,
+ 0x37, 0x48, 0x50, 0xBD,
+ 0x8A, 0x36, 0x20, 0xE9,
-0x86, 0x76, 0x57, 0xE9,
-0x8B, 0x3E, 0x20, 0xE9,
+ 0x86, 0x76, 0x57, 0xE9,
+ 0x8B, 0x3E, 0x20, 0xE9,
-0x82, 0x30, 0x57, 0xE9,
-0x87, 0x77, 0x57, 0xE9,
+ 0x82, 0x30, 0x57, 0xE9,
+ 0x87, 0x77, 0x57, 0xE9,
-0x83, 0x38, 0x57, 0xE9,
-0x35, 0x49, 0x51, 0xBD,
+ 0x83, 0x38, 0x57, 0xE9,
+ 0x35, 0x49, 0x51, 0xBD,
-0x84, 0x31, 0x5E, 0xE9,
-0x30, 0x1F, 0x5F, 0xE9,
+ 0x84, 0x31, 0x5E, 0xE9,
+ 0x30, 0x1F, 0x5F, 0xE9,
-0x85, 0x39, 0x5E, 0xE9,
-0x57, 0x25, 0x20, 0xE9,
+ 0x85, 0x39, 0x5E, 0xE9,
+ 0x57, 0x25, 0x20, 0xE9,
-0x2B, 0x48, 0x20, 0xE9,
-0x1D, 0x37, 0xE1, 0xEA,
+ 0x2B, 0x48, 0x20, 0xE9,
+ 0x1D, 0x37, 0xE1, 0xEA,
-0x1E, 0x35, 0xE1, 0xEA,
-0x00, 0xE0,
-0x26, 0x77,
+ 0x1E, 0x35, 0xE1, 0xEA,
+ 0x00, 0xE0,
+ 0x26, 0x77,
-0x24, 0x49, 0x20, 0xE9,
-0x9D, 0xFF, 0x20, 0xEA,
+ 0x24, 0x49, 0x20, 0xE9,
+ 0x9D, 0xFF, 0x20, 0xEA,
-0x16, 0x26, 0x20, 0xE9,
-0x57, 0x2E, 0xBF, 0xEA,
+ 0x16, 0x26, 0x20, 0xE9,
+ 0x57, 0x2E, 0xBF, 0xEA,
-0x1C, 0x46, 0xA0, 0xE8,
-0x23, 0x4E, 0xA0, 0xE8,
+ 0x1C, 0x46, 0xA0, 0xE8,
+ 0x23, 0x4E, 0xA0, 0xE8,
-0x2B, 0x56, 0xA0, 0xE8,
-0x1D, 0x47, 0xA0, 0xE8,
+ 0x2B, 0x56, 0xA0, 0xE8,
+ 0x1D, 0x47, 0xA0, 0xE8,
-0x24, 0x4F, 0xA0, 0xE8,
-0x2C, 0x57, 0xA0, 0xE8,
+ 0x24, 0x4F, 0xA0, 0xE8,
+ 0x2C, 0x57, 0xA0, 0xE8,
-0x1C, 0x00,
-0x23, 0x00,
-0x2B, 0x00,
-0x00, 0xE0,
+ 0x1C, 0x00,
+ 0x23, 0x00,
+ 0x2B, 0x00,
+ 0x00, 0xE0,
-0x1D, 0x00,
-0x24, 0x00,
-0x2C, 0x00,
-0x00, 0xE0,
+ 0x1D, 0x00,
+ 0x24, 0x00,
+ 0x2C, 0x00,
+ 0x00, 0xE0,
-0x1C, 0x65,
-0x23, 0x65,
-0x2B, 0x65,
-0x00, 0xE0,
+ 0x1C, 0x65,
+ 0x23, 0x65,
+ 0x2B, 0x65,
+ 0x00, 0xE0,
-0x1D, 0x65,
-0x24, 0x65,
-0x2C, 0x65,
-0x00, 0xE0,
+ 0x1D, 0x65,
+ 0x24, 0x65,
+ 0x2C, 0x65,
+ 0x00, 0xE0,
-0x1C, 0x23, 0x60, 0xEC,
-0x36, 0xD7, 0x36, 0xAD,
+ 0x1C, 0x23, 0x60, 0xEC,
+ 0x36, 0xD7, 0x36, 0xAD,
-0x2B, 0x80, 0x60, 0xEC,
-0x1D, 0x24, 0x60, 0xEC,
+ 0x2B, 0x80, 0x60, 0xEC,
+ 0x1D, 0x24, 0x60, 0xEC,
-0x3E, 0xD7, 0x3E, 0xAD,
-0x2C, 0x80, 0x60, 0xEC,
+ 0x3E, 0xD7, 0x3E, 0xAD,
+ 0x2C, 0x80, 0x60, 0xEC,
-0x1C, 0x2B, 0xDE, 0xE8,
-0x23, 0x80, 0xDE, 0xE8,
+ 0x1C, 0x2B, 0xDE, 0xE8,
+ 0x23, 0x80, 0xDE, 0xE8,
-0x36, 0x80, 0x36, 0xBD,
-0x3E, 0x80, 0x3E, 0xBD,
+ 0x36, 0x80, 0x36, 0xBD,
+ 0x3E, 0x80, 0x3E, 0xBD,
-0x33, 0xD7, 0x1C, 0xBD,
-0x3B, 0xD7, 0x23, 0xBD,
+ 0x33, 0xD7, 0x1C, 0xBD,
+ 0x3B, 0xD7, 0x23, 0xBD,
-0x46, 0x80, 0x46, 0xCF,
-0x4F, 0x80, 0x4F, 0xCF,
+ 0x46, 0x80, 0x46, 0xCF,
+ 0x4F, 0x80, 0x4F, 0xCF,
-0x56, 0x33, 0x56, 0xCF,
-0x47, 0x3B, 0x47, 0xCF,
+ 0x56, 0x33, 0x56, 0xCF,
+ 0x47, 0x3B, 0x47, 0xCF,
-0xC5, 0xFF, 0x20, 0xEA,
-0x00, 0x80, 0x00, 0xE8,
+ 0xC5, 0xFF, 0x20, 0xEA,
+ 0x00, 0x80, 0x00, 0xE8,
-0x4E, 0x33, 0x4E, 0xCF,
-0x57, 0x3B, 0x57, 0xCF,
+ 0x4E, 0x33, 0x4E, 0xCF,
+ 0x57, 0x3B, 0x57, 0xCF,
-0x8B, 0xFF, 0x20, 0xEA,
-0x57, 0xC0, 0xBF, 0xEA,
+ 0x8B, 0xFF, 0x20, 0xEA,
+ 0x57, 0xC0, 0xBF, 0xEA,
-0x00, 0x80, 0xA0, 0xE9,
-0x00, 0x00, 0xD8, 0xEC,
+ 0x00, 0x80, 0xA0, 0xE9,
+ 0x00, 0x00, 0xD8, 0xEC,
};
diff --git a/drivers/char/drm/mga_warp.c b/drivers/char/drm/mga_warp.c
index 55ccc8a0ac29..d67f4925fbac 100644
--- a/drivers/char/drm/mga_warp.c
+++ b/drivers/char/drm/mga_warp.c
@@ -33,8 +33,7 @@
#include "mga_drv.h"
#include "mga_ucode.h"
-
-#define MGA_WARP_CODE_ALIGN 256 /* in bytes */
+#define MGA_WARP_CODE_ALIGN 256 /* in bytes */
#define WARP_UCODE_SIZE( which ) \
((sizeof(which) / MGA_WARP_CODE_ALIGN + 1) * MGA_WARP_CODE_ALIGN)
@@ -49,33 +48,30 @@ do { \
} while (0)
static const unsigned int mga_warp_g400_microcode_size =
- (WARP_UCODE_SIZE(warp_g400_tgz) +
- WARP_UCODE_SIZE(warp_g400_tgza) +
- WARP_UCODE_SIZE(warp_g400_tgzaf) +
- WARP_UCODE_SIZE(warp_g400_tgzf) +
- WARP_UCODE_SIZE(warp_g400_tgzs) +
- WARP_UCODE_SIZE(warp_g400_tgzsa) +
- WARP_UCODE_SIZE(warp_g400_tgzsaf) +
- WARP_UCODE_SIZE(warp_g400_tgzsf) +
- WARP_UCODE_SIZE(warp_g400_t2gz) +
- WARP_UCODE_SIZE(warp_g400_t2gza) +
- WARP_UCODE_SIZE(warp_g400_t2gzaf) +
- WARP_UCODE_SIZE(warp_g400_t2gzf) +
- WARP_UCODE_SIZE(warp_g400_t2gzs) +
- WARP_UCODE_SIZE(warp_g400_t2gzsa) +
- WARP_UCODE_SIZE(warp_g400_t2gzsaf) +
- WARP_UCODE_SIZE(warp_g400_t2gzsf));
+ (WARP_UCODE_SIZE(warp_g400_tgz) +
+ WARP_UCODE_SIZE(warp_g400_tgza) +
+ WARP_UCODE_SIZE(warp_g400_tgzaf) +
+ WARP_UCODE_SIZE(warp_g400_tgzf) +
+ WARP_UCODE_SIZE(warp_g400_tgzs) +
+ WARP_UCODE_SIZE(warp_g400_tgzsa) +
+ WARP_UCODE_SIZE(warp_g400_tgzsaf) +
+ WARP_UCODE_SIZE(warp_g400_tgzsf) +
+ WARP_UCODE_SIZE(warp_g400_t2gz) +
+ WARP_UCODE_SIZE(warp_g400_t2gza) +
+ WARP_UCODE_SIZE(warp_g400_t2gzaf) +
+ WARP_UCODE_SIZE(warp_g400_t2gzf) +
+ WARP_UCODE_SIZE(warp_g400_t2gzs) +
+ WARP_UCODE_SIZE(warp_g400_t2gzsa) +
+ WARP_UCODE_SIZE(warp_g400_t2gzsaf) + WARP_UCODE_SIZE(warp_g400_t2gzsf));
static const unsigned int mga_warp_g200_microcode_size =
- (WARP_UCODE_SIZE(warp_g200_tgz) +
- WARP_UCODE_SIZE(warp_g200_tgza) +
- WARP_UCODE_SIZE(warp_g200_tgzaf) +
- WARP_UCODE_SIZE(warp_g200_tgzf) +
- WARP_UCODE_SIZE(warp_g200_tgzs) +
- WARP_UCODE_SIZE(warp_g200_tgzsa) +
- WARP_UCODE_SIZE(warp_g200_tgzsaf) +
- WARP_UCODE_SIZE(warp_g200_tgzsf));
-
+ (WARP_UCODE_SIZE(warp_g200_tgz) +
+ WARP_UCODE_SIZE(warp_g200_tgza) +
+ WARP_UCODE_SIZE(warp_g200_tgzaf) +
+ WARP_UCODE_SIZE(warp_g200_tgzf) +
+ WARP_UCODE_SIZE(warp_g200_tgzs) +
+ WARP_UCODE_SIZE(warp_g200_tgzsa) +
+ WARP_UCODE_SIZE(warp_g200_tgzsaf) + WARP_UCODE_SIZE(warp_g200_tgzsf));
unsigned int mga_warp_microcode_size(const drm_mga_private_t * dev_priv)
{
@@ -90,36 +86,35 @@ unsigned int mga_warp_microcode_size(const drm_mga_private_t * dev_priv)
}
}
-static int mga_warp_install_g400_microcode( drm_mga_private_t *dev_priv )
+static int mga_warp_install_g400_microcode(drm_mga_private_t * dev_priv)
{
unsigned char *vcbase = dev_priv->warp->handle;
unsigned long pcbase = dev_priv->warp->offset;
- memset( dev_priv->warp_pipe_phys, 0,
- sizeof(dev_priv->warp_pipe_phys) );
-
- WARP_UCODE_INSTALL( warp_g400_tgz, MGA_WARP_TGZ );
- WARP_UCODE_INSTALL( warp_g400_tgzf, MGA_WARP_TGZF );
- WARP_UCODE_INSTALL( warp_g400_tgza, MGA_WARP_TGZA );
- WARP_UCODE_INSTALL( warp_g400_tgzaf, MGA_WARP_TGZAF );
- WARP_UCODE_INSTALL( warp_g400_tgzs, MGA_WARP_TGZS );
- WARP_UCODE_INSTALL( warp_g400_tgzsf, MGA_WARP_TGZSF );
- WARP_UCODE_INSTALL( warp_g400_tgzsa, MGA_WARP_TGZSA );
- WARP_UCODE_INSTALL( warp_g400_tgzsaf, MGA_WARP_TGZSAF );
-
- WARP_UCODE_INSTALL( warp_g400_t2gz, MGA_WARP_T2GZ );
- WARP_UCODE_INSTALL( warp_g400_t2gzf, MGA_WARP_T2GZF );
- WARP_UCODE_INSTALL( warp_g400_t2gza, MGA_WARP_T2GZA );
- WARP_UCODE_INSTALL( warp_g400_t2gzaf, MGA_WARP_T2GZAF );
- WARP_UCODE_INSTALL( warp_g400_t2gzs, MGA_WARP_T2GZS );
- WARP_UCODE_INSTALL( warp_g400_t2gzsf, MGA_WARP_T2GZSF );
- WARP_UCODE_INSTALL( warp_g400_t2gzsa, MGA_WARP_T2GZSA );
- WARP_UCODE_INSTALL( warp_g400_t2gzsaf, MGA_WARP_T2GZSAF );
+ memset(dev_priv->warp_pipe_phys, 0, sizeof(dev_priv->warp_pipe_phys));
+
+ WARP_UCODE_INSTALL(warp_g400_tgz, MGA_WARP_TGZ);
+ WARP_UCODE_INSTALL(warp_g400_tgzf, MGA_WARP_TGZF);
+ WARP_UCODE_INSTALL(warp_g400_tgza, MGA_WARP_TGZA);
+ WARP_UCODE_INSTALL(warp_g400_tgzaf, MGA_WARP_TGZAF);
+ WARP_UCODE_INSTALL(warp_g400_tgzs, MGA_WARP_TGZS);
+ WARP_UCODE_INSTALL(warp_g400_tgzsf, MGA_WARP_TGZSF);
+ WARP_UCODE_INSTALL(warp_g400_tgzsa, MGA_WARP_TGZSA);
+ WARP_UCODE_INSTALL(warp_g400_tgzsaf, MGA_WARP_TGZSAF);
+
+ WARP_UCODE_INSTALL(warp_g400_t2gz, MGA_WARP_T2GZ);
+ WARP_UCODE_INSTALL(warp_g400_t2gzf, MGA_WARP_T2GZF);
+ WARP_UCODE_INSTALL(warp_g400_t2gza, MGA_WARP_T2GZA);
+ WARP_UCODE_INSTALL(warp_g400_t2gzaf, MGA_WARP_T2GZAF);
+ WARP_UCODE_INSTALL(warp_g400_t2gzs, MGA_WARP_T2GZS);
+ WARP_UCODE_INSTALL(warp_g400_t2gzsf, MGA_WARP_T2GZSF);
+ WARP_UCODE_INSTALL(warp_g400_t2gzsa, MGA_WARP_T2GZSA);
+ WARP_UCODE_INSTALL(warp_g400_t2gzsaf, MGA_WARP_T2GZSAF);
return 0;
}
-static int mga_warp_install_g200_microcode( drm_mga_private_t *dev_priv )
+static int mga_warp_install_g200_microcode(drm_mga_private_t * dev_priv)
{
unsigned char *vcbase = dev_priv->warp->handle;
unsigned long pcbase = dev_priv->warp->offset;
@@ -138,7 +133,7 @@ static int mga_warp_install_g200_microcode( drm_mga_private_t *dev_priv )
return 0;
}
-int mga_warp_install_microcode( drm_mga_private_t *dev_priv )
+int mga_warp_install_microcode(drm_mga_private_t * dev_priv)
{
const unsigned int size = mga_warp_microcode_size(dev_priv);
@@ -154,7 +149,7 @@ int mga_warp_install_microcode( drm_mga_private_t *dev_priv )
case MGA_CARD_TYPE_G550:
return mga_warp_install_g400_microcode(dev_priv);
case MGA_CARD_TYPE_G200:
- return mga_warp_install_g200_microcode( dev_priv );
+ return mga_warp_install_g200_microcode(dev_priv);
default:
return DRM_ERR(EINVAL);
}
@@ -162,13 +157,13 @@ int mga_warp_install_microcode( drm_mga_private_t *dev_priv )
#define WMISC_EXPECTED (MGA_WUCODECACHE_ENABLE | MGA_WMASTER_ENABLE)
-int mga_warp_init( drm_mga_private_t *dev_priv )
+int mga_warp_init(drm_mga_private_t * dev_priv)
{
u32 wmisc;
/* FIXME: Get rid of these damned magic numbers...
*/
- switch ( dev_priv->chipset ) {
+ switch (dev_priv->chipset) {
case MGA_CARD_TYPE_G400:
case MGA_CARD_TYPE_G550:
MGA_WRITE(MGA_WIADDR2, MGA_WMODE_SUSPEND);
@@ -177,21 +172,20 @@ int mga_warp_init( drm_mga_private_t *dev_priv )
MGA_WRITE(MGA_WACCEPTSEQ, 0x18000000);
break;
case MGA_CARD_TYPE_G200:
- MGA_WRITE( MGA_WIADDR, MGA_WMODE_SUSPEND );
- MGA_WRITE( MGA_WGETMSB, 0x1606 );
- MGA_WRITE( MGA_WVRTXSZ, 7 );
+ MGA_WRITE(MGA_WIADDR, MGA_WMODE_SUSPEND);
+ MGA_WRITE(MGA_WGETMSB, 0x1606);
+ MGA_WRITE(MGA_WVRTXSZ, 7);
break;
default:
return DRM_ERR(EINVAL);
}
- MGA_WRITE( MGA_WMISC, (MGA_WUCODECACHE_ENABLE |
- MGA_WMASTER_ENABLE |
- MGA_WCACHEFLUSH_ENABLE) );
- wmisc = MGA_READ( MGA_WMISC );
- if ( wmisc != WMISC_EXPECTED ) {
- DRM_ERROR( "WARP engine config failed! 0x%x != 0x%x\n",
- wmisc, WMISC_EXPECTED );
+ MGA_WRITE(MGA_WMISC, (MGA_WUCODECACHE_ENABLE |
+ MGA_WMASTER_ENABLE | MGA_WCACHEFLUSH_ENABLE));
+ wmisc = MGA_READ(MGA_WMISC);
+ if (wmisc != WMISC_EXPECTED) {
+ DRM_ERROR("WARP engine config failed! 0x%x != 0x%x\n",
+ wmisc, WMISC_EXPECTED);
return DRM_ERR(EINVAL);
}
diff --git a/drivers/char/drm/r128_cce.c b/drivers/char/drm/r128_cce.c
index 895152206b31..7452753d4d01 100644
--- a/drivers/char/drm/r128_cce.c
+++ b/drivers/char/drm/r128_cce.c
@@ -80,7 +80,7 @@ static u32 r128_cce_microcode[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
-static int R128_READ_PLL(drm_device_t *dev, int addr)
+static int R128_READ_PLL(drm_device_t * dev, int addr)
{
drm_r128_private_t *dev_priv = dev->dev_private;
@@ -89,106 +89,105 @@ static int R128_READ_PLL(drm_device_t *dev, int addr)
}
#if R128_FIFO_DEBUG
-static void r128_status( drm_r128_private_t *dev_priv )
+static void r128_status(drm_r128_private_t * dev_priv)
{
- printk( "GUI_STAT = 0x%08x\n",
- (unsigned int)R128_READ( R128_GUI_STAT ) );
- printk( "PM4_STAT = 0x%08x\n",
- (unsigned int)R128_READ( R128_PM4_STAT ) );
- printk( "PM4_BUFFER_DL_WPTR = 0x%08x\n",
- (unsigned int)R128_READ( R128_PM4_BUFFER_DL_WPTR ) );
- printk( "PM4_BUFFER_DL_RPTR = 0x%08x\n",
- (unsigned int)R128_READ( R128_PM4_BUFFER_DL_RPTR ) );
- printk( "PM4_MICRO_CNTL = 0x%08x\n",
- (unsigned int)R128_READ( R128_PM4_MICRO_CNTL ) );
- printk( "PM4_BUFFER_CNTL = 0x%08x\n",
- (unsigned int)R128_READ( R128_PM4_BUFFER_CNTL ) );
+ printk("GUI_STAT = 0x%08x\n",
+ (unsigned int)R128_READ(R128_GUI_STAT));
+ printk("PM4_STAT = 0x%08x\n",
+ (unsigned int)R128_READ(R128_PM4_STAT));
+ printk("PM4_BUFFER_DL_WPTR = 0x%08x\n",
+ (unsigned int)R128_READ(R128_PM4_BUFFER_DL_WPTR));
+ printk("PM4_BUFFER_DL_RPTR = 0x%08x\n",
+ (unsigned int)R128_READ(R128_PM4_BUFFER_DL_RPTR));
+ printk("PM4_MICRO_CNTL = 0x%08x\n",
+ (unsigned int)R128_READ(R128_PM4_MICRO_CNTL));
+ printk("PM4_BUFFER_CNTL = 0x%08x\n",
+ (unsigned int)R128_READ(R128_PM4_BUFFER_CNTL));
}
#endif
-
/* ================================================================
* Engine, FIFO control
*/
-static int r128_do_pixcache_flush( drm_r128_private_t *dev_priv )
+static int r128_do_pixcache_flush(drm_r128_private_t * dev_priv)
{
u32 tmp;
int i;
- tmp = R128_READ( R128_PC_NGUI_CTLSTAT ) | R128_PC_FLUSH_ALL;
- R128_WRITE( R128_PC_NGUI_CTLSTAT, tmp );
+ tmp = R128_READ(R128_PC_NGUI_CTLSTAT) | R128_PC_FLUSH_ALL;
+ R128_WRITE(R128_PC_NGUI_CTLSTAT, tmp);
- for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) {
- if ( !(R128_READ( R128_PC_NGUI_CTLSTAT ) & R128_PC_BUSY) ) {
+ for (i = 0; i < dev_priv->usec_timeout; i++) {
+ if (!(R128_READ(R128_PC_NGUI_CTLSTAT) & R128_PC_BUSY)) {
return 0;
}
- DRM_UDELAY( 1 );
+ DRM_UDELAY(1);
}
#if R128_FIFO_DEBUG
- DRM_ERROR( "failed!\n" );
+ DRM_ERROR("failed!\n");
#endif
return DRM_ERR(EBUSY);
}
-static int r128_do_wait_for_fifo( drm_r128_private_t *dev_priv, int entries )
+static int r128_do_wait_for_fifo(drm_r128_private_t * dev_priv, int entries)
{
int i;
- for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) {
- int slots = R128_READ( R128_GUI_STAT ) & R128_GUI_FIFOCNT_MASK;
- if ( slots >= entries ) return 0;
- DRM_UDELAY( 1 );
+ for (i = 0; i < dev_priv->usec_timeout; i++) {
+ int slots = R128_READ(R128_GUI_STAT) & R128_GUI_FIFOCNT_MASK;
+ if (slots >= entries)
+ return 0;
+ DRM_UDELAY(1);
}
#if R128_FIFO_DEBUG
- DRM_ERROR( "failed!\n" );
+ DRM_ERROR("failed!\n");
#endif
return DRM_ERR(EBUSY);
}
-static int r128_do_wait_for_idle( drm_r128_private_t *dev_priv )
+static int r128_do_wait_for_idle(drm_r128_private_t * dev_priv)
{
int i, ret;
- ret = r128_do_wait_for_fifo( dev_priv, 64 );
- if ( ret ) return ret;
+ ret = r128_do_wait_for_fifo(dev_priv, 64);
+ if (ret)
+ return ret;
- for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) {
- if ( !(R128_READ( R128_GUI_STAT ) & R128_GUI_ACTIVE) ) {
- r128_do_pixcache_flush( dev_priv );
+ for (i = 0; i < dev_priv->usec_timeout; i++) {
+ if (!(R128_READ(R128_GUI_STAT) & R128_GUI_ACTIVE)) {
+ r128_do_pixcache_flush(dev_priv);
return 0;
}
- DRM_UDELAY( 1 );
+ DRM_UDELAY(1);
}
#if R128_FIFO_DEBUG
- DRM_ERROR( "failed!\n" );
+ DRM_ERROR("failed!\n");
#endif
return DRM_ERR(EBUSY);
}
-
/* ================================================================
* CCE control, initialization
*/
/* Load the microcode for the CCE */
-static void r128_cce_load_microcode( drm_r128_private_t *dev_priv )
+static void r128_cce_load_microcode(drm_r128_private_t * dev_priv)
{
int i;
- DRM_DEBUG( "\n" );
+ DRM_DEBUG("\n");
- r128_do_wait_for_idle( dev_priv );
+ r128_do_wait_for_idle(dev_priv);
- R128_WRITE( R128_PM4_MICROCODE_ADDR, 0 );
- for ( i = 0 ; i < 256 ; i++ ) {
- R128_WRITE( R128_PM4_MICROCODE_DATAH,
- r128_cce_microcode[i * 2] );
- R128_WRITE( R128_PM4_MICROCODE_DATAL,
- r128_cce_microcode[i * 2 + 1] );
+ R128_WRITE(R128_PM4_MICROCODE_ADDR, 0);
+ for (i = 0; i < 256; i++) {
+ R128_WRITE(R128_PM4_MICROCODE_DATAH, r128_cce_microcode[i * 2]);
+ R128_WRITE(R128_PM4_MICROCODE_DATAL,
+ r128_cce_microcode[i * 2 + 1]);
}
}
@@ -196,51 +195,51 @@ static void r128_cce_load_microcode( drm_r128_private_t *dev_priv )
* prior to a wait for idle, as it informs the engine that the command
* stream is ending.
*/
-static void r128_do_cce_flush( drm_r128_private_t *dev_priv )
+static void r128_do_cce_flush(drm_r128_private_t * dev_priv)
{
u32 tmp;
- tmp = R128_READ( R128_PM4_BUFFER_DL_WPTR ) | R128_PM4_BUFFER_DL_DONE;
- R128_WRITE( R128_PM4_BUFFER_DL_WPTR, tmp );
+ tmp = R128_READ(R128_PM4_BUFFER_DL_WPTR) | R128_PM4_BUFFER_DL_DONE;
+ R128_WRITE(R128_PM4_BUFFER_DL_WPTR, tmp);
}
/* Wait for the CCE to go idle.
*/
-int r128_do_cce_idle( drm_r128_private_t *dev_priv )
+int r128_do_cce_idle(drm_r128_private_t * dev_priv)
{
int i;
- for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) {
- if ( GET_RING_HEAD( dev_priv ) == dev_priv->ring.tail ) {
- int pm4stat = R128_READ( R128_PM4_STAT );
- if ( ( (pm4stat & R128_PM4_FIFOCNT_MASK) >=
- dev_priv->cce_fifo_size ) &&
- !(pm4stat & (R128_PM4_BUSY |
- R128_PM4_GUI_ACTIVE)) ) {
- return r128_do_pixcache_flush( dev_priv );
+ for (i = 0; i < dev_priv->usec_timeout; i++) {
+ if (GET_RING_HEAD(dev_priv) == dev_priv->ring.tail) {
+ int pm4stat = R128_READ(R128_PM4_STAT);
+ if (((pm4stat & R128_PM4_FIFOCNT_MASK) >=
+ dev_priv->cce_fifo_size) &&
+ !(pm4stat & (R128_PM4_BUSY |
+ R128_PM4_GUI_ACTIVE))) {
+ return r128_do_pixcache_flush(dev_priv);
}
}
- DRM_UDELAY( 1 );
+ DRM_UDELAY(1);
}
#if R128_FIFO_DEBUG
- DRM_ERROR( "failed!\n" );
- r128_status( dev_priv );
+ DRM_ERROR("failed!\n");
+ r128_status(dev_priv);
#endif
return DRM_ERR(EBUSY);
}
/* Start the Concurrent Command Engine.
*/
-static void r128_do_cce_start( drm_r128_private_t *dev_priv )
+static void r128_do_cce_start(drm_r128_private_t * dev_priv)
{
- r128_do_wait_for_idle( dev_priv );
+ r128_do_wait_for_idle(dev_priv);
- R128_WRITE( R128_PM4_BUFFER_CNTL,
- dev_priv->cce_mode | dev_priv->ring.size_l2qw
- | R128_PM4_BUFFER_CNTL_NOUPDATE );
- R128_READ( R128_PM4_BUFFER_ADDR ); /* as per the sample code */
- R128_WRITE( R128_PM4_MICRO_CNTL, R128_PM4_MICRO_FREERUN );
+ R128_WRITE(R128_PM4_BUFFER_CNTL,
+ dev_priv->cce_mode | dev_priv->ring.size_l2qw
+ | R128_PM4_BUFFER_CNTL_NOUPDATE);
+ R128_READ(R128_PM4_BUFFER_ADDR); /* as per the sample code */
+ R128_WRITE(R128_PM4_MICRO_CNTL, R128_PM4_MICRO_FREERUN);
dev_priv->cce_running = 1;
}
@@ -249,10 +248,10 @@ static void r128_do_cce_start( drm_r128_private_t *dev_priv )
* commands, so you must wait for the CCE command stream to complete
* before calling this routine.
*/
-static void r128_do_cce_reset( drm_r128_private_t *dev_priv )
+static void r128_do_cce_reset(drm_r128_private_t * dev_priv)
{
- R128_WRITE( R128_PM4_BUFFER_DL_WPTR, 0 );
- R128_WRITE( R128_PM4_BUFFER_DL_RPTR, 0 );
+ R128_WRITE(R128_PM4_BUFFER_DL_WPTR, 0);
+ R128_WRITE(R128_PM4_BUFFER_DL_RPTR, 0);
dev_priv->ring.tail = 0;
}
@@ -260,122 +259,120 @@ static void r128_do_cce_reset( drm_r128_private_t *dev_priv )
* commands, so you must flush the command stream and wait for the CCE
* to go idle before calling this routine.
*/
-static void r128_do_cce_stop( drm_r128_private_t *dev_priv )
+static void r128_do_cce_stop(drm_r128_private_t * dev_priv)
{
- R128_WRITE( R128_PM4_MICRO_CNTL, 0 );
- R128_WRITE( R128_PM4_BUFFER_CNTL,
- R128_PM4_NONPM4 | R128_PM4_BUFFER_CNTL_NOUPDATE );
+ R128_WRITE(R128_PM4_MICRO_CNTL, 0);
+ R128_WRITE(R128_PM4_BUFFER_CNTL,
+ R128_PM4_NONPM4 | R128_PM4_BUFFER_CNTL_NOUPDATE);
dev_priv->cce_running = 0;
}
/* Reset the engine. This will stop the CCE if it is running.
*/
-static int r128_do_engine_reset( drm_device_t *dev )
+static int r128_do_engine_reset(drm_device_t * dev)
{
drm_r128_private_t *dev_priv = dev->dev_private;
u32 clock_cntl_index, mclk_cntl, gen_reset_cntl;
- r128_do_pixcache_flush( dev_priv );
+ r128_do_pixcache_flush(dev_priv);
- clock_cntl_index = R128_READ( R128_CLOCK_CNTL_INDEX );
- mclk_cntl = R128_READ_PLL( dev, R128_MCLK_CNTL );
+ clock_cntl_index = R128_READ(R128_CLOCK_CNTL_INDEX);
+ mclk_cntl = R128_READ_PLL(dev, R128_MCLK_CNTL);
- R128_WRITE_PLL( R128_MCLK_CNTL,
- mclk_cntl | R128_FORCE_GCP | R128_FORCE_PIPE3D_CP );
+ R128_WRITE_PLL(R128_MCLK_CNTL,
+ mclk_cntl | R128_FORCE_GCP | R128_FORCE_PIPE3D_CP);
- gen_reset_cntl = R128_READ( R128_GEN_RESET_CNTL );
+ gen_reset_cntl = R128_READ(R128_GEN_RESET_CNTL);
/* Taken from the sample code - do not change */
- R128_WRITE( R128_GEN_RESET_CNTL,
- gen_reset_cntl | R128_SOFT_RESET_GUI );
- R128_READ( R128_GEN_RESET_CNTL );
- R128_WRITE( R128_GEN_RESET_CNTL,
- gen_reset_cntl & ~R128_SOFT_RESET_GUI );
- R128_READ( R128_GEN_RESET_CNTL );
+ R128_WRITE(R128_GEN_RESET_CNTL, gen_reset_cntl | R128_SOFT_RESET_GUI);
+ R128_READ(R128_GEN_RESET_CNTL);
+ R128_WRITE(R128_GEN_RESET_CNTL, gen_reset_cntl & ~R128_SOFT_RESET_GUI);
+ R128_READ(R128_GEN_RESET_CNTL);
- R128_WRITE_PLL( R128_MCLK_CNTL, mclk_cntl );
- R128_WRITE( R128_CLOCK_CNTL_INDEX, clock_cntl_index );
- R128_WRITE( R128_GEN_RESET_CNTL, gen_reset_cntl );
+ R128_WRITE_PLL(R128_MCLK_CNTL, mclk_cntl);
+ R128_WRITE(R128_CLOCK_CNTL_INDEX, clock_cntl_index);
+ R128_WRITE(R128_GEN_RESET_CNTL, gen_reset_cntl);
/* Reset the CCE ring */
- r128_do_cce_reset( dev_priv );
+ r128_do_cce_reset(dev_priv);
/* The CCE is no longer running after an engine reset */
dev_priv->cce_running = 0;
/* Reset any pending vertex, indirect buffers */
- r128_freelist_reset( dev );
+ r128_freelist_reset(dev);
return 0;
}
-static void r128_cce_init_ring_buffer( drm_device_t *dev,
- drm_r128_private_t *dev_priv )
+static void r128_cce_init_ring_buffer(drm_device_t * dev,
+ drm_r128_private_t * dev_priv)
{
u32 ring_start;
u32 tmp;
- DRM_DEBUG( "\n" );
+ DRM_DEBUG("\n");
/* The manual (p. 2) says this address is in "VM space". This
* means it's an offset from the start of AGP space.
*/
#if __OS_HAS_AGP
- if ( !dev_priv->is_pci )
+ if (!dev_priv->is_pci)
ring_start = dev_priv->cce_ring->offset - dev->agp->base;
else
#endif
- ring_start = dev_priv->cce_ring->offset -
- (unsigned long)dev->sg->virtual;
+ ring_start = dev_priv->cce_ring->offset -
+ (unsigned long)dev->sg->virtual;
- R128_WRITE( R128_PM4_BUFFER_OFFSET, ring_start | R128_AGP_OFFSET );
+ R128_WRITE(R128_PM4_BUFFER_OFFSET, ring_start | R128_AGP_OFFSET);
- R128_WRITE( R128_PM4_BUFFER_DL_WPTR, 0 );
- R128_WRITE( R128_PM4_BUFFER_DL_RPTR, 0 );
+ R128_WRITE(R128_PM4_BUFFER_DL_WPTR, 0);
+ R128_WRITE(R128_PM4_BUFFER_DL_RPTR, 0);
/* Set watermark control */
- R128_WRITE( R128_PM4_BUFFER_WM_CNTL,
- ((R128_WATERMARK_L/4) << R128_WMA_SHIFT)
- | ((R128_WATERMARK_M/4) << R128_WMB_SHIFT)
- | ((R128_WATERMARK_N/4) << R128_WMC_SHIFT)
- | ((R128_WATERMARK_K/64) << R128_WB_WM_SHIFT) );
+ R128_WRITE(R128_PM4_BUFFER_WM_CNTL,
+ ((R128_WATERMARK_L / 4) << R128_WMA_SHIFT)
+ | ((R128_WATERMARK_M / 4) << R128_WMB_SHIFT)
+ | ((R128_WATERMARK_N / 4) << R128_WMC_SHIFT)
+ | ((R128_WATERMARK_K / 64) << R128_WB_WM_SHIFT));
/* Force read. Why? Because it's in the examples... */
- R128_READ( R128_PM4_BUFFER_ADDR );
+ R128_READ(R128_PM4_BUFFER_ADDR);
/* Turn on bus mastering */
- tmp = R128_READ( R128_BUS_CNTL ) & ~R128_BUS_MASTER_DIS;
- R128_WRITE( R128_BUS_CNTL, tmp );
+ tmp = R128_READ(R128_BUS_CNTL) & ~R128_BUS_MASTER_DIS;
+ R128_WRITE(R128_BUS_CNTL, tmp);
}
-static int r128_do_init_cce( drm_device_t *dev, drm_r128_init_t *init )
+static int r128_do_init_cce(drm_device_t * dev, drm_r128_init_t * init)
{
drm_r128_private_t *dev_priv;
- DRM_DEBUG( "\n" );
+ DRM_DEBUG("\n");
- dev_priv = drm_alloc( sizeof(drm_r128_private_t), DRM_MEM_DRIVER );
- if ( dev_priv == NULL )
+ dev_priv = drm_alloc(sizeof(drm_r128_private_t), DRM_MEM_DRIVER);
+ if (dev_priv == NULL)
return DRM_ERR(ENOMEM);
- memset( dev_priv, 0, sizeof(drm_r128_private_t) );
+ memset(dev_priv, 0, sizeof(drm_r128_private_t));
dev_priv->is_pci = init->is_pci;
- if ( dev_priv->is_pci && !dev->sg ) {
- DRM_ERROR( "PCI GART memory not allocated!\n" );
+ if (dev_priv->is_pci && !dev->sg) {
+ DRM_ERROR("PCI GART memory not allocated!\n");
dev->dev_private = (void *)dev_priv;
- r128_do_cleanup_cce( dev );
+ r128_do_cleanup_cce(dev);
return DRM_ERR(EINVAL);
}
dev_priv->usec_timeout = init->usec_timeout;
- if ( dev_priv->usec_timeout < 1 ||
- dev_priv->usec_timeout > R128_MAX_USEC_TIMEOUT ) {
- DRM_DEBUG( "TIMEOUT problem!\n" );
+ if (dev_priv->usec_timeout < 1 ||
+ dev_priv->usec_timeout > R128_MAX_USEC_TIMEOUT) {
+ DRM_DEBUG("TIMEOUT problem!\n");
dev->dev_private = (void *)dev_priv;
- r128_do_cleanup_cce( dev );
+ r128_do_cleanup_cce(dev);
return DRM_ERR(EINVAL);
}
@@ -383,23 +380,23 @@ static int r128_do_init_cce( drm_device_t *dev, drm_r128_init_t *init )
/* GH: Simple idle check.
*/
- atomic_set( &dev_priv->idle_count, 0 );
+ atomic_set(&dev_priv->idle_count, 0);
/* We don't support anything other than bus-mastering ring mode,
* but the ring can be in either AGP or PCI space for the ring
* read pointer.
*/
- if ( ( init->cce_mode != R128_PM4_192BM ) &&
- ( init->cce_mode != R128_PM4_128BM_64INDBM ) &&
- ( init->cce_mode != R128_PM4_64BM_128INDBM ) &&
- ( init->cce_mode != R128_PM4_64BM_64VCBM_64INDBM ) ) {
- DRM_DEBUG( "Bad cce_mode!\n" );
+ if ((init->cce_mode != R128_PM4_192BM) &&
+ (init->cce_mode != R128_PM4_128BM_64INDBM) &&
+ (init->cce_mode != R128_PM4_64BM_128INDBM) &&
+ (init->cce_mode != R128_PM4_64BM_64VCBM_64INDBM)) {
+ DRM_DEBUG("Bad cce_mode!\n");
dev->dev_private = (void *)dev_priv;
- r128_do_cleanup_cce( dev );
+ r128_do_cleanup_cce(dev);
return DRM_ERR(EINVAL);
}
- switch ( init->cce_mode ) {
+ switch (init->cce_mode) {
case R128_PM4_NONPM4:
dev_priv->cce_fifo_size = 0;
break;
@@ -420,7 +417,7 @@ static int r128_do_init_cce( drm_device_t *dev, drm_r128_init_t *init )
break;
}
- switch ( init->fb_bpp ) {
+ switch (init->fb_bpp) {
case 16:
dev_priv->color_fmt = R128_DATATYPE_RGB565;
break;
@@ -429,12 +426,12 @@ static int r128_do_init_cce( drm_device_t *dev, drm_r128_init_t *init )
dev_priv->color_fmt = R128_DATATYPE_ARGB8888;
break;
}
- dev_priv->front_offset = init->front_offset;
- dev_priv->front_pitch = init->front_pitch;
- dev_priv->back_offset = init->back_offset;
- dev_priv->back_pitch = init->back_pitch;
+ dev_priv->front_offset = init->front_offset;
+ dev_priv->front_pitch = init->front_pitch;
+ dev_priv->back_offset = init->back_offset;
+ dev_priv->back_pitch = init->back_pitch;
- switch ( init->depth_bpp ) {
+ switch (init->depth_bpp) {
case 16:
dev_priv->depth_fmt = R128_DATATYPE_RGB565;
break;
@@ -444,218 +441,223 @@ static int r128_do_init_cce( drm_device_t *dev, drm_r128_init_t *init )
dev_priv->depth_fmt = R128_DATATYPE_ARGB8888;
break;
}
- dev_priv->depth_offset = init->depth_offset;
- dev_priv->depth_pitch = init->depth_pitch;
- dev_priv->span_offset = init->span_offset;
+ dev_priv->depth_offset = init->depth_offset;
+ dev_priv->depth_pitch = init->depth_pitch;
+ dev_priv->span_offset = init->span_offset;
- dev_priv->front_pitch_offset_c = (((dev_priv->front_pitch/8) << 21) |
+ dev_priv->front_pitch_offset_c = (((dev_priv->front_pitch / 8) << 21) |
(dev_priv->front_offset >> 5));
- dev_priv->back_pitch_offset_c = (((dev_priv->back_pitch/8) << 21) |
+ dev_priv->back_pitch_offset_c = (((dev_priv->back_pitch / 8) << 21) |
(dev_priv->back_offset >> 5));
- dev_priv->depth_pitch_offset_c = (((dev_priv->depth_pitch/8) << 21) |
+ dev_priv->depth_pitch_offset_c = (((dev_priv->depth_pitch / 8) << 21) |
(dev_priv->depth_offset >> 5) |
R128_DST_TILE);
- dev_priv->span_pitch_offset_c = (((dev_priv->depth_pitch/8) << 21) |
+ dev_priv->span_pitch_offset_c = (((dev_priv->depth_pitch / 8) << 21) |
(dev_priv->span_offset >> 5));
DRM_GETSAREA();
-
- if(!dev_priv->sarea) {
+
+ if (!dev_priv->sarea) {
DRM_ERROR("could not find sarea!\n");
dev->dev_private = (void *)dev_priv;
- r128_do_cleanup_cce( dev );
+ r128_do_cleanup_cce(dev);
return DRM_ERR(EINVAL);
}
dev_priv->mmio = drm_core_findmap(dev, init->mmio_offset);
- if(!dev_priv->mmio) {
+ if (!dev_priv->mmio) {
DRM_ERROR("could not find mmio region!\n");
dev->dev_private = (void *)dev_priv;
- r128_do_cleanup_cce( dev );
+ r128_do_cleanup_cce(dev);
return DRM_ERR(EINVAL);
}
dev_priv->cce_ring = drm_core_findmap(dev, init->ring_offset);
- if(!dev_priv->cce_ring) {
+ if (!dev_priv->cce_ring) {
DRM_ERROR("could not find cce ring region!\n");
dev->dev_private = (void *)dev_priv;
- r128_do_cleanup_cce( dev );
+ r128_do_cleanup_cce(dev);
return DRM_ERR(EINVAL);
}
dev_priv->ring_rptr = drm_core_findmap(dev, init->ring_rptr_offset);
- if(!dev_priv->ring_rptr) {
+ if (!dev_priv->ring_rptr) {
DRM_ERROR("could not find ring read pointer!\n");
dev->dev_private = (void *)dev_priv;
- r128_do_cleanup_cce( dev );
+ r128_do_cleanup_cce(dev);
return DRM_ERR(EINVAL);
}
dev->agp_buffer_token = init->buffers_offset;
dev->agp_buffer_map = drm_core_findmap(dev, init->buffers_offset);
- if(!dev->agp_buffer_map) {
+ if (!dev->agp_buffer_map) {
DRM_ERROR("could not find dma buffer region!\n");
dev->dev_private = (void *)dev_priv;
- r128_do_cleanup_cce( dev );
+ r128_do_cleanup_cce(dev);
return DRM_ERR(EINVAL);
}
- if ( !dev_priv->is_pci ) {
- dev_priv->agp_textures = drm_core_findmap(dev, init->agp_textures_offset);
- if(!dev_priv->agp_textures) {
+ if (!dev_priv->is_pci) {
+ dev_priv->agp_textures =
+ drm_core_findmap(dev, init->agp_textures_offset);
+ if (!dev_priv->agp_textures) {
DRM_ERROR("could not find agp texture region!\n");
dev->dev_private = (void *)dev_priv;
- r128_do_cleanup_cce( dev );
+ r128_do_cleanup_cce(dev);
return DRM_ERR(EINVAL);
}
}
dev_priv->sarea_priv =
- (drm_r128_sarea_t *)((u8 *)dev_priv->sarea->handle +
- init->sarea_priv_offset);
+ (drm_r128_sarea_t *) ((u8 *) dev_priv->sarea->handle +
+ init->sarea_priv_offset);
#if __OS_HAS_AGP
- if ( !dev_priv->is_pci ) {
- drm_core_ioremap( dev_priv->cce_ring, dev );
- drm_core_ioremap( dev_priv->ring_rptr, dev );
- drm_core_ioremap( dev->agp_buffer_map, dev );
- if(!dev_priv->cce_ring->handle ||
- !dev_priv->ring_rptr->handle ||
- !dev->agp_buffer_map->handle) {
+ if (!dev_priv->is_pci) {
+ drm_core_ioremap(dev_priv->cce_ring, dev);
+ drm_core_ioremap(dev_priv->ring_rptr, dev);
+ drm_core_ioremap(dev->agp_buffer_map, dev);
+ if (!dev_priv->cce_ring->handle ||
+ !dev_priv->ring_rptr->handle ||
+ !dev->agp_buffer_map->handle) {
DRM_ERROR("Could not ioremap agp regions!\n");
dev->dev_private = (void *)dev_priv;
- r128_do_cleanup_cce( dev );
+ r128_do_cleanup_cce(dev);
return DRM_ERR(ENOMEM);
}
} else
#endif
{
- dev_priv->cce_ring->handle =
- (void *)dev_priv->cce_ring->offset;
+ dev_priv->cce_ring->handle = (void *)dev_priv->cce_ring->offset;
dev_priv->ring_rptr->handle =
- (void *)dev_priv->ring_rptr->offset;
- dev->agp_buffer_map->handle = (void *)dev->agp_buffer_map->offset;
+ (void *)dev_priv->ring_rptr->offset;
+ dev->agp_buffer_map->handle =
+ (void *)dev->agp_buffer_map->offset;
}
#if __OS_HAS_AGP
- if ( !dev_priv->is_pci )
+ if (!dev_priv->is_pci)
dev_priv->cce_buffers_offset = dev->agp->base;
else
#endif
dev_priv->cce_buffers_offset = (unsigned long)dev->sg->virtual;
- dev_priv->ring.start = (u32 *)dev_priv->cce_ring->handle;
- dev_priv->ring.end = ((u32 *)dev_priv->cce_ring->handle
+ dev_priv->ring.start = (u32 *) dev_priv->cce_ring->handle;
+ dev_priv->ring.end = ((u32 *) dev_priv->cce_ring->handle
+ init->ring_size / sizeof(u32));
dev_priv->ring.size = init->ring_size;
- dev_priv->ring.size_l2qw = drm_order( init->ring_size / 8 );
+ dev_priv->ring.size_l2qw = drm_order(init->ring_size / 8);
- dev_priv->ring.tail_mask =
- (dev_priv->ring.size / sizeof(u32)) - 1;
+ dev_priv->ring.tail_mask = (dev_priv->ring.size / sizeof(u32)) - 1;
dev_priv->ring.high_mark = 128;
dev_priv->sarea_priv->last_frame = 0;
- R128_WRITE( R128_LAST_FRAME_REG, dev_priv->sarea_priv->last_frame );
+ R128_WRITE(R128_LAST_FRAME_REG, dev_priv->sarea_priv->last_frame);
dev_priv->sarea_priv->last_dispatch = 0;
- R128_WRITE( R128_LAST_DISPATCH_REG,
- dev_priv->sarea_priv->last_dispatch );
+ R128_WRITE(R128_LAST_DISPATCH_REG, dev_priv->sarea_priv->last_dispatch);
#if __OS_HAS_AGP
- if ( dev_priv->is_pci ) {
+ if (dev_priv->is_pci) {
#endif
- if (!drm_ati_pcigart_init( dev, &dev_priv->phys_pci_gart,
- &dev_priv->bus_pci_gart) ) {
- DRM_ERROR( "failed to init PCI GART!\n" );
+ dev_priv->gart_info.gart_table_location = DRM_ATI_GART_MAIN;
+ dev_priv->gart_info.addr = dev_priv->gart_info.bus_addr = 0;
+ dev_priv->gart_info.is_pcie = 0;
+ if (!drm_ati_pcigart_init(dev, &dev_priv->gart_info)) {
+ DRM_ERROR("failed to init PCI GART!\n");
dev->dev_private = (void *)dev_priv;
- r128_do_cleanup_cce( dev );
+ r128_do_cleanup_cce(dev);
return DRM_ERR(ENOMEM);
}
- R128_WRITE( R128_PCI_GART_PAGE, dev_priv->bus_pci_gart );
+ R128_WRITE(R128_PCI_GART_PAGE, dev_priv->gart_info.bus_addr);
#if __OS_HAS_AGP
}
#endif
- r128_cce_init_ring_buffer( dev, dev_priv );
- r128_cce_load_microcode( dev_priv );
+ r128_cce_init_ring_buffer(dev, dev_priv);
+ r128_cce_load_microcode(dev_priv);
dev->dev_private = (void *)dev_priv;
- r128_do_engine_reset( dev );
+ r128_do_engine_reset(dev);
return 0;
}
-int r128_do_cleanup_cce( drm_device_t *dev )
+int r128_do_cleanup_cce(drm_device_t * dev)
{
/* Make sure interrupts are disabled here because the uninstall ioctl
* may not have been called from userspace and after dev_private
* is freed, it's too late.
*/
- if ( dev->irq_enabled ) drm_irq_uninstall(dev);
+ if (dev->irq_enabled)
+ drm_irq_uninstall(dev);
- if ( dev->dev_private ) {
+ if (dev->dev_private) {
drm_r128_private_t *dev_priv = dev->dev_private;
#if __OS_HAS_AGP
- if ( !dev_priv->is_pci ) {
- if ( dev_priv->cce_ring != NULL )
- drm_core_ioremapfree( dev_priv->cce_ring, dev );
- if ( dev_priv->ring_rptr != NULL )
- drm_core_ioremapfree( dev_priv->ring_rptr, dev );
- if ( dev->agp_buffer_map != NULL )
- drm_core_ioremapfree( dev->agp_buffer_map, dev );
+ if (!dev_priv->is_pci) {
+ if (dev_priv->cce_ring != NULL)
+ drm_core_ioremapfree(dev_priv->cce_ring, dev);
+ if (dev_priv->ring_rptr != NULL)
+ drm_core_ioremapfree(dev_priv->ring_rptr, dev);
+ if (dev->agp_buffer_map != NULL)
+ drm_core_ioremapfree(dev->agp_buffer_map, dev);
} else
#endif
{
- if (!drm_ati_pcigart_cleanup( dev,
- dev_priv->phys_pci_gart,
- dev_priv->bus_pci_gart ))
- DRM_ERROR( "failed to cleanup PCI GART!\n" );
+ if (dev_priv->gart_info.bus_addr)
+ if (!drm_ati_pcigart_cleanup(dev,
+ &dev_priv->
+ gart_info))
+ DRM_ERROR
+ ("failed to cleanup PCI GART!\n");
}
- drm_free( dev->dev_private, sizeof(drm_r128_private_t),
- DRM_MEM_DRIVER );
+ drm_free(dev->dev_private, sizeof(drm_r128_private_t),
+ DRM_MEM_DRIVER);
dev->dev_private = NULL;
}
return 0;
}
-int r128_cce_init( DRM_IOCTL_ARGS )
+int r128_cce_init(DRM_IOCTL_ARGS)
{
DRM_DEVICE;
drm_r128_init_t init;
- DRM_DEBUG( "\n" );
+ DRM_DEBUG("\n");
- LOCK_TEST_WITH_RETURN( dev, filp );
+ LOCK_TEST_WITH_RETURN(dev, filp);
- DRM_COPY_FROM_USER_IOCTL( init, (drm_r128_init_t __user *)data, sizeof(init) );
+ DRM_COPY_FROM_USER_IOCTL(init, (drm_r128_init_t __user *) data,
+ sizeof(init));
- switch ( init.func ) {
+ switch (init.func) {
case R128_INIT_CCE:
- return r128_do_init_cce( dev, &init );
+ return r128_do_init_cce(dev, &init);
case R128_CLEANUP_CCE:
- return r128_do_cleanup_cce( dev );
+ return r128_do_cleanup_cce(dev);
}
return DRM_ERR(EINVAL);
}
-int r128_cce_start( DRM_IOCTL_ARGS )
+int r128_cce_start(DRM_IOCTL_ARGS)
{
DRM_DEVICE;
drm_r128_private_t *dev_priv = dev->dev_private;
- DRM_DEBUG( "\n" );
+ DRM_DEBUG("\n");
- LOCK_TEST_WITH_RETURN( dev, filp );
+ LOCK_TEST_WITH_RETURN(dev, filp);
- if ( dev_priv->cce_running || dev_priv->cce_mode == R128_PM4_NONPM4 ) {
- DRM_DEBUG( "%s while CCE running\n", __FUNCTION__ );
+ if (dev_priv->cce_running || dev_priv->cce_mode == R128_PM4_NONPM4) {
+ DRM_DEBUG("%s while CCE running\n", __FUNCTION__);
return 0;
}
- r128_do_cce_start( dev_priv );
+ r128_do_cce_start(dev_priv);
return 0;
}
@@ -663,61 +665,63 @@ int r128_cce_start( DRM_IOCTL_ARGS )
/* Stop the CCE. The engine must have been idled before calling this
* routine.
*/
-int r128_cce_stop( DRM_IOCTL_ARGS )
+int r128_cce_stop(DRM_IOCTL_ARGS)
{
DRM_DEVICE;
drm_r128_private_t *dev_priv = dev->dev_private;
drm_r128_cce_stop_t stop;
int ret;
- DRM_DEBUG( "\n" );
+ DRM_DEBUG("\n");
- LOCK_TEST_WITH_RETURN( dev, filp );
+ LOCK_TEST_WITH_RETURN(dev, filp);
- DRM_COPY_FROM_USER_IOCTL(stop, (drm_r128_cce_stop_t __user *)data, sizeof(stop) );
+ DRM_COPY_FROM_USER_IOCTL(stop, (drm_r128_cce_stop_t __user *) data,
+ sizeof(stop));
/* Flush any pending CCE commands. This ensures any outstanding
* commands are exectuted by the engine before we turn it off.
*/
- if ( stop.flush ) {
- r128_do_cce_flush( dev_priv );
+ if (stop.flush) {
+ r128_do_cce_flush(dev_priv);
}
/* If we fail to make the engine go idle, we return an error
* code so that the DRM ioctl wrapper can try again.
*/
- if ( stop.idle ) {
- ret = r128_do_cce_idle( dev_priv );
- if ( ret ) return ret;
+ if (stop.idle) {
+ ret = r128_do_cce_idle(dev_priv);
+ if (ret)
+ return ret;
}
/* Finally, we can turn off the CCE. If the engine isn't idle,
* we will get some dropped triangles as they won't be fully
* rendered before the CCE is shut down.
*/
- r128_do_cce_stop( dev_priv );
+ r128_do_cce_stop(dev_priv);
/* Reset the engine */
- r128_do_engine_reset( dev );
+ r128_do_engine_reset(dev);
return 0;
}
/* Just reset the CCE ring. Called as part of an X Server engine reset.
*/
-int r128_cce_reset( DRM_IOCTL_ARGS )
+int r128_cce_reset(DRM_IOCTL_ARGS)
{
DRM_DEVICE;
drm_r128_private_t *dev_priv = dev->dev_private;
- DRM_DEBUG( "\n" );
+ DRM_DEBUG("\n");
- LOCK_TEST_WITH_RETURN( dev, filp );
+ LOCK_TEST_WITH_RETURN(dev, filp);
- if ( !dev_priv ) {
- DRM_DEBUG( "%s called before init done\n", __FUNCTION__ );
+ if (!dev_priv) {
+ DRM_DEBUG("%s called before init done\n", __FUNCTION__);
return DRM_ERR(EINVAL);
}
- r128_do_cce_reset( dev_priv );
+ r128_do_cce_reset(dev_priv);
/* The CCE is no longer running after an engine reset */
dev_priv->cce_running = 0;
@@ -725,37 +729,36 @@ int r128_cce_reset( DRM_IOCTL_ARGS )
return 0;
}
-int r128_cce_idle( DRM_IOCTL_ARGS )
+int r128_cce_idle(DRM_IOCTL_ARGS)
{
DRM_DEVICE;
drm_r128_private_t *dev_priv = dev->dev_private;
- DRM_DEBUG( "\n" );
+ DRM_DEBUG("\n");
- LOCK_TEST_WITH_RETURN( dev, filp );
+ LOCK_TEST_WITH_RETURN(dev, filp);
- if ( dev_priv->cce_running ) {
- r128_do_cce_flush( dev_priv );
+ if (dev_priv->cce_running) {
+ r128_do_cce_flush(dev_priv);
}
- return r128_do_cce_idle( dev_priv );
+ return r128_do_cce_idle(dev_priv);
}
-int r128_engine_reset( DRM_IOCTL_ARGS )
+int r128_engine_reset(DRM_IOCTL_ARGS)
{
DRM_DEVICE;
- DRM_DEBUG( "\n" );
+ DRM_DEBUG("\n");
- LOCK_TEST_WITH_RETURN( dev, filp );
+ LOCK_TEST_WITH_RETURN(dev, filp);
- return r128_do_engine_reset( dev );
+ return r128_do_engine_reset(dev);
}
-int r128_fullscreen( DRM_IOCTL_ARGS )
+int r128_fullscreen(DRM_IOCTL_ARGS)
{
return DRM_ERR(EINVAL);
}
-
/* ================================================================
* Freelist management
*/
@@ -763,7 +766,7 @@ int r128_fullscreen( DRM_IOCTL_ARGS )
#define R128_BUFFER_FREE 0
#if 0
-static int r128_freelist_init( drm_device_t *dev )
+static int r128_freelist_init(drm_device_t * dev)
{
drm_device_dma_t *dma = dev->dma;
drm_r128_private_t *dev_priv = dev->dev_private;
@@ -772,27 +775,26 @@ static int r128_freelist_init( drm_device_t *dev )
drm_r128_freelist_t *entry;
int i;
- dev_priv->head = drm_alloc( sizeof(drm_r128_freelist_t),
- DRM_MEM_DRIVER );
- if ( dev_priv->head == NULL )
+ dev_priv->head = drm_alloc(sizeof(drm_r128_freelist_t), DRM_MEM_DRIVER);
+ if (dev_priv->head == NULL)
return DRM_ERR(ENOMEM);
- memset( dev_priv->head, 0, sizeof(drm_r128_freelist_t) );
+ memset(dev_priv->head, 0, sizeof(drm_r128_freelist_t));
dev_priv->head->age = R128_BUFFER_USED;
- for ( i = 0 ; i < dma->buf_count ; i++ ) {
+ for (i = 0; i < dma->buf_count; i++) {
buf = dma->buflist[i];
buf_priv = buf->dev_private;
- entry = drm_alloc( sizeof(drm_r128_freelist_t),
- DRM_MEM_DRIVER );
- if ( !entry ) return DRM_ERR(ENOMEM);
+ entry = drm_alloc(sizeof(drm_r128_freelist_t), DRM_MEM_DRIVER);
+ if (!entry)
+ return DRM_ERR(ENOMEM);
entry->age = R128_BUFFER_FREE;
entry->buf = buf;
entry->prev = dev_priv->head;
entry->next = dev_priv->head->next;
- if ( !entry->next )
+ if (!entry->next)
dev_priv->tail = entry;
buf_priv->discard = 0;
@@ -801,7 +803,7 @@ static int r128_freelist_init( drm_device_t *dev )
dev_priv->head->next = entry;
- if ( dev_priv->head->next )
+ if (dev_priv->head->next)
dev_priv->head->next->prev = entry;
}
@@ -810,7 +812,7 @@ static int r128_freelist_init( drm_device_t *dev )
}
#endif
-static drm_buf_t *r128_freelist_get( drm_device_t *dev )
+static drm_buf_t *r128_freelist_get(drm_device_t * dev)
{
drm_device_dma_t *dma = dev->dma;
drm_r128_private_t *dev_priv = dev->dev_private;
@@ -820,20 +822,20 @@ static drm_buf_t *r128_freelist_get( drm_device_t *dev )
/* FIXME: Optimize -- use freelist code */
- for ( i = 0 ; i < dma->buf_count ; i++ ) {
+ for (i = 0; i < dma->buf_count; i++) {
buf = dma->buflist[i];
buf_priv = buf->dev_private;
- if ( buf->filp == 0 )
+ if (buf->filp == 0)
return buf;
}
- for ( t = 0 ; t < dev_priv->usec_timeout ; t++ ) {
- u32 done_age = R128_READ( R128_LAST_DISPATCH_REG );
+ for (t = 0; t < dev_priv->usec_timeout; t++) {
+ u32 done_age = R128_READ(R128_LAST_DISPATCH_REG);
- for ( i = 0 ; i < dma->buf_count ; i++ ) {
+ for (i = 0; i < dma->buf_count; i++) {
buf = dma->buflist[i];
buf_priv = buf->dev_private;
- if ( buf->pending && buf_priv->age <= done_age ) {
+ if (buf->pending && buf_priv->age <= done_age) {
/* The buffer has been processed, so it
* can now be used.
*/
@@ -841,63 +843,63 @@ static drm_buf_t *r128_freelist_get( drm_device_t *dev )
return buf;
}
}
- DRM_UDELAY( 1 );
+ DRM_UDELAY(1);
}
- DRM_DEBUG( "returning NULL!\n" );
+ DRM_DEBUG("returning NULL!\n");
return NULL;
}
-void r128_freelist_reset( drm_device_t *dev )
+void r128_freelist_reset(drm_device_t * dev)
{
drm_device_dma_t *dma = dev->dma;
int i;
- for ( i = 0 ; i < dma->buf_count ; i++ ) {
+ for (i = 0; i < dma->buf_count; i++) {
drm_buf_t *buf = dma->buflist[i];
drm_r128_buf_priv_t *buf_priv = buf->dev_private;
buf_priv->age = 0;
}
}
-
/* ================================================================
* CCE command submission
*/
-int r128_wait_ring( drm_r128_private_t *dev_priv, int n )
+int r128_wait_ring(drm_r128_private_t * dev_priv, int n)
{
drm_r128_ring_buffer_t *ring = &dev_priv->ring;
int i;
- for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) {
- r128_update_ring_snapshot( dev_priv );
- if ( ring->space >= n )
+ for (i = 0; i < dev_priv->usec_timeout; i++) {
+ r128_update_ring_snapshot(dev_priv);
+ if (ring->space >= n)
return 0;
- DRM_UDELAY( 1 );
+ DRM_UDELAY(1);
}
/* FIXME: This is being ignored... */
- DRM_ERROR( "failed!\n" );
+ DRM_ERROR("failed!\n");
return DRM_ERR(EBUSY);
}
-static int r128_cce_get_buffers( DRMFILE filp, drm_device_t *dev, drm_dma_t *d )
+static int r128_cce_get_buffers(DRMFILE filp, drm_device_t * dev, drm_dma_t * d)
{
int i;
drm_buf_t *buf;
- for ( i = d->granted_count ; i < d->request_count ; i++ ) {
- buf = r128_freelist_get( dev );
- if ( !buf ) return DRM_ERR(EAGAIN);
+ for (i = d->granted_count; i < d->request_count; i++) {
+ buf = r128_freelist_get(dev);
+ if (!buf)
+ return DRM_ERR(EAGAIN);
buf->filp = filp;
- if ( DRM_COPY_TO_USER( &d->request_indices[i], &buf->idx,
- sizeof(buf->idx) ) )
+ if (DRM_COPY_TO_USER(&d->request_indices[i], &buf->idx,
+ sizeof(buf->idx)))
return DRM_ERR(EFAULT);
- if ( DRM_COPY_TO_USER( &d->request_sizes[i], &buf->total,
- sizeof(buf->total) ) )
+ if (DRM_COPY_TO_USER(&d->request_sizes[i], &buf->total,
+ sizeof(buf->total)))
return DRM_ERR(EFAULT);
d->granted_count++;
@@ -905,7 +907,7 @@ static int r128_cce_get_buffers( DRMFILE filp, drm_device_t *dev, drm_dma_t *d )
return 0;
}
-int r128_cce_buffers( DRM_IOCTL_ARGS )
+int r128_cce_buffers(DRM_IOCTL_ARGS)
{
DRM_DEVICE;
drm_device_dma_t *dma = dev->dma;
@@ -913,33 +915,33 @@ int r128_cce_buffers( DRM_IOCTL_ARGS )
drm_dma_t __user *argp = (void __user *)data;
drm_dma_t d;
- LOCK_TEST_WITH_RETURN( dev, filp );
+ LOCK_TEST_WITH_RETURN(dev, filp);
- DRM_COPY_FROM_USER_IOCTL( d, argp, sizeof(d) );
+ DRM_COPY_FROM_USER_IOCTL(d, argp, sizeof(d));
/* Please don't send us buffers.
*/
- if ( d.send_count != 0 ) {
- DRM_ERROR( "Process %d trying to send %d buffers via drmDMA\n",
- DRM_CURRENTPID, d.send_count );
+ if (d.send_count != 0) {
+ DRM_ERROR("Process %d trying to send %d buffers via drmDMA\n",
+ DRM_CURRENTPID, d.send_count);
return DRM_ERR(EINVAL);
}
/* We'll send you buffers.
*/
- if ( d.request_count < 0 || d.request_count > dma->buf_count ) {
- DRM_ERROR( "Process %d trying to get %d buffers (of %d max)\n",
- DRM_CURRENTPID, d.request_count, dma->buf_count );
+ if (d.request_count < 0 || d.request_count > dma->buf_count) {
+ DRM_ERROR("Process %d trying to get %d buffers (of %d max)\n",
+ DRM_CURRENTPID, d.request_count, dma->buf_count);
return DRM_ERR(EINVAL);
}
d.granted_count = 0;
- if ( d.request_count ) {
- ret = r128_cce_get_buffers( filp, dev, &d );
+ if (d.request_count) {
+ ret = r128_cce_get_buffers(filp, dev, &d);
}
- DRM_COPY_TO_USER_IOCTL(argp, d, sizeof(d) );
+ DRM_COPY_TO_USER_IOCTL(argp, d, sizeof(d));
return ret;
}
diff --git a/drivers/char/drm/r128_drm.h b/drivers/char/drm/r128_drm.h
index b616cd3ed2cd..5ddc03202411 100644
--- a/drivers/char/drm/r128_drm.h
+++ b/drivers/char/drm/r128_drm.h
@@ -93,7 +93,7 @@
#define R128_MAX_TEXTURE_LEVELS 11
#define R128_MAX_TEXTURE_UNITS 2
-#endif /* __R128_SAREA_DEFINES__ */
+#endif /* __R128_SAREA_DEFINES__ */
typedef struct {
/* Context state - can be written in one large chunk */
@@ -140,7 +140,6 @@ typedef struct {
unsigned int tex_border_color;
} drm_r128_texture_regs_t;
-
typedef struct drm_r128_sarea {
/* The channel for communication of state information to the kernel
* on firing a vertex buffer.
@@ -161,14 +160,13 @@ typedef struct drm_r128_sarea {
unsigned int last_frame;
unsigned int last_dispatch;
- drm_tex_region_t tex_list[R128_NR_TEX_HEAPS][R128_NR_TEX_REGIONS+1];
+ drm_tex_region_t tex_list[R128_NR_TEX_HEAPS][R128_NR_TEX_REGIONS + 1];
unsigned int tex_age[R128_NR_TEX_HEAPS];
int ctx_owner;
- int pfAllowPageFlip; /* number of 3d windows (0,1,2 or more) */
- int pfCurrentPage; /* which buffer is being displayed? */
+ int pfAllowPageFlip; /* number of 3d windows (0,1,2 or more) */
+ int pfCurrentPage; /* which buffer is being displayed? */
} drm_r128_sarea_t;
-
/* WARNING: If you change any of these defines, make sure to change the
* defines in the Xserver file (xf86drmR128.h)
*/
@@ -220,7 +218,7 @@ typedef struct drm_r128_sarea {
typedef struct drm_r128_init {
enum {
- R128_INIT_CCE = 0x01,
+ R128_INIT_CCE = 0x01,
R128_CLEANUP_CCE = 0x02
} func;
#if CONFIG_XFREE86_VERSION < XFREE86_VERSION(4,1,0,0)
@@ -278,9 +276,9 @@ typedef struct drm_r128_clear {
typedef struct drm_r128_vertex {
int prim;
- int idx; /* Index of vertex buffer */
- int count; /* Number of vertices in buffer */
- int discard; /* Client finished with buffer? */
+ int idx; /* Index of vertex buffer */
+ int count; /* Number of vertices in buffer */
+ int discard; /* Client finished with buffer? */
} drm_r128_vertex_t;
typedef struct drm_r128_indices {
@@ -288,7 +286,7 @@ typedef struct drm_r128_indices {
int idx;
int start;
int end;
- int discard; /* Client finished with buffer? */
+ int discard; /* Client finished with buffer? */
} drm_r128_indices_t;
typedef struct drm_r128_blit {
@@ -302,10 +300,10 @@ typedef struct drm_r128_blit {
typedef struct drm_r128_depth {
enum {
- R128_WRITE_SPAN = 0x01,
- R128_WRITE_PIXELS = 0x02,
- R128_READ_SPAN = 0x03,
- R128_READ_PIXELS = 0x04
+ R128_WRITE_SPAN = 0x01,
+ R128_WRITE_PIXELS = 0x02,
+ R128_READ_SPAN = 0x03,
+ R128_READ_PIXELS = 0x04
} func;
int n;
int __user *x;
@@ -327,13 +325,13 @@ typedef struct drm_r128_indirect {
typedef struct drm_r128_fullscreen {
enum {
- R128_INIT_FULLSCREEN = 0x01,
+ R128_INIT_FULLSCREEN = 0x01,
R128_CLEANUP_FULLSCREEN = 0x02
} func;
} drm_r128_fullscreen_t;
/* 2.3: An ioctl to get parameters that aren't available to the 3d
- * client any other way.
+ * client any other way.
*/
#define R128_PARAM_IRQ_NR 1
diff --git a/drivers/char/drm/r128_drv.c b/drivers/char/drm/r128_drv.c
index bc446da1b210..1661e7351402 100644
--- a/drivers/char/drm/r128_drv.c
+++ b/drivers/char/drm/r128_drv.c
@@ -37,30 +37,28 @@
#include "drm_pciids.h"
-static int postinit( struct drm_device *dev, unsigned long flags )
+static int postinit(struct drm_device *dev, unsigned long flags)
{
- DRM_INFO( "Initialized %s %d.%d.%d %s on minor %d: %s\n",
- DRIVER_NAME,
- DRIVER_MAJOR,
- DRIVER_MINOR,
- DRIVER_PATCHLEVEL,
- DRIVER_DATE,
- dev->primary.minor,
- pci_pretty_name(dev->pdev)
- );
+ DRM_INFO("Initialized %s %d.%d.%d %s on minor %d: %s\n",
+ DRIVER_NAME,
+ DRIVER_MAJOR,
+ DRIVER_MINOR,
+ DRIVER_PATCHLEVEL,
+ DRIVER_DATE, dev->primary.minor, pci_pretty_name(dev->pdev)
+ );
return 0;
}
-static int version( drm_version_t *version )
+static int version(drm_version_t * version)
{
int len;
version->version_major = DRIVER_MAJOR;
version->version_minor = DRIVER_MINOR;
version->version_patchlevel = DRIVER_PATCHLEVEL;
- DRM_COPY( version->name, DRIVER_NAME );
- DRM_COPY( version->date, DRIVER_DATE );
- DRM_COPY( version->desc, DRIVER_DESC );
+ DRM_COPY(version->name, DRIVER_NAME);
+ DRM_COPY(version->date, DRIVER_DATE);
+ DRM_COPY(version->desc, DRIVER_DESC);
return 0;
}
@@ -68,11 +66,11 @@ static struct pci_device_id pciidlist[] = {
r128_PCI_IDS
};
-extern drm_ioctl_desc_t r128_ioctls[];
-extern int r128_max_ioctl;
-
static struct drm_driver driver = {
- .driver_features = DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | DRIVER_SG | DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_IRQ_VBL,
+ .driver_features =
+ DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | DRIVER_SG |
+ DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED |
+ DRIVER_IRQ_VBL,
.dev_priv_size = sizeof(drm_r128_buf_priv_t),
.prerelease = r128_driver_prerelease,
.pretakedown = r128_driver_pretakedown,
@@ -89,21 +87,22 @@ static struct drm_driver driver = {
.ioctls = r128_ioctls,
.dma_ioctl = r128_cce_buffers,
.fops = {
- .owner = THIS_MODULE,
- .open = drm_open,
- .release = drm_release,
- .ioctl = drm_ioctl,
- .mmap = drm_mmap,
- .poll = drm_poll,
- .fasync = drm_fasync,
+ .owner = THIS_MODULE,
+ .open = drm_open,
+ .release = drm_release,
+ .ioctl = drm_ioctl,
+ .mmap = drm_mmap,
+ .poll = drm_poll,
+ .fasync = drm_fasync,
#ifdef CONFIG_COMPAT
- .compat_ioctl = r128_compat_ioctl,
+ .compat_ioctl = r128_compat_ioctl,
#endif
- },
+ }
+ ,
.pci_driver = {
- .name = DRIVER_NAME,
- .id_table = pciidlist,
- }
+ .name = DRIVER_NAME,
+ .id_table = pciidlist,
+ }
};
static int __init r128_init(void)
@@ -120,6 +119,6 @@ static void __exit r128_exit(void)
module_init(r128_init);
module_exit(r128_exit);
-MODULE_AUTHOR( DRIVER_AUTHOR );
-MODULE_DESCRIPTION( DRIVER_DESC );
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL and additional rights");
diff --git a/drivers/char/drm/r128_drv.h b/drivers/char/drm/r128_drv.h
index 0fb687c9505e..5c79e40eb88f 100644
--- a/drivers/char/drm/r128_drv.h
+++ b/drivers/char/drm/r128_drv.h
@@ -52,14 +52,13 @@
#define DRIVER_MINOR 5
#define DRIVER_PATCHLEVEL 0
-
#define GET_RING_HEAD(dev_priv) R128_READ( R128_PM4_BUFFER_DL_RPTR )
typedef struct drm_r128_freelist {
- unsigned int age;
- drm_buf_t *buf;
- struct drm_r128_freelist *next;
- struct drm_r128_freelist *prev;
+ unsigned int age;
+ drm_buf_t *buf;
+ struct drm_r128_freelist *next;
+ struct drm_r128_freelist *prev;
} drm_r128_freelist_t;
typedef struct drm_r128_ring_buffer {
@@ -83,13 +82,11 @@ typedef struct drm_r128_private {
int cce_fifo_size;
int cce_running;
- drm_r128_freelist_t *head;
- drm_r128_freelist_t *tail;
+ drm_r128_freelist_t *head;
+ drm_r128_freelist_t *tail;
int usec_timeout;
int is_pci;
- unsigned long phys_pci_gart;
- dma_addr_t bus_pci_gart;
unsigned long cce_buffers_offset;
atomic_t idle_count;
@@ -120,6 +117,7 @@ typedef struct drm_r128_private {
drm_local_map_t *cce_ring;
drm_local_map_t *ring_rptr;
drm_local_map_t *agp_textures;
+ drm_ati_pcigart_info gart_info;
} drm_r128_private_t;
typedef struct drm_r128_buf_priv {
@@ -127,34 +125,37 @@ typedef struct drm_r128_buf_priv {
int prim;
int discard;
int dispatched;
- drm_r128_freelist_t *list_entry;
+ drm_r128_freelist_t *list_entry;
} drm_r128_buf_priv_t;
+extern drm_ioctl_desc_t r128_ioctls[];
+extern int r128_max_ioctl;
+
/* r128_cce.c */
-extern int r128_cce_init( DRM_IOCTL_ARGS );
-extern int r128_cce_start( DRM_IOCTL_ARGS );
-extern int r128_cce_stop( DRM_IOCTL_ARGS );
-extern int r128_cce_reset( DRM_IOCTL_ARGS );
-extern int r128_cce_idle( DRM_IOCTL_ARGS );
-extern int r128_engine_reset( DRM_IOCTL_ARGS );
-extern int r128_fullscreen( DRM_IOCTL_ARGS );
-extern int r128_cce_buffers( DRM_IOCTL_ARGS );
+extern int r128_cce_init(DRM_IOCTL_ARGS);
+extern int r128_cce_start(DRM_IOCTL_ARGS);
+extern int r128_cce_stop(DRM_IOCTL_ARGS);
+extern int r128_cce_reset(DRM_IOCTL_ARGS);
+extern int r128_cce_idle(DRM_IOCTL_ARGS);
+extern int r128_engine_reset(DRM_IOCTL_ARGS);
+extern int r128_fullscreen(DRM_IOCTL_ARGS);
+extern int r128_cce_buffers(DRM_IOCTL_ARGS);
-extern void r128_freelist_reset( drm_device_t *dev );
+extern void r128_freelist_reset(drm_device_t * dev);
-extern int r128_wait_ring( drm_r128_private_t *dev_priv, int n );
+extern int r128_wait_ring(drm_r128_private_t * dev_priv, int n);
-extern int r128_do_cce_idle( drm_r128_private_t *dev_priv );
-extern int r128_do_cleanup_cce( drm_device_t *dev );
+extern int r128_do_cce_idle(drm_r128_private_t * dev_priv);
+extern int r128_do_cleanup_cce(drm_device_t * dev);
-extern int r128_driver_vblank_wait(drm_device_t *dev, unsigned int *sequence);
+extern int r128_driver_vblank_wait(drm_device_t * dev, unsigned int *sequence);
-extern irqreturn_t r128_driver_irq_handler( DRM_IRQ_ARGS );
-extern void r128_driver_irq_preinstall( drm_device_t *dev );
-extern void r128_driver_irq_postinstall( drm_device_t *dev );
-extern void r128_driver_irq_uninstall( drm_device_t *dev );
-extern void r128_driver_pretakedown(drm_device_t *dev);
-extern void r128_driver_prerelease(drm_device_t *dev, DRMFILE filp);
+extern irqreturn_t r128_driver_irq_handler(DRM_IRQ_ARGS);
+extern void r128_driver_irq_preinstall(drm_device_t * dev);
+extern void r128_driver_irq_postinstall(drm_device_t * dev);
+extern void r128_driver_irq_uninstall(drm_device_t * dev);
+extern void r128_driver_pretakedown(drm_device_t * dev);
+extern void r128_driver_prerelease(drm_device_t * dev, DRMFILE filp);
extern long r128_compat_ioctl(struct file *filp, unsigned int cmd,
unsigned long arg);
@@ -266,7 +267,6 @@ extern long r128_compat_ioctl(struct file *filp, unsigned int cmd,
# define R128_EVENT_CRTC_OFFSET (1 << 0)
#define R128_WINDOW_XY_OFFSET 0x1bcc
-
/* CCE registers
*/
#define R128_PM4_BUFFER_OFFSET 0x0700
@@ -317,7 +317,6 @@ extern long r128_compat_ioctl(struct file *filp, unsigned int cmd,
#define R128_PM4_FIFO_DATA_EVEN 0x1000
#define R128_PM4_FIFO_DATA_ODD 0x1004
-
/* CCE command packets
*/
#define R128_CCE_PACKET0 0x00000000
@@ -395,7 +394,6 @@ do { \
R128_WRITE(R128_CLOCK_CNTL_DATA, (val)); \
} while (0)
-
#define CCE_PACKET0( reg, n ) (R128_CCE_PACKET0 | \
((n) << 16) | ((reg) >> 2))
#define CCE_PACKET1( reg0, reg1 ) (R128_CCE_PACKET1 | \
@@ -404,13 +402,11 @@ do { \
#define CCE_PACKET3( pkt, n ) (R128_CCE_PACKET3 | \
(pkt) | ((n) << 16))
-
-static __inline__ void
-r128_update_ring_snapshot( drm_r128_private_t *dev_priv )
+static __inline__ void r128_update_ring_snapshot(drm_r128_private_t * dev_priv)
{
drm_r128_ring_buffer_t *ring = &dev_priv->ring;
- ring->space = (GET_RING_HEAD( dev_priv ) - ring->tail) * sizeof(u32);
- if ( ring->space <= 0 )
+ ring->space = (GET_RING_HEAD(dev_priv) - ring->tail) * sizeof(u32);
+ if (ring->space <= 0)
ring->space += ring->size;
}
@@ -451,7 +447,6 @@ do { \
OUT_RING( R128_EVENT_CRTC_OFFSET ); \
} while (0)
-
/* ================================================================
* Ring control
*/
@@ -521,4 +516,4 @@ do { \
write &= tail_mask; \
} while (0)
-#endif /* __R128_DRV_H__ */
+#endif /* __R128_DRV_H__ */
diff --git a/drivers/char/drm/r128_ioc32.c b/drivers/char/drm/r128_ioc32.c
index 60598ef9475a..1e2e367b8b82 100644
--- a/drivers/char/drm/r128_ioc32.c
+++ b/drivers/char/drm/r128_ioc32.c
@@ -65,10 +65,10 @@ static int compat_r128_init(struct file *file, unsigned int cmd,
{
drm_r128_init32_t init32;
drm_r128_init_t __user *init;
-
+
if (copy_from_user(&init32, (void __user *)arg, sizeof(init32)))
return -EFAULT;
-
+
init = compat_alloc_user_space(sizeof(*init));
if (!access_ok(VERIFY_WRITE, init, sizeof(*init))
|| __put_user(init32.func, &init->func)
@@ -92,14 +92,14 @@ static int compat_r128_init(struct file *file, unsigned int cmd,
|| __put_user(init32.ring_offset, &init->ring_offset)
|| __put_user(init32.ring_rptr_offset, &init->ring_rptr_offset)
|| __put_user(init32.buffers_offset, &init->buffers_offset)
- || __put_user(init32.agp_textures_offset, &init->agp_textures_offset))
+ || __put_user(init32.agp_textures_offset,
+ &init->agp_textures_offset))
return -EFAULT;
-
+
return drm_ioctl(file->f_dentry->d_inode, file,
DRM_IOCTL_R128_INIT, (unsigned long)init);
}
-
typedef struct drm_r128_depth32 {
int func;
int n;
@@ -124,13 +124,15 @@ static int compat_r128_depth(struct file *file, unsigned int cmd,
|| __put_user(depth32.n, &depth->n)
|| __put_user((int __user *)(unsigned long)depth32.x, &depth->x)
|| __put_user((int __user *)(unsigned long)depth32.y, &depth->y)
- || __put_user((unsigned int __user *)(unsigned long)depth32.buffer, &depth->buffer)
- || __put_user((unsigned char __user *)(unsigned long)depth32.mask, &depth->mask))
+ || __put_user((unsigned int __user *)(unsigned long)depth32.buffer,
+ &depth->buffer)
+ || __put_user((unsigned char __user *)(unsigned long)depth32.mask,
+ &depth->mask))
return -EFAULT;
-
+
return drm_ioctl(file->f_dentry->d_inode, file,
- DRM_IOCTL_R128_DEPTH, (unsigned long)depth);
-
+ DRM_IOCTL_R128_DEPTH, (unsigned long)depth);
+
}
typedef struct drm_r128_stipple32 {
@@ -148,7 +150,8 @@ static int compat_r128_stipple(struct file *file, unsigned int cmd,
stipple = compat_alloc_user_space(sizeof(*stipple));
if (!access_ok(VERIFY_WRITE, stipple, sizeof(*stipple))
- || __put_user((unsigned int __user *)(unsigned long)stipple32.mask, &stipple->mask))
+ || __put_user((unsigned int __user *)(unsigned long)stipple32.mask,
+ &stipple->mask))
return -EFAULT;
return drm_ioctl(file->f_dentry->d_inode, file,
@@ -172,9 +175,10 @@ static int compat_r128_getparam(struct file *file, unsigned int cmd,
getparam = compat_alloc_user_space(sizeof(*getparam));
if (!access_ok(VERIFY_WRITE, getparam, sizeof(*getparam))
|| __put_user(getparam32.param, &getparam->param)
- || __put_user((void __user *)(unsigned long)getparam32.value, &getparam->value))
+ || __put_user((void __user *)(unsigned long)getparam32.value,
+ &getparam->value))
return -EFAULT;
-
+
return drm_ioctl(file->f_dentry->d_inode, file,
DRM_IOCTL_R128_GETPARAM, (unsigned long)getparam);
}
@@ -195,8 +199,7 @@ drm_ioctl_compat_t *r128_compat_ioctls[] = {
* \param arg user argument.
* \return zero on success or negative number on failure.
*/
-long r128_compat_ioctl(struct file *filp, unsigned int cmd,
- unsigned long arg)
+long r128_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
unsigned int nr = DRM_IOCTL_NR(cmd);
drm_ioctl_compat_t *fn = NULL;
@@ -210,7 +213,7 @@ long r128_compat_ioctl(struct file *filp, unsigned int cmd,
lock_kernel(); /* XXX for now */
if (fn != NULL)
- ret = (*fn)(filp, cmd, arg);
+ ret = (*fn) (filp, cmd, arg);
else
ret = drm_ioctl(filp->f_dentry->d_inode, filp, cmd, arg);
unlock_kernel();
diff --git a/drivers/char/drm/r128_irq.c b/drivers/char/drm/r128_irq.c
index 643a30785fe5..27eb0e31bd3b 100644
--- a/drivers/char/drm/r128_irq.c
+++ b/drivers/char/drm/r128_irq.c
@@ -1,7 +1,7 @@
/* r128_irq.c -- IRQ handling for radeon -*- linux-c -*-
*
* Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
- *
+ *
* The Weather Channel (TM) funded Tungsten Graphics to develop the
* initial release of the Radeon 8500 driver under the XFree86 license.
* This notice must be preserved.
@@ -35,68 +35,67 @@
#include "r128_drm.h"
#include "r128_drv.h"
-irqreturn_t r128_driver_irq_handler( DRM_IRQ_ARGS )
+irqreturn_t r128_driver_irq_handler(DRM_IRQ_ARGS)
{
drm_device_t *dev = (drm_device_t *) arg;
- drm_r128_private_t *dev_priv =
- (drm_r128_private_t *)dev->dev_private;
+ drm_r128_private_t *dev_priv = (drm_r128_private_t *) dev->dev_private;
int status;
- status = R128_READ( R128_GEN_INT_STATUS );
-
+ status = R128_READ(R128_GEN_INT_STATUS);
+
/* VBLANK interrupt */
- if ( status & R128_CRTC_VBLANK_INT ) {
- R128_WRITE( R128_GEN_INT_STATUS, R128_CRTC_VBLANK_INT_AK );
+ if (status & R128_CRTC_VBLANK_INT) {
+ R128_WRITE(R128_GEN_INT_STATUS, R128_CRTC_VBLANK_INT_AK);
atomic_inc(&dev->vbl_received);
DRM_WAKEUP(&dev->vbl_queue);
- drm_vbl_send_signals( dev );
+ drm_vbl_send_signals(dev);
return IRQ_HANDLED;
}
return IRQ_NONE;
}
-int r128_driver_vblank_wait(drm_device_t *dev, unsigned int *sequence)
+int r128_driver_vblank_wait(drm_device_t * dev, unsigned int *sequence)
{
unsigned int cur_vblank;
int ret = 0;
/* Assume that the user has missed the current sequence number
* by about a day rather than she wants to wait for years
- * using vertical blanks...
+ * using vertical blanks...
*/
- DRM_WAIT_ON( ret, dev->vbl_queue, 3*DRM_HZ,
- ( ( ( cur_vblank = atomic_read(&dev->vbl_received ) )
- - *sequence ) <= (1<<23) ) );
+ DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ,
+ (((cur_vblank = atomic_read(&dev->vbl_received))
+ - *sequence) <= (1 << 23)));
*sequence = cur_vblank;
return ret;
}
-void r128_driver_irq_preinstall( drm_device_t *dev ) {
- drm_r128_private_t *dev_priv =
- (drm_r128_private_t *)dev->dev_private;
+void r128_driver_irq_preinstall(drm_device_t * dev)
+{
+ drm_r128_private_t *dev_priv = (drm_r128_private_t *) dev->dev_private;
/* Disable *all* interrupts */
- R128_WRITE( R128_GEN_INT_CNTL, 0 );
+ R128_WRITE(R128_GEN_INT_CNTL, 0);
/* Clear vblank bit if it's already high */
- R128_WRITE( R128_GEN_INT_STATUS, R128_CRTC_VBLANK_INT_AK );
+ R128_WRITE(R128_GEN_INT_STATUS, R128_CRTC_VBLANK_INT_AK);
}
-void r128_driver_irq_postinstall( drm_device_t *dev ) {
- drm_r128_private_t *dev_priv =
- (drm_r128_private_t *)dev->dev_private;
+void r128_driver_irq_postinstall(drm_device_t * dev)
+{
+ drm_r128_private_t *dev_priv = (drm_r128_private_t *) dev->dev_private;
/* Turn on VBL interrupt */
- R128_WRITE( R128_GEN_INT_CNTL, R128_CRTC_VBLANK_INT_EN );
+ R128_WRITE(R128_GEN_INT_CNTL, R128_CRTC_VBLANK_INT_EN);
}
-void r128_driver_irq_uninstall( drm_device_t *dev ) {
- drm_r128_private_t *dev_priv =
- (drm_r128_private_t *)dev->dev_private;
+void r128_driver_irq_uninstall(drm_device_t * dev)
+{
+ drm_r128_private_t *dev_priv = (drm_r128_private_t *) dev->dev_private;
if (!dev_priv)
return;
/* Disable *all* interrupts */
- R128_WRITE( R128_GEN_INT_CNTL, 0 );
+ R128_WRITE(R128_GEN_INT_CNTL, 0);
}
diff --git a/drivers/char/drm/r128_state.c b/drivers/char/drm/r128_state.c
index 426a71c049d9..14479cc08a57 100644
--- a/drivers/char/drm/r128_state.c
+++ b/drivers/char/drm/r128_state.c
@@ -32,235 +32,233 @@
#include "r128_drm.h"
#include "r128_drv.h"
-
/* ================================================================
* CCE hardware state programming functions
*/
-static void r128_emit_clip_rects( drm_r128_private_t *dev_priv,
- drm_clip_rect_t *boxes, int count )
+static void r128_emit_clip_rects(drm_r128_private_t * dev_priv,
+ drm_clip_rect_t * boxes, int count)
{
u32 aux_sc_cntl = 0x00000000;
RING_LOCALS;
- DRM_DEBUG( " %s\n", __FUNCTION__ );
+ DRM_DEBUG(" %s\n", __FUNCTION__);
- BEGIN_RING( (count < 3? count: 3) * 5 + 2 );
+ BEGIN_RING((count < 3 ? count : 3) * 5 + 2);
- if ( count >= 1 ) {
- OUT_RING( CCE_PACKET0( R128_AUX1_SC_LEFT, 3 ) );
- OUT_RING( boxes[0].x1 );
- OUT_RING( boxes[0].x2 - 1 );
- OUT_RING( boxes[0].y1 );
- OUT_RING( boxes[0].y2 - 1 );
+ if (count >= 1) {
+ OUT_RING(CCE_PACKET0(R128_AUX1_SC_LEFT, 3));
+ OUT_RING(boxes[0].x1);
+ OUT_RING(boxes[0].x2 - 1);
+ OUT_RING(boxes[0].y1);
+ OUT_RING(boxes[0].y2 - 1);
aux_sc_cntl |= (R128_AUX1_SC_EN | R128_AUX1_SC_MODE_OR);
}
- if ( count >= 2 ) {
- OUT_RING( CCE_PACKET0( R128_AUX2_SC_LEFT, 3 ) );
- OUT_RING( boxes[1].x1 );
- OUT_RING( boxes[1].x2 - 1 );
- OUT_RING( boxes[1].y1 );
- OUT_RING( boxes[1].y2 - 1 );
+ if (count >= 2) {
+ OUT_RING(CCE_PACKET0(R128_AUX2_SC_LEFT, 3));
+ OUT_RING(boxes[1].x1);
+ OUT_RING(boxes[1].x2 - 1);
+ OUT_RING(boxes[1].y1);
+ OUT_RING(boxes[1].y2 - 1);
aux_sc_cntl |= (R128_AUX2_SC_EN | R128_AUX2_SC_MODE_OR);
}
- if ( count >= 3 ) {
- OUT_RING( CCE_PACKET0( R128_AUX3_SC_LEFT, 3 ) );
- OUT_RING( boxes[2].x1 );
- OUT_RING( boxes[2].x2 - 1 );
- OUT_RING( boxes[2].y1 );
- OUT_RING( boxes[2].y2 - 1 );
+ if (count >= 3) {
+ OUT_RING(CCE_PACKET0(R128_AUX3_SC_LEFT, 3));
+ OUT_RING(boxes[2].x1);
+ OUT_RING(boxes[2].x2 - 1);
+ OUT_RING(boxes[2].y1);
+ OUT_RING(boxes[2].y2 - 1);
aux_sc_cntl |= (R128_AUX3_SC_EN | R128_AUX3_SC_MODE_OR);
}
- OUT_RING( CCE_PACKET0( R128_AUX_SC_CNTL, 0 ) );
- OUT_RING( aux_sc_cntl );
+ OUT_RING(CCE_PACKET0(R128_AUX_SC_CNTL, 0));
+ OUT_RING(aux_sc_cntl);
ADVANCE_RING();
}
-static __inline__ void r128_emit_core( drm_r128_private_t *dev_priv )
+static __inline__ void r128_emit_core(drm_r128_private_t * dev_priv)
{
drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
drm_r128_context_regs_t *ctx = &sarea_priv->context_state;
RING_LOCALS;
- DRM_DEBUG( " %s\n", __FUNCTION__ );
+ DRM_DEBUG(" %s\n", __FUNCTION__);
- BEGIN_RING( 2 );
+ BEGIN_RING(2);
- OUT_RING( CCE_PACKET0( R128_SCALE_3D_CNTL, 0 ) );
- OUT_RING( ctx->scale_3d_cntl );
+ OUT_RING(CCE_PACKET0(R128_SCALE_3D_CNTL, 0));
+ OUT_RING(ctx->scale_3d_cntl);
ADVANCE_RING();
}
-static __inline__ void r128_emit_context( drm_r128_private_t *dev_priv )
+static __inline__ void r128_emit_context(drm_r128_private_t * dev_priv)
{
drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
drm_r128_context_regs_t *ctx = &sarea_priv->context_state;
RING_LOCALS;
- DRM_DEBUG( " %s\n", __FUNCTION__ );
-
- BEGIN_RING( 13 );
-
- OUT_RING( CCE_PACKET0( R128_DST_PITCH_OFFSET_C, 11 ) );
- OUT_RING( ctx->dst_pitch_offset_c );
- OUT_RING( ctx->dp_gui_master_cntl_c );
- OUT_RING( ctx->sc_top_left_c );
- OUT_RING( ctx->sc_bottom_right_c );
- OUT_RING( ctx->z_offset_c );
- OUT_RING( ctx->z_pitch_c );
- OUT_RING( ctx->z_sten_cntl_c );
- OUT_RING( ctx->tex_cntl_c );
- OUT_RING( ctx->misc_3d_state_cntl_reg );
- OUT_RING( ctx->texture_clr_cmp_clr_c );
- OUT_RING( ctx->texture_clr_cmp_msk_c );
- OUT_RING( ctx->fog_color_c );
+ DRM_DEBUG(" %s\n", __FUNCTION__);
+
+ BEGIN_RING(13);
+
+ OUT_RING(CCE_PACKET0(R128_DST_PITCH_OFFSET_C, 11));
+ OUT_RING(ctx->dst_pitch_offset_c);
+ OUT_RING(ctx->dp_gui_master_cntl_c);
+ OUT_RING(ctx->sc_top_left_c);
+ OUT_RING(ctx->sc_bottom_right_c);
+ OUT_RING(ctx->z_offset_c);
+ OUT_RING(ctx->z_pitch_c);
+ OUT_RING(ctx->z_sten_cntl_c);
+ OUT_RING(ctx->tex_cntl_c);
+ OUT_RING(ctx->misc_3d_state_cntl_reg);
+ OUT_RING(ctx->texture_clr_cmp_clr_c);
+ OUT_RING(ctx->texture_clr_cmp_msk_c);
+ OUT_RING(ctx->fog_color_c);
ADVANCE_RING();
}
-static __inline__ void r128_emit_setup( drm_r128_private_t *dev_priv )
+static __inline__ void r128_emit_setup(drm_r128_private_t * dev_priv)
{
drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
drm_r128_context_regs_t *ctx = &sarea_priv->context_state;
RING_LOCALS;
- DRM_DEBUG( " %s\n", __FUNCTION__ );
+ DRM_DEBUG(" %s\n", __FUNCTION__);
- BEGIN_RING( 3 );
+ BEGIN_RING(3);
- OUT_RING( CCE_PACKET1( R128_SETUP_CNTL, R128_PM4_VC_FPU_SETUP ) );
- OUT_RING( ctx->setup_cntl );
- OUT_RING( ctx->pm4_vc_fpu_setup );
+ OUT_RING(CCE_PACKET1(R128_SETUP_CNTL, R128_PM4_VC_FPU_SETUP));
+ OUT_RING(ctx->setup_cntl);
+ OUT_RING(ctx->pm4_vc_fpu_setup);
ADVANCE_RING();
}
-static __inline__ void r128_emit_masks( drm_r128_private_t *dev_priv )
+static __inline__ void r128_emit_masks(drm_r128_private_t * dev_priv)
{
drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
drm_r128_context_regs_t *ctx = &sarea_priv->context_state;
RING_LOCALS;
- DRM_DEBUG( " %s\n", __FUNCTION__ );
+ DRM_DEBUG(" %s\n", __FUNCTION__);
- BEGIN_RING( 5 );
+ BEGIN_RING(5);
- OUT_RING( CCE_PACKET0( R128_DP_WRITE_MASK, 0 ) );
- OUT_RING( ctx->dp_write_mask );
+ OUT_RING(CCE_PACKET0(R128_DP_WRITE_MASK, 0));
+ OUT_RING(ctx->dp_write_mask);
- OUT_RING( CCE_PACKET0( R128_STEN_REF_MASK_C, 1 ) );
- OUT_RING( ctx->sten_ref_mask_c );
- OUT_RING( ctx->plane_3d_mask_c );
+ OUT_RING(CCE_PACKET0(R128_STEN_REF_MASK_C, 1));
+ OUT_RING(ctx->sten_ref_mask_c);
+ OUT_RING(ctx->plane_3d_mask_c);
ADVANCE_RING();
}
-static __inline__ void r128_emit_window( drm_r128_private_t *dev_priv )
+static __inline__ void r128_emit_window(drm_r128_private_t * dev_priv)
{
drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
drm_r128_context_regs_t *ctx = &sarea_priv->context_state;
RING_LOCALS;
- DRM_DEBUG( " %s\n", __FUNCTION__ );
+ DRM_DEBUG(" %s\n", __FUNCTION__);
- BEGIN_RING( 2 );
+ BEGIN_RING(2);
- OUT_RING( CCE_PACKET0( R128_WINDOW_XY_OFFSET, 0 ) );
- OUT_RING( ctx->window_xy_offset );
+ OUT_RING(CCE_PACKET0(R128_WINDOW_XY_OFFSET, 0));
+ OUT_RING(ctx->window_xy_offset);
ADVANCE_RING();
}
-static __inline__ void r128_emit_tex0( drm_r128_private_t *dev_priv )
+static __inline__ void r128_emit_tex0(drm_r128_private_t * dev_priv)
{
drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
drm_r128_context_regs_t *ctx = &sarea_priv->context_state;
drm_r128_texture_regs_t *tex = &sarea_priv->tex_state[0];
int i;
RING_LOCALS;
- DRM_DEBUG( " %s\n", __FUNCTION__ );
+ DRM_DEBUG(" %s\n", __FUNCTION__);
- BEGIN_RING( 7 + R128_MAX_TEXTURE_LEVELS );
+ BEGIN_RING(7 + R128_MAX_TEXTURE_LEVELS);
- OUT_RING( CCE_PACKET0( R128_PRIM_TEX_CNTL_C,
- 2 + R128_MAX_TEXTURE_LEVELS ) );
- OUT_RING( tex->tex_cntl );
- OUT_RING( tex->tex_combine_cntl );
- OUT_RING( ctx->tex_size_pitch_c );
- for ( i = 0 ; i < R128_MAX_TEXTURE_LEVELS ; i++ ) {
- OUT_RING( tex->tex_offset[i] );
+ OUT_RING(CCE_PACKET0(R128_PRIM_TEX_CNTL_C,
+ 2 + R128_MAX_TEXTURE_LEVELS));
+ OUT_RING(tex->tex_cntl);
+ OUT_RING(tex->tex_combine_cntl);
+ OUT_RING(ctx->tex_size_pitch_c);
+ for (i = 0; i < R128_MAX_TEXTURE_LEVELS; i++) {
+ OUT_RING(tex->tex_offset[i]);
}
- OUT_RING( CCE_PACKET0( R128_CONSTANT_COLOR_C, 1 ) );
- OUT_RING( ctx->constant_color_c );
- OUT_RING( tex->tex_border_color );
+ OUT_RING(CCE_PACKET0(R128_CONSTANT_COLOR_C, 1));
+ OUT_RING(ctx->constant_color_c);
+ OUT_RING(tex->tex_border_color);
ADVANCE_RING();
}
-static __inline__ void r128_emit_tex1( drm_r128_private_t *dev_priv )
+static __inline__ void r128_emit_tex1(drm_r128_private_t * dev_priv)
{
drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
drm_r128_texture_regs_t *tex = &sarea_priv->tex_state[1];
int i;
RING_LOCALS;
- DRM_DEBUG( " %s\n", __FUNCTION__ );
+ DRM_DEBUG(" %s\n", __FUNCTION__);
- BEGIN_RING( 5 + R128_MAX_TEXTURE_LEVELS );
+ BEGIN_RING(5 + R128_MAX_TEXTURE_LEVELS);
- OUT_RING( CCE_PACKET0( R128_SEC_TEX_CNTL_C,
- 1 + R128_MAX_TEXTURE_LEVELS ) );
- OUT_RING( tex->tex_cntl );
- OUT_RING( tex->tex_combine_cntl );
- for ( i = 0 ; i < R128_MAX_TEXTURE_LEVELS ; i++ ) {
- OUT_RING( tex->tex_offset[i] );
+ OUT_RING(CCE_PACKET0(R128_SEC_TEX_CNTL_C, 1 + R128_MAX_TEXTURE_LEVELS));
+ OUT_RING(tex->tex_cntl);
+ OUT_RING(tex->tex_combine_cntl);
+ for (i = 0; i < R128_MAX_TEXTURE_LEVELS; i++) {
+ OUT_RING(tex->tex_offset[i]);
}
- OUT_RING( CCE_PACKET0( R128_SEC_TEXTURE_BORDER_COLOR_C, 0 ) );
- OUT_RING( tex->tex_border_color );
+ OUT_RING(CCE_PACKET0(R128_SEC_TEXTURE_BORDER_COLOR_C, 0));
+ OUT_RING(tex->tex_border_color);
ADVANCE_RING();
}
-static __inline__ void r128_emit_state( drm_r128_private_t *dev_priv )
+static __inline__ void r128_emit_state(drm_r128_private_t * dev_priv)
{
drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
unsigned int dirty = sarea_priv->dirty;
- DRM_DEBUG( "%s: dirty=0x%08x\n", __FUNCTION__, dirty );
+ DRM_DEBUG("%s: dirty=0x%08x\n", __FUNCTION__, dirty);
- if ( dirty & R128_UPLOAD_CORE ) {
- r128_emit_core( dev_priv );
+ if (dirty & R128_UPLOAD_CORE) {
+ r128_emit_core(dev_priv);
sarea_priv->dirty &= ~R128_UPLOAD_CORE;
}
- if ( dirty & R128_UPLOAD_CONTEXT ) {
- r128_emit_context( dev_priv );
+ if (dirty & R128_UPLOAD_CONTEXT) {
+ r128_emit_context(dev_priv);
sarea_priv->dirty &= ~R128_UPLOAD_CONTEXT;
}
- if ( dirty & R128_UPLOAD_SETUP ) {
- r128_emit_setup( dev_priv );
+ if (dirty & R128_UPLOAD_SETUP) {
+ r128_emit_setup(dev_priv);
sarea_priv->dirty &= ~R128_UPLOAD_SETUP;
}
- if ( dirty & R128_UPLOAD_MASKS ) {
- r128_emit_masks( dev_priv );
+ if (dirty & R128_UPLOAD_MASKS) {
+ r128_emit_masks(dev_priv);
sarea_priv->dirty &= ~R128_UPLOAD_MASKS;
}
- if ( dirty & R128_UPLOAD_WINDOW ) {
- r128_emit_window( dev_priv );
+ if (dirty & R128_UPLOAD_WINDOW) {
+ r128_emit_window(dev_priv);
sarea_priv->dirty &= ~R128_UPLOAD_WINDOW;
}
- if ( dirty & R128_UPLOAD_TEX0 ) {
- r128_emit_tex0( dev_priv );
+ if (dirty & R128_UPLOAD_TEX0) {
+ r128_emit_tex0(dev_priv);
sarea_priv->dirty &= ~R128_UPLOAD_TEX0;
}
- if ( dirty & R128_UPLOAD_TEX1 ) {
- r128_emit_tex1( dev_priv );
+ if (dirty & R128_UPLOAD_TEX1) {
+ r128_emit_tex1(dev_priv);
sarea_priv->dirty &= ~R128_UPLOAD_TEX1;
}
@@ -270,26 +268,23 @@ static __inline__ void r128_emit_state( drm_r128_private_t *dev_priv )
sarea_priv->dirty &= ~R128_REQUIRE_QUIESCENCE;
}
-
#if R128_PERFORMANCE_BOXES
/* ================================================================
* Performance monitoring functions
*/
-static void r128_clear_box( drm_r128_private_t *dev_priv,
- int x, int y, int w, int h,
- int r, int g, int b )
+static void r128_clear_box(drm_r128_private_t * dev_priv,
+ int x, int y, int w, int h, int r, int g, int b)
{
u32 pitch, offset;
u32 fb_bpp, color;
RING_LOCALS;
- switch ( dev_priv->fb_bpp ) {
+ switch (dev_priv->fb_bpp) {
case 16:
fb_bpp = R128_GMC_DST_16BPP;
color = (((r & 0xf8) << 8) |
- ((g & 0xfc) << 3) |
- ((b & 0xf8) >> 3));
+ ((g & 0xfc) << 3) | ((b & 0xf8) >> 3));
break;
case 24:
fb_bpp = R128_GMC_DST_24BPP;
@@ -297,7 +292,7 @@ static void r128_clear_box( drm_r128_private_t *dev_priv,
break;
case 32:
fb_bpp = R128_GMC_DST_32BPP;
- color = (((0xff) << 24) | (r << 16) | (g << 8) | b);
+ color = (((0xff) << 24) | (r << 16) | (g << 8) | b);
break;
default:
return;
@@ -306,60 +301,58 @@ static void r128_clear_box( drm_r128_private_t *dev_priv,
offset = dev_priv->back_offset;
pitch = dev_priv->back_pitch >> 3;
- BEGIN_RING( 6 );
+ BEGIN_RING(6);
- OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) );
- OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL |
- R128_GMC_BRUSH_SOLID_COLOR |
- fb_bpp |
- R128_GMC_SRC_DATATYPE_COLOR |
- R128_ROP3_P |
- R128_GMC_CLR_CMP_CNTL_DIS |
- R128_GMC_AUX_CLIP_DIS );
+ OUT_RING(CCE_PACKET3(R128_CNTL_PAINT_MULTI, 4));
+ OUT_RING(R128_GMC_DST_PITCH_OFFSET_CNTL |
+ R128_GMC_BRUSH_SOLID_COLOR |
+ fb_bpp |
+ R128_GMC_SRC_DATATYPE_COLOR |
+ R128_ROP3_P |
+ R128_GMC_CLR_CMP_CNTL_DIS | R128_GMC_AUX_CLIP_DIS);
- OUT_RING( (pitch << 21) | (offset >> 5) );
- OUT_RING( color );
+ OUT_RING((pitch << 21) | (offset >> 5));
+ OUT_RING(color);
- OUT_RING( (x << 16) | y );
- OUT_RING( (w << 16) | h );
+ OUT_RING((x << 16) | y);
+ OUT_RING((w << 16) | h);
ADVANCE_RING();
}
-static void r128_cce_performance_boxes( drm_r128_private_t *dev_priv )
+static void r128_cce_performance_boxes(drm_r128_private_t * dev_priv)
{
- if ( atomic_read( &dev_priv->idle_count ) == 0 ) {
- r128_clear_box( dev_priv, 64, 4, 8, 8, 0, 255, 0 );
+ if (atomic_read(&dev_priv->idle_count) == 0) {
+ r128_clear_box(dev_priv, 64, 4, 8, 8, 0, 255, 0);
} else {
- atomic_set( &dev_priv->idle_count, 0 );
+ atomic_set(&dev_priv->idle_count, 0);
}
}
#endif
-
/* ================================================================
* CCE command dispatch functions
*/
-static void r128_print_dirty( const char *msg, unsigned int flags )
+static void r128_print_dirty(const char *msg, unsigned int flags)
{
- DRM_INFO( "%s: (0x%x) %s%s%s%s%s%s%s%s%s\n",
- msg,
- flags,
- (flags & R128_UPLOAD_CORE) ? "core, " : "",
- (flags & R128_UPLOAD_CONTEXT) ? "context, " : "",
- (flags & R128_UPLOAD_SETUP) ? "setup, " : "",
- (flags & R128_UPLOAD_TEX0) ? "tex0, " : "",
- (flags & R128_UPLOAD_TEX1) ? "tex1, " : "",
- (flags & R128_UPLOAD_MASKS) ? "masks, " : "",
- (flags & R128_UPLOAD_WINDOW) ? "window, " : "",
- (flags & R128_UPLOAD_CLIPRECTS) ? "cliprects, " : "",
- (flags & R128_REQUIRE_QUIESCENCE) ? "quiescence, " : "" );
+ DRM_INFO("%s: (0x%x) %s%s%s%s%s%s%s%s%s\n",
+ msg,
+ flags,
+ (flags & R128_UPLOAD_CORE) ? "core, " : "",
+ (flags & R128_UPLOAD_CONTEXT) ? "context, " : "",
+ (flags & R128_UPLOAD_SETUP) ? "setup, " : "",
+ (flags & R128_UPLOAD_TEX0) ? "tex0, " : "",
+ (flags & R128_UPLOAD_TEX1) ? "tex1, " : "",
+ (flags & R128_UPLOAD_MASKS) ? "masks, " : "",
+ (flags & R128_UPLOAD_WINDOW) ? "window, " : "",
+ (flags & R128_UPLOAD_CLIPRECTS) ? "cliprects, " : "",
+ (flags & R128_REQUIRE_QUIESCENCE) ? "quiescence, " : "");
}
-static void r128_cce_dispatch_clear( drm_device_t *dev,
- drm_r128_clear_t *clear )
+static void r128_cce_dispatch_clear(drm_device_t * dev,
+ drm_r128_clear_t * clear)
{
drm_r128_private_t *dev_priv = dev->dev_private;
drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
@@ -368,102 +361,103 @@ static void r128_cce_dispatch_clear( drm_device_t *dev,
unsigned int flags = clear->flags;
int i;
RING_LOCALS;
- DRM_DEBUG( "%s\n", __FUNCTION__ );
+ DRM_DEBUG("%s\n", __FUNCTION__);
- if ( dev_priv->page_flipping && dev_priv->current_page == 1 ) {
+ if (dev_priv->page_flipping && dev_priv->current_page == 1) {
unsigned int tmp = flags;
flags &= ~(R128_FRONT | R128_BACK);
- if ( tmp & R128_FRONT ) flags |= R128_BACK;
- if ( tmp & R128_BACK ) flags |= R128_FRONT;
+ if (tmp & R128_FRONT)
+ flags |= R128_BACK;
+ if (tmp & R128_BACK)
+ flags |= R128_FRONT;
}
- for ( i = 0 ; i < nbox ; i++ ) {
+ for (i = 0; i < nbox; i++) {
int x = pbox[i].x1;
int y = pbox[i].y1;
int w = pbox[i].x2 - x;
int h = pbox[i].y2 - y;
- DRM_DEBUG( "dispatch clear %d,%d-%d,%d flags 0x%x\n",
- pbox[i].x1, pbox[i].y1, pbox[i].x2,
- pbox[i].y2, flags );
+ DRM_DEBUG("dispatch clear %d,%d-%d,%d flags 0x%x\n",
+ pbox[i].x1, pbox[i].y1, pbox[i].x2,
+ pbox[i].y2, flags);
- if ( flags & (R128_FRONT | R128_BACK) ) {
- BEGIN_RING( 2 );
+ if (flags & (R128_FRONT | R128_BACK)) {
+ BEGIN_RING(2);
- OUT_RING( CCE_PACKET0( R128_DP_WRITE_MASK, 0 ) );
- OUT_RING( clear->color_mask );
+ OUT_RING(CCE_PACKET0(R128_DP_WRITE_MASK, 0));
+ OUT_RING(clear->color_mask);
ADVANCE_RING();
}
- if ( flags & R128_FRONT ) {
- BEGIN_RING( 6 );
+ if (flags & R128_FRONT) {
+ BEGIN_RING(6);
- OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) );
- OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL |
- R128_GMC_BRUSH_SOLID_COLOR |
- (dev_priv->color_fmt << 8) |
- R128_GMC_SRC_DATATYPE_COLOR |
- R128_ROP3_P |
- R128_GMC_CLR_CMP_CNTL_DIS |
- R128_GMC_AUX_CLIP_DIS );
+ OUT_RING(CCE_PACKET3(R128_CNTL_PAINT_MULTI, 4));
+ OUT_RING(R128_GMC_DST_PITCH_OFFSET_CNTL |
+ R128_GMC_BRUSH_SOLID_COLOR |
+ (dev_priv->color_fmt << 8) |
+ R128_GMC_SRC_DATATYPE_COLOR |
+ R128_ROP3_P |
+ R128_GMC_CLR_CMP_CNTL_DIS |
+ R128_GMC_AUX_CLIP_DIS);
- OUT_RING( dev_priv->front_pitch_offset_c );
- OUT_RING( clear->clear_color );
+ OUT_RING(dev_priv->front_pitch_offset_c);
+ OUT_RING(clear->clear_color);
- OUT_RING( (x << 16) | y );
- OUT_RING( (w << 16) | h );
+ OUT_RING((x << 16) | y);
+ OUT_RING((w << 16) | h);
ADVANCE_RING();
}
- if ( flags & R128_BACK ) {
- BEGIN_RING( 6 );
+ if (flags & R128_BACK) {
+ BEGIN_RING(6);
- OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) );
- OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL |
- R128_GMC_BRUSH_SOLID_COLOR |
- (dev_priv->color_fmt << 8) |
- R128_GMC_SRC_DATATYPE_COLOR |
- R128_ROP3_P |
- R128_GMC_CLR_CMP_CNTL_DIS |
- R128_GMC_AUX_CLIP_DIS );
+ OUT_RING(CCE_PACKET3(R128_CNTL_PAINT_MULTI, 4));
+ OUT_RING(R128_GMC_DST_PITCH_OFFSET_CNTL |
+ R128_GMC_BRUSH_SOLID_COLOR |
+ (dev_priv->color_fmt << 8) |
+ R128_GMC_SRC_DATATYPE_COLOR |
+ R128_ROP3_P |
+ R128_GMC_CLR_CMP_CNTL_DIS |
+ R128_GMC_AUX_CLIP_DIS);
- OUT_RING( dev_priv->back_pitch_offset_c );
- OUT_RING( clear->clear_color );
+ OUT_RING(dev_priv->back_pitch_offset_c);
+ OUT_RING(clear->clear_color);
- OUT_RING( (x << 16) | y );
- OUT_RING( (w << 16) | h );
+ OUT_RING((x << 16) | y);
+ OUT_RING((w << 16) | h);
ADVANCE_RING();
}
- if ( flags & R128_DEPTH ) {
- BEGIN_RING( 6 );
+ if (flags & R128_DEPTH) {
+ BEGIN_RING(6);
- OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) );
- OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL |
- R128_GMC_BRUSH_SOLID_COLOR |
- (dev_priv->depth_fmt << 8) |
- R128_GMC_SRC_DATATYPE_COLOR |
- R128_ROP3_P |
- R128_GMC_CLR_CMP_CNTL_DIS |
- R128_GMC_AUX_CLIP_DIS |
- R128_GMC_WR_MSK_DIS );
+ OUT_RING(CCE_PACKET3(R128_CNTL_PAINT_MULTI, 4));
+ OUT_RING(R128_GMC_DST_PITCH_OFFSET_CNTL |
+ R128_GMC_BRUSH_SOLID_COLOR |
+ (dev_priv->depth_fmt << 8) |
+ R128_GMC_SRC_DATATYPE_COLOR |
+ R128_ROP3_P |
+ R128_GMC_CLR_CMP_CNTL_DIS |
+ R128_GMC_AUX_CLIP_DIS | R128_GMC_WR_MSK_DIS);
- OUT_RING( dev_priv->depth_pitch_offset_c );
- OUT_RING( clear->clear_depth );
+ OUT_RING(dev_priv->depth_pitch_offset_c);
+ OUT_RING(clear->clear_depth);
- OUT_RING( (x << 16) | y );
- OUT_RING( (w << 16) | h );
+ OUT_RING((x << 16) | y);
+ OUT_RING((w << 16) | h);
ADVANCE_RING();
}
}
}
-static void r128_cce_dispatch_swap( drm_device_t *dev )
+static void r128_cce_dispatch_swap(drm_device_t * dev)
{
drm_r128_private_t *dev_priv = dev->dev_private;
drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
@@ -471,48 +465,46 @@ static void r128_cce_dispatch_swap( drm_device_t *dev )
drm_clip_rect_t *pbox = sarea_priv->boxes;
int i;
RING_LOCALS;
- DRM_DEBUG( "%s\n", __FUNCTION__ );
+ DRM_DEBUG("%s\n", __FUNCTION__);
#if R128_PERFORMANCE_BOXES
/* Do some trivial performance monitoring...
*/
- r128_cce_performance_boxes( dev_priv );
+ r128_cce_performance_boxes(dev_priv);
#endif
- for ( i = 0 ; i < nbox ; i++ ) {
+ for (i = 0; i < nbox; i++) {
int x = pbox[i].x1;
int y = pbox[i].y1;
int w = pbox[i].x2 - x;
int h = pbox[i].y2 - y;
- BEGIN_RING( 7 );
+ BEGIN_RING(7);
- OUT_RING( CCE_PACKET3( R128_CNTL_BITBLT_MULTI, 5 ) );
- OUT_RING( R128_GMC_SRC_PITCH_OFFSET_CNTL |
- R128_GMC_DST_PITCH_OFFSET_CNTL |
- R128_GMC_BRUSH_NONE |
- (dev_priv->color_fmt << 8) |
- R128_GMC_SRC_DATATYPE_COLOR |
- R128_ROP3_S |
- R128_DP_SRC_SOURCE_MEMORY |
- R128_GMC_CLR_CMP_CNTL_DIS |
- R128_GMC_AUX_CLIP_DIS |
- R128_GMC_WR_MSK_DIS );
+ OUT_RING(CCE_PACKET3(R128_CNTL_BITBLT_MULTI, 5));
+ OUT_RING(R128_GMC_SRC_PITCH_OFFSET_CNTL |
+ R128_GMC_DST_PITCH_OFFSET_CNTL |
+ R128_GMC_BRUSH_NONE |
+ (dev_priv->color_fmt << 8) |
+ R128_GMC_SRC_DATATYPE_COLOR |
+ R128_ROP3_S |
+ R128_DP_SRC_SOURCE_MEMORY |
+ R128_GMC_CLR_CMP_CNTL_DIS |
+ R128_GMC_AUX_CLIP_DIS | R128_GMC_WR_MSK_DIS);
/* Make this work even if front & back are flipped:
*/
if (dev_priv->current_page == 0) {
- OUT_RING( dev_priv->back_pitch_offset_c );
- OUT_RING( dev_priv->front_pitch_offset_c );
- }
- else {
- OUT_RING( dev_priv->front_pitch_offset_c );
- OUT_RING( dev_priv->back_pitch_offset_c );
+ OUT_RING(dev_priv->back_pitch_offset_c);
+ OUT_RING(dev_priv->front_pitch_offset_c);
+ } else {
+ OUT_RING(dev_priv->front_pitch_offset_c);
+ OUT_RING(dev_priv->back_pitch_offset_c);
}
- OUT_RING( (x << 16) | y );
- OUT_RING( (x << 16) | y );
- OUT_RING( (w << 16) | h );
+ OUT_RING((x << 16) | y);
+ OUT_RING((x << 16) | y);
+ OUT_RING((w << 16) | h);
ADVANCE_RING();
}
@@ -523,38 +515,37 @@ static void r128_cce_dispatch_swap( drm_device_t *dev )
*/
dev_priv->sarea_priv->last_frame++;
- BEGIN_RING( 2 );
+ BEGIN_RING(2);
- OUT_RING( CCE_PACKET0( R128_LAST_FRAME_REG, 0 ) );
- OUT_RING( dev_priv->sarea_priv->last_frame );
+ OUT_RING(CCE_PACKET0(R128_LAST_FRAME_REG, 0));
+ OUT_RING(dev_priv->sarea_priv->last_frame);
ADVANCE_RING();
}
-static void r128_cce_dispatch_flip( drm_device_t *dev )
+static void r128_cce_dispatch_flip(drm_device_t * dev)
{
drm_r128_private_t *dev_priv = dev->dev_private;
RING_LOCALS;
- DRM_DEBUG("%s: page=%d pfCurrentPage=%d\n",
- __FUNCTION__,
- dev_priv->current_page,
- dev_priv->sarea_priv->pfCurrentPage);
+ DRM_DEBUG("%s: page=%d pfCurrentPage=%d\n",
+ __FUNCTION__,
+ dev_priv->current_page, dev_priv->sarea_priv->pfCurrentPage);
#if R128_PERFORMANCE_BOXES
/* Do some trivial performance monitoring...
*/
- r128_cce_performance_boxes( dev_priv );
+ r128_cce_performance_boxes(dev_priv);
#endif
- BEGIN_RING( 4 );
+ BEGIN_RING(4);
R128_WAIT_UNTIL_PAGE_FLIPPED();
- OUT_RING( CCE_PACKET0( R128_CRTC_OFFSET, 0 ) );
+ OUT_RING(CCE_PACKET0(R128_CRTC_OFFSET, 0));
- if ( dev_priv->current_page == 0 ) {
- OUT_RING( dev_priv->back_offset );
+ if (dev_priv->current_page == 0) {
+ OUT_RING(dev_priv->back_offset);
} else {
- OUT_RING( dev_priv->front_offset );
+ OUT_RING(dev_priv->front_offset);
}
ADVANCE_RING();
@@ -565,18 +556,17 @@ static void r128_cce_dispatch_flip( drm_device_t *dev )
*/
dev_priv->sarea_priv->last_frame++;
dev_priv->sarea_priv->pfCurrentPage = dev_priv->current_page =
- 1 - dev_priv->current_page;
+ 1 - dev_priv->current_page;
- BEGIN_RING( 2 );
+ BEGIN_RING(2);
- OUT_RING( CCE_PACKET0( R128_LAST_FRAME_REG, 0 ) );
- OUT_RING( dev_priv->sarea_priv->last_frame );
+ OUT_RING(CCE_PACKET0(R128_LAST_FRAME_REG, 0));
+ OUT_RING(dev_priv->sarea_priv->last_frame);
ADVANCE_RING();
}
-static void r128_cce_dispatch_vertex( drm_device_t *dev,
- drm_buf_t *buf )
+static void r128_cce_dispatch_vertex(drm_device_t * dev, drm_buf_t * buf)
{
drm_r128_private_t *dev_priv = dev->dev_private;
drm_r128_buf_priv_t *buf_priv = buf->dev_private;
@@ -587,50 +577,50 @@ static void r128_cce_dispatch_vertex( drm_device_t *dev,
int prim = buf_priv->prim;
int i = 0;
RING_LOCALS;
- DRM_DEBUG( "buf=%d nbox=%d\n", buf->idx, sarea_priv->nbox );
+ DRM_DEBUG("buf=%d nbox=%d\n", buf->idx, sarea_priv->nbox);
- if ( 0 )
- r128_print_dirty( "dispatch_vertex", sarea_priv->dirty );
+ if (0)
+ r128_print_dirty("dispatch_vertex", sarea_priv->dirty);
- if ( buf->used ) {
+ if (buf->used) {
buf_priv->dispatched = 1;
- if ( sarea_priv->dirty & ~R128_UPLOAD_CLIPRECTS ) {
- r128_emit_state( dev_priv );
+ if (sarea_priv->dirty & ~R128_UPLOAD_CLIPRECTS) {
+ r128_emit_state(dev_priv);
}
do {
/* Emit the next set of up to three cliprects */
- if ( i < sarea_priv->nbox ) {
- r128_emit_clip_rects( dev_priv,
- &sarea_priv->boxes[i],
- sarea_priv->nbox - i );
+ if (i < sarea_priv->nbox) {
+ r128_emit_clip_rects(dev_priv,
+ &sarea_priv->boxes[i],
+ sarea_priv->nbox - i);
}
/* Emit the vertex buffer rendering commands */
- BEGIN_RING( 5 );
+ BEGIN_RING(5);
- OUT_RING( CCE_PACKET3( R128_3D_RNDR_GEN_INDX_PRIM, 3 ) );
- OUT_RING( offset );
- OUT_RING( size );
- OUT_RING( format );
- OUT_RING( prim | R128_CCE_VC_CNTL_PRIM_WALK_LIST |
- (size << R128_CCE_VC_CNTL_NUM_SHIFT) );
+ OUT_RING(CCE_PACKET3(R128_3D_RNDR_GEN_INDX_PRIM, 3));
+ OUT_RING(offset);
+ OUT_RING(size);
+ OUT_RING(format);
+ OUT_RING(prim | R128_CCE_VC_CNTL_PRIM_WALK_LIST |
+ (size << R128_CCE_VC_CNTL_NUM_SHIFT));
ADVANCE_RING();
i += 3;
- } while ( i < sarea_priv->nbox );
+ } while (i < sarea_priv->nbox);
}
- if ( buf_priv->discard ) {
+ if (buf_priv->discard) {
buf_priv->age = dev_priv->sarea_priv->last_dispatch;
/* Emit the vertex buffer age */
- BEGIN_RING( 2 );
+ BEGIN_RING(2);
- OUT_RING( CCE_PACKET0( R128_LAST_DISPATCH_REG, 0 ) );
- OUT_RING( buf_priv->age );
+ OUT_RING(CCE_PACKET0(R128_LAST_DISPATCH_REG, 0));
+ OUT_RING(buf_priv->age);
ADVANCE_RING();
@@ -646,17 +636,15 @@ static void r128_cce_dispatch_vertex( drm_device_t *dev,
sarea_priv->nbox = 0;
}
-static void r128_cce_dispatch_indirect( drm_device_t *dev,
- drm_buf_t *buf,
- int start, int end )
+static void r128_cce_dispatch_indirect(drm_device_t * dev,
+ drm_buf_t * buf, int start, int end)
{
drm_r128_private_t *dev_priv = dev->dev_private;
drm_r128_buf_priv_t *buf_priv = buf->dev_private;
RING_LOCALS;
- DRM_DEBUG( "indirect: buf=%d s=0x%x e=0x%x\n",
- buf->idx, start, end );
+ DRM_DEBUG("indirect: buf=%d s=0x%x e=0x%x\n", buf->idx, start, end);
- if ( start != end ) {
+ if (start != end) {
int offset = buf->bus_address + start;
int dwords = (end - start + 3) / sizeof(u32);
@@ -664,33 +652,33 @@ static void r128_cce_dispatch_indirect( drm_device_t *dev,
* dwords, so if we've been given an odd number we must
* pad the data with a Type-2 CCE packet.
*/
- if ( dwords & 1 ) {
+ if (dwords & 1) {
u32 *data = (u32 *)
- ((char *)dev->agp_buffer_map->handle
- + buf->offset + start);
- data[dwords++] = cpu_to_le32( R128_CCE_PACKET2 );
+ ((char *)dev->agp_buffer_map->handle
+ + buf->offset + start);
+ data[dwords++] = cpu_to_le32(R128_CCE_PACKET2);
}
buf_priv->dispatched = 1;
/* Fire off the indirect buffer */
- BEGIN_RING( 3 );
+ BEGIN_RING(3);
- OUT_RING( CCE_PACKET0( R128_PM4_IW_INDOFF, 1 ) );
- OUT_RING( offset );
- OUT_RING( dwords );
+ OUT_RING(CCE_PACKET0(R128_PM4_IW_INDOFF, 1));
+ OUT_RING(offset);
+ OUT_RING(dwords);
ADVANCE_RING();
}
- if ( buf_priv->discard ) {
+ if (buf_priv->discard) {
buf_priv->age = dev_priv->sarea_priv->last_dispatch;
/* Emit the indirect buffer age */
- BEGIN_RING( 2 );
+ BEGIN_RING(2);
- OUT_RING( CCE_PACKET0( R128_LAST_DISPATCH_REG, 0 ) );
- OUT_RING( buf_priv->age );
+ OUT_RING(CCE_PACKET0(R128_LAST_DISPATCH_REG, 0));
+ OUT_RING(buf_priv->age);
ADVANCE_RING();
@@ -703,10 +691,9 @@ static void r128_cce_dispatch_indirect( drm_device_t *dev,
dev_priv->sarea_priv->last_dispatch++;
}
-static void r128_cce_dispatch_indices( drm_device_t *dev,
- drm_buf_t *buf,
- int start, int end,
- int count )
+static void r128_cce_dispatch_indices(drm_device_t * dev,
+ drm_buf_t * buf,
+ int start, int end, int count)
{
drm_r128_private_t *dev_priv = dev->dev_private;
drm_r128_buf_priv_t *buf_priv = buf->dev_private;
@@ -718,62 +705,62 @@ static void r128_cce_dispatch_indices( drm_device_t *dev,
int dwords;
int i = 0;
RING_LOCALS;
- DRM_DEBUG( "indices: s=%d e=%d c=%d\n", start, end, count );
+ DRM_DEBUG("indices: s=%d e=%d c=%d\n", start, end, count);
- if ( 0 )
- r128_print_dirty( "dispatch_indices", sarea_priv->dirty );
+ if (0)
+ r128_print_dirty("dispatch_indices", sarea_priv->dirty);
- if ( start != end ) {
+ if (start != end) {
buf_priv->dispatched = 1;
- if ( sarea_priv->dirty & ~R128_UPLOAD_CLIPRECTS ) {
- r128_emit_state( dev_priv );
+ if (sarea_priv->dirty & ~R128_UPLOAD_CLIPRECTS) {
+ r128_emit_state(dev_priv);
}
dwords = (end - start + 3) / sizeof(u32);
- data = (u32 *)((char *)dev->agp_buffer_map->handle
- + buf->offset + start);
+ data = (u32 *) ((char *)dev->agp_buffer_map->handle
+ + buf->offset + start);
- data[0] = cpu_to_le32( CCE_PACKET3( R128_3D_RNDR_GEN_INDX_PRIM,
- dwords-2 ) );
+ data[0] = cpu_to_le32(CCE_PACKET3(R128_3D_RNDR_GEN_INDX_PRIM,
+ dwords - 2));
- data[1] = cpu_to_le32( offset );
- data[2] = cpu_to_le32( R128_MAX_VB_VERTS );
- data[3] = cpu_to_le32( format );
- data[4] = cpu_to_le32( (prim | R128_CCE_VC_CNTL_PRIM_WALK_IND |
- (count << 16)) );
+ data[1] = cpu_to_le32(offset);
+ data[2] = cpu_to_le32(R128_MAX_VB_VERTS);
+ data[3] = cpu_to_le32(format);
+ data[4] = cpu_to_le32((prim | R128_CCE_VC_CNTL_PRIM_WALK_IND |
+ (count << 16)));
- if ( count & 0x1 ) {
+ if (count & 0x1) {
#ifdef __LITTLE_ENDIAN
- data[dwords-1] &= 0x0000ffff;
+ data[dwords - 1] &= 0x0000ffff;
#else
- data[dwords-1] &= 0xffff0000;
+ data[dwords - 1] &= 0xffff0000;
#endif
}
do {
/* Emit the next set of up to three cliprects */
- if ( i < sarea_priv->nbox ) {
- r128_emit_clip_rects( dev_priv,
- &sarea_priv->boxes[i],
- sarea_priv->nbox - i );
+ if (i < sarea_priv->nbox) {
+ r128_emit_clip_rects(dev_priv,
+ &sarea_priv->boxes[i],
+ sarea_priv->nbox - i);
}
- r128_cce_dispatch_indirect( dev, buf, start, end );
+ r128_cce_dispatch_indirect(dev, buf, start, end);
i += 3;
- } while ( i < sarea_priv->nbox );
+ } while (i < sarea_priv->nbox);
}
- if ( buf_priv->discard ) {
+ if (buf_priv->discard) {
buf_priv->age = dev_priv->sarea_priv->last_dispatch;
/* Emit the vertex buffer age */
- BEGIN_RING( 2 );
+ BEGIN_RING(2);
- OUT_RING( CCE_PACKET0( R128_LAST_DISPATCH_REG, 0 ) );
- OUT_RING( buf_priv->age );
+ OUT_RING(CCE_PACKET0(R128_LAST_DISPATCH_REG, 0));
+ OUT_RING(buf_priv->age);
ADVANCE_RING();
@@ -788,9 +775,8 @@ static void r128_cce_dispatch_indices( drm_device_t *dev,
sarea_priv->nbox = 0;
}
-static int r128_cce_dispatch_blit( DRMFILE filp,
- drm_device_t *dev,
- drm_r128_blit_t *blit )
+static int r128_cce_dispatch_blit(DRMFILE filp,
+ drm_device_t * dev, drm_r128_blit_t * blit)
{
drm_r128_private_t *dev_priv = dev->dev_private;
drm_device_dma_t *dma = dev->dma;
@@ -799,13 +785,13 @@ static int r128_cce_dispatch_blit( DRMFILE filp,
u32 *data;
int dword_shift, dwords;
RING_LOCALS;
- DRM_DEBUG( "\n" );
+ DRM_DEBUG("\n");
/* The compiler won't optimize away a division by a variable,
* even if the only legal values are powers of two. Thus, we'll
* use a shift instead.
*/
- switch ( blit->format ) {
+ switch (blit->format) {
case R128_DATATYPE_ARGB8888:
dword_shift = 0;
break;
@@ -821,7 +807,7 @@ static int r128_cce_dispatch_blit( DRMFILE filp,
dword_shift = 2;
break;
default:
- DRM_ERROR( "invalid blit format %d\n", blit->format );
+ DRM_ERROR("invalid blit format %d\n", blit->format);
return DRM_ERR(EINVAL);
}
@@ -830,10 +816,10 @@ static int r128_cce_dispatch_blit( DRMFILE filp,
* data from the host data blit, otherwise part of the texture
* image may be corrupted.
*/
- BEGIN_RING( 2 );
+ BEGIN_RING(2);
- OUT_RING( CCE_PACKET0( R128_PC_GUI_CTLSTAT, 0 ) );
- OUT_RING( R128_PC_RI_GUI | R128_PC_FLUSH_GUI );
+ OUT_RING(CCE_PACKET0(R128_PC_GUI_CTLSTAT, 0));
+ OUT_RING(R128_PC_RI_GUI | R128_PC_FLUSH_GUI);
ADVANCE_RING();
@@ -842,13 +828,13 @@ static int r128_cce_dispatch_blit( DRMFILE filp,
buf = dma->buflist[blit->idx];
buf_priv = buf->dev_private;
- if ( buf->filp != filp ) {
- DRM_ERROR( "process %d using buffer owned by %p\n",
- DRM_CURRENTPID, buf->filp );
+ if (buf->filp != filp) {
+ DRM_ERROR("process %d using buffer owned by %p\n",
+ DRM_CURRENTPID, buf->filp);
return DRM_ERR(EINVAL);
}
- if ( buf->pending ) {
- DRM_ERROR( "sending pending buffer %d\n", blit->idx );
+ if (buf->pending) {
+ DRM_ERROR("sending pending buffer %d\n", blit->idx);
return DRM_ERR(EINVAL);
}
@@ -856,45 +842,43 @@ static int r128_cce_dispatch_blit( DRMFILE filp,
dwords = (blit->width * blit->height) >> dword_shift;
- data = (u32 *)((char *)dev->agp_buffer_map->handle + buf->offset);
-
- data[0] = cpu_to_le32( CCE_PACKET3( R128_CNTL_HOSTDATA_BLT, dwords + 6 ) );
- data[1] = cpu_to_le32( (R128_GMC_DST_PITCH_OFFSET_CNTL |
- R128_GMC_BRUSH_NONE |
- (blit->format << 8) |
- R128_GMC_SRC_DATATYPE_COLOR |
- R128_ROP3_S |
- R128_DP_SRC_SOURCE_HOST_DATA |
- R128_GMC_CLR_CMP_CNTL_DIS |
- R128_GMC_AUX_CLIP_DIS |
- R128_GMC_WR_MSK_DIS) );
-
- data[2] = cpu_to_le32( (blit->pitch << 21) | (blit->offset >> 5) );
- data[3] = cpu_to_le32( 0xffffffff );
- data[4] = cpu_to_le32( 0xffffffff );
- data[5] = cpu_to_le32( (blit->y << 16) | blit->x );
- data[6] = cpu_to_le32( (blit->height << 16) | blit->width );
- data[7] = cpu_to_le32( dwords );
+ data = (u32 *) ((char *)dev->agp_buffer_map->handle + buf->offset);
+
+ data[0] = cpu_to_le32(CCE_PACKET3(R128_CNTL_HOSTDATA_BLT, dwords + 6));
+ data[1] = cpu_to_le32((R128_GMC_DST_PITCH_OFFSET_CNTL |
+ R128_GMC_BRUSH_NONE |
+ (blit->format << 8) |
+ R128_GMC_SRC_DATATYPE_COLOR |
+ R128_ROP3_S |
+ R128_DP_SRC_SOURCE_HOST_DATA |
+ R128_GMC_CLR_CMP_CNTL_DIS |
+ R128_GMC_AUX_CLIP_DIS | R128_GMC_WR_MSK_DIS));
+
+ data[2] = cpu_to_le32((blit->pitch << 21) | (blit->offset >> 5));
+ data[3] = cpu_to_le32(0xffffffff);
+ data[4] = cpu_to_le32(0xffffffff);
+ data[5] = cpu_to_le32((blit->y << 16) | blit->x);
+ data[6] = cpu_to_le32((blit->height << 16) | blit->width);
+ data[7] = cpu_to_le32(dwords);
buf->used = (dwords + 8) * sizeof(u32);
- r128_cce_dispatch_indirect( dev, buf, 0, buf->used );
+ r128_cce_dispatch_indirect(dev, buf, 0, buf->used);
/* Flush the pixel cache after the blit completes. This ensures
* the texture data is written out to memory before rendering
* continues.
*/
- BEGIN_RING( 2 );
+ BEGIN_RING(2);
- OUT_RING( CCE_PACKET0( R128_PC_GUI_CTLSTAT, 0 ) );
- OUT_RING( R128_PC_FLUSH_GUI );
+ OUT_RING(CCE_PACKET0(R128_PC_GUI_CTLSTAT, 0));
+ OUT_RING(R128_PC_FLUSH_GUI);
ADVANCE_RING();
return 0;
}
-
/* ================================================================
* Tiled depth buffer management
*
@@ -902,8 +886,8 @@ static int r128_cce_dispatch_blit( DRMFILE filp,
* have hardware stencil support.
*/
-static int r128_cce_dispatch_write_span( drm_device_t *dev,
- drm_r128_depth_t *depth )
+static int r128_cce_dispatch_write_span(drm_device_t * dev,
+ drm_r128_depth_t * depth)
{
drm_r128_private_t *dev_priv = dev->dev_private;
int count, x, y;
@@ -911,95 +895,95 @@ static int r128_cce_dispatch_write_span( drm_device_t *dev,
u8 *mask;
int i, buffer_size, mask_size;
RING_LOCALS;
- DRM_DEBUG( "\n" );
+ DRM_DEBUG("\n");
count = depth->n;
if (count > 4096 || count <= 0)
return DRM_ERR(EMSGSIZE);
- if ( DRM_COPY_FROM_USER( &x, depth->x, sizeof(x) ) ) {
+ if (DRM_COPY_FROM_USER(&x, depth->x, sizeof(x))) {
return DRM_ERR(EFAULT);
}
- if ( DRM_COPY_FROM_USER( &y, depth->y, sizeof(y) ) ) {
+ if (DRM_COPY_FROM_USER(&y, depth->y, sizeof(y))) {
return DRM_ERR(EFAULT);
}
buffer_size = depth->n * sizeof(u32);
- buffer = drm_alloc( buffer_size, DRM_MEM_BUFS );
- if ( buffer == NULL )
+ buffer = drm_alloc(buffer_size, DRM_MEM_BUFS);
+ if (buffer == NULL)
return DRM_ERR(ENOMEM);
- if ( DRM_COPY_FROM_USER( buffer, depth->buffer, buffer_size ) ) {
- drm_free( buffer, buffer_size, DRM_MEM_BUFS);
+ if (DRM_COPY_FROM_USER(buffer, depth->buffer, buffer_size)) {
+ drm_free(buffer, buffer_size, DRM_MEM_BUFS);
return DRM_ERR(EFAULT);
}
mask_size = depth->n * sizeof(u8);
- if ( depth->mask ) {
- mask = drm_alloc( mask_size, DRM_MEM_BUFS );
- if ( mask == NULL ) {
- drm_free( buffer, buffer_size, DRM_MEM_BUFS );
+ if (depth->mask) {
+ mask = drm_alloc(mask_size, DRM_MEM_BUFS);
+ if (mask == NULL) {
+ drm_free(buffer, buffer_size, DRM_MEM_BUFS);
return DRM_ERR(ENOMEM);
}
- if ( DRM_COPY_FROM_USER( mask, depth->mask, mask_size ) ) {
- drm_free( buffer, buffer_size, DRM_MEM_BUFS );
- drm_free( mask, mask_size, DRM_MEM_BUFS );
+ if (DRM_COPY_FROM_USER(mask, depth->mask, mask_size)) {
+ drm_free(buffer, buffer_size, DRM_MEM_BUFS);
+ drm_free(mask, mask_size, DRM_MEM_BUFS);
return DRM_ERR(EFAULT);
}
- for ( i = 0 ; i < count ; i++, x++ ) {
- if ( mask[i] ) {
- BEGIN_RING( 6 );
+ for (i = 0; i < count; i++, x++) {
+ if (mask[i]) {
+ BEGIN_RING(6);
- OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) );
- OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL |
- R128_GMC_BRUSH_SOLID_COLOR |
- (dev_priv->depth_fmt << 8) |
- R128_GMC_SRC_DATATYPE_COLOR |
- R128_ROP3_P |
- R128_GMC_CLR_CMP_CNTL_DIS |
- R128_GMC_WR_MSK_DIS );
+ OUT_RING(CCE_PACKET3(R128_CNTL_PAINT_MULTI, 4));
+ OUT_RING(R128_GMC_DST_PITCH_OFFSET_CNTL |
+ R128_GMC_BRUSH_SOLID_COLOR |
+ (dev_priv->depth_fmt << 8) |
+ R128_GMC_SRC_DATATYPE_COLOR |
+ R128_ROP3_P |
+ R128_GMC_CLR_CMP_CNTL_DIS |
+ R128_GMC_WR_MSK_DIS);
- OUT_RING( dev_priv->depth_pitch_offset_c );
- OUT_RING( buffer[i] );
+ OUT_RING(dev_priv->depth_pitch_offset_c);
+ OUT_RING(buffer[i]);
- OUT_RING( (x << 16) | y );
- OUT_RING( (1 << 16) | 1 );
+ OUT_RING((x << 16) | y);
+ OUT_RING((1 << 16) | 1);
ADVANCE_RING();
}
}
- drm_free( mask, mask_size, DRM_MEM_BUFS );
+ drm_free(mask, mask_size, DRM_MEM_BUFS);
} else {
- for ( i = 0 ; i < count ; i++, x++ ) {
- BEGIN_RING( 6 );
+ for (i = 0; i < count; i++, x++) {
+ BEGIN_RING(6);
- OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) );
- OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL |
- R128_GMC_BRUSH_SOLID_COLOR |
- (dev_priv->depth_fmt << 8) |
- R128_GMC_SRC_DATATYPE_COLOR |
- R128_ROP3_P |
- R128_GMC_CLR_CMP_CNTL_DIS |
- R128_GMC_WR_MSK_DIS );
+ OUT_RING(CCE_PACKET3(R128_CNTL_PAINT_MULTI, 4));
+ OUT_RING(R128_GMC_DST_PITCH_OFFSET_CNTL |
+ R128_GMC_BRUSH_SOLID_COLOR |
+ (dev_priv->depth_fmt << 8) |
+ R128_GMC_SRC_DATATYPE_COLOR |
+ R128_ROP3_P |
+ R128_GMC_CLR_CMP_CNTL_DIS |
+ R128_GMC_WR_MSK_DIS);
- OUT_RING( dev_priv->depth_pitch_offset_c );
- OUT_RING( buffer[i] );
+ OUT_RING(dev_priv->depth_pitch_offset_c);
+ OUT_RING(buffer[i]);
- OUT_RING( (x << 16) | y );
- OUT_RING( (1 << 16) | 1 );
+ OUT_RING((x << 16) | y);
+ OUT_RING((1 << 16) | 1);
ADVANCE_RING();
}
}
- drm_free( buffer, buffer_size, DRM_MEM_BUFS );
+ drm_free(buffer, buffer_size, DRM_MEM_BUFS);
return 0;
}
-static int r128_cce_dispatch_write_pixels( drm_device_t *dev,
- drm_r128_depth_t *depth )
+static int r128_cce_dispatch_write_pixels(drm_device_t * dev,
+ drm_r128_depth_t * depth)
{
drm_r128_private_t *dev_priv = dev->dev_private;
int count, *x, *y;
@@ -1007,7 +991,7 @@ static int r128_cce_dispatch_write_pixels( drm_device_t *dev,
u8 *mask;
int i, xbuf_size, ybuf_size, buffer_size, mask_size;
RING_LOCALS;
- DRM_DEBUG( "\n" );
+ DRM_DEBUG("\n");
count = depth->n;
if (count > 4096 || count <= 0)
@@ -1015,270 +999,266 @@ static int r128_cce_dispatch_write_pixels( drm_device_t *dev,
xbuf_size = count * sizeof(*x);
ybuf_size = count * sizeof(*y);
- x = drm_alloc( xbuf_size, DRM_MEM_BUFS );
- if ( x == NULL ) {
+ x = drm_alloc(xbuf_size, DRM_MEM_BUFS);
+ if (x == NULL) {
return DRM_ERR(ENOMEM);
}
- y = drm_alloc( ybuf_size, DRM_MEM_BUFS );
- if ( y == NULL ) {
- drm_free( x, xbuf_size, DRM_MEM_BUFS );
+ y = drm_alloc(ybuf_size, DRM_MEM_BUFS);
+ if (y == NULL) {
+ drm_free(x, xbuf_size, DRM_MEM_BUFS);
return DRM_ERR(ENOMEM);
}
- if ( DRM_COPY_FROM_USER( x, depth->x, xbuf_size ) ) {
- drm_free( x, xbuf_size, DRM_MEM_BUFS );
- drm_free( y, ybuf_size, DRM_MEM_BUFS );
+ if (DRM_COPY_FROM_USER(x, depth->x, xbuf_size)) {
+ drm_free(x, xbuf_size, DRM_MEM_BUFS);
+ drm_free(y, ybuf_size, DRM_MEM_BUFS);
return DRM_ERR(EFAULT);
}
- if ( DRM_COPY_FROM_USER( y, depth->y, xbuf_size ) ) {
- drm_free( x, xbuf_size, DRM_MEM_BUFS );
- drm_free( y, ybuf_size, DRM_MEM_BUFS );
+ if (DRM_COPY_FROM_USER(y, depth->y, xbuf_size)) {
+ drm_free(x, xbuf_size, DRM_MEM_BUFS);
+ drm_free(y, ybuf_size, DRM_MEM_BUFS);
return DRM_ERR(EFAULT);
}
buffer_size = depth->n * sizeof(u32);
- buffer = drm_alloc( buffer_size, DRM_MEM_BUFS );
- if ( buffer == NULL ) {
- drm_free( x, xbuf_size, DRM_MEM_BUFS );
- drm_free( y, ybuf_size, DRM_MEM_BUFS );
+ buffer = drm_alloc(buffer_size, DRM_MEM_BUFS);
+ if (buffer == NULL) {
+ drm_free(x, xbuf_size, DRM_MEM_BUFS);
+ drm_free(y, ybuf_size, DRM_MEM_BUFS);
return DRM_ERR(ENOMEM);
}
- if ( DRM_COPY_FROM_USER( buffer, depth->buffer, buffer_size ) ) {
- drm_free( x, xbuf_size, DRM_MEM_BUFS );
- drm_free( y, ybuf_size, DRM_MEM_BUFS );
- drm_free( buffer, buffer_size, DRM_MEM_BUFS );
+ if (DRM_COPY_FROM_USER(buffer, depth->buffer, buffer_size)) {
+ drm_free(x, xbuf_size, DRM_MEM_BUFS);
+ drm_free(y, ybuf_size, DRM_MEM_BUFS);
+ drm_free(buffer, buffer_size, DRM_MEM_BUFS);
return DRM_ERR(EFAULT);
}
- if ( depth->mask ) {
+ if (depth->mask) {
mask_size = depth->n * sizeof(u8);
- mask = drm_alloc( mask_size, DRM_MEM_BUFS );
- if ( mask == NULL ) {
- drm_free( x, xbuf_size, DRM_MEM_BUFS );
- drm_free( y, ybuf_size, DRM_MEM_BUFS );
- drm_free( buffer, buffer_size, DRM_MEM_BUFS );
+ mask = drm_alloc(mask_size, DRM_MEM_BUFS);
+ if (mask == NULL) {
+ drm_free(x, xbuf_size, DRM_MEM_BUFS);
+ drm_free(y, ybuf_size, DRM_MEM_BUFS);
+ drm_free(buffer, buffer_size, DRM_MEM_BUFS);
return DRM_ERR(ENOMEM);
}
- if ( DRM_COPY_FROM_USER( mask, depth->mask, mask_size ) ) {
- drm_free( x, xbuf_size, DRM_MEM_BUFS );
- drm_free( y, ybuf_size, DRM_MEM_BUFS );
- drm_free( buffer, buffer_size, DRM_MEM_BUFS );
- drm_free( mask, mask_size, DRM_MEM_BUFS );
+ if (DRM_COPY_FROM_USER(mask, depth->mask, mask_size)) {
+ drm_free(x, xbuf_size, DRM_MEM_BUFS);
+ drm_free(y, ybuf_size, DRM_MEM_BUFS);
+ drm_free(buffer, buffer_size, DRM_MEM_BUFS);
+ drm_free(mask, mask_size, DRM_MEM_BUFS);
return DRM_ERR(EFAULT);
}
- for ( i = 0 ; i < count ; i++ ) {
- if ( mask[i] ) {
- BEGIN_RING( 6 );
+ for (i = 0; i < count; i++) {
+ if (mask[i]) {
+ BEGIN_RING(6);
- OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) );
- OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL |
- R128_GMC_BRUSH_SOLID_COLOR |
- (dev_priv->depth_fmt << 8) |
- R128_GMC_SRC_DATATYPE_COLOR |
- R128_ROP3_P |
- R128_GMC_CLR_CMP_CNTL_DIS |
- R128_GMC_WR_MSK_DIS );
+ OUT_RING(CCE_PACKET3(R128_CNTL_PAINT_MULTI, 4));
+ OUT_RING(R128_GMC_DST_PITCH_OFFSET_CNTL |
+ R128_GMC_BRUSH_SOLID_COLOR |
+ (dev_priv->depth_fmt << 8) |
+ R128_GMC_SRC_DATATYPE_COLOR |
+ R128_ROP3_P |
+ R128_GMC_CLR_CMP_CNTL_DIS |
+ R128_GMC_WR_MSK_DIS);
- OUT_RING( dev_priv->depth_pitch_offset_c );
- OUT_RING( buffer[i] );
+ OUT_RING(dev_priv->depth_pitch_offset_c);
+ OUT_RING(buffer[i]);
- OUT_RING( (x[i] << 16) | y[i] );
- OUT_RING( (1 << 16) | 1 );
+ OUT_RING((x[i] << 16) | y[i]);
+ OUT_RING((1 << 16) | 1);
ADVANCE_RING();
}
}
- drm_free( mask, mask_size, DRM_MEM_BUFS );
+ drm_free(mask, mask_size, DRM_MEM_BUFS);
} else {
- for ( i = 0 ; i < count ; i++ ) {
- BEGIN_RING( 6 );
+ for (i = 0; i < count; i++) {
+ BEGIN_RING(6);
- OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) );
- OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL |
- R128_GMC_BRUSH_SOLID_COLOR |
- (dev_priv->depth_fmt << 8) |
- R128_GMC_SRC_DATATYPE_COLOR |
- R128_ROP3_P |
- R128_GMC_CLR_CMP_CNTL_DIS |
- R128_GMC_WR_MSK_DIS );
+ OUT_RING(CCE_PACKET3(R128_CNTL_PAINT_MULTI, 4));
+ OUT_RING(R128_GMC_DST_PITCH_OFFSET_CNTL |
+ R128_GMC_BRUSH_SOLID_COLOR |
+ (dev_priv->depth_fmt << 8) |
+ R128_GMC_SRC_DATATYPE_COLOR |
+ R128_ROP3_P |
+ R128_GMC_CLR_CMP_CNTL_DIS |
+ R128_GMC_WR_MSK_DIS);
- OUT_RING( dev_priv->depth_pitch_offset_c );
- OUT_RING( buffer[i] );
+ OUT_RING(dev_priv->depth_pitch_offset_c);
+ OUT_RING(buffer[i]);
- OUT_RING( (x[i] << 16) | y[i] );
- OUT_RING( (1 << 16) | 1 );
+ OUT_RING((x[i] << 16) | y[i]);
+ OUT_RING((1 << 16) | 1);
ADVANCE_RING();
}
}
- drm_free( x, xbuf_size, DRM_MEM_BUFS );
- drm_free( y, ybuf_size, DRM_MEM_BUFS );
- drm_free( buffer, buffer_size, DRM_MEM_BUFS );
+ drm_free(x, xbuf_size, DRM_MEM_BUFS);
+ drm_free(y, ybuf_size, DRM_MEM_BUFS);
+ drm_free(buffer, buffer_size, DRM_MEM_BUFS);
return 0;
}
-static int r128_cce_dispatch_read_span( drm_device_t *dev,
- drm_r128_depth_t *depth )
+static int r128_cce_dispatch_read_span(drm_device_t * dev,
+ drm_r128_depth_t * depth)
{
drm_r128_private_t *dev_priv = dev->dev_private;
int count, x, y;
RING_LOCALS;
- DRM_DEBUG( "\n" );
+ DRM_DEBUG("\n");
count = depth->n;
if (count > 4096 || count <= 0)
return DRM_ERR(EMSGSIZE);
- if ( DRM_COPY_FROM_USER( &x, depth->x, sizeof(x) ) ) {
+ if (DRM_COPY_FROM_USER(&x, depth->x, sizeof(x))) {
return DRM_ERR(EFAULT);
}
- if ( DRM_COPY_FROM_USER( &y, depth->y, sizeof(y) ) ) {
+ if (DRM_COPY_FROM_USER(&y, depth->y, sizeof(y))) {
return DRM_ERR(EFAULT);
}
- BEGIN_RING( 7 );
+ BEGIN_RING(7);
- OUT_RING( CCE_PACKET3( R128_CNTL_BITBLT_MULTI, 5 ) );
- OUT_RING( R128_GMC_SRC_PITCH_OFFSET_CNTL |
- R128_GMC_DST_PITCH_OFFSET_CNTL |
- R128_GMC_BRUSH_NONE |
- (dev_priv->depth_fmt << 8) |
- R128_GMC_SRC_DATATYPE_COLOR |
- R128_ROP3_S |
- R128_DP_SRC_SOURCE_MEMORY |
- R128_GMC_CLR_CMP_CNTL_DIS |
- R128_GMC_WR_MSK_DIS );
+ OUT_RING(CCE_PACKET3(R128_CNTL_BITBLT_MULTI, 5));
+ OUT_RING(R128_GMC_SRC_PITCH_OFFSET_CNTL |
+ R128_GMC_DST_PITCH_OFFSET_CNTL |
+ R128_GMC_BRUSH_NONE |
+ (dev_priv->depth_fmt << 8) |
+ R128_GMC_SRC_DATATYPE_COLOR |
+ R128_ROP3_S |
+ R128_DP_SRC_SOURCE_MEMORY |
+ R128_GMC_CLR_CMP_CNTL_DIS | R128_GMC_WR_MSK_DIS);
- OUT_RING( dev_priv->depth_pitch_offset_c );
- OUT_RING( dev_priv->span_pitch_offset_c );
+ OUT_RING(dev_priv->depth_pitch_offset_c);
+ OUT_RING(dev_priv->span_pitch_offset_c);
- OUT_RING( (x << 16) | y );
- OUT_RING( (0 << 16) | 0 );
- OUT_RING( (count << 16) | 1 );
+ OUT_RING((x << 16) | y);
+ OUT_RING((0 << 16) | 0);
+ OUT_RING((count << 16) | 1);
ADVANCE_RING();
return 0;
}
-static int r128_cce_dispatch_read_pixels( drm_device_t *dev,
- drm_r128_depth_t *depth )
+static int r128_cce_dispatch_read_pixels(drm_device_t * dev,
+ drm_r128_depth_t * depth)
{
drm_r128_private_t *dev_priv = dev->dev_private;
int count, *x, *y;
int i, xbuf_size, ybuf_size;
RING_LOCALS;
- DRM_DEBUG( "%s\n", __FUNCTION__ );
+ DRM_DEBUG("%s\n", __FUNCTION__);
count = depth->n;
if (count > 4096 || count <= 0)
return DRM_ERR(EMSGSIZE);
- if ( count > dev_priv->depth_pitch ) {
+ if (count > dev_priv->depth_pitch) {
count = dev_priv->depth_pitch;
}
xbuf_size = count * sizeof(*x);
ybuf_size = count * sizeof(*y);
- x = drm_alloc( xbuf_size, DRM_MEM_BUFS );
- if ( x == NULL ) {
+ x = drm_alloc(xbuf_size, DRM_MEM_BUFS);
+ if (x == NULL) {
return DRM_ERR(ENOMEM);
}
- y = drm_alloc( ybuf_size, DRM_MEM_BUFS );
- if ( y == NULL ) {
- drm_free( x, xbuf_size, DRM_MEM_BUFS );
+ y = drm_alloc(ybuf_size, DRM_MEM_BUFS);
+ if (y == NULL) {
+ drm_free(x, xbuf_size, DRM_MEM_BUFS);
return DRM_ERR(ENOMEM);
}
- if ( DRM_COPY_FROM_USER( x, depth->x, xbuf_size ) ) {
- drm_free( x, xbuf_size, DRM_MEM_BUFS );
- drm_free( y, ybuf_size, DRM_MEM_BUFS );
+ if (DRM_COPY_FROM_USER(x, depth->x, xbuf_size)) {
+ drm_free(x, xbuf_size, DRM_MEM_BUFS);
+ drm_free(y, ybuf_size, DRM_MEM_BUFS);
return DRM_ERR(EFAULT);
}
- if ( DRM_COPY_FROM_USER( y, depth->y, ybuf_size ) ) {
- drm_free( x, xbuf_size, DRM_MEM_BUFS );
- drm_free( y, ybuf_size, DRM_MEM_BUFS );
+ if (DRM_COPY_FROM_USER(y, depth->y, ybuf_size)) {
+ drm_free(x, xbuf_size, DRM_MEM_BUFS);
+ drm_free(y, ybuf_size, DRM_MEM_BUFS);
return DRM_ERR(EFAULT);
}
- for ( i = 0 ; i < count ; i++ ) {
- BEGIN_RING( 7 );
+ for (i = 0; i < count; i++) {
+ BEGIN_RING(7);
- OUT_RING( CCE_PACKET3( R128_CNTL_BITBLT_MULTI, 5 ) );
- OUT_RING( R128_GMC_SRC_PITCH_OFFSET_CNTL |
- R128_GMC_DST_PITCH_OFFSET_CNTL |
- R128_GMC_BRUSH_NONE |
- (dev_priv->depth_fmt << 8) |
- R128_GMC_SRC_DATATYPE_COLOR |
- R128_ROP3_S |
- R128_DP_SRC_SOURCE_MEMORY |
- R128_GMC_CLR_CMP_CNTL_DIS |
- R128_GMC_WR_MSK_DIS );
+ OUT_RING(CCE_PACKET3(R128_CNTL_BITBLT_MULTI, 5));
+ OUT_RING(R128_GMC_SRC_PITCH_OFFSET_CNTL |
+ R128_GMC_DST_PITCH_OFFSET_CNTL |
+ R128_GMC_BRUSH_NONE |
+ (dev_priv->depth_fmt << 8) |
+ R128_GMC_SRC_DATATYPE_COLOR |
+ R128_ROP3_S |
+ R128_DP_SRC_SOURCE_MEMORY |
+ R128_GMC_CLR_CMP_CNTL_DIS | R128_GMC_WR_MSK_DIS);
- OUT_RING( dev_priv->depth_pitch_offset_c );
- OUT_RING( dev_priv->span_pitch_offset_c );
+ OUT_RING(dev_priv->depth_pitch_offset_c);
+ OUT_RING(dev_priv->span_pitch_offset_c);
- OUT_RING( (x[i] << 16) | y[i] );
- OUT_RING( (i << 16) | 0 );
- OUT_RING( (1 << 16) | 1 );
+ OUT_RING((x[i] << 16) | y[i]);
+ OUT_RING((i << 16) | 0);
+ OUT_RING((1 << 16) | 1);
ADVANCE_RING();
}
- drm_free( x, xbuf_size, DRM_MEM_BUFS );
- drm_free( y, ybuf_size, DRM_MEM_BUFS );
+ drm_free(x, xbuf_size, DRM_MEM_BUFS);
+ drm_free(y, ybuf_size, DRM_MEM_BUFS);
return 0;
}
-
/* ================================================================
* Polygon stipple
*/
-static void r128_cce_dispatch_stipple( drm_device_t *dev, u32 *stipple )
+static void r128_cce_dispatch_stipple(drm_device_t * dev, u32 * stipple)
{
drm_r128_private_t *dev_priv = dev->dev_private;
int i;
RING_LOCALS;
- DRM_DEBUG( "%s\n", __FUNCTION__ );
+ DRM_DEBUG("%s\n", __FUNCTION__);
- BEGIN_RING( 33 );
+ BEGIN_RING(33);
- OUT_RING( CCE_PACKET0( R128_BRUSH_DATA0, 31 ) );
- for ( i = 0 ; i < 32 ; i++ ) {
- OUT_RING( stipple[i] );
+ OUT_RING(CCE_PACKET0(R128_BRUSH_DATA0, 31));
+ for (i = 0; i < 32; i++) {
+ OUT_RING(stipple[i]);
}
ADVANCE_RING();
}
-
/* ================================================================
* IOCTL functions
*/
-static int r128_cce_clear( DRM_IOCTL_ARGS )
+static int r128_cce_clear(DRM_IOCTL_ARGS)
{
DRM_DEVICE;
drm_r128_private_t *dev_priv = dev->dev_private;
drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
drm_r128_clear_t clear;
- DRM_DEBUG( "\n" );
+ DRM_DEBUG("\n");
- LOCK_TEST_WITH_RETURN( dev, filp );
+ LOCK_TEST_WITH_RETURN(dev, filp);
- DRM_COPY_FROM_USER_IOCTL( clear, (drm_r128_clear_t __user *) data,
- sizeof(clear) );
+ DRM_COPY_FROM_USER_IOCTL(clear, (drm_r128_clear_t __user *) data,
+ sizeof(clear));
- RING_SPACE_TEST_WITH_RETURN( dev_priv );
+ RING_SPACE_TEST_WITH_RETURN(dev_priv);
- if ( sarea_priv->nbox > R128_NR_SAREA_CLIPRECTS )
+ if (sarea_priv->nbox > R128_NR_SAREA_CLIPRECTS)
sarea_priv->nbox = R128_NR_SAREA_CLIPRECTS;
- r128_cce_dispatch_clear( dev, &clear );
+ r128_cce_dispatch_clear(dev, &clear);
COMMIT_RING();
/* Make sure we restore the 3D state next time.
@@ -1288,17 +1268,17 @@ static int r128_cce_clear( DRM_IOCTL_ARGS )
return 0;
}
-static int r128_do_init_pageflip( drm_device_t *dev )
+static int r128_do_init_pageflip(drm_device_t * dev)
{
drm_r128_private_t *dev_priv = dev->dev_private;
- DRM_DEBUG( "\n" );
+ DRM_DEBUG("\n");
- dev_priv->crtc_offset = R128_READ( R128_CRTC_OFFSET );
- dev_priv->crtc_offset_cntl = R128_READ( R128_CRTC_OFFSET_CNTL );
+ dev_priv->crtc_offset = R128_READ(R128_CRTC_OFFSET);
+ dev_priv->crtc_offset_cntl = R128_READ(R128_CRTC_OFFSET_CNTL);
- R128_WRITE( R128_CRTC_OFFSET, dev_priv->front_offset );
- R128_WRITE( R128_CRTC_OFFSET_CNTL,
- dev_priv->crtc_offset_cntl | R128_CRTC_OFFSET_FLIP_CNTL );
+ R128_WRITE(R128_CRTC_OFFSET, dev_priv->front_offset);
+ R128_WRITE(R128_CRTC_OFFSET_CNTL,
+ dev_priv->crtc_offset_cntl | R128_CRTC_OFFSET_FLIP_CNTL);
dev_priv->page_flipping = 1;
dev_priv->current_page = 0;
@@ -1307,16 +1287,16 @@ static int r128_do_init_pageflip( drm_device_t *dev )
return 0;
}
-static int r128_do_cleanup_pageflip( drm_device_t *dev )
+static int r128_do_cleanup_pageflip(drm_device_t * dev)
{
drm_r128_private_t *dev_priv = dev->dev_private;
- DRM_DEBUG( "\n" );
+ DRM_DEBUG("\n");
- R128_WRITE( R128_CRTC_OFFSET, dev_priv->crtc_offset );
- R128_WRITE( R128_CRTC_OFFSET_CNTL, dev_priv->crtc_offset_cntl );
+ R128_WRITE(R128_CRTC_OFFSET, dev_priv->crtc_offset);
+ R128_WRITE(R128_CRTC_OFFSET_CNTL, dev_priv->crtc_offset_cntl);
if (dev_priv->current_page != 0) {
- r128_cce_dispatch_flip( dev );
+ r128_cce_dispatch_flip(dev);
COMMIT_RING();
}
@@ -1325,43 +1305,43 @@ static int r128_do_cleanup_pageflip( drm_device_t *dev )
}
/* Swapping and flipping are different operations, need different ioctls.
- * They can & should be intermixed to support multiple 3d windows.
+ * They can & should be intermixed to support multiple 3d windows.
*/
-static int r128_cce_flip( DRM_IOCTL_ARGS )
+static int r128_cce_flip(DRM_IOCTL_ARGS)
{
DRM_DEVICE;
drm_r128_private_t *dev_priv = dev->dev_private;
- DRM_DEBUG( "%s\n", __FUNCTION__ );
+ DRM_DEBUG("%s\n", __FUNCTION__);
- LOCK_TEST_WITH_RETURN( dev, filp );
+ LOCK_TEST_WITH_RETURN(dev, filp);
- RING_SPACE_TEST_WITH_RETURN( dev_priv );
+ RING_SPACE_TEST_WITH_RETURN(dev_priv);
- if (!dev_priv->page_flipping)
- r128_do_init_pageflip( dev );
+ if (!dev_priv->page_flipping)
+ r128_do_init_pageflip(dev);
- r128_cce_dispatch_flip( dev );
+ r128_cce_dispatch_flip(dev);
COMMIT_RING();
return 0;
}
-static int r128_cce_swap( DRM_IOCTL_ARGS )
+static int r128_cce_swap(DRM_IOCTL_ARGS)
{
DRM_DEVICE;
drm_r128_private_t *dev_priv = dev->dev_private;
drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
- DRM_DEBUG( "%s\n", __FUNCTION__ );
+ DRM_DEBUG("%s\n", __FUNCTION__);
- LOCK_TEST_WITH_RETURN( dev, filp );
+ LOCK_TEST_WITH_RETURN(dev, filp);
- RING_SPACE_TEST_WITH_RETURN( dev_priv );
+ RING_SPACE_TEST_WITH_RETURN(dev_priv);
- if ( sarea_priv->nbox > R128_NR_SAREA_CLIPRECTS )
+ if (sarea_priv->nbox > R128_NR_SAREA_CLIPRECTS)
sarea_priv->nbox = R128_NR_SAREA_CLIPRECTS;
- r128_cce_dispatch_swap( dev );
+ r128_cce_dispatch_swap(dev);
dev_priv->sarea_priv->dirty |= (R128_UPLOAD_CONTEXT |
R128_UPLOAD_MASKS);
@@ -1369,7 +1349,7 @@ static int r128_cce_swap( DRM_IOCTL_ARGS )
return 0;
}
-static int r128_cce_vertex( DRM_IOCTL_ARGS )
+static int r128_cce_vertex(DRM_IOCTL_ARGS)
{
DRM_DEVICE;
drm_r128_private_t *dev_priv = dev->dev_private;
@@ -1378,44 +1358,43 @@ static int r128_cce_vertex( DRM_IOCTL_ARGS )
drm_r128_buf_priv_t *buf_priv;
drm_r128_vertex_t vertex;
- LOCK_TEST_WITH_RETURN( dev, filp );
+ LOCK_TEST_WITH_RETURN(dev, filp);
- if ( !dev_priv ) {
- DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
+ if (!dev_priv) {
+ DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
return DRM_ERR(EINVAL);
}
- DRM_COPY_FROM_USER_IOCTL( vertex, (drm_r128_vertex_t __user *) data,
- sizeof(vertex) );
+ DRM_COPY_FROM_USER_IOCTL(vertex, (drm_r128_vertex_t __user *) data,
+ sizeof(vertex));
- DRM_DEBUG( "pid=%d index=%d count=%d discard=%d\n",
- DRM_CURRENTPID,
- vertex.idx, vertex.count, vertex.discard );
+ DRM_DEBUG("pid=%d index=%d count=%d discard=%d\n",
+ DRM_CURRENTPID, vertex.idx, vertex.count, vertex.discard);
- if ( vertex.idx < 0 || vertex.idx >= dma->buf_count ) {
- DRM_ERROR( "buffer index %d (of %d max)\n",
- vertex.idx, dma->buf_count - 1 );
+ if (vertex.idx < 0 || vertex.idx >= dma->buf_count) {
+ DRM_ERROR("buffer index %d (of %d max)\n",
+ vertex.idx, dma->buf_count - 1);
return DRM_ERR(EINVAL);
}
- if ( vertex.prim < 0 ||
- vertex.prim > R128_CCE_VC_CNTL_PRIM_TYPE_TRI_TYPE2 ) {
- DRM_ERROR( "buffer prim %d\n", vertex.prim );
+ if (vertex.prim < 0 ||
+ vertex.prim > R128_CCE_VC_CNTL_PRIM_TYPE_TRI_TYPE2) {
+ DRM_ERROR("buffer prim %d\n", vertex.prim);
return DRM_ERR(EINVAL);
}
- RING_SPACE_TEST_WITH_RETURN( dev_priv );
- VB_AGE_TEST_WITH_RETURN( dev_priv );
+ RING_SPACE_TEST_WITH_RETURN(dev_priv);
+ VB_AGE_TEST_WITH_RETURN(dev_priv);
buf = dma->buflist[vertex.idx];
buf_priv = buf->dev_private;
- if ( buf->filp != filp ) {
- DRM_ERROR( "process %d using buffer owned by %p\n",
- DRM_CURRENTPID, buf->filp );
+ if (buf->filp != filp) {
+ DRM_ERROR("process %d using buffer owned by %p\n",
+ DRM_CURRENTPID, buf->filp);
return DRM_ERR(EINVAL);
}
- if ( buf->pending ) {
- DRM_ERROR( "sending pending buffer %d\n", vertex.idx );
+ if (buf->pending) {
+ DRM_ERROR("sending pending buffer %d\n", vertex.idx);
return DRM_ERR(EINVAL);
}
@@ -1423,13 +1402,13 @@ static int r128_cce_vertex( DRM_IOCTL_ARGS )
buf_priv->prim = vertex.prim;
buf_priv->discard = vertex.discard;
- r128_cce_dispatch_vertex( dev, buf );
+ r128_cce_dispatch_vertex(dev, buf);
COMMIT_RING();
return 0;
}
-static int r128_cce_indices( DRM_IOCTL_ARGS )
+static int r128_cce_indices(DRM_IOCTL_ARGS)
{
DRM_DEVICE;
drm_r128_private_t *dev_priv = dev->dev_private;
@@ -1439,55 +1418,54 @@ static int r128_cce_indices( DRM_IOCTL_ARGS )
drm_r128_indices_t elts;
int count;
- LOCK_TEST_WITH_RETURN( dev, filp );
+ LOCK_TEST_WITH_RETURN(dev, filp);
- if ( !dev_priv ) {
- DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
+ if (!dev_priv) {
+ DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
return DRM_ERR(EINVAL);
}
- DRM_COPY_FROM_USER_IOCTL( elts, (drm_r128_indices_t __user *) data,
- sizeof(elts) );
+ DRM_COPY_FROM_USER_IOCTL(elts, (drm_r128_indices_t __user *) data,
+ sizeof(elts));
- DRM_DEBUG( "pid=%d buf=%d s=%d e=%d d=%d\n", DRM_CURRENTPID,
- elts.idx, elts.start, elts.end, elts.discard );
+ DRM_DEBUG("pid=%d buf=%d s=%d e=%d d=%d\n", DRM_CURRENTPID,
+ elts.idx, elts.start, elts.end, elts.discard);
- if ( elts.idx < 0 || elts.idx >= dma->buf_count ) {
- DRM_ERROR( "buffer index %d (of %d max)\n",
- elts.idx, dma->buf_count - 1 );
+ if (elts.idx < 0 || elts.idx >= dma->buf_count) {
+ DRM_ERROR("buffer index %d (of %d max)\n",
+ elts.idx, dma->buf_count - 1);
return DRM_ERR(EINVAL);
}
- if ( elts.prim < 0 ||
- elts.prim > R128_CCE_VC_CNTL_PRIM_TYPE_TRI_TYPE2 ) {
- DRM_ERROR( "buffer prim %d\n", elts.prim );
+ if (elts.prim < 0 || elts.prim > R128_CCE_VC_CNTL_PRIM_TYPE_TRI_TYPE2) {
+ DRM_ERROR("buffer prim %d\n", elts.prim);
return DRM_ERR(EINVAL);
}
- RING_SPACE_TEST_WITH_RETURN( dev_priv );
- VB_AGE_TEST_WITH_RETURN( dev_priv );
+ RING_SPACE_TEST_WITH_RETURN(dev_priv);
+ VB_AGE_TEST_WITH_RETURN(dev_priv);
buf = dma->buflist[elts.idx];
buf_priv = buf->dev_private;
- if ( buf->filp != filp ) {
- DRM_ERROR( "process %d using buffer owned by %p\n",
- DRM_CURRENTPID, buf->filp );
+ if (buf->filp != filp) {
+ DRM_ERROR("process %d using buffer owned by %p\n",
+ DRM_CURRENTPID, buf->filp);
return DRM_ERR(EINVAL);
}
- if ( buf->pending ) {
- DRM_ERROR( "sending pending buffer %d\n", elts.idx );
+ if (buf->pending) {
+ DRM_ERROR("sending pending buffer %d\n", elts.idx);
return DRM_ERR(EINVAL);
}
count = (elts.end - elts.start) / sizeof(u16);
elts.start -= R128_INDEX_PRIM_OFFSET;
- if ( elts.start & 0x7 ) {
- DRM_ERROR( "misaligned buffer 0x%x\n", elts.start );
+ if (elts.start & 0x7) {
+ DRM_ERROR("misaligned buffer 0x%x\n", elts.start);
return DRM_ERR(EINVAL);
}
- if ( elts.start < buf->used ) {
- DRM_ERROR( "no header 0x%x - 0x%x\n", elts.start, buf->used );
+ if (elts.start < buf->used) {
+ DRM_ERROR("no header 0x%x - 0x%x\n", elts.start, buf->used);
return DRM_ERR(EINVAL);
}
@@ -1495,13 +1473,13 @@ static int r128_cce_indices( DRM_IOCTL_ARGS )
buf_priv->prim = elts.prim;
buf_priv->discard = elts.discard;
- r128_cce_dispatch_indices( dev, buf, elts.start, elts.end, count );
+ r128_cce_dispatch_indices(dev, buf, elts.start, elts.end, count);
COMMIT_RING();
return 0;
}
-static int r128_cce_blit( DRM_IOCTL_ARGS )
+static int r128_cce_blit(DRM_IOCTL_ARGS)
{
DRM_DEVICE;
drm_device_dma_t *dma = dev->dma;
@@ -1509,55 +1487,55 @@ static int r128_cce_blit( DRM_IOCTL_ARGS )
drm_r128_blit_t blit;
int ret;
- LOCK_TEST_WITH_RETURN( dev, filp );
+ LOCK_TEST_WITH_RETURN(dev, filp);
- DRM_COPY_FROM_USER_IOCTL( blit, (drm_r128_blit_t __user *) data,
- sizeof(blit) );
+ DRM_COPY_FROM_USER_IOCTL(blit, (drm_r128_blit_t __user *) data,
+ sizeof(blit));
- DRM_DEBUG( "pid=%d index=%d\n", DRM_CURRENTPID, blit.idx );
+ DRM_DEBUG("pid=%d index=%d\n", DRM_CURRENTPID, blit.idx);
- if ( blit.idx < 0 || blit.idx >= dma->buf_count ) {
- DRM_ERROR( "buffer index %d (of %d max)\n",
- blit.idx, dma->buf_count - 1 );
+ if (blit.idx < 0 || blit.idx >= dma->buf_count) {
+ DRM_ERROR("buffer index %d (of %d max)\n",
+ blit.idx, dma->buf_count - 1);
return DRM_ERR(EINVAL);
}
- RING_SPACE_TEST_WITH_RETURN( dev_priv );
- VB_AGE_TEST_WITH_RETURN( dev_priv );
+ RING_SPACE_TEST_WITH_RETURN(dev_priv);
+ VB_AGE_TEST_WITH_RETURN(dev_priv);
- ret = r128_cce_dispatch_blit( filp, dev, &blit );
+ ret = r128_cce_dispatch_blit(filp, dev, &blit);
COMMIT_RING();
return ret;
}
-static int r128_cce_depth( DRM_IOCTL_ARGS )
+static int r128_cce_depth(DRM_IOCTL_ARGS)
{
DRM_DEVICE;
drm_r128_private_t *dev_priv = dev->dev_private;
drm_r128_depth_t depth;
int ret;
- LOCK_TEST_WITH_RETURN( dev, filp );
+ LOCK_TEST_WITH_RETURN(dev, filp);
- DRM_COPY_FROM_USER_IOCTL( depth, (drm_r128_depth_t __user *) data,
- sizeof(depth) );
+ DRM_COPY_FROM_USER_IOCTL(depth, (drm_r128_depth_t __user *) data,
+ sizeof(depth));
- RING_SPACE_TEST_WITH_RETURN( dev_priv );
+ RING_SPACE_TEST_WITH_RETURN(dev_priv);
ret = DRM_ERR(EINVAL);
- switch ( depth.func ) {
+ switch (depth.func) {
case R128_WRITE_SPAN:
- ret = r128_cce_dispatch_write_span( dev, &depth );
+ ret = r128_cce_dispatch_write_span(dev, &depth);
break;
case R128_WRITE_PIXELS:
- ret = r128_cce_dispatch_write_pixels( dev, &depth );
+ ret = r128_cce_dispatch_write_pixels(dev, &depth);
break;
case R128_READ_SPAN:
- ret = r128_cce_dispatch_read_span( dev, &depth );
+ ret = r128_cce_dispatch_read_span(dev, &depth);
break;
case R128_READ_PIXELS:
- ret = r128_cce_dispatch_read_pixels( dev, &depth );
+ ret = r128_cce_dispatch_read_pixels(dev, &depth);
break;
}
@@ -1565,31 +1543,30 @@ static int r128_cce_depth( DRM_IOCTL_ARGS )
return ret;
}
-static int r128_cce_stipple( DRM_IOCTL_ARGS )
+static int r128_cce_stipple(DRM_IOCTL_ARGS)
{
DRM_DEVICE;
drm_r128_private_t *dev_priv = dev->dev_private;
drm_r128_stipple_t stipple;
u32 mask[32];
- LOCK_TEST_WITH_RETURN( dev, filp );
+ LOCK_TEST_WITH_RETURN(dev, filp);
- DRM_COPY_FROM_USER_IOCTL( stipple, (drm_r128_stipple_t __user *) data,
- sizeof(stipple) );
+ DRM_COPY_FROM_USER_IOCTL(stipple, (drm_r128_stipple_t __user *) data,
+ sizeof(stipple));
- if ( DRM_COPY_FROM_USER( &mask, stipple.mask,
- 32 * sizeof(u32) ) )
- return DRM_ERR( EFAULT );
+ if (DRM_COPY_FROM_USER(&mask, stipple.mask, 32 * sizeof(u32)))
+ return DRM_ERR(EFAULT);
- RING_SPACE_TEST_WITH_RETURN( dev_priv );
+ RING_SPACE_TEST_WITH_RETURN(dev_priv);
- r128_cce_dispatch_stipple( dev, mask );
+ r128_cce_dispatch_stipple(dev, mask);
COMMIT_RING();
return 0;
}
-static int r128_cce_indirect( DRM_IOCTL_ARGS )
+static int r128_cce_indirect(DRM_IOCTL_ARGS)
{
DRM_DEVICE;
drm_r128_private_t *dev_priv = dev->dev_private;
@@ -1601,47 +1578,46 @@ static int r128_cce_indirect( DRM_IOCTL_ARGS )
RING_LOCALS;
#endif
- LOCK_TEST_WITH_RETURN( dev, filp );
+ LOCK_TEST_WITH_RETURN(dev, filp);
- if ( !dev_priv ) {
- DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
+ if (!dev_priv) {
+ DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
return DRM_ERR(EINVAL);
}
- DRM_COPY_FROM_USER_IOCTL( indirect, (drm_r128_indirect_t __user *) data,
- sizeof(indirect) );
+ DRM_COPY_FROM_USER_IOCTL(indirect, (drm_r128_indirect_t __user *) data,
+ sizeof(indirect));
- DRM_DEBUG( "indirect: idx=%d s=%d e=%d d=%d\n",
- indirect.idx, indirect.start,
- indirect.end, indirect.discard );
+ DRM_DEBUG("indirect: idx=%d s=%d e=%d d=%d\n",
+ indirect.idx, indirect.start, indirect.end, indirect.discard);
- if ( indirect.idx < 0 || indirect.idx >= dma->buf_count ) {
- DRM_ERROR( "buffer index %d (of %d max)\n",
- indirect.idx, dma->buf_count - 1 );
+ if (indirect.idx < 0 || indirect.idx >= dma->buf_count) {
+ DRM_ERROR("buffer index %d (of %d max)\n",
+ indirect.idx, dma->buf_count - 1);
return DRM_ERR(EINVAL);
}
buf = dma->buflist[indirect.idx];
buf_priv = buf->dev_private;
- if ( buf->filp != filp ) {
- DRM_ERROR( "process %d using buffer owned by %p\n",
- DRM_CURRENTPID, buf->filp );
+ if (buf->filp != filp) {
+ DRM_ERROR("process %d using buffer owned by %p\n",
+ DRM_CURRENTPID, buf->filp);
return DRM_ERR(EINVAL);
}
- if ( buf->pending ) {
- DRM_ERROR( "sending pending buffer %d\n", indirect.idx );
+ if (buf->pending) {
+ DRM_ERROR("sending pending buffer %d\n", indirect.idx);
return DRM_ERR(EINVAL);
}
- if ( indirect.start < buf->used ) {
- DRM_ERROR( "reusing indirect: start=0x%x actual=0x%x\n",
- indirect.start, buf->used );
+ if (indirect.start < buf->used) {
+ DRM_ERROR("reusing indirect: start=0x%x actual=0x%x\n",
+ indirect.start, buf->used);
return DRM_ERR(EINVAL);
}
- RING_SPACE_TEST_WITH_RETURN( dev_priv );
- VB_AGE_TEST_WITH_RETURN( dev_priv );
+ RING_SPACE_TEST_WITH_RETURN(dev_priv);
+ VB_AGE_TEST_WITH_RETURN(dev_priv);
buf->used = indirect.end;
buf_priv->discard = indirect.discard;
@@ -1650,7 +1626,7 @@ static int r128_cce_indirect( DRM_IOCTL_ARGS )
/* Wait for the 3D stream to idle before the indirect buffer
* containing 2D acceleration commands is processed.
*/
- BEGIN_RING( 2 );
+ BEGIN_RING(2);
RADEON_WAIT_UNTIL_3D_IDLE();
ADVANCE_RING();
#endif
@@ -1659,30 +1635,30 @@ static int r128_cce_indirect( DRM_IOCTL_ARGS )
* X server. This is insecure and is thus only available to
* privileged clients.
*/
- r128_cce_dispatch_indirect( dev, buf, indirect.start, indirect.end );
+ r128_cce_dispatch_indirect(dev, buf, indirect.start, indirect.end);
COMMIT_RING();
return 0;
}
-static int r128_getparam( DRM_IOCTL_ARGS )
+static int r128_getparam(DRM_IOCTL_ARGS)
{
DRM_DEVICE;
drm_r128_private_t *dev_priv = dev->dev_private;
drm_r128_getparam_t param;
int value;
- if ( !dev_priv ) {
- DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
+ if (!dev_priv) {
+ DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
return DRM_ERR(EINVAL);
}
- DRM_COPY_FROM_USER_IOCTL( param, (drm_r128_getparam_t __user *)data,
- sizeof(param) );
+ DRM_COPY_FROM_USER_IOCTL(param, (drm_r128_getparam_t __user *) data,
+ sizeof(param));
- DRM_DEBUG( "pid=%d\n", DRM_CURRENTPID );
+ DRM_DEBUG("pid=%d\n", DRM_CURRENTPID);
- switch( param.param ) {
+ switch (param.param) {
case R128_PARAM_IRQ_NR:
value = dev->irq;
break;
@@ -1690,47 +1666,47 @@ static int r128_getparam( DRM_IOCTL_ARGS )
return DRM_ERR(EINVAL);
}
- if ( DRM_COPY_TO_USER( param.value, &value, sizeof(int) ) ) {
- DRM_ERROR( "copy_to_user\n" );
+ if (DRM_COPY_TO_USER(param.value, &value, sizeof(int))) {
+ DRM_ERROR("copy_to_user\n");
return DRM_ERR(EFAULT);
}
-
+
return 0;
}
-void r128_driver_prerelease(drm_device_t *dev, DRMFILE filp)
+void r128_driver_prerelease(drm_device_t * dev, DRMFILE filp)
{
- if ( dev->dev_private ) {
+ if (dev->dev_private) {
drm_r128_private_t *dev_priv = dev->dev_private;
- if ( dev_priv->page_flipping ) {
- r128_do_cleanup_pageflip( dev );
+ if (dev_priv->page_flipping) {
+ r128_do_cleanup_pageflip(dev);
}
- }
+ }
}
-void r128_driver_pretakedown(drm_device_t *dev)
+void r128_driver_pretakedown(drm_device_t * dev)
{
- r128_do_cleanup_cce( dev );
+ r128_do_cleanup_cce(dev);
}
drm_ioctl_desc_t r128_ioctls[] = {
- [DRM_IOCTL_NR(DRM_R128_INIT)] = { r128_cce_init, 1, 1 },
- [DRM_IOCTL_NR(DRM_R128_CCE_START)] = { r128_cce_start, 1, 1 },
- [DRM_IOCTL_NR(DRM_R128_CCE_STOP)] = { r128_cce_stop, 1, 1 },
- [DRM_IOCTL_NR(DRM_R128_CCE_RESET)] = { r128_cce_reset, 1, 1 },
- [DRM_IOCTL_NR(DRM_R128_CCE_IDLE)] = { r128_cce_idle, 1, 0 },
- [DRM_IOCTL_NR(DRM_R128_RESET)] = { r128_engine_reset, 1, 0 },
- [DRM_IOCTL_NR(DRM_R128_FULLSCREEN)] = { r128_fullscreen, 1, 0 },
- [DRM_IOCTL_NR(DRM_R128_SWAP)] = { r128_cce_swap, 1, 0 },
- [DRM_IOCTL_NR(DRM_R128_FLIP)] = { r128_cce_flip, 1, 0 },
- [DRM_IOCTL_NR(DRM_R128_CLEAR)] = { r128_cce_clear, 1, 0 },
- [DRM_IOCTL_NR(DRM_R128_VERTEX)] = { r128_cce_vertex, 1, 0 },
- [DRM_IOCTL_NR(DRM_R128_INDICES)] = { r128_cce_indices, 1, 0 },
- [DRM_IOCTL_NR(DRM_R128_BLIT)] = { r128_cce_blit, 1, 0 },
- [DRM_IOCTL_NR(DRM_R128_DEPTH)] = { r128_cce_depth, 1, 0 },
- [DRM_IOCTL_NR(DRM_R128_STIPPLE)] = { r128_cce_stipple, 1, 0 },
- [DRM_IOCTL_NR(DRM_R128_INDIRECT)] = { r128_cce_indirect, 1, 1 },
- [DRM_IOCTL_NR(DRM_R128_GETPARAM)] = { r128_getparam, 1, 0 },
+ [DRM_IOCTL_NR(DRM_R128_INIT)] = {r128_cce_init, 1, 1},
+ [DRM_IOCTL_NR(DRM_R128_CCE_START)] = {r128_cce_start, 1, 1},
+ [DRM_IOCTL_NR(DRM_R128_CCE_STOP)] = {r128_cce_stop, 1, 1},
+ [DRM_IOCTL_NR(DRM_R128_CCE_RESET)] = {r128_cce_reset, 1, 1},
+ [DRM_IOCTL_NR(DRM_R128_CCE_IDLE)] = {r128_cce_idle, 1, 0},
+ [DRM_IOCTL_NR(DRM_R128_RESET)] = {r128_engine_reset, 1, 0},
+ [DRM_IOCTL_NR(DRM_R128_FULLSCREEN)] = {r128_fullscreen, 1, 0},
+ [DRM_IOCTL_NR(DRM_R128_SWAP)] = {r128_cce_swap, 1, 0},
+ [DRM_IOCTL_NR(DRM_R128_FLIP)] = {r128_cce_flip, 1, 0},
+ [DRM_IOCTL_NR(DRM_R128_CLEAR)] = {r128_cce_clear, 1, 0},
+ [DRM_IOCTL_NR(DRM_R128_VERTEX)] = {r128_cce_vertex, 1, 0},
+ [DRM_IOCTL_NR(DRM_R128_INDICES)] = {r128_cce_indices, 1, 0},
+ [DRM_IOCTL_NR(DRM_R128_BLIT)] = {r128_cce_blit, 1, 0},
+ [DRM_IOCTL_NR(DRM_R128_DEPTH)] = {r128_cce_depth, 1, 0},
+ [DRM_IOCTL_NR(DRM_R128_STIPPLE)] = {r128_cce_stipple, 1, 0},
+ [DRM_IOCTL_NR(DRM_R128_INDIRECT)] = {r128_cce_indirect, 1, 1},
+ [DRM_IOCTL_NR(DRM_R128_GETPARAM)] = {r128_getparam, 1, 0},
};
int r128_max_ioctl = DRM_ARRAY_SIZE(r128_ioctls);
diff --git a/drivers/char/drm/r300_cmdbuf.c b/drivers/char/drm/r300_cmdbuf.c
index 623f1f460cb5..3a1ac5f78b43 100644
--- a/drivers/char/drm/r300_cmdbuf.c
+++ b/drivers/char/drm/r300_cmdbuf.c
@@ -37,7 +37,6 @@
#include "radeon_drv.h"
#include "r300_reg.h"
-
#define R300_SIMULTANEOUS_CLIPRECTS 4
/* Values for R300_RE_CLIPRECT_CNTL depending on the number of cliprects
@@ -49,14 +48,12 @@ static const int r300_cliprect_cntl[4] = {
0xFFFE
};
-
/**
* Emit up to R300_SIMULTANEOUS_CLIPRECTS cliprects from the given command
* buffer, starting with index n.
*/
-static int r300_emit_cliprects(drm_radeon_private_t* dev_priv,
- drm_radeon_cmd_buffer_t* cmdbuf,
- int n)
+static int r300_emit_cliprects(drm_radeon_private_t * dev_priv,
+ drm_radeon_kcmd_buffer_t * cmdbuf, int n)
{
drm_clip_rect_t box;
int nr;
@@ -70,38 +67,47 @@ static int r300_emit_cliprects(drm_radeon_private_t* dev_priv,
DRM_DEBUG("%i cliprects\n", nr);
if (nr) {
- BEGIN_RING(6 + nr*2);
- OUT_RING( CP_PACKET0( R300_RE_CLIPRECT_TL_0, nr*2 - 1 ) );
+ BEGIN_RING(6 + nr * 2);
+ OUT_RING(CP_PACKET0(R300_RE_CLIPRECT_TL_0, nr * 2 - 1));
- for(i = 0; i < nr; ++i) {
- if (DRM_COPY_FROM_USER_UNCHECKED(&box, &cmdbuf->boxes[n+i], sizeof(box))) {
+ for (i = 0; i < nr; ++i) {
+ if (DRM_COPY_FROM_USER_UNCHECKED
+ (&box, &cmdbuf->boxes[n + i], sizeof(box))) {
DRM_ERROR("copy cliprect faulted\n");
return DRM_ERR(EFAULT);
}
- box.x1 = (box.x1 + R300_CLIPRECT_OFFSET) & R300_CLIPRECT_MASK;
- box.y1 = (box.y1 + R300_CLIPRECT_OFFSET) & R300_CLIPRECT_MASK;
- box.x2 = (box.x2 + R300_CLIPRECT_OFFSET) & R300_CLIPRECT_MASK;
- box.y2 = (box.y2 + R300_CLIPRECT_OFFSET) & R300_CLIPRECT_MASK;
+ box.x1 =
+ (box.x1 +
+ R300_CLIPRECT_OFFSET) & R300_CLIPRECT_MASK;
+ box.y1 =
+ (box.y1 +
+ R300_CLIPRECT_OFFSET) & R300_CLIPRECT_MASK;
+ box.x2 =
+ (box.x2 +
+ R300_CLIPRECT_OFFSET) & R300_CLIPRECT_MASK;
+ box.y2 =
+ (box.y2 +
+ R300_CLIPRECT_OFFSET) & R300_CLIPRECT_MASK;
OUT_RING((box.x1 << R300_CLIPRECT_X_SHIFT) |
- (box.y1 << R300_CLIPRECT_Y_SHIFT));
+ (box.y1 << R300_CLIPRECT_Y_SHIFT));
OUT_RING((box.x2 << R300_CLIPRECT_X_SHIFT) |
- (box.y2 << R300_CLIPRECT_Y_SHIFT));
+ (box.y2 << R300_CLIPRECT_Y_SHIFT));
}
- OUT_RING_REG( R300_RE_CLIPRECT_CNTL, r300_cliprect_cntl[nr-1] );
+ OUT_RING_REG(R300_RE_CLIPRECT_CNTL, r300_cliprect_cntl[nr - 1]);
/* TODO/SECURITY: Force scissors to a safe value, otherwise the
- * client might be able to trample over memory.
- * The impact should be very limited, but I'd rather be safe than
- * sorry.
- */
- OUT_RING( CP_PACKET0( R300_RE_SCISSORS_TL, 1 ) );
- OUT_RING( 0 );
- OUT_RING( R300_SCISSORS_X_MASK | R300_SCISSORS_Y_MASK );
+ * client might be able to trample over memory.
+ * The impact should be very limited, but I'd rather be safe than
+ * sorry.
+ */
+ OUT_RING(CP_PACKET0(R300_RE_SCISSORS_TL, 1));
+ OUT_RING(0);
+ OUT_RING(R300_SCISSORS_X_MASK | R300_SCISSORS_Y_MASK);
ADVANCE_RING();
- } else {
+ } else {
/* Why we allow zero cliprect rendering:
* There are some commands in a command buffer that must be submitted
* even when there are no cliprects, e.g. DMA buffer discard
@@ -118,28 +124,27 @@ static int r300_emit_cliprects(drm_radeon_private_t* dev_priv,
* can't produce any fragments.
*/
BEGIN_RING(2);
- OUT_RING_REG( R300_RE_CLIPRECT_CNTL, 0 );
+ OUT_RING_REG(R300_RE_CLIPRECT_CNTL, 0);
ADVANCE_RING();
- }
+ }
return 0;
}
-u8 r300_reg_flags[0x10000>>2];
-
+static u8 r300_reg_flags[0x10000 >> 2];
void r300_init_reg_flags(void)
{
int i;
- memset(r300_reg_flags, 0, 0x10000>>2);
- #define ADD_RANGE_MARK(reg, count,mark) \
+ memset(r300_reg_flags, 0, 0x10000 >> 2);
+#define ADD_RANGE_MARK(reg, count,mark) \
for(i=((reg)>>2);i<((reg)>>2)+(count);i++)\
r300_reg_flags[i]|=(mark);
-
- #define MARK_SAFE 1
- #define MARK_CHECK_OFFSET 2
-
- #define ADD_RANGE(reg, count) ADD_RANGE_MARK(reg, count, MARK_SAFE)
+
+#define MARK_SAFE 1
+#define MARK_CHECK_OFFSET 2
+
+#define ADD_RANGE(reg, count) ADD_RANGE_MARK(reg, count, MARK_SAFE)
/* these match cmducs() command in r300_driver/r300/r300_cmdbuf.c */
ADD_RANGE(R300_SE_VPORT_XSCALE, 6);
@@ -193,15 +198,15 @@ void r300_init_reg_flags(void)
ADD_RANGE(R300_RB3D_CBLEND, 2);
ADD_RANGE(R300_RB3D_COLORMASK, 1);
ADD_RANGE(0x4E10, 3);
- ADD_RANGE_MARK(R300_RB3D_COLOROFFSET0, 1, MARK_CHECK_OFFSET); /* check offset */
+ ADD_RANGE_MARK(R300_RB3D_COLOROFFSET0, 1, MARK_CHECK_OFFSET); /* check offset */
ADD_RANGE(R300_RB3D_COLORPITCH0, 1);
ADD_RANGE(0x4E50, 9);
ADD_RANGE(0x4E88, 1);
ADD_RANGE(0x4EA0, 2);
ADD_RANGE(R300_RB3D_ZSTENCIL_CNTL_0, 3);
ADD_RANGE(0x4F10, 4);
- ADD_RANGE_MARK(R300_RB3D_DEPTHOFFSET, 1, MARK_CHECK_OFFSET); /* check offset */
- ADD_RANGE(R300_RB3D_DEPTHPITCH, 1);
+ ADD_RANGE_MARK(R300_RB3D_DEPTHOFFSET, 1, MARK_CHECK_OFFSET); /* check offset */
+ ADD_RANGE(R300_RB3D_DEPTHPITCH, 1);
ADD_RANGE(0x4F28, 1);
ADD_RANGE(0x4F30, 2);
ADD_RANGE(0x4F44, 1);
@@ -211,7 +216,7 @@ void r300_init_reg_flags(void)
ADD_RANGE(R300_TX_UNK1_0, 16);
ADD_RANGE(R300_TX_SIZE_0, 16);
ADD_RANGE(R300_TX_FORMAT_0, 16);
- /* Texture offset is dangerous and needs more checking */
+ /* Texture offset is dangerous and needs more checking */
ADD_RANGE_MARK(R300_TX_OFFSET_0, 16, MARK_CHECK_OFFSET);
ADD_RANGE(R300_TX_UNK4_0, 16);
ADD_RANGE(R300_TX_BORDER_COLOR_0, 16);
@@ -224,33 +229,41 @@ void r300_init_reg_flags(void)
}
-static __inline__ int r300_check_range(unsigned reg, int count)
+static __inline__ int r300_check_range(unsigned reg, int count)
{
int i;
- if(reg & ~0xffff)return -1;
- for(i=(reg>>2);i<(reg>>2)+count;i++)
- if(r300_reg_flags[i]!=MARK_SAFE)return 1;
+ if (reg & ~0xffff)
+ return -1;
+ for (i = (reg >> 2); i < (reg >> 2) + count; i++)
+ if (r300_reg_flags[i] != MARK_SAFE)
+ return 1;
return 0;
}
/* we expect offsets passed to the framebuffer to be either within video memory or
- within AGP space */
-static __inline__ int r300_check_offset(drm_radeon_private_t* dev_priv, u32 offset)
+ within AGP space */
+static __inline__ int r300_check_offset(drm_radeon_private_t * dev_priv,
+ u32 offset)
{
/* we realy want to check against end of video aperture
- but this value is not being kept.
- This code is correct for now (does the same thing as the
- code that sets MC_FB_LOCATION) in radeon_cp.c */
- if((offset>=dev_priv->fb_location) &&
- (offset<dev_priv->gart_vm_start))return 0;
- if((offset>=dev_priv->gart_vm_start) &&
- (offset<dev_priv->gart_vm_start+dev_priv->gart_size))return 0;
+ but this value is not being kept.
+ This code is correct for now (does the same thing as the
+ code that sets MC_FB_LOCATION) in radeon_cp.c */
+ if ((offset >= dev_priv->fb_location) &&
+ (offset < dev_priv->gart_vm_start))
+ return 0;
+ if ((offset >= dev_priv->gart_vm_start) &&
+ (offset < dev_priv->gart_vm_start + dev_priv->gart_size))
+ return 0;
return 1;
}
-static __inline__ int r300_emit_carefully_checked_packet0(drm_radeon_private_t* dev_priv,
- drm_radeon_cmd_buffer_t* cmdbuf,
- drm_r300_cmd_header_t header)
+static __inline__ int r300_emit_carefully_checked_packet0(drm_radeon_private_t *
+ dev_priv,
+ drm_radeon_kcmd_buffer_t
+ * cmdbuf,
+ drm_r300_cmd_header_t
+ header)
{
int reg;
int sz;
@@ -260,35 +273,40 @@ static __inline__ int r300_emit_carefully_checked_packet0(drm_radeon_private_t*
sz = header.packet0.count;
reg = (header.packet0.reghi << 8) | header.packet0.reglo;
-
- if((sz>64)||(sz<0)){
- DRM_ERROR("Cannot emit more than 64 values at a time (reg=%04x sz=%d)\n", reg, sz);
+
+ if ((sz > 64) || (sz < 0)) {
+ DRM_ERROR
+ ("Cannot emit more than 64 values at a time (reg=%04x sz=%d)\n",
+ reg, sz);
return DRM_ERR(EINVAL);
- }
- for(i=0;i<sz;i++){
- values[i]=((int __user*)cmdbuf->buf)[i];
- switch(r300_reg_flags[(reg>>2)+i]){
+ }
+ for (i = 0; i < sz; i++) {
+ values[i] = ((int *)cmdbuf->buf)[i];
+ switch (r300_reg_flags[(reg >> 2) + i]) {
case MARK_SAFE:
break;
case MARK_CHECK_OFFSET:
- if(r300_check_offset(dev_priv, (u32)values[i])){
- DRM_ERROR("Offset failed range check (reg=%04x sz=%d)\n", reg, sz);
+ if (r300_check_offset(dev_priv, (u32) values[i])) {
+ DRM_ERROR
+ ("Offset failed range check (reg=%04x sz=%d)\n",
+ reg, sz);
return DRM_ERR(EINVAL);
- }
+ }
break;
default:
- DRM_ERROR("Register %04x failed check as flag=%02x\n", reg+i*4, r300_reg_flags[(reg>>2)+i]);
+ DRM_ERROR("Register %04x failed check as flag=%02x\n",
+ reg + i * 4, r300_reg_flags[(reg >> 2) + i]);
return DRM_ERR(EINVAL);
- }
}
-
- BEGIN_RING(1+sz);
- OUT_RING( CP_PACKET0( reg, sz-1 ) );
- OUT_RING_TABLE( values, sz );
+ }
+
+ BEGIN_RING(1 + sz);
+ OUT_RING(CP_PACKET0(reg, sz - 1));
+ OUT_RING_TABLE(values, sz);
ADVANCE_RING();
- cmdbuf->buf += sz*4;
- cmdbuf->bufsz -= sz*4;
+ cmdbuf->buf += sz * 4;
+ cmdbuf->bufsz -= sz * 4;
return 0;
}
@@ -299,9 +317,9 @@ static __inline__ int r300_emit_carefully_checked_packet0(drm_radeon_private_t*
*
* Note that checks are performed on contents and addresses of the registers
*/
-static __inline__ int r300_emit_packet0(drm_radeon_private_t* dev_priv,
- drm_radeon_cmd_buffer_t* cmdbuf,
- drm_r300_cmd_header_t header)
+static __inline__ int r300_emit_packet0(drm_radeon_private_t * dev_priv,
+ drm_radeon_kcmd_buffer_t * cmdbuf,
+ drm_r300_cmd_header_t header)
{
int reg;
int sz;
@@ -313,39 +331,40 @@ static __inline__ int r300_emit_packet0(drm_radeon_private_t* dev_priv,
if (!sz)
return 0;
- if (sz*4 > cmdbuf->bufsz)
+ if (sz * 4 > cmdbuf->bufsz)
return DRM_ERR(EINVAL);
-
- if (reg+sz*4 >= 0x10000){
- DRM_ERROR("No such registers in hardware reg=%04x sz=%d\n", reg, sz);
+
+ if (reg + sz * 4 >= 0x10000) {
+ DRM_ERROR("No such registers in hardware reg=%04x sz=%d\n", reg,
+ sz);
return DRM_ERR(EINVAL);
- }
+ }
- if(r300_check_range(reg, sz)){
+ if (r300_check_range(reg, sz)) {
/* go and check everything */
- return r300_emit_carefully_checked_packet0(dev_priv, cmdbuf, header);
- }
+ return r300_emit_carefully_checked_packet0(dev_priv, cmdbuf,
+ header);
+ }
/* the rest of the data is safe to emit, whatever the values the user passed */
- BEGIN_RING(1+sz);
- OUT_RING( CP_PACKET0( reg, sz-1 ) );
- OUT_RING_TABLE( (int __user*)cmdbuf->buf, sz );
+ BEGIN_RING(1 + sz);
+ OUT_RING(CP_PACKET0(reg, sz - 1));
+ OUT_RING_TABLE((int *)cmdbuf->buf, sz);
ADVANCE_RING();
- cmdbuf->buf += sz*4;
- cmdbuf->bufsz -= sz*4;
+ cmdbuf->buf += sz * 4;
+ cmdbuf->bufsz -= sz * 4;
return 0;
}
-
/**
* Uploads user-supplied vertex program instructions or parameters onto
* the graphics card.
* Called by r300_do_cp_cmdbuf.
*/
-static __inline__ int r300_emit_vpu(drm_radeon_private_t* dev_priv,
- drm_radeon_cmd_buffer_t* cmdbuf,
+static __inline__ int r300_emit_vpu(drm_radeon_private_t * dev_priv,
+ drm_radeon_kcmd_buffer_t * cmdbuf,
drm_r300_cmd_header_t header)
{
int sz;
@@ -357,114 +376,121 @@ static __inline__ int r300_emit_vpu(drm_radeon_private_t* dev_priv,
if (!sz)
return 0;
- if (sz*16 > cmdbuf->bufsz)
+ if (sz * 16 > cmdbuf->bufsz)
return DRM_ERR(EINVAL);
- BEGIN_RING(5+sz*4);
+ BEGIN_RING(5 + sz * 4);
/* Wait for VAP to come to senses.. */
/* there is no need to emit it multiple times, (only once before VAP is programmed,
but this optimization is for later */
- OUT_RING_REG( R300_VAP_PVS_WAITIDLE, 0 );
- OUT_RING_REG( R300_VAP_PVS_UPLOAD_ADDRESS, addr );
- OUT_RING( CP_PACKET0_TABLE( R300_VAP_PVS_UPLOAD_DATA, sz*4 - 1 ) );
- OUT_RING_TABLE( (int __user*)cmdbuf->buf, sz*4 );
+ OUT_RING_REG(R300_VAP_PVS_WAITIDLE, 0);
+ OUT_RING_REG(R300_VAP_PVS_UPLOAD_ADDRESS, addr);
+ OUT_RING(CP_PACKET0_TABLE(R300_VAP_PVS_UPLOAD_DATA, sz * 4 - 1));
+ OUT_RING_TABLE((int *)cmdbuf->buf, sz * 4);
ADVANCE_RING();
- cmdbuf->buf += sz*16;
- cmdbuf->bufsz -= sz*16;
+ cmdbuf->buf += sz * 16;
+ cmdbuf->bufsz -= sz * 16;
return 0;
}
-
/**
* Emit a clear packet from userspace.
* Called by r300_emit_packet3.
*/
-static __inline__ int r300_emit_clear(drm_radeon_private_t* dev_priv,
- drm_radeon_cmd_buffer_t* cmdbuf)
+static __inline__ int r300_emit_clear(drm_radeon_private_t * dev_priv,
+ drm_radeon_kcmd_buffer_t * cmdbuf)
{
RING_LOCALS;
- if (8*4 > cmdbuf->bufsz)
+ if (8 * 4 > cmdbuf->bufsz)
return DRM_ERR(EINVAL);
BEGIN_RING(10);
- OUT_RING( CP_PACKET3( R200_3D_DRAW_IMMD_2, 8 ) );
- OUT_RING( R300_PRIM_TYPE_POINT|R300_PRIM_WALK_RING|
- (1<<R300_PRIM_NUM_VERTICES_SHIFT) );
- OUT_RING_TABLE( (int __user*)cmdbuf->buf, 8 );
+ OUT_RING(CP_PACKET3(R200_3D_DRAW_IMMD_2, 8));
+ OUT_RING(R300_PRIM_TYPE_POINT | R300_PRIM_WALK_RING |
+ (1 << R300_PRIM_NUM_VERTICES_SHIFT));
+ OUT_RING_TABLE((int *)cmdbuf->buf, 8);
ADVANCE_RING();
- cmdbuf->buf += 8*4;
- cmdbuf->bufsz -= 8*4;
+ cmdbuf->buf += 8 * 4;
+ cmdbuf->bufsz -= 8 * 4;
return 0;
}
-static __inline__ int r300_emit_3d_load_vbpntr(drm_radeon_private_t* dev_priv,
- drm_radeon_cmd_buffer_t* cmdbuf,
- u32 header)
+static __inline__ int r300_emit_3d_load_vbpntr(drm_radeon_private_t * dev_priv,
+ drm_radeon_kcmd_buffer_t * cmdbuf,
+ u32 header)
{
- int count, i,k;
- #define MAX_ARRAY_PACKET 64
+ int count, i, k;
+#define MAX_ARRAY_PACKET 64
u32 payload[MAX_ARRAY_PACKET];
u32 narrays;
RING_LOCALS;
- count=(header>>16) & 0x3fff;
-
- if((count+1)>MAX_ARRAY_PACKET){
- DRM_ERROR("Too large payload in 3D_LOAD_VBPNTR (count=%d)\n", count);
+ count = (header >> 16) & 0x3fff;
+
+ if ((count + 1) > MAX_ARRAY_PACKET) {
+ DRM_ERROR("Too large payload in 3D_LOAD_VBPNTR (count=%d)\n",
+ count);
return DRM_ERR(EINVAL);
- }
- memset(payload, 0, MAX_ARRAY_PACKET*4);
- memcpy(payload, cmdbuf->buf+4, (count+1)*4);
-
+ }
+ memset(payload, 0, MAX_ARRAY_PACKET * 4);
+ memcpy(payload, cmdbuf->buf + 4, (count + 1) * 4);
+
/* carefully check packet contents */
-
- narrays=payload[0];
- k=0;
- i=1;
- while((k<narrays) && (i<(count+1))){
- i++; /* skip attribute field */
- if(r300_check_offset(dev_priv, payload[i])){
- DRM_ERROR("Offset failed range check (k=%d i=%d) while processing 3D_LOAD_VBPNTR packet.\n", k, i);
+
+ narrays = payload[0];
+ k = 0;
+ i = 1;
+ while ((k < narrays) && (i < (count + 1))) {
+ i++; /* skip attribute field */
+ if (r300_check_offset(dev_priv, payload[i])) {
+ DRM_ERROR
+ ("Offset failed range check (k=%d i=%d) while processing 3D_LOAD_VBPNTR packet.\n",
+ k, i);
return DRM_ERR(EINVAL);
- }
+ }
k++;
i++;
- if(k==narrays)break;
+ if (k == narrays)
+ break;
/* have one more to process, they come in pairs */
- if(r300_check_offset(dev_priv, payload[i])){
- DRM_ERROR("Offset failed range check (k=%d i=%d) while processing 3D_LOAD_VBPNTR packet.\n", k, i);
+ if (r300_check_offset(dev_priv, payload[i])) {
+ DRM_ERROR
+ ("Offset failed range check (k=%d i=%d) while processing 3D_LOAD_VBPNTR packet.\n",
+ k, i);
return DRM_ERR(EINVAL);
- }
- k++;
- i++;
}
+ k++;
+ i++;
+ }
/* do the counts match what we expect ? */
- if((k!=narrays) || (i!=(count+1))){
- DRM_ERROR("Malformed 3D_LOAD_VBPNTR packet (k=%d i=%d narrays=%d count+1=%d).\n", k, i, narrays, count+1);
+ if ((k != narrays) || (i != (count + 1))) {
+ DRM_ERROR
+ ("Malformed 3D_LOAD_VBPNTR packet (k=%d i=%d narrays=%d count+1=%d).\n",
+ k, i, narrays, count + 1);
return DRM_ERR(EINVAL);
- }
+ }
/* all clear, output packet */
- BEGIN_RING(count+2);
+ BEGIN_RING(count + 2);
OUT_RING(header);
- OUT_RING_TABLE(payload, count+1);
+ OUT_RING_TABLE(payload, count + 1);
ADVANCE_RING();
- cmdbuf->buf += (count+2)*4;
- cmdbuf->bufsz -= (count+2)*4;
+ cmdbuf->buf += (count + 2) * 4;
+ cmdbuf->bufsz -= (count + 2) * 4;
return 0;
}
-static __inline__ int r300_emit_raw_packet3(drm_radeon_private_t* dev_priv,
- drm_radeon_cmd_buffer_t* cmdbuf)
+static __inline__ int r300_emit_raw_packet3(drm_radeon_private_t * dev_priv,
+ drm_radeon_kcmd_buffer_t * cmdbuf)
{
u32 header;
int count;
@@ -473,36 +499,37 @@ static __inline__ int r300_emit_raw_packet3(drm_radeon_private_t* dev_priv,
if (4 > cmdbuf->bufsz)
return DRM_ERR(EINVAL);
- /* Fixme !! This simply emits a packet without much checking.
+ /* Fixme !! This simply emits a packet without much checking.
We need to be smarter. */
/* obtain first word - actual packet3 header */
- header = *(u32 __user*)cmdbuf->buf;
+ header = *(u32 *) cmdbuf->buf;
/* Is it packet 3 ? */
- if( (header>>30)!=0x3 ) {
+ if ((header >> 30) != 0x3) {
DRM_ERROR("Not a packet3 header (0x%08x)\n", header);
return DRM_ERR(EINVAL);
- }
+ }
- count=(header>>16) & 0x3fff;
+ count = (header >> 16) & 0x3fff;
/* Check again now that we know how much data to expect */
- if ((count+2)*4 > cmdbuf->bufsz){
- DRM_ERROR("Expected packet3 of length %d but have only %d bytes left\n",
- (count+2)*4, cmdbuf->bufsz);
+ if ((count + 2) * 4 > cmdbuf->bufsz) {
+ DRM_ERROR
+ ("Expected packet3 of length %d but have only %d bytes left\n",
+ (count + 2) * 4, cmdbuf->bufsz);
return DRM_ERR(EINVAL);
- }
+ }
/* Is it a packet type we know about ? */
- switch(header & 0xff00){
- case RADEON_3D_LOAD_VBPNTR: /* load vertex array pointers */
+ switch (header & 0xff00) {
+ case RADEON_3D_LOAD_VBPNTR: /* load vertex array pointers */
return r300_emit_3d_load_vbpntr(dev_priv, cmdbuf, header);
- case RADEON_CP_3D_DRAW_IMMD_2: /* triggers drawing using in-packet vertex data */
- case RADEON_CP_3D_DRAW_VBUF_2: /* triggers drawing of vertex buffers setup elsewhere */
- case RADEON_CP_3D_DRAW_INDX_2: /* triggers drawing using indices to vertex buffer */
- case RADEON_CP_INDX_BUFFER: /* DRAW_INDX_2 without INDX_BUFFER seems to lock up the gpu */
+ case RADEON_CP_3D_DRAW_IMMD_2: /* triggers drawing using in-packet vertex data */
+ case RADEON_CP_3D_DRAW_VBUF_2: /* triggers drawing of vertex buffers setup elsewhere */
+ case RADEON_CP_3D_DRAW_INDX_2: /* triggers drawing using indices to vertex buffer */
+ case RADEON_CP_INDX_BUFFER: /* DRAW_INDX_2 without INDX_BUFFER seems to lock up the gpu */
case RADEON_WAIT_FOR_IDLE:
case RADEON_CP_NOP:
/* these packets are safe */
@@ -510,32 +537,30 @@ static __inline__ int r300_emit_raw_packet3(drm_radeon_private_t* dev_priv,
default:
DRM_ERROR("Unknown packet3 header (0x%08x)\n", header);
return DRM_ERR(EINVAL);
- }
-
+ }
- BEGIN_RING(count+2);
+ BEGIN_RING(count + 2);
OUT_RING(header);
- OUT_RING_TABLE( (int __user*)(cmdbuf->buf+4), count+1);
+ OUT_RING_TABLE((int *)(cmdbuf->buf + 4), count + 1);
ADVANCE_RING();
- cmdbuf->buf += (count+2)*4;
- cmdbuf->bufsz -= (count+2)*4;
+ cmdbuf->buf += (count + 2) * 4;
+ cmdbuf->bufsz -= (count + 2) * 4;
return 0;
}
-
/**
* Emit a rendering packet3 from userspace.
* Called by r300_do_cp_cmdbuf.
*/
-static __inline__ int r300_emit_packet3(drm_radeon_private_t* dev_priv,
- drm_radeon_cmd_buffer_t* cmdbuf,
+static __inline__ int r300_emit_packet3(drm_radeon_private_t * dev_priv,
+ drm_radeon_kcmd_buffer_t * cmdbuf,
drm_r300_cmd_header_t header)
{
int n;
int ret;
- char __user* orig_buf = cmdbuf->buf;
+ char *orig_buf = cmdbuf->buf;
int orig_bufsz = cmdbuf->bufsz;
/* This is a do-while-loop so that we run the interior at least once,
@@ -550,16 +575,16 @@ static __inline__ int r300_emit_packet3(drm_radeon_private_t* dev_priv,
cmdbuf->buf = orig_buf;
cmdbuf->bufsz = orig_bufsz;
- }
+ }
- switch(header.packet3.packet) {
+ switch (header.packet3.packet) {
case R300_CMD_PACKET3_CLEAR:
DRM_DEBUG("R300_CMD_PACKET3_CLEAR\n");
ret = r300_emit_clear(dev_priv, cmdbuf);
if (ret) {
DRM_ERROR("r300_emit_clear failed\n");
return ret;
- }
+ }
break;
case R300_CMD_PACKET3_RAW:
@@ -568,18 +593,18 @@ static __inline__ int r300_emit_packet3(drm_radeon_private_t* dev_priv,
if (ret) {
DRM_ERROR("r300_emit_raw_packet3 failed\n");
return ret;
- }
+ }
break;
default:
DRM_ERROR("bad packet3 type %i at %p\n",
- header.packet3.packet,
- cmdbuf->buf - sizeof(header));
+ header.packet3.packet,
+ cmdbuf->buf - sizeof(header));
return DRM_ERR(EINVAL);
- }
+ }
n += R300_SIMULTANEOUS_CLIPRECTS;
- } while(n < cmdbuf->nbox);
+ } while (n < cmdbuf->nbox);
return 0;
}
@@ -598,21 +623,20 @@ static __inline__ int r300_emit_packet3(drm_radeon_private_t* dev_priv,
/**
* Emit the sequence to pacify R300.
*/
-static __inline__ void r300_pacify(drm_radeon_private_t* dev_priv)
+static __inline__ void r300_pacify(drm_radeon_private_t * dev_priv)
{
RING_LOCALS;
BEGIN_RING(6);
- OUT_RING( CP_PACKET0( R300_RB3D_DSTCACHE_CTLSTAT, 0 ) );
- OUT_RING( 0xa );
- OUT_RING( CP_PACKET0( 0x4f18, 0 ) );
- OUT_RING( 0x3 );
- OUT_RING( CP_PACKET3( RADEON_CP_NOP, 0 ) );
- OUT_RING( 0x0 );
+ OUT_RING(CP_PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0));
+ OUT_RING(0xa);
+ OUT_RING(CP_PACKET0(0x4f18, 0));
+ OUT_RING(0x3);
+ OUT_RING(CP_PACKET3(RADEON_CP_NOP, 0));
+ OUT_RING(0x0);
ADVANCE_RING();
}
-
/**
* Called by r300_do_cp_cmdbuf to update the internal buffer age and state.
* The actual age emit is done by r300_do_cp_cmdbuf, which is why you must
@@ -628,20 +652,18 @@ static void r300_discard_buffer(drm_device_t * dev, drm_buf_t * buf)
buf->used = 0;
}
-
/**
* Parses and validates a user-supplied command buffer and emits appropriate
* commands on the DMA ring buffer.
* Called by the ioctl handler function radeon_cp_cmdbuf.
*/
-int r300_do_cp_cmdbuf(drm_device_t* dev,
- DRMFILE filp,
- drm_file_t* filp_priv,
- drm_radeon_cmd_buffer_t* cmdbuf)
+int r300_do_cp_cmdbuf(drm_device_t * dev,
+ DRMFILE filp,
+ drm_file_t * filp_priv, drm_radeon_kcmd_buffer_t * cmdbuf)
{
drm_radeon_private_t *dev_priv = dev->dev_private;
- drm_device_dma_t *dma = dev->dma;
- drm_buf_t *buf = NULL;
+ drm_device_dma_t *dma = dev->dma;
+ drm_buf_t *buf = NULL;
int emit_dispatch_age = 0;
int ret = 0;
@@ -655,9 +677,9 @@ int r300_do_cp_cmdbuf(drm_device_t* dev,
ret = r300_emit_cliprects(dev_priv, cmdbuf, 0);
if (ret)
goto cleanup;
- }
+ }
- while(cmdbuf->bufsz >= sizeof(drm_r300_cmd_header_t)) {
+ while (cmdbuf->bufsz >= sizeof(drm_r300_cmd_header_t)) {
int idx;
drm_r300_cmd_header_t header;
@@ -666,14 +688,14 @@ int r300_do_cp_cmdbuf(drm_device_t* dev,
cmdbuf->buf += sizeof(header);
cmdbuf->bufsz -= sizeof(header);
- switch(header.header.cmd_type) {
- case R300_CMD_PACKET0:
+ switch (header.header.cmd_type) {
+ case R300_CMD_PACKET0:
DRM_DEBUG("R300_CMD_PACKET0\n");
ret = r300_emit_packet0(dev_priv, cmdbuf, header);
if (ret) {
DRM_ERROR("r300_emit_packet0 failed\n");
goto cleanup;
- }
+ }
break;
case R300_CMD_VPU:
@@ -682,7 +704,7 @@ int r300_do_cp_cmdbuf(drm_device_t* dev,
if (ret) {
DRM_ERROR("r300_emit_vpu failed\n");
goto cleanup;
- }
+ }
break;
case R300_CMD_PACKET3:
@@ -691,26 +713,26 @@ int r300_do_cp_cmdbuf(drm_device_t* dev,
if (ret) {
DRM_ERROR("r300_emit_packet3 failed\n");
goto cleanup;
- }
+ }
break;
case R300_CMD_END3D:
DRM_DEBUG("R300_CMD_END3D\n");
- /* TODO:
- Ideally userspace driver should not need to issue this call,
- i.e. the drm driver should issue it automatically and prevent
- lockups.
-
- In practice, we do not understand why this call is needed and what
- it does (except for some vague guesses that it has to do with cache
- coherence) and so the user space driver does it.
-
- Once we are sure which uses prevent lockups the code could be moved
- into the kernel and the userspace driver will not
- need to use this command.
-
- Note that issuing this command does not hurt anything
- except, possibly, performance */
+ /* TODO:
+ Ideally userspace driver should not need to issue this call,
+ i.e. the drm driver should issue it automatically and prevent
+ lockups.
+
+ In practice, we do not understand why this call is needed and what
+ it does (except for some vague guesses that it has to do with cache
+ coherence) and so the user space driver does it.
+
+ Once we are sure which uses prevent lockups the code could be moved
+ into the kernel and the userspace driver will not
+ need to use this command.
+
+ Note that issuing this command does not hurt anything
+ except, possibly, performance */
r300_pacify(dev_priv);
break;
@@ -722,7 +744,7 @@ int r300_do_cp_cmdbuf(drm_device_t* dev,
RING_LOCALS;
BEGIN_RING(header.delay.count);
- for(i=0;i<header.delay.count;i++)
+ for (i = 0; i < header.delay.count; i++)
OUT_RING(RADEON_CP_PACKET2);
ADVANCE_RING();
}
@@ -730,53 +752,54 @@ int r300_do_cp_cmdbuf(drm_device_t* dev,
case R300_CMD_DMA_DISCARD:
DRM_DEBUG("RADEON_CMD_DMA_DISCARD\n");
- idx = header.dma.buf_idx;
- if (idx < 0 || idx >= dma->buf_count) {
- DRM_ERROR("buffer index %d (of %d max)\n",
- idx, dma->buf_count - 1);
+ idx = header.dma.buf_idx;
+ if (idx < 0 || idx >= dma->buf_count) {
+ DRM_ERROR("buffer index %d (of %d max)\n",
+ idx, dma->buf_count - 1);
ret = DRM_ERR(EINVAL);
- goto cleanup;
- }
-
- buf = dma->buflist[idx];
- if (buf->filp != filp || buf->pending) {
- DRM_ERROR("bad buffer %p %p %d\n",
- buf->filp, filp, buf->pending);
- ret = DRM_ERR(EINVAL);
goto cleanup;
- }
+ }
+
+ buf = dma->buflist[idx];
+ if (buf->filp != filp || buf->pending) {
+ DRM_ERROR("bad buffer %p %p %d\n",
+ buf->filp, filp, buf->pending);
+ ret = DRM_ERR(EINVAL);
+ goto cleanup;
+ }
emit_dispatch_age = 1;
r300_discard_buffer(dev, buf);
- break;
+ break;
case R300_CMD_WAIT:
/* simple enough, we can do it here */
DRM_DEBUG("R300_CMD_WAIT\n");
- if(header.wait.flags==0)break; /* nothing to do */
+ if (header.wait.flags == 0)
+ break; /* nothing to do */
{
RING_LOCALS;
BEGIN_RING(2);
- OUT_RING( CP_PACKET0( RADEON_WAIT_UNTIL, 0 ) );
- OUT_RING( (header.wait.flags & 0xf)<<14 );
+ OUT_RING(CP_PACKET0(RADEON_WAIT_UNTIL, 0));
+ OUT_RING((header.wait.flags & 0xf) << 14);
ADVANCE_RING();
}
break;
default:
DRM_ERROR("bad cmd_type %i at %p\n",
- header.header.cmd_type,
+ header.header.cmd_type,
cmdbuf->buf - sizeof(header));
ret = DRM_ERR(EINVAL);
goto cleanup;
- }
+ }
}
DRM_DEBUG("END\n");
-cleanup:
+ cleanup:
r300_pacify(dev_priv);
/* We emit the vertex buffer age here, outside the pacifier "brackets"
@@ -792,10 +815,9 @@ cleanup:
BEGIN_RING(2);
RADEON_DISPATCH_AGE(dev_priv->sarea_priv->last_dispatch);
ADVANCE_RING();
- }
+ }
COMMIT_RING();
return ret;
}
-
diff --git a/drivers/char/drm/r300_reg.h b/drivers/char/drm/r300_reg.h
index c3e7ca3dbe3d..e5b73c002394 100644
--- a/drivers/char/drm/r300_reg.h
+++ b/drivers/char/drm/r300_reg.h
@@ -36,7 +36,6 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
# define R300_MC_MISC__MC_SAME_PAGE_PRIO_SHIFT 24
# define R300_MC_MISC__MC_GLOBW_INIT_LAT_SHIFT 28
-
#define R300_MC_INIT_GFX_LAT_TIMER 0x154
# define R300_MC_MISC__MC_G3D0R_INIT_LAT_SHIFT 0
# define R300_MC_MISC__MC_G3D1R_INIT_LAT_SHIFT 4
@@ -62,7 +61,6 @@ I am fairly certain that they are correct unless stated otherwise in comments.
#define R300_SE_VPORT_ZSCALE 0x1DA8
#define R300_SE_VPORT_ZOFFSET 0x1DAC
-
/* This register is written directly and also starts data section in many 3d CP_PACKET3's */
#define R300_VAP_VF_CNTL 0x2084
@@ -93,17 +91,17 @@ I am fairly certain that they are correct unless stated otherwise in comments.
/* index size - when not set the indices are assumed to be 16 bit */
# define R300_VAP_VF_CNTL__INDEX_SIZE_32bit (1<<11)
- /* number of vertices */
+ /* number of vertices */
# define R300_VAP_VF_CNTL__NUM_VERTICES__SHIFT 16
/* BEGIN: Wild guesses */
#define R300_VAP_OUTPUT_VTX_FMT_0 0x2090
# define R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT (1<<0)
# define R300_VAP_OUTPUT_VTX_FMT_0__COLOR_PRESENT (1<<1)
-# define R300_VAP_OUTPUT_VTX_FMT_0__COLOR_1_PRESENT (1<<2) /* GUESS */
-# define R300_VAP_OUTPUT_VTX_FMT_0__COLOR_2_PRESENT (1<<3) /* GUESS */
-# define R300_VAP_OUTPUT_VTX_FMT_0__COLOR_3_PRESENT (1<<4) /* GUESS */
-# define R300_VAP_OUTPUT_VTX_FMT_0__PT_SIZE_PRESENT (1<<16) /* GUESS */
+# define R300_VAP_OUTPUT_VTX_FMT_0__COLOR_1_PRESENT (1<<2) /* GUESS */
+# define R300_VAP_OUTPUT_VTX_FMT_0__COLOR_2_PRESENT (1<<3) /* GUESS */
+# define R300_VAP_OUTPUT_VTX_FMT_0__COLOR_3_PRESENT (1<<4) /* GUESS */
+# define R300_VAP_OUTPUT_VTX_FMT_0__PT_SIZE_PRESENT (1<<16) /* GUESS */
#define R300_VAP_OUTPUT_VTX_FMT_1 0x2094
# define R300_VAP_OUTPUT_VTX_FMT_1__TEX_0_COMP_CNT_SHIFT 0
@@ -159,14 +157,14 @@ I am fairly certain that they are correct unless stated otherwise in comments.
# define R300_INPUT_ROUTE_COMPONENTS_2 (1 << 0)
# define R300_INPUT_ROUTE_COMPONENTS_3 (2 << 0)
# define R300_INPUT_ROUTE_COMPONENTS_4 (3 << 0)
-# define R300_INPUT_ROUTE_COMPONENTS_RGBA (4 << 0) /* GUESS */
+# define R300_INPUT_ROUTE_COMPONENTS_RGBA (4 << 0) /* GUESS */
# define R300_VAP_INPUT_ROUTE_IDX_SHIFT 8
-# define R300_VAP_INPUT_ROUTE_IDX_MASK (31 << 8) /* GUESS */
+# define R300_VAP_INPUT_ROUTE_IDX_MASK (31 << 8) /* GUESS */
# define R300_VAP_INPUT_ROUTE_END (1 << 13)
-# define R300_INPUT_ROUTE_IMMEDIATE_MODE (0 << 14) /* GUESS */
-# define R300_INPUT_ROUTE_FLOAT (1 << 14) /* GUESS */
-# define R300_INPUT_ROUTE_UNSIGNED_BYTE (2 << 14) /* GUESS */
-# define R300_INPUT_ROUTE_FLOAT_COLOR (3 << 14) /* GUESS */
+# define R300_INPUT_ROUTE_IMMEDIATE_MODE (0 << 14) /* GUESS */
+# define R300_INPUT_ROUTE_FLOAT (1 << 14) /* GUESS */
+# define R300_INPUT_ROUTE_UNSIGNED_BYTE (2 << 14) /* GUESS */
+# define R300_INPUT_ROUTE_FLOAT_COLOR (3 << 14) /* GUESS */
#define R300_VAP_INPUT_ROUTE_0_1 0x2154
#define R300_VAP_INPUT_ROUTE_0_2 0x2158
#define R300_VAP_INPUT_ROUTE_0_3 0x215C
@@ -188,12 +186,12 @@ I am fairly certain that they are correct unless stated otherwise in comments.
# define R300_INPUT_CNTL_COLOR 0x00000004
# define R300_INPUT_CNTL_TC0 0x00000400
# define R300_INPUT_CNTL_TC1 0x00000800
-# define R300_INPUT_CNTL_TC2 0x00001000 /* GUESS */
-# define R300_INPUT_CNTL_TC3 0x00002000 /* GUESS */
-# define R300_INPUT_CNTL_TC4 0x00004000 /* GUESS */
-# define R300_INPUT_CNTL_TC5 0x00008000 /* GUESS */
-# define R300_INPUT_CNTL_TC6 0x00010000 /* GUESS */
-# define R300_INPUT_CNTL_TC7 0x00020000 /* GUESS */
+# define R300_INPUT_CNTL_TC2 0x00001000 /* GUESS */
+# define R300_INPUT_CNTL_TC3 0x00002000 /* GUESS */
+# define R300_INPUT_CNTL_TC4 0x00004000 /* GUESS */
+# define R300_INPUT_CNTL_TC5 0x00008000 /* GUESS */
+# define R300_INPUT_CNTL_TC6 0x00010000 /* GUESS */
+# define R300_INPUT_CNTL_TC7 0x00020000 /* GUESS */
/* gap */
/* Words parallel to INPUT_ROUTE_0; All words that are active in INPUT_ROUTE_0
@@ -270,12 +268,12 @@ I am fairly certain that they are correct unless stated otherwise in comments.
// rendering commands and overwriting vertex program parameters.
// Therefore, I suspect writing zero to 0x2284 synchronizes the engine and
// avoids bugs caused by still running shaders reading bad data from memory. */
-#define R300_VAP_PVS_WAITIDLE 0x2284 /* GUESS */
+#define R300_VAP_PVS_WAITIDLE 0x2284 /* GUESS */
/* Absolutely no clue what this register is about. */
#define R300_VAP_UNKNOWN_2288 0x2288
-# define R300_2288_R300 0x00750000 /* -- nh */
-# define R300_2288_RV350 0x0000FFFF /* -- Vladimir */
+# define R300_2288_R300 0x00750000 /* -- nh */
+# define R300_2288_RV350 0x0000FFFF /* -- Vladimir */
/* gap */
/* Addresses are relative to the vertex program instruction area of the
@@ -286,10 +284,10 @@ I am fairly certain that they are correct unless stated otherwise in comments.
// experiments so far have shown that both *must* point to an instruction
// inside the vertex program, otherwise the GPU locks up.
// fglrx usually sets CNTL_3_UNKNOWN to the end of the program and
-// CNTL_1_UNKNOWN points to instruction where last write to position takes place.
+// CNTL_1_UNKNOWN points to instruction where last write to position takes place.
// Most likely this is used to ignore rest of the program in cases where group of verts arent visible.
// For some reason this "section" is sometimes accepted other instruction that have
-// no relationship with position calculations.
+// no relationship with position calculations.
*/
#define R300_VAP_PVS_CNTL_1 0x22D0
# define R300_PVS_CNTL_1_PROGRAM_START_SHIFT 0
@@ -308,13 +306,13 @@ I am fairly certain that they are correct unless stated otherwise in comments.
#define R300_VAP_VTX_COLOR_R 0x2464
#define R300_VAP_VTX_COLOR_G 0x2468
#define R300_VAP_VTX_COLOR_B 0x246C
-#define R300_VAP_VTX_POS_0_X_1 0x2490 /* used for glVertex2*() */
+#define R300_VAP_VTX_POS_0_X_1 0x2490 /* used for glVertex2*() */
#define R300_VAP_VTX_POS_0_Y_1 0x2494
-#define R300_VAP_VTX_COLOR_PKD 0x249C /* RGBA */
-#define R300_VAP_VTX_POS_0_X_2 0x24A0 /* used for glVertex3*() */
+#define R300_VAP_VTX_COLOR_PKD 0x249C /* RGBA */
+#define R300_VAP_VTX_POS_0_X_2 0x24A0 /* used for glVertex3*() */
#define R300_VAP_VTX_POS_0_Y_2 0x24A4
#define R300_VAP_VTX_POS_0_Z_2 0x24A8
-#define R300_VAP_VTX_END_OF_PKT 0x24AC /* write 0 to indicate end of packet? */
+#define R300_VAP_VTX_END_OF_PKT 0x24AC /* write 0 to indicate end of packet? */
/* gap */
@@ -385,7 +383,6 @@ I am fairly certain that they are correct unless stated otherwise in comments.
# define R300_GB_MSPOS1__MS_Y5_SHIFT 20
# define R300_GB_MSPOS1__MSBD1 24
-
#define R300_GB_TILE_CONFIG 0x4018
# define R300_GB_TILE_ENABLE (1<<0)
# define R300_GB_TILE_PIPE_COUNT_RV300 0
@@ -478,9 +475,9 @@ I am fairly certain that they are correct unless stated otherwise in comments.
// framebuffer. */
#define R300_RE_POINTSIZE 0x421C
# define R300_POINTSIZE_Y_SHIFT 0
-# define R300_POINTSIZE_Y_MASK (0xFFFF << 0) /* GUESS */
+# define R300_POINTSIZE_Y_MASK (0xFFFF << 0) /* GUESS */
# define R300_POINTSIZE_X_SHIFT 16
-# define R300_POINTSIZE_X_MASK (0xFFFF << 16) /* GUESS */
+# define R300_POINTSIZE_X_MASK (0xFFFF << 16) /* GUESS */
# define R300_POINTSIZE_MAX (R300_POINTSIZE_Y_MASK / 6)
/* The line width is given in multiples of 6.
@@ -491,7 +488,7 @@ I am fairly certain that they are correct unless stated otherwise in comments.
*/
#define R300_RE_LINE_CNT 0x4234
# define R300_LINESIZE_SHIFT 0
-# define R300_LINESIZE_MASK (0xFFFF << 0) /* GUESS */
+# define R300_LINESIZE_MASK (0xFFFF << 0) /* GUESS */
# define R300_LINESIZE_MAX (R300_LINESIZE_MASK / 6)
# define R300_LINE_CNT_HO (1 << 16)
# define R300_LINE_CNT_VE (1 << 17)
@@ -513,8 +510,8 @@ I am fairly certain that they are correct unless stated otherwise in comments.
# define R300_PM_BACK_LINE (1 << 7)
# define R300_PM_BACK_FILL (1 << 8)
-/* Not sure why there are duplicate of factor and constant values.
- My best guess so far is that there are seperate zbiases for test and write.
+/* Not sure why there are duplicate of factor and constant values.
+ My best guess so far is that there are seperate zbiases for test and write.
Ordering might be wrong.
Some of the tests indicate that fgl has a fallback implementation of zbias
via pixel shaders. */
@@ -540,7 +537,6 @@ I am fairly certain that they are correct unless stated otherwise in comments.
# define R300_FRONT_FACE_CCW (0 << 2)
# define R300_FRONT_FACE_CW (1 << 2)
-
/* BEGIN: Rasterization / Interpolators - many guesses
// 0_UNKNOWN_18 has always been set except for clear operations.
// TC_CNT is the number of incoming texture coordinate sets (i.e. it depends
@@ -548,7 +544,7 @@ I am fairly certain that they are correct unless stated otherwise in comments.
#define R300_RS_CNTL_0 0x4300
# define R300_RS_CNTL_TC_CNT_SHIFT 2
# define R300_RS_CNTL_TC_CNT_MASK (7 << 2)
-# define R300_RS_CNTL_CI_CNT_SHIFT 7 /* number of color interpolators used */
+# define R300_RS_CNTL_CI_CNT_SHIFT 7 /* number of color interpolators used */
# define R300_RS_CNTL_0_UNKNOWN_18 (1 << 18)
/* Guess: RS_CNTL_1 holds the index of the highest used RS_ROUTE_n register. */
#define R300_RS_CNTL_1 0x4304
@@ -585,29 +581,29 @@ I am fairly certain that they are correct unless stated otherwise in comments.
#define R300_RS_ROUTE_0 0x4330
#define R300_RS_ROUTE_1 0x4334
#define R300_RS_ROUTE_2 0x4338
-#define R300_RS_ROUTE_3 0x433C /* GUESS */
-#define R300_RS_ROUTE_4 0x4340 /* GUESS */
-#define R300_RS_ROUTE_5 0x4344 /* GUESS */
-#define R300_RS_ROUTE_6 0x4348 /* GUESS */
-#define R300_RS_ROUTE_7 0x434C /* GUESS */
+#define R300_RS_ROUTE_3 0x433C /* GUESS */
+#define R300_RS_ROUTE_4 0x4340 /* GUESS */
+#define R300_RS_ROUTE_5 0x4344 /* GUESS */
+#define R300_RS_ROUTE_6 0x4348 /* GUESS */
+#define R300_RS_ROUTE_7 0x434C /* GUESS */
# define R300_RS_ROUTE_SOURCE_INTERP_0 0
# define R300_RS_ROUTE_SOURCE_INTERP_1 1
# define R300_RS_ROUTE_SOURCE_INTERP_2 2
# define R300_RS_ROUTE_SOURCE_INTERP_3 3
# define R300_RS_ROUTE_SOURCE_INTERP_4 4
-# define R300_RS_ROUTE_SOURCE_INTERP_5 5 /* GUESS */
-# define R300_RS_ROUTE_SOURCE_INTERP_6 6 /* GUESS */
-# define R300_RS_ROUTE_SOURCE_INTERP_7 7 /* GUESS */
-# define R300_RS_ROUTE_ENABLE (1 << 3) /* GUESS */
+# define R300_RS_ROUTE_SOURCE_INTERP_5 5 /* GUESS */
+# define R300_RS_ROUTE_SOURCE_INTERP_6 6 /* GUESS */
+# define R300_RS_ROUTE_SOURCE_INTERP_7 7 /* GUESS */
+# define R300_RS_ROUTE_ENABLE (1 << 3) /* GUESS */
# define R300_RS_ROUTE_DEST_SHIFT 6
-# define R300_RS_ROUTE_DEST_MASK (31 << 6) /* GUESS */
+# define R300_RS_ROUTE_DEST_MASK (31 << 6) /* GUESS */
/* Special handling for color: When the fragment program uses color,
// the ROUTE_0_COLOR bit is set and ROUTE_0_COLOR_DEST contains the
// color register index. */
# define R300_RS_ROUTE_0_COLOR (1 << 14)
# define R300_RS_ROUTE_0_COLOR_DEST_SHIFT 17
-# define R300_RS_ROUTE_0_COLOR_DEST_MASK (31 << 17) /* GUESS */
+# define R300_RS_ROUTE_0_COLOR_DEST_MASK (31 << 17) /* GUESS */
/* As above, but for secondary color */
# define R300_RS_ROUTE_1_COLOR1 (1 << 14)
# define R300_RS_ROUTE_1_COLOR1_DEST_SHIFT 17
@@ -721,7 +717,7 @@ I am fairly certain that they are correct unless stated otherwise in comments.
# define R300_TX_HEIGHTMASK_SHIFT 11
# define R300_TX_HEIGHTMASK_MASK (2047 << 11)
# define R300_TX_UNK23 (1 << 23)
-# define R300_TX_SIZE_SHIFT 26 /* largest of width, height */
+# define R300_TX_SIZE_SHIFT 26 /* largest of width, height */
# define R300_TX_SIZE_MASK (15 << 26)
#define R300_TX_FORMAT_0 0x44C0
/* The interpretation of the format word by Wladimir van der Laan */
@@ -746,12 +742,12 @@ I am fairly certain that they are correct unless stated otherwise in comments.
# define R300_TX_FORMAT_DXT1 0xF
# define R300_TX_FORMAT_DXT3 0x10
# define R300_TX_FORMAT_DXT5 0x11
-# define R300_TX_FORMAT_D3DMFT_CxV8U8 0x12 /* no swizzle */
-# define R300_TX_FORMAT_A8R8G8B8 0x13 /* no swizzle */
-# define R300_TX_FORMAT_B8G8_B8G8 0x14 /* no swizzle */
-# define R300_TX_FORMAT_G8R8_G8B8 0x15 /* no swizzle */
+# define R300_TX_FORMAT_D3DMFT_CxV8U8 0x12 /* no swizzle */
+# define R300_TX_FORMAT_A8R8G8B8 0x13 /* no swizzle */
+# define R300_TX_FORMAT_B8G8_B8G8 0x14 /* no swizzle */
+# define R300_TX_FORMAT_G8R8_G8B8 0x15 /* no swizzle */
/* 0x16 - some 16 bit green format.. ?? */
-# define R300_TX_FORMAT_UNK25 (1 << 25) /* no swizzle */
+# define R300_TX_FORMAT_UNK25 (1 << 25) /* no swizzle */
/* gap */
/* Floating point formats */
@@ -777,8 +773,8 @@ I am fairly certain that they are correct unless stated otherwise in comments.
# define R300_TX_FORMAT_W 3
# define R300_TX_FORMAT_ZERO 4
# define R300_TX_FORMAT_ONE 5
-# define R300_TX_FORMAT_CUT_Z 6 /* 2.0*Z, everything above 1.0 is set to 0.0 */
-# define R300_TX_FORMAT_CUT_W 7 /* 2.0*W, everything above 1.0 is set to 0.0 */
+# define R300_TX_FORMAT_CUT_Z 6 /* 2.0*Z, everything above 1.0 is set to 0.0 */
+# define R300_TX_FORMAT_CUT_W 7 /* 2.0*W, everything above 1.0 is set to 0.0 */
# define R300_TX_FORMAT_B_SHIFT 18
# define R300_TX_FORMAT_G_SHIFT 15
@@ -811,7 +807,7 @@ I am fairly certain that they are correct unless stated otherwise in comments.
# define R300_TXO_OFFSET_SHIFT 5
/* END */
#define R300_TX_UNK4_0 0x4580
-#define R300_TX_BORDER_COLOR_0 0x45C0 //ff00ff00 == { 0, 1.0, 0, 1.0 }
+#define R300_TX_BORDER_COLOR_0 0x45C0 //ff00ff00 == { 0, 1.0, 0, 1.0 }
/* END */
@@ -844,9 +840,9 @@ I am fairly certain that they are correct unless stated otherwise in comments.
# define R300_PFS_CNTL_ALU_END_SHIFT 6
# define R300_PFS_CNTL_ALU_END_MASK (63 << 0)
# define R300_PFS_CNTL_TEX_OFFSET_SHIFT 12
-# define R300_PFS_CNTL_TEX_OFFSET_MASK (31 << 12) /* GUESS */
+# define R300_PFS_CNTL_TEX_OFFSET_MASK (31 << 12) /* GUESS */
# define R300_PFS_CNTL_TEX_END_SHIFT 18
-# define R300_PFS_CNTL_TEX_END_MASK (31 << 18) /* GUESS */
+# define R300_PFS_CNTL_TEX_END_MASK (31 << 18) /* GUESS */
/* gap */
/* Nodes are stored backwards. The last active node is always stored in
@@ -877,11 +873,11 @@ I am fairly certain that they are correct unless stated otherwise in comments.
#define R300_PFS_TEXI_0 0x4620
# define R300_FPITX_SRC_SHIFT 0
# define R300_FPITX_SRC_MASK (31 << 0)
-# define R300_FPITX_SRC_CONST (1 << 5) /* GUESS */
+# define R300_FPITX_SRC_CONST (1 << 5) /* GUESS */
# define R300_FPITX_DST_SHIFT 6
# define R300_FPITX_DST_MASK (31 << 6)
# define R300_FPITX_IMAGE_SHIFT 11
-# define R300_FPITX_IMAGE_MASK (15 << 11) /* GUESS based on layout and native limits */
+# define R300_FPITX_IMAGE_MASK (15 << 11) /* GUESS based on layout and native limits */
/* Unsure if these are opcodes, or some kind of bitfield, but this is how
* they were set when I checked
*/
@@ -1003,7 +999,7 @@ I am fairly certain that they are correct unless stated otherwise in comments.
# define R300_FPI0_ARGC_SRC1C_LRP 15
# define R300_FPI0_ARGC_ZERO 20
# define R300_FPI0_ARGC_ONE 21
-# define R300_FPI0_ARGC_HALF 22 /* GUESS */
+# define R300_FPI0_ARGC_HALF 22 /* GUESS */
# define R300_FPI0_ARGC_SRC0C_YZX 23
# define R300_FPI0_ARGC_SRC1C_YZX 24
# define R300_FPI0_ARGC_SRC2C_YZX 25
@@ -1054,20 +1050,20 @@ I am fairly certain that they are correct unless stated otherwise in comments.
# define R300_FPI2_ARGA_SRC1A_LRP 15
# define R300_FPI2_ARGA_ZERO 16
# define R300_FPI2_ARGA_ONE 17
-# define R300_FPI2_ARGA_HALF 18 /* GUESS */
+# define R300_FPI2_ARGA_HALF 18 /* GUESS */
# define R300_FPI2_ARG0A_SHIFT 0
# define R300_FPI2_ARG0A_MASK (31 << 0)
# define R300_FPI2_ARG0A_NEG (1 << 5)
-# define R300_FPI2_ARG0A_ABS (1 << 6) /* GUESS */
+# define R300_FPI2_ARG0A_ABS (1 << 6) /* GUESS */
# define R300_FPI2_ARG1A_SHIFT 7
# define R300_FPI2_ARG1A_MASK (31 << 7)
# define R300_FPI2_ARG1A_NEG (1 << 12)
-# define R300_FPI2_ARG1A_ABS (1 << 13) /* GUESS */
+# define R300_FPI2_ARG1A_ABS (1 << 13) /* GUESS */
# define R300_FPI2_ARG2A_SHIFT 14
# define R300_FPI2_ARG2A_MASK (31 << 14)
# define R300_FPI2_ARG2A_NEG (1 << 19)
-# define R300_FPI2_ARG2A_ABS (1 << 20) /* GUESS */
+# define R300_FPI2_ARG2A_ABS (1 << 20) /* GUESS */
# define R300_FPI2_SPECIAL_LRP (1 << 21)
# define R300_FPI2_OUTA_MAD (0 << 23)
# define R300_FPI2_OUTA_DP4 (1 << 23)
@@ -1157,26 +1153,26 @@ I am fairly certain that they are correct unless stated otherwise in comments.
/* gap */
#define R300_RB3D_COLOROFFSET0 0x4E28
-# define R300_COLOROFFSET_MASK 0xFFFFFFF0 /* GUESS */
-#define R300_RB3D_COLOROFFSET1 0x4E2C /* GUESS */
-#define R300_RB3D_COLOROFFSET2 0x4E30 /* GUESS */
-#define R300_RB3D_COLOROFFSET3 0x4E34 /* GUESS */
+# define R300_COLOROFFSET_MASK 0xFFFFFFF0 /* GUESS */
+#define R300_RB3D_COLOROFFSET1 0x4E2C /* GUESS */
+#define R300_RB3D_COLOROFFSET2 0x4E30 /* GUESS */
+#define R300_RB3D_COLOROFFSET3 0x4E34 /* GUESS */
/* gap */
/* Bit 16: Larger tiles
// Bit 17: 4x2 tiles
// Bit 18: Extremely weird tile like, but some pixels duplicated? */
#define R300_RB3D_COLORPITCH0 0x4E38
-# define R300_COLORPITCH_MASK 0x00001FF8 /* GUESS */
-# define R300_COLOR_TILE_ENABLE (1 << 16) /* GUESS */
-# define R300_COLOR_MICROTILE_ENABLE (1 << 17) /* GUESS */
-# define R300_COLOR_ENDIAN_NO_SWAP (0 << 18) /* GUESS */
-# define R300_COLOR_ENDIAN_WORD_SWAP (1 << 18) /* GUESS */
-# define R300_COLOR_ENDIAN_DWORD_SWAP (2 << 18) /* GUESS */
+# define R300_COLORPITCH_MASK 0x00001FF8 /* GUESS */
+# define R300_COLOR_TILE_ENABLE (1 << 16) /* GUESS */
+# define R300_COLOR_MICROTILE_ENABLE (1 << 17) /* GUESS */
+# define R300_COLOR_ENDIAN_NO_SWAP (0 << 18) /* GUESS */
+# define R300_COLOR_ENDIAN_WORD_SWAP (1 << 18) /* GUESS */
+# define R300_COLOR_ENDIAN_DWORD_SWAP (2 << 18) /* GUESS */
# define R300_COLOR_FORMAT_RGB565 (2 << 22)
# define R300_COLOR_FORMAT_ARGB8888 (3 << 22)
-#define R300_RB3D_COLORPITCH1 0x4E3C /* GUESS */
-#define R300_RB3D_COLORPITCH2 0x4E40 /* GUESS */
-#define R300_RB3D_COLORPITCH3 0x4E44 /* GUESS */
+#define R300_RB3D_COLORPITCH1 0x4E3C /* GUESS */
+#define R300_RB3D_COLORPITCH2 0x4E40 /* GUESS */
+#define R300_RB3D_COLORPITCH3 0x4E44 /* GUESS */
/* gap */
/* Guess by Vladimir.
@@ -1189,8 +1185,8 @@ I am fairly certain that they are correct unless stated otherwise in comments.
/* There seems to be no "write only" setting, so use Z-test = ALWAYS for this. */
/* Bit (1<<8) is the "test" bit. so plain write is 6 - vd */
#define R300_RB3D_ZSTENCIL_CNTL_0 0x4F00
-# define R300_RB3D_Z_DISABLED_1 0x00000010 /* GUESS */
-# define R300_RB3D_Z_DISABLED_2 0x00000014 /* GUESS */
+# define R300_RB3D_Z_DISABLED_1 0x00000010 /* GUESS */
+# define R300_RB3D_Z_DISABLED_2 0x00000014 /* GUESS */
# define R300_RB3D_Z_TEST 0x00000012
# define R300_RB3D_Z_TEST_AND_WRITE 0x00000016
# define R300_RB3D_Z_WRITE_ONLY 0x00000006
@@ -1233,8 +1229,6 @@ I am fairly certain that they are correct unless stated otherwise in comments.
# define R300_RB3D_ZS1_BACK_ZPASS_OP_SHIFT 21
# define R300_RB3D_ZS1_BACK_ZFAIL_OP_SHIFT 24
-
-
#define R300_RB3D_ZSTENCIL_CNTL_2 0x4F08
# define R300_RB3D_ZS2_STENCIL_REF_SHIFT 0
# define R300_RB3D_ZS2_STENCIL_MASK 0xFF
@@ -1250,12 +1244,12 @@ I am fairly certain that they are correct unless stated otherwise in comments.
/* gap */
#define R300_RB3D_DEPTHOFFSET 0x4F20
#define R300_RB3D_DEPTHPITCH 0x4F24
-# define R300_DEPTHPITCH_MASK 0x00001FF8 /* GUESS */
-# define R300_DEPTH_TILE_ENABLE (1 << 16) /* GUESS */
-# define R300_DEPTH_MICROTILE_ENABLE (1 << 17) /* GUESS */
-# define R300_DEPTH_ENDIAN_NO_SWAP (0 << 18) /* GUESS */
-# define R300_DEPTH_ENDIAN_WORD_SWAP (1 << 18) /* GUESS */
-# define R300_DEPTH_ENDIAN_DWORD_SWAP (2 << 18) /* GUESS */
+# define R300_DEPTHPITCH_MASK 0x00001FF8 /* GUESS */
+# define R300_DEPTH_TILE_ENABLE (1 << 16) /* GUESS */
+# define R300_DEPTH_MICROTILE_ENABLE (1 << 17) /* GUESS */
+# define R300_DEPTH_ENDIAN_NO_SWAP (0 << 18) /* GUESS */
+# define R300_DEPTH_ENDIAN_WORD_SWAP (1 << 18) /* GUESS */
+# define R300_DEPTH_ENDIAN_DWORD_SWAP (2 << 18) /* GUESS */
/* BEGIN: Vertex program instruction set
// Every instruction is four dwords long:
@@ -1295,26 +1289,26 @@ I am fairly certain that they are correct unless stated otherwise in comments.
#define R300_VPI_OUT_OP_MIN (8 << 0)
#define R300_VPI_OUT_OP_SGE (9 << 0)
#define R300_VPI_OUT_OP_SLT (10 << 0)
-#define R300_VPI_OUT_OP_UNK12 (12 << 0) /* Used in GL_POINT_DISTANCE_ATTENUATION_ARB, vector(scalar, vector) */
+#define R300_VPI_OUT_OP_UNK12 (12 << 0) /* Used in GL_POINT_DISTANCE_ATTENUATION_ARB, vector(scalar, vector) */
#define R300_VPI_OUT_OP_EXP (65 << 0)
#define R300_VPI_OUT_OP_LOG (66 << 0)
-#define R300_VPI_OUT_OP_UNK67 (67 << 0) /* Used in fog computations, scalar(scalar) */
+#define R300_VPI_OUT_OP_UNK67 (67 << 0) /* Used in fog computations, scalar(scalar) */
#define R300_VPI_OUT_OP_LIT (68 << 0)
#define R300_VPI_OUT_OP_POW (69 << 0)
#define R300_VPI_OUT_OP_RCP (70 << 0)
#define R300_VPI_OUT_OP_RSQ (72 << 0)
-#define R300_VPI_OUT_OP_UNK73 (73 << 0) /* Used in GL_POINT_DISTANCE_ATTENUATION_ARB, scalar(scalar) */
+#define R300_VPI_OUT_OP_UNK73 (73 << 0) /* Used in GL_POINT_DISTANCE_ATTENUATION_ARB, scalar(scalar) */
#define R300_VPI_OUT_OP_EX2 (75 << 0)
#define R300_VPI_OUT_OP_LG2 (76 << 0)
#define R300_VPI_OUT_OP_MAD_2 (128 << 0)
-#define R300_VPI_OUT_OP_UNK129 (129 << 0) /* all temps, vector(scalar, vector, vector) */
+#define R300_VPI_OUT_OP_UNK129 (129 << 0) /* all temps, vector(scalar, vector, vector) */
#define R300_VPI_OUT_REG_CLASS_TEMPORARY (0 << 8)
#define R300_VPI_OUT_REG_CLASS_RESULT (2 << 8)
#define R300_VPI_OUT_REG_CLASS_MASK (31 << 8)
#define R300_VPI_OUT_REG_INDEX_SHIFT 13
-#define R300_VPI_OUT_REG_INDEX_MASK (31 << 13) /* GUESS based on fglrx native limits */
+#define R300_VPI_OUT_REG_INDEX_MASK (31 << 13) /* GUESS based on fglrx native limits */
#define R300_VPI_OUT_WRITE_X (1 << 20)
#define R300_VPI_OUT_WRITE_Y (1 << 21)
@@ -1325,10 +1319,10 @@ I am fairly certain that they are correct unless stated otherwise in comments.
#define R300_VPI_IN_REG_CLASS_ATTRIBUTE (1 << 0)
#define R300_VPI_IN_REG_CLASS_PARAMETER (2 << 0)
#define R300_VPI_IN_REG_CLASS_NONE (9 << 0)
-#define R300_VPI_IN_REG_CLASS_MASK (31 << 0) /* GUESS */
+#define R300_VPI_IN_REG_CLASS_MASK (31 << 0) /* GUESS */
#define R300_VPI_IN_REG_INDEX_SHIFT 5
-#define R300_VPI_IN_REG_INDEX_MASK (255 << 5) /* GUESS based on fglrx native limits */
+#define R300_VPI_IN_REG_INDEX_MASK (255 << 5) /* GUESS based on fglrx native limits */
/* The R300 can select components from the input register arbitrarily.
// Use the following constants, shifted by the component shift you
@@ -1366,7 +1360,7 @@ I am fairly certain that they are correct unless stated otherwise in comments.
#define R300_PRIM_TYPE_RECT_LIST (8 << 0)
#define R300_PRIM_TYPE_3VRT_POINT_LIST (9 << 0)
#define R300_PRIM_TYPE_3VRT_LINE_LIST (10 << 0)
-#define R300_PRIM_TYPE_POINT_SPRITES (11 << 0) // GUESS (based on r200)
+#define R300_PRIM_TYPE_POINT_SPRITES (11 << 0) // GUESS (based on r200)
#define R300_PRIM_TYPE_LINE_LOOP (12 << 0)
#define R300_PRIM_TYPE_QUADS (13 << 0)
#define R300_PRIM_TYPE_QUAD_STRIP (14 << 0)
@@ -1376,8 +1370,8 @@ I am fairly certain that they are correct unless stated otherwise in comments.
#define R300_PRIM_WALK_LIST (2 << 4)
#define R300_PRIM_WALK_RING (3 << 4)
#define R300_PRIM_WALK_MASK (3 << 4)
-#define R300_PRIM_COLOR_ORDER_BGRA (0 << 6) // GUESS (based on r200)
-#define R300_PRIM_COLOR_ORDER_RGBA (1 << 6) // GUESS
+#define R300_PRIM_COLOR_ORDER_BGRA (0 << 6) // GUESS (based on r200)
+#define R300_PRIM_COLOR_ORDER_RGBA (1 << 6) // GUESS
#define R300_PRIM_NUM_VERTICES_SHIFT 16
// Draw a primitive from vertex data in arrays loaded via 3D_LOAD_VBPNTR.
@@ -1409,4 +1403,4 @@ I am fairly certain that they are correct unless stated otherwise in comments.
//END
-#endif /* _R300_REG_H */
+#endif /* _R300_REG_H */
diff --git a/drivers/char/drm/radeon_cp.c b/drivers/char/drm/radeon_cp.c
index 12ef13ff04ca..03839ea31092 100644
--- a/drivers/char/drm/radeon_cp.c
+++ b/drivers/char/drm/radeon_cp.c
@@ -36,788 +36,787 @@
#define RADEON_FIFO_DEBUG 0
-static int radeon_do_cleanup_cp( drm_device_t *dev );
+static int radeon_do_cleanup_cp(drm_device_t * dev);
/* CP microcode (from ATI) */
static u32 R200_cp_microcode[][2] = {
- { 0x21007000, 0000000000 },
- { 0x20007000, 0000000000 },
- { 0x000000ab, 0x00000004 },
- { 0x000000af, 0x00000004 },
- { 0x66544a49, 0000000000 },
- { 0x49494174, 0000000000 },
- { 0x54517d83, 0000000000 },
- { 0x498d8b64, 0000000000 },
- { 0x49494949, 0000000000 },
- { 0x49da493c, 0000000000 },
- { 0x49989898, 0000000000 },
- { 0xd34949d5, 0000000000 },
- { 0x9dc90e11, 0000000000 },
- { 0xce9b9b9b, 0000000000 },
- { 0x000f0000, 0x00000016 },
- { 0x352e232c, 0000000000 },
- { 0x00000013, 0x00000004 },
- { 0x000f0000, 0x00000016 },
- { 0x352e272c, 0000000000 },
- { 0x000f0001, 0x00000016 },
- { 0x3239362f, 0000000000 },
- { 0x000077ef, 0x00000002 },
- { 0x00061000, 0x00000002 },
- { 0x00000020, 0x0000001a },
- { 0x00004000, 0x0000001e },
- { 0x00061000, 0x00000002 },
- { 0x00000020, 0x0000001a },
- { 0x00004000, 0x0000001e },
- { 0x00061000, 0x00000002 },
- { 0x00000020, 0x0000001a },
- { 0x00004000, 0x0000001e },
- { 0x00000016, 0x00000004 },
- { 0x0003802a, 0x00000002 },
- { 0x040067e0, 0x00000002 },
- { 0x00000016, 0x00000004 },
- { 0x000077e0, 0x00000002 },
- { 0x00065000, 0x00000002 },
- { 0x000037e1, 0x00000002 },
- { 0x040067e1, 0x00000006 },
- { 0x000077e0, 0x00000002 },
- { 0x000077e1, 0x00000002 },
- { 0x000077e1, 0x00000006 },
- { 0xffffffff, 0000000000 },
- { 0x10000000, 0000000000 },
- { 0x0003802a, 0x00000002 },
- { 0x040067e0, 0x00000006 },
- { 0x00007675, 0x00000002 },
- { 0x00007676, 0x00000002 },
- { 0x00007677, 0x00000002 },
- { 0x00007678, 0x00000006 },
- { 0x0003802b, 0x00000002 },
- { 0x04002676, 0x00000002 },
- { 0x00007677, 0x00000002 },
- { 0x00007678, 0x00000006 },
- { 0x0000002e, 0x00000018 },
- { 0x0000002e, 0x00000018 },
- { 0000000000, 0x00000006 },
- { 0x0000002f, 0x00000018 },
- { 0x0000002f, 0x00000018 },
- { 0000000000, 0x00000006 },
- { 0x01605000, 0x00000002 },
- { 0x00065000, 0x00000002 },
- { 0x00098000, 0x00000002 },
- { 0x00061000, 0x00000002 },
- { 0x64c0603d, 0x00000004 },
- { 0x00080000, 0x00000016 },
- { 0000000000, 0000000000 },
- { 0x0400251d, 0x00000002 },
- { 0x00007580, 0x00000002 },
- { 0x00067581, 0x00000002 },
- { 0x04002580, 0x00000002 },
- { 0x00067581, 0x00000002 },
- { 0x00000046, 0x00000004 },
- { 0x00005000, 0000000000 },
- { 0x00061000, 0x00000002 },
- { 0x0000750e, 0x00000002 },
- { 0x00019000, 0x00000002 },
- { 0x00011055, 0x00000014 },
- { 0x00000055, 0x00000012 },
- { 0x0400250f, 0x00000002 },
- { 0x0000504a, 0x00000004 },
- { 0x00007565, 0x00000002 },
- { 0x00007566, 0x00000002 },
- { 0x00000051, 0x00000004 },
- { 0x01e655b4, 0x00000002 },
- { 0x4401b0dc, 0x00000002 },
- { 0x01c110dc, 0x00000002 },
- { 0x2666705d, 0x00000018 },
- { 0x040c2565, 0x00000002 },
- { 0x0000005d, 0x00000018 },
- { 0x04002564, 0x00000002 },
- { 0x00007566, 0x00000002 },
- { 0x00000054, 0x00000004 },
- { 0x00401060, 0x00000008 },
- { 0x00101000, 0x00000002 },
- { 0x000d80ff, 0x00000002 },
- { 0x00800063, 0x00000008 },
- { 0x000f9000, 0x00000002 },
- { 0x000e00ff, 0x00000002 },
- { 0000000000, 0x00000006 },
- { 0x00000080, 0x00000018 },
- { 0x00000054, 0x00000004 },
- { 0x00007576, 0x00000002 },
- { 0x00065000, 0x00000002 },
- { 0x00009000, 0x00000002 },
- { 0x00041000, 0x00000002 },
- { 0x0c00350e, 0x00000002 },
- { 0x00049000, 0x00000002 },
- { 0x00051000, 0x00000002 },
- { 0x01e785f8, 0x00000002 },
- { 0x00200000, 0x00000002 },
- { 0x00600073, 0x0000000c },
- { 0x00007563, 0x00000002 },
- { 0x006075f0, 0x00000021 },
- { 0x20007068, 0x00000004 },
- { 0x00005068, 0x00000004 },
- { 0x00007576, 0x00000002 },
- { 0x00007577, 0x00000002 },
- { 0x0000750e, 0x00000002 },
- { 0x0000750f, 0x00000002 },
- { 0x00a05000, 0x00000002 },
- { 0x00600076, 0x0000000c },
- { 0x006075f0, 0x00000021 },
- { 0x000075f8, 0x00000002 },
- { 0x00000076, 0x00000004 },
- { 0x000a750e, 0x00000002 },
- { 0x0020750f, 0x00000002 },
- { 0x00600079, 0x00000004 },
- { 0x00007570, 0x00000002 },
- { 0x00007571, 0x00000002 },
- { 0x00007572, 0x00000006 },
- { 0x00005000, 0x00000002 },
- { 0x00a05000, 0x00000002 },
- { 0x00007568, 0x00000002 },
- { 0x00061000, 0x00000002 },
- { 0x00000084, 0x0000000c },
- { 0x00058000, 0x00000002 },
- { 0x0c607562, 0x00000002 },
- { 0x00000086, 0x00000004 },
- { 0x00600085, 0x00000004 },
- { 0x400070dd, 0000000000 },
- { 0x000380dd, 0x00000002 },
- { 0x00000093, 0x0000001c },
- { 0x00065095, 0x00000018 },
- { 0x040025bb, 0x00000002 },
- { 0x00061096, 0x00000018 },
- { 0x040075bc, 0000000000 },
- { 0x000075bb, 0x00000002 },
- { 0x000075bc, 0000000000 },
- { 0x00090000, 0x00000006 },
- { 0x00090000, 0x00000002 },
- { 0x000d8002, 0x00000006 },
- { 0x00005000, 0x00000002 },
- { 0x00007821, 0x00000002 },
- { 0x00007800, 0000000000 },
- { 0x00007821, 0x00000002 },
- { 0x00007800, 0000000000 },
- { 0x01665000, 0x00000002 },
- { 0x000a0000, 0x00000002 },
- { 0x000671cc, 0x00000002 },
- { 0x0286f1cd, 0x00000002 },
- { 0x000000a3, 0x00000010 },
- { 0x21007000, 0000000000 },
- { 0x000000aa, 0x0000001c },
- { 0x00065000, 0x00000002 },
- { 0x000a0000, 0x00000002 },
- { 0x00061000, 0x00000002 },
- { 0x000b0000, 0x00000002 },
- { 0x38067000, 0x00000002 },
- { 0x000a00a6, 0x00000004 },
- { 0x20007000, 0000000000 },
- { 0x01200000, 0x00000002 },
- { 0x20077000, 0x00000002 },
- { 0x01200000, 0x00000002 },
- { 0x20007000, 0000000000 },
- { 0x00061000, 0x00000002 },
- { 0x0120751b, 0x00000002 },
- { 0x8040750a, 0x00000002 },
- { 0x8040750b, 0x00000002 },
- { 0x00110000, 0x00000002 },
- { 0x000380dd, 0x00000002 },
- { 0x000000bd, 0x0000001c },
- { 0x00061096, 0x00000018 },
- { 0x844075bd, 0x00000002 },
- { 0x00061095, 0x00000018 },
- { 0x840075bb, 0x00000002 },
- { 0x00061096, 0x00000018 },
- { 0x844075bc, 0x00000002 },
- { 0x000000c0, 0x00000004 },
- { 0x804075bd, 0x00000002 },
- { 0x800075bb, 0x00000002 },
- { 0x804075bc, 0x00000002 },
- { 0x00108000, 0x00000002 },
- { 0x01400000, 0x00000002 },
- { 0x006000c4, 0x0000000c },
- { 0x20c07000, 0x00000020 },
- { 0x000000c6, 0x00000012 },
- { 0x00800000, 0x00000006 },
- { 0x0080751d, 0x00000006 },
- { 0x000025bb, 0x00000002 },
- { 0x000040c0, 0x00000004 },
- { 0x0000775c, 0x00000002 },
- { 0x00a05000, 0x00000002 },
- { 0x00661000, 0x00000002 },
- { 0x0460275d, 0x00000020 },
- { 0x00004000, 0000000000 },
- { 0x00007999, 0x00000002 },
- { 0x00a05000, 0x00000002 },
- { 0x00661000, 0x00000002 },
- { 0x0460299b, 0x00000020 },
- { 0x00004000, 0000000000 },
- { 0x01e00830, 0x00000002 },
- { 0x21007000, 0000000000 },
- { 0x00005000, 0x00000002 },
- { 0x00038042, 0x00000002 },
- { 0x040025e0, 0x00000002 },
- { 0x000075e1, 0000000000 },
- { 0x00000001, 0000000000 },
- { 0x000380d9, 0x00000002 },
- { 0x04007394, 0000000000 },
- { 0000000000, 0000000000 },
- { 0000000000, 0000000000 },
- { 0000000000, 0000000000 },
- { 0000000000, 0000000000 },
- { 0000000000, 0000000000 },
- { 0000000000, 0000000000 },
- { 0000000000, 0000000000 },
- { 0000000000, 0000000000 },
- { 0000000000, 0000000000 },
- { 0000000000, 0000000000 },
- { 0000000000, 0000000000 },
- { 0000000000, 0000000000 },
- { 0000000000, 0000000000 },
- { 0000000000, 0000000000 },
- { 0000000000, 0000000000 },
- { 0000000000, 0000000000 },
- { 0000000000, 0000000000 },
- { 0000000000, 0000000000 },
- { 0000000000, 0000000000 },
- { 0000000000, 0000000000 },
- { 0000000000, 0000000000 },
- { 0000000000, 0000000000 },
- { 0000000000, 0000000000 },
- { 0000000000, 0000000000 },
- { 0000000000, 0000000000 },
- { 0000000000, 0000000000 },
- { 0000000000, 0000000000 },
- { 0000000000, 0000000000 },
- { 0000000000, 0000000000 },
- { 0000000000, 0000000000 },
- { 0000000000, 0000000000 },
- { 0000000000, 0000000000 },
- { 0000000000, 0000000000 },
- { 0000000000, 0000000000 },
- { 0000000000, 0000000000 },
- { 0000000000, 0000000000 },
+ {0x21007000, 0000000000},
+ {0x20007000, 0000000000},
+ {0x000000ab, 0x00000004},
+ {0x000000af, 0x00000004},
+ {0x66544a49, 0000000000},
+ {0x49494174, 0000000000},
+ {0x54517d83, 0000000000},
+ {0x498d8b64, 0000000000},
+ {0x49494949, 0000000000},
+ {0x49da493c, 0000000000},
+ {0x49989898, 0000000000},
+ {0xd34949d5, 0000000000},
+ {0x9dc90e11, 0000000000},
+ {0xce9b9b9b, 0000000000},
+ {0x000f0000, 0x00000016},
+ {0x352e232c, 0000000000},
+ {0x00000013, 0x00000004},
+ {0x000f0000, 0x00000016},
+ {0x352e272c, 0000000000},
+ {0x000f0001, 0x00000016},
+ {0x3239362f, 0000000000},
+ {0x000077ef, 0x00000002},
+ {0x00061000, 0x00000002},
+ {0x00000020, 0x0000001a},
+ {0x00004000, 0x0000001e},
+ {0x00061000, 0x00000002},
+ {0x00000020, 0x0000001a},
+ {0x00004000, 0x0000001e},
+ {0x00061000, 0x00000002},
+ {0x00000020, 0x0000001a},
+ {0x00004000, 0x0000001e},
+ {0x00000016, 0x00000004},
+ {0x0003802a, 0x00000002},
+ {0x040067e0, 0x00000002},
+ {0x00000016, 0x00000004},
+ {0x000077e0, 0x00000002},
+ {0x00065000, 0x00000002},
+ {0x000037e1, 0x00000002},
+ {0x040067e1, 0x00000006},
+ {0x000077e0, 0x00000002},
+ {0x000077e1, 0x00000002},
+ {0x000077e1, 0x00000006},
+ {0xffffffff, 0000000000},
+ {0x10000000, 0000000000},
+ {0x0003802a, 0x00000002},
+ {0x040067e0, 0x00000006},
+ {0x00007675, 0x00000002},
+ {0x00007676, 0x00000002},
+ {0x00007677, 0x00000002},
+ {0x00007678, 0x00000006},
+ {0x0003802b, 0x00000002},
+ {0x04002676, 0x00000002},
+ {0x00007677, 0x00000002},
+ {0x00007678, 0x00000006},
+ {0x0000002e, 0x00000018},
+ {0x0000002e, 0x00000018},
+ {0000000000, 0x00000006},
+ {0x0000002f, 0x00000018},
+ {0x0000002f, 0x00000018},
+ {0000000000, 0x00000006},
+ {0x01605000, 0x00000002},
+ {0x00065000, 0x00000002},
+ {0x00098000, 0x00000002},
+ {0x00061000, 0x00000002},
+ {0x64c0603d, 0x00000004},
+ {0x00080000, 0x00000016},
+ {0000000000, 0000000000},
+ {0x0400251d, 0x00000002},
+ {0x00007580, 0x00000002},
+ {0x00067581, 0x00000002},
+ {0x04002580, 0x00000002},
+ {0x00067581, 0x00000002},
+ {0x00000046, 0x00000004},
+ {0x00005000, 0000000000},
+ {0x00061000, 0x00000002},
+ {0x0000750e, 0x00000002},
+ {0x00019000, 0x00000002},
+ {0x00011055, 0x00000014},
+ {0x00000055, 0x00000012},
+ {0x0400250f, 0x00000002},
+ {0x0000504a, 0x00000004},
+ {0x00007565, 0x00000002},
+ {0x00007566, 0x00000002},
+ {0x00000051, 0x00000004},
+ {0x01e655b4, 0x00000002},
+ {0x4401b0dc, 0x00000002},
+ {0x01c110dc, 0x00000002},
+ {0x2666705d, 0x00000018},
+ {0x040c2565, 0x00000002},
+ {0x0000005d, 0x00000018},
+ {0x04002564, 0x00000002},
+ {0x00007566, 0x00000002},
+ {0x00000054, 0x00000004},
+ {0x00401060, 0x00000008},
+ {0x00101000, 0x00000002},
+ {0x000d80ff, 0x00000002},
+ {0x00800063, 0x00000008},
+ {0x000f9000, 0x00000002},
+ {0x000e00ff, 0x00000002},
+ {0000000000, 0x00000006},
+ {0x00000080, 0x00000018},
+ {0x00000054, 0x00000004},
+ {0x00007576, 0x00000002},
+ {0x00065000, 0x00000002},
+ {0x00009000, 0x00000002},
+ {0x00041000, 0x00000002},
+ {0x0c00350e, 0x00000002},
+ {0x00049000, 0x00000002},
+ {0x00051000, 0x00000002},
+ {0x01e785f8, 0x00000002},
+ {0x00200000, 0x00000002},
+ {0x00600073, 0x0000000c},
+ {0x00007563, 0x00000002},
+ {0x006075f0, 0x00000021},
+ {0x20007068, 0x00000004},
+ {0x00005068, 0x00000004},
+ {0x00007576, 0x00000002},
+ {0x00007577, 0x00000002},
+ {0x0000750e, 0x00000002},
+ {0x0000750f, 0x00000002},
+ {0x00a05000, 0x00000002},
+ {0x00600076, 0x0000000c},
+ {0x006075f0, 0x00000021},
+ {0x000075f8, 0x00000002},
+ {0x00000076, 0x00000004},
+ {0x000a750e, 0x00000002},
+ {0x0020750f, 0x00000002},
+ {0x00600079, 0x00000004},
+ {0x00007570, 0x00000002},
+ {0x00007571, 0x00000002},
+ {0x00007572, 0x00000006},
+ {0x00005000, 0x00000002},
+ {0x00a05000, 0x00000002},
+ {0x00007568, 0x00000002},
+ {0x00061000, 0x00000002},
+ {0x00000084, 0x0000000c},
+ {0x00058000, 0x00000002},
+ {0x0c607562, 0x00000002},
+ {0x00000086, 0x00000004},
+ {0x00600085, 0x00000004},
+ {0x400070dd, 0000000000},
+ {0x000380dd, 0x00000002},
+ {0x00000093, 0x0000001c},
+ {0x00065095, 0x00000018},
+ {0x040025bb, 0x00000002},
+ {0x00061096, 0x00000018},
+ {0x040075bc, 0000000000},
+ {0x000075bb, 0x00000002},
+ {0x000075bc, 0000000000},
+ {0x00090000, 0x00000006},
+ {0x00090000, 0x00000002},
+ {0x000d8002, 0x00000006},
+ {0x00005000, 0x00000002},
+ {0x00007821, 0x00000002},
+ {0x00007800, 0000000000},
+ {0x00007821, 0x00000002},
+ {0x00007800, 0000000000},
+ {0x01665000, 0x00000002},
+ {0x000a0000, 0x00000002},
+ {0x000671cc, 0x00000002},
+ {0x0286f1cd, 0x00000002},
+ {0x000000a3, 0x00000010},
+ {0x21007000, 0000000000},
+ {0x000000aa, 0x0000001c},
+ {0x00065000, 0x00000002},
+ {0x000a0000, 0x00000002},
+ {0x00061000, 0x00000002},
+ {0x000b0000, 0x00000002},
+ {0x38067000, 0x00000002},
+ {0x000a00a6, 0x00000004},
+ {0x20007000, 0000000000},
+ {0x01200000, 0x00000002},
+ {0x20077000, 0x00000002},
+ {0x01200000, 0x00000002},
+ {0x20007000, 0000000000},
+ {0x00061000, 0x00000002},
+ {0x0120751b, 0x00000002},
+ {0x8040750a, 0x00000002},
+ {0x8040750b, 0x00000002},
+ {0x00110000, 0x00000002},
+ {0x000380dd, 0x00000002},
+ {0x000000bd, 0x0000001c},
+ {0x00061096, 0x00000018},
+ {0x844075bd, 0x00000002},
+ {0x00061095, 0x00000018},
+ {0x840075bb, 0x00000002},
+ {0x00061096, 0x00000018},
+ {0x844075bc, 0x00000002},
+ {0x000000c0, 0x00000004},
+ {0x804075bd, 0x00000002},
+ {0x800075bb, 0x00000002},
+ {0x804075bc, 0x00000002},
+ {0x00108000, 0x00000002},
+ {0x01400000, 0x00000002},
+ {0x006000c4, 0x0000000c},
+ {0x20c07000, 0x00000020},
+ {0x000000c6, 0x00000012},
+ {0x00800000, 0x00000006},
+ {0x0080751d, 0x00000006},
+ {0x000025bb, 0x00000002},
+ {0x000040c0, 0x00000004},
+ {0x0000775c, 0x00000002},
+ {0x00a05000, 0x00000002},
+ {0x00661000, 0x00000002},
+ {0x0460275d, 0x00000020},
+ {0x00004000, 0000000000},
+ {0x00007999, 0x00000002},
+ {0x00a05000, 0x00000002},
+ {0x00661000, 0x00000002},
+ {0x0460299b, 0x00000020},
+ {0x00004000, 0000000000},
+ {0x01e00830, 0x00000002},
+ {0x21007000, 0000000000},
+ {0x00005000, 0x00000002},
+ {0x00038042, 0x00000002},
+ {0x040025e0, 0x00000002},
+ {0x000075e1, 0000000000},
+ {0x00000001, 0000000000},
+ {0x000380d9, 0x00000002},
+ {0x04007394, 0000000000},
+ {0000000000, 0000000000},
+ {0000000000, 0000000000},
+ {0000000000, 0000000000},
+ {0000000000, 0000000000},
+ {0000000000, 0000000000},
+ {0000000000, 0000000000},
+ {0000000000, 0000000000},
+ {0000000000, 0000000000},
+ {0000000000, 0000000000},
+ {0000000000, 0000000000},
+ {0000000000, 0000000000},
+ {0000000000, 0000000000},
+ {0000000000, 0000000000},
+ {0000000000, 0000000000},
+ {0000000000, 0000000000},
+ {0000000000, 0000000000},
+ {0000000000, 0000000000},
+ {0000000000, 0000000000},
+ {0000000000, 0000000000},
+ {0000000000, 0000000000},
+ {0000000000, 0000000000},
+ {0000000000, 0000000000},
+ {0000000000, 0000000000},
+ {0000000000, 0000000000},
+ {0000000000, 0000000000},
+ {0000000000, 0000000000},
+ {0000000000, 0000000000},
+ {0000000000, 0000000000},
+ {0000000000, 0000000000},
+ {0000000000, 0000000000},
+ {0000000000, 0000000000},
+ {0000000000, 0000000000},
+ {0000000000, 0000000000},
+ {0000000000, 0000000000},
+ {0000000000, 0000000000},
+ {0000000000, 0000000000},
};
-
static u32 radeon_cp_microcode[][2] = {
- { 0x21007000, 0000000000 },
- { 0x20007000, 0000000000 },
- { 0x000000b4, 0x00000004 },
- { 0x000000b8, 0x00000004 },
- { 0x6f5b4d4c, 0000000000 },
- { 0x4c4c427f, 0000000000 },
- { 0x5b568a92, 0000000000 },
- { 0x4ca09c6d, 0000000000 },
- { 0xad4c4c4c, 0000000000 },
- { 0x4ce1af3d, 0000000000 },
- { 0xd8afafaf, 0000000000 },
- { 0xd64c4cdc, 0000000000 },
- { 0x4cd10d10, 0000000000 },
- { 0x000f0000, 0x00000016 },
- { 0x362f242d, 0000000000 },
- { 0x00000012, 0x00000004 },
- { 0x000f0000, 0x00000016 },
- { 0x362f282d, 0000000000 },
- { 0x000380e7, 0x00000002 },
- { 0x04002c97, 0x00000002 },
- { 0x000f0001, 0x00000016 },
- { 0x333a3730, 0000000000 },
- { 0x000077ef, 0x00000002 },
- { 0x00061000, 0x00000002 },
- { 0x00000021, 0x0000001a },
- { 0x00004000, 0x0000001e },
- { 0x00061000, 0x00000002 },
- { 0x00000021, 0x0000001a },
- { 0x00004000, 0x0000001e },
- { 0x00061000, 0x00000002 },
- { 0x00000021, 0x0000001a },
- { 0x00004000, 0x0000001e },
- { 0x00000017, 0x00000004 },
- { 0x0003802b, 0x00000002 },
- { 0x040067e0, 0x00000002 },
- { 0x00000017, 0x00000004 },
- { 0x000077e0, 0x00000002 },
- { 0x00065000, 0x00000002 },
- { 0x000037e1, 0x00000002 },
- { 0x040067e1, 0x00000006 },
- { 0x000077e0, 0x00000002 },
- { 0x000077e1, 0x00000002 },
- { 0x000077e1, 0x00000006 },
- { 0xffffffff, 0000000000 },
- { 0x10000000, 0000000000 },
- { 0x0003802b, 0x00000002 },
- { 0x040067e0, 0x00000006 },
- { 0x00007675, 0x00000002 },
- { 0x00007676, 0x00000002 },
- { 0x00007677, 0x00000002 },
- { 0x00007678, 0x00000006 },
- { 0x0003802c, 0x00000002 },
- { 0x04002676, 0x00000002 },
- { 0x00007677, 0x00000002 },
- { 0x00007678, 0x00000006 },
- { 0x0000002f, 0x00000018 },
- { 0x0000002f, 0x00000018 },
- { 0000000000, 0x00000006 },
- { 0x00000030, 0x00000018 },
- { 0x00000030, 0x00000018 },
- { 0000000000, 0x00000006 },
- { 0x01605000, 0x00000002 },
- { 0x00065000, 0x00000002 },
- { 0x00098000, 0x00000002 },
- { 0x00061000, 0x00000002 },
- { 0x64c0603e, 0x00000004 },
- { 0x000380e6, 0x00000002 },
- { 0x040025c5, 0x00000002 },
- { 0x00080000, 0x00000016 },
- { 0000000000, 0000000000 },
- { 0x0400251d, 0x00000002 },
- { 0x00007580, 0x00000002 },
- { 0x00067581, 0x00000002 },
- { 0x04002580, 0x00000002 },
- { 0x00067581, 0x00000002 },
- { 0x00000049, 0x00000004 },
- { 0x00005000, 0000000000 },
- { 0x000380e6, 0x00000002 },
- { 0x040025c5, 0x00000002 },
- { 0x00061000, 0x00000002 },
- { 0x0000750e, 0x00000002 },
- { 0x00019000, 0x00000002 },
- { 0x00011055, 0x00000014 },
- { 0x00000055, 0x00000012 },
- { 0x0400250f, 0x00000002 },
- { 0x0000504f, 0x00000004 },
- { 0x000380e6, 0x00000002 },
- { 0x040025c5, 0x00000002 },
- { 0x00007565, 0x00000002 },
- { 0x00007566, 0x00000002 },
- { 0x00000058, 0x00000004 },
- { 0x000380e6, 0x00000002 },
- { 0x040025c5, 0x00000002 },
- { 0x01e655b4, 0x00000002 },
- { 0x4401b0e4, 0x00000002 },
- { 0x01c110e4, 0x00000002 },
- { 0x26667066, 0x00000018 },
- { 0x040c2565, 0x00000002 },
- { 0x00000066, 0x00000018 },
- { 0x04002564, 0x00000002 },
- { 0x00007566, 0x00000002 },
- { 0x0000005d, 0x00000004 },
- { 0x00401069, 0x00000008 },
- { 0x00101000, 0x00000002 },
- { 0x000d80ff, 0x00000002 },
- { 0x0080006c, 0x00000008 },
- { 0x000f9000, 0x00000002 },
- { 0x000e00ff, 0x00000002 },
- { 0000000000, 0x00000006 },
- { 0x0000008f, 0x00000018 },
- { 0x0000005b, 0x00000004 },
- { 0x000380e6, 0x00000002 },
- { 0x040025c5, 0x00000002 },
- { 0x00007576, 0x00000002 },
- { 0x00065000, 0x00000002 },
- { 0x00009000, 0x00000002 },
- { 0x00041000, 0x00000002 },
- { 0x0c00350e, 0x00000002 },
- { 0x00049000, 0x00000002 },
- { 0x00051000, 0x00000002 },
- { 0x01e785f8, 0x00000002 },
- { 0x00200000, 0x00000002 },
- { 0x0060007e, 0x0000000c },
- { 0x00007563, 0x00000002 },
- { 0x006075f0, 0x00000021 },
- { 0x20007073, 0x00000004 },
- { 0x00005073, 0x00000004 },
- { 0x000380e6, 0x00000002 },
- { 0x040025c5, 0x00000002 },
- { 0x00007576, 0x00000002 },
- { 0x00007577, 0x00000002 },
- { 0x0000750e, 0x00000002 },
- { 0x0000750f, 0x00000002 },
- { 0x00a05000, 0x00000002 },
- { 0x00600083, 0x0000000c },
- { 0x006075f0, 0x00000021 },
- { 0x000075f8, 0x00000002 },
- { 0x00000083, 0x00000004 },
- { 0x000a750e, 0x00000002 },
- { 0x000380e6, 0x00000002 },
- { 0x040025c5, 0x00000002 },
- { 0x0020750f, 0x00000002 },
- { 0x00600086, 0x00000004 },
- { 0x00007570, 0x00000002 },
- { 0x00007571, 0x00000002 },
- { 0x00007572, 0x00000006 },
- { 0x000380e6, 0x00000002 },
- { 0x040025c5, 0x00000002 },
- { 0x00005000, 0x00000002 },
- { 0x00a05000, 0x00000002 },
- { 0x00007568, 0x00000002 },
- { 0x00061000, 0x00000002 },
- { 0x00000095, 0x0000000c },
- { 0x00058000, 0x00000002 },
- { 0x0c607562, 0x00000002 },
- { 0x00000097, 0x00000004 },
- { 0x000380e6, 0x00000002 },
- { 0x040025c5, 0x00000002 },
- { 0x00600096, 0x00000004 },
- { 0x400070e5, 0000000000 },
- { 0x000380e6, 0x00000002 },
- { 0x040025c5, 0x00000002 },
- { 0x000380e5, 0x00000002 },
- { 0x000000a8, 0x0000001c },
- { 0x000650aa, 0x00000018 },
- { 0x040025bb, 0x00000002 },
- { 0x000610ab, 0x00000018 },
- { 0x040075bc, 0000000000 },
- { 0x000075bb, 0x00000002 },
- { 0x000075bc, 0000000000 },
- { 0x00090000, 0x00000006 },
- { 0x00090000, 0x00000002 },
- { 0x000d8002, 0x00000006 },
- { 0x00007832, 0x00000002 },
- { 0x00005000, 0x00000002 },
- { 0x000380e7, 0x00000002 },
- { 0x04002c97, 0x00000002 },
- { 0x00007820, 0x00000002 },
- { 0x00007821, 0x00000002 },
- { 0x00007800, 0000000000 },
- { 0x01200000, 0x00000002 },
- { 0x20077000, 0x00000002 },
- { 0x01200000, 0x00000002 },
- { 0x20007000, 0x00000002 },
- { 0x00061000, 0x00000002 },
- { 0x0120751b, 0x00000002 },
- { 0x8040750a, 0x00000002 },
- { 0x8040750b, 0x00000002 },
- { 0x00110000, 0x00000002 },
- { 0x000380e5, 0x00000002 },
- { 0x000000c6, 0x0000001c },
- { 0x000610ab, 0x00000018 },
- { 0x844075bd, 0x00000002 },
- { 0x000610aa, 0x00000018 },
- { 0x840075bb, 0x00000002 },
- { 0x000610ab, 0x00000018 },
- { 0x844075bc, 0x00000002 },
- { 0x000000c9, 0x00000004 },
- { 0x804075bd, 0x00000002 },
- { 0x800075bb, 0x00000002 },
- { 0x804075bc, 0x00000002 },
- { 0x00108000, 0x00000002 },
- { 0x01400000, 0x00000002 },
- { 0x006000cd, 0x0000000c },
- { 0x20c07000, 0x00000020 },
- { 0x000000cf, 0x00000012 },
- { 0x00800000, 0x00000006 },
- { 0x0080751d, 0x00000006 },
- { 0000000000, 0000000000 },
- { 0x0000775c, 0x00000002 },
- { 0x00a05000, 0x00000002 },
- { 0x00661000, 0x00000002 },
- { 0x0460275d, 0x00000020 },
- { 0x00004000, 0000000000 },
- { 0x01e00830, 0x00000002 },
- { 0x21007000, 0000000000 },
- { 0x6464614d, 0000000000 },
- { 0x69687420, 0000000000 },
- { 0x00000073, 0000000000 },
- { 0000000000, 0000000000 },
- { 0x00005000, 0x00000002 },
- { 0x000380d0, 0x00000002 },
- { 0x040025e0, 0x00000002 },
- { 0x000075e1, 0000000000 },
- { 0x00000001, 0000000000 },
- { 0x000380e0, 0x00000002 },
- { 0x04002394, 0x00000002 },
- { 0x00005000, 0000000000 },
- { 0000000000, 0000000000 },
- { 0000000000, 0000000000 },
- { 0x00000008, 0000000000 },
- { 0x00000004, 0000000000 },
- { 0000000000, 0000000000 },
- { 0000000000, 0000000000 },
- { 0000000000, 0000000000 },
- { 0000000000, 0000000000 },
- { 0000000000, 0000000000 },
- { 0000000000, 0000000000 },
- { 0000000000, 0000000000 },
- { 0000000000, 0000000000 },
- { 0000000000, 0000000000 },
- { 0000000000, 0000000000 },
- { 0000000000, 0000000000 },
- { 0000000000, 0000000000 },
- { 0000000000, 0000000000 },
- { 0000000000, 0000000000 },
- { 0000000000, 0000000000 },
- { 0000000000, 0000000000 },
- { 0000000000, 0000000000 },
- { 0000000000, 0000000000 },
- { 0000000000, 0000000000 },
- { 0000000000, 0000000000 },
- { 0000000000, 0000000000 },
- { 0000000000, 0000000000 },
- { 0000000000, 0000000000 },
- { 0000000000, 0000000000 },
+ {0x21007000, 0000000000},
+ {0x20007000, 0000000000},
+ {0x000000b4, 0x00000004},
+ {0x000000b8, 0x00000004},
+ {0x6f5b4d4c, 0000000000},
+ {0x4c4c427f, 0000000000},
+ {0x5b568a92, 0000000000},
+ {0x4ca09c6d, 0000000000},
+ {0xad4c4c4c, 0000000000},
+ {0x4ce1af3d, 0000000000},
+ {0xd8afafaf, 0000000000},
+ {0xd64c4cdc, 0000000000},
+ {0x4cd10d10, 0000000000},
+ {0x000f0000, 0x00000016},
+ {0x362f242d, 0000000000},
+ {0x00000012, 0x00000004},
+ {0x000f0000, 0x00000016},
+ {0x362f282d, 0000000000},
+ {0x000380e7, 0x00000002},
+ {0x04002c97, 0x00000002},
+ {0x000f0001, 0x00000016},
+ {0x333a3730, 0000000000},
+ {0x000077ef, 0x00000002},
+ {0x00061000, 0x00000002},
+ {0x00000021, 0x0000001a},
+ {0x00004000, 0x0000001e},
+ {0x00061000, 0x00000002},
+ {0x00000021, 0x0000001a},
+ {0x00004000, 0x0000001e},
+ {0x00061000, 0x00000002},
+ {0x00000021, 0x0000001a},
+ {0x00004000, 0x0000001e},
+ {0x00000017, 0x00000004},
+ {0x0003802b, 0x00000002},
+ {0x040067e0, 0x00000002},
+ {0x00000017, 0x00000004},
+ {0x000077e0, 0x00000002},
+ {0x00065000, 0x00000002},
+ {0x000037e1, 0x00000002},
+ {0x040067e1, 0x00000006},
+ {0x000077e0, 0x00000002},
+ {0x000077e1, 0x00000002},
+ {0x000077e1, 0x00000006},
+ {0xffffffff, 0000000000},
+ {0x10000000, 0000000000},
+ {0x0003802b, 0x00000002},
+ {0x040067e0, 0x00000006},
+ {0x00007675, 0x00000002},
+ {0x00007676, 0x00000002},
+ {0x00007677, 0x00000002},
+ {0x00007678, 0x00000006},
+ {0x0003802c, 0x00000002},
+ {0x04002676, 0x00000002},
+ {0x00007677, 0x00000002},
+ {0x00007678, 0x00000006},
+ {0x0000002f, 0x00000018},
+ {0x0000002f, 0x00000018},
+ {0000000000, 0x00000006},
+ {0x00000030, 0x00000018},
+ {0x00000030, 0x00000018},
+ {0000000000, 0x00000006},
+ {0x01605000, 0x00000002},
+ {0x00065000, 0x00000002},
+ {0x00098000, 0x00000002},
+ {0x00061000, 0x00000002},
+ {0x64c0603e, 0x00000004},
+ {0x000380e6, 0x00000002},
+ {0x040025c5, 0x00000002},
+ {0x00080000, 0x00000016},
+ {0000000000, 0000000000},
+ {0x0400251d, 0x00000002},
+ {0x00007580, 0x00000002},
+ {0x00067581, 0x00000002},
+ {0x04002580, 0x00000002},
+ {0x00067581, 0x00000002},
+ {0x00000049, 0x00000004},
+ {0x00005000, 0000000000},
+ {0x000380e6, 0x00000002},
+ {0x040025c5, 0x00000002},
+ {0x00061000, 0x00000002},
+ {0x0000750e, 0x00000002},
+ {0x00019000, 0x00000002},
+ {0x00011055, 0x00000014},
+ {0x00000055, 0x00000012},
+ {0x0400250f, 0x00000002},
+ {0x0000504f, 0x00000004},
+ {0x000380e6, 0x00000002},
+ {0x040025c5, 0x00000002},
+ {0x00007565, 0x00000002},
+ {0x00007566, 0x00000002},
+ {0x00000058, 0x00000004},
+ {0x000380e6, 0x00000002},
+ {0x040025c5, 0x00000002},
+ {0x01e655b4, 0x00000002},
+ {0x4401b0e4, 0x00000002},
+ {0x01c110e4, 0x00000002},
+ {0x26667066, 0x00000018},
+ {0x040c2565, 0x00000002},
+ {0x00000066, 0x00000018},
+ {0x04002564, 0x00000002},
+ {0x00007566, 0x00000002},
+ {0x0000005d, 0x00000004},
+ {0x00401069, 0x00000008},
+ {0x00101000, 0x00000002},
+ {0x000d80ff, 0x00000002},
+ {0x0080006c, 0x00000008},
+ {0x000f9000, 0x00000002},
+ {0x000e00ff, 0x00000002},
+ {0000000000, 0x00000006},
+ {0x0000008f, 0x00000018},
+ {0x0000005b, 0x00000004},
+ {0x000380e6, 0x00000002},
+ {0x040025c5, 0x00000002},
+ {0x00007576, 0x00000002},
+ {0x00065000, 0x00000002},
+ {0x00009000, 0x00000002},
+ {0x00041000, 0x00000002},
+ {0x0c00350e, 0x00000002},
+ {0x00049000, 0x00000002},
+ {0x00051000, 0x00000002},
+ {0x01e785f8, 0x00000002},
+ {0x00200000, 0x00000002},
+ {0x0060007e, 0x0000000c},
+ {0x00007563, 0x00000002},
+ {0x006075f0, 0x00000021},
+ {0x20007073, 0x00000004},
+ {0x00005073, 0x00000004},
+ {0x000380e6, 0x00000002},
+ {0x040025c5, 0x00000002},
+ {0x00007576, 0x00000002},
+ {0x00007577, 0x00000002},
+ {0x0000750e, 0x00000002},
+ {0x0000750f, 0x00000002},
+ {0x00a05000, 0x00000002},
+ {0x00600083, 0x0000000c},
+ {0x006075f0, 0x00000021},
+ {0x000075f8, 0x00000002},
+ {0x00000083, 0x00000004},
+ {0x000a750e, 0x00000002},
+ {0x000380e6, 0x00000002},
+ {0x040025c5, 0x00000002},
+ {0x0020750f, 0x00000002},
+ {0x00600086, 0x00000004},
+ {0x00007570, 0x00000002},
+ {0x00007571, 0x00000002},
+ {0x00007572, 0x00000006},
+ {0x000380e6, 0x00000002},
+ {0x040025c5, 0x00000002},
+ {0x00005000, 0x00000002},
+ {0x00a05000, 0x00000002},
+ {0x00007568, 0x00000002},
+ {0x00061000, 0x00000002},
+ {0x00000095, 0x0000000c},
+ {0x00058000, 0x00000002},
+ {0x0c607562, 0x00000002},
+ {0x00000097, 0x00000004},
+ {0x000380e6, 0x00000002},
+ {0x040025c5, 0x00000002},
+ {0x00600096, 0x00000004},
+ {0x400070e5, 0000000000},
+ {0x000380e6, 0x00000002},
+ {0x040025c5, 0x00000002},
+ {0x000380e5, 0x00000002},
+ {0x000000a8, 0x0000001c},
+ {0x000650aa, 0x00000018},
+ {0x040025bb, 0x00000002},
+ {0x000610ab, 0x00000018},
+ {0x040075bc, 0000000000},
+ {0x000075bb, 0x00000002},
+ {0x000075bc, 0000000000},
+ {0x00090000, 0x00000006},
+ {0x00090000, 0x00000002},
+ {0x000d8002, 0x00000006},
+ {0x00007832, 0x00000002},
+ {0x00005000, 0x00000002},
+ {0x000380e7, 0x00000002},
+ {0x04002c97, 0x00000002},
+ {0x00007820, 0x00000002},
+ {0x00007821, 0x00000002},
+ {0x00007800, 0000000000},
+ {0x01200000, 0x00000002},
+ {0x20077000, 0x00000002},
+ {0x01200000, 0x00000002},
+ {0x20007000, 0x00000002},
+ {0x00061000, 0x00000002},
+ {0x0120751b, 0x00000002},
+ {0x8040750a, 0x00000002},
+ {0x8040750b, 0x00000002},
+ {0x00110000, 0x00000002},
+ {0x000380e5, 0x00000002},
+ {0x000000c6, 0x0000001c},
+ {0x000610ab, 0x00000018},
+ {0x844075bd, 0x00000002},
+ {0x000610aa, 0x00000018},
+ {0x840075bb, 0x00000002},
+ {0x000610ab, 0x00000018},
+ {0x844075bc, 0x00000002},
+ {0x000000c9, 0x00000004},
+ {0x804075bd, 0x00000002},
+ {0x800075bb, 0x00000002},
+ {0x804075bc, 0x00000002},
+ {0x00108000, 0x00000002},
+ {0x01400000, 0x00000002},
+ {0x006000cd, 0x0000000c},
+ {0x20c07000, 0x00000020},
+ {0x000000cf, 0x00000012},
+ {0x00800000, 0x00000006},
+ {0x0080751d, 0x00000006},
+ {0000000000, 0000000000},
+ {0x0000775c, 0x00000002},
+ {0x00a05000, 0x00000002},
+ {0x00661000, 0x00000002},
+ {0x0460275d, 0x00000020},
+ {0x00004000, 0000000000},
+ {0x01e00830, 0x00000002},
+ {0x21007000, 0000000000},
+ {0x6464614d, 0000000000},
+ {0x69687420, 0000000000},
+ {0x00000073, 0000000000},
+ {0000000000, 0000000000},
+ {0x00005000, 0x00000002},
+ {0x000380d0, 0x00000002},
+ {0x040025e0, 0x00000002},
+ {0x000075e1, 0000000000},
+ {0x00000001, 0000000000},
+ {0x000380e0, 0x00000002},
+ {0x04002394, 0x00000002},
+ {0x00005000, 0000000000},
+ {0000000000, 0000000000},
+ {0000000000, 0000000000},
+ {0x00000008, 0000000000},
+ {0x00000004, 0000000000},
+ {0000000000, 0000000000},
+ {0000000000, 0000000000},
+ {0000000000, 0000000000},
+ {0000000000, 0000000000},
+ {0000000000, 0000000000},
+ {0000000000, 0000000000},
+ {0000000000, 0000000000},
+ {0000000000, 0000000000},
+ {0000000000, 0000000000},
+ {0000000000, 0000000000},
+ {0000000000, 0000000000},
+ {0000000000, 0000000000},
+ {0000000000, 0000000000},
+ {0000000000, 0000000000},
+ {0000000000, 0000000000},
+ {0000000000, 0000000000},
+ {0000000000, 0000000000},
+ {0000000000, 0000000000},
+ {0000000000, 0000000000},
+ {0000000000, 0000000000},
+ {0000000000, 0000000000},
+ {0000000000, 0000000000},
+ {0000000000, 0000000000},
+ {0000000000, 0000000000},
};
static u32 R300_cp_microcode[][2] = {
- { 0x4200e000, 0000000000 },
- { 0x4000e000, 0000000000 },
- { 0x000000af, 0x00000008 },
- { 0x000000b3, 0x00000008 },
- { 0x6c5a504f, 0000000000 },
- { 0x4f4f497a, 0000000000 },
- { 0x5a578288, 0000000000 },
- { 0x4f91906a, 0000000000 },
- { 0x4f4f4f4f, 0000000000 },
- { 0x4fe24f44, 0000000000 },
- { 0x4f9c9c9c, 0000000000 },
- { 0xdc4f4fde, 0000000000 },
- { 0xa1cd4f4f, 0000000000 },
- { 0xd29d9d9d, 0000000000 },
- { 0x4f0f9fd7, 0000000000 },
- { 0x000ca000, 0x00000004 },
- { 0x000d0012, 0x00000038 },
- { 0x0000e8b4, 0x00000004 },
- { 0x000d0014, 0x00000038 },
- { 0x0000e8b6, 0x00000004 },
- { 0x000d0016, 0x00000038 },
- { 0x0000e854, 0x00000004 },
- { 0x000d0018, 0x00000038 },
- { 0x0000e855, 0x00000004 },
- { 0x000d001a, 0x00000038 },
- { 0x0000e856, 0x00000004 },
- { 0x000d001c, 0x00000038 },
- { 0x0000e857, 0x00000004 },
- { 0x000d001e, 0x00000038 },
- { 0x0000e824, 0x00000004 },
- { 0x000d0020, 0x00000038 },
- { 0x0000e825, 0x00000004 },
- { 0x000d0022, 0x00000038 },
- { 0x0000e830, 0x00000004 },
- { 0x000d0024, 0x00000038 },
- { 0x0000f0c0, 0x00000004 },
- { 0x000d0026, 0x00000038 },
- { 0x0000f0c1, 0x00000004 },
- { 0x000d0028, 0x00000038 },
- { 0x0000f041, 0x00000004 },
- { 0x000d002a, 0x00000038 },
- { 0x0000f184, 0x00000004 },
- { 0x000d002c, 0x00000038 },
- { 0x0000f185, 0x00000004 },
- { 0x000d002e, 0x00000038 },
- { 0x0000f186, 0x00000004 },
- { 0x000d0030, 0x00000038 },
- { 0x0000f187, 0x00000004 },
- { 0x000d0032, 0x00000038 },
- { 0x0000f180, 0x00000004 },
- { 0x000d0034, 0x00000038 },
- { 0x0000f393, 0x00000004 },
- { 0x000d0036, 0x00000038 },
- { 0x0000f38a, 0x00000004 },
- { 0x000d0038, 0x00000038 },
- { 0x0000f38e, 0x00000004 },
- { 0x0000e821, 0x00000004 },
- { 0x0140a000, 0x00000004 },
- { 0x00000043, 0x00000018 },
- { 0x00cce800, 0x00000004 },
- { 0x001b0001, 0x00000004 },
- { 0x08004800, 0x00000004 },
- { 0x001b0001, 0x00000004 },
- { 0x08004800, 0x00000004 },
- { 0x001b0001, 0x00000004 },
- { 0x08004800, 0x00000004 },
- { 0x0000003a, 0x00000008 },
- { 0x0000a000, 0000000000 },
- { 0x02c0a000, 0x00000004 },
- { 0x000ca000, 0x00000004 },
- { 0x00130000, 0x00000004 },
- { 0x000c2000, 0x00000004 },
- { 0xc980c045, 0x00000008 },
- { 0x2000451d, 0x00000004 },
- { 0x0000e580, 0x00000004 },
- { 0x000ce581, 0x00000004 },
- { 0x08004580, 0x00000004 },
- { 0x000ce581, 0x00000004 },
- { 0x0000004c, 0x00000008 },
- { 0x0000a000, 0000000000 },
- { 0x000c2000, 0x00000004 },
- { 0x0000e50e, 0x00000004 },
- { 0x00032000, 0x00000004 },
- { 0x00022056, 0x00000028 },
- { 0x00000056, 0x00000024 },
- { 0x0800450f, 0x00000004 },
- { 0x0000a050, 0x00000008 },
- { 0x0000e565, 0x00000004 },
- { 0x0000e566, 0x00000004 },
- { 0x00000057, 0x00000008 },
- { 0x03cca5b4, 0x00000004 },
- { 0x05432000, 0x00000004 },
- { 0x00022000, 0x00000004 },
- { 0x4ccce063, 0x00000030 },
- { 0x08274565, 0x00000004 },
- { 0x00000063, 0x00000030 },
- { 0x08004564, 0x00000004 },
- { 0x0000e566, 0x00000004 },
- { 0x0000005a, 0x00000008 },
- { 0x00802066, 0x00000010 },
- { 0x00202000, 0x00000004 },
- { 0x001b00ff, 0x00000004 },
- { 0x01000069, 0x00000010 },
- { 0x001f2000, 0x00000004 },
- { 0x001c00ff, 0x00000004 },
- { 0000000000, 0x0000000c },
- { 0x00000085, 0x00000030 },
- { 0x0000005a, 0x00000008 },
- { 0x0000e576, 0x00000004 },
- { 0x000ca000, 0x00000004 },
- { 0x00012000, 0x00000004 },
- { 0x00082000, 0x00000004 },
- { 0x1800650e, 0x00000004 },
- { 0x00092000, 0x00000004 },
- { 0x000a2000, 0x00000004 },
- { 0x000f0000, 0x00000004 },
- { 0x00400000, 0x00000004 },
- { 0x00000079, 0x00000018 },
- { 0x0000e563, 0x00000004 },
- { 0x00c0e5f9, 0x000000c2 },
- { 0x0000006e, 0x00000008 },
- { 0x0000a06e, 0x00000008 },
- { 0x0000e576, 0x00000004 },
- { 0x0000e577, 0x00000004 },
- { 0x0000e50e, 0x00000004 },
- { 0x0000e50f, 0x00000004 },
- { 0x0140a000, 0x00000004 },
- { 0x0000007c, 0x00000018 },
- { 0x00c0e5f9, 0x000000c2 },
- { 0x0000007c, 0x00000008 },
- { 0x0014e50e, 0x00000004 },
- { 0x0040e50f, 0x00000004 },
- { 0x00c0007f, 0x00000008 },
- { 0x0000e570, 0x00000004 },
- { 0x0000e571, 0x00000004 },
- { 0x0000e572, 0x0000000c },
- { 0x0000a000, 0x00000004 },
- { 0x0140a000, 0x00000004 },
- { 0x0000e568, 0x00000004 },
- { 0x000c2000, 0x00000004 },
- { 0x00000089, 0x00000018 },
- { 0x000b0000, 0x00000004 },
- { 0x18c0e562, 0x00000004 },
- { 0x0000008b, 0x00000008 },
- { 0x00c0008a, 0x00000008 },
- { 0x000700e4, 0x00000004 },
- { 0x00000097, 0x00000038 },
- { 0x000ca099, 0x00000030 },
- { 0x080045bb, 0x00000004 },
- { 0x000c209a, 0x00000030 },
- { 0x0800e5bc, 0000000000 },
- { 0x0000e5bb, 0x00000004 },
- { 0x0000e5bc, 0000000000 },
- { 0x00120000, 0x0000000c },
- { 0x00120000, 0x00000004 },
- { 0x001b0002, 0x0000000c },
- { 0x0000a000, 0x00000004 },
- { 0x0000e821, 0x00000004 },
- { 0x0000e800, 0000000000 },
- { 0x0000e821, 0x00000004 },
- { 0x0000e82e, 0000000000 },
- { 0x02cca000, 0x00000004 },
- { 0x00140000, 0x00000004 },
- { 0x000ce1cc, 0x00000004 },
- { 0x050de1cd, 0x00000004 },
- { 0x000000a7, 0x00000020 },
- { 0x4200e000, 0000000000 },
- { 0x000000ae, 0x00000038 },
- { 0x000ca000, 0x00000004 },
- { 0x00140000, 0x00000004 },
- { 0x000c2000, 0x00000004 },
- { 0x00160000, 0x00000004 },
- { 0x700ce000, 0x00000004 },
- { 0x001400aa, 0x00000008 },
- { 0x4000e000, 0000000000 },
- { 0x02400000, 0x00000004 },
- { 0x400ee000, 0x00000004 },
- { 0x02400000, 0x00000004 },
- { 0x4000e000, 0000000000 },
- { 0x000c2000, 0x00000004 },
- { 0x0240e51b, 0x00000004 },
- { 0x0080e50a, 0x00000005 },
- { 0x0080e50b, 0x00000005 },
- { 0x00220000, 0x00000004 },
- { 0x000700e4, 0x00000004 },
- { 0x000000c1, 0x00000038 },
- { 0x000c209a, 0x00000030 },
- { 0x0880e5bd, 0x00000005 },
- { 0x000c2099, 0x00000030 },
- { 0x0800e5bb, 0x00000005 },
- { 0x000c209a, 0x00000030 },
- { 0x0880e5bc, 0x00000005 },
- { 0x000000c4, 0x00000008 },
- { 0x0080e5bd, 0x00000005 },
- { 0x0000e5bb, 0x00000005 },
- { 0x0080e5bc, 0x00000005 },
- { 0x00210000, 0x00000004 },
- { 0x02800000, 0x00000004 },
- { 0x00c000c8, 0x00000018 },
- { 0x4180e000, 0x00000040 },
- { 0x000000ca, 0x00000024 },
- { 0x01000000, 0x0000000c },
- { 0x0100e51d, 0x0000000c },
- { 0x000045bb, 0x00000004 },
- { 0x000080c4, 0x00000008 },
- { 0x0000f3ce, 0x00000004 },
- { 0x0140a000, 0x00000004 },
- { 0x00cc2000, 0x00000004 },
- { 0x08c053cf, 0x00000040 },
- { 0x00008000, 0000000000 },
- { 0x0000f3d2, 0x00000004 },
- { 0x0140a000, 0x00000004 },
- { 0x00cc2000, 0x00000004 },
- { 0x08c053d3, 0x00000040 },
- { 0x00008000, 0000000000 },
- { 0x0000f39d, 0x00000004 },
- { 0x0140a000, 0x00000004 },
- { 0x00cc2000, 0x00000004 },
- { 0x08c0539e, 0x00000040 },
- { 0x00008000, 0000000000 },
- { 0x03c00830, 0x00000004 },
- { 0x4200e000, 0000000000 },
- { 0x0000a000, 0x00000004 },
- { 0x200045e0, 0x00000004 },
- { 0x0000e5e1, 0000000000 },
- { 0x00000001, 0000000000 },
- { 0x000700e1, 0x00000004 },
- { 0x0800e394, 0000000000 },
- { 0000000000, 0000000000 },
- { 0000000000, 0000000000 },
- { 0000000000, 0000000000 },
- { 0000000000, 0000000000 },
- { 0000000000, 0000000000 },
- { 0000000000, 0000000000 },
- { 0000000000, 0000000000 },
- { 0000000000, 0000000000 },
- { 0000000000, 0000000000 },
- { 0000000000, 0000000000 },
- { 0000000000, 0000000000 },
- { 0000000000, 0000000000 },
- { 0000000000, 0000000000 },
- { 0000000000, 0000000000 },
- { 0000000000, 0000000000 },
- { 0000000000, 0000000000 },
- { 0000000000, 0000000000 },
- { 0000000000, 0000000000 },
- { 0000000000, 0000000000 },
- { 0000000000, 0000000000 },
- { 0000000000, 0000000000 },
- { 0000000000, 0000000000 },
- { 0000000000, 0000000000 },
- { 0000000000, 0000000000 },
- { 0000000000, 0000000000 },
- { 0000000000, 0000000000 },
- { 0000000000, 0000000000 },
- { 0000000000, 0000000000 },
+ {0x4200e000, 0000000000},
+ {0x4000e000, 0000000000},
+ {0x000000af, 0x00000008},
+ {0x000000b3, 0x00000008},
+ {0x6c5a504f, 0000000000},
+ {0x4f4f497a, 0000000000},
+ {0x5a578288, 0000000000},
+ {0x4f91906a, 0000000000},
+ {0x4f4f4f4f, 0000000000},
+ {0x4fe24f44, 0000000000},
+ {0x4f9c9c9c, 0000000000},
+ {0xdc4f4fde, 0000000000},
+ {0xa1cd4f4f, 0000000000},
+ {0xd29d9d9d, 0000000000},
+ {0x4f0f9fd7, 0000000000},
+ {0x000ca000, 0x00000004},
+ {0x000d0012, 0x00000038},
+ {0x0000e8b4, 0x00000004},
+ {0x000d0014, 0x00000038},
+ {0x0000e8b6, 0x00000004},
+ {0x000d0016, 0x00000038},
+ {0x0000e854, 0x00000004},
+ {0x000d0018, 0x00000038},
+ {0x0000e855, 0x00000004},
+ {0x000d001a, 0x00000038},
+ {0x0000e856, 0x00000004},
+ {0x000d001c, 0x00000038},
+ {0x0000e857, 0x00000004},
+ {0x000d001e, 0x00000038},
+ {0x0000e824, 0x00000004},
+ {0x000d0020, 0x00000038},
+ {0x0000e825, 0x00000004},
+ {0x000d0022, 0x00000038},
+ {0x0000e830, 0x00000004},
+ {0x000d0024, 0x00000038},
+ {0x0000f0c0, 0x00000004},
+ {0x000d0026, 0x00000038},
+ {0x0000f0c1, 0x00000004},
+ {0x000d0028, 0x00000038},
+ {0x0000f041, 0x00000004},
+ {0x000d002a, 0x00000038},
+ {0x0000f184, 0x00000004},
+ {0x000d002c, 0x00000038},
+ {0x0000f185, 0x00000004},
+ {0x000d002e, 0x00000038},
+ {0x0000f186, 0x00000004},
+ {0x000d0030, 0x00000038},
+ {0x0000f187, 0x00000004},
+ {0x000d0032, 0x00000038},
+ {0x0000f180, 0x00000004},
+ {0x000d0034, 0x00000038},
+ {0x0000f393, 0x00000004},
+ {0x000d0036, 0x00000038},
+ {0x0000f38a, 0x00000004},
+ {0x000d0038, 0x00000038},
+ {0x0000f38e, 0x00000004},
+ {0x0000e821, 0x00000004},
+ {0x0140a000, 0x00000004},
+ {0x00000043, 0x00000018},
+ {0x00cce800, 0x00000004},
+ {0x001b0001, 0x00000004},
+ {0x08004800, 0x00000004},
+ {0x001b0001, 0x00000004},
+ {0x08004800, 0x00000004},
+ {0x001b0001, 0x00000004},
+ {0x08004800, 0x00000004},
+ {0x0000003a, 0x00000008},
+ {0x0000a000, 0000000000},
+ {0x02c0a000, 0x00000004},
+ {0x000ca000, 0x00000004},
+ {0x00130000, 0x00000004},
+ {0x000c2000, 0x00000004},
+ {0xc980c045, 0x00000008},
+ {0x2000451d, 0x00000004},
+ {0x0000e580, 0x00000004},
+ {0x000ce581, 0x00000004},
+ {0x08004580, 0x00000004},
+ {0x000ce581, 0x00000004},
+ {0x0000004c, 0x00000008},
+ {0x0000a000, 0000000000},
+ {0x000c2000, 0x00000004},
+ {0x0000e50e, 0x00000004},
+ {0x00032000, 0x00000004},
+ {0x00022056, 0x00000028},
+ {0x00000056, 0x00000024},
+ {0x0800450f, 0x00000004},
+ {0x0000a050, 0x00000008},
+ {0x0000e565, 0x00000004},
+ {0x0000e566, 0x00000004},
+ {0x00000057, 0x00000008},
+ {0x03cca5b4, 0x00000004},
+ {0x05432000, 0x00000004},
+ {0x00022000, 0x00000004},
+ {0x4ccce063, 0x00000030},
+ {0x08274565, 0x00000004},
+ {0x00000063, 0x00000030},
+ {0x08004564, 0x00000004},
+ {0x0000e566, 0x00000004},
+ {0x0000005a, 0x00000008},
+ {0x00802066, 0x00000010},
+ {0x00202000, 0x00000004},
+ {0x001b00ff, 0x00000004},
+ {0x01000069, 0x00000010},
+ {0x001f2000, 0x00000004},
+ {0x001c00ff, 0x00000004},
+ {0000000000, 0x0000000c},
+ {0x00000085, 0x00000030},
+ {0x0000005a, 0x00000008},
+ {0x0000e576, 0x00000004},
+ {0x000ca000, 0x00000004},
+ {0x00012000, 0x00000004},
+ {0x00082000, 0x00000004},
+ {0x1800650e, 0x00000004},
+ {0x00092000, 0x00000004},
+ {0x000a2000, 0x00000004},
+ {0x000f0000, 0x00000004},
+ {0x00400000, 0x00000004},
+ {0x00000079, 0x00000018},
+ {0x0000e563, 0x00000004},
+ {0x00c0e5f9, 0x000000c2},
+ {0x0000006e, 0x00000008},
+ {0x0000a06e, 0x00000008},
+ {0x0000e576, 0x00000004},
+ {0x0000e577, 0x00000004},
+ {0x0000e50e, 0x00000004},
+ {0x0000e50f, 0x00000004},
+ {0x0140a000, 0x00000004},
+ {0x0000007c, 0x00000018},
+ {0x00c0e5f9, 0x000000c2},
+ {0x0000007c, 0x00000008},
+ {0x0014e50e, 0x00000004},
+ {0x0040e50f, 0x00000004},
+ {0x00c0007f, 0x00000008},
+ {0x0000e570, 0x00000004},
+ {0x0000e571, 0x00000004},
+ {0x0000e572, 0x0000000c},
+ {0x0000a000, 0x00000004},
+ {0x0140a000, 0x00000004},
+ {0x0000e568, 0x00000004},
+ {0x000c2000, 0x00000004},
+ {0x00000089, 0x00000018},
+ {0x000b0000, 0x00000004},
+ {0x18c0e562, 0x00000004},
+ {0x0000008b, 0x00000008},
+ {0x00c0008a, 0x00000008},
+ {0x000700e4, 0x00000004},
+ {0x00000097, 0x00000038},
+ {0x000ca099, 0x00000030},
+ {0x080045bb, 0x00000004},
+ {0x000c209a, 0x00000030},
+ {0x0800e5bc, 0000000000},
+ {0x0000e5bb, 0x00000004},
+ {0x0000e5bc, 0000000000},
+ {0x00120000, 0x0000000c},
+ {0x00120000, 0x00000004},
+ {0x001b0002, 0x0000000c},
+ {0x0000a000, 0x00000004},
+ {0x0000e821, 0x00000004},
+ {0x0000e800, 0000000000},
+ {0x0000e821, 0x00000004},
+ {0x0000e82e, 0000000000},
+ {0x02cca000, 0x00000004},
+ {0x00140000, 0x00000004},
+ {0x000ce1cc, 0x00000004},
+ {0x050de1cd, 0x00000004},
+ {0x000000a7, 0x00000020},
+ {0x4200e000, 0000000000},
+ {0x000000ae, 0x00000038},
+ {0x000ca000, 0x00000004},
+ {0x00140000, 0x00000004},
+ {0x000c2000, 0x00000004},
+ {0x00160000, 0x00000004},
+ {0x700ce000, 0x00000004},
+ {0x001400aa, 0x00000008},
+ {0x4000e000, 0000000000},
+ {0x02400000, 0x00000004},
+ {0x400ee000, 0x00000004},
+ {0x02400000, 0x00000004},
+ {0x4000e000, 0000000000},
+ {0x000c2000, 0x00000004},
+ {0x0240e51b, 0x00000004},
+ {0x0080e50a, 0x00000005},
+ {0x0080e50b, 0x00000005},
+ {0x00220000, 0x00000004},
+ {0x000700e4, 0x00000004},
+ {0x000000c1, 0x00000038},
+ {0x000c209a, 0x00000030},
+ {0x0880e5bd, 0x00000005},
+ {0x000c2099, 0x00000030},
+ {0x0800e5bb, 0x00000005},
+ {0x000c209a, 0x00000030},
+ {0x0880e5bc, 0x00000005},
+ {0x000000c4, 0x00000008},
+ {0x0080e5bd, 0x00000005},
+ {0x0000e5bb, 0x00000005},
+ {0x0080e5bc, 0x00000005},
+ {0x00210000, 0x00000004},
+ {0x02800000, 0x00000004},
+ {0x00c000c8, 0x00000018},
+ {0x4180e000, 0x00000040},
+ {0x000000ca, 0x00000024},
+ {0x01000000, 0x0000000c},
+ {0x0100e51d, 0x0000000c},
+ {0x000045bb, 0x00000004},
+ {0x000080c4, 0x00000008},
+ {0x0000f3ce, 0x00000004},
+ {0x0140a000, 0x00000004},
+ {0x00cc2000, 0x00000004},
+ {0x08c053cf, 0x00000040},
+ {0x00008000, 0000000000},
+ {0x0000f3d2, 0x00000004},
+ {0x0140a000, 0x00000004},
+ {0x00cc2000, 0x00000004},
+ {0x08c053d3, 0x00000040},
+ {0x00008000, 0000000000},
+ {0x0000f39d, 0x00000004},
+ {0x0140a000, 0x00000004},
+ {0x00cc2000, 0x00000004},
+ {0x08c0539e, 0x00000040},
+ {0x00008000, 0000000000},
+ {0x03c00830, 0x00000004},
+ {0x4200e000, 0000000000},
+ {0x0000a000, 0x00000004},
+ {0x200045e0, 0x00000004},
+ {0x0000e5e1, 0000000000},
+ {0x00000001, 0000000000},
+ {0x000700e1, 0x00000004},
+ {0x0800e394, 0000000000},
+ {0000000000, 0000000000},
+ {0000000000, 0000000000},
+ {0000000000, 0000000000},
+ {0000000000, 0000000000},
+ {0000000000, 0000000000},
+ {0000000000, 0000000000},
+ {0000000000, 0000000000},
+ {0000000000, 0000000000},
+ {0000000000, 0000000000},
+ {0000000000, 0000000000},
+ {0000000000, 0000000000},
+ {0000000000, 0000000000},
+ {0000000000, 0000000000},
+ {0000000000, 0000000000},
+ {0000000000, 0000000000},
+ {0000000000, 0000000000},
+ {0000000000, 0000000000},
+ {0000000000, 0000000000},
+ {0000000000, 0000000000},
+ {0000000000, 0000000000},
+ {0000000000, 0000000000},
+ {0000000000, 0000000000},
+ {0000000000, 0000000000},
+ {0000000000, 0000000000},
+ {0000000000, 0000000000},
+ {0000000000, 0000000000},
+ {0000000000, 0000000000},
+ {0000000000, 0000000000},
};
-static int RADEON_READ_PLL(drm_device_t *dev, int addr)
+static int RADEON_READ_PLL(drm_device_t * dev, int addr)
{
drm_radeon_private_t *dev_priv = dev->dev_private;
@@ -825,145 +824,148 @@ static int RADEON_READ_PLL(drm_device_t *dev, int addr)
return RADEON_READ(RADEON_CLOCK_CNTL_DATA);
}
+static int RADEON_READ_PCIE(drm_radeon_private_t * dev_priv, int addr)
+{
+ RADEON_WRITE8(RADEON_PCIE_INDEX, addr & 0xff);
+ return RADEON_READ(RADEON_PCIE_DATA);
+}
+
#if RADEON_FIFO_DEBUG
-static void radeon_status( drm_radeon_private_t *dev_priv )
+static void radeon_status(drm_radeon_private_t * dev_priv)
{
- printk( "%s:\n", __FUNCTION__ );
- printk( "RBBM_STATUS = 0x%08x\n",
- (unsigned int)RADEON_READ( RADEON_RBBM_STATUS ) );
- printk( "CP_RB_RTPR = 0x%08x\n",
- (unsigned int)RADEON_READ( RADEON_CP_RB_RPTR ) );
- printk( "CP_RB_WTPR = 0x%08x\n",
- (unsigned int)RADEON_READ( RADEON_CP_RB_WPTR ) );
- printk( "AIC_CNTL = 0x%08x\n",
- (unsigned int)RADEON_READ( RADEON_AIC_CNTL ) );
- printk( "AIC_STAT = 0x%08x\n",
- (unsigned int)RADEON_READ( RADEON_AIC_STAT ) );
- printk( "AIC_PT_BASE = 0x%08x\n",
- (unsigned int)RADEON_READ( RADEON_AIC_PT_BASE ) );
- printk( "TLB_ADDR = 0x%08x\n",
- (unsigned int)RADEON_READ( RADEON_AIC_TLB_ADDR ) );
- printk( "TLB_DATA = 0x%08x\n",
- (unsigned int)RADEON_READ( RADEON_AIC_TLB_DATA ) );
+ printk("%s:\n", __FUNCTION__);
+ printk("RBBM_STATUS = 0x%08x\n",
+ (unsigned int)RADEON_READ(RADEON_RBBM_STATUS));
+ printk("CP_RB_RTPR = 0x%08x\n",
+ (unsigned int)RADEON_READ(RADEON_CP_RB_RPTR));
+ printk("CP_RB_WTPR = 0x%08x\n",
+ (unsigned int)RADEON_READ(RADEON_CP_RB_WPTR));
+ printk("AIC_CNTL = 0x%08x\n",
+ (unsigned int)RADEON_READ(RADEON_AIC_CNTL));
+ printk("AIC_STAT = 0x%08x\n",
+ (unsigned int)RADEON_READ(RADEON_AIC_STAT));
+ printk("AIC_PT_BASE = 0x%08x\n",
+ (unsigned int)RADEON_READ(RADEON_AIC_PT_BASE));
+ printk("TLB_ADDR = 0x%08x\n",
+ (unsigned int)RADEON_READ(RADEON_AIC_TLB_ADDR));
+ printk("TLB_DATA = 0x%08x\n",
+ (unsigned int)RADEON_READ(RADEON_AIC_TLB_DATA));
}
#endif
-
/* ================================================================
* Engine, FIFO control
*/
-static int radeon_do_pixcache_flush( drm_radeon_private_t *dev_priv )
+static int radeon_do_pixcache_flush(drm_radeon_private_t * dev_priv)
{
u32 tmp;
int i;
dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE;
- tmp = RADEON_READ( RADEON_RB2D_DSTCACHE_CTLSTAT );
+ tmp = RADEON_READ(RADEON_RB2D_DSTCACHE_CTLSTAT);
tmp |= RADEON_RB2D_DC_FLUSH_ALL;
- RADEON_WRITE( RADEON_RB2D_DSTCACHE_CTLSTAT, tmp );
+ RADEON_WRITE(RADEON_RB2D_DSTCACHE_CTLSTAT, tmp);
- for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) {
- if ( !(RADEON_READ( RADEON_RB2D_DSTCACHE_CTLSTAT )
- & RADEON_RB2D_DC_BUSY) ) {
+ for (i = 0; i < dev_priv->usec_timeout; i++) {
+ if (!(RADEON_READ(RADEON_RB2D_DSTCACHE_CTLSTAT)
+ & RADEON_RB2D_DC_BUSY)) {
return 0;
}
- DRM_UDELAY( 1 );
+ DRM_UDELAY(1);
}
#if RADEON_FIFO_DEBUG
- DRM_ERROR( "failed!\n" );
- radeon_status( dev_priv );
+ DRM_ERROR("failed!\n");
+ radeon_status(dev_priv);
#endif
return DRM_ERR(EBUSY);
}
-static int radeon_do_wait_for_fifo( drm_radeon_private_t *dev_priv,
- int entries )
+static int radeon_do_wait_for_fifo(drm_radeon_private_t * dev_priv, int entries)
{
int i;
dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE;
- for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) {
- int slots = ( RADEON_READ( RADEON_RBBM_STATUS )
- & RADEON_RBBM_FIFOCNT_MASK );
- if ( slots >= entries ) return 0;
- DRM_UDELAY( 1 );
+ for (i = 0; i < dev_priv->usec_timeout; i++) {
+ int slots = (RADEON_READ(RADEON_RBBM_STATUS)
+ & RADEON_RBBM_FIFOCNT_MASK);
+ if (slots >= entries)
+ return 0;
+ DRM_UDELAY(1);
}
#if RADEON_FIFO_DEBUG
- DRM_ERROR( "failed!\n" );
- radeon_status( dev_priv );
+ DRM_ERROR("failed!\n");
+ radeon_status(dev_priv);
#endif
return DRM_ERR(EBUSY);
}
-static int radeon_do_wait_for_idle( drm_radeon_private_t *dev_priv )
+static int radeon_do_wait_for_idle(drm_radeon_private_t * dev_priv)
{
int i, ret;
dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE;
- ret = radeon_do_wait_for_fifo( dev_priv, 64 );
- if ( ret ) return ret;
+ ret = radeon_do_wait_for_fifo(dev_priv, 64);
+ if (ret)
+ return ret;
- for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) {
- if ( !(RADEON_READ( RADEON_RBBM_STATUS )
- & RADEON_RBBM_ACTIVE) ) {
- radeon_do_pixcache_flush( dev_priv );
+ for (i = 0; i < dev_priv->usec_timeout; i++) {
+ if (!(RADEON_READ(RADEON_RBBM_STATUS)
+ & RADEON_RBBM_ACTIVE)) {
+ radeon_do_pixcache_flush(dev_priv);
return 0;
}
- DRM_UDELAY( 1 );
+ DRM_UDELAY(1);
}
#if RADEON_FIFO_DEBUG
- DRM_ERROR( "failed!\n" );
- radeon_status( dev_priv );
+ DRM_ERROR("failed!\n");
+ radeon_status(dev_priv);
#endif
return DRM_ERR(EBUSY);
}
-
/* ================================================================
* CP control, initialization
*/
/* Load the microcode for the CP */
-static void radeon_cp_load_microcode( drm_radeon_private_t *dev_priv )
+static void radeon_cp_load_microcode(drm_radeon_private_t * dev_priv)
{
int i;
- DRM_DEBUG( "\n" );
+ DRM_DEBUG("\n");
- radeon_do_wait_for_idle( dev_priv );
+ radeon_do_wait_for_idle(dev_priv);
- RADEON_WRITE( RADEON_CP_ME_RAM_ADDR, 0 );
+ RADEON_WRITE(RADEON_CP_ME_RAM_ADDR, 0);
- if (dev_priv->microcode_version==UCODE_R200) {
+ if (dev_priv->microcode_version == UCODE_R200) {
DRM_INFO("Loading R200 Microcode\n");
- for ( i = 0 ; i < 256 ; i++ )
- {
- RADEON_WRITE( RADEON_CP_ME_RAM_DATAH,
- R200_cp_microcode[i][1] );
- RADEON_WRITE( RADEON_CP_ME_RAM_DATAL,
- R200_cp_microcode[i][0] );
+ for (i = 0; i < 256; i++) {
+ RADEON_WRITE(RADEON_CP_ME_RAM_DATAH,
+ R200_cp_microcode[i][1]);
+ RADEON_WRITE(RADEON_CP_ME_RAM_DATAL,
+ R200_cp_microcode[i][0]);
}
- } else if (dev_priv->microcode_version==UCODE_R300) {
+ } else if (dev_priv->microcode_version == UCODE_R300) {
DRM_INFO("Loading R300 Microcode\n");
- for ( i = 0 ; i < 256 ; i++ )
- {
- RADEON_WRITE( RADEON_CP_ME_RAM_DATAH,
- R300_cp_microcode[i][1] );
- RADEON_WRITE( RADEON_CP_ME_RAM_DATAL,
- R300_cp_microcode[i][0] );
+ for (i = 0; i < 256; i++) {
+ RADEON_WRITE(RADEON_CP_ME_RAM_DATAH,
+ R300_cp_microcode[i][1]);
+ RADEON_WRITE(RADEON_CP_ME_RAM_DATAL,
+ R300_cp_microcode[i][0]);
}
} else {
- for ( i = 0 ; i < 256 ; i++ ) {
- RADEON_WRITE( RADEON_CP_ME_RAM_DATAH,
- radeon_cp_microcode[i][1] );
- RADEON_WRITE( RADEON_CP_ME_RAM_DATAL,
- radeon_cp_microcode[i][0] );
+ for (i = 0; i < 256; i++) {
+ RADEON_WRITE(RADEON_CP_ME_RAM_DATAH,
+ radeon_cp_microcode[i][1]);
+ RADEON_WRITE(RADEON_CP_ME_RAM_DATAL,
+ radeon_cp_microcode[i][0]);
}
}
}
@@ -972,25 +974,25 @@ static void radeon_cp_load_microcode( drm_radeon_private_t *dev_priv )
* prior to a wait for idle, as it informs the engine that the command
* stream is ending.
*/
-static void radeon_do_cp_flush( drm_radeon_private_t *dev_priv )
+static void radeon_do_cp_flush(drm_radeon_private_t * dev_priv)
{
- DRM_DEBUG( "\n" );
+ DRM_DEBUG("\n");
#if 0
u32 tmp;
- tmp = RADEON_READ( RADEON_CP_RB_WPTR ) | (1 << 31);
- RADEON_WRITE( RADEON_CP_RB_WPTR, tmp );
+ tmp = RADEON_READ(RADEON_CP_RB_WPTR) | (1 << 31);
+ RADEON_WRITE(RADEON_CP_RB_WPTR, tmp);
#endif
}
/* Wait for the CP to go idle.
*/
-int radeon_do_cp_idle( drm_radeon_private_t *dev_priv )
+int radeon_do_cp_idle(drm_radeon_private_t * dev_priv)
{
RING_LOCALS;
- DRM_DEBUG( "\n" );
+ DRM_DEBUG("\n");
- BEGIN_RING( 6 );
+ BEGIN_RING(6);
RADEON_PURGE_CACHE();
RADEON_PURGE_ZCACHE();
@@ -999,23 +1001,23 @@ int radeon_do_cp_idle( drm_radeon_private_t *dev_priv )
ADVANCE_RING();
COMMIT_RING();
- return radeon_do_wait_for_idle( dev_priv );
+ return radeon_do_wait_for_idle(dev_priv);
}
/* Start the Command Processor.
*/
-static void radeon_do_cp_start( drm_radeon_private_t *dev_priv )
+static void radeon_do_cp_start(drm_radeon_private_t * dev_priv)
{
RING_LOCALS;
- DRM_DEBUG( "\n" );
+ DRM_DEBUG("\n");
- radeon_do_wait_for_idle( dev_priv );
+ radeon_do_wait_for_idle(dev_priv);
- RADEON_WRITE( RADEON_CP_CSQ_CNTL, dev_priv->cp_mode );
+ RADEON_WRITE(RADEON_CP_CSQ_CNTL, dev_priv->cp_mode);
dev_priv->cp_running = 1;
- BEGIN_RING( 6 );
+ BEGIN_RING(6);
RADEON_PURGE_CACHE();
RADEON_PURGE_ZCACHE();
@@ -1029,14 +1031,14 @@ static void radeon_do_cp_start( drm_radeon_private_t *dev_priv )
* commands, so you must wait for the CP command stream to complete
* before calling this routine.
*/
-static void radeon_do_cp_reset( drm_radeon_private_t *dev_priv )
+static void radeon_do_cp_reset(drm_radeon_private_t * dev_priv)
{
u32 cur_read_ptr;
- DRM_DEBUG( "\n" );
+ DRM_DEBUG("\n");
- cur_read_ptr = RADEON_READ( RADEON_CP_RB_RPTR );
- RADEON_WRITE( RADEON_CP_RB_WPTR, cur_read_ptr );
- SET_RING_HEAD( dev_priv, cur_read_ptr );
+ cur_read_ptr = RADEON_READ(RADEON_CP_RB_RPTR);
+ RADEON_WRITE(RADEON_CP_RB_WPTR, cur_read_ptr);
+ SET_RING_HEAD(dev_priv, cur_read_ptr);
dev_priv->ring.tail = cur_read_ptr;
}
@@ -1044,91 +1046,90 @@ static void radeon_do_cp_reset( drm_radeon_private_t *dev_priv )
* commands, so you must flush the command stream and wait for the CP
* to go idle before calling this routine.
*/
-static void radeon_do_cp_stop( drm_radeon_private_t *dev_priv )
+static void radeon_do_cp_stop(drm_radeon_private_t * dev_priv)
{
- DRM_DEBUG( "\n" );
+ DRM_DEBUG("\n");
- RADEON_WRITE( RADEON_CP_CSQ_CNTL, RADEON_CSQ_PRIDIS_INDDIS );
+ RADEON_WRITE(RADEON_CP_CSQ_CNTL, RADEON_CSQ_PRIDIS_INDDIS);
dev_priv->cp_running = 0;
}
/* Reset the engine. This will stop the CP if it is running.
*/
-static int radeon_do_engine_reset( drm_device_t *dev )
+static int radeon_do_engine_reset(drm_device_t * dev)
{
drm_radeon_private_t *dev_priv = dev->dev_private;
u32 clock_cntl_index, mclk_cntl, rbbm_soft_reset;
- DRM_DEBUG( "\n" );
-
- radeon_do_pixcache_flush( dev_priv );
-
- clock_cntl_index = RADEON_READ( RADEON_CLOCK_CNTL_INDEX );
- mclk_cntl = RADEON_READ_PLL( dev, RADEON_MCLK_CNTL );
-
- RADEON_WRITE_PLL( RADEON_MCLK_CNTL, ( mclk_cntl |
- RADEON_FORCEON_MCLKA |
- RADEON_FORCEON_MCLKB |
- RADEON_FORCEON_YCLKA |
- RADEON_FORCEON_YCLKB |
- RADEON_FORCEON_MC |
- RADEON_FORCEON_AIC ) );
-
- rbbm_soft_reset = RADEON_READ( RADEON_RBBM_SOFT_RESET );
+ DRM_DEBUG("\n");
- RADEON_WRITE( RADEON_RBBM_SOFT_RESET, ( rbbm_soft_reset |
- RADEON_SOFT_RESET_CP |
+ radeon_do_pixcache_flush(dev_priv);
+
+ clock_cntl_index = RADEON_READ(RADEON_CLOCK_CNTL_INDEX);
+ mclk_cntl = RADEON_READ_PLL(dev, RADEON_MCLK_CNTL);
+
+ RADEON_WRITE_PLL(RADEON_MCLK_CNTL, (mclk_cntl |
+ RADEON_FORCEON_MCLKA |
+ RADEON_FORCEON_MCLKB |
+ RADEON_FORCEON_YCLKA |
+ RADEON_FORCEON_YCLKB |
+ RADEON_FORCEON_MC |
+ RADEON_FORCEON_AIC));
+
+ rbbm_soft_reset = RADEON_READ(RADEON_RBBM_SOFT_RESET);
+
+ RADEON_WRITE(RADEON_RBBM_SOFT_RESET, (rbbm_soft_reset |
+ RADEON_SOFT_RESET_CP |
+ RADEON_SOFT_RESET_HI |
+ RADEON_SOFT_RESET_SE |
+ RADEON_SOFT_RESET_RE |
+ RADEON_SOFT_RESET_PP |
+ RADEON_SOFT_RESET_E2 |
+ RADEON_SOFT_RESET_RB));
+ RADEON_READ(RADEON_RBBM_SOFT_RESET);
+ RADEON_WRITE(RADEON_RBBM_SOFT_RESET, (rbbm_soft_reset &
+ ~(RADEON_SOFT_RESET_CP |
RADEON_SOFT_RESET_HI |
RADEON_SOFT_RESET_SE |
RADEON_SOFT_RESET_RE |
RADEON_SOFT_RESET_PP |
RADEON_SOFT_RESET_E2 |
- RADEON_SOFT_RESET_RB ) );
- RADEON_READ( RADEON_RBBM_SOFT_RESET );
- RADEON_WRITE( RADEON_RBBM_SOFT_RESET, ( rbbm_soft_reset &
- ~( RADEON_SOFT_RESET_CP |
- RADEON_SOFT_RESET_HI |
- RADEON_SOFT_RESET_SE |
- RADEON_SOFT_RESET_RE |
- RADEON_SOFT_RESET_PP |
- RADEON_SOFT_RESET_E2 |
- RADEON_SOFT_RESET_RB ) ) );
- RADEON_READ( RADEON_RBBM_SOFT_RESET );
-
-
- RADEON_WRITE_PLL( RADEON_MCLK_CNTL, mclk_cntl );
- RADEON_WRITE( RADEON_CLOCK_CNTL_INDEX, clock_cntl_index );
- RADEON_WRITE( RADEON_RBBM_SOFT_RESET, rbbm_soft_reset );
+ RADEON_SOFT_RESET_RB)));
+ RADEON_READ(RADEON_RBBM_SOFT_RESET);
+
+ RADEON_WRITE_PLL(RADEON_MCLK_CNTL, mclk_cntl);
+ RADEON_WRITE(RADEON_CLOCK_CNTL_INDEX, clock_cntl_index);
+ RADEON_WRITE(RADEON_RBBM_SOFT_RESET, rbbm_soft_reset);
/* Reset the CP ring */
- radeon_do_cp_reset( dev_priv );
+ radeon_do_cp_reset(dev_priv);
/* The CP is no longer running after an engine reset */
dev_priv->cp_running = 0;
/* Reset any pending vertex, indirect buffers */
- radeon_freelist_reset( dev );
+ radeon_freelist_reset(dev);
return 0;
}
-static void radeon_cp_init_ring_buffer( drm_device_t *dev,
- drm_radeon_private_t *dev_priv )
+static void radeon_cp_init_ring_buffer(drm_device_t * dev,
+ drm_radeon_private_t * dev_priv)
{
u32 ring_start, cur_read_ptr;
u32 tmp;
/* Initialize the memory controller */
- RADEON_WRITE( RADEON_MC_FB_LOCATION,
- ( ( dev_priv->gart_vm_start - 1 ) & 0xffff0000 )
- | ( dev_priv->fb_location >> 16 ) );
+ RADEON_WRITE(RADEON_MC_FB_LOCATION,
+ ((dev_priv->gart_vm_start - 1) & 0xffff0000)
+ | (dev_priv->fb_location >> 16));
#if __OS_HAS_AGP
- if ( !dev_priv->is_pci ) {
- RADEON_WRITE( RADEON_MC_AGP_LOCATION,
- (((dev_priv->gart_vm_start - 1 +
- dev_priv->gart_size) & 0xffff0000) |
- (dev_priv->gart_vm_start >> 16)) );
+ if (!dev_priv->is_pci) {
+ RADEON_WRITE(RADEON_MC_AGP_LOCATION,
+ (((dev_priv->gart_vm_start - 1 +
+ dev_priv->gart_size) & 0xffff0000) |
+ (dev_priv->gart_vm_start >> 16)));
ring_start = (dev_priv->cp_ring->offset
- dev->agp->base
@@ -1139,25 +1140,24 @@ static void radeon_cp_init_ring_buffer( drm_device_t *dev,
- (unsigned long)dev->sg->virtual
+ dev_priv->gart_vm_start);
- RADEON_WRITE( RADEON_CP_RB_BASE, ring_start );
+ RADEON_WRITE(RADEON_CP_RB_BASE, ring_start);
/* Set the write pointer delay */
- RADEON_WRITE( RADEON_CP_RB_WPTR_DELAY, 0 );
+ RADEON_WRITE(RADEON_CP_RB_WPTR_DELAY, 0);
/* Initialize the ring buffer's read and write pointers */
- cur_read_ptr = RADEON_READ( RADEON_CP_RB_RPTR );
- RADEON_WRITE( RADEON_CP_RB_WPTR, cur_read_ptr );
- SET_RING_HEAD( dev_priv, cur_read_ptr );
+ cur_read_ptr = RADEON_READ(RADEON_CP_RB_RPTR);
+ RADEON_WRITE(RADEON_CP_RB_WPTR, cur_read_ptr);
+ SET_RING_HEAD(dev_priv, cur_read_ptr);
dev_priv->ring.tail = cur_read_ptr;
#if __OS_HAS_AGP
- if ( !dev_priv->is_pci ) {
+ if (!dev_priv->is_pci) {
/* set RADEON_AGP_BASE here instead of relying on X from user space */
RADEON_WRITE(RADEON_AGP_BASE, (unsigned int)dev->agp->base);
- RADEON_WRITE( RADEON_CP_RB_RPTR_ADDR,
- dev_priv->ring_rptr->offset
- - dev->agp->base
- + dev_priv->gart_vm_start);
+ RADEON_WRITE(RADEON_CP_RB_RPTR_ADDR,
+ dev_priv->ring_rptr->offset
+ - dev->agp->base + dev_priv->gart_vm_start);
} else
#endif
{
@@ -1168,11 +1168,10 @@ static void radeon_cp_init_ring_buffer( drm_device_t *dev,
(unsigned long)dev->sg->virtual;
page_ofs = tmp_ofs >> PAGE_SHIFT;
- RADEON_WRITE( RADEON_CP_RB_RPTR_ADDR,
- entry->busaddr[page_ofs]);
- DRM_DEBUG( "ring rptr: offset=0x%08lx handle=0x%08lx\n",
- (unsigned long) entry->busaddr[page_ofs],
- entry->handle + tmp_ofs );
+ RADEON_WRITE(RADEON_CP_RB_RPTR_ADDR, entry->busaddr[page_ofs]);
+ DRM_DEBUG("ring rptr: offset=0x%08lx handle=0x%08lx\n",
+ (unsigned long)entry->busaddr[page_ofs],
+ entry->handle + tmp_ofs);
}
/* Initialize the scratch register pointer. This will cause
@@ -1182,127 +1181,168 @@ static void radeon_cp_init_ring_buffer( drm_device_t *dev,
* We simply put this behind the ring read pointer, this works
* with PCI GART as well as (whatever kind of) AGP GART
*/
- RADEON_WRITE( RADEON_SCRATCH_ADDR, RADEON_READ( RADEON_CP_RB_RPTR_ADDR )
- + RADEON_SCRATCH_REG_OFFSET );
+ RADEON_WRITE(RADEON_SCRATCH_ADDR, RADEON_READ(RADEON_CP_RB_RPTR_ADDR)
+ + RADEON_SCRATCH_REG_OFFSET);
dev_priv->scratch = ((__volatile__ u32 *)
dev_priv->ring_rptr->handle +
(RADEON_SCRATCH_REG_OFFSET / sizeof(u32)));
- RADEON_WRITE( RADEON_SCRATCH_UMSK, 0x7 );
+ RADEON_WRITE(RADEON_SCRATCH_UMSK, 0x7);
/* Writeback doesn't seem to work everywhere, test it first */
- DRM_WRITE32( dev_priv->ring_rptr, RADEON_SCRATCHOFF(1), 0 );
- RADEON_WRITE( RADEON_SCRATCH_REG1, 0xdeadbeef );
+ DRM_WRITE32(dev_priv->ring_rptr, RADEON_SCRATCHOFF(1), 0);
+ RADEON_WRITE(RADEON_SCRATCH_REG1, 0xdeadbeef);
- for ( tmp = 0 ; tmp < dev_priv->usec_timeout ; tmp++ ) {
- if ( DRM_READ32( dev_priv->ring_rptr, RADEON_SCRATCHOFF(1) ) == 0xdeadbeef )
+ for (tmp = 0; tmp < dev_priv->usec_timeout; tmp++) {
+ if (DRM_READ32(dev_priv->ring_rptr, RADEON_SCRATCHOFF(1)) ==
+ 0xdeadbeef)
break;
- DRM_UDELAY( 1 );
+ DRM_UDELAY(1);
}
- if ( tmp < dev_priv->usec_timeout ) {
+ if (tmp < dev_priv->usec_timeout) {
dev_priv->writeback_works = 1;
- DRM_DEBUG( "writeback test succeeded, tmp=%d\n", tmp );
+ DRM_DEBUG("writeback test succeeded, tmp=%d\n", tmp);
} else {
dev_priv->writeback_works = 0;
- DRM_DEBUG( "writeback test failed\n" );
+ DRM_DEBUG("writeback test failed\n");
+ }
+ if (radeon_no_wb == 1) {
+ dev_priv->writeback_works = 0;
+ DRM_DEBUG("writeback forced off\n");
}
dev_priv->sarea_priv->last_frame = dev_priv->scratch[0] = 0;
- RADEON_WRITE( RADEON_LAST_FRAME_REG,
- dev_priv->sarea_priv->last_frame );
+ RADEON_WRITE(RADEON_LAST_FRAME_REG, dev_priv->sarea_priv->last_frame);
dev_priv->sarea_priv->last_dispatch = dev_priv->scratch[1] = 0;
- RADEON_WRITE( RADEON_LAST_DISPATCH_REG,
- dev_priv->sarea_priv->last_dispatch );
+ RADEON_WRITE(RADEON_LAST_DISPATCH_REG,
+ dev_priv->sarea_priv->last_dispatch);
dev_priv->sarea_priv->last_clear = dev_priv->scratch[2] = 0;
- RADEON_WRITE( RADEON_LAST_CLEAR_REG,
- dev_priv->sarea_priv->last_clear );
+ RADEON_WRITE(RADEON_LAST_CLEAR_REG, dev_priv->sarea_priv->last_clear);
/* Set ring buffer size */
#ifdef __BIG_ENDIAN
- RADEON_WRITE( RADEON_CP_RB_CNTL, dev_priv->ring.size_l2qw | RADEON_BUF_SWAP_32BIT );
+ RADEON_WRITE(RADEON_CP_RB_CNTL,
+ dev_priv->ring.size_l2qw | RADEON_BUF_SWAP_32BIT);
#else
- RADEON_WRITE( RADEON_CP_RB_CNTL, dev_priv->ring.size_l2qw );
+ RADEON_WRITE(RADEON_CP_RB_CNTL, dev_priv->ring.size_l2qw);
#endif
- radeon_do_wait_for_idle( dev_priv );
+ radeon_do_wait_for_idle(dev_priv);
/* Turn on bus mastering */
- tmp = RADEON_READ( RADEON_BUS_CNTL ) & ~RADEON_BUS_MASTER_DIS;
- RADEON_WRITE( RADEON_BUS_CNTL, tmp );
+ tmp = RADEON_READ(RADEON_BUS_CNTL) & ~RADEON_BUS_MASTER_DIS;
+ RADEON_WRITE(RADEON_BUS_CNTL, tmp);
/* Sync everything up */
- RADEON_WRITE( RADEON_ISYNC_CNTL,
- (RADEON_ISYNC_ANY2D_IDLE3D |
- RADEON_ISYNC_ANY3D_IDLE2D |
- RADEON_ISYNC_WAIT_IDLEGUI |
- RADEON_ISYNC_CPSCRATCH_IDLEGUI) );
+ RADEON_WRITE(RADEON_ISYNC_CNTL,
+ (RADEON_ISYNC_ANY2D_IDLE3D |
+ RADEON_ISYNC_ANY3D_IDLE2D |
+ RADEON_ISYNC_WAIT_IDLEGUI |
+ RADEON_ISYNC_CPSCRATCH_IDLEGUI));
+}
+
+/* Enable or disable PCI-E GART on the chip */
+static void radeon_set_pciegart(drm_radeon_private_t * dev_priv, int on)
+{
+ u32 tmp = RADEON_READ_PCIE(dev_priv, RADEON_PCIE_TX_GART_CNTL);
+ if (on) {
+
+ DRM_DEBUG("programming pcie %08X %08lX %08X\n",
+ dev_priv->gart_vm_start,
+ (long)dev_priv->gart_info.bus_addr,
+ dev_priv->gart_size);
+ RADEON_WRITE_PCIE(RADEON_PCIE_TX_DISCARD_RD_ADDR_LO,
+ dev_priv->gart_vm_start);
+ RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_BASE,
+ dev_priv->gart_info.bus_addr);
+ RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_START_LO,
+ dev_priv->gart_vm_start);
+ RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_END_LO,
+ dev_priv->gart_vm_start +
+ dev_priv->gart_size - 1);
+
+ RADEON_WRITE(RADEON_MC_AGP_LOCATION, 0xffffffc0); /* ?? */
+
+ RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_CNTL,
+ RADEON_PCIE_TX_GART_EN);
+ } else {
+ RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_CNTL,
+ tmp & ~RADEON_PCIE_TX_GART_EN);
+ }
}
/* Enable or disable PCI GART on the chip */
-static void radeon_set_pcigart( drm_radeon_private_t *dev_priv, int on )
+static void radeon_set_pcigart(drm_radeon_private_t * dev_priv, int on)
{
- u32 tmp = RADEON_READ( RADEON_AIC_CNTL );
+ u32 tmp = RADEON_READ(RADEON_AIC_CNTL);
+
+ if (dev_priv->flags & CHIP_IS_PCIE) {
+ radeon_set_pciegart(dev_priv, on);
+ return;
+ }
- if ( on ) {
- RADEON_WRITE( RADEON_AIC_CNTL, tmp | RADEON_PCIGART_TRANSLATE_EN );
+ if (on) {
+ RADEON_WRITE(RADEON_AIC_CNTL,
+ tmp | RADEON_PCIGART_TRANSLATE_EN);
/* set PCI GART page-table base address
*/
- RADEON_WRITE( RADEON_AIC_PT_BASE, dev_priv->bus_pci_gart );
+ RADEON_WRITE(RADEON_AIC_PT_BASE, dev_priv->gart_info.bus_addr);
/* set address range for PCI address translate
*/
- RADEON_WRITE( RADEON_AIC_LO_ADDR, dev_priv->gart_vm_start );
- RADEON_WRITE( RADEON_AIC_HI_ADDR, dev_priv->gart_vm_start
- + dev_priv->gart_size - 1);
+ RADEON_WRITE(RADEON_AIC_LO_ADDR, dev_priv->gart_vm_start);
+ RADEON_WRITE(RADEON_AIC_HI_ADDR, dev_priv->gart_vm_start
+ + dev_priv->gart_size - 1);
/* Turn off AGP aperture -- is this required for PCI GART?
*/
- RADEON_WRITE( RADEON_MC_AGP_LOCATION, 0xffffffc0 ); /* ?? */
- RADEON_WRITE( RADEON_AGP_COMMAND, 0 ); /* clear AGP_COMMAND */
+ RADEON_WRITE(RADEON_MC_AGP_LOCATION, 0xffffffc0); /* ?? */
+ RADEON_WRITE(RADEON_AGP_COMMAND, 0); /* clear AGP_COMMAND */
} else {
- RADEON_WRITE( RADEON_AIC_CNTL, tmp & ~RADEON_PCIGART_TRANSLATE_EN );
+ RADEON_WRITE(RADEON_AIC_CNTL,
+ tmp & ~RADEON_PCIGART_TRANSLATE_EN);
}
}
-static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init )
+static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init)
{
drm_radeon_private_t *dev_priv = dev->dev_private;;
- DRM_DEBUG( "\n" );
+ DRM_DEBUG("\n");
dev_priv->is_pci = init->is_pci;
- if ( dev_priv->is_pci && !dev->sg ) {
- DRM_ERROR( "PCI GART memory not allocated!\n" );
+ if (dev_priv->is_pci && !dev->sg) {
+ DRM_ERROR("PCI GART memory not allocated!\n");
dev->dev_private = (void *)dev_priv;
radeon_do_cleanup_cp(dev);
return DRM_ERR(EINVAL);
}
dev_priv->usec_timeout = init->usec_timeout;
- if ( dev_priv->usec_timeout < 1 ||
- dev_priv->usec_timeout > RADEON_MAX_USEC_TIMEOUT ) {
- DRM_DEBUG( "TIMEOUT problem!\n" );
+ if (dev_priv->usec_timeout < 1 ||
+ dev_priv->usec_timeout > RADEON_MAX_USEC_TIMEOUT) {
+ DRM_DEBUG("TIMEOUT problem!\n");
dev->dev_private = (void *)dev_priv;
radeon_do_cleanup_cp(dev);
return DRM_ERR(EINVAL);
}
- switch(init->func) {
+ switch (init->func) {
case RADEON_INIT_R200_CP:
- dev_priv->microcode_version=UCODE_R200;
+ dev_priv->microcode_version = UCODE_R200;
break;
case RADEON_INIT_R300_CP:
- dev_priv->microcode_version=UCODE_R300;
+ dev_priv->microcode_version = UCODE_R300;
break;
default:
- dev_priv->microcode_version=UCODE_R100;
+ dev_priv->microcode_version = UCODE_R100;
}
-
+
dev_priv->do_boxes = 0;
dev_priv->cp_mode = init->cp_mode;
@@ -1310,15 +1350,15 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init )
* but the ring can be in either AGP or PCI space for the ring
* read pointer.
*/
- if ( ( init->cp_mode != RADEON_CSQ_PRIBM_INDDIS ) &&
- ( init->cp_mode != RADEON_CSQ_PRIBM_INDBM ) ) {
- DRM_DEBUG( "BAD cp_mode (%x)!\n", init->cp_mode );
+ if ((init->cp_mode != RADEON_CSQ_PRIBM_INDDIS) &&
+ (init->cp_mode != RADEON_CSQ_PRIBM_INDBM)) {
+ DRM_DEBUG("BAD cp_mode (%x)!\n", init->cp_mode);
dev->dev_private = (void *)dev_priv;
radeon_do_cleanup_cp(dev);
return DRM_ERR(EINVAL);
}
- switch ( init->fb_bpp ) {
+ switch (init->fb_bpp) {
case 16:
dev_priv->color_fmt = RADEON_COLOR_FORMAT_RGB565;
break;
@@ -1327,12 +1367,12 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init )
dev_priv->color_fmt = RADEON_COLOR_FORMAT_ARGB8888;
break;
}
- dev_priv->front_offset = init->front_offset;
- dev_priv->front_pitch = init->front_pitch;
- dev_priv->back_offset = init->back_offset;
- dev_priv->back_pitch = init->back_pitch;
+ dev_priv->front_offset = init->front_offset;
+ dev_priv->front_pitch = init->front_pitch;
+ dev_priv->back_offset = init->back_offset;
+ dev_priv->back_pitch = init->back_pitch;
- switch ( init->depth_bpp ) {
+ switch (init->depth_bpp) {
case 16:
dev_priv->depth_fmt = RADEON_DEPTH_FORMAT_16BIT_INT_Z;
break;
@@ -1341,8 +1381,8 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init )
dev_priv->depth_fmt = RADEON_DEPTH_FORMAT_24BIT_INT_Z;
break;
}
- dev_priv->depth_offset = init->depth_offset;
- dev_priv->depth_pitch = init->depth_pitch;
+ dev_priv->depth_offset = init->depth_offset;
+ dev_priv->depth_pitch = init->depth_pitch;
/* Hardware state for depth clears. Remove this if/when we no
* longer clear the depth buffer with a 3D rectangle. Hard-code
@@ -1351,16 +1391,16 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init )
*/
dev_priv->depth_clear.rb3d_cntl = (RADEON_PLANE_MASK_ENABLE |
(dev_priv->color_fmt << 10) |
- (dev_priv->microcode_version == UCODE_R100 ? RADEON_ZBLOCK16 : 0));
+ (dev_priv->microcode_version ==
+ UCODE_R100 ? RADEON_ZBLOCK16 : 0));
- dev_priv->depth_clear.rb3d_zstencilcntl =
- (dev_priv->depth_fmt |
- RADEON_Z_TEST_ALWAYS |
- RADEON_STENCIL_TEST_ALWAYS |
- RADEON_STENCIL_S_FAIL_REPLACE |
- RADEON_STENCIL_ZPASS_REPLACE |
- RADEON_STENCIL_ZFAIL_REPLACE |
- RADEON_Z_WRITE_ENABLE);
+ dev_priv->depth_clear.rb3d_zstencilcntl =
+ (dev_priv->depth_fmt |
+ RADEON_Z_TEST_ALWAYS |
+ RADEON_STENCIL_TEST_ALWAYS |
+ RADEON_STENCIL_S_FAIL_REPLACE |
+ RADEON_STENCIL_ZPASS_REPLACE |
+ RADEON_STENCIL_ZFAIL_REPLACE | RADEON_Z_WRITE_ENABLE);
dev_priv->depth_clear.se_cntl = (RADEON_FFACE_CULL_CW |
RADEON_BFACE_SOLID |
@@ -1382,8 +1422,8 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init )
dev_priv->ring_rptr_offset = init->ring_rptr_offset;
dev_priv->buffers_offset = init->buffers_offset;
dev_priv->gart_textures_offset = init->gart_textures_offset;
-
- if(!dev_priv->sarea) {
+
+ if (!dev_priv->sarea) {
DRM_ERROR("could not find sarea!\n");
dev->dev_private = (void *)dev_priv;
radeon_do_cleanup_cp(dev);
@@ -1391,21 +1431,21 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init )
}
dev_priv->mmio = drm_core_findmap(dev, init->mmio_offset);
- if(!dev_priv->mmio) {
+ if (!dev_priv->mmio) {
DRM_ERROR("could not find mmio region!\n");
dev->dev_private = (void *)dev_priv;
radeon_do_cleanup_cp(dev);
return DRM_ERR(EINVAL);
}
dev_priv->cp_ring = drm_core_findmap(dev, init->ring_offset);
- if(!dev_priv->cp_ring) {
+ if (!dev_priv->cp_ring) {
DRM_ERROR("could not find cp ring region!\n");
dev->dev_private = (void *)dev_priv;
radeon_do_cleanup_cp(dev);
return DRM_ERR(EINVAL);
}
dev_priv->ring_rptr = drm_core_findmap(dev, init->ring_rptr_offset);
- if(!dev_priv->ring_rptr) {
+ if (!dev_priv->ring_rptr) {
DRM_ERROR("could not find ring read pointer!\n");
dev->dev_private = (void *)dev_priv;
radeon_do_cleanup_cp(dev);
@@ -1413,16 +1453,17 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init )
}
dev->agp_buffer_token = init->buffers_offset;
dev->agp_buffer_map = drm_core_findmap(dev, init->buffers_offset);
- if(!dev->agp_buffer_map) {
+ if (!dev->agp_buffer_map) {
DRM_ERROR("could not find dma buffer region!\n");
dev->dev_private = (void *)dev_priv;
radeon_do_cleanup_cp(dev);
return DRM_ERR(EINVAL);
}
- if ( init->gart_textures_offset ) {
- dev_priv->gart_textures = drm_core_findmap(dev, init->gart_textures_offset);
- if ( !dev_priv->gart_textures ) {
+ if (init->gart_textures_offset) {
+ dev_priv->gart_textures =
+ drm_core_findmap(dev, init->gart_textures_offset);
+ if (!dev_priv->gart_textures) {
DRM_ERROR("could not find GART texture region!\n");
dev->dev_private = (void *)dev_priv;
radeon_do_cleanup_cp(dev);
@@ -1431,17 +1472,17 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init )
}
dev_priv->sarea_priv =
- (drm_radeon_sarea_t *)((u8 *)dev_priv->sarea->handle +
- init->sarea_priv_offset);
+ (drm_radeon_sarea_t *) ((u8 *) dev_priv->sarea->handle +
+ init->sarea_priv_offset);
#if __OS_HAS_AGP
- if ( !dev_priv->is_pci ) {
- drm_core_ioremap( dev_priv->cp_ring, dev );
- drm_core_ioremap( dev_priv->ring_rptr, dev );
- drm_core_ioremap( dev->agp_buffer_map, dev );
- if(!dev_priv->cp_ring->handle ||
- !dev_priv->ring_rptr->handle ||
- !dev->agp_buffer_map->handle) {
+ if (!dev_priv->is_pci) {
+ drm_core_ioremap(dev_priv->cp_ring, dev);
+ drm_core_ioremap(dev_priv->ring_rptr, dev);
+ drm_core_ioremap(dev->agp_buffer_map, dev);
+ if (!dev_priv->cp_ring->handle ||
+ !dev_priv->ring_rptr->handle ||
+ !dev->agp_buffer_map->handle) {
DRM_ERROR("could not find ioremap agp regions!\n");
dev->dev_private = (void *)dev_priv;
radeon_do_cleanup_cp(dev);
@@ -1450,220 +1491,251 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init )
} else
#endif
{
- dev_priv->cp_ring->handle =
- (void *)dev_priv->cp_ring->offset;
+ dev_priv->cp_ring->handle = (void *)dev_priv->cp_ring->offset;
dev_priv->ring_rptr->handle =
- (void *)dev_priv->ring_rptr->offset;
- dev->agp_buffer_map->handle = (void *)dev->agp_buffer_map->offset;
-
- DRM_DEBUG( "dev_priv->cp_ring->handle %p\n",
- dev_priv->cp_ring->handle );
- DRM_DEBUG( "dev_priv->ring_rptr->handle %p\n",
- dev_priv->ring_rptr->handle );
- DRM_DEBUG( "dev->agp_buffer_map->handle %p\n",
- dev->agp_buffer_map->handle );
+ (void *)dev_priv->ring_rptr->offset;
+ dev->agp_buffer_map->handle =
+ (void *)dev->agp_buffer_map->offset;
+
+ DRM_DEBUG("dev_priv->cp_ring->handle %p\n",
+ dev_priv->cp_ring->handle);
+ DRM_DEBUG("dev_priv->ring_rptr->handle %p\n",
+ dev_priv->ring_rptr->handle);
+ DRM_DEBUG("dev->agp_buffer_map->handle %p\n",
+ dev->agp_buffer_map->handle);
}
- dev_priv->fb_location = ( RADEON_READ( RADEON_MC_FB_LOCATION )
- & 0xffff ) << 16;
+ dev_priv->fb_location = (RADEON_READ(RADEON_MC_FB_LOCATION)
+ & 0xffff) << 16;
- dev_priv->front_pitch_offset = (((dev_priv->front_pitch/64) << 22) |
- ( ( dev_priv->front_offset
- + dev_priv->fb_location ) >> 10 ) );
+ dev_priv->front_pitch_offset = (((dev_priv->front_pitch / 64) << 22) |
+ ((dev_priv->front_offset
+ + dev_priv->fb_location) >> 10));
- dev_priv->back_pitch_offset = (((dev_priv->back_pitch/64) << 22) |
- ( ( dev_priv->back_offset
- + dev_priv->fb_location ) >> 10 ) );
-
- dev_priv->depth_pitch_offset = (((dev_priv->depth_pitch/64) << 22) |
- ( ( dev_priv->depth_offset
- + dev_priv->fb_location ) >> 10 ) );
+ dev_priv->back_pitch_offset = (((dev_priv->back_pitch / 64) << 22) |
+ ((dev_priv->back_offset
+ + dev_priv->fb_location) >> 10));
+ dev_priv->depth_pitch_offset = (((dev_priv->depth_pitch / 64) << 22) |
+ ((dev_priv->depth_offset
+ + dev_priv->fb_location) >> 10));
dev_priv->gart_size = init->gart_size;
dev_priv->gart_vm_start = dev_priv->fb_location
- + RADEON_READ( RADEON_CONFIG_APER_SIZE );
+ + RADEON_READ(RADEON_CONFIG_APER_SIZE);
#if __OS_HAS_AGP
- if ( !dev_priv->is_pci )
+ if (!dev_priv->is_pci)
dev_priv->gart_buffers_offset = (dev->agp_buffer_map->offset
- - dev->agp->base
- + dev_priv->gart_vm_start);
+ - dev->agp->base
+ + dev_priv->gart_vm_start);
else
#endif
dev_priv->gart_buffers_offset = (dev->agp_buffer_map->offset
- (unsigned long)dev->sg->virtual
+ dev_priv->gart_vm_start);
- DRM_DEBUG( "dev_priv->gart_size %d\n",
- dev_priv->gart_size );
- DRM_DEBUG( "dev_priv->gart_vm_start 0x%x\n",
- dev_priv->gart_vm_start );
- DRM_DEBUG( "dev_priv->gart_buffers_offset 0x%lx\n",
- dev_priv->gart_buffers_offset );
+ DRM_DEBUG("dev_priv->gart_size %d\n", dev_priv->gart_size);
+ DRM_DEBUG("dev_priv->gart_vm_start 0x%x\n", dev_priv->gart_vm_start);
+ DRM_DEBUG("dev_priv->gart_buffers_offset 0x%lx\n",
+ dev_priv->gart_buffers_offset);
- dev_priv->ring.start = (u32 *)dev_priv->cp_ring->handle;
- dev_priv->ring.end = ((u32 *)dev_priv->cp_ring->handle
+ dev_priv->ring.start = (u32 *) dev_priv->cp_ring->handle;
+ dev_priv->ring.end = ((u32 *) dev_priv->cp_ring->handle
+ init->ring_size / sizeof(u32));
dev_priv->ring.size = init->ring_size;
- dev_priv->ring.size_l2qw = drm_order( init->ring_size / 8 );
+ dev_priv->ring.size_l2qw = drm_order(init->ring_size / 8);
- dev_priv->ring.tail_mask =
- (dev_priv->ring.size / sizeof(u32)) - 1;
+ dev_priv->ring.tail_mask = (dev_priv->ring.size / sizeof(u32)) - 1;
dev_priv->ring.high_mark = RADEON_RING_HIGH_MARK;
#if __OS_HAS_AGP
- if ( !dev_priv->is_pci ) {
+ if (!dev_priv->is_pci) {
/* Turn off PCI GART */
- radeon_set_pcigart( dev_priv, 0 );
+ radeon_set_pcigart(dev_priv, 0);
} else
#endif
{
- if (!drm_ati_pcigart_init( dev, &dev_priv->phys_pci_gart,
- &dev_priv->bus_pci_gart)) {
- DRM_ERROR( "failed to init PCI GART!\n" );
+ /* if we have an offset set from userspace */
+ if (dev_priv->pcigart_offset) {
+ dev_priv->gart_info.bus_addr =
+ dev_priv->pcigart_offset + dev_priv->fb_location;
+ dev_priv->gart_info.addr =
+ (unsigned long)drm_ioremap(dev_priv->gart_info.
+ bus_addr,
+ RADEON_PCIGART_TABLE_SIZE,
+ dev);
+
+ dev_priv->gart_info.is_pcie =
+ !!(dev_priv->flags & CHIP_IS_PCIE);
+ dev_priv->gart_info.gart_table_location =
+ DRM_ATI_GART_FB;
+
+ DRM_DEBUG("Setting phys_pci_gart to %08lX %08lX\n",
+ dev_priv->gart_info.addr,
+ dev_priv->pcigart_offset);
+ } else {
+ dev_priv->gart_info.gart_table_location =
+ DRM_ATI_GART_MAIN;
+ dev_priv->gart_info.addr =
+ dev_priv->gart_info.bus_addr = 0;
+ if (dev_priv->flags & CHIP_IS_PCIE) {
+ DRM_ERROR
+ ("Cannot use PCI Express without GART in FB memory\n");
+ radeon_do_cleanup_cp(dev);
+ return DRM_ERR(EINVAL);
+ }
+ }
+
+ if (!drm_ati_pcigart_init(dev, &dev_priv->gart_info)) {
+ DRM_ERROR("failed to init PCI GART!\n");
dev->dev_private = (void *)dev_priv;
radeon_do_cleanup_cp(dev);
return DRM_ERR(ENOMEM);
}
/* Turn on PCI GART */
- radeon_set_pcigart( dev_priv, 1 );
+ radeon_set_pcigart(dev_priv, 1);
}
- radeon_cp_load_microcode( dev_priv );
- radeon_cp_init_ring_buffer( dev, dev_priv );
+ radeon_cp_load_microcode(dev_priv);
+ radeon_cp_init_ring_buffer(dev, dev_priv);
dev_priv->last_buf = 0;
dev->dev_private = (void *)dev_priv;
- radeon_do_engine_reset( dev );
+ radeon_do_engine_reset(dev);
return 0;
}
-static int radeon_do_cleanup_cp( drm_device_t *dev )
+static int radeon_do_cleanup_cp(drm_device_t * dev)
{
drm_radeon_private_t *dev_priv = dev->dev_private;
- DRM_DEBUG( "\n" );
+ DRM_DEBUG("\n");
/* Make sure interrupts are disabled here because the uninstall ioctl
* may not have been called from userspace and after dev_private
* is freed, it's too late.
*/
- if ( dev->irq_enabled ) drm_irq_uninstall(dev);
+ if (dev->irq_enabled)
+ drm_irq_uninstall(dev);
#if __OS_HAS_AGP
- if ( !dev_priv->is_pci ) {
- if ( dev_priv->cp_ring != NULL )
- drm_core_ioremapfree( dev_priv->cp_ring, dev );
- if ( dev_priv->ring_rptr != NULL )
- drm_core_ioremapfree( dev_priv->ring_rptr, dev );
- if ( dev->agp_buffer_map != NULL )
- {
- drm_core_ioremapfree( dev->agp_buffer_map, dev );
+ if (!dev_priv->is_pci) {
+ if (dev_priv->cp_ring != NULL)
+ drm_core_ioremapfree(dev_priv->cp_ring, dev);
+ if (dev_priv->ring_rptr != NULL)
+ drm_core_ioremapfree(dev_priv->ring_rptr, dev);
+ if (dev->agp_buffer_map != NULL) {
+ drm_core_ioremapfree(dev->agp_buffer_map, dev);
dev->agp_buffer_map = NULL;
}
} else
#endif
{
- if (!drm_ati_pcigart_cleanup( dev,
- dev_priv->phys_pci_gart,
- dev_priv->bus_pci_gart ))
- DRM_ERROR( "failed to cleanup PCI GART!\n" );
+ if (dev_priv->gart_info.bus_addr)
+ if (!drm_ati_pcigart_cleanup(dev, &dev_priv->gart_info))
+ DRM_ERROR("failed to cleanup PCI GART!\n");
+
+ if (dev_priv->gart_info.gart_table_location == DRM_ATI_GART_FB) {
+ drm_ioremapfree((void *)dev_priv->gart_info.addr,
+ RADEON_PCIGART_TABLE_SIZE, dev);
+ dev_priv->gart_info.addr = 0;
+ }
}
-
+
/* only clear to the start of flags */
memset(dev_priv, 0, offsetof(drm_radeon_private_t, flags));
return 0;
}
-/* This code will reinit the Radeon CP hardware after a resume from disc.
- * AFAIK, it would be very difficult to pickle the state at suspend time, so
+/* This code will reinit the Radeon CP hardware after a resume from disc.
+ * AFAIK, it would be very difficult to pickle the state at suspend time, so
* here we make sure that all Radeon hardware initialisation is re-done without
* affecting running applications.
*
* Charl P. Botha <http://cpbotha.net>
*/
-static int radeon_do_resume_cp( drm_device_t *dev )
+static int radeon_do_resume_cp(drm_device_t * dev)
{
drm_radeon_private_t *dev_priv = dev->dev_private;
- if ( !dev_priv ) {
- DRM_ERROR( "Called with no initialization\n" );
- return DRM_ERR( EINVAL );
+ if (!dev_priv) {
+ DRM_ERROR("Called with no initialization\n");
+ return DRM_ERR(EINVAL);
}
DRM_DEBUG("Starting radeon_do_resume_cp()\n");
#if __OS_HAS_AGP
- if ( !dev_priv->is_pci ) {
+ if (!dev_priv->is_pci) {
/* Turn off PCI GART */
- radeon_set_pcigart( dev_priv, 0 );
+ radeon_set_pcigart(dev_priv, 0);
} else
#endif
{
/* Turn on PCI GART */
- radeon_set_pcigart( dev_priv, 1 );
+ radeon_set_pcigart(dev_priv, 1);
}
- radeon_cp_load_microcode( dev_priv );
- radeon_cp_init_ring_buffer( dev, dev_priv );
+ radeon_cp_load_microcode(dev_priv);
+ radeon_cp_init_ring_buffer(dev, dev_priv);
- radeon_do_engine_reset( dev );
+ radeon_do_engine_reset(dev);
DRM_DEBUG("radeon_do_resume_cp() complete\n");
return 0;
}
-
-int radeon_cp_init( DRM_IOCTL_ARGS )
+int radeon_cp_init(DRM_IOCTL_ARGS)
{
DRM_DEVICE;
drm_radeon_init_t init;
- LOCK_TEST_WITH_RETURN( dev, filp );
+ LOCK_TEST_WITH_RETURN(dev, filp);
- DRM_COPY_FROM_USER_IOCTL( init, (drm_radeon_init_t __user *)data, sizeof(init) );
+ DRM_COPY_FROM_USER_IOCTL(init, (drm_radeon_init_t __user *) data,
+ sizeof(init));
- if(init.func == RADEON_INIT_R300_CP)
+ if (init.func == RADEON_INIT_R300_CP)
r300_init_reg_flags();
- switch ( init.func ) {
+ switch (init.func) {
case RADEON_INIT_CP:
case RADEON_INIT_R200_CP:
case RADEON_INIT_R300_CP:
- return radeon_do_init_cp( dev, &init );
+ return radeon_do_init_cp(dev, &init);
case RADEON_CLEANUP_CP:
- return radeon_do_cleanup_cp( dev );
+ return radeon_do_cleanup_cp(dev);
}
return DRM_ERR(EINVAL);
}
-int radeon_cp_start( DRM_IOCTL_ARGS )
+int radeon_cp_start(DRM_IOCTL_ARGS)
{
DRM_DEVICE;
drm_radeon_private_t *dev_priv = dev->dev_private;
- DRM_DEBUG( "\n" );
+ DRM_DEBUG("\n");
- LOCK_TEST_WITH_RETURN( dev, filp );
+ LOCK_TEST_WITH_RETURN(dev, filp);
- if ( dev_priv->cp_running ) {
- DRM_DEBUG( "%s while CP running\n", __FUNCTION__ );
+ if (dev_priv->cp_running) {
+ DRM_DEBUG("%s while CP running\n", __FUNCTION__);
return 0;
}
- if ( dev_priv->cp_mode == RADEON_CSQ_PRIDIS_INDDIS ) {
- DRM_DEBUG( "%s called with bogus CP mode (%d)\n",
- __FUNCTION__, dev_priv->cp_mode );
+ if (dev_priv->cp_mode == RADEON_CSQ_PRIDIS_INDDIS) {
+ DRM_DEBUG("%s called with bogus CP mode (%d)\n",
+ __FUNCTION__, dev_priv->cp_mode);
return 0;
}
- radeon_do_cp_start( dev_priv );
+ radeon_do_cp_start(dev_priv);
return 0;
}
@@ -1671,17 +1743,18 @@ int radeon_cp_start( DRM_IOCTL_ARGS )
/* Stop the CP. The engine must have been idled before calling this
* routine.
*/
-int radeon_cp_stop( DRM_IOCTL_ARGS )
+int radeon_cp_stop(DRM_IOCTL_ARGS)
{
DRM_DEVICE;
drm_radeon_private_t *dev_priv = dev->dev_private;
drm_radeon_cp_stop_t stop;
int ret;
- DRM_DEBUG( "\n" );
+ DRM_DEBUG("\n");
- LOCK_TEST_WITH_RETURN( dev, filp );
+ LOCK_TEST_WITH_RETURN(dev, filp);
- DRM_COPY_FROM_USER_IOCTL( stop, (drm_radeon_cp_stop_t __user *)data, sizeof(stop) );
+ DRM_COPY_FROM_USER_IOCTL(stop, (drm_radeon_cp_stop_t __user *) data,
+ sizeof(stop));
if (!dev_priv->cp_running)
return 0;
@@ -1689,32 +1762,32 @@ int radeon_cp_stop( DRM_IOCTL_ARGS )
/* Flush any pending CP commands. This ensures any outstanding
* commands are exectuted by the engine before we turn it off.
*/
- if ( stop.flush ) {
- radeon_do_cp_flush( dev_priv );
+ if (stop.flush) {
+ radeon_do_cp_flush(dev_priv);
}
/* If we fail to make the engine go idle, we return an error
* code so that the DRM ioctl wrapper can try again.
*/
- if ( stop.idle ) {
- ret = radeon_do_cp_idle( dev_priv );
- if ( ret ) return ret;
+ if (stop.idle) {
+ ret = radeon_do_cp_idle(dev_priv);
+ if (ret)
+ return ret;
}
/* Finally, we can turn off the CP. If the engine isn't idle,
* we will get some dropped triangles as they won't be fully
* rendered before the CP is shut down.
*/
- radeon_do_cp_stop( dev_priv );
+ radeon_do_cp_stop(dev_priv);
/* Reset the engine */
- radeon_do_engine_reset( dev );
+ radeon_do_engine_reset(dev);
return 0;
}
-
-void radeon_do_release( drm_device_t *dev )
+void radeon_do_release(drm_device_t * dev)
{
drm_radeon_private_t *dev_priv = dev->dev_private;
int i, ret;
@@ -1722,7 +1795,7 @@ void radeon_do_release( drm_device_t *dev )
if (dev_priv) {
if (dev_priv->cp_running) {
/* Stop the cp */
- while ((ret = radeon_do_cp_idle( dev_priv )) != 0) {
+ while ((ret = radeon_do_cp_idle(dev_priv)) != 0) {
DRM_DEBUG("radeon_do_cp_idle %d\n", ret);
#ifdef __linux__
schedule();
@@ -1730,47 +1803,49 @@ void radeon_do_release( drm_device_t *dev )
tsleep(&ret, PZERO, "rdnrel", 1);
#endif
}
- radeon_do_cp_stop( dev_priv );
- radeon_do_engine_reset( dev );
+ radeon_do_cp_stop(dev_priv);
+ radeon_do_engine_reset(dev);
}
/* Disable *all* interrupts */
if (dev_priv->mmio) /* remove this after permanent addmaps */
- RADEON_WRITE( RADEON_GEN_INT_CNTL, 0 );
+ RADEON_WRITE(RADEON_GEN_INT_CNTL, 0);
- if (dev_priv->mmio) {/* remove all surfaces */
+ if (dev_priv->mmio) { /* remove all surfaces */
for (i = 0; i < RADEON_MAX_SURFACES; i++) {
- RADEON_WRITE(RADEON_SURFACE0_INFO + 16*i, 0);
- RADEON_WRITE(RADEON_SURFACE0_LOWER_BOUND + 16*i, 0);
- RADEON_WRITE(RADEON_SURFACE0_UPPER_BOUND + 16*i, 0);
+ RADEON_WRITE(RADEON_SURFACE0_INFO + 16 * i, 0);
+ RADEON_WRITE(RADEON_SURFACE0_LOWER_BOUND +
+ 16 * i, 0);
+ RADEON_WRITE(RADEON_SURFACE0_UPPER_BOUND +
+ 16 * i, 0);
}
}
/* Free memory heap structures */
- radeon_mem_takedown( &(dev_priv->gart_heap) );
- radeon_mem_takedown( &(dev_priv->fb_heap) );
+ radeon_mem_takedown(&(dev_priv->gart_heap));
+ radeon_mem_takedown(&(dev_priv->fb_heap));
/* deallocate kernel resources */
- radeon_do_cleanup_cp( dev );
+ radeon_do_cleanup_cp(dev);
}
}
/* Just reset the CP ring. Called as part of an X Server engine reset.
*/
-int radeon_cp_reset( DRM_IOCTL_ARGS )
+int radeon_cp_reset(DRM_IOCTL_ARGS)
{
DRM_DEVICE;
drm_radeon_private_t *dev_priv = dev->dev_private;
- DRM_DEBUG( "\n" );
+ DRM_DEBUG("\n");
- LOCK_TEST_WITH_RETURN( dev, filp );
+ LOCK_TEST_WITH_RETURN(dev, filp);
- if ( !dev_priv ) {
- DRM_DEBUG( "%s called before init done\n", __FUNCTION__ );
+ if (!dev_priv) {
+ DRM_DEBUG("%s called before init done\n", __FUNCTION__);
return DRM_ERR(EINVAL);
}
- radeon_do_cp_reset( dev_priv );
+ radeon_do_cp_reset(dev_priv);
/* The CP is no longer running after an engine reset */
dev_priv->cp_running = 0;
@@ -1778,50 +1853,47 @@ int radeon_cp_reset( DRM_IOCTL_ARGS )
return 0;
}
-int radeon_cp_idle( DRM_IOCTL_ARGS )
+int radeon_cp_idle(DRM_IOCTL_ARGS)
{
DRM_DEVICE;
drm_radeon_private_t *dev_priv = dev->dev_private;
- DRM_DEBUG( "\n" );
+ DRM_DEBUG("\n");
- LOCK_TEST_WITH_RETURN( dev, filp );
+ LOCK_TEST_WITH_RETURN(dev, filp);
- return radeon_do_cp_idle( dev_priv );
+ return radeon_do_cp_idle(dev_priv);
}
/* Added by Charl P. Botha to call radeon_do_resume_cp().
*/
-int radeon_cp_resume( DRM_IOCTL_ARGS )
+int radeon_cp_resume(DRM_IOCTL_ARGS)
{
DRM_DEVICE;
return radeon_do_resume_cp(dev);
}
-
-int radeon_engine_reset( DRM_IOCTL_ARGS )
+int radeon_engine_reset(DRM_IOCTL_ARGS)
{
DRM_DEVICE;
- DRM_DEBUG( "\n" );
+ DRM_DEBUG("\n");
- LOCK_TEST_WITH_RETURN( dev, filp );
+ LOCK_TEST_WITH_RETURN(dev, filp);
- return radeon_do_engine_reset( dev );
+ return radeon_do_engine_reset(dev);
}
-
/* ================================================================
* Fullscreen mode
*/
/* KW: Deprecated to say the least:
*/
-int radeon_fullscreen( DRM_IOCTL_ARGS )
+int radeon_fullscreen(DRM_IOCTL_ARGS)
{
return 0;
}
-
/* ================================================================
* Freelist management
*/
@@ -1830,20 +1902,20 @@ int radeon_fullscreen( DRM_IOCTL_ARGS )
* bufs until freelist code is used. Note this hides a problem with
* the scratch register * (used to keep track of last buffer
* completed) being written to before * the last buffer has actually
- * completed rendering.
+ * completed rendering.
*
* KW: It's also a good way to find free buffers quickly.
*
* KW: Ideally this loop wouldn't exist, and freelist_get wouldn't
* sleep. However, bugs in older versions of radeon_accel.c mean that
* we essentially have to do this, else old clients will break.
- *
+ *
* However, it does leave open a potential deadlock where all the
* buffers are held by other clients, which can't release them because
- * they can't get the lock.
+ * they can't get the lock.
*/
-drm_buf_t *radeon_freelist_get( drm_device_t *dev )
+drm_buf_t *radeon_freelist_get(drm_device_t * dev)
{
drm_device_dma_t *dma = dev->dma;
drm_radeon_private_t *dev_priv = dev->dev_private;
@@ -1852,19 +1924,19 @@ drm_buf_t *radeon_freelist_get( drm_device_t *dev )
int i, t;
int start;
- if ( ++dev_priv->last_buf >= dma->buf_count )
+ if (++dev_priv->last_buf >= dma->buf_count)
dev_priv->last_buf = 0;
start = dev_priv->last_buf;
- for ( t = 0 ; t < dev_priv->usec_timeout ; t++ ) {
- u32 done_age = GET_SCRATCH( 1 );
- DRM_DEBUG("done_age = %d\n",done_age);
- for ( i = start ; i < dma->buf_count ; i++ ) {
+ for (t = 0; t < dev_priv->usec_timeout; t++) {
+ u32 done_age = GET_SCRATCH(1);
+ DRM_DEBUG("done_age = %d\n", done_age);
+ for (i = start; i < dma->buf_count; i++) {
buf = dma->buflist[i];
buf_priv = buf->dev_private;
- if ( buf->filp == 0 || (buf->pending &&
- buf_priv->age <= done_age) ) {
+ if (buf->filp == 0 || (buf->pending &&
+ buf_priv->age <= done_age)) {
dev_priv->stats.requested_bufs++;
buf->pending = 0;
return buf;
@@ -1873,16 +1945,17 @@ drm_buf_t *radeon_freelist_get( drm_device_t *dev )
}
if (t) {
- DRM_UDELAY( 1 );
+ DRM_UDELAY(1);
dev_priv->stats.freelist_loops++;
}
}
- DRM_DEBUG( "returning NULL!\n" );
+ DRM_DEBUG("returning NULL!\n");
return NULL;
}
+
#if 0
-drm_buf_t *radeon_freelist_get( drm_device_t *dev )
+drm_buf_t *radeon_freelist_get(drm_device_t * dev)
{
drm_device_dma_t *dma = dev->dma;
drm_radeon_private_t *dev_priv = dev->dev_private;
@@ -1892,18 +1965,18 @@ drm_buf_t *radeon_freelist_get( drm_device_t *dev )
int start;
u32 done_age = DRM_READ32(dev_priv->ring_rptr, RADEON_SCRATCHOFF(1));
- if ( ++dev_priv->last_buf >= dma->buf_count )
+ if (++dev_priv->last_buf >= dma->buf_count)
dev_priv->last_buf = 0;
start = dev_priv->last_buf;
dev_priv->stats.freelist_loops++;
-
- for ( t = 0 ; t < 2 ; t++ ) {
- for ( i = start ; i < dma->buf_count ; i++ ) {
+
+ for (t = 0; t < 2; t++) {
+ for (i = start; i < dma->buf_count; i++) {
buf = dma->buflist[i];
buf_priv = buf->dev_private;
- if ( buf->filp == 0 || (buf->pending &&
- buf_priv->age <= done_age) ) {
+ if (buf->filp == 0 || (buf->pending &&
+ buf_priv->age <= done_age)) {
dev_priv->stats.requested_bufs++;
buf->pending = 0;
return buf;
@@ -1916,73 +1989,74 @@ drm_buf_t *radeon_freelist_get( drm_device_t *dev )
}
#endif
-void radeon_freelist_reset( drm_device_t *dev )
+void radeon_freelist_reset(drm_device_t * dev)
{
drm_device_dma_t *dma = dev->dma;
drm_radeon_private_t *dev_priv = dev->dev_private;
int i;
dev_priv->last_buf = 0;
- for ( i = 0 ; i < dma->buf_count ; i++ ) {
+ for (i = 0; i < dma->buf_count; i++) {
drm_buf_t *buf = dma->buflist[i];
drm_radeon_buf_priv_t *buf_priv = buf->dev_private;
buf_priv->age = 0;
}
}
-
/* ================================================================
* CP command submission
*/
-int radeon_wait_ring( drm_radeon_private_t *dev_priv, int n )
+int radeon_wait_ring(drm_radeon_private_t * dev_priv, int n)
{
drm_radeon_ring_buffer_t *ring = &dev_priv->ring;
int i;
- u32 last_head = GET_RING_HEAD( dev_priv );
+ u32 last_head = GET_RING_HEAD(dev_priv);
- for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) {
- u32 head = GET_RING_HEAD( dev_priv );
+ for (i = 0; i < dev_priv->usec_timeout; i++) {
+ u32 head = GET_RING_HEAD(dev_priv);
ring->space = (head - ring->tail) * sizeof(u32);
- if ( ring->space <= 0 )
+ if (ring->space <= 0)
ring->space += ring->size;
- if ( ring->space > n )
+ if (ring->space > n)
return 0;
-
+
dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE;
if (head != last_head)
i = 0;
last_head = head;
- DRM_UDELAY( 1 );
+ DRM_UDELAY(1);
}
/* FIXME: This return value is ignored in the BEGIN_RING macro! */
#if RADEON_FIFO_DEBUG
- radeon_status( dev_priv );
- DRM_ERROR( "failed!\n" );
+ radeon_status(dev_priv);
+ DRM_ERROR("failed!\n");
#endif
return DRM_ERR(EBUSY);
}
-static int radeon_cp_get_buffers( DRMFILE filp, drm_device_t *dev, drm_dma_t *d )
+static int radeon_cp_get_buffers(DRMFILE filp, drm_device_t * dev,
+ drm_dma_t * d)
{
int i;
drm_buf_t *buf;
- for ( i = d->granted_count ; i < d->request_count ; i++ ) {
- buf = radeon_freelist_get( dev );
- if ( !buf ) return DRM_ERR(EBUSY); /* NOTE: broken client */
+ for (i = d->granted_count; i < d->request_count; i++) {
+ buf = radeon_freelist_get(dev);
+ if (!buf)
+ return DRM_ERR(EBUSY); /* NOTE: broken client */
buf->filp = filp;
- if ( DRM_COPY_TO_USER( &d->request_indices[i], &buf->idx,
- sizeof(buf->idx) ) )
+ if (DRM_COPY_TO_USER(&d->request_indices[i], &buf->idx,
+ sizeof(buf->idx)))
return DRM_ERR(EFAULT);
- if ( DRM_COPY_TO_USER( &d->request_sizes[i], &buf->total,
- sizeof(buf->total) ) )
+ if (DRM_COPY_TO_USER(&d->request_sizes[i], &buf->total,
+ sizeof(buf->total)))
return DRM_ERR(EFAULT);
d->granted_count++;
@@ -1990,7 +2064,7 @@ static int radeon_cp_get_buffers( DRMFILE filp, drm_device_t *dev, drm_dma_t *d
return 0;
}
-int radeon_cp_buffers( DRM_IOCTL_ARGS )
+int radeon_cp_buffers(DRM_IOCTL_ARGS)
{
DRM_DEVICE;
drm_device_dma_t *dma = dev->dma;
@@ -1998,33 +2072,33 @@ int radeon_cp_buffers( DRM_IOCTL_ARGS )
drm_dma_t __user *argp = (void __user *)data;
drm_dma_t d;
- LOCK_TEST_WITH_RETURN( dev, filp );
+ LOCK_TEST_WITH_RETURN(dev, filp);
- DRM_COPY_FROM_USER_IOCTL( d, argp, sizeof(d) );
+ DRM_COPY_FROM_USER_IOCTL(d, argp, sizeof(d));
/* Please don't send us buffers.
*/
- if ( d.send_count != 0 ) {
- DRM_ERROR( "Process %d trying to send %d buffers via drmDMA\n",
- DRM_CURRENTPID, d.send_count );
+ if (d.send_count != 0) {
+ DRM_ERROR("Process %d trying to send %d buffers via drmDMA\n",
+ DRM_CURRENTPID, d.send_count);
return DRM_ERR(EINVAL);
}
/* We'll send you buffers.
*/
- if ( d.request_count < 0 || d.request_count > dma->buf_count ) {
- DRM_ERROR( "Process %d trying to get %d buffers (of %d max)\n",
- DRM_CURRENTPID, d.request_count, dma->buf_count );
+ if (d.request_count < 0 || d.request_count > dma->buf_count) {
+ DRM_ERROR("Process %d trying to get %d buffers (of %d max)\n",
+ DRM_CURRENTPID, d.request_count, dma->buf_count);
return DRM_ERR(EINVAL);
}
d.granted_count = 0;
- if ( d.request_count ) {
- ret = radeon_cp_get_buffers( filp, dev, &d );
+ if (d.request_count) {
+ ret = radeon_cp_get_buffers(filp, dev, &d);
}
- DRM_COPY_TO_USER_IOCTL( argp, d, sizeof(d) );
+ DRM_COPY_TO_USER_IOCTL(argp, d, sizeof(d));
return ret;
}
@@ -2051,13 +2125,16 @@ int radeon_driver_preinit(struct drm_device *dev, unsigned long flags)
dev_priv->flags |= CHIP_HAS_HIERZ;
break;
default:
- /* all other chips have no hierarchical z buffer */
+ /* all other chips have no hierarchical z buffer */
break;
}
if (drm_device_is_agp(dev))
dev_priv->flags |= CHIP_IS_AGP;
-
+
+ if (drm_device_is_pcie(dev))
+ dev_priv->flags |= CHIP_IS_PCIE;
+
DRM_DEBUG("%s card detected\n",
((dev_priv->flags & CHIP_IS_AGP) ? "AGP" : "PCI"));
return ret;
diff --git a/drivers/char/drm/radeon_drm.h b/drivers/char/drm/radeon_drm.h
index 3792798270a4..1cd81a671a36 100644
--- a/drivers/char/drm/radeon_drm.h
+++ b/drivers/char/drm/radeon_drm.h
@@ -57,78 +57,77 @@
#define RADEON_UPLOAD_TEX0IMAGES 0x00001000
#define RADEON_UPLOAD_TEX1IMAGES 0x00002000
#define RADEON_UPLOAD_TEX2IMAGES 0x00004000
-#define RADEON_UPLOAD_CLIPRECTS 0x00008000 /* handled client-side */
+#define RADEON_UPLOAD_CLIPRECTS 0x00008000 /* handled client-side */
#define RADEON_REQUIRE_QUIESCENCE 0x00010000
-#define RADEON_UPLOAD_ZBIAS 0x00020000 /* version 1.2 and newer */
+#define RADEON_UPLOAD_ZBIAS 0x00020000 /* version 1.2 and newer */
#define RADEON_UPLOAD_ALL 0x003effff
#define RADEON_UPLOAD_CONTEXT_ALL 0x003e01ff
-
/* New style per-packet identifiers for use in cmd_buffer ioctl with
* the RADEON_EMIT_PACKET command. Comments relate new packets to old
* state bits and the packet size:
*/
-#define RADEON_EMIT_PP_MISC 0 /* context/7 */
-#define RADEON_EMIT_PP_CNTL 1 /* context/3 */
-#define RADEON_EMIT_RB3D_COLORPITCH 2 /* context/1 */
-#define RADEON_EMIT_RE_LINE_PATTERN 3 /* line/2 */
-#define RADEON_EMIT_SE_LINE_WIDTH 4 /* line/1 */
-#define RADEON_EMIT_PP_LUM_MATRIX 5 /* bumpmap/1 */
-#define RADEON_EMIT_PP_ROT_MATRIX_0 6 /* bumpmap/2 */
-#define RADEON_EMIT_RB3D_STENCILREFMASK 7 /* masks/3 */
-#define RADEON_EMIT_SE_VPORT_XSCALE 8 /* viewport/6 */
-#define RADEON_EMIT_SE_CNTL 9 /* setup/2 */
-#define RADEON_EMIT_SE_CNTL_STATUS 10 /* setup/1 */
-#define RADEON_EMIT_RE_MISC 11 /* misc/1 */
-#define RADEON_EMIT_PP_TXFILTER_0 12 /* tex0/6 */
-#define RADEON_EMIT_PP_BORDER_COLOR_0 13 /* tex0/1 */
-#define RADEON_EMIT_PP_TXFILTER_1 14 /* tex1/6 */
-#define RADEON_EMIT_PP_BORDER_COLOR_1 15 /* tex1/1 */
-#define RADEON_EMIT_PP_TXFILTER_2 16 /* tex2/6 */
-#define RADEON_EMIT_PP_BORDER_COLOR_2 17 /* tex2/1 */
-#define RADEON_EMIT_SE_ZBIAS_FACTOR 18 /* zbias/2 */
-#define RADEON_EMIT_SE_TCL_OUTPUT_VTX_FMT 19 /* tcl/11 */
-#define RADEON_EMIT_SE_TCL_MATERIAL_EMMISSIVE_RED 20 /* material/17 */
-#define R200_EMIT_PP_TXCBLEND_0 21 /* tex0/4 */
-#define R200_EMIT_PP_TXCBLEND_1 22 /* tex1/4 */
-#define R200_EMIT_PP_TXCBLEND_2 23 /* tex2/4 */
-#define R200_EMIT_PP_TXCBLEND_3 24 /* tex3/4 */
-#define R200_EMIT_PP_TXCBLEND_4 25 /* tex4/4 */
-#define R200_EMIT_PP_TXCBLEND_5 26 /* tex5/4 */
-#define R200_EMIT_PP_TXCBLEND_6 27 /* /4 */
-#define R200_EMIT_PP_TXCBLEND_7 28 /* /4 */
-#define R200_EMIT_TCL_LIGHT_MODEL_CTL_0 29 /* tcl/7 */
-#define R200_EMIT_TFACTOR_0 30 /* tf/7 */
-#define R200_EMIT_VTX_FMT_0 31 /* vtx/5 */
-#define R200_EMIT_VAP_CTL 32 /* vap/1 */
-#define R200_EMIT_MATRIX_SELECT_0 33 /* msl/5 */
-#define R200_EMIT_TEX_PROC_CTL_2 34 /* tcg/5 */
-#define R200_EMIT_TCL_UCP_VERT_BLEND_CTL 35 /* tcl/1 */
-#define R200_EMIT_PP_TXFILTER_0 36 /* tex0/6 */
-#define R200_EMIT_PP_TXFILTER_1 37 /* tex1/6 */
-#define R200_EMIT_PP_TXFILTER_2 38 /* tex2/6 */
-#define R200_EMIT_PP_TXFILTER_3 39 /* tex3/6 */
-#define R200_EMIT_PP_TXFILTER_4 40 /* tex4/6 */
-#define R200_EMIT_PP_TXFILTER_5 41 /* tex5/6 */
-#define R200_EMIT_PP_TXOFFSET_0 42 /* tex0/1 */
-#define R200_EMIT_PP_TXOFFSET_1 43 /* tex1/1 */
-#define R200_EMIT_PP_TXOFFSET_2 44 /* tex2/1 */
-#define R200_EMIT_PP_TXOFFSET_3 45 /* tex3/1 */
-#define R200_EMIT_PP_TXOFFSET_4 46 /* tex4/1 */
-#define R200_EMIT_PP_TXOFFSET_5 47 /* tex5/1 */
-#define R200_EMIT_VTE_CNTL 48 /* vte/1 */
-#define R200_EMIT_OUTPUT_VTX_COMP_SEL 49 /* vtx/1 */
-#define R200_EMIT_PP_TAM_DEBUG3 50 /* tam/1 */
-#define R200_EMIT_PP_CNTL_X 51 /* cst/1 */
-#define R200_EMIT_RB3D_DEPTHXY_OFFSET 52 /* cst/1 */
-#define R200_EMIT_RE_AUX_SCISSOR_CNTL 53 /* cst/1 */
-#define R200_EMIT_RE_SCISSOR_TL_0 54 /* cst/2 */
-#define R200_EMIT_RE_SCISSOR_TL_1 55 /* cst/2 */
-#define R200_EMIT_RE_SCISSOR_TL_2 56 /* cst/2 */
-#define R200_EMIT_SE_VAP_CNTL_STATUS 57 /* cst/1 */
-#define R200_EMIT_SE_VTX_STATE_CNTL 58 /* cst/1 */
-#define R200_EMIT_RE_POINTSIZE 59 /* cst/1 */
-#define R200_EMIT_TCL_INPUT_VTX_VECTOR_ADDR_0 60 /* cst/4 */
+#define RADEON_EMIT_PP_MISC 0 /* context/7 */
+#define RADEON_EMIT_PP_CNTL 1 /* context/3 */
+#define RADEON_EMIT_RB3D_COLORPITCH 2 /* context/1 */
+#define RADEON_EMIT_RE_LINE_PATTERN 3 /* line/2 */
+#define RADEON_EMIT_SE_LINE_WIDTH 4 /* line/1 */
+#define RADEON_EMIT_PP_LUM_MATRIX 5 /* bumpmap/1 */
+#define RADEON_EMIT_PP_ROT_MATRIX_0 6 /* bumpmap/2 */
+#define RADEON_EMIT_RB3D_STENCILREFMASK 7 /* masks/3 */
+#define RADEON_EMIT_SE_VPORT_XSCALE 8 /* viewport/6 */
+#define RADEON_EMIT_SE_CNTL 9 /* setup/2 */
+#define RADEON_EMIT_SE_CNTL_STATUS 10 /* setup/1 */
+#define RADEON_EMIT_RE_MISC 11 /* misc/1 */
+#define RADEON_EMIT_PP_TXFILTER_0 12 /* tex0/6 */
+#define RADEON_EMIT_PP_BORDER_COLOR_0 13 /* tex0/1 */
+#define RADEON_EMIT_PP_TXFILTER_1 14 /* tex1/6 */
+#define RADEON_EMIT_PP_BORDER_COLOR_1 15 /* tex1/1 */
+#define RADEON_EMIT_PP_TXFILTER_2 16 /* tex2/6 */
+#define RADEON_EMIT_PP_BORDER_COLOR_2 17 /* tex2/1 */
+#define RADEON_EMIT_SE_ZBIAS_FACTOR 18 /* zbias/2 */
+#define RADEON_EMIT_SE_TCL_OUTPUT_VTX_FMT 19 /* tcl/11 */
+#define RADEON_EMIT_SE_TCL_MATERIAL_EMMISSIVE_RED 20 /* material/17 */
+#define R200_EMIT_PP_TXCBLEND_0 21 /* tex0/4 */
+#define R200_EMIT_PP_TXCBLEND_1 22 /* tex1/4 */
+#define R200_EMIT_PP_TXCBLEND_2 23 /* tex2/4 */
+#define R200_EMIT_PP_TXCBLEND_3 24 /* tex3/4 */
+#define R200_EMIT_PP_TXCBLEND_4 25 /* tex4/4 */
+#define R200_EMIT_PP_TXCBLEND_5 26 /* tex5/4 */
+#define R200_EMIT_PP_TXCBLEND_6 27 /* /4 */
+#define R200_EMIT_PP_TXCBLEND_7 28 /* /4 */
+#define R200_EMIT_TCL_LIGHT_MODEL_CTL_0 29 /* tcl/7 */
+#define R200_EMIT_TFACTOR_0 30 /* tf/7 */
+#define R200_EMIT_VTX_FMT_0 31 /* vtx/5 */
+#define R200_EMIT_VAP_CTL 32 /* vap/1 */
+#define R200_EMIT_MATRIX_SELECT_0 33 /* msl/5 */
+#define R200_EMIT_TEX_PROC_CTL_2 34 /* tcg/5 */
+#define R200_EMIT_TCL_UCP_VERT_BLEND_CTL 35 /* tcl/1 */
+#define R200_EMIT_PP_TXFILTER_0 36 /* tex0/6 */
+#define R200_EMIT_PP_TXFILTER_1 37 /* tex1/6 */
+#define R200_EMIT_PP_TXFILTER_2 38 /* tex2/6 */
+#define R200_EMIT_PP_TXFILTER_3 39 /* tex3/6 */
+#define R200_EMIT_PP_TXFILTER_4 40 /* tex4/6 */
+#define R200_EMIT_PP_TXFILTER_5 41 /* tex5/6 */
+#define R200_EMIT_PP_TXOFFSET_0 42 /* tex0/1 */
+#define R200_EMIT_PP_TXOFFSET_1 43 /* tex1/1 */
+#define R200_EMIT_PP_TXOFFSET_2 44 /* tex2/1 */
+#define R200_EMIT_PP_TXOFFSET_3 45 /* tex3/1 */
+#define R200_EMIT_PP_TXOFFSET_4 46 /* tex4/1 */
+#define R200_EMIT_PP_TXOFFSET_5 47 /* tex5/1 */
+#define R200_EMIT_VTE_CNTL 48 /* vte/1 */
+#define R200_EMIT_OUTPUT_VTX_COMP_SEL 49 /* vtx/1 */
+#define R200_EMIT_PP_TAM_DEBUG3 50 /* tam/1 */
+#define R200_EMIT_PP_CNTL_X 51 /* cst/1 */
+#define R200_EMIT_RB3D_DEPTHXY_OFFSET 52 /* cst/1 */
+#define R200_EMIT_RE_AUX_SCISSOR_CNTL 53 /* cst/1 */
+#define R200_EMIT_RE_SCISSOR_TL_0 54 /* cst/2 */
+#define R200_EMIT_RE_SCISSOR_TL_1 55 /* cst/2 */
+#define R200_EMIT_RE_SCISSOR_TL_2 56 /* cst/2 */
+#define R200_EMIT_SE_VAP_CNTL_STATUS 57 /* cst/1 */
+#define R200_EMIT_SE_VTX_STATE_CNTL 58 /* cst/1 */
+#define R200_EMIT_RE_POINTSIZE 59 /* cst/1 */
+#define R200_EMIT_TCL_INPUT_VTX_VECTOR_ADDR_0 60 /* cst/4 */
#define R200_EMIT_PP_CUBIC_FACES_0 61
#define R200_EMIT_PP_CUBIC_OFFSETS_0 62
#define R200_EMIT_PP_CUBIC_FACES_1 63
@@ -153,42 +152,50 @@
#define RADEON_EMIT_PP_CUBIC_FACES_2 82
#define RADEON_EMIT_PP_CUBIC_OFFSETS_T2 83
#define R200_EMIT_PP_TRI_PERF_CNTL 84
-#define RADEON_MAX_STATE_PACKETS 85
+#define R200_EMIT_PP_AFS_0 85
+#define R200_EMIT_PP_AFS_1 86
+#define R200_EMIT_ATF_TFACTOR 87
+#define R200_EMIT_PP_TXCTLALL_0 88
+#define R200_EMIT_PP_TXCTLALL_1 89
+#define R200_EMIT_PP_TXCTLALL_2 90
+#define R200_EMIT_PP_TXCTLALL_3 91
+#define R200_EMIT_PP_TXCTLALL_4 92
+#define R200_EMIT_PP_TXCTLALL_5 93
+#define RADEON_MAX_STATE_PACKETS 94
/* Commands understood by cmd_buffer ioctl. More can be added but
* obviously these can't be removed or changed:
*/
-#define RADEON_CMD_PACKET 1 /* emit one of the register packets above */
-#define RADEON_CMD_SCALARS 2 /* emit scalar data */
-#define RADEON_CMD_VECTORS 3 /* emit vector data */
-#define RADEON_CMD_DMA_DISCARD 4 /* discard current dma buf */
-#define RADEON_CMD_PACKET3 5 /* emit hw packet */
-#define RADEON_CMD_PACKET3_CLIP 6 /* emit hw packet wrapped in cliprects */
-#define RADEON_CMD_SCALARS2 7 /* r200 stopgap */
-#define RADEON_CMD_WAIT 8 /* emit hw wait commands -- note:
- * doesn't make the cpu wait, just
- * the graphics hardware */
-
+#define RADEON_CMD_PACKET 1 /* emit one of the register packets above */
+#define RADEON_CMD_SCALARS 2 /* emit scalar data */
+#define RADEON_CMD_VECTORS 3 /* emit vector data */
+#define RADEON_CMD_DMA_DISCARD 4 /* discard current dma buf */
+#define RADEON_CMD_PACKET3 5 /* emit hw packet */
+#define RADEON_CMD_PACKET3_CLIP 6 /* emit hw packet wrapped in cliprects */
+#define RADEON_CMD_SCALARS2 7 /* r200 stopgap */
+#define RADEON_CMD_WAIT 8 /* emit hw wait commands -- note:
+ * doesn't make the cpu wait, just
+ * the graphics hardware */
typedef union {
int i;
- struct {
+ struct {
unsigned char cmd_type, pad0, pad1, pad2;
} header;
- struct {
+ struct {
unsigned char cmd_type, packet_id, pad0, pad1;
} packet;
- struct {
- unsigned char cmd_type, offset, stride, count;
+ struct {
+ unsigned char cmd_type, offset, stride, count;
} scalars;
- struct {
- unsigned char cmd_type, offset, stride, count;
+ struct {
+ unsigned char cmd_type, offset, stride, count;
} vectors;
- struct {
- unsigned char cmd_type, buf_idx, pad0, pad1;
+ struct {
+ unsigned char cmd_type, buf_idx, pad0, pad1;
} dma;
- struct {
- unsigned char cmd_type, flags, pad0, pad1;
+ struct {
+ unsigned char cmd_type, flags, pad0, pad1;
} wait;
} drm_radeon_cmd_header_t;
@@ -204,10 +211,10 @@ typedef union {
* The interface has not been stabilized, so some of these may be removed
* and eventually reordered before stabilization.
*/
-#define R300_CMD_PACKET0 1
-#define R300_CMD_VPU 2 /* emit vertex program upload */
-#define R300_CMD_PACKET3 3 /* emit a packet3 */
-#define R300_CMD_END3D 4 /* emit sequence ending 3d rendering */
+#define R300_CMD_PACKET0 1
+#define R300_CMD_VPU 2 /* emit vertex program upload */
+#define R300_CMD_PACKET3 3 /* emit a packet3 */
+#define R300_CMD_END3D 4 /* emit sequence ending 3d rendering */
#define R300_CMD_CP_DELAY 5
#define R300_CMD_DMA_DISCARD 6
#define R300_CMD_WAIT 7
@@ -232,13 +239,13 @@ typedef union {
} packet3;
struct {
unsigned char cmd_type, packet;
- unsigned short count; /* amount of packet2 to emit */
+ unsigned short count; /* amount of packet2 to emit */
} delay;
struct {
unsigned char cmd_type, buf_idx, pad0, pad1;
} dma;
struct {
- unsigned char cmd_type, flags, pad0, pad1;
+ unsigned char cmd_type, flags, pad0, pad1;
} wait;
} drm_r300_cmd_header_t;
@@ -292,7 +299,7 @@ typedef union {
#define RADEON_OFFSET_ALIGN (1 << RADEON_OFFSET_SHIFT)
#define RADEON_OFFSET_MASK (RADEON_OFFSET_ALIGN - 1)
-#endif /* __RADEON_SAREA_DEFINES__ */
+#endif /* __RADEON_SAREA_DEFINES__ */
typedef struct {
unsigned int red;
@@ -303,7 +310,7 @@ typedef struct {
typedef struct {
/* Context state */
- unsigned int pp_misc; /* 0x1c14 */
+ unsigned int pp_misc; /* 0x1c14 */
unsigned int pp_fog_color;
unsigned int re_solid_color;
unsigned int rb3d_blendcntl;
@@ -311,7 +318,7 @@ typedef struct {
unsigned int rb3d_depthpitch;
unsigned int rb3d_zstencilcntl;
- unsigned int pp_cntl; /* 0x1c38 */
+ unsigned int pp_cntl; /* 0x1c38 */
unsigned int rb3d_cntl;
unsigned int rb3d_coloroffset;
unsigned int re_width_height;
@@ -319,27 +326,27 @@ typedef struct {
unsigned int se_cntl;
/* Vertex format state */
- unsigned int se_coord_fmt; /* 0x1c50 */
+ unsigned int se_coord_fmt; /* 0x1c50 */
/* Line state */
- unsigned int re_line_pattern; /* 0x1cd0 */
+ unsigned int re_line_pattern; /* 0x1cd0 */
unsigned int re_line_state;
- unsigned int se_line_width; /* 0x1db8 */
+ unsigned int se_line_width; /* 0x1db8 */
/* Bumpmap state */
- unsigned int pp_lum_matrix; /* 0x1d00 */
+ unsigned int pp_lum_matrix; /* 0x1d00 */
- unsigned int pp_rot_matrix_0; /* 0x1d58 */
+ unsigned int pp_rot_matrix_0; /* 0x1d58 */
unsigned int pp_rot_matrix_1;
/* Mask state */
- unsigned int rb3d_stencilrefmask; /* 0x1d7c */
+ unsigned int rb3d_stencilrefmask; /* 0x1d7c */
unsigned int rb3d_ropcntl;
unsigned int rb3d_planemask;
/* Viewport state */
- unsigned int se_vport_xscale; /* 0x1d98 */
+ unsigned int se_vport_xscale; /* 0x1d98 */
unsigned int se_vport_xoffset;
unsigned int se_vport_yscale;
unsigned int se_vport_yoffset;
@@ -347,20 +354,19 @@ typedef struct {
unsigned int se_vport_zoffset;
/* Setup state */
- unsigned int se_cntl_status; /* 0x2140 */
+ unsigned int se_cntl_status; /* 0x2140 */
/* Misc state */
- unsigned int re_top_left; /* 0x26c0 */
+ unsigned int re_top_left; /* 0x26c0 */
unsigned int re_misc;
} drm_radeon_context_regs_t;
typedef struct {
/* Zbias state */
- unsigned int se_zbias_factor; /* 0x1dac */
+ unsigned int se_zbias_factor; /* 0x1dac */
unsigned int se_zbias_constant;
} drm_radeon_context2_regs_t;
-
/* Setup registers for each texture unit
*/
typedef struct {
@@ -378,11 +384,10 @@ typedef struct {
unsigned int finish;
unsigned int prim:8;
unsigned int stateidx:8;
- unsigned int numverts:16; /* overloaded as offset/64 for elt prims */
- unsigned int vc_format; /* vertex format */
+ unsigned int numverts:16; /* overloaded as offset/64 for elt prims */
+ unsigned int vc_format; /* vertex format */
} drm_radeon_prim_t;
-
typedef struct {
drm_radeon_context_regs_t context;
drm_radeon_texture_regs_t tex[RADEON_MAX_TEXTURE_UNITS];
@@ -390,7 +395,6 @@ typedef struct {
unsigned int dirty;
} drm_radeon_state_t;
-
typedef struct {
/* The channel for communication of state information to the
* kernel on firing a vertex buffer with either of the
@@ -413,16 +417,16 @@ typedef struct {
unsigned int last_dispatch;
unsigned int last_clear;
- drm_tex_region_t tex_list[RADEON_NR_TEX_HEAPS][RADEON_NR_TEX_REGIONS+1];
+ drm_tex_region_t tex_list[RADEON_NR_TEX_HEAPS][RADEON_NR_TEX_REGIONS +
+ 1];
unsigned int tex_age[RADEON_NR_TEX_HEAPS];
int ctx_owner;
- int pfState; /* number of 3d windows (0,1,2ormore) */
- int pfCurrentPage; /* which buffer is being displayed? */
- int crtc2_base; /* CRTC2 frame offset */
+ int pfState; /* number of 3d windows (0,1,2ormore) */
+ int pfCurrentPage; /* which buffer is being displayed? */
+ int crtc2_base; /* CRTC2 frame offset */
int tiling_enabled; /* set by drm, read by 2d + 3d clients */
} drm_radeon_sarea_t;
-
/* WARNING: If you change any of these defines, make sure to change the
* defines in the Xserver file (xf86drmRadeon.h)
*
@@ -432,15 +436,15 @@ typedef struct {
/* Radeon specific ioctls
* The device specific ioctl range is 0x40 to 0x79.
*/
-#define DRM_RADEON_CP_INIT 0x00
-#define DRM_RADEON_CP_START 0x01
+#define DRM_RADEON_CP_INIT 0x00
+#define DRM_RADEON_CP_START 0x01
#define DRM_RADEON_CP_STOP 0x02
#define DRM_RADEON_CP_RESET 0x03
#define DRM_RADEON_CP_IDLE 0x04
-#define DRM_RADEON_RESET 0x05
+#define DRM_RADEON_RESET 0x05
#define DRM_RADEON_FULLSCREEN 0x06
-#define DRM_RADEON_SWAP 0x07
-#define DRM_RADEON_CLEAR 0x08
+#define DRM_RADEON_SWAP 0x07
+#define DRM_RADEON_CLEAR 0x08
#define DRM_RADEON_VERTEX 0x09
#define DRM_RADEON_INDICES 0x0A
#define DRM_RADEON_NOT_USED
@@ -491,7 +495,7 @@ typedef struct {
typedef struct drm_radeon_init {
enum {
- RADEON_INIT_CP = 0x01,
+ RADEON_INIT_CP = 0x01,
RADEON_CLEANUP_CP = 0x02,
RADEON_INIT_R200_CP = 0x03,
RADEON_INIT_R300_CP = 0x04
@@ -524,7 +528,7 @@ typedef struct drm_radeon_cp_stop {
typedef struct drm_radeon_fullscreen {
enum {
- RADEON_INIT_FULLSCREEN = 0x01,
+ RADEON_INIT_FULLSCREEN = 0x01,
RADEON_CLEANUP_FULLSCREEN = 0x02
} func;
} drm_radeon_fullscreen_t;
@@ -545,15 +549,15 @@ typedef struct drm_radeon_clear {
unsigned int clear_color;
unsigned int clear_depth;
unsigned int color_mask;
- unsigned int depth_mask; /* misnamed field: should be stencil */
+ unsigned int depth_mask; /* misnamed field: should be stencil */
drm_radeon_clear_rect_t __user *depth_boxes;
} drm_radeon_clear_t;
typedef struct drm_radeon_vertex {
int prim;
- int idx; /* Index of vertex buffer */
- int count; /* Number of vertices in buffer */
- int discard; /* Client finished with buffer? */
+ int idx; /* Index of vertex buffer */
+ int count; /* Number of vertices in buffer */
+ int discard; /* Client finished with buffer? */
} drm_radeon_vertex_t;
typedef struct drm_radeon_indices {
@@ -561,7 +565,7 @@ typedef struct drm_radeon_indices {
int idx;
int start;
int end;
- int discard; /* Client finished with buffer? */
+ int discard; /* Client finished with buffer? */
} drm_radeon_indices_t;
/* v1.2 - obsoletes drm_radeon_vertex and drm_radeon_indices
@@ -569,8 +573,8 @@ typedef struct drm_radeon_indices {
* - supports driver change to emit native primitives
*/
typedef struct drm_radeon_vertex2 {
- int idx; /* Index of vertex buffer */
- int discard; /* Client finished with buffer? */
+ int idx; /* Index of vertex buffer */
+ int discard; /* Client finished with buffer? */
int nr_states;
drm_radeon_state_t __user *state;
int nr_prims;
@@ -578,10 +582,10 @@ typedef struct drm_radeon_vertex2 {
} drm_radeon_vertex2_t;
/* v1.3 - obsoletes drm_radeon_vertex2
- * - allows arbitarily large cliprect list
+ * - allows arbitarily large cliprect list
* - allows updating of tcl packet, vector and scalar state
* - allows memory-efficient description of state updates
- * - allows state to be emitted without a primitive
+ * - allows state to be emitted without a primitive
* (for clears, ctx switches)
* - allows more than one dma buffer to be referenced per ioctl
* - supports tcl driver
@@ -595,7 +599,7 @@ typedef struct drm_radeon_cmd_buffer {
} drm_radeon_cmd_buffer_t;
typedef struct drm_radeon_tex_image {
- unsigned int x, y; /* Blit coordinates */
+ unsigned int x, y; /* Blit coordinates */
unsigned int width, height;
const void __user *data;
} drm_radeon_tex_image_t;
@@ -604,7 +608,7 @@ typedef struct drm_radeon_texture {
unsigned int offset;
int pitch;
int format;
- int width; /* Texture image coordinates */
+ int width; /* Texture image coordinates */
int height;
drm_radeon_tex_image_t __user *image;
} drm_radeon_texture_t;
@@ -620,19 +624,18 @@ typedef struct drm_radeon_indirect {
int discard;
} drm_radeon_indirect_t;
-
/* 1.3: An ioctl to get parameters that aren't available to the 3d
- * client any other way.
+ * client any other way.
*/
-#define RADEON_PARAM_GART_BUFFER_OFFSET 1 /* card offset of 1st GART buffer */
+#define RADEON_PARAM_GART_BUFFER_OFFSET 1 /* card offset of 1st GART buffer */
#define RADEON_PARAM_LAST_FRAME 2
#define RADEON_PARAM_LAST_DISPATCH 3
#define RADEON_PARAM_LAST_CLEAR 4
/* Added with DRM version 1.6. */
#define RADEON_PARAM_IRQ_NR 5
-#define RADEON_PARAM_GART_BASE 6 /* card offset of GART base */
+#define RADEON_PARAM_GART_BASE 6 /* card offset of GART base */
/* Added with DRM version 1.8. */
-#define RADEON_PARAM_REGISTER_HANDLE 7 /* for drmMap() */
+#define RADEON_PARAM_REGISTER_HANDLE 7 /* for drmMap() */
#define RADEON_PARAM_STATUS_HANDLE 8
#define RADEON_PARAM_SAREA_HANDLE 9
#define RADEON_PARAM_GART_TEX_HANDLE 10
@@ -663,10 +666,9 @@ typedef struct drm_radeon_mem_free {
typedef struct drm_radeon_mem_init_heap {
int region;
int size;
- int start;
+ int start;
} drm_radeon_mem_init_heap_t;
-
/* 1.6: Userspace can request & wait on irq's:
*/
typedef struct drm_radeon_irq_emit {
@@ -677,18 +679,18 @@ typedef struct drm_radeon_irq_wait {
int irq_seq;
} drm_radeon_irq_wait_t;
-
/* 1.10: Clients tell the DRM where they think the framebuffer is located in
* the card's address space, via a new generic ioctl to set parameters
*/
typedef struct drm_radeon_setparam {
unsigned int param;
- int64_t value;
+ int64_t value;
} drm_radeon_setparam_t;
#define RADEON_SETPARAM_FB_LOCATION 1 /* determined framebuffer location */
#define RADEON_SETPARAM_SWITCH_TILING 2 /* enable/disable color tiling */
+#define RADEON_SETPARAM_PCIGART_LOCATION 3 /* PCI Gart Location */
/* 1.14: Clients can allocate/free a surface
*/
diff --git a/drivers/char/drm/radeon_drv.c b/drivers/char/drm/radeon_drv.c
index e0682f64b400..ee49670d8162 100644
--- a/drivers/char/drm/radeon_drv.c
+++ b/drivers/char/drm/radeon_drv.c
@@ -29,7 +29,6 @@
* OTHER DEALINGS IN THE SOFTWARE.
*/
-
#include <linux/config.h>
#include "drmP.h"
#include "drm.h"
@@ -38,30 +37,33 @@
#include "drm_pciids.h"
-static int postinit( struct drm_device *dev, unsigned long flags )
+int radeon_no_wb;
+
+MODULE_PARM_DESC(no_wb, "Disable AGP writeback for scratch registers\n");
+module_param_named(no_wb, radeon_no_wb, int, 0444);
+
+static int postinit(struct drm_device *dev, unsigned long flags)
{
- DRM_INFO( "Initialized %s %d.%d.%d %s on minor %d: %s\n",
- DRIVER_NAME,
- DRIVER_MAJOR,
- DRIVER_MINOR,
- DRIVER_PATCHLEVEL,
- DRIVER_DATE,
- dev->primary.minor,
- pci_pretty_name(dev->pdev)
- );
+ DRM_INFO("Initialized %s %d.%d.%d %s on minor %d: %s\n",
+ DRIVER_NAME,
+ DRIVER_MAJOR,
+ DRIVER_MINOR,
+ DRIVER_PATCHLEVEL,
+ DRIVER_DATE, dev->primary.minor, pci_pretty_name(dev->pdev)
+ );
return 0;
}
-static int version( drm_version_t *version )
+static int version(drm_version_t * version)
{
int len;
version->version_major = DRIVER_MAJOR;
version->version_minor = DRIVER_MINOR;
version->version_patchlevel = DRIVER_PATCHLEVEL;
- DRM_COPY( version->name, DRIVER_NAME );
- DRM_COPY( version->date, DRIVER_DATE );
- DRM_COPY( version->desc, DRIVER_DESC );
+ DRM_COPY(version->name, DRIVER_NAME);
+ DRM_COPY(version->date, DRIVER_DATE);
+ DRM_COPY(version->desc, DRIVER_DESC);
return 0;
}
@@ -69,11 +71,11 @@ static struct pci_device_id pciidlist[] = {
radeon_PCI_IDS
};
-extern drm_ioctl_desc_t radeon_ioctls[];
-extern int radeon_max_ioctl;
-
static struct drm_driver driver = {
- .driver_features = DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | DRIVER_SG | DRIVER_HAVE_IRQ | DRIVER_HAVE_DMA | DRIVER_IRQ_SHARED | DRIVER_IRQ_VBL,
+ .driver_features =
+ DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | DRIVER_SG |
+ DRIVER_HAVE_IRQ | DRIVER_HAVE_DMA | DRIVER_IRQ_SHARED |
+ DRIVER_IRQ_VBL,
.dev_priv_size = sizeof(drm_radeon_buf_priv_t),
.preinit = radeon_driver_preinit,
.presetup = radeon_presetup,
@@ -95,21 +97,22 @@ static struct drm_driver driver = {
.ioctls = radeon_ioctls,
.dma_ioctl = radeon_cp_buffers,
.fops = {
- .owner = THIS_MODULE,
- .open = drm_open,
- .release = drm_release,
- .ioctl = drm_ioctl,
- .mmap = drm_mmap,
- .poll = drm_poll,
- .fasync = drm_fasync,
+ .owner = THIS_MODULE,
+ .open = drm_open,
+ .release = drm_release,
+ .ioctl = drm_ioctl,
+ .mmap = drm_mmap,
+ .poll = drm_poll,
+ .fasync = drm_fasync,
#ifdef CONFIG_COMPAT
- .compat_ioctl = radeon_compat_ioctl,
+ .compat_ioctl = radeon_compat_ioctl,
#endif
- },
+ }
+ ,
.pci_driver = {
- .name = DRIVER_NAME,
- .id_table = pciidlist,
- }
+ .name = DRIVER_NAME,
+ .id_table = pciidlist,
+ }
};
static int __init radeon_init(void)
@@ -126,6 +129,6 @@ static void __exit radeon_exit(void)
module_init(radeon_init);
module_exit(radeon_exit);
-MODULE_AUTHOR( DRIVER_AUTHOR );
-MODULE_DESCRIPTION( DRIVER_DESC );
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL and additional rights");
diff --git a/drivers/char/drm/radeon_drv.h b/drivers/char/drm/radeon_drv.h
index f12a963ede18..120ee5a8ebcc 100644
--- a/drivers/char/drm/radeon_drv.h
+++ b/drivers/char/drm/radeon_drv.h
@@ -38,7 +38,7 @@
#define DRIVER_NAME "radeon"
#define DRIVER_DESC "ATI Radeon"
-#define DRIVER_DATE "20050311"
+#define DRIVER_DATE "20050911"
/* Interface history:
*
@@ -68,7 +68,7 @@
* 1.9 - Add DRM_IOCTL_RADEON_CP_RESUME ioctl.
* Add texture rectangle support for r100.
* 1.10- Add SETPARAM ioctl; first parameter to set is FB_LOCATION, which
- * clients use to tell the DRM where they think the framebuffer is
+ * clients use to tell the DRM where they think the framebuffer is
* located in the card's address space
* 1.11- Add packet R200_EMIT_RB3D_BLENDCOLOR to support GL_EXT_blend_color
* and GL_EXT_blend_[func|equation]_separate on r200
@@ -83,9 +83,14 @@
* 1.16- Add R200_EMIT_PP_TRI_PERF_CNTL packet to support brilinear
* texture filtering on r200
* 1.17- Add initial support for R300 (3D).
+ * 1.18- Add support for GL_ATI_fragment_shader, new packets
+ * R200_EMIT_PP_AFS_0/1, R200_EMIT_PP_TXCTLALL_0-5 (replaces
+ * R200_EMIT_PP_TXFILTER_0-5, 2 more regs) and R200_EMIT_ATF_TFACTOR
+ * (replaces R200_EMIT_TFACTOR_0 (8 consts instead of 6)
+ * 1.19- Add support for gart table in FB memory and PCIE r300
*/
#define DRIVER_MAJOR 1
-#define DRIVER_MINOR 17
+#define DRIVER_MINOR 19
#define DRIVER_PATCHLEVEL 0
#define GET_RING_HEAD(dev_priv) DRM_READ32( (dev_priv)->ring_rptr, 0 )
@@ -129,14 +134,15 @@ enum radeon_chip_flags {
CHIP_IS_IGP = 0x00020000UL,
CHIP_SINGLE_CRTC = 0x00040000UL,
CHIP_IS_AGP = 0x00080000UL,
- CHIP_HAS_HIERZ = 0x00100000UL,
+ CHIP_HAS_HIERZ = 0x00100000UL,
+ CHIP_IS_PCIE = 0x00200000UL,
};
typedef struct drm_radeon_freelist {
- unsigned int age;
- drm_buf_t *buf;
- struct drm_radeon_freelist *next;
- struct drm_radeon_freelist *prev;
+ unsigned int age;
+ drm_buf_t *buf;
+ struct drm_radeon_freelist *next;
+ struct drm_radeon_freelist *prev;
} drm_radeon_freelist_t;
typedef struct drm_radeon_ring_buffer {
@@ -198,8 +204,8 @@ typedef struct drm_radeon_private {
int cp_mode;
int cp_running;
- drm_radeon_freelist_t *head;
- drm_radeon_freelist_t *tail;
+ drm_radeon_freelist_t *head;
+ drm_radeon_freelist_t *tail;
int last_buf;
volatile u32 *scratch;
int writeback_works;
@@ -209,8 +215,6 @@ typedef struct drm_radeon_private {
int microcode_version;
int is_pci;
- unsigned long phys_pci_gart;
- dma_addr_t bus_pci_gart;
struct {
u32 boxes;
@@ -242,7 +246,7 @@ typedef struct drm_radeon_private {
u32 depth_pitch_offset;
drm_radeon_depth_clear_t depth_clear;
-
+
unsigned long fb_offset;
unsigned long mmio_offset;
unsigned long ring_offset;
@@ -260,11 +264,14 @@ typedef struct drm_radeon_private {
struct mem_block *fb_heap;
/* SW interrupt */
- wait_queue_head_t swi_queue;
- atomic_t swi_emitted;
+ wait_queue_head_t swi_queue;
+ atomic_t swi_emitted;
struct radeon_surface surfaces[RADEON_MAX_SURFACES];
- struct radeon_virt_surface virt_surfaces[2*RADEON_MAX_SURFACES];
+ struct radeon_virt_surface virt_surfaces[2 * RADEON_MAX_SURFACES];
+
+ unsigned long pcigart_offset;
+ drm_ati_pcigart_info gart_info;
/* starting from here on, data is preserved accross an open */
uint32_t flags; /* see radeon_chip_flags */
@@ -274,63 +281,76 @@ typedef struct drm_radeon_buf_priv {
u32 age;
} drm_radeon_buf_priv_t;
+typedef struct drm_radeon_kcmd_buffer {
+ int bufsz;
+ char *buf;
+ int nbox;
+ drm_clip_rect_t __user *boxes;
+} drm_radeon_kcmd_buffer_t;
+
+extern int radeon_no_wb;
+extern drm_ioctl_desc_t radeon_ioctls[];
+extern int radeon_max_ioctl;
+
/* radeon_cp.c */
-extern int radeon_cp_init( DRM_IOCTL_ARGS );
-extern int radeon_cp_start( DRM_IOCTL_ARGS );
-extern int radeon_cp_stop( DRM_IOCTL_ARGS );
-extern int radeon_cp_reset( DRM_IOCTL_ARGS );
-extern int radeon_cp_idle( DRM_IOCTL_ARGS );
-extern int radeon_cp_resume( DRM_IOCTL_ARGS );
-extern int radeon_engine_reset( DRM_IOCTL_ARGS );
-extern int radeon_fullscreen( DRM_IOCTL_ARGS );
-extern int radeon_cp_buffers( DRM_IOCTL_ARGS );
+extern int radeon_cp_init(DRM_IOCTL_ARGS);
+extern int radeon_cp_start(DRM_IOCTL_ARGS);
+extern int radeon_cp_stop(DRM_IOCTL_ARGS);
+extern int radeon_cp_reset(DRM_IOCTL_ARGS);
+extern int radeon_cp_idle(DRM_IOCTL_ARGS);
+extern int radeon_cp_resume(DRM_IOCTL_ARGS);
+extern int radeon_engine_reset(DRM_IOCTL_ARGS);
+extern int radeon_fullscreen(DRM_IOCTL_ARGS);
+extern int radeon_cp_buffers(DRM_IOCTL_ARGS);
-extern void radeon_freelist_reset( drm_device_t *dev );
-extern drm_buf_t *radeon_freelist_get( drm_device_t *dev );
+extern void radeon_freelist_reset(drm_device_t * dev);
+extern drm_buf_t *radeon_freelist_get(drm_device_t * dev);
-extern int radeon_wait_ring( drm_radeon_private_t *dev_priv, int n );
+extern int radeon_wait_ring(drm_radeon_private_t * dev_priv, int n);
-extern int radeon_do_cp_idle( drm_radeon_private_t *dev_priv );
+extern int radeon_do_cp_idle(drm_radeon_private_t * dev_priv);
extern int radeon_driver_preinit(struct drm_device *dev, unsigned long flags);
extern int radeon_presetup(struct drm_device *dev);
extern int radeon_driver_postcleanup(struct drm_device *dev);
-extern int radeon_mem_alloc( DRM_IOCTL_ARGS );
-extern int radeon_mem_free( DRM_IOCTL_ARGS );
-extern int radeon_mem_init_heap( DRM_IOCTL_ARGS );
-extern void radeon_mem_takedown( struct mem_block **heap );
-extern void radeon_mem_release( DRMFILE filp, struct mem_block *heap );
+extern int radeon_mem_alloc(DRM_IOCTL_ARGS);
+extern int radeon_mem_free(DRM_IOCTL_ARGS);
+extern int radeon_mem_init_heap(DRM_IOCTL_ARGS);
+extern void radeon_mem_takedown(struct mem_block **heap);
+extern void radeon_mem_release(DRMFILE filp, struct mem_block *heap);
/* radeon_irq.c */
-extern int radeon_irq_emit( DRM_IOCTL_ARGS );
-extern int radeon_irq_wait( DRM_IOCTL_ARGS );
-
-extern void radeon_do_release(drm_device_t *dev);
-extern int radeon_driver_vblank_wait(drm_device_t *dev, unsigned int *sequence);
-extern irqreturn_t radeon_driver_irq_handler( DRM_IRQ_ARGS );
-extern void radeon_driver_irq_preinstall( drm_device_t *dev );
-extern void radeon_driver_irq_postinstall( drm_device_t *dev );
-extern void radeon_driver_irq_uninstall( drm_device_t *dev );
-extern void radeon_driver_prerelease(drm_device_t *dev, DRMFILE filp);
-extern void radeon_driver_pretakedown(drm_device_t *dev);
-extern int radeon_driver_open_helper(drm_device_t *dev, drm_file_t *filp_priv);
-extern void radeon_driver_free_filp_priv(drm_device_t *dev, drm_file_t *filp_priv);
-
-extern int radeon_preinit( struct drm_device *dev, unsigned long flags );
-extern int radeon_postinit( struct drm_device *dev, unsigned long flags );
-extern int radeon_postcleanup( struct drm_device *dev );
+extern int radeon_irq_emit(DRM_IOCTL_ARGS);
+extern int radeon_irq_wait(DRM_IOCTL_ARGS);
+
+extern void radeon_do_release(drm_device_t * dev);
+extern int radeon_driver_vblank_wait(drm_device_t * dev,
+ unsigned int *sequence);
+extern irqreturn_t radeon_driver_irq_handler(DRM_IRQ_ARGS);
+extern void radeon_driver_irq_preinstall(drm_device_t * dev);
+extern void radeon_driver_irq_postinstall(drm_device_t * dev);
+extern void radeon_driver_irq_uninstall(drm_device_t * dev);
+extern void radeon_driver_prerelease(drm_device_t * dev, DRMFILE filp);
+extern void radeon_driver_pretakedown(drm_device_t * dev);
+extern int radeon_driver_open_helper(drm_device_t * dev,
+ drm_file_t * filp_priv);
+extern void radeon_driver_free_filp_priv(drm_device_t * dev,
+ drm_file_t * filp_priv);
+
+extern int radeon_preinit(struct drm_device *dev, unsigned long flags);
+extern int radeon_postinit(struct drm_device *dev, unsigned long flags);
+extern int radeon_postcleanup(struct drm_device *dev);
extern long radeon_compat_ioctl(struct file *filp, unsigned int cmd,
unsigned long arg);
-
/* r300_cmdbuf.c */
extern void r300_init_reg_flags(void);
-extern int r300_do_cp_cmdbuf(drm_device_t* dev, DRMFILE filp,
- drm_file_t* filp_priv,
- drm_radeon_cmd_buffer_t* cmdbuf);
+extern int r300_do_cp_cmdbuf(drm_device_t * dev, DRMFILE filp,
+ drm_file_t * filp_priv,
+ drm_radeon_kcmd_buffer_t * cmdbuf);
/* Flags for stats.boxes
*/
@@ -340,8 +360,6 @@ extern int r300_do_cp_cmdbuf(drm_device_t* dev, DRMFILE filp,
#define RADEON_BOX_WAIT_IDLE 0x8
#define RADEON_BOX_TEXTURE_LOAD 0x10
-
-
/* Register definitions, register access macros and drmAddMap constants
* for Radeon kernel driver.
*/
@@ -369,6 +387,25 @@ extern int r300_do_cp_cmdbuf(drm_device_t* dev, DRMFILE filp,
#define RADEON_CRTC2_OFFSET 0x0324
#define RADEON_CRTC2_OFFSET_CNTL 0x0328
+#define RADEON_PCIE_INDEX 0x0030
+#define RADEON_PCIE_DATA 0x0034
+#define RADEON_PCIE_TX_GART_CNTL 0x10
+# define RADEON_PCIE_TX_GART_EN (1 << 0)
+# define RADEON_PCIE_TX_GART_UNMAPPED_ACCESS_PASS_THRU (0<<1)
+# define RADEON_PCIE_TX_GART_UNMAPPED_ACCESS_CLAMP_LO (1<<1)
+# define RADEON_PCIE_TX_GART_UNMAPPED_ACCESS_DISCARD (3<<1)
+# define RADEON_PCIE_TX_GART_MODE_32_128_CACHE (0<<3)
+# define RADEON_PCIE_TX_GART_MODE_8_4_128_CACHE (1<<3)
+# define RADEON_PCIE_TX_GART_CHK_RW_VALID_EN (1<<5)
+# define RADEON_PCIE_TX_GART_INVALIDATE_TLB (1<<8)
+#define RADEON_PCIE_TX_DISCARD_RD_ADDR_LO 0x11
+#define RADEON_PCIE_TX_DISCARD_RD_ADDR_HI 0x12
+#define RADEON_PCIE_TX_GART_BASE 0x13
+#define RADEON_PCIE_TX_GART_START_LO 0x14
+#define RADEON_PCIE_TX_GART_START_HI 0x15
+#define RADEON_PCIE_TX_GART_END_LO 0x16
+#define RADEON_PCIE_TX_GART_END_HI 0x17
+
#define RADEON_MPP_TB_CONFIG 0x01c0
#define RADEON_MEM_CNTL 0x0140
#define RADEON_MEM_SDRAM_MODE_REG 0x0158
@@ -416,7 +453,6 @@ extern int r300_do_cp_cmdbuf(drm_device_t* dev, DRMFILE filp,
? DRM_READ32( dev_priv->ring_rptr, RADEON_SCRATCHOFF(x) ) \
: RADEON_READ( RADEON_SCRATCH_REG0 + 4*(x) ) )
-
#define RADEON_GEN_INT_CNTL 0x0040
# define RADEON_CRTC_VBLANK_MASK (1 << 0)
# define RADEON_GUI_IDLE_INT_ENABLE (1 << 19)
@@ -624,7 +660,6 @@ extern int r300_do_cp_cmdbuf(drm_device_t* dev, DRMFILE filp,
# define RADEON_DEPTH_FORMAT_16BIT_INT_Z (0 << 0)
# define RADEON_DEPTH_FORMAT_24BIT_INT_Z (2 << 0)
-
/* CP registers */
#define RADEON_CP_ME_RAM_ADDR 0x07d4
#define RADEON_CP_ME_RAM_RADDR 0x07d8
@@ -672,7 +707,7 @@ extern int r300_do_cp_cmdbuf(drm_device_t* dev, DRMFILE filp,
# define RADEON_CP_NEXT_CHAR 0x00001900
# define RADEON_CP_PLY_NEXTSCAN 0x00001D00
# define RADEON_CP_SET_SCISSORS 0x00001E00
- /* GEN_INDX_PRIM is unsupported starting with R300 */
+ /* GEN_INDX_PRIM is unsupported starting with R300 */
# define RADEON_3D_RNDR_GEN_INDX_PRIM 0x00002300
# define RADEON_WAIT_FOR_IDLE 0x00002600
# define RADEON_3D_DRAW_VBUF 0x00002800
@@ -756,19 +791,19 @@ extern int r300_do_cp_cmdbuf(drm_device_t* dev, DRMFILE filp,
#define R200_PP_TXCBLEND_5 0x2f50
#define R200_PP_TXCBLEND_6 0x2f60
#define R200_PP_TXCBLEND_7 0x2f70
-#define R200_SE_TCL_LIGHT_MODEL_CTL_0 0x2268
+#define R200_SE_TCL_LIGHT_MODEL_CTL_0 0x2268
#define R200_PP_TFACTOR_0 0x2ee0
#define R200_SE_VTX_FMT_0 0x2088
#define R200_SE_VAP_CNTL 0x2080
#define R200_SE_TCL_MATRIX_SEL_0 0x2230
-#define R200_SE_TCL_TEX_PROC_CTL_2 0x22a8
-#define R200_SE_TCL_UCP_VERT_BLEND_CTL 0x22c0
-#define R200_PP_TXFILTER_5 0x2ca0
-#define R200_PP_TXFILTER_4 0x2c80
-#define R200_PP_TXFILTER_3 0x2c60
-#define R200_PP_TXFILTER_2 0x2c40
-#define R200_PP_TXFILTER_1 0x2c20
-#define R200_PP_TXFILTER_0 0x2c00
+#define R200_SE_TCL_TEX_PROC_CTL_2 0x22a8
+#define R200_SE_TCL_UCP_VERT_BLEND_CTL 0x22c0
+#define R200_PP_TXFILTER_5 0x2ca0
+#define R200_PP_TXFILTER_4 0x2c80
+#define R200_PP_TXFILTER_3 0x2c60
+#define R200_PP_TXFILTER_2 0x2c40
+#define R200_PP_TXFILTER_1 0x2c20
+#define R200_PP_TXFILTER_0 0x2c00
#define R200_PP_TXOFFSET_5 0x2d78
#define R200_PP_TXOFFSET_4 0x2d60
#define R200_PP_TXOFFSET_3 0x2d48
@@ -822,13 +857,13 @@ extern int r300_do_cp_cmdbuf(drm_device_t* dev, DRMFILE filp,
#define R200_RE_SCISSOR_TL_0 0x1cd8
#define R200_RE_SCISSOR_TL_1 0x1ce0
#define R200_RE_SCISSOR_TL_2 0x1ce8
-#define R200_RB3D_DEPTHXY_OFFSET 0x1d60
+#define R200_RB3D_DEPTHXY_OFFSET 0x1d60
#define R200_RE_AUX_SCISSOR_CNTL 0x26f0
#define R200_SE_VTX_STATE_CNTL 0x2180
#define R200_RE_POINTSIZE 0x2648
#define R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_0 0x2254
-#define RADEON_PP_TEX_SIZE_0 0x1d04 /* NPOT */
+#define RADEON_PP_TEX_SIZE_0 0x1d04 /* NPOT */
#define RADEON_PP_TEX_SIZE_1 0x1d0c
#define RADEON_PP_TEX_SIZE_2 0x1d14
@@ -849,7 +884,7 @@ extern int r300_do_cp_cmdbuf(drm_device_t* dev, DRMFILE filp,
#define SE_VTX_FMT_0__VTX_COLOR_0_FMT__SHIFT 0x0000000b
#define R200_3D_DRAW_IMMD_2 0xC0003500
#define R200_SE_VTX_FMT_1 0x208c
-#define R200_RE_CNTL 0x1c50
+#define R200_RE_CNTL 0x1c50
#define R200_RB3D_BLENDCOLOR 0x3218
@@ -857,6 +892,9 @@ extern int r300_do_cp_cmdbuf(drm_device_t* dev, DRMFILE filp,
#define R200_PP_TRI_PERF 0x2cf8
+#define R200_PP_AFS_0 0x2f80
+#define R200_PP_AFS_1 0x2f00 /* same as txcblend_0 */
+
/* Constants */
#define RADEON_MAX_USEC_TIMEOUT 100000 /* 100 ms */
@@ -871,6 +909,8 @@ extern int r300_do_cp_cmdbuf(drm_device_t* dev, DRMFILE filp,
#define RADEON_RING_HIGH_MARK 128
+#define RADEON_PCIGART_TABLE_SIZE (32*1024)
+
#define RADEON_READ(reg) DRM_READ32( dev_priv->mmio, (reg) )
#define RADEON_WRITE(reg,val) DRM_WRITE32( dev_priv->mmio, (reg), (val) )
#define RADEON_READ8(reg) DRM_READ8( dev_priv->mmio, (reg) )
@@ -883,6 +923,13 @@ do { \
RADEON_WRITE( RADEON_CLOCK_CNTL_DATA, (val) ); \
} while (0)
+#define RADEON_WRITE_PCIE( addr, val ) \
+do { \
+ RADEON_WRITE8( RADEON_PCIE_INDEX, \
+ ((addr) & 0xff)); \
+ RADEON_WRITE( RADEON_PCIE_DATA, (val) ); \
+} while (0)
+
#define CP_PACKET0( reg, n ) \
(RADEON_CP_PACKET0 | ((n) << 16) | ((reg) >> 2))
#define CP_PACKET0_TABLE( reg, n ) \
@@ -894,7 +941,6 @@ do { \
#define CP_PACKET3( pkt, n ) \
(RADEON_CP_PACKET3 | (pkt) | ((n) << 16))
-
/* ================================================================
* Engine control helper macros
*/
@@ -943,12 +989,11 @@ do { \
OUT_RING( RADEON_RB3D_ZC_FLUSH_ALL ); \
} while (0)
-
/* ================================================================
* Misc helper macros
*/
-/* Perfbox functionality only.
+/* Perfbox functionality only.
*/
#define RING_SPACE_TEST_WITH_RETURN( dev_priv ) \
do { \
@@ -985,7 +1030,6 @@ do { \
OUT_RING( age ); \
} while (0)
-
/* ================================================================
* Ring control
*/
@@ -1046,7 +1090,6 @@ do { \
OUT_RING( val ); \
} while (0)
-
#define OUT_RING_TABLE( tab, sz ) do { \
int _size = (sz); \
int *_tab = (int *)(tab); \
@@ -1071,5 +1114,4 @@ do { \
write &= mask; \
} while (0)
-
-#endif /* __RADEON_DRV_H__ */
+#endif /* __RADEON_DRV_H__ */
diff --git a/drivers/char/drm/radeon_ioc32.c b/drivers/char/drm/radeon_ioc32.c
index bfe612215fb3..fef4a2b84c1e 100644
--- a/drivers/char/drm/radeon_ioc32.c
+++ b/drivers/char/drm/radeon_ioc32.c
@@ -94,7 +94,7 @@ static int compat_radeon_cp_init(struct file *file, unsigned int cmd,
return -EFAULT;
return drm_ioctl(file->f_dentry->d_inode, file,
- DRM_IOCTL_RADEON_CP_INIT, (unsigned long) init);
+ DRM_IOCTL_RADEON_CP_INIT, (unsigned long)init);
}
typedef struct drm_radeon_clear32 {
@@ -102,8 +102,8 @@ typedef struct drm_radeon_clear32 {
unsigned int clear_color;
unsigned int clear_depth;
unsigned int color_mask;
- unsigned int depth_mask; /* misnamed field: should be stencil */
- u32 depth_boxes;
+ unsigned int depth_mask; /* misnamed field: should be stencil */
+ u32 depth_boxes;
} drm_radeon_clear32_t;
static int compat_radeon_cp_clear(struct file *file, unsigned int cmd,
@@ -127,7 +127,7 @@ static int compat_radeon_cp_clear(struct file *file, unsigned int cmd,
return -EFAULT;
return drm_ioctl(file->f_dentry->d_inode, file,
- DRM_IOCTL_RADEON_CLEAR, (unsigned long) clr);
+ DRM_IOCTL_RADEON_CLEAR, (unsigned long)clr);
}
typedef struct drm_radeon_stipple32 {
@@ -137,7 +137,7 @@ typedef struct drm_radeon_stipple32 {
static int compat_radeon_cp_stipple(struct file *file, unsigned int cmd,
unsigned long arg)
{
- drm_radeon_stipple32_t __user *argp = (void __user *) arg;
+ drm_radeon_stipple32_t __user *argp = (void __user *)arg;
drm_radeon_stipple_t __user *request;
u32 mask;
@@ -146,16 +146,16 @@ static int compat_radeon_cp_stipple(struct file *file, unsigned int cmd,
request = compat_alloc_user_space(sizeof(*request));
if (!access_ok(VERIFY_WRITE, request, sizeof(*request))
- || __put_user((unsigned int __user *)(unsigned long) mask,
+ || __put_user((unsigned int __user *)(unsigned long)mask,
&request->mask))
return -EFAULT;
return drm_ioctl(file->f_dentry->d_inode, file,
- DRM_IOCTL_RADEON_STIPPLE, (unsigned long) request);
+ DRM_IOCTL_RADEON_STIPPLE, (unsigned long)request);
}
typedef struct drm_radeon_tex_image32 {
- unsigned int x, y; /* Blit coordinates */
+ unsigned int x, y; /* Blit coordinates */
unsigned int width, height;
u32 data;
} drm_radeon_tex_image32_t;
@@ -164,7 +164,7 @@ typedef struct drm_radeon_texture32 {
unsigned int offset;
int pitch;
int format;
- int width; /* Texture image coordinates */
+ int width; /* Texture image coordinates */
int height;
u32 image;
} drm_radeon_texture32_t;
@@ -177,7 +177,7 @@ static int compat_radeon_cp_texture(struct file *file, unsigned int cmd,
drm_radeon_tex_image32_t img32;
drm_radeon_tex_image_t __user *image;
- if (copy_from_user(&req32, (void __user *) arg, sizeof(req32)))
+ if (copy_from_user(&req32, (void __user *)arg, sizeof(req32)))
return -EFAULT;
if (req32.image == 0)
return -EINVAL;
@@ -206,12 +206,12 @@ static int compat_radeon_cp_texture(struct file *file, unsigned int cmd,
return -EFAULT;
return drm_ioctl(file->f_dentry->d_inode, file,
- DRM_IOCTL_RADEON_TEXTURE, (unsigned long) request);
+ DRM_IOCTL_RADEON_TEXTURE, (unsigned long)request);
}
typedef struct drm_radeon_vertex2_32 {
- int idx; /* Index of vertex buffer */
- int discard; /* Client finished with buffer? */
+ int idx; /* Index of vertex buffer */
+ int discard; /* Client finished with buffer? */
int nr_states;
u32 state;
int nr_prims;
@@ -224,7 +224,7 @@ static int compat_radeon_cp_vertex2(struct file *file, unsigned int cmd,
drm_radeon_vertex2_32_t req32;
drm_radeon_vertex2_t __user *request;
- if (copy_from_user(&req32, (void __user *) arg, sizeof(req32)))
+ if (copy_from_user(&req32, (void __user *)arg, sizeof(req32)))
return -EFAULT;
request = compat_alloc_user_space(sizeof(*request));
@@ -240,7 +240,7 @@ static int compat_radeon_cp_vertex2(struct file *file, unsigned int cmd,
return -EFAULT;
return drm_ioctl(file->f_dentry->d_inode, file,
- DRM_IOCTL_RADEON_VERTEX2, (unsigned long) request);
+ DRM_IOCTL_RADEON_VERTEX2, (unsigned long)request);
}
typedef struct drm_radeon_cmd_buffer32 {
@@ -256,7 +256,7 @@ static int compat_radeon_cp_cmdbuf(struct file *file, unsigned int cmd,
drm_radeon_cmd_buffer32_t req32;
drm_radeon_cmd_buffer_t __user *request;
- if (copy_from_user(&req32, (void __user *) arg, sizeof(req32)))
+ if (copy_from_user(&req32, (void __user *)arg, sizeof(req32)))
return -EFAULT;
request = compat_alloc_user_space(sizeof(*request));
@@ -270,7 +270,7 @@ static int compat_radeon_cp_cmdbuf(struct file *file, unsigned int cmd,
return -EFAULT;
return drm_ioctl(file->f_dentry->d_inode, file,
- DRM_IOCTL_RADEON_CMDBUF, (unsigned long) request);
+ DRM_IOCTL_RADEON_CMDBUF, (unsigned long)request);
}
typedef struct drm_radeon_getparam32 {
@@ -284,7 +284,7 @@ static int compat_radeon_cp_getparam(struct file *file, unsigned int cmd,
drm_radeon_getparam32_t req32;
drm_radeon_getparam_t __user *request;
- if (copy_from_user(&req32, (void __user *) arg, sizeof(req32)))
+ if (copy_from_user(&req32, (void __user *)arg, sizeof(req32)))
return -EFAULT;
request = compat_alloc_user_space(sizeof(*request));
@@ -295,7 +295,7 @@ static int compat_radeon_cp_getparam(struct file *file, unsigned int cmd,
return -EFAULT;
return drm_ioctl(file->f_dentry->d_inode, file,
- DRM_IOCTL_RADEON_GETPARAM, (unsigned long) request);
+ DRM_IOCTL_RADEON_GETPARAM, (unsigned long)request);
}
typedef struct drm_radeon_mem_alloc32 {
@@ -311,7 +311,7 @@ static int compat_radeon_mem_alloc(struct file *file, unsigned int cmd,
drm_radeon_mem_alloc32_t req32;
drm_radeon_mem_alloc_t __user *request;
- if (copy_from_user(&req32, (void __user *) arg, sizeof(req32)))
+ if (copy_from_user(&req32, (void __user *)arg, sizeof(req32)))
return -EFAULT;
request = compat_alloc_user_space(sizeof(*request));
@@ -324,7 +324,7 @@ static int compat_radeon_mem_alloc(struct file *file, unsigned int cmd,
return -EFAULT;
return drm_ioctl(file->f_dentry->d_inode, file,
- DRM_IOCTL_RADEON_ALLOC, (unsigned long) request);
+ DRM_IOCTL_RADEON_ALLOC, (unsigned long)request);
}
typedef struct drm_radeon_irq_emit32 {
@@ -337,7 +337,7 @@ static int compat_radeon_irq_emit(struct file *file, unsigned int cmd,
drm_radeon_irq_emit32_t req32;
drm_radeon_irq_emit_t __user *request;
- if (copy_from_user(&req32, (void __user *) arg, sizeof(req32)))
+ if (copy_from_user(&req32, (void __user *)arg, sizeof(req32)))
return -EFAULT;
request = compat_alloc_user_space(sizeof(*request));
@@ -347,7 +347,7 @@ static int compat_radeon_irq_emit(struct file *file, unsigned int cmd,
return -EFAULT;
return drm_ioctl(file->f_dentry->d_inode, file,
- DRM_IOCTL_RADEON_IRQ_EMIT, (unsigned long) request);
+ DRM_IOCTL_RADEON_IRQ_EMIT, (unsigned long)request);
}
drm_ioctl_compat_t *radeon_compat_ioctls[] = {
@@ -371,8 +371,7 @@ drm_ioctl_compat_t *radeon_compat_ioctls[] = {
* \param arg user argument.
* \return zero on success or negative number on failure.
*/
-long radeon_compat_ioctl(struct file *filp, unsigned int cmd,
- unsigned long arg)
+long radeon_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
unsigned int nr = DRM_IOCTL_NR(cmd);
drm_ioctl_compat_t *fn = NULL;
@@ -386,7 +385,7 @@ long radeon_compat_ioctl(struct file *filp, unsigned int cmd,
lock_kernel(); /* XXX for now */
if (fn != NULL)
- ret = (*fn)(filp, cmd, arg);
+ ret = (*fn) (filp, cmd, arg);
else
ret = drm_ioctl(filp->f_dentry->d_inode, filp, cmd, arg);
unlock_kernel();
diff --git a/drivers/char/drm/radeon_irq.c b/drivers/char/drm/radeon_irq.c
index 40474a65f56d..d60519de887b 100644
--- a/drivers/char/drm/radeon_irq.c
+++ b/drivers/char/drm/radeon_irq.c
@@ -1,7 +1,7 @@
/* radeon_irq.c -- IRQ handling for radeon -*- linux-c -*-
*
* Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
- *
+ *
* The Weather Channel (TM) funded Tungsten Graphics to develop the
* initial release of the Radeon 8500 driver under the XFree86 license.
* This notice must be preserved.
@@ -35,7 +35,8 @@
#include "radeon_drm.h"
#include "radeon_drv.h"
-static __inline__ u32 radeon_acknowledge_irqs(drm_radeon_private_t *dev_priv, u32 mask)
+static __inline__ u32 radeon_acknowledge_irqs(drm_radeon_private_t * dev_priv,
+ u32 mask)
{
u32 irqs = RADEON_READ(RADEON_GEN_INT_STATUS) & mask;
if (irqs)
@@ -61,37 +62,37 @@ static __inline__ u32 radeon_acknowledge_irqs(drm_radeon_private_t *dev_priv, u3
* tied to dma at all, this is just a hangover from dri prehistory.
*/
-irqreturn_t radeon_driver_irq_handler( DRM_IRQ_ARGS )
+irqreturn_t radeon_driver_irq_handler(DRM_IRQ_ARGS)
{
drm_device_t *dev = (drm_device_t *) arg;
- drm_radeon_private_t *dev_priv =
- (drm_radeon_private_t *)dev->dev_private;
- u32 stat;
+ drm_radeon_private_t *dev_priv =
+ (drm_radeon_private_t *) dev->dev_private;
+ u32 stat;
/* Only consider the bits we're interested in - others could be used
* outside the DRM
*/
- stat = radeon_acknowledge_irqs(dev_priv, (RADEON_SW_INT_TEST_ACK |
+ stat = radeon_acknowledge_irqs(dev_priv, (RADEON_SW_INT_TEST_ACK |
RADEON_CRTC_VBLANK_STAT));
if (!stat)
return IRQ_NONE;
/* SW interrupt */
if (stat & RADEON_SW_INT_TEST) {
- DRM_WAKEUP( &dev_priv->swi_queue );
+ DRM_WAKEUP(&dev_priv->swi_queue);
}
/* VBLANK interrupt */
if (stat & RADEON_CRTC_VBLANK_STAT) {
atomic_inc(&dev->vbl_received);
DRM_WAKEUP(&dev->vbl_queue);
- drm_vbl_send_signals( dev );
+ drm_vbl_send_signals(dev);
}
return IRQ_HANDLED;
}
-static int radeon_emit_irq(drm_device_t *dev)
+static int radeon_emit_irq(drm_device_t * dev)
{
drm_radeon_private_t *dev_priv = dev->dev_private;
unsigned int ret;
@@ -100,42 +101,41 @@ static int radeon_emit_irq(drm_device_t *dev)
atomic_inc(&dev_priv->swi_emitted);
ret = atomic_read(&dev_priv->swi_emitted);
- BEGIN_RING( 4 );
- OUT_RING_REG( RADEON_LAST_SWI_REG, ret );
- OUT_RING_REG( RADEON_GEN_INT_STATUS, RADEON_SW_INT_FIRE );
- ADVANCE_RING();
- COMMIT_RING();
+ BEGIN_RING(4);
+ OUT_RING_REG(RADEON_LAST_SWI_REG, ret);
+ OUT_RING_REG(RADEON_GEN_INT_STATUS, RADEON_SW_INT_FIRE);
+ ADVANCE_RING();
+ COMMIT_RING();
return ret;
}
-
-static int radeon_wait_irq(drm_device_t *dev, int swi_nr)
+static int radeon_wait_irq(drm_device_t * dev, int swi_nr)
{
- drm_radeon_private_t *dev_priv =
- (drm_radeon_private_t *)dev->dev_private;
+ drm_radeon_private_t *dev_priv =
+ (drm_radeon_private_t *) dev->dev_private;
int ret = 0;
- if (RADEON_READ( RADEON_LAST_SWI_REG ) >= swi_nr)
- return 0;
+ if (RADEON_READ(RADEON_LAST_SWI_REG) >= swi_nr)
+ return 0;
dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE;
- DRM_WAIT_ON( ret, dev_priv->swi_queue, 3 * DRM_HZ,
- RADEON_READ( RADEON_LAST_SWI_REG ) >= swi_nr );
+ DRM_WAIT_ON(ret, dev_priv->swi_queue, 3 * DRM_HZ,
+ RADEON_READ(RADEON_LAST_SWI_REG) >= swi_nr);
return ret;
}
-int radeon_driver_vblank_wait(drm_device_t *dev, unsigned int *sequence)
+int radeon_driver_vblank_wait(drm_device_t * dev, unsigned int *sequence)
{
- drm_radeon_private_t *dev_priv =
- (drm_radeon_private_t *)dev->dev_private;
+ drm_radeon_private_t *dev_priv =
+ (drm_radeon_private_t *) dev->dev_private;
unsigned int cur_vblank;
int ret = 0;
- if ( !dev_priv ) {
- DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
+ if (!dev_priv) {
+ DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
return DRM_ERR(EINVAL);
}
@@ -145,101 +145,100 @@ int radeon_driver_vblank_wait(drm_device_t *dev, unsigned int *sequence)
/* Assume that the user has missed the current sequence number
* by about a day rather than she wants to wait for years
- * using vertical blanks...
+ * using vertical blanks...
*/
- DRM_WAIT_ON( ret, dev->vbl_queue, 3*DRM_HZ,
- ( ( ( cur_vblank = atomic_read(&dev->vbl_received ) )
- - *sequence ) <= (1<<23) ) );
+ DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ,
+ (((cur_vblank = atomic_read(&dev->vbl_received))
+ - *sequence) <= (1 << 23)));
*sequence = cur_vblank;
return ret;
}
-
/* Needs the lock as it touches the ring.
*/
-int radeon_irq_emit( DRM_IOCTL_ARGS )
+int radeon_irq_emit(DRM_IOCTL_ARGS)
{
DRM_DEVICE;
drm_radeon_private_t *dev_priv = dev->dev_private;
drm_radeon_irq_emit_t emit;
int result;
- LOCK_TEST_WITH_RETURN( dev, filp );
+ LOCK_TEST_WITH_RETURN(dev, filp);
- if ( !dev_priv ) {
- DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
+ if (!dev_priv) {
+ DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
return DRM_ERR(EINVAL);
}
- DRM_COPY_FROM_USER_IOCTL( emit, (drm_radeon_irq_emit_t __user *)data,
- sizeof(emit) );
+ DRM_COPY_FROM_USER_IOCTL(emit, (drm_radeon_irq_emit_t __user *) data,
+ sizeof(emit));
- result = radeon_emit_irq( dev );
+ result = radeon_emit_irq(dev);
- if ( DRM_COPY_TO_USER( emit.irq_seq, &result, sizeof(int) ) ) {
- DRM_ERROR( "copy_to_user\n" );
+ if (DRM_COPY_TO_USER(emit.irq_seq, &result, sizeof(int))) {
+ DRM_ERROR("copy_to_user\n");
return DRM_ERR(EFAULT);
}
return 0;
}
-
/* Doesn't need the hardware lock.
*/
-int radeon_irq_wait( DRM_IOCTL_ARGS )
+int radeon_irq_wait(DRM_IOCTL_ARGS)
{
DRM_DEVICE;
drm_radeon_private_t *dev_priv = dev->dev_private;
drm_radeon_irq_wait_t irqwait;
- if ( !dev_priv ) {
- DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
+ if (!dev_priv) {
+ DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
return DRM_ERR(EINVAL);
}
- DRM_COPY_FROM_USER_IOCTL( irqwait, (drm_radeon_irq_wait_t __user*)data,
- sizeof(irqwait) );
+ DRM_COPY_FROM_USER_IOCTL(irqwait, (drm_radeon_irq_wait_t __user *) data,
+ sizeof(irqwait));
- return radeon_wait_irq( dev, irqwait.irq_seq );
+ return radeon_wait_irq(dev, irqwait.irq_seq);
}
-
/* drm_dma.h hooks
*/
-void radeon_driver_irq_preinstall( drm_device_t *dev ) {
+void radeon_driver_irq_preinstall(drm_device_t * dev)
+{
drm_radeon_private_t *dev_priv =
- (drm_radeon_private_t *)dev->dev_private;
+ (drm_radeon_private_t *) dev->dev_private;
- /* Disable *all* interrupts */
- RADEON_WRITE( RADEON_GEN_INT_CNTL, 0 );
+ /* Disable *all* interrupts */
+ RADEON_WRITE(RADEON_GEN_INT_CNTL, 0);
/* Clear bits if they're already high */
radeon_acknowledge_irqs(dev_priv, (RADEON_SW_INT_TEST_ACK |
RADEON_CRTC_VBLANK_STAT));
}
-void radeon_driver_irq_postinstall( drm_device_t *dev ) {
+void radeon_driver_irq_postinstall(drm_device_t * dev)
+{
drm_radeon_private_t *dev_priv =
- (drm_radeon_private_t *)dev->dev_private;
+ (drm_radeon_private_t *) dev->dev_private;
- atomic_set(&dev_priv->swi_emitted, 0);
- DRM_INIT_WAITQUEUE( &dev_priv->swi_queue );
+ atomic_set(&dev_priv->swi_emitted, 0);
+ DRM_INIT_WAITQUEUE(&dev_priv->swi_queue);
/* Turn on SW and VBL ints */
- RADEON_WRITE( RADEON_GEN_INT_CNTL,
- RADEON_CRTC_VBLANK_MASK |
- RADEON_SW_INT_ENABLE );
+ RADEON_WRITE(RADEON_GEN_INT_CNTL,
+ RADEON_CRTC_VBLANK_MASK | RADEON_SW_INT_ENABLE);
}
-void radeon_driver_irq_uninstall( drm_device_t *dev ) {
+void radeon_driver_irq_uninstall(drm_device_t * dev)
+{
drm_radeon_private_t *dev_priv =
- (drm_radeon_private_t *)dev->dev_private;
+ (drm_radeon_private_t *) dev->dev_private;
if (!dev_priv)
return;
/* Disable *all* interrupts */
- RADEON_WRITE( RADEON_GEN_INT_CNTL, 0 );
+ RADEON_WRITE(RADEON_GEN_INT_CNTL, 0);
}
diff --git a/drivers/char/drm/radeon_mem.c b/drivers/char/drm/radeon_mem.c
index 134f894e6e4b..030a6fad0d86 100644
--- a/drivers/char/drm/radeon_mem.c
+++ b/drivers/char/drm/radeon_mem.c
@@ -1,7 +1,7 @@
/* radeon_mem.c -- Simple GART/fb memory manager for radeon -*- linux-c -*-
*
* Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
- *
+ *
* The Weather Channel (TM) funded Tungsten Graphics to develop the
* initial release of the Radeon 8500 driver under the XFree86 license.
* This notice must be preserved.
@@ -35,16 +35,17 @@
#include "radeon_drv.h"
/* Very simple allocator for GART memory, working on a static range
- * already mapped into each client's address space.
+ * already mapped into each client's address space.
*/
static struct mem_block *split_block(struct mem_block *p, int start, int size,
- DRMFILE filp )
+ DRMFILE filp)
{
/* Maybe cut off the start of an existing block */
if (start > p->start) {
- struct mem_block *newblock = drm_alloc(sizeof(*newblock), DRM_MEM_BUFS );
- if (!newblock)
+ struct mem_block *newblock =
+ drm_alloc(sizeof(*newblock), DRM_MEM_BUFS);
+ if (!newblock)
goto out;
newblock->start = start;
newblock->size = p->size - (start - p->start);
@@ -56,10 +57,11 @@ static struct mem_block *split_block(struct mem_block *p, int start, int size,
p->size -= newblock->size;
p = newblock;
}
-
+
/* Maybe cut off the end of an existing block */
if (size < p->size) {
- struct mem_block *newblock = drm_alloc(sizeof(*newblock), DRM_MEM_BUFS );
+ struct mem_block *newblock =
+ drm_alloc(sizeof(*newblock), DRM_MEM_BUFS);
if (!newblock)
goto out;
newblock->start = start + size;
@@ -72,40 +74,39 @@ static struct mem_block *split_block(struct mem_block *p, int start, int size,
p->size = size;
}
- out:
+ out:
/* Our block is in the middle */
p->filp = filp;
return p;
}
-static struct mem_block *alloc_block( struct mem_block *heap, int size,
- int align2, DRMFILE filp )
+static struct mem_block *alloc_block(struct mem_block *heap, int size,
+ int align2, DRMFILE filp)
{
struct mem_block *p;
- int mask = (1 << align2)-1;
+ int mask = (1 << align2) - 1;
list_for_each(p, heap) {
int start = (p->start + mask) & ~mask;
if (p->filp == 0 && start + size <= p->start + p->size)
- return split_block( p, start, size, filp );
+ return split_block(p, start, size, filp);
}
return NULL;
}
-static struct mem_block *find_block( struct mem_block *heap, int start )
+static struct mem_block *find_block(struct mem_block *heap, int start)
{
struct mem_block *p;
list_for_each(p, heap)
- if (p->start == start)
- return p;
+ if (p->start == start)
+ return p;
return NULL;
}
-
-static void free_block( struct mem_block *p )
+static void free_block(struct mem_block *p)
{
p->filp = NULL;
@@ -117,7 +118,7 @@ static void free_block( struct mem_block *p )
p->size += q->size;
p->next = q->next;
p->next->prev = p;
- drm_free(q, sizeof(*q), DRM_MEM_BUFS );
+ drm_free(q, sizeof(*q), DRM_MEM_BUFS);
}
if (p->prev->filp == 0) {
@@ -125,7 +126,7 @@ static void free_block( struct mem_block *p )
q->size += p->size;
q->next = p->next;
q->next->prev = q;
- drm_free(p, sizeof(*q), DRM_MEM_BUFS );
+ drm_free(p, sizeof(*q), DRM_MEM_BUFS);
}
}
@@ -133,14 +134,14 @@ static void free_block( struct mem_block *p )
*/
static int init_heap(struct mem_block **heap, int start, int size)
{
- struct mem_block *blocks = drm_alloc(sizeof(*blocks), DRM_MEM_BUFS );
+ struct mem_block *blocks = drm_alloc(sizeof(*blocks), DRM_MEM_BUFS);
- if (!blocks)
+ if (!blocks)
return DRM_ERR(ENOMEM);
-
- *heap = drm_alloc(sizeof(**heap), DRM_MEM_BUFS );
+
+ *heap = drm_alloc(sizeof(**heap), DRM_MEM_BUFS);
if (!*heap) {
- drm_free( blocks, sizeof(*blocks), DRM_MEM_BUFS );
+ drm_free(blocks, sizeof(*blocks), DRM_MEM_BUFS);
return DRM_ERR(ENOMEM);
}
@@ -149,16 +150,15 @@ static int init_heap(struct mem_block **heap, int start, int size)
blocks->filp = NULL;
blocks->next = blocks->prev = *heap;
- memset( *heap, 0, sizeof(**heap) );
- (*heap)->filp = (DRMFILE) -1;
+ memset(*heap, 0, sizeof(**heap));
+ (*heap)->filp = (DRMFILE) - 1;
(*heap)->next = (*heap)->prev = blocks;
return 0;
}
-
/* Free all blocks associated with the releasing file.
*/
-void radeon_mem_release( DRMFILE filp, struct mem_block *heap )
+void radeon_mem_release(DRMFILE filp, struct mem_block *heap)
{
struct mem_block *p;
@@ -166,7 +166,7 @@ void radeon_mem_release( DRMFILE filp, struct mem_block *heap )
return;
list_for_each(p, heap) {
- if (p->filp == filp)
+ if (p->filp == filp)
p->filp = NULL;
}
@@ -179,40 +179,37 @@ void radeon_mem_release( DRMFILE filp, struct mem_block *heap )
p->size += q->size;
p->next = q->next;
p->next->prev = p;
- drm_free(q, sizeof(*q),DRM_MEM_DRIVER);
+ drm_free(q, sizeof(*q), DRM_MEM_DRIVER);
}
}
}
/* Shutdown.
*/
-void radeon_mem_takedown( struct mem_block **heap )
+void radeon_mem_takedown(struct mem_block **heap)
{
struct mem_block *p;
-
+
if (!*heap)
return;
- for (p = (*heap)->next ; p != *heap ; ) {
+ for (p = (*heap)->next; p != *heap;) {
struct mem_block *q = p;
p = p->next;
- drm_free(q, sizeof(*q),DRM_MEM_DRIVER);
+ drm_free(q, sizeof(*q), DRM_MEM_DRIVER);
}
- drm_free( *heap, sizeof(**heap),DRM_MEM_DRIVER );
+ drm_free(*heap, sizeof(**heap), DRM_MEM_DRIVER);
*heap = NULL;
}
-
-
/* IOCTL HANDLERS */
-static struct mem_block **get_heap( drm_radeon_private_t *dev_priv,
- int region )
+static struct mem_block **get_heap(drm_radeon_private_t * dev_priv, int region)
{
- switch( region ) {
+ switch (region) {
case RADEON_MEM_REGION_GART:
- return &dev_priv->gart_heap;
+ return &dev_priv->gart_heap;
case RADEON_MEM_REGION_FB:
return &dev_priv->fb_heap;
default:
@@ -220,103 +217,98 @@ static struct mem_block **get_heap( drm_radeon_private_t *dev_priv,
}
}
-int radeon_mem_alloc( DRM_IOCTL_ARGS )
+int radeon_mem_alloc(DRM_IOCTL_ARGS)
{
DRM_DEVICE;
drm_radeon_private_t *dev_priv = dev->dev_private;
drm_radeon_mem_alloc_t alloc;
struct mem_block *block, **heap;
- if ( !dev_priv ) {
- DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
+ if (!dev_priv) {
+ DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
return DRM_ERR(EINVAL);
}
- DRM_COPY_FROM_USER_IOCTL( alloc, (drm_radeon_mem_alloc_t __user *)data,
- sizeof(alloc) );
+ DRM_COPY_FROM_USER_IOCTL(alloc, (drm_radeon_mem_alloc_t __user *) data,
+ sizeof(alloc));
- heap = get_heap( dev_priv, alloc.region );
+ heap = get_heap(dev_priv, alloc.region);
if (!heap || !*heap)
return DRM_ERR(EFAULT);
-
+
/* Make things easier on ourselves: all allocations at least
* 4k aligned.
*/
if (alloc.alignment < 12)
alloc.alignment = 12;
- block = alloc_block( *heap, alloc.size, alloc.alignment,
- filp );
+ block = alloc_block(*heap, alloc.size, alloc.alignment, filp);
- if (!block)
+ if (!block)
return DRM_ERR(ENOMEM);
- if ( DRM_COPY_TO_USER( alloc.region_offset, &block->start,
- sizeof(int) ) ) {
- DRM_ERROR( "copy_to_user\n" );
+ if (DRM_COPY_TO_USER(alloc.region_offset, &block->start, sizeof(int))) {
+ DRM_ERROR("copy_to_user\n");
return DRM_ERR(EFAULT);
}
-
+
return 0;
}
-
-
-int radeon_mem_free( DRM_IOCTL_ARGS )
+int radeon_mem_free(DRM_IOCTL_ARGS)
{
DRM_DEVICE;
drm_radeon_private_t *dev_priv = dev->dev_private;
drm_radeon_mem_free_t memfree;
struct mem_block *block, **heap;
- if ( !dev_priv ) {
- DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
+ if (!dev_priv) {
+ DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
return DRM_ERR(EINVAL);
}
- DRM_COPY_FROM_USER_IOCTL( memfree, (drm_radeon_mem_free_t __user *)data,
- sizeof(memfree) );
+ DRM_COPY_FROM_USER_IOCTL(memfree, (drm_radeon_mem_free_t __user *) data,
+ sizeof(memfree));
- heap = get_heap( dev_priv, memfree.region );
+ heap = get_heap(dev_priv, memfree.region);
if (!heap || !*heap)
return DRM_ERR(EFAULT);
-
- block = find_block( *heap, memfree.region_offset );
+
+ block = find_block(*heap, memfree.region_offset);
if (!block)
return DRM_ERR(EFAULT);
if (block->filp != filp)
return DRM_ERR(EPERM);
- free_block( block );
+ free_block(block);
return 0;
}
-int radeon_mem_init_heap( DRM_IOCTL_ARGS )
+int radeon_mem_init_heap(DRM_IOCTL_ARGS)
{
DRM_DEVICE;
drm_radeon_private_t *dev_priv = dev->dev_private;
drm_radeon_mem_init_heap_t initheap;
struct mem_block **heap;
- if ( !dev_priv ) {
- DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
+ if (!dev_priv) {
+ DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
return DRM_ERR(EINVAL);
}
- DRM_COPY_FROM_USER_IOCTL( initheap, (drm_radeon_mem_init_heap_t __user *)data,
- sizeof(initheap) );
+ DRM_COPY_FROM_USER_IOCTL(initheap,
+ (drm_radeon_mem_init_heap_t __user *) data,
+ sizeof(initheap));
- heap = get_heap( dev_priv, initheap.region );
- if (!heap)
+ heap = get_heap(dev_priv, initheap.region);
+ if (!heap)
return DRM_ERR(EFAULT);
-
+
if (*heap) {
DRM_ERROR("heap already initialized?");
return DRM_ERR(EFAULT);
}
-
- return init_heap( heap, initheap.start, initheap.size );
-}
-
+ return init_heap(heap, initheap.start, initheap.size);
+}
diff --git a/drivers/char/drm/radeon_state.c b/drivers/char/drm/radeon_state.c
index 64a3e3a406ef..231ac1438c69 100644
--- a/drivers/char/drm/radeon_state.c
+++ b/drivers/char/drm/radeon_state.c
@@ -37,51 +37,58 @@
* Helper functions for client state checking and fixup
*/
-static __inline__ int radeon_check_and_fixup_offset( drm_radeon_private_t *dev_priv,
- drm_file_t *filp_priv,
- u32 *offset ) {
+static __inline__ int radeon_check_and_fixup_offset(drm_radeon_private_t *
+ dev_priv,
+ drm_file_t * filp_priv,
+ u32 *offset)
+{
u32 off = *offset;
struct drm_radeon_driver_file_fields *radeon_priv;
- if ( off >= dev_priv->fb_location &&
- off < ( dev_priv->gart_vm_start + dev_priv->gart_size ) )
+ if (off >= dev_priv->fb_location &&
+ off < (dev_priv->gart_vm_start + dev_priv->gart_size))
return 0;
radeon_priv = filp_priv->driver_priv;
off += radeon_priv->radeon_fb_delta;
- DRM_DEBUG( "offset fixed up to 0x%x\n", off );
+ DRM_DEBUG("offset fixed up to 0x%x\n", off);
- if ( off < dev_priv->fb_location ||
- off >= ( dev_priv->gart_vm_start + dev_priv->gart_size ) )
- return DRM_ERR( EINVAL );
+ if (off < dev_priv->fb_location ||
+ off >= (dev_priv->gart_vm_start + dev_priv->gart_size))
+ return DRM_ERR(EINVAL);
*offset = off;
return 0;
}
-static __inline__ int radeon_check_and_fixup_packets( drm_radeon_private_t *dev_priv,
- drm_file_t *filp_priv,
- int id,
- u32 __user *data ) {
- switch ( id ) {
+static __inline__ int radeon_check_and_fixup_packets(drm_radeon_private_t *
+ dev_priv,
+ drm_file_t * filp_priv,
+ int id, u32 *data)
+{
+ switch (id) {
case RADEON_EMIT_PP_MISC:
- if ( radeon_check_and_fixup_offset( dev_priv, filp_priv,
- &data[( RADEON_RB3D_DEPTHOFFSET
- - RADEON_PP_MISC ) / 4] ) ) {
- DRM_ERROR( "Invalid depth buffer offset\n" );
- return DRM_ERR( EINVAL );
+ if (radeon_check_and_fixup_offset(dev_priv, filp_priv,
+ &data[(RADEON_RB3D_DEPTHOFFSET
+ -
+ RADEON_PP_MISC) /
+ 4])) {
+ DRM_ERROR("Invalid depth buffer offset\n");
+ return DRM_ERR(EINVAL);
}
break;
case RADEON_EMIT_PP_CNTL:
- if ( radeon_check_and_fixup_offset( dev_priv, filp_priv,
- &data[( RADEON_RB3D_COLOROFFSET
- - RADEON_PP_CNTL ) / 4] ) ) {
- DRM_ERROR( "Invalid colour buffer offset\n" );
- return DRM_ERR( EINVAL );
+ if (radeon_check_and_fixup_offset(dev_priv, filp_priv,
+ &data[(RADEON_RB3D_COLOROFFSET
+ -
+ RADEON_PP_CNTL) /
+ 4])) {
+ DRM_ERROR("Invalid colour buffer offset\n");
+ return DRM_ERR(EINVAL);
}
break;
@@ -91,21 +98,23 @@ static __inline__ int radeon_check_and_fixup_packets( drm_radeon_private_t *dev_
case R200_EMIT_PP_TXOFFSET_3:
case R200_EMIT_PP_TXOFFSET_4:
case R200_EMIT_PP_TXOFFSET_5:
- if ( radeon_check_and_fixup_offset( dev_priv, filp_priv,
- &data[0] ) ) {
- DRM_ERROR( "Invalid R200 texture offset\n" );
- return DRM_ERR( EINVAL );
+ if (radeon_check_and_fixup_offset(dev_priv, filp_priv,
+ &data[0])) {
+ DRM_ERROR("Invalid R200 texture offset\n");
+ return DRM_ERR(EINVAL);
}
break;
case RADEON_EMIT_PP_TXFILTER_0:
case RADEON_EMIT_PP_TXFILTER_1:
case RADEON_EMIT_PP_TXFILTER_2:
- if ( radeon_check_and_fixup_offset( dev_priv, filp_priv,
- &data[( RADEON_PP_TXOFFSET_0
- - RADEON_PP_TXFILTER_0 ) / 4] ) ) {
- DRM_ERROR( "Invalid R100 texture offset\n" );
- return DRM_ERR( EINVAL );
+ if (radeon_check_and_fixup_offset(dev_priv, filp_priv,
+ &data[(RADEON_PP_TXOFFSET_0
+ -
+ RADEON_PP_TXFILTER_0) /
+ 4])) {
+ DRM_ERROR("Invalid R100 texture offset\n");
+ return DRM_ERR(EINVAL);
}
break;
@@ -114,17 +123,18 @@ static __inline__ int radeon_check_and_fixup_packets( drm_radeon_private_t *dev_
case R200_EMIT_PP_CUBIC_OFFSETS_2:
case R200_EMIT_PP_CUBIC_OFFSETS_3:
case R200_EMIT_PP_CUBIC_OFFSETS_4:
- case R200_EMIT_PP_CUBIC_OFFSETS_5: {
- int i;
- for ( i = 0; i < 5; i++ ) {
- if ( radeon_check_and_fixup_offset( dev_priv, filp_priv,
- &data[i] ) ) {
- DRM_ERROR( "Invalid R200 cubic texture offset\n" );
- return DRM_ERR( EINVAL );
+ case R200_EMIT_PP_CUBIC_OFFSETS_5:{
+ int i;
+ for (i = 0; i < 5; i++) {
+ if (radeon_check_and_fixup_offset
+ (dev_priv, filp_priv, &data[i])) {
+ DRM_ERROR
+ ("Invalid R200 cubic texture offset\n");
+ return DRM_ERR(EINVAL);
+ }
}
+ break;
}
- break;
- }
case RADEON_EMIT_PP_CUBIC_OFFSETS_T0:
case RADEON_EMIT_PP_CUBIC_OFFSETS_T1:
@@ -207,247 +217,259 @@ static __inline__ int radeon_check_and_fixup_packets( drm_radeon_private_t *dev_
case RADEON_EMIT_PP_CUBIC_FACES_1:
case RADEON_EMIT_PP_CUBIC_FACES_2:
case R200_EMIT_PP_TRI_PERF_CNTL:
+ case R200_EMIT_PP_AFS_0:
+ case R200_EMIT_PP_AFS_1:
+ case R200_EMIT_ATF_TFACTOR:
+ case R200_EMIT_PP_TXCTLALL_0:
+ case R200_EMIT_PP_TXCTLALL_1:
+ case R200_EMIT_PP_TXCTLALL_2:
+ case R200_EMIT_PP_TXCTLALL_3:
+ case R200_EMIT_PP_TXCTLALL_4:
+ case R200_EMIT_PP_TXCTLALL_5:
/* These packets don't contain memory offsets */
break;
default:
- DRM_ERROR( "Unknown state packet ID %d\n", id );
- return DRM_ERR( EINVAL );
+ DRM_ERROR("Unknown state packet ID %d\n", id);
+ return DRM_ERR(EINVAL);
}
return 0;
}
-static __inline__ int radeon_check_and_fixup_packet3( drm_radeon_private_t *dev_priv,
- drm_file_t *filp_priv,
- drm_radeon_cmd_buffer_t *cmdbuf,
- unsigned int *cmdsz ) {
+static __inline__ int radeon_check_and_fixup_packet3(drm_radeon_private_t *
+ dev_priv,
+ drm_file_t * filp_priv,
+ drm_radeon_kcmd_buffer_t *cmdbuf,
+ unsigned int *cmdsz)
+{
u32 *cmd = (u32 *) cmdbuf->buf;
- *cmdsz = 2 + ( ( cmd[0] & RADEON_CP_PACKET_COUNT_MASK ) >> 16 );
+ *cmdsz = 2 + ((cmd[0] & RADEON_CP_PACKET_COUNT_MASK) >> 16);
- if ( ( cmd[0] & 0xc0000000 ) != RADEON_CP_PACKET3 ) {
- DRM_ERROR( "Not a type 3 packet\n" );
- return DRM_ERR( EINVAL );
+ if ((cmd[0] & 0xc0000000) != RADEON_CP_PACKET3) {
+ DRM_ERROR("Not a type 3 packet\n");
+ return DRM_ERR(EINVAL);
}
- if ( 4 * *cmdsz > cmdbuf->bufsz ) {
- DRM_ERROR( "Packet size larger than size of data provided\n" );
- return DRM_ERR( EINVAL );
+ if (4 * *cmdsz > cmdbuf->bufsz) {
+ DRM_ERROR("Packet size larger than size of data provided\n");
+ return DRM_ERR(EINVAL);
}
/* Check client state and fix it up if necessary */
- if ( cmd[0] & 0x8000 ) { /* MSB of opcode: next DWORD GUI_CNTL */
+ if (cmd[0] & 0x8000) { /* MSB of opcode: next DWORD GUI_CNTL */
u32 offset;
- if ( cmd[1] & ( RADEON_GMC_SRC_PITCH_OFFSET_CNTL
- | RADEON_GMC_DST_PITCH_OFFSET_CNTL ) ) {
+ if (cmd[1] & (RADEON_GMC_SRC_PITCH_OFFSET_CNTL
+ | RADEON_GMC_DST_PITCH_OFFSET_CNTL)) {
offset = cmd[2] << 10;
- if ( radeon_check_and_fixup_offset( dev_priv, filp_priv, &offset ) ) {
- DRM_ERROR( "Invalid first packet offset\n" );
- return DRM_ERR( EINVAL );
+ if (radeon_check_and_fixup_offset
+ (dev_priv, filp_priv, &offset)) {
+ DRM_ERROR("Invalid first packet offset\n");
+ return DRM_ERR(EINVAL);
}
- cmd[2] = ( cmd[2] & 0xffc00000 ) | offset >> 10;
+ cmd[2] = (cmd[2] & 0xffc00000) | offset >> 10;
}
- if ( ( cmd[1] & RADEON_GMC_SRC_PITCH_OFFSET_CNTL ) &&
- ( cmd[1] & RADEON_GMC_DST_PITCH_OFFSET_CNTL ) ) {
+ if ((cmd[1] & RADEON_GMC_SRC_PITCH_OFFSET_CNTL) &&
+ (cmd[1] & RADEON_GMC_DST_PITCH_OFFSET_CNTL)) {
offset = cmd[3] << 10;
- if ( radeon_check_and_fixup_offset( dev_priv, filp_priv, &offset ) ) {
- DRM_ERROR( "Invalid second packet offset\n" );
- return DRM_ERR( EINVAL );
+ if (radeon_check_and_fixup_offset
+ (dev_priv, filp_priv, &offset)) {
+ DRM_ERROR("Invalid second packet offset\n");
+ return DRM_ERR(EINVAL);
}
- cmd[3] = ( cmd[3] & 0xffc00000 ) | offset >> 10;
+ cmd[3] = (cmd[3] & 0xffc00000) | offset >> 10;
}
}
return 0;
}
-
/* ================================================================
* CP hardware state programming functions
*/
-static __inline__ void radeon_emit_clip_rect( drm_radeon_private_t *dev_priv,
- drm_clip_rect_t *box )
+static __inline__ void radeon_emit_clip_rect(drm_radeon_private_t * dev_priv,
+ drm_clip_rect_t * box)
{
RING_LOCALS;
- DRM_DEBUG( " box: x1=%d y1=%d x2=%d y2=%d\n",
- box->x1, box->y1, box->x2, box->y2 );
+ DRM_DEBUG(" box: x1=%d y1=%d x2=%d y2=%d\n",
+ box->x1, box->y1, box->x2, box->y2);
- BEGIN_RING( 4 );
- OUT_RING( CP_PACKET0( RADEON_RE_TOP_LEFT, 0 ) );
- OUT_RING( (box->y1 << 16) | box->x1 );
- OUT_RING( CP_PACKET0( RADEON_RE_WIDTH_HEIGHT, 0 ) );
- OUT_RING( ((box->y2 - 1) << 16) | (box->x2 - 1) );
+ BEGIN_RING(4);
+ OUT_RING(CP_PACKET0(RADEON_RE_TOP_LEFT, 0));
+ OUT_RING((box->y1 << 16) | box->x1);
+ OUT_RING(CP_PACKET0(RADEON_RE_WIDTH_HEIGHT, 0));
+ OUT_RING(((box->y2 - 1) << 16) | (box->x2 - 1));
ADVANCE_RING();
}
/* Emit 1.1 state
*/
-static int radeon_emit_state( drm_radeon_private_t *dev_priv,
- drm_file_t *filp_priv,
- drm_radeon_context_regs_t *ctx,
- drm_radeon_texture_regs_t *tex,
- unsigned int dirty )
+static int radeon_emit_state(drm_radeon_private_t * dev_priv,
+ drm_file_t * filp_priv,
+ drm_radeon_context_regs_t * ctx,
+ drm_radeon_texture_regs_t * tex,
+ unsigned int dirty)
{
RING_LOCALS;
- DRM_DEBUG( "dirty=0x%08x\n", dirty );
+ DRM_DEBUG("dirty=0x%08x\n", dirty);
- if ( dirty & RADEON_UPLOAD_CONTEXT ) {
- if ( radeon_check_and_fixup_offset( dev_priv, filp_priv,
- &ctx->rb3d_depthoffset ) ) {
- DRM_ERROR( "Invalid depth buffer offset\n" );
- return DRM_ERR( EINVAL );
+ if (dirty & RADEON_UPLOAD_CONTEXT) {
+ if (radeon_check_and_fixup_offset(dev_priv, filp_priv,
+ &ctx->rb3d_depthoffset)) {
+ DRM_ERROR("Invalid depth buffer offset\n");
+ return DRM_ERR(EINVAL);
}
- if ( radeon_check_and_fixup_offset( dev_priv, filp_priv,
- &ctx->rb3d_coloroffset ) ) {
- DRM_ERROR( "Invalid depth buffer offset\n" );
- return DRM_ERR( EINVAL );
+ if (radeon_check_and_fixup_offset(dev_priv, filp_priv,
+ &ctx->rb3d_coloroffset)) {
+ DRM_ERROR("Invalid depth buffer offset\n");
+ return DRM_ERR(EINVAL);
}
- BEGIN_RING( 14 );
- OUT_RING( CP_PACKET0( RADEON_PP_MISC, 6 ) );
- OUT_RING( ctx->pp_misc );
- OUT_RING( ctx->pp_fog_color );
- OUT_RING( ctx->re_solid_color );
- OUT_RING( ctx->rb3d_blendcntl );
- OUT_RING( ctx->rb3d_depthoffset );
- OUT_RING( ctx->rb3d_depthpitch );
- OUT_RING( ctx->rb3d_zstencilcntl );
- OUT_RING( CP_PACKET0( RADEON_PP_CNTL, 2 ) );
- OUT_RING( ctx->pp_cntl );
- OUT_RING( ctx->rb3d_cntl );
- OUT_RING( ctx->rb3d_coloroffset );
- OUT_RING( CP_PACKET0( RADEON_RB3D_COLORPITCH, 0 ) );
- OUT_RING( ctx->rb3d_colorpitch );
+ BEGIN_RING(14);
+ OUT_RING(CP_PACKET0(RADEON_PP_MISC, 6));
+ OUT_RING(ctx->pp_misc);
+ OUT_RING(ctx->pp_fog_color);
+ OUT_RING(ctx->re_solid_color);
+ OUT_RING(ctx->rb3d_blendcntl);
+ OUT_RING(ctx->rb3d_depthoffset);
+ OUT_RING(ctx->rb3d_depthpitch);
+ OUT_RING(ctx->rb3d_zstencilcntl);
+ OUT_RING(CP_PACKET0(RADEON_PP_CNTL, 2));
+ OUT_RING(ctx->pp_cntl);
+ OUT_RING(ctx->rb3d_cntl);
+ OUT_RING(ctx->rb3d_coloroffset);
+ OUT_RING(CP_PACKET0(RADEON_RB3D_COLORPITCH, 0));
+ OUT_RING(ctx->rb3d_colorpitch);
ADVANCE_RING();
}
- if ( dirty & RADEON_UPLOAD_VERTFMT ) {
- BEGIN_RING( 2 );
- OUT_RING( CP_PACKET0( RADEON_SE_COORD_FMT, 0 ) );
- OUT_RING( ctx->se_coord_fmt );
+ if (dirty & RADEON_UPLOAD_VERTFMT) {
+ BEGIN_RING(2);
+ OUT_RING(CP_PACKET0(RADEON_SE_COORD_FMT, 0));
+ OUT_RING(ctx->se_coord_fmt);
ADVANCE_RING();
}
- if ( dirty & RADEON_UPLOAD_LINE ) {
- BEGIN_RING( 5 );
- OUT_RING( CP_PACKET0( RADEON_RE_LINE_PATTERN, 1 ) );
- OUT_RING( ctx->re_line_pattern );
- OUT_RING( ctx->re_line_state );
- OUT_RING( CP_PACKET0( RADEON_SE_LINE_WIDTH, 0 ) );
- OUT_RING( ctx->se_line_width );
+ if (dirty & RADEON_UPLOAD_LINE) {
+ BEGIN_RING(5);
+ OUT_RING(CP_PACKET0(RADEON_RE_LINE_PATTERN, 1));
+ OUT_RING(ctx->re_line_pattern);
+ OUT_RING(ctx->re_line_state);
+ OUT_RING(CP_PACKET0(RADEON_SE_LINE_WIDTH, 0));
+ OUT_RING(ctx->se_line_width);
ADVANCE_RING();
}
- if ( dirty & RADEON_UPLOAD_BUMPMAP ) {
- BEGIN_RING( 5 );
- OUT_RING( CP_PACKET0( RADEON_PP_LUM_MATRIX, 0 ) );
- OUT_RING( ctx->pp_lum_matrix );
- OUT_RING( CP_PACKET0( RADEON_PP_ROT_MATRIX_0, 1 ) );
- OUT_RING( ctx->pp_rot_matrix_0 );
- OUT_RING( ctx->pp_rot_matrix_1 );
+ if (dirty & RADEON_UPLOAD_BUMPMAP) {
+ BEGIN_RING(5);
+ OUT_RING(CP_PACKET0(RADEON_PP_LUM_MATRIX, 0));
+ OUT_RING(ctx->pp_lum_matrix);
+ OUT_RING(CP_PACKET0(RADEON_PP_ROT_MATRIX_0, 1));
+ OUT_RING(ctx->pp_rot_matrix_0);
+ OUT_RING(ctx->pp_rot_matrix_1);
ADVANCE_RING();
}
- if ( dirty & RADEON_UPLOAD_MASKS ) {
- BEGIN_RING( 4 );
- OUT_RING( CP_PACKET0( RADEON_RB3D_STENCILREFMASK, 2 ) );
- OUT_RING( ctx->rb3d_stencilrefmask );
- OUT_RING( ctx->rb3d_ropcntl );
- OUT_RING( ctx->rb3d_planemask );
+ if (dirty & RADEON_UPLOAD_MASKS) {
+ BEGIN_RING(4);
+ OUT_RING(CP_PACKET0(RADEON_RB3D_STENCILREFMASK, 2));
+ OUT_RING(ctx->rb3d_stencilrefmask);
+ OUT_RING(ctx->rb3d_ropcntl);
+ OUT_RING(ctx->rb3d_planemask);
ADVANCE_RING();
}
- if ( dirty & RADEON_UPLOAD_VIEWPORT ) {
- BEGIN_RING( 7 );
- OUT_RING( CP_PACKET0( RADEON_SE_VPORT_XSCALE, 5 ) );
- OUT_RING( ctx->se_vport_xscale );
- OUT_RING( ctx->se_vport_xoffset );
- OUT_RING( ctx->se_vport_yscale );
- OUT_RING( ctx->se_vport_yoffset );
- OUT_RING( ctx->se_vport_zscale );
- OUT_RING( ctx->se_vport_zoffset );
+ if (dirty & RADEON_UPLOAD_VIEWPORT) {
+ BEGIN_RING(7);
+ OUT_RING(CP_PACKET0(RADEON_SE_VPORT_XSCALE, 5));
+ OUT_RING(ctx->se_vport_xscale);
+ OUT_RING(ctx->se_vport_xoffset);
+ OUT_RING(ctx->se_vport_yscale);
+ OUT_RING(ctx->se_vport_yoffset);
+ OUT_RING(ctx->se_vport_zscale);
+ OUT_RING(ctx->se_vport_zoffset);
ADVANCE_RING();
}
- if ( dirty & RADEON_UPLOAD_SETUP ) {
- BEGIN_RING( 4 );
- OUT_RING( CP_PACKET0( RADEON_SE_CNTL, 0 ) );
- OUT_RING( ctx->se_cntl );
- OUT_RING( CP_PACKET0( RADEON_SE_CNTL_STATUS, 0 ) );
- OUT_RING( ctx->se_cntl_status );
+ if (dirty & RADEON_UPLOAD_SETUP) {
+ BEGIN_RING(4);
+ OUT_RING(CP_PACKET0(RADEON_SE_CNTL, 0));
+ OUT_RING(ctx->se_cntl);
+ OUT_RING(CP_PACKET0(RADEON_SE_CNTL_STATUS, 0));
+ OUT_RING(ctx->se_cntl_status);
ADVANCE_RING();
}
- if ( dirty & RADEON_UPLOAD_MISC ) {
- BEGIN_RING( 2 );
- OUT_RING( CP_PACKET0( RADEON_RE_MISC, 0 ) );
- OUT_RING( ctx->re_misc );
+ if (dirty & RADEON_UPLOAD_MISC) {
+ BEGIN_RING(2);
+ OUT_RING(CP_PACKET0(RADEON_RE_MISC, 0));
+ OUT_RING(ctx->re_misc);
ADVANCE_RING();
}
- if ( dirty & RADEON_UPLOAD_TEX0 ) {
- if ( radeon_check_and_fixup_offset( dev_priv, filp_priv,
- &tex[0].pp_txoffset ) ) {
- DRM_ERROR( "Invalid texture offset for unit 0\n" );
- return DRM_ERR( EINVAL );
+ if (dirty & RADEON_UPLOAD_TEX0) {
+ if (radeon_check_and_fixup_offset(dev_priv, filp_priv,
+ &tex[0].pp_txoffset)) {
+ DRM_ERROR("Invalid texture offset for unit 0\n");
+ return DRM_ERR(EINVAL);
}
- BEGIN_RING( 9 );
- OUT_RING( CP_PACKET0( RADEON_PP_TXFILTER_0, 5 ) );
- OUT_RING( tex[0].pp_txfilter );
- OUT_RING( tex[0].pp_txformat );
- OUT_RING( tex[0].pp_txoffset );
- OUT_RING( tex[0].pp_txcblend );
- OUT_RING( tex[0].pp_txablend );
- OUT_RING( tex[0].pp_tfactor );
- OUT_RING( CP_PACKET0( RADEON_PP_BORDER_COLOR_0, 0 ) );
- OUT_RING( tex[0].pp_border_color );
+ BEGIN_RING(9);
+ OUT_RING(CP_PACKET0(RADEON_PP_TXFILTER_0, 5));
+ OUT_RING(tex[0].pp_txfilter);
+ OUT_RING(tex[0].pp_txformat);
+ OUT_RING(tex[0].pp_txoffset);
+ OUT_RING(tex[0].pp_txcblend);
+ OUT_RING(tex[0].pp_txablend);
+ OUT_RING(tex[0].pp_tfactor);
+ OUT_RING(CP_PACKET0(RADEON_PP_BORDER_COLOR_0, 0));
+ OUT_RING(tex[0].pp_border_color);
ADVANCE_RING();
}
- if ( dirty & RADEON_UPLOAD_TEX1 ) {
- if ( radeon_check_and_fixup_offset( dev_priv, filp_priv,
- &tex[1].pp_txoffset ) ) {
- DRM_ERROR( "Invalid texture offset for unit 1\n" );
- return DRM_ERR( EINVAL );
+ if (dirty & RADEON_UPLOAD_TEX1) {
+ if (radeon_check_and_fixup_offset(dev_priv, filp_priv,
+ &tex[1].pp_txoffset)) {
+ DRM_ERROR("Invalid texture offset for unit 1\n");
+ return DRM_ERR(EINVAL);
}
- BEGIN_RING( 9 );
- OUT_RING( CP_PACKET0( RADEON_PP_TXFILTER_1, 5 ) );
- OUT_RING( tex[1].pp_txfilter );
- OUT_RING( tex[1].pp_txformat );
- OUT_RING( tex[1].pp_txoffset );
- OUT_RING( tex[1].pp_txcblend );
- OUT_RING( tex[1].pp_txablend );
- OUT_RING( tex[1].pp_tfactor );
- OUT_RING( CP_PACKET0( RADEON_PP_BORDER_COLOR_1, 0 ) );
- OUT_RING( tex[1].pp_border_color );
+ BEGIN_RING(9);
+ OUT_RING(CP_PACKET0(RADEON_PP_TXFILTER_1, 5));
+ OUT_RING(tex[1].pp_txfilter);
+ OUT_RING(tex[1].pp_txformat);
+ OUT_RING(tex[1].pp_txoffset);
+ OUT_RING(tex[1].pp_txcblend);
+ OUT_RING(tex[1].pp_txablend);
+ OUT_RING(tex[1].pp_tfactor);
+ OUT_RING(CP_PACKET0(RADEON_PP_BORDER_COLOR_1, 0));
+ OUT_RING(tex[1].pp_border_color);
ADVANCE_RING();
}
- if ( dirty & RADEON_UPLOAD_TEX2 ) {
- if ( radeon_check_and_fixup_offset( dev_priv, filp_priv,
- &tex[2].pp_txoffset ) ) {
- DRM_ERROR( "Invalid texture offset for unit 2\n" );
- return DRM_ERR( EINVAL );
+ if (dirty & RADEON_UPLOAD_TEX2) {
+ if (radeon_check_and_fixup_offset(dev_priv, filp_priv,
+ &tex[2].pp_txoffset)) {
+ DRM_ERROR("Invalid texture offset for unit 2\n");
+ return DRM_ERR(EINVAL);
}
- BEGIN_RING( 9 );
- OUT_RING( CP_PACKET0( RADEON_PP_TXFILTER_2, 5 ) );
- OUT_RING( tex[2].pp_txfilter );
- OUT_RING( tex[2].pp_txformat );
- OUT_RING( tex[2].pp_txoffset );
- OUT_RING( tex[2].pp_txcblend );
- OUT_RING( tex[2].pp_txablend );
- OUT_RING( tex[2].pp_tfactor );
- OUT_RING( CP_PACKET0( RADEON_PP_BORDER_COLOR_2, 0 ) );
- OUT_RING( tex[2].pp_border_color );
+ BEGIN_RING(9);
+ OUT_RING(CP_PACKET0(RADEON_PP_TXFILTER_2, 5));
+ OUT_RING(tex[2].pp_txfilter);
+ OUT_RING(tex[2].pp_txformat);
+ OUT_RING(tex[2].pp_txoffset);
+ OUT_RING(tex[2].pp_txcblend);
+ OUT_RING(tex[2].pp_txablend);
+ OUT_RING(tex[2].pp_tfactor);
+ OUT_RING(CP_PACKET0(RADEON_PP_BORDER_COLOR_2, 0));
+ OUT_RING(tex[2].pp_border_color);
ADVANCE_RING();
}
@@ -456,129 +478,137 @@ static int radeon_emit_state( drm_radeon_private_t *dev_priv,
/* Emit 1.2 state
*/
-static int radeon_emit_state2( drm_radeon_private_t *dev_priv,
- drm_file_t *filp_priv,
- drm_radeon_state_t *state )
+static int radeon_emit_state2(drm_radeon_private_t * dev_priv,
+ drm_file_t * filp_priv,
+ drm_radeon_state_t * state)
{
RING_LOCALS;
if (state->dirty & RADEON_UPLOAD_ZBIAS) {
- BEGIN_RING( 3 );
- OUT_RING( CP_PACKET0( RADEON_SE_ZBIAS_FACTOR, 1 ) );
- OUT_RING( state->context2.se_zbias_factor );
- OUT_RING( state->context2.se_zbias_constant );
+ BEGIN_RING(3);
+ OUT_RING(CP_PACKET0(RADEON_SE_ZBIAS_FACTOR, 1));
+ OUT_RING(state->context2.se_zbias_factor);
+ OUT_RING(state->context2.se_zbias_constant);
ADVANCE_RING();
}
- return radeon_emit_state( dev_priv, filp_priv, &state->context,
- state->tex, state->dirty );
+ return radeon_emit_state(dev_priv, filp_priv, &state->context,
+ state->tex, state->dirty);
}
/* New (1.3) state mechanism. 3 commands (packet, scalar, vector) in
* 1.3 cmdbuffers allow all previous state to be updated as well as
- * the tcl scalar and vector areas.
+ * the tcl scalar and vector areas.
*/
-static struct {
- int start;
- int len;
+static struct {
+ int start;
+ int len;
const char *name;
} packet[RADEON_MAX_STATE_PACKETS] = {
- { RADEON_PP_MISC,7,"RADEON_PP_MISC" },
- { RADEON_PP_CNTL,3,"RADEON_PP_CNTL" },
- { RADEON_RB3D_COLORPITCH,1,"RADEON_RB3D_COLORPITCH" },
- { RADEON_RE_LINE_PATTERN,2,"RADEON_RE_LINE_PATTERN" },
- { RADEON_SE_LINE_WIDTH,1,"RADEON_SE_LINE_WIDTH" },
- { RADEON_PP_LUM_MATRIX,1,"RADEON_PP_LUM_MATRIX" },
- { RADEON_PP_ROT_MATRIX_0,2,"RADEON_PP_ROT_MATRIX_0" },
- { RADEON_RB3D_STENCILREFMASK,3,"RADEON_RB3D_STENCILREFMASK" },
- { RADEON_SE_VPORT_XSCALE,6,"RADEON_SE_VPORT_XSCALE" },
- { RADEON_SE_CNTL,2,"RADEON_SE_CNTL" },
- { RADEON_SE_CNTL_STATUS,1,"RADEON_SE_CNTL_STATUS" },
- { RADEON_RE_MISC,1,"RADEON_RE_MISC" },
- { RADEON_PP_TXFILTER_0,6,"RADEON_PP_TXFILTER_0" },
- { RADEON_PP_BORDER_COLOR_0,1,"RADEON_PP_BORDER_COLOR_0" },
- { RADEON_PP_TXFILTER_1,6,"RADEON_PP_TXFILTER_1" },
- { RADEON_PP_BORDER_COLOR_1,1,"RADEON_PP_BORDER_COLOR_1" },
- { RADEON_PP_TXFILTER_2,6,"RADEON_PP_TXFILTER_2" },
- { RADEON_PP_BORDER_COLOR_2,1,"RADEON_PP_BORDER_COLOR_2" },
- { RADEON_SE_ZBIAS_FACTOR,2,"RADEON_SE_ZBIAS_FACTOR" },
- { RADEON_SE_TCL_OUTPUT_VTX_FMT,11,"RADEON_SE_TCL_OUTPUT_VTX_FMT" },
- { RADEON_SE_TCL_MATERIAL_EMMISSIVE_RED,17,"RADEON_SE_TCL_MATERIAL_EMMISSIVE_RED" },
- { R200_PP_TXCBLEND_0, 4, "R200_PP_TXCBLEND_0" },
- { R200_PP_TXCBLEND_1, 4, "R200_PP_TXCBLEND_1" },
- { R200_PP_TXCBLEND_2, 4, "R200_PP_TXCBLEND_2" },
- { R200_PP_TXCBLEND_3, 4, "R200_PP_TXCBLEND_3" },
- { R200_PP_TXCBLEND_4, 4, "R200_PP_TXCBLEND_4" },
- { R200_PP_TXCBLEND_5, 4, "R200_PP_TXCBLEND_5" },
- { R200_PP_TXCBLEND_6, 4, "R200_PP_TXCBLEND_6" },
- { R200_PP_TXCBLEND_7, 4, "R200_PP_TXCBLEND_7" },
- { R200_SE_TCL_LIGHT_MODEL_CTL_0, 6, "R200_SE_TCL_LIGHT_MODEL_CTL_0" },
- { R200_PP_TFACTOR_0, 6, "R200_PP_TFACTOR_0" },
- { R200_SE_VTX_FMT_0, 4, "R200_SE_VTX_FMT_0" },
- { R200_SE_VAP_CNTL, 1, "R200_SE_VAP_CNTL" },
- { R200_SE_TCL_MATRIX_SEL_0, 5, "R200_SE_TCL_MATRIX_SEL_0" },
- { R200_SE_TCL_TEX_PROC_CTL_2, 5, "R200_SE_TCL_TEX_PROC_CTL_2" },
- { R200_SE_TCL_UCP_VERT_BLEND_CTL, 1, "R200_SE_TCL_UCP_VERT_BLEND_CTL" },
- { R200_PP_TXFILTER_0, 6, "R200_PP_TXFILTER_0" },
- { R200_PP_TXFILTER_1, 6, "R200_PP_TXFILTER_1" },
- { R200_PP_TXFILTER_2, 6, "R200_PP_TXFILTER_2" },
- { R200_PP_TXFILTER_3, 6, "R200_PP_TXFILTER_3" },
- { R200_PP_TXFILTER_4, 6, "R200_PP_TXFILTER_4" },
- { R200_PP_TXFILTER_5, 6, "R200_PP_TXFILTER_5" },
- { R200_PP_TXOFFSET_0, 1, "R200_PP_TXOFFSET_0" },
- { R200_PP_TXOFFSET_1, 1, "R200_PP_TXOFFSET_1" },
- { R200_PP_TXOFFSET_2, 1, "R200_PP_TXOFFSET_2" },
- { R200_PP_TXOFFSET_3, 1, "R200_PP_TXOFFSET_3" },
- { R200_PP_TXOFFSET_4, 1, "R200_PP_TXOFFSET_4" },
- { R200_PP_TXOFFSET_5, 1, "R200_PP_TXOFFSET_5" },
- { R200_SE_VTE_CNTL, 1, "R200_SE_VTE_CNTL" },
- { R200_SE_TCL_OUTPUT_VTX_COMP_SEL, 1, "R200_SE_TCL_OUTPUT_VTX_COMP_SEL" },
- { R200_PP_TAM_DEBUG3, 1, "R200_PP_TAM_DEBUG3" },
- { R200_PP_CNTL_X, 1, "R200_PP_CNTL_X" },
- { R200_RB3D_DEPTHXY_OFFSET, 1, "R200_RB3D_DEPTHXY_OFFSET" },
- { R200_RE_AUX_SCISSOR_CNTL, 1, "R200_RE_AUX_SCISSOR_CNTL" },
- { R200_RE_SCISSOR_TL_0, 2, "R200_RE_SCISSOR_TL_0" },
- { R200_RE_SCISSOR_TL_1, 2, "R200_RE_SCISSOR_TL_1" },
- { R200_RE_SCISSOR_TL_2, 2, "R200_RE_SCISSOR_TL_2" },
- { R200_SE_VAP_CNTL_STATUS, 1, "R200_SE_VAP_CNTL_STATUS" },
- { R200_SE_VTX_STATE_CNTL, 1, "R200_SE_VTX_STATE_CNTL" },
- { R200_RE_POINTSIZE, 1, "R200_RE_POINTSIZE" },
- { R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_0, 4, "R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_0" },
- { R200_PP_CUBIC_FACES_0, 1, "R200_PP_CUBIC_FACES_0" }, /* 61 */
- { R200_PP_CUBIC_OFFSET_F1_0, 5, "R200_PP_CUBIC_OFFSET_F1_0" }, /* 62 */
- { R200_PP_CUBIC_FACES_1, 1, "R200_PP_CUBIC_FACES_1" },
- { R200_PP_CUBIC_OFFSET_F1_1, 5, "R200_PP_CUBIC_OFFSET_F1_1" },
- { R200_PP_CUBIC_FACES_2, 1, "R200_PP_CUBIC_FACES_2" },
- { R200_PP_CUBIC_OFFSET_F1_2, 5, "R200_PP_CUBIC_OFFSET_F1_2" },
- { R200_PP_CUBIC_FACES_3, 1, "R200_PP_CUBIC_FACES_3" },
- { R200_PP_CUBIC_OFFSET_F1_3, 5, "R200_PP_CUBIC_OFFSET_F1_3" },
- { R200_PP_CUBIC_FACES_4, 1, "R200_PP_CUBIC_FACES_4" },
- { R200_PP_CUBIC_OFFSET_F1_4, 5, "R200_PP_CUBIC_OFFSET_F1_4" },
- { R200_PP_CUBIC_FACES_5, 1, "R200_PP_CUBIC_FACES_5" },
- { R200_PP_CUBIC_OFFSET_F1_5, 5, "R200_PP_CUBIC_OFFSET_F1_5" },
- { RADEON_PP_TEX_SIZE_0, 2, "RADEON_PP_TEX_SIZE_0" },
- { RADEON_PP_TEX_SIZE_1, 2, "RADEON_PP_TEX_SIZE_1" },
- { RADEON_PP_TEX_SIZE_2, 2, "RADEON_PP_TEX_SIZE_2" },
- { R200_RB3D_BLENDCOLOR, 3, "R200_RB3D_BLENDCOLOR" },
- { R200_SE_TCL_POINT_SPRITE_CNTL, 1, "R200_SE_TCL_POINT_SPRITE_CNTL" },
- { RADEON_PP_CUBIC_FACES_0, 1, "RADEON_PP_CUBIC_FACES_0"},
- { RADEON_PP_CUBIC_OFFSET_T0_0, 5, "RADEON_PP_CUBIC_OFFSET_T0_0"},
- { RADEON_PP_CUBIC_FACES_1, 1, "RADEON_PP_CUBIC_FACES_1"},
- { RADEON_PP_CUBIC_OFFSET_T1_0, 5, "RADEON_PP_CUBIC_OFFSET_T1_0"},
- { RADEON_PP_CUBIC_FACES_2, 1, "RADEON_PP_CUBIC_FACES_2"},
- { RADEON_PP_CUBIC_OFFSET_T2_0, 5, "RADEON_PP_CUBIC_OFFSET_T2_0"},
- { R200_PP_TRI_PERF, 2, "R200_PP_TRI_PERF"},
+ {RADEON_PP_MISC, 7, "RADEON_PP_MISC"},
+ {RADEON_PP_CNTL, 3, "RADEON_PP_CNTL"},
+ {RADEON_RB3D_COLORPITCH, 1, "RADEON_RB3D_COLORPITCH"},
+ {RADEON_RE_LINE_PATTERN, 2, "RADEON_RE_LINE_PATTERN"},
+ {RADEON_SE_LINE_WIDTH, 1, "RADEON_SE_LINE_WIDTH"},
+ {RADEON_PP_LUM_MATRIX, 1, "RADEON_PP_LUM_MATRIX"},
+ {RADEON_PP_ROT_MATRIX_0, 2, "RADEON_PP_ROT_MATRIX_0"},
+ {RADEON_RB3D_STENCILREFMASK, 3, "RADEON_RB3D_STENCILREFMASK"},
+ {RADEON_SE_VPORT_XSCALE, 6, "RADEON_SE_VPORT_XSCALE"},
+ {RADEON_SE_CNTL, 2, "RADEON_SE_CNTL"},
+ {RADEON_SE_CNTL_STATUS, 1, "RADEON_SE_CNTL_STATUS"},
+ {RADEON_RE_MISC, 1, "RADEON_RE_MISC"},
+ {RADEON_PP_TXFILTER_0, 6, "RADEON_PP_TXFILTER_0"},
+ {RADEON_PP_BORDER_COLOR_0, 1, "RADEON_PP_BORDER_COLOR_0"},
+ {RADEON_PP_TXFILTER_1, 6, "RADEON_PP_TXFILTER_1"},
+ {RADEON_PP_BORDER_COLOR_1, 1, "RADEON_PP_BORDER_COLOR_1"},
+ {RADEON_PP_TXFILTER_2, 6, "RADEON_PP_TXFILTER_2"},
+ {RADEON_PP_BORDER_COLOR_2, 1, "RADEON_PP_BORDER_COLOR_2"},
+ {RADEON_SE_ZBIAS_FACTOR, 2, "RADEON_SE_ZBIAS_FACTOR"},
+ {RADEON_SE_TCL_OUTPUT_VTX_FMT, 11, "RADEON_SE_TCL_OUTPUT_VTX_FMT"},
+ {RADEON_SE_TCL_MATERIAL_EMMISSIVE_RED, 17,
+ "RADEON_SE_TCL_MATERIAL_EMMISSIVE_RED"},
+ {R200_PP_TXCBLEND_0, 4, "R200_PP_TXCBLEND_0"},
+ {R200_PP_TXCBLEND_1, 4, "R200_PP_TXCBLEND_1"},
+ {R200_PP_TXCBLEND_2, 4, "R200_PP_TXCBLEND_2"},
+ {R200_PP_TXCBLEND_3, 4, "R200_PP_TXCBLEND_3"},
+ {R200_PP_TXCBLEND_4, 4, "R200_PP_TXCBLEND_4"},
+ {R200_PP_TXCBLEND_5, 4, "R200_PP_TXCBLEND_5"},
+ {R200_PP_TXCBLEND_6, 4, "R200_PP_TXCBLEND_6"},
+ {R200_PP_TXCBLEND_7, 4, "R200_PP_TXCBLEND_7"},
+ {R200_SE_TCL_LIGHT_MODEL_CTL_0, 6, "R200_SE_TCL_LIGHT_MODEL_CTL_0"},
+ {R200_PP_TFACTOR_0, 6, "R200_PP_TFACTOR_0"},
+ {R200_SE_VTX_FMT_0, 4, "R200_SE_VTX_FMT_0"},
+ {R200_SE_VAP_CNTL, 1, "R200_SE_VAP_CNTL"},
+ {R200_SE_TCL_MATRIX_SEL_0, 5, "R200_SE_TCL_MATRIX_SEL_0"},
+ {R200_SE_TCL_TEX_PROC_CTL_2, 5, "R200_SE_TCL_TEX_PROC_CTL_2"},
+ {R200_SE_TCL_UCP_VERT_BLEND_CTL, 1, "R200_SE_TCL_UCP_VERT_BLEND_CTL"},
+ {R200_PP_TXFILTER_0, 6, "R200_PP_TXFILTER_0"},
+ {R200_PP_TXFILTER_1, 6, "R200_PP_TXFILTER_1"},
+ {R200_PP_TXFILTER_2, 6, "R200_PP_TXFILTER_2"},
+ {R200_PP_TXFILTER_3, 6, "R200_PP_TXFILTER_3"},
+ {R200_PP_TXFILTER_4, 6, "R200_PP_TXFILTER_4"},
+ {R200_PP_TXFILTER_5, 6, "R200_PP_TXFILTER_5"},
+ {R200_PP_TXOFFSET_0, 1, "R200_PP_TXOFFSET_0"},
+ {R200_PP_TXOFFSET_1, 1, "R200_PP_TXOFFSET_1"},
+ {R200_PP_TXOFFSET_2, 1, "R200_PP_TXOFFSET_2"},
+ {R200_PP_TXOFFSET_3, 1, "R200_PP_TXOFFSET_3"},
+ {R200_PP_TXOFFSET_4, 1, "R200_PP_TXOFFSET_4"},
+ {R200_PP_TXOFFSET_5, 1, "R200_PP_TXOFFSET_5"},
+ {R200_SE_VTE_CNTL, 1, "R200_SE_VTE_CNTL"},
+ {R200_SE_TCL_OUTPUT_VTX_COMP_SEL, 1, "R200_SE_TCL_OUTPUT_VTX_COMP_SEL"},
+ {R200_PP_TAM_DEBUG3, 1, "R200_PP_TAM_DEBUG3"},
+ {R200_PP_CNTL_X, 1, "R200_PP_CNTL_X"},
+ {R200_RB3D_DEPTHXY_OFFSET, 1, "R200_RB3D_DEPTHXY_OFFSET"},
+ {R200_RE_AUX_SCISSOR_CNTL, 1, "R200_RE_AUX_SCISSOR_CNTL"},
+ {R200_RE_SCISSOR_TL_0, 2, "R200_RE_SCISSOR_TL_0"},
+ {R200_RE_SCISSOR_TL_1, 2, "R200_RE_SCISSOR_TL_1"},
+ {R200_RE_SCISSOR_TL_2, 2, "R200_RE_SCISSOR_TL_2"},
+ {R200_SE_VAP_CNTL_STATUS, 1, "R200_SE_VAP_CNTL_STATUS"},
+ {R200_SE_VTX_STATE_CNTL, 1, "R200_SE_VTX_STATE_CNTL"},
+ {R200_RE_POINTSIZE, 1, "R200_RE_POINTSIZE"},
+ {R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_0, 4,
+ "R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_0"},
+ {R200_PP_CUBIC_FACES_0, 1, "R200_PP_CUBIC_FACES_0"}, /* 61 */
+ {R200_PP_CUBIC_OFFSET_F1_0, 5, "R200_PP_CUBIC_OFFSET_F1_0"}, /* 62 */
+ {R200_PP_CUBIC_FACES_1, 1, "R200_PP_CUBIC_FACES_1"},
+ {R200_PP_CUBIC_OFFSET_F1_1, 5, "R200_PP_CUBIC_OFFSET_F1_1"},
+ {R200_PP_CUBIC_FACES_2, 1, "R200_PP_CUBIC_FACES_2"},
+ {R200_PP_CUBIC_OFFSET_F1_2, 5, "R200_PP_CUBIC_OFFSET_F1_2"},
+ {R200_PP_CUBIC_FACES_3, 1, "R200_PP_CUBIC_FACES_3"},
+ {R200_PP_CUBIC_OFFSET_F1_3, 5, "R200_PP_CUBIC_OFFSET_F1_3"},
+ {R200_PP_CUBIC_FACES_4, 1, "R200_PP_CUBIC_FACES_4"},
+ {R200_PP_CUBIC_OFFSET_F1_4, 5, "R200_PP_CUBIC_OFFSET_F1_4"},
+ {R200_PP_CUBIC_FACES_5, 1, "R200_PP_CUBIC_FACES_5"},
+ {R200_PP_CUBIC_OFFSET_F1_5, 5, "R200_PP_CUBIC_OFFSET_F1_5"},
+ {RADEON_PP_TEX_SIZE_0, 2, "RADEON_PP_TEX_SIZE_0"},
+ {RADEON_PP_TEX_SIZE_1, 2, "RADEON_PP_TEX_SIZE_1"},
+ {RADEON_PP_TEX_SIZE_2, 2, "RADEON_PP_TEX_SIZE_2"},
+ {R200_RB3D_BLENDCOLOR, 3, "R200_RB3D_BLENDCOLOR"},
+ {R200_SE_TCL_POINT_SPRITE_CNTL, 1, "R200_SE_TCL_POINT_SPRITE_CNTL"},
+ {RADEON_PP_CUBIC_FACES_0, 1, "RADEON_PP_CUBIC_FACES_0"},
+ {RADEON_PP_CUBIC_OFFSET_T0_0, 5, "RADEON_PP_CUBIC_OFFSET_T0_0"},
+ {RADEON_PP_CUBIC_FACES_1, 1, "RADEON_PP_CUBIC_FACES_1"},
+ {RADEON_PP_CUBIC_OFFSET_T1_0, 5, "RADEON_PP_CUBIC_OFFSET_T1_0"},
+ {RADEON_PP_CUBIC_FACES_2, 1, "RADEON_PP_CUBIC_FACES_2"},
+ {RADEON_PP_CUBIC_OFFSET_T2_0, 5, "RADEON_PP_CUBIC_OFFSET_T2_0"},
+ {R200_PP_TRI_PERF, 2, "R200_PP_TRI_PERF"},
+ {R200_PP_AFS_0, 32, "R200_PP_AFS_0"}, /* 85 */
+ {R200_PP_AFS_1, 32, "R200_PP_AFS_1"},
+ {R200_PP_TFACTOR_0, 8, "R200_ATF_TFACTOR"},
+ {R200_PP_TXFILTER_0, 8, "R200_PP_TXCTLALL_0"},
+ {R200_PP_TXFILTER_1, 8, "R200_PP_TXCTLALL_1"},
+ {R200_PP_TXFILTER_2, 8, "R200_PP_TXCTLALL_2"},
+ {R200_PP_TXFILTER_3, 8, "R200_PP_TXCTLALL_3"},
+ {R200_PP_TXFILTER_4, 8, "R200_PP_TXCTLALL_4"},
+ {R200_PP_TXFILTER_5, 8, "R200_PP_TXCTLALL_5"},
};
-
-
/* ================================================================
* Performance monitoring functions
*/
-static void radeon_clear_box( drm_radeon_private_t *dev_priv,
- int x, int y, int w, int h,
- int r, int g, int b )
+static void radeon_clear_box(drm_radeon_private_t * dev_priv,
+ int x, int y, int w, int h, int r, int g, int b)
{
u32 color;
RING_LOCALS;
@@ -586,49 +616,47 @@ static void radeon_clear_box( drm_radeon_private_t *dev_priv,
x += dev_priv->sarea_priv->boxes[0].x1;
y += dev_priv->sarea_priv->boxes[0].y1;
- switch ( dev_priv->color_fmt ) {
+ switch (dev_priv->color_fmt) {
case RADEON_COLOR_FORMAT_RGB565:
color = (((r & 0xf8) << 8) |
- ((g & 0xfc) << 3) |
- ((b & 0xf8) >> 3));
+ ((g & 0xfc) << 3) | ((b & 0xf8) >> 3));
break;
case RADEON_COLOR_FORMAT_ARGB8888:
default:
- color = (((0xff) << 24) | (r << 16) | (g << 8) | b);
+ color = (((0xff) << 24) | (r << 16) | (g << 8) | b);
break;
}
- BEGIN_RING( 4 );
- RADEON_WAIT_UNTIL_3D_IDLE();
- OUT_RING( CP_PACKET0( RADEON_DP_WRITE_MASK, 0 ) );
- OUT_RING( 0xffffffff );
+ BEGIN_RING(4);
+ RADEON_WAIT_UNTIL_3D_IDLE();
+ OUT_RING(CP_PACKET0(RADEON_DP_WRITE_MASK, 0));
+ OUT_RING(0xffffffff);
ADVANCE_RING();
- BEGIN_RING( 6 );
+ BEGIN_RING(6);
- OUT_RING( CP_PACKET3( RADEON_CNTL_PAINT_MULTI, 4 ) );
- OUT_RING( RADEON_GMC_DST_PITCH_OFFSET_CNTL |
- RADEON_GMC_BRUSH_SOLID_COLOR |
- (dev_priv->color_fmt << 8) |
- RADEON_GMC_SRC_DATATYPE_COLOR |
- RADEON_ROP3_P |
- RADEON_GMC_CLR_CMP_CNTL_DIS );
+ OUT_RING(CP_PACKET3(RADEON_CNTL_PAINT_MULTI, 4));
+ OUT_RING(RADEON_GMC_DST_PITCH_OFFSET_CNTL |
+ RADEON_GMC_BRUSH_SOLID_COLOR |
+ (dev_priv->color_fmt << 8) |
+ RADEON_GMC_SRC_DATATYPE_COLOR |
+ RADEON_ROP3_P | RADEON_GMC_CLR_CMP_CNTL_DIS);
- if ( dev_priv->page_flipping && dev_priv->current_page == 1 ) {
- OUT_RING( dev_priv->front_pitch_offset );
- } else {
- OUT_RING( dev_priv->back_pitch_offset );
- }
+ if (dev_priv->page_flipping && dev_priv->current_page == 1) {
+ OUT_RING(dev_priv->front_pitch_offset);
+ } else {
+ OUT_RING(dev_priv->back_pitch_offset);
+ }
- OUT_RING( color );
+ OUT_RING(color);
- OUT_RING( (x << 16) | y );
- OUT_RING( (w << 16) | h );
+ OUT_RING((x << 16) | y);
+ OUT_RING((w << 16) | h);
ADVANCE_RING();
}
-static void radeon_cp_performance_boxes( drm_radeon_private_t *dev_priv )
+static void radeon_cp_performance_boxes(drm_radeon_private_t * dev_priv)
{
/* Collapse various things into a wait flag -- trying to
* guess if userspase slept -- better just to have them tell us.
@@ -644,50 +672,50 @@ static void radeon_cp_performance_boxes( drm_radeon_private_t *dev_priv )
/* Purple box for page flipping
*/
- if ( dev_priv->stats.boxes & RADEON_BOX_FLIP )
- radeon_clear_box( dev_priv, 4, 4, 8, 8, 255, 0, 255 );
+ if (dev_priv->stats.boxes & RADEON_BOX_FLIP)
+ radeon_clear_box(dev_priv, 4, 4, 8, 8, 255, 0, 255);
/* Red box if we have to wait for idle at any point
*/
- if ( dev_priv->stats.boxes & RADEON_BOX_WAIT_IDLE )
- radeon_clear_box( dev_priv, 16, 4, 8, 8, 255, 0, 0 );
+ if (dev_priv->stats.boxes & RADEON_BOX_WAIT_IDLE)
+ radeon_clear_box(dev_priv, 16, 4, 8, 8, 255, 0, 0);
/* Blue box: lost context?
*/
/* Yellow box for texture swaps
*/
- if ( dev_priv->stats.boxes & RADEON_BOX_TEXTURE_LOAD )
- radeon_clear_box( dev_priv, 40, 4, 8, 8, 255, 255, 0 );
+ if (dev_priv->stats.boxes & RADEON_BOX_TEXTURE_LOAD)
+ radeon_clear_box(dev_priv, 40, 4, 8, 8, 255, 255, 0);
/* Green box if hardware never idles (as far as we can tell)
*/
- if ( !(dev_priv->stats.boxes & RADEON_BOX_DMA_IDLE) )
- radeon_clear_box( dev_priv, 64, 4, 8, 8, 0, 255, 0 );
-
+ if (!(dev_priv->stats.boxes & RADEON_BOX_DMA_IDLE))
+ radeon_clear_box(dev_priv, 64, 4, 8, 8, 0, 255, 0);
- /* Draw bars indicating number of buffers allocated
+ /* Draw bars indicating number of buffers allocated
* (not a great measure, easily confused)
*/
if (dev_priv->stats.requested_bufs) {
if (dev_priv->stats.requested_bufs > 100)
dev_priv->stats.requested_bufs = 100;
- radeon_clear_box( dev_priv, 4, 16,
- dev_priv->stats.requested_bufs, 4,
- 196, 128, 128 );
+ radeon_clear_box(dev_priv, 4, 16,
+ dev_priv->stats.requested_bufs, 4,
+ 196, 128, 128);
}
- memset( &dev_priv->stats, 0, sizeof(dev_priv->stats) );
+ memset(&dev_priv->stats, 0, sizeof(dev_priv->stats));
}
+
/* ================================================================
* CP command dispatch functions
*/
-static void radeon_cp_dispatch_clear( drm_device_t *dev,
- drm_radeon_clear_t *clear,
- drm_radeon_clear_rect_t *depth_boxes )
+static void radeon_cp_dispatch_clear(drm_device_t * dev,
+ drm_radeon_clear_t * clear,
+ drm_radeon_clear_rect_t * depth_boxes)
{
drm_radeon_private_t *dev_priv = dev->dev_private;
drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
@@ -695,32 +723,34 @@ static void radeon_cp_dispatch_clear( drm_device_t *dev,
int nbox = sarea_priv->nbox;
drm_clip_rect_t *pbox = sarea_priv->boxes;
unsigned int flags = clear->flags;
- u32 rb3d_cntl = 0, rb3d_stencilrefmask= 0;
+ u32 rb3d_cntl = 0, rb3d_stencilrefmask = 0;
int i;
RING_LOCALS;
- DRM_DEBUG( "flags = 0x%x\n", flags );
+ DRM_DEBUG("flags = 0x%x\n", flags);
dev_priv->stats.clears++;
- if ( dev_priv->page_flipping && dev_priv->current_page == 1 ) {
+ if (dev_priv->page_flipping && dev_priv->current_page == 1) {
unsigned int tmp = flags;
flags &= ~(RADEON_FRONT | RADEON_BACK);
- if ( tmp & RADEON_FRONT ) flags |= RADEON_BACK;
- if ( tmp & RADEON_BACK ) flags |= RADEON_FRONT;
+ if (tmp & RADEON_FRONT)
+ flags |= RADEON_BACK;
+ if (tmp & RADEON_BACK)
+ flags |= RADEON_FRONT;
}
- if ( flags & (RADEON_FRONT | RADEON_BACK) ) {
+ if (flags & (RADEON_FRONT | RADEON_BACK)) {
- BEGIN_RING( 4 );
+ BEGIN_RING(4);
/* Ensure the 3D stream is idle before doing a
* 2D fill to clear the front or back buffer.
*/
RADEON_WAIT_UNTIL_3D_IDLE();
-
- OUT_RING( CP_PACKET0( RADEON_DP_WRITE_MASK, 0 ) );
- OUT_RING( clear->color_mask );
+
+ OUT_RING(CP_PACKET0(RADEON_DP_WRITE_MASK, 0));
+ OUT_RING(clear->color_mask);
ADVANCE_RING();
@@ -728,121 +758,130 @@ static void radeon_cp_dispatch_clear( drm_device_t *dev,
*/
dev_priv->sarea_priv->ctx_owner = 0;
- for ( i = 0 ; i < nbox ; i++ ) {
+ for (i = 0; i < nbox; i++) {
int x = pbox[i].x1;
int y = pbox[i].y1;
int w = pbox[i].x2 - x;
int h = pbox[i].y2 - y;
- DRM_DEBUG( "dispatch clear %d,%d-%d,%d flags 0x%x\n",
- x, y, w, h, flags );
-
- if ( flags & RADEON_FRONT ) {
- BEGIN_RING( 6 );
-
- OUT_RING( CP_PACKET3( RADEON_CNTL_PAINT_MULTI, 4 ) );
- OUT_RING( RADEON_GMC_DST_PITCH_OFFSET_CNTL |
- RADEON_GMC_BRUSH_SOLID_COLOR |
- (dev_priv->color_fmt << 8) |
- RADEON_GMC_SRC_DATATYPE_COLOR |
- RADEON_ROP3_P |
- RADEON_GMC_CLR_CMP_CNTL_DIS );
-
- OUT_RING( dev_priv->front_pitch_offset );
- OUT_RING( clear->clear_color );
-
- OUT_RING( (x << 16) | y );
- OUT_RING( (w << 16) | h );
-
+ DRM_DEBUG("dispatch clear %d,%d-%d,%d flags 0x%x\n",
+ x, y, w, h, flags);
+
+ if (flags & RADEON_FRONT) {
+ BEGIN_RING(6);
+
+ OUT_RING(CP_PACKET3
+ (RADEON_CNTL_PAINT_MULTI, 4));
+ OUT_RING(RADEON_GMC_DST_PITCH_OFFSET_CNTL |
+ RADEON_GMC_BRUSH_SOLID_COLOR |
+ (dev_priv->
+ color_fmt << 8) |
+ RADEON_GMC_SRC_DATATYPE_COLOR |
+ RADEON_ROP3_P |
+ RADEON_GMC_CLR_CMP_CNTL_DIS);
+
+ OUT_RING(dev_priv->front_pitch_offset);
+ OUT_RING(clear->clear_color);
+
+ OUT_RING((x << 16) | y);
+ OUT_RING((w << 16) | h);
+
ADVANCE_RING();
}
-
- if ( flags & RADEON_BACK ) {
- BEGIN_RING( 6 );
-
- OUT_RING( CP_PACKET3( RADEON_CNTL_PAINT_MULTI, 4 ) );
- OUT_RING( RADEON_GMC_DST_PITCH_OFFSET_CNTL |
- RADEON_GMC_BRUSH_SOLID_COLOR |
- (dev_priv->color_fmt << 8) |
- RADEON_GMC_SRC_DATATYPE_COLOR |
- RADEON_ROP3_P |
- RADEON_GMC_CLR_CMP_CNTL_DIS );
-
- OUT_RING( dev_priv->back_pitch_offset );
- OUT_RING( clear->clear_color );
-
- OUT_RING( (x << 16) | y );
- OUT_RING( (w << 16) | h );
+
+ if (flags & RADEON_BACK) {
+ BEGIN_RING(6);
+
+ OUT_RING(CP_PACKET3
+ (RADEON_CNTL_PAINT_MULTI, 4));
+ OUT_RING(RADEON_GMC_DST_PITCH_OFFSET_CNTL |
+ RADEON_GMC_BRUSH_SOLID_COLOR |
+ (dev_priv->
+ color_fmt << 8) |
+ RADEON_GMC_SRC_DATATYPE_COLOR |
+ RADEON_ROP3_P |
+ RADEON_GMC_CLR_CMP_CNTL_DIS);
+
+ OUT_RING(dev_priv->back_pitch_offset);
+ OUT_RING(clear->clear_color);
+
+ OUT_RING((x << 16) | y);
+ OUT_RING((w << 16) | h);
ADVANCE_RING();
}
}
}
-
+
/* hyper z clear */
/* no docs available, based on reverse engeneering by Stephane Marchesin */
- if ((flags & (RADEON_DEPTH | RADEON_STENCIL)) && (flags & RADEON_CLEAR_FASTZ)) {
+ if ((flags & (RADEON_DEPTH | RADEON_STENCIL))
+ && (flags & RADEON_CLEAR_FASTZ)) {
int i;
- int depthpixperline = dev_priv->depth_fmt==RADEON_DEPTH_FORMAT_16BIT_INT_Z?
- (dev_priv->depth_pitch / 2): (dev_priv->depth_pitch / 4);
-
+ int depthpixperline =
+ dev_priv->depth_fmt ==
+ RADEON_DEPTH_FORMAT_16BIT_INT_Z ? (dev_priv->depth_pitch /
+ 2) : (dev_priv->
+ depth_pitch / 4);
+
u32 clearmask;
u32 tempRB3D_DEPTHCLEARVALUE = clear->clear_depth |
- ((clear->depth_mask & 0xff) << 24);
-
-
+ ((clear->depth_mask & 0xff) << 24);
+
/* Make sure we restore the 3D state next time.
* we haven't touched any "normal" state - still need this?
*/
dev_priv->sarea_priv->ctx_owner = 0;
- if ((dev_priv->flags & CHIP_HAS_HIERZ) && (flags & RADEON_USE_HIERZ)) {
- /* FIXME : reverse engineer that for Rx00 cards */
- /* FIXME : the mask supposedly contains low-res z values. So can't set
- just to the max (0xff? or actually 0x3fff?), need to take z clear
- value into account? */
- /* pattern seems to work for r100, though get slight
- rendering errors with glxgears. If hierz is not enabled for r100,
- only 4 bits which indicate clear (15,16,31,32, all zero) matter, the
- other ones are ignored, and the same clear mask can be used. That's
- very different behaviour than R200 which needs different clear mask
- and different number of tiles to clear if hierz is enabled or not !?!
- */
- clearmask = (0xff<<22)|(0xff<<6)| 0x003f003f;
- }
- else {
- /* clear mask : chooses the clearing pattern.
- rv250: could be used to clear only parts of macrotiles
- (but that would get really complicated...)?
- bit 0 and 1 (either or both of them ?!?!) are used to
- not clear tile (or maybe one of the bits indicates if the tile is
- compressed or not), bit 2 and 3 to not clear tile 1,...,.
- Pattern is as follows:
- | 0,1 | 4,5 | 8,9 |12,13|16,17|20,21|24,25|28,29|
- bits -------------------------------------------------
- | 2,3 | 6,7 |10,11|14,15|18,19|22,23|26,27|30,31|
- rv100: clearmask covers 2x8 4x1 tiles, but one clear still
- covers 256 pixels ?!?
- */
+ if ((dev_priv->flags & CHIP_HAS_HIERZ)
+ && (flags & RADEON_USE_HIERZ)) {
+ /* FIXME : reverse engineer that for Rx00 cards */
+ /* FIXME : the mask supposedly contains low-res z values. So can't set
+ just to the max (0xff? or actually 0x3fff?), need to take z clear
+ value into account? */
+ /* pattern seems to work for r100, though get slight
+ rendering errors with glxgears. If hierz is not enabled for r100,
+ only 4 bits which indicate clear (15,16,31,32, all zero) matter, the
+ other ones are ignored, and the same clear mask can be used. That's
+ very different behaviour than R200 which needs different clear mask
+ and different number of tiles to clear if hierz is enabled or not !?!
+ */
+ clearmask = (0xff << 22) | (0xff << 6) | 0x003f003f;
+ } else {
+ /* clear mask : chooses the clearing pattern.
+ rv250: could be used to clear only parts of macrotiles
+ (but that would get really complicated...)?
+ bit 0 and 1 (either or both of them ?!?!) are used to
+ not clear tile (or maybe one of the bits indicates if the tile is
+ compressed or not), bit 2 and 3 to not clear tile 1,...,.
+ Pattern is as follows:
+ | 0,1 | 4,5 | 8,9 |12,13|16,17|20,21|24,25|28,29|
+ bits -------------------------------------------------
+ | 2,3 | 6,7 |10,11|14,15|18,19|22,23|26,27|30,31|
+ rv100: clearmask covers 2x8 4x1 tiles, but one clear still
+ covers 256 pixels ?!?
+ */
clearmask = 0x0;
}
- BEGIN_RING( 8 );
+ BEGIN_RING(8);
RADEON_WAIT_UNTIL_2D_IDLE();
- OUT_RING_REG( RADEON_RB3D_DEPTHCLEARVALUE,
- tempRB3D_DEPTHCLEARVALUE);
+ OUT_RING_REG(RADEON_RB3D_DEPTHCLEARVALUE,
+ tempRB3D_DEPTHCLEARVALUE);
/* what offset is this exactly ? */
- OUT_RING_REG( RADEON_RB3D_ZMASKOFFSET, 0 );
+ OUT_RING_REG(RADEON_RB3D_ZMASKOFFSET, 0);
/* need ctlstat, otherwise get some strange black flickering */
- OUT_RING_REG( RADEON_RB3D_ZCACHE_CTLSTAT, RADEON_RB3D_ZC_FLUSH_ALL );
+ OUT_RING_REG(RADEON_RB3D_ZCACHE_CTLSTAT,
+ RADEON_RB3D_ZC_FLUSH_ALL);
ADVANCE_RING();
for (i = 0; i < nbox; i++) {
int tileoffset, nrtilesx, nrtilesy, j;
/* it looks like r200 needs rv-style clears, at least if hierz is not enabled? */
- if ((dev_priv->flags&CHIP_HAS_HIERZ) && !(dev_priv->microcode_version==UCODE_R200)) {
+ if ((dev_priv->flags & CHIP_HAS_HIERZ)
+ && !(dev_priv->microcode_version == UCODE_R200)) {
/* FIXME : figure this out for r200 (when hierz is enabled). Or
maybe r200 actually doesn't need to put the low-res z value into
the tile cache like r100, but just needs to clear the hi-level z-buffer?
@@ -850,59 +889,74 @@ static void radeon_cp_dispatch_clear( drm_device_t *dev,
R100 seems to operate on 2x1 8x8 tiles, but...
odd: offset/nrtiles need to be 64 pix (4 block) aligned? Potentially
problematic with resolutions which are not 64 pix aligned? */
- tileoffset = ((pbox[i].y1 >> 3) * depthpixperline + pbox[i].x1) >> 6;
- nrtilesx = ((pbox[i].x2 & ~63) - (pbox[i].x1 & ~63)) >> 4;
- nrtilesy = (pbox[i].y2 >> 3) - (pbox[i].y1 >> 3);
+ tileoffset =
+ ((pbox[i].y1 >> 3) * depthpixperline +
+ pbox[i].x1) >> 6;
+ nrtilesx =
+ ((pbox[i].x2 & ~63) -
+ (pbox[i].x1 & ~63)) >> 4;
+ nrtilesy =
+ (pbox[i].y2 >> 3) - (pbox[i].y1 >> 3);
for (j = 0; j <= nrtilesy; j++) {
- BEGIN_RING( 4 );
- OUT_RING( CP_PACKET3( RADEON_3D_CLEAR_ZMASK, 2 ) );
+ BEGIN_RING(4);
+ OUT_RING(CP_PACKET3
+ (RADEON_3D_CLEAR_ZMASK, 2));
/* first tile */
- OUT_RING( tileoffset * 8 );
+ OUT_RING(tileoffset * 8);
/* the number of tiles to clear */
- OUT_RING( nrtilesx + 4 );
+ OUT_RING(nrtilesx + 4);
/* clear mask : chooses the clearing pattern. */
- OUT_RING( clearmask );
+ OUT_RING(clearmask);
ADVANCE_RING();
tileoffset += depthpixperline >> 6;
}
- }
- else if (dev_priv->microcode_version==UCODE_R200) {
+ } else if (dev_priv->microcode_version == UCODE_R200) {
/* works for rv250. */
/* find first macro tile (8x2 4x4 z-pixels on rv250) */
- tileoffset = ((pbox[i].y1 >> 3) * depthpixperline + pbox[i].x1) >> 5;
- nrtilesx = (pbox[i].x2 >> 5) - (pbox[i].x1 >> 5);
- nrtilesy = (pbox[i].y2 >> 3) - (pbox[i].y1 >> 3);
+ tileoffset =
+ ((pbox[i].y1 >> 3) * depthpixperline +
+ pbox[i].x1) >> 5;
+ nrtilesx =
+ (pbox[i].x2 >> 5) - (pbox[i].x1 >> 5);
+ nrtilesy =
+ (pbox[i].y2 >> 3) - (pbox[i].y1 >> 3);
for (j = 0; j <= nrtilesy; j++) {
- BEGIN_RING( 4 );
- OUT_RING( CP_PACKET3( RADEON_3D_CLEAR_ZMASK, 2 ) );
+ BEGIN_RING(4);
+ OUT_RING(CP_PACKET3
+ (RADEON_3D_CLEAR_ZMASK, 2));
/* first tile */
/* judging by the first tile offset needed, could possibly
directly address/clear 4x4 tiles instead of 8x2 * 4x4
macro tiles, though would still need clear mask for
right/bottom if truely 4x4 granularity is desired ? */
- OUT_RING( tileoffset * 16 );
+ OUT_RING(tileoffset * 16);
/* the number of tiles to clear */
- OUT_RING( nrtilesx + 1 );
+ OUT_RING(nrtilesx + 1);
/* clear mask : chooses the clearing pattern. */
- OUT_RING( clearmask );
+ OUT_RING(clearmask);
ADVANCE_RING();
tileoffset += depthpixperline >> 5;
}
- }
- else { /* rv 100 */
+ } else { /* rv 100 */
/* rv100 might not need 64 pix alignment, who knows */
/* offsets are, hmm, weird */
- tileoffset = ((pbox[i].y1 >> 4) * depthpixperline + pbox[i].x1) >> 6;
- nrtilesx = ((pbox[i].x2 & ~63) - (pbox[i].x1 & ~63)) >> 4;
- nrtilesy = (pbox[i].y2 >> 4) - (pbox[i].y1 >> 4);
+ tileoffset =
+ ((pbox[i].y1 >> 4) * depthpixperline +
+ pbox[i].x1) >> 6;
+ nrtilesx =
+ ((pbox[i].x2 & ~63) -
+ (pbox[i].x1 & ~63)) >> 4;
+ nrtilesy =
+ (pbox[i].y2 >> 4) - (pbox[i].y1 >> 4);
for (j = 0; j <= nrtilesy; j++) {
- BEGIN_RING( 4 );
- OUT_RING( CP_PACKET3( RADEON_3D_CLEAR_ZMASK, 2 ) );
- OUT_RING( tileoffset * 128 );
+ BEGIN_RING(4);
+ OUT_RING(CP_PACKET3
+ (RADEON_3D_CLEAR_ZMASK, 2));
+ OUT_RING(tileoffset * 128);
/* the number of tiles to clear */
- OUT_RING( nrtilesx + 4 );
+ OUT_RING(nrtilesx + 4);
/* clear mask : chooses the clearing pattern. */
- OUT_RING( clearmask );
+ OUT_RING(clearmask);
ADVANCE_RING();
tileoffset += depthpixperline >> 6;
}
@@ -910,18 +964,19 @@ static void radeon_cp_dispatch_clear( drm_device_t *dev,
}
/* TODO don't always clear all hi-level z tiles */
- if ((dev_priv->flags & CHIP_HAS_HIERZ) && (dev_priv->microcode_version==UCODE_R200)
- && (flags & RADEON_USE_HIERZ))
- /* r100 and cards without hierarchical z-buffer have no high-level z-buffer */
- /* FIXME : the mask supposedly contains low-res z values. So can't set
- just to the max (0xff? or actually 0x3fff?), need to take z clear
- value into account? */
+ if ((dev_priv->flags & CHIP_HAS_HIERZ)
+ && (dev_priv->microcode_version == UCODE_R200)
+ && (flags & RADEON_USE_HIERZ))
+ /* r100 and cards without hierarchical z-buffer have no high-level z-buffer */
+ /* FIXME : the mask supposedly contains low-res z values. So can't set
+ just to the max (0xff? or actually 0x3fff?), need to take z clear
+ value into account? */
{
- BEGIN_RING( 4 );
- OUT_RING( CP_PACKET3( RADEON_3D_CLEAR_HIZ, 2 ) );
- OUT_RING( 0x0 ); /* First tile */
- OUT_RING( 0x3cc0 );
- OUT_RING( (0xff<<22)|(0xff<<6)| 0x003f003f);
+ BEGIN_RING(4);
+ OUT_RING(CP_PACKET3(RADEON_3D_CLEAR_HIZ, 2));
+ OUT_RING(0x0); /* First tile */
+ OUT_RING(0x3cc0);
+ OUT_RING((0xff << 22) | (0xff << 6) | 0x003f003f);
ADVANCE_RING();
}
}
@@ -956,30 +1011,27 @@ static void radeon_cp_dispatch_clear( drm_device_t *dev,
tempSE_CNTL = depth_clear->se_cntl;
-
-
/* Disable TCL */
- tempSE_VAP_CNTL = (/* SE_VAP_CNTL__FORCE_W_TO_ONE_MASK | */
- (0x9 << SE_VAP_CNTL__VF_MAX_VTX_NUM__SHIFT));
+ tempSE_VAP_CNTL = ( /* SE_VAP_CNTL__FORCE_W_TO_ONE_MASK | */
+ (0x9 <<
+ SE_VAP_CNTL__VF_MAX_VTX_NUM__SHIFT));
tempRB3D_PLANEMASK = 0x0;
tempRE_AUX_SCISSOR_CNTL = 0x0;
tempSE_VTE_CNTL =
- SE_VTE_CNTL__VTX_XY_FMT_MASK |
- SE_VTE_CNTL__VTX_Z_FMT_MASK;
+ SE_VTE_CNTL__VTX_XY_FMT_MASK | SE_VTE_CNTL__VTX_Z_FMT_MASK;
- /* Vertex format (X, Y, Z, W)*/
+ /* Vertex format (X, Y, Z, W) */
tempSE_VTX_FMT_0 =
- SE_VTX_FMT_0__VTX_Z0_PRESENT_MASK |
- SE_VTX_FMT_0__VTX_W0_PRESENT_MASK;
+ SE_VTX_FMT_0__VTX_Z0_PRESENT_MASK |
+ SE_VTX_FMT_0__VTX_W0_PRESENT_MASK;
tempSE_VTX_FMT_1 = 0x0;
-
- /*
- * Depth buffer specific enables
+ /*
+ * Depth buffer specific enables
*/
if (flags & RADEON_DEPTH) {
/* Enable depth buffer */
@@ -989,12 +1041,12 @@ static void radeon_cp_dispatch_clear( drm_device_t *dev,
tempRB3D_CNTL &= ~RADEON_Z_ENABLE;
}
- /*
+ /*
* Stencil buffer specific enables
*/
- if ( flags & RADEON_STENCIL ) {
- tempRB3D_CNTL |= RADEON_STENCIL_ENABLE;
- tempRB3D_STENCILREFMASK = clear->depth_mask;
+ if (flags & RADEON_STENCIL) {
+ tempRB3D_CNTL |= RADEON_STENCIL_ENABLE;
+ tempRB3D_STENCILREFMASK = clear->depth_mask;
} else {
tempRB3D_CNTL &= ~RADEON_STENCIL_ENABLE;
tempRB3D_STENCILREFMASK = 0x00000000;
@@ -1002,79 +1054,75 @@ static void radeon_cp_dispatch_clear( drm_device_t *dev,
if (flags & RADEON_USE_COMP_ZBUF) {
tempRB3D_ZSTENCILCNTL |= RADEON_Z_COMPRESSION_ENABLE |
- RADEON_Z_DECOMPRESSION_ENABLE;
+ RADEON_Z_DECOMPRESSION_ENABLE;
}
if (flags & RADEON_USE_HIERZ) {
tempRB3D_ZSTENCILCNTL |= RADEON_Z_HIERARCHY_ENABLE;
}
- BEGIN_RING( 26 );
+ BEGIN_RING(26);
RADEON_WAIT_UNTIL_2D_IDLE();
- OUT_RING_REG( RADEON_PP_CNTL, tempPP_CNTL );
- OUT_RING_REG( R200_RE_CNTL, tempRE_CNTL );
- OUT_RING_REG( RADEON_RB3D_CNTL, tempRB3D_CNTL );
- OUT_RING_REG( RADEON_RB3D_ZSTENCILCNTL,
- tempRB3D_ZSTENCILCNTL );
- OUT_RING_REG( RADEON_RB3D_STENCILREFMASK,
- tempRB3D_STENCILREFMASK );
- OUT_RING_REG( RADEON_RB3D_PLANEMASK, tempRB3D_PLANEMASK );
- OUT_RING_REG( RADEON_SE_CNTL, tempSE_CNTL );
- OUT_RING_REG( R200_SE_VTE_CNTL, tempSE_VTE_CNTL );
- OUT_RING_REG( R200_SE_VTX_FMT_0, tempSE_VTX_FMT_0 );
- OUT_RING_REG( R200_SE_VTX_FMT_1, tempSE_VTX_FMT_1 );
- OUT_RING_REG( R200_SE_VAP_CNTL, tempSE_VAP_CNTL );
- OUT_RING_REG( R200_RE_AUX_SCISSOR_CNTL,
- tempRE_AUX_SCISSOR_CNTL );
+ OUT_RING_REG(RADEON_PP_CNTL, tempPP_CNTL);
+ OUT_RING_REG(R200_RE_CNTL, tempRE_CNTL);
+ OUT_RING_REG(RADEON_RB3D_CNTL, tempRB3D_CNTL);
+ OUT_RING_REG(RADEON_RB3D_ZSTENCILCNTL, tempRB3D_ZSTENCILCNTL);
+ OUT_RING_REG(RADEON_RB3D_STENCILREFMASK,
+ tempRB3D_STENCILREFMASK);
+ OUT_RING_REG(RADEON_RB3D_PLANEMASK, tempRB3D_PLANEMASK);
+ OUT_RING_REG(RADEON_SE_CNTL, tempSE_CNTL);
+ OUT_RING_REG(R200_SE_VTE_CNTL, tempSE_VTE_CNTL);
+ OUT_RING_REG(R200_SE_VTX_FMT_0, tempSE_VTX_FMT_0);
+ OUT_RING_REG(R200_SE_VTX_FMT_1, tempSE_VTX_FMT_1);
+ OUT_RING_REG(R200_SE_VAP_CNTL, tempSE_VAP_CNTL);
+ OUT_RING_REG(R200_RE_AUX_SCISSOR_CNTL, tempRE_AUX_SCISSOR_CNTL);
ADVANCE_RING();
/* Make sure we restore the 3D state next time.
*/
dev_priv->sarea_priv->ctx_owner = 0;
- for ( i = 0 ; i < nbox ; i++ ) {
-
- /* Funny that this should be required --
+ for (i = 0; i < nbox; i++) {
+
+ /* Funny that this should be required --
* sets top-left?
*/
- radeon_emit_clip_rect( dev_priv,
- &sarea_priv->boxes[i] );
-
- BEGIN_RING( 14 );
- OUT_RING( CP_PACKET3( R200_3D_DRAW_IMMD_2, 12 ) );
- OUT_RING( (RADEON_PRIM_TYPE_RECT_LIST |
- RADEON_PRIM_WALK_RING |
- (3 << RADEON_NUM_VERTICES_SHIFT)) );
- OUT_RING( depth_boxes[i].ui[CLEAR_X1] );
- OUT_RING( depth_boxes[i].ui[CLEAR_Y1] );
- OUT_RING( depth_boxes[i].ui[CLEAR_DEPTH] );
- OUT_RING( 0x3f800000 );
- OUT_RING( depth_boxes[i].ui[CLEAR_X1] );
- OUT_RING( depth_boxes[i].ui[CLEAR_Y2] );
- OUT_RING( depth_boxes[i].ui[CLEAR_DEPTH] );
- OUT_RING( 0x3f800000 );
- OUT_RING( depth_boxes[i].ui[CLEAR_X2] );
- OUT_RING( depth_boxes[i].ui[CLEAR_Y2] );
- OUT_RING( depth_boxes[i].ui[CLEAR_DEPTH] );
- OUT_RING( 0x3f800000 );
+ radeon_emit_clip_rect(dev_priv, &sarea_priv->boxes[i]);
+
+ BEGIN_RING(14);
+ OUT_RING(CP_PACKET3(R200_3D_DRAW_IMMD_2, 12));
+ OUT_RING((RADEON_PRIM_TYPE_RECT_LIST |
+ RADEON_PRIM_WALK_RING |
+ (3 << RADEON_NUM_VERTICES_SHIFT)));
+ OUT_RING(depth_boxes[i].ui[CLEAR_X1]);
+ OUT_RING(depth_boxes[i].ui[CLEAR_Y1]);
+ OUT_RING(depth_boxes[i].ui[CLEAR_DEPTH]);
+ OUT_RING(0x3f800000);
+ OUT_RING(depth_boxes[i].ui[CLEAR_X1]);
+ OUT_RING(depth_boxes[i].ui[CLEAR_Y2]);
+ OUT_RING(depth_boxes[i].ui[CLEAR_DEPTH]);
+ OUT_RING(0x3f800000);
+ OUT_RING(depth_boxes[i].ui[CLEAR_X2]);
+ OUT_RING(depth_boxes[i].ui[CLEAR_Y2]);
+ OUT_RING(depth_boxes[i].ui[CLEAR_DEPTH]);
+ OUT_RING(0x3f800000);
ADVANCE_RING();
}
- }
- else if ( (flags & (RADEON_DEPTH | RADEON_STENCIL)) ) {
+ } else if ((flags & (RADEON_DEPTH | RADEON_STENCIL))) {
int tempRB3D_ZSTENCILCNTL = depth_clear->rb3d_zstencilcntl;
rb3d_cntl = depth_clear->rb3d_cntl;
- if ( flags & RADEON_DEPTH ) {
- rb3d_cntl |= RADEON_Z_ENABLE;
+ if (flags & RADEON_DEPTH) {
+ rb3d_cntl |= RADEON_Z_ENABLE;
} else {
rb3d_cntl &= ~RADEON_Z_ENABLE;
}
- if ( flags & RADEON_STENCIL ) {
- rb3d_cntl |= RADEON_STENCIL_ENABLE;
- rb3d_stencilrefmask = clear->depth_mask; /* misnamed field */
+ if (flags & RADEON_STENCIL) {
+ rb3d_cntl |= RADEON_STENCIL_ENABLE;
+ rb3d_stencilrefmask = clear->depth_mask; /* misnamed field */
} else {
rb3d_cntl &= ~RADEON_STENCIL_ENABLE;
rb3d_stencilrefmask = 0x00000000;
@@ -1082,66 +1130,61 @@ static void radeon_cp_dispatch_clear( drm_device_t *dev,
if (flags & RADEON_USE_COMP_ZBUF) {
tempRB3D_ZSTENCILCNTL |= RADEON_Z_COMPRESSION_ENABLE |
- RADEON_Z_DECOMPRESSION_ENABLE;
+ RADEON_Z_DECOMPRESSION_ENABLE;
}
if (flags & RADEON_USE_HIERZ) {
tempRB3D_ZSTENCILCNTL |= RADEON_Z_HIERARCHY_ENABLE;
}
- BEGIN_RING( 13 );
+ BEGIN_RING(13);
RADEON_WAIT_UNTIL_2D_IDLE();
- OUT_RING( CP_PACKET0( RADEON_PP_CNTL, 1 ) );
- OUT_RING( 0x00000000 );
- OUT_RING( rb3d_cntl );
-
- OUT_RING_REG( RADEON_RB3D_ZSTENCILCNTL, tempRB3D_ZSTENCILCNTL );
- OUT_RING_REG( RADEON_RB3D_STENCILREFMASK,
- rb3d_stencilrefmask );
- OUT_RING_REG( RADEON_RB3D_PLANEMASK,
- 0x00000000 );
- OUT_RING_REG( RADEON_SE_CNTL,
- depth_clear->se_cntl );
+ OUT_RING(CP_PACKET0(RADEON_PP_CNTL, 1));
+ OUT_RING(0x00000000);
+ OUT_RING(rb3d_cntl);
+
+ OUT_RING_REG(RADEON_RB3D_ZSTENCILCNTL, tempRB3D_ZSTENCILCNTL);
+ OUT_RING_REG(RADEON_RB3D_STENCILREFMASK, rb3d_stencilrefmask);
+ OUT_RING_REG(RADEON_RB3D_PLANEMASK, 0x00000000);
+ OUT_RING_REG(RADEON_SE_CNTL, depth_clear->se_cntl);
ADVANCE_RING();
/* Make sure we restore the 3D state next time.
*/
dev_priv->sarea_priv->ctx_owner = 0;
- for ( i = 0 ; i < nbox ; i++ ) {
-
- /* Funny that this should be required --
+ for (i = 0; i < nbox; i++) {
+
+ /* Funny that this should be required --
* sets top-left?
*/
- radeon_emit_clip_rect( dev_priv,
- &sarea_priv->boxes[i] );
-
- BEGIN_RING( 15 );
-
- OUT_RING( CP_PACKET3( RADEON_3D_DRAW_IMMD, 13 ) );
- OUT_RING( RADEON_VTX_Z_PRESENT |
- RADEON_VTX_PKCOLOR_PRESENT);
- OUT_RING( (RADEON_PRIM_TYPE_RECT_LIST |
- RADEON_PRIM_WALK_RING |
- RADEON_MAOS_ENABLE |
- RADEON_VTX_FMT_RADEON_MODE |
- (3 << RADEON_NUM_VERTICES_SHIFT)) );
-
-
- OUT_RING( depth_boxes[i].ui[CLEAR_X1] );
- OUT_RING( depth_boxes[i].ui[CLEAR_Y1] );
- OUT_RING( depth_boxes[i].ui[CLEAR_DEPTH] );
- OUT_RING( 0x0 );
-
- OUT_RING( depth_boxes[i].ui[CLEAR_X1] );
- OUT_RING( depth_boxes[i].ui[CLEAR_Y2] );
- OUT_RING( depth_boxes[i].ui[CLEAR_DEPTH] );
- OUT_RING( 0x0 );
-
- OUT_RING( depth_boxes[i].ui[CLEAR_X2] );
- OUT_RING( depth_boxes[i].ui[CLEAR_Y2] );
- OUT_RING( depth_boxes[i].ui[CLEAR_DEPTH] );
- OUT_RING( 0x0 );
+ radeon_emit_clip_rect(dev_priv, &sarea_priv->boxes[i]);
+
+ BEGIN_RING(15);
+
+ OUT_RING(CP_PACKET3(RADEON_3D_DRAW_IMMD, 13));
+ OUT_RING(RADEON_VTX_Z_PRESENT |
+ RADEON_VTX_PKCOLOR_PRESENT);
+ OUT_RING((RADEON_PRIM_TYPE_RECT_LIST |
+ RADEON_PRIM_WALK_RING |
+ RADEON_MAOS_ENABLE |
+ RADEON_VTX_FMT_RADEON_MODE |
+ (3 << RADEON_NUM_VERTICES_SHIFT)));
+
+ OUT_RING(depth_boxes[i].ui[CLEAR_X1]);
+ OUT_RING(depth_boxes[i].ui[CLEAR_Y1]);
+ OUT_RING(depth_boxes[i].ui[CLEAR_DEPTH]);
+ OUT_RING(0x0);
+
+ OUT_RING(depth_boxes[i].ui[CLEAR_X1]);
+ OUT_RING(depth_boxes[i].ui[CLEAR_Y2]);
+ OUT_RING(depth_boxes[i].ui[CLEAR_DEPTH]);
+ OUT_RING(0x0);
+
+ OUT_RING(depth_boxes[i].ui[CLEAR_X2]);
+ OUT_RING(depth_boxes[i].ui[CLEAR_Y2]);
+ OUT_RING(depth_boxes[i].ui[CLEAR_DEPTH]);
+ OUT_RING(0x0);
ADVANCE_RING();
}
@@ -1153,15 +1196,15 @@ static void radeon_cp_dispatch_clear( drm_device_t *dev,
*/
dev_priv->sarea_priv->last_clear++;
- BEGIN_RING( 4 );
+ BEGIN_RING(4);
- RADEON_CLEAR_AGE( dev_priv->sarea_priv->last_clear );
+ RADEON_CLEAR_AGE(dev_priv->sarea_priv->last_clear);
RADEON_WAIT_UNTIL_IDLE();
ADVANCE_RING();
}
-static void radeon_cp_dispatch_swap( drm_device_t *dev )
+static void radeon_cp_dispatch_swap(drm_device_t * dev)
{
drm_radeon_private_t *dev_priv = dev->dev_private;
drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
@@ -1169,59 +1212,55 @@ static void radeon_cp_dispatch_swap( drm_device_t *dev )
drm_clip_rect_t *pbox = sarea_priv->boxes;
int i;
RING_LOCALS;
- DRM_DEBUG( "\n" );
+ DRM_DEBUG("\n");
/* Do some trivial performance monitoring...
*/
if (dev_priv->do_boxes)
- radeon_cp_performance_boxes( dev_priv );
-
+ radeon_cp_performance_boxes(dev_priv);
/* Wait for the 3D stream to idle before dispatching the bitblt.
* This will prevent data corruption between the two streams.
*/
- BEGIN_RING( 2 );
+ BEGIN_RING(2);
RADEON_WAIT_UNTIL_3D_IDLE();
ADVANCE_RING();
- for ( i = 0 ; i < nbox ; i++ ) {
+ for (i = 0; i < nbox; i++) {
int x = pbox[i].x1;
int y = pbox[i].y1;
int w = pbox[i].x2 - x;
int h = pbox[i].y2 - y;
- DRM_DEBUG( "dispatch swap %d,%d-%d,%d\n",
- x, y, w, h );
-
- BEGIN_RING( 7 );
-
- OUT_RING( CP_PACKET3( RADEON_CNTL_BITBLT_MULTI, 5 ) );
- OUT_RING( RADEON_GMC_SRC_PITCH_OFFSET_CNTL |
- RADEON_GMC_DST_PITCH_OFFSET_CNTL |
- RADEON_GMC_BRUSH_NONE |
- (dev_priv->color_fmt << 8) |
- RADEON_GMC_SRC_DATATYPE_COLOR |
- RADEON_ROP3_S |
- RADEON_DP_SRC_SOURCE_MEMORY |
- RADEON_GMC_CLR_CMP_CNTL_DIS |
- RADEON_GMC_WR_MSK_DIS );
-
+ DRM_DEBUG("dispatch swap %d,%d-%d,%d\n", x, y, w, h);
+
+ BEGIN_RING(7);
+
+ OUT_RING(CP_PACKET3(RADEON_CNTL_BITBLT_MULTI, 5));
+ OUT_RING(RADEON_GMC_SRC_PITCH_OFFSET_CNTL |
+ RADEON_GMC_DST_PITCH_OFFSET_CNTL |
+ RADEON_GMC_BRUSH_NONE |
+ (dev_priv->color_fmt << 8) |
+ RADEON_GMC_SRC_DATATYPE_COLOR |
+ RADEON_ROP3_S |
+ RADEON_DP_SRC_SOURCE_MEMORY |
+ RADEON_GMC_CLR_CMP_CNTL_DIS | RADEON_GMC_WR_MSK_DIS);
+
/* Make this work even if front & back are flipped:
*/
if (dev_priv->current_page == 0) {
- OUT_RING( dev_priv->back_pitch_offset );
- OUT_RING( dev_priv->front_pitch_offset );
- }
- else {
- OUT_RING( dev_priv->front_pitch_offset );
- OUT_RING( dev_priv->back_pitch_offset );
+ OUT_RING(dev_priv->back_pitch_offset);
+ OUT_RING(dev_priv->front_pitch_offset);
+ } else {
+ OUT_RING(dev_priv->front_pitch_offset);
+ OUT_RING(dev_priv->back_pitch_offset);
}
- OUT_RING( (x << 16) | y );
- OUT_RING( (x << 16) | y );
- OUT_RING( (w << 16) | h );
+ OUT_RING((x << 16) | y);
+ OUT_RING((x << 16) | y);
+ OUT_RING((w << 16) | h);
ADVANCE_RING();
}
@@ -1232,44 +1271,43 @@ static void radeon_cp_dispatch_swap( drm_device_t *dev )
*/
dev_priv->sarea_priv->last_frame++;
- BEGIN_RING( 4 );
+ BEGIN_RING(4);
- RADEON_FRAME_AGE( dev_priv->sarea_priv->last_frame );
+ RADEON_FRAME_AGE(dev_priv->sarea_priv->last_frame);
RADEON_WAIT_UNTIL_2D_IDLE();
ADVANCE_RING();
}
-static void radeon_cp_dispatch_flip( drm_device_t *dev )
+static void radeon_cp_dispatch_flip(drm_device_t * dev)
{
drm_radeon_private_t *dev_priv = dev->dev_private;
- drm_sarea_t *sarea = (drm_sarea_t *)dev_priv->sarea->handle;
+ drm_sarea_t *sarea = (drm_sarea_t *) dev_priv->sarea->handle;
int offset = (dev_priv->current_page == 1)
- ? dev_priv->front_offset : dev_priv->back_offset;
+ ? dev_priv->front_offset : dev_priv->back_offset;
RING_LOCALS;
- DRM_DEBUG( "%s: page=%d pfCurrentPage=%d\n",
- __FUNCTION__,
- dev_priv->current_page,
- dev_priv->sarea_priv->pfCurrentPage);
+ DRM_DEBUG("%s: page=%d pfCurrentPage=%d\n",
+ __FUNCTION__,
+ dev_priv->current_page, dev_priv->sarea_priv->pfCurrentPage);
/* Do some trivial performance monitoring...
*/
if (dev_priv->do_boxes) {
dev_priv->stats.boxes |= RADEON_BOX_FLIP;
- radeon_cp_performance_boxes( dev_priv );
+ radeon_cp_performance_boxes(dev_priv);
}
/* Update the frame offsets for both CRTCs
*/
- BEGIN_RING( 6 );
+ BEGIN_RING(6);
RADEON_WAIT_UNTIL_3D_IDLE();
- OUT_RING_REG( RADEON_CRTC_OFFSET, ( ( sarea->frame.y * dev_priv->front_pitch
- + sarea->frame.x
- * ( dev_priv->color_fmt - 2 ) ) & ~7 )
- + offset );
- OUT_RING_REG( RADEON_CRTC2_OFFSET, dev_priv->sarea_priv->crtc2_base
- + offset );
+ OUT_RING_REG(RADEON_CRTC_OFFSET,
+ ((sarea->frame.y * dev_priv->front_pitch +
+ sarea->frame.x * (dev_priv->color_fmt - 2)) & ~7)
+ + offset);
+ OUT_RING_REG(RADEON_CRTC2_OFFSET, dev_priv->sarea_priv->crtc2_base
+ + offset);
ADVANCE_RING();
@@ -1279,16 +1317,16 @@ static void radeon_cp_dispatch_flip( drm_device_t *dev )
*/
dev_priv->sarea_priv->last_frame++;
dev_priv->sarea_priv->pfCurrentPage = dev_priv->current_page =
- 1 - dev_priv->current_page;
+ 1 - dev_priv->current_page;
- BEGIN_RING( 2 );
+ BEGIN_RING(2);
- RADEON_FRAME_AGE( dev_priv->sarea_priv->last_frame );
+ RADEON_FRAME_AGE(dev_priv->sarea_priv->last_frame);
ADVANCE_RING();
}
-static int bad_prim_vertex_nr( int primitive, int nr )
+static int bad_prim_vertex_nr(int primitive, int nr)
{
switch (primitive & RADEON_PRIM_TYPE_MASK) {
case RADEON_PRIM_TYPE_NONE:
@@ -1308,24 +1346,21 @@ static int bad_prim_vertex_nr( int primitive, int nr )
return nr < 3;
default:
return 1;
- }
+ }
}
-
-
typedef struct {
unsigned int start;
unsigned int finish;
unsigned int prim;
unsigned int numverts;
- unsigned int offset;
- unsigned int vc_format;
+ unsigned int offset;
+ unsigned int vc_format;
} drm_radeon_tcl_prim_t;
-static void radeon_cp_dispatch_vertex( drm_device_t *dev,
- drm_buf_t *buf,
- drm_radeon_tcl_prim_t *prim )
-
+static void radeon_cp_dispatch_vertex(drm_device_t * dev,
+ drm_buf_t * buf,
+ drm_radeon_tcl_prim_t * prim)
{
drm_radeon_private_t *dev_priv = dev->dev_private;
drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
@@ -1337,45 +1372,39 @@ static void radeon_cp_dispatch_vertex( drm_device_t *dev,
DRM_DEBUG("hwprim 0x%x vfmt 0x%x %d..%d %d verts\n",
prim->prim,
- prim->vc_format,
- prim->start,
- prim->finish,
- prim->numverts);
+ prim->vc_format, prim->start, prim->finish, prim->numverts);
- if (bad_prim_vertex_nr( prim->prim, prim->numverts )) {
- DRM_ERROR( "bad prim %x numverts %d\n",
- prim->prim, prim->numverts );
+ if (bad_prim_vertex_nr(prim->prim, prim->numverts)) {
+ DRM_ERROR("bad prim %x numverts %d\n",
+ prim->prim, prim->numverts);
return;
}
do {
/* Emit the next cliprect */
- if ( i < nbox ) {
- radeon_emit_clip_rect( dev_priv,
- &sarea_priv->boxes[i] );
+ if (i < nbox) {
+ radeon_emit_clip_rect(dev_priv, &sarea_priv->boxes[i]);
}
/* Emit the vertex buffer rendering commands */
- BEGIN_RING( 5 );
+ BEGIN_RING(5);
- OUT_RING( CP_PACKET3( RADEON_3D_RNDR_GEN_INDX_PRIM, 3 ) );
- OUT_RING( offset );
- OUT_RING( numverts );
- OUT_RING( prim->vc_format );
- OUT_RING( prim->prim | RADEON_PRIM_WALK_LIST |
- RADEON_COLOR_ORDER_RGBA |
- RADEON_VTX_FMT_RADEON_MODE |
- (numverts << RADEON_NUM_VERTICES_SHIFT) );
+ OUT_RING(CP_PACKET3(RADEON_3D_RNDR_GEN_INDX_PRIM, 3));
+ OUT_RING(offset);
+ OUT_RING(numverts);
+ OUT_RING(prim->vc_format);
+ OUT_RING(prim->prim | RADEON_PRIM_WALK_LIST |
+ RADEON_COLOR_ORDER_RGBA |
+ RADEON_VTX_FMT_RADEON_MODE |
+ (numverts << RADEON_NUM_VERTICES_SHIFT));
ADVANCE_RING();
i++;
- } while ( i < nbox );
+ } while (i < nbox);
}
-
-
-static void radeon_cp_discard_buffer( drm_device_t *dev, drm_buf_t *buf )
+static void radeon_cp_discard_buffer(drm_device_t * dev, drm_buf_t * buf)
{
drm_radeon_private_t *dev_priv = dev->dev_private;
drm_radeon_buf_priv_t *buf_priv = buf->dev_private;
@@ -1384,24 +1413,22 @@ static void radeon_cp_discard_buffer( drm_device_t *dev, drm_buf_t *buf )
buf_priv->age = ++dev_priv->sarea_priv->last_dispatch;
/* Emit the vertex buffer age */
- BEGIN_RING( 2 );
- RADEON_DISPATCH_AGE( buf_priv->age );
+ BEGIN_RING(2);
+ RADEON_DISPATCH_AGE(buf_priv->age);
ADVANCE_RING();
buf->pending = 1;
buf->used = 0;
}
-static void radeon_cp_dispatch_indirect( drm_device_t *dev,
- drm_buf_t *buf,
- int start, int end )
+static void radeon_cp_dispatch_indirect(drm_device_t * dev,
+ drm_buf_t * buf, int start, int end)
{
drm_radeon_private_t *dev_priv = dev->dev_private;
RING_LOCALS;
- DRM_DEBUG( "indirect: buf=%d s=0x%x e=0x%x\n",
- buf->idx, start, end );
+ DRM_DEBUG("indirect: buf=%d s=0x%x e=0x%x\n", buf->idx, start, end);
- if ( start != end ) {
+ if (start != end) {
int offset = (dev_priv->gart_buffers_offset
+ buf->offset + start);
int dwords = (end - start + 3) / sizeof(u32);
@@ -1410,28 +1437,27 @@ static void radeon_cp_dispatch_indirect( drm_device_t *dev,
* dwords, so if we've been given an odd number we must
* pad the data with a Type-2 CP packet.
*/
- if ( dwords & 1 ) {
+ if (dwords & 1) {
u32 *data = (u32 *)
- ((char *)dev->agp_buffer_map->handle
- + buf->offset + start);
+ ((char *)dev->agp_buffer_map->handle
+ + buf->offset + start);
data[dwords++] = RADEON_CP_PACKET2;
}
/* Fire off the indirect buffer */
- BEGIN_RING( 3 );
+ BEGIN_RING(3);
- OUT_RING( CP_PACKET0( RADEON_CP_IB_BASE, 1 ) );
- OUT_RING( offset );
- OUT_RING( dwords );
+ OUT_RING(CP_PACKET0(RADEON_CP_IB_BASE, 1));
+ OUT_RING(offset);
+ OUT_RING(dwords);
ADVANCE_RING();
}
}
-
-static void radeon_cp_dispatch_indices( drm_device_t *dev,
- drm_buf_t *elt_buf,
- drm_radeon_tcl_prim_t *prim )
+static void radeon_cp_dispatch_indices(drm_device_t * dev,
+ drm_buf_t * elt_buf,
+ drm_radeon_tcl_prim_t * prim)
{
drm_radeon_private_t *dev_priv = dev->dev_private;
drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
@@ -1446,30 +1472,24 @@ static void radeon_cp_dispatch_indices( drm_device_t *dev,
DRM_DEBUG("hwprim 0x%x vfmt 0x%x %d..%d offset: %x nr %d\n",
prim->prim,
prim->vc_format,
- prim->start,
- prim->finish,
- prim->offset,
- prim->numverts);
-
- if (bad_prim_vertex_nr( prim->prim, count )) {
- DRM_ERROR( "bad prim %x count %d\n",
- prim->prim, count );
+ prim->start, prim->finish, prim->offset, prim->numverts);
+
+ if (bad_prim_vertex_nr(prim->prim, count)) {
+ DRM_ERROR("bad prim %x count %d\n", prim->prim, count);
return;
}
-
- if ( start >= prim->finish ||
- (prim->start & 0x7) ) {
- DRM_ERROR( "buffer prim %d\n", prim->prim );
+ if (start >= prim->finish || (prim->start & 0x7)) {
+ DRM_ERROR("buffer prim %d\n", prim->prim);
return;
}
dwords = (prim->finish - prim->start + 3) / sizeof(u32);
- data = (u32 *)((char *)dev->agp_buffer_map->handle +
- elt_buf->offset + prim->start);
+ data = (u32 *) ((char *)dev->agp_buffer_map->handle +
+ elt_buf->offset + prim->start);
- data[0] = CP_PACKET3( RADEON_3D_RNDR_GEN_INDX_PRIM, dwords-2 );
+ data[0] = CP_PACKET3(RADEON_3D_RNDR_GEN_INDX_PRIM, dwords - 2);
data[1] = offset;
data[2] = prim->numverts;
data[3] = prim->vc_format;
@@ -1477,28 +1497,26 @@ static void radeon_cp_dispatch_indices( drm_device_t *dev,
RADEON_PRIM_WALK_IND |
RADEON_COLOR_ORDER_RGBA |
RADEON_VTX_FMT_RADEON_MODE |
- (count << RADEON_NUM_VERTICES_SHIFT) );
+ (count << RADEON_NUM_VERTICES_SHIFT));
do {
- if ( i < nbox )
- radeon_emit_clip_rect( dev_priv,
- &sarea_priv->boxes[i] );
+ if (i < nbox)
+ radeon_emit_clip_rect(dev_priv, &sarea_priv->boxes[i]);
- radeon_cp_dispatch_indirect( dev, elt_buf,
- prim->start,
- prim->finish );
+ radeon_cp_dispatch_indirect(dev, elt_buf,
+ prim->start, prim->finish);
i++;
- } while ( i < nbox );
+ } while (i < nbox);
}
#define RADEON_MAX_TEXTURE_SIZE RADEON_BUFFER_SIZE
-static int radeon_cp_dispatch_texture( DRMFILE filp,
- drm_device_t *dev,
- drm_radeon_texture_t *tex,
- drm_radeon_tex_image_t *image )
+static int radeon_cp_dispatch_texture(DRMFILE filp,
+ drm_device_t * dev,
+ drm_radeon_texture_t * tex,
+ drm_radeon_tex_image_t * image)
{
drm_radeon_private_t *dev_priv = dev->dev_private;
drm_file_t *filp_priv;
@@ -1513,11 +1531,11 @@ static int radeon_cp_dispatch_texture( DRMFILE filp,
u32 offset;
RING_LOCALS;
- DRM_GET_PRIV_WITH_RETURN( filp_priv, filp );
+ DRM_GET_PRIV_WITH_RETURN(filp_priv, filp);
- if ( radeon_check_and_fixup_offset( dev_priv, filp_priv, &tex->offset ) ) {
- DRM_ERROR( "Invalid destination offset\n" );
- return DRM_ERR( EINVAL );
+ if (radeon_check_and_fixup_offset(dev_priv, filp_priv, &tex->offset)) {
+ DRM_ERROR("Invalid destination offset\n");
+ return DRM_ERR(EINVAL);
}
dev_priv->stats.boxes |= RADEON_BOX_TEXTURE_LOAD;
@@ -1526,7 +1544,7 @@ static int radeon_cp_dispatch_texture( DRMFILE filp,
* up with the texture data from the host data blit, otherwise
* part of the texture image may be corrupted.
*/
- BEGIN_RING( 4 );
+ BEGIN_RING(4);
RADEON_FLUSH_CACHE();
RADEON_WAIT_UNTIL_IDLE();
ADVANCE_RING();
@@ -1535,7 +1553,7 @@ static int radeon_cp_dispatch_texture( DRMFILE filp,
* even if the only legal values are powers of two. Thus, we'll
* use a shift instead.
*/
- switch ( tex->format ) {
+ switch (tex->format) {
case RADEON_TXFORMAT_ARGB8888:
case RADEON_TXFORMAT_RGBA8888:
format = RADEON_COLOR_FORMAT_ARGB8888;
@@ -1559,7 +1577,7 @@ static int radeon_cp_dispatch_texture( DRMFILE filp,
blit_width = image->width * 1;
break;
default:
- DRM_ERROR( "invalid texture format %d\n", tex->format );
+ DRM_ERROR("invalid texture format %d\n", tex->format);
return DRM_ERR(EINVAL);
}
spitch = blit_width >> 6;
@@ -1574,49 +1592,49 @@ static int radeon_cp_dispatch_texture( DRMFILE filp,
/* we got tiled coordinates, untile them */
image->x *= 2;
}
- }
- else microtile = 0;
+ } else
+ microtile = 0;
- DRM_DEBUG("tex=%dx%d blit=%d\n", tex_width, tex->height, blit_width );
+ DRM_DEBUG("tex=%dx%d blit=%d\n", tex_width, tex->height, blit_width);
do {
- DRM_DEBUG( "tex: ofs=0x%x p=%d f=%d x=%hd y=%hd w=%hd h=%hd\n",
- tex->offset >> 10, tex->pitch, tex->format,
- image->x, image->y, image->width, image->height );
+ DRM_DEBUG("tex: ofs=0x%x p=%d f=%d x=%hd y=%hd w=%hd h=%hd\n",
+ tex->offset >> 10, tex->pitch, tex->format,
+ image->x, image->y, image->width, image->height);
/* Make a copy of some parameters in case we have to
* update them for a multi-pass texture blit.
*/
height = image->height;
data = (const u8 __user *)image->data;
-
+
size = height * blit_width;
- if ( size > RADEON_MAX_TEXTURE_SIZE ) {
+ if (size > RADEON_MAX_TEXTURE_SIZE) {
height = RADEON_MAX_TEXTURE_SIZE / blit_width;
size = height * blit_width;
- } else if ( size < 4 && size > 0 ) {
+ } else if (size < 4 && size > 0) {
size = 4;
- } else if ( size == 0 ) {
+ } else if (size == 0) {
return 0;
}
- buf = radeon_freelist_get( dev );
- if ( 0 && !buf ) {
- radeon_do_cp_idle( dev_priv );
- buf = radeon_freelist_get( dev );
+ buf = radeon_freelist_get(dev);
+ if (0 && !buf) {
+ radeon_do_cp_idle(dev_priv);
+ buf = radeon_freelist_get(dev);
}
- if ( !buf ) {
+ if (!buf) {
DRM_DEBUG("radeon_cp_dispatch_texture: EAGAIN\n");
- if (DRM_COPY_TO_USER( tex->image, image, sizeof(*image) ))
+ if (DRM_COPY_TO_USER(tex->image, image, sizeof(*image)))
return DRM_ERR(EFAULT);
return DRM_ERR(EAGAIN);
}
-
/* Dispatch the indirect buffer.
*/
- buffer = (u32*)((char*)dev->agp_buffer_map->handle + buf->offset);
+ buffer =
+ (u32 *) ((char *)dev->agp_buffer_map->handle + buf->offset);
dwords = size / 4;
if (microtile) {
@@ -1631,20 +1649,26 @@ static int radeon_cp_dispatch_texture( DRMFILE filp,
if (tex->height == 1) {
if (tex_width >= 64 || tex_width <= 16) {
if (DRM_COPY_FROM_USER(buffer, data,
- tex_width * sizeof(u32))) {
- DRM_ERROR("EFAULT on pad, %d bytes\n",
- tex_width);
+ tex_width *
+ sizeof(u32))) {
+ DRM_ERROR
+ ("EFAULT on pad, %d bytes\n",
+ tex_width);
return DRM_ERR(EFAULT);
}
} else if (tex_width == 32) {
- if (DRM_COPY_FROM_USER(buffer, data, 16)) {
- DRM_ERROR("EFAULT on pad, %d bytes\n",
- tex_width);
+ if (DRM_COPY_FROM_USER
+ (buffer, data, 16)) {
+ DRM_ERROR
+ ("EFAULT on pad, %d bytes\n",
+ tex_width);
return DRM_ERR(EFAULT);
}
- if (DRM_COPY_FROM_USER(buffer + 8, data + 16, 16)) {
- DRM_ERROR("EFAULT on pad, %d bytes\n",
- tex_width);
+ if (DRM_COPY_FROM_USER
+ (buffer + 8, data + 16, 16)) {
+ DRM_ERROR
+ ("EFAULT on pad, %d bytes\n",
+ tex_width);
return DRM_ERR(EFAULT);
}
}
@@ -1657,9 +1681,11 @@ static int radeon_cp_dispatch_texture( DRMFILE filp,
}
} else if (tex_width < 16) {
for (i = 0; i < tex->height; i++) {
- if (DRM_COPY_FROM_USER(buffer, data, tex_width)) {
- DRM_ERROR("EFAULT on pad, %d bytes\n",
- tex_width);
+ if (DRM_COPY_FROM_USER
+ (buffer, data, tex_width)) {
+ DRM_ERROR
+ ("EFAULT on pad, %d bytes\n",
+ tex_width);
return DRM_ERR(EFAULT);
}
buffer += 4;
@@ -1669,35 +1695,42 @@ static int radeon_cp_dispatch_texture( DRMFILE filp,
/* TODO: make sure this works when not fitting in one buffer
(i.e. 32bytes x 2048...) */
for (i = 0; i < tex->height; i += 2) {
- if (DRM_COPY_FROM_USER(buffer, data, 16)) {
- DRM_ERROR("EFAULT on pad, %d bytes\n",
- tex_width);
+ if (DRM_COPY_FROM_USER
+ (buffer, data, 16)) {
+ DRM_ERROR
+ ("EFAULT on pad, %d bytes\n",
+ tex_width);
return DRM_ERR(EFAULT);
}
data += 16;
- if (DRM_COPY_FROM_USER(buffer + 8, data, 16)) {
- DRM_ERROR("EFAULT on pad, %d bytes\n",
- tex_width);
+ if (DRM_COPY_FROM_USER
+ (buffer + 8, data, 16)) {
+ DRM_ERROR
+ ("EFAULT on pad, %d bytes\n",
+ tex_width);
return DRM_ERR(EFAULT);
}
data += 16;
- if (DRM_COPY_FROM_USER(buffer + 4, data, 16)) {
- DRM_ERROR("EFAULT on pad, %d bytes\n",
- tex_width);
+ if (DRM_COPY_FROM_USER
+ (buffer + 4, data, 16)) {
+ DRM_ERROR
+ ("EFAULT on pad, %d bytes\n",
+ tex_width);
return DRM_ERR(EFAULT);
}
data += 16;
- if (DRM_COPY_FROM_USER(buffer + 12, data, 16)) {
- DRM_ERROR("EFAULT on pad, %d bytes\n",
- tex_width);
+ if (DRM_COPY_FROM_USER
+ (buffer + 12, data, 16)) {
+ DRM_ERROR
+ ("EFAULT on pad, %d bytes\n",
+ tex_width);
return DRM_ERR(EFAULT);
}
data += 16;
buffer += 16;
}
}
- }
- else {
+ } else {
if (tex_width >= 32) {
/* Texture image width is larger than the minimum, so we
* can upload it directly.
@@ -1713,9 +1746,12 @@ static int radeon_cp_dispatch_texture( DRMFILE filp,
* need to pad out each image scanline to the minimum
* width.
*/
- for (i = 0 ; i < tex->height ; i++) {
- if (DRM_COPY_FROM_USER(buffer, data, tex_width )) {
- DRM_ERROR("EFAULT on pad, %d bytes\n", tex_width);
+ for (i = 0; i < tex->height; i++) {
+ if (DRM_COPY_FROM_USER
+ (buffer, data, tex_width)) {
+ DRM_ERROR
+ ("EFAULT on pad, %d bytes\n",
+ tex_width);
return DRM_ERR(EFAULT);
}
buffer += 8;
@@ -1736,8 +1772,7 @@ static int radeon_cp_dispatch_texture( DRMFILE filp,
RADEON_GMC_SRC_DATATYPE_COLOR |
RADEON_ROP3_S |
RADEON_DP_SRC_SOURCE_MEMORY |
- RADEON_GMC_CLR_CMP_CNTL_DIS |
- RADEON_GMC_WR_MSK_DIS );
+ RADEON_GMC_CLR_CMP_CNTL_DIS | RADEON_GMC_WR_MSK_DIS);
OUT_RING((spitch << 22) | (offset >> 10));
OUT_RING((texpitch << 22) | (tex->offset >> 10));
OUT_RING(0);
@@ -1758,62 +1793,62 @@ static int radeon_cp_dispatch_texture( DRMFILE filp,
* the texture data is written out to memory before rendering
* continues.
*/
- BEGIN_RING( 4 );
+ BEGIN_RING(4);
RADEON_FLUSH_CACHE();
RADEON_WAIT_UNTIL_2D_IDLE();
ADVANCE_RING();
return 0;
}
-
-static void radeon_cp_dispatch_stipple( drm_device_t *dev, u32 *stipple )
+static void radeon_cp_dispatch_stipple(drm_device_t * dev, u32 * stipple)
{
drm_radeon_private_t *dev_priv = dev->dev_private;
int i;
RING_LOCALS;
- DRM_DEBUG( "\n" );
+ DRM_DEBUG("\n");
- BEGIN_RING( 35 );
+ BEGIN_RING(35);
- OUT_RING( CP_PACKET0( RADEON_RE_STIPPLE_ADDR, 0 ) );
- OUT_RING( 0x00000000 );
+ OUT_RING(CP_PACKET0(RADEON_RE_STIPPLE_ADDR, 0));
+ OUT_RING(0x00000000);
- OUT_RING( CP_PACKET0_TABLE( RADEON_RE_STIPPLE_DATA, 31 ) );
- for ( i = 0 ; i < 32 ; i++ ) {
- OUT_RING( stipple[i] );
+ OUT_RING(CP_PACKET0_TABLE(RADEON_RE_STIPPLE_DATA, 31));
+ for (i = 0; i < 32; i++) {
+ OUT_RING(stipple[i]);
}
ADVANCE_RING();
}
-static void radeon_apply_surface_regs(int surf_index, drm_radeon_private_t *dev_priv)
+static void radeon_apply_surface_regs(int surf_index,
+ drm_radeon_private_t * dev_priv)
{
if (!dev_priv->mmio)
return;
radeon_do_cp_idle(dev_priv);
- RADEON_WRITE(RADEON_SURFACE0_INFO + 16*surf_index,
- dev_priv->surfaces[surf_index].flags);
- RADEON_WRITE(RADEON_SURFACE0_LOWER_BOUND + 16*surf_index,
- dev_priv->surfaces[surf_index].lower);
- RADEON_WRITE(RADEON_SURFACE0_UPPER_BOUND + 16*surf_index,
- dev_priv->surfaces[surf_index].upper);
+ RADEON_WRITE(RADEON_SURFACE0_INFO + 16 * surf_index,
+ dev_priv->surfaces[surf_index].flags);
+ RADEON_WRITE(RADEON_SURFACE0_LOWER_BOUND + 16 * surf_index,
+ dev_priv->surfaces[surf_index].lower);
+ RADEON_WRITE(RADEON_SURFACE0_UPPER_BOUND + 16 * surf_index,
+ dev_priv->surfaces[surf_index].upper);
}
-
/* Allocates a virtual surface
- * doesn't always allocate a real surface, will stretch an existing
+ * doesn't always allocate a real surface, will stretch an existing
* surface when possible.
*
* Note that refcount can be at most 2, since during a free refcount=3
* might mean we have to allocate a new surface which might not always
* be available.
- * For example : we allocate three contigous surfaces ABC. If B is
+ * For example : we allocate three contigous surfaces ABC. If B is
* freed, we suddenly need two surfaces to store A and C, which might
* not always be available.
*/
-static int alloc_surface(drm_radeon_surface_alloc_t* new, drm_radeon_private_t *dev_priv, DRMFILE filp)
+static int alloc_surface(drm_radeon_surface_alloc_t * new,
+ drm_radeon_private_t * dev_priv, DRMFILE filp)
{
struct radeon_virt_surface *s;
int i;
@@ -1825,34 +1860,37 @@ static int alloc_surface(drm_radeon_surface_alloc_t* new, drm_radeon_private_t *
/* sanity check */
if ((new_lower >= new_upper) || (new->flags == 0) || (new->size == 0) ||
- ((new_upper & RADEON_SURF_ADDRESS_FIXED_MASK) != RADEON_SURF_ADDRESS_FIXED_MASK) ||
- ((new_lower & RADEON_SURF_ADDRESS_FIXED_MASK) != 0))
+ ((new_upper & RADEON_SURF_ADDRESS_FIXED_MASK) !=
+ RADEON_SURF_ADDRESS_FIXED_MASK)
+ || ((new_lower & RADEON_SURF_ADDRESS_FIXED_MASK) != 0))
return -1;
/* make sure there is no overlap with existing surfaces */
for (i = 0; i < RADEON_MAX_SURFACES; i++) {
if ((dev_priv->surfaces[i].refcount != 0) &&
- (( (new_lower >= dev_priv->surfaces[i].lower) &&
- (new_lower < dev_priv->surfaces[i].upper) ) ||
- ( (new_lower < dev_priv->surfaces[i].lower) &&
- (new_upper > dev_priv->surfaces[i].lower) )) ){
- return -1;}
+ (((new_lower >= dev_priv->surfaces[i].lower) &&
+ (new_lower < dev_priv->surfaces[i].upper)) ||
+ ((new_lower < dev_priv->surfaces[i].lower) &&
+ (new_upper > dev_priv->surfaces[i].lower)))) {
+ return -1;
+ }
}
/* find a virtual surface */
- for (i = 0; i < 2*RADEON_MAX_SURFACES; i++)
+ for (i = 0; i < 2 * RADEON_MAX_SURFACES; i++)
if (dev_priv->virt_surfaces[i].filp == 0)
break;
- if (i == 2*RADEON_MAX_SURFACES) {
- return -1;}
+ if (i == 2 * RADEON_MAX_SURFACES) {
+ return -1;
+ }
virt_surface_index = i;
/* try to reuse an existing surface */
for (i = 0; i < RADEON_MAX_SURFACES; i++) {
/* extend before */
if ((dev_priv->surfaces[i].refcount == 1) &&
- (new->flags == dev_priv->surfaces[i].flags) &&
- (new_upper + 1 == dev_priv->surfaces[i].lower)) {
+ (new->flags == dev_priv->surfaces[i].flags) &&
+ (new_upper + 1 == dev_priv->surfaces[i].lower)) {
s = &(dev_priv->virt_surfaces[virt_surface_index]);
s->surface_index = i;
s->lower = new_lower;
@@ -1867,8 +1905,8 @@ static int alloc_surface(drm_radeon_surface_alloc_t* new, drm_radeon_private_t *
/* extend after */
if ((dev_priv->surfaces[i].refcount == 1) &&
- (new->flags == dev_priv->surfaces[i].flags) &&
- (new_lower == dev_priv->surfaces[i].upper + 1)) {
+ (new->flags == dev_priv->surfaces[i].flags) &&
+ (new_lower == dev_priv->surfaces[i].upper + 1)) {
s = &(dev_priv->virt_surfaces[virt_surface_index]);
s->surface_index = i;
s->lower = new_lower;
@@ -1904,26 +1942,34 @@ static int alloc_surface(drm_radeon_surface_alloc_t* new, drm_radeon_private_t *
return -1;
}
-static int free_surface(DRMFILE filp, drm_radeon_private_t *dev_priv, int lower)
+static int free_surface(DRMFILE filp, drm_radeon_private_t * dev_priv,
+ int lower)
{
struct radeon_virt_surface *s;
int i;
/* find the virtual surface */
- for(i = 0; i < 2*RADEON_MAX_SURFACES; i++) {
+ for (i = 0; i < 2 * RADEON_MAX_SURFACES; i++) {
s = &(dev_priv->virt_surfaces[i]);
if (s->filp) {
if ((lower == s->lower) && (filp == s->filp)) {
- if (dev_priv->surfaces[s->surface_index].lower == s->lower)
- dev_priv->surfaces[s->surface_index].lower = s->upper;
+ if (dev_priv->surfaces[s->surface_index].
+ lower == s->lower)
+ dev_priv->surfaces[s->surface_index].
+ lower = s->upper;
- if (dev_priv->surfaces[s->surface_index].upper == s->upper)
- dev_priv->surfaces[s->surface_index].upper = s->lower;
+ if (dev_priv->surfaces[s->surface_index].
+ upper == s->upper)
+ dev_priv->surfaces[s->surface_index].
+ upper = s->lower;
dev_priv->surfaces[s->surface_index].refcount--;
- if (dev_priv->surfaces[s->surface_index].refcount == 0)
- dev_priv->surfaces[s->surface_index].flags = 0;
+ if (dev_priv->surfaces[s->surface_index].
+ refcount == 0)
+ dev_priv->surfaces[s->surface_index].
+ flags = 0;
s->filp = NULL;
- radeon_apply_surface_regs(s->surface_index, dev_priv);
+ radeon_apply_surface_regs(s->surface_index,
+ dev_priv);
return 0;
}
}
@@ -1931,13 +1977,14 @@ static int free_surface(DRMFILE filp, drm_radeon_private_t *dev_priv, int lower)
return 1;
}
-static void radeon_surfaces_release(DRMFILE filp, drm_radeon_private_t *dev_priv)
+static void radeon_surfaces_release(DRMFILE filp,
+ drm_radeon_private_t * dev_priv)
{
int i;
- for( i = 0; i < 2*RADEON_MAX_SURFACES; i++)
- {
+ for (i = 0; i < 2 * RADEON_MAX_SURFACES; i++) {
if (dev_priv->virt_surfaces[i].filp == filp)
- free_surface(filp, dev_priv, dev_priv->virt_surfaces[i].lower);
+ free_surface(filp, dev_priv,
+ dev_priv->virt_surfaces[i].lower);
}
}
@@ -1951,12 +1998,13 @@ static int radeon_surface_alloc(DRM_IOCTL_ARGS)
drm_radeon_surface_alloc_t alloc;
if (!dev_priv) {
- DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
+ DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
return DRM_ERR(EINVAL);
}
- DRM_COPY_FROM_USER_IOCTL(alloc, (drm_radeon_surface_alloc_t __user *)data,
- sizeof(alloc));
+ DRM_COPY_FROM_USER_IOCTL(alloc,
+ (drm_radeon_surface_alloc_t __user *) data,
+ sizeof(alloc));
if (alloc_surface(&alloc, dev_priv, filp) == -1)
return DRM_ERR(EINVAL);
@@ -1971,12 +2019,12 @@ static int radeon_surface_free(DRM_IOCTL_ARGS)
drm_radeon_surface_free_t memfree;
if (!dev_priv) {
- DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
+ DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
return DRM_ERR(EINVAL);
}
- DRM_COPY_FROM_USER_IOCTL(memfree, (drm_radeon_mem_free_t __user *)data,
- sizeof(memfree) );
+ DRM_COPY_FROM_USER_IOCTL(memfree, (drm_radeon_mem_free_t __user *) data,
+ sizeof(memfree));
if (free_surface(filp, dev_priv, memfree.address))
return DRM_ERR(EINVAL);
@@ -1984,51 +2032,52 @@ static int radeon_surface_free(DRM_IOCTL_ARGS)
return 0;
}
-static int radeon_cp_clear( DRM_IOCTL_ARGS )
+static int radeon_cp_clear(DRM_IOCTL_ARGS)
{
DRM_DEVICE;
drm_radeon_private_t *dev_priv = dev->dev_private;
drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
drm_radeon_clear_t clear;
drm_radeon_clear_rect_t depth_boxes[RADEON_NR_SAREA_CLIPRECTS];
- DRM_DEBUG( "\n" );
+ DRM_DEBUG("\n");
- LOCK_TEST_WITH_RETURN( dev, filp );
+ LOCK_TEST_WITH_RETURN(dev, filp);
- DRM_COPY_FROM_USER_IOCTL( clear, (drm_radeon_clear_t __user *)data,
- sizeof(clear) );
+ DRM_COPY_FROM_USER_IOCTL(clear, (drm_radeon_clear_t __user *) data,
+ sizeof(clear));
- RING_SPACE_TEST_WITH_RETURN( dev_priv );
+ RING_SPACE_TEST_WITH_RETURN(dev_priv);
- if ( sarea_priv->nbox > RADEON_NR_SAREA_CLIPRECTS )
+ if (sarea_priv->nbox > RADEON_NR_SAREA_CLIPRECTS)
sarea_priv->nbox = RADEON_NR_SAREA_CLIPRECTS;
- if ( DRM_COPY_FROM_USER( &depth_boxes, clear.depth_boxes,
- sarea_priv->nbox * sizeof(depth_boxes[0]) ) )
+ if (DRM_COPY_FROM_USER(&depth_boxes, clear.depth_boxes,
+ sarea_priv->nbox * sizeof(depth_boxes[0])))
return DRM_ERR(EFAULT);
- radeon_cp_dispatch_clear( dev, &clear, depth_boxes );
+ radeon_cp_dispatch_clear(dev, &clear, depth_boxes);
COMMIT_RING();
return 0;
}
-
/* Not sure why this isn't set all the time:
- */
-static int radeon_do_init_pageflip( drm_device_t *dev )
+ */
+static int radeon_do_init_pageflip(drm_device_t * dev)
{
drm_radeon_private_t *dev_priv = dev->dev_private;
RING_LOCALS;
- DRM_DEBUG( "\n" );
+ DRM_DEBUG("\n");
- BEGIN_RING( 6 );
+ BEGIN_RING(6);
RADEON_WAIT_UNTIL_3D_IDLE();
- OUT_RING( CP_PACKET0( RADEON_CRTC_OFFSET_CNTL, 0 ) );
- OUT_RING( RADEON_READ( RADEON_CRTC_OFFSET_CNTL ) | RADEON_CRTC_OFFSET_FLIP_CNTL );
- OUT_RING( CP_PACKET0( RADEON_CRTC2_OFFSET_CNTL, 0 ) );
- OUT_RING( RADEON_READ( RADEON_CRTC2_OFFSET_CNTL ) | RADEON_CRTC_OFFSET_FLIP_CNTL );
+ OUT_RING(CP_PACKET0(RADEON_CRTC_OFFSET_CNTL, 0));
+ OUT_RING(RADEON_READ(RADEON_CRTC_OFFSET_CNTL) |
+ RADEON_CRTC_OFFSET_FLIP_CNTL);
+ OUT_RING(CP_PACKET0(RADEON_CRTC2_OFFSET_CNTL, 0));
+ OUT_RING(RADEON_READ(RADEON_CRTC2_OFFSET_CNTL) |
+ RADEON_CRTC_OFFSET_FLIP_CNTL);
ADVANCE_RING();
dev_priv->page_flipping = 1;
@@ -2041,62 +2090,62 @@ static int radeon_do_init_pageflip( drm_device_t *dev )
/* Called whenever a client dies, from drm_release.
* NOTE: Lock isn't necessarily held when this is called!
*/
-static int radeon_do_cleanup_pageflip( drm_device_t *dev )
+static int radeon_do_cleanup_pageflip(drm_device_t * dev)
{
drm_radeon_private_t *dev_priv = dev->dev_private;
- DRM_DEBUG( "\n" );
+ DRM_DEBUG("\n");
if (dev_priv->current_page != 0)
- radeon_cp_dispatch_flip( dev );
+ radeon_cp_dispatch_flip(dev);
dev_priv->page_flipping = 0;
return 0;
}
/* Swapping and flipping are different operations, need different ioctls.
- * They can & should be intermixed to support multiple 3d windows.
+ * They can & should be intermixed to support multiple 3d windows.
*/
-static int radeon_cp_flip( DRM_IOCTL_ARGS )
+static int radeon_cp_flip(DRM_IOCTL_ARGS)
{
DRM_DEVICE;
drm_radeon_private_t *dev_priv = dev->dev_private;
- DRM_DEBUG( "\n" );
+ DRM_DEBUG("\n");
+
+ LOCK_TEST_WITH_RETURN(dev, filp);
- LOCK_TEST_WITH_RETURN( dev, filp );
+ RING_SPACE_TEST_WITH_RETURN(dev_priv);
- RING_SPACE_TEST_WITH_RETURN( dev_priv );
+ if (!dev_priv->page_flipping)
+ radeon_do_init_pageflip(dev);
- if (!dev_priv->page_flipping)
- radeon_do_init_pageflip( dev );
-
- radeon_cp_dispatch_flip( dev );
+ radeon_cp_dispatch_flip(dev);
COMMIT_RING();
return 0;
}
-static int radeon_cp_swap( DRM_IOCTL_ARGS )
+static int radeon_cp_swap(DRM_IOCTL_ARGS)
{
DRM_DEVICE;
drm_radeon_private_t *dev_priv = dev->dev_private;
drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
- DRM_DEBUG( "\n" );
+ DRM_DEBUG("\n");
- LOCK_TEST_WITH_RETURN( dev, filp );
+ LOCK_TEST_WITH_RETURN(dev, filp);
- RING_SPACE_TEST_WITH_RETURN( dev_priv );
+ RING_SPACE_TEST_WITH_RETURN(dev_priv);
- if ( sarea_priv->nbox > RADEON_NR_SAREA_CLIPRECTS )
+ if (sarea_priv->nbox > RADEON_NR_SAREA_CLIPRECTS)
sarea_priv->nbox = RADEON_NR_SAREA_CLIPRECTS;
- radeon_cp_dispatch_swap( dev );
+ radeon_cp_dispatch_swap(dev);
dev_priv->sarea_priv->ctx_owner = 0;
COMMIT_RING();
return 0;
}
-static int radeon_cp_vertex( DRM_IOCTL_ARGS )
+static int radeon_cp_vertex(DRM_IOCTL_ARGS)
{
DRM_DEVICE;
drm_radeon_private_t *dev_priv = dev->dev_private;
@@ -2107,55 +2156,53 @@ static int radeon_cp_vertex( DRM_IOCTL_ARGS )
drm_radeon_vertex_t vertex;
drm_radeon_tcl_prim_t prim;
- LOCK_TEST_WITH_RETURN( dev, filp );
+ LOCK_TEST_WITH_RETURN(dev, filp);
- DRM_GET_PRIV_WITH_RETURN( filp_priv, filp );
+ DRM_GET_PRIV_WITH_RETURN(filp_priv, filp);
- DRM_COPY_FROM_USER_IOCTL( vertex, (drm_radeon_vertex_t __user *)data,
- sizeof(vertex) );
+ DRM_COPY_FROM_USER_IOCTL(vertex, (drm_radeon_vertex_t __user *) data,
+ sizeof(vertex));
- DRM_DEBUG( "pid=%d index=%d count=%d discard=%d\n",
- DRM_CURRENTPID,
- vertex.idx, vertex.count, vertex.discard );
+ DRM_DEBUG("pid=%d index=%d count=%d discard=%d\n",
+ DRM_CURRENTPID, vertex.idx, vertex.count, vertex.discard);
- if ( vertex.idx < 0 || vertex.idx >= dma->buf_count ) {
- DRM_ERROR( "buffer index %d (of %d max)\n",
- vertex.idx, dma->buf_count - 1 );
+ if (vertex.idx < 0 || vertex.idx >= dma->buf_count) {
+ DRM_ERROR("buffer index %d (of %d max)\n",
+ vertex.idx, dma->buf_count - 1);
return DRM_ERR(EINVAL);
}
- if ( vertex.prim < 0 ||
- vertex.prim > RADEON_PRIM_TYPE_3VRT_LINE_LIST ) {
- DRM_ERROR( "buffer prim %d\n", vertex.prim );
+ if (vertex.prim < 0 || vertex.prim > RADEON_PRIM_TYPE_3VRT_LINE_LIST) {
+ DRM_ERROR("buffer prim %d\n", vertex.prim);
return DRM_ERR(EINVAL);
}
- RING_SPACE_TEST_WITH_RETURN( dev_priv );
- VB_AGE_TEST_WITH_RETURN( dev_priv );
+ RING_SPACE_TEST_WITH_RETURN(dev_priv);
+ VB_AGE_TEST_WITH_RETURN(dev_priv);
buf = dma->buflist[vertex.idx];
- if ( buf->filp != filp ) {
- DRM_ERROR( "process %d using buffer owned by %p\n",
- DRM_CURRENTPID, buf->filp );
+ if (buf->filp != filp) {
+ DRM_ERROR("process %d using buffer owned by %p\n",
+ DRM_CURRENTPID, buf->filp);
return DRM_ERR(EINVAL);
}
- if ( buf->pending ) {
- DRM_ERROR( "sending pending buffer %d\n", vertex.idx );
+ if (buf->pending) {
+ DRM_ERROR("sending pending buffer %d\n", vertex.idx);
return DRM_ERR(EINVAL);
}
/* Build up a prim_t record:
*/
if (vertex.count) {
- buf->used = vertex.count; /* not used? */
-
- if ( sarea_priv->dirty & ~RADEON_UPLOAD_CLIPRECTS ) {
- if ( radeon_emit_state( dev_priv, filp_priv,
- &sarea_priv->context_state,
- sarea_priv->tex_state,
- sarea_priv->dirty ) ) {
- DRM_ERROR( "radeon_emit_state failed\n" );
- return DRM_ERR( EINVAL );
+ buf->used = vertex.count; /* not used? */
+
+ if (sarea_priv->dirty & ~RADEON_UPLOAD_CLIPRECTS) {
+ if (radeon_emit_state(dev_priv, filp_priv,
+ &sarea_priv->context_state,
+ sarea_priv->tex_state,
+ sarea_priv->dirty)) {
+ DRM_ERROR("radeon_emit_state failed\n");
+ return DRM_ERR(EINVAL);
}
sarea_priv->dirty &= ~(RADEON_UPLOAD_TEX0IMAGES |
@@ -2165,23 +2212,23 @@ static int radeon_cp_vertex( DRM_IOCTL_ARGS )
}
prim.start = 0;
- prim.finish = vertex.count; /* unused */
+ prim.finish = vertex.count; /* unused */
prim.prim = vertex.prim;
prim.numverts = vertex.count;
prim.vc_format = dev_priv->sarea_priv->vc_format;
-
- radeon_cp_dispatch_vertex( dev, buf, &prim );
+
+ radeon_cp_dispatch_vertex(dev, buf, &prim);
}
if (vertex.discard) {
- radeon_cp_discard_buffer( dev, buf );
+ radeon_cp_discard_buffer(dev, buf);
}
COMMIT_RING();
return 0;
}
-static int radeon_cp_indices( DRM_IOCTL_ARGS )
+static int radeon_cp_indices(DRM_IOCTL_ARGS)
{
DRM_DEVICE;
drm_radeon_private_t *dev_priv = dev->dev_private;
@@ -2193,69 +2240,67 @@ static int radeon_cp_indices( DRM_IOCTL_ARGS )
drm_radeon_tcl_prim_t prim;
int count;
- LOCK_TEST_WITH_RETURN( dev, filp );
+ LOCK_TEST_WITH_RETURN(dev, filp);
- if ( !dev_priv ) {
- DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
+ if (!dev_priv) {
+ DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
return DRM_ERR(EINVAL);
}
- DRM_GET_PRIV_WITH_RETURN( filp_priv, filp );
+ DRM_GET_PRIV_WITH_RETURN(filp_priv, filp);
- DRM_COPY_FROM_USER_IOCTL( elts, (drm_radeon_indices_t __user *)data,
- sizeof(elts) );
+ DRM_COPY_FROM_USER_IOCTL(elts, (drm_radeon_indices_t __user *) data,
+ sizeof(elts));
- DRM_DEBUG( "pid=%d index=%d start=%d end=%d discard=%d\n",
- DRM_CURRENTPID,
- elts.idx, elts.start, elts.end, elts.discard );
+ DRM_DEBUG("pid=%d index=%d start=%d end=%d discard=%d\n",
+ DRM_CURRENTPID, elts.idx, elts.start, elts.end, elts.discard);
- if ( elts.idx < 0 || elts.idx >= dma->buf_count ) {
- DRM_ERROR( "buffer index %d (of %d max)\n",
- elts.idx, dma->buf_count - 1 );
+ if (elts.idx < 0 || elts.idx >= dma->buf_count) {
+ DRM_ERROR("buffer index %d (of %d max)\n",
+ elts.idx, dma->buf_count - 1);
return DRM_ERR(EINVAL);
}
- if ( elts.prim < 0 ||
- elts.prim > RADEON_PRIM_TYPE_3VRT_LINE_LIST ) {
- DRM_ERROR( "buffer prim %d\n", elts.prim );
+ if (elts.prim < 0 || elts.prim > RADEON_PRIM_TYPE_3VRT_LINE_LIST) {
+ DRM_ERROR("buffer prim %d\n", elts.prim);
return DRM_ERR(EINVAL);
}
- RING_SPACE_TEST_WITH_RETURN( dev_priv );
- VB_AGE_TEST_WITH_RETURN( dev_priv );
+ RING_SPACE_TEST_WITH_RETURN(dev_priv);
+ VB_AGE_TEST_WITH_RETURN(dev_priv);
buf = dma->buflist[elts.idx];
- if ( buf->filp != filp ) {
- DRM_ERROR( "process %d using buffer owned by %p\n",
- DRM_CURRENTPID, buf->filp );
+ if (buf->filp != filp) {
+ DRM_ERROR("process %d using buffer owned by %p\n",
+ DRM_CURRENTPID, buf->filp);
return DRM_ERR(EINVAL);
}
- if ( buf->pending ) {
- DRM_ERROR( "sending pending buffer %d\n", elts.idx );
+ if (buf->pending) {
+ DRM_ERROR("sending pending buffer %d\n", elts.idx);
return DRM_ERR(EINVAL);
}
count = (elts.end - elts.start) / sizeof(u16);
elts.start -= RADEON_INDEX_PRIM_OFFSET;
- if ( elts.start & 0x7 ) {
- DRM_ERROR( "misaligned buffer 0x%x\n", elts.start );
+ if (elts.start & 0x7) {
+ DRM_ERROR("misaligned buffer 0x%x\n", elts.start);
return DRM_ERR(EINVAL);
}
- if ( elts.start < buf->used ) {
- DRM_ERROR( "no header 0x%x - 0x%x\n", elts.start, buf->used );
+ if (elts.start < buf->used) {
+ DRM_ERROR("no header 0x%x - 0x%x\n", elts.start, buf->used);
return DRM_ERR(EINVAL);
}
buf->used = elts.end;
- if ( sarea_priv->dirty & ~RADEON_UPLOAD_CLIPRECTS ) {
- if ( radeon_emit_state( dev_priv, filp_priv,
- &sarea_priv->context_state,
- sarea_priv->tex_state,
- sarea_priv->dirty ) ) {
- DRM_ERROR( "radeon_emit_state failed\n" );
- return DRM_ERR( EINVAL );
+ if (sarea_priv->dirty & ~RADEON_UPLOAD_CLIPRECTS) {
+ if (radeon_emit_state(dev_priv, filp_priv,
+ &sarea_priv->context_state,
+ sarea_priv->tex_state,
+ sarea_priv->dirty)) {
+ DRM_ERROR("radeon_emit_state failed\n");
+ return DRM_ERR(EINVAL);
}
sarea_priv->dirty &= ~(RADEON_UPLOAD_TEX0IMAGES |
@@ -2264,26 +2309,25 @@ static int radeon_cp_indices( DRM_IOCTL_ARGS )
RADEON_REQUIRE_QUIESCENCE);
}
-
/* Build up a prim_t record:
*/
prim.start = elts.start;
- prim.finish = elts.end;
+ prim.finish = elts.end;
prim.prim = elts.prim;
prim.offset = 0; /* offset from start of dma buffers */
- prim.numverts = RADEON_MAX_VB_VERTS; /* duh */
+ prim.numverts = RADEON_MAX_VB_VERTS; /* duh */
prim.vc_format = dev_priv->sarea_priv->vc_format;
-
- radeon_cp_dispatch_indices( dev, buf, &prim );
+
+ radeon_cp_dispatch_indices(dev, buf, &prim);
if (elts.discard) {
- radeon_cp_discard_buffer( dev, buf );
+ radeon_cp_discard_buffer(dev, buf);
}
COMMIT_RING();
return 0;
}
-static int radeon_cp_texture( DRM_IOCTL_ARGS )
+static int radeon_cp_texture(DRM_IOCTL_ARGS)
{
DRM_DEVICE;
drm_radeon_private_t *dev_priv = dev->dev_private;
@@ -2291,53 +2335,54 @@ static int radeon_cp_texture( DRM_IOCTL_ARGS )
drm_radeon_tex_image_t image;
int ret;
- LOCK_TEST_WITH_RETURN( dev, filp );
+ LOCK_TEST_WITH_RETURN(dev, filp);
- DRM_COPY_FROM_USER_IOCTL( tex, (drm_radeon_texture_t __user *)data, sizeof(tex) );
+ DRM_COPY_FROM_USER_IOCTL(tex, (drm_radeon_texture_t __user *) data,
+ sizeof(tex));
- if ( tex.image == NULL ) {
- DRM_ERROR( "null texture image!\n" );
+ if (tex.image == NULL) {
+ DRM_ERROR("null texture image!\n");
return DRM_ERR(EINVAL);
}
- if ( DRM_COPY_FROM_USER( &image,
- (drm_radeon_tex_image_t __user *)tex.image,
- sizeof(image) ) )
+ if (DRM_COPY_FROM_USER(&image,
+ (drm_radeon_tex_image_t __user *) tex.image,
+ sizeof(image)))
return DRM_ERR(EFAULT);
- RING_SPACE_TEST_WITH_RETURN( dev_priv );
- VB_AGE_TEST_WITH_RETURN( dev_priv );
+ RING_SPACE_TEST_WITH_RETURN(dev_priv);
+ VB_AGE_TEST_WITH_RETURN(dev_priv);
- ret = radeon_cp_dispatch_texture( filp, dev, &tex, &image );
+ ret = radeon_cp_dispatch_texture(filp, dev, &tex, &image);
COMMIT_RING();
return ret;
}
-static int radeon_cp_stipple( DRM_IOCTL_ARGS )
+static int radeon_cp_stipple(DRM_IOCTL_ARGS)
{
DRM_DEVICE;
drm_radeon_private_t *dev_priv = dev->dev_private;
drm_radeon_stipple_t stipple;
u32 mask[32];
- LOCK_TEST_WITH_RETURN( dev, filp );
+ LOCK_TEST_WITH_RETURN(dev, filp);
- DRM_COPY_FROM_USER_IOCTL( stipple, (drm_radeon_stipple_t __user *)data,
- sizeof(stipple) );
+ DRM_COPY_FROM_USER_IOCTL(stipple, (drm_radeon_stipple_t __user *) data,
+ sizeof(stipple));
- if ( DRM_COPY_FROM_USER( &mask, stipple.mask, 32 * sizeof(u32) ) )
+ if (DRM_COPY_FROM_USER(&mask, stipple.mask, 32 * sizeof(u32)))
return DRM_ERR(EFAULT);
- RING_SPACE_TEST_WITH_RETURN( dev_priv );
+ RING_SPACE_TEST_WITH_RETURN(dev_priv);
- radeon_cp_dispatch_stipple( dev, mask );
+ radeon_cp_dispatch_stipple(dev, mask);
COMMIT_RING();
return 0;
}
-static int radeon_cp_indirect( DRM_IOCTL_ARGS )
+static int radeon_cp_indirect(DRM_IOCTL_ARGS)
{
DRM_DEVICE;
drm_radeon_private_t *dev_priv = dev->dev_private;
@@ -2346,53 +2391,53 @@ static int radeon_cp_indirect( DRM_IOCTL_ARGS )
drm_radeon_indirect_t indirect;
RING_LOCALS;
- LOCK_TEST_WITH_RETURN( dev, filp );
+ LOCK_TEST_WITH_RETURN(dev, filp);
- if ( !dev_priv ) {
- DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
+ if (!dev_priv) {
+ DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
return DRM_ERR(EINVAL);
}
- DRM_COPY_FROM_USER_IOCTL( indirect, (drm_radeon_indirect_t __user *)data,
- sizeof(indirect) );
+ DRM_COPY_FROM_USER_IOCTL(indirect,
+ (drm_radeon_indirect_t __user *) data,
+ sizeof(indirect));
- DRM_DEBUG( "indirect: idx=%d s=%d e=%d d=%d\n",
- indirect.idx, indirect.start,
- indirect.end, indirect.discard );
+ DRM_DEBUG("indirect: idx=%d s=%d e=%d d=%d\n",
+ indirect.idx, indirect.start, indirect.end, indirect.discard);
- if ( indirect.idx < 0 || indirect.idx >= dma->buf_count ) {
- DRM_ERROR( "buffer index %d (of %d max)\n",
- indirect.idx, dma->buf_count - 1 );
+ if (indirect.idx < 0 || indirect.idx >= dma->buf_count) {
+ DRM_ERROR("buffer index %d (of %d max)\n",
+ indirect.idx, dma->buf_count - 1);
return DRM_ERR(EINVAL);
}
buf = dma->buflist[indirect.idx];
- if ( buf->filp != filp ) {
- DRM_ERROR( "process %d using buffer owned by %p\n",
- DRM_CURRENTPID, buf->filp );
+ if (buf->filp != filp) {
+ DRM_ERROR("process %d using buffer owned by %p\n",
+ DRM_CURRENTPID, buf->filp);
return DRM_ERR(EINVAL);
}
- if ( buf->pending ) {
- DRM_ERROR( "sending pending buffer %d\n", indirect.idx );
+ if (buf->pending) {
+ DRM_ERROR("sending pending buffer %d\n", indirect.idx);
return DRM_ERR(EINVAL);
}
- if ( indirect.start < buf->used ) {
- DRM_ERROR( "reusing indirect: start=0x%x actual=0x%x\n",
- indirect.start, buf->used );
+ if (indirect.start < buf->used) {
+ DRM_ERROR("reusing indirect: start=0x%x actual=0x%x\n",
+ indirect.start, buf->used);
return DRM_ERR(EINVAL);
}
- RING_SPACE_TEST_WITH_RETURN( dev_priv );
- VB_AGE_TEST_WITH_RETURN( dev_priv );
+ RING_SPACE_TEST_WITH_RETURN(dev_priv);
+ VB_AGE_TEST_WITH_RETURN(dev_priv);
buf->used = indirect.end;
/* Wait for the 3D stream to idle before the indirect buffer
* containing 2D acceleration commands is processed.
*/
- BEGIN_RING( 2 );
+ BEGIN_RING(2);
RADEON_WAIT_UNTIL_3D_IDLE();
@@ -2402,17 +2447,16 @@ static int radeon_cp_indirect( DRM_IOCTL_ARGS )
* X server. This is insecure and is thus only available to
* privileged clients.
*/
- radeon_cp_dispatch_indirect( dev, buf, indirect.start, indirect.end );
+ radeon_cp_dispatch_indirect(dev, buf, indirect.start, indirect.end);
if (indirect.discard) {
- radeon_cp_discard_buffer( dev, buf );
+ radeon_cp_discard_buffer(dev, buf);
}
-
COMMIT_RING();
return 0;
}
-static int radeon_cp_vertex2( DRM_IOCTL_ARGS )
+static int radeon_cp_vertex2(DRM_IOCTL_ARGS)
{
DRM_DEVICE;
drm_radeon_private_t *dev_priv = dev->dev_private;
@@ -2424,65 +2468,64 @@ static int radeon_cp_vertex2( DRM_IOCTL_ARGS )
int i;
unsigned char laststate;
- LOCK_TEST_WITH_RETURN( dev, filp );
+ LOCK_TEST_WITH_RETURN(dev, filp);
- if ( !dev_priv ) {
- DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
+ if (!dev_priv) {
+ DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
return DRM_ERR(EINVAL);
}
- DRM_GET_PRIV_WITH_RETURN( filp_priv, filp );
+ DRM_GET_PRIV_WITH_RETURN(filp_priv, filp);
- DRM_COPY_FROM_USER_IOCTL( vertex, (drm_radeon_vertex2_t __user *)data,
- sizeof(vertex) );
+ DRM_COPY_FROM_USER_IOCTL(vertex, (drm_radeon_vertex2_t __user *) data,
+ sizeof(vertex));
- DRM_DEBUG( "pid=%d index=%d discard=%d\n",
- DRM_CURRENTPID,
- vertex.idx, vertex.discard );
+ DRM_DEBUG("pid=%d index=%d discard=%d\n",
+ DRM_CURRENTPID, vertex.idx, vertex.discard);
- if ( vertex.idx < 0 || vertex.idx >= dma->buf_count ) {
- DRM_ERROR( "buffer index %d (of %d max)\n",
- vertex.idx, dma->buf_count - 1 );
+ if (vertex.idx < 0 || vertex.idx >= dma->buf_count) {
+ DRM_ERROR("buffer index %d (of %d max)\n",
+ vertex.idx, dma->buf_count - 1);
return DRM_ERR(EINVAL);
}
- RING_SPACE_TEST_WITH_RETURN( dev_priv );
- VB_AGE_TEST_WITH_RETURN( dev_priv );
+ RING_SPACE_TEST_WITH_RETURN(dev_priv);
+ VB_AGE_TEST_WITH_RETURN(dev_priv);
buf = dma->buflist[vertex.idx];
- if ( buf->filp != filp ) {
- DRM_ERROR( "process %d using buffer owned by %p\n",
- DRM_CURRENTPID, buf->filp );
+ if (buf->filp != filp) {
+ DRM_ERROR("process %d using buffer owned by %p\n",
+ DRM_CURRENTPID, buf->filp);
return DRM_ERR(EINVAL);
}
- if ( buf->pending ) {
- DRM_ERROR( "sending pending buffer %d\n", vertex.idx );
+ if (buf->pending) {
+ DRM_ERROR("sending pending buffer %d\n", vertex.idx);
return DRM_ERR(EINVAL);
}
-
+
if (sarea_priv->nbox > RADEON_NR_SAREA_CLIPRECTS)
return DRM_ERR(EINVAL);
- for (laststate = 0xff, i = 0 ; i < vertex.nr_prims ; i++) {
+ for (laststate = 0xff, i = 0; i < vertex.nr_prims; i++) {
drm_radeon_prim_t prim;
drm_radeon_tcl_prim_t tclprim;
-
- if ( DRM_COPY_FROM_USER( &prim, &vertex.prim[i], sizeof(prim) ) )
+
+ if (DRM_COPY_FROM_USER(&prim, &vertex.prim[i], sizeof(prim)))
return DRM_ERR(EFAULT);
-
- if ( prim.stateidx != laststate ) {
- drm_radeon_state_t state;
-
- if ( DRM_COPY_FROM_USER( &state,
- &vertex.state[prim.stateidx],
- sizeof(state) ) )
+
+ if (prim.stateidx != laststate) {
+ drm_radeon_state_t state;
+
+ if (DRM_COPY_FROM_USER(&state,
+ &vertex.state[prim.stateidx],
+ sizeof(state)))
return DRM_ERR(EFAULT);
- if ( radeon_emit_state2( dev_priv, filp_priv, &state ) ) {
- DRM_ERROR( "radeon_emit_state2 failed\n" );
- return DRM_ERR( EINVAL );
+ if (radeon_emit_state2(dev_priv, filp_priv, &state)) {
+ DRM_ERROR("radeon_emit_state2 failed\n");
+ return DRM_ERR(EINVAL);
}
laststate = prim.stateidx;
@@ -2493,42 +2536,40 @@ static int radeon_cp_vertex2( DRM_IOCTL_ARGS )
tclprim.prim = prim.prim;
tclprim.vc_format = prim.vc_format;
- if ( prim.prim & RADEON_PRIM_WALK_IND ) {
+ if (prim.prim & RADEON_PRIM_WALK_IND) {
tclprim.offset = prim.numverts * 64;
- tclprim.numverts = RADEON_MAX_VB_VERTS; /* duh */
+ tclprim.numverts = RADEON_MAX_VB_VERTS; /* duh */
- radeon_cp_dispatch_indices( dev, buf, &tclprim );
+ radeon_cp_dispatch_indices(dev, buf, &tclprim);
} else {
tclprim.numverts = prim.numverts;
- tclprim.offset = 0; /* not used */
+ tclprim.offset = 0; /* not used */
- radeon_cp_dispatch_vertex( dev, buf, &tclprim );
+ radeon_cp_dispatch_vertex(dev, buf, &tclprim);
}
-
+
if (sarea_priv->nbox == 1)
sarea_priv->nbox = 0;
}
- if ( vertex.discard ) {
- radeon_cp_discard_buffer( dev, buf );
+ if (vertex.discard) {
+ radeon_cp_discard_buffer(dev, buf);
}
COMMIT_RING();
return 0;
}
-
-static int radeon_emit_packets(
- drm_radeon_private_t *dev_priv,
- drm_file_t *filp_priv,
- drm_radeon_cmd_header_t header,
- drm_radeon_cmd_buffer_t *cmdbuf )
+static int radeon_emit_packets(drm_radeon_private_t * dev_priv,
+ drm_file_t * filp_priv,
+ drm_radeon_cmd_header_t header,
+ drm_radeon_kcmd_buffer_t *cmdbuf)
{
int id = (int)header.packet.packet_id;
int sz, reg;
int *data = (int *)cmdbuf->buf;
RING_LOCALS;
-
+
if (id >= RADEON_MAX_STATE_PACKETS)
return DRM_ERR(EINVAL);
@@ -2536,18 +2577,18 @@ static int radeon_emit_packets(
reg = packet[id].start;
if (sz * sizeof(int) > cmdbuf->bufsz) {
- DRM_ERROR( "Packet size provided larger than data provided\n" );
+ DRM_ERROR("Packet size provided larger than data provided\n");
return DRM_ERR(EINVAL);
}
- if ( radeon_check_and_fixup_packets( dev_priv, filp_priv, id, data ) ) {
- DRM_ERROR( "Packet verification failed\n" );
- return DRM_ERR( EINVAL );
+ if (radeon_check_and_fixup_packets(dev_priv, filp_priv, id, data)) {
+ DRM_ERROR("Packet verification failed\n");
+ return DRM_ERR(EINVAL);
}
- BEGIN_RING(sz+1);
- OUT_RING( CP_PACKET0( reg, (sz-1) ) );
- OUT_RING_TABLE( data, sz );
+ BEGIN_RING(sz + 1);
+ OUT_RING(CP_PACKET0(reg, (sz - 1)));
+ OUT_RING_TABLE(data, sz);
ADVANCE_RING();
cmdbuf->buf += sz * sizeof(int);
@@ -2555,21 +2596,20 @@ static int radeon_emit_packets(
return 0;
}
-static __inline__ int radeon_emit_scalars(
- drm_radeon_private_t *dev_priv,
- drm_radeon_cmd_header_t header,
- drm_radeon_cmd_buffer_t *cmdbuf )
+static __inline__ int radeon_emit_scalars(drm_radeon_private_t * dev_priv,
+ drm_radeon_cmd_header_t header,
+ drm_radeon_kcmd_buffer_t * cmdbuf)
{
int sz = header.scalars.count;
int start = header.scalars.offset;
int stride = header.scalars.stride;
RING_LOCALS;
- BEGIN_RING( 3+sz );
- OUT_RING( CP_PACKET0( RADEON_SE_TCL_SCALAR_INDX_REG, 0 ) );
- OUT_RING( start | (stride << RADEON_SCAL_INDX_DWORD_STRIDE_SHIFT));
- OUT_RING( CP_PACKET0_TABLE( RADEON_SE_TCL_SCALAR_DATA_REG, sz-1 ) );
- OUT_RING_TABLE( cmdbuf->buf, sz );
+ BEGIN_RING(3 + sz);
+ OUT_RING(CP_PACKET0(RADEON_SE_TCL_SCALAR_INDX_REG, 0));
+ OUT_RING(start | (stride << RADEON_SCAL_INDX_DWORD_STRIDE_SHIFT));
+ OUT_RING(CP_PACKET0_TABLE(RADEON_SE_TCL_SCALAR_DATA_REG, sz - 1));
+ OUT_RING_TABLE(cmdbuf->buf, sz);
ADVANCE_RING();
cmdbuf->buf += sz * sizeof(int);
cmdbuf->bufsz -= sz * sizeof(int);
@@ -2578,42 +2618,40 @@ static __inline__ int radeon_emit_scalars(
/* God this is ugly
*/
-static __inline__ int radeon_emit_scalars2(
- drm_radeon_private_t *dev_priv,
- drm_radeon_cmd_header_t header,
- drm_radeon_cmd_buffer_t *cmdbuf )
+static __inline__ int radeon_emit_scalars2(drm_radeon_private_t * dev_priv,
+ drm_radeon_cmd_header_t header,
+ drm_radeon_kcmd_buffer_t * cmdbuf)
{
int sz = header.scalars.count;
int start = ((unsigned int)header.scalars.offset) + 0x100;
int stride = header.scalars.stride;
RING_LOCALS;
- BEGIN_RING( 3+sz );
- OUT_RING( CP_PACKET0( RADEON_SE_TCL_SCALAR_INDX_REG, 0 ) );
- OUT_RING( start | (stride << RADEON_SCAL_INDX_DWORD_STRIDE_SHIFT));
- OUT_RING( CP_PACKET0_TABLE( RADEON_SE_TCL_SCALAR_DATA_REG, sz-1 ) );
- OUT_RING_TABLE( cmdbuf->buf, sz );
+ BEGIN_RING(3 + sz);
+ OUT_RING(CP_PACKET0(RADEON_SE_TCL_SCALAR_INDX_REG, 0));
+ OUT_RING(start | (stride << RADEON_SCAL_INDX_DWORD_STRIDE_SHIFT));
+ OUT_RING(CP_PACKET0_TABLE(RADEON_SE_TCL_SCALAR_DATA_REG, sz - 1));
+ OUT_RING_TABLE(cmdbuf->buf, sz);
ADVANCE_RING();
cmdbuf->buf += sz * sizeof(int);
cmdbuf->bufsz -= sz * sizeof(int);
return 0;
}
-static __inline__ int radeon_emit_vectors(
- drm_radeon_private_t *dev_priv,
- drm_radeon_cmd_header_t header,
- drm_radeon_cmd_buffer_t *cmdbuf )
+static __inline__ int radeon_emit_vectors(drm_radeon_private_t * dev_priv,
+ drm_radeon_cmd_header_t header,
+ drm_radeon_kcmd_buffer_t * cmdbuf)
{
int sz = header.vectors.count;
int start = header.vectors.offset;
int stride = header.vectors.stride;
RING_LOCALS;
- BEGIN_RING( 3+sz );
- OUT_RING( CP_PACKET0( RADEON_SE_TCL_VECTOR_INDX_REG, 0 ) );
- OUT_RING( start | (stride << RADEON_VEC_INDX_OCTWORD_STRIDE_SHIFT));
- OUT_RING( CP_PACKET0_TABLE( RADEON_SE_TCL_VECTOR_DATA_REG, (sz-1) ) );
- OUT_RING_TABLE( cmdbuf->buf, sz );
+ BEGIN_RING(3 + sz);
+ OUT_RING(CP_PACKET0(RADEON_SE_TCL_VECTOR_INDX_REG, 0));
+ OUT_RING(start | (stride << RADEON_VEC_INDX_OCTWORD_STRIDE_SHIFT));
+ OUT_RING(CP_PACKET0_TABLE(RADEON_SE_TCL_VECTOR_DATA_REG, (sz - 1)));
+ OUT_RING_TABLE(cmdbuf->buf, sz);
ADVANCE_RING();
cmdbuf->buf += sz * sizeof(int);
@@ -2621,10 +2659,9 @@ static __inline__ int radeon_emit_vectors(
return 0;
}
-
-static int radeon_emit_packet3( drm_device_t *dev,
- drm_file_t *filp_priv,
- drm_radeon_cmd_buffer_t *cmdbuf )
+static int radeon_emit_packet3(drm_device_t * dev,
+ drm_file_t * filp_priv,
+ drm_radeon_kcmd_buffer_t *cmdbuf)
{
drm_radeon_private_t *dev_priv = dev->dev_private;
unsigned int cmdsz;
@@ -2633,14 +2670,14 @@ static int radeon_emit_packet3( drm_device_t *dev,
DRM_DEBUG("\n");
- if ( ( ret = radeon_check_and_fixup_packet3( dev_priv, filp_priv,
- cmdbuf, &cmdsz ) ) ) {
- DRM_ERROR( "Packet verification failed\n" );
+ if ((ret = radeon_check_and_fixup_packet3(dev_priv, filp_priv,
+ cmdbuf, &cmdsz))) {
+ DRM_ERROR("Packet verification failed\n");
return ret;
}
- BEGIN_RING( cmdsz );
- OUT_RING_TABLE( cmdbuf->buf, cmdsz );
+ BEGIN_RING(cmdsz);
+ OUT_RING_TABLE(cmdbuf->buf, cmdsz);
ADVANCE_RING();
cmdbuf->buf += cmdsz * 4;
@@ -2648,11 +2685,10 @@ static int radeon_emit_packet3( drm_device_t *dev,
return 0;
}
-
-static int radeon_emit_packet3_cliprect( drm_device_t *dev,
- drm_file_t *filp_priv,
- drm_radeon_cmd_buffer_t *cmdbuf,
- int orig_nbox )
+static int radeon_emit_packet3_cliprect(drm_device_t * dev,
+ drm_file_t * filp_priv,
+ drm_radeon_kcmd_buffer_t *cmdbuf,
+ int orig_nbox)
{
drm_radeon_private_t *dev_priv = dev->dev_private;
drm_clip_rect_t box;
@@ -2664,9 +2700,9 @@ static int radeon_emit_packet3_cliprect( drm_device_t *dev,
DRM_DEBUG("\n");
- if ( ( ret = radeon_check_and_fixup_packet3( dev_priv, filp_priv,
- cmdbuf, &cmdsz ) ) ) {
- DRM_ERROR( "Packet verification failed\n" );
+ if ((ret = radeon_check_and_fixup_packet3(dev_priv, filp_priv,
+ cmdbuf, &cmdsz))) {
+ DRM_ERROR("Packet verification failed\n");
return ret;
}
@@ -2674,8 +2710,8 @@ static int radeon_emit_packet3_cliprect( drm_device_t *dev,
goto out;
do {
- if ( i < cmdbuf->nbox ) {
- if (DRM_COPY_FROM_USER( &box, &boxes[i], sizeof(box) ))
+ if (i < cmdbuf->nbox) {
+ if (DRM_COPY_FROM_USER(&box, &boxes[i], sizeof(box)))
return DRM_ERR(EFAULT);
/* FIXME The second and subsequent times round
* this loop, send a WAIT_UNTIL_3D_IDLE before
@@ -2689,30 +2725,29 @@ static int radeon_emit_packet3_cliprect( drm_device_t *dev,
* the correct place to fix it but this works
* around it until I can figure that out - Tim
* Smith */
- if ( i ) {
- BEGIN_RING( 2 );
+ if (i) {
+ BEGIN_RING(2);
RADEON_WAIT_UNTIL_3D_IDLE();
ADVANCE_RING();
}
- radeon_emit_clip_rect( dev_priv, &box );
+ radeon_emit_clip_rect(dev_priv, &box);
}
-
- BEGIN_RING( cmdsz );
- OUT_RING_TABLE( cmdbuf->buf, cmdsz );
+
+ BEGIN_RING(cmdsz);
+ OUT_RING_TABLE(cmdbuf->buf, cmdsz);
ADVANCE_RING();
- } while ( ++i < cmdbuf->nbox );
- if (cmdbuf->nbox == 1)
+ } while (++i < cmdbuf->nbox);
+ if (cmdbuf->nbox == 1)
cmdbuf->nbox = 0;
- out:
+ out:
cmdbuf->buf += cmdsz * 4;
cmdbuf->bufsz -= cmdsz * 4;
return 0;
}
-
-static int radeon_emit_wait( drm_device_t *dev, int flags )
+static int radeon_emit_wait(drm_device_t * dev, int flags)
{
drm_radeon_private_t *dev_priv = dev->dev_private;
RING_LOCALS;
@@ -2720,18 +2755,18 @@ static int radeon_emit_wait( drm_device_t *dev, int flags )
DRM_DEBUG("%s: %x\n", __FUNCTION__, flags);
switch (flags) {
case RADEON_WAIT_2D:
- BEGIN_RING( 2 );
- RADEON_WAIT_UNTIL_2D_IDLE();
+ BEGIN_RING(2);
+ RADEON_WAIT_UNTIL_2D_IDLE();
ADVANCE_RING();
break;
case RADEON_WAIT_3D:
- BEGIN_RING( 2 );
- RADEON_WAIT_UNTIL_3D_IDLE();
+ BEGIN_RING(2);
+ RADEON_WAIT_UNTIL_3D_IDLE();
ADVANCE_RING();
break;
- case RADEON_WAIT_2D|RADEON_WAIT_3D:
- BEGIN_RING( 2 );
- RADEON_WAIT_UNTIL_IDLE();
+ case RADEON_WAIT_2D | RADEON_WAIT_3D:
+ BEGIN_RING(2);
+ RADEON_WAIT_UNTIL_IDLE();
ADVANCE_RING();
break;
default:
@@ -2741,7 +2776,7 @@ static int radeon_emit_wait( drm_device_t *dev, int flags )
return 0;
}
-static int radeon_cp_cmdbuf( DRM_IOCTL_ARGS )
+static int radeon_cp_cmdbuf(DRM_IOCTL_ARGS)
{
DRM_DEVICE;
drm_radeon_private_t *dev_priv = dev->dev_private;
@@ -2749,27 +2784,28 @@ static int radeon_cp_cmdbuf( DRM_IOCTL_ARGS )
drm_device_dma_t *dma = dev->dma;
drm_buf_t *buf = NULL;
int idx;
- drm_radeon_cmd_buffer_t cmdbuf;
+ drm_radeon_kcmd_buffer_t cmdbuf;
drm_radeon_cmd_header_t header;
int orig_nbox, orig_bufsz;
- char *kbuf=NULL;
+ char *kbuf = NULL;
- LOCK_TEST_WITH_RETURN( dev, filp );
+ LOCK_TEST_WITH_RETURN(dev, filp);
- if ( !dev_priv ) {
- DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
+ if (!dev_priv) {
+ DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
return DRM_ERR(EINVAL);
}
- DRM_GET_PRIV_WITH_RETURN( filp_priv, filp );
+ DRM_GET_PRIV_WITH_RETURN(filp_priv, filp);
- DRM_COPY_FROM_USER_IOCTL( cmdbuf, (drm_radeon_cmd_buffer_t __user *)data,
- sizeof(cmdbuf) );
+ DRM_COPY_FROM_USER_IOCTL(cmdbuf,
+ (drm_radeon_cmd_buffer_t __user *) data,
+ sizeof(cmdbuf));
- RING_SPACE_TEST_WITH_RETURN( dev_priv );
- VB_AGE_TEST_WITH_RETURN( dev_priv );
+ RING_SPACE_TEST_WITH_RETURN(dev_priv);
+ VB_AGE_TEST_WITH_RETURN(dev_priv);
- if (cmdbuf.bufsz > 64*1024 || cmdbuf.bufsz<0) {
+ if (cmdbuf.bufsz > 64 * 1024 || cmdbuf.bufsz < 0) {
return DRM_ERR(EINVAL);
}
@@ -2782,7 +2818,7 @@ static int radeon_cp_cmdbuf( DRM_IOCTL_ARGS )
kbuf = drm_alloc(cmdbuf.bufsz, DRM_MEM_DRIVER);
if (kbuf == NULL)
return DRM_ERR(ENOMEM);
- if (DRM_COPY_FROM_USER(kbuf, cmdbuf.buf, cmdbuf.bufsz)) {
+ if (DRM_COPY_FROM_USER(kbuf, (void __user *)cmdbuf.buf, cmdbuf.bufsz)) {
drm_free(kbuf, orig_bufsz, DRM_MEM_DRIVER);
return DRM_ERR(EFAULT);
}
@@ -2791,27 +2827,28 @@ static int radeon_cp_cmdbuf( DRM_IOCTL_ARGS )
orig_nbox = cmdbuf.nbox;
- if(dev_priv->microcode_version == UCODE_R300) {
+ if (dev_priv->microcode_version == UCODE_R300) {
int temp;
- temp=r300_do_cp_cmdbuf(dev, filp, filp_priv, &cmdbuf);
-
+ temp = r300_do_cp_cmdbuf(dev, filp, filp_priv, &cmdbuf);
+
if (orig_bufsz != 0)
drm_free(kbuf, orig_bufsz, DRM_MEM_DRIVER);
-
+
return temp;
}
/* microcode_version != r300 */
- while ( cmdbuf.bufsz >= sizeof(header) ) {
+ while (cmdbuf.bufsz >= sizeof(header)) {
header.i = *(int *)cmdbuf.buf;
cmdbuf.buf += sizeof(header);
cmdbuf.bufsz -= sizeof(header);
switch (header.header.cmd_type) {
- case RADEON_CMD_PACKET:
+ case RADEON_CMD_PACKET:
DRM_DEBUG("RADEON_CMD_PACKET\n");
- if (radeon_emit_packets( dev_priv, filp_priv, header, &cmdbuf )) {
+ if (radeon_emit_packets
+ (dev_priv, filp_priv, header, &cmdbuf)) {
DRM_ERROR("radeon_emit_packets failed\n");
goto err;
}
@@ -2819,7 +2856,7 @@ static int radeon_cp_cmdbuf( DRM_IOCTL_ARGS )
case RADEON_CMD_SCALARS:
DRM_DEBUG("RADEON_CMD_SCALARS\n");
- if (radeon_emit_scalars( dev_priv, header, &cmdbuf )) {
+ if (radeon_emit_scalars(dev_priv, header, &cmdbuf)) {
DRM_ERROR("radeon_emit_scalars failed\n");
goto err;
}
@@ -2827,7 +2864,7 @@ static int radeon_cp_cmdbuf( DRM_IOCTL_ARGS )
case RADEON_CMD_VECTORS:
DRM_DEBUG("RADEON_CMD_VECTORS\n");
- if (radeon_emit_vectors( dev_priv, header, &cmdbuf )) {
+ if (radeon_emit_vectors(dev_priv, header, &cmdbuf)) {
DRM_ERROR("radeon_emit_vectors failed\n");
goto err;
}
@@ -2836,25 +2873,25 @@ static int radeon_cp_cmdbuf( DRM_IOCTL_ARGS )
case RADEON_CMD_DMA_DISCARD:
DRM_DEBUG("RADEON_CMD_DMA_DISCARD\n");
idx = header.dma.buf_idx;
- if ( idx < 0 || idx >= dma->buf_count ) {
- DRM_ERROR( "buffer index %d (of %d max)\n",
- idx, dma->buf_count - 1 );
+ if (idx < 0 || idx >= dma->buf_count) {
+ DRM_ERROR("buffer index %d (of %d max)\n",
+ idx, dma->buf_count - 1);
goto err;
}
buf = dma->buflist[idx];
- if ( buf->filp != filp || buf->pending ) {
- DRM_ERROR( "bad buffer %p %p %d\n",
- buf->filp, filp, buf->pending);
+ if (buf->filp != filp || buf->pending) {
+ DRM_ERROR("bad buffer %p %p %d\n",
+ buf->filp, filp, buf->pending);
goto err;
}
- radeon_cp_discard_buffer( dev, buf );
+ radeon_cp_discard_buffer(dev, buf);
break;
case RADEON_CMD_PACKET3:
DRM_DEBUG("RADEON_CMD_PACKET3\n");
- if (radeon_emit_packet3( dev, filp_priv, &cmdbuf )) {
+ if (radeon_emit_packet3(dev, filp_priv, &cmdbuf)) {
DRM_ERROR("radeon_emit_packet3 failed\n");
goto err;
}
@@ -2862,7 +2899,8 @@ static int radeon_cp_cmdbuf( DRM_IOCTL_ARGS )
case RADEON_CMD_PACKET3_CLIP:
DRM_DEBUG("RADEON_CMD_PACKET3_CLIP\n");
- if (radeon_emit_packet3_cliprect( dev, filp_priv, &cmdbuf, orig_nbox )) {
+ if (radeon_emit_packet3_cliprect
+ (dev, filp_priv, &cmdbuf, orig_nbox)) {
DRM_ERROR("radeon_emit_packet3_clip failed\n");
goto err;
}
@@ -2870,7 +2908,7 @@ static int radeon_cp_cmdbuf( DRM_IOCTL_ARGS )
case RADEON_CMD_SCALARS2:
DRM_DEBUG("RADEON_CMD_SCALARS2\n");
- if (radeon_emit_scalars2( dev_priv, header, &cmdbuf )) {
+ if (radeon_emit_scalars2(dev_priv, header, &cmdbuf)) {
DRM_ERROR("radeon_emit_scalars2 failed\n");
goto err;
}
@@ -2878,13 +2916,13 @@ static int radeon_cp_cmdbuf( DRM_IOCTL_ARGS )
case RADEON_CMD_WAIT:
DRM_DEBUG("RADEON_CMD_WAIT\n");
- if (radeon_emit_wait( dev, header.wait.flags )) {
+ if (radeon_emit_wait(dev, header.wait.flags)) {
DRM_ERROR("radeon_emit_wait failed\n");
goto err;
}
break;
default:
- DRM_ERROR("bad cmd_type %d at %p\n",
+ DRM_ERROR("bad cmd_type %d at %p\n",
header.header.cmd_type,
cmdbuf.buf - sizeof(header));
goto err;
@@ -2898,45 +2936,43 @@ static int radeon_cp_cmdbuf( DRM_IOCTL_ARGS )
COMMIT_RING();
return 0;
-err:
+ err:
if (orig_bufsz != 0)
drm_free(kbuf, orig_bufsz, DRM_MEM_DRIVER);
return DRM_ERR(EINVAL);
}
-
-
-static int radeon_cp_getparam( DRM_IOCTL_ARGS )
+static int radeon_cp_getparam(DRM_IOCTL_ARGS)
{
DRM_DEVICE;
drm_radeon_private_t *dev_priv = dev->dev_private;
drm_radeon_getparam_t param;
int value;
- if ( !dev_priv ) {
- DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
+ if (!dev_priv) {
+ DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
return DRM_ERR(EINVAL);
}
- DRM_COPY_FROM_USER_IOCTL( param, (drm_radeon_getparam_t __user *)data,
- sizeof(param) );
+ DRM_COPY_FROM_USER_IOCTL(param, (drm_radeon_getparam_t __user *) data,
+ sizeof(param));
- DRM_DEBUG( "pid=%d\n", DRM_CURRENTPID );
+ DRM_DEBUG("pid=%d\n", DRM_CURRENTPID);
- switch( param.param ) {
+ switch (param.param) {
case RADEON_PARAM_GART_BUFFER_OFFSET:
value = dev_priv->gart_buffers_offset;
break;
case RADEON_PARAM_LAST_FRAME:
dev_priv->stats.last_frame_reads++;
- value = GET_SCRATCH( 0 );
+ value = GET_SCRATCH(0);
break;
case RADEON_PARAM_LAST_DISPATCH:
- value = GET_SCRATCH( 1 );
+ value = GET_SCRATCH(1);
break;
case RADEON_PARAM_LAST_CLEAR:
dev_priv->stats.last_clear_reads++;
- value = GET_SCRATCH( 2 );
+ value = GET_SCRATCH(2);
break;
case RADEON_PARAM_IRQ_NR:
value = dev->irq;
@@ -2951,15 +2987,15 @@ static int radeon_cp_getparam( DRM_IOCTL_ARGS )
value = dev_priv->ring_rptr_offset;
break;
#if BITS_PER_LONG == 32
- /*
- * This ioctl() doesn't work on 64-bit platforms because hw_lock is a
- * pointer which can't fit into an int-sized variable. According to
- * Michel Dänzer, the ioctl() is only used on embedded platforms, so
- * not supporting it shouldn't be a problem. If the same functionality
- * is needed on 64-bit platforms, a new ioctl() would have to be added,
- * so backwards-compatibility for the embedded platforms can be
- * maintained. --davidm 4-Feb-2004.
- */
+ /*
+ * This ioctl() doesn't work on 64-bit platforms because hw_lock is a
+ * pointer which can't fit into an int-sized variable. According to
+ * Michel Dänzer, the ioctl() is only used on embedded platforms, so
+ * not supporting it shouldn't be a problem. If the same functionality
+ * is needed on 64-bit platforms, a new ioctl() would have to be added,
+ * so backwards-compatibility for the embedded platforms can be
+ * maintained. --davidm 4-Feb-2004.
+ */
case RADEON_PARAM_SAREA_HANDLE:
/* The lock is the first dword in the sarea. */
value = (long)dev->lock.hw_lock;
@@ -2972,53 +3008,56 @@ static int radeon_cp_getparam( DRM_IOCTL_ARGS )
return DRM_ERR(EINVAL);
}
- if ( DRM_COPY_TO_USER( param.value, &value, sizeof(int) ) ) {
- DRM_ERROR( "copy_to_user\n" );
+ if (DRM_COPY_TO_USER(param.value, &value, sizeof(int))) {
+ DRM_ERROR("copy_to_user\n");
return DRM_ERR(EFAULT);
}
-
+
return 0;
}
-static int radeon_cp_setparam( DRM_IOCTL_ARGS ) {
+static int radeon_cp_setparam(DRM_IOCTL_ARGS)
+{
DRM_DEVICE;
drm_radeon_private_t *dev_priv = dev->dev_private;
drm_file_t *filp_priv;
drm_radeon_setparam_t sp;
struct drm_radeon_driver_file_fields *radeon_priv;
- if ( !dev_priv ) {
- DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
- return DRM_ERR( EINVAL );
+ if (!dev_priv) {
+ DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
+ return DRM_ERR(EINVAL);
}
- DRM_GET_PRIV_WITH_RETURN( filp_priv, filp );
+ DRM_GET_PRIV_WITH_RETURN(filp_priv, filp);
- DRM_COPY_FROM_USER_IOCTL( sp, ( drm_radeon_setparam_t __user * )data,
- sizeof( sp ) );
+ DRM_COPY_FROM_USER_IOCTL(sp, (drm_radeon_setparam_t __user *) data,
+ sizeof(sp));
- switch( sp.param ) {
+ switch (sp.param) {
case RADEON_SETPARAM_FB_LOCATION:
radeon_priv = filp_priv->driver_priv;
radeon_priv->radeon_fb_delta = dev_priv->fb_location - sp.value;
break;
case RADEON_SETPARAM_SWITCH_TILING:
if (sp.value == 0) {
- DRM_DEBUG( "color tiling disabled\n" );
+ DRM_DEBUG("color tiling disabled\n");
dev_priv->front_pitch_offset &= ~RADEON_DST_TILE_MACRO;
dev_priv->back_pitch_offset &= ~RADEON_DST_TILE_MACRO;
dev_priv->sarea_priv->tiling_enabled = 0;
- }
- else if (sp.value == 1) {
- DRM_DEBUG( "color tiling enabled\n" );
+ } else if (sp.value == 1) {
+ DRM_DEBUG("color tiling enabled\n");
dev_priv->front_pitch_offset |= RADEON_DST_TILE_MACRO;
dev_priv->back_pitch_offset |= RADEON_DST_TILE_MACRO;
dev_priv->sarea_priv->tiling_enabled = 1;
}
- break;
+ break;
+ case RADEON_SETPARAM_PCIGART_LOCATION:
+ dev_priv->pcigart_offset = sp.value;
+ break;
default:
- DRM_DEBUG( "Invalid parameter %d\n", sp.param );
- return DRM_ERR( EINVAL );
+ DRM_DEBUG("Invalid parameter %d\n", sp.param);
+ return DRM_ERR(EINVAL);
}
return 0;
@@ -3030,78 +3069,80 @@ static int radeon_cp_setparam( DRM_IOCTL_ARGS ) {
*
* DRM infrastructure takes care of reclaiming dma buffers.
*/
-void radeon_driver_prerelease(drm_device_t *dev, DRMFILE filp)
+void radeon_driver_prerelease(drm_device_t * dev, DRMFILE filp)
{
- if ( dev->dev_private ) {
- drm_radeon_private_t *dev_priv = dev->dev_private;
- if ( dev_priv->page_flipping ) {
- radeon_do_cleanup_pageflip( dev );
- }
- radeon_mem_release( filp, dev_priv->gart_heap );
- radeon_mem_release( filp, dev_priv->fb_heap );
+ if (dev->dev_private) {
+ drm_radeon_private_t *dev_priv = dev->dev_private;
+ if (dev_priv->page_flipping) {
+ radeon_do_cleanup_pageflip(dev);
+ }
+ radeon_mem_release(filp, dev_priv->gart_heap);
+ radeon_mem_release(filp, dev_priv->fb_heap);
radeon_surfaces_release(filp, dev_priv);
- }
+ }
}
-void radeon_driver_pretakedown(drm_device_t *dev)
+void radeon_driver_pretakedown(drm_device_t * dev)
{
radeon_do_release(dev);
}
-int radeon_driver_open_helper(drm_device_t *dev, drm_file_t *filp_priv)
+int radeon_driver_open_helper(drm_device_t * dev, drm_file_t * filp_priv)
{
drm_radeon_private_t *dev_priv = dev->dev_private;
struct drm_radeon_driver_file_fields *radeon_priv;
-
- radeon_priv = (struct drm_radeon_driver_file_fields *)drm_alloc(sizeof(*radeon_priv), DRM_MEM_FILES);
-
+
+ radeon_priv =
+ (struct drm_radeon_driver_file_fields *)
+ drm_alloc(sizeof(*radeon_priv), DRM_MEM_FILES);
+
if (!radeon_priv)
return -ENOMEM;
filp_priv->driver_priv = radeon_priv;
- if ( dev_priv )
+ if (dev_priv)
radeon_priv->radeon_fb_delta = dev_priv->fb_location;
else
radeon_priv->radeon_fb_delta = 0;
return 0;
}
-
-void radeon_driver_free_filp_priv(drm_device_t *dev, drm_file_t *filp_priv)
+void radeon_driver_free_filp_priv(drm_device_t * dev, drm_file_t * filp_priv)
{
- struct drm_radeon_driver_file_fields *radeon_priv = filp_priv->driver_priv;
-
- drm_free(radeon_priv, sizeof(*radeon_priv), DRM_MEM_FILES);
+ struct drm_radeon_driver_file_fields *radeon_priv =
+ filp_priv->driver_priv;
+
+ drm_free(radeon_priv, sizeof(*radeon_priv), DRM_MEM_FILES);
}
drm_ioctl_desc_t radeon_ioctls[] = {
- [DRM_IOCTL_NR(DRM_RADEON_CP_INIT)] = { radeon_cp_init, 1, 1 },
- [DRM_IOCTL_NR(DRM_RADEON_CP_START)] = { radeon_cp_start, 1, 1 },
- [DRM_IOCTL_NR(DRM_RADEON_CP_STOP)] = { radeon_cp_stop, 1, 1 },
- [DRM_IOCTL_NR(DRM_RADEON_CP_RESET)] = { radeon_cp_reset, 1, 1 },
- [DRM_IOCTL_NR(DRM_RADEON_CP_IDLE)] = { radeon_cp_idle, 1, 0 },
- [DRM_IOCTL_NR(DRM_RADEON_CP_RESUME)] = { radeon_cp_resume, 1, 0 },
- [DRM_IOCTL_NR(DRM_RADEON_RESET)] = { radeon_engine_reset, 1, 0 },
- [DRM_IOCTL_NR(DRM_RADEON_FULLSCREEN)] = { radeon_fullscreen, 1, 0 },
- [DRM_IOCTL_NR(DRM_RADEON_SWAP)] = { radeon_cp_swap, 1, 0 },
- [DRM_IOCTL_NR(DRM_RADEON_CLEAR)] = { radeon_cp_clear, 1, 0 },
- [DRM_IOCTL_NR(DRM_RADEON_VERTEX)] = { radeon_cp_vertex, 1, 0 },
- [DRM_IOCTL_NR(DRM_RADEON_INDICES)] = { radeon_cp_indices, 1, 0 },
- [DRM_IOCTL_NR(DRM_RADEON_TEXTURE)] = { radeon_cp_texture, 1, 0 },
- [DRM_IOCTL_NR(DRM_RADEON_STIPPLE)] = { radeon_cp_stipple, 1, 0 },
- [DRM_IOCTL_NR(DRM_RADEON_INDIRECT)] = { radeon_cp_indirect, 1, 1 },
- [DRM_IOCTL_NR(DRM_RADEON_VERTEX2)] = { radeon_cp_vertex2, 1, 0 },
- [DRM_IOCTL_NR(DRM_RADEON_CMDBUF)] = { radeon_cp_cmdbuf, 1, 0 },
- [DRM_IOCTL_NR(DRM_RADEON_GETPARAM)] = { radeon_cp_getparam, 1, 0 },
- [DRM_IOCTL_NR(DRM_RADEON_FLIP)] = { radeon_cp_flip, 1, 0 },
- [DRM_IOCTL_NR(DRM_RADEON_ALLOC)] = { radeon_mem_alloc, 1, 0 },
- [DRM_IOCTL_NR(DRM_RADEON_FREE)] = { radeon_mem_free, 1, 0 },
- [DRM_IOCTL_NR(DRM_RADEON_INIT_HEAP)] = { radeon_mem_init_heap,1, 1 },
- [DRM_IOCTL_NR(DRM_RADEON_IRQ_EMIT)] = { radeon_irq_emit, 1, 0 },
- [DRM_IOCTL_NR(DRM_RADEON_IRQ_WAIT)] = { radeon_irq_wait, 1, 0 },
- [DRM_IOCTL_NR(DRM_RADEON_SETPARAM)] = { radeon_cp_setparam, 1, 0 },
- [DRM_IOCTL_NR(DRM_RADEON_SURF_ALLOC)] = { radeon_surface_alloc,1, 0 },
- [DRM_IOCTL_NR(DRM_RADEON_SURF_FREE)] = { radeon_surface_free, 1, 0 }
+ [DRM_IOCTL_NR(DRM_RADEON_CP_INIT)] = {radeon_cp_init, 1, 1},
+ [DRM_IOCTL_NR(DRM_RADEON_CP_START)] = {radeon_cp_start, 1, 1},
+ [DRM_IOCTL_NR(DRM_RADEON_CP_STOP)] = {radeon_cp_stop, 1, 1},
+ [DRM_IOCTL_NR(DRM_RADEON_CP_RESET)] = {radeon_cp_reset, 1, 1},
+ [DRM_IOCTL_NR(DRM_RADEON_CP_IDLE)] = {radeon_cp_idle, 1, 0},
+ [DRM_IOCTL_NR(DRM_RADEON_CP_RESUME)] = {radeon_cp_resume, 1, 0},
+ [DRM_IOCTL_NR(DRM_RADEON_RESET)] = {radeon_engine_reset, 1, 0},
+ [DRM_IOCTL_NR(DRM_RADEON_FULLSCREEN)] = {radeon_fullscreen, 1, 0},
+ [DRM_IOCTL_NR(DRM_RADEON_SWAP)] = {radeon_cp_swap, 1, 0},
+ [DRM_IOCTL_NR(DRM_RADEON_CLEAR)] = {radeon_cp_clear, 1, 0},
+ [DRM_IOCTL_NR(DRM_RADEON_VERTEX)] = {radeon_cp_vertex, 1, 0},
+ [DRM_IOCTL_NR(DRM_RADEON_INDICES)] = {radeon_cp_indices, 1, 0},
+ [DRM_IOCTL_NR(DRM_RADEON_TEXTURE)] = {radeon_cp_texture, 1, 0},
+ [DRM_IOCTL_NR(DRM_RADEON_STIPPLE)] = {radeon_cp_stipple, 1, 0},
+ [DRM_IOCTL_NR(DRM_RADEON_INDIRECT)] = {radeon_cp_indirect, 1, 1},
+ [DRM_IOCTL_NR(DRM_RADEON_VERTEX2)] = {radeon_cp_vertex2, 1, 0},
+ [DRM_IOCTL_NR(DRM_RADEON_CMDBUF)] = {radeon_cp_cmdbuf, 1, 0},
+ [DRM_IOCTL_NR(DRM_RADEON_GETPARAM)] = {radeon_cp_getparam, 1, 0},
+ [DRM_IOCTL_NR(DRM_RADEON_FLIP)] = {radeon_cp_flip, 1, 0},
+ [DRM_IOCTL_NR(DRM_RADEON_ALLOC)] = {radeon_mem_alloc, 1, 0},
+ [DRM_IOCTL_NR(DRM_RADEON_FREE)] = {radeon_mem_free, 1, 0},
+ [DRM_IOCTL_NR(DRM_RADEON_INIT_HEAP)] = {radeon_mem_init_heap, 1, 1},
+ [DRM_IOCTL_NR(DRM_RADEON_IRQ_EMIT)] = {radeon_irq_emit, 1, 0},
+ [DRM_IOCTL_NR(DRM_RADEON_IRQ_WAIT)] = {radeon_irq_wait, 1, 0},
+ [DRM_IOCTL_NR(DRM_RADEON_SETPARAM)] = {radeon_cp_setparam, 1, 0},
+ [DRM_IOCTL_NR(DRM_RADEON_SURF_ALLOC)] = {radeon_surface_alloc, 1, 0},
+ [DRM_IOCTL_NR(DRM_RADEON_SURF_FREE)] = {radeon_surface_free, 1, 0}
};
int radeon_max_ioctl = DRM_ARRAY_SIZE(radeon_ioctls);
diff --git a/drivers/char/drm/savage_bci.c b/drivers/char/drm/savage_bci.c
index 2fd40bac7c97..6d10515795cc 100644
--- a/drivers/char/drm/savage_bci.c
+++ b/drivers/char/drm/savage_bci.c
@@ -28,12 +28,12 @@
/* Need a long timeout for shadow status updates can take a while
* and so can waiting for events when the queue is full. */
-#define SAVAGE_DEFAULT_USEC_TIMEOUT 1000000 /* 1s */
-#define SAVAGE_EVENT_USEC_TIMEOUT 5000000 /* 5s */
+#define SAVAGE_DEFAULT_USEC_TIMEOUT 1000000 /* 1s */
+#define SAVAGE_EVENT_USEC_TIMEOUT 5000000 /* 5s */
#define SAVAGE_FREELIST_DEBUG 0
static int
-savage_bci_wait_fifo_shadow(drm_savage_private_t *dev_priv, unsigned int n)
+savage_bci_wait_fifo_shadow(drm_savage_private_t * dev_priv, unsigned int n)
{
uint32_t mask = dev_priv->status_used_mask;
uint32_t threshold = dev_priv->bci_threshold_hi;
@@ -62,7 +62,7 @@ savage_bci_wait_fifo_shadow(drm_savage_private_t *dev_priv, unsigned int n)
}
static int
-savage_bci_wait_fifo_s3d(drm_savage_private_t *dev_priv, unsigned int n)
+savage_bci_wait_fifo_s3d(drm_savage_private_t * dev_priv, unsigned int n)
{
uint32_t maxUsed = dev_priv->cob_size + SAVAGE_BCI_FIFO_SIZE - n;
uint32_t status;
@@ -83,7 +83,7 @@ savage_bci_wait_fifo_s3d(drm_savage_private_t *dev_priv, unsigned int n)
}
static int
-savage_bci_wait_fifo_s4(drm_savage_private_t *dev_priv, unsigned int n)
+savage_bci_wait_fifo_s4(drm_savage_private_t * dev_priv, unsigned int n)
{
uint32_t maxUsed = dev_priv->cob_size + SAVAGE_BCI_FIFO_SIZE - n;
uint32_t status;
@@ -115,7 +115,7 @@ savage_bci_wait_fifo_s4(drm_savage_private_t *dev_priv, unsigned int n)
* rule. Otherwise there may be glitches every 2^16 events.
*/
static int
-savage_bci_wait_event_shadow(drm_savage_private_t *dev_priv, uint16_t e)
+savage_bci_wait_event_shadow(drm_savage_private_t * dev_priv, uint16_t e)
{
uint32_t status;
int i;
@@ -138,7 +138,7 @@ savage_bci_wait_event_shadow(drm_savage_private_t *dev_priv, uint16_t e)
}
static int
-savage_bci_wait_event_reg(drm_savage_private_t *dev_priv, uint16_t e)
+savage_bci_wait_event_reg(drm_savage_private_t * dev_priv, uint16_t e)
{
uint32_t status;
int i;
@@ -159,7 +159,7 @@ savage_bci_wait_event_reg(drm_savage_private_t *dev_priv, uint16_t e)
return DRM_ERR(EBUSY);
}
-uint16_t savage_bci_emit_event(drm_savage_private_t *dev_priv,
+uint16_t savage_bci_emit_event(drm_savage_private_t * dev_priv,
unsigned int flags)
{
uint16_t count;
@@ -175,12 +175,12 @@ uint16_t savage_bci_emit_event(drm_savage_private_t *dev_priv,
}
count = (count + 1) & 0xffff;
if (count == 0) {
- count++; /* See the comment above savage_wait_event_*. */
+ count++; /* See the comment above savage_wait_event_*. */
dev_priv->event_wrap++;
}
dev_priv->event_counter = count;
if (dev_priv->status_ptr)
- dev_priv->status_ptr[1023] = (uint32_t)count;
+ dev_priv->status_ptr[1023] = (uint32_t) count;
if ((flags & (SAVAGE_WAIT_2D | SAVAGE_WAIT_3D))) {
unsigned int wait_cmd = BCI_CMD_WAIT;
@@ -193,7 +193,7 @@ uint16_t savage_bci_emit_event(drm_savage_private_t *dev_priv,
} else {
BEGIN_BCI(1);
}
- BCI_WRITE(BCI_CMD_UPDATE_EVENT_TAG | (uint32_t)count);
+ BCI_WRITE(BCI_CMD_UPDATE_EVENT_TAG | (uint32_t) count);
return count;
}
@@ -201,7 +201,7 @@ uint16_t savage_bci_emit_event(drm_savage_private_t *dev_priv,
/*
* Freelist management
*/
-static int savage_freelist_init(drm_device_t *dev)
+static int savage_freelist_init(drm_device_t * dev)
{
drm_savage_private_t *dev_priv = dev->dev_private;
drm_device_dma_t *dma = dev->dma;
@@ -234,7 +234,7 @@ static int savage_freelist_init(drm_device_t *dev)
return 0;
}
-static drm_buf_t *savage_freelist_get(drm_device_t *dev)
+static drm_buf_t *savage_freelist_get(drm_device_t * dev)
{
drm_savage_private_t *dev_priv = dev->dev_private;
drm_savage_buf_priv_t *tail = dev_priv->tail.prev;
@@ -249,7 +249,7 @@ static drm_buf_t *savage_freelist_get(drm_device_t *dev)
event = SAVAGE_READ(SAVAGE_STATUS_WORD1) & 0xffff;
wrap = dev_priv->event_wrap;
if (event > dev_priv->event_counter)
- wrap--; /* hardware hasn't passed the last wrap yet */
+ wrap--; /* hardware hasn't passed the last wrap yet */
DRM_DEBUG(" tail=0x%04x %d\n", tail->age.event, tail->age.wrap);
DRM_DEBUG(" head=0x%04x %d\n", event, wrap);
@@ -267,7 +267,7 @@ static drm_buf_t *savage_freelist_get(drm_device_t *dev)
return NULL;
}
-void savage_freelist_put(drm_device_t *dev, drm_buf_t *buf)
+void savage_freelist_put(drm_device_t * dev, drm_buf_t * buf)
{
drm_savage_private_t *dev_priv = dev->dev_private;
drm_savage_buf_priv_t *entry = buf->dev_private, *prev, *next;
@@ -290,15 +290,14 @@ void savage_freelist_put(drm_device_t *dev, drm_buf_t *buf)
/*
* Command DMA
*/
-static int savage_dma_init(drm_savage_private_t *dev_priv)
+static int savage_dma_init(drm_savage_private_t * dev_priv)
{
unsigned int i;
dev_priv->nr_dma_pages = dev_priv->cmd_dma->size /
- (SAVAGE_DMA_PAGE_SIZE*4);
+ (SAVAGE_DMA_PAGE_SIZE * 4);
dev_priv->dma_pages = drm_alloc(sizeof(drm_savage_dma_page_t) *
- dev_priv->nr_dma_pages,
- DRM_MEM_DRIVER);
+ dev_priv->nr_dma_pages, DRM_MEM_DRIVER);
if (dev_priv->dma_pages == NULL)
return DRM_ERR(ENOMEM);
@@ -315,7 +314,7 @@ static int savage_dma_init(drm_savage_private_t *dev_priv)
return 0;
}
-void savage_dma_reset(drm_savage_private_t *dev_priv)
+void savage_dma_reset(drm_savage_private_t * dev_priv)
{
uint16_t event;
unsigned int wrap, i;
@@ -330,7 +329,7 @@ void savage_dma_reset(drm_savage_private_t *dev_priv)
dev_priv->first_dma_page = dev_priv->current_dma_page = 0;
}
-void savage_dma_wait(drm_savage_private_t *dev_priv, unsigned int page)
+void savage_dma_wait(drm_savage_private_t * dev_priv, unsigned int page)
{
uint16_t event;
unsigned int wrap;
@@ -346,7 +345,7 @@ void savage_dma_wait(drm_savage_private_t *dev_priv, unsigned int page)
event = SAVAGE_READ(SAVAGE_STATUS_WORD1) & 0xffff;
wrap = dev_priv->event_wrap;
if (event > dev_priv->event_counter)
- wrap--; /* hardware hasn't passed the last wrap yet */
+ wrap--; /* hardware hasn't passed the last wrap yet */
if (dev_priv->dma_pages[page].age.wrap > wrap ||
(dev_priv->dma_pages[page].age.wrap == wrap &&
@@ -358,13 +357,13 @@ void savage_dma_wait(drm_savage_private_t *dev_priv, unsigned int page)
}
}
-uint32_t *savage_dma_alloc(drm_savage_private_t *dev_priv, unsigned int n)
+uint32_t *savage_dma_alloc(drm_savage_private_t * dev_priv, unsigned int n)
{
unsigned int cur = dev_priv->current_dma_page;
unsigned int rest = SAVAGE_DMA_PAGE_SIZE -
- dev_priv->dma_pages[cur].used;
- unsigned int nr_pages = (n - rest + SAVAGE_DMA_PAGE_SIZE-1) /
- SAVAGE_DMA_PAGE_SIZE;
+ dev_priv->dma_pages[cur].used;
+ unsigned int nr_pages = (n - rest + SAVAGE_DMA_PAGE_SIZE - 1) /
+ SAVAGE_DMA_PAGE_SIZE;
uint32_t *dma_ptr;
unsigned int i;
@@ -372,9 +371,8 @@ uint32_t *savage_dma_alloc(drm_savage_private_t *dev_priv, unsigned int n)
cur, dev_priv->dma_pages[cur].used, n, rest, nr_pages);
if (cur + nr_pages < dev_priv->nr_dma_pages) {
- dma_ptr = (uint32_t *)dev_priv->cmd_dma->handle +
- cur*SAVAGE_DMA_PAGE_SIZE +
- dev_priv->dma_pages[cur].used;
+ dma_ptr = (uint32_t *) dev_priv->cmd_dma->handle +
+ cur * SAVAGE_DMA_PAGE_SIZE + dev_priv->dma_pages[cur].used;
if (n < rest)
rest = n;
dev_priv->dma_pages[cur].used += rest;
@@ -382,13 +380,14 @@ uint32_t *savage_dma_alloc(drm_savage_private_t *dev_priv, unsigned int n)
cur++;
} else {
dev_priv->dma_flush(dev_priv);
- nr_pages = (n + SAVAGE_DMA_PAGE_SIZE-1) / SAVAGE_DMA_PAGE_SIZE;
+ nr_pages =
+ (n + SAVAGE_DMA_PAGE_SIZE - 1) / SAVAGE_DMA_PAGE_SIZE;
for (i = cur; i < dev_priv->nr_dma_pages; ++i) {
dev_priv->dma_pages[i].age = dev_priv->last_dma_age;
dev_priv->dma_pages[i].used = 0;
dev_priv->dma_pages[i].flushed = 0;
}
- dma_ptr = (uint32_t *)dev_priv->cmd_dma->handle;
+ dma_ptr = (uint32_t *) dev_priv->cmd_dma->handle;
dev_priv->first_dma_page = cur = 0;
}
for (i = cur; nr_pages > 0; ++i, --nr_pages) {
@@ -414,7 +413,7 @@ uint32_t *savage_dma_alloc(drm_savage_private_t *dev_priv, unsigned int n)
return dma_ptr;
}
-static void savage_dma_flush(drm_savage_private_t *dev_priv)
+static void savage_dma_flush(drm_savage_private_t * dev_priv)
{
unsigned int first = dev_priv->first_dma_page;
unsigned int cur = dev_priv->current_dma_page;
@@ -439,11 +438,10 @@ static void savage_dma_flush(drm_savage_private_t *dev_priv)
/* pad with noops */
if (pad) {
- uint32_t *dma_ptr = (uint32_t *)dev_priv->cmd_dma->handle +
- cur * SAVAGE_DMA_PAGE_SIZE +
- dev_priv->dma_pages[cur].used;
+ uint32_t *dma_ptr = (uint32_t *) dev_priv->cmd_dma->handle +
+ cur * SAVAGE_DMA_PAGE_SIZE + dev_priv->dma_pages[cur].used;
dev_priv->dma_pages[cur].used += pad;
- while(pad != 0) {
+ while (pad != 0) {
*dma_ptr++ = BCI_CMD_WAIT;
pad--;
}
@@ -453,11 +451,10 @@ static void savage_dma_flush(drm_savage_private_t *dev_priv)
/* do flush ... */
phys_addr = dev_priv->cmd_dma->offset +
- (first * SAVAGE_DMA_PAGE_SIZE +
- dev_priv->dma_pages[first].flushed) * 4;
+ (first * SAVAGE_DMA_PAGE_SIZE +
+ dev_priv->dma_pages[first].flushed) * 4;
len = (cur - first) * SAVAGE_DMA_PAGE_SIZE +
- dev_priv->dma_pages[cur].used -
- dev_priv->dma_pages[first].flushed;
+ dev_priv->dma_pages[cur].used - dev_priv->dma_pages[first].flushed;
DRM_DEBUG("phys_addr=%lx, len=%u\n",
phys_addr | dev_priv->dma_type, len);
@@ -499,7 +496,7 @@ static void savage_dma_flush(drm_savage_private_t *dev_priv)
dev_priv->dma_pages[cur].flushed);
}
-static void savage_fake_dma_flush(drm_savage_private_t *dev_priv)
+static void savage_fake_dma_flush(drm_savage_private_t * dev_priv)
{
unsigned int i, j;
BCI_LOCALS;
@@ -515,8 +512,8 @@ static void savage_fake_dma_flush(drm_savage_private_t *dev_priv)
for (i = dev_priv->first_dma_page;
i <= dev_priv->current_dma_page && dev_priv->dma_pages[i].used;
++i) {
- uint32_t *dma_ptr = (uint32_t *)dev_priv->cmd_dma->handle +
- i * SAVAGE_DMA_PAGE_SIZE;
+ uint32_t *dma_ptr = (uint32_t *) dev_priv->cmd_dma->handle +
+ i * SAVAGE_DMA_PAGE_SIZE;
#if SAVAGE_DMA_DEBUG
/* Sanity check: all pages except the last one must be full. */
if (i < dev_priv->current_dma_page &&
@@ -543,7 +540,7 @@ static void savage_fake_dma_flush(drm_savage_private_t *dev_priv)
* initialized. We also need to take care of deleting the MTRRs in
* postcleanup.
*/
-int savage_preinit(drm_device_t *dev, unsigned long chipset)
+int savage_preinit(drm_device_t * dev, unsigned long chipset)
{
drm_savage_private_t *dev_priv;
unsigned long mmio_base, fb_base, fb_size, aperture_base;
@@ -578,19 +575,22 @@ int savage_preinit(drm_device_t *dev, unsigned long chipset)
* MTRRs. */
dev_priv->mtrr[0].base = fb_base;
dev_priv->mtrr[0].size = 0x01000000;
- dev_priv->mtrr[0].handle = mtrr_add(
- dev_priv->mtrr[0].base, dev_priv->mtrr[0].size,
- MTRR_TYPE_WRCOMB, 1);
- dev_priv->mtrr[1].base = fb_base+0x02000000;
+ dev_priv->mtrr[0].handle =
+ mtrr_add(dev_priv->mtrr[0].base,
+ dev_priv->mtrr[0].size, MTRR_TYPE_WRCOMB,
+ 1);
+ dev_priv->mtrr[1].base = fb_base + 0x02000000;
dev_priv->mtrr[1].size = 0x02000000;
- dev_priv->mtrr[1].handle = mtrr_add(
- dev_priv->mtrr[1].base, dev_priv->mtrr[1].size,
- MTRR_TYPE_WRCOMB, 1);
- dev_priv->mtrr[2].base = fb_base+0x04000000;
+ dev_priv->mtrr[1].handle =
+ mtrr_add(dev_priv->mtrr[1].base,
+ dev_priv->mtrr[1].size, MTRR_TYPE_WRCOMB,
+ 1);
+ dev_priv->mtrr[2].base = fb_base + 0x04000000;
dev_priv->mtrr[2].size = 0x04000000;
- dev_priv->mtrr[2].handle = mtrr_add(
- dev_priv->mtrr[2].base, dev_priv->mtrr[2].size,
- MTRR_TYPE_WRCOMB, 1);
+ dev_priv->mtrr[2].handle =
+ mtrr_add(dev_priv->mtrr[2].base,
+ dev_priv->mtrr[2].size, MTRR_TYPE_WRCOMB,
+ 1);
} else {
DRM_ERROR("strange pci_resource_len %08lx\n",
drm_get_resource_len(dev, 0));
@@ -608,9 +608,10 @@ int savage_preinit(drm_device_t *dev, unsigned long chipset)
* aperture. */
dev_priv->mtrr[0].base = fb_base;
dev_priv->mtrr[0].size = 0x08000000;
- dev_priv->mtrr[0].handle = mtrr_add(
- dev_priv->mtrr[0].base, dev_priv->mtrr[0].size,
- MTRR_TYPE_WRCOMB, 1);
+ dev_priv->mtrr[0].handle =
+ mtrr_add(dev_priv->mtrr[0].base,
+ dev_priv->mtrr[0].size, MTRR_TYPE_WRCOMB,
+ 1);
} else {
DRM_ERROR("strange pci_resource_len %08lx\n",
drm_get_resource_len(dev, 1));
@@ -647,7 +648,7 @@ int savage_preinit(drm_device_t *dev, unsigned long chipset)
/*
* Delete MTRRs and free device-private data.
*/
-int savage_postcleanup(drm_device_t *dev)
+int savage_postcleanup(drm_device_t * dev)
{
drm_savage_private_t *dev_priv = dev->dev_private;
int i;
@@ -663,7 +664,7 @@ int savage_postcleanup(drm_device_t *dev)
return 0;
}
-static int savage_do_init_bci(drm_device_t *dev, drm_savage_init_t *init)
+static int savage_do_init_bci(drm_device_t * dev, drm_savage_init_t * init)
{
drm_savage_private_t *dev_priv = dev->dev_private;
@@ -731,7 +732,7 @@ static int savage_do_init_bci(drm_device_t *dev, drm_savage_init_t *init)
}
if (init->agp_textures_offset) {
dev_priv->agp_textures =
- drm_core_findmap(dev, init->agp_textures_offset);
+ drm_core_findmap(dev, init->agp_textures_offset);
if (!dev_priv->agp_textures) {
DRM_ERROR("could not find agp texture region!\n");
savage_do_cleanup_bci(dev);
@@ -802,8 +803,8 @@ static int savage_do_init_bci(drm_device_t *dev, drm_savage_init_t *init)
}
dev_priv->sarea_priv =
- (drm_savage_sarea_t *)((uint8_t *)dev_priv->sarea->handle +
- init->sarea_priv_offset);
+ (drm_savage_sarea_t *) ((uint8_t *) dev_priv->sarea->handle +
+ init->sarea_priv_offset);
/* setup bitmap descriptors */
{
@@ -812,35 +813,36 @@ static int savage_do_init_bci(drm_device_t *dev, drm_savage_init_t *init)
unsigned int front_stride, back_stride, depth_stride;
if (dev_priv->chipset <= S3_SAVAGE4) {
color_tile_format = dev_priv->fb_bpp == 16 ?
- SAVAGE_BD_TILE_16BPP : SAVAGE_BD_TILE_32BPP;
+ SAVAGE_BD_TILE_16BPP : SAVAGE_BD_TILE_32BPP;
depth_tile_format = dev_priv->depth_bpp == 16 ?
- SAVAGE_BD_TILE_16BPP : SAVAGE_BD_TILE_32BPP;
+ SAVAGE_BD_TILE_16BPP : SAVAGE_BD_TILE_32BPP;
} else {
color_tile_format = SAVAGE_BD_TILE_DEST;
depth_tile_format = SAVAGE_BD_TILE_DEST;
}
- front_stride = dev_priv->front_pitch / (dev_priv->fb_bpp/8);
- back_stride = dev_priv-> back_pitch / (dev_priv->fb_bpp/8);
- depth_stride = dev_priv->depth_pitch / (dev_priv->depth_bpp/8);
+ front_stride = dev_priv->front_pitch / (dev_priv->fb_bpp / 8);
+ back_stride = dev_priv->back_pitch / (dev_priv->fb_bpp / 8);
+ depth_stride =
+ dev_priv->depth_pitch / (dev_priv->depth_bpp / 8);
dev_priv->front_bd = front_stride | SAVAGE_BD_BW_DISABLE |
- (dev_priv->fb_bpp << SAVAGE_BD_BPP_SHIFT) |
- (color_tile_format << SAVAGE_BD_TILE_SHIFT);
+ (dev_priv->fb_bpp << SAVAGE_BD_BPP_SHIFT) |
+ (color_tile_format << SAVAGE_BD_TILE_SHIFT);
- dev_priv-> back_bd = back_stride | SAVAGE_BD_BW_DISABLE |
- (dev_priv->fb_bpp << SAVAGE_BD_BPP_SHIFT) |
- (color_tile_format << SAVAGE_BD_TILE_SHIFT);
+ dev_priv->back_bd = back_stride | SAVAGE_BD_BW_DISABLE |
+ (dev_priv->fb_bpp << SAVAGE_BD_BPP_SHIFT) |
+ (color_tile_format << SAVAGE_BD_TILE_SHIFT);
dev_priv->depth_bd = depth_stride | SAVAGE_BD_BW_DISABLE |
- (dev_priv->depth_bpp << SAVAGE_BD_BPP_SHIFT) |
- (depth_tile_format << SAVAGE_BD_TILE_SHIFT);
+ (dev_priv->depth_bpp << SAVAGE_BD_BPP_SHIFT) |
+ (depth_tile_format << SAVAGE_BD_TILE_SHIFT);
}
/* setup status and bci ptr */
dev_priv->event_counter = 0;
dev_priv->event_wrap = 0;
dev_priv->bci_ptr = (volatile uint32_t *)
- ((uint8_t *)dev_priv->mmio->handle + SAVAGE_BCI_OFFSET);
+ ((uint8_t *) dev_priv->mmio->handle + SAVAGE_BCI_OFFSET);
if (S3_SAVAGE3D_SERIES(dev_priv->chipset)) {
dev_priv->status_used_mask = SAVAGE_FIFO_USED_MASK_S3D;
} else {
@@ -848,7 +850,7 @@ static int savage_do_init_bci(drm_device_t *dev, drm_savage_init_t *init)
}
if (dev_priv->status != NULL) {
dev_priv->status_ptr =
- (volatile uint32_t *)dev_priv->status->handle;
+ (volatile uint32_t *)dev_priv->status->handle;
dev_priv->wait_fifo = savage_bci_wait_fifo_shadow;
dev_priv->wait_evnt = savage_bci_wait_event_shadow;
dev_priv->status_ptr[1023] = dev_priv->event_counter;
@@ -874,7 +876,7 @@ static int savage_do_init_bci(drm_device_t *dev, drm_savage_init_t *init)
return DRM_ERR(ENOMEM);
}
- if (savage_dma_init(dev_priv) < 0) {
+ if (savage_dma_init(dev_priv) < 0) {
DRM_ERROR("could not initialize command DMA\n");
savage_do_cleanup_bci(dev);
return DRM_ERR(ENOMEM);
@@ -883,7 +885,7 @@ static int savage_do_init_bci(drm_device_t *dev, drm_savage_init_t *init)
return 0;
}
-int savage_do_cleanup_bci(drm_device_t *dev)
+int savage_do_cleanup_bci(drm_device_t * dev)
{
drm_savage_private_t *dev_priv = dev->dev_private;
@@ -907,7 +909,7 @@ int savage_do_cleanup_bci(drm_device_t *dev)
if (dev_priv->dma_pages)
drm_free(dev_priv->dma_pages,
- sizeof(drm_savage_dma_page_t)*dev_priv->nr_dma_pages,
+ sizeof(drm_savage_dma_page_t) * dev_priv->nr_dma_pages,
DRM_MEM_DRIVER);
return 0;
@@ -920,7 +922,7 @@ static int savage_bci_init(DRM_IOCTL_ARGS)
LOCK_TEST_WITH_RETURN(dev, filp);
- DRM_COPY_FROM_USER_IOCTL(init, (drm_savage_init_t __user *)data,
+ DRM_COPY_FROM_USER_IOCTL(init, (drm_savage_init_t __user *) data,
sizeof(init));
switch (init.func) {
@@ -943,13 +945,13 @@ static int savage_bci_event_emit(DRM_IOCTL_ARGS)
LOCK_TEST_WITH_RETURN(dev, filp);
- DRM_COPY_FROM_USER_IOCTL(event, (drm_savage_event_emit_t __user *)data,
+ DRM_COPY_FROM_USER_IOCTL(event, (drm_savage_event_emit_t __user *) data,
sizeof(event));
event.count = savage_bci_emit_event(dev_priv, event.flags);
event.count |= dev_priv->event_wrap << 16;
- DRM_COPY_TO_USER_IOCTL(&((drm_savage_event_emit_t __user *)data)->count,
- event.count, sizeof(event.count));
+ DRM_COPY_TO_USER_IOCTL(&((drm_savage_event_emit_t __user *) data)->
+ count, event.count, sizeof(event.count));
return 0;
}
@@ -963,7 +965,7 @@ static int savage_bci_event_wait(DRM_IOCTL_ARGS)
DRM_DEBUG("\n");
- DRM_COPY_FROM_USER_IOCTL(event, (drm_savage_event_wait_t __user *)data,
+ DRM_COPY_FROM_USER_IOCTL(event, (drm_savage_event_wait_t __user *) data,
sizeof(event));
UPDATE_EVENT_COUNTER();
@@ -973,7 +975,7 @@ static int savage_bci_event_wait(DRM_IOCTL_ARGS)
hw_e = SAVAGE_READ(SAVAGE_STATUS_WORD1) & 0xffff;
hw_w = dev_priv->event_wrap;
if (hw_e > dev_priv->event_counter)
- hw_w--; /* hardware hasn't passed the last wrap yet */
+ hw_w--; /* hardware hasn't passed the last wrap yet */
event_e = event.count & 0xffff;
event_w = event.count >> 16;
@@ -982,7 +984,7 @@ static int savage_bci_event_wait(DRM_IOCTL_ARGS)
* - event counter wrapped since the event was emitted or
* - the hardware has advanced up to or over the event to wait for.
*/
- if (event_w < hw_w || (event_w == hw_w && event_e <= hw_e) )
+ if (event_w < hw_w || (event_w == hw_w && event_e <= hw_e))
return 0;
else
return dev_priv->wait_evnt(dev_priv, event_e);
@@ -992,7 +994,8 @@ static int savage_bci_event_wait(DRM_IOCTL_ARGS)
* DMA buffer management
*/
-static int savage_bci_get_buffers(DRMFILE filp, drm_device_t *dev, drm_dma_t *d)
+static int savage_bci_get_buffers(DRMFILE filp, drm_device_t * dev,
+ drm_dma_t * d)
{
drm_buf_t *buf;
int i;
@@ -1025,7 +1028,7 @@ int savage_bci_buffers(DRM_IOCTL_ARGS)
LOCK_TEST_WITH_RETURN(dev, filp);
- DRM_COPY_FROM_USER_IOCTL(d, (drm_dma_t __user *)data, sizeof(d));
+ DRM_COPY_FROM_USER_IOCTL(d, (drm_dma_t __user *) data, sizeof(d));
/* Please don't send us buffers.
*/
@@ -1049,12 +1052,13 @@ int savage_bci_buffers(DRM_IOCTL_ARGS)
ret = savage_bci_get_buffers(filp, dev, &d);
}
- DRM_COPY_TO_USER_IOCTL((drm_dma_t __user *)data, d, sizeof(d));
+ DRM_COPY_TO_USER_IOCTL((drm_dma_t __user *) data, d, sizeof(d));
return ret;
}
-void savage_reclaim_buffers(drm_device_t *dev, DRMFILE filp) {
+void savage_reclaim_buffers(drm_device_t * dev, DRMFILE filp)
+{
drm_device_dma_t *dma = dev->dma;
drm_savage_private_t *dev_priv = dev->dev_private;
int i;
@@ -1066,7 +1070,7 @@ void savage_reclaim_buffers(drm_device_t *dev, DRMFILE filp) {
if (!dma->buflist)
return;
- /*i830_flush_queue(dev);*/
+ /*i830_flush_queue(dev); */
for (i = 0; i < dma->buf_count; i++) {
drm_buf_t *buf = dma->buflist[i];
@@ -1085,7 +1089,6 @@ void savage_reclaim_buffers(drm_device_t *dev, DRMFILE filp) {
drm_core_reclaim_buffers(dev, filp);
}
-
drm_ioctl_desc_t savage_ioctls[] = {
[DRM_IOCTL_NR(DRM_SAVAGE_BCI_INIT)] = {savage_bci_init, 1, 1},
[DRM_IOCTL_NR(DRM_SAVAGE_BCI_CMDBUF)] = {savage_bci_cmdbuf, 1, 0},
diff --git a/drivers/char/drm/savage_drm.h b/drivers/char/drm/savage_drm.h
index 6526c9aa7589..e1148e8e7994 100644
--- a/drivers/char/drm/savage_drm.h
+++ b/drivers/char/drm/savage_drm.h
@@ -42,12 +42,13 @@
#define SAVAGE_NR_TEX_REGIONS 16
#define SAVAGE_LOG_MIN_TEX_REGION_SIZE 16
-#endif /* __SAVAGE_SAREA_DEFINES__ */
+#endif /* __SAVAGE_SAREA_DEFINES__ */
typedef struct _drm_savage_sarea {
/* LRU lists for texture memory in agp space and on the card.
*/
- drm_tex_region_t texList[SAVAGE_NR_TEX_HEAPS][SAVAGE_NR_TEX_REGIONS+1];
+ drm_tex_region_t texList[SAVAGE_NR_TEX_HEAPS][SAVAGE_NR_TEX_REGIONS +
+ 1];
unsigned int texAge[SAVAGE_NR_TEX_HEAPS];
/* Mechanism to validate card state.
@@ -101,24 +102,24 @@ typedef struct drm_savage_init {
typedef union drm_savage_cmd_header drm_savage_cmd_header_t;
typedef struct drm_savage_cmdbuf {
- /* command buffer in client's address space */
+ /* command buffer in client's address space */
drm_savage_cmd_header_t __user *cmd_addr;
unsigned int size; /* size of the command buffer in 64bit units */
unsigned int dma_idx; /* DMA buffer index to use */
int discard; /* discard DMA buffer when done */
- /* vertex buffer in client's address space */
+ /* vertex buffer in client's address space */
unsigned int __user *vb_addr;
unsigned int vb_size; /* size of client vertex buffer in bytes */
unsigned int vb_stride; /* stride of vertices in 32bit words */
- /* boxes in client's address space */
+ /* boxes in client's address space */
drm_clip_rect_t __user *box_addr;
unsigned int nbox; /* number of clipping boxes */
} drm_savage_cmdbuf_t;
-#define SAVAGE_WAIT_2D 0x1 /* wait for 2D idle before updating event tag */
-#define SAVAGE_WAIT_3D 0x2 /* wait for 3D idle before updating event tag */
-#define SAVAGE_WAIT_IRQ 0x4 /* emit or wait for IRQ, not implemented yet */
+#define SAVAGE_WAIT_2D 0x1 /* wait for 2D idle before updating event tag */
+#define SAVAGE_WAIT_3D 0x2 /* wait for 3D idle before updating event tag */
+#define SAVAGE_WAIT_IRQ 0x4 /* emit or wait for IRQ, not implemented yet */
typedef struct drm_savage_event {
unsigned int count;
unsigned int flags;
@@ -126,21 +127,21 @@ typedef struct drm_savage_event {
/* Commands for the cmdbuf ioctl
*/
-#define SAVAGE_CMD_STATE 0 /* a range of state registers */
-#define SAVAGE_CMD_DMA_PRIM 1 /* vertices from DMA buffer */
-#define SAVAGE_CMD_VB_PRIM 2 /* vertices from client vertex buffer */
-#define SAVAGE_CMD_DMA_IDX 3 /* indexed vertices from DMA buffer */
-#define SAVAGE_CMD_VB_IDX 4 /* indexed vertices client vertex buffer */
-#define SAVAGE_CMD_CLEAR 5 /* clear buffers */
-#define SAVAGE_CMD_SWAP 6 /* swap buffers */
+#define SAVAGE_CMD_STATE 0 /* a range of state registers */
+#define SAVAGE_CMD_DMA_PRIM 1 /* vertices from DMA buffer */
+#define SAVAGE_CMD_VB_PRIM 2 /* vertices from client vertex buffer */
+#define SAVAGE_CMD_DMA_IDX 3 /* indexed vertices from DMA buffer */
+#define SAVAGE_CMD_VB_IDX 4 /* indexed vertices client vertex buffer */
+#define SAVAGE_CMD_CLEAR 5 /* clear buffers */
+#define SAVAGE_CMD_SWAP 6 /* swap buffers */
/* Primitive types
*/
-#define SAVAGE_PRIM_TRILIST 0 /* triangle list */
-#define SAVAGE_PRIM_TRISTRIP 1 /* triangle strip */
-#define SAVAGE_PRIM_TRIFAN 2 /* triangle fan */
-#define SAVAGE_PRIM_TRILIST_201 3 /* reorder verts for correct flat
- * shading on s3d */
+#define SAVAGE_PRIM_TRILIST 0 /* triangle list */
+#define SAVAGE_PRIM_TRISTRIP 1 /* triangle strip */
+#define SAVAGE_PRIM_TRIFAN 2 /* triangle fan */
+#define SAVAGE_PRIM_TRILIST_201 3 /* reorder verts for correct flat
+ * shading on s3d */
/* Skip flags (vertex format)
*/
@@ -172,38 +173,38 @@ union drm_savage_cmd_header {
unsigned short pad1;
unsigned short pad2;
unsigned short pad3;
- } cmd; /* generic */
+ } cmd; /* generic */
struct {
unsigned char cmd;
unsigned char global; /* need idle engine? */
unsigned short count; /* number of consecutive registers */
unsigned short start; /* first register */
unsigned short pad3;
- } state; /* SAVAGE_CMD_STATE */
+ } state; /* SAVAGE_CMD_STATE */
struct {
unsigned char cmd;
unsigned char prim; /* primitive type */
unsigned short skip; /* vertex format (skip flags) */
unsigned short count; /* number of vertices */
unsigned short start; /* first vertex in DMA/vertex buffer */
- } prim; /* SAVAGE_CMD_DMA_PRIM, SAVAGE_CMD_VB_PRIM */
+ } prim; /* SAVAGE_CMD_DMA_PRIM, SAVAGE_CMD_VB_PRIM */
struct {
unsigned char cmd;
unsigned char prim;
unsigned short skip;
unsigned short count; /* number of indices that follow */
unsigned short pad3;
- } idx; /* SAVAGE_CMD_DMA_IDX, SAVAGE_CMD_VB_IDX */
+ } idx; /* SAVAGE_CMD_DMA_IDX, SAVAGE_CMD_VB_IDX */
struct {
unsigned char cmd;
unsigned char pad0;
unsigned short pad1;
unsigned int flags;
- } clear0; /* SAVAGE_CMD_CLEAR */
+ } clear0; /* SAVAGE_CMD_CLEAR */
struct {
unsigned int mask;
unsigned int value;
- } clear1; /* SAVAGE_CMD_CLEAR data */
+ } clear1; /* SAVAGE_CMD_CLEAR data */
};
#endif
diff --git a/drivers/char/drm/savage_drv.c b/drivers/char/drm/savage_drv.c
index ac8d270427ca..22d799cde41c 100644
--- a/drivers/char/drm/savage_drv.c
+++ b/drivers/char/drm/savage_drv.c
@@ -30,30 +30,28 @@
#include "drm_pciids.h"
-static int postinit( struct drm_device *dev, unsigned long flags )
+static int postinit(struct drm_device *dev, unsigned long flags)
{
- DRM_INFO( "Initialized %s %d.%d.%d %s on minor %d: %s\n",
- DRIVER_NAME,
- DRIVER_MAJOR,
- DRIVER_MINOR,
- DRIVER_PATCHLEVEL,
- DRIVER_DATE,
- dev->primary.minor,
- pci_pretty_name(dev->pdev)
- );
+ DRM_INFO("Initialized %s %d.%d.%d %s on minor %d: %s\n",
+ DRIVER_NAME,
+ DRIVER_MAJOR,
+ DRIVER_MINOR,
+ DRIVER_PATCHLEVEL,
+ DRIVER_DATE, dev->primary.minor, pci_pretty_name(dev->pdev)
+ );
return 0;
}
-static int version( drm_version_t *version )
+static int version(drm_version_t * version)
{
int len;
version->version_major = DRIVER_MAJOR;
version->version_minor = DRIVER_MINOR;
version->version_patchlevel = DRIVER_PATCHLEVEL;
- DRM_COPY( version->name, DRIVER_NAME );
- DRM_COPY( version->date, DRIVER_DATE );
- DRM_COPY( version->desc, DRIVER_DESC );
+ DRM_COPY(version->name, DRIVER_NAME);
+ DRM_COPY(version->date, DRIVER_DATE);
+ DRM_COPY(version->desc, DRIVER_DESC);
return 0;
}
@@ -61,13 +59,9 @@ static struct pci_device_id pciidlist[] = {
savage_PCI_IDS
};
-extern drm_ioctl_desc_t savage_ioctls[];
-extern int savage_max_ioctl;
-
static struct drm_driver driver = {
.driver_features =
- DRIVER_USE_AGP | DRIVER_USE_MTRR |
- DRIVER_HAVE_DMA | DRIVER_PCI_DMA,
+ DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_HAVE_DMA | DRIVER_PCI_DMA,
.dev_priv_size = sizeof(drm_savage_buf_priv_t),
.preinit = savage_preinit,
.postinit = postinit,
@@ -79,18 +73,19 @@ static struct drm_driver driver = {
.ioctls = savage_ioctls,
.dma_ioctl = savage_bci_buffers,
.fops = {
- .owner = THIS_MODULE,
- .open = drm_open,
- .release = drm_release,
- .ioctl = drm_ioctl,
- .mmap = drm_mmap,
- .poll = drm_poll,
- .fasync = drm_fasync,
- },
+ .owner = THIS_MODULE,
+ .open = drm_open,
+ .release = drm_release,
+ .ioctl = drm_ioctl,
+ .mmap = drm_mmap,
+ .poll = drm_poll,
+ .fasync = drm_fasync,
+ }
+ ,
.pci_driver = {
- .name = DRIVER_NAME,
- .id_table = pciidlist,
- }
+ .name = DRIVER_NAME,
+ .id_table = pciidlist,
+ }
};
static int __init savage_init(void)
@@ -107,6 +102,6 @@ static void __exit savage_exit(void)
module_init(savage_init);
module_exit(savage_exit);
-MODULE_AUTHOR( DRIVER_AUTHOR );
-MODULE_DESCRIPTION( DRIVER_DESC );
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL and additional rights");
diff --git a/drivers/char/drm/savage_drv.h b/drivers/char/drm/savage_drv.h
index a45434944658..a4b0fa998a95 100644
--- a/drivers/char/drm/savage_drv.h
+++ b/drivers/char/drm/savage_drv.h
@@ -65,7 +65,7 @@ typedef struct drm_savage_dma_page {
drm_savage_age_t age;
unsigned int used, flushed;
} drm_savage_dma_page_t;
-#define SAVAGE_DMA_PAGE_SIZE 1024 /* in dwords */
+#define SAVAGE_DMA_PAGE_SIZE 1024 /* in dwords */
/* Fake DMA buffer size in bytes. 4 pages. Allows a maximum command
* size of 16kbytes or 4k entries. Minimum requirement would be
* 10kbytes for 255 40-byte vertices in one drawing command. */
@@ -104,6 +104,9 @@ enum savage_family {
S3_LAST
};
+extern drm_ioctl_desc_t savage_ioctls[];
+extern int savage_max_ioctl;
+
#define S3_SAVAGE3D_SERIES(chip) ((chip>=S3_SAVAGE3D) && (chip<=S3_SAVAGE_MX))
#define S3_SAVAGE4_SERIES(chip) ((chip==S3_SAVAGE4) \
@@ -184,13 +187,13 @@ typedef struct drm_savage_private {
unsigned int waiting;
/* config/hardware-dependent function pointers */
- int (*wait_fifo)(struct drm_savage_private *dev_priv, unsigned int n);
- int (*wait_evnt)(struct drm_savage_private *dev_priv, uint16_t e);
+ int (*wait_fifo) (struct drm_savage_private * dev_priv, unsigned int n);
+ int (*wait_evnt) (struct drm_savage_private * dev_priv, uint16_t e);
/* Err, there is a macro wait_event in include/linux/wait.h.
* Avoid unwanted macro expansion. */
- void (*emit_clip_rect)(struct drm_savage_private *dev_priv,
- drm_clip_rect_t *pbox);
- void (*dma_flush)(struct drm_savage_private *dev_priv);
+ void (*emit_clip_rect) (struct drm_savage_private * dev_priv,
+ drm_clip_rect_t * pbox);
+ void (*dma_flush) (struct drm_savage_private * dev_priv);
} drm_savage_private_t;
/* ioctls */
@@ -198,23 +201,23 @@ extern int savage_bci_cmdbuf(DRM_IOCTL_ARGS);
extern int savage_bci_buffers(DRM_IOCTL_ARGS);
/* BCI functions */
-extern uint16_t savage_bci_emit_event(drm_savage_private_t *dev_priv,
+extern uint16_t savage_bci_emit_event(drm_savage_private_t * dev_priv,
unsigned int flags);
-extern void savage_freelist_put(drm_device_t *dev, drm_buf_t *buf);
-extern void savage_dma_reset(drm_savage_private_t *dev_priv);
-extern void savage_dma_wait(drm_savage_private_t *dev_priv, unsigned int page);
-extern uint32_t *savage_dma_alloc(drm_savage_private_t *dev_priv,
+extern void savage_freelist_put(drm_device_t * dev, drm_buf_t * buf);
+extern void savage_dma_reset(drm_savage_private_t * dev_priv);
+extern void savage_dma_wait(drm_savage_private_t * dev_priv, unsigned int page);
+extern uint32_t *savage_dma_alloc(drm_savage_private_t * dev_priv,
unsigned int n);
-extern int savage_preinit(drm_device_t *dev, unsigned long chipset);
-extern int savage_postcleanup(drm_device_t *dev);
-extern int savage_do_cleanup_bci(drm_device_t *dev);
-extern void savage_reclaim_buffers(drm_device_t *dev, DRMFILE filp);
+extern int savage_preinit(drm_device_t * dev, unsigned long chipset);
+extern int savage_postcleanup(drm_device_t * dev);
+extern int savage_do_cleanup_bci(drm_device_t * dev);
+extern void savage_reclaim_buffers(drm_device_t * dev, DRMFILE filp);
/* state functions */
-extern void savage_emit_clip_rect_s3d(drm_savage_private_t *dev_priv,
- drm_clip_rect_t *pbox);
-extern void savage_emit_clip_rect_s4(drm_savage_private_t *dev_priv,
- drm_clip_rect_t *pbox);
+extern void savage_emit_clip_rect_s3d(drm_savage_private_t * dev_priv,
+ drm_clip_rect_t * pbox);
+extern void savage_emit_clip_rect_s4(drm_savage_private_t * dev_priv,
+ drm_clip_rect_t * pbox);
#define SAVAGE_FB_SIZE_S3 0x01000000 /* 16MB */
#define SAVAGE_FB_SIZE_S4 0x02000000 /* 32MB */
@@ -222,10 +225,10 @@ extern void savage_emit_clip_rect_s4(drm_savage_private_t *dev_priv,
#define SAVAGE_APERTURE_OFFSET 0x02000000 /* 32MB */
#define SAVAGE_APERTURE_SIZE 0x05000000 /* 5 tiled surfaces, 16MB each */
-#define SAVAGE_BCI_OFFSET 0x00010000 /* offset of the BCI region
+#define SAVAGE_BCI_OFFSET 0x00010000 /* offset of the BCI region
* inside the MMIO region */
-#define SAVAGE_BCI_FIFO_SIZE 32 /* number of entries in on-chip
- * BCI FIFO */
+#define SAVAGE_BCI_FIFO_SIZE 32 /* number of entries in on-chip
+ * BCI FIFO */
/*
* MMIO registers
@@ -278,7 +281,7 @@ extern void savage_emit_clip_rect_s4(drm_savage_private_t *dev_priv,
#define SAVAGE_TEXADDR1_S4 0x23
#define SAVAGE_TEXBLEND0_S4 0x24
#define SAVAGE_TEXBLEND1_S4 0x25
-#define SAVAGE_TEXXPRCLR_S4 0x26 /* never used */
+#define SAVAGE_TEXXPRCLR_S4 0x26 /* never used */
#define SAVAGE_TEXDESCR_S4 0x27
#define SAVAGE_FOGTABLE_S4 0x28
#define SAVAGE_FOGCTRL_S4 0x30
@@ -293,7 +296,7 @@ extern void savage_emit_clip_rect_s4(drm_savage_private_t *dev_priv,
#define SAVAGE_TEXBLENDCOLOR_S4 0x39
/* Savage3D/MX/IX 3D registers */
#define SAVAGE_TEXPALADDR_S3D 0x18
-#define SAVAGE_TEXXPRCLR_S3D 0x19 /* never used */
+#define SAVAGE_TEXXPRCLR_S3D 0x19 /* never used */
#define SAVAGE_TEXADDR_S3D 0x1A
#define SAVAGE_TEXDESCR_S3D 0x1B
#define SAVAGE_TEXCTRL_S3D 0x1C
@@ -305,7 +308,7 @@ extern void savage_emit_clip_rect_s4(drm_savage_private_t *dev_priv,
#define SAVAGE_DESTCTRL_S3D 0x34
#define SAVAGE_SCSTART_S3D 0x35
#define SAVAGE_SCEND_S3D 0x36
-#define SAVAGE_ZWATERMARK_S3D 0x37
+#define SAVAGE_ZWATERMARK_S3D 0x37
#define SAVAGE_DESTTEXRWWATERMARK_S3D 0x38
/* common stuff */
#define SAVAGE_VERTBUFADDR 0x3e
@@ -313,9 +316,9 @@ extern void savage_emit_clip_rect_s4(drm_savage_private_t *dev_priv,
#define SAVAGE_DMABUFADDR 0x51
/* texture enable bits (needed for tex addr checking) */
-#define SAVAGE_TEXCTRL_TEXEN_MASK 0x00010000 /* S3D */
-#define SAVAGE_TEXDESCR_TEX0EN_MASK 0x02000000 /* S4 */
-#define SAVAGE_TEXDESCR_TEX1EN_MASK 0x04000000 /* S4 */
+#define SAVAGE_TEXCTRL_TEXEN_MASK 0x00010000 /* S3D */
+#define SAVAGE_TEXDESCR_TEX0EN_MASK 0x02000000 /* S4 */
+#define SAVAGE_TEXDESCR_TEX1EN_MASK 0x04000000 /* S4 */
/* Global fields in Savage4/Twister/ProSavage 3D registers:
*
@@ -576,4 +579,4 @@ extern void savage_emit_clip_rect_s4(drm_savage_private_t *dev_priv,
#define TEST_AGE( age, e, w ) \
( (age)->wrap < (w) || ( (age)->wrap == (w) && (age)->event <= (e) ) )
-#endif /* __SAVAGE_DRV_H__ */
+#endif /* __SAVAGE_DRV_H__ */
diff --git a/drivers/char/drm/savage_state.c b/drivers/char/drm/savage_state.c
index 475695a00083..e87a5d59b99c 100644
--- a/drivers/char/drm/savage_state.c
+++ b/drivers/char/drm/savage_state.c
@@ -26,48 +26,48 @@
#include "savage_drm.h"
#include "savage_drv.h"
-void savage_emit_clip_rect_s3d(drm_savage_private_t *dev_priv,
- drm_clip_rect_t *pbox)
+void savage_emit_clip_rect_s3d(drm_savage_private_t * dev_priv,
+ drm_clip_rect_t * pbox)
{
uint32_t scstart = dev_priv->state.s3d.new_scstart;
- uint32_t scend = dev_priv->state.s3d.new_scend;
+ uint32_t scend = dev_priv->state.s3d.new_scend;
scstart = (scstart & ~SAVAGE_SCISSOR_MASK_S3D) |
- ((uint32_t)pbox->x1 & 0x000007ff) |
- (((uint32_t)pbox->y1 << 16) & 0x07ff0000);
- scend = (scend & ~SAVAGE_SCISSOR_MASK_S3D) |
- (((uint32_t)pbox->x2-1) & 0x000007ff) |
- ((((uint32_t)pbox->y2-1) << 16) & 0x07ff0000);
+ ((uint32_t) pbox->x1 & 0x000007ff) |
+ (((uint32_t) pbox->y1 << 16) & 0x07ff0000);
+ scend = (scend & ~SAVAGE_SCISSOR_MASK_S3D) |
+ (((uint32_t) pbox->x2 - 1) & 0x000007ff) |
+ ((((uint32_t) pbox->y2 - 1) << 16) & 0x07ff0000);
if (scstart != dev_priv->state.s3d.scstart ||
- scend != dev_priv->state.s3d.scend) {
+ scend != dev_priv->state.s3d.scend) {
DMA_LOCALS;
BEGIN_DMA(4);
- DMA_WRITE(BCI_CMD_WAIT|BCI_CMD_WAIT_3D);
+ DMA_WRITE(BCI_CMD_WAIT | BCI_CMD_WAIT_3D);
DMA_SET_REGISTERS(SAVAGE_SCSTART_S3D, 2);
DMA_WRITE(scstart);
DMA_WRITE(scend);
dev_priv->state.s3d.scstart = scstart;
- dev_priv->state.s3d.scend = scend;
+ dev_priv->state.s3d.scend = scend;
dev_priv->waiting = 1;
DMA_COMMIT();
}
}
-void savage_emit_clip_rect_s4(drm_savage_private_t *dev_priv,
- drm_clip_rect_t *pbox)
+void savage_emit_clip_rect_s4(drm_savage_private_t * dev_priv,
+ drm_clip_rect_t * pbox)
{
uint32_t drawctrl0 = dev_priv->state.s4.new_drawctrl0;
uint32_t drawctrl1 = dev_priv->state.s4.new_drawctrl1;
drawctrl0 = (drawctrl0 & ~SAVAGE_SCISSOR_MASK_S4) |
- ((uint32_t)pbox->x1 & 0x000007ff) |
- (((uint32_t)pbox->y1 << 12) & 0x00fff000);
+ ((uint32_t) pbox->x1 & 0x000007ff) |
+ (((uint32_t) pbox->y1 << 12) & 0x00fff000);
drawctrl1 = (drawctrl1 & ~SAVAGE_SCISSOR_MASK_S4) |
- (((uint32_t)pbox->x2-1) & 0x000007ff) |
- ((((uint32_t)pbox->y2-1) << 12) & 0x00fff000);
+ (((uint32_t) pbox->x2 - 1) & 0x000007ff) |
+ ((((uint32_t) pbox->y2 - 1) << 12) & 0x00fff000);
if (drawctrl0 != dev_priv->state.s4.drawctrl0 ||
drawctrl1 != dev_priv->state.s4.drawctrl1) {
DMA_LOCALS;
BEGIN_DMA(4);
- DMA_WRITE(BCI_CMD_WAIT|BCI_CMD_WAIT_3D);
+ DMA_WRITE(BCI_CMD_WAIT | BCI_CMD_WAIT_3D);
DMA_SET_REGISTERS(SAVAGE_DRAWCTRL0_S4, 2);
DMA_WRITE(drawctrl0);
DMA_WRITE(drawctrl1);
@@ -78,22 +78,23 @@ void savage_emit_clip_rect_s4(drm_savage_private_t *dev_priv,
}
}
-static int savage_verify_texaddr(drm_savage_private_t *dev_priv, int unit,
+static int savage_verify_texaddr(drm_savage_private_t * dev_priv, int unit,
uint32_t addr)
{
- if ((addr & 6) != 2) { /* reserved bits */
+ if ((addr & 6) != 2) { /* reserved bits */
DRM_ERROR("bad texAddr%d %08x (reserved bits)\n", unit, addr);
return DRM_ERR(EINVAL);
}
- if (!(addr & 1)) { /* local */
+ if (!(addr & 1)) { /* local */
addr &= ~7;
- if (addr < dev_priv->texture_offset ||
- addr >= dev_priv->texture_offset+dev_priv->texture_size) {
- DRM_ERROR("bad texAddr%d %08x (local addr out of range)\n",
- unit, addr);
+ if (addr < dev_priv->texture_offset ||
+ addr >= dev_priv->texture_offset + dev_priv->texture_size) {
+ DRM_ERROR
+ ("bad texAddr%d %08x (local addr out of range)\n",
+ unit, addr);
return DRM_ERR(EINVAL);
}
- } else { /* AGP */
+ } else { /* AGP */
if (!dev_priv->agp_textures) {
DRM_ERROR("bad texAddr%d %08x (AGP not available)\n",
unit, addr);
@@ -103,8 +104,9 @@ static int savage_verify_texaddr(drm_savage_private_t *dev_priv, int unit,
if (addr < dev_priv->agp_textures->offset ||
addr >= (dev_priv->agp_textures->offset +
dev_priv->agp_textures->size)) {
- DRM_ERROR("bad texAddr%d %08x (AGP addr out of range)\n",
- unit, addr);
+ DRM_ERROR
+ ("bad texAddr%d %08x (AGP addr out of range)\n",
+ unit, addr);
return DRM_ERR(EINVAL);
}
}
@@ -122,14 +124,14 @@ static int savage_verify_texaddr(drm_savage_private_t *dev_priv, int unit,
(dev_priv->state.where & ~(mask)); \
} \
} while (0)
-static int savage_verify_state_s3d(drm_savage_private_t *dev_priv,
+static int savage_verify_state_s3d(drm_savage_private_t * dev_priv,
unsigned int start, unsigned int count,
- const uint32_t __user *regs)
+ const uint32_t __user * regs)
{
if (start < SAVAGE_TEXPALADDR_S3D ||
- start+count-1 > SAVAGE_DESTTEXRWWATERMARK_S3D) {
+ start + count - 1 > SAVAGE_DESTTEXRWWATERMARK_S3D) {
DRM_ERROR("invalid register range (0x%04x-0x%04x)\n",
- start, start+count-1);
+ start, start + count - 1);
return DRM_ERR(EINVAL);
}
@@ -140,28 +142,29 @@ static int savage_verify_state_s3d(drm_savage_private_t *dev_priv,
/* if any texture regs were changed ... */
if (start <= SAVAGE_TEXCTRL_S3D &&
- start+count > SAVAGE_TEXPALADDR_S3D) {
+ start + count > SAVAGE_TEXPALADDR_S3D) {
/* ... check texture state */
SAVE_STATE(SAVAGE_TEXCTRL_S3D, s3d.texctrl);
SAVE_STATE(SAVAGE_TEXADDR_S3D, s3d.texaddr);
if (dev_priv->state.s3d.texctrl & SAVAGE_TEXCTRL_TEXEN_MASK)
- return savage_verify_texaddr(
- dev_priv, 0, dev_priv->state.s3d.texaddr);
+ return savage_verify_texaddr(dev_priv, 0,
+ dev_priv->state.s3d.
+ texaddr);
}
return 0;
}
-static int savage_verify_state_s4(drm_savage_private_t *dev_priv,
+static int savage_verify_state_s4(drm_savage_private_t * dev_priv,
unsigned int start, unsigned int count,
- const uint32_t __user *regs)
+ const uint32_t __user * regs)
{
int ret = 0;
if (start < SAVAGE_DRAWLOCALCTRL_S4 ||
- start+count-1 > SAVAGE_TEXBLENDCOLOR_S4) {
+ start + count - 1 > SAVAGE_TEXBLENDCOLOR_S4) {
DRM_ERROR("invalid register range (0x%04x-0x%04x)\n",
- start, start+count-1);
+ start, start + count - 1);
return DRM_ERR(EINVAL);
}
@@ -171,28 +174,30 @@ static int savage_verify_state_s4(drm_savage_private_t *dev_priv,
~SAVAGE_SCISSOR_MASK_S4);
/* if any texture regs were changed ... */
- if (start <= SAVAGE_TEXDESCR_S4 &&
- start+count > SAVAGE_TEXPALADDR_S4) {
+ if (start <= SAVAGE_TEXDESCR_S4 && start + count > SAVAGE_TEXPALADDR_S4) {
/* ... check texture state */
SAVE_STATE(SAVAGE_TEXDESCR_S4, s4.texdescr);
SAVE_STATE(SAVAGE_TEXADDR0_S4, s4.texaddr0);
SAVE_STATE(SAVAGE_TEXADDR1_S4, s4.texaddr1);
if (dev_priv->state.s4.texdescr & SAVAGE_TEXDESCR_TEX0EN_MASK)
- ret |= savage_verify_texaddr(
- dev_priv, 0, dev_priv->state.s4.texaddr0);
+ ret |=
+ savage_verify_texaddr(dev_priv, 0,
+ dev_priv->state.s4.texaddr0);
if (dev_priv->state.s4.texdescr & SAVAGE_TEXDESCR_TEX1EN_MASK)
- ret |= savage_verify_texaddr(
- dev_priv, 1, dev_priv->state.s4.texaddr1);
+ ret |=
+ savage_verify_texaddr(dev_priv, 1,
+ dev_priv->state.s4.texaddr1);
}
return ret;
}
+
#undef SAVE_STATE
#undef SAVE_STATE_MASK
-static int savage_dispatch_state(drm_savage_private_t *dev_priv,
- const drm_savage_cmd_header_t *cmd_header,
- const uint32_t __user *regs)
+static int savage_dispatch_state(drm_savage_private_t * dev_priv,
+ const drm_savage_cmd_header_t * cmd_header,
+ const uint32_t __user * regs)
{
unsigned int count = cmd_header->state.count;
unsigned int start = cmd_header->state.start;
@@ -204,7 +209,7 @@ static int savage_dispatch_state(drm_savage_private_t *dev_priv,
if (!count)
return 0;
- if (DRM_VERIFYAREA_READ(regs, count*4))
+ if (DRM_VERIFYAREA_READ(regs, count * 4))
return DRM_ERR(EFAULT);
if (S3_SAVAGE3D_SERIES(dev_priv->chipset)) {
@@ -213,14 +218,14 @@ static int savage_dispatch_state(drm_savage_private_t *dev_priv,
return ret;
/* scissor regs are emitted in savage_dispatch_draw */
if (start < SAVAGE_SCSTART_S3D) {
- if (start+count > SAVAGE_SCEND_S3D+1)
- count2 = count - (SAVAGE_SCEND_S3D+1 - start);
- if (start+count > SAVAGE_SCSTART_S3D)
+ if (start + count > SAVAGE_SCEND_S3D + 1)
+ count2 = count - (SAVAGE_SCEND_S3D + 1 - start);
+ if (start + count > SAVAGE_SCSTART_S3D)
count = SAVAGE_SCSTART_S3D - start;
} else if (start <= SAVAGE_SCEND_S3D) {
- if (start+count > SAVAGE_SCEND_S3D+1) {
- count -= SAVAGE_SCEND_S3D+1 - start;
- start = SAVAGE_SCEND_S3D+1;
+ if (start + count > SAVAGE_SCEND_S3D + 1) {
+ count -= SAVAGE_SCEND_S3D + 1 - start;
+ start = SAVAGE_SCEND_S3D + 1;
} else
return 0;
}
@@ -230,23 +235,24 @@ static int savage_dispatch_state(drm_savage_private_t *dev_priv,
return ret;
/* scissor regs are emitted in savage_dispatch_draw */
if (start < SAVAGE_DRAWCTRL0_S4) {
- if (start+count > SAVAGE_DRAWCTRL1_S4+1)
- count2 = count - (SAVAGE_DRAWCTRL1_S4+1 - start);
- if (start+count > SAVAGE_DRAWCTRL0_S4)
+ if (start + count > SAVAGE_DRAWCTRL1_S4 + 1)
+ count2 =
+ count - (SAVAGE_DRAWCTRL1_S4 + 1 - start);
+ if (start + count > SAVAGE_DRAWCTRL0_S4)
count = SAVAGE_DRAWCTRL0_S4 - start;
} else if (start <= SAVAGE_DRAWCTRL1_S4) {
- if (start+count > SAVAGE_DRAWCTRL1_S4+1) {
- count -= SAVAGE_DRAWCTRL1_S4+1 - start;
- start = SAVAGE_DRAWCTRL1_S4+1;
+ if (start + count > SAVAGE_DRAWCTRL1_S4 + 1) {
+ count -= SAVAGE_DRAWCTRL1_S4 + 1 - start;
+ start = SAVAGE_DRAWCTRL1_S4 + 1;
} else
return 0;
}
}
- bci_size = count + (count+254)/255 + count2 + (count2+254)/255;
+ bci_size = count + (count + 254) / 255 + count2 + (count2 + 254) / 255;
if (cmd_header->state.global) {
- BEGIN_DMA(bci_size+1);
+ BEGIN_DMA(bci_size + 1);
DMA_WRITE(BCI_CMD_WAIT | BCI_CMD_WAIT_3D);
dev_priv->waiting = 1;
} else {
@@ -273,9 +279,9 @@ static int savage_dispatch_state(drm_savage_private_t *dev_priv,
return 0;
}
-static int savage_dispatch_dma_prim(drm_savage_private_t *dev_priv,
- const drm_savage_cmd_header_t *cmd_header,
- const drm_buf_t *dmabuf)
+static int savage_dispatch_dma_prim(drm_savage_private_t * dev_priv,
+ const drm_savage_cmd_header_t * cmd_header,
+ const drm_buf_t * dmabuf)
{
unsigned char reorder = 0;
unsigned int prim = cmd_header->prim.prim;
@@ -286,8 +292,8 @@ static int savage_dispatch_dma_prim(drm_savage_private_t *dev_priv,
BCI_LOCALS;
if (!dmabuf) {
- DRM_ERROR("called without dma buffers!\n");
- return DRM_ERR(EINVAL);
+ DRM_ERROR("called without dma buffers!\n");
+ return DRM_ERR(EINVAL);
}
if (!n)
@@ -307,8 +313,9 @@ static int savage_dispatch_dma_prim(drm_savage_private_t *dev_priv,
case SAVAGE_PRIM_TRISTRIP:
case SAVAGE_PRIM_TRIFAN:
if (n < 3) {
- DRM_ERROR("wrong number of vertices %u in TRIFAN/STRIP\n",
- n);
+ DRM_ERROR
+ ("wrong number of vertices %u in TRIFAN/STRIP\n",
+ n);
return DRM_ERR(EINVAL);
}
break;
@@ -319,17 +326,15 @@ static int savage_dispatch_dma_prim(drm_savage_private_t *dev_priv,
if (S3_SAVAGE3D_SERIES(dev_priv->chipset)) {
if (skip != 0) {
- DRM_ERROR("invalid skip flags 0x%04x for DMA\n",
- skip);
+ DRM_ERROR("invalid skip flags 0x%04x for DMA\n", skip);
return DRM_ERR(EINVAL);
}
} else {
unsigned int size = 10 - (skip & 1) - (skip >> 1 & 1) -
- (skip >> 2 & 1) - (skip >> 3 & 1) - (skip >> 4 & 1) -
- (skip >> 5 & 1) - (skip >> 6 & 1) - (skip >> 7 & 1);
+ (skip >> 2 & 1) - (skip >> 3 & 1) - (skip >> 4 & 1) -
+ (skip >> 5 & 1) - (skip >> 6 & 1) - (skip >> 7 & 1);
if (skip > SAVAGE_SKIP_ALL_S4 || size != 8) {
- DRM_ERROR("invalid skip flags 0x%04x for DMA\n",
- skip);
+ DRM_ERROR("invalid skip flags 0x%04x for DMA\n", skip);
return DRM_ERR(EINVAL);
}
if (reorder) {
@@ -338,9 +343,9 @@ static int savage_dispatch_dma_prim(drm_savage_private_t *dev_priv,
}
}
- if (start + n > dmabuf->total/32) {
+ if (start + n > dmabuf->total / 32) {
DRM_ERROR("vertex indices (%u-%u) out of range (0-%u)\n",
- start, start + n - 1, dmabuf->total/32);
+ start, start + n - 1, dmabuf->total / 32);
return DRM_ERR(EINVAL);
}
@@ -375,32 +380,33 @@ static int savage_dispatch_dma_prim(drm_savage_private_t *dev_priv,
/* Need to reorder indices for correct flat
* shading while preserving the clock sense
* for correct culling. Only on Savage3D. */
- int reorder[3] = {-1, -1, -1};
- reorder[start%3] = 2;
+ int reorder[3] = { -1, -1, -1 };
+ reorder[start % 3] = 2;
- BEGIN_BCI((count+1+1)/2);
- BCI_DRAW_INDICES_S3D(count, prim, start+2);
+ BEGIN_BCI((count + 1 + 1) / 2);
+ BCI_DRAW_INDICES_S3D(count, prim, start + 2);
- for (i = start+1; i+1 < start+count; i += 2)
+ for (i = start + 1; i + 1 < start + count; i += 2)
BCI_WRITE((i + reorder[i % 3]) |
- ((i+1 + reorder[(i+1) % 3]) << 16));
- if (i < start+count)
- BCI_WRITE(i + reorder[i%3]);
+ ((i + 1 +
+ reorder[(i + 1) % 3]) << 16));
+ if (i < start + count)
+ BCI_WRITE(i + reorder[i % 3]);
} else if (S3_SAVAGE3D_SERIES(dev_priv->chipset)) {
- BEGIN_BCI((count+1+1)/2);
+ BEGIN_BCI((count + 1 + 1) / 2);
BCI_DRAW_INDICES_S3D(count, prim, start);
- for (i = start+1; i+1 < start+count; i += 2)
- BCI_WRITE(i | ((i+1) << 16));
- if (i < start+count)
+ for (i = start + 1; i + 1 < start + count; i += 2)
+ BCI_WRITE(i | ((i + 1) << 16));
+ if (i < start + count)
BCI_WRITE(i);
} else {
- BEGIN_BCI((count+2+1)/2);
+ BEGIN_BCI((count + 2 + 1) / 2);
BCI_DRAW_INDICES_S4(count, prim, skip);
- for (i = start; i+1 < start+count; i += 2)
- BCI_WRITE(i | ((i+1) << 16));
- if (i < start+count)
+ for (i = start; i + 1 < start + count; i += 2)
+ BCI_WRITE(i | ((i + 1) << 16));
+ if (i < start + count)
BCI_WRITE(i);
}
@@ -413,11 +419,10 @@ static int savage_dispatch_dma_prim(drm_savage_private_t *dev_priv,
return 0;
}
-static int savage_dispatch_vb_prim(drm_savage_private_t *dev_priv,
- const drm_savage_cmd_header_t *cmd_header,
- const uint32_t __user *vtxbuf,
- unsigned int vb_size,
- unsigned int vb_stride)
+static int savage_dispatch_vb_prim(drm_savage_private_t * dev_priv,
+ const drm_savage_cmd_header_t * cmd_header,
+ const uint32_t __user * vtxbuf,
+ unsigned int vb_size, unsigned int vb_stride)
{
unsigned char reorder = 0;
unsigned int prim = cmd_header->prim.prim;
@@ -445,8 +450,9 @@ static int savage_dispatch_vb_prim(drm_savage_private_t *dev_priv,
case SAVAGE_PRIM_TRISTRIP:
case SAVAGE_PRIM_TRIFAN:
if (n < 3) {
- DRM_ERROR("wrong number of vertices %u in TRIFAN/STRIP\n",
- n);
+ DRM_ERROR
+ ("wrong number of vertices %u in TRIFAN/STRIP\n",
+ n);
return DRM_ERR(EINVAL);
}
break;
@@ -460,18 +466,18 @@ static int savage_dispatch_vb_prim(drm_savage_private_t *dev_priv,
DRM_ERROR("invalid skip flags 0x%04x\n", skip);
return DRM_ERR(EINVAL);
}
- vtx_size = 8; /* full vertex */
+ vtx_size = 8; /* full vertex */
} else {
if (skip > SAVAGE_SKIP_ALL_S4) {
DRM_ERROR("invalid skip flags 0x%04x\n", skip);
return DRM_ERR(EINVAL);
}
- vtx_size = 10; /* full vertex */
+ vtx_size = 10; /* full vertex */
}
vtx_size -= (skip & 1) + (skip >> 1 & 1) +
- (skip >> 2 & 1) + (skip >> 3 & 1) + (skip >> 4 & 1) +
- (skip >> 5 & 1) + (skip >> 6 & 1) + (skip >> 7 & 1);
+ (skip >> 2 & 1) + (skip >> 3 & 1) + (skip >> 4 & 1) +
+ (skip >> 5 & 1) + (skip >> 6 & 1) + (skip >> 7 & 1);
if (vtx_size > vb_stride) {
DRM_ERROR("vertex size greater than vb stride (%u > %u)\n",
@@ -479,9 +485,9 @@ static int savage_dispatch_vb_prim(drm_savage_private_t *dev_priv,
return DRM_ERR(EINVAL);
}
- if (start + n > vb_size / (vb_stride*4)) {
+ if (start + n > vb_size / (vb_stride * 4)) {
DRM_ERROR("vertex indices (%u-%u) out of range (0-%u)\n",
- start, start + n - 1, vb_size / (vb_stride*4));
+ start, start + n - 1, vb_size / (vb_stride * 4));
return DRM_ERR(EINVAL);
}
@@ -493,31 +499,31 @@ static int savage_dispatch_vb_prim(drm_savage_private_t *dev_priv,
/* Need to reorder vertices for correct flat
* shading while preserving the clock sense
* for correct culling. Only on Savage3D. */
- int reorder[3] = {-1, -1, -1};
- reorder[start%3] = 2;
+ int reorder[3] = { -1, -1, -1 };
+ reorder[start % 3] = 2;
- BEGIN_DMA(count*vtx_size+1);
+ BEGIN_DMA(count * vtx_size + 1);
DMA_DRAW_PRIMITIVE(count, prim, skip);
- for (i = start; i < start+count; ++i) {
+ for (i = start; i < start + count; ++i) {
unsigned int j = i + reorder[i % 3];
- DMA_COPY_FROM_USER(&vtxbuf[vb_stride*j],
+ DMA_COPY_FROM_USER(&vtxbuf[vb_stride * j],
vtx_size);
}
DMA_COMMIT();
} else {
- BEGIN_DMA(count*vtx_size+1);
+ BEGIN_DMA(count * vtx_size + 1);
DMA_DRAW_PRIMITIVE(count, prim, skip);
if (vb_stride == vtx_size) {
- DMA_COPY_FROM_USER(&vtxbuf[vb_stride*start],
- vtx_size*count);
+ DMA_COPY_FROM_USER(&vtxbuf[vb_stride * start],
+ vtx_size * count);
} else {
- for (i = start; i < start+count; ++i) {
- DMA_COPY_FROM_USER(
- &vtxbuf[vb_stride*i],
- vtx_size);
+ for (i = start; i < start + count; ++i) {
+ DMA_COPY_FROM_USER(&vtxbuf
+ [vb_stride * i],
+ vtx_size);
}
}
@@ -533,10 +539,10 @@ static int savage_dispatch_vb_prim(drm_savage_private_t *dev_priv,
return 0;
}
-static int savage_dispatch_dma_idx(drm_savage_private_t *dev_priv,
- const drm_savage_cmd_header_t *cmd_header,
- const uint16_t __user *usr_idx,
- const drm_buf_t *dmabuf)
+static int savage_dispatch_dma_idx(drm_savage_private_t * dev_priv,
+ const drm_savage_cmd_header_t * cmd_header,
+ const uint16_t __user * usr_idx,
+ const drm_buf_t * dmabuf)
{
unsigned char reorder = 0;
unsigned int prim = cmd_header->idx.prim;
@@ -546,8 +552,8 @@ static int savage_dispatch_dma_idx(drm_savage_private_t *dev_priv,
BCI_LOCALS;
if (!dmabuf) {
- DRM_ERROR("called without dma buffers!\n");
- return DRM_ERR(EINVAL);
+ DRM_ERROR("called without dma buffers!\n");
+ return DRM_ERR(EINVAL);
}
if (!n)
@@ -559,16 +565,15 @@ static int savage_dispatch_dma_idx(drm_savage_private_t *dev_priv,
prim = SAVAGE_PRIM_TRILIST;
case SAVAGE_PRIM_TRILIST:
if (n % 3 != 0) {
- DRM_ERROR("wrong number of indices %u in TRILIST\n",
- n);
+ DRM_ERROR("wrong number of indices %u in TRILIST\n", n);
return DRM_ERR(EINVAL);
}
break;
case SAVAGE_PRIM_TRISTRIP:
case SAVAGE_PRIM_TRIFAN:
if (n < 3) {
- DRM_ERROR("wrong number of indices %u in TRIFAN/STRIP\n",
- n);
+ DRM_ERROR
+ ("wrong number of indices %u in TRIFAN/STRIP\n", n);
return DRM_ERR(EINVAL);
}
break;
@@ -579,17 +584,15 @@ static int savage_dispatch_dma_idx(drm_savage_private_t *dev_priv,
if (S3_SAVAGE3D_SERIES(dev_priv->chipset)) {
if (skip != 0) {
- DRM_ERROR("invalid skip flags 0x%04x for DMA\n",
- skip);
+ DRM_ERROR("invalid skip flags 0x%04x for DMA\n", skip);
return DRM_ERR(EINVAL);
}
} else {
unsigned int size = 10 - (skip & 1) - (skip >> 1 & 1) -
- (skip >> 2 & 1) - (skip >> 3 & 1) - (skip >> 4 & 1) -
- (skip >> 5 & 1) - (skip >> 6 & 1) - (skip >> 7 & 1);
+ (skip >> 2 & 1) - (skip >> 3 & 1) - (skip >> 4 & 1) -
+ (skip >> 5 & 1) - (skip >> 6 & 1) - (skip >> 7 & 1);
if (skip > SAVAGE_SKIP_ALL_S4 || size != 8) {
- DRM_ERROR("invalid skip flags 0x%04x for DMA\n",
- skip);
+ DRM_ERROR("invalid skip flags 0x%04x for DMA\n", skip);
return DRM_ERR(EINVAL);
}
if (reorder) {
@@ -629,11 +632,11 @@ static int savage_dispatch_dma_idx(drm_savage_private_t *dev_priv,
uint16_t idx[255];
/* Copy and check indices */
- DRM_COPY_FROM_USER_UNCHECKED(idx, usr_idx, count*2);
+ DRM_COPY_FROM_USER_UNCHECKED(idx, usr_idx, count * 2);
for (i = 0; i < count; ++i) {
- if (idx[i] > dmabuf->total/32) {
+ if (idx[i] > dmabuf->total / 32) {
DRM_ERROR("idx[%u]=%u out of range (0-%u)\n",
- i, idx[i], dmabuf->total/32);
+ i, idx[i], dmabuf->total / 32);
return DRM_ERR(EINVAL);
}
}
@@ -642,30 +645,31 @@ static int savage_dispatch_dma_idx(drm_savage_private_t *dev_priv,
/* Need to reorder indices for correct flat
* shading while preserving the clock sense
* for correct culling. Only on Savage3D. */
- int reorder[3] = {2, -1, -1};
+ int reorder[3] = { 2, -1, -1 };
- BEGIN_BCI((count+1+1)/2);
+ BEGIN_BCI((count + 1 + 1) / 2);
BCI_DRAW_INDICES_S3D(count, prim, idx[2]);
- for (i = 1; i+1 < count; i += 2)
+ for (i = 1; i + 1 < count; i += 2)
BCI_WRITE(idx[i + reorder[i % 3]] |
- (idx[i+1 + reorder[(i+1) % 3]] << 16));
+ (idx[i + 1 + reorder[(i + 1) % 3]] <<
+ 16));
if (i < count)
- BCI_WRITE(idx[i + reorder[i%3]]);
+ BCI_WRITE(idx[i + reorder[i % 3]]);
} else if (S3_SAVAGE3D_SERIES(dev_priv->chipset)) {
- BEGIN_BCI((count+1+1)/2);
+ BEGIN_BCI((count + 1 + 1) / 2);
BCI_DRAW_INDICES_S3D(count, prim, idx[0]);
- for (i = 1; i+1 < count; i += 2)
- BCI_WRITE(idx[i] | (idx[i+1] << 16));
+ for (i = 1; i + 1 < count; i += 2)
+ BCI_WRITE(idx[i] | (idx[i + 1] << 16));
if (i < count)
BCI_WRITE(idx[i]);
} else {
- BEGIN_BCI((count+2+1)/2);
+ BEGIN_BCI((count + 2 + 1) / 2);
BCI_DRAW_INDICES_S4(count, prim, skip);
- for (i = 0; i+1 < count; i += 2)
- BCI_WRITE(idx[i] | (idx[i+1] << 16));
+ for (i = 0; i + 1 < count; i += 2)
+ BCI_WRITE(idx[i] | (idx[i + 1] << 16));
if (i < count)
BCI_WRITE(idx[i]);
}
@@ -679,12 +683,11 @@ static int savage_dispatch_dma_idx(drm_savage_private_t *dev_priv,
return 0;
}
-static int savage_dispatch_vb_idx(drm_savage_private_t *dev_priv,
- const drm_savage_cmd_header_t *cmd_header,
- const uint16_t __user *usr_idx,
- const uint32_t __user *vtxbuf,
- unsigned int vb_size,
- unsigned int vb_stride)
+static int savage_dispatch_vb_idx(drm_savage_private_t * dev_priv,
+ const drm_savage_cmd_header_t * cmd_header,
+ const uint16_t __user * usr_idx,
+ const uint32_t __user * vtxbuf,
+ unsigned int vb_size, unsigned int vb_stride)
{
unsigned char reorder = 0;
unsigned int prim = cmd_header->idx.prim;
@@ -703,16 +706,15 @@ static int savage_dispatch_vb_idx(drm_savage_private_t *dev_priv,
prim = SAVAGE_PRIM_TRILIST;
case SAVAGE_PRIM_TRILIST:
if (n % 3 != 0) {
- DRM_ERROR("wrong number of indices %u in TRILIST\n",
- n);
+ DRM_ERROR("wrong number of indices %u in TRILIST\n", n);
return DRM_ERR(EINVAL);
}
break;
case SAVAGE_PRIM_TRISTRIP:
case SAVAGE_PRIM_TRIFAN:
if (n < 3) {
- DRM_ERROR("wrong number of indices %u in TRIFAN/STRIP\n",
- n);
+ DRM_ERROR
+ ("wrong number of indices %u in TRIFAN/STRIP\n", n);
return DRM_ERR(EINVAL);
}
break;
@@ -726,18 +728,18 @@ static int savage_dispatch_vb_idx(drm_savage_private_t *dev_priv,
DRM_ERROR("invalid skip flags 0x%04x\n", skip);
return DRM_ERR(EINVAL);
}
- vtx_size = 8; /* full vertex */
+ vtx_size = 8; /* full vertex */
} else {
if (skip > SAVAGE_SKIP_ALL_S4) {
DRM_ERROR("invalid skip flags 0x%04x\n", skip);
return DRM_ERR(EINVAL);
}
- vtx_size = 10; /* full vertex */
+ vtx_size = 10; /* full vertex */
}
vtx_size -= (skip & 1) + (skip >> 1 & 1) +
- (skip >> 2 & 1) + (skip >> 3 & 1) + (skip >> 4 & 1) +
- (skip >> 5 & 1) + (skip >> 6 & 1) + (skip >> 7 & 1);
+ (skip >> 2 & 1) + (skip >> 3 & 1) + (skip >> 4 & 1) +
+ (skip >> 5 & 1) + (skip >> 6 & 1) + (skip >> 7 & 1);
if (vtx_size > vb_stride) {
DRM_ERROR("vertex size greater than vb stride (%u > %u)\n",
@@ -753,11 +755,11 @@ static int savage_dispatch_vb_idx(drm_savage_private_t *dev_priv,
uint16_t idx[255];
/* Copy and check indices */
- DRM_COPY_FROM_USER_UNCHECKED(idx, usr_idx, count*2);
+ DRM_COPY_FROM_USER_UNCHECKED(idx, usr_idx, count * 2);
for (i = 0; i < count; ++i) {
- if (idx[i] > vb_size / (vb_stride*4)) {
+ if (idx[i] > vb_size / (vb_stride * 4)) {
DRM_ERROR("idx[%u]=%u out of range (0-%u)\n",
- i, idx[i], vb_size / (vb_stride*4));
+ i, idx[i], vb_size / (vb_stride * 4));
return DRM_ERR(EINVAL);
}
}
@@ -766,25 +768,25 @@ static int savage_dispatch_vb_idx(drm_savage_private_t *dev_priv,
/* Need to reorder vertices for correct flat
* shading while preserving the clock sense
* for correct culling. Only on Savage3D. */
- int reorder[3] = {2, -1, -1};
+ int reorder[3] = { 2, -1, -1 };
- BEGIN_DMA(count*vtx_size+1);
+ BEGIN_DMA(count * vtx_size + 1);
DMA_DRAW_PRIMITIVE(count, prim, skip);
for (i = 0; i < count; ++i) {
unsigned int j = idx[i + reorder[i % 3]];
- DMA_COPY_FROM_USER(&vtxbuf[vb_stride*j],
+ DMA_COPY_FROM_USER(&vtxbuf[vb_stride * j],
vtx_size);
}
DMA_COMMIT();
} else {
- BEGIN_DMA(count*vtx_size+1);
+ BEGIN_DMA(count * vtx_size + 1);
DMA_DRAW_PRIMITIVE(count, prim, skip);
for (i = 0; i < count; ++i) {
unsigned int j = idx[i];
- DMA_COPY_FROM_USER(&vtxbuf[vb_stride*j],
+ DMA_COPY_FROM_USER(&vtxbuf[vb_stride * j],
vtx_size);
}
@@ -800,11 +802,11 @@ static int savage_dispatch_vb_idx(drm_savage_private_t *dev_priv,
return 0;
}
-static int savage_dispatch_clear(drm_savage_private_t *dev_priv,
- const drm_savage_cmd_header_t *cmd_header,
- const drm_savage_cmd_header_t __user *data,
+static int savage_dispatch_clear(drm_savage_private_t * dev_priv,
+ const drm_savage_cmd_header_t * cmd_header,
+ const drm_savage_cmd_header_t __user * data,
unsigned int nbox,
- const drm_clip_rect_t __user *usr_boxes)
+ const drm_clip_rect_t __user * usr_boxes)
{
unsigned int flags = cmd_header->clear0.flags, mask, value;
unsigned int clear_cmd;
@@ -814,18 +816,15 @@ static int savage_dispatch_clear(drm_savage_private_t *dev_priv,
if (nbox == 0)
return 0;
- DRM_GET_USER_UNCHECKED(mask, &((const drm_savage_cmd_header_t*)data)
- ->clear1.mask);
- DRM_GET_USER_UNCHECKED(value, &((const drm_savage_cmd_header_t*)data)
- ->clear1.value);
+ DRM_GET_USER_UNCHECKED(mask, &data->clear1.mask);
+ DRM_GET_USER_UNCHECKED(value, &data->clear1.value);
clear_cmd = BCI_CMD_RECT | BCI_CMD_RECT_XP | BCI_CMD_RECT_YP |
- BCI_CMD_SEND_COLOR | BCI_CMD_DEST_PBD_NEW;
- BCI_CMD_SET_ROP(clear_cmd,0xCC);
+ BCI_CMD_SEND_COLOR | BCI_CMD_DEST_PBD_NEW;
+ BCI_CMD_SET_ROP(clear_cmd, 0xCC);
nbufs = ((flags & SAVAGE_FRONT) ? 1 : 0) +
- ((flags & SAVAGE_BACK) ? 1 : 0) +
- ((flags & SAVAGE_DEPTH) ? 1 : 0);
+ ((flags & SAVAGE_BACK) ? 1 : 0) + ((flags & SAVAGE_DEPTH) ? 1 : 0);
if (nbufs == 0)
return 0;
@@ -844,12 +843,12 @@ static int savage_dispatch_clear(drm_savage_private_t *dev_priv,
x = box.x1, y = box.y1;
w = box.x2 - box.x1;
h = box.y2 - box.y1;
- BEGIN_DMA(nbufs*6);
+ BEGIN_DMA(nbufs * 6);
for (buf = SAVAGE_FRONT; buf <= SAVAGE_DEPTH; buf <<= 1) {
if (!(flags & buf))
continue;
DMA_WRITE(clear_cmd);
- switch(buf) {
+ switch (buf) {
case SAVAGE_FRONT:
DMA_WRITE(dev_priv->front_offset);
DMA_WRITE(dev_priv->front_bd);
@@ -880,9 +879,9 @@ static int savage_dispatch_clear(drm_savage_private_t *dev_priv,
return 0;
}
-static int savage_dispatch_swap(drm_savage_private_t *dev_priv,
+static int savage_dispatch_swap(drm_savage_private_t * dev_priv,
unsigned int nbox,
- const drm_clip_rect_t __user *usr_boxes)
+ const drm_clip_rect_t __user * usr_boxes)
{
unsigned int swap_cmd;
unsigned int i;
@@ -892,8 +891,8 @@ static int savage_dispatch_swap(drm_savage_private_t *dev_priv,
return 0;
swap_cmd = BCI_CMD_RECT | BCI_CMD_RECT_XP | BCI_CMD_RECT_YP |
- BCI_CMD_SRC_PBD_COLOR_NEW | BCI_CMD_DEST_GBD;
- BCI_CMD_SET_ROP(swap_cmd,0xCC);
+ BCI_CMD_SRC_PBD_COLOR_NEW | BCI_CMD_DEST_GBD;
+ BCI_CMD_SET_ROP(swap_cmd, 0xCC);
for (i = 0; i < nbox; ++i) {
drm_clip_rect_t box;
@@ -905,21 +904,21 @@ static int savage_dispatch_swap(drm_savage_private_t *dev_priv,
DMA_WRITE(dev_priv->back_bd);
DMA_WRITE(BCI_X_Y(box.x1, box.y1));
DMA_WRITE(BCI_X_Y(box.x1, box.y1));
- DMA_WRITE(BCI_W_H(box.x2-box.x1, box.y2-box.y1));
+ DMA_WRITE(BCI_W_H(box.x2 - box.x1, box.y2 - box.y1));
DMA_COMMIT();
}
return 0;
}
-static int savage_dispatch_draw(drm_savage_private_t *dev_priv,
- const drm_savage_cmd_header_t __user *start,
- const drm_savage_cmd_header_t __user *end,
- const drm_buf_t *dmabuf,
- const unsigned int __user *usr_vtxbuf,
+static int savage_dispatch_draw(drm_savage_private_t * dev_priv,
+ const drm_savage_cmd_header_t __user * start,
+ const drm_savage_cmd_header_t __user * end,
+ const drm_buf_t * dmabuf,
+ const unsigned int __user * usr_vtxbuf,
unsigned int vb_size, unsigned int vb_stride,
unsigned int nbox,
- const drm_clip_rect_t __user *usr_boxes)
+ const drm_clip_rect_t __user * usr_boxes)
{
unsigned int i, j;
int ret;
@@ -938,32 +937,42 @@ static int savage_dispatch_draw(drm_savage_private_t *dev_priv,
usr_cmdbuf++;
switch (cmd_header.cmd.cmd) {
case SAVAGE_CMD_DMA_PRIM:
- ret = savage_dispatch_dma_prim(
- dev_priv, &cmd_header, dmabuf);
+ ret =
+ savage_dispatch_dma_prim(dev_priv,
+ &cmd_header,
+ dmabuf);
break;
case SAVAGE_CMD_VB_PRIM:
- ret = savage_dispatch_vb_prim(
- dev_priv, &cmd_header,
- (const uint32_t __user *)usr_vtxbuf,
- vb_size, vb_stride);
+ ret =
+ savage_dispatch_vb_prim(dev_priv,
+ &cmd_header,
+ (const uint32_t
+ __user *)
+ usr_vtxbuf, vb_size,
+ vb_stride);
break;
case SAVAGE_CMD_DMA_IDX:
j = (cmd_header.idx.count + 3) / 4;
/* j was check in savage_bci_cmdbuf */
- ret = savage_dispatch_dma_idx(
- dev_priv, &cmd_header,
- (const uint16_t __user *)usr_cmdbuf,
- dmabuf);
+ ret =
+ savage_dispatch_dma_idx(dev_priv,
+ &cmd_header,
+ (const uint16_t
+ __user *)
+ usr_cmdbuf, dmabuf);
usr_cmdbuf += j;
break;
case SAVAGE_CMD_VB_IDX:
j = (cmd_header.idx.count + 3) / 4;
/* j was check in savage_bci_cmdbuf */
- ret = savage_dispatch_vb_idx(
- dev_priv, &cmd_header,
- (const uint16_t __user *)usr_cmdbuf,
- (const uint32_t __user *)usr_vtxbuf,
- vb_size, vb_stride);
+ ret =
+ savage_dispatch_vb_idx(dev_priv,
+ &cmd_header,
+ (const uint16_t
+ __user *)usr_cmdbuf,
+ (const uint32_t
+ __user *)usr_vtxbuf,
+ vb_size, vb_stride);
usr_cmdbuf += j;
break;
default:
@@ -997,16 +1006,17 @@ int savage_bci_cmdbuf(DRM_IOCTL_ARGS)
int ret = 0;
DRM_DEBUG("\n");
-
+
LOCK_TEST_WITH_RETURN(dev, filp);
- DRM_COPY_FROM_USER_IOCTL(cmdbuf, (drm_savage_cmdbuf_t __user *)data,
+ DRM_COPY_FROM_USER_IOCTL(cmdbuf, (drm_savage_cmdbuf_t __user *) data,
sizeof(cmdbuf));
if (dma && dma->buflist) {
if (cmdbuf.dma_idx > dma->buf_count) {
- DRM_ERROR("vertex buffer index %u out of range (0-%u)\n",
- cmdbuf.dma_idx, dma->buf_count-1);
+ DRM_ERROR
+ ("vertex buffer index %u out of range (0-%u)\n",
+ cmdbuf.dma_idx, dma->buf_count - 1);
return DRM_ERR(EINVAL);
}
dmabuf = dma->buflist[cmdbuf.dma_idx];
@@ -1014,14 +1024,14 @@ int savage_bci_cmdbuf(DRM_IOCTL_ARGS)
dmabuf = NULL;
}
- usr_cmdbuf = (drm_savage_cmd_header_t __user *)cmdbuf.cmd_addr;
+ usr_cmdbuf = (drm_savage_cmd_header_t __user *) cmdbuf.cmd_addr;
usr_vtxbuf = (unsigned int __user *)cmdbuf.vb_addr;
- usr_boxes = (drm_clip_rect_t __user *)cmdbuf.box_addr;
- if ((cmdbuf.size && DRM_VERIFYAREA_READ(usr_cmdbuf, cmdbuf.size*8)) ||
- (cmdbuf.vb_size && DRM_VERIFYAREA_READ(
- usr_vtxbuf, cmdbuf.vb_size)) ||
- (cmdbuf.nbox && DRM_VERIFYAREA_READ(
- usr_boxes, cmdbuf.nbox*sizeof(drm_clip_rect_t))))
+ usr_boxes = (drm_clip_rect_t __user *) cmdbuf.box_addr;
+ if ((cmdbuf.size && DRM_VERIFYAREA_READ(usr_cmdbuf, cmdbuf.size * 8)) ||
+ (cmdbuf.vb_size && DRM_VERIFYAREA_READ(usr_vtxbuf, cmdbuf.vb_size))
+ || (cmdbuf.nbox
+ && DRM_VERIFYAREA_READ(usr_boxes,
+ cmdbuf.nbox * sizeof(drm_clip_rect_t))))
return DRM_ERR(EFAULT);
/* Make sure writes to DMA buffers are finished before sending
@@ -1058,17 +1068,21 @@ int savage_bci_cmdbuf(DRM_IOCTL_ARGS)
case SAVAGE_CMD_DMA_PRIM:
case SAVAGE_CMD_VB_PRIM:
if (!first_draw_cmd)
- first_draw_cmd = usr_cmdbuf-1;
+ first_draw_cmd = usr_cmdbuf - 1;
usr_cmdbuf += j;
i += j;
break;
default:
if (first_draw_cmd) {
- ret = savage_dispatch_draw (
- dev_priv, first_draw_cmd, usr_cmdbuf-1,
- dmabuf, usr_vtxbuf, cmdbuf.vb_size,
- cmdbuf.vb_stride,
- cmdbuf.nbox, usr_boxes);
+ ret =
+ savage_dispatch_draw(dev_priv,
+ first_draw_cmd,
+ usr_cmdbuf - 1, dmabuf,
+ usr_vtxbuf,
+ cmdbuf.vb_size,
+ cmdbuf.vb_stride,
+ cmdbuf.nbox,
+ usr_boxes);
if (ret != 0)
return ret;
first_draw_cmd = NULL;
@@ -1086,9 +1100,9 @@ int savage_bci_cmdbuf(DRM_IOCTL_ARGS)
DMA_FLUSH();
return DRM_ERR(EINVAL);
}
- ret = savage_dispatch_state(
- dev_priv, &cmd_header,
- (uint32_t __user *)usr_cmdbuf);
+ ret = savage_dispatch_state(dev_priv, &cmd_header,
+ (uint32_t __user *)
+ usr_cmdbuf);
usr_cmdbuf += j;
i += j;
break;
@@ -1122,10 +1136,11 @@ int savage_bci_cmdbuf(DRM_IOCTL_ARGS)
}
if (first_draw_cmd) {
- ret = savage_dispatch_draw (
- dev_priv, first_draw_cmd, usr_cmdbuf, dmabuf,
- usr_vtxbuf, cmdbuf.vb_size, cmdbuf.vb_stride,
- cmdbuf.nbox, usr_boxes);
+ ret =
+ savage_dispatch_draw(dev_priv, first_draw_cmd, usr_cmdbuf,
+ dmabuf, usr_vtxbuf, cmdbuf.vb_size,
+ cmdbuf.vb_stride, cmdbuf.nbox,
+ usr_boxes);
if (ret != 0) {
DMA_FLUSH();
return ret;
diff --git a/drivers/char/drm/sis_drm.h b/drivers/char/drm/sis_drm.h
index e99c3a43abbc..8f273da76ddb 100644
--- a/drivers/char/drm/sis_drm.h
+++ b/drivers/char/drm/sis_drm.h
@@ -39,4 +39,4 @@ typedef struct {
unsigned int offset, size;
} drm_sis_fb_t;
-#endif /* __SIS_DRM_H__ */
+#endif /* __SIS_DRM_H__ */
diff --git a/drivers/char/drm/sis_drv.c b/drivers/char/drm/sis_drv.c
index f441714faae3..3cef10643a8f 100644
--- a/drivers/char/drm/sis_drv.c
+++ b/drivers/char/drm/sis_drv.c
@@ -10,11 +10,11 @@
* 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 (including the next
* paragraph) 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
@@ -31,31 +31,29 @@
#include "sis_drv.h"
#include "drm_pciids.h"
-
-static int postinit( struct drm_device *dev, unsigned long flags )
+
+static int postinit(struct drm_device *dev, unsigned long flags)
{
- DRM_INFO( "Initialized %s %d.%d.%d %s on minor %d: %s\n",
- DRIVER_NAME,
- DRIVER_MAJOR,
- DRIVER_MINOR,
- DRIVER_PATCHLEVEL,
- DRIVER_DATE,
- dev->primary.minor,
- pci_pretty_name(dev->pdev)
- );
+ DRM_INFO("Initialized %s %d.%d.%d %s on minor %d: %s\n",
+ DRIVER_NAME,
+ DRIVER_MAJOR,
+ DRIVER_MINOR,
+ DRIVER_PATCHLEVEL,
+ DRIVER_DATE, dev->primary.minor, pci_pretty_name(dev->pdev)
+ );
return 0;
}
-static int version( drm_version_t *version )
+static int version(drm_version_t * version)
{
int len;
version->version_major = DRIVER_MAJOR;
version->version_minor = DRIVER_MINOR;
version->version_patchlevel = DRIVER_PATCHLEVEL;
- DRM_COPY( version->name, DRIVER_NAME );
- DRM_COPY( version->date, DRIVER_DATE );
- DRM_COPY( version->desc, DRIVER_DESC );
+ DRM_COPY(version->name, DRIVER_NAME);
+ DRM_COPY(version->date, DRIVER_DATE);
+ DRM_COPY(version->desc, DRIVER_DESC);
return 0;
}
@@ -63,9 +61,6 @@ static struct pci_device_id pciidlist[] = {
sisdrv_PCI_IDS
};
-extern drm_ioctl_desc_t sis_ioctls[];
-extern int sis_max_ioctl;
-
static struct drm_driver driver = {
.driver_features = DRIVER_USE_AGP | DRIVER_USE_MTRR,
.context_ctor = sis_init_context,
@@ -77,18 +72,18 @@ static struct drm_driver driver = {
.version = version,
.ioctls = sis_ioctls,
.fops = {
- .owner = THIS_MODULE,
- .open = drm_open,
- .release = drm_release,
- .ioctl = drm_ioctl,
- .mmap = drm_mmap,
- .poll = drm_poll,
- .fasync = drm_fasync,
- },
+ .owner = THIS_MODULE,
+ .open = drm_open,
+ .release = drm_release,
+ .ioctl = drm_ioctl,
+ .mmap = drm_mmap,
+ .poll = drm_poll,
+ .fasync = drm_fasync,
+ },
.pci_driver = {
- .name = DRIVER_NAME,
- .id_table = pciidlist,
- }
+ .name = DRIVER_NAME,
+ .id_table = pciidlist,
+ }
};
static int __init sis_init(void)
@@ -105,6 +100,6 @@ static void __exit sis_exit(void)
module_init(sis_init);
module_exit(sis_exit);
-MODULE_AUTHOR( DRIVER_AUTHOR );
-MODULE_DESCRIPTION( DRIVER_DESC );
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL and additional rights");
diff --git a/drivers/char/drm/sis_drv.h b/drivers/char/drm/sis_drv.h
index 5be36b5caec9..b1fddad83a93 100644
--- a/drivers/char/drm/sis_drv.h
+++ b/drivers/char/drm/sis_drv.h
@@ -10,11 +10,11 @@
* 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 (including the next
* paragraph) 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
@@ -22,7 +22,7 @@
* 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 _SIS_DRV_H_
@@ -46,7 +46,10 @@ typedef struct drm_sis_private {
memHeap_t *FBHeap;
} drm_sis_private_t;
-extern int sis_init_context(drm_device_t *dev, int context);
-extern int sis_final_context(drm_device_t *dev, int context);
+extern int sis_init_context(drm_device_t * dev, int context);
+extern int sis_final_context(drm_device_t * dev, int context);
+
+extern drm_ioctl_desc_t sis_ioctls[];
+extern int sis_max_ioctl;
#endif
diff --git a/drivers/char/drm/sis_ds.c b/drivers/char/drm/sis_ds.c
index e37ed8ce48df..2e485d482943 100644
--- a/drivers/char/drm/sis_ds.c
+++ b/drivers/char/drm/sis_ds.c
@@ -10,11 +10,11 @@
* 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 (including the next
* paragraph) 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
@@ -22,10 +22,10 @@
* 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.
- *
+ *
* Authors:
* Sung-Ching Lin <sclin@sis.com.tw>
- *
+ *
*/
#include "drmP.h"
@@ -41,13 +41,13 @@ set_t *setInit(void)
int i;
set_t *set;
- set = (set_t *)drm_alloc(sizeof(set_t), DRM_MEM_DRIVER);
+ set = (set_t *) drm_alloc(sizeof(set_t), DRM_MEM_DRIVER);
if (set != NULL) {
for (i = 0; i < SET_SIZE; i++) {
- set->list[i].free_next = i + 1;
+ set->list[i].free_next = i + 1;
set->list[i].alloc_next = -1;
}
- set->list[SET_SIZE-1].free_next = -1;
+ set->list[SET_SIZE - 1].free_next = -1;
set->free = 0;
set->alloc = -1;
set->trace = -1;
@@ -55,10 +55,10 @@ set_t *setInit(void)
return set;
}
-int setAdd(set_t *set, ITEM_TYPE item)
+int setAdd(set_t * set, ITEM_TYPE item)
{
int free = set->free;
-
+
if (free != -1) {
set->list[free].val = item;
set->free = set->list[free].free_next;
@@ -67,16 +67,16 @@ int setAdd(set_t *set, ITEM_TYPE item)
}
set->list[free].alloc_next = set->alloc;
- set->alloc = free;
- set->list[free].free_next = -1;
+ set->alloc = free;
+ set->list[free].free_next = -1;
return 1;
}
-int setDel(set_t *set, ITEM_TYPE item)
+int setDel(set_t * set, ITEM_TYPE item)
{
int alloc = set->alloc;
- int prev = -1;
+ int prev = -1;
while (alloc != -1) {
if (set->list[alloc].val == item) {
@@ -103,7 +103,7 @@ int setDel(set_t *set, ITEM_TYPE item)
/* setFirst -> setAdd -> setNext is wrong */
-int setFirst(set_t *set, ITEM_TYPE *item)
+int setFirst(set_t * set, ITEM_TYPE * item)
{
if (set->alloc == -1)
return 0;
@@ -114,7 +114,7 @@ int setFirst(set_t *set, ITEM_TYPE *item)
return 1;
}
-int setNext(set_t *set, ITEM_TYPE *item)
+int setNext(set_t * set, ITEM_TYPE * item)
{
if (set->trace == -1)
return 0;
@@ -125,7 +125,7 @@ int setNext(set_t *set, ITEM_TYPE *item)
return 1;
}
-int setDestroy(set_t *set)
+int setDestroy(set_t * set)
{
drm_free(set, sizeof(set_t), DRM_MEM_DRIVER);
@@ -149,35 +149,34 @@ int setDestroy(set_t *set)
* 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
- * WITTAWAT YAMWONG, OR ANY OTHER CONTRIBUTORS 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
+ * WITTAWAT YAMWONG, OR ANY OTHER CONTRIBUTORS 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.
*
*/
#define ISFREE(bptr) ((bptr)->free)
-memHeap_t *mmInit(int ofs,
- int size)
+memHeap_t *mmInit(int ofs, int size)
{
PMemBlock blocks;
if (size <= 0)
return NULL;
- blocks = (TMemBlock *)drm_calloc(1, sizeof(TMemBlock), DRM_MEM_DRIVER);
+ blocks = (TMemBlock *) drm_calloc(1, sizeof(TMemBlock), DRM_MEM_DRIVER);
if (blocks != NULL) {
blocks->ofs = ofs;
blocks->size = size;
blocks->free = 1;
- return (memHeap_t *)blocks;
+ return (memHeap_t *) blocks;
} else
return NULL;
}
/* Checks if a pointer 'b' is part of the heap 'heap' */
-int mmBlockInHeap(memHeap_t *heap, PMemBlock b)
+int mmBlockInHeap(memHeap_t * heap, PMemBlock b)
{
TMemBlock *p;
@@ -194,16 +193,16 @@ int mmBlockInHeap(memHeap_t *heap, PMemBlock b)
return 0;
}
-static TMemBlock* SliceBlock(TMemBlock *p,
- int startofs, int size,
+static TMemBlock *SliceBlock(TMemBlock * p,
+ int startofs, int size,
int reserved, int alignment)
{
TMemBlock *newblock;
/* break left */
if (startofs > p->ofs) {
- newblock = (TMemBlock*) drm_calloc(1, sizeof(TMemBlock),
- DRM_MEM_DRIVER);
+ newblock = (TMemBlock *) drm_calloc(1, sizeof(TMemBlock),
+ DRM_MEM_DRIVER);
newblock->ofs = startofs;
newblock->size = p->size - (startofs - p->ofs);
newblock->free = 1;
@@ -215,8 +214,8 @@ static TMemBlock* SliceBlock(TMemBlock *p,
/* break right */
if (size < p->size) {
- newblock = (TMemBlock*) drm_calloc(1, sizeof(TMemBlock),
- DRM_MEM_DRIVER);
+ newblock = (TMemBlock *) drm_calloc(1, sizeof(TMemBlock),
+ DRM_MEM_DRIVER);
newblock->ofs = startofs + size;
newblock->size = p->size - size;
newblock->free = 1;
@@ -232,37 +231,37 @@ static TMemBlock* SliceBlock(TMemBlock *p,
return p;
}
-PMemBlock mmAllocMem( memHeap_t *heap, int size, int align2, int startSearch)
+PMemBlock mmAllocMem(memHeap_t * heap, int size, int align2, int startSearch)
{
- int mask,startofs, endofs;
+ int mask, startofs, endofs;
TMemBlock *p;
-
+
if (heap == NULL || align2 < 0 || size <= 0)
return NULL;
- mask = (1 << align2)-1;
+ mask = (1 << align2) - 1;
startofs = 0;
- p = (TMemBlock *)heap;
+ p = (TMemBlock *) heap;
while (p != NULL) {
if (ISFREE(p)) {
startofs = (p->ofs + mask) & ~mask;
- if ( startofs < startSearch ) {
+ if (startofs < startSearch) {
startofs = startSearch;
}
- endofs = startofs+size;
- if (endofs <= (p->ofs+p->size))
+ endofs = startofs + size;
+ if (endofs <= (p->ofs + p->size))
break;
}
p = p->next;
}
if (p == NULL)
return NULL;
- p = SliceBlock(p,startofs,size,0,mask+1);
+ p = SliceBlock(p, startofs, size, 0, mask + 1);
p->heap = heap;
return p;
}
-static __inline__ int Join2Blocks(TMemBlock *p)
+static __inline__ int Join2Blocks(TMemBlock * p)
{
if (p->free && p->next && p->next->free) {
TMemBlock *q = p->next;
@@ -295,7 +294,6 @@ int mmFreeMem(PMemBlock b)
p->free = 1;
Join2Blocks(p);
if (prev)
- Join2Blocks(prev);
+ Join2Blocks(prev);
return 0;
}
-
diff --git a/drivers/char/drm/sis_ds.h b/drivers/char/drm/sis_ds.h
index 171ee75afa57..da850b4f5440 100644
--- a/drivers/char/drm/sis_ds.h
+++ b/drivers/char/drm/sis_ds.h
@@ -10,11 +10,11 @@
* 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 (including the next
* paragraph) 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
@@ -22,10 +22,10 @@
* 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.
- *
+ *
* Authors:
* Sung-Ching Lin <sclin@sis.com.tw>
- *
+ *
*/
#ifndef __SIS_DS_H__
@@ -50,11 +50,11 @@ typedef struct {
} set_t;
set_t *setInit(void);
-int setAdd(set_t *set, ITEM_TYPE item);
-int setDel(set_t *set, ITEM_TYPE item);
-int setFirst(set_t *set, ITEM_TYPE *item);
-int setNext(set_t *set, ITEM_TYPE *item);
-int setDestroy(set_t *set);
+int setAdd(set_t * set, ITEM_TYPE item);
+int setDel(set_t * set, ITEM_TYPE item);
+int setFirst(set_t * set, ITEM_TYPE * item);
+int setNext(set_t * set, ITEM_TYPE * item);
+int setDestroy(set_t * set);
/*
* GLX Hardware Device Driver common code
@@ -73,9 +73,9 @@ int setDestroy(set_t *set);
* 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
- * WITTAWAT YAMWONG, OR ANY OTHER CONTRIBUTORS 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
+ * WITTAWAT YAMWONG, OR ANY OTHER CONTRIBUTORS 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.
*
*/
@@ -83,7 +83,7 @@ int setDestroy(set_t *set);
struct mem_block_t {
struct mem_block_t *next;
struct mem_block_t *heap;
- int ofs,size;
+ int ofs, size;
int align;
unsigned int free:1;
unsigned int reserved:1;
@@ -109,11 +109,11 @@ static __inline__ void mmMarkReserved(PMemBlock b)
b->reserved = 1;
}
-/*
+/*
* input: total size in bytes
* return: a heap pointer if OK, NULL if error
*/
-memHeap_t *mmInit( int ofs, int size );
+memHeap_t *mmInit(int ofs, int size);
/*
* Allocate 'size' bytes with 2^align2 bytes alignment,
@@ -125,21 +125,21 @@ memHeap_t *mmInit( int ofs, int size );
* startSearch = linear offset from start of heap to begin search
* return: pointer to the allocated block, 0 if error
*/
-PMemBlock mmAllocMem( memHeap_t *heap, int size, int align2, int startSearch );
+PMemBlock mmAllocMem(memHeap_t * heap, int size, int align2, int startSearch);
/*
* Returns 1 if the block 'b' is part of the heap 'heap'
*/
-int mmBlockInHeap( PMemBlock heap, PMemBlock b );
+int mmBlockInHeap(PMemBlock heap, PMemBlock b);
/*
* Free block starts at offset
* input: pointer to a block
* return: 0 if OK, -1 if error
*/
-int mmFreeMem( PMemBlock b );
+int mmFreeMem(PMemBlock b);
/* For debuging purpose. */
-void mmDumpMemInfo( memHeap_t *mmInit );
+void mmDumpMemInfo(memHeap_t * mmInit);
-#endif /* __SIS_DS_H__ */
+#endif /* __SIS_DS_H__ */
diff --git a/drivers/char/drm/sis_mm.c b/drivers/char/drm/sis_mm.c
index 6610c5576d22..a8529728fa63 100644
--- a/drivers/char/drm/sis_mm.c
+++ b/drivers/char/drm/sis_mm.c
@@ -10,11 +10,11 @@
* 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 (including the next
* paragraph) 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
@@ -22,10 +22,10 @@
* 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.
- *
+ *
* Authors:
* Sung-Ching Lin <sclin@sis.com.tw>
- *
+ *
*/
#include "drmP.h"
@@ -37,25 +37,23 @@
#endif
#define MAX_CONTEXT 100
-#define VIDEO_TYPE 0
+#define VIDEO_TYPE 0
#define AGP_TYPE 1
typedef struct {
int used;
int context;
- set_t *sets[2]; /* 0 for video, 1 for AGP */
+ set_t *sets[2]; /* 0 for video, 1 for AGP */
} sis_context_t;
static sis_context_t global_ppriv[MAX_CONTEXT];
-
static int add_alloc_set(int context, int type, unsigned int val)
{
int i, retval = 0;
-
+
for (i = 0; i < MAX_CONTEXT; i++) {
- if (global_ppriv[i].used && global_ppriv[i].context == context)
- {
+ if (global_ppriv[i].used && global_ppriv[i].context == context) {
retval = setAdd(global_ppriv[i].sets[type], val);
break;
}
@@ -64,12 +62,11 @@ static int add_alloc_set(int context, int type, unsigned int val)
}
static int del_alloc_set(int context, int type, unsigned int val)
-{
+{
int i, retval = 0;
for (i = 0; i < MAX_CONTEXT; i++) {
- if (global_ppriv[i].used && global_ppriv[i].context == context)
- {
+ if (global_ppriv[i].used && global_ppriv[i].context == context) {
retval = setDel(global_ppriv[i].sets[type], val);
break;
}
@@ -77,15 +74,15 @@ static int del_alloc_set(int context, int type, unsigned int val)
return retval;
}
-/* fb management via fb device */
+/* fb management via fb device */
#if defined(__linux__) && defined(CONFIG_FB_SIS)
-static int sis_fb_init( DRM_IOCTL_ARGS )
+static int sis_fb_init(DRM_IOCTL_ARGS)
{
return 0;
}
-static int sis_fb_alloc( DRM_IOCTL_ARGS )
+static int sis_fb_alloc(DRM_IOCTL_ARGS)
{
drm_sis_mem_t fb;
struct sis_memreq req;
@@ -105,7 +102,7 @@ static int sis_fb_alloc( DRM_IOCTL_ARGS )
sis_free(req.offset);
retval = DRM_ERR(EINVAL);
}
- } else {
+ } else {
fb.offset = 0;
fb.size = 0;
fb.free = 0;
@@ -118,19 +115,19 @@ static int sis_fb_alloc( DRM_IOCTL_ARGS )
return retval;
}
-static int sis_fb_free( DRM_IOCTL_ARGS )
+static int sis_fb_free(DRM_IOCTL_ARGS)
{
drm_sis_mem_t fb;
int retval = 0;
- DRM_COPY_FROM_USER_IOCTL(fb, (drm_sis_mem_t __user *)data, sizeof(fb));
+ DRM_COPY_FROM_USER_IOCTL(fb, (drm_sis_mem_t __user *) data, sizeof(fb));
if (!fb.free)
return DRM_ERR(EINVAL);
if (!del_alloc_set(fb.context, VIDEO_TYPE, fb.free))
retval = DRM_ERR(EINVAL);
- sis_free((u32)fb.free);
+ sis_free((u32) fb.free);
DRM_DEBUG("free fb, offset = %lu\n", fb.free);
@@ -149,17 +146,17 @@ static int sis_fb_free( DRM_IOCTL_ARGS )
* X driver/sisfb HW- Command-
* framebuffer memory DRI heap Cursor queue
*/
-static int sis_fb_init( DRM_IOCTL_ARGS )
+static int sis_fb_init(DRM_IOCTL_ARGS)
{
DRM_DEVICE;
drm_sis_private_t *dev_priv = dev->dev_private;
drm_sis_fb_t fb;
- DRM_COPY_FROM_USER_IOCTL(fb, (drm_sis_fb_t __user *)data, sizeof(fb));
+ DRM_COPY_FROM_USER_IOCTL(fb, (drm_sis_fb_t __user *) data, sizeof(fb));
if (dev_priv == NULL) {
dev->dev_private = drm_calloc(1, sizeof(drm_sis_private_t),
- DRM_MEM_DRIVER);
+ DRM_MEM_DRIVER);
dev_priv = dev->dev_private;
if (dev_priv == NULL)
return ENOMEM;
@@ -175,7 +172,7 @@ static int sis_fb_init( DRM_IOCTL_ARGS )
return 0;
}
-static int sis_fb_alloc( DRM_IOCTL_ARGS )
+static int sis_fb_alloc(DRM_IOCTL_ARGS)
{
DRM_DEVICE;
drm_sis_private_t *dev_priv = dev->dev_private;
@@ -186,9 +183,9 @@ static int sis_fb_alloc( DRM_IOCTL_ARGS )
if (dev_priv == NULL || dev_priv->FBHeap == NULL)
return DRM_ERR(EINVAL);
-
+
DRM_COPY_FROM_USER_IOCTL(fb, argp, sizeof(fb));
-
+
block = mmAllocMem(dev_priv->FBHeap, fb.size, 0, 0);
if (block) {
/* TODO */
@@ -196,7 +193,7 @@ static int sis_fb_alloc( DRM_IOCTL_ARGS )
fb.free = (unsigned long)block;
if (!add_alloc_set(fb.context, VIDEO_TYPE, fb.free)) {
DRM_DEBUG("adding to allocation set fails\n");
- mmFreeMem((PMemBlock)fb.free);
+ mmFreeMem((PMemBlock) fb.free);
retval = DRM_ERR(EINVAL);
}
} else {
@@ -212,7 +209,7 @@ static int sis_fb_alloc( DRM_IOCTL_ARGS )
return retval;
}
-static int sis_fb_free( DRM_IOCTL_ARGS )
+static int sis_fb_free(DRM_IOCTL_ARGS)
{
DRM_DEVICE;
drm_sis_private_t *dev_priv = dev->dev_private;
@@ -221,14 +218,14 @@ static int sis_fb_free( DRM_IOCTL_ARGS )
if (dev_priv == NULL || dev_priv->FBHeap == NULL)
return DRM_ERR(EINVAL);
- DRM_COPY_FROM_USER_IOCTL(fb, (drm_sis_mem_t __user *)data, sizeof(fb));
+ DRM_COPY_FROM_USER_IOCTL(fb, (drm_sis_mem_t __user *) data, sizeof(fb));
- if (!mmBlockInHeap(dev_priv->FBHeap, (PMemBlock)fb.free))
+ if (!mmBlockInHeap(dev_priv->FBHeap, (PMemBlock) fb.free))
return DRM_ERR(EINVAL);
if (!del_alloc_set(fb.context, VIDEO_TYPE, fb.free))
return DRM_ERR(EINVAL);
- mmFreeMem((PMemBlock)fb.free);
+ mmFreeMem((PMemBlock) fb.free);
DRM_DEBUG("free fb, free = 0x%lx\n", fb.free);
@@ -237,9 +234,9 @@ static int sis_fb_free( DRM_IOCTL_ARGS )
#endif
-/* agp memory management */
+/* agp memory management */
-static int sis_ioctl_agp_init( DRM_IOCTL_ARGS )
+static int sis_ioctl_agp_init(DRM_IOCTL_ARGS)
{
DRM_DEVICE;
drm_sis_private_t *dev_priv = dev->dev_private;
@@ -247,7 +244,7 @@ static int sis_ioctl_agp_init( DRM_IOCTL_ARGS )
if (dev_priv == NULL) {
dev->dev_private = drm_calloc(1, sizeof(drm_sis_private_t),
- DRM_MEM_DRIVER);
+ DRM_MEM_DRIVER);
dev_priv = dev->dev_private;
if (dev_priv == NULL)
return ENOMEM;
@@ -256,16 +253,17 @@ static int sis_ioctl_agp_init( DRM_IOCTL_ARGS )
if (dev_priv->AGPHeap != NULL)
return DRM_ERR(EINVAL);
- DRM_COPY_FROM_USER_IOCTL(agp, (drm_sis_agp_t __user *)data, sizeof(agp));
+ DRM_COPY_FROM_USER_IOCTL(agp, (drm_sis_agp_t __user *) data,
+ sizeof(agp));
dev_priv->AGPHeap = mmInit(agp.offset, agp.size);
DRM_DEBUG("offset = %u, size = %u", agp.offset, agp.size);
-
+
return 0;
}
-static int sis_ioctl_agp_alloc( DRM_IOCTL_ARGS )
+static int sis_ioctl_agp_alloc(DRM_IOCTL_ARGS)
{
DRM_DEVICE;
drm_sis_private_t *dev_priv = dev->dev_private;
@@ -273,12 +271,12 @@ static int sis_ioctl_agp_alloc( DRM_IOCTL_ARGS )
drm_sis_mem_t agp;
PMemBlock block;
int retval = 0;
-
+
if (dev_priv == NULL || dev_priv->AGPHeap == NULL)
return DRM_ERR(EINVAL);
-
+
DRM_COPY_FROM_USER_IOCTL(agp, argp, sizeof(agp));
-
+
block = mmAllocMem(dev_priv->AGPHeap, agp.size, 0, 0);
if (block) {
/* TODO */
@@ -286,10 +284,10 @@ static int sis_ioctl_agp_alloc( DRM_IOCTL_ARGS )
agp.free = (unsigned long)block;
if (!add_alloc_set(agp.context, AGP_TYPE, agp.free)) {
DRM_DEBUG("adding to allocation set fails\n");
- mmFreeMem((PMemBlock)agp.free);
+ mmFreeMem((PMemBlock) agp.free);
retval = -1;
}
- } else {
+ } else {
agp.offset = 0;
agp.size = 0;
agp.free = 0;
@@ -302,7 +300,7 @@ static int sis_ioctl_agp_alloc( DRM_IOCTL_ARGS )
return retval;
}
-static int sis_ioctl_agp_free( DRM_IOCTL_ARGS )
+static int sis_ioctl_agp_free(DRM_IOCTL_ARGS)
{
DRM_DEVICE;
drm_sis_private_t *dev_priv = dev->dev_private;
@@ -311,12 +309,13 @@ static int sis_ioctl_agp_free( DRM_IOCTL_ARGS )
if (dev_priv == NULL || dev_priv->AGPHeap == NULL)
return DRM_ERR(EINVAL);
- DRM_COPY_FROM_USER_IOCTL(agp, (drm_sis_mem_t __user *)data, sizeof(agp));
+ DRM_COPY_FROM_USER_IOCTL(agp, (drm_sis_mem_t __user *) data,
+ sizeof(agp));
- if (!mmBlockInHeap(dev_priv->AGPHeap, (PMemBlock)agp.free))
+ if (!mmBlockInHeap(dev_priv->AGPHeap, (PMemBlock) agp.free))
return DRM_ERR(EINVAL);
- mmFreeMem((PMemBlock)agp.free);
+ mmFreeMem((PMemBlock) agp.free);
if (!del_alloc_set(agp.context, AGP_TYPE, agp.free))
return DRM_ERR(EINVAL);
@@ -329,31 +328,30 @@ int sis_init_context(struct drm_device *dev, int context)
{
int i;
- for (i = 0; i < MAX_CONTEXT ; i++) {
+ for (i = 0; i < MAX_CONTEXT; i++) {
if (global_ppriv[i].used &&
(global_ppriv[i].context == context))
break;
}
if (i >= MAX_CONTEXT) {
- for (i = 0; i < MAX_CONTEXT ; i++) {
+ for (i = 0; i < MAX_CONTEXT; i++) {
if (!global_ppriv[i].used) {
global_ppriv[i].context = context;
global_ppriv[i].used = 1;
global_ppriv[i].sets[0] = setInit();
global_ppriv[i].sets[1] = setInit();
DRM_DEBUG("init allocation set, socket=%d, "
- "context = %d\n", i, context);
+ "context = %d\n", i, context);
break;
}
}
if ((i >= MAX_CONTEXT) || (global_ppriv[i].sets[0] == NULL) ||
- (global_ppriv[i].sets[1] == NULL))
- {
+ (global_ppriv[i].sets[1] == NULL)) {
return 0;
}
}
-
+
return 1;
}
@@ -361,7 +359,7 @@ int sis_final_context(struct drm_device *dev, int context)
{
int i;
- for (i=0; i<MAX_CONTEXT; i++) {
+ for (i = 0; i < MAX_CONTEXT; i++) {
if (global_ppriv[i].used &&
(global_ppriv[i].context == context))
break;
@@ -382,7 +380,7 @@ int sis_final_context(struct drm_device *dev, int context)
#if defined(__linux__) && defined(CONFIG_FB_SIS)
sis_free(item);
#else
- mmFreeMem((PMemBlock)item);
+ mmFreeMem((PMemBlock) item);
#endif
retval = setNext(set, &item);
}
@@ -393,25 +391,24 @@ int sis_final_context(struct drm_device *dev, int context)
retval = setFirst(set, &item);
while (retval) {
DRM_DEBUG("free agp memory 0x%x\n", item);
- mmFreeMem((PMemBlock)item);
+ mmFreeMem((PMemBlock) item);
retval = setNext(set, &item);
}
setDestroy(set);
- global_ppriv[i].used = 0;
- }
-
+ global_ppriv[i].used = 0;
+ }
+
return 1;
}
drm_ioctl_desc_t sis_ioctls[] = {
- [DRM_IOCTL_NR(DRM_SIS_FB_ALLOC)] = { sis_fb_alloc, 1, 0 },
- [DRM_IOCTL_NR(DRM_SIS_FB_FREE)] = { sis_fb_free, 1, 0 },
- [DRM_IOCTL_NR(DRM_SIS_AGP_INIT)] = { sis_ioctl_agp_init, 1, 1 },
- [DRM_IOCTL_NR(DRM_SIS_AGP_ALLOC)] = { sis_ioctl_agp_alloc, 1, 0 },
- [DRM_IOCTL_NR(DRM_SIS_AGP_FREE)] = { sis_ioctl_agp_free, 1, 0 },
- [DRM_IOCTL_NR(DRM_SIS_FB_INIT)] = { sis_fb_init, 1, 1 }
+ [DRM_IOCTL_NR(DRM_SIS_FB_ALLOC)] = {sis_fb_alloc, 1, 0},
+ [DRM_IOCTL_NR(DRM_SIS_FB_FREE)] = {sis_fb_free, 1, 0},
+ [DRM_IOCTL_NR(DRM_SIS_AGP_INIT)] = {sis_ioctl_agp_init, 1, 1},
+ [DRM_IOCTL_NR(DRM_SIS_AGP_ALLOC)] = {sis_ioctl_agp_alloc, 1, 0},
+ [DRM_IOCTL_NR(DRM_SIS_AGP_FREE)] = {sis_ioctl_agp_free, 1, 0},
+ [DRM_IOCTL_NR(DRM_SIS_FB_INIT)] = {sis_fb_init, 1, 1}
};
int sis_max_ioctl = DRM_ARRAY_SIZE(sis_ioctls);
-
diff --git a/drivers/char/drm/tdfx_drv.c b/drivers/char/drm/tdfx_drv.c
index 0e7943e6efea..c275cbb6e9ce 100644
--- a/drivers/char/drm/tdfx_drv.c
+++ b/drivers/char/drm/tdfx_drv.c
@@ -36,30 +36,28 @@
#include "drm_pciids.h"
-static int postinit( struct drm_device *dev, unsigned long flags )
+static int postinit(struct drm_device *dev, unsigned long flags)
{
- DRM_INFO( "Initialized %s %d.%d.%d %s on minor %d: %s\n",
- DRIVER_NAME,
- DRIVER_MAJOR,
- DRIVER_MINOR,
- DRIVER_PATCHLEVEL,
- DRIVER_DATE,
- dev->primary.minor,
- pci_pretty_name(dev->pdev)
- );
+ DRM_INFO("Initialized %s %d.%d.%d %s on minor %d: %s\n",
+ DRIVER_NAME,
+ DRIVER_MAJOR,
+ DRIVER_MINOR,
+ DRIVER_PATCHLEVEL,
+ DRIVER_DATE, dev->primary.minor, pci_pretty_name(dev->pdev)
+ );
return 0;
}
-static int version( drm_version_t *version )
+static int version(drm_version_t * version)
{
int len;
version->version_major = DRIVER_MAJOR;
version->version_minor = DRIVER_MINOR;
version->version_patchlevel = DRIVER_PATCHLEVEL;
- DRM_COPY( version->name, DRIVER_NAME );
- DRM_COPY( version->date, DRIVER_DATE );
- DRM_COPY( version->desc, DRIVER_DESC );
+ DRM_COPY(version->name, DRIVER_NAME);
+ DRM_COPY(version->date, DRIVER_DATE);
+ DRM_COPY(version->desc, DRIVER_DESC);
return 0;
}
@@ -75,18 +73,18 @@ static struct drm_driver driver = {
.postinit = postinit,
.version = version,
.fops = {
- .owner = THIS_MODULE,
- .open = drm_open,
- .release = drm_release,
- .ioctl = drm_ioctl,
- .mmap = drm_mmap,
- .poll = drm_poll,
- .fasync = drm_fasync,
- },
+ .owner = THIS_MODULE,
+ .open = drm_open,
+ .release = drm_release,
+ .ioctl = drm_ioctl,
+ .mmap = drm_mmap,
+ .poll = drm_poll,
+ .fasync = drm_fasync,
+ },
.pci_driver = {
- .name = DRIVER_NAME,
- .id_table = pciidlist,
- }
+ .name = DRIVER_NAME,
+ .id_table = pciidlist,
+ }
};
static int __init tdfx_init(void)
@@ -102,6 +100,6 @@ static void __exit tdfx_exit(void)
module_init(tdfx_init);
module_exit(tdfx_exit);
-MODULE_AUTHOR( DRIVER_AUTHOR );
-MODULE_DESCRIPTION( DRIVER_DESC );
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL and additional rights");
diff --git a/drivers/char/drm/via_3d_reg.h b/drivers/char/drm/via_3d_reg.h
index cf61bb514db1..462375d543b9 100644
--- a/drivers/char/drm/via_3d_reg.h
+++ b/drivers/char/drm/via_3d_reg.h
@@ -1643,7 +1643,6 @@
#define HC_HAGPBpID_STOP 0x00000002
#define HC_HAGPBpH_MASK 0x00ffffff
-
#define VIA_VIDEO_HEADER5 0xFE040000
#define VIA_VIDEO_HEADER6 0xFE050000
#define VIA_VIDEO_HEADER7 0xFE060000
diff --git a/drivers/char/drm/via_dma.c b/drivers/char/drm/via_dma.c
index 4f60f7f4193d..d4b1766608b0 100644
--- a/drivers/char/drm/via_dma.c
+++ b/drivers/char/drm/via_dma.c
@@ -1,11 +1,11 @@
/* via_dma.c -- DMA support for the VIA Unichrome/Pro
- *
+ *
* Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
* All Rights Reserved.
*
* Copyright 2004 Digeo, Inc., Palo Alto, CA, U.S.A.
* All Rights Reserved.
- *
+ *
* Copyright 2004 The Unichrome project.
* All Rights Reserved.
*
@@ -23,14 +23,14 @@
* 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 NON-INFRINGEMENT. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS 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
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS 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.
*
- * Authors:
- * Tungsten Graphics,
- * Erdi Chen,
+ * Authors:
+ * Tungsten Graphics,
+ * Erdi Chen,
* Thomas Hellstrom.
*/
@@ -61,34 +61,31 @@
dev_priv->dma_low +=8; \
}
-#define via_flush_write_combine() DRM_MEMORYBARRIER()
+#define via_flush_write_combine() DRM_MEMORYBARRIER()
#define VIA_OUT_RING_QW(w1,w2) \
*vb++ = (w1); \
*vb++ = (w2); \
- dev_priv->dma_low += 8;
+ dev_priv->dma_low += 8;
static void via_cmdbuf_start(drm_via_private_t * dev_priv);
static void via_cmdbuf_pause(drm_via_private_t * dev_priv);
static void via_cmdbuf_reset(drm_via_private_t * dev_priv);
static void via_cmdbuf_rewind(drm_via_private_t * dev_priv);
static int via_wait_idle(drm_via_private_t * dev_priv);
-static void via_pad_cache(drm_via_private_t *dev_priv, int qwords);
-
+static void via_pad_cache(drm_via_private_t * dev_priv, int qwords);
/*
* Free space in command buffer.
*/
-static uint32_t
-via_cmdbuf_space(drm_via_private_t *dev_priv)
+static uint32_t via_cmdbuf_space(drm_via_private_t * dev_priv)
{
- uint32_t agp_base = dev_priv->dma_offset +
- (uint32_t) dev_priv->agpAddr;
+ uint32_t agp_base = dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr;
uint32_t hw_addr = *(dev_priv->hw_addr_ptr) - agp_base;
-
- return ((hw_addr <= dev_priv->dma_low) ?
- (dev_priv->dma_high + hw_addr - dev_priv->dma_low) :
+
+ return ((hw_addr <= dev_priv->dma_low) ?
+ (dev_priv->dma_high + hw_addr - dev_priv->dma_low) :
(hw_addr - dev_priv->dma_low));
}
@@ -96,15 +93,13 @@ via_cmdbuf_space(drm_via_private_t *dev_priv)
* How much does the command regulator lag behind?
*/
-static uint32_t
-via_cmdbuf_lag(drm_via_private_t *dev_priv)
+static uint32_t via_cmdbuf_lag(drm_via_private_t * dev_priv)
{
- uint32_t agp_base = dev_priv->dma_offset +
- (uint32_t) dev_priv->agpAddr;
+ uint32_t agp_base = dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr;
uint32_t hw_addr = *(dev_priv->hw_addr_ptr) - agp_base;
-
- return ((hw_addr <= dev_priv->dma_low) ?
- (dev_priv->dma_low - hw_addr) :
+
+ return ((hw_addr <= dev_priv->dma_low) ?
+ (dev_priv->dma_low - hw_addr) :
(dev_priv->dma_wrap + dev_priv->dma_low - hw_addr));
}
@@ -121,20 +116,20 @@ via_cmdbuf_wait(drm_via_private_t * dev_priv, unsigned int size)
uint32_t count;
hw_addr_ptr = dev_priv->hw_addr_ptr;
cur_addr = dev_priv->dma_low;
- next_addr = cur_addr + size + 512*1024;
+ next_addr = cur_addr + size + 512 * 1024;
count = 1000000;
do {
- hw_addr = *hw_addr_ptr - agp_base;
+ hw_addr = *hw_addr_ptr - agp_base;
if (count-- == 0) {
- DRM_ERROR("via_cmdbuf_wait timed out hw %x cur_addr %x next_addr %x\n",
- hw_addr, cur_addr, next_addr);
+ DRM_ERROR
+ ("via_cmdbuf_wait timed out hw %x cur_addr %x next_addr %x\n",
+ hw_addr, cur_addr, next_addr);
return -1;
}
} while ((cur_addr < hw_addr) && (next_addr >= hw_addr));
return 0;
}
-
/*
* Checks whether buffer head has reach the end. Rewind the ring buffer
* when necessary.
@@ -145,7 +140,8 @@ via_cmdbuf_wait(drm_via_private_t * dev_priv, unsigned int size)
static inline uint32_t *via_check_dma(drm_via_private_t * dev_priv,
unsigned int size)
{
- if ((dev_priv->dma_low + size + 4*CMDBUF_ALIGNMENT_SIZE) > dev_priv->dma_high) {
+ if ((dev_priv->dma_low + size + 4 * CMDBUF_ALIGNMENT_SIZE) >
+ dev_priv->dma_high) {
via_cmdbuf_rewind(dev_priv);
}
if (via_cmdbuf_wait(dev_priv, size) != 0) {
@@ -159,7 +155,7 @@ int via_dma_cleanup(drm_device_t * dev)
{
if (dev->dev_private) {
drm_via_private_t *dev_priv =
- (drm_via_private_t *) dev->dev_private;
+ (drm_via_private_t *) dev->dev_private;
if (dev_priv->ring.virtual_start) {
via_cmdbuf_reset(dev_priv);
@@ -189,7 +185,7 @@ static int via_initialize(drm_device_t * dev,
}
if (!dev->agp || !dev->agp->base) {
- DRM_ERROR("%s called with no agp memory available\n",
+ DRM_ERROR("%s called with no agp memory available\n",
__FUNCTION__);
return DRM_ERR(EFAULT);
}
@@ -247,10 +243,10 @@ int via_dma_init(DRM_IOCTL_ARGS)
else
retcode = via_dma_cleanup(dev);
break;
- case VIA_DMA_INITIALIZED:
- retcode = (dev_priv->ring.virtual_start != NULL) ?
- 0: DRM_ERR( EFAULT );
- break;
+ case VIA_DMA_INITIALIZED:
+ retcode = (dev_priv->ring.virtual_start != NULL) ?
+ 0 : DRM_ERR(EFAULT);
+ break;
default:
retcode = DRM_ERR(EINVAL);
break;
@@ -259,8 +255,6 @@ int via_dma_init(DRM_IOCTL_ARGS)
return retcode;
}
-
-
static int via_dispatch_cmdbuffer(drm_device_t * dev, drm_via_cmdbuffer_t * cmd)
{
drm_via_private_t *dev_priv;
@@ -277,8 +271,7 @@ static int via_dispatch_cmdbuffer(drm_device_t * dev, drm_via_cmdbuffer_t * cmd)
if (cmd->size > VIA_PCI_BUF_SIZE) {
return DRM_ERR(ENOMEM);
- }
-
+ }
if (DRM_COPY_FROM_USER(dev_priv->pci_buf, cmd->buf, cmd->size))
return DRM_ERR(EFAULT);
@@ -289,19 +282,19 @@ static int via_dispatch_cmdbuffer(drm_device_t * dev, drm_via_cmdbuffer_t * cmd)
* copy it to AGP memory when ready.
*/
-
- if ((ret = via_verify_command_stream((uint32_t *)dev_priv->pci_buf, cmd->size, dev, 1))) {
+ if ((ret =
+ via_verify_command_stream((uint32_t *) dev_priv->pci_buf,
+ cmd->size, dev, 1))) {
return ret;
}
-
-
+
vb = via_check_dma(dev_priv, (cmd->size < 0x100) ? 0x102 : cmd->size);
if (vb == NULL) {
return DRM_ERR(EAGAIN);
}
memcpy(vb, dev_priv->pci_buf, cmd->size);
-
+
dev_priv->dma_low += cmd->size;
/*
@@ -310,7 +303,7 @@ static int via_dispatch_cmdbuffer(drm_device_t * dev, drm_via_cmdbuffer_t * cmd)
*/
if (cmd->size < 0x100)
- via_pad_cache(dev_priv,(0x100 - cmd->size) >> 3);
+ via_pad_cache(dev_priv, (0x100 - cmd->size) >> 3);
via_cmdbuf_pause(dev_priv);
return 0;
@@ -330,7 +323,7 @@ int via_flush_ioctl(DRM_IOCTL_ARGS)
{
DRM_DEVICE;
- LOCK_TEST_WITH_RETURN( dev, filp );
+ LOCK_TEST_WITH_RETURN(dev, filp);
return via_driver_dma_quiescent(dev);
}
@@ -341,7 +334,7 @@ int via_cmdbuffer(DRM_IOCTL_ARGS)
drm_via_cmdbuffer_t cmdbuf;
int ret;
- LOCK_TEST_WITH_RETURN( dev, filp );
+ LOCK_TEST_WITH_RETURN(dev, filp);
DRM_COPY_FROM_USER_IOCTL(cmdbuf, (drm_via_cmdbuffer_t __user *) data,
sizeof(cmdbuf));
@@ -356,8 +349,9 @@ int via_cmdbuffer(DRM_IOCTL_ARGS)
return 0;
}
-extern int
-via_parse_command_stream(drm_device_t *dev, const uint32_t * buf, unsigned int size);
+extern int
+via_parse_command_stream(drm_device_t * dev, const uint32_t * buf,
+ unsigned int size);
static int via_dispatch_pci_cmdbuffer(drm_device_t * dev,
drm_via_cmdbuffer_t * cmd)
{
@@ -366,15 +360,19 @@ static int via_dispatch_pci_cmdbuffer(drm_device_t * dev,
if (cmd->size > VIA_PCI_BUF_SIZE) {
return DRM_ERR(ENOMEM);
- }
+ }
if (DRM_COPY_FROM_USER(dev_priv->pci_buf, cmd->buf, cmd->size))
return DRM_ERR(EFAULT);
-
- if ((ret = via_verify_command_stream((uint32_t *)dev_priv->pci_buf, cmd->size, dev, 0))) {
+
+ if ((ret =
+ via_verify_command_stream((uint32_t *) dev_priv->pci_buf,
+ cmd->size, dev, 0))) {
return ret;
}
-
- ret = via_parse_command_stream(dev, (const uint32_t *)dev_priv->pci_buf, cmd->size);
+
+ ret =
+ via_parse_command_stream(dev, (const uint32_t *)dev_priv->pci_buf,
+ cmd->size);
return ret;
}
@@ -384,7 +382,7 @@ int via_pci_cmdbuffer(DRM_IOCTL_ARGS)
drm_via_cmdbuffer_t cmdbuf;
int ret;
- LOCK_TEST_WITH_RETURN( dev, filp );
+ LOCK_TEST_WITH_RETURN(dev, filp);
DRM_COPY_FROM_USER_IOCTL(cmdbuf, (drm_via_cmdbuffer_t __user *) data,
sizeof(cmdbuf));
@@ -400,17 +398,15 @@ int via_pci_cmdbuffer(DRM_IOCTL_ARGS)
return 0;
}
-
static inline uint32_t *via_align_buffer(drm_via_private_t * dev_priv,
uint32_t * vb, int qw_count)
{
- for (; qw_count > 0; --qw_count) {
+ for (; qw_count > 0; --qw_count) {
VIA_OUT_RING_QW(HC_DUMMY, HC_DUMMY);
}
return vb;
}
-
/*
* This function is used internally by ring buffer mangement code.
*
@@ -426,7 +422,7 @@ static inline uint32_t *via_get_dma(drm_via_private_t * dev_priv)
* modifying the pause address stored in the buffer itself. If
* the regulator has already paused, restart it.
*/
-static int via_hook_segment(drm_via_private_t *dev_priv,
+static int via_hook_segment(drm_via_private_t * dev_priv,
uint32_t pause_addr_hi, uint32_t pause_addr_lo,
int no_pci_fire)
{
@@ -434,7 +430,7 @@ static int via_hook_segment(drm_via_private_t *dev_priv,
volatile uint32_t *paused_at = dev_priv->last_pause_ptr;
via_flush_write_combine();
- while(! *(via_get_dma(dev_priv)-1));
+ while (!*(via_get_dma(dev_priv) - 1)) ;
*dev_priv->last_pause_ptr = pause_addr_lo;
via_flush_write_combine();
@@ -443,55 +439,53 @@ static int via_hook_segment(drm_via_private_t *dev_priv,
* Not sure it is needed.
*/
- while(! *dev_priv->last_pause_ptr);
+ while (!*dev_priv->last_pause_ptr) ;
dev_priv->last_pause_ptr = via_get_dma(dev_priv) - 1;
- while(! *dev_priv->last_pause_ptr);
-
+ while (!*dev_priv->last_pause_ptr) ;
paused = 0;
- count = 20;
+ count = 20;
- while (!(paused = (VIA_READ(0x41c) & 0x80000000)) && count--);
+ while (!(paused = (VIA_READ(0x41c) & 0x80000000)) && count--) ;
if ((count <= 8) && (count >= 0)) {
uint32_t rgtr, ptr;
rgtr = *(dev_priv->hw_addr_ptr);
- ptr = ((char *)dev_priv->last_pause_ptr - dev_priv->dma_ptr) +
- dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr + 4 -
- CMDBUF_ALIGNMENT_SIZE;
+ ptr = ((char *)dev_priv->last_pause_ptr - dev_priv->dma_ptr) +
+ dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr + 4 -
+ CMDBUF_ALIGNMENT_SIZE;
if (rgtr <= ptr) {
- DRM_ERROR("Command regulator\npaused at count %d, address %x, "
- "while current pause address is %x.\n"
- "Please mail this message to "
- "<unichrome-devel@lists.sourceforge.net>\n",
- count, rgtr, ptr);
+ DRM_ERROR
+ ("Command regulator\npaused at count %d, address %x, "
+ "while current pause address is %x.\n"
+ "Please mail this message to "
+ "<unichrome-devel@lists.sourceforge.net>\n", count,
+ rgtr, ptr);
}
}
-
+
if (paused && !no_pci_fire) {
- uint32_t rgtr,ptr;
+ uint32_t rgtr, ptr;
uint32_t ptr_low;
count = 1000000;
- while ((VIA_READ(VIA_REG_STATUS) & VIA_CMD_RGTR_BUSY) && count--);
-
+ while ((VIA_READ(VIA_REG_STATUS) & VIA_CMD_RGTR_BUSY)
+ && count--) ;
+
rgtr = *(dev_priv->hw_addr_ptr);
- ptr = ((char *)paused_at - dev_priv->dma_ptr) +
- dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr + 4;
-
+ ptr = ((char *)paused_at - dev_priv->dma_ptr) +
+ dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr + 4;
- ptr_low = (ptr > 3*CMDBUF_ALIGNMENT_SIZE) ?
- ptr - 3*CMDBUF_ALIGNMENT_SIZE : 0;
+ ptr_low = (ptr > 3 * CMDBUF_ALIGNMENT_SIZE) ?
+ ptr - 3 * CMDBUF_ALIGNMENT_SIZE : 0;
if (rgtr <= ptr && rgtr >= ptr_low) {
VIA_WRITE(VIA_REG_TRANSET, (HC_ParaType_PreCR << 16));
VIA_WRITE(VIA_REG_TRANSPACE, pause_addr_hi);
VIA_WRITE(VIA_REG_TRANSPACE, pause_addr_lo);
- }
+ }
}
return paused;
}
-
-
static int via_wait_idle(drm_via_private_t * dev_priv)
{
int count = 10000000;
@@ -502,9 +496,8 @@ static int via_wait_idle(drm_via_private_t * dev_priv)
}
static uint32_t *via_align_cmd(drm_via_private_t * dev_priv, uint32_t cmd_type,
- uint32_t addr, uint32_t *cmd_addr_hi,
- uint32_t *cmd_addr_lo,
- int skip_wait)
+ uint32_t addr, uint32_t * cmd_addr_hi,
+ uint32_t * cmd_addr_lo, int skip_wait)
{
uint32_t agp_base;
uint32_t cmd_addr, addr_lo, addr_hi;
@@ -512,31 +505,26 @@ static uint32_t *via_align_cmd(drm_via_private_t * dev_priv, uint32_t cmd_type,
uint32_t qw_pad_count;
if (!skip_wait)
- via_cmdbuf_wait(dev_priv, 2*CMDBUF_ALIGNMENT_SIZE);
+ via_cmdbuf_wait(dev_priv, 2 * CMDBUF_ALIGNMENT_SIZE);
vb = via_get_dma(dev_priv);
- VIA_OUT_RING_QW( HC_HEADER2 | ((VIA_REG_TRANSET >> 2) << 12) |
- (VIA_REG_TRANSPACE >> 2), HC_ParaType_PreCR << 16);
+ VIA_OUT_RING_QW(HC_HEADER2 | ((VIA_REG_TRANSET >> 2) << 12) |
+ (VIA_REG_TRANSPACE >> 2), HC_ParaType_PreCR << 16);
agp_base = dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr;
qw_pad_count = (CMDBUF_ALIGNMENT_SIZE >> 3) -
- ((dev_priv->dma_low & CMDBUF_ALIGNMENT_MASK) >> 3);
+ ((dev_priv->dma_low & CMDBUF_ALIGNMENT_MASK) >> 3);
-
- cmd_addr = (addr) ? addr :
- agp_base + dev_priv->dma_low - 8 + (qw_pad_count << 3);
+ cmd_addr = (addr) ? addr :
+ agp_base + dev_priv->dma_low - 8 + (qw_pad_count << 3);
addr_lo = ((HC_SubA_HAGPBpL << 24) | (cmd_type & HC_HAGPBpID_MASK) |
(cmd_addr & HC_HAGPBpL_MASK));
addr_hi = ((HC_SubA_HAGPBpH << 24) | (cmd_addr >> 24));
vb = via_align_buffer(dev_priv, vb, qw_pad_count - 1);
- VIA_OUT_RING_QW(*cmd_addr_hi = addr_hi,
- *cmd_addr_lo = addr_lo);
+ VIA_OUT_RING_QW(*cmd_addr_hi = addr_hi, *cmd_addr_lo = addr_lo);
return vb;
}
-
-
-
static void via_cmdbuf_start(drm_via_private_t * dev_priv)
{
uint32_t pause_addr_lo, pause_addr_hi;
@@ -545,7 +533,6 @@ static void via_cmdbuf_start(drm_via_private_t * dev_priv)
uint32_t command;
uint32_t agp_base;
-
dev_priv->dma_low = 0;
agp_base = dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr;
@@ -557,12 +544,12 @@ static void via_cmdbuf_start(drm_via_private_t * dev_priv)
command = ((HC_SubA_HAGPCMNT << 24) | (start_addr >> 24) |
((end_addr & 0xff000000) >> 16));
- dev_priv->last_pause_ptr =
- via_align_cmd(dev_priv, HC_HAGPBpID_PAUSE, 0,
- &pause_addr_hi, & pause_addr_lo, 1) - 1;
+ dev_priv->last_pause_ptr =
+ via_align_cmd(dev_priv, HC_HAGPBpID_PAUSE, 0,
+ &pause_addr_hi, &pause_addr_lo, 1) - 1;
via_flush_write_combine();
- while(! *dev_priv->last_pause_ptr);
+ while (!*dev_priv->last_pause_ptr) ;
VIA_WRITE(VIA_REG_TRANSET, (HC_ParaType_PreCR << 16));
VIA_WRITE(VIA_REG_TRANSPACE, command);
@@ -575,14 +562,14 @@ static void via_cmdbuf_start(drm_via_private_t * dev_priv)
VIA_WRITE(VIA_REG_TRANSPACE, command | HC_HAGPCMNT_MASK);
}
-static void via_pad_cache(drm_via_private_t *dev_priv, int qwords)
+static void via_pad_cache(drm_via_private_t * dev_priv, int qwords)
{
uint32_t *vb;
via_cmdbuf_wait(dev_priv, qwords + 2);
vb = via_get_dma(dev_priv);
- VIA_OUT_RING_QW( HC_HEADER2, HC_ParaType_NotTex << 16);
- via_align_buffer(dev_priv,vb,qwords);
+ VIA_OUT_RING_QW(HC_HEADER2, HC_ParaType_NotTex << 16);
+ via_align_buffer(dev_priv, vb, qwords);
}
static inline void via_dummy_bitblt(drm_via_private_t * dev_priv)
@@ -590,10 +577,9 @@ static inline void via_dummy_bitblt(drm_via_private_t * dev_priv)
uint32_t *vb = via_get_dma(dev_priv);
SetReg2DAGP(0x0C, (0 | (0 << 16)));
SetReg2DAGP(0x10, 0 | (0 << 16));
- SetReg2DAGP(0x0, 0x1 | 0x2000 | 0xAA000000);
+ SetReg2DAGP(0x0, 0x1 | 0x2000 | 0xAA000000);
}
-
static void via_cmdbuf_jump(drm_via_private_t * dev_priv)
{
uint32_t agp_base;
@@ -603,11 +589,10 @@ static void via_cmdbuf_jump(drm_via_private_t * dev_priv)
uint32_t dma_low_save1, dma_low_save2;
agp_base = dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr;
- via_align_cmd(dev_priv, HC_HAGPBpID_JUMP, 0, &jump_addr_hi,
+ via_align_cmd(dev_priv, HC_HAGPBpID_JUMP, 0, &jump_addr_hi,
&jump_addr_lo, 0);
-
- dev_priv->dma_wrap = dev_priv->dma_low;
+ dev_priv->dma_wrap = dev_priv->dma_low;
/*
* Wrap command buffer to the beginning.
@@ -619,11 +604,12 @@ static void via_cmdbuf_jump(drm_via_private_t * dev_priv)
}
via_dummy_bitblt(dev_priv);
- via_dummy_bitblt(dev_priv);
+ via_dummy_bitblt(dev_priv);
- last_pause_ptr = via_align_cmd(dev_priv, HC_HAGPBpID_PAUSE, 0, &pause_addr_hi,
- &pause_addr_lo, 0) -1;
- via_align_cmd(dev_priv, HC_HAGPBpID_PAUSE, 0, &pause_addr_hi,
+ last_pause_ptr =
+ via_align_cmd(dev_priv, HC_HAGPBpID_PAUSE, 0, &pause_addr_hi,
+ &pause_addr_lo, 0) - 1;
+ via_align_cmd(dev_priv, HC_HAGPBpID_PAUSE, 0, &pause_addr_hi,
&pause_addr_lo, 0);
*last_pause_ptr = pause_addr_lo;
@@ -638,23 +624,23 @@ static void via_cmdbuf_jump(drm_via_private_t * dev_priv)
* does not seem to get updated immediately when a jump occurs.
*/
- last_pause_ptr = via_align_cmd(dev_priv, HC_HAGPBpID_PAUSE, 0, &pause_addr_hi,
- &pause_addr_lo, 0) -1;
- via_align_cmd(dev_priv, HC_HAGPBpID_PAUSE, 0, &pause_addr_hi,
+ last_pause_ptr =
+ via_align_cmd(dev_priv, HC_HAGPBpID_PAUSE, 0, &pause_addr_hi,
+ &pause_addr_lo, 0) - 1;
+ via_align_cmd(dev_priv, HC_HAGPBpID_PAUSE, 0, &pause_addr_hi,
&pause_addr_lo, 0);
*last_pause_ptr = pause_addr_lo;
dma_low_save2 = dev_priv->dma_low;
- dev_priv->dma_low = dma_low_save1;
- via_hook_segment( dev_priv, jump_addr_hi, jump_addr_lo, 0);
+ dev_priv->dma_low = dma_low_save1;
+ via_hook_segment(dev_priv, jump_addr_hi, jump_addr_lo, 0);
dev_priv->dma_low = dma_low_save2;
- via_hook_segment( dev_priv, pause_addr_hi, pause_addr_lo, 0);
+ via_hook_segment(dev_priv, pause_addr_hi, pause_addr_lo, 0);
}
-
static void via_cmdbuf_rewind(drm_via_private_t * dev_priv)
{
- via_cmdbuf_jump(dev_priv);
+ via_cmdbuf_jump(dev_priv);
}
static void via_cmdbuf_flush(drm_via_private_t * dev_priv, uint32_t cmd_type)
@@ -662,10 +648,9 @@ static void via_cmdbuf_flush(drm_via_private_t * dev_priv, uint32_t cmd_type)
uint32_t pause_addr_lo, pause_addr_hi;
via_align_cmd(dev_priv, cmd_type, 0, &pause_addr_hi, &pause_addr_lo, 0);
- via_hook_segment( dev_priv, pause_addr_hi, pause_addr_lo, 0);
+ via_hook_segment(dev_priv, pause_addr_hi, pause_addr_lo, 0);
}
-
static void via_cmdbuf_pause(drm_via_private_t * dev_priv)
{
via_cmdbuf_flush(dev_priv, HC_HAGPBpID_PAUSE);
@@ -681,8 +666,7 @@ static void via_cmdbuf_reset(drm_via_private_t * dev_priv)
* User interface to the space and lag functions.
*/
-int
-via_cmdbuf_size(DRM_IOCTL_ARGS)
+int via_cmdbuf_size(DRM_IOCTL_ARGS)
{
DRM_DEVICE;
drm_via_cmdbuf_size_t d_siz;
@@ -691,7 +675,7 @@ via_cmdbuf_size(DRM_IOCTL_ARGS)
drm_via_private_t *dev_priv;
DRM_DEBUG("via cmdbuf_size\n");
- LOCK_TEST_WITH_RETURN( dev, filp );
+ LOCK_TEST_WITH_RETURN(dev, filp);
dev_priv = (drm_via_private_t *) dev->dev_private;
@@ -704,12 +688,12 @@ via_cmdbuf_size(DRM_IOCTL_ARGS)
DRM_COPY_FROM_USER_IOCTL(d_siz, (drm_via_cmdbuf_size_t __user *) data,
sizeof(d_siz));
-
count = 1000000;
tmp_size = d_siz.size;
- switch(d_siz.func) {
+ switch (d_siz.func) {
case VIA_CMDBUF_SPACE:
- while (((tmp_size = via_cmdbuf_space(dev_priv)) < d_siz.size) && count--) {
+ while (((tmp_size = via_cmdbuf_space(dev_priv)) < d_siz.size)
+ && count--) {
if (!d_siz.wait) {
break;
}
@@ -720,7 +704,8 @@ via_cmdbuf_size(DRM_IOCTL_ARGS)
}
break;
case VIA_CMDBUF_LAG:
- while (((tmp_size = via_cmdbuf_lag(dev_priv)) > d_siz.size) && count--) {
+ while (((tmp_size = via_cmdbuf_lag(dev_priv)) > d_siz.size)
+ && count--) {
if (!d_siz.wait) {
break;
}
diff --git a/drivers/char/drm/via_drm.h b/drivers/char/drm/via_drm.h
index be346bb0a26a..ebde9206115e 100644
--- a/drivers/char/drm/via_drm.h
+++ b/drivers/char/drm/via_drm.h
@@ -149,7 +149,7 @@ typedef struct _drm_via_dma_init {
enum {
VIA_INIT_DMA = 0x01,
VIA_CLEANUP_DMA = 0x02,
- VIA_DMA_INITIALIZED = 0x03
+ VIA_DMA_INITIALIZED = 0x03
} func;
unsigned long offset;
@@ -212,7 +212,7 @@ typedef enum {
#define VIA_IRQ_FLAGS_MASK 0xF0000000
-struct drm_via_wait_irq_request{
+struct drm_via_wait_irq_request {
unsigned irq;
via_irq_seq_type_t type;
uint32_t sequence;
diff --git a/drivers/char/drm/via_drv.c b/drivers/char/drm/via_drv.c
index 275eefc79221..016665e0c69f 100644
--- a/drivers/char/drm/via_drv.c
+++ b/drivers/char/drm/via_drv.c
@@ -93,18 +93,18 @@ static struct drm_driver driver = {
.ioctls = ioctls,
.num_ioctls = DRM_ARRAY_SIZE(ioctls),
.fops = {
- .owner = THIS_MODULE,
- .open = drm_open,
- .release = drm_release,
- .ioctl = drm_ioctl,
- .mmap = drm_mmap,
- .poll = drm_poll,
- .fasync = drm_fasync,
- },
+ .owner = THIS_MODULE,
+ .open = drm_open,
+ .release = drm_release,
+ .ioctl = drm_ioctl,
+ .mmap = drm_mmap,
+ .poll = drm_poll,
+ .fasync = drm_fasync,
+ },
.pci_driver = {
- .name = DRIVER_NAME,
- .id_table = pciidlist,
- }
+ .name = DRIVER_NAME,
+ .id_table = pciidlist,
+ }
};
static int __init via_init(void)
diff --git a/drivers/char/drm/via_drv.h b/drivers/char/drm/via_drv.h
index 4eaa8b7c4c96..7d5daf43797e 100644
--- a/drivers/char/drm/via_drv.h
+++ b/drivers/char/drm/via_drv.h
@@ -40,8 +40,6 @@
#define VIA_FIRE_BUF_SIZE 1024
#define VIA_NUM_IRQS 2
-
-
typedef struct drm_via_ring_buffer {
drm_map_t map;
char *virtual_start;
@@ -55,7 +53,7 @@ typedef struct drm_via_irq {
uint32_t enable_mask;
wait_queue_head_t irq_queue;
} drm_via_irq_t;
-
+
typedef struct drm_via_private {
drm_via_sarea_t *sarea_priv;
drm_map_t *sarea;
@@ -71,9 +69,9 @@ typedef struct drm_via_private {
volatile uint32_t *last_pause_ptr;
volatile uint32_t *hw_addr_ptr;
drm_via_ring_buffer_t ring;
- struct timeval last_vblank;
- int last_vblank_valid;
- unsigned usec_per_vblank;
+ struct timeval last_vblank;
+ int last_vblank_valid;
+ unsigned usec_per_vblank;
drm_via_state_t hc_state;
char pci_buf[VIA_PCI_BUF_SIZE];
const uint32_t *fire_offsets[VIA_FIRE_BUF_SIZE];
@@ -82,8 +80,8 @@ typedef struct drm_via_private {
drm_via_irq_t via_irqs[VIA_NUM_IRQS];
unsigned num_irqs;
maskarray_t *irq_masks;
- uint32_t irq_enable_mask;
- uint32_t irq_pending_mask;
+ uint32_t irq_enable_mask;
+ uint32_t irq_pending_mask;
} drm_via_private_t;
/* VIA MMIO register access */
@@ -110,9 +108,11 @@ extern void via_driver_irq_uninstall(drm_device_t * dev);
extern int via_dma_cleanup(drm_device_t * dev);
extern void via_init_command_verifier(void);
extern int via_driver_dma_quiescent(drm_device_t * dev);
-extern void via_init_futex(drm_via_private_t *dev_priv);
-extern void via_cleanup_futex(drm_via_private_t *dev_priv);
-extern void via_release_futex(drm_via_private_t *dev_priv, int context);
+extern void via_init_futex(drm_via_private_t * dev_priv);
+extern void via_cleanup_futex(drm_via_private_t * dev_priv);
+extern void via_release_futex(drm_via_private_t * dev_priv, int context);
+extern int via_parse_command_stream(drm_device_t * dev, const uint32_t * buf,
+ unsigned int size);
#endif
diff --git a/drivers/char/drm/via_irq.c b/drivers/char/drm/via_irq.c
index e8027f3a93b0..d023add1929b 100644
--- a/drivers/char/drm/via_irq.c
+++ b/drivers/char/drm/via_irq.c
@@ -54,23 +54,26 @@
/*
* Device-specific IRQs go here. This type might need to be extended with
* the register if there are multiple IRQ control registers.
- * Currently we activate the HQV interrupts of Unichrome Pro group A.
+ * Currently we activate the HQV interrupts of Unichrome Pro group A.
*/
static maskarray_t via_pro_group_a_irqs[] = {
- {VIA_IRQ_HQV0_ENABLE, VIA_IRQ_HQV0_PENDING, 0x000003D0, 0x00008010, 0x00000000 },
- {VIA_IRQ_HQV1_ENABLE, VIA_IRQ_HQV1_PENDING, 0x000013D0, 0x00008010, 0x00000000 }};
-static int via_num_pro_group_a = sizeof(via_pro_group_a_irqs)/sizeof(maskarray_t);
-
-static maskarray_t via_unichrome_irqs[] = {};
-static int via_num_unichrome = sizeof(via_unichrome_irqs)/sizeof(maskarray_t);
-
-
-static unsigned time_diff(struct timeval *now,struct timeval *then)
+ {VIA_IRQ_HQV0_ENABLE, VIA_IRQ_HQV0_PENDING, 0x000003D0, 0x00008010,
+ 0x00000000},
+ {VIA_IRQ_HQV1_ENABLE, VIA_IRQ_HQV1_PENDING, 0x000013D0, 0x00008010,
+ 0x00000000}
+};
+static int via_num_pro_group_a =
+ sizeof(via_pro_group_a_irqs) / sizeof(maskarray_t);
+
+static maskarray_t via_unichrome_irqs[] = { };
+static int via_num_unichrome = sizeof(via_unichrome_irqs) / sizeof(maskarray_t);
+
+static unsigned time_diff(struct timeval *now, struct timeval *then)
{
- return (now->tv_usec >= then->tv_usec) ?
- now->tv_usec - then->tv_usec :
- 1000000 - (then->tv_usec - now->tv_usec);
+ return (now->tv_usec >= then->tv_usec) ?
+ now->tv_usec - then->tv_usec :
+ 1000000 - (then->tv_usec - now->tv_usec);
}
irqreturn_t via_driver_irq_handler(DRM_IRQ_ARGS)
@@ -86,38 +89,37 @@ irqreturn_t via_driver_irq_handler(DRM_IRQ_ARGS)
status = VIA_READ(VIA_REG_INTERRUPT);
if (status & VIA_IRQ_VBLANK_PENDING) {
atomic_inc(&dev->vbl_received);
- if (!(atomic_read(&dev->vbl_received) & 0x0F)) {
+ if (!(atomic_read(&dev->vbl_received) & 0x0F)) {
do_gettimeofday(&cur_vblank);
- if (dev_priv->last_vblank_valid) {
- dev_priv->usec_per_vblank =
- time_diff( &cur_vblank,&dev_priv->last_vblank) >> 4;
+ if (dev_priv->last_vblank_valid) {
+ dev_priv->usec_per_vblank =
+ time_diff(&cur_vblank,
+ &dev_priv->last_vblank) >> 4;
}
dev_priv->last_vblank = cur_vblank;
dev_priv->last_vblank_valid = 1;
- }
- if (!(atomic_read(&dev->vbl_received) & 0xFF)) {
+ }
+ if (!(atomic_read(&dev->vbl_received) & 0xFF)) {
DRM_DEBUG("US per vblank is: %u\n",
- dev_priv->usec_per_vblank);
+ dev_priv->usec_per_vblank);
}
DRM_WAKEUP(&dev->vbl_queue);
drm_vbl_send_signals(dev);
handled = 1;
}
-
- for (i=0; i<dev_priv->num_irqs; ++i) {
+ for (i = 0; i < dev_priv->num_irqs; ++i) {
if (status & cur_irq->pending_mask) {
- atomic_inc( &cur_irq->irq_received );
- DRM_WAKEUP( &cur_irq->irq_queue );
+ atomic_inc(&cur_irq->irq_received);
+ DRM_WAKEUP(&cur_irq->irq_queue);
handled = 1;
}
cur_irq++;
}
-
+
/* Acknowlege interrupts */
VIA_WRITE(VIA_REG_INTERRUPT, status);
-
if (handled)
return IRQ_HANDLED;
else
@@ -131,7 +133,7 @@ static __inline__ void viadrv_acknowledge_irqs(drm_via_private_t * dev_priv)
if (dev_priv) {
/* Acknowlege interrupts */
status = VIA_READ(VIA_REG_INTERRUPT);
- VIA_WRITE(VIA_REG_INTERRUPT, status |
+ VIA_WRITE(VIA_REG_INTERRUPT, status |
dev_priv->irq_pending_mask);
}
}
@@ -158,12 +160,12 @@ int via_driver_vblank_wait(drm_device_t * dev, unsigned int *sequence)
DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ,
(((cur_vblank = atomic_read(&dev->vbl_received)) -
*sequence) <= (1 << 23)));
-
+
*sequence = cur_vblank;
return ret;
}
-static int
+static int
via_driver_irq_wait(drm_device_t * dev, unsigned int irq, int force_sequence,
unsigned int *sequence)
{
@@ -180,27 +182,29 @@ via_driver_irq_wait(drm_device_t * dev, unsigned int irq, int force_sequence,
return DRM_ERR(EINVAL);
}
- if (irq >= dev_priv->num_irqs ) {
- DRM_ERROR("%s Trying to wait on unknown irq %d\n", __FUNCTION__, irq);
+ if (irq >= dev_priv->num_irqs) {
+ DRM_ERROR("%s Trying to wait on unknown irq %d\n", __FUNCTION__,
+ irq);
return DRM_ERR(EINVAL);
}
-
+
cur_irq += irq;
if (masks[irq][2] && !force_sequence) {
DRM_WAIT_ON(ret, cur_irq->irq_queue, 3 * DRM_HZ,
- ((VIA_READ(masks[irq][2]) & masks[irq][3]) == masks[irq][4]));
+ ((VIA_READ(masks[irq][2]) & masks[irq][3]) ==
+ masks[irq][4]));
cur_irq_sequence = atomic_read(&cur_irq->irq_received);
} else {
DRM_WAIT_ON(ret, cur_irq->irq_queue, 3 * DRM_HZ,
- (((cur_irq_sequence = atomic_read(&cur_irq->irq_received)) -
- *sequence) <= (1 << 23)));
+ (((cur_irq_sequence =
+ atomic_read(&cur_irq->irq_received)) -
+ *sequence) <= (1 << 23)));
}
*sequence = cur_irq_sequence;
return ret;
}
-
/*
* drm_dma.h hooks
*/
@@ -219,29 +223,29 @@ void via_driver_irq_preinstall(drm_device_t * dev)
dev_priv->irq_pending_mask = VIA_IRQ_VBLANK_PENDING;
dev_priv->irq_masks = (dev_priv->pro_group_a) ?
- via_pro_group_a_irqs : via_unichrome_irqs;
+ via_pro_group_a_irqs : via_unichrome_irqs;
dev_priv->num_irqs = (dev_priv->pro_group_a) ?
- via_num_pro_group_a : via_num_unichrome;
-
- for(i=0; i < dev_priv->num_irqs; ++i) {
+ via_num_pro_group_a : via_num_unichrome;
+
+ for (i = 0; i < dev_priv->num_irqs; ++i) {
atomic_set(&cur_irq->irq_received, 0);
- cur_irq->enable_mask = dev_priv->irq_masks[i][0];
+ cur_irq->enable_mask = dev_priv->irq_masks[i][0];
cur_irq->pending_mask = dev_priv->irq_masks[i][1];
- DRM_INIT_WAITQUEUE( &cur_irq->irq_queue );
+ DRM_INIT_WAITQUEUE(&cur_irq->irq_queue);
dev_priv->irq_enable_mask |= cur_irq->enable_mask;
dev_priv->irq_pending_mask |= cur_irq->pending_mask;
cur_irq++;
-
+
DRM_DEBUG("Initializing IRQ %d\n", i);
}
-
- dev_priv->last_vblank_valid = 0;
+
+ dev_priv->last_vblank_valid = 0;
// Clear VSync interrupt regs
status = VIA_READ(VIA_REG_INTERRUPT);
- VIA_WRITE(VIA_REG_INTERRUPT, status &
+ VIA_WRITE(VIA_REG_INTERRUPT, status &
~(dev_priv->irq_enable_mask));
-
+
/* Clear bits if they're already high */
viadrv_acknowledge_irqs(dev_priv);
}
@@ -262,7 +266,7 @@ void via_driver_irq_postinstall(drm_device_t * dev)
VIA_WRITE8(0x83d4, 0x11);
VIA_WRITE8(0x83d5, VIA_READ8(0x83d5) | 0x30);
-
+
}
}
@@ -280,7 +284,7 @@ void via_driver_irq_uninstall(drm_device_t * dev)
VIA_WRITE8(0x83d5, VIA_READ8(0x83d5) & ~0x30);
status = VIA_READ(VIA_REG_INTERRUPT);
- VIA_WRITE(VIA_REG_INTERRUPT, status &
+ VIA_WRITE(VIA_REG_INTERRUPT, status &
~(VIA_IRQ_VBLANK_ENABLE | dev_priv->irq_enable_mask));
}
}
@@ -302,7 +306,7 @@ int via_wait_irq(DRM_IOCTL_ARGS)
DRM_COPY_FROM_USER_IOCTL(irqwait, argp, sizeof(irqwait));
if (irqwait.request.irq >= dev_priv->num_irqs) {
- DRM_ERROR("%s Trying to wait on unknown irq %d\n", __FUNCTION__,
+ DRM_ERROR("%s Trying to wait on unknown irq %d\n", __FUNCTION__,
irqwait.request.irq);
return DRM_ERR(EINVAL);
}
@@ -320,7 +324,7 @@ int via_wait_irq(DRM_IOCTL_ARGS)
}
if (irqwait.request.type & VIA_IRQ_SIGNAL) {
- DRM_ERROR("%s Signals on Via IRQs not implemented yet.\n",
+ DRM_ERROR("%s Signals on Via IRQs not implemented yet.\n",
__FUNCTION__);
return DRM_ERR(EINVAL);
}
diff --git a/drivers/char/drm/via_map.c b/drivers/char/drm/via_map.c
index bb171139e737..6bd6ac52ad1b 100644
--- a/drivers/char/drm/via_map.c
+++ b/drivers/char/drm/via_map.c
@@ -66,7 +66,7 @@ static int via_do_init_map(drm_device_t * dev, drm_via_init_t * init)
dev_priv->agpAddr = init->agpAddr;
- via_init_futex( dev_priv );
+ via_init_futex(dev_priv);
dev_priv->pro_group_a = (dev->pdev->device == 0x3118);
dev->dev_private = (void *)dev_priv;
@@ -107,5 +107,3 @@ int via_map_init(DRM_IOCTL_ARGS)
return -EINVAL;
}
-
-
diff --git a/drivers/char/drm/via_mm.c b/drivers/char/drm/via_mm.c
index 13921f3c0ec2..3baddacdff26 100644
--- a/drivers/char/drm/via_mm.c
+++ b/drivers/char/drm/via_mm.c
@@ -81,7 +81,8 @@ int via_agp_init(DRM_IOCTL_ARGS)
AgpHeap = via_mmInit(agp.offset, agp.size);
- DRM_DEBUG("offset = %lu, size = %lu", (unsigned long)agp.offset, (unsigned long)agp.size);
+ DRM_DEBUG("offset = %lu, size = %lu", (unsigned long)agp.offset,
+ (unsigned long)agp.size);
return 0;
}
@@ -97,7 +98,8 @@ int via_fb_init(DRM_IOCTL_ARGS)
FBHeap = via_mmInit(fb.offset, fb.size);
- DRM_DEBUG("offset = %lu, size = %lu", (unsigned long)fb.offset, (unsigned long)fb.size);
+ DRM_DEBUG("offset = %lu, size = %lu", (unsigned long)fb.offset,
+ (unsigned long)fb.size);
return 0;
}
@@ -134,8 +136,8 @@ int via_init_context(struct drm_device *dev, int context)
}
int via_final_context(struct drm_device *dev, int context)
-{
- int i;
+{
+ int i;
drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private;
for (i = 0; i < MAX_CONTEXT; i++)
@@ -171,14 +173,13 @@ int via_final_context(struct drm_device *dev, int context)
via_setDestroy(set);
global_ppriv[i].used = 0;
}
- via_release_futex(dev_priv, context);
-
-
+ via_release_futex(dev_priv, context);
+
#if defined(__linux__)
/* Linux specific until context tracking code gets ported to BSD */
/* Last context, perform cleanup */
if (dev->ctx_count == 1 && dev->dev_private) {
- DRM_DEBUG("Last Context\n");
+ DRM_DEBUG("Last Context\n");
if (dev->irq)
drm_irq_uninstall(dev);
diff --git a/drivers/char/drm/via_verifier.c b/drivers/char/drm/via_verifier.c
index 07923b0c7a97..4ac495f297f7 100644
--- a/drivers/char/drm/via_verifier.c
+++ b/drivers/char/drm/via_verifier.c
@@ -28,7 +28,6 @@
* be very slow.
*/
-
#include "via_3d_reg.h"
#include "drmP.h"
#include "drm.h"
@@ -36,7 +35,7 @@
#include "via_verifier.h"
#include "via_drv.h"
-typedef enum{
+typedef enum {
state_command,
state_header2,
state_header1,
@@ -45,8 +44,7 @@ typedef enum{
state_error
} verifier_state_t;
-
-typedef enum{
+typedef enum {
no_check = 0,
check_for_header2,
check_for_header1,
@@ -74,16 +72,16 @@ typedef enum{
check_for_vertex_count,
check_number_texunits,
forbidden_command
-}hazard_t;
+} hazard_t;
/*
* Associates each hazard above with a possible multi-command
* sequence. For example an address that is split over multiple
- * commands and that needs to be checked at the first command
+ * commands and that needs to be checked at the first command
* that does not include any part of the address.
*/
-static drm_via_sequence_t seqs[] = {
+static drm_via_sequence_t seqs[] = {
no_sequence,
no_sequence,
no_sequence,
@@ -110,14 +108,12 @@ static drm_via_sequence_t seqs[] = {
tex_address,
no_sequence
};
-
-typedef struct{
+
+typedef struct {
unsigned int code;
hazard_t hz;
} hz_init_t;
-
-
static hz_init_t init_table1[] = {
{0xf2, check_for_header2_err},
{0xf0, check_for_header1_err},
@@ -169,8 +165,6 @@ static hz_init_t init_table1[] = {
{0x7D, check_for_vertex_count}
};
-
-
static hz_init_t init_table2[] = {
{0xf2, check_for_header2_err},
{0xf0, check_for_header1_err},
@@ -235,49 +229,49 @@ static hz_init_t init_table3[] = {
{0xcc, check_for_dummy},
{0x00, check_number_texunits}
};
-
-
-static hazard_t table1[256];
-static hazard_t table2[256];
-static hazard_t table3[256];
-
+static hazard_t table1[256];
+static hazard_t table2[256];
+static hazard_t table3[256];
static __inline__ int
-eat_words(const uint32_t **buf, const uint32_t *buf_end, unsigned num_words)
+eat_words(const uint32_t ** buf, const uint32_t * buf_end, unsigned num_words)
{
if ((*buf - buf_end) >= num_words) {
*buf += num_words;
return 0;
- }
+ }
DRM_ERROR("Illegal termination of DMA command buffer\n");
return 1;
}
-
/*
* Partially stolen from drm_memory.h
*/
-static __inline__ drm_map_t *
-via_drm_lookup_agp_map (drm_via_state_t *seq, unsigned long offset, unsigned long size,
- drm_device_t *dev)
+static __inline__ drm_map_t *via_drm_lookup_agp_map(drm_via_state_t * seq,
+ unsigned long offset,
+ unsigned long size,
+ drm_device_t * dev)
{
struct list_head *list;
drm_map_list_t *r_list;
drm_map_t *map = seq->map_cache;
- if (map && map->offset <= offset && (offset + size) <= (map->offset + map->size)) {
+ if (map && map->offset <= offset
+ && (offset + size) <= (map->offset + map->size)) {
return map;
}
-
+
list_for_each(list, &dev->maplist->head) {
r_list = (drm_map_list_t *) list;
map = r_list->map;
if (!map)
continue;
- if (map->offset <= offset && (offset + size) <= (map->offset + map->size) &&
- !(map->flags & _DRM_RESTRICTED) && (map->type == _DRM_AGP)) {
+ if (map->offset <= offset
+ && (offset + size) <= (map->offset + map->size)
+ && !(map->flags & _DRM_RESTRICTED)
+ && (map->type == _DRM_AGP)) {
seq->map_cache = map;
return map;
}
@@ -285,54 +279,60 @@ via_drm_lookup_agp_map (drm_via_state_t *seq, unsigned long offset, unsigned lon
return NULL;
}
-
/*
- * Require that all AGP texture levels reside in the same AGP map which should
+ * Require that all AGP texture levels reside in the same AGP map which should
* be mappable by the client. This is not a big restriction.
- * FIXME: To actually enforce this security policy strictly, drm_rmmap
- * would have to wait for dma quiescent before removing an AGP map.
+ * FIXME: To actually enforce this security policy strictly, drm_rmmap
+ * would have to wait for dma quiescent before removing an AGP map.
* The via_drm_lookup_agp_map call in reality seems to take
* very little CPU time.
*/
-
-static __inline__ int
-finish_current_sequence(drm_via_state_t *cur_seq)
+static __inline__ int finish_current_sequence(drm_via_state_t * cur_seq)
{
- switch(cur_seq->unfinished) {
+ switch (cur_seq->unfinished) {
case z_address:
DRM_DEBUG("Z Buffer start address is 0x%x\n", cur_seq->z_addr);
break;
case dest_address:
- DRM_DEBUG("Destination start address is 0x%x\n", cur_seq->d_addr);
+ DRM_DEBUG("Destination start address is 0x%x\n",
+ cur_seq->d_addr);
break;
case tex_address:
- if (cur_seq->agp_texture) {
- unsigned start = cur_seq->tex_level_lo[cur_seq->texture];
+ if (cur_seq->agp_texture) {
+ unsigned start =
+ cur_seq->tex_level_lo[cur_seq->texture];
unsigned end = cur_seq->tex_level_hi[cur_seq->texture];
- unsigned long lo=~0, hi=0, tmp;
+ unsigned long lo = ~0, hi = 0, tmp;
uint32_t *addr, *pitch, *height, tex;
unsigned i;
- if (end > 9) end = 9;
- if (start > 9) start = 9;
+ if (end > 9)
+ end = 9;
+ if (start > 9)
+ start = 9;
- addr =&(cur_seq->t_addr[tex = cur_seq->texture][start]);
+ addr =
+ &(cur_seq->t_addr[tex = cur_seq->texture][start]);
pitch = &(cur_seq->pitch[tex][start]);
height = &(cur_seq->height[tex][start]);
- for (i=start; i<= end; ++i) {
+ for (i = start; i <= end; ++i) {
tmp = *addr++;
- if (tmp < lo) lo = tmp;
+ if (tmp < lo)
+ lo = tmp;
tmp += (*height++ << *pitch++);
- if (tmp > hi) hi = tmp;
+ if (tmp > hi)
+ hi = tmp;
}
- if (! via_drm_lookup_agp_map (cur_seq, lo, hi - lo, cur_seq->dev)) {
- DRM_ERROR("AGP texture is not in allowed map\n");
+ if (!via_drm_lookup_agp_map
+ (cur_seq, lo, hi - lo, cur_seq->dev)) {
+ DRM_ERROR
+ ("AGP texture is not in allowed map\n");
return 2;
}
- }
+ }
break;
default:
break;
@@ -341,73 +341,84 @@ finish_current_sequence(drm_via_state_t *cur_seq)
return 0;
}
-static __inline__ int
-investigate_hazard( uint32_t cmd, hazard_t hz, drm_via_state_t *cur_seq)
+static __inline__ int
+investigate_hazard(uint32_t cmd, hazard_t hz, drm_via_state_t * cur_seq)
{
register uint32_t tmp, *tmp_addr;
if (cur_seq->unfinished && (cur_seq->unfinished != seqs[hz])) {
int ret;
- if ((ret = finish_current_sequence(cur_seq))) return ret;
+ if ((ret = finish_current_sequence(cur_seq)))
+ return ret;
}
- switch(hz) {
+ switch (hz) {
case check_for_header2:
- if (cmd == HALCYON_HEADER2) return 1;
+ if (cmd == HALCYON_HEADER2)
+ return 1;
return 0;
case check_for_header1:
- if ((cmd & HALCYON_HEADER1MASK) == HALCYON_HEADER1) return 1;
+ if ((cmd & HALCYON_HEADER1MASK) == HALCYON_HEADER1)
+ return 1;
return 0;
case check_for_header2_err:
- if (cmd == HALCYON_HEADER2) return 1;
+ if (cmd == HALCYON_HEADER2)
+ return 1;
DRM_ERROR("Illegal DMA HALCYON_HEADER2 command\n");
break;
case check_for_header1_err:
- if ((cmd & HALCYON_HEADER1MASK) == HALCYON_HEADER1) return 1;
+ if ((cmd & HALCYON_HEADER1MASK) == HALCYON_HEADER1)
+ return 1;
DRM_ERROR("Illegal DMA HALCYON_HEADER1 command\n");
break;
case check_for_fire:
- if ((cmd & HALCYON_FIREMASK) == HALCYON_FIRECMD) return 1;
+ if ((cmd & HALCYON_FIREMASK) == HALCYON_FIRECMD)
+ return 1;
DRM_ERROR("Illegal DMA HALCYON_FIRECMD command\n");
break;
case check_for_dummy:
- if (HC_DUMMY == cmd) return 0;
+ if (HC_DUMMY == cmd)
+ return 0;
DRM_ERROR("Illegal DMA HC_DUMMY command\n");
break;
case check_for_dd:
- if (0xdddddddd == cmd) return 0;
+ if (0xdddddddd == cmd)
+ return 0;
DRM_ERROR("Illegal DMA 0xdddddddd command\n");
break;
case check_z_buffer_addr0:
cur_seq->unfinished = z_address;
cur_seq->z_addr = (cur_seq->z_addr & 0xFF000000) |
- (cmd & 0x00FFFFFF);
+ (cmd & 0x00FFFFFF);
return 0;
case check_z_buffer_addr1:
cur_seq->unfinished = z_address;
cur_seq->z_addr = (cur_seq->z_addr & 0x00FFFFFF) |
- ((cmd & 0xFF) << 24);
+ ((cmd & 0xFF) << 24);
return 0;
case check_z_buffer_addr_mode:
cur_seq->unfinished = z_address;
- if ((cmd & 0x0000C000) == 0) return 0;
+ if ((cmd & 0x0000C000) == 0)
+ return 0;
DRM_ERROR("Attempt to place Z buffer in system memory\n");
return 2;
case check_destination_addr0:
cur_seq->unfinished = dest_address;
cur_seq->d_addr = (cur_seq->d_addr & 0xFF000000) |
- (cmd & 0x00FFFFFF);
+ (cmd & 0x00FFFFFF);
return 0;
case check_destination_addr1:
cur_seq->unfinished = dest_address;
cur_seq->d_addr = (cur_seq->d_addr & 0x00FFFFFF) |
- ((cmd & 0xFF) << 24);
+ ((cmd & 0xFF) << 24);
return 0;
case check_destination_addr_mode:
cur_seq->unfinished = dest_address;
- if ((cmd & 0x0000C000) == 0) return 0;
- DRM_ERROR("Attempt to place 3D drawing buffer in system memory\n");
- return 2;
+ if ((cmd & 0x0000C000) == 0)
+ return 0;
+ DRM_ERROR
+ ("Attempt to place 3D drawing buffer in system memory\n");
+ return 2;
case check_texture_addr0:
cur_seq->unfinished = tex_address;
tmp = (cmd >> 24);
@@ -433,9 +444,11 @@ investigate_hazard( uint32_t cmd, hazard_t hz, drm_via_state_t *cur_seq)
case check_texture_addr3:
cur_seq->unfinished = tex_address;
tmp = ((cmd >> 24) - 0x2B);
- cur_seq->pitch[cur_seq->texture][tmp] = (cmd & 0x00F00000) >> 20;
+ cur_seq->pitch[cur_seq->texture][tmp] =
+ (cmd & 0x00F00000) >> 20;
if (!tmp && (cmd & 0x000FFFFF)) {
- DRM_ERROR("Unimplemented texture level 0 pitch mode.\n");
+ DRM_ERROR
+ ("Unimplemented texture level 0 pitch mode.\n");
return 2;
}
return 0;
@@ -449,7 +462,7 @@ investigate_hazard( uint32_t cmd, hazard_t hz, drm_via_state_t *cur_seq)
cur_seq->unfinished = tex_address;
/*
* Texture width. We don't care since we have the pitch.
- */
+ */
return 0;
case check_texture_addr7:
cur_seq->unfinished = tex_address;
@@ -465,25 +478,26 @@ investigate_hazard( uint32_t cmd, hazard_t hz, drm_via_state_t *cur_seq)
cur_seq->unfinished = tex_address;
tmp_addr = &(cur_seq->height[cur_seq->texture][0]);
tmp_addr[9] = 1 << ((cmd & 0x0000F000) >> 12);
- tmp_addr[8] = 1 << ((cmd & 0x00000F00) >> 8);
+ tmp_addr[8] = 1 << ((cmd & 0x00000F00) >> 8);
tmp_addr[7] = 1 << ((cmd & 0x000000F0) >> 4);
tmp_addr[6] = 1 << (cmd & 0x0000000F);
return 0;
case check_texture_addr_mode:
cur_seq->unfinished = tex_address;
- if ( 2 == (tmp = cmd & 0x00000003)) {
- DRM_ERROR("Attempt to fetch texture from system memory.\n");
+ if (2 == (tmp = cmd & 0x00000003)) {
+ DRM_ERROR
+ ("Attempt to fetch texture from system memory.\n");
return 2;
}
cur_seq->agp_texture = (tmp == 3);
- cur_seq->tex_palette_size[cur_seq->texture] =
- (cmd >> 16) & 0x000000007;
+ cur_seq->tex_palette_size[cur_seq->texture] =
+ (cmd >> 16) & 0x000000007;
return 0;
case check_for_vertex_count:
cur_seq->vertex_count = cmd & 0x0000FFFF;
return 0;
case check_number_texunits:
- cur_seq->multitex = (cmd >> 3) & 1;
+ cur_seq->multitex = (cmd >> 3) & 1;
return 0;
default:
DRM_ERROR("Illegal DMA data: 0x%x\n", cmd);
@@ -492,25 +506,27 @@ investigate_hazard( uint32_t cmd, hazard_t hz, drm_via_state_t *cur_seq)
return 2;
}
-
static __inline__ int
-via_check_prim_list(uint32_t const **buffer, const uint32_t *buf_end,
- drm_via_state_t *cur_seq)
+via_check_prim_list(uint32_t const **buffer, const uint32_t * buf_end,
+ drm_via_state_t * cur_seq)
{
- drm_via_private_t *dev_priv = (drm_via_private_t *) cur_seq->dev->dev_private;
- uint32_t a_fire, bcmd , dw_count;
+ drm_via_private_t *dev_priv =
+ (drm_via_private_t *) cur_seq->dev->dev_private;
+ uint32_t a_fire, bcmd, dw_count;
int ret = 0;
int have_fire;
const uint32_t *buf = *buffer;
- while(buf < buf_end) {
- have_fire = 0;
+ while (buf < buf_end) {
+ have_fire = 0;
if ((buf_end - buf) < 2) {
- DRM_ERROR("Unexpected termination of primitive list.\n");
+ DRM_ERROR
+ ("Unexpected termination of primitive list.\n");
ret = 1;
break;
}
- if ((*buf & HC_ACMD_MASK) != HC_ACMD_HCmdB) break;
+ if ((*buf & HC_ACMD_MASK) != HC_ACMD_HCmdB)
+ break;
bcmd = *buf++;
if ((*buf & HC_ACMD_MASK) != HC_ACMD_HCmdA) {
DRM_ERROR("Expected Vertex List A command, got 0x%x\n",
@@ -518,43 +534,56 @@ via_check_prim_list(uint32_t const **buffer, const uint32_t *buf_end,
ret = 1;
break;
}
- a_fire = *buf++ | HC_HPLEND_MASK | HC_HPMValidN_MASK | HC_HE3Fire_MASK;
-
+ a_fire =
+ *buf++ | HC_HPLEND_MASK | HC_HPMValidN_MASK |
+ HC_HE3Fire_MASK;
+
/*
* How many dwords per vertex ?
- */
-
+ */
+
if (cur_seq->agp && ((bcmd & (0xF << 11)) == 0)) {
DRM_ERROR("Illegal B command vertex data for AGP.\n");
ret = 1;
break;
- }
+ }
dw_count = 0;
- if (bcmd & (1 << 7)) dw_count += (cur_seq->multitex) ? 2:1;
- if (bcmd & (1 << 8)) dw_count += (cur_seq->multitex) ? 2:1;
- if (bcmd & (1 << 9)) dw_count++;
- if (bcmd & (1 << 10)) dw_count++;
- if (bcmd & (1 << 11)) dw_count++;
- if (bcmd & (1 << 12)) dw_count++;
- if (bcmd & (1 << 13)) dw_count++;
- if (bcmd & (1 << 14)) dw_count++;
-
- while(buf < buf_end) {
+ if (bcmd & (1 << 7))
+ dw_count += (cur_seq->multitex) ? 2 : 1;
+ if (bcmd & (1 << 8))
+ dw_count += (cur_seq->multitex) ? 2 : 1;
+ if (bcmd & (1 << 9))
+ dw_count++;
+ if (bcmd & (1 << 10))
+ dw_count++;
+ if (bcmd & (1 << 11))
+ dw_count++;
+ if (bcmd & (1 << 12))
+ dw_count++;
+ if (bcmd & (1 << 13))
+ dw_count++;
+ if (bcmd & (1 << 14))
+ dw_count++;
+
+ while (buf < buf_end) {
if (*buf == a_fire) {
- if (dev_priv->num_fire_offsets >= VIA_FIRE_BUF_SIZE) {
+ if (dev_priv->num_fire_offsets >=
+ VIA_FIRE_BUF_SIZE) {
DRM_ERROR("Fire offset buffer full.\n");
ret = 1;
break;
}
- dev_priv->fire_offsets[dev_priv->num_fire_offsets++] = buf;
- have_fire = 1;
+ dev_priv->fire_offsets[dev_priv->
+ num_fire_offsets++] =
+ buf;
+ have_fire = 1;
buf++;
- if (buf < buf_end && *buf == a_fire)
+ if (buf < buf_end && *buf == a_fire)
buf++;
break;
}
- if ((*buf == HALCYON_HEADER2) ||
+ if ((*buf == HALCYON_HEADER2) ||
((*buf & HALCYON_FIREMASK) == HALCYON_FIRECMD)) {
DRM_ERROR("Missing Vertex Fire command, "
"Stray Vertex Fire command or verifier "
@@ -576,18 +605,14 @@ via_check_prim_list(uint32_t const **buffer, const uint32_t *buf_end,
ret = 1;
break;
}
- }
+ }
*buffer = buf;
return ret;
}
-
-
-
-
static __inline__ verifier_state_t
-via_check_header2( uint32_t const **buffer, const uint32_t *buf_end,
- drm_via_state_t *hc_state)
+via_check_header2(uint32_t const **buffer, const uint32_t * buf_end,
+ drm_via_state_t * hc_state)
{
uint32_t cmd;
int hz_mode;
@@ -595,17 +620,17 @@ via_check_header2( uint32_t const **buffer, const uint32_t *buf_end,
const uint32_t *buf = *buffer;
const hazard_t *hz_table;
-
if ((buf_end - buf) < 2) {
- DRM_ERROR("Illegal termination of DMA HALCYON_HEADER2 sequence.\n");
+ DRM_ERROR
+ ("Illegal termination of DMA HALCYON_HEADER2 sequence.\n");
return state_error;
}
buf++;
cmd = (*buf++ & 0xFFFF0000) >> 16;
- switch(cmd) {
+ switch (cmd) {
case HC_ParaType_CmdVdata:
- if (via_check_prim_list(&buf, buf_end, hc_state ))
+ if (via_check_prim_list(&buf, buf_end, hc_state))
return state_error;
*buffer = buf;
return state_command;
@@ -650,13 +675,13 @@ via_check_header2( uint32_t const **buffer, const uint32_t *buf_end,
*/
DRM_ERROR("Invalid or unimplemented HALCYON_HEADER2 "
- "DMA subcommand: 0x%x. Previous dword: 0x%x\n",
- cmd, *(buf -2));
+ "DMA subcommand: 0x%x. Previous dword: 0x%x\n",
+ cmd, *(buf - 2));
*buffer = buf;
return state_error;
}
- while(buf < buf_end) {
+ while (buf < buf_end) {
cmd = *buf++;
if ((hz = hz_table[cmd >> 24])) {
if ((hz_mode = investigate_hazard(cmd, hz, hc_state))) {
@@ -666,7 +691,7 @@ via_check_header2( uint32_t const **buffer, const uint32_t *buf_end,
}
return state_error;
}
- } else if (hc_state->unfinished &&
+ } else if (hc_state->unfinished &&
finish_current_sequence(hc_state)) {
return state_error;
}
@@ -679,64 +704,65 @@ via_check_header2( uint32_t const **buffer, const uint32_t *buf_end,
}
static __inline__ verifier_state_t
-via_parse_header2( drm_via_private_t *dev_priv, uint32_t const **buffer, const uint32_t *buf_end,
- int *fire_count)
+via_parse_header2(drm_via_private_t * dev_priv, uint32_t const **buffer,
+ const uint32_t * buf_end, int *fire_count)
{
uint32_t cmd;
const uint32_t *buf = *buffer;
- const uint32_t *next_fire;
+ const uint32_t *next_fire;
int burst = 0;
next_fire = dev_priv->fire_offsets[*fire_count];
buf++;
cmd = (*buf & 0xFFFF0000) >> 16;
VIA_WRITE(HC_REG_TRANS_SET + HC_REG_BASE, *buf++);
- switch(cmd) {
+ switch (cmd) {
case HC_ParaType_CmdVdata:
while ((buf < buf_end) &&
- (*fire_count < dev_priv->num_fire_offsets) &&
- (*buf & HC_ACMD_MASK) == HC_ACMD_HCmdB ) {
- while(buf <= next_fire) {
- VIA_WRITE(HC_REG_TRANS_SPACE + HC_REG_BASE + (burst & 63), *buf++);
+ (*fire_count < dev_priv->num_fire_offsets) &&
+ (*buf & HC_ACMD_MASK) == HC_ACMD_HCmdB) {
+ while (buf <= next_fire) {
+ VIA_WRITE(HC_REG_TRANS_SPACE + HC_REG_BASE +
+ (burst & 63), *buf++);
burst += 4;
}
- if ( ( buf < buf_end ) && ((*buf & HALCYON_FIREMASK) == HALCYON_FIRECMD))
+ if ((buf < buf_end)
+ && ((*buf & HALCYON_FIREMASK) == HALCYON_FIRECMD))
buf++;
- if (++(*fire_count) < dev_priv->num_fire_offsets)
+ if (++(*fire_count) < dev_priv->num_fire_offsets)
next_fire = dev_priv->fire_offsets[*fire_count];
}
break;
default:
- while(buf < buf_end) {
-
- if ( *buf == HC_HEADER2 ||
- (*buf & HALCYON_HEADER1MASK) == HALCYON_HEADER1 ||
- (*buf & VIA_VIDEOMASK) == VIA_VIDEO_HEADER5 ||
- (*buf & VIA_VIDEOMASK) == VIA_VIDEO_HEADER6 ) break;
-
- VIA_WRITE(HC_REG_TRANS_SPACE + HC_REG_BASE + (burst & 63), *buf++);
- burst +=4;
+ while (buf < buf_end) {
+
+ if (*buf == HC_HEADER2 ||
+ (*buf & HALCYON_HEADER1MASK) == HALCYON_HEADER1 ||
+ (*buf & VIA_VIDEOMASK) == VIA_VIDEO_HEADER5 ||
+ (*buf & VIA_VIDEOMASK) == VIA_VIDEO_HEADER6)
+ break;
+
+ VIA_WRITE(HC_REG_TRANS_SPACE + HC_REG_BASE +
+ (burst & 63), *buf++);
+ burst += 4;
}
}
*buffer = buf;
return state_command;
}
-
-
-static __inline__ int
-verify_mmio_address( uint32_t address)
+static __inline__ int verify_mmio_address(uint32_t address)
{
- if ((address > 0x3FF) && (address < 0xC00 )) {
+ if ((address > 0x3FF) && (address < 0xC00)) {
DRM_ERROR("Invalid VIDEO DMA command. "
"Attempt to access 3D- or command burst area.\n");
return 1;
} else if ((address > 0xCFF) && (address < 0x1300)) {
DRM_ERROR("Invalid VIDEO DMA command. "
"Attempt to access PCI DMA area.\n");
- return 1;
- } else if (address > 0x13FF ) {
+ return 1;
+ } else if (address > 0x13FF) {
DRM_ERROR("Invalid VIDEO DMA command. "
"Attempt to access VGA registers.\n");
return 1;
@@ -745,7 +771,8 @@ verify_mmio_address( uint32_t address)
}
static __inline__ int
-verify_video_tail( uint32_t const **buffer, const uint32_t *buf_end, uint32_t dwords)
+verify_video_tail(uint32_t const **buffer, const uint32_t * buf_end,
+ uint32_t dwords)
{
const uint32_t *buf = *buffer;
@@ -762,10 +789,9 @@ verify_video_tail( uint32_t const **buffer, const uint32_t *buf_end, uint32_t dw
*buffer = buf;
return 0;
}
-
static __inline__ verifier_state_t
-via_check_header1( uint32_t const **buffer, const uint32_t *buf_end )
+via_check_header1(uint32_t const **buffer, const uint32_t * buf_end)
{
uint32_t cmd;
const uint32_t *buf = *buffer;
@@ -774,21 +800,21 @@ via_check_header1( uint32_t const **buffer, const uint32_t *buf_end )
while (buf < buf_end) {
cmd = *buf;
if ((cmd > ((0x3FF >> 2) | HALCYON_HEADER1)) &&
- (cmd < ((0xC00 >> 2) | HALCYON_HEADER1))) {
- if ((cmd & HALCYON_HEADER1MASK) != HALCYON_HEADER1)
+ (cmd < ((0xC00 >> 2) | HALCYON_HEADER1))) {
+ if ((cmd & HALCYON_HEADER1MASK) != HALCYON_HEADER1)
break;
DRM_ERROR("Invalid HALCYON_HEADER1 command. "
"Attempt to access 3D- or command burst area.\n");
ret = state_error;
break;
} else if (cmd > ((0xCFF >> 2) | HALCYON_HEADER1)) {
- if ((cmd & HALCYON_HEADER1MASK) != HALCYON_HEADER1)
+ if ((cmd & HALCYON_HEADER1MASK) != HALCYON_HEADER1)
break;
DRM_ERROR("Invalid HALCYON_HEADER1 command. "
"Attempt to access VGA registers.\n");
ret = state_error;
- break;
- } else {
+ break;
+ } else {
buf += 2;
}
}
@@ -797,15 +823,17 @@ via_check_header1( uint32_t const **buffer, const uint32_t *buf_end )
}
static __inline__ verifier_state_t
-via_parse_header1( drm_via_private_t *dev_priv, uint32_t const **buffer, const uint32_t *buf_end )
+via_parse_header1(drm_via_private_t * dev_priv, uint32_t const **buffer,
+ const uint32_t * buf_end)
{
register uint32_t cmd;
const uint32_t *buf = *buffer;
while (buf < buf_end) {
cmd = *buf;
- if ((cmd & HALCYON_HEADER1MASK) != HALCYON_HEADER1) break;
- VIA_WRITE( (cmd & ~HALCYON_HEADER1MASK) << 2, *++buf);
+ if ((cmd & HALCYON_HEADER1MASK) != HALCYON_HEADER1)
+ break;
+ VIA_WRITE((cmd & ~HALCYON_HEADER1MASK) << 2, *++buf);
buf++;
}
*buffer = buf;
@@ -813,7 +841,7 @@ via_parse_header1( drm_via_private_t *dev_priv, uint32_t const **buffer, const u
}
static __inline__ verifier_state_t
-via_check_vheader5( uint32_t const **buffer, const uint32_t *buf_end )
+via_check_vheader5(uint32_t const **buffer, const uint32_t * buf_end)
{
uint32_t data;
const uint32_t *buf = *buffer;
@@ -836,41 +864,41 @@ via_check_vheader5( uint32_t const **buffer, const uint32_t *buf_end )
DRM_ERROR("Illegal header5 header data\n");
return state_error;
}
- if (eat_words(&buf, buf_end, data))
+ if (eat_words(&buf, buf_end, data))
return state_error;
- if ((data & 3) && verify_video_tail(&buf, buf_end, 4 - (data & 3)))
+ if ((data & 3) && verify_video_tail(&buf, buf_end, 4 - (data & 3)))
return state_error;
*buffer = buf;
return state_command;
-
-}
+
+}
static __inline__ verifier_state_t
-via_parse_vheader5( drm_via_private_t *dev_priv, uint32_t const **buffer, const uint32_t *buf_end )
+via_parse_vheader5(drm_via_private_t * dev_priv, uint32_t const **buffer,
+ const uint32_t * buf_end)
{
- uint32_t addr, count, i;
+ uint32_t addr, count, i;
const uint32_t *buf = *buffer;
-
+
addr = *buf++ & ~VIA_VIDEOMASK;
i = count = *buf;
buf += 3;
- while(i--) {
+ while (i--) {
VIA_WRITE(addr, *buf++);
}
- if (count & 3) buf += 4 - (count & 3);
+ if (count & 3)
+ buf += 4 - (count & 3);
*buffer = buf;
- return state_command;
-}
-
+ return state_command;
+}
static __inline__ verifier_state_t
-via_check_vheader6( uint32_t const **buffer, const uint32_t *buf_end )
+via_check_vheader6(uint32_t const **buffer, const uint32_t * buf_end)
{
uint32_t data;
const uint32_t *buf = *buffer;
uint32_t i;
-
if (buf_end - buf < 4) {
DRM_ERROR("Illegal termination of video header6 command\n");
return state_error;
@@ -889,7 +917,7 @@ via_check_vheader6( uint32_t const **buffer, const uint32_t *buf_end )
DRM_ERROR("Illegal termination of video header6 command\n");
return state_error;
}
- for (i=0; i<data; ++i) {
+ for (i = 0; i < data; ++i) {
if (verify_mmio_address(*buf++))
return state_error;
buf++;
@@ -899,42 +927,42 @@ via_check_vheader6( uint32_t const **buffer, const uint32_t *buf_end )
return state_error;
*buffer = buf;
return state_command;
-}
+}
static __inline__ verifier_state_t
-via_parse_vheader6( drm_via_private_t *dev_priv, uint32_t const **buffer, const uint32_t *buf_end )
+via_parse_vheader6(drm_via_private_t * dev_priv, uint32_t const **buffer,
+ const uint32_t * buf_end)
{
- uint32_t addr, count, i;
+ uint32_t addr, count, i;
const uint32_t *buf = *buffer;
i = count = *++buf;
buf += 3;
- while(i--) {
+ while (i--) {
addr = *buf++;
VIA_WRITE(addr, *buf++);
}
count <<= 1;
- if (count & 3) buf += 4 - (count & 3);
+ if (count & 3)
+ buf += 4 - (count & 3);
*buffer = buf;
return state_command;
-}
-
-
+}
-int
-via_verify_command_stream(const uint32_t * buf, unsigned int size, drm_device_t *dev,
- int agp)
+int
+via_verify_command_stream(const uint32_t * buf, unsigned int size,
+ drm_device_t * dev, int agp)
{
drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private;
drm_via_state_t *hc_state = &dev_priv->hc_state;
drm_via_state_t saved_state = *hc_state;
uint32_t cmd;
- const uint32_t *buf_end = buf + ( size >> 2 );
+ const uint32_t *buf_end = buf + (size >> 2);
verifier_state_t state = state_command;
int pro_group_a = dev_priv->pro_group_a;
-
+
hc_state->dev = dev;
hc_state->unfinished = no_sequence;
hc_state->map_cache = NULL;
@@ -946,38 +974,41 @@ via_verify_command_stream(const uint32_t * buf, unsigned int size, drm_device_t
switch (state) {
case state_header2:
- state = via_check_header2( &buf, buf_end, hc_state );
+ state = via_check_header2(&buf, buf_end, hc_state);
break;
case state_header1:
- state = via_check_header1( &buf, buf_end );
+ state = via_check_header1(&buf, buf_end);
break;
case state_vheader5:
- state = via_check_vheader5( &buf, buf_end );
+ state = via_check_vheader5(&buf, buf_end);
break;
case state_vheader6:
- state = via_check_vheader6( &buf, buf_end );
+ state = via_check_vheader6(&buf, buf_end);
break;
case state_command:
- if (HALCYON_HEADER2 == (cmd = *buf))
+ if (HALCYON_HEADER2 == (cmd = *buf))
state = state_header2;
- else if ((cmd & HALCYON_HEADER1MASK) == HALCYON_HEADER1)
+ else if ((cmd & HALCYON_HEADER1MASK) == HALCYON_HEADER1)
state = state_header1;
- else if (pro_group_a && (cmd & VIA_VIDEOMASK) == VIA_VIDEO_HEADER5)
+ else if (pro_group_a
+ && (cmd & VIA_VIDEOMASK) == VIA_VIDEO_HEADER5)
state = state_vheader5;
- else if (pro_group_a && (cmd & VIA_VIDEOMASK) == VIA_VIDEO_HEADER6)
+ else if (pro_group_a
+ && (cmd & VIA_VIDEOMASK) == VIA_VIDEO_HEADER6)
state = state_vheader6;
else {
- DRM_ERROR("Invalid / Unimplemented DMA HEADER command. 0x%x\n",
- cmd);
+ DRM_ERROR
+ ("Invalid / Unimplemented DMA HEADER command. 0x%x\n",
+ cmd);
state = state_error;
}
break;
case state_error:
default:
*hc_state = saved_state;
- return DRM_ERR(EINVAL);
+ return DRM_ERR(EINVAL);
}
- }
+ }
if (state == state_error) {
*hc_state = saved_state;
return DRM_ERR(EINVAL);
@@ -985,77 +1016,81 @@ via_verify_command_stream(const uint32_t * buf, unsigned int size, drm_device_t
return 0;
}
-int
-via_parse_command_stream(drm_device_t *dev, const uint32_t * buf, unsigned int size)
+int
+via_parse_command_stream(drm_device_t * dev, const uint32_t * buf,
+ unsigned int size)
{
drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private;
uint32_t cmd;
- const uint32_t *buf_end = buf + ( size >> 2 );
+ const uint32_t *buf_end = buf + (size >> 2);
verifier_state_t state = state_command;
int fire_count = 0;
-
+
while (buf < buf_end) {
switch (state) {
case state_header2:
- state = via_parse_header2( dev_priv, &buf, buf_end, &fire_count );
+ state =
+ via_parse_header2(dev_priv, &buf, buf_end,
+ &fire_count);
break;
case state_header1:
- state = via_parse_header1( dev_priv, &buf, buf_end );
+ state = via_parse_header1(dev_priv, &buf, buf_end);
break;
case state_vheader5:
- state = via_parse_vheader5( dev_priv, &buf, buf_end );
+ state = via_parse_vheader5(dev_priv, &buf, buf_end);
break;
case state_vheader6:
- state = via_parse_vheader6( dev_priv, &buf, buf_end );
+ state = via_parse_vheader6(dev_priv, &buf, buf_end);
break;
case state_command:
- if (HALCYON_HEADER2 == (cmd = *buf))
+ if (HALCYON_HEADER2 == (cmd = *buf))
state = state_header2;
- else if ((cmd & HALCYON_HEADER1MASK) == HALCYON_HEADER1)
+ else if ((cmd & HALCYON_HEADER1MASK) == HALCYON_HEADER1)
state = state_header1;
else if ((cmd & VIA_VIDEOMASK) == VIA_VIDEO_HEADER5)
state = state_vheader5;
else if ((cmd & VIA_VIDEOMASK) == VIA_VIDEO_HEADER6)
state = state_vheader6;
else {
- DRM_ERROR("Invalid / Unimplemented DMA HEADER command. 0x%x\n",
- cmd);
+ DRM_ERROR
+ ("Invalid / Unimplemented DMA HEADER command. 0x%x\n",
+ cmd);
state = state_error;
}
break;
case state_error:
default:
- return DRM_ERR(EINVAL);
+ return DRM_ERR(EINVAL);
}
- }
+ }
if (state == state_error) {
return DRM_ERR(EINVAL);
}
return 0;
}
-
-
-static void
+static void
setup_hazard_table(hz_init_t init_table[], hazard_t table[], int size)
{
int i;
- for(i=0; i<256; ++i) {
+ for (i = 0; i < 256; ++i) {
table[i] = forbidden_command;
}
- for(i=0; i<size; ++i) {
+ for (i = 0; i < size; ++i) {
table[init_table[i].code] = init_table[i].hz;
}
}
-void
-via_init_command_verifier( void )
+void via_init_command_verifier(void)
{
- setup_hazard_table(init_table1, table1, sizeof(init_table1) / sizeof(hz_init_t));
- setup_hazard_table(init_table2, table2, sizeof(init_table2) / sizeof(hz_init_t));
- setup_hazard_table(init_table3, table3, sizeof(init_table3) / sizeof(hz_init_t));
+ setup_hazard_table(init_table1, table1,
+ sizeof(init_table1) / sizeof(hz_init_t));
+ setup_hazard_table(init_table2, table2,
+ sizeof(init_table2) / sizeof(hz_init_t));
+ setup_hazard_table(init_table3, table3,
+ sizeof(init_table3) / sizeof(hz_init_t));
}
diff --git a/drivers/char/drm/via_verifier.h b/drivers/char/drm/via_verifier.h
index a8e13592620f..eb4eda344345 100644
--- a/drivers/char/drm/via_verifier.h
+++ b/drivers/char/drm/via_verifier.h
@@ -26,23 +26,21 @@
#ifndef _VIA_VERIFIER_H_
#define _VIA_VERIFIER_H_
-typedef enum{
- no_sequence = 0,
+typedef enum {
+ no_sequence = 0,
z_address,
dest_address,
tex_address
-}drm_via_sequence_t;
+} drm_via_sequence_t;
-
-
-typedef struct{
+typedef struct {
unsigned texture;
- uint32_t z_addr;
- uint32_t d_addr;
- uint32_t t_addr[2][10];
+ uint32_t z_addr;
+ uint32_t d_addr;
+ uint32_t t_addr[2][10];
uint32_t pitch[2][10];
uint32_t height[2][10];
- uint32_t tex_level_lo[2];
+ uint32_t tex_level_lo[2];
uint32_t tex_level_hi[2];
uint32_t tex_palette_size[2];
drm_via_sequence_t unfinished;
@@ -55,7 +53,7 @@ typedef struct{
const uint32_t *buf_start;
} drm_via_state_t;
-extern int via_verify_command_stream(const uint32_t * buf, unsigned int size,
- drm_device_t *dev, int agp);
+extern int via_verify_command_stream(const uint32_t * buf, unsigned int size,
+ drm_device_t * dev, int agp);
#endif
diff --git a/drivers/char/drm/via_video.c b/drivers/char/drm/via_video.c
index 1e2d444587bf..7fab9fbdf424 100644
--- a/drivers/char/drm/via_video.c
+++ b/drivers/char/drm/via_video.c
@@ -29,8 +29,7 @@
#include "via_drm.h"
#include "via_drv.h"
-void
-via_init_futex(drm_via_private_t *dev_priv)
+void via_init_futex(drm_via_private_t * dev_priv)
{
unsigned int i;
@@ -42,30 +41,28 @@ via_init_futex(drm_via_private_t *dev_priv)
}
}
-void
-via_cleanup_futex(drm_via_private_t *dev_priv)
+void via_cleanup_futex(drm_via_private_t * dev_priv)
{
-}
+}
-void
-via_release_futex(drm_via_private_t *dev_priv, int context)
+void via_release_futex(drm_via_private_t * dev_priv, int context)
{
unsigned int i;
volatile int *lock;
- for (i=0; i < VIA_NR_XVMC_LOCKS; ++i) {
- lock = (int *) XVMCLOCKPTR(dev_priv->sarea_priv, i);
- if ( (_DRM_LOCKING_CONTEXT( *lock ) == context)) {
- if (_DRM_LOCK_IS_HELD( *lock ) && (*lock & _DRM_LOCK_CONT)) {
- DRM_WAKEUP( &(dev_priv->decoder_queue[i]));
+ for (i = 0; i < VIA_NR_XVMC_LOCKS; ++i) {
+ lock = (int *)XVMCLOCKPTR(dev_priv->sarea_priv, i);
+ if ((_DRM_LOCKING_CONTEXT(*lock) == context)) {
+ if (_DRM_LOCK_IS_HELD(*lock)
+ && (*lock & _DRM_LOCK_CONT)) {
+ DRM_WAKEUP(&(dev_priv->decoder_queue[i]));
}
*lock = 0;
}
- }
-}
+ }
+}
-int
-via_decoder_futex(DRM_IOCTL_ARGS)
+int via_decoder_futex(DRM_IOCTL_ARGS)
{
DRM_DEVICE;
drm_via_futex_t fx;
@@ -95,4 +92,3 @@ via_decoder_futex(DRM_IOCTL_ARGS)
}
return 0;
}
-
diff --git a/drivers/char/dsp56k.c b/drivers/char/dsp56k.c
index 26271e3ca823..8693835cb2d5 100644
--- a/drivers/char/dsp56k.c
+++ b/drivers/char/dsp56k.c
@@ -515,7 +515,7 @@ static int __init dsp56k_init_driver(void)
err = PTR_ERR(dsp56k_class);
goto out_chrdev;
}
- class_device_create(dsp56k_class, MKDEV(DSP56K_MAJOR, 0), NULL, "dsp56k");
+ class_device_create(dsp56k_class, NULL, MKDEV(DSP56K_MAJOR, 0), NULL, "dsp56k");
err = devfs_mk_cdev(MKDEV(DSP56K_MAJOR, 0),
S_IFCHR | S_IRUSR | S_IWUSR, "dsp56k");
diff --git a/drivers/char/ftape/zftape/zftape-init.c b/drivers/char/ftape/zftape/zftape-init.c
index 5745b74044ec..821357ce7e0e 100644
--- a/drivers/char/ftape/zftape/zftape-init.c
+++ b/drivers/char/ftape/zftape/zftape-init.c
@@ -331,27 +331,27 @@ KERN_INFO
zft_class = class_create(THIS_MODULE, "zft");
for (i = 0; i < 4; i++) {
- class_device_create(zft_class, MKDEV(QIC117_TAPE_MAJOR, i), NULL, "qft%i", i);
+ class_device_create(zft_class, NULL, MKDEV(QIC117_TAPE_MAJOR, i), NULL, "qft%i", i);
devfs_mk_cdev(MKDEV(QIC117_TAPE_MAJOR, i),
S_IFCHR | S_IRUSR | S_IWUSR,
"qft%i", i);
- class_device_create(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 4), NULL, "nqft%i", i);
+ class_device_create(zft_class, NULL, MKDEV(QIC117_TAPE_MAJOR, i + 4), NULL, "nqft%i", i);
devfs_mk_cdev(MKDEV(QIC117_TAPE_MAJOR, i + 4),
S_IFCHR | S_IRUSR | S_IWUSR,
"nqft%i", i);
- class_device_create(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 16), NULL, "zqft%i", i);
+ class_device_create(zft_class, NULL, MKDEV(QIC117_TAPE_MAJOR, i + 16), NULL, "zqft%i", i);
devfs_mk_cdev(MKDEV(QIC117_TAPE_MAJOR, i + 16),
S_IFCHR | S_IRUSR | S_IWUSR,
"zqft%i", i);
- class_device_create(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 20), NULL, "nzqft%i", i);
+ class_device_create(zft_class, NULL, MKDEV(QIC117_TAPE_MAJOR, i + 20), NULL, "nzqft%i", i);
devfs_mk_cdev(MKDEV(QIC117_TAPE_MAJOR, i + 20),
S_IFCHR | S_IRUSR | S_IWUSR,
"nzqft%i", i);
- class_device_create(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 32), NULL, "rawqft%i", i);
+ class_device_create(zft_class, NULL, MKDEV(QIC117_TAPE_MAJOR, i + 32), NULL, "rawqft%i", i);
devfs_mk_cdev(MKDEV(QIC117_TAPE_MAJOR, i + 32),
S_IFCHR | S_IRUSR | S_IWUSR,
"rawqft%i", i);
- class_device_create(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 36), NULL, "nrawrawqft%i", i);
+ class_device_create(zft_class, NULL, MKDEV(QIC117_TAPE_MAJOR, i + 36), NULL, "nrawrawqft%i", i);
devfs_mk_cdev(MKDEV(QIC117_TAPE_MAJOR, i + 36),
S_IFCHR | S_IRUSR | S_IWUSR,
"nrawqft%i", i);
diff --git a/drivers/char/hangcheck-timer.c b/drivers/char/hangcheck-timer.c
index a54bc93353af..66e53dd450ff 100644
--- a/drivers/char/hangcheck-timer.c
+++ b/drivers/char/hangcheck-timer.c
@@ -117,7 +117,7 @@ __setup("hcheck_reboot", hangcheck_parse_reboot);
__setup("hcheck_dump_tasks", hangcheck_parse_dump_tasks);
#endif /* not MODULE */
-#if defined(CONFIG_X86) || defined(CONFIG_X86_64)
+#if defined(CONFIG_X86)
# define HAVE_MONOTONIC
# define TIMER_FREQ 1000000000ULL
#elif defined(CONFIG_ARCH_S390)
diff --git a/drivers/char/hpet.c b/drivers/char/hpet.c
index c055bb630ffc..3808d9572619 100644
--- a/drivers/char/hpet.c
+++ b/drivers/char/hpet.c
@@ -49,7 +49,9 @@
#define HPET_USER_FREQ (64)
#define HPET_DRIFT (500)
-static u32 hpet_ntimer, hpet_nhpet, hpet_max_freq = HPET_USER_FREQ;
+#define HPET_RANGE_SIZE 1024 /* from HPET spec */
+
+static u32 hpet_nhpet, hpet_max_freq = HPET_USER_FREQ;
/* A lock for concurrent access by app and isr hpet activity. */
static DEFINE_SPINLOCK(hpet_lock);
@@ -78,7 +80,7 @@ struct hpets {
struct hpet __iomem *hp_hpet;
unsigned long hp_hpet_phys;
struct time_interpolator *hp_interpolator;
- unsigned long hp_period;
+ unsigned long long hp_tick_freq;
unsigned long hp_delta;
unsigned int hp_ntimer;
unsigned int hp_which;
@@ -90,6 +92,7 @@ static struct hpets *hpets;
#define HPET_OPEN 0x0001
#define HPET_IE 0x0002 /* interrupt enabled */
#define HPET_PERIODIC 0x0004
+#define HPET_SHARED_IRQ 0x0008
#if BITS_PER_LONG == 64
#define write_counter(V, MC) writeq(V, MC)
@@ -120,6 +123,11 @@ static irqreturn_t hpet_interrupt(int irq, void *data, struct pt_regs *regs)
unsigned long isr;
devp = data;
+ isr = 1 << (devp - devp->hd_hpets->hp_dev);
+
+ if ((devp->hd_flags & HPET_SHARED_IRQ) &&
+ !(isr & readl(&devp->hd_hpet->hpet_isr)))
+ return IRQ_NONE;
spin_lock(&hpet_lock);
devp->hd_irqdata++;
@@ -137,8 +145,8 @@ static irqreturn_t hpet_interrupt(int irq, void *data, struct pt_regs *regs)
&devp->hd_timer->hpet_compare);
}
- isr = (1 << (devp - devp->hd_hpets->hp_dev));
- writeq(isr, &devp->hd_hpet->hpet_isr);
+ if (devp->hd_flags & HPET_SHARED_IRQ)
+ writel(isr, &devp->hd_hpet->hpet_isr);
spin_unlock(&hpet_lock);
spin_lock(&hpet_task_lock);
@@ -276,7 +284,8 @@ static int hpet_mmap(struct file *file, struct vm_area_struct *vma)
if (io_remap_pfn_range(vma, vma->vm_start, addr >> PAGE_SHIFT,
PAGE_SIZE, vma->vm_page_prot)) {
- printk(KERN_ERR "remap_pfn_range failed in hpet.c\n");
+ printk(KERN_ERR "%s: io_remap_pfn_range failed\n",
+ __FUNCTION__);
return -EAGAIN;
}
@@ -364,7 +373,9 @@ static int hpet_ioctl_ieon(struct hpet_dev *devp)
hpet = devp->hd_hpet;
hpetp = devp->hd_hpets;
- v = readq(&timer->hpet_config);
+ if (!devp->hd_ireqfreq)
+ return -EIO;
+
spin_lock_irq(&hpet_lock);
if (devp->hd_flags & HPET_IE) {
@@ -373,16 +384,21 @@ static int hpet_ioctl_ieon(struct hpet_dev *devp)
}
devp->hd_flags |= HPET_IE;
+
+ if (readl(&timer->hpet_config) & Tn_INT_TYPE_CNF_MASK)
+ devp->hd_flags |= HPET_SHARED_IRQ;
spin_unlock_irq(&hpet_lock);
- t = readq(&timer->hpet_config);
irq = devp->hd_hdwirq;
if (irq) {
- sprintf(devp->hd_name, "hpet%d", (int)(devp - hpetp->hp_dev));
+ unsigned long irq_flags;
- if (request_irq
- (irq, hpet_interrupt, SA_INTERRUPT, devp->hd_name, (void *)devp)) {
+ sprintf(devp->hd_name, "hpet%d", (int)(devp - hpetp->hp_dev));
+ irq_flags = devp->hd_flags & HPET_SHARED_IRQ
+ ? SA_SHIRQ : SA_INTERRUPT;
+ if (request_irq(irq, hpet_interrupt, irq_flags,
+ devp->hd_name, (void *)devp)) {
printk(KERN_ERR "hpet: IRQ %d is not free\n", irq);
irq = 0;
}
@@ -416,20 +432,24 @@ static int hpet_ioctl_ieon(struct hpet_dev *devp)
write_counter(t + m + hpetp->hp_delta, &timer->hpet_compare);
}
- isr = (1 << (devp - hpets->hp_dev));
- writeq(isr, &hpet->hpet_isr);
+ if (devp->hd_flags & HPET_SHARED_IRQ) {
+ isr = 1 << (devp - devp->hd_hpets->hp_dev);
+ writel(isr, &hpet->hpet_isr);
+ }
writeq(g, &timer->hpet_config);
local_irq_restore(flags);
return 0;
}
-static inline unsigned long hpet_time_div(unsigned long dis)
+/* converts Hz to number of timer ticks */
+static inline unsigned long hpet_time_div(struct hpets *hpets,
+ unsigned long dis)
{
- unsigned long long m = 1000000000000000ULL;
+ unsigned long long m;
+ m = hpets->hp_tick_freq + (dis >> 1);
do_div(m, dis);
-
return (unsigned long)m;
}
@@ -477,14 +497,21 @@ hpet_ioctl_common(struct hpet_dev *devp, int cmd, unsigned long arg, int kernel)
{
struct hpet_info info;
- info.hi_ireqfreq = hpet_time_div(hpetp->hp_period *
- devp->hd_ireqfreq);
+ if (devp->hd_ireqfreq)
+ info.hi_ireqfreq =
+ hpet_time_div(hpetp, devp->hd_ireqfreq);
+ else
+ info.hi_ireqfreq = 0;
info.hi_flags =
readq(&timer->hpet_config) & Tn_PER_INT_CAP_MASK;
- info.hi_hpet = devp->hd_hpets->hp_which;
- info.hi_timer = devp - devp->hd_hpets->hp_dev;
- if (copy_to_user((void __user *)arg, &info, sizeof(info)))
- err = -EFAULT;
+ info.hi_hpet = hpetp->hp_which;
+ info.hi_timer = devp - hpetp->hp_dev;
+ if (kernel)
+ memcpy((void *)arg, &info, sizeof(info));
+ else
+ if (copy_to_user((void __user *)arg, &info,
+ sizeof(info)))
+ err = -EFAULT;
break;
}
case HPET_EPI:
@@ -516,12 +543,12 @@ hpet_ioctl_common(struct hpet_dev *devp, int cmd, unsigned long arg, int kernel)
break;
}
- if (arg & (arg - 1)) {
+ if (!arg) {
err = -EINVAL;
break;
}
- devp->hd_ireqfreq = hpet_time_div(hpetp->hp_period * arg);
+ devp->hd_ireqfreq = hpet_time_div(hpetp, arg);
}
return err;
@@ -539,6 +566,17 @@ static struct file_operations hpet_fops = {
.mmap = hpet_mmap,
};
+static int hpet_is_known(struct hpet_data *hdp)
+{
+ struct hpets *hpetp;
+
+ for (hpetp = hpets; hpetp; hpetp = hpetp->hp_next)
+ if (hpetp->hp_hpet_phys == hdp->hd_phys_address)
+ return 1;
+
+ return 0;
+}
+
EXPORT_SYMBOL(hpet_alloc);
EXPORT_SYMBOL(hpet_register);
EXPORT_SYMBOL(hpet_unregister);
@@ -563,6 +601,8 @@ int hpet_register(struct hpet_task *tp, int periodic)
return -EINVAL;
}
+ tp->ht_opaque = NULL;
+
spin_lock_irq(&hpet_task_lock);
spin_lock(&hpet_lock);
@@ -702,15 +742,14 @@ static void hpet_register_interpolator(struct hpets *hpetp)
#ifdef CONFIG_TIME_INTERPOLATION
struct time_interpolator *ti;
- ti = kmalloc(sizeof(*ti), GFP_KERNEL);
+ ti = kzalloc(sizeof(*ti), GFP_KERNEL);
if (!ti)
return;
- memset(ti, 0, sizeof(*ti));
ti->source = TIME_SOURCE_MMIO64;
ti->shift = 10;
ti->addr = &hpetp->hp_hpet->hpet_mc;
- ti->frequency = hpet_time_div(hpets->hp_period);
+ ti->frequency = hpetp->hp_tick_freq;
ti->drift = HPET_DRIFT;
ti->mask = -1;
@@ -743,11 +782,11 @@ static unsigned long hpet_calibrate(struct hpets *hpetp)
if (!timer)
return 0;
- hpet = hpets->hp_hpet;
+ hpet = hpetp->hp_hpet;
t = read_counter(&timer->hpet_compare);
i = 0;
- count = hpet_time_div(hpetp->hp_period * TICK_CALIBRATE);
+ count = hpet_time_div(hpetp, TICK_CALIBRATE);
local_irq_save(flags);
@@ -771,28 +810,29 @@ int hpet_alloc(struct hpet_data *hdp)
struct hpets *hpetp;
size_t siz;
struct hpet __iomem *hpet;
- static struct hpets *last = (struct hpets *)0;
- unsigned long ns;
+ static struct hpets *last = NULL;
+ unsigned long period;
+ unsigned long long temp;
/*
* hpet_alloc can be called by platform dependent code.
- * if platform dependent code has allocated the hpet
- * ACPI also reports hpet, then we catch it here.
+ * If platform dependent code has allocated the hpet that
+ * ACPI has also reported, then we catch it here.
*/
- for (hpetp = hpets; hpetp; hpetp = hpetp->hp_next)
- if (hpetp->hp_hpet == hdp->hd_address)
- return 0;
+ if (hpet_is_known(hdp)) {
+ printk(KERN_DEBUG "%s: duplicate HPET ignored\n",
+ __FUNCTION__);
+ return 0;
+ }
siz = sizeof(struct hpets) + ((hdp->hd_nirqs - 1) *
sizeof(struct hpet_dev));
- hpetp = kmalloc(siz, GFP_KERNEL);
+ hpetp = kzalloc(siz, GFP_KERNEL);
if (!hpetp)
return -ENOMEM;
- memset(hpetp, 0, siz);
-
hpetp->hp_which = hpet_nhpet++;
hpetp->hp_hpet = hdp->hd_address;
hpetp->hp_hpet_phys = hdp->hd_phys_address;
@@ -822,21 +862,23 @@ int hpet_alloc(struct hpet_data *hdp)
last = hpetp;
- hpetp->hp_period = (cap & HPET_COUNTER_CLK_PERIOD_MASK) >>
- HPET_COUNTER_CLK_PERIOD_SHIFT;
+ period = (cap & HPET_COUNTER_CLK_PERIOD_MASK) >>
+ HPET_COUNTER_CLK_PERIOD_SHIFT; /* fs, 10^-15 */
+ temp = 1000000000000000uLL; /* 10^15 femtoseconds per second */
+ temp += period >> 1; /* round */
+ do_div(temp, period);
+ hpetp->hp_tick_freq = temp; /* ticks per second */
- printk(KERN_INFO "hpet%d: at MMIO 0x%lx, IRQ%s",
- hpetp->hp_which, hdp->hd_phys_address,
+ printk(KERN_INFO "hpet%d: at MMIO 0x%lx (virtual 0x%p), IRQ%s",
+ hpetp->hp_which, hdp->hd_phys_address, hdp->hd_address,
hpetp->hp_ntimer > 1 ? "s" : "");
for (i = 0; i < hpetp->hp_ntimer; i++)
printk("%s %d", i > 0 ? "," : "", hdp->hd_irq[i]);
printk("\n");
- ns = hpetp->hp_period; /* femptoseconds, 10^-15 */
- ns /= 1000000; /* convert to nanoseconds, 10^-9 */
- printk(KERN_INFO "hpet%d: %ldns tick, %d %d-bit timers\n",
- hpetp->hp_which, ns, hpetp->hp_ntimer,
- cap & HPET_COUNTER_SIZE_MASK ? 64 : 32);
+ printk(KERN_INFO "hpet%u: %u %d-bit timers, %Lu Hz\n",
+ hpetp->hp_which, hpetp->hp_ntimer,
+ cap & HPET_COUNTER_SIZE_MASK ? 64 : 32, hpetp->hp_tick_freq);
mcfg = readq(&hpet->hpet_config);
if ((mcfg & HPET_ENABLE_CNF_MASK) == 0) {
@@ -845,13 +887,10 @@ int hpet_alloc(struct hpet_data *hdp)
writeq(mcfg, &hpet->hpet_config);
}
- for (i = 0, devp = hpetp->hp_dev; i < hpetp->hp_ntimer;
- i++, hpet_ntimer++, devp++) {
- unsigned long v;
+ for (i = 0, devp = hpetp->hp_dev; i < hpetp->hp_ntimer; i++, devp++) {
struct hpet_timer __iomem *timer;
timer = &hpet->hpet_timers[devp - hpetp->hp_dev];
- v = readq(&timer->hpet_config);
devp->hd_hpets = hpetp;
devp->hd_hpet = hpet;
@@ -880,7 +919,6 @@ static acpi_status hpet_resources(struct acpi_resource *res, void *data)
struct hpet_data *hdp;
acpi_status status;
struct acpi_resource_address64 addr;
- struct hpets *hpetp;
hdp = data;
@@ -893,9 +931,29 @@ static acpi_status hpet_resources(struct acpi_resource *res, void *data)
hdp->hd_phys_address = addr.min_address_range;
hdp->hd_address = ioremap(addr.min_address_range, size);
- for (hpetp = hpets; hpetp; hpetp = hpetp->hp_next)
- if (hpetp->hp_hpet == hdp->hd_address)
- return -EBUSY;
+ if (hpet_is_known(hdp)) {
+ printk(KERN_DEBUG "%s: 0x%lx is busy\n",
+ __FUNCTION__, hdp->hd_phys_address);
+ iounmap(hdp->hd_address);
+ return -EBUSY;
+ }
+ } else if (res->id == ACPI_RSTYPE_FIXED_MEM32) {
+ struct acpi_resource_fixed_mem32 *fixmem32;
+
+ fixmem32 = &res->data.fixed_memory32;
+ if (!fixmem32)
+ return -EINVAL;
+
+ hdp->hd_phys_address = fixmem32->range_base_address;
+ hdp->hd_address = ioremap(fixmem32->range_base_address,
+ HPET_RANGE_SIZE);
+
+ if (hpet_is_known(hdp)) {
+ printk(KERN_DEBUG "%s: 0x%lx is busy\n",
+ __FUNCTION__, hdp->hd_phys_address);
+ iounmap(hdp->hd_address);
+ return -EBUSY;
+ }
} else if (res->id == ACPI_RSTYPE_EXT_IRQ) {
struct acpi_resource_ext_irq *irqp;
int i;
diff --git a/drivers/char/hvc_vio.c b/drivers/char/hvc_vio.c
index 78d681dc35a8..f5212eb2b41d 100644
--- a/drivers/char/hvc_vio.c
+++ b/drivers/char/hvc_vio.c
@@ -95,11 +95,11 @@ static int __devexit hvc_vio_remove(struct vio_dev *vdev)
}
static struct vio_driver hvc_vio_driver = {
- .name = hvc_driver_name,
.id_table = hvc_driver_table,
.probe = hvc_vio_probe,
.remove = hvc_vio_remove,
.driver = {
+ .name = hvc_driver_name,
.owner = THIS_MODULE,
}
};
diff --git a/drivers/char/hvcs.c b/drivers/char/hvcs.c
index f47f009f9259..53dc77c760fc 100644
--- a/drivers/char/hvcs.c
+++ b/drivers/char/hvcs.c
@@ -720,10 +720,13 @@ static int __devexit hvcs_remove(struct vio_dev *dev)
};
static struct vio_driver hvcs_vio_driver = {
- .name = hvcs_driver_name,
.id_table = hvcs_driver_table,
.probe = hvcs_probe,
.remove = hvcs_remove,
+ .driver = {
+ .name = hvcs_driver_name,
+ .owner = THIS_MODULE,
+ }
};
/* Only called from hvcs_get_pi please */
diff --git a/drivers/char/ip2.c b/drivers/char/ip2.c
index 6cd12f23aa58..7cadfc6ef352 100644
--- a/drivers/char/ip2.c
+++ b/drivers/char/ip2.c
@@ -7,7 +7,6 @@
//
#include <linux/module.h>
-#include <linux/version.h>
#include <linux/init.h>
#include <linux/wait.h>
diff --git a/drivers/char/ip2/i2ellis.c b/drivers/char/ip2/i2ellis.c
index f834d05ccc97..dd761a1e4f08 100644
--- a/drivers/char/ip2/i2ellis.c
+++ b/drivers/char/ip2/i2ellis.c
@@ -106,9 +106,7 @@ iiEllisInit(void)
static void
iiEllisCleanup(void)
{
- if ( pDelayTimer != NULL ) {
- kfree ( pDelayTimer );
- }
+ kfree(pDelayTimer);
}
//******************************************************************************
diff --git a/drivers/char/ip2main.c b/drivers/char/ip2main.c
index 9e4e26aef94e..d815d197dc3e 100644
--- a/drivers/char/ip2main.c
+++ b/drivers/char/ip2main.c
@@ -721,8 +721,9 @@ ip2_loadmain(int *iop, int *irqp, unsigned char *firmware, int firmsize)
}
if ( NULL != ( pB = i2BoardPtrTable[i] ) ) {
- class_device_create(ip2_class, MKDEV(IP2_IPL_MAJOR,
- 4 * i), NULL, "ipl%d", i);
+ class_device_create(ip2_class, NULL,
+ MKDEV(IP2_IPL_MAJOR, 4 * i),
+ NULL, "ipl%d", i);
err = devfs_mk_cdev(MKDEV(IP2_IPL_MAJOR, 4 * i),
S_IRUSR | S_IWUSR | S_IRGRP | S_IFCHR,
"ip2/ipl%d", i);
@@ -732,8 +733,9 @@ ip2_loadmain(int *iop, int *irqp, unsigned char *firmware, int firmsize)
goto out_class;
}
- class_device_create(ip2_class, MKDEV(IP2_IPL_MAJOR,
- 4 * i + 1), NULL, "stat%d", i);
+ class_device_create(ip2_class, NULL,
+ MKDEV(IP2_IPL_MAJOR, 4 * i + 1),
+ NULL, "stat%d", i);
err = devfs_mk_cdev(MKDEV(IP2_IPL_MAJOR, 4 * i + 1),
S_IRUSR | S_IWUSR | S_IRGRP | S_IFCHR,
"ip2/stat%d", i);
diff --git a/drivers/char/ipmi/ipmi_bt_sm.c b/drivers/char/ipmi/ipmi_bt_sm.c
index 33862670e285..58dcdee1cd71 100644
--- a/drivers/char/ipmi/ipmi_bt_sm.c
+++ b/drivers/char/ipmi/ipmi_bt_sm.c
@@ -28,6 +28,8 @@
#include <linux/kernel.h> /* For printk. */
#include <linux/string.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
#include <linux/ipmi_msgdefs.h> /* for completion codes */
#include "ipmi_si_sm.h"
@@ -36,6 +38,8 @@ static int bt_debug = 0x00; /* Production value 0, see following flags */
#define BT_DEBUG_ENABLE 1
#define BT_DEBUG_MSG 2
#define BT_DEBUG_STATES 4
+module_param(bt_debug, int, 0644);
+MODULE_PARM_DESC(bt_debug, "debug bitmask, 1=enable, 2=messages, 4=states");
/* Typical "Get BT Capabilities" values are 2-3 retries, 5-10 seconds,
and 64 byte buffers. However, one HP implementation wants 255 bytes of
@@ -43,7 +47,7 @@ static int bt_debug = 0x00; /* Production value 0, see following flags */
Since the Open IPMI architecture is single-message oriented at this
stage, the queue depth of BT is of no concern. */
-#define BT_NORMAL_TIMEOUT 2000000 /* seconds in microseconds */
+#define BT_NORMAL_TIMEOUT 5000000 /* seconds in microseconds */
#define BT_RETRY_LIMIT 2
#define BT_RESET_DELAY 6000000 /* 6 seconds after warm reset */
@@ -202,7 +206,7 @@ static int bt_get_result(struct si_sm_data *bt,
msg_len = bt->read_count - 2; /* account for length & seq */
/* Always NetFn, Cmd, cCode */
if (msg_len < 3 || msg_len > IPMI_MAX_MSG_LENGTH) {
- printk(KERN_WARNING "BT results: bad msg_len = %d\n", msg_len);
+ printk(KERN_DEBUG "BT results: bad msg_len = %d\n", msg_len);
data[0] = bt->write_data[1] | 0x4; /* Kludge a response */
data[1] = bt->write_data[3];
data[2] = IPMI_ERR_UNSPECIFIED;
@@ -240,7 +244,7 @@ static void reset_flags(struct si_sm_data *bt)
BT_CONTROL(BT_B_BUSY);
BT_CONTROL(BT_CLR_WR_PTR);
BT_CONTROL(BT_SMS_ATN);
-#ifdef DEVELOPMENT_ONLY_NOT_FOR_PRODUCTION
+
if (BT_STATUS & BT_B2H_ATN) {
int i;
BT_CONTROL(BT_H_BUSY);
@@ -250,7 +254,6 @@ static void reset_flags(struct si_sm_data *bt)
BMC2HOST;
BT_CONTROL(BT_H_BUSY);
}
-#endif
}
static inline void write_all_bytes(struct si_sm_data *bt)
@@ -295,7 +298,7 @@ static inline int read_all_bytes(struct si_sm_data *bt)
printk ("\n");
}
if (bt->seq != bt->write_data[2]) /* idiot check */
- printk(KERN_WARNING "BT: internal error: sequence mismatch\n");
+ printk(KERN_DEBUG "BT: internal error: sequence mismatch\n");
/* per the spec, the (NetFn, Seq, Cmd) tuples should match */
if ((bt->read_data[3] == bt->write_data[3]) && /* Cmd */
@@ -321,18 +324,17 @@ static void error_recovery(struct si_sm_data *bt, char *reason)
bt->timeout = BT_NORMAL_TIMEOUT; /* various places want to retry */
status = BT_STATUS;
- printk(KERN_WARNING "BT: %s in %s %s ", reason, STATE2TXT,
+ printk(KERN_DEBUG "BT: %s in %s %s\n", reason, STATE2TXT,
STATUS2TXT(buf));
(bt->error_retries)++;
if (bt->error_retries > BT_RETRY_LIMIT) {
- printk("retry limit (%d) exceeded\n", BT_RETRY_LIMIT);
+ printk(KERN_DEBUG "retry limit (%d) exceeded\n", BT_RETRY_LIMIT);
bt->state = BT_STATE_HOSED;
if (!bt->nonzero_status)
printk(KERN_ERR "IPMI: BT stuck, try power cycle\n");
- else if (bt->seq == FIRST_SEQ + BT_RETRY_LIMIT) {
- /* most likely during insmod */
- printk(KERN_WARNING "IPMI: BT reset (takes 5 secs)\n");
+ else if (bt->error_retries <= BT_RETRY_LIMIT + 1) {
+ printk(KERN_DEBUG "IPMI: BT reset (takes 5 secs)\n");
bt->state = BT_STATE_RESET1;
}
return;
@@ -340,11 +342,11 @@ static void error_recovery(struct si_sm_data *bt, char *reason)
/* Sometimes the BMC queues get in an "off-by-one" state...*/
if ((bt->state == BT_STATE_B2H_WAIT) && (status & BT_B2H_ATN)) {
- printk("retry B2H_WAIT\n");
+ printk(KERN_DEBUG "retry B2H_WAIT\n");
return;
}
- printk("restart command\n");
+ printk(KERN_DEBUG "restart command\n");
bt->state = BT_STATE_RESTART;
}
@@ -372,17 +374,6 @@ static enum si_sm_result bt_event(struct si_sm_data *bt, long time)
return SI_SM_HOSED;
if (bt->state != BT_STATE_IDLE) { /* do timeout test */
-
- /* Certain states, on error conditions, can lock up a CPU
- because they are effectively in an infinite loop with
- CALL_WITHOUT_DELAY (right back here with time == 0).
- Prevent infinite lockup by ALWAYS decrementing timeout. */
-
- /* FIXME: bt_event is sometimes called with time > BT_NORMAL_TIMEOUT
- (noticed in ipmi_smic_sm.c January 2004) */
-
- if ((time <= 0) || (time >= BT_NORMAL_TIMEOUT))
- time = 100;
bt->timeout -= time;
if ((bt->timeout < 0) && (bt->state < BT_STATE_RESET1)) {
error_recovery(bt, "timed out");
@@ -483,6 +474,7 @@ static enum si_sm_result bt_event(struct si_sm_data *bt, long time)
break;
case BT_STATE_RESTART: /* don't reset retries! */
+ reset_flags(bt);
bt->write_data[2] = ++bt->seq;
bt->read_count = 0;
bt->nonzero_status = 0;
diff --git a/drivers/char/ipmi/ipmi_devintf.c b/drivers/char/ipmi/ipmi_devintf.c
index a09ff1080687..7c0684deea06 100644
--- a/drivers/char/ipmi/ipmi_devintf.c
+++ b/drivers/char/ipmi/ipmi_devintf.c
@@ -798,7 +798,7 @@ static void ipmi_new_smi(int if_num)
devfs_mk_cdev(dev, S_IFCHR | S_IRUSR | S_IWUSR,
"ipmidev/%d", if_num);
- class_device_create(ipmi_class, dev, NULL, "ipmi%d", if_num);
+ class_device_create(ipmi_class, NULL, dev, NULL, "ipmi%d", if_num);
}
static void ipmi_smi_gone(int if_num)
diff --git a/drivers/char/ipmi/ipmi_kcs_sm.c b/drivers/char/ipmi/ipmi_kcs_sm.c
index d21853a594a3..da1554194d3d 100644
--- a/drivers/char/ipmi/ipmi_kcs_sm.c
+++ b/drivers/char/ipmi/ipmi_kcs_sm.c
@@ -38,16 +38,25 @@
*/
#include <linux/kernel.h> /* For printk. */
+#include <linux/module.h>
+#include <linux/moduleparam.h>
#include <linux/string.h>
+#include <linux/jiffies.h>
#include <linux/ipmi_msgdefs.h> /* for completion codes */
#include "ipmi_si_sm.h"
-/* Set this if you want a printout of why the state machine was hosed
- when it gets hosed. */
-#define DEBUG_HOSED_REASON
+/* kcs_debug is a bit-field
+ * KCS_DEBUG_ENABLE - turned on for now
+ * KCS_DEBUG_MSG - commands and their responses
+ * KCS_DEBUG_STATES - state machine
+ */
+#define KCS_DEBUG_STATES 4
+#define KCS_DEBUG_MSG 2
+#define KCS_DEBUG_ENABLE 1
-/* Print the state machine state on entry every time. */
-#undef DEBUG_STATE
+static int kcs_debug;
+module_param(kcs_debug, int, 0644);
+MODULE_PARM_DESC(kcs_debug, "debug bitmask, 1=enable, 2=messages, 4=states");
/* The states the KCS driver may be in. */
enum kcs_states {
@@ -91,6 +100,7 @@ enum kcs_states {
#define IBF_RETRY_TIMEOUT 1000000
#define OBF_RETRY_TIMEOUT 1000000
#define MAX_ERROR_RETRIES 10
+#define ERROR0_OBF_WAIT_JIFFIES (2*HZ)
struct si_sm_data
{
@@ -107,6 +117,7 @@ struct si_sm_data
unsigned int error_retries;
long ibf_timeout;
long obf_timeout;
+ unsigned long error0_timeout;
};
static unsigned int init_kcs_data(struct si_sm_data *kcs,
@@ -175,11 +186,11 @@ static inline void start_error_recovery(struct si_sm_data *kcs, char *reason)
{
(kcs->error_retries)++;
if (kcs->error_retries > MAX_ERROR_RETRIES) {
-#ifdef DEBUG_HOSED_REASON
- printk("ipmi_kcs_sm: kcs hosed: %s\n", reason);
-#endif
+ if (kcs_debug & KCS_DEBUG_ENABLE)
+ printk(KERN_DEBUG "ipmi_kcs_sm: kcs hosed: %s\n", reason);
kcs->state = KCS_HOSED;
} else {
+ kcs->error0_timeout = jiffies + ERROR0_OBF_WAIT_JIFFIES;
kcs->state = KCS_ERROR0;
}
}
@@ -248,14 +259,21 @@ static void restart_kcs_transaction(struct si_sm_data *kcs)
static int start_kcs_transaction(struct si_sm_data *kcs, unsigned char *data,
unsigned int size)
{
+ unsigned int i;
+
if ((size < 2) || (size > MAX_KCS_WRITE_SIZE)) {
return -1;
}
-
if ((kcs->state != KCS_IDLE) && (kcs->state != KCS_HOSED)) {
return -2;
}
-
+ if (kcs_debug & KCS_DEBUG_MSG) {
+ printk(KERN_DEBUG "start_kcs_transaction -");
+ for (i = 0; i < size; i ++) {
+ printk(" %02x", (unsigned char) (data [i]));
+ }
+ printk ("\n");
+ }
kcs->error_retries = 0;
memcpy(kcs->write_data, data, size);
kcs->write_count = size;
@@ -305,9 +323,9 @@ static enum si_sm_result kcs_event(struct si_sm_data *kcs, long time)
status = read_status(kcs);
-#ifdef DEBUG_STATE
- printk(" State = %d, %x\n", kcs->state, status);
-#endif
+ if (kcs_debug & KCS_DEBUG_STATES)
+ printk(KERN_DEBUG "KCS: State = %d, %x\n", kcs->state, status);
+
/* All states wait for ibf, so just do it here. */
if (!check_ibf(kcs, status, time))
return SI_SM_CALL_WITH_DELAY;
@@ -409,6 +427,10 @@ static enum si_sm_result kcs_event(struct si_sm_data *kcs, long time)
case KCS_ERROR0:
clear_obf(kcs, status);
+ status = read_status(kcs);
+ if (GET_STATUS_OBF(status)) /* controller isn't responding */
+ if (time_before(jiffies, kcs->error0_timeout))
+ return SI_SM_CALL_WITH_TICK_DELAY;
write_cmd(kcs, KCS_GET_STATUS_ABORT);
kcs->state = KCS_ERROR1;
break;
diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c
index 32fa82c78c73..c1d06ba449b6 100644
--- a/drivers/char/ipmi/ipmi_msghandler.c
+++ b/drivers/char/ipmi/ipmi_msghandler.c
@@ -38,13 +38,13 @@
#include <linux/sched.h>
#include <linux/poll.h>
#include <linux/spinlock.h>
-#include <linux/rwsem.h>
#include <linux/slab.h>
#include <linux/ipmi.h>
#include <linux/ipmi_smi.h>
#include <linux/notifier.h>
#include <linux/init.h>
#include <linux/proc_fs.h>
+#include <linux/rcupdate.h>
#define PFX "IPMI message handler: "
@@ -65,10 +65,19 @@ struct proc_dir_entry *proc_ipmi_root = NULL;
the max message timer. This is in milliseconds. */
#define MAX_MSG_TIMEOUT 60000
+
+/*
+ * The main "user" data structure.
+ */
struct ipmi_user
{
struct list_head link;
+ /* Set to "0" when the user is destroyed. */
+ int valid;
+
+ struct kref refcount;
+
/* The upper layer that handles receive messages. */
struct ipmi_user_hndl *handler;
void *handler_data;
@@ -87,6 +96,15 @@ struct cmd_rcvr
ipmi_user_t user;
unsigned char netfn;
unsigned char cmd;
+
+ /*
+ * This is used to form a linked lised during mass deletion.
+ * Since this is in an RCU list, we cannot use the link above
+ * or change any data until the RCU period completes. So we
+ * use this next variable during mass deletion so we can have
+ * a list and don't have to wait and restart the search on
+ * every individual deletion of a command. */
+ struct cmd_rcvr *next;
};
struct seq_table
@@ -150,13 +168,11 @@ struct ipmi_smi
/* What interface number are we? */
int intf_num;
- /* The list of upper layers that are using me. We read-lock
- this when delivering messages to the upper layer to keep
- the user from going away while we are processing the
- message. This means that you cannot add or delete a user
- from the receive callback. */
- rwlock_t users_lock;
- struct list_head users;
+ struct kref refcount;
+
+ /* The list of upper layers that are using me. seq_lock
+ * protects this. */
+ struct list_head users;
/* Used for wake ups at startup. */
wait_queue_head_t waitq;
@@ -193,7 +209,7 @@ struct ipmi_smi
/* The list of command receivers that are registered for commands
on this interface. */
- rwlock_t cmd_rcvr_lock;
+ struct semaphore cmd_rcvrs_lock;
struct list_head cmd_rcvrs;
/* Events that were queues because no one was there to receive
@@ -296,16 +312,17 @@ struct ipmi_smi
unsigned int events;
};
+/* Used to mark an interface entry that cannot be used but is not a
+ * free entry, either, primarily used at creation and deletion time so
+ * a slot doesn't get reused too quickly. */
+#define IPMI_INVALID_INTERFACE_ENTRY ((ipmi_smi_t) ((long) 1))
+#define IPMI_INVALID_INTERFACE(i) (((i) == NULL) \
+ || (i == IPMI_INVALID_INTERFACE_ENTRY))
+
#define MAX_IPMI_INTERFACES 4
static ipmi_smi_t ipmi_interfaces[MAX_IPMI_INTERFACES];
-/* Used to keep interfaces from going away while operations are
- operating on interfaces. Grab read if you are not modifying the
- interfaces, write if you are. */
-static DECLARE_RWSEM(interfaces_sem);
-
-/* Directly protects the ipmi_interfaces data structure. This is
- claimed in the timer interrupt. */
+/* Directly protects the ipmi_interfaces data structure. */
static DEFINE_SPINLOCK(interfaces_lock);
/* List of watchers that want to know when smi's are added and
@@ -313,20 +330,72 @@ static DEFINE_SPINLOCK(interfaces_lock);
static struct list_head smi_watchers = LIST_HEAD_INIT(smi_watchers);
static DECLARE_RWSEM(smi_watchers_sem);
+
+static void free_recv_msg_list(struct list_head *q)
+{
+ struct ipmi_recv_msg *msg, *msg2;
+
+ list_for_each_entry_safe(msg, msg2, q, link) {
+ list_del(&msg->link);
+ ipmi_free_recv_msg(msg);
+ }
+}
+
+static void clean_up_interface_data(ipmi_smi_t intf)
+{
+ int i;
+ struct cmd_rcvr *rcvr, *rcvr2;
+ struct list_head list;
+
+ free_recv_msg_list(&intf->waiting_msgs);
+ free_recv_msg_list(&intf->waiting_events);
+
+ /* Wholesale remove all the entries from the list in the
+ * interface and wait for RCU to know that none are in use. */
+ down(&intf->cmd_rcvrs_lock);
+ list_add_rcu(&list, &intf->cmd_rcvrs);
+ list_del_rcu(&intf->cmd_rcvrs);
+ up(&intf->cmd_rcvrs_lock);
+ synchronize_rcu();
+
+ list_for_each_entry_safe(rcvr, rcvr2, &list, link)
+ kfree(rcvr);
+
+ for (i = 0; i < IPMI_IPMB_NUM_SEQ; i++) {
+ if ((intf->seq_table[i].inuse)
+ && (intf->seq_table[i].recv_msg))
+ {
+ ipmi_free_recv_msg(intf->seq_table[i].recv_msg);
+ }
+ }
+}
+
+static void intf_free(struct kref *ref)
+{
+ ipmi_smi_t intf = container_of(ref, struct ipmi_smi, refcount);
+
+ clean_up_interface_data(intf);
+ kfree(intf);
+}
+
int ipmi_smi_watcher_register(struct ipmi_smi_watcher *watcher)
{
- int i;
+ int i;
+ unsigned long flags;
- down_read(&interfaces_sem);
down_write(&smi_watchers_sem);
list_add(&(watcher->link), &smi_watchers);
+ up_write(&smi_watchers_sem);
+ spin_lock_irqsave(&interfaces_lock, flags);
for (i = 0; i < MAX_IPMI_INTERFACES; i++) {
- if (ipmi_interfaces[i] != NULL) {
- watcher->new_smi(i);
- }
+ ipmi_smi_t intf = ipmi_interfaces[i];
+ if (IPMI_INVALID_INTERFACE(intf))
+ continue;
+ spin_unlock_irqrestore(&interfaces_lock, flags);
+ watcher->new_smi(i);
+ spin_lock_irqsave(&interfaces_lock, flags);
}
- up_write(&smi_watchers_sem);
- up_read(&interfaces_sem);
+ spin_unlock_irqrestore(&interfaces_lock, flags);
return 0;
}
@@ -471,8 +540,8 @@ static void deliver_response(struct ipmi_recv_msg *msg)
}
ipmi_free_recv_msg(msg);
} else {
- msg->user->handler->ipmi_recv_hndl(msg,
- msg->user->handler_data);
+ ipmi_user_t user = msg->user;
+ user->handler->ipmi_recv_hndl(msg, user->handler_data);
}
}
@@ -662,15 +731,18 @@ int ipmi_create_user(unsigned int if_num,
if (! new_user)
return -ENOMEM;
- down_read(&interfaces_sem);
- if ((if_num >= MAX_IPMI_INTERFACES) || ipmi_interfaces[if_num] == NULL)
- {
- rv = -EINVAL;
- goto out_unlock;
+ spin_lock_irqsave(&interfaces_lock, flags);
+ intf = ipmi_interfaces[if_num];
+ if ((if_num >= MAX_IPMI_INTERFACES) || IPMI_INVALID_INTERFACE(intf)) {
+ spin_unlock_irqrestore(&interfaces_lock, flags);
+ return -EINVAL;
}
- intf = ipmi_interfaces[if_num];
+ /* Note that each existing user holds a refcount to the interface. */
+ kref_get(&intf->refcount);
+ spin_unlock_irqrestore(&interfaces_lock, flags);
+ kref_init(&new_user->refcount);
new_user->handler = handler;
new_user->handler_data = handler_data;
new_user->intf = intf;
@@ -678,98 +750,92 @@ int ipmi_create_user(unsigned int if_num,
if (!try_module_get(intf->handlers->owner)) {
rv = -ENODEV;
- goto out_unlock;
+ goto out_err;
}
if (intf->handlers->inc_usecount) {
rv = intf->handlers->inc_usecount(intf->send_info);
if (rv) {
module_put(intf->handlers->owner);
- goto out_unlock;
+ goto out_err;
}
}
- write_lock_irqsave(&intf->users_lock, flags);
- list_add_tail(&new_user->link, &intf->users);
- write_unlock_irqrestore(&intf->users_lock, flags);
-
- out_unlock:
- if (rv) {
- kfree(new_user);
- } else {
- *user = new_user;
- }
+ new_user->valid = 1;
+ spin_lock_irqsave(&intf->seq_lock, flags);
+ list_add_rcu(&new_user->link, &intf->users);
+ spin_unlock_irqrestore(&intf->seq_lock, flags);
+ *user = new_user;
+ return 0;
- up_read(&interfaces_sem);
+ out_err:
+ kfree(new_user);
+ kref_put(&intf->refcount, intf_free);
return rv;
}
-static int ipmi_destroy_user_nolock(ipmi_user_t user)
+static void free_user(struct kref *ref)
+{
+ ipmi_user_t user = container_of(ref, struct ipmi_user, refcount);
+ kfree(user);
+}
+
+int ipmi_destroy_user(ipmi_user_t user)
{
int rv = -ENODEV;
- ipmi_user_t t_user;
- struct cmd_rcvr *rcvr, *rcvr2;
+ ipmi_smi_t intf = user->intf;
int i;
unsigned long flags;
+ struct cmd_rcvr *rcvr;
+ struct list_head *entry1, *entry2;
+ struct cmd_rcvr *rcvrs = NULL;
- /* Find the user and delete them from the list. */
- list_for_each_entry(t_user, &(user->intf->users), link) {
- if (t_user == user) {
- list_del(&t_user->link);
- rv = 0;
- break;
- }
- }
+ user->valid = 1;
- if (rv) {
- goto out_unlock;
- }
+ /* Remove the user from the interface's sequence table. */
+ spin_lock_irqsave(&intf->seq_lock, flags);
+ list_del_rcu(&user->link);
- /* Remove the user from the interfaces sequence table. */
- spin_lock_irqsave(&(user->intf->seq_lock), flags);
for (i = 0; i < IPMI_IPMB_NUM_SEQ; i++) {
- if (user->intf->seq_table[i].inuse
- && (user->intf->seq_table[i].recv_msg->user == user))
+ if (intf->seq_table[i].inuse
+ && (intf->seq_table[i].recv_msg->user == user))
{
- user->intf->seq_table[i].inuse = 0;
+ intf->seq_table[i].inuse = 0;
}
}
- spin_unlock_irqrestore(&(user->intf->seq_lock), flags);
-
- /* Remove the user from the command receiver's table. */
- write_lock_irqsave(&(user->intf->cmd_rcvr_lock), flags);
- list_for_each_entry_safe(rcvr, rcvr2, &(user->intf->cmd_rcvrs), link) {
+ spin_unlock_irqrestore(&intf->seq_lock, flags);
+
+ /*
+ * Remove the user from the command receiver's table. First
+ * we build a list of everything (not using the standard link,
+ * since other things may be using it till we do
+ * synchronize_rcu()) then free everything in that list.
+ */
+ down(&intf->cmd_rcvrs_lock);
+ list_for_each_safe_rcu(entry1, entry2, &intf->cmd_rcvrs) {
+ rcvr = list_entry(entry1, struct cmd_rcvr, link);
if (rcvr->user == user) {
- list_del(&rcvr->link);
- kfree(rcvr);
+ list_del_rcu(&rcvr->link);
+ rcvr->next = rcvrs;
+ rcvrs = rcvr;
}
}
- write_unlock_irqrestore(&(user->intf->cmd_rcvr_lock), flags);
+ up(&intf->cmd_rcvrs_lock);
+ synchronize_rcu();
+ while (rcvrs) {
+ rcvr = rcvrs;
+ rcvrs = rcvr->next;
+ kfree(rcvr);
+ }
- kfree(user);
+ module_put(intf->handlers->owner);
+ if (intf->handlers->dec_usecount)
+ intf->handlers->dec_usecount(intf->send_info);
- out_unlock:
+ kref_put(&intf->refcount, intf_free);
- return rv;
-}
-
-int ipmi_destroy_user(ipmi_user_t user)
-{
- int rv;
- ipmi_smi_t intf = user->intf;
- unsigned long flags;
+ kref_put(&user->refcount, free_user);
- down_read(&interfaces_sem);
- write_lock_irqsave(&intf->users_lock, flags);
- rv = ipmi_destroy_user_nolock(user);
- if (!rv) {
- module_put(intf->handlers->owner);
- if (intf->handlers->dec_usecount)
- intf->handlers->dec_usecount(intf->send_info);
- }
-
- write_unlock_irqrestore(&intf->users_lock, flags);
- up_read(&interfaces_sem);
return rv;
}
@@ -823,62 +889,78 @@ int ipmi_get_my_LUN(ipmi_user_t user,
int ipmi_set_gets_events(ipmi_user_t user, int val)
{
- unsigned long flags;
- struct ipmi_recv_msg *msg, *msg2;
+ unsigned long flags;
+ ipmi_smi_t intf = user->intf;
+ struct ipmi_recv_msg *msg, *msg2;
+ struct list_head msgs;
- read_lock(&(user->intf->users_lock));
- spin_lock_irqsave(&(user->intf->events_lock), flags);
+ INIT_LIST_HEAD(&msgs);
+
+ spin_lock_irqsave(&intf->events_lock, flags);
user->gets_events = val;
if (val) {
/* Deliver any queued events. */
- list_for_each_entry_safe(msg, msg2, &(user->intf->waiting_events), link) {
+ list_for_each_entry_safe(msg, msg2, &intf->waiting_events, link) {
list_del(&msg->link);
- msg->user = user;
- deliver_response(msg);
+ list_add_tail(&msg->link, &msgs);
}
}
-
- spin_unlock_irqrestore(&(user->intf->events_lock), flags);
- read_unlock(&(user->intf->users_lock));
+
+ /* Hold the events lock while doing this to preserve order. */
+ list_for_each_entry_safe(msg, msg2, &msgs, link) {
+ msg->user = user;
+ kref_get(&user->refcount);
+ deliver_response(msg);
+ }
+
+ spin_unlock_irqrestore(&intf->events_lock, flags);
return 0;
}
+static struct cmd_rcvr *find_cmd_rcvr(ipmi_smi_t intf,
+ unsigned char netfn,
+ unsigned char cmd)
+{
+ struct cmd_rcvr *rcvr;
+
+ list_for_each_entry_rcu(rcvr, &intf->cmd_rcvrs, link) {
+ if ((rcvr->netfn == netfn) && (rcvr->cmd == cmd))
+ return rcvr;
+ }
+ return NULL;
+}
+
int ipmi_register_for_cmd(ipmi_user_t user,
unsigned char netfn,
unsigned char cmd)
{
- struct cmd_rcvr *cmp;
- unsigned long flags;
- struct cmd_rcvr *rcvr;
- int rv = 0;
+ ipmi_smi_t intf = user->intf;
+ struct cmd_rcvr *rcvr;
+ struct cmd_rcvr *entry;
+ int rv = 0;
rcvr = kmalloc(sizeof(*rcvr), GFP_KERNEL);
if (! rcvr)
return -ENOMEM;
+ rcvr->cmd = cmd;
+ rcvr->netfn = netfn;
+ rcvr->user = user;
- read_lock(&(user->intf->users_lock));
- write_lock_irqsave(&(user->intf->cmd_rcvr_lock), flags);
+ down(&intf->cmd_rcvrs_lock);
/* Make sure the command/netfn is not already registered. */
- list_for_each_entry(cmp, &(user->intf->cmd_rcvrs), link) {
- if ((cmp->netfn == netfn) && (cmp->cmd == cmd)) {
- rv = -EBUSY;
- break;
- }
- }
-
- if (! rv) {
- rcvr->cmd = cmd;
- rcvr->netfn = netfn;
- rcvr->user = user;
- list_add_tail(&(rcvr->link), &(user->intf->cmd_rcvrs));
+ entry = find_cmd_rcvr(intf, netfn, cmd);
+ if (entry) {
+ rv = -EBUSY;
+ goto out_unlock;
}
- write_unlock_irqrestore(&(user->intf->cmd_rcvr_lock), flags);
- read_unlock(&(user->intf->users_lock));
+ list_add_rcu(&rcvr->link, &intf->cmd_rcvrs);
+ out_unlock:
+ up(&intf->cmd_rcvrs_lock);
if (rv)
kfree(rcvr);
@@ -889,31 +971,28 @@ int ipmi_unregister_for_cmd(ipmi_user_t user,
unsigned char netfn,
unsigned char cmd)
{
- unsigned long flags;
- struct cmd_rcvr *rcvr;
- int rv = -ENOENT;
+ ipmi_smi_t intf = user->intf;
+ struct cmd_rcvr *rcvr;
- read_lock(&(user->intf->users_lock));
- write_lock_irqsave(&(user->intf->cmd_rcvr_lock), flags);
+ down(&intf->cmd_rcvrs_lock);
/* Make sure the command/netfn is not already registered. */
- list_for_each_entry(rcvr, &(user->intf->cmd_rcvrs), link) {
- if ((rcvr->netfn == netfn) && (rcvr->cmd == cmd)) {
- rv = 0;
- list_del(&rcvr->link);
- kfree(rcvr);
- break;
- }
+ rcvr = find_cmd_rcvr(intf, netfn, cmd);
+ if ((rcvr) && (rcvr->user == user)) {
+ list_del_rcu(&rcvr->link);
+ up(&intf->cmd_rcvrs_lock);
+ synchronize_rcu();
+ kfree(rcvr);
+ return 0;
+ } else {
+ up(&intf->cmd_rcvrs_lock);
+ return -ENOENT;
}
- write_unlock_irqrestore(&(user->intf->cmd_rcvr_lock), flags);
- read_unlock(&(user->intf->users_lock));
-
- return rv;
}
void ipmi_user_set_run_to_completion(ipmi_user_t user, int val)
{
- user->intf->handlers->set_run_to_completion(user->intf->send_info,
- val);
+ ipmi_smi_t intf = user->intf;
+ intf->handlers->set_run_to_completion(intf->send_info, val);
}
static unsigned char
@@ -1010,19 +1089,19 @@ static inline void format_lan_msg(struct ipmi_smi_msg *smi_msg,
supplied in certain circumstances (mainly at panic time). If
messages are supplied, they will be freed, even if an error
occurs. */
-static inline int i_ipmi_request(ipmi_user_t user,
- ipmi_smi_t intf,
- struct ipmi_addr *addr,
- long msgid,
- struct kernel_ipmi_msg *msg,
- void *user_msg_data,
- void *supplied_smi,
- struct ipmi_recv_msg *supplied_recv,
- int priority,
- unsigned char source_address,
- unsigned char source_lun,
- int retries,
- unsigned int retry_time_ms)
+static int i_ipmi_request(ipmi_user_t user,
+ ipmi_smi_t intf,
+ struct ipmi_addr *addr,
+ long msgid,
+ struct kernel_ipmi_msg *msg,
+ void *user_msg_data,
+ void *supplied_smi,
+ struct ipmi_recv_msg *supplied_recv,
+ int priority,
+ unsigned char source_address,
+ unsigned char source_lun,
+ int retries,
+ unsigned int retry_time_ms)
{
int rv = 0;
struct ipmi_smi_msg *smi_msg;
@@ -1051,6 +1130,8 @@ static inline int i_ipmi_request(ipmi_user_t user,
}
recv_msg->user = user;
+ if (user)
+ kref_get(&user->refcount);
recv_msg->msgid = msgid;
/* Store the message to send in the receive message so timeout
responses can get the proper response data. */
@@ -1725,11 +1806,11 @@ int ipmi_register_smi(struct ipmi_smi_handlers *handlers,
unsigned char version_major,
unsigned char version_minor,
unsigned char slave_addr,
- ipmi_smi_t *intf)
+ ipmi_smi_t *new_intf)
{
int i, j;
int rv;
- ipmi_smi_t new_intf;
+ ipmi_smi_t intf;
unsigned long flags;
@@ -1745,189 +1826,142 @@ int ipmi_register_smi(struct ipmi_smi_handlers *handlers,
return -ENODEV;
}
- new_intf = kmalloc(sizeof(*new_intf), GFP_KERNEL);
- if (!new_intf)
+ intf = kmalloc(sizeof(*intf), GFP_KERNEL);
+ if (!intf)
return -ENOMEM;
- memset(new_intf, 0, sizeof(*new_intf));
-
- new_intf->proc_dir = NULL;
+ memset(intf, 0, sizeof(*intf));
+ intf->intf_num = -1;
+ kref_init(&intf->refcount);
+ intf->version_major = version_major;
+ intf->version_minor = version_minor;
+ for (j = 0; j < IPMI_MAX_CHANNELS; j++) {
+ intf->channels[j].address = IPMI_BMC_SLAVE_ADDR;
+ intf->channels[j].lun = 2;
+ }
+ if (slave_addr != 0)
+ intf->channels[0].address = slave_addr;
+ INIT_LIST_HEAD(&intf->users);
+ intf->handlers = handlers;
+ intf->send_info = send_info;
+ spin_lock_init(&intf->seq_lock);
+ for (j = 0; j < IPMI_IPMB_NUM_SEQ; j++) {
+ intf->seq_table[j].inuse = 0;
+ intf->seq_table[j].seqid = 0;
+ }
+ intf->curr_seq = 0;
+#ifdef CONFIG_PROC_FS
+ spin_lock_init(&intf->proc_entry_lock);
+#endif
+ spin_lock_init(&intf->waiting_msgs_lock);
+ INIT_LIST_HEAD(&intf->waiting_msgs);
+ spin_lock_init(&intf->events_lock);
+ INIT_LIST_HEAD(&intf->waiting_events);
+ intf->waiting_events_count = 0;
+ init_MUTEX(&intf->cmd_rcvrs_lock);
+ INIT_LIST_HEAD(&intf->cmd_rcvrs);
+ init_waitqueue_head(&intf->waitq);
+
+ spin_lock_init(&intf->counter_lock);
+ intf->proc_dir = NULL;
rv = -ENOMEM;
-
- down_write(&interfaces_sem);
+ spin_lock_irqsave(&interfaces_lock, flags);
for (i = 0; i < MAX_IPMI_INTERFACES; i++) {
if (ipmi_interfaces[i] == NULL) {
- new_intf->intf_num = i;
- new_intf->version_major = version_major;
- new_intf->version_minor = version_minor;
- for (j = 0; j < IPMI_MAX_CHANNELS; j++) {
- new_intf->channels[j].address
- = IPMI_BMC_SLAVE_ADDR;
- new_intf->channels[j].lun = 2;
- }
- if (slave_addr != 0)
- new_intf->channels[0].address = slave_addr;
- rwlock_init(&(new_intf->users_lock));
- INIT_LIST_HEAD(&(new_intf->users));
- new_intf->handlers = handlers;
- new_intf->send_info = send_info;
- spin_lock_init(&(new_intf->seq_lock));
- for (j = 0; j < IPMI_IPMB_NUM_SEQ; j++) {
- new_intf->seq_table[j].inuse = 0;
- new_intf->seq_table[j].seqid = 0;
- }
- new_intf->curr_seq = 0;
-#ifdef CONFIG_PROC_FS
- spin_lock_init(&(new_intf->proc_entry_lock));
-#endif
- spin_lock_init(&(new_intf->waiting_msgs_lock));
- INIT_LIST_HEAD(&(new_intf->waiting_msgs));
- spin_lock_init(&(new_intf->events_lock));
- INIT_LIST_HEAD(&(new_intf->waiting_events));
- new_intf->waiting_events_count = 0;
- rwlock_init(&(new_intf->cmd_rcvr_lock));
- init_waitqueue_head(&new_intf->waitq);
- INIT_LIST_HEAD(&(new_intf->cmd_rcvrs));
-
- spin_lock_init(&(new_intf->counter_lock));
-
- spin_lock_irqsave(&interfaces_lock, flags);
- ipmi_interfaces[i] = new_intf;
- spin_unlock_irqrestore(&interfaces_lock, flags);
-
+ intf->intf_num = i;
+ /* Reserve the entry till we are done. */
+ ipmi_interfaces[i] = IPMI_INVALID_INTERFACE_ENTRY;
rv = 0;
- *intf = new_intf;
break;
}
}
+ spin_unlock_irqrestore(&interfaces_lock, flags);
+ if (rv)
+ goto out;
- downgrade_write(&interfaces_sem);
-
- if (rv == 0)
- rv = add_proc_entries(*intf, i);
-
- if (rv == 0) {
- if ((version_major > 1)
- || ((version_major == 1) && (version_minor >= 5)))
- {
- /* Start scanning the channels to see what is
- available. */
- (*intf)->null_user_handler = channel_handler;
- (*intf)->curr_channel = 0;
- rv = send_channel_info_cmd(*intf, 0);
- if (rv)
- goto out;
+ /* FIXME - this is an ugly kludge, this sets the intf for the
+ caller before sending any messages with it. */
+ *new_intf = intf;
- /* Wait for the channel info to be read. */
- up_read(&interfaces_sem);
- wait_event((*intf)->waitq,
- ((*intf)->curr_channel>=IPMI_MAX_CHANNELS));
- down_read(&interfaces_sem);
+ if ((version_major > 1)
+ || ((version_major == 1) && (version_minor >= 5)))
+ {
+ /* Start scanning the channels to see what is
+ available. */
+ intf->null_user_handler = channel_handler;
+ intf->curr_channel = 0;
+ rv = send_channel_info_cmd(intf, 0);
+ if (rv)
+ goto out;
- if (ipmi_interfaces[i] != new_intf)
- /* Well, it went away. Just return. */
- goto out;
- } else {
- /* Assume a single IPMB channel at zero. */
- (*intf)->channels[0].medium = IPMI_CHANNEL_MEDIUM_IPMB;
- (*intf)->channels[0].protocol
- = IPMI_CHANNEL_PROTOCOL_IPMB;
- }
-
- /* Call all the watcher interfaces to tell
- them that a new interface is available. */
- call_smi_watchers(i);
+ /* Wait for the channel info to be read. */
+ wait_event(intf->waitq,
+ intf->curr_channel >= IPMI_MAX_CHANNELS);
+ } else {
+ /* Assume a single IPMB channel at zero. */
+ intf->channels[0].medium = IPMI_CHANNEL_MEDIUM_IPMB;
+ intf->channels[0].protocol = IPMI_CHANNEL_PROTOCOL_IPMB;
}
- out:
- up_read(&interfaces_sem);
+ if (rv == 0)
+ rv = add_proc_entries(intf, i);
+ out:
if (rv) {
- if (new_intf->proc_dir)
- remove_proc_entries(new_intf);
- kfree(new_intf);
+ if (intf->proc_dir)
+ remove_proc_entries(intf);
+ kref_put(&intf->refcount, intf_free);
+ if (i < MAX_IPMI_INTERFACES) {
+ spin_lock_irqsave(&interfaces_lock, flags);
+ ipmi_interfaces[i] = NULL;
+ spin_unlock_irqrestore(&interfaces_lock, flags);
+ }
+ } else {
+ spin_lock_irqsave(&interfaces_lock, flags);
+ ipmi_interfaces[i] = intf;
+ spin_unlock_irqrestore(&interfaces_lock, flags);
+ call_smi_watchers(i);
}
return rv;
}
-static void free_recv_msg_list(struct list_head *q)
-{
- struct ipmi_recv_msg *msg, *msg2;
-
- list_for_each_entry_safe(msg, msg2, q, link) {
- list_del(&msg->link);
- ipmi_free_recv_msg(msg);
- }
-}
-
-static void free_cmd_rcvr_list(struct list_head *q)
-{
- struct cmd_rcvr *rcvr, *rcvr2;
-
- list_for_each_entry_safe(rcvr, rcvr2, q, link) {
- list_del(&rcvr->link);
- kfree(rcvr);
- }
-}
-
-static void clean_up_interface_data(ipmi_smi_t intf)
-{
- int i;
-
- free_recv_msg_list(&(intf->waiting_msgs));
- free_recv_msg_list(&(intf->waiting_events));
- free_cmd_rcvr_list(&(intf->cmd_rcvrs));
-
- for (i = 0; i < IPMI_IPMB_NUM_SEQ; i++) {
- if ((intf->seq_table[i].inuse)
- && (intf->seq_table[i].recv_msg))
- {
- ipmi_free_recv_msg(intf->seq_table[i].recv_msg);
- }
- }
-}
-
int ipmi_unregister_smi(ipmi_smi_t intf)
{
- int rv = -ENODEV;
int i;
struct ipmi_smi_watcher *w;
unsigned long flags;
- down_write(&interfaces_sem);
- if (list_empty(&(intf->users)))
- {
- for (i = 0; i < MAX_IPMI_INTERFACES; i++) {
- if (ipmi_interfaces[i] == intf) {
- remove_proc_entries(intf);
- spin_lock_irqsave(&interfaces_lock, flags);
- ipmi_interfaces[i] = NULL;
- clean_up_interface_data(intf);
- spin_unlock_irqrestore(&interfaces_lock,flags);
- kfree(intf);
- rv = 0;
- goto out_call_watcher;
- }
+ spin_lock_irqsave(&interfaces_lock, flags);
+ for (i = 0; i < MAX_IPMI_INTERFACES; i++) {
+ if (ipmi_interfaces[i] == intf) {
+ /* Set the interface number reserved until we
+ * are done. */
+ ipmi_interfaces[i] = IPMI_INVALID_INTERFACE_ENTRY;
+ intf->intf_num = -1;
+ break;
}
- } else {
- rv = -EBUSY;
}
- up_write(&interfaces_sem);
+ spin_unlock_irqrestore(&interfaces_lock,flags);
- return rv;
+ if (i == MAX_IPMI_INTERFACES)
+ return -ENODEV;
- out_call_watcher:
- downgrade_write(&interfaces_sem);
+ remove_proc_entries(intf);
/* Call all the watcher interfaces to tell them that
an interface is gone. */
down_read(&smi_watchers_sem);
- list_for_each_entry(w, &smi_watchers, link) {
+ list_for_each_entry(w, &smi_watchers, link)
w->smi_gone(i);
- }
up_read(&smi_watchers_sem);
- up_read(&interfaces_sem);
+
+ /* Allow the entry to be reused now. */
+ spin_lock_irqsave(&interfaces_lock, flags);
+ ipmi_interfaces[i] = NULL;
+ spin_unlock_irqrestore(&interfaces_lock,flags);
+
+ kref_put(&intf->refcount, intf_free);
return 0;
}
@@ -1998,14 +2032,14 @@ static int handle_ipmb_get_msg_rsp(ipmi_smi_t intf,
static int handle_ipmb_get_msg_cmd(ipmi_smi_t intf,
struct ipmi_smi_msg *msg)
{
- struct cmd_rcvr *rcvr;
- int rv = 0;
- unsigned char netfn;
- unsigned char cmd;
- ipmi_user_t user = NULL;
- struct ipmi_ipmb_addr *ipmb_addr;
- struct ipmi_recv_msg *recv_msg;
- unsigned long flags;
+ struct cmd_rcvr *rcvr;
+ int rv = 0;
+ unsigned char netfn;
+ unsigned char cmd;
+ ipmi_user_t user = NULL;
+ struct ipmi_ipmb_addr *ipmb_addr;
+ struct ipmi_recv_msg *recv_msg;
+ unsigned long flags;
if (msg->rsp_size < 10) {
/* Message not big enough, just ignore it. */
@@ -2023,16 +2057,14 @@ static int handle_ipmb_get_msg_cmd(ipmi_smi_t intf,
netfn = msg->rsp[4] >> 2;
cmd = msg->rsp[8];
- read_lock(&(intf->cmd_rcvr_lock));
-
- /* Find the command/netfn. */
- list_for_each_entry(rcvr, &(intf->cmd_rcvrs), link) {
- if ((rcvr->netfn == netfn) && (rcvr->cmd == cmd)) {
- user = rcvr->user;
- break;
- }
- }
- read_unlock(&(intf->cmd_rcvr_lock));
+ rcu_read_lock();
+ rcvr = find_cmd_rcvr(intf, netfn, cmd);
+ if (rcvr) {
+ user = rcvr->user;
+ kref_get(&user->refcount);
+ } else
+ user = NULL;
+ rcu_read_unlock();
if (user == NULL) {
/* We didn't find a user, deliver an error response. */
@@ -2079,6 +2111,7 @@ static int handle_ipmb_get_msg_cmd(ipmi_smi_t intf,
message, so requeue it for handling
later. */
rv = 1;
+ kref_put(&user->refcount, free_user);
} else {
/* Extract the source address from the data. */
ipmb_addr = (struct ipmi_ipmb_addr *) &recv_msg->addr;
@@ -2179,14 +2212,14 @@ static int handle_lan_get_msg_rsp(ipmi_smi_t intf,
static int handle_lan_get_msg_cmd(ipmi_smi_t intf,
struct ipmi_smi_msg *msg)
{
- struct cmd_rcvr *rcvr;
- int rv = 0;
- unsigned char netfn;
- unsigned char cmd;
- ipmi_user_t user = NULL;
- struct ipmi_lan_addr *lan_addr;
- struct ipmi_recv_msg *recv_msg;
- unsigned long flags;
+ struct cmd_rcvr *rcvr;
+ int rv = 0;
+ unsigned char netfn;
+ unsigned char cmd;
+ ipmi_user_t user = NULL;
+ struct ipmi_lan_addr *lan_addr;
+ struct ipmi_recv_msg *recv_msg;
+ unsigned long flags;
if (msg->rsp_size < 12) {
/* Message not big enough, just ignore it. */
@@ -2204,19 +2237,17 @@ static int handle_lan_get_msg_cmd(ipmi_smi_t intf,
netfn = msg->rsp[6] >> 2;
cmd = msg->rsp[10];
- read_lock(&(intf->cmd_rcvr_lock));
-
- /* Find the command/netfn. */
- list_for_each_entry(rcvr, &(intf->cmd_rcvrs), link) {
- if ((rcvr->netfn == netfn) && (rcvr->cmd == cmd)) {
- user = rcvr->user;
- break;
- }
- }
- read_unlock(&(intf->cmd_rcvr_lock));
+ rcu_read_lock();
+ rcvr = find_cmd_rcvr(intf, netfn, cmd);
+ if (rcvr) {
+ user = rcvr->user;
+ kref_get(&user->refcount);
+ } else
+ user = NULL;
+ rcu_read_unlock();
if (user == NULL) {
- /* We didn't find a user, deliver an error response. */
+ /* We didn't find a user, just give up. */
spin_lock_irqsave(&intf->counter_lock, flags);
intf->unhandled_commands++;
spin_unlock_irqrestore(&intf->counter_lock, flags);
@@ -2235,6 +2266,7 @@ static int handle_lan_get_msg_cmd(ipmi_smi_t intf,
message, so requeue it for handling
later. */
rv = 1;
+ kref_put(&user->refcount, free_user);
} else {
/* Extract the source address from the data. */
lan_addr = (struct ipmi_lan_addr *) &recv_msg->addr;
@@ -2286,8 +2318,6 @@ static void copy_event_into_recv_msg(struct ipmi_recv_msg *recv_msg,
recv_msg->msg.data_len = msg->rsp_size - 3;
}
-/* This will be called with the intf->users_lock read-locked, so no need
- to do that here. */
static int handle_read_event_rsp(ipmi_smi_t intf,
struct ipmi_smi_msg *msg)
{
@@ -2313,7 +2343,7 @@ static int handle_read_event_rsp(ipmi_smi_t intf,
INIT_LIST_HEAD(&msgs);
- spin_lock_irqsave(&(intf->events_lock), flags);
+ spin_lock_irqsave(&intf->events_lock, flags);
spin_lock(&intf->counter_lock);
intf->events++;
@@ -2321,12 +2351,14 @@ static int handle_read_event_rsp(ipmi_smi_t intf,
/* Allocate and fill in one message for every user that is getting
events. */
- list_for_each_entry(user, &(intf->users), link) {
+ rcu_read_lock();
+ list_for_each_entry_rcu(user, &intf->users, link) {
if (! user->gets_events)
continue;
recv_msg = ipmi_alloc_recv_msg();
if (! recv_msg) {
+ rcu_read_unlock();
list_for_each_entry_safe(recv_msg, recv_msg2, &msgs, link) {
list_del(&recv_msg->link);
ipmi_free_recv_msg(recv_msg);
@@ -2342,8 +2374,10 @@ static int handle_read_event_rsp(ipmi_smi_t intf,
copy_event_into_recv_msg(recv_msg, msg);
recv_msg->user = user;
+ kref_get(&user->refcount);
list_add_tail(&(recv_msg->link), &msgs);
}
+ rcu_read_unlock();
if (deliver_count) {
/* Now deliver all the messages. */
@@ -2382,9 +2416,8 @@ static int handle_bmc_rsp(ipmi_smi_t intf,
struct ipmi_smi_msg *msg)
{
struct ipmi_recv_msg *recv_msg;
- int found = 0;
- struct ipmi_user *user;
unsigned long flags;
+ struct ipmi_user *user;
recv_msg = (struct ipmi_recv_msg *) msg->user_data;
if (recv_msg == NULL)
@@ -2396,16 +2429,9 @@ static int handle_bmc_rsp(ipmi_smi_t intf,
return 0;
}
+ user = recv_msg->user;
/* Make sure the user still exists. */
- list_for_each_entry(user, &(intf->users), link) {
- if (user == recv_msg->user) {
- /* Found it, so we can deliver it */
- found = 1;
- break;
- }
- }
-
- if ((! found) && recv_msg->user) {
+ if (user && !user->valid) {
/* The user for the message went away, so give up. */
spin_lock_irqsave(&intf->counter_lock, flags);
intf->unhandled_local_responses++;
@@ -2486,7 +2512,7 @@ static int handle_new_recv_msg(ipmi_smi_t intf,
{
/* It's a response to a response we sent. For this we
deliver a send message response to the user. */
- struct ipmi_recv_msg *recv_msg = msg->user_data;
+ struct ipmi_recv_msg *recv_msg = msg->user_data;
requeue = 0;
if (msg->rsp_size < 2)
@@ -2498,13 +2524,18 @@ static int handle_new_recv_msg(ipmi_smi_t intf,
/* Invalid channel number */
goto out;
- if (recv_msg) {
- recv_msg->recv_type = IPMI_RESPONSE_RESPONSE_TYPE;
- recv_msg->msg.data = recv_msg->msg_data;
- recv_msg->msg.data_len = 1;
- recv_msg->msg_data[0] = msg->rsp[2];
- deliver_response(recv_msg);
- }
+ if (!recv_msg)
+ goto out;
+
+ /* Make sure the user still exists. */
+ if (!recv_msg->user || !recv_msg->user->valid)
+ goto out;
+
+ recv_msg->recv_type = IPMI_RESPONSE_RESPONSE_TYPE;
+ recv_msg->msg.data = recv_msg->msg_data;
+ recv_msg->msg.data_len = 1;
+ recv_msg->msg_data[0] = msg->rsp[2];
+ deliver_response(recv_msg);
} else if ((msg->rsp[0] == ((IPMI_NETFN_APP_REQUEST|1) << 2))
&& (msg->rsp[1] == IPMI_GET_MSG_CMD))
{
@@ -2570,14 +2601,11 @@ void ipmi_smi_msg_received(ipmi_smi_t intf,
int rv;
- /* Lock the user lock so the user can't go away while we are
- working on it. */
- read_lock(&(intf->users_lock));
-
if ((msg->data_size >= 2)
&& (msg->data[0] == (IPMI_NETFN_APP_REQUEST << 2))
&& (msg->data[1] == IPMI_SEND_MSG_CMD)
- && (msg->user_data == NULL)) {
+ && (msg->user_data == NULL))
+ {
/* This is the local response to a command send, start
the timer for these. The user_data will not be
NULL if this is a response send, and we will let
@@ -2612,46 +2640,46 @@ void ipmi_smi_msg_received(ipmi_smi_t intf,
}
ipmi_free_smi_msg(msg);
- goto out_unlock;
+ goto out;
}
/* To preserve message order, if the list is not empty, we
tack this message onto the end of the list. */
- spin_lock_irqsave(&(intf->waiting_msgs_lock), flags);
- if (!list_empty(&(intf->waiting_msgs))) {
- list_add_tail(&(msg->link), &(intf->waiting_msgs));
- spin_unlock_irqrestore(&(intf->waiting_msgs_lock), flags);
- goto out_unlock;
+ spin_lock_irqsave(&intf->waiting_msgs_lock, flags);
+ if (!list_empty(&intf->waiting_msgs)) {
+ list_add_tail(&msg->link, &intf->waiting_msgs);
+ spin_unlock(&intf->waiting_msgs_lock);
+ goto out;
}
- spin_unlock_irqrestore(&(intf->waiting_msgs_lock), flags);
+ spin_unlock_irqrestore(&intf->waiting_msgs_lock, flags);
rv = handle_new_recv_msg(intf, msg);
if (rv > 0) {
/* Could not handle the message now, just add it to a
list to handle later. */
- spin_lock_irqsave(&(intf->waiting_msgs_lock), flags);
- list_add_tail(&(msg->link), &(intf->waiting_msgs));
- spin_unlock_irqrestore(&(intf->waiting_msgs_lock), flags);
+ spin_lock(&intf->waiting_msgs_lock);
+ list_add_tail(&msg->link, &intf->waiting_msgs);
+ spin_unlock(&intf->waiting_msgs_lock);
} else if (rv == 0) {
ipmi_free_smi_msg(msg);
}
- out_unlock:
- read_unlock(&(intf->users_lock));
+ out:
+ return;
}
void ipmi_smi_watchdog_pretimeout(ipmi_smi_t intf)
{
ipmi_user_t user;
- read_lock(&(intf->users_lock));
- list_for_each_entry(user, &(intf->users), link) {
+ rcu_read_lock();
+ list_for_each_entry_rcu(user, &intf->users, link) {
if (! user->handler->ipmi_watchdog_pretimeout)
continue;
user->handler->ipmi_watchdog_pretimeout(user->handler_data);
}
- read_unlock(&(intf->users_lock));
+ rcu_read_unlock();
}
static void
@@ -2691,8 +2719,65 @@ smi_from_recv_msg(ipmi_smi_t intf, struct ipmi_recv_msg *recv_msg,
return smi_msg;
}
-static void
-ipmi_timeout_handler(long timeout_period)
+static void check_msg_timeout(ipmi_smi_t intf, struct seq_table *ent,
+ struct list_head *timeouts, long timeout_period,
+ int slot, unsigned long *flags)
+{
+ struct ipmi_recv_msg *msg;
+
+ if (!ent->inuse)
+ return;
+
+ ent->timeout -= timeout_period;
+ if (ent->timeout > 0)
+ return;
+
+ if (ent->retries_left == 0) {
+ /* The message has used all its retries. */
+ ent->inuse = 0;
+ msg = ent->recv_msg;
+ list_add_tail(&msg->link, timeouts);
+ spin_lock(&intf->counter_lock);
+ if (ent->broadcast)
+ intf->timed_out_ipmb_broadcasts++;
+ else if (ent->recv_msg->addr.addr_type == IPMI_LAN_ADDR_TYPE)
+ intf->timed_out_lan_commands++;
+ else
+ intf->timed_out_ipmb_commands++;
+ spin_unlock(&intf->counter_lock);
+ } else {
+ struct ipmi_smi_msg *smi_msg;
+ /* More retries, send again. */
+
+ /* Start with the max timer, set to normal
+ timer after the message is sent. */
+ ent->timeout = MAX_MSG_TIMEOUT;
+ ent->retries_left--;
+ spin_lock(&intf->counter_lock);
+ if (ent->recv_msg->addr.addr_type == IPMI_LAN_ADDR_TYPE)
+ intf->retransmitted_lan_commands++;
+ else
+ intf->retransmitted_ipmb_commands++;
+ spin_unlock(&intf->counter_lock);
+
+ smi_msg = smi_from_recv_msg(intf, ent->recv_msg, slot,
+ ent->seqid);
+ if (! smi_msg)
+ return;
+
+ spin_unlock_irqrestore(&intf->seq_lock, *flags);
+ /* Send the new message. We send with a zero
+ * priority. It timed out, I doubt time is
+ * that critical now, and high priority
+ * messages are really only for messages to the
+ * local MC, which don't get resent. */
+ intf->handlers->sender(intf->send_info,
+ smi_msg, 0);
+ spin_lock_irqsave(&intf->seq_lock, *flags);
+ }
+}
+
+static void ipmi_timeout_handler(long timeout_period)
{
ipmi_smi_t intf;
struct list_head timeouts;
@@ -2706,14 +2791,14 @@ ipmi_timeout_handler(long timeout_period)
spin_lock(&interfaces_lock);
for (i = 0; i < MAX_IPMI_INTERFACES; i++) {
intf = ipmi_interfaces[i];
- if (intf == NULL)
+ if (IPMI_INVALID_INTERFACE(intf))
continue;
-
- read_lock(&(intf->users_lock));
+ kref_get(&intf->refcount);
+ spin_unlock(&interfaces_lock);
/* See if any waiting messages need to be processed. */
- spin_lock_irqsave(&(intf->waiting_msgs_lock), flags);
- list_for_each_entry_safe(smi_msg, smi_msg2, &(intf->waiting_msgs), link) {
+ spin_lock_irqsave(&intf->waiting_msgs_lock, flags);
+ list_for_each_entry_safe(smi_msg, smi_msg2, &intf->waiting_msgs, link) {
if (! handle_new_recv_msg(intf, smi_msg)) {
list_del(&smi_msg->link);
ipmi_free_smi_msg(smi_msg);
@@ -2723,73 +2808,23 @@ ipmi_timeout_handler(long timeout_period)
break;
}
}
- spin_unlock_irqrestore(&(intf->waiting_msgs_lock), flags);
+ spin_unlock_irqrestore(&intf->waiting_msgs_lock, flags);
/* Go through the seq table and find any messages that
have timed out, putting them in the timeouts
list. */
- spin_lock_irqsave(&(intf->seq_lock), flags);
- for (j = 0; j < IPMI_IPMB_NUM_SEQ; j++) {
- struct seq_table *ent = &(intf->seq_table[j]);
- if (!ent->inuse)
- continue;
-
- ent->timeout -= timeout_period;
- if (ent->timeout > 0)
- continue;
-
- if (ent->retries_left == 0) {
- /* The message has used all its retries. */
- ent->inuse = 0;
- msg = ent->recv_msg;
- list_add_tail(&(msg->link), &timeouts);
- spin_lock(&intf->counter_lock);
- if (ent->broadcast)
- intf->timed_out_ipmb_broadcasts++;
- else if (ent->recv_msg->addr.addr_type
- == IPMI_LAN_ADDR_TYPE)
- intf->timed_out_lan_commands++;
- else
- intf->timed_out_ipmb_commands++;
- spin_unlock(&intf->counter_lock);
- } else {
- struct ipmi_smi_msg *smi_msg;
- /* More retries, send again. */
-
- /* Start with the max timer, set to normal
- timer after the message is sent. */
- ent->timeout = MAX_MSG_TIMEOUT;
- ent->retries_left--;
- spin_lock(&intf->counter_lock);
- if (ent->recv_msg->addr.addr_type
- == IPMI_LAN_ADDR_TYPE)
- intf->retransmitted_lan_commands++;
- else
- intf->retransmitted_ipmb_commands++;
- spin_unlock(&intf->counter_lock);
- smi_msg = smi_from_recv_msg(intf,
- ent->recv_msg, j, ent->seqid);
- if (! smi_msg)
- continue;
-
- spin_unlock_irqrestore(&(intf->seq_lock),flags);
- /* Send the new message. We send with a zero
- * priority. It timed out, I doubt time is
- * that critical now, and high priority
- * messages are really only for messages to the
- * local MC, which don't get resent. */
- intf->handlers->sender(intf->send_info,
- smi_msg, 0);
- spin_lock_irqsave(&(intf->seq_lock), flags);
- }
- }
- spin_unlock_irqrestore(&(intf->seq_lock), flags);
-
- list_for_each_entry_safe(msg, msg2, &timeouts, link) {
+ spin_lock_irqsave(&intf->seq_lock, flags);
+ for (j = 0; j < IPMI_IPMB_NUM_SEQ; j++)
+ check_msg_timeout(intf, &(intf->seq_table[j]),
+ &timeouts, timeout_period, j,
+ &flags);
+ spin_unlock_irqrestore(&intf->seq_lock, flags);
+
+ list_for_each_entry_safe(msg, msg2, &timeouts, link)
handle_msg_timeout(msg);
- }
- read_unlock(&(intf->users_lock));
+ kref_put(&intf->refcount, intf_free);
+ spin_lock(&interfaces_lock);
}
spin_unlock(&interfaces_lock);
}
@@ -2802,7 +2837,7 @@ static void ipmi_request_event(void)
spin_lock(&interfaces_lock);
for (i = 0; i < MAX_IPMI_INTERFACES; i++) {
intf = ipmi_interfaces[i];
- if (intf == NULL)
+ if (IPMI_INVALID_INTERFACE(intf))
continue;
intf->handlers->request_events(intf->send_info);
@@ -2884,6 +2919,13 @@ struct ipmi_recv_msg *ipmi_alloc_recv_msg(void)
return rv;
}
+void ipmi_free_recv_msg(struct ipmi_recv_msg *msg)
+{
+ if (msg->user)
+ kref_put(&msg->user->refcount, free_user);
+ msg->done(msg);
+}
+
#ifdef CONFIG_IPMI_PANIC_EVENT
static void dummy_smi_done_handler(struct ipmi_smi_msg *msg)
@@ -2964,7 +3006,7 @@ static void send_panic_events(char *str)
/* For every registered interface, send the event. */
for (i = 0; i < MAX_IPMI_INTERFACES; i++) {
intf = ipmi_interfaces[i];
- if (intf == NULL)
+ if (IPMI_INVALID_INTERFACE(intf))
continue;
/* Send the event announcing the panic. */
@@ -2995,7 +3037,7 @@ static void send_panic_events(char *str)
int j;
intf = ipmi_interfaces[i];
- if (intf == NULL)
+ if (IPMI_INVALID_INTERFACE(intf))
continue;
/* First job here is to figure out where to send the
@@ -3131,7 +3173,7 @@ static int panic_event(struct notifier_block *this,
/* For every registered interface, set it to run to completion. */
for (i = 0; i < MAX_IPMI_INTERFACES; i++) {
intf = ipmi_interfaces[i];
- if (intf == NULL)
+ if (IPMI_INVALID_INTERFACE(intf))
continue;
intf->handlers->set_run_to_completion(intf->send_info, 1);
@@ -3160,9 +3202,8 @@ static int ipmi_init_msghandler(void)
printk(KERN_INFO "ipmi message handler version "
IPMI_DRIVER_VERSION "\n");
- for (i = 0; i < MAX_IPMI_INTERFACES; i++) {
+ for (i = 0; i < MAX_IPMI_INTERFACES; i++)
ipmi_interfaces[i] = NULL;
- }
#ifdef CONFIG_PROC_FS
proc_ipmi_root = proc_mkdir("ipmi", NULL);
@@ -3258,3 +3299,4 @@ EXPORT_SYMBOL(ipmi_get_my_LUN);
EXPORT_SYMBOL(ipmi_smi_add_proc_entry);
EXPORT_SYMBOL(proc_ipmi_root);
EXPORT_SYMBOL(ipmi_user_set_run_to_completion);
+EXPORT_SYMBOL(ipmi_free_recv_msg);
diff --git a/drivers/char/ipmi/ipmi_poweroff.c b/drivers/char/ipmi/ipmi_poweroff.c
index f66947722e12..e053eade0366 100644
--- a/drivers/char/ipmi/ipmi_poweroff.c
+++ b/drivers/char/ipmi/ipmi_poweroff.c
@@ -56,7 +56,7 @@ static int poweroff_powercycle;
/* parameter definition to allow user to flag power cycle */
module_param(poweroff_powercycle, int, 0644);
-MODULE_PARM_DESC(poweroff_powercycles, " Set to non-zero to enable power cycle instead of power down. Power cycle is contingent on hardware support, otherwise it defaults back to power down.");
+MODULE_PARM_DESC(poweroff_powercycle, " Set to non-zero to enable power cycle instead of power down. Power cycle is contingent on hardware support, otherwise it defaults back to power down.");
/* Stuff from the get device id command. */
static unsigned int mfg_id;
@@ -611,9 +611,7 @@ static int ipmi_poweroff_init (void)
}
#endif
-#ifdef CONFIG_PROC_FS
rv = ipmi_smi_watcher_register(&smi_watcher);
-#endif
if (rv) {
unregister_sysctl_table(ipmi_table_header);
printk(KERN_ERR PFX "Unable to register SMI watcher: %d\n", rv);
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c
index b6e5cbfb09f8..ea89dca3dbb5 100644
--- a/drivers/char/ipmi/ipmi_si_intf.c
+++ b/drivers/char/ipmi/ipmi_si_intf.c
@@ -51,6 +51,8 @@
#include <linux/list.h>
#include <linux/pci.h>
#include <linux/ioport.h>
+#include <linux/notifier.h>
+#include <linux/kthread.h>
#include <asm/irq.h>
#ifdef CONFIG_HIGH_RES_TIMERS
#include <linux/hrtime.h>
@@ -125,6 +127,7 @@ struct ipmi_device_id {
struct smi_info
{
+ int intf_num;
ipmi_smi_t intf;
struct si_sm_data *si_sm;
struct si_sm_handlers *handlers;
@@ -192,8 +195,7 @@ struct smi_info
unsigned long last_timeout_jiffies;
/* Used to gracefully stop the timer without race conditions. */
- volatile int stop_operation;
- volatile int timer_stopped;
+ atomic_t stop_operation;
/* The driver will disable interrupts when it gets into a
situation where it cannot handle messages due to lack of
@@ -220,8 +222,16 @@ struct smi_info
unsigned long events;
unsigned long watchdog_pretimeouts;
unsigned long incoming_messages;
+
+ struct task_struct *thread;
};
+static struct notifier_block *xaction_notifier_list;
+static int register_xaction_notifier(struct notifier_block * nb)
+{
+ return notifier_chain_register(&xaction_notifier_list, nb);
+}
+
static void si_restart_short_timer(struct smi_info *smi_info);
static void deliver_recv_msg(struct smi_info *smi_info,
@@ -281,6 +291,11 @@ static enum si_sm_result start_next_msg(struct smi_info *smi_info)
do_gettimeofday(&t);
printk("**Start2: %d.%9.9d\n", t.tv_sec, t.tv_usec);
#endif
+ err = notifier_call_chain(&xaction_notifier_list, 0, smi_info);
+ if (err & NOTIFY_STOP_MASK) {
+ rv = SI_SM_CALL_WITHOUT_DELAY;
+ goto out;
+ }
err = smi_info->handlers->start_transaction(
smi_info->si_sm,
smi_info->curr_msg->data,
@@ -291,6 +306,7 @@ static enum si_sm_result start_next_msg(struct smi_info *smi_info)
rv = SI_SM_CALL_WITHOUT_DELAY;
}
+ out:
spin_unlock(&(smi_info->msg_lock));
return rv;
@@ -766,6 +782,29 @@ static void set_run_to_completion(void *send_info, int i_run_to_completion)
spin_unlock_irqrestore(&(smi_info->si_lock), flags);
}
+static int ipmi_thread(void *data)
+{
+ struct smi_info *smi_info = data;
+ unsigned long flags;
+ enum si_sm_result smi_result;
+
+ set_user_nice(current, 19);
+ while (!kthread_should_stop()) {
+ spin_lock_irqsave(&(smi_info->si_lock), flags);
+ smi_result=smi_event_handler(smi_info, 0);
+ spin_unlock_irqrestore(&(smi_info->si_lock), flags);
+ if (smi_result == SI_SM_CALL_WITHOUT_DELAY) {
+ /* do nothing */
+ }
+ else if (smi_result == SI_SM_CALL_WITH_DELAY)
+ udelay(1);
+ else
+ schedule_timeout_interruptible(1);
+ }
+ return 0;
+}
+
+
static void poll(void *send_info)
{
struct smi_info *smi_info = send_info;
@@ -819,15 +858,13 @@ static void smi_timeout(unsigned long data)
enum si_sm_result smi_result;
unsigned long flags;
unsigned long jiffies_now;
- unsigned long time_diff;
+ long time_diff;
#ifdef DEBUG_TIMING
struct timeval t;
#endif
- if (smi_info->stop_operation) {
- smi_info->timer_stopped = 1;
+ if (atomic_read(&smi_info->stop_operation))
return;
- }
spin_lock_irqsave(&(smi_info->si_lock), flags);
#ifdef DEBUG_TIMING
@@ -835,7 +872,7 @@ static void smi_timeout(unsigned long data)
printk("**Timer: %d.%9.9d\n", t.tv_sec, t.tv_usec);
#endif
jiffies_now = jiffies;
- time_diff = ((jiffies_now - smi_info->last_timeout_jiffies)
+ time_diff = (((long)jiffies_now - (long)smi_info->last_timeout_jiffies)
* SI_USEC_PER_JIFFY);
smi_result = smi_event_handler(smi_info, time_diff);
@@ -900,7 +937,7 @@ static irqreturn_t si_irq_handler(int irq, void *data, struct pt_regs *regs)
smi_info->interrupts++;
spin_unlock(&smi_info->count_lock);
- if (smi_info->stop_operation)
+ if (atomic_read(&smi_info->stop_operation))
goto out;
#ifdef DEBUG_TIMING
@@ -1419,7 +1456,7 @@ static u32 ipmi_acpi_gpe(void *context)
smi_info->interrupts++;
spin_unlock(&smi_info->count_lock);
- if (smi_info->stop_operation)
+ if (atomic_read(&smi_info->stop_operation))
goto out;
#ifdef DEBUG_TIMING
@@ -1919,7 +1956,8 @@ static int try_get_dev_id(struct smi_info *smi_info)
smi_result = smi_info->handlers->event(smi_info->si_sm, 0);
for (;;)
{
- if (smi_result == SI_SM_CALL_WITH_DELAY) {
+ if (smi_result == SI_SM_CALL_WITH_DELAY ||
+ smi_result == SI_SM_CALL_WITH_TICK_DELAY) {
schedule_timeout_uninterruptible(1);
smi_result = smi_info->handlers->event(
smi_info->si_sm, 100);
@@ -2052,6 +2090,9 @@ static int oem_data_avail_to_receive_msg_avail(struct smi_info *smi_info)
* IPMI Version = 0x51 IPMI 1.5
* Manufacturer ID = A2 02 00 Dell IANA
*
+ * Additionally, PowerEdge systems with IPMI < 1.5 may also assert
+ * OEM0_DATA_AVAIL and needs to be treated as RECEIVE_MSG_AVAIL.
+ *
*/
#define DELL_POWEREDGE_8G_BMC_DEVICE_ID 0x20
#define DELL_POWEREDGE_8G_BMC_DEVICE_REV 0x80
@@ -2061,16 +2102,87 @@ static void setup_dell_poweredge_oem_data_handler(struct smi_info *smi_info)
{
struct ipmi_device_id *id = &smi_info->device_id;
const char mfr[3]=DELL_IANA_MFR_ID;
- if (! memcmp(mfr, id->manufacturer_id, sizeof(mfr))
- && (id->device_id == DELL_POWEREDGE_8G_BMC_DEVICE_ID)
- && (id->device_revision == DELL_POWEREDGE_8G_BMC_DEVICE_REV)
- && (id->ipmi_version == DELL_POWEREDGE_8G_BMC_IPMI_VERSION))
- {
- smi_info->oem_data_avail_handler =
- oem_data_avail_to_receive_msg_avail;
+ if (! memcmp(mfr, id->manufacturer_id, sizeof(mfr))) {
+ if (id->device_id == DELL_POWEREDGE_8G_BMC_DEVICE_ID &&
+ id->device_revision == DELL_POWEREDGE_8G_BMC_DEVICE_REV &&
+ id->ipmi_version == DELL_POWEREDGE_8G_BMC_IPMI_VERSION) {
+ smi_info->oem_data_avail_handler =
+ oem_data_avail_to_receive_msg_avail;
+ }
+ else if (ipmi_version_major(id) < 1 ||
+ (ipmi_version_major(id) == 1 &&
+ ipmi_version_minor(id) < 5)) {
+ smi_info->oem_data_avail_handler =
+ oem_data_avail_to_receive_msg_avail;
+ }
}
}
+#define CANNOT_RETURN_REQUESTED_LENGTH 0xCA
+static void return_hosed_msg_badsize(struct smi_info *smi_info)
+{
+ struct ipmi_smi_msg *msg = smi_info->curr_msg;
+
+ /* Make it a reponse */
+ msg->rsp[0] = msg->data[0] | 4;
+ msg->rsp[1] = msg->data[1];
+ msg->rsp[2] = CANNOT_RETURN_REQUESTED_LENGTH;
+ msg->rsp_size = 3;
+ smi_info->curr_msg = NULL;
+ deliver_recv_msg(smi_info, msg);
+}
+
+/*
+ * dell_poweredge_bt_xaction_handler
+ * @info - smi_info.device_id must be populated
+ *
+ * Dell PowerEdge servers with the BT interface (x6xx and 1750) will
+ * not respond to a Get SDR command if the length of the data
+ * requested is exactly 0x3A, which leads to command timeouts and no
+ * data returned. This intercepts such commands, and causes userspace
+ * callers to try again with a different-sized buffer, which succeeds.
+ */
+
+#define STORAGE_NETFN 0x0A
+#define STORAGE_CMD_GET_SDR 0x23
+static int dell_poweredge_bt_xaction_handler(struct notifier_block *self,
+ unsigned long unused,
+ void *in)
+{
+ struct smi_info *smi_info = in;
+ unsigned char *data = smi_info->curr_msg->data;
+ unsigned int size = smi_info->curr_msg->data_size;
+ if (size >= 8 &&
+ (data[0]>>2) == STORAGE_NETFN &&
+ data[1] == STORAGE_CMD_GET_SDR &&
+ data[7] == 0x3A) {
+ return_hosed_msg_badsize(smi_info);
+ return NOTIFY_STOP;
+ }
+ return NOTIFY_DONE;
+}
+
+static struct notifier_block dell_poweredge_bt_xaction_notifier = {
+ .notifier_call = dell_poweredge_bt_xaction_handler,
+};
+
+/*
+ * setup_dell_poweredge_bt_xaction_handler
+ * @info - smi_info.device_id must be filled in already
+ *
+ * Fills in smi_info.device_id.start_transaction_pre_hook
+ * when we know what function to use there.
+ */
+static void
+setup_dell_poweredge_bt_xaction_handler(struct smi_info *smi_info)
+{
+ struct ipmi_device_id *id = &smi_info->device_id;
+ const char mfr[3]=DELL_IANA_MFR_ID;
+ if (! memcmp(mfr, id->manufacturer_id, sizeof(mfr)) &&
+ smi_info->si_type == SI_BT)
+ register_xaction_notifier(&dell_poweredge_bt_xaction_notifier);
+}
+
/*
* setup_oem_data_handler
* @info - smi_info.device_id must be filled in already
@@ -2084,6 +2196,18 @@ static void setup_oem_data_handler(struct smi_info *smi_info)
setup_dell_poweredge_oem_data_handler(smi_info);
}
+static void setup_xaction_handlers(struct smi_info *smi_info)
+{
+ setup_dell_poweredge_bt_xaction_handler(smi_info);
+}
+
+static inline void wait_for_timer_and_thread(struct smi_info *smi_info)
+{
+ if (smi_info->thread != ERR_PTR(-ENOMEM))
+ kthread_stop(smi_info->thread);
+ del_timer_sync(&smi_info->si_timer);
+}
+
/* Returns 0 if initialized, or negative on an error. */
static int init_one_smi(int intf_num, struct smi_info **smi)
{
@@ -2179,6 +2303,7 @@ static int init_one_smi(int intf_num, struct smi_info **smi)
goto out_err;
setup_oem_data_handler(new_smi);
+ setup_xaction_handlers(new_smi);
/* Try to claim any interrupts. */
new_smi->irq_setup(new_smi);
@@ -2190,8 +2315,8 @@ static int init_one_smi(int intf_num, struct smi_info **smi)
new_smi->run_to_completion = 0;
new_smi->interrupt_disabled = 0;
- new_smi->timer_stopped = 0;
- new_smi->stop_operation = 0;
+ atomic_set(&new_smi->stop_operation, 0);
+ new_smi->intf_num = intf_num;
/* Start clearing the flags before we enable interrupts or the
timer to avoid racing with the timer. */
@@ -2209,7 +2334,11 @@ static int init_one_smi(int intf_num, struct smi_info **smi)
new_smi->si_timer.function = smi_timeout;
new_smi->last_timeout_jiffies = jiffies;
new_smi->si_timer.expires = jiffies + SI_TIMEOUT_JIFFIES;
+
add_timer(&(new_smi->si_timer));
+ if (new_smi->si_type != SI_BT)
+ new_smi->thread = kthread_run(ipmi_thread, new_smi,
+ "kipmi%d", new_smi->intf_num);
rv = ipmi_register_smi(&handlers,
new_smi,
@@ -2251,12 +2380,8 @@ static int init_one_smi(int intf_num, struct smi_info **smi)
return 0;
out_err_stop_timer:
- new_smi->stop_operation = 1;
-
- /* Wait for the timer to stop. This avoids problems with race
- conditions removing the timer here. */
- while (!new_smi->timer_stopped)
- schedule_timeout_uninterruptible(1);
+ atomic_inc(&new_smi->stop_operation);
+ wait_for_timer_and_thread(new_smi);
out_err:
if (new_smi->intf)
@@ -2362,8 +2487,7 @@ static void __exit cleanup_one_si(struct smi_info *to_clean)
spin_lock_irqsave(&(to_clean->si_lock), flags);
spin_lock(&(to_clean->msg_lock));
- to_clean->stop_operation = 1;
-
+ atomic_inc(&to_clean->stop_operation);
to_clean->irq_cleanup(to_clean);
spin_unlock(&(to_clean->msg_lock));
@@ -2374,10 +2498,7 @@ static void __exit cleanup_one_si(struct smi_info *to_clean)
interrupt. */
synchronize_sched();
- /* Wait for the timer to stop. This avoids problems with race
- conditions removing the timer here. */
- while (!to_clean->timer_stopped)
- schedule_timeout_uninterruptible(1);
+ wait_for_timer_and_thread(to_clean);
/* Interrupts and timeouts are stopped, now make sure the
interface is in a clean state. */
diff --git a/drivers/char/ipmi/ipmi_si_sm.h b/drivers/char/ipmi/ipmi_si_sm.h
index 62791dd42985..bf3d4962d6a5 100644
--- a/drivers/char/ipmi/ipmi_si_sm.h
+++ b/drivers/char/ipmi/ipmi_si_sm.h
@@ -62,6 +62,7 @@ enum si_sm_result
{
SI_SM_CALL_WITHOUT_DELAY, /* Call the driver again immediately */
SI_SM_CALL_WITH_DELAY, /* Delay some before calling again. */
+ SI_SM_CALL_WITH_TICK_DELAY, /* Delay at least 1 tick before calling again. */
SI_SM_TRANSACTION_COMPLETE, /* A transaction is finished. */
SI_SM_IDLE, /* The SM is in idle state. */
SI_SM_HOSED, /* The hardware violated the state machine. */
diff --git a/drivers/char/ipmi/ipmi_smic_sm.c b/drivers/char/ipmi/ipmi_smic_sm.c
index add2aa2732f0..39d7e5ef1a2b 100644
--- a/drivers/char/ipmi/ipmi_smic_sm.c
+++ b/drivers/char/ipmi/ipmi_smic_sm.c
@@ -43,6 +43,8 @@
#include <linux/kernel.h> /* For printk. */
#include <linux/string.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
#include <linux/ipmi_msgdefs.h> /* for completion codes */
#include "ipmi_si_sm.h"
@@ -56,6 +58,8 @@
#define SMIC_DEBUG_ENABLE 1
static int smic_debug = 1;
+module_param(smic_debug, int, 0644);
+MODULE_PARM_DESC(smic_debug, "debug bitmask, 1=enable, 2=messages, 4=states");
enum smic_states {
SMIC_IDLE,
@@ -76,11 +80,17 @@ enum smic_states {
#define SMIC_MAX_ERROR_RETRIES 3
/* Timeouts in microseconds. */
-#define SMIC_RETRY_TIMEOUT 100000
+#define SMIC_RETRY_TIMEOUT 2000000
/* SMIC Flags Register Bits */
#define SMIC_RX_DATA_READY 0x80
#define SMIC_TX_DATA_READY 0x40
+/*
+ * SMIC_SMI and SMIC_EVM_DATA_AVAIL are only used by
+ * a few systems, and then only by Systems Management
+ * Interrupts, not by the OS. Always ignore these bits.
+ *
+ */
#define SMIC_SMI 0x10
#define SMIC_EVM_DATA_AVAIL 0x08
#define SMIC_SMS_DATA_AVAIL 0x04
@@ -364,8 +374,7 @@ static enum si_sm_result smic_event (struct si_sm_data *smic, long time)
switch (smic->state) {
case SMIC_IDLE:
/* in IDLE we check for available messages */
- if (flags & (SMIC_SMI |
- SMIC_EVM_DATA_AVAIL | SMIC_SMS_DATA_AVAIL))
+ if (flags & SMIC_SMS_DATA_AVAIL)
{
return SI_SM_ATTN;
}
diff --git a/drivers/char/ipmi/ipmi_watchdog.c b/drivers/char/ipmi/ipmi_watchdog.c
index 2da64bf7469c..1f3159eb1ede 100644
--- a/drivers/char/ipmi/ipmi_watchdog.c
+++ b/drivers/char/ipmi/ipmi_watchdog.c
@@ -47,6 +47,9 @@
#include <linux/reboot.h>
#include <linux/wait.h>
#include <linux/poll.h>
+#include <linux/string.h>
+#include <linux/ctype.h>
+#include <asm/atomic.h>
#ifdef CONFIG_X86_LOCAL_APIC
#include <asm/apic.h>
#endif
@@ -158,27 +161,120 @@ static struct fasync_struct *fasync_q = NULL;
static char pretimeout_since_last_heartbeat = 0;
static char expect_close;
+static DECLARE_RWSEM(register_sem);
+
+/* Parameters to ipmi_set_timeout */
+#define IPMI_SET_TIMEOUT_NO_HB 0
+#define IPMI_SET_TIMEOUT_HB_IF_NECESSARY 1
+#define IPMI_SET_TIMEOUT_FORCE_HB 2
+
+static int ipmi_set_timeout(int do_heartbeat);
+
/* If true, the driver will start running as soon as it is configured
and ready. */
static int start_now = 0;
-module_param(timeout, int, 0);
+static int set_param_int(const char *val, struct kernel_param *kp)
+{
+ char *endp;
+ int l;
+ int rv = 0;
+
+ if (!val)
+ return -EINVAL;
+ l = simple_strtoul(val, &endp, 0);
+ if (endp == val)
+ return -EINVAL;
+
+ down_read(&register_sem);
+ *((int *)kp->arg) = l;
+ if (watchdog_user)
+ rv = ipmi_set_timeout(IPMI_SET_TIMEOUT_HB_IF_NECESSARY);
+ up_read(&register_sem);
+
+ return rv;
+}
+
+static int get_param_int(char *buffer, struct kernel_param *kp)
+{
+ return sprintf(buffer, "%i", *((int *)kp->arg));
+}
+
+typedef int (*action_fn)(const char *intval, char *outval);
+
+static int action_op(const char *inval, char *outval);
+static int preaction_op(const char *inval, char *outval);
+static int preop_op(const char *inval, char *outval);
+static void check_parms(void);
+
+static int set_param_str(const char *val, struct kernel_param *kp)
+{
+ action_fn fn = (action_fn) kp->arg;
+ int rv = 0;
+ const char *end;
+ char valcp[16];
+ int len;
+
+ /* Truncate leading and trailing spaces. */
+ while (isspace(*val))
+ val++;
+ end = val + strlen(val) - 1;
+ while ((end >= val) && isspace(*end))
+ end--;
+ len = end - val + 1;
+ if (len > sizeof(valcp) - 1)
+ return -EINVAL;
+ memcpy(valcp, val, len);
+ valcp[len] = '\0';
+
+ down_read(&register_sem);
+ rv = fn(valcp, NULL);
+ if (rv)
+ goto out_unlock;
+
+ check_parms();
+ if (watchdog_user)
+ rv = ipmi_set_timeout(IPMI_SET_TIMEOUT_HB_IF_NECESSARY);
+
+ out_unlock:
+ up_read(&register_sem);
+ return rv;
+}
+
+static int get_param_str(char *buffer, struct kernel_param *kp)
+{
+ action_fn fn = (action_fn) kp->arg;
+ int rv;
+
+ rv = fn(NULL, buffer);
+ if (rv)
+ return rv;
+ return strlen(buffer);
+}
+
+module_param_call(timeout, set_param_int, get_param_int, &timeout, 0644);
MODULE_PARM_DESC(timeout, "Timeout value in seconds.");
-module_param(pretimeout, int, 0);
+
+module_param_call(pretimeout, set_param_int, get_param_int, &pretimeout, 0644);
MODULE_PARM_DESC(pretimeout, "Pretimeout value in seconds.");
-module_param_string(action, action, sizeof(action), 0);
+
+module_param_call(action, set_param_str, get_param_str, action_op, 0644);
MODULE_PARM_DESC(action, "Timeout action. One of: "
"reset, none, power_cycle, power_off.");
-module_param_string(preaction, preaction, sizeof(preaction), 0);
+
+module_param_call(preaction, set_param_str, get_param_str, preaction_op, 0644);
MODULE_PARM_DESC(preaction, "Pretimeout action. One of: "
"pre_none, pre_smi, pre_nmi, pre_int.");
-module_param_string(preop, preop, sizeof(preop), 0);
+
+module_param_call(preop, set_param_str, get_param_str, preop_op, 0644);
MODULE_PARM_DESC(preop, "Pretimeout driver operation. One of: "
"preop_none, preop_panic, preop_give_data.");
+
module_param(start_now, int, 0);
MODULE_PARM_DESC(start_now, "Set to 1 to start the watchdog as"
"soon as the driver is loaded.");
-module_param(nowayout, int, 0);
+
+module_param(nowayout, int, 0644);
MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
/* Default state of the timer. */
@@ -200,6 +296,8 @@ static int ipmi_start_timer_on_heartbeat = 0;
static unsigned char ipmi_version_major;
static unsigned char ipmi_version_minor;
+/* If a pretimeout occurs, this is used to allow only one panic to happen. */
+static atomic_t preop_panic_excl = ATOMIC_INIT(-1);
static int ipmi_heartbeat(void);
static void panic_halt_ipmi_heartbeat(void);
@@ -294,11 +392,6 @@ static int i_ipmi_set_timeout(struct ipmi_smi_msg *smi_msg,
return rv;
}
-/* Parameters to ipmi_set_timeout */
-#define IPMI_SET_TIMEOUT_NO_HB 0
-#define IPMI_SET_TIMEOUT_HB_IF_NECESSARY 1
-#define IPMI_SET_TIMEOUT_FORCE_HB 2
-
static int ipmi_set_timeout(int do_heartbeat)
{
int send_heartbeat_now;
@@ -732,8 +825,6 @@ static struct miscdevice ipmi_wdog_miscdev = {
.fops = &ipmi_wdog_fops
};
-static DECLARE_RWSEM(register_sem);
-
static void ipmi_wdog_msg_handler(struct ipmi_recv_msg *msg,
void *handler_data)
{
@@ -749,9 +840,10 @@ static void ipmi_wdog_msg_handler(struct ipmi_recv_msg *msg,
static void ipmi_wdog_pretimeout_handler(void *handler_data)
{
if (preaction_val != WDOG_PRETIMEOUT_NONE) {
- if (preop_val == WDOG_PREOP_PANIC)
- panic("Watchdog pre-timeout");
- else if (preop_val == WDOG_PREOP_GIVE_DATA) {
+ if (preop_val == WDOG_PREOP_PANIC) {
+ if (atomic_inc_and_test(&preop_panic_excl))
+ panic("Watchdog pre-timeout");
+ } else if (preop_val == WDOG_PREOP_GIVE_DATA) {
spin_lock(&ipmi_read_lock);
data_to_read = 1;
wake_up_interruptible(&read_q);
@@ -825,7 +917,8 @@ ipmi_nmi(void *dev_id, struct pt_regs *regs, int cpu, int handled)
an error and not work unless we re-enable
the timer. So do so. */
pretimeout_since_last_heartbeat = 1;
- panic(PFX "pre-timeout");
+ if (atomic_inc_and_test(&preop_panic_excl))
+ panic(PFX "pre-timeout");
}
return NOTIFY_DONE;
@@ -839,6 +932,7 @@ static struct nmi_handler ipmi_nmi_handler =
.handler = ipmi_nmi,
.priority = 0, /* Call us last. */
};
+int nmi_handler_registered;
#endif
static int wdog_reboot_handler(struct notifier_block *this,
@@ -921,59 +1015,86 @@ static struct ipmi_smi_watcher smi_watcher =
.smi_gone = ipmi_smi_gone
};
-static int __init ipmi_wdog_init(void)
+static int action_op(const char *inval, char *outval)
{
- int rv;
+ if (outval)
+ strcpy(outval, action);
+
+ if (!inval)
+ return 0;
- if (strcmp(action, "reset") == 0) {
+ if (strcmp(inval, "reset") == 0)
action_val = WDOG_TIMEOUT_RESET;
- } else if (strcmp(action, "none") == 0) {
+ else if (strcmp(inval, "none") == 0)
action_val = WDOG_TIMEOUT_NONE;
- } else if (strcmp(action, "power_cycle") == 0) {
+ else if (strcmp(inval, "power_cycle") == 0)
action_val = WDOG_TIMEOUT_POWER_CYCLE;
- } else if (strcmp(action, "power_off") == 0) {
+ else if (strcmp(inval, "power_off") == 0)
action_val = WDOG_TIMEOUT_POWER_DOWN;
- } else {
- action_val = WDOG_TIMEOUT_RESET;
- printk(KERN_INFO PFX "Unknown action '%s', defaulting to"
- " reset\n", action);
- }
+ else
+ return -EINVAL;
+ strcpy(action, inval);
+ return 0;
+}
+
+static int preaction_op(const char *inval, char *outval)
+{
+ if (outval)
+ strcpy(outval, preaction);
- if (strcmp(preaction, "pre_none") == 0) {
+ if (!inval)
+ return 0;
+
+ if (strcmp(inval, "pre_none") == 0)
preaction_val = WDOG_PRETIMEOUT_NONE;
- } else if (strcmp(preaction, "pre_smi") == 0) {
+ else if (strcmp(inval, "pre_smi") == 0)
preaction_val = WDOG_PRETIMEOUT_SMI;
#ifdef HAVE_NMI_HANDLER
- } else if (strcmp(preaction, "pre_nmi") == 0) {
+ else if (strcmp(inval, "pre_nmi") == 0)
preaction_val = WDOG_PRETIMEOUT_NMI;
#endif
- } else if (strcmp(preaction, "pre_int") == 0) {
+ else if (strcmp(inval, "pre_int") == 0)
preaction_val = WDOG_PRETIMEOUT_MSG_INT;
- } else {
- preaction_val = WDOG_PRETIMEOUT_NONE;
- printk(KERN_INFO PFX "Unknown preaction '%s', defaulting to"
- " none\n", preaction);
- }
+ else
+ return -EINVAL;
+ strcpy(preaction, inval);
+ return 0;
+}
+
+static int preop_op(const char *inval, char *outval)
+{
+ if (outval)
+ strcpy(outval, preop);
- if (strcmp(preop, "preop_none") == 0) {
+ if (!inval)
+ return 0;
+
+ if (strcmp(inval, "preop_none") == 0)
preop_val = WDOG_PREOP_NONE;
- } else if (strcmp(preop, "preop_panic") == 0) {
+ else if (strcmp(inval, "preop_panic") == 0)
preop_val = WDOG_PREOP_PANIC;
- } else if (strcmp(preop, "preop_give_data") == 0) {
+ else if (strcmp(inval, "preop_give_data") == 0)
preop_val = WDOG_PREOP_GIVE_DATA;
- } else {
- preop_val = WDOG_PREOP_NONE;
- printk(KERN_INFO PFX "Unknown preop '%s', defaulting to"
- " none\n", preop);
- }
+ else
+ return -EINVAL;
+ strcpy(preop, inval);
+ return 0;
+}
+static void check_parms(void)
+{
#ifdef HAVE_NMI_HANDLER
+ int do_nmi = 0;
+ int rv;
+
if (preaction_val == WDOG_PRETIMEOUT_NMI) {
+ do_nmi = 1;
if (preop_val == WDOG_PREOP_GIVE_DATA) {
printk(KERN_WARNING PFX "Pretimeout op is to give data"
" but NMI pretimeout is enabled, setting"
" pretimeout op to none\n");
- preop_val = WDOG_PREOP_NONE;
+ preop_op("preop_none", NULL);
+ do_nmi = 0;
}
#ifdef CONFIG_X86_LOCAL_APIC
if (nmi_watchdog == NMI_IO_APIC) {
@@ -983,18 +1104,48 @@ static int __init ipmi_wdog_init(void)
" Disabling IPMI nmi pretimeout.\n",
nmi_watchdog);
preaction_val = WDOG_PRETIMEOUT_NONE;
- } else {
+ do_nmi = 0;
+ }
#endif
+ }
+ if (do_nmi && !nmi_handler_registered) {
rv = request_nmi(&ipmi_nmi_handler);
if (rv) {
- printk(KERN_WARNING PFX "Can't register nmi handler\n");
- return rv;
- }
-#ifdef CONFIG_X86_LOCAL_APIC
- }
-#endif
+ printk(KERN_WARNING PFX
+ "Can't register nmi handler\n");
+ return;
+ } else
+ nmi_handler_registered = 1;
+ } else if (!do_nmi && nmi_handler_registered) {
+ release_nmi(&ipmi_nmi_handler);
+ nmi_handler_registered = 0;
}
#endif
+}
+
+static int __init ipmi_wdog_init(void)
+{
+ int rv;
+
+ if (action_op(action, NULL)) {
+ action_op("reset", NULL);
+ printk(KERN_INFO PFX "Unknown action '%s', defaulting to"
+ " reset\n", action);
+ }
+
+ if (preaction_op(preaction, NULL)) {
+ preaction_op("pre_none", NULL);
+ printk(KERN_INFO PFX "Unknown preaction '%s', defaulting to"
+ " none\n", preaction);
+ }
+
+ if (preop_op(preop, NULL)) {
+ preop_op("preop_none", NULL);
+ printk(KERN_INFO PFX "Unknown preop '%s', defaulting to"
+ " none\n", preop);
+ }
+
+ check_parms();
rv = ipmi_smi_watcher_register(&smi_watcher);
if (rv) {
@@ -1021,7 +1172,7 @@ static __exit void ipmi_unregister_watchdog(void)
down_write(&register_sem);
#ifdef HAVE_NMI_HANDLER
- if (preaction_val == WDOG_PRETIMEOUT_NMI)
+ if (nmi_handler_registered)
release_nmi(&ipmi_nmi_handler);
#endif
diff --git a/drivers/char/istallion.c b/drivers/char/istallion.c
index 9c19e5435a11..ce3bc0d45f1f 100644
--- a/drivers/char/istallion.c
+++ b/drivers/char/istallion.c
@@ -860,10 +860,9 @@ static void __exit istallion_module_exit(void)
if ((i = unregister_chrdev(STL_SIOMEMMAJOR, "staliomem")))
printk("STALLION: failed to un-register serial memory device, "
"errno=%d\n", -i);
- if (stli_tmpwritebuf != (char *) NULL)
- kfree(stli_tmpwritebuf);
- if (stli_txcookbuf != (char *) NULL)
- kfree(stli_txcookbuf);
+
+ kfree(stli_tmpwritebuf);
+ kfree(stli_txcookbuf);
for (i = 0; (i < stli_nrbrds); i++) {
if ((brdp = stli_brds[i]) == (stlibrd_t *) NULL)
@@ -5246,7 +5245,8 @@ int __init stli_init(void)
devfs_mk_cdev(MKDEV(STL_SIOMEMMAJOR, i),
S_IFCHR | S_IRUSR | S_IWUSR,
"staliomem/%d", i);
- class_device_create(istallion_class, MKDEV(STL_SIOMEMMAJOR, i),
+ class_device_create(istallion_class, NULL,
+ MKDEV(STL_SIOMEMMAJOR, i),
NULL, "staliomem%d", i);
}
diff --git a/drivers/char/lcd.c b/drivers/char/lcd.c
index b77161146144..29963d8be667 100644
--- a/drivers/char/lcd.c
+++ b/drivers/char/lcd.c
@@ -575,8 +575,8 @@ static inline int button_pressed(void)
static int lcd_waiters = 0;
-static long lcd_read(struct inode *inode, struct file *file, char *buf,
- unsigned long count)
+static ssize_t lcd_read(struct file *file, char *buf,
+ size_t count, loff_t *ofs)
{
long buttons_now;
diff --git a/drivers/char/lcd.h b/drivers/char/lcd.h
index 878a95280e87..a8d4ae737158 100644
--- a/drivers/char/lcd.h
+++ b/drivers/char/lcd.h
@@ -22,7 +22,7 @@ static int timeout(volatile unsigned long);
#define MAX_IDLE_TIME 120
struct lcd_display {
- unsigned long buttons;
+ unsigned buttons;
int size1;
int size2;
unsigned char line1[LCD_CHARS_PER_LINE];
diff --git a/drivers/char/lp.c b/drivers/char/lp.c
index 2afb9038dbc5..e57260525293 100644
--- a/drivers/char/lp.c
+++ b/drivers/char/lp.c
@@ -805,7 +805,7 @@ static int lp_register(int nr, struct parport *port)
if (reset)
lp_reset(nr);
- class_device_create(lp_class, MKDEV(LP_MAJOR, nr), NULL,
+ class_device_create(lp_class, NULL, MKDEV(LP_MAJOR, nr), NULL,
"lp%d", nr);
devfs_mk_cdev(MKDEV(LP_MAJOR, nr), S_IFCHR | S_IRUGO | S_IWUGO,
"printers/%d", nr);
diff --git a/drivers/char/mem.c b/drivers/char/mem.c
index f182752fe918..91dd669273e0 100644
--- a/drivers/char/mem.c
+++ b/drivers/char/mem.c
@@ -231,9 +231,7 @@ static ssize_t write_mem(struct file * file, const char __user * buf,
static int mmap_mem(struct file * file, struct vm_area_struct * vma)
{
#if defined(__HAVE_PHYS_MEM_ACCESS_PROT)
- unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
-
- vma->vm_page_prot = phys_mem_access_prot(file, offset,
+ vma->vm_page_prot = phys_mem_access_prot(file, vma->vm_pgoff,
vma->vm_end - vma->vm_start,
vma->vm_page_prot);
#elif defined(pgprot_noncached)
@@ -920,7 +918,8 @@ static int __init chr_dev_init(void)
mem_class = class_create(THIS_MODULE, "mem");
for (i = 0; i < ARRAY_SIZE(devlist); i++) {
- class_device_create(mem_class, MKDEV(MEM_MAJOR, devlist[i].minor),
+ class_device_create(mem_class, NULL,
+ MKDEV(MEM_MAJOR, devlist[i].minor),
NULL, devlist[i].name);
devfs_mk_cdev(MKDEV(MEM_MAJOR, devlist[i].minor),
S_IFCHR | devlist[i].mode, devlist[i].name);
diff --git a/drivers/char/misc.c b/drivers/char/misc.c
index 0c8375165e29..3e4c0414a01a 100644
--- a/drivers/char/misc.c
+++ b/drivers/char/misc.c
@@ -234,7 +234,7 @@ int misc_register(struct miscdevice * misc)
}
dev = MKDEV(MISC_MAJOR, misc->minor);
- misc->class = class_device_create(misc_class, dev, misc->dev,
+ misc->class = class_device_create(misc_class, NULL, dev, misc->dev,
"%s", misc->name);
if (IS_ERR(misc->class)) {
err = PTR_ERR(misc->class);
diff --git a/drivers/char/mmtimer.c b/drivers/char/mmtimer.c
index 12006182f575..78c89a3e7825 100644
--- a/drivers/char/mmtimer.c
+++ b/drivers/char/mmtimer.c
@@ -441,7 +441,7 @@ static irqreturn_t
mmtimer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
int i;
- mmtimer_t *base = timers + cpuid_to_cnodeid(smp_processor_id()) *
+ mmtimer_t *base = timers + cpu_to_node(smp_processor_id()) *
NUM_COMPARATORS;
unsigned long expires = 0;
int result = IRQ_NONE;
@@ -608,7 +608,7 @@ static int sgi_timer_set(struct k_itimer *timr, int flags,
*/
preempt_disable();
- nodeid = cpuid_to_cnodeid(smp_processor_id());
+ nodeid = cpu_to_node(smp_processor_id());
base = timers + nodeid * NUM_COMPARATORS;
retry:
/* Don't use an allocated timer, or a deleted one that's pending */
diff --git a/drivers/char/mwave/3780i.c b/drivers/char/mwave/3780i.c
index 613aed9e1840..d1fe05e83882 100644
--- a/drivers/char/mwave/3780i.c
+++ b/drivers/char/mwave/3780i.c
@@ -53,6 +53,8 @@
#include <linux/ioport.h>
#include <linux/init.h>
#include <linux/bitops.h>
+#include <linux/sched.h> /* cond_resched() */
+
#include <asm/io.h>
#include <asm/uaccess.h>
#include <asm/system.h>
diff --git a/drivers/char/mwave/tp3780i.c b/drivers/char/mwave/tp3780i.c
index d6c72e0934e2..cc3e54dd7234 100644
--- a/drivers/char/mwave/tp3780i.c
+++ b/drivers/char/mwave/tp3780i.c
@@ -46,7 +46,6 @@
* First release to the public
*/
-#include <linux/version.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/ptrace.h>
diff --git a/drivers/char/mxser.c b/drivers/char/mxser.c
index 45d012d85e8c..26448f176803 100644
--- a/drivers/char/mxser.c
+++ b/drivers/char/mxser.c
@@ -38,7 +38,6 @@
#include <linux/config.h>
#include <linux/module.h>
-#include <linux/version.h>
#include <linux/autoconf.h>
#include <linux/errno.h>
#include <linux/signal.h>
@@ -470,6 +469,8 @@ static struct tty_operations mxser_ops = {
.stop = mxser_stop,
.start = mxser_start,
.hangup = mxser_hangup,
+ .break_ctl = mxser_rs_break,
+ .wait_until_sent = mxser_wait_until_sent,
.tiocmget = mxser_tiocmget,
.tiocmset = mxser_tiocmset,
};
@@ -492,14 +493,18 @@ static int __init mxser_module_init(void)
static void __exit mxser_module_exit(void)
{
- int i, err = 0;
+ int i, err;
if (verbose)
printk(KERN_DEBUG "Unloading module mxser ...\n");
- if ((err |= tty_unregister_driver(mxvar_sdriver)))
+ err = tty_unregister_driver(mxvar_sdriver);
+ if (!err)
+ put_tty_driver(mxvar_sdriver);
+ else
printk(KERN_ERR "Couldn't unregister MOXA Smartio/Industio family serial driver\n");
+
for (i = 0; i < MXSER_BOARDS; i++) {
struct pci_dev *pdev;
@@ -688,7 +693,6 @@ static int mxser_get_PCI_conf(int busnum, int devnum, int board_type, struct mxs
static int mxser_init(void)
{
int i, m, retval, b, n;
- int ret1;
struct pci_dev *pdev = NULL;
int index;
unsigned char busnum, devnum;
@@ -722,24 +726,6 @@ static int mxser_init(void)
mxvar_sdriver->termios = mxvar_termios;
mxvar_sdriver->termios_locked = mxvar_termios_locked;
- mxvar_sdriver->open = mxser_open;
- mxvar_sdriver->close = mxser_close;
- mxvar_sdriver->write = mxser_write;
- mxvar_sdriver->put_char = mxser_put_char;
- mxvar_sdriver->flush_chars = mxser_flush_chars;
- mxvar_sdriver->write_room = mxser_write_room;
- mxvar_sdriver->chars_in_buffer = mxser_chars_in_buffer;
- mxvar_sdriver->flush_buffer = mxser_flush_buffer;
- mxvar_sdriver->ioctl = mxser_ioctl;
- mxvar_sdriver->throttle = mxser_throttle;
- mxvar_sdriver->unthrottle = mxser_unthrottle;
- mxvar_sdriver->set_termios = mxser_set_termios;
- mxvar_sdriver->stop = mxser_stop;
- mxvar_sdriver->start = mxser_start;
- mxvar_sdriver->hangup = mxser_hangup;
- mxvar_sdriver->break_ctl = mxser_rs_break;
- mxvar_sdriver->wait_until_sent = mxser_wait_until_sent;
-
mxvar_diagflag = 0;
memset(mxvar_table, 0, MXSER_PORTS * sizeof(struct mxser_struct));
memset(&mxvar_log, 0, sizeof(struct mxser_log));
@@ -870,14 +856,11 @@ static int mxser_init(void)
}
#endif
- ret1 = 0;
- if (!(ret1 = tty_register_driver(mxvar_sdriver))) {
- return 0;
- } else
+ retval = tty_register_driver(mxvar_sdriver);
+ if (retval) {
printk(KERN_ERR "Couldn't install MOXA Smartio/Industio family driver !\n");
+ put_tty_driver(mxvar_sdriver);
-
- if (ret1) {
for (i = 0; i < MXSER_BOARDS; i++) {
if (mxsercfg[i].board_type == -1)
continue;
@@ -886,10 +869,10 @@ static int mxser_init(void)
//todo: release io, vector
}
}
- return -1;
+ return retval;
}
- return (0);
+ return 0;
}
static void mxser_do_softint(void *private_)
@@ -933,6 +916,9 @@ static int mxser_open(struct tty_struct *tty, struct file *filp)
struct mxser_struct *info;
int retval, line;
+ /* initialize driver_data in case something fails */
+ tty->driver_data = NULL;
+
line = tty->index;
if (line == MXSER_PORTS)
return 0;
@@ -995,7 +981,7 @@ static void mxser_close(struct tty_struct *tty, struct file *filp)
if (tty->index == MXSER_PORTS)
return;
if (!info)
- BUG();
+ return;
spin_lock_irqsave(&info->slock, flags);
diff --git a/drivers/char/n_hdlc.c b/drivers/char/n_hdlc.c
index 5079beda69b5..c3660d8781a4 100644
--- a/drivers/char/n_hdlc.c
+++ b/drivers/char/n_hdlc.c
@@ -264,8 +264,7 @@ static void n_hdlc_release(struct n_hdlc *n_hdlc)
} else
break;
}
- if (n_hdlc->tbuf)
- kfree(n_hdlc->tbuf);
+ kfree(n_hdlc->tbuf);
kfree(n_hdlc);
} /* end of n_hdlc_release() */
diff --git a/drivers/char/n_tty.c b/drivers/char/n_tty.c
index c9bdf544ed2c..c556f4d3ccd7 100644
--- a/drivers/char/n_tty.c
+++ b/drivers/char/n_tty.c
@@ -62,7 +62,7 @@
static inline unsigned char *alloc_buf(void)
{
- unsigned int prio = in_interrupt() ? GFP_ATOMIC : GFP_KERNEL;
+ gfp_t prio = in_interrupt() ? GFP_ATOMIC : GFP_KERNEL;
if (PAGE_SIZE != N_TTY_BUF_SIZE)
return kmalloc(N_TTY_BUF_SIZE, prio);
diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c
index 02d7f046c10a..2c326ea53421 100644
--- a/drivers/char/pcmcia/synclink_cs.c
+++ b/drivers/char/pcmcia/synclink_cs.c
@@ -2994,8 +2994,7 @@ int rx_alloc_buffers(MGSLPC_INFO *info)
void rx_free_buffers(MGSLPC_INFO *info)
{
- if (info->rx_buf)
- kfree(info->rx_buf);
+ kfree(info->rx_buf);
info->rx_buf = NULL;
}
diff --git a/drivers/char/ppdev.c b/drivers/char/ppdev.c
index 0e22880432bc..306ee0f091a4 100644
--- a/drivers/char/ppdev.c
+++ b/drivers/char/ppdev.c
@@ -752,7 +752,7 @@ static struct file_operations pp_fops = {
static void pp_attach(struct parport *port)
{
- class_device_create(ppdev_class, MKDEV(PP_MAJOR, port->number),
+ class_device_create(ppdev_class, NULL, MKDEV(PP_MAJOR, port->number),
NULL, "parport%d", port->number);
}
diff --git a/drivers/char/qtronix.c b/drivers/char/qtronix.c
index 40a3cf62e1a8..601d09baf9d7 100644
--- a/drivers/char/qtronix.c
+++ b/drivers/char/qtronix.c
@@ -591,6 +591,11 @@ static int __init psaux_init(void)
return retval;
queue = (struct aux_queue *) kmalloc(sizeof(*queue), GFP_KERNEL);
+ if (!queue) {
+ misc_deregister(&psaux_mouse);
+ return -ENOMEM;
+ }
+
memset(queue, 0, sizeof(*queue));
queue->head = queue->tail = 0;
init_waitqueue_head(&queue->proc_list);
diff --git a/drivers/char/raw.c b/drivers/char/raw.c
index f13e5de02207..30e4cbe16bb0 100644
--- a/drivers/char/raw.c
+++ b/drivers/char/raw.c
@@ -128,7 +128,7 @@ raw_ioctl(struct inode *inode, struct file *filp,
static void bind_device(struct raw_config_request *rq)
{
class_device_destroy(raw_class, MKDEV(RAW_MAJOR, rq->raw_minor));
- class_device_create(raw_class, MKDEV(RAW_MAJOR, rq->raw_minor),
+ class_device_create(raw_class, NULL, MKDEV(RAW_MAJOR, rq->raw_minor),
NULL, "raw%d", rq->raw_minor);
}
@@ -307,7 +307,7 @@ static int __init raw_init(void)
unregister_chrdev_region(dev, MAX_RAW_MINORS);
goto error;
}
- class_device_create(raw_class, MKDEV(RAW_MAJOR, 0), NULL, "rawctl");
+ class_device_create(raw_class, NULL, MKDEV(RAW_MAJOR, 0), NULL, "rawctl");
devfs_mk_cdev(MKDEV(RAW_MAJOR, 0),
S_IFCHR | S_IRUGO | S_IWUGO,
diff --git a/drivers/char/rocket.c b/drivers/char/rocket.c
index 5b1d3680c8ab..d3bc731fbb27 100644
--- a/drivers/char/rocket.c
+++ b/drivers/char/rocket.c
@@ -256,7 +256,6 @@ static int sInitController(CONTROLLER_T * CtlP, int CtlNum, ByteIO_t MudbacIO,
static int sReadAiopID(ByteIO_t io);
static int sReadAiopNumChan(WordIO_t io);
-#ifdef MODULE
MODULE_AUTHOR("Theodore Ts'o");
MODULE_DESCRIPTION("Comtrol RocketPort driver");
module_param(board1, ulong, 0);
@@ -288,17 +287,14 @@ MODULE_PARM_DESC(pc104_3, "set interface types for ISA(PC104) board #3 (e.g. pc1
module_param_array(pc104_4, ulong, NULL, 0);
MODULE_PARM_DESC(pc104_4, "set interface types for ISA(PC104) board #4 (e.g. pc104_4=232,232,485,485,...");
-int rp_init(void);
+static int rp_init(void);
static void rp_cleanup_module(void);
module_init(rp_init);
module_exit(rp_cleanup_module);
-#endif
-#ifdef MODULE_LICENSE
MODULE_LICENSE("Dual BSD/GPL");
-#endif
/*************************************************************************/
/* Module code starts here */
@@ -2378,7 +2374,7 @@ static struct tty_operations rocket_ops = {
/*
* The module "startup" routine; it's run when the module is loaded.
*/
-int __init rp_init(void)
+static int __init rp_init(void)
{
int retval, pci_boards_found, isa_boards_found, i;
@@ -2502,7 +2498,6 @@ int __init rp_init(void)
return 0;
}
-#ifdef MODULE
static void rp_cleanup_module(void)
{
@@ -2517,10 +2512,8 @@ static void rp_cleanup_module(void)
"rocketport driver\n", -retval);
put_tty_driver(rocket_driver);
- for (i = 0; i < MAX_RP_PORTS; i++) {
- if (rp_table[i])
- kfree(rp_table[i]);
- }
+ for (i = 0; i < MAX_RP_PORTS; i++)
+ kfree(rp_table[i]);
for (i = 0; i < NUM_BOARDS; i++) {
if (rcktpt_io_addr[i] <= 0 || is_PCI[i])
@@ -2530,7 +2523,6 @@ static void rp_cleanup_module(void)
if (controller)
release_region(controller, 4);
}
-#endif
/***************************************************************************
Function: sInitController
diff --git a/drivers/char/rtc.c b/drivers/char/rtc.c
index 63fff7c1244a..a7f099fb7dfe 100644
--- a/drivers/char/rtc.c
+++ b/drivers/char/rtc.c
@@ -149,8 +149,22 @@ static void get_rtc_alm_time (struct rtc_time *alm_tm);
#ifdef RTC_IRQ
static void rtc_dropped_irq(unsigned long data);
-static void set_rtc_irq_bit(unsigned char bit);
-static void mask_rtc_irq_bit(unsigned char bit);
+static void set_rtc_irq_bit_locked(unsigned char bit);
+static void mask_rtc_irq_bit_locked(unsigned char bit);
+
+static inline void set_rtc_irq_bit(unsigned char bit)
+{
+ spin_lock_irq(&rtc_lock);
+ set_rtc_irq_bit_locked(bit);
+ spin_unlock_irq(&rtc_lock);
+}
+
+static void mask_rtc_irq_bit(unsigned char bit)
+{
+ spin_lock_irq(&rtc_lock);
+ mask_rtc_irq_bit_locked(bit);
+ spin_unlock_irq(&rtc_lock);
+}
#endif
static int rtc_proc_open(struct inode *inode, struct file *file);
@@ -401,18 +415,19 @@ static int rtc_do_ioctl(unsigned int cmd, unsigned long arg, int kernel)
}
case RTC_PIE_OFF: /* Mask periodic int. enab. bit */
{
- mask_rtc_irq_bit(RTC_PIE);
+ unsigned long flags; /* can be called from isr via rtc_control() */
+ spin_lock_irqsave (&rtc_lock, flags);
+ mask_rtc_irq_bit_locked(RTC_PIE);
if (rtc_status & RTC_TIMER_ON) {
- spin_lock_irq (&rtc_lock);
rtc_status &= ~RTC_TIMER_ON;
del_timer(&rtc_irq_timer);
- spin_unlock_irq (&rtc_lock);
}
+ spin_unlock_irqrestore (&rtc_lock, flags);
return 0;
}
case RTC_PIE_ON: /* Allow periodic ints */
{
-
+ unsigned long flags; /* can be called from isr via rtc_control() */
/*
* We don't really want Joe User enabling more
* than 64Hz of interrupts on a multi-user machine.
@@ -421,14 +436,14 @@ static int rtc_do_ioctl(unsigned int cmd, unsigned long arg, int kernel)
(!capable(CAP_SYS_RESOURCE)))
return -EACCES;
+ spin_lock_irqsave (&rtc_lock, flags);
if (!(rtc_status & RTC_TIMER_ON)) {
- spin_lock_irq (&rtc_lock);
rtc_irq_timer.expires = jiffies + HZ/rtc_freq + 2*HZ/100;
add_timer(&rtc_irq_timer);
rtc_status |= RTC_TIMER_ON;
- spin_unlock_irq (&rtc_lock);
}
- set_rtc_irq_bit(RTC_PIE);
+ set_rtc_irq_bit_locked(RTC_PIE);
+ spin_unlock_irqrestore (&rtc_lock, flags);
return 0;
}
case RTC_UIE_OFF: /* Mask ints from RTC updates. */
@@ -609,6 +624,7 @@ static int rtc_do_ioctl(unsigned int cmd, unsigned long arg, int kernel)
{
int tmp = 0;
unsigned char val;
+ unsigned long flags; /* can be called from isr via rtc_control() */
/*
* The max we can do is 8192Hz.
@@ -631,9 +647,9 @@ static int rtc_do_ioctl(unsigned int cmd, unsigned long arg, int kernel)
if (arg != (1<<tmp))
return -EINVAL;
- spin_lock_irq(&rtc_lock);
+ spin_lock_irqsave(&rtc_lock, flags);
if (hpet_set_periodic_freq(arg)) {
- spin_unlock_irq(&rtc_lock);
+ spin_unlock_irqrestore(&rtc_lock, flags);
return 0;
}
rtc_freq = arg;
@@ -641,7 +657,7 @@ static int rtc_do_ioctl(unsigned int cmd, unsigned long arg, int kernel)
val = CMOS_READ(RTC_FREQ_SELECT) & 0xf0;
val |= (16 - tmp);
CMOS_WRITE(val, RTC_FREQ_SELECT);
- spin_unlock_irq(&rtc_lock);
+ spin_unlock_irqrestore(&rtc_lock, flags);
return 0;
}
#endif
@@ -844,12 +860,15 @@ int rtc_control(rtc_task_t *task, unsigned int cmd, unsigned long arg)
#ifndef RTC_IRQ
return -EIO;
#else
- spin_lock_irq(&rtc_task_lock);
+ unsigned long flags;
+ if (cmd != RTC_PIE_ON && cmd != RTC_PIE_OFF && cmd != RTC_IRQP_SET)
+ return -EINVAL;
+ spin_lock_irqsave(&rtc_task_lock, flags);
if (rtc_callback != task) {
- spin_unlock_irq(&rtc_task_lock);
+ spin_unlock_irqrestore(&rtc_task_lock, flags);
return -ENXIO;
}
- spin_unlock_irq(&rtc_task_lock);
+ spin_unlock_irqrestore(&rtc_task_lock, flags);
return rtc_do_ioctl(cmd, arg, 1);
#endif
}
@@ -1306,40 +1325,32 @@ static void get_rtc_alm_time(struct rtc_time *alm_tm)
* meddles with the interrupt enable/disable bits.
*/
-static void mask_rtc_irq_bit(unsigned char bit)
+static void mask_rtc_irq_bit_locked(unsigned char bit)
{
unsigned char val;
- spin_lock_irq(&rtc_lock);
- if (hpet_mask_rtc_irq_bit(bit)) {
- spin_unlock_irq(&rtc_lock);
+ if (hpet_mask_rtc_irq_bit(bit))
return;
- }
val = CMOS_READ(RTC_CONTROL);
val &= ~bit;
CMOS_WRITE(val, RTC_CONTROL);
CMOS_READ(RTC_INTR_FLAGS);
rtc_irq_data = 0;
- spin_unlock_irq(&rtc_lock);
}
-static void set_rtc_irq_bit(unsigned char bit)
+static void set_rtc_irq_bit_locked(unsigned char bit)
{
unsigned char val;
- spin_lock_irq(&rtc_lock);
- if (hpet_set_rtc_irq_bit(bit)) {
- spin_unlock_irq(&rtc_lock);
+ if (hpet_set_rtc_irq_bit(bit))
return;
- }
val = CMOS_READ(RTC_CONTROL);
val |= bit;
CMOS_WRITE(val, RTC_CONTROL);
CMOS_READ(RTC_INTR_FLAGS);
rtc_irq_data = 0;
- spin_unlock_irq(&rtc_lock);
}
#endif
diff --git a/drivers/char/s3c2410-rtc.c b/drivers/char/s3c2410-rtc.c
index e1a90d9a8756..d724c0de4f28 100644
--- a/drivers/char/s3c2410-rtc.c
+++ b/drivers/char/s3c2410-rtc.c
@@ -20,7 +20,7 @@
#include <linux/fs.h>
#include <linux/string.h>
#include <linux/init.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <linux/interrupt.h>
#include <linux/rtc.h>
#include <linux/bcd.h>
@@ -519,30 +519,28 @@ static struct timespec s3c2410_rtc_delta;
static int ticnt_save;
-static int s3c2410_rtc_suspend(struct device *dev, pm_message_t state, u32 level)
+static int s3c2410_rtc_suspend(struct device *dev, pm_message_t state)
{
struct rtc_time tm;
struct timespec time;
time.tv_nsec = 0;
- if (level == SUSPEND_POWER_DOWN) {
- /* save TICNT for anyone using periodic interrupts */
+ /* save TICNT for anyone using periodic interrupts */
- ticnt_save = readb(S3C2410_TICNT);
+ ticnt_save = readb(S3C2410_TICNT);
- /* calculate time delta for suspend */
+ /* calculate time delta for suspend */
- s3c2410_rtc_gettime(&tm);
- rtc_tm_to_time(&tm, &time.tv_sec);
- save_time_delta(&s3c2410_rtc_delta, &time);
- s3c2410_rtc_enable(dev, 0);
- }
+ s3c2410_rtc_gettime(&tm);
+ rtc_tm_to_time(&tm, &time.tv_sec);
+ save_time_delta(&s3c2410_rtc_delta, &time);
+ s3c2410_rtc_enable(dev, 0);
return 0;
}
-static int s3c2410_rtc_resume(struct device *dev, u32 level)
+static int s3c2410_rtc_resume(struct device *dev)
{
struct rtc_time tm;
struct timespec time;
diff --git a/drivers/char/selection.c b/drivers/char/selection.c
index 16d630f58bb4..5b187c895c18 100644
--- a/drivers/char/selection.c
+++ b/drivers/char/selection.c
@@ -246,8 +246,7 @@ int set_selection(const struct tiocl_selection __user *sel, struct tty_struct *t
clear_selection();
return -ENOMEM;
}
- if (sel_buffer)
- kfree(sel_buffer);
+ kfree(sel_buffer);
sel_buffer = bp;
obp = bp;
diff --git a/drivers/char/ser_a2232.c b/drivers/char/ser_a2232.c
index 6b4e9d155f50..dda30e42ec79 100644
--- a/drivers/char/ser_a2232.c
+++ b/drivers/char/ser_a2232.c
@@ -790,7 +790,7 @@ static int __init a2232board_init(void)
}
- printk("Total: %d A2232 boards initialized.\n.", nr_a2232); /* Some status report if no card was found */
+ printk("Total: %d A2232 boards initialized.\n", nr_a2232); /* Some status report if no card was found */
a2232_init_portstructs();
diff --git a/drivers/char/snsc.c b/drivers/char/snsc.c
index 261a41bf6d02..0e7d216e7eb0 100644
--- a/drivers/char/snsc.c
+++ b/drivers/char/snsc.c
@@ -377,7 +377,7 @@ scdrv_init(void)
dev_t first_dev, dev;
nasid_t event_nasid = ia64_sn_get_console_nasid();
- if (alloc_chrdev_region(&first_dev, 0, numionodes,
+ if (alloc_chrdev_region(&first_dev, 0, num_cnodes,
SYSCTL_BASENAME) < 0) {
printk("%s: failed to register SN system controller device\n",
__FUNCTION__);
@@ -385,7 +385,7 @@ scdrv_init(void)
}
snsc_class = class_create(THIS_MODULE, SYSCTL_BASENAME);
- for (cnode = 0; cnode < numionodes; cnode++) {
+ for (cnode = 0; cnode < num_cnodes; cnode++) {
geoid = cnodeid_get_geoid(cnode);
devnamep = devname;
format_module_id(devnamep, geo_module(geoid),
@@ -437,7 +437,7 @@ scdrv_init(void)
continue;
}
- class_device_create(snsc_class, dev, NULL,
+ class_device_create(snsc_class, NULL, dev, NULL,
"%s", devname);
ia64_sn_irtr_intr_enable(scd->scd_nasid,
diff --git a/drivers/char/sonypi.c b/drivers/char/sonypi.c
index 36ae9ad2598c..d05067dcea01 100644
--- a/drivers/char/sonypi.c
+++ b/drivers/char/sonypi.c
@@ -48,6 +48,7 @@
#include <linux/dmi.h>
#include <linux/err.h>
#include <linux/kfifo.h>
+#include <linux/platform_device.h>
#include <asm/uaccess.h>
#include <asm/io.h>
@@ -424,10 +425,6 @@ static struct sonypi_eventtypes {
#define SONYPI_BUF_SIZE 128
-/* The name of the devices for the input device drivers */
-#define SONYPI_JOG_INPUTNAME "Sony Vaio Jogdial"
-#define SONYPI_KEY_INPUTNAME "Sony Vaio Keys"
-
/* Correspondance table between sonypi events and input layer events */
static struct {
int sonypiev;
@@ -490,8 +487,8 @@ static struct sonypi_device {
struct fasync_struct *fifo_async;
int open_count;
int model;
- struct input_dev input_jog_dev;
- struct input_dev input_key_dev;
+ struct input_dev *input_jog_dev;
+ struct input_dev *input_key_dev;
struct work_struct input_work;
struct kfifo *input_fifo;
spinlock_t input_fifo_lock;
@@ -779,8 +776,8 @@ static void input_keyrelease(void *data)
static void sonypi_report_input_event(u8 event)
{
- struct input_dev *jog_dev = &sonypi_device.input_jog_dev;
- struct input_dev *key_dev = &sonypi_device.input_key_dev;
+ struct input_dev *jog_dev = sonypi_device.input_jog_dev;
+ struct input_dev *key_dev = sonypi_device.input_key_dev;
struct sonypi_keypress kp = { NULL };
int i;
@@ -1171,19 +1168,17 @@ static int sonypi_disable(void)
#ifdef CONFIG_PM
static int old_camera_power;
-static int sonypi_suspend(struct device *dev, pm_message_t state, u32 level)
+static int sonypi_suspend(struct device *dev, pm_message_t state)
{
- if (level == SUSPEND_DISABLE) {
- old_camera_power = sonypi_device.camera_power;
- sonypi_disable();
- }
+ old_camera_power = sonypi_device.camera_power;
+ sonypi_disable();
+
return 0;
}
-static int sonypi_resume(struct device *dev, u32 level)
+static int sonypi_resume(struct device *dev)
{
- if (level == RESUME_ENABLE)
- sonypi_enable(old_camera_power);
+ sonypi_enable(old_camera_power);
return 0;
}
#endif
@@ -1203,6 +1198,47 @@ static struct device_driver sonypi_driver = {
.shutdown = sonypi_shutdown,
};
+static int __devinit sonypi_create_input_devices(void)
+{
+ struct input_dev *jog_dev;
+ struct input_dev *key_dev;
+ int i;
+
+ sonypi_device.input_jog_dev = jog_dev = input_allocate_device();
+ if (!jog_dev)
+ return -ENOMEM;
+
+ jog_dev->name = "Sony Vaio Jogdial";
+ jog_dev->id.bustype = BUS_ISA;
+ jog_dev->id.vendor = PCI_VENDOR_ID_SONY;
+
+ jog_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
+ jog_dev->keybit[LONG(BTN_MOUSE)] = BIT(BTN_MIDDLE);
+ jog_dev->relbit[0] = BIT(REL_WHEEL);
+
+ sonypi_device.input_key_dev = key_dev = input_allocate_device();
+ if (!key_dev) {
+ input_free_device(jog_dev);
+ sonypi_device.input_jog_dev = NULL;
+ return -ENOMEM;
+ }
+
+ key_dev->name = "Sony Vaio Keys";
+ key_dev->id.bustype = BUS_ISA;
+ key_dev->id.vendor = PCI_VENDOR_ID_SONY;
+
+ /* Initialize the Input Drivers: special keys */
+ key_dev->evbit[0] = BIT(EV_KEY);
+ for (i = 0; sonypi_inputkeys[i].sonypiev; i++)
+ if (sonypi_inputkeys[i].inputev)
+ set_bit(sonypi_inputkeys[i].inputev, key_dev->keybit);
+
+ input_register_device(jog_dev);
+ input_register_device(key_dev);
+
+ return 0;
+}
+
static int __devinit sonypi_probe(void)
{
int i, ret;
@@ -1298,34 +1334,10 @@ static int __devinit sonypi_probe(void)
}
if (useinput) {
- /* Initialize the Input Drivers: jogdial */
- int i;
- sonypi_device.input_jog_dev.evbit[0] =
- BIT(EV_KEY) | BIT(EV_REL);
- sonypi_device.input_jog_dev.keybit[LONG(BTN_MOUSE)] =
- BIT(BTN_MIDDLE);
- sonypi_device.input_jog_dev.relbit[0] = BIT(REL_WHEEL);
- sonypi_device.input_jog_dev.name = SONYPI_JOG_INPUTNAME;
- sonypi_device.input_jog_dev.id.bustype = BUS_ISA;
- sonypi_device.input_jog_dev.id.vendor = PCI_VENDOR_ID_SONY;
-
- input_register_device(&sonypi_device.input_jog_dev);
- printk(KERN_INFO "%s input method installed.\n",
- sonypi_device.input_jog_dev.name);
-
- /* Initialize the Input Drivers: special keys */
- sonypi_device.input_key_dev.evbit[0] = BIT(EV_KEY);
- for (i = 0; sonypi_inputkeys[i].sonypiev; i++)
- if (sonypi_inputkeys[i].inputev)
- set_bit(sonypi_inputkeys[i].inputev,
- sonypi_device.input_key_dev.keybit);
- sonypi_device.input_key_dev.name = SONYPI_KEY_INPUTNAME;
- sonypi_device.input_key_dev.id.bustype = BUS_ISA;
- sonypi_device.input_key_dev.id.vendor = PCI_VENDOR_ID_SONY;
- input_register_device(&sonypi_device.input_key_dev);
- printk(KERN_INFO "%s input method installed.\n",
- sonypi_device.input_key_dev.name);
+ ret = sonypi_create_input_devices();
+ if (ret)
+ goto out_inputdevices;
spin_lock_init(&sonypi_device.input_fifo_lock);
sonypi_device.input_fifo =
@@ -1375,8 +1387,9 @@ static int __devinit sonypi_probe(void)
out_platformdev:
kfifo_free(sonypi_device.input_fifo);
out_infifo:
- input_unregister_device(&sonypi_device.input_key_dev);
- input_unregister_device(&sonypi_device.input_jog_dev);
+ input_unregister_device(sonypi_device.input_key_dev);
+ input_unregister_device(sonypi_device.input_jog_dev);
+out_inputdevices:
free_irq(sonypi_device.irq, sonypi_irq);
out_reqirq:
release_region(sonypi_device.ioport1, sonypi_device.region_size);
@@ -1402,8 +1415,8 @@ static void __devexit sonypi_remove(void)
platform_device_unregister(sonypi_device.pdev);
if (useinput) {
- input_unregister_device(&sonypi_device.input_key_dev);
- input_unregister_device(&sonypi_device.input_jog_dev);
+ input_unregister_device(sonypi_device.input_key_dev);
+ input_unregister_device(sonypi_device.input_jog_dev);
kfifo_free(sonypi_device.input_fifo);
}
diff --git a/drivers/char/specialix.c b/drivers/char/specialix.c
index 50e0b612a8a2..0bbfce43031c 100644
--- a/drivers/char/specialix.c
+++ b/drivers/char/specialix.c
@@ -38,19 +38,19 @@
*
* Revision 1.0: April 1st 1997.
* Initial release for alpha testing.
- * Revision 1.1: April 14th 1997.
- * Incorporated Richard Hudsons suggestions,
+ * Revision 1.1: April 14th 1997.
+ * Incorporated Richard Hudsons suggestions,
* removed some debugging printk's.
* Revision 1.2: April 15th 1997.
* Ported to 2.1.x kernels.
- * Revision 1.3: April 17th 1997
- * Backported to 2.0. (Compatibility macros).
+ * Revision 1.3: April 17th 1997
+ * Backported to 2.0. (Compatibility macros).
* Revision 1.4: April 18th 1997
- * Fixed DTR/RTS bug that caused the card to indicate
- * "don't send data" to a modem after the password prompt.
+ * Fixed DTR/RTS bug that caused the card to indicate
+ * "don't send data" to a modem after the password prompt.
* Fixed bug for premature (fake) interrupts.
* Revision 1.5: April 19th 1997
- * fixed a minor typo in the header file, cleanup a little.
+ * fixed a minor typo in the header file, cleanup a little.
* performance warnings are now MAXed at once per minute.
* Revision 1.6: May 23 1997
* Changed the specialix=... format to include interrupt.
@@ -60,10 +60,10 @@
* port to linux-2.1.43 kernel.
* Revision 1.9: Oct 9 1998
* Added stuff for the IO8+/PCI version.
- * Revision 1.10: Oct 22 1999 / Jan 21 2000.
- * Added stuff for setserial.
+ * Revision 1.10: Oct 22 1999 / Jan 21 2000.
+ * Added stuff for setserial.
* Nicolas Mailhot (Nicolas.Mailhot@email.enst.fr)
- *
+ *
*/
#define VERSION "1.11"
@@ -90,7 +90,6 @@
#include <linux/fcntl.h>
#include <linux/major.h>
#include <linux/delay.h>
-#include <linux/version.h>
#include <linux/pci.h>
#include <linux/init.h>
#include <asm/uaccess.h>
@@ -154,7 +153,7 @@ static int sx_poll = HZ;
-/*
+/*
* The following defines are mostly for testing purposes. But if you need
* some nice reporting in your syslog, you can define them also.
*/
@@ -188,7 +187,7 @@ static DECLARE_MUTEX(tmp_buf_sem);
static unsigned long baud_table[] = {
0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800,
- 9600, 19200, 38400, 57600, 115200, 0,
+ 9600, 19200, 38400, 57600, 115200, 0,
};
static struct specialix_board sx_board[SX_NBOARD] = {
@@ -216,7 +215,7 @@ static inline int sx_paranoia_check(struct specialix_port const * port,
KERN_ERR "sx: Warning: bad specialix port magic number for device %s in %s\n";
static const char *badinfo =
KERN_ERR "sx: Warning: null specialix port for device %s in %s\n";
-
+
if (!port) {
printk(badinfo, name, routine);
return 1;
@@ -231,9 +230,9 @@ static inline int sx_paranoia_check(struct specialix_port const * port,
/*
- *
+ *
* Service functions for specialix IO8+ driver.
- *
+ *
*/
/* Get board number from pointer */
@@ -246,7 +245,7 @@ static inline int board_No (struct specialix_board * bp)
/* Get port number from pointer */
static inline int port_No (struct specialix_port const * port)
{
- return SX_PORT(port - sx_port);
+ return SX_PORT(port - sx_port);
}
@@ -309,7 +308,7 @@ static inline void sx_wait_CCR(struct specialix_board * bp)
return;
udelay (1);
}
-
+
printk(KERN_ERR "sx%d: Timeout waiting for CCR.\n", board_No(bp));
}
@@ -329,7 +328,7 @@ static inline void sx_wait_CCR_off(struct specialix_board * bp)
return;
udelay (1);
}
-
+
printk(KERN_ERR "sx%d: Timeout waiting for CCR.\n", board_No(bp));
}
@@ -338,34 +337,28 @@ static inline void sx_wait_CCR_off(struct specialix_board * bp)
* specialix IO8+ IO range functions.
*/
-static inline int sx_check_io_range(struct specialix_board * bp)
+static inline int sx_request_io_range(struct specialix_board * bp)
{
- return check_region (bp->base, SX_IO_SPACE);
-}
-
-
-static inline void sx_request_io_range(struct specialix_board * bp)
-{
- request_region(bp->base,
- bp->flags&SX_BOARD_IS_PCI?SX_PCI_IO_SPACE:SX_IO_SPACE,
- "specialix IO8+" );
+ return request_region(bp->base,
+ bp->flags & SX_BOARD_IS_PCI ? SX_PCI_IO_SPACE : SX_IO_SPACE,
+ "specialix IO8+") == NULL;
}
static inline void sx_release_io_range(struct specialix_board * bp)
{
- release_region(bp->base,
+ release_region(bp->base,
bp->flags&SX_BOARD_IS_PCI?SX_PCI_IO_SPACE:SX_IO_SPACE);
}
-
+
/* Must be called with enabled interrupts */
-/* Ugly. Very ugly. Don't use this for anything else than initialization
+/* Ugly. Very ugly. Don't use this for anything else than initialization
code */
static inline void sx_long_delay(unsigned long delay)
{
unsigned long i;
-
+
for (i = jiffies + delay; time_after(i, jiffies); ) ;
}
@@ -378,7 +371,7 @@ static int sx_set_irq ( struct specialix_board *bp)
int i;
unsigned long flags;
- if (bp->flags & SX_BOARD_IS_PCI)
+ if (bp->flags & SX_BOARD_IS_PCI)
return 1;
switch (bp->irq) {
/* In the same order as in the docs... */
@@ -420,7 +413,7 @@ static int sx_init_CD186x(struct specialix_board * bp)
sx_out_off(bp, CD186x_PILR3, SX_ACK_RINT); /* Prio for receiver intr */
/* Set RegAckEn */
sx_out_off(bp, CD186x_SRCR, sx_in (bp, CD186x_SRCR) | SRCR_REGACKEN);
-
+
/* Setting up prescaler. We need 4 ticks per 1 ms */
scaler = SX_OSCFREQ/SPECIALIX_TPS;
@@ -448,7 +441,7 @@ static int read_cross_byte (struct specialix_board *bp, int reg, int bit)
spin_lock_irqsave(&bp->lock, flags);
for (i=0, t=0;i<8;i++) {
sx_out_off (bp, CD186x_CAR, i);
- if (sx_in_off (bp, reg) & bit)
+ if (sx_in_off (bp, reg) & bit)
t |= 1 << i;
}
spin_unlock_irqrestore(&bp->lock, flags);
@@ -472,7 +465,7 @@ void missed_irq (unsigned long data)
spin_unlock_irqrestore(&bp->lock, flags);
if (irq) {
printk (KERN_INFO "Missed interrupt... Calling int from timer. \n");
- sx_interrupt (((struct specialix_board *)data)->irq,
+ sx_interrupt (((struct specialix_board *)data)->irq,
(void*)data, NULL);
}
missed_irq_timer.expires = jiffies + sx_poll;
@@ -495,7 +488,7 @@ static int sx_probe(struct specialix_board *bp)
func_enter();
- if (sx_check_io_range(bp)) {
+ if (sx_request_io_range(bp)) {
func_exit();
return 1;
}
@@ -509,15 +502,16 @@ static int sx_probe(struct specialix_board *bp)
short_pause ();
val2 = sx_in_off(bp, CD186x_PPRL);
-
+
if ((val1 != 0x5a) || (val2 != 0xa5)) {
printk(KERN_INFO "sx%d: specialix IO8+ Board at 0x%03x not found.\n",
board_No(bp), bp->base);
+ sx_release_io_range(bp);
func_exit();
return 1;
}
- /* Check the DSR lines that Specialix uses as board
+ /* Check the DSR lines that Specialix uses as board
identification */
val1 = read_cross_byte (bp, CD186x_MSVR, MSVR_DSR);
val2 = read_cross_byte (bp, CD186x_MSVR, MSVR_RTS);
@@ -532,6 +526,7 @@ static int sx_probe(struct specialix_board *bp)
if (val1 != val2) {
printk(KERN_INFO "sx%d: specialix IO8+ ID %02x at 0x%03x not found (%02x).\n",
board_No(bp), val2, bp->base, val1);
+ sx_release_io_range(bp);
func_exit();
return 1;
}
@@ -546,7 +541,7 @@ static int sx_probe(struct specialix_board *bp)
sx_wait_CCR(bp);
sx_out(bp, CD186x_CCR, CCR_TXEN); /* Enable transmitter */
sx_out(bp, CD186x_IER, IER_TXRDY); /* Enable tx empty intr */
- sx_long_delay(HZ/20);
+ sx_long_delay(HZ/20);
irqs = probe_irq_off(irqs);
dprintk (SX_DEBUG_INIT, "SRSR = %02x, ", sx_in(bp, CD186x_SRSR));
@@ -561,14 +556,15 @@ static int sx_probe(struct specialix_board *bp)
}
dprintk (SX_DEBUG_INIT "val1 = %02x, val2 = %02x, val3 = %02x.\n",
- val1, val2, val3);
-
+ val1, val2, val3);
+
}
-
+
#if 0
if (irqs <= 0) {
printk(KERN_ERR "sx%d: Can't find IRQ for specialix IO8+ board at 0x%03x.\n",
board_No(bp), bp->base);
+ sx_release_io_range(bp);
func_exit();
return 1;
}
@@ -579,19 +575,20 @@ static int sx_probe(struct specialix_board *bp)
#endif
/* Reset CD186x again */
if (!sx_init_CD186x(bp)) {
+ sx_release_io_range(bp);
func_exit();
- return -EIO;
+ return 1;
}
sx_request_io_range(bp);
bp->flags |= SX_BOARD_PRESENT;
-
+
/* Chip revcode pkgtype
GFRCR SRCR bit 7
CD180 rev B 0x81 0
CD180 rev C 0x82 0
CD1864 rev A 0x82 1
- CD1865 rev A 0x83 1 -- Do not use!!! Does not work.
+ CD1865 rev A 0x83 1 -- Do not use!!! Does not work.
CD1865 rev B 0x84 1
-- Thanks to Gwen Wang, Cirrus Logic.
*/
@@ -623,8 +620,8 @@ static int sx_probe(struct specialix_board *bp)
return 0;
}
-/*
- *
+/*
+ *
* Interrupt processing routines.
* */
@@ -657,7 +654,7 @@ static inline struct specialix_port * sx_get_port(struct specialix_board * bp,
return port;
}
}
- printk(KERN_INFO "sx%d: %s interrupt from invalid port %d\n",
+ printk(KERN_INFO "sx%d: %s interrupt from invalid port %d\n",
board_No(bp), what, channel);
return NULL;
}
@@ -681,7 +678,7 @@ static inline void sx_receive_exc(struct specialix_board * bp)
tty = port->tty;
dprintk (SX_DEBUG_RX, "port: %p count: %d BUFF_SIZE: %d\n",
port, tty->flip.count, TTY_FLIPBUF_SIZE);
-
+
status = sx_in(bp, CD186x_RCSR);
dprintk (SX_DEBUG_RX, "status: 0x%x\n", status);
@@ -707,30 +704,30 @@ static inline void sx_receive_exc(struct specialix_board * bp)
return;
}
if (status & RCSR_TOUT) {
- printk(KERN_INFO "sx%d: port %d: Receiver timeout. Hardware problems ?\n",
+ printk(KERN_INFO "sx%d: port %d: Receiver timeout. Hardware problems ?\n",
board_No(bp), port_No(port));
func_exit();
return;
-
+
} else if (status & RCSR_BREAK) {
dprintk(SX_DEBUG_RX, "sx%d: port %d: Handling break...\n",
board_No(bp), port_No(port));
*tty->flip.flag_buf_ptr++ = TTY_BREAK;
if (port->flags & ASYNC_SAK)
do_SAK(tty);
-
- } else if (status & RCSR_PE)
+
+ } else if (status & RCSR_PE)
*tty->flip.flag_buf_ptr++ = TTY_PARITY;
-
- else if (status & RCSR_FE)
+
+ else if (status & RCSR_FE)
*tty->flip.flag_buf_ptr++ = TTY_FRAME;
-
+
else if (status & RCSR_OE)
*tty->flip.flag_buf_ptr++ = TTY_OVERRUN;
-
+
else
*tty->flip.flag_buf_ptr++ = 0;
-
+
*tty->flip.char_buf_ptr++ = ch;
tty->flip.count++;
schedule_delayed_work(&tty->flip.work, 1);
@@ -746,18 +743,18 @@ static inline void sx_receive(struct specialix_board * bp)
unsigned char count;
func_enter();
-
+
if (!(port = sx_get_port(bp, "Receive"))) {
dprintk (SX_DEBUG_RX, "Hmm, couldn't find port.\n");
func_exit();
return;
}
tty = port->tty;
-
+
count = sx_in(bp, CD186x_RDCR);
dprintk (SX_DEBUG_RX, "port: %p: count: %d\n", port, count);
port->hits[count > 8 ? 9 : count]++;
-
+
while (count--) {
if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
printk(KERN_INFO "sx%d: port %d: Working around flip buffer overflow.\n",
@@ -787,7 +784,7 @@ static inline void sx_transmit(struct specialix_board * bp)
}
dprintk (SX_DEBUG_TX, "port: %p\n", port);
tty = port->tty;
-
+
if (port->IER & IER_TXEMPTY) {
/* FIFO drained */
sx_out(bp, CD186x_CAR, port_No(port));
@@ -796,7 +793,7 @@ static inline void sx_transmit(struct specialix_board * bp)
func_exit();
return;
}
-
+
if ((port->xmit_cnt <= 0 && !port->break_length)
|| tty->stopped || tty->hw_stopped) {
sx_out(bp, CD186x_CAR, port_No(port));
@@ -805,7 +802,7 @@ static inline void sx_transmit(struct specialix_board * bp)
func_exit();
return;
}
-
+
if (port->break_length) {
if (port->break_length > 0) {
if (port->COR2 & COR2_ETC) {
@@ -831,7 +828,7 @@ static inline void sx_transmit(struct specialix_board * bp)
func_exit();
return;
}
-
+
count = CD186x_NFIFO;
do {
sx_out(bp, CD186x_TDR, port->xmit_buf[port->xmit_tail++]);
@@ -839,7 +836,7 @@ static inline void sx_transmit(struct specialix_board * bp)
if (--port->xmit_cnt <= 0)
break;
} while (--count > 0);
-
+
if (port->xmit_cnt <= 0) {
sx_out(bp, CD186x_CAR, port_No(port));
port->IER &= ~IER_TXRDY;
@@ -862,9 +859,9 @@ static inline void sx_check_modem(struct specialix_board * bp)
dprintk (SX_DEBUG_SIGNALS, "Modem intr. ");
if (!(port = sx_get_port(bp, "Modem")))
return;
-
+
tty = port->tty;
-
+
mcr = sx_in(bp, CD186x_MCR);
printk ("mcr = %02x.\n", mcr);
@@ -879,7 +876,7 @@ static inline void sx_check_modem(struct specialix_board * bp)
schedule_work(&port->tqueue_hangup);
}
}
-
+
#ifdef SPECIALIX_BRAIN_DAMAGED_CTS
if (mcr & MCR_CTSCHG) {
if (sx_in(bp, CD186x_MSVR) & MSVR_CTS) {
@@ -906,7 +903,7 @@ static inline void sx_check_modem(struct specialix_board * bp)
sx_out(bp, CD186x_IER, port->IER);
}
#endif /* SPECIALIX_BRAIN_DAMAGED_CTS */
-
+
/* Clear change bits */
sx_out(bp, CD186x_MCR, 0);
}
@@ -940,7 +937,7 @@ static irqreturn_t sx_interrupt(int irq, void *dev_id, struct pt_regs *regs)
while ((++loop < 16) && (status = (sx_in(bp, CD186x_SRSR) &
(SRSR_RREQint |
SRSR_TREQint |
- SRSR_MREQint)))) {
+ SRSR_MREQint)))) {
if (status & SRSR_RREQint) {
ack = sx_in(bp, CD186x_RRAR);
@@ -951,7 +948,7 @@ static irqreturn_t sx_interrupt(int irq, void *dev_id, struct pt_regs *regs)
else
printk(KERN_ERR "sx%d: status: 0x%x Bad receive ack 0x%02x.\n",
board_No(bp), status, ack);
-
+
} else if (status & SRSR_TREQint) {
ack = sx_in(bp, CD186x_TRAR);
@@ -963,13 +960,13 @@ static irqreturn_t sx_interrupt(int irq, void *dev_id, struct pt_regs *regs)
} else if (status & SRSR_MREQint) {
ack = sx_in(bp, CD186x_MRAR);
- if (ack == (SX_ID | GIVR_IT_MODEM))
+ if (ack == (SX_ID | GIVR_IT_MODEM))
sx_check_modem(bp);
else
printk(KERN_ERR "sx%d: status: 0x%x Bad modem ack 0x%02x.\n",
board_No(bp), status, ack);
-
- }
+
+ }
sx_out(bp, CD186x_EOIR, 0); /* Mark end of interrupt */
}
@@ -1026,7 +1023,7 @@ static inline int sx_setup_board(struct specialix_board * bp)
{
int error;
- if (bp->flags & SX_BOARD_ACTIVE)
+ if (bp->flags & SX_BOARD_ACTIVE)
return 0;
if (bp->flags & SX_BOARD_IS_PCI)
@@ -1034,7 +1031,7 @@ static inline int sx_setup_board(struct specialix_board * bp)
else
error = request_irq(bp->irq, sx_interrupt, SA_INTERRUPT, "specialix IO8+", bp);
- if (error)
+ if (error)
return error;
turn_ints_on (bp);
@@ -1055,7 +1052,7 @@ static inline void sx_shutdown_board(struct specialix_board *bp)
}
bp->flags &= ~SX_BOARD_ACTIVE;
-
+
dprintk (SX_DEBUG_IRQ, "Freeing IRQ%d for board %d.\n",
bp->irq, board_No (bp));
free_irq(bp->irq, bp);
@@ -1068,7 +1065,7 @@ static inline void sx_shutdown_board(struct specialix_board *bp)
/*
- * Setting up port characteristics.
+ * Setting up port characteristics.
* Must be called with disabled interrupts
*/
static void sx_change_speed(struct specialix_board *bp, struct specialix_port *port)
@@ -1103,10 +1100,10 @@ static void sx_change_speed(struct specialix_board *bp, struct specialix_port *p
spin_unlock_irqrestore(&bp->lock, flags);
dprintk (SX_DEBUG_TERMIOS, "sx: got MSVR=%02x.\n", port->MSVR);
baud = C_BAUD(tty);
-
+
if (baud & CBAUDEX) {
baud &= ~CBAUDEX;
- if (baud < 1 || baud > 2)
+ if (baud < 1 || baud > 2)
port->tty->termios->c_cflag &= ~CBAUDEX;
else
baud += 15;
@@ -1117,8 +1114,8 @@ static void sx_change_speed(struct specialix_board *bp, struct specialix_port *p
if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
baud += 2;
}
-
-
+
+
if (!baud_table[baud]) {
/* Drop DTR & exit */
dprintk (SX_DEBUG_TERMIOS, "Dropping DTR... Hmm....\n");
@@ -1127,7 +1124,7 @@ static void sx_change_speed(struct specialix_board *bp, struct specialix_port *p
spin_lock_irqsave(&bp->lock, flags);
sx_out(bp, CD186x_MSVR, port->MSVR );
spin_unlock_irqrestore(&bp->lock, flags);
- }
+ }
else
dprintk (SX_DEBUG_TERMIOS, "Can't drop DTR: no DTR.\n");
return;
@@ -1137,9 +1134,9 @@ static void sx_change_speed(struct specialix_board *bp, struct specialix_port *p
port ->MSVR |= MSVR_DTR;
}
}
-
+
/*
- * Now we must calculate some speed depended things
+ * Now we must calculate some speed depended things
*/
/* Set baud rate for port */
@@ -1152,7 +1149,7 @@ static void sx_change_speed(struct specialix_board *bp, struct specialix_port *p
tmp = (((SX_OSCFREQ + baud_table[baud]/2) / baud_table[baud] +
CD186x_TPC/2) / CD186x_TPC);
- if ((tmp < 0x10) && time_before(again, jiffies)) {
+ if ((tmp < 0x10) && time_before(again, jiffies)) {
again = jiffies + HZ * 60;
/* Page 48 of version 2.0 of the CL-CD1865 databook */
if (tmp >= 12) {
@@ -1164,27 +1161,27 @@ static void sx_change_speed(struct specialix_board *bp, struct specialix_port *p
printk (KERN_INFO "sx%d: Baud rate divisor is %ld. \n"
"Warning: overstressing Cirrus chip. "
"This might not work.\n"
- "Read specialix.txt for more info.\n",
+ "Read specialix.txt for more info.\n",
port_No (port), tmp);
}
}
spin_lock_irqsave(&bp->lock, flags);
- sx_out(bp, CD186x_RBPRH, (tmp >> 8) & 0xff);
- sx_out(bp, CD186x_TBPRH, (tmp >> 8) & 0xff);
- sx_out(bp, CD186x_RBPRL, tmp & 0xff);
+ sx_out(bp, CD186x_RBPRH, (tmp >> 8) & 0xff);
+ sx_out(bp, CD186x_TBPRH, (tmp >> 8) & 0xff);
+ sx_out(bp, CD186x_RBPRL, tmp & 0xff);
sx_out(bp, CD186x_TBPRL, tmp & 0xff);
spin_unlock_irqrestore(&bp->lock, flags);
if (port->custom_divisor) {
baud = (SX_OSCFREQ + port->custom_divisor/2) / port->custom_divisor;
baud = ( baud + 5 ) / 10;
- } else
+ } else
baud = (baud_table[baud] + 5) / 10; /* Estimated CPS */
/* Two timer ticks seems enough to wakeup something like SLIP driver */
- tmp = ((baud + HZ/2) / HZ) * 2 - CD186x_NFIFO;
+ tmp = ((baud + HZ/2) / HZ) * 2 - CD186x_NFIFO;
port->wakeup_chars = (tmp < 0) ? 0 : ((tmp >= SERIAL_XMIT_SIZE) ?
SERIAL_XMIT_SIZE - 1 : tmp);
-
+
/* Receiver timeout will be transmission time for 1.5 chars */
tmp = (SPECIALIX_TPS + SPECIALIX_TPS/2 + baud/2) / baud;
tmp = (tmp > 0xff) ? 0xff : tmp;
@@ -1205,29 +1202,29 @@ static void sx_change_speed(struct specialix_board *bp, struct specialix_port *p
cor1 |= COR1_8BITS;
break;
}
-
- if (C_CSTOPB(tty))
+
+ if (C_CSTOPB(tty))
cor1 |= COR1_2SB;
-
+
cor1 |= COR1_IGNORE;
if (C_PARENB(tty)) {
cor1 |= COR1_NORMPAR;
- if (C_PARODD(tty))
+ if (C_PARODD(tty))
cor1 |= COR1_ODDP;
- if (I_INPCK(tty))
+ if (I_INPCK(tty))
cor1 &= ~COR1_IGNORE;
}
/* Set marking of some errors */
port->mark_mask = RCSR_OE | RCSR_TOUT;
- if (I_INPCK(tty))
+ if (I_INPCK(tty))
port->mark_mask |= RCSR_FE | RCSR_PE;
- if (I_BRKINT(tty) || I_PARMRK(tty))
+ if (I_BRKINT(tty) || I_PARMRK(tty))
port->mark_mask |= RCSR_BREAK;
- if (I_IGNPAR(tty))
+ if (I_IGNPAR(tty))
port->mark_mask &= ~(RCSR_FE | RCSR_PE);
if (I_IGNBRK(tty)) {
port->mark_mask &= ~RCSR_BREAK;
- if (I_IGNPAR(tty))
+ if (I_IGNPAR(tty))
/* Real raw mode. Ignore all */
port->mark_mask &= ~RCSR_OE;
}
@@ -1241,7 +1238,7 @@ static void sx_change_speed(struct specialix_board *bp, struct specialix_port *p
tty->hw_stopped = !(sx_in(bp, CD186x_MSVR) & (MSVR_CTS|MSVR_DSR));
spin_unlock_irqrestore(&bp->lock, flags);
#else
- port->COR2 |= COR2_CTSAE;
+ port->COR2 |= COR2_CTSAE;
#endif
}
/* Enable Software Flow Control. FIXME: I'm not sure about this */
@@ -1264,11 +1261,11 @@ static void sx_change_speed(struct specialix_board *bp, struct specialix_port *p
mcor1 |= MCOR1_CDZD;
mcor2 |= MCOR2_CDOD;
}
-
- if (C_CREAD(tty))
+
+ if (C_CREAD(tty))
/* Enable receiver */
port->IER |= IER_RXD;
-
+
/* Set input FIFO size (1-8 bytes) */
cor3 |= sx_rxfifo;
/* Setting up CD186x channel registers */
@@ -1311,11 +1308,11 @@ static int sx_setup_port(struct specialix_board *bp, struct specialix_port *port
func_exit();
return 0;
}
-
+
if (!port->xmit_buf) {
/* We may sleep in get_zeroed_page() */
unsigned long tmp;
-
+
if (!(tmp = get_zeroed_page(GFP_KERNEL))) {
func_exit();
return -ENOMEM;
@@ -1328,10 +1325,10 @@ static int sx_setup_port(struct specialix_board *bp, struct specialix_port *port
}
port->xmit_buf = (unsigned char *) tmp;
}
-
+
spin_lock_irqsave(&port->lock, flags);
- if (port->tty)
+ if (port->tty)
clear_bit(TTY_IO_ERROR, &port->tty->flags);
port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
@@ -1340,7 +1337,7 @@ static int sx_setup_port(struct specialix_board *bp, struct specialix_port *port
spin_unlock_irqrestore(&port->lock, flags);
-
+
func_exit();
return 0;
}
@@ -1352,14 +1349,14 @@ static void sx_shutdown_port(struct specialix_board *bp, struct specialix_port *
struct tty_struct *tty;
int i;
unsigned long flags;
-
+
func_enter();
if (!(port->flags & ASYNC_INITIALIZED)) {
func_exit();
return;
}
-
+
if (sx_debug & SX_DEBUG_FIFO) {
dprintk(SX_DEBUG_FIFO, "sx%d: port %d: %ld overruns, FIFO hits [ ",
board_No(bp), port_No(port), port->overrun);
@@ -1394,13 +1391,13 @@ static void sx_shutdown_port(struct specialix_board *bp, struct specialix_port *
if (tty)
set_bit(TTY_IO_ERROR, &tty->flags);
port->flags &= ~ASYNC_INITIALIZED;
-
- if (!bp->count)
+
+ if (!bp->count)
sx_shutdown_board(bp);
func_exit();
}
-
+
static int block_til_ready(struct tty_struct *tty, struct file * filp,
struct specialix_port *port)
{
@@ -1427,7 +1424,7 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp,
return -ERESTARTSYS;
}
}
-
+
/*
* If non-blocking mode is set, or the port is not enabled,
* then make the check up front and then exit.
@@ -1477,7 +1474,7 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp,
if (port->flags & ASYNC_HUP_NOTIFY)
retval = -EAGAIN;
else
- retval = -ERESTARTSYS;
+ retval = -ERESTARTSYS;
break;
}
if (!(port->flags & ASYNC_CLOSING) &&
@@ -1506,7 +1503,7 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp,
port->flags |= ASYNC_NORMAL_ACTIVE;
func_exit();
return 0;
-}
+}
static int sx_open(struct tty_struct * tty, struct file * filp)
@@ -1526,7 +1523,7 @@ static int sx_open(struct tty_struct * tty, struct file * filp)
func_exit();
return -ENODEV;
}
-
+
bp = &sx_board[board];
port = sx_port + board * SX_NPORT + SX_PORT(tty->index);
port->overrun = 0;
@@ -1557,7 +1554,7 @@ static int sx_open(struct tty_struct * tty, struct file * filp)
func_enter();
return error;
}
-
+
if ((error = block_til_ready(tty, filp, port))) {
func_enter();
return error;
@@ -1574,7 +1571,7 @@ static void sx_close(struct tty_struct * tty, struct file * filp)
struct specialix_board *bp;
unsigned long flags;
unsigned long timeout;
-
+
func_enter();
if (!port || sx_paranoia_check(port, tty->name, "close")) {
func_exit();
@@ -1587,7 +1584,7 @@ static void sx_close(struct tty_struct * tty, struct file * filp)
func_exit();
return;
}
-
+
bp = port_Board(port);
if ((tty->count == 1) && (port->count != 1)) {
printk(KERN_ERR "sx%d: sx_close: bad port count;"
@@ -1607,7 +1604,7 @@ static void sx_close(struct tty_struct * tty, struct file * filp)
}
port->flags |= ASYNC_CLOSING;
/*
- * Now we wait for the transmit buffer to clear; and we notify
+ * Now we wait for the transmit buffer to clear; and we notify
* the line discipline to only process XON/XOFF characters.
*/
tty->closing = 1;
@@ -1681,7 +1678,7 @@ static void sx_close(struct tty_struct * tty, struct file * filp)
}
-static int sx_write(struct tty_struct * tty,
+static int sx_write(struct tty_struct * tty,
const unsigned char *buf, int count)
{
struct specialix_port *port = (struct specialix_port *)tty->driver_data;
@@ -1694,7 +1691,7 @@ static int sx_write(struct tty_struct * tty,
func_exit();
return 0;
}
-
+
bp = port_Board(port);
if (!tty || !port->xmit_buf || !tmp_buf) {
@@ -1824,7 +1821,7 @@ static int sx_chars_in_buffer(struct tty_struct *tty)
struct specialix_port *port = (struct specialix_port *)tty->driver_data;
func_enter();
-
+
if (sx_paranoia_check(port, tty->name, "sx_chars_in_buffer")) {
func_exit();
return 0;
@@ -1881,13 +1878,13 @@ static int sx_tiocmget(struct tty_struct *tty, struct file *file)
port_No(port), status, sx_in (bp, CD186x_CAR));
dprintk (SX_DEBUG_INIT, "sx_port = %p, port = %p\n", sx_port, port);
if (SX_CRTSCTS(port->tty)) {
- result = /* (status & MSVR_RTS) ? */ TIOCM_DTR /* : 0) */
+ result = /* (status & MSVR_RTS) ? */ TIOCM_DTR /* : 0) */
| ((status & MSVR_DTR) ? TIOCM_RTS : 0)
| ((status & MSVR_CD) ? TIOCM_CAR : 0)
|/* ((status & MSVR_DSR) ? */ TIOCM_DSR /* : 0) */
| ((status & MSVR_CTS) ? TIOCM_CTS : 0);
} else {
- result = /* (status & MSVR_RTS) ? */ TIOCM_RTS /* : 0) */
+ result = /* (status & MSVR_RTS) ? */ TIOCM_RTS /* : 0) */
| ((status & MSVR_DTR) ? TIOCM_DTR : 0)
| ((status & MSVR_CD) ? TIOCM_CAR : 0)
|/* ((status & MSVR_DSR) ? */ TIOCM_DSR /* : 0) */
@@ -1955,7 +1952,7 @@ static inline void sx_send_break(struct specialix_port * port, unsigned long len
{
struct specialix_board *bp = port_Board(port);
unsigned long flags;
-
+
func_enter();
spin_lock_irqsave (&port->lock, flags);
@@ -1996,8 +1993,8 @@ static inline int sx_set_serial_info(struct specialix_port * port,
func_enter();
return -EFAULT;
}
-
-#if 0
+
+#if 0
if ((tmp.irq != bp->irq) ||
(tmp.port != bp->base) ||
(tmp.type != PORT_CIRRUS) ||
@@ -2008,12 +2005,12 @@ static inline int sx_set_serial_info(struct specialix_port * port,
func_exit();
return -EINVAL;
}
-#endif
+#endif
change_speed = ((port->flags & ASYNC_SPD_MASK) !=
(tmp.flags & ASYNC_SPD_MASK));
change_speed |= (tmp.custom_divisor != port->custom_divisor);
-
+
if (!capable(CAP_SYS_ADMIN)) {
if ((tmp.close_delay != port->close_delay) ||
(tmp.closing_wait != port->closing_wait) ||
@@ -2045,7 +2042,7 @@ static inline int sx_get_serial_info(struct specialix_port * port,
{
struct serial_struct tmp;
struct specialix_board *bp = port_Board(port);
-
+
func_enter();
/*
@@ -2074,7 +2071,7 @@ static inline int sx_get_serial_info(struct specialix_port * port,
}
-static int sx_ioctl(struct tty_struct * tty, struct file * filp,
+static int sx_ioctl(struct tty_struct * tty, struct file * filp,
unsigned int cmd, unsigned long arg)
{
struct specialix_port *port = (struct specialix_port *)tty->driver_data;
@@ -2087,7 +2084,7 @@ static int sx_ioctl(struct tty_struct * tty, struct file * filp,
func_exit();
return -ENODEV;
}
-
+
switch (cmd) {
case TCSBRK: /* SVID version: non-zero arg --> no break */
retval = tty_check_change(tty);
@@ -2129,7 +2126,7 @@ static int sx_ioctl(struct tty_struct * tty, struct file * filp,
case TIOCGSERIAL:
func_exit();
return sx_get_serial_info(port, argp);
- case TIOCSSERIAL:
+ case TIOCSSERIAL:
func_exit();
return sx_set_serial_info(port, argp);
default:
@@ -2153,16 +2150,16 @@ static void sx_throttle(struct tty_struct * tty)
func_exit();
return;
}
-
+
bp = port_Board(port);
-
+
/* Use DTR instead of RTS ! */
- if (SX_CRTSCTS (tty))
+ if (SX_CRTSCTS (tty))
port->MSVR &= ~MSVR_DTR;
else {
/* Auch!!! I think the system shouldn't call this then. */
/* Or maybe we're supposed (allowed?) to do our side of hw
- handshake anyway, even when hardware handshake is off.
+ handshake anyway, even when hardware handshake is off.
When you see this in your logs, please report.... */
printk (KERN_ERR "sx%d: Need to throttle, but can't (hardware hs is off)\n",
port_No (port));
@@ -2193,14 +2190,14 @@ static void sx_unthrottle(struct tty_struct * tty)
unsigned long flags;
func_enter();
-
+
if (sx_paranoia_check(port, tty->name, "sx_unthrottle")) {
func_exit();
return;
}
-
+
bp = port_Board(port);
-
+
spin_lock_irqsave(&port->lock, flags);
/* XXXX Use DTR INSTEAD???? */
if (SX_CRTSCTS(tty)) {
@@ -2234,14 +2231,14 @@ static void sx_stop(struct tty_struct * tty)
unsigned long flags;
func_enter();
-
+
if (sx_paranoia_check(port, tty->name, "sx_stop")) {
func_exit();
return;
}
bp = port_Board(port);
-
+
spin_lock_irqsave(&port->lock, flags);
port->IER &= ~IER_TXRDY;
spin_lock_irqsave(&bp->lock, flags);
@@ -2261,14 +2258,14 @@ static void sx_start(struct tty_struct * tty)
unsigned long flags;
func_enter();
-
+
if (sx_paranoia_check(port, tty->name, "sx_start")) {
func_exit();
return;
}
-
+
bp = port_Board(port);
-
+
spin_lock_irqsave(&port->lock, flags);
if (port->xmit_cnt && port->xmit_buf && !(port->IER & IER_TXRDY)) {
port->IER |= IER_TXRDY;
@@ -2290,13 +2287,13 @@ static void sx_start(struct tty_struct * tty)
*
* serial interrupt routine -> (workqueue) ->
* do_sx_hangup() -> tty->hangup() -> sx_hangup()
- *
+ *
*/
static void do_sx_hangup(void *private_)
{
struct specialix_port *port = (struct specialix_port *) private_;
struct tty_struct *tty;
-
+
func_enter();
tty = port->tty;
@@ -2319,9 +2316,9 @@ static void sx_hangup(struct tty_struct * tty)
func_exit();
return;
}
-
+
bp = port_Board(port);
-
+
sx_shutdown_port(bp, port);
spin_lock_irqsave(&port->lock, flags);
port->event = 0;
@@ -2346,10 +2343,10 @@ static void sx_set_termios(struct tty_struct * tty, struct termios * old_termios
struct specialix_port *port = (struct specialix_port *)tty->driver_data;
unsigned long flags;
struct specialix_board * bp;
-
+
if (sx_paranoia_check(port, tty->name, "sx_set_termios"))
return;
-
+
if (tty->termios->c_cflag == old_termios->c_cflag &&
tty->termios->c_iflag == old_termios->c_iflag)
return;
@@ -2420,7 +2417,7 @@ static int sx_init_drivers(void)
func_exit();
return 1;
}
-
+
if (!(tmp_buf = (unsigned char *) get_zeroed_page(GFP_KERNEL))) {
printk(KERN_ERR "sx: Couldn't get free page.\n");
put_tty_driver(specialix_driver);
@@ -2457,7 +2454,7 @@ static int sx_init_drivers(void)
init_waitqueue_head(&sx_port[i].close_wait);
spin_lock_init(&sx_port[i].lock);
}
-
+
func_exit();
return 0;
}
@@ -2472,8 +2469,8 @@ static void sx_release_drivers(void)
func_exit();
}
-/*
- * This routine must be called by kernel at boot time
+/*
+ * This routine must be called by kernel at boot time
*/
static int __init specialix_init(void)
{
@@ -2489,7 +2486,7 @@ static int __init specialix_init(void)
#else
printk (KERN_INFO "sx: DTR/RTS pin is RTS when CRTSCTS is on.\n");
#endif
-
+
for (i = 0; i < SX_NBOARD; i++)
sx_board[i].lock = SPIN_LOCK_UNLOCKED;
@@ -2498,7 +2495,7 @@ static int __init specialix_init(void)
return -EIO;
}
- for (i = 0; i < SX_NBOARD; i++)
+ for (i = 0; i < SX_NBOARD; i++)
if (sx_board[i].base && !sx_probe(&sx_board[i]))
found++;
@@ -2512,8 +2509,8 @@ static int __init specialix_init(void)
i++;
continue;
}
- pdev = pci_find_device (PCI_VENDOR_ID_SPECIALIX,
- PCI_DEVICE_ID_SPECIALIX_IO8,
+ pdev = pci_find_device (PCI_VENDOR_ID_SPECIALIX,
+ PCI_DEVICE_ID_SPECIALIX_IO8,
pdev);
if (!pdev) break;
@@ -2557,10 +2554,10 @@ module_param(sx_poll, int, 0);
/*
* You can setup up to 4 boards.
* by specifying "iobase=0xXXX,0xXXX ..." as insmod parameter.
- * You should specify the IRQs too in that case "irq=....,...".
- *
+ * You should specify the IRQs too in that case "irq=....,...".
+ *
* More than 4 boards in one computer is not possible, as the card can
- * only use 4 different interrupts.
+ * only use 4 different interrupts.
*
*/
static int __init specialix_init_module(void)
@@ -2583,16 +2580,16 @@ static int __init specialix_init_module(void)
return specialix_init();
}
-
+
static void __exit specialix_exit_module(void)
{
int i;
-
+
func_enter();
sx_release_drivers();
for (i = 0; i < SX_NBOARD; i++)
- if (sx_board[i].flags & SX_BOARD_PRESENT)
+ if (sx_board[i].flags & SX_BOARD_PRESENT)
sx_release_io_range(&sx_board[i]);
#ifdef SPECIALIX_TIMER
del_timer (&missed_irq_timer);
diff --git a/drivers/char/stallion.c b/drivers/char/stallion.c
index 951545a6ef2d..95af2a941595 100644
--- a/drivers/char/stallion.c
+++ b/drivers/char/stallion.c
@@ -785,8 +785,7 @@ static void __exit stallion_module_exit(void)
"errno=%d\n", -i);
class_destroy(stallion_class);
- if (stl_tmpwritebuf != (char *) NULL)
- kfree(stl_tmpwritebuf);
+ kfree(stl_tmpwritebuf);
for (i = 0; (i < stl_nrbrds); i++) {
if ((brdp = stl_brds[i]) == (stlbrd_t *) NULL)
@@ -804,8 +803,7 @@ static void __exit stallion_module_exit(void)
continue;
if (portp->tty != (struct tty_struct *) NULL)
stl_hangup(portp->tty);
- if (portp->tx.buf != (char *) NULL)
- kfree(portp->tx.buf);
+ kfree(portp->tx.buf);
kfree(portp);
}
kfree(panelp);
@@ -3095,7 +3093,9 @@ static int __init stl_init(void)
devfs_mk_cdev(MKDEV(STL_SIOMEMMAJOR, i),
S_IFCHR|S_IRUSR|S_IWUSR,
"staliomem/%d", i);
- class_device_create(stallion_class, MKDEV(STL_SIOMEMMAJOR, i), NULL, "staliomem%d", i);
+ class_device_create(stallion_class, NULL,
+ MKDEV(STL_SIOMEMMAJOR, i), NULL,
+ "staliomem%d", i);
}
stl_serial->owner = THIS_MODULE;
diff --git a/drivers/char/synclink.c b/drivers/char/synclink.c
index ea2d54be4843..82c6abde68df 100644
--- a/drivers/char/synclink.c
+++ b/drivers/char/synclink.c
@@ -4015,9 +4015,7 @@ static int mgsl_alloc_intermediate_rxbuffer_memory(struct mgsl_struct *info)
*/
static void mgsl_free_intermediate_rxbuffer_memory(struct mgsl_struct *info)
{
- if ( info->intermediate_rxbuffer )
- kfree(info->intermediate_rxbuffer);
-
+ kfree(info->intermediate_rxbuffer);
info->intermediate_rxbuffer = NULL;
} /* end of mgsl_free_intermediate_rxbuffer_memory() */
@@ -4071,10 +4069,8 @@ static void mgsl_free_intermediate_txbuffer_memory(struct mgsl_struct *info)
int i;
for ( i=0; i<info->num_tx_holding_buffers; ++i ) {
- if ( info->tx_holding_buffers[i].buffer ) {
- kfree(info->tx_holding_buffers[i].buffer);
- info->tx_holding_buffers[i].buffer=NULL;
- }
+ kfree(info->tx_holding_buffers[i].buffer);
+ info->tx_holding_buffers[i].buffer = NULL;
}
info->get_tx_holding_index = 0;
diff --git a/drivers/char/synclinkmp.c b/drivers/char/synclinkmp.c
index 6fb165cf8a61..ee5a40be9f99 100644
--- a/drivers/char/synclinkmp.c
+++ b/drivers/char/synclinkmp.c
@@ -2787,10 +2787,8 @@ static void shutdown(SLMP_INFO * info)
del_timer(&info->tx_timer);
del_timer(&info->status_timer);
- if (info->tx_buf) {
- kfree(info->tx_buf);
- info->tx_buf = NULL;
- }
+ kfree(info->tx_buf);
+ info->tx_buf = NULL;
spin_lock_irqsave(&info->lock,flags);
@@ -3610,8 +3608,7 @@ int alloc_tmp_rx_buf(SLMP_INFO *info)
void free_tmp_rx_buf(SLMP_INFO *info)
{
- if (info->tmp_rx_buf)
- kfree(info->tmp_rx_buf);
+ kfree(info->tmp_rx_buf);
info->tmp_rx_buf = NULL;
}
diff --git a/drivers/char/sysrq.c b/drivers/char/sysrq.c
index feb25158c8ee..145275ebdd7e 100644
--- a/drivers/char/sysrq.c
+++ b/drivers/char/sysrq.c
@@ -354,7 +354,7 @@ struct sysrq_key_op *__sysrq_get_key_op (int key) {
return op_p;
}
-void __sysrq_put_key_op (int key, struct sysrq_key_op *op_p) {
+static void __sysrq_put_key_op (int key, struct sysrq_key_op *op_p) {
int i;
i = sysrq_key_table_key2index(key);
@@ -419,7 +419,7 @@ void handle_sysrq(int key, struct pt_regs *pt_regs, struct tty_struct *tty)
__handle_sysrq(key, pt_regs, tty, 1);
}
-int __sysrq_swap_key_ops(int key, struct sysrq_key_op *insert_op_p,
+static int __sysrq_swap_key_ops(int key, struct sysrq_key_op *insert_op_p,
struct sysrq_key_op *remove_op_p) {
int retval;
diff --git a/drivers/char/tb0219.c b/drivers/char/tb0219.c
index eb7058cbf015..24355b23b2ca 100644
--- a/drivers/char/tb0219.c
+++ b/drivers/char/tb0219.c
@@ -17,7 +17,7 @@
* 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/device.h>
+#include <linux/platform_device.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/module.h>
diff --git a/drivers/char/tipar.c b/drivers/char/tipar.c
index ec78d2f161f7..41a94bc79f67 100644
--- a/drivers/char/tipar.c
+++ b/drivers/char/tipar.c
@@ -436,7 +436,7 @@ tipar_register(int nr, struct parport *port)
goto out;
}
- class_device_create(tipar_class, MKDEV(TIPAR_MAJOR,
+ class_device_create(tipar_class, NULL, MKDEV(TIPAR_MAJOR,
TIPAR_MINOR + nr), NULL, "par%d", nr);
/* Use devfs, tree: /dev/ticables/par/[0..2] */
err = devfs_mk_cdev(MKDEV(TIPAR_MAJOR, TIPAR_MINOR + nr),
diff --git a/drivers/char/tlclk.c b/drivers/char/tlclk.c
new file mode 100644
index 000000000000..12167c04fa4c
--- /dev/null
+++ b/drivers/char/tlclk.c
@@ -0,0 +1,897 @@
+/*
+ * Telecom Clock driver for Intel NetStructure(tm) MPCBL0010
+ *
+ * Copyright (C) 2005 Kontron Canada
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. 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.
+ *
+ * Send feedback to <sebastien.bouchard@ca.kontron.com> and the current
+ * Maintainer <mark.gross@intel.com>
+ *
+ * Description : This is the TELECOM CLOCK module driver for the ATCA
+ * MPCBL0010 ATCA computer.
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/kernel.h> /* printk() */
+#include <linux/fs.h> /* everything... */
+#include <linux/errno.h> /* error codes */
+#include <linux/delay.h> /* udelay */
+#include <linux/slab.h>
+#include <linux/ioport.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+#include <linux/timer.h>
+#include <linux/sysfs.h>
+#include <linux/device.h>
+#include <linux/miscdevice.h>
+#include <linux/platform_device.h>
+#include <asm/io.h> /* inb/outb */
+#include <asm/uaccess.h>
+
+MODULE_AUTHOR("Sebastien Bouchard <sebastien.bouchard@ca.kontron.com>");
+MODULE_LICENSE("GPL");
+
+/*Hardware Reset of the PLL */
+#define RESET_ON 0x00
+#define RESET_OFF 0x01
+
+/* MODE SELECT */
+#define NORMAL_MODE 0x00
+#define HOLDOVER_MODE 0x10
+#define FREERUN_MODE 0x20
+
+/* FILTER SELECT */
+#define FILTER_6HZ 0x04
+#define FILTER_12HZ 0x00
+
+/* SELECT REFERENCE FREQUENCY */
+#define REF_CLK1_8kHz 0x00
+#define REF_CLK2_19_44MHz 0x02
+
+/* Select primary or secondary redundant clock */
+#define PRIMARY_CLOCK 0x00
+#define SECONDARY_CLOCK 0x01
+
+/* CLOCK TRANSMISSION DEFINE */
+#define CLK_8kHz 0xff
+#define CLK_16_384MHz 0xfb
+
+#define CLK_1_544MHz 0x00
+#define CLK_2_048MHz 0x01
+#define CLK_4_096MHz 0x02
+#define CLK_6_312MHz 0x03
+#define CLK_8_192MHz 0x04
+#define CLK_19_440MHz 0x06
+
+#define CLK_8_592MHz 0x08
+#define CLK_11_184MHz 0x09
+#define CLK_34_368MHz 0x0b
+#define CLK_44_736MHz 0x0a
+
+/* RECEIVED REFERENCE */
+#define AMC_B1 0
+#define AMC_B2 1
+
+/* HARDWARE SWITCHING DEFINE */
+#define HW_ENABLE 0x80
+#define HW_DISABLE 0x00
+
+/* HARDWARE SWITCHING MODE DEFINE */
+#define PLL_HOLDOVER 0x40
+#define LOST_CLOCK 0x00
+
+/* ALARMS DEFINE */
+#define UNLOCK_MASK 0x10
+#define HOLDOVER_MASK 0x20
+#define SEC_LOST_MASK 0x40
+#define PRI_LOST_MASK 0x80
+
+/* INTERRUPT CAUSE DEFINE */
+
+#define PRI_LOS_01_MASK 0x01
+#define PRI_LOS_10_MASK 0x02
+
+#define SEC_LOS_01_MASK 0x04
+#define SEC_LOS_10_MASK 0x08
+
+#define HOLDOVER_01_MASK 0x10
+#define HOLDOVER_10_MASK 0x20
+
+#define UNLOCK_01_MASK 0x40
+#define UNLOCK_10_MASK 0x80
+
+struct tlclk_alarms {
+ __u32 lost_clocks;
+ __u32 lost_primary_clock;
+ __u32 lost_secondary_clock;
+ __u32 primary_clock_back;
+ __u32 secondary_clock_back;
+ __u32 switchover_primary;
+ __u32 switchover_secondary;
+ __u32 pll_holdover;
+ __u32 pll_end_holdover;
+ __u32 pll_lost_sync;
+ __u32 pll_sync;
+};
+/* Telecom clock I/O register definition */
+#define TLCLK_BASE 0xa08
+#define TLCLK_REG0 TLCLK_BASE
+#define TLCLK_REG1 (TLCLK_BASE+1)
+#define TLCLK_REG2 (TLCLK_BASE+2)
+#define TLCLK_REG3 (TLCLK_BASE+3)
+#define TLCLK_REG4 (TLCLK_BASE+4)
+#define TLCLK_REG5 (TLCLK_BASE+5)
+#define TLCLK_REG6 (TLCLK_BASE+6)
+#define TLCLK_REG7 (TLCLK_BASE+7)
+
+#define SET_PORT_BITS(port, mask, val) outb(((inb(port) & mask) | val), port)
+
+/* 0 = Dynamic allocation of the major device number */
+#define TLCLK_MAJOR 0
+
+/* sysfs interface definition:
+Upon loading the driver will create a sysfs directory under
+/sys/devices/platform/telco_clock.
+
+This directory exports the following interfaces. There operation is
+documented in the MCPBL0010 TPS under the Telecom Clock API section, 11.4.
+alarms :
+current_ref :
+enable_clk3a_output :
+enable_clk3b_output :
+enable_clka0_output :
+enable_clka1_output :
+enable_clkb0_output :
+enable_clkb1_output :
+filter_select :
+hardware_switching :
+hardware_switching_mode :
+interrupt_switch :
+mode_select :
+refalign :
+reset :
+select_amcb1_transmit_clock :
+select_amcb2_transmit_clock :
+select_redundant_clock :
+select_ref_frequency :
+test_mode :
+
+All sysfs interfaces are integers in hex format, i.e echo 99 > refalign
+has the same effect as echo 0x99 > refalign.
+*/
+
+static unsigned int telclk_interrupt;
+
+static int int_events; /* Event that generate a interrupt */
+static int got_event; /* if events processing have been done */
+
+static void switchover_timeout(unsigned long data);
+static struct timer_list switchover_timer =
+ TIMER_INITIALIZER(switchover_timeout , 0, 0);
+
+static struct tlclk_alarms *alarm_events;
+
+static DEFINE_SPINLOCK(event_lock);
+
+static int tlclk_major = TLCLK_MAJOR;
+
+static irqreturn_t tlclk_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+
+static DECLARE_WAIT_QUEUE_HEAD(wq);
+
+static int tlclk_open(struct inode *inode, struct file *filp)
+{
+ int result;
+
+ /* Make sure there is no interrupt pending while
+ * initialising interrupt handler */
+ inb(TLCLK_REG6);
+
+ /* This device is wired through the FPGA IO space of the ATCA blade
+ * we can't share this IRQ */
+ result = request_irq(telclk_interrupt, &tlclk_interrupt,
+ SA_INTERRUPT, "telco_clock", tlclk_interrupt);
+ if (result == -EBUSY) {
+ printk(KERN_ERR "telco_clock: Interrupt can't be reserved!\n");
+ return -EBUSY;
+ }
+ inb(TLCLK_REG6); /* Clear interrupt events */
+
+ return 0;
+}
+
+static int tlclk_release(struct inode *inode, struct file *filp)
+{
+ free_irq(telclk_interrupt, tlclk_interrupt);
+
+ return 0;
+}
+
+ssize_t tlclk_read(struct file *filp, char __user *buf, size_t count,
+ loff_t *f_pos)
+{
+ if (count < sizeof(struct tlclk_alarms))
+ return -EIO;
+
+ wait_event_interruptible(wq, got_event);
+ if (copy_to_user(buf, alarm_events, sizeof(struct tlclk_alarms)))
+ return -EFAULT;
+
+ memset(alarm_events, 0, sizeof(struct tlclk_alarms));
+ got_event = 0;
+
+ return sizeof(struct tlclk_alarms);
+}
+
+ssize_t tlclk_write(struct file *filp, const char __user *buf, size_t count,
+ loff_t *f_pos)
+{
+ return 0;
+}
+
+static struct file_operations tlclk_fops = {
+ .read = tlclk_read,
+ .write = tlclk_write,
+ .open = tlclk_open,
+ .release = tlclk_release,
+
+};
+
+static struct miscdevice tlclk_miscdev = {
+ .minor = MISC_DYNAMIC_MINOR,
+ .name = "telco_clock",
+ .fops = &tlclk_fops,
+};
+
+static ssize_t show_current_ref(struct device *d,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned long ret_val;
+ unsigned long flags;
+
+ spin_lock_irqsave(&event_lock, flags);
+ ret_val = ((inb(TLCLK_REG1) & 0x08) >> 3);
+ spin_unlock_irqrestore(&event_lock, flags);
+
+ return sprintf(buf, "0x%lX\n", ret_val);
+}
+
+static DEVICE_ATTR(current_ref, S_IRUGO, show_current_ref, NULL);
+
+
+static ssize_t show_interrupt_switch(struct device *d,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned long ret_val;
+ unsigned long flags;
+
+ spin_lock_irqsave(&event_lock, flags);
+ ret_val = inb(TLCLK_REG6);
+ spin_unlock_irqrestore(&event_lock, flags);
+
+ return sprintf(buf, "0x%lX\n", ret_val);
+}
+
+static DEVICE_ATTR(interrupt_switch, S_IRUGO,
+ show_interrupt_switch, NULL);
+
+static ssize_t show_alarms(struct device *d,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned long ret_val;
+ unsigned long flags;
+
+ spin_lock_irqsave(&event_lock, flags);
+ ret_val = (inb(TLCLK_REG2) & 0xf0);
+ spin_unlock_irqrestore(&event_lock, flags);
+
+ return sprintf(buf, "0x%lX\n", ret_val);
+}
+
+static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);
+
+static ssize_t store_enable_clk3b_output(struct device *d,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ unsigned long tmp;
+ unsigned char val;
+ unsigned long flags;
+
+ sscanf(buf, "%lX", &tmp);
+ dev_dbg(d, ": tmp = 0x%lX\n", tmp);
+
+ val = (unsigned char)tmp;
+ spin_lock_irqsave(&event_lock, flags);
+ SET_PORT_BITS(TLCLK_REG3, 0x7f, val << 7);
+ spin_unlock_irqrestore(&event_lock, flags);
+
+ return strnlen(buf, count);
+}
+
+static DEVICE_ATTR(enable_clk3b_output, S_IWUGO, NULL,
+ store_enable_clk3b_output);
+
+static ssize_t store_enable_clk3a_output(struct device *d,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ unsigned long flags;
+ unsigned long tmp;
+ unsigned char val;
+
+ sscanf(buf, "%lX", &tmp);
+ dev_dbg(d, "tmp = 0x%lX\n", tmp);
+
+ val = (unsigned char)tmp;
+ spin_lock_irqsave(&event_lock, flags);
+ SET_PORT_BITS(TLCLK_REG3, 0xbf, val << 6);
+ spin_unlock_irqrestore(&event_lock, flags);
+
+ return strnlen(buf, count);
+}
+
+static DEVICE_ATTR(enable_clk3a_output, S_IWUGO, NULL,
+ store_enable_clk3a_output);
+
+static ssize_t store_enable_clkb1_output(struct device *d,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ unsigned long flags;
+ unsigned long tmp;
+ unsigned char val;
+
+ sscanf(buf, "%lX", &tmp);
+ dev_dbg(d, "tmp = 0x%lX\n", tmp);
+
+ val = (unsigned char)tmp;
+ spin_lock_irqsave(&event_lock, flags);
+ SET_PORT_BITS(TLCLK_REG2, 0xf7, val << 3);
+ spin_unlock_irqrestore(&event_lock, flags);
+
+ return strnlen(buf, count);
+}
+
+static DEVICE_ATTR(enable_clkb1_output, S_IWUGO, NULL,
+ store_enable_clkb1_output);
+
+
+static ssize_t store_enable_clka1_output(struct device *d,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ unsigned long flags;
+ unsigned long tmp;
+ unsigned char val;
+
+ sscanf(buf, "%lX", &tmp);
+ dev_dbg(d, "tmp = 0x%lX\n", tmp);
+
+ val = (unsigned char)tmp;
+ spin_lock_irqsave(&event_lock, flags);
+ SET_PORT_BITS(TLCLK_REG2, 0xfb, val << 2);
+ spin_unlock_irqrestore(&event_lock, flags);
+
+ return strnlen(buf, count);
+}
+
+static DEVICE_ATTR(enable_clka1_output, S_IWUGO, NULL,
+ store_enable_clka1_output);
+
+static ssize_t store_enable_clkb0_output(struct device *d,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ unsigned long flags;
+ unsigned long tmp;
+ unsigned char val;
+
+ sscanf(buf, "%lX", &tmp);
+ dev_dbg(d, "tmp = 0x%lX\n", tmp);
+
+ val = (unsigned char)tmp;
+ spin_lock_irqsave(&event_lock, flags);
+ SET_PORT_BITS(TLCLK_REG2, 0xfd, val << 1);
+ spin_unlock_irqrestore(&event_lock, flags);
+
+ return strnlen(buf, count);
+}
+
+static DEVICE_ATTR(enable_clkb0_output, S_IWUGO, NULL,
+ store_enable_clkb0_output);
+
+static ssize_t store_enable_clka0_output(struct device *d,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ unsigned long flags;
+ unsigned long tmp;
+ unsigned char val;
+
+ sscanf(buf, "%lX", &tmp);
+ dev_dbg(d, "tmp = 0x%lX\n", tmp);
+
+ val = (unsigned char)tmp;
+ spin_lock_irqsave(&event_lock, flags);
+ SET_PORT_BITS(TLCLK_REG2, 0xfe, val);
+ spin_unlock_irqrestore(&event_lock, flags);
+
+ return strnlen(buf, count);
+}
+
+static DEVICE_ATTR(enable_clka0_output, S_IWUGO, NULL,
+ store_enable_clka0_output);
+
+static ssize_t store_test_mode(struct device *d,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ unsigned long flags;
+ unsigned long tmp;
+ unsigned char val;
+
+ sscanf(buf, "%lX", &tmp);
+ dev_dbg(d, "tmp = 0x%lX\n", tmp);
+
+ val = (unsigned char)tmp;
+ spin_lock_irqsave(&event_lock, flags);
+ SET_PORT_BITS(TLCLK_REG4, 0xfd, 2);
+ spin_unlock_irqrestore(&event_lock, flags);
+
+ return strnlen(buf, count);
+}
+
+static DEVICE_ATTR(test_mode, S_IWUGO, NULL, store_test_mode);
+
+static ssize_t store_select_amcb2_transmit_clock(struct device *d,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ unsigned long flags;
+ unsigned long tmp;
+ unsigned char val;
+
+ sscanf(buf, "%lX", &tmp);
+ dev_dbg(d, "tmp = 0x%lX\n", tmp);
+
+ val = (unsigned char)tmp;
+ spin_lock_irqsave(&event_lock, flags);
+ if ((val == CLK_8kHz) || (val == CLK_16_384MHz)) {
+ SET_PORT_BITS(TLCLK_REG3, 0xc7, 0x28);
+ SET_PORT_BITS(TLCLK_REG1, 0xfb, ~val);
+ } else if (val >= CLK_8_592MHz) {
+ SET_PORT_BITS(TLCLK_REG3, 0xc7, 0x38);
+ switch (val) {
+ case CLK_8_592MHz:
+ SET_PORT_BITS(TLCLK_REG0, 0xfc, 1);
+ break;
+ case CLK_11_184MHz:
+ SET_PORT_BITS(TLCLK_REG0, 0xfc, 0);
+ break;
+ case CLK_34_368MHz:
+ SET_PORT_BITS(TLCLK_REG0, 0xfc, 3);
+ break;
+ case CLK_44_736MHz:
+ SET_PORT_BITS(TLCLK_REG0, 0xfc, 2);
+ break;
+ }
+ } else
+ SET_PORT_BITS(TLCLK_REG3, 0xc7, val << 3);
+
+ spin_unlock_irqrestore(&event_lock, flags);
+
+ return strnlen(buf, count);
+}
+
+static DEVICE_ATTR(select_amcb2_transmit_clock, S_IWUGO, NULL,
+ store_select_amcb2_transmit_clock);
+
+static ssize_t store_select_amcb1_transmit_clock(struct device *d,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ unsigned long tmp;
+ unsigned char val;
+ unsigned long flags;
+
+ sscanf(buf, "%lX", &tmp);
+ dev_dbg(d, "tmp = 0x%lX\n", tmp);
+
+ val = (unsigned char)tmp;
+ spin_lock_irqsave(&event_lock, flags);
+ if ((val == CLK_8kHz) || (val == CLK_16_384MHz)) {
+ SET_PORT_BITS(TLCLK_REG3, 0xf8, 0x5);
+ SET_PORT_BITS(TLCLK_REG1, 0xfb, ~val);
+ } else if (val >= CLK_8_592MHz) {
+ SET_PORT_BITS(TLCLK_REG3, 0xf8, 0x7);
+ switch (val) {
+ case CLK_8_592MHz:
+ SET_PORT_BITS(TLCLK_REG0, 0xfc, 1);
+ break;
+ case CLK_11_184MHz:
+ SET_PORT_BITS(TLCLK_REG0, 0xfc, 0);
+ break;
+ case CLK_34_368MHz:
+ SET_PORT_BITS(TLCLK_REG0, 0xfc, 3);
+ break;
+ case CLK_44_736MHz:
+ SET_PORT_BITS(TLCLK_REG0, 0xfc, 2);
+ break;
+ }
+ } else
+ SET_PORT_BITS(TLCLK_REG3, 0xf8, val);
+ spin_unlock_irqrestore(&event_lock, flags);
+
+ return strnlen(buf, count);
+}
+
+static DEVICE_ATTR(select_amcb1_transmit_clock, S_IWUGO, NULL,
+ store_select_amcb1_transmit_clock);
+
+static ssize_t store_select_redundant_clock(struct device *d,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ unsigned long tmp;
+ unsigned char val;
+ unsigned long flags;
+
+ sscanf(buf, "%lX", &tmp);
+ dev_dbg(d, "tmp = 0x%lX\n", tmp);
+
+ val = (unsigned char)tmp;
+ spin_lock_irqsave(&event_lock, flags);
+ SET_PORT_BITS(TLCLK_REG1, 0xfe, val);
+ spin_unlock_irqrestore(&event_lock, flags);
+
+ return strnlen(buf, count);
+}
+
+static DEVICE_ATTR(select_redundant_clock, S_IWUGO, NULL,
+ store_select_redundant_clock);
+
+static ssize_t store_select_ref_frequency(struct device *d,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ unsigned long tmp;
+ unsigned char val;
+ unsigned long flags;
+
+ sscanf(buf, "%lX", &tmp);
+ dev_dbg(d, "tmp = 0x%lX\n", tmp);
+
+ val = (unsigned char)tmp;
+ spin_lock_irqsave(&event_lock, flags);
+ SET_PORT_BITS(TLCLK_REG1, 0xfd, val);
+ spin_unlock_irqrestore(&event_lock, flags);
+
+ return strnlen(buf, count);
+}
+
+static DEVICE_ATTR(select_ref_frequency, S_IWUGO, NULL,
+ store_select_ref_frequency);
+
+static ssize_t store_filter_select(struct device *d,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ unsigned long tmp;
+ unsigned char val;
+ unsigned long flags;
+
+ sscanf(buf, "%lX", &tmp);
+ dev_dbg(d, "tmp = 0x%lX\n", tmp);
+
+ val = (unsigned char)tmp;
+ spin_lock_irqsave(&event_lock, flags);
+ SET_PORT_BITS(TLCLK_REG0, 0xfb, val);
+ spin_unlock_irqrestore(&event_lock, flags);
+
+ return strnlen(buf, count);
+}
+
+static DEVICE_ATTR(filter_select, S_IWUGO, NULL, store_filter_select);
+
+static ssize_t store_hardware_switching_mode(struct device *d,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ unsigned long tmp;
+ unsigned char val;
+ unsigned long flags;
+
+ sscanf(buf, "%lX", &tmp);
+ dev_dbg(d, "tmp = 0x%lX\n", tmp);
+
+ val = (unsigned char)tmp;
+ spin_lock_irqsave(&event_lock, flags);
+ SET_PORT_BITS(TLCLK_REG0, 0xbf, val);
+ spin_unlock_irqrestore(&event_lock, flags);
+
+ return strnlen(buf, count);
+}
+
+static DEVICE_ATTR(hardware_switching_mode, S_IWUGO, NULL,
+ store_hardware_switching_mode);
+
+static ssize_t store_hardware_switching(struct device *d,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ unsigned long tmp;
+ unsigned char val;
+ unsigned long flags;
+
+ sscanf(buf, "%lX", &tmp);
+ dev_dbg(d, "tmp = 0x%lX\n", tmp);
+
+ val = (unsigned char)tmp;
+ spin_lock_irqsave(&event_lock, flags);
+ SET_PORT_BITS(TLCLK_REG0, 0x7f, val);
+ spin_unlock_irqrestore(&event_lock, flags);
+
+ return strnlen(buf, count);
+}
+
+static DEVICE_ATTR(hardware_switching, S_IWUGO, NULL,
+ store_hardware_switching);
+
+static ssize_t store_refalign (struct device *d,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ unsigned long tmp;
+ unsigned long flags;
+
+ sscanf(buf, "%lX", &tmp);
+ dev_dbg(d, "tmp = 0x%lX\n", tmp);
+ spin_lock_irqsave(&event_lock, flags);
+ SET_PORT_BITS(TLCLK_REG0, 0xf7, 0);
+ udelay(2);
+ SET_PORT_BITS(TLCLK_REG0, 0xf7, 0x08);
+ udelay(2);
+ SET_PORT_BITS(TLCLK_REG0, 0xf7, 0);
+ spin_unlock_irqrestore(&event_lock, flags);
+
+ return strnlen(buf, count);
+}
+
+static DEVICE_ATTR(refalign, S_IWUGO, NULL, store_refalign);
+
+static ssize_t store_mode_select (struct device *d,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ unsigned long tmp;
+ unsigned char val;
+ unsigned long flags;
+
+ sscanf(buf, "%lX", &tmp);
+ dev_dbg(d, "tmp = 0x%lX\n", tmp);
+
+ val = (unsigned char)tmp;
+ spin_lock_irqsave(&event_lock, flags);
+ SET_PORT_BITS(TLCLK_REG0, 0xcf, val);
+ spin_unlock_irqrestore(&event_lock, flags);
+
+ return strnlen(buf, count);
+}
+
+static DEVICE_ATTR(mode_select, S_IWUGO, NULL, store_mode_select);
+
+static ssize_t store_reset (struct device *d,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ unsigned long tmp;
+ unsigned char val;
+ unsigned long flags;
+
+ sscanf(buf, "%lX", &tmp);
+ dev_dbg(d, "tmp = 0x%lX\n", tmp);
+
+ val = (unsigned char)tmp;
+ spin_lock_irqsave(&event_lock, flags);
+ SET_PORT_BITS(TLCLK_REG4, 0xfd, val);
+ spin_unlock_irqrestore(&event_lock, flags);
+
+ return strnlen(buf, count);
+}
+
+static DEVICE_ATTR(reset, S_IWUGO, NULL, store_reset);
+
+static struct attribute *tlclk_sysfs_entries[] = {
+ &dev_attr_current_ref.attr,
+ &dev_attr_interrupt_switch.attr,
+ &dev_attr_alarms.attr,
+ &dev_attr_enable_clk3a_output.attr,
+ &dev_attr_enable_clk3b_output.attr,
+ &dev_attr_enable_clkb1_output.attr,
+ &dev_attr_enable_clka1_output.attr,
+ &dev_attr_enable_clkb0_output.attr,
+ &dev_attr_enable_clka0_output.attr,
+ &dev_attr_test_mode.attr,
+ &dev_attr_select_amcb1_transmit_clock.attr,
+ &dev_attr_select_amcb2_transmit_clock.attr,
+ &dev_attr_select_redundant_clock.attr,
+ &dev_attr_select_ref_frequency.attr,
+ &dev_attr_filter_select.attr,
+ &dev_attr_hardware_switching_mode.attr,
+ &dev_attr_hardware_switching.attr,
+ &dev_attr_refalign.attr,
+ &dev_attr_mode_select.attr,
+ &dev_attr_reset.attr,
+ NULL
+};
+
+static struct attribute_group tlclk_attribute_group = {
+ .name = NULL, /* put in device directory */
+ .attrs = tlclk_sysfs_entries,
+};
+
+static struct platform_device *tlclk_device;
+
+static int __init tlclk_init(void)
+{
+ int ret;
+
+ ret = register_chrdev(tlclk_major, "telco_clock", &tlclk_fops);
+ if (ret < 0) {
+ printk(KERN_ERR "telco_clock: can't get major! %d\n", tlclk_major);
+ return ret;
+ }
+ alarm_events = kzalloc( sizeof(struct tlclk_alarms), GFP_KERNEL);
+ if (!alarm_events)
+ goto out1;
+
+ /* Read telecom clock IRQ number (Set by BIOS) */
+ if (!request_region(TLCLK_BASE, 8, "telco_clock")) {
+ printk(KERN_ERR "tlclk: request_region failed! 0x%X\n",
+ TLCLK_BASE);
+ ret = -EBUSY;
+ goto out2;
+ }
+ telclk_interrupt = (inb(TLCLK_REG7) & 0x0f);
+
+ if (0x0F == telclk_interrupt ) { /* not MCPBL0010 ? */
+ printk(KERN_ERR "telclk_interrup = 0x%x non-mcpbl0010 hw\n",
+ telclk_interrupt);
+ ret = -ENXIO;
+ goto out3;
+ }
+
+ init_timer(&switchover_timer);
+
+ ret = misc_register(&tlclk_miscdev);
+ if (ret < 0) {
+ printk(KERN_ERR " misc_register retruns %d\n", ret);
+ ret = -EBUSY;
+ goto out3;
+ }
+
+ tlclk_device = platform_device_register_simple("telco_clock",
+ -1, NULL, 0);
+ if (!tlclk_device) {
+ printk(KERN_ERR " platform_device_register retruns 0x%X\n",
+ (unsigned int) tlclk_device);
+ ret = -EBUSY;
+ goto out4;
+ }
+
+ ret = sysfs_create_group(&tlclk_device->dev.kobj,
+ &tlclk_attribute_group);
+ if (ret) {
+ printk(KERN_ERR "failed to create sysfs device attributes\n");
+ sysfs_remove_group(&tlclk_device->dev.kobj,
+ &tlclk_attribute_group);
+ goto out5;
+ }
+
+ return 0;
+out5:
+ platform_device_unregister(tlclk_device);
+out4:
+ misc_deregister(&tlclk_miscdev);
+out3:
+ release_region(TLCLK_BASE, 8);
+out2:
+ kfree(alarm_events);
+out1:
+ unregister_chrdev(tlclk_major, "telco_clock");
+ return ret;
+}
+
+static void __exit tlclk_cleanup(void)
+{
+ sysfs_remove_group(&tlclk_device->dev.kobj, &tlclk_attribute_group);
+ platform_device_unregister(tlclk_device);
+ misc_deregister(&tlclk_miscdev);
+ unregister_chrdev(tlclk_major, "telco_clock");
+
+ release_region(TLCLK_BASE, 8);
+ del_timer_sync(&switchover_timer);
+ kfree(alarm_events);
+
+}
+
+static void switchover_timeout(unsigned long data)
+{
+ if ((data & 1)) {
+ if ((inb(TLCLK_REG1) & 0x08) != (data & 0x08))
+ alarm_events->switchover_primary++;
+ } else {
+ if ((inb(TLCLK_REG1) & 0x08) != (data & 0x08))
+ alarm_events->switchover_secondary++;
+ }
+
+ /* Alarm processing is done, wake up read task */
+ del_timer(&switchover_timer);
+ got_event = 1;
+ wake_up(&wq);
+}
+
+static irqreturn_t tlclk_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&event_lock, flags);
+ /* Read and clear interrupt events */
+ int_events = inb(TLCLK_REG6);
+
+ /* Primary_Los changed from 0 to 1 ? */
+ if (int_events & PRI_LOS_01_MASK) {
+ if (inb(TLCLK_REG2) & SEC_LOST_MASK)
+ alarm_events->lost_clocks++;
+ else
+ alarm_events->lost_primary_clock++;
+ }
+
+ /* Primary_Los changed from 1 to 0 ? */
+ if (int_events & PRI_LOS_10_MASK) {
+ alarm_events->primary_clock_back++;
+ SET_PORT_BITS(TLCLK_REG1, 0xFE, 1);
+ }
+ /* Secondary_Los changed from 0 to 1 ? */
+ if (int_events & SEC_LOS_01_MASK) {
+ if (inb(TLCLK_REG2) & PRI_LOST_MASK)
+ alarm_events->lost_clocks++;
+ else
+ alarm_events->lost_secondary_clock++;
+ }
+ /* Secondary_Los changed from 1 to 0 ? */
+ if (int_events & SEC_LOS_10_MASK) {
+ alarm_events->secondary_clock_back++;
+ SET_PORT_BITS(TLCLK_REG1, 0xFE, 0);
+ }
+ if (int_events & HOLDOVER_10_MASK)
+ alarm_events->pll_end_holdover++;
+
+ if (int_events & UNLOCK_01_MASK)
+ alarm_events->pll_lost_sync++;
+
+ if (int_events & UNLOCK_10_MASK)
+ alarm_events->pll_sync++;
+
+ /* Holdover changed from 0 to 1 ? */
+ if (int_events & HOLDOVER_01_MASK) {
+ alarm_events->pll_holdover++;
+
+ /* TIMEOUT in ~10ms */
+ switchover_timer.expires = jiffies + msecs_to_jiffies(10);
+ switchover_timer.data = inb(TLCLK_REG1);
+ add_timer(&switchover_timer);
+ } else {
+ got_event = 1;
+ wake_up(&wq);
+ }
+ spin_unlock_irqrestore(&event_lock, flags);
+
+ return IRQ_HANDLED;
+}
+
+module_init(tlclk_init);
+module_exit(tlclk_cleanup);
diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c
index 049d128ae7f0..303f15880466 100644
--- a/drivers/char/tpm/tpm.c
+++ b/drivers/char/tpm/tpm.c
@@ -64,7 +64,7 @@ static ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf,
if (count == 0)
return -ENODATA;
if (count > bufsiz) {
- dev_err(&chip->pci_dev->dev,
+ dev_err(chip->dev,
"invalid count value %x %zx \n", count, bufsiz);
return -E2BIG;
}
@@ -72,21 +72,21 @@ static ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf,
down(&chip->tpm_mutex);
if ((rc = chip->vendor->send(chip, (u8 *) buf, count)) < 0) {
- dev_err(&chip->pci_dev->dev,
+ dev_err(chip->dev,
"tpm_transmit: tpm_send: error %zd\n", rc);
goto out;
}
stop = jiffies + 2 * 60 * HZ;
do {
- u8 status = inb(chip->vendor->base + 1);
+ u8 status = chip->vendor->status(chip);
if ((status & chip->vendor->req_complete_mask) ==
chip->vendor->req_complete_val) {
goto out_recv;
}
if ((status == chip->vendor->req_canceled)) {
- dev_err(&chip->pci_dev->dev, "Operation Canceled\n");
+ dev_err(chip->dev, "Operation Canceled\n");
rc = -ECANCELED;
goto out;
}
@@ -97,14 +97,14 @@ static ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf,
chip->vendor->cancel(chip);
- dev_err(&chip->pci_dev->dev, "Operation Timed out\n");
+ dev_err(chip->dev, "Operation Timed out\n");
rc = -ETIME;
goto out;
out_recv:
rc = chip->vendor->recv(chip, (u8 *) buf, bufsiz);
if (rc < 0)
- dev_err(&chip->pci_dev->dev,
+ dev_err(chip->dev,
"tpm_transmit: tpm_recv: error %zd\n", rc);
out:
up(&chip->tpm_mutex);
@@ -139,15 +139,14 @@ ssize_t tpm_show_pcrs(struct device *dev, struct device_attribute *attr,
__be32 index;
char *str = buf;
- struct tpm_chip *chip =
- pci_get_drvdata(to_pci_dev(dev));
+ struct tpm_chip *chip = dev_get_drvdata(dev);
if (chip == NULL)
return -ENODEV;
memcpy(data, cap_pcr, sizeof(cap_pcr));
if ((len = tpm_transmit(chip, data, sizeof(data)))
< CAP_PCR_RESULT_SIZE) {
- dev_dbg(&chip->pci_dev->dev, "A TPM error (%d) occurred "
+ dev_dbg(chip->dev, "A TPM error (%d) occurred "
"attempting to determine the number of PCRS\n",
be32_to_cpu(*((__be32 *) (data + 6))));
return 0;
@@ -161,9 +160,10 @@ ssize_t tpm_show_pcrs(struct device *dev, struct device_attribute *attr,
memcpy(data + 10, &index, 4);
if ((len = tpm_transmit(chip, data, sizeof(data)))
< READ_PCR_RESULT_SIZE){
- dev_dbg(&chip->pci_dev->dev, "A TPM error (%d) occurred"
+ dev_dbg(chip->dev, "A TPM error (%d) occurred"
" attempting to read PCR %d of %d\n",
- be32_to_cpu(*((__be32 *) (data + 6))), i, num_pcrs);
+ be32_to_cpu(*((__be32 *) (data + 6))),
+ i, num_pcrs);
goto out;
}
str += sprintf(str, "PCR-%02d: ", i);
@@ -191,21 +191,19 @@ ssize_t tpm_show_pubek(struct device *dev, struct device_attribute *attr,
int i, rc;
char *str = buf;
- struct tpm_chip *chip =
- pci_get_drvdata(to_pci_dev(dev));
+ struct tpm_chip *chip = dev_get_drvdata(dev);
if (chip == NULL)
return -ENODEV;
- data = kmalloc(READ_PUBEK_RESULT_SIZE, GFP_KERNEL);
+ data = kzalloc(READ_PUBEK_RESULT_SIZE, GFP_KERNEL);
if (!data)
return -ENOMEM;
memcpy(data, readpubek, sizeof(readpubek));
- memset(data + sizeof(readpubek), 0, 20); /* zero nonce */
if ((len = tpm_transmit(chip, data, READ_PUBEK_RESULT_SIZE)) <
READ_PUBEK_RESULT_SIZE) {
- dev_dbg(&chip->pci_dev->dev, "A TPM error (%d) occurred "
+ dev_dbg(chip->dev, "A TPM error (%d) occurred "
"attempting to read the PUBEK\n",
be32_to_cpu(*((__be32 *) (data + 6))));
rc = 0;
@@ -245,7 +243,6 @@ out:
kfree(data);
return rc;
}
-
EXPORT_SYMBOL_GPL(tpm_show_pubek);
#define CAP_VER_RESULT_SIZE 18
@@ -274,8 +271,7 @@ ssize_t tpm_show_caps(struct device *dev, struct device_attribute *attr,
ssize_t len;
char *str = buf;
- struct tpm_chip *chip =
- pci_get_drvdata(to_pci_dev(dev));
+ struct tpm_chip *chip = dev_get_drvdata(dev);
if (chip == NULL)
return -ENODEV;
@@ -315,7 +311,6 @@ ssize_t tpm_store_cancel(struct device *dev, struct device_attribute *attr,
}
EXPORT_SYMBOL_GPL(tpm_store_cancel);
-
/*
* Device file system interface to the TPM
*/
@@ -339,21 +334,20 @@ int tpm_open(struct inode *inode, struct file *file)
}
if (chip->num_opens) {
- dev_dbg(&chip->pci_dev->dev,
- "Another process owns this TPM\n");
+ dev_dbg(chip->dev, "Another process owns this TPM\n");
rc = -EBUSY;
goto err_out;
}
chip->num_opens++;
- pci_dev_get(chip->pci_dev);
+ get_device(chip->dev);
spin_unlock(&driver_lock);
chip->data_buffer = kmalloc(TPM_BUFSIZE * sizeof(u8), GFP_KERNEL);
if (chip->data_buffer == NULL) {
chip->num_opens--;
- pci_dev_put(chip->pci_dev);
+ put_device(chip->dev);
return -ENOMEM;
}
@@ -366,7 +360,6 @@ err_out:
spin_unlock(&driver_lock);
return rc;
}
-
EXPORT_SYMBOL_GPL(tpm_open);
int tpm_release(struct inode *inode, struct file *file)
@@ -378,15 +371,14 @@ int tpm_release(struct inode *inode, struct file *file)
chip->num_opens--;
del_singleshot_timer_sync(&chip->user_read_timer);
atomic_set(&chip->data_pending, 0);
- pci_dev_put(chip->pci_dev);
+ put_device(chip->dev);
kfree(chip->data_buffer);
spin_unlock(&driver_lock);
return 0;
}
-
EXPORT_SYMBOL_GPL(tpm_release);
-ssize_t tpm_write(struct file * file, const char __user * buf,
+ssize_t tpm_write(struct file *file, const char __user *buf,
size_t size, loff_t * off)
{
struct tpm_chip *chip = file->private_data;
@@ -422,7 +414,7 @@ ssize_t tpm_write(struct file * file, const char __user * buf,
EXPORT_SYMBOL_GPL(tpm_write);
-ssize_t tpm_read(struct file * file, char __user * buf,
+ssize_t tpm_read(struct file * file, char __user *buf,
size_t size, loff_t * off)
{
struct tpm_chip *chip = file->private_data;
@@ -444,15 +436,14 @@ ssize_t tpm_read(struct file * file, char __user * buf,
return ret_size;
}
-
EXPORT_SYMBOL_GPL(tpm_read);
-void __devexit tpm_remove(struct pci_dev *pci_dev)
+void tpm_remove_hardware(struct device *dev)
{
- struct tpm_chip *chip = pci_get_drvdata(pci_dev);
+ struct tpm_chip *chip = dev_get_drvdata(dev);
if (chip == NULL) {
- dev_err(&pci_dev->dev, "No device data found\n");
+ dev_err(dev, "No device data found\n");
return;
}
@@ -462,22 +453,20 @@ void __devexit tpm_remove(struct pci_dev *pci_dev)
spin_unlock(&driver_lock);
- pci_set_drvdata(pci_dev, NULL);
+ dev_set_drvdata(dev, NULL);
misc_deregister(&chip->vendor->miscdev);
kfree(chip->vendor->miscdev.name);
- sysfs_remove_group(&pci_dev->dev.kobj, chip->vendor->attr_group);
+ sysfs_remove_group(&dev->kobj, chip->vendor->attr_group);
- pci_disable_device(pci_dev);
-
- dev_mask[chip->dev_num / TPM_NUM_MASK_ENTRIES ] &= !(1 << (chip->dev_num % TPM_NUM_MASK_ENTRIES));
+ dev_mask[chip->dev_num / TPM_NUM_MASK_ENTRIES ] &=
+ !(1 << (chip->dev_num % TPM_NUM_MASK_ENTRIES));
kfree(chip);
- pci_dev_put(pci_dev);
+ put_device(dev);
}
-
-EXPORT_SYMBOL_GPL(tpm_remove);
+EXPORT_SYMBOL_GPL(tpm_remove_hardware);
static u8 savestate[] = {
0, 193, /* TPM_TAG_RQU_COMMAND */
@@ -489,32 +478,30 @@ static u8 savestate[] = {
* We are about to suspend. Save the TPM state
* so that it can be restored.
*/
-int tpm_pm_suspend(struct pci_dev *pci_dev, pm_message_t pm_state)
+int tpm_pm_suspend(struct device *dev, pm_message_t pm_state)
{
- struct tpm_chip *chip = pci_get_drvdata(pci_dev);
+ struct tpm_chip *chip = dev_get_drvdata(dev);
if (chip == NULL)
return -ENODEV;
tpm_transmit(chip, savestate, sizeof(savestate));
return 0;
}
-
EXPORT_SYMBOL_GPL(tpm_pm_suspend);
/*
* Resume from a power safe. The BIOS already restored
* the TPM state.
*/
-int tpm_pm_resume(struct pci_dev *pci_dev)
+int tpm_pm_resume(struct device *dev)
{
- struct tpm_chip *chip = pci_get_drvdata(pci_dev);
+ struct tpm_chip *chip = dev_get_drvdata(dev);
if (chip == NULL)
return -ENODEV;
return 0;
}
-
EXPORT_SYMBOL_GPL(tpm_pm_resume);
/*
@@ -524,8 +511,7 @@ EXPORT_SYMBOL_GPL(tpm_pm_resume);
* upon errant exit from this function specific probe function should call
* pci_disable_device
*/
-int tpm_register_hardware(struct pci_dev *pci_dev,
- struct tpm_vendor_specific *entry)
+int tpm_register_hardware(struct device *dev, struct tpm_vendor_specific *entry)
{
#define DEVNAME_SIZE 7
@@ -534,12 +520,10 @@ int tpm_register_hardware(struct pci_dev *pci_dev,
int i, j;
/* Driver specific per-device data */
- chip = kmalloc(sizeof(*chip), GFP_KERNEL);
+ chip = kzalloc(sizeof(*chip), GFP_KERNEL);
if (chip == NULL)
return -ENOMEM;
- memset(chip, 0, sizeof(struct tpm_chip));
-
init_MUTEX(&chip->buffer_mutex);
init_MUTEX(&chip->tpm_mutex);
INIT_LIST_HEAD(&chip->list);
@@ -563,8 +547,7 @@ int tpm_register_hardware(struct pci_dev *pci_dev,
dev_num_search_complete:
if (chip->dev_num < 0) {
- dev_err(&pci_dev->dev,
- "No available tpm device numbers\n");
+ dev_err(dev, "No available tpm device numbers\n");
kfree(chip);
return -ENODEV;
} else if (chip->dev_num == 0)
@@ -576,15 +559,15 @@ dev_num_search_complete:
scnprintf(devname, DEVNAME_SIZE, "%s%d", "tpm", chip->dev_num);
chip->vendor->miscdev.name = devname;
- chip->vendor->miscdev.dev = &(pci_dev->dev);
- chip->pci_dev = pci_dev_get(pci_dev);
+ chip->vendor->miscdev.dev = dev;
+ chip->dev = get_device(dev);
if (misc_register(&chip->vendor->miscdev)) {
- dev_err(&chip->pci_dev->dev,
+ dev_err(chip->dev,
"unable to misc_register %s, minor %d\n",
chip->vendor->miscdev.name,
chip->vendor->miscdev.minor);
- pci_dev_put(pci_dev);
+ put_device(dev);
kfree(chip);
dev_mask[i] &= !(1 << j);
return -ENODEV;
@@ -592,17 +575,16 @@ dev_num_search_complete:
spin_lock(&driver_lock);
- pci_set_drvdata(pci_dev, chip);
+ dev_set_drvdata(dev, chip);
list_add(&chip->list, &tpm_chip_list);
spin_unlock(&driver_lock);
- sysfs_create_group(&pci_dev->dev.kobj, chip->vendor->attr_group);
+ sysfs_create_group(&dev->kobj, chip->vendor->attr_group);
return 0;
}
-
EXPORT_SYMBOL_GPL(tpm_register_hardware);
MODULE_AUTHOR("Leendert van Doorn (leendert@watson.ibm.com)");
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
index 373b41f6b460..9293bcc4dc62 100644
--- a/drivers/char/tpm/tpm.h
+++ b/drivers/char/tpm/tpm.h
@@ -19,11 +19,11 @@
*
*/
#include <linux/module.h>
-#include <linux/version.h>
#include <linux/pci.h>
#include <linux/delay.h>
#include <linux/fs.h>
#include <linux/miscdevice.h>
+#include <linux/platform_device.h>
enum tpm_timeout {
TPM_TIMEOUT = 5, /* msecs */
@@ -55,12 +55,13 @@ struct tpm_vendor_specific {
int (*recv) (struct tpm_chip *, u8 *, size_t);
int (*send) (struct tpm_chip *, u8 *, size_t);
void (*cancel) (struct tpm_chip *);
+ u8 (*status) (struct tpm_chip *);
struct miscdevice miscdev;
struct attribute_group *attr_group;
};
struct tpm_chip {
- struct pci_dev *pci_dev; /* PCI device stuff */
+ struct device *dev; /* Device stuff */
int dev_num; /* /dev/tpm# */
int num_opens; /* only one allowed */
@@ -91,13 +92,13 @@ static inline void tpm_write_index(int base, int index, int value)
outb(value & 0xFF, base+1);
}
-extern int tpm_register_hardware(struct pci_dev *,
+extern int tpm_register_hardware(struct device *,
struct tpm_vendor_specific *);
extern int tpm_open(struct inode *, struct file *);
extern int tpm_release(struct inode *, struct file *);
extern ssize_t tpm_write(struct file *, const char __user *, size_t,
loff_t *);
extern ssize_t tpm_read(struct file *, char __user *, size_t, loff_t *);
-extern void __devexit tpm_remove(struct pci_dev *);
-extern int tpm_pm_suspend(struct pci_dev *, pm_message_t);
-extern int tpm_pm_resume(struct pci_dev *);
+extern void tpm_remove_hardware(struct device *);
+extern int tpm_pm_suspend(struct device *, pm_message_t);
+extern int tpm_pm_resume(struct device *);
diff --git a/drivers/char/tpm/tpm_atmel.c b/drivers/char/tpm/tpm_atmel.c
index c0d64914595f..32e01450c425 100644
--- a/drivers/char/tpm/tpm_atmel.c
+++ b/drivers/char/tpm/tpm_atmel.c
@@ -19,6 +19,7 @@
*
*/
+#include <linux/platform_device.h>
#include "tpm.h"
/* Atmel definitions */
@@ -40,7 +41,7 @@ enum tpm_atmel_read_status {
ATML_STATUS_READY = 0x08
};
-static int tpm_atml_recv(struct tpm_chip *chip, u8 * buf, size_t count)
+static int tpm_atml_recv(struct tpm_chip *chip, u8 *buf, size_t count)
{
u8 status, *hdr = buf;
u32 size;
@@ -54,7 +55,7 @@ static int tpm_atml_recv(struct tpm_chip *chip, u8 * buf, size_t count)
for (i = 0; i < 6; i++) {
status = inb(chip->vendor->base + 1);
if ((status & ATML_STATUS_DATA_AVAIL) == 0) {
- dev_err(&chip->pci_dev->dev,
+ dev_err(chip->dev,
"error reading header\n");
return -EIO;
}
@@ -66,12 +67,12 @@ static int tpm_atml_recv(struct tpm_chip *chip, u8 * buf, size_t count)
size = be32_to_cpu(*native_size);
if (count < size) {
- dev_err(&chip->pci_dev->dev,
+ dev_err(chip->dev,
"Recv size(%d) less than available space\n", size);
for (; i < size; i++) { /* clear the waiting data anyway */
status = inb(chip->vendor->base + 1);
if ((status & ATML_STATUS_DATA_AVAIL) == 0) {
- dev_err(&chip->pci_dev->dev,
+ dev_err(chip->dev,
"error reading data\n");
return -EIO;
}
@@ -83,7 +84,7 @@ static int tpm_atml_recv(struct tpm_chip *chip, u8 * buf, size_t count)
for (; i < size; i++) {
status = inb(chip->vendor->base + 1);
if ((status & ATML_STATUS_DATA_AVAIL) == 0) {
- dev_err(&chip->pci_dev->dev,
+ dev_err(chip->dev,
"error reading data\n");
return -EIO;
}
@@ -93,20 +94,20 @@ static int tpm_atml_recv(struct tpm_chip *chip, u8 * buf, size_t count)
/* make sure data available is gone */
status = inb(chip->vendor->base + 1);
if (status & ATML_STATUS_DATA_AVAIL) {
- dev_err(&chip->pci_dev->dev, "data available is stuck\n");
+ dev_err(chip->dev, "data available is stuck\n");
return -EIO;
}
return size;
}
-static int tpm_atml_send(struct tpm_chip *chip, u8 * buf, size_t count)
+static int tpm_atml_send(struct tpm_chip *chip, u8 *buf, size_t count)
{
int i;
- dev_dbg(&chip->pci_dev->dev, "tpm_atml_send: ");
+ dev_dbg(chip->dev, "tpm_atml_send:\n");
for (i = 0; i < count; i++) {
- dev_dbg(&chip->pci_dev->dev, "0x%x(%d) ", buf[i], buf[i]);
+ dev_dbg(chip->dev, "%d 0x%x(%d)\n", i, buf[i], buf[i]);
outb(buf[i], chip->vendor->base);
}
@@ -118,6 +119,11 @@ static void tpm_atml_cancel(struct tpm_chip *chip)
outb(ATML_STATUS_ABORT, chip->vendor->base + 1);
}
+static u8 tpm_atml_status(struct tpm_chip *chip)
+{
+ return inb(chip->vendor->base + 1);
+}
+
static struct file_operations atmel_ops = {
.owner = THIS_MODULE,
.llseek = no_llseek,
@@ -137,7 +143,7 @@ static struct attribute* atmel_attrs[] = {
&dev_attr_pcrs.attr,
&dev_attr_caps.attr,
&dev_attr_cancel.attr,
- 0,
+ NULL,
};
static struct attribute_group atmel_attr_grp = { .attrs = atmel_attrs };
@@ -146,6 +152,7 @@ static struct tpm_vendor_specific tpm_atmel = {
.recv = tpm_atml_recv,
.send = tpm_atml_send,
.cancel = tpm_atml_cancel,
+ .status = tpm_atml_status,
.req_complete_mask = ATML_STATUS_BUSY | ATML_STATUS_DATA_AVAIL,
.req_complete_val = ATML_STATUS_DATA_AVAIL,
.req_canceled = ATML_STATUS_READY,
@@ -153,86 +160,94 @@ static struct tpm_vendor_specific tpm_atmel = {
.miscdev = { .fops = &atmel_ops, },
};
-static int __devinit tpm_atml_init(struct pci_dev *pci_dev,
- const struct pci_device_id *pci_id)
+static struct platform_device *pdev;
+
+static void __devexit tpm_atml_remove(struct device *dev)
+{
+ struct tpm_chip *chip = dev_get_drvdata(dev);
+ if (chip) {
+ release_region(chip->vendor->base, 2);
+ tpm_remove_hardware(chip->dev);
+ }
+}
+
+static struct device_driver atml_drv = {
+ .name = "tpm_atmel",
+ .bus = &platform_bus_type,
+ .owner = THIS_MODULE,
+ .suspend = tpm_pm_suspend,
+ .resume = tpm_pm_resume,
+};
+
+static int __init init_atmel(void)
{
- u8 version[4];
int rc = 0;
int lo, hi;
- if (pci_enable_device(pci_dev))
- return -EIO;
+ driver_register(&atml_drv);
lo = tpm_read_index(TPM_ADDR, TPM_ATMEL_BASE_ADDR_LO);
hi = tpm_read_index(TPM_ADDR, TPM_ATMEL_BASE_ADDR_HI);
tpm_atmel.base = (hi<<8)|lo;
- dev_dbg( &pci_dev->dev, "Operating with base: 0x%x\n", tpm_atmel.base);
/* verify that it is an Atmel part */
if (tpm_read_index(TPM_ADDR, 4) != 'A' || tpm_read_index(TPM_ADDR, 5) != 'T'
|| tpm_read_index(TPM_ADDR, 6) != 'M' || tpm_read_index(TPM_ADDR, 7) != 'L') {
- rc = -ENODEV;
- goto out_err;
+ return -ENODEV;
}
- /* query chip for its version number */
- if ((version[0] = tpm_read_index(TPM_ADDR, 0x00)) != 0xFF) {
- version[1] = tpm_read_index(TPM_ADDR, 0x01);
- version[2] = tpm_read_index(TPM_ADDR, 0x02);
- version[3] = tpm_read_index(TPM_ADDR, 0x03);
- } else {
- dev_info(&pci_dev->dev, "version query failed\n");
- rc = -ENODEV;
- goto out_err;
+ /* verify chip version number is 1.1 */
+ if ( (tpm_read_index(TPM_ADDR, 0x00) != 0x01) ||
+ (tpm_read_index(TPM_ADDR, 0x01) != 0x01 ))
+ return -ENODEV;
+
+ pdev = kzalloc(sizeof(struct platform_device), GFP_KERNEL);
+ if ( !pdev )
+ return -ENOMEM;
+
+ pdev->name = "tpm_atmel0";
+ pdev->id = -1;
+ pdev->num_resources = 0;
+ pdev->dev.release = tpm_atml_remove;
+ pdev->dev.driver = &atml_drv;
+
+ if ((rc = platform_device_register(pdev)) < 0) {
+ kfree(pdev);
+ pdev = NULL;
+ return rc;
}
- if ((rc = tpm_register_hardware(pci_dev, &tpm_atmel)) < 0)
- goto out_err;
+ if (request_region(tpm_atmel.base, 2, "tpm_atmel0") == NULL ) {
+ platform_device_unregister(pdev);
+ kfree(pdev);
+ pdev = NULL;
+ return -EBUSY;
+ }
- dev_info(&pci_dev->dev,
- "Atmel TPM version %d.%d.%d.%d\n", version[0], version[1],
- version[2], version[3]);
+ if ((rc = tpm_register_hardware(&pdev->dev, &tpm_atmel)) < 0) {
+ release_region(tpm_atmel.base, 2);
+ platform_device_unregister(pdev);
+ kfree(pdev);
+ pdev = NULL;
+ return rc;
+ }
+ dev_info(&pdev->dev, "Atmel TPM 1.1, Base Address: 0x%x\n",
+ tpm_atmel.base);
return 0;
-out_err:
- pci_disable_device(pci_dev);
- return rc;
-}
-
-static struct pci_device_id tpm_pci_tbl[] __devinitdata = {
- {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0)},
- {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12)},
- {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0)},
- {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12)},
- {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0)},
- {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_0)},
- {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1)},
- {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_0)},
- {PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8111_LPC)},
- {PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB6LPC)},
- {0,}
-};
-
-MODULE_DEVICE_TABLE(pci, tpm_pci_tbl);
-
-static struct pci_driver atmel_pci_driver = {
- .name = "tpm_atmel",
- .id_table = tpm_pci_tbl,
- .probe = tpm_atml_init,
- .remove = __devexit_p(tpm_remove),
- .suspend = tpm_pm_suspend,
- .resume = tpm_pm_resume,
-};
-
-static int __init init_atmel(void)
-{
- return pci_register_driver(&atmel_pci_driver);
}
static void __exit cleanup_atmel(void)
{
- pci_unregister_driver(&atmel_pci_driver);
+ if (pdev) {
+ tpm_atml_remove(&pdev->dev);
+ platform_device_unregister(pdev);
+ kfree(pdev);
+ pdev = NULL;
+ }
+
+ driver_unregister(&atml_drv);
}
module_init(init_atmel);
diff --git a/drivers/char/tpm/tpm_infineon.c b/drivers/char/tpm/tpm_infineon.c
index 939e51e119e6..8198dbb7370f 100644
--- a/drivers/char/tpm/tpm_infineon.c
+++ b/drivers/char/tpm/tpm_infineon.c
@@ -5,6 +5,7 @@
* Specifications at www.trustedcomputinggroup.org
*
* Copyright (C) 2005, Marcel Selhorst <selhorst@crypto.rub.de>
+ * Sirrix AG - security technologies, http://www.sirrix.com and
* Applied Data Security Group, Ruhr-University Bochum, Germany
* Project-Homepage: http://www.prosec.rub.de/tpm
*
@@ -29,9 +30,10 @@
#define TPM_INFINEON_DEV_VEN_VALUE 0x15D1
/* These values will be filled after PnP-call */
-static int TPM_INF_DATA = 0;
-static int TPM_INF_ADDR = 0;
-static int pnp_registered = 0;
+static int TPM_INF_DATA;
+static int TPM_INF_ADDR;
+static int TPM_INF_BASE;
+static int TPM_INF_PORT_LEN;
/* TPM header definitions */
enum infineon_tpm_header {
@@ -143,11 +145,9 @@ static int wait(struct tpm_chip *chip, int wait_for_bit)
}
if (i == TPM_MAX_TRIES) { /* timeout occurs */
if (wait_for_bit == STAT_XFE)
- dev_err(&chip->pci_dev->dev,
- "Timeout in wait(STAT_XFE)\n");
+ dev_err(chip->dev, "Timeout in wait(STAT_XFE)\n");
if (wait_for_bit == STAT_RDA)
- dev_err(&chip->pci_dev->dev,
- "Timeout in wait(STAT_RDA)\n");
+ dev_err(chip->dev, "Timeout in wait(STAT_RDA)\n");
return -EIO;
}
return 0;
@@ -170,7 +170,7 @@ static void wait_and_send(struct tpm_chip *chip, u8 sendbyte)
static void tpm_wtx(struct tpm_chip *chip)
{
number_of_wtx++;
- dev_info(&chip->pci_dev->dev, "Granting WTX (%02d / %02d)\n",
+ dev_info(chip->dev, "Granting WTX (%02d / %02d)\n",
number_of_wtx, TPM_MAX_WTX_PACKAGES);
wait_and_send(chip, TPM_VL_VER);
wait_and_send(chip, TPM_CTRL_WTX);
@@ -181,7 +181,7 @@ static void tpm_wtx(struct tpm_chip *chip)
static void tpm_wtx_abort(struct tpm_chip *chip)
{
- dev_info(&chip->pci_dev->dev, "Aborting WTX\n");
+ dev_info(chip->dev, "Aborting WTX\n");
wait_and_send(chip, TPM_VL_VER);
wait_and_send(chip, TPM_CTRL_WTX_ABORT);
wait_and_send(chip, 0x00);
@@ -206,7 +206,7 @@ recv_begin:
}
if (buf[0] != TPM_VL_VER) {
- dev_err(&chip->pci_dev->dev,
+ dev_err(chip->dev,
"Wrong transport protocol implementation!\n");
return -EIO;
}
@@ -221,8 +221,7 @@ recv_begin:
}
if ((size == 0x6D00) && (buf[1] == 0x80)) {
- dev_err(&chip->pci_dev->dev,
- "Error handling on vendor layer!\n");
+ dev_err(chip->dev, "Error handling on vendor layer!\n");
return -EIO;
}
@@ -234,7 +233,7 @@ recv_begin:
}
if (buf[1] == TPM_CTRL_WTX) {
- dev_info(&chip->pci_dev->dev, "WTX-package received\n");
+ dev_info(chip->dev, "WTX-package received\n");
if (number_of_wtx < TPM_MAX_WTX_PACKAGES) {
tpm_wtx(chip);
goto recv_begin;
@@ -245,14 +244,14 @@ recv_begin:
}
if (buf[1] == TPM_CTRL_WTX_ABORT_ACK) {
- dev_info(&chip->pci_dev->dev, "WTX-abort acknowledged\n");
+ dev_info(chip->dev, "WTX-abort acknowledged\n");
return size;
}
if (buf[1] == TPM_CTRL_ERROR) {
- dev_err(&chip->pci_dev->dev, "ERROR-package received:\n");
+ dev_err(chip->dev, "ERROR-package received:\n");
if (buf[4] == TPM_INF_NAK)
- dev_err(&chip->pci_dev->dev,
+ dev_err(chip->dev,
"-> Negative acknowledgement"
" - retransmit command!\n");
return -EIO;
@@ -271,7 +270,7 @@ static int tpm_inf_send(struct tpm_chip *chip, u8 * buf, size_t count)
ret = empty_fifo(chip, 1);
if (ret) {
- dev_err(&chip->pci_dev->dev, "Timeout while clearing FIFO\n");
+ dev_err(chip->dev, "Timeout while clearing FIFO\n");
return -EIO;
}
@@ -316,6 +315,11 @@ static void tpm_inf_cancel(struct tpm_chip *chip)
*/
}
+static u8 tpm_inf_status(struct tpm_chip *chip)
+{
+ return inb(chip->vendor->base + STAT);
+}
+
static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL);
static DEVICE_ATTR(pcrs, S_IRUGO, tpm_show_pcrs, NULL);
static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps, NULL);
@@ -344,6 +348,7 @@ static struct tpm_vendor_specific tpm_inf = {
.recv = tpm_inf_recv,
.send = tpm_inf_send,
.cancel = tpm_inf_cancel,
+ .status = tpm_inf_status,
.req_complete_mask = 0,
.req_complete_val = 0,
.attr_group = &inf_attr_grp,
@@ -356,30 +361,11 @@ static const struct pnp_device_id tpm_pnp_tbl[] = {
{"IFX0102", 0},
{"", 0}
};
+
MODULE_DEVICE_TABLE(pnp, tpm_pnp_tbl);
static int __devinit tpm_inf_pnp_probe(struct pnp_dev *dev,
- const struct pnp_device_id *dev_id)
-{
- if (pnp_port_valid(dev, 0)) {
- TPM_INF_ADDR = (pnp_port_start(dev, 0) & 0xff);
- TPM_INF_DATA = ((TPM_INF_ADDR + 1) & 0xff);
- tpm_inf.base = pnp_port_start(dev, 1);
- dev_info(&dev->dev, "Found %s with ID %s\n",
- dev->name, dev_id->id);
- return 0;
- }
- return -ENODEV;
-}
-
-static struct pnp_driver tpm_inf_pnp = {
- .name = "tpm_inf_pnp",
- .id_table = tpm_pnp_tbl,
- .probe = tpm_inf_pnp_probe,
-};
-
-static int __devinit tpm_inf_probe(struct pci_dev *pci_dev,
- const struct pci_device_id *pci_id)
+ const struct pnp_device_id *dev_id)
{
int rc = 0;
u8 iol, ioh;
@@ -388,30 +374,28 @@ static int __devinit tpm_inf_probe(struct pci_dev *pci_dev,
int productid[2];
char chipname[20];
- rc = pci_enable_device(pci_dev);
- if (rc)
- return rc;
-
- dev_info(&pci_dev->dev, "LPC-bus found at 0x%x\n", pci_id->device);
-
- /* read IO-ports from PnP */
- rc = pnp_register_driver(&tpm_inf_pnp);
- if (rc < 0) {
- dev_err(&pci_dev->dev,
- "Error %x from pnp_register_driver!\n",rc);
- goto error2;
- }
- if (!rc) {
- dev_info(&pci_dev->dev, "No Infineon TPM found!\n");
- goto error;
+ /* read IO-ports through PnP */
+ if (pnp_port_valid(dev, 0) && pnp_port_valid(dev, 1) &&
+ !(pnp_port_flags(dev, 0) & IORESOURCE_DISABLED)) {
+ TPM_INF_ADDR = pnp_port_start(dev, 0);
+ TPM_INF_DATA = (TPM_INF_ADDR + 1);
+ TPM_INF_BASE = pnp_port_start(dev, 1);
+ TPM_INF_PORT_LEN = pnp_port_len(dev, 1);
+ if (!TPM_INF_PORT_LEN)
+ return -EINVAL;
+ dev_info(&dev->dev, "Found %s with ID %s\n",
+ dev->name, dev_id->id);
+ if (!((TPM_INF_BASE >> 8) & 0xff))
+ return -EINVAL;
+ /* publish my base address and request region */
+ tpm_inf.base = TPM_INF_BASE;
+ if (request_region
+ (tpm_inf.base, TPM_INF_PORT_LEN, "tpm_infineon0") == NULL) {
+ release_region(tpm_inf.base, TPM_INF_PORT_LEN);
+ return -EINVAL;
+ }
} else {
- pnp_registered = 1;
- }
-
- /* Make sure, we have received valid config ports */
- if (!TPM_INF_ADDR) {
- dev_err(&pci_dev->dev, "No valid IO-ports received!\n");
- goto error;
+ return -EINVAL;
}
/* query chip for its vendor, its version number a.s.o. */
@@ -443,10 +427,6 @@ static int __devinit tpm_inf_probe(struct pci_dev *pci_dev,
if ((vendorid[0] << 8 | vendorid[1]) == (TPM_INFINEON_DEV_VEN_VALUE)) {
- if (tpm_inf.base == 0) {
- dev_err(&pci_dev->dev, "No IO-ports found!\n");
- goto error;
- }
/* configure TPM with IO-ports */
outb(IOLIMH, TPM_INF_ADDR);
outb(((tpm_inf.base >> 8) & 0xff), TPM_INF_DATA);
@@ -460,10 +440,11 @@ static int __devinit tpm_inf_probe(struct pci_dev *pci_dev,
iol = inb(TPM_INF_DATA);
if ((ioh << 8 | iol) != tpm_inf.base) {
- dev_err(&pci_dev->dev,
+ dev_err(&dev->dev,
"Could not set IO-ports to %04x\n",
tpm_inf.base);
- goto error;
+ release_region(tpm_inf.base, TPM_INF_PORT_LEN);
+ return -EIO;
}
/* activate register */
@@ -475,7 +456,7 @@ static int __devinit tpm_inf_probe(struct pci_dev *pci_dev,
outb(RESET_LP_IRQC_DISABLE, tpm_inf.base + CMD);
/* Finally, we're done, print some infos */
- dev_info(&pci_dev->dev, "TPM found: "
+ dev_info(&dev->dev, "TPM found: "
"config base 0x%x, "
"io base 0x%x, "
"chip version %02x%02x, "
@@ -483,59 +464,53 @@ static int __devinit tpm_inf_probe(struct pci_dev *pci_dev,
"product id %02x%02x"
"%s\n",
TPM_INF_ADDR,
- tpm_inf.base,
+ TPM_INF_BASE,
version[0], version[1],
vendorid[0], vendorid[1],
productid[0], productid[1], chipname);
- rc = tpm_register_hardware(pci_dev, &tpm_inf);
- if (rc < 0)
- goto error;
+ rc = tpm_register_hardware(&dev->dev, &tpm_inf);
+ if (rc < 0) {
+ release_region(tpm_inf.base, TPM_INF_PORT_LEN);
+ return -ENODEV;
+ }
return 0;
} else {
- dev_info(&pci_dev->dev, "No Infineon TPM found!\n");
-error:
- pnp_unregister_driver(&tpm_inf_pnp);
-error2:
- pci_disable_device(pci_dev);
- pnp_registered = 0;
+ dev_info(&dev->dev, "No Infineon TPM found!\n");
return -ENODEV;
}
}
-static struct pci_device_id tpm_pci_tbl[] __devinitdata = {
- {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0)},
- {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12)},
- {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0)},
- {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12)},
- {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0)},
- {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_0)},
- {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1)},
- {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_2)},
- {0,}
-};
+static __devexit void tpm_inf_pnp_remove(struct pnp_dev *dev)
+{
+ struct tpm_chip *chip = pnp_get_drvdata(dev);
-MODULE_DEVICE_TABLE(pci, tpm_pci_tbl);
+ if (chip) {
+ release_region(chip->vendor->base, TPM_INF_PORT_LEN);
+ tpm_remove_hardware(chip->dev);
+ }
+}
-static struct pci_driver inf_pci_driver = {
- .name = "tpm_inf",
- .id_table = tpm_pci_tbl,
- .probe = tpm_inf_probe,
- .remove = __devexit_p(tpm_remove),
- .suspend = tpm_pm_suspend,
- .resume = tpm_pm_resume,
+static struct pnp_driver tpm_inf_pnp = {
+ .name = "tpm_inf_pnp",
+ .driver = {
+ .owner = THIS_MODULE,
+ .suspend = tpm_pm_suspend,
+ .resume = tpm_pm_resume,
+ },
+ .id_table = tpm_pnp_tbl,
+ .probe = tpm_inf_pnp_probe,
+ .remove = tpm_inf_pnp_remove,
};
static int __init init_inf(void)
{
- return pci_register_driver(&inf_pci_driver);
+ return pnp_register_driver(&tpm_inf_pnp);
}
static void __exit cleanup_inf(void)
{
- if (pnp_registered)
- pnp_unregister_driver(&tpm_inf_pnp);
- pci_unregister_driver(&inf_pci_driver);
+ pnp_unregister_driver(&tpm_inf_pnp);
}
module_init(init_inf);
@@ -543,5 +518,5 @@ module_exit(cleanup_inf);
MODULE_AUTHOR("Marcel Selhorst <selhorst@crypto.rub.de>");
MODULE_DESCRIPTION("Driver for Infineon TPM SLD 9630 TT 1.1 / SLB 9635 TT 1.2");
-MODULE_VERSION("1.5");
+MODULE_VERSION("1.6");
MODULE_LICENSE("GPL");
diff --git a/drivers/char/tpm/tpm_nsc.c b/drivers/char/tpm/tpm_nsc.c
index b4127348c063..680a8e331887 100644
--- a/drivers/char/tpm/tpm_nsc.c
+++ b/drivers/char/tpm/tpm_nsc.c
@@ -19,6 +19,7 @@
*
*/
+#include <linux/platform_device.h>
#include "tpm.h"
/* National definitions */
@@ -111,7 +112,7 @@ static int nsc_wait_for_ready(struct tpm_chip *chip)
}
while (time_before(jiffies, stop));
- dev_info(&chip->pci_dev->dev, "wait for ready failed\n");
+ dev_info(chip->dev, "wait for ready failed\n");
return -EBUSY;
}
@@ -127,12 +128,12 @@ static int tpm_nsc_recv(struct tpm_chip *chip, u8 * buf, size_t count)
return -EIO;
if (wait_for_stat(chip, NSC_STATUS_F0, NSC_STATUS_F0, &data) < 0) {
- dev_err(&chip->pci_dev->dev, "F0 timeout\n");
+ dev_err(chip->dev, "F0 timeout\n");
return -EIO;
}
if ((data =
inb(chip->vendor->base + NSC_DATA)) != NSC_COMMAND_NORMAL) {
- dev_err(&chip->pci_dev->dev, "not in normal mode (0x%x)\n",
+ dev_err(chip->dev, "not in normal mode (0x%x)\n",
data);
return -EIO;
}
@@ -141,7 +142,7 @@ static int tpm_nsc_recv(struct tpm_chip *chip, u8 * buf, size_t count)
for (p = buffer; p < &buffer[count]; p++) {
if (wait_for_stat
(chip, NSC_STATUS_OBF, NSC_STATUS_OBF, &data) < 0) {
- dev_err(&chip->pci_dev->dev,
+ dev_err(chip->dev,
"OBF timeout (while reading data)\n");
return -EIO;
}
@@ -152,11 +153,11 @@ static int tpm_nsc_recv(struct tpm_chip *chip, u8 * buf, size_t count)
if ((data & NSC_STATUS_F0) == 0 &&
(wait_for_stat(chip, NSC_STATUS_F0, NSC_STATUS_F0, &data) < 0)) {
- dev_err(&chip->pci_dev->dev, "F0 not set\n");
+ dev_err(chip->dev, "F0 not set\n");
return -EIO;
}
if ((data = inb(chip->vendor->base + NSC_DATA)) != NSC_COMMAND_EOC) {
- dev_err(&chip->pci_dev->dev,
+ dev_err(chip->dev,
"expected end of command(0x%x)\n", data);
return -EIO;
}
@@ -187,19 +188,19 @@ static int tpm_nsc_send(struct tpm_chip *chip, u8 * buf, size_t count)
return -EIO;
if (wait_for_stat(chip, NSC_STATUS_IBF, 0, &data) < 0) {
- dev_err(&chip->pci_dev->dev, "IBF timeout\n");
+ dev_err(chip->dev, "IBF timeout\n");
return -EIO;
}
outb(NSC_COMMAND_NORMAL, chip->vendor->base + NSC_COMMAND);
if (wait_for_stat(chip, NSC_STATUS_IBR, NSC_STATUS_IBR, &data) < 0) {
- dev_err(&chip->pci_dev->dev, "IBR timeout\n");
+ dev_err(chip->dev, "IBR timeout\n");
return -EIO;
}
for (i = 0; i < count; i++) {
if (wait_for_stat(chip, NSC_STATUS_IBF, 0, &data) < 0) {
- dev_err(&chip->pci_dev->dev,
+ dev_err(chip->dev,
"IBF timeout (while writing data)\n");
return -EIO;
}
@@ -207,7 +208,7 @@ static int tpm_nsc_send(struct tpm_chip *chip, u8 * buf, size_t count)
}
if (wait_for_stat(chip, NSC_STATUS_IBF, 0, &data) < 0) {
- dev_err(&chip->pci_dev->dev, "IBF timeout\n");
+ dev_err(chip->dev, "IBF timeout\n");
return -EIO;
}
outb(NSC_COMMAND_EOC, chip->vendor->base + NSC_COMMAND);
@@ -220,6 +221,11 @@ static void tpm_nsc_cancel(struct tpm_chip *chip)
outb(NSC_COMMAND_CANCEL, chip->vendor->base + NSC_COMMAND);
}
+static u8 tpm_nsc_status(struct tpm_chip *chip)
+{
+ return inb(chip->vendor->base + NSC_STATUS);
+}
+
static struct file_operations nsc_ops = {
.owner = THIS_MODULE,
.llseek = no_llseek,
@@ -239,7 +245,7 @@ static struct attribute * nsc_attrs[] = {
&dev_attr_pcrs.attr,
&dev_attr_caps.attr,
&dev_attr_cancel.attr,
- 0,
+ NULL,
};
static struct attribute_group nsc_attr_grp = { .attrs = nsc_attrs };
@@ -248,6 +254,7 @@ static struct tpm_vendor_specific tpm_nsc = {
.recv = tpm_nsc_recv,
.send = tpm_nsc_send,
.cancel = tpm_nsc_cancel,
+ .status = tpm_nsc_status,
.req_complete_mask = NSC_STATUS_OBF,
.req_complete_val = NSC_STATUS_OBF,
.req_canceled = NSC_STATUS_RDY,
@@ -255,55 +262,93 @@ static struct tpm_vendor_specific tpm_nsc = {
.miscdev = { .fops = &nsc_ops, },
};
-static int __devinit tpm_nsc_init(struct pci_dev *pci_dev,
- const struct pci_device_id *pci_id)
+static struct platform_device *pdev = NULL;
+
+static void __devexit tpm_nsc_remove(struct device *dev)
+{
+ struct tpm_chip *chip = dev_get_drvdata(dev);
+ if ( chip ) {
+ release_region(chip->vendor->base, 2);
+ tpm_remove_hardware(chip->dev);
+ }
+}
+
+static struct device_driver nsc_drv = {
+ .name = "tpm_nsc",
+ .bus = &platform_bus_type,
+ .owner = THIS_MODULE,
+ .suspend = tpm_pm_suspend,
+ .resume = tpm_pm_resume,
+};
+
+static int __init init_nsc(void)
{
int rc = 0;
int lo, hi;
int nscAddrBase = TPM_ADDR;
- if (pci_enable_device(pci_dev))
- return -EIO;
-
- /* select PM channel 1 */
- tpm_write_index(nscAddrBase,NSC_LDN_INDEX, 0x12);
-
/* verify that it is a National part (SID) */
if (tpm_read_index(TPM_ADDR, NSC_SID_INDEX) != 0xEF) {
nscAddrBase = (tpm_read_index(TPM_SUPERIO_ADDR, 0x2C)<<8)|
(tpm_read_index(TPM_SUPERIO_ADDR, 0x2B)&0xFE);
- if (tpm_read_index(nscAddrBase, NSC_SID_INDEX) != 0xF6) {
- rc = -ENODEV;
- goto out_err;
- }
+ if (tpm_read_index(nscAddrBase, NSC_SID_INDEX) != 0xF6)
+ return -ENODEV;
}
+ driver_register(&nsc_drv);
+
hi = tpm_read_index(nscAddrBase, TPM_NSC_BASE0_HI);
lo = tpm_read_index(nscAddrBase, TPM_NSC_BASE0_LO);
tpm_nsc.base = (hi<<8) | lo;
- dev_dbg(&pci_dev->dev, "NSC TPM detected\n");
- dev_dbg(&pci_dev->dev,
+ /* enable the DPM module */
+ tpm_write_index(nscAddrBase, NSC_LDC_INDEX, 0x01);
+
+ pdev = kzalloc(sizeof(struct platform_device), GFP_KERNEL);
+ if (!pdev) {
+ rc = -ENOMEM;
+ goto err_unreg_drv;
+ }
+
+ pdev->name = "tpm_nscl0";
+ pdev->id = -1;
+ pdev->num_resources = 0;
+ pdev->dev.release = tpm_nsc_remove;
+ pdev->dev.driver = &nsc_drv;
+
+ if ((rc = platform_device_register(pdev)) < 0)
+ goto err_free_dev;
+
+ if (request_region(tpm_nsc.base, 2, "tpm_nsc0") == NULL ) {
+ rc = -EBUSY;
+ goto err_unreg_dev;
+ }
+
+ if ((rc = tpm_register_hardware(&pdev->dev, &tpm_nsc)) < 0)
+ goto err_rel_reg;
+
+ dev_dbg(&pdev->dev, "NSC TPM detected\n");
+ dev_dbg(&pdev->dev,
"NSC LDN 0x%x, SID 0x%x, SRID 0x%x\n",
tpm_read_index(nscAddrBase,0x07), tpm_read_index(nscAddrBase,0x20),
tpm_read_index(nscAddrBase,0x27));
- dev_dbg(&pci_dev->dev,
+ dev_dbg(&pdev->dev,
"NSC SIOCF1 0x%x SIOCF5 0x%x SIOCF6 0x%x SIOCF8 0x%x\n",
tpm_read_index(nscAddrBase,0x21), tpm_read_index(nscAddrBase,0x25),
tpm_read_index(nscAddrBase,0x26), tpm_read_index(nscAddrBase,0x28));
- dev_dbg(&pci_dev->dev, "NSC IO Base0 0x%x\n",
+ dev_dbg(&pdev->dev, "NSC IO Base0 0x%x\n",
(tpm_read_index(nscAddrBase,0x60) << 8) | tpm_read_index(nscAddrBase,0x61));
- dev_dbg(&pci_dev->dev, "NSC IO Base1 0x%x\n",
+ dev_dbg(&pdev->dev, "NSC IO Base1 0x%x\n",
(tpm_read_index(nscAddrBase,0x62) << 8) | tpm_read_index(nscAddrBase,0x63));
- dev_dbg(&pci_dev->dev, "NSC Interrupt number and wakeup 0x%x\n",
+ dev_dbg(&pdev->dev, "NSC Interrupt number and wakeup 0x%x\n",
tpm_read_index(nscAddrBase,0x70));
- dev_dbg(&pci_dev->dev, "NSC IRQ type select 0x%x\n",
+ dev_dbg(&pdev->dev, "NSC IRQ type select 0x%x\n",
tpm_read_index(nscAddrBase,0x71));
- dev_dbg(&pci_dev->dev,
+ dev_dbg(&pdev->dev,
"NSC DMA channel select0 0x%x, select1 0x%x\n",
tpm_read_index(nscAddrBase,0x74), tpm_read_index(nscAddrBase,0x75));
- dev_dbg(&pci_dev->dev,
+ dev_dbg(&pdev->dev,
"NSC Config "
"0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
tpm_read_index(nscAddrBase,0xF0), tpm_read_index(nscAddrBase,0xF1),
@@ -312,55 +357,33 @@ static int __devinit tpm_nsc_init(struct pci_dev *pci_dev,
tpm_read_index(nscAddrBase,0xF6), tpm_read_index(nscAddrBase,0xF7),
tpm_read_index(nscAddrBase,0xF8), tpm_read_index(nscAddrBase,0xF9));
- dev_info(&pci_dev->dev,
+ dev_info(&pdev->dev,
"NSC TPM revision %d\n",
tpm_read_index(nscAddrBase, 0x27) & 0x1F);
- /* enable the DPM module */
- tpm_write_index(nscAddrBase, NSC_LDC_INDEX, 0x01);
-
- if ((rc = tpm_register_hardware(pci_dev, &tpm_nsc)) < 0)
- goto out_err;
-
return 0;
-out_err:
- pci_disable_device(pci_dev);
+err_rel_reg:
+ release_region(tpm_nsc.base, 2);
+err_unreg_dev:
+ platform_device_unregister(pdev);
+err_free_dev:
+ kfree(pdev);
+err_unreg_drv:
+ driver_unregister(&nsc_drv);
return rc;
}
-static struct pci_device_id tpm_pci_tbl[] __devinitdata = {
- {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0)},
- {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12)},
- {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0)},
- {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12)},
- {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0)},
- {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_0)},
- {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1)},
- {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_0)},
- {PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8111_LPC)},
- {0,}
-};
-
-MODULE_DEVICE_TABLE(pci, tpm_pci_tbl);
-
-static struct pci_driver nsc_pci_driver = {
- .name = "tpm_nsc",
- .id_table = tpm_pci_tbl,
- .probe = tpm_nsc_init,
- .remove = __devexit_p(tpm_remove),
- .suspend = tpm_pm_suspend,
- .resume = tpm_pm_resume,
-};
-
-static int __init init_nsc(void)
-{
- return pci_register_driver(&nsc_pci_driver);
-}
-
static void __exit cleanup_nsc(void)
{
- pci_unregister_driver(&nsc_pci_driver);
+ if (pdev) {
+ tpm_nsc_remove(&pdev->dev);
+ platform_device_unregister(pdev);
+ kfree(pdev);
+ pdev = NULL;
+ }
+
+ driver_unregister(&nsc_drv);
}
module_init(init_nsc);
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index e5953f3433f3..4b1eef51ec59 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -809,7 +809,7 @@ static void do_tty_hangup(void *data)
check_tty_count(tty, "do_tty_hangup");
file_list_lock();
/* This breaks for file handles being sent over AF_UNIX sockets ? */
- list_for_each_entry(filp, &tty->tty_files, f_list) {
+ list_for_each_entry(filp, &tty->tty_files, f_u.fu_list) {
if (filp->f_op->write == redirected_tty_write)
cons_filp = filp;
if (filp->f_op->write != tty_write)
@@ -1416,14 +1416,11 @@ end_init:
/* Release locally allocated memory ... nothing placed in slots */
free_mem_out:
- if (o_tp)
- kfree(o_tp);
+ kfree(o_tp);
if (o_tty)
free_tty_struct(o_tty);
- if (ltp)
- kfree(ltp);
- if (tp)
- kfree(tp);
+ kfree(ltp);
+ kfree(tp);
free_tty_struct(tty);
fail_no_mem:
@@ -2728,7 +2725,7 @@ void tty_register_device(struct tty_driver *driver, unsigned index,
pty_line_name(driver, index, name);
else
tty_line_name(driver, index, name);
- class_device_create(tty_class, dev, device, name);
+ class_device_create(tty_class, NULL, dev, device, "%s", name);
}
/**
@@ -2983,14 +2980,14 @@ static int __init tty_init(void)
register_chrdev_region(MKDEV(TTYAUX_MAJOR, 0), 1, "/dev/tty") < 0)
panic("Couldn't register /dev/tty driver\n");
devfs_mk_cdev(MKDEV(TTYAUX_MAJOR, 0), S_IFCHR|S_IRUGO|S_IWUGO, "tty");
- class_device_create(tty_class, MKDEV(TTYAUX_MAJOR, 0), NULL, "tty");
+ class_device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 0), NULL, "tty");
cdev_init(&console_cdev, &console_fops);
if (cdev_add(&console_cdev, MKDEV(TTYAUX_MAJOR, 1), 1) ||
register_chrdev_region(MKDEV(TTYAUX_MAJOR, 1), 1, "/dev/console") < 0)
panic("Couldn't register /dev/console driver\n");
devfs_mk_cdev(MKDEV(TTYAUX_MAJOR, 1), S_IFCHR|S_IRUSR|S_IWUSR, "console");
- class_device_create(tty_class, MKDEV(TTYAUX_MAJOR, 1), NULL, "console");
+ class_device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 1), NULL, "console");
#ifdef CONFIG_UNIX98_PTYS
cdev_init(&ptmx_cdev, &ptmx_fops);
@@ -2998,7 +2995,7 @@ static int __init tty_init(void)
register_chrdev_region(MKDEV(TTYAUX_MAJOR, 2), 1, "/dev/ptmx") < 0)
panic("Couldn't register /dev/ptmx driver\n");
devfs_mk_cdev(MKDEV(TTYAUX_MAJOR, 2), S_IFCHR|S_IRUGO|S_IWUGO, "ptmx");
- class_device_create(tty_class, MKDEV(TTYAUX_MAJOR, 2), NULL, "ptmx");
+ class_device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 2), NULL, "ptmx");
#endif
#ifdef CONFIG_VT
@@ -3007,7 +3004,7 @@ static int __init tty_init(void)
register_chrdev_region(MKDEV(TTY_MAJOR, 0), 1, "/dev/vc/0") < 0)
panic("Couldn't register /dev/tty0 driver\n");
devfs_mk_cdev(MKDEV(TTY_MAJOR, 0), S_IFCHR|S_IRUSR|S_IWUSR, "vc/0");
- class_device_create(tty_class, MKDEV(TTY_MAJOR, 0), NULL, "tty0");
+ class_device_create(tty_class, NULL, MKDEV(TTY_MAJOR, 0), NULL, "tty0");
vty_init();
#endif
diff --git a/drivers/char/vc_screen.c b/drivers/char/vc_screen.c
index 79c2928a8817..f66c7ad6fd38 100644
--- a/drivers/char/vc_screen.c
+++ b/drivers/char/vc_screen.c
@@ -484,8 +484,10 @@ void vcs_make_devfs(struct tty_struct *tty)
devfs_mk_cdev(MKDEV(VCS_MAJOR, tty->index + 129),
S_IFCHR|S_IRUSR|S_IWUSR,
"vcc/a%u", tty->index + 1);
- class_device_create(vc_class, MKDEV(VCS_MAJOR, tty->index + 1), NULL, "vcs%u", tty->index + 1);
- class_device_create(vc_class, MKDEV(VCS_MAJOR, tty->index + 129), NULL, "vcsa%u", tty->index + 1);
+ class_device_create(vc_class, NULL, MKDEV(VCS_MAJOR, tty->index + 1),
+ NULL, "vcs%u", tty->index + 1);
+ class_device_create(vc_class, NULL, MKDEV(VCS_MAJOR, tty->index + 129),
+ NULL, "vcsa%u", tty->index + 1);
}
void vcs_remove_devfs(struct tty_struct *tty)
{
@@ -503,7 +505,7 @@ int __init vcs_init(void)
devfs_mk_cdev(MKDEV(VCS_MAJOR, 0), S_IFCHR|S_IRUSR|S_IWUSR, "vcc/0");
devfs_mk_cdev(MKDEV(VCS_MAJOR, 128), S_IFCHR|S_IRUSR|S_IWUSR, "vcc/a0");
- class_device_create(vc_class, MKDEV(VCS_MAJOR, 0), NULL, "vcs");
- class_device_create(vc_class, MKDEV(VCS_MAJOR, 128), NULL, "vcsa");
+ class_device_create(vc_class, NULL, MKDEV(VCS_MAJOR, 0), NULL, "vcs");
+ class_device_create(vc_class, NULL, MKDEV(VCS_MAJOR, 128), NULL, "vcsa");
return 0;
}
diff --git a/drivers/char/viocons.c b/drivers/char/viocons.c
index 44f5fb4a46ef..4d75c261f98a 100644
--- a/drivers/char/viocons.c
+++ b/drivers/char/viocons.c
@@ -26,7 +26,6 @@
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <linux/config.h>
-#include <linux/version.h>
#include <linux/kernel.h>
#include <linux/proc_fs.h>
#include <linux/errno.h>
@@ -44,12 +43,12 @@
#include <linux/tty_flip.h>
#include <linux/sysrq.h>
-#include <asm/iSeries/vio.h>
+#include <asm/iseries/vio.h>
-#include <asm/iSeries/HvLpEvent.h>
-#include <asm/iSeries/HvCallEvent.h>
-#include <asm/iSeries/HvLpConfig.h>
-#include <asm/iSeries/HvCall.h>
+#include <asm/iseries/hv_lp_event.h>
+#include <asm/iseries/hv_call_event.h>
+#include <asm/iseries/hv_lp_config.h>
+#include <asm/iseries/hv_call.h>
#ifdef CONFIG_VT
#error You must turn off CONFIG_VT to use CONFIG_VIOCONS
diff --git a/drivers/char/viotape.c b/drivers/char/viotape.c
index 0aff45fac2e6..60aabdb4a046 100644
--- a/drivers/char/viotape.c
+++ b/drivers/char/viotape.c
@@ -29,10 +29,9 @@
*
* All tape operations are performed by sending messages back and forth to
* the OS/400 partition. The format of the messages is defined in
- * iSeries/vio.h
+ * iseries/vio.h
*/
#include <linux/config.h>
-#include <linux/version.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/errno.h>
@@ -54,10 +53,10 @@
#include <asm/ioctls.h>
#include <asm/vio.h>
-#include <asm/iSeries/vio.h>
-#include <asm/iSeries/HvLpEvent.h>
-#include <asm/iSeries/HvCallEvent.h>
-#include <asm/iSeries/HvLpConfig.h>
+#include <asm/iseries/vio.h>
+#include <asm/iseries/hv_lp_event.h>
+#include <asm/iseries/hv_call_event.h>
+#include <asm/iseries/hv_lp_config.h>
#define VIOTAPE_VERSION "1.2"
#define VIOTAPE_MAXREQ 1
@@ -956,9 +955,9 @@ static int viotape_probe(struct vio_dev *vdev, const struct vio_device_id *id)
state[i].cur_part = 0;
for (j = 0; j < MAX_PARTITIONS; ++j)
state[i].part_stat_rwi[j] = VIOT_IDLE;
- class_device_create(tape_class, MKDEV(VIOTAPE_MAJOR, i), NULL,
+ class_device_create(tape_class, NULL, MKDEV(VIOTAPE_MAJOR, i), NULL,
"iseries!vt%d", i);
- class_device_create(tape_class, MKDEV(VIOTAPE_MAJOR, i | 0x80),
+ class_device_create(tape_class, NULL, MKDEV(VIOTAPE_MAJOR, i | 0x80),
NULL, "iseries!nvt%d", i);
devfs_mk_cdev(MKDEV(VIOTAPE_MAJOR, i), S_IFCHR | S_IRUSR | S_IWUSR,
"iseries/vt%d", i);
@@ -993,13 +992,16 @@ static struct vio_device_id viotape_device_table[] __devinitdata = {
{ "viotape", "" },
{ "", "" }
};
-
MODULE_DEVICE_TABLE(vio, viotape_device_table);
+
static struct vio_driver viotape_driver = {
- .name = "viotape",
.id_table = viotape_device_table,
.probe = viotape_probe,
- .remove = viotape_remove
+ .remove = viotape_remove,
+ .driver = {
+ .name = "viotape",
+ .owner = THIS_MODULE,
+ }
};
diff --git a/drivers/char/vr41xx_giu.c b/drivers/char/vr41xx_giu.c
index 683278bc5241..94641085faf8 100644
--- a/drivers/char/vr41xx_giu.c
+++ b/drivers/char/vr41xx_giu.c
@@ -19,7 +19,7 @@
* 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/device.h>
+#include <linux/platform_device.h>
#include <linux/errno.h>
#include <linux/fs.h>
#include <linux/init.h>
diff --git a/drivers/char/vr41xx_rtc.c b/drivers/char/vr41xx_rtc.c
index a6dbe4da030c..5e3292df69d8 100644
--- a/drivers/char/vr41xx_rtc.c
+++ b/drivers/char/vr41xx_rtc.c
@@ -17,7 +17,7 @@
* 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/device.h>
+#include <linux/platform_device.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/ioport.h>
diff --git a/drivers/char/vt_ioctl.c b/drivers/char/vt_ioctl.c
index 1d44f69e1fda..24011e7c81ff 100644
--- a/drivers/char/vt_ioctl.c
+++ b/drivers/char/vt_ioctl.c
@@ -80,6 +80,9 @@ do_kdsk_ioctl(int cmd, struct kbentry __user *user_kbe, int perm, struct kbd_str
if (copy_from_user(&tmp, user_kbe, sizeof(struct kbentry)))
return -EFAULT;
+ if (!capable(CAP_SYS_TTY_CONFIG))
+ perm = 0;
+
switch (cmd) {
case KDGKBENT:
key_map = key_maps[s];
@@ -192,6 +195,9 @@ do_kdgkb_ioctl(int cmd, struct kbsentry __user *user_kdgkb, int perm)
int i, j, k;
int ret;
+ if (!capable(CAP_SYS_TTY_CONFIG))
+ perm = 0;
+
kbs = kmalloc(sizeof(*kbs), GFP_KERNEL);
if (!kbs) {
ret = -ENOMEM;
diff --git a/drivers/char/watchdog/cpu5wdt.c b/drivers/char/watchdog/cpu5wdt.c
index 2865dac0a813..e75045fe2641 100644
--- a/drivers/char/watchdog/cpu5wdt.c
+++ b/drivers/char/watchdog/cpu5wdt.c
@@ -28,6 +28,7 @@
#include <linux/init.h>
#include <linux/ioport.h>
#include <linux/timer.h>
+#include <linux/jiffies.h>
#include <asm/io.h>
#include <asm/uaccess.h>
diff --git a/drivers/char/watchdog/mixcomwd.c b/drivers/char/watchdog/mixcomwd.c
index 7fc2188386d9..d8dede575402 100644
--- a/drivers/char/watchdog/mixcomwd.c
+++ b/drivers/char/watchdog/mixcomwd.c
@@ -45,6 +45,8 @@
#include <linux/fs.h>
#include <linux/reboot.h>
#include <linux/init.h>
+#include <linux/jiffies.h>
+#include <linux/timer.h>
#include <asm/uaccess.h>
#include <asm/io.h>
diff --git a/drivers/char/watchdog/mpcore_wdt.c b/drivers/char/watchdog/mpcore_wdt.c
index 75ca84ed4adf..da631c114fd1 100644
--- a/drivers/char/watchdog/mpcore_wdt.c
+++ b/drivers/char/watchdog/mpcore_wdt.c
@@ -29,7 +29,7 @@
#include <linux/reboot.h>
#include <linux/init.h>
#include <linux/interrupt.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <asm/hardware/arm_twd.h>
#include <asm/uaccess.h>
@@ -396,6 +396,7 @@ static int __devexit mpcore_wdt_remove(struct device *dev)
}
static struct device_driver mpcore_wdt_driver = {
+ .owner = THIS_MODULE,
.name = "mpcore_wdt",
.bus = &platform_bus_type,
.probe = mpcore_wdt_probe,
diff --git a/drivers/char/watchdog/mv64x60_wdt.c b/drivers/char/watchdog/mv64x60_wdt.c
index 6d3ff0836c44..119b3c541d95 100644
--- a/drivers/char/watchdog/mv64x60_wdt.c
+++ b/drivers/char/watchdog/mv64x60_wdt.c
@@ -22,6 +22,8 @@
#include <linux/miscdevice.h>
#include <linux/module.h>
#include <linux/watchdog.h>
+#include <linux/platform_device.h>
+
#include <asm/mv64x60.h>
#include <asm/uaccess.h>
#include <asm/io.h>
@@ -211,6 +213,7 @@ static int __devexit mv64x60_wdt_remove(struct device *dev)
}
static struct device_driver mv64x60_wdt_driver = {
+ .owner = THIS_MODULE,
.name = MV64x60_WDT_NAME,
.bus = &platform_bus_type,
.probe = mv64x60_wdt_probe,
diff --git a/drivers/char/watchdog/pcwd.c b/drivers/char/watchdog/pcwd.c
index 427ad51b7a35..37c9e13ad3ac 100644
--- a/drivers/char/watchdog/pcwd.c
+++ b/drivers/char/watchdog/pcwd.c
@@ -66,7 +66,7 @@
#include <linux/init.h>
#include <linux/spinlock.h>
#include <linux/reboot.h>
-
+#include <linux/sched.h> /* TASK_INTERRUPTIBLE, set_current_state() and friends */
#include <asm/uaccess.h>
#include <asm/io.h>
diff --git a/drivers/char/watchdog/pcwd_pci.c b/drivers/char/watchdog/pcwd_pci.c
index 0b8e493be045..2451edbefece 100644
--- a/drivers/char/watchdog/pcwd_pci.c
+++ b/drivers/char/watchdog/pcwd_pci.c
@@ -1,7 +1,7 @@
/*
* Berkshire PCI-PC Watchdog Card Driver
*
- * (c) Copyright 2003 Wim Van Sebroeck <wim@iguana.be>.
+ * (c) Copyright 2003-2005 Wim Van Sebroeck <wim@iguana.be>.
*
* Based on source code of the following authors:
* Ken Hollis <kenji@bitgate.com>,
@@ -21,7 +21,9 @@
*/
/*
- * A bells and whistles driver is available from http://www.pcwd.de/
+ * A bells and whistles driver is available from:
+ * http://www.kernel.org/pub/linux/kernel/people/wim/pcwd/pcwd_pci/
+ *
* More info available at http://www.berkprod.com/ or http://www.pcwatchdog.com/
*/
diff --git a/drivers/char/watchdog/s3c2410_wdt.c b/drivers/char/watchdog/s3c2410_wdt.c
index 3625b2601b42..751cb77b0715 100644
--- a/drivers/char/watchdog/s3c2410_wdt.c
+++ b/drivers/char/watchdog/s3c2410_wdt.c
@@ -44,7 +44,7 @@
#include <linux/watchdog.h>
#include <linux/fs.h>
#include <linux/init.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <linux/interrupt.h>
#include <asm/uaccess.h>
@@ -464,32 +464,28 @@ static void s3c2410wdt_shutdown(struct device *dev)
static unsigned long wtcon_save;
static unsigned long wtdat_save;
-static int s3c2410wdt_suspend(struct device *dev, pm_message_t state, u32 level)
+static int s3c2410wdt_suspend(struct device *dev, pm_message_t state)
{
- if (level == SUSPEND_POWER_DOWN) {
- /* Save watchdog state, and turn it off. */
- wtcon_save = readl(wdt_base + S3C2410_WTCON);
- wtdat_save = readl(wdt_base + S3C2410_WTDAT);
+ /* Save watchdog state, and turn it off. */
+ wtcon_save = readl(wdt_base + S3C2410_WTCON);
+ wtdat_save = readl(wdt_base + S3C2410_WTDAT);
- /* Note that WTCNT doesn't need to be saved. */
- s3c2410wdt_stop();
- }
+ /* Note that WTCNT doesn't need to be saved. */
+ s3c2410wdt_stop();
return 0;
}
-static int s3c2410wdt_resume(struct device *dev, u32 level)
+static int s3c2410wdt_resume(struct device *dev)
{
- if (level == RESUME_POWER_ON) {
- /* Restore watchdog state. */
+ /* Restore watchdog state. */
- writel(wtdat_save, wdt_base + S3C2410_WTDAT);
- writel(wtdat_save, wdt_base + S3C2410_WTCNT); /* Reset count */
- writel(wtcon_save, wdt_base + S3C2410_WTCON);
+ writel(wtdat_save, wdt_base + S3C2410_WTDAT);
+ writel(wtdat_save, wdt_base + S3C2410_WTCNT); /* Reset count */
+ writel(wtcon_save, wdt_base + S3C2410_WTCON);
- printk(KERN_INFO PFX "watchdog %sabled\n",
- (wtcon_save & S3C2410_WTCON_ENABLE) ? "en" : "dis");
- }
+ printk(KERN_INFO PFX "watchdog %sabled\n",
+ (wtcon_save & S3C2410_WTCON_ENABLE) ? "en" : "dis");
return 0;
}
@@ -501,6 +497,7 @@ static int s3c2410wdt_resume(struct device *dev, u32 level)
static struct device_driver s3c2410wdt_driver = {
+ .owner = THIS_MODULE,
.name = "s3c2410-wdt",
.bus = &platform_bus_type,
.probe = s3c2410wdt_probe,
diff --git a/drivers/char/watchdog/sc520_wdt.c b/drivers/char/watchdog/sc520_wdt.c
index 72501be79b0c..4ee9974ad8cb 100644
--- a/drivers/char/watchdog/sc520_wdt.c
+++ b/drivers/char/watchdog/sc520_wdt.c
@@ -63,6 +63,7 @@
#include <linux/notifier.h>
#include <linux/reboot.h>
#include <linux/init.h>
+#include <linux/jiffies.h>
#include <asm/io.h>
#include <asm/uaccess.h>
diff --git a/drivers/char/watchdog/softdog.c b/drivers/char/watchdog/softdog.c
index 20e5eb8667f2..a91edaf3a350 100644
--- a/drivers/char/watchdog/softdog.c
+++ b/drivers/char/watchdog/softdog.c
@@ -47,6 +47,8 @@
#include <linux/notifier.h>
#include <linux/reboot.h>
#include <linux/init.h>
+#include <linux/jiffies.h>
+
#include <asm/uaccess.h>
#define PFX "SoftDog: "
diff --git a/drivers/char/watchdog/w83627hf_wdt.c b/drivers/char/watchdog/w83627hf_wdt.c
index b5d821015421..d15ca9a3986f 100644
--- a/drivers/char/watchdog/w83627hf_wdt.c
+++ b/drivers/char/watchdog/w83627hf_wdt.c
@@ -359,5 +359,5 @@ module_exit(wdt_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Pádraig Brady <P@draigBrady.com>");
-MODULE_DESCRIPTION("w38627hf WDT driver");
+MODULE_DESCRIPTION("w83627hf WDT driver");
MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
diff --git a/drivers/connector/Kconfig b/drivers/connector/Kconfig
index 0bc2059c1e08..e0bdc0db9640 100644
--- a/drivers/connector/Kconfig
+++ b/drivers/connector/Kconfig
@@ -10,4 +10,12 @@ config CONNECTOR
Connector support can also be built as a module. If so, the module
will be called cn.ko.
+config PROC_EVENTS
+ boolean "Report process events to userspace"
+ depends on CONNECTOR=y
+ default y
+ ---help---
+ Provide a connector that reports process events to userspace. Send
+ events such as fork, exec, id change (uid, gid, suid, etc), and exit.
+
endmenu
diff --git a/drivers/connector/Makefile b/drivers/connector/Makefile
index 12ca79e8234d..1f255e46e916 100644
--- a/drivers/connector/Makefile
+++ b/drivers/connector/Makefile
@@ -1,3 +1,4 @@
obj-$(CONFIG_CONNECTOR) += cn.o
+obj-$(CONFIG_PROC_EVENTS) += cn_proc.o
cn-y += cn_queue.o connector.o
diff --git a/drivers/connector/cn_proc.c b/drivers/connector/cn_proc.c
new file mode 100644
index 000000000000..fcdf0fff13a6
--- /dev/null
+++ b/drivers/connector/cn_proc.c
@@ -0,0 +1,222 @@
+/*
+ * cn_proc.c - process events connector
+ *
+ * Copyright (C) Matt Helsley, IBM Corp. 2005
+ * Based on cn_fork.c by Guillaume Thouvenin <guillaume.thouvenin@bull.net>
+ * Original copyright notice follows:
+ * Copyright (C) 2005 BULL SA.
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <asm/atomic.h>
+
+#include <linux/cn_proc.h>
+
+#define CN_PROC_MSG_SIZE (sizeof(struct cn_msg) + sizeof(struct proc_event))
+
+static atomic_t proc_event_num_listeners = ATOMIC_INIT(0);
+static struct cb_id cn_proc_event_id = { CN_IDX_PROC, CN_VAL_PROC };
+
+/* proc_counts is used as the sequence number of the netlink message */
+static DEFINE_PER_CPU(__u32, proc_event_counts) = { 0 };
+
+static inline void get_seq(__u32 *ts, int *cpu)
+{
+ *ts = get_cpu_var(proc_event_counts)++;
+ *cpu = smp_processor_id();
+ put_cpu_var(proc_counts);
+}
+
+void proc_fork_connector(struct task_struct *task)
+{
+ struct cn_msg *msg;
+ struct proc_event *ev;
+ __u8 buffer[CN_PROC_MSG_SIZE];
+
+ if (atomic_read(&proc_event_num_listeners) < 1)
+ return;
+
+ msg = (struct cn_msg*)buffer;
+ ev = (struct proc_event*)msg->data;
+ get_seq(&msg->seq, &ev->cpu);
+ ev->what = PROC_EVENT_FORK;
+ ev->event_data.fork.parent_pid = task->real_parent->pid;
+ ev->event_data.fork.parent_tgid = task->real_parent->tgid;
+ ev->event_data.fork.child_pid = task->pid;
+ ev->event_data.fork.child_tgid = task->tgid;
+
+ memcpy(&msg->id, &cn_proc_event_id, sizeof(msg->id));
+ msg->ack = 0; /* not used */
+ msg->len = sizeof(*ev);
+ /* If cn_netlink_send() failed, the data is not sent */
+ cn_netlink_send(msg, CN_IDX_PROC, GFP_KERNEL);
+}
+
+void proc_exec_connector(struct task_struct *task)
+{
+ struct cn_msg *msg;
+ struct proc_event *ev;
+ __u8 buffer[CN_PROC_MSG_SIZE];
+
+ if (atomic_read(&proc_event_num_listeners) < 1)
+ return;
+
+ msg = (struct cn_msg*)buffer;
+ ev = (struct proc_event*)msg->data;
+ get_seq(&msg->seq, &ev->cpu);
+ ev->what = PROC_EVENT_EXEC;
+ ev->event_data.exec.process_pid = task->pid;
+ ev->event_data.exec.process_tgid = task->tgid;
+
+ memcpy(&msg->id, &cn_proc_event_id, sizeof(msg->id));
+ msg->ack = 0; /* not used */
+ msg->len = sizeof(*ev);
+ cn_netlink_send(msg, CN_IDX_PROC, GFP_KERNEL);
+}
+
+void proc_id_connector(struct task_struct *task, int which_id)
+{
+ struct cn_msg *msg;
+ struct proc_event *ev;
+ __u8 buffer[CN_PROC_MSG_SIZE];
+
+ if (atomic_read(&proc_event_num_listeners) < 1)
+ return;
+
+ msg = (struct cn_msg*)buffer;
+ ev = (struct proc_event*)msg->data;
+ ev->what = which_id;
+ ev->event_data.id.process_pid = task->pid;
+ ev->event_data.id.process_tgid = task->tgid;
+ if (which_id == PROC_EVENT_UID) {
+ ev->event_data.id.r.ruid = task->uid;
+ ev->event_data.id.e.euid = task->euid;
+ } else if (which_id == PROC_EVENT_GID) {
+ ev->event_data.id.r.rgid = task->gid;
+ ev->event_data.id.e.egid = task->egid;
+ } else
+ return;
+ get_seq(&msg->seq, &ev->cpu);
+
+ memcpy(&msg->id, &cn_proc_event_id, sizeof(msg->id));
+ msg->ack = 0; /* not used */
+ msg->len = sizeof(*ev);
+ cn_netlink_send(msg, CN_IDX_PROC, GFP_KERNEL);
+}
+
+void proc_exit_connector(struct task_struct *task)
+{
+ struct cn_msg *msg;
+ struct proc_event *ev;
+ __u8 buffer[CN_PROC_MSG_SIZE];
+
+ if (atomic_read(&proc_event_num_listeners) < 1)
+ return;
+
+ msg = (struct cn_msg*)buffer;
+ ev = (struct proc_event*)msg->data;
+ get_seq(&msg->seq, &ev->cpu);
+ ev->what = PROC_EVENT_EXIT;
+ ev->event_data.exit.process_pid = task->pid;
+ ev->event_data.exit.process_tgid = task->tgid;
+ ev->event_data.exit.exit_code = task->exit_code;
+ ev->event_data.exit.exit_signal = task->exit_signal;
+
+ memcpy(&msg->id, &cn_proc_event_id, sizeof(msg->id));
+ msg->ack = 0; /* not used */
+ msg->len = sizeof(*ev);
+ cn_netlink_send(msg, CN_IDX_PROC, GFP_KERNEL);
+}
+
+/*
+ * Send an acknowledgement message to userspace
+ *
+ * Use 0 for success, EFOO otherwise.
+ * Note: this is the negative of conventional kernel error
+ * values because it's not being returned via syscall return
+ * mechanisms.
+ */
+static void cn_proc_ack(int err, int rcvd_seq, int rcvd_ack)
+{
+ struct cn_msg *msg;
+ struct proc_event *ev;
+ __u8 buffer[CN_PROC_MSG_SIZE];
+
+ if (atomic_read(&proc_event_num_listeners) < 1)
+ return;
+
+ msg = (struct cn_msg*)buffer;
+ ev = (struct proc_event*)msg->data;
+ msg->seq = rcvd_seq;
+ ev->cpu = -1;
+ ev->what = PROC_EVENT_NONE;
+ ev->event_data.ack.err = err;
+ memcpy(&msg->id, &cn_proc_event_id, sizeof(msg->id));
+ msg->ack = rcvd_ack + 1;
+ msg->len = sizeof(*ev);
+ cn_netlink_send(msg, CN_IDX_PROC, GFP_KERNEL);
+}
+
+/**
+ * cn_proc_mcast_ctl
+ * @data: message sent from userspace via the connector
+ */
+static void cn_proc_mcast_ctl(void *data)
+{
+ struct cn_msg *msg = data;
+ enum proc_cn_mcast_op *mc_op = NULL;
+ int err = 0;
+
+ if (msg->len != sizeof(*mc_op))
+ return;
+
+ mc_op = (enum proc_cn_mcast_op*)msg->data;
+ switch (*mc_op) {
+ case PROC_CN_MCAST_LISTEN:
+ atomic_inc(&proc_event_num_listeners);
+ break;
+ case PROC_CN_MCAST_IGNORE:
+ atomic_dec(&proc_event_num_listeners);
+ break;
+ default:
+ err = EINVAL;
+ break;
+ }
+ cn_proc_ack(err, msg->seq, msg->ack);
+}
+
+/*
+ * cn_proc_init - initialization entry point
+ *
+ * Adds the connector callback to the connector driver.
+ */
+static int __init cn_proc_init(void)
+{
+ int err;
+
+ if ((err = cn_add_callback(&cn_proc_event_id, "cn_proc",
+ &cn_proc_mcast_ctl))) {
+ printk(KERN_WARNING "cn_proc failed to register\n");
+ return err;
+ }
+ return 0;
+}
+
+module_init(cn_proc_init);
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index 109d62ccf651..23a63207d747 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -4,6 +4,9 @@
* Copyright (C) 2001 Russell King
* (C) 2002 - 2003 Dominik Brodowski <linux@brodo.de>
*
+ * Oct 2005 - Ashok Raj <ashok.raj@intel.com>
+ * Added handling for CPU hotplug
+ *
* 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.
@@ -35,14 +38,6 @@ static struct cpufreq_driver *cpufreq_driver;
static struct cpufreq_policy *cpufreq_cpu_data[NR_CPUS];
static DEFINE_SPINLOCK(cpufreq_driver_lock);
-
-/* we keep a copy of all ->add'ed CPU's struct sys_device here;
- * as it is only accessed in ->add and ->remove, no lock or reference
- * count is necessary.
- */
-static struct sys_device *cpu_sys_devices[NR_CPUS];
-
-
/* internal prototypes */
static int __cpufreq_governor(struct cpufreq_policy *policy, unsigned int event);
static void handle_update(void *data);
@@ -574,6 +569,9 @@ static int cpufreq_add_dev (struct sys_device * sys_dev)
unsigned long flags;
unsigned int j;
+ if (cpu_is_offline(cpu))
+ return 0;
+
cpufreq_debug_disable_ratelimit();
dprintk("adding CPU %u\n", cpu);
@@ -582,7 +580,6 @@ static int cpufreq_add_dev (struct sys_device * sys_dev)
* CPU because it is in the same boat. */
policy = cpufreq_cpu_get(cpu);
if (unlikely(policy)) {
- cpu_sys_devices[cpu] = sys_dev;
dprintk("CPU already managed, adding link\n");
sysfs_create_link(&sys_dev->kobj, &policy->kobj, "cpufreq");
cpufreq_debug_enable_ratelimit();
@@ -595,12 +592,11 @@ static int cpufreq_add_dev (struct sys_device * sys_dev)
goto module_out;
}
- policy = kmalloc(sizeof(struct cpufreq_policy), GFP_KERNEL);
+ policy = kzalloc(sizeof(struct cpufreq_policy), GFP_KERNEL);
if (!policy) {
ret = -ENOMEM;
goto nomem_out;
}
- memset(policy, 0, sizeof(struct cpufreq_policy));
policy->cpu = cpu;
policy->cpus = cpumask_of_cpu(cpu);
@@ -657,7 +653,6 @@ static int cpufreq_add_dev (struct sys_device * sys_dev)
}
module_put(cpufreq_driver->owner);
- cpu_sys_devices[cpu] = sys_dev;
dprintk("initialization complete\n");
cpufreq_debug_enable_ratelimit();
@@ -682,7 +677,7 @@ err_out:
nomem_out:
module_put(cpufreq_driver->owner);
- module_out:
+module_out:
cpufreq_debug_enable_ratelimit();
return ret;
}
@@ -698,6 +693,7 @@ static int cpufreq_remove_dev (struct sys_device * sys_dev)
unsigned int cpu = sys_dev->id;
unsigned long flags;
struct cpufreq_policy *data;
+ struct sys_device *cpu_sys_dev;
#ifdef CONFIG_SMP
unsigned int j;
#endif
@@ -710,7 +706,6 @@ static int cpufreq_remove_dev (struct sys_device * sys_dev)
if (!data) {
spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
- cpu_sys_devices[cpu] = NULL;
cpufreq_debug_enable_ratelimit();
return -EINVAL;
}
@@ -725,14 +720,12 @@ static int cpufreq_remove_dev (struct sys_device * sys_dev)
dprintk("removing link\n");
spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
sysfs_remove_link(&sys_dev->kobj, "cpufreq");
- cpu_sys_devices[cpu] = NULL;
cpufreq_cpu_put(data);
cpufreq_debug_enable_ratelimit();
return 0;
}
#endif
- cpu_sys_devices[cpu] = NULL;
if (!kobject_get(&data->kobj)) {
spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
@@ -761,7 +754,8 @@ static int cpufreq_remove_dev (struct sys_device * sys_dev)
if (j == cpu)
continue;
dprintk("removing link for cpu %u\n", j);
- sysfs_remove_link(&cpu_sys_devices[j]->kobj, "cpufreq");
+ cpu_sys_dev = get_cpu_sysdev(j);
+ sysfs_remove_link(&cpu_sys_dev->kobj, "cpufreq");
cpufreq_cpu_put(data);
}
}
@@ -772,7 +766,6 @@ static int cpufreq_remove_dev (struct sys_device * sys_dev)
down(&data->lock);
if (cpufreq_driver->target)
__cpufreq_governor(data, CPUFREQ_GOV_STOP);
- cpufreq_driver->target = NULL;
up(&data->lock);
kobject_unregister(&data->kobj);
@@ -1119,17 +1112,27 @@ int __cpufreq_driver_target(struct cpufreq_policy *policy,
unsigned int relation)
{
int retval = -EINVAL;
- lock_cpu_hotplug();
+
+ /*
+ * If we are already in context of hotplug thread, we dont need to
+ * acquire the hotplug lock. Otherwise acquire cpucontrol to prevent
+ * hotplug from removing this cpu that we are working on.
+ */
+ if (!current_in_cpu_hotplug())
+ lock_cpu_hotplug();
+
dprintk("target for CPU %u: %u kHz, relation %u\n", policy->cpu,
target_freq, relation);
if (cpu_online(policy->cpu) && cpufreq_driver->target)
retval = cpufreq_driver->target(policy, target_freq, relation);
- unlock_cpu_hotplug();
+
+ if (!current_in_cpu_hotplug())
+ unlock_cpu_hotplug();
+
return retval;
}
EXPORT_SYMBOL_GPL(__cpufreq_driver_target);
-
int cpufreq_driver_target(struct cpufreq_policy *policy,
unsigned int target_freq,
unsigned int relation)
@@ -1416,6 +1419,45 @@ int cpufreq_update_policy(unsigned int cpu)
}
EXPORT_SYMBOL(cpufreq_update_policy);
+static int __cpuinit cpufreq_cpu_callback(struct notifier_block *nfb,
+ unsigned long action, void *hcpu)
+{
+ unsigned int cpu = (unsigned long)hcpu;
+ struct cpufreq_policy *policy;
+ struct sys_device *sys_dev;
+
+ sys_dev = get_cpu_sysdev(cpu);
+
+ if (sys_dev) {
+ switch (action) {
+ case CPU_ONLINE:
+ cpufreq_add_dev(sys_dev);
+ break;
+ case CPU_DOWN_PREPARE:
+ /*
+ * We attempt to put this cpu in lowest frequency
+ * possible before going down. This will permit
+ * hardware-managed P-State to switch other related
+ * threads to min or higher speeds if possible.
+ */
+ policy = cpufreq_cpu_data[cpu];
+ if (policy) {
+ cpufreq_driver_target(policy, policy->min,
+ CPUFREQ_RELATION_H);
+ }
+ break;
+ case CPU_DEAD:
+ cpufreq_remove_dev(sys_dev);
+ break;
+ }
+ }
+ return NOTIFY_OK;
+}
+
+static struct notifier_block cpufreq_cpu_notifier =
+{
+ .notifier_call = cpufreq_cpu_callback,
+};
/*********************************************************************
* REGISTER / UNREGISTER CPUFREQ DRIVER *
@@ -1476,6 +1518,7 @@ int cpufreq_register_driver(struct cpufreq_driver *driver_data)
}
if (!ret) {
+ register_cpu_notifier(&cpufreq_cpu_notifier);
dprintk("driver %s up and running\n", driver_data->name);
cpufreq_debug_enable_ratelimit();
}
@@ -1507,6 +1550,7 @@ int cpufreq_unregister_driver(struct cpufreq_driver *driver)
dprintk("unregistering driver %s\n", driver->name);
sysdev_driver_unregister(&cpu_sysdev_class, &cpufreq_sysdev_driver);
+ unregister_cpu_notifier(&cpufreq_cpu_notifier);
spin_lock_irqsave(&cpufreq_driver_lock, flags);
cpufreq_driver = NULL;
diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c
index c1fc9c62bb51..17741111246b 100644
--- a/drivers/cpufreq/cpufreq_ondemand.c
+++ b/drivers/cpufreq/cpufreq_ondemand.c
@@ -48,7 +48,10 @@
* All times here are in uS.
*/
static unsigned int def_sampling_rate;
-#define MIN_SAMPLING_RATE (def_sampling_rate / 2)
+#define MIN_SAMPLING_RATE_RATIO (2)
+/* for correct statistics, we need at least 10 ticks between each measure */
+#define MIN_STAT_SAMPLING_RATE (MIN_SAMPLING_RATE_RATIO * jiffies_to_usecs(10))
+#define MIN_SAMPLING_RATE (def_sampling_rate / MIN_SAMPLING_RATE_RATIO)
#define MAX_SAMPLING_RATE (500 * def_sampling_rate)
#define DEF_SAMPLING_RATE_LATENCY_MULTIPLIER (1000)
#define DEF_SAMPLING_DOWN_FACTOR (1)
@@ -416,13 +419,16 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
if (dbs_enable == 1) {
unsigned int latency;
/* policy latency is in nS. Convert it to uS first */
+ latency = policy->cpuinfo.transition_latency / 1000;
+ if (latency == 0)
+ latency = 1;
- latency = policy->cpuinfo.transition_latency;
- if (latency < 1000)
- latency = 1000;
-
- def_sampling_rate = (latency / 1000) *
+ def_sampling_rate = latency *
DEF_SAMPLING_RATE_LATENCY_MULTIPLIER;
+
+ if (def_sampling_rate < MIN_STAT_SAMPLING_RATE)
+ def_sampling_rate = MIN_STAT_SAMPLING_RATE;
+
dbs_tuners_ins.sampling_rate = def_sampling_rate;
dbs_tuners_ins.ignore_nice = 0;
diff --git a/drivers/cpufreq/cpufreq_stats.c b/drivers/cpufreq/cpufreq_stats.c
index 741b6b191e6a..0bddb8e694d9 100644
--- a/drivers/cpufreq/cpufreq_stats.c
+++ b/drivers/cpufreq/cpufreq_stats.c
@@ -19,6 +19,7 @@
#include <linux/percpu.h>
#include <linux/kobject.h>
#include <linux/spinlock.h>
+#include <linux/notifier.h>
#include <asm/cputime.h>
static spinlock_t cpufreq_stats_lock;
@@ -192,11 +193,15 @@ cpufreq_stats_create_table (struct cpufreq_policy *policy,
unsigned int cpu = policy->cpu;
if (cpufreq_stats_table[cpu])
return -EBUSY;
- if ((stat = kmalloc(sizeof(struct cpufreq_stats), GFP_KERNEL)) == NULL)
+ if ((stat = kzalloc(sizeof(struct cpufreq_stats), GFP_KERNEL)) == NULL)
return -ENOMEM;
- memset(stat, 0, sizeof (struct cpufreq_stats));
data = cpufreq_cpu_get(cpu);
+ if (data == NULL) {
+ ret = -EINVAL;
+ goto error_get_fail;
+ }
+
if ((ret = sysfs_create_group(&data->kobj, &stats_attr_group)))
goto error_out;
@@ -216,12 +221,11 @@ cpufreq_stats_create_table (struct cpufreq_policy *policy,
alloc_size += count * count * sizeof(int);
#endif
stat->max_state = count;
- stat->time_in_state = kmalloc(alloc_size, GFP_KERNEL);
+ stat->time_in_state = kzalloc(alloc_size, GFP_KERNEL);
if (!stat->time_in_state) {
ret = -ENOMEM;
goto error_out;
}
- memset(stat->time_in_state, 0, alloc_size);
stat->freq_table = (unsigned int *)(stat->time_in_state + count);
#ifdef CONFIG_CPU_FREQ_STAT_DETAILS
@@ -244,6 +248,7 @@ cpufreq_stats_create_table (struct cpufreq_policy *policy,
return 0;
error_out:
cpufreq_cpu_put(data);
+error_get_fail:
kfree(stat);
cpufreq_stats_table[cpu] = NULL;
return ret;
@@ -298,6 +303,27 @@ cpufreq_stat_notifier_trans (struct notifier_block *nb, unsigned long val,
return 0;
}
+static int __cpuinit cpufreq_stat_cpu_callback(struct notifier_block *nfb,
+ unsigned long action, void *hcpu)
+{
+ unsigned int cpu = (unsigned long)hcpu;
+
+ switch (action) {
+ case CPU_ONLINE:
+ cpufreq_update_policy(cpu);
+ break;
+ case CPU_DEAD:
+ cpufreq_stats_free_table(cpu);
+ break;
+ }
+ return NOTIFY_OK;
+}
+
+static struct notifier_block cpufreq_stat_cpu_notifier =
+{
+ .notifier_call = cpufreq_stat_cpu_callback,
+};
+
static struct notifier_block notifier_policy_block = {
.notifier_call = cpufreq_stat_notifier_policy
};
@@ -311,6 +337,7 @@ __init cpufreq_stats_init(void)
{
int ret;
unsigned int cpu;
+
spin_lock_init(&cpufreq_stats_lock);
if ((ret = cpufreq_register_notifier(&notifier_policy_block,
CPUFREQ_POLICY_NOTIFIER)))
@@ -323,20 +350,31 @@ __init cpufreq_stats_init(void)
return ret;
}
- for_each_cpu(cpu)
- cpufreq_update_policy(cpu);
+ register_cpu_notifier(&cpufreq_stat_cpu_notifier);
+ lock_cpu_hotplug();
+ for_each_online_cpu(cpu) {
+ cpufreq_stat_cpu_callback(&cpufreq_stat_cpu_notifier, CPU_ONLINE,
+ (void *)(long)cpu);
+ }
+ unlock_cpu_hotplug();
return 0;
}
static void
__exit cpufreq_stats_exit(void)
{
unsigned int cpu;
+
cpufreq_unregister_notifier(&notifier_policy_block,
CPUFREQ_POLICY_NOTIFIER);
cpufreq_unregister_notifier(&notifier_trans_block,
CPUFREQ_TRANSITION_NOTIFIER);
- for_each_cpu(cpu)
- cpufreq_stats_free_table(cpu);
+ unregister_cpu_notifier(&cpufreq_stat_cpu_notifier);
+ lock_cpu_hotplug();
+ for_each_online_cpu(cpu) {
+ cpufreq_stat_cpu_callback(&cpufreq_stat_cpu_notifier, CPU_DEAD,
+ (void *)(long)cpu);
+ }
+ unlock_cpu_hotplug();
}
MODULE_AUTHOR ("Zou Nan hai <nanhai.zou@intel.com>");
diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig
index 094835cce321..4263935443cc 100644
--- a/drivers/crypto/Kconfig
+++ b/drivers/crypto/Kconfig
@@ -2,7 +2,7 @@ menu "Hardware crypto devices"
config CRYPTO_DEV_PADLOCK
tristate "Support for VIA PadLock ACE"
- depends on CRYPTO && X86 && !X86_64
+ depends on CRYPTO && X86_32
help
Some VIA processors come with an integrated crypto engine
(so called VIA PadLock ACE, Advanced Cryptography Engine)
diff --git a/drivers/dio/dio.c b/drivers/dio/dio.c
index a620f7d9ac8e..17502d6efae7 100644
--- a/drivers/dio/dio.c
+++ b/drivers/dio/dio.c
@@ -224,11 +224,10 @@ static int __init dio_init(void)
set_fs(fs);
/* Found a board, allocate it an entry in the list */
- dev = kmalloc(sizeof(struct dio_dev), GFP_KERNEL);
+ dev = kzalloc(sizeof(struct dio_dev), GFP_KERNEL);
if (!dev)
return 0;
- memset(dev, 0, sizeof(struct dio_dev));
dev->bus = &dio_bus;
dev->dev.parent = &dio_bus.dev;
dev->dev.bus = &dio_bus_type;
diff --git a/drivers/eisa/eisa-bus.c b/drivers/eisa/eisa-bus.c
index 1937743c8e29..4196137e66de 100644
--- a/drivers/eisa/eisa-bus.c
+++ b/drivers/eisa/eisa-bus.c
@@ -281,13 +281,11 @@ static int __init eisa_probe (struct eisa_root_device *root)
/* First try to get hold of slot 0. If there is no device
* here, simply fail, unless root->force_probe is set. */
- if (!(edev = kmalloc (sizeof (*edev), GFP_KERNEL))) {
+ if (!(edev = kzalloc (sizeof (*edev), GFP_KERNEL))) {
printk (KERN_ERR "EISA: Couldn't allocate mainboard slot\n");
return -ENOMEM;
}
- memset (edev, 0, sizeof (*edev));
-
if (eisa_request_resources (root, edev, 0)) {
printk (KERN_WARNING \
"EISA: Cannot allocate resource for mainboard\n");
@@ -317,13 +315,11 @@ static int __init eisa_probe (struct eisa_root_device *root)
force_probe:
for (c = 0, i = 1; i <= root->slots; i++) {
- if (!(edev = kmalloc (sizeof (*edev), GFP_KERNEL))) {
+ if (!(edev = kzalloc (sizeof (*edev), GFP_KERNEL))) {
printk (KERN_ERR "EISA: Out of memory for slot %d\n",
i);
continue;
}
-
- memset (edev, 0, sizeof (*edev));
if (eisa_request_resources (root, edev, i)) {
printk (KERN_WARNING \
diff --git a/drivers/eisa/virtual_root.c b/drivers/eisa/virtual_root.c
index 15677f20bd85..0f97a0cb0ff4 100644
--- a/drivers/eisa/virtual_root.c
+++ b/drivers/eisa/virtual_root.c
@@ -9,7 +9,7 @@
#include <linux/config.h>
#include <linux/kernel.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <linux/eisa.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
diff --git a/drivers/fc4/fc.c b/drivers/fc4/fc.c
index e4710d1d1f9d..5c8943509cc1 100644
--- a/drivers/fc4/fc.c
+++ b/drivers/fc4/fc.c
@@ -266,13 +266,12 @@ static void fcp_report_map_done(fc_channel *fc, int i, int status)
printk ("FC: Bad magic from REPORT_AL_MAP on %s - %08x\n", fc->name, p->magic);
fc->state = FC_STATE_OFFLINE;
} else {
- fc->posmap = (fcp_posmap *)kmalloc(sizeof(fcp_posmap)+p->len, GFP_KERNEL);
+ fc->posmap = (fcp_posmap *)kzalloc(sizeof(fcp_posmap)+p->len, GFP_KERNEL);
if (!fc->posmap) {
printk("FC: Not enough memory, offlining channel\n");
fc->state = FC_STATE_OFFLINE;
} else {
int k;
- memset(fc->posmap, 0, sizeof(fcp_posmap)+p->len);
/* FIXME: This is where SOCAL transfers our AL-PA.
Keep it here till we found out what other cards do... */
fc->sid = (p->magic & 0xff);
@@ -351,14 +350,12 @@ void fcp_register(fc_channel *fc, u8 type, int unregister)
fc->dma_scsi_rsp = fc->dma_scsi_cmd + slots * sizeof (fcp_cmd);
fc->scsi_bitmap_end = (slots + 63) & ~63;
size = fc->scsi_bitmap_end / 8;
- fc->scsi_bitmap = kmalloc (size, GFP_KERNEL);
- memset (fc->scsi_bitmap, 0, size);
+ fc->scsi_bitmap = kzalloc (size, GFP_KERNEL);
set_bit (0, fc->scsi_bitmap);
for (i = fc->can_queue; i < fc->scsi_bitmap_end; i++)
set_bit (i, fc->scsi_bitmap);
fc->scsi_free = fc->can_queue;
- fc->cmd_slots = (fcp_cmnd **)kmalloc(slots * sizeof(fcp_cmnd*), GFP_KERNEL);
- memset(fc->cmd_slots, 0, slots * sizeof(fcp_cmnd*));
+ fc->cmd_slots = (fcp_cmnd **)kzalloc(slots * sizeof(fcp_cmnd*), GFP_KERNEL);
fc->abort_count = 0;
} else {
fc->scsi_name[0] = 0;
@@ -541,12 +538,11 @@ int fcp_initialize(fc_channel *fcchain, int count)
FCND(("fcp_inititialize %08lx\n", (long)fcp_init))
FCND(("fc_channels %08lx\n", (long)fc_channels))
FCND((" SID %d DID %d\n", fcchain->sid, fcchain->did))
- l = kmalloc(sizeof (ls) + count, GFP_KERNEL);
+ l = kzalloc(sizeof (ls) + count, GFP_KERNEL);
if (!l) {
printk ("FC: Cannot allocate memory for initialization\n");
return -ENOMEM;
}
- memset (l, 0, sizeof(ls) + count);
l->magic = LSMAGIC;
l->count = count;
FCND(("FCP Init for %d channels\n", count))
@@ -555,17 +551,15 @@ int fcp_initialize(fc_channel *fcchain, int count)
l->timer.function = fcp_login_timeout;
l->timer.data = (unsigned long)l;
atomic_set (&l->todo, count);
- l->logi = kmalloc (count * 3 * sizeof(logi), GFP_KERNEL);
- l->fcmds = kmalloc (count * sizeof(fcp_cmnd), GFP_KERNEL);
+ l->logi = kzalloc (count * 3 * sizeof(logi), GFP_KERNEL);
+ l->fcmds = kzalloc (count * sizeof(fcp_cmnd), GFP_KERNEL);
if (!l->logi || !l->fcmds) {
- if (l->logi) kfree (l->logi);
- if (l->fcmds) kfree (l->fcmds);
+ kfree (l->logi);
+ kfree (l->fcmds);
kfree (l);
printk ("FC: Cannot allocate DMA memory for initialization\n");
return -ENOMEM;
}
- memset (l->logi, 0, count * 3 * sizeof(logi));
- memset (l->fcmds, 0, count * sizeof(fcp_cmnd));
for (fc = fcchain, i = 0; fc && i < count; fc = fc->next, i++) {
fc->state = FC_STATE_UNINITED;
fc->rst_pkt = NULL; /* kmalloc when first used */
@@ -678,13 +672,11 @@ int fcp_forceoffline(fc_channel *fcchain, int count)
l.timer.function = fcp_login_timeout;
l.timer.data = (unsigned long)&l;
atomic_set (&l.todo, count);
- l.fcmds = kmalloc (count * sizeof(fcp_cmnd), GFP_KERNEL);
+ l.fcmds = kzalloc (count * sizeof(fcp_cmnd), GFP_KERNEL);
if (!l.fcmds) {
- kfree (l.fcmds);
printk ("FC: Cannot allocate memory for forcing offline\n");
return -ENOMEM;
}
- memset (l.fcmds, 0, count * sizeof(fcp_cmnd));
FCND(("Initializing OFFLINE packets\n"))
for (fc = fcchain, i = 0; fc && i < count; fc = fc->next, i++) {
fc->state = FC_STATE_UNINITED;
@@ -1114,9 +1106,8 @@ int fc_do_plogi(fc_channel *fc, unsigned char alpa, fc_wwn *node, fc_wwn *nport)
logi *l;
int status;
- l = (logi *)kmalloc(2 * sizeof(logi), GFP_KERNEL);
+ l = (logi *)kzalloc(2 * sizeof(logi), GFP_KERNEL);
if (!l) return -ENOMEM;
- memset(l, 0, 2 * sizeof(logi));
l->code = LS_PLOGI;
memcpy (&l->nport_wwn, &fc->wwn_nport, sizeof(fc_wwn));
memcpy (&l->node_wwn, &fc->wwn_node, sizeof(fc_wwn));
@@ -1149,9 +1140,8 @@ int fc_do_prli(fc_channel *fc, unsigned char alpa)
prli *p;
int status;
- p = (prli *)kmalloc(2 * sizeof(prli), GFP_KERNEL);
+ p = (prli *)kzalloc(2 * sizeof(prli), GFP_KERNEL);
if (!p) return -ENOMEM;
- memset(p, 0, 2 * sizeof(prli));
p->code = LS_PRLI;
p->params[0] = 0x08002000;
p->params[3] = 0x00000022;
diff --git a/drivers/fc4/soc.c b/drivers/fc4/soc.c
index 247b46302777..ec1f94738c59 100644
--- a/drivers/fc4/soc.c
+++ b/drivers/fc4/soc.c
@@ -556,10 +556,9 @@ static inline void soc_init(struct sbus_dev *sdev, int no)
int size, i;
int irq;
- s = kmalloc (sizeof (struct soc), GFP_KERNEL);
+ s = kzalloc (sizeof (struct soc), GFP_KERNEL);
if (s == NULL)
return;
- memset (s, 0, sizeof(struct soc));
spin_lock_init(&s->lock);
s->soc_no = no;
diff --git a/drivers/fc4/socal.c b/drivers/fc4/socal.c
index b2377dbd84a1..922e9613b2cf 100644
--- a/drivers/fc4/socal.c
+++ b/drivers/fc4/socal.c
@@ -665,9 +665,8 @@ static inline void socal_init(struct sbus_dev *sdev, int no)
int size, i;
int irq, node;
- s = kmalloc (sizeof (struct socal), GFP_KERNEL);
+ s = kzalloc (sizeof (struct socal), GFP_KERNEL);
if (!s) return;
- memset (s, 0, sizeof(struct socal));
spin_lock_init(&s->lock);
s->socal_no = no;
diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig
index 327b58e64875..b6815c6c29a2 100644
--- a/drivers/firmware/Kconfig
+++ b/drivers/firmware/Kconfig
@@ -70,8 +70,7 @@ config DELL_RBU
config DCDBAS
tristate "Dell Systems Management Base Driver"
- depends on X86 || X86_64
- default m
+ depends on X86
help
The Dell Systems Management Base Driver provides a sysfs interface
for systems management software to perform System Management
diff --git a/drivers/firmware/dcdbas.c b/drivers/firmware/dcdbas.c
index 955537fe9958..8ed6ddbb9c5d 100644
--- a/drivers/firmware/dcdbas.c
+++ b/drivers/firmware/dcdbas.c
@@ -20,7 +20,7 @@
* GNU General Public License for more details.
*/
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
#include <linux/errno.h>
#include <linux/init.h>
diff --git a/drivers/firmware/dell_rbu.c b/drivers/firmware/dell_rbu.c
index 4f4ba9b6d182..6d83299e7c9b 100644
--- a/drivers/firmware/dell_rbu.c
+++ b/drivers/firmware/dell_rbu.c
@@ -34,14 +34,13 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
-#include <linux/version.h>
#include <linux/config.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/string.h>
#include <linux/errno.h>
#include <linux/blkdev.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <linux/spinlock.h>
#include <linux/moduleparam.h>
#include <linux/firmware.h>
@@ -50,7 +49,7 @@
MODULE_AUTHOR("Abhay Salunke <abhay_salunke@dell.com>");
MODULE_DESCRIPTION("Driver for updating BIOS image on DELL systems");
MODULE_LICENSE("GPL");
-MODULE_VERSION("3.0");
+MODULE_VERSION("3.1");
#define BIOS_SCAN_LIMIT 0xffffffff
#define MAX_IMAGE_LENGTH 16
@@ -73,6 +72,11 @@ module_param_string(image_type, image_type, sizeof (image_type), 0);
MODULE_PARM_DESC(image_type,
"BIOS image type. choose- mono or packet or init");
+static unsigned long allocation_floor = 0x100000;
+module_param(allocation_floor, ulong, 0644);
+MODULE_PARM_DESC(allocation_floor,
+ "Minimum address for allocations when using Packet mode");
+
struct packet_data {
struct list_head list;
size_t length;
@@ -99,61 +103,122 @@ static int create_packet(void *data, size_t length)
{
struct packet_data *newpacket;
int ordernum = 0;
+ int retval = 0;
+ unsigned int packet_array_size = 0;
+ void **invalid_addr_packet_array = 0;
+ void *packet_data_temp_buf = 0;
+ unsigned int idx = 0;
pr_debug("create_packet: entry \n");
if (!rbu_data.packetsize) {
pr_debug("create_packet: packetsize not specified\n");
- return -EINVAL;
+ retval = -EINVAL;
+ goto out_noalloc;
}
+
spin_unlock(&rbu_data.lock);
- newpacket = kmalloc(sizeof (struct packet_data), GFP_KERNEL);
- spin_lock(&rbu_data.lock);
+
+ newpacket = kzalloc(sizeof (struct packet_data), GFP_KERNEL);
if (!newpacket) {
printk(KERN_WARNING
"dell_rbu:%s: failed to allocate new "
"packet\n", __FUNCTION__);
- return -ENOMEM;
+ retval = -ENOMEM;
+ spin_lock(&rbu_data.lock);
+ goto out_noalloc;
}
ordernum = get_order(length);
+
/*
- * there is no upper limit on memory
- * address for packetized mechanism
+ * BIOS errata mean we cannot allocate packets below 1MB or they will
+ * be overwritten by BIOS.
+ *
+ * array to temporarily hold packets
+ * that are below the allocation floor
+ *
+ * NOTE: very simplistic because we only need the floor to be at 1MB
+ * due to BIOS errata. This shouldn't be used for higher floors
+ * or you will run out of mem trying to allocate the array.
*/
- spin_unlock(&rbu_data.lock);
- newpacket->data = (unsigned char *) __get_free_pages(GFP_KERNEL,
- ordernum);
- spin_lock(&rbu_data.lock);
+ packet_array_size = max(
+ (unsigned int)(allocation_floor / rbu_data.packetsize),
+ (unsigned int)1);
+ invalid_addr_packet_array = kzalloc(packet_array_size * sizeof(void*),
+ GFP_KERNEL);
- pr_debug("create_packet: newpacket %p\n", newpacket->data);
-
- if (!newpacket->data) {
+ if (!invalid_addr_packet_array) {
printk(KERN_WARNING
- "dell_rbu:%s: failed to allocate new "
- "packet\n", __FUNCTION__);
- kfree(newpacket);
- return -ENOMEM;
+ "dell_rbu:%s: failed to allocate "
+ "invalid_addr_packet_array \n",
+ __FUNCTION__);
+ retval = -ENOMEM;
+ spin_lock(&rbu_data.lock);
+ goto out_alloc_packet;
}
+ while (!packet_data_temp_buf) {
+ packet_data_temp_buf = (unsigned char *)
+ __get_free_pages(GFP_KERNEL, ordernum);
+ if (!packet_data_temp_buf) {
+ printk(KERN_WARNING
+ "dell_rbu:%s: failed to allocate new "
+ "packet\n", __FUNCTION__);
+ retval = -ENOMEM;
+ spin_lock(&rbu_data.lock);
+ goto out_alloc_packet_array;
+ }
+
+ if ((unsigned long)virt_to_phys(packet_data_temp_buf)
+ < allocation_floor) {
+ pr_debug("packet 0x%lx below floor at 0x%lx.\n",
+ (unsigned long)virt_to_phys(
+ packet_data_temp_buf),
+ allocation_floor);
+ invalid_addr_packet_array[idx++] = packet_data_temp_buf;
+ packet_data_temp_buf = 0;
+ }
+ }
+ spin_lock(&rbu_data.lock);
+
+ newpacket->data = packet_data_temp_buf;
+
+ pr_debug("create_packet: newpacket at physical addr %lx\n",
+ (unsigned long)virt_to_phys(newpacket->data));
+
+ /* packets may not have fixed size */
+ newpacket->length = length;
newpacket->ordernum = ordernum;
++rbu_data.num_packets;
- /*
- * initialize the newly created packet headers
- */
+
+ /* initialize the newly created packet headers */
INIT_LIST_HEAD(&newpacket->list);
list_add_tail(&newpacket->list, &packet_data_head.list);
- /*
- * packets may not have fixed size
- */
- newpacket->length = length;
memcpy(newpacket->data, data, length);
pr_debug("create_packet: exit \n");
- return 0;
+out_alloc_packet_array:
+ /* always free packet array */
+ for (;idx>0;idx--) {
+ pr_debug("freeing unused packet below floor 0x%lx.\n",
+ (unsigned long)virt_to_phys(
+ invalid_addr_packet_array[idx-1]));
+ free_pages((unsigned long)invalid_addr_packet_array[idx-1],
+ ordernum);
+ }
+ kfree(invalid_addr_packet_array);
+
+out_alloc_packet:
+ /* if error, free data */
+ if (retval)
+ kfree(newpacket);
+
+out_noalloc:
+ return retval;
}
static int packetize_data(void *data, size_t length)
@@ -693,3 +758,6 @@ static __exit void dcdrbu_exit(void)
module_exit(dcdrbu_exit);
module_init(dcdrbu_init);
+
+/* vim:noet:ts=8:sw=8
+*/
diff --git a/drivers/firmware/edd.c b/drivers/firmware/edd.c
index 6996476669f1..b4502ed65793 100644
--- a/drivers/firmware/edd.c
+++ b/drivers/firmware/edd.c
@@ -715,7 +715,6 @@ edd_device_register(struct edd_device *edev, int i)
if (!edev)
return 1;
- memset(edev, 0, sizeof (*edev));
edd_dev_set_info(edev, i);
kobject_set_name(&edev->kobj, "int13_dev%02x",
0x80 + i);
@@ -756,7 +755,7 @@ edd_init(void)
return rc;
for (i = 0; i < edd_num_devices() && !rc; i++) {
- edev = kmalloc(sizeof (*edev), GFP_KERNEL);
+ edev = kzalloc(sizeof (*edev), GFP_KERNEL);
if (!edev)
return -ENOMEM;
diff --git a/drivers/firmware/efivars.c b/drivers/firmware/efivars.c
index 33b17c6a46fb..bda5bce681b6 100644
--- a/drivers/firmware/efivars.c
+++ b/drivers/firmware/efivars.c
@@ -614,16 +614,14 @@ efivar_create_sysfs_entry(unsigned long variable_name_size,
char *short_name;
struct efivar_entry *new_efivar;
- short_name = kmalloc(short_name_size + 1, GFP_KERNEL);
- new_efivar = kmalloc(sizeof(struct efivar_entry), GFP_KERNEL);
+ short_name = kzalloc(short_name_size + 1, GFP_KERNEL);
+ new_efivar = kzalloc(sizeof(struct efivar_entry), GFP_KERNEL);
if (!short_name || !new_efivar) {
kfree(short_name);
kfree(new_efivar);
return 1;
}
- memset(short_name, 0, short_name_size+1);
- memset(new_efivar, 0, sizeof(struct efivar_entry));
memcpy(new_efivar->var.VariableName, variable_name,
variable_name_size);
@@ -674,14 +672,12 @@ efivars_init(void)
if (!efi_enabled)
return -ENODEV;
- variable_name = kmalloc(variable_name_size, GFP_KERNEL);
+ variable_name = kzalloc(variable_name_size, GFP_KERNEL);
if (!variable_name) {
printk(KERN_ERR "efivars: Memory allocation failed.\n");
return -ENOMEM;
}
- memset(variable_name, 0, variable_name_size);
-
printk(KERN_INFO "EFI Variables Facility v%s %s\n", EFIVARS_VERSION,
EFIVARS_DATE);
diff --git a/drivers/hwmon/adm1021.c b/drivers/hwmon/adm1021.c
index e928cdb041cb..8102876c7c3f 100644
--- a/drivers/hwmon/adm1021.c
+++ b/drivers/hwmon/adm1021.c
@@ -121,7 +121,7 @@ static int adm1021_write_value(struct i2c_client *client, u8 reg,
static struct adm1021_data *adm1021_update_device(struct device *dev);
/* (amalysh) read only mode, otherwise any limit's writing confuse BIOS */
-static int read_only = 0;
+static int read_only;
/* This is the driver that will be inserted */
@@ -204,11 +204,10 @@ static int adm1021_detect(struct i2c_adapter *adapter, int address, int kind)
client structure, even though we cannot fill it completely yet.
But it allows us to access adm1021_{read,write}_value. */
- if (!(data = kmalloc(sizeof(struct adm1021_data), GFP_KERNEL))) {
+ if (!(data = kzalloc(sizeof(struct adm1021_data), GFP_KERNEL))) {
err = -ENOMEM;
goto error0;
}
- memset(data, 0, sizeof(struct adm1021_data));
new_client = &data->client;
i2c_set_clientdata(new_client, data);
diff --git a/drivers/hwmon/adm1025.c b/drivers/hwmon/adm1025.c
index 526b7ff179eb..3ec12421694f 100644
--- a/drivers/hwmon/adm1025.c
+++ b/drivers/hwmon/adm1025.c
@@ -331,11 +331,10 @@ static int adm1025_detect(struct i2c_adapter *adapter, int address, int kind)
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
goto exit;
- if (!(data = kmalloc(sizeof(struct adm1025_data), GFP_KERNEL))) {
+ if (!(data = kzalloc(sizeof(struct adm1025_data), GFP_KERNEL))) {
err = -ENOMEM;
goto exit;
}
- memset(data, 0, sizeof(struct adm1025_data));
/* The common I2C client data is placed right before the
ADM1025-specific data. */
diff --git a/drivers/hwmon/adm1026.c b/drivers/hwmon/adm1026.c
index 625158110fd4..e0f56549d1d8 100644
--- a/drivers/hwmon/adm1026.c
+++ b/drivers/hwmon/adm1026.c
@@ -315,7 +315,7 @@ static struct i2c_driver adm1026_driver = {
.detach_client = adm1026_detach_client,
};
-int adm1026_attach_adapter(struct i2c_adapter *adapter)
+static int adm1026_attach_adapter(struct i2c_adapter *adapter)
{
if (!(adapter->class & I2C_CLASS_HWMON)) {
return 0;
@@ -323,7 +323,7 @@ int adm1026_attach_adapter(struct i2c_adapter *adapter)
return i2c_probe(adapter, &addr_data, adm1026_detect);
}
-int adm1026_detach_client(struct i2c_client *client)
+static int adm1026_detach_client(struct i2c_client *client)
{
struct adm1026_data *data = i2c_get_clientdata(client);
hwmon_device_unregister(data->class_dev);
@@ -332,7 +332,7 @@ int adm1026_detach_client(struct i2c_client *client)
return 0;
}
-int adm1026_read_value(struct i2c_client *client, u8 reg)
+static int adm1026_read_value(struct i2c_client *client, u8 reg)
{
int res;
@@ -346,7 +346,7 @@ int adm1026_read_value(struct i2c_client *client, u8 reg)
return res;
}
-int adm1026_write_value(struct i2c_client *client, u8 reg, int value)
+static int adm1026_write_value(struct i2c_client *client, u8 reg, int value)
{
int res;
@@ -360,7 +360,7 @@ int adm1026_write_value(struct i2c_client *client, u8 reg, int value)
return res;
}
-void adm1026_init_client(struct i2c_client *client)
+static void adm1026_init_client(struct i2c_client *client)
{
int value, i;
struct adm1026_data *data = i2c_get_clientdata(client);
@@ -460,7 +460,7 @@ void adm1026_init_client(struct i2c_client *client)
}
}
-void adm1026_print_gpio(struct i2c_client *client)
+static void adm1026_print_gpio(struct i2c_client *client)
{
struct adm1026_data *data = i2c_get_clientdata(client);
int i;
@@ -492,7 +492,7 @@ void adm1026_print_gpio(struct i2c_client *client)
}
}
-void adm1026_fixup_gpio(struct i2c_client *client)
+static void adm1026_fixup_gpio(struct i2c_client *client)
{
struct adm1026_data *data = i2c_get_clientdata(client);
int i;
@@ -1452,8 +1452,8 @@ static DEVICE_ATTR(temp1_auto_point2_pwm, S_IRUGO, show_auto_pwm_max, NULL);
static DEVICE_ATTR(temp2_auto_point2_pwm, S_IRUGO, show_auto_pwm_max, NULL);
static DEVICE_ATTR(temp3_auto_point2_pwm, S_IRUGO, show_auto_pwm_max, NULL);
-int adm1026_detect(struct i2c_adapter *adapter, int address,
- int kind)
+static int adm1026_detect(struct i2c_adapter *adapter, int address,
+ int kind)
{
int company, verstep;
struct i2c_client *new_client;
@@ -1470,13 +1470,11 @@ int adm1026_detect(struct i2c_adapter *adapter, int address,
client structure, even though we cannot fill it completely yet.
But it allows us to access adm1026_{read,write}_value. */
- if (!(data = kmalloc(sizeof(struct adm1026_data), GFP_KERNEL))) {
+ if (!(data = kzalloc(sizeof(struct adm1026_data), GFP_KERNEL))) {
err = -ENOMEM;
goto exit;
}
- memset(data, 0, sizeof(struct adm1026_data));
-
new_client = &data->client;
i2c_set_clientdata(new_client, data);
new_client->addr = address;
diff --git a/drivers/hwmon/adm1031.c b/drivers/hwmon/adm1031.c
index 58338ed7c8a1..7c545d5eee45 100644
--- a/drivers/hwmon/adm1031.c
+++ b/drivers/hwmon/adm1031.c
@@ -740,11 +740,10 @@ static int adm1031_detect(struct i2c_adapter *adapter, int address, int kind)
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
goto exit;
- if (!(data = kmalloc(sizeof(struct adm1031_data), GFP_KERNEL))) {
+ if (!(data = kzalloc(sizeof(struct adm1031_data), GFP_KERNEL))) {
err = -ENOMEM;
goto exit;
}
- memset(data, 0, sizeof(struct adm1031_data));
new_client = &data->client;
i2c_set_clientdata(new_client, data);
diff --git a/drivers/hwmon/adm9240.c b/drivers/hwmon/adm9240.c
index bc7faef162f7..11dc95f8a17e 100644
--- a/drivers/hwmon/adm9240.c
+++ b/drivers/hwmon/adm9240.c
@@ -45,6 +45,7 @@
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/i2c.h>
+#include <linux/hwmon-sysfs.h>
#include <linux/hwmon.h>
#include <linux/hwmon-vid.h>
#include <linux/err.h>
@@ -69,8 +70,7 @@ I2C_CLIENT_INSMOD_3(adm9240, ds1780, lm81);
#define ADM9240_REG_INT(nr) (0x41 + (nr))
#define ADM9240_REG_INT_MASK(nr) (0x43 + (nr))
#define ADM9240_REG_TEMP 0x27
-#define ADM9240_REG_TEMP_HIGH 0x39
-#define ADM9240_REG_TEMP_HYST 0x3a
+#define ADM9240_REG_TEMP_MAX(nr) (0x39 + (nr)) /* 0, 1 = high, hyst */
#define ADM9240_REG_ANALOG_OUT 0x19
#define ADM9240_REG_CHASSIS_CLEAR 0x46
#define ADM9240_REG_VID_FAN_DIV 0x47
@@ -162,177 +162,155 @@ struct adm9240_data {
u8 fan_min[2]; /* rw fan1_min */
u8 fan_div[2]; /* rw fan1_div, read-only accessor */
s16 temp; /* ro temp1_input, 9-bit sign-extended */
- s8 temp_high; /* rw temp1_max */
- s8 temp_hyst; /* rw temp1_max_hyst */
+ s8 temp_max[2]; /* rw 0 -> temp_max, 1 -> temp_max_hyst */
u16 alarms; /* ro alarms */
u8 aout; /* rw aout_output */
u8 vid; /* ro vid */
u8 vrm; /* -- vrm set on startup, no accessor */
};
-/* i2c byte read/write interface */
-static int adm9240_read_value(struct i2c_client *client, u8 reg)
+/*** sysfs accessors ***/
+
+/* temperature */
+static ssize_t show_temp(struct device *dev, struct device_attribute *dummy,
+ char *buf)
{
- return i2c_smbus_read_byte_data(client, reg);
+ struct adm9240_data *data = adm9240_update_device(dev);
+ return sprintf(buf, "%d\n", data->temp * 500); /* 9-bit value */
}
-static int adm9240_write_value(struct i2c_client *client, u8 reg, u8 value)
+static ssize_t show_max(struct device *dev, struct device_attribute *devattr,
+ char *buf)
{
- return i2c_smbus_write_byte_data(client, reg, value);
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+ struct adm9240_data *data = adm9240_update_device(dev);
+ return sprintf(buf, "%d\n", data->temp_max[attr->index] * 1000);
}
-/*** sysfs accessors ***/
+static ssize_t set_max(struct device *dev, struct device_attribute *devattr,
+ const char *buf, size_t count)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+ struct i2c_client *client = to_i2c_client(dev);
+ struct adm9240_data *data = i2c_get_clientdata(client);
+ long val = simple_strtol(buf, NULL, 10);
+
+ down(&data->update_lock);
+ data->temp_max[attr->index] = TEMP_TO_REG(val);
+ i2c_smbus_write_byte_data(client, ADM9240_REG_TEMP_MAX(attr->index),
+ data->temp_max[attr->index]);
+ up(&data->update_lock);
+ return count;
+}
-/* temperature */
-#define show_temp(value, scale) \
-static ssize_t show_##value(struct device *dev, \
- struct device_attribute *attr, \
- char *buf) \
-{ \
- struct adm9240_data *data = adm9240_update_device(dev); \
- return sprintf(buf, "%d\n", data->value * scale); \
-}
-show_temp(temp_high, 1000);
-show_temp(temp_hyst, 1000);
-show_temp(temp, 500); /* 0.5'C per bit */
-
-#define set_temp(value, reg) \
-static ssize_t set_##value(struct device *dev, \
- struct device_attribute *attr, \
- const char *buf, size_t count) \
-{ \
- struct i2c_client *client = to_i2c_client(dev); \
- struct adm9240_data *data = adm9240_update_device(dev); \
- long temp = simple_strtoul(buf, NULL, 10); \
- \
- down(&data->update_lock); \
- data->value = TEMP_TO_REG(temp); \
- adm9240_write_value(client, reg, data->value); \
- up(&data->update_lock); \
- return count; \
-}
-
-set_temp(temp_high, ADM9240_REG_TEMP_HIGH);
-set_temp(temp_hyst, ADM9240_REG_TEMP_HYST);
-
-static DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO,
- show_temp_high, set_temp_high);
-static DEVICE_ATTR(temp1_max_hyst, S_IWUSR | S_IRUGO,
- show_temp_hyst, set_temp_hyst);
static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL);
+static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO,
+ show_max, set_max, 0);
+static SENSOR_DEVICE_ATTR(temp1_max_hyst, S_IWUSR | S_IRUGO,
+ show_max, set_max, 1);
/* voltage */
-static ssize_t show_in(struct device *dev, char *buf, int nr)
+static ssize_t show_in(struct device *dev, struct device_attribute *devattr,
+ char *buf)
{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
struct adm9240_data *data = adm9240_update_device(dev);
- return sprintf(buf, "%d\n", IN_FROM_REG(data->in[nr], nr));
+ return sprintf(buf, "%d\n", IN_FROM_REG(data->in[attr->index],
+ attr->index));
}
-static ssize_t show_in_min(struct device *dev, char *buf, int nr)
+static ssize_t show_in_min(struct device *dev,
+ struct device_attribute *devattr, char *buf)
{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
struct adm9240_data *data = adm9240_update_device(dev);
- return sprintf(buf, "%d\n", IN_FROM_REG(data->in_min[nr], nr));
+ return sprintf(buf, "%d\n", IN_FROM_REG(data->in_min[attr->index],
+ attr->index));
}
-static ssize_t show_in_max(struct device *dev, char *buf, int nr)
+static ssize_t show_in_max(struct device *dev,
+ struct device_attribute *devattr, char *buf)
{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
struct adm9240_data *data = adm9240_update_device(dev);
- return sprintf(buf, "%d\n", IN_FROM_REG(data->in_max[nr], nr));
+ return sprintf(buf, "%d\n", IN_FROM_REG(data->in_max[attr->index],
+ attr->index));
}
-static ssize_t set_in_min(struct device *dev, const char *buf,
- size_t count, int nr)
+static ssize_t set_in_min(struct device *dev,
+ struct device_attribute *devattr,
+ const char *buf, size_t count)
{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
struct i2c_client *client = to_i2c_client(dev);
struct adm9240_data *data = i2c_get_clientdata(client);
unsigned long val = simple_strtoul(buf, NULL, 10);
down(&data->update_lock);
- data->in_min[nr] = IN_TO_REG(val, nr);
- adm9240_write_value(client, ADM9240_REG_IN_MIN(nr), data->in_min[nr]);
+ data->in_min[attr->index] = IN_TO_REG(val, attr->index);
+ i2c_smbus_write_byte_data(client, ADM9240_REG_IN_MIN(attr->index),
+ data->in_min[attr->index]);
up(&data->update_lock);
return count;
}
-static ssize_t set_in_max(struct device *dev, const char *buf,
- size_t count, int nr)
+static ssize_t set_in_max(struct device *dev,
+ struct device_attribute *devattr,
+ const char *buf, size_t count)
{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
struct i2c_client *client = to_i2c_client(dev);
struct adm9240_data *data = i2c_get_clientdata(client);
unsigned long val = simple_strtoul(buf, NULL, 10);
down(&data->update_lock);
- data->in_max[nr] = IN_TO_REG(val, nr);
- adm9240_write_value(client, ADM9240_REG_IN_MAX(nr), data->in_max[nr]);
+ data->in_max[attr->index] = IN_TO_REG(val, attr->index);
+ i2c_smbus_write_byte_data(client, ADM9240_REG_IN_MAX(attr->index),
+ data->in_max[attr->index]);
up(&data->update_lock);
return count;
}
-#define show_in_offset(offset) \
-static ssize_t show_in##offset(struct device *dev, \
- struct device_attribute *attr, \
- char *buf) \
-{ \
- return show_in(dev, buf, offset); \
-} \
-static DEVICE_ATTR(in##offset##_input, S_IRUGO, show_in##offset, NULL); \
-static ssize_t show_in##offset##_min(struct device *dev, \
- struct device_attribute *attr, \
- char *buf) \
-{ \
- return show_in_min(dev, buf, offset); \
-} \
-static ssize_t show_in##offset##_max(struct device *dev, \
- struct device_attribute *attr, \
- char *buf) \
-{ \
- return show_in_max(dev, buf, offset); \
-} \
-static ssize_t \
-set_in##offset##_min(struct device *dev, \
- struct device_attribute *attr, const char *buf, \
- size_t count) \
-{ \
- return set_in_min(dev, buf, count, offset); \
-} \
-static ssize_t \
-set_in##offset##_max(struct device *dev, \
- struct device_attribute *attr, const char *buf, \
- size_t count) \
-{ \
- return set_in_max(dev, buf, count, offset); \
-} \
-static DEVICE_ATTR(in##offset##_min, S_IRUGO | S_IWUSR, \
- show_in##offset##_min, set_in##offset##_min); \
-static DEVICE_ATTR(in##offset##_max, S_IRUGO | S_IWUSR, \
- show_in##offset##_max, set_in##offset##_max);
-
-show_in_offset(0);
-show_in_offset(1);
-show_in_offset(2);
-show_in_offset(3);
-show_in_offset(4);
-show_in_offset(5);
+#define vin(nr) \
+static SENSOR_DEVICE_ATTR(in##nr##_input, S_IRUGO, \
+ show_in, NULL, nr); \
+static SENSOR_DEVICE_ATTR(in##nr##_min, S_IRUGO | S_IWUSR, \
+ show_in_min, set_in_min, nr); \
+static SENSOR_DEVICE_ATTR(in##nr##_max, S_IRUGO | S_IWUSR, \
+ show_in_max, set_in_max, nr);
+
+vin(0);
+vin(1);
+vin(2);
+vin(3);
+vin(4);
+vin(5);
/* fans */
-static ssize_t show_fan(struct device *dev, char *buf, int nr)
+static ssize_t show_fan(struct device *dev,
+ struct device_attribute *devattr, char *buf)
{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
struct adm9240_data *data = adm9240_update_device(dev);
- return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan[nr],
- 1 << data->fan_div[nr]));
+ return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan[attr->index],
+ 1 << data->fan_div[attr->index]));
}
-static ssize_t show_fan_min(struct device *dev, char *buf, int nr)
+static ssize_t show_fan_min(struct device *dev,
+ struct device_attribute *devattr, char *buf)
{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
struct adm9240_data *data = adm9240_update_device(dev);
- return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan_min[nr],
- 1 << data->fan_div[nr]));
+ return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan_min[attr->index],
+ 1 << data->fan_div[attr->index]));
}
-static ssize_t show_fan_div(struct device *dev, char *buf, int nr)
+static ssize_t show_fan_div(struct device *dev,
+ struct device_attribute *devattr, char *buf)
{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
struct adm9240_data *data = adm9240_update_device(dev);
- return sprintf(buf, "%d\n", 1 << data->fan_div[nr]);
+ return sprintf(buf, "%d\n", 1 << data->fan_div[attr->index]);
}
/* write new fan div, callers must hold data->update_lock */
@@ -341,16 +319,16 @@ static void adm9240_write_fan_div(struct i2c_client *client, int nr,
{
u8 reg, old, shift = (nr + 2) * 2;
- reg = adm9240_read_value(client, ADM9240_REG_VID_FAN_DIV);
+ reg = i2c_smbus_read_byte_data(client, ADM9240_REG_VID_FAN_DIV);
old = (reg >> shift) & 3;
reg &= ~(3 << shift);
reg |= (fan_div << shift);
- adm9240_write_value(client, ADM9240_REG_VID_FAN_DIV, reg);
+ i2c_smbus_write_byte_data(client, ADM9240_REG_VID_FAN_DIV, reg);
dev_dbg(&client->dev, "fan%d clock divider changed from %u "
"to %u\n", nr + 1, 1 << old, 1 << fan_div);
}
-/*
+/*
* set fan speed low limit:
*
* - value is zero: disable fan speed low limit alarm
@@ -361,12 +339,15 @@ static void adm9240_write_fan_div(struct i2c_client *client, int nr,
* - otherwise: select fan clock divider to suit fan speed low limit,
* measurement code may adjust registers to ensure fan speed reading
*/
-static ssize_t set_fan_min(struct device *dev, const char *buf,
- size_t count, int nr)
+static ssize_t set_fan_min(struct device *dev,
+ struct device_attribute *devattr,
+ const char *buf, size_t count)
{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
struct i2c_client *client = to_i2c_client(dev);
struct adm9240_data *data = i2c_get_clientdata(client);
unsigned long val = simple_strtoul(buf, NULL, 10);
+ int nr = attr->index;
u8 new_div;
down(&data->update_lock);
@@ -406,50 +387,27 @@ static ssize_t set_fan_min(struct device *dev, const char *buf,
data->fan_div[nr] = new_div;
adm9240_write_fan_div(client, nr, new_div);
}
- adm9240_write_value(client, ADM9240_REG_FAN_MIN(nr),
+ i2c_smbus_write_byte_data(client, ADM9240_REG_FAN_MIN(nr),
data->fan_min[nr]);
up(&data->update_lock);
return count;
}
-#define show_fan_offset(offset) \
-static ssize_t show_fan_##offset (struct device *dev, \
- struct device_attribute *attr, \
- char *buf) \
-{ \
-return show_fan(dev, buf, offset - 1); \
-} \
-static ssize_t show_fan_##offset##_div (struct device *dev, \
- struct device_attribute *attr, \
- char *buf) \
-{ \
-return show_fan_div(dev, buf, offset - 1); \
-} \
-static ssize_t show_fan_##offset##_min (struct device *dev, \
- struct device_attribute *attr, \
- char *buf) \
-{ \
-return show_fan_min(dev, buf, offset - 1); \
-} \
-static ssize_t set_fan_##offset##_min (struct device *dev, \
- struct device_attribute *attr, \
- const char *buf, size_t count) \
-{ \
-return set_fan_min(dev, buf, count, offset - 1); \
-} \
-static DEVICE_ATTR(fan##offset##_input, S_IRUGO, \
- show_fan_##offset, NULL); \
-static DEVICE_ATTR(fan##offset##_div, S_IRUGO, \
- show_fan_##offset##_div, NULL); \
-static DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \
- show_fan_##offset##_min, set_fan_##offset##_min);
-
-show_fan_offset(1);
-show_fan_offset(2);
+#define fan(nr) \
+static SENSOR_DEVICE_ATTR(fan##nr##_input, S_IRUGO, \
+ show_fan, NULL, nr - 1); \
+static SENSOR_DEVICE_ATTR(fan##nr##_div, S_IRUGO, \
+ show_fan_div, NULL, nr - 1); \
+static SENSOR_DEVICE_ATTR(fan##nr##_min, S_IRUGO | S_IWUSR, \
+ show_fan_min, set_fan_min, nr - 1);
+
+fan(1);
+fan(2);
/* alarms */
-static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t show_alarms(struct device *dev,
+ struct device_attribute *attr, char *buf)
{
struct adm9240_data *data = adm9240_update_device(dev);
return sprintf(buf, "%u\n", data->alarms);
@@ -457,7 +415,8 @@ static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, ch
static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);
/* vid */
-static ssize_t show_vid(struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t show_vid(struct device *dev,
+ struct device_attribute *attr, char *buf)
{
struct adm9240_data *data = adm9240_update_device(dev);
return sprintf(buf, "%d\n", vid_from_reg(data->vid, data->vrm));
@@ -465,13 +424,16 @@ static ssize_t show_vid(struct device *dev, struct device_attribute *attr, char
static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid, NULL);
/* analog output */
-static ssize_t show_aout(struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t show_aout(struct device *dev,
+ struct device_attribute *attr, char *buf)
{
struct adm9240_data *data = adm9240_update_device(dev);
return sprintf(buf, "%d\n", AOUT_FROM_REG(data->aout));
}
-static ssize_t set_aout(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+static ssize_t set_aout(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
{
struct i2c_client *client = to_i2c_client(dev);
struct adm9240_data *data = i2c_get_clientdata(client);
@@ -479,20 +441,23 @@ static ssize_t set_aout(struct device *dev, struct device_attribute *attr, const
down(&data->update_lock);
data->aout = AOUT_TO_REG(val);
- adm9240_write_value(client, ADM9240_REG_ANALOG_OUT, data->aout);
+ i2c_smbus_write_byte_data(client, ADM9240_REG_ANALOG_OUT, data->aout);
up(&data->update_lock);
return count;
}
static DEVICE_ATTR(aout_output, S_IRUGO | S_IWUSR, show_aout, set_aout);
/* chassis_clear */
-static ssize_t chassis_clear(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+static ssize_t chassis_clear(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
{
struct i2c_client *client = to_i2c_client(dev);
unsigned long val = simple_strtol(buf, NULL, 10);
if (val == 1) {
- adm9240_write_value(client, ADM9240_REG_CHASSIS_CLEAR, 0x80);
+ i2c_smbus_write_byte_data(client,
+ ADM9240_REG_CHASSIS_CLEAR, 0x80);
dev_dbg(&client->dev, "chassis intrusion latch cleared\n");
}
return count;
@@ -513,11 +478,10 @@ static int adm9240_detect(struct i2c_adapter *adapter, int address, int kind)
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
goto exit;
- if (!(data = kmalloc(sizeof(struct adm9240_data), GFP_KERNEL))) {
+ if (!(data = kzalloc(sizeof(*data), GFP_KERNEL))) {
err = -ENOMEM;
goto exit;
}
- memset(data, 0, sizeof(struct adm9240_data));
new_client = &data->client;
i2c_set_clientdata(new_client, data);
@@ -533,7 +497,7 @@ static int adm9240_detect(struct i2c_adapter *adapter, int address, int kind)
if (kind < 0) {
/* verify chip: reg address should match i2c address */
- if (adm9240_read_value(new_client, ADM9240_REG_I2C_ADDR)
+ if (i2c_smbus_read_byte_data(new_client, ADM9240_REG_I2C_ADDR)
!= address) {
dev_err(&adapter->dev, "detect fail: address match, "
"0x%02x\n", address);
@@ -541,8 +505,8 @@ static int adm9240_detect(struct i2c_adapter *adapter, int address, int kind)
}
/* check known chip manufacturer */
- man_id = adm9240_read_value(new_client, ADM9240_REG_MAN_ID);
-
+ man_id = i2c_smbus_read_byte_data(new_client,
+ ADM9240_REG_MAN_ID);
if (man_id == 0x23) {
kind = adm9240;
} else if (man_id == 0xda) {
@@ -556,7 +520,8 @@ static int adm9240_detect(struct i2c_adapter *adapter, int address, int kind)
}
/* successful detect, print chip info */
- die_rev = adm9240_read_value(new_client, ADM9240_REG_DIE_REV);
+ die_rev = i2c_smbus_read_byte_data(new_client,
+ ADM9240_REG_DIE_REV);
dev_info(&adapter->dev, "found %s revision %u\n",
man_id == 0x23 ? "ADM9240" :
man_id == 0xda ? "DS1780" : "LM81", die_rev);
@@ -588,33 +553,59 @@ static int adm9240_detect(struct i2c_adapter *adapter, int address, int kind)
goto exit_detach;
}
- device_create_file(&new_client->dev, &dev_attr_in0_input);
- device_create_file(&new_client->dev, &dev_attr_in0_min);
- device_create_file(&new_client->dev, &dev_attr_in0_max);
- device_create_file(&new_client->dev, &dev_attr_in1_input);
- device_create_file(&new_client->dev, &dev_attr_in1_min);
- device_create_file(&new_client->dev, &dev_attr_in1_max);
- device_create_file(&new_client->dev, &dev_attr_in2_input);
- device_create_file(&new_client->dev, &dev_attr_in2_min);
- device_create_file(&new_client->dev, &dev_attr_in2_max);
- device_create_file(&new_client->dev, &dev_attr_in3_input);
- device_create_file(&new_client->dev, &dev_attr_in3_min);
- device_create_file(&new_client->dev, &dev_attr_in3_max);
- device_create_file(&new_client->dev, &dev_attr_in4_input);
- device_create_file(&new_client->dev, &dev_attr_in4_min);
- device_create_file(&new_client->dev, &dev_attr_in4_max);
- device_create_file(&new_client->dev, &dev_attr_in5_input);
- device_create_file(&new_client->dev, &dev_attr_in5_min);
- device_create_file(&new_client->dev, &dev_attr_in5_max);
- device_create_file(&new_client->dev, &dev_attr_temp1_max);
- device_create_file(&new_client->dev, &dev_attr_temp1_max_hyst);
+ device_create_file(&new_client->dev,
+ &sensor_dev_attr_in0_input.dev_attr);
+ device_create_file(&new_client->dev,
+ &sensor_dev_attr_in0_min.dev_attr);
+ device_create_file(&new_client->dev,
+ &sensor_dev_attr_in0_max.dev_attr);
+ device_create_file(&new_client->dev,
+ &sensor_dev_attr_in1_input.dev_attr);
+ device_create_file(&new_client->dev,
+ &sensor_dev_attr_in1_min.dev_attr);
+ device_create_file(&new_client->dev,
+ &sensor_dev_attr_in1_max.dev_attr);
+ device_create_file(&new_client->dev,
+ &sensor_dev_attr_in2_input.dev_attr);
+ device_create_file(&new_client->dev,
+ &sensor_dev_attr_in2_min.dev_attr);
+ device_create_file(&new_client->dev,
+ &sensor_dev_attr_in2_max.dev_attr);
+ device_create_file(&new_client->dev,
+ &sensor_dev_attr_in3_input.dev_attr);
+ device_create_file(&new_client->dev,
+ &sensor_dev_attr_in3_min.dev_attr);
+ device_create_file(&new_client->dev,
+ &sensor_dev_attr_in3_max.dev_attr);
+ device_create_file(&new_client->dev,
+ &sensor_dev_attr_in4_input.dev_attr);
+ device_create_file(&new_client->dev,
+ &sensor_dev_attr_in4_min.dev_attr);
+ device_create_file(&new_client->dev,
+ &sensor_dev_attr_in4_max.dev_attr);
+ device_create_file(&new_client->dev,
+ &sensor_dev_attr_in5_input.dev_attr);
+ device_create_file(&new_client->dev,
+ &sensor_dev_attr_in5_min.dev_attr);
+ device_create_file(&new_client->dev,
+ &sensor_dev_attr_in5_max.dev_attr);
device_create_file(&new_client->dev, &dev_attr_temp1_input);
- device_create_file(&new_client->dev, &dev_attr_fan1_input);
- device_create_file(&new_client->dev, &dev_attr_fan1_div);
- device_create_file(&new_client->dev, &dev_attr_fan1_min);
- device_create_file(&new_client->dev, &dev_attr_fan2_input);
- device_create_file(&new_client->dev, &dev_attr_fan2_div);
- device_create_file(&new_client->dev, &dev_attr_fan2_min);
+ device_create_file(&new_client->dev,
+ &sensor_dev_attr_temp1_max.dev_attr);
+ device_create_file(&new_client->dev,
+ &sensor_dev_attr_temp1_max_hyst.dev_attr);
+ device_create_file(&new_client->dev,
+ &sensor_dev_attr_fan1_input.dev_attr);
+ device_create_file(&new_client->dev,
+ &sensor_dev_attr_fan1_div.dev_attr);
+ device_create_file(&new_client->dev,
+ &sensor_dev_attr_fan1_min.dev_attr);
+ device_create_file(&new_client->dev,
+ &sensor_dev_attr_fan2_input.dev_attr);
+ device_create_file(&new_client->dev,
+ &sensor_dev_attr_fan2_div.dev_attr);
+ device_create_file(&new_client->dev,
+ &sensor_dev_attr_fan2_min.dev_attr);
device_create_file(&new_client->dev, &dev_attr_alarms);
device_create_file(&new_client->dev, &dev_attr_aout_output);
device_create_file(&new_client->dev, &dev_attr_chassis_clear);
@@ -654,8 +645,8 @@ static int adm9240_detach_client(struct i2c_client *client)
static void adm9240_init_client(struct i2c_client *client)
{
struct adm9240_data *data = i2c_get_clientdata(client);
- u8 conf = adm9240_read_value(client, ADM9240_REG_CONFIG);
- u8 mode = adm9240_read_value(client, ADM9240_REG_TEMP_CONF) & 3;
+ u8 conf = i2c_smbus_read_byte_data(client, ADM9240_REG_CONFIG);
+ u8 mode = i2c_smbus_read_byte_data(client, ADM9240_REG_TEMP_CONF) & 3;
data->vrm = vid_which_vrm(); /* need this to report vid as mV */
@@ -672,18 +663,22 @@ static void adm9240_init_client(struct i2c_client *client)
for (i = 0; i < 6; i++)
{
- adm9240_write_value(client,
+ i2c_smbus_write_byte_data(client,
ADM9240_REG_IN_MIN(i), 0);
- adm9240_write_value(client,
+ i2c_smbus_write_byte_data(client,
ADM9240_REG_IN_MAX(i), 255);
}
- adm9240_write_value(client, ADM9240_REG_FAN_MIN(0), 255);
- adm9240_write_value(client, ADM9240_REG_FAN_MIN(1), 255);
- adm9240_write_value(client, ADM9240_REG_TEMP_HIGH, 127);
- adm9240_write_value(client, ADM9240_REG_TEMP_HYST, 127);
+ i2c_smbus_write_byte_data(client,
+ ADM9240_REG_FAN_MIN(0), 255);
+ i2c_smbus_write_byte_data(client,
+ ADM9240_REG_FAN_MIN(1), 255);
+ i2c_smbus_write_byte_data(client,
+ ADM9240_REG_TEMP_MAX(0), 127);
+ i2c_smbus_write_byte_data(client,
+ ADM9240_REG_TEMP_MAX(1), 127);
/* start measurement cycle */
- adm9240_write_value(client, ADM9240_REG_CONFIG, 1);
+ i2c_smbus_write_byte_data(client, ADM9240_REG_CONFIG, 1);
dev_info(&client->dev, "cold start: config was 0x%02x "
"mode %u\n", conf, mode);
@@ -704,25 +699,25 @@ static struct adm9240_data *adm9240_update_device(struct device *dev)
for (i = 0; i < 6; i++) /* read voltages */
{
- data->in[i] = adm9240_read_value(client,
+ data->in[i] = i2c_smbus_read_byte_data(client,
ADM9240_REG_IN(i));
}
- data->alarms = adm9240_read_value(client,
+ data->alarms = i2c_smbus_read_byte_data(client,
ADM9240_REG_INT(0)) |
- adm9240_read_value(client,
+ i2c_smbus_read_byte_data(client,
ADM9240_REG_INT(1)) << 8;
/* read temperature: assume temperature changes less than
* 0.5'C per two measurement cycles thus ignore possible
* but unlikely aliasing error on lsb reading. --Grant */
- data->temp = ((adm9240_read_value(client,
+ data->temp = ((i2c_smbus_read_byte_data(client,
ADM9240_REG_TEMP) << 8) |
- adm9240_read_value(client,
+ i2c_smbus_read_byte_data(client,
ADM9240_REG_TEMP_CONF)) / 128;
for (i = 0; i < 2; i++) /* read fans */
{
- data->fan[i] = adm9240_read_value(client,
+ data->fan[i] = i2c_smbus_read_byte_data(client,
ADM9240_REG_FAN(i));
/* adjust fan clock divider on overflow */
@@ -747,30 +742,30 @@ static struct adm9240_data *adm9240_update_device(struct device *dev)
for (i = 0; i < 6; i++)
{
- data->in_min[i] = adm9240_read_value(client,
+ data->in_min[i] = i2c_smbus_read_byte_data(client,
ADM9240_REG_IN_MIN(i));
- data->in_max[i] = adm9240_read_value(client,
+ data->in_max[i] = i2c_smbus_read_byte_data(client,
ADM9240_REG_IN_MAX(i));
}
for (i = 0; i < 2; i++)
{
- data->fan_min[i] = adm9240_read_value(client,
+ data->fan_min[i] = i2c_smbus_read_byte_data(client,
ADM9240_REG_FAN_MIN(i));
}
- data->temp_high = adm9240_read_value(client,
- ADM9240_REG_TEMP_HIGH);
- data->temp_hyst = adm9240_read_value(client,
- ADM9240_REG_TEMP_HYST);
+ data->temp_max[0] = i2c_smbus_read_byte_data(client,
+ ADM9240_REG_TEMP_MAX(0));
+ data->temp_max[1] = i2c_smbus_read_byte_data(client,
+ ADM9240_REG_TEMP_MAX(1));
/* read fan divs and 5-bit VID */
- i = adm9240_read_value(client, ADM9240_REG_VID_FAN_DIV);
+ i = i2c_smbus_read_byte_data(client, ADM9240_REG_VID_FAN_DIV);
data->fan_div[0] = (i >> 4) & 3;
data->fan_div[1] = (i >> 6) & 3;
data->vid = i & 0x0f;
- data->vid |= (adm9240_read_value(client,
+ data->vid |= (i2c_smbus_read_byte_data(client,
ADM9240_REG_VID4) & 1) << 4;
/* read analog out */
- data->aout = adm9240_read_value(client,
+ data->aout = i2c_smbus_read_byte_data(client,
ADM9240_REG_ANALOG_OUT);
data->last_updated_config = jiffies;
diff --git a/drivers/hwmon/asb100.c b/drivers/hwmon/asb100.c
index 8e34855a6274..52c469722a65 100644
--- a/drivers/hwmon/asb100.c
+++ b/drivers/hwmon/asb100.c
@@ -629,19 +629,17 @@ static int asb100_detect_subclients(struct i2c_adapter *adapter, int address,
int i, id, err;
struct asb100_data *data = i2c_get_clientdata(new_client);
- data->lm75[0] = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
+ data->lm75[0] = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
if (!(data->lm75[0])) {
err = -ENOMEM;
goto ERROR_SC_0;
}
- memset(data->lm75[0], 0x00, sizeof(struct i2c_client));
- data->lm75[1] = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
+ data->lm75[1] = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
if (!(data->lm75[1])) {
err = -ENOMEM;
goto ERROR_SC_1;
}
- memset(data->lm75[1], 0x00, sizeof(struct i2c_client));
id = i2c_adapter_id(adapter);
@@ -724,12 +722,11 @@ static int asb100_detect(struct i2c_adapter *adapter, int address, int kind)
client structure, even though we cannot fill it completely yet.
But it allows us to access asb100_{read,write}_value. */
- if (!(data = kmalloc(sizeof(struct asb100_data), GFP_KERNEL))) {
- pr_debug("asb100.o: detect failed, kmalloc failed!\n");
+ if (!(data = kzalloc(sizeof(struct asb100_data), GFP_KERNEL))) {
+ pr_debug("asb100.o: detect failed, kzalloc failed!\n");
err = -ENOMEM;
goto ERROR0;
}
- memset(data, 0, sizeof(struct asb100_data));
new_client = &data->client;
init_MUTEX(&data->lock);
diff --git a/drivers/hwmon/atxp1.c b/drivers/hwmon/atxp1.c
index deb4d34c9539..53324f56404e 100644
--- a/drivers/hwmon/atxp1.c
+++ b/drivers/hwmon/atxp1.c
@@ -253,6 +253,8 @@ static DEVICE_ATTR(gpio2, S_IRUGO | S_IWUSR, atxp1_showgpio2, atxp1_storegpio2);
static int atxp1_attach_adapter(struct i2c_adapter *adapter)
{
+ if (!(adapter->class & I2C_CLASS_HWMON))
+ return 0;
return i2c_probe(adapter, &addr_data, &atxp1_detect);
};
@@ -266,12 +268,11 @@ static int atxp1_detect(struct i2c_adapter *adapter, int address, int kind)
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
goto exit;
- if (!(data = kmalloc(sizeof(struct atxp1_data), GFP_KERNEL))) {
+ if (!(data = kzalloc(sizeof(struct atxp1_data), GFP_KERNEL))) {
err = -ENOMEM;
goto exit;
}
- memset(data, 0, sizeof(struct atxp1_data));
new_client = &data->client;
i2c_set_clientdata(new_client, data);
diff --git a/drivers/hwmon/ds1621.c b/drivers/hwmon/ds1621.c
index b0199e063d0e..34f71b7c7f37 100644
--- a/drivers/hwmon/ds1621.c
+++ b/drivers/hwmon/ds1621.c
@@ -180,12 +180,14 @@ static DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp_max, set_temp_max);
static int ds1621_attach_adapter(struct i2c_adapter *adapter)
{
+ if (!(adapter->class & I2C_CLASS_HWMON))
+ return 0;
return i2c_probe(adapter, &addr_data, ds1621_detect);
}
/* This function is called by i2c_probe */
-int ds1621_detect(struct i2c_adapter *adapter, int address,
- int kind)
+static int ds1621_detect(struct i2c_adapter *adapter, int address,
+ int kind)
{
int conf, temp;
struct i2c_client *new_client;
@@ -200,11 +202,10 @@ int ds1621_detect(struct i2c_adapter *adapter, int address,
/* OK. For now, we presume we have a valid client. We now create the
client structure, even though we cannot fill it completely yet.
But it allows us to access ds1621_{read,write}_value. */
- if (!(data = kmalloc(sizeof(struct ds1621_data), GFP_KERNEL))) {
+ if (!(data = kzalloc(sizeof(struct ds1621_data), GFP_KERNEL))) {
err = -ENOMEM;
goto exit;
}
- memset(data, 0, sizeof(struct ds1621_data));
new_client = &data->client;
i2c_set_clientdata(new_client, data);
diff --git a/drivers/hwmon/fscher.c b/drivers/hwmon/fscher.c
index eef6061d786b..a02e1c34c757 100644
--- a/drivers/hwmon/fscher.c
+++ b/drivers/hwmon/fscher.c
@@ -303,11 +303,10 @@ static int fscher_detect(struct i2c_adapter *adapter, int address, int kind)
/* OK. For now, we presume we have a valid client. We now create the
* client structure, even though we cannot fill it completely yet.
* But it allows us to access i2c_smbus_read_byte_data. */
- if (!(data = kmalloc(sizeof(struct fscher_data), GFP_KERNEL))) {
+ if (!(data = kzalloc(sizeof(struct fscher_data), GFP_KERNEL))) {
err = -ENOMEM;
goto exit;
}
- memset(data, 0, sizeof(struct fscher_data));
/* The common I2C client data is placed right before the
* Hermes-specific data. */
diff --git a/drivers/hwmon/fscpos.c b/drivers/hwmon/fscpos.c
index 5fc77a5fed07..64e4edc64f8d 100644
--- a/drivers/hwmon/fscpos.c
+++ b/drivers/hwmon/fscpos.c
@@ -438,7 +438,7 @@ static int fscpos_attach_adapter(struct i2c_adapter *adapter)
return i2c_probe(adapter, &addr_data, fscpos_detect);
}
-int fscpos_detect(struct i2c_adapter *adapter, int address, int kind)
+static int fscpos_detect(struct i2c_adapter *adapter, int address, int kind)
{
struct i2c_client *new_client;
struct fscpos_data *data;
@@ -453,11 +453,10 @@ int fscpos_detect(struct i2c_adapter *adapter, int address, int kind)
* But it allows us to access fscpos_{read,write}_value.
*/
- if (!(data = kmalloc(sizeof(struct fscpos_data), GFP_KERNEL))) {
+ if (!(data = kzalloc(sizeof(struct fscpos_data), GFP_KERNEL))) {
err = -ENOMEM;
goto exit;
}
- memset(data, 0, sizeof(struct fscpos_data));
new_client = &data->client;
i2c_set_clientdata(new_client, data);
diff --git a/drivers/hwmon/gl518sm.c b/drivers/hwmon/gl518sm.c
index 256b9323c84b..2f178dbe3d87 100644
--- a/drivers/hwmon/gl518sm.c
+++ b/drivers/hwmon/gl518sm.c
@@ -365,11 +365,10 @@ static int gl518_detect(struct i2c_adapter *adapter, int address, int kind)
client structure, even though we cannot fill it completely yet.
But it allows us to access gl518_{read,write}_value. */
- if (!(data = kmalloc(sizeof(struct gl518_data), GFP_KERNEL))) {
+ if (!(data = kzalloc(sizeof(struct gl518_data), GFP_KERNEL))) {
err = -ENOMEM;
goto exit;
}
- memset(data, 0, sizeof(struct gl518_data));
new_client = &data->client;
i2c_set_clientdata(new_client, data);
diff --git a/drivers/hwmon/gl520sm.c b/drivers/hwmon/gl520sm.c
index 12fd757066fc..c39ba1239426 100644
--- a/drivers/hwmon/gl520sm.c
+++ b/drivers/hwmon/gl520sm.c
@@ -536,11 +536,10 @@ static int gl520_detect(struct i2c_adapter *adapter, int address, int kind)
client structure, even though we cannot fill it completely yet.
But it allows us to access gl520_{read,write}_value. */
- if (!(data = kmalloc(sizeof(struct gl520_data), GFP_KERNEL))) {
+ if (!(data = kzalloc(sizeof(struct gl520_data), GFP_KERNEL))) {
err = -ENOMEM;
goto exit;
}
- memset(data, 0, sizeof(struct gl520_data));
new_client = &data->client;
i2c_set_clientdata(new_client, data);
diff --git a/drivers/hwmon/hdaps.c b/drivers/hwmon/hdaps.c
index 7f0107613827..1e5dfc7805e2 100644
--- a/drivers/hwmon/hdaps.c
+++ b/drivers/hwmon/hdaps.c
@@ -27,7 +27,7 @@
*/
#include <linux/delay.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <linux/input.h>
#include <linux/kernel.h>
#include <linux/module.h>
@@ -296,11 +296,9 @@ static int hdaps_probe(struct device *dev)
return 0;
}
-static int hdaps_resume(struct device *dev, u32 level)
+static int hdaps_resume(struct device *dev)
{
- if (level == RESUME_ENABLE)
- return hdaps_device_init();
- return 0;
+ return hdaps_device_init();
}
static struct device_driver hdaps_driver = {
diff --git a/drivers/hwmon/hwmon.c b/drivers/hwmon/hwmon.c
index 9b41c9bd805f..dddd3eb9b387 100644
--- a/drivers/hwmon/hwmon.c
+++ b/drivers/hwmon/hwmon.c
@@ -16,6 +16,7 @@
#include <linux/kdev_t.h>
#include <linux/idr.h>
#include <linux/hwmon.h>
+#include <linux/gfp.h>
#define HWMON_ID_PREFIX "hwmon"
#define HWMON_ID_FORMAT HWMON_ID_PREFIX "%d"
@@ -45,7 +46,7 @@ struct class_device *hwmon_device_register(struct device *dev)
return ERR_PTR(-ENOMEM);
id = id & MAX_ID_MASK;
- cdev = class_device_create(hwmon_class, MKDEV(0,0), dev,
+ cdev = class_device_create(hwmon_class, NULL, MKDEV(0,0), dev,
HWMON_ID_FORMAT, id);
if (IS_ERR(cdev))
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
index 53cc2b6d6385..6c41e25e670b 100644
--- a/drivers/hwmon/it87.c
+++ b/drivers/hwmon/it87.c
@@ -2,7 +2,7 @@
it87.c - Part of lm_sensors, Linux kernel modules for hardware
monitoring.
- Supports: IT8705F Super I/O chip w/LPC interface & SMBus
+ Supports: IT8705F Super I/O chip w/LPC interface
IT8712F Super I/O chip w/LPC interface & SMBus
Sis950 A clone of the IT8705F
@@ -47,7 +47,7 @@
/* Addresses to scan */
static unsigned short normal_i2c[] = { 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d,
0x2e, 0x2f, I2C_CLIENT_END };
-static unsigned short isa_address = 0x290;
+static unsigned short isa_address;
/* Insmod parameters */
I2C_CLIENT_INSMOD_2(it87, it8712);
@@ -706,7 +706,7 @@ static int it87_isa_attach_adapter(struct i2c_adapter *adapter)
}
/* SuperIO detection - will change isa_address if a chip is found */
-static int __init it87_find(int *address)
+static int __init it87_find(unsigned short *address)
{
int err = -ENODEV;
@@ -738,7 +738,7 @@ exit:
}
/* This function is called by i2c_probe */
-int it87_detect(struct i2c_adapter *adapter, int address, int kind)
+static int it87_detect(struct i2c_adapter *adapter, int address, int kind)
{
int i;
struct i2c_client *new_client;
@@ -757,42 +757,14 @@ int it87_detect(struct i2c_adapter *adapter, int address, int kind)
if (!request_region(address, IT87_EXTENT, it87_isa_driver.name))
goto ERROR0;
- /* Probe whether there is anything available on this address. Already
- done for SMBus and Super-I/O clients */
- if (kind < 0) {
- if (is_isa && !chip_type) {
-#define REALLY_SLOW_IO
- /* We need the timeouts for at least some IT87-like chips. But only
- if we read 'undefined' registers. */
- i = inb_p(address + 1);
- if (inb_p(address + 2) != i
- || inb_p(address + 3) != i
- || inb_p(address + 7) != i) {
- err = -ENODEV;
- goto ERROR1;
- }
-#undef REALLY_SLOW_IO
-
- /* Let's just hope nothing breaks here */
- i = inb_p(address + 5) & 0x7f;
- outb_p(~i & 0x7f, address + 5);
- if ((inb_p(address + 5) & 0x7f) != (~i & 0x7f)) {
- outb_p(i, address + 5);
- err = -ENODEV;
- goto ERROR1;
- }
- }
- }
-
- /* OK. For now, we presume we have a valid client. We now create the
+ /* For now, we presume we have a valid client. We create the
client structure, even though we cannot fill it completely yet.
But it allows us to access it87_{read,write}_value. */
- if (!(data = kmalloc(sizeof(struct it87_data), GFP_KERNEL))) {
+ if (!(data = kzalloc(sizeof(struct it87_data), GFP_KERNEL))) {
err = -ENOMEM;
goto ERROR1;
}
- memset(data, 0, sizeof(struct it87_data));
new_client = &data->client;
if (is_isa)
@@ -1182,20 +1154,18 @@ static struct it87_data *it87_update_device(struct device *dev)
static int __init sm_it87_init(void)
{
- int addr, res;
-
- if (!it87_find(&addr)) {
- isa_address = addr;
- }
+ int res;
res = i2c_add_driver(&it87_driver);
if (res)
return res;
- res = i2c_isa_add_driver(&it87_isa_driver);
- if (res) {
- i2c_del_driver(&it87_driver);
- return res;
+ if (!it87_find(&isa_address)) {
+ res = i2c_isa_add_driver(&it87_isa_driver);
+ if (res) {
+ i2c_del_driver(&it87_driver);
+ return res;
+ }
}
return 0;
diff --git a/drivers/hwmon/lm63.c b/drivers/hwmon/lm63.c
index be5c7095ecbb..954ec2497249 100644
--- a/drivers/hwmon/lm63.c
+++ b/drivers/hwmon/lm63.c
@@ -375,11 +375,10 @@ static int lm63_detect(struct i2c_adapter *adapter, int address, int kind)
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
goto exit;
- if (!(data = kmalloc(sizeof(struct lm63_data), GFP_KERNEL))) {
+ if (!(data = kzalloc(sizeof(struct lm63_data), GFP_KERNEL))) {
err = -ENOMEM;
goto exit;
}
- memset(data, 0, sizeof(struct lm63_data));
/* The common I2C client data is placed right before the
LM63-specific data. */
diff --git a/drivers/hwmon/lm75.c b/drivers/hwmon/lm75.c
index 9a3ebdf583f4..d70f4c8fc1e6 100644
--- a/drivers/hwmon/lm75.c
+++ b/drivers/hwmon/lm75.c
@@ -127,11 +127,10 @@ static int lm75_detect(struct i2c_adapter *adapter, int address, int kind)
/* OK. For now, we presume we have a valid client. We now create the
client structure, even though we cannot fill it completely yet.
But it allows us to access lm75_{read,write}_value. */
- if (!(data = kmalloc(sizeof(struct lm75_data), GFP_KERNEL))) {
+ if (!(data = kzalloc(sizeof(struct lm75_data), GFP_KERNEL))) {
err = -ENOMEM;
goto exit;
}
- memset(data, 0, sizeof(struct lm75_data));
new_client = &data->client;
i2c_set_clientdata(new_client, data);
diff --git a/drivers/hwmon/lm77.c b/drivers/hwmon/lm77.c
index 866eab96a6f6..9380fda7dcd1 100644
--- a/drivers/hwmon/lm77.c
+++ b/drivers/hwmon/lm77.c
@@ -226,11 +226,10 @@ static int lm77_detect(struct i2c_adapter *adapter, int address, int kind)
/* OK. For now, we presume we have a valid client. We now create the
client structure, even though we cannot fill it completely yet.
But it allows us to access lm77_{read,write}_value. */
- if (!(data = kmalloc(sizeof(struct lm77_data), GFP_KERNEL))) {
+ if (!(data = kzalloc(sizeof(struct lm77_data), GFP_KERNEL))) {
err = -ENOMEM;
goto exit;
}
- memset(data, 0, sizeof(struct lm77_data));
new_client = &data->client;
i2c_set_clientdata(new_client, data);
diff --git a/drivers/hwmon/lm78.c b/drivers/hwmon/lm78.c
index f6730dc3573b..bde0cda9477e 100644
--- a/drivers/hwmon/lm78.c
+++ b/drivers/hwmon/lm78.c
@@ -480,7 +480,7 @@ static int lm78_isa_attach_adapter(struct i2c_adapter *adapter)
}
/* This function is called by i2c_probe */
-int lm78_detect(struct i2c_adapter *adapter, int address, int kind)
+static int lm78_detect(struct i2c_adapter *adapter, int address, int kind)
{
int i, err;
struct i2c_client *new_client;
@@ -540,11 +540,10 @@ int lm78_detect(struct i2c_adapter *adapter, int address, int kind)
client structure, even though we cannot fill it completely yet.
But it allows us to access lm78_{read,write}_value. */
- if (!(data = kmalloc(sizeof(struct lm78_data), GFP_KERNEL))) {
+ if (!(data = kzalloc(sizeof(struct lm78_data), GFP_KERNEL))) {
err = -ENOMEM;
goto ERROR1;
}
- memset(data, 0, sizeof(struct lm78_data));
new_client = &data->client;
if (is_isa)
@@ -726,7 +725,6 @@ static int lm78_write_value(struct i2c_client *client, u8 reg, u8 value)
return i2c_smbus_write_byte_data(client, reg, value);
}
-/* Called when we have found a new LM78. It should set limits, etc. */
static void lm78_init_client(struct i2c_client *client)
{
u8 config = lm78_read_value(client, LM78_REG_CONFIG);
diff --git a/drivers/hwmon/lm80.c b/drivers/hwmon/lm80.c
index 83af8b3a0cac..c359fdea211e 100644
--- a/drivers/hwmon/lm80.c
+++ b/drivers/hwmon/lm80.c
@@ -393,7 +393,7 @@ static int lm80_attach_adapter(struct i2c_adapter *adapter)
return i2c_probe(adapter, &addr_data, lm80_detect);
}
-int lm80_detect(struct i2c_adapter *adapter, int address, int kind)
+static int lm80_detect(struct i2c_adapter *adapter, int address, int kind)
{
int i, cur;
struct i2c_client *new_client;
@@ -407,11 +407,10 @@ int lm80_detect(struct i2c_adapter *adapter, int address, int kind)
/* OK. For now, we presume we have a valid client. We now create the
client structure, even though we cannot fill it completely yet.
But it allows us to access lm80_{read,write}_value. */
- if (!(data = kmalloc(sizeof(struct lm80_data), GFP_KERNEL))) {
+ if (!(data = kzalloc(sizeof(struct lm80_data), GFP_KERNEL))) {
err = -ENOMEM;
goto exit;
}
- memset(data, 0, sizeof(struct lm80_data));
new_client = &data->client;
i2c_set_clientdata(new_client, data);
diff --git a/drivers/hwmon/lm83.c b/drivers/hwmon/lm83.c
index d74b2c20c719..9a70611a9f69 100644
--- a/drivers/hwmon/lm83.c
+++ b/drivers/hwmon/lm83.c
@@ -230,11 +230,10 @@ static int lm83_detect(struct i2c_adapter *adapter, int address, int kind)
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
goto exit;
- if (!(data = kmalloc(sizeof(struct lm83_data), GFP_KERNEL))) {
+ if (!(data = kzalloc(sizeof(struct lm83_data), GFP_KERNEL))) {
err = -ENOMEM;
goto exit;
}
- memset(data, 0, sizeof(struct lm83_data));
/* The common I2C client data is placed right after the
* LM83-specific data. */
diff --git a/drivers/hwmon/lm85.c b/drivers/hwmon/lm85.c
index ab214df9624b..d1070ed2bee6 100644
--- a/drivers/hwmon/lm85.c
+++ b/drivers/hwmon/lm85.c
@@ -1007,14 +1007,14 @@ temp_auto(1);
temp_auto(2);
temp_auto(3);
-int lm85_attach_adapter(struct i2c_adapter *adapter)
+static int lm85_attach_adapter(struct i2c_adapter *adapter)
{
if (!(adapter->class & I2C_CLASS_HWMON))
return 0;
return i2c_probe(adapter, &addr_data, lm85_detect);
}
-int lm85_detect(struct i2c_adapter *adapter, int address,
+static int lm85_detect(struct i2c_adapter *adapter, int address,
int kind)
{
int company, verstep ;
@@ -1033,11 +1033,10 @@ int lm85_detect(struct i2c_adapter *adapter, int address,
client structure, even though we cannot fill it completely yet.
But it allows us to access lm85_{read,write}_value. */
- if (!(data = kmalloc(sizeof(struct lm85_data), GFP_KERNEL))) {
+ if (!(data = kzalloc(sizeof(struct lm85_data), GFP_KERNEL))) {
err = -ENOMEM;
goto ERROR0;
}
- memset(data, 0, sizeof(struct lm85_data));
new_client = &data->client;
i2c_set_clientdata(new_client, data);
@@ -1236,7 +1235,7 @@ int lm85_detect(struct i2c_adapter *adapter, int address,
return err;
}
-int lm85_detach_client(struct i2c_client *client)
+static int lm85_detach_client(struct i2c_client *client)
{
struct lm85_data *data = i2c_get_clientdata(client);
hwmon_device_unregister(data->class_dev);
@@ -1246,7 +1245,7 @@ int lm85_detach_client(struct i2c_client *client)
}
-int lm85_read_value(struct i2c_client *client, u8 reg)
+static int lm85_read_value(struct i2c_client *client, u8 reg)
{
int res;
@@ -1276,7 +1275,7 @@ int lm85_read_value(struct i2c_client *client, u8 reg)
return res ;
}
-int lm85_write_value(struct i2c_client *client, u8 reg, int value)
+static int lm85_write_value(struct i2c_client *client, u8 reg, int value)
{
int res ;
@@ -1305,7 +1304,7 @@ int lm85_write_value(struct i2c_client *client, u8 reg, int value)
return res ;
}
-void lm85_init_client(struct i2c_client *client)
+static void lm85_init_client(struct i2c_client *client)
{
int value;
struct lm85_data *data = i2c_get_clientdata(client);
diff --git a/drivers/hwmon/lm87.c b/drivers/hwmon/lm87.c
index dca996de4c33..eeec18177861 100644
--- a/drivers/hwmon/lm87.c
+++ b/drivers/hwmon/lm87.c
@@ -554,11 +554,10 @@ static int lm87_detect(struct i2c_adapter *adapter, int address, int kind)
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
goto exit;
- if (!(data = kmalloc(sizeof(struct lm87_data), GFP_KERNEL))) {
+ if (!(data = kzalloc(sizeof(struct lm87_data), GFP_KERNEL))) {
err = -ENOMEM;
goto exit;
}
- memset(data, 0, sizeof(struct lm87_data));
/* The common I2C client data is placed right before the
LM87-specific data. */
diff --git a/drivers/hwmon/lm90.c b/drivers/hwmon/lm90.c
index 14de05fcd431..83cf2e1b09f5 100644
--- a/drivers/hwmon/lm90.c
+++ b/drivers/hwmon/lm90.c
@@ -31,7 +31,7 @@
* Devices. That chip is similar to the LM90, with a few differences
* that are not handled by this driver. Complete datasheet can be
* obtained from Analog's website at:
- * http://products.analog.com/products/info.asp?product=ADM1032
+ * http://www.analog.com/en/prod/0,2877,ADM1032,00.html
* Among others, it has a higher accuracy than the LM90, much like the
* LM86 does.
*
@@ -49,7 +49,7 @@
* register values are decoded differently) it is ignored by this
* driver. Complete datasheet can be obtained from Analog's website
* at:
- * http://products.analog.com/products/info.asp?product=ADT7461
+ * http://www.analog.com/en/prod/0,2877,ADT7461,00.html
*
* Since the LM90 was the first chipset supported by this driver, most
* comments will refer to this chipset, but are actually general and
@@ -83,10 +83,10 @@
* Addresses to scan
* Address is fully defined internally and cannot be changed except for
* MAX6659.
- * LM86, LM89, LM90, LM99, ADM1032, MAX6657 and MAX6658 have address 0x4c.
- * LM89-1, and LM99-1 have address 0x4d.
+ * LM86, LM89, LM90, LM99, ADM1032, ADM1032-1, ADT7461, MAX6657 and MAX6658
+ * have address 0x4c.
+ * ADM1032-2, ADT7461-2, LM89-1, and LM99-1 have address 0x4d.
* MAX6659 can have address 0x4c, 0x4d or 0x4e (unsupported).
- * ADT7461 always has address 0x4c.
*/
static unsigned short normal_i2c[] = { 0x4c, 0x4d, I2C_CLIENT_END };
@@ -345,10 +345,74 @@ static SENSOR_DEVICE_ATTR(temp1_crit_hyst, S_IWUSR | S_IRUGO, show_temphyst,
static SENSOR_DEVICE_ATTR(temp2_crit_hyst, S_IRUGO, show_temphyst, NULL, 4);
static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);
+/* pec used for ADM1032 only */
+static ssize_t show_pec(struct device *dev, struct device_attribute *dummy,
+ char *buf)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ return sprintf(buf, "%d\n", !!(client->flags & I2C_CLIENT_PEC));
+}
+
+static ssize_t set_pec(struct device *dev, struct device_attribute *dummy,
+ const char *buf, size_t count)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ long val = simple_strtol(buf, NULL, 10);
+
+ switch (val) {
+ case 0:
+ client->flags &= ~I2C_CLIENT_PEC;
+ break;
+ case 1:
+ client->flags |= I2C_CLIENT_PEC;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return count;
+}
+
+static DEVICE_ATTR(pec, S_IWUSR | S_IRUGO, show_pec, set_pec);
+
/*
* Real code
*/
+/* The ADM1032 supports PEC but not on write byte transactions, so we need
+ to explicitely ask for a transaction without PEC. */
+static inline s32 adm1032_write_byte(struct i2c_client *client, u8 value)
+{
+ return i2c_smbus_xfer(client->adapter, client->addr,
+ client->flags & ~I2C_CLIENT_PEC,
+ I2C_SMBUS_WRITE, value, I2C_SMBUS_BYTE, NULL);
+}
+
+/* It is assumed that client->update_lock is held (unless we are in
+ detection or initialization steps). This matters when PEC is enabled,
+ because we don't want the address pointer to change between the write
+ byte and the read byte transactions. */
+static int lm90_read_reg(struct i2c_client* client, u8 reg, u8 *value)
+{
+ int err;
+
+ if (client->flags & I2C_CLIENT_PEC) {
+ err = adm1032_write_byte(client, reg);
+ if (err >= 0)
+ err = i2c_smbus_read_byte(client);
+ } else
+ err = i2c_smbus_read_byte_data(client, reg);
+
+ if (err < 0) {
+ dev_warn(&client->dev, "Register %#02x read failed (%d)\n",
+ reg, err);
+ return err;
+ }
+ *value = err;
+
+ return 0;
+}
+
static int lm90_attach_adapter(struct i2c_adapter *adapter)
{
if (!(adapter->class & I2C_CLASS_HWMON))
@@ -370,11 +434,10 @@ static int lm90_detect(struct i2c_adapter *adapter, int address, int kind)
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
goto exit;
- if (!(data = kmalloc(sizeof(struct lm90_data), GFP_KERNEL))) {
+ if (!(data = kzalloc(sizeof(struct lm90_data), GFP_KERNEL))) {
err = -ENOMEM;
goto exit;
}
- memset(data, 0, sizeof(struct lm90_data));
/* The common I2C client data is placed right before the
LM90-specific data. */
@@ -403,20 +466,22 @@ static int lm90_detect(struct i2c_adapter *adapter, int address, int kind)
if (kind < 0) { /* detection and identification */
u8 man_id, chip_id, reg_config1, reg_convrate;
- man_id = i2c_smbus_read_byte_data(new_client,
- LM90_REG_R_MAN_ID);
- chip_id = i2c_smbus_read_byte_data(new_client,
- LM90_REG_R_CHIP_ID);
- reg_config1 = i2c_smbus_read_byte_data(new_client,
- LM90_REG_R_CONFIG1);
- reg_convrate = i2c_smbus_read_byte_data(new_client,
- LM90_REG_R_CONVRATE);
+ if (lm90_read_reg(new_client, LM90_REG_R_MAN_ID,
+ &man_id) < 0
+ || lm90_read_reg(new_client, LM90_REG_R_CHIP_ID,
+ &chip_id) < 0
+ || lm90_read_reg(new_client, LM90_REG_R_CONFIG1,
+ &reg_config1) < 0
+ || lm90_read_reg(new_client, LM90_REG_R_CONVRATE,
+ &reg_convrate) < 0)
+ goto exit_free;
if (man_id == 0x01) { /* National Semiconductor */
u8 reg_config2;
- reg_config2 = i2c_smbus_read_byte_data(new_client,
- LM90_REG_R_CONFIG2);
+ if (lm90_read_reg(new_client, LM90_REG_R_CONFIG2,
+ &reg_config2) < 0)
+ goto exit_free;
if ((reg_config1 & 0x2A) == 0x00
&& (reg_config2 & 0xF8) == 0x00
@@ -435,14 +500,12 @@ static int lm90_detect(struct i2c_adapter *adapter, int address, int kind)
}
} else
if (man_id == 0x41) { /* Analog Devices */
- if (address == 0x4C
- && (chip_id & 0xF0) == 0x40 /* ADM1032 */
+ if ((chip_id & 0xF0) == 0x40 /* ADM1032 */
&& (reg_config1 & 0x3F) == 0x00
&& reg_convrate <= 0x0A) {
kind = adm1032;
} else
- if (address == 0x4c
- && chip_id == 0x51 /* ADT7461 */
+ if (chip_id == 0x51 /* ADT7461 */
&& (reg_config1 & 0x1F) == 0x00 /* check compat mode */
&& reg_convrate <= 0x0A) {
kind = adt7461;
@@ -477,6 +540,10 @@ static int lm90_detect(struct i2c_adapter *adapter, int address, int kind)
name = "lm90";
} else if (kind == adm1032) {
name = "adm1032";
+ /* The ADM1032 supports PEC, but only if combined
+ transactions are not used. */
+ if (i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE))
+ new_client->flags |= I2C_CLIENT_PEC;
} else if (kind == lm99) {
name = "lm99";
} else if (kind == lm86) {
@@ -529,6 +596,9 @@ static int lm90_detect(struct i2c_adapter *adapter, int address, int kind)
&sensor_dev_attr_temp2_crit_hyst.dev_attr);
device_create_file(&new_client->dev, &dev_attr_alarms);
+ if (new_client->flags & I2C_CLIENT_PEC)
+ device_create_file(&new_client->dev, &dev_attr_pec);
+
return 0;
exit_detach:
@@ -548,7 +618,10 @@ static void lm90_init_client(struct i2c_client *client)
*/
i2c_smbus_write_byte_data(client, LM90_REG_W_CONVRATE,
5); /* 2 Hz */
- config = i2c_smbus_read_byte_data(client, LM90_REG_R_CONFIG1);
+ if (lm90_read_reg(client, LM90_REG_R_CONFIG1, &config) < 0) {
+ dev_warn(&client->dev, "Initialization failed!\n");
+ return;
+ }
if (config & 0x40)
i2c_smbus_write_byte_data(client, LM90_REG_W_CONFIG1,
config & 0xBF); /* run */
@@ -576,21 +649,15 @@ static struct lm90_data *lm90_update_device(struct device *dev)
down(&data->update_lock);
if (time_after(jiffies, data->last_updated + HZ * 2) || !data->valid) {
- u8 oldh, newh;
+ u8 oldh, newh, l;
dev_dbg(&client->dev, "Updating lm90 data.\n");
- data->temp8[0] = i2c_smbus_read_byte_data(client,
- LM90_REG_R_LOCAL_TEMP);
- data->temp8[1] = i2c_smbus_read_byte_data(client,
- LM90_REG_R_LOCAL_LOW);
- data->temp8[2] = i2c_smbus_read_byte_data(client,
- LM90_REG_R_LOCAL_HIGH);
- data->temp8[3] = i2c_smbus_read_byte_data(client,
- LM90_REG_R_LOCAL_CRIT);
- data->temp8[4] = i2c_smbus_read_byte_data(client,
- LM90_REG_R_REMOTE_CRIT);
- data->temp_hyst = i2c_smbus_read_byte_data(client,
- LM90_REG_R_TCRIT_HYST);
+ lm90_read_reg(client, LM90_REG_R_LOCAL_TEMP, &data->temp8[0]);
+ lm90_read_reg(client, LM90_REG_R_LOCAL_LOW, &data->temp8[1]);
+ lm90_read_reg(client, LM90_REG_R_LOCAL_HIGH, &data->temp8[2]);
+ lm90_read_reg(client, LM90_REG_R_LOCAL_CRIT, &data->temp8[3]);
+ lm90_read_reg(client, LM90_REG_R_REMOTE_CRIT, &data->temp8[4]);
+ lm90_read_reg(client, LM90_REG_R_TCRIT_HYST, &data->temp_hyst);
/*
* There is a trick here. We have to read two registers to
@@ -606,36 +673,20 @@ static struct lm90_data *lm90_update_device(struct device *dev)
* then we have a valid reading. Else we have to read the low
* byte again, and now we believe we have a correct reading.
*/
- oldh = i2c_smbus_read_byte_data(client,
- LM90_REG_R_REMOTE_TEMPH);
- data->temp11[0] = i2c_smbus_read_byte_data(client,
- LM90_REG_R_REMOTE_TEMPL);
- newh = i2c_smbus_read_byte_data(client,
- LM90_REG_R_REMOTE_TEMPH);
- if (newh != oldh) {
- data->temp11[0] = i2c_smbus_read_byte_data(client,
- LM90_REG_R_REMOTE_TEMPL);
-#ifdef DEBUG
- oldh = i2c_smbus_read_byte_data(client,
- LM90_REG_R_REMOTE_TEMPH);
- /* oldh is actually newer */
- if (newh != oldh)
- dev_warn(&client->dev, "Remote temperature may be "
- "wrong.\n");
-#endif
- }
- data->temp11[0] |= (newh << 8);
-
- data->temp11[1] = (i2c_smbus_read_byte_data(client,
- LM90_REG_R_REMOTE_LOWH) << 8) +
- i2c_smbus_read_byte_data(client,
- LM90_REG_R_REMOTE_LOWL);
- data->temp11[2] = (i2c_smbus_read_byte_data(client,
- LM90_REG_R_REMOTE_HIGHH) << 8) +
- i2c_smbus_read_byte_data(client,
- LM90_REG_R_REMOTE_HIGHL);
- data->alarms = i2c_smbus_read_byte_data(client,
- LM90_REG_R_STATUS);
+ if (lm90_read_reg(client, LM90_REG_R_REMOTE_TEMPH, &oldh) == 0
+ && lm90_read_reg(client, LM90_REG_R_REMOTE_TEMPL, &l) == 0
+ && lm90_read_reg(client, LM90_REG_R_REMOTE_TEMPH, &newh) == 0
+ && (newh == oldh
+ || lm90_read_reg(client, LM90_REG_R_REMOTE_TEMPL, &l) == 0))
+ data->temp11[0] = (newh << 8) | l;
+
+ if (lm90_read_reg(client, LM90_REG_R_REMOTE_LOWH, &newh) == 0
+ && lm90_read_reg(client, LM90_REG_R_REMOTE_LOWL, &l) == 0)
+ data->temp11[1] = (newh << 8) | l;
+ if (lm90_read_reg(client, LM90_REG_R_REMOTE_HIGHH, &newh) == 0
+ && lm90_read_reg(client, LM90_REG_R_REMOTE_HIGHL, &l) == 0)
+ data->temp11[2] = (newh << 8) | l;
+ lm90_read_reg(client, LM90_REG_R_STATUS, &data->alarms);
data->last_updated = jiffies;
data->valid = 1;
diff --git a/drivers/hwmon/lm92.c b/drivers/hwmon/lm92.c
index 647b7c7cd575..7a4b3701ed1a 100644
--- a/drivers/hwmon/lm92.c
+++ b/drivers/hwmon/lm92.c
@@ -300,11 +300,10 @@ static int lm92_detect(struct i2c_adapter *adapter, int address, int kind)
| I2C_FUNC_SMBUS_WORD_DATA))
goto exit;
- if (!(data = kmalloc(sizeof(struct lm92_data), GFP_KERNEL))) {
+ if (!(data = kzalloc(sizeof(struct lm92_data), GFP_KERNEL))) {
err = -ENOMEM;
goto exit;
}
- memset(data, 0, sizeof(struct lm92_data));
/* Fill in enough client fields so that we can read from the chip,
which is required for identication */
diff --git a/drivers/hwmon/max1619.c b/drivers/hwmon/max1619.c
index 16bf71f3a04d..69e7e125683b 100644
--- a/drivers/hwmon/max1619.c
+++ b/drivers/hwmon/max1619.c
@@ -193,15 +193,14 @@ static int max1619_detect(struct i2c_adapter *adapter, int address, int kind)
int err = 0;
const char *name = "";
u8 reg_config=0, reg_convrate=0, reg_status=0;
- u8 man_id, chip_id;
+
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
goto exit;
- if (!(data = kmalloc(sizeof(struct max1619_data), GFP_KERNEL))) {
+ if (!(data = kzalloc(sizeof(struct max1619_data), GFP_KERNEL))) {
err = -ENOMEM;
goto exit;
}
- memset(data, 0, sizeof(struct max1619_data));
/* The common I2C client data is placed right before the
MAX1619-specific data. */
@@ -239,16 +238,15 @@ static int max1619_detect(struct i2c_adapter *adapter, int address, int kind)
}
if (kind <= 0) { /* identification */
+ u8 man_id, chip_id;
man_id = i2c_smbus_read_byte_data(new_client,
MAX1619_REG_R_MAN_ID);
chip_id = i2c_smbus_read_byte_data(new_client,
MAX1619_REG_R_CHIP_ID);
- if ((man_id == 0x4D) && (chip_id == 0x04)){
- kind = max1619;
- }
- }
+ if ((man_id == 0x4D) && (chip_id == 0x04))
+ kind = max1619;
if (kind <= 0) { /* identification failed */
dev_info(&adapter->dev,
@@ -256,11 +254,10 @@ static int max1619_detect(struct i2c_adapter *adapter, int address, int kind)
"chip_id=0x%02X).\n", man_id, chip_id);
goto exit_free;
}
-
+ }
- if (kind == max1619){
+ if (kind == max1619)
name = "max1619";
- }
/* We can fill in the remaining client fields */
strlcpy(new_client->name, name, I2C_NAME_SIZE);
diff --git a/drivers/hwmon/pc87360.c b/drivers/hwmon/pc87360.c
index cf2a35799c7c..17f745a23d04 100644
--- a/drivers/hwmon/pc87360.c
+++ b/drivers/hwmon/pc87360.c
@@ -754,9 +754,8 @@ static int pc87360_detect(struct i2c_adapter *adapter)
const char *name = "pc87360";
int use_thermistors = 0;
- if (!(data = kmalloc(sizeof(struct pc87360_data), GFP_KERNEL)))
+ if (!(data = kzalloc(sizeof(struct pc87360_data), GFP_KERNEL)))
return -ENOMEM;
- memset(data, 0x00, sizeof(struct pc87360_data));
new_client = &data->client;
i2c_set_clientdata(new_client, data);
diff --git a/drivers/hwmon/sis5595.c b/drivers/hwmon/sis5595.c
index 21aa9a41f62c..9c6cadec1087 100644
--- a/drivers/hwmon/sis5595.c
+++ b/drivers/hwmon/sis5595.c
@@ -518,11 +518,10 @@ static int sis5595_detect(struct i2c_adapter *adapter)
goto exit_release;
}
- if (!(data = kmalloc(sizeof(struct sis5595_data), GFP_KERNEL))) {
+ if (!(data = kzalloc(sizeof(struct sis5595_data), GFP_KERNEL))) {
err = -ENOMEM;
goto exit_release;
}
- memset(data, 0, sizeof(struct sis5595_data));
new_client = &data->client;
new_client->addr = address;
diff --git a/drivers/hwmon/smsc47b397.c b/drivers/hwmon/smsc47b397.c
index 7fe71576dea4..2a3e21b5b6b4 100644
--- a/drivers/hwmon/smsc47b397.c
+++ b/drivers/hwmon/smsc47b397.c
@@ -244,11 +244,10 @@ static int smsc47b397_detect(struct i2c_adapter *adapter)
return -EBUSY;
}
- if (!(data = kmalloc(sizeof(struct smsc47b397_data), GFP_KERNEL))) {
+ if (!(data = kzalloc(sizeof(struct smsc47b397_data), GFP_KERNEL))) {
err = -ENOMEM;
goto error_release;
}
- memset(data, 0x00, sizeof(struct smsc47b397_data));
new_client = &data->client;
i2c_set_clientdata(new_client, data);
@@ -299,7 +298,7 @@ static int __init smsc47b397_find(unsigned short *addr)
superio_enter();
id = superio_inb(SUPERIO_REG_DEVID);
- if (id != 0x6f) {
+ if ((id != 0x6f) && (id != 0x81)) {
superio_exit();
return -ENODEV;
}
@@ -310,8 +309,9 @@ static int __init smsc47b397_find(unsigned short *addr)
*addr = (superio_inb(SUPERIO_REG_BASE_MSB) << 8)
| superio_inb(SUPERIO_REG_BASE_LSB);
- printk(KERN_INFO "smsc47b397: found SMSC LPC47B397-NC "
- "(base address 0x%04x, revision %u)\n", *addr, rev);
+ printk(KERN_INFO "smsc47b397: found SMSC %s "
+ "(base address 0x%04x, revision %u)\n",
+ id == 0x81 ? "SCH5307-NS" : "LPC47B397-NC", *addr, rev);
superio_exit();
return 0;
diff --git a/drivers/hwmon/smsc47m1.c b/drivers/hwmon/smsc47m1.c
index c9cc683eba4a..5905c1af88f2 100644
--- a/drivers/hwmon/smsc47m1.c
+++ b/drivers/hwmon/smsc47m1.c
@@ -3,7 +3,7 @@
for hardware monitoring
Supports the SMSC LPC47B27x, LPC47M10x, LPC47M13x, LPC47M14x,
- LPC47M15x and LPC47M192 Super-I/O chips.
+ LPC47M15x, LPC47M192 and LPC47M997 Super-I/O chips.
Copyright (C) 2002 Mark D. Studebaker <mdsxyz123@yahoo.com>
Copyright (C) 2004 Jean Delvare <khali@linux-fr.org>
@@ -356,6 +356,8 @@ static int __init smsc47m1_find(unsigned short *addr)
* 0x5F) and LPC47B27x (device id 0x51) have fan control.
* The LPC47M15x and LPC47M192 chips "with hardware monitoring block"
* can do much more besides (device id 0x60).
+ * The LPC47M997 is undocumented, but seems to be compatible with
+ * the LPC47M192, and has the same device id.
*/
if (val == 0x51)
printk(KERN_INFO "smsc47m1: Found SMSC LPC47B27x\n");
@@ -364,7 +366,8 @@ static int __init smsc47m1_find(unsigned short *addr)
else if (val == 0x5F)
printk(KERN_INFO "smsc47m1: Found SMSC LPC47M14x\n");
else if (val == 0x60)
- printk(KERN_INFO "smsc47m1: Found SMSC LPC47M15x/LPC47M192\n");
+ printk(KERN_INFO "smsc47m1: Found SMSC "
+ "LPC47M15x/LPC47M192/LPC47M997\n");
else {
superio_exit();
return -ENODEV;
@@ -396,11 +399,10 @@ static int smsc47m1_detect(struct i2c_adapter *adapter)
return -EBUSY;
}
- if (!(data = kmalloc(sizeof(struct smsc47m1_data), GFP_KERNEL))) {
+ if (!(data = kzalloc(sizeof(struct smsc47m1_data), GFP_KERNEL))) {
err = -ENOMEM;
goto error_release;
}
- memset(data, 0x00, sizeof(struct smsc47m1_data));
new_client = &data->client;
i2c_set_clientdata(new_client, data);
diff --git a/drivers/hwmon/via686a.c b/drivers/hwmon/via686a.c
index 05ddc88e7dd2..6f696f897176 100644
--- a/drivers/hwmon/via686a.c
+++ b/drivers/hwmon/via686a.c
@@ -44,7 +44,7 @@
/* If force_addr is set to anything different from 0, we forcibly enable
the device at the given address. */
-static unsigned short force_addr = 0;
+static unsigned short force_addr;
module_param(force_addr, ushort, 0);
MODULE_PARM_DESC(force_addr,
"Initialize the base address of the sensors");
@@ -198,7 +198,7 @@ static inline u8 FAN_TO_REG(long rpm, int div)
but the function is very linear in the useful range (0-80 deg C), so
we'll just use linear interpolation for 10-bit readings.) So, tempLUT
is the temp at via register values 0-255: */
-static const long tempLUT[] =
+static const s16 tempLUT[] =
{ -709, -688, -667, -646, -627, -607, -589, -570, -553, -536, -519,
-503, -487, -471, -456, -442, -428, -414, -400, -387, -375,
-362, -350, -339, -327, -316, -305, -295, -285, -275, -265,
@@ -270,7 +270,7 @@ static inline u8 TEMP_TO_REG(long val)
}
/* for 8-bit temperature hyst and over registers */
-#define TEMP_FROM_REG(val) (tempLUT[(val)] * 100)
+#define TEMP_FROM_REG(val) ((long)tempLUT[val] * 100)
/* for 10-bit temperature readings */
static inline long TEMP_FROM_REG10(u16 val)
@@ -589,10 +589,8 @@ static int via686a_detect(struct i2c_adapter *adapter)
u16 val;
/* 8231 requires multiple of 256, we enforce that on 686 as well */
- if (force_addr)
- address = force_addr & 0xFF00;
-
if (force_addr) {
+ address = force_addr & 0xFF00;
dev_warn(&adapter->dev, "forcing ISA address 0x%04X\n",
address);
if (PCIBIOS_SUCCESSFUL !=
@@ -603,11 +601,17 @@ static int via686a_detect(struct i2c_adapter *adapter)
pci_read_config_word(s_bridge, VIA686A_ENABLE_REG, &val))
return -ENODEV;
if (!(val & 0x0001)) {
- dev_warn(&adapter->dev, "enabling sensors\n");
- if (PCIBIOS_SUCCESSFUL !=
- pci_write_config_word(s_bridge, VIA686A_ENABLE_REG,
- val | 0x0001))
+ if (force_addr) {
+ dev_info(&adapter->dev, "enabling sensors\n");
+ if (PCIBIOS_SUCCESSFUL !=
+ pci_write_config_word(s_bridge, VIA686A_ENABLE_REG,
+ val | 0x0001))
+ return -ENODEV;
+ } else {
+ dev_warn(&adapter->dev, "sensors disabled - enable "
+ "with force_addr=0x%x\n", address);
return -ENODEV;
+ }
}
/* Reserve the ISA region */
@@ -617,11 +621,10 @@ static int via686a_detect(struct i2c_adapter *adapter)
return -ENODEV;
}
- if (!(data = kmalloc(sizeof(struct via686a_data), GFP_KERNEL))) {
+ if (!(data = kzalloc(sizeof(struct via686a_data), GFP_KERNEL))) {
err = -ENOMEM;
goto exit_release;
}
- memset(data, 0, sizeof(struct via686a_data));
new_client = &data->client;
i2c_set_clientdata(new_client, data);
@@ -708,7 +711,6 @@ static int via686a_detach_client(struct i2c_client *client)
return 0;
}
-/* Called when we have found a new VIA686A. Set limits, etc. */
static void via686a_init_client(struct i2c_client *client)
{
u8 reg;
diff --git a/drivers/hwmon/w83627ehf.c b/drivers/hwmon/w83627ehf.c
index b60efe8f8b26..eee22a57e929 100644
--- a/drivers/hwmon/w83627ehf.c
+++ b/drivers/hwmon/w83627ehf.c
@@ -105,7 +105,9 @@ superio_exit(void)
* ISA constants
*/
-#define REGION_LENGTH 8
+#define REGION_ALIGNMENT ~7
+#define REGION_OFFSET 5
+#define REGION_LENGTH 2
#define ADDR_REG_OFFSET 5
#define DATA_REG_OFFSET 6
@@ -673,16 +675,16 @@ static int w83627ehf_detect(struct i2c_adapter *adapter)
struct w83627ehf_data *data;
int i, err = 0;
- if (!request_region(address, REGION_LENGTH, w83627ehf_driver.name)) {
+ if (!request_region(address + REGION_OFFSET, REGION_LENGTH,
+ w83627ehf_driver.name)) {
err = -EBUSY;
goto exit;
}
- if (!(data = kmalloc(sizeof(struct w83627ehf_data), GFP_KERNEL))) {
+ if (!(data = kzalloc(sizeof(struct w83627ehf_data), GFP_KERNEL))) {
err = -ENOMEM;
goto exit_release;
}
- memset(data, 0, sizeof(struct w83627ehf_data));
client = &data->client;
i2c_set_clientdata(client, data);
@@ -762,7 +764,7 @@ exit_detach:
exit_free:
kfree(data);
exit_release:
- release_region(address, REGION_LENGTH);
+ release_region(address + REGION_OFFSET, REGION_LENGTH);
exit:
return err;
}
@@ -776,7 +778,7 @@ static int w83627ehf_detach_client(struct i2c_client *client)
if ((err = i2c_detach_client(client)))
return err;
- release_region(client->addr, REGION_LENGTH);
+ release_region(client->addr + REGION_OFFSET, REGION_LENGTH);
kfree(data);
return 0;
@@ -807,7 +809,7 @@ static int __init w83627ehf_find(int sioaddr, unsigned short *addr)
superio_select(W83627EHF_LD_HWM);
val = (superio_inb(SIO_REG_ADDR) << 8)
| superio_inb(SIO_REG_ADDR + 1);
- *addr = val & ~(REGION_LENGTH - 1);
+ *addr = val & REGION_ALIGNMENT;
if (*addr == 0) {
superio_exit();
return -ENODEV;
diff --git a/drivers/hwmon/w83627hf.c b/drivers/hwmon/w83627hf.c
index 3479dc5208e2..4e9a04e1f08e 100644
--- a/drivers/hwmon/w83627hf.c
+++ b/drivers/hwmon/w83627hf.c
@@ -142,10 +142,14 @@ superio_exit(void)
#define WINB_BASE_REG 0x60
/* Constants specified below */
-/* Length of ISA address segment */
-#define WINB_EXTENT 8
+/* Alignment of the base address */
+#define WINB_ALIGNMENT ~7
-/* Where are the ISA address/data registers relative to the base address */
+/* Offset & size of I/O region we are interested in */
+#define WINB_REGION_OFFSET 5
+#define WINB_REGION_SIZE 2
+
+/* Where are the sensors address/data registers relative to the base address */
#define W83781D_ADDR_REG_OFFSET 5
#define W83781D_DATA_REG_OFFSET 6
@@ -176,11 +180,10 @@ superio_exit(void)
#define W83781D_REG_BANK 0x4E
#define W83781D_REG_CONFIG 0x40
-#define W83781D_REG_ALARM1 0x41
-#define W83781D_REG_ALARM2 0x42
-#define W83781D_REG_ALARM3 0x450
+#define W83781D_REG_ALARM1 0x459
+#define W83781D_REG_ALARM2 0x45A
+#define W83781D_REG_ALARM3 0x45B
-#define W83781D_REG_IRQ 0x4C
#define W83781D_REG_BEEP_CONFIG 0x4D
#define W83781D_REG_BEEP_INTS1 0x56
#define W83781D_REG_BEEP_INTS2 0x57
@@ -197,7 +200,6 @@ superio_exit(void)
#define W83627HF_REG_PWM1 0x5A
#define W83627HF_REG_PWM2 0x5B
-#define W83627HF_REG_PWMCLK12 0x5C
#define W83627THF_REG_PWM1 0x01 /* 697HF and 637HF too */
#define W83627THF_REG_PWM2 0x03 /* 697HF and 637HF too */
@@ -981,7 +983,7 @@ static int __init w83627hf_find(int sioaddr, unsigned short *addr)
superio_select(W83627HF_LD_HWM);
val = (superio_inb(WINB_BASE_REG) << 8) |
superio_inb(WINB_BASE_REG + 1);
- *addr = val & ~(WINB_EXTENT - 1);
+ *addr = val & WINB_ALIGNMENT;
if (*addr == 0 && force_addr == 0) {
superio_exit();
return -ENODEV;
@@ -1000,9 +1002,10 @@ static int w83627hf_detect(struct i2c_adapter *adapter)
const char *client_name = "";
if(force_addr)
- address = force_addr & ~(WINB_EXTENT - 1);
+ address = force_addr & WINB_ALIGNMENT;
- if (!request_region(address, WINB_EXTENT, w83627hf_driver.name)) {
+ if (!request_region(address + WINB_REGION_OFFSET, WINB_REGION_SIZE,
+ w83627hf_driver.name)) {
err = -EBUSY;
goto ERROR0;
}
@@ -1041,11 +1044,10 @@ static int w83627hf_detect(struct i2c_adapter *adapter)
client structure, even though we cannot fill it completely yet.
But it allows us to access w83627hf_{read,write}_value. */
- if (!(data = kmalloc(sizeof(struct w83627hf_data), GFP_KERNEL))) {
+ if (!(data = kzalloc(sizeof(struct w83627hf_data), GFP_KERNEL))) {
err = -ENOMEM;
goto ERROR1;
}
- memset(data, 0, sizeof(struct w83627hf_data));
new_client = &data->client;
i2c_set_clientdata(new_client, data);
@@ -1148,7 +1150,7 @@ static int w83627hf_detect(struct i2c_adapter *adapter)
ERROR2:
kfree(data);
ERROR1:
- release_region(address, WINB_EXTENT);
+ release_region(address + WINB_REGION_OFFSET, WINB_REGION_SIZE);
ERROR0:
return err;
}
@@ -1163,7 +1165,7 @@ static int w83627hf_detach_client(struct i2c_client *client)
if ((err = i2c_detach_client(client)))
return err;
- release_region(client->addr, WINB_EXTENT);
+ release_region(client->addr + WINB_REGION_OFFSET, WINB_REGION_SIZE);
kfree(data);
return 0;
@@ -1275,7 +1277,6 @@ static int w83627hf_write_value(struct i2c_client *client, u16 reg, u16 value)
return 0;
}
-/* Called when we have found a new W83781D. It should set limits, etc. */
static void w83627hf_init_client(struct i2c_client *client)
{
struct w83627hf_data *data = i2c_get_clientdata(client);
@@ -1368,19 +1369,6 @@ static void w83627hf_init_client(struct i2c_client *client)
W83781D_REG_TEMP3_CONFIG, tmp & 0xfe);
}
}
-
- if (type == w83627hf) {
- /* enable PWM2 control (can't hurt since PWM reg
- should have been reset to 0xff) */
- w83627hf_write_value(client, W83627HF_REG_PWMCLK12,
- 0x19);
- }
- /* enable comparator mode for temp2 and temp3 so
- alarm indication will work correctly */
- i = w83627hf_read_value(client, W83781D_REG_IRQ);
- if (!(i & 0x40))
- w83627hf_write_value(client, W83781D_REG_IRQ,
- i | 0x40);
}
/* Start monitoring */
@@ -1404,7 +1392,7 @@ static struct w83627hf_data *w83627hf_update_device(struct device *dev)
/* skip missing sensors */
if (((data->type == w83697hf) && (i == 1)) ||
((data->type == w83627thf || data->type == w83637hf)
- && (i == 4 || i == 5)))
+ && (i == 5 || i == 6)))
continue;
data->in[i] =
w83627hf_read_value(client, W83781D_REG_IN(i));
diff --git a/drivers/hwmon/w83781d.c b/drivers/hwmon/w83781d.c
index 4c43337ca780..ffdb3a03e2b5 100644
--- a/drivers/hwmon/w83781d.c
+++ b/drivers/hwmon/w83781d.c
@@ -889,12 +889,11 @@ w83781d_detect_subclients(struct i2c_adapter *adapter, int address, int kind,
const char *client_name = "";
struct w83781d_data *data = i2c_get_clientdata(new_client);
- data->lm75[0] = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
+ data->lm75[0] = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
if (!(data->lm75[0])) {
err = -ENOMEM;
goto ERROR_SC_0;
}
- memset(data->lm75[0], 0x00, sizeof (struct i2c_client));
id = i2c_adapter_id(adapter);
@@ -919,13 +918,11 @@ w83781d_detect_subclients(struct i2c_adapter *adapter, int address, int kind,
}
if (kind != w83783s) {
-
- data->lm75[1] = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
+ data->lm75[1] = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
if (!(data->lm75[1])) {
err = -ENOMEM;
goto ERROR_SC_1;
}
- memset(data->lm75[1], 0x0, sizeof(struct i2c_client));
if (force_subclients[0] == id &&
force_subclients[1] == address) {
@@ -979,11 +976,9 @@ w83781d_detect_subclients(struct i2c_adapter *adapter, int address, int kind,
ERROR_SC_3:
i2c_detach_client(data->lm75[0]);
ERROR_SC_2:
- if (data->lm75[1])
- kfree(data->lm75[1]);
+ kfree(data->lm75[1]);
ERROR_SC_1:
- if (data->lm75[0])
- kfree(data->lm75[0]);
+ kfree(data->lm75[0]);
ERROR_SC_0:
return err;
}
@@ -1064,11 +1059,10 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind)
client structure, even though we cannot fill it completely yet.
But it allows us to access w83781d_{read,write}_value. */
- if (!(data = kmalloc(sizeof(struct w83781d_data), GFP_KERNEL))) {
+ if (!(data = kzalloc(sizeof(struct w83781d_data), GFP_KERNEL))) {
err = -ENOMEM;
goto ERROR1;
}
- memset(data, 0, sizeof(struct w83781d_data));
new_client = &data->client;
i2c_set_clientdata(new_client, data);
@@ -1451,7 +1445,6 @@ w83781d_write_value(struct i2c_client *client, u16 reg, u16 value)
return 0;
}
-/* Called when we have found a new W83781D. It should set limits, etc. */
static void
w83781d_init_client(struct i2c_client *client)
{
diff --git a/drivers/hwmon/w83792d.c b/drivers/hwmon/w83792d.c
index ba0c28015f6a..4be59dbb78c4 100644
--- a/drivers/hwmon/w83792d.c
+++ b/drivers/hwmon/w83792d.c
@@ -1086,11 +1086,10 @@ w83792d_create_subclient(struct i2c_adapter *adapter,
int err;
struct i2c_client *sub_client;
- (*sub_cli) = sub_client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
+ (*sub_cli) = sub_client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
if (!(sub_client)) {
return -ENOMEM;
}
- memset(sub_client, 0x00, sizeof(struct i2c_client));
sub_client->addr = 0x48 + addr;
i2c_set_clientdata(sub_client, NULL);
sub_client->adapter = adapter;
@@ -1184,11 +1183,10 @@ w83792d_detect(struct i2c_adapter *adapter, int address, int kind)
client structure, even though we cannot fill it completely yet.
But it allows us to access w83792d_{read,write}_value. */
- if (!(data = kmalloc(sizeof(struct w83792d_data), GFP_KERNEL))) {
+ if (!(data = kzalloc(sizeof(struct w83792d_data), GFP_KERNEL))) {
err = -ENOMEM;
goto ERROR0;
}
- memset(data, 0, sizeof(struct w83792d_data));
new_client = &data->client;
i2c_set_clientdata(new_client, data);
@@ -1429,7 +1427,6 @@ w83792d_write_value(struct i2c_client *client, u8 reg, u8 value)
return 0;
}
-/* Called when we have found a new W83792D. It should set limits, etc. */
static void
w83792d_init_client(struct i2c_client *client)
{
diff --git a/drivers/hwmon/w83l785ts.c b/drivers/hwmon/w83l785ts.c
index 133e34ab1d0a..f495b6378668 100644
--- a/drivers/hwmon/w83l785ts.c
+++ b/drivers/hwmon/w83l785ts.c
@@ -37,6 +37,7 @@
#include <linux/jiffies.h>
#include <linux/i2c.h>
#include <linux/hwmon.h>
+#include <linux/hwmon-sysfs.h>
#include <linux/err.h>
/* How many retries on register read error */
@@ -73,7 +74,7 @@ I2C_CLIENT_INSMOD_1(w83l785ts);
* The W83L785TS-S uses signed 8-bit values.
*/
-#define TEMP_FROM_REG(val) ((val & 0x80 ? val-0x100 : val) * 1000)
+#define TEMP_FROM_REG(val) ((val) * 1000)
/*
* Functions declaration
@@ -111,27 +112,24 @@ struct w83l785ts_data {
unsigned long last_updated; /* in jiffies */
/* registers values */
- u8 temp, temp_over;
+ s8 temp[2]; /* 0: input
+ 1: critical limit */
};
/*
* Sysfs stuff
*/
-static ssize_t show_temp(struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t show_temp(struct device *dev, struct device_attribute *devattr,
+ char *buf)
{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
struct w83l785ts_data *data = w83l785ts_update_device(dev);
- return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp));
+ return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp[attr->index]));
}
-static ssize_t show_temp_over(struct device *dev, struct device_attribute *attr, char *buf)
-{
- struct w83l785ts_data *data = w83l785ts_update_device(dev);
- return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_over));
-}
-
-static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL);
-static DEVICE_ATTR(temp1_max, S_IRUGO, show_temp_over, NULL);
+static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, 0);
+static SENSOR_DEVICE_ATTR(temp1_max, S_IRUGO, show_temp, NULL, 1);
/*
* Real code
@@ -158,12 +156,10 @@ static int w83l785ts_detect(struct i2c_adapter *adapter, int address, int kind)
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
goto exit;
- if (!(data = kmalloc(sizeof(struct w83l785ts_data), GFP_KERNEL))) {
+ if (!(data = kzalloc(sizeof(struct w83l785ts_data), GFP_KERNEL))) {
err = -ENOMEM;
goto exit;
}
- memset(data, 0, sizeof(struct w83l785ts_data));
-
/* The common I2C client data is placed right before the
* W83L785TS-specific data. */
@@ -228,7 +224,7 @@ static int w83l785ts_detect(struct i2c_adapter *adapter, int address, int kind)
init_MUTEX(&data->update_lock);
/* Default values in case the first read fails (unlikely). */
- data->temp_over = data->temp = 0;
+ data->temp[1] = data->temp[0] = 0;
/* Tell the I2C layer a new client has arrived. */
if ((err = i2c_attach_client(new_client)))
@@ -246,8 +242,10 @@ static int w83l785ts_detect(struct i2c_adapter *adapter, int address, int kind)
goto exit_detach;
}
- device_create_file(&new_client->dev, &dev_attr_temp1_input);
- device_create_file(&new_client->dev, &dev_attr_temp1_max);
+ device_create_file(&new_client->dev,
+ &sensor_dev_attr_temp1_input.dev_attr);
+ device_create_file(&new_client->dev,
+ &sensor_dev_attr_temp1_max.dev_attr);
return 0;
@@ -305,10 +303,10 @@ static struct w83l785ts_data *w83l785ts_update_device(struct device *dev)
if (!data->valid || time_after(jiffies, data->last_updated + HZ * 2)) {
dev_dbg(&client->dev, "Updating w83l785ts data.\n");
- data->temp = w83l785ts_read_value(client,
- W83L785TS_REG_TEMP, data->temp);
- data->temp_over = w83l785ts_read_value(client,
- W83L785TS_REG_TEMP_OVER, data->temp_over);
+ data->temp[0] = w83l785ts_read_value(client,
+ W83L785TS_REG_TEMP, data->temp[0]);
+ data->temp[1] = w83l785ts_read_value(client,
+ W83L785TS_REG_TEMP_OVER, data->temp[1]);
data->last_updated = jiffies;
data->valid = 1;
diff --git a/drivers/i2c/algos/i2c-algo-pca.c b/drivers/i2c/algos/i2c-algo-pca.c
index beb10edfe9c1..82946acab4c7 100644
--- a/drivers/i2c/algos/i2c-algo-pca.c
+++ b/drivers/i2c/algos/i2c-algo-pca.c
@@ -34,7 +34,7 @@
#define DEB2(fmt, args...) do { if (i2c_debug>=2) printk(fmt, ## args); } while(0)
#define DEB3(fmt, args...) do { if (i2c_debug>=3) printk(fmt, ## args); } while(0)
-static int i2c_debug=0;
+static int i2c_debug;
#define pca_outw(adap, reg, val) adap->write_byte(adap, reg, val)
#define pca_inw(adap, reg) adap->read_byte(adap, reg)
diff --git a/drivers/i2c/algos/i2c-algo-sibyte.c b/drivers/i2c/algos/i2c-algo-sibyte.c
index 8ed5ad12552f..938848ae162d 100644
--- a/drivers/i2c/algos/i2c-algo-sibyte.c
+++ b/drivers/i2c/algos/i2c-algo-sibyte.c
@@ -42,7 +42,7 @@
/* module parameters:
*/
-static int bit_scan=0; /* have a look at what's hanging 'round */
+static int bit_scan; /* have a look at what's hanging 'round */
static int smbus_xfer(struct i2c_adapter *i2c_adap, u16 addr,
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index 3badfec75b1c..4010fe92e72b 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -135,11 +135,12 @@ config I2C_I810
help
If you say yes to this option, support will be included for the Intel
810/815 family of mainboard I2C interfaces. Specifically, the
- following versions of the chipset is supported:
+ following versions of the chipset are supported:
i810AA
i810AB
i810E
i815
+ i845G
This driver can also be built as a module. If so, the module
will be called i2c-i810.
diff --git a/drivers/i2c/busses/i2c-ali1535.c b/drivers/i2c/busses/i2c-ali1535.c
index f021acd2674e..3eb47890db40 100644
--- a/drivers/i2c/busses/i2c-ali1535.c
+++ b/drivers/i2c/busses/i2c-ali1535.c
@@ -134,7 +134,7 @@
/* -> Read = 1 */
#define ALI1535_SMBIO_EN 0x04 /* SMB I/O Space enable */
-
+static struct pci_driver ali1535_driver;
static unsigned short ali1535_smba;
static DECLARE_MUTEX(i2c_ali1535_sem);
@@ -162,7 +162,8 @@ static int ali1535_setup(struct pci_dev *dev)
goto exit;
}
- if (!request_region(ali1535_smba, ALI1535_SMB_IOSIZE, "ali1535-smb")) {
+ if (!request_region(ali1535_smba, ALI1535_SMB_IOSIZE,
+ ali1535_driver.name)) {
dev_err(&dev->dev, "ALI1535_smb region 0x%x already in use!\n",
ali1535_smba);
goto exit;
@@ -480,7 +481,6 @@ static struct i2c_adapter ali1535_adapter = {
.owner = THIS_MODULE,
.class = I2C_CLASS_HWMON,
.algo = &smbus_algorithm,
- .name = "unset",
};
static struct pci_device_id ali1535_ids[] = {
diff --git a/drivers/i2c/busses/i2c-ali1563.c b/drivers/i2c/busses/i2c-ali1563.c
index 86947504aea1..e6f63208fc4a 100644
--- a/drivers/i2c/busses/i2c-ali1563.c
+++ b/drivers/i2c/busses/i2c-ali1563.c
@@ -60,6 +60,7 @@
#define HST_CNTL2_SIZEMASK 0x38
+static struct pci_driver ali1563_pci_driver;
static unsigned short ali1563_smba;
static int ali1563_transaction(struct i2c_adapter * a, int size)
@@ -350,7 +351,8 @@ static int __devinit ali1563_setup(struct pci_dev * dev)
dev_warn(&dev->dev,"ali1563_smba Uninitialized\n");
goto Err;
}
- if (!request_region(ali1563_smba,ALI1563_SMB_IOSIZE,"i2c-ali1563")) {
+ if (!request_region(ali1563_smba, ALI1563_SMB_IOSIZE,
+ ali1563_pci_driver.name)) {
dev_warn(&dev->dev,"Could not allocate I/O space");
goto Err;
}
@@ -406,7 +408,7 @@ static struct pci_device_id __devinitdata ali1563_id_table[] = {
MODULE_DEVICE_TABLE (pci, ali1563_id_table);
static struct pci_driver ali1563_pci_driver = {
- .name = "ali1563_i2c",
+ .name = "ali1563_smbus",
.id_table = ali1563_id_table,
.probe = ali1563_probe,
.remove = __devexit_p(ali1563_remove),
diff --git a/drivers/i2c/busses/i2c-ali15x3.c b/drivers/i2c/busses/i2c-ali15x3.c
index b3f50bff39a0..7a5c0941dbc1 100644
--- a/drivers/i2c/busses/i2c-ali15x3.c
+++ b/drivers/i2c/busses/i2c-ali15x3.c
@@ -125,12 +125,13 @@
/* If force_addr is set to anything different from 0, we forcibly enable
the device at the given address. */
-static u16 force_addr = 0;
+static u16 force_addr;
module_param(force_addr, ushort, 0);
MODULE_PARM_DESC(force_addr,
"Initialize the base address of the i2c controller");
-static unsigned short ali15x3_smba = 0;
+static struct pci_driver ali15x3_driver;
+static unsigned short ali15x3_smba;
static int ali15x3_setup(struct pci_dev *ALI15X3_dev)
{
@@ -166,7 +167,8 @@ static int ali15x3_setup(struct pci_dev *ALI15X3_dev)
if(force_addr)
ali15x3_smba = force_addr & ~(ALI15X3_SMB_IOSIZE - 1);
- if (!request_region(ali15x3_smba, ALI15X3_SMB_IOSIZE, "ali15x3-smb")) {
+ if (!request_region(ali15x3_smba, ALI15X3_SMB_IOSIZE,
+ ali15x3_driver.name)) {
dev_err(&ALI15X3_dev->dev,
"ALI15X3_smb region 0x%x already in use!\n",
ali15x3_smba);
@@ -470,7 +472,6 @@ static struct i2c_adapter ali15x3_adapter = {
.owner = THIS_MODULE,
.class = I2C_CLASS_HWMON,
.algo = &smbus_algorithm,
- .name = "unset",
};
static struct pci_device_id ali15x3_ids[] = {
diff --git a/drivers/i2c/busses/i2c-amd756-s4882.c b/drivers/i2c/busses/i2c-amd756-s4882.c
index 4e553e8c5cba..56c7d987590f 100644
--- a/drivers/i2c/busses/i2c-amd756-s4882.c
+++ b/drivers/i2c/busses/i2c-amd756-s4882.c
@@ -169,12 +169,12 @@ static int __init amd756_s4882_init(void)
init_MUTEX(&amd756_lock);
/* Define the 5 virtual adapters and algorithms structures */
- if (!(s4882_adapter = kmalloc(5 * sizeof(struct i2c_adapter),
+ if (!(s4882_adapter = kzalloc(5 * sizeof(struct i2c_adapter),
GFP_KERNEL))) {
error = -ENOMEM;
goto ERROR1;
}
- if (!(s4882_algo = kmalloc(5 * sizeof(struct i2c_algorithm),
+ if (!(s4882_algo = kzalloc(5 * sizeof(struct i2c_algorithm),
GFP_KERNEL))) {
error = -ENOMEM;
goto ERROR2;
@@ -245,10 +245,8 @@ static void __exit amd756_s4882_exit(void)
kfree(s4882_adapter);
s4882_adapter = NULL;
}
- if (s4882_algo) {
- kfree(s4882_algo);
- s4882_algo = NULL;
- }
+ kfree(s4882_algo);
+ s4882_algo = NULL;
/* Restore physical bus */
if (i2c_add_adapter(&amd756_smbus))
diff --git a/drivers/i2c/busses/i2c-amd756.c b/drivers/i2c/busses/i2c-amd756.c
index 6ad0603384b8..1750dedaf4b5 100644
--- a/drivers/i2c/busses/i2c-amd756.c
+++ b/drivers/i2c/busses/i2c-amd756.c
@@ -85,8 +85,8 @@
#define AMD756_PROCESS_CALL 0x04
#define AMD756_BLOCK_DATA 0x05
-
-static unsigned short amd756_ioport = 0;
+static struct pci_driver amd756_driver;
+static unsigned short amd756_ioport;
/*
SMBUS event = I/O 28-29 bit 11
@@ -303,7 +303,6 @@ struct i2c_adapter amd756_smbus = {
.owner = THIS_MODULE,
.class = I2C_CLASS_HWMON,
.algo = &smbus_algorithm,
- .name = "unset",
};
enum chiptype { AMD756, AMD766, AMD768, NFORCE, AMD8111 };
@@ -365,7 +364,7 @@ static int __devinit amd756_probe(struct pci_dev *pdev,
amd756_ioport += SMB_ADDR_OFFSET;
}
- if (!request_region(amd756_ioport, SMB_IOSIZE, "amd756-smbus")) {
+ if (!request_region(amd756_ioport, SMB_IOSIZE, amd756_driver.name)) {
dev_err(&pdev->dev, "SMB region 0x%x already in use!\n",
amd756_ioport);
return -ENODEV;
diff --git a/drivers/i2c/busses/i2c-amd8111.c b/drivers/i2c/busses/i2c-amd8111.c
index 45ea24ba14d5..e5ef560e686a 100644
--- a/drivers/i2c/busses/i2c-amd8111.c
+++ b/drivers/i2c/busses/i2c-amd8111.c
@@ -30,6 +30,8 @@ struct amd_smbus {
int size;
};
+static struct pci_driver amd8111_driver;
+
/*
* AMD PCI control registers definitions.
*/
@@ -242,7 +244,6 @@ static s32 amd8111_access(struct i2c_adapter * adap, u16 addr, unsigned short fl
break;
case I2C_SMBUS_BLOCK_PROC_CALL:
- protocol |= pec;
len = min_t(u8, data->block[0], 31);
amd_ec_write(smbus, AMD_SMB_CMD, command);
amd_ec_write(smbus, AMD_SMB_BCNT, len);
@@ -252,13 +253,6 @@ static s32 amd8111_access(struct i2c_adapter * adap, u16 addr, unsigned short fl
read_write = I2C_SMBUS_READ;
break;
- case I2C_SMBUS_WORD_DATA_PEC:
- case I2C_SMBUS_BLOCK_DATA_PEC:
- case I2C_SMBUS_PROC_CALL_PEC:
- case I2C_SMBUS_BLOCK_PROC_CALL_PEC:
- dev_warn(&adap->dev, "Unexpected software PEC transaction %d\n.", size);
- return -1;
-
default:
dev_warn(&adap->dev, "Unsupported transaction %d\n", size);
return -1;
@@ -343,16 +337,15 @@ static int __devinit amd8111_probe(struct pci_dev *dev, const struct pci_device_
if (~pci_resource_flags(dev, 0) & IORESOURCE_IO)
return -ENODEV;
- smbus = kmalloc(sizeof(struct amd_smbus), GFP_KERNEL);
+ smbus = kzalloc(sizeof(struct amd_smbus), GFP_KERNEL);
if (!smbus)
return -ENOMEM;
- memset(smbus, 0, sizeof(struct amd_smbus));
smbus->dev = dev;
smbus->base = pci_resource_start(dev, 0);
smbus->size = pci_resource_len(dev, 0);
- if (!request_region(smbus->base, smbus->size, "amd8111 SMBus 2.0"))
+ if (!request_region(smbus->base, smbus->size, amd8111_driver.name))
goto out_kfree;
smbus->adapter.owner = THIS_MODULE;
diff --git a/drivers/i2c/busses/i2c-elektor.c b/drivers/i2c/busses/i2c-elektor.c
index 6930b660e508..59f8308c2356 100644
--- a/drivers/i2c/busses/i2c-elektor.c
+++ b/drivers/i2c/busses/i2c-elektor.c
@@ -22,7 +22,7 @@
/* With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi> and even
Frodo Looijaard <frodol@dds.nl> */
-/* Partialy rewriten by Oleg I. Vdovikin for mmapped support of
+/* Partialy rewriten by Oleg I. Vdovikin for mmapped support of
for Alpha Processor Inc. UP-2000(+) boards */
#include <linux/kernel.h>
@@ -46,12 +46,14 @@
#define DEFAULT_BASE 0x330
static int base;
+static u8 __iomem *base_iomem;
+
static int irq;
static int clock = 0x1c;
static int own = 0x55;
static int mmapped;
-/* vdovikin: removed static struct i2c_pcf_isa gpi; code -
+/* vdovikin: removed static struct i2c_pcf_isa gpi; code -
this module in real supports only one device, due to missing arguments
in some functions, called from the algo-pcf module. Sometimes it's
need to be rewriten - but for now just remove this for simpler reading */
@@ -60,40 +62,33 @@ static wait_queue_head_t pcf_wait;
static int pcf_pending;
static spinlock_t lock;
+static struct i2c_adapter pcf_isa_ops;
+
/* ----- local functions ---------------------------------------------- */
static void pcf_isa_setbyte(void *data, int ctl, int val)
{
- int address = ctl ? (base + 1) : base;
+ u8 __iomem *address = ctl ? (base_iomem + 1) : base_iomem;
/* enable irq if any specified for serial operation */
if (ctl && irq && (val & I2C_PCF_ESO)) {
val |= I2C_PCF_ENI;
}
- pr_debug("i2c-elektor: Write 0x%X 0x%02X\n", address, val & 255);
-
- switch (mmapped) {
- case 0: /* regular I/O */
- outb(val, address);
- break;
- case 2: /* double mapped I/O needed for UP2000 board,
- I don't know why this... */
- writeb(val, (void *)address);
- /* fall */
- case 1: /* memory mapped I/O */
- writeb(val, (void *)address);
- break;
- }
+ pr_debug("%s: Write %p 0x%02X\n", pcf_isa_ops.name, address, val);
+ iowrite8(val, address);
+#ifdef __alpha__
+ /* API UP2000 needs some hardware fudging to make the write stick */
+ iowrite8(val, address);
+#endif
}
static int pcf_isa_getbyte(void *data, int ctl)
{
- int address = ctl ? (base + 1) : base;
- int val = mmapped ? readb((void *)address) : inb(address);
-
- pr_debug("i2c-elektor: Read 0x%X 0x%02X\n", address, val);
+ u8 __iomem *address = ctl ? (base_iomem + 1) : base_iomem;
+ int val = ioread8(address);
+ pr_debug("%s: Read %p 0x%02X\n", pcf_isa_ops.name, address, val);
return (val);
}
@@ -149,16 +144,40 @@ static int pcf_isa_init(void)
{
spin_lock_init(&lock);
if (!mmapped) {
- if (!request_region(base, 2, "i2c (isa bus adapter)")) {
- printk(KERN_ERR
- "i2c-elektor: requested I/O region (0x%X:2) "
- "is in use.\n", base);
+ if (!request_region(base, 2, pcf_isa_ops.name)) {
+ printk(KERN_ERR "%s: requested I/O region (%#x:2) is "
+ "in use\n", pcf_isa_ops.name, base);
+ return -ENODEV;
+ }
+ base_iomem = ioport_map(base, 2);
+ if (!base_iomem) {
+ printk(KERN_ERR "%s: remap of I/O region %#x failed\n",
+ pcf_isa_ops.name, base);
+ release_region(base, 2);
+ return -ENODEV;
+ }
+ } else {
+ if (!request_mem_region(base, 2, pcf_isa_ops.name)) {
+ printk(KERN_ERR "%s: requested memory region (%#x:2) "
+ "is in use\n", pcf_isa_ops.name, base);
+ return -ENODEV;
+ }
+ base_iomem = ioremap(base, 2);
+ if (base_iomem == NULL) {
+ printk(KERN_ERR "%s: remap of memory region %#x "
+ "failed\n", pcf_isa_ops.name, base);
+ release_mem_region(base, 2);
return -ENODEV;
}
}
+ pr_debug("%s: registers %#x remapped to %p\n", pcf_isa_ops.name, base,
+ base_iomem);
+
if (irq > 0) {
- if (request_irq(irq, pcf_isa_handler, 0, "PCF8584", NULL) < 0) {
- printk(KERN_ERR "i2c-elektor: Request irq%d failed\n", irq);
+ if (request_irq(irq, pcf_isa_handler, 0, pcf_isa_ops.name,
+ NULL) < 0) {
+ printk(KERN_ERR "%s: Request irq%d failed\n",
+ pcf_isa_ops.name, irq);
irq = 0;
} else
enable_irq(irq);
@@ -186,47 +205,49 @@ static struct i2c_adapter pcf_isa_ops = {
.class = I2C_CLASS_HWMON,
.id = I2C_HW_P_ELEK,
.algo_data = &pcf_isa_data,
- .name = "PCF8584 ISA adapter",
+ .name = "i2c-elektor",
};
-static int __init i2c_pcfisa_init(void)
+static int __init i2c_pcfisa_init(void)
{
#ifdef __alpha__
- /* check to see we have memory mapped PCF8584 connected to the
+ /* check to see we have memory mapped PCF8584 connected to the
Cypress cy82c693 PCI-ISA bridge as on UP2000 board */
if (base == 0) {
struct pci_dev *cy693_dev;
-
- cy693_dev = pci_get_device(PCI_VENDOR_ID_CONTAQ,
+
+ cy693_dev = pci_get_device(PCI_VENDOR_ID_CONTAQ,
PCI_DEVICE_ID_CONTAQ_82C693, NULL);
if (cy693_dev) {
- char config;
+ unsigned char config;
/* yeap, we've found cypress, let's check config */
if (!pci_read_config_byte(cy693_dev, 0x47, &config)) {
-
- pr_debug("i2c-elektor: found cy82c693, config register 0x47 = 0x%02x.\n", config);
+
+ pr_debug("%s: found cy82c693, config "
+ "register 0x47 = 0x%02x\n",
+ pcf_isa_ops.name, config);
/* UP2000 board has this register set to 0xe1,
- but the most significant bit as seems can be
+ but the most significant bit as seems can be
reset during the proper initialisation
- sequence if guys from API decides to do that
- (so, we can even enable Tsunami Pchip
- window for the upper 1 Gb) */
+ sequence if guys from API decides to do that
+ (so, we can even enable Tsunami Pchip
+ window for the upper 1 Gb) */
/* so just check for ROMCS at 0xe0000,
- ROMCS enabled for writes
+ ROMCS enabled for writes
and external XD Bus buffer in use. */
if ((config & 0x7f) == 0x61) {
/* seems to be UP2000 like board */
base = 0xe0000;
- /* I don't know why we need to
- write twice */
- mmapped = 2;
- /* UP2000 drives ISA with
+ mmapped = 1;
+ /* UP2000 drives ISA with
8.25 MHz (PCI/4) clock
(this can be read from cypress) */
clock = I2C_PCF_CLK | I2C_PCF_TRNS90;
- printk(KERN_INFO "i2c-elektor: found API UP2000 like board, will probe PCF8584 later.\n");
+ pr_info("%s: found API UP2000 like "
+ "board, will probe PCF8584 "
+ "later\n", pcf_isa_ops.name);
}
}
pci_dev_put(cy693_dev);
@@ -236,12 +257,11 @@ static int __init i2c_pcfisa_init(void)
/* sanity checks for mmapped I/O */
if (mmapped && base < 0xc8000) {
- printk(KERN_ERR "i2c-elektor: incorrect base address (0x%0X) specified for mmapped I/O.\n", base);
+ printk(KERN_ERR "%s: incorrect base address (%#x) specified "
+ "for mmapped I/O\n", pcf_isa_ops.name, base);
return -ENODEV;
}
- printk(KERN_INFO "i2c-elektor: i2c pcf8584-isa adapter driver\n");
-
if (base == 0) {
base = DEFAULT_BASE;
}
@@ -251,8 +271,8 @@ static int __init i2c_pcfisa_init(void)
return -ENODEV;
if (i2c_pcf_add_bus(&pcf_isa_ops) < 0)
goto fail;
-
- printk(KERN_ERR "i2c-elektor: found device at %#x.\n", base);
+
+ dev_info(&pcf_isa_ops.dev, "found device at %#x\n", base);
return 0;
@@ -262,8 +282,13 @@ static int __init i2c_pcfisa_init(void)
free_irq(irq, NULL);
}
- if (!mmapped)
- release_region(base , 2);
+ if (!mmapped) {
+ ioport_unmap(base_iomem);
+ release_region(base, 2);
+ } else {
+ iounmap(base_iomem);
+ release_mem_region(base, 2);
+ }
return -ENODEV;
}
@@ -276,8 +301,13 @@ static void i2c_pcfisa_exit(void)
free_irq(irq, NULL);
}
- if (!mmapped)
- release_region(base , 2);
+ if (!mmapped) {
+ ioport_unmap(base_iomem);
+ release_region(base, 2);
+ } else {
+ iounmap(base_iomem);
+ release_mem_region(base, 2);
+ }
}
MODULE_AUTHOR("Hans Berglund <hb@spacetec.no>");
diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c
index 709beab76609..ac3eafa8aac0 100644
--- a/drivers/i2c/busses/i2c-i801.c
+++ b/drivers/i2c/busses/i2c-i801.c
@@ -52,10 +52,6 @@
#include <linux/i2c.h>
#include <asm/io.h>
-#ifdef I2C_FUNC_SMBUS_BLOCK_DATA_PEC
-#define HAVE_PEC
-#endif
-
/* I801 SMBus address offsets */
#define SMBHSTSTS (0 + i801_smba)
#define SMBHSTCNT (2 + i801_smba)
@@ -106,10 +102,11 @@ MODULE_PARM_DESC(force_addr,
"EXTREMELY DANGEROUS!");
static int i801_transaction(void);
-static int i801_block_transaction(union i2c_smbus_data *data,
- char read_write, int command);
+static int i801_block_transaction(union i2c_smbus_data *data, char read_write,
+ int command, int hwpec);
static unsigned short i801_smba;
+static struct pci_driver i801_driver;
static struct pci_dev *I801_dev;
static int isich4;
@@ -143,7 +140,7 @@ static int i801_setup(struct pci_dev *dev)
}
}
- if (!request_region(i801_smba, (isich4 ? 16 : 8), "i801-smbus")) {
+ if (!request_region(i801_smba, (isich4 ? 16 : 8), i801_driver.name)) {
dev_err(&dev->dev, "I801_smb region 0x%x already in use!\n",
i801_smba);
error_return = -EBUSY;
@@ -252,7 +249,7 @@ static int i801_transaction(void)
/* All-inclusive block transaction function */
static int i801_block_transaction(union i2c_smbus_data *data, char read_write,
- int command)
+ int command, int hwpec)
{
int i, len;
int smbcmd;
@@ -391,8 +388,7 @@ static int i801_block_transaction(union i2c_smbus_data *data, char read_write,
goto END;
}
-#ifdef HAVE_PEC
- if(isich4 && command == I2C_SMBUS_BLOCK_DATA_PEC) {
+ if (hwpec) {
/* wait for INTR bit as advised by Intel */
timeout = 0;
do {
@@ -406,7 +402,6 @@ static int i801_block_transaction(union i2c_smbus_data *data, char read_write,
}
outb_p(temp, SMBHSTSTS);
}
-#endif
result = 0;
END:
if (command == I2C_SMBUS_I2C_BLOCK_DATA) {
@@ -421,14 +416,13 @@ static s32 i801_access(struct i2c_adapter * adap, u16 addr,
unsigned short flags, char read_write, u8 command,
int size, union i2c_smbus_data * data)
{
- int hwpec = 0;
+ int hwpec;
int block = 0;
int ret, xact = 0;
-#ifdef HAVE_PEC
- if(isich4)
- hwpec = (flags & I2C_CLIENT_PEC) != 0;
-#endif
+ hwpec = isich4 && (flags & I2C_CLIENT_PEC)
+ && size != I2C_SMBUS_QUICK
+ && size != I2C_SMBUS_I2C_BLOCK_DATA;
switch (size) {
case I2C_SMBUS_QUICK:
@@ -463,11 +457,6 @@ static s32 i801_access(struct i2c_adapter * adap, u16 addr,
break;
case I2C_SMBUS_BLOCK_DATA:
case I2C_SMBUS_I2C_BLOCK_DATA:
-#ifdef HAVE_PEC
- case I2C_SMBUS_BLOCK_DATA_PEC:
- if(hwpec && size == I2C_SMBUS_BLOCK_DATA)
- size = I2C_SMBUS_BLOCK_DATA_PEC;
-#endif
outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
SMBHSTADD);
outb_p(command, SMBHSTCMD);
@@ -479,27 +468,18 @@ static s32 i801_access(struct i2c_adapter * adap, u16 addr,
return -1;
}
-#ifdef HAVE_PEC
- if(isich4 && hwpec) {
- if(size != I2C_SMBUS_QUICK &&
- size != I2C_SMBUS_I2C_BLOCK_DATA)
- outb_p(1, SMBAUXCTL); /* enable HW PEC */
- }
-#endif
+ if (hwpec)
+ outb_p(1, SMBAUXCTL); /* enable hardware PEC */
+
if(block)
- ret = i801_block_transaction(data, read_write, size);
+ ret = i801_block_transaction(data, read_write, size, hwpec);
else {
outb_p(xact | ENABLE_INT9, SMBHSTCNT);
ret = i801_transaction();
}
-#ifdef HAVE_PEC
- if(isich4 && hwpec) {
- if(size != I2C_SMBUS_QUICK &&
- size != I2C_SMBUS_I2C_BLOCK_DATA)
- outb_p(0, SMBAUXCTL);
- }
-#endif
+ if (hwpec)
+ outb_p(0, SMBAUXCTL); /* disable hardware PEC */
if(block)
return ret;
@@ -526,12 +506,7 @@ static u32 i801_func(struct i2c_adapter *adapter)
return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |
I2C_FUNC_SMBUS_BLOCK_DATA | I2C_FUNC_SMBUS_WRITE_I2C_BLOCK
-#ifdef HAVE_PEC
- | (isich4 ? I2C_FUNC_SMBUS_BLOCK_DATA_PEC |
- I2C_FUNC_SMBUS_HWPEC_CALC
- : 0)
-#endif
- ;
+ | (isich4 ? I2C_FUNC_SMBUS_HWPEC_CALC : 0);
}
static struct i2c_algorithm smbus_algorithm = {
@@ -543,7 +518,6 @@ static struct i2c_adapter i801_adapter = {
.owner = THIS_MODULE,
.class = I2C_CLASS_HWMON,
.algo = &smbus_algorithm,
- .name = "unset",
};
static struct pci_device_id i801_ids[] = {
diff --git a/drivers/i2c/busses/i2c-i810.c b/drivers/i2c/busses/i2c-i810.c
index 0ff7016e0629..748be30f2bae 100644
--- a/drivers/i2c/busses/i2c-i810.c
+++ b/drivers/i2c/busses/i2c-i810.c
@@ -32,6 +32,7 @@
i810AB 7123
i810E 7125
i815 1132
+ i845G 2562
*/
#include <linux/kernel.h>
diff --git a/drivers/i2c/busses/i2c-ibm_iic.c b/drivers/i2c/busses/i2c-ibm_iic.c
index a3ed9590f028..1a587253d716 100644
--- a/drivers/i2c/busses/i2c-ibm_iic.c
+++ b/drivers/i2c/busses/i2c-ibm_iic.c
@@ -672,13 +672,12 @@ static int __devinit iic_probe(struct ocp_device *ocp){
printk(KERN_WARNING"ibm-iic%d: missing additional data!\n",
ocp->def->index);
- if (!(dev = kmalloc(sizeof(*dev), GFP_KERNEL))){
+ if (!(dev = kzalloc(sizeof(*dev), GFP_KERNEL))) {
printk(KERN_CRIT "ibm-iic%d: failed to allocate device data\n",
ocp->def->index);
return -ENOMEM;
}
- memset(dev, 0, sizeof(*dev));
dev->idx = ocp->def->index;
ocp_set_drvdata(ocp, dev);
diff --git a/drivers/i2c/busses/i2c-iop3xx.c b/drivers/i2c/busses/i2c-iop3xx.c
index 7bd9102db701..cfae4ad00fae 100644
--- a/drivers/i2c/busses/i2c-iop3xx.c
+++ b/drivers/i2c/busses/i2c-iop3xx.c
@@ -11,7 +11,7 @@
*
* Copyright (C) 1995-1997 Simon G. Vogl, 1998-2000 Hans Berglund
*
- * And which acknowledged Kyösti Mälkki <kmalkki@cc.hut.fi>,
+ * And which acknowledged Kyösti Mälkki <kmalkki@cc.hut.fi>,
* Frodo Looijaard <frodol@dds.nl>, Martin Bailey<mbailey@littlefeet-inc.com>
*
* Major cleanup by Deepak Saxena <dsaxena@plexity.net>, 01/2005:
@@ -35,7 +35,7 @@
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/sched.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <linux/i2c.h>
#include <asm/io.h>
@@ -43,7 +43,7 @@
#include "i2c-iop3xx.h"
/* global unit counter */
-static int i2c_id = 0;
+static int i2c_id;
static inline unsigned char
iic_cook_addr(struct i2c_msg *msg)
@@ -184,7 +184,7 @@ iop3xx_i2c_wait_event(struct i2c_algo_iop3xx_data *iop3xx_adap,
do {
interrupted = wait_event_interruptible_timeout (
iop3xx_adap->waitq,
- (done = compare( sr = iop3xx_i2c_get_srstat(iop3xx_adap) ,flags )),
+ (done = compare( sr = iop3xx_i2c_get_srstat(iop3xx_adap) ,flags )),
1 * HZ;
);
if ((rc = iop3xx_i2c_error(sr)) < 0) {
@@ -440,19 +440,17 @@ iop3xx_i2c_probe(struct device *dev)
struct i2c_adapter *new_adapter;
struct i2c_algo_iop3xx_data *adapter_data;
- new_adapter = kmalloc(sizeof(struct i2c_adapter), GFP_KERNEL);
+ new_adapter = kzalloc(sizeof(struct i2c_adapter), GFP_KERNEL);
if (!new_adapter) {
ret = -ENOMEM;
goto out;
}
- memset((void*)new_adapter, 0, sizeof(*new_adapter));
- adapter_data = kmalloc(sizeof(struct i2c_algo_iop3xx_data), GFP_KERNEL);
+ adapter_data = kzalloc(sizeof(struct i2c_algo_iop3xx_data), GFP_KERNEL);
if (!adapter_data) {
ret = -ENOMEM;
goto free_adapter;
}
- memset((void*)adapter_data, 0, sizeof(*adapter_data));
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) {
@@ -474,9 +472,10 @@ iop3xx_i2c_probe(struct device *dev)
goto release_region;
}
- res = request_irq(platform_get_irq(pdev, 0), iop3xx_i2c_irq_handler, 0,
+ ret = request_irq(platform_get_irq(pdev, 0), iop3xx_i2c_irq_handler, 0,
pdev->name, adapter_data);
- if (res) {
+
+ if (ret) {
ret = -EIO;
goto unmap;
}
@@ -525,6 +524,7 @@ out:
static struct device_driver iop3xx_i2c_driver = {
+ .owner = THIS_MODULE,
.name = "IOP3xx-I2C",
.bus = &platform_bus_type,
.probe = iop3xx_i2c_probe,
diff --git a/drivers/i2c/busses/i2c-isa.c b/drivers/i2c/busses/i2c-isa.c
index bdc6806dafae..03672c9ca409 100644
--- a/drivers/i2c/busses/i2c-isa.c
+++ b/drivers/i2c/busses/i2c-isa.c
@@ -38,6 +38,7 @@
#include <linux/errno.h>
#include <linux/i2c.h>
#include <linux/i2c-isa.h>
+#include <linux/platform_device.h>
static u32 isa_func(struct i2c_adapter *adapter);
@@ -92,6 +93,7 @@ int i2c_isa_add_driver(struct i2c_driver *driver)
/* Add the driver to the list of i2c drivers in the driver core */
driver->driver.name = driver->name;
+ driver->driver.owner = driver->owner;
driver->driver.bus = &i2c_bus_type;
driver->driver.probe = i2c_isa_device_probe;
driver->driver.remove = i2c_isa_device_remove;
diff --git a/drivers/i2c/busses/i2c-ixp2000.c b/drivers/i2c/busses/i2c-ixp2000.c
index 1956af382cd8..64552a376f2d 100644
--- a/drivers/i2c/busses/i2c-ixp2000.c
+++ b/drivers/i2c/busses/i2c-ixp2000.c
@@ -28,7 +28,7 @@
#include <linux/kernel.h>
#include <linux/init.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <linux/module.h>
#include <linux/i2c.h>
#include <linux/i2c-algo-bit.h>
@@ -36,6 +36,8 @@
#include <asm/hardware.h> /* Pick up IXP2000-specific bits */
#include <asm/arch/gpio.h>
+static struct device_driver ixp2000_i2c_driver;
+
static inline int ixp2000_scl_pin(void *data)
{
return ((struct ixp2000_i2c_pins*)data)->scl_pin;
@@ -104,11 +106,10 @@ static int ixp2000_i2c_probe(struct device *dev)
struct platform_device *plat_dev = to_platform_device(dev);
struct ixp2000_i2c_pins *gpio = plat_dev->dev.platform_data;
struct ixp2000_i2c_data *drv_data =
- kmalloc(sizeof(struct ixp2000_i2c_data), GFP_KERNEL);
+ kzalloc(sizeof(struct ixp2000_i2c_data), GFP_KERNEL);
if (!drv_data)
return -ENOMEM;
- memzero(drv_data, sizeof(*drv_data));
drv_data->gpio_pins = gpio;
drv_data->algo_data.data = gpio;
@@ -121,6 +122,8 @@ static int ixp2000_i2c_probe(struct device *dev)
drv_data->algo_data.timeout = 100;
drv_data->adapter.id = I2C_HW_B_IXP2000,
+ strlcpy(drv_data->adapter.name, ixp2000_i2c_driver.name,
+ I2C_NAME_SIZE);
drv_data->adapter.algo_data = &drv_data->algo_data,
drv_data->adapter.dev.parent = &plat_dev->dev;
@@ -142,6 +145,7 @@ static int ixp2000_i2c_probe(struct device *dev)
}
static struct device_driver ixp2000_i2c_driver = {
+ .owner = THIS_MODULE,
.name = "IXP2000-I2C",
.bus = &platform_bus_type,
.probe = ixp2000_i2c_probe,
diff --git a/drivers/i2c/busses/i2c-ixp4xx.c b/drivers/i2c/busses/i2c-ixp4xx.c
index f6f5ca31fdba..cc652c350814 100644
--- a/drivers/i2c/busses/i2c-ixp4xx.c
+++ b/drivers/i2c/busses/i2c-ixp4xx.c
@@ -28,13 +28,15 @@
#include <linux/kernel.h>
#include <linux/init.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <linux/module.h>
#include <linux/i2c.h>
#include <linux/i2c-algo-bit.h>
#include <asm/hardware.h> /* Pick up IXP4xx-specific bits */
+static struct device_driver ixp4xx_i2c_driver;
+
static inline int ixp4xx_scl_pin(void *data)
{
return ((struct ixp4xx_i2c_pins*)data)->scl_pin;
@@ -105,12 +107,11 @@ static int ixp4xx_i2c_probe(struct device *dev)
struct platform_device *plat_dev = to_platform_device(dev);
struct ixp4xx_i2c_pins *gpio = plat_dev->dev.platform_data;
struct ixp4xx_i2c_data *drv_data =
- kmalloc(sizeof(struct ixp4xx_i2c_data), GFP_KERNEL);
+ kzalloc(sizeof(struct ixp4xx_i2c_data), GFP_KERNEL);
if(!drv_data)
return -ENOMEM;
- memzero(drv_data, sizeof(struct ixp4xx_i2c_data));
drv_data->gpio_pins = gpio;
/*
@@ -129,6 +130,8 @@ static int ixp4xx_i2c_probe(struct device *dev)
drv_data->algo_data.timeout = 100;
drv_data->adapter.id = I2C_HW_B_IXP4XX;
+ strlcpy(drv_data->adapter.name, ixp4xx_i2c_driver.name,
+ I2C_NAME_SIZE);
drv_data->adapter.algo_data = &drv_data->algo_data;
drv_data->adapter.dev.parent = &plat_dev->dev;
@@ -151,6 +154,7 @@ static int ixp4xx_i2c_probe(struct device *dev)
}
static struct device_driver ixp4xx_i2c_driver = {
+ .owner = THIS_MODULE,
.name = "IXP4XX-I2C",
.bus = &platform_bus_type,
.probe = ixp4xx_i2c_probe,
diff --git a/drivers/i2c/busses/i2c-keywest.c b/drivers/i2c/busses/i2c-keywest.c
index eff5896ce865..d61f748278fc 100644
--- a/drivers/i2c/busses/i2c-keywest.c
+++ b/drivers/i2c/busses/i2c-keywest.c
@@ -535,13 +535,12 @@ create_iface(struct device_node *np, struct device *dev)
tsize = sizeof(struct keywest_iface) +
(sizeof(struct keywest_chan) + 4) * nchan;
- iface = (struct keywest_iface *) kmalloc(tsize, GFP_KERNEL);
+ iface = kzalloc(tsize, GFP_KERNEL);
if (iface == NULL) {
printk(KERN_ERR "i2c-keywest: can't allocate inteface !\n");
pmac_low_i2c_unlock(np);
return -ENOMEM;
}
- memset(iface, 0, tsize);
spin_lock_init(&iface->lock);
init_completion(&iface->complete);
iface->node = of_node_get(np);
@@ -716,6 +715,7 @@ static struct of_device_id i2c_keywest_match[] =
static struct macio_driver i2c_keywest_macio_driver =
{
+ .owner = THIS_MODULE,
.name = "i2c-keywest",
.match_table = i2c_keywest_match,
.probe = create_iface_macio,
@@ -724,6 +724,7 @@ static struct macio_driver i2c_keywest_macio_driver =
static struct of_platform_driver i2c_keywest_of_platform_driver =
{
+ .owner = THIS_MODULE,
.name = "i2c-keywest",
.match_table = i2c_keywest_match,
.probe = create_iface_of_platform,
diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c
index f065583ddcf1..65b939a059e9 100644
--- a/drivers/i2c/busses/i2c-mpc.c
+++ b/drivers/i2c/busses/i2c-mpc.c
@@ -19,6 +19,8 @@
#include <linux/sched.h>
#include <linux/init.h>
#include <linux/pci.h>
+#include <linux/platform_device.h>
+
#include <asm/io.h>
#include <linux/fsl_devices.h>
#include <linux/i2c.h>
@@ -296,10 +298,9 @@ static int fsl_i2c_probe(struct device *device)
pdata = (struct fsl_i2c_platform_data *) pdev->dev.platform_data;
- if (!(i2c = kmalloc(sizeof(*i2c), GFP_KERNEL))) {
+ if (!(i2c = kzalloc(sizeof(*i2c), GFP_KERNEL))) {
return -ENOMEM;
}
- memset(i2c, 0, sizeof(*i2c));
i2c->irq = platform_get_irq(pdev, 0);
i2c->flags = pdata->device_flags;
@@ -361,6 +362,7 @@ static int fsl_i2c_remove(struct device *device)
/* Structure for a device driver */
static struct device_driver fsl_i2c_driver = {
+ .owner = THIS_MODULE,
.name = "fsl-i2c",
.bus = &platform_bus_type,
.probe = fsl_i2c_probe,
diff --git a/drivers/i2c/busses/i2c-mv64xxx.c b/drivers/i2c/busses/i2c-mv64xxx.c
index 99abca45fece..6b48027b2ee3 100644
--- a/drivers/i2c/busses/i2c-mv64xxx.c
+++ b/drivers/i2c/busses/i2c-mv64xxx.c
@@ -17,6 +17,8 @@
#include <linux/i2c.h>
#include <linux/interrupt.h>
#include <linux/mv643xx.h>
+#include <linux/platform_device.h>
+
#include <asm/io.h>
/* Register defines */
@@ -500,13 +502,10 @@ mv64xxx_i2c_probe(struct device *dev)
if ((pd->id != 0) || !pdata)
return -ENODEV;
- drv_data = kmalloc(sizeof(struct mv64xxx_i2c_data), GFP_KERNEL);
-
+ drv_data = kzalloc(sizeof(struct mv64xxx_i2c_data), GFP_KERNEL);
if (!drv_data)
return -ENOMEM;
- memset(drv_data, 0, sizeof(struct mv64xxx_i2c_data));
-
if (mv64xxx_i2c_map_regs(pd, drv_data)) {
rc = -ENODEV;
goto exit_kfree;
@@ -570,6 +569,7 @@ mv64xxx_i2c_remove(struct device *dev)
}
static struct device_driver mv64xxx_i2c_driver = {
+ .owner = THIS_MODULE,
.name = MV64XXX_I2C_CTLR_NAME,
.bus = &platform_bus_type,
.probe = mv64xxx_i2c_probe,
diff --git a/drivers/i2c/busses/i2c-nforce2.c b/drivers/i2c/busses/i2c-nforce2.c
index fe9c0f42a2b7..4d18e6e5f159 100644
--- a/drivers/i2c/busses/i2c-nforce2.c
+++ b/drivers/i2c/busses/i2c-nforce2.c
@@ -97,6 +97,7 @@ struct nforce2_smbus {
#define NVIDIA_SMB_PRTCL_I2C_BLOCK_DATA 0x4a
#define NVIDIA_SMB_PRTCL_PEC 0x80
+static struct pci_driver nforce2_driver;
static s32 nforce2_access(struct i2c_adapter *adap, u16 addr,
unsigned short flags, char read_write,
@@ -113,7 +114,6 @@ static struct i2c_adapter nforce2_adapter = {
.owner = THIS_MODULE,
.class = I2C_CLASS_HWMON,
.algo = &smbus_algorithm,
- .name = "unset",
};
/* Return -1 on error. See smbus.h for more information */
@@ -188,13 +188,6 @@ static s32 nforce2_access(struct i2c_adapter * adap, u16 addr,
dev_err(&adap->dev, "I2C_SMBUS_BLOCK_PROC_CALL not supported!\n");
return -1;
- case I2C_SMBUS_WORD_DATA_PEC:
- case I2C_SMBUS_BLOCK_DATA_PEC:
- case I2C_SMBUS_PROC_CALL_PEC:
- case I2C_SMBUS_BLOCK_PROC_CALL_PEC:
- dev_err(&adap->dev, "Unexpected software PEC transaction %d\n.", size);
- return -1;
-
default:
dev_err(&adap->dev, "Unsupported transaction %d\n", size);
return -1;
@@ -285,7 +278,7 @@ static int __devinit nforce2_probe_smb (struct pci_dev *dev, int reg,
smbus->base = iobase & 0xfffc;
smbus->size = 8;
- if (!request_region(smbus->base, smbus->size, "nForce2 SMBus")) {
+ if (!request_region(smbus->base, smbus->size, nforce2_driver.name)) {
dev_err(&smbus->adapter.dev, "Error requesting region %02x .. %02X for %s\n",
smbus->base, smbus->base+smbus->size-1, name);
return -1;
@@ -313,10 +306,8 @@ static int __devinit nforce2_probe(struct pci_dev *dev, const struct pci_device_
int res1, res2;
/* we support 2 SMBus adapters */
- if (!(smbuses = (void *)kmalloc(2*sizeof(struct nforce2_smbus),
- GFP_KERNEL)))
+ if (!(smbuses = kzalloc(2*sizeof(struct nforce2_smbus), GFP_KERNEL)))
return -ENOMEM;
- memset (smbuses, 0, 2*sizeof(struct nforce2_smbus));
pci_set_drvdata(dev, smbuses);
/* SMBus adapter 1 */
diff --git a/drivers/i2c/busses/i2c-parport.c b/drivers/i2c/busses/i2c-parport.c
index 71a2502fe069..2854d858fc9b 100644
--- a/drivers/i2c/busses/i2c-parport.c
+++ b/drivers/i2c/busses/i2c-parport.c
@@ -155,12 +155,11 @@ static void i2c_parport_attach (struct parport *port)
{
struct i2c_par *adapter;
- adapter = kmalloc(sizeof(struct i2c_par), GFP_KERNEL);
+ adapter = kzalloc(sizeof(struct i2c_par), GFP_KERNEL);
if (adapter == NULL) {
- printk(KERN_ERR "i2c-parport: Failed to kmalloc\n");
+ printk(KERN_ERR "i2c-parport: Failed to kzalloc\n");
return;
}
- memset(adapter, 0x00, sizeof(struct i2c_par));
pr_debug("i2c-parport: attaching to %s\n", port->name);
adapter->pdev = parport_register_device(port, "i2c-parport",
@@ -232,7 +231,7 @@ static void i2c_parport_detach (struct parport *port)
}
}
-static struct parport_driver i2c_driver = {
+static struct parport_driver i2c_parport_driver = {
.name = "i2c-parport",
.attach = i2c_parport_attach,
.detach = i2c_parport_detach,
@@ -250,12 +249,12 @@ static int __init i2c_parport_init(void)
type = 0;
}
- return parport_register_driver(&i2c_driver);
+ return parport_register_driver(&i2c_parport_driver);
}
static void __exit i2c_parport_exit(void)
{
- parport_unregister_driver(&i2c_driver);
+ parport_unregister_driver(&i2c_parport_driver);
}
MODULE_AUTHOR("Jean Delvare <khali@linux-fr.org>");
diff --git a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c
index 6d48a4da7bed..692f47345481 100644
--- a/drivers/i2c/busses/i2c-piix4.c
+++ b/drivers/i2c/busses/i2c-piix4.c
@@ -90,13 +90,13 @@ struct sd {
/* If force is set to anything different from 0, we forcibly enable the
PIIX4. DANGEROUS! */
-static int force = 0;
+static int force;
module_param (force, int, 0);
MODULE_PARM_DESC(force, "Forcibly enable the PIIX4. DANGEROUS!");
/* If force_addr is set to anything different from 0, we forcibly enable
the PIIX4 at the given address. VERY DANGEROUS! */
-static int force_addr = 0;
+static int force_addr;
module_param (force_addr, int, 0);
MODULE_PARM_DESC(force_addr,
"Forcibly enable the PIIX4 at the given address. "
@@ -104,14 +104,15 @@ MODULE_PARM_DESC(force_addr,
/* If fix_hstcfg is set to anything different from 0, we reset one of the
registers to be a valid value. */
-static int fix_hstcfg = 0;
+static int fix_hstcfg;
module_param (fix_hstcfg, int, 0);
MODULE_PARM_DESC(fix_hstcfg,
"Fix config register. Needed on some boards (Force CPCI735).");
static int piix4_transaction(void);
-static unsigned short piix4_smba = 0;
+static unsigned short piix4_smba;
+static struct pci_driver piix4_driver;
static struct i2c_adapter piix4_adapter;
static struct dmi_system_id __devinitdata piix4_dmi_table[] = {
@@ -157,7 +158,7 @@ static int __devinit piix4_setup(struct pci_dev *PIIX4_dev,
}
}
- if (!request_region(piix4_smba, SMBIOSIZE, "piix4-smbus")) {
+ if (!request_region(piix4_smba, SMBIOSIZE, piix4_driver.name)) {
dev_err(&PIIX4_dev->dev, "SMB region 0x%x already in use!\n",
piix4_smba);
return -ENODEV;
@@ -407,7 +408,6 @@ static struct i2c_adapter piix4_adapter = {
.owner = THIS_MODULE,
.class = I2C_CLASS_HWMON,
.algo = &smbus_algorithm,
- .name = "unset",
};
static struct pci_device_id piix4_ids[] = {
diff --git a/drivers/i2c/busses/i2c-pmac-smu.c b/drivers/i2c/busses/i2c-pmac-smu.c
index 8a9f5648a23d..bfefe7f7a53d 100644
--- a/drivers/i2c/busses/i2c-pmac-smu.c
+++ b/drivers/i2c/busses/i2c-pmac-smu.c
@@ -211,12 +211,11 @@ static int create_iface(struct device_node *np, struct device *dev)
}
busid = *reg;
- iface = kmalloc(sizeof(struct smu_iface), GFP_KERNEL);
+ iface = kzalloc(sizeof(struct smu_iface), GFP_KERNEL);
if (iface == NULL) {
printk(KERN_ERR "i2c-pmac-smu: can't allocate inteface !\n");
return -ENOMEM;
}
- memset(iface, 0, sizeof(struct smu_iface));
init_completion(&iface->complete);
iface->busid = busid;
diff --git a/drivers/i2c/busses/i2c-prosavage.c b/drivers/i2c/busses/i2c-prosavage.c
index 83fd16d61ce5..9479525892e3 100644
--- a/drivers/i2c/busses/i2c-prosavage.c
+++ b/drivers/i2c/busses/i2c-prosavage.c
@@ -83,11 +83,6 @@ struct s_i2c_chip {
/*
* i2c configuration
*/
-#ifndef I2C_HW_B_S3VIA
-#define I2C_HW_B_S3VIA 0x18 /* S3VIA ProSavage adapter */
-#endif
-
-/* delays */
#define CYCLE_DELAY 10
#define TIMEOUT (HZ / 2)
@@ -241,14 +236,12 @@ static int __devinit prosavage_probe(struct pci_dev *dev, const struct pci_devic
struct s_i2c_chip *chip;
struct s_i2c_bus *bus;
- pci_set_drvdata(dev, kmalloc(sizeof(struct s_i2c_chip), GFP_KERNEL));
+ pci_set_drvdata(dev, kzalloc(sizeof(struct s_i2c_chip), GFP_KERNEL));
chip = (struct s_i2c_chip *)pci_get_drvdata(dev);
if (chip == NULL) {
return -ENOMEM;
}
- memset(chip, 0, sizeof(struct s_i2c_chip));
-
base = dev->resource[0].start & PCI_BASE_ADDRESS_MEM_MASK;
len = dev->resource[0].end - base + 1;
chip->mmio = ioremap_nocache(base, len);
diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c
index 44b595d90a4a..67ccbea24ba4 100644
--- a/drivers/i2c/busses/i2c-pxa.c
+++ b/drivers/i2c/busses/i2c-pxa.c
@@ -30,6 +30,7 @@
#include <linux/errno.h>
#include <linux/interrupt.h>
#include <linux/i2c-pxa.h>
+#include <linux/platform_device.h>
#include <asm/hardware.h>
#include <asm/irq.h>
diff --git a/drivers/i2c/busses/i2c-s3c2410.c b/drivers/i2c/busses/i2c-s3c2410.c
index 73a092fb0e7e..1b582262e677 100644
--- a/drivers/i2c/busses/i2c-s3c2410.c
+++ b/drivers/i2c/busses/i2c-s3c2410.c
@@ -33,7 +33,7 @@
#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/err.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <asm/hardware.h>
#include <asm/irq.h>
@@ -879,14 +879,12 @@ static int s3c24xx_i2c_remove(struct device *dev)
}
#ifdef CONFIG_PM
-static int s3c24xx_i2c_resume(struct device *dev, u32 level)
+static int s3c24xx_i2c_resume(struct device *dev)
{
struct s3c24xx_i2c *i2c = dev_get_drvdata(dev);
-
- if (i2c != NULL && level == RESUME_ENABLE) {
- dev_dbg(dev, "resume: level %d\n", level);
+
+ if (i2c != NULL)
s3c24xx_i2c_init(i2c);
- }
return 0;
}
@@ -898,6 +896,7 @@ static int s3c24xx_i2c_resume(struct device *dev, u32 level)
/* device driver for platform bus bits */
static struct device_driver s3c2410_i2c_driver = {
+ .owner = THIS_MODULE,
.name = "s3c2410-i2c",
.bus = &platform_bus_type,
.probe = s3c24xx_i2c_probe,
@@ -906,6 +905,7 @@ static struct device_driver s3c2410_i2c_driver = {
};
static struct device_driver s3c2440_i2c_driver = {
+ .owner = THIS_MODULE,
.name = "s3c2440-i2c",
.bus = &platform_bus_type,
.probe = s3c24xx_i2c_probe,
@@ -918,8 +918,11 @@ static int __init i2c_adap_s3c_init(void)
int ret;
ret = driver_register(&s3c2410_i2c_driver);
- if (ret == 0)
- ret = driver_register(&s3c2440_i2c_driver);
+ if (ret == 0) {
+ ret = driver_register(&s3c2440_i2c_driver);
+ if (ret)
+ driver_unregister(&s3c2410_i2c_driver);
+ }
return ret;
}
diff --git a/drivers/i2c/busses/i2c-sis5595.c b/drivers/i2c/busses/i2c-sis5595.c
index 080318d6f54b..b57ab74d23ec 100644
--- a/drivers/i2c/busses/i2c-sis5595.c
+++ b/drivers/i2c/busses/i2c-sis5595.c
@@ -123,11 +123,12 @@ static int blacklist[] = {
/* If force_addr is set to anything different from 0, we forcibly enable
the device at the given address. */
-static u16 force_addr = 0;
+static u16 force_addr;
module_param(force_addr, ushort, 0);
MODULE_PARM_DESC(force_addr, "Initialize the base address of the i2c controller");
-static unsigned short sis5595_base = 0;
+static struct pci_driver sis5595_driver;
+static unsigned short sis5595_base;
static u8 sis5595_read(u8 reg)
{
@@ -172,7 +173,8 @@ static int sis5595_setup(struct pci_dev *SIS5595_dev)
/* NB: We grab just the two SMBus registers here, but this may still
* interfere with ACPI :-( */
- if (!request_region(sis5595_base + SMB_INDEX, 2, "sis5595-smbus")) {
+ if (!request_region(sis5595_base + SMB_INDEX, 2,
+ sis5595_driver.name)) {
dev_err(&SIS5595_dev->dev, "SMBus registers 0x%04x-0x%04x already in use!\n",
sis5595_base + SMB_INDEX, sis5595_base + SMB_INDEX + 1);
return -ENODEV;
@@ -364,7 +366,6 @@ static struct i2c_algorithm smbus_algorithm = {
static struct i2c_adapter sis5595_adapter = {
.owner = THIS_MODULE,
.class = I2C_CLASS_HWMON,
- .name = "unset",
.algo = &smbus_algorithm,
};
diff --git a/drivers/i2c/busses/i2c-sis630.c b/drivers/i2c/busses/i2c-sis630.c
index 86f0f448fa0b..acb75e282414 100644
--- a/drivers/i2c/busses/i2c-sis630.c
+++ b/drivers/i2c/busses/i2c-sis630.c
@@ -92,6 +92,8 @@
#define SIS630_PCALL 0x04
#define SIS630_BLOCK_DATA 0x05
+static struct pci_driver sis630_driver;
+
/* insmod parameters */
static int high_clock;
static int force;
@@ -101,7 +103,7 @@ module_param(force, bool, 0);
MODULE_PARM_DESC(force, "Forcibly enable the SIS630. DANGEROUS!");
/* acpi base address */
-static unsigned short acpi_base = 0;
+static unsigned short acpi_base;
/* supported chips */
static int supported[] = {
@@ -432,7 +434,8 @@ static int sis630_setup(struct pci_dev *sis630_dev)
dev_dbg(&sis630_dev->dev, "ACPI base at 0x%04x\n", acpi_base);
/* Everything is happy, let's grab the memory and set things up. */
- if (!request_region(acpi_base + SMB_STS, SIS630_SMB_IOREGION, "sis630-smbus")) {
+ if (!request_region(acpi_base + SMB_STS, SIS630_SMB_IOREGION,
+ sis630_driver.name)) {
dev_err(&sis630_dev->dev, "SMBus registers 0x%04x-0x%04x already "
"in use!\n", acpi_base + SMB_STS, acpi_base + SMB_SAA);
goto exit;
@@ -455,7 +458,6 @@ static struct i2c_algorithm smbus_algorithm = {
static struct i2c_adapter sis630_adapter = {
.owner = THIS_MODULE,
.class = I2C_CLASS_HWMON,
- .name = "unset",
.algo = &smbus_algorithm,
};
diff --git a/drivers/i2c/busses/i2c-sis96x.c b/drivers/i2c/busses/i2c-sis96x.c
index ead2ff3cf60e..3024907cdafe 100644
--- a/drivers/i2c/busses/i2c-sis96x.c
+++ b/drivers/i2c/busses/i2c-sis96x.c
@@ -82,8 +82,9 @@
#define SIS96x_PROC_CALL 0x04
#define SIS96x_BLOCK_DATA 0x05
+static struct pci_driver sis96x_driver;
static struct i2c_adapter sis96x_adapter;
-static u16 sis96x_smbus_base = 0;
+static u16 sis96x_smbus_base;
static inline u8 sis96x_read(u8 reg)
{
@@ -257,7 +258,6 @@ static struct i2c_adapter sis96x_adapter = {
.owner = THIS_MODULE,
.class = I2C_CLASS_HWMON,
.algo = &smbus_algorithm,
- .name = "unset",
};
static struct pci_device_id sis96x_ids[] = {
@@ -294,7 +294,8 @@ static int __devinit sis96x_probe(struct pci_dev *dev,
sis96x_smbus_base);
/* Everything is happy, let's grab the memory and set things up. */
- if (!request_region(sis96x_smbus_base, SMB_IOSIZE, "sis96x-smbus")) {
+ if (!request_region(sis96x_smbus_base, SMB_IOSIZE,
+ sis96x_driver.name)) {
dev_err(&dev->dev, "SMBus registers 0x%04x-0x%04x "
"already in use!\n", sis96x_smbus_base,
sis96x_smbus_base + SMB_IOSIZE - 1);
diff --git a/drivers/i2c/busses/i2c-via.c b/drivers/i2c/busses/i2c-via.c
index 040b8abeabba..484bbacfce6b 100644
--- a/drivers/i2c/busses/i2c-via.c
+++ b/drivers/i2c/busses/i2c-via.c
@@ -43,9 +43,9 @@
/* io-region reservation */
#define IOSPACE 0x06
-#define IOTEXT "via-i2c"
-static u16 pm_io_base = 0;
+static struct pci_driver vt586b_driver;
+static u16 pm_io_base;
/*
It does not appear from the datasheet that the GPIO pins are
@@ -130,7 +130,7 @@ static int __devinit vt586b_probe(struct pci_dev *dev, const struct pci_device_i
pci_read_config_word(dev, base, &pm_io_base);
pm_io_base &= (0xff << 8);
- if (!request_region(I2C_DIR, IOSPACE, IOTEXT)) {
+ if (!request_region(I2C_DIR, IOSPACE, vt586b_driver.name)) {
dev_err(&dev->dev, "IO 0x%x-0x%x already in use\n", I2C_DIR, I2C_DIR + IOSPACE);
return -ENODEV;
}
diff --git a/drivers/i2c/busses/i2c-viapro.c b/drivers/i2c/busses/i2c-viapro.c
index 99d209e0485a..47e52bf2c5ec 100644
--- a/drivers/i2c/busses/i2c-viapro.c
+++ b/drivers/i2c/busses/i2c-viapro.c
@@ -1,9 +1,10 @@
/*
i2c-viapro.c - Part of lm_sensors, Linux kernel modules for hardware
monitoring
- Copyright (c) 1998 - 2002 Frodo Looijaard <frodol@dds.nl>,
+ Copyright (c) 1998 - 2002 Frodo Looijaard <frodol@dds.nl>,
Philip Edelbrock <phil@netroedge.com>, Kyösti Mälkki <kmalkki@cc.hut.fi>,
Mark D. Studebaker <mdsxyz123@yahoo.com>
+ Copyright (C) 2005 Jean Delvare <khali@linux-fr.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
@@ -21,15 +22,19 @@
*/
/*
- Supports Via devices:
- 82C596A/B (0x3050)
- 82C596B (0x3051)
- 82C686A/B
- 8231
- 8233
- 8233A (0x3147 and 0x3177)
- 8235
- 8237
+ Supports the following VIA south bridges:
+
+ Chip name PCI ID REV I2C block
+ VT82C596A 0x3050 no
+ VT82C596B 0x3051 no
+ VT82C686A 0x3057 0x30 no
+ VT82C686B 0x3057 0x40 yes
+ VT8231 0x8235 no?
+ VT8233 0x3074 yes
+ VT8233A 0x3147 yes?
+ VT8235 0x3177 yes
+ VT8237R 0x3227 yes
+
Note: we assume there can only be one device, with one SMBus interface.
*/
@@ -38,7 +43,6 @@
#include <linux/pci.h>
#include <linux/kernel.h>
#include <linux/stddef.h>
-#include <linux/sched.h>
#include <linux/ioport.h>
#include <linux/i2c.h>
#include <linux/init.h>
@@ -46,48 +50,37 @@
static struct pci_dev *vt596_pdev;
-#define SMBBA1 0x90
-#define SMBBA2 0x80
-#define SMBBA3 0xD0
+#define SMBBA1 0x90
+#define SMBBA2 0x80
+#define SMBBA3 0xD0
/* SMBus address offsets */
static unsigned short vt596_smba;
#define SMBHSTSTS (vt596_smba + 0)
-#define SMBHSLVSTS (vt596_smba + 1)
#define SMBHSTCNT (vt596_smba + 2)
#define SMBHSTCMD (vt596_smba + 3)
#define SMBHSTADD (vt596_smba + 4)
#define SMBHSTDAT0 (vt596_smba + 5)
#define SMBHSTDAT1 (vt596_smba + 6)
#define SMBBLKDAT (vt596_smba + 7)
-#define SMBSLVCNT (vt596_smba + 8)
-#define SMBSHDWCMD (vt596_smba + 9)
-#define SMBSLVEVT (vt596_smba + 0xA)
-#define SMBSLVDAT (vt596_smba + 0xC)
/* PCI Address Constants */
/* SMBus data in configuration space can be found in two places,
- We try to select the better one*/
-
-static unsigned short smb_cf_hstcfg = 0xD2;
+ We try to select the better one */
-#define SMBHSTCFG (smb_cf_hstcfg)
-#define SMBSLVC (smb_cf_hstcfg + 1)
-#define SMBSHDW1 (smb_cf_hstcfg + 2)
-#define SMBSHDW2 (smb_cf_hstcfg + 3)
-#define SMBREV (smb_cf_hstcfg + 4)
+static unsigned short SMBHSTCFG = 0xD2;
/* Other settings */
#define MAX_TIMEOUT 500
-#define ENABLE_INT9 0
/* VT82C596 constants */
-#define VT596_QUICK 0x00
-#define VT596_BYTE 0x04
-#define VT596_BYTE_DATA 0x08
-#define VT596_WORD_DATA 0x0C
-#define VT596_BLOCK_DATA 0x14
+#define VT596_QUICK 0x00
+#define VT596_BYTE 0x04
+#define VT596_BYTE_DATA 0x08
+#define VT596_WORD_DATA 0x0C
+#define VT596_BLOCK_DATA 0x14
+#define VT596_I2C_BLOCK_DATA 0x34
/* If force is set to anything different from 0, we forcibly enable the
@@ -105,40 +98,64 @@ MODULE_PARM_DESC(force_addr,
"EXTREMELY DANGEROUS!");
+static struct pci_driver vt596_driver;
static struct i2c_adapter vt596_adapter;
-/* Another internally used function */
-static int vt596_transaction(void)
+#define FEATURE_I2CBLOCK (1<<0)
+static unsigned int vt596_features;
+
+#ifdef DEBUG
+static void vt596_dump_regs(const char *msg, u8 size)
+{
+ dev_dbg(&vt596_adapter.dev, "%s: STS=%02x CNT=%02x CMD=%02x ADD=%02x "
+ "DAT=%02x,%02x\n", msg, inb_p(SMBHSTSTS), inb_p(SMBHSTCNT),
+ inb_p(SMBHSTCMD), inb_p(SMBHSTADD), inb_p(SMBHSTDAT0),
+ inb_p(SMBHSTDAT1));
+
+ if (size == VT596_BLOCK_DATA
+ || size == VT596_I2C_BLOCK_DATA) {
+ int i;
+
+ dev_dbg(&vt596_adapter.dev, "BLK=");
+ for (i = 0; i < I2C_SMBUS_BLOCK_MAX / 2; i++)
+ printk("%02x,", inb_p(SMBBLKDAT));
+ printk("\n");
+ dev_dbg(&vt596_adapter.dev, " ");
+ for (; i < I2C_SMBUS_BLOCK_MAX - 1; i++)
+ printk("%02x,", inb_p(SMBBLKDAT));
+ printk("%02x\n", inb_p(SMBBLKDAT));
+ }
+}
+#else
+static inline void vt596_dump_regs(const char *msg, u8 size) { }
+#endif
+
+/* Return -1 on error, 0 on success */
+static int vt596_transaction(u8 size)
{
int temp;
int result = 0;
int timeout = 0;
- dev_dbg(&vt596_adapter.dev, "Transaction (pre): CNT=%02x, CMD=%02x, "
- "ADD=%02x, DAT0=%02x, DAT1=%02x\n", inb_p(SMBHSTCNT),
- inb_p(SMBHSTCMD), inb_p(SMBHSTADD), inb_p(SMBHSTDAT0),
- inb_p(SMBHSTDAT1));
+ vt596_dump_regs("Transaction (pre)", size);
/* Make sure the SMBus host is ready to start transmitting */
if ((temp = inb_p(SMBHSTSTS)) & 0x1F) {
dev_dbg(&vt596_adapter.dev, "SMBus busy (0x%02x). "
- "Resetting...\n", temp);
-
+ "Resetting...\n", temp);
+
outb_p(temp, SMBHSTSTS);
if ((temp = inb_p(SMBHSTSTS)) & 0x1F) {
- dev_dbg(&vt596_adapter.dev, "Failed! (0x%02x)\n", temp);
-
+ dev_err(&vt596_adapter.dev, "SMBus reset failed! "
+ "(0x%02x)\n", temp);
return -1;
- } else {
- dev_dbg(&vt596_adapter.dev, "Successfull!\n");
}
}
- /* start the transaction by setting bit 6 */
- outb_p(inb(SMBHSTCNT) | 0x040, SMBHSTCNT);
+ /* Start the transaction by setting bit 6 */
+ outb_p(0x40 | size, SMBHSTCNT);
- /* We will always wait for a fraction of a second!
- I don't know if VIA needs this, Intel did */
+ /* We will always wait for a fraction of a second */
do {
msleep(1);
temp = inb_p(SMBHSTSTS);
@@ -147,77 +164,63 @@ static int vt596_transaction(void)
/* If the SMBus is still busy, we give up */
if (timeout >= MAX_TIMEOUT) {
result = -1;
- dev_dbg(&vt596_adapter.dev, "SMBus Timeout!\n");
+ dev_err(&vt596_adapter.dev, "SMBus timeout!\n");
}
if (temp & 0x10) {
result = -1;
- dev_dbg(&vt596_adapter.dev, "Error: Failed bus transaction\n");
+ dev_err(&vt596_adapter.dev, "Transaction failed (0x%02x)\n",
+ size);
}
if (temp & 0x08) {
result = -1;
- dev_info(&vt596_adapter.dev, "Bus collision! SMBus may be "
- "locked until next hard\nreset. (sorry!)\n");
- /* Clock stops and slave is stuck in mid-transmission */
+ dev_err(&vt596_adapter.dev, "SMBus collision!\n");
}
if (temp & 0x04) {
+ int read = inb_p(SMBHSTADD) & 0x01;
result = -1;
- dev_dbg(&vt596_adapter.dev, "Error: no response!\n");
+ /* The quick and receive byte commands are used to probe
+ for chips, so errors are expected, and we don't want
+ to frighten the user. */
+ if (!((size == VT596_QUICK && !read) ||
+ (size == VT596_BYTE && read)))
+ dev_err(&vt596_adapter.dev, "Transaction error!\n");
}
- if ((temp = inb_p(SMBHSTSTS)) & 0x1F) {
+ /* Resetting status register */
+ if (temp & 0x1F)
outb_p(temp, SMBHSTSTS);
- if ((temp = inb_p(SMBHSTSTS)) & 0x1F) {
- dev_warn(&vt596_adapter.dev, "Failed reset at end "
- "of transaction (%02x)\n", temp);
- }
- }
- dev_dbg(&vt596_adapter.dev, "Transaction (post): CNT=%02x, CMD=%02x, "
- "ADD=%02x, DAT0=%02x, DAT1=%02x\n", inb_p(SMBHSTCNT),
- inb_p(SMBHSTCMD), inb_p(SMBHSTADD), inb_p(SMBHSTDAT0),
- inb_p(SMBHSTDAT1));
-
+ vt596_dump_regs("Transaction (post)", size);
+
return result;
}
-/* Return -1 on error. */
+/* Return -1 on error, 0 on success */
static s32 vt596_access(struct i2c_adapter *adap, u16 addr,
- unsigned short flags, char read_write, u8 command,
- int size, union i2c_smbus_data *data)
+ unsigned short flags, char read_write, u8 command,
+ int size, union i2c_smbus_data *data)
{
- int i, len;
+ int i;
switch (size) {
- case I2C_SMBUS_PROC_CALL:
- dev_info(&vt596_adapter.dev,
- "I2C_SMBUS_PROC_CALL not supported!\n");
- return -1;
case I2C_SMBUS_QUICK:
- outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
- SMBHSTADD);
size = VT596_QUICK;
break;
case I2C_SMBUS_BYTE:
- outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
- SMBHSTADD);
if (read_write == I2C_SMBUS_WRITE)
outb_p(command, SMBHSTCMD);
size = VT596_BYTE;
break;
case I2C_SMBUS_BYTE_DATA:
- outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
- SMBHSTADD);
outb_p(command, SMBHSTCMD);
if (read_write == I2C_SMBUS_WRITE)
outb_p(data->byte, SMBHSTDAT0);
size = VT596_BYTE_DATA;
break;
case I2C_SMBUS_WORD_DATA:
- outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
- SMBHSTADD);
outb_p(command, SMBHSTCMD);
if (read_write == I2C_SMBUS_WRITE) {
outb_p(data->word & 0xff, SMBHSTDAT0);
@@ -225,28 +228,33 @@ static s32 vt596_access(struct i2c_adapter *adap, u16 addr,
}
size = VT596_WORD_DATA;
break;
+ case I2C_SMBUS_I2C_BLOCK_DATA:
+ if (!(vt596_features & FEATURE_I2CBLOCK))
+ goto exit_unsupported;
+ if (read_write == I2C_SMBUS_READ)
+ outb_p(I2C_SMBUS_BLOCK_MAX, SMBHSTDAT0);
+ /* Fall through */
case I2C_SMBUS_BLOCK_DATA:
- outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
- SMBHSTADD);
outb_p(command, SMBHSTCMD);
if (read_write == I2C_SMBUS_WRITE) {
- len = data->block[0];
- if (len < 0)
- len = 0;
+ u8 len = data->block[0];
if (len > I2C_SMBUS_BLOCK_MAX)
len = I2C_SMBUS_BLOCK_MAX;
outb_p(len, SMBHSTDAT0);
- i = inb_p(SMBHSTCNT); /* Reset SMBBLKDAT */
+ inb_p(SMBHSTCNT); /* Reset SMBBLKDAT */
for (i = 1; i <= len; i++)
outb_p(data->block[i], SMBBLKDAT);
}
- size = VT596_BLOCK_DATA;
+ size = (size == I2C_SMBUS_I2C_BLOCK_DATA) ?
+ VT596_I2C_BLOCK_DATA : VT596_BLOCK_DATA;
break;
+ default:
+ goto exit_unsupported;
}
- outb_p((size & 0x1C) + (ENABLE_INT9 & 1), SMBHSTCNT);
+ outb_p(((addr & 0x7f) << 1) | read_write, SMBHSTADD);
- if (vt596_transaction()) /* Error in transaction */
+ if (vt596_transaction(size)) /* Error in transaction */
return -1;
if ((read_write == I2C_SMBUS_WRITE) || (size == VT596_QUICK))
@@ -254,35 +262,39 @@ static s32 vt596_access(struct i2c_adapter *adap, u16 addr,
switch (size) {
case VT596_BYTE:
- /* Where is the result put? I assume here it is in
- * SMBHSTDAT0 but it might just as well be in the
- * SMBHSTCMD. No clue in the docs
- */
- data->byte = inb_p(SMBHSTDAT0);
- break;
case VT596_BYTE_DATA:
data->byte = inb_p(SMBHSTDAT0);
break;
case VT596_WORD_DATA:
data->word = inb_p(SMBHSTDAT0) + (inb_p(SMBHSTDAT1) << 8);
break;
+ case VT596_I2C_BLOCK_DATA:
case VT596_BLOCK_DATA:
data->block[0] = inb_p(SMBHSTDAT0);
if (data->block[0] > I2C_SMBUS_BLOCK_MAX)
data->block[0] = I2C_SMBUS_BLOCK_MAX;
- i = inb_p(SMBHSTCNT); /* Reset SMBBLKDAT */
+ inb_p(SMBHSTCNT); /* Reset SMBBLKDAT */
for (i = 1; i <= data->block[0]; i++)
data->block[i] = inb_p(SMBBLKDAT);
break;
}
return 0;
+
+exit_unsupported:
+ dev_warn(&vt596_adapter.dev, "Unsupported command invoked! (0x%02x)\n",
+ size);
+ return -1;
}
static u32 vt596_func(struct i2c_adapter *adapter)
{
- return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
+ u32 func = I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |
I2C_FUNC_SMBUS_BLOCK_DATA;
+
+ if (vt596_features & FEATURE_I2CBLOCK)
+ func |= I2C_FUNC_SMBUS_I2C_BLOCK;
+ return func;
}
static struct i2c_algorithm smbus_algorithm = {
@@ -294,7 +306,6 @@ static struct i2c_adapter vt596_adapter = {
.owner = THIS_MODULE,
.class = I2C_CLASS_HWMON,
.algo = &smbus_algorithm,
- .name = "unset",
};
static int __devinit vt596_probe(struct pci_dev *pdev,
@@ -302,7 +313,7 @@ static int __devinit vt596_probe(struct pci_dev *pdev,
{
unsigned char temp;
int error = -ENODEV;
-
+
/* Determine the address of the SMBus areas */
if (force_addr) {
vt596_smba = force_addr & 0xfff0;
@@ -311,12 +322,12 @@ static int __devinit vt596_probe(struct pci_dev *pdev,
}
if ((pci_read_config_word(pdev, id->driver_data, &vt596_smba)) ||
- !(vt596_smba & 0x1)) {
+ !(vt596_smba & 0x0001)) {
/* try 2nd address and config reg. for 596 */
if (id->device == PCI_DEVICE_ID_VIA_82C596_3 &&
!pci_read_config_word(pdev, SMBBA2, &vt596_smba) &&
- (vt596_smba & 0x1)) {
- smb_cf_hstcfg = 0x84;
+ (vt596_smba & 0x0001)) {
+ SMBHSTCFG = 0x84;
} else {
/* no matches at all */
dev_err(&pdev->dev, "Cannot configure "
@@ -333,10 +344,10 @@ static int __devinit vt596_probe(struct pci_dev *pdev,
return -ENODEV;
}
- found:
- if (!request_region(vt596_smba, 8, "viapro-smbus")) {
+found:
+ if (!request_region(vt596_smba, 8, vt596_driver.name)) {
dev_err(&pdev->dev, "SMBus region 0x%x already in use!\n",
- vt596_smba);
+ vt596_smba);
return -ENODEV;
}
@@ -348,16 +359,16 @@ static int __devinit vt596_probe(struct pci_dev *pdev,
pci_write_config_word(pdev, id->driver_data, vt596_smba);
pci_write_config_byte(pdev, SMBHSTCFG, temp | 0x01);
dev_warn(&pdev->dev, "WARNING: SMBus interface set to new "
- "address 0x%04x!\n", vt596_smba);
- } else if ((temp & 1) == 0) {
+ "address 0x%04x!\n", vt596_smba);
+ } else if (!(temp & 0x01)) {
if (force) {
- /* NOTE: This assumes I/O space and other allocations
- * WERE done by the Bios! Don't complain if your
- * hardware does weird things after enabling this.
- * :') Check for Bios updates before resorting to
+ /* NOTE: This assumes I/O space and other allocations
+ * WERE done by the Bios! Don't complain if your
+ * hardware does weird things after enabling this.
+ * :') Check for Bios updates before resorting to
* this.
*/
- pci_write_config_byte(pdev, SMBHSTCFG, temp | 1);
+ pci_write_config_byte(pdev, SMBHSTCFG, temp | 0x01);
dev_info(&pdev->dev, "Enabling SMBus device\n");
} else {
dev_err(&pdev->dev, "SMBUS: Error: Host SMBus "
@@ -367,22 +378,28 @@ static int __devinit vt596_probe(struct pci_dev *pdev,
}
}
- if ((temp & 0x0E) == 8)
- dev_dbg(&pdev->dev, "using Interrupt 9 for SMBus.\n");
- else if ((temp & 0x0E) == 0)
- dev_dbg(&pdev->dev, "using Interrupt SMI# for SMBus.\n");
- else
- dev_dbg(&pdev->dev, "Illegal Interrupt configuration "
- "(or code out of date)!\n");
-
- pci_read_config_byte(pdev, SMBREV, &temp);
- dev_dbg(&pdev->dev, "SMBREV = 0x%X\n", temp);
dev_dbg(&pdev->dev, "VT596_smba = 0x%X\n", vt596_smba);
+ switch (pdev->device) {
+ case PCI_DEVICE_ID_VIA_8237:
+ case PCI_DEVICE_ID_VIA_8235:
+ case PCI_DEVICE_ID_VIA_8233A:
+ case PCI_DEVICE_ID_VIA_8233_0:
+ vt596_features |= FEATURE_I2CBLOCK;
+ break;
+ case PCI_DEVICE_ID_VIA_82C686_4:
+ /* The VT82C686B (rev 0x40) does support I2C block
+ transactions, but the VT82C686A (rev 0x30) doesn't */
+ if (!pci_read_config_byte(pdev, PCI_REVISION_ID, &temp)
+ && temp >= 0x40)
+ vt596_features |= FEATURE_I2CBLOCK;
+ break;
+ }
+
vt596_adapter.dev.parent = &pdev->dev;
snprintf(vt596_adapter.name, I2C_NAME_SIZE,
- "SMBus Via Pro adapter at %04x", vt596_smba);
-
+ "SMBus Via Pro adapter at %04x", vt596_smba);
+
vt596_pdev = pci_dev_get(pdev);
if (i2c_add_adapter(&vt596_adapter)) {
pci_dev_put(vt596_pdev);
@@ -395,7 +412,7 @@ static int __devinit vt596_probe(struct pci_dev *pdev,
*/
return -ENODEV;
- release_region:
+release_region:
release_region(vt596_smba, 8);
return error;
}
@@ -420,7 +437,7 @@ static struct pci_device_id vt596_ids[] = {
{ 0, }
};
-MODULE_DEVICE_TABLE (pci, vt596_ids);
+MODULE_DEVICE_TABLE(pci, vt596_ids);
static struct pci_driver vt596_driver = {
.name = "vt596_smbus",
@@ -445,9 +462,9 @@ static void __exit i2c_vt596_exit(void)
}
}
-MODULE_AUTHOR(
- "Frodo Looijaard <frodol@dds.nl> and "
- "Philip Edelbrock <phil@netroedge.com>");
+MODULE_AUTHOR("Kyosti Malkki <kmalkki@cc.hut.fi>, "
+ "Mark D. Studebaker <mdsxyz123@yahoo.com> and "
+ "Jean Delvare <khali@linux-fr.org>");
MODULE_DESCRIPTION("vt82c596 SMBus driver");
MODULE_LICENSE("GPL");
diff --git a/drivers/i2c/busses/scx200_acb.c b/drivers/i2c/busses/scx200_acb.c
index a1d580e05361..d3478e084522 100644
--- a/drivers/i2c/busses/scx200_acb.c
+++ b/drivers/i2c/busses/scx200_acb.c
@@ -442,14 +442,13 @@ static int __init scx200_acb_create(int base, int index)
int rc = 0;
char description[64];
- iface = kmalloc(sizeof(*iface), GFP_KERNEL);
+ iface = kzalloc(sizeof(*iface), GFP_KERNEL);
if (!iface) {
printk(KERN_ERR NAME ": can't allocate memory\n");
rc = -ENOMEM;
goto errout;
}
- memset(iface, 0, sizeof(*iface));
adapter = &iface->adapter;
i2c_set_adapdata(adapter, iface);
snprintf(adapter->name, I2C_NAME_SIZE, "SCx200 ACB%d", index);
diff --git a/drivers/i2c/chips/Kconfig b/drivers/i2c/chips/Kconfig
index 6bd44a44cd28..f9fae28f5612 100644
--- a/drivers/i2c/chips/Kconfig
+++ b/drivers/i2c/chips/Kconfig
@@ -126,4 +126,13 @@ config SENSORS_MAX6875
This driver can also be built as a module. If so, the module
will be called max6875.
+config RTC_X1205_I2C
+ tristate "Xicor X1205 RTC chip"
+ depends on I2C && EXPERIMENTAL
+ help
+ If you say yes here you get support for the Xicor X1205 RTC chip.
+
+ This driver can also be built as a module. If so, the module
+ will be called x1205.
+
endmenu
diff --git a/drivers/i2c/chips/Makefile b/drivers/i2c/chips/Makefile
index a876dd42b860..46178b57b1f1 100644
--- a/drivers/i2c/chips/Makefile
+++ b/drivers/i2c/chips/Makefile
@@ -13,6 +13,7 @@ obj-$(CONFIG_SENSORS_PCF8591) += pcf8591.o
obj-$(CONFIG_SENSORS_RTC8564) += rtc8564.o
obj-$(CONFIG_ISP1301_OMAP) += isp1301_omap.o
obj-$(CONFIG_TPS65010) += tps65010.o
+obj-$(CONFIG_RTC_X1205_I2C) += x1205.o
ifeq ($(CONFIG_I2C_DEBUG_CHIP),y)
EXTRA_CFLAGS += -DDEBUG
diff --git a/drivers/i2c/chips/ds1337.c b/drivers/i2c/chips/ds1337.c
index 9d3175c03395..02682fb794c8 100644
--- a/drivers/i2c/chips/ds1337.c
+++ b/drivers/i2c/chips/ds1337.c
@@ -164,9 +164,9 @@ static int ds1337_set_datetime(struct i2c_client *client, struct rtc_time *dt)
buf[1] = BIN2BCD(dt->tm_sec);
buf[2] = BIN2BCD(dt->tm_min);
buf[3] = BIN2BCD(dt->tm_hour);
- buf[4] = BIN2BCD(dt->tm_wday) + 1;
+ buf[4] = BIN2BCD(dt->tm_wday + 1);
buf[5] = BIN2BCD(dt->tm_mday);
- buf[6] = BIN2BCD(dt->tm_mon) + 1;
+ buf[6] = BIN2BCD(dt->tm_mon + 1);
val = dt->tm_year;
if (val >= 100) {
val -= 100;
@@ -243,11 +243,10 @@ static int ds1337_detect(struct i2c_adapter *adapter, int address, int kind)
I2C_FUNC_I2C))
goto exit;
- if (!(data = kmalloc(sizeof(struct ds1337_data), GFP_KERNEL))) {
+ if (!(data = kzalloc(sizeof(struct ds1337_data), GFP_KERNEL))) {
err = -ENOMEM;
goto exit;
}
- memset(data, 0, sizeof(struct ds1337_data));
INIT_LIST_HEAD(&data->list);
/* The common I2C client data is placed right before the
diff --git a/drivers/i2c/chips/ds1374.c b/drivers/i2c/chips/ds1374.c
index 0936327a946d..da488b735abf 100644
--- a/drivers/i2c/chips/ds1374.c
+++ b/drivers/i2c/chips/ds1374.c
@@ -167,7 +167,8 @@ static void ds1374_set_tlet(ulong arg)
static ulong new_time;
-DECLARE_TASKLET_DISABLED(ds1374_tasklet, ds1374_set_tlet, (ulong) & new_time);
+static DECLARE_TASKLET_DISABLED(ds1374_tasklet, ds1374_set_tlet,
+ (ulong) & new_time);
int ds1374_set_rtc_time(ulong nowtime)
{
@@ -193,13 +194,11 @@ static int ds1374_probe(struct i2c_adapter *adap, int addr, int kind)
struct i2c_client *client;
int rc;
- client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
+ client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
if (!client)
return -ENOMEM;
- memset(client, 0, sizeof(struct i2c_client));
strncpy(client->name, DS1374_DRV_NAME, I2C_NAME_SIZE);
- client->flags = I2C_DF_NOTIFY;
client->addr = addr;
client->adapter = adap;
client->driver = &ds1374_driver;
diff --git a/drivers/i2c/chips/eeprom.c b/drivers/i2c/chips/eeprom.c
index d58403a47908..4baf573fa04f 100644
--- a/drivers/i2c/chips/eeprom.c
+++ b/drivers/i2c/chips/eeprom.c
@@ -88,8 +88,8 @@ static void eeprom_update_client(struct i2c_client *client, u8 slice)
dev_dbg(&client->dev, "Starting eeprom update, slice %u\n", slice);
if (i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_READ_I2C_BLOCK)) {
- for (i = slice << 5; i < (slice + 1) << 5; i += I2C_SMBUS_I2C_BLOCK_MAX)
- if (i2c_smbus_read_i2c_block_data(client, i, data->data + i) != I2C_SMBUS_I2C_BLOCK_MAX)
+ for (i = slice << 5; i < (slice + 1) << 5; i += I2C_SMBUS_BLOCK_MAX)
+ if (i2c_smbus_read_i2c_block_data(client, i, data->data + i) != I2C_SMBUS_BLOCK_MAX)
goto exit;
} else {
if (i2c_smbus_write_byte(client, slice << 5)) {
@@ -155,7 +155,7 @@ static int eeprom_attach_adapter(struct i2c_adapter *adapter)
}
/* This function is called by i2c_probe */
-int eeprom_detect(struct i2c_adapter *adapter, int address, int kind)
+static int eeprom_detect(struct i2c_adapter *adapter, int address, int kind)
{
struct i2c_client *new_client;
struct eeprom_data *data;
@@ -171,11 +171,10 @@ int eeprom_detect(struct i2c_adapter *adapter, int address, int kind)
| I2C_FUNC_SMBUS_BYTE))
goto exit;
- if (!(data = kmalloc(sizeof(struct eeprom_data), GFP_KERNEL))) {
+ if (!(data = kzalloc(sizeof(struct eeprom_data), GFP_KERNEL))) {
err = -ENOMEM;
goto exit;
}
- memset(data, 0, sizeof(struct eeprom_data));
new_client = &data->client;
memset(data->data, 0xff, EEPROM_SIZE);
diff --git a/drivers/i2c/chips/isp1301_omap.c b/drivers/i2c/chips/isp1301_omap.c
index 8ee56d4b3891..9dbb72fffbe2 100644
--- a/drivers/i2c/chips/isp1301_omap.c
+++ b/drivers/i2c/chips/isp1301_omap.c
@@ -27,7 +27,7 @@
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <linux/usb_ch9.h>
#include <linux/usb_gadget.h>
#include <linux/usb.h>
@@ -888,6 +888,7 @@ static int otg_remove(struct device *dev)
}
struct device_driver omap_otg_driver = {
+ .owner = THIS_MODULE,
.name = "omap_otg",
.bus = &platform_bus_type,
.probe = otg_probe,
diff --git a/drivers/i2c/chips/m41t00.c b/drivers/i2c/chips/m41t00.c
index 3f14528a52a9..3df309ae44a6 100644
--- a/drivers/i2c/chips/m41t00.c
+++ b/drivers/i2c/chips/m41t00.c
@@ -174,13 +174,11 @@ m41t00_probe(struct i2c_adapter *adap, int addr, int kind)
struct i2c_client *client;
int rc;
- client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
+ client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
if (!client)
return -ENOMEM;
- memset(client, 0, sizeof(struct i2c_client));
strncpy(client->name, M41T00_DRV_NAME, I2C_NAME_SIZE);
- client->flags = I2C_DF_NOTIFY;
client->addr = addr;
client->adapter = adap;
client->driver = &m41t00_driver;
diff --git a/drivers/i2c/chips/max6875.c b/drivers/i2c/chips/max6875.c
index 9e1aeb69abf9..b376a006883c 100644
--- a/drivers/i2c/chips/max6875.c
+++ b/drivers/i2c/chips/max6875.c
@@ -179,16 +179,14 @@ static int max6875_detect(struct i2c_adapter *adapter, int address, int kind)
if (address & 1)
return 0;
- if (!(data = kmalloc(sizeof(struct max6875_data), GFP_KERNEL)))
+ if (!(data = kzalloc(sizeof(struct max6875_data), GFP_KERNEL)))
return -ENOMEM;
- memset(data, 0, sizeof(struct max6875_data));
/* A fake client is created on the odd address */
- if (!(fake_client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL))) {
+ if (!(fake_client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL))) {
err = -ENOMEM;
goto exit_kfree1;
}
- memset(fake_client, 0, sizeof(struct i2c_client));
/* Init real i2c_client */
real_client = &data->client;
diff --git a/drivers/i2c/chips/pca9539.c b/drivers/i2c/chips/pca9539.c
index 225577fdda4d..59a930346229 100644
--- a/drivers/i2c/chips/pca9539.c
+++ b/drivers/i2c/chips/pca9539.c
@@ -122,11 +122,10 @@ static int pca9539_detect(struct i2c_adapter *adapter, int address, int kind)
/* OK. For now, we presume we have a valid client. We now create the
client structure, even though we cannot fill it completely yet. */
- if (!(data = kmalloc(sizeof(struct pca9539_data), GFP_KERNEL))) {
+ if (!(data = kzalloc(sizeof(struct pca9539_data), GFP_KERNEL))) {
err = -ENOMEM;
goto exit;
}
- memset(data, 0, sizeof(struct pca9539_data));
new_client = &data->client;
i2c_set_clientdata(new_client, data);
diff --git a/drivers/i2c/chips/pcf8574.c b/drivers/i2c/chips/pcf8574.c
index 6525743ff9fd..c323c2de236c 100644
--- a/drivers/i2c/chips/pcf8574.c
+++ b/drivers/i2c/chips/pcf8574.c
@@ -115,7 +115,7 @@ static int pcf8574_attach_adapter(struct i2c_adapter *adapter)
}
/* This function is called by i2c_probe */
-int pcf8574_detect(struct i2c_adapter *adapter, int address, int kind)
+static int pcf8574_detect(struct i2c_adapter *adapter, int address, int kind)
{
struct i2c_client *new_client;
struct pcf8574_data *data;
@@ -127,11 +127,10 @@ int pcf8574_detect(struct i2c_adapter *adapter, int address, int kind)
/* OK. For now, we presume we have a valid client. We now create the
client structure, even though we cannot fill it completely yet. */
- if (!(data = kmalloc(sizeof(struct pcf8574_data), GFP_KERNEL))) {
+ if (!(data = kzalloc(sizeof(struct pcf8574_data), GFP_KERNEL))) {
err = -ENOMEM;
goto exit;
}
- memset(data, 0, sizeof(struct pcf8574_data));
new_client = &data->client;
i2c_set_clientdata(new_client, data);
diff --git a/drivers/i2c/chips/pcf8591.c b/drivers/i2c/chips/pcf8591.c
index 80f1df9a4500..ce420a67560b 100644
--- a/drivers/i2c/chips/pcf8591.c
+++ b/drivers/i2c/chips/pcf8591.c
@@ -166,7 +166,7 @@ static int pcf8591_attach_adapter(struct i2c_adapter *adapter)
}
/* This function is called by i2c_probe */
-int pcf8591_detect(struct i2c_adapter *adapter, int address, int kind)
+static int pcf8591_detect(struct i2c_adapter *adapter, int address, int kind)
{
struct i2c_client *new_client;
struct pcf8591_data *data;
@@ -178,11 +178,10 @@ int pcf8591_detect(struct i2c_adapter *adapter, int address, int kind)
/* OK. For now, we presume we have a valid client. We now create the
client structure, even though we cannot fill it completely yet. */
- if (!(data = kmalloc(sizeof(struct pcf8591_data), GFP_KERNEL))) {
+ if (!(data = kzalloc(sizeof(struct pcf8591_data), GFP_KERNEL))) {
err = -ENOMEM;
goto exit;
}
- memset(data, 0, sizeof(struct pcf8591_data));
new_client = &data->client;
i2c_set_clientdata(new_client, data);
diff --git a/drivers/i2c/chips/rtc8564.c b/drivers/i2c/chips/rtc8564.c
index 0b5385c892b1..916cdc1af23c 100644
--- a/drivers/i2c/chips/rtc8564.c
+++ b/drivers/i2c/chips/rtc8564.c
@@ -148,17 +148,16 @@ static int rtc8564_attach(struct i2c_adapter *adap, int addr, int kind)
{addr, I2C_M_RD, 2, data}
};
- d = kmalloc(sizeof(struct rtc8564_data), GFP_KERNEL);
+ d = kzalloc(sizeof(struct rtc8564_data), GFP_KERNEL);
if (!d) {
ret = -ENOMEM;
goto done;
}
- memset(d, 0, sizeof(struct rtc8564_data));
new_client = &d->client;
strlcpy(new_client->name, "RTC8564", I2C_NAME_SIZE);
i2c_set_clientdata(new_client, d);
- new_client->flags = I2C_CLIENT_ALLOW_USE | I2C_DF_NOTIFY;
+ new_client->flags = I2C_CLIENT_ALLOW_USE;
new_client->addr = addr;
new_client->adapter = adap;
new_client->driver = &rtc8564_driver;
diff --git a/drivers/i2c/chips/tps65010.c b/drivers/i2c/chips/tps65010.c
index 280e9638c0f8..280dd7a45db6 100644
--- a/drivers/i2c/chips/tps65010.c
+++ b/drivers/i2c/chips/tps65010.c
@@ -500,11 +500,10 @@ tps65010_probe(struct i2c_adapter *bus, int address, int kind)
return 0;
}
- tps = kmalloc(sizeof *tps, GFP_KERNEL);
+ tps = kzalloc(sizeof *tps, GFP_KERNEL);
if (!tps)
return 0;
- memset(tps, 0, sizeof *tps);
init_MUTEX(&tps->lock);
INIT_WORK(&tps->work, tps65010_work, tps);
tps->irq = -1;
diff --git a/drivers/i2c/chips/x1205.c b/drivers/i2c/chips/x1205.c
new file mode 100644
index 000000000000..7da366cdc18c
--- /dev/null
+++ b/drivers/i2c/chips/x1205.c
@@ -0,0 +1,698 @@
+/*
+ * x1205.c - An i2c driver for the Xicor X1205 RTC
+ * Copyright 2004 Karen Spearel
+ * Copyright 2005 Alessandro Zummo
+ *
+ * please send all reports to:
+ * kas11 at tampabay dot rr dot com
+ * a dot zummo at towertech dot it
+ *
+ * based on the other drivers in this same directory.
+ *
+ * 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/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/string.h>
+#include <linux/bcd.h>
+#include <linux/rtc.h>
+#include <linux/list.h>
+
+#include <linux/x1205.h>
+
+#define DRV_VERSION "0.9.9"
+
+/* Addresses to scan: none. This chip is located at
+ * 0x6f and uses a two bytes register addressing.
+ * Two bytes need to be written to read a single register,
+ * while most other chips just require one and take the second
+ * one as the data to be written. To prevent corrupting
+ * unknown chips, the user must explicitely set the probe parameter.
+ */
+
+static unsigned short normal_i2c[] = { I2C_CLIENT_END };
+
+/* Insmod parameters */
+I2C_CLIENT_INSMOD;
+I2C_CLIENT_MODULE_PARM(hctosys,
+ "Set the system time from the hardware clock upon initialization");
+
+/* offsets into CCR area */
+
+#define CCR_SEC 0
+#define CCR_MIN 1
+#define CCR_HOUR 2
+#define CCR_MDAY 3
+#define CCR_MONTH 4
+#define CCR_YEAR 5
+#define CCR_WDAY 6
+#define CCR_Y2K 7
+
+#define X1205_REG_SR 0x3F /* status register */
+#define X1205_REG_Y2K 0x37
+#define X1205_REG_DW 0x36
+#define X1205_REG_YR 0x35
+#define X1205_REG_MO 0x34
+#define X1205_REG_DT 0x33
+#define X1205_REG_HR 0x32
+#define X1205_REG_MN 0x31
+#define X1205_REG_SC 0x30
+#define X1205_REG_DTR 0x13
+#define X1205_REG_ATR 0x12
+#define X1205_REG_INT 0x11
+#define X1205_REG_0 0x10
+#define X1205_REG_Y2K1 0x0F
+#define X1205_REG_DWA1 0x0E
+#define X1205_REG_YRA1 0x0D
+#define X1205_REG_MOA1 0x0C
+#define X1205_REG_DTA1 0x0B
+#define X1205_REG_HRA1 0x0A
+#define X1205_REG_MNA1 0x09
+#define X1205_REG_SCA1 0x08
+#define X1205_REG_Y2K0 0x07
+#define X1205_REG_DWA0 0x06
+#define X1205_REG_YRA0 0x05
+#define X1205_REG_MOA0 0x04
+#define X1205_REG_DTA0 0x03
+#define X1205_REG_HRA0 0x02
+#define X1205_REG_MNA0 0x01
+#define X1205_REG_SCA0 0x00
+
+#define X1205_CCR_BASE 0x30 /* Base address of CCR */
+#define X1205_ALM0_BASE 0x00 /* Base address of ALARM0 */
+
+#define X1205_SR_RTCF 0x01 /* Clock failure */
+#define X1205_SR_WEL 0x02 /* Write Enable Latch */
+#define X1205_SR_RWEL 0x04 /* Register Write Enable */
+
+#define X1205_DTR_DTR0 0x01
+#define X1205_DTR_DTR1 0x02
+#define X1205_DTR_DTR2 0x04
+
+#define X1205_HR_MIL 0x80 /* Set in ccr.hour for 24 hr mode */
+
+/* Prototypes */
+static int x1205_attach(struct i2c_adapter *adapter);
+static int x1205_detach(struct i2c_client *client);
+static int x1205_probe(struct i2c_adapter *adapter, int address, int kind);
+static int x1205_command(struct i2c_client *client, unsigned int cmd,
+ void *arg);
+
+static struct i2c_driver x1205_driver = {
+ .owner = THIS_MODULE,
+ .name = "x1205",
+ .flags = I2C_DF_NOTIFY,
+ .attach_adapter = &x1205_attach,
+ .detach_client = &x1205_detach,
+};
+
+struct x1205_data {
+ struct i2c_client client;
+ struct list_head list;
+ unsigned int epoch;
+};
+
+static const unsigned char days_in_mo[] =
+ { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
+
+static LIST_HEAD(x1205_clients);
+
+/* Workaround until the I2C subsytem will allow to send
+ * commands to a specific client. This function will send the command
+ * to the first client.
+ */
+int x1205_do_command(unsigned int cmd, void *arg)
+{
+ struct list_head *walk;
+ struct list_head *tmp;
+ struct x1205_data *data;
+
+ list_for_each_safe(walk, tmp, &x1205_clients) {
+ data = list_entry(walk, struct x1205_data, list);
+ return x1205_command(&data->client, cmd, arg);
+ }
+
+ return -ENODEV;
+}
+
+#define is_leap(year) \
+ ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))
+
+/* make sure the rtc_time values are in bounds */
+static int x1205_validate_tm(struct rtc_time *tm)
+{
+ int year = tm->tm_year + 1900;
+
+ if ((tm->tm_year < 70) || (tm->tm_year > 255))
+ return -EINVAL;
+
+ if ((tm->tm_mon > 11) || (tm->tm_mday == 0))
+ return -EINVAL;
+
+ if (tm->tm_mday > days_in_mo[tm->tm_mon]
+ + ((tm->tm_mon == 1) && is_leap(year)))
+ return -EINVAL;
+
+ if ((tm->tm_hour >= 24) || (tm->tm_min >= 60) || (tm->tm_sec >= 60))
+ return -EINVAL;
+
+ return 0;
+}
+
+/*
+ * In the routines that deal directly with the x1205 hardware, we use
+ * rtc_time -- month 0-11, hour 0-23, yr = calendar year-epoch
+ * Epoch is initialized as 2000. Time is set to UTC.
+ */
+static int x1205_get_datetime(struct i2c_client *client, struct rtc_time *tm,
+ u8 reg_base)
+{
+ unsigned char dt_addr[2] = { 0, reg_base };
+ static unsigned char sr_addr[2] = { 0, X1205_REG_SR };
+
+ unsigned char buf[8], sr;
+
+ struct i2c_msg msgs[] = {
+ { client->addr, 0, 2, sr_addr }, /* setup read ptr */
+ { client->addr, I2C_M_RD, 1, &sr }, /* read status */
+ { client->addr, 0, 2, dt_addr }, /* setup read ptr */
+ { client->addr, I2C_M_RD, 8, buf }, /* read date */
+ };
+
+ struct x1205_data *data = i2c_get_clientdata(client);
+
+ /* read status register */
+ if ((i2c_transfer(client->adapter, &msgs[0], 2)) != 2) {
+ dev_err(&client->dev, "%s: read error\n", __FUNCTION__);
+ return -EIO;
+ }
+
+ /* check for battery failure */
+ if (sr & X1205_SR_RTCF) {
+ dev_warn(&client->dev,
+ "Clock had a power failure, you must set the date.\n");
+ return -EINVAL;
+ }
+
+ /* read date registers */
+ if ((i2c_transfer(client->adapter, &msgs[2], 2)) != 2) {
+ dev_err(&client->dev, "%s: read error\n", __FUNCTION__);
+ return -EIO;
+ }
+
+ dev_dbg(&client->dev,
+ "%s: raw read data - sec=%02x, min=%02x, hr=%02x, "
+ "mday=%02x, mon=%02x, year=%02x, wday=%02x, y2k=%02x\n",
+ __FUNCTION__,
+ buf[0], buf[1], buf[2], buf[3],
+ buf[4], buf[5], buf[6], buf[7]);
+
+ tm->tm_sec = BCD2BIN(buf[CCR_SEC]);
+ tm->tm_min = BCD2BIN(buf[CCR_MIN]);
+ tm->tm_hour = BCD2BIN(buf[CCR_HOUR] & 0x3F); /* hr is 0-23 */
+ tm->tm_mday = BCD2BIN(buf[CCR_MDAY]);
+ tm->tm_mon = BCD2BIN(buf[CCR_MONTH]);
+ data->epoch = BCD2BIN(buf[CCR_Y2K]) * 100;
+ tm->tm_year = BCD2BIN(buf[CCR_YEAR]) + data->epoch - 1900;
+ tm->tm_wday = buf[CCR_WDAY];
+
+ dev_dbg(&client->dev, "%s: tm is secs=%d, mins=%d, hours=%d, "
+ "mday=%d, mon=%d, year=%d, wday=%d\n",
+ __FUNCTION__,
+ tm->tm_sec, tm->tm_min, tm->tm_hour,
+ tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday);
+
+ return 0;
+}
+
+static int x1205_set_datetime(struct i2c_client *client, struct rtc_time *tm,
+ int datetoo, u8 reg_base)
+{
+ int i, err, xfer;
+
+ unsigned char buf[8];
+
+ static const unsigned char wel[3] = { 0, X1205_REG_SR,
+ X1205_SR_WEL };
+
+ static const unsigned char rwel[3] = { 0, X1205_REG_SR,
+ X1205_SR_WEL | X1205_SR_RWEL };
+
+ static const unsigned char diswe[3] = { 0, X1205_REG_SR, 0 };
+
+ struct x1205_data *data = i2c_get_clientdata(client);
+
+ /* check if all values in the tm struct are correct */
+ if ((err = x1205_validate_tm(tm)) < 0)
+ return err;
+
+ dev_dbg(&client->dev, "%s: secs=%d, mins=%d, hours=%d, "
+ "mday=%d, mon=%d, year=%d, wday=%d\n",
+ __FUNCTION__,
+ tm->tm_sec, tm->tm_min, tm->tm_hour,
+ tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday);
+
+ buf[CCR_SEC] = BIN2BCD(tm->tm_sec);
+ buf[CCR_MIN] = BIN2BCD(tm->tm_min);
+
+ /* set hour and 24hr bit */
+ buf[CCR_HOUR] = BIN2BCD(tm->tm_hour) | X1205_HR_MIL;
+
+ /* should we also set the date? */
+ if (datetoo) {
+ buf[CCR_MDAY] = BIN2BCD(tm->tm_mday);
+
+ /* month, 0 - 11 */
+ buf[CCR_MONTH] = BIN2BCD(tm->tm_mon);
+
+ /* year, since 1900 */
+ buf[CCR_YEAR] = BIN2BCD(tm->tm_year + 1900 - data->epoch);
+ buf[CCR_WDAY] = tm->tm_wday & 0x07;
+ buf[CCR_Y2K] = BIN2BCD(data->epoch / 100);
+ }
+
+ /* this sequence is required to unlock the chip */
+ xfer = i2c_master_send(client, wel, 3);
+ if (xfer != 3) {
+ dev_err(&client->dev, "%s: wel - %d\n", __FUNCTION__, xfer);
+ return -EIO;
+ }
+
+ xfer = i2c_master_send(client, rwel, 3);
+ if (xfer != 3) {
+ dev_err(&client->dev, "%s: rwel - %d\n", __FUNCTION__, xfer);
+ return -EIO;
+ }
+
+ /* write register's data */
+ for (i = 0; i < (datetoo ? 8 : 3); i++) {
+ unsigned char rdata[3] = { 0, reg_base + i, buf[i] };
+
+ xfer = i2c_master_send(client, rdata, 3);
+ if (xfer != 3) {
+ dev_err(&client->dev,
+ "%s: xfer=%d addr=%02x, data=%02x\n",
+ __FUNCTION__,
+ xfer, rdata[1], rdata[2]);
+ return -EIO;
+ }
+ };
+
+ /* disable further writes */
+ xfer = i2c_master_send(client, diswe, 3);
+ if (xfer != 3) {
+ dev_err(&client->dev, "%s: diswe - %d\n", __FUNCTION__, xfer);
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static int x1205_get_dtrim(struct i2c_client *client, int *trim)
+{
+ unsigned char dtr;
+ static unsigned char dtr_addr[2] = { 0, X1205_REG_DTR };
+
+ struct i2c_msg msgs[] = {
+ { client->addr, 0, 2, dtr_addr }, /* setup read ptr */
+ { client->addr, I2C_M_RD, 1, &dtr }, /* read dtr */
+ };
+
+ /* read dtr register */
+ if ((i2c_transfer(client->adapter, &msgs[0], 2)) != 2) {
+ dev_err(&client->dev, "%s: read error\n", __FUNCTION__);
+ return -EIO;
+ }
+
+ dev_dbg(&client->dev, "%s: raw dtr=%x\n", __FUNCTION__, dtr);
+
+ *trim = 0;
+
+ if (dtr & X1205_DTR_DTR0)
+ *trim += 20;
+
+ if (dtr & X1205_DTR_DTR1)
+ *trim += 10;
+
+ if (dtr & X1205_DTR_DTR2)
+ *trim = -*trim;
+
+ return 0;
+}
+
+static int x1205_get_atrim(struct i2c_client *client, int *trim)
+{
+ s8 atr;
+ static unsigned char atr_addr[2] = { 0, X1205_REG_ATR };
+
+ struct i2c_msg msgs[] = {
+ { client->addr, 0, 2, atr_addr }, /* setup read ptr */
+ { client->addr, I2C_M_RD, 1, &atr }, /* read atr */
+ };
+
+ /* read atr register */
+ if ((i2c_transfer(client->adapter, &msgs[0], 2)) != 2) {
+ dev_err(&client->dev, "%s: read error\n", __FUNCTION__);
+ return -EIO;
+ }
+
+ dev_dbg(&client->dev, "%s: raw atr=%x\n", __FUNCTION__, atr);
+
+ /* atr is a two's complement value on 6 bits,
+ * perform sign extension. The formula is
+ * Catr = (atr * 0.25pF) + 11.00pF.
+ */
+ if (atr & 0x20)
+ atr |= 0xC0;
+
+ dev_dbg(&client->dev, "%s: raw atr=%x (%d)\n", __FUNCTION__, atr, atr);
+
+ *trim = (atr * 250) + 11000;
+
+ dev_dbg(&client->dev, "%s: real=%d\n", __FUNCTION__, *trim);
+
+ return 0;
+}
+
+static int x1205_hctosys(struct i2c_client *client)
+{
+ int err;
+
+ struct rtc_time tm;
+ struct timespec tv;
+
+ err = x1205_command(client, X1205_CMD_GETDATETIME, &tm);
+
+ if (err) {
+ dev_err(&client->dev,
+ "Unable to set the system clock\n");
+ return err;
+ }
+
+ /* IMPORTANT: the RTC only stores whole seconds. It is arbitrary
+ * whether it stores the most close value or the value with partial
+ * seconds truncated. However, it is important that we use it to store
+ * the truncated value. This is because otherwise it is necessary,
+ * in an rtc sync function, to read both xtime.tv_sec and
+ * xtime.tv_nsec. On some processors (i.e. ARM), an atomic read
+ * of >32bits is not possible. So storing the most close value would
+ * slow down the sync API. So here we have the truncated value and
+ * the best guess is to add 0.5s.
+ */
+
+ tv.tv_nsec = NSEC_PER_SEC >> 1;
+
+ /* WARNING: this is not the C library 'mktime' call, it is a built in
+ * inline function from include/linux/time.h. It expects (requires)
+ * the month to be in the range 1-12
+ */
+
+ tv.tv_sec = mktime(tm.tm_year + 1900, tm.tm_mon + 1,
+ tm.tm_mday, tm.tm_hour,
+ tm.tm_min, tm.tm_sec);
+
+ do_settimeofday(&tv);
+
+ dev_info(&client->dev,
+ "setting the system clock to %d-%d-%d %d:%d:%d\n",
+ tm.tm_year + 1900, tm.tm_mon + 1,
+ tm.tm_mday, tm.tm_hour, tm.tm_min,
+ tm.tm_sec);
+
+ return 0;
+}
+
+struct x1205_limit
+{
+ unsigned char reg;
+ unsigned char mask;
+ unsigned char min;
+ unsigned char max;
+};
+
+static int x1205_validate_client(struct i2c_client *client)
+{
+ int i, xfer;
+
+ /* Probe array. We will read the register at the specified
+ * address and check if the given bits are zero.
+ */
+ static const unsigned char probe_zero_pattern[] = {
+ /* register, mask */
+ X1205_REG_SR, 0x18,
+ X1205_REG_DTR, 0xF8,
+ X1205_REG_ATR, 0xC0,
+ X1205_REG_INT, 0x18,
+ X1205_REG_0, 0xFF,
+ };
+
+ static const struct x1205_limit probe_limits_pattern[] = {
+ /* register, mask, min, max */
+ { X1205_REG_Y2K, 0xFF, 19, 20 },
+ { X1205_REG_DW, 0xFF, 0, 6 },
+ { X1205_REG_YR, 0xFF, 0, 99 },
+ { X1205_REG_MO, 0xFF, 0, 12 },
+ { X1205_REG_DT, 0xFF, 0, 31 },
+ { X1205_REG_HR, 0x7F, 0, 23 },
+ { X1205_REG_MN, 0xFF, 0, 59 },
+ { X1205_REG_SC, 0xFF, 0, 59 },
+ { X1205_REG_Y2K1, 0xFF, 19, 20 },
+ { X1205_REG_Y2K0, 0xFF, 19, 20 },
+ };
+
+ /* check that registers have bits a 0 where expected */
+ for (i = 0; i < ARRAY_SIZE(probe_zero_pattern); i += 2) {
+ unsigned char buf;
+
+ unsigned char addr[2] = { 0, probe_zero_pattern[i] };
+
+ struct i2c_msg msgs[2] = {
+ { client->addr, 0, 2, addr },
+ { client->addr, I2C_M_RD, 1, &buf },
+ };
+
+ xfer = i2c_transfer(client->adapter, msgs, 2);
+ if (xfer != 2) {
+ dev_err(&client->adapter->dev,
+ "%s: could not read register %x\n",
+ __FUNCTION__, addr[1]);
+
+ return -EIO;
+ }
+
+ if ((buf & probe_zero_pattern[i+1]) != 0) {
+ dev_err(&client->adapter->dev,
+ "%s: register=%02x, zero pattern=%d, value=%x\n",
+ __FUNCTION__, addr[1], i, buf);
+
+ return -ENODEV;
+ }
+ }
+
+ /* check limits (only registers with bcd values) */
+ for (i = 0; i < ARRAY_SIZE(probe_limits_pattern); i++) {
+ unsigned char reg, value;
+
+ unsigned char addr[2] = { 0, probe_limits_pattern[i].reg };
+
+ struct i2c_msg msgs[2] = {
+ { client->addr, 0, 2, addr },
+ { client->addr, I2C_M_RD, 1, &reg },
+ };
+
+ xfer = i2c_transfer(client->adapter, msgs, 2);
+
+ if (xfer != 2) {
+ dev_err(&client->adapter->dev,
+ "%s: could not read register %x\n",
+ __FUNCTION__, addr[1]);
+
+ return -EIO;
+ }
+
+ value = BCD2BIN(reg & probe_limits_pattern[i].mask);
+
+ if (value > probe_limits_pattern[i].max ||
+ value < probe_limits_pattern[i].min) {
+ dev_dbg(&client->adapter->dev,
+ "%s: register=%x, lim pattern=%d, value=%d\n",
+ __FUNCTION__, addr[1], i, value);
+
+ return -ENODEV;
+ }
+ }
+
+ return 0;
+}
+
+static int x1205_attach(struct i2c_adapter *adapter)
+{
+ dev_dbg(&adapter->dev, "%s\n", __FUNCTION__);
+
+ return i2c_probe(adapter, &addr_data, x1205_probe);
+}
+
+int x1205_direct_attach(int adapter_id,
+ struct i2c_client_address_data *address_data)
+{
+ int err;
+ struct i2c_adapter *adapter = i2c_get_adapter(adapter_id);
+
+ if (adapter) {
+ err = i2c_probe(adapter,
+ address_data, x1205_probe);
+
+ i2c_put_adapter(adapter);
+
+ return err;
+ }
+
+ return -ENODEV;
+}
+
+static int x1205_probe(struct i2c_adapter *adapter, int address, int kind)
+{
+ struct i2c_client *client;
+ struct x1205_data *data;
+
+ int err = 0;
+
+ dev_dbg(&adapter->dev, "%s\n", __FUNCTION__);
+
+ if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) {
+ err = -ENODEV;
+ goto exit;
+ }
+
+ if (!(data = kzalloc(sizeof(struct x1205_data), GFP_KERNEL))) {
+ err = -ENOMEM;
+ goto exit;
+ }
+
+ /* Initialize our structures */
+ data->epoch = 2000;
+
+ client = &data->client;
+ client->addr = address;
+ client->driver = &x1205_driver;
+ client->adapter = adapter;
+
+ strlcpy(client->name, "x1205", I2C_NAME_SIZE);
+
+ i2c_set_clientdata(client, data);
+
+ /* Verify the chip is really an X1205 */
+ if (kind < 0) {
+ if (x1205_validate_client(client) < 0) {
+ err = -ENODEV;
+ goto exit_kfree;
+ }
+ }
+
+ /* Inform the i2c layer */
+ if ((err = i2c_attach_client(client)))
+ goto exit_kfree;
+
+ list_add(&data->list, &x1205_clients);
+
+ dev_info(&client->dev, "chip found, driver version " DRV_VERSION "\n");
+
+ /* If requested, set the system time */
+ if (hctosys)
+ x1205_hctosys(client);
+
+ return 0;
+
+exit_kfree:
+ kfree(data);
+
+exit:
+ return err;
+}
+
+static int x1205_detach(struct i2c_client *client)
+{
+ int err;
+ struct x1205_data *data = i2c_get_clientdata(client);
+
+ dev_dbg(&client->dev, "%s\n", __FUNCTION__);
+
+ if ((err = i2c_detach_client(client)))
+ return err;
+
+ list_del(&data->list);
+
+ kfree(data);
+
+ return 0;
+}
+
+static int x1205_command(struct i2c_client *client, unsigned int cmd,
+ void *param)
+{
+ if (param == NULL)
+ return -EINVAL;
+
+ if (!capable(CAP_SYS_TIME))
+ return -EACCES;
+
+ dev_dbg(&client->dev, "%s: cmd=%d\n", __FUNCTION__, cmd);
+
+ switch (cmd) {
+ case X1205_CMD_GETDATETIME:
+ return x1205_get_datetime(client, param, X1205_CCR_BASE);
+
+ case X1205_CMD_SETTIME:
+ return x1205_set_datetime(client, param, 0,
+ X1205_CCR_BASE);
+
+ case X1205_CMD_SETDATETIME:
+ return x1205_set_datetime(client, param, 1,
+ X1205_CCR_BASE);
+
+ case X1205_CMD_GETALARM:
+ return x1205_get_datetime(client, param, X1205_ALM0_BASE);
+
+ case X1205_CMD_SETALARM:
+ return x1205_set_datetime(client, param, 1,
+ X1205_ALM0_BASE);
+
+ case X1205_CMD_GETDTRIM:
+ return x1205_get_dtrim(client, param);
+
+ case X1205_CMD_GETATRIM:
+ return x1205_get_atrim(client, param);
+
+ default:
+ return -EINVAL;
+ }
+}
+
+static int __init x1205_init(void)
+{
+ return i2c_add_driver(&x1205_driver);
+}
+
+static void __exit x1205_exit(void)
+{
+ i2c_del_driver(&x1205_driver);
+}
+
+MODULE_AUTHOR(
+ "Karen Spearel <kas11@tampabay.rr.com>, "
+ "Alessandro Zummo <a.zummo@towertech.it>");
+MODULE_DESCRIPTION("Xicor X1205 RTC driver");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(DRV_VERSION);
+
+EXPORT_SYMBOL_GPL(x1205_do_command);
+EXPORT_SYMBOL_GPL(x1205_direct_attach);
+
+module_init(x1205_init);
+module_exit(x1205_exit);
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
index dda472e5e8be..82ea1b7ec914 100644
--- a/drivers/i2c/i2c-core.c
+++ b/drivers/i2c/i2c-core.c
@@ -19,7 +19,8 @@
/* With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi>.
All SMBus-related things are written by Frodo Looijaard <frodol@dds.nl>
- SMBus 2.0 support by Mark Studebaker <mdsxyz123@yahoo.com> */
+ SMBus 2.0 support by Mark Studebaker <mdsxyz123@yahoo.com> and
+ Jean Delvare <khali@linux-fr.org> */
#include <linux/module.h>
#include <linux/kernel.h>
@@ -29,6 +30,7 @@
#include <linux/init.h>
#include <linux/idr.h>
#include <linux/seq_file.h>
+#include <linux/platform_device.h>
#include <asm/uaccess.h>
@@ -48,7 +50,7 @@ static int i2c_bus_suspend(struct device * dev, pm_message_t state)
int rc = 0;
if (dev->driver && dev->driver->suspend)
- rc = dev->driver->suspend(dev,state,0);
+ rc = dev->driver->suspend(dev, state);
return rc;
}
@@ -57,7 +59,7 @@ static int i2c_bus_resume(struct device * dev)
int rc = 0;
if (dev->driver && dev->driver->resume)
- rc = dev->driver->resume(dev,0);
+ rc = dev->driver->resume(dev);
return rc;
}
@@ -85,6 +87,7 @@ void i2c_adapter_dev_release(struct device *dev)
}
struct device_driver i2c_adapter_driver = {
+ .owner = THIS_MODULE,
.name = "i2c_adapter",
.bus = &i2c_bus_type,
.probe = i2c_device_probe,
@@ -98,6 +101,7 @@ static void i2c_adapter_class_dev_release(struct class_device *dev)
}
struct class i2c_adapter_class = {
+ .owner = THIS_MODULE,
.name = "i2c-adapter",
.release = &i2c_adapter_class_dev_release,
};
@@ -291,6 +295,7 @@ int i2c_add_driver(struct i2c_driver *driver)
down(&core_lists);
/* add the driver to the list of i2c drivers in the driver core */
+ driver->driver.owner = driver->owner;
driver->driver.name = driver->name;
driver->driver.bus = &i2c_bus_type;
driver->driver.probe = i2c_device_probe;
@@ -706,10 +711,6 @@ int i2c_probe(struct i2c_adapter *adapter,
int i, err;
int adap_id = i2c_adapter_id(adapter);
- /* Forget it if we can't probe using SMBUS_QUICK */
- if (! i2c_check_functionality(adapter,I2C_FUNC_SMBUS_QUICK))
- return -1;
-
/* Force entries are done first, and are not affected by ignore
entries */
if (address_data->forces) {
@@ -736,6 +737,17 @@ int i2c_probe(struct i2c_adapter *adapter,
}
}
+ /* 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_warn(&adapter->dev, "SMBus Quick command not supported, "
+ "can't probe for chips\n");
+ return -1;
+ }
+
/* 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) {
@@ -820,101 +832,44 @@ crc8(u16 data)
return (u8)(data >> 8);
}
-/* CRC over count bytes in the first array plus the bytes in the rest
- array if it is non-null. rest[0] is the (length of rest) - 1
- and is included. */
-static u8 i2c_smbus_partial_pec(u8 crc, int count, u8 *first, u8 *rest)
+/* Incremental CRC8 over count bytes in the array pointed to by p */
+static u8 i2c_smbus_pec(u8 crc, u8 *p, size_t count)
{
int i;
for(i = 0; i < count; i++)
- crc = crc8((crc ^ first[i]) << 8);
- if(rest != NULL)
- for(i = 0; i <= rest[0]; i++)
- crc = crc8((crc ^ rest[i]) << 8);
+ crc = crc8((crc ^ p[i]) << 8);
return crc;
}
-static u8 i2c_smbus_pec(int count, u8 *first, u8 *rest)
+/* Assume a 7-bit address, which is reasonable for SMBus */
+static u8 i2c_smbus_msg_pec(u8 pec, struct i2c_msg *msg)
{
- return i2c_smbus_partial_pec(0, count, first, rest);
+ /* The address will be sent first */
+ u8 addr = (msg->addr << 1) | !!(msg->flags & I2C_M_RD);
+ pec = i2c_smbus_pec(pec, &addr, 1);
+
+ /* The data buffer follows */
+ return i2c_smbus_pec(pec, msg->buf, msg->len);
}
-/* Returns new "size" (transaction type)
- Note that we convert byte to byte_data and byte_data to word_data
- rather than invent new xxx_PEC transactions. */
-static int i2c_smbus_add_pec(u16 addr, u8 command, int size,
- union i2c_smbus_data *data)
+/* Used for write only transactions */
+static inline void i2c_smbus_add_pec(struct i2c_msg *msg)
{
- u8 buf[3];
-
- buf[0] = addr << 1;
- buf[1] = command;
- switch(size) {
- case I2C_SMBUS_BYTE:
- data->byte = i2c_smbus_pec(2, buf, NULL);
- size = I2C_SMBUS_BYTE_DATA;
- break;
- case I2C_SMBUS_BYTE_DATA:
- buf[2] = data->byte;
- data->word = buf[2] ||
- (i2c_smbus_pec(3, buf, NULL) << 8);
- size = I2C_SMBUS_WORD_DATA;
- break;
- case I2C_SMBUS_WORD_DATA:
- /* unsupported */
- break;
- case I2C_SMBUS_BLOCK_DATA:
- data->block[data->block[0] + 1] =
- i2c_smbus_pec(2, buf, data->block);
- size = I2C_SMBUS_BLOCK_DATA_PEC;
- break;
- }
- return size;
+ msg->buf[msg->len] = i2c_smbus_msg_pec(0, msg);
+ msg->len++;
}
-static int i2c_smbus_check_pec(u16 addr, u8 command, int size, u8 partial,
- union i2c_smbus_data *data)
+/* Return <0 on CRC error
+ If there was a write before this read (most cases) we need to take the
+ partial CRC from the write part into account.
+ Note that this function does modify the message (we need to decrease the
+ message length to hide the CRC byte from the caller). */
+static int i2c_smbus_check_pec(u8 cpec, struct i2c_msg *msg)
{
- u8 buf[3], rpec, cpec;
+ u8 rpec = msg->buf[--msg->len];
+ cpec = i2c_smbus_msg_pec(cpec, msg);
- buf[1] = command;
- switch(size) {
- case I2C_SMBUS_BYTE_DATA:
- buf[0] = (addr << 1) | 1;
- cpec = i2c_smbus_pec(2, buf, NULL);
- rpec = data->byte;
- break;
- case I2C_SMBUS_WORD_DATA:
- buf[0] = (addr << 1) | 1;
- buf[2] = data->word & 0xff;
- cpec = i2c_smbus_pec(3, buf, NULL);
- rpec = data->word >> 8;
- break;
- case I2C_SMBUS_WORD_DATA_PEC:
- /* unsupported */
- cpec = rpec = 0;
- break;
- case I2C_SMBUS_PROC_CALL_PEC:
- /* unsupported */
- cpec = rpec = 0;
- break;
- case I2C_SMBUS_BLOCK_DATA_PEC:
- buf[0] = (addr << 1);
- buf[2] = (addr << 1) | 1;
- cpec = i2c_smbus_pec(3, buf, data->block);
- rpec = data->block[data->block[0] + 1];
- break;
- case I2C_SMBUS_BLOCK_PROC_CALL_PEC:
- buf[0] = (addr << 1) | 1;
- rpec = i2c_smbus_partial_pec(partial, 1,
- buf, data->block);
- cpec = data->block[data->block[0] + 1];
- break;
- default:
- cpec = rpec = 0;
- break;
- }
if (rpec != cpec) {
pr_debug("i2c-core: Bad PEC 0x%02x vs. 0x%02x\n",
rpec, cpec);
@@ -941,9 +896,8 @@ s32 i2c_smbus_read_byte(struct i2c_client *client)
s32 i2c_smbus_write_byte(struct i2c_client *client, u8 value)
{
- union i2c_smbus_data data; /* only for PEC */
return i2c_smbus_xfer(client->adapter,client->addr,client->flags,
- I2C_SMBUS_WRITE,value, I2C_SMBUS_BYTE,&data);
+ I2C_SMBUS_WRITE, value, I2C_SMBUS_BYTE, NULL);
}
s32 i2c_smbus_read_byte_data(struct i2c_client *client, u8 command)
@@ -1026,13 +980,14 @@ static s32 i2c_smbus_xfer_emulated(struct i2c_adapter * adapter, u16 addr,
need to use only one message; when reading, we need two. We initialize
most things with sane defaults, to keep the code below somewhat
simpler. */
- unsigned char msgbuf0[34];
- unsigned char msgbuf1[34];
+ unsigned char msgbuf0[I2C_SMBUS_BLOCK_MAX+3];
+ unsigned char msgbuf1[I2C_SMBUS_BLOCK_MAX+2];
int num = read_write == I2C_SMBUS_READ?2:1;
struct i2c_msg msg[2] = { { addr, flags, 1, msgbuf0 },
{ addr, flags | I2C_M_RD, 0, msgbuf1 }
};
int i;
+ u8 partial_pec = 0;
msgbuf0[0] = command;
switch(size) {
@@ -1075,7 +1030,6 @@ static s32 i2c_smbus_xfer_emulated(struct i2c_adapter * adapter, u16 addr,
msgbuf0[2] = (data->word >> 8) & 0xff;
break;
case I2C_SMBUS_BLOCK_DATA:
- case I2C_SMBUS_BLOCK_DATA_PEC:
if (read_write == I2C_SMBUS_READ) {
dev_err(&adapter->dev, "Block read not supported "
"under I2C emulation!\n");
@@ -1088,23 +1042,20 @@ static s32 i2c_smbus_xfer_emulated(struct i2c_adapter * adapter, u16 addr,
data->block[0]);
return -1;
}
- if(size == I2C_SMBUS_BLOCK_DATA_PEC)
- (msg[0].len)++;
- for (i = 1; i <= msg[0].len; i++)
+ for (i = 1; i < msg[0].len; i++)
msgbuf0[i] = data->block[i-1];
}
break;
case I2C_SMBUS_BLOCK_PROC_CALL:
- case I2C_SMBUS_BLOCK_PROC_CALL_PEC:
dev_dbg(&adapter->dev, "Block process call not supported "
"under I2C emulation!\n");
return -1;
case I2C_SMBUS_I2C_BLOCK_DATA:
if (read_write == I2C_SMBUS_READ) {
- msg[1].len = I2C_SMBUS_I2C_BLOCK_MAX;
+ msg[1].len = I2C_SMBUS_BLOCK_MAX;
} else {
msg[0].len = data->block[0] + 1;
- if (msg[0].len > I2C_SMBUS_I2C_BLOCK_MAX + 1) {
+ if (msg[0].len > I2C_SMBUS_BLOCK_MAX + 1) {
dev_err(&adapter->dev, "i2c_smbus_xfer_emulated called with "
"invalid block write size (%d)\n",
data->block[0]);
@@ -1120,9 +1071,30 @@ static s32 i2c_smbus_xfer_emulated(struct i2c_adapter * adapter, u16 addr,
return -1;
}
+ i = ((flags & I2C_CLIENT_PEC) && size != I2C_SMBUS_QUICK
+ && size != I2C_SMBUS_I2C_BLOCK_DATA);
+ if (i) {
+ /* Compute PEC if first message is a write */
+ if (!(msg[0].flags & I2C_M_RD)) {
+ if (num == 1) /* Write only */
+ i2c_smbus_add_pec(&msg[0]);
+ else /* Write followed by read */
+ partial_pec = i2c_smbus_msg_pec(0, &msg[0]);
+ }
+ /* Ask for PEC if last message is a read */
+ if (msg[num-1].flags & I2C_M_RD)
+ msg[num-1].len++;
+ }
+
if (i2c_transfer(adapter, msg, num) < 0)
return -1;
+ /* Check PEC if last message is a read */
+ if (i && (msg[num-1].flags & I2C_M_RD)) {
+ if (i2c_smbus_check_pec(partial_pec, &msg[num-1]) < 0)
+ return -1;
+ }
+
if (read_write == I2C_SMBUS_READ)
switch(size) {
case I2C_SMBUS_BYTE:
@@ -1137,8 +1109,8 @@ static s32 i2c_smbus_xfer_emulated(struct i2c_adapter * adapter, u16 addr,
break;
case I2C_SMBUS_I2C_BLOCK_DATA:
/* fixed at 32 for now */
- data->block[0] = I2C_SMBUS_I2C_BLOCK_MAX;
- for (i = 0; i < I2C_SMBUS_I2C_BLOCK_MAX; i++)
+ data->block[0] = I2C_SMBUS_BLOCK_MAX;
+ for (i = 0; i < I2C_SMBUS_BLOCK_MAX; i++)
data->block[i+1] = msgbuf1[i];
break;
}
@@ -1151,28 +1123,8 @@ s32 i2c_smbus_xfer(struct i2c_adapter * adapter, u16 addr, unsigned short flags,
union i2c_smbus_data * data)
{
s32 res;
- int swpec = 0;
- u8 partial = 0;
flags &= I2C_M_TEN | I2C_CLIENT_PEC;
- if((flags & I2C_CLIENT_PEC) &&
- !(i2c_check_functionality(adapter, I2C_FUNC_SMBUS_HWPEC_CALC))) {
- swpec = 1;
- if(read_write == I2C_SMBUS_READ &&
- size == I2C_SMBUS_BLOCK_DATA)
- size = I2C_SMBUS_BLOCK_DATA_PEC;
- else if(size == I2C_SMBUS_PROC_CALL)
- size = I2C_SMBUS_PROC_CALL_PEC;
- else if(size == I2C_SMBUS_BLOCK_PROC_CALL) {
- i2c_smbus_add_pec(addr, command,
- I2C_SMBUS_BLOCK_DATA, data);
- partial = data->block[data->block[0] + 1];
- size = I2C_SMBUS_BLOCK_PROC_CALL_PEC;
- } else if(read_write == I2C_SMBUS_WRITE &&
- size != I2C_SMBUS_QUICK &&
- size != I2C_SMBUS_I2C_BLOCK_DATA)
- size = i2c_smbus_add_pec(addr, command, size, data);
- }
if (adapter->algo->smbus_xfer) {
down(&adapter->bus_lock);
@@ -1183,13 +1135,6 @@ s32 i2c_smbus_xfer(struct i2c_adapter * adapter, u16 addr, unsigned short flags,
res = i2c_smbus_xfer_emulated(adapter,addr,flags,read_write,
command,size,data);
- if(res >= 0 && swpec &&
- size != I2C_SMBUS_QUICK && size != I2C_SMBUS_I2C_BLOCK_DATA &&
- (read_write == I2C_SMBUS_READ || size == I2C_SMBUS_PROC_CALL_PEC ||
- size == I2C_SMBUS_BLOCK_PROC_CALL_PEC)) {
- if(i2c_smbus_check_pec(addr, command, size, partial, data))
- return -1;
- }
return res;
}
diff --git a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c
index aa7a4fadef64..8af0bd1424d2 100644
--- a/drivers/i2c/i2c-dev.c
+++ b/drivers/i2c/i2c-dev.c
@@ -26,18 +26,15 @@
/* The I2C_RDWR ioctl code is written by Kolja Waschk <waschk@telos.de> */
-/* The devfs code is contributed by Philipp Matthias Hahn
- <pmhahn@titan.lahn.de> */
-
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/slab.h>
#include <linux/smp_lock.h>
-#include <linux/devfs_fs_kernel.h>
#include <linux/init.h>
#include <linux/i2c.h>
#include <linux/i2c-dev.h>
+#include <linux/platform_device.h>
#include <asm/uaccess.h>
static struct i2c_client i2cdev_client_template;
@@ -80,10 +77,9 @@ static struct i2c_dev *get_free_i2c_dev(struct i2c_adapter *adap)
{
struct i2c_dev *i2c_dev;
- i2c_dev = kmalloc(sizeof(*i2c_dev), GFP_KERNEL);
+ i2c_dev = kzalloc(sizeof(*i2c_dev), GFP_KERNEL);
if (!i2c_dev)
return ERR_PTR(-ENOMEM);
- memset(i2c_dev, 0x00, sizeof(*i2c_dev));
spin_lock(&i2c_dev_array_lock);
if (i2c_dev_array[adap->nr]) {
@@ -177,8 +173,8 @@ static int i2cdev_ioctl(struct inode *inode, struct file *file,
int i,datasize,res;
unsigned long funcs;
- dev_dbg(&client->adapter->dev, "i2c-%d ioctl, cmd: 0x%x, arg: %lx.\n",
- iminor(inode),cmd, arg);
+ dev_dbg(&client->adapter->dev, "ioctl, cmd=0x%02x, arg=0x%02lx\n",
+ cmd, arg);
switch ( cmd ) {
case I2C_SLAVE:
@@ -432,8 +428,6 @@ static int i2cdev_attach_adapter(struct i2c_adapter *adap)
if (IS_ERR(i2c_dev))
return PTR_ERR(i2c_dev);
- devfs_mk_cdev(MKDEV(I2C_MAJOR, i2c_dev->minor),
- S_IFCHR|S_IRUSR|S_IWUSR, "i2c/%d", i2c_dev->minor);
pr_debug("i2c-dev: adapter [%s] registered as minor %d\n",
adap->name, i2c_dev->minor);
@@ -466,7 +460,6 @@ static int i2cdev_detach_adapter(struct i2c_adapter *adap)
return -ENODEV;
init_completion(&i2c_dev->released);
- devfs_remove("i2c/%d", i2c_dev->minor);
return_i2c_dev(i2c_dev);
class_device_unregister(&i2c_dev->class_dev);
wait_for_completion(&i2c_dev->released);
@@ -522,8 +515,6 @@ static int __init i2c_dev_init(void)
if (res)
goto out_unreg_class;
- devfs_mk_dir("i2c");
-
return 0;
out_unreg_class:
@@ -539,7 +530,6 @@ static void __exit i2c_dev_exit(void)
{
i2c_del_driver(&i2cdev_driver);
class_unregister(&i2c_dev_class);
- devfs_remove("i2c");
unregister_chrdev(I2C_MAJOR,"i2c");
}
diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig
index 1cadd2c3cadd..42e5b8175cbf 100644
--- a/drivers/ide/Kconfig
+++ b/drivers/ide/Kconfig
@@ -539,6 +539,15 @@ config BLK_DEV_CS5530
It is safe to say Y to this question.
+config BLK_DEV_CS5535
+ tristate "AMD CS5535 chipset support"
+ depends on X86 && !X86_64
+ help
+ Include support for UDMA on the NSC/AMD CS5535 companion chipset.
+ This will automatically be detected and configured if found.
+
+ It is safe to say Y to this question.
+
config BLK_DEV_HPT34X
tristate "HPT34X chipset support"
help
@@ -778,6 +787,35 @@ config BLK_DEV_IDE_PMAC_BLINK
This option enables the use of the sleep LED as a hard drive
activity LED.
+config BLK_DEV_IDE_AU1XXX
+ bool "IDE for AMD Alchemy Au1200"
+ depends on SOC_AU1200
+choice
+ prompt "IDE Mode for AMD Alchemy Au1200"
+ default CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA
+ depends on SOC_AU1200 && BLK_DEV_IDE_AU1XXX
+
+config BLK_DEV_IDE_AU1XXX_PIO_DBDMA
+ bool "PIO+DbDMA IDE for AMD Alchemy Au1200"
+
+config BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
+ bool "MDMA2+DbDMA IDE for AMD Alchemy Au1200"
+ depends on SOC_AU1200 && BLK_DEV_IDE_AU1XXX
+endchoice
+
+config BLK_DEV_IDE_AU1XXX_BURSTABLE_ON
+ bool "Enable burstable Mode on DbDMA"
+ default false
+ depends BLK_DEV_IDE_AU1XXX
+ help
+ This option enable the burstable Flag on DbDMA controller
+ (cf. "AMD Alchemy 'Au1200' Processor Data Book - PRELIMINARY").
+
+config BLK_DEV_IDE_AU1XXX_SEQTS_PER_RQ
+ int "Maximum transfer size (KB) per request (up to 128)"
+ default "128"
+ depends BLK_DEV_IDE_AU1XXX
+
config IDE_ARM
def_bool ARM && (ARCH_A5K || ARCH_CLPS7500 || ARCH_RPC || ARCH_SHARK)
@@ -1013,7 +1051,7 @@ config BLK_DEV_UMC8672
endif
config BLK_DEV_IDEDMA
- def_bool BLK_DEV_IDEDMA_PCI || BLK_DEV_IDEDMA_PMAC || BLK_DEV_IDEDMA_ICS
+ def_bool BLK_DEV_IDEDMA_PCI || BLK_DEV_IDEDMA_PMAC || BLK_DEV_IDEDMA_ICS || BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
config IDEDMA_IVB
bool "IGNORE word93 Validation BITS"
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c
index 74af7e074868..c2f47923d174 100644
--- a/drivers/ide/ide-cd.c
+++ b/drivers/ide/ide-cd.c
@@ -2211,13 +2211,12 @@ static int cdrom_read_toc(ide_drive_t *drive, struct request_sense *sense)
if (toc == NULL) {
/* Try to allocate space. */
- toc = (struct atapi_toc *) kmalloc (sizeof (struct atapi_toc),
- GFP_KERNEL);
- info->toc = toc;
+ toc = kmalloc(sizeof(struct atapi_toc), GFP_KERNEL);
if (toc == NULL) {
printk (KERN_ERR "%s: No cdrom TOC buffer!\n", drive->name);
return -ENOMEM;
}
+ info->toc = toc;
}
/* Check to see if the existing data is still valid.
@@ -2240,7 +2239,8 @@ static int cdrom_read_toc(ide_drive_t *drive, struct request_sense *sense)
/* First read just the header, so we know how long the TOC is. */
stat = cdrom_read_tocentry(drive, 0, 1, 0, (char *) &toc->hdr,
sizeof(struct atapi_toc_header), sense);
- if (stat) return stat;
+ if (stat)
+ return stat;
#if ! STANDARD_ATAPI
if (CDROM_CONFIG_FLAGS(drive)->toctracks_as_bcd) {
@@ -2324,7 +2324,8 @@ static int cdrom_read_toc(ide_drive_t *drive, struct request_sense *sense)
/* Read the multisession information. */
stat = cdrom_read_tocentry(drive, 0, 0, 1, (char *)&ms_tmp,
sizeof(ms_tmp), sense);
- if (stat) return stat;
+ if (stat)
+ return stat;
toc->last_session_lba = be32_to_cpu(ms_tmp.ent.addr.lba);
} else {
@@ -2460,7 +2461,7 @@ static int ide_cdrom_packet(struct cdrom_device_info *cdi,
struct packet_command *cgc)
{
struct request req;
- ide_drive_t *drive = (ide_drive_t*) cdi->handle;
+ ide_drive_t *drive = cdi->handle;
if (cgc->timeout <= 0)
cgc->timeout = ATAPI_WAIT_PC;
@@ -2537,7 +2538,7 @@ int ide_cdrom_audio_ioctl (struct cdrom_device_info *cdi,
unsigned int cmd, void *arg)
{
- ide_drive_t *drive = (ide_drive_t*) cdi->handle;
+ ide_drive_t *drive = cdi->handle;
struct cdrom_info *info = drive->driver_data;
int stat;
@@ -2548,7 +2549,7 @@ int ide_cdrom_audio_ioctl (struct cdrom_device_info *cdi,
*/
case CDROMPLAYTRKIND: {
unsigned long lba_start, lba_end;
- struct cdrom_ti *ti = (struct cdrom_ti *)arg;
+ struct cdrom_ti *ti = arg;
struct atapi_toc_entry *first_toc, *last_toc;
stat = cdrom_get_toc_entry(drive, ti->cdti_trk0, &first_toc);
@@ -2571,12 +2572,13 @@ int ide_cdrom_audio_ioctl (struct cdrom_device_info *cdi,
}
case CDROMREADTOCHDR: {
- struct cdrom_tochdr *tochdr = (struct cdrom_tochdr *) arg;
+ struct cdrom_tochdr *tochdr = arg;
struct atapi_toc *toc;
/* Make sure our saved TOC is valid. */
stat = cdrom_read_toc(drive, NULL);
- if (stat) return stat;
+ if (stat)
+ return stat;
toc = info->toc;
tochdr->cdth_trk0 = toc->hdr.first_track;
@@ -2586,11 +2588,12 @@ int ide_cdrom_audio_ioctl (struct cdrom_device_info *cdi,
}
case CDROMREADTOCENTRY: {
- struct cdrom_tocentry *tocentry = (struct cdrom_tocentry*) arg;
+ struct cdrom_tocentry *tocentry = arg;
struct atapi_toc_entry *toce;
stat = cdrom_get_toc_entry(drive, tocentry->cdte_track, &toce);
- if (stat) return stat;
+ if (stat)
+ return stat;
tocentry->cdte_ctrl = toce->control;
tocentry->cdte_adr = toce->adr;
@@ -2613,7 +2616,7 @@ int ide_cdrom_audio_ioctl (struct cdrom_device_info *cdi,
static
int ide_cdrom_reset (struct cdrom_device_info *cdi)
{
- ide_drive_t *drive = (ide_drive_t*) cdi->handle;
+ ide_drive_t *drive = cdi->handle;
struct request_sense sense;
struct request req;
int ret;
@@ -2636,12 +2639,13 @@ int ide_cdrom_reset (struct cdrom_device_info *cdi)
static
int ide_cdrom_tray_move (struct cdrom_device_info *cdi, int position)
{
- ide_drive_t *drive = (ide_drive_t*) cdi->handle;
+ ide_drive_t *drive = cdi->handle;
struct request_sense sense;
if (position) {
int stat = cdrom_lockdoor(drive, 0, &sense);
- if (stat) return stat;
+ if (stat)
+ return stat;
}
return cdrom_eject(drive, !position, &sense);
@@ -2650,7 +2654,7 @@ int ide_cdrom_tray_move (struct cdrom_device_info *cdi, int position)
static
int ide_cdrom_lock_door (struct cdrom_device_info *cdi, int lock)
{
- ide_drive_t *drive = (ide_drive_t*) cdi->handle;
+ ide_drive_t *drive = cdi->handle;
return cdrom_lockdoor(drive, lock, NULL);
}
@@ -2700,7 +2704,7 @@ void ide_cdrom_update_speed (ide_drive_t *drive, struct atapi_capabilities_page
static
int ide_cdrom_select_speed (struct cdrom_device_info *cdi, int speed)
{
- ide_drive_t *drive = (ide_drive_t*) cdi->handle;
+ ide_drive_t *drive = cdi->handle;
struct request_sense sense;
struct atapi_capabilities_page cap;
int stat;
@@ -2723,7 +2727,7 @@ int ide_cdrom_select_speed (struct cdrom_device_info *cdi, int speed)
static
int ide_cdrom_drive_status (struct cdrom_device_info *cdi, int slot_nr)
{
- ide_drive_t *drive = (ide_drive_t*) cdi->handle;
+ ide_drive_t *drive = cdi->handle;
struct media_event_desc med;
struct request_sense sense;
int stat;
@@ -2769,7 +2773,7 @@ int ide_cdrom_get_last_session (struct cdrom_device_info *cdi,
struct cdrom_multisession *ms_info)
{
struct atapi_toc *toc;
- ide_drive_t *drive = (ide_drive_t*) cdi->handle;
+ ide_drive_t *drive = cdi->handle;
struct cdrom_info *info = drive->driver_data;
struct request_sense sense;
int ret;
@@ -2791,7 +2795,7 @@ int ide_cdrom_get_mcn (struct cdrom_device_info *cdi,
{
int stat;
char mcnbuf[24];
- ide_drive_t *drive = (ide_drive_t*) cdi->handle;
+ ide_drive_t *drive = cdi->handle;
/* get MCN */
if ((stat = cdrom_read_subchannel(drive, 2, mcnbuf, sizeof (mcnbuf), NULL)))
@@ -2815,7 +2819,7 @@ static
int ide_cdrom_check_media_change_real (struct cdrom_device_info *cdi,
int slot_nr)
{
- ide_drive_t *drive = (ide_drive_t*) cdi->handle;
+ ide_drive_t *drive = cdi->handle;
int retval;
if (slot_nr == CDSL_CURRENT) {
@@ -2886,7 +2890,7 @@ static int ide_cdrom_register (ide_drive_t *drive, int nslots)
devinfo->mask = 0;
devinfo->speed = CDROM_STATE_FLAGS(drive)->current_speed;
devinfo->capacity = nslots;
- devinfo->handle = (void *) drive;
+ devinfo->handle = drive;
strcpy(devinfo->name, drive->name);
/* set capability mask to match the probe. */
@@ -2942,7 +2946,7 @@ int ide_cdrom_probe_capabilities (ide_drive_t *drive)
* registered with the Uniform layer yet, it can't do this.
* Same goes for cdi->ops.
*/
- cdi->handle = (ide_drive_t *) drive;
+ cdi->handle = drive;
cdi->ops = &ide_cdrom_dops;
if (ide_cdrom_get_capabilities(drive, &cap))
@@ -3254,6 +3258,7 @@ int ide_cdrom_setup (ide_drive_t *drive)
return 0;
}
+#ifdef CONFIG_PROC_FS
static
sector_t ide_cdrom_capacity (ide_drive_t *drive)
{
@@ -3264,6 +3269,7 @@ sector_t ide_cdrom_capacity (ide_drive_t *drive)
return capacity * sectors_per_frame;
}
+#endif
static int ide_cd_remove(struct device *dev)
{
@@ -3286,12 +3292,9 @@ static void ide_cd_release(struct kref *kref)
ide_drive_t *drive = info->drive;
struct gendisk *g = info->disk;
- if (info->buffer != NULL)
- kfree(info->buffer);
- if (info->toc != NULL)
- kfree(info->toc);
- if (info->changer_info != NULL)
- kfree(info->changer_info);
+ kfree(info->buffer);
+ kfree(info->toc);
+ kfree(info->changer_info);
if (devinfo->handle == drive && unregister_cdrom(devinfo))
printk(KERN_ERR "%s: %s failed to unregister device from the cdrom "
"driver.\n", __FUNCTION__, drive->name);
@@ -3309,7 +3312,7 @@ static int ide_cd_probe(struct device *);
static int proc_idecd_read_capacity
(char *page, char **start, off_t off, int count, int *eof, void *data)
{
- ide_drive_t*drive = (ide_drive_t *)data;
+ ide_drive_t *drive = data;
int len;
len = sprintf(page,"%llu\n", (long long)ide_cdrom_capacity(drive));
@@ -3449,7 +3452,7 @@ static int ide_cd_probe(struct device *dev)
printk(KERN_INFO "ide-cd: passing drive %s to ide-scsi emulation.\n", drive->name);
goto failed;
}
- info = (struct cdrom_info *) kmalloc (sizeof (struct cdrom_info), GFP_KERNEL);
+ info = kzalloc(sizeof(struct cdrom_info), GFP_KERNEL);
if (info == NULL) {
printk(KERN_ERR "%s: Can't allocate a cdrom structure\n", drive->name);
goto failed;
@@ -3463,8 +3466,6 @@ static int ide_cd_probe(struct device *dev)
ide_register_subdriver(drive, &ide_cdrom_driver);
- memset(info, 0, sizeof (struct cdrom_info));
-
kref_init(&info->kref);
info->drive = drive;
@@ -3483,12 +3484,9 @@ static int ide_cd_probe(struct device *dev)
if (ide_cdrom_setup(drive)) {
struct cdrom_device_info *devinfo = &info->devinfo;
ide_unregister_subdriver(drive, &ide_cdrom_driver);
- if (info->buffer != NULL)
- kfree(info->buffer);
- if (info->toc != NULL)
- kfree(info->toc);
- if (info->changer_info != NULL)
- kfree(info->changer_info);
+ kfree(info->buffer);
+ kfree(info->toc);
+ kfree(info->changer_info);
if (devinfo->handle == drive && unregister_cdrom(devinfo))
printk (KERN_ERR "%s: ide_cdrom_cleanup failed to unregister device from the cdrom driver.\n", drive->name);
kfree(info);
diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c
index 234f5de3e929..e827b39e4b3c 100644
--- a/drivers/ide/ide-disk.c
+++ b/drivers/ide/ide-disk.c
@@ -1215,7 +1215,7 @@ static int ide_disk_probe(struct device *dev)
if (drive->media != ide_disk)
goto failed;
- idkp = kmalloc(sizeof(*idkp), GFP_KERNEL);
+ idkp = kzalloc(sizeof(*idkp), GFP_KERNEL);
if (!idkp)
goto failed;
@@ -1228,8 +1228,6 @@ static int ide_disk_probe(struct device *dev)
ide_register_subdriver(drive, &idedisk_driver);
- memset(idkp, 0, sizeof(*idkp));
-
kref_init(&idkp->kref);
idkp->drive = drive;
diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c
index 29c22fc278c6..f615ab759962 100644
--- a/drivers/ide/ide-floppy.c
+++ b/drivers/ide/ide-floppy.c
@@ -2038,11 +2038,9 @@ static int idefloppy_ioctl(struct inode *inode, struct file *file,
struct ide_floppy_obj *floppy = ide_floppy_g(bdev->bd_disk);
ide_drive_t *drive = floppy->drive;
void __user *argp = (void __user *)arg;
- int err = generic_ide_ioctl(drive, file, bdev, cmd, arg);
+ int err;
int prevent = (arg) ? 1 : 0;
idefloppy_pc_t pc;
- if (err != -EINVAL)
- return err;
switch (cmd) {
case CDROMEJECT:
@@ -2094,7 +2092,7 @@ static int idefloppy_ioctl(struct inode *inode, struct file *file,
case IDEFLOPPY_IOCTL_FORMAT_GET_PROGRESS:
return idefloppy_get_format_progress(drive, argp);
}
- return -EINVAL;
+ return generic_ide_ioctl(drive, file, bdev, cmd, arg);
}
static int idefloppy_media_changed(struct gendisk *disk)
@@ -2146,7 +2144,7 @@ static int ide_floppy_probe(struct device *dev)
printk("ide-floppy: passing drive %s to ide-scsi emulation.\n", drive->name);
goto failed;
}
- if ((floppy = (idefloppy_floppy_t *) kmalloc (sizeof (idefloppy_floppy_t), GFP_KERNEL)) == NULL) {
+ if ((floppy = (idefloppy_floppy_t *) kzalloc (sizeof (idefloppy_floppy_t), GFP_KERNEL)) == NULL) {
printk (KERN_ERR "ide-floppy: %s: Can't allocate a floppy structure\n", drive->name);
goto failed;
}
@@ -2159,8 +2157,6 @@ static int ide_floppy_probe(struct device *dev)
ide_register_subdriver(drive, &idefloppy_driver);
- memset(floppy, 0, sizeof(*floppy));
-
kref_init(&floppy->kref);
floppy->drive = drive;
diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c
index 0b0aa4f51628..af7af958ab3e 100644
--- a/drivers/ide/ide-iops.c
+++ b/drivers/ide/ide-iops.c
@@ -104,8 +104,6 @@ void default_hwif_iops (ide_hwif_t *hwif)
hwif->INSL = ide_insl;
}
-EXPORT_SYMBOL(default_hwif_iops);
-
/*
* MMIO operations, typically used for SATA controllers
*/
@@ -329,8 +327,6 @@ void default_hwif_transport(ide_hwif_t *hwif)
hwif->atapi_output_bytes = atapi_output_bytes;
}
-EXPORT_SYMBOL(default_hwif_transport);
-
/*
* Beginning of Taskfile OPCODE Library and feature sets.
*/
@@ -529,8 +525,6 @@ int wait_for_ready (ide_drive_t *drive, int timeout)
return 0;
}
-EXPORT_SYMBOL(wait_for_ready);
-
/*
* This routine busy-waits for the drive status to be not "busy".
* It then checks the status for all of the "good" bits and none
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c
index c1128ae5cd2f..02167a5b751d 100644
--- a/drivers/ide/ide-probe.c
+++ b/drivers/ide/ide-probe.c
@@ -596,14 +596,13 @@ static inline u8 probe_for_drive (ide_drive_t *drive)
* Also note that 0 everywhere means "can't do X"
*/
- drive->id = kmalloc(SECTOR_WORDS *4, GFP_KERNEL);
+ drive->id = kzalloc(SECTOR_WORDS *4, GFP_KERNEL);
drive->id_read = 0;
if(drive->id == NULL)
{
printk(KERN_ERR "ide: out of memory for id data.\n");
return 0;
}
- memset(drive->id, 0, SECTOR_WORDS * 4);
strcpy(drive->id->model, "UNKNOWN");
/* skip probing? */
@@ -1316,10 +1315,8 @@ static void drive_release_dev (struct device *dev)
drive->devfs_name[0] = '\0';
}
ide_remove_drive_from_hwgroup(drive);
- if (drive->id != NULL) {
- kfree(drive->id);
- drive->id = NULL;
- }
+ kfree(drive->id);
+ drive->id = NULL;
drive->present = 0;
/* Messed up locking ... */
spin_unlock_irq(&ide_lock);
diff --git a/drivers/ide/ide-proc.c b/drivers/ide/ide-proc.c
index 4063d2c34e3d..84665e2ba3c8 100644
--- a/drivers/ide/ide-proc.c
+++ b/drivers/ide/ide-proc.c
@@ -64,6 +64,7 @@ static int proc_ide_read_imodel
case ide_cy82c693: name = "cy82c693"; break;
case ide_4drives: name = "4drives"; break;
case ide_pmac: name = "mac-io"; break;
+ case ide_au1xxx: name = "au1xxx"; break;
default: name = "(unknown)"; break;
}
len = sprintf(page, "%s\n", name);
diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c
index ee38e6b143a4..0ac7eb8f40d5 100644
--- a/drivers/ide/ide-tape.c
+++ b/drivers/ide/ide-tape.c
@@ -1013,6 +1013,8 @@ typedef struct ide_tape_obj {
static DECLARE_MUTEX(idetape_ref_sem);
+static struct class *idetape_sysfs_class;
+
#define to_ide_tape(obj) container_of(obj, struct ide_tape_obj, kref)
#define ide_tape_g(disk) \
@@ -4704,6 +4706,10 @@ static void ide_tape_release(struct kref *kref)
drive->dsc_overlap = 0;
drive->driver_data = NULL;
+ class_device_destroy(idetape_sysfs_class,
+ MKDEV(IDETAPE_MAJOR, tape->minor));
+ class_device_destroy(idetape_sysfs_class,
+ MKDEV(IDETAPE_MAJOR, tape->minor + 128));
devfs_remove("%s/mt", drive->devfs_name);
devfs_remove("%s/mtn", drive->devfs_name);
devfs_unregister_tape(g->number);
@@ -4844,7 +4850,7 @@ static int ide_tape_probe(struct device *dev)
printk(KERN_WARNING "ide-tape: Use drive %s with ide-scsi emulation and osst.\n", drive->name);
printk(KERN_WARNING "ide-tape: OnStream support will be removed soon from ide-tape!\n");
}
- tape = (idetape_tape_t *) kmalloc (sizeof (idetape_tape_t), GFP_KERNEL);
+ tape = (idetape_tape_t *) kzalloc (sizeof (idetape_tape_t), GFP_KERNEL);
if (tape == NULL) {
printk(KERN_ERR "ide-tape: %s: Can't allocate a tape structure\n", drive->name);
goto failed;
@@ -4858,8 +4864,6 @@ static int ide_tape_probe(struct device *dev)
ide_register_subdriver(drive, &idetape_driver);
- memset(tape, 0, sizeof(*tape));
-
kref_init(&tape->kref);
tape->drive = drive;
@@ -4878,6 +4882,11 @@ static int ide_tape_probe(struct device *dev)
idetape_setup(drive, tape, minor);
+ class_device_create(idetape_sysfs_class, NULL,
+ MKDEV(IDETAPE_MAJOR, minor), dev, "%s", tape->name);
+ class_device_create(idetape_sysfs_class, NULL,
+ MKDEV(IDETAPE_MAJOR, minor + 128), dev, "n%s", tape->name);
+
devfs_mk_cdev(MKDEV(HWIF(drive)->major, minor),
S_IFCHR | S_IRUGO | S_IWUGO,
"%s/mt", drive->devfs_name);
@@ -4903,6 +4912,7 @@ MODULE_LICENSE("GPL");
static void __exit idetape_exit (void)
{
driver_unregister(&idetape_driver.gen_driver);
+ class_destroy(idetape_sysfs_class);
unregister_chrdev(IDETAPE_MAJOR, "ht");
}
@@ -4911,11 +4921,33 @@ static void __exit idetape_exit (void)
*/
static int idetape_init (void)
{
+ int error = 1;
+ idetape_sysfs_class = class_create(THIS_MODULE, "ide_tape");
+ if (IS_ERR(idetape_sysfs_class)) {
+ idetape_sysfs_class = NULL;
+ printk(KERN_ERR "Unable to create sysfs class for ide tapes\n");
+ error = -EBUSY;
+ goto out;
+ }
+
if (register_chrdev(IDETAPE_MAJOR, "ht", &idetape_fops)) {
printk(KERN_ERR "ide-tape: Failed to register character device interface\n");
- return -EBUSY;
+ error = -EBUSY;
+ goto out_free_class;
}
- return driver_register(&idetape_driver.gen_driver);
+
+ error = driver_register(&idetape_driver.gen_driver);
+ if (error)
+ goto out_free_driver;
+
+ return 0;
+
+out_free_driver:
+ driver_unregister(&idetape_driver.gen_driver);
+out_free_class:
+ class_destroy(idetape_sysfs_class);
+out:
+ return error;
}
module_init(idetape_init);
diff --git a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c
index ace8edad6e96..54f9639c2a8c 100644
--- a/drivers/ide/ide-taskfile.c
+++ b/drivers/ide/ide-taskfile.c
@@ -161,8 +161,6 @@ ide_startstop_t do_rw_taskfile (ide_drive_t *drive, ide_task_t *task)
return ide_stopped;
}
-EXPORT_SYMBOL(do_rw_taskfile);
-
/*
* set_multmode_intr() is invoked on completion of a WIN_SETMULT cmd.
*/
@@ -528,9 +526,8 @@ int ide_taskfile_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
// printk("IDE Taskfile ...\n");
- req_task = kmalloc(tasksize, GFP_KERNEL);
+ req_task = kzalloc(tasksize, GFP_KERNEL);
if (req_task == NULL) return -ENOMEM;
- memset(req_task, 0, tasksize);
if (copy_from_user(req_task, buf, tasksize)) {
kfree(req_task);
return -EFAULT;
@@ -541,12 +538,11 @@ int ide_taskfile_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
if (taskout) {
int outtotal = tasksize;
- outbuf = kmalloc(taskout, GFP_KERNEL);
+ outbuf = kzalloc(taskout, GFP_KERNEL);
if (outbuf == NULL) {
err = -ENOMEM;
goto abort;
}
- memset(outbuf, 0, taskout);
if (copy_from_user(outbuf, buf + outtotal, taskout)) {
err = -EFAULT;
goto abort;
@@ -555,12 +551,11 @@ int ide_taskfile_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
if (taskin) {
int intotal = tasksize + taskout;
- inbuf = kmalloc(taskin, GFP_KERNEL);
+ inbuf = kzalloc(taskin, GFP_KERNEL);
if (inbuf == NULL) {
err = -ENOMEM;
goto abort;
}
- memset(inbuf, 0, taskin);
if (copy_from_user(inbuf, buf + intotal, taskin)) {
err = -EFAULT;
goto abort;
@@ -649,10 +644,8 @@ int ide_taskfile_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
}
abort:
kfree(req_task);
- if (outbuf != NULL)
- kfree(outbuf);
- if (inbuf != NULL)
- kfree(inbuf);
+ kfree(outbuf);
+ kfree(inbuf);
// printk("IDE Taskfile ioctl ended. rc = %i\n", err);
@@ -709,10 +702,9 @@ int ide_cmd_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
if (args[3]) {
argsize = 4 + (SECTOR_WORDS * 4 * args[3]);
- argbuf = kmalloc(argsize, GFP_KERNEL);
+ argbuf = kzalloc(argsize, GFP_KERNEL);
if (argbuf == NULL)
return -ENOMEM;
- memcpy(argbuf, args, 4);
}
if (set_transfer(drive, &tfargs)) {
xfer_rate = args[1];
diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c
index 73ca8f73917d..8af179b531c3 100644
--- a/drivers/ide/ide.c
+++ b/drivers/ide/ide.c
@@ -803,6 +803,7 @@ found:
hwif->irq = hw->irq;
hwif->noprobe = 0;
hwif->chipset = hw->chipset;
+ hwif->gendev.parent = hw->dev;
if (!initializing) {
probe_hwif_init_with_fixup(hwif, fixup);
@@ -864,9 +865,8 @@ static int __ide_add_setting(ide_drive_t *drive, const char *name, int rw, int r
down(&ide_setting_sem);
while ((*p) && strcmp((*p)->name, name) < 0)
p = &((*p)->next);
- if ((setting = kmalloc(sizeof(*setting), GFP_KERNEL)) == NULL)
+ if ((setting = kzalloc(sizeof(*setting), GFP_KERNEL)) == NULL)
goto abort;
- memset(setting, 0, sizeof(*setting));
if ((setting->name = kmalloc(strlen(name) + 1, GFP_KERNEL)) == NULL)
goto abort;
strcpy(setting->name, name);
@@ -889,8 +889,7 @@ static int __ide_add_setting(ide_drive_t *drive, const char *name, int rw, int r
return 0;
abort:
up(&ide_setting_sem);
- if (setting)
- kfree(setting);
+ kfree(setting);
return -1;
}
diff --git a/drivers/ide/legacy/ide-cs.c b/drivers/ide/legacy/ide-cs.c
index a35a58bef1a4..ef79805218e4 100644
--- a/drivers/ide/legacy/ide-cs.c
+++ b/drivers/ide/legacy/ide-cs.c
@@ -116,9 +116,8 @@ static dev_link_t *ide_attach(void)
DEBUG(0, "ide_attach()\n");
/* Create new ide device */
- info = kmalloc(sizeof(*info), GFP_KERNEL);
+ info = kzalloc(sizeof(*info), GFP_KERNEL);
if (!info) return NULL;
- memset(info, 0, sizeof(*info));
link = &info->link; link->priv = info;
link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
@@ -183,13 +182,14 @@ static void ide_detach(dev_link_t *link)
} /* ide_detach */
-static int idecs_register(unsigned long io, unsigned long ctl, unsigned long irq)
+static int idecs_register(unsigned long io, unsigned long ctl, unsigned long irq, struct pcmcia_device *handle)
{
hw_regs_t hw;
memset(&hw, 0, sizeof(hw));
ide_init_hwif_ports(&hw, io, ctl, NULL);
hw.irq = irq;
hw.chipset = ide_pci;
+ hw.dev = &handle->dev;
return ide_register_hw_with_fixup(&hw, NULL, ide_undecoded_slave);
}
@@ -221,9 +221,8 @@ static void ide_config(dev_link_t *link)
DEBUG(0, "ide_config(0x%p)\n", link);
- stk = kmalloc(sizeof(*stk), GFP_KERNEL);
+ stk = kzalloc(sizeof(*stk), GFP_KERNEL);
if (!stk) goto err_mem;
- memset(stk, 0, sizeof(*stk));
cfg = &stk->parse.cftable_entry;
tuple.TupleData = (cisdata_t *)&stk->buf;
@@ -329,12 +328,12 @@ static void ide_config(dev_link_t *link)
/* retry registration in case device is still spinning up */
for (hd = -1, i = 0; i < 10; i++) {
- hd = idecs_register(io_base, ctl_base, link->irq.AssignedIRQ);
+ hd = idecs_register(io_base, ctl_base, link->irq.AssignedIRQ, handle);
if (hd >= 0) break;
if (link->io.NumPorts1 == 0x20) {
outb(0x02, ctl_base + 0x10);
hd = idecs_register(io_base + 0x10, ctl_base + 0x10,
- link->irq.AssignedIRQ);
+ link->irq.AssignedIRQ, handle);
if (hd >= 0) {
io_base += 0x10;
ctl_base += 0x10;
diff --git a/drivers/ide/mips/au1xxx-ide.c b/drivers/ide/mips/au1xxx-ide.c
new file mode 100644
index 000000000000..2b6327c576b9
--- /dev/null
+++ b/drivers/ide/mips/au1xxx-ide.c
@@ -0,0 +1,1250 @@
+/*
+ * linux/drivers/ide/mips/au1xxx-ide.c version 01.30.00 Aug. 02 2005
+ *
+ * BRIEF MODULE DESCRIPTION
+ * AMD Alchemy Au1xxx IDE interface routines over the Static Bus
+ *
+ * Copyright (c) 2003-2005 AMD, Personal Connectivity Solutions
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation; either version 2 of the License, or (at your option) any later
+ * version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Note: for more information, please refer "AMD Alchemy Au1200/Au1550 IDE
+ * Interface and Linux Device Driver" Application Note.
+ */
+#undef REALLY_SLOW_IO /* most systems can safely undef this */
+
+#include <linux/config.h> /* for CONFIG_BLK_DEV_IDEPCI */
+#include <linux/types.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/timer.h>
+#include <linux/mm.h>
+#include <linux/ioport.h>
+#include <linux/hdreg.h>
+#include <linux/init.h>
+#include <linux/ide.h>
+#include <linux/sysdev.h>
+
+#include <linux/dma-mapping.h>
+
+#include <asm/io.h>
+#include <asm/mach-au1x00/au1xxx.h>
+#include <asm/mach-au1x00/au1xxx_dbdma.h>
+
+#if CONFIG_PM
+#include <asm/mach-au1x00/au1xxx_pm.h>
+#endif
+
+#include <asm/mach-au1x00/au1xxx_ide.h>
+
+#define DRV_NAME "au1200-ide"
+#define DRV_VERSION "1.0"
+#define DRV_AUTHOR "AMD PCS / Pete Popov <ppopov@embeddedalley.com>"
+#define DRV_DESC "Au1200 IDE"
+
+static _auide_hwif auide_hwif;
+static spinlock_t ide_tune_drive_spin_lock = SPIN_LOCK_UNLOCKED;
+static spinlock_t ide_tune_chipset_spin_lock = SPIN_LOCK_UNLOCKED;
+static int dbdma_init_done = 0;
+
+/*
+ * local I/O functions
+ */
+u8 auide_inb(unsigned long port)
+{
+ return (au_readb(port));
+}
+
+u16 auide_inw(unsigned long port)
+{
+ return (au_readw(port));
+}
+
+u32 auide_inl(unsigned long port)
+{
+ return (au_readl(port));
+}
+
+void auide_insw(unsigned long port, void *addr, u32 count)
+{
+#if defined(CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA)
+
+ _auide_hwif *ahwif = &auide_hwif;
+ chan_tab_t *ctp;
+ au1x_ddma_desc_t *dp;
+
+ if(!put_dest_flags(ahwif->rx_chan, (void*)addr, count << 1,
+ DDMA_FLAGS_NOIE)) {
+ printk(KERN_ERR "%s failed %d\n", __FUNCTION__, __LINE__);
+ return;
+ }
+ ctp = *((chan_tab_t **)ahwif->rx_chan);
+ dp = ctp->cur_ptr;
+ while (dp->dscr_cmd0 & DSCR_CMD0_V)
+ ;
+ ctp->cur_ptr = au1xxx_ddma_get_nextptr_virt(dp);
+#else
+ while (count--)
+ {
+ *(u16 *)addr = au_readw(port);
+ addr +=2 ;
+ }
+#endif
+}
+
+void auide_insl(unsigned long port, void *addr, u32 count)
+{
+ while (count--)
+ {
+ *(u32 *)addr = au_readl(port);
+ /* NOTE: For IDE interfaces over PCMCIA,
+ * 32-bit access does not work
+ */
+ addr += 4;
+ }
+}
+
+void auide_outb(u8 addr, unsigned long port)
+{
+ return (au_writeb(addr, port));
+}
+
+void auide_outbsync(ide_drive_t *drive, u8 addr, unsigned long port)
+{
+ return (au_writeb(addr, port));
+}
+
+void auide_outw(u16 addr, unsigned long port)
+{
+ return (au_writew(addr, port));
+}
+
+void auide_outl(u32 addr, unsigned long port)
+{
+ return (au_writel(addr, port));
+}
+
+void auide_outsw(unsigned long port, void *addr, u32 count)
+{
+#if defined(CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA)
+ _auide_hwif *ahwif = &auide_hwif;
+ chan_tab_t *ctp;
+ au1x_ddma_desc_t *dp;
+
+ if(!put_source_flags(ahwif->tx_chan, (void*)addr,
+ count << 1, DDMA_FLAGS_NOIE)) {
+ printk(KERN_ERR "%s failed %d\n", __FUNCTION__, __LINE__);
+ return;
+ }
+ ctp = *((chan_tab_t **)ahwif->tx_chan);
+ dp = ctp->cur_ptr;
+ while (dp->dscr_cmd0 & DSCR_CMD0_V)
+ ;
+ ctp->cur_ptr = au1xxx_ddma_get_nextptr_virt(dp);
+#else
+ while (count--)
+ {
+ au_writew(*(u16 *)addr, port);
+ addr += 2;
+ }
+#endif
+}
+
+void auide_outsl(unsigned long port, void *addr, u32 count)
+{
+ while (count--)
+ {
+ au_writel(*(u32 *)addr, port);
+ /* NOTE: For IDE interfaces over PCMCIA,
+ * 32-bit access does not work
+ */
+ addr += 4;
+ }
+}
+
+static void auide_tune_drive(ide_drive_t *drive, byte pio)
+{
+ int mem_sttime;
+ int mem_stcfg;
+ unsigned long flags;
+ u8 speed;
+
+ /* get the best pio mode for the drive */
+ pio = ide_get_best_pio_mode(drive, pio, 4, NULL);
+
+ printk("%s: setting Au1XXX IDE to PIO mode%d\n",
+ drive->name, pio);
+
+ spin_lock_irqsave(&ide_tune_drive_spin_lock, flags);
+
+ mem_sttime = 0;
+ mem_stcfg = au_readl(MEM_STCFG2);
+
+ /* set pio mode! */
+ switch(pio) {
+ case 0:
+ /* set timing parameters for RCS2# */
+ mem_sttime = SBC_IDE_PIO0_TWCS
+ | SBC_IDE_PIO0_TCSH
+ | SBC_IDE_PIO0_TCSOFF
+ | SBC_IDE_PIO0_TWP
+ | SBC_IDE_PIO0_TCSW
+ | SBC_IDE_PIO0_TPM
+ | SBC_IDE_PIO0_TA;
+ /* set configuration for RCS2# */
+ mem_stcfg |= TS_MASK;
+ mem_stcfg &= ~TCSOE_MASK;
+ mem_stcfg &= ~TOECS_MASK;
+ mem_stcfg |= SBC_IDE_PIO0_TCSOE | SBC_IDE_PIO0_TOECS;
+
+ au_writel(mem_sttime,MEM_STTIME2);
+ au_writel(mem_stcfg,MEM_STCFG2);
+ break;
+
+ case 1:
+ /* set timing parameters for RCS2# */
+ mem_sttime = SBC_IDE_PIO1_TWCS
+ | SBC_IDE_PIO1_TCSH
+ | SBC_IDE_PIO1_TCSOFF
+ | SBC_IDE_PIO1_TWP
+ | SBC_IDE_PIO1_TCSW
+ | SBC_IDE_PIO1_TPM
+ | SBC_IDE_PIO1_TA;
+ /* set configuration for RCS2# */
+ mem_stcfg |= TS_MASK;
+ mem_stcfg &= ~TCSOE_MASK;
+ mem_stcfg &= ~TOECS_MASK;
+ mem_stcfg |= SBC_IDE_PIO1_TCSOE | SBC_IDE_PIO1_TOECS;
+ break;
+
+ case 2:
+ /* set timing parameters for RCS2# */
+ mem_sttime = SBC_IDE_PIO2_TWCS
+ | SBC_IDE_PIO2_TCSH
+ | SBC_IDE_PIO2_TCSOFF
+ | SBC_IDE_PIO2_TWP
+ | SBC_IDE_PIO2_TCSW
+ | SBC_IDE_PIO2_TPM
+ | SBC_IDE_PIO2_TA;
+ /* set configuration for RCS2# */
+ mem_stcfg &= ~TS_MASK;
+ mem_stcfg &= ~TCSOE_MASK;
+ mem_stcfg &= ~TOECS_MASK;
+ mem_stcfg |= SBC_IDE_PIO2_TCSOE | SBC_IDE_PIO2_TOECS;
+ break;
+
+ case 3:
+ /* set timing parameters for RCS2# */
+ mem_sttime = SBC_IDE_PIO3_TWCS
+ | SBC_IDE_PIO3_TCSH
+ | SBC_IDE_PIO3_TCSOFF
+ | SBC_IDE_PIO3_TWP
+ | SBC_IDE_PIO3_TCSW
+ | SBC_IDE_PIO3_TPM
+ | SBC_IDE_PIO3_TA;
+ /* set configuration for RCS2# */
+ mem_stcfg |= TS_MASK;
+ mem_stcfg &= ~TS_MASK;
+ mem_stcfg &= ~TCSOE_MASK;
+ mem_stcfg &= ~TOECS_MASK;
+ mem_stcfg |= SBC_IDE_PIO3_TCSOE | SBC_IDE_PIO3_TOECS;
+
+ break;
+
+ case 4:
+ /* set timing parameters for RCS2# */
+ mem_sttime = SBC_IDE_PIO4_TWCS
+ | SBC_IDE_PIO4_TCSH
+ | SBC_IDE_PIO4_TCSOFF
+ | SBC_IDE_PIO4_TWP
+ | SBC_IDE_PIO4_TCSW
+ | SBC_IDE_PIO4_TPM
+ | SBC_IDE_PIO4_TA;
+ /* set configuration for RCS2# */
+ mem_stcfg &= ~TS_MASK;
+ mem_stcfg &= ~TCSOE_MASK;
+ mem_stcfg &= ~TOECS_MASK;
+ mem_stcfg |= SBC_IDE_PIO4_TCSOE | SBC_IDE_PIO4_TOECS;
+ break;
+ }
+
+ au_writel(mem_sttime,MEM_STTIME2);
+ au_writel(mem_stcfg,MEM_STCFG2);
+
+ spin_unlock_irqrestore(&ide_tune_drive_spin_lock, flags);
+
+ speed = pio + XFER_PIO_0;
+ ide_config_drive_speed(drive, speed);
+}
+
+static int auide_tune_chipset (ide_drive_t *drive, u8 speed)
+{
+ u8 mode = 0;
+ int mem_sttime;
+ int mem_stcfg;
+ unsigned long flags;
+#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
+ struct hd_driveid *id = drive->id;
+
+ /*
+ * Now see what the current drive is capable of,
+ * selecting UDMA only if the mate said it was ok.
+ */
+ if (id && (id->capability & 1) && drive->autodma &&
+ !__ide_dma_bad_drive(drive)) {
+ if (!mode && (id->field_valid & 2) && (id->dma_mword & 7)) {
+ if (id->dma_mword & 4)
+ mode = XFER_MW_DMA_2;
+ else if (id->dma_mword & 2)
+ mode = XFER_MW_DMA_1;
+ else if (id->dma_mword & 1)
+ mode = XFER_MW_DMA_0;
+ }
+ }
+#endif
+
+ spin_lock_irqsave(&ide_tune_chipset_spin_lock, flags);
+
+ mem_sttime = 0;
+ mem_stcfg = au_readl(MEM_STCFG2);
+
+ switch(speed) {
+ case XFER_PIO_4:
+ case XFER_PIO_3:
+ case XFER_PIO_2:
+ case XFER_PIO_1:
+ case XFER_PIO_0:
+ auide_tune_drive(drive, (speed - XFER_PIO_0));
+ break;
+#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
+ case XFER_MW_DMA_2:
+ /* set timing parameters for RCS2# */
+ mem_sttime = SBC_IDE_MDMA2_TWCS
+ | SBC_IDE_MDMA2_TCSH
+ | SBC_IDE_MDMA2_TCSOFF
+ | SBC_IDE_MDMA2_TWP
+ | SBC_IDE_MDMA2_TCSW
+ | SBC_IDE_MDMA2_TPM
+ | SBC_IDE_MDMA2_TA;
+ /* set configuration for RCS2# */
+ mem_stcfg &= ~TS_MASK;
+ mem_stcfg &= ~TCSOE_MASK;
+ mem_stcfg &= ~TOECS_MASK;
+ mem_stcfg |= SBC_IDE_MDMA2_TCSOE | SBC_IDE_MDMA2_TOECS;
+
+ mode = XFER_MW_DMA_2;
+ break;
+ case XFER_MW_DMA_1:
+ /* set timing parameters for RCS2# */
+ mem_sttime = SBC_IDE_MDMA1_TWCS
+ | SBC_IDE_MDMA1_TCSH
+ | SBC_IDE_MDMA1_TCSOFF
+ | SBC_IDE_MDMA1_TWP
+ | SBC_IDE_MDMA1_TCSW
+ | SBC_IDE_MDMA1_TPM
+ | SBC_IDE_MDMA1_TA;
+ /* set configuration for RCS2# */
+ mem_stcfg &= ~TS_MASK;
+ mem_stcfg &= ~TCSOE_MASK;
+ mem_stcfg &= ~TOECS_MASK;
+ mem_stcfg |= SBC_IDE_MDMA1_TCSOE | SBC_IDE_MDMA1_TOECS;
+
+ mode = XFER_MW_DMA_1;
+ break;
+ case XFER_MW_DMA_0:
+ /* set timing parameters for RCS2# */
+ mem_sttime = SBC_IDE_MDMA0_TWCS
+ | SBC_IDE_MDMA0_TCSH
+ | SBC_IDE_MDMA0_TCSOFF
+ | SBC_IDE_MDMA0_TWP
+ | SBC_IDE_MDMA0_TCSW
+ | SBC_IDE_MDMA0_TPM
+ | SBC_IDE_MDMA0_TA;
+ /* set configuration for RCS2# */
+ mem_stcfg |= TS_MASK;
+ mem_stcfg &= ~TCSOE_MASK;
+ mem_stcfg &= ~TOECS_MASK;
+ mem_stcfg |= SBC_IDE_MDMA0_TCSOE | SBC_IDE_MDMA0_TOECS;
+
+ mode = XFER_MW_DMA_0;
+ break;
+#endif
+ default:
+ return 1;
+ }
+
+ /*
+ * Tell the drive to switch to the new mode; abort on failure.
+ */
+ if (!mode || ide_config_drive_speed(drive, mode))
+ {
+ return 1; /* failure */
+ }
+
+
+ au_writel(mem_sttime,MEM_STTIME2);
+ au_writel(mem_stcfg,MEM_STCFG2);
+
+ spin_unlock_irqrestore(&ide_tune_chipset_spin_lock, flags);
+
+ return 0;
+}
+
+/*
+ * Multi-Word DMA + DbDMA functions
+ */
+#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
+
+static int in_drive_list(struct hd_driveid *id,
+ const struct drive_list_entry *drive_table)
+{
+ for ( ; drive_table->id_model ; drive_table++){
+ if ((!strcmp(drive_table->id_model, id->model)) &&
+ ((strstr(drive_table->id_firmware, id->fw_rev)) ||
+ (!strcmp(drive_table->id_firmware, "ALL")))
+ )
+ return 1;
+ }
+ return 0;
+}
+
+static int auide_build_sglist(ide_drive_t *drive, struct request *rq)
+{
+ ide_hwif_t *hwif = drive->hwif;
+ _auide_hwif *ahwif = (_auide_hwif*)hwif->hwif_data;
+ struct scatterlist *sg = hwif->sg_table;
+
+ ide_map_sg(drive, rq);
+
+ if (rq_data_dir(rq) == READ)
+ hwif->sg_dma_direction = DMA_FROM_DEVICE;
+ else
+ hwif->sg_dma_direction = DMA_TO_DEVICE;
+
+ return dma_map_sg(ahwif->dev, sg, hwif->sg_nents,
+ hwif->sg_dma_direction);
+}
+
+static int auide_build_dmatable(ide_drive_t *drive)
+{
+ int i, iswrite, count = 0;
+ ide_hwif_t *hwif = HWIF(drive);
+
+ struct request *rq = HWGROUP(drive)->rq;
+
+ _auide_hwif *ahwif = (_auide_hwif*)hwif->hwif_data;
+ struct scatterlist *sg;
+
+ iswrite = (rq_data_dir(rq) == WRITE);
+ /* Save for interrupt context */
+ ahwif->drive = drive;
+
+ /* Build sglist */
+ hwif->sg_nents = i = auide_build_sglist(drive, rq);
+
+ if (!i)
+ return 0;
+
+ /* fill the descriptors */
+ sg = hwif->sg_table;
+ while (i && sg_dma_len(sg)) {
+ u32 cur_addr;
+ u32 cur_len;
+
+ cur_addr = sg_dma_address(sg);
+ cur_len = sg_dma_len(sg);
+
+ while (cur_len) {
+ u32 flags = DDMA_FLAGS_NOIE;
+ unsigned int tc = (cur_len < 0xfe00)? cur_len: 0xfe00;
+
+ if (++count >= PRD_ENTRIES) {
+ printk(KERN_WARNING "%s: DMA table too small\n",
+ drive->name);
+ goto use_pio_instead;
+ }
+
+ /* Lets enable intr for the last descriptor only */
+ if (1==i)
+ flags = DDMA_FLAGS_IE;
+ else
+ flags = DDMA_FLAGS_NOIE;
+
+ if (iswrite) {
+ if(!put_source_flags(ahwif->tx_chan,
+ (void*)(page_address(sg->page)
+ + sg->offset),
+ tc, flags)) {
+ printk(KERN_ERR "%s failed %d\n",
+ __FUNCTION__, __LINE__);
+ }
+ } else
+ {
+ if(!put_dest_flags(ahwif->rx_chan,
+ (void*)(page_address(sg->page)
+ + sg->offset),
+ tc, flags)) {
+ printk(KERN_ERR "%s failed %d\n",
+ __FUNCTION__, __LINE__);
+ }
+ }
+
+ cur_addr += tc;
+ cur_len -= tc;
+ }
+ sg++;
+ i--;
+ }
+
+ if (count)
+ return 1;
+
+use_pio_instead:
+ dma_unmap_sg(ahwif->dev,
+ hwif->sg_table,
+ hwif->sg_nents,
+ hwif->sg_dma_direction);
+
+ return 0; /* revert to PIO for this request */
+}
+
+static int auide_dma_end(ide_drive_t *drive)
+{
+ ide_hwif_t *hwif = HWIF(drive);
+ _auide_hwif *ahwif = (_auide_hwif*)hwif->hwif_data;
+
+ if (hwif->sg_nents) {
+ dma_unmap_sg(ahwif->dev, hwif->sg_table, hwif->sg_nents,
+ hwif->sg_dma_direction);
+ hwif->sg_nents = 0;
+ }
+
+ return 0;
+}
+
+static void auide_dma_start(ide_drive_t *drive )
+{
+// printk("%s\n", __FUNCTION__);
+}
+
+ide_startstop_t auide_dma_intr(ide_drive_t *drive)
+{
+ //printk("%s\n", __FUNCTION__);
+
+ u8 stat = 0, dma_stat = 0;
+
+ dma_stat = HWIF(drive)->ide_dma_end(drive);
+ stat = HWIF(drive)->INB(IDE_STATUS_REG); /* get drive status */
+ if (OK_STAT(stat,DRIVE_READY,drive->bad_wstat|DRQ_STAT)) {
+ if (!dma_stat) {
+ struct request *rq = HWGROUP(drive)->rq;
+
+ ide_end_request(drive, 1, rq->nr_sectors);
+ return ide_stopped;
+ }
+ printk(KERN_ERR "%s: dma_intr: bad DMA status (dma_stat=%x)\n",
+ drive->name, dma_stat);
+ }
+ return ide_error(drive, "dma_intr", stat);
+}
+
+static void auide_dma_exec_cmd(ide_drive_t *drive, u8 command)
+{
+ //printk("%s\n", __FUNCTION__);
+
+ /* issue cmd to drive */
+ ide_execute_command(drive, command, &auide_dma_intr,
+ (2*WAIT_CMD), NULL);
+}
+
+static int auide_dma_setup(ide_drive_t *drive)
+{
+// printk("%s\n", __FUNCTION__);
+
+ if (drive->media != ide_disk)
+ return 1;
+
+ if (!auide_build_dmatable(drive))
+ /* try PIO instead of DMA */
+ return 1;
+
+ drive->waiting_for_dma = 1;
+
+ return 0;
+}
+
+static int auide_dma_check(ide_drive_t *drive)
+{
+// printk("%s\n", __FUNCTION__);
+
+#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
+ if( !dbdma_init_done ){
+ auide_hwif.white_list = in_drive_list(drive->id,
+ dma_white_list);
+ auide_hwif.black_list = in_drive_list(drive->id,
+ dma_black_list);
+ auide_hwif.drive = drive;
+ auide_ddma_init(&auide_hwif);
+ dbdma_init_done = 1;
+ }
+#endif
+
+ /* Is the drive in our DMA black list? */
+ if ( auide_hwif.black_list ) {
+ drive->using_dma = 0;
+ printk("%s found in dma_blacklist[]! Disabling DMA.\n",
+ drive->id->model);
+ }
+ else
+ drive->using_dma = 1;
+
+ return HWIF(drive)->ide_dma_host_on(drive);
+}
+
+static int auide_dma_test_irq(ide_drive_t *drive)
+{
+// printk("%s\n", __FUNCTION__);
+
+ if (!drive->waiting_for_dma)
+ printk(KERN_WARNING "%s: ide_dma_test_irq \
+ called while not waiting\n", drive->name);
+
+ /* If dbdma didn't execute the STOP command yet, the
+ * active bit is still set
+ */
+ drive->waiting_for_dma++;
+ if (drive->waiting_for_dma >= DMA_WAIT_TIMEOUT) {
+ printk(KERN_WARNING "%s: timeout waiting for ddma to \
+ complete\n", drive->name);
+ return 1;
+ }
+ udelay(10);
+ return 0;
+}
+
+static int auide_dma_host_on(ide_drive_t *drive)
+{
+// printk("%s\n", __FUNCTION__);
+ return 0;
+}
+
+static int auide_dma_on(ide_drive_t *drive)
+{
+// printk("%s\n", __FUNCTION__);
+ drive->using_dma = 1;
+ return auide_dma_host_on(drive);
+}
+
+
+static int auide_dma_host_off(ide_drive_t *drive)
+{
+// printk("%s\n", __FUNCTION__);
+ return 0;
+}
+
+static int auide_dma_off_quietly(ide_drive_t *drive)
+{
+// printk("%s\n", __FUNCTION__);
+ drive->using_dma = 0;
+ return auide_dma_host_off(drive);
+}
+
+static int auide_dma_lostirq(ide_drive_t *drive)
+{
+// printk("%s\n", __FUNCTION__);
+
+ printk(KERN_ERR "%s: IRQ lost\n", drive->name);
+ return 0;
+}
+
+static void auide_ddma_tx_callback(int irq, void *param, struct pt_regs *regs)
+{
+// printk("%s\n", __FUNCTION__);
+
+ _auide_hwif *ahwif = (_auide_hwif*)param;
+ ahwif->drive->waiting_for_dma = 0;
+ return;
+}
+
+static void auide_ddma_rx_callback(int irq, void *param, struct pt_regs *regs)
+{
+// printk("%s\n", __FUNCTION__);
+
+ _auide_hwif *ahwif = (_auide_hwif*)param;
+ ahwif->drive->waiting_for_dma = 0;
+ return;
+}
+
+static int auide_dma_timeout(ide_drive_t *drive)
+{
+// printk("%s\n", __FUNCTION__);
+
+ printk(KERN_ERR "%s: DMA timeout occurred: ", drive->name);
+
+ if (HWIF(drive)->ide_dma_test_irq(drive))
+ return 0;
+
+ return HWIF(drive)->ide_dma_end(drive);
+}
+#endif /* end CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA */
+
+
+static int auide_ddma_init( _auide_hwif *auide )
+{
+// printk("%s\n", __FUNCTION__);
+
+ dbdev_tab_t source_dev_tab;
+#if defined(CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA)
+ dbdev_tab_t target_dev_tab;
+ ide_hwif_t *hwif = auide->hwif;
+ char warning_output [2][80];
+ int i;
+#endif
+
+ /* Add our custom device to DDMA device table */
+ /* Create our new device entries in the table */
+#if defined(CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA)
+ source_dev_tab.dev_id = AU1XXX_ATA_DDMA_REQ;
+
+ if( auide->white_list || auide->black_list ){
+ source_dev_tab.dev_tsize = 8;
+ source_dev_tab.dev_devwidth = 32;
+ source_dev_tab.dev_physaddr = (u32)AU1XXX_ATA_PHYS_ADDR;
+ source_dev_tab.dev_intlevel = 0;
+ source_dev_tab.dev_intpolarity = 0;
+
+ /* init device table for target - static bus controller - */
+ target_dev_tab.dev_id = DSCR_CMD0_ALWAYS;
+ target_dev_tab.dev_tsize = 8;
+ target_dev_tab.dev_devwidth = 32;
+ target_dev_tab.dev_physaddr = (u32)AU1XXX_ATA_PHYS_ADDR;
+ target_dev_tab.dev_intlevel = 0;
+ target_dev_tab.dev_intpolarity = 0;
+ target_dev_tab.dev_flags = DEV_FLAGS_ANYUSE;
+ }
+ else{
+ source_dev_tab.dev_tsize = 1;
+ source_dev_tab.dev_devwidth = 16;
+ source_dev_tab.dev_physaddr = (u32)AU1XXX_ATA_PHYS_ADDR;
+ source_dev_tab.dev_intlevel = 0;
+ source_dev_tab.dev_intpolarity = 0;
+
+ /* init device table for target - static bus controller - */
+ target_dev_tab.dev_id = DSCR_CMD0_ALWAYS;
+ target_dev_tab.dev_tsize = 1;
+ target_dev_tab.dev_devwidth = 16;
+ target_dev_tab.dev_physaddr = (u32)AU1XXX_ATA_PHYS_ADDR;
+ target_dev_tab.dev_intlevel = 0;
+ target_dev_tab.dev_intpolarity = 0;
+ target_dev_tab.dev_flags = DEV_FLAGS_ANYUSE;
+
+ sprintf(&warning_output[0][0],
+ "%s is not on ide driver white list.",
+ auide_hwif.drive->id->model);
+ for ( i=strlen(&warning_output[0][0]) ; i<76; i++ ){
+ sprintf(&warning_output[0][i]," ");
+ }
+
+ sprintf(&warning_output[1][0],
+ "To add %s please read 'Documentation/mips/AU1xxx_IDE.README'.",
+ auide_hwif.drive->id->model);
+ for ( i=strlen(&warning_output[1][0]) ; i<76; i++ ){
+ sprintf(&warning_output[1][i]," ");
+ }
+
+ printk("\n****************************************");
+ printk("****************************************\n");
+ printk("* %s *\n",&warning_output[0][0]);
+ printk("* Switch to safe MWDMA Mode! ");
+ printk(" *\n");
+ printk("* %s *\n",&warning_output[1][0]);
+ printk("****************************************");
+ printk("****************************************\n\n");
+ }
+#else
+ source_dev_tab.dev_id = DSCR_CMD0_ALWAYS;
+ source_dev_tab.dev_tsize = 8;
+ source_dev_tab.dev_devwidth = 32;
+ source_dev_tab.dev_physaddr = (u32)AU1XXX_ATA_PHYS_ADDR;
+ source_dev_tab.dev_intlevel = 0;
+ source_dev_tab.dev_intpolarity = 0;
+#endif
+
+#if CONFIG_BLK_DEV_IDE_AU1XXX_BURSTABLE_ON
+ /* set flags for tx channel */
+ source_dev_tab.dev_flags = DEV_FLAGS_OUT
+ | DEV_FLAGS_SYNC
+ | DEV_FLAGS_BURSTABLE;
+ auide->tx_dev_id = au1xxx_ddma_add_device( &source_dev_tab );
+ /* set flags for rx channel */
+ source_dev_tab.dev_flags = DEV_FLAGS_IN
+ | DEV_FLAGS_SYNC
+ | DEV_FLAGS_BURSTABLE;
+ auide->rx_dev_id = au1xxx_ddma_add_device( &source_dev_tab );
+#else
+ /* set flags for tx channel */
+ source_dev_tab.dev_flags = DEV_FLAGS_OUT | DEV_FLAGS_SYNC;
+ auide->tx_dev_id = au1xxx_ddma_add_device( &source_dev_tab );
+ /* set flags for rx channel */
+ source_dev_tab.dev_flags = DEV_FLAGS_IN | DEV_FLAGS_SYNC;
+ auide->rx_dev_id = au1xxx_ddma_add_device( &source_dev_tab );
+#endif
+
+#if defined(CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA)
+
+ auide->target_dev_id = au1xxx_ddma_add_device(&target_dev_tab);
+
+ /* Get a channel for TX */
+ auide->tx_chan = au1xxx_dbdma_chan_alloc(auide->target_dev_id,
+ auide->tx_dev_id,
+ auide_ddma_tx_callback,
+ (void*)auide);
+ /* Get a channel for RX */
+ auide->rx_chan = au1xxx_dbdma_chan_alloc(auide->rx_dev_id,
+ auide->target_dev_id,
+ auide_ddma_rx_callback,
+ (void*)auide);
+#else /* CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA */
+ /*
+ * Note: if call back is not enabled, update ctp->cur_ptr manually
+ */
+ auide->tx_chan = au1xxx_dbdma_chan_alloc(DSCR_CMD0_ALWAYS,
+ auide->tx_dev_id,
+ NULL,
+ (void*)auide);
+ auide->rx_chan = au1xxx_dbdma_chan_alloc(auide->rx_dev_id,
+ DSCR_CMD0_ALWAYS,
+ NULL,
+ (void*)auide);
+#endif
+ auide->tx_desc_head = (void*)au1xxx_dbdma_ring_alloc(auide->tx_chan,
+ NUM_DESCRIPTORS);
+ auide->rx_desc_head = (void*)au1xxx_dbdma_ring_alloc(auide->rx_chan,
+ NUM_DESCRIPTORS);
+
+#if defined(CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA)
+ hwif->dmatable_cpu = dma_alloc_coherent(auide->dev,
+ PRD_ENTRIES * PRD_BYTES, /* 1 Page */
+ &hwif->dmatable_dma, GFP_KERNEL);
+
+ auide->sg_table = kmalloc(sizeof(struct scatterlist) * PRD_ENTRIES,
+ GFP_KERNEL|GFP_DMA);
+ if (auide->sg_table == NULL) {
+ return -ENOMEM;
+ }
+#endif
+ au1xxx_dbdma_start( auide->tx_chan );
+ au1xxx_dbdma_start( auide->rx_chan );
+ return 0;
+}
+
+static void auide_setup_ports(hw_regs_t *hw, _auide_hwif *ahwif)
+{
+ int i;
+#define ide_ioreg_t unsigned long
+ ide_ioreg_t *ata_regs = hw->io_ports;
+
+ /* fixme */
+ for (i = 0; i < IDE_CONTROL_OFFSET; i++) {
+ *ata_regs++ = (ide_ioreg_t) ahwif->regbase
+ + (ide_ioreg_t)(i << AU1XXX_ATA_REG_OFFSET);
+ }
+
+ /* set the Alternative Status register */
+ *ata_regs = (ide_ioreg_t) ahwif->regbase
+ + (ide_ioreg_t)(14 << AU1XXX_ATA_REG_OFFSET);
+}
+
+static int au_ide_probe(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ _auide_hwif *ahwif = &auide_hwif;
+ ide_hwif_t *hwif;
+ struct resource *res;
+ int ret = 0;
+
+#if defined(CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA)
+ char *mode = "MWDMA2";
+#elif defined(CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA)
+ char *mode = "PIO+DDMA(offload)";
+#endif
+
+ memset(&auide_hwif, 0, sizeof(_auide_hwif));
+ auide_hwif.dev = 0;
+
+ ahwif->dev = dev;
+ ahwif->irq = platform_get_irq(pdev, 0);
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+ if (res == NULL) {
+ pr_debug("%s %d: no base address\n", DRV_NAME, pdev->id);
+ ret = -ENODEV;
+ goto out;
+ }
+
+ if (!request_mem_region (res->start, res->end-res->start, pdev->name)) {
+ pr_debug("%s: request_mem_region failed\n", DRV_NAME);
+ ret = -EBUSY;
+ goto out;
+ }
+
+ ahwif->regbase = (u32)ioremap(res->start, res->end-res->start);
+ if (ahwif->regbase == 0) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ hwif = &ide_hwifs[pdev->id];
+ hw_regs_t *hw = &hwif->hw;
+ hwif->irq = hw->irq = ahwif->irq;
+ hwif->chipset = ide_au1xxx;
+
+ auide_setup_ports(hw, ahwif);
+ memcpy(hwif->io_ports, hw->io_ports, sizeof(hwif->io_ports));
+
+#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_SEQTS_PER_RQ
+ hwif->rqsize = CONFIG_BLK_DEV_IDE_AU1XXX_SEQTS_PER_RQ;
+ hwif->rqsize = ((hwif->rqsize > AU1XXX_ATA_RQSIZE)
+ || (hwif->rqsize < 32)) ? AU1XXX_ATA_RQSIZE : hwif->rqsize;
+#else /* if kernel config is not set */
+ hwif->rqsize = AU1XXX_ATA_RQSIZE;
+#endif
+
+ hwif->ultra_mask = 0x0; /* Disable Ultra DMA */
+#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
+ hwif->mwdma_mask = 0x07; /* Multimode-2 DMA */
+ hwif->swdma_mask = 0x07;
+#else
+ hwif->mwdma_mask = 0x0;
+ hwif->swdma_mask = 0x0;
+#endif
+ //hwif->noprobe = !hwif->io_ports[IDE_DATA_OFFSET];
+ hwif->noprobe = 0;
+ hwif->drives[0].unmask = 1;
+ hwif->drives[1].unmask = 1;
+
+ /* hold should be on in all cases */
+ hwif->hold = 1;
+ hwif->mmio = 2;
+
+ /* set up local I/O function entry points */
+ hwif->INB = auide_inb;
+ hwif->INW = auide_inw;
+ hwif->INL = auide_inl;
+ hwif->INSW = auide_insw;
+ hwif->INSL = auide_insl;
+ hwif->OUTB = auide_outb;
+ hwif->OUTBSYNC = auide_outbsync;
+ hwif->OUTW = auide_outw;
+ hwif->OUTL = auide_outl;
+ hwif->OUTSW = auide_outsw;
+ hwif->OUTSL = auide_outsl;
+
+ hwif->tuneproc = &auide_tune_drive;
+ hwif->speedproc = &auide_tune_chipset;
+
+#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
+ hwif->ide_dma_off_quietly = &auide_dma_off_quietly;
+ hwif->ide_dma_timeout = &auide_dma_timeout;
+
+ hwif->ide_dma_check = &auide_dma_check;
+ hwif->dma_exec_cmd = &auide_dma_exec_cmd;
+ hwif->dma_start = &auide_dma_start;
+ hwif->ide_dma_end = &auide_dma_end;
+ hwif->dma_setup = &auide_dma_setup;
+ hwif->ide_dma_test_irq = &auide_dma_test_irq;
+ hwif->ide_dma_host_off = &auide_dma_host_off;
+ hwif->ide_dma_host_on = &auide_dma_host_on;
+ hwif->ide_dma_lostirq = &auide_dma_lostirq;
+ hwif->ide_dma_on = &auide_dma_on;
+
+ hwif->autodma = 1;
+ hwif->drives[0].autodma = hwif->autodma;
+ hwif->drives[1].autodma = hwif->autodma;
+ hwif->atapi_dma = 1;
+ hwif->drives[0].using_dma = 1;
+ hwif->drives[1].using_dma = 1;
+#else /* !CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA */
+ hwif->autodma = 0;
+ hwif->channel = 0;
+ hwif->hold = 1;
+ hwif->select_data = 0; /* no chipset-specific code */
+ hwif->config_data = 0; /* no chipset-specific code */
+
+ hwif->drives[0].autodma = 0;
+ hwif->drives[0].drive_data = 0; /* no drive data */
+ hwif->drives[0].using_dma = 0;
+ hwif->drives[0].waiting_for_dma = 0;
+ hwif->drives[0].autotune = 1; /* 1=autotune, 2=noautotune, 0=default */
+ /* secondary hdd not supported */
+ hwif->drives[1].autodma = 0;
+
+ hwif->drives[1].drive_data = 0;
+ hwif->drives[1].using_dma = 0;
+ hwif->drives[1].waiting_for_dma = 0;
+ hwif->drives[1].autotune = 2; /* 1=autotune, 2=noautotune, 0=default */
+#endif
+ hwif->drives[0].io_32bit = 0; /* 0=16-bit, 1=32-bit, 2/3=32bit+sync */
+ hwif->drives[1].io_32bit = 0; /* 0=16-bit, 1=32-bit, 2/3=32bit+sync */
+
+ /*Register Driver with PM Framework*/
+#ifdef CONFIG_PM
+ auide_hwif.pm.lock = SPIN_LOCK_UNLOCKED;
+ auide_hwif.pm.stopped = 0;
+
+ auide_hwif.pm.dev = new_au1xxx_power_device( "ide",
+ &au1200ide_pm_callback,
+ NULL);
+ if ( auide_hwif.pm.dev == NULL )
+ printk(KERN_INFO "Unable to create a power management \
+ device entry for the au1200-IDE.\n");
+ else
+ printk(KERN_INFO "Power management device entry for the \
+ au1200-IDE loaded.\n");
+#endif
+
+ auide_hwif.hwif = hwif;
+ hwif->hwif_data = &auide_hwif;
+
+#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA
+ auide_ddma_init(&auide_hwif);
+ dbdma_init_done = 1;
+#endif
+
+ probe_hwif_init(hwif);
+ dev_set_drvdata(dev, hwif);
+
+ printk(KERN_INFO "Au1xxx IDE(builtin) configured for %s\n", mode );
+
+out:
+ return ret;
+}
+
+static int au_ide_remove(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct resource *res;
+ ide_hwif_t *hwif = dev_get_drvdata(dev);
+ _auide_hwif *ahwif = &auide_hwif;
+
+ ide_unregister(hwif - ide_hwifs);
+
+ iounmap((void *)ahwif->regbase);
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ release_mem_region(res->start, res->end - res->start);
+
+ return 0;
+}
+
+static struct device_driver au1200_ide_driver = {
+ .name = "au1200-ide",
+ .bus = &platform_bus_type,
+ .probe = au_ide_probe,
+ .remove = au_ide_remove,
+};
+
+static int __init au_ide_init(void)
+{
+ return driver_register(&au1200_ide_driver);
+}
+
+static void __init au_ide_exit(void)
+{
+ driver_unregister(&au1200_ide_driver);
+}
+
+#ifdef CONFIG_PM
+int au1200ide_pm_callback( au1xxx_power_dev_t *dev,\
+ au1xxx_request_t request, void *data) {
+
+ unsigned int d, err = 0;
+ unsigned long flags;
+
+ spin_lock_irqsave(auide_hwif.pm.lock, flags);
+
+ switch (request){
+ case AU1XXX_PM_SLEEP:
+ err = au1xxxide_pm_sleep(dev);
+ break;
+ case AU1XXX_PM_WAKEUP:
+ d = *((unsigned int*)data);
+ if ( d > 0 && d <= 99) {
+ err = au1xxxide_pm_standby(dev);
+ }
+ else {
+ err = au1xxxide_pm_resume(dev);
+ }
+ break;
+ case AU1XXX_PM_GETSTATUS:
+ err = au1xxxide_pm_getstatus(dev);
+ break;
+ case AU1XXX_PM_ACCESS:
+ err = au1xxxide_pm_access(dev);
+ break;
+ case AU1XXX_PM_IDLE:
+ err = au1xxxide_pm_idle(dev);
+ break;
+ case AU1XXX_PM_CLEANUP:
+ err = au1xxxide_pm_cleanup(dev);
+ break;
+ default:
+ err = -1;
+ break;
+ }
+
+ spin_unlock_irqrestore(auide_hwif.pm.lock, flags);
+
+ return err;
+}
+
+static int au1xxxide_pm_standby( au1xxx_power_dev_t *dev ) {
+ return 0;
+}
+
+static int au1xxxide_pm_sleep( au1xxx_power_dev_t *dev ) {
+
+ int retval;
+ ide_hwif_t *hwif = auide_hwif.hwif;
+ struct request rq;
+ struct request_pm_state rqpm;
+ ide_task_t args;
+
+ if(auide_hwif.pm.stopped)
+ return -1;
+
+ /*
+ * wait until hard disc is ready
+ */
+ if ( wait_for_ready(&hwif->drives[0], 35000) ) {
+ printk("Wait for drive sleep timeout!\n");
+ retval = -1;
+ }
+
+ /*
+ * sequenz to tell the high level ide driver that pm is resuming
+ */
+ memset(&rq, 0, sizeof(rq));
+ memset(&rqpm, 0, sizeof(rqpm));
+ memset(&args, 0, sizeof(args));
+ rq.flags = REQ_PM_SUSPEND;
+ rq.special = &args;
+ rq.pm = &rqpm;
+ rqpm.pm_step = ide_pm_state_start_suspend;
+ rqpm.pm_state = PMSG_SUSPEND;
+
+ retval = ide_do_drive_cmd(&hwif->drives[0], &rq, ide_wait);
+
+ if (wait_for_ready (&hwif->drives[0], 35000)) {
+ printk("Wait for drive sleep timeout!\n");
+ retval = -1;
+ }
+
+ /*
+ * stop dbdma channels
+ */
+ au1xxx_dbdma_reset(auide_hwif.tx_chan);
+ au1xxx_dbdma_reset(auide_hwif.rx_chan);
+
+ auide_hwif.pm.stopped = 1;
+
+ return retval;
+}
+
+static int au1xxxide_pm_resume( au1xxx_power_dev_t *dev ) {
+
+ int retval;
+ ide_hwif_t *hwif = auide_hwif.hwif;
+ struct request rq;
+ struct request_pm_state rqpm;
+ ide_task_t args;
+
+ if(!auide_hwif.pm.stopped)
+ return -1;
+
+ /*
+ * start dbdma channels
+ */
+ au1xxx_dbdma_start(auide_hwif.tx_chan);
+ au1xxx_dbdma_start(auide_hwif.rx_chan);
+
+ /*
+ * wait until hard disc is ready
+ */
+ if (wait_for_ready ( &hwif->drives[0], 35000)) {
+ printk("Wait for drive wake up timeout!\n");
+ retval = -1;
+ }
+
+ /*
+ * sequenz to tell the high level ide driver that pm is resuming
+ */
+ memset(&rq, 0, sizeof(rq));
+ memset(&rqpm, 0, sizeof(rqpm));
+ memset(&args, 0, sizeof(args));
+ rq.flags = REQ_PM_RESUME;
+ rq.special = &args;
+ rq.pm = &rqpm;
+ rqpm.pm_step = ide_pm_state_start_resume;
+ rqpm.pm_state = PMSG_ON;
+
+ retval = ide_do_drive_cmd(&hwif->drives[0], &rq, ide_head_wait);
+
+ /*
+ * wait for hard disc
+ */
+ if ( wait_for_ready(&hwif->drives[0], 35000) ) {
+ printk("Wait for drive wake up timeout!\n");
+ retval = -1;
+ }
+
+ auide_hwif.pm.stopped = 0;
+
+ return retval;
+}
+
+static int au1xxxide_pm_getstatus( au1xxx_power_dev_t *dev ) {
+ return dev->cur_state;
+}
+
+static int au1xxxide_pm_access( au1xxx_power_dev_t *dev ) {
+ if (dev->cur_state != AWAKE_STATE)
+ return 0;
+ else
+ return -1;
+}
+
+static int au1xxxide_pm_idle( au1xxx_power_dev_t *dev ) {
+ return 0;
+}
+
+static int au1xxxide_pm_cleanup( au1xxx_power_dev_t *dev ) {
+ return 0;
+}
+#endif /* CONFIG_PM */
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("AU1200 IDE driver");
+
+module_init(au_ide_init);
+module_exit(au_ide_exit);
diff --git a/drivers/ide/pci/Makefile b/drivers/ide/pci/Makefile
index af46226c1796..f35d684edc25 100644
--- a/drivers/ide/pci/Makefile
+++ b/drivers/ide/pci/Makefile
@@ -6,6 +6,7 @@ obj-$(CONFIG_BLK_DEV_ATIIXP) += atiixp.o
obj-$(CONFIG_BLK_DEV_CMD64X) += cmd64x.o
obj-$(CONFIG_BLK_DEV_CS5520) += cs5520.o
obj-$(CONFIG_BLK_DEV_CS5530) += cs5530.o
+obj-$(CONFIG_BLK_DEV_CS5535) += cs5535.o
obj-$(CONFIG_BLK_DEV_SC1200) += sc1200.o
obj-$(CONFIG_BLK_DEV_CY82C693) += cy82c693.o
obj-$(CONFIG_BLK_DEV_HPT34X) += hpt34x.o
diff --git a/drivers/ide/pci/amd74xx.c b/drivers/ide/pci/amd74xx.c
index 844a6c9fb949..21965e5ef25e 100644
--- a/drivers/ide/pci/amd74xx.c
+++ b/drivers/ide/pci/amd74xx.c
@@ -74,6 +74,7 @@ static struct amd_ide_chip {
{ PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_IDE, 0x50, AMD_UDMA_133 },
{ PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_IDE, 0x50, AMD_UDMA_133 },
{ PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_IDE, 0x50, AMD_UDMA_133 },
+ { PCI_DEVICE_ID_AMD_CS5536_IDE, 0x40, AMD_UDMA_100 },
{ 0 }
};
@@ -491,6 +492,7 @@ static ide_pci_device_t amd74xx_chipsets[] __devinitdata = {
/* 14 */ DECLARE_NV_DEV("NFORCE-MCP04"),
/* 15 */ DECLARE_NV_DEV("NFORCE-MCP51"),
/* 16 */ DECLARE_NV_DEV("NFORCE-MCP55"),
+ /* 17 */ DECLARE_AMD_DEV("AMD5536"),
};
static int __devinit amd74xx_probe(struct pci_dev *dev, const struct pci_device_id *id)
@@ -527,6 +529,7 @@ static struct pci_device_id amd74xx_pci_tbl[] = {
{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 14 },
{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 15 },
{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 16 },
+ { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 17 },
{ 0, },
};
MODULE_DEVICE_TABLE(pci, amd74xx_pci_tbl);
diff --git a/drivers/ide/pci/cs5535.c b/drivers/ide/pci/cs5535.c
new file mode 100644
index 000000000000..6eb305197f3c
--- /dev/null
+++ b/drivers/ide/pci/cs5535.c
@@ -0,0 +1,305 @@
+/*
+ * linux/drivers/ide/pci/cs5535.c
+ *
+ * Copyright (C) 2004-2005 Advanced Micro Devices, Inc.
+ *
+ * History:
+ * 09/20/2005 - Jaya Kumar <jayakumar.ide@gmail.com>
+ * - Reworked tuneproc, set_drive, misc mods to prep for mainline
+ * - Work was sponsored by CIS (M) Sdn Bhd.
+ * Ported to Kernel 2.6.11 on June 26, 2005 by
+ * Wolfgang Zuleger <wolfgang.zuleger@gmx.de>
+ * Alexander Kiausch <alex.kiausch@t-online.de>
+ * Originally developed by AMD for 2.4/2.6
+ *
+ * Development of this chipset driver was funded
+ * by the nice folks at National Semiconductor/AMD.
+ *
+ * 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.
+ *
+ * Documentation:
+ * CS5535 documentation available from AMD
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/ide.h>
+
+#include "ide-timing.h"
+
+#define MSR_ATAC_BASE 0x51300000
+#define ATAC_GLD_MSR_CAP (MSR_ATAC_BASE+0)
+#define ATAC_GLD_MSR_CONFIG (MSR_ATAC_BASE+0x01)
+#define ATAC_GLD_MSR_SMI (MSR_ATAC_BASE+0x02)
+#define ATAC_GLD_MSR_ERROR (MSR_ATAC_BASE+0x03)
+#define ATAC_GLD_MSR_PM (MSR_ATAC_BASE+0x04)
+#define ATAC_GLD_MSR_DIAG (MSR_ATAC_BASE+0x05)
+#define ATAC_IO_BAR (MSR_ATAC_BASE+0x08)
+#define ATAC_RESET (MSR_ATAC_BASE+0x10)
+#define ATAC_CH0D0_PIO (MSR_ATAC_BASE+0x20)
+#define ATAC_CH0D0_DMA (MSR_ATAC_BASE+0x21)
+#define ATAC_CH0D1_PIO (MSR_ATAC_BASE+0x22)
+#define ATAC_CH0D1_DMA (MSR_ATAC_BASE+0x23)
+#define ATAC_PCI_ABRTERR (MSR_ATAC_BASE+0x24)
+#define ATAC_BM0_CMD_PRIM 0x00
+#define ATAC_BM0_STS_PRIM 0x02
+#define ATAC_BM0_PRD 0x04
+#define CS5535_CABLE_DETECT 0x48
+
+/* Format I PIO settings. We seperate out cmd and data for safer timings */
+
+static unsigned int cs5535_pio_cmd_timings[5] =
+{ 0xF7F4, 0x53F3, 0x13F1, 0x5131, 0x1131 };
+static unsigned int cs5535_pio_dta_timings[5] =
+{ 0xF7F4, 0xF173, 0x8141, 0x5131, 0x1131 };
+
+static unsigned int cs5535_mwdma_timings[3] =
+{ 0x7F0FFFF3, 0x7F035352, 0x7f024241 };
+
+static unsigned int cs5535_udma_timings[5] =
+{ 0x7F7436A1, 0x7F733481, 0x7F723261, 0x7F713161, 0x7F703061 };
+
+/* Macros to check if the register is the reset value - reset value is an
+ invalid timing and indicates the register has not been set previously */
+
+#define CS5535_BAD_PIO(timings) ( (timings&~0x80000000UL) == 0x00009172 )
+#define CS5535_BAD_DMA(timings) ( (timings & 0x000FFFFF) == 0x00077771 )
+
+/****
+ * cs5535_set_speed - Configure the chipset to the new speed
+ * @drive: Drive to set up
+ * @speed: desired speed
+ *
+ * cs5535_set_speed() configures the chipset to a new speed.
+ */
+static void cs5535_set_speed(ide_drive_t *drive, u8 speed)
+{
+
+ u32 reg = 0, dummy;
+ int unit = drive->select.b.unit;
+
+
+ /* Set the PIO timings */
+ if ((speed & XFER_MODE) == XFER_PIO) {
+ u8 pioa;
+ u8 piob;
+ u8 cmd;
+
+ pioa = speed - XFER_PIO_0;
+ piob = ide_get_best_pio_mode(&(drive->hwif->drives[!unit]),
+ 255, 4, NULL);
+ cmd = pioa < piob ? pioa : piob;
+
+ /* Write the speed of the current drive */
+ reg = (cs5535_pio_cmd_timings[cmd] << 16) |
+ cs5535_pio_dta_timings[pioa];
+ wrmsr(unit ? ATAC_CH0D1_PIO : ATAC_CH0D0_PIO, reg, 0);
+
+ /* And if nessesary - change the speed of the other drive */
+ rdmsr(unit ? ATAC_CH0D0_PIO : ATAC_CH0D1_PIO, reg, dummy);
+
+ if (((reg >> 16) & cs5535_pio_cmd_timings[cmd]) !=
+ cs5535_pio_cmd_timings[cmd]) {
+ reg &= 0x0000FFFF;
+ reg |= cs5535_pio_cmd_timings[cmd] << 16;
+ wrmsr(unit ? ATAC_CH0D0_PIO : ATAC_CH0D1_PIO, reg, 0);
+ }
+
+ /* Set bit 31 of the DMA register for PIO format 1 timings */
+ rdmsr(unit ? ATAC_CH0D1_DMA : ATAC_CH0D0_DMA, reg, dummy);
+ wrmsr(unit ? ATAC_CH0D1_DMA : ATAC_CH0D0_DMA,
+ reg | 0x80000000UL, 0);
+ } else {
+ rdmsr(unit ? ATAC_CH0D1_DMA : ATAC_CH0D0_DMA, reg, dummy);
+
+ reg &= 0x80000000UL; /* Preserve the PIO format bit */
+
+ if (speed >= XFER_UDMA_0 && speed <= XFER_UDMA_7)
+ reg |= cs5535_udma_timings[speed - XFER_UDMA_0];
+ else if (speed >= XFER_MW_DMA_0 && speed <= XFER_MW_DMA_2)
+ reg |= cs5535_mwdma_timings[speed - XFER_MW_DMA_0];
+ else
+ return;
+
+ wrmsr(unit ? ATAC_CH0D1_DMA : ATAC_CH0D0_DMA, reg, 0);
+ }
+}
+
+static u8 cs5535_ratemask(ide_drive_t *drive)
+{
+ /* eighty93 will return 1 if it's 80core and capable of
+ exceeding udma2, 0 otherwise. we need ratemask to set
+ the max speed and if we can > udma2 then we return 2
+ which selects speed_max as udma4 which is the 5535's max
+ speed, and 1 selects udma2 which is the max for 40c */
+ if (!eighty_ninty_three(drive))
+ return 1;
+
+ return 2;
+}
+
+
+/****
+ * cs5535_set_drive - Configure the drive to the new speed
+ * @drive: Drive to set up
+ * @speed: desired speed
+ *
+ * cs5535_set_drive() configures the drive and the chipset to a
+ * new speed. It also can be called by upper layers.
+ */
+static int cs5535_set_drive(ide_drive_t *drive, u8 speed)
+{
+ speed = ide_rate_filter(cs5535_ratemask(drive), speed);
+ ide_config_drive_speed(drive, speed);
+ cs5535_set_speed(drive, speed);
+
+ return 0;
+}
+
+/****
+ * cs5535_tuneproc - PIO setup
+ * @drive: drive to set up
+ * @pio: mode to use (255 for 'best possible')
+ *
+ * A callback from the upper layers for PIO-only tuning.
+ */
+static void cs5535_tuneproc(ide_drive_t *drive, u8 xferspeed)
+{
+ u8 modes[] = { XFER_PIO_0, XFER_PIO_1, XFER_PIO_2, XFER_PIO_3,
+ XFER_PIO_4 };
+
+ /* cs5535 max pio is pio 4, best_pio will check the blacklist.
+ i think we don't need to rate_filter the incoming xferspeed
+ since we know we're only going to choose pio */
+ xferspeed = ide_get_best_pio_mode(drive, xferspeed, 4, NULL);
+ ide_config_drive_speed(drive, modes[xferspeed]);
+ cs5535_set_speed(drive, xferspeed);
+}
+
+static int cs5535_config_drive_for_dma(ide_drive_t *drive)
+{
+ u8 speed;
+
+ speed = ide_dma_speed(drive, cs5535_ratemask(drive));
+
+ /* If no DMA speed was available then let dma_check hit pio */
+ if (!speed) {
+ return 0;
+ }
+
+ cs5535_set_drive(drive, speed);
+ return ide_dma_enable(drive);
+}
+
+static int cs5535_dma_check(ide_drive_t *drive)
+{
+ ide_hwif_t *hwif = drive->hwif;
+ struct hd_driveid *id = drive->id;
+ u8 speed;
+
+ drive->init_speed = 0;
+
+ if ((id->capability & 1) && drive->autodma) {
+ if (ide_use_dma(drive)) {
+ if (cs5535_config_drive_for_dma(drive))
+ return hwif->ide_dma_on(drive);
+ }
+
+ goto fast_ata_pio;
+
+ } else if ((id->capability & 8) || (id->field_valid & 2)) {
+fast_ata_pio:
+ speed = ide_get_best_pio_mode(drive, 255, 4, NULL);
+ cs5535_set_drive(drive, speed);
+ return hwif->ide_dma_off_quietly(drive);
+ }
+ /* IORDY not supported */
+ return 0;
+}
+
+static u8 __devinit cs5535_cable_detect(struct pci_dev *dev)
+{
+ u8 bit;
+
+ /* if a 80 wire cable was detected */
+ pci_read_config_byte(dev, CS5535_CABLE_DETECT, &bit);
+ return (bit & 1);
+}
+
+/****
+ * init_hwif_cs5535 - Initialize one ide cannel
+ * @hwif: Channel descriptor
+ *
+ * This gets invoked by the IDE driver once for each channel. It
+ * performs channel-specific pre-initialization before drive probing.
+ *
+ */
+static void __devinit init_hwif_cs5535(ide_hwif_t *hwif)
+{
+ int i;
+
+ hwif->autodma = 0;
+
+ hwif->tuneproc = &cs5535_tuneproc;
+ hwif->speedproc = &cs5535_set_drive;
+ hwif->ide_dma_check = &cs5535_dma_check;
+
+ hwif->atapi_dma = 1;
+ hwif->ultra_mask = 0x1F;
+ hwif->mwdma_mask = 0x07;
+
+
+ hwif->udma_four = cs5535_cable_detect(hwif->pci_dev);
+
+ if (!noautodma)
+ hwif->autodma = 1;
+
+ /* just setting autotune and not worrying about bios timings */
+ for (i = 0; i < 2; i++) {
+ hwif->drives[i].autotune = 1;
+ hwif->drives[i].autodma = hwif->autodma;
+ }
+}
+
+static ide_pci_device_t cs5535_chipset __devinitdata = {
+ .name = "CS5535",
+ .init_hwif = init_hwif_cs5535,
+ .channels = 1,
+ .autodma = AUTODMA,
+ .bootable = ON_BOARD,
+};
+
+static int __devinit cs5535_init_one(struct pci_dev *dev,
+ const struct pci_device_id *id)
+{
+ return ide_setup_pci_device(dev, &cs5535_chipset);
+}
+
+static struct pci_device_id cs5535_pci_tbl[] =
+{
+ { PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_CS5535_IDE, PCI_ANY_ID,
+ PCI_ANY_ID, 0, 0, 0},
+ { 0, },
+};
+
+MODULE_DEVICE_TABLE(pci, cs5535_pci_tbl);
+
+static struct pci_driver driver = {
+ .name = "CS5535_IDE",
+ .id_table = cs5535_pci_tbl,
+ .probe = cs5535_init_one,
+};
+
+static int __init cs5535_ide_init(void)
+{
+ return ide_pci_register_driver(&driver);
+}
+
+module_init(cs5535_ide_init);
+
+MODULE_AUTHOR("AMD");
+MODULE_DESCRIPTION("PCI driver module for AMD/NS CS5535 IDE");
+MODULE_LICENSE("GPL");
diff --git a/drivers/ide/pci/cy82c693.c b/drivers/ide/pci/cy82c693.c
index 5a33513f3dd1..9f41ecd56338 100644
--- a/drivers/ide/pci/cy82c693.c
+++ b/drivers/ide/pci/cy82c693.c
@@ -469,7 +469,7 @@ static void __devinit init_hwif_cy82c693(ide_hwif_t *hwif)
static __devinitdata ide_hwif_t *primary;
-void __devinit init_iops_cy82c693(ide_hwif_t *hwif)
+static void __devinit init_iops_cy82c693(ide_hwif_t *hwif)
{
if (PCI_FUNC(hwif->pci_dev->devfn) == 1)
primary = hwif;
diff --git a/drivers/ide/pci/hpt366.c b/drivers/ide/pci/hpt366.c
index 127619a109ed..7b589d948bf9 100644
--- a/drivers/ide/pci/hpt366.c
+++ b/drivers/ide/pci/hpt366.c
@@ -1516,7 +1516,7 @@ static void __devinit init_dma_hpt366(ide_hwif_t *hwif, unsigned long dmabase)
static void __devinit init_iops_hpt366(ide_hwif_t *hwif)
{
- struct hpt_info *info = kmalloc(sizeof(struct hpt_info), GFP_KERNEL);
+ struct hpt_info *info = kzalloc(sizeof(struct hpt_info), GFP_KERNEL);
unsigned long dmabase = pci_resource_start(hwif->pci_dev, 4);
u8 did, rid;
@@ -1524,7 +1524,6 @@ static void __devinit init_iops_hpt366(ide_hwif_t *hwif)
printk(KERN_WARNING "hpt366: out of memory.\n");
return;
}
- memset(info, 0, sizeof(struct hpt_info));
ide_set_hwifdata(hwif, info);
if(dmabase) {
diff --git a/drivers/ide/pci/it821x.c b/drivers/ide/pci/it821x.c
index e440036e651f..108fda83fea4 100644
--- a/drivers/ide/pci/it821x.c
+++ b/drivers/ide/pci/it821x.c
@@ -642,14 +642,13 @@ static void __devinit it821x_fixups(ide_hwif_t *hwif)
static void __devinit init_hwif_it821x(ide_hwif_t *hwif)
{
- struct it821x_dev *idev = kmalloc(sizeof(struct it821x_dev), GFP_KERNEL);
+ struct it821x_dev *idev = kzalloc(sizeof(struct it821x_dev), GFP_KERNEL);
u8 conf;
if(idev == NULL) {
printk(KERN_ERR "it821x: out of memory, falling back to legacy behaviour.\n");
goto fallback;
}
- memset(idev, 0, sizeof(struct it821x_dev));
ide_set_hwifdata(hwif, idev);
pci_read_config_byte(hwif->pci_dev, 0x50, &conf);
diff --git a/drivers/ide/pci/siimage.c b/drivers/ide/pci/siimage.c
index 2b9961b88135..022d244f2eb0 100644
--- a/drivers/ide/pci/siimage.c
+++ b/drivers/ide/pci/siimage.c
@@ -701,6 +701,7 @@ static unsigned int setup_mmio_siimage (struct pci_dev *dev, const char *name)
unsigned long barsize = pci_resource_len(dev, 5);
u8 tmpbyte = 0;
void __iomem *ioaddr;
+ u32 tmp, irq_mask;
/*
* Drop back to PIO if we can't map the mmio. Some
@@ -726,6 +727,14 @@ static unsigned int setup_mmio_siimage (struct pci_dev *dev, const char *name)
pci_set_drvdata(dev, (void *) ioaddr);
if (pdev_is_sata(dev)) {
+ /* make sure IDE0/1 interrupts are not masked */
+ irq_mask = (1 << 22) | (1 << 23);
+ tmp = readl(ioaddr + 0x48);
+ if (tmp & irq_mask) {
+ tmp &= ~irq_mask;
+ writel(tmp, ioaddr + 0x48);
+ readl(ioaddr + 0x48); /* flush */
+ }
writel(0, ioaddr + 0x148);
writel(0, ioaddr + 0x1C8);
}
diff --git a/drivers/ide/ppc/pmac.c b/drivers/ide/ppc/pmac.c
index 87d1f8a1f41e..b3e65a65d202 100644
--- a/drivers/ide/ppc/pmac.c
+++ b/drivers/ide/ppc/pmac.c
@@ -81,7 +81,7 @@ typedef struct pmac_ide_hwif {
} pmac_ide_hwif_t;
-static pmac_ide_hwif_t pmac_ide[MAX_HWIFS] __pmacdata;
+static pmac_ide_hwif_t pmac_ide[MAX_HWIFS];
static int pmac_ide_count;
enum {
@@ -242,7 +242,7 @@ struct mdma_timings_t {
int cycleTime;
};
-struct mdma_timings_t mdma_timings_33[] __pmacdata =
+struct mdma_timings_t mdma_timings_33[] =
{
{ 240, 240, 480 },
{ 180, 180, 360 },
@@ -255,7 +255,7 @@ struct mdma_timings_t mdma_timings_33[] __pmacdata =
{ 0, 0, 0 }
};
-struct mdma_timings_t mdma_timings_33k[] __pmacdata =
+struct mdma_timings_t mdma_timings_33k[] =
{
{ 240, 240, 480 },
{ 180, 180, 360 },
@@ -268,7 +268,7 @@ struct mdma_timings_t mdma_timings_33k[] __pmacdata =
{ 0, 0, 0 }
};
-struct mdma_timings_t mdma_timings_66[] __pmacdata =
+struct mdma_timings_t mdma_timings_66[] =
{
{ 240, 240, 480 },
{ 180, 180, 360 },
@@ -286,7 +286,7 @@ struct {
int addrSetup; /* ??? */
int rdy2pause;
int wrDataSetup;
-} kl66_udma_timings[] __pmacdata =
+} kl66_udma_timings[] =
{
{ 0, 180, 120 }, /* Mode 0 */
{ 0, 150, 90 }, /* 1 */
@@ -301,7 +301,7 @@ struct kauai_timing {
u32 timing_reg;
};
-static struct kauai_timing kauai_pio_timings[] __pmacdata =
+static struct kauai_timing kauai_pio_timings[] =
{
{ 930 , 0x08000fff },
{ 600 , 0x08000a92 },
@@ -316,7 +316,7 @@ static struct kauai_timing kauai_pio_timings[] __pmacdata =
{ 120 , 0x04000148 }
};
-static struct kauai_timing kauai_mdma_timings[] __pmacdata =
+static struct kauai_timing kauai_mdma_timings[] =
{
{ 1260 , 0x00fff000 },
{ 480 , 0x00618000 },
@@ -330,7 +330,7 @@ static struct kauai_timing kauai_mdma_timings[] __pmacdata =
{ 0 , 0 },
};
-static struct kauai_timing kauai_udma_timings[] __pmacdata =
+static struct kauai_timing kauai_udma_timings[] =
{
{ 120 , 0x000070c0 },
{ 90 , 0x00005d80 },
@@ -341,7 +341,7 @@ static struct kauai_timing kauai_udma_timings[] __pmacdata =
{ 0 , 0 },
};
-static struct kauai_timing shasta_pio_timings[] __pmacdata =
+static struct kauai_timing shasta_pio_timings[] =
{
{ 930 , 0x08000fff },
{ 600 , 0x0A000c97 },
@@ -356,7 +356,7 @@ static struct kauai_timing shasta_pio_timings[] __pmacdata =
{ 120 , 0x0400010a }
};
-static struct kauai_timing shasta_mdma_timings[] __pmacdata =
+static struct kauai_timing shasta_mdma_timings[] =
{
{ 1260 , 0x00fff000 },
{ 480 , 0x00820800 },
@@ -370,7 +370,7 @@ static struct kauai_timing shasta_mdma_timings[] __pmacdata =
{ 0 , 0 },
};
-static struct kauai_timing shasta_udma133_timings[] __pmacdata =
+static struct kauai_timing shasta_udma133_timings[] =
{
{ 120 , 0x00035901, },
{ 90 , 0x000348b1, },
@@ -497,16 +497,19 @@ pmu_hd_blink_init(void)
if (pmu_get_model() != PMU_KEYLARGO_BASED)
return 0;
- dt = find_devices("device-tree");
+ dt = of_find_node_by_path("/");
if (dt == NULL)
return 0;
model = (const char *)get_property(dt, "model", NULL);
if (model == NULL)
return 0;
if (strncmp(model, "PowerBook", strlen("PowerBook")) != 0 &&
- strncmp(model, "iBook", strlen("iBook")) != 0)
+ strncmp(model, "iBook", strlen("iBook")) != 0) {
+ of_node_put(dt);
return 0;
-
+ }
+ of_node_put(dt);
+
pmu_blink_on.complete = 1;
pmu_blink_off.complete = 1;
spin_lock_init(&pmu_blink_lock);
@@ -522,7 +525,7 @@ pmu_hd_blink_init(void)
* N.B. this can't be an initfunc, because the media-bay task can
* call ide_[un]register at any time.
*/
-void __pmac
+void
pmac_ide_init_hwif_ports(hw_regs_t *hw,
unsigned long data_port, unsigned long ctrl_port,
int *irq)
@@ -559,7 +562,7 @@ pmac_ide_init_hwif_ports(hw_regs_t *hw,
* timing register when selecting that unit. This version is for
* ASICs with a single timing register
*/
-static void __pmac
+static void
pmac_ide_selectproc(ide_drive_t *drive)
{
pmac_ide_hwif_t* pmif = (pmac_ide_hwif_t *)HWIF(drive)->hwif_data;
@@ -579,7 +582,7 @@ pmac_ide_selectproc(ide_drive_t *drive)
* timing register when selecting that unit. This version is for
* ASICs with a dual timing register (Kauai)
*/
-static void __pmac
+static void
pmac_ide_kauai_selectproc(ide_drive_t *drive)
{
pmac_ide_hwif_t* pmif = (pmac_ide_hwif_t *)HWIF(drive)->hwif_data;
@@ -600,7 +603,7 @@ pmac_ide_kauai_selectproc(ide_drive_t *drive)
/*
* Force an update of controller timing values for a given drive
*/
-static void __pmac
+static void
pmac_ide_do_update_timings(ide_drive_t *drive)
{
pmac_ide_hwif_t* pmif = (pmac_ide_hwif_t *)HWIF(drive)->hwif_data;
@@ -633,7 +636,7 @@ pmac_outbsync(ide_drive_t *drive, u8 value, unsigned long port)
* to sort that out sooner or later and see if I can finally get the
* common version to work properly in all cases
*/
-static int __pmac
+static int
pmac_ide_do_setfeature(ide_drive_t *drive, u8 command)
{
ide_hwif_t *hwif = HWIF(drive);
@@ -710,7 +713,7 @@ out:
/*
* Old tuning functions (called on hdparm -p), sets up drive PIO timings
*/
-static void __pmac
+static void
pmac_ide_tuneproc(ide_drive_t *drive, u8 pio)
{
ide_pio_data_t d;
@@ -801,7 +804,7 @@ pmac_ide_tuneproc(ide_drive_t *drive, u8 pio)
/*
* Calculate KeyLargo ATA/66 UDMA timings
*/
-static int __pmac
+static int
set_timings_udma_ata4(u32 *timings, u8 speed)
{
unsigned rdyToPauseTicks, wrDataSetupTicks, addrTicks;
@@ -829,7 +832,7 @@ set_timings_udma_ata4(u32 *timings, u8 speed)
/*
* Calculate Kauai ATA/100 UDMA timings
*/
-static int __pmac
+static int
set_timings_udma_ata6(u32 *pio_timings, u32 *ultra_timings, u8 speed)
{
struct ide_timing *t = ide_timing_find_mode(speed);
@@ -849,7 +852,7 @@ set_timings_udma_ata6(u32 *pio_timings, u32 *ultra_timings, u8 speed)
/*
* Calculate Shasta ATA/133 UDMA timings
*/
-static int __pmac
+static int
set_timings_udma_shasta(u32 *pio_timings, u32 *ultra_timings, u8 speed)
{
struct ide_timing *t = ide_timing_find_mode(speed);
@@ -869,7 +872,7 @@ set_timings_udma_shasta(u32 *pio_timings, u32 *ultra_timings, u8 speed)
/*
* Calculate MDMA timings for all cells
*/
-static int __pmac
+static int
set_timings_mdma(ide_drive_t *drive, int intf_type, u32 *timings, u32 *timings2,
u8 speed, int drive_cycle_time)
{
@@ -1014,7 +1017,7 @@ set_timings_mdma(ide_drive_t *drive, int intf_type, u32 *timings, u32 *timings2,
* our dedicated function is more precise as it uses the drive provided
* cycle time value. We should probably fix this one to deal with that too...
*/
-static int __pmac
+static int
pmac_ide_tune_chipset (ide_drive_t *drive, byte speed)
{
int unit = (drive->select.b.unit & 0x01);
@@ -1092,7 +1095,7 @@ pmac_ide_tune_chipset (ide_drive_t *drive, byte speed)
* Blast some well known "safe" values to the timing registers at init or
* wakeup from sleep time, before we do real calculation
*/
-static void __pmac
+static void
sanitize_timings(pmac_ide_hwif_t *pmif)
{
unsigned int value, value2 = 0;
@@ -1123,13 +1126,13 @@ sanitize_timings(pmac_ide_hwif_t *pmif)
pmif->timings[2] = pmif->timings[3] = value2;
}
-unsigned long __pmac
+unsigned long
pmac_ide_get_base(int index)
{
return pmac_ide[index].regbase;
}
-int __pmac
+int
pmac_ide_check_base(unsigned long base)
{
int ix;
@@ -1140,7 +1143,7 @@ pmac_ide_check_base(unsigned long base)
return -1;
}
-int __pmac
+int
pmac_ide_get_irq(unsigned long base)
{
int ix;
@@ -1151,7 +1154,7 @@ pmac_ide_get_irq(unsigned long base)
return 0;
}
-static int ide_majors[] __pmacdata = { 3, 22, 33, 34, 56, 57 };
+static int ide_majors[] = { 3, 22, 33, 34, 56, 57 };
dev_t __init
pmac_find_ide_boot(char *bootdevice, int n)
@@ -1701,7 +1704,7 @@ pmac_ide_probe(void)
* pmac_ide_build_dmatable builds the DBDMA command list
* for a transfer and sets the DBDMA channel to point to it.
*/
-static int __pmac
+static int
pmac_ide_build_dmatable(ide_drive_t *drive, struct request *rq)
{
struct dbdma_cmd *table;
@@ -1785,7 +1788,7 @@ pmac_ide_build_dmatable(ide_drive_t *drive, struct request *rq)
}
/* Teardown mappings after DMA has completed. */
-static void __pmac
+static void
pmac_ide_destroy_dmatable (ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
@@ -1802,7 +1805,7 @@ pmac_ide_destroy_dmatable (ide_drive_t *drive)
/*
* Pick up best MDMA timing for the drive and apply it
*/
-static int __pmac
+static int
pmac_ide_mdma_enable(ide_drive_t *drive, u16 mode)
{
ide_hwif_t *hwif = HWIF(drive);
@@ -1859,7 +1862,7 @@ pmac_ide_mdma_enable(ide_drive_t *drive, u16 mode)
/*
* Pick up best UDMA timing for the drive and apply it
*/
-static int __pmac
+static int
pmac_ide_udma_enable(ide_drive_t *drive, u16 mode)
{
ide_hwif_t *hwif = HWIF(drive);
@@ -1915,7 +1918,7 @@ pmac_ide_udma_enable(ide_drive_t *drive, u16 mode)
* Check what is the best DMA timing setting for the drive and
* call appropriate functions to apply it.
*/
-static int __pmac
+static int
pmac_ide_dma_check(ide_drive_t *drive)
{
struct hd_driveid *id = drive->id;
@@ -1967,7 +1970,7 @@ pmac_ide_dma_check(ide_drive_t *drive)
* Prepare a DMA transfer. We build the DMA table, adjust the timings for
* a read on KeyLargo ATA/66 and mark us as waiting for DMA completion
*/
-static int __pmac
+static int
pmac_ide_dma_setup(ide_drive_t *drive)
{
ide_hwif_t *hwif = HWIF(drive);
@@ -1997,7 +2000,7 @@ pmac_ide_dma_setup(ide_drive_t *drive)
return 0;
}
-static void __pmac
+static void
pmac_ide_dma_exec_cmd(ide_drive_t *drive, u8 command)
{
/* issue cmd to drive */
@@ -2008,7 +2011,7 @@ pmac_ide_dma_exec_cmd(ide_drive_t *drive, u8 command)
* Kick the DMA controller into life after the DMA command has been issued
* to the drive.
*/
-static void __pmac
+static void
pmac_ide_dma_start(ide_drive_t *drive)
{
pmac_ide_hwif_t* pmif = (pmac_ide_hwif_t *)HWIF(drive)->hwif_data;
@@ -2024,7 +2027,7 @@ pmac_ide_dma_start(ide_drive_t *drive)
/*
* After a DMA transfer, make sure the controller is stopped
*/
-static int __pmac
+static int
pmac_ide_dma_end (ide_drive_t *drive)
{
pmac_ide_hwif_t* pmif = (pmac_ide_hwif_t *)HWIF(drive)->hwif_data;
@@ -2052,7 +2055,7 @@ pmac_ide_dma_end (ide_drive_t *drive)
* that's not implemented yet), on the other hand, we don't have shared interrupts
* so it's not really a problem
*/
-static int __pmac
+static int
pmac_ide_dma_test_irq (ide_drive_t *drive)
{
pmac_ide_hwif_t* pmif = (pmac_ide_hwif_t *)HWIF(drive)->hwif_data;
@@ -2108,19 +2111,19 @@ pmac_ide_dma_test_irq (ide_drive_t *drive)
return 1;
}
-static int __pmac
+static int
pmac_ide_dma_host_off (ide_drive_t *drive)
{
return 0;
}
-static int __pmac
+static int
pmac_ide_dma_host_on (ide_drive_t *drive)
{
return 0;
}
-static int __pmac
+static int
pmac_ide_dma_lostirq (ide_drive_t *drive)
{
pmac_ide_hwif_t* pmif = (pmac_ide_hwif_t *)HWIF(drive)->hwif_data;
diff --git a/drivers/ide/setup-pci.c b/drivers/ide/setup-pci.c
index 18ed7765417c..d4f2111d4364 100644
--- a/drivers/ide/setup-pci.c
+++ b/drivers/ide/setup-pci.c
@@ -787,8 +787,9 @@ static int pre_init = 1; /* Before first ordered IDE scan */
static LIST_HEAD(ide_pci_drivers);
/*
- * ide_register_pci_driver - attach IDE driver
+ * __ide_register_pci_driver - attach IDE driver
* @driver: pci driver
+ * @module: owner module of the driver
*
* Registers a driver with the IDE layer. The IDE layer arranges that
* boot time setup is done in the expected device order and then
@@ -801,15 +802,16 @@ static LIST_HEAD(ide_pci_drivers);
* Returns are the same as for pci_register_driver
*/
-int ide_pci_register_driver(struct pci_driver *driver)
+int __ide_pci_register_driver(struct pci_driver *driver, struct module *module)
{
if(!pre_init)
- return pci_module_init(driver);
+ return __pci_register_driver(driver, module);
+ driver->driver.owner = module;
list_add_tail(&driver->node, &ide_pci_drivers);
return 0;
}
-EXPORT_SYMBOL_GPL(ide_pci_register_driver);
+EXPORT_SYMBOL_GPL(__ide_pci_register_driver);
/**
* ide_unregister_pci_driver - unregister an IDE driver
@@ -897,6 +899,6 @@ void __init ide_scan_pcibus (int scan_direction)
{
list_del(l);
d = list_entry(l, struct pci_driver, node);
- pci_register_driver(d);
+ __pci_register_driver(d, d->driver.owner);
}
}
diff --git a/drivers/ieee1394/amdtp.c b/drivers/ieee1394/amdtp.c
index e8e28569a668..75897509c401 100644
--- a/drivers/ieee1394/amdtp.c
+++ b/drivers/ieee1394/amdtp.c
@@ -320,8 +320,7 @@ static void ohci1394_stop_it_ctx(struct ti_ohci *ohci, int ctx, int synchronous)
if ((control & OHCI1394_CONTEXT_ACTIVE) == 0)
break;
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(1);
+ schedule_timeout_interruptible(1);
}
}
}
diff --git a/drivers/ieee1394/dv1394.c b/drivers/ieee1394/dv1394.c
index e34730c7a874..cbbbe14b8849 100644
--- a/drivers/ieee1394/dv1394.c
+++ b/drivers/ieee1394/dv1394.c
@@ -2361,7 +2361,7 @@ static void dv1394_add_host (struct hpsb_host *host)
ohci = (struct ti_ohci *)host->hostdata;
- class_device_create(hpsb_protocol_class, MKDEV(
+ class_device_create(hpsb_protocol_class, NULL, MKDEV(
IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_DV1394 * 16 + (id<<2)),
NULL, "dv1394-%d", id);
devfs_mk_dir("ieee1394/dv/host%d", id);
diff --git a/drivers/ieee1394/eth1394.c b/drivers/ieee1394/eth1394.c
index 4802bbbb6dc9..c9e92d85c893 100644
--- a/drivers/ieee1394/eth1394.c
+++ b/drivers/ieee1394/eth1394.c
@@ -1630,7 +1630,7 @@ static void ether1394_complete_cb(void *__ptask)
/* Transmit a packet (called by kernel) */
static int ether1394_tx (struct sk_buff *skb, struct net_device *dev)
{
- int kmflags = in_interrupt() ? GFP_ATOMIC : GFP_KERNEL;
+ gfp_t kmflags = in_interrupt() ? GFP_ATOMIC : GFP_KERNEL;
struct eth1394hdr *eth;
struct eth1394_priv *priv = netdev_priv(dev);
int proto;
diff --git a/drivers/ieee1394/nodemgr.c b/drivers/ieee1394/nodemgr.c
index 347ece6b583c..7fff5a1d2ea4 100644
--- a/drivers/ieee1394/nodemgr.c
+++ b/drivers/ieee1394/nodemgr.c
@@ -1292,7 +1292,7 @@ static void nodemgr_suspend_ne(struct node_entry *ne)
if (ud->device.driver &&
(!ud->device.driver->suspend ||
- ud->device.driver->suspend(&ud->device, PMSG_SUSPEND, 0)))
+ ud->device.driver->suspend(&ud->device, PMSG_SUSPEND)))
device_release_driver(&ud->device);
}
up_write(&ne->device.bus->subsys.rwsem);
@@ -1315,7 +1315,7 @@ static void nodemgr_resume_ne(struct node_entry *ne)
continue;
if (ud->device.driver && ud->device.driver->resume)
- ud->device.driver->resume(&ud->device, 0);
+ ud->device.driver->resume(&ud->device);
}
up_read(&ne->device.bus->subsys.rwsem);
diff --git a/drivers/ieee1394/raw1394.c b/drivers/ieee1394/raw1394.c
index 0470f77a9cd1..24411e666b21 100644
--- a/drivers/ieee1394/raw1394.c
+++ b/drivers/ieee1394/raw1394.c
@@ -2912,7 +2912,7 @@ static int __init init_raw1394(void)
hpsb_register_highlevel(&raw1394_highlevel);
- if (IS_ERR(class_device_create(hpsb_protocol_class, MKDEV(
+ if (IS_ERR(class_device_create(hpsb_protocol_class, NULL, MKDEV(
IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_RAW1394 * 16),
NULL, RAW1394_DEVICE_NAME))) {
ret = -EFAULT;
diff --git a/drivers/ieee1394/video1394.c b/drivers/ieee1394/video1394.c
index 11be9c9c82a8..23911da50154 100644
--- a/drivers/ieee1394/video1394.c
+++ b/drivers/ieee1394/video1394.c
@@ -1370,7 +1370,7 @@ static void video1394_add_host (struct hpsb_host *host)
hpsb_set_hostinfo_key(&video1394_highlevel, host, ohci->host->id);
minor = IEEE1394_MINOR_BLOCK_VIDEO1394 * 16 + ohci->host->id;
- class_device_create(hpsb_protocol_class, MKDEV(
+ class_device_create(hpsb_protocol_class, NULL, MKDEV(
IEEE1394_MAJOR, minor),
NULL, "%s-%d", VIDEO1394_DRIVER_NAME, ohci->host->id);
devfs_mk_cdev(MKDEV(IEEE1394_MAJOR, minor),
diff --git a/drivers/infiniband/Kconfig b/drivers/infiniband/Kconfig
index 325d502e25cd..bdf0891a92dd 100644
--- a/drivers/infiniband/Kconfig
+++ b/drivers/infiniband/Kconfig
@@ -33,4 +33,6 @@ source "drivers/infiniband/hw/mthca/Kconfig"
source "drivers/infiniband/ulp/ipoib/Kconfig"
+source "drivers/infiniband/ulp/srp/Kconfig"
+
endmenu
diff --git a/drivers/infiniband/Makefile b/drivers/infiniband/Makefile
index d256cf798218..a43fb34cca94 100644
--- a/drivers/infiniband/Makefile
+++ b/drivers/infiniband/Makefile
@@ -1,3 +1,4 @@
obj-$(CONFIG_INFINIBAND) += core/
obj-$(CONFIG_INFINIBAND_MTHCA) += hw/mthca/
obj-$(CONFIG_INFINIBAND_IPOIB) += ulp/ipoib/
+obj-$(CONFIG_INFINIBAND_SRP) += ulp/srp/
diff --git a/drivers/infiniband/core/agent.c b/drivers/infiniband/core/agent.c
index 5ac86f566dc0..34b724afd28d 100644
--- a/drivers/infiniband/core/agent.c
+++ b/drivers/infiniband/core/agent.c
@@ -37,58 +37,44 @@
* $Id: agent.c 1389 2004-12-27 22:56:47Z roland $
*/
-#include <linux/dma-mapping.h>
+#include <linux/slab.h>
+#include <linux/string.h>
-#include <asm/bug.h>
+#include "agent.h"
+#include "smi.h"
-#include <rdma/ib_smi.h>
+#define SPFX "ib_agent: "
-#include "smi.h"
-#include "agent_priv.h"
-#include "mad_priv.h"
-#include "agent.h"
+struct ib_agent_port_private {
+ struct list_head port_list;
+ struct ib_mad_agent *agent[2];
+};
-spinlock_t ib_agent_port_list_lock;
+static DEFINE_SPINLOCK(ib_agent_port_list_lock);
static LIST_HEAD(ib_agent_port_list);
-/*
- * Caller must hold ib_agent_port_list_lock
- */
-static inline struct ib_agent_port_private *
-__ib_get_agent_port(struct ib_device *device, int port_num,
- struct ib_mad_agent *mad_agent)
+static struct ib_agent_port_private *
+__ib_get_agent_port(struct ib_device *device, int port_num)
{
struct ib_agent_port_private *entry;
- BUG_ON(!(!!device ^ !!mad_agent)); /* Exactly one MUST be (!NULL) */
-
- if (device) {
- list_for_each_entry(entry, &ib_agent_port_list, port_list) {
- if (entry->smp_agent->device == device &&
- entry->port_num == port_num)
- return entry;
- }
- } else {
- list_for_each_entry(entry, &ib_agent_port_list, port_list) {
- if ((entry->smp_agent == mad_agent) ||
- (entry->perf_mgmt_agent == mad_agent))
- return entry;
- }
+ list_for_each_entry(entry, &ib_agent_port_list, port_list) {
+ if (entry->agent[0]->device == device &&
+ entry->agent[0]->port_num == port_num)
+ return entry;
}
return NULL;
}
-static inline struct ib_agent_port_private *
-ib_get_agent_port(struct ib_device *device, int port_num,
- struct ib_mad_agent *mad_agent)
+static struct ib_agent_port_private *
+ib_get_agent_port(struct ib_device *device, int port_num)
{
struct ib_agent_port_private *entry;
unsigned long flags;
spin_lock_irqsave(&ib_agent_port_list_lock, flags);
- entry = __ib_get_agent_port(device, port_num, mad_agent);
+ entry = __ib_get_agent_port(device, port_num);
spin_unlock_irqrestore(&ib_agent_port_list_lock, flags);
-
return entry;
}
@@ -100,226 +86,102 @@ int smi_check_local_dr_smp(struct ib_smp *smp,
if (smp->mgmt_class != IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE)
return 1;
- port_priv = ib_get_agent_port(device, port_num, NULL);
+
+ port_priv = ib_get_agent_port(device, port_num);
if (!port_priv) {
printk(KERN_DEBUG SPFX "smi_check_local_dr_smp %s port %d "
- "not open\n",
- device->name, port_num);
+ "not open\n", device->name, port_num);
return 1;
}
- return smi_check_local_smp(port_priv->smp_agent, smp);
+ return smi_check_local_smp(port_priv->agent[0], smp);
}
-static int agent_mad_send(struct ib_mad_agent *mad_agent,
- struct ib_agent_port_private *port_priv,
- struct ib_mad_private *mad_priv,
- struct ib_grh *grh,
- struct ib_wc *wc)
+int agent_send_response(struct ib_mad *mad, struct ib_grh *grh,
+ struct ib_wc *wc, struct ib_device *device,
+ int port_num, int qpn)
{
- struct ib_agent_send_wr *agent_send_wr;
- struct ib_sge gather_list;
- struct ib_send_wr send_wr;
- struct ib_send_wr *bad_send_wr;
- struct ib_ah_attr ah_attr;
- unsigned long flags;
- int ret = 1;
-
- agent_send_wr = kmalloc(sizeof(*agent_send_wr), GFP_KERNEL);
- if (!agent_send_wr)
- goto out;
- agent_send_wr->mad = mad_priv;
-
- gather_list.addr = dma_map_single(mad_agent->device->dma_device,
- &mad_priv->mad,
- sizeof(mad_priv->mad),
- DMA_TO_DEVICE);
- gather_list.length = sizeof(mad_priv->mad);
- gather_list.lkey = mad_agent->mr->lkey;
-
- send_wr.next = NULL;
- send_wr.opcode = IB_WR_SEND;
- send_wr.sg_list = &gather_list;
- send_wr.num_sge = 1;
- send_wr.wr.ud.remote_qpn = wc->src_qp; /* DQPN */
- send_wr.wr.ud.timeout_ms = 0;
- send_wr.send_flags = IB_SEND_SIGNALED | IB_SEND_SOLICITED;
+ struct ib_agent_port_private *port_priv;
+ struct ib_mad_agent *agent;
+ struct ib_mad_send_buf *send_buf;
+ struct ib_ah *ah;
+ int ret;
- ah_attr.dlid = wc->slid;
- ah_attr.port_num = mad_agent->port_num;
- ah_attr.src_path_bits = wc->dlid_path_bits;
- ah_attr.sl = wc->sl;
- ah_attr.static_rate = 0;
- ah_attr.ah_flags = 0; /* No GRH */
- if (mad_priv->mad.mad.mad_hdr.mgmt_class == IB_MGMT_CLASS_PERF_MGMT) {
- if (wc->wc_flags & IB_WC_GRH) {
- ah_attr.ah_flags = IB_AH_GRH;
- /* Should sgid be looked up ? */
- ah_attr.grh.sgid_index = 0;
- ah_attr.grh.hop_limit = grh->hop_limit;
- ah_attr.grh.flow_label = be32_to_cpu(
- grh->version_tclass_flow) & 0xfffff;
- ah_attr.grh.traffic_class = (be32_to_cpu(
- grh->version_tclass_flow) >> 20) & 0xff;
- memcpy(ah_attr.grh.dgid.raw,
- grh->sgid.raw,
- sizeof(ah_attr.grh.dgid));
- }
+ port_priv = ib_get_agent_port(device, port_num);
+ if (!port_priv) {
+ printk(KERN_ERR SPFX "Unable to find port agent\n");
+ return -ENODEV;
}
- agent_send_wr->ah = ib_create_ah(mad_agent->qp->pd, &ah_attr);
- if (IS_ERR(agent_send_wr->ah)) {
- printk(KERN_ERR SPFX "No memory for address handle\n");
- kfree(agent_send_wr);
- goto out;
+ agent = port_priv->agent[qpn];
+ ah = ib_create_ah_from_wc(agent->qp->pd, wc, grh, port_num);
+ if (IS_ERR(ah)) {
+ ret = PTR_ERR(ah);
+ printk(KERN_ERR SPFX "ib_create_ah_from_wc error:%d\n", ret);
+ return ret;
}
- send_wr.wr.ud.ah = agent_send_wr->ah;
- if (mad_priv->mad.mad.mad_hdr.mgmt_class == IB_MGMT_CLASS_PERF_MGMT) {
- send_wr.wr.ud.pkey_index = wc->pkey_index;
- send_wr.wr.ud.remote_qkey = IB_QP1_QKEY;
- } else { /* for SMPs */
- send_wr.wr.ud.pkey_index = 0;
- send_wr.wr.ud.remote_qkey = 0;
+ send_buf = ib_create_send_mad(agent, wc->src_qp, wc->pkey_index, 0,
+ IB_MGMT_MAD_HDR, IB_MGMT_MAD_DATA,
+ GFP_KERNEL);
+ if (IS_ERR(send_buf)) {
+ ret = PTR_ERR(send_buf);
+ printk(KERN_ERR SPFX "ib_create_send_mad error:%d\n", ret);
+ goto err1;
}
- send_wr.wr.ud.mad_hdr = &mad_priv->mad.mad.mad_hdr;
- send_wr.wr_id = (unsigned long)agent_send_wr;
-
- pci_unmap_addr_set(agent_send_wr, mapping, gather_list.addr);
- /* Send */
- spin_lock_irqsave(&port_priv->send_list_lock, flags);
- if (ib_post_send_mad(mad_agent, &send_wr, &bad_send_wr)) {
- spin_unlock_irqrestore(&port_priv->send_list_lock, flags);
- dma_unmap_single(mad_agent->device->dma_device,
- pci_unmap_addr(agent_send_wr, mapping),
- sizeof(mad_priv->mad),
- DMA_TO_DEVICE);
- ib_destroy_ah(agent_send_wr->ah);
- kfree(agent_send_wr);
- } else {
- list_add_tail(&agent_send_wr->send_list,
- &port_priv->send_posted_list);
- spin_unlock_irqrestore(&port_priv->send_list_lock, flags);
- ret = 0;
+ memcpy(send_buf->mad, mad, sizeof *mad);
+ send_buf->ah = ah;
+ if ((ret = ib_post_send_mad(send_buf, NULL))) {
+ printk(KERN_ERR SPFX "ib_post_send_mad error:%d\n", ret);
+ goto err2;
}
-
-out:
+ return 0;
+err2:
+ ib_free_send_mad(send_buf);
+err1:
+ ib_destroy_ah(ah);
return ret;
}
-int agent_send(struct ib_mad_private *mad,
- struct ib_grh *grh,
- struct ib_wc *wc,
- struct ib_device *device,
- int port_num)
-{
- struct ib_agent_port_private *port_priv;
- struct ib_mad_agent *mad_agent;
-
- port_priv = ib_get_agent_port(device, port_num, NULL);
- if (!port_priv) {
- printk(KERN_DEBUG SPFX "agent_send %s port %d not open\n",
- device->name, port_num);
- return 1;
- }
-
- /* Get mad agent based on mgmt_class in MAD */
- switch (mad->mad.mad.mad_hdr.mgmt_class) {
- case IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE:
- case IB_MGMT_CLASS_SUBN_LID_ROUTED:
- mad_agent = port_priv->smp_agent;
- break;
- case IB_MGMT_CLASS_PERF_MGMT:
- mad_agent = port_priv->perf_mgmt_agent;
- break;
- default:
- return 1;
- }
-
- return agent_mad_send(mad_agent, port_priv, mad, grh, wc);
-}
-
static void agent_send_handler(struct ib_mad_agent *mad_agent,
struct ib_mad_send_wc *mad_send_wc)
{
- struct ib_agent_port_private *port_priv;
- struct ib_agent_send_wr *agent_send_wr;
- unsigned long flags;
-
- /* Find matching MAD agent */
- port_priv = ib_get_agent_port(NULL, 0, mad_agent);
- if (!port_priv) {
- printk(KERN_ERR SPFX "agent_send_handler: no matching MAD "
- "agent %p\n", mad_agent);
- return;
- }
-
- agent_send_wr = (struct ib_agent_send_wr *)(unsigned long)mad_send_wc->wr_id;
- spin_lock_irqsave(&port_priv->send_list_lock, flags);
- /* Remove completed send from posted send MAD list */
- list_del(&agent_send_wr->send_list);
- spin_unlock_irqrestore(&port_priv->send_list_lock, flags);
-
- dma_unmap_single(mad_agent->device->dma_device,
- pci_unmap_addr(agent_send_wr, mapping),
- sizeof(agent_send_wr->mad->mad),
- DMA_TO_DEVICE);
-
- ib_destroy_ah(agent_send_wr->ah);
-
- /* Release allocated memory */
- kmem_cache_free(ib_mad_cache, agent_send_wr->mad);
- kfree(agent_send_wr);
+ ib_destroy_ah(mad_send_wc->send_buf->ah);
+ ib_free_send_mad(mad_send_wc->send_buf);
}
int ib_agent_port_open(struct ib_device *device, int port_num)
{
- int ret;
struct ib_agent_port_private *port_priv;
unsigned long flags;
-
- /* First, check if port already open for SMI */
- port_priv = ib_get_agent_port(device, port_num, NULL);
- if (port_priv) {
- printk(KERN_DEBUG SPFX "%s port %d already open\n",
- device->name, port_num);
- return 0;
- }
+ int ret;
/* Create new device info */
- port_priv = kmalloc(sizeof *port_priv, GFP_KERNEL);
+ port_priv = kzalloc(sizeof *port_priv, GFP_KERNEL);
if (!port_priv) {
printk(KERN_ERR SPFX "No memory for ib_agent_port_private\n");
ret = -ENOMEM;
goto error1;
}
- memset(port_priv, 0, sizeof *port_priv);
- port_priv->port_num = port_num;
- spin_lock_init(&port_priv->send_list_lock);
- INIT_LIST_HEAD(&port_priv->send_posted_list);
-
- /* Obtain send only MAD agent for SM class (SMI QP) */
- port_priv->smp_agent = ib_register_mad_agent(device, port_num,
- IB_QPT_SMI,
- NULL, 0,
+ /* Obtain send only MAD agent for SMI QP */
+ port_priv->agent[0] = ib_register_mad_agent(device, port_num,
+ IB_QPT_SMI, NULL, 0,
&agent_send_handler,
- NULL, NULL);
-
- if (IS_ERR(port_priv->smp_agent)) {
- ret = PTR_ERR(port_priv->smp_agent);
+ NULL, NULL);
+ if (IS_ERR(port_priv->agent[0])) {
+ ret = PTR_ERR(port_priv->agent[0]);
goto error2;
}
- /* Obtain send only MAD agent for PerfMgmt class (GSI QP) */
- port_priv->perf_mgmt_agent = ib_register_mad_agent(device, port_num,
- IB_QPT_GSI,
- NULL, 0,
- &agent_send_handler,
- NULL, NULL);
- if (IS_ERR(port_priv->perf_mgmt_agent)) {
- ret = PTR_ERR(port_priv->perf_mgmt_agent);
+ /* Obtain send only MAD agent for GSI QP */
+ port_priv->agent[1] = ib_register_mad_agent(device, port_num,
+ IB_QPT_GSI, NULL, 0,
+ &agent_send_handler,
+ NULL, NULL);
+ if (IS_ERR(port_priv->agent[1])) {
+ ret = PTR_ERR(port_priv->agent[1]);
goto error3;
}
@@ -330,7 +192,7 @@ int ib_agent_port_open(struct ib_device *device, int port_num)
return 0;
error3:
- ib_unregister_mad_agent(port_priv->smp_agent);
+ ib_unregister_mad_agent(port_priv->agent[0]);
error2:
kfree(port_priv);
error1:
@@ -343,7 +205,7 @@ int ib_agent_port_close(struct ib_device *device, int port_num)
unsigned long flags;
spin_lock_irqsave(&ib_agent_port_list_lock, flags);
- port_priv = __ib_get_agent_port(device, port_num, NULL);
+ port_priv = __ib_get_agent_port(device, port_num);
if (port_priv == NULL) {
spin_unlock_irqrestore(&ib_agent_port_list_lock, flags);
printk(KERN_ERR SPFX "Port %d not found\n", port_num);
@@ -352,9 +214,8 @@ int ib_agent_port_close(struct ib_device *device, int port_num)
list_del(&port_priv->port_list);
spin_unlock_irqrestore(&ib_agent_port_list_lock, flags);
- ib_unregister_mad_agent(port_priv->perf_mgmt_agent);
- ib_unregister_mad_agent(port_priv->smp_agent);
+ ib_unregister_mad_agent(port_priv->agent[1]);
+ ib_unregister_mad_agent(port_priv->agent[0]);
kfree(port_priv);
-
return 0;
}
diff --git a/drivers/infiniband/core/agent.h b/drivers/infiniband/core/agent.h
index d9426842254a..86d72fab37b0 100644
--- a/drivers/infiniband/core/agent.h
+++ b/drivers/infiniband/core/agent.h
@@ -39,17 +39,15 @@
#ifndef __AGENT_H_
#define __AGENT_H_
-extern spinlock_t ib_agent_port_list_lock;
+#include <linux/err.h>
+#include <rdma/ib_mad.h>
-extern int ib_agent_port_open(struct ib_device *device,
- int port_num);
+extern int ib_agent_port_open(struct ib_device *device, int port_num);
extern int ib_agent_port_close(struct ib_device *device, int port_num);
-extern int agent_send(struct ib_mad_private *mad,
- struct ib_grh *grh,
- struct ib_wc *wc,
- struct ib_device *device,
- int port_num);
+extern int agent_send_response(struct ib_mad *mad, struct ib_grh *grh,
+ struct ib_wc *wc, struct ib_device *device,
+ int port_num, int qpn);
#endif /* __AGENT_H_ */
diff --git a/drivers/infiniband/core/agent_priv.h b/drivers/infiniband/core/agent_priv.h
deleted file mode 100644
index 2ec6d7f1b7d0..000000000000
--- a/drivers/infiniband/core/agent_priv.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (c) 2004, 2005 Mellanox Technologies Ltd. All rights reserved.
- * Copyright (c) 2004, 2005 Infinicon Corporation. All rights reserved.
- * Copyright (c) 2004, 2005 Intel Corporation. All rights reserved.
- * Copyright (c) 2004, 2005 Topspin Corporation. All rights reserved.
- * Copyright (c) 2004, 2005 Voltaire Corporation. All rights reserved.
- *
- * This software is available to you under a choice of one of two
- * licenses. You may choose to be licensed under the terms of the GNU
- * General Public License (GPL) Version 2, available from the file
- * COPYING in the main directory of this source tree, or the
- * OpenIB.org BSD license below:
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- *
- * 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.
- *
- * $Id: agent_priv.h 1640 2005-01-24 22:39:02Z halr $
- */
-
-#ifndef __IB_AGENT_PRIV_H__
-#define __IB_AGENT_PRIV_H__
-
-#include <linux/pci.h>
-
-#define SPFX "ib_agent: "
-
-struct ib_agent_send_wr {
- struct list_head send_list;
- struct ib_ah *ah;
- struct ib_mad_private *mad;
- DECLARE_PCI_UNMAP_ADDR(mapping)
-};
-
-struct ib_agent_port_private {
- struct list_head port_list;
- struct list_head send_posted_list;
- spinlock_t send_list_lock;
- int port_num;
- struct ib_mad_agent *smp_agent; /* SM class */
- struct ib_mad_agent *perf_mgmt_agent; /* PerfMgmt class */
-};
-
-#endif /* __IB_AGENT_PRIV_H__ */
diff --git a/drivers/infiniband/core/cache.c b/drivers/infiniband/core/cache.c
index f014e639088c..c57a3871184c 100644
--- a/drivers/infiniband/core/cache.c
+++ b/drivers/infiniband/core/cache.c
@@ -38,6 +38,7 @@
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/slab.h>
+#include <linux/sched.h> /* INIT_WORK, schedule_work(), flush_scheduled_work() */
#include <rdma/ib_cache.h>
diff --git a/drivers/infiniband/core/cm.c b/drivers/infiniband/core/cm.c
index 54db6d4831f1..02110e00d145 100644
--- a/drivers/infiniband/core/cm.c
+++ b/drivers/infiniband/core/cm.c
@@ -135,6 +135,7 @@ struct cm_id_private {
__be64 tid;
__be32 local_qpn;
__be32 remote_qpn;
+ enum ib_qp_type qp_type;
__be32 sq_psn;
__be32 rq_psn;
int timeout_ms;
@@ -175,8 +176,7 @@ static int cm_alloc_msg(struct cm_id_private *cm_id_priv,
m = ib_create_send_mad(mad_agent, cm_id_priv->id.remote_cm_qpn,
cm_id_priv->av.pkey_index,
- ah, 0, sizeof(struct ib_mad_hdr),
- sizeof(struct ib_mad)-sizeof(struct ib_mad_hdr),
+ 0, IB_MGMT_MAD_HDR, IB_MGMT_MAD_DATA,
GFP_ATOMIC);
if (IS_ERR(m)) {
ib_destroy_ah(ah);
@@ -184,7 +184,8 @@ static int cm_alloc_msg(struct cm_id_private *cm_id_priv,
}
/* Timeout set by caller if response is expected. */
- m->send_wr.wr.ud.retries = cm_id_priv->max_cm_retries;
+ m->ah = ah;
+ m->retries = cm_id_priv->max_cm_retries;
atomic_inc(&cm_id_priv->refcount);
m->context[0] = cm_id_priv;
@@ -205,20 +206,20 @@ static int cm_alloc_response_msg(struct cm_port *port,
return PTR_ERR(ah);
m = ib_create_send_mad(port->mad_agent, 1, mad_recv_wc->wc->pkey_index,
- ah, 0, sizeof(struct ib_mad_hdr),
- sizeof(struct ib_mad)-sizeof(struct ib_mad_hdr),
+ 0, IB_MGMT_MAD_HDR, IB_MGMT_MAD_DATA,
GFP_ATOMIC);
if (IS_ERR(m)) {
ib_destroy_ah(ah);
return PTR_ERR(m);
}
+ m->ah = ah;
*msg = m;
return 0;
}
static void cm_free_msg(struct ib_mad_send_buf *msg)
{
- ib_destroy_ah(msg->send_wr.wr.ud.ah);
+ ib_destroy_ah(msg->ah);
if (msg->context[0])
cm_deref_id(msg->context[0]);
ib_free_send_mad(msg);
@@ -366,9 +367,15 @@ static struct cm_id_private * cm_insert_listen(struct cm_id_private *cm_id_priv)
cur_cm_id_priv = rb_entry(parent, struct cm_id_private,
service_node);
if ((cur_cm_id_priv->id.service_mask & service_id) ==
- (service_mask & cur_cm_id_priv->id.service_id))
- return cm_id_priv;
- if (service_id < cur_cm_id_priv->id.service_id)
+ (service_mask & cur_cm_id_priv->id.service_id) &&
+ (cm_id_priv->id.device == cur_cm_id_priv->id.device))
+ return cur_cm_id_priv;
+
+ if (cm_id_priv->id.device < cur_cm_id_priv->id.device)
+ link = &(*link)->rb_left;
+ else if (cm_id_priv->id.device > cur_cm_id_priv->id.device)
+ link = &(*link)->rb_right;
+ else if (service_id < cur_cm_id_priv->id.service_id)
link = &(*link)->rb_left;
else
link = &(*link)->rb_right;
@@ -378,7 +385,8 @@ static struct cm_id_private * cm_insert_listen(struct cm_id_private *cm_id_priv)
return NULL;
}
-static struct cm_id_private * cm_find_listen(__be64 service_id)
+static struct cm_id_private * cm_find_listen(struct ib_device *device,
+ __be64 service_id)
{
struct rb_node *node = cm.listen_service_table.rb_node;
struct cm_id_private *cm_id_priv;
@@ -386,9 +394,15 @@ static struct cm_id_private * cm_find_listen(__be64 service_id)
while (node) {
cm_id_priv = rb_entry(node, struct cm_id_private, service_node);
if ((cm_id_priv->id.service_mask & service_id) ==
- (cm_id_priv->id.service_mask & cm_id_priv->id.service_id))
+ cm_id_priv->id.service_id &&
+ (cm_id_priv->id.device == device))
return cm_id_priv;
- if (service_id < cm_id_priv->id.service_id)
+
+ if (device < cm_id_priv->id.device)
+ node = node->rb_left;
+ else if (device > cm_id_priv->id.device)
+ node = node->rb_right;
+ else if (service_id < cm_id_priv->id.service_id)
node = node->rb_left;
else
node = node->rb_right;
@@ -523,18 +537,19 @@ static void cm_reject_sidr_req(struct cm_id_private *cm_id_priv,
ib_send_cm_sidr_rep(&cm_id_priv->id, &param);
}
-struct ib_cm_id *ib_create_cm_id(ib_cm_handler cm_handler,
+struct ib_cm_id *ib_create_cm_id(struct ib_device *device,
+ ib_cm_handler cm_handler,
void *context)
{
struct cm_id_private *cm_id_priv;
int ret;
- cm_id_priv = kmalloc(sizeof *cm_id_priv, GFP_KERNEL);
+ cm_id_priv = kzalloc(sizeof *cm_id_priv, GFP_KERNEL);
if (!cm_id_priv)
return ERR_PTR(-ENOMEM);
- memset(cm_id_priv, 0, sizeof *cm_id_priv);
cm_id_priv->id.state = IB_CM_IDLE;
+ cm_id_priv->id.device = device;
cm_id_priv->id.cm_handler = cm_handler;
cm_id_priv->id.context = context;
cm_id_priv->id.remote_cm_qpn = 1;
@@ -605,10 +620,9 @@ static struct cm_timewait_info * cm_create_timewait_info(__be32 local_id)
{
struct cm_timewait_info *timewait_info;
- timewait_info = kmalloc(sizeof *timewait_info, GFP_KERNEL);
+ timewait_info = kzalloc(sizeof *timewait_info, GFP_KERNEL);
if (!timewait_info)
return ERR_PTR(-ENOMEM);
- memset(timewait_info, 0, sizeof *timewait_info);
timewait_info->work.local_id = local_id;
INIT_WORK(&timewait_info->work.work, cm_work_handler,
@@ -662,8 +676,7 @@ retest:
break;
case IB_CM_SIDR_REQ_SENT:
cm_id->state = IB_CM_IDLE;
- ib_cancel_mad(cm_id_priv->av.port->mad_agent,
- (unsigned long) cm_id_priv->msg);
+ ib_cancel_mad(cm_id_priv->av.port->mad_agent, cm_id_priv->msg);
spin_unlock_irqrestore(&cm_id_priv->lock, flags);
break;
case IB_CM_SIDR_REQ_RCVD:
@@ -674,8 +687,7 @@ retest:
case IB_CM_MRA_REQ_RCVD:
case IB_CM_REP_SENT:
case IB_CM_MRA_REP_RCVD:
- ib_cancel_mad(cm_id_priv->av.port->mad_agent,
- (unsigned long) cm_id_priv->msg);
+ ib_cancel_mad(cm_id_priv->av.port->mad_agent, cm_id_priv->msg);
/* Fall through */
case IB_CM_REQ_RCVD:
case IB_CM_MRA_REQ_SENT:
@@ -692,8 +704,7 @@ retest:
ib_send_cm_dreq(cm_id, NULL, 0);
goto retest;
case IB_CM_DREQ_SENT:
- ib_cancel_mad(cm_id_priv->av.port->mad_agent,
- (unsigned long) cm_id_priv->msg);
+ ib_cancel_mad(cm_id_priv->av.port->mad_agent, cm_id_priv->msg);
cm_enter_timewait(cm_id_priv);
spin_unlock_irqrestore(&cm_id_priv->lock, flags);
break;
@@ -867,7 +878,6 @@ int ib_send_cm_req(struct ib_cm_id *cm_id,
struct ib_cm_req_param *param)
{
struct cm_id_private *cm_id_priv;
- struct ib_send_wr *bad_send_wr;
struct cm_req_msg *req_msg;
unsigned long flags;
int ret;
@@ -911,6 +921,7 @@ int ib_send_cm_req(struct ib_cm_id *cm_id,
cm_id_priv->responder_resources = param->responder_resources;
cm_id_priv->retry_count = param->retry_count;
cm_id_priv->path_mtu = param->primary_path->mtu;
+ cm_id_priv->qp_type = param->qp_type;
ret = cm_alloc_msg(cm_id_priv, &cm_id_priv->msg);
if (ret)
@@ -919,7 +930,7 @@ int ib_send_cm_req(struct ib_cm_id *cm_id,
req_msg = (struct cm_req_msg *) cm_id_priv->msg->mad;
cm_format_req(req_msg, cm_id_priv, param);
cm_id_priv->tid = req_msg->hdr.tid;
- cm_id_priv->msg->send_wr.wr.ud.timeout_ms = cm_id_priv->timeout_ms;
+ cm_id_priv->msg->timeout_ms = cm_id_priv->timeout_ms;
cm_id_priv->msg->context[1] = (void *) (unsigned long) IB_CM_REQ_SENT;
cm_id_priv->local_qpn = cm_req_get_local_qpn(req_msg);
@@ -928,8 +939,7 @@ int ib_send_cm_req(struct ib_cm_id *cm_id,
cm_req_get_primary_local_ack_timeout(req_msg);
spin_lock_irqsave(&cm_id_priv->lock, flags);
- ret = ib_post_send_mad(cm_id_priv->av.port->mad_agent,
- &cm_id_priv->msg->send_wr, &bad_send_wr);
+ ret = ib_post_send_mad(cm_id_priv->msg, NULL);
if (ret) {
spin_unlock_irqrestore(&cm_id_priv->lock, flags);
goto error2;
@@ -952,7 +962,6 @@ static int cm_issue_rej(struct cm_port *port,
void *ari, u8 ari_length)
{
struct ib_mad_send_buf *msg = NULL;
- struct ib_send_wr *bad_send_wr;
struct cm_rej_msg *rej_msg, *rcv_msg;
int ret;
@@ -975,7 +984,7 @@ static int cm_issue_rej(struct cm_port *port,
memcpy(rej_msg->ari, ari, ari_length);
}
- ret = ib_post_send_mad(port->mad_agent, &msg->send_wr, &bad_send_wr);
+ ret = ib_post_send_mad(msg, NULL);
if (ret)
cm_free_msg(msg);
@@ -1047,7 +1056,6 @@ static void cm_format_req_event(struct cm_work *work,
req_msg = (struct cm_req_msg *)work->mad_recv_wc->recv_buf.mad;
param = &work->cm_event.param.req_rcvd;
param->listen_id = listen_id;
- param->device = cm_id_priv->av.port->mad_agent->device;
param->port = cm_id_priv->av.port->port_num;
param->primary_path = &work->path[0];
if (req_msg->alt_local_lid)
@@ -1156,7 +1164,6 @@ static void cm_dup_req_handler(struct cm_work *work,
struct cm_id_private *cm_id_priv)
{
struct ib_mad_send_buf *msg = NULL;
- struct ib_send_wr *bad_send_wr;
unsigned long flags;
int ret;
@@ -1185,8 +1192,7 @@ static void cm_dup_req_handler(struct cm_work *work,
}
spin_unlock_irqrestore(&cm_id_priv->lock, flags);
- ret = ib_post_send_mad(cm_id_priv->av.port->mad_agent, &msg->send_wr,
- &bad_send_wr);
+ ret = ib_post_send_mad(msg, NULL);
if (ret)
goto free;
return;
@@ -1226,7 +1232,8 @@ static struct cm_id_private * cm_match_req(struct cm_work *work,
}
/* Find matching listen request. */
- listen_cm_id_priv = cm_find_listen(req_msg->service_id);
+ listen_cm_id_priv = cm_find_listen(cm_id_priv->id.device,
+ req_msg->service_id);
if (!listen_cm_id_priv) {
spin_unlock_irqrestore(&cm.lock, flags);
cm_issue_rej(work->port, work->mad_recv_wc,
@@ -1254,7 +1261,7 @@ static int cm_req_handler(struct cm_work *work)
req_msg = (struct cm_req_msg *)work->mad_recv_wc->recv_buf.mad;
- cm_id = ib_create_cm_id(NULL, NULL);
+ cm_id = ib_create_cm_id(work->port->cm_dev->device, NULL, NULL);
if (IS_ERR(cm_id))
return PTR_ERR(cm_id);
@@ -1305,6 +1312,7 @@ static int cm_req_handler(struct cm_work *work)
cm_req_get_primary_local_ack_timeout(req_msg);
cm_id_priv->retry_count = cm_req_get_retry_count(req_msg);
cm_id_priv->rnr_retry_count = cm_req_get_rnr_retry_count(req_msg);
+ cm_id_priv->qp_type = cm_req_get_qp_type(req_msg);
cm_format_req_event(work, cm_id_priv, &listen_cm_id_priv->id);
cm_process_work(cm_id_priv, work);
@@ -1349,7 +1357,6 @@ int ib_send_cm_rep(struct ib_cm_id *cm_id,
struct cm_id_private *cm_id_priv;
struct ib_mad_send_buf *msg;
struct cm_rep_msg *rep_msg;
- struct ib_send_wr *bad_send_wr;
unsigned long flags;
int ret;
@@ -1371,11 +1378,10 @@ int ib_send_cm_rep(struct ib_cm_id *cm_id,
rep_msg = (struct cm_rep_msg *) msg->mad;
cm_format_rep(rep_msg, cm_id_priv, param);
- msg->send_wr.wr.ud.timeout_ms = cm_id_priv->timeout_ms;
+ msg->timeout_ms = cm_id_priv->timeout_ms;
msg->context[1] = (void *) (unsigned long) IB_CM_REP_SENT;
- ret = ib_post_send_mad(cm_id_priv->av.port->mad_agent,
- &msg->send_wr, &bad_send_wr);
+ ret = ib_post_send_mad(msg, NULL);
if (ret) {
spin_unlock_irqrestore(&cm_id_priv->lock, flags);
cm_free_msg(msg);
@@ -1413,7 +1419,6 @@ int ib_send_cm_rtu(struct ib_cm_id *cm_id,
{
struct cm_id_private *cm_id_priv;
struct ib_mad_send_buf *msg;
- struct ib_send_wr *bad_send_wr;
unsigned long flags;
void *data;
int ret;
@@ -1440,8 +1445,7 @@ int ib_send_cm_rtu(struct ib_cm_id *cm_id,
cm_format_rtu((struct cm_rtu_msg *) msg->mad, cm_id_priv,
private_data, private_data_len);
- ret = ib_post_send_mad(cm_id_priv->av.port->mad_agent,
- &msg->send_wr, &bad_send_wr);
+ ret = ib_post_send_mad(msg, NULL);
if (ret) {
spin_unlock_irqrestore(&cm_id_priv->lock, flags);
cm_free_msg(msg);
@@ -1486,7 +1490,6 @@ static void cm_dup_rep_handler(struct cm_work *work)
struct cm_id_private *cm_id_priv;
struct cm_rep_msg *rep_msg;
struct ib_mad_send_buf *msg = NULL;
- struct ib_send_wr *bad_send_wr;
unsigned long flags;
int ret;
@@ -1514,8 +1517,7 @@ static void cm_dup_rep_handler(struct cm_work *work)
goto unlock;
spin_unlock_irqrestore(&cm_id_priv->lock, flags);
- ret = ib_post_send_mad(cm_id_priv->av.port->mad_agent, &msg->send_wr,
- &bad_send_wr);
+ ret = ib_post_send_mad(msg, NULL);
if (ret)
goto free;
goto deref;
@@ -1583,8 +1585,7 @@ static int cm_rep_handler(struct cm_work *work)
/* todo: handle peer_to_peer */
- ib_cancel_mad(cm_id_priv->av.port->mad_agent,
- (unsigned long) cm_id_priv->msg);
+ ib_cancel_mad(cm_id_priv->av.port->mad_agent, cm_id_priv->msg);
ret = atomic_inc_and_test(&cm_id_priv->work_count);
if (!ret)
list_add_tail(&work->list, &cm_id_priv->work_list);
@@ -1618,8 +1619,7 @@ static int cm_establish_handler(struct cm_work *work)
goto out;
}
- ib_cancel_mad(cm_id_priv->av.port->mad_agent,
- (unsigned long) cm_id_priv->msg);
+ ib_cancel_mad(cm_id_priv->av.port->mad_agent, cm_id_priv->msg);
ret = atomic_inc_and_test(&cm_id_priv->work_count);
if (!ret)
list_add_tail(&work->list, &cm_id_priv->work_list);
@@ -1658,8 +1658,7 @@ static int cm_rtu_handler(struct cm_work *work)
}
cm_id_priv->id.state = IB_CM_ESTABLISHED;
- ib_cancel_mad(cm_id_priv->av.port->mad_agent,
- (unsigned long) cm_id_priv->msg);
+ ib_cancel_mad(cm_id_priv->av.port->mad_agent, cm_id_priv->msg);
ret = atomic_inc_and_test(&cm_id_priv->work_count);
if (!ret)
list_add_tail(&work->list, &cm_id_priv->work_list);
@@ -1696,7 +1695,6 @@ int ib_send_cm_dreq(struct ib_cm_id *cm_id,
{
struct cm_id_private *cm_id_priv;
struct ib_mad_send_buf *msg;
- struct ib_send_wr *bad_send_wr;
unsigned long flags;
int ret;
@@ -1718,11 +1716,10 @@ int ib_send_cm_dreq(struct ib_cm_id *cm_id,
cm_format_dreq((struct cm_dreq_msg *) msg->mad, cm_id_priv,
private_data, private_data_len);
- msg->send_wr.wr.ud.timeout_ms = cm_id_priv->timeout_ms;
+ msg->timeout_ms = cm_id_priv->timeout_ms;
msg->context[1] = (void *) (unsigned long) IB_CM_DREQ_SENT;
- ret = ib_post_send_mad(cm_id_priv->av.port->mad_agent,
- &msg->send_wr, &bad_send_wr);
+ ret = ib_post_send_mad(msg, NULL);
if (ret) {
cm_enter_timewait(cm_id_priv);
spin_unlock_irqrestore(&cm_id_priv->lock, flags);
@@ -1756,7 +1753,6 @@ int ib_send_cm_drep(struct ib_cm_id *cm_id,
{
struct cm_id_private *cm_id_priv;
struct ib_mad_send_buf *msg;
- struct ib_send_wr *bad_send_wr;
unsigned long flags;
void *data;
int ret;
@@ -1786,8 +1782,7 @@ int ib_send_cm_drep(struct ib_cm_id *cm_id,
cm_format_drep((struct cm_drep_msg *) msg->mad, cm_id_priv,
private_data, private_data_len);
- ret = ib_post_send_mad(cm_id_priv->av.port->mad_agent, &msg->send_wr,
- &bad_send_wr);
+ ret = ib_post_send_mad(msg, NULL);
if (ret) {
spin_unlock_irqrestore(&cm_id_priv->lock, flags);
cm_free_msg(msg);
@@ -1804,7 +1799,6 @@ static int cm_dreq_handler(struct cm_work *work)
struct cm_id_private *cm_id_priv;
struct cm_dreq_msg *dreq_msg;
struct ib_mad_send_buf *msg = NULL;
- struct ib_send_wr *bad_send_wr;
unsigned long flags;
int ret;
@@ -1823,8 +1817,7 @@ static int cm_dreq_handler(struct cm_work *work)
switch (cm_id_priv->id.state) {
case IB_CM_REP_SENT:
case IB_CM_DREQ_SENT:
- ib_cancel_mad(cm_id_priv->av.port->mad_agent,
- (unsigned long) cm_id_priv->msg);
+ ib_cancel_mad(cm_id_priv->av.port->mad_agent, cm_id_priv->msg);
break;
case IB_CM_ESTABLISHED:
case IB_CM_MRA_REP_RCVD:
@@ -1838,8 +1831,7 @@ static int cm_dreq_handler(struct cm_work *work)
cm_id_priv->private_data_len);
spin_unlock_irqrestore(&cm_id_priv->lock, flags);
- if (ib_post_send_mad(cm_id_priv->av.port->mad_agent,
- &msg->send_wr, &bad_send_wr))
+ if (ib_post_send_mad(msg, NULL))
cm_free_msg(msg);
goto deref;
default:
@@ -1886,8 +1878,7 @@ static int cm_drep_handler(struct cm_work *work)
}
cm_enter_timewait(cm_id_priv);
- ib_cancel_mad(cm_id_priv->av.port->mad_agent,
- (unsigned long) cm_id_priv->msg);
+ ib_cancel_mad(cm_id_priv->av.port->mad_agent, cm_id_priv->msg);
ret = atomic_inc_and_test(&cm_id_priv->work_count);
if (!ret)
list_add_tail(&work->list, &cm_id_priv->work_list);
@@ -1912,7 +1903,6 @@ int ib_send_cm_rej(struct ib_cm_id *cm_id,
{
struct cm_id_private *cm_id_priv;
struct ib_mad_send_buf *msg;
- struct ib_send_wr *bad_send_wr;
unsigned long flags;
int ret;
@@ -1956,8 +1946,7 @@ int ib_send_cm_rej(struct ib_cm_id *cm_id,
if (ret)
goto out;
- ret = ib_post_send_mad(cm_id_priv->av.port->mad_agent,
- &msg->send_wr, &bad_send_wr);
+ ret = ib_post_send_mad(msg, NULL);
if (ret)
cm_free_msg(msg);
@@ -2033,8 +2022,7 @@ static int cm_rej_handler(struct cm_work *work)
case IB_CM_MRA_REQ_RCVD:
case IB_CM_REP_SENT:
case IB_CM_MRA_REP_RCVD:
- ib_cancel_mad(cm_id_priv->av.port->mad_agent,
- (unsigned long) cm_id_priv->msg);
+ ib_cancel_mad(cm_id_priv->av.port->mad_agent, cm_id_priv->msg);
/* fall through */
case IB_CM_REQ_RCVD:
case IB_CM_MRA_REQ_SENT:
@@ -2044,8 +2032,7 @@ static int cm_rej_handler(struct cm_work *work)
cm_reset_to_idle(cm_id_priv);
break;
case IB_CM_DREQ_SENT:
- ib_cancel_mad(cm_id_priv->av.port->mad_agent,
- (unsigned long) cm_id_priv->msg);
+ ib_cancel_mad(cm_id_priv->av.port->mad_agent, cm_id_priv->msg);
/* fall through */
case IB_CM_REP_RCVD:
case IB_CM_MRA_REP_SENT:
@@ -2080,7 +2067,6 @@ int ib_send_cm_mra(struct ib_cm_id *cm_id,
{
struct cm_id_private *cm_id_priv;
struct ib_mad_send_buf *msg;
- struct ib_send_wr *bad_send_wr;
void *data;
unsigned long flags;
int ret;
@@ -2104,8 +2090,7 @@ int ib_send_cm_mra(struct ib_cm_id *cm_id,
cm_format_mra((struct cm_mra_msg *) msg->mad, cm_id_priv,
CM_MSG_RESPONSE_REQ, service_timeout,
private_data, private_data_len);
- ret = ib_post_send_mad(cm_id_priv->av.port->mad_agent,
- &msg->send_wr, &bad_send_wr);
+ ret = ib_post_send_mad(msg, NULL);
if (ret)
goto error2;
cm_id->state = IB_CM_MRA_REQ_SENT;
@@ -2118,8 +2103,7 @@ int ib_send_cm_mra(struct ib_cm_id *cm_id,
cm_format_mra((struct cm_mra_msg *) msg->mad, cm_id_priv,
CM_MSG_RESPONSE_REP, service_timeout,
private_data, private_data_len);
- ret = ib_post_send_mad(cm_id_priv->av.port->mad_agent,
- &msg->send_wr, &bad_send_wr);
+ ret = ib_post_send_mad(msg, NULL);
if (ret)
goto error2;
cm_id->state = IB_CM_MRA_REP_SENT;
@@ -2132,8 +2116,7 @@ int ib_send_cm_mra(struct ib_cm_id *cm_id,
cm_format_mra((struct cm_mra_msg *) msg->mad, cm_id_priv,
CM_MSG_RESPONSE_OTHER, service_timeout,
private_data, private_data_len);
- ret = ib_post_send_mad(cm_id_priv->av.port->mad_agent,
- &msg->send_wr, &bad_send_wr);
+ ret = ib_post_send_mad(msg, NULL);
if (ret)
goto error2;
cm_id->lap_state = IB_CM_MRA_LAP_SENT;
@@ -2195,14 +2178,14 @@ static int cm_mra_handler(struct cm_work *work)
case IB_CM_REQ_SENT:
if (cm_mra_get_msg_mraed(mra_msg) != CM_MSG_RESPONSE_REQ ||
ib_modify_mad(cm_id_priv->av.port->mad_agent,
- (unsigned long) cm_id_priv->msg, timeout))
+ cm_id_priv->msg, timeout))
goto out;
cm_id_priv->id.state = IB_CM_MRA_REQ_RCVD;
break;
case IB_CM_REP_SENT:
if (cm_mra_get_msg_mraed(mra_msg) != CM_MSG_RESPONSE_REP ||
ib_modify_mad(cm_id_priv->av.port->mad_agent,
- (unsigned long) cm_id_priv->msg, timeout))
+ cm_id_priv->msg, timeout))
goto out;
cm_id_priv->id.state = IB_CM_MRA_REP_RCVD;
break;
@@ -2210,7 +2193,7 @@ static int cm_mra_handler(struct cm_work *work)
if (cm_mra_get_msg_mraed(mra_msg) != CM_MSG_RESPONSE_OTHER ||
cm_id_priv->id.lap_state != IB_CM_LAP_SENT ||
ib_modify_mad(cm_id_priv->av.port->mad_agent,
- (unsigned long) cm_id_priv->msg, timeout))
+ cm_id_priv->msg, timeout))
goto out;
cm_id_priv->id.lap_state = IB_CM_MRA_LAP_RCVD;
break;
@@ -2273,7 +2256,6 @@ int ib_send_cm_lap(struct ib_cm_id *cm_id,
{
struct cm_id_private *cm_id_priv;
struct ib_mad_send_buf *msg;
- struct ib_send_wr *bad_send_wr;
unsigned long flags;
int ret;
@@ -2294,11 +2276,10 @@ int ib_send_cm_lap(struct ib_cm_id *cm_id,
cm_format_lap((struct cm_lap_msg *) msg->mad, cm_id_priv,
alternate_path, private_data, private_data_len);
- msg->send_wr.wr.ud.timeout_ms = cm_id_priv->timeout_ms;
+ msg->timeout_ms = cm_id_priv->timeout_ms;
msg->context[1] = (void *) (unsigned long) IB_CM_ESTABLISHED;
- ret = ib_post_send_mad(cm_id_priv->av.port->mad_agent,
- &msg->send_wr, &bad_send_wr);
+ ret = ib_post_send_mad(msg, NULL);
if (ret) {
spin_unlock_irqrestore(&cm_id_priv->lock, flags);
cm_free_msg(msg);
@@ -2342,7 +2323,6 @@ static int cm_lap_handler(struct cm_work *work)
struct cm_lap_msg *lap_msg;
struct ib_cm_lap_event_param *param;
struct ib_mad_send_buf *msg = NULL;
- struct ib_send_wr *bad_send_wr;
unsigned long flags;
int ret;
@@ -2376,8 +2356,7 @@ static int cm_lap_handler(struct cm_work *work)
cm_id_priv->private_data_len);
spin_unlock_irqrestore(&cm_id_priv->lock, flags);
- if (ib_post_send_mad(cm_id_priv->av.port->mad_agent,
- &msg->send_wr, &bad_send_wr))
+ if (ib_post_send_mad(msg, NULL))
cm_free_msg(msg);
goto deref;
default:
@@ -2433,7 +2412,6 @@ int ib_send_cm_apr(struct ib_cm_id *cm_id,
{
struct cm_id_private *cm_id_priv;
struct ib_mad_send_buf *msg;
- struct ib_send_wr *bad_send_wr;
unsigned long flags;
int ret;
@@ -2456,8 +2434,7 @@ int ib_send_cm_apr(struct ib_cm_id *cm_id,
cm_format_apr((struct cm_apr_msg *) msg->mad, cm_id_priv, status,
info, info_length, private_data, private_data_len);
- ret = ib_post_send_mad(cm_id_priv->av.port->mad_agent,
- &msg->send_wr, &bad_send_wr);
+ ret = ib_post_send_mad(msg, NULL);
if (ret) {
spin_unlock_irqrestore(&cm_id_priv->lock, flags);
cm_free_msg(msg);
@@ -2496,8 +2473,7 @@ static int cm_apr_handler(struct cm_work *work)
goto out;
}
cm_id_priv->id.lap_state = IB_CM_LAP_IDLE;
- ib_cancel_mad(cm_id_priv->av.port->mad_agent,
- (unsigned long) cm_id_priv->msg);
+ ib_cancel_mad(cm_id_priv->av.port->mad_agent, cm_id_priv->msg);
cm_id_priv->msg = NULL;
ret = atomic_inc_and_test(&cm_id_priv->work_count);
@@ -2572,7 +2548,6 @@ int ib_send_cm_sidr_req(struct ib_cm_id *cm_id,
{
struct cm_id_private *cm_id_priv;
struct ib_mad_send_buf *msg;
- struct ib_send_wr *bad_send_wr;
unsigned long flags;
int ret;
@@ -2595,13 +2570,12 @@ int ib_send_cm_sidr_req(struct ib_cm_id *cm_id,
cm_format_sidr_req((struct cm_sidr_req_msg *) msg->mad, cm_id_priv,
param);
- msg->send_wr.wr.ud.timeout_ms = cm_id_priv->timeout_ms;
+ msg->timeout_ms = cm_id_priv->timeout_ms;
msg->context[1] = (void *) (unsigned long) IB_CM_SIDR_REQ_SENT;
spin_lock_irqsave(&cm_id_priv->lock, flags);
if (cm_id->state == IB_CM_IDLE)
- ret = ib_post_send_mad(cm_id_priv->av.port->mad_agent,
- &msg->send_wr, &bad_send_wr);
+ ret = ib_post_send_mad(msg, NULL);
else
ret = -EINVAL;
@@ -2629,7 +2603,6 @@ static void cm_format_sidr_req_event(struct cm_work *work,
param = &work->cm_event.param.sidr_req_rcvd;
param->pkey = __be16_to_cpu(sidr_req_msg->pkey);
param->listen_id = listen_id;
- param->device = work->port->mad_agent->device;
param->port = work->port->port_num;
work->cm_event.private_data = &sidr_req_msg->private_data;
}
@@ -2642,7 +2615,7 @@ static int cm_sidr_req_handler(struct cm_work *work)
struct ib_wc *wc;
unsigned long flags;
- cm_id = ib_create_cm_id(NULL, NULL);
+ cm_id = ib_create_cm_id(work->port->cm_dev->device, NULL, NULL);
if (IS_ERR(cm_id))
return PTR_ERR(cm_id);
cm_id_priv = container_of(cm_id, struct cm_id_private, id);
@@ -2666,7 +2639,8 @@ static int cm_sidr_req_handler(struct cm_work *work)
spin_unlock_irqrestore(&cm.lock, flags);
goto out; /* Duplicate message. */
}
- cur_cm_id_priv = cm_find_listen(sidr_req_msg->service_id);
+ cur_cm_id_priv = cm_find_listen(cm_id->device,
+ sidr_req_msg->service_id);
if (!cur_cm_id_priv) {
rb_erase(&cm_id_priv->sidr_id_node, &cm.remote_sidr_table);
spin_unlock_irqrestore(&cm.lock, flags);
@@ -2715,7 +2689,6 @@ int ib_send_cm_sidr_rep(struct ib_cm_id *cm_id,
{
struct cm_id_private *cm_id_priv;
struct ib_mad_send_buf *msg;
- struct ib_send_wr *bad_send_wr;
unsigned long flags;
int ret;
@@ -2737,8 +2710,7 @@ int ib_send_cm_sidr_rep(struct ib_cm_id *cm_id,
cm_format_sidr_rep((struct cm_sidr_rep_msg *) msg->mad, cm_id_priv,
param);
- ret = ib_post_send_mad(cm_id_priv->av.port->mad_agent,
- &msg->send_wr, &bad_send_wr);
+ ret = ib_post_send_mad(msg, NULL);
if (ret) {
spin_unlock_irqrestore(&cm_id_priv->lock, flags);
cm_free_msg(msg);
@@ -2791,8 +2763,7 @@ static int cm_sidr_rep_handler(struct cm_work *work)
goto out;
}
cm_id_priv->id.state = IB_CM_IDLE;
- ib_cancel_mad(cm_id_priv->av.port->mad_agent,
- (unsigned long) cm_id_priv->msg);
+ ib_cancel_mad(cm_id_priv->av.port->mad_agent, cm_id_priv->msg);
spin_unlock_irqrestore(&cm_id_priv->lock, flags);
cm_format_sidr_rep_event(work);
@@ -2860,9 +2831,7 @@ discard:
static void cm_send_handler(struct ib_mad_agent *mad_agent,
struct ib_mad_send_wc *mad_send_wc)
{
- struct ib_mad_send_buf *msg;
-
- msg = (struct ib_mad_send_buf *)(unsigned long)mad_send_wc->wr_id;
+ struct ib_mad_send_buf *msg = mad_send_wc->send_buf;
switch (mad_send_wc->status) {
case IB_WC_SUCCESS:
@@ -3064,10 +3033,10 @@ static int cm_init_qp_init_attr(struct cm_id_private *cm_id_priv,
case IB_CM_ESTABLISHED:
*qp_attr_mask = IB_QP_STATE | IB_QP_ACCESS_FLAGS |
IB_QP_PKEY_INDEX | IB_QP_PORT;
- qp_attr->qp_access_flags = IB_ACCESS_LOCAL_WRITE;
+ qp_attr->qp_access_flags = IB_ACCESS_LOCAL_WRITE |
+ IB_ACCESS_REMOTE_WRITE;
if (cm_id_priv->responder_resources)
- qp_attr->qp_access_flags |= IB_ACCESS_REMOTE_WRITE |
- IB_ACCESS_REMOTE_READ;
+ qp_attr->qp_access_flags |= IB_ACCESS_REMOTE_READ;
qp_attr->pkey_index = cm_id_priv->av.pkey_index;
qp_attr->port_num = cm_id_priv->av.port->port_num;
ret = 0;
@@ -3097,14 +3066,18 @@ static int cm_init_qp_rtr_attr(struct cm_id_private *cm_id_priv,
case IB_CM_MRA_REP_RCVD:
case IB_CM_ESTABLISHED:
*qp_attr_mask = IB_QP_STATE | IB_QP_AV | IB_QP_PATH_MTU |
- IB_QP_DEST_QPN | IB_QP_RQ_PSN |
- IB_QP_MAX_DEST_RD_ATOMIC | IB_QP_MIN_RNR_TIMER;
+ IB_QP_DEST_QPN | IB_QP_RQ_PSN;
qp_attr->ah_attr = cm_id_priv->av.ah_attr;
qp_attr->path_mtu = cm_id_priv->path_mtu;
qp_attr->dest_qp_num = be32_to_cpu(cm_id_priv->remote_qpn);
qp_attr->rq_psn = be32_to_cpu(cm_id_priv->rq_psn);
- qp_attr->max_dest_rd_atomic = cm_id_priv->responder_resources;
- qp_attr->min_rnr_timer = 0;
+ if (cm_id_priv->qp_type == IB_QPT_RC) {
+ *qp_attr_mask |= IB_QP_MAX_DEST_RD_ATOMIC |
+ IB_QP_MIN_RNR_TIMER;
+ qp_attr->max_dest_rd_atomic =
+ cm_id_priv->responder_resources;
+ qp_attr->min_rnr_timer = 0;
+ }
if (cm_id_priv->alt_av.ah_attr.dlid) {
*qp_attr_mask |= IB_QP_ALT_PATH;
qp_attr->alt_ah_attr = cm_id_priv->alt_av.ah_attr;
@@ -3133,14 +3106,17 @@ static int cm_init_qp_rts_attr(struct cm_id_private *cm_id_priv,
case IB_CM_REP_SENT:
case IB_CM_MRA_REP_RCVD:
case IB_CM_ESTABLISHED:
- *qp_attr_mask = IB_QP_STATE | IB_QP_TIMEOUT | IB_QP_RETRY_CNT |
- IB_QP_RNR_RETRY | IB_QP_SQ_PSN |
- IB_QP_MAX_QP_RD_ATOMIC;
- qp_attr->timeout = cm_id_priv->local_ack_timeout;
- qp_attr->retry_cnt = cm_id_priv->retry_count;
- qp_attr->rnr_retry = cm_id_priv->rnr_retry_count;
+ *qp_attr_mask = IB_QP_STATE | IB_QP_SQ_PSN;
qp_attr->sq_psn = be32_to_cpu(cm_id_priv->sq_psn);
- qp_attr->max_rd_atomic = cm_id_priv->initiator_depth;
+ if (cm_id_priv->qp_type == IB_QPT_RC) {
+ *qp_attr_mask |= IB_QP_TIMEOUT | IB_QP_RETRY_CNT |
+ IB_QP_RNR_RETRY |
+ IB_QP_MAX_QP_RD_ATOMIC;
+ qp_attr->timeout = cm_id_priv->local_ack_timeout;
+ qp_attr->retry_cnt = cm_id_priv->retry_count;
+ qp_attr->rnr_retry = cm_id_priv->rnr_retry_count;
+ qp_attr->max_rd_atomic = cm_id_priv->initiator_depth;
+ }
if (cm_id_priv->alt_av.ah_attr.dlid) {
*qp_attr_mask |= IB_QP_PATH_MIG_STATE;
qp_attr->path_mig_state = IB_MIG_REARM;
@@ -3323,6 +3299,7 @@ static void __exit ib_cm_cleanup(void)
flush_workqueue(cm.wq);
destroy_workqueue(cm.wq);
ib_unregister_client(&cm_client);
+ idr_destroy(&cm.local_id_table);
}
module_init(ib_cm_init);
diff --git a/drivers/infiniband/core/cm_msgs.h b/drivers/infiniband/core/cm_msgs.h
index 813ab70bf6d5..4d3aee90c249 100644
--- a/drivers/infiniband/core/cm_msgs.h
+++ b/drivers/infiniband/core/cm_msgs.h
@@ -186,6 +186,7 @@ static inline void cm_req_set_qp_type(struct cm_req_msg *req_msg,
req_msg->offset40 = cpu_to_be32((be32_to_cpu(
req_msg->offset40) &
0xFFFFFFF9) | 0x2);
+ break;
default:
req_msg->offset40 = cpu_to_be32(be32_to_cpu(
req_msg->offset40) &
diff --git a/drivers/infiniband/core/device.c b/drivers/infiniband/core/device.c
index d3cf84e01587..e169e798354b 100644
--- a/drivers/infiniband/core/device.c
+++ b/drivers/infiniband/core/device.c
@@ -161,17 +161,9 @@ static int alloc_name(char *name)
*/
struct ib_device *ib_alloc_device(size_t size)
{
- void *dev;
-
BUG_ON(size < sizeof (struct ib_device));
- dev = kmalloc(size, GFP_KERNEL);
- if (!dev)
- return NULL;
-
- memset(dev, 0, size);
-
- return dev;
+ return kzalloc(size, GFP_KERNEL);
}
EXPORT_SYMBOL(ib_alloc_device);
@@ -514,6 +506,12 @@ int ib_query_port(struct ib_device *device,
u8 port_num,
struct ib_port_attr *port_attr)
{
+ if (device->node_type == IB_NODE_SWITCH) {
+ if (port_num)
+ return -EINVAL;
+ } else if (port_num < 1 || port_num > device->phys_port_cnt)
+ return -EINVAL;
+
return device->query_port(device, port_num, port_attr);
}
EXPORT_SYMBOL(ib_query_port);
@@ -583,6 +581,12 @@ int ib_modify_port(struct ib_device *device,
u8 port_num, int port_modify_mask,
struct ib_port_modify *port_modify)
{
+ if (device->node_type == IB_NODE_SWITCH) {
+ if (port_num)
+ return -EINVAL;
+ } else if (port_num < 1 || port_num > device->phys_port_cnt)
+ return -EINVAL;
+
return device->modify_port(device, port_num, port_modify_mask,
port_modify);
}
diff --git a/drivers/infiniband/core/mad.c b/drivers/infiniband/core/mad.c
index a14ca87fda18..41d6b4017acb 100644
--- a/drivers/infiniband/core/mad.c
+++ b/drivers/infiniband/core/mad.c
@@ -255,12 +255,11 @@ struct ib_mad_agent *ib_register_mad_agent(struct ib_device *device,
}
/* Allocate structures */
- mad_agent_priv = kmalloc(sizeof *mad_agent_priv, GFP_KERNEL);
+ mad_agent_priv = kzalloc(sizeof *mad_agent_priv, GFP_KERNEL);
if (!mad_agent_priv) {
ret = ERR_PTR(-ENOMEM);
goto error1;
}
- memset(mad_agent_priv, 0, sizeof *mad_agent_priv);
mad_agent_priv->agent.mr = ib_get_dma_mr(port_priv->qp_info[qpn].qp->pd,
IB_ACCESS_LOCAL_WRITE);
@@ -448,14 +447,13 @@ struct ib_mad_agent *ib_register_mad_snoop(struct ib_device *device,
goto error1;
}
/* Allocate structures */
- mad_snoop_priv = kmalloc(sizeof *mad_snoop_priv, GFP_KERNEL);
+ mad_snoop_priv = kzalloc(sizeof *mad_snoop_priv, GFP_KERNEL);
if (!mad_snoop_priv) {
ret = ERR_PTR(-ENOMEM);
goto error1;
}
/* Now, fill in the various structures */
- memset(mad_snoop_priv, 0, sizeof *mad_snoop_priv);
mad_snoop_priv->qp_info = &port_priv->qp_info[qpn];
mad_snoop_priv->agent.device = device;
mad_snoop_priv->agent.recv_handler = recv_handler;
@@ -510,8 +508,7 @@ static void unregister_mad_agent(struct ib_mad_agent_private *mad_agent_priv)
wait_event(mad_agent_priv->wait,
!atomic_read(&mad_agent_priv->refcount));
- if (mad_agent_priv->reg_req)
- kfree(mad_agent_priv->reg_req);
+ kfree(mad_agent_priv->reg_req);
ib_dereg_mr(mad_agent_priv->agent.mr);
kfree(mad_agent_priv);
}
@@ -579,7 +576,7 @@ static void dequeue_mad(struct ib_mad_list_head *mad_list)
}
static void snoop_send(struct ib_mad_qp_info *qp_info,
- struct ib_send_wr *send_wr,
+ struct ib_mad_send_buf *send_buf,
struct ib_mad_send_wc *mad_send_wc,
int mad_snoop_flags)
{
@@ -597,7 +594,7 @@ static void snoop_send(struct ib_mad_qp_info *qp_info,
atomic_inc(&mad_snoop_priv->refcount);
spin_unlock_irqrestore(&qp_info->snoop_lock, flags);
mad_snoop_priv->agent.snoop_handler(&mad_snoop_priv->agent,
- send_wr, mad_send_wc);
+ send_buf, mad_send_wc);
if (atomic_dec_and_test(&mad_snoop_priv->refcount))
wake_up(&mad_snoop_priv->wait);
spin_lock_irqsave(&qp_info->snoop_lock, flags);
@@ -654,10 +651,10 @@ static void build_smp_wc(u64 wr_id, u16 slid, u16 pkey_index, u8 port_num,
* Return < 0 if error
*/
static int handle_outgoing_dr_smp(struct ib_mad_agent_private *mad_agent_priv,
- struct ib_smp *smp,
- struct ib_send_wr *send_wr)
+ struct ib_mad_send_wr_private *mad_send_wr)
{
int ret;
+ struct ib_smp *smp = mad_send_wr->send_buf.mad;
unsigned long flags;
struct ib_mad_local_private *local;
struct ib_mad_private *mad_priv;
@@ -666,6 +663,7 @@ static int handle_outgoing_dr_smp(struct ib_mad_agent_private *mad_agent_priv,
struct ib_device *device = mad_agent_priv->agent.device;
u8 port_num = mad_agent_priv->agent.port_num;
struct ib_wc mad_wc;
+ struct ib_send_wr *send_wr = &mad_send_wr->send_wr;
if (!smi_handle_dr_smp_send(smp, device->node_type, port_num)) {
ret = -EINVAL;
@@ -745,13 +743,7 @@ static int handle_outgoing_dr_smp(struct ib_mad_agent_private *mad_agent_priv,
goto out;
}
- local->send_wr = *send_wr;
- local->send_wr.sg_list = local->sg_list;
- memcpy(local->sg_list, send_wr->sg_list,
- sizeof *send_wr->sg_list * send_wr->num_sge);
- local->send_wr.next = NULL;
- local->tid = send_wr->wr.ud.mad_hdr->tid;
- local->wr_id = send_wr->wr_id;
+ local->mad_send_wr = mad_send_wr;
/* Reference MAD agent until send side of local completion handled */
atomic_inc(&mad_agent_priv->refcount);
/* Queue local completion to local list */
@@ -781,17 +773,17 @@ static int get_buf_length(int hdr_len, int data_len)
struct ib_mad_send_buf * ib_create_send_mad(struct ib_mad_agent *mad_agent,
u32 remote_qpn, u16 pkey_index,
- struct ib_ah *ah, int rmpp_active,
+ int rmpp_active,
int hdr_len, int data_len,
gfp_t gfp_mask)
{
struct ib_mad_agent_private *mad_agent_priv;
- struct ib_mad_send_buf *send_buf;
+ struct ib_mad_send_wr_private *mad_send_wr;
int buf_size;
void *buf;
- mad_agent_priv = container_of(mad_agent,
- struct ib_mad_agent_private, agent);
+ mad_agent_priv = container_of(mad_agent, struct ib_mad_agent_private,
+ agent);
buf_size = get_buf_length(hdr_len, data_len);
if ((!mad_agent->rmpp_version &&
@@ -799,45 +791,39 @@ struct ib_mad_send_buf * ib_create_send_mad(struct ib_mad_agent *mad_agent,
(!rmpp_active && buf_size > sizeof(struct ib_mad)))
return ERR_PTR(-EINVAL);
- buf = kmalloc(sizeof *send_buf + buf_size, gfp_mask);
+ buf = kzalloc(sizeof *mad_send_wr + buf_size, gfp_mask);
if (!buf)
return ERR_PTR(-ENOMEM);
- memset(buf, 0, sizeof *send_buf + buf_size);
-
- send_buf = buf + buf_size;
- send_buf->mad = buf;
-
- send_buf->sge.addr = dma_map_single(mad_agent->device->dma_device,
- buf, buf_size, DMA_TO_DEVICE);
- pci_unmap_addr_set(send_buf, mapping, send_buf->sge.addr);
- send_buf->sge.length = buf_size;
- send_buf->sge.lkey = mad_agent->mr->lkey;
-
- send_buf->send_wr.wr_id = (unsigned long) send_buf;
- send_buf->send_wr.sg_list = &send_buf->sge;
- send_buf->send_wr.num_sge = 1;
- send_buf->send_wr.opcode = IB_WR_SEND;
- send_buf->send_wr.send_flags = IB_SEND_SIGNALED;
- send_buf->send_wr.wr.ud.ah = ah;
- send_buf->send_wr.wr.ud.mad_hdr = &send_buf->mad->mad_hdr;
- send_buf->send_wr.wr.ud.remote_qpn = remote_qpn;
- send_buf->send_wr.wr.ud.remote_qkey = IB_QP_SET_QKEY;
- send_buf->send_wr.wr.ud.pkey_index = pkey_index;
+
+ mad_send_wr = buf + buf_size;
+ mad_send_wr->send_buf.mad = buf;
+
+ mad_send_wr->mad_agent_priv = mad_agent_priv;
+ mad_send_wr->sg_list[0].length = buf_size;
+ mad_send_wr->sg_list[0].lkey = mad_agent->mr->lkey;
+
+ mad_send_wr->send_wr.wr_id = (unsigned long) mad_send_wr;
+ mad_send_wr->send_wr.sg_list = mad_send_wr->sg_list;
+ mad_send_wr->send_wr.num_sge = 1;
+ mad_send_wr->send_wr.opcode = IB_WR_SEND;
+ mad_send_wr->send_wr.send_flags = IB_SEND_SIGNALED;
+ mad_send_wr->send_wr.wr.ud.remote_qpn = remote_qpn;
+ mad_send_wr->send_wr.wr.ud.remote_qkey = IB_QP_SET_QKEY;
+ mad_send_wr->send_wr.wr.ud.pkey_index = pkey_index;
if (rmpp_active) {
- struct ib_rmpp_mad *rmpp_mad;
- rmpp_mad = (struct ib_rmpp_mad *)send_buf->mad;
+ struct ib_rmpp_mad *rmpp_mad = mad_send_wr->send_buf.mad;
rmpp_mad->rmpp_hdr.paylen_newwin = cpu_to_be32(hdr_len -
- offsetof(struct ib_rmpp_mad, data) + data_len);
+ IB_MGMT_RMPP_HDR + data_len);
rmpp_mad->rmpp_hdr.rmpp_version = mad_agent->rmpp_version;
rmpp_mad->rmpp_hdr.rmpp_type = IB_MGMT_RMPP_TYPE_DATA;
ib_set_rmpp_flags(&rmpp_mad->rmpp_hdr,
IB_MGMT_RMPP_FLAG_ACTIVE);
}
- send_buf->mad_agent = mad_agent;
+ mad_send_wr->send_buf.mad_agent = mad_agent;
atomic_inc(&mad_agent_priv->refcount);
- return send_buf;
+ return &mad_send_wr->send_buf;
}
EXPORT_SYMBOL(ib_create_send_mad);
@@ -847,10 +833,6 @@ void ib_free_send_mad(struct ib_mad_send_buf *send_buf)
mad_agent_priv = container_of(send_buf->mad_agent,
struct ib_mad_agent_private, agent);
-
- dma_unmap_single(send_buf->mad_agent->device->dma_device,
- pci_unmap_addr(send_buf, mapping),
- send_buf->sge.length, DMA_TO_DEVICE);
kfree(send_buf->mad);
if (atomic_dec_and_test(&mad_agent_priv->refcount))
@@ -861,8 +843,10 @@ EXPORT_SYMBOL(ib_free_send_mad);
int ib_send_mad(struct ib_mad_send_wr_private *mad_send_wr)
{
struct ib_mad_qp_info *qp_info;
- struct ib_send_wr *bad_send_wr;
struct list_head *list;
+ struct ib_send_wr *bad_send_wr;
+ struct ib_mad_agent *mad_agent;
+ struct ib_sge *sge;
unsigned long flags;
int ret;
@@ -871,10 +855,17 @@ int ib_send_mad(struct ib_mad_send_wr_private *mad_send_wr)
mad_send_wr->send_wr.wr_id = (unsigned long)&mad_send_wr->mad_list;
mad_send_wr->mad_list.mad_queue = &qp_info->send_queue;
+ mad_agent = mad_send_wr->send_buf.mad_agent;
+ sge = mad_send_wr->sg_list;
+ sge->addr = dma_map_single(mad_agent->device->dma_device,
+ mad_send_wr->send_buf.mad, sge->length,
+ DMA_TO_DEVICE);
+ pci_unmap_addr_set(mad_send_wr, mapping, sge->addr);
+
spin_lock_irqsave(&qp_info->send_queue.lock, flags);
if (qp_info->send_queue.count < qp_info->send_queue.max_active) {
- ret = ib_post_send(mad_send_wr->mad_agent_priv->agent.qp,
- &mad_send_wr->send_wr, &bad_send_wr);
+ ret = ib_post_send(mad_agent->qp, &mad_send_wr->send_wr,
+ &bad_send_wr);
list = &qp_info->send_queue.list;
} else {
ret = 0;
@@ -886,6 +877,11 @@ int ib_send_mad(struct ib_mad_send_wr_private *mad_send_wr)
list_add_tail(&mad_send_wr->mad_list.list, list);
}
spin_unlock_irqrestore(&qp_info->send_queue.lock, flags);
+ if (ret)
+ dma_unmap_single(mad_agent->device->dma_device,
+ pci_unmap_addr(mad_send_wr, mapping),
+ sge->length, DMA_TO_DEVICE);
+
return ret;
}
@@ -893,45 +889,28 @@ int ib_send_mad(struct ib_mad_send_wr_private *mad_send_wr)
* ib_post_send_mad - Posts MAD(s) to the send queue of the QP associated
* with the registered client
*/
-int ib_post_send_mad(struct ib_mad_agent *mad_agent,
- struct ib_send_wr *send_wr,
- struct ib_send_wr **bad_send_wr)
+int ib_post_send_mad(struct ib_mad_send_buf *send_buf,
+ struct ib_mad_send_buf **bad_send_buf)
{
- int ret = -EINVAL;
struct ib_mad_agent_private *mad_agent_priv;
-
- /* Validate supplied parameters */
- if (!bad_send_wr)
- goto error1;
-
- if (!mad_agent || !send_wr)
- goto error2;
-
- if (!mad_agent->send_handler)
- goto error2;
-
- mad_agent_priv = container_of(mad_agent,
- struct ib_mad_agent_private,
- agent);
+ struct ib_mad_send_buf *next_send_buf;
+ struct ib_mad_send_wr_private *mad_send_wr;
+ unsigned long flags;
+ int ret = -EINVAL;
/* Walk list of send WRs and post each on send list */
- while (send_wr) {
- unsigned long flags;
- struct ib_send_wr *next_send_wr;
- struct ib_mad_send_wr_private *mad_send_wr;
- struct ib_smp *smp;
-
- /* Validate more parameters */
- if (send_wr->num_sge > IB_MAD_SEND_REQ_MAX_SG)
- goto error2;
-
- if (send_wr->wr.ud.timeout_ms && !mad_agent->recv_handler)
- goto error2;
+ for (; send_buf; send_buf = next_send_buf) {
- if (!send_wr->wr.ud.mad_hdr) {
- printk(KERN_ERR PFX "MAD header must be supplied "
- "in WR %p\n", send_wr);
- goto error2;
+ mad_send_wr = container_of(send_buf,
+ struct ib_mad_send_wr_private,
+ send_buf);
+ mad_agent_priv = mad_send_wr->mad_agent_priv;
+
+ if (!send_buf->mad_agent->send_handler ||
+ (send_buf->timeout_ms &&
+ !send_buf->mad_agent->recv_handler)) {
+ ret = -EINVAL;
+ goto error;
}
/*
@@ -939,40 +918,24 @@ int ib_post_send_mad(struct ib_mad_agent *mad_agent,
* current one completes, and the user modifies the work
* request associated with the completion
*/
- next_send_wr = (struct ib_send_wr *)send_wr->next;
+ next_send_buf = send_buf->next;
+ mad_send_wr->send_wr.wr.ud.ah = send_buf->ah;
- smp = (struct ib_smp *)send_wr->wr.ud.mad_hdr;
- if (smp->mgmt_class == IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE) {
- ret = handle_outgoing_dr_smp(mad_agent_priv, smp,
- send_wr);
+ if (((struct ib_mad_hdr *) send_buf->mad)->mgmt_class ==
+ IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE) {
+ ret = handle_outgoing_dr_smp(mad_agent_priv,
+ mad_send_wr);
if (ret < 0) /* error */
- goto error2;
+ goto error;
else if (ret == 1) /* locally consumed */
- goto next;
+ continue;
}
- /* Allocate MAD send WR tracking structure */
- mad_send_wr = kmalloc(sizeof *mad_send_wr, GFP_ATOMIC);
- if (!mad_send_wr) {
- printk(KERN_ERR PFX "No memory for "
- "ib_mad_send_wr_private\n");
- ret = -ENOMEM;
- goto error2;
- }
- memset(mad_send_wr, 0, sizeof *mad_send_wr);
-
- mad_send_wr->send_wr = *send_wr;
- mad_send_wr->send_wr.sg_list = mad_send_wr->sg_list;
- memcpy(mad_send_wr->sg_list, send_wr->sg_list,
- sizeof *send_wr->sg_list * send_wr->num_sge);
- mad_send_wr->wr_id = send_wr->wr_id;
- mad_send_wr->tid = send_wr->wr.ud.mad_hdr->tid;
- mad_send_wr->mad_agent_priv = mad_agent_priv;
+ mad_send_wr->tid = ((struct ib_mad_hdr *) send_buf->mad)->tid;
/* Timeout will be updated after send completes */
- mad_send_wr->timeout = msecs_to_jiffies(send_wr->wr.
- ud.timeout_ms);
- mad_send_wr->retries = mad_send_wr->send_wr.wr.ud.retries;
- /* One reference for each work request to QP + response */
+ mad_send_wr->timeout = msecs_to_jiffies(send_buf->timeout_ms);
+ mad_send_wr->retries = send_buf->retries;
+ /* Reference for work request to QP + response */
mad_send_wr->refcount = 1 + (mad_send_wr->timeout > 0);
mad_send_wr->status = IB_WC_SUCCESS;
@@ -995,16 +958,13 @@ int ib_post_send_mad(struct ib_mad_agent *mad_agent,
list_del(&mad_send_wr->agent_list);
spin_unlock_irqrestore(&mad_agent_priv->lock, flags);
atomic_dec(&mad_agent_priv->refcount);
- goto error2;
+ goto error;
}
-next:
- send_wr = next_send_wr;
}
return 0;
-
-error2:
- *bad_send_wr = send_wr;
-error1:
+error:
+ if (bad_send_buf)
+ *bad_send_buf = send_buf;
return ret;
}
EXPORT_SYMBOL(ib_post_send_mad);
@@ -1075,14 +1035,12 @@ static int method_in_use(struct ib_mad_mgmt_method_table **method,
static int allocate_method_table(struct ib_mad_mgmt_method_table **method)
{
/* Allocate management method table */
- *method = kmalloc(sizeof **method, GFP_ATOMIC);
+ *method = kzalloc(sizeof **method, GFP_ATOMIC);
if (!*method) {
printk(KERN_ERR PFX "No memory for "
"ib_mad_mgmt_method_table\n");
return -ENOMEM;
}
- /* Clear management method table */
- memset(*method, 0, sizeof **method);
return 0;
}
@@ -1173,15 +1131,14 @@ static int add_nonoui_reg_req(struct ib_mad_reg_req *mad_reg_req,
class = &port_priv->version[mad_reg_req->mgmt_class_version].class;
if (!*class) {
/* Allocate management class table for "new" class version */
- *class = kmalloc(sizeof **class, GFP_ATOMIC);
+ *class = kzalloc(sizeof **class, GFP_ATOMIC);
if (!*class) {
printk(KERN_ERR PFX "No memory for "
"ib_mad_mgmt_class_table\n");
ret = -ENOMEM;
goto error1;
}
- /* Clear management class table */
- memset(*class, 0, sizeof(**class));
+
/* Allocate method table for this management class */
method = &(*class)->method_table[mgmt_class];
if ((ret = allocate_method_table(method)))
@@ -1245,25 +1202,24 @@ static int add_oui_reg_req(struct ib_mad_reg_req *mad_reg_req,
mad_reg_req->mgmt_class_version].vendor;
if (!*vendor_table) {
/* Allocate mgmt vendor class table for "new" class version */
- vendor = kmalloc(sizeof *vendor, GFP_ATOMIC);
+ vendor = kzalloc(sizeof *vendor, GFP_ATOMIC);
if (!vendor) {
printk(KERN_ERR PFX "No memory for "
"ib_mad_mgmt_vendor_class_table\n");
goto error1;
}
- /* Clear management vendor class table */
- memset(vendor, 0, sizeof(*vendor));
+
*vendor_table = vendor;
}
if (!(*vendor_table)->vendor_class[vclass]) {
/* Allocate table for this management vendor class */
- vendor_class = kmalloc(sizeof *vendor_class, GFP_ATOMIC);
+ vendor_class = kzalloc(sizeof *vendor_class, GFP_ATOMIC);
if (!vendor_class) {
printk(KERN_ERR PFX "No memory for "
"ib_mad_mgmt_vendor_class\n");
goto error2;
}
- memset(vendor_class, 0, sizeof(*vendor_class));
+
(*vendor_table)->vendor_class[vclass] = vendor_class;
}
for (i = 0; i < MAX_MGMT_OUI; i++) {
@@ -1447,8 +1403,7 @@ find_mad_agent(struct ib_mad_port_private *port_priv,
* of MAD.
*/
hi_tid = be64_to_cpu(mad->mad_hdr.tid) >> 32;
- list_for_each_entry(entry, &port_priv->agent_list,
- agent_list) {
+ list_for_each_entry(entry, &port_priv->agent_list, agent_list) {
if (entry->agent.hi_tid == hi_tid) {
mad_agent = entry;
break;
@@ -1571,8 +1526,7 @@ ib_find_send_mad(struct ib_mad_agent_private *mad_agent_priv, __be64 tid)
*/
list_for_each_entry(mad_send_wr, &mad_agent_priv->send_list,
agent_list) {
- if (is_data_mad(mad_agent_priv,
- mad_send_wr->send_wr.wr.ud.mad_hdr) &&
+ if (is_data_mad(mad_agent_priv, mad_send_wr->send_buf.mad) &&
mad_send_wr->tid == tid && mad_send_wr->timeout) {
/* Verify request has not been canceled */
return (mad_send_wr->status == IB_WC_SUCCESS) ?
@@ -1628,14 +1582,14 @@ static void ib_mad_complete_recv(struct ib_mad_agent_private *mad_agent_priv,
spin_unlock_irqrestore(&mad_agent_priv->lock, flags);
/* Defined behavior is to complete response before request */
- mad_recv_wc->wc->wr_id = mad_send_wr->wr_id;
+ mad_recv_wc->wc->wr_id = (unsigned long) &mad_send_wr->send_buf;
mad_agent_priv->agent.recv_handler(&mad_agent_priv->agent,
mad_recv_wc);
atomic_dec(&mad_agent_priv->refcount);
mad_send_wc.status = IB_WC_SUCCESS;
mad_send_wc.vendor_err = 0;
- mad_send_wc.wr_id = mad_send_wr->wr_id;
+ mad_send_wc.send_buf = &mad_send_wr->send_buf;
ib_mad_complete_send_wr(mad_send_wr, &mad_send_wc);
} else {
mad_agent_priv->agent.recv_handler(&mad_agent_priv->agent,
@@ -1728,11 +1682,11 @@ local:
if (ret & IB_MAD_RESULT_CONSUMED)
goto out;
if (ret & IB_MAD_RESULT_REPLY) {
- /* Send response */
- if (!agent_send(response, &recv->grh, wc,
- port_priv->device,
- port_priv->port_num))
- response = NULL;
+ agent_send_response(&response->mad.mad,
+ &recv->grh, wc,
+ port_priv->device,
+ port_priv->port_num,
+ qp_info->qp->qp_num);
goto out;
}
}
@@ -1866,15 +1820,15 @@ void ib_mad_complete_send_wr(struct ib_mad_send_wr_private *mad_send_wr,
if (mad_send_wr->status != IB_WC_SUCCESS )
mad_send_wc->status = mad_send_wr->status;
- if (ret != IB_RMPP_RESULT_INTERNAL)
+ if (ret == IB_RMPP_RESULT_INTERNAL)
+ ib_rmpp_send_handler(mad_send_wc);
+ else
mad_agent_priv->agent.send_handler(&mad_agent_priv->agent,
mad_send_wc);
/* Release reference on agent taken when sending */
if (atomic_dec_and_test(&mad_agent_priv->refcount))
wake_up(&mad_agent_priv->wait);
-
- kfree(mad_send_wr);
return;
done:
spin_unlock_irqrestore(&mad_agent_priv->lock, flags);
@@ -1888,6 +1842,7 @@ static void ib_mad_send_done_handler(struct ib_mad_port_private *port_priv,
struct ib_mad_qp_info *qp_info;
struct ib_mad_queue *send_queue;
struct ib_send_wr *bad_send_wr;
+ struct ib_mad_send_wc mad_send_wc;
unsigned long flags;
int ret;
@@ -1898,6 +1853,9 @@ static void ib_mad_send_done_handler(struct ib_mad_port_private *port_priv,
qp_info = send_queue->qp_info;
retry:
+ dma_unmap_single(mad_send_wr->send_buf.mad_agent->device->dma_device,
+ pci_unmap_addr(mad_send_wr, mapping),
+ mad_send_wr->sg_list[0].length, DMA_TO_DEVICE);
queued_send_wr = NULL;
spin_lock_irqsave(&send_queue->lock, flags);
list_del(&mad_list->list);
@@ -1914,17 +1872,17 @@ retry:
}
spin_unlock_irqrestore(&send_queue->lock, flags);
- /* Restore client wr_id in WC and complete send */
- wc->wr_id = mad_send_wr->wr_id;
+ mad_send_wc.send_buf = &mad_send_wr->send_buf;
+ mad_send_wc.status = wc->status;
+ mad_send_wc.vendor_err = wc->vendor_err;
if (atomic_read(&qp_info->snoop_count))
- snoop_send(qp_info, &mad_send_wr->send_wr,
- (struct ib_mad_send_wc *)wc,
+ snoop_send(qp_info, &mad_send_wr->send_buf, &mad_send_wc,
IB_MAD_SNOOP_SEND_COMPLETIONS);
- ib_mad_complete_send_wr(mad_send_wr, (struct ib_mad_send_wc *)wc);
+ ib_mad_complete_send_wr(mad_send_wr, &mad_send_wc);
if (queued_send_wr) {
ret = ib_post_send(qp_info->qp, &queued_send_wr->send_wr,
- &bad_send_wr);
+ &bad_send_wr);
if (ret) {
printk(KERN_ERR PFX "ib_post_send failed: %d\n", ret);
mad_send_wr = queued_send_wr;
@@ -2066,38 +2024,37 @@ static void cancel_mads(struct ib_mad_agent_private *mad_agent_priv)
list_for_each_entry_safe(mad_send_wr, temp_mad_send_wr,
&cancel_list, agent_list) {
- mad_send_wc.wr_id = mad_send_wr->wr_id;
+ mad_send_wc.send_buf = &mad_send_wr->send_buf;
+ list_del(&mad_send_wr->agent_list);
mad_agent_priv->agent.send_handler(&mad_agent_priv->agent,
&mad_send_wc);
-
- list_del(&mad_send_wr->agent_list);
- kfree(mad_send_wr);
atomic_dec(&mad_agent_priv->refcount);
}
}
static struct ib_mad_send_wr_private*
-find_send_by_wr_id(struct ib_mad_agent_private *mad_agent_priv, u64 wr_id)
+find_send_wr(struct ib_mad_agent_private *mad_agent_priv,
+ struct ib_mad_send_buf *send_buf)
{
struct ib_mad_send_wr_private *mad_send_wr;
list_for_each_entry(mad_send_wr, &mad_agent_priv->wait_list,
agent_list) {
- if (mad_send_wr->wr_id == wr_id)
+ if (&mad_send_wr->send_buf == send_buf)
return mad_send_wr;
}
list_for_each_entry(mad_send_wr, &mad_agent_priv->send_list,
agent_list) {
- if (is_data_mad(mad_agent_priv,
- mad_send_wr->send_wr.wr.ud.mad_hdr) &&
- mad_send_wr->wr_id == wr_id)
+ if (is_data_mad(mad_agent_priv, mad_send_wr->send_buf.mad) &&
+ &mad_send_wr->send_buf == send_buf)
return mad_send_wr;
}
return NULL;
}
-int ib_modify_mad(struct ib_mad_agent *mad_agent, u64 wr_id, u32 timeout_ms)
+int ib_modify_mad(struct ib_mad_agent *mad_agent,
+ struct ib_mad_send_buf *send_buf, u32 timeout_ms)
{
struct ib_mad_agent_private *mad_agent_priv;
struct ib_mad_send_wr_private *mad_send_wr;
@@ -2107,7 +2064,7 @@ int ib_modify_mad(struct ib_mad_agent *mad_agent, u64 wr_id, u32 timeout_ms)
mad_agent_priv = container_of(mad_agent, struct ib_mad_agent_private,
agent);
spin_lock_irqsave(&mad_agent_priv->lock, flags);
- mad_send_wr = find_send_by_wr_id(mad_agent_priv, wr_id);
+ mad_send_wr = find_send_wr(mad_agent_priv, send_buf);
if (!mad_send_wr || mad_send_wr->status != IB_WC_SUCCESS) {
spin_unlock_irqrestore(&mad_agent_priv->lock, flags);
return -EINVAL;
@@ -2119,7 +2076,7 @@ int ib_modify_mad(struct ib_mad_agent *mad_agent, u64 wr_id, u32 timeout_ms)
mad_send_wr->refcount -= (mad_send_wr->timeout > 0);
}
- mad_send_wr->send_wr.wr.ud.timeout_ms = timeout_ms;
+ mad_send_wr->send_buf.timeout_ms = timeout_ms;
if (active)
mad_send_wr->timeout = msecs_to_jiffies(timeout_ms);
else
@@ -2130,9 +2087,10 @@ int ib_modify_mad(struct ib_mad_agent *mad_agent, u64 wr_id, u32 timeout_ms)
}
EXPORT_SYMBOL(ib_modify_mad);
-void ib_cancel_mad(struct ib_mad_agent *mad_agent, u64 wr_id)
+void ib_cancel_mad(struct ib_mad_agent *mad_agent,
+ struct ib_mad_send_buf *send_buf)
{
- ib_modify_mad(mad_agent, wr_id, 0);
+ ib_modify_mad(mad_agent, send_buf, 0);
}
EXPORT_SYMBOL(ib_cancel_mad);
@@ -2166,10 +2124,9 @@ static void local_completions(void *data)
* Defined behavior is to complete response
* before request
*/
- build_smp_wc(local->wr_id,
+ build_smp_wc((unsigned long) local->mad_send_wr,
be16_to_cpu(IB_LID_PERMISSIVE),
- 0 /* pkey index */,
- recv_mad_agent->agent.port_num, &wc);
+ 0, recv_mad_agent->agent.port_num, &wc);
local->mad_priv->header.recv_wc.wc = &wc;
local->mad_priv->header.recv_wc.mad_len =
@@ -2196,11 +2153,11 @@ local_send_completion:
/* Complete send */
mad_send_wc.status = IB_WC_SUCCESS;
mad_send_wc.vendor_err = 0;
- mad_send_wc.wr_id = local->wr_id;
+ mad_send_wc.send_buf = &local->mad_send_wr->send_buf;
if (atomic_read(&mad_agent_priv->qp_info->snoop_count))
- snoop_send(mad_agent_priv->qp_info, &local->send_wr,
- &mad_send_wc,
- IB_MAD_SNOOP_SEND_COMPLETIONS);
+ snoop_send(mad_agent_priv->qp_info,
+ &local->mad_send_wr->send_buf,
+ &mad_send_wc, IB_MAD_SNOOP_SEND_COMPLETIONS);
mad_agent_priv->agent.send_handler(&mad_agent_priv->agent,
&mad_send_wc);
@@ -2221,8 +2178,7 @@ static int retry_send(struct ib_mad_send_wr_private *mad_send_wr)
if (!mad_send_wr->retries--)
return -ETIMEDOUT;
- mad_send_wr->timeout = msecs_to_jiffies(mad_send_wr->send_wr.
- wr.ud.timeout_ms);
+ mad_send_wr->timeout = msecs_to_jiffies(mad_send_wr->send_buf.timeout_ms);
if (mad_send_wr->mad_agent_priv->agent.rmpp_version) {
ret = ib_retry_rmpp(mad_send_wr);
@@ -2285,11 +2241,10 @@ static void timeout_sends(void *data)
mad_send_wc.status = IB_WC_RESP_TIMEOUT_ERR;
else
mad_send_wc.status = mad_send_wr->status;
- mad_send_wc.wr_id = mad_send_wr->wr_id;
+ mad_send_wc.send_buf = &mad_send_wr->send_buf;
mad_agent_priv->agent.send_handler(&mad_agent_priv->agent,
&mad_send_wc);
- kfree(mad_send_wr);
atomic_dec(&mad_agent_priv->refcount);
spin_lock_irqsave(&mad_agent_priv->lock, flags);
}
@@ -2544,8 +2499,7 @@ error:
static void destroy_mad_qp(struct ib_mad_qp_info *qp_info)
{
ib_destroy_qp(qp_info->qp);
- if (qp_info->snoop_table)
- kfree(qp_info->snoop_table);
+ kfree(qp_info->snoop_table);
}
/*
@@ -2561,12 +2515,12 @@ static int ib_mad_port_open(struct ib_device *device,
char name[sizeof "ib_mad123"];
/* Create new device info */
- port_priv = kmalloc(sizeof *port_priv, GFP_KERNEL);
+ port_priv = kzalloc(sizeof *port_priv, GFP_KERNEL);
if (!port_priv) {
printk(KERN_ERR PFX "No memory for ib_mad_port_private\n");
return -ENOMEM;
}
- memset(port_priv, 0, sizeof *port_priv);
+
port_priv->device = device;
port_priv->port_num = port_num;
spin_lock_init(&port_priv->reg_lock);
@@ -2683,40 +2637,47 @@ static int ib_mad_port_close(struct ib_device *device, int port_num)
static void ib_mad_init_device(struct ib_device *device)
{
- int num_ports, cur_port, i;
+ int start, end, i;
if (device->node_type == IB_NODE_SWITCH) {
- num_ports = 1;
- cur_port = 0;
+ start = 0;
+ end = 0;
} else {
- num_ports = device->phys_port_cnt;
- cur_port = 1;
+ start = 1;
+ end = device->phys_port_cnt;
}
- for (i = 0; i < num_ports; i++, cur_port++) {
- if (ib_mad_port_open(device, cur_port)) {
+
+ for (i = start; i <= end; i++) {
+ if (ib_mad_port_open(device, i)) {
printk(KERN_ERR PFX "Couldn't open %s port %d\n",
- device->name, cur_port);
- goto error_device_open;
+ device->name, i);
+ goto error;
}
- if (ib_agent_port_open(device, cur_port)) {
+ if (ib_agent_port_open(device, i)) {
printk(KERN_ERR PFX "Couldn't open %s port %d "
"for agents\n",
- device->name, cur_port);
- goto error_device_open;
+ device->name, i);
+ goto error_agent;
}
}
return;
-error_device_open:
- while (i > 0) {
- cur_port--;
- if (ib_agent_port_close(device, cur_port))
+error_agent:
+ if (ib_mad_port_close(device, i))
+ printk(KERN_ERR PFX "Couldn't close %s port %d\n",
+ device->name, i);
+
+error:
+ i--;
+
+ while (i >= start) {
+ if (ib_agent_port_close(device, i))
printk(KERN_ERR PFX "Couldn't close %s port %d "
"for agents\n",
- device->name, cur_port);
- if (ib_mad_port_close(device, cur_port))
+ device->name, i);
+ if (ib_mad_port_close(device, i))
printk(KERN_ERR PFX "Couldn't close %s port %d\n",
- device->name, cur_port);
+ device->name, i);
i--;
}
}
@@ -2754,7 +2715,6 @@ static int __init ib_mad_init_module(void)
int ret;
spin_lock_init(&ib_mad_port_list_lock);
- spin_lock_init(&ib_agent_port_list_lock);
ib_mad_cache = kmem_cache_create("ib_mad",
sizeof(struct ib_mad_private),
diff --git a/drivers/infiniband/core/mad_priv.h b/drivers/infiniband/core/mad_priv.h
index f1ba794e0daa..570f78682af3 100644
--- a/drivers/infiniband/core/mad_priv.h
+++ b/drivers/infiniband/core/mad_priv.h
@@ -118,9 +118,10 @@ struct ib_mad_send_wr_private {
struct ib_mad_list_head mad_list;
struct list_head agent_list;
struct ib_mad_agent_private *mad_agent_priv;
+ struct ib_mad_send_buf send_buf;
+ DECLARE_PCI_UNMAP_ADDR(mapping)
struct ib_send_wr send_wr;
struct ib_sge sg_list[IB_MAD_SEND_REQ_MAX_SG];
- u64 wr_id; /* client WR ID */
__be64 tid;
unsigned long timeout;
int retries;
@@ -141,10 +142,7 @@ struct ib_mad_local_private {
struct list_head completion_list;
struct ib_mad_private *mad_priv;
struct ib_mad_agent_private *recv_mad_agent;
- struct ib_send_wr send_wr;
- struct ib_sge sg_list[IB_MAD_SEND_REQ_MAX_SG];
- u64 wr_id; /* client WR ID */
- __be64 tid;
+ struct ib_mad_send_wr_private *mad_send_wr;
};
struct ib_mad_mgmt_method_table {
diff --git a/drivers/infiniband/core/mad_rmpp.c b/drivers/infiniband/core/mad_rmpp.c
index e23836d0e21b..3249e1d8c07b 100644
--- a/drivers/infiniband/core/mad_rmpp.c
+++ b/drivers/infiniband/core/mad_rmpp.c
@@ -103,12 +103,12 @@ void ib_cancel_rmpp_recvs(struct ib_mad_agent_private *agent)
static int data_offset(u8 mgmt_class)
{
if (mgmt_class == IB_MGMT_CLASS_SUBN_ADM)
- return offsetof(struct ib_sa_mad, data);
+ return IB_MGMT_SA_HDR;
else if ((mgmt_class >= IB_MGMT_CLASS_VENDOR_RANGE2_START) &&
(mgmt_class <= IB_MGMT_CLASS_VENDOR_RANGE2_END))
- return offsetof(struct ib_vendor_mad, data);
+ return IB_MGMT_VENDOR_HDR;
else
- return offsetof(struct ib_rmpp_mad, data);
+ return IB_MGMT_RMPP_HDR;
}
static void format_ack(struct ib_rmpp_mad *ack,
@@ -135,55 +135,52 @@ static void ack_recv(struct mad_rmpp_recv *rmpp_recv,
struct ib_mad_recv_wc *recv_wc)
{
struct ib_mad_send_buf *msg;
- struct ib_send_wr *bad_send_wr;
- int hdr_len, ret;
+ int ret;
- hdr_len = sizeof(struct ib_mad_hdr) + sizeof(struct ib_rmpp_hdr);
msg = ib_create_send_mad(&rmpp_recv->agent->agent, recv_wc->wc->src_qp,
- recv_wc->wc->pkey_index, rmpp_recv->ah, 1,
- hdr_len, sizeof(struct ib_rmpp_mad) - hdr_len,
- GFP_KERNEL);
+ recv_wc->wc->pkey_index, 1, IB_MGMT_RMPP_HDR,
+ IB_MGMT_RMPP_DATA, GFP_KERNEL);
if (!msg)
return;
- format_ack((struct ib_rmpp_mad *) msg->mad,
- (struct ib_rmpp_mad *) recv_wc->recv_buf.mad, rmpp_recv);
- ret = ib_post_send_mad(&rmpp_recv->agent->agent, &msg->send_wr,
- &bad_send_wr);
+ format_ack(msg->mad, (struct ib_rmpp_mad *) recv_wc->recv_buf.mad,
+ rmpp_recv);
+ msg->ah = rmpp_recv->ah;
+ ret = ib_post_send_mad(msg, NULL);
if (ret)
ib_free_send_mad(msg);
}
-static int alloc_response_msg(struct ib_mad_agent *agent,
- struct ib_mad_recv_wc *recv_wc,
- struct ib_mad_send_buf **msg)
+static struct ib_mad_send_buf *alloc_response_msg(struct ib_mad_agent *agent,
+ struct ib_mad_recv_wc *recv_wc)
{
- struct ib_mad_send_buf *m;
+ struct ib_mad_send_buf *msg;
struct ib_ah *ah;
- int hdr_len;
ah = ib_create_ah_from_wc(agent->qp->pd, recv_wc->wc,
recv_wc->recv_buf.grh, agent->port_num);
if (IS_ERR(ah))
- return PTR_ERR(ah);
-
- hdr_len = sizeof(struct ib_mad_hdr) + sizeof(struct ib_rmpp_hdr);
- m = ib_create_send_mad(agent, recv_wc->wc->src_qp,
- recv_wc->wc->pkey_index, ah, 1, hdr_len,
- sizeof(struct ib_rmpp_mad) - hdr_len,
- GFP_KERNEL);
- if (IS_ERR(m)) {
+ return (void *) ah;
+
+ msg = ib_create_send_mad(agent, recv_wc->wc->src_qp,
+ recv_wc->wc->pkey_index, 1,
+ IB_MGMT_RMPP_HDR, IB_MGMT_RMPP_DATA,
+ GFP_KERNEL);
+ if (IS_ERR(msg))
ib_destroy_ah(ah);
- return PTR_ERR(m);
- }
- *msg = m;
- return 0;
+ else
+ msg->ah = ah;
+
+ return msg;
}
-static void free_msg(struct ib_mad_send_buf *msg)
+void ib_rmpp_send_handler(struct ib_mad_send_wc *mad_send_wc)
{
- ib_destroy_ah(msg->send_wr.wr.ud.ah);
- ib_free_send_mad(msg);
+ struct ib_rmpp_mad *rmpp_mad = mad_send_wc->send_buf->mad;
+
+ if (rmpp_mad->rmpp_hdr.rmpp_type != IB_MGMT_RMPP_TYPE_ACK)
+ ib_destroy_ah(mad_send_wc->send_buf->ah);
+ ib_free_send_mad(mad_send_wc->send_buf);
}
static void nack_recv(struct ib_mad_agent_private *agent,
@@ -191,14 +188,13 @@ static void nack_recv(struct ib_mad_agent_private *agent,
{
struct ib_mad_send_buf *msg;
struct ib_rmpp_mad *rmpp_mad;
- struct ib_send_wr *bad_send_wr;
int ret;
- ret = alloc_response_msg(&agent->agent, recv_wc, &msg);
- if (ret)
+ msg = alloc_response_msg(&agent->agent, recv_wc);
+ if (IS_ERR(msg))
return;
- rmpp_mad = (struct ib_rmpp_mad *) msg->mad;
+ rmpp_mad = msg->mad;
memcpy(rmpp_mad, recv_wc->recv_buf.mad,
data_offset(recv_wc->recv_buf.mad->mad_hdr.mgmt_class));
@@ -210,9 +206,11 @@ static void nack_recv(struct ib_mad_agent_private *agent,
rmpp_mad->rmpp_hdr.seg_num = 0;
rmpp_mad->rmpp_hdr.paylen_newwin = 0;
- ret = ib_post_send_mad(&agent->agent, &msg->send_wr, &bad_send_wr);
- if (ret)
- free_msg(msg);
+ ret = ib_post_send_mad(msg, NULL);
+ if (ret) {
+ ib_destroy_ah(msg->ah);
+ ib_free_send_mad(msg);
+ }
}
static void recv_timeout_handler(void *data)
@@ -585,7 +583,7 @@ static int send_next_seg(struct ib_mad_send_wr_private *mad_send_wr)
int timeout;
u32 paylen;
- rmpp_mad = (struct ib_rmpp_mad *)mad_send_wr->send_wr.wr.ud.mad_hdr;
+ rmpp_mad = mad_send_wr->send_buf.mad;
ib_set_rmpp_flags(&rmpp_mad->rmpp_hdr, IB_MGMT_RMPP_FLAG_ACTIVE);
rmpp_mad->rmpp_hdr.seg_num = cpu_to_be32(mad_send_wr->seg_num);
@@ -612,7 +610,7 @@ static int send_next_seg(struct ib_mad_send_wr_private *mad_send_wr)
}
/* 2 seconds for an ACK until we can find the packet lifetime */
- timeout = mad_send_wr->send_wr.wr.ud.timeout_ms;
+ timeout = mad_send_wr->send_buf.timeout_ms;
if (!timeout || timeout > 2000)
mad_send_wr->timeout = msecs_to_jiffies(2000);
mad_send_wr->seg_num++;
@@ -640,7 +638,7 @@ static void abort_send(struct ib_mad_agent_private *agent, __be64 tid,
wc.status = IB_WC_REM_ABORT_ERR;
wc.vendor_err = rmpp_status;
- wc.wr_id = mad_send_wr->wr_id;
+ wc.send_buf = &mad_send_wr->send_buf;
ib_mad_complete_send_wr(mad_send_wr, &wc);
return;
out:
@@ -694,12 +692,12 @@ static void process_rmpp_ack(struct ib_mad_agent_private *agent,
if (seg_num > mad_send_wr->last_ack) {
mad_send_wr->last_ack = seg_num;
- mad_send_wr->retries = mad_send_wr->send_wr.wr.ud.retries;
+ mad_send_wr->retries = mad_send_wr->send_buf.retries;
}
mad_send_wr->newwin = newwin;
if (mad_send_wr->last_ack == mad_send_wr->total_seg) {
/* If no response is expected, the ACK completes the send */
- if (!mad_send_wr->send_wr.wr.ud.timeout_ms) {
+ if (!mad_send_wr->send_buf.timeout_ms) {
struct ib_mad_send_wc wc;
ib_mark_mad_done(mad_send_wr);
@@ -707,13 +705,13 @@ static void process_rmpp_ack(struct ib_mad_agent_private *agent,
wc.status = IB_WC_SUCCESS;
wc.vendor_err = 0;
- wc.wr_id = mad_send_wr->wr_id;
+ wc.send_buf = &mad_send_wr->send_buf;
ib_mad_complete_send_wr(mad_send_wr, &wc);
return;
}
if (mad_send_wr->refcount == 1)
- ib_reset_mad_timeout(mad_send_wr, mad_send_wr->
- send_wr.wr.ud.timeout_ms);
+ ib_reset_mad_timeout(mad_send_wr,
+ mad_send_wr->send_buf.timeout_ms);
} else if (mad_send_wr->refcount == 1 &&
mad_send_wr->seg_num < mad_send_wr->newwin &&
mad_send_wr->seg_num <= mad_send_wr->total_seg) {
@@ -842,7 +840,7 @@ int ib_send_rmpp_mad(struct ib_mad_send_wr_private *mad_send_wr)
struct ib_rmpp_mad *rmpp_mad;
int i, total_len, ret;
- rmpp_mad = (struct ib_rmpp_mad *)mad_send_wr->send_wr.wr.ud.mad_hdr;
+ rmpp_mad = mad_send_wr->send_buf.mad;
if (!(ib_get_rmpp_flags(&rmpp_mad->rmpp_hdr) &
IB_MGMT_RMPP_FLAG_ACTIVE))
return IB_RMPP_RESULT_UNHANDLED;
@@ -863,7 +861,7 @@ int ib_send_rmpp_mad(struct ib_mad_send_wr_private *mad_send_wr)
mad_send_wr->total_seg = (total_len - mad_send_wr->data_offset) /
(sizeof(struct ib_rmpp_mad) - mad_send_wr->data_offset);
- mad_send_wr->pad = total_len - offsetof(struct ib_rmpp_mad, data) -
+ mad_send_wr->pad = total_len - IB_MGMT_RMPP_HDR -
be32_to_cpu(rmpp_mad->rmpp_hdr.paylen_newwin);
/* We need to wait for the final ACK even if there isn't a response */
@@ -878,23 +876,15 @@ int ib_process_rmpp_send_wc(struct ib_mad_send_wr_private *mad_send_wr,
struct ib_mad_send_wc *mad_send_wc)
{
struct ib_rmpp_mad *rmpp_mad;
- struct ib_mad_send_buf *msg;
int ret;
- rmpp_mad = (struct ib_rmpp_mad *)mad_send_wr->send_wr.wr.ud.mad_hdr;
+ rmpp_mad = mad_send_wr->send_buf.mad;
if (!(ib_get_rmpp_flags(&rmpp_mad->rmpp_hdr) &
IB_MGMT_RMPP_FLAG_ACTIVE))
return IB_RMPP_RESULT_UNHANDLED; /* RMPP not active */
- if (rmpp_mad->rmpp_hdr.rmpp_type != IB_MGMT_RMPP_TYPE_DATA) {
- msg = (struct ib_mad_send_buf *) (unsigned long)
- mad_send_wc->wr_id;
- if (rmpp_mad->rmpp_hdr.rmpp_type == IB_MGMT_RMPP_TYPE_ACK)
- ib_free_send_mad(msg);
- else
- free_msg(msg);
+ if (rmpp_mad->rmpp_hdr.rmpp_type != IB_MGMT_RMPP_TYPE_DATA)
return IB_RMPP_RESULT_INTERNAL; /* ACK, STOP, or ABORT */
- }
if (mad_send_wc->status != IB_WC_SUCCESS ||
mad_send_wr->status != IB_WC_SUCCESS)
@@ -905,7 +895,7 @@ int ib_process_rmpp_send_wc(struct ib_mad_send_wr_private *mad_send_wr,
if (mad_send_wr->last_ack == mad_send_wr->total_seg) {
mad_send_wr->timeout =
- msecs_to_jiffies(mad_send_wr->send_wr.wr.ud.timeout_ms);
+ msecs_to_jiffies(mad_send_wr->send_buf.timeout_ms);
return IB_RMPP_RESULT_PROCESSED; /* Send done */
}
@@ -926,7 +916,7 @@ int ib_retry_rmpp(struct ib_mad_send_wr_private *mad_send_wr)
struct ib_rmpp_mad *rmpp_mad;
int ret;
- rmpp_mad = (struct ib_rmpp_mad *)mad_send_wr->send_wr.wr.ud.mad_hdr;
+ rmpp_mad = mad_send_wr->send_buf.mad;
if (!(ib_get_rmpp_flags(&rmpp_mad->rmpp_hdr) &
IB_MGMT_RMPP_FLAG_ACTIVE))
return IB_RMPP_RESULT_UNHANDLED; /* RMPP not active */
diff --git a/drivers/infiniband/core/mad_rmpp.h b/drivers/infiniband/core/mad_rmpp.h
index c4924dfb8e75..f0616fd22494 100644
--- a/drivers/infiniband/core/mad_rmpp.h
+++ b/drivers/infiniband/core/mad_rmpp.h
@@ -51,6 +51,8 @@ ib_process_rmpp_recv_wc(struct ib_mad_agent_private *agent,
int ib_process_rmpp_send_wc(struct ib_mad_send_wr_private *mad_send_wr,
struct ib_mad_send_wc *mad_send_wc);
+void ib_rmpp_send_handler(struct ib_mad_send_wc *mad_send_wc);
+
void ib_cancel_rmpp_recvs(struct ib_mad_agent_private *agent);
int ib_retry_rmpp(struct ib_mad_send_wr_private *mad_send_wr);
diff --git a/drivers/infiniband/core/packer.c b/drivers/infiniband/core/packer.c
index 35df5010e723..c972d7235764 100644
--- a/drivers/infiniband/core/packer.c
+++ b/drivers/infiniband/core/packer.c
@@ -33,6 +33,8 @@
* $Id: packer.c 1349 2004-12-16 21:09:43Z roland $
*/
+#include <linux/string.h>
+
#include <rdma/ib_pack.h>
static u64 value_read(int offset, int size, void *structure)
diff --git a/drivers/infiniband/core/sa_query.c b/drivers/infiniband/core/sa_query.c
index 262618210c1c..acda7d63d6fe 100644
--- a/drivers/infiniband/core/sa_query.c
+++ b/drivers/infiniband/core/sa_query.c
@@ -43,6 +43,7 @@
#include <linux/dma-mapping.h>
#include <linux/kref.h>
#include <linux/idr.h>
+#include <linux/workqueue.h>
#include <rdma/ib_pack.h>
#include <rdma/ib_sa.h>
@@ -73,11 +74,10 @@ struct ib_sa_device {
struct ib_sa_query {
void (*callback)(struct ib_sa_query *, int, struct ib_sa_mad *);
void (*release)(struct ib_sa_query *);
- struct ib_sa_port *port;
- struct ib_sa_mad *mad;
- struct ib_sa_sm_ah *sm_ah;
- DECLARE_PCI_UNMAP_ADDR(mapping)
- int id;
+ struct ib_sa_port *port;
+ struct ib_mad_send_buf *mad_buf;
+ struct ib_sa_sm_ah *sm_ah;
+ int id;
};
struct ib_sa_service_query {
@@ -426,6 +426,7 @@ void ib_sa_cancel_query(int id, struct ib_sa_query *query)
{
unsigned long flags;
struct ib_mad_agent *agent;
+ struct ib_mad_send_buf *mad_buf;
spin_lock_irqsave(&idr_lock, flags);
if (idr_find(&query_idr, id) != query) {
@@ -433,9 +434,10 @@ void ib_sa_cancel_query(int id, struct ib_sa_query *query)
return;
}
agent = query->port->agent;
+ mad_buf = query->mad_buf;
spin_unlock_irqrestore(&idr_lock, flags);
- ib_cancel_mad(agent, id);
+ ib_cancel_mad(agent, mad_buf);
}
EXPORT_SYMBOL(ib_sa_cancel_query);
@@ -457,71 +459,46 @@ static void init_mad(struct ib_sa_mad *mad, struct ib_mad_agent *agent)
static int send_mad(struct ib_sa_query *query, int timeout_ms)
{
- struct ib_sa_port *port = query->port;
unsigned long flags;
- int ret;
- struct ib_sge gather_list;
- struct ib_send_wr *bad_wr, wr = {
- .opcode = IB_WR_SEND,
- .sg_list = &gather_list,
- .num_sge = 1,
- .send_flags = IB_SEND_SIGNALED,
- .wr = {
- .ud = {
- .mad_hdr = &query->mad->mad_hdr,
- .remote_qpn = 1,
- .remote_qkey = IB_QP1_QKEY,
- .timeout_ms = timeout_ms,
- }
- }
- };
+ int ret, id;
retry:
if (!idr_pre_get(&query_idr, GFP_ATOMIC))
return -ENOMEM;
spin_lock_irqsave(&idr_lock, flags);
- ret = idr_get_new(&query_idr, query, &query->id);
+ ret = idr_get_new(&query_idr, query, &id);
spin_unlock_irqrestore(&idr_lock, flags);
if (ret == -EAGAIN)
goto retry;
if (ret)
return ret;
- wr.wr_id = query->id;
+ query->mad_buf->timeout_ms = timeout_ms;
+ query->mad_buf->context[0] = query;
+ query->id = id;
- spin_lock_irqsave(&port->ah_lock, flags);
- kref_get(&port->sm_ah->ref);
- query->sm_ah = port->sm_ah;
- wr.wr.ud.ah = port->sm_ah->ah;
- spin_unlock_irqrestore(&port->ah_lock, flags);
+ spin_lock_irqsave(&query->port->ah_lock, flags);
+ kref_get(&query->port->sm_ah->ref);
+ query->sm_ah = query->port->sm_ah;
+ spin_unlock_irqrestore(&query->port->ah_lock, flags);
- gather_list.addr = dma_map_single(port->agent->device->dma_device,
- query->mad,
- sizeof (struct ib_sa_mad),
- DMA_TO_DEVICE);
- gather_list.length = sizeof (struct ib_sa_mad);
- gather_list.lkey = port->agent->mr->lkey;
- pci_unmap_addr_set(query, mapping, gather_list.addr);
+ query->mad_buf->ah = query->sm_ah->ah;
- ret = ib_post_send_mad(port->agent, &wr, &bad_wr);
+ ret = ib_post_send_mad(query->mad_buf, NULL);
if (ret) {
- dma_unmap_single(port->agent->device->dma_device,
- pci_unmap_addr(query, mapping),
- sizeof (struct ib_sa_mad),
- DMA_TO_DEVICE);
- kref_put(&query->sm_ah->ref, free_sm_ah);
spin_lock_irqsave(&idr_lock, flags);
- idr_remove(&query_idr, query->id);
+ idr_remove(&query_idr, id);
spin_unlock_irqrestore(&idr_lock, flags);
+
+ kref_put(&query->sm_ah->ref, free_sm_ah);
}
/*
* It's not safe to dereference query any more, because the
* send may already have completed and freed the query in
- * another context. So use wr.wr_id, which has a copy of the
- * query's id.
+ * another context.
*/
- return ret ? ret : wr.wr_id;
+ return ret ? ret : id;
}
static void ib_sa_path_rec_callback(struct ib_sa_query *sa_query,
@@ -543,7 +520,6 @@ static void ib_sa_path_rec_callback(struct ib_sa_query *sa_query,
static void ib_sa_path_rec_release(struct ib_sa_query *sa_query)
{
- kfree(sa_query->mad);
kfree(container_of(sa_query, struct ib_sa_path_query, sa_query));
}
@@ -583,43 +559,58 @@ int ib_sa_path_rec_get(struct ib_device *device, u8 port_num,
{
struct ib_sa_path_query *query;
struct ib_sa_device *sa_dev = ib_get_client_data(device, &sa_client);
- struct ib_sa_port *port = &sa_dev->port[port_num - sa_dev->start_port];
- struct ib_mad_agent *agent = port->agent;
+ struct ib_sa_port *port;
+ struct ib_mad_agent *agent;
+ struct ib_sa_mad *mad;
int ret;
+ if (!sa_dev)
+ return -ENODEV;
+
+ port = &sa_dev->port[port_num - sa_dev->start_port];
+ agent = port->agent;
+
query = kmalloc(sizeof *query, gfp_mask);
if (!query)
return -ENOMEM;
- query->sa_query.mad = kmalloc(sizeof *query->sa_query.mad, gfp_mask);
- if (!query->sa_query.mad) {
- kfree(query);
- return -ENOMEM;
+
+ query->sa_query.mad_buf = ib_create_send_mad(agent, 1, 0,
+ 0, IB_MGMT_SA_HDR,
+ IB_MGMT_SA_DATA, gfp_mask);
+ if (!query->sa_query.mad_buf) {
+ ret = -ENOMEM;
+ goto err1;
}
query->callback = callback;
query->context = context;
- init_mad(query->sa_query.mad, agent);
+ mad = query->sa_query.mad_buf->mad;
+ init_mad(mad, agent);
- query->sa_query.callback = callback ? ib_sa_path_rec_callback : NULL;
- query->sa_query.release = ib_sa_path_rec_release;
- query->sa_query.port = port;
- query->sa_query.mad->mad_hdr.method = IB_MGMT_METHOD_GET;
- query->sa_query.mad->mad_hdr.attr_id = cpu_to_be16(IB_SA_ATTR_PATH_REC);
- query->sa_query.mad->sa_hdr.comp_mask = comp_mask;
+ query->sa_query.callback = callback ? ib_sa_path_rec_callback : NULL;
+ query->sa_query.release = ib_sa_path_rec_release;
+ query->sa_query.port = port;
+ mad->mad_hdr.method = IB_MGMT_METHOD_GET;
+ mad->mad_hdr.attr_id = cpu_to_be16(IB_SA_ATTR_PATH_REC);
+ mad->sa_hdr.comp_mask = comp_mask;
- ib_pack(path_rec_table, ARRAY_SIZE(path_rec_table),
- rec, query->sa_query.mad->data);
+ ib_pack(path_rec_table, ARRAY_SIZE(path_rec_table), rec, mad->data);
*sa_query = &query->sa_query;
ret = send_mad(&query->sa_query, timeout_ms);
- if (ret < 0) {
- *sa_query = NULL;
- kfree(query->sa_query.mad);
- kfree(query);
- }
+ if (ret < 0)
+ goto err2;
+
+ return ret;
+err2:
+ *sa_query = NULL;
+ ib_free_send_mad(query->sa_query.mad_buf);
+
+err1:
+ kfree(query);
return ret;
}
EXPORT_SYMBOL(ib_sa_path_rec_get);
@@ -643,7 +634,6 @@ static void ib_sa_service_rec_callback(struct ib_sa_query *sa_query,
static void ib_sa_service_rec_release(struct ib_sa_query *sa_query)
{
- kfree(sa_query->mad);
kfree(container_of(sa_query, struct ib_sa_service_query, sa_query));
}
@@ -685,10 +675,17 @@ int ib_sa_service_rec_query(struct ib_device *device, u8 port_num, u8 method,
{
struct ib_sa_service_query *query;
struct ib_sa_device *sa_dev = ib_get_client_data(device, &sa_client);
- struct ib_sa_port *port = &sa_dev->port[port_num - sa_dev->start_port];
- struct ib_mad_agent *agent = port->agent;
+ struct ib_sa_port *port;
+ struct ib_mad_agent *agent;
+ struct ib_sa_mad *mad;
int ret;
+ if (!sa_dev)
+ return -ENODEV;
+
+ port = &sa_dev->port[port_num - sa_dev->start_port];
+ agent = port->agent;
+
if (method != IB_MGMT_METHOD_GET &&
method != IB_MGMT_METHOD_SET &&
method != IB_SA_METHOD_DELETE)
@@ -697,37 +694,45 @@ int ib_sa_service_rec_query(struct ib_device *device, u8 port_num, u8 method,
query = kmalloc(sizeof *query, gfp_mask);
if (!query)
return -ENOMEM;
- query->sa_query.mad = kmalloc(sizeof *query->sa_query.mad, gfp_mask);
- if (!query->sa_query.mad) {
- kfree(query);
- return -ENOMEM;
+
+ query->sa_query.mad_buf = ib_create_send_mad(agent, 1, 0,
+ 0, IB_MGMT_SA_HDR,
+ IB_MGMT_SA_DATA, gfp_mask);
+ if (!query->sa_query.mad_buf) {
+ ret = -ENOMEM;
+ goto err1;
}
query->callback = callback;
query->context = context;
- init_mad(query->sa_query.mad, agent);
+ mad = query->sa_query.mad_buf->mad;
+ init_mad(mad, agent);
- query->sa_query.callback = callback ? ib_sa_service_rec_callback : NULL;
- query->sa_query.release = ib_sa_service_rec_release;
- query->sa_query.port = port;
- query->sa_query.mad->mad_hdr.method = method;
- query->sa_query.mad->mad_hdr.attr_id =
- cpu_to_be16(IB_SA_ATTR_SERVICE_REC);
- query->sa_query.mad->sa_hdr.comp_mask = comp_mask;
+ query->sa_query.callback = callback ? ib_sa_service_rec_callback : NULL;
+ query->sa_query.release = ib_sa_service_rec_release;
+ query->sa_query.port = port;
+ mad->mad_hdr.method = method;
+ mad->mad_hdr.attr_id = cpu_to_be16(IB_SA_ATTR_SERVICE_REC);
+ mad->sa_hdr.comp_mask = comp_mask;
ib_pack(service_rec_table, ARRAY_SIZE(service_rec_table),
- rec, query->sa_query.mad->data);
+ rec, mad->data);
*sa_query = &query->sa_query;
ret = send_mad(&query->sa_query, timeout_ms);
- if (ret < 0) {
- *sa_query = NULL;
- kfree(query->sa_query.mad);
- kfree(query);
- }
+ if (ret < 0)
+ goto err2;
+
+ return ret;
+err2:
+ *sa_query = NULL;
+ ib_free_send_mad(query->sa_query.mad_buf);
+
+err1:
+ kfree(query);
return ret;
}
EXPORT_SYMBOL(ib_sa_service_rec_query);
@@ -751,7 +756,6 @@ static void ib_sa_mcmember_rec_callback(struct ib_sa_query *sa_query,
static void ib_sa_mcmember_rec_release(struct ib_sa_query *sa_query)
{
- kfree(sa_query->mad);
kfree(container_of(sa_query, struct ib_sa_mcmember_query, sa_query));
}
@@ -768,60 +772,69 @@ int ib_sa_mcmember_rec_query(struct ib_device *device, u8 port_num,
{
struct ib_sa_mcmember_query *query;
struct ib_sa_device *sa_dev = ib_get_client_data(device, &sa_client);
- struct ib_sa_port *port = &sa_dev->port[port_num - sa_dev->start_port];
- struct ib_mad_agent *agent = port->agent;
+ struct ib_sa_port *port;
+ struct ib_mad_agent *agent;
+ struct ib_sa_mad *mad;
int ret;
+ if (!sa_dev)
+ return -ENODEV;
+
+ port = &sa_dev->port[port_num - sa_dev->start_port];
+ agent = port->agent;
+
query = kmalloc(sizeof *query, gfp_mask);
if (!query)
return -ENOMEM;
- query->sa_query.mad = kmalloc(sizeof *query->sa_query.mad, gfp_mask);
- if (!query->sa_query.mad) {
- kfree(query);
- return -ENOMEM;
+
+ query->sa_query.mad_buf = ib_create_send_mad(agent, 1, 0,
+ 0, IB_MGMT_SA_HDR,
+ IB_MGMT_SA_DATA, gfp_mask);
+ if (!query->sa_query.mad_buf) {
+ ret = -ENOMEM;
+ goto err1;
}
query->callback = callback;
query->context = context;
- init_mad(query->sa_query.mad, agent);
+ mad = query->sa_query.mad_buf->mad;
+ init_mad(mad, agent);
- query->sa_query.callback = callback ? ib_sa_mcmember_rec_callback : NULL;
- query->sa_query.release = ib_sa_mcmember_rec_release;
- query->sa_query.port = port;
- query->sa_query.mad->mad_hdr.method = method;
- query->sa_query.mad->mad_hdr.attr_id = cpu_to_be16(IB_SA_ATTR_MC_MEMBER_REC);
- query->sa_query.mad->sa_hdr.comp_mask = comp_mask;
+ query->sa_query.callback = callback ? ib_sa_mcmember_rec_callback : NULL;
+ query->sa_query.release = ib_sa_mcmember_rec_release;
+ query->sa_query.port = port;
+ mad->mad_hdr.method = method;
+ mad->mad_hdr.attr_id = cpu_to_be16(IB_SA_ATTR_MC_MEMBER_REC);
+ mad->sa_hdr.comp_mask = comp_mask;
ib_pack(mcmember_rec_table, ARRAY_SIZE(mcmember_rec_table),
- rec, query->sa_query.mad->data);
+ rec, mad->data);
*sa_query = &query->sa_query;
ret = send_mad(&query->sa_query, timeout_ms);
- if (ret < 0) {
- *sa_query = NULL;
- kfree(query->sa_query.mad);
- kfree(query);
- }
+ if (ret < 0)
+ goto err2;
return ret;
+
+err2:
+ *sa_query = NULL;
+ ib_free_send_mad(query->sa_query.mad_buf);
+
+err1:
+ kfree(query);
+ return ret;
}
EXPORT_SYMBOL(ib_sa_mcmember_rec_query);
static void send_handler(struct ib_mad_agent *agent,
struct ib_mad_send_wc *mad_send_wc)
{
- struct ib_sa_query *query;
+ struct ib_sa_query *query = mad_send_wc->send_buf->context[0];
unsigned long flags;
- spin_lock_irqsave(&idr_lock, flags);
- query = idr_find(&query_idr, mad_send_wc->wr_id);
- spin_unlock_irqrestore(&idr_lock, flags);
-
- if (!query)
- return;
-
if (query->callback)
switch (mad_send_wc->status) {
case IB_WC_SUCCESS:
@@ -838,30 +851,25 @@ static void send_handler(struct ib_mad_agent *agent,
break;
}
- dma_unmap_single(agent->device->dma_device,
- pci_unmap_addr(query, mapping),
- sizeof (struct ib_sa_mad),
- DMA_TO_DEVICE);
- kref_put(&query->sm_ah->ref, free_sm_ah);
-
- query->release(query);
-
spin_lock_irqsave(&idr_lock, flags);
- idr_remove(&query_idr, mad_send_wc->wr_id);
+ idr_remove(&query_idr, query->id);
spin_unlock_irqrestore(&idr_lock, flags);
+
+ ib_free_send_mad(mad_send_wc->send_buf);
+ kref_put(&query->sm_ah->ref, free_sm_ah);
+ query->release(query);
}
static void recv_handler(struct ib_mad_agent *mad_agent,
struct ib_mad_recv_wc *mad_recv_wc)
{
struct ib_sa_query *query;
- unsigned long flags;
+ struct ib_mad_send_buf *mad_buf;
- spin_lock_irqsave(&idr_lock, flags);
- query = idr_find(&query_idr, mad_recv_wc->wc->wr_id);
- spin_unlock_irqrestore(&idr_lock, flags);
+ mad_buf = (void *) (unsigned long) mad_recv_wc->wc->wr_id;
+ query = mad_buf->context[0];
- if (query && query->callback) {
+ if (query->callback) {
if (mad_recv_wc->wc->status == IB_WC_SUCCESS)
query->callback(query,
mad_recv_wc->recv_buf.mad->mad_hdr.status ?
@@ -975,6 +983,7 @@ static int __init ib_sa_init(void)
static void __exit ib_sa_cleanup(void)
{
ib_unregister_client(&sa_client);
+ idr_destroy(&query_idr);
}
module_init(ib_sa_init);
diff --git a/drivers/infiniband/core/smi.h b/drivers/infiniband/core/smi.h
index db25503a0736..2b3c40198f81 100644
--- a/drivers/infiniband/core/smi.h
+++ b/drivers/infiniband/core/smi.h
@@ -39,6 +39,8 @@
#ifndef __SMI_H_
#define __SMI_H_
+#include <rdma/ib_smi.h>
+
int smi_handle_dr_smp_recv(struct ib_smp *smp,
u8 node_type,
int port_num,
diff --git a/drivers/infiniband/core/sysfs.c b/drivers/infiniband/core/sysfs.c
index 211ba3223f65..08648b1a387e 100644
--- a/drivers/infiniband/core/sysfs.c
+++ b/drivers/infiniband/core/sysfs.c
@@ -36,6 +36,9 @@
#include "core_priv.h"
+#include <linux/slab.h>
+#include <linux/string.h>
+
#include <rdma/ib_mad.h>
struct ib_port {
@@ -65,6 +68,11 @@ struct port_table_attribute {
int index;
};
+static inline int ibdev_is_alive(const struct ib_device *dev)
+{
+ return dev->reg_state == IB_DEV_REGISTERED;
+}
+
static ssize_t port_attr_show(struct kobject *kobj,
struct attribute *attr, char *buf)
{
@@ -74,6 +82,8 @@ static ssize_t port_attr_show(struct kobject *kobj,
if (!port_attr->show)
return -EIO;
+ if (!ibdev_is_alive(p->ibdev))
+ return -ENODEV;
return port_attr->show(p, port_attr, buf);
}
@@ -300,14 +310,13 @@ static ssize_t show_pma_counter(struct ib_port *p, struct port_attribute *attr,
if (!p->ibdev->process_mad)
return sprintf(buf, "N/A (no PMA)\n");
- in_mad = kmalloc(sizeof *in_mad, GFP_KERNEL);
+ in_mad = kzalloc(sizeof *in_mad, GFP_KERNEL);
out_mad = kmalloc(sizeof *in_mad, GFP_KERNEL);
if (!in_mad || !out_mad) {
ret = -ENOMEM;
goto out;
}
- memset(in_mad, 0, sizeof *in_mad);
in_mad->mad_hdr.base_version = 1;
in_mad->mad_hdr.mgmt_class = IB_MGMT_CLASS_PERF_MGMT;
in_mad->mad_hdr.class_version = 1;
@@ -501,10 +510,9 @@ static int add_port(struct ib_device *device, int port_num)
if (ret)
return ret;
- p = kmalloc(sizeof *p, GFP_KERNEL);
+ p = kzalloc(sizeof *p, GFP_KERNEL);
if (!p)
return -ENOMEM;
- memset(p, 0, sizeof *p);
p->ibdev = device;
p->port_num = port_num;
@@ -581,6 +589,9 @@ static ssize_t show_node_type(struct class_device *cdev, char *buf)
{
struct ib_device *dev = container_of(cdev, struct ib_device, class_dev);
+ if (!ibdev_is_alive(dev))
+ return -ENODEV;
+
switch (dev->node_type) {
case IB_NODE_CA: return sprintf(buf, "%d: CA\n", dev->node_type);
case IB_NODE_SWITCH: return sprintf(buf, "%d: switch\n", dev->node_type);
@@ -595,6 +606,9 @@ static ssize_t show_sys_image_guid(struct class_device *cdev, char *buf)
struct ib_device_attr attr;
ssize_t ret;
+ if (!ibdev_is_alive(dev))
+ return -ENODEV;
+
ret = ib_query_device(dev, &attr);
if (ret)
return ret;
@@ -612,6 +626,9 @@ static ssize_t show_node_guid(struct class_device *cdev, char *buf)
struct ib_device_attr attr;
ssize_t ret;
+ if (!ibdev_is_alive(dev))
+ return -ENODEV;
+
ret = ib_query_device(dev, &attr);
if (ret)
return ret;
diff --git a/drivers/infiniband/core/ucm.c b/drivers/infiniband/core/ucm.c
index d0f0b0a2edd3..6e15787d1de1 100644
--- a/drivers/infiniband/core/ucm.c
+++ b/drivers/infiniband/core/ucm.c
@@ -41,37 +41,81 @@
#include <linux/file.h>
#include <linux/mount.h>
#include <linux/cdev.h>
+#include <linux/idr.h>
#include <asm/uaccess.h>
-#include "ucm.h"
+#include <rdma/ib_cm.h>
+#include <rdma/ib_user_cm.h>
MODULE_AUTHOR("Libor Michalek");
MODULE_DESCRIPTION("InfiniBand userspace Connection Manager access");
MODULE_LICENSE("Dual BSD/GPL");
-static int ucm_debug_level;
+struct ib_ucm_device {
+ int devnum;
+ struct cdev dev;
+ struct class_device class_dev;
+ struct ib_device *ib_dev;
+};
+
+struct ib_ucm_file {
+ struct semaphore mutex;
+ struct file *filp;
+ struct ib_ucm_device *device;
+
+ struct list_head ctxs;
+ struct list_head events;
+ wait_queue_head_t poll_wait;
+};
+
+struct ib_ucm_context {
+ int id;
+ wait_queue_head_t wait;
+ atomic_t ref;
+ int events_reported;
+
+ struct ib_ucm_file *file;
+ struct ib_cm_id *cm_id;
+ __u64 uid;
+
+ struct list_head events; /* list of pending events. */
+ struct list_head file_list; /* member in file ctx list */
+};
+
+struct ib_ucm_event {
+ struct ib_ucm_context *ctx;
+ struct list_head file_list; /* member in file event list */
+ struct list_head ctx_list; /* member in ctx event list */
-module_param_named(debug_level, ucm_debug_level, int, 0644);
-MODULE_PARM_DESC(debug_level, "Enable debug tracing if > 0");
+ struct ib_cm_id *cm_id;
+ struct ib_ucm_event_resp resp;
+ void *data;
+ void *info;
+ int data_len;
+ int info_len;
+};
enum {
IB_UCM_MAJOR = 231,
- IB_UCM_MINOR = 255
+ IB_UCM_BASE_MINOR = 224,
+ IB_UCM_MAX_DEVICES = 32
};
-#define IB_UCM_DEV MKDEV(IB_UCM_MAJOR, IB_UCM_MINOR)
+#define IB_UCM_BASE_DEV MKDEV(IB_UCM_MAJOR, IB_UCM_BASE_MINOR)
-#define PFX "UCM: "
+static void ib_ucm_add_one(struct ib_device *device);
+static void ib_ucm_remove_one(struct ib_device *device);
-#define ucm_dbg(format, arg...) \
- do { \
- if (ucm_debug_level > 0) \
- printk(KERN_DEBUG PFX format, ## arg); \
- } while (0)
+static struct ib_client ucm_client = {
+ .name = "ucm",
+ .add = ib_ucm_add_one,
+ .remove = ib_ucm_remove_one
+};
-static struct semaphore ctx_id_mutex;
-static struct idr ctx_id_table;
+static DECLARE_MUTEX(ctx_id_mutex);
+static DEFINE_IDR(ctx_id_table);
+static DECLARE_BITMAP(dev_map, IB_UCM_MAX_DEVICES);
static struct ib_ucm_context *ib_ucm_ctx_get(struct ib_ucm_file *file, int id)
{
@@ -128,11 +172,10 @@ static struct ib_ucm_context *ib_ucm_ctx_alloc(struct ib_ucm_file *file)
struct ib_ucm_context *ctx;
int result;
- ctx = kmalloc(sizeof(*ctx), GFP_KERNEL);
+ ctx = kzalloc(sizeof *ctx, GFP_KERNEL);
if (!ctx)
return NULL;
- memset(ctx, 0, sizeof *ctx);
atomic_set(&ctx->ref, 1);
init_waitqueue_head(&ctx->wait);
ctx->file = file;
@@ -152,17 +195,13 @@ static struct ib_ucm_context *ib_ucm_ctx_alloc(struct ib_ucm_file *file)
goto error;
list_add_tail(&ctx->file_list, &file->ctxs);
- ucm_dbg("Allocated CM ID <%d>\n", ctx->id);
return ctx;
error:
kfree(ctx);
return NULL;
}
-/*
- * Event portion of the API, handle CM events
- * and allow event polling.
- */
+
static void ib_ucm_event_path_get(struct ib_ucm_path_rec *upath,
struct ib_sa_path_rec *kpath)
{
@@ -209,6 +248,7 @@ static void ib_ucm_event_req_get(struct ib_ucm_req_event_resp *ureq,
ureq->retry_count = kreq->retry_count;
ureq->rnr_retry_count = kreq->rnr_retry_count;
ureq->srq = kreq->srq;
+ ureq->port = kreq->port;
ib_ucm_event_path_get(&ureq->primary_path, kreq->primary_path);
ib_ucm_event_path_get(&ureq->alternate_path, kreq->alternate_path);
@@ -295,6 +335,8 @@ static int ib_ucm_event_process(struct ib_cm_event *evt,
case IB_CM_SIDR_REQ_RECEIVED:
uvt->resp.u.sidr_req_resp.pkey =
evt->param.sidr_req_rcvd.pkey;
+ uvt->resp.u.sidr_req_resp.port =
+ evt->param.sidr_req_rcvd.port;
uvt->data_len = IB_CM_SIDR_REQ_PRIVATE_DATA_SIZE;
break;
case IB_CM_SIDR_REP_RECEIVED:
@@ -343,11 +385,10 @@ static int ib_ucm_event_handler(struct ib_cm_id *cm_id,
ctx = cm_id->context;
- uevent = kmalloc(sizeof(*uevent), GFP_KERNEL);
+ uevent = kzalloc(sizeof *uevent, GFP_KERNEL);
if (!uevent)
goto err1;
- memset(uevent, 0, sizeof(*uevent));
uevent->ctx = ctx;
uevent->cm_id = cm_id;
uevent->resp.uid = ctx->uid;
@@ -387,9 +428,7 @@ static ssize_t ib_ucm_event(struct ib_ucm_file *file,
if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
return -EFAULT;
- /*
- * wait
- */
+
down(&file->mutex);
while (list_empty(&file->events)) {
@@ -471,7 +510,6 @@ done:
return result;
}
-
static ssize_t ib_ucm_create_id(struct ib_ucm_file *file,
const char __user *inbuf,
int in_len, int out_len)
@@ -494,29 +532,27 @@ static ssize_t ib_ucm_create_id(struct ib_ucm_file *file,
return -ENOMEM;
ctx->uid = cmd.uid;
- ctx->cm_id = ib_create_cm_id(ib_ucm_event_handler, ctx);
+ ctx->cm_id = ib_create_cm_id(file->device->ib_dev,
+ ib_ucm_event_handler, ctx);
if (IS_ERR(ctx->cm_id)) {
result = PTR_ERR(ctx->cm_id);
- goto err;
+ goto err1;
}
resp.id = ctx->id;
if (copy_to_user((void __user *)(unsigned long)cmd.response,
&resp, sizeof(resp))) {
result = -EFAULT;
- goto err;
+ goto err2;
}
-
return 0;
-err:
+err2:
+ ib_destroy_cm_id(ctx->cm_id);
+err1:
down(&ctx_id_mutex);
idr_remove(&ctx_id_table, ctx->id);
up(&ctx_id_mutex);
-
- if (!IS_ERR(ctx->cm_id))
- ib_destroy_cm_id(ctx->cm_id);
-
kfree(ctx);
return result;
}
@@ -1184,9 +1220,6 @@ static ssize_t ib_ucm_write(struct file *filp, const char __user *buf,
if (copy_from_user(&hdr, buf, sizeof(hdr)))
return -EFAULT;
- ucm_dbg("Write. cmd <%d> in <%d> out <%d> len <%Zu>\n",
- hdr.cmd, hdr.in, hdr.out, len);
-
if (hdr.cmd < 0 || hdr.cmd >= ARRAY_SIZE(ucm_cmd_table))
return -EINVAL;
@@ -1231,8 +1264,7 @@ static int ib_ucm_open(struct inode *inode, struct file *filp)
filp->private_data = file;
file->filp = filp;
-
- ucm_dbg("Created struct\n");
+ file->device = container_of(inode->i_cdev, struct ib_ucm_device, dev);
return 0;
}
@@ -1263,7 +1295,17 @@ static int ib_ucm_close(struct inode *inode, struct file *filp)
return 0;
}
-static struct file_operations ib_ucm_fops = {
+static void ib_ucm_release_class_dev(struct class_device *class_dev)
+{
+ struct ib_ucm_device *dev;
+
+ dev = container_of(class_dev, struct ib_ucm_device, class_dev);
+ cdev_del(&dev->dev);
+ clear_bit(dev->devnum, dev_map);
+ kfree(dev);
+}
+
+static struct file_operations ucm_fops = {
.owner = THIS_MODULE,
.open = ib_ucm_open,
.release = ib_ucm_close,
@@ -1271,55 +1313,141 @@ static struct file_operations ib_ucm_fops = {
.poll = ib_ucm_poll,
};
+static struct class ucm_class = {
+ .name = "infiniband_cm",
+ .release = ib_ucm_release_class_dev
+};
-static struct class *ib_ucm_class;
-static struct cdev ib_ucm_cdev;
+static ssize_t show_dev(struct class_device *class_dev, char *buf)
+{
+ struct ib_ucm_device *dev;
+
+ dev = container_of(class_dev, struct ib_ucm_device, class_dev);
+ return print_dev_t(buf, dev->dev.dev);
+}
+static CLASS_DEVICE_ATTR(dev, S_IRUGO, show_dev, NULL);
-static int __init ib_ucm_init(void)
+static ssize_t show_ibdev(struct class_device *class_dev, char *buf)
{
- int result;
+ struct ib_ucm_device *dev;
+
+ dev = container_of(class_dev, struct ib_ucm_device, class_dev);
+ return sprintf(buf, "%s\n", dev->ib_dev->name);
+}
+static CLASS_DEVICE_ATTR(ibdev, S_IRUGO, show_ibdev, NULL);
- result = register_chrdev_region(IB_UCM_DEV, 1, "infiniband_cm");
- if (result) {
- ucm_dbg("Error <%d> registering dev\n", result);
- goto err_chr;
- }
+static void ib_ucm_add_one(struct ib_device *device)
+{
+ struct ib_ucm_device *ucm_dev;
+
+ if (!device->alloc_ucontext)
+ return;
+
+ ucm_dev = kzalloc(sizeof *ucm_dev, GFP_KERNEL);
+ if (!ucm_dev)
+ return;
- cdev_init(&ib_ucm_cdev, &ib_ucm_fops);
+ ucm_dev->ib_dev = device;
+
+ ucm_dev->devnum = find_first_zero_bit(dev_map, IB_UCM_MAX_DEVICES);
+ if (ucm_dev->devnum >= IB_UCM_MAX_DEVICES)
+ goto err;
+
+ set_bit(ucm_dev->devnum, dev_map);
+
+ cdev_init(&ucm_dev->dev, &ucm_fops);
+ ucm_dev->dev.owner = THIS_MODULE;
+ kobject_set_name(&ucm_dev->dev.kobj, "ucm%d", ucm_dev->devnum);
+ if (cdev_add(&ucm_dev->dev, IB_UCM_BASE_DEV + ucm_dev->devnum, 1))
+ goto err;
- result = cdev_add(&ib_ucm_cdev, IB_UCM_DEV, 1);
- if (result) {
- ucm_dbg("Error <%d> adding cdev\n", result);
+ ucm_dev->class_dev.class = &ucm_class;
+ ucm_dev->class_dev.dev = device->dma_device;
+ snprintf(ucm_dev->class_dev.class_id, BUS_ID_SIZE, "ucm%d",
+ ucm_dev->devnum);
+ if (class_device_register(&ucm_dev->class_dev))
goto err_cdev;
- }
- ib_ucm_class = class_create(THIS_MODULE, "infiniband_cm");
- if (IS_ERR(ib_ucm_class)) {
- result = PTR_ERR(ib_ucm_class);
- ucm_dbg("Error <%d> creating class\n", result);
+ if (class_device_create_file(&ucm_dev->class_dev,
+ &class_device_attr_dev))
+ goto err_class;
+ if (class_device_create_file(&ucm_dev->class_dev,
+ &class_device_attr_ibdev))
goto err_class;
+
+ ib_set_client_data(device, &ucm_client, ucm_dev);
+ return;
+
+err_class:
+ class_device_unregister(&ucm_dev->class_dev);
+err_cdev:
+ cdev_del(&ucm_dev->dev);
+ clear_bit(ucm_dev->devnum, dev_map);
+err:
+ kfree(ucm_dev);
+ return;
+}
+
+static void ib_ucm_remove_one(struct ib_device *device)
+{
+ struct ib_ucm_device *ucm_dev = ib_get_client_data(device, &ucm_client);
+
+ if (!ucm_dev)
+ return;
+
+ class_device_unregister(&ucm_dev->class_dev);
+}
+
+static ssize_t show_abi_version(struct class *class, char *buf)
+{
+ return sprintf(buf, "%d\n", IB_USER_CM_ABI_VERSION);
+}
+static CLASS_ATTR(abi_version, S_IRUGO, show_abi_version, NULL);
+
+static int __init ib_ucm_init(void)
+{
+ int ret;
+
+ ret = register_chrdev_region(IB_UCM_BASE_DEV, IB_UCM_MAX_DEVICES,
+ "infiniband_cm");
+ if (ret) {
+ printk(KERN_ERR "ucm: couldn't register device number\n");
+ goto err;
}
- class_device_create(ib_ucm_class, IB_UCM_DEV, NULL, "ucm");
+ ret = class_register(&ucm_class);
+ if (ret) {
+ printk(KERN_ERR "ucm: couldn't create class infiniband_cm\n");
+ goto err_chrdev;
+ }
- idr_init(&ctx_id_table);
- init_MUTEX(&ctx_id_mutex);
+ ret = class_create_file(&ucm_class, &class_attr_abi_version);
+ if (ret) {
+ printk(KERN_ERR "ucm: couldn't create abi_version attribute\n");
+ goto err_class;
+ }
+ ret = ib_register_client(&ucm_client);
+ if (ret) {
+ printk(KERN_ERR "ucm: couldn't register client\n");
+ goto err_class;
+ }
return 0;
+
err_class:
- cdev_del(&ib_ucm_cdev);
-err_cdev:
- unregister_chrdev_region(IB_UCM_DEV, 1);
-err_chr:
- return result;
+ class_unregister(&ucm_class);
+err_chrdev:
+ unregister_chrdev_region(IB_UCM_BASE_DEV, IB_UCM_MAX_DEVICES);
+err:
+ return ret;
}
static void __exit ib_ucm_cleanup(void)
{
- class_device_destroy(ib_ucm_class, IB_UCM_DEV);
- class_destroy(ib_ucm_class);
- cdev_del(&ib_ucm_cdev);
- unregister_chrdev_region(IB_UCM_DEV, 1);
+ ib_unregister_client(&ucm_client);
+ class_unregister(&ucm_class);
+ unregister_chrdev_region(IB_UCM_BASE_DEV, IB_UCM_MAX_DEVICES);
+ idr_destroy(&ctx_id_table);
}
module_init(ib_ucm_init);
diff --git a/drivers/infiniband/core/ucm.h b/drivers/infiniband/core/ucm.h
deleted file mode 100644
index f46f37bc1201..000000000000
--- a/drivers/infiniband/core/ucm.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (c) 2005 Topspin Communications. All rights reserved.
- * Copyright (c) 2005 Intel Corporation. All rights reserved.
- *
- * This software is available to you under a choice of one of two
- * licenses. You may choose to be licensed under the terms of the GNU
- * General Public License (GPL) Version 2, available from the file
- * COPYING in the main directory of this source tree, or the
- * OpenIB.org BSD license below:
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- *
- * 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.
- *
- * $Id: ucm.h 2208 2005-04-22 23:24:31Z libor $
- */
-
-#ifndef UCM_H
-#define UCM_H
-
-#include <linux/fs.h>
-#include <linux/device.h>
-#include <linux/cdev.h>
-#include <linux/idr.h>
-
-#include <rdma/ib_cm.h>
-#include <rdma/ib_user_cm.h>
-
-struct ib_ucm_file {
- struct semaphore mutex;
- struct file *filp;
-
- struct list_head ctxs; /* list of active connections */
- struct list_head events; /* list of pending events */
- wait_queue_head_t poll_wait;
-};
-
-struct ib_ucm_context {
- int id;
- wait_queue_head_t wait;
- atomic_t ref;
- int events_reported;
-
- struct ib_ucm_file *file;
- struct ib_cm_id *cm_id;
- __u64 uid;
-
- struct list_head events; /* list of pending events. */
- struct list_head file_list; /* member in file ctx list */
-};
-
-struct ib_ucm_event {
- struct ib_ucm_context *ctx;
- struct list_head file_list; /* member in file event list */
- struct list_head ctx_list; /* member in ctx event list */
-
- struct ib_cm_id *cm_id;
- struct ib_ucm_event_resp resp;
- void *data;
- void *info;
- int data_len;
- int info_len;
-};
-
-#endif /* UCM_H */
diff --git a/drivers/infiniband/core/ud_header.c b/drivers/infiniband/core/ud_header.c
index 527b23450ab3..997c07db6d8f 100644
--- a/drivers/infiniband/core/ud_header.c
+++ b/drivers/infiniband/core/ud_header.c
@@ -34,6 +34,7 @@
*/
#include <linux/errno.h>
+#include <linux/string.h>
#include <rdma/ib_pack.h>
diff --git a/drivers/infiniband/core/user_mad.c b/drivers/infiniband/core/user_mad.c
index a64d6b4dcc16..5ea741f47fc8 100644
--- a/drivers/infiniband/core/user_mad.c
+++ b/drivers/infiniband/core/user_mad.c
@@ -31,7 +31,7 @@
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
- * $Id: user_mad.c 2814 2005-07-06 19:14:09Z halr $
+ * $Id: user_mad.c 4010 2005-11-09 23:11:56Z roland $
*/
#include <linux/module.h>
@@ -64,18 +64,42 @@ enum {
IB_UMAD_MINOR_BASE = 0
};
+/*
+ * Our lifetime rules for these structs are the following: each time a
+ * device special file is opened, we look up the corresponding struct
+ * ib_umad_port by minor in the umad_port[] table while holding the
+ * port_lock. If this lookup succeeds, we take a reference on the
+ * ib_umad_port's struct ib_umad_device while still holding the
+ * port_lock; if the lookup fails, we fail the open(). We drop these
+ * references in the corresponding close().
+ *
+ * In addition to references coming from open character devices, there
+ * is one more reference to each ib_umad_device representing the
+ * module's reference taken when allocating the ib_umad_device in
+ * ib_umad_add_one().
+ *
+ * When destroying an ib_umad_device, we clear all of its
+ * ib_umad_ports from umad_port[] while holding port_lock before
+ * dropping the module's reference to the ib_umad_device. This is
+ * always safe because any open() calls will either succeed and obtain
+ * a reference before we clear the umad_port[] entries, or fail after
+ * we clear the umad_port[] entries.
+ */
+
struct ib_umad_port {
- int devnum;
- struct cdev dev;
- struct class_device class_dev;
+ struct cdev *dev;
+ struct class_device *class_dev;
- int sm_devnum;
- struct cdev sm_dev;
- struct class_device sm_class_dev;
+ struct cdev *sm_dev;
+ struct class_device *sm_class_dev;
struct semaphore sm_sem;
+ struct rw_semaphore mutex;
+ struct list_head file_list;
+
struct ib_device *ib_dev;
struct ib_umad_device *umad_dev;
+ int dev_num;
u8 port_num;
};
@@ -86,42 +110,59 @@ struct ib_umad_device {
};
struct ib_umad_file {
- struct ib_umad_port *port;
- spinlock_t recv_lock;
- struct list_head recv_list;
- wait_queue_head_t recv_wait;
- struct rw_semaphore agent_mutex;
- struct ib_mad_agent *agent[IB_UMAD_MAX_AGENTS];
- struct ib_mr *mr[IB_UMAD_MAX_AGENTS];
+ struct ib_umad_port *port;
+ struct list_head recv_list;
+ struct list_head port_list;
+ spinlock_t recv_lock;
+ wait_queue_head_t recv_wait;
+ struct ib_mad_agent *agent[IB_UMAD_MAX_AGENTS];
+ int agents_dead;
};
struct ib_umad_packet {
- struct ib_ah *ah;
struct ib_mad_send_buf *msg;
struct list_head list;
int length;
- DECLARE_PCI_UNMAP_ADDR(mapping)
struct ib_user_mad mad;
};
+static struct class *umad_class;
+
static const dev_t base_dev = MKDEV(IB_UMAD_MAJOR, IB_UMAD_MINOR_BASE);
-static spinlock_t map_lock;
+
+static DEFINE_SPINLOCK(port_lock);
+static struct ib_umad_port *umad_port[IB_UMAD_MAX_PORTS];
static DECLARE_BITMAP(dev_map, IB_UMAD_MAX_PORTS * 2);
static void ib_umad_add_one(struct ib_device *device);
static void ib_umad_remove_one(struct ib_device *device);
+static void ib_umad_release_dev(struct kref *ref)
+{
+ struct ib_umad_device *dev =
+ container_of(ref, struct ib_umad_device, ref);
+
+ kfree(dev);
+}
+
+/* caller must hold port->mutex at least for reading */
+static struct ib_mad_agent *__get_agent(struct ib_umad_file *file, int id)
+{
+ return file->agents_dead ? NULL : file->agent[id];
+}
+
static int queue_packet(struct ib_umad_file *file,
struct ib_mad_agent *agent,
struct ib_umad_packet *packet)
{
int ret = 1;
- down_read(&file->agent_mutex);
+ down_read(&file->port->mutex);
+
for (packet->mad.hdr.id = 0;
packet->mad.hdr.id < IB_UMAD_MAX_AGENTS;
packet->mad.hdr.id++)
- if (agent == file->agent[packet->mad.hdr.id]) {
+ if (agent == __get_agent(file, packet->mad.hdr.id)) {
spin_lock_irq(&file->recv_lock);
list_add_tail(&packet->list, &file->recv_list);
spin_unlock_irq(&file->recv_lock);
@@ -130,7 +171,7 @@ static int queue_packet(struct ib_umad_file *file,
break;
}
- up_read(&file->agent_mutex);
+ up_read(&file->port->mutex);
return ret;
}
@@ -139,22 +180,19 @@ static void send_handler(struct ib_mad_agent *agent,
struct ib_mad_send_wc *send_wc)
{
struct ib_umad_file *file = agent->context;
- struct ib_umad_packet *timeout, *packet =
- (void *) (unsigned long) send_wc->wr_id;
+ struct ib_umad_packet *timeout;
+ struct ib_umad_packet *packet = send_wc->send_buf->context[0];
- ib_destroy_ah(packet->msg->send_wr.wr.ud.ah);
+ ib_destroy_ah(packet->msg->ah);
ib_free_send_mad(packet->msg);
if (send_wc->status == IB_WC_RESP_TIMEOUT_ERR) {
- timeout = kmalloc(sizeof *timeout + sizeof (struct ib_mad_hdr),
- GFP_KERNEL);
+ timeout = kzalloc(sizeof *timeout + IB_MGMT_MAD_HDR, GFP_KERNEL);
if (!timeout)
goto out;
- memset(timeout, 0, sizeof *timeout + sizeof (struct ib_mad_hdr));
-
- timeout->length = sizeof (struct ib_mad_hdr);
- timeout->mad.hdr.id = packet->mad.hdr.id;
+ timeout->length = IB_MGMT_MAD_HDR;
+ timeout->mad.hdr.id = packet->mad.hdr.id;
timeout->mad.hdr.status = ETIMEDOUT;
memcpy(timeout->mad.data, packet->mad.data,
sizeof (struct ib_mad_hdr));
@@ -177,11 +215,10 @@ static void recv_handler(struct ib_mad_agent *agent,
goto out;
length = mad_recv_wc->mad_len;
- packet = kmalloc(sizeof *packet + length, GFP_KERNEL);
+ packet = kzalloc(sizeof *packet + length, GFP_KERNEL);
if (!packet)
goto out;
- memset(packet, 0, sizeof *packet + length);
packet->length = length;
ib_coalesce_recv_mad(mad_recv_wc, packet->mad.data);
@@ -247,7 +284,7 @@ static ssize_t ib_umad_read(struct file *filp, char __user *buf,
else
ret = -ENOSPC;
} else if (copy_to_user(buf, &packet->mad,
- packet->length + sizeof (struct ib_user_mad)))
+ packet->length + sizeof (struct ib_user_mad)))
ret = -EFAULT;
else
ret = packet->length + sizeof (struct ib_user_mad);
@@ -268,26 +305,23 @@ static ssize_t ib_umad_write(struct file *filp, const char __user *buf,
struct ib_umad_packet *packet;
struct ib_mad_agent *agent;
struct ib_ah_attr ah_attr;
- struct ib_send_wr *bad_wr;
+ struct ib_ah *ah;
struct ib_rmpp_mad *rmpp_mad;
u8 method;
__be64 *tid;
- int ret, length, hdr_len, data_len, rmpp_hdr_size;
+ int ret, length, hdr_len, copy_offset;
int rmpp_active = 0;
if (count < sizeof (struct ib_user_mad))
return -EINVAL;
length = count - sizeof (struct ib_user_mad);
- packet = kmalloc(sizeof *packet + sizeof(struct ib_mad_hdr) +
- sizeof(struct ib_rmpp_hdr), GFP_KERNEL);
+ packet = kmalloc(sizeof *packet + IB_MGMT_RMPP_HDR, GFP_KERNEL);
if (!packet)
return -ENOMEM;
if (copy_from_user(&packet->mad, buf,
- sizeof (struct ib_user_mad) +
- sizeof(struct ib_mad_hdr) +
- sizeof(struct ib_rmpp_hdr))) {
+ sizeof (struct ib_user_mad) + IB_MGMT_RMPP_HDR)) {
ret = -EFAULT;
goto err;
}
@@ -298,11 +332,9 @@ static ssize_t ib_umad_write(struct file *filp, const char __user *buf,
goto err;
}
- packet->length = length;
+ down_read(&file->port->mutex);
- down_read(&file->agent_mutex);
-
- agent = file->agent[packet->mad.hdr.id];
+ agent = __get_agent(file, packet->mad.hdr.id);
if (!agent) {
ret = -EINVAL;
goto err_up;
@@ -321,9 +353,9 @@ static ssize_t ib_umad_write(struct file *filp, const char __user *buf,
ah_attr.grh.traffic_class = packet->mad.hdr.traffic_class;
}
- packet->ah = ib_create_ah(agent->qp->pd, &ah_attr);
- if (IS_ERR(packet->ah)) {
- ret = PTR_ERR(packet->ah);
+ ah = ib_create_ah(agent->qp->pd, &ah_attr);
+ if (IS_ERR(ah)) {
+ ret = PTR_ERR(ah);
goto err_up;
}
@@ -337,64 +369,44 @@ static ssize_t ib_umad_write(struct file *filp, const char __user *buf,
/* Validate that the management class can support RMPP */
if (rmpp_mad->mad_hdr.mgmt_class == IB_MGMT_CLASS_SUBN_ADM) {
- hdr_len = offsetof(struct ib_sa_mad, data);
- data_len = length - hdr_len;
+ hdr_len = IB_MGMT_SA_HDR;
} else if ((rmpp_mad->mad_hdr.mgmt_class >= IB_MGMT_CLASS_VENDOR_RANGE2_START) &&
(rmpp_mad->mad_hdr.mgmt_class <= IB_MGMT_CLASS_VENDOR_RANGE2_END)) {
- hdr_len = offsetof(struct ib_vendor_mad, data);
- data_len = length - hdr_len;
+ hdr_len = IB_MGMT_VENDOR_HDR;
} else {
ret = -EINVAL;
goto err_ah;
}
rmpp_active = 1;
+ copy_offset = IB_MGMT_RMPP_HDR;
} else {
- if (length > sizeof(struct ib_mad)) {
- ret = -EINVAL;
- goto err_ah;
- }
- hdr_len = offsetof(struct ib_mad, data);
- data_len = length - hdr_len;
+ hdr_len = IB_MGMT_MAD_HDR;
+ copy_offset = IB_MGMT_MAD_HDR;
}
packet->msg = ib_create_send_mad(agent,
be32_to_cpu(packet->mad.hdr.qpn),
- 0, packet->ah, rmpp_active,
- hdr_len, data_len,
+ 0, rmpp_active,
+ hdr_len, length - hdr_len,
GFP_KERNEL);
if (IS_ERR(packet->msg)) {
ret = PTR_ERR(packet->msg);
goto err_ah;
}
- packet->msg->send_wr.wr.ud.timeout_ms = packet->mad.hdr.timeout_ms;
- packet->msg->send_wr.wr.ud.retries = packet->mad.hdr.retries;
-
- /* Override send WR WRID initialized in ib_create_send_mad */
- packet->msg->send_wr.wr_id = (unsigned long) packet;
-
- if (!rmpp_active) {
- /* Copy message from user into send buffer */
- if (copy_from_user(packet->msg->mad,
- buf + sizeof(struct ib_user_mad), length)) {
- ret = -EFAULT;
- goto err_msg;
- }
- } else {
- rmpp_hdr_size = sizeof(struct ib_mad_hdr) +
- sizeof(struct ib_rmpp_hdr);
-
- /* Only copy MAD headers (RMPP header in place) */
- memcpy(packet->msg->mad, packet->mad.data,
- sizeof(struct ib_mad_hdr));
+ packet->msg->ah = ah;
+ packet->msg->timeout_ms = packet->mad.hdr.timeout_ms;
+ packet->msg->retries = packet->mad.hdr.retries;
+ packet->msg->context[0] = packet;
- /* Now, copy rest of message from user into send buffer */
- if (copy_from_user(((struct ib_rmpp_mad *) packet->msg->mad)->data,
- buf + sizeof (struct ib_user_mad) + rmpp_hdr_size,
- length - rmpp_hdr_size)) {
- ret = -EFAULT;
- goto err_msg;
- }
+ /* Copy MAD headers (RMPP header in place) */
+ memcpy(packet->msg->mad, packet->mad.data, IB_MGMT_MAD_HDR);
+ /* Now, copy rest of message from user into send buffer */
+ if (copy_from_user(packet->msg->mad + copy_offset,
+ buf + sizeof (struct ib_user_mad) + copy_offset,
+ length - copy_offset)) {
+ ret = -EFAULT;
+ goto err_msg;
}
/*
@@ -403,32 +415,32 @@ static ssize_t ib_umad_write(struct file *filp, const char __user *buf,
* transaction ID matches the agent being used to send the
* MAD.
*/
- method = packet->msg->mad->mad_hdr.method;
+ method = ((struct ib_mad_hdr *) packet->msg->mad)->method;
if (!(method & IB_MGMT_METHOD_RESP) &&
method != IB_MGMT_METHOD_TRAP_REPRESS &&
method != IB_MGMT_METHOD_SEND) {
- tid = &packet->msg->mad->mad_hdr.tid;
+ tid = &((struct ib_mad_hdr *) packet->msg->mad)->tid;
*tid = cpu_to_be64(((u64) agent->hi_tid) << 32 |
(be64_to_cpup(tid) & 0xffffffff));
}
- ret = ib_post_send_mad(agent, &packet->msg->send_wr, &bad_wr);
+ ret = ib_post_send_mad(packet->msg, NULL);
if (ret)
goto err_msg;
- up_read(&file->agent_mutex);
+ up_read(&file->port->mutex);
- return sizeof (struct ib_user_mad_hdr) + packet->length;
+ return count;
err_msg:
ib_free_send_mad(packet->msg);
err_ah:
- ib_destroy_ah(packet->ah);
+ ib_destroy_ah(ah);
err_up:
- up_read(&file->agent_mutex);
+ up_read(&file->port->mutex);
err:
kfree(packet);
@@ -458,7 +470,12 @@ static int ib_umad_reg_agent(struct ib_umad_file *file, unsigned long arg)
int agent_id;
int ret;
- down_write(&file->agent_mutex);
+ down_write(&file->port->mutex);
+
+ if (!file->port->ib_dev) {
+ ret = -EPIPE;
+ goto out;
+ }
if (copy_from_user(&ureq, (void __user *) arg, sizeof ureq)) {
ret = -EFAULT;
@@ -471,7 +488,7 @@ static int ib_umad_reg_agent(struct ib_umad_file *file, unsigned long arg)
}
for (agent_id = 0; agent_id < IB_UMAD_MAX_AGENTS; ++agent_id)
- if (!file->agent[agent_id])
+ if (!__get_agent(file, agent_id))
goto found;
ret = -ENOMEM;
@@ -495,58 +512,46 @@ found:
goto out;
}
- file->agent[agent_id] = agent;
-
- file->mr[agent_id] = ib_get_dma_mr(agent->qp->pd, IB_ACCESS_LOCAL_WRITE);
- if (IS_ERR(file->mr[agent_id])) {
- ret = -ENOMEM;
- goto err;
- }
-
if (put_user(agent_id,
(u32 __user *) (arg + offsetof(struct ib_user_mad_reg_req, id)))) {
ret = -EFAULT;
- goto err_mr;
+ ib_unregister_mad_agent(agent);
+ goto out;
}
+ file->agent[agent_id] = agent;
ret = 0;
- goto out;
-
-err_mr:
- ib_dereg_mr(file->mr[agent_id]);
-
-err:
- file->agent[agent_id] = NULL;
- ib_unregister_mad_agent(agent);
out:
- up_write(&file->agent_mutex);
+ up_write(&file->port->mutex);
return ret;
}
static int ib_umad_unreg_agent(struct ib_umad_file *file, unsigned long arg)
{
+ struct ib_mad_agent *agent = NULL;
u32 id;
int ret = 0;
- down_write(&file->agent_mutex);
+ if (get_user(id, (u32 __user *) arg))
+ return -EFAULT;
- if (get_user(id, (u32 __user *) arg)) {
- ret = -EFAULT;
- goto out;
- }
+ down_write(&file->port->mutex);
- if (id < 0 || id >= IB_UMAD_MAX_AGENTS || !file->agent[id]) {
+ if (id < 0 || id >= IB_UMAD_MAX_AGENTS || !__get_agent(file, id)) {
ret = -EINVAL;
goto out;
}
- ib_dereg_mr(file->mr[id]);
- ib_unregister_mad_agent(file->agent[id]);
+ agent = file->agent[id];
file->agent[id] = NULL;
out:
- up_write(&file->agent_mutex);
+ up_write(&file->port->mutex);
+
+ if (agent)
+ ib_unregister_mad_agent(agent);
+
return ret;
}
@@ -565,43 +570,76 @@ static long ib_umad_ioctl(struct file *filp, unsigned int cmd,
static int ib_umad_open(struct inode *inode, struct file *filp)
{
- struct ib_umad_port *port =
- container_of(inode->i_cdev, struct ib_umad_port, dev);
+ struct ib_umad_port *port;
struct ib_umad_file *file;
+ int ret = 0;
- file = kmalloc(sizeof *file, GFP_KERNEL);
- if (!file)
- return -ENOMEM;
+ spin_lock(&port_lock);
+ port = umad_port[iminor(inode) - IB_UMAD_MINOR_BASE];
+ if (port)
+ kref_get(&port->umad_dev->ref);
+ spin_unlock(&port_lock);
- memset(file, 0, sizeof *file);
+ if (!port)
+ return -ENXIO;
+
+ down_write(&port->mutex);
+
+ if (!port->ib_dev) {
+ ret = -ENXIO;
+ goto out;
+ }
+
+ file = kzalloc(sizeof *file, GFP_KERNEL);
+ if (!file) {
+ kref_put(&port->umad_dev->ref, ib_umad_release_dev);
+ ret = -ENOMEM;
+ goto out;
+ }
spin_lock_init(&file->recv_lock);
- init_rwsem(&file->agent_mutex);
INIT_LIST_HEAD(&file->recv_list);
init_waitqueue_head(&file->recv_wait);
file->port = port;
filp->private_data = file;
- return 0;
+ list_add_tail(&file->port_list, &port->file_list);
+
+out:
+ up_write(&port->mutex);
+ return ret;
}
static int ib_umad_close(struct inode *inode, struct file *filp)
{
struct ib_umad_file *file = filp->private_data;
+ struct ib_umad_device *dev = file->port->umad_dev;
struct ib_umad_packet *packet, *tmp;
+ int already_dead;
int i;
- for (i = 0; i < IB_UMAD_MAX_AGENTS; ++i)
- if (file->agent[i]) {
- ib_dereg_mr(file->mr[i]);
- ib_unregister_mad_agent(file->agent[i]);
- }
+ down_write(&file->port->mutex);
+
+ already_dead = file->agents_dead;
+ file->agents_dead = 1;
list_for_each_entry_safe(packet, tmp, &file->recv_list, list)
kfree(packet);
+ list_del(&file->port_list);
+
+ downgrade_write(&file->port->mutex);
+
+ if (!already_dead)
+ for (i = 0; i < IB_UMAD_MAX_AGENTS; ++i)
+ if (file->agent[i])
+ ib_unregister_mad_agent(file->agent[i]);
+
+ up_read(&file->port->mutex);
+
kfree(file);
+ kref_put(&dev->ref, ib_umad_release_dev);
return 0;
}
@@ -619,30 +657,46 @@ static struct file_operations umad_fops = {
static int ib_umad_sm_open(struct inode *inode, struct file *filp)
{
- struct ib_umad_port *port =
- container_of(inode->i_cdev, struct ib_umad_port, sm_dev);
+ struct ib_umad_port *port;
struct ib_port_modify props = {
.set_port_cap_mask = IB_PORT_SM
};
int ret;
+ spin_lock(&port_lock);
+ port = umad_port[iminor(inode) - IB_UMAD_MINOR_BASE - IB_UMAD_MAX_PORTS];
+ if (port)
+ kref_get(&port->umad_dev->ref);
+ spin_unlock(&port_lock);
+
+ if (!port)
+ return -ENXIO;
+
if (filp->f_flags & O_NONBLOCK) {
- if (down_trylock(&port->sm_sem))
- return -EAGAIN;
+ if (down_trylock(&port->sm_sem)) {
+ ret = -EAGAIN;
+ goto fail;
+ }
} else {
- if (down_interruptible(&port->sm_sem))
- return -ERESTARTSYS;
+ if (down_interruptible(&port->sm_sem)) {
+ ret = -ERESTARTSYS;
+ goto fail;
+ }
}
ret = ib_modify_port(port->ib_dev, port->port_num, 0, &props);
if (ret) {
up(&port->sm_sem);
- return ret;
+ goto fail;
}
filp->private_data = port;
return 0;
+
+fail:
+ kref_put(&port->umad_dev->ref, ib_umad_release_dev);
+ return ret;
}
static int ib_umad_sm_close(struct inode *inode, struct file *filp)
@@ -651,11 +705,17 @@ static int ib_umad_sm_close(struct inode *inode, struct file *filp)
struct ib_port_modify props = {
.clr_port_cap_mask = IB_PORT_SM
};
- int ret;
+ int ret = 0;
+
+ down_write(&port->mutex);
+ if (port->ib_dev)
+ ret = ib_modify_port(port->ib_dev, port->port_num, 0, &props);
+ up_write(&port->mutex);
- ret = ib_modify_port(port->ib_dev, port->port_num, 0, &props);
up(&port->sm_sem);
+ kref_put(&port->umad_dev->ref, ib_umad_release_dev);
+
return ret;
}
@@ -671,21 +731,13 @@ static struct ib_client umad_client = {
.remove = ib_umad_remove_one
};
-static ssize_t show_dev(struct class_device *class_dev, char *buf)
-{
- struct ib_umad_port *port = class_get_devdata(class_dev);
-
- if (class_dev == &port->class_dev)
- return print_dev_t(buf, port->dev.dev);
- else
- return print_dev_t(buf, port->sm_dev.dev);
-}
-static CLASS_DEVICE_ATTR(dev, S_IRUGO, show_dev, NULL);
-
static ssize_t show_ibdev(struct class_device *class_dev, char *buf)
{
struct ib_umad_port *port = class_get_devdata(class_dev);
+ if (!port)
+ return -ENODEV;
+
return sprintf(buf, "%s\n", port->ib_dev->name);
}
static CLASS_DEVICE_ATTR(ibdev, S_IRUGO, show_ibdev, NULL);
@@ -694,38 +746,13 @@ static ssize_t show_port(struct class_device *class_dev, char *buf)
{
struct ib_umad_port *port = class_get_devdata(class_dev);
+ if (!port)
+ return -ENODEV;
+
return sprintf(buf, "%d\n", port->port_num);
}
static CLASS_DEVICE_ATTR(port, S_IRUGO, show_port, NULL);
-static void ib_umad_release_dev(struct kref *ref)
-{
- struct ib_umad_device *dev =
- container_of(ref, struct ib_umad_device, ref);
-
- kfree(dev);
-}
-
-static void ib_umad_release_port(struct class_device *class_dev)
-{
- struct ib_umad_port *port = class_get_devdata(class_dev);
-
- if (class_dev == &port->class_dev) {
- cdev_del(&port->dev);
- clear_bit(port->devnum, dev_map);
- } else {
- cdev_del(&port->sm_dev);
- clear_bit(port->sm_devnum, dev_map);
- }
-
- kref_put(&port->umad_dev->ref, ib_umad_release_dev);
-}
-
-static struct class umad_class = {
- .name = "infiniband_mad",
- .release = ib_umad_release_port
-};
-
static ssize_t show_abi_version(struct class *class, char *buf)
{
return sprintf(buf, "%d\n", IB_USER_MAD_ABI_VERSION);
@@ -735,91 +762,144 @@ static CLASS_ATTR(abi_version, S_IRUGO, show_abi_version, NULL);
static int ib_umad_init_port(struct ib_device *device, int port_num,
struct ib_umad_port *port)
{
- spin_lock(&map_lock);
- port->devnum = find_first_zero_bit(dev_map, IB_UMAD_MAX_PORTS);
- if (port->devnum >= IB_UMAD_MAX_PORTS) {
- spin_unlock(&map_lock);
- return -1;
- }
- port->sm_devnum = find_next_zero_bit(dev_map, IB_UMAD_MAX_PORTS * 2, IB_UMAD_MAX_PORTS);
- if (port->sm_devnum >= IB_UMAD_MAX_PORTS * 2) {
- spin_unlock(&map_lock);
+ spin_lock(&port_lock);
+ port->dev_num = find_first_zero_bit(dev_map, IB_UMAD_MAX_PORTS);
+ if (port->dev_num >= IB_UMAD_MAX_PORTS) {
+ spin_unlock(&port_lock);
return -1;
}
- set_bit(port->devnum, dev_map);
- set_bit(port->sm_devnum, dev_map);
- spin_unlock(&map_lock);
+ set_bit(port->dev_num, dev_map);
+ spin_unlock(&port_lock);
port->ib_dev = device;
port->port_num = port_num;
init_MUTEX(&port->sm_sem);
+ init_rwsem(&port->mutex);
+ INIT_LIST_HEAD(&port->file_list);
- cdev_init(&port->dev, &umad_fops);
- port->dev.owner = THIS_MODULE;
- kobject_set_name(&port->dev.kobj, "umad%d", port->devnum);
- if (cdev_add(&port->dev, base_dev + port->devnum, 1))
+ port->dev = cdev_alloc();
+ if (!port->dev)
return -1;
-
- port->class_dev.class = &umad_class;
- port->class_dev.dev = device->dma_device;
-
- snprintf(port->class_dev.class_id, BUS_ID_SIZE, "umad%d", port->devnum);
-
- if (class_device_register(&port->class_dev))
+ port->dev->owner = THIS_MODULE;
+ port->dev->ops = &umad_fops;
+ kobject_set_name(&port->dev->kobj, "umad%d", port->dev_num);
+ if (cdev_add(port->dev, base_dev + port->dev_num, 1))
goto err_cdev;
- class_set_devdata(&port->class_dev, port);
- kref_get(&port->umad_dev->ref);
+ port->class_dev = class_device_create(umad_class, NULL, port->dev->dev,
+ device->dma_device,
+ "umad%d", port->dev_num);
+ if (IS_ERR(port->class_dev))
+ goto err_cdev;
- if (class_device_create_file(&port->class_dev, &class_device_attr_dev))
- goto err_class;
- if (class_device_create_file(&port->class_dev, &class_device_attr_ibdev))
+ if (class_device_create_file(port->class_dev, &class_device_attr_ibdev))
goto err_class;
- if (class_device_create_file(&port->class_dev, &class_device_attr_port))
+ if (class_device_create_file(port->class_dev, &class_device_attr_port))
goto err_class;
- cdev_init(&port->sm_dev, &umad_sm_fops);
- port->sm_dev.owner = THIS_MODULE;
- kobject_set_name(&port->dev.kobj, "issm%d", port->sm_devnum - IB_UMAD_MAX_PORTS);
- if (cdev_add(&port->sm_dev, base_dev + port->sm_devnum, 1))
- return -1;
-
- port->sm_class_dev.class = &umad_class;
- port->sm_class_dev.dev = device->dma_device;
-
- snprintf(port->sm_class_dev.class_id, BUS_ID_SIZE, "issm%d", port->sm_devnum - IB_UMAD_MAX_PORTS);
+ port->sm_dev = cdev_alloc();
+ if (!port->sm_dev)
+ goto err_class;
+ port->sm_dev->owner = THIS_MODULE;
+ port->sm_dev->ops = &umad_sm_fops;
+ kobject_set_name(&port->sm_dev->kobj, "issm%d", port->dev_num);
+ if (cdev_add(port->sm_dev, base_dev + port->dev_num + IB_UMAD_MAX_PORTS, 1))
+ goto err_sm_cdev;
- if (class_device_register(&port->sm_class_dev))
+ port->sm_class_dev = class_device_create(umad_class, NULL, port->sm_dev->dev,
+ device->dma_device,
+ "issm%d", port->dev_num);
+ if (IS_ERR(port->sm_class_dev))
goto err_sm_cdev;
- class_set_devdata(&port->sm_class_dev, port);
- kref_get(&port->umad_dev->ref);
+ class_set_devdata(port->class_dev, port);
+ class_set_devdata(port->sm_class_dev, port);
- if (class_device_create_file(&port->sm_class_dev, &class_device_attr_dev))
+ if (class_device_create_file(port->sm_class_dev, &class_device_attr_ibdev))
goto err_sm_class;
- if (class_device_create_file(&port->sm_class_dev, &class_device_attr_ibdev))
- goto err_sm_class;
- if (class_device_create_file(&port->sm_class_dev, &class_device_attr_port))
+ if (class_device_create_file(port->sm_class_dev, &class_device_attr_port))
goto err_sm_class;
+ spin_lock(&port_lock);
+ umad_port[port->dev_num] = port;
+ spin_unlock(&port_lock);
+
return 0;
err_sm_class:
- class_device_unregister(&port->sm_class_dev);
+ class_device_destroy(umad_class, port->sm_dev->dev);
err_sm_cdev:
- cdev_del(&port->sm_dev);
+ cdev_del(port->sm_dev);
err_class:
- class_device_unregister(&port->class_dev);
+ class_device_destroy(umad_class, port->dev->dev);
err_cdev:
- cdev_del(&port->dev);
- clear_bit(port->devnum, dev_map);
+ cdev_del(port->dev);
+ clear_bit(port->dev_num, dev_map);
return -1;
}
+static void ib_umad_kill_port(struct ib_umad_port *port)
+{
+ struct ib_umad_file *file;
+ int id;
+
+ class_set_devdata(port->class_dev, NULL);
+ class_set_devdata(port->sm_class_dev, NULL);
+
+ class_device_destroy(umad_class, port->dev->dev);
+ class_device_destroy(umad_class, port->sm_dev->dev);
+
+ cdev_del(port->dev);
+ cdev_del(port->sm_dev);
+
+ spin_lock(&port_lock);
+ umad_port[port->dev_num] = NULL;
+ spin_unlock(&port_lock);
+
+ down_write(&port->mutex);
+
+ port->ib_dev = NULL;
+
+ /*
+ * Now go through the list of files attached to this port and
+ * unregister all of their MAD agents. We need to hold
+ * port->mutex while doing this to avoid racing with
+ * ib_umad_close(), but we can't hold the mutex for writing
+ * while calling ib_unregister_mad_agent(), since that might
+ * deadlock by calling back into queue_packet(). So we
+ * downgrade our lock to a read lock, and then drop and
+ * reacquire the write lock for the next iteration.
+ *
+ * We do list_del_init() on the file's list_head so that the
+ * list_del in ib_umad_close() is still OK, even after the
+ * file is removed from the list.
+ */
+ while (!list_empty(&port->file_list)) {
+ file = list_entry(port->file_list.next, struct ib_umad_file,
+ port_list);
+
+ file->agents_dead = 1;
+ list_del_init(&file->port_list);
+
+ downgrade_write(&port->mutex);
+
+ for (id = 0; id < IB_UMAD_MAX_AGENTS; ++id)
+ if (file->agent[id])
+ ib_unregister_mad_agent(file->agent[id]);
+
+ up_read(&port->mutex);
+ down_write(&port->mutex);
+ }
+
+ up_write(&port->mutex);
+
+ clear_bit(port->dev_num, dev_map);
+}
+
static void ib_umad_add_one(struct ib_device *device)
{
struct ib_umad_device *umad_dev;
@@ -832,15 +912,12 @@ static void ib_umad_add_one(struct ib_device *device)
e = device->phys_port_cnt;
}
- umad_dev = kmalloc(sizeof *umad_dev +
+ umad_dev = kzalloc(sizeof *umad_dev +
(e - s + 1) * sizeof (struct ib_umad_port),
GFP_KERNEL);
if (!umad_dev)
return;
- memset(umad_dev, 0, sizeof *umad_dev +
- (e - s + 1) * sizeof (struct ib_umad_port));
-
kref_init(&umad_dev->ref);
umad_dev->start_port = s;
@@ -858,10 +935,8 @@ static void ib_umad_add_one(struct ib_device *device)
return;
err:
- while (--i >= s) {
- class_device_unregister(&umad_dev->port[i - s].class_dev);
- class_device_unregister(&umad_dev->port[i - s].sm_class_dev);
- }
+ while (--i >= s)
+ ib_umad_kill_port(&umad_dev->port[i - s]);
kref_put(&umad_dev->ref, ib_umad_release_dev);
}
@@ -874,10 +949,8 @@ static void ib_umad_remove_one(struct ib_device *device)
if (!umad_dev)
return;
- for (i = 0; i <= umad_dev->end_port - umad_dev->start_port; ++i) {
- class_device_unregister(&umad_dev->port[i].class_dev);
- class_device_unregister(&umad_dev->port[i].sm_class_dev);
- }
+ for (i = 0; i <= umad_dev->end_port - umad_dev->start_port; ++i)
+ ib_umad_kill_port(&umad_dev->port[i]);
kref_put(&umad_dev->ref, ib_umad_release_dev);
}
@@ -886,8 +959,6 @@ static int __init ib_umad_init(void)
{
int ret;
- spin_lock_init(&map_lock);
-
ret = register_chrdev_region(base_dev, IB_UMAD_MAX_PORTS * 2,
"infiniband_mad");
if (ret) {
@@ -895,13 +966,14 @@ static int __init ib_umad_init(void)
goto out;
}
- ret = class_register(&umad_class);
- if (ret) {
+ umad_class = class_create(THIS_MODULE, "infiniband_mad");
+ if (IS_ERR(umad_class)) {
+ ret = PTR_ERR(umad_class);
printk(KERN_ERR "user_mad: couldn't create class infiniband_mad\n");
goto out_chrdev;
}
- ret = class_create_file(&umad_class, &class_attr_abi_version);
+ ret = class_create_file(umad_class, &class_attr_abi_version);
if (ret) {
printk(KERN_ERR "user_mad: couldn't create abi_version attribute\n");
goto out_class;
@@ -916,7 +988,7 @@ static int __init ib_umad_init(void)
return 0;
out_class:
- class_unregister(&umad_class);
+ class_destroy(umad_class);
out_chrdev:
unregister_chrdev_region(base_dev, IB_UMAD_MAX_PORTS * 2);
@@ -928,7 +1000,7 @@ out:
static void __exit ib_umad_cleanup(void)
{
ib_unregister_client(&umad_client);
- class_unregister(&umad_class);
+ class_destroy(umad_class);
unregister_chrdev_region(base_dev, IB_UMAD_MAX_PORTS * 2);
}
diff --git a/drivers/infiniband/core/uverbs.h b/drivers/infiniband/core/uverbs.h
index cc124344dd2c..ecb830127865 100644
--- a/drivers/infiniband/core/uverbs.h
+++ b/drivers/infiniband/core/uverbs.h
@@ -3,6 +3,7 @@
* Copyright (c) 2005 Cisco Systems. All rights reserved.
* Copyright (c) 2005 Mellanox Technologies. All rights reserved.
* Copyright (c) 2005 Voltaire, Inc. All rights reserved.
+ * Copyright (c) 2005 PathScale, Inc. All rights reserved.
*
* This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU
@@ -38,29 +39,47 @@
#ifndef UVERBS_H
#define UVERBS_H
-/* Include device.h and fs.h until cdev.h is self-sufficient */
-#include <linux/fs.h>
-#include <linux/device.h>
-#include <linux/cdev.h>
#include <linux/kref.h>
#include <linux/idr.h>
#include <rdma/ib_verbs.h>
#include <rdma/ib_user_verbs.h>
+/*
+ * Our lifetime rules for these structs are the following:
+ *
+ * struct ib_uverbs_device: One reference is held by the module and
+ * released in ib_uverbs_remove_one(). Another reference is taken by
+ * ib_uverbs_open() each time the character special file is opened,
+ * and released in ib_uverbs_release_file() when the file is released.
+ *
+ * struct ib_uverbs_file: One reference is held by the VFS and
+ * released when the file is closed. Another reference is taken when
+ * an asynchronous event queue file is created and released when the
+ * event file is closed.
+ *
+ * struct ib_uverbs_event_file: One reference is held by the VFS and
+ * released when the file is closed. For asynchronous event files,
+ * another reference is held by the corresponding main context file
+ * and released when that file is closed. For completion event files,
+ * a reference is taken when a CQ is created that uses the file, and
+ * released when the CQ is destroyed.
+ */
+
struct ib_uverbs_device {
+ struct kref ref;
int devnum;
- struct cdev dev;
- struct class_device class_dev;
+ struct cdev *dev;
+ struct class_device *class_dev;
struct ib_device *ib_dev;
- int num_comp;
+ int num_comp_vectors;
};
struct ib_uverbs_event_file {
struct kref ref;
+ struct file *file;
struct ib_uverbs_file *uverbs_file;
spinlock_t lock;
- int fd;
int is_async;
wait_queue_head_t poll_wait;
struct fasync_struct *async_queue;
@@ -73,8 +92,7 @@ struct ib_uverbs_file {
struct ib_uverbs_device *device;
struct ib_ucontext *ucontext;
struct ib_event_handler event_handler;
- struct ib_uverbs_event_file async_file;
- struct ib_uverbs_event_file comp_file[1];
+ struct ib_uverbs_event_file *async_file;
};
struct ib_uverbs_event {
@@ -95,6 +113,7 @@ struct ib_uevent_object {
struct ib_ucq_object {
struct ib_uobject uobject;
+ struct ib_uverbs_file *uverbs_file;
struct list_head comp_list;
struct list_head async_list;
u32 comp_events_reported;
@@ -110,10 +129,23 @@ extern struct idr ib_uverbs_cq_idr;
extern struct idr ib_uverbs_qp_idr;
extern struct idr ib_uverbs_srq_idr;
+struct file *ib_uverbs_alloc_event_file(struct ib_uverbs_file *uverbs_file,
+ int is_async, int *fd);
+void ib_uverbs_release_event_file(struct kref *ref);
+struct ib_uverbs_event_file *ib_uverbs_lookup_comp_file(int fd);
+
+void ib_uverbs_release_ucq(struct ib_uverbs_file *file,
+ struct ib_uverbs_event_file *ev_file,
+ struct ib_ucq_object *uobj);
+void ib_uverbs_release_uevent(struct ib_uverbs_file *file,
+ struct ib_uevent_object *uobj);
+
void ib_uverbs_comp_handler(struct ib_cq *cq, void *cq_context);
void ib_uverbs_cq_event_handler(struct ib_event *event, void *context_ptr);
void ib_uverbs_qp_event_handler(struct ib_event *event, void *context_ptr);
void ib_uverbs_srq_event_handler(struct ib_event *event, void *context_ptr);
+void ib_uverbs_event_handler(struct ib_event_handler *handler,
+ struct ib_event *event);
int ib_umem_get(struct ib_device *dev, struct ib_umem *mem,
void *addr, size_t size, int write);
@@ -125,21 +157,26 @@ void ib_umem_release_on_close(struct ib_device *dev, struct ib_umem *umem);
const char __user *buf, int in_len, \
int out_len)
-IB_UVERBS_DECLARE_CMD(query_params);
IB_UVERBS_DECLARE_CMD(get_context);
IB_UVERBS_DECLARE_CMD(query_device);
IB_UVERBS_DECLARE_CMD(query_port);
-IB_UVERBS_DECLARE_CMD(query_gid);
-IB_UVERBS_DECLARE_CMD(query_pkey);
IB_UVERBS_DECLARE_CMD(alloc_pd);
IB_UVERBS_DECLARE_CMD(dealloc_pd);
IB_UVERBS_DECLARE_CMD(reg_mr);
IB_UVERBS_DECLARE_CMD(dereg_mr);
+IB_UVERBS_DECLARE_CMD(create_comp_channel);
IB_UVERBS_DECLARE_CMD(create_cq);
+IB_UVERBS_DECLARE_CMD(poll_cq);
+IB_UVERBS_DECLARE_CMD(req_notify_cq);
IB_UVERBS_DECLARE_CMD(destroy_cq);
IB_UVERBS_DECLARE_CMD(create_qp);
IB_UVERBS_DECLARE_CMD(modify_qp);
IB_UVERBS_DECLARE_CMD(destroy_qp);
+IB_UVERBS_DECLARE_CMD(post_send);
+IB_UVERBS_DECLARE_CMD(post_recv);
+IB_UVERBS_DECLARE_CMD(post_srq_recv);
+IB_UVERBS_DECLARE_CMD(create_ah);
+IB_UVERBS_DECLARE_CMD(destroy_ah);
IB_UVERBS_DECLARE_CMD(attach_mcast);
IB_UVERBS_DECLARE_CMD(detach_mcast);
IB_UVERBS_DECLARE_CMD(create_srq);
diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c
index 562445165d2b..ed45da892b1c 100644
--- a/drivers/infiniband/core/uverbs_cmd.c
+++ b/drivers/infiniband/core/uverbs_cmd.c
@@ -1,6 +1,7 @@
/*
* Copyright (c) 2005 Topspin Communications. All rights reserved.
* Copyright (c) 2005 Cisco Systems. All rights reserved.
+ * Copyright (c) 2005 PathScale, Inc. All rights reserved.
*
* This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU
@@ -33,6 +34,9 @@
* $Id: uverbs_cmd.c 2708 2005-06-24 17:27:21Z roland $
*/
+#include <linux/file.h>
+#include <linux/fs.h>
+
#include <asm/uaccess.h>
#include "uverbs.h"
@@ -45,29 +49,6 @@
(udata)->outlen = (olen); \
} while (0)
-ssize_t ib_uverbs_query_params(struct ib_uverbs_file *file,
- const char __user *buf,
- int in_len, int out_len)
-{
- struct ib_uverbs_query_params cmd;
- struct ib_uverbs_query_params_resp resp;
-
- if (out_len < sizeof resp)
- return -ENOSPC;
-
- if (copy_from_user(&cmd, buf, sizeof cmd))
- return -EFAULT;
-
- memset(&resp, 0, sizeof resp);
-
- resp.num_cq_events = file->device->num_comp;
-
- if (copy_to_user((void __user *) (unsigned long) cmd.response, &resp, sizeof resp))
- return -EFAULT;
-
- return in_len;
-}
-
ssize_t ib_uverbs_get_context(struct ib_uverbs_file *file,
const char __user *buf,
int in_len, int out_len)
@@ -77,7 +58,7 @@ ssize_t ib_uverbs_get_context(struct ib_uverbs_file *file,
struct ib_udata udata;
struct ib_device *ibdev = file->device->ib_dev;
struct ib_ucontext *ucontext;
- int i;
+ struct file *filp;
int ret;
if (out_len < sizeof resp)
@@ -110,26 +91,42 @@ ssize_t ib_uverbs_get_context(struct ib_uverbs_file *file,
INIT_LIST_HEAD(&ucontext->srq_list);
INIT_LIST_HEAD(&ucontext->ah_list);
- resp.async_fd = file->async_file.fd;
- for (i = 0; i < file->device->num_comp; ++i)
- if (copy_to_user((void __user *) (unsigned long) cmd.cq_fd_tab +
- i * sizeof (__u32),
- &file->comp_file[i].fd, sizeof (__u32))) {
- ret = -EFAULT;
- goto err_free;
- }
+ resp.num_comp_vectors = file->device->num_comp_vectors;
+
+ filp = ib_uverbs_alloc_event_file(file, 1, &resp.async_fd);
+ if (IS_ERR(filp)) {
+ ret = PTR_ERR(filp);
+ goto err_free;
+ }
if (copy_to_user((void __user *) (unsigned long) cmd.response,
&resp, sizeof resp)) {
ret = -EFAULT;
- goto err_free;
+ goto err_file;
}
+ file->async_file = filp->private_data;
+
+ INIT_IB_EVENT_HANDLER(&file->event_handler, file->device->ib_dev,
+ ib_uverbs_event_handler);
+ ret = ib_register_event_handler(&file->event_handler);
+ if (ret)
+ goto err_file;
+
+ kref_get(&file->async_file->ref);
+ kref_get(&file->ref);
file->ucontext = ucontext;
+
+ fd_install(resp.async_fd, filp);
+
up(&file->mutex);
return in_len;
+err_file:
+ put_unused_fd(resp.async_fd);
+ fput(filp);
+
err_free:
ibdev->dealloc_ucontext(ucontext);
@@ -255,62 +252,6 @@ ssize_t ib_uverbs_query_port(struct ib_uverbs_file *file,
return in_len;
}
-ssize_t ib_uverbs_query_gid(struct ib_uverbs_file *file,
- const char __user *buf,
- int in_len, int out_len)
-{
- struct ib_uverbs_query_gid cmd;
- struct ib_uverbs_query_gid_resp resp;
- int ret;
-
- if (out_len < sizeof resp)
- return -ENOSPC;
-
- if (copy_from_user(&cmd, buf, sizeof cmd))
- return -EFAULT;
-
- memset(&resp, 0, sizeof resp);
-
- ret = ib_query_gid(file->device->ib_dev, cmd.port_num, cmd.index,
- (union ib_gid *) resp.gid);
- if (ret)
- return ret;
-
- if (copy_to_user((void __user *) (unsigned long) cmd.response,
- &resp, sizeof resp))
- return -EFAULT;
-
- return in_len;
-}
-
-ssize_t ib_uverbs_query_pkey(struct ib_uverbs_file *file,
- const char __user *buf,
- int in_len, int out_len)
-{
- struct ib_uverbs_query_pkey cmd;
- struct ib_uverbs_query_pkey_resp resp;
- int ret;
-
- if (out_len < sizeof resp)
- return -ENOSPC;
-
- if (copy_from_user(&cmd, buf, sizeof cmd))
- return -EFAULT;
-
- memset(&resp, 0, sizeof resp);
-
- ret = ib_query_pkey(file->device->ib_dev, cmd.port_num, cmd.index,
- &resp.pkey);
- if (ret)
- return ret;
-
- if (copy_to_user((void __user *) (unsigned long) cmd.response,
- &resp, sizeof resp))
- return -EFAULT;
-
- return in_len;
-}
-
ssize_t ib_uverbs_alloc_pd(struct ib_uverbs_file *file,
const char __user *buf,
int in_len, int out_len)
@@ -349,24 +290,20 @@ ssize_t ib_uverbs_alloc_pd(struct ib_uverbs_file *file,
pd->uobject = uobj;
atomic_set(&pd->usecnt, 0);
+ down(&ib_uverbs_idr_mutex);
+
retry:
if (!idr_pre_get(&ib_uverbs_pd_idr, GFP_KERNEL)) {
ret = -ENOMEM;
- goto err_pd;
+ goto err_up;
}
- down(&ib_uverbs_idr_mutex);
ret = idr_get_new(&ib_uverbs_pd_idr, pd, &uobj->id);
- up(&ib_uverbs_idr_mutex);
if (ret == -EAGAIN)
goto retry;
if (ret)
- goto err_pd;
-
- down(&file->mutex);
- list_add_tail(&uobj->list, &file->ucontext->pd_list);
- up(&file->mutex);
+ goto err_up;
memset(&resp, 0, sizeof resp);
resp.pd_handle = uobj->id;
@@ -374,21 +311,22 @@ retry:
if (copy_to_user((void __user *) (unsigned long) cmd.response,
&resp, sizeof resp)) {
ret = -EFAULT;
- goto err_list;
+ goto err_idr;
}
- return in_len;
-
-err_list:
- down(&file->mutex);
- list_del(&uobj->list);
+ down(&file->mutex);
+ list_add_tail(&uobj->list, &file->ucontext->pd_list);
up(&file->mutex);
- down(&ib_uverbs_idr_mutex);
- idr_remove(&ib_uverbs_pd_idr, uobj->id);
up(&ib_uverbs_idr_mutex);
-err_pd:
+ return in_len;
+
+err_idr:
+ idr_remove(&ib_uverbs_pd_idr, uobj->id);
+
+err_up:
+ up(&ib_uverbs_idr_mutex);
ib_dealloc_pd(pd);
err:
@@ -459,6 +397,14 @@ ssize_t ib_uverbs_reg_mr(struct ib_uverbs_file *file,
if ((cmd.start & ~PAGE_MASK) != (cmd.hca_va & ~PAGE_MASK))
return -EINVAL;
+ /*
+ * Local write permission is required if remote write or
+ * remote atomic permission is also requested.
+ */
+ if (cmd.access_flags & (IB_ACCESS_REMOTE_ATOMIC | IB_ACCESS_REMOTE_WRITE) &&
+ !(cmd.access_flags & IB_ACCESS_LOCAL_WRITE))
+ return -EINVAL;
+
obj = kmalloc(sizeof *obj, GFP_KERNEL);
if (!obj)
return -ENOMEM;
@@ -524,24 +470,22 @@ retry:
resp.mr_handle = obj->uobject.id;
- down(&file->mutex);
- list_add_tail(&obj->uobject.list, &file->ucontext->mr_list);
- up(&file->mutex);
-
if (copy_to_user((void __user *) (unsigned long) cmd.response,
&resp, sizeof resp)) {
ret = -EFAULT;
- goto err_list;
+ goto err_idr;
}
+ down(&file->mutex);
+ list_add_tail(&obj->uobject.list, &file->ucontext->mr_list);
+ up(&file->mutex);
+
up(&ib_uverbs_idr_mutex);
return in_len;
-err_list:
- down(&file->mutex);
- list_del(&obj->uobject.list);
- up(&file->mutex);
+err_idr:
+ idr_remove(&ib_uverbs_mr_idr, obj->uobject.id);
err_unreg:
ib_dereg_mr(mr);
@@ -595,6 +539,35 @@ out:
return ret ? ret : in_len;
}
+ssize_t ib_uverbs_create_comp_channel(struct ib_uverbs_file *file,
+ const char __user *buf, int in_len,
+ int out_len)
+{
+ struct ib_uverbs_create_comp_channel cmd;
+ struct ib_uverbs_create_comp_channel_resp resp;
+ struct file *filp;
+
+ if (out_len < sizeof resp)
+ return -ENOSPC;
+
+ if (copy_from_user(&cmd, buf, sizeof cmd))
+ return -EFAULT;
+
+ filp = ib_uverbs_alloc_event_file(file, 0, &resp.fd);
+ if (IS_ERR(filp))
+ return PTR_ERR(filp);
+
+ if (copy_to_user((void __user *) (unsigned long) cmd.response,
+ &resp, sizeof resp)) {
+ put_unused_fd(resp.fd);
+ fput(filp);
+ return -EFAULT;
+ }
+
+ fd_install(resp.fd, filp);
+ return in_len;
+}
+
ssize_t ib_uverbs_create_cq(struct ib_uverbs_file *file,
const char __user *buf, int in_len,
int out_len)
@@ -603,6 +576,7 @@ ssize_t ib_uverbs_create_cq(struct ib_uverbs_file *file,
struct ib_uverbs_create_cq_resp resp;
struct ib_udata udata;
struct ib_ucq_object *uobj;
+ struct ib_uverbs_event_file *ev_file = NULL;
struct ib_cq *cq;
int ret;
@@ -616,15 +590,19 @@ ssize_t ib_uverbs_create_cq(struct ib_uverbs_file *file,
(unsigned long) cmd.response + sizeof resp,
in_len - sizeof cmd, out_len - sizeof resp);
- if (cmd.event_handler >= file->device->num_comp)
+ if (cmd.comp_vector >= file->device->num_comp_vectors)
return -EINVAL;
+ if (cmd.comp_channel >= 0)
+ ev_file = ib_uverbs_lookup_comp_file(cmd.comp_channel);
+
uobj = kmalloc(sizeof *uobj, GFP_KERNEL);
if (!uobj)
return -ENOMEM;
uobj->uobject.user_handle = cmd.user_handle;
uobj->uobject.context = file->ucontext;
+ uobj->uverbs_file = file;
uobj->comp_events_reported = 0;
uobj->async_events_reported = 0;
INIT_LIST_HEAD(&uobj->comp_list);
@@ -641,27 +619,23 @@ ssize_t ib_uverbs_create_cq(struct ib_uverbs_file *file,
cq->uobject = &uobj->uobject;
cq->comp_handler = ib_uverbs_comp_handler;
cq->event_handler = ib_uverbs_cq_event_handler;
- cq->cq_context = file;
+ cq->cq_context = ev_file;
atomic_set(&cq->usecnt, 0);
+ down(&ib_uverbs_idr_mutex);
+
retry:
if (!idr_pre_get(&ib_uverbs_cq_idr, GFP_KERNEL)) {
ret = -ENOMEM;
- goto err_cq;
+ goto err_up;
}
- down(&ib_uverbs_idr_mutex);
ret = idr_get_new(&ib_uverbs_cq_idr, cq, &uobj->uobject.id);
- up(&ib_uverbs_idr_mutex);
if (ret == -EAGAIN)
goto retry;
if (ret)
- goto err_cq;
-
- down(&file->mutex);
- list_add_tail(&uobj->uobject.list, &file->ucontext->cq_list);
- up(&file->mutex);
+ goto err_up;
memset(&resp, 0, sizeof resp);
resp.cq_handle = uobj->uobject.id;
@@ -670,21 +644,22 @@ retry:
if (copy_to_user((void __user *) (unsigned long) cmd.response,
&resp, sizeof resp)) {
ret = -EFAULT;
- goto err_list;
+ goto err_idr;
}
- return in_len;
-
-err_list:
- down(&file->mutex);
- list_del(&uobj->uobject.list);
+ down(&file->mutex);
+ list_add_tail(&uobj->uobject.list, &file->ucontext->cq_list);
up(&file->mutex);
- down(&ib_uverbs_idr_mutex);
- idr_remove(&ib_uverbs_cq_idr, uobj->uobject.id);
up(&ib_uverbs_idr_mutex);
-err_cq:
+ return in_len;
+
+err_idr:
+ idr_remove(&ib_uverbs_cq_idr, uobj->uobject.id);
+
+err_up:
+ up(&ib_uverbs_idr_mutex);
ib_destroy_cq(cq);
err:
@@ -692,6 +667,93 @@ err:
return ret;
}
+ssize_t ib_uverbs_poll_cq(struct ib_uverbs_file *file,
+ const char __user *buf, int in_len,
+ int out_len)
+{
+ struct ib_uverbs_poll_cq cmd;
+ struct ib_uverbs_poll_cq_resp *resp;
+ struct ib_cq *cq;
+ struct ib_wc *wc;
+ int ret = 0;
+ int i;
+ int rsize;
+
+ if (copy_from_user(&cmd, buf, sizeof cmd))
+ return -EFAULT;
+
+ wc = kmalloc(cmd.ne * sizeof *wc, GFP_KERNEL);
+ if (!wc)
+ return -ENOMEM;
+
+ rsize = sizeof *resp + cmd.ne * sizeof(struct ib_uverbs_wc);
+ resp = kmalloc(rsize, GFP_KERNEL);
+ if (!resp) {
+ ret = -ENOMEM;
+ goto out_wc;
+ }
+
+ down(&ib_uverbs_idr_mutex);
+ cq = idr_find(&ib_uverbs_cq_idr, cmd.cq_handle);
+ if (!cq || cq->uobject->context != file->ucontext) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ resp->count = ib_poll_cq(cq, cmd.ne, wc);
+
+ for (i = 0; i < resp->count; i++) {
+ resp->wc[i].wr_id = wc[i].wr_id;
+ resp->wc[i].status = wc[i].status;
+ resp->wc[i].opcode = wc[i].opcode;
+ resp->wc[i].vendor_err = wc[i].vendor_err;
+ resp->wc[i].byte_len = wc[i].byte_len;
+ resp->wc[i].imm_data = (__u32 __force) wc[i].imm_data;
+ resp->wc[i].qp_num = wc[i].qp_num;
+ resp->wc[i].src_qp = wc[i].src_qp;
+ resp->wc[i].wc_flags = wc[i].wc_flags;
+ resp->wc[i].pkey_index = wc[i].pkey_index;
+ resp->wc[i].slid = wc[i].slid;
+ resp->wc[i].sl = wc[i].sl;
+ resp->wc[i].dlid_path_bits = wc[i].dlid_path_bits;
+ resp->wc[i].port_num = wc[i].port_num;
+ }
+
+ if (copy_to_user((void __user *) (unsigned long) cmd.response, resp, rsize))
+ ret = -EFAULT;
+
+out:
+ up(&ib_uverbs_idr_mutex);
+ kfree(resp);
+
+out_wc:
+ kfree(wc);
+ return ret ? ret : in_len;
+}
+
+ssize_t ib_uverbs_req_notify_cq(struct ib_uverbs_file *file,
+ const char __user *buf, int in_len,
+ int out_len)
+{
+ struct ib_uverbs_req_notify_cq cmd;
+ struct ib_cq *cq;
+ int ret = -EINVAL;
+
+ if (copy_from_user(&cmd, buf, sizeof cmd))
+ return -EFAULT;
+
+ down(&ib_uverbs_idr_mutex);
+ cq = idr_find(&ib_uverbs_cq_idr, cmd.cq_handle);
+ if (cq && cq->uobject->context == file->ucontext) {
+ ib_req_notify_cq(cq, cmd.solicited_only ?
+ IB_CQ_SOLICITED : IB_CQ_NEXT_COMP);
+ ret = in_len;
+ }
+ up(&ib_uverbs_idr_mutex);
+
+ return ret;
+}
+
ssize_t ib_uverbs_destroy_cq(struct ib_uverbs_file *file,
const char __user *buf, int in_len,
int out_len)
@@ -700,7 +762,7 @@ ssize_t ib_uverbs_destroy_cq(struct ib_uverbs_file *file,
struct ib_uverbs_destroy_cq_resp resp;
struct ib_cq *cq;
struct ib_ucq_object *uobj;
- struct ib_uverbs_event *evt, *tmp;
+ struct ib_uverbs_event_file *ev_file;
u64 user_handle;
int ret = -EINVAL;
@@ -716,7 +778,8 @@ ssize_t ib_uverbs_destroy_cq(struct ib_uverbs_file *file,
goto out;
user_handle = cq->uobject->user_handle;
- uobj = container_of(cq->uobject, struct ib_ucq_object, uobject);
+ uobj = container_of(cq->uobject, struct ib_ucq_object, uobject);
+ ev_file = cq->cq_context;
ret = ib_destroy_cq(cq);
if (ret)
@@ -728,19 +791,7 @@ ssize_t ib_uverbs_destroy_cq(struct ib_uverbs_file *file,
list_del(&uobj->uobject.list);
up(&file->mutex);
- spin_lock_irq(&file->comp_file[0].lock);
- list_for_each_entry_safe(evt, tmp, &uobj->comp_list, obj_list) {
- list_del(&evt->list);
- kfree(evt);
- }
- spin_unlock_irq(&file->comp_file[0].lock);
-
- spin_lock_irq(&file->async_file.lock);
- list_for_each_entry_safe(evt, tmp, &uobj->async_list, obj_list) {
- list_del(&evt->list);
- kfree(evt);
- }
- spin_unlock_irq(&file->async_file.lock);
+ ib_uverbs_release_ucq(file, ev_file, uobj);
resp.comp_events_reported = uobj->comp_events_reported;
resp.async_events_reported = uobj->async_events_reported;
@@ -857,26 +908,29 @@ retry:
if (ret)
goto err_destroy;
- resp.qp_handle = uobj->uobject.id;
-
- down(&file->mutex);
- list_add_tail(&uobj->uobject.list, &file->ucontext->qp_list);
- up(&file->mutex);
+ resp.qp_handle = uobj->uobject.id;
+ resp.max_recv_sge = attr.cap.max_recv_sge;
+ resp.max_send_sge = attr.cap.max_send_sge;
+ resp.max_recv_wr = attr.cap.max_recv_wr;
+ resp.max_send_wr = attr.cap.max_send_wr;
+ resp.max_inline_data = attr.cap.max_inline_data;
if (copy_to_user((void __user *) (unsigned long) cmd.response,
&resp, sizeof resp)) {
ret = -EFAULT;
- goto err_list;
+ goto err_idr;
}
+ down(&file->mutex);
+ list_add_tail(&uobj->uobject.list, &file->ucontext->qp_list);
+ up(&file->mutex);
+
up(&ib_uverbs_idr_mutex);
return in_len;
-err_list:
- down(&file->mutex);
- list_del(&uobj->uobject.list);
- up(&file->mutex);
+err_idr:
+ idr_remove(&ib_uverbs_qp_idr, uobj->uobject.id);
err_destroy:
ib_destroy_qp(qp);
@@ -979,7 +1033,6 @@ ssize_t ib_uverbs_destroy_qp(struct ib_uverbs_file *file,
struct ib_uverbs_destroy_qp_resp resp;
struct ib_qp *qp;
struct ib_uevent_object *uobj;
- struct ib_uverbs_event *evt, *tmp;
int ret = -EINVAL;
if (copy_from_user(&cmd, buf, sizeof cmd))
@@ -1005,12 +1058,7 @@ ssize_t ib_uverbs_destroy_qp(struct ib_uverbs_file *file,
list_del(&uobj->uobject.list);
up(&file->mutex);
- spin_lock_irq(&file->async_file.lock);
- list_for_each_entry_safe(evt, tmp, &uobj->event_list, obj_list) {
- list_del(&evt->list);
- kfree(evt);
- }
- spin_unlock_irq(&file->async_file.lock);
+ ib_uverbs_release_uevent(file, uobj);
resp.events_reported = uobj->events_reported;
@@ -1026,6 +1074,468 @@ out:
return ret ? ret : in_len;
}
+ssize_t ib_uverbs_post_send(struct ib_uverbs_file *file,
+ const char __user *buf, int in_len,
+ int out_len)
+{
+ struct ib_uverbs_post_send cmd;
+ struct ib_uverbs_post_send_resp resp;
+ struct ib_uverbs_send_wr *user_wr;
+ struct ib_send_wr *wr = NULL, *last, *next, *bad_wr;
+ struct ib_qp *qp;
+ int i, sg_ind;
+ ssize_t ret = -EINVAL;
+
+ if (copy_from_user(&cmd, buf, sizeof cmd))
+ return -EFAULT;
+
+ if (in_len < sizeof cmd + cmd.wqe_size * cmd.wr_count +
+ cmd.sge_count * sizeof (struct ib_uverbs_sge))
+ return -EINVAL;
+
+ if (cmd.wqe_size < sizeof (struct ib_uverbs_send_wr))
+ return -EINVAL;
+
+ user_wr = kmalloc(cmd.wqe_size, GFP_KERNEL);
+ if (!user_wr)
+ return -ENOMEM;
+
+ down(&ib_uverbs_idr_mutex);
+
+ qp = idr_find(&ib_uverbs_qp_idr, cmd.qp_handle);
+ if (!qp || qp->uobject->context != file->ucontext)
+ goto out;
+
+ sg_ind = 0;
+ last = NULL;
+ for (i = 0; i < cmd.wr_count; ++i) {
+ if (copy_from_user(user_wr,
+ buf + sizeof cmd + i * cmd.wqe_size,
+ cmd.wqe_size)) {
+ ret = -EFAULT;
+ goto out;
+ }
+
+ if (user_wr->num_sge + sg_ind > cmd.sge_count) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ next = kmalloc(ALIGN(sizeof *next, sizeof (struct ib_sge)) +
+ user_wr->num_sge * sizeof (struct ib_sge),
+ GFP_KERNEL);
+ if (!next) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ if (!last)
+ wr = next;
+ else
+ last->next = next;
+ last = next;
+
+ next->next = NULL;
+ next->wr_id = user_wr->wr_id;
+ next->num_sge = user_wr->num_sge;
+ next->opcode = user_wr->opcode;
+ next->send_flags = user_wr->send_flags;
+ next->imm_data = (__be32 __force) user_wr->imm_data;
+
+ if (qp->qp_type == IB_QPT_UD) {
+ next->wr.ud.ah = idr_find(&ib_uverbs_ah_idr,
+ user_wr->wr.ud.ah);
+ if (!next->wr.ud.ah) {
+ ret = -EINVAL;
+ goto out;
+ }
+ next->wr.ud.remote_qpn = user_wr->wr.ud.remote_qpn;
+ next->wr.ud.remote_qkey = user_wr->wr.ud.remote_qkey;
+ } else {
+ switch (next->opcode) {
+ case IB_WR_RDMA_WRITE:
+ case IB_WR_RDMA_WRITE_WITH_IMM:
+ case IB_WR_RDMA_READ:
+ next->wr.rdma.remote_addr =
+ user_wr->wr.rdma.remote_addr;
+ next->wr.rdma.rkey =
+ user_wr->wr.rdma.rkey;
+ break;
+ case IB_WR_ATOMIC_CMP_AND_SWP:
+ case IB_WR_ATOMIC_FETCH_AND_ADD:
+ next->wr.atomic.remote_addr =
+ user_wr->wr.atomic.remote_addr;
+ next->wr.atomic.compare_add =
+ user_wr->wr.atomic.compare_add;
+ next->wr.atomic.swap = user_wr->wr.atomic.swap;
+ next->wr.atomic.rkey = user_wr->wr.atomic.rkey;
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (next->num_sge) {
+ next->sg_list = (void *) next +
+ ALIGN(sizeof *next, sizeof (struct ib_sge));
+ if (copy_from_user(next->sg_list,
+ buf + sizeof cmd +
+ cmd.wr_count * cmd.wqe_size +
+ sg_ind * sizeof (struct ib_sge),
+ next->num_sge * sizeof (struct ib_sge))) {
+ ret = -EFAULT;
+ goto out;
+ }
+ sg_ind += next->num_sge;
+ } else
+ next->sg_list = NULL;
+ }
+
+ resp.bad_wr = 0;
+ ret = qp->device->post_send(qp, wr, &bad_wr);
+ if (ret)
+ for (next = wr; next; next = next->next) {
+ ++resp.bad_wr;
+ if (next == bad_wr)
+ break;
+ }
+
+ if (copy_to_user((void __user *) (unsigned long) cmd.response,
+ &resp, sizeof resp))
+ ret = -EFAULT;
+
+out:
+ up(&ib_uverbs_idr_mutex);
+
+ while (wr) {
+ next = wr->next;
+ kfree(wr);
+ wr = next;
+ }
+
+ kfree(user_wr);
+
+ return ret ? ret : in_len;
+}
+
+static struct ib_recv_wr *ib_uverbs_unmarshall_recv(const char __user *buf,
+ int in_len,
+ u32 wr_count,
+ u32 sge_count,
+ u32 wqe_size)
+{
+ struct ib_uverbs_recv_wr *user_wr;
+ struct ib_recv_wr *wr = NULL, *last, *next;
+ int sg_ind;
+ int i;
+ int ret;
+
+ if (in_len < wqe_size * wr_count +
+ sge_count * sizeof (struct ib_uverbs_sge))
+ return ERR_PTR(-EINVAL);
+
+ if (wqe_size < sizeof (struct ib_uverbs_recv_wr))
+ return ERR_PTR(-EINVAL);
+
+ user_wr = kmalloc(wqe_size, GFP_KERNEL);
+ if (!user_wr)
+ return ERR_PTR(-ENOMEM);
+
+ sg_ind = 0;
+ last = NULL;
+ for (i = 0; i < wr_count; ++i) {
+ if (copy_from_user(user_wr, buf + i * wqe_size,
+ wqe_size)) {
+ ret = -EFAULT;
+ goto err;
+ }
+
+ if (user_wr->num_sge + sg_ind > sge_count) {
+ ret = -EINVAL;
+ goto err;
+ }
+
+ next = kmalloc(ALIGN(sizeof *next, sizeof (struct ib_sge)) +
+ user_wr->num_sge * sizeof (struct ib_sge),
+ GFP_KERNEL);
+ if (!next) {
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ if (!last)
+ wr = next;
+ else
+ last->next = next;
+ last = next;
+
+ next->next = NULL;
+ next->wr_id = user_wr->wr_id;
+ next->num_sge = user_wr->num_sge;
+
+ if (next->num_sge) {
+ next->sg_list = (void *) next +
+ ALIGN(sizeof *next, sizeof (struct ib_sge));
+ if (copy_from_user(next->sg_list,
+ buf + wr_count * wqe_size +
+ sg_ind * sizeof (struct ib_sge),
+ next->num_sge * sizeof (struct ib_sge))) {
+ ret = -EFAULT;
+ goto err;
+ }
+ sg_ind += next->num_sge;
+ } else
+ next->sg_list = NULL;
+ }
+
+ kfree(user_wr);
+ return wr;
+
+err:
+ kfree(user_wr);
+
+ while (wr) {
+ next = wr->next;
+ kfree(wr);
+ wr = next;
+ }
+
+ return ERR_PTR(ret);
+}
+
+ssize_t ib_uverbs_post_recv(struct ib_uverbs_file *file,
+ const char __user *buf, int in_len,
+ int out_len)
+{
+ struct ib_uverbs_post_recv cmd;
+ struct ib_uverbs_post_recv_resp resp;
+ struct ib_recv_wr *wr, *next, *bad_wr;
+ struct ib_qp *qp;
+ ssize_t ret = -EINVAL;
+
+ if (copy_from_user(&cmd, buf, sizeof cmd))
+ return -EFAULT;
+
+ wr = ib_uverbs_unmarshall_recv(buf + sizeof cmd,
+ in_len - sizeof cmd, cmd.wr_count,
+ cmd.sge_count, cmd.wqe_size);
+ if (IS_ERR(wr))
+ return PTR_ERR(wr);
+
+ down(&ib_uverbs_idr_mutex);
+
+ qp = idr_find(&ib_uverbs_qp_idr, cmd.qp_handle);
+ if (!qp || qp->uobject->context != file->ucontext)
+ goto out;
+
+ resp.bad_wr = 0;
+ ret = qp->device->post_recv(qp, wr, &bad_wr);
+ if (ret)
+ for (next = wr; next; next = next->next) {
+ ++resp.bad_wr;
+ if (next == bad_wr)
+ break;
+ }
+
+
+ if (copy_to_user((void __user *) (unsigned long) cmd.response,
+ &resp, sizeof resp))
+ ret = -EFAULT;
+
+out:
+ up(&ib_uverbs_idr_mutex);
+
+ while (wr) {
+ next = wr->next;
+ kfree(wr);
+ wr = next;
+ }
+
+ return ret ? ret : in_len;
+}
+
+ssize_t ib_uverbs_post_srq_recv(struct ib_uverbs_file *file,
+ const char __user *buf, int in_len,
+ int out_len)
+{
+ struct ib_uverbs_post_srq_recv cmd;
+ struct ib_uverbs_post_srq_recv_resp resp;
+ struct ib_recv_wr *wr, *next, *bad_wr;
+ struct ib_srq *srq;
+ ssize_t ret = -EINVAL;
+
+ if (copy_from_user(&cmd, buf, sizeof cmd))
+ return -EFAULT;
+
+ wr = ib_uverbs_unmarshall_recv(buf + sizeof cmd,
+ in_len - sizeof cmd, cmd.wr_count,
+ cmd.sge_count, cmd.wqe_size);
+ if (IS_ERR(wr))
+ return PTR_ERR(wr);
+
+ down(&ib_uverbs_idr_mutex);
+
+ srq = idr_find(&ib_uverbs_srq_idr, cmd.srq_handle);
+ if (!srq || srq->uobject->context != file->ucontext)
+ goto out;
+
+ resp.bad_wr = 0;
+ ret = srq->device->post_srq_recv(srq, wr, &bad_wr);
+ if (ret)
+ for (next = wr; next; next = next->next) {
+ ++resp.bad_wr;
+ if (next == bad_wr)
+ break;
+ }
+
+
+ if (copy_to_user((void __user *) (unsigned long) cmd.response,
+ &resp, sizeof resp))
+ ret = -EFAULT;
+
+out:
+ up(&ib_uverbs_idr_mutex);
+
+ while (wr) {
+ next = wr->next;
+ kfree(wr);
+ wr = next;
+ }
+
+ return ret ? ret : in_len;
+}
+
+ssize_t ib_uverbs_create_ah(struct ib_uverbs_file *file,
+ const char __user *buf, int in_len,
+ int out_len)
+{
+ struct ib_uverbs_create_ah cmd;
+ struct ib_uverbs_create_ah_resp resp;
+ struct ib_uobject *uobj;
+ struct ib_pd *pd;
+ struct ib_ah *ah;
+ struct ib_ah_attr attr;
+ int ret;
+
+ if (out_len < sizeof resp)
+ return -ENOSPC;
+
+ if (copy_from_user(&cmd, buf, sizeof cmd))
+ return -EFAULT;
+
+ uobj = kmalloc(sizeof *uobj, GFP_KERNEL);
+ if (!uobj)
+ return -ENOMEM;
+
+ down(&ib_uverbs_idr_mutex);
+
+ pd = idr_find(&ib_uverbs_pd_idr, cmd.pd_handle);
+ if (!pd || pd->uobject->context != file->ucontext) {
+ ret = -EINVAL;
+ goto err_up;
+ }
+
+ uobj->user_handle = cmd.user_handle;
+ uobj->context = file->ucontext;
+
+ attr.dlid = cmd.attr.dlid;
+ attr.sl = cmd.attr.sl;
+ attr.src_path_bits = cmd.attr.src_path_bits;
+ attr.static_rate = cmd.attr.static_rate;
+ attr.port_num = cmd.attr.port_num;
+ attr.grh.flow_label = cmd.attr.grh.flow_label;
+ attr.grh.sgid_index = cmd.attr.grh.sgid_index;
+ attr.grh.hop_limit = cmd.attr.grh.hop_limit;
+ attr.grh.traffic_class = cmd.attr.grh.traffic_class;
+ memcpy(attr.grh.dgid.raw, cmd.attr.grh.dgid, 16);
+
+ ah = ib_create_ah(pd, &attr);
+ if (IS_ERR(ah)) {
+ ret = PTR_ERR(ah);
+ goto err_up;
+ }
+
+ ah->uobject = uobj;
+
+retry:
+ if (!idr_pre_get(&ib_uverbs_ah_idr, GFP_KERNEL)) {
+ ret = -ENOMEM;
+ goto err_destroy;
+ }
+
+ ret = idr_get_new(&ib_uverbs_ah_idr, ah, &uobj->id);
+
+ if (ret == -EAGAIN)
+ goto retry;
+ if (ret)
+ goto err_destroy;
+
+ resp.ah_handle = uobj->id;
+
+ if (copy_to_user((void __user *) (unsigned long) cmd.response,
+ &resp, sizeof resp)) {
+ ret = -EFAULT;
+ goto err_idr;
+ }
+
+ down(&file->mutex);
+ list_add_tail(&uobj->list, &file->ucontext->ah_list);
+ up(&file->mutex);
+
+ up(&ib_uverbs_idr_mutex);
+
+ return in_len;
+
+err_idr:
+ idr_remove(&ib_uverbs_ah_idr, uobj->id);
+
+err_destroy:
+ ib_destroy_ah(ah);
+
+err_up:
+ up(&ib_uverbs_idr_mutex);
+
+ kfree(uobj);
+ return ret;
+}
+
+ssize_t ib_uverbs_destroy_ah(struct ib_uverbs_file *file,
+ const char __user *buf, int in_len, int out_len)
+{
+ struct ib_uverbs_destroy_ah cmd;
+ struct ib_ah *ah;
+ struct ib_uobject *uobj;
+ int ret = -EINVAL;
+
+ if (copy_from_user(&cmd, buf, sizeof cmd))
+ return -EFAULT;
+
+ down(&ib_uverbs_idr_mutex);
+
+ ah = idr_find(&ib_uverbs_ah_idr, cmd.ah_handle);
+ if (!ah || ah->uobject->context != file->ucontext)
+ goto out;
+
+ uobj = ah->uobject;
+
+ ret = ib_destroy_ah(ah);
+ if (ret)
+ goto out;
+
+ idr_remove(&ib_uverbs_ah_idr, cmd.ah_handle);
+
+ down(&file->mutex);
+ list_del(&uobj->list);
+ up(&file->mutex);
+
+ kfree(uobj);
+
+out:
+ up(&ib_uverbs_idr_mutex);
+
+ return ret ? ret : in_len;
+}
+
ssize_t ib_uverbs_attach_mcast(struct ib_uverbs_file *file,
const char __user *buf, int in_len,
int out_len)
@@ -1148,24 +1658,22 @@ retry:
resp.srq_handle = uobj->uobject.id;
- down(&file->mutex);
- list_add_tail(&uobj->uobject.list, &file->ucontext->srq_list);
- up(&file->mutex);
-
if (copy_to_user((void __user *) (unsigned long) cmd.response,
&resp, sizeof resp)) {
ret = -EFAULT;
- goto err_list;
+ goto err_idr;
}
+ down(&file->mutex);
+ list_add_tail(&uobj->uobject.list, &file->ucontext->srq_list);
+ up(&file->mutex);
+
up(&ib_uverbs_idr_mutex);
return in_len;
-err_list:
- down(&file->mutex);
- list_del(&uobj->uobject.list);
- up(&file->mutex);
+err_idr:
+ idr_remove(&ib_uverbs_srq_idr, uobj->uobject.id);
err_destroy:
ib_destroy_srq(srq);
@@ -1198,7 +1706,6 @@ ssize_t ib_uverbs_modify_srq(struct ib_uverbs_file *file,
}
attr.max_wr = cmd.max_wr;
- attr.max_sge = cmd.max_sge;
attr.srq_limit = cmd.srq_limit;
ret = ib_modify_srq(srq, &attr, cmd.attr_mask);
@@ -1217,7 +1724,6 @@ ssize_t ib_uverbs_destroy_srq(struct ib_uverbs_file *file,
struct ib_uverbs_destroy_srq_resp resp;
struct ib_srq *srq;
struct ib_uevent_object *uobj;
- struct ib_uverbs_event *evt, *tmp;
int ret = -EINVAL;
if (copy_from_user(&cmd, buf, sizeof cmd))
@@ -1243,12 +1749,7 @@ ssize_t ib_uverbs_destroy_srq(struct ib_uverbs_file *file,
list_del(&uobj->uobject.list);
up(&file->mutex);
- spin_lock_irq(&file->async_file.lock);
- list_for_each_entry_safe(evt, tmp, &uobj->event_list, obj_list) {
- list_del(&evt->list);
- kfree(evt);
- }
- spin_unlock_irq(&file->async_file.lock);
+ ib_uverbs_release_uevent(file, uobj);
resp.events_reported = uobj->events_reported;
diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/core/uverbs_main.c
index 12511808de21..de6581d7cb8d 100644
--- a/drivers/infiniband/core/uverbs_main.c
+++ b/drivers/infiniband/core/uverbs_main.c
@@ -3,6 +3,7 @@
* Copyright (c) 2005 Cisco Systems. All rights reserved.
* Copyright (c) 2005 Mellanox Technologies. All rights reserved.
* Copyright (c) 2005 Voltaire, Inc. All rights reserved.
+ * Copyright (c) 2005 PathScale, Inc. All rights reserved.
*
* This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU
@@ -43,6 +44,7 @@
#include <linux/poll.h>
#include <linux/file.h>
#include <linux/mount.h>
+#include <linux/cdev.h>
#include <asm/uaccess.h>
@@ -62,6 +64,8 @@ enum {
#define IB_UVERBS_BASE_DEV MKDEV(IB_UVERBS_MAJOR, IB_UVERBS_BASE_MINOR)
+static struct class *uverbs_class;
+
DECLARE_MUTEX(ib_uverbs_idr_mutex);
DEFINE_IDR(ib_uverbs_pd_idr);
DEFINE_IDR(ib_uverbs_mr_idr);
@@ -72,31 +76,37 @@ DEFINE_IDR(ib_uverbs_qp_idr);
DEFINE_IDR(ib_uverbs_srq_idr);
static spinlock_t map_lock;
+static struct ib_uverbs_device *dev_table[IB_UVERBS_MAX_DEVICES];
static DECLARE_BITMAP(dev_map, IB_UVERBS_MAX_DEVICES);
static ssize_t (*uverbs_cmd_table[])(struct ib_uverbs_file *file,
const char __user *buf, int in_len,
int out_len) = {
- [IB_USER_VERBS_CMD_QUERY_PARAMS] = ib_uverbs_query_params,
- [IB_USER_VERBS_CMD_GET_CONTEXT] = ib_uverbs_get_context,
- [IB_USER_VERBS_CMD_QUERY_DEVICE] = ib_uverbs_query_device,
- [IB_USER_VERBS_CMD_QUERY_PORT] = ib_uverbs_query_port,
- [IB_USER_VERBS_CMD_QUERY_GID] = ib_uverbs_query_gid,
- [IB_USER_VERBS_CMD_QUERY_PKEY] = ib_uverbs_query_pkey,
- [IB_USER_VERBS_CMD_ALLOC_PD] = ib_uverbs_alloc_pd,
- [IB_USER_VERBS_CMD_DEALLOC_PD] = ib_uverbs_dealloc_pd,
- [IB_USER_VERBS_CMD_REG_MR] = ib_uverbs_reg_mr,
- [IB_USER_VERBS_CMD_DEREG_MR] = ib_uverbs_dereg_mr,
- [IB_USER_VERBS_CMD_CREATE_CQ] = ib_uverbs_create_cq,
- [IB_USER_VERBS_CMD_DESTROY_CQ] = ib_uverbs_destroy_cq,
- [IB_USER_VERBS_CMD_CREATE_QP] = ib_uverbs_create_qp,
- [IB_USER_VERBS_CMD_MODIFY_QP] = ib_uverbs_modify_qp,
- [IB_USER_VERBS_CMD_DESTROY_QP] = ib_uverbs_destroy_qp,
- [IB_USER_VERBS_CMD_ATTACH_MCAST] = ib_uverbs_attach_mcast,
- [IB_USER_VERBS_CMD_DETACH_MCAST] = ib_uverbs_detach_mcast,
- [IB_USER_VERBS_CMD_CREATE_SRQ] = ib_uverbs_create_srq,
- [IB_USER_VERBS_CMD_MODIFY_SRQ] = ib_uverbs_modify_srq,
- [IB_USER_VERBS_CMD_DESTROY_SRQ] = ib_uverbs_destroy_srq,
+ [IB_USER_VERBS_CMD_GET_CONTEXT] = ib_uverbs_get_context,
+ [IB_USER_VERBS_CMD_QUERY_DEVICE] = ib_uverbs_query_device,
+ [IB_USER_VERBS_CMD_QUERY_PORT] = ib_uverbs_query_port,
+ [IB_USER_VERBS_CMD_ALLOC_PD] = ib_uverbs_alloc_pd,
+ [IB_USER_VERBS_CMD_DEALLOC_PD] = ib_uverbs_dealloc_pd,
+ [IB_USER_VERBS_CMD_REG_MR] = ib_uverbs_reg_mr,
+ [IB_USER_VERBS_CMD_DEREG_MR] = ib_uverbs_dereg_mr,
+ [IB_USER_VERBS_CMD_CREATE_COMP_CHANNEL] = ib_uverbs_create_comp_channel,
+ [IB_USER_VERBS_CMD_CREATE_CQ] = ib_uverbs_create_cq,
+ [IB_USER_VERBS_CMD_POLL_CQ] = ib_uverbs_poll_cq,
+ [IB_USER_VERBS_CMD_REQ_NOTIFY_CQ] = ib_uverbs_req_notify_cq,
+ [IB_USER_VERBS_CMD_DESTROY_CQ] = ib_uverbs_destroy_cq,
+ [IB_USER_VERBS_CMD_CREATE_QP] = ib_uverbs_create_qp,
+ [IB_USER_VERBS_CMD_MODIFY_QP] = ib_uverbs_modify_qp,
+ [IB_USER_VERBS_CMD_DESTROY_QP] = ib_uverbs_destroy_qp,
+ [IB_USER_VERBS_CMD_POST_SEND] = ib_uverbs_post_send,
+ [IB_USER_VERBS_CMD_POST_RECV] = ib_uverbs_post_recv,
+ [IB_USER_VERBS_CMD_POST_SRQ_RECV] = ib_uverbs_post_srq_recv,
+ [IB_USER_VERBS_CMD_CREATE_AH] = ib_uverbs_create_ah,
+ [IB_USER_VERBS_CMD_DESTROY_AH] = ib_uverbs_destroy_ah,
+ [IB_USER_VERBS_CMD_ATTACH_MCAST] = ib_uverbs_attach_mcast,
+ [IB_USER_VERBS_CMD_DETACH_MCAST] = ib_uverbs_detach_mcast,
+ [IB_USER_VERBS_CMD_CREATE_SRQ] = ib_uverbs_create_srq,
+ [IB_USER_VERBS_CMD_MODIFY_SRQ] = ib_uverbs_modify_srq,
+ [IB_USER_VERBS_CMD_DESTROY_SRQ] = ib_uverbs_destroy_srq,
};
static struct vfsmount *uverbs_event_mnt;
@@ -104,7 +114,54 @@ static struct vfsmount *uverbs_event_mnt;
static void ib_uverbs_add_one(struct ib_device *device);
static void ib_uverbs_remove_one(struct ib_device *device);
-static int ib_dealloc_ucontext(struct ib_ucontext *context)
+static void ib_uverbs_release_dev(struct kref *ref)
+{
+ struct ib_uverbs_device *dev =
+ container_of(ref, struct ib_uverbs_device, ref);
+
+ kfree(dev);
+}
+
+void ib_uverbs_release_ucq(struct ib_uverbs_file *file,
+ struct ib_uverbs_event_file *ev_file,
+ struct ib_ucq_object *uobj)
+{
+ struct ib_uverbs_event *evt, *tmp;
+
+ if (ev_file) {
+ spin_lock_irq(&ev_file->lock);
+ list_for_each_entry_safe(evt, tmp, &uobj->comp_list, obj_list) {
+ list_del(&evt->list);
+ kfree(evt);
+ }
+ spin_unlock_irq(&ev_file->lock);
+
+ kref_put(&ev_file->ref, ib_uverbs_release_event_file);
+ }
+
+ spin_lock_irq(&file->async_file->lock);
+ list_for_each_entry_safe(evt, tmp, &uobj->async_list, obj_list) {
+ list_del(&evt->list);
+ kfree(evt);
+ }
+ spin_unlock_irq(&file->async_file->lock);
+}
+
+void ib_uverbs_release_uevent(struct ib_uverbs_file *file,
+ struct ib_uevent_object *uobj)
+{
+ struct ib_uverbs_event *evt, *tmp;
+
+ spin_lock_irq(&file->async_file->lock);
+ list_for_each_entry_safe(evt, tmp, &uobj->event_list, obj_list) {
+ list_del(&evt->list);
+ kfree(evt);
+ }
+ spin_unlock_irq(&file->async_file->lock);
+}
+
+static int ib_uverbs_cleanup_ucontext(struct ib_uverbs_file *file,
+ struct ib_ucontext *context)
{
struct ib_uobject *uobj, *tmp;
@@ -113,30 +170,46 @@ static int ib_dealloc_ucontext(struct ib_ucontext *context)
down(&ib_uverbs_idr_mutex);
- /* XXX Free AHs */
+ list_for_each_entry_safe(uobj, tmp, &context->ah_list, list) {
+ struct ib_ah *ah = idr_find(&ib_uverbs_ah_idr, uobj->id);
+ idr_remove(&ib_uverbs_ah_idr, uobj->id);
+ ib_destroy_ah(ah);
+ list_del(&uobj->list);
+ kfree(uobj);
+ }
list_for_each_entry_safe(uobj, tmp, &context->qp_list, list) {
struct ib_qp *qp = idr_find(&ib_uverbs_qp_idr, uobj->id);
+ struct ib_uevent_object *uevent =
+ container_of(uobj, struct ib_uevent_object, uobject);
idr_remove(&ib_uverbs_qp_idr, uobj->id);
ib_destroy_qp(qp);
list_del(&uobj->list);
- kfree(container_of(uobj, struct ib_uevent_object, uobject));
+ ib_uverbs_release_uevent(file, uevent);
+ kfree(uevent);
}
list_for_each_entry_safe(uobj, tmp, &context->cq_list, list) {
struct ib_cq *cq = idr_find(&ib_uverbs_cq_idr, uobj->id);
+ struct ib_uverbs_event_file *ev_file = cq->cq_context;
+ struct ib_ucq_object *ucq =
+ container_of(uobj, struct ib_ucq_object, uobject);
idr_remove(&ib_uverbs_cq_idr, uobj->id);
ib_destroy_cq(cq);
list_del(&uobj->list);
- kfree(container_of(uobj, struct ib_ucq_object, uobject));
+ ib_uverbs_release_ucq(file, ev_file, ucq);
+ kfree(ucq);
}
list_for_each_entry_safe(uobj, tmp, &context->srq_list, list) {
struct ib_srq *srq = idr_find(&ib_uverbs_srq_idr, uobj->id);
+ struct ib_uevent_object *uevent =
+ container_of(uobj, struct ib_uevent_object, uobject);
idr_remove(&ib_uverbs_srq_idr, uobj->id);
ib_destroy_srq(srq);
list_del(&uobj->list);
- kfree(container_of(uobj, struct ib_uevent_object, uobject));
+ ib_uverbs_release_uevent(file, uevent);
+ kfree(uevent);
}
/* XXX Free MWs */
@@ -175,6 +248,8 @@ static void ib_uverbs_release_file(struct kref *ref)
container_of(ref, struct ib_uverbs_file, ref);
module_put(file->device->ib_dev->owner);
+ kref_put(&file->device->ref, ib_uverbs_release_dev);
+
kfree(file);
}
@@ -188,25 +263,19 @@ static ssize_t ib_uverbs_event_read(struct file *filp, char __user *buf,
spin_lock_irq(&file->lock);
- while (list_empty(&file->event_list) && file->fd >= 0) {
+ while (list_empty(&file->event_list)) {
spin_unlock_irq(&file->lock);
if (filp->f_flags & O_NONBLOCK)
return -EAGAIN;
if (wait_event_interruptible(file->poll_wait,
- !list_empty(&file->event_list) ||
- file->fd < 0))
+ !list_empty(&file->event_list)))
return -ERESTARTSYS;
spin_lock_irq(&file->lock);
}
- if (file->fd < 0) {
- spin_unlock_irq(&file->lock);
- return -ENODEV;
- }
-
event = list_entry(file->event_list.next, struct ib_uverbs_event, list);
if (file->is_async)
@@ -248,26 +317,19 @@ static unsigned int ib_uverbs_event_poll(struct file *filp,
poll_wait(filp, &file->poll_wait, wait);
spin_lock_irq(&file->lock);
- if (file->fd < 0)
- pollflags = POLLERR;
- else if (!list_empty(&file->event_list))
+ if (!list_empty(&file->event_list))
pollflags = POLLIN | POLLRDNORM;
spin_unlock_irq(&file->lock);
return pollflags;
}
-static void ib_uverbs_event_release(struct ib_uverbs_event_file *file)
+void ib_uverbs_release_event_file(struct kref *ref)
{
- struct ib_uverbs_event *entry, *tmp;
+ struct ib_uverbs_event_file *file =
+ container_of(ref, struct ib_uverbs_event_file, ref);
- spin_lock_irq(&file->lock);
- if (file->fd != -1) {
- file->fd = -1;
- list_for_each_entry_safe(entry, tmp, &file->event_list, list)
- kfree(entry);
- }
- spin_unlock_irq(&file->lock);
+ kfree(file);
}
static int ib_uverbs_event_fasync(int fd, struct file *filp, int on)
@@ -280,21 +342,30 @@ static int ib_uverbs_event_fasync(int fd, struct file *filp, int on)
static int ib_uverbs_event_close(struct inode *inode, struct file *filp)
{
struct ib_uverbs_event_file *file = filp->private_data;
+ struct ib_uverbs_event *entry, *tmp;
+
+ spin_lock_irq(&file->lock);
+ file->file = NULL;
+ list_for_each_entry_safe(entry, tmp, &file->event_list, list) {
+ if (entry->counter)
+ list_del(&entry->obj_list);
+ kfree(entry);
+ }
+ spin_unlock_irq(&file->lock);
- ib_uverbs_event_release(file);
ib_uverbs_event_fasync(-1, filp, 0);
- kref_put(&file->uverbs_file->ref, ib_uverbs_release_file);
+
+ if (file->is_async) {
+ ib_unregister_event_handler(&file->uverbs_file->event_handler);
+ kref_put(&file->uverbs_file->ref, ib_uverbs_release_file);
+ }
+ kref_put(&file->ref, ib_uverbs_release_event_file);
return 0;
}
static struct file_operations uverbs_event_fops = {
- /*
- * No .owner field since we artificially create event files,
- * so there is no increment to the module reference count in
- * the open path. All event files come from a uverbs command
- * file, which already takes a module reference, so this is OK.
- */
+ .owner = THIS_MODULE,
.read = ib_uverbs_event_read,
.poll = ib_uverbs_event_poll,
.release = ib_uverbs_event_close,
@@ -303,27 +374,37 @@ static struct file_operations uverbs_event_fops = {
void ib_uverbs_comp_handler(struct ib_cq *cq, void *cq_context)
{
- struct ib_uverbs_file *file = cq_context;
- struct ib_ucq_object *uobj;
- struct ib_uverbs_event *entry;
- unsigned long flags;
+ struct ib_uverbs_event_file *file = cq_context;
+ struct ib_ucq_object *uobj;
+ struct ib_uverbs_event *entry;
+ unsigned long flags;
+
+ if (!file)
+ return;
+
+ spin_lock_irqsave(&file->lock, flags);
+ if (!file->file) {
+ spin_unlock_irqrestore(&file->lock, flags);
+ return;
+ }
entry = kmalloc(sizeof *entry, GFP_ATOMIC);
- if (!entry)
+ if (!entry) {
+ spin_unlock_irqrestore(&file->lock, flags);
return;
+ }
uobj = container_of(cq->uobject, struct ib_ucq_object, uobject);
entry->desc.comp.cq_handle = cq->uobject->user_handle;
entry->counter = &uobj->comp_events_reported;
- spin_lock_irqsave(&file->comp_file[0].lock, flags);
- list_add_tail(&entry->list, &file->comp_file[0].event_list);
+ list_add_tail(&entry->list, &file->event_list);
list_add_tail(&entry->obj_list, &uobj->comp_list);
- spin_unlock_irqrestore(&file->comp_file[0].lock, flags);
+ spin_unlock_irqrestore(&file->lock, flags);
- wake_up_interruptible(&file->comp_file[0].poll_wait);
- kill_fasync(&file->comp_file[0].async_queue, SIGIO, POLL_IN);
+ wake_up_interruptible(&file->poll_wait);
+ kill_fasync(&file->async_queue, SIGIO, POLL_IN);
}
static void ib_uverbs_async_handler(struct ib_uverbs_file *file,
@@ -334,32 +415,37 @@ static void ib_uverbs_async_handler(struct ib_uverbs_file *file,
struct ib_uverbs_event *entry;
unsigned long flags;
+ spin_lock_irqsave(&file->async_file->lock, flags);
+ if (!file->async_file->file) {
+ spin_unlock_irqrestore(&file->async_file->lock, flags);
+ return;
+ }
+
entry = kmalloc(sizeof *entry, GFP_ATOMIC);
- if (!entry)
+ if (!entry) {
+ spin_unlock_irqrestore(&file->async_file->lock, flags);
return;
+ }
entry->desc.async.element = element;
entry->desc.async.event_type = event;
entry->counter = counter;
- spin_lock_irqsave(&file->async_file.lock, flags);
- list_add_tail(&entry->list, &file->async_file.event_list);
+ list_add_tail(&entry->list, &file->async_file->event_list);
if (obj_list)
list_add_tail(&entry->obj_list, obj_list);
- spin_unlock_irqrestore(&file->async_file.lock, flags);
+ spin_unlock_irqrestore(&file->async_file->lock, flags);
- wake_up_interruptible(&file->async_file.poll_wait);
- kill_fasync(&file->async_file.async_queue, SIGIO, POLL_IN);
+ wake_up_interruptible(&file->async_file->poll_wait);
+ kill_fasync(&file->async_file->async_queue, SIGIO, POLL_IN);
}
void ib_uverbs_cq_event_handler(struct ib_event *event, void *context_ptr)
{
- struct ib_ucq_object *uobj;
-
- uobj = container_of(event->element.cq->uobject,
- struct ib_ucq_object, uobject);
+ struct ib_ucq_object *uobj = container_of(event->element.cq->uobject,
+ struct ib_ucq_object, uobject);
- ib_uverbs_async_handler(context_ptr, uobj->uobject.user_handle,
+ ib_uverbs_async_handler(uobj->uverbs_file, uobj->uobject.user_handle,
event->event, &uobj->async_list,
&uobj->async_events_reported);
@@ -389,8 +475,8 @@ void ib_uverbs_srq_event_handler(struct ib_event *event, void *context_ptr)
&uobj->events_reported);
}
-static void ib_uverbs_event_handler(struct ib_event_handler *handler,
- struct ib_event *event)
+void ib_uverbs_event_handler(struct ib_event_handler *handler,
+ struct ib_event *event)
{
struct ib_uverbs_file *file =
container_of(handler, struct ib_uverbs_file, event_handler);
@@ -399,38 +485,90 @@ static void ib_uverbs_event_handler(struct ib_event_handler *handler,
NULL, NULL);
}
-static int ib_uverbs_event_init(struct ib_uverbs_event_file *file,
- struct ib_uverbs_file *uverbs_file)
+struct file *ib_uverbs_alloc_event_file(struct ib_uverbs_file *uverbs_file,
+ int is_async, int *fd)
{
+ struct ib_uverbs_event_file *ev_file;
struct file *filp;
+ int ret;
- spin_lock_init(&file->lock);
- INIT_LIST_HEAD(&file->event_list);
- init_waitqueue_head(&file->poll_wait);
- file->uverbs_file = uverbs_file;
- file->async_queue = NULL;
-
- file->fd = get_unused_fd();
- if (file->fd < 0)
- return file->fd;
+ ev_file = kmalloc(sizeof *ev_file, GFP_KERNEL);
+ if (!ev_file)
+ return ERR_PTR(-ENOMEM);
+
+ kref_init(&ev_file->ref);
+ spin_lock_init(&ev_file->lock);
+ INIT_LIST_HEAD(&ev_file->event_list);
+ init_waitqueue_head(&ev_file->poll_wait);
+ ev_file->uverbs_file = uverbs_file;
+ ev_file->async_queue = NULL;
+ ev_file->is_async = is_async;
+
+ *fd = get_unused_fd();
+ if (*fd < 0) {
+ ret = *fd;
+ goto err;
+ }
filp = get_empty_filp();
if (!filp) {
- put_unused_fd(file->fd);
- return -ENFILE;
+ ret = -ENFILE;
+ goto err_fd;
}
- filp->f_op = &uverbs_event_fops;
+ ev_file->file = filp;
+
+ /*
+ * fops_get() can't fail here, because we're coming from a
+ * system call on a uverbs file, which will already have a
+ * module reference.
+ */
+ filp->f_op = fops_get(&uverbs_event_fops);
filp->f_vfsmnt = mntget(uverbs_event_mnt);
filp->f_dentry = dget(uverbs_event_mnt->mnt_root);
filp->f_mapping = filp->f_dentry->d_inode->i_mapping;
filp->f_flags = O_RDONLY;
filp->f_mode = FMODE_READ;
- filp->private_data = file;
+ filp->private_data = ev_file;
- fd_install(file->fd, filp);
+ return filp;
- return 0;
+err_fd:
+ put_unused_fd(*fd);
+
+err:
+ kfree(ev_file);
+ return ERR_PTR(ret);
+}
+
+/*
+ * Look up a completion event file by FD. If lookup is successful,
+ * takes a ref to the event file struct that it returns; if
+ * unsuccessful, returns NULL.
+ */
+struct ib_uverbs_event_file *ib_uverbs_lookup_comp_file(int fd)
+{
+ struct ib_uverbs_event_file *ev_file = NULL;
+ struct file *filp;
+
+ filp = fget(fd);
+ if (!filp)
+ return NULL;
+
+ if (filp->f_op != &uverbs_event_fops)
+ goto out;
+
+ ev_file = filp->private_data;
+ if (ev_file->is_async) {
+ ev_file = NULL;
+ goto out;
+ }
+
+ kref_get(&ev_file->ref);
+
+out:
+ fput(filp);
+ return ev_file;
}
static ssize_t ib_uverbs_write(struct file *filp, const char __user *buf,
@@ -450,11 +588,11 @@ static ssize_t ib_uverbs_write(struct file *filp, const char __user *buf,
if (hdr.command < 0 ||
hdr.command >= ARRAY_SIZE(uverbs_cmd_table) ||
- !uverbs_cmd_table[hdr.command])
+ !uverbs_cmd_table[hdr.command] ||
+ !(file->device->ib_dev->uverbs_cmd_mask & (1ull << hdr.command)))
return -EINVAL;
- if (!file->ucontext &&
- hdr.command != IB_USER_VERBS_CMD_QUERY_PARAMS &&
+ if (!file->ucontext &&
hdr.command != IB_USER_VERBS_CMD_GET_CONTEXT)
return -EINVAL;
@@ -474,84 +612,57 @@ static int ib_uverbs_mmap(struct file *filp, struct vm_area_struct *vma)
static int ib_uverbs_open(struct inode *inode, struct file *filp)
{
- struct ib_uverbs_device *dev =
- container_of(inode->i_cdev, struct ib_uverbs_device, dev);
+ struct ib_uverbs_device *dev;
struct ib_uverbs_file *file;
- int i = 0;
int ret;
- if (!try_module_get(dev->ib_dev->owner))
- return -ENODEV;
+ spin_lock(&map_lock);
+ dev = dev_table[iminor(inode) - IB_UVERBS_BASE_MINOR];
+ if (dev)
+ kref_get(&dev->ref);
+ spin_unlock(&map_lock);
+
+ if (!dev)
+ return -ENXIO;
+
+ if (!try_module_get(dev->ib_dev->owner)) {
+ ret = -ENODEV;
+ goto err;
+ }
- file = kmalloc(sizeof *file +
- (dev->num_comp - 1) * sizeof (struct ib_uverbs_event_file),
- GFP_KERNEL);
+ file = kmalloc(sizeof *file, GFP_KERNEL);
if (!file) {
ret = -ENOMEM;
- goto err;
+ goto err_module;
}
- file->device = dev;
+ file->device = dev;
+ file->ucontext = NULL;
+ file->async_file = NULL;
kref_init(&file->ref);
init_MUTEX(&file->mutex);
- file->ucontext = NULL;
-
- kref_get(&file->ref);
- ret = ib_uverbs_event_init(&file->async_file, file);
- if (ret)
- goto err_kref;
-
- file->async_file.is_async = 1;
-
- for (i = 0; i < dev->num_comp; ++i) {
- kref_get(&file->ref);
- ret = ib_uverbs_event_init(&file->comp_file[i], file);
- if (ret)
- goto err_async;
- file->comp_file[i].is_async = 0;
- }
-
-
filp->private_data = file;
- INIT_IB_EVENT_HANDLER(&file->event_handler, dev->ib_dev,
- ib_uverbs_event_handler);
- if (ib_register_event_handler(&file->event_handler))
- goto err_async;
-
return 0;
-err_async:
- while (i--)
- ib_uverbs_event_release(&file->comp_file[i]);
-
- ib_uverbs_event_release(&file->async_file);
-
-err_kref:
- /*
- * One extra kref_put() because we took a reference before the
- * event file creation that failed and got us here.
- */
- kref_put(&file->ref, ib_uverbs_release_file);
- kref_put(&file->ref, ib_uverbs_release_file);
+err_module:
+ module_put(dev->ib_dev->owner);
err:
- module_put(dev->ib_dev->owner);
+ kref_put(&dev->ref, ib_uverbs_release_dev);
+
return ret;
}
static int ib_uverbs_close(struct inode *inode, struct file *filp)
{
struct ib_uverbs_file *file = filp->private_data;
- int i;
- ib_unregister_event_handler(&file->event_handler);
- ib_uverbs_event_release(&file->async_file);
- ib_dealloc_ucontext(file->ucontext);
+ ib_uverbs_cleanup_ucontext(file, file->ucontext);
- for (i = 0; i < file->device->num_comp; ++i)
- ib_uverbs_event_release(&file->comp_file[i]);
+ if (file->async_file)
+ kref_put(&file->async_file->ref, ib_uverbs_release_event_file);
kref_put(&file->ref, ib_uverbs_release_file);
@@ -581,27 +692,25 @@ static struct ib_client uverbs_client = {
static ssize_t show_ibdev(struct class_device *class_dev, char *buf)
{
- struct ib_uverbs_device *dev =
- container_of(class_dev, struct ib_uverbs_device, class_dev);
+ struct ib_uverbs_device *dev = class_get_devdata(class_dev);
+
+ if (!dev)
+ return -ENODEV;
return sprintf(buf, "%s\n", dev->ib_dev->name);
}
static CLASS_DEVICE_ATTR(ibdev, S_IRUGO, show_ibdev, NULL);
-static void ib_uverbs_release_class_dev(struct class_device *class_dev)
+static ssize_t show_dev_abi_version(struct class_device *class_dev, char *buf)
{
- struct ib_uverbs_device *dev =
- container_of(class_dev, struct ib_uverbs_device, class_dev);
+ struct ib_uverbs_device *dev = class_get_devdata(class_dev);
- cdev_del(&dev->dev);
- clear_bit(dev->devnum, dev_map);
- kfree(dev);
-}
+ if (!dev)
+ return -ENODEV;
-static struct class uverbs_class = {
- .name = "infiniband_verbs",
- .release = ib_uverbs_release_class_dev
-};
+ return sprintf(buf, "%d\n", dev->ib_dev->uverbs_abi_ver);
+}
+static CLASS_DEVICE_ATTR(abi_version, S_IRUGO, show_dev_abi_version, NULL);
static ssize_t show_abi_version(struct class *class, char *buf)
{
@@ -616,11 +725,11 @@ static void ib_uverbs_add_one(struct ib_device *device)
if (!device->alloc_ucontext)
return;
- uverbs_dev = kmalloc(sizeof *uverbs_dev, GFP_KERNEL);
+ uverbs_dev = kzalloc(sizeof *uverbs_dev, GFP_KERNEL);
if (!uverbs_dev)
return;
- memset(uverbs_dev, 0, sizeof *uverbs_dev);
+ kref_init(&uverbs_dev->ref);
spin_lock(&map_lock);
uverbs_dev->devnum = find_first_zero_bit(dev_map, IB_UVERBS_MAX_DEVICES);
@@ -631,41 +740,49 @@ static void ib_uverbs_add_one(struct ib_device *device)
set_bit(uverbs_dev->devnum, dev_map);
spin_unlock(&map_lock);
- uverbs_dev->ib_dev = device;
- uverbs_dev->num_comp = 1;
+ uverbs_dev->ib_dev = device;
+ uverbs_dev->num_comp_vectors = 1;
- if (device->mmap)
- cdev_init(&uverbs_dev->dev, &uverbs_mmap_fops);
- else
- cdev_init(&uverbs_dev->dev, &uverbs_fops);
- uverbs_dev->dev.owner = THIS_MODULE;
- kobject_set_name(&uverbs_dev->dev.kobj, "uverbs%d", uverbs_dev->devnum);
- if (cdev_add(&uverbs_dev->dev, IB_UVERBS_BASE_DEV + uverbs_dev->devnum, 1))
+ uverbs_dev->dev = cdev_alloc();
+ if (!uverbs_dev->dev)
goto err;
+ uverbs_dev->dev->owner = THIS_MODULE;
+ uverbs_dev->dev->ops = device->mmap ? &uverbs_mmap_fops : &uverbs_fops;
+ kobject_set_name(&uverbs_dev->dev->kobj, "uverbs%d", uverbs_dev->devnum);
+ if (cdev_add(uverbs_dev->dev, IB_UVERBS_BASE_DEV + uverbs_dev->devnum, 1))
+ goto err_cdev;
- uverbs_dev->class_dev.class = &uverbs_class;
- uverbs_dev->class_dev.dev = device->dma_device;
- uverbs_dev->class_dev.devt = uverbs_dev->dev.dev;
- snprintf(uverbs_dev->class_dev.class_id, BUS_ID_SIZE, "uverbs%d", uverbs_dev->devnum);
- if (class_device_register(&uverbs_dev->class_dev))
+ uverbs_dev->class_dev = class_device_create(uverbs_class, NULL,
+ uverbs_dev->dev->dev,
+ device->dma_device,
+ "uverbs%d", uverbs_dev->devnum);
+ if (IS_ERR(uverbs_dev->class_dev))
goto err_cdev;
- if (class_device_create_file(&uverbs_dev->class_dev, &class_device_attr_ibdev))
+ class_set_devdata(uverbs_dev->class_dev, uverbs_dev);
+
+ if (class_device_create_file(uverbs_dev->class_dev, &class_device_attr_ibdev))
goto err_class;
+ if (class_device_create_file(uverbs_dev->class_dev, &class_device_attr_abi_version))
+ goto err_class;
+
+ spin_lock(&map_lock);
+ dev_table[uverbs_dev->devnum] = uverbs_dev;
+ spin_unlock(&map_lock);
ib_set_client_data(device, &uverbs_client, uverbs_dev);
return;
err_class:
- class_device_unregister(&uverbs_dev->class_dev);
+ class_device_destroy(uverbs_class, uverbs_dev->dev->dev);
err_cdev:
- cdev_del(&uverbs_dev->dev);
+ cdev_del(uverbs_dev->dev);
clear_bit(uverbs_dev->devnum, dev_map);
err:
- kfree(uverbs_dev);
+ kref_put(&uverbs_dev->ref, ib_uverbs_release_dev);
return;
}
@@ -676,7 +793,16 @@ static void ib_uverbs_remove_one(struct ib_device *device)
if (!uverbs_dev)
return;
- class_device_unregister(&uverbs_dev->class_dev);
+ class_set_devdata(uverbs_dev->class_dev, NULL);
+ class_device_destroy(uverbs_class, uverbs_dev->dev->dev);
+ cdev_del(uverbs_dev->dev);
+
+ spin_lock(&map_lock);
+ dev_table[uverbs_dev->devnum] = NULL;
+ spin_unlock(&map_lock);
+
+ clear_bit(uverbs_dev->devnum, dev_map);
+ kref_put(&uverbs_dev->ref, ib_uverbs_release_dev);
}
static struct super_block *uverbs_event_get_sb(struct file_system_type *fs_type, int flags,
@@ -706,13 +832,14 @@ static int __init ib_uverbs_init(void)
goto out;
}
- ret = class_register(&uverbs_class);
- if (ret) {
+ uverbs_class = class_create(THIS_MODULE, "infiniband_verbs");
+ if (IS_ERR(uverbs_class)) {
+ ret = PTR_ERR(uverbs_class);
printk(KERN_ERR "user_verbs: couldn't create class infiniband_verbs\n");
goto out_chrdev;
}
- ret = class_create_file(&uverbs_class, &class_attr_abi_version);
+ ret = class_create_file(uverbs_class, &class_attr_abi_version);
if (ret) {
printk(KERN_ERR "user_verbs: couldn't create abi_version attribute\n");
goto out_class;
@@ -746,7 +873,7 @@ out_fs:
unregister_filesystem(&uverbs_event_fs);
out_class:
- class_unregister(&uverbs_class);
+ class_destroy(uverbs_class);
out_chrdev:
unregister_chrdev_region(IB_UVERBS_BASE_DEV, IB_UVERBS_MAX_DEVICES);
@@ -760,8 +887,15 @@ static void __exit ib_uverbs_cleanup(void)
ib_unregister_client(&uverbs_client);
mntput(uverbs_event_mnt);
unregister_filesystem(&uverbs_event_fs);
- class_unregister(&uverbs_class);
+ class_destroy(uverbs_class);
unregister_chrdev_region(IB_UVERBS_BASE_DEV, IB_UVERBS_MAX_DEVICES);
+ idr_destroy(&ib_uverbs_pd_idr);
+ idr_destroy(&ib_uverbs_mr_idr);
+ idr_destroy(&ib_uverbs_mw_idr);
+ idr_destroy(&ib_uverbs_ah_idr);
+ idr_destroy(&ib_uverbs_cq_idr);
+ idr_destroy(&ib_uverbs_qp_idr);
+ idr_destroy(&ib_uverbs_srq_idr);
}
module_init(ib_uverbs_init);
diff --git a/drivers/infiniband/core/verbs.c b/drivers/infiniband/core/verbs.c
index 5081d903e561..4c15e112736c 100644
--- a/drivers/infiniband/core/verbs.c
+++ b/drivers/infiniband/core/verbs.c
@@ -40,6 +40,7 @@
#include <linux/errno.h>
#include <linux/err.h>
+#include <linux/string.h>
#include <rdma/ib_verbs.h>
#include <rdma/ib_cache.h>
@@ -324,16 +325,8 @@ EXPORT_SYMBOL(ib_destroy_cq);
int ib_resize_cq(struct ib_cq *cq,
int cqe)
{
- int ret;
-
- if (!cq->device->resize_cq)
- return -ENOSYS;
-
- ret = cq->device->resize_cq(cq, &cqe);
- if (!ret)
- cq->cqe = cqe;
-
- return ret;
+ return cq->device->resize_cq ?
+ cq->device->resize_cq(cq, cqe) : -ENOSYS;
}
EXPORT_SYMBOL(ib_resize_cq);
@@ -523,16 +516,22 @@ EXPORT_SYMBOL(ib_dealloc_fmr);
int ib_attach_mcast(struct ib_qp *qp, union ib_gid *gid, u16 lid)
{
- return qp->device->attach_mcast ?
- qp->device->attach_mcast(qp, gid, lid) :
- -ENOSYS;
+ if (!qp->device->attach_mcast)
+ return -ENOSYS;
+ if (gid->raw[0] != 0xff || qp->qp_type != IB_QPT_UD)
+ return -EINVAL;
+
+ return qp->device->attach_mcast(qp, gid, lid);
}
EXPORT_SYMBOL(ib_attach_mcast);
int ib_detach_mcast(struct ib_qp *qp, union ib_gid *gid, u16 lid)
{
- return qp->device->detach_mcast ?
- qp->device->detach_mcast(qp, gid, lid) :
- -ENOSYS;
+ if (!qp->device->detach_mcast)
+ return -ENOSYS;
+ if (gid->raw[0] != 0xff || qp->qp_type != IB_QPT_UD)
+ return -EINVAL;
+
+ return qp->device->detach_mcast(qp, gid, lid);
}
EXPORT_SYMBOL(ib_detach_mcast);
diff --git a/drivers/infiniband/hw/mthca/Makefile b/drivers/infiniband/hw/mthca/Makefile
index c44f7bae5424..47ec5a7cba0b 100644
--- a/drivers/infiniband/hw/mthca/Makefile
+++ b/drivers/infiniband/hw/mthca/Makefile
@@ -7,4 +7,5 @@ obj-$(CONFIG_INFINIBAND_MTHCA) += ib_mthca.o
ib_mthca-y := mthca_main.o mthca_cmd.o mthca_profile.o mthca_reset.o \
mthca_allocator.o mthca_eq.o mthca_pd.o mthca_cq.o \
mthca_mr.o mthca_qp.o mthca_av.o mthca_mcg.o mthca_mad.o \
- mthca_provider.o mthca_memfree.o mthca_uar.o mthca_srq.o
+ mthca_provider.o mthca_memfree.o mthca_uar.o mthca_srq.o \
+ mthca_catas.o
diff --git a/drivers/infiniband/hw/mthca/mthca_av.c b/drivers/infiniband/hw/mthca/mthca_av.c
index 889e85096736..22fdc446f25c 100644
--- a/drivers/infiniband/hw/mthca/mthca_av.c
+++ b/drivers/infiniband/hw/mthca/mthca_av.c
@@ -34,6 +34,8 @@
*/
#include <linux/init.h>
+#include <linux/string.h>
+#include <linux/slab.h>
#include <rdma/ib_verbs.h>
#include <rdma/ib_cache.h>
diff --git a/drivers/infiniband/hw/mthca/mthca_catas.c b/drivers/infiniband/hw/mthca/mthca_catas.c
new file mode 100644
index 000000000000..c3bec7490f52
--- /dev/null
+++ b/drivers/infiniband/hw/mthca/mthca_catas.c
@@ -0,0 +1,156 @@
+/*
+ * Copyright (c) 2005 Cisco Systems. All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses. You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * - Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * 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.
+ *
+ * $Id$
+ */
+
+#include <linux/jiffies.h>
+#include <linux/timer.h>
+
+#include "mthca_dev.h"
+
+enum {
+ MTHCA_CATAS_POLL_INTERVAL = 5 * HZ,
+
+ MTHCA_CATAS_TYPE_INTERNAL = 0,
+ MTHCA_CATAS_TYPE_UPLINK = 3,
+ MTHCA_CATAS_TYPE_DDR = 4,
+ MTHCA_CATAS_TYPE_PARITY = 5,
+};
+
+static DEFINE_SPINLOCK(catas_lock);
+
+static void handle_catas(struct mthca_dev *dev)
+{
+ struct ib_event event;
+ const char *type;
+ int i;
+
+ event.device = &dev->ib_dev;
+ event.event = IB_EVENT_DEVICE_FATAL;
+ event.element.port_num = 0;
+
+ ib_dispatch_event(&event);
+
+ switch (swab32(readl(dev->catas_err.map)) >> 24) {
+ case MTHCA_CATAS_TYPE_INTERNAL:
+ type = "internal error";
+ break;
+ case MTHCA_CATAS_TYPE_UPLINK:
+ type = "uplink bus error";
+ break;
+ case MTHCA_CATAS_TYPE_DDR:
+ type = "DDR data error";
+ break;
+ case MTHCA_CATAS_TYPE_PARITY:
+ type = "internal parity error";
+ break;
+ default:
+ type = "unknown error";
+ break;
+ }
+
+ mthca_err(dev, "Catastrophic error detected: %s\n", type);
+ for (i = 0; i < dev->catas_err.size; ++i)
+ mthca_err(dev, " buf[%02x]: %08x\n",
+ i, swab32(readl(dev->catas_err.map + i)));
+}
+
+static void poll_catas(unsigned long dev_ptr)
+{
+ struct mthca_dev *dev = (struct mthca_dev *) dev_ptr;
+ unsigned long flags;
+ int i;
+
+ for (i = 0; i < dev->catas_err.size; ++i)
+ if (readl(dev->catas_err.map + i)) {
+ handle_catas(dev);
+ return;
+ }
+
+ spin_lock_irqsave(&catas_lock, flags);
+ if (!dev->catas_err.stop)
+ mod_timer(&dev->catas_err.timer,
+ jiffies + MTHCA_CATAS_POLL_INTERVAL);
+ spin_unlock_irqrestore(&catas_lock, flags);
+
+ return;
+}
+
+void mthca_start_catas_poll(struct mthca_dev *dev)
+{
+ unsigned long addr;
+
+ init_timer(&dev->catas_err.timer);
+ dev->catas_err.stop = 0;
+ dev->catas_err.map = NULL;
+
+ addr = pci_resource_start(dev->pdev, 0) +
+ ((pci_resource_len(dev->pdev, 0) - 1) &
+ dev->catas_err.addr);
+
+ if (!request_mem_region(addr, dev->catas_err.size * 4,
+ DRV_NAME)) {
+ mthca_warn(dev, "couldn't request catastrophic error region "
+ "at 0x%lx/0x%x\n", addr, dev->catas_err.size * 4);
+ return;
+ }
+
+ dev->catas_err.map = ioremap(addr, dev->catas_err.size * 4);
+ if (!dev->catas_err.map) {
+ mthca_warn(dev, "couldn't map catastrophic error region "
+ "at 0x%lx/0x%x\n", addr, dev->catas_err.size * 4);
+ release_mem_region(addr, dev->catas_err.size * 4);
+ return;
+ }
+
+ dev->catas_err.timer.data = (unsigned long) dev;
+ dev->catas_err.timer.function = poll_catas;
+ dev->catas_err.timer.expires = jiffies + MTHCA_CATAS_POLL_INTERVAL;
+ add_timer(&dev->catas_err.timer);
+}
+
+void mthca_stop_catas_poll(struct mthca_dev *dev)
+{
+ spin_lock_irq(&catas_lock);
+ dev->catas_err.stop = 1;
+ spin_unlock_irq(&catas_lock);
+
+ del_timer_sync(&dev->catas_err.timer);
+
+ if (dev->catas_err.map) {
+ iounmap(dev->catas_err.map);
+ release_mem_region(pci_resource_start(dev->pdev, 0) +
+ ((pci_resource_len(dev->pdev, 0) - 1) &
+ dev->catas_err.addr),
+ dev->catas_err.size * 4);
+ }
+}
diff --git a/drivers/infiniband/hw/mthca/mthca_cmd.c b/drivers/infiniband/hw/mthca/mthca_cmd.c
index f6a8ac026557..9ed34587fc5c 100644
--- a/drivers/infiniband/hw/mthca/mthca_cmd.c
+++ b/drivers/infiniband/hw/mthca/mthca_cmd.c
@@ -1,6 +1,7 @@
/*
* Copyright (c) 2004, 2005 Topspin Communications. All rights reserved.
* Copyright (c) 2005 Mellanox Technologies. All rights reserved.
+ * Copyright (c) 2005 Cisco Systems. All rights reserved.
*
* This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU
@@ -524,7 +525,7 @@ void mthca_cmd_use_polling(struct mthca_dev *dev)
}
struct mthca_mailbox *mthca_alloc_mailbox(struct mthca_dev *dev,
- unsigned int gfp_mask)
+ gfp_t gfp_mask)
{
struct mthca_mailbox *mailbox;
@@ -706,9 +707,13 @@ int mthca_QUERY_FW(struct mthca_dev *dev, u8 *status)
MTHCA_GET(lg, outbox, QUERY_FW_MAX_CMD_OFFSET);
dev->cmd.max_cmds = 1 << lg;
+ MTHCA_GET(dev->catas_err.addr, outbox, QUERY_FW_ERR_START_OFFSET);
+ MTHCA_GET(dev->catas_err.size, outbox, QUERY_FW_ERR_SIZE_OFFSET);
mthca_dbg(dev, "FW version %012llx, max commands %d\n",
(unsigned long long) dev->fw_ver, dev->cmd.max_cmds);
+ mthca_dbg(dev, "Catastrophic error buffer at 0x%llx, size 0x%x\n",
+ (unsigned long long) dev->catas_err.addr, dev->catas_err.size);
if (mthca_is_memfree(dev)) {
MTHCA_GET(dev->fw.arbel.fw_pages, outbox, QUERY_FW_SIZE_OFFSET);
@@ -933,9 +938,9 @@ int mthca_QUERY_DEV_LIM(struct mthca_dev *dev,
goto out;
MTHCA_GET(field, outbox, QUERY_DEV_LIM_MAX_SRQ_SZ_OFFSET);
- dev_lim->max_srq_sz = 1 << field;
+ dev_lim->max_srq_sz = (1 << field) - 1;
MTHCA_GET(field, outbox, QUERY_DEV_LIM_MAX_QP_SZ_OFFSET);
- dev_lim->max_qp_sz = 1 << field;
+ dev_lim->max_qp_sz = (1 << field) - 1;
MTHCA_GET(field, outbox, QUERY_DEV_LIM_RSVD_QP_OFFSET);
dev_lim->reserved_qps = 1 << (field & 0xf);
MTHCA_GET(field, outbox, QUERY_DEV_LIM_MAX_QP_OFFSET);
@@ -1045,6 +1050,8 @@ int mthca_QUERY_DEV_LIM(struct mthca_dev *dev,
dev_lim->max_pds, dev_lim->reserved_pds, dev_lim->reserved_uars);
mthca_dbg(dev, "Max QP/MCG: %d, reserved MGMs: %d\n",
dev_lim->max_pds, dev_lim->reserved_mgms);
+ mthca_dbg(dev, "Max CQEs: %d, max WQEs: %d, max SRQ WQEs: %d\n",
+ dev_lim->max_cq_sz, dev_lim->max_qp_sz, dev_lim->max_srq_sz);
mthca_dbg(dev, "Flags: %08x\n", dev_lim->flags);
@@ -1053,6 +1060,8 @@ int mthca_QUERY_DEV_LIM(struct mthca_dev *dev,
dev_lim->hca.arbel.resize_srq = field & 1;
MTHCA_GET(field, outbox, QUERY_DEV_LIM_MAX_SG_RQ_OFFSET);
dev_lim->max_sg = min_t(int, field, dev_lim->max_sg);
+ MTHCA_GET(size, outbox, QUERY_DEV_LIM_MAX_DESC_SZ_RQ_OFFSET);
+ dev_lim->max_desc_sz = min_t(int, size, dev_lim->max_desc_sz);
MTHCA_GET(size, outbox, QUERY_DEV_LIM_MPT_ENTRY_SZ_OFFSET);
dev_lim->mpt_entry_sz = size;
MTHCA_GET(field, outbox, QUERY_DEV_LIM_PBL_SZ_OFFSET);
diff --git a/drivers/infiniband/hw/mthca/mthca_cmd.h b/drivers/infiniband/hw/mthca/mthca_cmd.h
index 65f976a13e02..18175bec84c2 100644
--- a/drivers/infiniband/hw/mthca/mthca_cmd.h
+++ b/drivers/infiniband/hw/mthca/mthca_cmd.h
@@ -248,7 +248,7 @@ void mthca_cmd_event(struct mthca_dev *dev, u16 token,
u8 status, u64 out_param);
struct mthca_mailbox *mthca_alloc_mailbox(struct mthca_dev *dev,
- unsigned int gfp_mask);
+ gfp_t gfp_mask);
void mthca_free_mailbox(struct mthca_dev *dev, struct mthca_mailbox *mailbox);
int mthca_SYS_EN(struct mthca_dev *dev, u8 *status);
diff --git a/drivers/infiniband/hw/mthca/mthca_cq.c b/drivers/infiniband/hw/mthca/mthca_cq.c
index 8600b6c3e0c2..4a8adcef2079 100644
--- a/drivers/infiniband/hw/mthca/mthca_cq.c
+++ b/drivers/infiniband/hw/mthca/mthca_cq.c
@@ -208,7 +208,7 @@ static inline void update_cons_index(struct mthca_dev *dev, struct mthca_cq *cq,
}
}
-void mthca_cq_event(struct mthca_dev *dev, u32 cqn)
+void mthca_cq_completion(struct mthca_dev *dev, u32 cqn)
{
struct mthca_cq *cq;
@@ -224,12 +224,41 @@ void mthca_cq_event(struct mthca_dev *dev, u32 cqn)
cq->ibcq.comp_handler(&cq->ibcq, cq->ibcq.cq_context);
}
+void mthca_cq_event(struct mthca_dev *dev, u32 cqn,
+ enum ib_event_type event_type)
+{
+ struct mthca_cq *cq;
+ struct ib_event event;
+
+ spin_lock(&dev->cq_table.lock);
+
+ cq = mthca_array_get(&dev->cq_table.cq, cqn & (dev->limits.num_cqs - 1));
+
+ if (cq)
+ atomic_inc(&cq->refcount);
+ spin_unlock(&dev->cq_table.lock);
+
+ if (!cq) {
+ mthca_warn(dev, "Async event for bogus CQ %08x\n", cqn);
+ return;
+ }
+
+ event.device = &dev->ib_dev;
+ event.event = event_type;
+ event.element.cq = &cq->ibcq;
+ if (cq->ibcq.event_handler)
+ cq->ibcq.event_handler(&event, cq->ibcq.cq_context);
+
+ if (atomic_dec_and_test(&cq->refcount))
+ wake_up(&cq->wait);
+}
+
void mthca_cq_clean(struct mthca_dev *dev, u32 cqn, u32 qpn,
struct mthca_srq *srq)
{
struct mthca_cq *cq;
struct mthca_cqe *cqe;
- int prod_index;
+ u32 prod_index;
int nfreed = 0;
spin_lock_irq(&dev->cq_table.lock);
@@ -264,19 +293,15 @@ void mthca_cq_clean(struct mthca_dev *dev, u32 cqn, u32 qpn,
* Now sweep backwards through the CQ, removing CQ entries
* that match our QP by copying older entries on top of them.
*/
- while (prod_index > cq->cons_index) {
- cqe = get_cqe(cq, (prod_index - 1) & cq->ibcq.cqe);
+ while ((int) --prod_index - (int) cq->cons_index >= 0) {
+ cqe = get_cqe(cq, prod_index & cq->ibcq.cqe);
if (cqe->my_qpn == cpu_to_be32(qpn)) {
if (srq)
mthca_free_srq_wqe(srq, be32_to_cpu(cqe->wqe));
++nfreed;
- }
- else if (nfreed)
- memcpy(get_cqe(cq, (prod_index - 1 + nfreed) &
- cq->ibcq.cqe),
- cqe,
- MTHCA_CQ_ENTRY_SIZE);
- --prod_index;
+ } else if (nfreed)
+ memcpy(get_cqe(cq, (prod_index + nfreed) & cq->ibcq.cqe),
+ cqe, MTHCA_CQ_ENTRY_SIZE);
}
if (nfreed) {
diff --git a/drivers/infiniband/hw/mthca/mthca_dev.h b/drivers/infiniband/hw/mthca/mthca_dev.h
index 7bff5a8425f4..497ff794ef6a 100644
--- a/drivers/infiniband/hw/mthca/mthca_dev.h
+++ b/drivers/infiniband/hw/mthca/mthca_dev.h
@@ -83,6 +83,8 @@ enum {
/* Arbel FW gives us these, but we need them for Tavor */
MTHCA_MPT_ENTRY_SIZE = 0x40,
MTHCA_MTT_SEG_SIZE = 0x40,
+
+ MTHCA_QP_PER_MGM = 4 * (MTHCA_MGM_ENTRY_SIZE / 16 - 2)
};
enum {
@@ -128,12 +130,17 @@ struct mthca_limits {
int num_uars;
int max_sg;
int num_qps;
+ int max_wqes;
+ int max_desc_sz;
+ int max_qp_init_rdma;
int reserved_qps;
int num_srqs;
+ int max_srq_wqes;
int reserved_srqs;
int num_eecs;
int reserved_eecs;
int num_cqs;
+ int max_cqes;
int reserved_cqs;
int num_eqs;
int reserved_eqs;
@@ -148,6 +155,8 @@ struct mthca_limits {
int reserved_mcgs;
int num_pds;
int reserved_pds;
+ u32 page_size_cap;
+ u32 flags;
u8 port_width_cap;
};
@@ -251,6 +260,14 @@ struct mthca_mcg_table {
struct mthca_icm_table *table;
};
+struct mthca_catas_err {
+ u64 addr;
+ u32 __iomem *map;
+ unsigned long stop;
+ u32 size;
+ struct timer_list timer;
+};
+
struct mthca_dev {
struct ib_device ib_dev;
struct pci_dev *pdev;
@@ -311,6 +328,8 @@ struct mthca_dev {
struct mthca_av_table av_table;
struct mthca_mcg_table mcg_table;
+ struct mthca_catas_err catas_err;
+
struct mthca_uar driver_uar;
struct mthca_db_table *db_tab;
struct mthca_pd driver_pd;
@@ -398,6 +417,9 @@ void mthca_cleanup_mcg_table(struct mthca_dev *dev);
int mthca_register_device(struct mthca_dev *dev);
void mthca_unregister_device(struct mthca_dev *dev);
+void mthca_start_catas_poll(struct mthca_dev *dev);
+void mthca_stop_catas_poll(struct mthca_dev *dev);
+
int mthca_uar_alloc(struct mthca_dev *dev, struct mthca_uar *uar);
void mthca_uar_free(struct mthca_dev *dev, struct mthca_uar *uar);
@@ -440,13 +462,17 @@ int mthca_init_cq(struct mthca_dev *dev, int nent,
struct mthca_cq *cq);
void mthca_free_cq(struct mthca_dev *dev,
struct mthca_cq *cq);
-void mthca_cq_event(struct mthca_dev *dev, u32 cqn);
+void mthca_cq_completion(struct mthca_dev *dev, u32 cqn);
+void mthca_cq_event(struct mthca_dev *dev, u32 cqn,
+ enum ib_event_type event_type);
void mthca_cq_clean(struct mthca_dev *dev, u32 cqn, u32 qpn,
struct mthca_srq *srq);
int mthca_alloc_srq(struct mthca_dev *dev, struct mthca_pd *pd,
struct ib_srq_attr *attr, struct mthca_srq *srq);
void mthca_free_srq(struct mthca_dev *dev, struct mthca_srq *srq);
+int mthca_modify_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr,
+ enum ib_srq_attr_mask attr_mask);
void mthca_srq_event(struct mthca_dev *dev, u32 srqn,
enum ib_event_type event_type);
void mthca_free_srq_wqe(struct mthca_srq *srq, u32 wqe_addr);
diff --git a/drivers/infiniband/hw/mthca/mthca_eq.c b/drivers/infiniband/hw/mthca/mthca_eq.c
index 8dfafda5ed24..34d68e5a72d8 100644
--- a/drivers/infiniband/hw/mthca/mthca_eq.c
+++ b/drivers/infiniband/hw/mthca/mthca_eq.c
@@ -83,7 +83,8 @@ enum {
MTHCA_EVENT_TYPE_PATH_MIG = 0x01,
MTHCA_EVENT_TYPE_COMM_EST = 0x02,
MTHCA_EVENT_TYPE_SQ_DRAINED = 0x03,
- MTHCA_EVENT_TYPE_SRQ_LAST_WQE = 0x13,
+ MTHCA_EVENT_TYPE_SRQ_QP_LAST_WQE = 0x13,
+ MTHCA_EVENT_TYPE_SRQ_LIMIT = 0x14,
MTHCA_EVENT_TYPE_CQ_ERROR = 0x04,
MTHCA_EVENT_TYPE_WQ_CATAS_ERROR = 0x05,
MTHCA_EVENT_TYPE_EEC_CATAS_ERROR = 0x06,
@@ -110,8 +111,9 @@ enum {
(1ULL << MTHCA_EVENT_TYPE_LOCAL_CATAS_ERROR) | \
(1ULL << MTHCA_EVENT_TYPE_PORT_CHANGE) | \
(1ULL << MTHCA_EVENT_TYPE_ECC_DETECT))
-#define MTHCA_SRQ_EVENT_MASK (1ULL << MTHCA_EVENT_TYPE_SRQ_CATAS_ERROR) | \
- (1ULL << MTHCA_EVENT_TYPE_SRQ_LAST_WQE)
+#define MTHCA_SRQ_EVENT_MASK ((1ULL << MTHCA_EVENT_TYPE_SRQ_CATAS_ERROR) | \
+ (1ULL << MTHCA_EVENT_TYPE_SRQ_QP_LAST_WQE) | \
+ (1ULL << MTHCA_EVENT_TYPE_SRQ_LIMIT))
#define MTHCA_CMD_EVENT_MASK (1ULL << MTHCA_EVENT_TYPE_CMD)
#define MTHCA_EQ_DB_INC_CI (1 << 24)
@@ -142,6 +144,9 @@ struct mthca_eqe {
__be32 qpn;
} __attribute__((packed)) qp;
struct {
+ __be32 srqn;
+ } __attribute__((packed)) srq;
+ struct {
__be32 cqn;
u32 reserved1;
u8 reserved2[3];
@@ -287,7 +292,7 @@ static int mthca_eq_int(struct mthca_dev *dev, struct mthca_eq *eq)
case MTHCA_EVENT_TYPE_COMP:
disarm_cqn = be32_to_cpu(eqe->event.comp.cqn) & 0xffffff;
disarm_cq(dev, eq->eqn, disarm_cqn);
- mthca_cq_event(dev, disarm_cqn);
+ mthca_cq_completion(dev, disarm_cqn);
break;
case MTHCA_EVENT_TYPE_PATH_MIG:
@@ -305,6 +310,16 @@ static int mthca_eq_int(struct mthca_dev *dev, struct mthca_eq *eq)
IB_EVENT_SQ_DRAINED);
break;
+ case MTHCA_EVENT_TYPE_SRQ_QP_LAST_WQE:
+ mthca_qp_event(dev, be32_to_cpu(eqe->event.qp.qpn) & 0xffffff,
+ IB_EVENT_QP_LAST_WQE_REACHED);
+ break;
+
+ case MTHCA_EVENT_TYPE_SRQ_LIMIT:
+ mthca_srq_event(dev, be32_to_cpu(eqe->event.srq.srqn) & 0xffffff,
+ IB_EVENT_SRQ_LIMIT_REACHED);
+ break;
+
case MTHCA_EVENT_TYPE_WQ_CATAS_ERROR:
mthca_qp_event(dev, be32_to_cpu(eqe->event.qp.qpn) & 0xffffff,
IB_EVENT_QP_FATAL);
@@ -349,6 +364,8 @@ static int mthca_eq_int(struct mthca_dev *dev, struct mthca_eq *eq)
eqe->event.cq_err.syndrome == 1 ?
"overrun" : "access violation",
be32_to_cpu(eqe->event.cq_err.cqn) & 0xffffff);
+ mthca_cq_event(dev, be32_to_cpu(eqe->event.cq_err.cqn),
+ IB_EVENT_CQ_ERR);
break;
case MTHCA_EVENT_TYPE_EQ_OVERFLOW:
diff --git a/drivers/infiniband/hw/mthca/mthca_mad.c b/drivers/infiniband/hw/mthca/mthca_mad.c
index 9804174f7f3c..1229c604c6e0 100644
--- a/drivers/infiniband/hw/mthca/mthca_mad.c
+++ b/drivers/infiniband/hw/mthca/mthca_mad.c
@@ -34,6 +34,9 @@
* $Id: mthca_mad.c 1349 2004-12-16 21:09:43Z roland $
*/
+#include <linux/string.h>
+#include <linux/slab.h>
+
#include <rdma/ib_verbs.h>
#include <rdma/ib_mad.h>
#include <rdma/ib_smi.h>
@@ -46,11 +49,6 @@ enum {
MTHCA_VENDOR_CLASS2 = 0xa
};
-struct mthca_trap_mad {
- struct ib_mad *mad;
- DECLARE_PCI_UNMAP_ADDR(mapping)
-};
-
static void update_sm_ah(struct mthca_dev *dev,
u8 port_num, u16 lid, u8 sl)
{
@@ -116,49 +114,14 @@ static void forward_trap(struct mthca_dev *dev,
struct ib_mad *mad)
{
int qpn = mad->mad_hdr.mgmt_class != IB_MGMT_CLASS_SUBN_LID_ROUTED;
- struct mthca_trap_mad *tmad;
- struct ib_sge gather_list;
- struct ib_send_wr *bad_wr, wr = {
- .opcode = IB_WR_SEND,
- .sg_list = &gather_list,
- .num_sge = 1,
- .send_flags = IB_SEND_SIGNALED,
- .wr = {
- .ud = {
- .remote_qpn = qpn,
- .remote_qkey = qpn ? IB_QP1_QKEY : 0,
- .timeout_ms = 0
- }
- }
- };
+ struct ib_mad_send_buf *send_buf;
struct ib_mad_agent *agent = dev->send_agent[port_num - 1][qpn];
int ret;
unsigned long flags;
if (agent) {
- tmad = kmalloc(sizeof *tmad, GFP_KERNEL);
- if (!tmad)
- return;
-
- tmad->mad = kmalloc(sizeof *tmad->mad, GFP_KERNEL);
- if (!tmad->mad) {
- kfree(tmad);
- return;
- }
-
- memcpy(tmad->mad, mad, sizeof *mad);
-
- wr.wr.ud.mad_hdr = &tmad->mad->mad_hdr;
- wr.wr_id = (unsigned long) tmad;
-
- gather_list.addr = dma_map_single(agent->device->dma_device,
- tmad->mad,
- sizeof *tmad->mad,
- DMA_TO_DEVICE);
- gather_list.length = sizeof *tmad->mad;
- gather_list.lkey = to_mpd(agent->qp->pd)->ntmr.ibmr.lkey;
- pci_unmap_addr_set(tmad, mapping, gather_list.addr);
-
+ send_buf = ib_create_send_mad(agent, qpn, 0, 0, IB_MGMT_MAD_HDR,
+ IB_MGMT_MAD_DATA, GFP_ATOMIC);
/*
* We rely here on the fact that MLX QPs don't use the
* address handle after the send is posted (this is
@@ -166,21 +129,15 @@ static void forward_trap(struct mthca_dev *dev,
* it's OK for our devices).
*/
spin_lock_irqsave(&dev->sm_lock, flags);
- wr.wr.ud.ah = dev->sm_ah[port_num - 1];
- if (wr.wr.ud.ah)
- ret = ib_post_send_mad(agent, &wr, &bad_wr);
+ memcpy(send_buf->mad, mad, sizeof *mad);
+ if ((send_buf->ah = dev->sm_ah[port_num - 1]))
+ ret = ib_post_send_mad(send_buf, NULL);
else
ret = -EINVAL;
spin_unlock_irqrestore(&dev->sm_lock, flags);
- if (ret) {
- dma_unmap_single(agent->device->dma_device,
- pci_unmap_addr(tmad, mapping),
- sizeof *tmad->mad,
- DMA_TO_DEVICE);
- kfree(tmad->mad);
- kfree(tmad);
- }
+ if (ret)
+ ib_free_send_mad(send_buf);
}
}
@@ -267,15 +224,7 @@ int mthca_process_mad(struct ib_device *ibdev,
static void send_handler(struct ib_mad_agent *agent,
struct ib_mad_send_wc *mad_send_wc)
{
- struct mthca_trap_mad *tmad =
- (void *) (unsigned long) mad_send_wc->wr_id;
-
- dma_unmap_single(agent->device->dma_device,
- pci_unmap_addr(tmad, mapping),
- sizeof *tmad->mad,
- DMA_TO_DEVICE);
- kfree(tmad->mad);
- kfree(tmad);
+ ib_free_send_mad(mad_send_wc->send_buf);
}
int mthca_create_agents(struct mthca_dev *dev)
diff --git a/drivers/infiniband/hw/mthca/mthca_main.c b/drivers/infiniband/hw/mthca/mthca_main.c
index 23a3f56c7899..6f94b25f3acd 100644
--- a/drivers/infiniband/hw/mthca/mthca_main.c
+++ b/drivers/infiniband/hw/mthca/mthca_main.c
@@ -162,9 +162,19 @@ static int __devinit mthca_dev_lim(struct mthca_dev *mdev, struct mthca_dev_lim
mdev->limits.pkey_table_len = dev_lim->max_pkeys;
mdev->limits.local_ca_ack_delay = dev_lim->local_ca_ack_delay;
mdev->limits.max_sg = dev_lim->max_sg;
+ mdev->limits.max_wqes = dev_lim->max_qp_sz;
+ mdev->limits.max_qp_init_rdma = dev_lim->max_requester_per_qp;
mdev->limits.reserved_qps = dev_lim->reserved_qps;
+ mdev->limits.max_srq_wqes = dev_lim->max_srq_sz;
mdev->limits.reserved_srqs = dev_lim->reserved_srqs;
mdev->limits.reserved_eecs = dev_lim->reserved_eecs;
+ mdev->limits.max_desc_sz = dev_lim->max_desc_sz;
+ /*
+ * Subtract 1 from the limit because we need to allocate a
+ * spare CQE so the HCA HW can tell the difference between an
+ * empty CQ and a full CQ.
+ */
+ mdev->limits.max_cqes = dev_lim->max_cq_sz - 1;
mdev->limits.reserved_cqs = dev_lim->reserved_cqs;
mdev->limits.reserved_eqs = dev_lim->reserved_eqs;
mdev->limits.reserved_mtts = dev_lim->reserved_mtts;
@@ -172,6 +182,8 @@ static int __devinit mthca_dev_lim(struct mthca_dev *mdev, struct mthca_dev_lim
mdev->limits.reserved_uars = dev_lim->reserved_uars;
mdev->limits.reserved_pds = dev_lim->reserved_pds;
mdev->limits.port_width_cap = dev_lim->max_port_width;
+ mdev->limits.page_size_cap = ~(u32) (dev_lim->min_page_sz - 1);
+ mdev->limits.flags = dev_lim->flags;
/* IB_DEVICE_RESIZE_MAX_WR not supported by driver.
May be doable since hardware supports it for SRQ.
@@ -1047,7 +1059,7 @@ static int __devinit mthca_init_one(struct pci_dev *pdev,
goto err_cmd;
if (mdev->fw_ver < mthca_hca_table[id->driver_data].latest_fw) {
- mthca_warn(mdev, "HCA FW version %x.%x.%x is old (%x.%x.%x is current).\n",
+ mthca_warn(mdev, "HCA FW version %d.%d.%d is old (%d.%d.%d is current).\n",
(int) (mdev->fw_ver >> 32), (int) (mdev->fw_ver >> 16) & 0xffff,
(int) (mdev->fw_ver & 0xffff),
(int) (mthca_hca_table[id->driver_data].latest_fw >> 32),
diff --git a/drivers/infiniband/hw/mthca/mthca_mcg.c b/drivers/infiniband/hw/mthca/mthca_mcg.c
index a2707605f4c8..2fc449da418d 100644
--- a/drivers/infiniband/hw/mthca/mthca_mcg.c
+++ b/drivers/infiniband/hw/mthca/mthca_mcg.c
@@ -33,14 +33,12 @@
*/
#include <linux/init.h>
+#include <linux/string.h>
+#include <linux/slab.h>
#include "mthca_dev.h"
#include "mthca_cmd.h"
-enum {
- MTHCA_QP_PER_MGM = 4 * (MTHCA_MGM_ENTRY_SIZE / 16 - 2)
-};
-
struct mthca_mgm {
__be32 next_gid_index;
u32 reserved[3];
@@ -189,7 +187,12 @@ int mthca_multicast_attach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
}
for (i = 0; i < MTHCA_QP_PER_MGM; ++i)
- if (!(mgm->qp[i] & cpu_to_be32(1 << 31))) {
+ if (mgm->qp[i] == cpu_to_be32(ibqp->qp_num | (1 << 31))) {
+ mthca_dbg(dev, "QP %06x already a member of MGM\n",
+ ibqp->qp_num);
+ err = 0;
+ goto out;
+ } else if (!(mgm->qp[i] & cpu_to_be32(1 << 31))) {
mgm->qp[i] = cpu_to_be32(ibqp->qp_num | (1 << 31));
break;
}
diff --git a/drivers/infiniband/hw/mthca/mthca_memfree.c b/drivers/infiniband/hw/mthca/mthca_memfree.c
index 7bd7a4bec7b4..d72fe95cba08 100644
--- a/drivers/infiniband/hw/mthca/mthca_memfree.c
+++ b/drivers/infiniband/hw/mthca/mthca_memfree.c
@@ -82,7 +82,7 @@ void mthca_free_icm(struct mthca_dev *dev, struct mthca_icm *icm)
}
struct mthca_icm *mthca_alloc_icm(struct mthca_dev *dev, int npages,
- unsigned int gfp_mask)
+ gfp_t gfp_mask)
{
struct mthca_icm *icm;
struct mthca_icm_chunk *chunk = NULL;
@@ -487,7 +487,8 @@ void mthca_cleanup_user_db_tab(struct mthca_dev *dev, struct mthca_uar *uar,
}
}
-int mthca_alloc_db(struct mthca_dev *dev, int type, u32 qn, __be32 **db)
+int mthca_alloc_db(struct mthca_dev *dev, enum mthca_db_type type,
+ u32 qn, __be32 **db)
{
int group;
int start, end, dir;
diff --git a/drivers/infiniband/hw/mthca/mthca_memfree.h b/drivers/infiniband/hw/mthca/mthca_memfree.h
index bafa51544aa3..4fdca26eea85 100644
--- a/drivers/infiniband/hw/mthca/mthca_memfree.h
+++ b/drivers/infiniband/hw/mthca/mthca_memfree.h
@@ -77,7 +77,7 @@ struct mthca_icm_iter {
struct mthca_dev;
struct mthca_icm *mthca_alloc_icm(struct mthca_dev *dev, int npages,
- unsigned int gfp_mask);
+ gfp_t gfp_mask);
void mthca_free_icm(struct mthca_dev *dev, struct mthca_icm *icm);
struct mthca_icm_table *mthca_alloc_icm_table(struct mthca_dev *dev,
@@ -173,7 +173,8 @@ void mthca_cleanup_user_db_tab(struct mthca_dev *dev, struct mthca_uar *uar,
int mthca_init_db_tab(struct mthca_dev *dev);
void mthca_cleanup_db_tab(struct mthca_dev *dev);
-int mthca_alloc_db(struct mthca_dev *dev, int type, u32 qn, __be32 **db);
+int mthca_alloc_db(struct mthca_dev *dev, enum mthca_db_type type,
+ u32 qn, __be32 **db);
void mthca_free_db(struct mthca_dev *dev, int type, int db_index);
#endif /* MTHCA_MEMFREE_H */
diff --git a/drivers/infiniband/hw/mthca/mthca_mr.c b/drivers/infiniband/hw/mthca/mthca_mr.c
index 1f97a44477f5..e995e2aa016d 100644
--- a/drivers/infiniband/hw/mthca/mthca_mr.c
+++ b/drivers/infiniband/hw/mthca/mthca_mr.c
@@ -140,13 +140,11 @@ static int __devinit mthca_buddy_init(struct mthca_buddy *buddy, int max_order)
buddy->max_order = max_order;
spin_lock_init(&buddy->lock);
- buddy->bits = kmalloc((buddy->max_order + 1) * sizeof (long *),
+ buddy->bits = kzalloc((buddy->max_order + 1) * sizeof (long *),
GFP_KERNEL);
if (!buddy->bits)
goto err_out;
- memset(buddy->bits, 0, (buddy->max_order + 1) * sizeof (long *));
-
for (i = 0; i <= buddy->max_order; ++i) {
s = BITS_TO_LONGS(1 << (buddy->max_order - i));
buddy->bits[i] = kmalloc(s * sizeof (long), GFP_KERNEL);
diff --git a/drivers/infiniband/hw/mthca/mthca_profile.c b/drivers/infiniband/hw/mthca/mthca_profile.c
index 0576056b34f4..08a909371b0a 100644
--- a/drivers/infiniband/hw/mthca/mthca_profile.c
+++ b/drivers/infiniband/hw/mthca/mthca_profile.c
@@ -35,6 +35,8 @@
#include <linux/module.h>
#include <linux/moduleparam.h>
+#include <linux/string.h>
+#include <linux/slab.h>
#include "mthca_profile.h"
@@ -80,12 +82,10 @@ u64 mthca_make_profile(struct mthca_dev *dev,
struct mthca_resource tmp;
int i, j;
- profile = kmalloc(MTHCA_RES_NUM * sizeof *profile, GFP_KERNEL);
+ profile = kzalloc(MTHCA_RES_NUM * sizeof *profile, GFP_KERNEL);
if (!profile)
return -ENOMEM;
- memset(profile, 0, MTHCA_RES_NUM * sizeof *profile);
-
profile[MTHCA_RES_QP].size = dev_lim->qpc_entry_sz;
profile[MTHCA_RES_EEC].size = dev_lim->eec_entry_sz;
profile[MTHCA_RES_SRQ].size = dev_lim->srq_entry_sz;
diff --git a/drivers/infiniband/hw/mthca/mthca_provider.c b/drivers/infiniband/hw/mthca/mthca_provider.c
index 3f5319a46577..4cc7e2846df1 100644
--- a/drivers/infiniband/hw/mthca/mthca_provider.c
+++ b/drivers/infiniband/hw/mthca/mthca_provider.c
@@ -37,6 +37,7 @@
*/
#include <rdma/ib_smi.h>
+#include <rdma/ib_user_verbs.h>
#include <linux/mm.h>
#include "mthca_dev.h"
@@ -89,16 +90,28 @@ static int mthca_query_device(struct ib_device *ibdev,
memcpy(&props->node_guid, out_mad->data + 12, 8);
props->max_mr_size = ~0ull;
+ props->page_size_cap = mdev->limits.page_size_cap;
props->max_qp = mdev->limits.num_qps - mdev->limits.reserved_qps;
- props->max_qp_wr = 0xffff;
+ props->max_qp_wr = mdev->limits.max_wqes;
props->max_sge = mdev->limits.max_sg;
props->max_cq = mdev->limits.num_cqs - mdev->limits.reserved_cqs;
- props->max_cqe = 0xffff;
+ props->max_cqe = mdev->limits.max_cqes;
props->max_mr = mdev->limits.num_mpts - mdev->limits.reserved_mrws;
props->max_pd = mdev->limits.num_pds - mdev->limits.reserved_pds;
props->max_qp_rd_atom = 1 << mdev->qp_table.rdb_shift;
- props->max_qp_init_rd_atom = 1 << mdev->qp_table.rdb_shift;
+ props->max_qp_init_rd_atom = mdev->limits.max_qp_init_rdma;
+ props->max_res_rd_atom = props->max_qp_rd_atom * props->max_qp;
+ props->max_srq = mdev->limits.num_srqs - mdev->limits.reserved_srqs;
+ props->max_srq_wr = mdev->limits.max_srq_wqes;
+ props->max_srq_sge = mdev->limits.max_sg;
props->local_ca_ack_delay = mdev->limits.local_ca_ack_delay;
+ props->atomic_cap = mdev->limits.flags & DEV_LIM_FLAG_ATOMIC ?
+ IB_ATOMIC_HCA : IB_ATOMIC_NONE;
+ props->max_pkeys = mdev->limits.pkey_table_len;
+ props->max_mcast_grp = mdev->limits.num_mgms + mdev->limits.num_amgms;
+ props->max_mcast_qp_attach = MTHCA_QP_PER_MGM;
+ props->max_total_mcast_qp_attach = props->max_mcast_qp_attach *
+ props->max_mcast_grp;
err = 0;
out:
@@ -150,9 +163,13 @@ static int mthca_query_port(struct ib_device *ibdev,
props->gid_tbl_len = to_mdev(ibdev)->limits.gid_table_len;
props->max_msg_sz = 0x80000000;
props->pkey_tbl_len = to_mdev(ibdev)->limits.pkey_table_len;
+ props->bad_pkey_cntr = be16_to_cpup((__be16 *) (out_mad->data + 46));
props->qkey_viol_cntr = be16_to_cpup((__be16 *) (out_mad->data + 48));
props->active_width = out_mad->data[31] & 0xf;
props->active_speed = out_mad->data[35] >> 4;
+ props->max_mtu = out_mad->data[41] & 0xf;
+ props->active_mtu = out_mad->data[36] >> 4;
+ props->subnet_timeout = out_mad->data[51] & 0x1f;
out:
kfree(in_mad);
@@ -599,11 +616,11 @@ static struct ib_qp *mthca_create_qp(struct ib_pd *pd,
return ERR_PTR(err);
}
- init_attr->cap.max_inline_data = 0;
init_attr->cap.max_send_wr = qp->sq.max;
init_attr->cap.max_recv_wr = qp->rq.max;
init_attr->cap.max_send_sge = qp->sq.max_gs;
init_attr->cap.max_recv_sge = qp->rq.max_gs;
+ init_attr->cap.max_inline_data = qp->max_inline_data;
return &qp->ibqp;
}
@@ -634,6 +651,9 @@ static struct ib_cq *mthca_create_cq(struct ib_device *ibdev, int entries,
int nent;
int err;
+ if (entries < 1 || entries > to_mdev(ibdev)->limits.max_cqes)
+ return ERR_PTR(-EINVAL);
+
if (context) {
if (ib_copy_from_udata(&ucmd, udata, sizeof ucmd))
return ERR_PTR(-EFAULT);
@@ -1009,7 +1029,7 @@ static ssize_t show_rev(struct class_device *cdev, char *buf)
static ssize_t show_fw_ver(struct class_device *cdev, char *buf)
{
struct mthca_dev *dev = container_of(cdev, struct mthca_dev, ib_dev.class_dev);
- return sprintf(buf, "%x.%x.%x\n", (int) (dev->fw_ver >> 32),
+ return sprintf(buf, "%d.%d.%d\n", (int) (dev->fw_ver >> 32),
(int) (dev->fw_ver >> 16) & 0xffff,
(int) dev->fw_ver & 0xffff);
}
@@ -1058,6 +1078,26 @@ int mthca_register_device(struct mthca_dev *dev)
strlcpy(dev->ib_dev.name, "mthca%d", IB_DEVICE_NAME_MAX);
dev->ib_dev.owner = THIS_MODULE;
+ dev->ib_dev.uverbs_abi_ver = MTHCA_UVERBS_ABI_VERSION;
+ dev->ib_dev.uverbs_cmd_mask =
+ (1ull << IB_USER_VERBS_CMD_GET_CONTEXT) |
+ (1ull << IB_USER_VERBS_CMD_QUERY_DEVICE) |
+ (1ull << IB_USER_VERBS_CMD_QUERY_PORT) |
+ (1ull << IB_USER_VERBS_CMD_ALLOC_PD) |
+ (1ull << IB_USER_VERBS_CMD_DEALLOC_PD) |
+ (1ull << IB_USER_VERBS_CMD_REG_MR) |
+ (1ull << IB_USER_VERBS_CMD_DEREG_MR) |
+ (1ull << IB_USER_VERBS_CMD_CREATE_COMP_CHANNEL) |
+ (1ull << IB_USER_VERBS_CMD_CREATE_CQ) |
+ (1ull << IB_USER_VERBS_CMD_DESTROY_CQ) |
+ (1ull << IB_USER_VERBS_CMD_CREATE_QP) |
+ (1ull << IB_USER_VERBS_CMD_MODIFY_QP) |
+ (1ull << IB_USER_VERBS_CMD_DESTROY_QP) |
+ (1ull << IB_USER_VERBS_CMD_ATTACH_MCAST) |
+ (1ull << IB_USER_VERBS_CMD_DETACH_MCAST) |
+ (1ull << IB_USER_VERBS_CMD_CREATE_SRQ) |
+ (1ull << IB_USER_VERBS_CMD_MODIFY_SRQ) |
+ (1ull << IB_USER_VERBS_CMD_DESTROY_SRQ);
dev->ib_dev.node_type = IB_NODE_CA;
dev->ib_dev.phys_port_cnt = dev->limits.num_ports;
dev->ib_dev.dma_device = &dev->pdev->dev;
@@ -1077,6 +1117,7 @@ int mthca_register_device(struct mthca_dev *dev)
if (dev->mthca_flags & MTHCA_FLAG_SRQ) {
dev->ib_dev.create_srq = mthca_create_srq;
+ dev->ib_dev.modify_srq = mthca_modify_srq;
dev->ib_dev.destroy_srq = mthca_destroy_srq;
if (mthca_is_memfree(dev))
@@ -1135,10 +1176,13 @@ int mthca_register_device(struct mthca_dev *dev)
}
}
+ mthca_start_catas_poll(dev);
+
return 0;
}
void mthca_unregister_device(struct mthca_dev *dev)
{
+ mthca_stop_catas_poll(dev);
ib_unregister_device(&dev->ib_dev);
}
diff --git a/drivers/infiniband/hw/mthca/mthca_provider.h b/drivers/infiniband/hw/mthca/mthca_provider.h
index bcd4b01a339c..1e73947b4702 100644
--- a/drivers/infiniband/hw/mthca/mthca_provider.h
+++ b/drivers/infiniband/hw/mthca/mthca_provider.h
@@ -251,6 +251,7 @@ struct mthca_qp {
struct mthca_wq sq;
enum ib_sig_type sq_policy;
int send_wqe_offset;
+ int max_inline_data;
u64 *wrid;
union mthca_buf queue;
diff --git a/drivers/infiniband/hw/mthca/mthca_qp.c b/drivers/infiniband/hw/mthca/mthca_qp.c
index 5fa00669f9b8..760c418d5bc9 100644
--- a/drivers/infiniband/hw/mthca/mthca_qp.c
+++ b/drivers/infiniband/hw/mthca/mthca_qp.c
@@ -36,6 +36,8 @@
*/
#include <linux/init.h>
+#include <linux/string.h>
+#include <linux/slab.h>
#include <rdma/ib_verbs.h>
#include <rdma/ib_cache.h>
@@ -338,8 +340,7 @@ static const struct {
[UC] = (IB_QP_AV |
IB_QP_PATH_MTU |
IB_QP_DEST_QPN |
- IB_QP_RQ_PSN |
- IB_QP_MAX_DEST_RD_ATOMIC),
+ IB_QP_RQ_PSN),
[RC] = (IB_QP_AV |
IB_QP_PATH_MTU |
IB_QP_DEST_QPN |
@@ -368,8 +369,7 @@ static const struct {
.trans = MTHCA_TRANS_RTR2RTS,
.req_param = {
[UD] = IB_QP_SQ_PSN,
- [UC] = (IB_QP_SQ_PSN |
- IB_QP_MAX_QP_RD_ATOMIC),
+ [UC] = IB_QP_SQ_PSN,
[RC] = (IB_QP_TIMEOUT |
IB_QP_RETRY_CNT |
IB_QP_RNR_RETRY |
@@ -446,8 +446,6 @@ static const struct {
[UD] = (IB_QP_PKEY_INDEX |
IB_QP_QKEY),
[UC] = (IB_QP_AV |
- IB_QP_MAX_QP_RD_ATOMIC |
- IB_QP_MAX_DEST_RD_ATOMIC |
IB_QP_CUR_STATE |
IB_QP_ALT_PATH |
IB_QP_ACCESS_FLAGS |
@@ -478,7 +476,7 @@ static const struct {
.opt_param = {
[UD] = (IB_QP_CUR_STATE |
IB_QP_QKEY),
- [UC] = (IB_QP_CUR_STATE),
+ [UC] = IB_QP_CUR_STATE,
[RC] = (IB_QP_CUR_STATE |
IB_QP_MIN_RNR_TIMER),
[MLX] = (IB_QP_CUR_STATE |
@@ -586,6 +584,13 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask)
return -EINVAL;
}
+ if ((attr_mask & IB_QP_PKEY_INDEX) &&
+ attr->pkey_index >= dev->limits.pkey_table_len) {
+ mthca_dbg(dev, "PKey index (%u) too large. max is %d\n",
+ attr->pkey_index,dev->limits.pkey_table_len-1);
+ return -EINVAL;
+ }
+
mailbox = mthca_alloc_mailbox(dev, GFP_KERNEL);
if (IS_ERR(mailbox))
return PTR_ERR(mailbox);
@@ -880,6 +885,48 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask)
return err;
}
+static void mthca_adjust_qp_caps(struct mthca_dev *dev,
+ struct mthca_pd *pd,
+ struct mthca_qp *qp)
+{
+ int max_data_size;
+
+ /*
+ * Calculate the maximum size of WQE s/g segments, excluding
+ * the next segment and other non-data segments.
+ */
+ max_data_size = min(dev->limits.max_desc_sz, 1 << qp->sq.wqe_shift) -
+ sizeof (struct mthca_next_seg);
+
+ switch (qp->transport) {
+ case MLX:
+ max_data_size -= 2 * sizeof (struct mthca_data_seg);
+ break;
+
+ case UD:
+ if (mthca_is_memfree(dev))
+ max_data_size -= sizeof (struct mthca_arbel_ud_seg);
+ else
+ max_data_size -= sizeof (struct mthca_tavor_ud_seg);
+ break;
+
+ default:
+ max_data_size -= sizeof (struct mthca_raddr_seg);
+ break;
+ }
+
+ /* We don't support inline data for kernel QPs (yet). */
+ if (!pd->ibpd.uobject)
+ qp->max_inline_data = 0;
+ else
+ qp->max_inline_data = max_data_size - MTHCA_INLINE_HEADER_SIZE;
+
+ qp->sq.max_gs = max_data_size / sizeof (struct mthca_data_seg);
+ qp->rq.max_gs = (min(dev->limits.max_desc_sz, 1 << qp->rq.wqe_shift) -
+ sizeof (struct mthca_next_seg)) /
+ sizeof (struct mthca_data_seg);
+}
+
/*
* Allocate and register buffer for WQEs. qp->rq.max, sq.max,
* rq.max_gs and sq.max_gs must all be assigned.
@@ -897,27 +944,53 @@ static int mthca_alloc_wqe_buf(struct mthca_dev *dev,
size = sizeof (struct mthca_next_seg) +
qp->rq.max_gs * sizeof (struct mthca_data_seg);
+ if (size > dev->limits.max_desc_sz)
+ return -EINVAL;
+
for (qp->rq.wqe_shift = 6; 1 << qp->rq.wqe_shift < size;
qp->rq.wqe_shift++)
; /* nothing */
- size = sizeof (struct mthca_next_seg) +
- qp->sq.max_gs * sizeof (struct mthca_data_seg);
+ size = qp->sq.max_gs * sizeof (struct mthca_data_seg);
switch (qp->transport) {
case MLX:
size += 2 * sizeof (struct mthca_data_seg);
break;
+
case UD:
- if (mthca_is_memfree(dev))
- size += sizeof (struct mthca_arbel_ud_seg);
- else
- size += sizeof (struct mthca_tavor_ud_seg);
+ size += mthca_is_memfree(dev) ?
+ sizeof (struct mthca_arbel_ud_seg) :
+ sizeof (struct mthca_tavor_ud_seg);
break;
+
+ case UC:
+ size += sizeof (struct mthca_raddr_seg);
+ break;
+
+ case RC:
+ size += sizeof (struct mthca_raddr_seg);
+ /*
+ * An atomic op will require an atomic segment, a
+ * remote address segment and one scatter entry.
+ */
+ size = max_t(int, size,
+ sizeof (struct mthca_atomic_seg) +
+ sizeof (struct mthca_raddr_seg) +
+ sizeof (struct mthca_data_seg));
+ break;
+
default:
- /* bind seg is as big as atomic + raddr segs */
- size += sizeof (struct mthca_bind_seg);
+ break;
}
+ /* Make sure that we have enough space for a bind request */
+ size = max_t(int, size, sizeof (struct mthca_bind_seg));
+
+ size += sizeof (struct mthca_next_seg);
+
+ if (size > dev->limits.max_desc_sz)
+ return -EINVAL;
+
for (qp->sq.wqe_shift = 6; 1 << qp->sq.wqe_shift < size;
qp->sq.wqe_shift++)
; /* nothing */
@@ -1061,6 +1134,8 @@ static int mthca_alloc_qp_common(struct mthca_dev *dev,
return ret;
}
+ mthca_adjust_qp_caps(dev, pd, qp);
+
/*
* If this is a userspace QP, we're done now. The doorbells
* will be allocated and buffers will be initialized in
@@ -1112,8 +1187,10 @@ static int mthca_set_qp_size(struct mthca_dev *dev, struct ib_qp_cap *cap,
struct mthca_qp *qp)
{
/* Sanity check QP size before proceeding */
- if (cap->max_send_wr > 65536 || cap->max_recv_wr > 65536 ||
- cap->max_send_sge > 64 || cap->max_recv_sge > 64)
+ if (cap->max_send_wr > dev->limits.max_wqes ||
+ cap->max_recv_wr > dev->limits.max_wqes ||
+ cap->max_send_sge > dev->limits.max_sg ||
+ cap->max_recv_sge > dev->limits.max_sg)
return -EINVAL;
if (mthca_is_memfree(dev)) {
@@ -1479,8 +1556,8 @@ int mthca_tavor_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
}
wqe += sizeof (struct mthca_atomic_seg);
- size += sizeof (struct mthca_raddr_seg) / 16 +
- sizeof (struct mthca_atomic_seg);
+ size += (sizeof (struct mthca_raddr_seg) +
+ sizeof (struct mthca_atomic_seg)) / 16;
break;
case IB_WR_RDMA_WRITE:
@@ -1630,6 +1707,7 @@ int mthca_tavor_post_receive(struct ib_qp *ibqp, struct ib_recv_wr *wr,
{
struct mthca_dev *dev = to_mdev(ibqp->device);
struct mthca_qp *qp = to_mqp(ibqp);
+ __be32 doorbell[2];
unsigned long flags;
int err = 0;
int nreq;
@@ -1647,6 +1725,22 @@ int mthca_tavor_post_receive(struct ib_qp *ibqp, struct ib_recv_wr *wr,
ind = qp->rq.next_ind;
for (nreq = 0; wr; ++nreq, wr = wr->next) {
+ if (unlikely(nreq == MTHCA_TAVOR_MAX_WQES_PER_RECV_DB)) {
+ nreq = 0;
+
+ doorbell[0] = cpu_to_be32((qp->rq.next_ind << qp->rq.wqe_shift) | size0);
+ doorbell[1] = cpu_to_be32(qp->qpn << 8);
+
+ wmb();
+
+ mthca_write64(doorbell,
+ dev->kar + MTHCA_RECEIVE_DOORBELL,
+ MTHCA_GET_DOORBELL_LOCK(&dev->doorbell_lock));
+
+ qp->rq.head += MTHCA_TAVOR_MAX_WQES_PER_RECV_DB;
+ size0 = 0;
+ }
+
if (mthca_wq_overflow(&qp->rq, nreq, qp->ibqp.recv_cq)) {
mthca_err(dev, "RQ %06x full (%u head, %u tail,"
" %d max, %d nreq)\n", qp->qpn,
@@ -1704,8 +1798,6 @@ int mthca_tavor_post_receive(struct ib_qp *ibqp, struct ib_recv_wr *wr,
out:
if (likely(nreq)) {
- __be32 doorbell[2];
-
doorbell[0] = cpu_to_be32((qp->rq.next_ind << qp->rq.wqe_shift) | size0);
doorbell[1] = cpu_to_be32((qp->qpn << 8) | nreq);
@@ -1799,8 +1891,8 @@ int mthca_arbel_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
}
wqe += sizeof (struct mthca_atomic_seg);
- size += sizeof (struct mthca_raddr_seg) / 16 +
- sizeof (struct mthca_atomic_seg);
+ size += (sizeof (struct mthca_raddr_seg) +
+ sizeof (struct mthca_atomic_seg)) / 16;
break;
case IB_WR_RDMA_READ:
diff --git a/drivers/infiniband/hw/mthca/mthca_reset.c b/drivers/infiniband/hw/mthca/mthca_reset.c
index 4f995391dd1d..df5e494a9d38 100644
--- a/drivers/infiniband/hw/mthca/mthca_reset.c
+++ b/drivers/infiniband/hw/mthca/mthca_reset.c
@@ -37,6 +37,7 @@
#include <linux/errno.h>
#include <linux/pci.h>
#include <linux/delay.h>
+#include <linux/slab.h>
#include "mthca_dev.h"
#include "mthca_cmd.h"
diff --git a/drivers/infiniband/hw/mthca/mthca_srq.c b/drivers/infiniband/hw/mthca/mthca_srq.c
index 18998d48c53e..f7d234295efe 100644
--- a/drivers/infiniband/hw/mthca/mthca_srq.c
+++ b/drivers/infiniband/hw/mthca/mthca_srq.c
@@ -32,6 +32,9 @@
* $Id: mthca_srq.c 3047 2005-08-10 03:59:35Z roland $
*/
+#include <linux/slab.h>
+#include <linux/string.h>
+
#include "mthca_dev.h"
#include "mthca_cmd.h"
#include "mthca_memfree.h"
@@ -75,15 +78,16 @@ static void *get_wqe(struct mthca_srq *srq, int n)
/*
* Return a pointer to the location within a WQE that we're using as a
- * link when the WQE is in the free list. We use an offset of 4
- * because in the Tavor case, posting a WQE may overwrite the first
- * four bytes of the previous WQE. The offset avoids corrupting our
- * free list if the WQE has already completed and been put on the free
- * list when we post the next WQE.
+ * link when the WQE is in the free list. We use the imm field
+ * because in the Tavor case, posting a WQE may overwrite the next
+ * segment of the previous WQE, but a receive WQE will never touch the
+ * imm field. This avoids corrupting our free list if the previous
+ * WQE has already completed and been put on the free list when we
+ * post the next WQE.
*/
static inline int *wqe_to_link(void *wqe)
{
- return (int *) (wqe + 4);
+ return (int *) (wqe + offsetof(struct mthca_next_seg, imm));
}
static void mthca_tavor_init_srq_context(struct mthca_dev *dev,
@@ -186,7 +190,8 @@ int mthca_alloc_srq(struct mthca_dev *dev, struct mthca_pd *pd,
int err;
/* Sanity check SRQ size before proceeding */
- if (attr->max_wr > 16 << 20 || attr->max_sge > 64)
+ if (attr->max_wr > dev->limits.max_srq_wqes ||
+ attr->max_sge > dev->limits.max_sg)
return -EINVAL;
srq->max = attr->max_wr;
@@ -332,6 +337,29 @@ void mthca_free_srq(struct mthca_dev *dev, struct mthca_srq *srq)
mthca_free_mailbox(dev, mailbox);
}
+int mthca_modify_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr,
+ enum ib_srq_attr_mask attr_mask)
+{
+ struct mthca_dev *dev = to_mdev(ibsrq->device);
+ struct mthca_srq *srq = to_msrq(ibsrq);
+ int ret;
+ u8 status;
+
+ /* We don't support resizing SRQs (yet?) */
+ if (attr_mask & IB_SRQ_MAX_WR)
+ return -EINVAL;
+
+ if (attr_mask & IB_SRQ_LIMIT) {
+ ret = mthca_ARM_SRQ(dev, srq->srqn, attr->srq_limit, &status);
+ if (ret)
+ return ret;
+ if (status)
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
void mthca_srq_event(struct mthca_dev *dev, u32 srqn,
enum ib_event_type event_type)
{
@@ -354,7 +382,7 @@ void mthca_srq_event(struct mthca_dev *dev, u32 srqn,
event.device = &dev->ib_dev;
event.event = event_type;
- event.element.srq = &srq->ibsrq;
+ event.element.srq = &srq->ibsrq;
srq->ibsrq.event_handler(&event, srq->ibsrq.srq_context);
out:
@@ -389,6 +417,7 @@ int mthca_tavor_post_srq_recv(struct ib_srq *ibsrq, struct ib_recv_wr *wr,
{
struct mthca_dev *dev = to_mdev(ibsrq->device);
struct mthca_srq *srq = to_msrq(ibsrq);
+ __be32 doorbell[2];
unsigned long flags;
int err = 0;
int first_ind;
@@ -404,6 +433,25 @@ int mthca_tavor_post_srq_recv(struct ib_srq *ibsrq, struct ib_recv_wr *wr,
first_ind = srq->first_free;
for (nreq = 0; wr; ++nreq, wr = wr->next) {
+ if (unlikely(nreq == MTHCA_TAVOR_MAX_WQES_PER_RECV_DB)) {
+ nreq = 0;
+
+ doorbell[0] = cpu_to_be32(first_ind << srq->wqe_shift);
+ doorbell[1] = cpu_to_be32(srq->srqn << 8);
+
+ /*
+ * Make sure that descriptors are written
+ * before doorbell is rung.
+ */
+ wmb();
+
+ mthca_write64(doorbell,
+ dev->kar + MTHCA_RECEIVE_DOORBELL,
+ MTHCA_GET_DOORBELL_LOCK(&dev->doorbell_lock));
+
+ first_ind = srq->first_free;
+ }
+
ind = srq->first_free;
if (ind < 0) {
@@ -415,6 +463,14 @@ int mthca_tavor_post_srq_recv(struct ib_srq *ibsrq, struct ib_recv_wr *wr,
wqe = get_wqe(srq, ind);
next_ind = *wqe_to_link(wqe);
+
+ if (next_ind < 0) {
+ mthca_err(dev, "SRQ %06x full\n", srq->srqn);
+ err = -ENOMEM;
+ *bad_wr = wr;
+ break;
+ }
+
prev_wqe = srq->last;
srq->last = wqe;
@@ -458,8 +514,6 @@ int mthca_tavor_post_srq_recv(struct ib_srq *ibsrq, struct ib_recv_wr *wr,
}
if (likely(nreq)) {
- __be32 doorbell[2];
-
doorbell[0] = cpu_to_be32(first_ind << srq->wqe_shift);
doorbell[1] = cpu_to_be32((srq->srqn << 8) | nreq);
@@ -506,6 +560,13 @@ int mthca_arbel_post_srq_recv(struct ib_srq *ibsrq, struct ib_recv_wr *wr,
wqe = get_wqe(srq, ind);
next_ind = *wqe_to_link(wqe);
+ if (next_ind < 0) {
+ mthca_err(dev, "SRQ %06x full\n", srq->srqn);
+ err = -ENOMEM;
+ *bad_wr = wr;
+ break;
+ }
+
((struct mthca_next_seg *) wqe)->nda_op =
cpu_to_be32((next_ind << srq->wqe_shift) | 1);
((struct mthca_next_seg *) wqe)->ee_nds = 0;
diff --git a/drivers/infiniband/hw/mthca/mthca_uar.c b/drivers/infiniband/hw/mthca/mthca_uar.c
index 1c8791ded6ff..8e9219842be4 100644
--- a/drivers/infiniband/hw/mthca/mthca_uar.c
+++ b/drivers/infiniband/hw/mthca/mthca_uar.c
@@ -32,6 +32,8 @@
* $Id$
*/
+#include <asm/page.h> /* PAGE_SHIFT */
+
#include "mthca_dev.h"
#include "mthca_memfree.h"
diff --git a/drivers/infiniband/hw/mthca/mthca_user.h b/drivers/infiniband/hw/mthca/mthca_user.h
index 41613ec8a04e..bb015c6494c4 100644
--- a/drivers/infiniband/hw/mthca/mthca_user.h
+++ b/drivers/infiniband/hw/mthca/mthca_user.h
@@ -38,6 +38,12 @@
#include <linux/types.h>
/*
+ * Increment this value if any changes that break userspace ABI
+ * compatibility are made.
+ */
+#define MTHCA_UVERBS_ABI_VERSION 1
+
+/*
* Make sure that all structs defined in this file remain laid out so
* that they pack the same way on 32-bit and 64-bit architectures (to
* avoid incompatibility between 32-bit userspace and 64-bit kernels).
diff --git a/drivers/infiniband/hw/mthca/mthca_wqe.h b/drivers/infiniband/hw/mthca/mthca_wqe.h
index 1f4c0ff28f79..73f1c0b9021e 100644
--- a/drivers/infiniband/hw/mthca/mthca_wqe.h
+++ b/drivers/infiniband/hw/mthca/mthca_wqe.h
@@ -49,7 +49,8 @@ enum {
};
enum {
- MTHCA_INVAL_LKEY = 0x100
+ MTHCA_INVAL_LKEY = 0x100,
+ MTHCA_TAVOR_MAX_WQES_PER_RECV_DB = 256
};
struct mthca_next_seg {
diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h b/drivers/infiniband/ulp/ipoib/ipoib.h
index 4ea1c1ca85bc..9923a15a9996 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib.h
+++ b/drivers/infiniband/ulp/ipoib/ipoib.h
@@ -100,7 +100,12 @@ struct ipoib_pseudoheader {
struct ipoib_mcast;
-struct ipoib_buf {
+struct ipoib_rx_buf {
+ struct sk_buff *skb;
+ dma_addr_t mapping;
+};
+
+struct ipoib_tx_buf {
struct sk_buff *skb;
DECLARE_PCI_UNMAP_ADDR(mapping)
};
@@ -150,14 +155,14 @@ struct ipoib_dev_priv {
unsigned int admin_mtu;
unsigned int mcast_mtu;
- struct ipoib_buf *rx_ring;
+ struct ipoib_rx_buf *rx_ring;
- spinlock_t tx_lock;
- struct ipoib_buf *tx_ring;
- unsigned tx_head;
- unsigned tx_tail;
- struct ib_sge tx_sge;
- struct ib_send_wr tx_wr;
+ spinlock_t tx_lock;
+ struct ipoib_tx_buf *tx_ring;
+ unsigned tx_head;
+ unsigned tx_tail;
+ struct ib_sge tx_sge;
+ struct ib_send_wr tx_wr;
struct ib_wc ibwc[IPOIB_NUM_WC];
@@ -174,6 +179,7 @@ struct ipoib_dev_priv {
#ifdef CONFIG_INFINIBAND_IPOIB_DEBUG
struct list_head fs_list;
struct dentry *mcg_dentry;
+ struct dentry *path_dentry;
#endif
};
@@ -230,6 +236,7 @@ static inline void ipoib_put_ah(struct ipoib_ah *ah)
kref_put(&ah->ref, ipoib_free_ah);
}
+int ipoib_open(struct net_device *dev);
int ipoib_add_pkey_attr(struct net_device *dev);
void ipoib_send(struct net_device *dev, struct sk_buff *skb,
@@ -262,8 +269,8 @@ int ipoib_mcast_stop_thread(struct net_device *dev, int flush);
void ipoib_mcast_dev_down(struct net_device *dev);
void ipoib_mcast_dev_flush(struct net_device *dev);
+#ifdef CONFIG_INFINIBAND_IPOIB_DEBUG
struct ipoib_mcast_iter *ipoib_mcast_iter_init(struct net_device *dev);
-void ipoib_mcast_iter_free(struct ipoib_mcast_iter *iter);
int ipoib_mcast_iter_next(struct ipoib_mcast_iter *iter);
void ipoib_mcast_iter_read(struct ipoib_mcast_iter *iter,
union ib_gid *gid,
@@ -272,12 +279,18 @@ void ipoib_mcast_iter_read(struct ipoib_mcast_iter *iter,
unsigned int *complete,
unsigned int *send_only);
+struct ipoib_path_iter *ipoib_path_iter_init(struct net_device *dev);
+int ipoib_path_iter_next(struct ipoib_path_iter *iter);
+void ipoib_path_iter_read(struct ipoib_path_iter *iter,
+ struct ipoib_path *path);
+#endif
+
int ipoib_mcast_attach(struct net_device *dev, u16 mlid,
union ib_gid *mgid);
int ipoib_mcast_detach(struct net_device *dev, u16 mlid,
union ib_gid *mgid);
-int ipoib_qp_create(struct net_device *dev);
+int ipoib_init_qp(struct net_device *dev);
int ipoib_transport_dev_init(struct net_device *dev, struct ib_device *ca);
void ipoib_transport_dev_cleanup(struct net_device *dev);
@@ -291,13 +304,13 @@ void ipoib_pkey_poll(void *dev);
int ipoib_pkey_dev_delay_open(struct net_device *dev);
#ifdef CONFIG_INFINIBAND_IPOIB_DEBUG
-int ipoib_create_debug_file(struct net_device *dev);
-void ipoib_delete_debug_file(struct net_device *dev);
+void ipoib_create_debug_files(struct net_device *dev);
+void ipoib_delete_debug_files(struct net_device *dev);
int ipoib_register_debugfs(void);
void ipoib_unregister_debugfs(void);
#else
-static inline int ipoib_create_debug_file(struct net_device *dev) { return 0; }
-static inline void ipoib_delete_debug_file(struct net_device *dev) { }
+static inline void ipoib_create_debug_files(struct net_device *dev) { }
+static inline void ipoib_delete_debug_files(struct net_device *dev) { }
static inline int ipoib_register_debugfs(void) { return 0; }
static inline void ipoib_unregister_debugfs(void) { }
#endif
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_fs.c b/drivers/infiniband/ulp/ipoib/ipoib_fs.c
index 38b150f775e7..685258e34034 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_fs.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_fs.c
@@ -43,6 +43,18 @@ struct file_operations;
static struct dentry *ipoib_root;
+static void format_gid(union ib_gid *gid, char *buf)
+{
+ int i, n;
+
+ for (n = 0, i = 0; i < 8; ++i) {
+ n += sprintf(buf + n, "%x",
+ be16_to_cpu(((__be16 *) gid->raw)[i]));
+ if (i < 7)
+ buf[n++] = ':';
+ }
+}
+
static void *ipoib_mcg_seq_start(struct seq_file *file, loff_t *pos)
{
struct ipoib_mcast_iter *iter;
@@ -54,7 +66,7 @@ static void *ipoib_mcg_seq_start(struct seq_file *file, loff_t *pos)
while (n--) {
if (ipoib_mcast_iter_next(iter)) {
- ipoib_mcast_iter_free(iter);
+ kfree(iter);
return NULL;
}
}
@@ -70,7 +82,7 @@ static void *ipoib_mcg_seq_next(struct seq_file *file, void *iter_ptr,
(*pos)++;
if (ipoib_mcast_iter_next(iter)) {
- ipoib_mcast_iter_free(iter);
+ kfree(iter);
return NULL;
}
@@ -87,32 +99,32 @@ static int ipoib_mcg_seq_show(struct seq_file *file, void *iter_ptr)
struct ipoib_mcast_iter *iter = iter_ptr;
char gid_buf[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"];
union ib_gid mgid;
- int i, n;
unsigned long created;
unsigned int queuelen, complete, send_only;
- if (iter) {
- ipoib_mcast_iter_read(iter, &mgid, &created, &queuelen,
- &complete, &send_only);
+ if (!iter)
+ return 0;
- for (n = 0, i = 0; i < sizeof mgid / 2; ++i) {
- n += sprintf(gid_buf + n, "%x",
- be16_to_cpu(((__be16 *) mgid.raw)[i]));
- if (i < sizeof mgid / 2 - 1)
- gid_buf[n++] = ':';
- }
- }
+ ipoib_mcast_iter_read(iter, &mgid, &created, &queuelen,
+ &complete, &send_only);
- seq_printf(file, "GID: %*s", -(1 + (int) sizeof gid_buf), gid_buf);
+ format_gid(&mgid, gid_buf);
seq_printf(file,
- " created: %10ld queuelen: %4d complete: %d send_only: %d\n",
- created, queuelen, complete, send_only);
+ "GID: %s\n"
+ " created: %10ld\n"
+ " queuelen: %9d\n"
+ " complete: %9s\n"
+ " send_only: %8s\n"
+ "\n",
+ gid_buf, created, queuelen,
+ complete ? "yes" : "no",
+ send_only ? "yes" : "no");
return 0;
}
-static struct seq_operations ipoib_seq_ops = {
+static struct seq_operations ipoib_mcg_seq_ops = {
.start = ipoib_mcg_seq_start,
.next = ipoib_mcg_seq_next,
.stop = ipoib_mcg_seq_stop,
@@ -124,7 +136,7 @@ static int ipoib_mcg_open(struct inode *inode, struct file *file)
struct seq_file *seq;
int ret;
- ret = seq_open(file, &ipoib_seq_ops);
+ ret = seq_open(file, &ipoib_mcg_seq_ops);
if (ret)
return ret;
@@ -134,7 +146,7 @@ static int ipoib_mcg_open(struct inode *inode, struct file *file)
return 0;
}
-static struct file_operations ipoib_fops = {
+static struct file_operations ipoib_mcg_fops = {
.owner = THIS_MODULE,
.open = ipoib_mcg_open,
.read = seq_read,
@@ -142,25 +154,138 @@ static struct file_operations ipoib_fops = {
.release = seq_release
};
-int ipoib_create_debug_file(struct net_device *dev)
+static void *ipoib_path_seq_start(struct seq_file *file, loff_t *pos)
+{
+ struct ipoib_path_iter *iter;
+ loff_t n = *pos;
+
+ iter = ipoib_path_iter_init(file->private);
+ if (!iter)
+ return NULL;
+
+ while (n--) {
+ if (ipoib_path_iter_next(iter)) {
+ kfree(iter);
+ return NULL;
+ }
+ }
+
+ return iter;
+}
+
+static void *ipoib_path_seq_next(struct seq_file *file, void *iter_ptr,
+ loff_t *pos)
+{
+ struct ipoib_path_iter *iter = iter_ptr;
+
+ (*pos)++;
+
+ if (ipoib_path_iter_next(iter)) {
+ kfree(iter);
+ return NULL;
+ }
+
+ return iter;
+}
+
+static void ipoib_path_seq_stop(struct seq_file *file, void *iter_ptr)
+{
+ /* nothing for now */
+}
+
+static int ipoib_path_seq_show(struct seq_file *file, void *iter_ptr)
+{
+ struct ipoib_path_iter *iter = iter_ptr;
+ char gid_buf[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"];
+ struct ipoib_path path;
+ int rate;
+
+ if (!iter)
+ return 0;
+
+ ipoib_path_iter_read(iter, &path);
+
+ format_gid(&path.pathrec.dgid, gid_buf);
+
+ seq_printf(file,
+ "GID: %s\n"
+ " complete: %6s\n",
+ gid_buf, path.pathrec.dlid ? "yes" : "no");
+
+ if (path.pathrec.dlid) {
+ rate = ib_sa_rate_enum_to_int(path.pathrec.rate) * 25;
+
+ seq_printf(file,
+ " DLID: 0x%04x\n"
+ " SL: %12d\n"
+ " rate: %*d%s Gb/sec\n",
+ be16_to_cpu(path.pathrec.dlid),
+ path.pathrec.sl,
+ 10 - ((rate % 10) ? 2 : 0),
+ rate / 10, rate % 10 ? ".5" : "");
+ }
+
+ seq_putc(file, '\n');
+
+ return 0;
+}
+
+static struct seq_operations ipoib_path_seq_ops = {
+ .start = ipoib_path_seq_start,
+ .next = ipoib_path_seq_next,
+ .stop = ipoib_path_seq_stop,
+ .show = ipoib_path_seq_show,
+};
+
+static int ipoib_path_open(struct inode *inode, struct file *file)
+{
+ struct seq_file *seq;
+ int ret;
+
+ ret = seq_open(file, &ipoib_path_seq_ops);
+ if (ret)
+ return ret;
+
+ seq = file->private_data;
+ seq->private = inode->u.generic_ip;
+
+ return 0;
+}
+
+static struct file_operations ipoib_path_fops = {
+ .owner = THIS_MODULE,
+ .open = ipoib_path_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = seq_release
+};
+
+void ipoib_create_debug_files(struct net_device *dev)
{
struct ipoib_dev_priv *priv = netdev_priv(dev);
- char name[IFNAMSIZ + sizeof "_mcg"];
+ char name[IFNAMSIZ + sizeof "_path"];
snprintf(name, sizeof name, "%s_mcg", dev->name);
-
priv->mcg_dentry = debugfs_create_file(name, S_IFREG | S_IRUGO,
- ipoib_root, dev, &ipoib_fops);
-
- return priv->mcg_dentry ? 0 : -ENOMEM;
+ ipoib_root, dev, &ipoib_mcg_fops);
+ if (!priv->mcg_dentry)
+ ipoib_warn(priv, "failed to create mcg debug file\n");
+
+ snprintf(name, sizeof name, "%s_path", dev->name);
+ priv->path_dentry = debugfs_create_file(name, S_IFREG | S_IRUGO,
+ ipoib_root, dev, &ipoib_path_fops);
+ if (!priv->path_dentry)
+ ipoib_warn(priv, "failed to create path debug file\n");
}
-void ipoib_delete_debug_file(struct net_device *dev)
+void ipoib_delete_debug_files(struct net_device *dev)
{
struct ipoib_dev_priv *priv = netdev_priv(dev);
if (priv->mcg_dentry)
debugfs_remove(priv->mcg_dentry);
+ if (priv->path_dentry)
+ debugfs_remove(priv->path_dentry);
}
int ipoib_register_debugfs(void)
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_ib.c b/drivers/infiniband/ulp/ipoib/ipoib_ib.c
index f7440096b5ed..54ef2fea530f 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_ib.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_ib.c
@@ -95,57 +95,65 @@ void ipoib_free_ah(struct kref *kref)
}
}
-static inline int ipoib_ib_receive(struct ipoib_dev_priv *priv,
- unsigned int wr_id,
- dma_addr_t addr)
+static int ipoib_ib_post_receive(struct net_device *dev, int id)
{
- struct ib_sge list = {
- .addr = addr,
- .length = IPOIB_BUF_SIZE,
- .lkey = priv->mr->lkey,
- };
- struct ib_recv_wr param = {
- .wr_id = wr_id | IPOIB_OP_RECV,
- .sg_list = &list,
- .num_sge = 1,
- };
+ struct ipoib_dev_priv *priv = netdev_priv(dev);
+ struct ib_sge list;
+ struct ib_recv_wr param;
struct ib_recv_wr *bad_wr;
+ int ret;
+
+ list.addr = priv->rx_ring[id].mapping;
+ list.length = IPOIB_BUF_SIZE;
+ list.lkey = priv->mr->lkey;
+
+ param.next = NULL;
+ param.wr_id = id | IPOIB_OP_RECV;
+ param.sg_list = &list;
+ param.num_sge = 1;
+
+ ret = ib_post_recv(priv->qp, &param, &bad_wr);
+ if (unlikely(ret)) {
+ ipoib_warn(priv, "receive failed for buf %d (%d)\n", id, ret);
+ dma_unmap_single(priv->ca->dma_device,
+ priv->rx_ring[id].mapping,
+ IPOIB_BUF_SIZE, DMA_FROM_DEVICE);
+ dev_kfree_skb_any(priv->rx_ring[id].skb);
+ priv->rx_ring[id].skb = NULL;
+ }
- return ib_post_recv(priv->qp, &param, &bad_wr);
+ return ret;
}
-static int ipoib_ib_post_receive(struct net_device *dev, int id)
+static int ipoib_alloc_rx_skb(struct net_device *dev, int id)
{
struct ipoib_dev_priv *priv = netdev_priv(dev);
struct sk_buff *skb;
dma_addr_t addr;
- int ret;
skb = dev_alloc_skb(IPOIB_BUF_SIZE + 4);
- if (!skb) {
- ipoib_warn(priv, "failed to allocate receive buffer\n");
-
- priv->rx_ring[id].skb = NULL;
+ if (!skb)
return -ENOMEM;
- }
- skb_reserve(skb, 4); /* 16 byte align IP header */
- priv->rx_ring[id].skb = skb;
+
+ /*
+ * IB will leave a 40 byte gap for a GRH and IPoIB adds a 4 byte
+ * header. So we need 4 more bytes to get to 48 and align the
+ * IP header to a multiple of 16.
+ */
+ skb_reserve(skb, 4);
+
addr = dma_map_single(priv->ca->dma_device,
skb->data, IPOIB_BUF_SIZE,
DMA_FROM_DEVICE);
- pci_unmap_addr_set(&priv->rx_ring[id], mapping, addr);
-
- ret = ipoib_ib_receive(priv, id, addr);
- if (ret) {
- ipoib_warn(priv, "ipoib_ib_receive failed for buf %d (%d)\n",
- id, ret);
- dma_unmap_single(priv->ca->dma_device, addr,
- IPOIB_BUF_SIZE, DMA_FROM_DEVICE);
+ if (unlikely(dma_mapping_error(addr))) {
dev_kfree_skb_any(skb);
- priv->rx_ring[id].skb = NULL;
+ return -EIO;
}
- return ret;
+ priv->rx_ring[id].skb = skb;
+ priv->rx_ring[id].mapping = addr;
+
+ return 0;
}
static int ipoib_ib_post_receives(struct net_device *dev)
@@ -154,6 +162,10 @@ static int ipoib_ib_post_receives(struct net_device *dev)
int i;
for (i = 0; i < IPOIB_RX_RING_SIZE; ++i) {
+ if (ipoib_alloc_rx_skb(dev, i)) {
+ ipoib_warn(priv, "failed to allocate receive buffer %d\n", i);
+ return -ENOMEM;
+ }
if (ipoib_ib_post_receive(dev, i)) {
ipoib_warn(priv, "ipoib_ib_post_receive failed for buf %d\n", i);
return -EIO;
@@ -176,28 +188,36 @@ static void ipoib_ib_handle_wc(struct net_device *dev,
wr_id &= ~IPOIB_OP_RECV;
if (wr_id < IPOIB_RX_RING_SIZE) {
- struct sk_buff *skb = priv->rx_ring[wr_id].skb;
+ struct sk_buff *skb = priv->rx_ring[wr_id].skb;
+ dma_addr_t addr = priv->rx_ring[wr_id].mapping;
- priv->rx_ring[wr_id].skb = NULL;
-
- dma_unmap_single(priv->ca->dma_device,
- pci_unmap_addr(&priv->rx_ring[wr_id],
- mapping),
- IPOIB_BUF_SIZE,
- DMA_FROM_DEVICE);
-
- if (wc->status != IB_WC_SUCCESS) {
+ if (unlikely(wc->status != IB_WC_SUCCESS)) {
if (wc->status != IB_WC_WR_FLUSH_ERR)
ipoib_warn(priv, "failed recv event "
"(status=%d, wrid=%d vend_err %x)\n",
wc->status, wr_id, wc->vendor_err);
+ dma_unmap_single(priv->ca->dma_device, addr,
+ IPOIB_BUF_SIZE, DMA_FROM_DEVICE);
dev_kfree_skb_any(skb);
+ priv->rx_ring[wr_id].skb = NULL;
return;
}
+ /*
+ * If we can't allocate a new RX buffer, dump
+ * this packet and reuse the old buffer.
+ */
+ if (unlikely(ipoib_alloc_rx_skb(dev, wr_id))) {
+ ++priv->stats.rx_dropped;
+ goto repost;
+ }
+
ipoib_dbg_data(priv, "received %d bytes, SLID 0x%04x\n",
wc->byte_len, wc->slid);
+ dma_unmap_single(priv->ca->dma_device, addr,
+ IPOIB_BUF_SIZE, DMA_FROM_DEVICE);
+
skb_put(skb, wc->byte_len);
skb_pull(skb, IB_GRH_BYTES);
@@ -220,8 +240,8 @@ static void ipoib_ib_handle_wc(struct net_device *dev,
dev_kfree_skb_any(skb);
}
- /* repost receive */
- if (ipoib_ib_post_receive(dev, wr_id))
+ repost:
+ if (unlikely(ipoib_ib_post_receive(dev, wr_id)))
ipoib_warn(priv, "ipoib_ib_post_receive failed "
"for buf %d\n", wr_id);
} else
@@ -229,7 +249,7 @@ static void ipoib_ib_handle_wc(struct net_device *dev,
wr_id);
} else {
- struct ipoib_buf *tx_req;
+ struct ipoib_tx_buf *tx_req;
unsigned long flags;
if (wr_id >= IPOIB_TX_RING_SIZE) {
@@ -302,7 +322,7 @@ void ipoib_send(struct net_device *dev, struct sk_buff *skb,
struct ipoib_ah *address, u32 qpn)
{
struct ipoib_dev_priv *priv = netdev_priv(dev);
- struct ipoib_buf *tx_req;
+ struct ipoib_tx_buf *tx_req;
dma_addr_t addr;
if (skb->len > dev->mtu + INFINIBAND_ALEN) {
@@ -387,9 +407,9 @@ int ipoib_ib_dev_open(struct net_device *dev)
struct ipoib_dev_priv *priv = netdev_priv(dev);
int ret;
- ret = ipoib_qp_create(dev);
+ ret = ipoib_init_qp(dev);
if (ret) {
- ipoib_warn(priv, "ipoib_qp_create returned %d\n", ret);
+ ipoib_warn(priv, "ipoib_init_qp returned %d\n", ret);
return -1;
}
@@ -466,15 +486,16 @@ int ipoib_ib_dev_stop(struct net_device *dev)
{
struct ipoib_dev_priv *priv = netdev_priv(dev);
struct ib_qp_attr qp_attr;
- int attr_mask;
unsigned long begin;
- struct ipoib_buf *tx_req;
+ struct ipoib_tx_buf *tx_req;
int i;
- /* Kill the existing QP and allocate a new one */
+ /*
+ * Move our QP to the error state and then reinitialize in
+ * when all work requests have completed or have been flushed.
+ */
qp_attr.qp_state = IB_QPS_ERR;
- attr_mask = IB_QP_STATE;
- if (ib_modify_qp(priv->qp, &qp_attr, attr_mask))
+ if (ib_modify_qp(priv->qp, &qp_attr, IB_QP_STATE))
ipoib_warn(priv, "Failed to modify QP to ERROR state\n");
/* Wait for all sends and receives to complete */
@@ -521,8 +542,7 @@ int ipoib_ib_dev_stop(struct net_device *dev)
timeout:
qp_attr.qp_state = IB_QPS_RESET;
- attr_mask = IB_QP_STATE;
- if (ib_modify_qp(priv->qp, &qp_attr, attr_mask))
+ if (ib_modify_qp(priv->qp, &qp_attr, IB_QP_STATE))
ipoib_warn(priv, "Failed to modify QP to RESET state\n");
/* Wait for all AHs to be reaped */
@@ -616,7 +636,6 @@ void ipoib_ib_dev_cleanup(struct net_device *dev)
* Bug #2507. This implementation will probably be removed when the P_Key
* change async notification is available.
*/
-int ipoib_open(struct net_device *dev);
static void ipoib_pkey_dev_check_presence(struct net_device *dev)
{
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c
index 6c5bf07489f4..2fa30751f362 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_main.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c
@@ -58,6 +58,11 @@ module_param_named(debug_level, ipoib_debug_level, int, 0644);
MODULE_PARM_DESC(debug_level, "Enable debug tracing if > 0");
#endif
+struct ipoib_path_iter {
+ struct net_device *dev;
+ struct ipoib_path path;
+};
+
static const u8 ipv4_bcast_addr[] = {
0x00, 0xff, 0xff, 0xff,
0xff, 0x12, 0x40, 0x1b, 0x00, 0x00, 0x00, 0x00,
@@ -250,6 +255,64 @@ static void path_free(struct net_device *dev, struct ipoib_path *path)
kfree(path);
}
+#ifdef CONFIG_INFINIBAND_IPOIB_DEBUG
+
+struct ipoib_path_iter *ipoib_path_iter_init(struct net_device *dev)
+{
+ struct ipoib_path_iter *iter;
+
+ iter = kmalloc(sizeof *iter, GFP_KERNEL);
+ if (!iter)
+ return NULL;
+
+ iter->dev = dev;
+ memset(iter->path.pathrec.dgid.raw, 0, 16);
+
+ if (ipoib_path_iter_next(iter)) {
+ kfree(iter);
+ return NULL;
+ }
+
+ return iter;
+}
+
+int ipoib_path_iter_next(struct ipoib_path_iter *iter)
+{
+ struct ipoib_dev_priv *priv = netdev_priv(iter->dev);
+ struct rb_node *n;
+ struct ipoib_path *path;
+ int ret = 1;
+
+ spin_lock_irq(&priv->lock);
+
+ n = rb_first(&priv->path_tree);
+
+ while (n) {
+ path = rb_entry(n, struct ipoib_path, rb_node);
+
+ if (memcmp(iter->path.pathrec.dgid.raw, path->pathrec.dgid.raw,
+ sizeof (union ib_gid)) < 0) {
+ iter->path = *path;
+ ret = 0;
+ break;
+ }
+
+ n = rb_next(n);
+ }
+
+ spin_unlock_irq(&priv->lock);
+
+ return ret;
+}
+
+void ipoib_path_iter_read(struct ipoib_path_iter *iter,
+ struct ipoib_path *path)
+{
+ *path = iter->path;
+}
+
+#endif /* CONFIG_INFINIBAND_IPOIB_DEBUG */
+
void ipoib_flush_paths(struct net_device *dev)
{
struct ipoib_dev_priv *priv = netdev_priv(dev);
@@ -356,18 +419,15 @@ static struct ipoib_path *path_rec_create(struct net_device *dev,
struct ipoib_dev_priv *priv = netdev_priv(dev);
struct ipoib_path *path;
- path = kmalloc(sizeof *path, GFP_ATOMIC);
+ path = kzalloc(sizeof *path, GFP_ATOMIC);
if (!path)
return NULL;
- path->dev = dev;
- path->pathrec.dlid = 0;
- path->ah = NULL;
+ path->dev = dev;
skb_queue_head_init(&path->queue);
INIT_LIST_HEAD(&path->neigh_list);
- path->query = NULL;
init_completion(&path->done);
memcpy(path->pathrec.dgid.raw, gid->raw, sizeof (union ib_gid));
@@ -551,11 +611,8 @@ static int ipoib_start_xmit(struct sk_buff *skb, struct net_device *dev)
struct ipoib_neigh *neigh;
unsigned long flags;
- local_irq_save(flags);
- if (!spin_trylock(&priv->tx_lock)) {
- local_irq_restore(flags);
+ if (!spin_trylock_irqsave(&priv->tx_lock, flags))
return NETDEV_TX_LOCKED;
- }
/*
* Check if our queue is stopped. Since we have the LLTX bit
@@ -637,8 +694,11 @@ static void ipoib_timeout(struct net_device *dev)
{
struct ipoib_dev_priv *priv = netdev_priv(dev);
- ipoib_warn(priv, "transmit timeout: latency %ld\n",
- jiffies - dev->trans_start);
+ ipoib_warn(priv, "transmit timeout: latency %d msecs\n",
+ jiffies_to_msecs(jiffies - dev->trans_start));
+ ipoib_warn(priv, "queue stopped %d, tx_head %u, tx_tail %u\n",
+ netif_queue_stopped(dev),
+ priv->tx_head, priv->tx_tail);
/* XXX reset QP, etc. */
}
@@ -729,25 +789,21 @@ int ipoib_dev_init(struct net_device *dev, struct ib_device *ca, int port)
/* Allocate RX/TX "rings" to hold queued skbs */
- priv->rx_ring = kmalloc(IPOIB_RX_RING_SIZE * sizeof (struct ipoib_buf),
+ priv->rx_ring = kzalloc(IPOIB_RX_RING_SIZE * sizeof (struct ipoib_rx_buf),
GFP_KERNEL);
if (!priv->rx_ring) {
printk(KERN_WARNING "%s: failed to allocate RX ring (%d entries)\n",
ca->name, IPOIB_RX_RING_SIZE);
goto out;
}
- memset(priv->rx_ring, 0,
- IPOIB_RX_RING_SIZE * sizeof (struct ipoib_buf));
- priv->tx_ring = kmalloc(IPOIB_TX_RING_SIZE * sizeof (struct ipoib_buf),
+ priv->tx_ring = kzalloc(IPOIB_TX_RING_SIZE * sizeof (struct ipoib_tx_buf),
GFP_KERNEL);
if (!priv->tx_ring) {
printk(KERN_WARNING "%s: failed to allocate TX ring (%d entries)\n",
ca->name, IPOIB_TX_RING_SIZE);
goto out_rx_ring_cleanup;
}
- memset(priv->tx_ring, 0,
- IPOIB_TX_RING_SIZE * sizeof (struct ipoib_buf));
/* priv->tx_head & tx_tail are already 0 */
@@ -770,7 +826,7 @@ void ipoib_dev_cleanup(struct net_device *dev)
{
struct ipoib_dev_priv *priv = netdev_priv(dev), *cpriv, *tcpriv;
- ipoib_delete_debug_file(dev);
+ ipoib_delete_debug_files(dev);
/* Delete any child interfaces first */
list_for_each_entry_safe(cpriv, tcpriv, &priv->child_intfs, list) {
@@ -804,10 +860,6 @@ static void ipoib_setup(struct net_device *dev)
dev->watchdog_timeo = HZ;
- dev->rebuild_header = NULL;
- dev->set_mac_address = NULL;
- dev->header_cache_update = NULL;
-
dev->flags |= IFF_BROADCAST | IFF_MULTICAST;
/*
@@ -983,8 +1035,7 @@ static struct net_device *ipoib_add_port(const char *format,
goto register_failed;
}
- if (ipoib_create_debug_file(priv->dev))
- goto debug_failed;
+ ipoib_create_debug_files(priv->dev);
if (ipoib_add_pkey_attr(priv->dev))
goto sysfs_failed;
@@ -998,9 +1049,7 @@ static struct net_device *ipoib_add_port(const char *format,
return priv->dev;
sysfs_failed:
- ipoib_delete_debug_file(priv->dev);
-
-debug_failed:
+ ipoib_delete_debug_files(priv->dev);
unregister_netdev(priv->dev);
register_failed:
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
index 36ce29836bf2..c33ed87f9dff 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
@@ -120,12 +120,8 @@ static void ipoib_mcast_free(struct ipoib_mcast *mcast)
if (mcast->ah)
ipoib_put_ah(mcast->ah);
- while (!skb_queue_empty(&mcast->pkt_queue)) {
- struct sk_buff *skb = skb_dequeue(&mcast->pkt_queue);
-
- skb->dev = dev;
- dev_kfree_skb_any(skb);
- }
+ while (!skb_queue_empty(&mcast->pkt_queue))
+ dev_kfree_skb_any(skb_dequeue(&mcast->pkt_queue));
kfree(mcast);
}
@@ -135,12 +131,10 @@ static struct ipoib_mcast *ipoib_mcast_alloc(struct net_device *dev,
{
struct ipoib_mcast *mcast;
- mcast = kmalloc(sizeof (*mcast), can_sleep ? GFP_KERNEL : GFP_ATOMIC);
+ mcast = kzalloc(sizeof *mcast, can_sleep ? GFP_KERNEL : GFP_ATOMIC);
if (!mcast)
return NULL;
- memset(mcast, 0, sizeof (*mcast));
-
init_completion(&mcast->done);
mcast->dev = dev;
@@ -319,13 +313,8 @@ ipoib_mcast_sendonly_join_complete(int status,
IPOIB_GID_ARG(mcast->mcmember.mgid), status);
/* Flush out any queued packets */
- while (!skb_queue_empty(&mcast->pkt_queue)) {
- struct sk_buff *skb = skb_dequeue(&mcast->pkt_queue);
-
- skb->dev = dev;
-
- dev_kfree_skb_any(skb);
- }
+ while (!skb_queue_empty(&mcast->pkt_queue))
+ dev_kfree_skb_any(skb_dequeue(&mcast->pkt_queue));
/* Clear the busy flag so we try again */
clear_bit(IPOIB_MCAST_FLAG_BUSY, &mcast->flags);
@@ -919,6 +908,8 @@ void ipoib_mcast_restart_task(void *dev_ptr)
ipoib_mcast_start_thread(dev);
}
+#ifdef CONFIG_INFINIBAND_IPOIB_DEBUG
+
struct ipoib_mcast_iter *ipoib_mcast_iter_init(struct net_device *dev)
{
struct ipoib_mcast_iter *iter;
@@ -928,21 +919,16 @@ struct ipoib_mcast_iter *ipoib_mcast_iter_init(struct net_device *dev)
return NULL;
iter->dev = dev;
- memset(iter->mgid.raw, 0, sizeof iter->mgid);
+ memset(iter->mgid.raw, 0, 16);
if (ipoib_mcast_iter_next(iter)) {
- ipoib_mcast_iter_free(iter);
+ kfree(iter);
return NULL;
}
return iter;
}
-void ipoib_mcast_iter_free(struct ipoib_mcast_iter *iter)
-{
- kfree(iter);
-}
-
int ipoib_mcast_iter_next(struct ipoib_mcast_iter *iter)
{
struct ipoib_dev_priv *priv = netdev_priv(iter->dev);
@@ -991,3 +977,5 @@ void ipoib_mcast_iter_read(struct ipoib_mcast_iter *iter,
*complete = iter->complete;
*send_only = iter->send_only;
}
+
+#endif /* CONFIG_INFINIBAND_IPOIB_DEBUG */
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_verbs.c b/drivers/infiniband/ulp/ipoib/ipoib_verbs.c
index 79f59d0563ed..e829e10400e3 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_verbs.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_verbs.c
@@ -41,7 +41,6 @@ int ipoib_mcast_attach(struct net_device *dev, u16 mlid, union ib_gid *mgid)
{
struct ipoib_dev_priv *priv = netdev_priv(dev);
struct ib_qp_attr *qp_attr;
- int attr_mask;
int ret;
u16 pkey_index;
@@ -59,8 +58,7 @@ int ipoib_mcast_attach(struct net_device *dev, u16 mlid, union ib_gid *mgid)
/* set correct QKey for QP */
qp_attr->qkey = priv->qkey;
- attr_mask = IB_QP_QKEY;
- ret = ib_modify_qp(priv->qp, qp_attr, attr_mask);
+ ret = ib_modify_qp(priv->qp, qp_attr, IB_QP_QKEY);
if (ret) {
ipoib_warn(priv, "failed to modify QP, ret = %d\n", ret);
goto out;
@@ -92,7 +90,7 @@ int ipoib_mcast_detach(struct net_device *dev, u16 mlid, union ib_gid *mgid)
return ret;
}
-int ipoib_qp_create(struct net_device *dev)
+int ipoib_init_qp(struct net_device *dev)
{
struct ipoib_dev_priv *priv = netdev_priv(dev);
int ret;
@@ -149,10 +147,11 @@ int ipoib_qp_create(struct net_device *dev)
return 0;
out_fail:
- ib_destroy_qp(priv->qp);
- priv->qp = NULL;
+ qp_attr.qp_state = IB_QPS_RESET;
+ if (ib_modify_qp(priv->qp, &qp_attr, IB_QP_STATE))
+ ipoib_warn(priv, "Failed to modify QP to RESET state\n");
- return -EINVAL;
+ return ret;
}
int ipoib_transport_dev_init(struct net_device *dev, struct ib_device *ca)
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_vlan.c b/drivers/infiniband/ulp/ipoib/ipoib_vlan.c
index 332d730e60c2..d280b341a37f 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_vlan.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_vlan.c
@@ -113,8 +113,7 @@ int ipoib_vlan_add(struct net_device *pdev, unsigned short pkey)
priv->parent = ppriv->dev;
- if (ipoib_create_debug_file(priv->dev))
- goto debug_failed;
+ ipoib_create_debug_files(priv->dev);
if (ipoib_add_pkey_attr(priv->dev))
goto sysfs_failed;
@@ -130,9 +129,7 @@ int ipoib_vlan_add(struct net_device *pdev, unsigned short pkey)
return 0;
sysfs_failed:
- ipoib_delete_debug_file(priv->dev);
-
-debug_failed:
+ ipoib_delete_debug_files(priv->dev);
unregister_netdev(priv->dev);
register_failed:
diff --git a/drivers/infiniband/ulp/srp/Kbuild b/drivers/infiniband/ulp/srp/Kbuild
new file mode 100644
index 000000000000..a16c73c667cb
--- /dev/null
+++ b/drivers/infiniband/ulp/srp/Kbuild
@@ -0,0 +1 @@
+obj-$(CONFIG_INFINIBAND_SRP) += ib_srp.o
diff --git a/drivers/infiniband/ulp/srp/Kconfig b/drivers/infiniband/ulp/srp/Kconfig
new file mode 100644
index 000000000000..8fe3be4e9910
--- /dev/null
+++ b/drivers/infiniband/ulp/srp/Kconfig
@@ -0,0 +1,11 @@
+config INFINIBAND_SRP
+ tristate "InfiniBand SCSI RDMA Protocol"
+ depends on INFINIBAND && SCSI
+ ---help---
+ Support for the SCSI RDMA Protocol over InfiniBand. This
+ allows you to access storage devices that speak SRP over
+ InfiniBand.
+
+ The SRP protocol is defined by the INCITS T10 technical
+ committee. See <http://www.t10.org/>.
+
diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c
new file mode 100644
index 000000000000..321a3a10e69b
--- /dev/null
+++ b/drivers/infiniband/ulp/srp/ib_srp.c
@@ -0,0 +1,1699 @@
+/*
+ * Copyright (c) 2005 Cisco Systems. All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses. You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * - Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * 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.
+ *
+ * $Id: ib_srp.c 3932 2005-11-01 17:19:29Z roland $
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/err.h>
+#include <linux/string.h>
+#include <linux/parser.h>
+#include <linux/random.h>
+
+#include <asm/atomic.h>
+
+#include <scsi/scsi.h>
+#include <scsi/scsi_device.h>
+#include <scsi/scsi_dbg.h>
+#include <scsi/srp.h>
+
+#include <rdma/ib_cache.h>
+
+#include "ib_srp.h"
+
+#define DRV_NAME "ib_srp"
+#define PFX DRV_NAME ": "
+#define DRV_VERSION "0.2"
+#define DRV_RELDATE "November 1, 2005"
+
+MODULE_AUTHOR("Roland Dreier");
+MODULE_DESCRIPTION("InfiniBand SCSI RDMA Protocol initiator "
+ "v" DRV_VERSION " (" DRV_RELDATE ")");
+MODULE_LICENSE("Dual BSD/GPL");
+
+static int topspin_workarounds = 1;
+
+module_param(topspin_workarounds, int, 0444);
+MODULE_PARM_DESC(topspin_workarounds,
+ "Enable workarounds for Topspin/Cisco SRP target bugs if != 0");
+
+static const u8 topspin_oui[3] = { 0x00, 0x05, 0xad };
+
+static void srp_add_one(struct ib_device *device);
+static void srp_remove_one(struct ib_device *device);
+static void srp_completion(struct ib_cq *cq, void *target_ptr);
+static int srp_cm_handler(struct ib_cm_id *cm_id, struct ib_cm_event *event);
+
+static struct ib_client srp_client = {
+ .name = "srp",
+ .add = srp_add_one,
+ .remove = srp_remove_one
+};
+
+static inline struct srp_target_port *host_to_target(struct Scsi_Host *host)
+{
+ return (struct srp_target_port *) host->hostdata;
+}
+
+static const char *srp_target_info(struct Scsi_Host *host)
+{
+ return host_to_target(host)->target_name;
+}
+
+static struct srp_iu *srp_alloc_iu(struct srp_host *host, size_t size,
+ gfp_t gfp_mask,
+ enum dma_data_direction direction)
+{
+ struct srp_iu *iu;
+
+ iu = kmalloc(sizeof *iu, gfp_mask);
+ if (!iu)
+ goto out;
+
+ iu->buf = kzalloc(size, gfp_mask);
+ if (!iu->buf)
+ goto out_free_iu;
+
+ iu->dma = dma_map_single(host->dev->dma_device, iu->buf, size, direction);
+ if (dma_mapping_error(iu->dma))
+ goto out_free_buf;
+
+ iu->size = size;
+ iu->direction = direction;
+
+ return iu;
+
+out_free_buf:
+ kfree(iu->buf);
+out_free_iu:
+ kfree(iu);
+out:
+ return NULL;
+}
+
+static void srp_free_iu(struct srp_host *host, struct srp_iu *iu)
+{
+ if (!iu)
+ return;
+
+ dma_unmap_single(host->dev->dma_device, iu->dma, iu->size, iu->direction);
+ kfree(iu->buf);
+ kfree(iu);
+}
+
+static void srp_qp_event(struct ib_event *event, void *context)
+{
+ printk(KERN_ERR PFX "QP event %d\n", event->event);
+}
+
+static int srp_init_qp(struct srp_target_port *target,
+ struct ib_qp *qp)
+{
+ struct ib_qp_attr *attr;
+ int ret;
+
+ attr = kmalloc(sizeof *attr, GFP_KERNEL);
+ if (!attr)
+ return -ENOMEM;
+
+ ret = ib_find_cached_pkey(target->srp_host->dev,
+ target->srp_host->port,
+ be16_to_cpu(target->path.pkey),
+ &attr->pkey_index);
+ if (ret)
+ goto out;
+
+ attr->qp_state = IB_QPS_INIT;
+ attr->qp_access_flags = (IB_ACCESS_REMOTE_READ |
+ IB_ACCESS_REMOTE_WRITE);
+ attr->port_num = target->srp_host->port;
+
+ ret = ib_modify_qp(qp, attr,
+ IB_QP_STATE |
+ IB_QP_PKEY_INDEX |
+ IB_QP_ACCESS_FLAGS |
+ IB_QP_PORT);
+
+out:
+ kfree(attr);
+ return ret;
+}
+
+static int srp_create_target_ib(struct srp_target_port *target)
+{
+ struct ib_qp_init_attr *init_attr;
+ int ret;
+
+ init_attr = kzalloc(sizeof *init_attr, GFP_KERNEL);
+ if (!init_attr)
+ return -ENOMEM;
+
+ target->cq = ib_create_cq(target->srp_host->dev, srp_completion,
+ NULL, target, SRP_CQ_SIZE);
+ if (IS_ERR(target->cq)) {
+ ret = PTR_ERR(target->cq);
+ goto out;
+ }
+
+ ib_req_notify_cq(target->cq, IB_CQ_NEXT_COMP);
+
+ init_attr->event_handler = srp_qp_event;
+ init_attr->cap.max_send_wr = SRP_SQ_SIZE;
+ init_attr->cap.max_recv_wr = SRP_RQ_SIZE;
+ init_attr->cap.max_recv_sge = 1;
+ init_attr->cap.max_send_sge = 1;
+ init_attr->sq_sig_type = IB_SIGNAL_ALL_WR;
+ init_attr->qp_type = IB_QPT_RC;
+ init_attr->send_cq = target->cq;
+ init_attr->recv_cq = target->cq;
+
+ target->qp = ib_create_qp(target->srp_host->pd, init_attr);
+ if (IS_ERR(target->qp)) {
+ ret = PTR_ERR(target->qp);
+ ib_destroy_cq(target->cq);
+ goto out;
+ }
+
+ ret = srp_init_qp(target, target->qp);
+ if (ret) {
+ ib_destroy_qp(target->qp);
+ ib_destroy_cq(target->cq);
+ goto out;
+ }
+
+out:
+ kfree(init_attr);
+ return ret;
+}
+
+static void srp_free_target_ib(struct srp_target_port *target)
+{
+ int i;
+
+ ib_destroy_qp(target->qp);
+ ib_destroy_cq(target->cq);
+
+ for (i = 0; i < SRP_RQ_SIZE; ++i)
+ srp_free_iu(target->srp_host, target->rx_ring[i]);
+ for (i = 0; i < SRP_SQ_SIZE + 1; ++i)
+ srp_free_iu(target->srp_host, target->tx_ring[i]);
+}
+
+static void srp_path_rec_completion(int status,
+ struct ib_sa_path_rec *pathrec,
+ void *target_ptr)
+{
+ struct srp_target_port *target = target_ptr;
+
+ target->status = status;
+ if (status)
+ printk(KERN_ERR PFX "Got failed path rec status %d\n", status);
+ else
+ target->path = *pathrec;
+ complete(&target->done);
+}
+
+static int srp_lookup_path(struct srp_target_port *target)
+{
+ target->path.numb_path = 1;
+
+ init_completion(&target->done);
+
+ target->path_query_id = ib_sa_path_rec_get(target->srp_host->dev,
+ target->srp_host->port,
+ &target->path,
+ IB_SA_PATH_REC_DGID |
+ IB_SA_PATH_REC_SGID |
+ IB_SA_PATH_REC_NUMB_PATH |
+ IB_SA_PATH_REC_PKEY,
+ SRP_PATH_REC_TIMEOUT_MS,
+ GFP_KERNEL,
+ srp_path_rec_completion,
+ target, &target->path_query);
+ if (target->path_query_id < 0)
+ return target->path_query_id;
+
+ wait_for_completion(&target->done);
+
+ if (target->status < 0)
+ printk(KERN_WARNING PFX "Path record query failed\n");
+
+ return target->status;
+}
+
+static int srp_send_req(struct srp_target_port *target)
+{
+ struct {
+ struct ib_cm_req_param param;
+ struct srp_login_req priv;
+ } *req = NULL;
+ int status;
+
+ req = kzalloc(sizeof *req, GFP_KERNEL);
+ if (!req)
+ return -ENOMEM;
+
+ req->param.primary_path = &target->path;
+ req->param.alternate_path = NULL;
+ req->param.service_id = target->service_id;
+ req->param.qp_num = target->qp->qp_num;
+ req->param.qp_type = target->qp->qp_type;
+ req->param.private_data = &req->priv;
+ req->param.private_data_len = sizeof req->priv;
+ req->param.flow_control = 1;
+
+ get_random_bytes(&req->param.starting_psn, 4);
+ req->param.starting_psn &= 0xffffff;
+
+ /*
+ * Pick some arbitrary defaults here; we could make these
+ * module parameters if anyone cared about setting them.
+ */
+ req->param.responder_resources = 4;
+ req->param.remote_cm_response_timeout = 20;
+ req->param.local_cm_response_timeout = 20;
+ req->param.retry_count = 7;
+ req->param.rnr_retry_count = 7;
+ req->param.max_cm_retries = 15;
+
+ req->priv.opcode = SRP_LOGIN_REQ;
+ req->priv.tag = 0;
+ req->priv.req_it_iu_len = cpu_to_be32(SRP_MAX_IU_LEN);
+ req->priv.req_buf_fmt = cpu_to_be16(SRP_BUF_FORMAT_DIRECT |
+ SRP_BUF_FORMAT_INDIRECT);
+ memcpy(req->priv.initiator_port_id, target->srp_host->initiator_port_id, 16);
+ /*
+ * Topspin/Cisco SRP targets will reject our login unless we
+ * zero out the first 8 bytes of our initiator port ID. The
+ * second 8 bytes must be our local node GUID, but we always
+ * use that anyway.
+ */
+ if (topspin_workarounds && !memcmp(&target->ioc_guid, topspin_oui, 3)) {
+ printk(KERN_DEBUG PFX "Topspin/Cisco initiator port ID workaround "
+ "activated for target GUID %016llx\n",
+ (unsigned long long) be64_to_cpu(target->ioc_guid));
+ memset(req->priv.initiator_port_id, 0, 8);
+ }
+ memcpy(req->priv.target_port_id, &target->id_ext, 8);
+ memcpy(req->priv.target_port_id + 8, &target->ioc_guid, 8);
+
+ status = ib_send_cm_req(target->cm_id, &req->param);
+
+ kfree(req);
+
+ return status;
+}
+
+static void srp_disconnect_target(struct srp_target_port *target)
+{
+ /* XXX should send SRP_I_LOGOUT request */
+
+ init_completion(&target->done);
+ ib_send_cm_dreq(target->cm_id, NULL, 0);
+ wait_for_completion(&target->done);
+}
+
+static void srp_remove_work(void *target_ptr)
+{
+ struct srp_target_port *target = target_ptr;
+
+ spin_lock_irq(target->scsi_host->host_lock);
+ if (target->state != SRP_TARGET_DEAD) {
+ spin_unlock_irq(target->scsi_host->host_lock);
+ scsi_host_put(target->scsi_host);
+ return;
+ }
+ target->state = SRP_TARGET_REMOVED;
+ spin_unlock_irq(target->scsi_host->host_lock);
+
+ down(&target->srp_host->target_mutex);
+ list_del(&target->list);
+ up(&target->srp_host->target_mutex);
+
+ scsi_remove_host(target->scsi_host);
+ ib_destroy_cm_id(target->cm_id);
+ srp_free_target_ib(target);
+ scsi_host_put(target->scsi_host);
+ /* And another put to really free the target port... */
+ scsi_host_put(target->scsi_host);
+}
+
+static int srp_connect_target(struct srp_target_port *target)
+{
+ int ret;
+
+ ret = srp_lookup_path(target);
+ if (ret)
+ return ret;
+
+ while (1) {
+ init_completion(&target->done);
+ ret = srp_send_req(target);
+ if (ret)
+ return ret;
+ wait_for_completion(&target->done);
+
+ /*
+ * The CM event handling code will set status to
+ * SRP_PORT_REDIRECT if we get a port redirect REJ
+ * back, or SRP_DLID_REDIRECT if we get a lid/qp
+ * redirect REJ back.
+ */
+ switch (target->status) {
+ case 0:
+ return 0;
+
+ case SRP_PORT_REDIRECT:
+ ret = srp_lookup_path(target);
+ if (ret)
+ return ret;
+ break;
+
+ case SRP_DLID_REDIRECT:
+ break;
+
+ default:
+ return target->status;
+ }
+ }
+}
+
+static int srp_reconnect_target(struct srp_target_port *target)
+{
+ struct ib_cm_id *new_cm_id;
+ struct ib_qp_attr qp_attr;
+ struct srp_request *req;
+ struct ib_wc wc;
+ int ret;
+ int i;
+
+ spin_lock_irq(target->scsi_host->host_lock);
+ if (target->state != SRP_TARGET_LIVE) {
+ spin_unlock_irq(target->scsi_host->host_lock);
+ return -EAGAIN;
+ }
+ target->state = SRP_TARGET_CONNECTING;
+ spin_unlock_irq(target->scsi_host->host_lock);
+
+ srp_disconnect_target(target);
+ /*
+ * Now get a new local CM ID so that we avoid confusing the
+ * target in case things are really fouled up.
+ */
+ new_cm_id = ib_create_cm_id(target->srp_host->dev,
+ srp_cm_handler, target);
+ if (IS_ERR(new_cm_id)) {
+ ret = PTR_ERR(new_cm_id);
+ goto err;
+ }
+ ib_destroy_cm_id(target->cm_id);
+ target->cm_id = new_cm_id;
+
+ qp_attr.qp_state = IB_QPS_RESET;
+ ret = ib_modify_qp(target->qp, &qp_attr, IB_QP_STATE);
+ if (ret)
+ goto err;
+
+ ret = srp_init_qp(target, target->qp);
+ if (ret)
+ goto err;
+
+ while (ib_poll_cq(target->cq, 1, &wc) > 0)
+ ; /* nothing */
+
+ list_for_each_entry(req, &target->req_queue, list) {
+ req->scmnd->result = DID_RESET << 16;
+ req->scmnd->scsi_done(req->scmnd);
+ }
+
+ target->rx_head = 0;
+ target->tx_head = 0;
+ target->tx_tail = 0;
+ target->req_head = 0;
+ for (i = 0; i < SRP_SQ_SIZE - 1; ++i)
+ target->req_ring[i].next = i + 1;
+ target->req_ring[SRP_SQ_SIZE - 1].next = -1;
+ INIT_LIST_HEAD(&target->req_queue);
+
+ ret = srp_connect_target(target);
+ if (ret)
+ goto err;
+
+ spin_lock_irq(target->scsi_host->host_lock);
+ if (target->state == SRP_TARGET_CONNECTING) {
+ ret = 0;
+ target->state = SRP_TARGET_LIVE;
+ } else
+ ret = -EAGAIN;
+ spin_unlock_irq(target->scsi_host->host_lock);
+
+ return ret;
+
+err:
+ printk(KERN_ERR PFX "reconnect failed (%d), removing target port.\n", ret);
+
+ /*
+ * We couldn't reconnect, so kill our target port off.
+ * However, we have to defer the real removal because we might
+ * be in the context of the SCSI error handler now, which
+ * would deadlock if we call scsi_remove_host().
+ */
+ spin_lock_irq(target->scsi_host->host_lock);
+ if (target->state == SRP_TARGET_CONNECTING) {
+ target->state = SRP_TARGET_DEAD;
+ INIT_WORK(&target->work, srp_remove_work, target);
+ schedule_work(&target->work);
+ }
+ spin_unlock_irq(target->scsi_host->host_lock);
+
+ return ret;
+}
+
+static int srp_map_data(struct scsi_cmnd *scmnd, struct srp_target_port *target,
+ struct srp_request *req)
+{
+ struct srp_cmd *cmd = req->cmd->buf;
+ int len;
+ u8 fmt;
+
+ if (!scmnd->request_buffer || scmnd->sc_data_direction == DMA_NONE)
+ return sizeof (struct srp_cmd);
+
+ if (scmnd->sc_data_direction != DMA_FROM_DEVICE &&
+ scmnd->sc_data_direction != DMA_TO_DEVICE) {
+ printk(KERN_WARNING PFX "Unhandled data direction %d\n",
+ scmnd->sc_data_direction);
+ return -EINVAL;
+ }
+
+ if (scmnd->use_sg) {
+ struct scatterlist *scat = scmnd->request_buffer;
+ int n;
+ int i;
+
+ n = dma_map_sg(target->srp_host->dev->dma_device,
+ scat, scmnd->use_sg, scmnd->sc_data_direction);
+
+ if (n == 1) {
+ struct srp_direct_buf *buf = (void *) cmd->add_data;
+
+ fmt = SRP_DATA_DESC_DIRECT;
+
+ buf->va = cpu_to_be64(sg_dma_address(scat));
+ buf->key = cpu_to_be32(target->srp_host->mr->rkey);
+ buf->len = cpu_to_be32(sg_dma_len(scat));
+
+ len = sizeof (struct srp_cmd) +
+ sizeof (struct srp_direct_buf);
+ } else {
+ struct srp_indirect_buf *buf = (void *) cmd->add_data;
+ u32 datalen = 0;
+
+ fmt = SRP_DATA_DESC_INDIRECT;
+
+ if (scmnd->sc_data_direction == DMA_TO_DEVICE)
+ cmd->data_out_desc_cnt = n;
+ else
+ cmd->data_in_desc_cnt = n;
+
+ buf->table_desc.va = cpu_to_be64(req->cmd->dma +
+ sizeof *cmd +
+ sizeof *buf);
+ buf->table_desc.key =
+ cpu_to_be32(target->srp_host->mr->rkey);
+ buf->table_desc.len =
+ cpu_to_be32(n * sizeof (struct srp_direct_buf));
+
+ for (i = 0; i < n; ++i) {
+ buf->desc_list[i].va = cpu_to_be64(sg_dma_address(&scat[i]));
+ buf->desc_list[i].key =
+ cpu_to_be32(target->srp_host->mr->rkey);
+ buf->desc_list[i].len = cpu_to_be32(sg_dma_len(&scat[i]));
+
+ datalen += sg_dma_len(&scat[i]);
+ }
+
+ buf->len = cpu_to_be32(datalen);
+
+ len = sizeof (struct srp_cmd) +
+ sizeof (struct srp_indirect_buf) +
+ n * sizeof (struct srp_direct_buf);
+ }
+ } else {
+ struct srp_direct_buf *buf = (void *) cmd->add_data;
+ dma_addr_t dma;
+
+ dma = dma_map_single(target->srp_host->dev->dma_device,
+ scmnd->request_buffer, scmnd->request_bufflen,
+ scmnd->sc_data_direction);
+ if (dma_mapping_error(dma)) {
+ printk(KERN_WARNING PFX "unable to map %p/%d (dir %d)\n",
+ scmnd->request_buffer, (int) scmnd->request_bufflen,
+ scmnd->sc_data_direction);
+ return -EINVAL;
+ }
+
+ pci_unmap_addr_set(req, direct_mapping, dma);
+
+ buf->va = cpu_to_be64(dma);
+ buf->key = cpu_to_be32(target->srp_host->mr->rkey);
+ buf->len = cpu_to_be32(scmnd->request_bufflen);
+
+ fmt = SRP_DATA_DESC_DIRECT;
+
+ len = sizeof (struct srp_cmd) + sizeof (struct srp_direct_buf);
+ }
+
+ if (scmnd->sc_data_direction == DMA_TO_DEVICE)
+ cmd->buf_fmt = fmt << 4;
+ else
+ cmd->buf_fmt = fmt;
+
+
+ return len;
+}
+
+static void srp_unmap_data(struct scsi_cmnd *scmnd,
+ struct srp_target_port *target,
+ struct srp_request *req)
+{
+ if (!scmnd->request_buffer ||
+ (scmnd->sc_data_direction != DMA_TO_DEVICE &&
+ scmnd->sc_data_direction != DMA_FROM_DEVICE))
+ return;
+
+ if (scmnd->use_sg)
+ dma_unmap_sg(target->srp_host->dev->dma_device,
+ (struct scatterlist *) scmnd->request_buffer,
+ scmnd->use_sg, scmnd->sc_data_direction);
+ else
+ dma_unmap_single(target->srp_host->dev->dma_device,
+ pci_unmap_addr(req, direct_mapping),
+ scmnd->request_bufflen,
+ scmnd->sc_data_direction);
+}
+
+static void srp_process_rsp(struct srp_target_port *target, struct srp_rsp *rsp)
+{
+ struct srp_request *req;
+ struct scsi_cmnd *scmnd;
+ unsigned long flags;
+ s32 delta;
+
+ delta = (s32) be32_to_cpu(rsp->req_lim_delta);
+
+ spin_lock_irqsave(target->scsi_host->host_lock, flags);
+
+ target->req_lim += delta;
+
+ req = &target->req_ring[rsp->tag & ~SRP_TAG_TSK_MGMT];
+
+ if (unlikely(rsp->tag & SRP_TAG_TSK_MGMT)) {
+ if (be32_to_cpu(rsp->resp_data_len) < 4)
+ req->tsk_status = -1;
+ else
+ req->tsk_status = rsp->data[3];
+ complete(&req->done);
+ } else {
+ scmnd = req->scmnd;
+ if (!scmnd)
+ printk(KERN_ERR "Null scmnd for RSP w/tag %016llx\n",
+ (unsigned long long) rsp->tag);
+ scmnd->result = rsp->status;
+
+ if (rsp->flags & SRP_RSP_FLAG_SNSVALID) {
+ memcpy(scmnd->sense_buffer, rsp->data +
+ be32_to_cpu(rsp->resp_data_len),
+ min_t(int, be32_to_cpu(rsp->sense_data_len),
+ SCSI_SENSE_BUFFERSIZE));
+ }
+
+ if (rsp->flags & (SRP_RSP_FLAG_DOOVER | SRP_RSP_FLAG_DOUNDER))
+ scmnd->resid = be32_to_cpu(rsp->data_out_res_cnt);
+ else if (rsp->flags & (SRP_RSP_FLAG_DIOVER | SRP_RSP_FLAG_DIUNDER))
+ scmnd->resid = be32_to_cpu(rsp->data_in_res_cnt);
+
+ srp_unmap_data(scmnd, target, req);
+
+ if (!req->tsk_mgmt) {
+ req->scmnd = NULL;
+ scmnd->host_scribble = (void *) -1L;
+ scmnd->scsi_done(scmnd);
+
+ list_del(&req->list);
+ req->next = target->req_head;
+ target->req_head = rsp->tag & ~SRP_TAG_TSK_MGMT;
+ } else
+ req->cmd_done = 1;
+ }
+
+ spin_unlock_irqrestore(target->scsi_host->host_lock, flags);
+}
+
+static void srp_reconnect_work(void *target_ptr)
+{
+ struct srp_target_port *target = target_ptr;
+
+ srp_reconnect_target(target);
+}
+
+static void srp_handle_recv(struct srp_target_port *target, struct ib_wc *wc)
+{
+ struct srp_iu *iu;
+ u8 opcode;
+
+ iu = target->rx_ring[wc->wr_id & ~SRP_OP_RECV];
+
+ dma_sync_single_for_cpu(target->srp_host->dev->dma_device, iu->dma,
+ target->max_ti_iu_len, DMA_FROM_DEVICE);
+
+ opcode = *(u8 *) iu->buf;
+
+ if (0) {
+ int i;
+
+ printk(KERN_ERR PFX "recv completion, opcode 0x%02x\n", opcode);
+
+ for (i = 0; i < wc->byte_len; ++i) {
+ if (i % 8 == 0)
+ printk(KERN_ERR " [%02x] ", i);
+ printk(" %02x", ((u8 *) iu->buf)[i]);
+ if ((i + 1) % 8 == 0)
+ printk("\n");
+ }
+
+ if (wc->byte_len % 8)
+ printk("\n");
+ }
+
+ switch (opcode) {
+ case SRP_RSP:
+ srp_process_rsp(target, iu->buf);
+ break;
+
+ case SRP_T_LOGOUT:
+ /* XXX Handle target logout */
+ printk(KERN_WARNING PFX "Got target logout request\n");
+ break;
+
+ default:
+ printk(KERN_WARNING PFX "Unhandled SRP opcode 0x%02x\n", opcode);
+ break;
+ }
+
+ dma_sync_single_for_device(target->srp_host->dev->dma_device, iu->dma,
+ target->max_ti_iu_len, DMA_FROM_DEVICE);
+}
+
+static void srp_completion(struct ib_cq *cq, void *target_ptr)
+{
+ struct srp_target_port *target = target_ptr;
+ struct ib_wc wc;
+ unsigned long flags;
+
+ ib_req_notify_cq(cq, IB_CQ_NEXT_COMP);
+ while (ib_poll_cq(cq, 1, &wc) > 0) {
+ if (wc.status) {
+ printk(KERN_ERR PFX "failed %s status %d\n",
+ wc.wr_id & SRP_OP_RECV ? "receive" : "send",
+ wc.status);
+ spin_lock_irqsave(target->scsi_host->host_lock, flags);
+ if (target->state == SRP_TARGET_LIVE)
+ schedule_work(&target->work);
+ spin_unlock_irqrestore(target->scsi_host->host_lock, flags);
+ break;
+ }
+
+ if (wc.wr_id & SRP_OP_RECV)
+ srp_handle_recv(target, &wc);
+ else
+ ++target->tx_tail;
+ }
+}
+
+static int __srp_post_recv(struct srp_target_port *target)
+{
+ struct srp_iu *iu;
+ struct ib_sge list;
+ struct ib_recv_wr wr, *bad_wr;
+ unsigned int next;
+ int ret;
+
+ next = target->rx_head & (SRP_RQ_SIZE - 1);
+ wr.wr_id = next | SRP_OP_RECV;
+ iu = target->rx_ring[next];
+
+ list.addr = iu->dma;
+ list.length = iu->size;
+ list.lkey = target->srp_host->mr->lkey;
+
+ wr.next = NULL;
+ wr.sg_list = &list;
+ wr.num_sge = 1;
+
+ ret = ib_post_recv(target->qp, &wr, &bad_wr);
+ if (!ret)
+ ++target->rx_head;
+
+ return ret;
+}
+
+static int srp_post_recv(struct srp_target_port *target)
+{
+ unsigned long flags;
+ int ret;
+
+ spin_lock_irqsave(target->scsi_host->host_lock, flags);
+ ret = __srp_post_recv(target);
+ spin_unlock_irqrestore(target->scsi_host->host_lock, flags);
+
+ return ret;
+}
+
+/*
+ * Must be called with target->scsi_host->host_lock held to protect
+ * req_lim and tx_head.
+ */
+static struct srp_iu *__srp_get_tx_iu(struct srp_target_port *target)
+{
+ if (target->tx_head - target->tx_tail >= SRP_SQ_SIZE)
+ return NULL;
+
+ return target->tx_ring[target->tx_head & SRP_SQ_SIZE];
+}
+
+/*
+ * Must be called with target->scsi_host->host_lock held to protect
+ * req_lim and tx_head.
+ */
+static int __srp_post_send(struct srp_target_port *target,
+ struct srp_iu *iu, int len)
+{
+ struct ib_sge list;
+ struct ib_send_wr wr, *bad_wr;
+ int ret = 0;
+
+ if (target->req_lim < 1) {
+ printk(KERN_ERR PFX "Target has req_lim %d\n", target->req_lim);
+ return -EAGAIN;
+ }
+
+ list.addr = iu->dma;
+ list.length = len;
+ list.lkey = target->srp_host->mr->lkey;
+
+ wr.next = NULL;
+ wr.wr_id = target->tx_head & SRP_SQ_SIZE;
+ wr.sg_list = &list;
+ wr.num_sge = 1;
+ wr.opcode = IB_WR_SEND;
+ wr.send_flags = IB_SEND_SIGNALED;
+
+ ret = ib_post_send(target->qp, &wr, &bad_wr);
+
+ if (!ret) {
+ ++target->tx_head;
+ --target->req_lim;
+ }
+
+ return ret;
+}
+
+static int srp_queuecommand(struct scsi_cmnd *scmnd,
+ void (*done)(struct scsi_cmnd *))
+{
+ struct srp_target_port *target = host_to_target(scmnd->device->host);
+ struct srp_request *req;
+ struct srp_iu *iu;
+ struct srp_cmd *cmd;
+ long req_index;
+ int len;
+
+ if (target->state == SRP_TARGET_CONNECTING)
+ goto err;
+
+ if (target->state == SRP_TARGET_DEAD ||
+ target->state == SRP_TARGET_REMOVED) {
+ scmnd->result = DID_BAD_TARGET << 16;
+ done(scmnd);
+ return 0;
+ }
+
+ iu = __srp_get_tx_iu(target);
+ if (!iu)
+ goto err;
+
+ dma_sync_single_for_cpu(target->srp_host->dev->dma_device, iu->dma,
+ SRP_MAX_IU_LEN, DMA_TO_DEVICE);
+
+ req_index = target->req_head;
+
+ scmnd->scsi_done = done;
+ scmnd->result = 0;
+ scmnd->host_scribble = (void *) req_index;
+
+ cmd = iu->buf;
+ memset(cmd, 0, sizeof *cmd);
+
+ cmd->opcode = SRP_CMD;
+ cmd->lun = cpu_to_be64((u64) scmnd->device->lun << 48);
+ cmd->tag = req_index;
+ memcpy(cmd->cdb, scmnd->cmnd, scmnd->cmd_len);
+
+ req = &target->req_ring[req_index];
+
+ req->scmnd = scmnd;
+ req->cmd = iu;
+ req->cmd_done = 0;
+ req->tsk_mgmt = NULL;
+
+ len = srp_map_data(scmnd, target, req);
+ if (len < 0) {
+ printk(KERN_ERR PFX "Failed to map data\n");
+ goto err;
+ }
+
+ if (__srp_post_recv(target)) {
+ printk(KERN_ERR PFX "Recv failed\n");
+ goto err_unmap;
+ }
+
+ dma_sync_single_for_device(target->srp_host->dev->dma_device, iu->dma,
+ SRP_MAX_IU_LEN, DMA_TO_DEVICE);
+
+ if (__srp_post_send(target, iu, len)) {
+ printk(KERN_ERR PFX "Send failed\n");
+ goto err_unmap;
+ }
+
+ target->req_head = req->next;
+ list_add_tail(&req->list, &target->req_queue);
+
+ return 0;
+
+err_unmap:
+ srp_unmap_data(scmnd, target, req);
+
+err:
+ return SCSI_MLQUEUE_HOST_BUSY;
+}
+
+static int srp_alloc_iu_bufs(struct srp_target_port *target)
+{
+ int i;
+
+ for (i = 0; i < SRP_RQ_SIZE; ++i) {
+ target->rx_ring[i] = srp_alloc_iu(target->srp_host,
+ target->max_ti_iu_len,
+ GFP_KERNEL, DMA_FROM_DEVICE);
+ if (!target->rx_ring[i])
+ goto err;
+ }
+
+ for (i = 0; i < SRP_SQ_SIZE + 1; ++i) {
+ target->tx_ring[i] = srp_alloc_iu(target->srp_host,
+ SRP_MAX_IU_LEN,
+ GFP_KERNEL, DMA_TO_DEVICE);
+ if (!target->tx_ring[i])
+ goto err;
+ }
+
+ return 0;
+
+err:
+ for (i = 0; i < SRP_RQ_SIZE; ++i) {
+ srp_free_iu(target->srp_host, target->rx_ring[i]);
+ target->rx_ring[i] = NULL;
+ }
+
+ for (i = 0; i < SRP_SQ_SIZE + 1; ++i) {
+ srp_free_iu(target->srp_host, target->tx_ring[i]);
+ target->tx_ring[i] = NULL;
+ }
+
+ return -ENOMEM;
+}
+
+static void srp_cm_rej_handler(struct ib_cm_id *cm_id,
+ struct ib_cm_event *event,
+ struct srp_target_port *target)
+{
+ struct ib_class_port_info *cpi;
+ int opcode;
+
+ switch (event->param.rej_rcvd.reason) {
+ case IB_CM_REJ_PORT_CM_REDIRECT:
+ cpi = event->param.rej_rcvd.ari;
+ target->path.dlid = cpi->redirect_lid;
+ target->path.pkey = cpi->redirect_pkey;
+ cm_id->remote_cm_qpn = be32_to_cpu(cpi->redirect_qp) & 0x00ffffff;
+ memcpy(target->path.dgid.raw, cpi->redirect_gid, 16);
+
+ target->status = target->path.dlid ?
+ SRP_DLID_REDIRECT : SRP_PORT_REDIRECT;
+ break;
+
+ case IB_CM_REJ_PORT_REDIRECT:
+ if (topspin_workarounds &&
+ !memcmp(&target->ioc_guid, topspin_oui, 3)) {
+ /*
+ * Topspin/Cisco SRP gateways incorrectly send
+ * reject reason code 25 when they mean 24
+ * (port redirect).
+ */
+ memcpy(target->path.dgid.raw,
+ event->param.rej_rcvd.ari, 16);
+
+ printk(KERN_DEBUG PFX "Topspin/Cisco redirect to target port GID %016llx%016llx\n",
+ (unsigned long long) be64_to_cpu(target->path.dgid.global.subnet_prefix),
+ (unsigned long long) be64_to_cpu(target->path.dgid.global.interface_id));
+
+ target->status = SRP_PORT_REDIRECT;
+ } else {
+ printk(KERN_WARNING " REJ reason: IB_CM_REJ_PORT_REDIRECT\n");
+ target->status = -ECONNRESET;
+ }
+ break;
+
+ case IB_CM_REJ_DUPLICATE_LOCAL_COMM_ID:
+ printk(KERN_WARNING " REJ reason: IB_CM_REJ_DUPLICATE_LOCAL_COMM_ID\n");
+ target->status = -ECONNRESET;
+ break;
+
+ case IB_CM_REJ_CONSUMER_DEFINED:
+ opcode = *(u8 *) event->private_data;
+ if (opcode == SRP_LOGIN_REJ) {
+ struct srp_login_rej *rej = event->private_data;
+ u32 reason = be32_to_cpu(rej->reason);
+
+ if (reason == SRP_LOGIN_REJ_REQ_IT_IU_LENGTH_TOO_LARGE)
+ printk(KERN_WARNING PFX
+ "SRP_LOGIN_REJ: requested max_it_iu_len too large\n");
+ else
+ printk(KERN_WARNING PFX
+ "SRP LOGIN REJECTED, reason 0x%08x\n", reason);
+ } else
+ printk(KERN_WARNING " REJ reason: IB_CM_REJ_CONSUMER_DEFINED,"
+ " opcode 0x%02x\n", opcode);
+ target->status = -ECONNRESET;
+ break;
+
+ default:
+ printk(KERN_WARNING " REJ reason 0x%x\n",
+ event->param.rej_rcvd.reason);
+ target->status = -ECONNRESET;
+ }
+}
+
+static int srp_cm_handler(struct ib_cm_id *cm_id, struct ib_cm_event *event)
+{
+ struct srp_target_port *target = cm_id->context;
+ struct ib_qp_attr *qp_attr = NULL;
+ int attr_mask = 0;
+ int comp = 0;
+ int opcode = 0;
+
+ switch (event->event) {
+ case IB_CM_REQ_ERROR:
+ printk(KERN_DEBUG PFX "Sending CM REQ failed\n");
+ comp = 1;
+ target->status = -ECONNRESET;
+ break;
+
+ case IB_CM_REP_RECEIVED:
+ comp = 1;
+ opcode = *(u8 *) event->private_data;
+
+ if (opcode == SRP_LOGIN_RSP) {
+ struct srp_login_rsp *rsp = event->private_data;
+
+ target->max_ti_iu_len = be32_to_cpu(rsp->max_ti_iu_len);
+ target->req_lim = be32_to_cpu(rsp->req_lim_delta);
+
+ target->scsi_host->can_queue = min(target->req_lim,
+ target->scsi_host->can_queue);
+ } else {
+ printk(KERN_WARNING PFX "Unhandled RSP opcode %#x\n", opcode);
+ target->status = -ECONNRESET;
+ break;
+ }
+
+ target->status = srp_alloc_iu_bufs(target);
+ if (target->status)
+ break;
+
+ qp_attr = kmalloc(sizeof *qp_attr, GFP_KERNEL);
+ if (!qp_attr) {
+ target->status = -ENOMEM;
+ break;
+ }
+
+ qp_attr->qp_state = IB_QPS_RTR;
+ target->status = ib_cm_init_qp_attr(cm_id, qp_attr, &attr_mask);
+ if (target->status)
+ break;
+
+ target->status = ib_modify_qp(target->qp, qp_attr, attr_mask);
+ if (target->status)
+ break;
+
+ target->status = srp_post_recv(target);
+ if (target->status)
+ break;
+
+ qp_attr->qp_state = IB_QPS_RTS;
+ target->status = ib_cm_init_qp_attr(cm_id, qp_attr, &attr_mask);
+ if (target->status)
+ break;
+
+ target->status = ib_modify_qp(target->qp, qp_attr, attr_mask);
+ if (target->status)
+ break;
+
+ target->status = ib_send_cm_rtu(cm_id, NULL, 0);
+ if (target->status)
+ break;
+
+ break;
+
+ case IB_CM_REJ_RECEIVED:
+ printk(KERN_DEBUG PFX "REJ received\n");
+ comp = 1;
+
+ srp_cm_rej_handler(cm_id, event, target);
+ break;
+
+ case IB_CM_MRA_RECEIVED:
+ printk(KERN_ERR PFX "MRA received\n");
+ break;
+
+ case IB_CM_DREP_RECEIVED:
+ break;
+
+ case IB_CM_TIMEWAIT_EXIT:
+ printk(KERN_ERR PFX "connection closed\n");
+
+ comp = 1;
+ target->status = 0;
+ break;
+
+ default:
+ printk(KERN_WARNING PFX "Unhandled CM event %d\n", event->event);
+ break;
+ }
+
+ if (comp)
+ complete(&target->done);
+
+ kfree(qp_attr);
+
+ return 0;
+}
+
+static int srp_send_tsk_mgmt(struct scsi_cmnd *scmnd, u8 func)
+{
+ struct srp_target_port *target = host_to_target(scmnd->device->host);
+ struct srp_request *req;
+ struct srp_iu *iu;
+ struct srp_tsk_mgmt *tsk_mgmt;
+ int req_index;
+ int ret = FAILED;
+
+ spin_lock_irq(target->scsi_host->host_lock);
+
+ if (scmnd->host_scribble == (void *) -1L)
+ goto out;
+
+ req_index = (long) scmnd->host_scribble;
+ printk(KERN_ERR "Abort for req_index %d\n", req_index);
+
+ req = &target->req_ring[req_index];
+ init_completion(&req->done);
+
+ iu = __srp_get_tx_iu(target);
+ if (!iu)
+ goto out;
+
+ tsk_mgmt = iu->buf;
+ memset(tsk_mgmt, 0, sizeof *tsk_mgmt);
+
+ tsk_mgmt->opcode = SRP_TSK_MGMT;
+ tsk_mgmt->lun = cpu_to_be64((u64) scmnd->device->lun << 48);
+ tsk_mgmt->tag = req_index | SRP_TAG_TSK_MGMT;
+ tsk_mgmt->tsk_mgmt_func = func;
+ tsk_mgmt->task_tag = req_index;
+
+ if (__srp_post_send(target, iu, sizeof *tsk_mgmt))
+ goto out;
+
+ req->tsk_mgmt = iu;
+
+ spin_unlock_irq(target->scsi_host->host_lock);
+ if (!wait_for_completion_timeout(&req->done,
+ msecs_to_jiffies(SRP_ABORT_TIMEOUT_MS)))
+ return FAILED;
+ spin_lock_irq(target->scsi_host->host_lock);
+
+ if (req->cmd_done) {
+ list_del(&req->list);
+ req->next = target->req_head;
+ target->req_head = req_index;
+
+ scmnd->scsi_done(scmnd);
+ } else if (!req->tsk_status) {
+ scmnd->result = DID_ABORT << 16;
+ ret = SUCCESS;
+ }
+
+out:
+ spin_unlock_irq(target->scsi_host->host_lock);
+ return ret;
+}
+
+static int srp_abort(struct scsi_cmnd *scmnd)
+{
+ printk(KERN_ERR "SRP abort called\n");
+
+ return srp_send_tsk_mgmt(scmnd, SRP_TSK_ABORT_TASK);
+}
+
+static int srp_reset_device(struct scsi_cmnd *scmnd)
+{
+ printk(KERN_ERR "SRP reset_device called\n");
+
+ return srp_send_tsk_mgmt(scmnd, SRP_TSK_LUN_RESET);
+}
+
+static int srp_reset_host(struct scsi_cmnd *scmnd)
+{
+ struct srp_target_port *target = host_to_target(scmnd->device->host);
+ int ret = FAILED;
+
+ printk(KERN_ERR PFX "SRP reset_host called\n");
+
+ if (!srp_reconnect_target(target))
+ ret = SUCCESS;
+
+ return ret;
+}
+
+static struct scsi_host_template srp_template = {
+ .module = THIS_MODULE,
+ .name = DRV_NAME,
+ .info = srp_target_info,
+ .queuecommand = srp_queuecommand,
+ .eh_abort_handler = srp_abort,
+ .eh_device_reset_handler = srp_reset_device,
+ .eh_host_reset_handler = srp_reset_host,
+ .can_queue = SRP_SQ_SIZE,
+ .this_id = -1,
+ .sg_tablesize = SRP_MAX_INDIRECT,
+ .cmd_per_lun = SRP_SQ_SIZE,
+ .use_clustering = ENABLE_CLUSTERING
+};
+
+static int srp_add_target(struct srp_host *host, struct srp_target_port *target)
+{
+ sprintf(target->target_name, "SRP.T10:%016llX",
+ (unsigned long long) be64_to_cpu(target->id_ext));
+
+ if (scsi_add_host(target->scsi_host, host->dev->dma_device))
+ return -ENODEV;
+
+ down(&host->target_mutex);
+ list_add_tail(&target->list, &host->target_list);
+ up(&host->target_mutex);
+
+ target->state = SRP_TARGET_LIVE;
+
+ /* XXX: are we supposed to have a definition of SCAN_WILD_CARD ?? */
+ scsi_scan_target(&target->scsi_host->shost_gendev,
+ 0, target->scsi_id, ~0, 0);
+
+ return 0;
+}
+
+static void srp_release_class_dev(struct class_device *class_dev)
+{
+ struct srp_host *host =
+ container_of(class_dev, struct srp_host, class_dev);
+
+ complete(&host->released);
+}
+
+static struct class srp_class = {
+ .name = "infiniband_srp",
+ .release = srp_release_class_dev
+};
+
+/*
+ * Target ports are added by writing
+ *
+ * id_ext=<SRP ID ext>,ioc_guid=<SRP IOC GUID>,dgid=<dest GID>,
+ * pkey=<P_Key>,service_id=<service ID>
+ *
+ * to the add_target sysfs attribute.
+ */
+enum {
+ SRP_OPT_ERR = 0,
+ SRP_OPT_ID_EXT = 1 << 0,
+ SRP_OPT_IOC_GUID = 1 << 1,
+ SRP_OPT_DGID = 1 << 2,
+ SRP_OPT_PKEY = 1 << 3,
+ SRP_OPT_SERVICE_ID = 1 << 4,
+ SRP_OPT_MAX_SECT = 1 << 5,
+ SRP_OPT_ALL = (SRP_OPT_ID_EXT |
+ SRP_OPT_IOC_GUID |
+ SRP_OPT_DGID |
+ SRP_OPT_PKEY |
+ SRP_OPT_SERVICE_ID),
+};
+
+static match_table_t srp_opt_tokens = {
+ { SRP_OPT_ID_EXT, "id_ext=%s" },
+ { SRP_OPT_IOC_GUID, "ioc_guid=%s" },
+ { SRP_OPT_DGID, "dgid=%s" },
+ { SRP_OPT_PKEY, "pkey=%x" },
+ { SRP_OPT_SERVICE_ID, "service_id=%s" },
+ { SRP_OPT_MAX_SECT, "max_sect=%d" },
+ { SRP_OPT_ERR, NULL }
+};
+
+static int srp_parse_options(const char *buf, struct srp_target_port *target)
+{
+ char *options, *sep_opt;
+ char *p;
+ char dgid[3];
+ substring_t args[MAX_OPT_ARGS];
+ int opt_mask = 0;
+ int token;
+ int ret = -EINVAL;
+ int i;
+
+ options = kstrdup(buf, GFP_KERNEL);
+ if (!options)
+ return -ENOMEM;
+
+ sep_opt = options;
+ while ((p = strsep(&sep_opt, ",")) != NULL) {
+ if (!*p)
+ continue;
+
+ token = match_token(p, srp_opt_tokens, args);
+ opt_mask |= token;
+
+ switch (token) {
+ case SRP_OPT_ID_EXT:
+ p = match_strdup(args);
+ target->id_ext = cpu_to_be64(simple_strtoull(p, NULL, 16));
+ kfree(p);
+ break;
+
+ case SRP_OPT_IOC_GUID:
+ p = match_strdup(args);
+ target->ioc_guid = cpu_to_be64(simple_strtoull(p, NULL, 16));
+ kfree(p);
+ break;
+
+ case SRP_OPT_DGID:
+ p = match_strdup(args);
+ if (strlen(p) != 32) {
+ printk(KERN_WARNING PFX "bad dest GID parameter '%s'\n", p);
+ goto out;
+ }
+
+ for (i = 0; i < 16; ++i) {
+ strlcpy(dgid, p + i * 2, 3);
+ target->path.dgid.raw[i] = simple_strtoul(dgid, NULL, 16);
+ }
+ break;
+
+ case SRP_OPT_PKEY:
+ if (match_hex(args, &token)) {
+ printk(KERN_WARNING PFX "bad P_Key parameter '%s'\n", p);
+ goto out;
+ }
+ target->path.pkey = cpu_to_be16(token);
+ break;
+
+ case SRP_OPT_SERVICE_ID:
+ p = match_strdup(args);
+ target->service_id = cpu_to_be64(simple_strtoull(p, NULL, 16));
+ kfree(p);
+ break;
+
+ case SRP_OPT_MAX_SECT:
+ if (match_int(args, &token)) {
+ printk(KERN_WARNING PFX "bad max sect parameter '%s'\n", p);
+ goto out;
+ }
+ target->scsi_host->max_sectors = token;
+ break;
+
+ default:
+ printk(KERN_WARNING PFX "unknown parameter or missing value "
+ "'%s' in target creation request\n", p);
+ goto out;
+ }
+ }
+
+ if ((opt_mask & SRP_OPT_ALL) == SRP_OPT_ALL)
+ ret = 0;
+ else
+ for (i = 0; i < ARRAY_SIZE(srp_opt_tokens); ++i)
+ if ((srp_opt_tokens[i].token & SRP_OPT_ALL) &&
+ !(srp_opt_tokens[i].token & opt_mask))
+ printk(KERN_WARNING PFX "target creation request is "
+ "missing parameter '%s'\n",
+ srp_opt_tokens[i].pattern);
+
+out:
+ kfree(options);
+ return ret;
+}
+
+static ssize_t srp_create_target(struct class_device *class_dev,
+ const char *buf, size_t count)
+{
+ struct srp_host *host =
+ container_of(class_dev, struct srp_host, class_dev);
+ struct Scsi_Host *target_host;
+ struct srp_target_port *target;
+ int ret;
+ int i;
+
+ target_host = scsi_host_alloc(&srp_template,
+ sizeof (struct srp_target_port));
+ if (!target_host)
+ return -ENOMEM;
+
+ target = host_to_target(target_host);
+ memset(target, 0, sizeof *target);
+
+ target->scsi_host = target_host;
+ target->srp_host = host;
+
+ INIT_WORK(&target->work, srp_reconnect_work, target);
+
+ for (i = 0; i < SRP_SQ_SIZE - 1; ++i)
+ target->req_ring[i].next = i + 1;
+ target->req_ring[SRP_SQ_SIZE - 1].next = -1;
+ INIT_LIST_HEAD(&target->req_queue);
+
+ ret = srp_parse_options(buf, target);
+ if (ret)
+ goto err;
+
+ ib_get_cached_gid(host->dev, host->port, 0, &target->path.sgid);
+
+ printk(KERN_DEBUG PFX "new target: id_ext %016llx ioc_guid %016llx pkey %04x "
+ "service_id %016llx dgid %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n",
+ (unsigned long long) be64_to_cpu(target->id_ext),
+ (unsigned long long) be64_to_cpu(target->ioc_guid),
+ be16_to_cpu(target->path.pkey),
+ (unsigned long long) be64_to_cpu(target->service_id),
+ (int) be16_to_cpu(*(__be16 *) &target->path.dgid.raw[0]),
+ (int) be16_to_cpu(*(__be16 *) &target->path.dgid.raw[2]),
+ (int) be16_to_cpu(*(__be16 *) &target->path.dgid.raw[4]),
+ (int) be16_to_cpu(*(__be16 *) &target->path.dgid.raw[6]),
+ (int) be16_to_cpu(*(__be16 *) &target->path.dgid.raw[8]),
+ (int) be16_to_cpu(*(__be16 *) &target->path.dgid.raw[10]),
+ (int) be16_to_cpu(*(__be16 *) &target->path.dgid.raw[12]),
+ (int) be16_to_cpu(*(__be16 *) &target->path.dgid.raw[14]));
+
+ ret = srp_create_target_ib(target);
+ if (ret)
+ goto err;
+
+ target->cm_id = ib_create_cm_id(host->dev, srp_cm_handler, target);
+ if (IS_ERR(target->cm_id)) {
+ ret = PTR_ERR(target->cm_id);
+ goto err_free;
+ }
+
+ ret = srp_connect_target(target);
+ if (ret) {
+ printk(KERN_ERR PFX "Connection failed\n");
+ goto err_cm_id;
+ }
+
+ ret = srp_add_target(host, target);
+ if (ret)
+ goto err_disconnect;
+
+ return count;
+
+err_disconnect:
+ srp_disconnect_target(target);
+
+err_cm_id:
+ ib_destroy_cm_id(target->cm_id);
+
+err_free:
+ srp_free_target_ib(target);
+
+err:
+ scsi_host_put(target_host);
+
+ return ret;
+}
+
+static CLASS_DEVICE_ATTR(add_target, S_IWUSR, NULL, srp_create_target);
+
+static ssize_t show_ibdev(struct class_device *class_dev, char *buf)
+{
+ struct srp_host *host =
+ container_of(class_dev, struct srp_host, class_dev);
+
+ return sprintf(buf, "%s\n", host->dev->name);
+}
+
+static CLASS_DEVICE_ATTR(ibdev, S_IRUGO, show_ibdev, NULL);
+
+static ssize_t show_port(struct class_device *class_dev, char *buf)
+{
+ struct srp_host *host =
+ container_of(class_dev, struct srp_host, class_dev);
+
+ return sprintf(buf, "%d\n", host->port);
+}
+
+static CLASS_DEVICE_ATTR(port, S_IRUGO, show_port, NULL);
+
+static struct srp_host *srp_add_port(struct ib_device *device,
+ __be64 node_guid, u8 port)
+{
+ struct srp_host *host;
+
+ host = kzalloc(sizeof *host, GFP_KERNEL);
+ if (!host)
+ return NULL;
+
+ INIT_LIST_HEAD(&host->target_list);
+ init_MUTEX(&host->target_mutex);
+ init_completion(&host->released);
+ host->dev = device;
+ host->port = port;
+
+ host->initiator_port_id[7] = port;
+ memcpy(host->initiator_port_id + 8, &node_guid, 8);
+
+ host->pd = ib_alloc_pd(device);
+ if (IS_ERR(host->pd))
+ goto err_free;
+
+ host->mr = ib_get_dma_mr(host->pd,
+ IB_ACCESS_LOCAL_WRITE |
+ IB_ACCESS_REMOTE_READ |
+ IB_ACCESS_REMOTE_WRITE);
+ if (IS_ERR(host->mr))
+ goto err_pd;
+
+ host->class_dev.class = &srp_class;
+ host->class_dev.dev = device->dma_device;
+ snprintf(host->class_dev.class_id, BUS_ID_SIZE, "srp-%s-%d",
+ device->name, port);
+
+ if (class_device_register(&host->class_dev))
+ goto err_mr;
+ if (class_device_create_file(&host->class_dev, &class_device_attr_add_target))
+ goto err_class;
+ if (class_device_create_file(&host->class_dev, &class_device_attr_ibdev))
+ goto err_class;
+ if (class_device_create_file(&host->class_dev, &class_device_attr_port))
+ goto err_class;
+
+ return host;
+
+err_class:
+ class_device_unregister(&host->class_dev);
+
+err_mr:
+ ib_dereg_mr(host->mr);
+
+err_pd:
+ ib_dealloc_pd(host->pd);
+
+err_free:
+ kfree(host);
+
+ return NULL;
+}
+
+static void srp_add_one(struct ib_device *device)
+{
+ struct list_head *dev_list;
+ struct srp_host *host;
+ struct ib_device_attr *dev_attr;
+ int s, e, p;
+
+ dev_attr = kmalloc(sizeof *dev_attr, GFP_KERNEL);
+ if (!dev_attr)
+ return;
+
+ if (ib_query_device(device, dev_attr)) {
+ printk(KERN_WARNING PFX "Couldn't query node GUID for %s.\n",
+ device->name);
+ goto out;
+ }
+
+ dev_list = kmalloc(sizeof *dev_list, GFP_KERNEL);
+ if (!dev_list)
+ goto out;
+
+ INIT_LIST_HEAD(dev_list);
+
+ if (device->node_type == IB_NODE_SWITCH) {
+ s = 0;
+ e = 0;
+ } else {
+ s = 1;
+ e = device->phys_port_cnt;
+ }
+
+ for (p = s; p <= e; ++p) {
+ host = srp_add_port(device, dev_attr->node_guid, p);
+ if (host)
+ list_add_tail(&host->list, dev_list);
+ }
+
+ ib_set_client_data(device, &srp_client, dev_list);
+
+out:
+ kfree(dev_attr);
+}
+
+static void srp_remove_one(struct ib_device *device)
+{
+ struct list_head *dev_list;
+ struct srp_host *host, *tmp_host;
+ LIST_HEAD(target_list);
+ struct srp_target_port *target, *tmp_target;
+ unsigned long flags;
+
+ dev_list = ib_get_client_data(device, &srp_client);
+
+ list_for_each_entry_safe(host, tmp_host, dev_list, list) {
+ class_device_unregister(&host->class_dev);
+ /*
+ * Wait for the sysfs entry to go away, so that no new
+ * target ports can be created.
+ */
+ wait_for_completion(&host->released);
+
+ /*
+ * Mark all target ports as removed, so we stop queueing
+ * commands and don't try to reconnect.
+ */
+ down(&host->target_mutex);
+ list_for_each_entry_safe(target, tmp_target,
+ &host->target_list, list) {
+ spin_lock_irqsave(target->scsi_host->host_lock, flags);
+ if (target->state != SRP_TARGET_REMOVED)
+ target->state = SRP_TARGET_REMOVED;
+ spin_unlock_irqrestore(target->scsi_host->host_lock, flags);
+ }
+ up(&host->target_mutex);
+
+ /*
+ * Wait for any reconnection tasks that may have
+ * started before we marked our target ports as
+ * removed, and any target port removal tasks.
+ */
+ flush_scheduled_work();
+
+ list_for_each_entry_safe(target, tmp_target,
+ &host->target_list, list) {
+ scsi_remove_host(target->scsi_host);
+ srp_disconnect_target(target);
+ ib_destroy_cm_id(target->cm_id);
+ srp_free_target_ib(target);
+ scsi_host_put(target->scsi_host);
+ }
+
+ ib_dereg_mr(host->mr);
+ ib_dealloc_pd(host->pd);
+ kfree(host);
+ }
+
+ kfree(dev_list);
+}
+
+static int __init srp_init_module(void)
+{
+ int ret;
+
+ ret = class_register(&srp_class);
+ if (ret) {
+ printk(KERN_ERR PFX "couldn't register class infiniband_srp\n");
+ return ret;
+ }
+
+ ret = ib_register_client(&srp_client);
+ if (ret) {
+ printk(KERN_ERR PFX "couldn't register IB client\n");
+ class_unregister(&srp_class);
+ return ret;
+ }
+
+ return 0;
+}
+
+static void __exit srp_cleanup_module(void)
+{
+ ib_unregister_client(&srp_client);
+ class_unregister(&srp_class);
+}
+
+module_init(srp_init_module);
+module_exit(srp_cleanup_module);
diff --git a/drivers/infiniband/ulp/srp/ib_srp.h b/drivers/infiniband/ulp/srp/ib_srp.h
new file mode 100644
index 000000000000..4fec28a71367
--- /dev/null
+++ b/drivers/infiniband/ulp/srp/ib_srp.h
@@ -0,0 +1,150 @@
+/*
+ * Copyright (c) 2005 Cisco Systems. All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses. You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * - Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * 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.
+ *
+ * $Id: ib_srp.h 3932 2005-11-01 17:19:29Z roland $
+ */
+
+#ifndef IB_SRP_H
+#define IB_SRP_H
+
+#include <linux/types.h>
+#include <linux/list.h>
+
+#include <asm/semaphore.h>
+
+#include <scsi/scsi_host.h>
+#include <scsi/scsi_cmnd.h>
+
+#include <rdma/ib_verbs.h>
+#include <rdma/ib_sa.h>
+#include <rdma/ib_cm.h>
+
+enum {
+ SRP_PATH_REC_TIMEOUT_MS = 1000,
+ SRP_ABORT_TIMEOUT_MS = 5000,
+
+ SRP_PORT_REDIRECT = 1,
+ SRP_DLID_REDIRECT = 2,
+
+ SRP_MAX_IU_LEN = 256,
+
+ SRP_RQ_SHIFT = 6,
+ SRP_RQ_SIZE = 1 << SRP_RQ_SHIFT,
+ SRP_SQ_SIZE = SRP_RQ_SIZE - 1,
+ SRP_CQ_SIZE = SRP_SQ_SIZE + SRP_RQ_SIZE,
+
+ SRP_TAG_TSK_MGMT = 1 << (SRP_RQ_SHIFT + 1)
+};
+
+#define SRP_OP_RECV (1 << 31)
+#define SRP_MAX_INDIRECT ((SRP_MAX_IU_LEN - \
+ sizeof (struct srp_cmd) - \
+ sizeof (struct srp_indirect_buf)) / 16)
+
+enum srp_target_state {
+ SRP_TARGET_LIVE,
+ SRP_TARGET_CONNECTING,
+ SRP_TARGET_DEAD,
+ SRP_TARGET_REMOVED
+};
+
+struct srp_host {
+ u8 initiator_port_id[16];
+ struct ib_device *dev;
+ u8 port;
+ struct ib_pd *pd;
+ struct ib_mr *mr;
+ struct class_device class_dev;
+ struct list_head target_list;
+ struct semaphore target_mutex;
+ struct completion released;
+ struct list_head list;
+};
+
+struct srp_request {
+ struct list_head list;
+ struct scsi_cmnd *scmnd;
+ struct srp_iu *cmd;
+ struct srp_iu *tsk_mgmt;
+ DECLARE_PCI_UNMAP_ADDR(direct_mapping)
+ struct completion done;
+ short next;
+ u8 cmd_done;
+ u8 tsk_status;
+};
+
+struct srp_target_port {
+ __be64 id_ext;
+ __be64 ioc_guid;
+ __be64 service_id;
+ struct srp_host *srp_host;
+ struct Scsi_Host *scsi_host;
+ char target_name[32];
+ unsigned int scsi_id;
+
+ struct ib_sa_path_rec path;
+ struct ib_sa_query *path_query;
+ int path_query_id;
+
+ struct ib_cm_id *cm_id;
+ struct ib_cq *cq;
+ struct ib_qp *qp;
+
+ int max_ti_iu_len;
+ s32 req_lim;
+
+ unsigned rx_head;
+ struct srp_iu *rx_ring[SRP_RQ_SIZE];
+
+ unsigned tx_head;
+ unsigned tx_tail;
+ struct srp_iu *tx_ring[SRP_SQ_SIZE + 1];
+
+ int req_head;
+ struct list_head req_queue;
+ struct srp_request req_ring[SRP_SQ_SIZE];
+
+ struct work_struct work;
+
+ struct list_head list;
+ struct completion done;
+ int status;
+ enum srp_target_state state;
+};
+
+struct srp_iu {
+ dma_addr_t dma;
+ void *buf;
+ size_t size;
+ enum dma_data_direction direction;
+};
+
+#endif /* IB_SRP_H */
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c
index 3738d173f9a6..9f2352bd8348 100644
--- a/drivers/input/evdev.c
+++ b/drivers/input/evdev.c
@@ -20,7 +20,6 @@
#include <linux/major.h>
#include <linux/smp_lock.h>
#include <linux/device.h>
-#include <linux/devfs_fs_kernel.h>
#include <linux/compat.h>
struct evdev {
@@ -566,6 +565,7 @@ static long evdev_ioctl_compat(struct file *file, unsigned int cmd, unsigned lon
case EV_LED: bits = dev->ledbit; max = LED_MAX; break;
case EV_SND: bits = dev->sndbit; max = SND_MAX; break;
case EV_FF: bits = dev->ffbit; max = FF_MAX; break;
+ case EV_SW: bits = dev->swbit; max = SW_MAX; break;
default: return -EINVAL;
}
bit_to_user(bits, max);
@@ -580,6 +580,9 @@ static long evdev_ioctl_compat(struct file *file, unsigned int cmd, unsigned lon
if (_IOC_NR(cmd) == _IOC_NR(EVIOCGSND(0)))
bit_to_user(dev->snd, SND_MAX);
+ if (_IOC_NR(cmd) == _IOC_NR(EVIOCGSW(0)))
+ bit_to_user(dev->sw, SW_MAX);
+
if (_IOC_NR(cmd) == _IOC_NR(EVIOCGNAME(0))) {
int len;
if (!dev->name) return -ENOENT;
@@ -662,6 +665,7 @@ static struct file_operations evdev_fops = {
static struct input_handle *evdev_connect(struct input_handler *handler, struct input_dev *dev, struct input_device_id *id)
{
struct evdev *evdev;
+ struct class_device *cdev;
int minor;
for (minor = 0; minor < EVDEV_MINORS && evdev_table[minor]; minor++);
@@ -687,11 +691,13 @@ static struct input_handle *evdev_connect(struct input_handler *handler, struct
evdev_table[minor] = evdev;
- devfs_mk_cdev(MKDEV(INPUT_MAJOR, EVDEV_MINOR_BASE + minor),
- S_IFCHR|S_IRUGO|S_IWUSR, "input/event%d", minor);
- class_device_create(input_class,
+ cdev = class_device_create(&input_class, &dev->cdev,
MKDEV(INPUT_MAJOR, EVDEV_MINOR_BASE + minor),
- dev->dev, "event%d", minor);
+ dev->cdev.dev, evdev->name);
+
+ /* temporary symlink to keep userspace happy */
+ sysfs_create_link(&input_class.subsys.kset.kobj, &cdev->kobj,
+ evdev->name);
return &evdev->handle;
}
@@ -701,9 +707,9 @@ static void evdev_disconnect(struct input_handle *handle)
struct evdev *evdev = handle->private;
struct evdev_list *list;
- class_device_destroy(input_class,
+ sysfs_remove_link(&input_class.subsys.kset.kobj, evdev->name);
+ class_device_destroy(&input_class,
MKDEV(INPUT_MAJOR, EVDEV_MINOR_BASE + evdev->minor));
- devfs_remove("input/event%d", evdev->minor);
evdev->exist = 0;
if (evdev->open) {
diff --git a/drivers/input/gameport/gameport.c b/drivers/input/gameport/gameport.c
index ab09cf4093e3..0506934244f0 100644
--- a/drivers/input/gameport/gameport.c
+++ b/drivers/input/gameport/gameport.c
@@ -21,6 +21,7 @@
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/kthread.h>
+#include <linux/sched.h> /* HZ */
/*#include <asm/io.h>*/
diff --git a/drivers/input/input.c b/drivers/input/input.c
index 14ae5583e198..c8ae2bb054e0 100644
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -22,12 +22,12 @@
#include <linux/interrupt.h>
#include <linux/poll.h>
#include <linux/device.h>
-#include <linux/devfs_fs_kernel.h>
MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>");
MODULE_DESCRIPTION("Input core");
MODULE_LICENSE("GPL");
+EXPORT_SYMBOL(input_allocate_device);
EXPORT_SYMBOL(input_register_device);
EXPORT_SYMBOL(input_unregister_device);
EXPORT_SYMBOL(input_register_handler);
@@ -39,7 +39,7 @@ EXPORT_SYMBOL(input_close_device);
EXPORT_SYMBOL(input_accept_process);
EXPORT_SYMBOL(input_flush_device);
EXPORT_SYMBOL(input_event);
-EXPORT_SYMBOL(input_class);
+EXPORT_SYMBOL_GPL(input_class);
#define INPUT_DEVICES 256
@@ -316,124 +316,21 @@ static struct input_device_id *input_match_device(struct input_device_id *id, st
return NULL;
}
-
-/*
- * Input hotplugging interface - loading event handlers based on
- * device bitfields.
- */
-
-#ifdef CONFIG_HOTPLUG
-
-/*
- * Input hotplugging invokes what /proc/sys/kernel/hotplug says
- * (normally /sbin/hotplug) when input devices get added or removed.
- *
- * This invokes a user mode policy agent, typically helping to load driver
- * or other modules, configure the device, and more. Drivers can provide
- * a MODULE_DEVICE_TABLE to help with module loading subtasks.
- *
- */
-
-#define SPRINTF_BIT_A(bit, name, max) \
- do { \
- envp[i++] = scratch; \
- scratch += sprintf(scratch, name); \
- for (j = NBITS(max) - 1; j >= 0; j--) \
- if (dev->bit[j]) break; \
- for (; j >= 0; j--) \
- scratch += sprintf(scratch, "%lx ", dev->bit[j]); \
- scratch++; \
- } while (0)
-
-#define SPRINTF_BIT_A2(bit, name, max, ev) \
- do { \
- if (test_bit(ev, dev->evbit)) \
- SPRINTF_BIT_A(bit, name, max); \
- } while (0)
-
-static void input_call_hotplug(char *verb, struct input_dev *dev)
+static int input_print_bitmap(char *buf, int buf_size, unsigned long *bitmap, int max)
{
- char *argv[3], **envp, *buf, *scratch;
- int i = 0, j, value;
-
- if (!hotplug_path[0]) {
- printk(KERN_ERR "input.c: calling hotplug without a hotplug agent defined\n");
- return;
- }
- if (in_interrupt()) {
- printk(KERN_ERR "input.c: calling hotplug from interrupt\n");
- return;
- }
- if (!current->fs->root) {
- printk(KERN_WARNING "input.c: calling hotplug without valid filesystem\n");
- return;
- }
- if (!(envp = (char **) kmalloc(20 * sizeof(char *), GFP_KERNEL))) {
- printk(KERN_ERR "input.c: not enough memory allocating hotplug environment\n");
- return;
- }
- if (!(buf = kmalloc(1024, GFP_KERNEL))) {
- kfree (envp);
- printk(KERN_ERR "input.c: not enough memory allocating hotplug environment\n");
- return;
- }
-
- argv[0] = hotplug_path;
- argv[1] = "input";
- argv[2] = NULL;
-
- envp[i++] = "HOME=/";
- envp[i++] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
-
- scratch = buf;
-
- envp[i++] = scratch;
- scratch += sprintf(scratch, "ACTION=%s", verb) + 1;
-
- envp[i++] = scratch;
- scratch += sprintf(scratch, "PRODUCT=%x/%x/%x/%x",
- dev->id.bustype, dev->id.vendor, dev->id.product, dev->id.version) + 1;
-
- if (dev->name) {
- envp[i++] = scratch;
- scratch += sprintf(scratch, "NAME=%s", dev->name) + 1;
- }
-
- if (dev->phys) {
- envp[i++] = scratch;
- scratch += sprintf(scratch, "PHYS=%s", dev->phys) + 1;
- }
-
- SPRINTF_BIT_A(evbit, "EV=", EV_MAX);
- SPRINTF_BIT_A2(keybit, "KEY=", KEY_MAX, EV_KEY);
- SPRINTF_BIT_A2(relbit, "REL=", REL_MAX, EV_REL);
- SPRINTF_BIT_A2(absbit, "ABS=", ABS_MAX, EV_ABS);
- SPRINTF_BIT_A2(mscbit, "MSC=", MSC_MAX, EV_MSC);
- SPRINTF_BIT_A2(ledbit, "LED=", LED_MAX, EV_LED);
- SPRINTF_BIT_A2(sndbit, "SND=", SND_MAX, EV_SND);
- SPRINTF_BIT_A2(ffbit, "FF=", FF_MAX, EV_FF);
- SPRINTF_BIT_A2(swbit, "SW=", SW_MAX, EV_SW);
-
- envp[i++] = NULL;
-
-#ifdef INPUT_DEBUG
- printk(KERN_DEBUG "input.c: calling %s %s [%s %s %s %s %s]\n",
- argv[0], argv[1], envp[0], envp[1], envp[2], envp[3], envp[4]);
-#endif
-
- value = call_usermodehelper(argv [0], argv, envp, 0);
+ int i;
+ int len = 0;
- kfree(buf);
- kfree(envp);
+ for (i = NBITS(max) - 1; i > 0; i--)
+ if (bitmap[i])
+ break;
-#ifdef INPUT_DEBUG
- if (value != 0)
- printk(KERN_DEBUG "input.c: hotplug returned %d\n", value);
-#endif
+ for (; i >= 0; i--)
+ len += snprintf(buf + len, max(buf_size - len, 0),
+ "%lx%s", bitmap[i], i > 0 ? " " : "");
+ return len;
}
-#endif
-
#ifdef CONFIG_PROC_FS
static struct proc_dir_entry *proc_bus_input_dir;
@@ -455,37 +352,39 @@ static unsigned int input_devices_poll(struct file *file, poll_table *wait)
return 0;
}
-#define SPRINTF_BIT_B(bit, name, max) \
- do { \
- len += sprintf(buf + len, "B: %s", name); \
- for (i = NBITS(max) - 1; i >= 0; i--) \
- if (dev->bit[i]) break; \
- for (; i >= 0; i--) \
- len += sprintf(buf + len, "%lx ", dev->bit[i]); \
- len += sprintf(buf + len, "\n"); \
+#define SPRINTF_BIT(ev, bm) \
+ do { \
+ len += sprintf(buf + len, "B: %s=", #ev); \
+ len += input_print_bitmap(buf + len, INT_MAX, \
+ dev->bm##bit, ev##_MAX); \
+ len += sprintf(buf + len, "\n"); \
} while (0)
-#define SPRINTF_BIT_B2(bit, name, max, ev) \
- do { \
- if (test_bit(ev, dev->evbit)) \
- SPRINTF_BIT_B(bit, name, max); \
+#define TEST_AND_SPRINTF_BIT(ev, bm) \
+ do { \
+ if (test_bit(EV_##ev, dev->evbit)) \
+ SPRINTF_BIT(ev, bm); \
} while (0)
static int input_devices_read(char *buf, char **start, off_t pos, int count, int *eof, void *data)
{
struct input_dev *dev;
struct input_handle *handle;
+ const char *path;
off_t at = 0;
- int i, len, cnt = 0;
+ int len, cnt = 0;
list_for_each_entry(dev, &input_dev_list, node) {
+ path = kobject_get_path(&dev->cdev.kobj, GFP_KERNEL);
+
len = sprintf(buf, "I: Bus=%04x Vendor=%04x Product=%04x Version=%04x\n",
dev->id.bustype, dev->id.vendor, dev->id.product, dev->id.version);
len += sprintf(buf + len, "N: Name=\"%s\"\n", dev->name ? dev->name : "");
len += sprintf(buf + len, "P: Phys=%s\n", dev->phys ? dev->phys : "");
+ len += sprintf(buf + len, "S: Sysfs=%s\n", path ? path : "");
len += sprintf(buf + len, "H: Handlers=");
list_for_each_entry(handle, &dev->h_list, d_node)
@@ -493,15 +392,15 @@ static int input_devices_read(char *buf, char **start, off_t pos, int count, int
len += sprintf(buf + len, "\n");
- SPRINTF_BIT_B(evbit, "EV=", EV_MAX);
- SPRINTF_BIT_B2(keybit, "KEY=", KEY_MAX, EV_KEY);
- SPRINTF_BIT_B2(relbit, "REL=", REL_MAX, EV_REL);
- SPRINTF_BIT_B2(absbit, "ABS=", ABS_MAX, EV_ABS);
- SPRINTF_BIT_B2(mscbit, "MSC=", MSC_MAX, EV_MSC);
- SPRINTF_BIT_B2(ledbit, "LED=", LED_MAX, EV_LED);
- SPRINTF_BIT_B2(sndbit, "SND=", SND_MAX, EV_SND);
- SPRINTF_BIT_B2(ffbit, "FF=", FF_MAX, EV_FF);
- SPRINTF_BIT_B2(swbit, "SW=", SW_MAX, EV_SW);
+ SPRINTF_BIT(EV, ev);
+ TEST_AND_SPRINTF_BIT(KEY, key);
+ TEST_AND_SPRINTF_BIT(REL, rel);
+ TEST_AND_SPRINTF_BIT(ABS, abs);
+ TEST_AND_SPRINTF_BIT(MSC, msc);
+ TEST_AND_SPRINTF_BIT(LED, led);
+ TEST_AND_SPRINTF_BIT(SND, snd);
+ TEST_AND_SPRINTF_BIT(FF, ff);
+ TEST_AND_SPRINTF_BIT(SW, sw);
len += sprintf(buf + len, "\n");
@@ -516,6 +415,8 @@ static int input_devices_read(char *buf, char **start, off_t pos, int count, int
if (cnt >= count)
break;
}
+
+ kfree(path);
}
if (&dev->node == &input_dev_list)
@@ -606,15 +507,255 @@ static inline int input_proc_init(void) { return 0; }
static inline void input_proc_exit(void) { }
#endif
-void input_register_device(struct input_dev *dev)
+#define INPUT_DEV_STRING_ATTR_SHOW(name) \
+static ssize_t input_dev_show_##name(struct class_device *dev, char *buf) \
+{ \
+ struct input_dev *input_dev = to_input_dev(dev); \
+ int retval; \
+ \
+ retval = down_interruptible(&input_dev->sem); \
+ if (retval) \
+ return retval; \
+ \
+ retval = sprintf(buf, "%s\n", input_dev->name ? input_dev->name : ""); \
+ \
+ up(&input_dev->sem); \
+ \
+ return retval; \
+} \
+static CLASS_DEVICE_ATTR(name, S_IRUGO, input_dev_show_##name, NULL);
+
+INPUT_DEV_STRING_ATTR_SHOW(name);
+INPUT_DEV_STRING_ATTR_SHOW(phys);
+INPUT_DEV_STRING_ATTR_SHOW(uniq);
+
+static struct attribute *input_dev_attrs[] = {
+ &class_device_attr_name.attr,
+ &class_device_attr_phys.attr,
+ &class_device_attr_uniq.attr,
+ NULL
+};
+
+static struct attribute_group input_dev_group = {
+ .attrs = input_dev_attrs,
+};
+
+#define INPUT_DEV_ID_ATTR(name) \
+static ssize_t input_dev_show_id_##name(struct class_device *dev, char *buf) \
+{ \
+ struct input_dev *input_dev = to_input_dev(dev); \
+ return sprintf(buf, "%04x\n", input_dev->id.name); \
+} \
+static CLASS_DEVICE_ATTR(name, S_IRUGO, input_dev_show_id_##name, NULL);
+
+INPUT_DEV_ID_ATTR(bustype);
+INPUT_DEV_ID_ATTR(vendor);
+INPUT_DEV_ID_ATTR(product);
+INPUT_DEV_ID_ATTR(version);
+
+static struct attribute *input_dev_id_attrs[] = {
+ &class_device_attr_bustype.attr,
+ &class_device_attr_vendor.attr,
+ &class_device_attr_product.attr,
+ &class_device_attr_version.attr,
+ NULL
+};
+
+static struct attribute_group input_dev_id_attr_group = {
+ .name = "id",
+ .attrs = input_dev_id_attrs,
+};
+
+#define INPUT_DEV_CAP_ATTR(ev, bm) \
+static ssize_t input_dev_show_cap_##bm(struct class_device *dev, char *buf) \
+{ \
+ struct input_dev *input_dev = to_input_dev(dev); \
+ return input_print_bitmap(buf, PAGE_SIZE, input_dev->bm##bit, ev##_MAX);\
+} \
+static CLASS_DEVICE_ATTR(bm, S_IRUGO, input_dev_show_cap_##bm, NULL);
+
+INPUT_DEV_CAP_ATTR(EV, ev);
+INPUT_DEV_CAP_ATTR(KEY, key);
+INPUT_DEV_CAP_ATTR(REL, rel);
+INPUT_DEV_CAP_ATTR(ABS, abs);
+INPUT_DEV_CAP_ATTR(MSC, msc);
+INPUT_DEV_CAP_ATTR(LED, led);
+INPUT_DEV_CAP_ATTR(SND, snd);
+INPUT_DEV_CAP_ATTR(FF, ff);
+INPUT_DEV_CAP_ATTR(SW, sw);
+
+static struct attribute *input_dev_caps_attrs[] = {
+ &class_device_attr_ev.attr,
+ &class_device_attr_key.attr,
+ &class_device_attr_rel.attr,
+ &class_device_attr_abs.attr,
+ &class_device_attr_msc.attr,
+ &class_device_attr_led.attr,
+ &class_device_attr_snd.attr,
+ &class_device_attr_ff.attr,
+ &class_device_attr_sw.attr,
+ NULL
+};
+
+static struct attribute_group input_dev_caps_attr_group = {
+ .name = "capabilities",
+ .attrs = input_dev_caps_attrs,
+};
+
+static void input_dev_release(struct class_device *class_dev)
+{
+ struct input_dev *dev = to_input_dev(class_dev);
+
+ kfree(dev);
+ module_put(THIS_MODULE);
+}
+
+/*
+ * Input hotplugging interface - loading event handlers based on
+ * device bitfields.
+ */
+static int input_add_hotplug_bm_var(char **envp, int num_envp, int *cur_index,
+ char *buffer, int buffer_size, int *cur_len,
+ const char *name, unsigned long *bitmap, int max)
+{
+ if (*cur_index >= num_envp - 1)
+ return -ENOMEM;
+
+ envp[*cur_index] = buffer + *cur_len;
+
+ *cur_len += snprintf(buffer + *cur_len, max(buffer_size - *cur_len, 0), name);
+ if (*cur_len > buffer_size)
+ return -ENOMEM;
+
+ *cur_len += input_print_bitmap(buffer + *cur_len,
+ max(buffer_size - *cur_len, 0),
+ bitmap, max) + 1;
+ if (*cur_len > buffer_size)
+ return -ENOMEM;
+
+ (*cur_index)++;
+ return 0;
+}
+
+#define INPUT_ADD_HOTPLUG_VAR(fmt, val...) \
+ do { \
+ int err = add_hotplug_env_var(envp, num_envp, &i, \
+ buffer, buffer_size, &len, \
+ fmt, val); \
+ if (err) \
+ return err; \
+ } while (0)
+
+#define INPUT_ADD_HOTPLUG_BM_VAR(name, bm, max) \
+ do { \
+ int err = input_add_hotplug_bm_var(envp, num_envp, &i, \
+ buffer, buffer_size, &len, \
+ name, bm, max); \
+ if (err) \
+ return err; \
+ } while (0)
+
+static int input_dev_hotplug(struct class_device *cdev, char **envp,
+ int num_envp, char *buffer, int buffer_size)
+{
+ struct input_dev *dev = to_input_dev(cdev);
+ int i = 0;
+ int len = 0;
+
+ INPUT_ADD_HOTPLUG_VAR("PRODUCT=%x/%x/%x/%x",
+ dev->id.bustype, dev->id.vendor,
+ dev->id.product, dev->id.version);
+ if (dev->name)
+ INPUT_ADD_HOTPLUG_VAR("NAME=\"%s\"", dev->name);
+ if (dev->phys)
+ INPUT_ADD_HOTPLUG_VAR("PHYS=\"%s\"", dev->phys);
+ if (dev->uniq)
+ INPUT_ADD_HOTPLUG_VAR("UNIQ=\"%s\"", dev->uniq);
+
+ INPUT_ADD_HOTPLUG_BM_VAR("EV=", dev->evbit, EV_MAX);
+ if (test_bit(EV_KEY, dev->evbit))
+ INPUT_ADD_HOTPLUG_BM_VAR("KEY=", dev->keybit, KEY_MAX);
+ if (test_bit(EV_REL, dev->evbit))
+ INPUT_ADD_HOTPLUG_BM_VAR("REL=", dev->relbit, REL_MAX);
+ if (test_bit(EV_ABS, dev->evbit))
+ INPUT_ADD_HOTPLUG_BM_VAR("ABS=", dev->absbit, ABS_MAX);
+ if (test_bit(EV_MSC, dev->evbit))
+ INPUT_ADD_HOTPLUG_BM_VAR("MSC=", dev->mscbit, MSC_MAX);
+ if (test_bit(EV_LED, dev->evbit))
+ INPUT_ADD_HOTPLUG_BM_VAR("LED=", dev->ledbit, LED_MAX);
+ if (test_bit(EV_SND, dev->evbit))
+ INPUT_ADD_HOTPLUG_BM_VAR("SND=", dev->sndbit, SND_MAX);
+ if (test_bit(EV_FF, dev->evbit))
+ INPUT_ADD_HOTPLUG_BM_VAR("FF=", dev->ffbit, FF_MAX);
+ if (test_bit(EV_SW, dev->evbit))
+ INPUT_ADD_HOTPLUG_BM_VAR("SW=", dev->swbit, SW_MAX);
+
+ envp[i] = NULL;
+
+ return 0;
+}
+
+struct class input_class = {
+ .name = "input",
+ .release = input_dev_release,
+ .hotplug = input_dev_hotplug,
+};
+
+struct input_dev *input_allocate_device(void)
+{
+ struct input_dev *dev;
+
+ dev = kzalloc(sizeof(struct input_dev), GFP_KERNEL);
+ if (dev) {
+ dev->dynalloc = 1;
+ dev->cdev.class = &input_class;
+ class_device_initialize(&dev->cdev);
+ INIT_LIST_HEAD(&dev->h_list);
+ INIT_LIST_HEAD(&dev->node);
+ }
+
+ return dev;
+}
+
+static void input_register_classdevice(struct input_dev *dev)
+{
+ static atomic_t input_no = ATOMIC_INIT(0);
+ const char *path;
+
+ __module_get(THIS_MODULE);
+
+ dev->dev = dev->cdev.dev;
+
+ snprintf(dev->cdev.class_id, sizeof(dev->cdev.class_id),
+ "input%ld", (unsigned long) atomic_inc_return(&input_no) - 1);
+
+ path = kobject_get_path(&dev->cdev.class->subsys.kset.kobj, GFP_KERNEL);
+ printk(KERN_INFO "input: %s as %s/%s\n",
+ dev->name ? dev->name : "Unspecified device",
+ path ? path : "", dev->cdev.class_id);
+ kfree(path);
+
+ class_device_add(&dev->cdev);
+ sysfs_create_group(&dev->cdev.kobj, &input_dev_group);
+ sysfs_create_group(&dev->cdev.kobj, &input_dev_id_attr_group);
+ sysfs_create_group(&dev->cdev.kobj, &input_dev_caps_attr_group);
+}
+
+int input_register_device(struct input_dev *dev)
{
struct input_handle *handle;
struct input_handler *handler;
struct input_device_id *id;
- set_bit(EV_SYN, dev->evbit);
+ if (!dev->dynalloc) {
+ printk(KERN_WARNING "input: device %s is statically allocated, will not register\n"
+ "Please convert to input_allocate_device() or contact dtor_core@ameritech.net\n",
+ dev->name ? dev->name : "<Unknown>");
+ return -EINVAL;
+ }
init_MUTEX(&dev->sem);
+ set_bit(EV_SYN, dev->evbit);
/*
* If delay and period are pre-set by the driver, then autorepeating
@@ -632,17 +773,17 @@ void input_register_device(struct input_dev *dev)
INIT_LIST_HEAD(&dev->h_list);
list_add_tail(&dev->node, &input_dev_list);
+ input_register_classdevice(dev);
+
list_for_each_entry(handler, &input_handler_list, node)
if (!handler->blacklist || !input_match_device(handler->blacklist, dev))
if ((id = input_match_device(handler->id_table, dev)))
if ((handle = handler->connect(handler, dev, id)))
input_link_handle(handle);
-#ifdef CONFIG_HOTPLUG
- input_call_hotplug("add", dev);
-#endif
-
input_wakeup_procfs_readers();
+
+ return 0;
}
void input_unregister_device(struct input_dev *dev)
@@ -660,12 +801,13 @@ void input_unregister_device(struct input_dev *dev)
handle->handler->disconnect(handle);
}
-#ifdef CONFIG_HOTPLUG
- input_call_hotplug("remove", dev);
-#endif
-
list_del_init(&dev->node);
+ sysfs_remove_group(&dev->cdev.kobj, &input_dev_caps_attr_group);
+ sysfs_remove_group(&dev->cdev.kobj, &input_dev_id_attr_group);
+ sysfs_remove_group(&dev->cdev.kobj, &input_dev_group);
+ class_device_unregister(&dev->cdev);
+
input_wakeup_procfs_readers();
}
@@ -748,16 +890,14 @@ static struct file_operations input_fops = {
.open = input_open_file,
};
-struct class *input_class;
-
static int __init input_init(void)
{
int err;
- input_class = class_create(THIS_MODULE, "input");
- if (IS_ERR(input_class)) {
- printk(KERN_ERR "input: unable to register input class\n");
- return PTR_ERR(input_class);
+ err = class_register(&input_class);
+ if (err) {
+ printk(KERN_ERR "input: unable to register input_dev class\n");
+ return err;
}
err = input_proc_init();
@@ -770,24 +910,18 @@ static int __init input_init(void)
goto fail2;
}
- err = devfs_mk_dir("input");
- if (err)
- goto fail3;
-
return 0;
- fail3: unregister_chrdev(INPUT_MAJOR, "input");
fail2: input_proc_exit();
- fail1: class_destroy(input_class);
+ fail1: class_unregister(&input_class);
return err;
}
static void __exit input_exit(void)
{
input_proc_exit();
- devfs_remove("input");
unregister_chrdev(INPUT_MAJOR, "input");
- class_destroy(input_class);
+ class_unregister(&input_class);
}
subsys_initcall(input_init);
diff --git a/drivers/input/joydev.c b/drivers/input/joydev.c
index e0938d1d3ad7..20e2972b9204 100644
--- a/drivers/input/joydev.c
+++ b/drivers/input/joydev.c
@@ -26,7 +26,6 @@
#include <linux/init.h>
#include <linux/smp_lock.h>
#include <linux/device.h>
-#include <linux/devfs_fs_kernel.h>
MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
MODULE_DESCRIPTION("Joystick device interfaces");
@@ -449,6 +448,7 @@ static struct file_operations joydev_fops = {
static struct input_handle *joydev_connect(struct input_handler *handler, struct input_dev *dev, struct input_device_id *id)
{
struct joydev *joydev;
+ struct class_device *cdev;
int i, j, t, minor;
for (minor = 0; minor < JOYDEV_MINORS && joydev_table[minor]; minor++);
@@ -514,11 +514,13 @@ static struct input_handle *joydev_connect(struct input_handler *handler, struct
joydev_table[minor] = joydev;
- devfs_mk_cdev(MKDEV(INPUT_MAJOR, JOYDEV_MINOR_BASE + minor),
- S_IFCHR|S_IRUGO|S_IWUSR, "input/js%d", minor);
- class_device_create(input_class,
+ cdev = class_device_create(&input_class, &dev->cdev,
MKDEV(INPUT_MAJOR, JOYDEV_MINOR_BASE + minor),
- dev->dev, "js%d", minor);
+ dev->cdev.dev, joydev->name);
+
+ /* temporary symlink to keep userspace happy */
+ sysfs_create_link(&input_class.subsys.kset.kobj, &cdev->kobj,
+ joydev->name);
return &joydev->handle;
}
@@ -528,8 +530,8 @@ static void joydev_disconnect(struct input_handle *handle)
struct joydev *joydev = handle->private;
struct joydev_list *list;
- class_device_destroy(input_class, MKDEV(INPUT_MAJOR, JOYDEV_MINOR_BASE + joydev->minor));
- devfs_remove("input/js%d", joydev->minor);
+ sysfs_remove_link(&input_class.subsys.kset.kobj, joydev->name);
+ class_device_destroy(&input_class, MKDEV(INPUT_MAJOR, JOYDEV_MINOR_BASE + joydev->minor));
joydev->exist = 0;
if (joydev->open) {
diff --git a/drivers/input/joystick/a3d.c b/drivers/input/joystick/a3d.c
index bf65430181fa..4571ea3a4b92 100644
--- a/drivers/input/joystick/a3d.c
+++ b/drivers/input/joystick/a3d.c
@@ -34,6 +34,7 @@
#include <linux/init.h>
#include <linux/gameport.h>
#include <linux/input.h>
+#include <linux/jiffies.h>
#define DRIVER_DESC "FP-Gaming Assasin 3D joystick driver"
diff --git a/drivers/input/joystick/adi.c b/drivers/input/joystick/adi.c
index cf35ae638a0d..704bf70f1db7 100644
--- a/drivers/input/joystick/adi.c
+++ b/drivers/input/joystick/adi.c
@@ -34,6 +34,7 @@
#include <linux/input.h>
#include <linux/gameport.h>
#include <linux/init.h>
+#include <linux/jiffies.h>
#define DRIVER_DESC "Logitech ADI joystick family driver"
@@ -54,7 +55,7 @@ MODULE_LICENSE("GPL");
#define ADI_MIN_LENGTH 8
#define ADI_MIN_LEN_LENGTH 10
#define ADI_MIN_ID_LENGTH 66
-#define ADI_MAX_NAME_LENGTH 48
+#define ADI_MAX_NAME_LENGTH 64
#define ADI_MAX_CNAME_LENGTH 16
#define ADI_MAX_PHYS_LENGTH 64
@@ -106,7 +107,7 @@ static struct {
*/
struct adi {
- struct input_dev dev;
+ struct input_dev *dev;
int length;
int ret;
int idx;
@@ -215,7 +216,7 @@ static inline int adi_get_bits(struct adi *adi, int count)
static int adi_decode(struct adi *adi)
{
- struct input_dev *dev = &adi->dev;
+ struct input_dev *dev = adi->dev;
char *abs = adi->abs;
short *key = adi->key;
int i, t;
@@ -318,7 +319,8 @@ static void adi_init_digital(struct gameport *gameport)
for (i = 0; seq[i]; i++) {
gameport_trigger(gameport);
- if (seq[i] > 0) msleep(seq[i]);
+ if (seq[i] > 0)
+ msleep(seq[i]);
if (seq[i] < 0) {
mdelay(-seq[i]);
udelay(-seq[i]*14); /* It looks like mdelay() is off by approx 1.4% */
@@ -397,42 +399,46 @@ static void adi_id_decode(struct adi *adi, struct adi_port *port)
}
}
-static void adi_init_input(struct adi *adi, struct adi_port *port, int half)
+static int adi_init_input(struct adi *adi, struct adi_port *port, int half)
{
- int i, t;
+ struct input_dev *input_dev;
char buf[ADI_MAX_NAME_LENGTH];
+ int i, t;
- if (!adi->length) return;
-
- init_input_dev(&adi->dev);
+ adi->dev = input_dev = input_allocate_device();
+ if (!input_dev)
+ return -ENOMEM;
t = adi->id < ADI_ID_MAX ? adi->id : ADI_ID_MAX;
snprintf(buf, ADI_MAX_PHYS_LENGTH, adi_names[t], adi->id);
- snprintf(adi->name, ADI_MAX_NAME_LENGTH, "Logitech %s", buf);
+ snprintf(adi->name, ADI_MAX_NAME_LENGTH, "Logitech %s [%s]", buf, adi->cname);
snprintf(adi->phys, ADI_MAX_PHYS_LENGTH, "%s/input%d", port->gameport->phys, half);
adi->abs = adi_abs[t];
adi->key = adi_key[t];
- adi->dev.open = adi_open;
- adi->dev.close = adi_close;
+ input_dev->name = adi->name;
+ input_dev->phys = adi->phys;
+ input_dev->id.bustype = BUS_GAMEPORT;
+ input_dev->id.vendor = GAMEPORT_ID_VENDOR_LOGITECH;
+ input_dev->id.product = adi->id;
+ input_dev->id.version = 0x0100;
+ input_dev->cdev.dev = &port->gameport->dev;
+ input_dev->private = port;
- adi->dev.name = adi->name;
- adi->dev.phys = adi->phys;
- adi->dev.id.bustype = BUS_GAMEPORT;
- adi->dev.id.vendor = GAMEPORT_ID_VENDOR_LOGITECH;
- adi->dev.id.product = adi->id;
- adi->dev.id.version = 0x0100;
+ input_dev->open = adi_open;
+ input_dev->close = adi_close;
- adi->dev.private = port;
- adi->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+ input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
for (i = 0; i < adi->axes10 + adi->axes8 + (adi->hats + (adi->pad != -1)) * 2; i++)
- set_bit(adi->abs[i], adi->dev.absbit);
+ set_bit(adi->abs[i], input_dev->absbit);
for (i = 0; i < adi->buttons; i++)
- set_bit(adi->key[i], adi->dev.keybit);
+ set_bit(adi->key[i], input_dev->keybit);
+
+ return 0;
}
static void adi_init_center(struct adi *adi)
@@ -445,17 +451,17 @@ static void adi_init_center(struct adi *adi)
for (i = 0; i < adi->axes10 + adi->axes8 + (adi->hats + (adi->pad != -1)) * 2; i++) {
t = adi->abs[i];
- x = adi->dev.abs[t];
+ x = adi->dev->abs[t];
if (t == ABS_THROTTLE || t == ABS_RUDDER || adi->id == ADI_ID_WGPE)
x = i < adi->axes10 ? 512 : 128;
if (i < adi->axes10)
- input_set_abs_params(&adi->dev, t, 64, x * 2 - 64, 2, 16);
+ input_set_abs_params(adi->dev, t, 64, x * 2 - 64, 2, 16);
else if (i < adi->axes10 + adi->axes8)
- input_set_abs_params(&adi->dev, t, 48, x * 2 - 48, 1, 16);
+ input_set_abs_params(adi->dev, t, 48, x * 2 - 48, 1, 16);
else
- input_set_abs_params(&adi->dev, t, -1, 1, 0, 0);
+ input_set_abs_params(adi->dev, t, -1, 1, 0, 0);
}
}
@@ -469,7 +475,8 @@ static int adi_connect(struct gameport *gameport, struct gameport_driver *drv)
int i;
int err;
- if (!(port = kzalloc(sizeof(struct adi_port), GFP_KERNEL)))
+ port = kzalloc(sizeof(struct adi_port), GFP_KERNEL);
+ if (!port)
return -ENOMEM;
port->gameport = gameport;
@@ -477,10 +484,8 @@ static int adi_connect(struct gameport *gameport, struct gameport_driver *drv)
gameport_set_drvdata(gameport, port);
err = gameport_open(gameport, drv, GAMEPORT_MODE_RAW);
- if (err) {
- kfree(port);
- return err;
- }
+ if (err)
+ goto fail1;
adi_init_digital(gameport);
adi_read_packet(port);
@@ -490,13 +495,18 @@ static int adi_connect(struct gameport *gameport, struct gameport_driver *drv)
for (i = 0; i < 2; i++) {
adi_id_decode(port->adi + i, port);
- adi_init_input(port->adi + i, port, i);
+
+ if (!port->adi[i].length)
+ continue;
+
+ err = adi_init_input(port->adi + i, port, i);
+ if (err)
+ goto fail2;
}
if (!port->adi[0].length && !port->adi[1].length) {
- gameport_close(gameport);
- kfree(port);
- return -ENODEV;
+ err = -ENODEV;
+ goto fail2;
}
gameport_set_poll_handler(gameport, adi_poll);
@@ -511,12 +521,18 @@ static int adi_connect(struct gameport *gameport, struct gameport_driver *drv)
for (i = 0; i < 2; i++)
if (port->adi[i].length > 0) {
adi_init_center(port->adi + i);
- input_register_device(&port->adi[i].dev);
- printk(KERN_INFO "input: %s [%s] on %s\n",
- port->adi[i].name, port->adi[i].cname, gameport->phys);
+ input_register_device(port->adi[i].dev);
}
return 0;
+
+ fail2: for (i = 0; i < 2; i++)
+ if (port->adi[i].dev)
+ input_free_device(port->adi[i].dev);
+ gameport_close(gameport);
+ fail1: gameport_set_drvdata(gameport, NULL);
+ kfree(port);
+ return err;
}
static void adi_disconnect(struct gameport *gameport)
@@ -526,7 +542,7 @@ static void adi_disconnect(struct gameport *gameport)
for (i = 0; i < 2; i++)
if (port->adi[i].length > 0)
- input_unregister_device(&port->adi[i].dev);
+ input_unregister_device(port->adi[i].dev);
gameport_close(gameport);
gameport_set_drvdata(gameport, NULL);
kfree(port);
diff --git a/drivers/input/joystick/amijoy.c b/drivers/input/joystick/amijoy.c
index e996183c5b06..8558a99f6635 100644
--- a/drivers/input/joystick/amijoy.c
+++ b/drivers/input/joystick/amijoy.c
@@ -53,11 +53,9 @@ __obsolete_setup("amijoy=");
static int amijoy_used;
static DECLARE_MUTEX(amijoy_sem);
-static struct input_dev amijoy_dev[2];
+static struct input_dev *amijoy_dev[2];
static char *amijoy_phys[2] = { "amijoy/input0", "amijoy/input1" };
-static char *amijoy_name = "Amiga joystick";
-
static irqreturn_t amijoy_interrupt(int irq, void *dummy, struct pt_regs *fp)
{
int i, data = 0, button = 0;
@@ -70,15 +68,15 @@ static irqreturn_t amijoy_interrupt(int irq, void *dummy, struct pt_regs *fp)
case 1: data = ~custom.joy1dat; button = (~ciaa.pra >> 7) & 1; break;
}
- input_regs(amijoy_dev + i, fp);
+ input_regs(amijoy_dev[i], fp);
- input_report_key(amijoy_dev + i, BTN_TRIGGER, button);
+ input_report_key(amijoy_dev[i], BTN_TRIGGER, button);
- input_report_abs(amijoy_dev + i, ABS_X, ((data >> 1) & 1) - ((data >> 9) & 1));
+ input_report_abs(amijoy_dev[i], ABS_X, ((data >> 1) & 1) - ((data >> 9) & 1));
data = ~(data ^ (data << 1));
- input_report_abs(amijoy_dev + i, ABS_Y, ((data >> 1) & 1) - ((data >> 9) & 1));
+ input_report_abs(amijoy_dev[i], ABS_Y, ((data >> 1) & 1) - ((data >> 9) & 1));
- input_sync(amijoy_dev + i);
+ input_sync(amijoy_dev[i]);
}
return IRQ_HANDLED;
}
@@ -114,39 +112,52 @@ static void amijoy_close(struct input_dev *dev)
static int __init amijoy_init(void)
{
int i, j;
+ int err;
- for (i = 0; i < 2; i++)
- if (amijoy[i]) {
- if (!request_mem_region(CUSTOM_PHYSADDR+10+i*2, 2,
- "amijoy [Denise]")) {
- if (i == 1 && amijoy[0]) {
- input_unregister_device(amijoy_dev);
- release_mem_region(CUSTOM_PHYSADDR+10, 2);
- }
- return -EBUSY;
- }
+ for (i = 0; i < 2; i++) {
+ if (!amijoy[i])
+ continue;
- amijoy_dev[i].open = amijoy_open;
- amijoy_dev[i].close = amijoy_close;
- amijoy_dev[i].evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
- amijoy_dev[i].absbit[0] = BIT(ABS_X) | BIT(ABS_Y);
- amijoy_dev[i].keybit[LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
- for (j = 0; j < 2; j++) {
- amijoy_dev[i].absmin[ABS_X + j] = -1;
- amijoy_dev[i].absmax[ABS_X + j] = 1;
- }
+ amijoy_dev[i] = input_allocate_device();
+ if (!amijoy_dev[i]) {
+ err = -ENOMEM;
+ goto fail;
+ }
- amijoy_dev[i].name = amijoy_name;
- amijoy_dev[i].phys = amijoy_phys[i];
- amijoy_dev[i].id.bustype = BUS_AMIGA;
- amijoy_dev[i].id.vendor = 0x0001;
- amijoy_dev[i].id.product = 0x0003;
- amijoy_dev[i].id.version = 0x0100;
+ if (!request_mem_region(CUSTOM_PHYSADDR + 10 + i * 2, 2, "amijoy [Denise]")) {
+ input_free_device(amijoy_dev[i]);
+ err = -EBUSY;
+ goto fail;
+ }
- input_register_device(amijoy_dev + i);
- printk(KERN_INFO "input: %s at joy%ddat\n", amijoy_name, i);
+ amijoy_dev[i]->name = "Amiga joystick";
+ amijoy_dev[i]->phys = amijoy_phys[i];
+ amijoy_dev[i]->id.bustype = BUS_AMIGA;
+ amijoy_dev[i]->id.vendor = 0x0001;
+ amijoy_dev[i]->id.product = 0x0003;
+ amijoy_dev[i]->id.version = 0x0100;
+
+ amijoy_dev[i]->open = amijoy_open;
+ amijoy_dev[i]->close = amijoy_close;
+
+ amijoy_dev[i]->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+ amijoy_dev[i]->absbit[0] = BIT(ABS_X) | BIT(ABS_Y);
+ amijoy_dev[i]->keybit[LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
+ for (j = 0; j < 2; j++) {
+ amijoy_dev[i]->absmin[ABS_X + j] = -1;
+ amijoy_dev[i]->absmax[ABS_X + j] = 1;
}
+
+ input_register_device(amijoy_dev[i]);
+ }
return 0;
+
+ fail: while (--i >= 0)
+ if (amijoy[i]) {
+ input_unregister_device(amijoy_dev[i]);
+ release_mem_region(CUSTOM_PHYSADDR + 10 + i * 2, 2);
+ }
+ return err;
}
static void __exit amijoy_exit(void)
@@ -155,8 +166,8 @@ static void __exit amijoy_exit(void)
for (i = 0; i < 2; i++)
if (amijoy[i]) {
- input_unregister_device(amijoy_dev + i);
- release_mem_region(CUSTOM_PHYSADDR+10+i*2, 2);
+ input_unregister_device(amijoy_dev[i]);
+ release_mem_region(CUSTOM_PHYSADDR + 10 + i * 2, 2);
}
}
diff --git a/drivers/input/joystick/analog.c b/drivers/input/joystick/analog.c
index 64b1313a3c66..3121961e3e7c 100644
--- a/drivers/input/joystick/analog.c
+++ b/drivers/input/joystick/analog.c
@@ -38,6 +38,7 @@
#include <linux/init.h>
#include <linux/input.h>
#include <linux/gameport.h>
+#include <linux/jiffies.h>
#include <asm/timex.h>
#define DRIVER_DESC "Analog joystick and gamepad driver"
@@ -111,7 +112,7 @@ static short analog_joy_btn[] = { BTN_TRIGGER, BTN_THUMB, BTN_TOP, BTN_TOP2, BTN
static unsigned char analog_chf[] = { 0xf, 0x0, 0x1, 0x9, 0x2, 0x4, 0xc, 0x8, 0x3, 0x5, 0xb, 0x7, 0xd, 0xe, 0xa, 0x6 };
struct analog {
- struct input_dev dev;
+ struct input_dev *dev;
int mask;
short *buttons;
char name[ANALOG_MAX_NAME_LENGTH];
@@ -182,7 +183,7 @@ static unsigned long analog_faketime = 0;
static void analog_decode(struct analog *analog, int *axes, int *initial, int buttons)
{
- struct input_dev *dev = &analog->dev;
+ struct input_dev *dev = analog->dev;
int i, j;
if (analog->mask & ANALOG_HAT_FCS)
@@ -428,27 +429,30 @@ static void analog_name(struct analog *analog)
* analog_init_device()
*/
-static void analog_init_device(struct analog_port *port, struct analog *analog, int index)
+static int analog_init_device(struct analog_port *port, struct analog *analog, int index)
{
+ struct input_dev *input_dev;
int i, j, t, v, w, x, y, z;
analog_name(analog);
sprintf(analog->phys, "%s/input%d", port->gameport->phys, index);
analog->buttons = (analog->mask & ANALOG_GAMEPAD) ? analog_pad_btn : analog_joy_btn;
- init_input_dev(&analog->dev);
+ analog->dev = input_dev = input_allocate_device();
+ if (!input_dev)
+ return -ENOMEM;
- analog->dev.name = analog->name;
- analog->dev.phys = analog->phys;
- analog->dev.id.bustype = BUS_GAMEPORT;
- analog->dev.id.vendor = GAMEPORT_ID_VENDOR_ANALOG;
- analog->dev.id.product = analog->mask >> 4;
- analog->dev.id.version = 0x0100;
+ input_dev->name = analog->name;
+ input_dev->phys = analog->phys;
+ input_dev->id.bustype = BUS_GAMEPORT;
+ input_dev->id.vendor = GAMEPORT_ID_VENDOR_ANALOG;
+ input_dev->id.product = analog->mask >> 4;
+ input_dev->id.version = 0x0100;
- analog->dev.open = analog_open;
- analog->dev.close = analog_close;
- analog->dev.private = port;
- analog->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+ input_dev->open = analog_open;
+ input_dev->close = analog_close;
+ input_dev->private = port;
+ input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
for (i = j = 0; i < 4; i++)
if (analog->mask & (1 << i)) {
@@ -461,8 +465,6 @@ static void analog_init_device(struct analog_port *port, struct analog *analog,
v = (x >> 3);
w = (x >> 3);
- set_bit(t, analog->dev.absbit);
-
if ((i == 2 || i == 3) && (j == 2 || j == 3) && (z > (y >> 3)))
x = y;
@@ -472,11 +474,7 @@ static void analog_init_device(struct analog_port *port, struct analog *analog,
w = (x >> 4);
}
- analog->dev.absmax[t] = (x << 1) - v;
- analog->dev.absmin[t] = v;
- analog->dev.absfuzz[t] = port->fuzz;
- analog->dev.absflat[t] = w;
-
+ input_set_abs_params(input_dev, t, v, (x << 1) - v, port->fuzz, w);
j++;
}
@@ -484,41 +482,30 @@ static void analog_init_device(struct analog_port *port, struct analog *analog,
if (analog->mask & analog_exts[i])
for (x = 0; x < 2; x++) {
t = analog_hats[j++];
- set_bit(t, analog->dev.absbit);
- analog->dev.absmax[t] = 1;
- analog->dev.absmin[t] = -1;
+ input_set_abs_params(input_dev, t, -1, 1, 0, 0);
}
for (i = j = 0; i < 4; i++)
if (analog->mask & (0x10 << i))
- set_bit(analog->buttons[j++], analog->dev.keybit);
+ set_bit(analog->buttons[j++], input_dev->keybit);
if (analog->mask & ANALOG_BTNS_CHF)
for (i = 0; i < 2; i++)
- set_bit(analog->buttons[j++], analog->dev.keybit);
+ set_bit(analog->buttons[j++], input_dev->keybit);
if (analog->mask & ANALOG_HBTN_CHF)
for (i = 0; i < 4; i++)
- set_bit(analog->buttons[j++], analog->dev.keybit);
+ set_bit(analog->buttons[j++], input_dev->keybit);
for (i = 0; i < 4; i++)
if (analog->mask & (ANALOG_BTN_TL << i))
- set_bit(analog_pads[i], analog->dev.keybit);
+ set_bit(analog_pads[i], input_dev->keybit);
analog_decode(analog, port->axes, port->initial, port->buttons);
- input_register_device(&analog->dev);
+ input_register_device(analog->dev);
- printk(KERN_INFO "input: %s at %s", analog->name, port->gameport->phys);
-
- if (port->cooked)
- printk(" [ADC port]\n");
- else
- printk(" [%s timer, %d %sHz clock, %d ns res]\n", TIME_NAME,
- port->speed > 10000 ? (port->speed + 800) / 1000 : port->speed,
- port->speed > 10000 ? "M" : "k",
- port->speed > 10000 ? (port->loop * 1000) / (port->speed / 1000)
- : (port->loop * 1000000) / port->speed);
+ return 0;
}
/*
@@ -659,37 +646,41 @@ static int analog_connect(struct gameport *gameport, struct gameport_driver *drv
return - ENOMEM;
err = analog_init_port(gameport, drv, port);
- if (err) {
- kfree(port);
- return err;
- }
+ if (err)
+ goto fail1;
err = analog_init_masks(port);
- if (err) {
- gameport_close(gameport);
- gameport_set_drvdata(gameport, NULL);
- kfree(port);
- return err;
- }
+ if (err)
+ goto fail2;
gameport_set_poll_handler(gameport, analog_poll);
gameport_set_poll_interval(gameport, 10);
for (i = 0; i < 2; i++)
- if (port->analog[i].mask)
- analog_init_device(port, port->analog + i, i);
+ if (port->analog[i].mask) {
+ err = analog_init_device(port, port->analog + i, i);
+ if (err)
+ goto fail3;
+ }
return 0;
+
+ fail3: while (--i >= 0)
+ input_unregister_device(port->analog[i].dev);
+ fail2: gameport_close(gameport);
+ fail1: gameport_set_drvdata(gameport, NULL);
+ kfree(port);
+ return err;
}
static void analog_disconnect(struct gameport *gameport)
{
- int i;
struct analog_port *port = gameport_get_drvdata(gameport);
+ int i;
for (i = 0; i < 2; i++)
if (port->analog[i].mask)
- input_unregister_device(&port->analog[i].dev);
+ input_unregister_device(port->analog[i].dev);
gameport_close(gameport);
gameport_set_drvdata(gameport, NULL);
printk(KERN_INFO "analog.c: %d out of %d reads (%d%%) on %s failed\n",
diff --git a/drivers/input/joystick/cobra.c b/drivers/input/joystick/cobra.c
index 0b2e9fa26579..1909f7ef340c 100644
--- a/drivers/input/joystick/cobra.c
+++ b/drivers/input/joystick/cobra.c
@@ -34,6 +34,7 @@
#include <linux/init.h>
#include <linux/gameport.h>
#include <linux/input.h>
+#include <linux/jiffies.h>
#define DRIVER_DESC "Creative Labs Blaster GamePad Cobra driver"
@@ -44,13 +45,11 @@ MODULE_LICENSE("GPL");
#define COBRA_MAX_STROBE 45 /* 45 us max wait for first strobe */
#define COBRA_LENGTH 36
-static char* cobra_name = "Creative Labs Blaster GamePad Cobra";
-
static int cobra_btn[] = { BTN_START, BTN_SELECT, BTN_TL, BTN_TR, BTN_X, BTN_Y, BTN_Z, BTN_A, BTN_B, BTN_C, BTN_TL2, BTN_TR2, 0 };
struct cobra {
struct gameport *gameport;
- struct input_dev dev[2];
+ struct input_dev *dev[2];
int reads;
int bads;
unsigned char exists;
@@ -128,7 +127,7 @@ static void cobra_poll(struct gameport *gameport)
for (i = 0; i < 2; i++)
if (cobra->exists & r & (1 << i)) {
- dev = cobra->dev + i;
+ dev = cobra->dev[i];
input_report_abs(dev, ABS_X, ((data[i] >> 4) & 1) - ((data[i] >> 3) & 1));
input_report_abs(dev, ABS_Y, ((data[i] >> 2) & 1) - ((data[i] >> 1) & 1));
@@ -159,11 +158,13 @@ static void cobra_close(struct input_dev *dev)
static int cobra_connect(struct gameport *gameport, struct gameport_driver *drv)
{
struct cobra *cobra;
+ struct input_dev *input_dev;
unsigned int data[2];
int i, j;
int err;
- if (!(cobra = kzalloc(sizeof(struct cobra), GFP_KERNEL)))
+ cobra = kzalloc(sizeof(struct cobra), GFP_KERNEL);
+ if (!cobra)
return -ENOMEM;
cobra->gameport = gameport;
@@ -191,38 +192,46 @@ static int cobra_connect(struct gameport *gameport, struct gameport_driver *drv)
gameport_set_poll_handler(gameport, cobra_poll);
gameport_set_poll_interval(gameport, 20);
- for (i = 0; i < 2; i++)
- if ((cobra->exists >> i) & 1) {
-
- sprintf(cobra->phys[i], "%s/input%d", gameport->phys, i);
+ for (i = 0; i < 2; i++) {
+ if (~(cobra->exists >> i) & 1)
+ continue;
- cobra->dev[i].private = cobra;
- cobra->dev[i].open = cobra_open;
- cobra->dev[i].close = cobra_close;
+ cobra->dev[i] = input_dev = input_allocate_device();
+ if (!input_dev) {
+ err = -ENOMEM;
+ goto fail3;
+ }
- cobra->dev[i].name = cobra_name;
- cobra->dev[i].phys = cobra->phys[i];
- cobra->dev[i].id.bustype = BUS_GAMEPORT;
- cobra->dev[i].id.vendor = GAMEPORT_ID_VENDOR_CREATIVE;
- cobra->dev[i].id.product = 0x0008;
- cobra->dev[i].id.version = 0x0100;
+ sprintf(cobra->phys[i], "%s/input%d", gameport->phys, i);
- cobra->dev[i].evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+ input_dev->name = "Creative Labs Blaster GamePad Cobra";
+ input_dev->phys = cobra->phys[i];
+ input_dev->id.bustype = BUS_GAMEPORT;
+ input_dev->id.vendor = GAMEPORT_ID_VENDOR_CREATIVE;
+ input_dev->id.product = 0x0008;
+ input_dev->id.version = 0x0100;
+ input_dev->cdev.dev = &gameport->dev;
+ input_dev->private = cobra;
- input_set_abs_params(&cobra->dev[i], ABS_X, -1, 1, 0, 0);
- input_set_abs_params(&cobra->dev[i], ABS_Y, -1, 1, 0, 0);
+ input_dev->open = cobra_open;
+ input_dev->close = cobra_close;
- for (j = 0; cobra_btn[j]; j++)
- set_bit(cobra_btn[j], cobra->dev[i].keybit);
+ input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+ input_set_abs_params(input_dev, ABS_X, -1, 1, 0, 0);
+ input_set_abs_params(input_dev, ABS_Y, -1, 1, 0, 0);
+ for (j = 0; cobra_btn[j]; j++)
+ set_bit(cobra_btn[j], input_dev->keybit);
- input_register_device(&cobra->dev[i]);
- printk(KERN_INFO "input: %s on %s\n", cobra_name, gameport->phys);
- }
+ input_register_device(cobra->dev[i]);
+ }
return 0;
-fail2: gameport_close(gameport);
-fail1: gameport_set_drvdata(gameport, NULL);
+ fail3: for (i = 0; i < 2; i++)
+ if (cobra->dev[i])
+ input_unregister_device(cobra->dev[i]);
+ fail2: gameport_close(gameport);
+ fail1: gameport_set_drvdata(gameport, NULL);
kfree(cobra);
return err;
}
@@ -234,7 +243,7 @@ static void cobra_disconnect(struct gameport *gameport)
for (i = 0; i < 2; i++)
if ((cobra->exists >> i) & 1)
- input_unregister_device(cobra->dev + i);
+ input_unregister_device(cobra->dev[i]);
gameport_close(gameport);
gameport_set_drvdata(gameport, NULL);
kfree(cobra);
diff --git a/drivers/input/joystick/db9.c b/drivers/input/joystick/db9.c
index 2a3e4bb2da50..499344c72756 100644
--- a/drivers/input/joystick/db9.c
+++ b/drivers/input/joystick/db9.c
@@ -43,25 +43,28 @@ MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
MODULE_DESCRIPTION("Atari, Amstrad, Commodore, Amiga, Sega, etc. joystick driver");
MODULE_LICENSE("GPL");
-static int db9[] __initdata = { -1, 0 };
-static int db9_nargs __initdata = 0;
-module_param_array_named(dev, db9, int, &db9_nargs, 0);
-MODULE_PARM_DESC(dev, "Describes first attached device (<parport#>,<type>)");
+struct db9_config {
+ int args[2];
+ int nargs;
+};
-static int db9_2[] __initdata = { -1, 0 };
-static int db9_nargs_2 __initdata = 0;
-module_param_array_named(dev2, db9_2, int, &db9_nargs_2, 0);
-MODULE_PARM_DESC(dev2, "Describes second attached device (<parport#>,<type>)");
+#define DB9_MAX_PORTS 3
+static struct db9_config db9[DB9_MAX_PORTS] __initdata;
-static int db9_3[] __initdata = { -1, 0 };
-static int db9_nargs_3 __initdata = 0;
-module_param_array_named(dev3, db9_3, int, &db9_nargs_3, 0);
+module_param_array_named(dev, db9[0].args, int, &db9[0].nargs, 0);
+MODULE_PARM_DESC(dev, "Describes first attached device (<parport#>,<type>)");
+module_param_array_named(dev2, db9[1].args, int, &db9[0].nargs, 0);
+MODULE_PARM_DESC(dev2, "Describes second attached device (<parport#>,<type>)");
+module_param_array_named(dev3, db9[2].args, int, &db9[2].nargs, 0);
MODULE_PARM_DESC(dev3, "Describes third attached device (<parport#>,<type>)");
__obsolete_setup("db9=");
__obsolete_setup("db9_2=");
__obsolete_setup("db9_3=");
+#define DB9_ARG_PARPORT 0
+#define DB9_ARG_MODE 1
+
#define DB9_MULTI_STICK 0x01
#define DB9_MULTI2_STICK 0x02
#define DB9_GENESIS_PAD 0x03
@@ -87,40 +90,53 @@ __obsolete_setup("db9_3=");
#define DB9_NORMAL 0x0a
#define DB9_NOSELECT 0x08
-#define DB9_MAX_DEVICES 2
-
#define DB9_GENESIS6_DELAY 14
#define DB9_REFRESH_TIME HZ/100
+#define DB9_MAX_DEVICES 2
+
+struct db9_mode_data {
+ const char *name;
+ const short *buttons;
+ int n_buttons;
+ int n_pads;
+ int n_axis;
+ int bidirectional;
+ int reverse;
+};
+
struct db9 {
- struct input_dev dev[DB9_MAX_DEVICES];
+ struct input_dev *dev[DB9_MAX_DEVICES];
struct timer_list timer;
struct pardevice *pd;
int mode;
int used;
struct semaphore sem;
- char phys[2][32];
+ char phys[DB9_MAX_DEVICES][32];
};
static struct db9 *db9_base[3];
-static short db9_multi_btn[] = { BTN_TRIGGER, BTN_THUMB };
-static short db9_genesis_btn[] = { BTN_START, BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z, BTN_MODE };
-static short db9_cd32_btn[] = { BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z, BTN_TL, BTN_TR, BTN_START };
-
-static char db9_buttons[DB9_MAX_PAD] = { 0, 1, 2, 4, 0, 6, 8, 9, 1, 1, 7, 9, 9 };
-static short *db9_btn[DB9_MAX_PAD] = { NULL, db9_multi_btn, db9_multi_btn, db9_genesis_btn, NULL, db9_genesis_btn,
- db9_genesis_btn, db9_cd32_btn, db9_multi_btn, db9_multi_btn, db9_cd32_btn,
- db9_cd32_btn, db9_cd32_btn };
-static char *db9_name[DB9_MAX_PAD] = { NULL, "Multisystem joystick", "Multisystem joystick (2 fire)", "Genesis pad",
- NULL, "Genesis 5 pad", "Genesis 6 pad", "Saturn pad", "Multisystem (0.8.0.2) joystick",
- "Multisystem (0.8.0.2-dual) joystick", "Amiga CD-32 pad", "Saturn dpp", "Saturn dpp dual" };
-
-static const int db9_max_pads[DB9_MAX_PAD] = { 0, 1, 1, 1, 0, 1, 1, 6, 1, 2, 1, 6, 12 };
-static const int db9_num_axis[DB9_MAX_PAD] = { 0, 2, 2, 2, 0, 2, 2, 7, 2, 2, 2 ,7, 7 };
+static const short db9_multi_btn[] = { BTN_TRIGGER, BTN_THUMB };
+static const short db9_genesis_btn[] = { BTN_START, BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z, BTN_MODE };
+static const short db9_cd32_btn[] = { BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z, BTN_TL, BTN_TR, BTN_START };
static const short db9_abs[] = { ABS_X, ABS_Y, ABS_RX, ABS_RY, ABS_RZ, ABS_Z, ABS_HAT0X, ABS_HAT0Y, ABS_HAT1X, ABS_HAT1Y };
-static const int db9_bidirectional[DB9_MAX_PAD] = { 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0 };
-static const int db9_reverse[DB9_MAX_PAD] = { 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0 };
+
+static const struct db9_mode_data db9_modes[] = {
+ { NULL, NULL, 0, 0, 0, 0, 0 },
+ { "Multisystem joystick", db9_multi_btn, 1, 1, 2, 1, 1 },
+ { "Multisystem joystick (2 fire)", db9_multi_btn, 2, 1, 2, 1, 1 },
+ { "Genesis pad", db9_genesis_btn, 4, 1, 2, 1, 1 },
+ { NULL, NULL, 0, 0, 0, 0, 0 },
+ { "Genesis 5 pad", db9_genesis_btn, 6, 1, 2, 1, 1 },
+ { "Genesis 6 pad", db9_genesis_btn, 8, 1, 2, 1, 1 },
+ { "Saturn pad", db9_cd32_btn, 9, 6, 7, 0, 1 },
+ { "Multisystem (0.8.0.2) joystick", db9_multi_btn, 1, 1, 2, 1, 1 },
+ { "Multisystem (0.8.0.2-dual) joystick", db9_multi_btn, 1, 2, 2, 1, 1 },
+ { "Amiga CD-32 pad", db9_cd32_btn, 7, 1, 2, 1, 1 },
+ { "Saturn dpp", db9_cd32_btn, 9, 6, 7, 0, 0 },
+ { "Saturn dpp dual", db9_cd32_btn, 9, 12, 7, 0, 0 },
+};
/*
* Saturn controllers
@@ -342,7 +358,7 @@ static int db9_saturn(int mode, struct parport *port, struct input_dev *dev)
default:
return -1;
}
- max_pads = min(db9_max_pads[mode], DB9_MAX_DEVICES);
+ max_pads = min(db9_modes[mode].n_pads, DB9_MAX_DEVICES);
for (tmp = 0, i = 0; i < n; i++) {
id = db9_saturn_read_packet(port, data, type + i, 1);
tmp = db9_saturn_report(id, data, dev, tmp, max_pads);
@@ -354,17 +370,18 @@ static void db9_timer(unsigned long private)
{
struct db9 *db9 = (void *) private;
struct parport *port = db9->pd->port;
- struct input_dev *dev = db9->dev;
+ struct input_dev *dev = db9->dev[0];
+ struct input_dev *dev2 = db9->dev[1];
int data, i;
- switch(db9->mode) {
+ switch (db9->mode) {
case DB9_MULTI_0802_2:
data = parport_read_data(port) >> 3;
- input_report_abs(dev + 1, ABS_X, (data & DB9_RIGHT ? 0 : 1) - (data & DB9_LEFT ? 0 : 1));
- input_report_abs(dev + 1, ABS_Y, (data & DB9_DOWN ? 0 : 1) - (data & DB9_UP ? 0 : 1));
- input_report_key(dev + 1, BTN_TRIGGER, ~data & DB9_FIRE1);
+ input_report_abs(dev2, ABS_X, (data & DB9_RIGHT ? 0 : 1) - (data & DB9_LEFT ? 0 : 1));
+ input_report_abs(dev2, ABS_Y, (data & DB9_DOWN ? 0 : 1) - (data & DB9_UP ? 0 : 1));
+ input_report_key(dev2, BTN_TRIGGER, ~data & DB9_FIRE1);
case DB9_MULTI_0802:
@@ -405,7 +422,7 @@ static void db9_timer(unsigned long private)
input_report_key(dev, BTN_C, ~data & DB9_FIRE2);
parport_write_control(port, DB9_NORMAL);
- data=parport_read_data(port);
+ data = parport_read_data(port);
input_report_key(dev, BTN_A, ~data & DB9_FIRE1);
input_report_key(dev, BTN_START, ~data & DB9_FIRE2);
@@ -414,7 +431,7 @@ static void db9_timer(unsigned long private)
case DB9_GENESIS5_PAD:
parport_write_control(port, DB9_NOSELECT);
- data=parport_read_data(port);
+ data = parport_read_data(port);
input_report_abs(dev, ABS_X, (data & DB9_RIGHT ? 0 : 1) - (data & DB9_LEFT ? 0 : 1));
input_report_abs(dev, ABS_Y, (data & DB9_DOWN ? 0 : 1) - (data & DB9_UP ? 0 : 1));
@@ -422,7 +439,7 @@ static void db9_timer(unsigned long private)
input_report_key(dev, BTN_C, ~data & DB9_FIRE2);
parport_write_control(port, DB9_NORMAL);
- data=parport_read_data(port);
+ data = parport_read_data(port);
input_report_key(dev, BTN_A, ~data & DB9_FIRE1);
input_report_key(dev, BTN_X, ~data & DB9_FIRE2);
@@ -434,7 +451,7 @@ static void db9_timer(unsigned long private)
parport_write_control(port, DB9_NOSELECT); /* 1 */
udelay(DB9_GENESIS6_DELAY);
- data=parport_read_data(port);
+ data = parport_read_data(port);
input_report_abs(dev, ABS_X, (data & DB9_RIGHT ? 0 : 1) - (data & DB9_LEFT ? 0 : 1));
input_report_abs(dev, ABS_Y, (data & DB9_DOWN ? 0 : 1) - (data & DB9_UP ? 0 : 1));
@@ -443,7 +460,7 @@ static void db9_timer(unsigned long private)
parport_write_control(port, DB9_NORMAL);
udelay(DB9_GENESIS6_DELAY);
- data=parport_read_data(port);
+ data = parport_read_data(port);
input_report_key(dev, BTN_A, ~data & DB9_FIRE1);
input_report_key(dev, BTN_START, ~data & DB9_FIRE2);
@@ -477,7 +494,7 @@ static void db9_timer(unsigned long private)
case DB9_CD32_PAD:
- data=parport_read_data(port);
+ data = parport_read_data(port);
input_report_abs(dev, ABS_X, (data & DB9_RIGHT ? 0 : 1) - (data & DB9_LEFT ? 0 : 1));
input_report_abs(dev, ABS_Y, (data & DB9_DOWN ? 0 : 1) - (data & DB9_UP ? 0 : 1));
@@ -489,7 +506,7 @@ static void db9_timer(unsigned long private)
parport_write_control(port, 0x02);
parport_write_control(port, 0x0a);
input_report_key(dev, db9_cd32_btn[i], ~data & DB9_FIRE2);
- }
+ }
parport_write_control(port, 0x00);
break;
@@ -513,7 +530,7 @@ static int db9_open(struct input_dev *dev)
if (!db9->used++) {
parport_claim(db9->pd);
parport_write_data(port, 0xff);
- if (db9_reverse[db9->mode]) {
+ if (db9_modes[db9->mode].reverse) {
parport_data_reverse(port);
parport_write_control(port, DB9_NORMAL);
}
@@ -539,117 +556,160 @@ static void db9_close(struct input_dev *dev)
up(&db9->sem);
}
-static struct db9 __init *db9_probe(int *config, int nargs)
+static struct db9 __init *db9_probe(int parport, int mode)
{
struct db9 *db9;
+ const struct db9_mode_data *db9_mode;
struct parport *pp;
+ struct pardevice *pd;
+ struct input_dev *input_dev;
int i, j;
+ int err;
- if (config[0] < 0)
- return NULL;
-
- if (nargs < 2) {
- printk(KERN_ERR "db9.c: Device type must be specified.\n");
- return NULL;
+ if (mode < 1 || mode >= DB9_MAX_PAD || !db9_modes[mode].n_buttons) {
+ printk(KERN_ERR "db9.c: Bad device type %d\n", mode);
+ err = -EINVAL;
+ goto err_out;
}
- if (config[1] < 1 || config[1] >= DB9_MAX_PAD || !db9_buttons[config[1]]) {
- printk(KERN_ERR "db9.c: bad config\n");
- return NULL;
- }
+ db9_mode = &db9_modes[mode];
- pp = parport_find_number(config[0]);
+ pp = parport_find_number(parport);
if (!pp) {
printk(KERN_ERR "db9.c: no such parport\n");
- return NULL;
+ err = -ENODEV;
+ goto err_out;
}
- if (db9_bidirectional[config[1]]) {
- if (!(pp->modes & PARPORT_MODE_TRISTATE)) {
- printk(KERN_ERR "db9.c: specified parport is not bidirectional\n");
- parport_put_port(pp);
- return NULL;
- }
+ if (db9_mode[mode].bidirectional && !(pp->modes & PARPORT_MODE_TRISTATE)) {
+ printk(KERN_ERR "db9.c: specified parport is not bidirectional\n");
+ err = -EINVAL;
+ goto err_put_pp;
+ }
+
+ pd = parport_register_device(pp, "db9", NULL, NULL, NULL, PARPORT_DEV_EXCL, NULL);
+ if (!pd) {
+ printk(KERN_ERR "db9.c: parport busy already - lp.o loaded?\n");
+ err = -EBUSY;
+ goto err_put_pp;
}
- if (!(db9 = kzalloc(sizeof(struct db9), GFP_KERNEL))) {
- parport_put_port(pp);
- return NULL;
+ db9 = kzalloc(sizeof(struct db9), GFP_KERNEL);
+ if (!db9) {
+ printk(KERN_ERR "db9.c: Not enough memory\n");
+ err = -ENOMEM;
+ goto err_unreg_pardev;
}
init_MUTEX(&db9->sem);
- db9->mode = config[1];
+ db9->pd = pd;
+ db9->mode = mode;
init_timer(&db9->timer);
db9->timer.data = (long) db9;
db9->timer.function = db9_timer;
- db9->pd = parport_register_device(pp, "db9", NULL, NULL, NULL, PARPORT_DEV_EXCL, NULL);
- parport_put_port(pp);
-
- if (!db9->pd) {
- printk(KERN_ERR "db9.c: parport busy already - lp.o loaded?\n");
- kfree(db9);
- return NULL;
- }
+ for (i = 0; i < (min(db9_mode->n_pads, DB9_MAX_DEVICES)); i++) {
- for (i = 0; i < (min(db9_max_pads[db9->mode], DB9_MAX_DEVICES)); i++) {
+ db9->dev[i] = input_dev = input_allocate_device();
+ if (!input_dev) {
+ printk(KERN_ERR "db9.c: Not enough memory for input device\n");
+ err = -ENOMEM;
+ goto err_free_devs;
+ }
sprintf(db9->phys[i], "%s/input%d", db9->pd->port->name, i);
- db9->dev[i].private = db9;
- db9->dev[i].open = db9_open;
- db9->dev[i].close = db9_close;
-
- db9->dev[i].name = db9_name[db9->mode];
- db9->dev[i].phys = db9->phys[i];
- db9->dev[i].id.bustype = BUS_PARPORT;
- db9->dev[i].id.vendor = 0x0002;
- db9->dev[i].id.product = config[1];
- db9->dev[i].id.version = 0x0100;
-
- db9->dev[i].evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
- for (j = 0; j < db9_buttons[db9->mode]; j++)
- set_bit(db9_btn[db9->mode][j], db9->dev[i].keybit);
- for (j = 0; j < db9_num_axis[db9->mode]; j++) {
- set_bit(db9_abs[j], db9->dev[i].absbit);
- if (j < 2) {
- db9->dev[i].absmin[db9_abs[j]] = -1;
- db9->dev[i].absmax[db9_abs[j]] = 1;
- } else {
- db9->dev[i].absmin[db9_abs[j]] = 1;
- db9->dev[i].absmax[db9_abs[j]] = 255;
- db9->dev[i].absflat[db9_abs[j]] = 0;
- }
+ input_dev->name = db9_mode->name;
+ input_dev->phys = db9->phys[i];
+ input_dev->id.bustype = BUS_PARPORT;
+ input_dev->id.vendor = 0x0002;
+ input_dev->id.product = mode;
+ input_dev->id.version = 0x0100;
+ input_dev->private = db9;
+
+ input_dev->open = db9_open;
+ input_dev->close = db9_close;
+
+ input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+ for (j = 0; j < db9_mode->n_buttons; j++)
+ set_bit(db9_mode->buttons[j], input_dev->keybit);
+ for (j = 0; j < db9_mode->n_axis; j++) {
+ if (j < 2)
+ input_set_abs_params(input_dev, db9_abs[j], -1, 1, 0, 0);
+ else
+ input_set_abs_params(input_dev, db9_abs[j], 1, 255, 0, 0);
}
- input_register_device(db9->dev + i);
- printk(KERN_INFO "input: %s on %s\n", db9->dev[i].name, db9->pd->port->name);
+
+ input_register_device(input_dev);
}
+ parport_put_port(pp);
return db9;
+
+ err_free_devs:
+ while (--i >= 0)
+ input_unregister_device(db9->dev[i]);
+ kfree(db9);
+ err_unreg_pardev:
+ parport_unregister_device(pd);
+ err_put_pp:
+ parport_put_port(pp);
+ err_out:
+ return ERR_PTR(err);
+}
+
+static void __exit db9_remove(struct db9 *db9)
+{
+ int i;
+
+ for (i = 0; i < min(db9_modes[db9->mode].n_pads, DB9_MAX_DEVICES); i++)
+ input_unregister_device(db9->dev[i]);
+ parport_unregister_device(db9->pd);
+ kfree(db9);
}
static int __init db9_init(void)
{
- db9_base[0] = db9_probe(db9, db9_nargs);
- db9_base[1] = db9_probe(db9_2, db9_nargs_2);
- db9_base[2] = db9_probe(db9_3, db9_nargs_3);
+ int i;
+ int have_dev = 0;
+ int err = 0;
+
+ for (i = 0; i < DB9_MAX_PORTS; i++) {
+ if (db9[i].nargs == 0 || db9[i].args[DB9_ARG_PARPORT] < 0)
+ continue;
+
+ if (db9[i].nargs < 2) {
+ printk(KERN_ERR "db9.c: Device type must be specified.\n");
+ err = -EINVAL;
+ break;
+ }
+
+ db9_base[i] = db9_probe(db9[i].args[DB9_ARG_PARPORT],
+ db9[i].args[DB9_ARG_MODE]);
+ if (IS_ERR(db9_base[i])) {
+ err = PTR_ERR(db9_base[i]);
+ break;
+ }
+
+ have_dev = 1;
+ }
- if (db9_base[0] || db9_base[1] || db9_base[2])
- return 0;
+ if (err) {
+ while (--i >= 0)
+ db9_remove(db9_base[i]);
+ return err;
+ }
- return -ENODEV;
+ return have_dev ? 0 : -ENODEV;
}
static void __exit db9_exit(void)
{
- int i, j;
+ int i;
- for (i = 0; i < 3; i++)
- if (db9_base[i]) {
- for (j = 0; j < min(db9_max_pads[db9_base[i]->mode], DB9_MAX_DEVICES); j++)
- input_unregister_device(db9_base[i]->dev + j);
- parport_unregister_device(db9_base[i]->pd);
- }
+ for (i = 0; i < DB9_MAX_PORTS; i++)
+ if (db9_base[i])
+ db9_remove(db9_base[i]);
}
module_init(db9_init);
diff --git a/drivers/input/joystick/gamecon.c b/drivers/input/joystick/gamecon.c
index 5427bf9fc862..7df2d82f2c83 100644
--- a/drivers/input/joystick/gamecon.c
+++ b/drivers/input/joystick/gamecon.c
@@ -41,20 +41,22 @@ MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
MODULE_DESCRIPTION("NES, SNES, N64, MultiSystem, PSX gamepad driver");
MODULE_LICENSE("GPL");
-static int gc[] __initdata = { -1, 0, 0, 0, 0, 0 };
-static int gc_nargs __initdata = 0;
-module_param_array_named(map, gc, int, &gc_nargs, 0);
-MODULE_PARM_DESC(map, "Describers first set of devices (<parport#>,<pad1>,<pad2>,..<pad5>)");
+#define GC_MAX_PORTS 3
+#define GC_MAX_DEVICES 5
-static int gc_2[] __initdata = { -1, 0, 0, 0, 0, 0 };
-static int gc_nargs_2 __initdata = 0;
-module_param_array_named(map2, gc_2, int, &gc_nargs_2, 0);
-MODULE_PARM_DESC(map2, "Describers second set of devices");
+struct gc_config {
+ int args[GC_MAX_DEVICES + 1];
+ int nargs;
+};
+
+static struct gc_config gc[GC_MAX_PORTS] __initdata;
-static int gc_3[] __initdata = { -1, 0, 0, 0, 0, 0 };
-static int gc_nargs_3 __initdata = 0;
-module_param_array_named(map3, gc_3, int, &gc_nargs_3, 0);
-MODULE_PARM_DESC(map3, "Describers third set of devices");
+module_param_array_named(map, gc[0].args, int, &gc[0].nargs, 0);
+MODULE_PARM_DESC(map, "Describes first set of devices (<parport#>,<pad1>,<pad2>,..<pad5>)");
+module_param_array_named(map2, gc[1].args, int, &gc[1].nargs, 0);
+MODULE_PARM_DESC(map2, "Describes second set of devices");
+module_param_array_named(map3, gc[2].args, int, &gc[2].nargs, 0);
+MODULE_PARM_DESC(map3, "Describes third set of devices");
__obsolete_setup("gc=");
__obsolete_setup("gc_2=");
@@ -77,12 +79,12 @@ __obsolete_setup("gc_3=");
struct gc {
struct pardevice *pd;
- struct input_dev dev[5];
+ struct input_dev *dev[GC_MAX_DEVICES];
struct timer_list timer;
unsigned char pads[GC_MAX + 1];
int used;
struct semaphore sem;
- char phys[5][32];
+ char phys[GC_MAX_DEVICES][32];
};
static struct gc *gc_base[3];
@@ -330,7 +332,6 @@ static void gc_psx_read_packet(struct gc *gc, unsigned char data[5][GC_PSX_BYTES
static void gc_timer(unsigned long private)
{
struct gc *gc = (void *) private;
- struct input_dev *dev = gc->dev;
unsigned char data[GC_MAX_LENGTH];
unsigned char data_psx[5][GC_PSX_BYTES];
int i, j, s;
@@ -357,16 +358,16 @@ static void gc_timer(unsigned long private)
if (data[31 - j] & s) axes[1] |= 1 << j;
}
- input_report_abs(dev + i, ABS_X, axes[0]);
- input_report_abs(dev + i, ABS_Y, -axes[1]);
+ input_report_abs(gc->dev[i], ABS_X, axes[0]);
+ input_report_abs(gc->dev[i], ABS_Y, -axes[1]);
- input_report_abs(dev + i, ABS_HAT0X, !(s & data[6]) - !(s & data[7]));
- input_report_abs(dev + i, ABS_HAT0Y, !(s & data[4]) - !(s & data[5]));
+ input_report_abs(gc->dev[i], ABS_HAT0X, !(s & data[6]) - !(s & data[7]));
+ input_report_abs(gc->dev[i], ABS_HAT0Y, !(s & data[4]) - !(s & data[5]));
for (j = 0; j < 10; j++)
- input_report_key(dev + i, gc_n64_btn[j], s & data[gc_n64_bytes[j]]);
+ input_report_key(gc->dev[i], gc_n64_btn[j], s & data[gc_n64_bytes[j]]);
- input_sync(dev + i);
+ input_sync(gc->dev[i]);
}
}
}
@@ -384,19 +385,19 @@ static void gc_timer(unsigned long private)
s = gc_status_bit[i];
if (s & (gc->pads[GC_NES] | gc->pads[GC_SNES])) {
- input_report_abs(dev + i, ABS_X, !(s & data[6]) - !(s & data[7]));
- input_report_abs(dev + i, ABS_Y, !(s & data[4]) - !(s & data[5]));
+ input_report_abs(gc->dev[i], ABS_X, !(s & data[6]) - !(s & data[7]));
+ input_report_abs(gc->dev[i], ABS_Y, !(s & data[4]) - !(s & data[5]));
}
if (s & gc->pads[GC_NES])
for (j = 0; j < 4; j++)
- input_report_key(dev + i, gc_snes_btn[j], s & data[gc_nes_bytes[j]]);
+ input_report_key(gc->dev[i], gc_snes_btn[j], s & data[gc_nes_bytes[j]]);
if (s & gc->pads[GC_SNES])
for (j = 0; j < 8; j++)
- input_report_key(dev + i, gc_snes_btn[j], s & data[gc_snes_bytes[j]]);
+ input_report_key(gc->dev[i], gc_snes_btn[j], s & data[gc_snes_bytes[j]]);
- input_sync(dev + i);
+ input_sync(gc->dev[i]);
}
}
@@ -413,15 +414,15 @@ static void gc_timer(unsigned long private)
s = gc_status_bit[i];
if (s & (gc->pads[GC_MULTI] | gc->pads[GC_MULTI2])) {
- input_report_abs(dev + i, ABS_X, !(s & data[2]) - !(s & data[3]));
- input_report_abs(dev + i, ABS_Y, !(s & data[0]) - !(s & data[1]));
- input_report_key(dev + i, BTN_TRIGGER, s & data[4]);
+ input_report_abs(gc->dev[i], ABS_X, !(s & data[2]) - !(s & data[3]));
+ input_report_abs(gc->dev[i], ABS_Y, !(s & data[0]) - !(s & data[1]));
+ input_report_key(gc->dev[i], BTN_TRIGGER, s & data[4]);
}
if (s & gc->pads[GC_MULTI2])
- input_report_key(dev + i, BTN_THUMB, s & data[5]);
+ input_report_key(gc->dev[i], BTN_THUMB, s & data[5]);
- input_sync(dev + i);
+ input_sync(gc->dev[i]);
}
}
@@ -438,44 +439,44 @@ static void gc_timer(unsigned long private)
case GC_PSX_RUMBLE:
- input_report_key(dev + i, BTN_THUMBL, ~data_psx[i][0] & 0x04);
- input_report_key(dev + i, BTN_THUMBR, ~data_psx[i][0] & 0x02);
+ input_report_key(gc->dev[i], BTN_THUMBL, ~data_psx[i][0] & 0x04);
+ input_report_key(gc->dev[i], BTN_THUMBR, ~data_psx[i][0] & 0x02);
case GC_PSX_NEGCON:
case GC_PSX_ANALOG:
- if(gc->pads[GC_DDR] & gc_status_bit[i]) {
+ if (gc->pads[GC_DDR] & gc_status_bit[i]) {
for(j = 0; j < 4; j++)
- input_report_key(dev + i, gc_psx_ddr_btn[j], ~data_psx[i][0] & (0x10 << j));
+ input_report_key(gc->dev[i], gc_psx_ddr_btn[j], ~data_psx[i][0] & (0x10 << j));
} else {
for (j = 0; j < 4; j++)
- input_report_abs(dev + i, gc_psx_abs[j+2], data_psx[i][j + 2]);
+ input_report_abs(gc->dev[i], gc_psx_abs[j+2], data_psx[i][j + 2]);
- input_report_abs(dev + i, ABS_X, 128 + !(data_psx[i][0] & 0x20) * 127 - !(data_psx[i][0] & 0x80) * 128);
- input_report_abs(dev + i, ABS_Y, 128 + !(data_psx[i][0] & 0x40) * 127 - !(data_psx[i][0] & 0x10) * 128);
+ input_report_abs(gc->dev[i], ABS_X, 128 + !(data_psx[i][0] & 0x20) * 127 - !(data_psx[i][0] & 0x80) * 128);
+ input_report_abs(gc->dev[i], ABS_Y, 128 + !(data_psx[i][0] & 0x40) * 127 - !(data_psx[i][0] & 0x10) * 128);
}
for (j = 0; j < 8; j++)
- input_report_key(dev + i, gc_psx_btn[j], ~data_psx[i][1] & (1 << j));
+ input_report_key(gc->dev[i], gc_psx_btn[j], ~data_psx[i][1] & (1 << j));
- input_report_key(dev + i, BTN_START, ~data_psx[i][0] & 0x08);
- input_report_key(dev + i, BTN_SELECT, ~data_psx[i][0] & 0x01);
+ input_report_key(gc->dev[i], BTN_START, ~data_psx[i][0] & 0x08);
+ input_report_key(gc->dev[i], BTN_SELECT, ~data_psx[i][0] & 0x01);
- input_sync(dev + i);
+ input_sync(gc->dev[i]);
break;
case GC_PSX_NORMAL:
- if(gc->pads[GC_DDR] & gc_status_bit[i]) {
+ if (gc->pads[GC_DDR] & gc_status_bit[i]) {
for(j = 0; j < 4; j++)
- input_report_key(dev + i, gc_psx_ddr_btn[j], ~data_psx[i][0] & (0x10 << j));
+ input_report_key(gc->dev[i], gc_psx_ddr_btn[j], ~data_psx[i][0] & (0x10 << j));
} else {
- input_report_abs(dev + i, ABS_X, 128 + !(data_psx[i][0] & 0x20) * 127 - !(data_psx[i][0] & 0x80) * 128);
- input_report_abs(dev + i, ABS_Y, 128 + !(data_psx[i][0] & 0x40) * 127 - !(data_psx[i][0] & 0x10) * 128);
+ input_report_abs(gc->dev[i], ABS_X, 128 + !(data_psx[i][0] & 0x20) * 127 - !(data_psx[i][0] & 0x80) * 128);
+ input_report_abs(gc->dev[i], ABS_Y, 128 + !(data_psx[i][0] & 0x40) * 127 - !(data_psx[i][0] & 0x10) * 128);
/* for some reason if the extra axes are left unset they drift */
/* for (j = 0; j < 4; j++)
- input_report_abs(dev + i, gc_psx_abs[j+2], 128);
+ input_report_abs(gc->dev[i], gc_psx_abs[j+2], 128);
* This needs to be debugged properly,
* maybe fuzz processing needs to be done in input_sync()
* --vojtech
@@ -483,12 +484,12 @@ static void gc_timer(unsigned long private)
}
for (j = 0; j < 8; j++)
- input_report_key(dev + i, gc_psx_btn[j], ~data_psx[i][1] & (1 << j));
+ input_report_key(gc->dev[i], gc_psx_btn[j], ~data_psx[i][1] & (1 << j));
- input_report_key(dev + i, BTN_START, ~data_psx[i][0] & 0x08);
- input_report_key(dev + i, BTN_SELECT, ~data_psx[i][0] & 0x01);
+ input_report_key(gc->dev[i], BTN_START, ~data_psx[i][0] & 0x08);
+ input_report_key(gc->dev[i], BTN_SELECT, ~data_psx[i][0] & 0x01);
- input_sync(dev + i);
+ input_sync(gc->dev[i]);
break;
@@ -533,177 +534,212 @@ static void gc_close(struct input_dev *dev)
up(&gc->sem);
}
-static struct gc __init *gc_probe(int *config, int nargs)
+static int __init gc_setup_pad(struct gc *gc, int idx, int pad_type)
{
- struct gc *gc;
- struct parport *pp;
- int i, j;
+ struct input_dev *input_dev;
+ int i;
- if (config[0] < 0)
- return NULL;
+ if (!pad_type)
+ return 0;
- if (nargs < 2) {
- printk(KERN_ERR "gamecon.c: at least one device must be specified\n");
- return NULL;
+ if (pad_type < 1 || pad_type > GC_MAX) {
+ printk(KERN_WARNING "gamecon.c: Pad type %d unknown\n", pad_type);
+ return -EINVAL;
}
- pp = parport_find_number(config[0]);
-
- if (!pp) {
- printk(KERN_ERR "gamecon.c: no such parport\n");
- return NULL;
+ gc->dev[idx] = input_dev = input_allocate_device();
+ if (!input_dev) {
+ printk(KERN_ERR "gamecon.c: Not enough memory for input device\n");
+ return -ENOMEM;
}
- if (!(gc = kzalloc(sizeof(struct gc), GFP_KERNEL))) {
- parport_put_port(pp);
- return NULL;
+ input_dev->name = gc_names[pad_type];
+ input_dev->phys = gc->phys[idx];
+ input_dev->id.bustype = BUS_PARPORT;
+ input_dev->id.vendor = 0x0001;
+ input_dev->id.product = pad_type;
+ input_dev->id.version = 0x0100;
+ input_dev->private = gc;
+
+ input_dev->open = gc_open;
+ input_dev->close = gc_close;
+
+ input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+
+ for (i = 0; i < 2; i++)
+ input_set_abs_params(input_dev, ABS_X + i, -1, 1, 0, 0);
+
+ gc->pads[0] |= gc_status_bit[idx];
+ gc->pads[pad_type] |= gc_status_bit[idx];
+
+ switch (pad_type) {
+
+ case GC_N64:
+ for (i = 0; i < 10; i++)
+ set_bit(gc_n64_btn[i], input_dev->keybit);
+
+ for (i = 0; i < 2; i++) {
+ input_set_abs_params(input_dev, ABS_X + i, -127, 126, 0, 2);
+ input_set_abs_params(input_dev, ABS_HAT0X + i, -1, 1, 0, 0);
+ }
+
+ break;
+
+ case GC_SNES:
+ for (i = 4; i < 8; i++)
+ set_bit(gc_snes_btn[i], input_dev->keybit);
+ case GC_NES:
+ for (i = 0; i < 4; i++)
+ set_bit(gc_snes_btn[i], input_dev->keybit);
+ break;
+
+ case GC_MULTI2:
+ set_bit(BTN_THUMB, input_dev->keybit);
+ case GC_MULTI:
+ set_bit(BTN_TRIGGER, input_dev->keybit);
+ break;
+
+ case GC_PSX:
+ for (i = 0; i < 6; i++)
+ input_set_abs_params(input_dev, gc_psx_abs[i], 4, 252, 0, 2);
+ for (i = 0; i < 12; i++)
+ set_bit(gc_psx_btn[i], input_dev->keybit);
+
+ break;
+
+ case GC_DDR:
+ for (i = 0; i < 4; i++)
+ set_bit(gc_psx_ddr_btn[i], input_dev->keybit);
+ for (i = 0; i < 12; i++)
+ set_bit(gc_psx_btn[i], input_dev->keybit);
+
+ break;
}
- init_MUTEX(&gc->sem);
+ return 0;
+}
- gc->pd = parport_register_device(pp, "gamecon", NULL, NULL, NULL, PARPORT_DEV_EXCL, NULL);
+static struct gc __init *gc_probe(int parport, int *pads, int n_pads)
+{
+ struct gc *gc;
+ struct parport *pp;
+ struct pardevice *pd;
+ int i;
+ int err;
- parport_put_port(pp);
+ pp = parport_find_number(parport);
+ if (!pp) {
+ printk(KERN_ERR "gamecon.c: no such parport\n");
+ err = -EINVAL;
+ goto err_out;
+ }
- if (!gc->pd) {
+ pd = parport_register_device(pp, "gamecon", NULL, NULL, NULL, PARPORT_DEV_EXCL, NULL);
+ if (!pd) {
printk(KERN_ERR "gamecon.c: parport busy already - lp.o loaded?\n");
- kfree(gc);
- return NULL;
+ err = -EBUSY;
+ goto err_put_pp;
}
- parport_claim(gc->pd);
+ gc = kzalloc(sizeof(struct gc), GFP_KERNEL);
+ if (!gc) {
+ printk(KERN_ERR "gamecon.c: Not enough memory\n");
+ err = -ENOMEM;
+ goto err_unreg_pardev;
+ }
+ init_MUTEX(&gc->sem);
+ gc->pd = pd;
init_timer(&gc->timer);
gc->timer.data = (long) gc;
gc->timer.function = gc_timer;
- for (i = 0; i < nargs - 1; i++) {
-
- if (!config[i + 1])
+ for (i = 0; i < n_pads; i++) {
+ if (!pads[i])
continue;
- if (config[i + 1] < 1 || config[i + 1] > GC_MAX) {
- printk(KERN_WARNING "gamecon.c: Pad type %d unknown\n", config[i + 1]);
- continue;
- }
-
- gc->dev[i].private = gc;
- gc->dev[i].open = gc_open;
- gc->dev[i].close = gc_close;
+ sprintf(gc->phys[i], "%s/input%d", gc->pd->port->name, i);
+ err = gc_setup_pad(gc, i, pads[i]);
+ if (err)
+ goto err_free_devs;
- gc->dev[i].evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+ input_register_device(gc->dev[i]);
+ }
- for (j = 0; j < 2; j++) {
- set_bit(ABS_X + j, gc->dev[i].absbit);
- gc->dev[i].absmin[ABS_X + j] = -1;
- gc->dev[i].absmax[ABS_X + j] = 1;
- }
+ if (!gc->pads[0]) {
+ printk(KERN_ERR "gamecon.c: No valid devices specified\n");
+ err = -EINVAL;
+ goto err_free_gc;
+ }
- gc->pads[0] |= gc_status_bit[i];
- gc->pads[config[i + 1]] |= gc_status_bit[i];
+ parport_put_port(pp);
+ return gc;
- switch(config[i + 1]) {
+ err_free_devs:
+ while (--i >= 0)
+ input_unregister_device(gc->dev[i]);
+ err_free_gc:
+ kfree(gc);
+ err_unreg_pardev:
+ parport_unregister_device(pd);
+ err_put_pp:
+ parport_put_port(pp);
+ err_out:
+ return ERR_PTR(err);
+}
- case GC_N64:
- for (j = 0; j < 10; j++)
- set_bit(gc_n64_btn[j], gc->dev[i].keybit);
-
- for (j = 0; j < 2; j++) {
- set_bit(ABS_X + j, gc->dev[i].absbit);
- gc->dev[i].absmin[ABS_X + j] = -127;
- gc->dev[i].absmax[ABS_X + j] = 126;
- gc->dev[i].absflat[ABS_X + j] = 2;
- set_bit(ABS_HAT0X + j, gc->dev[i].absbit);
- gc->dev[i].absmin[ABS_HAT0X + j] = -1;
- gc->dev[i].absmax[ABS_HAT0X + j] = 1;
- }
+static void __exit gc_remove(struct gc *gc)
+{
+ int i;
- break;
+ for (i = 0; i < GC_MAX_DEVICES; i++)
+ if (gc->dev[i])
+ input_unregister_device(gc->dev[i]);
+ parport_unregister_device(gc->pd);
+ kfree(gc);
+}
- case GC_SNES:
- for (j = 4; j < 8; j++)
- set_bit(gc_snes_btn[j], gc->dev[i].keybit);
- case GC_NES:
- for (j = 0; j < 4; j++)
- set_bit(gc_snes_btn[j], gc->dev[i].keybit);
- break;
-
- case GC_MULTI2:
- set_bit(BTN_THUMB, gc->dev[i].keybit);
- case GC_MULTI:
- set_bit(BTN_TRIGGER, gc->dev[i].keybit);
- break;
-
- case GC_PSX:
- case GC_DDR:
- if(config[i + 1] == GC_DDR) {
- for (j = 0; j < 4; j++)
- set_bit(gc_psx_ddr_btn[j], gc->dev[i].keybit);
- } else {
- for (j = 0; j < 6; j++) {
- set_bit(gc_psx_abs[j], gc->dev[i].absbit);
- gc->dev[i].absmin[gc_psx_abs[j]] = 4;
- gc->dev[i].absmax[gc_psx_abs[j]] = 252;
- gc->dev[i].absflat[gc_psx_abs[j]] = 2;
- }
- }
+static int __init gc_init(void)
+{
+ int i;
+ int have_dev = 0;
+ int err = 0;
- for (j = 0; j < 12; j++)
- set_bit(gc_psx_btn[j], gc->dev[i].keybit);
+ for (i = 0; i < GC_MAX_PORTS; i++) {
+ if (gc[i].nargs == 0 || gc[i].args[0] < 0)
+ continue;
- break;
+ if (gc[i].nargs < 2) {
+ printk(KERN_ERR "gamecon.c: at least one device must be specified\n");
+ err = -EINVAL;
+ break;
}
- sprintf(gc->phys[i], "%s/input%d", gc->pd->port->name, i);
+ gc_base[i] = gc_probe(gc[i].args[0], gc[i].args + 1, gc[i].nargs - 1);
+ if (IS_ERR(gc_base[i])) {
+ err = PTR_ERR(gc_base[i]);
+ break;
+ }
- gc->dev[i].name = gc_names[config[i + 1]];
- gc->dev[i].phys = gc->phys[i];
- gc->dev[i].id.bustype = BUS_PARPORT;
- gc->dev[i].id.vendor = 0x0001;
- gc->dev[i].id.product = config[i + 1];
- gc->dev[i].id.version = 0x0100;
+ have_dev = 1;
}
- parport_release(gc->pd);
-
- if (!gc->pads[0]) {
- parport_unregister_device(gc->pd);
- kfree(gc);
- return NULL;
+ if (err) {
+ while (--i >= 0)
+ gc_remove(gc_base[i]);
+ return err;
}
- for (i = 0; i < 5; i++)
- if (gc->pads[0] & gc_status_bit[i]) {
- input_register_device(gc->dev + i);
- printk(KERN_INFO "input: %s on %s\n", gc->dev[i].name, gc->pd->port->name);
- }
-
- return gc;
-}
-
-static int __init gc_init(void)
-{
- gc_base[0] = gc_probe(gc, gc_nargs);
- gc_base[1] = gc_probe(gc_2, gc_nargs_2);
- gc_base[2] = gc_probe(gc_3, gc_nargs_3);
-
- if (gc_base[0] || gc_base[1] || gc_base[2])
- return 0;
-
- return -ENODEV;
+ return have_dev ? 0 : -ENODEV;
}
static void __exit gc_exit(void)
{
- int i, j;
-
- for (i = 0; i < 3; i++)
- if (gc_base[i]) {
- for (j = 0; j < 5; j++)
- if (gc_base[i]->pads[0] & gc_status_bit[j])
- input_unregister_device(gc_base[i]->dev + j);
- parport_unregister_device(gc_base[i]->pd);
- }
+ int i;
+
+ for (i = 0; i < GC_MAX_PORTS; i++)
+ if (gc_base[i])
+ gc_remove(gc_base[i]);
}
module_init(gc_init);
diff --git a/drivers/input/joystick/gf2k.c b/drivers/input/joystick/gf2k.c
index 8e4f92b115e6..8a3ad455eb38 100644
--- a/drivers/input/joystick/gf2k.c
+++ b/drivers/input/joystick/gf2k.c
@@ -35,6 +35,7 @@
#include <linux/init.h>
#include <linux/input.h>
#include <linux/gameport.h>
+#include <linux/jiffies.h>
#define DRIVER_DESC "Genius Flight 2000 joystick driver"
@@ -81,7 +82,7 @@ static short gf2k_seq_digital[] = { 590, 320, 860, 0 };
struct gf2k {
struct gameport *gameport;
- struct input_dev dev;
+ struct input_dev *dev;
int reads;
int bads;
unsigned char id;
@@ -175,7 +176,7 @@ static int gf2k_get_bits(unsigned char *buf, int pos, int num, int shift)
static void gf2k_read(struct gf2k *gf2k, unsigned char *data)
{
- struct input_dev *dev = &gf2k->dev;
+ struct input_dev *dev = gf2k->dev;
int i, t;
for (i = 0; i < 4 && i < gf2k_axes[gf2k->id]; i++)
@@ -239,13 +240,19 @@ static void gf2k_close(struct input_dev *dev)
static int gf2k_connect(struct gameport *gameport, struct gameport_driver *drv)
{
struct gf2k *gf2k;
+ struct input_dev *input_dev;
unsigned char data[GF2K_LENGTH];
int i, err;
- if (!(gf2k = kzalloc(sizeof(struct gf2k), GFP_KERNEL)))
- return -ENOMEM;
+ gf2k = kzalloc(sizeof(struct gf2k), GFP_KERNEL);
+ input_dev = input_allocate_device();
+ if (!gf2k || !input_dev) {
+ err = -ENOMEM;
+ goto fail1;
+ }
gf2k->gameport = gameport;
+ gf2k->dev = input_dev;
gameport_set_drvdata(gameport, gf2k);
@@ -295,53 +302,52 @@ static int gf2k_connect(struct gameport *gameport, struct gameport_driver *drv)
gf2k->length = gf2k_lens[gf2k->id];
- init_input_dev(&gf2k->dev);
-
- gf2k->dev.private = gf2k;
- gf2k->dev.open = gf2k_open;
- gf2k->dev.close = gf2k_close;
- gf2k->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+ input_dev->name = gf2k_names[gf2k->id];
+ input_dev->phys = gf2k->phys;
+ input_dev->id.bustype = BUS_GAMEPORT;
+ input_dev->id.vendor = GAMEPORT_ID_VENDOR_GENIUS;
+ input_dev->id.product = gf2k->id;
+ input_dev->id.version = 0x0100;
+ input_dev->cdev.dev = &gameport->dev;
+ input_dev->private = gf2k;
- gf2k->dev.name = gf2k_names[gf2k->id];
- gf2k->dev.phys = gf2k->phys;
- gf2k->dev.id.bustype = BUS_GAMEPORT;
- gf2k->dev.id.vendor = GAMEPORT_ID_VENDOR_GENIUS;
- gf2k->dev.id.product = gf2k->id;
- gf2k->dev.id.version = 0x0100;
+ input_dev->open = gf2k_open;
+ input_dev->close = gf2k_close;
+ input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
for (i = 0; i < gf2k_axes[gf2k->id]; i++)
- set_bit(gf2k_abs[i], gf2k->dev.absbit);
+ set_bit(gf2k_abs[i], input_dev->absbit);
for (i = 0; i < gf2k_hats[gf2k->id]; i++) {
- set_bit(ABS_HAT0X + i, gf2k->dev.absbit);
- gf2k->dev.absmin[ABS_HAT0X + i] = -1;
- gf2k->dev.absmax[ABS_HAT0X + i] = 1;
+ set_bit(ABS_HAT0X + i, input_dev->absbit);
+ input_dev->absmin[ABS_HAT0X + i] = -1;
+ input_dev->absmax[ABS_HAT0X + i] = 1;
}
for (i = 0; i < gf2k_joys[gf2k->id]; i++)
- set_bit(gf2k_btn_joy[i], gf2k->dev.keybit);
+ set_bit(gf2k_btn_joy[i], input_dev->keybit);
for (i = 0; i < gf2k_pads[gf2k->id]; i++)
- set_bit(gf2k_btn_pad[i], gf2k->dev.keybit);
+ set_bit(gf2k_btn_pad[i], input_dev->keybit);
gf2k_read_packet(gameport, gf2k->length, data);
gf2k_read(gf2k, data);
for (i = 0; i < gf2k_axes[gf2k->id]; i++) {
- gf2k->dev.absmax[gf2k_abs[i]] = (i < 2) ? gf2k->dev.abs[gf2k_abs[i]] * 2 - 32 :
- gf2k->dev.abs[gf2k_abs[0]] + gf2k->dev.abs[gf2k_abs[1]] - 32;
- gf2k->dev.absmin[gf2k_abs[i]] = 32;
- gf2k->dev.absfuzz[gf2k_abs[i]] = 8;
- gf2k->dev.absflat[gf2k_abs[i]] = (i < 2) ? 24 : 0;
+ input_dev->absmax[gf2k_abs[i]] = (i < 2) ? input_dev->abs[gf2k_abs[i]] * 2 - 32 :
+ input_dev->abs[gf2k_abs[0]] + input_dev->abs[gf2k_abs[1]] - 32;
+ input_dev->absmin[gf2k_abs[i]] = 32;
+ input_dev->absfuzz[gf2k_abs[i]] = 8;
+ input_dev->absflat[gf2k_abs[i]] = (i < 2) ? 24 : 0;
}
- input_register_device(&gf2k->dev);
- printk(KERN_INFO "input: %s on %s\n", gf2k_names[gf2k->id], gameport->phys);
+ input_register_device(gf2k->dev);
return 0;
-fail2: gameport_close(gameport);
-fail1: gameport_set_drvdata(gameport, NULL);
+ fail2: gameport_close(gameport);
+ fail1: gameport_set_drvdata(gameport, NULL);
+ input_free_device(input_dev);
kfree(gf2k);
return err;
}
@@ -350,7 +356,7 @@ static void gf2k_disconnect(struct gameport *gameport)
{
struct gf2k *gf2k = gameport_get_drvdata(gameport);
- input_unregister_device(&gf2k->dev);
+ input_unregister_device(gf2k->dev);
gameport_close(gameport);
gameport_set_drvdata(gameport, NULL);
kfree(gf2k);
diff --git a/drivers/input/joystick/grip.c b/drivers/input/joystick/grip.c
index 9d3f910dd568..a936e7aedb10 100644
--- a/drivers/input/joystick/grip.c
+++ b/drivers/input/joystick/grip.c
@@ -34,6 +34,7 @@
#include <linux/slab.h>
#include <linux/gameport.h>
#include <linux/input.h>
+#include <linux/jiffies.h>
#define DRIVER_DESC "Gravis GrIP protocol joystick driver"
@@ -55,7 +56,7 @@ MODULE_LICENSE("GPL");
struct grip {
struct gameport *gameport;
- struct input_dev dev[2];
+ struct input_dev *dev[2];
unsigned char mode[2];
int reads;
int bads;
@@ -190,7 +191,7 @@ static void grip_poll(struct gameport *gameport)
for (i = 0; i < 2; i++) {
- dev = grip->dev + i;
+ dev = grip->dev[i];
grip->reads++;
switch (grip->mode[i]) {
@@ -297,6 +298,7 @@ static void grip_close(struct input_dev *dev)
static int grip_connect(struct gameport *gameport, struct gameport_driver *drv)
{
struct grip *grip;
+ struct input_dev *input_dev;
unsigned int data[GRIP_LENGTH_XT];
int i, j, t;
int err;
@@ -339,48 +341,56 @@ static int grip_connect(struct gameport *gameport, struct gameport_driver *drv)
gameport_set_poll_handler(gameport, grip_poll);
gameport_set_poll_interval(gameport, 20);
- for (i = 0; i < 2; i++)
- if (grip->mode[i]) {
+ for (i = 0; i < 2; i++) {
+ if (!grip->mode[i])
+ continue;
- sprintf(grip->phys[i], "%s/input%d", gameport->phys, i);
+ grip->dev[i] = input_dev = input_allocate_device();
+ if (!input_dev) {
+ err = -ENOMEM;
+ goto fail3;
+ }
- grip->dev[i].private = grip;
+ sprintf(grip->phys[i], "%s/input%d", gameport->phys, i);
- grip->dev[i].open = grip_open;
- grip->dev[i].close = grip_close;
+ input_dev->name = grip_name[grip->mode[i]];
+ input_dev->phys = grip->phys[i];
+ input_dev->id.bustype = BUS_GAMEPORT;
+ input_dev->id.vendor = GAMEPORT_ID_VENDOR_GRAVIS;
+ input_dev->id.product = grip->mode[i];
+ input_dev->id.version = 0x0100;
+ input_dev->cdev.dev = &gameport->dev;
+ input_dev->private = grip;
- grip->dev[i].name = grip_name[grip->mode[i]];
- grip->dev[i].phys = grip->phys[i];
- grip->dev[i].id.bustype = BUS_GAMEPORT;
- grip->dev[i].id.vendor = GAMEPORT_ID_VENDOR_GRAVIS;
- grip->dev[i].id.product = grip->mode[i];
- grip->dev[i].id.version = 0x0100;
+ input_dev->open = grip_open;
+ input_dev->close = grip_close;
- grip->dev[i].evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+ input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
- for (j = 0; (t = grip_abs[grip->mode[i]][j]) >= 0; j++) {
+ for (j = 0; (t = grip_abs[grip->mode[i]][j]) >= 0; j++) {
- if (j < grip_cen[grip->mode[i]])
- input_set_abs_params(&grip->dev[i], t, 14, 52, 1, 2);
- else if (j < grip_anx[grip->mode[i]])
- input_set_abs_params(&grip->dev[i], t, 3, 57, 1, 0);
- else
- input_set_abs_params(&grip->dev[i], t, -1, 1, 0, 0);
- }
+ if (j < grip_cen[grip->mode[i]])
+ input_set_abs_params(input_dev, t, 14, 52, 1, 2);
+ else if (j < grip_anx[grip->mode[i]])
+ input_set_abs_params(input_dev, t, 3, 57, 1, 0);
+ else
+ input_set_abs_params(input_dev, t, -1, 1, 0, 0);
+ }
- for (j = 0; (t = grip_btn[grip->mode[i]][j]) >= 0; j++)
- if (t > 0)
- set_bit(t, grip->dev[i].keybit);
+ for (j = 0; (t = grip_btn[grip->mode[i]][j]) >= 0; j++)
+ if (t > 0)
+ set_bit(t, input_dev->keybit);
- printk(KERN_INFO "input: %s on %s\n",
- grip_name[grip->mode[i]], gameport->phys);
- input_register_device(grip->dev + i);
- }
+ input_register_device(grip->dev[i]);
+ }
return 0;
-fail2: gameport_close(gameport);
-fail1: gameport_set_drvdata(gameport, NULL);
+ fail3: for (i = 0; i < 2; i++)
+ if (grip->dev[i])
+ input_unregister_device(grip->dev[i]);
+ fail2: gameport_close(gameport);
+ fail1: gameport_set_drvdata(gameport, NULL);
kfree(grip);
return err;
}
@@ -391,8 +401,8 @@ static void grip_disconnect(struct gameport *gameport)
int i;
for (i = 0; i < 2; i++)
- if (grip->mode[i])
- input_unregister_device(grip->dev + i);
+ if (grip->dev[i])
+ input_unregister_device(grip->dev[i]);
gameport_close(gameport);
gameport_set_drvdata(gameport, NULL);
kfree(grip);
diff --git a/drivers/input/joystick/grip_mp.c b/drivers/input/joystick/grip_mp.c
index da17eee6f574..51a912222e85 100644
--- a/drivers/input/joystick/grip_mp.c
+++ b/drivers/input/joystick/grip_mp.c
@@ -19,6 +19,7 @@
#include <linux/input.h>
#include <linux/delay.h>
#include <linux/proc_fs.h>
+#include <linux/jiffies.h>
#define DRIVER_DESC "Gravis Grip Multiport driver"
@@ -32,23 +33,37 @@ MODULE_LICENSE("GPL");
#define dbg(format, arg...) do {} while (0)
#endif
+#define GRIP_MAX_PORTS 4
/*
* Grip multiport state
*/
+struct grip_port {
+ struct input_dev *dev;
+ int mode;
+ int registered;
+
+ /* individual gamepad states */
+ int buttons;
+ int xaxes;
+ int yaxes;
+ int dirty; /* has the state been updated? */
+};
+
struct grip_mp {
struct gameport *gameport;
- struct input_dev dev[4];
- int mode[4];
- int registered[4];
+ struct grip_port *port[GRIP_MAX_PORTS];
+// struct input_dev *dev[4];
+// int mode[4];
+// int registered[4];
int reads;
int bads;
/* individual gamepad states */
- int buttons[4];
- int xaxes[4];
- int yaxes[4];
- int dirty[4]; /* has the state been updated? */
+// int buttons[4];
+// int xaxes[4];
+// int yaxes[4];
+// int dirty[4]; /* has the state been updated? */
};
/*
@@ -85,16 +100,16 @@ struct grip_mp {
#define GRIP_MODE_GP 2
#define GRIP_MODE_C64 3
-static int grip_btn_gp[] = { BTN_TR, BTN_TL, BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z, -1 };
-static int grip_btn_c64[] = { BTN_JOYSTICK, -1 };
+static const int grip_btn_gp[] = { BTN_TR, BTN_TL, BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z, -1 };
+static const int grip_btn_c64[] = { BTN_JOYSTICK, -1 };
-static int grip_abs_gp[] = { ABS_X, ABS_Y, -1 };
-static int grip_abs_c64[] = { ABS_X, ABS_Y, -1 };
+static const int grip_abs_gp[] = { ABS_X, ABS_Y, -1 };
+static const int grip_abs_c64[] = { ABS_X, ABS_Y, -1 };
-static int *grip_abs[] = { NULL, NULL, grip_abs_gp, grip_abs_c64 };
-static int *grip_btn[] = { NULL, NULL, grip_btn_gp, grip_btn_c64 };
+static const int *grip_abs[] = { NULL, NULL, grip_abs_gp, grip_abs_c64 };
+static const int *grip_btn[] = { NULL, NULL, grip_btn_gp, grip_btn_c64 };
-static char *grip_name[] = { NULL, NULL, "Gravis Grip Pad", "Commodore 64 Joystick" };
+static const char *grip_name[] = { NULL, NULL, "Gravis Grip Pad", "Commodore 64 Joystick" };
static const int init_seq[] = {
1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1,
@@ -104,9 +119,9 @@ static const int init_seq[] = {
/* Maps multiport directional values to X,Y axis values (each axis encoded in 3 bits) */
-static int axis_map[] = { 5, 9, 1, 5, 6, 10, 2, 6, 4, 8, 0, 4, 5, 9, 1, 5 };
+static const int axis_map[] = { 5, 9, 1, 5, 6, 10, 2, 6, 4, 8, 0, 4, 5, 9, 1, 5 };
-static void register_slot(int i, struct grip_mp *grip);
+static int register_slot(int i, struct grip_mp *grip);
/*
* Returns whether an odd or even number of bits are on in pkt.
@@ -353,9 +368,10 @@ static int dig_mode_start(struct gameport *gameport, u32 *packet)
static int get_and_decode_packet(struct grip_mp *grip, int flags)
{
+ struct grip_port *port;
u32 packet;
int joytype = 0;
- int slot = 0;
+ int slot;
/* Get a packet and check for validity */
@@ -377,6 +393,8 @@ static int get_and_decode_packet(struct grip_mp *grip, int flags)
if ((slot < 0) || (slot > 3))
return flags;
+ port = grip->port[slot];
+
/*
* Handle "reset" packets, which occur at startup, and when gamepads
* are removed or plugged in. May contain configuration of a new gamepad.
@@ -385,14 +403,14 @@ static int get_and_decode_packet(struct grip_mp *grip, int flags)
joytype = (packet >> 16) & 0x1f;
if (!joytype) {
- if (grip->registered[slot]) {
+ if (port->registered) {
printk(KERN_INFO "grip_mp: removing %s, slot %d\n",
- grip_name[grip->mode[slot]], slot);
- input_unregister_device(grip->dev + slot);
- grip->registered[slot] = 0;
+ grip_name[port->mode], slot);
+ input_unregister_device(port->dev);
+ port->registered = 0;
}
dbg("Reset: grip multiport slot %d\n", slot);
- grip->mode[slot] = GRIP_MODE_RESET;
+ port->mode = GRIP_MODE_RESET;
flags |= IO_SLOT_CHANGE;
return flags;
}
@@ -402,17 +420,17 @@ static int get_and_decode_packet(struct grip_mp *grip, int flags)
if (joytype == 0x1f) {
int dir = (packet >> 8) & 0xf; /* eight way directional value */
- grip->buttons[slot] = (~packet) & 0xff;
- grip->yaxes[slot] = ((axis_map[dir] >> 2) & 3) - 1;
- grip->xaxes[slot] = (axis_map[dir] & 3) - 1;
- grip->dirty[slot] = 1;
+ port->buttons = (~packet) & 0xff;
+ port->yaxes = ((axis_map[dir] >> 2) & 3) - 1;
+ port->xaxes = (axis_map[dir] & 3) - 1;
+ port->dirty = 1;
- if (grip->mode[slot] == GRIP_MODE_RESET)
+ if (port->mode == GRIP_MODE_RESET)
flags |= IO_SLOT_CHANGE;
- grip->mode[slot] = GRIP_MODE_GP;
+ port->mode = GRIP_MODE_GP;
- if (!grip->registered[slot]) {
+ if (!port->registered) {
dbg("New Grip pad in multiport slot %d.\n", slot);
register_slot(slot, grip);
}
@@ -445,9 +463,9 @@ static int slots_valid(struct grip_mp *grip)
return 0;
for (slot = 0; slot < 4; slot++) {
- if (grip->mode[slot] == GRIP_MODE_RESET)
+ if (grip->port[slot]->mode == GRIP_MODE_RESET)
invalid = 1;
- if (grip->mode[slot] != GRIP_MODE_NONE)
+ if (grip->port[slot]->mode != GRIP_MODE_NONE)
active = 1;
}
@@ -484,7 +502,7 @@ static int multiport_init(struct grip_mp *grip)
/* Get packets, store multiport state, and check state's validity */
for (tries = 0; tries < 4096; tries++) {
- if ( slots_valid(grip) ) {
+ if (slots_valid(grip)) {
initialized = 1;
break;
}
@@ -499,24 +517,24 @@ static int multiport_init(struct grip_mp *grip)
static void report_slot(struct grip_mp *grip, int slot)
{
- struct input_dev *dev = &(grip->dev[slot]);
- int i, buttons = grip->buttons[slot];
+ struct grip_port *port = grip->port[slot];
+ int i;
/* Store button states with linux input driver */
for (i = 0; i < 8; i++)
- input_report_key(dev, grip_btn_gp[i], (buttons >> i) & 1);
+ input_report_key(port->dev, grip_btn_gp[i], (port->buttons >> i) & 1);
/* Store axis states with linux driver */
- input_report_abs(dev, ABS_X, grip->xaxes[slot]);
- input_report_abs(dev, ABS_Y, grip->yaxes[slot]);
+ input_report_abs(port->dev, ABS_X, port->xaxes);
+ input_report_abs(port->dev, ABS_Y, port->yaxes);
/* Tell the receiver of the events to process them */
- input_sync(dev);
+ input_sync(port->dev);
- grip->dirty[slot] = 0;
+ port->dirty = 0;
}
/*
@@ -540,7 +558,7 @@ static void grip_poll(struct gameport *gameport)
}
for (i = 0; i < 4; i++)
- if (grip->dirty[i])
+ if (grip->port[i]->dirty)
report_slot(grip, i);
}
@@ -571,35 +589,43 @@ static void grip_close(struct input_dev *dev)
* Tell the linux input layer about a newly plugged-in gamepad.
*/
-static void register_slot(int slot, struct grip_mp *grip)
+static int register_slot(int slot, struct grip_mp *grip)
{
+ struct grip_port *port = grip->port[slot];
+ struct input_dev *input_dev;
int j, t;
- grip->dev[slot].private = grip;
- grip->dev[slot].open = grip_open;
- grip->dev[slot].close = grip_close;
- grip->dev[slot].name = grip_name[grip->mode[slot]];
- grip->dev[slot].id.bustype = BUS_GAMEPORT;
- grip->dev[slot].id.vendor = GAMEPORT_ID_VENDOR_GRAVIS;
- grip->dev[slot].id.product = 0x0100 + grip->mode[slot];
- grip->dev[slot].id.version = 0x0100;
- grip->dev[slot].evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+ port->dev = input_dev = input_allocate_device();
+ if (!input_dev)
+ return -ENOMEM;
+
+ input_dev->name = grip_name[port->mode];
+ input_dev->id.bustype = BUS_GAMEPORT;
+ input_dev->id.vendor = GAMEPORT_ID_VENDOR_GRAVIS;
+ input_dev->id.product = 0x0100 + port->mode;
+ input_dev->id.version = 0x0100;
+ input_dev->cdev.dev = &grip->gameport->dev;
+ input_dev->private = grip;
+
+ input_dev->open = grip_open;
+ input_dev->close = grip_close;
- for (j = 0; (t = grip_abs[grip->mode[slot]][j]) >= 0; j++)
- input_set_abs_params(&grip->dev[slot], t, -1, 1, 0, 0);
+ input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
- for (j = 0; (t = grip_btn[grip->mode[slot]][j]) >= 0; j++)
+ for (j = 0; (t = grip_abs[port->mode][j]) >= 0; j++)
+ input_set_abs_params(input_dev, t, -1, 1, 0, 0);
+
+ for (j = 0; (t = grip_btn[port->mode][j]) >= 0; j++)
if (t > 0)
- set_bit(t, grip->dev[slot].keybit);
+ set_bit(t, input_dev->keybit);
- input_register_device(grip->dev + slot);
- grip->registered[slot] = 1;
+ input_register_device(port->dev);
+ port->registered = 1;
- if (grip->dirty[slot]) /* report initial state, if any */
+ if (port->dirty) /* report initial state, if any */
report_slot(grip, slot);
- printk(KERN_INFO "grip_mp: added %s, slot %d\n",
- grip_name[grip->mode[slot]], slot);
+ return 0;
}
static int grip_connect(struct gameport *gameport, struct gameport_driver *drv)
@@ -626,7 +652,7 @@ static int grip_connect(struct gameport *gameport, struct gameport_driver *drv)
goto fail2;
}
- if (!grip->mode[0] && !grip->mode[1] && !grip->mode[2] && !grip->mode[3]) {
+ if (!grip->port[0]->mode && !grip->port[1]->mode && !grip->port[2]->mode && !grip->port[3]->mode) {
/* nothing plugged in */
err = -ENODEV;
goto fail2;
@@ -646,8 +672,8 @@ static void grip_disconnect(struct gameport *gameport)
int i;
for (i = 0; i < 4; i++)
- if (grip->registered[i])
- input_unregister_device(grip->dev + i);
+ if (grip->port[i]->registered)
+ input_unregister_device(grip->port[i]->dev);
gameport_close(gameport);
gameport_set_drvdata(gameport, NULL);
kfree(grip);
diff --git a/drivers/input/joystick/guillemot.c b/drivers/input/joystick/guillemot.c
index 6a70ec429f06..6e2c721c26ba 100644
--- a/drivers/input/joystick/guillemot.c
+++ b/drivers/input/joystick/guillemot.c
@@ -35,6 +35,7 @@
#include <linux/init.h>
#include <linux/gameport.h>
#include <linux/input.h>
+#include <linux/jiffies.h>
#define DRIVER_DESC "Guillemot Digital joystick driver"
@@ -67,7 +68,7 @@ struct guillemot_type {
struct guillemot {
struct gameport *gameport;
- struct input_dev dev;
+ struct input_dev *dev;
int bads;
int reads;
struct guillemot_type *type;
@@ -123,7 +124,7 @@ static int guillemot_read_packet(struct gameport *gameport, u8 *data)
static void guillemot_poll(struct gameport *gameport)
{
struct guillemot *guillemot = gameport_get_drvdata(gameport);
- struct input_dev *dev = &guillemot->dev;
+ struct input_dev *dev = guillemot->dev;
u8 data[GUILLEMOT_MAX_LENGTH];
int i;
@@ -179,14 +180,20 @@ static void guillemot_close(struct input_dev *dev)
static int guillemot_connect(struct gameport *gameport, struct gameport_driver *drv)
{
struct guillemot *guillemot;
+ struct input_dev *input_dev;
u8 data[GUILLEMOT_MAX_LENGTH];
int i, t;
int err;
- if (!(guillemot = kzalloc(sizeof(struct guillemot), GFP_KERNEL)))
- return -ENOMEM;
+ guillemot = kzalloc(sizeof(struct guillemot), GFP_KERNEL);
+ input_dev = input_allocate_device();
+ if (!guillemot || !input_dev) {
+ err = -ENOMEM;
+ goto fail1;
+ }
guillemot->gameport = gameport;
+ guillemot->dev = input_dev;
gameport_set_drvdata(gameport, guillemot);
@@ -216,41 +223,40 @@ static int guillemot_connect(struct gameport *gameport, struct gameport_driver *
gameport_set_poll_interval(gameport, 20);
sprintf(guillemot->phys, "%s/input0", gameport->phys);
-
guillemot->type = guillemot_type + i;
- guillemot->dev.private = guillemot;
- guillemot->dev.open = guillemot_open;
- guillemot->dev.close = guillemot_close;
+ input_dev->name = guillemot_type[i].name;
+ input_dev->phys = guillemot->phys;
+ input_dev->id.bustype = BUS_GAMEPORT;
+ input_dev->id.vendor = GAMEPORT_ID_VENDOR_GUILLEMOT;
+ input_dev->id.product = guillemot_type[i].id;
+ input_dev->id.version = (int)data[14] << 8 | data[15];
+ input_dev->cdev.dev = &gameport->dev;
+ input_dev->private = guillemot;
- guillemot->dev.name = guillemot_type[i].name;
- guillemot->dev.phys = guillemot->phys;
- guillemot->dev.id.bustype = BUS_GAMEPORT;
- guillemot->dev.id.vendor = GAMEPORT_ID_VENDOR_GUILLEMOT;
- guillemot->dev.id.product = guillemot_type[i].id;
- guillemot->dev.id.version = (int)data[14] << 8 | data[15];
+ input_dev->open = guillemot_open;
+ input_dev->close = guillemot_close;
- guillemot->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+ input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
for (i = 0; (t = guillemot->type->abs[i]) >= 0; i++)
- input_set_abs_params(&guillemot->dev, t, 0, 255, 0, 0);
+ input_set_abs_params(input_dev, t, 0, 255, 0, 0);
if (guillemot->type->hat) {
- input_set_abs_params(&guillemot->dev, ABS_HAT0X, -1, 1, 0, 0);
- input_set_abs_params(&guillemot->dev, ABS_HAT0Y, -1, 1, 0, 0);
+ input_set_abs_params(input_dev, ABS_HAT0X, -1, 1, 0, 0);
+ input_set_abs_params(input_dev, ABS_HAT0Y, -1, 1, 0, 0);
}
for (i = 0; (t = guillemot->type->btn[i]) >= 0; i++)
- set_bit(t, guillemot->dev.keybit);
+ set_bit(t, input_dev->keybit);
- input_register_device(&guillemot->dev);
- printk(KERN_INFO "input: %s ver %d.%02d on %s\n",
- guillemot->type->name, data[14], data[15], gameport->phys);
+ input_register_device(guillemot->dev);
return 0;
fail2: gameport_close(gameport);
fail1: gameport_set_drvdata(gameport, NULL);
+ input_free_device(input_dev);
kfree(guillemot);
return err;
}
@@ -260,7 +266,7 @@ static void guillemot_disconnect(struct gameport *gameport)
struct guillemot *guillemot = gameport_get_drvdata(gameport);
printk(KERN_INFO "guillemot.c: Failed %d reads out of %d on %s\n", guillemot->reads, guillemot->bads, guillemot->phys);
- input_unregister_device(&guillemot->dev);
+ input_unregister_device(guillemot->dev);
gameport_close(gameport);
kfree(guillemot);
}
diff --git a/drivers/input/joystick/iforce/iforce-main.c b/drivers/input/joystick/iforce/iforce-main.c
index e31b7b93fde2..64b9c31c47fc 100644
--- a/drivers/input/joystick/iforce/iforce-main.c
+++ b/drivers/input/joystick/iforce/iforce-main.c
@@ -144,7 +144,7 @@ static int iforce_upload_effect(struct input_dev *dev, struct ff_effect *effect)
int is_update;
/* Check this effect type is supported by this device */
- if (!test_bit(effect->type, iforce->dev.ffbit))
+ if (!test_bit(effect->type, iforce->dev->ffbit))
return -EINVAL;
/*
@@ -152,30 +152,31 @@ static int iforce_upload_effect(struct input_dev *dev, struct ff_effect *effect)
*/
if (effect->id == -1) {
- for (id=0; id < FF_EFFECTS_MAX; ++id)
- if (!test_and_set_bit(FF_CORE_IS_USED, iforce->core_effects[id].flags)) break;
+ for (id = 0; id < FF_EFFECTS_MAX; ++id)
+ if (!test_and_set_bit(FF_CORE_IS_USED, iforce->core_effects[id].flags))
+ break;
- if ( id == FF_EFFECTS_MAX || id >= iforce->dev.ff_effects_max)
+ if (id == FF_EFFECTS_MAX || id >= iforce->dev->ff_effects_max)
return -ENOMEM;
effect->id = id;
iforce->core_effects[id].owner = current->pid;
- iforce->core_effects[id].flags[0] = (1<<FF_CORE_IS_USED); /* Only IS_USED bit must be set */
+ iforce->core_effects[id].flags[0] = (1 << FF_CORE_IS_USED); /* Only IS_USED bit must be set */
is_update = FALSE;
}
else {
/* We want to update an effect */
- if (!CHECK_OWNERSHIP(effect->id, iforce)) return -EACCES;
+ if (!CHECK_OWNERSHIP(effect->id, iforce))
+ return -EACCES;
/* Parameter type cannot be updated */
if (effect->type != iforce->core_effects[effect->id].effect.type)
return -EINVAL;
/* Check the effect is not already being updated */
- if (test_bit(FF_CORE_UPDATE, iforce->core_effects[effect->id].flags)) {
+ if (test_bit(FF_CORE_UPDATE, iforce->core_effects[effect->id].flags))
return -EAGAIN;
- }
is_update = TRUE;
}
@@ -339,15 +340,19 @@ void iforce_delete_device(struct iforce *iforce)
int iforce_init_device(struct iforce *iforce)
{
+ struct input_dev *input_dev;
unsigned char c[] = "CEOV";
int i;
+ input_dev = input_allocate_device();
+ if (input_dev)
+ return -ENOMEM;
+
init_waitqueue_head(&iforce->wait);
spin_lock_init(&iforce->xmit_lock);
init_MUTEX(&iforce->mem_mutex);
iforce->xmit.buf = iforce->xmit_data;
-
- iforce->dev.ff_effects_max = 10;
+ iforce->dev = input_dev;
/*
* Input device fields.
@@ -356,26 +361,27 @@ int iforce_init_device(struct iforce *iforce)
switch (iforce->bus) {
#ifdef CONFIG_JOYSTICK_IFORCE_USB
case IFORCE_USB:
- iforce->dev.id.bustype = BUS_USB;
- iforce->dev.dev = &iforce->usbdev->dev;
+ input_dev->id.bustype = BUS_USB;
+ input_dev->cdev.dev = &iforce->usbdev->dev;
break;
#endif
#ifdef CONFIG_JOYSTICK_IFORCE_232
case IFORCE_232:
- iforce->dev.id.bustype = BUS_RS232;
- iforce->dev.dev = &iforce->serio->dev;
+ input_dev->id.bustype = BUS_RS232;
+ input_dev->cdev.dev = &iforce->serio->dev;
break;
#endif
}
- iforce->dev.private = iforce;
- iforce->dev.name = "Unknown I-Force device";
- iforce->dev.open = iforce_open;
- iforce->dev.close = iforce_release;
- iforce->dev.flush = iforce_flush;
- iforce->dev.event = iforce_input_event;
- iforce->dev.upload_effect = iforce_upload_effect;
- iforce->dev.erase_effect = iforce_erase_effect;
+ input_dev->private = iforce;
+ input_dev->name = "Unknown I-Force device";
+ input_dev->open = iforce_open;
+ input_dev->close = iforce_release;
+ input_dev->flush = iforce_flush;
+ input_dev->event = iforce_input_event;
+ input_dev->upload_effect = iforce_upload_effect;
+ input_dev->erase_effect = iforce_erase_effect;
+ input_dev->ff_effects_max = 10;
/*
* On-device memory allocation.
@@ -399,7 +405,8 @@ int iforce_init_device(struct iforce *iforce)
if (i == 20) { /* 5 seconds */
printk(KERN_ERR "iforce-main.c: Timeout waiting for response from device.\n");
- return -1;
+ input_free_device(input_dev);
+ return -ENODEV;
}
/*
@@ -407,12 +414,12 @@ int iforce_init_device(struct iforce *iforce)
*/
if (!iforce_get_id_packet(iforce, "M"))
- iforce->dev.id.vendor = (iforce->edata[2] << 8) | iforce->edata[1];
+ input_dev->id.vendor = (iforce->edata[2] << 8) | iforce->edata[1];
else
printk(KERN_WARNING "iforce-main.c: Device does not respond to id packet M\n");
if (!iforce_get_id_packet(iforce, "P"))
- iforce->dev.id.product = (iforce->edata[2] << 8) | iforce->edata[1];
+ input_dev->id.product = (iforce->edata[2] << 8) | iforce->edata[1];
else
printk(KERN_WARNING "iforce-main.c: Device does not respond to id packet P\n");
@@ -422,15 +429,15 @@ int iforce_init_device(struct iforce *iforce)
printk(KERN_WARNING "iforce-main.c: Device does not respond to id packet B\n");
if (!iforce_get_id_packet(iforce, "N"))
- iforce->dev.ff_effects_max = iforce->edata[1];
+ iforce->dev->ff_effects_max = iforce->edata[1];
else
printk(KERN_WARNING "iforce-main.c: Device does not respond to id packet N\n");
/* Check if the device can store more effects than the driver can really handle */
- if (iforce->dev.ff_effects_max > FF_EFFECTS_MAX) {
+ if (iforce->dev->ff_effects_max > FF_EFFECTS_MAX) {
printk(KERN_WARNING "input??: Device can handle %d effects, but N_EFFECTS_MAX is set to %d in iforce.h\n",
- iforce->dev.ff_effects_max, FF_EFFECTS_MAX);
- iforce->dev.ff_effects_max = FF_EFFECTS_MAX;
+ iforce->dev->ff_effects_max, FF_EFFECTS_MAX);
+ iforce->dev->ff_effects_max = FF_EFFECTS_MAX;
}
/*
@@ -453,29 +460,28 @@ int iforce_init_device(struct iforce *iforce)
*/
for (i = 0; iforce_device[i].idvendor; i++)
- if (iforce_device[i].idvendor == iforce->dev.id.vendor &&
- iforce_device[i].idproduct == iforce->dev.id.product)
+ if (iforce_device[i].idvendor == input_dev->id.vendor &&
+ iforce_device[i].idproduct == input_dev->id.product)
break;
iforce->type = iforce_device + i;
- iforce->dev.name = iforce->type->name;
+ input_dev->name = iforce->type->name;
/*
* Set input device bitfields and ranges.
*/
- iforce->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS) | BIT(EV_FF) | BIT(EV_FF_STATUS);
+ input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS) | BIT(EV_FF) | BIT(EV_FF_STATUS);
for (i = 0; iforce->type->btn[i] >= 0; i++) {
signed short t = iforce->type->btn[i];
- set_bit(t, iforce->dev.keybit);
+ set_bit(t, input_dev->keybit);
}
- set_bit(BTN_DEAD, iforce->dev.keybit);
+ set_bit(BTN_DEAD, input_dev->keybit);
for (i = 0; iforce->type->abs[i] >= 0; i++) {
signed short t = iforce->type->abs[i];
- set_bit(t, iforce->dev.absbit);
switch (t) {
@@ -483,52 +489,42 @@ int iforce_init_device(struct iforce *iforce)
case ABS_Y:
case ABS_WHEEL:
- iforce->dev.absmax[t] = 1920;
- iforce->dev.absmin[t] = -1920;
- iforce->dev.absflat[t] = 128;
- iforce->dev.absfuzz[t] = 16;
-
- set_bit(t, iforce->dev.ffbit);
+ input_set_abs_params(input_dev, t, -1920, 1920, 16, 128);
+ set_bit(t, input_dev->ffbit);
break;
case ABS_THROTTLE:
case ABS_GAS:
case ABS_BRAKE:
- iforce->dev.absmax[t] = 255;
- iforce->dev.absmin[t] = 0;
+ input_set_abs_params(input_dev, t, 0, 255, 0, 0);
break;
case ABS_RUDDER:
- iforce->dev.absmax[t] = 127;
- iforce->dev.absmin[t] = -128;
+ input_set_abs_params(input_dev, t, -128, 127, 0, 0);
break;
case ABS_HAT0X:
case ABS_HAT0Y:
case ABS_HAT1X:
case ABS_HAT1Y:
- iforce->dev.absmax[t] = 1;
- iforce->dev.absmin[t] = -1;
+
+ input_set_abs_params(input_dev, t, -1, 1, 0, 0);
break;
}
}
for (i = 0; iforce->type->ff[i] >= 0; i++)
- set_bit(iforce->type->ff[i], iforce->dev.ffbit);
+ set_bit(iforce->type->ff[i], input_dev->ffbit);
/*
* Register input device.
*/
- input_register_device(&iforce->dev);
-
- printk(KERN_DEBUG "iforce->dev.open = %p\n", iforce->dev.open);
+ input_register_device(iforce->dev);
- printk(KERN_INFO "input: %s [%d effects, %ld bytes memory]\n",
- iforce->dev.name, iforce->dev.ff_effects_max,
- iforce->device_memory.end);
+ printk(KERN_DEBUG "iforce->dev->open = %p\n", iforce->dev->open);
return 0;
}
diff --git a/drivers/input/joystick/iforce/iforce-packets.c b/drivers/input/joystick/iforce/iforce-packets.c
index e5a31e55d3e2..4a2629243e19 100644
--- a/drivers/input/joystick/iforce/iforce-packets.c
+++ b/drivers/input/joystick/iforce/iforce-packets.c
@@ -139,7 +139,8 @@ printk(KERN_DEBUG "iforce-packets.c: control_playback %d %d\n", id, value);
static int mark_core_as_ready(struct iforce *iforce, unsigned short addr)
{
int i;
- for (i=0; i<iforce->dev.ff_effects_max; ++i) {
+
+ for (i = 0; i < iforce->dev->ff_effects_max; ++i) {
if (test_bit(FF_CORE_IS_USED, iforce->core_effects[i].flags) &&
(iforce->core_effects[i].mod1_chunk.start == addr ||
iforce->core_effects[i].mod2_chunk.start == addr)) {
@@ -153,7 +154,7 @@ static int mark_core_as_ready(struct iforce *iforce, unsigned short addr)
void iforce_process_packet(struct iforce *iforce, u16 cmd, unsigned char *data, struct pt_regs *regs)
{
- struct input_dev *dev = &iforce->dev;
+ struct input_dev *dev = iforce->dev;
int i;
static int being_used = 0;
diff --git a/drivers/input/joystick/iforce/iforce-serio.c b/drivers/input/joystick/iforce/iforce-serio.c
index 11f51905cba7..64a78c515484 100644
--- a/drivers/input/joystick/iforce/iforce-serio.c
+++ b/drivers/input/joystick/iforce/iforce-serio.c
@@ -131,11 +131,10 @@ static int iforce_serio_connect(struct serio *serio, struct serio_driver *drv)
struct iforce *iforce;
int err;
- if (!(iforce = kmalloc(sizeof(struct iforce), GFP_KERNEL)))
+ iforce = kzalloc(sizeof(struct iforce), GFP_KERNEL);
+ if (!iforce)
return -ENOMEM;
- memset(iforce, 0, sizeof(struct iforce));
-
iforce->bus = IFORCE_232;
iforce->serio = serio;
@@ -148,7 +147,8 @@ static int iforce_serio_connect(struct serio *serio, struct serio_driver *drv)
return err;
}
- if (iforce_init_device(iforce)) {
+ err = iforce_init_device(iforce);
+ if (err) {
serio_close(serio);
serio_set_drvdata(serio, NULL);
kfree(iforce);
@@ -162,7 +162,7 @@ static void iforce_serio_disconnect(struct serio *serio)
{
struct iforce *iforce = serio_get_drvdata(serio);
- input_unregister_device(&iforce->dev);
+ input_unregister_device(iforce->dev);
serio_close(serio);
serio_set_drvdata(serio, NULL);
kfree(iforce);
diff --git a/drivers/input/joystick/iforce/iforce-usb.c b/drivers/input/joystick/iforce/iforce-usb.c
index 58600f91eff5..64b4a3080985 100644
--- a/drivers/input/joystick/iforce/iforce-usb.c
+++ b/drivers/input/joystick/iforce/iforce-usb.c
@@ -135,28 +135,24 @@ static int iforce_usb_probe(struct usb_interface *intf,
struct usb_host_interface *interface;
struct usb_endpoint_descriptor *epirq, *epout;
struct iforce *iforce;
+ int err = -ENOMEM;
interface = intf->cur_altsetting;
epirq = &interface->endpoint[0].desc;
epout = &interface->endpoint[1].desc;
- if (!(iforce = kmalloc(sizeof(struct iforce) + 32, GFP_KERNEL)))
+ if (!(iforce = kzalloc(sizeof(struct iforce) + 32, GFP_KERNEL)))
goto fail;
- memset(iforce, 0, sizeof(struct iforce));
-
- if (!(iforce->irq = usb_alloc_urb(0, GFP_KERNEL))) {
+ if (!(iforce->irq = usb_alloc_urb(0, GFP_KERNEL)))
goto fail;
- }
- if (!(iforce->out = usb_alloc_urb(0, GFP_KERNEL))) {
+ if (!(iforce->out = usb_alloc_urb(0, GFP_KERNEL)))
goto fail;
- }
- if (!(iforce->ctrl = usb_alloc_urb(0, GFP_KERNEL))) {
+ if (!(iforce->ctrl = usb_alloc_urb(0, GFP_KERNEL)))
goto fail;
- }
iforce->bus = IFORCE_USB;
iforce->usbdev = dev;
@@ -174,7 +170,9 @@ static int iforce_usb_probe(struct usb_interface *intf,
usb_fill_control_urb(iforce->ctrl, dev, usb_rcvctrlpipe(dev, 0),
(void*) &iforce->cr, iforce->edata, 16, iforce_usb_ctrl, iforce);
- if (iforce_init_device(iforce)) goto fail;
+ err = iforce_init_device(iforce);
+ if (err)
+ goto fail;
usb_set_intfdata(intf, iforce);
return 0;
@@ -187,7 +185,7 @@ fail:
kfree(iforce);
}
- return -ENODEV;
+ return err;
}
/* Called by iforce_delete() */
@@ -211,7 +209,7 @@ static void iforce_usb_disconnect(struct usb_interface *intf)
usb_set_intfdata(intf, NULL);
if (iforce) {
iforce->usbdev = NULL;
- input_unregister_device(&iforce->dev);
+ input_unregister_device(iforce->dev);
if (!open) {
iforce_delete_device(iforce);
diff --git a/drivers/input/joystick/iforce/iforce.h b/drivers/input/joystick/iforce/iforce.h
index bce247bc300b..146f406b8f8a 100644
--- a/drivers/input/joystick/iforce/iforce.h
+++ b/drivers/input/joystick/iforce/iforce.h
@@ -117,7 +117,7 @@ struct iforce_device {
};
struct iforce {
- struct input_dev dev; /* Input device interface */
+ struct input_dev *dev; /* Input device interface */
struct iforce_device *type;
int bus;
diff --git a/drivers/input/joystick/interact.c b/drivers/input/joystick/interact.c
index d7b3472bd686..c4ed01758226 100644
--- a/drivers/input/joystick/interact.c
+++ b/drivers/input/joystick/interact.c
@@ -38,6 +38,7 @@
#include <linux/init.h>
#include <linux/gameport.h>
#include <linux/input.h>
+#include <linux/jiffies.h>
#define DRIVER_DESC "InterAct digital joystick driver"
@@ -54,7 +55,7 @@ MODULE_LICENSE("GPL");
struct interact {
struct gameport *gameport;
- struct input_dev dev;
+ struct input_dev *dev;
int bads;
int reads;
unsigned char type;
@@ -130,7 +131,7 @@ static int interact_read_packet(struct gameport *gameport, int length, u32 *data
static void interact_poll(struct gameport *gameport)
{
struct interact *interact = gameport_get_drvdata(gameport);
- struct input_dev *dev = &interact->dev;
+ struct input_dev *dev = interact->dev;
u32 data[3];
int i;
@@ -208,14 +209,20 @@ static void interact_close(struct input_dev *dev)
static int interact_connect(struct gameport *gameport, struct gameport_driver *drv)
{
struct interact *interact;
+ struct input_dev *input_dev;
__u32 data[3];
int i, t;
int err;
- if (!(interact = kzalloc(sizeof(struct interact), GFP_KERNEL)))
- return -ENOMEM;
+ interact = kzalloc(sizeof(struct interact), GFP_KERNEL);
+ input_dev = input_allocate_device();
+ if (!interact || !input_dev) {
+ err = -ENOMEM;
+ goto fail1;
+ }
interact->gameport = gameport;
+ interact->dev = input_dev;
gameport_set_drvdata(gameport, interact);
@@ -249,41 +256,40 @@ static int interact_connect(struct gameport *gameport, struct gameport_driver *d
interact->type = i;
interact->length = interact_type[i].length;
- interact->dev.private = interact;
- interact->dev.open = interact_open;
- interact->dev.close = interact_close;
+ input_dev->name = interact_type[i].name;
+ input_dev->phys = interact->phys;
+ input_dev->id.bustype = BUS_GAMEPORT;
+ input_dev->id.vendor = GAMEPORT_ID_VENDOR_INTERACT;
+ input_dev->id.product = interact_type[i].id;
+ input_dev->id.version = 0x0100;
+ input_dev->private = interact;
- interact->dev.name = interact_type[i].name;
- interact->dev.phys = interact->phys;
- interact->dev.id.bustype = BUS_GAMEPORT;
- interact->dev.id.vendor = GAMEPORT_ID_VENDOR_INTERACT;
- interact->dev.id.product = interact_type[i].id;
- interact->dev.id.version = 0x0100;
+ input_dev->open = interact_open;
+ input_dev->close = interact_close;
- interact->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+ input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
for (i = 0; (t = interact_type[interact->type].abs[i]) >= 0; i++) {
- set_bit(t, interact->dev.absbit);
+ set_bit(t, input_dev->absbit);
if (i < interact_type[interact->type].b8) {
- interact->dev.absmin[t] = 0;
- interact->dev.absmax[t] = 255;
+ input_dev->absmin[t] = 0;
+ input_dev->absmax[t] = 255;
} else {
- interact->dev.absmin[t] = -1;
- interact->dev.absmax[t] = 1;
+ input_dev->absmin[t] = -1;
+ input_dev->absmax[t] = 1;
}
}
for (i = 0; (t = interact_type[interact->type].btn[i]) >= 0; i++)
- set_bit(t, interact->dev.keybit);
+ set_bit(t, input_dev->keybit);
- input_register_device(&interact->dev);
- printk(KERN_INFO "input: %s on %s\n",
- interact_type[interact->type].name, gameport->phys);
+ input_register_device(interact->dev);
return 0;
fail2: gameport_close(gameport);
fail1: gameport_set_drvdata(gameport, NULL);
+ input_free_device(input_dev);
kfree(interact);
return err;
}
@@ -292,7 +298,7 @@ static void interact_disconnect(struct gameport *gameport)
{
struct interact *interact = gameport_get_drvdata(gameport);
- input_unregister_device(&interact->dev);
+ input_unregister_device(interact->dev);
gameport_close(gameport);
gameport_set_drvdata(gameport, NULL);
kfree(interact);
diff --git a/drivers/input/joystick/joydump.c b/drivers/input/joystick/joydump.c
index 4234ccaf9146..88ec5a918f2e 100644
--- a/drivers/input/joystick/joydump.c
+++ b/drivers/input/joystick/joydump.c
@@ -34,6 +34,7 @@
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/init.h>
+#include <linux/slab.h>
#define DRIVER_DESC "Gameport data dumper module"
diff --git a/drivers/input/joystick/magellan.c b/drivers/input/joystick/magellan.c
index 1ba503627242..ca3cc2319d6a 100644
--- a/drivers/input/joystick/magellan.c
+++ b/drivers/input/joystick/magellan.c
@@ -49,14 +49,13 @@ MODULE_LICENSE("GPL");
static int magellan_buttons[] = { BTN_0, BTN_1, BTN_2, BTN_3, BTN_4, BTN_5, BTN_6, BTN_7, BTN_8 };
static int magellan_axes[] = { ABS_X, ABS_Y, ABS_Z, ABS_RX, ABS_RY, ABS_RZ };
-static char *magellan_name = "LogiCad3D Magellan / SpaceMouse";
/*
* Per-Magellan data.
*/
struct magellan {
- struct input_dev dev;
+ struct input_dev *dev;
int idx;
unsigned char data[MAGELLAN_MAX_LENGTH];
char phys[32];
@@ -85,7 +84,7 @@ static int magellan_crunch_nibbles(unsigned char *data, int count)
static void magellan_process_packet(struct magellan* magellan, struct pt_regs *regs)
{
- struct input_dev *dev = &magellan->dev;
+ struct input_dev *dev = magellan->dev;
unsigned char *data = magellan->data;
int i, t;
@@ -138,9 +137,9 @@ static void magellan_disconnect(struct serio *serio)
{
struct magellan* magellan = serio_get_drvdata(serio);
- input_unregister_device(&magellan->dev);
serio_close(serio);
serio_set_drvdata(serio, NULL);
+ input_unregister_device(magellan->dev);
kfree(magellan);
}
@@ -153,52 +152,48 @@ static void magellan_disconnect(struct serio *serio)
static int magellan_connect(struct serio *serio, struct serio_driver *drv)
{
struct magellan *magellan;
- int i, t;
- int err;
-
- if (!(magellan = kmalloc(sizeof(struct magellan), GFP_KERNEL)))
- return -ENOMEM;
+ struct input_dev *input_dev;
+ int err = -ENOMEM;
+ int i;
- memset(magellan, 0, sizeof(struct magellan));
+ magellan = kzalloc(sizeof(struct magellan), GFP_KERNEL);
+ input_dev = input_allocate_device();
+ if (!magellan || !input_dev)
+ goto fail;
- magellan->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+ magellan->dev = input_dev;
+ sprintf(magellan->phys, "%s/input0", serio->phys);
- for (i = 0; i < 9; i++)
- set_bit(magellan_buttons[i], magellan->dev.keybit);
+ input_dev->name = "LogiCad3D Magellan / SpaceMouse";
+ input_dev->phys = magellan->phys;
+ input_dev->id.bustype = BUS_RS232;
+ input_dev->id.vendor = SERIO_MAGELLAN;
+ input_dev->id.product = 0x0001;
+ input_dev->id.version = 0x0100;
+ input_dev->cdev.dev = &serio->dev;
+ input_dev->private = magellan;
- for (i = 0; i < 6; i++) {
- t = magellan_axes[i];
- set_bit(t, magellan->dev.absbit);
- magellan->dev.absmin[t] = -360;
- magellan->dev.absmax[t] = 360;
- }
+ input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
- sprintf(magellan->phys, "%s/input0", serio->phys);
+ for (i = 0; i < 9; i++)
+ set_bit(magellan_buttons[i], input_dev->keybit);
- init_input_dev(&magellan->dev);
- magellan->dev.private = magellan;
- magellan->dev.name = magellan_name;
- magellan->dev.phys = magellan->phys;
- magellan->dev.id.bustype = BUS_RS232;
- magellan->dev.id.vendor = SERIO_MAGELLAN;
- magellan->dev.id.product = 0x0001;
- magellan->dev.id.version = 0x0100;
- magellan->dev.dev = &serio->dev;
+ for (i = 0; i < 6; i++)
+ input_set_abs_params(input_dev, magellan_axes[i], -360, 360, 0, 0);
serio_set_drvdata(serio, magellan);
err = serio_open(serio, drv);
- if (err) {
- serio_set_drvdata(serio, NULL);
- kfree(magellan);
- return err;
- }
-
- input_register_device(&magellan->dev);
-
- printk(KERN_INFO "input: %s on %s\n", magellan_name, serio->phys);
+ if (err)
+ goto fail;
+ input_register_device(magellan->dev);
return 0;
+
+ fail: serio_set_drvdata(serio, NULL);
+ input_free_device(input_dev);
+ kfree(magellan);
+ return err;
}
/*
diff --git a/drivers/input/joystick/sidewinder.c b/drivers/input/joystick/sidewinder.c
index 9e0353721a35..78dd163cd702 100644
--- a/drivers/input/joystick/sidewinder.c
+++ b/drivers/input/joystick/sidewinder.c
@@ -33,6 +33,7 @@
#include <linux/init.h>
#include <linux/input.h>
#include <linux/gameport.h>
+#include <linux/jiffies.h>
#define DRIVER_DESC "Microsoft SideWinder joystick family driver"
@@ -113,7 +114,7 @@ static struct {
struct sw {
struct gameport *gameport;
- struct input_dev dev[4];
+ struct input_dev *dev[4];
char name[64];
char phys[4][32];
int length;
@@ -301,7 +302,7 @@ static int sw_check(__u64 t)
static int sw_parse(unsigned char *buf, struct sw *sw)
{
int hat, i, j;
- struct input_dev *dev = sw->dev;
+ struct input_dev *dev;
switch (sw->type) {
@@ -310,6 +311,8 @@ static int sw_parse(unsigned char *buf, struct sw *sw)
if (sw_check(GB(0,64)) || (hat = (GB(6,1) << 3) | GB(60,3)) > 8)
return -1;
+ dev = sw->dev[0];
+
input_report_abs(dev, ABS_X, (GB( 3,3) << 7) | GB(16,7));
input_report_abs(dev, ABS_Y, (GB( 0,3) << 7) | GB(24,7));
input_report_abs(dev, ABS_RZ, (GB(35,2) << 7) | GB(40,7));
@@ -335,13 +338,13 @@ static int sw_parse(unsigned char *buf, struct sw *sw)
if (sw_parity(GB(i*15,15)))
return -1;
- input_report_abs(dev + i, ABS_X, GB(i*15+3,1) - GB(i*15+2,1));
- input_report_abs(dev + i, ABS_Y, GB(i*15+0,1) - GB(i*15+1,1));
+ input_report_abs(sw->dev[i], ABS_X, GB(i*15+3,1) - GB(i*15+2,1));
+ input_report_abs(sw->dev[i], ABS_Y, GB(i*15+0,1) - GB(i*15+1,1));
for (j = 0; j < 10; j++)
- input_report_key(dev + i, sw_btn[SW_ID_GP][j], !GB(i*15+j+4,1));
+ input_report_key(sw->dev[i], sw_btn[SW_ID_GP][j], !GB(i*15+j+4,1));
- input_sync(dev + i);
+ input_sync(sw->dev[i]);
}
return 0;
@@ -352,6 +355,7 @@ static int sw_parse(unsigned char *buf, struct sw *sw)
if (!sw_parity(GB(0,48)) || (hat = GB(42,4)) > 8)
return -1;
+ dev = sw->dev[0];
input_report_abs(dev, ABS_X, GB( 9,10));
input_report_abs(dev, ABS_Y, GB(19,10));
input_report_abs(dev, ABS_RZ, GB(36, 6));
@@ -372,6 +376,7 @@ static int sw_parse(unsigned char *buf, struct sw *sw)
if (!sw_parity(GB(0,43)) || (hat = GB(28,4)) > 8)
return -1;
+ dev = sw->dev[0];
input_report_abs(dev, ABS_X, GB( 0,10));
input_report_abs(dev, ABS_Y, GB(16,10));
input_report_abs(dev, ABS_THROTTLE, GB(32, 6));
@@ -396,6 +401,7 @@ static int sw_parse(unsigned char *buf, struct sw *sw)
if (!sw_parity(GB(0,33)))
return -1;
+ dev = sw->dev[0];
input_report_abs(dev, ABS_RX, GB( 0,10));
input_report_abs(dev, ABS_RUDDER, GB(10, 6));
input_report_abs(dev, ABS_THROTTLE, GB(16, 6));
@@ -581,6 +587,7 @@ static int sw_guess_mode(unsigned char *buf, int len)
static int sw_connect(struct gameport *gameport, struct gameport_driver *drv)
{
struct sw *sw;
+ struct input_dev *input_dev;
int i, j, k, l;
int err;
unsigned char *buf = NULL; /* [SW_LENGTH] */
@@ -729,42 +736,50 @@ static int sw_connect(struct gameport *gameport, struct gameport_driver *drv)
sprintf(sw->name, "Microsoft SideWinder %s", sw_name[sw->type]);
sprintf(sw->phys[i], "%s/input%d", gameport->phys, i);
- sw->dev[i].private = sw;
+ input_dev = input_allocate_device();
+ if (!input_dev) {
+ err = -ENOMEM;
+ goto fail3;
+ }
- sw->dev[i].open = sw_open;
- sw->dev[i].close = sw_close;
+ input_dev->name = sw->name;
+ input_dev->phys = sw->phys[i];
+ input_dev->id.bustype = BUS_GAMEPORT;
+ input_dev->id.vendor = GAMEPORT_ID_VENDOR_MICROSOFT;
+ input_dev->id.product = sw->type;
+ input_dev->id.version = 0x0100;
+ input_dev->cdev.dev = &gameport->dev;
+ input_dev->private = sw;
- sw->dev[i].name = sw->name;
- sw->dev[i].phys = sw->phys[i];
- sw->dev[i].id.bustype = BUS_GAMEPORT;
- sw->dev[i].id.vendor = GAMEPORT_ID_VENDOR_MICROSOFT;
- sw->dev[i].id.product = sw->type;
- sw->dev[i].id.version = 0x0100;
+ input_dev->open = sw_open;
+ input_dev->close = sw_close;
- sw->dev[i].evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+ input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
for (j = 0; (bits = sw_bit[sw->type][j]); j++) {
code = sw_abs[sw->type][j];
- set_bit(code, sw->dev[i].absbit);
- sw->dev[i].absmax[code] = (1 << bits) - 1;
- sw->dev[i].absmin[code] = (bits == 1) ? -1 : 0;
- sw->dev[i].absfuzz[code] = ((bits >> 1) >= 2) ? (1 << ((bits >> 1) - 2)) : 0;
+ set_bit(code, input_dev->absbit);
+ input_dev->absmax[code] = (1 << bits) - 1;
+ input_dev->absmin[code] = (bits == 1) ? -1 : 0;
+ input_dev->absfuzz[code] = ((bits >> 1) >= 2) ? (1 << ((bits >> 1) - 2)) : 0;
if (code != ABS_THROTTLE)
- sw->dev[i].absflat[code] = (bits >= 5) ? (1 << (bits - 5)) : 0;
+ input_dev->absflat[code] = (bits >= 5) ? (1 << (bits - 5)) : 0;
}
for (j = 0; (code = sw_btn[sw->type][j]); j++)
- set_bit(code, sw->dev[i].keybit);
+ set_bit(code, input_dev->keybit);
+
+ dbg("%s%s [%d-bit id %d data %d]\n", sw->name, comment, m, l, k);
- input_register_device(sw->dev + i);
- printk(KERN_INFO "input: %s%s on %s [%d-bit id %d data %d]\n",
- sw->name, comment, gameport->phys, m, l, k);
+ input_register_device(sw->dev[i]);
}
return 0;
-fail2: gameport_close(gameport);
-fail1: gameport_set_drvdata(gameport, NULL);
+ fail3: while (--i >= 0)
+ input_unregister_device(sw->dev[i]);
+ fail2: gameport_close(gameport);
+ fail1: gameport_set_drvdata(gameport, NULL);
kfree(sw);
kfree(buf);
kfree(idbuf);
@@ -777,7 +792,7 @@ static void sw_disconnect(struct gameport *gameport)
int i;
for (i = 0; i < sw->number; i++)
- input_unregister_device(sw->dev + i);
+ input_unregister_device(sw->dev[i]);
gameport_close(gameport);
gameport_set_drvdata(gameport, NULL);
kfree(sw);
diff --git a/drivers/input/joystick/spaceball.c b/drivers/input/joystick/spaceball.c
index a436f2220856..d6f8db8ec3fd 100644
--- a/drivers/input/joystick/spaceball.c
+++ b/drivers/input/joystick/spaceball.c
@@ -70,8 +70,7 @@ static char *spaceball_names[] = {
*/
struct spaceball {
- struct input_dev dev;
- struct serio *serio;
+ struct input_dev *dev;
int idx;
int escape;
unsigned char data[SPACEBALL_MAX_LENGTH];
@@ -85,7 +84,7 @@ struct spaceball {
static void spaceball_process_packet(struct spaceball* spaceball, struct pt_regs *regs)
{
- struct input_dev *dev = &spaceball->dev;
+ struct input_dev *dev = spaceball->dev;
unsigned char *data = spaceball->data;
int i;
@@ -193,9 +192,9 @@ static void spaceball_disconnect(struct serio *serio)
{
struct spaceball* spaceball = serio_get_drvdata(serio);
- input_unregister_device(&spaceball->dev);
serio_close(serio);
serio_set_drvdata(serio, NULL);
+ input_unregister_device(spaceball->dev);
kfree(spaceball);
}
@@ -208,69 +207,62 @@ static void spaceball_disconnect(struct serio *serio)
static int spaceball_connect(struct serio *serio, struct serio_driver *drv)
{
struct spaceball *spaceball;
- int i, t, id;
- int err;
+ struct input_dev *input_dev;
+ int err = -ENOMEM;
+ int i, id;
if ((id = serio->id.id) > SPACEBALL_MAX_ID)
return -ENODEV;
- if (!(spaceball = kmalloc(sizeof(struct spaceball), GFP_KERNEL)))
- return - ENOMEM;
+ spaceball = kmalloc(sizeof(struct spaceball), GFP_KERNEL);
+ input_dev = input_allocate_device();
+ if (!spaceball || !input_dev)
+ goto fail;
- memset(spaceball, 0, sizeof(struct spaceball));
+ spaceball->dev = input_dev;
+ sprintf(spaceball->phys, "%s/input0", serio->phys);
+
+ input_dev->name = spaceball_names[id];
+ input_dev->phys = spaceball->phys;
+ input_dev->id.bustype = BUS_RS232;
+ input_dev->id.vendor = SERIO_SPACEBALL;
+ input_dev->id.product = id;
+ input_dev->id.version = 0x0100;
+ input_dev->cdev.dev = &serio->dev;
+ input_dev->private = spaceball;
- spaceball->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+ input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
switch (id) {
case SPACEBALL_4000FLX:
case SPACEBALL_4000FLX_L:
- spaceball->dev.keybit[LONG(BTN_0)] |= BIT(BTN_9);
- spaceball->dev.keybit[LONG(BTN_A)] |= BIT(BTN_A) | BIT(BTN_B) | BIT(BTN_C) | BIT(BTN_MODE);
+ input_dev->keybit[LONG(BTN_0)] |= BIT(BTN_9);
+ input_dev->keybit[LONG(BTN_A)] |= BIT(BTN_A) | BIT(BTN_B) | BIT(BTN_C) | BIT(BTN_MODE);
default:
- spaceball->dev.keybit[LONG(BTN_0)] |= BIT(BTN_2) | BIT(BTN_3) | BIT(BTN_4)
+ input_dev->keybit[LONG(BTN_0)] |= BIT(BTN_2) | BIT(BTN_3) | BIT(BTN_4)
| BIT(BTN_5) | BIT(BTN_6) | BIT(BTN_7) | BIT(BTN_8);
case SPACEBALL_3003C:
- spaceball->dev.keybit[LONG(BTN_0)] |= BIT(BTN_1) | BIT(BTN_8);
+ input_dev->keybit[LONG(BTN_0)] |= BIT(BTN_1) | BIT(BTN_8);
}
- for (i = 0; i < 6; i++) {
- t = spaceball_axes[i];
- set_bit(t, spaceball->dev.absbit);
- spaceball->dev.absmin[t] = i < 3 ? -8000 : -1600;
- spaceball->dev.absmax[t] = i < 3 ? 8000 : 1600;
- spaceball->dev.absflat[t] = i < 3 ? 40 : 8;
- spaceball->dev.absfuzz[t] = i < 3 ? 8 : 2;
+ for (i = 0; i < 3; i++) {
+ input_set_abs_params(input_dev, ABS_X + i, -8000, 8000, 8, 40);
+ input_set_abs_params(input_dev, ABS_RX + i, -1600, 1600, 2, 8);
}
- spaceball->serio = serio;
- spaceball->dev.private = spaceball;
-
- sprintf(spaceball->phys, "%s/input0", serio->phys);
-
- init_input_dev(&spaceball->dev);
- spaceball->dev.name = spaceball_names[id];
- spaceball->dev.phys = spaceball->phys;
- spaceball->dev.id.bustype = BUS_RS232;
- spaceball->dev.id.vendor = SERIO_SPACEBALL;
- spaceball->dev.id.product = id;
- spaceball->dev.id.version = 0x0100;
- spaceball->dev.dev = &serio->dev;
-
serio_set_drvdata(serio, spaceball);
err = serio_open(serio, drv);
- if (err) {
- serio_set_drvdata(serio, NULL);
- kfree(spaceball);
- return err;
- }
-
- input_register_device(&spaceball->dev);
-
- printk(KERN_INFO "input: %s on serio%s\n",
- spaceball_names[id], serio->phys);
+ if (err)
+ goto fail;
+ input_register_device(spaceball->dev);
return 0;
+
+ fail: serio_set_drvdata(serio, NULL);
+ input_free_device(input_dev);
+ kfree(spaceball);
+ return err;
}
/*
diff --git a/drivers/input/joystick/spaceorb.c b/drivers/input/joystick/spaceorb.c
index 01fd2e4791ae..7c123a01c58e 100644
--- a/drivers/input/joystick/spaceorb.c
+++ b/drivers/input/joystick/spaceorb.c
@@ -52,15 +52,13 @@ MODULE_LICENSE("GPL");
static int spaceorb_buttons[] = { BTN_TL, BTN_TR, BTN_Y, BTN_X, BTN_B, BTN_A };
static int spaceorb_axes[] = { ABS_X, ABS_Y, ABS_Z, ABS_RX, ABS_RY, ABS_RZ };
-static char *spaceorb_name = "SpaceTec SpaceOrb 360 / Avenger";
/*
* Per-Orb data.
*/
struct spaceorb {
- struct input_dev dev;
- struct serio *serio;
+ struct input_dev *dev;
int idx;
unsigned char data[SPACEORB_MAX_LENGTH];
char phys[32];
@@ -78,7 +76,7 @@ static unsigned char *spaceorb_errors[] = { "EEPROM storing 0 failed", "Receive
static void spaceorb_process_packet(struct spaceorb *spaceorb, struct pt_regs *regs)
{
- struct input_dev *dev = &spaceorb->dev;
+ struct input_dev *dev = spaceorb->dev;
unsigned char *data = spaceorb->data;
unsigned char c = 0;
int axes[6];
@@ -95,8 +93,8 @@ static void spaceorb_process_packet(struct spaceorb *spaceorb, struct pt_regs *r
case 'R': /* Reset packet */
spaceorb->data[spaceorb->idx - 1] = 0;
for (i = 1; i < spaceorb->idx && spaceorb->data[i] == ' '; i++);
- printk(KERN_INFO "input: %s [%s] on %s\n",
- spaceorb_name, spaceorb->data + i, spaceorb->serio->phys);
+ printk(KERN_INFO "input: %s [%s] is %s\n",
+ dev->name, spaceorb->data + i, spaceorb->phys);
break;
case 'D': /* Ball + button data */
@@ -123,7 +121,7 @@ static void spaceorb_process_packet(struct spaceorb *spaceorb, struct pt_regs *r
case 'E': /* Error packet */
if (spaceorb->idx != 4) return;
- printk(KERN_ERR "joy-spaceorb: Device error. [ ");
+ printk(KERN_ERR "spaceorb: Device error. [ ");
for (i = 0; i < 7; i++) if (data[1] & (1 << i)) printk("%s ", spaceorb_errors[i]);
printk("]\n");
break;
@@ -154,9 +152,9 @@ static void spaceorb_disconnect(struct serio *serio)
{
struct spaceorb* spaceorb = serio_get_drvdata(serio);
- input_unregister_device(&spaceorb->dev);
serio_close(serio);
serio_set_drvdata(serio, NULL);
+ input_unregister_device(spaceorb->dev);
kfree(spaceorb);
}
@@ -169,52 +167,48 @@ static void spaceorb_disconnect(struct serio *serio)
static int spaceorb_connect(struct serio *serio, struct serio_driver *drv)
{
struct spaceorb *spaceorb;
- int i, t;
- int err;
-
- if (!(spaceorb = kmalloc(sizeof(struct spaceorb), GFP_KERNEL)))
- return -ENOMEM;
-
- memset(spaceorb, 0, sizeof(struct spaceorb));
+ struct input_dev *input_dev;
+ int err = -ENOMEM;
+ int i;
- spaceorb->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+ spaceorb = kzalloc(sizeof(struct spaceorb), GFP_KERNEL);
+ input_dev = input_allocate_device();
+ if (!spaceorb || !input_dev)
+ goto fail;
- for (i = 0; i < 6; i++)
- set_bit(spaceorb_buttons[i], spaceorb->dev.keybit);
+ spaceorb->dev = input_dev;
+ sprintf(spaceorb->phys, "%s/input0", serio->phys);
- for (i = 0; i < 6; i++) {
- t = spaceorb_axes[i];
- set_bit(t, spaceorb->dev.absbit);
- spaceorb->dev.absmin[t] = -508;
- spaceorb->dev.absmax[t] = 508;
- }
+ input_dev->name = "SpaceTec SpaceOrb 360 / Avenger";
+ input_dev->phys = spaceorb->phys;
+ input_dev->id.bustype = BUS_RS232;
+ input_dev->id.vendor = SERIO_SPACEORB;
+ input_dev->id.product = 0x0001;
+ input_dev->id.version = 0x0100;
+ input_dev->cdev.dev = &serio->dev;
+ input_dev->private = spaceorb;
- spaceorb->serio = serio;
- spaceorb->dev.private = spaceorb;
+ input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
- sprintf(spaceorb->phys, "%s/input0", serio->phys);
+ for (i = 0; i < 6; i++)
+ set_bit(spaceorb_buttons[i], input_dev->keybit);
- init_input_dev(&spaceorb->dev);
- spaceorb->dev.name = spaceorb_name;
- spaceorb->dev.phys = spaceorb->phys;
- spaceorb->dev.id.bustype = BUS_RS232;
- spaceorb->dev.id.vendor = SERIO_SPACEORB;
- spaceorb->dev.id.product = 0x0001;
- spaceorb->dev.id.version = 0x0100;
- spaceorb->dev.dev = &serio->dev;
+ for (i = 0; i < 6; i++)
+ input_set_abs_params(input_dev, spaceorb_axes[i], -508, 508, 0, 0);
serio_set_drvdata(serio, spaceorb);
err = serio_open(serio, drv);
- if (err) {
- serio_set_drvdata(serio, NULL);
- kfree(spaceorb);
- return err;
- }
-
- input_register_device(&spaceorb->dev);
+ if (err)
+ goto fail;
+ input_register_device(spaceorb->dev);
return 0;
+
+ fail: serio_set_drvdata(serio, NULL);
+ input_free_device(input_dev);
+ kfree(spaceorb);
+ return err;
}
/*
diff --git a/drivers/input/joystick/stinger.c b/drivers/input/joystick/stinger.c
index 6f6e6753d590..0a9ed1d30636 100644
--- a/drivers/input/joystick/stinger.c
+++ b/drivers/input/joystick/stinger.c
@@ -48,14 +48,12 @@ MODULE_LICENSE("GPL");
#define STINGER_MAX_LENGTH 8
-static char *stinger_name = "Gravis Stinger";
-
/*
* Per-Stinger data.
*/
struct stinger {
- struct input_dev dev;
+ struct input_dev *dev;
int idx;
unsigned char data[STINGER_MAX_LENGTH];
char phys[32];
@@ -68,7 +66,7 @@ struct stinger {
static void stinger_process_packet(struct stinger *stinger, struct pt_regs *regs)
{
- struct input_dev *dev = &stinger->dev;
+ struct input_dev *dev = stinger->dev;
unsigned char *data = stinger->data;
if (!stinger->idx) return;
@@ -126,9 +124,9 @@ static void stinger_disconnect(struct serio *serio)
{
struct stinger *stinger = serio_get_drvdata(serio);
- input_unregister_device(&stinger->dev);
serio_close(serio);
serio_set_drvdata(serio, NULL);
+ input_unregister_device(stinger->dev);
kfree(stinger);
}
@@ -141,53 +139,46 @@ static void stinger_disconnect(struct serio *serio)
static int stinger_connect(struct serio *serio, struct serio_driver *drv)
{
struct stinger *stinger;
- int i;
- int err;
-
- if (!(stinger = kmalloc(sizeof(struct stinger), GFP_KERNEL)))
- return -ENOMEM;
-
- memset(stinger, 0, sizeof(struct stinger));
+ struct input_dev *input_dev;
+ int err = -ENOMEM;
- stinger->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
- stinger->dev.keybit[LONG(BTN_A)] = BIT(BTN_A) | BIT(BTN_B) | BIT(BTN_C) | BIT(BTN_X) | \
- BIT(BTN_Y) | BIT(BTN_Z) | BIT(BTN_TL) | BIT(BTN_TR) | \
- BIT(BTN_START) | BIT(BTN_SELECT);
- stinger->dev.absbit[0] = BIT(ABS_X) | BIT(ABS_Y);
+ stinger = kmalloc(sizeof(struct stinger), GFP_KERNEL);
+ input_dev = input_allocate_device();
+ if (!stinger || !input_dev)
+ goto fail;
+ stinger->dev = input_dev;
sprintf(stinger->phys, "%s/serio0", serio->phys);
- init_input_dev(&stinger->dev);
- stinger->dev.name = stinger_name;
- stinger->dev.phys = stinger->phys;
- stinger->dev.id.bustype = BUS_RS232;
- stinger->dev.id.vendor = SERIO_STINGER;
- stinger->dev.id.product = 0x0001;
- stinger->dev.id.version = 0x0100;
- stinger->dev.dev = &serio->dev;
-
- for (i = 0; i < 2; i++) {
- stinger->dev.absmax[ABS_X+i] = 64;
- stinger->dev.absmin[ABS_X+i] = -64;
- stinger->dev.absflat[ABS_X+i] = 4;
- }
-
- stinger->dev.private = stinger;
+ input_dev->name = "Gravis Stinger";
+ input_dev->phys = stinger->phys;
+ input_dev->id.bustype = BUS_RS232;
+ input_dev->id.vendor = SERIO_STINGER;
+ input_dev->id.product = 0x0001;
+ input_dev->id.version = 0x0100;
+ input_dev->cdev.dev = &serio->dev;
+ input_dev->private = stinger;
+
+ input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+ input_dev->keybit[LONG(BTN_A)] = BIT(BTN_A) | BIT(BTN_B) | BIT(BTN_C) | BIT(BTN_X) |
+ BIT(BTN_Y) | BIT(BTN_Z) | BIT(BTN_TL) | BIT(BTN_TR) |
+ BIT(BTN_START) | BIT(BTN_SELECT);
+ input_set_abs_params(input_dev, ABS_X, -64, 64, 0, 4);
+ input_set_abs_params(input_dev, ABS_Y, -64, 64, 0, 4);
serio_set_drvdata(serio, stinger);
err = serio_open(serio, drv);
- if (err) {
- serio_set_drvdata(serio, NULL);
- kfree(stinger);
- return err;
- }
-
- input_register_device(&stinger->dev);
-
- printk(KERN_INFO "input: %s on %s\n", stinger_name, serio->phys);
+ if (err)
+ goto fail;
+ input_register_device(stinger->dev);
return 0;
+
+ fail: serio_set_drvdata(serio, NULL);
+ input_free_device(input_dev);
+ kfree(stinger);
+ return err;
}
/*
diff --git a/drivers/input/joystick/tmdc.c b/drivers/input/joystick/tmdc.c
index 7431efc4330e..60e2aac7d06e 100644
--- a/drivers/input/joystick/tmdc.c
+++ b/drivers/input/joystick/tmdc.c
@@ -38,6 +38,7 @@
#include <linux/init.h>
#include <linux/gameport.h>
#include <linux/input.h>
+#include <linux/jiffies.h>
#define DRIVER_DESC "ThrustMaster DirectConnect joystick driver"
@@ -63,37 +64,70 @@ MODULE_LICENSE("GPL");
#define TMDC_ABS_HAT 4
#define TMDC_BTN 16
-static unsigned char tmdc_byte_a[16] = { 0, 1, 3, 4, 6, 7 };
-static unsigned char tmdc_byte_d[16] = { 2, 5, 8, 9 };
+static const unsigned char tmdc_byte_a[16] = { 0, 1, 3, 4, 6, 7 };
+static const unsigned char tmdc_byte_d[16] = { 2, 5, 8, 9 };
-static signed char tmdc_abs[TMDC_ABS] =
+static const signed char tmdc_abs[TMDC_ABS] =
{ ABS_X, ABS_Y, ABS_RUDDER, ABS_THROTTLE, ABS_RX, ABS_RY, ABS_RZ };
-static signed char tmdc_abs_hat[TMDC_ABS_HAT] =
+static const signed char tmdc_abs_hat[TMDC_ABS_HAT] =
{ ABS_HAT0X, ABS_HAT0Y, ABS_HAT1X, ABS_HAT1Y };
-static signed char tmdc_abs_at[TMDC_ABS] =
+static const signed char tmdc_abs_at[TMDC_ABS] =
{ ABS_X, ABS_Y, ABS_RUDDER, -1, ABS_THROTTLE };
-static signed char tmdc_abs_fm[TMDC_ABS] =
+static const signed char tmdc_abs_fm[TMDC_ABS] =
{ ABS_RX, ABS_RY, ABS_X, ABS_Y };
-static short tmdc_btn_pad[TMDC_BTN] =
+static const short tmdc_btn_pad[TMDC_BTN] =
{ BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z, BTN_START, BTN_SELECT, BTN_TL, BTN_TR };
-static short tmdc_btn_joy[TMDC_BTN] =
+static const short tmdc_btn_joy[TMDC_BTN] =
{ BTN_TRIGGER, BTN_THUMB, BTN_TOP, BTN_TOP2, BTN_BASE, BTN_BASE2, BTN_THUMB2, BTN_PINKIE,
BTN_BASE3, BTN_BASE4, BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z };
-static short tmdc_btn_fm[TMDC_BTN] =
+static const short tmdc_btn_fm[TMDC_BTN] =
{ BTN_TRIGGER, BTN_C, BTN_B, BTN_A, BTN_THUMB, BTN_X, BTN_Y, BTN_Z, BTN_TOP, BTN_TOP2 };
-static short tmdc_btn_at[TMDC_BTN] =
+static const short tmdc_btn_at[TMDC_BTN] =
{ BTN_TRIGGER, BTN_THUMB2, BTN_PINKIE, BTN_THUMB, BTN_BASE6, BTN_BASE5, BTN_BASE4,
BTN_BASE3, BTN_BASE2, BTN_BASE };
-static struct {
+static const struct {
int x;
int y;
} tmdc_hat_to_axis[] = {{ 0, 0}, { 1, 0}, { 0,-1}, {-1, 0}, { 0, 1}};
+static const struct tmdc_model {
+ unsigned char id;
+ const char *name;
+ char abs;
+ char hats;
+ char btnc[4];
+ char btno[4];
+ const signed char *axes;
+ const short *buttons;
+} tmdc_models[] = {
+ { 1, "ThrustMaster Millenium 3D Inceptor", 6, 2, { 4, 2 }, { 4, 6 }, tmdc_abs, tmdc_btn_joy },
+ { 3, "ThrustMaster Rage 3D Gamepad", 2, 0, { 8, 2 }, { 0, 0 }, tmdc_abs, tmdc_btn_pad },
+ { 4, "ThrustMaster Attack Throttle", 5, 2, { 4, 6 }, { 4, 2 }, tmdc_abs_at, tmdc_btn_at },
+ { 8, "ThrustMaster FragMaster", 4, 0, { 8, 2 }, { 0, 0 }, tmdc_abs_fm, tmdc_btn_fm },
+ { 163, "Thrustmaster Fusion GamePad", 2, 0, { 8, 2 }, { 0, 0 }, tmdc_abs, tmdc_btn_pad },
+ { 0, "Unknown %d-axis, %d-button TM device %d", 0, 0, { 0, 0 }, { 0, 0 }, tmdc_abs, tmdc_btn_joy }
+};
+
+
+struct tmdc_port {
+ struct input_dev *dev;
+ char name[64];
+ char phys[32];
+ int mode;
+ const signed char *abs;
+ const short *btn;
+ unsigned char absc;
+ unsigned char btnc[4];
+ unsigned char btno[4];
+};
+
struct tmdc {
struct gameport *gameport;
- struct input_dev dev[2];
+ struct tmdc_port *port[2];
+#if 0
+ struct input_dev *dev[2];
char name[2][64];
char phys[2][32];
int mode[2];
@@ -102,6 +136,7 @@ struct tmdc {
unsigned char absc[2];
unsigned char btnc[2][4];
unsigned char btno[2][4];
+#endif
int reads;
int bads;
unsigned char exists;
@@ -156,6 +191,50 @@ static int tmdc_read_packet(struct gameport *gameport, unsigned char data[2][TMD
return (i[0] == TMDC_MAX_LENGTH) | ((i[1] == TMDC_MAX_LENGTH) << 1);
}
+static int tmdc_parse_packet(struct tmdc_port *port, unsigned char *data)
+{
+ int i, k, l;
+
+ if (data[TMDC_BYTE_ID] != port->mode)
+ return -1;
+
+ for (i = 0; i < port->absc; i++) {
+ if (port->abs[i] < 0)
+ return 0;
+
+ input_report_abs(port->dev, port->abs[i], data[tmdc_byte_a[i]]);
+ }
+
+ switch (port->mode) {
+
+ case TMDC_MODE_M3DI:
+
+ i = tmdc_byte_d[0];
+ input_report_abs(port->dev, ABS_HAT0X, ((data[i] >> 3) & 1) - ((data[i] >> 1) & 1));
+ input_report_abs(port->dev, ABS_HAT0Y, ((data[i] >> 2) & 1) - ( data[i] & 1));
+ break;
+
+ case TMDC_MODE_AT:
+
+ i = tmdc_byte_a[3];
+ input_report_abs(port->dev, ABS_HAT0X, tmdc_hat_to_axis[(data[i] - 141) / 25].x);
+ input_report_abs(port->dev, ABS_HAT0Y, tmdc_hat_to_axis[(data[i] - 141) / 25].y);
+ break;
+
+ }
+
+ for (k = l = 0; k < 4; k++) {
+ for (i = 0; i < port->btnc[k]; i++)
+ input_report_key(port->dev, port->btn[i + l],
+ ((data[tmdc_byte_d[k]] >> (i + port->btno[k])) & 1));
+ l += port->btnc[k];
+ }
+
+ input_sync(port->dev);
+
+ return 0;
+}
+
/*
* tmdc_poll() reads and analyzes ThrustMaster joystick data.
*/
@@ -164,57 +243,21 @@ static void tmdc_poll(struct gameport *gameport)
{
unsigned char data[2][TMDC_MAX_LENGTH];
struct tmdc *tmdc = gameport_get_drvdata(gameport);
- struct input_dev *dev;
unsigned char r, bad = 0;
- int i, j, k, l;
+ int i;
tmdc->reads++;
if ((r = tmdc_read_packet(tmdc->gameport, data)) != tmdc->exists)
bad = 1;
- else
-
- for (j = 0; j < 2; j++)
- if (r & (1 << j) & tmdc->exists) {
-
- if (data[j][TMDC_BYTE_ID] != tmdc->mode[j]) {
- bad = 1;
- continue;
- }
-
- dev = tmdc->dev + j;
-
- for (i = 0; i < tmdc->absc[j]; i++) {
- if (tmdc->abs[j][i] < 0) continue;
- input_report_abs(dev, tmdc->abs[j][i], data[j][tmdc_byte_a[i]]);
- }
-
- switch (tmdc->mode[j]) {
+ else {
+ for (i = 0; i < 2; i++) {
+ if (r & (1 << i) & tmdc->exists) {
- case TMDC_MODE_M3DI:
-
- i = tmdc_byte_d[0];
- input_report_abs(dev, ABS_HAT0X, ((data[j][i] >> 3) & 1) - ((data[j][i] >> 1) & 1));
- input_report_abs(dev, ABS_HAT0Y, ((data[j][i] >> 2) & 1) - ( data[j][i] & 1));
- break;
-
- case TMDC_MODE_AT:
-
- i = tmdc_byte_a[3];
- input_report_abs(dev, ABS_HAT0X, tmdc_hat_to_axis[(data[j][i] - 141) / 25].x);
- input_report_abs(dev, ABS_HAT0Y, tmdc_hat_to_axis[(data[j][i] - 141) / 25].y);
- break;
-
- }
-
- for (k = l = 0; k < 4; k++) {
- for (i = 0; i < tmdc->btnc[j][k]; i++)
- input_report_key(dev, tmdc->btn[j][i + l],
- ((data[j][tmdc_byte_d[k]] >> (i + tmdc->btno[j][k])) & 1));
- l += tmdc->btnc[j][k];
+ if (tmdc_parse_packet(tmdc->port[i], data[i]))
+ bad = 1;
}
-
- input_sync(dev);
+ }
}
tmdc->bads += bad;
@@ -235,31 +278,89 @@ static void tmdc_close(struct input_dev *dev)
gameport_stop_polling(tmdc->gameport);
}
+static int tmdc_setup_port(struct tmdc *tmdc, int idx, unsigned char *data)
+{
+ const struct tmdc_model *model;
+ struct tmdc_port *port;
+ struct input_dev *input_dev;
+ int i, j, b = 0;
+
+ tmdc->port[idx] = port = kzalloc(sizeof (struct tmdc_port), GFP_KERNEL);
+ input_dev = input_allocate_device();
+ if (!port || !input_dev) {
+ kfree(port);
+ input_free_device(input_dev);
+ return -ENOMEM;
+ }
+
+ port->mode = data[TMDC_BYTE_ID];
+
+ for (model = tmdc_models; model->id && model->id != port->mode; model++)
+ /* empty */;
+
+ port->abs = model->axes;
+ port->btn = model->buttons;
+
+ if (!model->id) {
+ port->absc = data[TMDC_BYTE_DEF] >> 4;
+ for (i = 0; i < 4; i++)
+ port->btnc[i] = i < (data[TMDC_BYTE_DEF] & 0xf) ? 8 : 0;
+ } else {
+ port->absc = model->abs;
+ for (i = 0; i < 4; i++)
+ port->btnc[i] = model->btnc[i];
+ }
+
+ for (i = 0; i < 4; i++)
+ port->btno[i] = model->btno[i];
+
+ snprintf(port->name, sizeof(port->name), model->name,
+ port->absc, (data[TMDC_BYTE_DEF] & 0xf) << 3, port->mode);
+ snprintf(port->phys, sizeof(port->phys), "%s/input%d", tmdc->gameport->phys, i);
+
+ port->dev = input_dev;
+
+ input_dev->name = port->name;
+ input_dev->phys = port->phys;
+ input_dev->id.bustype = BUS_GAMEPORT;
+ input_dev->id.vendor = GAMEPORT_ID_VENDOR_THRUSTMASTER;
+ input_dev->id.product = model->id;
+ input_dev->id.version = 0x0100;
+ input_dev->cdev.dev = &tmdc->gameport->dev;
+ input_dev->private = tmdc;
+
+ input_dev->open = tmdc_open;
+ input_dev->close = tmdc_close;
+
+ input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+
+ for (i = 0; i < port->absc && i < TMDC_ABS; i++)
+ if (port->abs[i] >= 0)
+ input_set_abs_params(input_dev, port->abs[i], 8, 248, 2, 4);
+
+ for (i = 0; i < model->hats && i < TMDC_ABS_HAT; i++)
+ input_set_abs_params(input_dev, tmdc_abs_hat[i], -1, 1, 0, 0);
+
+ for (i = 0; i < 4; i++) {
+ for (j = 0; j < port->btnc[i] && j < TMDC_BTN; j++)
+ set_bit(port->btn[j + b], input_dev->keybit);
+ b += port->btnc[i];
+ }
+
+ input_register_device(port->dev);
+
+ return 0;
+}
+
/*
* tmdc_probe() probes for ThrustMaster type joysticks.
*/
static int tmdc_connect(struct gameport *gameport, struct gameport_driver *drv)
{
- static struct models {
- unsigned char id;
- char *name;
- char abs;
- char hats;
- char btnc[4];
- char btno[4];
- signed char *axes;
- short *buttons;
- } models[] = { { 1, "ThrustMaster Millenium 3D Inceptor", 6, 2, { 4, 2 }, { 4, 6 }, tmdc_abs, tmdc_btn_joy },
- { 3, "ThrustMaster Rage 3D Gamepad", 2, 0, { 8, 2 }, { 0, 0 }, tmdc_abs, tmdc_btn_pad },
- { 4, "ThrustMaster Attack Throttle", 5, 2, { 4, 6 }, { 4, 2 }, tmdc_abs_at, tmdc_btn_at },
- { 8, "ThrustMaster FragMaster", 4, 0, { 8, 2 }, { 0, 0 }, tmdc_abs_fm, tmdc_btn_fm },
- { 163, "Thrustmaster Fusion GamePad", 2, 0, { 8, 2 }, { 0, 0 }, tmdc_abs, tmdc_btn_pad },
- { 0, "Unknown %d-axis, %d-button TM device %d", 0, 0, { 0, 0 }, { 0, 0 }, tmdc_abs, tmdc_btn_joy }};
-
unsigned char data[2][TMDC_MAX_LENGTH];
struct tmdc *tmdc;
- int i, j, k, l, m;
+ int i;
int err;
if (!(tmdc = kzalloc(sizeof(struct tmdc), GFP_KERNEL)))
@@ -281,68 +382,25 @@ static int tmdc_connect(struct gameport *gameport, struct gameport_driver *drv)
gameport_set_poll_handler(gameport, tmdc_poll);
gameport_set_poll_interval(gameport, 20);
- for (j = 0; j < 2; j++)
- if (tmdc->exists & (1 << j)) {
+ for (i = 0; i < 2; i++) {
+ if (tmdc->exists & (1 << i)) {
- tmdc->mode[j] = data[j][TMDC_BYTE_ID];
-
- for (m = 0; models[m].id && models[m].id != tmdc->mode[j]; m++);
-
- tmdc->abs[j] = models[m].axes;
- tmdc->btn[j] = models[m].buttons;
-
- if (!models[m].id) {
- models[m].abs = data[j][TMDC_BYTE_DEF] >> 4;
- for (k = 0; k < 4; k++)
- models[m].btnc[k] = k < (data[j][TMDC_BYTE_DEF] & 0xf) ? 8 : 0;
- }
-
- tmdc->absc[j] = models[m].abs;
- for (k = 0; k < 4; k++) {
- tmdc->btnc[j][k] = models[m].btnc[k];
- tmdc->btno[j][k] = models[m].btno[k];
- }
-
- sprintf(tmdc->name[j], models[m].name, models[m].abs,
- (data[j][TMDC_BYTE_DEF] & 0xf) << 3, tmdc->mode[j]);
-
- sprintf(tmdc->phys[j], "%s/input%d", gameport->phys, j);
-
- tmdc->dev[j].private = tmdc;
- tmdc->dev[j].open = tmdc_open;
- tmdc->dev[j].close = tmdc_close;
-
- tmdc->dev[j].name = tmdc->name[j];
- tmdc->dev[j].phys = tmdc->phys[j];
- tmdc->dev[j].id.bustype = BUS_GAMEPORT;
- tmdc->dev[j].id.vendor = GAMEPORT_ID_VENDOR_THRUSTMASTER;
- tmdc->dev[j].id.product = models[m].id;
- tmdc->dev[j].id.version = 0x0100;
-
- tmdc->dev[j].evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
-
- for (i = 0; i < models[m].abs && i < TMDC_ABS; i++)
- if (tmdc->abs[j][i] >= 0)
- input_set_abs_params(&tmdc->dev[j], tmdc->abs[j][i], 8, 248, 2, 4);
-
- for (i = 0; i < models[m].hats && i < TMDC_ABS_HAT; i++)
- input_set_abs_params(&tmdc->dev[j], tmdc_abs_hat[i], -1, 1, 0, 0);
-
-
- for (k = l = 0; k < 4; k++) {
- for (i = 0; i < models[m].btnc[k] && i < TMDC_BTN; i++)
- set_bit(tmdc->btn[j][i + l], tmdc->dev[j].keybit);
- l += models[m].btnc[k];
- }
-
- input_register_device(tmdc->dev + j);
- printk(KERN_INFO "input: %s on %s\n", tmdc->name[j], gameport->phys);
+ err = tmdc_setup_port(tmdc, i, data[i]);
+ if (err)
+ goto fail3;
}
+ }
return 0;
-fail2: gameport_close(gameport);
-fail1: gameport_set_drvdata(gameport, NULL);
+ fail3: while (--i >= 0) {
+ if (tmdc->port[i]) {
+ input_unregister_device(tmdc->port[i]->dev);
+ kfree(tmdc->port[i]);
+ }
+ }
+ fail2: gameport_close(gameport);
+ fail1: gameport_set_drvdata(gameport, NULL);
kfree(tmdc);
return err;
}
@@ -352,9 +410,12 @@ static void tmdc_disconnect(struct gameport *gameport)
struct tmdc *tmdc = gameport_get_drvdata(gameport);
int i;
- for (i = 0; i < 2; i++)
- if (tmdc->exists & (1 << i))
- input_unregister_device(tmdc->dev + i);
+ for (i = 0; i < 2; i++) {
+ if (tmdc->port[i]) {
+ input_unregister_device(tmdc->port[i]->dev);
+ kfree(tmdc->port[i]);
+ }
+ }
gameport_close(gameport);
gameport_set_drvdata(gameport, NULL);
kfree(tmdc);
diff --git a/drivers/input/joystick/turbografx.c b/drivers/input/joystick/turbografx.c
index 0c5b9c8297cd..7e9764937d06 100644
--- a/drivers/input/joystick/turbografx.c
+++ b/drivers/input/joystick/turbografx.c
@@ -42,19 +42,21 @@ MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
MODULE_DESCRIPTION("TurboGraFX parallel port interface driver");
MODULE_LICENSE("GPL");
-static int tgfx[] __initdata = { -1, 0, 0, 0, 0, 0, 0, 0 };
-static int tgfx_nargs __initdata = 0;
-module_param_array_named(map, tgfx, int, &tgfx_nargs, 0);
-MODULE_PARM_DESC(map, "Describes first set of devices (<parport#>,<js1>,<js2>,..<js7>");
+#define TGFX_MAX_PORTS 3
+#define TGFX_MAX_DEVICES 7
-static int tgfx_2[] __initdata = { -1, 0, 0, 0, 0, 0, 0, 0 };
-static int tgfx_nargs_2 __initdata = 0;
-module_param_array_named(map2, tgfx_2, int, &tgfx_nargs_2, 0);
-MODULE_PARM_DESC(map2, "Describes second set of devices");
+struct tgfx_config {
+ int args[TGFX_MAX_DEVICES + 1];
+ int nargs;
+};
+
+static struct tgfx_config tgfx[TGFX_MAX_PORTS] __initdata;
-static int tgfx_3[] __initdata = { -1, 0, 0, 0, 0, 0, 0, 0 };
-static int tgfx_nargs_3 __initdata = 0;
-module_param_array_named(map3, tgfx_3, int, &tgfx_nargs_3, 0);
+module_param_array_named(map, tgfx[0].args, int, &tgfx[0].nargs, 0);
+MODULE_PARM_DESC(map, "Describes first set of devices (<parport#>,<js1>,<js2>,..<js7>");
+module_param_array_named(map2, tgfx[1].args, int, &tgfx[1].nargs, 0);
+MODULE_PARM_DESC(map2, "Describes second set of devices");
+module_param_array_named(map3, tgfx[2].args, int, &tgfx[2].nargs, 0);
MODULE_PARM_DESC(map3, "Describes third set of devices");
__obsolete_setup("tgfx=");
@@ -75,17 +77,17 @@ __obsolete_setup("tgfx_3=");
#define TGFX_TOP2 0x08
static int tgfx_buttons[] = { BTN_TRIGGER, BTN_THUMB, BTN_THUMB2, BTN_TOP, BTN_TOP2 };
-static char *tgfx_name = "TurboGraFX Multisystem joystick";
static struct tgfx {
struct pardevice *pd;
struct timer_list timer;
- struct input_dev dev[7];
- char phys[7][32];
+ struct input_dev *dev[TGFX_MAX_DEVICES];
+ char name[TGFX_MAX_DEVICES][64];
+ char phys[TGFX_MAX_DEVICES][32];
int sticks;
int used;
struct semaphore sem;
-} *tgfx_base[3];
+} *tgfx_base[TGFX_MAX_PORTS];
/*
* tgfx_timer() reads and analyzes TurboGraFX joystick data.
@@ -100,7 +102,7 @@ static void tgfx_timer(unsigned long private)
for (i = 0; i < 7; i++)
if (tgfx->sticks & (1 << i)) {
- dev = tgfx->dev + i;
+ dev = tgfx->dev[i];
parport_write_data(tgfx->pd->port, ~(1 << i));
data1 = parport_read_status(tgfx->pd->port) ^ 0x7f;
@@ -153,118 +155,165 @@ static void tgfx_close(struct input_dev *dev)
up(&tgfx->sem);
}
+
+
/*
* tgfx_probe() probes for tg gamepads.
*/
-static struct tgfx __init *tgfx_probe(int *config, int nargs)
+static struct tgfx __init *tgfx_probe(int parport, int *n_buttons, int n_devs)
{
struct tgfx *tgfx;
+ struct input_dev *input_dev;
struct parport *pp;
+ struct pardevice *pd;
int i, j;
+ int err;
- if (config[0] < 0)
- return NULL;
-
- if (nargs < 2) {
- printk(KERN_ERR "turbografx.c: at least one joystick must be specified\n");
- return NULL;
- }
-
- pp = parport_find_number(config[0]);
-
+ pp = parport_find_number(parport);
if (!pp) {
printk(KERN_ERR "turbografx.c: no such parport\n");
- return NULL;
+ err = -EINVAL;
+ goto err_out;
}
- if (!(tgfx = kzalloc(sizeof(struct tgfx), GFP_KERNEL))) {
- parport_put_port(pp);
- return NULL;
+ pd = parport_register_device(pp, "turbografx", NULL, NULL, NULL, PARPORT_DEV_EXCL, NULL);
+ if (!pd) {
+ printk(KERN_ERR "turbografx.c: parport busy already - lp.o loaded?\n");
+ err = -EBUSY;
+ goto err_put_pp;
}
- init_MUTEX(&tgfx->sem);
-
- tgfx->pd = parport_register_device(pp, "turbografx", NULL, NULL, NULL, PARPORT_DEV_EXCL, NULL);
-
- parport_put_port(pp);
-
- if (!tgfx->pd) {
- printk(KERN_ERR "turbografx.c: parport busy already - lp.o loaded?\n");
- kfree(tgfx);
- return NULL;
+ tgfx = kzalloc(sizeof(struct tgfx), GFP_KERNEL);
+ if (!tgfx) {
+ printk(KERN_ERR "turbografx.c: Not enough memory\n");
+ err = -ENOMEM;
+ goto err_unreg_pardev;
}
+ init_MUTEX(&tgfx->sem);
+ tgfx->pd = pd;
init_timer(&tgfx->timer);
tgfx->timer.data = (long) tgfx;
tgfx->timer.function = tgfx_timer;
- tgfx->sticks = 0;
+ for (i = 0; i < n_devs; i++) {
+ if (n_buttons[i] < 1)
+ continue;
- for (i = 0; i < nargs - 1; i++)
- if (config[i+1] > 0 && config[i+1] < 6) {
-
- tgfx->sticks |= (1 << i);
+ if (n_buttons[i] > 6) {
+ printk(KERN_ERR "turbografx.c: Invalid number of buttons %d\n", n_buttons[i]);
+ err = -EINVAL;
+ goto err_free_devs;
+ }
- tgfx->dev[i].private = tgfx;
- tgfx->dev[i].open = tgfx_open;
- tgfx->dev[i].close = tgfx_close;
+ tgfx->dev[i] = input_dev = input_allocate_device();
+ if (!input_dev) {
+ printk(KERN_ERR "turbografx.c: Not enough memory for input device\n");
+ err = -ENOMEM;
+ goto err_free_devs;
+ }
- sprintf(tgfx->phys[i], "%s/input0", tgfx->pd->port->name);
+ tgfx->sticks |= (1 << i);
+ snprintf(tgfx->name[i], sizeof(tgfx->name[i]),
+ "TurboGraFX %d-button Multisystem joystick", n_buttons[i]);
+ snprintf(tgfx->phys[i], sizeof(tgfx->phys[i]),
+ "%s/input%d", tgfx->pd->port->name, i);
- tgfx->dev[i].name = tgfx_name;
- tgfx->dev[i].phys = tgfx->phys[i];
- tgfx->dev[i].id.bustype = BUS_PARPORT;
- tgfx->dev[i].id.vendor = 0x0003;
- tgfx->dev[i].id.product = config[i+1];
- tgfx->dev[i].id.version = 0x0100;
+ input_dev->name = tgfx->name[i];
+ input_dev->phys = tgfx->phys[i];
+ input_dev->id.bustype = BUS_PARPORT;
+ input_dev->id.vendor = 0x0003;
+ input_dev->id.product = n_buttons[i];
+ input_dev->id.version = 0x0100;
- tgfx->dev[i].evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
- tgfx->dev[i].absbit[0] = BIT(ABS_X) | BIT(ABS_Y);
+ input_dev->private = tgfx;
+ input_dev->open = tgfx_open;
+ input_dev->close = tgfx_close;
- for (j = 0; j < config[i+1]; j++)
- set_bit(tgfx_buttons[j], tgfx->dev[i].keybit);
+ input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+ input_set_abs_params(input_dev, ABS_X, -1, 1, 0, 0);
+ input_set_abs_params(input_dev, ABS_Y, -1, 1, 0, 0);
- tgfx->dev[i].absmin[ABS_X] = -1; tgfx->dev[i].absmax[ABS_X] = 1;
- tgfx->dev[i].absmin[ABS_Y] = -1; tgfx->dev[i].absmax[ABS_Y] = 1;
+ for (j = 0; j < n_buttons[i]; j++)
+ set_bit(tgfx_buttons[j], input_dev->keybit);
- input_register_device(tgfx->dev + i);
- printk(KERN_INFO "input: %d-button Multisystem joystick on %s\n",
- config[i+1], tgfx->pd->port->name);
- }
+ input_register_device(tgfx->dev[i]);
+ }
if (!tgfx->sticks) {
- parport_unregister_device(tgfx->pd);
- kfree(tgfx);
- return NULL;
+ printk(KERN_ERR "turbografx.c: No valid devices specified\n");
+ err = -EINVAL;
+ goto err_free_tgfx;
}
return tgfx;
+
+ err_free_devs:
+ while (--i >= 0)
+ input_unregister_device(tgfx->dev[i]);
+ err_free_tgfx:
+ kfree(tgfx);
+ err_unreg_pardev:
+ parport_unregister_device(pd);
+ err_put_pp:
+ parport_put_port(pp);
+ err_out:
+ return ERR_PTR(err);
+}
+
+static void __exit tgfx_remove(struct tgfx *tgfx)
+{
+ int i;
+
+ for (i = 0; i < TGFX_MAX_DEVICES; i++)
+ if (tgfx->dev[i])
+ input_unregister_device(tgfx->dev[i]);
+ parport_unregister_device(tgfx->pd);
+ kfree(tgfx);
}
static int __init tgfx_init(void)
{
- tgfx_base[0] = tgfx_probe(tgfx, tgfx_nargs);
- tgfx_base[1] = tgfx_probe(tgfx_2, tgfx_nargs_2);
- tgfx_base[2] = tgfx_probe(tgfx_3, tgfx_nargs_3);
+ int i;
+ int have_dev = 0;
+ int err = 0;
+
+ for (i = 0; i < TGFX_MAX_PORTS; i++) {
+ if (tgfx[i].nargs == 0 || tgfx[i].args[0] < 0)
+ continue;
+
+ if (tgfx[i].nargs < 2) {
+ printk(KERN_ERR "turbografx.c: at least one joystick must be specified\n");
+ err = -EINVAL;
+ break;
+ }
+
+ tgfx_base[i] = tgfx_probe(tgfx[i].args[0], tgfx[i].args + 1, tgfx[i].nargs - 1);
+ if (IS_ERR(tgfx_base[i])) {
+ err = PTR_ERR(tgfx_base[i]);
+ break;
+ }
+
+ have_dev = 1;
+ }
- if (tgfx_base[0] || tgfx_base[1] || tgfx_base[2])
- return 0;
+ if (err) {
+ while (--i >= 0)
+ tgfx_remove(tgfx_base[i]);
+ return err;
+ }
- return -ENODEV;
+ return have_dev ? 0 : -ENODEV;
}
static void __exit tgfx_exit(void)
{
- int i, j;
+ int i;
- for (i = 0; i < 3; i++)
- if (tgfx_base[i]) {
- for (j = 0; j < 7; j++)
- if (tgfx_base[i]->sticks & (1 << j))
- input_unregister_device(tgfx_base[i]->dev + j);
- parport_unregister_device(tgfx_base[i]->pd);
- }
+ for (i = 0; i < TGFX_MAX_PORTS; i++)
+ if (tgfx_base[i])
+ tgfx_remove(tgfx_base[i]);
}
module_init(tgfx_init);
diff --git a/drivers/input/joystick/twidjoy.c b/drivers/input/joystick/twidjoy.c
index 0379bc166525..cd3a1e742a30 100644
--- a/drivers/input/joystick/twidjoy.c
+++ b/drivers/input/joystick/twidjoy.c
@@ -69,8 +69,6 @@ MODULE_LICENSE("GPL");
#define TWIDJOY_MAX_LENGTH 5
-static char *twidjoy_name = "Handykey Twiddler";
-
static struct twidjoy_button_spec {
int bitshift;
int bitmask;
@@ -95,7 +93,7 @@ twidjoy_buttons[] = {
*/
struct twidjoy {
- struct input_dev dev;
+ struct input_dev *dev;
int idx;
unsigned char data[TWIDJOY_MAX_LENGTH];
char phys[32];
@@ -108,37 +106,33 @@ struct twidjoy {
static void twidjoy_process_packet(struct twidjoy *twidjoy, struct pt_regs *regs)
{
- if (twidjoy->idx == TWIDJOY_MAX_LENGTH) {
- struct input_dev *dev = &twidjoy->dev;
- unsigned char *data = twidjoy->data;
- struct twidjoy_button_spec *bp;
- int button_bits, abs_x, abs_y;
-
- button_bits = ((data[1] & 0x7f) << 7) | (data[0] & 0x7f);
+ struct input_dev *dev = twidjoy->dev;
+ unsigned char *data = twidjoy->data;
+ struct twidjoy_button_spec *bp;
+ int button_bits, abs_x, abs_y;
- input_regs(dev, regs);
+ button_bits = ((data[1] & 0x7f) << 7) | (data[0] & 0x7f);
- for (bp = twidjoy_buttons; bp->bitmask; bp++) {
- int value = (button_bits & (bp->bitmask << bp->bitshift)) >> bp->bitshift;
- int i;
+ input_regs(dev, regs);
- for (i = 0; i < bp->bitmask; i++)
- input_report_key(dev, bp->buttons[i], i+1 == value);
- }
+ for (bp = twidjoy_buttons; bp->bitmask; bp++) {
+ int value = (button_bits & (bp->bitmask << bp->bitshift)) >> bp->bitshift;
+ int i;
- abs_x = ((data[4] & 0x07) << 5) | ((data[3] & 0x7C) >> 2);
- if (data[4] & 0x08) abs_x -= 256;
+ for (i = 0; i < bp->bitmask; i++)
+ input_report_key(dev, bp->buttons[i], i+1 == value);
+ }
- abs_y = ((data[3] & 0x01) << 7) | ((data[2] & 0x7F) >> 0);
- if (data[3] & 0x02) abs_y -= 256;
+ abs_x = ((data[4] & 0x07) << 5) | ((data[3] & 0x7C) >> 2);
+ if (data[4] & 0x08) abs_x -= 256;
- input_report_abs(dev, ABS_X, -abs_x);
- input_report_abs(dev, ABS_Y, +abs_y);
+ abs_y = ((data[3] & 0x01) << 7) | ((data[2] & 0x7F) >> 0);
+ if (data[3] & 0x02) abs_y -= 256;
- input_sync(dev);
- }
+ input_report_abs(dev, ABS_X, -abs_x);
+ input_report_abs(dev, ABS_Y, +abs_y);
- return;
+ input_sync(dev);
}
/*
@@ -179,9 +173,9 @@ static void twidjoy_disconnect(struct serio *serio)
{
struct twidjoy *twidjoy = serio_get_drvdata(serio);
- input_unregister_device(&twidjoy->dev);
serio_close(serio);
serio_set_drvdata(serio, NULL);
+ input_unregister_device(twidjoy->dev);
kfree(twidjoy);
}
@@ -195,59 +189,49 @@ static int twidjoy_connect(struct serio *serio, struct serio_driver *drv)
{
struct twidjoy_button_spec *bp;
struct twidjoy *twidjoy;
+ struct input_dev *input_dev;
+ int err = -ENOMEM;
int i;
- int err;
-
- if (!(twidjoy = kmalloc(sizeof(struct twidjoy), GFP_KERNEL)))
- return -ENOMEM;
- memset(twidjoy, 0, sizeof(struct twidjoy));
+ twidjoy = kzalloc(sizeof(struct twidjoy), GFP_KERNEL);
+ input_dev = input_allocate_device();
+ if (!twidjoy || !input_dev)
+ goto fail;
+ twidjoy->dev = input_dev;
sprintf(twidjoy->phys, "%s/input0", serio->phys);
- init_input_dev(&twidjoy->dev);
- twidjoy->dev.name = twidjoy_name;
- twidjoy->dev.phys = twidjoy->phys;
- twidjoy->dev.id.bustype = BUS_RS232;
- twidjoy->dev.id.vendor = SERIO_TWIDJOY;
- twidjoy->dev.id.product = 0x0001;
- twidjoy->dev.id.version = 0x0100;
- twidjoy->dev.dev = &serio->dev;
-
- twidjoy->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
-
- for (bp = twidjoy_buttons; bp->bitmask; bp++) {
+ input_dev->name = "Handykey Twiddler";
+ input_dev->phys = twidjoy->phys;
+ input_dev->id.bustype = BUS_RS232;
+ input_dev->id.vendor = SERIO_TWIDJOY;
+ input_dev->id.product = 0x0001;
+ input_dev->id.version = 0x0100;
+ input_dev->cdev.dev = &serio->dev;
+ input_dev->private = twidjoy;
+
+ input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+ input_dev->absbit[0] = BIT(ABS_X) | BIT(ABS_Y);
+ input_set_abs_params(input_dev, ABS_X, -50, 50, 4, 4);
+ input_set_abs_params(input_dev, ABS_Y, -50, 50, 4, 4);
+
+ for (bp = twidjoy_buttons; bp->bitmask; bp++)
for (i = 0; i < bp->bitmask; i++)
- set_bit(bp->buttons[i], twidjoy->dev.keybit);
- }
-
- twidjoy->dev.absbit[0] = BIT(ABS_X) | BIT(ABS_Y);
-
- for (i = 0; i < 2; i++) {
- twidjoy->dev.absmax[ABS_X+i] = 50;
- twidjoy->dev.absmin[ABS_X+i] = -50;
-
- /* TODO: arndt 20010708: Are these values appropriate? */
- twidjoy->dev.absfuzz[ABS_X+i] = 4;
- twidjoy->dev.absflat[ABS_X+i] = 4;
- }
-
- twidjoy->dev.private = twidjoy;
+ set_bit(bp->buttons[i], input_dev->keybit);
serio_set_drvdata(serio, twidjoy);
err = serio_open(serio, drv);
- if (err) {
- serio_set_drvdata(serio, NULL);
- kfree(twidjoy);
- return err;
- }
-
- input_register_device(&twidjoy->dev);
-
- printk(KERN_INFO "input: %s on %s\n", twidjoy_name, serio->phys);
+ if (err)
+ goto fail;
+ input_register_device(twidjoy->dev);
return 0;
+
+ fail: serio_set_drvdata(serio, NULL);
+ input_free_device(input_dev);
+ kfree(twidjoy);
+ return err;
}
/*
diff --git a/drivers/input/joystick/warrior.c b/drivers/input/joystick/warrior.c
index 6976a219504c..99a642d2a1fe 100644
--- a/drivers/input/joystick/warrior.c
+++ b/drivers/input/joystick/warrior.c
@@ -47,14 +47,13 @@ MODULE_LICENSE("GPL");
#define WARRIOR_MAX_LENGTH 16
static char warrior_lengths[] = { 0, 4, 12, 3, 4, 4, 0, 0 };
-static char *warrior_name = "Logitech WingMan Warrior";
/*
* Per-Warrior data.
*/
struct warrior {
- struct input_dev dev;
+ struct input_dev *dev;
int idx, len;
unsigned char data[WARRIOR_MAX_LENGTH];
char phys[32];
@@ -67,7 +66,7 @@ struct warrior {
static void warrior_process_packet(struct warrior *warrior, struct pt_regs *regs)
{
- struct input_dev *dev = &warrior->dev;
+ struct input_dev *dev = warrior->dev;
unsigned char *data = warrior->data;
if (!warrior->idx) return;
@@ -131,9 +130,9 @@ static void warrior_disconnect(struct serio *serio)
{
struct warrior *warrior = serio_get_drvdata(serio);
- input_unregister_device(&warrior->dev);
serio_close(serio);
serio_set_drvdata(serio, NULL);
+ input_unregister_device(warrior->dev);
kfree(warrior);
}
@@ -146,60 +145,48 @@ static void warrior_disconnect(struct serio *serio)
static int warrior_connect(struct serio *serio, struct serio_driver *drv)
{
struct warrior *warrior;
- int i;
- int err;
+ struct input_dev *input_dev;
+ int err = -ENOMEM;
- if (!(warrior = kmalloc(sizeof(struct warrior), GFP_KERNEL)))
- return -ENOMEM;
-
- memset(warrior, 0, sizeof(struct warrior));
-
- warrior->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REL) | BIT(EV_ABS);
- warrior->dev.keybit[LONG(BTN_TRIGGER)] = BIT(BTN_TRIGGER) | BIT(BTN_THUMB) | BIT(BTN_TOP) | BIT(BTN_TOP2);
- warrior->dev.relbit[0] = BIT(REL_DIAL);
- warrior->dev.absbit[0] = BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_THROTTLE) | BIT(ABS_HAT0X) | BIT(ABS_HAT0Y);
+ warrior = kzalloc(sizeof(struct warrior), GFP_KERNEL);
+ input_dev = input_allocate_device();
+ if (!warrior || !input_dev)
+ goto fail;
+ warrior->dev = input_dev;
sprintf(warrior->phys, "%s/input0", serio->phys);
- init_input_dev(&warrior->dev);
- warrior->dev.name = warrior_name;
- warrior->dev.phys = warrior->phys;
- warrior->dev.id.bustype = BUS_RS232;
- warrior->dev.id.vendor = SERIO_WARRIOR;
- warrior->dev.id.product = 0x0001;
- warrior->dev.id.version = 0x0100;
- warrior->dev.dev = &serio->dev;
-
- for (i = 0; i < 2; i++) {
- warrior->dev.absmax[ABS_X+i] = -64;
- warrior->dev.absmin[ABS_X+i] = 64;
- warrior->dev.absflat[ABS_X+i] = 8;
- }
-
- warrior->dev.absmax[ABS_THROTTLE] = -112;
- warrior->dev.absmin[ABS_THROTTLE] = 112;
-
- for (i = 0; i < 2; i++) {
- warrior->dev.absmax[ABS_HAT0X+i] = -1;
- warrior->dev.absmin[ABS_HAT0X+i] = 1;
- }
-
- warrior->dev.private = warrior;
+ input_dev->name = "Logitech WingMan Warrior";
+ input_dev->phys = warrior->phys;
+ input_dev->id.bustype = BUS_RS232;
+ input_dev->id.vendor = SERIO_WARRIOR;
+ input_dev->id.product = 0x0001;
+ input_dev->id.version = 0x0100;
+ input_dev->cdev.dev = &serio->dev;
+ input_dev->private = warrior;
+
+ input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL) | BIT(EV_ABS);
+ input_dev->keybit[LONG(BTN_TRIGGER)] = BIT(BTN_TRIGGER) | BIT(BTN_THUMB) | BIT(BTN_TOP) | BIT(BTN_TOP2);
+ input_dev->relbit[0] = BIT(REL_DIAL);
+ input_set_abs_params(input_dev, ABS_X, -64, 64, 0, 8);
+ input_set_abs_params(input_dev, ABS_Y, -64, 64, 0, 8);
+ input_set_abs_params(input_dev, ABS_THROTTLE, -112, 112, 0, 0);
+ input_set_abs_params(input_dev, ABS_HAT0X, -1, 1, 0, 0);
+ input_set_abs_params(input_dev, ABS_HAT0X, -1, 1, 0, 0);
serio_set_drvdata(serio, warrior);
err = serio_open(serio, drv);
- if (err) {
- serio_set_drvdata(serio, NULL);
- kfree(warrior);
- return err;
- }
-
- input_register_device(&warrior->dev);
-
- printk(KERN_INFO "input: Logitech WingMan Warrior on %s\n", serio->phys);
+ if (err)
+ goto fail;
+ input_register_device(warrior->dev);
return 0;
+
+ fail: serio_set_drvdata(serio, NULL);
+ input_free_device(input_dev);
+ kfree(warrior);
+ return err;
}
/*
diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
index 571a68691a4a..4a917748fd9f 100644
--- a/drivers/input/keyboard/Kconfig
+++ b/drivers/input/keyboard/Kconfig
@@ -13,11 +13,11 @@ menuconfig INPUT_KEYBOARD
if INPUT_KEYBOARD
config KEYBOARD_ATKBD
- tristate "AT keyboard" if !PC
+ tristate "AT keyboard" if !X86_PC
default y
select SERIO
select SERIO_LIBPS2
- select SERIO_I8042 if PC
+ select SERIO_I8042 if X86_PC
select SERIO_GSCPS2 if GSC
help
Say Y here if you want to use a standard AT or PS/2 keyboard. Usually
diff --git a/drivers/input/keyboard/amikbd.c b/drivers/input/keyboard/amikbd.c
index 4e8e8ea214ab..4c8fb1f8631f 100644
--- a/drivers/input/keyboard/amikbd.c
+++ b/drivers/input/keyboard/amikbd.c
@@ -155,10 +155,7 @@ static const char *amikbd_messages[8] = {
[7] = KERN_WARNING "amikbd: keyboard interrupt\n"
};
-static struct input_dev amikbd_dev;
-
-static char *amikbd_name = "Amiga keyboard";
-static char *amikbd_phys = "amikbd/input0";
+static struct input_dev *amikbd_dev;
static irqreturn_t amikbd_interrupt(int irq, void *dummy, struct pt_regs *fp)
{
@@ -176,16 +173,16 @@ static irqreturn_t amikbd_interrupt(int irq, void *dummy, struct pt_regs *fp)
scancode = amikbd_keycode[scancode];
- input_regs(&amikbd_dev, fp);
+ input_regs(amikbd_dev, fp);
if (scancode == KEY_CAPSLOCK) { /* CapsLock is a toggle switch key on Amiga */
- input_report_key(&amikbd_dev, scancode, 1);
- input_report_key(&amikbd_dev, scancode, 0);
- input_sync(&amikbd_dev);
+ input_report_key(amikbd_dev, scancode, 1);
+ input_report_key(amikbd_dev, scancode, 0);
} else {
- input_report_key(&amikbd_dev, scancode, down);
- input_sync(&amikbd_dev);
+ input_report_key(amikbd_dev, scancode, down);
}
+
+ input_sync(amikbd_dev);
} else /* scancodes >= 0x78 are error codes */
printk(amikbd_messages[scancode - 0x78]);
@@ -202,39 +199,41 @@ static int __init amikbd_init(void)
if (!request_mem_region(CIAA_PHYSADDR-1+0xb00, 0x100, "amikeyb"))
return -EBUSY;
- init_input_dev(&amikbd_dev);
-
- amikbd_dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
- amikbd_dev.keycode = amikbd_keycode;
- amikbd_dev.keycodesize = sizeof(unsigned char);
- amikbd_dev.keycodemax = ARRAY_SIZE(amikbd_keycode);
+ amikbd_dev = input_allocate_device();
+ if (!amikbd_dev) {
+ printk(KERN_ERR "amikbd: not enough memory for input device\n");
+ release_mem_region(CIAA_PHYSADDR - 1 + 0xb00, 0x100);
+ return -ENOMEM;
+ }
+
+ amikbd_dev->name = "Amiga Keyboard";
+ amikbd_dev->phys = "amikbd/input0";
+ amikbd_dev->id.bustype = BUS_AMIGA;
+ amikbd_dev->id.vendor = 0x0001;
+ amikbd_dev->id.product = 0x0001;
+ amikbd_dev->id.version = 0x0100;
+
+ amikbd_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
+ amikbd_dev->keycode = amikbd_keycode;
+ amikbd_dev->keycodesize = sizeof(unsigned char);
+ amikbd_dev->keycodemax = ARRAY_SIZE(amikbd_keycode);
for (i = 0; i < 0x78; i++)
if (amikbd_keycode[i])
- set_bit(amikbd_keycode[i], amikbd_dev.keybit);
+ set_bit(amikbd_keycode[i], amikbd_dev->keybit);
ciaa.cra &= ~0x41; /* serial data in, turn off TA */
request_irq(IRQ_AMIGA_CIAA_SP, amikbd_interrupt, 0, "amikbd", amikbd_interrupt);
- amikbd_dev.name = amikbd_name;
- amikbd_dev.phys = amikbd_phys;
- amikbd_dev.id.bustype = BUS_AMIGA;
- amikbd_dev.id.vendor = 0x0001;
- amikbd_dev.id.product = 0x0001;
- amikbd_dev.id.version = 0x0100;
-
- input_register_device(&amikbd_dev);
-
- printk(KERN_INFO "input: %s\n", amikbd_name);
-
+ input_register_device(amikbd_dev);
return 0;
}
static void __exit amikbd_exit(void)
{
- input_unregister_device(&amikbd_dev);
free_irq(IRQ_AMIGA_CIAA_SP, amikbd_interrupt);
- release_mem_region(CIAA_PHYSADDR-1+0xb00, 0x100);
+ input_unregister_device(amikbd_dev);
+ release_mem_region(CIAA_PHYSADDR - 1 + 0xb00, 0x100);
}
module_init(amikbd_init);
diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c
index 1ad8c2ee7dbf..820c7fd9a604 100644
--- a/drivers/input/keyboard/atkbd.c
+++ b/drivers/input/keyboard/atkbd.c
@@ -185,12 +185,12 @@ static struct {
struct atkbd {
- struct ps2dev ps2dev;
+ struct ps2dev ps2dev;
+ struct input_dev *dev;
/* Written only during init */
char name[64];
char phys[32];
- struct input_dev dev;
unsigned short id;
unsigned char keycode[512];
@@ -290,7 +290,7 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data,
if (!atkbd->enabled)
goto out;
- input_event(&atkbd->dev, EV_MSC, MSC_RAW, code);
+ input_event(atkbd->dev, EV_MSC, MSC_RAW, code);
if (atkbd->translated) {
@@ -326,10 +326,10 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data,
atkbd->release = 1;
goto out;
case ATKBD_RET_HANGUEL:
- atkbd_report_key(&atkbd->dev, regs, KEY_HANGUEL, 3);
+ atkbd_report_key(atkbd->dev, regs, KEY_HANGUEL, 3);
goto out;
case ATKBD_RET_HANJA:
- atkbd_report_key(&atkbd->dev, regs, KEY_HANJA, 3);
+ atkbd_report_key(atkbd->dev, regs, KEY_HANJA, 3);
goto out;
case ATKBD_RET_ERR:
printk(KERN_DEBUG "atkbd.c: Keyboard on %s reports too many keys pressed.\n", serio->phys);
@@ -345,7 +345,7 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data,
}
if (atkbd->keycode[code] != ATKBD_KEY_NULL)
- input_event(&atkbd->dev, EV_MSC, MSC_SCAN, code);
+ input_event(atkbd->dev, EV_MSC, MSC_SCAN, code);
switch (atkbd->keycode[code]) {
case ATKBD_KEY_NULL:
@@ -365,7 +365,7 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data,
"to make it known.\n",
code & 0x80 ? "e0" : "", code & 0x7f);
}
- input_sync(&atkbd->dev);
+ input_sync(atkbd->dev);
break;
case ATKBD_SCR_1:
scroll = 1 - atkbd->release * 2;
@@ -390,7 +390,7 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data,
break;
default:
value = atkbd->release ? 0 :
- (1 + (!atkbd->softrepeat && test_bit(atkbd->keycode[code], atkbd->dev.key)));
+ (1 + (!atkbd->softrepeat && test_bit(atkbd->keycode[code], atkbd->dev->key)));
switch (value) { /* Workaround Toshiba laptop multiple keypress */
case 0:
@@ -398,7 +398,7 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data,
break;
case 1:
atkbd->last = code;
- atkbd->time = jiffies + msecs_to_jiffies(atkbd->dev.rep[REP_DELAY]) / 2;
+ atkbd->time = jiffies + msecs_to_jiffies(atkbd->dev->rep[REP_DELAY]) / 2;
break;
case 2:
if (!time_after(jiffies, atkbd->time) && atkbd->last == code)
@@ -406,16 +406,16 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data,
break;
}
- atkbd_report_key(&atkbd->dev, regs, atkbd->keycode[code], value);
+ atkbd_report_key(atkbd->dev, regs, atkbd->keycode[code], value);
}
if (atkbd->scroll) {
- input_regs(&atkbd->dev, regs);
+ input_regs(atkbd->dev, regs);
if (click != -1)
- input_report_key(&atkbd->dev, BTN_MIDDLE, click);
- input_report_rel(&atkbd->dev, REL_WHEEL, scroll);
- input_report_rel(&atkbd->dev, REL_HWHEEL, hscroll);
- input_sync(&atkbd->dev);
+ input_report_key(atkbd->dev, BTN_MIDDLE, click);
+ input_report_rel(atkbd->dev, REL_WHEEL, scroll);
+ input_report_rel(atkbd->dev, REL_HWHEEL, hscroll);
+ input_sync(atkbd->dev);
}
atkbd->release = 0;
@@ -463,7 +463,6 @@ static int atkbd_event(struct input_dev *dev, unsigned int type, unsigned int co
return 0;
-
case EV_REP:
if (atkbd->softrepeat) return 0;
@@ -693,7 +692,7 @@ static void atkbd_disconnect(struct serio *serio)
device_remove_file(&serio->dev, &atkbd_attr_softrepeat);
device_remove_file(&serio->dev, &atkbd_attr_softraw);
- input_unregister_device(&atkbd->dev);
+ input_unregister_device(atkbd->dev);
serio_close(serio);
serio_set_drvdata(serio, NULL);
kfree(atkbd);
@@ -701,7 +700,7 @@ static void atkbd_disconnect(struct serio *serio)
/*
- * atkbd_set_device_attrs() initializes keyboard's keycode table
+ * atkbd_set_keycode_table() initializes keyboard's keycode table
* according to the selected scancode set
*/
@@ -737,53 +736,58 @@ static void atkbd_set_keycode_table(struct atkbd *atkbd)
static void atkbd_set_device_attrs(struct atkbd *atkbd)
{
+ struct input_dev *input_dev = atkbd->dev;
int i;
- memset(&atkbd->dev, 0, sizeof(struct input_dev));
+ if (atkbd->extra)
+ sprintf(atkbd->name, "AT Set 2 Extra keyboard");
+ else
+ sprintf(atkbd->name, "AT %s Set %d keyboard",
+ atkbd->translated ? "Translated" : "Raw", atkbd->set);
- init_input_dev(&atkbd->dev);
+ sprintf(atkbd->phys, "%s/input0", atkbd->ps2dev.serio->phys);
- atkbd->dev.name = atkbd->name;
- atkbd->dev.phys = atkbd->phys;
- atkbd->dev.id.bustype = BUS_I8042;
- atkbd->dev.id.vendor = 0x0001;
- atkbd->dev.id.product = atkbd->translated ? 1 : atkbd->set;
- atkbd->dev.id.version = atkbd->id;
- atkbd->dev.event = atkbd_event;
- atkbd->dev.private = atkbd;
- atkbd->dev.dev = &atkbd->ps2dev.serio->dev;
+ input_dev->name = atkbd->name;
+ input_dev->phys = atkbd->phys;
+ input_dev->id.bustype = BUS_I8042;
+ input_dev->id.vendor = 0x0001;
+ input_dev->id.product = atkbd->translated ? 1 : atkbd->set;
+ input_dev->id.version = atkbd->id;
+ input_dev->event = atkbd_event;
+ input_dev->private = atkbd;
+ input_dev->cdev.dev = &atkbd->ps2dev.serio->dev;
- atkbd->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REP) | BIT(EV_MSC);
+ input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP) | BIT(EV_MSC);
if (atkbd->write) {
- atkbd->dev.evbit[0] |= BIT(EV_LED);
- atkbd->dev.ledbit[0] = BIT(LED_NUML) | BIT(LED_CAPSL) | BIT(LED_SCROLLL);
+ input_dev->evbit[0] |= BIT(EV_LED);
+ input_dev->ledbit[0] = BIT(LED_NUML) | BIT(LED_CAPSL) | BIT(LED_SCROLLL);
}
if (atkbd->extra)
- atkbd->dev.ledbit[0] |= BIT(LED_COMPOSE) | BIT(LED_SUSPEND) |
+ input_dev->ledbit[0] |= BIT(LED_COMPOSE) | BIT(LED_SUSPEND) |
BIT(LED_SLEEP) | BIT(LED_MUTE) | BIT(LED_MISC);
if (!atkbd->softrepeat) {
- atkbd->dev.rep[REP_DELAY] = 250;
- atkbd->dev.rep[REP_PERIOD] = 33;
+ input_dev->rep[REP_DELAY] = 250;
+ input_dev->rep[REP_PERIOD] = 33;
}
- atkbd->dev.mscbit[0] = atkbd->softraw ? BIT(MSC_SCAN) : BIT(MSC_RAW) | BIT(MSC_SCAN);
+ input_dev->mscbit[0] = atkbd->softraw ? BIT(MSC_SCAN) : BIT(MSC_RAW) | BIT(MSC_SCAN);
if (atkbd->scroll) {
- atkbd->dev.evbit[0] |= BIT(EV_REL);
- atkbd->dev.relbit[0] = BIT(REL_WHEEL) | BIT(REL_HWHEEL);
- set_bit(BTN_MIDDLE, atkbd->dev.keybit);
+ input_dev->evbit[0] |= BIT(EV_REL);
+ input_dev->relbit[0] = BIT(REL_WHEEL) | BIT(REL_HWHEEL);
+ set_bit(BTN_MIDDLE, input_dev->keybit);
}
- atkbd->dev.keycode = atkbd->keycode;
- atkbd->dev.keycodesize = sizeof(unsigned char);
- atkbd->dev.keycodemax = ARRAY_SIZE(atkbd_set2_keycode);
+ input_dev->keycode = atkbd->keycode;
+ input_dev->keycodesize = sizeof(unsigned char);
+ input_dev->keycodemax = ARRAY_SIZE(atkbd_set2_keycode);
for (i = 0; i < 512; i++)
if (atkbd->keycode[i] && atkbd->keycode[i] < ATKBD_SPECIAL)
- set_bit(atkbd->keycode[i], atkbd->dev.keybit);
+ set_bit(atkbd->keycode[i], input_dev->keybit);
}
/*
@@ -796,13 +800,15 @@ static void atkbd_set_device_attrs(struct atkbd *atkbd)
static int atkbd_connect(struct serio *serio, struct serio_driver *drv)
{
struct atkbd *atkbd;
- int err;
-
- if (!(atkbd = kmalloc(sizeof(struct atkbd), GFP_KERNEL)))
- return - ENOMEM;
+ struct input_dev *dev;
+ int err = -ENOMEM;
- memset(atkbd, 0, sizeof(struct atkbd));
+ atkbd = kzalloc(sizeof(struct atkbd), GFP_KERNEL);
+ dev = input_allocate_device();
+ if (!atkbd || !dev)
+ goto fail;
+ atkbd->dev = dev;
ps2_init(&atkbd->ps2dev, serio);
switch (serio->id.type) {
@@ -828,19 +834,15 @@ static int atkbd_connect(struct serio *serio, struct serio_driver *drv)
serio_set_drvdata(serio, atkbd);
err = serio_open(serio, drv);
- if (err) {
- serio_set_drvdata(serio, NULL);
- kfree(atkbd);
- return err;
- }
+ if (err)
+ goto fail;
if (atkbd->write) {
if (atkbd_probe(atkbd)) {
serio_close(serio);
- serio_set_drvdata(serio, NULL);
- kfree(atkbd);
- return -ENODEV;
+ err = -ENODEV;
+ goto fail;
}
atkbd->set = atkbd_select_set(atkbd, atkbd_set, atkbd_extra);
@@ -851,19 +853,9 @@ static int atkbd_connect(struct serio *serio, struct serio_driver *drv)
atkbd->id = 0xab00;
}
- if (atkbd->extra)
- sprintf(atkbd->name, "AT Set 2 Extra keyboard");
- else
- sprintf(atkbd->name, "AT %s Set %d keyboard",
- atkbd->translated ? "Translated" : "Raw", atkbd->set);
-
- sprintf(atkbd->phys, "%s/input0", serio->phys);
-
atkbd_set_keycode_table(atkbd);
atkbd_set_device_attrs(atkbd);
- input_register_device(&atkbd->dev);
-
device_create_file(&serio->dev, &atkbd_attr_extra);
device_create_file(&serio->dev, &atkbd_attr_scroll);
device_create_file(&serio->dev, &atkbd_attr_set);
@@ -872,9 +864,14 @@ static int atkbd_connect(struct serio *serio, struct serio_driver *drv)
atkbd_enable(atkbd);
- printk(KERN_INFO "input: %s on %s\n", atkbd->name, serio->phys);
+ input_register_device(atkbd->dev);
return 0;
+
+ fail: serio_set_drvdata(serio, NULL);
+ input_free_device(dev);
+ kfree(atkbd);
+ return err;
}
/*
@@ -896,9 +893,9 @@ static int atkbd_reconnect(struct serio *serio)
atkbd_disable(atkbd);
if (atkbd->write) {
- param[0] = (test_bit(LED_SCROLLL, atkbd->dev.led) ? 1 : 0)
- | (test_bit(LED_NUML, atkbd->dev.led) ? 2 : 0)
- | (test_bit(LED_CAPSL, atkbd->dev.led) ? 4 : 0);
+ param[0] = (test_bit(LED_SCROLLL, atkbd->dev->led) ? 1 : 0)
+ | (test_bit(LED_NUML, atkbd->dev->led) ? 2 : 0)
+ | (test_bit(LED_CAPSL, atkbd->dev->led) ? 4 : 0);
if (atkbd_probe(atkbd))
return -1;
@@ -1008,6 +1005,7 @@ static ssize_t atkbd_show_extra(struct atkbd *atkbd, char *buf)
static ssize_t atkbd_set_extra(struct atkbd *atkbd, const char *buf, size_t count)
{
+ struct input_dev *new_dev;
unsigned long value;
char *rest;
@@ -1019,12 +1017,19 @@ static ssize_t atkbd_set_extra(struct atkbd *atkbd, const char *buf, size_t coun
return -EINVAL;
if (atkbd->extra != value) {
- /* unregister device as it's properties will change */
- input_unregister_device(&atkbd->dev);
+ /*
+ * Since device's properties will change we need to
+ * unregister old device. But allocate new one first
+ * to make sure we have it.
+ */
+ if (!(new_dev = input_allocate_device()))
+ return -ENOMEM;
+ input_unregister_device(atkbd->dev);
+ atkbd->dev = new_dev;
atkbd->set = atkbd_select_set(atkbd, atkbd->set, value);
atkbd_activate(atkbd);
atkbd_set_device_attrs(atkbd);
- input_register_device(&atkbd->dev);
+ input_register_device(atkbd->dev);
}
return count;
}
@@ -1036,6 +1041,7 @@ static ssize_t atkbd_show_scroll(struct atkbd *atkbd, char *buf)
static ssize_t atkbd_set_scroll(struct atkbd *atkbd, const char *buf, size_t count)
{
+ struct input_dev *new_dev;
unsigned long value;
char *rest;
@@ -1044,12 +1050,14 @@ static ssize_t atkbd_set_scroll(struct atkbd *atkbd, const char *buf, size_t cou
return -EINVAL;
if (atkbd->scroll != value) {
- /* unregister device as it's properties will change */
- input_unregister_device(&atkbd->dev);
+ if (!(new_dev = input_allocate_device()))
+ return -ENOMEM;
+ input_unregister_device(atkbd->dev);
+ atkbd->dev = new_dev;
atkbd->scroll = value;
atkbd_set_keycode_table(atkbd);
atkbd_set_device_attrs(atkbd);
- input_register_device(&atkbd->dev);
+ input_register_device(atkbd->dev);
}
return count;
}
@@ -1061,6 +1069,7 @@ static ssize_t atkbd_show_set(struct atkbd *atkbd, char *buf)
static ssize_t atkbd_set_set(struct atkbd *atkbd, const char *buf, size_t count)
{
+ struct input_dev *new_dev;
unsigned long value;
char *rest;
@@ -1072,13 +1081,15 @@ static ssize_t atkbd_set_set(struct atkbd *atkbd, const char *buf, size_t count)
return -EINVAL;
if (atkbd->set != value) {
- /* unregister device as it's properties will change */
- input_unregister_device(&atkbd->dev);
+ if (!(new_dev = input_allocate_device()))
+ return -ENOMEM;
+ input_unregister_device(atkbd->dev);
+ atkbd->dev = new_dev;
atkbd->set = atkbd_select_set(atkbd, value, atkbd->extra);
atkbd_activate(atkbd);
atkbd_set_keycode_table(atkbd);
atkbd_set_device_attrs(atkbd);
- input_register_device(&atkbd->dev);
+ input_register_device(atkbd->dev);
}
return count;
}
@@ -1090,6 +1101,7 @@ static ssize_t atkbd_show_softrepeat(struct atkbd *atkbd, char *buf)
static ssize_t atkbd_set_softrepeat(struct atkbd *atkbd, const char *buf, size_t count)
{
+ struct input_dev *new_dev;
unsigned long value;
char *rest;
@@ -1101,15 +1113,16 @@ static ssize_t atkbd_set_softrepeat(struct atkbd *atkbd, const char *buf, size_t
return -EINVAL;
if (atkbd->softrepeat != value) {
- /* unregister device as it's properties will change */
- input_unregister_device(&atkbd->dev);
+ if (!(new_dev = input_allocate_device()))
+ return -ENOMEM;
+ input_unregister_device(atkbd->dev);
+ atkbd->dev = new_dev;
atkbd->softrepeat = value;
if (atkbd->softrepeat)
atkbd->softraw = 1;
atkbd_set_device_attrs(atkbd);
- input_register_device(&atkbd->dev);
+ input_register_device(atkbd->dev);
}
-
return count;
}
@@ -1121,6 +1134,7 @@ static ssize_t atkbd_show_softraw(struct atkbd *atkbd, char *buf)
static ssize_t atkbd_set_softraw(struct atkbd *atkbd, const char *buf, size_t count)
{
+ struct input_dev *new_dev;
unsigned long value;
char *rest;
@@ -1129,11 +1143,13 @@ static ssize_t atkbd_set_softraw(struct atkbd *atkbd, const char *buf, size_t co
return -EINVAL;
if (atkbd->softraw != value) {
- /* unregister device as it's properties will change */
- input_unregister_device(&atkbd->dev);
+ if (!(new_dev = input_allocate_device()))
+ return -ENOMEM;
+ input_unregister_device(atkbd->dev);
+ atkbd->dev = new_dev;
atkbd->softraw = value;
atkbd_set_device_attrs(atkbd);
- input_register_device(&atkbd->dev);
+ input_register_device(atkbd->dev);
}
return count;
}
diff --git a/drivers/input/keyboard/corgikbd.c b/drivers/input/keyboard/corgikbd.c
index cd4b6e795013..d00d14bb637a 100644
--- a/drivers/input/keyboard/corgikbd.c
+++ b/drivers/input/keyboard/corgikbd.c
@@ -12,7 +12,7 @@
*/
#include <linux/delay.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <linux/init.h>
#include <linux/input.h>
#include <linux/interrupt.h>
@@ -70,8 +70,7 @@ static unsigned char corgikbd_keycode[NR_SCANCODES] = {
struct corgikbd {
unsigned char keycode[ARRAY_SIZE(corgikbd_keycode)];
- struct input_dev input;
- char phys[32];
+ struct input_dev *input;
spinlock_t lock;
struct timer_list timer;
@@ -147,7 +146,7 @@ static void corgikbd_scankeyboard(struct corgikbd *corgikbd_data, struct pt_regs
spin_lock_irqsave(&corgikbd_data->lock, flags);
if (regs)
- input_regs(&corgikbd_data->input, regs);
+ input_regs(corgikbd_data->input, regs);
num_pressed = 0;
for (col = 0; col < KB_COLS; col++) {
@@ -169,14 +168,14 @@ static void corgikbd_scankeyboard(struct corgikbd *corgikbd_data, struct pt_regs
scancode = SCANCODE(row, col);
pressed = rowd & KB_ROWMASK(row);
- input_report_key(&corgikbd_data->input, corgikbd_data->keycode[scancode], pressed);
+ input_report_key(corgikbd_data->input, corgikbd_data->keycode[scancode], pressed);
if (pressed)
num_pressed++;
if (pressed && (corgikbd_data->keycode[scancode] == CORGI_KEY_OFF)
&& time_after(jiffies, corgikbd_data->suspend_jiffies + HZ)) {
- input_event(&corgikbd_data->input, EV_PWR, CORGI_KEY_OFF, 1);
+ input_event(corgikbd_data->input, EV_PWR, CORGI_KEY_OFF, 1);
corgikbd_data->suspend_jiffies=jiffies;
}
}
@@ -185,7 +184,7 @@ static void corgikbd_scankeyboard(struct corgikbd *corgikbd_data, struct pt_regs
corgikbd_activate_all();
- input_sync(&corgikbd_data->input);
+ input_sync(corgikbd_data->input);
/* if any keys are pressed, enable the timer */
if (num_pressed)
@@ -249,9 +248,9 @@ static void corgikbd_hinge_timer(unsigned long data)
if (hinge_count >= HINGE_STABLE_COUNT) {
spin_lock_irqsave(&corgikbd_data->lock, flags);
- input_report_switch(&corgikbd_data->input, SW_0, ((sharpsl_hinge_state & CORGI_SCP_SWA) != 0));
- input_report_switch(&corgikbd_data->input, SW_1, ((sharpsl_hinge_state & CORGI_SCP_SWB) != 0));
- input_sync(&corgikbd_data->input);
+ input_report_switch(corgikbd_data->input, SW_0, ((sharpsl_hinge_state & CORGI_SCP_SWA) != 0));
+ input_report_switch(corgikbd_data->input, SW_1, ((sharpsl_hinge_state & CORGI_SCP_SWB) != 0));
+ input_sync(corgikbd_data->input);
spin_unlock_irqrestore(&corgikbd_data->lock, flags);
}
@@ -260,24 +259,22 @@ static void corgikbd_hinge_timer(unsigned long data)
}
#ifdef CONFIG_PM
-static int corgikbd_suspend(struct device *dev, pm_message_t state, uint32_t level)
+static int corgikbd_suspend(struct device *dev, pm_message_t state)
{
- if (level == SUSPEND_POWER_DOWN) {
- struct corgikbd *corgikbd = dev_get_drvdata(dev);
- corgikbd->suspended = 1;
- }
+ struct corgikbd *corgikbd = dev_get_drvdata(dev);
+ corgikbd->suspended = 1;
+
return 0;
}
-static int corgikbd_resume(struct device *dev, uint32_t level)
+static int corgikbd_resume(struct device *dev)
{
- if (level == RESUME_POWER_ON) {
- struct corgikbd *corgikbd = dev_get_drvdata(dev);
+ struct corgikbd *corgikbd = dev_get_drvdata(dev);
+
+ /* Upon resume, ignore the suspend key for a short while */
+ corgikbd->suspend_jiffies=jiffies;
+ corgikbd->suspended = 0;
- /* Upon resume, ignore the suspend key for a short while */
- corgikbd->suspend_jiffies=jiffies;
- corgikbd->suspended = 0;
- }
return 0;
}
#else
@@ -287,16 +284,21 @@ static int corgikbd_resume(struct device *dev, uint32_t level)
static int __init corgikbd_probe(struct device *dev)
{
- int i;
struct corgikbd *corgikbd;
+ struct input_dev *input_dev;
+ int i;
corgikbd = kzalloc(sizeof(struct corgikbd), GFP_KERNEL);
- if (!corgikbd)
+ input_dev = input_allocate_device();
+ if (!corgikbd || !input_dev) {
+ kfree(corgikbd);
+ input_free_device(input_dev);
return -ENOMEM;
+ }
- dev_set_drvdata(dev,corgikbd);
- strcpy(corgikbd->phys, "corgikbd/input0");
+ dev_set_drvdata(dev, corgikbd);
+ corgikbd->input = input_dev;
spin_lock_init(&corgikbd->lock);
/* Init Keyboard rescan timer */
@@ -311,28 +313,30 @@ static int __init corgikbd_probe(struct device *dev)
corgikbd->suspend_jiffies=jiffies;
- init_input_dev(&corgikbd->input);
- corgikbd->input.private = corgikbd;
- corgikbd->input.name = "Corgi Keyboard";
- corgikbd->input.dev = dev;
- corgikbd->input.phys = corgikbd->phys;
- corgikbd->input.id.bustype = BUS_HOST;
- corgikbd->input.id.vendor = 0x0001;
- corgikbd->input.id.product = 0x0001;
- corgikbd->input.id.version = 0x0100;
- corgikbd->input.evbit[0] = BIT(EV_KEY) | BIT(EV_REP) | BIT(EV_PWR) | BIT(EV_SW);
- corgikbd->input.keycode = corgikbd->keycode;
- corgikbd->input.keycodesize = sizeof(unsigned char);
- corgikbd->input.keycodemax = ARRAY_SIZE(corgikbd_keycode);
-
memcpy(corgikbd->keycode, corgikbd_keycode, sizeof(corgikbd->keycode));
+
+ input_dev->name = "Corgi Keyboard";
+ input_dev->phys = "corgikbd/input0";
+ input_dev->id.bustype = BUS_HOST;
+ input_dev->id.vendor = 0x0001;
+ input_dev->id.product = 0x0001;
+ input_dev->id.version = 0x0100;
+ input_dev->cdev.dev = dev;
+ input_dev->private = corgikbd;
+
+ input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP) | BIT(EV_PWR) | BIT(EV_SW);
+ input_dev->keycode = corgikbd->keycode;
+ input_dev->keycodesize = sizeof(unsigned char);
+ input_dev->keycodemax = ARRAY_SIZE(corgikbd_keycode);
+
for (i = 0; i < ARRAY_SIZE(corgikbd_keycode); i++)
- set_bit(corgikbd->keycode[i], corgikbd->input.keybit);
- clear_bit(0, corgikbd->input.keybit);
- set_bit(SW_0, corgikbd->input.swbit);
- set_bit(SW_1, corgikbd->input.swbit);
+ set_bit(corgikbd->keycode[i], input_dev->keybit);
+ clear_bit(0, input_dev->keybit);
+ set_bit(SW_0, input_dev->swbit);
+ set_bit(SW_1, input_dev->swbit);
+
+ input_register_device(corgikbd->input);
- input_register_device(&corgikbd->input);
mod_timer(&corgikbd->htimer, jiffies + HINGE_SCAN_INTERVAL);
/* Setup sense interrupts - RisingEdge Detect, sense lines as inputs */
@@ -349,8 +353,6 @@ static int __init corgikbd_probe(struct device *dev)
for (i = 0; i < CORGI_KEY_STROBE_NUM; i++)
pxa_gpio_mode(CORGI_GPIO_KEY_STROBE(i) | GPIO_OUT | GPIO_DFLT_HIGH);
- printk(KERN_INFO "input: Corgi Keyboard Registered\n");
-
return 0;
}
@@ -365,7 +367,7 @@ static int corgikbd_remove(struct device *dev)
del_timer_sync(&corgikbd->htimer);
del_timer_sync(&corgikbd->timer);
- input_unregister_device(&corgikbd->input);
+ input_unregister_device(corgikbd->input);
kfree(corgikbd);
diff --git a/drivers/input/keyboard/hil_kbd.c b/drivers/input/keyboard/hil_kbd.c
index ef78bffed5e7..0a90962c38e7 100644
--- a/drivers/input/keyboard/hil_kbd.c
+++ b/drivers/input/keyboard/hil_kbd.c
@@ -204,7 +204,7 @@ static irqreturn_t hil_kbd_interrupt(struct serio *serio,
hil_packet packet;
int idx;
- kbd = (struct hil_kbd *)serio->private;
+ kbd = serio_get_drvdata(serio);
if (kbd == NULL) {
BUG();
return IRQ_HANDLED;
@@ -234,7 +234,7 @@ static void hil_kbd_disconnect(struct serio *serio)
{
struct hil_kbd *kbd;
- kbd = (struct hil_kbd *)serio->private;
+ kbd = serio_get_drvdata(serio);
if (kbd == NULL) {
BUG();
return;
@@ -245,20 +245,20 @@ static void hil_kbd_disconnect(struct serio *serio)
kfree(kbd);
}
-static void hil_kbd_connect(struct serio *serio, struct serio_driver *drv)
+static int hil_kbd_connect(struct serio *serio, struct serio_driver *drv)
{
struct hil_kbd *kbd;
uint8_t did, *idd;
int i;
- if (serio->type != (SERIO_HIL_MLC | SERIO_HIL)) return;
-
- if (!(kbd = kmalloc(sizeof(struct hil_kbd), GFP_KERNEL))) return;
+ kbd = kmalloc(sizeof(*kbd), GFP_KERNEL);
+ if (!kbd)
+ return -ENOMEM;
memset(kbd, 0, sizeof(struct hil_kbd));
if (serio_open(serio, drv)) goto bail0;
- serio->private = kbd;
+ serio_set_drvdata(serio, kbd);
kbd->serio = serio;
kbd->dev.private = kbd;
@@ -342,19 +342,31 @@ static void hil_kbd_connect(struct serio *serio, struct serio_driver *drv)
down(&(kbd->sem));
up(&(kbd->sem));
- return;
+ return 0;
bail1:
serio_close(serio);
bail0:
kfree(kbd);
+ serio_set_drvdata(serio, NULL);
+ return -EIO;
}
+static struct serio_device_id hil_kbd_ids[] = {
+ {
+ .type = SERIO_HIL_MLC,
+ .proto = SERIO_HIL,
+ .id = SERIO_ANY,
+ .extra = SERIO_ANY,
+ },
+ { 0 }
+};
struct serio_driver hil_kbd_serio_drv = {
.driver = {
.name = "hil_kbd",
},
.description = "HP HIL keyboard driver",
+ .id_table = hil_kbd_ids,
.connect = hil_kbd_connect,
.disconnect = hil_kbd_disconnect,
.interrupt = hil_kbd_interrupt
diff --git a/drivers/input/keyboard/hilkbd.c b/drivers/input/keyboard/hilkbd.c
index eecb77db0847..e95bc052e32a 100644
--- a/drivers/input/keyboard/hilkbd.c
+++ b/drivers/input/keyboard/hilkbd.c
@@ -22,7 +22,7 @@
#include <linux/errno.h>
#include <linux/input.h>
#include <linux/init.h>
-#include <linux/irq.h>
+#include <linux/interrupt.h>
#include <linux/hil.h>
#include <linux/spinlock.h>
@@ -278,11 +278,11 @@ static int __init
hil_init_chip(struct parisc_device *dev)
{
if (!dev->irq) {
- printk(KERN_WARNING "HIL: IRQ not found for HIL bus at 0x%08lx\n", dev->hpa);
+ printk(KERN_WARNING "HIL: IRQ not found for HIL bus at 0x%08lx\n", dev->hpa.start);
return -ENODEV;
}
- hil_base = dev->hpa;
+ hil_base = dev->hpa.start;
hil_irq = dev->irq;
hil_dev.dev_id = dev;
@@ -299,7 +299,7 @@ static struct parisc_device_id hil_tbl[] = {
MODULE_DEVICE_TABLE(parisc, hil_tbl);
static struct parisc_driver hil_driver = {
- .name = "HIL",
+ .name = "hil",
.id_table = hil_tbl,
.probe = hil_init_chip,
};
diff --git a/drivers/input/keyboard/lkkbd.c b/drivers/input/keyboard/lkkbd.c
index 098963c7cdd6..77c4d9669ad0 100644
--- a/drivers/input/keyboard/lkkbd.c
+++ b/drivers/input/keyboard/lkkbd.c
@@ -102,7 +102,7 @@ static int ctrlclick_volume = 100; /* % */
module_param (ctrlclick_volume, int, 0);
MODULE_PARM_DESC (ctrlclick_volume, "Ctrlclick volume (in %), default is 100%");
-static int lk201_compose_is_alt = 0;
+static int lk201_compose_is_alt;
module_param (lk201_compose_is_alt, int, 0);
MODULE_PARM_DESC (lk201_compose_is_alt, "If set non-zero, LK201' Compose key "
"will act as an Alt key");
@@ -273,11 +273,11 @@ static lk_keycode_t lkkbd_keycode[LK_NUM_KEYCODES] = {
[0xfb] = KEY_APOSTROPHE,
};
-#define CHECK_LED(LED, BITS) do { \
- if (test_bit (LED, lk->dev.led)) \
- leds_on |= BITS; \
- else \
- leds_off |= BITS; \
+#define CHECK_LED(LK, VAR_ON, VAR_OFF, LED, BITS) do { \
+ if (test_bit (LED, (LK)->dev->led)) \
+ VAR_ON |= BITS; \
+ else \
+ VAR_OFF |= BITS; \
} while (0)
/*
@@ -287,7 +287,7 @@ struct lkkbd {
lk_keycode_t keycode[LK_NUM_KEYCODES];
int ignore_bytes;
unsigned char id[LK_NUM_IGNORE_BYTES];
- struct input_dev dev;
+ struct input_dev *dev;
struct serio *serio;
struct work_struct tq;
char name[64];
@@ -298,6 +298,42 @@ struct lkkbd {
int ctrlclick_volume;
};
+#ifdef LKKBD_DEBUG
+/*
+ * Responses from the keyboard and mapping back to their names.
+ */
+static struct {
+ unsigned char value;
+ unsigned char *name;
+} lk_response[] = {
+#define RESPONSE(x) { .value = (x), .name = #x, }
+ RESPONSE (LK_STUCK_KEY),
+ RESPONSE (LK_SELFTEST_FAILED),
+ RESPONSE (LK_ALL_KEYS_UP),
+ RESPONSE (LK_METRONOME),
+ RESPONSE (LK_OUTPUT_ERROR),
+ RESPONSE (LK_INPUT_ERROR),
+ RESPONSE (LK_KBD_LOCKED),
+ RESPONSE (LK_KBD_TEST_MODE_ACK),
+ RESPONSE (LK_PREFIX_KEY_DOWN),
+ RESPONSE (LK_MODE_CHANGE_ACK),
+ RESPONSE (LK_RESPONSE_RESERVED),
+#undef RESPONSE
+};
+
+static unsigned char *
+response_name (unsigned char value)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE (lk_response); i++)
+ if (lk_response[i].value == value)
+ return lk_response[i].name;
+
+ return "<unknown>";
+}
+#endif /* LKKBD_DEBUG */
+
/*
* Calculate volume parameter byte for a given volume.
*/
@@ -423,8 +459,7 @@ lkkbd_interrupt (struct serio *serio, unsigned char data, unsigned int flags,
DBG (KERN_INFO "Got byte 0x%02x\n", data);
if (lk->ignore_bytes > 0) {
- DBG (KERN_INFO "Ignoring a byte on %s\n",
- lk->name);
+ DBG (KERN_INFO "Ignoring a byte on %s\n", lk->name);
lk->id[LK_NUM_IGNORE_BYTES - lk->ignore_bytes--] = data;
if (lk->ignore_bytes == 0)
@@ -435,59 +470,40 @@ lkkbd_interrupt (struct serio *serio, unsigned char data, unsigned int flags,
switch (data) {
case LK_ALL_KEYS_UP:
- input_regs (&lk->dev, regs);
+ input_regs (lk->dev, regs);
for (i = 0; i < ARRAY_SIZE (lkkbd_keycode); i++)
if (lk->keycode[i] != KEY_RESERVED)
- input_report_key (&lk->dev, lk->keycode[i], 0);
- input_sync (&lk->dev);
+ input_report_key (lk->dev, lk->keycode[i], 0);
+ input_sync (lk->dev);
break;
- case LK_METRONOME:
- DBG (KERN_INFO "Got LK_METRONOME and don't "
- "know how to handle...\n");
+
+ case 0x01:
+ DBG (KERN_INFO "Got 0x01, scheduling re-initialization\n");
+ lk->ignore_bytes = LK_NUM_IGNORE_BYTES;
+ lk->id[LK_NUM_IGNORE_BYTES - lk->ignore_bytes--] = data;
+ schedule_work (&lk->tq);
break;
+
+ case LK_METRONOME:
case LK_OUTPUT_ERROR:
- DBG (KERN_INFO "Got LK_OUTPUT_ERROR and don't "
- "know how to handle...\n");
- break;
case LK_INPUT_ERROR:
- DBG (KERN_INFO "Got LK_INPUT_ERROR and don't "
- "know how to handle...\n");
- break;
case LK_KBD_LOCKED:
- DBG (KERN_INFO "Got LK_KBD_LOCKED and don't "
- "know how to handle...\n");
- break;
case LK_KBD_TEST_MODE_ACK:
- DBG (KERN_INFO "Got LK_KBD_TEST_MODE_ACK and don't "
- "know how to handle...\n");
- break;
case LK_PREFIX_KEY_DOWN:
- DBG (KERN_INFO "Got LK_PREFIX_KEY_DOWN and don't "
- "know how to handle...\n");
- break;
case LK_MODE_CHANGE_ACK:
- DBG (KERN_INFO "Got LK_MODE_CHANGE_ACK and ignored "
- "it properly...\n");
- break;
case LK_RESPONSE_RESERVED:
- DBG (KERN_INFO "Got LK_RESPONSE_RESERVED and don't "
- "know how to handle...\n");
- break;
- case 0x01:
- DBG (KERN_INFO "Got 0x01, scheduling re-initialization\n");
- lk->ignore_bytes = LK_NUM_IGNORE_BYTES;
- lk->id[LK_NUM_IGNORE_BYTES - lk->ignore_bytes--] = data;
- schedule_work (&lk->tq);
+ DBG (KERN_INFO "Got %s and don't know how to handle...\n",
+ response_name (data));
break;
default:
if (lk->keycode[data] != KEY_RESERVED) {
- input_regs (&lk->dev, regs);
- if (!test_bit (lk->keycode[data], lk->dev.key))
- input_report_key (&lk->dev, lk->keycode[data], 1);
+ input_regs (lk->dev, regs);
+ if (!test_bit (lk->keycode[data], lk->dev->key))
+ input_report_key (lk->dev, lk->keycode[data], 1);
else
- input_report_key (&lk->dev, lk->keycode[data], 0);
- input_sync (&lk->dev);
+ input_report_key (lk->dev, lk->keycode[data], 0);
+ input_sync (lk->dev);
} else
printk (KERN_WARNING "%s: Unknown key with "
"scancode 0x%02x on %s.\n",
@@ -510,10 +526,10 @@ lkkbd_event (struct input_dev *dev, unsigned int type, unsigned int code,
switch (type) {
case EV_LED:
- CHECK_LED (LED_CAPSL, LK_LED_SHIFTLOCK);
- CHECK_LED (LED_COMPOSE, LK_LED_COMPOSE);
- CHECK_LED (LED_SCROLLL, LK_LED_SCROLLLOCK);
- CHECK_LED (LED_SLEEP, LK_LED_WAIT);
+ CHECK_LED (lk, leds_on, leds_off, LED_CAPSL, LK_LED_SHIFTLOCK);
+ CHECK_LED (lk, leds_on, leds_off, LED_COMPOSE, LK_LED_COMPOSE);
+ CHECK_LED (lk, leds_on, leds_off, LED_SCROLLL, LK_LED_SCROLLLOCK);
+ CHECK_LED (lk, leds_on, leds_off, LED_SLEEP, LK_LED_WAIT);
if (leds_on != 0) {
lk->serio->write (lk->serio, LK_CMD_LED_ON);
lk->serio->write (lk->serio, leds_on);
@@ -575,10 +591,10 @@ lkkbd_reinit (void *data)
lk->serio->write (lk->serio, LK_CMD_SET_DEFAULTS);
/* Set LEDs */
- CHECK_LED (LED_CAPSL, LK_LED_SHIFTLOCK);
- CHECK_LED (LED_COMPOSE, LK_LED_COMPOSE);
- CHECK_LED (LED_SCROLLL, LK_LED_SCROLLLOCK);
- CHECK_LED (LED_SLEEP, LK_LED_WAIT);
+ CHECK_LED (lk, leds_on, leds_off, LED_CAPSL, LK_LED_SHIFTLOCK);
+ CHECK_LED (lk, leds_on, leds_off, LED_COMPOSE, LK_LED_COMPOSE);
+ CHECK_LED (lk, leds_on, leds_off, LED_SCROLLL, LK_LED_SCROLLLOCK);
+ CHECK_LED (lk, leds_on, leds_off, LED_SLEEP, LK_LED_WAIT);
if (leds_on != 0) {
lk->serio->write (lk->serio, LK_CMD_LED_ON);
lk->serio->write (lk->serio, leds_on);
@@ -605,7 +621,7 @@ lkkbd_reinit (void *data)
lk->serio->write (lk->serio, volume_to_hw (lk->bell_volume));
/* Enable/disable keyclick (and possibly set volume) */
- if (test_bit (SND_CLICK, lk->dev.snd)) {
+ if (test_bit (SND_CLICK, lk->dev->snd)) {
lk->serio->write (lk->serio, LK_CMD_ENABLE_KEYCLICK);
lk->serio->write (lk->serio, volume_to_hw (lk->keyclick_volume));
lk->serio->write (lk->serio, LK_CMD_ENABLE_CTRCLICK);
@@ -616,7 +632,7 @@ lkkbd_reinit (void *data)
}
/* Sound the bell if needed */
- if (test_bit (SND_BELL, lk->dev.snd))
+ if (test_bit (SND_BELL, lk->dev->snd))
lk->serio->write (lk->serio, LK_CMD_SOUND_BELL);
}
@@ -627,71 +643,70 @@ static int
lkkbd_connect (struct serio *serio, struct serio_driver *drv)
{
struct lkkbd *lk;
+ struct input_dev *input_dev;
int i;
int err;
- if (!(lk = kmalloc (sizeof (struct lkkbd), GFP_KERNEL)))
- return -ENOMEM;
-
- memset (lk, 0, sizeof (struct lkkbd));
-
- init_input_dev (&lk->dev);
- set_bit (EV_KEY, lk->dev.evbit);
- set_bit (EV_LED, lk->dev.evbit);
- set_bit (EV_SND, lk->dev.evbit);
- set_bit (EV_REP, lk->dev.evbit);
- set_bit (LED_CAPSL, lk->dev.ledbit);
- set_bit (LED_SLEEP, lk->dev.ledbit);
- set_bit (LED_COMPOSE, lk->dev.ledbit);
- set_bit (LED_SCROLLL, lk->dev.ledbit);
- set_bit (SND_BELL, lk->dev.sndbit);
- set_bit (SND_CLICK, lk->dev.sndbit);
+ lk = kzalloc (sizeof (struct lkkbd), GFP_KERNEL);
+ input_dev = input_allocate_device ();
+ if (!lk || !input_dev) {
+ err = -ENOMEM;
+ goto fail;
+ }
lk->serio = serio;
-
+ lk->dev = input_dev;
INIT_WORK (&lk->tq, lkkbd_reinit, lk);
-
lk->bell_volume = bell_volume;
lk->keyclick_volume = keyclick_volume;
lk->ctrlclick_volume = ctrlclick_volume;
+ memcpy (lk->keycode, lkkbd_keycode, sizeof (lk_keycode_t) * LK_NUM_KEYCODES);
- lk->dev.keycode = lk->keycode;
- lk->dev.keycodesize = sizeof (lk_keycode_t);
- lk->dev.keycodemax = LK_NUM_KEYCODES;
-
- lk->dev.event = lkkbd_event;
- lk->dev.private = lk;
+ strlcpy (lk->name, "DEC LK keyboard", sizeof(lk->name));
+ snprintf (lk->phys, sizeof(lk->phys), "%s/input0", serio->phys);
+
+ input_dev->name = lk->name;
+ input_dev->phys = lk->phys;
+ input_dev->id.bustype = BUS_RS232;
+ input_dev->id.vendor = SERIO_LKKBD;
+ input_dev->id.product = 0;
+ input_dev->id.version = 0x0100;
+ input_dev->cdev.dev = &serio->dev;
+ input_dev->event = lkkbd_event;
+ input_dev->private = lk;
+
+ set_bit (EV_KEY, input_dev->evbit);
+ set_bit (EV_LED, input_dev->evbit);
+ set_bit (EV_SND, input_dev->evbit);
+ set_bit (EV_REP, input_dev->evbit);
+ set_bit (LED_CAPSL, input_dev->ledbit);
+ set_bit (LED_SLEEP, input_dev->ledbit);
+ set_bit (LED_COMPOSE, input_dev->ledbit);
+ set_bit (LED_SCROLLL, input_dev->ledbit);
+ set_bit (SND_BELL, input_dev->sndbit);
+ set_bit (SND_CLICK, input_dev->sndbit);
+
+ input_dev->keycode = lk->keycode;
+ input_dev->keycodesize = sizeof (lk_keycode_t);
+ input_dev->keycodemax = LK_NUM_KEYCODES;
+ for (i = 0; i < LK_NUM_KEYCODES; i++)
+ set_bit (lk->keycode[i], input_dev->keybit);
serio_set_drvdata (serio, lk);
err = serio_open (serio, drv);
- if (err) {
- serio_set_drvdata (serio, NULL);
- kfree (lk);
- return err;
- }
-
- sprintf (lk->name, "DEC LK keyboard");
- sprintf (lk->phys, "%s/input0", serio->phys);
-
- memcpy (lk->keycode, lkkbd_keycode, sizeof (lk_keycode_t) * LK_NUM_KEYCODES);
- for (i = 0; i < LK_NUM_KEYCODES; i++)
- set_bit (lk->keycode[i], lk->dev.keybit);
-
- lk->dev.name = lk->name;
- lk->dev.phys = lk->phys;
- lk->dev.id.bustype = BUS_RS232;
- lk->dev.id.vendor = SERIO_LKKBD;
- lk->dev.id.product = 0;
- lk->dev.id.version = 0x0100;
- lk->dev.dev = &serio->dev;
+ if (err)
+ goto fail;
- input_register_device (&lk->dev);
-
- printk (KERN_INFO "input: %s on %s, initiating reset\n", lk->name, serio->phys);
+ input_register_device (lk->dev);
lk->serio->write (lk->serio, LK_CMD_POWERCYCLE_RESET);
return 0;
+
+ fail: serio_set_drvdata (serio, NULL);
+ input_free_device (input_dev);
+ kfree (lk);
+ return err;
}
/*
@@ -702,9 +717,11 @@ lkkbd_disconnect (struct serio *serio)
{
struct lkkbd *lk = serio_get_drvdata (serio);
- input_unregister_device (&lk->dev);
+ input_get_device (lk->dev);
+ input_unregister_device (lk->dev);
serio_close (serio);
serio_set_drvdata (serio, NULL);
+ input_put_device (lk->dev);
kfree (lk);
}
diff --git a/drivers/input/keyboard/locomokbd.c b/drivers/input/keyboard/locomokbd.c
index 8935290256b3..2c510881874a 100644
--- a/drivers/input/keyboard/locomokbd.c
+++ b/drivers/input/keyboard/locomokbd.c
@@ -76,7 +76,7 @@ static unsigned char locomokbd_keycode[LOCOMOKBD_NUMKEYS] = {
struct locomokbd {
unsigned char keycode[LOCOMOKBD_NUMKEYS];
- struct input_dev input;
+ struct input_dev *input;
char phys[32];
struct locomo_dev *ldev;
@@ -136,8 +136,7 @@ static void locomokbd_scankeyboard(struct locomokbd *locomokbd, struct pt_regs *
spin_lock_irqsave(&locomokbd->lock, flags);
- if (regs)
- input_regs(&locomokbd->input, regs);
+ input_regs(locomokbd->input, regs);
locomokbd_charge_all(membase);
@@ -152,16 +151,16 @@ static void locomokbd_scankeyboard(struct locomokbd *locomokbd, struct pt_regs *
scancode = SCANCODE(col, row);
if (rowd & KB_ROWMASK(row)) {
num_pressed += 1;
- input_report_key(&locomokbd->input, locomokbd->keycode[scancode], 1);
+ input_report_key(locomokbd->input, locomokbd->keycode[scancode], 1);
} else {
- input_report_key(&locomokbd->input, locomokbd->keycode[scancode], 0);
+ input_report_key(locomokbd->input, locomokbd->keycode[scancode], 0);
}
}
locomokbd_reset_col(membase, col);
}
locomokbd_activate_all(membase);
- input_sync(&locomokbd->input);
+ input_sync(locomokbd->input);
/* if any keys are pressed, enable the timer */
if (num_pressed)
@@ -196,13 +195,15 @@ static void locomokbd_timer_callback(unsigned long data)
static int locomokbd_probe(struct locomo_dev *dev)
{
struct locomokbd *locomokbd;
+ struct input_dev *input_dev;
int i, ret;
- locomokbd = kmalloc(sizeof(struct locomokbd), GFP_KERNEL);
- if (!locomokbd)
- return -ENOMEM;
-
- memset(locomokbd, 0, sizeof(struct locomokbd));
+ locomokbd = kzalloc(sizeof(struct locomokbd), GFP_KERNEL);
+ input_dev = input_allocate_device();
+ if (!locomokbd || !input_dev) {
+ ret = -ENOMEM;
+ goto free;
+ }
/* try and claim memory region */
if (!request_mem_region((unsigned long) dev->mapbase,
@@ -224,27 +225,26 @@ static int locomokbd_probe(struct locomo_dev *dev)
locomokbd->timer.function = locomokbd_timer_callback;
locomokbd->timer.data = (unsigned long) locomokbd;
- locomokbd->input.evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
+ locomokbd->input = input_dev;
+ strcpy(locomokbd->phys, "locomokbd/input0");
+
+ input_dev->name = "LoCoMo keyboard";
+ input_dev->phys = locomokbd->phys;
+ input_dev->id.bustype = BUS_HOST;
+ input_dev->id.vendor = 0x0001;
+ input_dev->id.product = 0x0001;
+ input_dev->id.version = 0x0100;
+ input_dev->private = locomokbd;
- init_input_dev(&locomokbd->input);
- locomokbd->input.keycode = locomokbd->keycode;
- locomokbd->input.keycodesize = sizeof(unsigned char);
- locomokbd->input.keycodemax = ARRAY_SIZE(locomokbd_keycode);
- locomokbd->input.private = locomokbd;
+ input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
+ input_dev->keycode = locomokbd->keycode;
+ input_dev->keycodesize = sizeof(unsigned char);
+ input_dev->keycodemax = ARRAY_SIZE(locomokbd_keycode);
memcpy(locomokbd->keycode, locomokbd_keycode, sizeof(locomokbd->keycode));
for (i = 0; i < LOCOMOKBD_NUMKEYS; i++)
- set_bit(locomokbd->keycode[i], locomokbd->input.keybit);
- clear_bit(0, locomokbd->input.keybit);
-
- strcpy(locomokbd->phys, "locomokbd/input0");
-
- locomokbd->input.name = "LoCoMo keyboard";
- locomokbd->input.phys = locomokbd->phys;
- locomokbd->input.id.bustype = BUS_XTKBD;
- locomokbd->input.id.vendor = 0x0001;
- locomokbd->input.id.product = 0x0001;
- locomokbd->input.id.version = 0x0100;
+ set_bit(locomokbd->keycode[i], input_dev->keybit);
+ clear_bit(0, input_dev->keybit);
/* attempt to get the interrupt */
ret = request_irq(dev->irq[0], locomokbd_interrupt, 0, "locomokbd", locomokbd);
@@ -253,9 +253,7 @@ static int locomokbd_probe(struct locomo_dev *dev)
goto out;
}
- input_register_device(&locomokbd->input);
-
- printk(KERN_INFO "input: LoCoMo keyboard on locomokbd\n");
+ input_register_device(locomokbd->input);
return 0;
@@ -263,6 +261,7 @@ out:
release_mem_region((unsigned long) dev->mapbase, dev->length);
locomo_set_drvdata(dev, NULL);
free:
+ input_free_device(input_dev);
kfree(locomokbd);
return ret;
@@ -276,7 +275,7 @@ static int locomokbd_remove(struct locomo_dev *dev)
del_timer_sync(&locomokbd->timer);
- input_unregister_device(&locomokbd->input);
+ input_unregister_device(locomokbd->input);
locomo_set_drvdata(dev, NULL);
release_mem_region((unsigned long) dev->mapbase, dev->length);
diff --git a/drivers/input/keyboard/maple_keyb.c b/drivers/input/keyboard/maple_keyb.c
index eecbde294f1f..cc6aaf9e85be 100644
--- a/drivers/input/keyboard/maple_keyb.c
+++ b/drivers/input/keyboard/maple_keyb.c
@@ -37,7 +37,7 @@ static unsigned char dc_kbd_keycode[256] = {
struct dc_kbd {
- struct input_dev dev;
+ struct input_dev *dev;
unsigned char new[8];
unsigned char old[8];
};
@@ -46,30 +46,24 @@ struct dc_kbd {
static void dc_scan_kbd(struct dc_kbd *kbd)
{
int i;
- struct input_dev *dev = &kbd->dev;
+ struct input_dev *dev = kbd->dev;
- for(i=0; i<8; i++)
- input_report_key(dev,
- dc_kbd_keycode[i+224],
- (kbd->new[0]>>i)&1);
+ for (i = 0; i < 8; i++)
+ input_report_key(dev, dc_kbd_keycode[i + 224], (kbd->new[0] >> i) & 1);
- for(i=2; i<8; i++) {
+ for (i = 2; i < 8; i++) {
- if(kbd->old[i]>3&&memscan(kbd->new+2, kbd->old[i], 6)==NULL) {
- if(dc_kbd_keycode[kbd->old[i]])
- input_report_key(dev,
- dc_kbd_keycode[kbd->old[i]],
- 0);
+ if (kbd->old[i] > 3 && memscan(kbd->new + 2, kbd->old[i], 6) == NULL) {
+ if (dc_kbd_keycode[kbd->old[i]])
+ input_report_key(dev, dc_kbd_keycode[kbd->old[i]], 0);
else
printk("Unknown key (scancode %#x) released.",
kbd->old[i]);
}
- if(kbd->new[i]>3&&memscan(kbd->old+2, kbd->new[i], 6)!=NULL) {
+ if (kbd->new[i] > 3 && memscan(kbd->old + 2, kbd->new[i], 6) != NULL) {
if(dc_kbd_keycode[kbd->new[i]])
- input_report_key(dev,
- dc_kbd_keycode[kbd->new[i]],
- 1);
+ input_report_key(dev, dc_kbd_keycode[kbd->new[i]], 1);
else
printk("Unknown key (scancode %#x) pressed.",
kbd->new[i]);
@@ -89,43 +83,39 @@ static void dc_kbd_callback(struct mapleq *mq)
unsigned long *buf = mq->recvbuf;
if (buf[1] == mapledev->function) {
- memcpy(kbd->new, buf+2, 8);
+ memcpy(kbd->new, buf + 2, 8);
dc_scan_kbd(kbd);
}
}
static int dc_kbd_connect(struct maple_device *dev)
{
- int i;
- unsigned long data = be32_to_cpu(dev->devinfo.function_data[0]);
struct dc_kbd *kbd;
+ struct input_dev *input_dev;
+ unsigned long data = be32_to_cpu(dev->devinfo.function_data[0]);
+ int i;
- if (!(kbd = kmalloc(sizeof(struct dc_kbd), GFP_KERNEL)))
- return -1;
- memset(kbd, 0, sizeof(struct dc_kbd));
-
- dev->private_data = kbd;
-
- kbd->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
-
- init_input_dev(&kbd->dev);
-
- for (i=0; i<255; i++)
- set_bit(dc_kbd_keycode[i], kbd->dev.keybit);
-
- clear_bit(0, kbd->dev.keybit);
+ dev->private_data = kbd = kzalloc(sizeof(struct dc_kbd), GFP_KERNEL);
+ input_dev = input_allocate_device();
+ if (!kbd || !input_dev) {
+ kfree(kbd);
+ input_free_device(input_dev);
+ return -ENOMEM;
+ }
- kbd->dev.private = kbd;
+ kbd->dev = input_dev;
- kbd->dev.name = dev->product_name;
- kbd->dev.id.bustype = BUS_MAPLE;
+ input_dev->name = dev->product_name;
+ input_dev->id.bustype = BUS_MAPLE;
+ input_dev->private = kbd;
+ input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
+ for (i = 0; i < 255; i++)
+ set_bit(dc_kbd_keycode[i], input_dev->keybit);
+ clear_bit(0, input_dev->keybit);
- input_register_device(&kbd->dev);
+ input_register_device(kbd->dev);
maple_getcond_callback(dev, dc_kbd_callback, 1, MAPLE_FUNC_KEYBOARD);
-
- printk(KERN_INFO "input: keyboard(0x%lx): %s\n", data, kbd->dev.name);
-
return 0;
}
@@ -134,7 +124,7 @@ static void dc_kbd_disconnect(struct maple_device *dev)
{
struct dc_kbd *kbd = dev->private_data;
- input_unregister_device(&kbd->dev);
+ input_unregister_device(kbd->dev);
kfree(kbd);
}
diff --git a/drivers/input/keyboard/newtonkbd.c b/drivers/input/keyboard/newtonkbd.c
index 2e8ce1613eec..d10983c521e6 100644
--- a/drivers/input/keyboard/newtonkbd.c
+++ b/drivers/input/keyboard/newtonkbd.c
@@ -57,11 +57,9 @@ static unsigned char nkbd_keycode[128] = {
KEY_LEFT, KEY_RIGHT, KEY_DOWN, KEY_UP, 0
};
-static char *nkbd_name = "Newton Keyboard";
-
struct nkbd {
unsigned char keycode[128];
- struct input_dev dev;
+ struct input_dev *dev;
struct serio *serio;
char phys[32];
};
@@ -73,13 +71,13 @@ static irqreturn_t nkbd_interrupt(struct serio *serio,
/* invalid scan codes are probably the init sequence, so we ignore them */
if (nkbd->keycode[data & NKBD_KEY]) {
- input_regs(&nkbd->dev, regs);
- input_report_key(&nkbd->dev, nkbd->keycode[data & NKBD_KEY], data & NKBD_PRESS);
- input_sync(&nkbd->dev);
+ input_regs(nkbd->dev, regs);
+ input_report_key(nkbd->dev, nkbd->keycode[data & NKBD_KEY], data & NKBD_PRESS);
+ input_sync(nkbd->dev);
}
else if (data == 0xe7) /* end of init sequence */
- printk(KERN_INFO "input: %s on %s\n", nkbd_name, serio->phys);
+ printk(KERN_INFO "input: %s on %s\n", nkbd->dev->name, serio->phys);
return IRQ_HANDLED;
}
@@ -87,62 +85,59 @@ static irqreturn_t nkbd_interrupt(struct serio *serio,
static int nkbd_connect(struct serio *serio, struct serio_driver *drv)
{
struct nkbd *nkbd;
+ struct input_dev *input_dev;
+ int err = -ENOMEM;
int i;
- int err;
-
- if (!(nkbd = kmalloc(sizeof(struct nkbd), GFP_KERNEL)))
- return -ENOMEM;
-
- memset(nkbd, 0, sizeof(struct nkbd));
- nkbd->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
+ nkbd = kzalloc(sizeof(struct nkbd), GFP_KERNEL);
+ input_dev = input_allocate_device();
+ if (!nkbd || !input_dev)
+ goto fail;
nkbd->serio = serio;
+ nkbd->dev = input_dev;
+ sprintf(nkbd->phys, "%s/input0", serio->phys);
+ memcpy(nkbd->keycode, nkbd_keycode, sizeof(nkbd->keycode));
- init_input_dev(&nkbd->dev);
- nkbd->dev.keycode = nkbd->keycode;
- nkbd->dev.keycodesize = sizeof(unsigned char);
- nkbd->dev.keycodemax = ARRAY_SIZE(nkbd_keycode);
- nkbd->dev.private = nkbd;
+ input_dev->name = "Newton Keyboard";
+ input_dev->phys = nkbd->phys;
+ input_dev->id.bustype = BUS_RS232;
+ input_dev->id.vendor = SERIO_NEWTON;
+ input_dev->id.product = 0x0001;
+ input_dev->id.version = 0x0100;
+ input_dev->cdev.dev = &serio->dev;
+ input_dev->private = nkbd;
+
+ input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
+ input_dev->keycode = nkbd->keycode;
+ input_dev->keycodesize = sizeof(unsigned char);
+ input_dev->keycodemax = ARRAY_SIZE(nkbd_keycode);
+ for (i = 0; i < 128; i++)
+ set_bit(nkbd->keycode[i], input_dev->keybit);
+ clear_bit(0, input_dev->keybit);
serio_set_drvdata(serio, nkbd);
err = serio_open(serio, drv);
- if (err) {
- serio_set_drvdata(serio, NULL);
- kfree(nkbd);
- return err;
- }
-
- memcpy(nkbd->keycode, nkbd_keycode, sizeof(nkbd->keycode));
- for (i = 0; i < 128; i++)
- set_bit(nkbd->keycode[i], nkbd->dev.keybit);
- clear_bit(0, nkbd->dev.keybit);
-
- sprintf(nkbd->phys, "%s/input0", serio->phys);
-
- nkbd->dev.name = nkbd_name;
- nkbd->dev.phys = nkbd->phys;
- nkbd->dev.id.bustype = BUS_RS232;
- nkbd->dev.id.vendor = SERIO_NEWTON;
- nkbd->dev.id.product = 0x0001;
- nkbd->dev.id.version = 0x0100;
- nkbd->dev.dev = &serio->dev;
-
- input_register_device(&nkbd->dev);
-
- printk(KERN_INFO "input: %s on %s\n", nkbd_name, serio->phys);
+ if (err)
+ goto fail;
+ input_register_device(nkbd->dev);
return 0;
+
+ fail: serio_set_drvdata(serio, NULL);
+ input_free_device(input_dev);
+ kfree(nkbd);
+ return err;
}
static void nkbd_disconnect(struct serio *serio)
{
struct nkbd *nkbd = serio_get_drvdata(serio);
- input_unregister_device(&nkbd->dev);
serio_close(serio);
serio_set_drvdata(serio, NULL);
+ input_unregister_device(nkbd->dev);
kfree(nkbd);
}
diff --git a/drivers/input/keyboard/spitzkbd.c b/drivers/input/keyboard/spitzkbd.c
index 344f46005401..0fa38a559cdf 100644
--- a/drivers/input/keyboard/spitzkbd.c
+++ b/drivers/input/keyboard/spitzkbd.c
@@ -12,7 +12,7 @@
*/
#include <linux/delay.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <linux/init.h>
#include <linux/input.h>
#include <linux/interrupt.h>
@@ -85,7 +85,7 @@ static int spitz_senses[] = {
struct spitzkbd {
unsigned char keycode[ARRAY_SIZE(spitzkbd_keycode)];
- struct input_dev input;
+ struct input_dev *input;
char phys[32];
spinlock_t lock;
@@ -187,8 +187,7 @@ static void spitzkbd_scankeyboard(struct spitzkbd *spitzkbd_data, struct pt_regs
spin_lock_irqsave(&spitzkbd_data->lock, flags);
- if (regs)
- input_regs(&spitzkbd_data->input, regs);
+ input_regs(spitzkbd_data->input, regs);
num_pressed = 0;
for (col = 0; col < KB_COLS; col++) {
@@ -210,7 +209,7 @@ static void spitzkbd_scankeyboard(struct spitzkbd *spitzkbd_data, struct pt_regs
scancode = SCANCODE(row, col);
pressed = rowd & KB_ROWMASK(row);
- input_report_key(&spitzkbd_data->input, spitzkbd_data->keycode[scancode], pressed);
+ input_report_key(spitzkbd_data->input, spitzkbd_data->keycode[scancode], pressed);
if (pressed)
num_pressed++;
@@ -220,15 +219,15 @@ static void spitzkbd_scankeyboard(struct spitzkbd *spitzkbd_data, struct pt_regs
spitzkbd_activate_all();
- input_report_key(&spitzkbd_data->input, SPITZ_KEY_SYNC, (GPLR(SPITZ_GPIO_SYNC) & GPIO_bit(SPITZ_GPIO_SYNC)) != 0 );
- input_report_key(&spitzkbd_data->input, KEY_SUSPEND, pwrkey);
+ input_report_key(spitzkbd_data->input, SPITZ_KEY_SYNC, (GPLR(SPITZ_GPIO_SYNC) & GPIO_bit(SPITZ_GPIO_SYNC)) != 0 );
+ input_report_key(spitzkbd_data->input, KEY_SUSPEND, pwrkey);
if (pwrkey && time_after(jiffies, spitzkbd_data->suspend_jiffies + msecs_to_jiffies(1000))) {
- input_event(&spitzkbd_data->input, EV_PWR, KEY_SUSPEND, 1);
+ input_event(spitzkbd_data->input, EV_PWR, KEY_SUSPEND, 1);
spitzkbd_data->suspend_jiffies = jiffies;
}
- input_sync(&spitzkbd_data->input);
+ input_sync(spitzkbd_data->input);
/* if any keys are pressed, enable the timer */
if (num_pressed)
@@ -259,6 +258,7 @@ static irqreturn_t spitzkbd_interrupt(int irq, void *dev_id, struct pt_regs *reg
static void spitzkbd_timer_callback(unsigned long data)
{
struct spitzkbd *spitzkbd_data = (struct spitzkbd *) data;
+
spitzkbd_scankeyboard(spitzkbd_data, NULL);
}
@@ -298,9 +298,9 @@ static void spitzkbd_hinge_timer(unsigned long data)
if (hinge_count >= HINGE_STABLE_COUNT) {
spin_lock_irqsave(&spitzkbd_data->lock, flags);
- input_report_switch(&spitzkbd_data->input, SW_0, ((GPLR(SPITZ_GPIO_SWA) & GPIO_bit(SPITZ_GPIO_SWA)) != 0));
- input_report_switch(&spitzkbd_data->input, SW_1, ((GPLR(SPITZ_GPIO_SWB) & GPIO_bit(SPITZ_GPIO_SWB)) != 0));
- input_sync(&spitzkbd_data->input);
+ input_report_switch(spitzkbd_data->input, SW_0, ((GPLR(SPITZ_GPIO_SWA) & GPIO_bit(SPITZ_GPIO_SWA)) != 0));
+ input_report_switch(spitzkbd_data->input, SW_1, ((GPLR(SPITZ_GPIO_SWB) & GPIO_bit(SPITZ_GPIO_SWB)) != 0));
+ input_sync(spitzkbd_data->input);
spin_unlock_irqrestore(&spitzkbd_data->lock, flags);
} else {
@@ -309,34 +309,32 @@ static void spitzkbd_hinge_timer(unsigned long data)
}
#ifdef CONFIG_PM
-static int spitzkbd_suspend(struct device *dev, pm_message_t state, uint32_t level)
+static int spitzkbd_suspend(struct device *dev, pm_message_t state)
{
- if (level == SUSPEND_POWER_DOWN) {
- int i;
- struct spitzkbd *spitzkbd = dev_get_drvdata(dev);
- spitzkbd->suspended = 1;
-
- /* Set Strobe lines as inputs - *except* strobe line 0 leave this
- enabled so we can detect a power button press for resume */
- for (i = 1; i < SPITZ_KEY_STROBE_NUM; i++)
- pxa_gpio_mode(spitz_strobes[i] | GPIO_IN);
- }
+ int i;
+ struct spitzkbd *spitzkbd = dev_get_drvdata(dev);
+ spitzkbd->suspended = 1;
+
+ /* Set Strobe lines as inputs - *except* strobe line 0 leave this
+ enabled so we can detect a power button press for resume */
+ for (i = 1; i < SPITZ_KEY_STROBE_NUM; i++)
+ pxa_gpio_mode(spitz_strobes[i] | GPIO_IN);
+
return 0;
}
-static int spitzkbd_resume(struct device *dev, uint32_t level)
+static int spitzkbd_resume(struct device *dev)
{
- if (level == RESUME_POWER_ON) {
- int i;
- struct spitzkbd *spitzkbd = dev_get_drvdata(dev);
+ int i;
+ struct spitzkbd *spitzkbd = dev_get_drvdata(dev);
- for (i = 0; i < SPITZ_KEY_STROBE_NUM; i++)
- pxa_gpio_mode(spitz_strobes[i] | GPIO_OUT | GPIO_DFLT_HIGH);
+ for (i = 0; i < SPITZ_KEY_STROBE_NUM; i++)
+ pxa_gpio_mode(spitz_strobes[i] | GPIO_OUT | GPIO_DFLT_HIGH);
+
+ /* Upon resume, ignore the suspend key for a short while */
+ spitzkbd->suspend_jiffies = jiffies;
+ spitzkbd->suspended = 0;
- /* Upon resume, ignore the suspend key for a short while */
- spitzkbd->suspend_jiffies = jiffies;
- spitzkbd->suspended = 0;
- }
return 0;
}
#else
@@ -346,14 +344,21 @@ static int spitzkbd_resume(struct device *dev, uint32_t level)
static int __init spitzkbd_probe(struct device *dev)
{
- int i;
struct spitzkbd *spitzkbd;
+ struct input_dev *input_dev;
+ int i;
spitzkbd = kzalloc(sizeof(struct spitzkbd), GFP_KERNEL);
if (!spitzkbd)
return -ENOMEM;
- dev_set_drvdata(dev,spitzkbd);
+ input_dev = input_allocate_device();
+ if (!input_dev) {
+ kfree(spitzkbd);
+ return -ENOMEM;
+ }
+
+ dev_set_drvdata(dev, spitzkbd);
strcpy(spitzkbd->phys, "spitzkbd/input0");
spin_lock_init(&spitzkbd->lock);
@@ -368,30 +373,34 @@ static int __init spitzkbd_probe(struct device *dev)
spitzkbd->htimer.function = spitzkbd_hinge_timer;
spitzkbd->htimer.data = (unsigned long) spitzkbd;
- spitzkbd->suspend_jiffies=jiffies;
-
- init_input_dev(&spitzkbd->input);
- spitzkbd->input.private = spitzkbd;
- spitzkbd->input.name = "Spitz Keyboard";
- spitzkbd->input.dev = dev;
- spitzkbd->input.phys = spitzkbd->phys;
- spitzkbd->input.id.bustype = BUS_HOST;
- spitzkbd->input.id.vendor = 0x0001;
- spitzkbd->input.id.product = 0x0001;
- spitzkbd->input.id.version = 0x0100;
- spitzkbd->input.evbit[0] = BIT(EV_KEY) | BIT(EV_REP) | BIT(EV_PWR) | BIT(EV_SW);
- spitzkbd->input.keycode = spitzkbd->keycode;
- spitzkbd->input.keycodesize = sizeof(unsigned char);
- spitzkbd->input.keycodemax = ARRAY_SIZE(spitzkbd_keycode);
+ spitzkbd->suspend_jiffies = jiffies;
+
+ spitzkbd->input = input_dev;
+
+ input_dev->private = spitzkbd;
+ input_dev->name = "Spitz Keyboard";
+ input_dev->phys = spitzkbd->phys;
+ input_dev->cdev.dev = dev;
+
+ input_dev->id.bustype = BUS_HOST;
+ input_dev->id.vendor = 0x0001;
+ input_dev->id.product = 0x0001;
+ input_dev->id.version = 0x0100;
+
+ input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP) | BIT(EV_PWR) | BIT(EV_SW);
+ input_dev->keycode = spitzkbd->keycode;
+ input_dev->keycodesize = sizeof(unsigned char);
+ input_dev->keycodemax = ARRAY_SIZE(spitzkbd_keycode);
memcpy(spitzkbd->keycode, spitzkbd_keycode, sizeof(spitzkbd->keycode));
for (i = 0; i < ARRAY_SIZE(spitzkbd_keycode); i++)
- set_bit(spitzkbd->keycode[i], spitzkbd->input.keybit);
- clear_bit(0, spitzkbd->input.keybit);
- set_bit(SW_0, spitzkbd->input.swbit);
- set_bit(SW_1, spitzkbd->input.swbit);
+ set_bit(spitzkbd->keycode[i], input_dev->keybit);
+ clear_bit(0, input_dev->keybit);
+ set_bit(SW_0, input_dev->swbit);
+ set_bit(SW_1, input_dev->swbit);
+
+ input_register_device(input_dev);
- input_register_device(&spitzkbd->input);
mod_timer(&spitzkbd->htimer, jiffies + msecs_to_jiffies(HINGE_SCAN_INTERVAL));
/* Setup sense interrupts - RisingEdge Detect, sense lines as inputs */
@@ -444,7 +453,7 @@ static int spitzkbd_remove(struct device *dev)
del_timer_sync(&spitzkbd->htimer);
del_timer_sync(&spitzkbd->timer);
- input_unregister_device(&spitzkbd->input);
+ input_unregister_device(spitzkbd->input);
kfree(spitzkbd);
diff --git a/drivers/input/keyboard/sunkbd.c b/drivers/input/keyboard/sunkbd.c
index 4bae5d89348d..b15b6d8d4f83 100644
--- a/drivers/input/keyboard/sunkbd.c
+++ b/drivers/input/keyboard/sunkbd.c
@@ -76,13 +76,14 @@ static unsigned char sunkbd_keycode[128] = {
struct sunkbd {
unsigned char keycode[128];
- struct input_dev dev;
+ struct input_dev *dev;
struct serio *serio;
struct work_struct tq;
wait_queue_head_t wait;
char name[64];
char phys[32];
char type;
+ unsigned char enabled;
volatile s8 reset;
volatile s8 layout;
};
@@ -124,10 +125,13 @@ static irqreturn_t sunkbd_interrupt(struct serio *serio,
break;
default:
+ if (!sunkbd->enabled)
+ break;
+
if (sunkbd->keycode[data & SUNKBD_KEY]) {
- input_regs(&sunkbd->dev, regs);
- input_report_key(&sunkbd->dev, sunkbd->keycode[data & SUNKBD_KEY], !(data & SUNKBD_RELEASE));
- input_sync(&sunkbd->dev);
+ input_regs(sunkbd->dev, regs);
+ input_report_key(sunkbd->dev, sunkbd->keycode[data & SUNKBD_KEY], !(data & SUNKBD_RELEASE));
+ input_sync(sunkbd->dev);
} else {
printk(KERN_WARNING "sunkbd.c: Unknown key (scancode %#x) %s.\n",
data & SUNKBD_KEY, data & SUNKBD_RELEASE ? "released" : "pressed");
@@ -184,7 +188,7 @@ static int sunkbd_initialize(struct sunkbd *sunkbd)
sunkbd->reset = -2;
sunkbd->serio->write(sunkbd->serio, SUNKBD_CMD_RESET);
wait_event_interruptible_timeout(sunkbd->wait, sunkbd->reset >= 0, HZ);
- if (sunkbd->reset <0)
+ if (sunkbd->reset < 0)
return -1;
sunkbd->type = sunkbd->reset;
@@ -213,10 +217,17 @@ static void sunkbd_reinit(void *data)
sunkbd->serio->write(sunkbd->serio, SUNKBD_CMD_SETLED);
sunkbd->serio->write(sunkbd->serio,
- (!!test_bit(LED_CAPSL, sunkbd->dev.led) << 3) | (!!test_bit(LED_SCROLLL, sunkbd->dev.led) << 2) |
- (!!test_bit(LED_COMPOSE, sunkbd->dev.led) << 1) | !!test_bit(LED_NUML, sunkbd->dev.led));
- sunkbd->serio->write(sunkbd->serio, SUNKBD_CMD_NOCLICK - !!test_bit(SND_CLICK, sunkbd->dev.snd));
- sunkbd->serio->write(sunkbd->serio, SUNKBD_CMD_BELLOFF - !!test_bit(SND_BELL, sunkbd->dev.snd));
+ (!!test_bit(LED_CAPSL, sunkbd->dev->led) << 3) | (!!test_bit(LED_SCROLLL, sunkbd->dev->led) << 2) |
+ (!!test_bit(LED_COMPOSE, sunkbd->dev->led) << 1) | !!test_bit(LED_NUML, sunkbd->dev->led));
+ sunkbd->serio->write(sunkbd->serio, SUNKBD_CMD_NOCLICK - !!test_bit(SND_CLICK, sunkbd->dev->snd));
+ sunkbd->serio->write(sunkbd->serio, SUNKBD_CMD_BELLOFF - !!test_bit(SND_BELL, sunkbd->dev->snd));
+}
+
+static void sunkbd_enable(struct sunkbd *sunkbd, int enable)
+{
+ serio_pause_rx(sunkbd->serio);
+ sunkbd->enabled = 1;
+ serio_continue_rx(sunkbd->serio);
}
/*
@@ -226,70 +237,64 @@ static void sunkbd_reinit(void *data)
static int sunkbd_connect(struct serio *serio, struct serio_driver *drv)
{
struct sunkbd *sunkbd;
+ struct input_dev *input_dev;
+ int err = -ENOMEM;
int i;
- int err;
-
- if (!(sunkbd = kmalloc(sizeof(struct sunkbd), GFP_KERNEL)))
- return -ENOMEM;
- memset(sunkbd, 0, sizeof(struct sunkbd));
-
- init_input_dev(&sunkbd->dev);
- init_waitqueue_head(&sunkbd->wait);
-
- sunkbd->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_LED) | BIT(EV_SND) | BIT(EV_REP);
- sunkbd->dev.ledbit[0] = BIT(LED_CAPSL) | BIT(LED_COMPOSE) | BIT(LED_SCROLLL) | BIT(LED_NUML);
- sunkbd->dev.sndbit[0] = BIT(SND_CLICK) | BIT(SND_BELL);
+ sunkbd = kzalloc(sizeof(struct sunkbd), GFP_KERNEL);
+ input_dev = input_allocate_device();
+ if (!sunkbd || !input_dev)
+ goto fail;
sunkbd->serio = serio;
-
+ sunkbd->dev = input_dev;
+ init_waitqueue_head(&sunkbd->wait);
INIT_WORK(&sunkbd->tq, sunkbd_reinit, sunkbd);
-
- sunkbd->dev.keycode = sunkbd->keycode;
- sunkbd->dev.keycodesize = sizeof(unsigned char);
- sunkbd->dev.keycodemax = ARRAY_SIZE(sunkbd_keycode);
-
- sunkbd->dev.event = sunkbd_event;
- sunkbd->dev.private = sunkbd;
+ snprintf(sunkbd->phys, sizeof(sunkbd->phys), "%s/input0", serio->phys);
serio_set_drvdata(serio, sunkbd);
err = serio_open(serio, drv);
- if (err) {
- serio_set_drvdata(serio, NULL);
- kfree(sunkbd);
- return err;
- }
+ if (err)
+ goto fail;
if (sunkbd_initialize(sunkbd) < 0) {
serio_close(serio);
- serio_set_drvdata(serio, NULL);
- kfree(sunkbd);
- return -ENODEV;
+ goto fail;
}
sprintf(sunkbd->name, "Sun Type %d keyboard", sunkbd->type);
-
memcpy(sunkbd->keycode, sunkbd_keycode, sizeof(sunkbd->keycode));
- for (i = 0; i < 128; i++)
- set_bit(sunkbd->keycode[i], sunkbd->dev.keybit);
- clear_bit(0, sunkbd->dev.keybit);
-
- sprintf(sunkbd->phys, "%s/input0", serio->phys);
-
- sunkbd->dev.name = sunkbd->name;
- sunkbd->dev.phys = sunkbd->phys;
- sunkbd->dev.id.bustype = BUS_RS232;
- sunkbd->dev.id.vendor = SERIO_SUNKBD;
- sunkbd->dev.id.product = sunkbd->type;
- sunkbd->dev.id.version = 0x0100;
- sunkbd->dev.dev = &serio->dev;
- input_register_device(&sunkbd->dev);
-
- printk(KERN_INFO "input: %s on %s\n", sunkbd->name, serio->phys);
+ input_dev->name = sunkbd->name;
+ input_dev->phys = sunkbd->phys;
+ input_dev->id.bustype = BUS_RS232;
+ input_dev->id.vendor = SERIO_SUNKBD;
+ input_dev->id.product = sunkbd->type;
+ input_dev->id.version = 0x0100;
+ input_dev->cdev.dev = &serio->dev;
+ input_dev->private = sunkbd;
+ input_dev->event = sunkbd_event;
+
+ input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_LED) | BIT(EV_SND) | BIT(EV_REP);
+ input_dev->ledbit[0] = BIT(LED_CAPSL) | BIT(LED_COMPOSE) | BIT(LED_SCROLLL) | BIT(LED_NUML);
+ input_dev->sndbit[0] = BIT(SND_CLICK) | BIT(SND_BELL);
+
+ input_dev->keycode = sunkbd->keycode;
+ input_dev->keycodesize = sizeof(unsigned char);
+ input_dev->keycodemax = ARRAY_SIZE(sunkbd_keycode);
+ for (i = 0; i < 128; i++)
+ set_bit(sunkbd->keycode[i], input_dev->keybit);
+ clear_bit(0, input_dev->keybit);
+ sunkbd_enable(sunkbd, 1);
+ input_register_device(sunkbd->dev);
return 0;
+
+ fail: serio_set_drvdata(serio, NULL);
+ input_free_device(input_dev);
+ kfree(sunkbd);
+ return err;
}
/*
@@ -299,7 +304,9 @@ static int sunkbd_connect(struct serio *serio, struct serio_driver *drv)
static void sunkbd_disconnect(struct serio *serio)
{
struct sunkbd *sunkbd = serio_get_drvdata(serio);
- input_unregister_device(&sunkbd->dev);
+
+ sunkbd_enable(sunkbd, 0);
+ input_unregister_device(sunkbd->dev);
serio_close(serio);
serio_set_drvdata(serio, NULL);
kfree(sunkbd);
diff --git a/drivers/input/keyboard/xtkbd.c b/drivers/input/keyboard/xtkbd.c
index 19eaec7789d1..4135e3e16c51 100644
--- a/drivers/input/keyboard/xtkbd.c
+++ b/drivers/input/keyboard/xtkbd.c
@@ -56,11 +56,9 @@ static unsigned char xtkbd_keycode[256] = {
106
};
-static char *xtkbd_name = "XT Keyboard";
-
struct xtkbd {
unsigned char keycode[256];
- struct input_dev dev;
+ struct input_dev *dev;
struct serio *serio;
char phys[32];
};
@@ -77,9 +75,9 @@ static irqreturn_t xtkbd_interrupt(struct serio *serio,
default:
if (xtkbd->keycode[data & XTKBD_KEY]) {
- input_regs(&xtkbd->dev, regs);
- input_report_key(&xtkbd->dev, xtkbd->keycode[data & XTKBD_KEY], !(data & XTKBD_RELEASE));
- input_sync(&xtkbd->dev);
+ input_regs(xtkbd->dev, regs);
+ input_report_key(xtkbd->dev, xtkbd->keycode[data & XTKBD_KEY], !(data & XTKBD_RELEASE));
+ input_sync(xtkbd->dev);
} else {
printk(KERN_WARNING "xtkbd.c: Unknown key (scancode %#x) %s.\n",
data & XTKBD_KEY, data & XTKBD_RELEASE ? "released" : "pressed");
@@ -91,62 +89,60 @@ static irqreturn_t xtkbd_interrupt(struct serio *serio,
static int xtkbd_connect(struct serio *serio, struct serio_driver *drv)
{
struct xtkbd *xtkbd;
+ struct input_dev *input_dev;
+ int err = -ENOMEM;
int i;
- int err;
-
- if (!(xtkbd = kmalloc(sizeof(struct xtkbd), GFP_KERNEL)))
- return -ENOMEM;
-
- memset(xtkbd, 0, sizeof(struct xtkbd));
- xtkbd->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
+ xtkbd = kmalloc(sizeof(struct xtkbd), GFP_KERNEL);
+ input_dev = input_allocate_device();
+ if (!xtkbd || !input_dev)
+ goto fail;
xtkbd->serio = serio;
+ xtkbd->dev = input_dev;
+ sprintf(xtkbd->phys, "%s/input0", serio->phys);
+ memcpy(xtkbd->keycode, xtkbd_keycode, sizeof(xtkbd->keycode));
- init_input_dev(&xtkbd->dev);
- xtkbd->dev.keycode = xtkbd->keycode;
- xtkbd->dev.keycodesize = sizeof(unsigned char);
- xtkbd->dev.keycodemax = ARRAY_SIZE(xtkbd_keycode);
- xtkbd->dev.private = xtkbd;
-
- serio_set_drvdata(serio, xtkbd);
+ input_dev->name = "XT Keyboard";
+ input_dev->phys = xtkbd->phys;
+ input_dev->id.bustype = BUS_XTKBD;
+ input_dev->id.vendor = 0x0001;
+ input_dev->id.product = 0x0001;
+ input_dev->id.version = 0x0100;
+ input_dev->cdev.dev = &serio->dev;
+ input_dev->private = xtkbd;
- err = serio_open(serio, drv);
- if (err) {
- serio_set_drvdata(serio, NULL);
- kfree(xtkbd);
- return err;
- }
+ input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
+ input_dev->keycode = xtkbd->keycode;
+ input_dev->keycodesize = sizeof(unsigned char);
+ input_dev->keycodemax = ARRAY_SIZE(xtkbd_keycode);
- memcpy(xtkbd->keycode, xtkbd_keycode, sizeof(xtkbd->keycode));
for (i = 0; i < 255; i++)
- set_bit(xtkbd->keycode[i], xtkbd->dev.keybit);
- clear_bit(0, xtkbd->dev.keybit);
-
- sprintf(xtkbd->phys, "%s/input0", serio->phys);
-
- xtkbd->dev.name = xtkbd_name;
- xtkbd->dev.phys = xtkbd->phys;
- xtkbd->dev.id.bustype = BUS_XTKBD;
- xtkbd->dev.id.vendor = 0x0001;
- xtkbd->dev.id.product = 0x0001;
- xtkbd->dev.id.version = 0x0100;
- xtkbd->dev.dev = &serio->dev;
+ set_bit(xtkbd->keycode[i], input_dev->keybit);
+ clear_bit(0, input_dev->keybit);
- input_register_device(&xtkbd->dev);
+ serio_set_drvdata(serio, xtkbd);
- printk(KERN_INFO "input: %s on %s\n", xtkbd_name, serio->phys);
+ err = serio_open(serio, drv);
+ if (err)
+ goto fail;
+ input_register_device(xtkbd->dev);
return 0;
+
+ fail: serio_set_drvdata(serio, NULL);
+ input_free_device(input_dev);
+ kfree(xtkbd);
+ return err;
}
static void xtkbd_disconnect(struct serio *serio)
{
struct xtkbd *xtkbd = serio_get_drvdata(serio);
- input_unregister_device(&xtkbd->dev);
serio_close(serio);
serio_set_drvdata(serio, NULL);
+ input_unregister_device(xtkbd->dev);
kfree(xtkbd);
}
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
index bb934e6d9636..b3eaac1b35b6 100644
--- a/drivers/input/misc/Kconfig
+++ b/drivers/input/misc/Kconfig
@@ -14,7 +14,7 @@ if INPUT_MISC
config INPUT_PCSPKR
tristate "PC Speaker support"
- depends on ALPHA || X86 || X86_64 || MIPS || PPC_PREP || PPC_CHRP || PPC_PSERIES
+ depends on ALPHA || X86 || MIPS || PPC_PREP || PPC_CHRP || PPC_PSERIES
help
Say Y here if you want the standard PC Speaker to be used for
bells and whistles.
diff --git a/drivers/input/misc/m68kspkr.c b/drivers/input/misc/m68kspkr.c
index 64abdd98d482..04489ad7702a 100644
--- a/drivers/input/misc/m68kspkr.c
+++ b/drivers/input/misc/m68kspkr.c
@@ -24,9 +24,7 @@ MODULE_AUTHOR("Richard Zidlicky <rz@linux-m68k.org>");
MODULE_DESCRIPTION("m68k beeper driver");
MODULE_LICENSE("GPL");
-static char m68kspkr_name[] = "m68k beeper";
-static char m68kspkr_phys[] = "m68k/generic";
-static struct input_dev m68kspkr_dev;
+static struct input_dev *m68kspkr_dev;
static int m68kspkr_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
{
@@ -51,32 +49,34 @@ static int m68kspkr_event(struct input_dev *dev, unsigned int type, unsigned int
static int __init m68kspkr_init(void)
{
- if (!mach_beep){
- printk("%s: no lowlevel beep support\n", m68kspkr_name);
- return -1;
+ if (!mach_beep) {
+ printk(KERN_INFO "m68kspkr: no lowlevel beep support\n");
+ return -ENODEV;
}
- m68kspkr_dev.evbit[0] = BIT(EV_SND);
- m68kspkr_dev.sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE);
- m68kspkr_dev.event = m68kspkr_event;
+ m68kspkr_dev = input_allocate_device();
+ if (!m68kspkr_dev)
+ return -ENOMEM;
- m68kspkr_dev.name = m68kspkr_name;
- m68kspkr_dev.phys = m68kspkr_phys;
- m68kspkr_dev.id.bustype = BUS_HOST;
- m68kspkr_dev.id.vendor = 0x001f;
- m68kspkr_dev.id.product = 0x0001;
- m68kspkr_dev.id.version = 0x0100;
+ m68kspkr_dev->name = "m68k beeper";
+ m68kspkr_dev->phys = "m68k/generic";
+ m68kspkr_dev->id.bustype = BUS_HOST;
+ m68kspkr_dev->id.vendor = 0x001f;
+ m68kspkr_dev->id.product = 0x0001;
+ m68kspkr_dev->id.version = 0x0100;
- input_register_device(&m68kspkr_dev);
+ m68kspkr_dev->evbit[0] = BIT(EV_SND);
+ m68kspkr_dev->sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE);
+ m68kspkr_dev->event = m68kspkr_event;
- printk(KERN_INFO "input: %s\n", m68kspkr_name);
+ input_register_device(m68kspkr_dev);
return 0;
}
static void __exit m68kspkr_exit(void)
{
- input_unregister_device(&m68kspkr_dev);
+ input_unregister_device(m68kspkr_dev);
}
module_init(m68kspkr_init);
diff --git a/drivers/input/misc/pcspkr.c b/drivers/input/misc/pcspkr.c
index 3013194f462b..68ac97f101b0 100644
--- a/drivers/input/misc/pcspkr.c
+++ b/drivers/input/misc/pcspkr.c
@@ -23,9 +23,7 @@ MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
MODULE_DESCRIPTION("PC Speaker beeper driver");
MODULE_LICENSE("GPL");
-static char pcspkr_name[] = "PC Speaker";
-static char pcspkr_phys[] = "isa0061/input0";
-static struct input_dev pcspkr_dev;
+static struct input_dev *pcspkr_dev;
static DEFINE_SPINLOCK(i8253_beep_lock);
@@ -68,27 +66,29 @@ static int pcspkr_event(struct input_dev *dev, unsigned int type, unsigned int c
static int __init pcspkr_init(void)
{
- pcspkr_dev.evbit[0] = BIT(EV_SND);
- pcspkr_dev.sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE);
- pcspkr_dev.event = pcspkr_event;
+ pcspkr_dev = input_allocate_device();
+ if (!pcspkr_dev)
+ return -ENOMEM;
- pcspkr_dev.name = pcspkr_name;
- pcspkr_dev.phys = pcspkr_phys;
- pcspkr_dev.id.bustype = BUS_ISA;
- pcspkr_dev.id.vendor = 0x001f;
- pcspkr_dev.id.product = 0x0001;
- pcspkr_dev.id.version = 0x0100;
+ pcspkr_dev->name = "PC Speaker";
+ pcspkr_dev->phys = "isa0061/input0";
+ pcspkr_dev->id.bustype = BUS_ISA;
+ pcspkr_dev->id.vendor = 0x001f;
+ pcspkr_dev->id.product = 0x0001;
+ pcspkr_dev->id.version = 0x0100;
- input_register_device(&pcspkr_dev);
+ pcspkr_dev->evbit[0] = BIT(EV_SND);
+ pcspkr_dev->sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE);
+ pcspkr_dev->event = pcspkr_event;
- printk(KERN_INFO "input: %s\n", pcspkr_name);
+ input_register_device(pcspkr_dev);
return 0;
}
static void __exit pcspkr_exit(void)
{
- input_unregister_device(&pcspkr_dev);
+ input_unregister_device(pcspkr_dev);
/* turn off the speaker */
pcspkr_event(NULL, EV_SND, SND_BELL, 0);
}
diff --git a/drivers/input/misc/sparcspkr.c b/drivers/input/misc/sparcspkr.c
index cdc3fb3d5f46..29d97b12be7a 100644
--- a/drivers/input/misc/sparcspkr.c
+++ b/drivers/input/misc/sparcspkr.c
@@ -17,28 +17,24 @@
#endif
MODULE_AUTHOR("David S. Miller <davem@redhat.com>");
-MODULE_DESCRIPTION("PC Speaker beeper driver");
+MODULE_DESCRIPTION("Sparc Speaker beeper driver");
MODULE_LICENSE("GPL");
static unsigned long beep_iobase;
-
-static char *sparcspkr_isa_name = "Sparc ISA Speaker";
-static char *sparcspkr_ebus_name = "Sparc EBUS Speaker";
-static char *sparcspkr_phys = "sparc/input0";
-static struct input_dev sparcspkr_dev;
+static struct input_dev *sparcspkr_dev;
DEFINE_SPINLOCK(beep_lock);
static void __init init_sparcspkr_struct(void)
{
- sparcspkr_dev.evbit[0] = BIT(EV_SND);
- sparcspkr_dev.sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE);
-
- sparcspkr_dev.phys = sparcspkr_phys;
- sparcspkr_dev.id.bustype = BUS_ISA;
- sparcspkr_dev.id.vendor = 0x001f;
- sparcspkr_dev.id.product = 0x0001;
- sparcspkr_dev.id.version = 0x0100;
+ sparcspkr_dev->evbit[0] = BIT(EV_SND);
+ sparcspkr_dev->sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE);
+
+ sparcspkr_dev->phys = "sparc/input0";
+ sparcspkr_dev->id.bustype = BUS_ISA;
+ sparcspkr_dev->id.vendor = 0x001f;
+ sparcspkr_dev->id.product = 0x0001;
+ sparcspkr_dev->id.version = 0x0100;
}
static int ebus_spkr_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
@@ -84,14 +80,15 @@ static int __init init_ebus_beep(struct linux_ebus_device *edev)
{
beep_iobase = edev->resource[0].start;
- init_sparcspkr_struct();
+ sparcspkr_dev = input_allocate_device();
+ if (!sparcspkr_dev)
+ return -ENOMEM;
- sparcspkr_dev.name = sparcspkr_ebus_name;
- sparcspkr_dev.event = ebus_spkr_event;
+ sparcspkr_dev->name = "Sparc EBUS Speaker";
+ sparcspkr_dev->event = ebus_spkr_event;
- input_register_device(&sparcspkr_dev);
+ input_register_device(sparcspkr_dev);
- printk(KERN_INFO "input: %s\n", sparcspkr_ebus_name);
return 0;
}
@@ -137,15 +134,17 @@ static int __init init_isa_beep(struct sparc_isa_device *isa_dev)
{
beep_iobase = isa_dev->resource.start;
+ sparcspkr_dev = input_allocate_device();
+ if (!sparcspkr_dev)
+ return -ENOMEM;
+
init_sparcspkr_struct();
- sparcspkr_dev.name = sparcspkr_isa_name;
- sparcspkr_dev.event = isa_spkr_event;
- sparcspkr_dev.id.bustype = BUS_ISA;
+ sparcspkr_dev->name = "Sparc ISA Speaker";
+ sparcspkr_dev->event = isa_spkr_event;
- input_register_device(&sparcspkr_dev);
+ input_register_device(sparcspkr_dev);
- printk(KERN_INFO "input: %s\n", sparcspkr_isa_name);
return 0;
}
#endif
@@ -182,7 +181,7 @@ static int __init sparcspkr_init(void)
static void __exit sparcspkr_exit(void)
{
- input_unregister_device(&sparcspkr_dev);
+ input_unregister_device(sparcspkr_dev);
}
module_init(sparcspkr_init);
diff --git a/drivers/input/misc/uinput.c b/drivers/input/misc/uinput.c
index 4015a91f4b6e..948c1cc01bc9 100644
--- a/drivers/input/misc/uinput.c
+++ b/drivers/input/misc/uinput.c
@@ -271,8 +271,7 @@ static int uinput_alloc_device(struct file *file, const char __user *buffer, siz
goto exit;
}
- if (dev->name)
- kfree(dev->name);
+ kfree(dev->name);
size = strnlen(user_dev->name, UINPUT_MAX_NAME_SIZE) + 1;
dev->name = name = kmalloc(size, GFP_KERNEL);
@@ -372,11 +371,8 @@ static int uinput_burn_device(struct uinput_device *udev)
if (test_bit(UIST_CREATED, &udev->state))
uinput_destroy_device(udev);
- if (udev->dev->name)
- kfree(udev->dev->name);
- if (udev->dev->phys)
- kfree(udev->dev->phys);
-
+ kfree(udev->dev->name);
+ kfree(udev->dev->phys);
kfree(udev->dev);
kfree(udev);
diff --git a/drivers/input/mouse/Kconfig b/drivers/input/mouse/Kconfig
index 537154dd7a87..574b18a523af 100644
--- a/drivers/input/mouse/Kconfig
+++ b/drivers/input/mouse/Kconfig
@@ -17,7 +17,7 @@ config MOUSE_PS2
default y
select SERIO
select SERIO_LIBPS2
- select SERIO_I8042 if PC
+ select SERIO_I8042 if X86_PC
select SERIO_GSCPS2 if GSC
---help---
Say Y here if you have a PS/2 mouse connected to your system. This
diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c
index b20783f9748a..4acc7fd4cd0f 100644
--- a/drivers/input/mouse/alps.c
+++ b/drivers/input/mouse/alps.c
@@ -79,8 +79,8 @@ static void alps_process_packet(struct psmouse *psmouse, struct pt_regs *regs)
{
struct alps_data *priv = psmouse->private;
unsigned char *packet = psmouse->packet;
- struct input_dev *dev = &psmouse->dev;
- struct input_dev *dev2 = &priv->dev2;
+ struct input_dev *dev = psmouse->dev;
+ struct input_dev *dev2 = priv->dev2;
int x, y, z, ges, fin, left, right, middle;
int back = 0, forward = 0;
@@ -379,20 +379,24 @@ static int alps_reconnect(struct psmouse *psmouse)
static void alps_disconnect(struct psmouse *psmouse)
{
struct alps_data *priv = psmouse->private;
+
psmouse_reset(psmouse);
- input_unregister_device(&priv->dev2);
+ input_unregister_device(priv->dev2);
kfree(priv);
}
int alps_init(struct psmouse *psmouse)
{
struct alps_data *priv;
+ struct input_dev *dev1 = psmouse->dev, *dev2;
int version;
- psmouse->private = priv = kmalloc(sizeof(struct alps_data), GFP_KERNEL);
- if (!priv)
+ psmouse->private = priv = kzalloc(sizeof(struct alps_data), GFP_KERNEL);
+ dev2 = input_allocate_device();
+ if (!priv || !dev2)
goto init_fail;
- memset(priv, 0, sizeof(struct alps_data));
+
+ priv->dev2 = dev2;
if (!(priv->i = alps_get_model(psmouse, &version)))
goto init_fail;
@@ -411,41 +415,39 @@ int alps_init(struct psmouse *psmouse)
if ((priv->i->flags & ALPS_PASS) && alps_passthrough_mode(psmouse, 0))
goto init_fail;
- psmouse->dev.evbit[LONG(EV_KEY)] |= BIT(EV_KEY);
- psmouse->dev.keybit[LONG(BTN_TOUCH)] |= BIT(BTN_TOUCH);
- psmouse->dev.keybit[LONG(BTN_TOOL_FINGER)] |= BIT(BTN_TOOL_FINGER);
- psmouse->dev.keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
+ dev1->evbit[LONG(EV_KEY)] |= BIT(EV_KEY);
+ dev1->keybit[LONG(BTN_TOUCH)] |= BIT(BTN_TOUCH);
+ dev1->keybit[LONG(BTN_TOOL_FINGER)] |= BIT(BTN_TOOL_FINGER);
+ dev1->keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
- psmouse->dev.evbit[LONG(EV_ABS)] |= BIT(EV_ABS);
- input_set_abs_params(&psmouse->dev, ABS_X, 0, 1023, 0, 0);
- input_set_abs_params(&psmouse->dev, ABS_Y, 0, 767, 0, 0);
- input_set_abs_params(&psmouse->dev, ABS_PRESSURE, 0, 127, 0, 0);
+ dev1->evbit[LONG(EV_ABS)] |= BIT(EV_ABS);
+ input_set_abs_params(dev1, ABS_X, 0, 1023, 0, 0);
+ input_set_abs_params(dev1, ABS_Y, 0, 767, 0, 0);
+ input_set_abs_params(dev1, ABS_PRESSURE, 0, 127, 0, 0);
if (priv->i->flags & ALPS_WHEEL) {
- psmouse->dev.evbit[LONG(EV_REL)] |= BIT(EV_REL);
- psmouse->dev.relbit[LONG(REL_WHEEL)] |= BIT(REL_WHEEL);
+ dev1->evbit[LONG(EV_REL)] |= BIT(EV_REL);
+ dev1->relbit[LONG(REL_WHEEL)] |= BIT(REL_WHEEL);
}
if (priv->i->flags & (ALPS_FW_BK_1 | ALPS_FW_BK_2)) {
- psmouse->dev.keybit[LONG(BTN_FORWARD)] |= BIT(BTN_FORWARD);
- psmouse->dev.keybit[LONG(BTN_BACK)] |= BIT(BTN_BACK);
+ dev1->keybit[LONG(BTN_FORWARD)] |= BIT(BTN_FORWARD);
+ dev1->keybit[LONG(BTN_BACK)] |= BIT(BTN_BACK);
}
sprintf(priv->phys, "%s/input1", psmouse->ps2dev.serio->phys);
- priv->dev2.phys = priv->phys;
- priv->dev2.name = (priv->i->flags & ALPS_DUALPOINT) ? "DualPoint Stick" : "PS/2 Mouse";
- priv->dev2.id.bustype = BUS_I8042;
- priv->dev2.id.vendor = 0x0002;
- priv->dev2.id.product = PSMOUSE_ALPS;
- priv->dev2.id.version = 0x0000;
-
- priv->dev2.evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
- priv->dev2.relbit[LONG(REL_X)] |= BIT(REL_X) | BIT(REL_Y);
- priv->dev2.keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
+ dev2->phys = priv->phys;
+ dev2->name = (priv->i->flags & ALPS_DUALPOINT) ? "DualPoint Stick" : "PS/2 Mouse";
+ dev2->id.bustype = BUS_I8042;
+ dev2->id.vendor = 0x0002;
+ dev2->id.product = PSMOUSE_ALPS;
+ dev2->id.version = 0x0000;
- input_register_device(&priv->dev2);
+ dev2->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
+ dev2->relbit[LONG(REL_X)] |= BIT(REL_X) | BIT(REL_Y);
+ dev2->keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
- printk(KERN_INFO "input: %s on %s\n", priv->dev2.name, psmouse->ps2dev.serio->phys);
+ input_register_device(priv->dev2);
psmouse->protocol_handler = alps_process_byte;
psmouse->disconnect = alps_disconnect;
@@ -455,6 +457,7 @@ int alps_init(struct psmouse *psmouse)
return 0;
init_fail:
+ input_free_device(dev2);
kfree(priv);
return -1;
}
diff --git a/drivers/input/mouse/alps.h b/drivers/input/mouse/alps.h
index aba103dd65b7..e428f8d5d12e 100644
--- a/drivers/input/mouse/alps.h
+++ b/drivers/input/mouse/alps.h
@@ -22,7 +22,7 @@ struct alps_model_info {
};
struct alps_data {
- struct input_dev dev2; /* Relative device */
+ struct input_dev *dev2; /* Relative device */
char name[32]; /* Name */
char phys[32]; /* Phys */
struct alps_model_info *i; /* Info */
diff --git a/drivers/input/mouse/amimouse.c b/drivers/input/mouse/amimouse.c
index e994849efb8f..d13d4c8fe3c5 100644
--- a/drivers/input/mouse/amimouse.c
+++ b/drivers/input/mouse/amimouse.c
@@ -34,10 +34,7 @@ MODULE_DESCRIPTION("Amiga mouse driver");
MODULE_LICENSE("GPL");
static int amimouse_lastx, amimouse_lasty;
-static struct input_dev amimouse_dev;
-
-static char *amimouse_name = "Amiga mouse";
-static char *amimouse_phys = "amimouse/input0";
+static struct input_dev *amimouse_dev;
static irqreturn_t amimouse_interrupt(int irq, void *dummy, struct pt_regs *fp)
{
@@ -62,16 +59,16 @@ static irqreturn_t amimouse_interrupt(int irq, void *dummy, struct pt_regs *fp)
potgor = custom.potgor;
- input_regs(&amimouse_dev, fp);
+ input_regs(amimouse_dev, fp);
- input_report_rel(&amimouse_dev, REL_X, dx);
- input_report_rel(&amimouse_dev, REL_Y, dy);
+ input_report_rel(amimouse_dev, REL_X, dx);
+ input_report_rel(amimouse_dev, REL_Y, dy);
- input_report_key(&amimouse_dev, BTN_LEFT, ciaa.pra & 0x40);
- input_report_key(&amimouse_dev, BTN_MIDDLE, potgor & 0x0100);
- input_report_key(&amimouse_dev, BTN_RIGHT, potgor & 0x0400);
+ input_report_key(amimouse_dev, BTN_LEFT, ciaa.pra & 0x40);
+ input_report_key(amimouse_dev, BTN_MIDDLE, potgor & 0x0100);
+ input_report_key(amimouse_dev, BTN_RIGHT, potgor & 0x0400);
- input_sync(&amimouse_dev);
+ input_sync(amimouse_dev);
return IRQ_HANDLED;
}
@@ -103,28 +100,30 @@ static int __init amimouse_init(void)
if (!MACH_IS_AMIGA || !AMIGAHW_PRESENT(AMI_MOUSE))
return -ENODEV;
- amimouse_dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
- amimouse_dev.relbit[0] = BIT(REL_X) | BIT(REL_Y);
- amimouse_dev.keybit[LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
- amimouse_dev.open = amimouse_open;
- amimouse_dev.close = amimouse_close;
+ if (!(amimouse_dev = input_allocate_device()))
+ return -ENOMEM;
+
+ amimouse_dev->name = "Amiga mouse";
+ amimouse_dev->phys = "amimouse/input0";
+ amimouse_dev->id.bustype = BUS_AMIGA;
+ amimouse_dev->id.vendor = 0x0001;
+ amimouse_dev->id.product = 0x0002;
+ amimouse_dev->id.version = 0x0100;
- amimouse_dev.name = amimouse_name;
- amimouse_dev.phys = amimouse_phys;
- amimouse_dev.id.bustype = BUS_AMIGA;
- amimouse_dev.id.vendor = 0x0001;
- amimouse_dev.id.product = 0x0002;
- amimouse_dev.id.version = 0x0100;
+ amimouse_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
+ amimouse_dev->relbit[0] = BIT(REL_X) | BIT(REL_Y);
+ amimouse_dev->keybit[LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
+ amimouse_dev->open = amimouse_open;
+ amimouse_dev->close = amimouse_close;
- input_register_device(&amimouse_dev);
+ input_register_device(amimouse_dev);
- printk(KERN_INFO "input: %s at joy0dat\n", amimouse_name);
return 0;
}
static void __exit amimouse_exit(void)
{
- input_unregister_device(&amimouse_dev);
+ input_unregister_device(amimouse_dev);
}
module_init(amimouse_init);
diff --git a/drivers/input/mouse/hil_ptr.c b/drivers/input/mouse/hil_ptr.c
index bc22849c6c79..c2bf2ed07dc6 100644
--- a/drivers/input/mouse/hil_ptr.c
+++ b/drivers/input/mouse/hil_ptr.c
@@ -196,7 +196,7 @@ static irqreturn_t hil_ptr_interrupt(struct serio *serio,
hil_packet packet;
int idx;
- ptr = (struct hil_ptr *)serio->private;
+ ptr = serio_get_drvdata(serio);
if (ptr == NULL) {
BUG();
return IRQ_HANDLED;
@@ -227,7 +227,7 @@ static void hil_ptr_disconnect(struct serio *serio)
{
struct hil_ptr *ptr;
- ptr = (struct hil_ptr *)serio->private;
+ ptr = serio_get_drvdata(serio);
if (ptr == NULL) {
BUG();
return;
@@ -238,21 +238,19 @@ static void hil_ptr_disconnect(struct serio *serio)
kfree(ptr);
}
-static void hil_ptr_connect(struct serio *serio, struct serio_driver *driver)
+static int hil_ptr_connect(struct serio *serio, struct serio_driver *driver)
{
struct hil_ptr *ptr;
char *txt;
unsigned int i, naxsets, btntype;
uint8_t did, *idd;
- if (serio->type != (SERIO_HIL_MLC | SERIO_HIL)) return;
-
- if (!(ptr = kmalloc(sizeof(struct hil_ptr), GFP_KERNEL))) return;
+ if (!(ptr = kmalloc(sizeof(struct hil_ptr), GFP_KERNEL))) return -ENOMEM;
memset(ptr, 0, sizeof(struct hil_ptr));
if (serio_open(serio, driver)) goto bail0;
- serio->private = ptr;
+ serio_set_drvdata(serio, ptr);
ptr->serio = serio;
ptr->dev.private = ptr;
@@ -380,23 +378,34 @@ static void hil_ptr_connect(struct serio *serio, struct serio_driver *driver)
(btntype == BTN_MOUSE) ? "HIL mouse":"HIL tablet or touchpad",
did);
- return;
+ return 0;
bail1:
serio_close(serio);
bail0:
kfree(ptr);
- return;
+ serio_set_drvdata(serio, NULL);
+ return -ENODEV;
}
+static struct serio_device_id hil_ptr_ids[] = {
+ {
+ .type = SERIO_HIL_MLC,
+ .proto = SERIO_HIL,
+ .id = SERIO_ANY,
+ .extra = SERIO_ANY,
+ },
+ { 0 }
+};
static struct serio_driver hil_ptr_serio_driver = {
.driver = {
.name = "hil_ptr",
},
.description = "HP HIL mouse/tablet driver",
- .connect = hil_ptr_connect,
- .disconnect = hil_ptr_disconnect,
- .interrupt = hil_ptr_interrupt
+ .id_table = hil_ptr_ids,
+ .connect = hil_ptr_connect,
+ .disconnect = hil_ptr_disconnect,
+ .interrupt = hil_ptr_interrupt
};
static int __init hil_ptr_init(void)
diff --git a/drivers/input/mouse/inport.c b/drivers/input/mouse/inport.c
index 1f62c0134010..afc66f56df43 100644
--- a/drivers/input/mouse/inport.c
+++ b/drivers/input/mouse/inport.c
@@ -87,40 +87,7 @@ MODULE_PARM_DESC(irq, "IRQ number (5=default)");
__obsolete_setup("inport_irq=");
-static irqreturn_t inport_interrupt(int irq, void *dev_id, struct pt_regs *regs);
-
-static int inport_open(struct input_dev *dev)
-{
- if (request_irq(inport_irq, inport_interrupt, 0, "inport", NULL))
- return -EBUSY;
- outb(INPORT_REG_MODE, INPORT_CONTROL_PORT);
- outb(INPORT_MODE_IRQ | INPORT_MODE_BASE, INPORT_DATA_PORT);
-
- return 0;
-}
-
-static void inport_close(struct input_dev *dev)
-{
- outb(INPORT_REG_MODE, INPORT_CONTROL_PORT);
- outb(INPORT_MODE_BASE, INPORT_DATA_PORT);
- free_irq(inport_irq, NULL);
-}
-
-static struct input_dev inport_dev = {
- .evbit = { BIT(EV_KEY) | BIT(EV_REL) },
- .keybit = { [LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT) },
- .relbit = { BIT(REL_X) | BIT(REL_Y) },
- .open = inport_open,
- .close = inport_close,
- .name = INPORT_NAME,
- .phys = "isa023c/input0",
- .id = {
- .bustype = BUS_ISA,
- .vendor = INPORT_VENDOR,
- .product = 0x0001,
- .version = 0x0100,
- },
-};
+static struct input_dev *inport_dev;
static irqreturn_t inport_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
@@ -129,31 +96,48 @@ static irqreturn_t inport_interrupt(int irq, void *dev_id, struct pt_regs *regs)
outb(INPORT_REG_MODE, INPORT_CONTROL_PORT);
outb(INPORT_MODE_HOLD | INPORT_MODE_IRQ | INPORT_MODE_BASE, INPORT_DATA_PORT);
- input_regs(&inport_dev, regs);
+ input_regs(inport_dev, regs);
outb(INPORT_REG_X, INPORT_CONTROL_PORT);
- input_report_rel(&inport_dev, REL_X, inb(INPORT_DATA_PORT));
+ input_report_rel(inport_dev, REL_X, inb(INPORT_DATA_PORT));
outb(INPORT_REG_Y, INPORT_CONTROL_PORT);
- input_report_rel(&inport_dev, REL_Y, inb(INPORT_DATA_PORT));
+ input_report_rel(inport_dev, REL_Y, inb(INPORT_DATA_PORT));
outb(INPORT_REG_BTNS, INPORT_CONTROL_PORT);
buttons = inb(INPORT_DATA_PORT);
- input_report_key(&inport_dev, BTN_MIDDLE, buttons & 1);
- input_report_key(&inport_dev, BTN_LEFT, buttons & 2);
- input_report_key(&inport_dev, BTN_RIGHT, buttons & 4);
+ input_report_key(inport_dev, BTN_MIDDLE, buttons & 1);
+ input_report_key(inport_dev, BTN_LEFT, buttons & 2);
+ input_report_key(inport_dev, BTN_RIGHT, buttons & 4);
outb(INPORT_REG_MODE, INPORT_CONTROL_PORT);
outb(INPORT_MODE_IRQ | INPORT_MODE_BASE, INPORT_DATA_PORT);
- input_sync(&inport_dev);
+ input_sync(inport_dev);
return IRQ_HANDLED;
}
+static int inport_open(struct input_dev *dev)
+{
+ if (request_irq(inport_irq, inport_interrupt, 0, "inport", NULL))
+ return -EBUSY;
+ outb(INPORT_REG_MODE, INPORT_CONTROL_PORT);
+ outb(INPORT_MODE_IRQ | INPORT_MODE_BASE, INPORT_DATA_PORT);
+
+ return 0;
+}
+
+static void inport_close(struct input_dev *dev)
+{
+ outb(INPORT_REG_MODE, INPORT_CONTROL_PORT);
+ outb(INPORT_MODE_BASE, INPORT_DATA_PORT);
+ free_irq(inport_irq, NULL);
+}
+
static int __init inport_init(void)
{
- unsigned char a,b,c;
+ unsigned char a, b, c;
if (!request_region(INPORT_BASE, INPORT_EXTENT, "inport")) {
printk(KERN_ERR "inport.c: Can't allocate ports at %#x\n", INPORT_BASE);
@@ -163,26 +147,44 @@ static int __init inport_init(void)
a = inb(INPORT_SIGNATURE_PORT);
b = inb(INPORT_SIGNATURE_PORT);
c = inb(INPORT_SIGNATURE_PORT);
- if (( a == b ) || ( a != c )) {
+ if (a == b || a != c) {
release_region(INPORT_BASE, INPORT_EXTENT);
printk(KERN_ERR "inport.c: Didn't find InPort mouse at %#x\n", INPORT_BASE);
return -ENODEV;
}
+ if (!(inport_dev = input_allocate_device())) {
+ printk(KERN_ERR "inport.c: Not enough memory for input device\n");
+ release_region(INPORT_BASE, INPORT_EXTENT);
+ return -ENOMEM;
+ }
+
+ inport_dev->name = INPORT_NAME;
+ inport_dev->phys = "isa023c/input0";
+ inport_dev->id.bustype = BUS_ISA;
+ inport_dev->id.vendor = INPORT_VENDOR;
+ inport_dev->id.product = 0x0001;
+ inport_dev->id.version = 0x0100;
+
+ inport_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
+ inport_dev->keybit[LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
+ inport_dev->relbit[0] = BIT(REL_X) | BIT(REL_Y);
+
+ inport_dev->open = inport_open;
+ inport_dev->close = inport_close;
+
outb(INPORT_RESET, INPORT_CONTROL_PORT);
outb(INPORT_REG_MODE, INPORT_CONTROL_PORT);
outb(INPORT_MODE_BASE, INPORT_DATA_PORT);
- input_register_device(&inport_dev);
-
- printk(KERN_INFO "input: " INPORT_NAME " at %#x irq %d\n", INPORT_BASE, inport_irq);
+ input_register_device(inport_dev);
return 0;
}
static void __exit inport_exit(void)
{
- input_unregister_device(&inport_dev);
+ input_unregister_device(inport_dev);
release_region(INPORT_BASE, INPORT_EXTENT);
}
diff --git a/drivers/input/mouse/lifebook.c b/drivers/input/mouse/lifebook.c
index bd9df9b28325..55991424ac91 100644
--- a/drivers/input/mouse/lifebook.c
+++ b/drivers/input/mouse/lifebook.c
@@ -34,7 +34,7 @@ static struct dmi_system_id lifebook_dmi_table[] = {
static psmouse_ret_t lifebook_process_byte(struct psmouse *psmouse, struct pt_regs *regs)
{
unsigned char *packet = psmouse->packet;
- struct input_dev *dev = &psmouse->dev;
+ struct input_dev *dev = psmouse->dev;
if (psmouse->pktcnt != 3)
return PSMOUSE_GOOD_DATA;
@@ -113,15 +113,17 @@ int lifebook_detect(struct psmouse *psmouse, int set_properties)
int lifebook_init(struct psmouse *psmouse)
{
+ struct input_dev *input_dev = psmouse->dev;
+
if (lifebook_absolute_mode(psmouse))
return -1;
- psmouse->dev.evbit[0] = BIT(EV_ABS) | BIT(EV_KEY) | BIT(EV_REL);
- psmouse->dev.keybit[LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
- psmouse->dev.keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
- psmouse->dev.relbit[0] = BIT(REL_X) | BIT(REL_Y);
- input_set_abs_params(&psmouse->dev, ABS_X, 0, 1024, 0, 0);
- input_set_abs_params(&psmouse->dev, ABS_Y, 0, 1024, 0, 0);
+ input_dev->evbit[0] = BIT(EV_ABS) | BIT(EV_KEY) | BIT(EV_REL);
+ input_dev->keybit[LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
+ input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
+ input_dev->relbit[0] = BIT(REL_X) | BIT(REL_Y);
+ input_set_abs_params(input_dev, ABS_X, 0, 1024, 0, 0);
+ input_set_abs_params(input_dev, ABS_Y, 0, 1024, 0, 0);
psmouse->protocol_handler = lifebook_process_byte;
psmouse->set_resolution = lifebook_set_resolution;
diff --git a/drivers/input/mouse/logibm.c b/drivers/input/mouse/logibm.c
index 8b5243167227..9c7ce38806d7 100644
--- a/drivers/input/mouse/logibm.c
+++ b/drivers/input/mouse/logibm.c
@@ -77,39 +77,7 @@ MODULE_PARM_DESC(irq, "IRQ number (5=default)");
__obsolete_setup("logibm_irq=");
-static irqreturn_t logibm_interrupt(int irq, void *dev_id, struct pt_regs *regs);
-
-static int logibm_open(struct input_dev *dev)
-{
- if (request_irq(logibm_irq, logibm_interrupt, 0, "logibm", NULL)) {
- printk(KERN_ERR "logibm.c: Can't allocate irq %d\n", logibm_irq);
- return -EBUSY;
- }
- outb(LOGIBM_ENABLE_IRQ, LOGIBM_CONTROL_PORT);
- return 0;
-}
-
-static void logibm_close(struct input_dev *dev)
-{
- outb(LOGIBM_DISABLE_IRQ, LOGIBM_CONTROL_PORT);
- free_irq(logibm_irq, NULL);
-}
-
-static struct input_dev logibm_dev = {
- .evbit = { BIT(EV_KEY) | BIT(EV_REL) },
- .keybit = { [LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT) },
- .relbit = { BIT(REL_X) | BIT(REL_Y) },
- .open = logibm_open,
- .close = logibm_close,
- .name = "Logitech bus mouse",
- .phys = "isa023c/input0",
- .id = {
- .bustype = BUS_ISA,
- .vendor = 0x0003,
- .product = 0x0001,
- .version = 0x0100,
- },
-};
+static struct input_dev *logibm_dev;
static irqreturn_t logibm_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
@@ -127,18 +95,34 @@ static irqreturn_t logibm_interrupt(int irq, void *dev_id, struct pt_regs *regs)
dy |= (buttons & 0xf) << 4;
buttons = ~buttons >> 5;
- input_regs(&logibm_dev, regs);
- input_report_rel(&logibm_dev, REL_X, dx);
- input_report_rel(&logibm_dev, REL_Y, dy);
- input_report_key(&logibm_dev, BTN_RIGHT, buttons & 1);
- input_report_key(&logibm_dev, BTN_MIDDLE, buttons & 2);
- input_report_key(&logibm_dev, BTN_LEFT, buttons & 4);
- input_sync(&logibm_dev);
+ input_regs(logibm_dev, regs);
+ input_report_rel(logibm_dev, REL_X, dx);
+ input_report_rel(logibm_dev, REL_Y, dy);
+ input_report_key(logibm_dev, BTN_RIGHT, buttons & 1);
+ input_report_key(logibm_dev, BTN_MIDDLE, buttons & 2);
+ input_report_key(logibm_dev, BTN_LEFT, buttons & 4);
+ input_sync(logibm_dev);
outb(LOGIBM_ENABLE_IRQ, LOGIBM_CONTROL_PORT);
return IRQ_HANDLED;
}
+static int logibm_open(struct input_dev *dev)
+{
+ if (request_irq(logibm_irq, logibm_interrupt, 0, "logibm", NULL)) {
+ printk(KERN_ERR "logibm.c: Can't allocate irq %d\n", logibm_irq);
+ return -EBUSY;
+ }
+ outb(LOGIBM_ENABLE_IRQ, LOGIBM_CONTROL_PORT);
+ return 0;
+}
+
+static void logibm_close(struct input_dev *dev)
+{
+ outb(LOGIBM_DISABLE_IRQ, LOGIBM_CONTROL_PORT);
+ free_irq(logibm_irq, NULL);
+}
+
static int __init logibm_init(void)
{
if (!request_region(LOGIBM_BASE, LOGIBM_EXTENT, "logibm")) {
@@ -159,16 +143,34 @@ static int __init logibm_init(void)
outb(LOGIBM_DEFAULT_MODE, LOGIBM_CONFIG_PORT);
outb(LOGIBM_DISABLE_IRQ, LOGIBM_CONTROL_PORT);
- input_register_device(&logibm_dev);
+ if (!(logibm_dev = input_allocate_device())) {
+ printk(KERN_ERR "logibm.c: Not enough memory for input device\n");
+ release_region(LOGIBM_BASE, LOGIBM_EXTENT);
+ return -ENOMEM;
+ }
+
+ logibm_dev->name = "Logitech bus mouse";
+ logibm_dev->phys = "isa023c/input0";
+ logibm_dev->id.bustype = BUS_ISA;
+ logibm_dev->id.vendor = 0x0003;
+ logibm_dev->id.product = 0x0001;
+ logibm_dev->id.version = 0x0100;
+
+ logibm_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
+ logibm_dev->keybit[LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
+ logibm_dev->relbit[0] = BIT(REL_X) | BIT(REL_Y);
+
+ logibm_dev->open = logibm_open;
+ logibm_dev->close = logibm_close;
- printk(KERN_INFO "input: Logitech bus mouse at %#x irq %d\n", LOGIBM_BASE, logibm_irq);
+ input_register_device(logibm_dev);
return 0;
}
static void __exit logibm_exit(void)
{
- input_unregister_device(&logibm_dev);
+ input_unregister_device(logibm_dev);
release_region(LOGIBM_BASE, LOGIBM_EXTENT);
}
diff --git a/drivers/input/mouse/logips2pp.c b/drivers/input/mouse/logips2pp.c
index 7df96525222e..31a59f7abfaf 100644
--- a/drivers/input/mouse/logips2pp.c
+++ b/drivers/input/mouse/logips2pp.c
@@ -40,7 +40,7 @@ struct ps2pp_info {
static psmouse_ret_t ps2pp_process_byte(struct psmouse *psmouse, struct pt_regs *regs)
{
- struct input_dev *dev = &psmouse->dev;
+ struct input_dev *dev = psmouse->dev;
unsigned char *packet = psmouse->packet;
if (psmouse->pktcnt < 3)
@@ -217,6 +217,9 @@ static struct ps2pp_info *get_model_info(unsigned char model)
{ 61, PS2PP_KIND_MX, /* MX700 */
PS2PP_WHEEL | PS2PP_SIDE_BTN | PS2PP_TASK_BTN |
PS2PP_EXTRA_BTN | PS2PP_NAV_BTN },
+ { 66, PS2PP_KIND_MX, /* MX3100 reciver */
+ PS2PP_WHEEL | PS2PP_SIDE_BTN | PS2PP_TASK_BTN |
+ PS2PP_EXTRA_BTN | PS2PP_NAV_BTN | PS2PP_HWHEEL },
{ 73, 0, PS2PP_SIDE_BTN },
{ 75, PS2PP_KIND_WHEEL, PS2PP_WHEEL },
{ 76, PS2PP_KIND_WHEEL, PS2PP_WHEEL },
@@ -257,25 +260,27 @@ static struct ps2pp_info *get_model_info(unsigned char model)
static void ps2pp_set_model_properties(struct psmouse *psmouse, struct ps2pp_info *model_info,
int using_ps2pp)
{
+ struct input_dev *input_dev = psmouse->dev;
+
if (model_info->features & PS2PP_SIDE_BTN)
- set_bit(BTN_SIDE, psmouse->dev.keybit);
+ set_bit(BTN_SIDE, input_dev->keybit);
if (model_info->features & PS2PP_EXTRA_BTN)
- set_bit(BTN_EXTRA, psmouse->dev.keybit);
+ set_bit(BTN_EXTRA, input_dev->keybit);
if (model_info->features & PS2PP_TASK_BTN)
- set_bit(BTN_TASK, psmouse->dev.keybit);
+ set_bit(BTN_TASK, input_dev->keybit);
if (model_info->features & PS2PP_NAV_BTN) {
- set_bit(BTN_FORWARD, psmouse->dev.keybit);
- set_bit(BTN_BACK, psmouse->dev.keybit);
+ set_bit(BTN_FORWARD, input_dev->keybit);
+ set_bit(BTN_BACK, input_dev->keybit);
}
if (model_info->features & PS2PP_WHEEL)
- set_bit(REL_WHEEL, psmouse->dev.relbit);
+ set_bit(REL_WHEEL, input_dev->relbit);
if (model_info->features & PS2PP_HWHEEL)
- set_bit(REL_HWHEEL, psmouse->dev.relbit);
+ set_bit(REL_HWHEEL, input_dev->relbit);
switch (model_info->kind) {
case PS2PP_KIND_WHEEL:
@@ -387,7 +392,7 @@ int ps2pp_init(struct psmouse *psmouse, int set_properties)
}
if (buttons < 3)
- clear_bit(BTN_MIDDLE, psmouse->dev.keybit);
+ clear_bit(BTN_MIDDLE, psmouse->dev->keybit);
if (model_info)
ps2pp_set_model_properties(psmouse, model_info, use_ps2pp);
diff --git a/drivers/input/mouse/maplemouse.c b/drivers/input/mouse/maplemouse.c
index e90c60cbbf05..b5b34fe4fee8 100644
--- a/drivers/input/mouse/maplemouse.c
+++ b/drivers/input/mouse/maplemouse.c
@@ -41,13 +41,12 @@ static int dc_mouse_connect(struct maple_device *dev)
unsigned long data = be32_to_cpu(dev->devinfo.function_data[0]);
struct input_dev *input_dev;
- if (!(input_dev = kmalloc(sizeof(struct input_dev), GFP_KERNEL)))
- return -1;
+ dev->private_data = input_dev = input_allocate_device();
+ if (!input_dev)
+ return -ENOMEM;
dev->private_data = input_dev;
- memset(input_dev, 0, sizeof(struct dc_mouse));
- init_input_dev(input_dev);
input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
input_dev->keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE);
input_dev->relbit[0] = BIT(REL_X) | BIT(REL_Y) | BIT(REL_WHEEL);
@@ -59,8 +58,6 @@ static int dc_mouse_connect(struct maple_device *dev)
maple_getcond_callback(dev, dc_mouse_callback, 1, MAPLE_FUNC_MOUSE);
- printk(KERN_INFO "input: mouse(0x%lx): %s\n", data, input_dev->name);
-
return 0;
}
@@ -70,7 +67,6 @@ static void dc_mouse_disconnect(struct maple_device *dev)
struct input_dev *input_dev = dev->private_data;
input_unregister_device(input_dev);
- kfree(input_dev);
}
diff --git a/drivers/input/mouse/pc110pad.c b/drivers/input/mouse/pc110pad.c
index 93393d5c0078..d284ea712151 100644
--- a/drivers/input/mouse/pc110pad.c
+++ b/drivers/input/mouse/pc110pad.c
@@ -53,13 +53,10 @@ MODULE_LICENSE("GPL");
static int pc110pad_irq = 10;
static int pc110pad_io = 0x15e0;
-static struct input_dev pc110pad_dev;
+static struct input_dev *pc110pad_dev;
static int pc110pad_data[3];
static int pc110pad_count;
-static char *pc110pad_name = "IBM PC110 TouchPad";
-static char *pc110pad_phys = "isa15e0/input0";
-
static irqreturn_t pc110pad_interrupt(int irq, void *ptr, struct pt_regs *regs)
{
int value = inb_p(pc110pad_io);
@@ -74,14 +71,14 @@ static irqreturn_t pc110pad_interrupt(int irq, void *ptr, struct pt_regs *regs)
if (pc110pad_count < 3)
return IRQ_HANDLED;
- input_regs(&pc110pad_dev, regs);
- input_report_key(&pc110pad_dev, BTN_TOUCH,
+ input_regs(pc110pad_dev, regs);
+ input_report_key(pc110pad_dev, BTN_TOUCH,
pc110pad_data[0] & 0x01);
- input_report_abs(&pc110pad_dev, ABS_X,
+ input_report_abs(pc110pad_dev, ABS_X,
pc110pad_data[1] | ((pc110pad_data[0] << 3) & 0x80) | ((pc110pad_data[0] << 1) & 0x100));
- input_report_abs(&pc110pad_dev, ABS_Y,
+ input_report_abs(pc110pad_dev, ABS_Y,
pc110pad_data[2] | ((pc110pad_data[0] << 4) & 0x80));
- input_sync(&pc110pad_dev);
+ input_sync(pc110pad_dev);
pc110pad_count = 0;
return IRQ_HANDLED;
@@ -94,9 +91,9 @@ static void pc110pad_close(struct input_dev *dev)
static int pc110pad_open(struct input_dev *dev)
{
- pc110pad_interrupt(0,NULL,NULL);
- pc110pad_interrupt(0,NULL,NULL);
- pc110pad_interrupt(0,NULL,NULL);
+ pc110pad_interrupt(0, NULL, NULL);
+ pc110pad_interrupt(0, NULL, NULL);
+ pc110pad_interrupt(0, NULL, NULL);
outb(PC110PAD_ON, pc110pad_io + 2);
pc110pad_count = 0;
@@ -127,45 +124,46 @@ static int __init pc110pad_init(void)
outb(PC110PAD_OFF, pc110pad_io + 2);
- if (request_irq(pc110pad_irq, pc110pad_interrupt, 0, "pc110pad", NULL))
- {
+ if (request_irq(pc110pad_irq, pc110pad_interrupt, 0, "pc110pad", NULL)) {
release_region(pc110pad_io, 4);
printk(KERN_ERR "pc110pad: Unable to get irq %d.\n", pc110pad_irq);
return -EBUSY;
}
- pc110pad_dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
- pc110pad_dev.absbit[0] = BIT(ABS_X) | BIT(ABS_Y);
- pc110pad_dev.keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
+ if (!(pc110pad_dev = input_allocate_device())) {
+ free_irq(pc110pad_irq, NULL);
+ release_region(pc110pad_io, 4);
+ printk(KERN_ERR "pc110pad: Not enough memory.\n");
+ return -ENOMEM;
+ }
- pc110pad_dev.absmax[ABS_X] = 0x1ff;
- pc110pad_dev.absmax[ABS_Y] = 0x0ff;
+ pc110pad_dev->name = "IBM PC110 TouchPad";
+ pc110pad_dev->phys = "isa15e0/input0";
+ pc110pad_dev->id.bustype = BUS_ISA;
+ pc110pad_dev->id.vendor = 0x0003;
+ pc110pad_dev->id.product = 0x0001;
+ pc110pad_dev->id.version = 0x0100;
- pc110pad_dev.open = pc110pad_open;
- pc110pad_dev.close = pc110pad_close;
+ pc110pad_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+ pc110pad_dev->absbit[0] = BIT(ABS_X) | BIT(ABS_Y);
+ pc110pad_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
- pc110pad_dev.name = pc110pad_name;
- pc110pad_dev.phys = pc110pad_phys;
- pc110pad_dev.id.bustype = BUS_ISA;
- pc110pad_dev.id.vendor = 0x0003;
- pc110pad_dev.id.product = 0x0001;
- pc110pad_dev.id.version = 0x0100;
+ pc110pad_dev->absmax[ABS_X] = 0x1ff;
+ pc110pad_dev->absmax[ABS_Y] = 0x0ff;
- input_register_device(&pc110pad_dev);
+ pc110pad_dev->open = pc110pad_open;
+ pc110pad_dev->close = pc110pad_close;
- printk(KERN_INFO "input: %s at %#x irq %d\n",
- pc110pad_name, pc110pad_io, pc110pad_irq);
+ input_register_device(pc110pad_dev);
return 0;
}
static void __exit pc110pad_exit(void)
{
- input_unregister_device(&pc110pad_dev);
-
outb(PC110PAD_OFF, pc110pad_io + 2);
-
free_irq(pc110pad_irq, NULL);
+ input_unregister_device(pc110pad_dev);
release_region(pc110pad_io, 4);
}
diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c
index af24313ff5bb..6ee9999a2eaa 100644
--- a/drivers/input/mouse/psmouse-base.c
+++ b/drivers/input/mouse/psmouse-base.c
@@ -114,7 +114,7 @@ struct psmouse_protocol {
static psmouse_ret_t psmouse_process_byte(struct psmouse *psmouse, struct pt_regs *regs)
{
- struct input_dev *dev = &psmouse->dev;
+ struct input_dev *dev = psmouse->dev;
unsigned char *packet = psmouse->packet;
if (psmouse->pktcnt < psmouse->pktsize)
@@ -333,12 +333,11 @@ static int genius_detect(struct psmouse *psmouse, int set_properties)
return -1;
if (set_properties) {
- set_bit(BTN_EXTRA, psmouse->dev.keybit);
- set_bit(BTN_SIDE, psmouse->dev.keybit);
- set_bit(REL_WHEEL, psmouse->dev.relbit);
+ set_bit(BTN_EXTRA, psmouse->dev->keybit);
+ set_bit(BTN_SIDE, psmouse->dev->keybit);
+ set_bit(REL_WHEEL, psmouse->dev->relbit);
psmouse->vendor = "Genius";
- psmouse->name = "Wheel Mouse";
psmouse->pktsize = 4;
}
@@ -365,8 +364,8 @@ static int intellimouse_detect(struct psmouse *psmouse, int set_properties)
return -1;
if (set_properties) {
- set_bit(BTN_MIDDLE, psmouse->dev.keybit);
- set_bit(REL_WHEEL, psmouse->dev.relbit);
+ set_bit(BTN_MIDDLE, psmouse->dev->keybit);
+ set_bit(REL_WHEEL, psmouse->dev->relbit);
if (!psmouse->vendor) psmouse->vendor = "Generic";
if (!psmouse->name) psmouse->name = "Wheel Mouse";
@@ -398,10 +397,10 @@ static int im_explorer_detect(struct psmouse *psmouse, int set_properties)
return -1;
if (set_properties) {
- set_bit(BTN_MIDDLE, psmouse->dev.keybit);
- set_bit(REL_WHEEL, psmouse->dev.relbit);
- set_bit(BTN_SIDE, psmouse->dev.keybit);
- set_bit(BTN_EXTRA, psmouse->dev.keybit);
+ set_bit(BTN_MIDDLE, psmouse->dev->keybit);
+ set_bit(REL_WHEEL, psmouse->dev->relbit);
+ set_bit(BTN_SIDE, psmouse->dev->keybit);
+ set_bit(BTN_EXTRA, psmouse->dev->keybit);
if (!psmouse->vendor) psmouse->vendor = "Generic";
if (!psmouse->name) psmouse->name = "Explorer Mouse";
@@ -433,7 +432,7 @@ static int thinking_detect(struct psmouse *psmouse, int set_properties)
return -1;
if (set_properties) {
- set_bit(BTN_EXTRA, psmouse->dev.keybit);
+ set_bit(BTN_EXTRA, psmouse->dev->keybit);
psmouse->vendor = "Kensington";
psmouse->name = "ThinkingMouse";
@@ -839,9 +838,9 @@ static void psmouse_disconnect(struct serio *serio)
psmouse_set_state(psmouse, PSMOUSE_IGNORE);
- input_unregister_device(&psmouse->dev);
serio_close(serio);
serio_set_drvdata(serio, NULL);
+ input_unregister_device(psmouse->dev);
kfree(psmouse);
if (parent)
@@ -852,16 +851,14 @@ static void psmouse_disconnect(struct serio *serio)
static int psmouse_switch_protocol(struct psmouse *psmouse, struct psmouse_protocol *proto)
{
- memset(&psmouse->dev, 0, sizeof(struct input_dev));
+ struct input_dev *input_dev = psmouse->dev;
- init_input_dev(&psmouse->dev);
+ input_dev->private = psmouse;
+ input_dev->cdev.dev = &psmouse->ps2dev.serio->dev;
- psmouse->dev.private = psmouse;
- psmouse->dev.dev = &psmouse->ps2dev.serio->dev;
-
- psmouse->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
- psmouse->dev.keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
- psmouse->dev.relbit[0] = BIT(REL_X) | BIT(REL_Y);
+ input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
+ input_dev->keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
+ input_dev->relbit[0] = BIT(REL_X) | BIT(REL_Y);
psmouse->set_rate = psmouse_set_rate;
psmouse->set_resolution = psmouse_set_resolution;
@@ -883,12 +880,12 @@ static int psmouse_switch_protocol(struct psmouse *psmouse, struct psmouse_proto
sprintf(psmouse->devname, "%s %s %s",
psmouse_protocol_by_type(psmouse->type)->name, psmouse->vendor, psmouse->name);
- psmouse->dev.name = psmouse->devname;
- psmouse->dev.phys = psmouse->phys;
- psmouse->dev.id.bustype = BUS_I8042;
- psmouse->dev.id.vendor = 0x0002;
- psmouse->dev.id.product = psmouse->type;
- psmouse->dev.id.version = psmouse->model;
+ input_dev->name = psmouse->devname;
+ input_dev->phys = psmouse->phys;
+ input_dev->id.bustype = BUS_I8042;
+ input_dev->id.vendor = 0x0002;
+ input_dev->id.product = psmouse->type;
+ input_dev->id.version = psmouse->model;
return 0;
}
@@ -900,7 +897,8 @@ static int psmouse_switch_protocol(struct psmouse *psmouse, struct psmouse_proto
static int psmouse_connect(struct serio *serio, struct serio_driver *drv)
{
struct psmouse *psmouse, *parent = NULL;
- int retval;
+ struct input_dev *input_dev;
+ int retval = -ENOMEM;
down(&psmouse_sem);
@@ -913,12 +911,13 @@ static int psmouse_connect(struct serio *serio, struct serio_driver *drv)
psmouse_deactivate(parent);
}
- if (!(psmouse = kzalloc(sizeof(struct psmouse), GFP_KERNEL))) {
- retval = -ENOMEM;
+ psmouse = kzalloc(sizeof(struct psmouse), GFP_KERNEL);
+ input_dev = input_allocate_device();
+ if (!psmouse || !input_dev)
goto out;
- }
ps2_init(&psmouse->ps2dev, serio);
+ psmouse->dev = input_dev;
sprintf(psmouse->phys, "%s/input0", serio->phys);
psmouse_set_state(psmouse, PSMOUSE_INITIALIZING);
@@ -926,16 +925,11 @@ static int psmouse_connect(struct serio *serio, struct serio_driver *drv)
serio_set_drvdata(serio, psmouse);
retval = serio_open(serio, drv);
- if (retval) {
- serio_set_drvdata(serio, NULL);
- kfree(psmouse);
+ if (retval)
goto out;
- }
if (psmouse_probe(psmouse) < 0) {
serio_close(serio);
- serio_set_drvdata(serio, NULL);
- kfree(psmouse);
retval = -ENODEV;
goto out;
}
@@ -947,13 +941,11 @@ static int psmouse_connect(struct serio *serio, struct serio_driver *drv)
psmouse_switch_protocol(psmouse, NULL);
- input_register_device(&psmouse->dev);
- printk(KERN_INFO "input: %s on %s\n", psmouse->devname, serio->phys);
-
psmouse_set_state(psmouse, PSMOUSE_CMD_MODE);
-
psmouse_initialize(psmouse);
+ input_register_device(psmouse->dev);
+
if (parent && parent->pt_activate)
parent->pt_activate(parent);
@@ -964,6 +956,12 @@ static int psmouse_connect(struct serio *serio, struct serio_driver *drv)
retval = 0;
out:
+ if (retval) {
+ serio_set_drvdata(serio, NULL);
+ input_free_device(input_dev);
+ kfree(psmouse);
+ }
+
/* If this is a pass-through port the parent needs to be re-activated */
if (parent)
psmouse_activate(parent);
@@ -1161,6 +1159,7 @@ static ssize_t psmouse_attr_set_protocol(struct psmouse *psmouse, void *data, co
{
struct serio *serio = psmouse->ps2dev.serio;
struct psmouse *parent = NULL;
+ struct input_dev *new_dev;
struct psmouse_protocol *proto;
int retry = 0;
@@ -1170,9 +1169,13 @@ static ssize_t psmouse_attr_set_protocol(struct psmouse *psmouse, void *data, co
if (psmouse->type == proto->type)
return count;
+ if (!(new_dev = input_allocate_device()))
+ return -ENOMEM;
+
while (serio->child) {
if (++retry > 3) {
printk(KERN_WARNING "psmouse: failed to destroy child port, protocol change aborted.\n");
+ input_free_device(new_dev);
return -EIO;
}
@@ -1182,11 +1185,15 @@ static ssize_t psmouse_attr_set_protocol(struct psmouse *psmouse, void *data, co
serio_pin_driver_uninterruptible(serio);
down(&psmouse_sem);
- if (serio->drv != &psmouse_drv)
+ if (serio->drv != &psmouse_drv) {
+ input_free_device(new_dev);
return -ENODEV;
+ }
- if (psmouse->type == proto->type)
+ if (psmouse->type == proto->type) {
+ input_free_device(new_dev);
return count; /* switched by other thread */
+ }
}
if (serio->parent && serio->id.type == SERIO_PS_PSTHRU) {
@@ -1199,8 +1206,9 @@ static ssize_t psmouse_attr_set_protocol(struct psmouse *psmouse, void *data, co
psmouse->disconnect(psmouse);
psmouse_set_state(psmouse, PSMOUSE_IGNORE);
- input_unregister_device(&psmouse->dev);
+ input_unregister_device(psmouse->dev);
+ psmouse->dev = new_dev;
psmouse_set_state(psmouse, PSMOUSE_INITIALIZING);
if (psmouse_switch_protocol(psmouse, proto) < 0) {
@@ -1212,8 +1220,7 @@ static ssize_t psmouse_attr_set_protocol(struct psmouse *psmouse, void *data, co
psmouse_initialize(psmouse);
psmouse_set_state(psmouse, PSMOUSE_CMD_MODE);
- input_register_device(&psmouse->dev);
- printk(KERN_INFO "input: %s on %s\n", psmouse->devname, serio->phys);
+ input_register_device(psmouse->dev);
if (parent && parent->pt_activate)
parent->pt_activate(parent);
diff --git a/drivers/input/mouse/psmouse.h b/drivers/input/mouse/psmouse.h
index 45d2bd774f00..7c4192bd1279 100644
--- a/drivers/input/mouse/psmouse.h
+++ b/drivers/input/mouse/psmouse.h
@@ -36,7 +36,7 @@ typedef enum {
struct psmouse {
void *private;
- struct input_dev dev;
+ struct input_dev *dev;
struct ps2dev ps2dev;
char *vendor;
char *name;
diff --git a/drivers/input/mouse/rpcmouse.c b/drivers/input/mouse/rpcmouse.c
index 8fe1212b8fd7..09b6ffdb7582 100644
--- a/drivers/input/mouse/rpcmouse.c
+++ b/drivers/input/mouse/rpcmouse.c
@@ -34,20 +34,7 @@ MODULE_DESCRIPTION("Acorn RiscPC mouse driver");
MODULE_LICENSE("GPL");
static short rpcmouse_lastx, rpcmouse_lasty;
-
-static struct input_dev rpcmouse_dev = {
- .evbit = { BIT(EV_KEY) | BIT(EV_REL) },
- .keybit = { [LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT) },
- .relbit = { BIT(REL_X) | BIT(REL_Y) },
- .name = "Acorn RiscPC Mouse",
- .phys = "rpcmouse/input0",
- .id = {
- .bustype = BUS_HOST,
- .vendor = 0x0005,
- .product = 0x0001,
- .version = 0x0100,
- },
-};
+static struct input_dev *rpcmouse_dev;
static irqreturn_t rpcmouse_irq(int irq, void *dev_id, struct pt_regs *regs)
{
@@ -78,29 +65,41 @@ static irqreturn_t rpcmouse_irq(int irq, void *dev_id, struct pt_regs *regs)
return IRQ_HANDLED;
}
+
static int __init rpcmouse_init(void)
{
- init_input_dev(&rpcmouse_dev);
+ if (!(rpcmouse_dev = input_allocate_device()))
+ return -ENOMEM;
+
+ rpcmouse_dev->name = "Acorn RiscPC Mouse";
+ rpcmouse_dev->phys = "rpcmouse/input0";
+ rpcmouse_dev->id.bustype = BUS_HOST;
+ rpcmouse_dev->id.vendor = 0x0005;
+ rpcmouse_dev->id.product = 0x0001;
+ rpcmouse_dev->id.version = 0x0100;
+
+ rpcmouse_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
+ rpcmouse_dev->keybit[LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
+ rpcmouse_dev->relbit[0] = BIT(REL_X) | BIT(REL_Y);
rpcmouse_lastx = (short) iomd_readl(IOMD_MOUSEX);
rpcmouse_lasty = (short) iomd_readl(IOMD_MOUSEY);
- if (request_irq(IRQ_VSYNCPULSE, rpcmouse_irq, SA_SHIRQ, "rpcmouse", &rpcmouse_dev)) {
+ if (request_irq(IRQ_VSYNCPULSE, rpcmouse_irq, SA_SHIRQ, "rpcmouse", rpcmouse_dev)) {
printk(KERN_ERR "rpcmouse: unable to allocate VSYNC interrupt\n");
- return -1;
+ input_free_device(rpcmouse_dev);
+ return -EBUSY;
}
- input_register_device(&rpcmouse_dev);
-
- printk(KERN_INFO "input: Acorn RiscPC mouse\n");
+ input_register_device(rpcmouse_dev);
return 0;
}
static void __exit rpcmouse_exit(void)
{
- input_unregister_device(&rpcmouse_dev);
- free_irq(IRQ_VSYNCPULSE, &rpcmouse_dev);
+ free_irq(IRQ_VSYNCPULSE, rpcmouse_dev);
+ input_unregister_device(rpcmouse_dev);
}
module_init(rpcmouse_init);
diff --git a/drivers/input/mouse/sermouse.c b/drivers/input/mouse/sermouse.c
index d12b93ae3900..4bf584364d28 100644
--- a/drivers/input/mouse/sermouse.c
+++ b/drivers/input/mouse/sermouse.c
@@ -48,7 +48,7 @@ static char *sermouse_protocols[] = { "None", "Mouse Systems Mouse", "Sun Mouse"
"Logitech MZ++ Mouse"};
struct sermouse {
- struct input_dev dev;
+ struct input_dev *dev;
signed char buf[8];
unsigned char count;
unsigned char type;
@@ -64,7 +64,7 @@ struct sermouse {
static void sermouse_process_msc(struct sermouse *sermouse, signed char data, struct pt_regs *regs)
{
- struct input_dev *dev = &sermouse->dev;
+ struct input_dev *dev = sermouse->dev;
signed char *buf = sermouse->buf;
input_regs(dev, regs);
@@ -107,7 +107,7 @@ static void sermouse_process_msc(struct sermouse *sermouse, signed char data, st
static void sermouse_process_ms(struct sermouse *sermouse, signed char data, struct pt_regs *regs)
{
- struct input_dev *dev = &sermouse->dev;
+ struct input_dev *dev = sermouse->dev;
signed char *buf = sermouse->buf;
if (data & 0x40) sermouse->count = 0;
@@ -230,9 +230,9 @@ static void sermouse_disconnect(struct serio *serio)
{
struct sermouse *sermouse = serio_get_drvdata(serio);
- input_unregister_device(&sermouse->dev);
serio_close(serio);
serio_set_drvdata(serio, NULL);
+ input_unregister_device(sermouse->dev);
kfree(sermouse);
}
@@ -244,56 +244,52 @@ static void sermouse_disconnect(struct serio *serio)
static int sermouse_connect(struct serio *serio, struct serio_driver *drv)
{
struct sermouse *sermouse;
- unsigned char c;
- int err;
+ struct input_dev *input_dev;
+ unsigned char c = serio->id.extra;
+ int err = -ENOMEM;
- if (!serio->id.proto || serio->id.proto > SERIO_MZPP)
- return -ENODEV;
-
- if (!(sermouse = kmalloc(sizeof(struct sermouse), GFP_KERNEL)))
- return -ENOMEM;
-
- memset(sermouse, 0, sizeof(struct sermouse));
-
- init_input_dev(&sermouse->dev);
- sermouse->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
- sermouse->dev.keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT);
- sermouse->dev.relbit[0] = BIT(REL_X) | BIT(REL_Y);
- sermouse->dev.private = sermouse;
-
- sermouse->type = serio->id.proto;
- c = serio->id.extra;
-
- if (c & 0x01) set_bit(BTN_MIDDLE, sermouse->dev.keybit);
- if (c & 0x02) set_bit(BTN_SIDE, sermouse->dev.keybit);
- if (c & 0x04) set_bit(BTN_EXTRA, sermouse->dev.keybit);
- if (c & 0x10) set_bit(REL_WHEEL, sermouse->dev.relbit);
- if (c & 0x20) set_bit(REL_HWHEEL, sermouse->dev.relbit);
+ sermouse = kzalloc(sizeof(struct sermouse), GFP_KERNEL);
+ input_dev = input_allocate_device();
+ if (!sermouse || !input_dev)
+ goto fail;
+ sermouse->dev = input_dev;
sprintf(sermouse->phys, "%s/input0", serio->phys);
+ sermouse->type = serio->id.proto;
- sermouse->dev.name = sermouse_protocols[sermouse->type];
- sermouse->dev.phys = sermouse->phys;
- sermouse->dev.id.bustype = BUS_RS232;
- sermouse->dev.id.vendor = sermouse->type;
- sermouse->dev.id.product = c;
- sermouse->dev.id.version = 0x0100;
- sermouse->dev.dev = &serio->dev;
+ input_dev->name = sermouse_protocols[sermouse->type];
+ input_dev->phys = sermouse->phys;
+ input_dev->id.bustype = BUS_RS232;
+ input_dev->id.vendor = sermouse->type;
+ input_dev->id.product = c;
+ input_dev->id.version = 0x0100;
+ input_dev->cdev.dev = &serio->dev;
+
+ input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
+ input_dev->keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT);
+ input_dev->relbit[0] = BIT(REL_X) | BIT(REL_Y);
+ input_dev->private = sermouse;
+
+ if (c & 0x01) set_bit(BTN_MIDDLE, input_dev->keybit);
+ if (c & 0x02) set_bit(BTN_SIDE, input_dev->keybit);
+ if (c & 0x04) set_bit(BTN_EXTRA, input_dev->keybit);
+ if (c & 0x10) set_bit(REL_WHEEL, input_dev->relbit);
+ if (c & 0x20) set_bit(REL_HWHEEL, input_dev->relbit);
serio_set_drvdata(serio, sermouse);
err = serio_open(serio, drv);
- if (err) {
- serio_set_drvdata(serio, NULL);
- kfree(sermouse);
- return err;
- }
-
- input_register_device(&sermouse->dev);
+ if (err)
+ goto fail;
- printk(KERN_INFO "input: %s on %s\n", sermouse_protocols[sermouse->type], serio->phys);
+ input_register_device(sermouse->dev);
return 0;
+
+ fail: serio_set_drvdata(serio, NULL);
+ input_free_device(input_dev);
+ kfree(sermouse);
+ return err;
}
static struct serio_device_id sermouse_serio_ids[] = {
diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c
index 029309422409..97cdfd6acaca 100644
--- a/drivers/input/mouse/synaptics.c
+++ b/drivers/input/mouse/synaptics.c
@@ -342,7 +342,7 @@ static void synaptics_parse_hw_state(unsigned char buf[], struct synaptics_data
*/
static void synaptics_process_packet(struct psmouse *psmouse)
{
- struct input_dev *dev = &psmouse->dev;
+ struct input_dev *dev = psmouse->dev;
struct synaptics_data *priv = psmouse->private;
struct synaptics_hw_state hw;
int num_fingers;
@@ -473,7 +473,7 @@ static unsigned char synaptics_detect_pkt_type(struct psmouse *psmouse)
static psmouse_ret_t synaptics_process_byte(struct psmouse *psmouse, struct pt_regs *regs)
{
- struct input_dev *dev = &psmouse->dev;
+ struct input_dev *dev = psmouse->dev;
struct synaptics_data *priv = psmouse->private;
input_regs(dev, regs);
@@ -645,7 +645,7 @@ int synaptics_init(struct psmouse *psmouse)
SYN_ID_MAJOR(priv->identity), SYN_ID_MINOR(priv->identity),
priv->model_id, priv->capabilities, priv->ext_cap);
- set_input_params(&psmouse->dev, priv);
+ set_input_params(psmouse->dev, priv);
psmouse->protocol_handler = synaptics_process_byte;
psmouse->set_rate = synaptics_set_rate;
diff --git a/drivers/input/mouse/vsxxxaa.c b/drivers/input/mouse/vsxxxaa.c
index f024be9b44d2..36e9442a16b2 100644
--- a/drivers/input/mouse/vsxxxaa.c
+++ b/drivers/input/mouse/vsxxxaa.c
@@ -112,7 +112,7 @@ MODULE_LICENSE ("GPL");
struct vsxxxaa {
- struct input_dev dev;
+ struct input_dev *dev;
struct serio *serio;
#define BUFLEN 15 /* At least 5 is needed for a full tablet packet */
unsigned char buf[BUFLEN];
@@ -211,7 +211,7 @@ vsxxxaa_smells_like_packet (struct vsxxxaa *mouse, unsigned char type, size_t le
static void
vsxxxaa_handle_REL_packet (struct vsxxxaa *mouse, struct pt_regs *regs)
{
- struct input_dev *dev = &mouse->dev;
+ struct input_dev *dev = mouse->dev;
unsigned char *buf = mouse->buf;
int left, middle, right;
int dx, dy;
@@ -269,7 +269,7 @@ vsxxxaa_handle_REL_packet (struct vsxxxaa *mouse, struct pt_regs *regs)
static void
vsxxxaa_handle_ABS_packet (struct vsxxxaa *mouse, struct pt_regs *regs)
{
- struct input_dev *dev = &mouse->dev;
+ struct input_dev *dev = mouse->dev;
unsigned char *buf = mouse->buf;
int left, middle, right, touch;
int x, y;
@@ -323,7 +323,7 @@ vsxxxaa_handle_ABS_packet (struct vsxxxaa *mouse, struct pt_regs *regs)
static void
vsxxxaa_handle_POR_packet (struct vsxxxaa *mouse, struct pt_regs *regs)
{
- struct input_dev *dev = &mouse->dev;
+ struct input_dev *dev = mouse->dev;
unsigned char *buf = mouse->buf;
int left, middle, right;
unsigned char error;
@@ -483,9 +483,9 @@ vsxxxaa_disconnect (struct serio *serio)
{
struct vsxxxaa *mouse = serio_get_drvdata (serio);
- input_unregister_device (&mouse->dev);
serio_close (serio);
serio_set_drvdata (serio, NULL);
+ input_unregister_device (mouse->dev);
kfree (mouse);
}
@@ -493,61 +493,57 @@ static int
vsxxxaa_connect (struct serio *serio, struct serio_driver *drv)
{
struct vsxxxaa *mouse;
- int err;
+ struct input_dev *input_dev;
+ int err = -ENOMEM;
- if (!(mouse = kmalloc (sizeof (struct vsxxxaa), GFP_KERNEL)))
- return -ENOMEM;
-
- memset (mouse, 0, sizeof (struct vsxxxaa));
-
- init_input_dev (&mouse->dev);
- set_bit (EV_KEY, mouse->dev.evbit); /* We have buttons */
- set_bit (EV_REL, mouse->dev.evbit);
- set_bit (EV_ABS, mouse->dev.evbit);
- set_bit (BTN_LEFT, mouse->dev.keybit); /* We have 3 buttons */
- set_bit (BTN_MIDDLE, mouse->dev.keybit);
- set_bit (BTN_RIGHT, mouse->dev.keybit);
- set_bit (BTN_TOUCH, mouse->dev.keybit); /* ...and Tablet */
- set_bit (REL_X, mouse->dev.relbit);
- set_bit (REL_Y, mouse->dev.relbit);
- set_bit (ABS_X, mouse->dev.absbit);
- set_bit (ABS_Y, mouse->dev.absbit);
-
- mouse->dev.absmin[ABS_X] = 0;
- mouse->dev.absmax[ABS_X] = 1023;
- mouse->dev.absmin[ABS_Y] = 0;
- mouse->dev.absmax[ABS_Y] = 1023;
-
- mouse->dev.private = mouse;
+ mouse = kzalloc (sizeof (struct vsxxxaa), GFP_KERNEL);
+ input_dev = input_allocate_device ();
+ if (!mouse || !input_dev)
+ goto fail;
+ mouse->dev = input_dev;
+ mouse->serio = serio;
sprintf (mouse->name, "DEC VSXXX-AA/-GA mouse or VSXXX-AB digitizer");
sprintf (mouse->phys, "%s/input0", serio->phys);
- mouse->dev.name = mouse->name;
- mouse->dev.phys = mouse->phys;
- mouse->dev.id.bustype = BUS_RS232;
- mouse->dev.dev = &serio->dev;
- mouse->serio = serio;
+
+ input_dev->name = mouse->name;
+ input_dev->phys = mouse->phys;
+ input_dev->id.bustype = BUS_RS232;
+ input_dev->cdev.dev = &serio->dev;
+ input_dev->private = mouse;
+
+ set_bit (EV_KEY, input_dev->evbit); /* We have buttons */
+ set_bit (EV_REL, input_dev->evbit);
+ set_bit (EV_ABS, input_dev->evbit);
+ set_bit (BTN_LEFT, input_dev->keybit); /* We have 3 buttons */
+ set_bit (BTN_MIDDLE, input_dev->keybit);
+ set_bit (BTN_RIGHT, input_dev->keybit);
+ set_bit (BTN_TOUCH, input_dev->keybit); /* ...and Tablet */
+ set_bit (REL_X, input_dev->relbit);
+ set_bit (REL_Y, input_dev->relbit);
+ input_set_abs_params (input_dev, ABS_X, 0, 1023, 0, 0);
+ input_set_abs_params (input_dev, ABS_Y, 0, 1023, 0, 0);
serio_set_drvdata (serio, mouse);
err = serio_open (serio, drv);
- if (err) {
- serio_set_drvdata (serio, NULL);
- kfree (mouse);
- return err;
- }
+ if (err)
+ goto fail;
/*
* Request selftest. Standard packet format and differential
* mode will be requested after the device ID'ed successfully.
*/
- mouse->serio->write (mouse->serio, 'T'); /* Test */
-
- input_register_device (&mouse->dev);
+ serio->write (serio, 'T'); /* Test */
- printk (KERN_INFO "input: %s on %s\n", mouse->name, mouse->phys);
+ input_register_device (input_dev);
return 0;
+
+ fail: serio_set_drvdata (serio, NULL);
+ input_free_device (input_dev);
+ kfree (mouse);
+ return err;
}
static struct serio_device_id vsxxaa_serio_ids[] = {
diff --git a/drivers/input/mousedev.c b/drivers/input/mousedev.c
index c6194a9dd174..2d0af44ac4b9 100644
--- a/drivers/input/mousedev.c
+++ b/drivers/input/mousedev.c
@@ -9,7 +9,7 @@
* the Free Software Foundation.
*/
-#define MOUSEDEV_MINOR_BASE 32
+#define MOUSEDEV_MINOR_BASE 32
#define MOUSEDEV_MINORS 32
#define MOUSEDEV_MIX 31
@@ -24,7 +24,6 @@
#include <linux/random.h>
#include <linux/major.h>
#include <linux/device.h>
-#include <linux/devfs_fs_kernel.h>
#ifdef CONFIG_INPUT_MOUSEDEV_PSAUX
#include <linux/miscdevice.h>
#endif
@@ -621,6 +620,7 @@ static struct file_operations mousedev_fops = {
static struct input_handle *mousedev_connect(struct input_handler *handler, struct input_dev *dev, struct input_device_id *id)
{
struct mousedev *mousedev;
+ struct class_device *cdev;
int minor = 0;
for (minor = 0; minor < MOUSEDEV_MINORS && mousedev_table[minor]; minor++);
@@ -649,11 +649,13 @@ static struct input_handle *mousedev_connect(struct input_handler *handler, stru
mousedev_table[minor] = mousedev;
- devfs_mk_cdev(MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + minor),
- S_IFCHR|S_IRUGO|S_IWUSR, "input/mouse%d", minor);
- class_device_create(input_class,
+ cdev = class_device_create(&input_class, &dev->cdev,
MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + minor),
- dev->dev, "mouse%d", minor);
+ dev->cdev.dev, mousedev->name);
+
+ /* temporary symlink to keep userspace happy */
+ sysfs_create_link(&input_class.subsys.kset.kobj, &cdev->kobj,
+ mousedev->name);
return &mousedev->handle;
}
@@ -663,9 +665,9 @@ static void mousedev_disconnect(struct input_handle *handle)
struct mousedev *mousedev = handle->private;
struct mousedev_list *list;
- class_device_destroy(input_class,
+ sysfs_remove_link(&input_class.subsys.kset.kobj, mousedev->name);
+ class_device_destroy(&input_class,
MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + mousedev->minor));
- devfs_remove("input/mouse%d", mousedev->minor);
mousedev->exist = 0;
if (mousedev->open) {
@@ -738,9 +740,7 @@ static int __init mousedev_init(void)
mousedev_mix.exist = 1;
mousedev_mix.minor = MOUSEDEV_MIX;
- devfs_mk_cdev(MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + MOUSEDEV_MIX),
- S_IFCHR|S_IRUGO|S_IWUSR, "input/mice");
- class_device_create(input_class,
+ class_device_create(&input_class, NULL,
MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + MOUSEDEV_MIX), NULL, "mice");
#ifdef CONFIG_INPUT_MOUSEDEV_PSAUX
@@ -759,8 +759,7 @@ static void __exit mousedev_exit(void)
if (psaux_registered)
misc_deregister(&psaux_mouse);
#endif
- devfs_remove("input/mice");
- class_device_destroy(input_class,
+ class_device_destroy(&input_class,
MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + MOUSEDEV_MIX));
input_unregister_handler(&mousedev_handler);
}
diff --git a/drivers/input/serio/ct82c710.c b/drivers/input/serio/ct82c710.c
index dd0f5bd90241..4da6c86b5d76 100644
--- a/drivers/input/serio/ct82c710.c
+++ b/drivers/input/serio/ct82c710.c
@@ -37,6 +37,7 @@
#include <linux/serio.h>
#include <linux/errno.h>
#include <linux/err.h>
+#include <linux/platform_device.h>
#include <asm/io.h>
diff --git a/drivers/input/serio/gscps2.c b/drivers/input/serio/gscps2.c
index 897e4c12b642..a7b0de0f92b2 100644
--- a/drivers/input/serio/gscps2.c
+++ b/drivers/input/serio/gscps2.c
@@ -211,9 +211,6 @@ static void gscps2_reset(struct gscps2port *ps2port)
writeb(0xff, addr+GSC_RESET);
gscps2_flush(ps2port);
spin_unlock_irqrestore(&ps2port->lock, flags);
-
- /* enable it */
- gscps2_enable(ps2port, ENABLE);
}
static LIST_HEAD(ps2port_list);
@@ -307,6 +304,9 @@ static int gscps2_open(struct serio *port)
gscps2_reset(ps2port);
+ /* enable it */
+ gscps2_enable(ps2port, ENABLE);
+
gscps2_interrupt(0, NULL, NULL);
return 0;
@@ -331,7 +331,7 @@ static int __init gscps2_probe(struct parisc_device *dev)
{
struct gscps2port *ps2port;
struct serio *serio;
- unsigned long hpa = dev->hpa;
+ unsigned long hpa = dev->hpa.start;
int ret;
if (!dev->irq)
@@ -370,8 +370,6 @@ static int __init gscps2_probe(struct parisc_device *dev)
serio->port_data = ps2port;
serio->dev.parent = &dev->dev;
- list_add_tail(&ps2port->node, &ps2port_list);
-
ret = -EBUSY;
if (request_irq(dev->irq, gscps2_interrupt, SA_SHIRQ, ps2port->port->name, ps2port))
goto fail_miserably;
@@ -396,15 +394,16 @@ static int __init gscps2_probe(struct parisc_device *dev)
serio_register_port(ps2port->port);
+ list_add_tail(&ps2port->node, &ps2port_list);
+
return 0;
fail:
free_irq(dev->irq, ps2port);
fail_miserably:
- list_del(&ps2port->node);
iounmap(ps2port->addr);
- release_mem_region(dev->hpa, GSC_STATUS + 4);
+ release_mem_region(dev->hpa.start, GSC_STATUS + 4);
fail_nomem:
kfree(ps2port);
@@ -444,7 +443,7 @@ static struct parisc_device_id gscps2_device_tbl[] = {
};
static struct parisc_driver parisc_ps2_driver = {
- .name = "GSC PS2",
+ .name = "gsc_ps2",
.id_table = gscps2_device_tbl,
.probe = gscps2_probe,
.remove = gscps2_remove,
diff --git a/drivers/input/serio/hil_mlc.c b/drivers/input/serio/hil_mlc.c
index c243cb6fdfc4..5704204964a3 100644
--- a/drivers/input/serio/hil_mlc.c
+++ b/drivers/input/serio/hil_mlc.c
@@ -801,7 +801,8 @@ static int hil_mlc_serio_open(struct serio *serio) {
struct hil_mlc_serio_map *map;
struct hil_mlc *mlc;
- if (serio->private != NULL) return -EBUSY;
+ if (serio_get_drvdata(serio) != NULL)
+ return -EBUSY;
map = serio->port_data;
if (map == NULL) {
@@ -832,11 +833,18 @@ static void hil_mlc_serio_close(struct serio *serio) {
return;
}
- serio->private = NULL;
+ serio_set_drvdata(serio, NULL);
serio->drv = NULL;
/* TODO wake up interruptable */
}
+static struct serio_device_id hil_mlc_serio_id = {
+ .type = SERIO_HIL_MLC,
+ .proto = SERIO_HIL,
+ .extra = SERIO_ANY,
+ .id = SERIO_ANY,
+};
+
int hil_mlc_register(hil_mlc *mlc) {
int i;
unsigned long flags;
@@ -867,7 +875,7 @@ int hil_mlc_register(hil_mlc *mlc) {
mlc_serio = kmalloc(sizeof(*mlc_serio), GFP_KERNEL);
mlc->serio[i] = mlc_serio;
memset(mlc_serio, 0, sizeof(*mlc_serio));
- mlc_serio->type = SERIO_HIL | SERIO_HIL_MLC;
+ mlc_serio->id = hil_mlc_serio_id;
mlc_serio->write = hil_mlc_serio_write;
mlc_serio->open = hil_mlc_serio_open;
mlc_serio->close = hil_mlc_serio_close;
diff --git a/drivers/input/serio/hp_sdc.c b/drivers/input/serio/hp_sdc.c
index 7629452dd64b..a10348bb25e9 100644
--- a/drivers/input/serio/hp_sdc.c
+++ b/drivers/input/serio/hp_sdc.c
@@ -764,7 +764,7 @@ MODULE_DEVICE_TABLE(parisc, hp_sdc_tbl);
static int __init hp_sdc_init_hppa(struct parisc_device *d);
static struct parisc_driver hp_sdc_driver = {
- .name = "HP SDC",
+ .name = "hp_sdc",
.id_table = hp_sdc_tbl,
.probe = hp_sdc_init_hppa,
};
@@ -875,9 +875,9 @@ static int __init hp_sdc_init_hppa(struct parisc_device *d)
hp_sdc.dev = d;
hp_sdc.irq = d->irq;
hp_sdc.nmi = d->aux_irq;
- hp_sdc.base_io = d->hpa;
- hp_sdc.data_io = d->hpa + 0x800;
- hp_sdc.status_io = d->hpa + 0x801;
+ hp_sdc.base_io = d->hpa.start;
+ hp_sdc.data_io = d->hpa.start + 0x800;
+ hp_sdc.status_io = d->hpa.start + 0x801;
return hp_sdc_init();
}
diff --git a/drivers/input/serio/hp_sdc_mlc.c b/drivers/input/serio/hp_sdc_mlc.c
index e3c44ffae674..1c9426fd5205 100644
--- a/drivers/input/serio/hp_sdc_mlc.c
+++ b/drivers/input/serio/hp_sdc_mlc.c
@@ -40,6 +40,7 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/string.h>
+#include <asm/semaphore.h>
#define PREFIX "HP SDC MLC: "
diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c
index 40d451ce07ff..01e186422021 100644
--- a/drivers/input/serio/i8042.c
+++ b/drivers/input/serio/i8042.c
@@ -20,6 +20,7 @@
#include <linux/serio.h>
#include <linux/err.h>
#include <linux/rcupdate.h>
+#include <linux/platform_device.h>
#include <asm/io.h>
@@ -911,12 +912,10 @@ static long i8042_panic_blink(long count)
* Here we try to restore the original BIOS settings
*/
-static int i8042_suspend(struct device *dev, pm_message_t state, u32 level)
+static int i8042_suspend(struct device *dev, pm_message_t state)
{
- if (level == SUSPEND_DISABLE) {
- del_timer_sync(&i8042_timer);
- i8042_controller_reset();
- }
+ del_timer_sync(&i8042_timer);
+ i8042_controller_reset();
return 0;
}
@@ -926,13 +925,10 @@ static int i8042_suspend(struct device *dev, pm_message_t state, u32 level)
* Here we try to reset everything back to a state in which suspended
*/
-static int i8042_resume(struct device *dev, u32 level)
+static int i8042_resume(struct device *dev)
{
int i;
- if (level != RESUME_ENABLE)
- return 0;
-
if (i8042_ctl_test())
return -1;
diff --git a/drivers/input/serio/maceps2.c b/drivers/input/serio/maceps2.c
index 9880fc145d90..d857f7081adb 100644
--- a/drivers/input/serio/maceps2.c
+++ b/drivers/input/serio/maceps2.c
@@ -14,7 +14,7 @@
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <linux/delay.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/err.h>
diff --git a/drivers/input/serio/q40kbd.c b/drivers/input/serio/q40kbd.c
index 46093c507988..b44d255596c2 100644
--- a/drivers/input/serio/q40kbd.c
+++ b/drivers/input/serio/q40kbd.c
@@ -37,6 +37,7 @@
#include <linux/interrupt.h>
#include <linux/err.h>
#include <linux/bitops.h>
+#include <linux/platform_device.h>
#include <asm/io.h>
#include <asm/uaccess.h>
diff --git a/drivers/input/serio/rpckbd.c b/drivers/input/serio/rpckbd.c
index 106f5eefd89a..52c49258f8a4 100644
--- a/drivers/input/serio/rpckbd.c
+++ b/drivers/input/serio/rpckbd.c
@@ -34,6 +34,7 @@
#include <linux/init.h>
#include <linux/serio.h>
#include <linux/err.h>
+#include <linux/platform_device.h>
#include <asm/irq.h>
#include <asm/hardware.h>
diff --git a/drivers/input/touchscreen/corgi_ts.c b/drivers/input/touchscreen/corgi_ts.c
index 4c7fbe550365..15e88eeae8d6 100644
--- a/drivers/input/touchscreen/corgi_ts.c
+++ b/drivers/input/touchscreen/corgi_ts.c
@@ -11,7 +11,7 @@
#include <linux/delay.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <linux/init.h>
#include <linux/input.h>
#include <linux/interrupt.h>
@@ -41,8 +41,7 @@ struct ts_event {
};
struct corgi_ts {
- char phys[32];
- struct input_dev input;
+ struct input_dev *input;
struct timer_list timer;
struct ts_event tc;
int pendown;
@@ -182,14 +181,12 @@ static void new_data(struct corgi_ts *corgi_ts, struct pt_regs *regs)
if (!corgi_ts->tc.pressure && corgi_ts->pendown == 0)
return;
- if (regs)
- input_regs(&corgi_ts->input, regs);
-
- input_report_abs(&corgi_ts->input, ABS_X, corgi_ts->tc.x);
- input_report_abs(&corgi_ts->input, ABS_Y, corgi_ts->tc.y);
- input_report_abs(&corgi_ts->input, ABS_PRESSURE, corgi_ts->tc.pressure);
- input_report_key(&corgi_ts->input, BTN_TOUCH, (corgi_ts->pendown != 0));
- input_sync(&corgi_ts->input);
+ input_regs(corgi_ts->input, regs);
+ input_report_abs(corgi_ts->input, ABS_X, corgi_ts->tc.x);
+ input_report_abs(corgi_ts->input, ABS_Y, corgi_ts->tc.y);
+ input_report_abs(corgi_ts->input, ABS_PRESSURE, corgi_ts->tc.pressure);
+ input_report_key(corgi_ts->input, BTN_TOUCH, (corgi_ts->pendown != 0));
+ input_sync(corgi_ts->input);
}
static void ts_interrupt_main(struct corgi_ts *corgi_ts, int isTimer, struct pt_regs *regs)
@@ -234,34 +231,32 @@ static irqreturn_t ts_interrupt(int irq, void *dev_id, struct pt_regs *regs)
}
#ifdef CONFIG_PM
-static int corgits_suspend(struct device *dev, pm_message_t state, uint32_t level)
+static int corgits_suspend(struct device *dev, pm_message_t state)
{
- if (level == SUSPEND_POWER_DOWN) {
- struct corgi_ts *corgi_ts = dev_get_drvdata(dev);
-
- if (corgi_ts->pendown) {
- del_timer_sync(&corgi_ts->timer);
- corgi_ts->tc.pressure = 0;
- new_data(corgi_ts, NULL);
- corgi_ts->pendown = 0;
- }
- corgi_ts->power_mode = PWR_MODE_SUSPEND;
+ struct corgi_ts *corgi_ts = dev_get_drvdata(dev);
- corgi_ssp_ads7846_putget((1u << ADSCTRL_ADR_SH) | ADSCTRL_STS);
+ if (corgi_ts->pendown) {
+ del_timer_sync(&corgi_ts->timer);
+ corgi_ts->tc.pressure = 0;
+ new_data(corgi_ts, NULL);
+ corgi_ts->pendown = 0;
}
+ corgi_ts->power_mode = PWR_MODE_SUSPEND;
+
+ corgi_ssp_ads7846_putget((1u << ADSCTRL_ADR_SH) | ADSCTRL_STS);
+
return 0;
}
-static int corgits_resume(struct device *dev, uint32_t level)
+static int corgits_resume(struct device *dev)
{
- if (level == RESUME_POWER_ON) {
- struct corgi_ts *corgi_ts = dev_get_drvdata(dev);
+ struct corgi_ts *corgi_ts = dev_get_drvdata(dev);
+
+ corgi_ssp_ads7846_putget((4u << ADSCTRL_ADR_SH) | ADSCTRL_STS);
+ /* Enable Falling Edge */
+ set_irq_type(corgi_ts->irq_gpio, IRQT_FALLING);
+ corgi_ts->power_mode = PWR_MODE_ACTIVE;
- corgi_ssp_ads7846_putget((4u << ADSCTRL_ADR_SH) | ADSCTRL_STS);
- /* Enable Falling Edge */
- set_irq_type(corgi_ts->irq_gpio, IRQT_FALLING);
- corgi_ts->power_mode = PWR_MODE_ACTIVE;
- }
return 0;
}
#else
@@ -273,39 +268,44 @@ static int __init corgits_probe(struct device *dev)
{
struct corgi_ts *corgi_ts;
struct platform_device *pdev = to_platform_device(dev);
+ struct input_dev *input_dev;
+ int err = -ENOMEM;
- if (!(corgi_ts = kmalloc(sizeof(struct corgi_ts), GFP_KERNEL)))
- return -ENOMEM;
+ corgi_ts = kzalloc(sizeof(struct corgi_ts), GFP_KERNEL);
+ input_dev = input_allocate_device();
+ if (!corgi_ts || !input_dev)
+ goto fail;
dev_set_drvdata(dev, corgi_ts);
- memset(corgi_ts, 0, sizeof(struct corgi_ts));
-
corgi_ts->machinfo = dev->platform_data;
corgi_ts->irq_gpio = platform_get_irq(pdev, 0);
if (corgi_ts->irq_gpio < 0) {
- kfree(corgi_ts);
- return -ENODEV;
+ err = -ENODEV;
+ goto fail;
}
- init_input_dev(&corgi_ts->input);
- corgi_ts->input.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
- corgi_ts->input.keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
- input_set_abs_params(&corgi_ts->input, ABS_X, X_AXIS_MIN, X_AXIS_MAX, 0, 0);
- input_set_abs_params(&corgi_ts->input, ABS_Y, Y_AXIS_MIN, Y_AXIS_MAX, 0, 0);
- input_set_abs_params(&corgi_ts->input, ABS_PRESSURE, PRESSURE_MIN, PRESSURE_MAX, 0, 0);
+ corgi_ts->input = input_dev;
- strcpy(corgi_ts->phys, "corgits/input0");
+ init_timer(&corgi_ts->timer);
+ corgi_ts->timer.data = (unsigned long) corgi_ts;
+ corgi_ts->timer.function = corgi_ts_timer;
- corgi_ts->input.private = corgi_ts;
- corgi_ts->input.name = "Corgi Touchscreen";
- corgi_ts->input.dev = dev;
- corgi_ts->input.phys = corgi_ts->phys;
- corgi_ts->input.id.bustype = BUS_HOST;
- corgi_ts->input.id.vendor = 0x0001;
- corgi_ts->input.id.product = 0x0002;
- corgi_ts->input.id.version = 0x0100;
+ input_dev->name = "Corgi Touchscreen";
+ input_dev->phys = "corgits/input0";
+ input_dev->id.bustype = BUS_HOST;
+ input_dev->id.vendor = 0x0001;
+ input_dev->id.product = 0x0002;
+ input_dev->id.version = 0x0100;
+ input_dev->cdev.dev = dev;
+ input_dev->private = corgi_ts;
+
+ input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+ input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
+ input_set_abs_params(input_dev, ABS_X, X_AXIS_MIN, X_AXIS_MAX, 0, 0);
+ input_set_abs_params(input_dev, ABS_Y, Y_AXIS_MIN, Y_AXIS_MAX, 0, 0);
+ input_set_abs_params(input_dev, ABS_PRESSURE, PRESSURE_MIN, PRESSURE_MAX, 0, 0);
pxa_gpio_mode(IRQ_TO_GPIO(corgi_ts->irq_gpio) | GPIO_IN);
@@ -319,25 +319,24 @@ static int __init corgits_probe(struct device *dev)
corgi_ssp_ads7846_putget((5u << ADSCTRL_ADR_SH) | ADSCTRL_STS);
mdelay(5);
- init_timer(&corgi_ts->timer);
- corgi_ts->timer.data = (unsigned long) corgi_ts;
- corgi_ts->timer.function = corgi_ts_timer;
-
- input_register_device(&corgi_ts->input);
- corgi_ts->power_mode = PWR_MODE_ACTIVE;
-
if (request_irq(corgi_ts->irq_gpio, ts_interrupt, SA_INTERRUPT, "ts", corgi_ts)) {
- input_unregister_device(&corgi_ts->input);
- kfree(corgi_ts);
- return -EBUSY;
+ err = -EBUSY;
+ goto fail;
}
+ input_register_device(corgi_ts->input);
+
+ corgi_ts->power_mode = PWR_MODE_ACTIVE;
+
/* Enable Falling Edge */
set_irq_type(corgi_ts->irq_gpio, IRQT_FALLING);
- printk(KERN_INFO "input: Corgi Touchscreen Registered\n");
-
return 0;
+
+ fail: input_free_device(input_dev);
+ kfree(corgi_ts);
+ return err;
+
}
static int corgits_remove(struct device *dev)
@@ -347,7 +346,7 @@ static int corgits_remove(struct device *dev)
free_irq(corgi_ts->irq_gpio, NULL);
del_timer_sync(&corgi_ts->timer);
corgi_ts->machinfo->put_hsync();
- input_unregister_device(&corgi_ts->input);
+ input_unregister_device(corgi_ts->input);
kfree(corgi_ts);
return 0;
}
diff --git a/drivers/input/touchscreen/elo.c b/drivers/input/touchscreen/elo.c
index 3cdc9cab688d..c86a2eb310fd 100644
--- a/drivers/input/touchscreen/elo.c
+++ b/drivers/input/touchscreen/elo.c
@@ -36,14 +36,12 @@ MODULE_LICENSE("GPL");
#define ELO_MAX_LENGTH 10
-static char *elo_name = "Elo Serial TouchScreen";
-
/*
* Per-touchscreen data.
*/
struct elo {
- struct input_dev dev;
+ struct input_dev *dev;
struct serio *serio;
int id;
int idx;
@@ -54,7 +52,7 @@ struct elo {
static void elo_process_data_10(struct elo* elo, unsigned char data, struct pt_regs *regs)
{
- struct input_dev *dev = &elo->dev;
+ struct input_dev *dev = elo->dev;
elo->csum += elo->data[elo->idx] = data;
@@ -80,7 +78,7 @@ static void elo_process_data_10(struct elo* elo, unsigned char data, struct pt_r
input_report_abs(dev, ABS_X, (elo->data[4] << 8) | elo->data[3]);
input_report_abs(dev, ABS_Y, (elo->data[6] << 8) | elo->data[5]);
input_report_abs(dev, ABS_PRESSURE, (elo->data[8] << 8) | elo->data[7]);
- input_report_key(dev, BTN_TOUCH, elo->data[2] & 3);
+ input_report_key(dev, BTN_TOUCH, elo->data[8] || elo->data[7]);
input_sync(dev);
}
elo->idx = 0;
@@ -91,7 +89,7 @@ static void elo_process_data_10(struct elo* elo, unsigned char data, struct pt_r
static void elo_process_data_6(struct elo* elo, unsigned char data, struct pt_regs *regs)
{
- struct input_dev *dev = &elo->dev;
+ struct input_dev *dev = elo->dev;
elo->data[elo->idx] = data;
@@ -129,7 +127,7 @@ static void elo_process_data_6(struct elo* elo, unsigned char data, struct pt_re
case 5:
if ((data & 0xf0) == 0) {
input_report_abs(dev, ABS_PRESSURE, elo->data[5]);
- input_report_key(dev, BTN_TOUCH, elo->data[5]);
+ input_report_key(dev, BTN_TOUCH, !!elo->data[5]);
}
input_sync(dev);
elo->idx = 0;
@@ -139,7 +137,7 @@ static void elo_process_data_6(struct elo* elo, unsigned char data, struct pt_re
static void elo_process_data_3(struct elo* elo, unsigned char data, struct pt_regs *regs)
{
- struct input_dev *dev = &elo->dev;
+ struct input_dev *dev = elo->dev;
elo->data[elo->idx] = data;
@@ -191,7 +189,7 @@ static void elo_disconnect(struct serio *serio)
{
struct elo* elo = serio_get_drvdata(serio);
- input_unregister_device(&elo->dev);
+ input_unregister_device(elo->dev);
serio_close(serio);
serio_set_drvdata(serio, NULL);
kfree(elo);
@@ -206,67 +204,68 @@ static void elo_disconnect(struct serio *serio)
static int elo_connect(struct serio *serio, struct serio_driver *drv)
{
struct elo *elo;
+ struct input_dev *input_dev;
int err;
- if (!(elo = kmalloc(sizeof(struct elo), GFP_KERNEL)))
- return -ENOMEM;
+ elo = kzalloc(sizeof(struct elo), GFP_KERNEL);
+ input_dev = input_allocate_device();
+ if (!elo || !input_dev) {
+ err = -ENOMEM;
+ goto fail;
+ }
- memset(elo, 0, sizeof(struct elo));
+ elo->serio = serio;
+ elo->id = serio->id.id;
+ elo->dev = input_dev;
+ snprintf(elo->phys, sizeof(elo->phys), "%s/input0", serio->phys);
- init_input_dev(&elo->dev);
- elo->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
- elo->dev.keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
+ input_dev->private = elo;
+ input_dev->name = "Elo Serial TouchScreen";
+ input_dev->phys = elo->phys;
+ input_dev->id.bustype = BUS_RS232;
+ input_dev->id.vendor = SERIO_ELO;
+ input_dev->id.product = elo->id;
+ input_dev->id.version = 0x0100;
+ input_dev->cdev.dev = &serio->dev;
- elo->id = serio->id.id;
+ input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+ input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
switch (elo->id) {
case 0: /* 10-byte protocol */
- input_set_abs_params(&elo->dev, ABS_X, 96, 4000, 0, 0);
- input_set_abs_params(&elo->dev, ABS_Y, 96, 4000, 0, 0);
- input_set_abs_params(&elo->dev, ABS_PRESSURE, 0, 255, 0, 0);
+ input_set_abs_params(input_dev, ABS_X, 96, 4000, 0, 0);
+ input_set_abs_params(input_dev, ABS_Y, 96, 4000, 0, 0);
+ input_set_abs_params(input_dev, ABS_PRESSURE, 0, 255, 0, 0);
break;
case 1: /* 6-byte protocol */
- input_set_abs_params(&elo->dev, ABS_PRESSURE, 0, 15, 0, 0);
+ input_set_abs_params(input_dev, ABS_PRESSURE, 0, 15, 0, 0);
case 2: /* 4-byte protocol */
- input_set_abs_params(&elo->dev, ABS_X, 96, 4000, 0, 0);
- input_set_abs_params(&elo->dev, ABS_Y, 96, 4000, 0, 0);
+ input_set_abs_params(input_dev, ABS_X, 96, 4000, 0, 0);
+ input_set_abs_params(input_dev, ABS_Y, 96, 4000, 0, 0);
break;
case 3: /* 3-byte protocol */
- input_set_abs_params(&elo->dev, ABS_X, 0, 255, 0, 0);
- input_set_abs_params(&elo->dev, ABS_Y, 0, 255, 0, 0);
+ input_set_abs_params(input_dev, ABS_X, 0, 255, 0, 0);
+ input_set_abs_params(input_dev, ABS_Y, 0, 255, 0, 0);
break;
}
- elo->serio = serio;
-
- sprintf(elo->phys, "%s/input0", serio->phys);
-
- elo->dev.private = elo;
- elo->dev.name = elo_name;
- elo->dev.phys = elo->phys;
- elo->dev.id.bustype = BUS_RS232;
- elo->dev.id.vendor = SERIO_ELO;
- elo->dev.id.product = elo->id;
- elo->dev.id.version = 0x0100;
-
serio_set_drvdata(serio, elo);
err = serio_open(serio, drv);
- if (err) {
- serio_set_drvdata(serio, NULL);
- kfree(elo);
- return err;
- }
-
- input_register_device(&elo->dev);
-
- printk(KERN_INFO "input: %s on %s\n", elo_name, serio->phys);
+ if (err)
+ goto fail;
+ input_register_device(elo->dev);
return 0;
+
+ fail: serio_set_drvdata(serio, NULL);
+ input_free_device(input_dev);
+ kfree(elo);
+ return err;
}
/*
diff --git a/drivers/input/touchscreen/gunze.c b/drivers/input/touchscreen/gunze.c
index 53a27e43dd23..466da190ceec 100644
--- a/drivers/input/touchscreen/gunze.c
+++ b/drivers/input/touchscreen/gunze.c
@@ -48,14 +48,12 @@ MODULE_LICENSE("GPL");
#define GUNZE_MAX_LENGTH 10
-static char *gunze_name = "Gunze AHL-51S TouchScreen";
-
/*
* Per-touchscreen data.
*/
struct gunze {
- struct input_dev dev;
+ struct input_dev *dev;
struct serio *serio;
int idx;
unsigned char data[GUNZE_MAX_LENGTH];
@@ -64,7 +62,7 @@ struct gunze {
static void gunze_process_packet(struct gunze* gunze, struct pt_regs *regs)
{
- struct input_dev *dev = &gunze->dev;
+ struct input_dev *dev = gunze->dev;
if (gunze->idx != GUNZE_MAX_LENGTH || gunze->data[5] != ',' ||
(gunze->data[0] != 'T' && gunze->data[0] != 'R')) {
@@ -100,11 +98,13 @@ static irqreturn_t gunze_interrupt(struct serio *serio,
static void gunze_disconnect(struct serio *serio)
{
- struct gunze* gunze = serio_get_drvdata(serio);
+ struct gunze *gunze = serio_get_drvdata(serio);
- input_unregister_device(&gunze->dev);
+ input_get_device(gunze->dev);
+ input_unregister_device(gunze->dev);
serio_close(serio);
serio_set_drvdata(serio, NULL);
+ input_put_device(gunze->dev);
kfree(gunze);
}
@@ -117,45 +117,45 @@ static void gunze_disconnect(struct serio *serio)
static int gunze_connect(struct serio *serio, struct serio_driver *drv)
{
struct gunze *gunze;
+ struct input_dev *input_dev;
int err;
- if (!(gunze = kmalloc(sizeof(struct gunze), GFP_KERNEL)))
- return -ENOMEM;
-
- memset(gunze, 0, sizeof(struct gunze));
-
- init_input_dev(&gunze->dev);
- gunze->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
- gunze->dev.keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
- input_set_abs_params(&gunze->dev, ABS_X, 24, 1000, 0, 0);
- input_set_abs_params(&gunze->dev, ABS_Y, 24, 1000, 0, 0);
+ gunze = kzalloc(sizeof(struct gunze), GFP_KERNEL);
+ input_dev = input_allocate_device();
+ if (!gunze || !input_dev) {
+ err = -ENOMEM;
+ goto fail;
+ }
gunze->serio = serio;
-
+ gunze->dev = input_dev;
sprintf(gunze->phys, "%s/input0", serio->phys);
- gunze->dev.private = gunze;
- gunze->dev.name = gunze_name;
- gunze->dev.phys = gunze->phys;
- gunze->dev.id.bustype = BUS_RS232;
- gunze->dev.id.vendor = SERIO_GUNZE;
- gunze->dev.id.product = 0x0051;
- gunze->dev.id.version = 0x0100;
+ input_dev->private = gunze;
+ input_dev->name = "Gunze AHL-51S TouchScreen";
+ input_dev->phys = gunze->phys;
+ input_dev->id.bustype = BUS_RS232;
+ input_dev->id.vendor = SERIO_GUNZE;
+ input_dev->id.product = 0x0051;
+ input_dev->id.version = 0x0100;
+ input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+ input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
+ input_set_abs_params(input_dev, ABS_X, 24, 1000, 0, 0);
+ input_set_abs_params(input_dev, ABS_Y, 24, 1000, 0, 0);
serio_set_drvdata(serio, gunze);
err = serio_open(serio, drv);
- if (err) {
- serio_set_drvdata(serio, NULL);
- kfree(gunze);
- return err;
- }
-
- input_register_device(&gunze->dev);
-
- printk(KERN_INFO "input: %s on %s\n", gunze_name, serio->phys);
+ if (err)
+ goto fail;
+ input_register_device(gunze->dev);
return 0;
+
+ fail: serio_set_drvdata(serio, NULL);
+ input_free_device(input_dev);
+ kfree(gunze);
+ return err;
}
/*
diff --git a/drivers/input/touchscreen/h3600_ts_input.c b/drivers/input/touchscreen/h3600_ts_input.c
index bcfa1e36f957..a18d56bdafd9 100644
--- a/drivers/input/touchscreen/h3600_ts_input.c
+++ b/drivers/input/touchscreen/h3600_ts_input.c
@@ -39,7 +39,6 @@
#include <linux/serio.h>
#include <linux/init.h>
#include <linux/delay.h>
-#include <linux/pm.h>
/* SA1100 serial defines */
#include <asm/arch/hardware.h>
@@ -93,16 +92,12 @@ MODULE_LICENSE("GPL");
#define H3600_SCANCODE_LEFT 8 /* 8 -> left */
#define H3600_SCANCODE_DOWN 9 /* 9 -> down */
-static char *h3600_name = "H3600 TouchScreen";
-
/*
* Per-touchscreen data.
*/
struct h3600_dev {
- struct input_dev dev;
- struct pm_dev *pm_dev;
+ struct input_dev *dev;
struct serio *serio;
- struct pm_dev *pm_dev;
unsigned char event; /* event ID from packet */
unsigned char chksum;
unsigned char len;
@@ -163,33 +158,6 @@ unsigned int h3600_flite_power(struct input_dev *dev, enum flite_pwr pwr)
return 0;
}
-static int suspended = 0;
-static int h3600ts_pm_callback(struct pm_dev *pm_dev, pm_request_t req,
- void *data)
-{
- struct input_dev *dev = (struct input_dev *) data;
-
- switch (req) {
- case PM_SUSPEND: /* enter D1-D3 */
- suspended = 1;
- h3600_flite_power(dev, FLITE_PWR_OFF);
- break;
- case PM_BLANK:
- if (!suspended)
- h3600_flite_power(dev, FLITE_PWR_OFF);
- break;
- case PM_RESUME: /* enter D0 */
- /* same as unblank */
- case PM_UNBLANK:
- if (suspended) {
- //initSerial();
- suspended = 0;
- }
- h3600_flite_power(dev, FLITE_PWR_ON);
- break;
- }
- return 0;
-}
#endif
/*
@@ -199,7 +167,7 @@ static int h3600ts_pm_callback(struct pm_dev *pm_dev, pm_request_t req,
*/
static void h3600ts_process_packet(struct h3600_dev *ts, struct pt_regs *regs)
{
- struct input_dev *dev = &ts->dev;
+ struct input_dev *dev = ts->dev;
static int touched = 0;
int key, down = 0;
@@ -295,6 +263,7 @@ static void h3600ts_process_packet(struct h3600_dev *ts, struct pt_regs *regs)
static int h3600ts_event(struct input_dev *dev, unsigned int type,
unsigned int code, int value)
{
+#if 0
struct h3600_dev *ts = dev->private;
switch (type) {
@@ -304,6 +273,8 @@ static int h3600ts_event(struct input_dev *dev, unsigned int type,
}
}
return -1;
+#endif
+ return 0;
}
/*
@@ -380,14 +351,48 @@ static irqreturn_t h3600ts_interrupt(struct serio *serio, unsigned char data,
static int h3600ts_connect(struct serio *serio, struct serio_driver *drv)
{
struct h3600_dev *ts;
+ struct input_dev *input_dev;
int err;
- if (!(ts = kmalloc(sizeof(struct h3600_dev), GFP_KERNEL)))
- return -ENOMEM;
+ ts = kzalloc(sizeof(struct h3600_dev), GFP_KERNEL);
+ input_dev = input_allocate_device();
+ if (!ts || !input_dev) {
+ err = -ENOMEM;
+ goto fail1;
+ }
- memset(ts, 0, sizeof(struct h3600_dev));
+ ts->serio = serio;
+ ts->dev = input_dev;
+ sprintf(ts->phys, "%s/input0", serio->phys);
- init_input_dev(&ts->dev);
+ input_dev->name = "H3600 TouchScreen";
+ input_dev->phys = ts->phys;
+ input_dev->id.bustype = BUS_RS232;
+ input_dev->id.vendor = SERIO_H3600;
+ input_dev->id.product = 0x0666; /* FIXME !!! We can ask the hardware */
+ input_dev->id.version = 0x0100;
+ input_dev->cdev.dev = &serio->dev;
+ input_dev->private = ts;
+
+ input_dev->event = h3600ts_event;
+
+ input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS) | BIT(EV_LED) | BIT(EV_PWR);
+ input_dev->ledbit[0] = BIT(LED_SLEEP);
+ input_set_abs_params(input_dev, ABS_X, 60, 985, 0, 0);
+ input_set_abs_params(input_dev, ABS_Y, 35, 1024, 0, 0);
+
+ set_bit(KEY_RECORD, input_dev->keybit);
+ set_bit(KEY_Q, input_dev->keybit);
+ set_bit(KEY_PROG1, input_dev->keybit);
+ set_bit(KEY_PROG2, input_dev->keybit);
+ set_bit(KEY_PROG3, input_dev->keybit);
+ set_bit(KEY_UP, input_dev->keybit);
+ set_bit(KEY_RIGHT, input_dev->keybit);
+ set_bit(KEY_LEFT, input_dev->keybit);
+ set_bit(KEY_DOWN, input_dev->keybit);
+ set_bit(KEY_ENTER, input_dev->keybit);
+ set_bit(KEY_SUSPEND, input_dev->keybit);
+ set_bit(BTN_TOUCH, input_dev->keybit);
/* Device specific stuff */
set_GPIO_IRQ_edge(GPIO_BITSY_ACTION_BUTTON, GPIO_BOTH_EDGES);
@@ -397,73 +402,35 @@ static int h3600ts_connect(struct serio *serio, struct serio_driver *drv)
SA_SHIRQ | SA_INTERRUPT | SA_SAMPLE_RANDOM,
"h3600_action", &ts->dev)) {
printk(KERN_ERR "h3600ts.c: Could not allocate Action Button IRQ!\n");
- kfree(ts);
- return -EBUSY;
+ err = -EBUSY;
+ goto fail2;
}
if (request_irq(IRQ_GPIO_BITSY_NPOWER_BUTTON, npower_button_handler,
SA_SHIRQ | SA_INTERRUPT | SA_SAMPLE_RANDOM,
"h3600_suspend", &ts->dev)) {
- free_irq(IRQ_GPIO_BITSY_ACTION_BUTTON, &ts->dev);
printk(KERN_ERR "h3600ts.c: Could not allocate Power Button IRQ!\n");
- kfree(ts);
- return -EBUSY;
+ err = -EBUSY;
+ goto fail3;
}
- /* Now we have things going we setup our input device */
- ts->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS) | BIT(EV_LED) | BIT(EV_PWR);
- ts->dev.ledbit[0] = BIT(LED_SLEEP);
- input_set_abs_params(&ts->dev, ABS_X, 60, 985, 0, 0);
- input_set_abs_params(&ts->dev, ABS_Y, 35, 1024, 0, 0);
-
- set_bit(KEY_RECORD, ts->dev.keybit);
- set_bit(KEY_Q, ts->dev.keybit);
- set_bit(KEY_PROG1, ts->dev.keybit);
- set_bit(KEY_PROG2, ts->dev.keybit);
- set_bit(KEY_PROG3, ts->dev.keybit);
- set_bit(KEY_UP, ts->dev.keybit);
- set_bit(KEY_RIGHT, ts->dev.keybit);
- set_bit(KEY_LEFT, ts->dev.keybit);
- set_bit(KEY_DOWN, ts->dev.keybit);
- set_bit(KEY_ENTER, ts->dev.keybit);
- ts->dev.keybit[LONG(BTN_TOUCH)] |= BIT(BTN_TOUCH);
- ts->dev.keybit[LONG(KEY_SUSPEND)] |= BIT(KEY_SUSPEND);
-
- ts->serio = serio;
-
- sprintf(ts->phys, "%s/input0", serio->phys);
-
- ts->dev.event = h3600ts_event;
- ts->dev.private = ts;
- ts->dev.name = h3600_name;
- ts->dev.phys = ts->phys;
- ts->dev.id.bustype = BUS_RS232;
- ts->dev.id.vendor = SERIO_H3600;
- ts->dev.id.product = 0x0666; /* FIXME !!! We can ask the hardware */
- ts->dev.id.version = 0x0100;
-
serio_set_drvdata(serio, ts);
err = serio_open(serio, drv);
- if (err) {
- free_irq(IRQ_GPIO_BITSY_ACTION_BUTTON, ts);
- free_irq(IRQ_GPIO_BITSY_NPOWER_BUTTON, ts);
- serio_set_drvdata(serio, NULL);
- kfree(ts);
+ if (err)
return err;
- }
//h3600_flite_control(1, 25); /* default brightness */
-#ifdef CONFIG_PM
- ts->pm_dev = pm_register(PM_ILLUMINATION_DEV, PM_SYS_LIGHT,
- h3600ts_pm_callback);
- printk("registered pm callback\n");
-#endif
- input_register_device(&ts->dev);
-
- printk(KERN_INFO "input: %s on %s\n", h3600_name, serio->phys);
+ input_register_device(ts->dev);
return 0;
+
+fail3: free_irq(IRQ_GPIO_BITSY_NPOWER_BUTTON, ts->dev);
+fail2: free_irq(IRQ_GPIO_BITSY_ACTION_BUTTON, ts->dev);
+fail1: serio_set_drvdata(serio, NULL);
+ input_free_device(input_dev);
+ kfree(ts);
+ return err;
}
/*
@@ -476,9 +443,11 @@ static void h3600ts_disconnect(struct serio *serio)
free_irq(IRQ_GPIO_BITSY_ACTION_BUTTON, &ts->dev);
free_irq(IRQ_GPIO_BITSY_NPOWER_BUTTON, &ts->dev);
- input_unregister_device(&ts->dev);
+ input_get_device(ts->dev);
+ input_unregister_device(ts->dev);
serio_close(serio);
serio_set_drvdata(serio, NULL);
+ input_put_device(ts->dev);
kfree(ts);
}
diff --git a/drivers/input/touchscreen/hp680_ts_input.c b/drivers/input/touchscreen/hp680_ts_input.c
index 7e1404441eca..957dd5a1b15e 100644
--- a/drivers/input/touchscreen/hp680_ts_input.c
+++ b/drivers/input/touchscreen/hp680_ts_input.c
@@ -21,10 +21,8 @@
static void do_softint(void *data);
-static struct input_dev hp680_ts_dev;
+static struct input_dev *hp680_ts_dev;
static DECLARE_WORK(work, do_softint, 0);
-static char *hp680_ts_name = "HP Jornada touchscreen";
-static char *hp680_ts_phys = "input0";
static void do_softint(void *data)
{
@@ -58,14 +56,14 @@ static void do_softint(void *data)
}
if (touched) {
- input_report_key(&hp680_ts_dev, BTN_TOUCH, 1);
- input_report_abs(&hp680_ts_dev, ABS_X, absx);
- input_report_abs(&hp680_ts_dev, ABS_Y, absy);
+ input_report_key(hp680_ts_dev, BTN_TOUCH, 1);
+ input_report_abs(hp680_ts_dev, ABS_X, absx);
+ input_report_abs(hp680_ts_dev, ABS_Y, absy);
} else {
- input_report_key(&hp680_ts_dev, BTN_TOUCH, 0);
+ input_report_key(hp680_ts_dev, BTN_TOUCH, 0);
}
- input_sync(&hp680_ts_dev);
+ input_sync(hp680_ts_dev);
enable_irq(HP680_TS_IRQ);
}
@@ -92,27 +90,29 @@ static int __init hp680_ts_init(void)
scpcr |= SCPCR_TS_ENABLE;
ctrl_outw(scpcr, SCPCR);
- memset(&hp680_ts_dev, 0, sizeof(hp680_ts_dev));
- init_input_dev(&hp680_ts_dev);
+ hp680_ts_dev = input_allocate_device();
+ if (!hp680_ts_dev)
+ return -ENOMEM;
- hp680_ts_dev.evbit[0] = BIT(EV_ABS) | BIT(EV_KEY);
- hp680_ts_dev.absbit[0] = BIT(ABS_X) | BIT(ABS_Y);
- hp680_ts_dev.keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
+ hp680_ts_dev->evbit[0] = BIT(EV_ABS) | BIT(EV_KEY);
+ hp680_ts_dev->absbit[0] = BIT(ABS_X) | BIT(ABS_Y);
+ hp680_ts_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
- hp680_ts_dev.absmin[ABS_X] = HP680_TS_ABS_X_MIN;
- hp680_ts_dev.absmin[ABS_Y] = HP680_TS_ABS_Y_MIN;
- hp680_ts_dev.absmax[ABS_X] = HP680_TS_ABS_X_MAX;
- hp680_ts_dev.absmax[ABS_Y] = HP680_TS_ABS_Y_MAX;
+ hp680_ts_dev->absmin[ABS_X] = HP680_TS_ABS_X_MIN;
+ hp680_ts_dev->absmin[ABS_Y] = HP680_TS_ABS_Y_MIN;
+ hp680_ts_dev->absmax[ABS_X] = HP680_TS_ABS_X_MAX;
+ hp680_ts_dev->absmax[ABS_Y] = HP680_TS_ABS_Y_MAX;
- hp680_ts_dev.name = hp680_ts_name;
- hp680_ts_dev.phys = hp680_ts_phys;
- input_register_device(&hp680_ts_dev);
+ hp680_ts_dev->name = "HP Jornada touchscreen";
+ hp680_ts_dev->phys = "hp680_ts/input0";
- if (request_irq
- (HP680_TS_IRQ, hp680_ts_interrupt, SA_INTERRUPT, MODNAME, 0) < 0) {
- printk(KERN_ERR "hp680_touchscreen.c : Can't allocate irq %d\n",
+ input_register_device(hp680_ts_dev);
+
+ if (request_irq(HP680_TS_IRQ, hp680_ts_interrupt,
+ SA_INTERRUPT, MODNAME, 0) < 0) {
+ printk(KERN_ERR "hp680_touchscreen.c: Can't allocate irq %d\n",
HP680_TS_IRQ);
- input_unregister_device(&hp680_ts_dev);
+ input_unregister_device(hp680_ts_dev);
return -EBUSY;
}
@@ -124,7 +124,7 @@ static void __exit hp680_ts_exit(void)
free_irq(HP680_TS_IRQ, 0);
cancel_delayed_work(&work);
flush_scheduled_work();
- input_unregister_device(&hp680_ts_dev);
+ input_unregister_device(hp680_ts_dev);
}
module_init(hp680_ts_init);
diff --git a/drivers/input/touchscreen/mk712.c b/drivers/input/touchscreen/mk712.c
index afaaebe5225b..4844d250a5eb 100644
--- a/drivers/input/touchscreen/mk712.c
+++ b/drivers/input/touchscreen/mk712.c
@@ -77,7 +77,7 @@ MODULE_PARM_DESC(irq, "IRQ of MK712 touchscreen controller");
#define MK712_READ_ONE_POINT 0x20
#define MK712_POWERUP 0x40
-static struct input_dev mk712_dev;
+static struct input_dev *mk712_dev;
static DEFINE_SPINLOCK(mk712_lock);
static irqreturn_t mk712_interrupt(int irq, void *dev_id, struct pt_regs *regs)
@@ -88,7 +88,7 @@ static irqreturn_t mk712_interrupt(int irq, void *dev_id, struct pt_regs *regs)
static unsigned short last_y;
spin_lock(&mk712_lock);
- input_regs(&mk712_dev, regs);
+ input_regs(mk712_dev, regs);
status = inb(mk712_io + MK712_STATUS);
@@ -100,7 +100,7 @@ static irqreturn_t mk712_interrupt(int irq, void *dev_id, struct pt_regs *regs)
if (~status & MK712_STATUS_TOUCH)
{
debounce = 1;
- input_report_key(&mk712_dev, BTN_TOUCH, 0);
+ input_report_key(mk712_dev, BTN_TOUCH, 0);
goto end;
}
@@ -110,15 +110,15 @@ static irqreturn_t mk712_interrupt(int irq, void *dev_id, struct pt_regs *regs)
goto end;
}
- input_report_key(&mk712_dev, BTN_TOUCH, 1);
- input_report_abs(&mk712_dev, ABS_X, last_x);
- input_report_abs(&mk712_dev, ABS_Y, last_y);
+ input_report_key(mk712_dev, BTN_TOUCH, 1);
+ input_report_abs(mk712_dev, ABS_X, last_x);
+ input_report_abs(mk712_dev, ABS_Y, last_y);
end:
last_x = inw(mk712_io + MK712_X) & 0x0fff;
last_y = inw(mk712_io + MK712_Y) & 0x0fff;
- input_sync(&mk712_dev);
+ input_sync(mk712_dev);
spin_unlock(&mk712_lock);
return IRQ_HANDLED;
}
@@ -154,30 +154,11 @@ static void mk712_close(struct input_dev *dev)
spin_unlock_irqrestore(&mk712_lock, flags);
}
-static struct input_dev mk712_dev = {
- .evbit = { BIT(EV_KEY) | BIT(EV_ABS) },
- .keybit = { [LONG(BTN_TOUCH)] = BIT(BTN_TOUCH) },
- .absbit = { BIT(ABS_X) | BIT(ABS_Y) },
- .open = mk712_open,
- .close = mk712_close,
- .name = "ICS MicroClock MK712 TouchScreen",
- .phys = "isa0260/input0",
- .absmin = { [ABS_X] = 0, [ABS_Y] = 0 },
- .absmax = { [ABS_X] = 0xfff, [ABS_Y] = 0xfff },
- .absfuzz = { [ABS_X] = 88, [ABS_Y] = 88 },
- .id = {
- .bustype = BUS_ISA,
- .vendor = 0x0005,
- .product = 0x0001,
- .version = 0x0100,
- },
-};
-
int __init mk712_init(void)
{
+ int err;
- if(!request_region(mk712_io, 8, "mk712"))
- {
+ if (!request_region(mk712_io, 8, "mk712")) {
printk(KERN_WARNING "mk712: unable to get IO region\n");
return -ENODEV;
}
@@ -188,28 +169,49 @@ int __init mk712_init(void)
(inw(mk712_io + MK712_Y) & 0xf000) ||
(inw(mk712_io + MK712_STATUS) & 0xf333)) {
printk(KERN_WARNING "mk712: device not present\n");
- release_region(mk712_io, 8);
- return -ENODEV;
+ err = -ENODEV;
+ goto fail;
}
- if(request_irq(mk712_irq, mk712_interrupt, 0, "mk712", &mk712_dev))
- {
- printk(KERN_WARNING "mk712: unable to get IRQ\n");
- release_region(mk712_io, 8);
- return -EBUSY;
+ if (!(mk712_dev = input_allocate_device())) {
+ printk(KERN_ERR "mk712: not enough memory\n");
+ err = -ENOMEM;
+ goto fail;
}
- input_register_device(&mk712_dev);
+ mk712_dev->name = "ICS MicroClock MK712 TouchScreen";
+ mk712_dev->phys = "isa0260/input0";
+ mk712_dev->id.bustype = BUS_ISA;
+ mk712_dev->id.vendor = 0x0005;
+ mk712_dev->id.product = 0x0001;
+ mk712_dev->id.version = 0x0100;
+
+ mk712_dev->open = mk712_open;
+ mk712_dev->close = mk712_close;
- printk(KERN_INFO "input: ICS MicroClock MK712 TouchScreen at %#x irq %d\n", mk712_io, mk712_irq);
+ mk712_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+ mk712_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
+ input_set_abs_params(mk712_dev, ABS_X, 0, 0xfff, 88, 0);
+ input_set_abs_params(mk712_dev, ABS_Y, 0, 0xfff, 88, 0);
+ if (request_irq(mk712_irq, mk712_interrupt, 0, "mk712", mk712_dev)) {
+ printk(KERN_WARNING "mk712: unable to get IRQ\n");
+ err = -EBUSY;
+ goto fail;
+ }
+
+ input_register_device(mk712_dev);
return 0;
+
+ fail: input_free_device(mk712_dev);
+ release_region(mk712_io, 8);
+ return err;
}
static void __exit mk712_exit(void)
{
- input_unregister_device(&mk712_dev);
- free_irq(mk712_irq, &mk712_dev);
+ input_unregister_device(mk712_dev);
+ free_irq(mk712_irq, mk712_dev);
release_region(mk712_io, 8);
}
diff --git a/drivers/input/touchscreen/mtouch.c b/drivers/input/touchscreen/mtouch.c
index aa8ee7842179..1d0d37eeef6e 100644
--- a/drivers/input/touchscreen/mtouch.c
+++ b/drivers/input/touchscreen/mtouch.c
@@ -51,14 +51,12 @@ MODULE_LICENSE("GPL");
#define MTOUCH_GET_YC(data) (((data[4])<<7) | data[3])
#define MTOUCH_GET_TOUCHED(data) (MTOUCH_FORMAT_TABLET_TOUCH_BIT & data[0])
-static char *mtouch_name = "MicroTouch Serial TouchScreen";
-
/*
* Per-touchscreen data.
*/
struct mtouch {
- struct input_dev dev;
+ struct input_dev *dev;
struct serio *serio;
int idx;
unsigned char data[MTOUCH_MAX_LENGTH];
@@ -67,7 +65,7 @@ struct mtouch {
static void mtouch_process_format_tablet(struct mtouch *mtouch, struct pt_regs *regs)
{
- struct input_dev *dev = &mtouch->dev;
+ struct input_dev *dev = mtouch->dev;
if (MTOUCH_FORMAT_TABLET_LENGTH == ++mtouch->idx) {
input_regs(dev, regs);
@@ -116,9 +114,11 @@ static void mtouch_disconnect(struct serio *serio)
{
struct mtouch* mtouch = serio_get_drvdata(serio);
- input_unregister_device(&mtouch->dev);
+ input_get_device(mtouch->dev);
+ input_unregister_device(mtouch->dev);
serio_close(serio);
serio_set_drvdata(serio, NULL);
+ input_put_device(mtouch->dev);
kfree(mtouch);
}
@@ -131,46 +131,46 @@ static void mtouch_disconnect(struct serio *serio)
static int mtouch_connect(struct serio *serio, struct serio_driver *drv)
{
struct mtouch *mtouch;
+ struct input_dev *input_dev;
int err;
- if (!(mtouch = kmalloc(sizeof(*mtouch), GFP_KERNEL)))
- return -ENOMEM;
-
- memset(mtouch, 0, sizeof(*mtouch));
-
- init_input_dev(&mtouch->dev);
- mtouch->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
- mtouch->dev.keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
-
- input_set_abs_params(&mtouch->dev, ABS_X, MTOUCH_MIN_XC, MTOUCH_MAX_XC, 0, 0);
- input_set_abs_params(&mtouch->dev, ABS_Y, MTOUCH_MIN_YC, MTOUCH_MAX_YC, 0, 0);
+ mtouch = kzalloc(sizeof(struct mtouch), GFP_KERNEL);
+ input_dev = input_allocate_device();
+ if (!mtouch || !input_dev) {
+ err = -ENOMEM;
+ goto fail;
+ }
mtouch->serio = serio;
-
+ mtouch->dev = input_dev;
sprintf(mtouch->phys, "%s/input0", serio->phys);
- mtouch->dev.private = mtouch;
- mtouch->dev.name = mtouch_name;
- mtouch->dev.phys = mtouch->phys;
- mtouch->dev.id.bustype = BUS_RS232;
- mtouch->dev.id.vendor = SERIO_MICROTOUCH;
- mtouch->dev.id.product = 0;
- mtouch->dev.id.version = 0x0100;
+ input_dev->private = mtouch;
+ input_dev->name = "MicroTouch Serial TouchScreen";
+ input_dev->phys = mtouch->phys;
+ input_dev->id.bustype = BUS_RS232;
+ input_dev->id.vendor = SERIO_MICROTOUCH;
+ input_dev->id.product = 0;
+ input_dev->id.version = 0x0100;
+ input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+ input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
+ input_set_abs_params(mtouch->dev, ABS_X, MTOUCH_MIN_XC, MTOUCH_MAX_XC, 0, 0);
+ input_set_abs_params(mtouch->dev, ABS_Y, MTOUCH_MIN_YC, MTOUCH_MAX_YC, 0, 0);
serio_set_drvdata(serio, mtouch);
err = serio_open(serio, drv);
- if (err) {
- serio_set_drvdata(serio, NULL);
- kfree(mtouch);
- return err;
- }
-
- input_register_device(&mtouch->dev);
+ if (err)
+ goto fail;
- printk(KERN_INFO "input: %s on %s\n", mtouch->dev.name, serio->phys);
+ input_register_device(mtouch->dev);
return 0;
+
+ fail: serio_set_drvdata(serio, NULL);
+ input_free_device(input_dev);
+ kfree(mtouch);
+ return err;
}
/*
diff --git a/drivers/input/tsdev.c b/drivers/input/tsdev.c
index 50c63a155156..ca1547929d62 100644
--- a/drivers/input/tsdev.c
+++ b/drivers/input/tsdev.c
@@ -53,7 +53,6 @@
#include <linux/random.h>
#include <linux/time.h>
#include <linux/device.h>
-#include <linux/devfs_fs_kernel.h>
#ifndef CONFIG_INPUT_TSDEV_SCREEN_X
#define CONFIG_INPUT_TSDEV_SCREEN_X 240
@@ -369,6 +368,7 @@ static struct input_handle *tsdev_connect(struct input_handler *handler,
struct input_device_id *id)
{
struct tsdev *tsdev;
+ struct class_device *cdev;
int minor, delta;
for (minor = 0; minor < TSDEV_MINORS/2 && tsdev_table[minor];
@@ -410,13 +410,13 @@ static struct input_handle *tsdev_connect(struct input_handler *handler,
tsdev_table[minor] = tsdev;
- devfs_mk_cdev(MKDEV(INPUT_MAJOR, TSDEV_MINOR_BASE + minor),
- S_IFCHR|S_IRUGO|S_IWUSR, "input/ts%d", minor);
- devfs_mk_cdev(MKDEV(INPUT_MAJOR, TSDEV_MINOR_BASE + minor + TSDEV_MINORS/2),
- S_IFCHR|S_IRUGO|S_IWUSR, "input/tsraw%d", minor);
- class_device_create(input_class,
+ cdev = class_device_create(&input_class, &dev->cdev,
MKDEV(INPUT_MAJOR, TSDEV_MINOR_BASE + minor),
- dev->dev, "ts%d", minor);
+ dev->cdev.dev, tsdev->name);
+
+ /* temporary symlink to keep userspace happy */
+ sysfs_create_link(&input_class.subsys.kset.kobj, &cdev->kobj,
+ tsdev->name);
return &tsdev->handle;
}
@@ -426,10 +426,9 @@ static void tsdev_disconnect(struct input_handle *handle)
struct tsdev *tsdev = handle->private;
struct tsdev_list *list;
- class_device_destroy(input_class,
+ sysfs_remove_link(&input_class.subsys.kset.kobj, tsdev->name);
+ class_device_destroy(&input_class,
MKDEV(INPUT_MAJOR, TSDEV_MINOR_BASE + tsdev->minor));
- devfs_remove("input/ts%d", tsdev->minor);
- devfs_remove("input/tsraw%d", tsdev->minor);
tsdev->exist = 0;
if (tsdev->open) {
diff --git a/drivers/isdn/capi/capi.c b/drivers/isdn/capi/capi.c
index 04fb606b5ddd..11ae0fddea04 100644
--- a/drivers/isdn/capi/capi.c
+++ b/drivers/isdn/capi/capi.c
@@ -1505,7 +1505,7 @@ static int __init capi_init(void)
return PTR_ERR(capi_class);
}
- class_device_create(capi_class, MKDEV(capi_major, 0), NULL, "capi");
+ class_device_create(capi_class, NULL, MKDEV(capi_major, 0), NULL, "capi");
devfs_mk_cdev(MKDEV(capi_major, 0), S_IFCHR | S_IRUSR | S_IWUSR,
"isdn/capi20");
diff --git a/drivers/isdn/capi/capifs.c b/drivers/isdn/capi/capifs.c
index 3abd7fc6e5ef..7b564c0dd996 100644
--- a/drivers/isdn/capi/capifs.c
+++ b/drivers/isdn/capi/capifs.c
@@ -15,6 +15,7 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/ctype.h>
+#include <linux/sched.h> /* current */
MODULE_DESCRIPTION("CAPI4Linux: /dev/capi/ filesystem");
MODULE_AUTHOR("Carsten Paeth");
diff --git a/drivers/isdn/divert/divert_init.c b/drivers/isdn/divert/divert_init.c
index 434e684f5dbb..2f7c9fc2e898 100644
--- a/drivers/isdn/divert/divert_init.c
+++ b/drivers/isdn/divert/divert_init.c
@@ -10,7 +10,6 @@
*/
#include <linux/module.h>
-#include <linux/version.h>
#include <linux/init.h>
#include <linux/kernel.h>
diff --git a/drivers/isdn/divert/divert_procfs.c b/drivers/isdn/divert/divert_procfs.c
index 0b0ea26023e5..1b37d86d5ee1 100644
--- a/drivers/isdn/divert/divert_procfs.c
+++ b/drivers/isdn/divert/divert_procfs.c
@@ -11,7 +11,6 @@
#include <linux/config.h>
#include <linux/module.h>
-#include <linux/version.h>
#include <linux/poll.h>
#include <linux/smp_lock.h>
#ifdef CONFIG_PROC_FS
diff --git a/drivers/isdn/divert/isdn_divert.c b/drivers/isdn/divert/isdn_divert.c
index 0bfd698726a6..f1a1f9a9b88e 100644
--- a/drivers/isdn/divert/isdn_divert.c
+++ b/drivers/isdn/divert/isdn_divert.c
@@ -9,7 +9,6 @@
*
*/
-#include <linux/version.h>
#include <linux/proc_fs.h>
#include "isdn_divert.h"
diff --git a/drivers/isdn/hardware/avm/avm_cs.c b/drivers/isdn/hardware/avm/avm_cs.c
index db9bad2b3d16..27391c32f3eb 100644
--- a/drivers/isdn/hardware/avm/avm_cs.c
+++ b/drivers/isdn/hardware/avm/avm_cs.c
@@ -212,11 +212,8 @@ static void avmcs_detach(dev_link_t *link)
/* Unlink device structure, free pieces */
*linkp = link->next;
- if (link->priv) {
- kfree(link->priv);
- }
+ kfree(link->priv);
kfree(link);
-
} /* avmcs_detach */
/*======================================================================
diff --git a/drivers/isdn/hisax/avm_pci.c b/drivers/isdn/hisax/avm_pci.c
index 625799ab0d14..5d8ee7368f7b 100644
--- a/drivers/isdn/hisax/avm_pci.c
+++ b/drivers/isdn/hisax/avm_pci.c
@@ -552,14 +552,10 @@ close_hdlcstate(struct BCState *bcs)
{
modehdlc(bcs, 0, 0);
if (test_and_clear_bit(BC_FLG_INIT, &bcs->Flag)) {
- if (bcs->hw.hdlc.rcvbuf) {
- kfree(bcs->hw.hdlc.rcvbuf);
- bcs->hw.hdlc.rcvbuf = NULL;
- }
- if (bcs->blog) {
- kfree(bcs->blog);
- bcs->blog = NULL;
- }
+ kfree(bcs->hw.hdlc.rcvbuf);
+ bcs->hw.hdlc.rcvbuf = NULL;
+ kfree(bcs->blog);
+ bcs->blog = NULL;
skb_queue_purge(&bcs->rqueue);
skb_queue_purge(&bcs->squeue);
if (bcs->tx_skb) {
diff --git a/drivers/isdn/hisax/avma1_cs.c b/drivers/isdn/hisax/avma1_cs.c
index 0e22991635e7..5f5a5ae740d2 100644
--- a/drivers/isdn/hisax/avma1_cs.c
+++ b/drivers/isdn/hisax/avma1_cs.c
@@ -236,9 +236,7 @@ static void avma1cs_detach(dev_link_t *link)
/* Unlink device structure, free pieces */
*linkp = link->next;
- if (link->priv) {
- kfree(link->priv);
- }
+ kfree(link->priv);
kfree(link);
} /* avma1cs_detach */
diff --git a/drivers/isdn/hisax/config.c b/drivers/isdn/hisax/config.c
index fbaab4352902..8159bcecd0c2 100644
--- a/drivers/isdn/hisax/config.c
+++ b/drivers/isdn/hisax/config.c
@@ -787,8 +787,7 @@ static void ll_unload(struct IsdnCardState *cs)
ic.command = ISDN_STAT_UNLOAD;
ic.driver = cs->myid;
cs->iif.statcallb(&ic);
- if (cs->status_buf)
- kfree(cs->status_buf);
+ kfree(cs->status_buf);
cs->status_read = NULL;
cs->status_write = NULL;
cs->status_end = NULL;
@@ -807,10 +806,8 @@ static void closecard(int cardnr)
skb_queue_purge(&csta->rq);
skb_queue_purge(&csta->sq);
- if (csta->rcvbuf) {
- kfree(csta->rcvbuf);
- csta->rcvbuf = NULL;
- }
+ kfree(csta->rcvbuf);
+ csta->rcvbuf = NULL;
if (csta->tx_skb) {
dev_kfree_skb(csta->tx_skb);
csta->tx_skb = NULL;
diff --git a/drivers/isdn/hisax/hfc4s8s_l1.c b/drivers/isdn/hisax/hfc4s8s_l1.c
index 7333377ab31d..e3866b0a97fd 100644
--- a/drivers/isdn/hisax/hfc4s8s_l1.c
+++ b/drivers/isdn/hisax/hfc4s8s_l1.c
@@ -1063,7 +1063,7 @@ tx_b_frame(struct hfc4s8s_btype *bch)
Write_hfc8(l1->hw, A_INC_RES_FIFO, 1);
}
ack_len += skb->truesize;
- bch->tx_skb = 0;
+ bch->tx_skb = NULL;
bch->tx_cnt = 0;
dev_kfree_skb(skb);
} else
@@ -1659,10 +1659,10 @@ hfc4s8s_remove(struct pci_dev *pdev)
}
static struct pci_driver hfc4s8s_driver = {
- name:"hfc4s8s_l1",
- probe:hfc4s8s_probe,
- remove:__devexit_p(hfc4s8s_remove),
- id_table:hfc4s8s_ids,
+ .name = "hfc4s8s_l1",
+ .probe = hfc4s8s_probe,
+ .remove = __devexit_p(hfc4s8s_remove),
+ .id_table = hfc4s8s_ids,
};
/**********************/
diff --git a/drivers/isdn/hisax/hfc_2bds0.c b/drivers/isdn/hisax/hfc_2bds0.c
index 7cf87793e790..637a261c9312 100644
--- a/drivers/isdn/hisax/hfc_2bds0.c
+++ b/drivers/isdn/hisax/hfc_2bds0.c
@@ -1052,18 +1052,12 @@ init2bds0(struct IsdnCardState *cs)
void
release2bds0(struct IsdnCardState *cs)
{
- if (cs->bcs[0].hw.hfc.send) {
- kfree(cs->bcs[0].hw.hfc.send);
- cs->bcs[0].hw.hfc.send = NULL;
- }
- if (cs->bcs[1].hw.hfc.send) {
- kfree(cs->bcs[1].hw.hfc.send);
- cs->bcs[1].hw.hfc.send = NULL;
- }
- if (cs->hw.hfcD.send) {
- kfree(cs->hw.hfcD.send);
- cs->hw.hfcD.send = NULL;
- }
+ kfree(cs->bcs[0].hw.hfc.send);
+ cs->bcs[0].hw.hfc.send = NULL;
+ kfree(cs->bcs[1].hw.hfc.send);
+ cs->bcs[1].hw.hfc.send = NULL;
+ kfree(cs->hw.hfcD.send);
+ cs->hw.hfcD.send = NULL;
}
void
diff --git a/drivers/isdn/hisax/hfc_2bs0.c b/drivers/isdn/hisax/hfc_2bs0.c
index f978a5af8662..c964539cc43e 100644
--- a/drivers/isdn/hisax/hfc_2bs0.c
+++ b/drivers/isdn/hisax/hfc_2bs0.c
@@ -582,12 +582,8 @@ inithfc(struct IsdnCardState *cs)
void
releasehfc(struct IsdnCardState *cs)
{
- if (cs->bcs[0].hw.hfc.send) {
- kfree(cs->bcs[0].hw.hfc.send);
- cs->bcs[0].hw.hfc.send = NULL;
- }
- if (cs->bcs[1].hw.hfc.send) {
- kfree(cs->bcs[1].hw.hfc.send);
- cs->bcs[1].hw.hfc.send = NULL;
- }
+ kfree(cs->bcs[0].hw.hfc.send);
+ cs->bcs[0].hw.hfc.send = NULL;
+ kfree(cs->bcs[1].hw.hfc.send);
+ cs->bcs[1].hw.hfc.send = NULL;
}
diff --git a/drivers/isdn/hisax/hfc_usb.c b/drivers/isdn/hisax/hfc_usb.c
index e2c3af49d72b..32bf0d5d0f9a 100644
--- a/drivers/isdn/hisax/hfc_usb.c
+++ b/drivers/isdn/hisax/hfc_usb.c
@@ -1,7 +1,7 @@
/*
* hfc_usb.c
*
- * $Id: hfc_usb.c,v 4.34 2005/01/26 17:25:53 martinb1 Exp $
+ * $Id: hfc_usb.c,v 4.36 2005/04/08 09:55:13 martinb1 Exp $
*
* modular HiSax ISDN driver for Colognechip HFC-S USB chip
*
@@ -44,12 +44,8 @@
#include "hisax_if.h"
#include "hfc_usb.h"
-/*
-* Version Information
-* (do not modify the CVS Makros $Revision: 4.34 $ and $Date: 2005/01/26 17:25:53 $ !)
-*/
static const char *hfcusb_revision =
- "Revision: 4.34 $ Date: 2005/01/26 17:25:53 $ ";
+ "$Revision: 4.36 $ $Date: 2005/04/08 09:55:13 $ ";
/* Hisax debug support
* use "modprobe debug=x" where x is bitfield of USB_DBG & ISDN_DBG
@@ -63,81 +59,89 @@ module_param(debug, uint, 0);
static int hfc_debug;
#endif
+/* private vendor specific data */
+typedef struct {
+ __u8 led_scheme; // led display scheme
+ signed short led_bits[8]; // array of 8 possible LED bitmask settings
+ char *vend_name; // device name
+} hfcsusb_vdata;
/****************************************/
/* data defining the devices to be used */
/****************************************/
-static struct usb_device_id hfc_usb_idtab[] = {
- {USB_DEVICE(0x0959, 0x2bd0)}, /* Colognechip USB eval TA */
- {USB_DEVICE(0x0675, 0x1688)}, /* DrayTek miniVigor 128 USB ISDN TA */
- {USB_DEVICE(0x07b0, 0x0007)}, /* Billion USB TA 2 */
- {USB_DEVICE(0x0742, 0x2008)}, /* Stollmann USB TA */
- {USB_DEVICE(0x0742, 0x2009)}, /* Aceex USB ISDN TA */
- {USB_DEVICE(0x0742, 0x200A)}, /* OEM USB ISDN TA */
- {USB_DEVICE(0x08e3, 0x0301)}, /* OliTec ISDN USB */
- {USB_DEVICE(0x07fa, 0x0846)}, /* Bewan ISDN USB TA */
- {USB_DEVICE(0x07fa, 0x0847)}, /* Djinn Numeris USB */
- {USB_DEVICE(0x07b0, 0x0006)}, /* Twister ISDN USB TA */
- {} /* end with an all-zeroes entry */
+static struct usb_device_id hfcusb_idtab[] = {
+ {
+ .idVendor = 0x0959,
+ .idProduct = 0x2bd0,
+ .driver_info = (unsigned long) &((hfcsusb_vdata)
+ {LED_OFF, {4, 0, 2, 1},
+ "ISDN USB TA (Cologne Chip HFC-S USB based)"}),
+ },
+ {
+ .idVendor = 0x0675,
+ .idProduct = 0x1688,
+ .driver_info = (unsigned long) &((hfcsusb_vdata)
+ {LED_SCHEME1, {1, 2, 0, 0},
+ "DrayTek miniVigor 128 USB ISDN TA"}),
+ },
+ {
+ .idVendor = 0x07b0,
+ .idProduct = 0x0007,
+ .driver_info = (unsigned long) &((hfcsusb_vdata)
+ {LED_SCHEME1, {0x80, -64, -32, -16},
+ "Billion tiny USB ISDN TA 128"}),
+ },
+ {
+ .idVendor = 0x0742,
+ .idProduct = 0x2008,
+ .driver_info = (unsigned long) &((hfcsusb_vdata)
+ {LED_SCHEME1, {4, 0, 2, 1},
+ "Stollmann USB TA"}),
+ },
+ {
+ .idVendor = 0x0742,
+ .idProduct = 0x2009,
+ .driver_info = (unsigned long) &((hfcsusb_vdata)
+ {LED_SCHEME1, {4, 0, 2, 1},
+ "Aceex USB ISDN TA"}),
+ },
+ {
+ .idVendor = 0x0742,
+ .idProduct = 0x200A,
+ .driver_info = (unsigned long) &((hfcsusb_vdata)
+ {LED_SCHEME1, {4, 0, 2, 1},
+ "OEM USB ISDN TA"}),
+ },
+ {
+ .idVendor = 0x08e3,
+ .idProduct = 0x0301,
+ .driver_info = (unsigned long) &((hfcsusb_vdata)
+ {LED_SCHEME1, {2, 0, 1, 4},
+ "Olitec USB RNIS"}),
+ },
+ {
+ .idVendor = 0x07fa,
+ .idProduct = 0x0846,
+ .driver_info = (unsigned long) &((hfcsusb_vdata)
+ {LED_SCHEME1, {0x80, -64, -32, -16},
+ "Bewan Modem RNIS USB"}),
+ },
+ {
+ .idVendor = 0x07fa,
+ .idProduct = 0x0847,
+ .driver_info = (unsigned long) &((hfcsusb_vdata)
+ {LED_SCHEME1, {0x80, -64, -32, -16},
+ "Djinn Numeris USB"}),
+ },
+ {
+ .idVendor = 0x07b0,
+ .idProduct = 0x0006,
+ .driver_info = (unsigned long) &((hfcsusb_vdata)
+ {LED_SCHEME1, {0x80, -64, -32, -16},
+ "Twister ISDN TA"}),
+ },
};
-/* driver internal device specific data:
-* VendorID, ProductID, Devicename, LED_SCHEME,
-* LED's BitMask in HFCUSB_P_DATA Register : LED_USB, LED_S0, LED_B1, LED_B2
-*/
-static vendor_data vdata[] = {
- /* CologneChip Eval TA */
- {0x0959, 0x2bd0, "ISDN USB TA (Cologne Chip HFC-S USB based)",
- LED_OFF, {4, 0, 2, 1}
- }
- ,
- /* DrayTek miniVigor 128 USB ISDN TA */
- {0x0675, 0x1688, "DrayTek miniVigor 128 USB ISDN TA",
- LED_SCHEME1, {1, 2, 0, 0}
- }
- ,
- /* Billion TA */
- {0x07b0, 0x0007, "Billion tiny USB ISDN TA 128",
- LED_SCHEME1, {0x80, -64, -32, -16}
- }
- ,
- /* Stollmann TA */
- {0x0742, 0x2008, "Stollmann USB TA",
- LED_SCHEME1, {4, 0, 2, 1}
- }
- ,
- /* Aceex USB ISDN TA */
- {0x0742, 0x2009, "Aceex USB ISDN TA",
- LED_SCHEME1, {4, 0, 2, 1}
- }
- ,
- /* OEM USB ISDN TA */
- {0x0742, 0x200A, "OEM USB ISDN TA",
- LED_SCHEME1, {4, 0, 2, 1}
- }
- ,
- /* Olitec TA */
- {0x08e3, 0x0301, "Olitec USB RNIS",
- LED_SCHEME1, {2, 0, 1, 4}
- }
- ,
- /* Bewan TA */
- {0x07fa, 0x0846, "Bewan Modem RNIS USB",
- LED_SCHEME1, {0x80, -64, -32, -16}
- }
- ,
- /* Bewan TA */
- {0x07fa, 0x0847, "Djinn Numeris USB",
- LED_SCHEME1, {0x80, -64, -32, -16}
- }
- ,
- /* Twister ISDN TA */
- {0x07b0, 0x0006, "Twister ISDN TA",
- LED_SCHEME1, {0x80, -64, -32, -16}
- }
- ,
- {0, 0, 0} /* EOL element */
-};
/***************************************************************/
/* structure defining input+output fifos (interrupt/bulk mode) */
@@ -211,8 +215,6 @@ typedef struct hfcusb_data {
volatile __u8 l1_state; /* actual l1 state */
struct timer_list t3_timer; /* timer 3 for activation/deactivation */
struct timer_list t4_timer; /* timer 4 for activation/deactivation */
- struct timer_list led_timer; /* timer flashing leds */
-
} hfcusb_data;
@@ -227,7 +229,7 @@ symbolic(struct hfcusb_symbolic_list list[], const int num)
for (i = 0; list[i].name != NULL; i++)
if (list[i].num == num)
return (list[i].name);
- return "<unkown>";
+ return "<unkown ERROR>";
}
@@ -335,93 +337,57 @@ set_led_bit(hfcusb_data * hfc, signed short led_bits, int unset)
}
}
-/******************************************/
-/* invert B-channel LEDs if data is sent */
-/******************************************/
-static void
-led_timer(hfcusb_data * hfc)
-{
- static int cnt = 0;
-
- if (cnt) {
- if (hfc->led_b_active & 1)
- set_led_bit(hfc, vdata[hfc->vend_idx].led_bits[2],
- 0);
- if (hfc->led_b_active & 2)
- set_led_bit(hfc, vdata[hfc->vend_idx].led_bits[3],
- 0);
- } else {
- if (!(hfc->led_b_active & 1) || hfc->led_new_data & 1)
- set_led_bit(hfc, vdata[hfc->vend_idx].led_bits[2],
- 1);
- if (!(hfc->led_b_active & 2) || hfc->led_new_data & 2)
- set_led_bit(hfc, vdata[hfc->vend_idx].led_bits[3],
- 1);
- }
-
- write_led(hfc, hfc->led_state);
- hfc->led_new_data = 0;
-
- cnt = !cnt;
-
- /* restart 4 hz timer */
- if (!timer_pending(&hfc->led_timer)) {
- add_timer(&hfc->led_timer);
- hfc->led_timer.expires = jiffies + (LED_TIME * HZ) / 1000;
- }
-}
-
/**************************/
/* handle LED requests */
/**************************/
static void
handle_led(hfcusb_data * hfc, int event)
{
+ hfcsusb_vdata *driver_info =
+ (hfcsusb_vdata *) hfcusb_idtab[hfc->vend_idx].driver_info;
+
/* if no scheme -> no LED action */
- if (vdata[hfc->vend_idx].led_scheme == LED_OFF)
+ if (driver_info->led_scheme == LED_OFF)
return;
switch (event) {
case LED_POWER_ON:
- set_led_bit(hfc, vdata[hfc->vend_idx].led_bits[0],
+ set_led_bit(hfc, driver_info->led_bits[0],
0);
- set_led_bit(hfc, vdata[hfc->vend_idx].led_bits[1],
+ set_led_bit(hfc, driver_info->led_bits[1],
1);
- set_led_bit(hfc, vdata[hfc->vend_idx].led_bits[2],
+ set_led_bit(hfc, driver_info->led_bits[2],
1);
- set_led_bit(hfc, vdata[hfc->vend_idx].led_bits[3],
+ set_led_bit(hfc, driver_info->led_bits[3],
1);
break;
case LED_POWER_OFF: /* no Power off handling */
break;
case LED_S0_ON:
- set_led_bit(hfc, vdata[hfc->vend_idx].led_bits[1],
+ set_led_bit(hfc, driver_info->led_bits[1],
0);
break;
case LED_S0_OFF:
- set_led_bit(hfc, vdata[hfc->vend_idx].led_bits[1],
+ set_led_bit(hfc, driver_info->led_bits[1],
1);
break;
case LED_B1_ON:
- hfc->led_b_active |= 1;
+ set_led_bit(hfc, driver_info->led_bits[2],
+ 0);
break;
case LED_B1_OFF:
- hfc->led_b_active &= ~1;
- break;
- case LED_B1_DATA:
- hfc->led_new_data |= 1;
+ set_led_bit(hfc, driver_info->led_bits[2],
+ 1);
break;
case LED_B2_ON:
- hfc->led_b_active |= 2;
+ set_led_bit(hfc, driver_info->led_bits[3],
+ 0);
break;
case LED_B2_OFF:
- hfc->led_b_active &= ~2;
- break;
- case LED_B2_DATA:
- hfc->led_new_data |= 2;
+ set_led_bit(hfc, driver_info->led_bits[3],
+ 1);
break;
}
-
write_led(hfc, hfc->led_state);
}
@@ -725,14 +691,6 @@ tx_iso_complete(struct urb *urb, struct pt_regs *regs)
current_len + 1;
tx_offset += (current_len + 1);
- if (!transp_mode) {
- if (fifon == HFCUSB_B1_TX)
- handle_led(hfc,
- LED_B1_DATA);
- if (fifon == HFCUSB_B2_TX)
- handle_led(hfc,
- LED_B2_DATA);
- }
} else {
urb->iso_frame_desc[k].offset =
tx_offset++;
@@ -966,14 +924,6 @@ collect_rx_frame(usb_fifo * fifo, __u8 * data, int len, int finish)
skb_trim(fifo->skbuff, 0);
}
}
-
- /* LED flashing only in HDLC mode */
- if (!transp_mode) {
- if (fifon == HFCUSB_B1_RX)
- handle_led(hfc, LED_B1_DATA);
- if (fifon == HFCUSB_B2_RX)
- handle_led(hfc, LED_B2_DATA);
- }
}
/***********************************************/
@@ -1339,17 +1289,6 @@ usb_init(hfcusb_data * hfc)
hfc->t4_timer.data = (long) hfc;
hfc->t4_timer.function = (void *) l1_timer_expire_t4;
- /* init the led timer */
- init_timer(&hfc->led_timer);
- hfc->led_timer.data = (long) hfc;
- hfc->led_timer.function = (void *) led_timer;
-
- /* trigger 4 hz led timer */
- if (!timer_pending(&hfc->led_timer)) {
- hfc->led_timer.expires = jiffies + (LED_TIME * HZ) / 1000;
- add_timer(&hfc->led_timer);
- }
-
/* init the background machinery for control requests */
hfc->ctrl_read.bRequestType = 0xc0;
hfc->ctrl_read.bRequest = 1;
@@ -1440,13 +1379,18 @@ hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
attr, cfg_found, cidx, ep_addr;
int cmptbl[16], small_match, iso_packet_size, packet_size,
alt_used = 0;
+ hfcsusb_vdata *driver_info;
vend_idx = 0xffff;
- for (i = 0; vdata[i].vendor; i++) {
- if (dev->descriptor.idVendor == vdata[i].vendor
- && dev->descriptor.idProduct == vdata[i].prod_id)
+ for (i = 0; hfcusb_idtab[i].idVendor; i++) {
+ if (dev->descriptor.idVendor == hfcusb_idtab[i].idVendor
+ && dev->descriptor.idProduct ==
+ hfcusb_idtab[i].idProduct) {
vend_idx = i;
+ continue;
+ }
}
+
#ifdef CONFIG_HISAX_DEBUG
DBG(USB_DBG,
"HFC-USB: probing interface(%d) actalt(%d) minor(%d)\n", ifnum,
@@ -1457,10 +1401,6 @@ hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
ifnum, iface->desc.bAlternateSetting, intf->minor);
if (vend_idx != 0xffff) {
-#ifdef CONFIG_HISAX_DEBUG
- DBG(USB_DBG, "HFC-S USB: found vendor idx:%d name:%s",
- vend_idx, vdata[vend_idx].vend_name);
-#endif
/* if vendor and product ID is OK, start probing alternate settings */
alt_idx = 0;
small_match = 0xffff;
@@ -1687,9 +1627,11 @@ hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
usb_sndctrlpipe(context->dev, 0);
context->ctrl_urb = usb_alloc_urb(0, GFP_KERNEL);
- printk(KERN_INFO
- "HFC-S USB: detected \"%s\"\n",
- vdata[vend_idx].vend_name);
+ driver_info =
+ (hfcsusb_vdata *) hfcusb_idtab[vend_idx].
+ driver_info;
+ printk(KERN_INFO "HFC-S USB: detected \"%s\"\n",
+ driver_info->vend_name);
#ifdef CONFIG_HISAX_DEBUG
DBG(USB_DBG,
"HFC-S USB: Endpoint-Config: %s (if=%d alt=%d)\n",
@@ -1740,8 +1682,6 @@ hfc_usb_disconnect(struct usb_interface
del_timer(&context->t3_timer);
if (timer_pending(&context->t4_timer))
del_timer(&context->t4_timer);
- if (timer_pending(&context->led_timer))
- del_timer(&context->led_timer);
/* tell all fifos to terminate */
for (i = 0; i < HFCUSB_NUM_FIFOS; i++) {
if (context->fifos[i].usb_transfer_mode == USB_ISOC) {
@@ -1785,9 +1725,11 @@ hfc_usb_disconnect(struct usb_interface
/* our driver information structure */
/************************************/
static struct usb_driver hfc_drv = {
- .owner = THIS_MODULE,.name =
- "hfc_usb",.id_table = hfc_usb_idtab,.probe =
- hfc_usb_probe,.disconnect = hfc_usb_disconnect,
+ .owner = THIS_MODULE,
+ .name = "hfc_usb",
+ .id_table = hfcusb_idtab,
+ .probe = hfc_usb_probe,
+ .disconnect = hfc_usb_disconnect,
};
static void __exit
hfc_usb_exit(void)
@@ -1825,4 +1767,4 @@ module_exit(hfc_usb_exit);
MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");
-MODULE_DEVICE_TABLE(usb, hfc_usb_idtab);
+MODULE_DEVICE_TABLE(usb, hfcusb_idtab);
diff --git a/drivers/isdn/hisax/hfc_usb.h b/drivers/isdn/hisax/hfc_usb.h
index 280dd29b30d6..ec52c1a7c22a 100644
--- a/drivers/isdn/hisax/hfc_usb.h
+++ b/drivers/isdn/hisax/hfc_usb.h
@@ -1,7 +1,7 @@
/*
* hfc_usb.h
*
-* $Id: hfc_usb.h,v 4.1 2005/01/26 17:25:53 martinb1 Exp $
+* $Id: hfc_usb.h,v 4.2 2005/04/07 15:27:17 martinb1 Exp $
*/
#ifndef __HFC_USB_H__
@@ -91,7 +91,7 @@
/**********/
/* macros */
/**********/
-#define write_usb(a,b,c)usb_control_msg((a)->dev,(a)->ctrl_out_pipe,0,0x40,(c),(b),0,0,HFC_CTRL_TIMEOUT)
+#define write_usb(a,b,c)usb_control_msg((a)->dev,(a)->ctrl_out_pipe,0,0x40,(c),(b),NULL,0,HFC_CTRL_TIMEOUT)
#define read_usb(a,b,c) usb_control_msg((a)->dev,(a)->ctrl_in_pipe,1,0xC0,0,(b),(c),1,HFC_CTRL_TIMEOUT)
@@ -186,6 +186,7 @@ static int validconf[][19] = {
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} // EOL element
};
+#ifdef CONFIG_HISAX_DEBUG
// string description of chosen config
static char *conf_str[] = {
"4 Interrupt IN + 3 Isochron OUT",
@@ -193,6 +194,7 @@ static char *conf_str[] = {
"4 Isochron IN + 3 Isochron OUT",
"3 Isochron IN + 3 Isochron OUT"
};
+#endif
typedef struct {
diff --git a/drivers/isdn/hisax/hisax_fcpcipnp.c b/drivers/isdn/hisax/hisax_fcpcipnp.c
index b4d795d40154..dc7ef957e897 100644
--- a/drivers/isdn/hisax/hisax_fcpcipnp.c
+++ b/drivers/isdn/hisax/hisax_fcpcipnp.c
@@ -23,7 +23,6 @@
* o tx_skb at PH_DEACTIVATE time
*/
-#include <linux/version.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/pci.h>
diff --git a/drivers/isdn/hisax/hscx.c b/drivers/isdn/hisax/hscx.c
index 66dbaee77bfb..c8f9951f7914 100644
--- a/drivers/isdn/hisax/hscx.c
+++ b/drivers/isdn/hisax/hscx.c
@@ -156,14 +156,10 @@ close_hscxstate(struct BCState *bcs)
{
modehscx(bcs, 0, bcs->channel);
if (test_and_clear_bit(BC_FLG_INIT, &bcs->Flag)) {
- if (bcs->hw.hscx.rcvbuf) {
- kfree(bcs->hw.hscx.rcvbuf);
- bcs->hw.hscx.rcvbuf = NULL;
- }
- if (bcs->blog) {
- kfree(bcs->blog);
- bcs->blog = NULL;
- }
+ kfree(bcs->hw.hscx.rcvbuf);
+ bcs->hw.hscx.rcvbuf = NULL;
+ kfree(bcs->blog);
+ bcs->blog = NULL;
skb_queue_purge(&bcs->rqueue);
skb_queue_purge(&bcs->squeue);
if (bcs->tx_skb) {
diff --git a/drivers/isdn/hisax/icc.c b/drivers/isdn/hisax/icc.c
index b4ca5859b177..c615752b96aa 100644
--- a/drivers/isdn/hisax/icc.c
+++ b/drivers/isdn/hisax/icc.c
@@ -571,14 +571,10 @@ setstack_icc(struct PStack *st, struct IsdnCardState *cs)
static void
DC_Close_icc(struct IsdnCardState *cs) {
- if (cs->dc.icc.mon_rx) {
- kfree(cs->dc.icc.mon_rx);
- cs->dc.icc.mon_rx = NULL;
- }
- if (cs->dc.icc.mon_tx) {
- kfree(cs->dc.icc.mon_tx);
- cs->dc.icc.mon_tx = NULL;
- }
+ kfree(cs->dc.icc.mon_rx);
+ cs->dc.icc.mon_rx = NULL;
+ kfree(cs->dc.icc.mon_tx);
+ cs->dc.icc.mon_tx = NULL;
}
static void
diff --git a/drivers/isdn/hisax/ipacx.c b/drivers/isdn/hisax/ipacx.c
index efba2f448017..2e9afae1254a 100644
--- a/drivers/isdn/hisax/ipacx.c
+++ b/drivers/isdn/hisax/ipacx.c
@@ -762,14 +762,10 @@ bch_close_state(struct BCState *bcs)
{
bch_mode(bcs, 0, bcs->channel);
if (test_and_clear_bit(BC_FLG_INIT, &bcs->Flag)) {
- if (bcs->hw.hscx.rcvbuf) {
- kfree(bcs->hw.hscx.rcvbuf);
- bcs->hw.hscx.rcvbuf = NULL;
- }
- if (bcs->blog) {
- kfree(bcs->blog);
- bcs->blog = NULL;
- }
+ kfree(bcs->hw.hscx.rcvbuf);
+ bcs->hw.hscx.rcvbuf = NULL;
+ kfree(bcs->blog);
+ bcs->blog = NULL;
skb_queue_purge(&bcs->rqueue);
skb_queue_purge(&bcs->squeue);
if (bcs->tx_skb) {
diff --git a/drivers/isdn/hisax/isac.c b/drivers/isdn/hisax/isac.c
index 85e063a08d23..565b7892c267 100644
--- a/drivers/isdn/hisax/isac.c
+++ b/drivers/isdn/hisax/isac.c
@@ -570,15 +570,12 @@ setstack_isac(struct PStack *st, struct IsdnCardState *cs)
}
static void
-DC_Close_isac(struct IsdnCardState *cs) {
- if (cs->dc.isac.mon_rx) {
- kfree(cs->dc.isac.mon_rx);
- cs->dc.isac.mon_rx = NULL;
- }
- if (cs->dc.isac.mon_tx) {
- kfree(cs->dc.isac.mon_tx);
- cs->dc.isac.mon_tx = NULL;
- }
+DC_Close_isac(struct IsdnCardState *cs)
+{
+ kfree(cs->dc.isac.mon_rx);
+ cs->dc.isac.mon_rx = NULL;
+ kfree(cs->dc.isac.mon_tx);
+ cs->dc.isac.mon_tx = NULL;
}
static void
diff --git a/drivers/isdn/hisax/isar.c b/drivers/isdn/hisax/isar.c
index 642a87c51295..674af673ff96 100644
--- a/drivers/isdn/hisax/isar.c
+++ b/drivers/isdn/hisax/isar.c
@@ -1688,10 +1688,8 @@ close_isarstate(struct BCState *bcs)
{
modeisar(bcs, 0, bcs->channel);
if (test_and_clear_bit(BC_FLG_INIT, &bcs->Flag)) {
- if (bcs->hw.isar.rcvbuf) {
- kfree(bcs->hw.isar.rcvbuf);
- bcs->hw.isar.rcvbuf = NULL;
- }
+ kfree(bcs->hw.isar.rcvbuf);
+ bcs->hw.isar.rcvbuf = NULL;
skb_queue_purge(&bcs->rqueue);
skb_queue_purge(&bcs->squeue);
if (bcs->tx_skb) {
diff --git a/drivers/isdn/hisax/jade.c b/drivers/isdn/hisax/jade.c
index 363ae3179bbd..2659fecc2674 100644
--- a/drivers/isdn/hisax/jade.c
+++ b/drivers/isdn/hisax/jade.c
@@ -195,14 +195,10 @@ close_jadestate(struct BCState *bcs)
{
modejade(bcs, 0, bcs->channel);
if (test_and_clear_bit(BC_FLG_INIT, &bcs->Flag)) {
- if (bcs->hw.hscx.rcvbuf) {
- kfree(bcs->hw.hscx.rcvbuf);
- bcs->hw.hscx.rcvbuf = NULL;
- }
- if (bcs->blog) {
- kfree(bcs->blog);
- bcs->blog = NULL;
- }
+ kfree(bcs->hw.hscx.rcvbuf);
+ bcs->hw.hscx.rcvbuf = NULL;
+ kfree(bcs->blog);
+ bcs->blog = NULL;
skb_queue_purge(&bcs->rqueue);
skb_queue_purge(&bcs->squeue);
if (bcs->tx_skb) {
diff --git a/drivers/isdn/hisax/netjet.c b/drivers/isdn/hisax/netjet.c
index 94da03c30c51..47a47ef0968b 100644
--- a/drivers/isdn/hisax/netjet.c
+++ b/drivers/isdn/hisax/netjet.c
@@ -855,14 +855,10 @@ close_tigerstate(struct BCState *bcs)
{
mode_tiger(bcs, 0, bcs->channel);
if (test_and_clear_bit(BC_FLG_INIT, &bcs->Flag)) {
- if (bcs->hw.tiger.rcvbuf) {
- kfree(bcs->hw.tiger.rcvbuf);
- bcs->hw.tiger.rcvbuf = NULL;
- }
- if (bcs->hw.tiger.sendbuf) {
- kfree(bcs->hw.tiger.sendbuf);
- bcs->hw.tiger.sendbuf = NULL;
- }
+ kfree(bcs->hw.tiger.rcvbuf);
+ bcs->hw.tiger.rcvbuf = NULL;
+ kfree(bcs->hw.tiger.sendbuf);
+ bcs->hw.tiger.sendbuf = NULL;
skb_queue_purge(&bcs->rqueue);
skb_queue_purge(&bcs->squeue);
if (bcs->tx_skb) {
@@ -967,20 +963,12 @@ inittiger(struct IsdnCardState *cs)
static void
releasetiger(struct IsdnCardState *cs)
{
- if (cs->bcs[0].hw.tiger.send) {
- kfree(cs->bcs[0].hw.tiger.send);
- cs->bcs[0].hw.tiger.send = NULL;
- }
- if (cs->bcs[1].hw.tiger.send) {
- cs->bcs[1].hw.tiger.send = NULL;
- }
- if (cs->bcs[0].hw.tiger.rec) {
- kfree(cs->bcs[0].hw.tiger.rec);
- cs->bcs[0].hw.tiger.rec = NULL;
- }
- if (cs->bcs[1].hw.tiger.rec) {
- cs->bcs[1].hw.tiger.rec = NULL;
- }
+ kfree(cs->bcs[0].hw.tiger.send);
+ cs->bcs[0].hw.tiger.send = NULL;
+ cs->bcs[1].hw.tiger.send = NULL;
+ kfree(cs->bcs[0].hw.tiger.rec);
+ cs->bcs[0].hw.tiger.rec = NULL;
+ cs->bcs[1].hw.tiger.rec = NULL;
}
void
diff --git a/drivers/isdn/hisax/st5481_init.c b/drivers/isdn/hisax/st5481_init.c
index 2cf5d1a6df6c..8e192a3a3490 100644
--- a/drivers/isdn/hisax/st5481_init.c
+++ b/drivers/isdn/hisax/st5481_init.c
@@ -25,7 +25,6 @@
*/
#include <linux/config.h>
-#include <linux/version.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/usb.h>
diff --git a/drivers/isdn/hisax/st5481_usb.c b/drivers/isdn/hisax/st5481_usb.c
index 89fbeb58485d..b096b64b0253 100644
--- a/drivers/isdn/hisax/st5481_usb.c
+++ b/drivers/isdn/hisax/st5481_usb.c
@@ -335,14 +335,12 @@ void st5481_release_usb(struct st5481_adapter *adapter)
// Stop and free Control and Interrupt URBs
usb_kill_urb(ctrl->urb);
- if (ctrl->urb->transfer_buffer)
- kfree(ctrl->urb->transfer_buffer);
+ kfree(ctrl->urb->transfer_buffer);
usb_free_urb(ctrl->urb);
ctrl->urb = NULL;
usb_kill_urb(intr->urb);
- if (intr->urb->transfer_buffer)
- kfree(intr->urb->transfer_buffer);
+ kfree(intr->urb->transfer_buffer);
usb_free_urb(intr->urb);
ctrl->urb = NULL;
}
@@ -457,8 +455,7 @@ st5481_setup_isocpipes(struct urb* urb[2], struct usb_device *dev,
err:
for (j = 0; j < 2; j++) {
if (urb[j]) {
- if (urb[j]->transfer_buffer)
- kfree(urb[j]->transfer_buffer);
+ kfree(urb[j]->transfer_buffer);
urb[j]->transfer_buffer = NULL;
usb_free_urb(urb[j]);
urb[j] = NULL;
@@ -473,8 +470,7 @@ void st5481_release_isocpipes(struct urb* urb[2])
for (j = 0; j < 2; j++) {
usb_kill_urb(urb[j]);
- if (urb[j]->transfer_buffer)
- kfree(urb[j]->transfer_buffer);
+ kfree(urb[j]->transfer_buffer);
usb_free_urb(urb[j]);
urb[j] = NULL;
}
diff --git a/drivers/isdn/hisax/w6692.c b/drivers/isdn/hisax/w6692.c
index 7baf8e488471..0352ee5f706c 100644
--- a/drivers/isdn/hisax/w6692.c
+++ b/drivers/isdn/hisax/w6692.c
@@ -819,14 +819,10 @@ close_w6692state(struct BCState *bcs)
{
W6692Bmode(bcs, 0, bcs->channel);
if (test_and_clear_bit(BC_FLG_INIT, &bcs->Flag)) {
- if (bcs->hw.w6692.rcvbuf) {
- kfree(bcs->hw.w6692.rcvbuf);
- bcs->hw.w6692.rcvbuf = NULL;
- }
- if (bcs->blog) {
- kfree(bcs->blog);
- bcs->blog = NULL;
- }
+ kfree(bcs->hw.w6692.rcvbuf);
+ bcs->hw.w6692.rcvbuf = NULL;
+ kfree(bcs->blog);
+ bcs->blog = NULL;
skb_queue_purge(&bcs->rqueue);
skb_queue_purge(&bcs->squeue);
if (bcs->tx_skb) {
diff --git a/drivers/isdn/hysdn/hycapi.c b/drivers/isdn/hysdn/hycapi.c
index 1fd3d4e5f284..acc1d3cceebb 100644
--- a/drivers/isdn/hysdn/hycapi.c
+++ b/drivers/isdn/hysdn/hycapi.c
@@ -11,7 +11,6 @@
*/
#include <linux/module.h>
-#include <linux/version.h>
#include <linux/signal.h>
#include <linux/kernel.h>
#include <linux/skbuff.h>
diff --git a/drivers/isdn/hysdn/hysdn_init.c b/drivers/isdn/hysdn/hysdn_init.c
index 12c8137b5161..cb791f8e793a 100644
--- a/drivers/isdn/hysdn/hysdn_init.c
+++ b/drivers/isdn/hysdn/hysdn_init.c
@@ -13,7 +13,6 @@
#include <linux/config.h>
#include <linux/module.h>
#include <linux/init.h>
-#include <linux/version.h>
#include <linux/poll.h>
#include <linux/vmalloc.h>
#include <linux/slab.h>
diff --git a/drivers/isdn/hysdn/hysdn_net.c b/drivers/isdn/hysdn/hysdn_net.c
index babec8157ae6..aa01628d74c6 100644
--- a/drivers/isdn/hysdn/hysdn_net.c
+++ b/drivers/isdn/hysdn/hysdn_net.c
@@ -14,7 +14,6 @@
*/
#include <linux/module.h>
-#include <linux/version.h>
#include <linux/signal.h>
#include <linux/kernel.h>
#include <linux/netdevice.h>
diff --git a/drivers/isdn/hysdn/hysdn_procconf.c b/drivers/isdn/hysdn/hysdn_procconf.c
index 639582f61f41..40e56143c768 100644
--- a/drivers/isdn/hysdn/hysdn_procconf.c
+++ b/drivers/isdn/hysdn/hysdn_procconf.c
@@ -12,7 +12,6 @@
*/
#include <linux/module.h>
-#include <linux/version.h>
#include <linux/poll.h>
#include <linux/proc_fs.h>
#include <linux/pci.h>
@@ -359,8 +358,7 @@ hysdn_conf_close(struct inode *ino, struct file *filep)
} else if ((filep->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ) {
/* read access -> output card info data */
- if (filep->private_data)
- kfree(filep->private_data); /* release memory */
+ kfree(filep->private_data); /* release memory */
}
unlock_kernel();
return (retval);
diff --git a/drivers/isdn/hysdn/hysdn_proclog.c b/drivers/isdn/hysdn/hysdn_proclog.c
index 4d57011c5737..6c26f1efabd5 100644
--- a/drivers/isdn/hysdn/hysdn_proclog.c
+++ b/drivers/isdn/hysdn/hysdn_proclog.c
@@ -11,7 +11,6 @@
*/
#include <linux/module.h>
-#include <linux/version.h>
#include <linux/poll.h>
#include <linux/proc_fs.h>
#include <linux/pci.h>
diff --git a/drivers/isdn/i4l/isdn_common.c b/drivers/isdn/i4l/isdn_common.c
index 8a7d54a5c97d..4643df097bfe 100644
--- a/drivers/isdn/i4l/isdn_common.c
+++ b/drivers/isdn/i4l/isdn_common.c
@@ -14,7 +14,6 @@
#include <linux/config.h>
#include <linux/module.h>
#include <linux/init.h>
-#include <linux/version.h>
#include <linux/poll.h>
#include <linux/vmalloc.h>
#include <linux/isdn.h>
diff --git a/drivers/isdn/i4l/isdn_ppp.c b/drivers/isdn/i4l/isdn_ppp.c
index d97a9be5469c..1a19a0f89428 100644
--- a/drivers/isdn/i4l/isdn_ppp.c
+++ b/drivers/isdn/i4l/isdn_ppp.c
@@ -364,10 +364,8 @@ isdn_ppp_release(int min, struct file *file)
isdn_net_hangup(&p->dev);
}
for (i = 0; i < NUM_RCV_BUFFS; i++) {
- if (is->rq[i].buf) {
- kfree(is->rq[i].buf);
- is->rq[i].buf = NULL;
- }
+ kfree(is->rq[i].buf);
+ is->rq[i].buf = NULL;
}
is->first = is->rq + NUM_RCV_BUFFS - 1; /* receive queue */
is->last = is->rq;
@@ -378,14 +376,10 @@ isdn_ppp_release(int min, struct file *file)
is->slcomp = NULL;
#endif
#ifdef CONFIG_IPPP_FILTER
- if (is->pass_filter) {
- kfree(is->pass_filter);
- is->pass_filter = NULL;
- }
- if (is->active_filter) {
- kfree(is->active_filter);
- is->active_filter = NULL;
- }
+ kfree(is->pass_filter);
+ is->pass_filter = NULL;
+ kfree(is->active_filter);
+ is->active_filter = NULL;
#endif
/* TODO: if this was the previous master: link the stuff to the new master */
@@ -914,8 +908,7 @@ isdn_ppp_cleanup(void)
kfree(ippp_table[i]);
#ifdef CONFIG_ISDN_MPP
- if (isdn_ppp_bundle_arr)
- kfree(isdn_ppp_bundle_arr);
+ kfree(isdn_ppp_bundle_arr);
#endif /* CONFIG_ISDN_MPP */
}
diff --git a/drivers/isdn/i4l/isdn_tty.c b/drivers/isdn/i4l/isdn_tty.c
index b37ef1f06b3d..8c404b4e2482 100644
--- a/drivers/isdn/i4l/isdn_tty.c
+++ b/drivers/isdn/i4l/isdn_tty.c
@@ -712,22 +712,14 @@ isdn_tty_modem_hup(modem_info * info, int local)
#endif
info->emu.vpar[4] = 0;
info->emu.vpar[5] = 8;
- if (info->dtmf_state) {
- kfree(info->dtmf_state);
- info->dtmf_state = NULL;
- }
- if (info->silence_state) {
- kfree(info->silence_state);
- info->silence_state = NULL;
- }
- if (info->adpcms) {
- kfree(info->adpcms);
- info->adpcms = NULL;
- }
- if (info->adpcmr) {
- kfree(info->adpcmr);
- info->adpcmr = NULL;
- }
+ kfree(info->dtmf_state);
+ info->dtmf_state = NULL;
+ kfree(info->silence_state);
+ info->silence_state = NULL;
+ kfree(info->adpcms);
+ info->adpcms = NULL;
+ kfree(info->adpcmr);
+ info->adpcmr = NULL;
#endif
if ((info->msr & UART_MSR_RI) &&
(info->emu.mdmreg[REG_RUNG] & BIT_RUNG))
@@ -1721,8 +1713,7 @@ isdn_tty_close(struct tty_struct *tty, struct file *filp)
*/
timeout = jiffies + HZ;
while (!(info->lsr & UART_LSR_TEMT)) {
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(20);
+ schedule_timeout_interruptible(20);
if (time_after(jiffies,timeout))
break;
}
diff --git a/drivers/isdn/icn/icn.c b/drivers/isdn/icn/icn.c
index 386df71eee74..6649f8bc9951 100644
--- a/drivers/isdn/icn/icn.c
+++ b/drivers/isdn/icn/icn.c
@@ -947,8 +947,7 @@ icn_loadproto(u_char __user * buffer, icn_card * card)
icn_maprelease_channel(card, 0);
return -EIO;
}
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(10);
+ schedule_timeout_interruptible(10);
}
}
writeb(0x20, &sbuf_n);
diff --git a/drivers/isdn/icn/icn.h b/drivers/isdn/icn/icn.h
index 9028cc3b5071..7d7245fb0b32 100644
--- a/drivers/isdn/icn/icn.h
+++ b/drivers/isdn/icn/icn.h
@@ -35,7 +35,6 @@ typedef struct icn_cdef {
#ifdef __KERNEL__
/* Kernel includes */
-#include <linux/version.h>
#include <linux/errno.h>
#include <linux/fs.h>
#include <linux/major.h>
diff --git a/drivers/isdn/isdnloop/isdnloop.c b/drivers/isdn/isdnloop/isdnloop.c
index 14e1f8fbc61f..33d339700411 100644
--- a/drivers/isdn/isdnloop/isdnloop.c
+++ b/drivers/isdn/isdnloop/isdnloop.c
@@ -1161,12 +1161,9 @@ isdnloop_command(isdn_ctrl * c, isdnloop_card * card)
if (a) {
if (!card->leased) {
card->leased = 1;
- while (card->ptype == ISDN_PTYPE_UNKNOWN) {
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(10);
- }
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(10);
+ while (card->ptype == ISDN_PTYPE_UNKNOWN)
+ schedule_timeout_interruptible(10);
+ schedule_timeout_interruptible(10);
sprintf(cbuf, "00;FV2ON\n01;EAZ1\n02;EAZ2\n");
i = isdnloop_writecmd(cbuf, strlen(cbuf), 0, card);
printk(KERN_INFO
diff --git a/drivers/isdn/isdnloop/isdnloop.h b/drivers/isdn/isdnloop/isdnloop.h
index 8fb7bc1bfe0f..d699fe53e1c3 100644
--- a/drivers/isdn/isdnloop/isdnloop.h
+++ b/drivers/isdn/isdnloop/isdnloop.h
@@ -33,7 +33,6 @@ typedef struct isdnloop_sdef {
#ifdef __KERNEL__
/* Kernel includes */
-#include <linux/version.h>
#include <linux/errno.h>
#include <linux/fs.h>
#include <linux/major.h>
diff --git a/drivers/isdn/pcbit/drv.c b/drivers/isdn/pcbit/drv.c
index 5de861f40816..94f21486bb24 100644
--- a/drivers/isdn/pcbit/drv.c
+++ b/drivers/isdn/pcbit/drv.c
@@ -561,10 +561,8 @@ void pcbit_l3_receive(struct pcbit_dev * dev, ulong msg,
else
pcbit_fsm_event(dev, chan, EV_USR_RELEASE_REQ, NULL);
- if (cbdata.data.setup.CalledPN)
- kfree(cbdata.data.setup.CalledPN);
- if (cbdata.data.setup.CallingPN)
- kfree(cbdata.data.setup.CallingPN);
+ kfree(cbdata.data.setup.CalledPN);
+ kfree(cbdata.data.setup.CallingPN);
break;
case MSG_CONN_CONF:
diff --git a/drivers/isdn/sc/includes.h b/drivers/isdn/sc/includes.h
index 4611da6e9231..5286e0c810a9 100644
--- a/drivers/isdn/sc/includes.h
+++ b/drivers/isdn/sc/includes.h
@@ -4,7 +4,6 @@
*
*/
-#include <linux/version.h>
#include <linux/errno.h>
#include <asm/io.h>
#include <linux/delay.h>
diff --git a/drivers/isdn/sc/init.c b/drivers/isdn/sc/init.c
index 1ebed041672d..62b7acfad8a4 100644
--- a/drivers/isdn/sc/init.c
+++ b/drivers/isdn/sc/init.c
@@ -529,8 +529,7 @@ static int identify_board(unsigned long rambase, unsigned int iobase)
*/
x = 0;
while((inb(iobase + FIFOSTAT_OFFSET) & RF_HAS_DATA) && x < 100) {
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(1);
+ schedule_timeout_interruptible(1);
x++;
}
if(x == 100) {
diff --git a/drivers/isdn/sc/message.c b/drivers/isdn/sc/message.c
index ca204da3257d..0a0fe6b8039b 100644
--- a/drivers/isdn/sc/message.c
+++ b/drivers/isdn/sc/message.c
@@ -208,8 +208,7 @@ int send_and_receive(int card,
tries = 0;
/* wait for the response */
while (tries < timeout) {
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(1);
+ schedule_timeout_interruptible(1);
pr_debug("SAR waiting..\n");
diff --git a/drivers/macintosh/Kconfig b/drivers/macintosh/Kconfig
index bc3e096d84f7..a0ea44c3e8b1 100644
--- a/drivers/macintosh/Kconfig
+++ b/drivers/macintosh/Kconfig
@@ -169,6 +169,25 @@ config THERM_PM72
This driver provides thermostat and fan control for the desktop
G5 machines.
+config WINDFARM
+ tristate "New PowerMac thermal control infrastructure"
+
+config WINDFARM_PM81
+ tristate "Support for thermal management on iMac G5"
+ depends on WINDFARM && I2C && CPU_FREQ_PMAC64 && PMAC_SMU
+ select I2C_PMAC_SMU
+ help
+ This driver provides thermal control for the iMacG5
+
+config WINDFARM_PM91
+ tristate "Support for thermal management on PowerMac9,1"
+ depends on WINDFARM && I2C && CPU_FREQ_PMAC64 && PMAC_SMU
+ select I2C_PMAC_SMU
+ help
+ This driver provides thermal control for the PowerMac9,1
+ which is the recent (SMU based) single CPU desktop G5
+
+
config ANSLCD
tristate "Support for ANS LCD display"
depends on ADB_CUDA && PPC_PMAC
diff --git a/drivers/macintosh/Makefile b/drivers/macintosh/Makefile
index 236291bd48a4..f4657aa81fb0 100644
--- a/drivers/macintosh/Makefile
+++ b/drivers/macintosh/Makefile
@@ -26,3 +26,12 @@ obj-$(CONFIG_ADB_MACIO) += macio-adb.o
obj-$(CONFIG_THERM_PM72) += therm_pm72.o
obj-$(CONFIG_THERM_WINDTUNNEL) += therm_windtunnel.o
obj-$(CONFIG_THERM_ADT746X) += therm_adt746x.o
+obj-$(CONFIG_WINDFARM) += windfarm_core.o
+obj-$(CONFIG_WINDFARM_PM81) += windfarm_smu_controls.o \
+ windfarm_smu_sensors.o \
+ windfarm_lm75_sensor.o windfarm_pid.o \
+ windfarm_cpufreq_clamp.o windfarm_pm81.o
+obj-$(CONFIG_WINDFARM_PM91) += windfarm_smu_controls.o \
+ windfarm_smu_sensors.o \
+ windfarm_lm75_sensor.o windfarm_pid.o \
+ windfarm_cpufreq_clamp.o windfarm_pm91.o
diff --git a/drivers/macintosh/adb.c b/drivers/macintosh/adb.c
index c0dc1e3fa58b..d2ead1776c16 100644
--- a/drivers/macintosh/adb.c
+++ b/drivers/macintosh/adb.c
@@ -905,5 +905,5 @@ adbdev_init(void)
adb_dev_class = class_create(THIS_MODULE, "adb");
if (IS_ERR(adb_dev_class))
return;
- class_device_create(adb_dev_class, MKDEV(ADB_MAJOR, 0), NULL, "adb");
+ class_device_create(adb_dev_class, NULL, MKDEV(ADB_MAJOR, 0), NULL, "adb");
}
diff --git a/drivers/macintosh/adbhid.c b/drivers/macintosh/adbhid.c
index db654e8bd67e..c0b46bceb5df 100644
--- a/drivers/macintosh/adbhid.c
+++ b/drivers/macintosh/adbhid.c
@@ -206,7 +206,7 @@ u8 adb_to_linux_keycodes[128] = {
};
struct adbhid {
- struct input_dev input;
+ struct input_dev *input;
int id;
int default_id;
int original_handler_id;
@@ -291,10 +291,10 @@ adbhid_input_keycode(int id, int keycode, int repeat, struct pt_regs *regs)
switch (keycode) {
case ADB_KEY_CAPSLOCK: /* Generate down/up events for CapsLock everytime. */
- input_regs(&ahid->input, regs);
- input_report_key(&ahid->input, KEY_CAPSLOCK, 1);
- input_report_key(&ahid->input, KEY_CAPSLOCK, 0);
- input_sync(&ahid->input);
+ input_regs(ahid->input, regs);
+ input_report_key(ahid->input, KEY_CAPSLOCK, 1);
+ input_report_key(ahid->input, KEY_CAPSLOCK, 0);
+ input_sync(ahid->input);
return;
#ifdef CONFIG_PPC_PMAC
case ADB_KEY_POWER_OLD: /* Power key on PBook 3400 needs remapping */
@@ -347,10 +347,10 @@ adbhid_input_keycode(int id, int keycode, int repeat, struct pt_regs *regs)
}
if (adbhid[id]->keycode[keycode]) {
- input_regs(&adbhid[id]->input, regs);
- input_report_key(&adbhid[id]->input,
+ input_regs(adbhid[id]->input, regs);
+ input_report_key(adbhid[id]->input,
adbhid[id]->keycode[keycode], !up_flag);
- input_sync(&adbhid[id]->input);
+ input_sync(adbhid[id]->input);
} else
printk(KERN_INFO "Unhandled ADB key (scancode %#02x) %s.\n", keycode,
up_flag ? "released" : "pressed");
@@ -441,20 +441,20 @@ adbhid_mouse_input(unsigned char *data, int nb, struct pt_regs *regs, int autopo
break;
}
- input_regs(&adbhid[id]->input, regs);
+ input_regs(adbhid[id]->input, regs);
- input_report_key(&adbhid[id]->input, BTN_LEFT, !((data[1] >> 7) & 1));
- input_report_key(&adbhid[id]->input, BTN_MIDDLE, !((data[2] >> 7) & 1));
+ input_report_key(adbhid[id]->input, BTN_LEFT, !((data[1] >> 7) & 1));
+ input_report_key(adbhid[id]->input, BTN_MIDDLE, !((data[2] >> 7) & 1));
if (nb >= 4 && adbhid[id]->mouse_kind != ADBMOUSE_TRACKPAD)
- input_report_key(&adbhid[id]->input, BTN_RIGHT, !((data[3] >> 7) & 1));
+ input_report_key(adbhid[id]->input, BTN_RIGHT, !((data[3] >> 7) & 1));
- input_report_rel(&adbhid[id]->input, REL_X,
+ input_report_rel(adbhid[id]->input, REL_X,
((data[2]&0x7f) < 64 ? (data[2]&0x7f) : (data[2]&0x7f)-128 ));
- input_report_rel(&adbhid[id]->input, REL_Y,
+ input_report_rel(adbhid[id]->input, REL_Y,
((data[1]&0x7f) < 64 ? (data[1]&0x7f) : (data[1]&0x7f)-128 ));
- input_sync(&adbhid[id]->input);
+ input_sync(adbhid[id]->input);
}
static void
@@ -467,7 +467,7 @@ adbhid_buttons_input(unsigned char *data, int nb, struct pt_regs *regs, int auto
return;
}
- input_regs(&adbhid[id]->input, regs);
+ input_regs(adbhid[id]->input, regs);
switch (adbhid[id]->original_handler_id) {
default:
@@ -477,19 +477,19 @@ adbhid_buttons_input(unsigned char *data, int nb, struct pt_regs *regs, int auto
switch (data[1] & 0x0f) {
case 0x0: /* microphone */
- input_report_key(&adbhid[id]->input, KEY_SOUND, down);
+ input_report_key(adbhid[id]->input, KEY_SOUND, down);
break;
case 0x1: /* mute */
- input_report_key(&adbhid[id]->input, KEY_MUTE, down);
+ input_report_key(adbhid[id]->input, KEY_MUTE, down);
break;
case 0x2: /* volume decrease */
- input_report_key(&adbhid[id]->input, KEY_VOLUMEDOWN, down);
+ input_report_key(adbhid[id]->input, KEY_VOLUMEDOWN, down);
break;
case 0x3: /* volume increase */
- input_report_key(&adbhid[id]->input, KEY_VOLUMEUP, down);
+ input_report_key(adbhid[id]->input, KEY_VOLUMEUP, down);
break;
default:
@@ -513,19 +513,19 @@ adbhid_buttons_input(unsigned char *data, int nb, struct pt_regs *regs, int auto
switch (data[1] & 0x0f) {
case 0x8: /* mute */
- input_report_key(&adbhid[id]->input, KEY_MUTE, down);
+ input_report_key(adbhid[id]->input, KEY_MUTE, down);
break;
case 0x7: /* volume decrease */
- input_report_key(&adbhid[id]->input, KEY_VOLUMEDOWN, down);
+ input_report_key(adbhid[id]->input, KEY_VOLUMEDOWN, down);
break;
case 0x6: /* volume increase */
- input_report_key(&adbhid[id]->input, KEY_VOLUMEUP, down);
+ input_report_key(adbhid[id]->input, KEY_VOLUMEUP, down);
break;
case 0xb: /* eject */
- input_report_key(&adbhid[id]->input, KEY_EJECTCD, down);
+ input_report_key(adbhid[id]->input, KEY_EJECTCD, down);
break;
case 0xa: /* brightness decrease */
@@ -539,7 +539,7 @@ adbhid_buttons_input(unsigned char *data, int nb, struct pt_regs *regs, int auto
}
}
#endif /* CONFIG_PMAC_BACKLIGHT */
- input_report_key(&adbhid[id]->input, KEY_BRIGHTNESSDOWN, down);
+ input_report_key(adbhid[id]->input, KEY_BRIGHTNESSDOWN, down);
break;
case 0x9: /* brightness increase */
@@ -553,19 +553,19 @@ adbhid_buttons_input(unsigned char *data, int nb, struct pt_regs *regs, int auto
}
}
#endif /* CONFIG_PMAC_BACKLIGHT */
- input_report_key(&adbhid[id]->input, KEY_BRIGHTNESSUP, down);
+ input_report_key(adbhid[id]->input, KEY_BRIGHTNESSUP, down);
break;
case 0xc: /* videomode switch */
- input_report_key(&adbhid[id]->input, KEY_SWITCHVIDEOMODE, down);
+ input_report_key(adbhid[id]->input, KEY_SWITCHVIDEOMODE, down);
break;
case 0xd: /* keyboard illumination toggle */
- input_report_key(&adbhid[id]->input, KEY_KBDILLUMTOGGLE, down);
+ input_report_key(adbhid[id]->input, KEY_KBDILLUMTOGGLE, down);
break;
case 0xe: /* keyboard illumination decrease */
- input_report_key(&adbhid[id]->input, KEY_KBDILLUMDOWN, down);
+ input_report_key(adbhid[id]->input, KEY_KBDILLUMDOWN, down);
break;
case 0xf:
@@ -573,7 +573,7 @@ adbhid_buttons_input(unsigned char *data, int nb, struct pt_regs *regs, int auto
case 0x8f:
case 0x0f:
/* keyboard illumination increase */
- input_report_key(&adbhid[id]->input, KEY_KBDILLUMUP, down);
+ input_report_key(adbhid[id]->input, KEY_KBDILLUMUP, down);
break;
case 0x7f:
@@ -596,7 +596,7 @@ adbhid_buttons_input(unsigned char *data, int nb, struct pt_regs *regs, int auto
break;
}
- input_sync(&adbhid[id]->input);
+ input_sync(adbhid[id]->input);
}
static struct adb_request led_request;
@@ -683,7 +683,7 @@ adb_message_handler(struct notifier_block *this, unsigned long code, void *x)
int i;
for (i = 1; i < 16; i++) {
if (adbhid[i])
- del_timer_sync(&adbhid[i]->input.timer);
+ del_timer_sync(&adbhid[i]->input->timer);
}
}
@@ -699,155 +699,165 @@ adb_message_handler(struct notifier_block *this, unsigned long code, void *x)
return NOTIFY_DONE;
}
-static void
+static int
adbhid_input_register(int id, int default_id, int original_handler_id,
int current_handler_id, int mouse_kind)
{
+ struct adbhid *hid;
+ struct input_dev *input_dev;
+ int err;
int i;
if (adbhid[id]) {
printk(KERN_ERR "Trying to reregister ADB HID on ID %d\n", id);
- return;
+ return -EEXIST;
}
- if (!(adbhid[id] = kmalloc(sizeof(struct adbhid), GFP_KERNEL)))
- return;
-
- memset(adbhid[id], 0, sizeof(struct adbhid));
- sprintf(adbhid[id]->phys, "adb%d:%d.%02x/input", id, default_id, original_handler_id);
+ adbhid[id] = hid = kzalloc(sizeof(struct adbhid), GFP_KERNEL);
+ input_dev = input_allocate_device();
+ if (!hid || !input_dev) {
+ err = -ENOMEM;
+ goto fail;
- init_input_dev(&adbhid[id]->input);
+ }
- adbhid[id]->id = default_id;
- adbhid[id]->original_handler_id = original_handler_id;
- adbhid[id]->current_handler_id = current_handler_id;
- adbhid[id]->mouse_kind = mouse_kind;
- adbhid[id]->flags = 0;
- adbhid[id]->input.private = adbhid[id];
- adbhid[id]->input.name = adbhid[id]->name;
- adbhid[id]->input.phys = adbhid[id]->phys;
- adbhid[id]->input.id.bustype = BUS_ADB;
- adbhid[id]->input.id.vendor = 0x0001;
- adbhid[id]->input.id.product = (id << 12) | (default_id << 8) | original_handler_id;
- adbhid[id]->input.id.version = 0x0100;
+ sprintf(hid->phys, "adb%d:%d.%02x/input", id, default_id, original_handler_id);
+
+ hid->input = input_dev;
+ hid->id = default_id;
+ hid->original_handler_id = original_handler_id;
+ hid->current_handler_id = current_handler_id;
+ hid->mouse_kind = mouse_kind;
+ hid->flags = 0;
+ input_dev->private = hid;
+ input_dev->name = hid->name;
+ input_dev->phys = hid->phys;
+ input_dev->id.bustype = BUS_ADB;
+ input_dev->id.vendor = 0x0001;
+ input_dev->id.product = (id << 12) | (default_id << 8) | original_handler_id;
+ input_dev->id.version = 0x0100;
switch (default_id) {
case ADB_KEYBOARD:
- if (!(adbhid[id]->keycode = kmalloc(sizeof(adb_to_linux_keycodes), GFP_KERNEL))) {
- kfree(adbhid[id]);
- return;
+ hid->keycode = kmalloc(sizeof(adb_to_linux_keycodes), GFP_KERNEL);
+ if (!hid->keycode) {
+ err = -ENOMEM;
+ goto fail;
}
- sprintf(adbhid[id]->name, "ADB keyboard");
+ sprintf(hid->name, "ADB keyboard");
- memcpy(adbhid[id]->keycode, adb_to_linux_keycodes, sizeof(adb_to_linux_keycodes));
+ memcpy(hid->keycode, adb_to_linux_keycodes, sizeof(adb_to_linux_keycodes));
printk(KERN_INFO "Detected ADB keyboard, type ");
switch (original_handler_id) {
default:
printk("<unknown>.\n");
- adbhid[id]->input.id.version = ADB_KEYBOARD_UNKNOWN;
+ input_dev->id.version = ADB_KEYBOARD_UNKNOWN;
break;
case 0x01: case 0x02: case 0x03: case 0x06: case 0x08:
case 0x0C: case 0x10: case 0x18: case 0x1B: case 0x1C:
case 0xC0: case 0xC3: case 0xC6:
printk("ANSI.\n");
- adbhid[id]->input.id.version = ADB_KEYBOARD_ANSI;
+ input_dev->id.version = ADB_KEYBOARD_ANSI;
break;
case 0x04: case 0x05: case 0x07: case 0x09: case 0x0D:
case 0x11: case 0x14: case 0x19: case 0x1D: case 0xC1:
case 0xC4: case 0xC7:
printk("ISO, swapping keys.\n");
- adbhid[id]->input.id.version = ADB_KEYBOARD_ISO;
- i = adbhid[id]->keycode[10];
- adbhid[id]->keycode[10] = adbhid[id]->keycode[50];
- adbhid[id]->keycode[50] = i;
+ input_dev->id.version = ADB_KEYBOARD_ISO;
+ i = hid->keycode[10];
+ hid->keycode[10] = hid->keycode[50];
+ hid->keycode[50] = i;
break;
case 0x12: case 0x15: case 0x16: case 0x17: case 0x1A:
case 0x1E: case 0xC2: case 0xC5: case 0xC8: case 0xC9:
printk("JIS.\n");
- adbhid[id]->input.id.version = ADB_KEYBOARD_JIS;
+ input_dev->id.version = ADB_KEYBOARD_JIS;
break;
}
for (i = 0; i < 128; i++)
- if (adbhid[id]->keycode[i])
- set_bit(adbhid[id]->keycode[i], adbhid[id]->input.keybit);
-
- adbhid[id]->input.evbit[0] = BIT(EV_KEY) | BIT(EV_LED) | BIT(EV_REP);
- adbhid[id]->input.ledbit[0] = BIT(LED_SCROLLL) | BIT(LED_CAPSL) | BIT(LED_NUML);
- adbhid[id]->input.event = adbhid_kbd_event;
- adbhid[id]->input.keycodemax = 127;
- adbhid[id]->input.keycodesize = 1;
+ if (hid->keycode[i])
+ set_bit(hid->keycode[i], input_dev->keybit);
+
+ input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_LED) | BIT(EV_REP);
+ input_dev->ledbit[0] = BIT(LED_SCROLLL) | BIT(LED_CAPSL) | BIT(LED_NUML);
+ input_dev->event = adbhid_kbd_event;
+ input_dev->keycodemax = 127;
+ input_dev->keycodesize = 1;
break;
case ADB_MOUSE:
- sprintf(adbhid[id]->name, "ADB mouse");
+ sprintf(hid->name, "ADB mouse");
- adbhid[id]->input.evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
- adbhid[id]->input.keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
- adbhid[id]->input.relbit[0] = BIT(REL_X) | BIT(REL_Y);
+ input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
+ input_dev->keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
+ input_dev->relbit[0] = BIT(REL_X) | BIT(REL_Y);
break;
case ADB_MISC:
switch (original_handler_id) {
case 0x02: /* Adjustable keyboard button device */
- sprintf(adbhid[id]->name, "ADB adjustable keyboard buttons");
- adbhid[id]->input.evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
- set_bit(KEY_SOUND, adbhid[id]->input.keybit);
- set_bit(KEY_MUTE, adbhid[id]->input.keybit);
- set_bit(KEY_VOLUMEUP, adbhid[id]->input.keybit);
- set_bit(KEY_VOLUMEDOWN, adbhid[id]->input.keybit);
+ sprintf(hid->name, "ADB adjustable keyboard buttons");
+ input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
+ set_bit(KEY_SOUND, input_dev->keybit);
+ set_bit(KEY_MUTE, input_dev->keybit);
+ set_bit(KEY_VOLUMEUP, input_dev->keybit);
+ set_bit(KEY_VOLUMEDOWN, input_dev->keybit);
break;
case 0x1f: /* Powerbook button device */
- sprintf(adbhid[id]->name, "ADB Powerbook buttons");
- adbhid[id]->input.evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
- set_bit(KEY_MUTE, adbhid[id]->input.keybit);
- set_bit(KEY_VOLUMEUP, adbhid[id]->input.keybit);
- set_bit(KEY_VOLUMEDOWN, adbhid[id]->input.keybit);
- set_bit(KEY_BRIGHTNESSUP, adbhid[id]->input.keybit);
- set_bit(KEY_BRIGHTNESSDOWN, adbhid[id]->input.keybit);
- set_bit(KEY_EJECTCD, adbhid[id]->input.keybit);
- set_bit(KEY_SWITCHVIDEOMODE, adbhid[id]->input.keybit);
- set_bit(KEY_KBDILLUMTOGGLE, adbhid[id]->input.keybit);
- set_bit(KEY_KBDILLUMDOWN, adbhid[id]->input.keybit);
- set_bit(KEY_KBDILLUMUP, adbhid[id]->input.keybit);
+ sprintf(hid->name, "ADB Powerbook buttons");
+ input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
+ set_bit(KEY_MUTE, input_dev->keybit);
+ set_bit(KEY_VOLUMEUP, input_dev->keybit);
+ set_bit(KEY_VOLUMEDOWN, input_dev->keybit);
+ set_bit(KEY_BRIGHTNESSUP, input_dev->keybit);
+ set_bit(KEY_BRIGHTNESSDOWN, input_dev->keybit);
+ set_bit(KEY_EJECTCD, input_dev->keybit);
+ set_bit(KEY_SWITCHVIDEOMODE, input_dev->keybit);
+ set_bit(KEY_KBDILLUMTOGGLE, input_dev->keybit);
+ set_bit(KEY_KBDILLUMDOWN, input_dev->keybit);
+ set_bit(KEY_KBDILLUMUP, input_dev->keybit);
break;
}
- if (adbhid[id]->name[0])
+ if (hid->name[0])
break;
/* else fall through */
default:
printk(KERN_INFO "Trying to register unknown ADB device to input layer.\n");
- kfree(adbhid[id]);
- return;
+ err = -ENODEV;
+ goto fail;
}
- adbhid[id]->input.keycode = adbhid[id]->keycode;
-
- input_register_device(&adbhid[id]->input);
+ input_dev->keycode = hid->keycode;
- printk(KERN_INFO "input: %s on %s\n",
- adbhid[id]->name, adbhid[id]->phys);
+ input_register_device(input_dev);
if (default_id == ADB_KEYBOARD) {
/* HACK WARNING!! This should go away as soon there is an utility
* to control that for event devices.
*/
- adbhid[id]->input.rep[REP_DELAY] = 500; /* input layer default: 250 */
- adbhid[id]->input.rep[REP_PERIOD] = 66; /* input layer default: 33 */
+ input_dev->rep[REP_DELAY] = 500; /* input layer default: 250 */
+ input_dev->rep[REP_PERIOD] = 66; /* input layer default: 33 */
}
+
+ return 0;
+
+ fail: input_free_device(input_dev);
+ kfree(hid);
+ adbhid[id] = NULL;
+ return err;
}
static void adbhid_input_unregister(int id)
{
- input_unregister_device(&adbhid[id]->input);
- if (adbhid[id]->keycode)
- kfree(adbhid[id]->keycode);
+ input_unregister_device(adbhid[id]->input);
+ kfree(adbhid[id]->keycode);
kfree(adbhid[id]);
adbhid[id] = NULL;
}
@@ -858,7 +868,7 @@ adbhid_input_reregister(int id, int default_id, int org_handler_id,
int cur_handler_id, int mk)
{
if (adbhid[id]) {
- if (adbhid[id]->input.id.product !=
+ if (adbhid[id]->input->id.product !=
((id << 12)|(default_id << 8)|org_handler_id)) {
adbhid_input_unregister(id);
adbhid_input_register(id, default_id, org_handler_id,
diff --git a/drivers/macintosh/ans-lcd.c b/drivers/macintosh/ans-lcd.c
index 5e0811dc6536..2b8a6e821d44 100644
--- a/drivers/macintosh/ans-lcd.c
+++ b/drivers/macintosh/ans-lcd.c
@@ -27,7 +27,7 @@ static volatile unsigned char __iomem *anslcd_ptr;
#undef DEBUG
-static void __pmac
+static void
anslcd_write_byte_ctrl ( unsigned char c )
{
#ifdef DEBUG
@@ -43,14 +43,14 @@ anslcd_write_byte_ctrl ( unsigned char c )
}
}
-static void __pmac
+static void
anslcd_write_byte_data ( unsigned char c )
{
out_8(anslcd_ptr + ANSLCD_DATA_IX, c);
udelay(anslcd_short_delay);
}
-static ssize_t __pmac
+static ssize_t
anslcd_write( struct file * file, const char __user * buf,
size_t count, loff_t *ppos )
{
@@ -73,7 +73,7 @@ anslcd_write( struct file * file, const char __user * buf,
return p - buf;
}
-static int __pmac
+static int
anslcd_ioctl( struct inode * inode, struct file * file,
unsigned int cmd, unsigned long arg )
{
@@ -115,7 +115,7 @@ anslcd_ioctl( struct inode * inode, struct file * file,
}
}
-static int __pmac
+static int
anslcd_open( struct inode * inode, struct file * file )
{
return 0;
diff --git a/drivers/macintosh/apm_emu.c b/drivers/macintosh/apm_emu.c
index 19d3e05d6825..e5a2bbf99399 100644
--- a/drivers/macintosh/apm_emu.c
+++ b/drivers/macintosh/apm_emu.c
@@ -430,8 +430,8 @@ static int apm_emu_get_info(char *buf, char **start, off_t fpos, int length)
-1: Unknown
8) min = minutes; sec = seconds */
- unsigned short ac_line_status = 0xff;
- unsigned short battery_status = 0xff;
+ unsigned short ac_line_status;
+ unsigned short battery_status = 0;
unsigned short battery_flag = 0xff;
int percentage = -1;
int time_units = -1;
@@ -446,6 +446,7 @@ static int apm_emu_get_info(char *buf, char **start, off_t fpos, int length)
ac_line_status = ((pmu_power_flags & PMU_PWR_AC_PRESENT) != 0);
for (i=0; i<pmu_battery_count; i++) {
if (pmu_batteries[i].flags & PMU_BATT_PRESENT) {
+ battery_status++;
if (percentage < 0)
percentage = 0;
if (charge < 0)
@@ -461,6 +462,9 @@ static int apm_emu_get_info(char *buf, char **start, off_t fpos, int length)
charging++;
}
}
+ if (0 == battery_status)
+ ac_line_status = 1;
+ battery_status = 0xff;
if (real_count) {
if (amperage < 0) {
if (btype == PMU_BATT_TYPE_SMART)
diff --git a/drivers/macintosh/mac_hid.c b/drivers/macintosh/mac_hid.c
index 5ad3a5a9eb7f..a66636116f0b 100644
--- a/drivers/macintosh/mac_hid.c
+++ b/drivers/macintosh/mac_hid.c
@@ -16,8 +16,8 @@
#include <linux/module.h>
-static struct input_dev emumousebtn;
-static void emumousebtn_input_register(void);
+static struct input_dev *emumousebtn;
+static int emumousebtn_input_register(void);
static int mouse_emulate_buttons = 0;
static int mouse_button2_keycode = KEY_RIGHTCTRL; /* right control key */
static int mouse_button3_keycode = KEY_RIGHTALT; /* right option key */
@@ -90,10 +90,10 @@ int mac_hid_mouse_emulate_buttons(int caller, unsigned int keycode, int down)
&& (keycode == mouse_button2_keycode
|| keycode == mouse_button3_keycode)) {
if (mouse_emulate_buttons == 1) {
- input_report_key(&emumousebtn,
+ input_report_key(emumousebtn,
keycode == mouse_button2_keycode ? BTN_MIDDLE : BTN_RIGHT,
down);
- input_sync(&emumousebtn);
+ input_sync(emumousebtn);
return 1;
}
mouse_last_keycode = down ? keycode : 0;
@@ -105,30 +105,34 @@ int mac_hid_mouse_emulate_buttons(int caller, unsigned int keycode, int down)
EXPORT_SYMBOL(mac_hid_mouse_emulate_buttons);
-static void emumousebtn_input_register(void)
+static int emumousebtn_input_register(void)
{
- emumousebtn.name = "Macintosh mouse button emulation";
+ emumousebtn = input_allocate_device();
+ if (!emumousebtn)
+ return -ENOMEM;
- init_input_dev(&emumousebtn);
+ emumousebtn->name = "Macintosh mouse button emulation";
+ emumousebtn->id.bustype = BUS_ADB;
+ emumousebtn->id.vendor = 0x0001;
+ emumousebtn->id.product = 0x0001;
+ emumousebtn->id.version = 0x0100;
- emumousebtn.evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
- emumousebtn.keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
- emumousebtn.relbit[0] = BIT(REL_X) | BIT(REL_Y);
+ emumousebtn->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
+ emumousebtn->keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
+ emumousebtn->relbit[0] = BIT(REL_X) | BIT(REL_Y);
- emumousebtn.id.bustype = BUS_ADB;
- emumousebtn.id.vendor = 0x0001;
- emumousebtn.id.product = 0x0001;
- emumousebtn.id.version = 0x0100;
+ input_register_device(emumousebtn);
- input_register_device(&emumousebtn);
-
- printk(KERN_INFO "input: Macintosh mouse button emulation\n");
+ return 0;
}
int __init mac_hid_init(void)
{
+ int err;
- emumousebtn_input_register();
+ err = emumousebtn_input_register();
+ if (err)
+ return err;
#if defined(CONFIG_SYSCTL)
mac_hid_sysctl_header = register_sysctl_table(mac_hid_root_dir, 1);
diff --git a/drivers/macintosh/macio_asic.c b/drivers/macintosh/macio_asic.c
index 1ee003346923..c34c96d18907 100644
--- a/drivers/macintosh/macio_asic.c
+++ b/drivers/macintosh/macio_asic.c
@@ -17,6 +17,8 @@
#include <linux/pci_ids.h>
#include <linux/init.h>
#include <linux/module.h>
+#include <linux/slab.h>
+
#include <asm/machdep.h>
#include <asm/macio.h>
#include <asm/pmac_feature.h>
diff --git a/drivers/macintosh/macio_sysfs.c b/drivers/macintosh/macio_sysfs.c
index 97d22bb4516a..7f7d4eaca870 100644
--- a/drivers/macintosh/macio_sysfs.c
+++ b/drivers/macintosh/macio_sysfs.c
@@ -39,6 +39,31 @@ compatible_show (struct device *dev, struct device_attribute *attr, char *buf)
return length;
}
+static ssize_t modalias_show (struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ struct of_device *of;
+ char *compat;
+ int cplen;
+ int length;
+
+ of = &to_macio_device (dev)->ofdev;
+ compat = (char *) get_property (of->node, "compatible", &cplen);
+ if (!compat) compat = "", cplen = 1;
+ length = sprintf (buf, "of:N%sT%s", of->node->name, of->node->type);
+ buf += length;
+ while (cplen > 0) {
+ int l;
+ length += sprintf (buf, "C%s", compat);
+ buf += length;
+ l = strlen (compat) + 1;
+ compat += l;
+ cplen -= l;
+ }
+
+ return length;
+}
+
macio_config_of_attr (name, "%s\n");
macio_config_of_attr (type, "%s\n");
@@ -46,5 +71,6 @@ struct device_attribute macio_dev_attrs[] = {
__ATTR_RO(name),
__ATTR_RO(type),
__ATTR_RO(compatible),
+ __ATTR_RO(modalias),
__ATTR_NULL
};
diff --git a/drivers/macintosh/mediabay.c b/drivers/macintosh/mediabay.c
index c0712a1ea5af..b856bb67169c 100644
--- a/drivers/macintosh/mediabay.c
+++ b/drivers/macintosh/mediabay.c
@@ -167,19 +167,19 @@ enum {
* Functions for polling content of media bay
*/
-static u8 __pmac
+static u8
ohare_mb_content(struct media_bay_info *bay)
{
return (MB_IN32(bay, OHARE_MBCR) >> 12) & 7;
}
-static u8 __pmac
+static u8
heathrow_mb_content(struct media_bay_info *bay)
{
return (MB_IN32(bay, HEATHROW_MBCR) >> 12) & 7;
}
-static u8 __pmac
+static u8
keylargo_mb_content(struct media_bay_info *bay)
{
int new_gpio;
@@ -205,7 +205,7 @@ keylargo_mb_content(struct media_bay_info *bay)
* into reset state as well
*/
-static void __pmac
+static void
ohare_mb_power(struct media_bay_info* bay, int on_off)
{
if (on_off) {
@@ -224,7 +224,7 @@ ohare_mb_power(struct media_bay_info* bay, int on_off)
MB_BIC(bay, OHARE_MBCR, 0x00000F00);
}
-static void __pmac
+static void
heathrow_mb_power(struct media_bay_info* bay, int on_off)
{
if (on_off) {
@@ -243,7 +243,7 @@ heathrow_mb_power(struct media_bay_info* bay, int on_off)
MB_BIC(bay, HEATHROW_MBCR, 0x00000F00);
}
-static void __pmac
+static void
keylargo_mb_power(struct media_bay_info* bay, int on_off)
{
if (on_off) {
@@ -267,7 +267,7 @@ keylargo_mb_power(struct media_bay_info* bay, int on_off)
* enable the related busses
*/
-static int __pmac
+static int
ohare_mb_setup_bus(struct media_bay_info* bay, u8 device_id)
{
switch(device_id) {
@@ -287,7 +287,7 @@ ohare_mb_setup_bus(struct media_bay_info* bay, u8 device_id)
return -ENODEV;
}
-static int __pmac
+static int
heathrow_mb_setup_bus(struct media_bay_info* bay, u8 device_id)
{
switch(device_id) {
@@ -307,7 +307,7 @@ heathrow_mb_setup_bus(struct media_bay_info* bay, u8 device_id)
return -ENODEV;
}
-static int __pmac
+static int
keylargo_mb_setup_bus(struct media_bay_info* bay, u8 device_id)
{
switch(device_id) {
@@ -330,43 +330,43 @@ keylargo_mb_setup_bus(struct media_bay_info* bay, u8 device_id)
* Functions for tweaking resets
*/
-static void __pmac
+static void
ohare_mb_un_reset(struct media_bay_info* bay)
{
MB_BIS(bay, OHARE_FCR, OH_BAY_RESET_N);
}
-static void __pmac keylargo_mb_init(struct media_bay_info *bay)
+static void keylargo_mb_init(struct media_bay_info *bay)
{
MB_BIS(bay, KEYLARGO_MBCR, KL_MBCR_MB0_ENABLE);
}
-static void __pmac heathrow_mb_un_reset(struct media_bay_info* bay)
+static void heathrow_mb_un_reset(struct media_bay_info* bay)
{
MB_BIS(bay, HEATHROW_FCR, HRW_BAY_RESET_N);
}
-static void __pmac keylargo_mb_un_reset(struct media_bay_info* bay)
+static void keylargo_mb_un_reset(struct media_bay_info* bay)
{
MB_BIS(bay, KEYLARGO_MBCR, KL_MBCR_MB0_DEV_RESET);
}
-static void __pmac ohare_mb_un_reset_ide(struct media_bay_info* bay)
+static void ohare_mb_un_reset_ide(struct media_bay_info* bay)
{
MB_BIS(bay, OHARE_FCR, OH_IDE1_RESET_N);
}
-static void __pmac heathrow_mb_un_reset_ide(struct media_bay_info* bay)
+static void heathrow_mb_un_reset_ide(struct media_bay_info* bay)
{
MB_BIS(bay, HEATHROW_FCR, HRW_IDE1_RESET_N);
}
-static void __pmac keylargo_mb_un_reset_ide(struct media_bay_info* bay)
+static void keylargo_mb_un_reset_ide(struct media_bay_info* bay)
{
MB_BIS(bay, KEYLARGO_FCR1, KL1_EIDE0_RESET_N);
}
-static inline void __pmac set_mb_power(struct media_bay_info* bay, int onoff)
+static inline void set_mb_power(struct media_bay_info* bay, int onoff)
{
/* Power up up and assert the bay reset line */
if (onoff) {
@@ -382,7 +382,7 @@ static inline void __pmac set_mb_power(struct media_bay_info* bay, int onoff)
bay->timer = msecs_to_jiffies(MB_POWER_DELAY);
}
-static void __pmac poll_media_bay(struct media_bay_info* bay)
+static void poll_media_bay(struct media_bay_info* bay)
{
int id = bay->ops->content(bay);
@@ -415,7 +415,7 @@ static void __pmac poll_media_bay(struct media_bay_info* bay)
}
}
-int __pmac check_media_bay(struct device_node *which_bay, int what)
+int check_media_bay(struct device_node *which_bay, int what)
{
#ifdef CONFIG_BLK_DEV_IDE
int i;
@@ -432,7 +432,7 @@ int __pmac check_media_bay(struct device_node *which_bay, int what)
}
EXPORT_SYMBOL(check_media_bay);
-int __pmac check_media_bay_by_base(unsigned long base, int what)
+int check_media_bay_by_base(unsigned long base, int what)
{
#ifdef CONFIG_BLK_DEV_IDE
int i;
@@ -449,7 +449,7 @@ int __pmac check_media_bay_by_base(unsigned long base, int what)
return -ENODEV;
}
-int __pmac media_bay_set_ide_infos(struct device_node* which_bay, unsigned long base,
+int media_bay_set_ide_infos(struct device_node* which_bay, unsigned long base,
int irq, int index)
{
#ifdef CONFIG_BLK_DEV_IDE
@@ -489,7 +489,7 @@ int __pmac media_bay_set_ide_infos(struct device_node* which_bay, unsigned long
return -ENODEV;
}
-static void __pmac media_bay_step(int i)
+static void media_bay_step(int i)
{
struct media_bay_info* bay = &media_bays[i];
@@ -619,7 +619,7 @@ static void __pmac media_bay_step(int i)
* with the IDE driver. It needs to be a thread because
* ide_register can't be called from interrupt context.
*/
-static int __pmac media_bay_task(void *x)
+static int media_bay_task(void *x)
{
int i;
@@ -704,7 +704,7 @@ static int __devinit media_bay_attach(struct macio_dev *mdev, const struct of_de
}
-static int __pmac media_bay_suspend(struct macio_dev *mdev, pm_message_t state)
+static int media_bay_suspend(struct macio_dev *mdev, pm_message_t state)
{
struct media_bay_info *bay = macio_get_drvdata(mdev);
@@ -719,7 +719,7 @@ static int __pmac media_bay_suspend(struct macio_dev *mdev, pm_message_t state)
return 0;
}
-static int __pmac media_bay_resume(struct macio_dev *mdev)
+static int media_bay_resume(struct macio_dev *mdev)
{
struct media_bay_info *bay = macio_get_drvdata(mdev);
@@ -760,7 +760,7 @@ static int __pmac media_bay_resume(struct macio_dev *mdev)
/* Definitions of "ops" structures.
*/
-static struct mb_ops ohare_mb_ops __pmacdata = {
+static struct mb_ops ohare_mb_ops = {
.name = "Ohare",
.content = ohare_mb_content,
.power = ohare_mb_power,
@@ -769,7 +769,7 @@ static struct mb_ops ohare_mb_ops __pmacdata = {
.un_reset_ide = ohare_mb_un_reset_ide,
};
-static struct mb_ops heathrow_mb_ops __pmacdata = {
+static struct mb_ops heathrow_mb_ops = {
.name = "Heathrow",
.content = heathrow_mb_content,
.power = heathrow_mb_power,
@@ -778,7 +778,7 @@ static struct mb_ops heathrow_mb_ops __pmacdata = {
.un_reset_ide = heathrow_mb_un_reset_ide,
};
-static struct mb_ops keylargo_mb_ops __pmacdata = {
+static struct mb_ops keylargo_mb_ops = {
.name = "KeyLargo",
.init = keylargo_mb_init,
.content = keylargo_mb_content,
diff --git a/drivers/macintosh/smu.c b/drivers/macintosh/smu.c
index 9b38674fbf75..e8378274d710 100644
--- a/drivers/macintosh/smu.c
+++ b/drivers/macintosh/smu.c
@@ -47,13 +47,13 @@
#include <asm/uaccess.h>
#include <asm/of_device.h>
-#define VERSION "0.6"
+#define VERSION "0.7"
#define AUTHOR "(c) 2005 Benjamin Herrenschmidt, IBM Corp."
#undef DEBUG_SMU
#ifdef DEBUG_SMU
-#define DPRINTK(fmt, args...) do { printk(KERN_DEBUG fmt , ##args); } while (0)
+#define DPRINTK(fmt, args...) do { udbg_printf(KERN_DEBUG fmt , ##args); } while (0)
#else
#define DPRINTK(fmt, args...) do { } while (0)
#endif
@@ -92,7 +92,7 @@ struct smu_device {
* for now, just hard code that
*/
static struct smu_device *smu;
-
+static DECLARE_MUTEX(smu_part_access);
/*
* SMU driver low level stuff
@@ -113,9 +113,11 @@ static void smu_start_cmd(void)
DPRINTK("SMU: starting cmd %x, %d bytes data\n", cmd->cmd,
cmd->data_len);
- DPRINTK("SMU: data buffer: %02x %02x %02x %02x ...\n",
+ DPRINTK("SMU: data buffer: %02x %02x %02x %02x %02x %02x %02x %02x\n",
((u8 *)cmd->data_buf)[0], ((u8 *)cmd->data_buf)[1],
- ((u8 *)cmd->data_buf)[2], ((u8 *)cmd->data_buf)[3]);
+ ((u8 *)cmd->data_buf)[2], ((u8 *)cmd->data_buf)[3],
+ ((u8 *)cmd->data_buf)[4], ((u8 *)cmd->data_buf)[5],
+ ((u8 *)cmd->data_buf)[6], ((u8 *)cmd->data_buf)[7]);
/* Fill the SMU command buffer */
smu->cmd_buf->cmd = cmd->cmd;
@@ -440,7 +442,7 @@ int smu_present(void)
EXPORT_SYMBOL(smu_present);
-int smu_init (void)
+int __init smu_init (void)
{
struct device_node *np;
u32 *data;
@@ -588,6 +590,8 @@ static void smu_expose_childs(void *unused)
sprintf(name, "smu-i2c-%02x", *reg);
of_platform_device_create(np, name, &smu->of_dev->dev);
}
+ if (device_is_compatible(np, "smu-sensors"))
+ of_platform_device_create(np, "smu-sensors", &smu->of_dev->dev);
}
}
@@ -845,6 +849,156 @@ int smu_queue_i2c(struct smu_i2c_cmd *cmd)
return 0;
}
+/*
+ * Handling of "partitions"
+ */
+
+static int smu_read_datablock(u8 *dest, unsigned int addr, unsigned int len)
+{
+ DECLARE_COMPLETION(comp);
+ unsigned int chunk;
+ struct smu_cmd cmd;
+ int rc;
+ u8 params[8];
+
+ /* We currently use a chunk size of 0xe. We could check the
+ * SMU firmware version and use bigger sizes though
+ */
+ chunk = 0xe;
+
+ while (len) {
+ unsigned int clen = min(len, chunk);
+
+ cmd.cmd = SMU_CMD_MISC_ee_COMMAND;
+ cmd.data_len = 7;
+ cmd.data_buf = params;
+ cmd.reply_len = chunk;
+ cmd.reply_buf = dest;
+ cmd.done = smu_done_complete;
+ cmd.misc = &comp;
+ params[0] = SMU_CMD_MISC_ee_GET_DATABLOCK_REC;
+ params[1] = 0x4;
+ *((u32 *)&params[2]) = addr;
+ params[6] = clen;
+
+ rc = smu_queue_cmd(&cmd);
+ if (rc)
+ return rc;
+ wait_for_completion(&comp);
+ if (cmd.status != 0)
+ return rc;
+ if (cmd.reply_len != clen) {
+ printk(KERN_DEBUG "SMU: short read in "
+ "smu_read_datablock, got: %d, want: %d\n",
+ cmd.reply_len, clen);
+ return -EIO;
+ }
+ len -= clen;
+ addr += clen;
+ dest += clen;
+ }
+ return 0;
+}
+
+static struct smu_sdbp_header *smu_create_sdb_partition(int id)
+{
+ DECLARE_COMPLETION(comp);
+ struct smu_simple_cmd cmd;
+ unsigned int addr, len, tlen;
+ struct smu_sdbp_header *hdr;
+ struct property *prop;
+
+ /* First query the partition info */
+ smu_queue_simple(&cmd, SMU_CMD_PARTITION_COMMAND, 2,
+ smu_done_complete, &comp,
+ SMU_CMD_PARTITION_LATEST, id);
+ wait_for_completion(&comp);
+
+ /* Partition doesn't exist (or other error) */
+ if (cmd.cmd.status != 0 || cmd.cmd.reply_len != 6)
+ return NULL;
+
+ /* Fetch address and length from reply */
+ addr = *((u16 *)cmd.buffer);
+ len = cmd.buffer[3] << 2;
+ /* Calucluate total length to allocate, including the 17 bytes
+ * for "sdb-partition-XX" that we append at the end of the buffer
+ */
+ tlen = sizeof(struct property) + len + 18;
+
+ prop = kcalloc(tlen, 1, GFP_KERNEL);
+ if (prop == NULL)
+ return NULL;
+ hdr = (struct smu_sdbp_header *)(prop + 1);
+ prop->name = ((char *)prop) + tlen - 18;
+ sprintf(prop->name, "sdb-partition-%02x", id);
+ prop->length = len;
+ prop->value = (unsigned char *)hdr;
+ prop->next = NULL;
+
+ /* Read the datablock */
+ if (smu_read_datablock((u8 *)hdr, addr, len)) {
+ printk(KERN_DEBUG "SMU: datablock read failed while reading "
+ "partition %02x !\n", id);
+ goto failure;
+ }
+
+ /* Got it, check a few things and create the property */
+ if (hdr->id != id) {
+ printk(KERN_DEBUG "SMU: Reading partition %02x and got "
+ "%02x !\n", id, hdr->id);
+ goto failure;
+ }
+ if (prom_add_property(smu->of_node, prop)) {
+ printk(KERN_DEBUG "SMU: Failed creating sdb-partition-%02x "
+ "property !\n", id);
+ goto failure;
+ }
+
+ return hdr;
+ failure:
+ kfree(prop);
+ return NULL;
+}
+
+/* Note: Only allowed to return error code in pointers (using ERR_PTR)
+ * when interruptible is 1
+ */
+struct smu_sdbp_header *__smu_get_sdb_partition(int id, unsigned int *size,
+ int interruptible)
+{
+ char pname[32];
+ struct smu_sdbp_header *part;
+
+ if (!smu)
+ return NULL;
+
+ sprintf(pname, "sdb-partition-%02x", id);
+
+ if (interruptible) {
+ int rc;
+ rc = down_interruptible(&smu_part_access);
+ if (rc)
+ return ERR_PTR(rc);
+ } else
+ down(&smu_part_access);
+
+ part = (struct smu_sdbp_header *)get_property(smu->of_node,
+ pname, size);
+ if (part == NULL) {
+ part = smu_create_sdb_partition(id);
+ if (part != NULL && size)
+ *size = part->len << 2;
+ }
+ up(&smu_part_access);
+ return part;
+}
+
+struct smu_sdbp_header *smu_get_sdb_partition(int id, unsigned int *size)
+{
+ return __smu_get_sdb_partition(id, size, 0);
+}
+EXPORT_SYMBOL(smu_get_sdb_partition);
/*
@@ -918,6 +1072,14 @@ static ssize_t smu_write(struct file *file, const char __user *buf,
else if (hdr.cmdtype == SMU_CMDTYPE_WANTS_EVENTS) {
pp->mode = smu_file_events;
return 0;
+ } else if (hdr.cmdtype == SMU_CMDTYPE_GET_PARTITION) {
+ struct smu_sdbp_header *part;
+ part = __smu_get_sdb_partition(hdr.cmd, NULL, 1);
+ if (part == NULL)
+ return -EINVAL;
+ else if (IS_ERR(part))
+ return PTR_ERR(part);
+ return 0;
} else if (hdr.cmdtype != SMU_CMDTYPE_SMU)
return -EINVAL;
else if (pp->mode != smu_file_commands)
@@ -1094,7 +1256,7 @@ static int smu_release(struct inode *inode, struct file *file)
}
-static struct file_operations smu_device_fops __pmacdata = {
+static struct file_operations smu_device_fops = {
.llseek = no_llseek,
.read = smu_read,
.write = smu_write,
@@ -1103,7 +1265,7 @@ static struct file_operations smu_device_fops __pmacdata = {
.release = smu_release,
};
-static struct miscdevice pmu_device __pmacdata = {
+static struct miscdevice pmu_device = {
MISC_DYNAMIC_MINOR, "smu", &smu_device_fops
};
diff --git a/drivers/macintosh/therm_pm72.c b/drivers/macintosh/therm_pm72.c
index cc507ceef153..3fc8cdd94c3d 100644
--- a/drivers/macintosh/therm_pm72.c
+++ b/drivers/macintosh/therm_pm72.c
@@ -1678,10 +1678,9 @@ static int main_control_loop(void *x)
}
// FIXME: Deal with signals
- set_current_state(TASK_INTERRUPTIBLE);
elapsed = jiffies - start;
if (elapsed < HZ)
- schedule_timeout(HZ - elapsed);
+ schedule_timeout_interruptible(HZ - elapsed);
}
out:
diff --git a/drivers/macintosh/via-cuda.c b/drivers/macintosh/via-cuda.c
index 417deb5de108..d843a6c9c6df 100644
--- a/drivers/macintosh/via-cuda.c
+++ b/drivers/macintosh/via-cuda.c
@@ -37,7 +37,6 @@ static DEFINE_SPINLOCK(cuda_lock);
#ifdef CONFIG_MAC
#define CUDA_IRQ IRQ_MAC_ADB
-#define __openfirmware
#define eieio()
#else
#define CUDA_IRQ vias->intrs[0].line
diff --git a/drivers/macintosh/via-pmu.c b/drivers/macintosh/via-pmu.c
index 645a2e5c70ab..564043508569 100644
--- a/drivers/macintosh/via-pmu.c
+++ b/drivers/macintosh/via-pmu.c
@@ -155,10 +155,10 @@ static spinlock_t pmu_lock;
static u8 pmu_intr_mask;
static int pmu_version;
static int drop_interrupts;
-#ifdef CONFIG_PM
+#if defined(CONFIG_PM) && defined(CONFIG_PPC32)
static int option_lid_wakeup = 1;
static int sleep_in_progress;
-#endif /* CONFIG_PM */
+#endif /* CONFIG_PM && CONFIG_PPC32 */
static unsigned long async_req_locks;
static unsigned int pmu_irq_stats[11];
@@ -244,7 +244,7 @@ int pmu_wink(struct adb_request *req);
* - the number of response bytes which the PMU will return, or
* -1 if it will send a length byte.
*/
-static const s8 pmu_data_len[256][2] __openfirmwaredata = {
+static const s8 pmu_data_len[256][2] = {
/* 0 1 2 3 4 5 6 7 */
/*00*/ {-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},
/*08*/ {-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
@@ -295,7 +295,7 @@ static struct backlight_controller pmu_backlight_controller = {
};
#endif /* CONFIG_PMAC_BACKLIGHT */
-int __openfirmware
+int
find_via_pmu(void)
{
if (via != 0)
@@ -374,7 +374,7 @@ find_via_pmu(void)
}
#ifdef CONFIG_ADB
-static int __openfirmware
+static int
pmu_probe(void)
{
return vias == NULL? -ENODEV: 0;
@@ -405,7 +405,7 @@ static int __init via_pmu_start(void)
bright_req_2.complete = 1;
batt_req.complete = 1;
-#ifdef CONFIG_PPC32
+#if defined(CONFIG_PPC32) && !defined(CONFIG_PPC_MERGE)
if (pmu_kind == PMU_KEYLARGO_BASED)
openpic_set_irq_priority(vias->intrs[0].line,
OPENPIC_PRIORITY_DEFAULT + 1);
@@ -520,7 +520,7 @@ static int __init via_pmu_dev_init(void)
device_initcall(via_pmu_dev_init);
-static int __openfirmware
+static int
init_pmu(void)
{
int timeout;
@@ -588,17 +588,6 @@ pmu_get_model(void)
return pmu_kind;
}
-#ifndef CONFIG_PPC64
-static inline void wakeup_decrementer(void)
-{
- set_dec(tb_ticks_per_jiffy);
- /* No currently-supported powerbook has a 601,
- * so use get_tbl, not native
- */
- last_jiffy_stamp(0) = tb_last_stamp = get_tbl();
-}
-#endif
-
static void pmu_set_server_mode(int server_mode)
{
struct adb_request req;
@@ -625,7 +614,7 @@ static void pmu_set_server_mode(int server_mode)
/* This new version of the code for 2400/3400/3500 powerbooks
* is inspired from the implementation in gkrellm-pmu
*/
-static void __pmac
+static void
done_battery_state_ohare(struct adb_request* req)
{
/* format:
@@ -713,7 +702,7 @@ done_battery_state_ohare(struct adb_request* req)
clear_bit(0, &async_req_locks);
}
-static void __pmac
+static void
done_battery_state_smart(struct adb_request* req)
{
/* format:
@@ -791,7 +780,7 @@ done_battery_state_smart(struct adb_request* req)
clear_bit(0, &async_req_locks);
}
-static void __pmac
+static void
query_battery_state(void)
{
if (test_and_set_bit(0, &async_req_locks))
@@ -804,7 +793,7 @@ query_battery_state(void)
2, PMU_SMART_BATTERY_STATE, pmu_cur_battery+1);
}
-static int __pmac
+static int
proc_get_info(char *page, char **start, off_t off,
int count, int *eof, void *data)
{
@@ -819,7 +808,7 @@ proc_get_info(char *page, char **start, off_t off,
return p - page;
}
-static int __pmac
+static int
proc_get_irqstats(char *page, char **start, off_t off,
int count, int *eof, void *data)
{
@@ -846,7 +835,7 @@ proc_get_irqstats(char *page, char **start, off_t off,
return p - page;
}
-static int __pmac
+static int
proc_get_batt(char *page, char **start, off_t off,
int count, int *eof, void *data)
{
@@ -870,13 +859,13 @@ proc_get_batt(char *page, char **start, off_t off,
return p - page;
}
-static int __pmac
+static int
proc_read_options(char *page, char **start, off_t off,
int count, int *eof, void *data)
{
char *p = page;
-#ifdef CONFIG_PM
+#if defined(CONFIG_PM) && defined(CONFIG_PPC32)
if (pmu_kind == PMU_KEYLARGO_BASED &&
pmac_call_feature(PMAC_FTR_SLEEP_STATE,NULL,0,-1) >= 0)
p += sprintf(p, "lid_wakeup=%d\n", option_lid_wakeup);
@@ -887,7 +876,7 @@ proc_read_options(char *page, char **start, off_t off,
return p - page;
}
-static int __pmac
+static int
proc_write_options(struct file *file, const char __user *buffer,
unsigned long count, void *data)
{
@@ -917,7 +906,7 @@ proc_write_options(struct file *file, const char __user *buffer,
*(val++) = 0;
while(*val == ' ')
val++;
-#ifdef CONFIG_PM
+#if defined(CONFIG_PM) && defined(CONFIG_PPC32)
if (pmu_kind == PMU_KEYLARGO_BASED &&
pmac_call_feature(PMAC_FTR_SLEEP_STATE,NULL,0,-1) >= 0)
if (!strcmp(label, "lid_wakeup"))
@@ -934,7 +923,7 @@ proc_write_options(struct file *file, const char __user *buffer,
#ifdef CONFIG_ADB
/* Send an ADB command */
-static int __pmac
+static int
pmu_send_request(struct adb_request *req, int sync)
{
int i, ret;
@@ -1014,7 +1003,7 @@ pmu_send_request(struct adb_request *req, int sync)
}
/* Enable/disable autopolling */
-static int __pmac
+static int
pmu_adb_autopoll(int devs)
{
struct adb_request req;
@@ -1037,7 +1026,7 @@ pmu_adb_autopoll(int devs)
}
/* Reset the ADB bus */
-static int __pmac
+static int
pmu_adb_reset_bus(void)
{
struct adb_request req;
@@ -1072,7 +1061,7 @@ pmu_adb_reset_bus(void)
#endif /* CONFIG_ADB */
/* Construct and send a pmu request */
-int __openfirmware
+int
pmu_request(struct adb_request *req, void (*done)(struct adb_request *),
int nbytes, ...)
{
@@ -1098,7 +1087,7 @@ pmu_request(struct adb_request *req, void (*done)(struct adb_request *),
return pmu_queue_request(req);
}
-int __pmac
+int
pmu_queue_request(struct adb_request *req)
{
unsigned long flags;
@@ -1190,7 +1179,7 @@ pmu_done(struct adb_request *req)
(*done)(req);
}
-static void __pmac
+static void
pmu_start(void)
{
struct adb_request *req;
@@ -1214,7 +1203,7 @@ pmu_start(void)
send_byte(req->data[0]);
}
-void __openfirmware
+void
pmu_poll(void)
{
if (!via)
@@ -1224,7 +1213,7 @@ pmu_poll(void)
via_pmu_interrupt(0, NULL, NULL);
}
-void __openfirmware
+void
pmu_poll_adb(void)
{
if (!via)
@@ -1239,7 +1228,7 @@ pmu_poll_adb(void)
|| req_awaiting_reply));
}
-void __openfirmware
+void
pmu_wait_complete(struct adb_request *req)
{
if (!via)
@@ -1253,7 +1242,7 @@ pmu_wait_complete(struct adb_request *req)
* This is done to avoid spurrious shutdowns when we know we'll have
* interrupts switched off for a long time
*/
-void __openfirmware
+void
pmu_suspend(void)
{
unsigned long flags;
@@ -1293,7 +1282,7 @@ pmu_suspend(void)
} while (1);
}
-void __openfirmware
+void
pmu_resume(void)
{
unsigned long flags;
@@ -1323,7 +1312,7 @@ pmu_resume(void)
}
/* Interrupt data could be the result data from an ADB cmd */
-static void __pmac
+static void
pmu_handle_data(unsigned char *data, int len, struct pt_regs *regs)
{
unsigned char ints, pirq;
@@ -1435,7 +1424,7 @@ next:
goto next;
}
-static struct adb_request* __pmac
+static struct adb_request*
pmu_sr_intr(struct pt_regs *regs)
{
struct adb_request *req;
@@ -1541,7 +1530,7 @@ pmu_sr_intr(struct pt_regs *regs)
return NULL;
}
-static irqreturn_t __pmac
+static irqreturn_t
via_pmu_interrupt(int irq, void *arg, struct pt_regs *regs)
{
unsigned long flags;
@@ -1629,7 +1618,7 @@ no_free_slot:
return IRQ_RETVAL(handled);
}
-void __pmac
+void
pmu_unlock(void)
{
unsigned long flags;
@@ -1642,7 +1631,7 @@ pmu_unlock(void)
}
-static irqreturn_t __pmac
+static irqreturn_t
gpio1_interrupt(int irq, void *arg, struct pt_regs *regs)
{
unsigned long flags;
@@ -1663,12 +1652,12 @@ gpio1_interrupt(int irq, void *arg, struct pt_regs *regs)
}
#ifdef CONFIG_PMAC_BACKLIGHT
-static int backlight_to_bright[] __pmacdata = {
+static int backlight_to_bright[] = {
0x7f, 0x46, 0x42, 0x3e, 0x3a, 0x36, 0x32, 0x2e,
0x2a, 0x26, 0x22, 0x1e, 0x1a, 0x16, 0x12, 0x0e
};
-static int __openfirmware
+static int
pmu_set_backlight_enable(int on, int level, void* data)
{
struct adb_request req;
@@ -1688,7 +1677,7 @@ pmu_set_backlight_enable(int on, int level, void* data)
return 0;
}
-static void __openfirmware
+static void
pmu_bright_complete(struct adb_request *req)
{
if (req == &bright_req_1)
@@ -1697,7 +1686,7 @@ pmu_bright_complete(struct adb_request *req)
clear_bit(2, &async_req_locks);
}
-static int __openfirmware
+static int
pmu_set_backlight_level(int level, void* data)
{
if (vias == NULL)
@@ -1717,7 +1706,7 @@ pmu_set_backlight_level(int level, void* data)
}
#endif /* CONFIG_PMAC_BACKLIGHT */
-void __pmac
+void
pmu_enable_irled(int on)
{
struct adb_request req;
@@ -1732,7 +1721,7 @@ pmu_enable_irled(int on)
pmu_wait_complete(&req);
}
-void __pmac
+void
pmu_restart(void)
{
struct adb_request req;
@@ -1757,7 +1746,7 @@ pmu_restart(void)
;
}
-void __pmac
+void
pmu_shutdown(void)
{
struct adb_request req;
@@ -2064,6 +2053,7 @@ pmu_register_sleep_notifier(struct pmu_sleep_notifier *n)
__list_add(&n->list, list->prev, list);
return 0;
}
+EXPORT_SYMBOL(pmu_register_sleep_notifier);
int
pmu_unregister_sleep_notifier(struct pmu_sleep_notifier* n)
@@ -2074,9 +2064,13 @@ pmu_unregister_sleep_notifier(struct pmu_sleep_notifier* n)
n->list.next = NULL;
return 0;
}
+EXPORT_SYMBOL(pmu_unregister_sleep_notifier);
+#endif /* CONFIG_PM */
+
+#if defined(CONFIG_PM) && defined(CONFIG_PPC32)
/* Sleep is broadcast last-to-first */
-static int __pmac
+static int
broadcast_sleep(int when, int fallback)
{
int ret = PBOOK_SLEEP_OK;
@@ -2101,7 +2095,7 @@ broadcast_sleep(int when, int fallback)
}
/* Wake is broadcast first-to-last */
-static int __pmac
+static int
broadcast_wake(void)
{
int ret = PBOOK_SLEEP_OK;
@@ -2132,7 +2126,7 @@ static struct pci_save {
} *pbook_pci_saves;
static int pbook_npci_saves;
-static void __pmac
+static void
pbook_alloc_pci_save(void)
{
int npci;
@@ -2149,7 +2143,7 @@ pbook_alloc_pci_save(void)
pbook_npci_saves = npci;
}
-static void __pmac
+static void
pbook_free_pci_save(void)
{
if (pbook_pci_saves == NULL)
@@ -2159,7 +2153,7 @@ pbook_free_pci_save(void)
pbook_npci_saves = 0;
}
-static void __pmac
+static void
pbook_pci_save(void)
{
struct pci_save *ps = pbook_pci_saves;
@@ -2190,7 +2184,7 @@ pbook_pci_save(void)
* during boot, it will be in the pci dev list. If it's disabled at this point
* (and it will probably be), then you can't access it's config space.
*/
-static void __pmac
+static void
pbook_pci_restore(void)
{
u16 cmd;
@@ -2238,7 +2232,7 @@ pbook_pci_restore(void)
#ifdef DEBUG_SLEEP
/* N.B. This doesn't work on the 3400 */
-void __pmac
+void
pmu_blink(int n)
{
struct adb_request req;
@@ -2277,9 +2271,9 @@ pmu_blink(int n)
* Put the powerbook to sleep.
*/
-static u32 save_via[8] __pmacdata;
+static u32 save_via[8];
-static void __pmac
+static void
save_via_state(void)
{
save_via[0] = in_8(&via[ANH]);
@@ -2291,7 +2285,7 @@ save_via_state(void)
save_via[6] = in_8(&via[T1CL]);
save_via[7] = in_8(&via[T1CH]);
}
-static void __pmac
+static void
restore_via_state(void)
{
out_8(&via[ANH], save_via[0]);
@@ -2307,7 +2301,7 @@ restore_via_state(void)
out_8(&via[IER], IER_SET | SR_INT | CB1_INT);
}
-static int __pmac
+static int
pmac_suspend_devices(void)
{
int ret;
@@ -2397,7 +2391,7 @@ pmac_suspend_devices(void)
return 0;
}
-static int __pmac
+static int
pmac_wakeup_devices(void)
{
mdelay(100);
@@ -2436,7 +2430,7 @@ pmac_wakeup_devices(void)
#define GRACKLE_NAP (1<<4)
#define GRACKLE_SLEEP (1<<3)
-int __pmac
+int
powerbook_sleep_grackle(void)
{
unsigned long save_l2cr;
@@ -2520,7 +2514,7 @@ powerbook_sleep_grackle(void)
return 0;
}
-static int __pmac
+static int
powerbook_sleep_Core99(void)
{
unsigned long save_l2cr;
@@ -2620,7 +2614,7 @@ powerbook_sleep_Core99(void)
#define PB3400_MEM_CTRL 0xf8000000
#define PB3400_MEM_CTRL_SLEEP 0x70
-static int __pmac
+static int
powerbook_sleep_3400(void)
{
int ret, i, x;
@@ -2675,10 +2669,10 @@ powerbook_sleep_3400(void)
asleep = 1;
/* Put the CPU into sleep mode */
- asm volatile("mfspr %0,1008" : "=r" (hid0) :);
+ hid0 = mfspr(SPRN_HID0);
hid0 = (hid0 & ~(HID0_NAP | HID0_DOZE)) | HID0_SLEEP;
- asm volatile("mtspr 1008,%0" : : "r" (hid0));
- _nmask_and_or_msr(0, MSR_POW | MSR_EE);
+ mtspr(SPRN_HID0, hid0);
+ mtmsr(mfmsr() | MSR_POW | MSR_EE);
udelay(10);
/* OK, we're awake again, start restoring things */
@@ -2698,7 +2692,7 @@ powerbook_sleep_3400(void)
return 0;
}
-#endif /* CONFIG_PM */
+#endif /* CONFIG_PM && CONFIG_PPC32 */
/*
* Support for /dev/pmu device
@@ -2720,9 +2714,9 @@ struct pmu_private {
};
static LIST_HEAD(all_pmu_pvt);
-static DEFINE_SPINLOCK(all_pvt_lock __pmacdata);
+static DEFINE_SPINLOCK(all_pvt_lock);
-static void __pmac
+static void
pmu_pass_intr(unsigned char *data, int len)
{
struct pmu_private *pp;
@@ -2751,7 +2745,7 @@ pmu_pass_intr(unsigned char *data, int len)
spin_unlock_irqrestore(&all_pvt_lock, flags);
}
-static int __pmac
+static int
pmu_open(struct inode *inode, struct file *file)
{
struct pmu_private *pp;
@@ -2773,7 +2767,7 @@ pmu_open(struct inode *inode, struct file *file)
return 0;
}
-static ssize_t __pmac
+static ssize_t
pmu_read(struct file *file, char __user *buf,
size_t count, loff_t *ppos)
{
@@ -2825,14 +2819,14 @@ pmu_read(struct file *file, char __user *buf,
return ret;
}
-static ssize_t __pmac
+static ssize_t
pmu_write(struct file *file, const char __user *buf,
size_t count, loff_t *ppos)
{
return 0;
}
-static unsigned int __pmac
+static unsigned int
pmu_fpoll(struct file *filp, poll_table *wait)
{
struct pmu_private *pp = filp->private_data;
@@ -2849,7 +2843,7 @@ pmu_fpoll(struct file *filp, poll_table *wait)
return mask;
}
-static int __pmac
+static int
pmu_release(struct inode *inode, struct file *file)
{
struct pmu_private *pp = file->private_data;
@@ -2874,8 +2868,7 @@ pmu_release(struct inode *inode, struct file *file)
return 0;
}
-/* Note: removed __openfirmware here since it causes link errors */
-static int __pmac
+static int
pmu_ioctl(struct inode * inode, struct file *filp,
u_int cmd, u_long arg)
{
@@ -2883,7 +2876,7 @@ pmu_ioctl(struct inode * inode, struct file *filp,
int error = -EINVAL;
switch (cmd) {
-#ifdef CONFIG_PM
+#if defined(CONFIG_PM) && defined(CONFIG_PPC32)
case PMU_IOC_SLEEP:
if (!capable(CAP_SYS_ADMIN))
return -EACCES;
@@ -2911,7 +2904,7 @@ pmu_ioctl(struct inode * inode, struct file *filp,
return put_user(0, argp);
else
return put_user(1, argp);
-#endif /* CONFIG_PM */
+#endif /* CONFIG_PM && CONFIG_PPC32 */
#ifdef CONFIG_PMAC_BACKLIGHT
/* Backlight should have its own device or go via
@@ -2957,7 +2950,7 @@ pmu_ioctl(struct inode * inode, struct file *filp,
return error;
}
-static struct file_operations pmu_device_fops __pmacdata = {
+static struct file_operations pmu_device_fops = {
.read = pmu_read,
.write = pmu_write,
.poll = pmu_fpoll,
@@ -2966,7 +2959,7 @@ static struct file_operations pmu_device_fops __pmacdata = {
.release = pmu_release,
};
-static struct miscdevice pmu_device __pmacdata = {
+static struct miscdevice pmu_device = {
PMU_MINOR, "pmu", &pmu_device_fops
};
@@ -2982,7 +2975,7 @@ device_initcall(pmu_device_init);
#ifdef DEBUG_SLEEP
-static inline void __pmac
+static inline void
polled_handshake(volatile unsigned char __iomem *via)
{
via[B] &= ~TREQ; eieio();
@@ -2993,7 +2986,7 @@ polled_handshake(volatile unsigned char __iomem *via)
;
}
-static inline void __pmac
+static inline void
polled_send_byte(volatile unsigned char __iomem *via, int x)
{
via[ACR] |= SR_OUT | SR_EXT; eieio();
@@ -3001,7 +2994,7 @@ polled_send_byte(volatile unsigned char __iomem *via, int x)
polled_handshake(via);
}
-static inline int __pmac
+static inline int
polled_recv_byte(volatile unsigned char __iomem *via)
{
int x;
@@ -3013,7 +3006,7 @@ polled_recv_byte(volatile unsigned char __iomem *via)
return x;
}
-int __pmac
+int
pmu_polled_request(struct adb_request *req)
{
unsigned long flags;
@@ -3059,7 +3052,7 @@ pmu_polled_request(struct adb_request *req)
* to do suspend-to-disk.
*/
-#ifdef CONFIG_PM
+#if defined(CONFIG_PM) && defined(CONFIG_PPC32)
static int pmu_sys_suspended = 0;
@@ -3094,7 +3087,7 @@ static int pmu_sys_resume(struct sys_device *sysdev)
return 0;
}
-#endif /* CONFIG_PM */
+#endif /* CONFIG_PM && CONFIG_PPC32 */
static struct sysdev_class pmu_sysclass = {
set_kset_name("pmu"),
@@ -3106,10 +3099,10 @@ static struct sys_device device_pmu = {
};
static struct sysdev_driver driver_pmu = {
-#ifdef CONFIG_PM
+#if defined(CONFIG_PM) && defined(CONFIG_PPC32)
.suspend = &pmu_sys_suspend,
.resume = &pmu_sys_resume,
-#endif /* CONFIG_PM */
+#endif /* CONFIG_PM && CONFIG_PPC32 */
};
static int __init init_pmu_sysfs(void)
@@ -3147,12 +3140,10 @@ EXPORT_SYMBOL(pmu_i2c_combined_read);
EXPORT_SYMBOL(pmu_i2c_stdsub_write);
EXPORT_SYMBOL(pmu_i2c_simple_read);
EXPORT_SYMBOL(pmu_i2c_simple_write);
-#ifdef CONFIG_PM
-EXPORT_SYMBOL(pmu_register_sleep_notifier);
-EXPORT_SYMBOL(pmu_unregister_sleep_notifier);
+#if defined(CONFIG_PM) && defined(CONFIG_PPC32)
EXPORT_SYMBOL(pmu_enable_irled);
EXPORT_SYMBOL(pmu_battery_count);
EXPORT_SYMBOL(pmu_batteries);
EXPORT_SYMBOL(pmu_power_flags);
-#endif /* CONFIG_PM */
+#endif /* CONFIG_PM && CONFIG_PPC32 */
diff --git a/drivers/macintosh/via-pmu68k.c b/drivers/macintosh/via-pmu68k.c
index 820dc52e30bc..6f80d76ac17c 100644
--- a/drivers/macintosh/via-pmu68k.c
+++ b/drivers/macintosh/via-pmu68k.c
@@ -835,7 +835,7 @@ static struct pci_save {
} *pbook_pci_saves;
static int n_pbook_pci_saves;
-static inline void __openfirmware
+static inline void
pbook_pci_save(void)
{
int npci;
@@ -863,7 +863,7 @@ pbook_pci_save(void)
}
}
-static inline void __openfirmware
+static inline void
pbook_pci_restore(void)
{
u16 cmd;
@@ -902,7 +902,7 @@ pbook_pci_restore(void)
#define IRQ_ENABLE ((unsigned int *)0xf3000024)
#define MEM_CTRL ((unsigned int *)0xf8000070)
-int __openfirmware powerbook_sleep(void)
+int powerbook_sleep(void)
{
int ret, i, x;
static int save_backlight;
@@ -1001,25 +1001,24 @@ int __openfirmware powerbook_sleep(void)
/*
* Support for /dev/pmu device
*/
-static int __openfirmware pmu_open(struct inode *inode, struct file *file)
+static int pmu_open(struct inode *inode, struct file *file)
{
return 0;
}
-static ssize_t __openfirmware pmu_read(struct file *file, char *buf,
+static ssize_t pmu_read(struct file *file, char *buf,
size_t count, loff_t *ppos)
{
return 0;
}
-static ssize_t __openfirmware pmu_write(struct file *file, const char *buf,
+static ssize_t pmu_write(struct file *file, const char *buf,
size_t count, loff_t *ppos)
{
return 0;
}
-/* Note: removed __openfirmware here since it causes link errors */
-static int /*__openfirmware*/ pmu_ioctl(struct inode * inode, struct file *filp,
+static int pmu_ioctl(struct inode * inode, struct file *filp,
u_int cmd, u_long arg)
{
int error;
diff --git a/drivers/macintosh/windfarm.h b/drivers/macintosh/windfarm.h
new file mode 100644
index 000000000000..3f0cb0312ea3
--- /dev/null
+++ b/drivers/macintosh/windfarm.h
@@ -0,0 +1,131 @@
+/*
+ * Windfarm PowerMac thermal control.
+ *
+ * (c) Copyright 2005 Benjamin Herrenschmidt, IBM Corp.
+ * <benh@kernel.crashing.org>
+ *
+ * Released under the term of the GNU GPL v2.
+ */
+
+#ifndef __WINDFARM_H__
+#define __WINDFARM_H__
+
+#include <linux/kref.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/notifier.h>
+
+/* Display a 16.16 fixed point value */
+#define FIX32TOPRINT(f) ((f) >> 16),((((f) & 0xffff) * 1000) >> 16)
+
+/*
+ * Control objects
+ */
+
+struct wf_control;
+
+struct wf_control_ops {
+ int (*set_value)(struct wf_control *ct, s32 val);
+ int (*get_value)(struct wf_control *ct, s32 *val);
+ s32 (*get_min)(struct wf_control *ct);
+ s32 (*get_max)(struct wf_control *ct);
+ void (*release)(struct wf_control *ct);
+ struct module *owner;
+};
+
+struct wf_control {
+ struct list_head link;
+ struct wf_control_ops *ops;
+ char *name;
+ int type;
+ struct kref ref;
+};
+
+#define WF_CONTROL_TYPE_GENERIC 0
+#define WF_CONTROL_RPM_FAN 1
+#define WF_CONTROL_PWM_FAN 2
+
+
+/* Note about lifetime rules: wf_register_control() will initialize
+ * the kref and wf_unregister_control will decrement it, thus the
+ * object creating/disposing a given control shouldn't assume it
+ * still exists after wf_unregister_control has been called.
+ * wf_find_control will inc the refcount for you
+ */
+extern int wf_register_control(struct wf_control *ct);
+extern void wf_unregister_control(struct wf_control *ct);
+extern struct wf_control * wf_find_control(const char *name);
+extern int wf_get_control(struct wf_control *ct);
+extern void wf_put_control(struct wf_control *ct);
+
+static inline int wf_control_set_max(struct wf_control *ct)
+{
+ s32 vmax = ct->ops->get_max(ct);
+ return ct->ops->set_value(ct, vmax);
+}
+
+static inline int wf_control_set_min(struct wf_control *ct)
+{
+ s32 vmin = ct->ops->get_min(ct);
+ return ct->ops->set_value(ct, vmin);
+}
+
+/*
+ * Sensor objects
+ */
+
+struct wf_sensor;
+
+struct wf_sensor_ops {
+ int (*get_value)(struct wf_sensor *sr, s32 *val);
+ void (*release)(struct wf_sensor *sr);
+ struct module *owner;
+};
+
+struct wf_sensor {
+ struct list_head link;
+ struct wf_sensor_ops *ops;
+ char *name;
+ struct kref ref;
+};
+
+/* Same lifetime rules as controls */
+extern int wf_register_sensor(struct wf_sensor *sr);
+extern void wf_unregister_sensor(struct wf_sensor *sr);
+extern struct wf_sensor * wf_find_sensor(const char *name);
+extern int wf_get_sensor(struct wf_sensor *sr);
+extern void wf_put_sensor(struct wf_sensor *sr);
+
+/* For use by clients. Note that we are a bit racy here since
+ * notifier_block doesn't have a module owner field. I may fix
+ * it one day ...
+ *
+ * LOCKING NOTE !
+ *
+ * All "events" except WF_EVENT_TICK are called with an internal mutex
+ * held which will deadlock if you call basically any core routine.
+ * So don't ! Just take note of the event and do your actual operations
+ * from the ticker.
+ *
+ */
+extern int wf_register_client(struct notifier_block *nb);
+extern int wf_unregister_client(struct notifier_block *nb);
+
+/* Overtemp conditions. Those are refcounted */
+extern void wf_set_overtemp(void);
+extern void wf_clear_overtemp(void);
+extern int wf_is_overtemp(void);
+
+#define WF_EVENT_NEW_CONTROL 0 /* param is wf_control * */
+#define WF_EVENT_NEW_SENSOR 1 /* param is wf_sensor * */
+#define WF_EVENT_OVERTEMP 2 /* no param */
+#define WF_EVENT_NORMALTEMP 3 /* overtemp condition cleared */
+#define WF_EVENT_TICK 4 /* 1 second tick */
+
+/* Note: If that driver gets more broad use, we could replace the
+ * simplistic overtemp bits with "environmental conditions". That
+ * could then be used to also notify of things like fan failure,
+ * case open, battery conditions, ...
+ */
+
+#endif /* __WINDFARM_H__ */
diff --git a/drivers/macintosh/windfarm_core.c b/drivers/macintosh/windfarm_core.c
new file mode 100644
index 000000000000..6c2a471ea6c0
--- /dev/null
+++ b/drivers/macintosh/windfarm_core.c
@@ -0,0 +1,426 @@
+/*
+ * Windfarm PowerMac thermal control. Core
+ *
+ * (c) Copyright 2005 Benjamin Herrenschmidt, IBM Corp.
+ * <benh@kernel.crashing.org>
+ *
+ * Released under the term of the GNU GPL v2.
+ *
+ * This core code tracks the list of sensors & controls, register
+ * clients, and holds the kernel thread used for control.
+ *
+ * TODO:
+ *
+ * Add some information about sensor/control type and data format to
+ * sensors/controls, and have the sysfs attribute stuff be moved
+ * generically here instead of hard coded in the platform specific
+ * driver as it us currently
+ *
+ * This however requires solving some annoying lifetime issues with
+ * sysfs which doesn't seem to have lifetime rules for struct attribute,
+ * I may have to create full features kobjects for every sensor/control
+ * instead which is a bit of an overkill imho
+ */
+
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/spinlock.h>
+#include <linux/smp_lock.h>
+#include <linux/kthread.h>
+#include <linux/jiffies.h>
+#include <linux/reboot.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+
+#include "windfarm.h"
+
+#define VERSION "0.2"
+
+#undef DEBUG
+
+#ifdef DEBUG
+#define DBG(args...) printk(args)
+#else
+#define DBG(args...) do { } while(0)
+#endif
+
+static LIST_HEAD(wf_controls);
+static LIST_HEAD(wf_sensors);
+static DECLARE_MUTEX(wf_lock);
+static struct notifier_block *wf_client_list;
+static int wf_client_count;
+static unsigned int wf_overtemp;
+static unsigned int wf_overtemp_counter;
+struct task_struct *wf_thread;
+
+/*
+ * Utilities & tick thread
+ */
+
+static inline void wf_notify(int event, void *param)
+{
+ notifier_call_chain(&wf_client_list, event, param);
+}
+
+int wf_critical_overtemp(void)
+{
+ static char * critical_overtemp_path = "/sbin/critical_overtemp";
+ char *argv[] = { critical_overtemp_path, NULL };
+ static char *envp[] = { "HOME=/",
+ "TERM=linux",
+ "PATH=/sbin:/usr/sbin:/bin:/usr/bin",
+ NULL };
+
+ return call_usermodehelper(critical_overtemp_path, argv, envp, 0);
+}
+EXPORT_SYMBOL_GPL(wf_critical_overtemp);
+
+static int wf_thread_func(void *data)
+{
+ unsigned long next, delay;
+
+ next = jiffies;
+
+ DBG("wf: thread started\n");
+
+ while(!kthread_should_stop()) {
+ try_to_freeze();
+
+ if (time_after_eq(jiffies, next)) {
+ wf_notify(WF_EVENT_TICK, NULL);
+ if (wf_overtemp) {
+ wf_overtemp_counter++;
+ /* 10 seconds overtemp, notify userland */
+ if (wf_overtemp_counter > 10)
+ wf_critical_overtemp();
+ /* 30 seconds, shutdown */
+ if (wf_overtemp_counter > 30) {
+ printk(KERN_ERR "windfarm: Overtemp "
+ "for more than 30"
+ " seconds, shutting down\n");
+ machine_power_off();
+ }
+ }
+ next += HZ;
+ }
+
+ delay = next - jiffies;
+ if (delay <= HZ)
+ schedule_timeout_interruptible(delay);
+
+ /* there should be no signal, but oh well */
+ if (signal_pending(current)) {
+ printk(KERN_WARNING "windfarm: thread got sigl !\n");
+ break;
+ }
+ }
+
+ DBG("wf: thread stopped\n");
+
+ return 0;
+}
+
+static void wf_start_thread(void)
+{
+ wf_thread = kthread_run(wf_thread_func, NULL, "kwindfarm");
+ if (IS_ERR(wf_thread)) {
+ printk(KERN_ERR "windfarm: failed to create thread,err %ld\n",
+ PTR_ERR(wf_thread));
+ wf_thread = NULL;
+ }
+}
+
+
+static void wf_stop_thread(void)
+{
+ if (wf_thread)
+ kthread_stop(wf_thread);
+ wf_thread = NULL;
+}
+
+/*
+ * Controls
+ */
+
+static void wf_control_release(struct kref *kref)
+{
+ struct wf_control *ct = container_of(kref, struct wf_control, ref);
+
+ DBG("wf: Deleting control %s\n", ct->name);
+
+ if (ct->ops && ct->ops->release)
+ ct->ops->release(ct);
+ else
+ kfree(ct);
+}
+
+int wf_register_control(struct wf_control *new_ct)
+{
+ struct wf_control *ct;
+
+ down(&wf_lock);
+ list_for_each_entry(ct, &wf_controls, link) {
+ if (!strcmp(ct->name, new_ct->name)) {
+ printk(KERN_WARNING "windfarm: trying to register"
+ " duplicate control %s\n", ct->name);
+ up(&wf_lock);
+ return -EEXIST;
+ }
+ }
+ kref_init(&new_ct->ref);
+ list_add(&new_ct->link, &wf_controls);
+
+ DBG("wf: Registered control %s\n", new_ct->name);
+
+ wf_notify(WF_EVENT_NEW_CONTROL, new_ct);
+ up(&wf_lock);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(wf_register_control);
+
+void wf_unregister_control(struct wf_control *ct)
+{
+ down(&wf_lock);
+ list_del(&ct->link);
+ up(&wf_lock);
+
+ DBG("wf: Unregistered control %s\n", ct->name);
+
+ kref_put(&ct->ref, wf_control_release);
+}
+EXPORT_SYMBOL_GPL(wf_unregister_control);
+
+struct wf_control * wf_find_control(const char *name)
+{
+ struct wf_control *ct;
+
+ down(&wf_lock);
+ list_for_each_entry(ct, &wf_controls, link) {
+ if (!strcmp(ct->name, name)) {
+ if (wf_get_control(ct))
+ ct = NULL;
+ up(&wf_lock);
+ return ct;
+ }
+ }
+ up(&wf_lock);
+ return NULL;
+}
+EXPORT_SYMBOL_GPL(wf_find_control);
+
+int wf_get_control(struct wf_control *ct)
+{
+ if (!try_module_get(ct->ops->owner))
+ return -ENODEV;
+ kref_get(&ct->ref);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(wf_get_control);
+
+void wf_put_control(struct wf_control *ct)
+{
+ struct module *mod = ct->ops->owner;
+ kref_put(&ct->ref, wf_control_release);
+ module_put(mod);
+}
+EXPORT_SYMBOL_GPL(wf_put_control);
+
+
+/*
+ * Sensors
+ */
+
+
+static void wf_sensor_release(struct kref *kref)
+{
+ struct wf_sensor *sr = container_of(kref, struct wf_sensor, ref);
+
+ DBG("wf: Deleting sensor %s\n", sr->name);
+
+ if (sr->ops && sr->ops->release)
+ sr->ops->release(sr);
+ else
+ kfree(sr);
+}
+
+int wf_register_sensor(struct wf_sensor *new_sr)
+{
+ struct wf_sensor *sr;
+
+ down(&wf_lock);
+ list_for_each_entry(sr, &wf_sensors, link) {
+ if (!strcmp(sr->name, new_sr->name)) {
+ printk(KERN_WARNING "windfarm: trying to register"
+ " duplicate sensor %s\n", sr->name);
+ up(&wf_lock);
+ return -EEXIST;
+ }
+ }
+ kref_init(&new_sr->ref);
+ list_add(&new_sr->link, &wf_sensors);
+
+ DBG("wf: Registered sensor %s\n", new_sr->name);
+
+ wf_notify(WF_EVENT_NEW_SENSOR, new_sr);
+ up(&wf_lock);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(wf_register_sensor);
+
+void wf_unregister_sensor(struct wf_sensor *sr)
+{
+ down(&wf_lock);
+ list_del(&sr->link);
+ up(&wf_lock);
+
+ DBG("wf: Unregistered sensor %s\n", sr->name);
+
+ wf_put_sensor(sr);
+}
+EXPORT_SYMBOL_GPL(wf_unregister_sensor);
+
+struct wf_sensor * wf_find_sensor(const char *name)
+{
+ struct wf_sensor *sr;
+
+ down(&wf_lock);
+ list_for_each_entry(sr, &wf_sensors, link) {
+ if (!strcmp(sr->name, name)) {
+ if (wf_get_sensor(sr))
+ sr = NULL;
+ up(&wf_lock);
+ return sr;
+ }
+ }
+ up(&wf_lock);
+ return NULL;
+}
+EXPORT_SYMBOL_GPL(wf_find_sensor);
+
+int wf_get_sensor(struct wf_sensor *sr)
+{
+ if (!try_module_get(sr->ops->owner))
+ return -ENODEV;
+ kref_get(&sr->ref);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(wf_get_sensor);
+
+void wf_put_sensor(struct wf_sensor *sr)
+{
+ struct module *mod = sr->ops->owner;
+ kref_put(&sr->ref, wf_sensor_release);
+ module_put(mod);
+}
+EXPORT_SYMBOL_GPL(wf_put_sensor);
+
+
+/*
+ * Client & notification
+ */
+
+int wf_register_client(struct notifier_block *nb)
+{
+ int rc;
+ struct wf_control *ct;
+ struct wf_sensor *sr;
+
+ down(&wf_lock);
+ rc = notifier_chain_register(&wf_client_list, nb);
+ if (rc != 0)
+ goto bail;
+ wf_client_count++;
+ list_for_each_entry(ct, &wf_controls, link)
+ wf_notify(WF_EVENT_NEW_CONTROL, ct);
+ list_for_each_entry(sr, &wf_sensors, link)
+ wf_notify(WF_EVENT_NEW_SENSOR, sr);
+ if (wf_client_count == 1)
+ wf_start_thread();
+ bail:
+ up(&wf_lock);
+ return rc;
+}
+EXPORT_SYMBOL_GPL(wf_register_client);
+
+int wf_unregister_client(struct notifier_block *nb)
+{
+ down(&wf_lock);
+ notifier_chain_unregister(&wf_client_list, nb);
+ wf_client_count++;
+ if (wf_client_count == 0)
+ wf_stop_thread();
+ up(&wf_lock);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(wf_unregister_client);
+
+void wf_set_overtemp(void)
+{
+ down(&wf_lock);
+ wf_overtemp++;
+ if (wf_overtemp == 1) {
+ printk(KERN_WARNING "windfarm: Overtemp condition detected !\n");
+ wf_overtemp_counter = 0;
+ wf_notify(WF_EVENT_OVERTEMP, NULL);
+ }
+ up(&wf_lock);
+}
+EXPORT_SYMBOL_GPL(wf_set_overtemp);
+
+void wf_clear_overtemp(void)
+{
+ down(&wf_lock);
+ WARN_ON(wf_overtemp == 0);
+ if (wf_overtemp == 0) {
+ up(&wf_lock);
+ return;
+ }
+ wf_overtemp--;
+ if (wf_overtemp == 0) {
+ printk(KERN_WARNING "windfarm: Overtemp condition cleared !\n");
+ wf_notify(WF_EVENT_NORMALTEMP, NULL);
+ }
+ up(&wf_lock);
+}
+EXPORT_SYMBOL_GPL(wf_clear_overtemp);
+
+int wf_is_overtemp(void)
+{
+ return (wf_overtemp != 0);
+}
+EXPORT_SYMBOL_GPL(wf_is_overtemp);
+
+static struct platform_device wf_platform_device = {
+ .name = "windfarm",
+};
+
+static int __init windfarm_core_init(void)
+{
+ DBG("wf: core loaded\n");
+
+ platform_device_register(&wf_platform_device);
+ return 0;
+}
+
+static void __exit windfarm_core_exit(void)
+{
+ BUG_ON(wf_client_count != 0);
+
+ DBG("wf: core unloaded\n");
+
+ platform_device_unregister(&wf_platform_device);
+}
+
+
+module_init(windfarm_core_init);
+module_exit(windfarm_core_exit);
+
+MODULE_AUTHOR("Benjamin Herrenschmidt <benh@kernel.crashing.org>");
+MODULE_DESCRIPTION("Core component of PowerMac thermal control");
+MODULE_LICENSE("GPL");
+
diff --git a/drivers/macintosh/windfarm_cpufreq_clamp.c b/drivers/macintosh/windfarm_cpufreq_clamp.c
new file mode 100644
index 000000000000..607dbaca69c9
--- /dev/null
+++ b/drivers/macintosh/windfarm_cpufreq_clamp.c
@@ -0,0 +1,105 @@
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/wait.h>
+#include <linux/cpufreq.h>
+
+#include "windfarm.h"
+
+#define VERSION "0.3"
+
+static int clamped;
+static struct wf_control *clamp_control;
+
+static int clamp_notifier_call(struct notifier_block *self,
+ unsigned long event, void *data)
+{
+ struct cpufreq_policy *p = data;
+ unsigned long max_freq;
+
+ if (event != CPUFREQ_ADJUST)
+ return 0;
+
+ max_freq = clamped ? (p->cpuinfo.min_freq) : (p->cpuinfo.max_freq);
+ cpufreq_verify_within_limits(p, 0, max_freq);
+
+ return 0;
+}
+
+static struct notifier_block clamp_notifier = {
+ .notifier_call = clamp_notifier_call,
+};
+
+static int clamp_set(struct wf_control *ct, s32 value)
+{
+ if (value)
+ printk(KERN_INFO "windfarm: Clamping CPU frequency to "
+ "minimum !\n");
+ else
+ printk(KERN_INFO "windfarm: CPU frequency unclamped !\n");
+ clamped = value;
+ cpufreq_update_policy(0);
+ return 0;
+}
+
+static int clamp_get(struct wf_control *ct, s32 *value)
+{
+ *value = clamped;
+ return 0;
+}
+
+static s32 clamp_min(struct wf_control *ct)
+{
+ return 0;
+}
+
+static s32 clamp_max(struct wf_control *ct)
+{
+ return 1;
+}
+
+static struct wf_control_ops clamp_ops = {
+ .set_value = clamp_set,
+ .get_value = clamp_get,
+ .get_min = clamp_min,
+ .get_max = clamp_max,
+ .owner = THIS_MODULE,
+};
+
+static int __init wf_cpufreq_clamp_init(void)
+{
+ struct wf_control *clamp;
+
+ clamp = kmalloc(sizeof(struct wf_control), GFP_KERNEL);
+ if (clamp == NULL)
+ return -ENOMEM;
+ cpufreq_register_notifier(&clamp_notifier, CPUFREQ_POLICY_NOTIFIER);
+ clamp->ops = &clamp_ops;
+ clamp->name = "cpufreq-clamp";
+ if (wf_register_control(clamp))
+ goto fail;
+ clamp_control = clamp;
+ return 0;
+ fail:
+ kfree(clamp);
+ return -ENODEV;
+}
+
+static void __exit wf_cpufreq_clamp_exit(void)
+{
+ if (clamp_control)
+ wf_unregister_control(clamp_control);
+}
+
+
+module_init(wf_cpufreq_clamp_init);
+module_exit(wf_cpufreq_clamp_exit);
+
+MODULE_AUTHOR("Benjamin Herrenschmidt <benh@kernel.crashing.org>");
+MODULE_DESCRIPTION("CPU frequency clamp for PowerMacs thermal control");
+MODULE_LICENSE("GPL");
+
diff --git a/drivers/macintosh/windfarm_lm75_sensor.c b/drivers/macintosh/windfarm_lm75_sensor.c
new file mode 100644
index 000000000000..a0a41ad0f2b5
--- /dev/null
+++ b/drivers/macintosh/windfarm_lm75_sensor.c
@@ -0,0 +1,263 @@
+/*
+ * Windfarm PowerMac thermal control. LM75 sensor
+ *
+ * (c) Copyright 2005 Benjamin Herrenschmidt, IBM Corp.
+ * <benh@kernel.crashing.org>
+ *
+ * Released under the term of the GNU GPL v2.
+ */
+
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/wait.h>
+#include <linux/i2c.h>
+#include <linux/i2c-dev.h>
+#include <asm/prom.h>
+#include <asm/machdep.h>
+#include <asm/io.h>
+#include <asm/system.h>
+#include <asm/sections.h>
+
+#include "windfarm.h"
+
+#define VERSION "0.1"
+
+#undef DEBUG
+
+#ifdef DEBUG
+#define DBG(args...) printk(args)
+#else
+#define DBG(args...) do { } while(0)
+#endif
+
+struct wf_lm75_sensor {
+ int ds1775 : 1;
+ int inited : 1;
+ 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 = {
+ .owner = THIS_MODULE,
+ .name = "wf_lm75",
+ .flags = I2C_DF_NOTIFY,
+ .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)
+ return -ENODEV;
+
+ /* Init chip if necessary */
+ if (!lm->inited) {
+ 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);
+
+ /* clear shutdown bit, keep other settings as left by
+ * the firmware for now
+ */
+ cfg_new = cfg & ~0x01;
+ i2c_smbus_write_byte_data(&lm->i2c, 1, cfg_new);
+ lm->inited = 1;
+
+ /* If we just powered it up, let's wait 200 ms */
+ msleep(200);
+ }
+
+ /* Read temperature register */
+ data = (s32)le16_to_cpu(i2c_smbus_read_word_data(&lm->i2c, 0));
+ data <<= 8;
+ *value = data;
+
+ return 0;
+}
+
+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);
+}
+
+static struct wf_sensor_ops wf_lm75_ops = {
+ .get_value = wf_lm75_get,
+ .release = wf_lm75_release,
+ .owner = THIS_MODULE,
+};
+
+static struct wf_lm75_sensor *wf_lm75_create(struct i2c_adapter *adapter,
+ u8 addr, int ds1775,
+ const char *loc)
+{
+ struct wf_lm75_sensor *lm;
+
+ DBG("wf_lm75: creating %s device at address 0x%02x\n",
+ ds1775 ? "ds1775" : "lm75", addr);
+
+ lm = kmalloc(sizeof(struct wf_lm75_sensor), GFP_KERNEL);
+ if (lm == NULL)
+ return NULL;
+ memset(lm, 0, sizeof(struct wf_lm75_sensor));
+
+ /* 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";
+ 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);
+
+ if (i2c_attach_client(&lm->i2c)) {
+ printk(KERN_ERR "windfarm: failed to attach %s %s to i2c\n",
+ ds1775 ? "ds1775" : "lm75", lm->i2c.name);
+ goto fail;
+ }
+
+ if (wf_register_sensor(&lm->sens)) {
+ i2c_detach_client(&lm->i2c);
+ goto fail;
+ }
+
+ return lm;
+ fail:
+ kfree(lm);
+ return NULL;
+}
+
+static int wf_lm75_attach(struct i2c_adapter *adapter)
+{
+ u8 bus_id;
+ struct device_node *smu, *bus, *dev;
+
+ /* We currently only deal with LM75's hanging off the SMU
+ * i2c busses. If we extend that driver to other/older
+ * machines, we should split this function into SMU-i2c,
+ * keywest-i2c, PMU-i2c, ...
+ */
+
+ DBG("wf_lm75: adapter %s detected\n", adapter->name);
+
+ if (strncmp(adapter->name, "smu-i2c-", 8) != 0)
+ return 0;
+ smu = of_find_node_by_type(NULL, "smu");
+ if (smu == NULL)
+ return 0;
+
+ /* Look for the bus in the device-tree */
+ bus_id = (u8)simple_strtoul(adapter->name + 8, NULL, 16);
+
+ DBG("wf_lm75: bus ID is %x\n", bus_id);
+
+ /* Look for sensors subdir */
+ for (bus = NULL;
+ (bus = of_get_next_child(smu, bus)) != NULL;) {
+ u32 *reg;
+
+ if (strcmp(bus->name, "i2c"))
+ continue;
+ reg = (u32 *)get_property(bus, "reg", NULL);
+ if (reg == NULL)
+ continue;
+ if (bus_id == *reg)
+ break;
+ }
+ of_node_put(smu);
+ if (bus == NULL) {
+ printk(KERN_WARNING "windfarm: SMU i2c bus 0x%x not found"
+ " in device-tree !\n", bus_id);
+ return 0;
+ }
+
+ DBG("wf_lm75: bus found, looking for device...\n");
+
+ /* Now look for lm75(s) in there */
+ for (dev = NULL;
+ (dev = of_get_next_child(bus, dev)) != NULL;) {
+ const char *loc =
+ get_property(dev, "hwsensor-location", NULL);
+ u32 *reg = (u32 *)get_property(dev, "reg", NULL);
+ DBG(" dev: %s... (loc: %p, reg: %p)\n", dev->name, loc, reg);
+ if (loc == NULL || reg == NULL)
+ continue;
+ /* real lm75 */
+ if (device_is_compatible(dev, "lm75"))
+ wf_lm75_create(adapter, *reg, 0, loc);
+ /* ds1775 (compatible, better resolution */
+ else if (device_is_compatible(dev, "ds1775"))
+ wf_lm75_create(adapter, *reg, 1, loc);
+ }
+
+ of_node_put(bus);
+
+ return 0;
+}
+
+static int wf_lm75_detach(struct i2c_client *client)
+{
+ struct wf_lm75_sensor *lm = i2c_to_lm75(client);
+
+ DBG("wf_lm75: i2c detatch called for %s\n", lm->sens.name);
+
+ /* Mark client detached */
+ lm->i2c.adapter = NULL;
+
+ /* release sensor */
+ wf_unregister_sensor(&lm->sens);
+
+ return 0;
+}
+
+static int __init wf_lm75_sensor_init(void)
+{
+ int rc;
+
+ rc = i2c_add_driver(&wf_lm75_driver);
+ if (rc < 0)
+ return rc;
+ return 0;
+}
+
+static void __exit wf_lm75_sensor_exit(void)
+{
+ i2c_del_driver(&wf_lm75_driver);
+}
+
+
+module_init(wf_lm75_sensor_init);
+module_exit(wf_lm75_sensor_exit);
+
+MODULE_AUTHOR("Benjamin Herrenschmidt <benh@kernel.crashing.org>");
+MODULE_DESCRIPTION("LM75 sensor objects for PowerMacs thermal control");
+MODULE_LICENSE("GPL");
+
diff --git a/drivers/macintosh/windfarm_pid.c b/drivers/macintosh/windfarm_pid.c
new file mode 100644
index 000000000000..2e803b368757
--- /dev/null
+++ b/drivers/macintosh/windfarm_pid.c
@@ -0,0 +1,145 @@
+/*
+ * Windfarm PowerMac thermal control. Generic PID helpers
+ *
+ * (c) Copyright 2005 Benjamin Herrenschmidt, IBM Corp.
+ * <benh@kernel.crashing.org>
+ *
+ * Released under the term of the GNU GPL v2.
+ */
+
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/module.h>
+
+#include "windfarm_pid.h"
+
+#undef DEBUG
+
+#ifdef DEBUG
+#define DBG(args...) printk(args)
+#else
+#define DBG(args...) do { } while(0)
+#endif
+
+void wf_pid_init(struct wf_pid_state *st, struct wf_pid_param *param)
+{
+ memset(st, 0, sizeof(struct wf_pid_state));
+ st->param = *param;
+ st->first = 1;
+}
+EXPORT_SYMBOL_GPL(wf_pid_init);
+
+s32 wf_pid_run(struct wf_pid_state *st, s32 new_sample)
+{
+ s64 error, integ, deriv;
+ s32 target;
+ int i, hlen = st->param.history_len;
+
+ /* Calculate error term */
+ error = new_sample - st->param.itarget;
+
+ /* Get samples into our history buffer */
+ if (st->first) {
+ for (i = 0; i < hlen; i++) {
+ st->samples[i] = new_sample;
+ st->errors[i] = error;
+ }
+ st->first = 0;
+ st->index = 0;
+ } else {
+ st->index = (st->index + 1) % hlen;
+ st->samples[st->index] = new_sample;
+ st->errors[st->index] = error;
+ }
+
+ /* Calculate integral term */
+ for (i = 0, integ = 0; i < hlen; i++)
+ integ += st->errors[(st->index + hlen - i) % hlen];
+ integ *= st->param.interval;
+
+ /* Calculate derivative term */
+ deriv = st->errors[st->index] -
+ st->errors[(st->index + hlen - 1) % hlen];
+ deriv /= st->param.interval;
+
+ /* Calculate target */
+ target = (s32)((integ * (s64)st->param.gr + deriv * (s64)st->param.gd +
+ error * (s64)st->param.gp) >> 36);
+ if (st->param.additive)
+ target += st->target;
+ target = max(target, st->param.min);
+ target = min(target, st->param.max);
+ st->target = target;
+
+ return st->target;
+}
+EXPORT_SYMBOL_GPL(wf_pid_run);
+
+void wf_cpu_pid_init(struct wf_cpu_pid_state *st,
+ struct wf_cpu_pid_param *param)
+{
+ memset(st, 0, sizeof(struct wf_cpu_pid_state));
+ st->param = *param;
+ st->first = 1;
+}
+EXPORT_SYMBOL_GPL(wf_cpu_pid_init);
+
+s32 wf_cpu_pid_run(struct wf_cpu_pid_state *st, s32 new_power, s32 new_temp)
+{
+ s64 error, integ, deriv, prop;
+ s32 target, sval, adj;
+ int i, hlen = st->param.history_len;
+
+ /* Calculate error term */
+ error = st->param.pmaxadj - new_power;
+
+ /* Get samples into our history buffer */
+ if (st->first) {
+ for (i = 0; i < hlen; i++) {
+ st->powers[i] = new_power;
+ st->errors[i] = error;
+ }
+ st->temps[0] = st->temps[1] = new_temp;
+ st->first = 0;
+ st->index = st->tindex = 0;
+ } else {
+ st->index = (st->index + 1) % hlen;
+ st->powers[st->index] = new_power;
+ st->errors[st->index] = error;
+ st->tindex = (st->tindex + 1) % 2;
+ st->temps[st->tindex] = new_temp;
+ }
+
+ /* Calculate integral term */
+ for (i = 0, integ = 0; i < hlen; i++)
+ integ += st->errors[(st->index + hlen - i) % hlen];
+ integ *= st->param.interval;
+ integ *= st->param.gr;
+ sval = st->param.tmax - ((integ >> 20) & 0xffffffff);
+ adj = min(st->param.ttarget, sval);
+
+ DBG("integ: %lx, sval: %lx, adj: %lx\n", integ, sval, adj);
+
+ /* Calculate derivative term */
+ deriv = st->temps[st->tindex] -
+ st->temps[(st->tindex + 2 - 1) % 2];
+ deriv /= st->param.interval;
+ deriv *= st->param.gd;
+
+ /* Calculate proportional term */
+ prop = (new_temp - adj);
+ prop *= st->param.gp;
+
+ DBG("deriv: %lx, prop: %lx\n", deriv, prop);
+
+ /* Calculate target */
+ target = st->target + (s32)((deriv + prop) >> 36);
+ target = max(target, st->param.min);
+ target = min(target, st->param.max);
+ st->target = target;
+
+ return st->target;
+}
+EXPORT_SYMBOL_GPL(wf_cpu_pid_run);
diff --git a/drivers/macintosh/windfarm_pid.h b/drivers/macintosh/windfarm_pid.h
new file mode 100644
index 000000000000..a364c2a2499c
--- /dev/null
+++ b/drivers/macintosh/windfarm_pid.h
@@ -0,0 +1,84 @@
+/*
+ * Windfarm PowerMac thermal control. Generic PID helpers
+ *
+ * (c) Copyright 2005 Benjamin Herrenschmidt, IBM Corp.
+ * <benh@kernel.crashing.org>
+ *
+ * Released under the term of the GNU GPL v2.
+ *
+ * This is a pair of generic PID helpers that can be used by
+ * control loops. One is the basic PID implementation, the
+ * other one is more specifically tailored to the loops used
+ * for CPU control with 2 input sample types (temp and power)
+ */
+
+/*
+ * *** Simple PID ***
+ */
+
+#define WF_PID_MAX_HISTORY 32
+
+/* This parameter array is passed to the PID algorithm. Currently,
+ * we don't support changing parameters on the fly as it's not needed
+ * but could be implemented (with necessary adjustment of the history
+ * buffer
+ */
+struct wf_pid_param {
+ int interval; /* Interval between samples in seconds */
+ int history_len; /* Size of history buffer */
+ int additive; /* 1: target relative to previous value */
+ s32 gd, gp, gr; /* PID gains */
+ s32 itarget; /* PID input target */
+ s32 min,max; /* min and max target values */
+};
+
+struct wf_pid_state {
+ int first; /* first run of the loop */
+ int index; /* index of current sample */
+ s32 target; /* current target value */
+ s32 samples[WF_PID_MAX_HISTORY]; /* samples history buffer */
+ s32 errors[WF_PID_MAX_HISTORY]; /* error history buffer */
+
+ struct wf_pid_param param;
+};
+
+extern void wf_pid_init(struct wf_pid_state *st, struct wf_pid_param *param);
+extern s32 wf_pid_run(struct wf_pid_state *st, s32 sample);
+
+
+/*
+ * *** CPU PID ***
+ */
+
+#define WF_CPU_PID_MAX_HISTORY 32
+
+/* This parameter array is passed to the CPU PID algorithm. Currently,
+ * we don't support changing parameters on the fly as it's not needed
+ * but could be implemented (with necessary adjustment of the history
+ * buffer
+ */
+struct wf_cpu_pid_param {
+ int interval; /* Interval between samples in seconds */
+ int history_len; /* Size of history buffer */
+ s32 gd, gp, gr; /* PID gains */
+ s32 pmaxadj; /* PID max power adjust */
+ s32 ttarget; /* PID input target */
+ s32 tmax; /* PID input max */
+ s32 min,max; /* min and max target values */
+};
+
+struct wf_cpu_pid_state {
+ int first; /* first run of the loop */
+ int index; /* index of current power */
+ int tindex; /* index of current temp */
+ s32 target; /* current target value */
+ s32 powers[WF_PID_MAX_HISTORY]; /* power history buffer */
+ s32 errors[WF_PID_MAX_HISTORY]; /* error history buffer */
+ s32 temps[2]; /* temp. history buffer */
+
+ struct wf_cpu_pid_param param;
+};
+
+extern void wf_cpu_pid_init(struct wf_cpu_pid_state *st,
+ struct wf_cpu_pid_param *param);
+extern s32 wf_cpu_pid_run(struct wf_cpu_pid_state *st, s32 power, s32 temp);
diff --git a/drivers/macintosh/windfarm_pm81.c b/drivers/macintosh/windfarm_pm81.c
new file mode 100644
index 000000000000..322c74b2687f
--- /dev/null
+++ b/drivers/macintosh/windfarm_pm81.c
@@ -0,0 +1,879 @@
+/*
+ * Windfarm PowerMac thermal control. iMac G5
+ *
+ * (c) Copyright 2005 Benjamin Herrenschmidt, IBM Corp.
+ * <benh@kernel.crashing.org>
+ *
+ * Released under the term of the GNU GPL v2.
+ *
+ * The algorithm used is the PID control algorithm, used the same
+ * way the published Darwin code does, using the same values that
+ * are present in the Darwin 8.2 snapshot property lists (note however
+ * that none of the code has been re-used, it's a complete re-implementation
+ *
+ * The various control loops found in Darwin config file are:
+ *
+ * PowerMac8,1 and PowerMac8,2
+ * ===========================
+ *
+ * System Fans control loop. Different based on models. In addition to the
+ * usual PID algorithm, the control loop gets 2 additional pairs of linear
+ * scaling factors (scale/offsets) expressed as 4.12 fixed point values
+ * signed offset, unsigned scale)
+ *
+ * The targets are modified such as:
+ * - the linked control (second control) gets the target value as-is
+ * (typically the drive fan)
+ * - the main control (first control) gets the target value scaled with
+ * the first pair of factors, and is then modified as below
+ * - the value of the target of the CPU Fan control loop is retreived,
+ * scaled with the second pair of factors, and the max of that and
+ * the scaled target is applied to the main control.
+ *
+ * # model_id: 2
+ * controls : system-fan, drive-bay-fan
+ * sensors : hd-temp
+ * PID params : G_d = 0x15400000
+ * G_p = 0x00200000
+ * G_r = 0x000002fd
+ * History = 2 entries
+ * Input target = 0x3a0000
+ * Interval = 5s
+ * linear-factors : offset = 0xff38 scale = 0x0ccd
+ * offset = 0x0208 scale = 0x07ae
+ *
+ * # model_id: 3
+ * controls : system-fan, drive-bay-fan
+ * sensors : hd-temp
+ * PID params : G_d = 0x08e00000
+ * G_p = 0x00566666
+ * G_r = 0x0000072b
+ * History = 2 entries
+ * Input target = 0x350000
+ * Interval = 5s
+ * linear-factors : offset = 0xff38 scale = 0x0ccd
+ * offset = 0x0000 scale = 0x0000
+ *
+ * # model_id: 5
+ * controls : system-fan
+ * sensors : hd-temp
+ * PID params : G_d = 0x15400000
+ * G_p = 0x00233333
+ * G_r = 0x000002fd
+ * History = 2 entries
+ * Input target = 0x3a0000
+ * Interval = 5s
+ * linear-factors : offset = 0x0000 scale = 0x1000
+ * offset = 0x0091 scale = 0x0bae
+ *
+ * CPU Fan control loop. The loop is identical for all models. it
+ * has an additional pair of scaling factor. This is used to scale the
+ * systems fan control loop target result (the one before it gets scaled
+ * by the System Fans control loop itself). Then, the max value of the
+ * calculated target value and system fan value is sent to the fans
+ *
+ * controls : cpu-fan
+ * sensors : cpu-temp cpu-power
+ * PID params : From SMU sdb partition
+ * linear-factors : offset = 0xfb50 scale = 0x1000
+ *
+ * CPU Slew control loop. Not implemented. The cpufreq driver in linux is
+ * completely separate for now, though we could find a way to link it, either
+ * as a client reacting to overtemp notifications, or directling monitoring
+ * the CPU temperature
+ *
+ * WARNING ! The CPU control loop requires the CPU tmax for the current
+ * operating point. However, we currently are completely separated from
+ * the cpufreq driver and thus do not know what the current operating
+ * point is. Fortunately, we also do not have any hardware supporting anything
+ * but operating point 0 at the moment, thus we just peek that value directly
+ * from the SDB partition. If we ever end up with actually slewing the system
+ * clock and thus changing operating points, we'll have to find a way to
+ * communicate with the CPU freq driver;
+ *
+ */
+
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/spinlock.h>
+#include <linux/wait.h>
+#include <linux/kmod.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <asm/prom.h>
+#include <asm/machdep.h>
+#include <asm/io.h>
+#include <asm/system.h>
+#include <asm/sections.h>
+#include <asm/smu.h>
+
+#include "windfarm.h"
+#include "windfarm_pid.h"
+
+#define VERSION "0.4"
+
+#undef DEBUG
+
+#ifdef DEBUG
+#define DBG(args...) printk(args)
+#else
+#define DBG(args...) do { } while(0)
+#endif
+
+/* define this to force CPU overtemp to 74 degree, useful for testing
+ * the overtemp code
+ */
+#undef HACKED_OVERTEMP
+
+static int wf_smu_mach_model; /* machine model id */
+
+static struct device *wf_smu_dev;
+
+/* Controls & sensors */
+static struct wf_sensor *sensor_cpu_power;
+static struct wf_sensor *sensor_cpu_temp;
+static struct wf_sensor *sensor_hd_temp;
+static struct wf_control *fan_cpu_main;
+static struct wf_control *fan_hd;
+static struct wf_control *fan_system;
+static struct wf_control *cpufreq_clamp;
+
+/* Set to kick the control loop into life */
+static int wf_smu_all_controls_ok, wf_smu_all_sensors_ok, wf_smu_started;
+
+/* Failure handling.. could be nicer */
+#define FAILURE_FAN 0x01
+#define FAILURE_SENSOR 0x02
+#define FAILURE_OVERTEMP 0x04
+
+static unsigned int wf_smu_failure_state;
+static int wf_smu_readjust, wf_smu_skipping;
+
+/*
+ * ****** System Fans Control Loop ******
+ *
+ */
+
+/* Parameters for the System Fans control loop. Parameters
+ * not in this table such as interval, history size, ...
+ * are common to all versions and thus hard coded for now.
+ */
+struct wf_smu_sys_fans_param {
+ int model_id;
+ s32 itarget;
+ s32 gd, gp, gr;
+
+ s16 offset0;
+ u16 scale0;
+ s16 offset1;
+ u16 scale1;
+};
+
+#define WF_SMU_SYS_FANS_INTERVAL 5
+#define WF_SMU_SYS_FANS_HISTORY_SIZE 2
+
+/* State data used by the system fans control loop
+ */
+struct wf_smu_sys_fans_state {
+ int ticks;
+ s32 sys_setpoint;
+ s32 hd_setpoint;
+ s16 offset0;
+ u16 scale0;
+ s16 offset1;
+ u16 scale1;
+ struct wf_pid_state pid;
+};
+
+/*
+ * Configs for SMU Sytem Fan control loop
+ */
+static struct wf_smu_sys_fans_param wf_smu_sys_all_params[] = {
+ /* Model ID 2 */
+ {
+ .model_id = 2,
+ .itarget = 0x3a0000,
+ .gd = 0x15400000,
+ .gp = 0x00200000,
+ .gr = 0x000002fd,
+ .offset0 = 0xff38,
+ .scale0 = 0x0ccd,
+ .offset1 = 0x0208,
+ .scale1 = 0x07ae,
+ },
+ /* Model ID 3 */
+ {
+ .model_id = 2,
+ .itarget = 0x350000,
+ .gd = 0x08e00000,
+ .gp = 0x00566666,
+ .gr = 0x0000072b,
+ .offset0 = 0xff38,
+ .scale0 = 0x0ccd,
+ .offset1 = 0x0000,
+ .scale1 = 0x0000,
+ },
+ /* Model ID 5 */
+ {
+ .model_id = 2,
+ .itarget = 0x3a0000,
+ .gd = 0x15400000,
+ .gp = 0x00233333,
+ .gr = 0x000002fd,
+ .offset0 = 0x0000,
+ .scale0 = 0x1000,
+ .offset1 = 0x0091,
+ .scale1 = 0x0bae,
+ },
+};
+#define WF_SMU_SYS_FANS_NUM_CONFIGS ARRAY_SIZE(wf_smu_sys_all_params)
+
+static struct wf_smu_sys_fans_state *wf_smu_sys_fans;
+
+/*
+ * ****** CPU Fans Control Loop ******
+ *
+ */
+
+
+#define WF_SMU_CPU_FANS_INTERVAL 1
+#define WF_SMU_CPU_FANS_MAX_HISTORY 16
+#define WF_SMU_CPU_FANS_SIBLING_SCALE 0x00001000
+#define WF_SMU_CPU_FANS_SIBLING_OFFSET 0xfffffb50
+
+/* State data used by the cpu fans control loop
+ */
+struct wf_smu_cpu_fans_state {
+ int ticks;
+ s32 cpu_setpoint;
+ s32 scale;
+ s32 offset;
+ struct wf_cpu_pid_state pid;
+};
+
+static struct wf_smu_cpu_fans_state *wf_smu_cpu_fans;
+
+
+
+/*
+ * ***** Implementation *****
+ *
+ */
+
+static void wf_smu_create_sys_fans(void)
+{
+ struct wf_smu_sys_fans_param *param = NULL;
+ struct wf_pid_param pid_param;
+ int i;
+
+ /* First, locate the params for this model */
+ for (i = 0; i < WF_SMU_SYS_FANS_NUM_CONFIGS; i++)
+ if (wf_smu_sys_all_params[i].model_id == wf_smu_mach_model) {
+ param = &wf_smu_sys_all_params[i];
+ break;
+ }
+
+ /* No params found, put fans to max */
+ if (param == NULL) {
+ printk(KERN_WARNING "windfarm: System fan config not found "
+ "for this machine model, max fan speed\n");
+ goto fail;
+ }
+
+ /* Alloc & initialize state */
+ wf_smu_sys_fans = kmalloc(sizeof(struct wf_smu_sys_fans_state),
+ GFP_KERNEL);
+ if (wf_smu_sys_fans == NULL) {
+ printk(KERN_WARNING "windfarm: Memory allocation error"
+ " max fan speed\n");
+ goto fail;
+ }
+ wf_smu_sys_fans->ticks = 1;
+ wf_smu_sys_fans->scale0 = param->scale0;
+ wf_smu_sys_fans->offset0 = param->offset0;
+ wf_smu_sys_fans->scale1 = param->scale1;
+ wf_smu_sys_fans->offset1 = param->offset1;
+
+ /* Fill PID params */
+ pid_param.gd = param->gd;
+ pid_param.gp = param->gp;
+ pid_param.gr = param->gr;
+ pid_param.interval = WF_SMU_SYS_FANS_INTERVAL;
+ pid_param.history_len = WF_SMU_SYS_FANS_HISTORY_SIZE;
+ pid_param.itarget = param->itarget;
+ pid_param.min = fan_system->ops->get_min(fan_system);
+ pid_param.max = fan_system->ops->get_max(fan_system);
+ if (fan_hd) {
+ pid_param.min =
+ max(pid_param.min,fan_hd->ops->get_min(fan_hd));
+ pid_param.max =
+ min(pid_param.max,fan_hd->ops->get_max(fan_hd));
+ }
+ wf_pid_init(&wf_smu_sys_fans->pid, &pid_param);
+
+ DBG("wf: System Fan control initialized.\n");
+ DBG(" itarged=%d.%03d, min=%d RPM, max=%d RPM\n",
+ FIX32TOPRINT(pid_param.itarget), pid_param.min, pid_param.max);
+ return;
+
+ fail:
+
+ if (fan_system)
+ wf_control_set_max(fan_system);
+ if (fan_hd)
+ wf_control_set_max(fan_hd);
+}
+
+static void wf_smu_sys_fans_tick(struct wf_smu_sys_fans_state *st)
+{
+ s32 new_setpoint, temp, scaled, cputarget;
+ int rc;
+
+ if (--st->ticks != 0) {
+ if (wf_smu_readjust)
+ goto readjust;
+ return;
+ }
+ st->ticks = WF_SMU_SYS_FANS_INTERVAL;
+
+ rc = sensor_hd_temp->ops->get_value(sensor_hd_temp, &temp);
+ if (rc) {
+ printk(KERN_WARNING "windfarm: HD temp sensor error %d\n",
+ rc);
+ wf_smu_failure_state |= FAILURE_SENSOR;
+ return;
+ }
+
+ DBG("wf_smu: System Fans tick ! HD temp: %d.%03d\n",
+ FIX32TOPRINT(temp));
+
+ if (temp > (st->pid.param.itarget + 0x50000))
+ wf_smu_failure_state |= FAILURE_OVERTEMP;
+
+ new_setpoint = wf_pid_run(&st->pid, temp);
+
+ DBG("wf_smu: new_setpoint: %d RPM\n", (int)new_setpoint);
+
+ scaled = ((((s64)new_setpoint) * (s64)st->scale0) >> 12) + st->offset0;
+
+ DBG("wf_smu: scaled setpoint: %d RPM\n", (int)scaled);
+
+ cputarget = wf_smu_cpu_fans ? wf_smu_cpu_fans->pid.target : 0;
+ cputarget = ((((s64)cputarget) * (s64)st->scale1) >> 12) + st->offset1;
+ scaled = max(scaled, cputarget);
+ scaled = max(scaled, st->pid.param.min);
+ scaled = min(scaled, st->pid.param.max);
+
+ DBG("wf_smu: adjusted setpoint: %d RPM\n", (int)scaled);
+
+ if (st->sys_setpoint == scaled && new_setpoint == st->hd_setpoint)
+ return;
+ st->sys_setpoint = scaled;
+ st->hd_setpoint = new_setpoint;
+ readjust:
+ if (fan_system && wf_smu_failure_state == 0) {
+ rc = fan_system->ops->set_value(fan_system, st->sys_setpoint);
+ if (rc) {
+ printk(KERN_WARNING "windfarm: Sys fan error %d\n",
+ rc);
+ wf_smu_failure_state |= FAILURE_FAN;
+ }
+ }
+ if (fan_hd && wf_smu_failure_state == 0) {
+ rc = fan_hd->ops->set_value(fan_hd, st->hd_setpoint);
+ if (rc) {
+ printk(KERN_WARNING "windfarm: HD fan error %d\n",
+ rc);
+ wf_smu_failure_state |= FAILURE_FAN;
+ }
+ }
+}
+
+static void wf_smu_create_cpu_fans(void)
+{
+ struct wf_cpu_pid_param pid_param;
+ struct smu_sdbp_header *hdr;
+ struct smu_sdbp_cpupiddata *piddata;
+ struct smu_sdbp_fvt *fvt;
+ s32 tmax, tdelta, maxpow, powadj;
+
+ /* First, locate the PID params in SMU SBD */
+ hdr = smu_get_sdb_partition(SMU_SDB_CPUPIDDATA_ID, NULL);
+ if (hdr == 0) {
+ printk(KERN_WARNING "windfarm: CPU PID fan config not found "
+ "max fan speed\n");
+ goto fail;
+ }
+ piddata = (struct smu_sdbp_cpupiddata *)&hdr[1];
+
+ /* Get the FVT params for operating point 0 (the only supported one
+ * for now) in order to get tmax
+ */
+ hdr = smu_get_sdb_partition(SMU_SDB_FVT_ID, NULL);
+ if (hdr) {
+ fvt = (struct smu_sdbp_fvt *)&hdr[1];
+ tmax = ((s32)fvt->maxtemp) << 16;
+ } else
+ tmax = 0x5e0000; /* 94 degree default */
+
+ /* Alloc & initialize state */
+ wf_smu_cpu_fans = kmalloc(sizeof(struct wf_smu_cpu_fans_state),
+ GFP_KERNEL);
+ if (wf_smu_cpu_fans == NULL)
+ goto fail;
+ wf_smu_cpu_fans->ticks = 1;
+
+ wf_smu_cpu_fans->scale = WF_SMU_CPU_FANS_SIBLING_SCALE;
+ wf_smu_cpu_fans->offset = WF_SMU_CPU_FANS_SIBLING_OFFSET;
+
+ /* Fill PID params */
+ pid_param.interval = WF_SMU_CPU_FANS_INTERVAL;
+ pid_param.history_len = piddata->history_len;
+ if (pid_param.history_len > WF_CPU_PID_MAX_HISTORY) {
+ printk(KERN_WARNING "windfarm: History size overflow on "
+ "CPU control loop (%d)\n", piddata->history_len);
+ pid_param.history_len = WF_CPU_PID_MAX_HISTORY;
+ }
+ pid_param.gd = piddata->gd;
+ pid_param.gp = piddata->gp;
+ pid_param.gr = piddata->gr / pid_param.history_len;
+
+ tdelta = ((s32)piddata->target_temp_delta) << 16;
+ maxpow = ((s32)piddata->max_power) << 16;
+ powadj = ((s32)piddata->power_adj) << 16;
+
+ pid_param.tmax = tmax;
+ pid_param.ttarget = tmax - tdelta;
+ pid_param.pmaxadj = maxpow - powadj;
+
+ pid_param.min = fan_cpu_main->ops->get_min(fan_cpu_main);
+ pid_param.max = fan_cpu_main->ops->get_max(fan_cpu_main);
+
+ wf_cpu_pid_init(&wf_smu_cpu_fans->pid, &pid_param);
+
+ DBG("wf: CPU Fan control initialized.\n");
+ DBG(" ttarged=%d.%03d, tmax=%d.%03d, min=%d RPM, max=%d RPM\n",
+ FIX32TOPRINT(pid_param.ttarget), FIX32TOPRINT(pid_param.tmax),
+ pid_param.min, pid_param.max);
+
+ return;
+
+ fail:
+ printk(KERN_WARNING "windfarm: CPU fan config not found\n"
+ "for this machine model, max fan speed\n");
+
+ if (cpufreq_clamp)
+ wf_control_set_max(cpufreq_clamp);
+ if (fan_cpu_main)
+ wf_control_set_max(fan_cpu_main);
+}
+
+static void wf_smu_cpu_fans_tick(struct wf_smu_cpu_fans_state *st)
+{
+ s32 new_setpoint, temp, power, systarget;
+ int rc;
+
+ if (--st->ticks != 0) {
+ if (wf_smu_readjust)
+ goto readjust;
+ return;
+ }
+ st->ticks = WF_SMU_CPU_FANS_INTERVAL;
+
+ rc = sensor_cpu_temp->ops->get_value(sensor_cpu_temp, &temp);
+ if (rc) {
+ printk(KERN_WARNING "windfarm: CPU temp sensor error %d\n",
+ rc);
+ wf_smu_failure_state |= FAILURE_SENSOR;
+ return;
+ }
+
+ rc = sensor_cpu_power->ops->get_value(sensor_cpu_power, &power);
+ if (rc) {
+ printk(KERN_WARNING "windfarm: CPU power sensor error %d\n",
+ rc);
+ wf_smu_failure_state |= FAILURE_SENSOR;
+ return;
+ }
+
+ DBG("wf_smu: CPU Fans tick ! CPU temp: %d.%03d, power: %d.%03d\n",
+ FIX32TOPRINT(temp), FIX32TOPRINT(power));
+
+#ifdef HACKED_OVERTEMP
+ if (temp > 0x4a0000)
+ wf_smu_failure_state |= FAILURE_OVERTEMP;
+#else
+ if (temp > st->pid.param.tmax)
+ wf_smu_failure_state |= FAILURE_OVERTEMP;
+#endif
+ new_setpoint = wf_cpu_pid_run(&st->pid, power, temp);
+
+ DBG("wf_smu: new_setpoint: %d RPM\n", (int)new_setpoint);
+
+ systarget = wf_smu_sys_fans ? wf_smu_sys_fans->pid.target : 0;
+ systarget = ((((s64)systarget) * (s64)st->scale) >> 12)
+ + st->offset;
+ new_setpoint = max(new_setpoint, systarget);
+ new_setpoint = max(new_setpoint, st->pid.param.min);
+ new_setpoint = min(new_setpoint, st->pid.param.max);
+
+ DBG("wf_smu: adjusted setpoint: %d RPM\n", (int)new_setpoint);
+
+ if (st->cpu_setpoint == new_setpoint)
+ return;
+ st->cpu_setpoint = new_setpoint;
+ readjust:
+ if (fan_cpu_main && wf_smu_failure_state == 0) {
+ rc = fan_cpu_main->ops->set_value(fan_cpu_main,
+ st->cpu_setpoint);
+ if (rc) {
+ printk(KERN_WARNING "windfarm: CPU main fan"
+ " error %d\n", rc);
+ wf_smu_failure_state |= FAILURE_FAN;
+ }
+ }
+}
+
+
+/*
+ * ****** Attributes ******
+ *
+ */
+
+#define BUILD_SHOW_FUNC_FIX(name, data) \
+static ssize_t show_##name(struct device *dev, \
+ struct device_attribute *attr, \
+ char *buf) \
+{ \
+ ssize_t r; \
+ s32 val = 0; \
+ data->ops->get_value(data, &val); \
+ r = sprintf(buf, "%d.%03d", FIX32TOPRINT(val)); \
+ return r; \
+} \
+static DEVICE_ATTR(name,S_IRUGO,show_##name, NULL);
+
+
+#define BUILD_SHOW_FUNC_INT(name, data) \
+static ssize_t show_##name(struct device *dev, \
+ struct device_attribute *attr, \
+ char *buf) \
+{ \
+ s32 val = 0; \
+ data->ops->get_value(data, &val); \
+ return sprintf(buf, "%d", val); \
+} \
+static DEVICE_ATTR(name,S_IRUGO,show_##name, NULL);
+
+BUILD_SHOW_FUNC_INT(cpu_fan, fan_cpu_main);
+BUILD_SHOW_FUNC_INT(sys_fan, fan_system);
+BUILD_SHOW_FUNC_INT(hd_fan, fan_hd);
+
+BUILD_SHOW_FUNC_FIX(cpu_temp, sensor_cpu_temp);
+BUILD_SHOW_FUNC_FIX(cpu_power, sensor_cpu_power);
+BUILD_SHOW_FUNC_FIX(hd_temp, sensor_hd_temp);
+
+/*
+ * ****** Setup / Init / Misc ... ******
+ *
+ */
+
+static void wf_smu_tick(void)
+{
+ unsigned int last_failure = wf_smu_failure_state;
+ unsigned int new_failure;
+
+ if (!wf_smu_started) {
+ DBG("wf: creating control loops !\n");
+ wf_smu_create_sys_fans();
+ wf_smu_create_cpu_fans();
+ wf_smu_started = 1;
+ }
+
+ /* Skipping ticks */
+ if (wf_smu_skipping && --wf_smu_skipping)
+ return;
+
+ wf_smu_failure_state = 0;
+ if (wf_smu_sys_fans)
+ wf_smu_sys_fans_tick(wf_smu_sys_fans);
+ if (wf_smu_cpu_fans)
+ wf_smu_cpu_fans_tick(wf_smu_cpu_fans);
+
+ wf_smu_readjust = 0;
+ new_failure = wf_smu_failure_state & ~last_failure;
+
+ /* If entering failure mode, clamp cpufreq and ramp all
+ * fans to full speed.
+ */
+ if (wf_smu_failure_state && !last_failure) {
+ if (cpufreq_clamp)
+ wf_control_set_max(cpufreq_clamp);
+ if (fan_system)
+ wf_control_set_max(fan_system);
+ if (fan_cpu_main)
+ wf_control_set_max(fan_cpu_main);
+ if (fan_hd)
+ wf_control_set_max(fan_hd);
+ }
+
+ /* If leaving failure mode, unclamp cpufreq and readjust
+ * all fans on next iteration
+ */
+ if (!wf_smu_failure_state && last_failure) {
+ if (cpufreq_clamp)
+ wf_control_set_min(cpufreq_clamp);
+ wf_smu_readjust = 1;
+ }
+
+ /* Overtemp condition detected, notify and start skipping a couple
+ * ticks to let the temperature go down
+ */
+ if (new_failure & FAILURE_OVERTEMP) {
+ wf_set_overtemp();
+ wf_smu_skipping = 2;
+ }
+
+ /* We only clear the overtemp condition if overtemp is cleared
+ * _and_ no other failure is present. Since a sensor error will
+ * clear the overtemp condition (can't measure temperature) at
+ * the control loop levels, but we don't want to keep it clear
+ * here in this case
+ */
+ if (new_failure == 0 && last_failure & FAILURE_OVERTEMP)
+ wf_clear_overtemp();
+}
+
+static void wf_smu_new_control(struct wf_control *ct)
+{
+ if (wf_smu_all_controls_ok)
+ return;
+
+ if (fan_cpu_main == NULL && !strcmp(ct->name, "cpu-fan")) {
+ if (wf_get_control(ct) == 0) {
+ fan_cpu_main = ct;
+ device_create_file(wf_smu_dev, &dev_attr_cpu_fan);
+ }
+ }
+
+ if (fan_system == NULL && !strcmp(ct->name, "system-fan")) {
+ if (wf_get_control(ct) == 0) {
+ fan_system = ct;
+ device_create_file(wf_smu_dev, &dev_attr_sys_fan);
+ }
+ }
+
+ if (cpufreq_clamp == NULL && !strcmp(ct->name, "cpufreq-clamp")) {
+ if (wf_get_control(ct) == 0)
+ cpufreq_clamp = ct;
+ }
+
+ /* Darwin property list says the HD fan is only for model ID
+ * 0, 1, 2 and 3
+ */
+
+ if (wf_smu_mach_model > 3) {
+ if (fan_system && fan_cpu_main && cpufreq_clamp)
+ wf_smu_all_controls_ok = 1;
+ return;
+ }
+
+ if (fan_hd == NULL && !strcmp(ct->name, "drive-bay-fan")) {
+ if (wf_get_control(ct) == 0) {
+ fan_hd = ct;
+ device_create_file(wf_smu_dev, &dev_attr_hd_fan);
+ }
+ }
+
+ if (fan_system && fan_hd && fan_cpu_main && cpufreq_clamp)
+ wf_smu_all_controls_ok = 1;
+}
+
+static void wf_smu_new_sensor(struct wf_sensor *sr)
+{
+ if (wf_smu_all_sensors_ok)
+ return;
+
+ if (sensor_cpu_power == NULL && !strcmp(sr->name, "cpu-power")) {
+ if (wf_get_sensor(sr) == 0) {
+ sensor_cpu_power = sr;
+ device_create_file(wf_smu_dev, &dev_attr_cpu_power);
+ }
+ }
+
+ if (sensor_cpu_temp == NULL && !strcmp(sr->name, "cpu-temp")) {
+ if (wf_get_sensor(sr) == 0) {
+ sensor_cpu_temp = sr;
+ device_create_file(wf_smu_dev, &dev_attr_cpu_temp);
+ }
+ }
+
+ if (sensor_hd_temp == NULL && !strcmp(sr->name, "hd-temp")) {
+ if (wf_get_sensor(sr) == 0) {
+ sensor_hd_temp = sr;
+ device_create_file(wf_smu_dev, &dev_attr_hd_temp);
+ }
+ }
+
+ if (sensor_cpu_power && sensor_cpu_temp && sensor_hd_temp)
+ wf_smu_all_sensors_ok = 1;
+}
+
+
+static int wf_smu_notify(struct notifier_block *self,
+ unsigned long event, void *data)
+{
+ switch(event) {
+ case WF_EVENT_NEW_CONTROL:
+ DBG("wf: new control %s detected\n",
+ ((struct wf_control *)data)->name);
+ wf_smu_new_control(data);
+ wf_smu_readjust = 1;
+ break;
+ case WF_EVENT_NEW_SENSOR:
+ DBG("wf: new sensor %s detected\n",
+ ((struct wf_sensor *)data)->name);
+ wf_smu_new_sensor(data);
+ break;
+ case WF_EVENT_TICK:
+ if (wf_smu_all_controls_ok && wf_smu_all_sensors_ok)
+ wf_smu_tick();
+ }
+
+ return 0;
+}
+
+static struct notifier_block wf_smu_events = {
+ .notifier_call = wf_smu_notify,
+};
+
+static int wf_init_pm(void)
+{
+ struct smu_sdbp_header *hdr;
+
+ hdr = smu_get_sdb_partition(SMU_SDB_SENSORTREE_ID, NULL);
+ if (hdr != 0) {
+ struct smu_sdbp_sensortree *st =
+ (struct smu_sdbp_sensortree *)&hdr[1];
+ wf_smu_mach_model = st->model_id;
+ }
+
+ printk(KERN_INFO "windfarm: Initializing for iMacG5 model ID %d\n",
+ wf_smu_mach_model);
+
+ return 0;
+}
+
+static int wf_smu_probe(struct device *ddev)
+{
+ wf_smu_dev = ddev;
+
+ wf_register_client(&wf_smu_events);
+
+ return 0;
+}
+
+static int wf_smu_remove(struct device *ddev)
+{
+ wf_unregister_client(&wf_smu_events);
+
+ /* XXX We don't have yet a guarantee that our callback isn't
+ * in progress when returning from wf_unregister_client, so
+ * we add an arbitrary delay. I'll have to fix that in the core
+ */
+ msleep(1000);
+
+ /* Release all sensors */
+ /* One more crappy race: I don't think we have any guarantee here
+ * that the attribute callback won't race with the sensor beeing
+ * disposed of, and I'm not 100% certain what best way to deal
+ * with that except by adding locks all over... I'll do that
+ * eventually but heh, who ever rmmod this module anyway ?
+ */
+ if (sensor_cpu_power) {
+ device_remove_file(wf_smu_dev, &dev_attr_cpu_power);
+ wf_put_sensor(sensor_cpu_power);
+ }
+ if (sensor_cpu_temp) {
+ device_remove_file(wf_smu_dev, &dev_attr_cpu_temp);
+ wf_put_sensor(sensor_cpu_temp);
+ }
+ if (sensor_hd_temp) {
+ device_remove_file(wf_smu_dev, &dev_attr_hd_temp);
+ wf_put_sensor(sensor_hd_temp);
+ }
+
+ /* Release all controls */
+ if (fan_cpu_main) {
+ device_remove_file(wf_smu_dev, &dev_attr_cpu_fan);
+ wf_put_control(fan_cpu_main);
+ }
+ if (fan_hd) {
+ device_remove_file(wf_smu_dev, &dev_attr_hd_fan);
+ wf_put_control(fan_hd);
+ }
+ if (fan_system) {
+ device_remove_file(wf_smu_dev, &dev_attr_sys_fan);
+ wf_put_control(fan_system);
+ }
+ if (cpufreq_clamp)
+ wf_put_control(cpufreq_clamp);
+
+ /* Destroy control loops state structures */
+ if (wf_smu_sys_fans)
+ kfree(wf_smu_sys_fans);
+ if (wf_smu_cpu_fans)
+ kfree(wf_smu_cpu_fans);
+
+ wf_smu_dev = NULL;
+
+ return 0;
+}
+
+static struct device_driver wf_smu_driver = {
+ .name = "windfarm",
+ .bus = &platform_bus_type,
+ .probe = wf_smu_probe,
+ .remove = wf_smu_remove,
+};
+
+
+static int __init wf_smu_init(void)
+{
+ int rc = -ENODEV;
+
+ if (machine_is_compatible("PowerMac8,1") ||
+ machine_is_compatible("PowerMac8,2"))
+ rc = wf_init_pm();
+
+ if (rc == 0) {
+#ifdef MODULE
+ request_module("windfarm_smu_controls");
+ request_module("windfarm_smu_sensors");
+ request_module("windfarm_lm75_sensor");
+
+#endif /* MODULE */
+ driver_register(&wf_smu_driver);
+ }
+
+ return rc;
+}
+
+static void __exit wf_smu_exit(void)
+{
+
+ driver_unregister(&wf_smu_driver);
+}
+
+
+module_init(wf_smu_init);
+module_exit(wf_smu_exit);
+
+MODULE_AUTHOR("Benjamin Herrenschmidt <benh@kernel.crashing.org>");
+MODULE_DESCRIPTION("Thermal control logic for iMac G5");
+MODULE_LICENSE("GPL");
+
diff --git a/drivers/macintosh/windfarm_pm91.c b/drivers/macintosh/windfarm_pm91.c
new file mode 100644
index 000000000000..43243cf7410b
--- /dev/null
+++ b/drivers/macintosh/windfarm_pm91.c
@@ -0,0 +1,814 @@
+/*
+ * Windfarm PowerMac thermal control. SMU based 1 CPU desktop control loops
+ *
+ * (c) Copyright 2005 Benjamin Herrenschmidt, IBM Corp.
+ * <benh@kernel.crashing.org>
+ *
+ * Released under the term of the GNU GPL v2.
+ *
+ * The algorithm used is the PID control algorithm, used the same
+ * way the published Darwin code does, using the same values that
+ * are present in the Darwin 8.2 snapshot property lists (note however
+ * that none of the code has been re-used, it's a complete re-implementation
+ *
+ * The various control loops found in Darwin config file are:
+ *
+ * PowerMac9,1
+ * ===========
+ *
+ * Has 3 control loops: CPU fans is similar to PowerMac8,1 (though it doesn't
+ * try to play with other control loops fans). Drive bay is rather basic PID
+ * with one sensor and one fan. Slots area is a bit different as the Darwin
+ * driver is supposed to be capable of working in a special "AGP" mode which
+ * involves the presence of an AGP sensor and an AGP fan (possibly on the
+ * AGP card itself). I can't deal with that special mode as I don't have
+ * access to those additional sensor/fans for now (though ultimately, it would
+ * be possible to add sensor objects for them) so I'm only implementing the
+ * basic PCI slot control loop
+ */
+
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/spinlock.h>
+#include <linux/wait.h>
+#include <linux/kmod.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <asm/prom.h>
+#include <asm/machdep.h>
+#include <asm/io.h>
+#include <asm/system.h>
+#include <asm/sections.h>
+#include <asm/smu.h>
+
+#include "windfarm.h"
+#include "windfarm_pid.h"
+
+#define VERSION "0.4"
+
+#undef DEBUG
+
+#ifdef DEBUG
+#define DBG(args...) printk(args)
+#else
+#define DBG(args...) do { } while(0)
+#endif
+
+/* define this to force CPU overtemp to 74 degree, useful for testing
+ * the overtemp code
+ */
+#undef HACKED_OVERTEMP
+
+static struct device *wf_smu_dev;
+
+/* Controls & sensors */
+static struct wf_sensor *sensor_cpu_power;
+static struct wf_sensor *sensor_cpu_temp;
+static struct wf_sensor *sensor_hd_temp;
+static struct wf_sensor *sensor_slots_power;
+static struct wf_control *fan_cpu_main;
+static struct wf_control *fan_cpu_second;
+static struct wf_control *fan_cpu_third;
+static struct wf_control *fan_hd;
+static struct wf_control *fan_slots;
+static struct wf_control *cpufreq_clamp;
+
+/* Set to kick the control loop into life */
+static int wf_smu_all_controls_ok, wf_smu_all_sensors_ok, wf_smu_started;
+
+/* Failure handling.. could be nicer */
+#define FAILURE_FAN 0x01
+#define FAILURE_SENSOR 0x02
+#define FAILURE_OVERTEMP 0x04
+
+static unsigned int wf_smu_failure_state;
+static int wf_smu_readjust, wf_smu_skipping;
+
+/*
+ * ****** CPU Fans Control Loop ******
+ *
+ */
+
+
+#define WF_SMU_CPU_FANS_INTERVAL 1
+#define WF_SMU_CPU_FANS_MAX_HISTORY 16
+
+/* State data used by the cpu fans control loop
+ */
+struct wf_smu_cpu_fans_state {
+ int ticks;
+ s32 cpu_setpoint;
+ struct wf_cpu_pid_state pid;
+};
+
+static struct wf_smu_cpu_fans_state *wf_smu_cpu_fans;
+
+
+
+/*
+ * ****** Drive Fan Control Loop ******
+ *
+ */
+
+struct wf_smu_drive_fans_state {
+ int ticks;
+ s32 setpoint;
+ struct wf_pid_state pid;
+};
+
+static struct wf_smu_drive_fans_state *wf_smu_drive_fans;
+
+/*
+ * ****** Slots Fan Control Loop ******
+ *
+ */
+
+struct wf_smu_slots_fans_state {
+ int ticks;
+ s32 setpoint;
+ struct wf_pid_state pid;
+};
+
+static struct wf_smu_slots_fans_state *wf_smu_slots_fans;
+
+/*
+ * ***** Implementation *****
+ *
+ */
+
+
+static void wf_smu_create_cpu_fans(void)
+{
+ struct wf_cpu_pid_param pid_param;
+ struct smu_sdbp_header *hdr;
+ struct smu_sdbp_cpupiddata *piddata;
+ struct smu_sdbp_fvt *fvt;
+ s32 tmax, tdelta, maxpow, powadj;
+
+ /* First, locate the PID params in SMU SBD */
+ hdr = smu_get_sdb_partition(SMU_SDB_CPUPIDDATA_ID, NULL);
+ if (hdr == 0) {
+ printk(KERN_WARNING "windfarm: CPU PID fan config not found "
+ "max fan speed\n");
+ goto fail;
+ }
+ piddata = (struct smu_sdbp_cpupiddata *)&hdr[1];
+
+ /* Get the FVT params for operating point 0 (the only supported one
+ * for now) in order to get tmax
+ */
+ hdr = smu_get_sdb_partition(SMU_SDB_FVT_ID, NULL);
+ if (hdr) {
+ fvt = (struct smu_sdbp_fvt *)&hdr[1];
+ tmax = ((s32)fvt->maxtemp) << 16;
+ } else
+ tmax = 0x5e0000; /* 94 degree default */
+
+ /* Alloc & initialize state */
+ wf_smu_cpu_fans = kmalloc(sizeof(struct wf_smu_cpu_fans_state),
+ GFP_KERNEL);
+ if (wf_smu_cpu_fans == NULL)
+ goto fail;
+ wf_smu_cpu_fans->ticks = 1;
+
+ /* Fill PID params */
+ pid_param.interval = WF_SMU_CPU_FANS_INTERVAL;
+ pid_param.history_len = piddata->history_len;
+ if (pid_param.history_len > WF_CPU_PID_MAX_HISTORY) {
+ printk(KERN_WARNING "windfarm: History size overflow on "
+ "CPU control loop (%d)\n", piddata->history_len);
+ pid_param.history_len = WF_CPU_PID_MAX_HISTORY;
+ }
+ pid_param.gd = piddata->gd;
+ pid_param.gp = piddata->gp;
+ pid_param.gr = piddata->gr / pid_param.history_len;
+
+ tdelta = ((s32)piddata->target_temp_delta) << 16;
+ maxpow = ((s32)piddata->max_power) << 16;
+ powadj = ((s32)piddata->power_adj) << 16;
+
+ pid_param.tmax = tmax;
+ pid_param.ttarget = tmax - tdelta;
+ pid_param.pmaxadj = maxpow - powadj;
+
+ pid_param.min = fan_cpu_main->ops->get_min(fan_cpu_main);
+ pid_param.max = fan_cpu_main->ops->get_max(fan_cpu_main);
+
+ wf_cpu_pid_init(&wf_smu_cpu_fans->pid, &pid_param);
+
+ DBG("wf: CPU Fan control initialized.\n");
+ DBG(" ttarged=%d.%03d, tmax=%d.%03d, min=%d RPM, max=%d RPM\n",
+ FIX32TOPRINT(pid_param.ttarget), FIX32TOPRINT(pid_param.tmax),
+ pid_param.min, pid_param.max);
+
+ return;
+
+ fail:
+ printk(KERN_WARNING "windfarm: CPU fan config not found\n"
+ "for this machine model, max fan speed\n");
+
+ if (cpufreq_clamp)
+ wf_control_set_max(cpufreq_clamp);
+ if (fan_cpu_main)
+ wf_control_set_max(fan_cpu_main);
+}
+
+static void wf_smu_cpu_fans_tick(struct wf_smu_cpu_fans_state *st)
+{
+ s32 new_setpoint, temp, power;
+ int rc;
+
+ if (--st->ticks != 0) {
+ if (wf_smu_readjust)
+ goto readjust;
+ return;
+ }
+ st->ticks = WF_SMU_CPU_FANS_INTERVAL;
+
+ rc = sensor_cpu_temp->ops->get_value(sensor_cpu_temp, &temp);
+ if (rc) {
+ printk(KERN_WARNING "windfarm: CPU temp sensor error %d\n",
+ rc);
+ wf_smu_failure_state |= FAILURE_SENSOR;
+ return;
+ }
+
+ rc = sensor_cpu_power->ops->get_value(sensor_cpu_power, &power);
+ if (rc) {
+ printk(KERN_WARNING "windfarm: CPU power sensor error %d\n",
+ rc);
+ wf_smu_failure_state |= FAILURE_SENSOR;
+ return;
+ }
+
+ DBG("wf_smu: CPU Fans tick ! CPU temp: %d.%03d, power: %d.%03d\n",
+ FIX32TOPRINT(temp), FIX32TOPRINT(power));
+
+#ifdef HACKED_OVERTEMP
+ if (temp > 0x4a0000)
+ wf_smu_failure_state |= FAILURE_OVERTEMP;
+#else
+ if (temp > st->pid.param.tmax)
+ wf_smu_failure_state |= FAILURE_OVERTEMP;
+#endif
+ new_setpoint = wf_cpu_pid_run(&st->pid, power, temp);
+
+ DBG("wf_smu: new_setpoint: %d RPM\n", (int)new_setpoint);
+
+ if (st->cpu_setpoint == new_setpoint)
+ return;
+ st->cpu_setpoint = new_setpoint;
+ readjust:
+ if (fan_cpu_main && wf_smu_failure_state == 0) {
+ rc = fan_cpu_main->ops->set_value(fan_cpu_main,
+ st->cpu_setpoint);
+ if (rc) {
+ printk(KERN_WARNING "windfarm: CPU main fan"
+ " error %d\n", rc);
+ wf_smu_failure_state |= FAILURE_FAN;
+ }
+ }
+ if (fan_cpu_second && wf_smu_failure_state == 0) {
+ rc = fan_cpu_second->ops->set_value(fan_cpu_second,
+ st->cpu_setpoint);
+ if (rc) {
+ printk(KERN_WARNING "windfarm: CPU second fan"
+ " error %d\n", rc);
+ wf_smu_failure_state |= FAILURE_FAN;
+ }
+ }
+ if (fan_cpu_third && wf_smu_failure_state == 0) {
+ rc = fan_cpu_main->ops->set_value(fan_cpu_third,
+ st->cpu_setpoint);
+ if (rc) {
+ printk(KERN_WARNING "windfarm: CPU third fan"
+ " error %d\n", rc);
+ wf_smu_failure_state |= FAILURE_FAN;
+ }
+ }
+}
+
+static void wf_smu_create_drive_fans(void)
+{
+ struct wf_pid_param param = {
+ .interval = 5,
+ .history_len = 2,
+ .gd = 0x01e00000,
+ .gp = 0x00500000,
+ .gr = 0x00000000,
+ .itarget = 0x00200000,
+ };
+
+ /* Alloc & initialize state */
+ wf_smu_drive_fans = kmalloc(sizeof(struct wf_smu_drive_fans_state),
+ GFP_KERNEL);
+ if (wf_smu_drive_fans == NULL) {
+ printk(KERN_WARNING "windfarm: Memory allocation error"
+ " max fan speed\n");
+ goto fail;
+ }
+ wf_smu_drive_fans->ticks = 1;
+
+ /* Fill PID params */
+ param.additive = (fan_hd->type == WF_CONTROL_RPM_FAN);
+ param.min = fan_hd->ops->get_min(fan_hd);
+ param.max = fan_hd->ops->get_max(fan_hd);
+ wf_pid_init(&wf_smu_drive_fans->pid, &param);
+
+ DBG("wf: Drive Fan control initialized.\n");
+ DBG(" itarged=%d.%03d, min=%d RPM, max=%d RPM\n",
+ FIX32TOPRINT(param.itarget), param.min, param.max);
+ return;
+
+ fail:
+ if (fan_hd)
+ wf_control_set_max(fan_hd);
+}
+
+static void wf_smu_drive_fans_tick(struct wf_smu_drive_fans_state *st)
+{
+ s32 new_setpoint, temp;
+ int rc;
+
+ if (--st->ticks != 0) {
+ if (wf_smu_readjust)
+ goto readjust;
+ return;
+ }
+ st->ticks = st->pid.param.interval;
+
+ rc = sensor_hd_temp->ops->get_value(sensor_hd_temp, &temp);
+ if (rc) {
+ printk(KERN_WARNING "windfarm: HD temp sensor error %d\n",
+ rc);
+ wf_smu_failure_state |= FAILURE_SENSOR;
+ return;
+ }
+
+ DBG("wf_smu: Drive Fans tick ! HD temp: %d.%03d\n",
+ FIX32TOPRINT(temp));
+
+ if (temp > (st->pid.param.itarget + 0x50000))
+ wf_smu_failure_state |= FAILURE_OVERTEMP;
+
+ new_setpoint = wf_pid_run(&st->pid, temp);
+
+ DBG("wf_smu: new_setpoint: %d\n", (int)new_setpoint);
+
+ if (st->setpoint == new_setpoint)
+ return;
+ st->setpoint = new_setpoint;
+ readjust:
+ if (fan_hd && wf_smu_failure_state == 0) {
+ rc = fan_hd->ops->set_value(fan_hd, st->setpoint);
+ if (rc) {
+ printk(KERN_WARNING "windfarm: HD fan error %d\n",
+ rc);
+ wf_smu_failure_state |= FAILURE_FAN;
+ }
+ }
+}
+
+static void wf_smu_create_slots_fans(void)
+{
+ struct wf_pid_param param = {
+ .interval = 1,
+ .history_len = 8,
+ .gd = 0x00000000,
+ .gp = 0x00000000,
+ .gr = 0x00020000,
+ .itarget = 0x00000000
+ };
+
+ /* Alloc & initialize state */
+ wf_smu_slots_fans = kmalloc(sizeof(struct wf_smu_slots_fans_state),
+ GFP_KERNEL);
+ if (wf_smu_slots_fans == NULL) {
+ printk(KERN_WARNING "windfarm: Memory allocation error"
+ " max fan speed\n");
+ goto fail;
+ }
+ wf_smu_slots_fans->ticks = 1;
+
+ /* Fill PID params */
+ param.additive = (fan_slots->type == WF_CONTROL_RPM_FAN);
+ param.min = fan_slots->ops->get_min(fan_slots);
+ param.max = fan_slots->ops->get_max(fan_slots);
+ wf_pid_init(&wf_smu_slots_fans->pid, &param);
+
+ DBG("wf: Slots Fan control initialized.\n");
+ DBG(" itarged=%d.%03d, min=%d RPM, max=%d RPM\n",
+ FIX32TOPRINT(param.itarget), param.min, param.max);
+ return;
+
+ fail:
+ if (fan_slots)
+ wf_control_set_max(fan_slots);
+}
+
+static void wf_smu_slots_fans_tick(struct wf_smu_slots_fans_state *st)
+{
+ s32 new_setpoint, power;
+ int rc;
+
+ if (--st->ticks != 0) {
+ if (wf_smu_readjust)
+ goto readjust;
+ return;
+ }
+ st->ticks = st->pid.param.interval;
+
+ rc = sensor_slots_power->ops->get_value(sensor_slots_power, &power);
+ if (rc) {
+ printk(KERN_WARNING "windfarm: Slots power sensor error %d\n",
+ rc);
+ wf_smu_failure_state |= FAILURE_SENSOR;
+ return;
+ }
+
+ DBG("wf_smu: Slots Fans tick ! Slots power: %d.%03d\n",
+ FIX32TOPRINT(power));
+
+#if 0 /* Check what makes a good overtemp condition */
+ if (power > (st->pid.param.itarget + 0x50000))
+ wf_smu_failure_state |= FAILURE_OVERTEMP;
+#endif
+
+ new_setpoint = wf_pid_run(&st->pid, power);
+
+ DBG("wf_smu: new_setpoint: %d\n", (int)new_setpoint);
+
+ if (st->setpoint == new_setpoint)
+ return;
+ st->setpoint = new_setpoint;
+ readjust:
+ if (fan_slots && wf_smu_failure_state == 0) {
+ rc = fan_slots->ops->set_value(fan_slots, st->setpoint);
+ if (rc) {
+ printk(KERN_WARNING "windfarm: Slots fan error %d\n",
+ rc);
+ wf_smu_failure_state |= FAILURE_FAN;
+ }
+ }
+}
+
+
+/*
+ * ****** Attributes ******
+ *
+ */
+
+#define BUILD_SHOW_FUNC_FIX(name, data) \
+static ssize_t show_##name(struct device *dev, \
+ struct device_attribute *attr, \
+ char *buf) \
+{ \
+ ssize_t r; \
+ s32 val = 0; \
+ data->ops->get_value(data, &val); \
+ r = sprintf(buf, "%d.%03d", FIX32TOPRINT(val)); \
+ return r; \
+} \
+static DEVICE_ATTR(name,S_IRUGO,show_##name, NULL);
+
+
+#define BUILD_SHOW_FUNC_INT(name, data) \
+static ssize_t show_##name(struct device *dev, \
+ struct device_attribute *attr, \
+ char *buf) \
+{ \
+ s32 val = 0; \
+ data->ops->get_value(data, &val); \
+ return sprintf(buf, "%d", val); \
+} \
+static DEVICE_ATTR(name,S_IRUGO,show_##name, NULL);
+
+BUILD_SHOW_FUNC_INT(cpu_fan, fan_cpu_main);
+BUILD_SHOW_FUNC_INT(hd_fan, fan_hd);
+BUILD_SHOW_FUNC_INT(slots_fan, fan_slots);
+
+BUILD_SHOW_FUNC_FIX(cpu_temp, sensor_cpu_temp);
+BUILD_SHOW_FUNC_FIX(cpu_power, sensor_cpu_power);
+BUILD_SHOW_FUNC_FIX(hd_temp, sensor_hd_temp);
+BUILD_SHOW_FUNC_FIX(slots_power, sensor_slots_power);
+
+/*
+ * ****** Setup / Init / Misc ... ******
+ *
+ */
+
+static void wf_smu_tick(void)
+{
+ unsigned int last_failure = wf_smu_failure_state;
+ unsigned int new_failure;
+
+ if (!wf_smu_started) {
+ DBG("wf: creating control loops !\n");
+ wf_smu_create_drive_fans();
+ wf_smu_create_slots_fans();
+ wf_smu_create_cpu_fans();
+ wf_smu_started = 1;
+ }
+
+ /* Skipping ticks */
+ if (wf_smu_skipping && --wf_smu_skipping)
+ return;
+
+ wf_smu_failure_state = 0;
+ if (wf_smu_drive_fans)
+ wf_smu_drive_fans_tick(wf_smu_drive_fans);
+ if (wf_smu_slots_fans)
+ wf_smu_slots_fans_tick(wf_smu_slots_fans);
+ if (wf_smu_cpu_fans)
+ wf_smu_cpu_fans_tick(wf_smu_cpu_fans);
+
+ wf_smu_readjust = 0;
+ new_failure = wf_smu_failure_state & ~last_failure;
+
+ /* If entering failure mode, clamp cpufreq and ramp all
+ * fans to full speed.
+ */
+ if (wf_smu_failure_state && !last_failure) {
+ if (cpufreq_clamp)
+ wf_control_set_max(cpufreq_clamp);
+ if (fan_cpu_main)
+ wf_control_set_max(fan_cpu_main);
+ if (fan_cpu_second)
+ wf_control_set_max(fan_cpu_second);
+ if (fan_cpu_third)
+ wf_control_set_max(fan_cpu_third);
+ if (fan_hd)
+ wf_control_set_max(fan_hd);
+ if (fan_slots)
+ wf_control_set_max(fan_slots);
+ }
+
+ /* If leaving failure mode, unclamp cpufreq and readjust
+ * all fans on next iteration
+ */
+ if (!wf_smu_failure_state && last_failure) {
+ if (cpufreq_clamp)
+ wf_control_set_min(cpufreq_clamp);
+ wf_smu_readjust = 1;
+ }
+
+ /* Overtemp condition detected, notify and start skipping a couple
+ * ticks to let the temperature go down
+ */
+ if (new_failure & FAILURE_OVERTEMP) {
+ wf_set_overtemp();
+ wf_smu_skipping = 2;
+ }
+
+ /* We only clear the overtemp condition if overtemp is cleared
+ * _and_ no other failure is present. Since a sensor error will
+ * clear the overtemp condition (can't measure temperature) at
+ * the control loop levels, but we don't want to keep it clear
+ * here in this case
+ */
+ if (new_failure == 0 && last_failure & FAILURE_OVERTEMP)
+ wf_clear_overtemp();
+}
+
+
+static void wf_smu_new_control(struct wf_control *ct)
+{
+ if (wf_smu_all_controls_ok)
+ return;
+
+ if (fan_cpu_main == NULL && !strcmp(ct->name, "cpu-rear-fan-0")) {
+ if (wf_get_control(ct) == 0) {
+ fan_cpu_main = ct;
+ device_create_file(wf_smu_dev, &dev_attr_cpu_fan);
+ }
+ }
+
+ if (fan_cpu_second == NULL && !strcmp(ct->name, "cpu-rear-fan-1")) {
+ if (wf_get_control(ct) == 0)
+ fan_cpu_second = ct;
+ }
+
+ if (fan_cpu_third == NULL && !strcmp(ct->name, "cpu-front-fan-0")) {
+ if (wf_get_control(ct) == 0)
+ fan_cpu_third = ct;
+ }
+
+ if (cpufreq_clamp == NULL && !strcmp(ct->name, "cpufreq-clamp")) {
+ if (wf_get_control(ct) == 0)
+ cpufreq_clamp = ct;
+ }
+
+ if (fan_hd == NULL && !strcmp(ct->name, "drive-bay-fan")) {
+ if (wf_get_control(ct) == 0) {
+ fan_hd = ct;
+ device_create_file(wf_smu_dev, &dev_attr_hd_fan);
+ }
+ }
+
+ if (fan_slots == NULL && !strcmp(ct->name, "slots-fan")) {
+ if (wf_get_control(ct) == 0) {
+ fan_slots = ct;
+ device_create_file(wf_smu_dev, &dev_attr_slots_fan);
+ }
+ }
+
+ if (fan_cpu_main && (fan_cpu_second || fan_cpu_third) && fan_hd &&
+ fan_slots && cpufreq_clamp)
+ wf_smu_all_controls_ok = 1;
+}
+
+static void wf_smu_new_sensor(struct wf_sensor *sr)
+{
+ if (wf_smu_all_sensors_ok)
+ return;
+
+ if (sensor_cpu_power == NULL && !strcmp(sr->name, "cpu-power")) {
+ if (wf_get_sensor(sr) == 0) {
+ sensor_cpu_power = sr;
+ device_create_file(wf_smu_dev, &dev_attr_cpu_power);
+ }
+ }
+
+ if (sensor_cpu_temp == NULL && !strcmp(sr->name, "cpu-temp")) {
+ if (wf_get_sensor(sr) == 0) {
+ sensor_cpu_temp = sr;
+ device_create_file(wf_smu_dev, &dev_attr_cpu_temp);
+ }
+ }
+
+ if (sensor_hd_temp == NULL && !strcmp(sr->name, "hd-temp")) {
+ if (wf_get_sensor(sr) == 0) {
+ sensor_hd_temp = sr;
+ device_create_file(wf_smu_dev, &dev_attr_hd_temp);
+ }
+ }
+
+ if (sensor_slots_power == NULL && !strcmp(sr->name, "slots-power")) {
+ if (wf_get_sensor(sr) == 0) {
+ sensor_slots_power = sr;
+ device_create_file(wf_smu_dev, &dev_attr_slots_power);
+ }
+ }
+
+ if (sensor_cpu_power && sensor_cpu_temp &&
+ sensor_hd_temp && sensor_slots_power)
+ wf_smu_all_sensors_ok = 1;
+}
+
+
+static int wf_smu_notify(struct notifier_block *self,
+ unsigned long event, void *data)
+{
+ switch(event) {
+ case WF_EVENT_NEW_CONTROL:
+ DBG("wf: new control %s detected\n",
+ ((struct wf_control *)data)->name);
+ wf_smu_new_control(data);
+ wf_smu_readjust = 1;
+ break;
+ case WF_EVENT_NEW_SENSOR:
+ DBG("wf: new sensor %s detected\n",
+ ((struct wf_sensor *)data)->name);
+ wf_smu_new_sensor(data);
+ break;
+ case WF_EVENT_TICK:
+ if (wf_smu_all_controls_ok && wf_smu_all_sensors_ok)
+ wf_smu_tick();
+ }
+
+ return 0;
+}
+
+static struct notifier_block wf_smu_events = {
+ .notifier_call = wf_smu_notify,
+};
+
+static int wf_init_pm(void)
+{
+ printk(KERN_INFO "windfarm: Initializing for Desktop G5 model\n");
+
+ return 0;
+}
+
+static int wf_smu_probe(struct device *ddev)
+{
+ wf_smu_dev = ddev;
+
+ wf_register_client(&wf_smu_events);
+
+ return 0;
+}
+
+static int wf_smu_remove(struct device *ddev)
+{
+ wf_unregister_client(&wf_smu_events);
+
+ /* XXX We don't have yet a guarantee that our callback isn't
+ * in progress when returning from wf_unregister_client, so
+ * we add an arbitrary delay. I'll have to fix that in the core
+ */
+ msleep(1000);
+
+ /* Release all sensors */
+ /* One more crappy race: I don't think we have any guarantee here
+ * that the attribute callback won't race with the sensor beeing
+ * disposed of, and I'm not 100% certain what best way to deal
+ * with that except by adding locks all over... I'll do that
+ * eventually but heh, who ever rmmod this module anyway ?
+ */
+ if (sensor_cpu_power) {
+ device_remove_file(wf_smu_dev, &dev_attr_cpu_power);
+ wf_put_sensor(sensor_cpu_power);
+ }
+ if (sensor_cpu_temp) {
+ device_remove_file(wf_smu_dev, &dev_attr_cpu_temp);
+ wf_put_sensor(sensor_cpu_temp);
+ }
+ if (sensor_hd_temp) {
+ device_remove_file(wf_smu_dev, &dev_attr_hd_temp);
+ wf_put_sensor(sensor_hd_temp);
+ }
+ if (sensor_slots_power) {
+ device_remove_file(wf_smu_dev, &dev_attr_slots_power);
+ wf_put_sensor(sensor_slots_power);
+ }
+
+ /* Release all controls */
+ if (fan_cpu_main) {
+ device_remove_file(wf_smu_dev, &dev_attr_cpu_fan);
+ wf_put_control(fan_cpu_main);
+ }
+ if (fan_cpu_second)
+ wf_put_control(fan_cpu_second);
+ if (fan_cpu_third)
+ wf_put_control(fan_cpu_third);
+ if (fan_hd) {
+ device_remove_file(wf_smu_dev, &dev_attr_hd_fan);
+ wf_put_control(fan_hd);
+ }
+ if (fan_slots) {
+ device_remove_file(wf_smu_dev, &dev_attr_slots_fan);
+ wf_put_control(fan_slots);
+ }
+ if (cpufreq_clamp)
+ wf_put_control(cpufreq_clamp);
+
+ /* Destroy control loops state structures */
+ if (wf_smu_slots_fans)
+ kfree(wf_smu_cpu_fans);
+ if (wf_smu_drive_fans)
+ kfree(wf_smu_cpu_fans);
+ if (wf_smu_cpu_fans)
+ kfree(wf_smu_cpu_fans);
+
+ wf_smu_dev = NULL;
+
+ return 0;
+}
+
+static struct device_driver wf_smu_driver = {
+ .name = "windfarm",
+ .bus = &platform_bus_type,
+ .probe = wf_smu_probe,
+ .remove = wf_smu_remove,
+};
+
+
+static int __init wf_smu_init(void)
+{
+ int rc = -ENODEV;
+
+ if (machine_is_compatible("PowerMac9,1"))
+ rc = wf_init_pm();
+
+ if (rc == 0) {
+#ifdef MODULE
+ request_module("windfarm_smu_controls");
+ request_module("windfarm_smu_sensors");
+ request_module("windfarm_lm75_sensor");
+
+#endif /* MODULE */
+ driver_register(&wf_smu_driver);
+ }
+
+ return rc;
+}
+
+static void __exit wf_smu_exit(void)
+{
+
+ driver_unregister(&wf_smu_driver);
+}
+
+
+module_init(wf_smu_init);
+module_exit(wf_smu_exit);
+
+MODULE_AUTHOR("Benjamin Herrenschmidt <benh@kernel.crashing.org>");
+MODULE_DESCRIPTION("Thermal control logic for PowerMac9,1");
+MODULE_LICENSE("GPL");
+
diff --git a/drivers/macintosh/windfarm_smu_controls.c b/drivers/macintosh/windfarm_smu_controls.c
new file mode 100644
index 000000000000..2c3158c81ff2
--- /dev/null
+++ b/drivers/macintosh/windfarm_smu_controls.c
@@ -0,0 +1,282 @@
+/*
+ * Windfarm PowerMac thermal control. SMU based controls
+ *
+ * (c) Copyright 2005 Benjamin Herrenschmidt, IBM Corp.
+ * <benh@kernel.crashing.org>
+ *
+ * Released under the term of the GNU GPL v2.
+ */
+
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/wait.h>
+#include <asm/prom.h>
+#include <asm/machdep.h>
+#include <asm/io.h>
+#include <asm/system.h>
+#include <asm/sections.h>
+#include <asm/smu.h>
+
+#include "windfarm.h"
+
+#define VERSION "0.3"
+
+#undef DEBUG
+
+#ifdef DEBUG
+#define DBG(args...) printk(args)
+#else
+#define DBG(args...) do { } while(0)
+#endif
+
+/*
+ * SMU fans control object
+ */
+
+static LIST_HEAD(smu_fans);
+
+struct smu_fan_control {
+ struct list_head link;
+ int fan_type; /* 0 = rpm, 1 = pwm */
+ u32 reg; /* index in SMU */
+ s32 value; /* current value */
+ s32 min, max; /* min/max values */
+ struct wf_control ctrl;
+};
+#define to_smu_fan(c) container_of(c, struct smu_fan_control, ctrl)
+
+static int smu_set_fan(int pwm, u8 id, u16 value)
+{
+ struct smu_cmd cmd;
+ u8 buffer[16];
+ DECLARE_COMPLETION(comp);
+ int rc;
+
+ /* Fill SMU command structure */
+ cmd.cmd = SMU_CMD_FAN_COMMAND;
+ cmd.data_len = 14;
+ cmd.reply_len = 16;
+ cmd.data_buf = cmd.reply_buf = buffer;
+ cmd.status = 0;
+ cmd.done = smu_done_complete;
+ cmd.misc = &comp;
+
+ /* Fill argument buffer */
+ memset(buffer, 0, 16);
+ buffer[0] = pwm ? 0x10 : 0x00;
+ buffer[1] = 0x01 << id;
+ *((u16 *)&buffer[2 + id * 2]) = value;
+
+ rc = smu_queue_cmd(&cmd);
+ if (rc)
+ return rc;
+ wait_for_completion(&comp);
+ return cmd.status;
+}
+
+static void smu_fan_release(struct wf_control *ct)
+{
+ struct smu_fan_control *fct = to_smu_fan(ct);
+
+ kfree(fct);
+}
+
+static int smu_fan_set(struct wf_control *ct, s32 value)
+{
+ struct smu_fan_control *fct = to_smu_fan(ct);
+
+ if (value < fct->min)
+ value = fct->min;
+ if (value > fct->max)
+ value = fct->max;
+ fct->value = value;
+
+ return smu_set_fan(fct->fan_type, fct->reg, value);
+}
+
+static int smu_fan_get(struct wf_control *ct, s32 *value)
+{
+ struct smu_fan_control *fct = to_smu_fan(ct);
+ *value = fct->value; /* todo: read from SMU */
+ return 0;
+}
+
+static s32 smu_fan_min(struct wf_control *ct)
+{
+ struct smu_fan_control *fct = to_smu_fan(ct);
+ return fct->min;
+}
+
+static s32 smu_fan_max(struct wf_control *ct)
+{
+ struct smu_fan_control *fct = to_smu_fan(ct);
+ return fct->max;
+}
+
+static struct wf_control_ops smu_fan_ops = {
+ .set_value = smu_fan_set,
+ .get_value = smu_fan_get,
+ .get_min = smu_fan_min,
+ .get_max = smu_fan_max,
+ .release = smu_fan_release,
+ .owner = THIS_MODULE,
+};
+
+static struct smu_fan_control *smu_fan_create(struct device_node *node,
+ int pwm_fan)
+{
+ struct smu_fan_control *fct;
+ s32 *v; u32 *reg;
+ char *l;
+
+ fct = kmalloc(sizeof(struct smu_fan_control), GFP_KERNEL);
+ if (fct == NULL)
+ return NULL;
+ fct->ctrl.ops = &smu_fan_ops;
+ l = (char *)get_property(node, "location", NULL);
+ if (l == NULL)
+ goto fail;
+
+ fct->fan_type = pwm_fan;
+ fct->ctrl.type = pwm_fan ? WF_CONTROL_PWM_FAN : WF_CONTROL_RPM_FAN;
+
+ /* We use the name & location here the same way we do for SMU sensors,
+ * see the comment in windfarm_smu_sensors.c. The locations are a bit
+ * less consistent here between the iMac and the desktop models, but
+ * that is good enough for our needs for now at least.
+ *
+ * One problem though is that Apple seem to be inconsistent with case
+ * and the kernel doesn't have strcasecmp =P
+ */
+
+ fct->ctrl.name = NULL;
+
+ /* Names used on desktop models */
+ if (!strcmp(l, "Rear Fan 0") || !strcmp(l, "Rear Fan") ||
+ !strcmp(l, "Rear fan 0") || !strcmp(l, "Rear fan"))
+ fct->ctrl.name = "cpu-rear-fan-0";
+ else if (!strcmp(l, "Rear Fan 1") || !strcmp(l, "Rear fan 1"))
+ fct->ctrl.name = "cpu-rear-fan-1";
+ else if (!strcmp(l, "Front Fan 0") || !strcmp(l, "Front Fan") ||
+ !strcmp(l, "Front fan 0") || !strcmp(l, "Front fan"))
+ fct->ctrl.name = "cpu-front-fan-0";
+ else if (!strcmp(l, "Front Fan 1") || !strcmp(l, "Front fan 1"))
+ fct->ctrl.name = "cpu-front-fan-1";
+ else if (!strcmp(l, "Slots Fan") || !strcmp(l, "Slots fan"))
+ fct->ctrl.name = "slots-fan";
+ else if (!strcmp(l, "Drive Bay") || !strcmp(l, "Drive bay"))
+ fct->ctrl.name = "drive-bay-fan";
+
+ /* Names used on iMac models */
+ if (!strcmp(l, "System Fan") || !strcmp(l, "System fan"))
+ fct->ctrl.name = "system-fan";
+ else if (!strcmp(l, "CPU Fan") || !strcmp(l, "CPU fan"))
+ fct->ctrl.name = "cpu-fan";
+ else if (!strcmp(l, "Hard Drive") || !strcmp(l, "Hard drive"))
+ fct->ctrl.name = "drive-bay-fan";
+
+ /* Unrecognized fan, bail out */
+ if (fct->ctrl.name == NULL)
+ goto fail;
+
+ /* Get min & max values*/
+ v = (s32 *)get_property(node, "min-value", NULL);
+ if (v == NULL)
+ goto fail;
+ fct->min = *v;
+ v = (s32 *)get_property(node, "max-value", NULL);
+ if (v == NULL)
+ goto fail;
+ fct->max = *v;
+
+ /* Get "reg" value */
+ reg = (u32 *)get_property(node, "reg", NULL);
+ if (reg == NULL)
+ goto fail;
+ fct->reg = *reg;
+
+ if (wf_register_control(&fct->ctrl))
+ goto fail;
+
+ return fct;
+ fail:
+ kfree(fct);
+ return NULL;
+}
+
+
+static int __init smu_controls_init(void)
+{
+ struct device_node *smu, *fans, *fan;
+
+ if (!smu_present())
+ return -ENODEV;
+
+ smu = of_find_node_by_type(NULL, "smu");
+ if (smu == NULL)
+ return -ENODEV;
+
+ /* Look for RPM fans */
+ for (fans = NULL; (fans = of_get_next_child(smu, fans)) != NULL;)
+ if (!strcmp(fans->name, "rpm-fans"))
+ break;
+ for (fan = NULL;
+ fans && (fan = of_get_next_child(fans, fan)) != NULL;) {
+ struct smu_fan_control *fct;
+
+ fct = smu_fan_create(fan, 0);
+ if (fct == NULL) {
+ printk(KERN_WARNING "windfarm: Failed to create SMU "
+ "RPM fan %s\n", fan->name);
+ continue;
+ }
+ list_add(&fct->link, &smu_fans);
+ }
+ of_node_put(fans);
+
+
+ /* Look for PWM fans */
+ for (fans = NULL; (fans = of_get_next_child(smu, fans)) != NULL;)
+ if (!strcmp(fans->name, "pwm-fans"))
+ break;
+ for (fan = NULL;
+ fans && (fan = of_get_next_child(fans, fan)) != NULL;) {
+ struct smu_fan_control *fct;
+
+ fct = smu_fan_create(fan, 1);
+ if (fct == NULL) {
+ printk(KERN_WARNING "windfarm: Failed to create SMU "
+ "PWM fan %s\n", fan->name);
+ continue;
+ }
+ list_add(&fct->link, &smu_fans);
+ }
+ of_node_put(fans);
+ of_node_put(smu);
+
+ return 0;
+}
+
+static void __exit smu_controls_exit(void)
+{
+ struct smu_fan_control *fct;
+
+ while (!list_empty(&smu_fans)) {
+ fct = list_entry(smu_fans.next, struct smu_fan_control, link);
+ list_del(&fct->link);
+ wf_unregister_control(&fct->ctrl);
+ }
+}
+
+
+module_init(smu_controls_init);
+module_exit(smu_controls_exit);
+
+MODULE_AUTHOR("Benjamin Herrenschmidt <benh@kernel.crashing.org>");
+MODULE_DESCRIPTION("SMU control objects for PowerMacs thermal control");
+MODULE_LICENSE("GPL");
+
diff --git a/drivers/macintosh/windfarm_smu_sensors.c b/drivers/macintosh/windfarm_smu_sensors.c
new file mode 100644
index 000000000000..b558cc209d49
--- /dev/null
+++ b/drivers/macintosh/windfarm_smu_sensors.c
@@ -0,0 +1,479 @@
+/*
+ * Windfarm PowerMac thermal control. SMU based sensors
+ *
+ * (c) Copyright 2005 Benjamin Herrenschmidt, IBM Corp.
+ * <benh@kernel.crashing.org>
+ *
+ * Released under the term of the GNU GPL v2.
+ */
+
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/wait.h>
+#include <asm/prom.h>
+#include <asm/machdep.h>
+#include <asm/io.h>
+#include <asm/system.h>
+#include <asm/sections.h>
+#include <asm/smu.h>
+
+#include "windfarm.h"
+
+#define VERSION "0.2"
+
+#undef DEBUG
+
+#ifdef DEBUG
+#define DBG(args...) printk(args)
+#else
+#define DBG(args...) do { } while(0)
+#endif
+
+/*
+ * Various SMU "partitions" calibration objects for which we
+ * keep pointers here for use by bits & pieces of the driver
+ */
+static struct smu_sdbp_cpuvcp *cpuvcp;
+static int cpuvcp_version;
+static struct smu_sdbp_cpudiode *cpudiode;
+static struct smu_sdbp_slotspow *slotspow;
+static u8 *debugswitches;
+
+/*
+ * SMU basic sensors objects
+ */
+
+static LIST_HEAD(smu_ads);
+
+struct smu_ad_sensor {
+ struct list_head link;
+ u32 reg; /* index in SMU */
+ struct wf_sensor sens;
+};
+#define to_smu_ads(c) container_of(c, struct smu_ad_sensor, sens)
+
+static void smu_ads_release(struct wf_sensor *sr)
+{
+ struct smu_ad_sensor *ads = to_smu_ads(sr);
+
+ kfree(ads);
+}
+
+static int smu_read_adc(u8 id, s32 *value)
+{
+ struct smu_simple_cmd cmd;
+ DECLARE_COMPLETION(comp);
+ int rc;
+
+ rc = smu_queue_simple(&cmd, SMU_CMD_READ_ADC, 1,
+ smu_done_complete, &comp, id);
+ if (rc)
+ return rc;
+ wait_for_completion(&comp);
+ if (cmd.cmd.status != 0)
+ return cmd.cmd.status;
+ if (cmd.cmd.reply_len != 2) {
+ printk(KERN_ERR "winfarm: read ADC 0x%x returned %d bytes !\n",
+ id, cmd.cmd.reply_len);
+ return -EIO;
+ }
+ *value = *((u16 *)cmd.buffer);
+ return 0;
+}
+
+static int smu_cputemp_get(struct wf_sensor *sr, s32 *value)
+{
+ struct smu_ad_sensor *ads = to_smu_ads(sr);
+ int rc;
+ s32 val;
+ s64 scaled;
+
+ rc = smu_read_adc(ads->reg, &val);
+ if (rc) {
+ printk(KERN_ERR "windfarm: read CPU temp failed, err %d\n",
+ rc);
+ return rc;
+ }
+
+ /* Ok, we have to scale & adjust, taking units into account */
+ scaled = (s64)(((u64)val) * (u64)cpudiode->m_value);
+ scaled >>= 3;
+ scaled += ((s64)cpudiode->b_value) << 9;
+ *value = (s32)(scaled << 1);
+
+ return 0;
+}
+
+static int smu_cpuamp_get(struct wf_sensor *sr, s32 *value)
+{
+ struct smu_ad_sensor *ads = to_smu_ads(sr);
+ s32 val, scaled;
+ int rc;
+
+ rc = smu_read_adc(ads->reg, &val);
+ if (rc) {
+ printk(KERN_ERR "windfarm: read CPU current failed, err %d\n",
+ rc);
+ return rc;
+ }
+
+ /* Ok, we have to scale & adjust, taking units into account */
+ scaled = (s32)(val * (u32)cpuvcp->curr_scale);
+ scaled += (s32)cpuvcp->curr_offset;
+ *value = scaled << 4;
+
+ return 0;
+}
+
+static int smu_cpuvolt_get(struct wf_sensor *sr, s32 *value)
+{
+ struct smu_ad_sensor *ads = to_smu_ads(sr);
+ s32 val, scaled;
+ int rc;
+
+ rc = smu_read_adc(ads->reg, &val);
+ if (rc) {
+ printk(KERN_ERR "windfarm: read CPU voltage failed, err %d\n",
+ rc);
+ return rc;
+ }
+
+ /* Ok, we have to scale & adjust, taking units into account */
+ scaled = (s32)(val * (u32)cpuvcp->volt_scale);
+ scaled += (s32)cpuvcp->volt_offset;
+ *value = scaled << 4;
+
+ return 0;
+}
+
+static int smu_slotspow_get(struct wf_sensor *sr, s32 *value)
+{
+ struct smu_ad_sensor *ads = to_smu_ads(sr);
+ s32 val, scaled;
+ int rc;
+
+ rc = smu_read_adc(ads->reg, &val);
+ if (rc) {
+ printk(KERN_ERR "windfarm: read slots power failed, err %d\n",
+ rc);
+ return rc;
+ }
+
+ /* Ok, we have to scale & adjust, taking units into account */
+ scaled = (s32)(val * (u32)slotspow->pow_scale);
+ scaled += (s32)slotspow->pow_offset;
+ *value = scaled << 4;
+
+ return 0;
+}
+
+
+static struct wf_sensor_ops smu_cputemp_ops = {
+ .get_value = smu_cputemp_get,
+ .release = smu_ads_release,
+ .owner = THIS_MODULE,
+};
+static struct wf_sensor_ops smu_cpuamp_ops = {
+ .get_value = smu_cpuamp_get,
+ .release = smu_ads_release,
+ .owner = THIS_MODULE,
+};
+static struct wf_sensor_ops smu_cpuvolt_ops = {
+ .get_value = smu_cpuvolt_get,
+ .release = smu_ads_release,
+ .owner = THIS_MODULE,
+};
+static struct wf_sensor_ops smu_slotspow_ops = {
+ .get_value = smu_slotspow_get,
+ .release = smu_ads_release,
+ .owner = THIS_MODULE,
+};
+
+
+static struct smu_ad_sensor *smu_ads_create(struct device_node *node)
+{
+ struct smu_ad_sensor *ads;
+ char *c, *l;
+ u32 *v;
+
+ ads = kmalloc(sizeof(struct smu_ad_sensor), GFP_KERNEL);
+ if (ads == NULL)
+ return NULL;
+ c = (char *)get_property(node, "device_type", NULL);
+ l = (char *)get_property(node, "location", NULL);
+ if (c == NULL || l == NULL)
+ goto fail;
+
+ /* We currently pick the sensors based on the OF name and location
+ * properties, while Darwin uses the sensor-id's.
+ * The problem with the IDs is that they are model specific while it
+ * looks like apple has been doing a reasonably good job at keeping
+ * the names and locations consistents so I'll stick with the names
+ * and locations for now.
+ */
+ if (!strcmp(c, "temp-sensor") &&
+ !strcmp(l, "CPU T-Diode")) {
+ ads->sens.ops = &smu_cputemp_ops;
+ ads->sens.name = "cpu-temp";
+ } else if (!strcmp(c, "current-sensor") &&
+ !strcmp(l, "CPU Current")) {
+ ads->sens.ops = &smu_cpuamp_ops;
+ ads->sens.name = "cpu-current";
+ } else if (!strcmp(c, "voltage-sensor") &&
+ !strcmp(l, "CPU Voltage")) {
+ ads->sens.ops = &smu_cpuvolt_ops;
+ ads->sens.name = "cpu-voltage";
+ } else if (!strcmp(c, "power-sensor") &&
+ !strcmp(l, "Slots Power")) {
+ ads->sens.ops = &smu_slotspow_ops;
+ ads->sens.name = "slots-power";
+ if (slotspow == NULL) {
+ DBG("wf: slotspow partition (%02x) not found\n",
+ SMU_SDB_SLOTSPOW_ID);
+ goto fail;
+ }
+ } else
+ goto fail;
+
+ v = (u32 *)get_property(node, "reg", NULL);
+ if (v == NULL)
+ goto fail;
+ ads->reg = *v;
+
+ if (wf_register_sensor(&ads->sens))
+ goto fail;
+ return ads;
+ fail:
+ kfree(ads);
+ return NULL;
+}
+
+/*
+ * SMU Power combo sensor object
+ */
+
+struct smu_cpu_power_sensor {
+ struct list_head link;
+ struct wf_sensor *volts;
+ struct wf_sensor *amps;
+ int fake_volts : 1;
+ int quadratic : 1;
+ struct wf_sensor sens;
+};
+#define to_smu_cpu_power(c) container_of(c, struct smu_cpu_power_sensor, sens)
+
+static struct smu_cpu_power_sensor *smu_cpu_power;
+
+static void smu_cpu_power_release(struct wf_sensor *sr)
+{
+ struct smu_cpu_power_sensor *pow = to_smu_cpu_power(sr);
+
+ if (pow->volts)
+ wf_put_sensor(pow->volts);
+ if (pow->amps)
+ wf_put_sensor(pow->amps);
+ kfree(pow);
+}
+
+static int smu_cpu_power_get(struct wf_sensor *sr, s32 *value)
+{
+ struct smu_cpu_power_sensor *pow = to_smu_cpu_power(sr);
+ s32 volts, amps, power;
+ u64 tmps, tmpa, tmpb;
+ int rc;
+
+ rc = pow->amps->ops->get_value(pow->amps, &amps);
+ if (rc)
+ return rc;
+
+ if (pow->fake_volts) {
+ *value = amps * 12 - 0x30000;
+ return 0;
+ }
+
+ rc = pow->volts->ops->get_value(pow->volts, &volts);
+ if (rc)
+ return rc;
+
+ power = (s32)((((u64)volts) * ((u64)amps)) >> 16);
+ if (!pow->quadratic) {
+ *value = power;
+ return 0;
+ }
+ tmps = (((u64)power) * ((u64)power)) >> 16;
+ tmpa = ((u64)cpuvcp->power_quads[0]) * tmps;
+ tmpb = ((u64)cpuvcp->power_quads[1]) * ((u64)power);
+ *value = (tmpa >> 28) + (tmpb >> 28) + (cpuvcp->power_quads[2] >> 12);
+
+ return 0;
+}
+
+static struct wf_sensor_ops smu_cpu_power_ops = {
+ .get_value = smu_cpu_power_get,
+ .release = smu_cpu_power_release,
+ .owner = THIS_MODULE,
+};
+
+
+static struct smu_cpu_power_sensor *
+smu_cpu_power_create(struct wf_sensor *volts, struct wf_sensor *amps)
+{
+ struct smu_cpu_power_sensor *pow;
+
+ pow = kmalloc(sizeof(struct smu_cpu_power_sensor), GFP_KERNEL);
+ if (pow == NULL)
+ return NULL;
+ pow->sens.ops = &smu_cpu_power_ops;
+ pow->sens.name = "cpu-power";
+
+ wf_get_sensor(volts);
+ pow->volts = volts;
+ wf_get_sensor(amps);
+ pow->amps = amps;
+
+ /* Some early machines need a faked voltage */
+ if (debugswitches && ((*debugswitches) & 0x80)) {
+ printk(KERN_INFO "windfarm: CPU Power sensor using faked"
+ " voltage !\n");
+ pow->fake_volts = 1;
+ } else
+ pow->fake_volts = 0;
+
+ /* Try to use quadratic transforms on PowerMac8,1 and 9,1 for now,
+ * I yet have to figure out what's up with 8,2 and will have to
+ * adjust for later, unless we can 100% trust the SDB partition...
+ */
+ if ((machine_is_compatible("PowerMac8,1") ||
+ machine_is_compatible("PowerMac8,2") ||
+ machine_is_compatible("PowerMac9,1")) &&
+ cpuvcp_version >= 2) {
+ pow->quadratic = 1;
+ DBG("windfarm: CPU Power using quadratic transform\n");
+ } else
+ pow->quadratic = 0;
+
+ if (wf_register_sensor(&pow->sens))
+ goto fail;
+ return pow;
+ fail:
+ kfree(pow);
+ return NULL;
+}
+
+static int smu_fetch_param_partitions(void)
+{
+ struct smu_sdbp_header *hdr;
+
+ /* Get CPU voltage/current/power calibration data */
+ hdr = smu_get_sdb_partition(SMU_SDB_CPUVCP_ID, NULL);
+ if (hdr == NULL) {
+ DBG("wf: cpuvcp partition (%02x) not found\n",
+ SMU_SDB_CPUVCP_ID);
+ return -ENODEV;
+ }
+ cpuvcp = (struct smu_sdbp_cpuvcp *)&hdr[1];
+ /* Keep version around */
+ cpuvcp_version = hdr->version;
+
+ /* Get CPU diode calibration data */
+ hdr = smu_get_sdb_partition(SMU_SDB_CPUDIODE_ID, NULL);
+ if (hdr == NULL) {
+ DBG("wf: cpudiode partition (%02x) not found\n",
+ SMU_SDB_CPUDIODE_ID);
+ return -ENODEV;
+ }
+ cpudiode = (struct smu_sdbp_cpudiode *)&hdr[1];
+
+ /* Get slots power calibration data if any */
+ hdr = smu_get_sdb_partition(SMU_SDB_SLOTSPOW_ID, NULL);
+ if (hdr != NULL)
+ slotspow = (struct smu_sdbp_slotspow *)&hdr[1];
+
+ /* Get debug switches if any */
+ hdr = smu_get_sdb_partition(SMU_SDB_DEBUG_SWITCHES_ID, NULL);
+ if (hdr != NULL)
+ debugswitches = (u8 *)&hdr[1];
+
+ return 0;
+}
+
+static int __init smu_sensors_init(void)
+{
+ struct device_node *smu, *sensors, *s;
+ struct smu_ad_sensor *volt_sensor = NULL, *curr_sensor = NULL;
+ int rc;
+
+ if (!smu_present())
+ return -ENODEV;
+
+ /* Get parameters partitions */
+ rc = smu_fetch_param_partitions();
+ if (rc)
+ return rc;
+
+ smu = of_find_node_by_type(NULL, "smu");
+ if (smu == NULL)
+ return -ENODEV;
+
+ /* Look for sensors subdir */
+ for (sensors = NULL;
+ (sensors = of_get_next_child(smu, sensors)) != NULL;)
+ if (!strcmp(sensors->name, "sensors"))
+ break;
+
+ of_node_put(smu);
+
+ /* Create basic sensors */
+ for (s = NULL;
+ sensors && (s = of_get_next_child(sensors, s)) != NULL;) {
+ struct smu_ad_sensor *ads;
+
+ ads = smu_ads_create(s);
+ if (ads == NULL)
+ continue;
+ list_add(&ads->link, &smu_ads);
+ /* keep track of cpu voltage & current */
+ if (!strcmp(ads->sens.name, "cpu-voltage"))
+ volt_sensor = ads;
+ else if (!strcmp(ads->sens.name, "cpu-current"))
+ curr_sensor = ads;
+ }
+
+ of_node_put(sensors);
+
+ /* Create CPU power sensor if possible */
+ if (volt_sensor && curr_sensor)
+ smu_cpu_power = smu_cpu_power_create(&volt_sensor->sens,
+ &curr_sensor->sens);
+
+ return 0;
+}
+
+static void __exit smu_sensors_exit(void)
+{
+ struct smu_ad_sensor *ads;
+
+ /* dispose of power sensor */
+ if (smu_cpu_power)
+ wf_unregister_sensor(&smu_cpu_power->sens);
+
+ /* dispose of basic sensors */
+ while (!list_empty(&smu_ads)) {
+ ads = list_entry(smu_ads.next, struct smu_ad_sensor, link);
+ list_del(&ads->link);
+ wf_unregister_sensor(&ads->sens);
+ }
+}
+
+
+module_init(smu_sensors_init);
+module_exit(smu_sensors_exit);
+
+MODULE_AUTHOR("Benjamin Herrenschmidt <benh@kernel.crashing.org>");
+MODULE_DESCRIPTION("SMU sensor objects for PowerMacs thermal control");
+MODULE_LICENSE("GPL");
+
diff --git a/drivers/mca/mca-device.c b/drivers/mca/mca-device.c
index 76d430aa243f..e7adf89fae41 100644
--- a/drivers/mca/mca-device.c
+++ b/drivers/mca/mca-device.c
@@ -29,6 +29,7 @@
#include <linux/module.h>
#include <linux/device.h>
#include <linux/mca.h>
+#include <linux/string.h>
/**
* mca_device_read_stored_pos - read POS register from stored data
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c
index 2fba2bbe72d8..51315302a85e 100644
--- a/drivers/md/bitmap.c
+++ b/drivers/md/bitmap.c
@@ -21,7 +21,6 @@
*/
#include <linux/module.h>
-#include <linux/version.h>
#include <linux/errno.h>
#include <linux/slab.h>
#include <linux/init.h>
@@ -91,7 +90,7 @@ int bitmap_active(struct bitmap *bitmap)
#define WRITE_POOL_SIZE 256
/* mempool for queueing pending writes on the bitmap file */
-static void *write_pool_alloc(unsigned int gfp_flags, void *data)
+static void *write_pool_alloc(gfp_t gfp_flags, void *data)
{
return kmalloc(sizeof(struct page_list), gfp_flags);
}
@@ -272,7 +271,8 @@ static struct page *read_sb_page(mddev_t *mddev, long offset, unsigned long inde
return ERR_PTR(-ENOMEM);
ITERATE_RDEV(mddev, rdev, tmp) {
- if (! rdev->in_sync || rdev->faulty)
+ if (! test_bit(In_sync, &rdev->flags)
+ || test_bit(Faulty, &rdev->flags))
continue;
target = (rdev->sb_offset << 1) + offset + index * (PAGE_SIZE/512);
@@ -292,7 +292,8 @@ static int write_sb_page(mddev_t *mddev, long offset, struct page *page, int wai
struct list_head *tmp;
ITERATE_RDEV(mddev, rdev, tmp)
- if (rdev->in_sync && !rdev->faulty)
+ if (test_bit(In_sync, &rdev->flags)
+ && !test_bit(Faulty, &rdev->flags))
md_super_write(mddev, rdev,
(rdev->sb_offset<<1) + offset
+ page->index * (PAGE_SIZE/512),
@@ -300,7 +301,7 @@ static int write_sb_page(mddev_t *mddev, long offset, struct page *page, int wai
page);
if (wait)
- wait_event(mddev->sb_wait, atomic_read(&mddev->pending_writes)==0);
+ md_super_wait(mddev);
return 0;
}
@@ -481,7 +482,8 @@ static int bitmap_read_sb(struct bitmap *bitmap)
/* verify that the bitmap-specific fields are valid */
if (sb->magic != cpu_to_le32(BITMAP_MAGIC))
reason = "bad magic";
- else if (sb->version != cpu_to_le32(BITMAP_MAJOR))
+ else if (le32_to_cpu(sb->version) < BITMAP_MAJOR_LO ||
+ le32_to_cpu(sb->version) > BITMAP_MAJOR_HI)
reason = "unrecognized superblock version";
else if (chunksize < 512 || chunksize > (1024 * 1024 * 4))
reason = "bitmap chunksize out of range (512B - 4MB)";
@@ -526,6 +528,8 @@ success:
bitmap->daemon_lastrun = jiffies;
bitmap->max_write_behind = write_behind;
bitmap->flags |= sb->state;
+ if (le32_to_cpu(sb->version) == BITMAP_MAJOR_HOSTENDIAN)
+ bitmap->flags |= BITMAP_HOSTENDIAN;
bitmap->events_cleared = le64_to_cpu(sb->events_cleared);
if (sb->state & BITMAP_STALE)
bitmap->events_cleared = bitmap->mddev->events;
@@ -763,7 +767,10 @@ static void bitmap_file_set_bit(struct bitmap *bitmap, sector_t block)
/* set the bit */
kaddr = kmap_atomic(page, KM_USER0);
- set_bit(bit, kaddr);
+ if (bitmap->flags & BITMAP_HOSTENDIAN)
+ set_bit(bit, kaddr);
+ else
+ ext2_set_bit(bit, kaddr);
kunmap_atomic(kaddr, KM_USER0);
PRINTK("set file bit %lu page %lu\n", bit, page->index);
@@ -821,8 +828,7 @@ int bitmap_unplug(struct bitmap *bitmap)
wake_up_process(bitmap->writeback_daemon->tsk));
spin_unlock_irq(&bitmap->write_lock);
} else
- wait_event(bitmap->mddev->sb_wait,
- atomic_read(&bitmap->mddev->pending_writes)==0);
+ md_super_wait(bitmap->mddev);
}
return 0;
}
@@ -890,6 +896,7 @@ static int bitmap_init_from_disk(struct bitmap *bitmap, sector_t start)
oldindex = ~0L;
for (i = 0; i < chunks; i++) {
+ int b;
index = file_page_index(i);
bit = file_page_offset(i);
if (index != oldindex) { /* this is a new page, read it in */
@@ -938,7 +945,11 @@ static int bitmap_init_from_disk(struct bitmap *bitmap, sector_t start)
bitmap->filemap[bitmap->file_pages++] = page;
}
- if (test_bit(bit, page_address(page))) {
+ if (bitmap->flags & BITMAP_HOSTENDIAN)
+ b = test_bit(bit, page_address(page));
+ else
+ b = ext2_test_bit(bit, page_address(page));
+ 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)
@@ -1096,7 +1107,10 @@ int bitmap_daemon_work(struct bitmap *bitmap)
-1);
/* clear the bit */
- clear_bit(file_page_offset(j), page_address(page));
+ if (bitmap->flags & BITMAP_HOSTENDIAN)
+ clear_bit(file_page_offset(j), page_address(page));
+ else
+ ext2_clear_bit(file_page_offset(j), page_address(page));
}
}
spin_unlock_irqrestore(&bitmap->lock, flags);
diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c
index b6148f6f7836..cf6631056683 100644
--- a/drivers/md/dm-crypt.c
+++ b/drivers/md/dm-crypt.c
@@ -15,7 +15,7 @@
#include <linux/crypto.h>
#include <linux/workqueue.h>
#include <asm/atomic.h>
-#include <asm/scatterlist.h>
+#include <linux/scatterlist.h>
#include <asm/page.h>
#include "dm.h"
@@ -164,9 +164,7 @@ static int crypt_iv_essiv_ctr(struct crypt_config *cc, struct dm_target *ti,
return -ENOMEM;
}
- sg.page = virt_to_page(cc->key);
- sg.offset = offset_in_page(cc->key);
- sg.length = cc->key_size;
+ sg_set_buf(&sg, cc->key, cc->key_size);
crypto_digest_digest(hash_tfm, &sg, 1, salt);
crypto_free_tfm(hash_tfm);
@@ -207,14 +205,12 @@ static void crypt_iv_essiv_dtr(struct crypt_config *cc)
static int crypt_iv_essiv_gen(struct crypt_config *cc, u8 *iv, sector_t sector)
{
- struct scatterlist sg = { NULL, };
+ struct scatterlist sg;
memset(iv, 0, cc->iv_size);
*(u64 *)iv = cpu_to_le64(sector);
- sg.page = virt_to_page(iv);
- sg.offset = offset_in_page(iv);
- sg.length = cc->iv_size;
+ sg_set_buf(&sg, iv, cc->iv_size);
crypto_cipher_encrypt((struct crypto_tfm *)cc->iv_gen_private,
&sg, &sg, cc->iv_size);
@@ -331,7 +327,7 @@ crypt_alloc_buffer(struct crypt_config *cc, unsigned int size,
{
struct bio *bio;
unsigned int nr_iovecs = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
- int gfp_mask = GFP_NOIO | __GFP_HIGHMEM;
+ gfp_t gfp_mask = GFP_NOIO | __GFP_HIGHMEM;
unsigned int i;
/*
diff --git a/drivers/md/linear.c b/drivers/md/linear.c
index bb279fad2fd2..946efef3a8f5 100644
--- a/drivers/md/linear.c
+++ b/drivers/md/linear.c
@@ -271,6 +271,7 @@ static int linear_stop (mddev_t *mddev)
static int linear_make_request (request_queue_t *q, struct bio *bio)
{
+ const int rw = bio_data_dir(bio);
mddev_t *mddev = q->queuedata;
dev_info_t *tmp_dev;
sector_t block;
@@ -280,13 +281,8 @@ static int linear_make_request (request_queue_t *q, struct bio *bio)
return 0;
}
- if (bio_data_dir(bio)==WRITE) {
- disk_stat_inc(mddev->gendisk, writes);
- disk_stat_add(mddev->gendisk, write_sectors, bio_sectors(bio));
- } else {
- disk_stat_inc(mddev->gendisk, reads);
- disk_stat_add(mddev->gendisk, read_sectors, bio_sectors(bio));
- }
+ disk_stat_inc(mddev->gendisk, ios[rw]);
+ disk_stat_add(mddev->gendisk, sectors[rw], bio_sectors(bio));
tmp_dev = which_dev(mddev, bio->bi_sector);
block = bio->bi_sector >> 1;
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 2a8a5696bf8a..adf960d8a7c9 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -131,6 +131,8 @@ static ctl_table raid_root_table[] = {
static struct block_device_operations md_fops;
+static int start_readonly;
+
/*
* Enables to iterate over all existing md arrays
* all_mddevs_lock protects this list.
@@ -181,7 +183,7 @@ static void mddev_put(mddev_t *mddev)
if (!mddev->raid_disks && list_empty(&mddev->disks)) {
list_del(&mddev->all_mddevs);
blk_put_queue(mddev->queue);
- kfree(mddev);
+ kobject_unregister(&mddev->kobj);
}
spin_unlock(&all_mddevs_lock);
}
@@ -330,18 +332,46 @@ static void free_disk_sb(mdk_rdev_t * rdev)
static int super_written(struct bio *bio, unsigned int bytes_done, int error)
{
mdk_rdev_t *rdev = bio->bi_private;
+ mddev_t *mddev = rdev->mddev;
if (bio->bi_size)
return 1;
if (error || !test_bit(BIO_UPTODATE, &bio->bi_flags))
- md_error(rdev->mddev, rdev);
+ md_error(mddev, rdev);
- if (atomic_dec_and_test(&rdev->mddev->pending_writes))
- wake_up(&rdev->mddev->sb_wait);
+ if (atomic_dec_and_test(&mddev->pending_writes))
+ wake_up(&mddev->sb_wait);
bio_put(bio);
return 0;
}
+static int super_written_barrier(struct bio *bio, unsigned int bytes_done, int error)
+{
+ struct bio *bio2 = bio->bi_private;
+ mdk_rdev_t *rdev = bio2->bi_private;
+ mddev_t *mddev = rdev->mddev;
+ if (bio->bi_size)
+ return 1;
+
+ if (!test_bit(BIO_UPTODATE, &bio->bi_flags) &&
+ error == -EOPNOTSUPP) {
+ unsigned long flags;
+ /* barriers don't appear to be supported :-( */
+ set_bit(BarriersNotsupp, &rdev->flags);
+ mddev->barriers_work = 0;
+ spin_lock_irqsave(&mddev->write_lock, flags);
+ bio2->bi_next = mddev->biolist;
+ mddev->biolist = bio2;
+ spin_unlock_irqrestore(&mddev->write_lock, flags);
+ wake_up(&mddev->sb_wait);
+ bio_put(bio);
+ return 0;
+ }
+ bio_put(bio2);
+ bio->bi_private = rdev;
+ return super_written(bio, bytes_done, error);
+}
+
void md_super_write(mddev_t *mddev, mdk_rdev_t *rdev,
sector_t sector, int size, struct page *page)
{
@@ -350,16 +380,54 @@ void md_super_write(mddev_t *mddev, mdk_rdev_t *rdev,
* and decrement it on completion, waking up sb_wait
* if zero is reached.
* If an error occurred, call md_error
+ *
+ * As we might need to resubmit the request if BIO_RW_BARRIER
+ * causes ENOTSUPP, we allocate a spare bio...
*/
struct bio *bio = bio_alloc(GFP_NOIO, 1);
+ int rw = (1<<BIO_RW) | (1<<BIO_RW_SYNC);
bio->bi_bdev = rdev->bdev;
bio->bi_sector = sector;
bio_add_page(bio, page, size, 0);
bio->bi_private = rdev;
bio->bi_end_io = super_written;
+ bio->bi_rw = rw;
+
atomic_inc(&mddev->pending_writes);
- submit_bio((1<<BIO_RW)|(1<<BIO_RW_SYNC), bio);
+ if (!test_bit(BarriersNotsupp, &rdev->flags)) {
+ struct bio *rbio;
+ rw |= (1<<BIO_RW_BARRIER);
+ rbio = bio_clone(bio, GFP_NOIO);
+ rbio->bi_private = bio;
+ rbio->bi_end_io = super_written_barrier;
+ submit_bio(rw, rbio);
+ } else
+ submit_bio(rw, bio);
+}
+
+void md_super_wait(mddev_t *mddev)
+{
+ /* wait for all superblock writes that were scheduled to complete.
+ * if any had to be retried (due to BARRIER problems), retry them
+ */
+ DEFINE_WAIT(wq);
+ for(;;) {
+ prepare_to_wait(&mddev->sb_wait, &wq, TASK_UNINTERRUPTIBLE);
+ if (atomic_read(&mddev->pending_writes)==0)
+ break;
+ while (mddev->biolist) {
+ struct bio *bio;
+ spin_lock_irq(&mddev->write_lock);
+ bio = mddev->biolist;
+ mddev->biolist = bio->bi_next ;
+ bio->bi_next = NULL;
+ spin_unlock_irq(&mddev->write_lock);
+ submit_bio(bio->bi_rw, bio);
+ }
+ schedule();
+ }
+ finish_wait(&mddev->sb_wait, &wq);
}
static int bi_complete(struct bio *bio, unsigned int bytes_done, int error)
@@ -610,7 +678,7 @@ static int super_90_validate(mddev_t *mddev, mdk_rdev_t *rdev)
mdp_super_t *sb = (mdp_super_t *)page_address(rdev->sb_page);
rdev->raid_disk = -1;
- rdev->in_sync = 0;
+ rdev->flags = 0;
if (mddev->raid_disks == 0) {
mddev->major_version = 0;
mddev->minor_version = sb->minor_version;
@@ -671,21 +739,19 @@ static int super_90_validate(mddev_t *mddev, mdk_rdev_t *rdev)
return 0;
if (mddev->level != LEVEL_MULTIPATH) {
- rdev->faulty = 0;
- rdev->flags = 0;
desc = sb->disks + rdev->desc_nr;
if (desc->state & (1<<MD_DISK_FAULTY))
- rdev->faulty = 1;
+ set_bit(Faulty, &rdev->flags);
else if (desc->state & (1<<MD_DISK_SYNC) &&
desc->raid_disk < mddev->raid_disks) {
- rdev->in_sync = 1;
+ set_bit(In_sync, &rdev->flags);
rdev->raid_disk = desc->raid_disk;
}
if (desc->state & (1<<MD_DISK_WRITEMOSTLY))
set_bit(WriteMostly, &rdev->flags);
} else /* MULTIPATH are always insync */
- rdev->in_sync = 1;
+ set_bit(In_sync, &rdev->flags);
return 0;
}
@@ -699,6 +765,7 @@ static void super_90_sync(mddev_t *mddev, mdk_rdev_t *rdev)
mdk_rdev_t *rdev2;
int next_spare = mddev->raid_disks;
+
/* make rdev->sb match mddev data..
*
* 1/ zero out disks
@@ -758,23 +825,27 @@ static void super_90_sync(mddev_t *mddev, mdk_rdev_t *rdev)
sb->disks[0].state = (1<<MD_DISK_REMOVED);
ITERATE_RDEV(mddev,rdev2,tmp) {
mdp_disk_t *d;
- if (rdev2->raid_disk >= 0 && rdev2->in_sync && !rdev2->faulty)
- rdev2->desc_nr = rdev2->raid_disk;
+ int desc_nr;
+ if (rdev2->raid_disk >= 0 && test_bit(In_sync, &rdev2->flags)
+ && !test_bit(Faulty, &rdev2->flags))
+ desc_nr = rdev2->raid_disk;
else
- rdev2->desc_nr = next_spare++;
+ desc_nr = next_spare++;
+ rdev2->desc_nr = desc_nr;
d = &sb->disks[rdev2->desc_nr];
nr_disks++;
d->number = rdev2->desc_nr;
d->major = MAJOR(rdev2->bdev->bd_dev);
d->minor = MINOR(rdev2->bdev->bd_dev);
- if (rdev2->raid_disk >= 0 && rdev->in_sync && !rdev2->faulty)
+ if (rdev2->raid_disk >= 0 && test_bit(In_sync, &rdev2->flags)
+ && !test_bit(Faulty, &rdev2->flags))
d->raid_disk = rdev2->raid_disk;
else
d->raid_disk = rdev2->desc_nr; /* compatibility */
- if (rdev2->faulty) {
+ if (test_bit(Faulty, &rdev2->flags)) {
d->state = (1<<MD_DISK_FAULTY);
failed++;
- } else if (rdev2->in_sync) {
+ } else if (test_bit(In_sync, &rdev2->flags)) {
d->state = (1<<MD_DISK_ACTIVE);
d->state |= (1<<MD_DISK_SYNC);
active++;
@@ -787,7 +858,6 @@ static void super_90_sync(mddev_t *mddev, mdk_rdev_t *rdev)
if (test_bit(WriteMostly, &rdev2->flags))
d->state |= (1<<MD_DISK_WRITEMOSTLY);
}
-
/* now set the "removed" and "faulty" bits on any missing devices */
for (i=0 ; i < mddev->raid_disks ; i++) {
mdp_disk_t *d = &sb->disks[i];
@@ -944,7 +1014,7 @@ static int super_1_validate(mddev_t *mddev, mdk_rdev_t *rdev)
struct mdp_superblock_1 *sb = (struct mdp_superblock_1*)page_address(rdev->sb_page);
rdev->raid_disk = -1;
- rdev->in_sync = 0;
+ rdev->flags = 0;
if (mddev->raid_disks == 0) {
mddev->major_version = 1;
mddev->patch_version = 0;
@@ -996,22 +1066,19 @@ static int super_1_validate(mddev_t *mddev, mdk_rdev_t *rdev)
role = le16_to_cpu(sb->dev_roles[rdev->desc_nr]);
switch(role) {
case 0xffff: /* spare */
- rdev->faulty = 0;
break;
case 0xfffe: /* faulty */
- rdev->faulty = 1;
+ set_bit(Faulty, &rdev->flags);
break;
default:
- rdev->in_sync = 1;
- rdev->faulty = 0;
+ set_bit(In_sync, &rdev->flags);
rdev->raid_disk = role;
break;
}
- rdev->flags = 0;
if (sb->devflags & WriteMostly1)
set_bit(WriteMostly, &rdev->flags);
} else /* MULTIPATH are always insync */
- rdev->in_sync = 1;
+ set_bit(In_sync, &rdev->flags);
return 0;
}
@@ -1055,9 +1122,9 @@ static void super_1_sync(mddev_t *mddev, mdk_rdev_t *rdev)
ITERATE_RDEV(mddev,rdev2,tmp) {
i = rdev2->desc_nr;
- if (rdev2->faulty)
+ if (test_bit(Faulty, &rdev2->flags))
sb->dev_roles[i] = cpu_to_le16(0xfffe);
- else if (rdev2->in_sync)
+ else if (test_bit(In_sync, &rdev2->flags))
sb->dev_roles[i] = cpu_to_le16(rdev2->raid_disk);
else
sb->dev_roles[i] = cpu_to_le16(0xffff);
@@ -1115,6 +1182,7 @@ static int bind_rdev_to_array(mdk_rdev_t * rdev, mddev_t * mddev)
{
mdk_rdev_t *same_pdev;
char b[BDEVNAME_SIZE], b2[BDEVNAME_SIZE];
+ struct kobject *ko;
if (rdev->mddev) {
MD_BUG();
@@ -1143,10 +1211,22 @@ static int bind_rdev_to_array(mdk_rdev_t * rdev, mddev_t * mddev)
if (find_rdev_nr(mddev, rdev->desc_nr))
return -EBUSY;
}
+ bdevname(rdev->bdev,b);
+ if (kobject_set_name(&rdev->kobj, "dev-%s", b) < 0)
+ return -ENOMEM;
list_add(&rdev->same_set, &mddev->disks);
rdev->mddev = mddev;
- printk(KERN_INFO "md: bind<%s>\n", bdevname(rdev->bdev,b));
+ printk(KERN_INFO "md: bind<%s>\n", b);
+
+ rdev->kobj.parent = &mddev->kobj;
+ kobject_add(&rdev->kobj);
+
+ if (rdev->bdev->bd_part)
+ ko = &rdev->bdev->bd_part->kobj;
+ else
+ ko = &rdev->bdev->bd_disk->kobj;
+ sysfs_create_link(&rdev->kobj, ko, "block");
return 0;
}
@@ -1160,6 +1240,8 @@ static void unbind_rdev_from_array(mdk_rdev_t * rdev)
list_del_init(&rdev->same_set);
printk(KERN_INFO "md: unbind<%s>\n", bdevname(rdev->bdev,b));
rdev->mddev = NULL;
+ sysfs_remove_link(&rdev->kobj, "block");
+ kobject_del(&rdev->kobj);
}
/*
@@ -1215,7 +1297,7 @@ static void export_rdev(mdk_rdev_t * rdev)
md_autodetect_dev(rdev->bdev->bd_dev);
#endif
unlock_rdev(rdev);
- kfree(rdev);
+ kobject_put(&rdev->kobj);
}
static void kick_rdev_from_array(mdk_rdev_t * rdev)
@@ -1287,7 +1369,8 @@ static void print_rdev(mdk_rdev_t *rdev)
char b[BDEVNAME_SIZE];
printk(KERN_INFO "md: rdev %s, SZ:%08llu F:%d S:%d DN:%u\n",
bdevname(rdev->bdev,b), (unsigned long long)rdev->size,
- rdev->faulty, rdev->in_sync, rdev->desc_nr);
+ test_bit(Faulty, &rdev->flags), test_bit(In_sync, &rdev->flags),
+ rdev->desc_nr);
if (rdev->sb_loaded) {
printk(KERN_INFO "md: rdev superblock:\n");
print_sb((mdp_super_t*)page_address(rdev->sb_page));
@@ -1344,7 +1427,7 @@ static void md_update_sb(mddev_t * mddev)
int sync_req;
repeat:
- spin_lock(&mddev->write_lock);
+ spin_lock_irq(&mddev->write_lock);
sync_req = mddev->in_sync;
mddev->utime = get_seconds();
mddev->events ++;
@@ -1367,11 +1450,11 @@ repeat:
*/
if (!mddev->persistent) {
mddev->sb_dirty = 0;
- spin_unlock(&mddev->write_lock);
+ spin_unlock_irq(&mddev->write_lock);
wake_up(&mddev->sb_wait);
return;
}
- spin_unlock(&mddev->write_lock);
+ spin_unlock_irq(&mddev->write_lock);
dprintk(KERN_INFO
"md: updating %s RAID superblock on device (in sync %d)\n",
@@ -1381,11 +1464,11 @@ repeat:
ITERATE_RDEV(mddev,rdev,tmp) {
char b[BDEVNAME_SIZE];
dprintk(KERN_INFO "md: ");
- if (rdev->faulty)
+ if (test_bit(Faulty, &rdev->flags))
dprintk("(skipping faulty ");
dprintk("%s ", bdevname(rdev->bdev,b));
- if (!rdev->faulty) {
+ if (!test_bit(Faulty, &rdev->flags)) {
md_super_write(mddev,rdev,
rdev->sb_offset<<1, rdev->sb_size,
rdev->sb_page);
@@ -1399,21 +1482,106 @@ repeat:
/* only need to write one superblock... */
break;
}
- wait_event(mddev->sb_wait, atomic_read(&mddev->pending_writes)==0);
+ md_super_wait(mddev);
/* if there was a failure, sb_dirty was set to 1, and we re-write super */
- spin_lock(&mddev->write_lock);
+ spin_lock_irq(&mddev->write_lock);
if (mddev->in_sync != sync_req|| mddev->sb_dirty == 1) {
/* have to write it out again */
- spin_unlock(&mddev->write_lock);
+ spin_unlock_irq(&mddev->write_lock);
goto repeat;
}
mddev->sb_dirty = 0;
- spin_unlock(&mddev->write_lock);
+ spin_unlock_irq(&mddev->write_lock);
wake_up(&mddev->sb_wait);
}
+struct rdev_sysfs_entry {
+ struct attribute attr;
+ ssize_t (*show)(mdk_rdev_t *, char *);
+ ssize_t (*store)(mdk_rdev_t *, const char *, size_t);
+};
+
+static ssize_t
+state_show(mdk_rdev_t *rdev, char *page)
+{
+ char *sep = "";
+ int len=0;
+
+ if (test_bit(Faulty, &rdev->flags)) {
+ len+= sprintf(page+len, "%sfaulty",sep);
+ sep = ",";
+ }
+ if (test_bit(In_sync, &rdev->flags)) {
+ len += sprintf(page+len, "%sin_sync",sep);
+ sep = ",";
+ }
+ if (!test_bit(Faulty, &rdev->flags) &&
+ !test_bit(In_sync, &rdev->flags)) {
+ len += sprintf(page+len, "%sspare", sep);
+ sep = ",";
+ }
+ return len+sprintf(page+len, "\n");
+}
+
+static struct rdev_sysfs_entry
+rdev_state = __ATTR_RO(state);
+
+static ssize_t
+super_show(mdk_rdev_t *rdev, char *page)
+{
+ if (rdev->sb_loaded && rdev->sb_size) {
+ memcpy(page, page_address(rdev->sb_page), rdev->sb_size);
+ return rdev->sb_size;
+ } else
+ return 0;
+}
+static struct rdev_sysfs_entry rdev_super = __ATTR_RO(super);
+
+static struct attribute *rdev_default_attrs[] = {
+ &rdev_state.attr,
+ &rdev_super.attr,
+ NULL,
+};
+static ssize_t
+rdev_attr_show(struct kobject *kobj, struct attribute *attr, char *page)
+{
+ struct rdev_sysfs_entry *entry = container_of(attr, struct rdev_sysfs_entry, attr);
+ mdk_rdev_t *rdev = container_of(kobj, mdk_rdev_t, kobj);
+
+ if (!entry->show)
+ return -EIO;
+ return entry->show(rdev, page);
+}
+
+static ssize_t
+rdev_attr_store(struct kobject *kobj, struct attribute *attr,
+ const char *page, size_t length)
+{
+ struct rdev_sysfs_entry *entry = container_of(attr, struct rdev_sysfs_entry, attr);
+ mdk_rdev_t *rdev = container_of(kobj, mdk_rdev_t, kobj);
+
+ if (!entry->store)
+ return -EIO;
+ return entry->store(rdev, page, length);
+}
+
+static void rdev_free(struct kobject *ko)
+{
+ mdk_rdev_t *rdev = container_of(ko, mdk_rdev_t, kobj);
+ kfree(rdev);
+}
+static struct sysfs_ops rdev_sysfs_ops = {
+ .show = rdev_attr_show,
+ .store = rdev_attr_store,
+};
+static struct kobj_type rdev_ktype = {
+ .release = rdev_free,
+ .sysfs_ops = &rdev_sysfs_ops,
+ .default_attrs = rdev_default_attrs,
+};
+
/*
* Import a device. If 'super_format' >= 0, then sanity check the superblock
*
@@ -1445,11 +1613,15 @@ static mdk_rdev_t *md_import_device(dev_t newdev, int super_format, int super_mi
if (err)
goto abort_free;
+ rdev->kobj.parent = NULL;
+ rdev->kobj.ktype = &rdev_ktype;
+ kobject_init(&rdev->kobj);
+
rdev->desc_nr = -1;
- rdev->faulty = 0;
- rdev->in_sync = 0;
+ rdev->flags = 0;
rdev->data_offset = 0;
atomic_set(&rdev->nr_pending, 0);
+ atomic_set(&rdev->read_errors, 0);
size = rdev->bdev->bd_inode->i_size >> BLOCK_SIZE_BITS;
if (!size) {
@@ -1537,7 +1709,7 @@ static void analyze_sbs(mddev_t * mddev)
if (mddev->level == LEVEL_MULTIPATH) {
rdev->desc_nr = i++;
rdev->raid_disk = rdev->desc_nr;
- rdev->in_sync = 1;
+ set_bit(In_sync, &rdev->flags);
}
}
@@ -1551,6 +1723,162 @@ static void analyze_sbs(mddev_t * mddev)
}
+static ssize_t
+level_show(mddev_t *mddev, char *page)
+{
+ mdk_personality_t *p = mddev->pers;
+ if (p == NULL && mddev->raid_disks == 0)
+ return 0;
+ if (mddev->level >= 0)
+ return sprintf(page, "RAID-%d\n", mddev->level);
+ else
+ return sprintf(page, "%s\n", p->name);
+}
+
+static struct md_sysfs_entry md_level = __ATTR_RO(level);
+
+static ssize_t
+raid_disks_show(mddev_t *mddev, char *page)
+{
+ if (mddev->raid_disks == 0)
+ return 0;
+ return sprintf(page, "%d\n", mddev->raid_disks);
+}
+
+static struct md_sysfs_entry md_raid_disks = __ATTR_RO(raid_disks);
+
+static ssize_t
+action_show(mddev_t *mddev, char *page)
+{
+ char *type = "idle";
+ if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery) ||
+ test_bit(MD_RECOVERY_NEEDED, &mddev->recovery)) {
+ if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery)) {
+ if (!test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery))
+ type = "resync";
+ else if (test_bit(MD_RECOVERY_CHECK, &mddev->recovery))
+ type = "check";
+ else
+ type = "repair";
+ } else
+ type = "recover";
+ }
+ return sprintf(page, "%s\n", type);
+}
+
+static ssize_t
+action_store(mddev_t *mddev, const char *page, size_t len)
+{
+ if (!mddev->pers || !mddev->pers->sync_request)
+ return -EINVAL;
+
+ if (strcmp(page, "idle")==0 || strcmp(page, "idle\n")==0) {
+ if (mddev->sync_thread) {
+ set_bit(MD_RECOVERY_INTR, &mddev->recovery);
+ md_unregister_thread(mddev->sync_thread);
+ mddev->sync_thread = NULL;
+ mddev->recovery = 0;
+ }
+ return len;
+ }
+
+ if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery) ||
+ test_bit(MD_RECOVERY_NEEDED, &mddev->recovery))
+ return -EBUSY;
+ if (strcmp(page, "resync")==0 || strcmp(page, "resync\n")==0 ||
+ strcmp(page, "recover")==0 || strcmp(page, "recover\n")==0)
+ set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
+ else {
+ if (strcmp(page, "check")==0 || strcmp(page, "check\n")==0)
+ set_bit(MD_RECOVERY_CHECK, &mddev->recovery);
+ else if (strcmp(page, "repair")!=0 && strcmp(page, "repair\n")!=0)
+ return -EINVAL;
+ set_bit(MD_RECOVERY_REQUESTED, &mddev->recovery);
+ set_bit(MD_RECOVERY_SYNC, &mddev->recovery);
+ set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
+ }
+ md_wakeup_thread(mddev->thread);
+ return len;
+}
+
+static ssize_t
+mismatch_cnt_show(mddev_t *mddev, char *page)
+{
+ return sprintf(page, "%llu\n",
+ (unsigned long long) mddev->resync_mismatches);
+}
+
+static struct md_sysfs_entry
+md_scan_mode = __ATTR(sync_action, S_IRUGO|S_IWUSR, action_show, action_store);
+
+
+static struct md_sysfs_entry
+md_mismatches = __ATTR_RO(mismatch_cnt);
+
+static struct attribute *md_default_attrs[] = {
+ &md_level.attr,
+ &md_raid_disks.attr,
+ NULL,
+};
+
+static struct attribute *md_redundancy_attrs[] = {
+ &md_scan_mode.attr,
+ &md_mismatches.attr,
+ NULL,
+};
+static struct attribute_group md_redundancy_group = {
+ .name = NULL,
+ .attrs = md_redundancy_attrs,
+};
+
+
+static ssize_t
+md_attr_show(struct kobject *kobj, struct attribute *attr, char *page)
+{
+ struct md_sysfs_entry *entry = container_of(attr, struct md_sysfs_entry, attr);
+ mddev_t *mddev = container_of(kobj, struct mddev_s, kobj);
+ ssize_t rv;
+
+ if (!entry->show)
+ return -EIO;
+ mddev_lock(mddev);
+ rv = entry->show(mddev, page);
+ mddev_unlock(mddev);
+ return rv;
+}
+
+static ssize_t
+md_attr_store(struct kobject *kobj, struct attribute *attr,
+ const char *page, size_t length)
+{
+ struct md_sysfs_entry *entry = container_of(attr, struct md_sysfs_entry, attr);
+ mddev_t *mddev = container_of(kobj, struct mddev_s, kobj);
+ ssize_t rv;
+
+ if (!entry->store)
+ return -EIO;
+ mddev_lock(mddev);
+ rv = entry->store(mddev, page, length);
+ mddev_unlock(mddev);
+ return rv;
+}
+
+static void md_free(struct kobject *ko)
+{
+ mddev_t *mddev = container_of(ko, mddev_t, kobj);
+ kfree(mddev);
+}
+
+static struct sysfs_ops md_sysfs_ops = {
+ .show = md_attr_show,
+ .store = md_attr_store,
+};
+static struct kobj_type md_ktype = {
+ .release = md_free,
+ .sysfs_ops = &md_sysfs_ops,
+ .default_attrs = md_default_attrs,
+};
+
int mdp_major = 0;
static struct kobject *md_probe(dev_t dev, int *part, void *data)
@@ -1592,6 +1920,11 @@ static struct kobject *md_probe(dev_t dev, int *part, void *data)
add_disk(disk);
mddev->gendisk = disk;
up(&disks_sem);
+ mddev->kobj.parent = &disk->kobj;
+ mddev->kobj.k_name = NULL;
+ snprintf(mddev->kobj.name, KOBJ_NAME_LEN, "%s", "md");
+ mddev->kobj.ktype = &md_ktype;
+ kobject_register(&mddev->kobj);
return NULL;
}
@@ -1663,7 +1996,7 @@ static int do_md_run(mddev_t * mddev)
/* devices must have minimum size of one chunk */
ITERATE_RDEV(mddev,rdev,tmp) {
- if (rdev->faulty)
+ if (test_bit(Faulty, &rdev->flags))
continue;
if (rdev->size < chunk_size / 1024) {
printk(KERN_WARNING
@@ -1691,7 +2024,7 @@ static int do_md_run(mddev_t * mddev)
* Also find largest hardsector size
*/
ITERATE_RDEV(mddev,rdev,tmp) {
- if (rdev->faulty)
+ if (test_bit(Faulty, &rdev->flags))
continue;
sync_blockdev(rdev->bdev);
invalidate_bdev(rdev->bdev, 0);
@@ -1715,6 +2048,10 @@ static int do_md_run(mddev_t * mddev)
mddev->recovery = 0;
mddev->resync_max_sectors = mddev->size << 1; /* may be over-ridden by personality */
+ mddev->barriers_work = 1;
+
+ if (start_readonly)
+ mddev->ro = 2; /* read-only, but switch on first write */
/* before we start the array running, initialise the bitmap */
err = bitmap_create(mddev);
@@ -1730,12 +2067,24 @@ static int do_md_run(mddev_t * mddev)
bitmap_destroy(mddev);
return err;
}
+ if (mddev->pers->sync_request)
+ sysfs_create_group(&mddev->kobj, &md_redundancy_group);
+ else if (mddev->ro == 2) /* auto-readonly not meaningful */
+ mddev->ro = 0;
+
atomic_set(&mddev->writes_pending,0);
mddev->safemode = 0;
mddev->safemode_timer.function = md_safemode_timeout;
mddev->safemode_timer.data = (unsigned long) mddev;
mddev->safemode_delay = (20 * HZ)/1000 +1; /* 20 msec delay */
mddev->in_sync = 1;
+
+ ITERATE_RDEV(mddev,rdev,tmp)
+ if (rdev->raid_disk >= 0) {
+ char nm[20];
+ sprintf(nm, "rd%d", rdev->raid_disk);
+ sysfs_create_link(&mddev->kobj, &rdev->kobj, nm);
+ }
set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
md_wakeup_thread(mddev->thread);
@@ -1821,16 +2170,19 @@ static int do_md_stop(mddev_t * mddev, int ro)
if (ro) {
err = -ENXIO;
- if (mddev->ro)
+ if (mddev->ro==1)
goto out;
mddev->ro = 1;
} else {
bitmap_flush(mddev);
- wait_event(mddev->sb_wait, atomic_read(&mddev->pending_writes)==0);
+ md_super_wait(mddev);
if (mddev->ro)
set_disk_ro(disk, 0);
blk_queue_make_request(mddev->queue, md_fail_request);
mddev->pers->stop(mddev);
+ if (mddev->pers->sync_request)
+ sysfs_remove_group(&mddev->kobj, &md_redundancy_group);
+
module_put(mddev->pers->owner);
mddev->pers = NULL;
if (mddev->ro)
@@ -1857,9 +2209,18 @@ static int do_md_stop(mddev_t * mddev, int ro)
* Free resources if final stop
*/
if (!ro) {
+ mdk_rdev_t *rdev;
+ struct list_head *tmp;
struct gendisk *disk;
printk(KERN_INFO "md: %s stopped.\n", mdname(mddev));
+ ITERATE_RDEV(mddev,rdev,tmp)
+ if (rdev->raid_disk >= 0) {
+ char nm[20];
+ sprintf(nm, "rd%d", rdev->raid_disk);
+ sysfs_remove_link(&mddev->kobj, nm);
+ }
+
export_array(mddev);
mddev->array_size = 0;
@@ -2012,7 +2373,7 @@ static int autostart_array(dev_t startdev)
return err;
}
- if (start_rdev->faulty) {
+ if (test_bit(Faulty, &start_rdev->flags)) {
printk(KERN_WARNING
"md: can not autostart based on faulty %s!\n",
bdevname(start_rdev->bdev,b));
@@ -2071,11 +2432,11 @@ static int get_array_info(mddev_t * mddev, void __user * arg)
nr=working=active=failed=spare=0;
ITERATE_RDEV(mddev,rdev,tmp) {
nr++;
- if (rdev->faulty)
+ if (test_bit(Faulty, &rdev->flags))
failed++;
else {
working++;
- if (rdev->in_sync)
+ if (test_bit(In_sync, &rdev->flags))
active++;
else
spare++;
@@ -2166,9 +2527,9 @@ static int get_disk_info(mddev_t * mddev, void __user * arg)
info.minor = MINOR(rdev->bdev->bd_dev);
info.raid_disk = rdev->raid_disk;
info.state = 0;
- if (rdev->faulty)
+ if (test_bit(Faulty, &rdev->flags))
info.state |= (1<<MD_DISK_FAULTY);
- else if (rdev->in_sync) {
+ else if (test_bit(In_sync, &rdev->flags)) {
info.state |= (1<<MD_DISK_ACTIVE);
info.state |= (1<<MD_DISK_SYNC);
}
@@ -2261,7 +2622,7 @@ static int add_new_disk(mddev_t * mddev, mdu_disk_info_t *info)
validate_super(mddev, rdev);
rdev->saved_raid_disk = rdev->raid_disk;
- rdev->in_sync = 0; /* just to be sure */
+ clear_bit(In_sync, &rdev->flags); /* just to be sure */
if (info->state & (1<<MD_DISK_WRITEMOSTLY))
set_bit(WriteMostly, &rdev->flags);
@@ -2299,11 +2660,11 @@ static int add_new_disk(mddev_t * mddev, mdu_disk_info_t *info)
else
rdev->raid_disk = -1;
- rdev->faulty = 0;
+ rdev->flags = 0;
+
if (rdev->raid_disk < mddev->raid_disks)
- rdev->in_sync = (info->state & (1<<MD_DISK_SYNC));
- else
- rdev->in_sync = 0;
+ if (info->state & (1<<MD_DISK_SYNC))
+ set_bit(In_sync, &rdev->flags);
if (info->state & (1<<MD_DISK_WRITEMOSTLY))
set_bit(WriteMostly, &rdev->flags);
@@ -2402,14 +2763,14 @@ static int hot_add_disk(mddev_t * mddev, dev_t dev)
goto abort_export;
}
- if (rdev->faulty) {
+ if (test_bit(Faulty, &rdev->flags)) {
printk(KERN_WARNING
"md: can not hot-add faulty %s disk to %s!\n",
bdevname(rdev->bdev,b), mdname(mddev));
err = -EINVAL;
goto abort_export;
}
- rdev->in_sync = 0;
+ clear_bit(In_sync, &rdev->flags);
rdev->desc_nr = -1;
bind_rdev_to_array(rdev, mddev);
@@ -2929,12 +3290,22 @@ static int md_ioctl(struct inode *inode, struct file *file,
/*
* The remaining ioctls are changing the state of the
- * superblock, so we do not allow read-only arrays
- * here:
+ * superblock, so we do not allow them on read-only arrays.
+ * However non-MD ioctls (e.g. get-size) will still come through
+ * here and hit the 'default' below, so only disallow
+ * 'md' ioctls, and switch to rw mode if started auto-readonly.
*/
- if (mddev->ro) {
- err = -EROFS;
- goto abort_unlock;
+ if (_IOC_TYPE(cmd) == MD_MAJOR &&
+ mddev->ro && mddev->pers) {
+ if (mddev->ro == 2) {
+ mddev->ro = 0;
+ set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
+ md_wakeup_thread(mddev->thread);
+
+ } else {
+ err = -EROFS;
+ goto abort_unlock;
+ }
}
switch (cmd)
@@ -3064,21 +3435,17 @@ static int md_thread(void * arg)
*/
allow_signal(SIGKILL);
- complete(thread->event);
while (!kthread_should_stop()) {
- void (*run)(mddev_t *);
- wait_event_interruptible_timeout(thread->wqueue,
- test_bit(THREAD_WAKEUP, &thread->flags)
- || kthread_should_stop(),
- thread->timeout);
+ wait_event_timeout(thread->wqueue,
+ test_bit(THREAD_WAKEUP, &thread->flags)
+ || kthread_should_stop(),
+ thread->timeout);
try_to_freeze();
clear_bit(THREAD_WAKEUP, &thread->flags);
- run = thread->run;
- if (run)
- run(thread->mddev);
+ thread->run(thread->mddev);
}
return 0;
@@ -3097,7 +3464,6 @@ mdk_thread_t *md_register_thread(void (*run) (mddev_t *), mddev_t *mddev,
const char *name)
{
mdk_thread_t *thread;
- struct completion event;
thread = kmalloc(sizeof(mdk_thread_t), GFP_KERNEL);
if (!thread)
@@ -3106,18 +3472,14 @@ mdk_thread_t *md_register_thread(void (*run) (mddev_t *), mddev_t *mddev,
memset(thread, 0, sizeof(mdk_thread_t));
init_waitqueue_head(&thread->wqueue);
- init_completion(&event);
- thread->event = &event;
thread->run = run;
thread->mddev = mddev;
- thread->name = name;
thread->timeout = MAX_SCHEDULE_TIMEOUT;
thread->tsk = kthread_run(md_thread, thread, name, mdname(thread->mddev));
if (IS_ERR(thread->tsk)) {
kfree(thread);
return NULL;
}
- wait_for_completion(&event);
return thread;
}
@@ -3136,7 +3498,7 @@ void md_error(mddev_t *mddev, mdk_rdev_t *rdev)
return;
}
- if (!rdev || rdev->faulty)
+ if (!rdev || test_bit(Faulty, &rdev->flags))
return;
/*
dprintk("md_error dev:%s, rdev:(%d:%d), (caller: %p,%p,%p,%p).\n",
@@ -3322,8 +3684,10 @@ static int md_seq_show(struct seq_file *seq, void *v)
seq_printf(seq, "%s : %sactive", mdname(mddev),
mddev->pers ? "" : "in");
if (mddev->pers) {
- if (mddev->ro)
+ if (mddev->ro==1)
seq_printf(seq, " (read-only)");
+ if (mddev->ro==2)
+ seq_printf(seq, "(auto-read-only)");
seq_printf(seq, " %s", mddev->pers->name);
}
@@ -3334,7 +3698,7 @@ static int md_seq_show(struct seq_file *seq, void *v)
bdevname(rdev->bdev,b), rdev->desc_nr);
if (test_bit(WriteMostly, &rdev->flags))
seq_printf(seq, "(W)");
- if (rdev->faulty) {
+ if (test_bit(Faulty, &rdev->flags)) {
seq_printf(seq, "(F)");
continue;
} else if (rdev->raid_disk < 0)
@@ -3363,11 +3727,15 @@ static int md_seq_show(struct seq_file *seq, void *v)
if (mddev->pers) {
mddev->pers->status (seq, mddev);
seq_printf(seq, "\n ");
- if (mddev->curr_resync > 2) {
- status_resync (seq, mddev);
- seq_printf(seq, "\n ");
- } else if (mddev->curr_resync == 1 || mddev->curr_resync == 2)
- seq_printf(seq, " resync=DELAYED\n ");
+ if (mddev->pers->sync_request) {
+ if (mddev->curr_resync > 2) {
+ status_resync (seq, mddev);
+ seq_printf(seq, "\n ");
+ } else if (mddev->curr_resync == 1 || mddev->curr_resync == 2)
+ seq_printf(seq, "\tresync=DELAYED\n ");
+ else if (mddev->recovery_cp < MaxSector)
+ seq_printf(seq, "\tresync=PENDING\n ");
+ }
} else
seq_printf(seq, "\n ");
@@ -3466,8 +3834,8 @@ static int is_mddev_idle(mddev_t *mddev)
idle = 1;
ITERATE_RDEV(mddev,rdev,tmp) {
struct gendisk *disk = rdev->bdev->bd_contains->bd_disk;
- curr_events = disk_stat_read(disk, read_sectors) +
- disk_stat_read(disk, write_sectors) -
+ curr_events = disk_stat_read(disk, sectors[0]) +
+ disk_stat_read(disk, sectors[1]) -
atomic_read(&disk->sync_io);
/* Allow some slack between valud of curr_events and last_events,
* as there are some uninteresting races.
@@ -3504,15 +3872,22 @@ void md_write_start(mddev_t *mddev, struct bio *bi)
if (bio_data_dir(bi) != WRITE)
return;
+ BUG_ON(mddev->ro == 1);
+ if (mddev->ro == 2) {
+ /* need to switch to read/write */
+ mddev->ro = 0;
+ set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
+ md_wakeup_thread(mddev->thread);
+ }
atomic_inc(&mddev->writes_pending);
if (mddev->in_sync) {
- spin_lock(&mddev->write_lock);
+ spin_lock_irq(&mddev->write_lock);
if (mddev->in_sync) {
mddev->in_sync = 0;
mddev->sb_dirty = 1;
md_wakeup_thread(mddev->thread);
}
- spin_unlock(&mddev->write_lock);
+ spin_unlock_irq(&mddev->write_lock);
}
wait_event(mddev->sb_wait, mddev->sb_dirty==0);
}
@@ -3568,9 +3943,7 @@ static void md_do_sync(mddev_t *mddev)
mddev->curr_resync = 2;
try_again:
- if (signal_pending(current) ||
- kthread_should_stop()) {
- flush_signals(current);
+ if (kthread_should_stop()) {
set_bit(MD_RECOVERY_INTR, &mddev->recovery);
goto skip;
}
@@ -3590,9 +3963,8 @@ static void md_do_sync(mddev_t *mddev)
* time 'round when curr_resync == 2
*/
continue;
- prepare_to_wait(&resync_wait, &wq, TASK_INTERRUPTIBLE);
- if (!signal_pending(current) &&
- !kthread_should_stop() &&
+ prepare_to_wait(&resync_wait, &wq, TASK_UNINTERRUPTIBLE);
+ if (!kthread_should_stop() &&
mddev2->curr_resync >= mddev->curr_resync) {
printk(KERN_INFO "md: delaying resync of %s"
" until %s has finished resync (they"
@@ -3608,12 +3980,13 @@ static void md_do_sync(mddev_t *mddev)
}
} while (mddev->curr_resync < 2);
- if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery))
+ if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery)) {
/* resync follows the size requested by the personality,
* which defaults to physical size, but can be virtual size
*/
max_sectors = mddev->resync_max_sectors;
- else
+ mddev->resync_mismatches = 0;
+ } else
/* recovery follows the physical size of devices */
max_sectors = mddev->size << 1;
@@ -3626,7 +3999,8 @@ static void md_do_sync(mddev_t *mddev)
is_mddev_idle(mddev); /* this also initializes IO event counters */
/* we don't use the checkpoint if there's a bitmap */
- if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery) && !mddev->bitmap)
+ if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery) && !mddev->bitmap
+ && ! test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery))
j = mddev->recovery_cp;
else
j = 0;
@@ -3699,13 +4073,12 @@ static void md_do_sync(mddev_t *mddev)
}
- if (signal_pending(current) || kthread_should_stop()) {
+ if (kthread_should_stop()) {
/*
* got a signal, exit.
*/
printk(KERN_INFO
"md: md_do_sync() got signal ... exiting\n");
- flush_signals(current);
set_bit(MD_RECOVERY_INTR, &mddev->recovery);
goto out;
}
@@ -3727,7 +4100,7 @@ static void md_do_sync(mddev_t *mddev)
if (currspeed > sysctl_speed_limit_min) {
if ((currspeed > sysctl_speed_limit_max) ||
!is_mddev_idle(mddev)) {
- msleep_interruptible(250);
+ msleep(250);
goto repeat;
}
}
@@ -3820,7 +4193,7 @@ void md_check_recovery(mddev_t *mddev)
if (mddev_trylock(mddev)==0) {
int spares =0;
- spin_lock(&mddev->write_lock);
+ spin_lock_irq(&mddev->write_lock);
if (mddev->safemode && !atomic_read(&mddev->writes_pending) &&
!mddev->in_sync && mddev->recovery_cp == MaxSector) {
mddev->in_sync = 1;
@@ -3828,7 +4201,7 @@ void md_check_recovery(mddev_t *mddev)
}
if (mddev->safemode == 1)
mddev->safemode = 0;
- spin_unlock(&mddev->write_lock);
+ spin_unlock_irq(&mddev->write_lock);
if (mddev->sb_dirty)
md_update_sb(mddev);
@@ -3864,9 +4237,13 @@ void md_check_recovery(mddev_t *mddev)
set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
goto unlock;
}
- if (mddev->recovery)
- /* probably just the RECOVERY_NEEDED flag */
- mddev->recovery = 0;
+ /* Clear some bits that don't mean anything, but
+ * might be left set
+ */
+ clear_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
+ clear_bit(MD_RECOVERY_ERR, &mddev->recovery);
+ clear_bit(MD_RECOVERY_INTR, &mddev->recovery);
+ clear_bit(MD_RECOVERY_DONE, &mddev->recovery);
/* no recovery is running.
* remove any failed drives, then
@@ -3876,31 +4253,41 @@ void md_check_recovery(mddev_t *mddev)
*/
ITERATE_RDEV(mddev,rdev,rtmp)
if (rdev->raid_disk >= 0 &&
- (rdev->faulty || ! rdev->in_sync) &&
+ (test_bit(Faulty, &rdev->flags) || ! test_bit(In_sync, &rdev->flags)) &&
atomic_read(&rdev->nr_pending)==0) {
- if (mddev->pers->hot_remove_disk(mddev, rdev->raid_disk)==0)
+ if (mddev->pers->hot_remove_disk(mddev, rdev->raid_disk)==0) {
+ char nm[20];
+ sprintf(nm,"rd%d", rdev->raid_disk);
+ sysfs_remove_link(&mddev->kobj, nm);
rdev->raid_disk = -1;
+ }
}
if (mddev->degraded) {
ITERATE_RDEV(mddev,rdev,rtmp)
if (rdev->raid_disk < 0
- && !rdev->faulty) {
- if (mddev->pers->hot_add_disk(mddev,rdev))
+ && !test_bit(Faulty, &rdev->flags)) {
+ if (mddev->pers->hot_add_disk(mddev,rdev)) {
+ char nm[20];
+ sprintf(nm, "rd%d", rdev->raid_disk);
+ sysfs_create_link(&mddev->kobj, &rdev->kobj, nm);
spares++;
- else
+ } else
break;
}
}
- if (!spares && (mddev->recovery_cp == MaxSector )) {
- /* nothing we can do ... */
+ if (spares) {
+ clear_bit(MD_RECOVERY_SYNC, &mddev->recovery);
+ clear_bit(MD_RECOVERY_CHECK, &mddev->recovery);
+ } else if (mddev->recovery_cp < MaxSector) {
+ set_bit(MD_RECOVERY_SYNC, &mddev->recovery);
+ } else if (!test_bit(MD_RECOVERY_SYNC, &mddev->recovery))
+ /* nothing to be done ... */
goto unlock;
- }
+
if (mddev->pers->sync_request) {
set_bit(MD_RECOVERY_RUNNING, &mddev->recovery);
- if (!spares)
- set_bit(MD_RECOVERY_SYNC, &mddev->recovery);
if (spares && mddev->bitmap && ! mddev->bitmap->file) {
/* We are adding a device or devices to an array
* which has the bitmap stored on all devices.
@@ -3975,7 +4362,7 @@ static int __init md_init(void)
" MD_SB_DISKS=%d\n",
MD_MAJOR_VERSION, MD_MINOR_VERSION,
MD_PATCHLEVEL_VERSION, MAX_MD_DEVS, MD_SB_DISKS);
- printk(KERN_INFO "md: bitmap version %d.%d\n", BITMAP_MAJOR,
+ printk(KERN_INFO "md: bitmap version %d.%d\n", BITMAP_MAJOR_HI,
BITMAP_MINOR);
if (register_blkdev(MAJOR_NR, "md"))
@@ -4039,7 +4426,7 @@ static void autostart_arrays(int part)
if (IS_ERR(rdev))
continue;
- if (rdev->faulty) {
+ if (test_bit(Faulty, &rdev->flags)) {
MD_BUG();
continue;
}
@@ -4086,6 +4473,23 @@ static __exit void md_exit(void)
module_init(md_init)
module_exit(md_exit)
+static int get_ro(char *buffer, struct kernel_param *kp)
+{
+ return sprintf(buffer, "%d", start_readonly);
+}
+static int set_ro(const char *val, struct kernel_param *kp)
+{
+ char *e;
+ int num = simple_strtoul(val, &e, 10);
+ if (*val && (*e == '\0' || *e == '\n')) {
+ start_readonly = num;
+ return 0;;
+ }
+ return -EINVAL;
+}
+
+module_param_call(start_ro, set_ro, get_ro, NULL, 0600);
+
EXPORT_SYMBOL(register_md_personality);
EXPORT_SYMBOL(unregister_md_personality);
EXPORT_SYMBOL(md_error);
diff --git a/drivers/md/multipath.c b/drivers/md/multipath.c
index 1151c3ed3006..145cdc5ad008 100644
--- a/drivers/md/multipath.c
+++ b/drivers/md/multipath.c
@@ -63,8 +63,8 @@ static int multipath_map (multipath_conf_t *conf)
rcu_read_lock();
for (i = 0; i < disks; i++) {
- mdk_rdev_t *rdev = conf->multipaths[i].rdev;
- if (rdev && rdev->in_sync) {
+ mdk_rdev_t *rdev = rcu_dereference(conf->multipaths[i].rdev);
+ if (rdev && test_bit(In_sync, &rdev->flags)) {
atomic_inc(&rdev->nr_pending);
rcu_read_unlock();
return i;
@@ -139,8 +139,9 @@ static void unplug_slaves(mddev_t *mddev)
rcu_read_lock();
for (i=0; i<mddev->raid_disks; i++) {
- mdk_rdev_t *rdev = conf->multipaths[i].rdev;
- if (rdev && !rdev->faulty && atomic_read(&rdev->nr_pending)) {
+ mdk_rdev_t *rdev = rcu_dereference(conf->multipaths[i].rdev);
+ if (rdev && !test_bit(Faulty, &rdev->flags)
+ && atomic_read(&rdev->nr_pending)) {
request_queue_t *r_queue = bdev_get_queue(rdev->bdev);
atomic_inc(&rdev->nr_pending);
@@ -168,6 +169,7 @@ static int multipath_make_request (request_queue_t *q, struct bio * bio)
multipath_conf_t *conf = mddev_to_conf(mddev);
struct multipath_bh * mp_bh;
struct multipath_info *multipath;
+ const int rw = bio_data_dir(bio);
if (unlikely(bio_barrier(bio))) {
bio_endio(bio, bio->bi_size, -EOPNOTSUPP);
@@ -179,13 +181,8 @@ static int multipath_make_request (request_queue_t *q, struct bio * bio)
mp_bh->master_bio = bio;
mp_bh->mddev = mddev;
- if (bio_data_dir(bio)==WRITE) {
- disk_stat_inc(mddev->gendisk, writes);
- disk_stat_add(mddev->gendisk, write_sectors, bio_sectors(bio));
- } else {
- disk_stat_inc(mddev->gendisk, reads);
- disk_stat_add(mddev->gendisk, read_sectors, bio_sectors(bio));
- }
+ disk_stat_inc(mddev->gendisk, ios[rw]);
+ disk_stat_add(mddev->gendisk, sectors[rw], bio_sectors(bio));
mp_bh->path = multipath_map(conf);
if (mp_bh->path < 0) {
@@ -215,7 +212,7 @@ static void multipath_status (struct seq_file *seq, mddev_t *mddev)
for (i = 0; i < conf->raid_disks; i++)
seq_printf (seq, "%s",
conf->multipaths[i].rdev &&
- conf->multipaths[i].rdev->in_sync ? "U" : "_");
+ test_bit(In_sync, &conf->multipaths[i].rdev->flags) ? "U" : "_");
seq_printf (seq, "]");
}
@@ -228,8 +225,8 @@ static int multipath_issue_flush(request_queue_t *q, struct gendisk *disk,
rcu_read_lock();
for (i=0; i<mddev->raid_disks && ret == 0; i++) {
- mdk_rdev_t *rdev = conf->multipaths[i].rdev;
- if (rdev && !rdev->faulty) {
+ mdk_rdev_t *rdev = rcu_dereference(conf->multipaths[i].rdev);
+ if (rdev && !test_bit(Faulty, &rdev->flags)) {
struct block_device *bdev = rdev->bdev;
request_queue_t *r_queue = bdev_get_queue(bdev);
@@ -269,10 +266,10 @@ static void multipath_error (mddev_t *mddev, mdk_rdev_t *rdev)
/*
* Mark disk as unusable
*/
- if (!rdev->faulty) {
+ if (!test_bit(Faulty, &rdev->flags)) {
char b[BDEVNAME_SIZE];
- rdev->in_sync = 0;
- rdev->faulty = 1;
+ clear_bit(In_sync, &rdev->flags);
+ set_bit(Faulty, &rdev->flags);
mddev->sb_dirty = 1;
conf->working_disks--;
printk(KERN_ALERT "multipath: IO failure on %s,"
@@ -302,7 +299,7 @@ static void print_multipath_conf (multipath_conf_t *conf)
tmp = conf->multipaths + i;
if (tmp->rdev)
printk(" disk%d, o:%d, dev:%s\n",
- i,!tmp->rdev->faulty,
+ i,!test_bit(Faulty, &tmp->rdev->flags),
bdevname(tmp->rdev->bdev,b));
}
}
@@ -334,8 +331,8 @@ static int multipath_add_disk(mddev_t *mddev, mdk_rdev_t *rdev)
conf->working_disks++;
rdev->raid_disk = path;
- rdev->in_sync = 1;
- p->rdev = rdev;
+ set_bit(In_sync, &rdev->flags);
+ rcu_assign_pointer(p->rdev, rdev);
found = 1;
}
@@ -354,7 +351,7 @@ static int multipath_remove_disk(mddev_t *mddev, int number)
rdev = p->rdev;
if (rdev) {
- if (rdev->in_sync ||
+ if (test_bit(In_sync, &rdev->flags) ||
atomic_read(&rdev->nr_pending)) {
printk(KERN_ERR "hot-remove-disk, slot %d is identified" " but is still operational!\n", number);
err = -EBUSY;
@@ -486,7 +483,7 @@ static int multipath_run (mddev_t *mddev)
mddev->queue->max_sectors > (PAGE_SIZE>>9))
blk_queue_max_sectors(mddev->queue, PAGE_SIZE>>9);
- if (!rdev->faulty)
+ if (!test_bit(Faulty, &rdev->flags))
conf->working_disks++;
}
diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c
index f6757259ce7f..fece3277c2a5 100644
--- a/drivers/md/raid0.c
+++ b/drivers/md/raid0.c
@@ -403,19 +403,15 @@ static int raid0_make_request (request_queue_t *q, struct bio *bio)
mdk_rdev_t *tmp_dev;
unsigned long chunk;
sector_t block, rsect;
+ const int rw = bio_data_dir(bio);
if (unlikely(bio_barrier(bio))) {
bio_endio(bio, bio->bi_size, -EOPNOTSUPP);
return 0;
}
- if (bio_data_dir(bio)==WRITE) {
- disk_stat_inc(mddev->gendisk, writes);
- disk_stat_add(mddev->gendisk, write_sectors, bio_sectors(bio));
- } else {
- disk_stat_inc(mddev->gendisk, reads);
- disk_stat_add(mddev->gendisk, read_sectors, bio_sectors(bio));
- }
+ disk_stat_inc(mddev->gendisk, ios[rw]);
+ disk_stat_add(mddev->gendisk, sectors[rw], bio_sectors(bio));
chunk_size = mddev->chunk_size >> 10;
chunk_sects = mddev->chunk_size >> 9;
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index 0e1f148dd41d..2da9d3ba902d 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -301,7 +301,7 @@ static int raid1_end_write_request(struct bio *bio, unsigned int bytes_done, int
{
int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags);
r1bio_t * r1_bio = (r1bio_t *)(bio->bi_private);
- int mirror, behind;
+ int mirror, behind = test_bit(R1BIO_BehindIO, &r1_bio->state);
conf_t *conf = mddev_to_conf(r1_bio->mddev);
if (bio->bi_size)
@@ -311,47 +311,54 @@ static int raid1_end_write_request(struct bio *bio, unsigned int bytes_done, int
if (r1_bio->bios[mirror] == bio)
break;
- /*
- * this branch is our 'one mirror IO has finished' event handler:
- */
- if (!uptodate) {
- md_error(r1_bio->mddev, conf->mirrors[mirror].rdev);
- /* an I/O failed, we can't clear the bitmap */
- set_bit(R1BIO_Degraded, &r1_bio->state);
- } else
+ if (error == -ENOTSUPP && test_bit(R1BIO_Barrier, &r1_bio->state)) {
+ set_bit(BarriersNotsupp, &conf->mirrors[mirror].rdev->flags);
+ set_bit(R1BIO_BarrierRetry, &r1_bio->state);
+ r1_bio->mddev->barriers_work = 0;
+ } else {
/*
- * Set R1BIO_Uptodate in our master bio, so that
- * we will return a good error code for to the higher
- * levels even if IO on some other mirrored buffer fails.
- *
- * The 'master' represents the composite IO operation to
- * user-side. So if something waits for IO, then it will
- * wait for the 'master' bio.
+ * this branch is our 'one mirror IO has finished' event handler:
*/
- set_bit(R1BIO_Uptodate, &r1_bio->state);
-
- update_head_pos(mirror, r1_bio);
-
- behind = test_bit(R1BIO_BehindIO, &r1_bio->state);
- if (behind) {
- if (test_bit(WriteMostly, &conf->mirrors[mirror].rdev->flags))
- atomic_dec(&r1_bio->behind_remaining);
-
- /* In behind mode, we ACK the master bio once the I/O has safely
- * reached all non-writemostly disks. Setting the Returned bit
- * ensures that this gets done only once -- we don't ever want to
- * return -EIO here, instead we'll wait */
-
- if (atomic_read(&r1_bio->behind_remaining) >= (atomic_read(&r1_bio->remaining)-1) &&
- test_bit(R1BIO_Uptodate, &r1_bio->state)) {
- /* Maybe we can return now */
- if (!test_and_set_bit(R1BIO_Returned, &r1_bio->state)) {
- struct bio *mbio = r1_bio->master_bio;
- PRINTK(KERN_DEBUG "raid1: behind end write sectors %llu-%llu\n",
- (unsigned long long) mbio->bi_sector,
- (unsigned long long) mbio->bi_sector +
- (mbio->bi_size >> 9) - 1);
- bio_endio(mbio, mbio->bi_size, 0);
+ r1_bio->bios[mirror] = NULL;
+ bio_put(bio);
+ if (!uptodate) {
+ md_error(r1_bio->mddev, conf->mirrors[mirror].rdev);
+ /* an I/O failed, we can't clear the bitmap */
+ set_bit(R1BIO_Degraded, &r1_bio->state);
+ } else
+ /*
+ * Set R1BIO_Uptodate in our master bio, so that
+ * we will return a good error code for to the higher
+ * levels even if IO on some other mirrored buffer fails.
+ *
+ * The 'master' represents the composite IO operation to
+ * user-side. So if something waits for IO, then it will
+ * wait for the 'master' bio.
+ */
+ set_bit(R1BIO_Uptodate, &r1_bio->state);
+
+ update_head_pos(mirror, r1_bio);
+
+ if (behind) {
+ if (test_bit(WriteMostly, &conf->mirrors[mirror].rdev->flags))
+ atomic_dec(&r1_bio->behind_remaining);
+
+ /* In behind mode, we ACK the master bio once the I/O has safely
+ * reached all non-writemostly disks. Setting the Returned bit
+ * ensures that this gets done only once -- we don't ever want to
+ * return -EIO here, instead we'll wait */
+
+ if (atomic_read(&r1_bio->behind_remaining) >= (atomic_read(&r1_bio->remaining)-1) &&
+ test_bit(R1BIO_Uptodate, &r1_bio->state)) {
+ /* Maybe we can return now */
+ if (!test_and_set_bit(R1BIO_Returned, &r1_bio->state)) {
+ struct bio *mbio = r1_bio->master_bio;
+ PRINTK(KERN_DEBUG "raid1: behind end write sectors %llu-%llu\n",
+ (unsigned long long) mbio->bi_sector,
+ (unsigned long long) mbio->bi_sector +
+ (mbio->bi_size >> 9) - 1);
+ bio_endio(mbio, mbio->bi_size, 0);
+ }
}
}
}
@@ -361,8 +368,16 @@ static int raid1_end_write_request(struct bio *bio, unsigned int bytes_done, int
* already.
*/
if (atomic_dec_and_test(&r1_bio->remaining)) {
+ if (test_bit(R1BIO_BarrierRetry, &r1_bio->state)) {
+ reschedule_retry(r1_bio);
+ /* Don't dec_pending yet, we want to hold
+ * the reference over the retry
+ */
+ return 0;
+ }
if (test_bit(R1BIO_BehindIO, &r1_bio->state)) {
/* free extra copy of the data pages */
+/* FIXME bio has been freed!!! */
int i = bio->bi_vcnt;
while (i--)
__free_page(bio->bi_io_vec[i].bv_page);
@@ -416,12 +431,12 @@ static int read_balance(conf_t *conf, r1bio_t *r1_bio)
/* Choose the first operation device, for consistancy */
new_disk = 0;
- for (rdev = conf->mirrors[new_disk].rdev;
- !rdev || !rdev->in_sync
+ for (rdev = rcu_dereference(conf->mirrors[new_disk].rdev);
+ !rdev || !test_bit(In_sync, &rdev->flags)
|| test_bit(WriteMostly, &rdev->flags);
- rdev = conf->mirrors[++new_disk].rdev) {
+ rdev = rcu_dereference(conf->mirrors[++new_disk].rdev)) {
- if (rdev && rdev->in_sync)
+ if (rdev && test_bit(In_sync, &rdev->flags))
wonly_disk = new_disk;
if (new_disk == conf->raid_disks - 1) {
@@ -434,12 +449,12 @@ static int read_balance(conf_t *conf, r1bio_t *r1_bio)
/* make sure the disk is operational */
- for (rdev = conf->mirrors[new_disk].rdev;
- !rdev || !rdev->in_sync ||
+ for (rdev = rcu_dereference(conf->mirrors[new_disk].rdev);
+ !rdev || !test_bit(In_sync, &rdev->flags) ||
test_bit(WriteMostly, &rdev->flags);
- rdev = conf->mirrors[new_disk].rdev) {
+ rdev = rcu_dereference(conf->mirrors[new_disk].rdev)) {
- if (rdev && rdev->in_sync)
+ if (rdev && test_bit(In_sync, &rdev->flags))
wonly_disk = new_disk;
if (new_disk <= 0)
@@ -474,10 +489,10 @@ static int read_balance(conf_t *conf, r1bio_t *r1_bio)
disk = conf->raid_disks;
disk--;
- rdev = conf->mirrors[disk].rdev;
+ rdev = rcu_dereference(conf->mirrors[disk].rdev);
if (!rdev ||
- !rdev->in_sync ||
+ !test_bit(In_sync, &rdev->flags) ||
test_bit(WriteMostly, &rdev->flags))
continue;
@@ -496,11 +511,11 @@ static int read_balance(conf_t *conf, r1bio_t *r1_bio)
if (new_disk >= 0) {
- rdev = conf->mirrors[new_disk].rdev;
+ rdev = rcu_dereference(conf->mirrors[new_disk].rdev);
if (!rdev)
goto retry;
atomic_inc(&rdev->nr_pending);
- if (!rdev->in_sync) {
+ if (!test_bit(In_sync, &rdev->flags)) {
/* cannot risk returning a device that failed
* before we inc'ed nr_pending
*/
@@ -522,8 +537,8 @@ static void unplug_slaves(mddev_t *mddev)
rcu_read_lock();
for (i=0; i<mddev->raid_disks; i++) {
- mdk_rdev_t *rdev = conf->mirrors[i].rdev;
- if (rdev && !rdev->faulty && atomic_read(&rdev->nr_pending)) {
+ mdk_rdev_t *rdev = rcu_dereference(conf->mirrors[i].rdev);
+ if (rdev && !test_bit(Faulty, &rdev->flags) && atomic_read(&rdev->nr_pending)) {
request_queue_t *r_queue = bdev_get_queue(rdev->bdev);
atomic_inc(&rdev->nr_pending);
@@ -556,8 +571,8 @@ static int raid1_issue_flush(request_queue_t *q, struct gendisk *disk,
rcu_read_lock();
for (i=0; i<mddev->raid_disks && ret == 0; i++) {
- mdk_rdev_t *rdev = conf->mirrors[i].rdev;
- if (rdev && !rdev->faulty) {
+ mdk_rdev_t *rdev = rcu_dereference(conf->mirrors[i].rdev);
+ if (rdev && !test_bit(Faulty, &rdev->flags)) {
struct block_device *bdev = rdev->bdev;
request_queue_t *r_queue = bdev_get_queue(bdev);
@@ -647,8 +662,10 @@ static int make_request(request_queue_t *q, struct bio * bio)
unsigned long flags;
struct bio_list bl;
struct page **behind_pages = NULL;
+ const int rw = bio_data_dir(bio);
+ int do_barriers;
- if (unlikely(bio_barrier(bio))) {
+ if (unlikely(!mddev->barriers_work && bio_barrier(bio))) {
bio_endio(bio, bio->bi_size, -EOPNOTSUPP);
return 0;
}
@@ -665,13 +682,8 @@ static int make_request(request_queue_t *q, struct bio * bio)
conf->nr_pending++;
spin_unlock_irq(&conf->resync_lock);
- if (bio_data_dir(bio)==WRITE) {
- disk_stat_inc(mddev->gendisk, writes);
- disk_stat_add(mddev->gendisk, write_sectors, bio_sectors(bio));
- } else {
- disk_stat_inc(mddev->gendisk, reads);
- disk_stat_add(mddev->gendisk, read_sectors, bio_sectors(bio));
- }
+ disk_stat_inc(mddev->gendisk, ios[rw]);
+ disk_stat_add(mddev->gendisk, sectors[rw], bio_sectors(bio));
/*
* make_request() can abort the operation when READA is being
@@ -686,7 +698,7 @@ static int make_request(request_queue_t *q, struct bio * bio)
r1_bio->mddev = mddev;
r1_bio->sector = bio->bi_sector;
- if (bio_data_dir(bio) == READ) {
+ if (rw == READ) {
/*
* read balancing logic:
*/
@@ -732,10 +744,10 @@ static int make_request(request_queue_t *q, struct bio * bio)
#endif
rcu_read_lock();
for (i = 0; i < disks; i++) {
- if ((rdev=conf->mirrors[i].rdev) != NULL &&
- !rdev->faulty) {
+ if ((rdev=rcu_dereference(conf->mirrors[i].rdev)) != NULL &&
+ !test_bit(Faulty, &rdev->flags)) {
atomic_inc(&rdev->nr_pending);
- if (rdev->faulty) {
+ if (test_bit(Faulty, &rdev->flags)) {
atomic_dec(&rdev->nr_pending);
r1_bio->bios[i] = NULL;
} else
@@ -763,6 +775,10 @@ static int make_request(request_queue_t *q, struct bio * bio)
atomic_set(&r1_bio->remaining, 0);
atomic_set(&r1_bio->behind_remaining, 0);
+ do_barriers = bio->bi_rw & BIO_RW_BARRIER;
+ if (do_barriers)
+ set_bit(R1BIO_Barrier, &r1_bio->state);
+
bio_list_init(&bl);
for (i = 0; i < disks; i++) {
struct bio *mbio;
@@ -775,7 +791,7 @@ static int make_request(request_queue_t *q, struct bio * bio)
mbio->bi_sector = r1_bio->sector + conf->mirrors[i].rdev->data_offset;
mbio->bi_bdev = conf->mirrors[i].rdev->bdev;
mbio->bi_end_io = raid1_end_write_request;
- mbio->bi_rw = WRITE;
+ mbio->bi_rw = WRITE | do_barriers;
mbio->bi_private = r1_bio;
if (behind_pages) {
@@ -828,7 +844,7 @@ static void status(struct seq_file *seq, mddev_t *mddev)
for (i = 0; i < conf->raid_disks; i++)
seq_printf(seq, "%s",
conf->mirrors[i].rdev &&
- conf->mirrors[i].rdev->in_sync ? "U" : "_");
+ test_bit(In_sync, &conf->mirrors[i].rdev->flags) ? "U" : "_");
seq_printf(seq, "]");
}
@@ -844,14 +860,14 @@ static void error(mddev_t *mddev, mdk_rdev_t *rdev)
* next level up know.
* else mark the drive as failed
*/
- if (rdev->in_sync
+ if (test_bit(In_sync, &rdev->flags)
&& conf->working_disks == 1)
/*
* Don't fail the drive, act as though we were just a
* normal single drive
*/
return;
- if (rdev->in_sync) {
+ if (test_bit(In_sync, &rdev->flags)) {
mddev->degraded++;
conf->working_disks--;
/*
@@ -859,8 +875,8 @@ static void error(mddev_t *mddev, mdk_rdev_t *rdev)
*/
set_bit(MD_RECOVERY_ERR, &mddev->recovery);
}
- rdev->in_sync = 0;
- rdev->faulty = 1;
+ clear_bit(In_sync, &rdev->flags);
+ set_bit(Faulty, &rdev->flags);
mddev->sb_dirty = 1;
printk(KERN_ALERT "raid1: Disk failure on %s, disabling device. \n"
" Operation continuing on %d devices\n",
@@ -885,7 +901,7 @@ static void print_conf(conf_t *conf)
tmp = conf->mirrors + i;
if (tmp->rdev)
printk(" disk %d, wo:%d, o:%d, dev:%s\n",
- i, !tmp->rdev->in_sync, !tmp->rdev->faulty,
+ i, !test_bit(In_sync, &tmp->rdev->flags), !test_bit(Faulty, &tmp->rdev->flags),
bdevname(tmp->rdev->bdev,b));
}
}
@@ -917,11 +933,11 @@ static int raid1_spare_active(mddev_t *mddev)
for (i = 0; i < conf->raid_disks; i++) {
tmp = conf->mirrors + i;
if (tmp->rdev
- && !tmp->rdev->faulty
- && !tmp->rdev->in_sync) {
+ && !test_bit(Faulty, &tmp->rdev->flags)
+ && !test_bit(In_sync, &tmp->rdev->flags)) {
conf->working_disks++;
mddev->degraded--;
- tmp->rdev->in_sync = 1;
+ set_bit(In_sync, &tmp->rdev->flags);
}
}
@@ -958,7 +974,7 @@ static int raid1_add_disk(mddev_t *mddev, mdk_rdev_t *rdev)
found = 1;
if (rdev->saved_raid_disk != mirror)
conf->fullsync = 1;
- p->rdev = rdev;
+ rcu_assign_pointer(p->rdev, rdev);
break;
}
@@ -976,7 +992,7 @@ static int raid1_remove_disk(mddev_t *mddev, int number)
print_conf(conf);
rdev = p->rdev;
if (rdev) {
- if (rdev->in_sync ||
+ if (test_bit(In_sync, &rdev->flags) ||
atomic_read(&rdev->nr_pending)) {
err = -EBUSY;
goto abort;
@@ -1157,6 +1173,36 @@ static void raid1d(mddev_t *mddev)
if (test_bit(R1BIO_IsSync, &r1_bio->state)) {
sync_request_write(mddev, r1_bio);
unplug = 1;
+ } else if (test_bit(R1BIO_BarrierRetry, &r1_bio->state)) {
+ /* some requests in the r1bio were BIO_RW_BARRIER
+ * requests which failed with -ENOTSUPP. Hohumm..
+ * Better resubmit without the barrier.
+ * We know which devices to resubmit for, because
+ * all others have had their bios[] entry cleared.
+ */
+ int i;
+ clear_bit(R1BIO_BarrierRetry, &r1_bio->state);
+ clear_bit(R1BIO_Barrier, &r1_bio->state);
+ for (i=0; i < conf->raid_disks; i++)
+ if (r1_bio->bios[i]) {
+ struct bio_vec *bvec;
+ int j;
+
+ bio = bio_clone(r1_bio->master_bio, GFP_NOIO);
+ /* copy pages from the failed bio, as
+ * this might be a write-behind device */
+ __bio_for_each_segment(bvec, bio, j, 0)
+ bvec->bv_page = bio_iovec_idx(r1_bio->bios[i], j)->bv_page;
+ bio_put(r1_bio->bios[i]);
+ bio->bi_sector = r1_bio->sector +
+ conf->mirrors[i].rdev->data_offset;
+ bio->bi_bdev = conf->mirrors[i].rdev->bdev;
+ bio->bi_end_io = raid1_end_write_request;
+ bio->bi_rw = WRITE;
+ bio->bi_private = r1_bio;
+ r1_bio->bios[i] = bio;
+ generic_make_request(bio);
+ }
} else {
int disk;
bio = r1_bio->bios[r1_bio->read_disk];
@@ -1264,7 +1310,7 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
* This call the bitmap_start_sync doesn't actually record anything
*/
if (!bitmap_start_sync(mddev->bitmap, sector_nr, &sync_blocks, 1) &&
- !conf->fullsync) {
+ !conf->fullsync && !test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery)) {
/* We can skip this block, and probably several more */
*skipped = 1;
return sync_blocks;
@@ -1286,11 +1332,11 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
/* make sure disk is operational */
wonly = disk;
while (conf->mirrors[disk].rdev == NULL ||
- !conf->mirrors[disk].rdev->in_sync ||
+ !test_bit(In_sync, &conf->mirrors[disk].rdev->flags) ||
test_bit(WriteMostly, &conf->mirrors[disk].rdev->flags)
) {
if (conf->mirrors[disk].rdev &&
- conf->mirrors[disk].rdev->in_sync)
+ test_bit(In_sync, &conf->mirrors[disk].rdev->flags))
wonly = disk;
if (disk <= 0)
disk = conf->raid_disks;
@@ -1337,11 +1383,12 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
bio->bi_rw = READ;
bio->bi_end_io = end_sync_read;
} else if (conf->mirrors[i].rdev == NULL ||
- conf->mirrors[i].rdev->faulty) {
+ test_bit(Faulty, &conf->mirrors[i].rdev->flags)) {
still_degraded = 1;
continue;
- } else if (!conf->mirrors[i].rdev->in_sync ||
- sector_nr + RESYNC_SECTORS > mddev->recovery_cp) {
+ } else if (!test_bit(In_sync, &conf->mirrors[i].rdev->flags) ||
+ sector_nr + RESYNC_SECTORS > mddev->recovery_cp ||
+ test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery)) {
bio->bi_rw = WRITE;
bio->bi_end_io = end_sync_write;
write_targets ++;
@@ -1375,8 +1422,9 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
break;
if (sync_blocks == 0) {
if (!bitmap_start_sync(mddev->bitmap, sector_nr,
- &sync_blocks, still_degraded) &&
- !conf->fullsync)
+ &sync_blocks, still_degraded) &&
+ !conf->fullsync &&
+ !test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery))
break;
if (sync_blocks < (PAGE_SIZE>>9))
BUG();
@@ -1482,7 +1530,7 @@ static int run(mddev_t *mddev)
blk_queue_max_sectors(mddev->queue, PAGE_SIZE>>9);
disk->head_position = 0;
- if (!rdev->faulty && rdev->in_sync)
+ if (!test_bit(Faulty, &rdev->flags) && test_bit(In_sync, &rdev->flags))
conf->working_disks++;
}
conf->raid_disks = mddev->raid_disks;
@@ -1522,7 +1570,7 @@ static int run(mddev_t *mddev)
*/
for (j = 0; j < conf->raid_disks &&
(!conf->mirrors[j].rdev ||
- !conf->mirrors[j].rdev->in_sync) ; j++)
+ !test_bit(In_sync, &conf->mirrors[j].rdev->flags)) ; j++)
/* nothing */;
conf->last_used = j;
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index 28dd028415e4..867f06ae33d9 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -496,6 +496,7 @@ static int read_balance(conf_t *conf, r10bio_t *r10_bio)
int disk, slot, nslot;
const int sectors = r10_bio->sectors;
sector_t new_distance, current_distance;
+ mdk_rdev_t *rdev;
raid10_find_phys(conf, r10_bio);
rcu_read_lock();
@@ -510,8 +511,8 @@ static int read_balance(conf_t *conf, r10bio_t *r10_bio)
slot = 0;
disk = r10_bio->devs[slot].devnum;
- while (!conf->mirrors[disk].rdev ||
- !conf->mirrors[disk].rdev->in_sync) {
+ while ((rdev = rcu_dereference(conf->mirrors[disk].rdev)) == NULL ||
+ !test_bit(In_sync, &rdev->flags)) {
slot++;
if (slot == conf->copies) {
slot = 0;
@@ -527,8 +528,8 @@ static int read_balance(conf_t *conf, r10bio_t *r10_bio)
/* make sure the disk is operational */
slot = 0;
disk = r10_bio->devs[slot].devnum;
- while (!conf->mirrors[disk].rdev ||
- !conf->mirrors[disk].rdev->in_sync) {
+ while ((rdev=rcu_dereference(conf->mirrors[disk].rdev)) == NULL ||
+ !test_bit(In_sync, &rdev->flags)) {
slot ++;
if (slot == conf->copies) {
disk = -1;
@@ -547,11 +548,11 @@ static int read_balance(conf_t *conf, r10bio_t *r10_bio)
int ndisk = r10_bio->devs[nslot].devnum;
- if (!conf->mirrors[ndisk].rdev ||
- !conf->mirrors[ndisk].rdev->in_sync)
+ if ((rdev=rcu_dereference(conf->mirrors[ndisk].rdev)) == NULL ||
+ !test_bit(In_sync, &rdev->flags))
continue;
- if (!atomic_read(&conf->mirrors[ndisk].rdev->nr_pending)) {
+ if (!atomic_read(&rdev->nr_pending)) {
disk = ndisk;
slot = nslot;
break;
@@ -569,7 +570,7 @@ rb_out:
r10_bio->read_slot = slot;
/* conf->next_seq_sect = this_sector + sectors;*/
- if (disk >= 0 && conf->mirrors[disk].rdev)
+ if (disk >= 0 && (rdev=rcu_dereference(conf->mirrors[disk].rdev))!= NULL)
atomic_inc(&conf->mirrors[disk].rdev->nr_pending);
rcu_read_unlock();
@@ -583,8 +584,8 @@ static void unplug_slaves(mddev_t *mddev)
rcu_read_lock();
for (i=0; i<mddev->raid_disks; i++) {
- mdk_rdev_t *rdev = conf->mirrors[i].rdev;
- if (rdev && !rdev->faulty && atomic_read(&rdev->nr_pending)) {
+ mdk_rdev_t *rdev = rcu_dereference(conf->mirrors[i].rdev);
+ if (rdev && !test_bit(Faulty, &rdev->flags) && atomic_read(&rdev->nr_pending)) {
request_queue_t *r_queue = bdev_get_queue(rdev->bdev);
atomic_inc(&rdev->nr_pending);
@@ -614,8 +615,8 @@ static int raid10_issue_flush(request_queue_t *q, struct gendisk *disk,
rcu_read_lock();
for (i=0; i<mddev->raid_disks && ret == 0; i++) {
- mdk_rdev_t *rdev = conf->mirrors[i].rdev;
- if (rdev && !rdev->faulty) {
+ mdk_rdev_t *rdev = rcu_dereference(conf->mirrors[i].rdev);
+ if (rdev && !test_bit(Faulty, &rdev->flags)) {
struct block_device *bdev = rdev->bdev;
request_queue_t *r_queue = bdev_get_queue(bdev);
@@ -668,6 +669,7 @@ static int make_request(request_queue_t *q, struct bio * bio)
struct bio *read_bio;
int i;
int chunk_sects = conf->chunk_mask + 1;
+ const int rw = bio_data_dir(bio);
if (unlikely(bio_barrier(bio))) {
bio_endio(bio, bio->bi_size, -EOPNOTSUPP);
@@ -718,13 +720,8 @@ static int make_request(request_queue_t *q, struct bio * bio)
conf->nr_pending++;
spin_unlock_irq(&conf->resync_lock);
- if (bio_data_dir(bio)==WRITE) {
- disk_stat_inc(mddev->gendisk, writes);
- disk_stat_add(mddev->gendisk, write_sectors, bio_sectors(bio));
- } else {
- disk_stat_inc(mddev->gendisk, reads);
- disk_stat_add(mddev->gendisk, read_sectors, bio_sectors(bio));
- }
+ disk_stat_inc(mddev->gendisk, ios[rw]);
+ disk_stat_add(mddev->gendisk, sectors[rw], bio_sectors(bio));
r10_bio = mempool_alloc(conf->r10bio_pool, GFP_NOIO);
@@ -734,7 +731,7 @@ static int make_request(request_queue_t *q, struct bio * bio)
r10_bio->mddev = mddev;
r10_bio->sector = bio->bi_sector;
- if (bio_data_dir(bio) == READ) {
+ if (rw == READ) {
/*
* read balancing logic:
*/
@@ -772,9 +769,10 @@ static int make_request(request_queue_t *q, struct bio * bio)
rcu_read_lock();
for (i = 0; i < conf->copies; i++) {
int d = r10_bio->devs[i].devnum;
- if (conf->mirrors[d].rdev &&
- !conf->mirrors[d].rdev->faulty) {
- atomic_inc(&conf->mirrors[d].rdev->nr_pending);
+ mdk_rdev_t *rdev = rcu_dereference(conf->mirrors[d].rdev);
+ if (rdev &&
+ !test_bit(Faulty, &rdev->flags)) {
+ atomic_inc(&rdev->nr_pending);
r10_bio->devs[i].bio = bio;
} else
r10_bio->devs[i].bio = NULL;
@@ -828,7 +826,7 @@ static void status(struct seq_file *seq, mddev_t *mddev)
for (i = 0; i < conf->raid_disks; i++)
seq_printf(seq, "%s",
conf->mirrors[i].rdev &&
- conf->mirrors[i].rdev->in_sync ? "U" : "_");
+ test_bit(In_sync, &conf->mirrors[i].rdev->flags) ? "U" : "_");
seq_printf(seq, "]");
}
@@ -843,7 +841,7 @@ static void error(mddev_t *mddev, mdk_rdev_t *rdev)
* next level up know.
* else mark the drive as failed
*/
- if (rdev->in_sync
+ if (test_bit(In_sync, &rdev->flags)
&& conf->working_disks == 1)
/*
* Don't fail the drive, just return an IO error.
@@ -853,7 +851,7 @@ static void error(mddev_t *mddev, mdk_rdev_t *rdev)
* really dead" tests...
*/
return;
- if (rdev->in_sync) {
+ if (test_bit(In_sync, &rdev->flags)) {
mddev->degraded++;
conf->working_disks--;
/*
@@ -861,8 +859,8 @@ static void error(mddev_t *mddev, mdk_rdev_t *rdev)
*/
set_bit(MD_RECOVERY_ERR, &mddev->recovery);
}
- rdev->in_sync = 0;
- rdev->faulty = 1;
+ clear_bit(In_sync, &rdev->flags);
+ set_bit(Faulty, &rdev->flags);
mddev->sb_dirty = 1;
printk(KERN_ALERT "raid10: Disk failure on %s, disabling device. \n"
" Operation continuing on %d devices\n",
@@ -887,7 +885,8 @@ static void print_conf(conf_t *conf)
tmp = conf->mirrors + i;
if (tmp->rdev)
printk(" disk %d, wo:%d, o:%d, dev:%s\n",
- i, !tmp->rdev->in_sync, !tmp->rdev->faulty,
+ i, !test_bit(In_sync, &tmp->rdev->flags),
+ !test_bit(Faulty, &tmp->rdev->flags),
bdevname(tmp->rdev->bdev,b));
}
}
@@ -940,11 +939,11 @@ static int raid10_spare_active(mddev_t *mddev)
for (i = 0; i < conf->raid_disks; i++) {
tmp = conf->mirrors + i;
if (tmp->rdev
- && !tmp->rdev->faulty
- && !tmp->rdev->in_sync) {
+ && !test_bit(Faulty, &tmp->rdev->flags)
+ && !test_bit(In_sync, &tmp->rdev->flags)) {
conf->working_disks++;
mddev->degraded--;
- tmp->rdev->in_sync = 1;
+ set_bit(In_sync, &tmp->rdev->flags);
}
}
@@ -984,7 +983,7 @@ static int raid10_add_disk(mddev_t *mddev, mdk_rdev_t *rdev)
p->head_position = 0;
rdev->raid_disk = mirror;
found = 1;
- p->rdev = rdev;
+ rcu_assign_pointer(p->rdev, rdev);
break;
}
@@ -1002,7 +1001,7 @@ static int raid10_remove_disk(mddev_t *mddev, int number)
print_conf(conf);
rdev = p->rdev;
if (rdev) {
- if (rdev->in_sync ||
+ if (test_bit(In_sync, &rdev->flags) ||
atomic_read(&rdev->nr_pending)) {
err = -EBUSY;
goto abort;
@@ -1418,7 +1417,7 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
for (i=0 ; i<conf->raid_disks; i++)
if (conf->mirrors[i].rdev &&
- !conf->mirrors[i].rdev->in_sync) {
+ !test_bit(In_sync, &conf->mirrors[i].rdev->flags)) {
/* want to reconstruct this device */
r10bio_t *rb2 = r10_bio;
@@ -1439,7 +1438,7 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
for (j=0; j<conf->copies;j++) {
int d = r10_bio->devs[j].devnum;
if (conf->mirrors[d].rdev &&
- conf->mirrors[d].rdev->in_sync) {
+ test_bit(In_sync, &conf->mirrors[d].rdev->flags)) {
/* This is where we read from */
bio = r10_bio->devs[0].bio;
bio->bi_next = biolist;
@@ -1515,7 +1514,7 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
bio = r10_bio->devs[i].bio;
bio->bi_end_io = NULL;
if (conf->mirrors[d].rdev == NULL ||
- conf->mirrors[d].rdev->faulty)
+ test_bit(Faulty, &conf->mirrors[d].rdev->flags))
continue;
atomic_inc(&conf->mirrors[d].rdev->nr_pending);
atomic_inc(&r10_bio->remaining);
@@ -1701,7 +1700,7 @@ static int run(mddev_t *mddev)
mddev->queue->max_sectors = (PAGE_SIZE>>9);
disk->head_position = 0;
- if (!rdev->faulty && rdev->in_sync)
+ if (!test_bit(Faulty, &rdev->flags) && test_bit(In_sync, &rdev->flags))
conf->working_disks++;
}
conf->raid_disks = mddev->raid_disks;
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index 4683ca24c046..e2a40283e323 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -293,9 +293,31 @@ static struct stripe_head *get_active_stripe(raid5_conf_t *conf, sector_t sector
return sh;
}
-static int grow_stripes(raid5_conf_t *conf, int num)
+static int grow_one_stripe(raid5_conf_t *conf)
{
struct stripe_head *sh;
+ sh = kmem_cache_alloc(conf->slab_cache, GFP_KERNEL);
+ if (!sh)
+ return 0;
+ memset(sh, 0, sizeof(*sh) + (conf->raid_disks-1)*sizeof(struct r5dev));
+ sh->raid_conf = conf;
+ spin_lock_init(&sh->lock);
+
+ if (grow_buffers(sh, conf->raid_disks)) {
+ shrink_buffers(sh, conf->raid_disks);
+ kmem_cache_free(conf->slab_cache, sh);
+ return 0;
+ }
+ /* we just created an active stripe so... */
+ atomic_set(&sh->count, 1);
+ atomic_inc(&conf->active_stripes);
+ INIT_LIST_HEAD(&sh->lru);
+ release_stripe(sh);
+ return 1;
+}
+
+static int grow_stripes(raid5_conf_t *conf, int num)
+{
kmem_cache_t *sc;
int devs = conf->raid_disks;
@@ -308,48 +330,39 @@ static int grow_stripes(raid5_conf_t *conf, int num)
return 1;
conf->slab_cache = sc;
while (num--) {
- sh = kmem_cache_alloc(sc, GFP_KERNEL);
- if (!sh)
+ if (!grow_one_stripe(conf))
return 1;
- memset(sh, 0, sizeof(*sh) + (devs-1)*sizeof(struct r5dev));
- sh->raid_conf = conf;
- spin_lock_init(&sh->lock);
-
- if (grow_buffers(sh, conf->raid_disks)) {
- shrink_buffers(sh, conf->raid_disks);
- kmem_cache_free(sc, sh);
- return 1;
- }
- /* we just created an active stripe so... */
- atomic_set(&sh->count, 1);
- atomic_inc(&conf->active_stripes);
- INIT_LIST_HEAD(&sh->lru);
- release_stripe(sh);
}
return 0;
}
-static void shrink_stripes(raid5_conf_t *conf)
+static int drop_one_stripe(raid5_conf_t *conf)
{
struct stripe_head *sh;
- while (1) {
- spin_lock_irq(&conf->device_lock);
- sh = get_free_stripe(conf);
- spin_unlock_irq(&conf->device_lock);
- if (!sh)
- break;
- if (atomic_read(&sh->count))
- BUG();
- shrink_buffers(sh, conf->raid_disks);
- kmem_cache_free(conf->slab_cache, sh);
- atomic_dec(&conf->active_stripes);
- }
+ spin_lock_irq(&conf->device_lock);
+ sh = get_free_stripe(conf);
+ spin_unlock_irq(&conf->device_lock);
+ if (!sh)
+ return 0;
+ if (atomic_read(&sh->count))
+ BUG();
+ shrink_buffers(sh, conf->raid_disks);
+ kmem_cache_free(conf->slab_cache, sh);
+ atomic_dec(&conf->active_stripes);
+ return 1;
+}
+
+static void shrink_stripes(raid5_conf_t *conf)
+{
+ while (drop_one_stripe(conf))
+ ;
+
kmem_cache_destroy(conf->slab_cache);
conf->slab_cache = NULL;
}
-static int raid5_end_read_request (struct bio * bi, unsigned int bytes_done,
+static int raid5_end_read_request(struct bio * bi, unsigned int bytes_done,
int error)
{
struct stripe_head *sh = bi->bi_private;
@@ -401,10 +414,35 @@ static int raid5_end_read_request (struct bio * bi, unsigned int bytes_done,
}
#else
set_bit(R5_UPTODATE, &sh->dev[i].flags);
-#endif
+#endif
+ if (test_bit(R5_ReadError, &sh->dev[i].flags)) {
+ printk("R5: read error corrected!!\n");
+ clear_bit(R5_ReadError, &sh->dev[i].flags);
+ clear_bit(R5_ReWrite, &sh->dev[i].flags);
+ }
+ if (atomic_read(&conf->disks[i].rdev->read_errors))
+ atomic_set(&conf->disks[i].rdev->read_errors, 0);
} else {
- md_error(conf->mddev, conf->disks[i].rdev);
+ int retry = 0;
clear_bit(R5_UPTODATE, &sh->dev[i].flags);
+ atomic_inc(&conf->disks[i].rdev->read_errors);
+ if (conf->mddev->degraded)
+ printk("R5: read error not correctable.\n");
+ else if (test_bit(R5_ReWrite, &sh->dev[i].flags))
+ /* Oh, no!!! */
+ printk("R5: read error NOT corrected!!\n");
+ else if (atomic_read(&conf->disks[i].rdev->read_errors)
+ > conf->max_nr_stripes)
+ printk("raid5: Too many read errors, failing device.\n");
+ else
+ retry = 1;
+ if (retry)
+ set_bit(R5_ReadError, &sh->dev[i].flags);
+ else {
+ clear_bit(R5_ReadError, &sh->dev[i].flags);
+ clear_bit(R5_ReWrite, &sh->dev[i].flags);
+ md_error(conf->mddev, conf->disks[i].rdev);
+ }
}
rdev_dec_pending(conf->disks[i].rdev, conf->mddev);
#if 0
@@ -487,19 +525,19 @@ static void error(mddev_t *mddev, mdk_rdev_t *rdev)
raid5_conf_t *conf = (raid5_conf_t *) mddev->private;
PRINTK("raid5: error called\n");
- if (!rdev->faulty) {
+ if (!test_bit(Faulty, &rdev->flags)) {
mddev->sb_dirty = 1;
- if (rdev->in_sync) {
+ if (test_bit(In_sync, &rdev->flags)) {
conf->working_disks--;
mddev->degraded++;
conf->failed_disks++;
- rdev->in_sync = 0;
+ clear_bit(In_sync, &rdev->flags);
/*
* if recovery was running, make sure it aborts.
*/
set_bit(MD_RECOVERY_ERR, &mddev->recovery);
}
- rdev->faulty = 1;
+ set_bit(Faulty, &rdev->flags);
printk (KERN_ALERT
"raid5: Disk failure on %s, disabling device."
" Operation continuing on %d devices\n",
@@ -965,7 +1003,13 @@ static void handle_stripe(struct stripe_head *sh)
}
if (dev->written) written++;
rdev = conf->disks[i].rdev; /* FIXME, should I be looking rdev */
- if (!rdev || !rdev->in_sync) {
+ if (!rdev || !test_bit(In_sync, &rdev->flags)) {
+ /* The ReadError flag wil just be confusing now */
+ clear_bit(R5_ReadError, &dev->flags);
+ clear_bit(R5_ReWrite, &dev->flags);
+ }
+ if (!rdev || !test_bit(In_sync, &rdev->flags)
+ || test_bit(R5_ReadError, &dev->flags)) {
failed++;
failed_num = i;
} else
@@ -980,6 +1024,14 @@ static void handle_stripe(struct stripe_head *sh)
if (failed > 1 && to_read+to_write+written) {
for (i=disks; i--; ) {
int bitmap_end = 0;
+
+ if (test_bit(R5_ReadError, &sh->dev[i].flags)) {
+ mdk_rdev_t *rdev = conf->disks[i].rdev;
+ if (rdev && test_bit(In_sync, &rdev->flags))
+ /* multiple read failures in one stripe */
+ md_error(conf->mddev, rdev);
+ }
+
spin_lock_irq(&conf->device_lock);
/* fail all writes first */
bi = sh->dev[i].towrite;
@@ -1015,7 +1067,8 @@ static void handle_stripe(struct stripe_head *sh)
}
/* fail any reads if this device is non-operational */
- if (!test_bit(R5_Insync, &sh->dev[i].flags)) {
+ if (!test_bit(R5_Insync, &sh->dev[i].flags) ||
+ test_bit(R5_ReadError, &sh->dev[i].flags)) {
bi = sh->dev[i].toread;
sh->dev[i].toread = NULL;
if (test_and_clear_bit(R5_Overlap, &sh->dev[i].flags))
@@ -1247,6 +1300,11 @@ static void handle_stripe(struct stripe_head *sh)
!memcmp(pagea, pagea+4, STRIPE_SIZE-4)) {
/* parity is correct (on disc, not in buffer any more) */
set_bit(STRIPE_INSYNC, &sh->state);
+ } else {
+ conf->mddev->resync_mismatches += STRIPE_SECTORS;
+ if (test_bit(MD_RECOVERY_CHECK, &conf->mddev->recovery))
+ /* don't try to repair!! */
+ set_bit(STRIPE_INSYNC, &sh->state);
}
}
if (!test_bit(STRIPE_INSYNC, &sh->state)) {
@@ -1274,7 +1332,27 @@ static void handle_stripe(struct stripe_head *sh)
md_done_sync(conf->mddev, STRIPE_SECTORS,1);
clear_bit(STRIPE_SYNCING, &sh->state);
}
-
+
+ /* If the failed drive is just a ReadError, then we might need to progress
+ * the repair/check process
+ */
+ if (failed == 1 && ! conf->mddev->ro &&
+ test_bit(R5_ReadError, &sh->dev[failed_num].flags)
+ && !test_bit(R5_LOCKED, &sh->dev[failed_num].flags)
+ && test_bit(R5_UPTODATE, &sh->dev[failed_num].flags)
+ ) {
+ dev = &sh->dev[failed_num];
+ if (!test_bit(R5_ReWrite, &dev->flags)) {
+ set_bit(R5_Wantwrite, &dev->flags);
+ set_bit(R5_ReWrite, &dev->flags);
+ set_bit(R5_LOCKED, &dev->flags);
+ } else {
+ /* let's read it back */
+ set_bit(R5_Wantread, &dev->flags);
+ set_bit(R5_LOCKED, &dev->flags);
+ }
+ }
+
spin_unlock(&sh->lock);
while ((bi=return_bi)) {
@@ -1305,8 +1383,8 @@ static void handle_stripe(struct stripe_head *sh)
bi->bi_end_io = raid5_end_read_request;
rcu_read_lock();
- rdev = conf->disks[i].rdev;
- if (rdev && rdev->faulty)
+ rdev = rcu_dereference(conf->disks[i].rdev);
+ if (rdev && test_bit(Faulty, &rdev->flags))
rdev = NULL;
if (rdev)
atomic_inc(&rdev->nr_pending);
@@ -1379,8 +1457,8 @@ static void unplug_slaves(mddev_t *mddev)
rcu_read_lock();
for (i=0; i<mddev->raid_disks; i++) {
- mdk_rdev_t *rdev = conf->disks[i].rdev;
- if (rdev && !rdev->faulty && atomic_read(&rdev->nr_pending)) {
+ mdk_rdev_t *rdev = rcu_dereference(conf->disks[i].rdev);
+ if (rdev && !test_bit(Faulty, &rdev->flags) && atomic_read(&rdev->nr_pending)) {
request_queue_t *r_queue = bdev_get_queue(rdev->bdev);
atomic_inc(&rdev->nr_pending);
@@ -1424,8 +1502,8 @@ static int raid5_issue_flush(request_queue_t *q, struct gendisk *disk,
rcu_read_lock();
for (i=0; i<mddev->raid_disks && ret == 0; i++) {
- mdk_rdev_t *rdev = conf->disks[i].rdev;
- if (rdev && !rdev->faulty) {
+ mdk_rdev_t *rdev = rcu_dereference(conf->disks[i].rdev);
+ if (rdev && !test_bit(Faulty, &rdev->flags)) {
struct block_device *bdev = rdev->bdev;
request_queue_t *r_queue = bdev_get_queue(bdev);
@@ -1462,6 +1540,7 @@ static int make_request (request_queue_t *q, struct bio * bi)
sector_t new_sector;
sector_t logical_sector, last_sector;
struct stripe_head *sh;
+ const int rw = bio_data_dir(bi);
if (unlikely(bio_barrier(bi))) {
bio_endio(bi, bi->bi_size, -EOPNOTSUPP);
@@ -1470,13 +1549,8 @@ static int make_request (request_queue_t *q, struct bio * bi)
md_write_start(mddev, bi);
- if (bio_data_dir(bi)==WRITE) {
- disk_stat_inc(mddev->gendisk, writes);
- disk_stat_add(mddev->gendisk, write_sectors, bio_sectors(bi));
- } else {
- disk_stat_inc(mddev->gendisk, reads);
- disk_stat_add(mddev->gendisk, read_sectors, bio_sectors(bi));
- }
+ disk_stat_inc(mddev->gendisk, ios[rw]);
+ disk_stat_add(mddev->gendisk, sectors[rw], bio_sectors(bi));
logical_sector = bi->bi_sector & ~((sector_t)STRIPE_SECTORS-1);
last_sector = bi->bi_sector + (bi->bi_size>>9);
@@ -1571,6 +1645,7 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
return rv;
}
if (!bitmap_start_sync(mddev->bitmap, sector_nr, &sync_blocks, 1) &&
+ !test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery) &&
!conf->fullsync && sync_blocks >= STRIPE_SECTORS) {
/* we can skip this block, and probably more */
sync_blocks /= STRIPE_SECTORS;
@@ -1591,8 +1666,7 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
/* make sure we don't swamp the stripe cache if someone else
* is trying to get access
*/
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(1);
+ schedule_timeout_uninterruptible(1);
}
bitmap_start_sync(mddev->bitmap, sector_nr, &sync_blocks, 0);
spin_lock(&sh->lock);
@@ -1668,6 +1742,74 @@ static void raid5d (mddev_t *mddev)
PRINTK("--- raid5d inactive\n");
}
+static ssize_t
+raid5_show_stripe_cache_size(mddev_t *mddev, char *page)
+{
+ raid5_conf_t *conf = mddev_to_conf(mddev);
+ if (conf)
+ return sprintf(page, "%d\n", conf->max_nr_stripes);
+ else
+ return 0;
+}
+
+static ssize_t
+raid5_store_stripe_cache_size(mddev_t *mddev, const char *page, size_t len)
+{
+ raid5_conf_t *conf = mddev_to_conf(mddev);
+ char *end;
+ int new;
+ if (len >= PAGE_SIZE)
+ return -EINVAL;
+ if (!conf)
+ return -ENODEV;
+
+ new = simple_strtoul(page, &end, 10);
+ if (!*page || (*end && *end != '\n') )
+ return -EINVAL;
+ if (new <= 16 || new > 32768)
+ return -EINVAL;
+ while (new < conf->max_nr_stripes) {
+ if (drop_one_stripe(conf))
+ conf->max_nr_stripes--;
+ else
+ break;
+ }
+ while (new > conf->max_nr_stripes) {
+ if (grow_one_stripe(conf))
+ conf->max_nr_stripes++;
+ else break;
+ }
+ return len;
+}
+
+static struct md_sysfs_entry
+raid5_stripecache_size = __ATTR(stripe_cache_size, S_IRUGO | S_IWUSR,
+ raid5_show_stripe_cache_size,
+ raid5_store_stripe_cache_size);
+
+static ssize_t
+stripe_cache_active_show(mddev_t *mddev, char *page)
+{
+ raid5_conf_t *conf = mddev_to_conf(mddev);
+ if (conf)
+ return sprintf(page, "%d\n", atomic_read(&conf->active_stripes));
+ else
+ return 0;
+}
+
+static struct md_sysfs_entry
+raid5_stripecache_active = __ATTR_RO(stripe_cache_active);
+
+static struct attribute *raid5_attrs[] = {
+ &raid5_stripecache_size.attr,
+ &raid5_stripecache_active.attr,
+ NULL,
+};
+static struct attribute_group raid5_attrs_group = {
+ .name = NULL,
+ .attrs = raid5_attrs,
+};
+
static int run(mddev_t *mddev)
{
raid5_conf_t *conf;
@@ -1714,7 +1856,7 @@ static int run(mddev_t *mddev)
disk->rdev = rdev;
- if (rdev->in_sync) {
+ if (test_bit(In_sync, &rdev->flags)) {
char b[BDEVNAME_SIZE];
printk(KERN_INFO "raid5: device %s operational as raid"
" disk %d\n", bdevname(rdev->bdev,b),
@@ -1809,6 +1951,7 @@ memory = conf->max_nr_stripes * (sizeof(struct stripe_head) +
}
/* Ok, everything is just fine now */
+ sysfs_create_group(&mddev->kobj, &raid5_attrs_group);
if (mddev->bitmap)
mddev->thread->timeout = mddev->bitmap->daemon_sleep * HZ;
@@ -1833,7 +1976,7 @@ abort:
-static int stop (mddev_t *mddev)
+static int stop(mddev_t *mddev)
{
raid5_conf_t *conf = (raid5_conf_t *) mddev->private;
@@ -1842,6 +1985,7 @@ static int stop (mddev_t *mddev)
shrink_stripes(conf);
free_pages((unsigned long) conf->stripe_hashtbl, HASH_PAGES_ORDER);
blk_sync_queue(mddev->queue); /* the unplug fn references 'conf'*/
+ sysfs_remove_group(&mddev->kobj, &raid5_attrs_group);
kfree(conf);
mddev->private = NULL;
return 0;
@@ -1892,7 +2036,7 @@ static void status (struct seq_file *seq, mddev_t *mddev)
for (i = 0; i < conf->raid_disks; i++)
seq_printf (seq, "%s",
conf->disks[i].rdev &&
- conf->disks[i].rdev->in_sync ? "U" : "_");
+ test_bit(In_sync, &conf->disks[i].rdev->flags) ? "U" : "_");
seq_printf (seq, "]");
#if RAID5_DEBUG
#define D(x) \
@@ -1919,7 +2063,7 @@ static void print_raid5_conf (raid5_conf_t *conf)
tmp = conf->disks + i;
if (tmp->rdev)
printk(" disk %d, o:%d, dev:%s\n",
- i, !tmp->rdev->faulty,
+ i, !test_bit(Faulty, &tmp->rdev->flags),
bdevname(tmp->rdev->bdev,b));
}
}
@@ -1933,12 +2077,12 @@ static int raid5_spare_active(mddev_t *mddev)
for (i = 0; i < conf->raid_disks; i++) {
tmp = conf->disks + i;
if (tmp->rdev
- && !tmp->rdev->faulty
- && !tmp->rdev->in_sync) {
+ && !test_bit(Faulty, &tmp->rdev->flags)
+ && !test_bit(In_sync, &tmp->rdev->flags)) {
mddev->degraded--;
conf->failed_disks--;
conf->working_disks++;
- tmp->rdev->in_sync = 1;
+ set_bit(In_sync, &tmp->rdev->flags);
}
}
print_raid5_conf(conf);
@@ -1955,7 +2099,7 @@ static int raid5_remove_disk(mddev_t *mddev, int number)
print_raid5_conf(conf);
rdev = p->rdev;
if (rdev) {
- if (rdev->in_sync ||
+ if (test_bit(In_sync, &rdev->flags) ||
atomic_read(&rdev->nr_pending)) {
err = -EBUSY;
goto abort;
@@ -1990,12 +2134,12 @@ static int raid5_add_disk(mddev_t *mddev, mdk_rdev_t *rdev)
*/
for (disk=0; disk < mddev->raid_disks; disk++)
if ((p=conf->disks + disk)->rdev == NULL) {
- rdev->in_sync = 0;
+ clear_bit(In_sync, &rdev->flags);
rdev->raid_disk = disk;
found = 1;
if (rdev->saved_raid_disk != disk)
conf->fullsync = 1;
- p->rdev = rdev;
+ rcu_assign_pointer(p->rdev, rdev);
break;
}
print_raid5_conf(conf);
diff --git a/drivers/md/raid6main.c b/drivers/md/raid6main.c
index 267eb1430c83..eae5a35629c5 100644
--- a/drivers/md/raid6main.c
+++ b/drivers/md/raid6main.c
@@ -507,19 +507,19 @@ static void error(mddev_t *mddev, mdk_rdev_t *rdev)
raid6_conf_t *conf = (raid6_conf_t *) mddev->private;
PRINTK("raid6: error called\n");
- if (!rdev->faulty) {
+ if (!test_bit(Faulty, &rdev->flags)) {
mddev->sb_dirty = 1;
- if (rdev->in_sync) {
+ if (test_bit(In_sync, &rdev->flags)) {
conf->working_disks--;
mddev->degraded++;
conf->failed_disks++;
- rdev->in_sync = 0;
+ clear_bit(In_sync, &rdev->flags);
/*
* if recovery was running, make sure it aborts.
*/
set_bit(MD_RECOVERY_ERR, &mddev->recovery);
}
- rdev->faulty = 1;
+ set_bit(Faulty, &rdev->flags);
printk (KERN_ALERT
"raid6: Disk failure on %s, disabling device."
" Operation continuing on %d devices\n",
@@ -1071,7 +1071,7 @@ static void handle_stripe(struct stripe_head *sh)
}
if (dev->written) written++;
rdev = conf->disks[i].rdev; /* FIXME, should I be looking rdev */
- if (!rdev || !rdev->in_sync) {
+ if (!rdev || !test_bit(In_sync, &rdev->flags)) {
if ( failed < 2 )
failed_num[failed] = i;
failed++;
@@ -1464,8 +1464,8 @@ static void handle_stripe(struct stripe_head *sh)
bi->bi_end_io = raid6_end_read_request;
rcu_read_lock();
- rdev = conf->disks[i].rdev;
- if (rdev && rdev->faulty)
+ rdev = rcu_dereference(conf->disks[i].rdev);
+ if (rdev && test_bit(Faulty, &rdev->flags))
rdev = NULL;
if (rdev)
atomic_inc(&rdev->nr_pending);
@@ -1538,8 +1538,8 @@ static void unplug_slaves(mddev_t *mddev)
rcu_read_lock();
for (i=0; i<mddev->raid_disks; i++) {
- mdk_rdev_t *rdev = conf->disks[i].rdev;
- if (rdev && !rdev->faulty && atomic_read(&rdev->nr_pending)) {
+ mdk_rdev_t *rdev = rcu_dereference(conf->disks[i].rdev);
+ if (rdev && !test_bit(Faulty, &rdev->flags) && atomic_read(&rdev->nr_pending)) {
request_queue_t *r_queue = bdev_get_queue(rdev->bdev);
atomic_inc(&rdev->nr_pending);
@@ -1583,8 +1583,8 @@ static int raid6_issue_flush(request_queue_t *q, struct gendisk *disk,
rcu_read_lock();
for (i=0; i<mddev->raid_disks && ret == 0; i++) {
- mdk_rdev_t *rdev = conf->disks[i].rdev;
- if (rdev && !rdev->faulty) {
+ mdk_rdev_t *rdev = rcu_dereference(conf->disks[i].rdev);
+ if (rdev && !test_bit(Faulty, &rdev->flags)) {
struct block_device *bdev = rdev->bdev;
request_queue_t *r_queue = bdev_get_queue(bdev);
@@ -1621,6 +1621,7 @@ static int make_request (request_queue_t *q, struct bio * bi)
sector_t new_sector;
sector_t logical_sector, last_sector;
struct stripe_head *sh;
+ const int rw = bio_data_dir(bi);
if (unlikely(bio_barrier(bi))) {
bio_endio(bi, bi->bi_size, -EOPNOTSUPP);
@@ -1629,13 +1630,8 @@ static int make_request (request_queue_t *q, struct bio * bi)
md_write_start(mddev, bi);
- if (bio_data_dir(bi)==WRITE) {
- disk_stat_inc(mddev->gendisk, writes);
- disk_stat_add(mddev->gendisk, write_sectors, bio_sectors(bi));
- } else {
- disk_stat_inc(mddev->gendisk, reads);
- disk_stat_add(mddev->gendisk, read_sectors, bio_sectors(bi));
- }
+ disk_stat_inc(mddev->gendisk, ios[rw]);
+ disk_stat_add(mddev->gendisk, sectors[rw], bio_sectors(bi));
logical_sector = bi->bi_sector & ~((sector_t)STRIPE_SECTORS-1);
last_sector = bi->bi_sector + (bi->bi_size>>9);
@@ -1682,7 +1678,7 @@ static int make_request (request_queue_t *q, struct bio * bi)
if (--bi->bi_phys_segments == 0) {
int bytes = bi->bi_size;
- if ( bio_data_dir(bi) == WRITE )
+ if (rw == WRITE )
md_write_end(mddev);
bi->bi_size = 0;
bi->bi_end_io(bi, bytes, 0);
@@ -1750,8 +1746,7 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
/* make sure we don't swamp the stripe cache if someone else
* is trying to get access
*/
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(1);
+ schedule_timeout_uninterruptible(1);
}
bitmap_start_sync(mddev->bitmap, sector_nr, &sync_blocks, 0);
spin_lock(&sh->lock);
@@ -1873,7 +1868,7 @@ static int run(mddev_t *mddev)
disk->rdev = rdev;
- if (rdev->in_sync) {
+ if (test_bit(In_sync, &rdev->flags)) {
char b[BDEVNAME_SIZE];
printk(KERN_INFO "raid6: device %s operational as raid"
" disk %d\n", bdevname(rdev->bdev,b),
@@ -2057,7 +2052,7 @@ static void status (struct seq_file *seq, mddev_t *mddev)
for (i = 0; i < conf->raid_disks; i++)
seq_printf (seq, "%s",
conf->disks[i].rdev &&
- conf->disks[i].rdev->in_sync ? "U" : "_");
+ test_bit(In_sync, &conf->disks[i].rdev->flags) ? "U" : "_");
seq_printf (seq, "]");
#if RAID6_DUMPSTATE
seq_printf (seq, "\n");
@@ -2083,7 +2078,7 @@ static void print_raid6_conf (raid6_conf_t *conf)
tmp = conf->disks + i;
if (tmp->rdev)
printk(" disk %d, o:%d, dev:%s\n",
- i, !tmp->rdev->faulty,
+ i, !test_bit(Faulty, &tmp->rdev->flags),
bdevname(tmp->rdev->bdev,b));
}
}
@@ -2097,12 +2092,12 @@ static int raid6_spare_active(mddev_t *mddev)
for (i = 0; i < conf->raid_disks; i++) {
tmp = conf->disks + i;
if (tmp->rdev
- && !tmp->rdev->faulty
- && !tmp->rdev->in_sync) {
+ && !test_bit(Faulty, &tmp->rdev->flags)
+ && !test_bit(In_sync, &tmp->rdev->flags)) {
mddev->degraded--;
conf->failed_disks--;
conf->working_disks++;
- tmp->rdev->in_sync = 1;
+ set_bit(In_sync, &tmp->rdev->flags);
}
}
print_raid6_conf(conf);
@@ -2119,7 +2114,7 @@ static int raid6_remove_disk(mddev_t *mddev, int number)
print_raid6_conf(conf);
rdev = p->rdev;
if (rdev) {
- if (rdev->in_sync ||
+ if (test_bit(In_sync, &rdev->flags) ||
atomic_read(&rdev->nr_pending)) {
err = -EBUSY;
goto abort;
@@ -2154,12 +2149,12 @@ static int raid6_add_disk(mddev_t *mddev, mdk_rdev_t *rdev)
*/
for (disk=0; disk < mddev->raid_disks; disk++)
if ((p=conf->disks + disk)->rdev == NULL) {
- rdev->in_sync = 0;
+ clear_bit(In_sync, &rdev->flags);
rdev->raid_disk = disk;
found = 1;
if (rdev->saved_raid_disk != disk)
conf->fullsync = 1;
- p->rdev = rdev;
+ rcu_assign_pointer(p->rdev, rdev);
break;
}
print_raid6_conf(conf);
diff --git a/drivers/media/common/ir-common.c b/drivers/media/common/ir-common.c
index a0e700d7a4a4..4b71fd6f7aed 100644
--- a/drivers/media/common/ir-common.c
+++ b/drivers/media/common/ir-common.c
@@ -22,6 +22,7 @@
#include <linux/module.h>
#include <linux/moduleparam.h>
+#include <linux/string.h>
#include <media/ir-common.h>
/* -------------------------------------------------------------------------- */
@@ -115,7 +116,7 @@ IR_KEYTAB_TYPE ir_codes_winfast[IR_KEYTAB_SIZE] = {
[ 46 ] = KEY_BLUE,
[ 24 ] = KEY_KPPLUS, /* fine tune + */
[ 25 ] = KEY_KPMINUS, /* fine tune - */
- [ 33 ] = KEY_KPDOT,
+ [ 33 ] = KEY_KPDOT,
[ 19 ] = KEY_KPENTER,
[ 34 ] = KEY_BACK,
[ 35 ] = KEY_PLAYPAUSE,
@@ -238,7 +239,7 @@ static void ir_input_key_event(struct input_dev *dev, struct ir_input_state *ir)
dprintk(1,"%s: key event code=%d down=%d\n",
dev->name,ir->keycode,ir->keypressed);
input_report_key(dev,ir->keycode,ir->keypressed);
- input_sync(dev);
+ input_sync(dev);
}
/* -------------------------------------------------------------------------- */
@@ -252,7 +253,6 @@ void ir_input_init(struct input_dev *dev, struct ir_input_state *ir,
if (ir_codes)
memcpy(ir->ir_codes, ir_codes, sizeof(ir->ir_codes));
- init_input_dev(dev);
dev->keycode = ir->ir_codes;
dev->keycodesize = sizeof(IR_KEYTAB_TYPE);
dev->keycodemax = IR_KEYTAB_SIZE;
diff --git a/drivers/media/dvb/b2c2/flexcop-fe-tuner.c b/drivers/media/dvb/b2c2/flexcop-fe-tuner.c
index 47e28b0ee951..a35330315f65 100644
--- a/drivers/media/dvb/b2c2/flexcop-fe-tuner.c
+++ b/drivers/media/dvb/b2c2/flexcop-fe-tuner.c
@@ -13,6 +13,8 @@
#include "bcm3510.h"
#include "stv0297.h"
#include "mt312.h"
+#include "lgdt330x.h"
+#include "dvb-pll.h"
/* lnb control */
@@ -234,7 +236,6 @@ static struct stv0299_config samsung_tbmu24112_config = {
.inittab = samsung_tbmu24112_inittab,
.mclk = 88000000UL,
.invert = 0,
- .enhanced_tuning = 0,
.skip_reinit = 0,
.lock_output = STV0229_LOCKOUTPUT_LK,
.volt13_op0_op1 = STV0299_VOLT13_OP1,
@@ -296,6 +297,52 @@ static int flexcop_fe_request_firmware(struct dvb_frontend* fe, const struct fir
return request_firmware(fw, name, fc->dev);
}
+static int lgdt3303_pll_set(struct dvb_frontend* fe,
+ struct dvb_frontend_parameters* params)
+{
+ struct flexcop_device *fc = fe->dvb->priv;
+ u8 buf[4];
+ struct i2c_msg msg =
+ { .addr = 0x61, .flags = 0, .buf = buf, .len = 4 };
+ int err;
+
+ dvb_pll_configure(&dvb_pll_tdvs_tua6034,buf, params->frequency, 0);
+ dprintk(1, "%s: tuner at 0x%02x bytes: 0x%02x 0x%02x 0x%02x 0x%02x\n",
+ __FUNCTION__, msg.addr, buf[0],buf[1],buf[2],buf[3]);
+ if ((err = i2c_transfer(&fc->i2c_adap, &msg, 1)) != 1) {
+ printk(KERN_WARNING "lgdt3303: %s error "
+ "(addr %02x <- %02x, err = %i)\n",
+ __FUNCTION__, buf[0], buf[1], err);
+ if (err < 0)
+ return err;
+ else
+ return -EREMOTEIO;
+ }
+
+ buf[0] = 0x86 | 0x18;
+ buf[1] = 0x50;
+ msg.len = 2;
+ if ((err = i2c_transfer(&fc->i2c_adap, &msg, 1)) != 1) {
+ printk(KERN_WARNING "lgdt3303: %s error "
+ "(addr %02x <- %02x, err = %i)\n",
+ __FUNCTION__, buf[0], buf[1], err);
+ if (err < 0)
+ return err;
+ else
+ return -EREMOTEIO;
+ }
+
+ return 0;
+}
+
+static struct lgdt330x_config air2pc_atsc_hd5000_config = {
+ .demod_address = 0x59,
+ .demod_chip = LGDT3303,
+ .serial_mpeg = 0x04,
+ .pll_set = lgdt3303_pll_set,
+ .clock_polarity_flip = 1,
+};
+
static struct nxt2002_config samsung_tbmv_config = {
.demod_address = 0x0a,
.request_firmware = flexcop_fe_request_firmware,
@@ -458,6 +505,11 @@ int flexcop_frontend_init(struct flexcop_device *fc)
fc->dev_type = FC_AIR_ATSC2;
info("found the nxt2002 at i2c address: 0x%02x",samsung_tbmv_config.demod_address);
} else
+ /* try the air atsc 3nd generation (lgdt3303) */
+ if ((fc->fe = lgdt330x_attach(&air2pc_atsc_hd5000_config, &fc->i2c_adap)) != NULL) {
+ fc->dev_type = FC_AIR_ATSC3;
+ info("found the lgdt3303 at i2c address: 0x%02x",air2pc_atsc_hd5000_config.demod_address);
+ } else
/* try the air atsc 1nd generation (bcm3510)/panasonic ct10s */
if ((fc->fe = bcm3510_attach(&air2pc_atsc_first_gen_config, &fc->i2c_adap)) != NULL) {
fc->dev_type = FC_AIR_ATSC1;
diff --git a/drivers/media/dvb/b2c2/flexcop-misc.c b/drivers/media/dvb/b2c2/flexcop-misc.c
index 3a08d38b318a..62282d8dbfa8 100644
--- a/drivers/media/dvb/b2c2/flexcop-misc.c
+++ b/drivers/media/dvb/b2c2/flexcop-misc.c
@@ -51,6 +51,7 @@ const char *flexcop_device_names[] = {
"Sky2PC/SkyStar 2 DVB-S",
"Sky2PC/SkyStar 2 DVB-S (old version)",
"Cable2PC/CableStar 2 DVB-C",
+ "Air2PC/AirStar 2 ATSC 3rd generation (HD5000)",
};
const char *flexcop_bus_names[] = {
diff --git a/drivers/media/dvb/b2c2/flexcop-reg.h b/drivers/media/dvb/b2c2/flexcop-reg.h
index 4ae1eb5bfe98..23cc6431e2b8 100644
--- a/drivers/media/dvb/b2c2/flexcop-reg.h
+++ b/drivers/media/dvb/b2c2/flexcop-reg.h
@@ -26,6 +26,7 @@ typedef enum {
FC_SKY,
FC_SKY_OLD,
FC_CABLE,
+ FC_AIR_ATSC3,
} flexcop_device_type_t;
typedef enum {
diff --git a/drivers/media/dvb/b2c2/flexcop.c b/drivers/media/dvb/b2c2/flexcop.c
index 12873d435406..123ed96f6faa 100644
--- a/drivers/media/dvb/b2c2/flexcop.c
+++ b/drivers/media/dvb/b2c2/flexcop.c
@@ -193,6 +193,7 @@ static void flexcop_reset(struct flexcop_device *fc)
v204 = fc->read_ibi_reg(fc,misc_204);
v204.misc_204.Per_reset_sig = 0;
fc->write_ibi_reg(fc,misc_204,v204);
+ msleep(1);
v204.misc_204.Per_reset_sig = 1;
fc->write_ibi_reg(fc,misc_204,v204);
}
diff --git a/drivers/media/dvb/bt8xx/Kconfig b/drivers/media/dvb/bt8xx/Kconfig
index 1e85d16491b0..2337b41714e0 100644
--- a/drivers/media/dvb/bt8xx/Kconfig
+++ b/drivers/media/dvb/bt8xx/Kconfig
@@ -6,10 +6,12 @@ config DVB_BT8XX
select DVB_NXT6000
select DVB_CX24110
select DVB_OR51211
+ select DVB_LGDT330X
help
Support for PCI cards based on the Bt8xx PCI bridge. Examples are
the Nebula cards, the Pinnacle PCTV cards, the Twinhan DST cards,
- the pcHDTV HD2000 cards, and certain AVerMedia cards.
+ the pcHDTV HD2000 cards, the DViCO FusionHDTV Lite cards, and
+ some AVerMedia cards.
Since these cards have no MPEG decoder onboard, they transmit
only compressed MPEG data over the PCI bus, so you need
diff --git a/drivers/media/dvb/bt8xx/dst.c b/drivers/media/dvb/bt8xx/dst.c
index 34a837a1abf4..8977c7a313df 100644
--- a/drivers/media/dvb/bt8xx/dst.c
+++ b/drivers/media/dvb/bt8xx/dst.c
@@ -690,8 +690,8 @@ struct dst_types dst_tlist[] = {
.device_id = "DTT-CI",
.offset = 1,
.dst_type = DST_TYPE_IS_TERR,
- .type_flags = DST_TYPE_HAS_TS204 | DST_TYPE_HAS_FW_2,
- .dst_feature = 0
+ .type_flags = DST_TYPE_HAS_TS204 | DST_TYPE_HAS_NEWTUNE | DST_TYPE_HAS_FW_2 | DST_TYPE_HAS_MULTI_FE,
+ .dst_feature = DST_TYPE_HAS_CA
},
{
@@ -796,6 +796,56 @@ static int dst_get_vendor(struct dst_state *state)
return 0;
}
+static int dst_get_tuner_info(struct dst_state *state)
+{
+ u8 get_tuner_1[] = { 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+ u8 get_tuner_2[] = { 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+
+ get_tuner_1[7] = dst_check_sum(get_tuner_1, 7);
+ get_tuner_2[7] = dst_check_sum(get_tuner_2, 7);
+ if (state->type_flags & DST_TYPE_HAS_MULTI_FE) {
+ if (dst_command(state, get_tuner_2, 8) < 0) {
+ dprintk(verbose, DST_INFO, 1, "Unsupported Command");
+ return -1;
+ }
+ } else {
+ if (dst_command(state, get_tuner_1, 8) < 0) {
+ dprintk(verbose, DST_INFO, 1, "Unsupported Command");
+ return -1;
+ }
+ }
+ memset(&state->board_info, '\0', 8);
+ memcpy(&state->board_info, &state->rxbuffer, 8);
+ if (state->type_flags & DST_TYPE_HAS_MULTI_FE) {
+ if (state->board_info[1] == 0x0b) {
+ if (state->type_flags & DST_TYPE_HAS_TS204)
+ state->type_flags &= ~DST_TYPE_HAS_TS204;
+ state->type_flags |= DST_TYPE_HAS_NEWTUNE;
+ dprintk(verbose, DST_INFO, 1, "DST type has TS=188");
+ } else {
+ if (state->type_flags & DST_TYPE_HAS_NEWTUNE)
+ state->type_flags &= ~DST_TYPE_HAS_NEWTUNE;
+ state->type_flags |= DST_TYPE_HAS_TS204;
+ dprintk(verbose, DST_INFO, 1, "DST type has TS=204");
+ }
+ } else {
+ if (state->board_info[0] == 0xbc) {
+ if (state->type_flags & DST_TYPE_HAS_TS204)
+ state->type_flags &= ~DST_TYPE_HAS_TS204;
+ state->type_flags |= DST_TYPE_HAS_NEWTUNE;
+ dprintk(verbose, DST_INFO, 1, "DST type has TS=188, Daughterboard=[%d]", state->board_info[1]);
+
+ } else if (state->board_info[0] == 0xcc) {
+ if (state->type_flags & DST_TYPE_HAS_NEWTUNE)
+ state->type_flags &= ~DST_TYPE_HAS_NEWTUNE;
+ state->type_flags |= DST_TYPE_HAS_TS204;
+ dprintk(verbose, DST_INFO, 1, "DST type has TS=204 Daughterboard=[%d]", state->board_info[1]);
+ }
+ }
+
+ return 0;
+}
+
static int dst_get_device_id(struct dst_state *state)
{
u8 reply;
@@ -855,15 +905,12 @@ static int dst_get_device_id(struct dst_state *state)
state->dst_type = use_dst_type;
dst_type_flags_print(state->type_flags);
- if (state->type_flags & DST_TYPE_HAS_TS204) {
- dst_packsize(state, 204);
- }
-
return 0;
}
static int dst_probe(struct dst_state *state)
{
+ sema_init(&state->dst_mutex, 1);
if ((rdc_8820_reset(state)) < 0) {
dprintk(verbose, DST_ERROR, 1, "RDC 8820 RESET Failed.");
return -1;
@@ -886,6 +933,13 @@ static int dst_probe(struct dst_state *state)
dprintk(verbose, DST_INFO, 1, "MAC: Unsupported command");
return 0;
}
+ if ((state->type_flags & DST_TYPE_HAS_MULTI_FE) || (state->type_flags & DST_TYPE_HAS_FW_BUILD)) {
+ if (dst_get_tuner_info(state) < 0)
+ dprintk(verbose, DST_INFO, 1, "Tuner: Unsupported command");
+ }
+ if (state->type_flags & DST_TYPE_HAS_TS204) {
+ dst_packsize(state, 204);
+ }
if (state->type_flags & DST_TYPE_HAS_FW_BUILD) {
if (dst_fw_ver(state) < 0) {
dprintk(verbose, DST_INFO, 1, "FW: Unsupported command");
@@ -907,21 +961,23 @@ static int dst_probe(struct dst_state *state)
int dst_command(struct dst_state *state, u8 *data, u8 len)
{
u8 reply;
+
+ down(&state->dst_mutex);
if ((dst_comm_init(state)) < 0) {
dprintk(verbose, DST_NOTICE, 1, "DST Communication Initialization Failed.");
- return -1;
+ goto error;
}
if (write_dst(state, data, len)) {
dprintk(verbose, DST_INFO, 1, "Tring to recover.. ");
if ((dst_error_recovery(state)) < 0) {
dprintk(verbose, DST_ERROR, 1, "Recovery Failed.");
- return -1;
+ goto error;
}
- return -1;
+ goto error;
}
if ((dst_pio_disable(state)) < 0) {
dprintk(verbose, DST_ERROR, 1, "PIO Disable Failed.");
- return -1;
+ goto error;
}
if (state->type_flags & DST_TYPE_HAS_FW_1)
udelay(3000);
@@ -929,36 +985,41 @@ int dst_command(struct dst_state *state, u8 *data, u8 len)
dprintk(verbose, DST_DEBUG, 1, "Trying to recover.. ");
if ((dst_error_recovery(state)) < 0) {
dprintk(verbose, DST_INFO, 1, "Recovery Failed.");
- return -1;
+ goto error;
}
- return -1;
+ goto error;
}
if (reply != ACK) {
dprintk(verbose, DST_INFO, 1, "write not acknowledged 0x%02x ", reply);
- return -1;
+ goto error;
}
if (len >= 2 && data[0] == 0 && (data[1] == 1 || data[1] == 3))
- return 0;
+ goto error;
if (state->type_flags & DST_TYPE_HAS_FW_1)
udelay(3000);
else
udelay(2000);
if (!dst_wait_dst_ready(state, NO_DELAY))
- return -1;
+ goto error;
if (read_dst(state, state->rxbuffer, FIXED_COMM)) {
dprintk(verbose, DST_DEBUG, 1, "Trying to recover.. ");
if ((dst_error_recovery(state)) < 0) {
dprintk(verbose, DST_INFO, 1, "Recovery failed.");
- return -1;
+ goto error;
}
- return -1;
+ goto error;
}
if (state->rxbuffer[7] != dst_check_sum(state->rxbuffer, 7)) {
dprintk(verbose, DST_INFO, 1, "checksum failure");
- return -1;
+ goto error;
}
-
+ up(&state->dst_mutex);
return 0;
+
+error:
+ up(&state->dst_mutex);
+ return -EIO;
+
}
EXPORT_SYMBOL(dst_command);
@@ -1016,7 +1077,7 @@ static int dst_get_tuna(struct dst_state *state)
return 0;
state->diseq_flags &= ~(HAS_LOCK);
if (!dst_wait_dst_ready(state, NO_DELAY))
- return 0;
+ return -EIO;
if (state->type_flags & DST_TYPE_HAS_NEWTUNE)
/* how to get variable length reply ???? */
retval = read_dst(state, state->rx_tuna, 10);
@@ -1024,22 +1085,27 @@ static int dst_get_tuna(struct dst_state *state)
retval = read_dst(state, &state->rx_tuna[2], FIXED_COMM);
if (retval < 0) {
dprintk(verbose, DST_DEBUG, 1, "read not successful");
- return 0;
+ return retval;
}
if (state->type_flags & DST_TYPE_HAS_NEWTUNE) {
if (state->rx_tuna[9] != dst_check_sum(&state->rx_tuna[0], 9)) {
dprintk(verbose, DST_INFO, 1, "checksum failure ? ");
- return 0;
+ return -EIO;
}
} else {
if (state->rx_tuna[9] != dst_check_sum(&state->rx_tuna[2], 7)) {
dprintk(verbose, DST_INFO, 1, "checksum failure? ");
- return 0;
+ return -EIO;
}
}
if (state->rx_tuna[2] == 0 && state->rx_tuna[3] == 0)
return 0;
- state->decode_freq = ((state->rx_tuna[2] & 0x7f) << 8) + state->rx_tuna[3];
+ if (state->dst_type == DST_TYPE_IS_SAT) {
+ state->decode_freq = ((state->rx_tuna[2] & 0x7f) << 8) + state->rx_tuna[3];
+ } else {
+ state->decode_freq = ((state->rx_tuna[2] & 0x7f) << 16) + (state->rx_tuna[3] << 8) + state->rx_tuna[4];
+ }
+ state->decode_freq = state->decode_freq * 1000;
state->decode_lock = 1;
state->diseq_flags |= HAS_LOCK;
@@ -1062,10 +1128,10 @@ static int dst_write_tuna(struct dvb_frontend *fe)
dst_set_voltage(fe, SEC_VOLTAGE_13);
}
state->diseq_flags &= ~(HAS_LOCK | ATTEMPT_TUNE);
-
+ down(&state->dst_mutex);
if ((dst_comm_init(state)) < 0) {
dprintk(verbose, DST_DEBUG, 1, "DST Communication initialization failed.");
- return -1;
+ goto error;
}
if (state->type_flags & DST_TYPE_HAS_NEWTUNE) {
state->tx_tuna[9] = dst_check_sum(&state->tx_tuna[0], 9);
@@ -1077,23 +1143,29 @@ static int dst_write_tuna(struct dvb_frontend *fe)
if (retval < 0) {
dst_pio_disable(state);
dprintk(verbose, DST_DEBUG, 1, "write not successful");
- return retval;
+ goto werr;
}
if ((dst_pio_disable(state)) < 0) {
dprintk(verbose, DST_DEBUG, 1, "DST PIO disable failed !");
- return -1;
+ goto error;
}
if ((read_dst(state, &reply, GET_ACK) < 0)) {
dprintk(verbose, DST_DEBUG, 1, "read verify not successful.");
- return -1;
+ goto error;
}
if (reply != ACK) {
dprintk(verbose, DST_DEBUG, 1, "write not acknowledged 0x%02x ", reply);
- return 0;
+ goto error;
}
state->diseq_flags |= ATTEMPT_TUNE;
-
- return dst_get_tuna(state);
+ retval = dst_get_tuna(state);
+werr:
+ up(&state->dst_mutex);
+ return retval;
+
+error:
+ up(&state->dst_mutex);
+ return -EIO;
}
/*
@@ -1331,9 +1403,7 @@ struct dst_state *dst_attach(struct dst_state *state, struct dvb_adapter *dvb_ad
{
/* check if the ASIC is there */
if (dst_probe(state) < 0) {
- if (state)
- kfree(state);
-
+ kfree(state);
return NULL;
}
/* determine settings based on type */
@@ -1349,9 +1419,7 @@ struct dst_state *dst_attach(struct dst_state *state, struct dvb_adapter *dvb_ad
break;
default:
dprintk(verbose, DST_ERROR, 1, "unknown DST type. please report to the LinuxTV.org DVB mailinglist.");
- if (state)
- kfree(state);
-
+ kfree(state);
return NULL;
}
diff --git a/drivers/media/dvb/bt8xx/dst_ca.c b/drivers/media/dvb/bt8xx/dst_ca.c
index 6776a592045f..e6541aff3996 100644
--- a/drivers/media/dvb/bt8xx/dst_ca.c
+++ b/drivers/media/dvb/bt8xx/dst_ca.c
@@ -69,62 +69,53 @@ static int ca_set_pid(void)
}
-static int put_checksum(u8 *check_string, int length)
+static void put_checksum(u8 *check_string, int length)
{
- u8 i = 0, checksum = 0;
-
- dprintk(verbose, DST_CA_DEBUG, 1, " ========================= Checksum calculation ===========================");
- dprintk(verbose, DST_CA_DEBUG, 1, " String Length=[0x%02x]", length);
- dprintk(verbose, DST_CA_DEBUG, 1, " String=[");
-
- while (i < length) {
- dprintk(verbose, DST_CA_DEBUG, 0, " %02x", check_string[i]);
- checksum += check_string[i];
- i++;
- }
- dprintk(verbose, DST_CA_DEBUG, 0, " ]\n");
- dprintk(verbose, DST_CA_DEBUG, 1, "Sum=[%02x]\n", checksum);
- check_string[length] = ~checksum + 1;
- dprintk(verbose, DST_CA_DEBUG, 1, " Checksum=[%02x]", check_string[length]);
- dprintk(verbose, DST_CA_DEBUG, 1, " ==========================================================================");
-
- return 0;
+ dprintk(verbose, DST_CA_DEBUG, 1, " Computing string checksum.");
+ dprintk(verbose, DST_CA_DEBUG, 1, " -> string length : 0x%02x", length);
+ check_string[length] = dst_check_sum (check_string, length);
+ dprintk(verbose, DST_CA_DEBUG, 1, " -> checksum : 0x%02x", check_string[length]);
}
static int dst_ci_command(struct dst_state* state, u8 * data, u8 *ca_string, u8 len, int read)
{
u8 reply;
+ down(&state->dst_mutex);
dst_comm_init(state);
msleep(65);
if (write_dst(state, data, len)) {
dprintk(verbose, DST_CA_INFO, 1, " Write not successful, trying to recover");
dst_error_recovery(state);
- return -1;
+ goto error;
}
if ((dst_pio_disable(state)) < 0) {
dprintk(verbose, DST_CA_ERROR, 1, " DST PIO disable failed.");
- return -1;
+ goto error;
}
if (read_dst(state, &reply, GET_ACK) < 0) {
dprintk(verbose, DST_CA_INFO, 1, " Read not successful, trying to recover");
dst_error_recovery(state);
- return -1;
+ goto error;
}
if (read) {
if (! dst_wait_dst_ready(state, LONG_DELAY)) {
dprintk(verbose, DST_CA_NOTICE, 1, " 8820 not ready");
- return -1;
+ goto error;
}
if (read_dst(state, ca_string, 128) < 0) { /* Try to make this dynamic */
dprintk(verbose, DST_CA_INFO, 1, " Read not successful, trying to recover");
dst_error_recovery(state);
- return -1;
+ goto error;
}
}
-
+ up(&state->dst_mutex);
return 0;
+
+error:
+ up(&state->dst_mutex);
+ return -EIO;
}
@@ -166,7 +157,7 @@ static int ca_get_app_info(struct dst_state *state)
return 0;
}
-static int ca_get_slot_caps(struct dst_state *state, struct ca_caps *p_ca_caps, void *arg)
+static int ca_get_slot_caps(struct dst_state *state, struct ca_caps *p_ca_caps, void __user *arg)
{
int i;
u8 slot_cap[256];
@@ -192,25 +183,25 @@ static int ca_get_slot_caps(struct dst_state *state, struct ca_caps *p_ca_caps,
p_ca_caps->descr_num = slot_cap[7];
p_ca_caps->descr_type = 1;
- if (copy_to_user((struct ca_caps *)arg, p_ca_caps, sizeof (struct ca_caps)))
+ if (copy_to_user(arg, p_ca_caps, sizeof (struct ca_caps)))
return -EFAULT;
return 0;
}
/* Need some more work */
-static int ca_get_slot_descr(struct dst_state *state, struct ca_msg *p_ca_message, void *arg)
+static int ca_get_slot_descr(struct dst_state *state, struct ca_msg *p_ca_message, void __user *arg)
{
return -EOPNOTSUPP;
}
-static int ca_get_slot_info(struct dst_state *state, struct ca_slot_info *p_ca_slot_info, void *arg)
+static int ca_get_slot_info(struct dst_state *state, struct ca_slot_info *p_ca_slot_info, void __user *arg)
{
int i;
static u8 slot_command[8] = {0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff};
- u8 *slot_info = state->rxbuffer;
+ u8 *slot_info = state->messages;
put_checksum(&slot_command[0], 7);
if ((dst_put_ci(state, slot_command, sizeof (slot_command), slot_info, GET_REPLY)) < 0) {
@@ -238,19 +229,19 @@ static int ca_get_slot_info(struct dst_state *state, struct ca_slot_info *p_ca_s
} else
p_ca_slot_info->flags = 0;
- if (copy_to_user((struct ca_slot_info *)arg, p_ca_slot_info, sizeof (struct ca_slot_info)))
+ if (copy_to_user(arg, p_ca_slot_info, sizeof (struct ca_slot_info)))
return -EFAULT;
return 0;
}
-static int ca_get_message(struct dst_state *state, struct ca_msg *p_ca_message, void *arg)
+static int ca_get_message(struct dst_state *state, struct ca_msg *p_ca_message, void __user *arg)
{
u8 i = 0;
u32 command = 0;
- if (copy_from_user(p_ca_message, (void *)arg, sizeof (struct ca_msg)))
+ if (copy_from_user(p_ca_message, arg, sizeof (struct ca_msg)))
return -EFAULT;
if (p_ca_message->msg) {
@@ -266,7 +257,7 @@ static int ca_get_message(struct dst_state *state, struct ca_msg *p_ca_message,
switch (command) {
case CA_APP_INFO:
memcpy(p_ca_message->msg, state->messages, 128);
- if (copy_to_user((void *)arg, p_ca_message, sizeof (struct ca_msg)) )
+ if (copy_to_user(arg, p_ca_message, sizeof (struct ca_msg)) )
return -EFAULT;
break;
}
@@ -315,7 +306,7 @@ static int write_to_8820(struct dst_state *state, struct ca_msg *hw_buffer, u8 l
return 0;
}
-u32 asn_1_decode(u8 *asn_1_array)
+static u32 asn_1_decode(u8 *asn_1_array)
{
u8 length_field = 0, word_count = 0, count = 0;
u32 length = 0;
@@ -328,7 +319,8 @@ u32 asn_1_decode(u8 *asn_1_array)
} else {
word_count = length_field & 0x7f;
for (count = 0; count < word_count; count++) {
- length = (length | asn_1_array[count + 1]) << 8;
+ length = length << 8;
+ length += asn_1_array[count + 1];
dprintk(verbose, DST_CA_DEBUG, 1, " Length=[%04x]", length);
}
}
@@ -399,13 +391,14 @@ static int dst_check_ca_pmt(struct dst_state *state, struct ca_msg *p_ca_message
return 0;
}
-static int ca_send_message(struct dst_state *state, struct ca_msg *p_ca_message, void *arg)
+static int ca_send_message(struct dst_state *state, struct ca_msg *p_ca_message, void __user *arg)
{
int i = 0;
unsigned int ca_message_header_len;
u32 command = 0;
struct ca_msg *hw_buffer;
+ int result = 0;
if ((hw_buffer = (struct ca_msg *) kmalloc(sizeof (struct ca_msg), GFP_KERNEL)) == NULL) {
dprintk(verbose, DST_CA_ERROR, 1, " Memory allocation failure");
@@ -413,8 +406,11 @@ static int ca_send_message(struct dst_state *state, struct ca_msg *p_ca_message,
}
dprintk(verbose, DST_CA_DEBUG, 1, " ");
- if (copy_from_user(p_ca_message, (void *)arg, sizeof (struct ca_msg)))
- return -EFAULT;
+ if (copy_from_user(p_ca_message, (void *)arg, sizeof (struct ca_msg))) {
+ result = -EFAULT;
+ goto free_mem_and_exit;
+ }
+
if (p_ca_message->msg) {
ca_message_header_len = p_ca_message->length; /* Restore it back when you are done */
@@ -433,7 +429,8 @@ static int ca_send_message(struct dst_state *state, struct ca_msg *p_ca_message,
dprintk(verbose, DST_CA_DEBUG, 1, "Command = SEND_CA_PMT");
if ((ca_set_pmt(state, p_ca_message, hw_buffer, 0, 0)) < 0) { // code simplification started
dprintk(verbose, DST_CA_ERROR, 1, " -->CA_PMT Failed !");
- return -1;
+ result = -1;
+ goto free_mem_and_exit;
}
dprintk(verbose, DST_CA_INFO, 1, " -->CA_PMT Success !");
break;
@@ -442,7 +439,8 @@ static int ca_send_message(struct dst_state *state, struct ca_msg *p_ca_message,
/* Have to handle the 2 basic types of cards here */
if ((dst_check_ca_pmt(state, p_ca_message, hw_buffer)) < 0) {
dprintk(verbose, DST_CA_ERROR, 1, " -->CA_PMT_REPLY Failed !");
- return -1;
+ result = -1;
+ goto free_mem_and_exit;
}
dprintk(verbose, DST_CA_INFO, 1, " -->CA_PMT_REPLY Success !");
break;
@@ -451,22 +449,28 @@ static int ca_send_message(struct dst_state *state, struct ca_msg *p_ca_message,
if ((ca_get_app_info(state)) < 0) {
dprintk(verbose, DST_CA_ERROR, 1, " -->CA_APP_INFO_ENQUIRY Failed !");
- return -1;
+ result = -1;
+ goto free_mem_and_exit;
}
dprintk(verbose, DST_CA_INFO, 1, " -->CA_APP_INFO_ENQUIRY Success !");
break;
}
}
- return 0;
+free_mem_and_exit:
+ kfree (hw_buffer);
+
+ return result;
}
-static int dst_ca_ioctl(struct inode *inode, struct file *file, unsigned int cmd, void *arg)
+static int dst_ca_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long ioctl_arg)
{
struct dvb_device* dvbdev = (struct dvb_device*) file->private_data;
struct dst_state* state = (struct dst_state*) dvbdev->priv;
struct ca_slot_info *p_ca_slot_info;
struct ca_caps *p_ca_caps;
struct ca_msg *p_ca_message;
+ void __user *arg = (void __user *)ioctl_arg;
+ int result = 0;
if ((p_ca_message = (struct ca_msg *) kmalloc(sizeof (struct ca_msg), GFP_KERNEL)) == NULL) {
dprintk(verbose, DST_CA_ERROR, 1, " Memory allocation failure");
@@ -486,14 +490,16 @@ static int dst_ca_ioctl(struct inode *inode, struct file *file, unsigned int cmd
dprintk(verbose, DST_CA_INFO, 1, " Sending message");
if ((ca_send_message(state, p_ca_message, arg)) < 0) {
dprintk(verbose, DST_CA_ERROR, 1, " -->CA_SEND_MSG Failed !");
- return -1;
+ result = -1;
+ goto free_mem_and_exit;
}
break;
case CA_GET_MSG:
dprintk(verbose, DST_CA_INFO, 1, " Getting message");
if ((ca_get_message(state, p_ca_message, arg)) < 0) {
dprintk(verbose, DST_CA_ERROR, 1, " -->CA_GET_MSG Failed !");
- return -1;
+ result = -1;
+ goto free_mem_and_exit;
}
dprintk(verbose, DST_CA_INFO, 1, " -->CA_GET_MSG Success !");
break;
@@ -506,7 +512,8 @@ static int dst_ca_ioctl(struct inode *inode, struct file *file, unsigned int cmd
dprintk(verbose, DST_CA_INFO, 1, " Getting Slot info");
if ((ca_get_slot_info(state, p_ca_slot_info, arg)) < 0) {
dprintk(verbose, DST_CA_ERROR, 1, " -->CA_GET_SLOT_INFO Failed !");
- return -1;
+ result = -1;
+ goto free_mem_and_exit;
}
dprintk(verbose, DST_CA_INFO, 1, " -->CA_GET_SLOT_INFO Success !");
break;
@@ -514,7 +521,8 @@ static int dst_ca_ioctl(struct inode *inode, struct file *file, unsigned int cmd
dprintk(verbose, DST_CA_INFO, 1, " Getting Slot capabilities");
if ((ca_get_slot_caps(state, p_ca_caps, arg)) < 0) {
dprintk(verbose, DST_CA_ERROR, 1, " -->CA_GET_CAP Failed !");
- return -1;
+ result = -1;
+ goto free_mem_and_exit;
}
dprintk(verbose, DST_CA_INFO, 1, " -->CA_GET_CAP Success !");
break;
@@ -522,7 +530,8 @@ static int dst_ca_ioctl(struct inode *inode, struct file *file, unsigned int cmd
dprintk(verbose, DST_CA_INFO, 1, " Getting descrambler description");
if ((ca_get_slot_descr(state, p_ca_message, arg)) < 0) {
dprintk(verbose, DST_CA_ERROR, 1, " -->CA_GET_DESCR_INFO Failed !");
- return -1;
+ result = -1;
+ goto free_mem_and_exit;
}
dprintk(verbose, DST_CA_INFO, 1, " -->CA_GET_DESCR_INFO Success !");
break;
@@ -530,7 +539,8 @@ static int dst_ca_ioctl(struct inode *inode, struct file *file, unsigned int cmd
dprintk(verbose, DST_CA_INFO, 1, " Setting descrambler");
if ((ca_set_slot_descr()) < 0) {
dprintk(verbose, DST_CA_ERROR, 1, " -->CA_SET_DESCR Failed !");
- return -1;
+ result = -1;
+ goto free_mem_and_exit;
}
dprintk(verbose, DST_CA_INFO, 1, " -->CA_SET_DESCR Success !");
break;
@@ -538,14 +548,19 @@ static int dst_ca_ioctl(struct inode *inode, struct file *file, unsigned int cmd
dprintk(verbose, DST_CA_INFO, 1, " Setting PID");
if ((ca_set_pid()) < 0) {
dprintk(verbose, DST_CA_ERROR, 1, " -->CA_SET_PID Failed !");
- return -1;
+ result = -1;
+ goto free_mem_and_exit;
}
dprintk(verbose, DST_CA_INFO, 1, " -->CA_SET_PID Success !");
default:
- return -EOPNOTSUPP;
+ result = -EOPNOTSUPP;
};
+ free_mem_and_exit:
+ kfree (p_ca_message);
+ kfree (p_ca_slot_info);
+ kfree (p_ca_caps);
- return 0;
+ return result;
}
static int dst_ca_open(struct inode *inode, struct file *file)
@@ -582,7 +597,7 @@ static int dst_ca_write(struct file *file, const char __user *buffer, size_t len
static struct file_operations dst_ca_fops = {
.owner = THIS_MODULE,
- .ioctl = (void *)dst_ca_ioctl,
+ .ioctl = dst_ca_ioctl,
.open = dst_ca_open,
.release = dst_ca_release,
.read = dst_ca_read,
diff --git a/drivers/media/dvb/bt8xx/dst_common.h b/drivers/media/dvb/bt8xx/dst_common.h
index 3281a6ca3685..81557f38fe38 100644
--- a/drivers/media/dvb/bt8xx/dst_common.h
+++ b/drivers/media/dvb/bt8xx/dst_common.h
@@ -22,6 +22,7 @@
#ifndef DST_COMMON_H
#define DST_COMMON_H
+#include <linux/smp_lock.h>
#include <linux/dvb/frontend.h>
#include <linux/device.h>
#include "bt878.h"
@@ -49,6 +50,7 @@
#define DST_TYPE_HAS_FW_BUILD 64
#define DST_TYPE_HAS_OBS_REGS 128
#define DST_TYPE_HAS_INC_COUNT 256
+#define DST_TYPE_HAS_MULTI_FE 512
/* Card capability list */
@@ -117,6 +119,9 @@ struct dst_state {
u8 fw_version[8];
u8 card_info[8];
u8 vendor[8];
+ u8 board_info[8];
+
+ struct semaphore dst_mutex;
};
struct dst_types {
diff --git a/drivers/media/dvb/bt8xx/dvb-bt8xx.c b/drivers/media/dvb/bt8xx/dvb-bt8xx.c
index c5c7672cd538..2e398090cf63 100644
--- a/drivers/media/dvb/bt8xx/dvb-bt8xx.c
+++ b/drivers/media/dvb/bt8xx/dvb-bt8xx.c
@@ -34,6 +34,7 @@
#include "dvb_frontend.h"
#include "dvb-bt8xx.h"
#include "bt878.h"
+#include "dvb-pll.h"
static int debug;
@@ -279,7 +280,7 @@ static int microtune_mt7202dtf_pll_set(struct dvb_frontend* fe, struct dvb_front
data[0] = (div >> 8) & 0x7f;
data[1] = div & 0xff;
data[2] = ((div >> 10) & 0x60) | cfg;
- data[3] = cpump | band_select;
+ data[3] = (cpump << 6) | band_select;
i2c_transfer(card->i2c_adapter, &msg, 1);
return (div * 166666 - 36000000);
@@ -522,9 +523,7 @@ static void digitv_alps_tded4_reset(struct dvb_bt8xx_card *bt)
/*
* Reset the frontend, must be called before trying
* to initialise the MT352 or mt352_attach
- * will fail.
- *
- * Presumably not required for the NXT6000 frontend.
+ * will fail. Same goes for the nxt6000 frontend.
*
*/
@@ -546,14 +545,63 @@ static struct mt352_config digitv_alps_tded4_config = {
.pll_set = digitv_alps_tded4_pll_set,
};
+static int tdvs_tua6034_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
+{
+ struct dvb_bt8xx_card *card = (struct dvb_bt8xx_card *) fe->dvb->priv;
+ u8 buf[4];
+ struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) };
+ int err;
+
+ dvb_pll_configure(&dvb_pll_tdvs_tua6034, buf, params->frequency, 0);
+ dprintk("%s: tuner at 0x%02x bytes: 0x%02x 0x%02x 0x%02x 0x%02x\n",
+ __FUNCTION__, msg.addr, buf[0],buf[1],buf[2],buf[3]);
+ if ((err = i2c_transfer(card->i2c_adapter, &msg, 1)) != 1) {
+ printk(KERN_WARNING "dvb-bt8xx: %s error "
+ "(addr %02x <- %02x, err = %i)\n",
+ __FUNCTION__, buf[0], buf[1], err);
+ if (err < 0)
+ return err;
+ else
+ return -EREMOTEIO;
+ }
+
+ /* Set the Auxiliary Byte. */
+ buf[2] &= ~0x20;
+ buf[2] |= 0x18;
+ buf[3] = 0x50;
+ i2c_transfer(card->i2c_adapter, &msg, 1);
+
+ return 0;
+}
+
+static struct lgdt330x_config tdvs_tua6034_config = {
+ .demod_address = 0x0e,
+ .demod_chip = LGDT3303,
+ .serial_mpeg = 0x40, /* TPSERIAL for 3303 in TOP_CONTROL */
+ .pll_set = tdvs_tua6034_pll_set,
+};
+
+static void lgdt330x_reset(struct dvb_bt8xx_card *bt)
+{
+ /* Set pin 27 of the lgdt3303 chip high to reset the frontend */
+
+ /* Pulse the reset line */
+ bttv_write_gpio(bt->bttv_nr, 0x00e00007, 0x00000001); /* High */
+ bttv_write_gpio(bt->bttv_nr, 0x00e00007, 0x00000000); /* Low */
+ msleep(100);
+
+ bttv_write_gpio(bt->bttv_nr, 0x00e00007, 0x00000001); /* High */
+ msleep(100);
+}
+
static void frontend_init(struct dvb_bt8xx_card *card, u32 type)
{
int ret;
struct dst_state* state = NULL;
switch(type) {
-#ifdef BTTV_DVICO_DVBT_LITE
- case BTTV_DVICO_DVBT_LITE:
+#ifdef BTTV_BOARD_DVICO_DVBT_LITE
+ case BTTV_BOARD_DVICO_DVBT_LITE:
card->fe = mt352_attach(&thomson_dtt7579_config, card->i2c_adapter);
if (card->fe != NULL) {
card->fe->ops->info.frequency_min = 174000000;
@@ -562,10 +610,19 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type)
break;
#endif
-#ifdef BTTV_TWINHAN_VP3021
- case BTTV_TWINHAN_VP3021:
+#ifdef BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE
+ case BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE:
+ lgdt330x_reset(card);
+ card->fe = lgdt330x_attach(&tdvs_tua6034_config, card->i2c_adapter);
+ if (card->fe != NULL)
+ dprintk ("dvb_bt8xx: lgdt330x detected\n");
+ break;
+#endif
+
+#ifdef BTTV_BOARD_TWINHAN_VP3021
+ case BTTV_BOARD_TWINHAN_VP3021:
#else
- case BTTV_NEBULA_DIGITV:
+ case BTTV_BOARD_NEBULA_DIGITV:
#endif
/*
* It is possible to determine the correct frontend using the I2C bus (see the Nebula SDK);
@@ -573,6 +630,7 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type)
*/
/* Old Nebula (marked (c)2003 on high profile pci card) has nxt6000 demod */
+ digitv_alps_tded4_reset(card);
card->fe = nxt6000_attach(&vp3021_alps_tded4_config, card->i2c_adapter);
if (card->fe != NULL) {
dprintk ("dvb_bt8xx: an nxt6000 was detected on your digitv card\n");
@@ -587,11 +645,11 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type)
dprintk ("dvb_bt8xx: an mt352 was detected on your digitv card\n");
break;
- case BTTV_AVDVBT_761:
+ case BTTV_BOARD_AVDVBT_761:
card->fe = sp887x_attach(&microtune_mt7202dtf_config, card->i2c_adapter);
break;
- case BTTV_AVDVBT_771:
+ case BTTV_BOARD_AVDVBT_771:
card->fe = mt352_attach(&advbt771_samsung_tdtc9251dh0_config, card->i2c_adapter);
if (card->fe != NULL) {
card->fe->ops->info.frequency_min = 174000000;
@@ -599,7 +657,7 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type)
}
break;
- case BTTV_TWINHAN_DST:
+ case BTTV_BOARD_TWINHAN_DST:
/* DST is not a frontend driver !!! */
state = (struct dst_state *) kmalloc(sizeof (struct dst_state), GFP_KERNEL);
/* Setup the Card */
@@ -620,11 +678,11 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type)
ret = dst_ca_attach(state, &card->dvb_adapter);
break;
- case BTTV_PINNACLESAT:
+ case BTTV_BOARD_PINNACLESAT:
card->fe = cx24110_attach(&pctvsat_config, card->i2c_adapter);
break;
- case BTTV_PC_HDTV:
+ case BTTV_BOARD_PC_HDTV:
card->fe = or51211_attach(&or51211_config, card->i2c_adapter);
break;
}
@@ -746,7 +804,7 @@ static int dvb_bt8xx_probe(struct device *dev)
card->i2c_adapter = &sub->core->i2c_adap;
switch(sub->core->type) {
- case BTTV_PINNACLESAT:
+ case BTTV_BOARD_PINNACLESAT:
card->gpio_mode = 0x0400c060;
/* should be: BT878_A_GAIN=0,BT878_A_PWRDN,BT878_DA_DPM,BT878_DA_SBR,
BT878_DA_IOM=1,BT878_DA_APP to enable serial highspeed mode. */
@@ -754,8 +812,8 @@ static int dvb_bt8xx_probe(struct device *dev)
card->irq_err_ignore = 0;
break;
-#ifdef BTTV_DVICO_DVBT_LITE
- case BTTV_DVICO_DVBT_LITE:
+#ifdef BTTV_BOARD_DVICO_DVBT_LITE
+ case BTTV_BOARD_DVICO_DVBT_LITE:
#endif
card->gpio_mode = 0x0400C060;
card->op_sync_orin = 0;
@@ -765,26 +823,34 @@ static int dvb_bt8xx_probe(struct device *dev)
* DA_APP(parallel) */
break;
-#ifdef BTTV_TWINHAN_VP3021
- case BTTV_TWINHAN_VP3021:
+#ifdef BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE
+ case BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE:
+#endif
+ card->gpio_mode = 0x0400c060;
+ card->op_sync_orin = BT878_RISC_SYNC_MASK;
+ card->irq_err_ignore = BT878_AFBUS | BT878_AFDSR;
+ break;
+
+#ifdef BTTV_BOARD_TWINHAN_VP3021
+ case BTTV_BOARD_TWINHAN_VP3021:
#else
- case BTTV_NEBULA_DIGITV:
+ case BTTV_BOARD_NEBULA_DIGITV:
#endif
- case BTTV_AVDVBT_761:
+ case BTTV_BOARD_AVDVBT_761:
card->gpio_mode = (1 << 26) | (1 << 14) | (1 << 5);
card->op_sync_orin = 0;
card->irq_err_ignore = 0;
/* A_PWRDN DA_SBR DA_APP (high speed serial) */
break;
- case BTTV_AVDVBT_771: //case 0x07711461:
+ case BTTV_BOARD_AVDVBT_771: //case 0x07711461:
card->gpio_mode = 0x0400402B;
card->op_sync_orin = BT878_RISC_SYNC_MASK;
card->irq_err_ignore = 0;
/* A_PWRDN DA_SBR DA_APP[0] PKTP=10 RISC_ENABLE FIFO_ENABLE*/
break;
- case BTTV_TWINHAN_DST:
+ case BTTV_BOARD_TWINHAN_DST:
card->gpio_mode = 0x2204f2c;
card->op_sync_orin = BT878_RISC_SYNC_MASK;
card->irq_err_ignore = BT878_APABORT | BT878_ARIPERR |
@@ -802,7 +868,7 @@ static int dvb_bt8xx_probe(struct device *dev)
* RISC+FIFO ENABLE */
break;
- case BTTV_PC_HDTV:
+ case BTTV_BOARD_PC_HDTV:
card->gpio_mode = 0x0100EC7B;
card->op_sync_orin = 0;
card->irq_err_ignore = 0;
diff --git a/drivers/media/dvb/bt8xx/dvb-bt8xx.h b/drivers/media/dvb/bt8xx/dvb-bt8xx.h
index 9ec8e5bd6c1f..cf035a80361c 100644
--- a/drivers/media/dvb/bt8xx/dvb-bt8xx.h
+++ b/drivers/media/dvb/bt8xx/dvb-bt8xx.h
@@ -35,6 +35,7 @@
#include "nxt6000.h"
#include "cx24110.h"
#include "or51211.h"
+#include "lgdt330x.h"
struct dvb_bt8xx_card {
struct semaphore lock;
diff --git a/drivers/media/dvb/cinergyT2/cinergyT2.c b/drivers/media/dvb/cinergyT2/cinergyT2.c
index 6db0929ef53d..a1607e7d6d6b 100644
--- a/drivers/media/dvb/cinergyT2/cinergyT2.c
+++ b/drivers/media/dvb/cinergyT2/cinergyT2.c
@@ -137,7 +137,8 @@ struct cinergyt2 {
struct urb *stream_urb [STREAM_URB_COUNT];
#ifdef ENABLE_RC
- struct input_dev rc_input_dev;
+ struct input_dev *rc_input_dev;
+ char phys[64];
struct work_struct rc_query_work;
int rc_input_event;
u32 rc_last_code;
@@ -683,6 +684,7 @@ static struct dvb_device cinergyt2_fe_template = {
};
#ifdef ENABLE_RC
+
static void cinergyt2_query_rc (void *data)
{
struct cinergyt2 *cinergyt2 = data;
@@ -703,7 +705,7 @@ static void cinergyt2_query_rc (void *data)
/* stop key repeat */
if (cinergyt2->rc_input_event != KEY_MAX) {
dprintk(1, "rc_input_event=%d Up\n", cinergyt2->rc_input_event);
- input_report_key(&cinergyt2->rc_input_dev,
+ input_report_key(cinergyt2->rc_input_dev,
cinergyt2->rc_input_event, 0);
cinergyt2->rc_input_event = KEY_MAX;
}
@@ -722,7 +724,7 @@ static void cinergyt2_query_rc (void *data)
/* keyrepeat bit -> just repeat last rc_input_event */
} else {
cinergyt2->rc_input_event = KEY_MAX;
- for (i = 0; i < sizeof(rc_keys) / sizeof(rc_keys[0]); i += 3) {
+ for (i = 0; i < ARRAY_SIZE(rc_keys); i += 3) {
if (rc_keys[i + 0] == rc_events[n].type &&
rc_keys[i + 1] == le32_to_cpu(rc_events[n].value)) {
cinergyt2->rc_input_event = rc_keys[i + 2];
@@ -736,11 +738,11 @@ static void cinergyt2_query_rc (void *data)
cinergyt2->rc_last_code != ~0) {
/* emit a key-up so the double event is recognized */
dprintk(1, "rc_input_event=%d UP\n", cinergyt2->rc_input_event);
- input_report_key(&cinergyt2->rc_input_dev,
+ input_report_key(cinergyt2->rc_input_dev,
cinergyt2->rc_input_event, 0);
}
dprintk(1, "rc_input_event=%d\n", cinergyt2->rc_input_event);
- input_report_key(&cinergyt2->rc_input_dev,
+ input_report_key(cinergyt2->rc_input_dev,
cinergyt2->rc_input_event, 1);
cinergyt2->rc_last_code = rc_events[n].value;
}
@@ -752,7 +754,59 @@ out:
up(&cinergyt2->sem);
}
-#endif
+
+static int cinergyt2_register_rc(struct cinergyt2 *cinergyt2)
+{
+ struct input_dev *input_dev;
+ int i;
+
+ cinergyt2->rc_input_dev = input_dev = input_allocate_device();
+ if (!input_dev)
+ return -ENOMEM;
+
+ usb_make_path(cinergyt2->udev, cinergyt2->phys, sizeof(cinergyt2->phys));
+ strlcat(cinergyt2->phys, "/input0", sizeof(cinergyt2->phys));
+ cinergyt2->rc_input_event = KEY_MAX;
+ cinergyt2->rc_last_code = ~0;
+ INIT_WORK(&cinergyt2->rc_query_work, cinergyt2_query_rc, cinergyt2);
+
+ input_dev->name = DRIVER_NAME " remote control";
+ input_dev->phys = cinergyt2->phys;
+ input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
+ for (i = 0; ARRAY_SIZE(rc_keys); i += 3)
+ set_bit(rc_keys[i + 2], input_dev->keybit);
+ input_dev->keycodesize = 0;
+ input_dev->keycodemax = 0;
+
+ input_register_device(cinergyt2->rc_input_dev);
+ schedule_delayed_work(&cinergyt2->rc_query_work, HZ/2);
+}
+
+static void cinergyt2_unregister_rc(struct cinergyt2 *cinergyt2)
+{
+ cancel_delayed_work(&cinergyt2->rc_query_work);
+ flush_scheduled_work();
+ input_unregister_device(cinergyt2->rc_input_dev);
+}
+
+static inline void cinergyt2_suspend_rc(struct cinergyt2 *cinergyt2)
+{
+ cancel_delayed_work(&cinergyt2->rc_query_work);
+}
+
+static inline void cinergyt2_resume_rc(struct cinergyt2 *cinergyt2)
+{
+ schedule_delayed_work(&cinergyt2->rc_query_work, HZ/2);
+}
+
+#else
+
+static inline int cinergyt2_register_rc(struct cinergyt2 *cinergyt2) { return 0; }
+static inline void cinergyt2_unregister_rc(struct cinergyt2 *cinergyt2) { }
+static inline void cinergyt2_suspend_rc(struct cinergyt2 *cinergyt2) { }
+static inline void cinergyt2_resume_rc(struct cinergyt2 *cinergyt2) { }
+
+#endif /* ENABLE_RC */
static void cinergyt2_query (void *data)
{
@@ -789,9 +843,6 @@ static int cinergyt2_probe (struct usb_interface *intf,
{
struct cinergyt2 *cinergyt2;
int err;
-#ifdef ENABLE_RC
- int i;
-#endif
if (!(cinergyt2 = kmalloc (sizeof(struct cinergyt2), GFP_KERNEL))) {
dprintk(1, "out of memory?!?\n");
@@ -846,30 +897,17 @@ static int cinergyt2_probe (struct usb_interface *intf,
&cinergyt2_fe_template, cinergyt2,
DVB_DEVICE_FRONTEND);
-#ifdef ENABLE_RC
- cinergyt2->rc_input_dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
- cinergyt2->rc_input_dev.keycodesize = 0;
- cinergyt2->rc_input_dev.keycodemax = 0;
- cinergyt2->rc_input_dev.name = DRIVER_NAME " remote control";
-
- for (i = 0; i < sizeof(rc_keys) / sizeof(rc_keys[0]); i += 3)
- set_bit(rc_keys[i + 2], cinergyt2->rc_input_dev.keybit);
-
- input_register_device(&cinergyt2->rc_input_dev);
-
- cinergyt2->rc_input_event = KEY_MAX;
- cinergyt2->rc_last_code = ~0;
+ err = cinergyt2_register_rc(cinergyt2);
+ if (err)
+ goto bailout;
- INIT_WORK(&cinergyt2->rc_query_work, cinergyt2_query_rc, cinergyt2);
- schedule_delayed_work(&cinergyt2->rc_query_work, HZ/2);
-#endif
return 0;
bailout:
dvb_dmxdev_release(&cinergyt2->dmxdev);
dvb_dmx_release(&cinergyt2->demux);
- dvb_unregister_adapter (&cinergyt2->adapter);
- cinergyt2_free_stream_urbs (cinergyt2);
+ dvb_unregister_adapter(&cinergyt2->adapter);
+ cinergyt2_free_stream_urbs(cinergyt2);
kfree(cinergyt2);
return -ENOMEM;
}
@@ -881,11 +919,7 @@ static void cinergyt2_disconnect (struct usb_interface *intf)
if (down_interruptible(&cinergyt2->sem))
return;
-#ifdef ENABLE_RC
- cancel_delayed_work(&cinergyt2->rc_query_work);
- flush_scheduled_work();
- input_unregister_device(&cinergyt2->rc_input_dev);
-#endif
+ cinergyt2_unregister_rc(cinergyt2);
cinergyt2->demux.dmx.close(&cinergyt2->demux.dmx);
dvb_net_release(&cinergyt2->dvbnet);
@@ -908,9 +942,8 @@ static int cinergyt2_suspend (struct usb_interface *intf, pm_message_t state)
if (state.event > PM_EVENT_ON) {
struct cinergyt2 *cinergyt2 = usb_get_intfdata (intf);
-#ifdef ENABLE_RC
- cancel_delayed_work(&cinergyt2->rc_query_work);
-#endif
+
+ cinergyt2_suspend_rc(cinergyt2);
cancel_delayed_work(&cinergyt2->query_work);
if (cinergyt2->streaming)
cinergyt2_stop_stream_xfer(cinergyt2);
@@ -938,9 +971,8 @@ static int cinergyt2_resume (struct usb_interface *intf)
schedule_delayed_work(&cinergyt2->query_work, HZ/2);
}
-#ifdef ENABLE_RC
- schedule_delayed_work(&cinergyt2->rc_query_work, HZ/2);
-#endif
+ cinergyt2_resume_rc(cinergyt2);
+
up(&cinergyt2->sem);
return 0;
}
diff --git a/drivers/media/dvb/dvb-core/demux.h b/drivers/media/dvb/dvb-core/demux.h
index 9719a3b30f78..7d7b0067f228 100644
--- a/drivers/media/dvb/dvb-core/demux.h
+++ b/drivers/media/dvb/dvb-core/demux.h
@@ -48,8 +48,11 @@
* DMX_MAX_SECFEED_SIZE: Maximum length (in bytes) of a private section feed filter.
*/
+#ifndef DMX_MAX_SECTION_SIZE
+#define DMX_MAX_SECTION_SIZE 4096
+#endif
#ifndef DMX_MAX_SECFEED_SIZE
-#define DMX_MAX_SECFEED_SIZE 4096
+#define DMX_MAX_SECFEED_SIZE (DMX_MAX_SECTION_SIZE + 188)
#endif
diff --git a/drivers/media/dvb/dvb-core/dvb_ca_en50221.c b/drivers/media/dvb/dvb-core/dvb_ca_en50221.c
index 88757e2634e5..2aa767f9bd7d 100644
--- a/drivers/media/dvb/dvb-core/dvb_ca_en50221.c
+++ b/drivers/media/dvb/dvb-core/dvb_ca_en50221.c
@@ -36,6 +36,7 @@
#include <linux/vmalloc.h>
#include <linux/delay.h>
#include <linux/rwsem.h>
+#include <linux/sched.h>
#include "dvb_ca_en50221.h"
#include "dvb_ringbuffer.h"
diff --git a/drivers/media/dvb/dvb-core/dvb_demux.c b/drivers/media/dvb/dvb-core/dvb_demux.c
index dc476dda2b71..b4c899b15959 100644
--- a/drivers/media/dvb/dvb-core/dvb_demux.c
+++ b/drivers/media/dvb/dvb-core/dvb_demux.c
@@ -246,7 +246,7 @@ static int dvb_dmx_swfilter_section_copy_dump(struct dvb_demux_feed *feed,
for (n = 0; sec->secbufp + 2 < limit; n++) {
seclen = section_length(sec->secbuf);
- if (seclen <= 0 || seclen > DMX_MAX_SECFEED_SIZE
+ if (seclen <= 0 || seclen > DMX_MAX_SECTION_SIZE
|| seclen + sec->secbufp > limit)
return 0;
sec->seclen = seclen;
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c
index a8bc84240b50..6ffa6b216363 100644
--- a/drivers/media/dvb/dvb-core/dvb_frontend.c
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.c
@@ -42,8 +42,6 @@
#include "dvb_frontend.h"
#include "dvbdev.h"
-// #define DEBUG_LOCKLOSS 1
-
static int dvb_frontend_debug;
static int dvb_shutdown_timeout = 5;
static int dvb_force_auto_inversion;
@@ -438,25 +436,6 @@ static int dvb_frontend_thread(void *data)
if (s & FE_HAS_LOCK)
continue;
else { /* if we _WERE_ tuned, but now don't have a lock */
-#ifdef DEBUG_LOCKLOSS
- /* first of all try setting the tone again if it was on - this
- * sometimes works around problems with noisy power supplies */
- if (fe->ops->set_tone && (fepriv->tone == SEC_TONE_ON)) {
- fe->ops->set_tone(fe, fepriv->tone);
- mdelay(100);
- s = 0;
- fe->ops->read_status(fe, &s);
- if (s & FE_HAS_LOCK) {
- printk("DVB%i: Lock was lost, but regained by setting "
- "the tone. This may indicate your power supply "
- "is noisy/slightly incompatable with this DVB-S "
- "adapter\n", fe->dvb->num);
- fepriv->state = FESTATE_TUNED;
- continue;
- }
- }
-#endif
- /* some other reason for losing the lock - start zigzagging */
fepriv->state = FESTATE_ZIGZAG_FAST;
fepriv->started_auto_step = fepriv->auto_step;
check_wrapped = 0;
@@ -577,6 +556,49 @@ static void dvb_frontend_stop(struct dvb_frontend *fe)
fepriv->thread_pid);
}
+s32 timeval_usec_diff(struct timeval lasttime, struct timeval curtime)
+{
+ return ((curtime.tv_usec < lasttime.tv_usec) ?
+ 1000000 - lasttime.tv_usec + curtime.tv_usec :
+ curtime.tv_usec - lasttime.tv_usec);
+}
+EXPORT_SYMBOL(timeval_usec_diff);
+
+static inline void timeval_usec_add(struct timeval *curtime, u32 add_usec)
+{
+ curtime->tv_usec += add_usec;
+ if (curtime->tv_usec >= 1000000) {
+ curtime->tv_usec -= 1000000;
+ curtime->tv_sec++;
+ }
+}
+
+/*
+ * Sleep until gettimeofday() > waketime + add_usec
+ * This needs to be as precise as possible, but as the delay is
+ * usually between 2ms and 32ms, it is done using a scheduled msleep
+ * followed by usleep (normally a busy-wait loop) for the remainder
+ */
+void dvb_frontend_sleep_until(struct timeval *waketime, u32 add_usec)
+{
+ struct timeval lasttime;
+ s32 delta, newdelta;
+
+ timeval_usec_add(waketime, add_usec);
+
+ do_gettimeofday(&lasttime);
+ delta = timeval_usec_diff(lasttime, *waketime);
+ if (delta > 2500) {
+ msleep((delta - 1500) / 1000);
+ do_gettimeofday(&lasttime);
+ newdelta = timeval_usec_diff(lasttime, *waketime);
+ delta = (newdelta > delta) ? 0 : newdelta;
+ }
+ if (delta > 0)
+ udelay(delta);
+}
+EXPORT_SYMBOL(dvb_frontend_sleep_until);
+
static int dvb_frontend_start(struct dvb_frontend *fe)
{
int ret;
@@ -728,6 +750,60 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file,
err = fe->ops->dishnetwork_send_legacy_command(fe, (unsigned int) parg);
fepriv->state = FESTATE_DISEQC;
fepriv->status = 0;
+ } else if (fe->ops->set_voltage) {
+ /*
+ * NOTE: This is a fallback condition. Some frontends
+ * (stv0299 for instance) take longer than 8msec to
+ * respond to a set_voltage command. Those switches
+ * need custom routines to switch properly. For all
+ * other frontends, the following shoule work ok.
+ * Dish network legacy switches (as used by Dish500)
+ * are controlled by sending 9-bit command words
+ * spaced 8msec apart.
+ * the actual command word is switch/port dependant
+ * so it is up to the userspace application to send
+ * the right command.
+ * The command must always start with a '0' after
+ * initialization, so parg is 8 bits and does not
+ * include the initialization or start bit
+ */
+ unsigned int cmd = ((unsigned int) parg) << 1;
+ struct timeval nexttime;
+ struct timeval tv[10];
+ int i;
+ u8 last = 1;
+ if (dvb_frontend_debug)
+ printk("%s switch command: 0x%04x\n", __FUNCTION__, cmd);
+ do_gettimeofday(&nexttime);
+ if (dvb_frontend_debug)
+ memcpy(&tv[0], &nexttime, sizeof(struct timeval));
+ /* before sending a command, initialize by sending
+ * a 32ms 18V to the switch
+ */
+ fe->ops->set_voltage(fe, SEC_VOLTAGE_18);
+ dvb_frontend_sleep_until(&nexttime, 32000);
+
+ for (i = 0; i < 9; i++) {
+ if (dvb_frontend_debug)
+ do_gettimeofday(&tv[i + 1]);
+ if ((cmd & 0x01) != last) {
+ /* set voltage to (last ? 13V : 18V) */
+ fe->ops->set_voltage(fe, (last) ? SEC_VOLTAGE_13 : SEC_VOLTAGE_18);
+ last = (last) ? 0 : 1;
+ }
+ cmd = cmd >> 1;
+ if (i != 8)
+ dvb_frontend_sleep_until(&nexttime, 8000);
+ }
+ if (dvb_frontend_debug) {
+ printk("%s(%d): switch delay (should be 32k followed by all 8k\n",
+ __FUNCTION__, fe->dvb->num);
+ for (i = 1; i < 10; i++)
+ printk("%d: %d\n", i, timeval_usec_diff(tv[i-1] , tv[i]));
+ }
+ err = 0;
+ fepriv->state = FESTATE_DISEQC;
+ fepriv->status = 0;
}
break;
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.h b/drivers/media/dvb/dvb-core/dvb_frontend.h
index 9c2c1d1136bd..348c9b0b988a 100644
--- a/drivers/media/dvb/dvb-core/dvb_frontend.h
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.h
@@ -101,4 +101,7 @@ extern int dvb_register_frontend(struct dvb_adapter* dvb,
extern int dvb_unregister_frontend(struct dvb_frontend* fe);
+extern void dvb_frontend_sleep_until(struct timeval *waketime, u32 add_usec);
+extern s32 timeval_usec_diff(struct timeval lasttime, struct timeval curtime);
+
#endif
diff --git a/drivers/media/dvb/dvb-core/dvbdev.c b/drivers/media/dvb/dvb-core/dvbdev.c
index 4b7adca3e286..477b4fa56430 100644
--- a/drivers/media/dvb/dvb-core/dvbdev.c
+++ b/drivers/media/dvb/dvb-core/dvbdev.c
@@ -235,7 +235,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
S_IFCHR | S_IRUSR | S_IWUSR,
"dvb/adapter%d/%s%d", adap->num, dnames[type], id);
- class_device_create(dvb_class, MKDEV(DVB_MAJOR, nums2minor(adap->num, type, id)),
+ class_device_create(dvb_class, NULL, MKDEV(DVB_MAJOR, nums2minor(adap->num, type, id)),
NULL, "dvb%d.%s%d", adap->num, dnames[type], id);
dprintk("DVB: register adapter%d/%s%d @ minor: %i (0x%02x)\n",
diff --git a/drivers/media/dvb/dvb-usb/a800.c b/drivers/media/dvb/dvb-usb/a800.c
index e55322ef76b3..49f541d9a042 100644
--- a/drivers/media/dvb/dvb-usb/a800.c
+++ b/drivers/media/dvb/dvb-usb/a800.c
@@ -43,11 +43,9 @@ static struct dvb_usb_rc_key a800_rc_keys[] = {
{ 0x02, 0x13, KEY_RIGHT }, /* R / CH RTN */
{ 0x02, 0x17, KEY_PROG2 }, /* SNAP SHOT */
{ 0x02, 0x10, KEY_PROG3 }, /* 16-CH PREV */
- { 0x02, 0x03, KEY_CHANNELUP }, /* CH UP */
{ 0x02, 0x1e, KEY_VOLUMEDOWN }, /* VOL DOWN */
{ 0x02, 0x0c, KEY_ZOOM }, /* FULL SCREEN */
{ 0x02, 0x1f, KEY_VOLUMEUP }, /* VOL UP */
- { 0x02, 0x02, KEY_CHANNELDOWN }, /* CH DOWN */
{ 0x02, 0x14, KEY_MUTE }, /* MUTE */
{ 0x02, 0x08, KEY_AUDIO }, /* AUDIO */
{ 0x02, 0x19, KEY_RECORD }, /* RECORD */
@@ -57,8 +55,6 @@ static struct dvb_usb_rc_key a800_rc_keys[] = {
{ 0x02, 0x1d, KEY_BACK }, /* << / RED */
{ 0x02, 0x1c, KEY_FORWARD }, /* >> / YELLOW */
{ 0x02, 0x03, KEY_TEXT }, /* TELETEXT */
- { 0x02, 0x01, KEY_FIRST }, /* |<< / GREEN */
- { 0x02, 0x00, KEY_LAST }, /* >>| / BLUE */
{ 0x02, 0x04, KEY_EPG }, /* EPG */
{ 0x02, 0x15, KEY_MENU }, /* MENU */
diff --git a/drivers/media/dvb/dvb-usb/dibusb-mb.c b/drivers/media/dvb/dvb-usb/dibusb-mb.c
index 0058505634a0..aa271a2496d5 100644
--- a/drivers/media/dvb/dvb-usb/dibusb-mb.c
+++ b/drivers/media/dvb/dvb-usb/dibusb-mb.c
@@ -82,13 +82,15 @@ static int dibusb_tuner_probe_and_attach(struct dvb_usb_device *d)
static struct dvb_usb_properties dibusb1_1_properties;
static struct dvb_usb_properties dibusb1_1_an2235_properties;
static struct dvb_usb_properties dibusb2_0b_properties;
+static struct dvb_usb_properties artec_t1_usb2_properties;
static int dibusb_probe(struct usb_interface *intf,
const struct usb_device_id *id)
{
if (dvb_usb_device_init(intf,&dibusb1_1_properties,THIS_MODULE,NULL) == 0 ||
dvb_usb_device_init(intf,&dibusb1_1_an2235_properties,THIS_MODULE,NULL) == 0 ||
- dvb_usb_device_init(intf,&dibusb2_0b_properties,THIS_MODULE,NULL) == 0)
+ dvb_usb_device_init(intf,&dibusb2_0b_properties,THIS_MODULE,NULL) == 0 ||
+ dvb_usb_device_init(intf,&artec_t1_usb2_properties,THIS_MODULE,NULL) == 0)
return 0;
return -EINVAL;
@@ -128,10 +130,13 @@ static struct usb_device_id dibusb_dib3000mb_table [] = {
/* 27 */ { USB_DEVICE(USB_VID_KWORLD, USB_PID_KWORLD_VSTREAM_COLD) },
+/* 28 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_USB2_COLD) },
+/* 29 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_USB2_WARM) },
+
// #define DVB_USB_DIBUSB_MB_FAULTY_USB_IDs
#ifdef DVB_USB_DIBUSB_MB_FAULTY_USB_IDs
-/* 28 */ { USB_DEVICE(USB_VID_ANCHOR, USB_PID_ULTIMA_TVBOX_ANCHOR_COLD) },
+/* 30 */ { USB_DEVICE(USB_VID_ANCHOR, USB_PID_ULTIMA_TVBOX_ANCHOR_COLD) },
#endif
{ } /* Terminating entry */
};
@@ -264,7 +269,7 @@ static struct dvb_usb_properties dibusb1_1_an2235_properties = {
},
#ifdef DVB_USB_DIBUSB_MB_FAULTY_USB_IDs
{ "Artec T1 USB1.1 TVBOX with AN2235 (faulty USB IDs)",
- { &dibusb_dib3000mb_table[28], NULL },
+ { &dibusb_dib3000mb_table[30], NULL },
{ NULL },
},
#endif
@@ -273,7 +278,7 @@ static struct dvb_usb_properties dibusb1_1_an2235_properties = {
static struct dvb_usb_properties dibusb2_0b_properties = {
.caps = DVB_USB_HAS_PID_FILTER | DVB_USB_PID_FILTER_CAN_BE_TURNED_OFF | DVB_USB_IS_AN_I2C_ADAPTER,
- .pid_filter_count = 32,
+ .pid_filter_count = 16,
.usb_ctrl = CYPRESS_FX2,
@@ -321,6 +326,52 @@ static struct dvb_usb_properties dibusb2_0b_properties = {
}
};
+static struct dvb_usb_properties artec_t1_usb2_properties = {
+ .caps = DVB_USB_HAS_PID_FILTER | DVB_USB_PID_FILTER_CAN_BE_TURNED_OFF | DVB_USB_IS_AN_I2C_ADAPTER,
+ .pid_filter_count = 16,
+
+ .usb_ctrl = CYPRESS_FX2,
+
+ .firmware = "dvb-usb-dibusb-6.0.0.8.fw",
+
+ .size_of_priv = sizeof(struct dibusb_state),
+
+ .streaming_ctrl = dibusb2_0_streaming_ctrl,
+ .pid_filter = dibusb_pid_filter,
+ .pid_filter_ctrl = dibusb_pid_filter_ctrl,
+ .power_ctrl = dibusb2_0_power_ctrl,
+ .frontend_attach = dibusb_dib3000mb_frontend_attach,
+ .tuner_attach = dibusb_tuner_probe_and_attach,
+
+ .rc_interval = DEFAULT_RC_INTERVAL,
+ .rc_key_map = dibusb_rc_keys,
+ .rc_key_map_size = 63, /* wow, that is ugly ... I want to load it to the driver dynamically */
+ .rc_query = dibusb_rc_query,
+
+ .i2c_algo = &dibusb_i2c_algo,
+
+ .generic_bulk_ctrl_endpoint = 0x01,
+ /* parameter for the MPEG2-data transfer */
+ .urb = {
+ .type = DVB_USB_BULK,
+ .count = 7,
+ .endpoint = 0x06,
+ .u = {
+ .bulk = {
+ .buffersize = 4096,
+ }
+ }
+ },
+
+ .num_device_descs = 1,
+ .devices = {
+ { "Artec T1 USB2.0",
+ { &dibusb_dib3000mb_table[28], NULL },
+ { &dibusb_dib3000mb_table[29], NULL },
+ },
+ }
+};
+
static struct usb_driver dibusb_driver = {
.owner = THIS_MODULE,
.name = "dvb_usb_dibusb_mb",
diff --git a/drivers/media/dvb/dvb-usb/dibusb.h b/drivers/media/dvb/dvb-usb/dibusb.h
index 6611f62977c0..2d99d05c7eab 100644
--- a/drivers/media/dvb/dvb-usb/dibusb.h
+++ b/drivers/media/dvb/dvb-usb/dibusb.h
@@ -11,7 +11,9 @@
#ifndef _DVB_USB_DIBUSB_H_
#define _DVB_USB_DIBUSB_H_
-#define DVB_USB_LOG_PREFIX "dibusb"
+#ifndef DVB_USB_LOG_PREFIX
+ #define DVB_USB_LOG_PREFIX "dibusb"
+#endif
#include "dvb-usb.h"
#include "dib3000.h"
diff --git a/drivers/media/dvb/dvb-usb/dtt200u.c b/drivers/media/dvb/dvb-usb/dtt200u.c
index 5aa12ebab34f..b595476332cd 100644
--- a/drivers/media/dvb/dvb-usb/dtt200u.c
+++ b/drivers/media/dvb/dvb-usb/dtt200u.c
@@ -151,7 +151,7 @@ static struct dvb_usb_properties dtt200u_properties = {
.cold_ids = { &dtt200u_usb_table[0], NULL },
.warm_ids = { &dtt200u_usb_table[1], NULL },
},
- { 0 },
+ { NULL },
}
};
@@ -192,7 +192,7 @@ static struct dvb_usb_properties wt220u_properties = {
.cold_ids = { &dtt200u_usb_table[2], NULL },
.warm_ids = { &dtt200u_usb_table[3], NULL },
},
- { 0 },
+ { NULL },
}
};
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
index 0818996bf150..6be99e537e12 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
@@ -43,10 +43,14 @@
#define USB_PID_COMPRO_DVBU2000_WARM 0xd001
#define USB_PID_COMPRO_DVBU2000_UNK_COLD 0x010c
#define USB_PID_COMPRO_DVBU2000_UNK_WARM 0x010d
+#define USB_PID_DIBCOM_HOOK_DEFAULT 0x0064
+#define USB_PID_DIBCOM_HOOK_DEFAULT_REENUM 0x0065
#define USB_PID_DIBCOM_MOD3000_COLD 0x0bb8
#define USB_PID_DIBCOM_MOD3000_WARM 0x0bb9
#define USB_PID_DIBCOM_MOD3001_COLD 0x0bc6
#define USB_PID_DIBCOM_MOD3001_WARM 0x0bc7
+#define USB_PID_DIBCOM_STK7700 0x1e14
+#define USB_PID_DIBCOM_STK7700_REENUM 0x1e15
#define USB_PID_DIBCOM_ANCHOR_2135_COLD 0x2131
#define USB_PID_GRANDTEC_DVBT_USB_COLD 0x0fa0
#define USB_PID_GRANDTEC_DVBT_USB_WARM 0x0fa1
@@ -68,6 +72,7 @@
#define USB_PID_ULTIMA_TVBOX_AN2235_WARM 0x8108
#define USB_PID_ULTIMA_TVBOX_ANCHOR_COLD 0x2235
#define USB_PID_ULTIMA_TVBOX_USB2_COLD 0x8109
+#define USB_PID_ULTIMA_TVBOX_USB2_WARM 0x810a
#define USB_PID_ULTIMA_TVBOX_USB2_FX_COLD 0x8613
#define USB_PID_ULTIMA_TVBOX_USB2_FX_WARM 0x1002
#define USB_PID_UNK_HYPER_PALTEK_COLD 0x005e
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-remote.c b/drivers/media/dvb/dvb-usb/dvb-usb-remote.c
index fc7800f1743e..e5c6d9835e06 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-remote.c
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-remote.c
@@ -39,9 +39,9 @@ static void dvb_usb_read_remote_control(void *data)
d->last_event = event;
case REMOTE_KEY_REPEAT:
deb_rc("key repeated\n");
- input_event(&d->rc_input_dev, EV_KEY, d->last_event, 1);
- input_event(&d->rc_input_dev, EV_KEY, d->last_event, 0);
- input_sync(&d->rc_input_dev);
+ input_event(d->rc_input_dev, EV_KEY, event, 1);
+ input_event(d->rc_input_dev, EV_KEY, d->last_event, 0);
+ input_sync(d->rc_input_dev);
break;
default:
break;
@@ -53,8 +53,8 @@ static void dvb_usb_read_remote_control(void *data)
deb_rc("NO KEY PRESSED\n");
if (d->last_state != REMOTE_NO_KEY_PRESSED) {
deb_rc("releasing event %d\n",d->last_event);
- input_event(&d->rc_input_dev, EV_KEY, d->last_event, 0);
- input_sync(&d->rc_input_dev);
+ input_event(d->rc_input_dev, EV_KEY, d->last_event, 0);
+ input_sync(d->rc_input_dev);
}
d->last_state = REMOTE_NO_KEY_PRESSED;
d->last_event = 0;
@@ -63,8 +63,8 @@ static void dvb_usb_read_remote_control(void *data)
deb_rc("KEY PRESSED\n");
deb_rc("pressing event %d\n",event);
- input_event(&d->rc_input_dev, EV_KEY, event, 1);
- input_sync(&d->rc_input_dev);
+ input_event(d->rc_input_dev, EV_KEY, event, 1);
+ input_sync(d->rc_input_dev);
d->last_event = event;
d->last_state = REMOTE_KEY_PRESSED;
@@ -73,8 +73,8 @@ static void dvb_usb_read_remote_control(void *data)
deb_rc("KEY_REPEAT\n");
if (d->last_state != REMOTE_NO_KEY_PRESSED) {
deb_rc("repeating event %d\n",d->last_event);
- input_event(&d->rc_input_dev, EV_KEY, d->last_event, 2);
- input_sync(&d->rc_input_dev);
+ input_event(d->rc_input_dev, EV_KEY, d->last_event, 2);
+ input_sync(d->rc_input_dev);
d->last_state = REMOTE_KEY_REPEAT;
}
default:
@@ -89,24 +89,30 @@ schedule:
int dvb_usb_remote_init(struct dvb_usb_device *d)
{
int i;
+
if (d->props.rc_key_map == NULL ||
d->props.rc_query == NULL ||
dvb_usb_disable_rc_polling)
return 0;
- /* Initialise the remote-control structures.*/
- init_input_dev(&d->rc_input_dev);
+ usb_make_path(d->udev, d->rc_phys, sizeof(d->rc_phys));
+ strlcpy(d->rc_phys, "/ir0", sizeof(d->rc_phys));
+
+ d->rc_input_dev = input_allocate_device();
+ if (!d->rc_input_dev)
+ return -ENOMEM;
- d->rc_input_dev.evbit[0] = BIT(EV_KEY);
- d->rc_input_dev.keycodesize = sizeof(unsigned char);
- d->rc_input_dev.keycodemax = KEY_MAX;
- d->rc_input_dev.name = "IR-receiver inside an USB DVB receiver";
+ d->rc_input_dev->evbit[0] = BIT(EV_KEY);
+ d->rc_input_dev->keycodesize = sizeof(unsigned char);
+ d->rc_input_dev->keycodemax = KEY_MAX;
+ d->rc_input_dev->name = "IR-receiver inside an USB DVB receiver";
+ d->rc_input_dev->phys = d->rc_phys;
/* set the bits for the keys */
- deb_rc("key map size: %d\n",d->props.rc_key_map_size);
+ deb_rc("key map size: %d\n", d->props.rc_key_map_size);
for (i = 0; i < d->props.rc_key_map_size; i++) {
deb_rc("setting bit for event %d item %d\n",d->props.rc_key_map[i].event, i);
- set_bit(d->props.rc_key_map[i].event, d->rc_input_dev.keybit);
+ set_bit(d->props.rc_key_map[i].event, d->rc_input_dev->keybit);
}
/* Start the remote-control polling. */
@@ -114,14 +120,14 @@ int dvb_usb_remote_init(struct dvb_usb_device *d)
d->props.rc_interval = 100; /* default */
/* setting these two values to non-zero, we have to manage key repeats */
- d->rc_input_dev.rep[REP_PERIOD] = d->props.rc_interval;
- d->rc_input_dev.rep[REP_DELAY] = d->props.rc_interval + 150;
+ d->rc_input_dev->rep[REP_PERIOD] = d->props.rc_interval;
+ d->rc_input_dev->rep[REP_DELAY] = d->props.rc_interval + 150;
- input_register_device(&d->rc_input_dev);
+ input_register_device(d->rc_input_dev);
INIT_WORK(&d->rc_query_work, dvb_usb_read_remote_control, d);
- info("schedule remote query interval to %d msecs.",d->props.rc_interval);
+ info("schedule remote query interval to %d msecs.", d->props.rc_interval);
schedule_delayed_work(&d->rc_query_work,msecs_to_jiffies(d->props.rc_interval));
d->state |= DVB_USB_STATE_REMOTE;
@@ -134,7 +140,7 @@ int dvb_usb_remote_exit(struct dvb_usb_device *d)
if (d->state & DVB_USB_STATE_REMOTE) {
cancel_delayed_work(&d->rc_query_work);
flush_scheduled_work();
- input_unregister_device(&d->rc_input_dev);
+ input_unregister_device(d->rc_input_dev);
}
d->state &= ~DVB_USB_STATE_REMOTE;
return 0;
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-urb.c b/drivers/media/dvb/dvb-usb/dvb-usb-urb.c
index f5799a4c228e..36b7048c02d2 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-urb.c
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-urb.c
@@ -196,7 +196,9 @@ static int dvb_usb_allocate_stream_buffers(struct dvb_usb_device *d, int num, un
dvb_usb_free_stream_buffers(d);
return -ENOMEM;
}
- deb_mem("buffer %d: %p (dma: %d)\n",d->buf_num,d->buf_list[d->buf_num],d->dma_addr[d->buf_num]);
+ deb_mem("buffer %d: %p (dma: %llu)\n",
+ d->buf_num, d->buf_list[d->buf_num],
+ (unsigned long long)d->dma_addr[d->buf_num]);
memset(d->buf_list[d->buf_num],0,size);
}
deb_mem("allocation successful\n");
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb.h b/drivers/media/dvb/dvb-usb/dvb-usb.h
index 0e4f1035b0dd..b4a1a98006c7 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb.h
+++ b/drivers/media/dvb/dvb-usb/dvb-usb.h
@@ -300,7 +300,8 @@ struct dvb_usb_device {
int (*fe_init) (struct dvb_frontend *);
/* remote control */
- struct input_dev rc_input_dev;
+ struct input_dev *rc_input_dev;
+ char rc_phys[64];
struct work_struct rc_query_work;
u32 last_event;
int last_state;
diff --git a/drivers/media/dvb/dvb-usb/vp7045.c b/drivers/media/dvb/dvb-usb/vp7045.c
index 0f57abeb6d6b..75765e3a569c 100644
--- a/drivers/media/dvb/dvb-usb/vp7045.c
+++ b/drivers/media/dvb/dvb-usb/vp7045.c
@@ -247,7 +247,7 @@ static struct dvb_usb_properties vp7045_properties = {
.cold_ids = { &vp7045_usb_table[2], NULL },
.warm_ids = { &vp7045_usb_table[3], NULL },
},
- { 0 },
+ { NULL },
}
};
diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig
index a50a41f6f79d..8e269e1c1f9d 100644
--- a/drivers/media/dvb/frontends/Kconfig
+++ b/drivers/media/dvb/frontends/Kconfig
@@ -164,6 +164,14 @@ config DVB_NXT2002
help
An ATSC 8VSB tuner module. Say Y when you want to support this frontend.
+config DVB_NXT200X
+ tristate "Nextwave NXT2002/NXT2004 based"
+ depends on DVB_CORE
+ select FW_LOADER
+ help
+ An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
+ to support this frontend.
+
config DVB_OR51211
tristate "or51211 based (pcHDTV HD2000 card)"
depends on DVB_CORE
diff --git a/drivers/media/dvb/frontends/Makefile b/drivers/media/dvb/frontends/Makefile
index ad8658ffd60a..a98760fe08a1 100644
--- a/drivers/media/dvb/frontends/Makefile
+++ b/drivers/media/dvb/frontends/Makefile
@@ -26,6 +26,7 @@ obj-$(CONFIG_DVB_TDA80XX) += tda80xx.o
obj-$(CONFIG_DVB_TDA10021) += tda10021.o
obj-$(CONFIG_DVB_STV0297) += stv0297.o
obj-$(CONFIG_DVB_NXT2002) += nxt2002.o
+obj-$(CONFIG_DVB_NXT200X) += nxt200x.o
obj-$(CONFIG_DVB_OR51211) += or51211.o
obj-$(CONFIG_DVB_OR51132) += or51132.o
obj-$(CONFIG_DVB_BCM3510) += bcm3510.o
diff --git a/drivers/media/dvb/frontends/bcm3510.c b/drivers/media/dvb/frontends/bcm3510.c
index f5fdc5c3e605..f6d4ee78bdd4 100644
--- a/drivers/media/dvb/frontends/bcm3510.c
+++ b/drivers/media/dvb/frontends/bcm3510.c
@@ -36,6 +36,9 @@
#include <linux/moduleparam.h>
#include <linux/device.h>
#include <linux/firmware.h>
+#include <linux/jiffies.h>
+#include <linux/string.h>
+#include <linux/slab.h>
#include "dvb_frontend.h"
#include "bcm3510.h"
diff --git a/drivers/media/dvb/frontends/cx24110.c b/drivers/media/dvb/frontends/cx24110.c
index d4b97989e3ed..654d7dc879d9 100644
--- a/drivers/media/dvb/frontends/cx24110.c
+++ b/drivers/media/dvb/frontends/cx24110.c
@@ -27,6 +27,7 @@
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>
+#include <linux/jiffies.h>
#include "dvb_frontend.h"
#include "cx24110.h"
diff --git a/drivers/media/dvb/frontends/dib3000mb.c b/drivers/media/dvb/frontends/dib3000mb.c
index 21433e1831e7..6b0553608610 100644
--- a/drivers/media/dvb/frontends/dib3000mb.c
+++ b/drivers/media/dvb/frontends/dib3000mb.c
@@ -27,6 +27,8 @@
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/delay.h>
+#include <linux/string.h>
+#include <linux/slab.h>
#include "dib3000-common.h"
#include "dib3000mb_priv.h"
diff --git a/drivers/media/dvb/frontends/dib3000mc.c b/drivers/media/dvb/frontends/dib3000mc.c
index 441de665fec3..c024fad17337 100644
--- a/drivers/media/dvb/frontends/dib3000mc.c
+++ b/drivers/media/dvb/frontends/dib3000mc.c
@@ -26,6 +26,8 @@
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/delay.h>
+#include <linux/string.h>
+#include <linux/slab.h>
#include "dib3000-common.h"
#include "dib3000mc_priv.h"
diff --git a/drivers/media/dvb/frontends/dvb-pll.c b/drivers/media/dvb/frontends/dvb-pll.c
index 536c35d969b7..f857b869616c 100644
--- a/drivers/media/dvb/frontends/dvb-pll.c
+++ b/drivers/media/dvb/frontends/dvb-pll.c
@@ -226,7 +226,7 @@ struct dvb_pll_desc dvb_pll_tua6034 = {
EXPORT_SYMBOL(dvb_pll_tua6034);
/* Infineon TUA6034
- * used in LG Innotek TDVS-H062F
+ * used in LG TDVS H061F and LG TDVS H062F
*/
struct dvb_pll_desc dvb_pll_tdvs_tua6034 = {
.name = "LG/Infineon TUA6034",
@@ -292,6 +292,58 @@ struct dvb_pll_desc dvb_pll_tded4 = {
};
EXPORT_SYMBOL(dvb_pll_tded4);
+/* ALPS TDHU2
+ * used in AverTVHD MCE A180
+ */
+struct dvb_pll_desc dvb_pll_tdhu2 = {
+ .name = "ALPS TDHU2",
+ .min = 54000000,
+ .max = 864000000,
+ .count = 4,
+ .entries = {
+ { 162000000, 44000000, 62500, 0x85, 0x01 },
+ { 426000000, 44000000, 62500, 0x85, 0x02 },
+ { 782000000, 44000000, 62500, 0x85, 0x08 },
+ { 999999999, 44000000, 62500, 0x85, 0x88 },
+ }
+};
+EXPORT_SYMBOL(dvb_pll_tdhu2);
+
+/* Philips TUV1236D
+ * used in ATI HDTV Wonder
+ */
+struct dvb_pll_desc dvb_pll_tuv1236d = {
+ .name = "Philips TUV1236D",
+ .min = 54000000,
+ .max = 864000000,
+ .count = 3,
+ .entries = {
+ { 157250000, 44000000, 62500, 0xc6, 0x41 },
+ { 454000000, 44000000, 62500, 0xc6, 0x42 },
+ { 999999999, 44000000, 62500, 0xc6, 0x44 },
+ },
+};
+EXPORT_SYMBOL(dvb_pll_tuv1236d);
+
+/* Samsung TBMV30111IN
+ * used in Air2PC ATSC - 2nd generation (nxt2002)
+ */
+struct dvb_pll_desc dvb_pll_tbmv30111in = {
+ .name = "Samsung TBMV30111IN",
+ .min = 54000000,
+ .max = 860000000,
+ .count = 4,
+ .entries = {
+ { 172000000, 44000000, 166666, 0xb4, 0x01 },
+ { 214000000, 44000000, 166666, 0xb4, 0x02 },
+ { 467000000, 44000000, 166666, 0xbc, 0x02 },
+ { 721000000, 44000000, 166666, 0xbc, 0x08 },
+ { 841000000, 44000000, 166666, 0xf4, 0x08 },
+ { 999999999, 44000000, 166666, 0xfc, 0x02 },
+ }
+};
+EXPORT_SYMBOL(dvb_pll_tbmv30111in);
+
/* ----------------------------------------------------------- */
/* code */
diff --git a/drivers/media/dvb/frontends/dvb-pll.h b/drivers/media/dvb/frontends/dvb-pll.h
index 205b2d1a8852..497d31dcf41e 100644
--- a/drivers/media/dvb/frontends/dvb-pll.h
+++ b/drivers/media/dvb/frontends/dvb-pll.h
@@ -36,6 +36,10 @@ extern struct dvb_pll_desc dvb_pll_tda665x;
extern struct dvb_pll_desc dvb_pll_fmd1216me;
extern struct dvb_pll_desc dvb_pll_tded4;
+extern struct dvb_pll_desc dvb_pll_tuv1236d;
+extern struct dvb_pll_desc dvb_pll_tdhu2;
+extern struct dvb_pll_desc dvb_pll_tbmv30111in;
+
int dvb_pll_configure(struct dvb_pll_desc *desc, u8 *buf,
u32 freq, int bandwidth);
diff --git a/drivers/media/dvb/frontends/dvb_dummy_fe.c b/drivers/media/dvb/frontends/dvb_dummy_fe.c
index cff93b9d8ab2..645946a992d9 100644
--- a/drivers/media/dvb/frontends/dvb_dummy_fe.c
+++ b/drivers/media/dvb/frontends/dvb_dummy_fe.c
@@ -22,6 +22,8 @@
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>
+#include <linux/string.h>
+#include <linux/slab.h>
#include "dvb_frontend.h"
#include "dvb_dummy_fe.h"
@@ -146,7 +148,7 @@ struct dvb_frontend* dvb_dummy_fe_qpsk_attach()
return &state->frontend;
error:
- if (state) kfree(state);
+ kfree(state);
return NULL;
}
@@ -169,7 +171,7 @@ struct dvb_frontend* dvb_dummy_fe_qam_attach()
return &state->frontend;
error:
- if (state) kfree(state);
+ kfree(state);
return NULL;
}
diff --git a/drivers/media/dvb/frontends/l64781.c b/drivers/media/dvb/frontends/l64781.c
index faaad1ae8559..19b4bf7c21a7 100644
--- a/drivers/media/dvb/frontends/l64781.c
+++ b/drivers/media/dvb/frontends/l64781.c
@@ -559,7 +559,8 @@ struct dvb_frontend* l64781_attach(const struct l64781_config* config,
return &state->frontend;
error:
- if (reg0x3e >= 0) l64781_writereg (state, 0x3e, reg0x3e); /* restore reg 0x3e */
+ if (reg0x3e >= 0)
+ l64781_writereg (state, 0x3e, reg0x3e); /* restore reg 0x3e */
kfree(state);
return NULL;
}
diff --git a/drivers/media/dvb/frontends/lgdt330x.c b/drivers/media/dvb/frontends/lgdt330x.c
index 7142b9c51dd2..6a33f5a19a8d 100644
--- a/drivers/media/dvb/frontends/lgdt330x.c
+++ b/drivers/media/dvb/frontends/lgdt330x.c
@@ -26,6 +26,8 @@
* DViCO FusionHDTV 3 Gold-Q
* DViCO FusionHDTV 3 Gold-T
* DViCO FusionHDTV 5 Gold
+ * DViCO FusionHDTV 5 Lite
+ * Air2PC/AirStar 2 ATSC 3rd generation (HD5000)
*
* TODO:
* signal strength always returns 0.
@@ -37,6 +39,8 @@
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/delay.h>
+#include <linux/string.h>
+#include <linux/slab.h>
#include <asm/byteorder.h>
#include "dvb_frontend.h"
@@ -220,6 +224,11 @@ static int lgdt330x_init(struct dvb_frontend* fe)
0x4c, 0x14
};
+ static u8 flip_lgdt3303_init_data[] = {
+ 0x4c, 0x14,
+ 0x87, 0xf3
+ };
+
struct lgdt330x_state* state = fe->demodulator_priv;
char *chip_name;
int err;
@@ -232,8 +241,13 @@ static int lgdt330x_init(struct dvb_frontend* fe)
break;
case LGDT3303:
chip_name = "LGDT3303";
- err = i2c_write_demod_bytes(state, lgdt3303_init_data,
- sizeof(lgdt3303_init_data));
+ if (state->config->clock_polarity_flip) {
+ err = i2c_write_demod_bytes(state, flip_lgdt3303_init_data,
+ sizeof(flip_lgdt3303_init_data));
+ } else {
+ err = i2c_write_demod_bytes(state, lgdt3303_init_data,
+ sizeof(lgdt3303_init_data));
+ }
break;
default:
chip_name = "undefined";
@@ -729,8 +743,7 @@ struct dvb_frontend* lgdt330x_attach(const struct lgdt330x_config* config,
return &state->frontend;
error:
- if (state)
- kfree(state);
+ kfree(state);
dprintk("%s: ERROR\n",__FUNCTION__);
return NULL;
}
@@ -742,9 +755,8 @@ static struct dvb_frontend_ops lgdt3302_ops = {
.frequency_min= 54000000,
.frequency_max= 858000000,
.frequency_stepsize= 62500,
- /* Symbol rate is for all VSB modes need to check QAM */
- .symbol_rate_min = 10762000,
- .symbol_rate_max = 10762000,
+ .symbol_rate_min = 5056941, /* QAM 64 */
+ .symbol_rate_max = 10762000, /* VSB 8 */
.caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB
},
.init = lgdt330x_init,
@@ -766,9 +778,8 @@ static struct dvb_frontend_ops lgdt3303_ops = {
.frequency_min= 54000000,
.frequency_max= 858000000,
.frequency_stepsize= 62500,
- /* Symbol rate is for all VSB modes need to check QAM */
- .symbol_rate_min = 10762000,
- .symbol_rate_max = 10762000,
+ .symbol_rate_min = 5056941, /* QAM 64 */
+ .symbol_rate_max = 10762000, /* VSB 8 */
.caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB
},
.init = lgdt330x_init,
diff --git a/drivers/media/dvb/frontends/lgdt330x.h b/drivers/media/dvb/frontends/lgdt330x.h
index e209ba1e47c5..2a6529cccf1a 100644
--- a/drivers/media/dvb/frontends/lgdt330x.h
+++ b/drivers/media/dvb/frontends/lgdt330x.h
@@ -47,6 +47,10 @@ struct lgdt330x_config
/* Need to set device param for start_dma */
int (*set_ts_params)(struct dvb_frontend* fe, int is_punctured);
+
+ /* Flip the polarity of the mpeg data transfer clock using alternate init data
+ * This option applies ONLY to LGDT3303 - 0:disabled (default) 1:enabled */
+ int clock_polarity_flip;
};
extern struct dvb_frontend* lgdt330x_attach(const struct lgdt330x_config* config,
diff --git a/drivers/media/dvb/frontends/mt312.c b/drivers/media/dvb/frontends/mt312.c
index e455aecd76b2..9c67f406d581 100644
--- a/drivers/media/dvb/frontends/mt312.c
+++ b/drivers/media/dvb/frontends/mt312.c
@@ -29,6 +29,8 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
+#include <linux/string.h>
+#include <linux/slab.h>
#include "dvb_frontend.h"
#include "mt312_priv.h"
@@ -675,8 +677,7 @@ struct dvb_frontend* mt312_attach(const struct mt312_config* config,
return &state->frontend;
error:
- if (state)
- kfree(state);
+ kfree(state);
return NULL;
}
diff --git a/drivers/media/dvb/frontends/mt352.c b/drivers/media/dvb/frontends/mt352.c
index cc1bc0edd65e..f0c610f2c2df 100644
--- a/drivers/media/dvb/frontends/mt352.c
+++ b/drivers/media/dvb/frontends/mt352.c
@@ -35,6 +35,8 @@
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/delay.h>
+#include <linux/string.h>
+#include <linux/slab.h>
#include "dvb_frontend.h"
#include "mt352_priv.h"
diff --git a/drivers/media/dvb/frontends/nxt2002.c b/drivers/media/dvb/frontends/nxt2002.c
index 35a1d60f1927..30786b1911bd 100644
--- a/drivers/media/dvb/frontends/nxt2002.c
+++ b/drivers/media/dvb/frontends/nxt2002.c
@@ -32,6 +32,8 @@
#include <linux/moduleparam.h>
#include <linux/device.h>
#include <linux/firmware.h>
+#include <linux/string.h>
+#include <linux/slab.h>
#include "dvb_frontend.h"
#include "nxt2002.h"
diff --git a/drivers/media/dvb/frontends/nxt200x.c b/drivers/media/dvb/frontends/nxt200x.c
new file mode 100644
index 000000000000..bad0933eb714
--- /dev/null
+++ b/drivers/media/dvb/frontends/nxt200x.c
@@ -0,0 +1,1205 @@
+/*
+ * Support for NXT2002 and NXT2004 - VSB/QAM
+ *
+ * Copyright (C) 2005 Kirk Lapray (kirk.lapray@gmail.com)
+ * based on nxt2002 by Taylor Jacob <rtjacob@earthlink.net>
+ * and nxt2004 by Jean-Francois Thibert (jeanfrancois@sagetv.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.
+ *
+*/
+
+/*
+ * NOTES ABOUT THIS DRIVER
+ *
+ * This Linux driver supports:
+ * B2C2/BBTI Technisat Air2PC - ATSC (NXT2002)
+ * AverTVHD MCE A180 (NXT2004)
+ * ATI HDTV Wonder (NXT2004)
+ *
+ * This driver needs external firmware. Please use the command
+ * "<kerneldir>/Documentation/dvb/get_dvb_firmware nxt2002" or
+ * "<kerneldir>/Documentation/dvb/get_dvb_firmware nxt2004" to
+ * download/extract the appropriate firmware, and then copy it to
+ * /usr/lib/hotplug/firmware/ or /lib/firmware/
+ * (depending on configuration of firmware hotplug).
+ */
+#define NXT2002_DEFAULT_FIRMWARE "dvb-fe-nxt2002.fw"
+#define NXT2004_DEFAULT_FIRMWARE "dvb-fe-nxt2004.fw"
+#define CRC_CCIT_MASK 0x1021
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+
+#include "dvb_frontend.h"
+#include "dvb-pll.h"
+#include "nxt200x.h"
+
+struct nxt200x_state {
+
+ struct i2c_adapter* i2c;
+ struct dvb_frontend_ops ops;
+ const struct nxt200x_config* config;
+ struct dvb_frontend frontend;
+
+ /* demodulator private data */
+ nxt_chip_type demod_chip;
+ u8 initialised:1;
+};
+
+static int debug;
+#define dprintk(args...) \
+ do { \
+ if (debug) printk(KERN_DEBUG "nxt200x: " args); \
+ } while (0)
+
+static int i2c_writebytes (struct nxt200x_state* state, u8 addr, u8 *buf, u8 len)
+{
+ int err;
+ struct i2c_msg msg = { .addr = addr, .flags = 0, .buf = buf, .len = len };
+
+ if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
+ printk (KERN_WARNING "nxt200x: %s: i2c write error (addr 0x%02x, err == %i)\n",
+ __FUNCTION__, addr, err);
+ return -EREMOTEIO;
+ }
+ return 0;
+}
+
+static u8 i2c_readbytes (struct nxt200x_state* state, u8 addr, u8* buf, u8 len)
+{
+ int err;
+ struct i2c_msg msg = { .addr = addr, .flags = I2C_M_RD, .buf = buf, .len = len };
+
+ if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
+ printk (KERN_WARNING "nxt200x: %s: i2c read error (addr 0x%02x, err == %i)\n",
+ __FUNCTION__, addr, err);
+ return -EREMOTEIO;
+ }
+ return 0;
+}
+
+static int nxt200x_writebytes (struct nxt200x_state* state, u8 reg, u8 *buf, u8 len)
+{
+ u8 buf2 [len+1];
+ int err;
+ struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf2, .len = len + 1 };
+
+ buf2[0] = reg;
+ memcpy(&buf2[1], buf, len);
+
+ if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
+ printk (KERN_WARNING "nxt200x: %s: i2c write error (addr 0x%02x, err == %i)\n",
+ __FUNCTION__, state->config->demod_address, err);
+ return -EREMOTEIO;
+ }
+ return 0;
+}
+
+static u8 nxt200x_readbytes (struct nxt200x_state* state, u8 reg, u8* buf, u8 len)
+{
+ u8 reg2 [] = { reg };
+
+ struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = reg2, .len = 1 },
+ { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = buf, .len = len } };
+
+ int err;
+
+ if ((err = i2c_transfer (state->i2c, msg, 2)) != 2) {
+ printk (KERN_WARNING "nxt200x: %s: i2c read error (addr 0x%02x, err == %i)\n",
+ __FUNCTION__, state->config->demod_address, err);
+ return -EREMOTEIO;
+ }
+ return 0;
+}
+
+static u16 nxt200x_crc(u16 crc, u8 c)
+{
+ u8 i;
+ u16 input = (u16) c & 0xFF;
+
+ input<<=8;
+ for(i=0; i<8; i++) {
+ if((crc^input) & 0x8000)
+ crc=(crc<<1)^CRC_CCIT_MASK;
+ else
+ crc<<=1;
+ input<<=1;
+ }
+ return crc;
+}
+
+static int nxt200x_writereg_multibyte (struct nxt200x_state* state, u8 reg, u8* data, u8 len)
+{
+ u8 attr, len2, buf;
+ dprintk("%s\n", __FUNCTION__);
+
+ /* set mutli register register */
+ nxt200x_writebytes(state, 0x35, &reg, 1);
+
+ /* send the actual data */
+ nxt200x_writebytes(state, 0x36, data, len);
+
+ switch (state->demod_chip) {
+ case NXT2002:
+ len2 = len;
+ buf = 0x02;
+ break;
+ case NXT2004:
+ /* probably not right, but gives correct values */
+ attr = 0x02;
+ if (reg & 0x80) {
+ attr = attr << 1;
+ if (reg & 0x04)
+ attr = attr >> 1;
+ }
+ /* set write bit */
+ len2 = ((attr << 4) | 0x10) | len;
+ buf = 0x80;
+ break;
+ default:
+ return -EINVAL;
+ break;
+ }
+
+ /* set multi register length */
+ nxt200x_writebytes(state, 0x34, &len2, 1);
+
+ /* toggle the multireg write bit */
+ nxt200x_writebytes(state, 0x21, &buf, 1);
+
+ nxt200x_readbytes(state, 0x21, &buf, 1);
+
+ switch (state->demod_chip) {
+ case NXT2002:
+ if ((buf & 0x02) == 0)
+ return 0;
+ break;
+ case NXT2004:
+ if (buf == 0)
+ return 0;
+ break;
+ default:
+ return -EINVAL;
+ break;
+ }
+
+ printk(KERN_WARNING "nxt200x: Error writing multireg register 0x%02X\n",reg);
+
+ return 0;
+}
+
+static int nxt200x_readreg_multibyte (struct nxt200x_state* state, u8 reg, u8* data, u8 len)
+{
+ int i;
+ u8 buf, len2, attr;
+ dprintk("%s\n", __FUNCTION__);
+
+ /* set mutli register register */
+ nxt200x_writebytes(state, 0x35, &reg, 1);
+
+ switch (state->demod_chip) {
+ case NXT2002:
+ /* set multi register length */
+ len2 = len & 0x80;
+ nxt200x_writebytes(state, 0x34, &len2, 1);
+
+ /* read the actual data */
+ nxt200x_readbytes(state, reg, data, len);
+ return 0;
+ break;
+ case NXT2004:
+ /* probably not right, but gives correct values */
+ attr = 0x02;
+ if (reg & 0x80) {
+ attr = attr << 1;
+ if (reg & 0x04)
+ attr = attr >> 1;
+ }
+
+ /* set multi register length */
+ len2 = (attr << 4) | len;
+ nxt200x_writebytes(state, 0x34, &len2, 1);
+
+ /* toggle the multireg bit*/
+ buf = 0x80;
+ nxt200x_writebytes(state, 0x21, &buf, 1);
+
+ /* read the actual data */
+ for(i = 0; i < len; i++) {
+ nxt200x_readbytes(state, 0x36 + i, &data[i], 1);
+ }
+ return 0;
+ break;
+ default:
+ return -EINVAL;
+ break;
+ }
+}
+
+static void nxt200x_microcontroller_stop (struct nxt200x_state* state)
+{
+ u8 buf, stopval, counter = 0;
+ dprintk("%s\n", __FUNCTION__);
+
+ /* set correct stop value */
+ switch (state->demod_chip) {
+ case NXT2002:
+ stopval = 0x40;
+ break;
+ case NXT2004:
+ stopval = 0x10;
+ break;
+ default:
+ stopval = 0;
+ break;
+ }
+
+ buf = 0x80;
+ nxt200x_writebytes(state, 0x22, &buf, 1);
+
+ while (counter < 20) {
+ nxt200x_readbytes(state, 0x31, &buf, 1);
+ if (buf & stopval)
+ return;
+ msleep(10);
+ counter++;
+ }
+
+ printk(KERN_WARNING "nxt200x: Timeout waiting for nxt200x to stop. This is ok after firmware upload.\n");
+ return;
+}
+
+static void nxt200x_microcontroller_start (struct nxt200x_state* state)
+{
+ u8 buf;
+ dprintk("%s\n", __FUNCTION__);
+
+ buf = 0x00;
+ nxt200x_writebytes(state, 0x22, &buf, 1);
+}
+
+static void nxt2004_microcontroller_init (struct nxt200x_state* state)
+{
+ u8 buf[9];
+ u8 counter = 0;
+ dprintk("%s\n", __FUNCTION__);
+
+ buf[0] = 0x00;
+ nxt200x_writebytes(state, 0x2b, buf, 1);
+ buf[0] = 0x70;
+ nxt200x_writebytes(state, 0x34, buf, 1);
+ buf[0] = 0x04;
+ nxt200x_writebytes(state, 0x35, buf, 1);
+ buf[0] = 0x01; buf[1] = 0x23; buf[2] = 0x45; buf[3] = 0x67; buf[4] = 0x89;
+ buf[5] = 0xAB; buf[6] = 0xCD; buf[7] = 0xEF; buf[8] = 0xC0;
+ nxt200x_writebytes(state, 0x36, buf, 9);
+ buf[0] = 0x80;
+ nxt200x_writebytes(state, 0x21, buf, 1);
+
+ while (counter < 20) {
+ nxt200x_readbytes(state, 0x21, buf, 1);
+ if (buf[0] == 0)
+ return;
+ msleep(10);
+ counter++;
+ }
+
+ printk(KERN_WARNING "nxt200x: Timeout waiting for nxt2004 to init.\n");
+
+ return;
+}
+
+static int nxt200x_writetuner (struct nxt200x_state* state, u8* data)
+{
+ u8 buf, count = 0;
+
+ dprintk("%s\n", __FUNCTION__);
+
+ dprintk("Tuner Bytes: %02X %02X %02X %02X\n", data[0], data[1], data[2], data[3]);
+
+ /* if NXT2004, write directly to tuner. if NXT2002, write through NXT chip.
+ * direct write is required for Philips TUV1236D and ALPS TDHU2 */
+ switch (state->demod_chip) {
+ case NXT2004:
+ if (i2c_writebytes(state, state->config->pll_address, data, 4))
+ printk(KERN_WARNING "nxt200x: error writing to tuner\n");
+ /* wait until we have a lock */
+ while (count < 20) {
+ i2c_readbytes(state, state->config->pll_address, &buf, 1);
+ if (buf & 0x40)
+ return 0;
+ msleep(100);
+ count++;
+ }
+ printk("nxt2004: timeout waiting for tuner lock\n");
+ break;
+ case NXT2002:
+ /* set the i2c transfer speed to the tuner */
+ buf = 0x03;
+ nxt200x_writebytes(state, 0x20, &buf, 1);
+
+ /* setup to transfer 4 bytes via i2c */
+ buf = 0x04;
+ nxt200x_writebytes(state, 0x34, &buf, 1);
+
+ /* write actual tuner bytes */
+ nxt200x_writebytes(state, 0x36, data, 4);
+
+ /* set tuner i2c address */
+ buf = state->config->pll_address;
+ nxt200x_writebytes(state, 0x35, &buf, 1);
+
+ /* write UC Opmode to begin transfer */
+ buf = 0x80;
+ nxt200x_writebytes(state, 0x21, &buf, 1);
+
+ while (count < 20) {
+ nxt200x_readbytes(state, 0x21, &buf, 1);
+ if ((buf & 0x80)== 0x00)
+ return 0;
+ msleep(100);
+ count++;
+ }
+ printk("nxt2002: timeout error writing tuner\n");
+ break;
+ default:
+ return -EINVAL;
+ break;
+ }
+ return 0;
+}
+
+static void nxt200x_agc_reset(struct nxt200x_state* state)
+{
+ u8 buf;
+ dprintk("%s\n", __FUNCTION__);
+
+ switch (state->demod_chip) {
+ case NXT2002:
+ buf = 0x08;
+ nxt200x_writebytes(state, 0x08, &buf, 1);
+ buf = 0x00;
+ nxt200x_writebytes(state, 0x08, &buf, 1);
+ break;
+ case NXT2004:
+ nxt200x_readreg_multibyte(state, 0x08, &buf, 1);
+ buf = 0x08;
+ nxt200x_writereg_multibyte(state, 0x08, &buf, 1);
+ buf = 0x00;
+ nxt200x_writereg_multibyte(state, 0x08, &buf, 1);
+ break;
+ default:
+ break;
+ }
+ return;
+}
+
+static int nxt2002_load_firmware (struct dvb_frontend* fe, const struct firmware *fw)
+{
+
+ struct nxt200x_state* state = fe->demodulator_priv;
+ u8 buf[3], written = 0, chunkpos = 0;
+ u16 rambase, position, crc = 0;
+
+ dprintk("%s\n", __FUNCTION__);
+ dprintk("Firmware is %zu bytes\n", fw->size);
+
+ /* Get the RAM base for this nxt2002 */
+ nxt200x_readbytes(state, 0x10, buf, 1);
+
+ if (buf[0] & 0x10)
+ rambase = 0x1000;
+ else
+ rambase = 0x0000;
+
+ dprintk("rambase on this nxt2002 is %04X\n", rambase);
+
+ /* Hold the micro in reset while loading firmware */
+ buf[0] = 0x80;
+ nxt200x_writebytes(state, 0x2B, buf, 1);
+
+ for (position = 0; position < fw->size; position++) {
+ if (written == 0) {
+ crc = 0;
+ chunkpos = 0x28;
+ buf[0] = ((rambase + position) >> 8);
+ buf[1] = (rambase + position) & 0xFF;
+ buf[2] = 0x81;
+ /* write starting address */
+ nxt200x_writebytes(state, 0x29, buf, 3);
+ }
+ written++;
+ chunkpos++;
+
+ if ((written % 4) == 0)
+ nxt200x_writebytes(state, chunkpos, &fw->data[position-3], 4);
+
+ crc = nxt200x_crc(crc, fw->data[position]);
+
+ if ((written == 255) || (position+1 == fw->size)) {
+ /* write remaining bytes of firmware */
+ nxt200x_writebytes(state, chunkpos+4-(written %4),
+ &fw->data[position-(written %4) + 1],
+ written %4);
+ buf[0] = crc << 8;
+ buf[1] = crc & 0xFF;
+
+ /* write crc */
+ nxt200x_writebytes(state, 0x2C, buf, 2);
+
+ /* do a read to stop things */
+ nxt200x_readbytes(state, 0x2A, buf, 1);
+
+ /* set transfer mode to complete */
+ buf[0] = 0x80;
+ nxt200x_writebytes(state, 0x2B, buf, 1);
+
+ written = 0;
+ }
+ }
+
+ return 0;
+};
+
+static int nxt2004_load_firmware (struct dvb_frontend* fe, const struct firmware *fw)
+{
+
+ struct nxt200x_state* state = fe->demodulator_priv;
+ u8 buf[3];
+ u16 rambase, position, crc=0;
+
+ dprintk("%s\n", __FUNCTION__);
+ dprintk("Firmware is %zu bytes\n", fw->size);
+
+ /* set rambase */
+ rambase = 0x1000;
+
+ /* hold the micro in reset while loading firmware */
+ buf[0] = 0x80;
+ nxt200x_writebytes(state, 0x2B, buf,1);
+
+ /* calculate firmware CRC */
+ for (position = 0; position < fw->size; position++) {
+ crc = nxt200x_crc(crc, fw->data[position]);
+ }
+
+ buf[0] = rambase >> 8;
+ buf[1] = rambase & 0xFF;
+ buf[2] = 0x81;
+ /* write starting address */
+ nxt200x_writebytes(state,0x29,buf,3);
+
+ for (position = 0; position < fw->size;) {
+ nxt200x_writebytes(state, 0x2C, &fw->data[position],
+ fw->size-position > 255 ? 255 : fw->size-position);
+ position += (fw->size-position > 255 ? 255 : fw->size-position);
+ }
+ buf[0] = crc >> 8;
+ buf[1] = crc & 0xFF;
+
+ dprintk("firmware crc is 0x%02X 0x%02X\n", buf[0], buf[1]);
+
+ /* write crc */
+ nxt200x_writebytes(state, 0x2C, buf,2);
+
+ /* do a read to stop things */
+ nxt200x_readbytes(state, 0x2C, buf, 1);
+
+ /* set transfer mode to complete */
+ buf[0] = 0x80;
+ nxt200x_writebytes(state, 0x2B, buf,1);
+
+ return 0;
+};
+
+static int nxt200x_setup_frontend_parameters (struct dvb_frontend* fe,
+ struct dvb_frontend_parameters *p)
+{
+ struct nxt200x_state* state = fe->demodulator_priv;
+ u8 buf[4];
+
+ /* stop the micro first */
+ nxt200x_microcontroller_stop(state);
+
+ if (state->demod_chip == NXT2004) {
+ /* make sure demod is set to digital */
+ buf[0] = 0x04;
+ nxt200x_writebytes(state, 0x14, buf, 1);
+ buf[0] = 0x00;
+ nxt200x_writebytes(state, 0x17, buf, 1);
+ }
+
+ /* get tuning information */
+ dvb_pll_configure(state->config->pll_desc, buf, p->frequency, 0);
+
+ /* set additional params */
+ switch (p->u.vsb.modulation) {
+ case QAM_64:
+ case QAM_256:
+ /* Set punctured clock for QAM */
+ /* This is just a guess since I am unable to test it */
+ if (state->config->set_ts_params)
+ state->config->set_ts_params(fe, 1);
+
+ /* set input */
+ if (state->config->set_pll_input)
+ state->config->set_pll_input(buf, 1);
+ break;
+ case VSB_8:
+ /* Set non-punctured clock for VSB */
+ if (state->config->set_ts_params)
+ state->config->set_ts_params(fe, 0);
+
+ /* set input */
+ if (state->config->set_pll_input)
+ state->config->set_pll_input(buf, 0);
+ break;
+ default:
+ return -EINVAL;
+ break;
+ }
+
+ /* write frequency information */
+ nxt200x_writetuner(state, buf);
+
+ /* reset the agc now that tuning has been completed */
+ nxt200x_agc_reset(state);
+
+ /* set target power level */
+ switch (p->u.vsb.modulation) {
+ case QAM_64:
+ case QAM_256:
+ buf[0] = 0x74;
+ break;
+ case VSB_8:
+ buf[0] = 0x70;
+ break;
+ default:
+ return -EINVAL;
+ break;
+ }
+ nxt200x_writebytes(state, 0x42, buf, 1);
+
+ /* configure sdm */
+ switch (state->demod_chip) {
+ case NXT2002:
+ buf[0] = 0x87;
+ break;
+ case NXT2004:
+ buf[0] = 0x07;
+ break;
+ default:
+ return -EINVAL;
+ break;
+ }
+ nxt200x_writebytes(state, 0x57, buf, 1);
+
+ /* write sdm1 input */
+ buf[0] = 0x10;
+ buf[1] = 0x00;
+ nxt200x_writebytes(state, 0x58, buf, 2);
+
+ /* write sdmx input */
+ switch (p->u.vsb.modulation) {
+ case QAM_64:
+ buf[0] = 0x68;
+ break;
+ case QAM_256:
+ buf[0] = 0x64;
+ break;
+ case VSB_8:
+ buf[0] = 0x60;
+ break;
+ default:
+ return -EINVAL;
+ break;
+ }
+ buf[1] = 0x00;
+ nxt200x_writebytes(state, 0x5C, buf, 2);
+
+ /* write adc power lpf fc */
+ buf[0] = 0x05;
+ nxt200x_writebytes(state, 0x43, buf, 1);
+
+ if (state->demod_chip == NXT2004) {
+ /* write ??? */
+ buf[0] = 0x00;
+ buf[1] = 0x00;
+ nxt200x_writebytes(state, 0x46, buf, 2);
+ }
+
+ /* write accumulator2 input */
+ buf[0] = 0x80;
+ buf[1] = 0x00;
+ nxt200x_writebytes(state, 0x4B, buf, 2);
+
+ /* write kg1 */
+ buf[0] = 0x00;
+ nxt200x_writebytes(state, 0x4D, buf, 1);
+
+ /* write sdm12 lpf fc */
+ buf[0] = 0x44;
+ nxt200x_writebytes(state, 0x55, buf, 1);
+
+ /* write agc control reg */
+ buf[0] = 0x04;
+ nxt200x_writebytes(state, 0x41, buf, 1);
+
+ if (state->demod_chip == NXT2004) {
+ nxt200x_readreg_multibyte(state, 0x80, buf, 1);
+ buf[0] = 0x24;
+ nxt200x_writereg_multibyte(state, 0x80, buf, 1);
+
+ /* soft reset? */
+ nxt200x_readreg_multibyte(state, 0x08, buf, 1);
+ buf[0] = 0x10;
+ nxt200x_writereg_multibyte(state, 0x08, buf, 1);
+ nxt200x_readreg_multibyte(state, 0x08, buf, 1);
+ buf[0] = 0x00;
+ nxt200x_writereg_multibyte(state, 0x08, buf, 1);
+
+ nxt200x_readreg_multibyte(state, 0x80, buf, 1);
+ buf[0] = 0x04;
+ nxt200x_writereg_multibyte(state, 0x80, buf, 1);
+ buf[0] = 0x00;
+ nxt200x_writereg_multibyte(state, 0x81, buf, 1);
+ buf[0] = 0x80; buf[1] = 0x00; buf[2] = 0x00;
+ nxt200x_writereg_multibyte(state, 0x82, buf, 3);
+ nxt200x_readreg_multibyte(state, 0x88, buf, 1);
+ buf[0] = 0x11;
+ nxt200x_writereg_multibyte(state, 0x88, buf, 1);
+ nxt200x_readreg_multibyte(state, 0x80, buf, 1);
+ buf[0] = 0x44;
+ nxt200x_writereg_multibyte(state, 0x80, buf, 1);
+ }
+
+ /* write agc ucgp0 */
+ switch (p->u.vsb.modulation) {
+ case QAM_64:
+ buf[0] = 0x02;
+ break;
+ case QAM_256:
+ buf[0] = 0x03;
+ break;
+ case VSB_8:
+ buf[0] = 0x00;
+ break;
+ default:
+ return -EINVAL;
+ break;
+ }
+ nxt200x_writebytes(state, 0x30, buf, 1);
+
+ /* write agc control reg */
+ buf[0] = 0x00;
+ nxt200x_writebytes(state, 0x41, buf, 1);
+
+ /* write accumulator2 input */
+ buf[0] = 0x80;
+ buf[1] = 0x00;
+ nxt200x_writebytes(state, 0x49, buf,2);
+ nxt200x_writebytes(state, 0x4B, buf,2);
+
+ /* write agc control reg */
+ buf[0] = 0x04;
+ nxt200x_writebytes(state, 0x41, buf, 1);
+
+ nxt200x_microcontroller_start(state);
+
+ if (state->demod_chip == NXT2004) {
+ nxt2004_microcontroller_init(state);
+
+ /* ???? */
+ buf[0] = 0xF0;
+ buf[1] = 0x00;
+ nxt200x_writebytes(state, 0x5C, buf, 2);
+ }
+
+ /* adjacent channel detection should be done here, but I don't
+ have any stations with this need so I cannot test it */
+
+ return 0;
+}
+
+static int nxt200x_read_status(struct dvb_frontend* fe, fe_status_t* status)
+{
+ struct nxt200x_state* state = fe->demodulator_priv;
+ u8 lock;
+ nxt200x_readbytes(state, 0x31, &lock, 1);
+
+ *status = 0;
+ if (lock & 0x20) {
+ *status |= FE_HAS_SIGNAL;
+ *status |= FE_HAS_CARRIER;
+ *status |= FE_HAS_VITERBI;
+ *status |= FE_HAS_SYNC;
+ *status |= FE_HAS_LOCK;
+ }
+ return 0;
+}
+
+static int nxt200x_read_ber(struct dvb_frontend* fe, u32* ber)
+{
+ struct nxt200x_state* state = fe->demodulator_priv;
+ u8 b[3];
+
+ nxt200x_readreg_multibyte(state, 0xE6, b, 3);
+
+ *ber = ((b[0] << 8) + b[1]) * 8;
+
+ return 0;
+}
+
+static int nxt200x_read_signal_strength(struct dvb_frontend* fe, u16* strength)
+{
+ struct nxt200x_state* state = fe->demodulator_priv;
+ u8 b[2];
+ u16 temp = 0;
+
+ /* setup to read cluster variance */
+ b[0] = 0x00;
+ nxt200x_writebytes(state, 0xA1, b, 1);
+
+ /* get multreg val */
+ nxt200x_readreg_multibyte(state, 0xA6, b, 2);
+
+ temp = (b[0] << 8) | b[1];
+ *strength = ((0x7FFF - temp) & 0x0FFF) * 16;
+
+ return 0;
+}
+
+static int nxt200x_read_snr(struct dvb_frontend* fe, u16* snr)
+{
+
+ struct nxt200x_state* state = fe->demodulator_priv;
+ u8 b[2];
+ u16 temp = 0, temp2;
+ u32 snrdb = 0;
+
+ /* setup to read cluster variance */
+ b[0] = 0x00;
+ nxt200x_writebytes(state, 0xA1, b, 1);
+
+ /* get multreg val from 0xA6 */
+ nxt200x_readreg_multibyte(state, 0xA6, b, 2);
+
+ temp = (b[0] << 8) | b[1];
+ temp2 = 0x7FFF - temp;
+
+ /* snr will be in db */
+ if (temp2 > 0x7F00)
+ snrdb = 1000*24 + ( 1000*(30-24) * ( temp2 - 0x7F00 ) / ( 0x7FFF - 0x7F00 ) );
+ else if (temp2 > 0x7EC0)
+ snrdb = 1000*18 + ( 1000*(24-18) * ( temp2 - 0x7EC0 ) / ( 0x7F00 - 0x7EC0 ) );
+ else if (temp2 > 0x7C00)
+ snrdb = 1000*12 + ( 1000*(18-12) * ( temp2 - 0x7C00 ) / ( 0x7EC0 - 0x7C00 ) );
+ else
+ snrdb = 1000*0 + ( 1000*(12-0) * ( temp2 - 0 ) / ( 0x7C00 - 0 ) );
+
+ /* the value reported back from the frontend will be FFFF=32db 0000=0db */
+ *snr = snrdb * (0xFFFF/32000);
+
+ return 0;
+}
+
+static int nxt200x_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
+{
+ struct nxt200x_state* state = fe->demodulator_priv;
+ u8 b[3];
+
+ nxt200x_readreg_multibyte(state, 0xE6, b, 3);
+ *ucblocks = b[2];
+
+ return 0;
+}
+
+static int nxt200x_sleep(struct dvb_frontend* fe)
+{
+ return 0;
+}
+
+static int nxt2002_init(struct dvb_frontend* fe)
+{
+ struct nxt200x_state* state = fe->demodulator_priv;
+ const struct firmware *fw;
+ int ret;
+ u8 buf[2];
+
+ /* request the firmware, this will block until someone uploads it */
+ printk("nxt2002: Waiting for firmware upload (%s)...\n", NXT2002_DEFAULT_FIRMWARE);
+ ret = request_firmware(&fw, NXT2002_DEFAULT_FIRMWARE, &state->i2c->dev);
+ printk("nxt2002: Waiting for firmware upload(2)...\n");
+ if (ret) {
+ printk("nxt2002: No firmware uploaded (timeout or file not found?)\n");
+ return ret;
+ }
+
+ ret = nxt2002_load_firmware(fe, fw);
+ if (ret) {
+ printk("nxt2002: Writing firmware to device failed\n");
+ release_firmware(fw);
+ return ret;
+ }
+ printk("nxt2002: Firmware upload complete\n");
+
+ /* Put the micro into reset */
+ nxt200x_microcontroller_stop(state);
+
+ /* ensure transfer is complete */
+ buf[0]=0x00;
+ nxt200x_writebytes(state, 0x2B, buf, 1);
+
+ /* Put the micro into reset for real this time */
+ nxt200x_microcontroller_stop(state);
+
+ /* soft reset everything (agc,frontend,eq,fec)*/
+ buf[0] = 0x0F;
+ nxt200x_writebytes(state, 0x08, buf, 1);
+ buf[0] = 0x00;
+ nxt200x_writebytes(state, 0x08, buf, 1);
+
+ /* write agc sdm configure */
+ buf[0] = 0xF1;
+ nxt200x_writebytes(state, 0x57, buf, 1);
+
+ /* write mod output format */
+ buf[0] = 0x20;
+ nxt200x_writebytes(state, 0x09, buf, 1);
+
+ /* write fec mpeg mode */
+ buf[0] = 0x7E;
+ buf[1] = 0x00;
+ nxt200x_writebytes(state, 0xE9, buf, 2);
+
+ /* write mux selection */
+ buf[0] = 0x00;
+ nxt200x_writebytes(state, 0xCC, buf, 1);
+
+ return 0;
+}
+
+static int nxt2004_init(struct dvb_frontend* fe)
+{
+ struct nxt200x_state* state = fe->demodulator_priv;
+ const struct firmware *fw;
+ int ret;
+ u8 buf[3];
+
+ /* ??? */
+ buf[0]=0x00;
+ nxt200x_writebytes(state, 0x1E, buf, 1);
+
+ /* request the firmware, this will block until someone uploads it */
+ printk("nxt2004: Waiting for firmware upload (%s)...\n", NXT2004_DEFAULT_FIRMWARE);
+ ret = request_firmware(&fw, NXT2004_DEFAULT_FIRMWARE, &state->i2c->dev);
+ printk("nxt2004: Waiting for firmware upload(2)...\n");
+ if (ret) {
+ printk("nxt2004: No firmware uploaded (timeout or file not found?)\n");
+ return ret;
+ }
+
+ ret = nxt2004_load_firmware(fe, fw);
+ if (ret) {
+ printk("nxt2004: Writing firmware to device failed\n");
+ release_firmware(fw);
+ return ret;
+ }
+ printk("nxt2004: Firmware upload complete\n");
+
+ /* ensure transfer is complete */
+ buf[0] = 0x01;
+ nxt200x_writebytes(state, 0x19, buf, 1);
+
+ nxt2004_microcontroller_init(state);
+ nxt200x_microcontroller_stop(state);
+ nxt200x_microcontroller_stop(state);
+ nxt2004_microcontroller_init(state);
+ nxt200x_microcontroller_stop(state);
+
+ /* soft reset everything (agc,frontend,eq,fec)*/
+ buf[0] = 0xFF;
+ nxt200x_writereg_multibyte(state, 0x08, buf, 1);
+ buf[0] = 0x00;
+ nxt200x_writereg_multibyte(state, 0x08, buf, 1);
+
+ /* write agc sdm configure */
+ buf[0] = 0xD7;
+ nxt200x_writebytes(state, 0x57, buf, 1);
+
+ /* ???*/
+ buf[0] = 0x07;
+ buf[1] = 0xfe;
+ nxt200x_writebytes(state, 0x35, buf, 2);
+ buf[0] = 0x12;
+ nxt200x_writebytes(state, 0x34, buf, 1);
+ buf[0] = 0x80;
+ nxt200x_writebytes(state, 0x21, buf, 1);
+
+ /* ???*/
+ buf[0] = 0x21;
+ nxt200x_writebytes(state, 0x0A, buf, 1);
+
+ /* ???*/
+ buf[0] = 0x01;
+ nxt200x_writereg_multibyte(state, 0x80, buf, 1);
+
+ /* write fec mpeg mode */
+ buf[0] = 0x7E;
+ buf[1] = 0x00;
+ nxt200x_writebytes(state, 0xE9, buf, 2);
+
+ /* write mux selection */
+ buf[0] = 0x00;
+ nxt200x_writebytes(state, 0xCC, buf, 1);
+
+ /* ???*/
+ nxt200x_readreg_multibyte(state, 0x80, buf, 1);
+ buf[0] = 0x00;
+ nxt200x_writereg_multibyte(state, 0x80, buf, 1);
+
+ /* soft reset? */
+ nxt200x_readreg_multibyte(state, 0x08, buf, 1);
+ buf[0] = 0x10;
+ nxt200x_writereg_multibyte(state, 0x08, buf, 1);
+ nxt200x_readreg_multibyte(state, 0x08, buf, 1);
+ buf[0] = 0x00;
+ nxt200x_writereg_multibyte(state, 0x08, buf, 1);
+
+ /* ???*/
+ nxt200x_readreg_multibyte(state, 0x80, buf, 1);
+ buf[0] = 0x01;
+ nxt200x_writereg_multibyte(state, 0x80, buf, 1);
+ buf[0] = 0x70;
+ nxt200x_writereg_multibyte(state, 0x81, buf, 1);
+ buf[0] = 0x31; buf[1] = 0x5E; buf[2] = 0x66;
+ nxt200x_writereg_multibyte(state, 0x82, buf, 3);
+
+ nxt200x_readreg_multibyte(state, 0x88, buf, 1);
+ buf[0] = 0x11;
+ nxt200x_writereg_multibyte(state, 0x88, buf, 1);
+ nxt200x_readreg_multibyte(state, 0x80, buf, 1);
+ buf[0] = 0x40;
+ nxt200x_writereg_multibyte(state, 0x80, buf, 1);
+
+ nxt200x_readbytes(state, 0x10, buf, 1);
+ buf[0] = 0x10;
+ nxt200x_writebytes(state, 0x10, buf, 1);
+ nxt200x_readbytes(state, 0x0A, buf, 1);
+ buf[0] = 0x21;
+ nxt200x_writebytes(state, 0x0A, buf, 1);
+
+ nxt2004_microcontroller_init(state);
+
+ buf[0] = 0x21;
+ nxt200x_writebytes(state, 0x0A, buf, 1);
+ buf[0] = 0x7E;
+ nxt200x_writebytes(state, 0xE9, buf, 1);
+ buf[0] = 0x00;
+ nxt200x_writebytes(state, 0xEA, buf, 1);
+
+ nxt200x_readreg_multibyte(state, 0x80, buf, 1);
+ buf[0] = 0x00;
+ nxt200x_writereg_multibyte(state, 0x80, buf, 1);
+ nxt200x_readreg_multibyte(state, 0x80, buf, 1);
+ buf[0] = 0x00;
+ nxt200x_writereg_multibyte(state, 0x80, buf, 1);
+
+ /* soft reset? */
+ nxt200x_readreg_multibyte(state, 0x08, buf, 1);
+ buf[0] = 0x10;
+ nxt200x_writereg_multibyte(state, 0x08, buf, 1);
+ nxt200x_readreg_multibyte(state, 0x08, buf, 1);
+ buf[0] = 0x00;
+ nxt200x_writereg_multibyte(state, 0x08, buf, 1);
+
+ nxt200x_readreg_multibyte(state, 0x80, buf, 1);
+ buf[0] = 0x04;
+ nxt200x_writereg_multibyte(state, 0x80, buf, 1);
+ buf[0] = 0x00;
+ nxt200x_writereg_multibyte(state, 0x81, buf, 1);
+ buf[0] = 0x80; buf[1] = 0x00; buf[2] = 0x00;
+ nxt200x_writereg_multibyte(state, 0x82, buf, 3);
+
+ nxt200x_readreg_multibyte(state, 0x88, buf, 1);
+ buf[0] = 0x11;
+ nxt200x_writereg_multibyte(state, 0x88, buf, 1);
+
+ nxt200x_readreg_multibyte(state, 0x80, buf, 1);
+ buf[0] = 0x44;
+ nxt200x_writereg_multibyte(state, 0x80, buf, 1);
+
+ /* initialize tuner */
+ nxt200x_readbytes(state, 0x10, buf, 1);
+ buf[0] = 0x12;
+ nxt200x_writebytes(state, 0x10, buf, 1);
+ buf[0] = 0x04;
+ nxt200x_writebytes(state, 0x13, buf, 1);
+ buf[0] = 0x00;
+ nxt200x_writebytes(state, 0x16, buf, 1);
+ buf[0] = 0x04;
+ nxt200x_writebytes(state, 0x14, buf, 1);
+ buf[0] = 0x00;
+ nxt200x_writebytes(state, 0x14, buf, 1);
+ nxt200x_writebytes(state, 0x17, buf, 1);
+ nxt200x_writebytes(state, 0x14, buf, 1);
+ nxt200x_writebytes(state, 0x17, buf, 1);
+
+ return 0;
+}
+
+static int nxt200x_init(struct dvb_frontend* fe)
+{
+ struct nxt200x_state* state = fe->demodulator_priv;
+ int ret = 0;
+
+ if (!state->initialised) {
+ switch (state->demod_chip) {
+ case NXT2002:
+ ret = nxt2002_init(fe);
+ break;
+ case NXT2004:
+ ret = nxt2004_init(fe);
+ break;
+ default:
+ return -EINVAL;
+ break;
+ }
+ state->initialised = 1;
+ }
+ return ret;
+}
+
+static int nxt200x_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings)
+{
+ fesettings->min_delay_ms = 500;
+ fesettings->step_size = 0;
+ fesettings->max_drift = 0;
+ return 0;
+}
+
+static void nxt200x_release(struct dvb_frontend* fe)
+{
+ struct nxt200x_state* state = fe->demodulator_priv;
+ kfree(state);
+}
+
+static struct dvb_frontend_ops nxt200x_ops;
+
+struct dvb_frontend* nxt200x_attach(const struct nxt200x_config* config,
+ struct i2c_adapter* i2c)
+{
+ struct nxt200x_state* state = NULL;
+ u8 buf [] = {0,0,0,0,0};
+
+ /* allocate memory for the internal state */
+ state = (struct nxt200x_state*) kmalloc(sizeof(struct nxt200x_state), GFP_KERNEL);
+ if (state == NULL)
+ goto error;
+ memset(state,0,sizeof(*state));
+
+ /* setup the state */
+ state->config = config;
+ state->i2c = i2c;
+ memcpy(&state->ops, &nxt200x_ops, sizeof(struct dvb_frontend_ops));
+ state->initialised = 0;
+
+ /* read card id */
+ nxt200x_readbytes(state, 0x00, buf, 5);
+ dprintk("NXT info: %02X %02X %02X %02X %02X\n",
+ buf[0], buf[1], buf[2], buf[3], buf[4]);
+
+ /* set demod chip */
+ switch (buf[0]) {
+ case 0x04:
+ state->demod_chip = NXT2002;
+ printk("nxt200x: NXT2002 Detected\n");
+ break;
+ case 0x05:
+ state->demod_chip = NXT2004;
+ printk("nxt200x: NXT2004 Detected\n");
+ break;
+ default:
+ goto error;
+ }
+
+ /* make sure demod chip is supported */
+ switch (state->demod_chip) {
+ case NXT2002:
+ if (buf[0] != 0x04) goto error; /* device id */
+ if (buf[1] != 0x02) goto error; /* fab id */
+ if (buf[2] != 0x11) goto error; /* month */
+ if (buf[3] != 0x20) goto error; /* year msb */
+ if (buf[4] != 0x00) goto error; /* year lsb */
+ break;
+ case NXT2004:
+ if (buf[0] != 0x05) goto error; /* device id */
+ break;
+ default:
+ goto error;
+ }
+
+ /* create dvb_frontend */
+ state->frontend.ops = &state->ops;
+ state->frontend.demodulator_priv = state;
+ return &state->frontend;
+
+error:
+ kfree(state);
+ printk("Unknown/Unsupported NXT chip: %02X %02X %02X %02X %02X\n",
+ buf[0], buf[1], buf[2], buf[3], buf[4]);
+ return NULL;
+}
+
+static struct dvb_frontend_ops nxt200x_ops = {
+
+ .info = {
+ .name = "Nextwave NXT200X VSB/QAM frontend",
+ .type = FE_ATSC,
+ .frequency_min = 54000000,
+ .frequency_max = 860000000,
+ .frequency_stepsize = 166666, /* stepsize is just a guess */
+ .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
+ FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
+ FE_CAN_8VSB | FE_CAN_QAM_64 | FE_CAN_QAM_256
+ },
+
+ .release = nxt200x_release,
+
+ .init = nxt200x_init,
+ .sleep = nxt200x_sleep,
+
+ .set_frontend = nxt200x_setup_frontend_parameters,
+ .get_tune_settings = nxt200x_get_tune_settings,
+
+ .read_status = nxt200x_read_status,
+ .read_ber = nxt200x_read_ber,
+ .read_signal_strength = nxt200x_read_signal_strength,
+ .read_snr = nxt200x_read_snr,
+ .read_ucblocks = nxt200x_read_ucblocks,
+};
+
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
+
+MODULE_DESCRIPTION("NXT200X (ATSC 8VSB & ITU-T J.83 AnnexB 64/256 QAM) Demodulator Driver");
+MODULE_AUTHOR("Kirk Lapray, Jean-Francois Thibert, and Taylor Jacob");
+MODULE_LICENSE("GPL");
+
+EXPORT_SYMBOL(nxt200x_attach);
+
diff --git a/drivers/media/dvb/frontends/nxt200x.h b/drivers/media/dvb/frontends/nxt200x.h
new file mode 100644
index 000000000000..1d9d70bc37ef
--- /dev/null
+++ b/drivers/media/dvb/frontends/nxt200x.h
@@ -0,0 +1,61 @@
+/*
+ * Support for NXT2002 and NXT2004 - VSB/QAM
+ *
+ * Copyright (C) 2005 Kirk Lapray (kirk.lapray@gmail.com)
+ * based on nxt2002 by Taylor Jacob <rtjacob@earthlink.net>
+ * and nxt2004 by Jean-Francois Thibert (jeanfrancois@sagetv.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 NXT200X_H
+#define NXT200X_H
+
+#include <linux/dvb/frontend.h>
+#include <linux/firmware.h>
+
+typedef enum nxt_chip_t {
+ NXTUNDEFINED,
+ NXT2002,
+ NXT2004
+}nxt_chip_type;
+
+struct nxt200x_config
+{
+ /* the demodulator's i2c address */
+ u8 demod_address;
+
+ /* tuner information */
+ u8 pll_address;
+ struct dvb_pll_desc *pll_desc;
+
+ /* used to set pll input */
+ int (*set_pll_input)(u8* buf, int input);
+
+ /* need to set device param for start_dma */
+ int (*set_ts_params)(struct dvb_frontend* fe, int is_punctured);
+};
+
+extern struct dvb_frontend* nxt200x_attach(const struct nxt200x_config* config,
+ struct i2c_adapter* i2c);
+
+#endif /* NXT200X_H */
+
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
diff --git a/drivers/media/dvb/frontends/or51132.c b/drivers/media/dvb/frontends/or51132.c
index b6d0eecc59eb..78bded861d02 100644
--- a/drivers/media/dvb/frontends/or51132.c
+++ b/drivers/media/dvb/frontends/or51132.c
@@ -36,6 +36,8 @@
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/delay.h>
+#include <linux/string.h>
+#include <linux/slab.h>
#include <asm/byteorder.h>
#include "dvb_frontend.h"
@@ -466,6 +468,7 @@ static int or51132_read_signal_strength(struct dvb_frontend* fe, u16* strength)
unsigned char snd_buf[2];
u8 rcvr_stat;
u16 snr_equ;
+ u32 signal_strength;
int usK;
snd_buf[0]=0x04;
@@ -501,7 +504,11 @@ static int or51132_read_signal_strength(struct dvb_frontend* fe, u16* strength)
usK = (rcvr_stat & 0x10) ? 3 : 0;
/* The value reported back from the frontend will be FFFF=100% 0000=0% */
- *strength = (((8952 - i20Log10(snr_equ) - usK*100)/3+5)*65535)/1000;
+ signal_strength = (((8952 - i20Log10(snr_equ) - usK*100)/3+5)*65535)/1000;
+ if (signal_strength > 0xffff)
+ *strength = 0xffff;
+ else
+ *strength = signal_strength;
dprintk("read_signal_strength %i\n",*strength);
return 0;
@@ -575,8 +582,7 @@ struct dvb_frontend* or51132_attach(const struct or51132_config* config,
return &state->frontend;
error:
- if (state)
- kfree(state);
+ kfree(state);
return NULL;
}
diff --git a/drivers/media/dvb/frontends/or51211.c b/drivers/media/dvb/frontends/or51211.c
index ad56a9958404..531f76246e5f 100644
--- a/drivers/media/dvb/frontends/or51211.c
+++ b/drivers/media/dvb/frontends/or51211.c
@@ -34,6 +34,8 @@
#include <linux/moduleparam.h>
#include <linux/device.h>
#include <linux/firmware.h>
+#include <linux/string.h>
+#include <linux/slab.h>
#include <asm/byteorder.h>
#include "dvb_frontend.h"
@@ -337,6 +339,7 @@ static int or51211_read_signal_strength(struct dvb_frontend* fe, u16* strength)
u8 rec_buf[2];
u8 snd_buf[4];
u8 snr_equ;
+ u32 signal_strength;
/* SNR after Equalizer */
snd_buf[0] = 0x04;
@@ -356,8 +359,11 @@ static int or51211_read_signal_strength(struct dvb_frontend* fe, u16* strength)
snr_equ = rec_buf[0] & 0xff;
/* The value reported back from the frontend will be FFFF=100% 0000=0% */
- *strength = (((5334 - i20Log10(snr_equ))/3+5)*65535)/1000;
-
+ signal_strength = (((5334 - i20Log10(snr_equ))/3+5)*65535)/1000;
+ if (signal_strength > 0xffff)
+ *strength = 0xffff;
+ else
+ *strength = signal_strength;
dprintk("read_signal_strength %i\n",*strength);
return 0;
diff --git a/drivers/media/dvb/frontends/s5h1420.c b/drivers/media/dvb/frontends/s5h1420.c
index c7fe27fd530c..f265418e3261 100644
--- a/drivers/media/dvb/frontends/s5h1420.c
+++ b/drivers/media/dvb/frontends/s5h1420.c
@@ -26,6 +26,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#include <linux/string.h>
#include <linux/slab.h>
#include <linux/delay.h>
+#include <linux/jiffies.h>
+#include <asm/div64.h>
#include "dvb_frontend.h"
#include "s5h1420.h"
diff --git a/drivers/media/dvb/frontends/sp8870.c b/drivers/media/dvb/frontends/sp8870.c
index 764a95a2e212..1c6b2e9264bc 100644
--- a/drivers/media/dvb/frontends/sp8870.c
+++ b/drivers/media/dvb/frontends/sp8870.c
@@ -32,6 +32,8 @@
#include <linux/device.h>
#include <linux/firmware.h>
#include <linux/delay.h>
+#include <linux/string.h>
+#include <linux/slab.h>
#include "dvb_frontend.h"
#include "sp8870.h"
diff --git a/drivers/media/dvb/frontends/sp887x.c b/drivers/media/dvb/frontends/sp887x.c
index d868a6927a16..73384e75625e 100644
--- a/drivers/media/dvb/frontends/sp887x.c
+++ b/drivers/media/dvb/frontends/sp887x.c
@@ -14,6 +14,8 @@
#include <linux/moduleparam.h>
#include <linux/device.h>
#include <linux/firmware.h>
+#include <linux/string.h>
+#include <linux/slab.h>
#include "dvb_frontend.h"
#include "sp887x.h"
diff --git a/drivers/media/dvb/frontends/stv0297.c b/drivers/media/dvb/frontends/stv0297.c
index 8d09afd7545d..6122ba754bc5 100644
--- a/drivers/media/dvb/frontends/stv0297.c
+++ b/drivers/media/dvb/frontends/stv0297.c
@@ -24,6 +24,8 @@
#include <linux/module.h>
#include <linux/string.h>
#include <linux/delay.h>
+#include <linux/jiffies.h>
+#include <linux/slab.h>
#include "dvb_frontend.h"
#include "stv0297.h"
diff --git a/drivers/media/dvb/frontends/stv0299.c b/drivers/media/dvb/frontends/stv0299.c
index 2d62931f20b5..29c48665e130 100644
--- a/drivers/media/dvb/frontends/stv0299.c
+++ b/drivers/media/dvb/frontends/stv0299.c
@@ -48,6 +48,7 @@
#include <linux/moduleparam.h>
#include <linux/string.h>
#include <linux/slab.h>
+#include <linux/jiffies.h>
#include <asm/div64.h>
#include "dvb_frontend.h"
@@ -63,8 +64,12 @@ struct stv0299_state {
u32 tuner_frequency;
u32 symbol_rate;
fe_code_rate_t fec_inner;
+ int errmode;
};
+#define STATUS_BER 0
+#define STATUS_UCBLOCKS 1
+
static int debug;
static int debug_legacy_dish_switch;
#define dprintk(args...) \
@@ -382,36 +387,6 @@ static int stv0299_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltag
};
}
-static inline s32 stv0299_calc_usec_delay (struct timeval lasttime, struct timeval curtime)
-{
- return ((curtime.tv_usec < lasttime.tv_usec) ?
- 1000000 - lasttime.tv_usec + curtime.tv_usec :
- curtime.tv_usec - lasttime.tv_usec);
-}
-
-static void stv0299_sleep_until (struct timeval *waketime, u32 add_usec)
-{
- struct timeval lasttime;
- s32 delta, newdelta;
-
- waketime->tv_usec += add_usec;
- if (waketime->tv_usec >= 1000000) {
- waketime->tv_usec -= 1000000;
- waketime->tv_sec++;
- }
-
- do_gettimeofday (&lasttime);
- delta = stv0299_calc_usec_delay (lasttime, *waketime);
- if (delta > 2500) {
- msleep ((delta - 1500) / 1000);
- do_gettimeofday (&lasttime);
- newdelta = stv0299_calc_usec_delay (lasttime, *waketime);
- delta = (newdelta > delta) ? 0 : newdelta;
- }
- if (delta > 0)
- udelay (delta);
-}
-
static int stv0299_send_legacy_dish_cmd (struct dvb_frontend* fe, u32 cmd)
{
struct stv0299_state* state = fe->demodulator_priv;
@@ -439,7 +414,7 @@ static int stv0299_send_legacy_dish_cmd (struct dvb_frontend* fe, u32 cmd)
memcpy (&tv[0], &nexttime, sizeof (struct timeval));
stv0299_writeregI (state, 0x0c, reg0x0c | 0x50); /* set LNB to 18V */
- stv0299_sleep_until (&nexttime, 32000);
+ dvb_frontend_sleep_until(&nexttime, 32000);
for (i=0; i<9; i++) {
if (debug_legacy_dish_switch)
@@ -453,13 +428,13 @@ static int stv0299_send_legacy_dish_cmd (struct dvb_frontend* fe, u32 cmd)
cmd = cmd >> 1;
if (i != 8)
- stv0299_sleep_until (&nexttime, 8000);
+ dvb_frontend_sleep_until(&nexttime, 8000);
}
if (debug_legacy_dish_switch) {
printk ("%s(%d): switch delay (should be 32k followed by all 8k\n",
__FUNCTION__, fe->dvb->num);
- for (i=1; i < 10; i++)
- printk ("%d: %d\n", i, stv0299_calc_usec_delay (tv[i-1] , tv[i]));
+ for (i = 1; i < 10; i++)
+ printk ("%d: %d\n", i, timeval_usec_diff(tv[i-1] , tv[i]));
}
return 0;
@@ -516,8 +491,7 @@ static int stv0299_read_ber(struct dvb_frontend* fe, u32* ber)
{
struct stv0299_state* state = fe->demodulator_priv;
- stv0299_writeregI(state, 0x34, (stv0299_readreg(state, 0x34) & 0xcf) | 0x10);
- msleep(100);
+ if (state->errmode != STATUS_BER) return 0;
*ber = (stv0299_readreg (state, 0x1d) << 8) | stv0299_readreg (state, 0x1e);
return 0;
@@ -556,9 +530,8 @@ static int stv0299_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
{
struct stv0299_state* state = fe->demodulator_priv;
- stv0299_writeregI(state, 0x34, (stv0299_readreg(state, 0x34) & 0xcf) | 0x30);
- msleep(100);
- *ucblocks = (stv0299_readreg (state, 0x1d) << 8) | stv0299_readreg (state, 0x1e);
+ if (state->errmode != STATUS_UCBLOCKS) *ucblocks = 0;
+ else *ucblocks = (stv0299_readreg (state, 0x1d) << 8) | stv0299_readreg (state, 0x1e);
return 0;
}
@@ -580,49 +553,14 @@ static int stv0299_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_par
if (state->config->invert) invval = (~invval) & 1;
stv0299_writeregI(state, 0x0c, (stv0299_readreg(state, 0x0c) & 0xfe) | invval);
- if (state->config->enhanced_tuning) {
- /* check if we should do a finetune */
- int frequency_delta = p->frequency - state->tuner_frequency;
- int minmax = p->u.qpsk.symbol_rate / 2000;
- if (minmax < 5000) minmax = 5000;
-
- if ((frequency_delta > -minmax) && (frequency_delta < minmax) && (frequency_delta != 0) &&
- (state->fec_inner == p->u.qpsk.fec_inner) &&
- (state->symbol_rate == p->u.qpsk.symbol_rate)) {
- int Drot_freq = (frequency_delta << 16) / (state->config->mclk / 1000);
-
- // zap the derotator registers first
- stv0299_writeregI(state, 0x22, 0x00);
- stv0299_writeregI(state, 0x23, 0x00);
-
- // now set them as we want
- stv0299_writeregI(state, 0x22, Drot_freq >> 8);
- stv0299_writeregI(state, 0x23, Drot_freq);
- } else {
- /* A "normal" tune is requested */
- stv0299_writeregI(state, 0x05, 0xb5); /* enable i2c repeater on stv0299 */
- state->config->pll_set(fe, state->i2c, p);
- stv0299_writeregI(state, 0x05, 0x35); /* disable i2c repeater on stv0299 */
-
- stv0299_writeregI(state, 0x32, 0x80);
- stv0299_writeregI(state, 0x22, 0x00);
- stv0299_writeregI(state, 0x23, 0x00);
- stv0299_writeregI(state, 0x32, 0x19);
- stv0299_set_symbolrate (fe, p->u.qpsk.symbol_rate);
- stv0299_set_FEC (state, p->u.qpsk.fec_inner);
- }
- } else {
- stv0299_writeregI(state, 0x05, 0xb5); /* enable i2c repeater on stv0299 */
- state->config->pll_set(fe, state->i2c, p);
- stv0299_writeregI(state, 0x05, 0x35); /* disable i2c repeater on stv0299 */
+ stv0299_writeregI(state, 0x05, 0xb5); /* enable i2c repeater on stv0299 */
+ state->config->pll_set(fe, state->i2c, p);
+ stv0299_writeregI(state, 0x05, 0x35); /* disable i2c repeater on stv0299 */
- stv0299_set_FEC (state, p->u.qpsk.fec_inner);
- stv0299_set_symbolrate (fe, p->u.qpsk.symbol_rate);
- stv0299_writeregI(state, 0x22, 0x00);
- stv0299_writeregI(state, 0x23, 0x00);
- stv0299_readreg (state, 0x23);
- stv0299_writeregI(state, 0x12, 0xb9);
- }
+ stv0299_set_FEC (state, p->u.qpsk.fec_inner);
+ stv0299_set_symbolrate (fe, p->u.qpsk.symbol_rate);
+ stv0299_writeregI(state, 0x22, 0x00);
+ stv0299_writeregI(state, 0x23, 0x00);
state->tuner_frequency = p->frequency;
state->fec_inner = p->u.qpsk.fec_inner;
@@ -707,6 +645,7 @@ struct dvb_frontend* stv0299_attach(const struct stv0299_config* config,
state->tuner_frequency = 0;
state->symbol_rate = 0;
state->fec_inner = 0;
+ state->errmode = STATUS_BER;
/* check if the demod is there */
stv0299_writeregI(state, 0x02, 0x34); /* standby off */
diff --git a/drivers/media/dvb/frontends/stv0299.h b/drivers/media/dvb/frontends/stv0299.h
index d0c4484861e1..9af3d71c89db 100644
--- a/drivers/media/dvb/frontends/stv0299.h
+++ b/drivers/media/dvb/frontends/stv0299.h
@@ -73,9 +73,6 @@ struct stv0299_config
/* does the inversion require inversion? */
u8 invert:1;
- /* Should the enhanced tuning code be used? */
- u8 enhanced_tuning:1;
-
/* Skip reinitialisation? */
u8 skip_reinit:1;
diff --git a/drivers/media/dvb/frontends/tda1004x.c b/drivers/media/dvb/frontends/tda1004x.c
index 74cea9f8d721..7968743826fc 100644
--- a/drivers/media/dvb/frontends/tda1004x.c
+++ b/drivers/media/dvb/frontends/tda1004x.c
@@ -32,6 +32,10 @@
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/device.h>
+#include <linux/jiffies.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+
#include "dvb_frontend.h"
#include "tda1004x.h"
@@ -416,7 +420,7 @@ static void tda10046_init_plls(struct dvb_frontend* fe)
struct tda1004x_state* state = fe->demodulator_priv;
tda1004x_write_byteI(state, TDA10046H_CONFPLL1, 0xf0);
- tda1004x_write_byteI(state, TDA10046H_CONFPLL2, 10); // PLL M = 10
+ tda1004x_write_byteI(state, TDA10046H_CONFPLL2, 0x0a); // PLL M = 10
if (state->config->xtal_freq == TDA10046_XTAL_4M ) {
dprintk("%s: setting up PLLs for a 4 MHz Xtal\n", __FUNCTION__);
tda1004x_write_byteI(state, TDA10046H_CONFPLL3, 0); // PLL P = N = 0
@@ -593,7 +597,10 @@ static int tda10046_init(struct dvb_frontend* fe)
// Init the tuner PLL
if (state->config->pll_init) {
tda1004x_enable_tuner_i2c(state);
- state->config->pll_init(fe);
+ if (state->config->pll_init(fe)) {
+ printk(KERN_ERR "tda1004x: pll init failed\n");
+ return -EIO;
+ }
tda1004x_disable_tuner_i2c(state);
}
@@ -663,7 +670,10 @@ static int tda1004x_set_fe(struct dvb_frontend* fe,
// set frequency
tda1004x_enable_tuner_i2c(state);
- state->config->pll_set(fe, fe_params);
+ if (state->config->pll_set(fe, fe_params)) {
+ printk(KERN_ERR "tda1004x: pll set failed\n");
+ return -EIO;
+ }
tda1004x_disable_tuner_i2c(state);
// Hardcoded to use auto as much as possible on the TDA10045 as it
@@ -828,6 +838,8 @@ static int tda1004x_set_fe(struct dvb_frontend* fe,
case TDA1004X_DEMOD_TDA10046:
tda1004x_write_mask(state, TDA1004X_AUTO, 0x40, 0x40);
+ msleep(1);
+ tda1004x_write_mask(state, TDA10046H_AGC_CONF, 4, 1);
break;
}
@@ -1125,7 +1137,12 @@ static int tda1004x_sleep(struct dvb_frontend* fe)
if (state->config->pll_sleep != NULL) {
tda1004x_enable_tuner_i2c(state);
state->config->pll_sleep(fe);
- tda1004x_disable_tuner_i2c(state);
+ if (state->config->if_freq != TDA10046_FREQ_052) {
+ /* special hack for Philips EUROPA Based boards:
+ * keep the I2c bridge open for tuner access in analog mode
+ */
+ tda1004x_disable_tuner_i2c(state);
+ }
}
tda1004x_write_mask(state, TDA1004X_CONFC4, 1, 1);
break;
diff --git a/drivers/media/dvb/frontends/tda8083.c b/drivers/media/dvb/frontends/tda8083.c
index 168e013d23bd..c05cf1861051 100644
--- a/drivers/media/dvb/frontends/tda8083.c
+++ b/drivers/media/dvb/frontends/tda8083.c
@@ -30,6 +30,7 @@
#include <linux/moduleparam.h>
#include <linux/string.h>
#include <linux/slab.h>
+#include <linux/jiffies.h>
#include "dvb_frontend.h"
#include "tda8083.h"
diff --git a/drivers/media/dvb/pluto2/pluto2.c b/drivers/media/dvb/pluto2/pluto2.c
index 85b437bbddcd..bbebd1c4caca 100644
--- a/drivers/media/dvb/pluto2/pluto2.c
+++ b/drivers/media/dvb/pluto2/pluto2.c
@@ -286,15 +286,10 @@ static void pluto_dma_end(struct pluto *pluto, unsigned int nbpackets)
* although one packet has been transfered.
*/
if ((nbpackets == 0) || (nbpackets > TS_DMA_PACKETS)) {
- unsigned int i = 0, valid;
+ unsigned int i = 0;
while (pluto->dma_buf[i] == 0x47)
i += 188;
- valid = i / 188;
- if (nbpackets != valid) {
- dev_err(&pluto->pdev->dev, "nbpackets=%u valid=%u\n",
- nbpackets, valid);
- nbpackets = valid;
- }
+ nbpackets = i / 188;
}
dvb_dmx_swfilter_packets(&pluto->demux, pluto->dma_buf, nbpackets);
diff --git a/drivers/media/dvb/ttpci/av7110.c b/drivers/media/dvb/ttpci/av7110.c
index 22b203f8ff27..87ea52757a21 100644
--- a/drivers/media/dvb/ttpci/av7110.c
+++ b/drivers/media/dvb/ttpci/av7110.c
@@ -1566,7 +1566,7 @@ static u8 alps_bsru6_inittab[] = {
0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */
0x10, 0x3f, // AGC2 0x3d
0x11, 0x84,
- 0x12, 0xb5, // Lock detect: -64 Carrier freq detect:on
+ 0x12, 0xb9,
0x15, 0xc9, // lock detector threshold
0x16, 0x00,
0x17, 0x00,
@@ -1644,7 +1644,6 @@ static struct stv0299_config alps_bsru6_config = {
.inittab = alps_bsru6_inittab,
.mclk = 88000000UL,
.invert = 1,
- .enhanced_tuning = 0,
.skip_reinit = 0,
.lock_output = STV0229_LOCKOUTPUT_1,
.volt13_op0_op1 = STV0299_VOLT13_OP1,
@@ -1669,7 +1668,7 @@ static u8 alps_bsbe1_inittab[] = {
0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */
0x10, 0x3f, // AGC2 0x3d
0x11, 0x84,
- 0x12, 0xb5, // Lock detect: -64 Carrier freq detect:on
+ 0x12, 0xb9,
0x15, 0xc9, // lock detector threshold
0x16, 0x00,
0x17, 0x00,
@@ -1721,7 +1720,6 @@ static struct stv0299_config alps_bsbe1_config = {
.inittab = alps_bsbe1_inittab,
.mclk = 88000000UL,
.invert = 1,
- .enhanced_tuning = 0,
.skip_reinit = 0,
.min_delay_ms = 100,
.set_symbol_rate = alps_bsru6_set_symbol_rate,
diff --git a/drivers/media/dvb/ttpci/av7110_ir.c b/drivers/media/dvb/ttpci/av7110_ir.c
index 357a3728ec68..f5e59fc924af 100644
--- a/drivers/media/dvb/ttpci/av7110_ir.c
+++ b/drivers/media/dvb/ttpci/av7110_ir.c
@@ -15,7 +15,7 @@
static int av_cnt;
static struct av7110 *av_list[4];
-static struct input_dev input_dev;
+static struct input_dev *input_dev;
static u16 key_map [256] = {
KEY_0, KEY_1, KEY_2, KEY_3, KEY_4, KEY_5, KEY_6, KEY_7,
@@ -43,10 +43,10 @@ static u16 key_map [256] = {
static void av7110_emit_keyup(unsigned long data)
{
- if (!data || !test_bit(data, input_dev.key))
+ if (!data || !test_bit(data, input_dev->key))
return;
- input_event(&input_dev, EV_KEY, data, !!0);
+ input_event(input_dev, EV_KEY, data, !!0);
}
@@ -112,13 +112,13 @@ static void av7110_emit_key(unsigned long parm)
if (timer_pending(&keyup_timer)) {
del_timer(&keyup_timer);
if (keyup_timer.data != keycode || new_toggle != old_toggle) {
- input_event(&input_dev, EV_KEY, keyup_timer.data, !!0);
- input_event(&input_dev, EV_KEY, keycode, !0);
+ input_event(input_dev, EV_KEY, keyup_timer.data, !!0);
+ input_event(input_dev, EV_KEY, keycode, !0);
} else
- input_event(&input_dev, EV_KEY, keycode, 2);
+ input_event(input_dev, EV_KEY, keycode, 2);
} else
- input_event(&input_dev, EV_KEY, keycode, !0);
+ input_event(input_dev, EV_KEY, keycode, !0);
keyup_timer.expires = jiffies + UP_TIMEOUT;
keyup_timer.data = keycode;
@@ -132,13 +132,13 @@ static void input_register_keys(void)
{
int i;
- memset(input_dev.keybit, 0, sizeof(input_dev.keybit));
+ memset(input_dev->keybit, 0, sizeof(input_dev->keybit));
- for (i = 0; i < sizeof(key_map) / sizeof(key_map[0]); i++) {
+ for (i = 0; i < ARRAY_SIZE(key_map); i++) {
if (key_map[i] > KEY_MAX)
key_map[i] = 0;
else if (key_map[i] > KEY_RESERVED)
- set_bit(key_map[i], input_dev.keybit);
+ set_bit(key_map[i], input_dev->keybit);
}
}
@@ -216,12 +216,17 @@ int __init av7110_ir_init(struct av7110 *av7110)
init_timer(&keyup_timer);
keyup_timer.data = 0;
- input_dev.name = "DVB on-card IR receiver";
- set_bit(EV_KEY, input_dev.evbit);
- set_bit(EV_REP, input_dev.evbit);
+ input_dev = input_allocate_device();
+ if (!input_dev)
+ return -ENOMEM;
+
+ input_dev->name = "DVB on-card IR receiver";
+
+ set_bit(EV_KEY, input_dev->evbit);
+ set_bit(EV_REP, input_dev->evbit);
input_register_keys();
- input_register_device(&input_dev);
- input_dev.timer.function = input_repeat_key;
+ input_register_device(input_dev);
+ input_dev->timer.function = input_repeat_key;
e = create_proc_entry("av7110_ir", S_IFREG | S_IRUGO | S_IWUSR, NULL);
if (e) {
@@ -256,7 +261,7 @@ void __exit av7110_ir_exit(struct av7110 *av7110)
if (av_cnt == 1) {
del_timer_sync(&keyup_timer);
remove_proc_entry("av7110_ir", NULL);
- input_unregister_device(&input_dev);
+ input_unregister_device(input_dev);
}
av_cnt--;
diff --git a/drivers/media/dvb/ttpci/budget-av.c b/drivers/media/dvb/ttpci/budget-av.c
index 7692cd23f839..aa75dc03a0b3 100644
--- a/drivers/media/dvb/ttpci/budget-av.c
+++ b/drivers/media/dvb/ttpci/budget-av.c
@@ -499,7 +499,7 @@ static u8 typhoon_cinergy1200s_inittab[] = {
0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */
0x10, 0x3f, // AGC2 0x3d
0x11, 0x84,
- 0x12, 0xb5, // Lock detect: -64 Carrier freq detect:on
+ 0x12, 0xb9,
0x15, 0xc9, // lock detector threshold
0x16, 0x00,
0x17, 0x00,
@@ -531,7 +531,6 @@ static struct stv0299_config typhoon_config = {
.inittab = typhoon_cinergy1200s_inittab,
.mclk = 88000000UL,
.invert = 0,
- .enhanced_tuning = 0,
.skip_reinit = 0,
.lock_output = STV0229_LOCKOUTPUT_1,
.volt13_op0_op1 = STV0299_VOLT13_OP0,
@@ -546,7 +545,6 @@ static struct stv0299_config cinergy_1200s_config = {
.inittab = typhoon_cinergy1200s_inittab,
.mclk = 88000000UL,
.invert = 0,
- .enhanced_tuning = 0,
.skip_reinit = 0,
.lock_output = STV0229_LOCKOUTPUT_0,
.volt13_op0_op1 = STV0299_VOLT13_OP0,
diff --git a/drivers/media/dvb/ttpci/budget-ci.c b/drivers/media/dvb/ttpci/budget-ci.c
index 2980db3ef22f..75fb92d60998 100644
--- a/drivers/media/dvb/ttpci/budget-ci.c
+++ b/drivers/media/dvb/ttpci/budget-ci.c
@@ -64,7 +64,7 @@
struct budget_ci {
struct budget budget;
- struct input_dev input_dev;
+ struct input_dev *input_dev;
struct tasklet_struct msp430_irq_tasklet;
struct tasklet_struct ciintf_irq_tasklet;
int slot_status;
@@ -145,7 +145,7 @@ static void msp430_ir_debounce(unsigned long data)
static void msp430_ir_interrupt(unsigned long data)
{
struct budget_ci *budget_ci = (struct budget_ci *) data;
- struct input_dev *dev = &budget_ci->input_dev;
+ struct input_dev *dev = budget_ci->input_dev;
unsigned int code =
ttpci_budget_debiread(&budget_ci->budget, DEBINOSWAP, DEBIADDR_IR, 2, 1, 0) >> 8;
@@ -181,25 +181,27 @@ static void msp430_ir_interrupt(unsigned long data)
static int msp430_ir_init(struct budget_ci *budget_ci)
{
struct saa7146_dev *saa = budget_ci->budget.dev;
+ struct input_dev *input_dev;
int i;
- memset(&budget_ci->input_dev, 0, sizeof(struct input_dev));
+ budget_ci->input_dev = input_dev = input_allocate_device();
+ if (!input_dev)
+ return -ENOMEM;
sprintf(budget_ci->ir_dev_name, "Budget-CI dvb ir receiver %s", saa->name);
- budget_ci->input_dev.name = budget_ci->ir_dev_name;
- set_bit(EV_KEY, budget_ci->input_dev.evbit);
+ input_dev->name = budget_ci->ir_dev_name;
- for (i = 0; i < sizeof(key_map) / sizeof(*key_map); i++)
+ set_bit(EV_KEY, input_dev->evbit);
+ for (i = 0; i < ARRAY_SIZE(key_map); i++)
if (key_map[i])
- set_bit(key_map[i], budget_ci->input_dev.keybit);
+ set_bit(key_map[i], input_dev->keybit);
- input_register_device(&budget_ci->input_dev);
+ input_register_device(budget_ci->input_dev);
- budget_ci->input_dev.timer.function = msp430_ir_debounce;
+ input_dev->timer.function = msp430_ir_debounce;
saa7146_write(saa, IER, saa7146_read(saa, IER) | MASK_06);
-
saa7146_setgpio(saa, 3, SAA7146_GPIO_IRQHI);
return 0;
@@ -208,7 +210,7 @@ static int msp430_ir_init(struct budget_ci *budget_ci)
static void msp430_ir_deinit(struct budget_ci *budget_ci)
{
struct saa7146_dev *saa = budget_ci->budget.dev;
- struct input_dev *dev = &budget_ci->input_dev;
+ struct input_dev *dev = budget_ci->input_dev;
saa7146_write(saa, IER, saa7146_read(saa, IER) & ~MASK_06);
saa7146_setgpio(saa, 3, SAA7146_GPIO_INPUT);
@@ -488,7 +490,7 @@ static u8 alps_bsru6_inittab[] = {
0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */
0x10, 0x3f, // AGC2 0x3d
0x11, 0x84,
- 0x12, 0xb5, // Lock detect: -64 Carrier freq detect:on
+ 0x12, 0xb9,
0x15, 0xc9, // lock detector threshold
0x16, 0x00,
0x17, 0x00,
@@ -578,7 +580,6 @@ static struct stv0299_config alps_bsru6_config = {
.inittab = alps_bsru6_inittab,
.mclk = 88000000UL,
.invert = 1,
- .enhanced_tuning = 0,
.skip_reinit = 0,
.lock_output = STV0229_LOCKOUTPUT_1,
.volt13_op0_op1 = STV0299_VOLT13_OP1,
@@ -708,7 +709,6 @@ static struct stv0299_config philips_su1278_tt_config = {
.inittab = philips_su1278_tt_inittab,
.mclk = 64000000UL,
.invert = 0,
- .enhanced_tuning = 1,
.skip_reinit = 1,
.lock_output = STV0229_LOCKOUTPUT_1,
.volt13_op0_op1 = STV0299_VOLT13_OP1,
diff --git a/drivers/media/dvb/ttpci/budget-patch.c b/drivers/media/dvb/ttpci/budget-patch.c
index b1f21ef0e3b3..755df81cbc49 100644
--- a/drivers/media/dvb/ttpci/budget-patch.c
+++ b/drivers/media/dvb/ttpci/budget-patch.c
@@ -305,7 +305,7 @@ static u8 alps_bsru6_inittab[] = {
0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */
0x10, 0x3f, // AGC2 0x3d
0x11, 0x84,
- 0x12, 0xb5, // Lock detect: -64 Carrier freq detect:on
+ 0x12, 0xb9,
0x15, 0xc9, // lock detector threshold
0x16, 0x00,
0x17, 0x00,
@@ -379,7 +379,6 @@ static struct stv0299_config alps_bsru6_config = {
.inittab = alps_bsru6_inittab,
.mclk = 88000000UL,
.invert = 1,
- .enhanced_tuning = 0,
.skip_reinit = 0,
.lock_output = STV0229_LOCKOUTPUT_1,
.volt13_op0_op1 = STV0299_VOLT13_OP1,
diff --git a/drivers/media/dvb/ttpci/budget.c b/drivers/media/dvb/ttpci/budget.c
index 43d6c8268642..4fd8bbc47037 100644
--- a/drivers/media/dvb/ttpci/budget.c
+++ b/drivers/media/dvb/ttpci/budget.c
@@ -226,12 +226,14 @@ static int lnbp21_enable_high_lnb_voltage(struct dvb_frontend* fe, int arg)
return 0;
}
-static void lnbp21_init(struct budget* budget)
+static int lnbp21_init(struct budget* budget)
{
u8 buf = 0x00;
struct i2c_msg msg = { .addr = 0x08, .flags = 0, .buf = &buf, .len = sizeof(buf) };
- i2c_transfer (&budget->i2c_adap, &msg, 1);
+ if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1)
+ return -EIO;
+ return 0;
}
static int alps_bsrv2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
@@ -273,7 +275,7 @@ static u8 alps_bsru6_inittab[] = {
0x01, 0x15,
0x02, 0x00,
0x03, 0x00,
- 0x04, 0x7d, /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */
+ 0x04, 0x7d, /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */
0x05, 0x35, /* I2CT = 0, SCLT = 1, SDAT = 1 */
0x06, 0x40, /* DAC not used, set to high impendance mode */
0x07, 0x00, /* DAC LSB */
@@ -284,7 +286,7 @@ static u8 alps_bsru6_inittab[] = {
0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */
0x10, 0x3f, // AGC2 0x3d
0x11, 0x84,
- 0x12, 0xb5, // Lock detect: -64 Carrier freq detect:on
+ 0x12, 0xb9,
0x15, 0xc9, // lock detector threshold
0x16, 0x00,
0x17, 0x00,
@@ -358,7 +360,6 @@ static struct stv0299_config alps_bsru6_config = {
.inittab = alps_bsru6_inittab,
.mclk = 88000000UL,
.invert = 1,
- .enhanced_tuning = 0,
.skip_reinit = 0,
.lock_output = STV0229_LOCKOUTPUT_1,
.volt13_op0_op1 = STV0299_VOLT13_OP1,
@@ -367,6 +368,79 @@ static struct stv0299_config alps_bsru6_config = {
.pll_set = alps_bsru6_pll_set,
};
+static u8 alps_bsbe1_inittab[] = {
+ 0x01, 0x15,
+ 0x02, 0x30,
+ 0x03, 0x00,
+ 0x04, 0x7d, /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */
+ 0x05, 0x35, /* I2CT = 0, SCLT = 1, SDAT = 1 */
+ 0x06, 0x40, /* DAC not used, set to high impendance mode */
+ 0x07, 0x00, /* DAC LSB */
+ 0x08, 0x40, /* DiSEqC off, LNB power on OP2/LOCK pin on */
+ 0x09, 0x00, /* FIFO */
+ 0x0c, 0x51, /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */
+ 0x0d, 0x82, /* DC offset compensation = ON, beta_agc1 = 2 */
+ 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */
+ 0x10, 0x3f, // AGC2 0x3d
+ 0x11, 0x84,
+ 0x12, 0xb9,
+ 0x15, 0xc9, // lock detector threshold
+ 0x16, 0x00,
+ 0x17, 0x00,
+ 0x18, 0x00,
+ 0x19, 0x00,
+ 0x1a, 0x00,
+ 0x1f, 0x50,
+ 0x20, 0x00,
+ 0x21, 0x00,
+ 0x22, 0x00,
+ 0x23, 0x00,
+ 0x28, 0x00, // out imp: normal out type: parallel FEC mode:0
+ 0x29, 0x1e, // 1/2 threshold
+ 0x2a, 0x14, // 2/3 threshold
+ 0x2b, 0x0f, // 3/4 threshold
+ 0x2c, 0x09, // 5/6 threshold
+ 0x2d, 0x05, // 7/8 threshold
+ 0x2e, 0x01,
+ 0x31, 0x1f, // test all FECs
+ 0x32, 0x19, // viterbi and synchro search
+ 0x33, 0xfc, // rs control
+ 0x34, 0x93, // error control
+ 0x0f, 0x92, // 0x80 = inverse AGC
+ 0xff, 0xff
+};
+
+static int alps_bsbe1_pll_set(struct dvb_frontend* fe, struct i2c_adapter *i2c, struct dvb_frontend_parameters* params)
+{
+ int ret;
+ u8 data[4];
+ u32 div;
+ struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) };
+
+ if ((params->frequency < 950000) || (params->frequency > 2150000))
+ return -EINVAL;
+
+ div = (params->frequency + (125 - 1)) / 125; // round correctly
+ data[0] = (div >> 8) & 0x7f;
+ data[1] = div & 0xff;
+ data[2] = 0x80 | ((div & 0x18000) >> 10) | 4;
+ data[3] = (params->frequency > 1530000) ? 0xE0 : 0xE4;
+
+ ret = i2c_transfer(i2c, &msg, 1);
+ return (ret != 1) ? -EIO : 0;
+}
+
+static struct stv0299_config alps_bsbe1_config = {
+ .demod_address = 0x68,
+ .inittab = alps_bsbe1_inittab,
+ .mclk = 88000000UL,
+ .invert = 1,
+ .skip_reinit = 0,
+ .min_delay_ms = 100,
+ .set_symbol_rate = alps_bsru6_set_symbol_rate,
+ .pll_set = alps_bsbe1_pll_set,
+};
+
static int alps_tdbe2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
{
struct budget* budget = (struct budget*) fe->dvb->priv;
@@ -500,6 +574,19 @@ static u8 read_pwm(struct budget* budget)
static void frontend_init(struct budget *budget)
{
switch(budget->dev->pci->subsystem_device) {
+ case 0x1017:
+ // try the ALPS BSBE1 now
+ budget->dvb_frontend = stv0299_attach(&alps_bsbe1_config, &budget->i2c_adap);
+ if (budget->dvb_frontend) {
+ budget->dvb_frontend->ops->set_voltage = lnbp21_set_voltage;
+ budget->dvb_frontend->ops->enable_high_lnb_voltage = lnbp21_enable_high_lnb_voltage;
+ if (lnbp21_init(budget)) {
+ printk("%s: No LNBP21 found!\n", __FUNCTION__);
+ goto error_out;
+ }
+ }
+
+ break;
case 0x1003: // Hauppauge/TT Nova budget (stv0299/ALPS BSRU6(tsa5059) OR ves1893/ALPS BSRV2(sp5659))
case 0x1013:
// try the ALPS BSRV2 first of all
@@ -554,7 +641,10 @@ static void frontend_init(struct budget *budget)
if (budget->dvb_frontend) {
budget->dvb_frontend->ops->set_voltage = lnbp21_set_voltage;
budget->dvb_frontend->ops->enable_high_lnb_voltage = lnbp21_enable_high_lnb_voltage;
- lnbp21_init(budget);
+ if (lnbp21_init(budget)) {
+ printk("%s: No LNBP21 found!\n", __FUNCTION__);
+ goto error_out;
+ }
break;
}
}
@@ -566,13 +656,17 @@ static void frontend_init(struct budget *budget)
budget->dev->pci->subsystem_vendor,
budget->dev->pci->subsystem_device);
} else {
- if (dvb_register_frontend(&budget->dvb_adapter, budget->dvb_frontend)) {
- printk("budget: Frontend registration failed!\n");
- if (budget->dvb_frontend->ops->release)
- budget->dvb_frontend->ops->release(budget->dvb_frontend);
- budget->dvb_frontend = NULL;
- }
+ if (dvb_register_frontend(&budget->dvb_adapter, budget->dvb_frontend))
+ goto error_out;
}
+ return;
+
+error_out:
+ printk("budget: Frontend registration failed!\n");
+ if (budget->dvb_frontend->ops->release)
+ budget->dvb_frontend->ops->release(budget->dvb_frontend);
+ budget->dvb_frontend = NULL;
+ return;
}
static int budget_attach (struct saa7146_dev* dev, struct saa7146_pci_extension_data *info)
@@ -618,6 +712,7 @@ static int budget_detach (struct saa7146_dev* dev)
static struct saa7146_extension budget_extension;
+MAKE_BUDGET_INFO(ttbs2, "TT-Budget/WinTV-NOVA-S PCI (rev AL/alps bsbe1 lnbp21 frontend)", BUDGET_TT);
MAKE_BUDGET_INFO(ttbs, "TT-Budget/WinTV-NOVA-S PCI", BUDGET_TT);
MAKE_BUDGET_INFO(ttbc, "TT-Budget/WinTV-NOVA-C PCI", BUDGET_TT);
MAKE_BUDGET_INFO(ttbt, "TT-Budget/WinTV-NOVA-T PCI", BUDGET_TT);
@@ -630,6 +725,7 @@ static struct pci_device_id pci_tbl[] = {
MAKE_EXTENSION_PCI(ttbc, 0x13c2, 0x1004),
MAKE_EXTENSION_PCI(ttbt, 0x13c2, 0x1005),
MAKE_EXTENSION_PCI(satel, 0x13c2, 0x1013),
+ MAKE_EXTENSION_PCI(ttbs2, 0x13c2, 0x1017),
MAKE_EXTENSION_PCI(ttbs, 0x13c2, 0x1016),
MAKE_EXTENSION_PCI(fsacs1,0x1131, 0x4f60),
MAKE_EXTENSION_PCI(fsacs0,0x1131, 0x4f61),
diff --git a/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c b/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
index d200ab0ad9e7..fd53d6010502 100644
--- a/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
+++ b/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
@@ -1198,7 +1198,7 @@ static u8 alps_bsbe1_inittab[] = {
0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */
0x10, 0x3f, // AGC2 0x3d
0x11, 0x84,
- 0x12, 0xb5, // Lock detect: -64 Carrier freq detect:on
+ 0x12, 0xb9,
0x15, 0xc9, // lock detector threshold
0x16, 0x00,
0x17, 0x00,
@@ -1240,7 +1240,7 @@ static u8 alps_bsru6_inittab[] = {
0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */
0x10, 0x3f, // AGC2 0x3d
0x11, 0x84,
- 0x12, 0xb5, // Lock detect: -64 Carrier freq detect:on
+ 0x12, 0xb9,
0x15, 0xc9, // lock detector threshold
0x16, 0x00,
0x17, 0x00,
@@ -1335,7 +1335,6 @@ static struct stv0299_config alps_stv0299_config = {
.inittab = alps_bsru6_inittab,
.mclk = 88000000UL,
.invert = 1,
- .enhanced_tuning = 0,
.skip_reinit = 0,
.lock_output = STV0229_LOCKOUTPUT_1,
.volt13_op0_op1 = STV0299_VOLT13_OP1,
diff --git a/drivers/media/dvb/ttusb-dec/ttusb_dec.c b/drivers/media/dvb/ttusb-dec/ttusb_dec.c
index 3d08fc83a754..832d179f26fa 100644
--- a/drivers/media/dvb/ttusb-dec/ttusb_dec.c
+++ b/drivers/media/dvb/ttusb-dec/ttusb_dec.c
@@ -152,7 +152,8 @@ struct ttusb_dec {
struct list_head filter_info_list;
spinlock_t filter_info_list_lock;
- struct input_dev rc_input_dev;
+ struct input_dev *rc_input_dev;
+ char rc_phys[64];
int active; /* Loaded successfully */
};
@@ -235,9 +236,9 @@ static void ttusb_dec_handle_irq( struct urb *urb, struct pt_regs *regs)
* this should/could be added later ...
* for now lets report each signal as a key down and up*/
dprintk("%s:rc signal:%d\n", __FUNCTION__, buffer[4]);
- input_report_key(&dec->rc_input_dev,rc_keys[buffer[4]-1],1);
- input_report_key(&dec->rc_input_dev,rc_keys[buffer[4]-1],0);
- input_sync(&dec->rc_input_dev);
+ input_report_key(dec->rc_input_dev, rc_keys[buffer[4] - 1], 1);
+ input_report_key(dec->rc_input_dev, rc_keys[buffer[4] - 1], 0);
+ input_sync(dec->rc_input_dev);
}
exit: retval = usb_submit_urb(urb, GFP_ATOMIC);
@@ -1181,29 +1182,38 @@ static void ttusb_dec_init_tasklet(struct ttusb_dec *dec)
(unsigned long)dec);
}
-static void ttusb_init_rc( struct ttusb_dec *dec)
+static int ttusb_init_rc(struct ttusb_dec *dec)
{
+ struct input_dev *input_dev;
u8 b[] = { 0x00, 0x01 };
int i;
- init_input_dev(&dec->rc_input_dev);
+ usb_make_path(dec->udev, dec->rc_phys, sizeof(dec->rc_phys));
+ strlcpy(dec->rc_phys, "/input0", sizeof(dec->rc_phys));
- dec->rc_input_dev.name = "ttusb_dec remote control";
- dec->rc_input_dev.evbit[0] = BIT(EV_KEY);
- dec->rc_input_dev.keycodesize = sizeof(u16);
- dec->rc_input_dev.keycodemax = 0x1a;
- dec->rc_input_dev.keycode = rc_keys;
+ dec->rc_input_dev = input_dev = input_allocate_device();
+ if (!input_dev)
+ return -ENOMEM;
+
+ input_dev->name = "ttusb_dec remote control";
+ input_dev->phys = dec->rc_phys;
+ input_dev->evbit[0] = BIT(EV_KEY);
+ input_dev->keycodesize = sizeof(u16);
+ input_dev->keycodemax = 0x1a;
+ input_dev->keycode = rc_keys;
- for (i = 0; i < sizeof(rc_keys)/sizeof(rc_keys[0]); i++)
- set_bit(rc_keys[i], dec->rc_input_dev.keybit);
+ for (i = 0; i < ARRAY_SIZE(rc_keys); i++)
+ set_bit(rc_keys[i], input_dev->keybit);
- input_register_device(&dec->rc_input_dev);
+ input_register_device(input_dev);
- if(usb_submit_urb(dec->irq_urb,GFP_KERNEL)) {
+ if (usb_submit_urb(dec->irq_urb, GFP_KERNEL))
printk("%s: usb_submit_urb failed\n",__FUNCTION__);
- }
+
/* enable irq pipe */
ttusb_dec_send_command(dec,0xb0,sizeof(b),b,NULL,NULL);
+
+ return 0;
}
static void ttusb_dec_init_v_pes(struct ttusb_dec *dec)
@@ -1513,7 +1523,7 @@ static void ttusb_dec_exit_rc(struct ttusb_dec *dec)
* As the irq is submitted after the interface is changed,
* this is the best method i figured out.
* Any others?*/
- if(dec->interface == TTUSB_DEC_INTERFACE_IN)
+ if (dec->interface == TTUSB_DEC_INTERFACE_IN)
usb_kill_urb(dec->irq_urb);
usb_free_urb(dec->irq_urb);
@@ -1521,7 +1531,10 @@ static void ttusb_dec_exit_rc(struct ttusb_dec *dec)
usb_buffer_free(dec->udev,IRQ_PACKET_SIZE,
dec->irq_buffer, dec->irq_dma_handle);
- input_unregister_device(&dec->rc_input_dev);
+ if (dec->rc_input_dev) {
+ input_unregister_device(dec->rc_input_dev);
+ dec->rc_input_dev = NULL;
+ }
}
@@ -1659,7 +1672,7 @@ static int ttusb_dec_probe(struct usb_interface *intf,
ttusb_dec_set_interface(dec, TTUSB_DEC_INTERFACE_IN);
- if(enable_rc)
+ if (enable_rc)
ttusb_init_rc(dec);
return 0;
diff --git a/drivers/media/radio/miropcm20-rds.c b/drivers/media/radio/miropcm20-rds.c
index df79d5e0aaed..e09214082e01 100644
--- a/drivers/media/radio/miropcm20-rds.c
+++ b/drivers/media/radio/miropcm20-rds.c
@@ -14,6 +14,7 @@
#include <linux/slab.h>
#include <linux/fs.h>
#include <linux/miscdevice.h>
+#include <linux/sched.h> /* current, TASK_*, schedule_timeout() */
#include <linux/delay.h>
#include <asm/uaccess.h>
#include "miropcm20-rds-core.h"
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index bbb989df4cf0..199b01188858 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -25,6 +25,16 @@ config VIDEO_BT848
To compile this driver as a module, choose M here: the
module will be called bttv.
+config VIDEO_BT848_DVB
+ tristate "DVB/ATSC Support for bt878 based TV cards"
+ depends on VIDEO_BT848 && DVB_CORE
+ select DVB_BT8XX
+ ---help---
+ This adds support for DVB/ATSC cards based on the BT878 chip.
+
+ To compile this driver as a module, choose M here: the
+ module will be called dvb-bt8xx.
+
config VIDEO_SAA6588
tristate "SAA6588 Radio Chip RDS decoder support on BT848 cards"
depends on VIDEO_DEV && I2C && VIDEO_BT848
@@ -243,29 +253,7 @@ config VIDEO_MEYE
To compile this driver as a module, choose M here: the
module will be called meye.
-config VIDEO_SAA7134
- tristate "Philips SAA7134 support"
- depends on VIDEO_DEV && PCI && I2C && SOUND
- select VIDEO_BUF
- select VIDEO_IR
- select VIDEO_TUNER
- select CRC32
- ---help---
- This is a video4linux driver for Philips SAA7130/7134 based
- TV cards.
-
- To compile this driver as a module, choose M here: the
- module will be called saa7134.
-
-config VIDEO_SAA7134_DVB
- tristate "DVB Support for saa7134 based TV cards"
- depends on VIDEO_SAA7134 && DVB_CORE
- select VIDEO_BUF_DVB
- select DVB_MT352
- select DVB_TDA1004X
- ---help---
- This adds support for DVB cards based on the
- Philips saa7134 chip.
+source "drivers/media/video/saa7134/Kconfig"
config VIDEO_MXB
tristate "Siemens-Nixdorf 'Multimedia eXtension Board'"
@@ -316,34 +304,9 @@ config VIDEO_HEXIUM_GEMINI
To compile this driver as a module, choose M here: the
module will be called hexium_gemini.
-config VIDEO_CX88
- tristate "Conexant 2388x (bt878 successor) support"
- depends on VIDEO_DEV && PCI && I2C && EXPERIMENTAL
- select I2C_ALGOBIT
- select FW_LOADER
- select VIDEO_BTCX
- select VIDEO_BUF
- select VIDEO_TUNER
- select VIDEO_TVEEPROM
- select VIDEO_IR
- ---help---
- This is a video4linux driver for Conexant 2388x based
- TV cards.
+source "drivers/media/video/cx88/Kconfig"
- To compile this driver as a module, choose M here: the
- module will be called cx8800
-
-config VIDEO_CX88_DVB
- tristate "DVB Support for cx2388x based TV cards"
- depends on VIDEO_CX88 && DVB_CORE
- select VIDEO_BUF_DVB
- select DVB_MT352
- select DVB_OR51132
- select DVB_CX22702
- select DVB_LGDT330X
- ---help---
- This adds support for DVB/ATSC cards based on the
- Connexant 2388x chip.
+source "drivers/media/video/em28xx/Kconfig"
config VIDEO_OVCAMCHIP
tristate "OmniVision Camera Chip support"
diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile
index 046b82de9285..3ac465992400 100644
--- a/drivers/media/video/Makefile
+++ b/drivers/media/video/Makefile
@@ -5,7 +5,6 @@
bttv-objs := bttv-driver.o bttv-cards.o bttv-if.o \
bttv-risc.o bttv-vbi.o bttv-i2c.o bttv-gpio.o
zoran-objs := zr36120.o zr36120_i2c.o zr36120_mem.o
-rds-objs := saa6588.o
zr36067-objs := zoran_procfs.o zoran_device.o \
zoran_driver.o zoran_card.o
tuner-objs := tuner-core.o tuner-simple.o mt20xx.o tda8290.o tea5767.o
@@ -16,7 +15,7 @@ obj-$(CONFIG_VIDEO_BT848) += bttv.o msp3400.o tvaudio.o \
obj-$(CONFIG_SOUND_TVMIXER) += tvmixer.o
obj-$(CONFIG_VIDEO_ZR36120) += zoran.o
-obj-$(CONFIG_VIDEO_SAA6588) += rds.o
+obj-$(CONFIG_VIDEO_SAA6588) += saa6588.o
obj-$(CONFIG_VIDEO_SAA5246A) += saa5246a.o
obj-$(CONFIG_VIDEO_SAA5249) += saa5249.o
obj-$(CONFIG_VIDEO_CQCAM) += c-qcam.o
@@ -39,6 +38,8 @@ obj-$(CONFIG_VIDEO_CPIA_USB) += cpia_usb.o
obj-$(CONFIG_VIDEO_MEYE) += meye.o
obj-$(CONFIG_VIDEO_SAA7134) += saa7134/
obj-$(CONFIG_VIDEO_CX88) += cx88/
+obj-$(CONFIG_VIDEO_EM28XX) += em28xx/
+obj-$(CONFIG_VIDEO_EM28XX) += saa711x.o tvp5150.o
obj-$(CONFIG_VIDEO_OVCAMCHIP) += ovcamchip/
obj-$(CONFIG_VIDEO_MXB) += saa7111.o tuner.o tda9840.o tea6415c.o tea6420.o mxb.o
obj-$(CONFIG_VIDEO_HEXIUM_ORION) += hexium_orion.o
diff --git a/drivers/media/video/arv.c b/drivers/media/video/arv.c
index 87fd3a7bb392..881cdcb1875d 100644
--- a/drivers/media/video/arv.c
+++ b/drivers/media/video/arv.c
@@ -22,7 +22,6 @@
#include <linux/init.h>
#include <linux/devfs_fs_kernel.h>
#include <linux/module.h>
-#include <linux/version.h>
#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/fs.h>
@@ -865,10 +864,8 @@ out_dev:
out_irq:
#endif
- for (i = 0; i < MAX_AR_HEIGHT; i++) {
- if (ar->frame[i])
- kfree(ar->frame[i]);
- }
+ for (i = 0; i < MAX_AR_HEIGHT; i++)
+ kfree(ar->frame[i]);
out_line_buff:
#if USE_INT
@@ -899,10 +896,8 @@ static void __exit ar_cleanup_module(void)
#if USE_INT
free_irq(M32R_IRQ_INT3, ar);
#endif
- for (i = 0; i < MAX_AR_HEIGHT; i++) {
- if (ar->frame[i])
- kfree(ar->frame[i]);
- }
+ for (i = 0; i < MAX_AR_HEIGHT; i++)
+ kfree(ar->frame[i]);
#if USE_INT
kfree(ar->line_buff);
#endif
diff --git a/drivers/media/video/bt832.c b/drivers/media/video/bt832.c
index 76c1b63ebdf2..e4063950ae57 100644
--- a/drivers/media/video/bt832.c
+++ b/drivers/media/video/bt832.c
@@ -32,7 +32,6 @@
#include <linux/slab.h>
#include <media/audiochip.h>
-#include <media/id.h>
#include "bttv.h"
#include "bt832.h"
@@ -54,36 +53,36 @@ static struct i2c_driver driver;
static struct i2c_client client_template;
struct bt832 {
- struct i2c_client client;
+ struct i2c_client client;
};
int bt832_hexdump(struct i2c_client *i2c_client_s, unsigned char *buf)
{
int i,rc;
buf[0]=0x80; // start at register 0 with auto-increment
- if (1 != (rc = i2c_master_send(i2c_client_s,buf,1)))
- printk("bt832: i2c i/o error: rc == %d (should be 1)\n",rc);
+ if (1 != (rc = i2c_master_send(i2c_client_s,buf,1)))
+ printk("bt832: i2c i/o error: rc == %d (should be 1)\n",rc);
- for(i=0;i<65;i++)
- buf[i]=0;
- if (65 != (rc=i2c_master_recv(i2c_client_s,buf,65)))
- printk("bt832: i2c i/o error: rc == %d (should be 65)\n",rc);
+ for(i=0;i<65;i++)
+ buf[i]=0;
+ if (65 != (rc=i2c_master_recv(i2c_client_s,buf,65)))
+ printk("bt832: i2c i/o error: rc == %d (should be 65)\n",rc);
- // Note: On READ the first byte is the current index
- // (e.g. 0x80, what we just wrote)
+ // Note: On READ the first byte is the current index
+ // (e.g. 0x80, what we just wrote)
- if(1) {
- int i;
- printk("BT832 hexdump:\n");
- for(i=1;i<65;i++) {
+ if(1) {
+ int i;
+ printk("BT832 hexdump:\n");
+ for(i=1;i<65;i++) {
if(i!=1) {
if(((i-1)%8)==0) printk(" ");
- if(((i-1)%16)==0) printk("\n");
+ if(((i-1)%16)==0) printk("\n");
}
- printk(" %02x",buf[i]);
- }
- printk("\n");
- }
+ printk(" %02x",buf[i]);
+ }
+ printk("\n");
+ }
return 0;
}
@@ -102,13 +101,13 @@ int bt832_init(struct i2c_client *i2c_client_s)
return 0;
}
- printk("Write 0 tp VPSTATUS\n");
- buf[0]=BT832_VP_STATUS; // Reg.52
- buf[1]= 0x00;
- if (2 != (rc = i2c_master_send(i2c_client_s,buf,2)))
- printk("bt832: i2c i/o error VPS: rc == %d (should be 2)\n",rc);
+ printk("Write 0 tp VPSTATUS\n");
+ buf[0]=BT832_VP_STATUS; // Reg.52
+ buf[1]= 0x00;
+ if (2 != (rc = i2c_master_send(i2c_client_s,buf,2)))
+ printk("bt832: i2c i/o error VPS: rc == %d (should be 2)\n",rc);
- bt832_hexdump(i2c_client_s,buf);
+ bt832_hexdump(i2c_client_s,buf);
// Leave low power mode:
@@ -116,17 +115,17 @@ int bt832_init(struct i2c_client *i2c_client_s)
buf[0]=BT832_CAM_SETUP0; //0x39 57
buf[1]=0x08;
if (2 != (rc = i2c_master_send(i2c_client_s,buf,2)))
- printk("bt832: i2c i/o error LLPM: rc == %d (should be 2)\n",rc);
+ printk("bt832: i2c i/o error LLPM: rc == %d (should be 2)\n",rc);
- bt832_hexdump(i2c_client_s,buf);
+ bt832_hexdump(i2c_client_s,buf);
printk("Write 0 tp VPSTATUS\n");
- buf[0]=BT832_VP_STATUS; // Reg.52
- buf[1]= 0x00;
- if (2 != (rc = i2c_master_send(i2c_client_s,buf,2)))
- printk("bt832: i2c i/o error VPS: rc == %d (should be 2)\n",rc);
+ buf[0]=BT832_VP_STATUS; // Reg.52
+ buf[1]= 0x00;
+ if (2 != (rc = i2c_master_send(i2c_client_s,buf,2)))
+ printk("bt832: i2c i/o error VPS: rc == %d (should be 2)\n",rc);
- bt832_hexdump(i2c_client_s,buf);
+ bt832_hexdump(i2c_client_s,buf);
// Enable Output
@@ -134,22 +133,22 @@ int bt832_init(struct i2c_client *i2c_client_s)
buf[0]=BT832_VP_CONTROL1; // Reg.40
buf[1]= 0x27 & (~0x01); // Default | !skip
if (2 != (rc = i2c_master_send(i2c_client_s,buf,2)))
- printk("bt832: i2c i/o error EO: rc == %d (should be 2)\n",rc);
+ printk("bt832: i2c i/o error EO: rc == %d (should be 2)\n",rc);
- bt832_hexdump(i2c_client_s,buf);
+ bt832_hexdump(i2c_client_s,buf);
// for testing (even works when no camera attached)
printk("bt832: *** Generate NTSC M Bars *****\n");
buf[0]=BT832_VP_TESTCONTROL0; // Reg. 42
buf[1]=3; // Generate NTSC System M bars, Generate Frame timing internally
- if (2 != (rc = i2c_master_send(i2c_client_s,buf,2)))
- printk("bt832: i2c i/o error MBAR: rc == %d (should be 2)\n",rc);
+ if (2 != (rc = i2c_master_send(i2c_client_s,buf,2)))
+ printk("bt832: i2c i/o error MBAR: rc == %d (should be 2)\n",rc);
printk("Bt832: Camera Present: %s\n",
(buf[1+BT832_CAM_STATUS] & BT832_56_CAMERA_PRESENT) ? "yes":"no");
- bt832_hexdump(i2c_client_s,buf);
+ bt832_hexdump(i2c_client_s,buf);
kfree(buf);
return 1;
}
@@ -162,17 +161,17 @@ static int bt832_attach(struct i2c_adapter *adap, int addr, int kind)
printk("bt832_attach\n");
- client_template.adapter = adap;
- client_template.addr = addr;
+ client_template.adapter = adap;
+ client_template.addr = addr;
- printk("bt832: chip found @ 0x%x\n", addr<<1);
+ printk("bt832: chip found @ 0x%x\n", addr<<1);
- if (NULL == (t = kmalloc(sizeof(*t), GFP_KERNEL)))
- return -ENOMEM;
+ if (NULL == (t = kmalloc(sizeof(*t), GFP_KERNEL)))
+ return -ENOMEM;
memset(t,0,sizeof(*t));
t->client = client_template;
- i2c_set_clientdata(&t->client, t);
- i2c_attach_client(&t->client);
+ i2c_set_clientdata(&t->client, t);
+ i2c_attach_client(&t->client);
if(! bt832_init(&t->client)) {
bt832_detach(&t->client);
@@ -211,7 +210,7 @@ bt832_command(struct i2c_client *client, unsigned int cmd, void *arg)
printk("bt832: command %x\n",cmd);
- switch (cmd) {
+ switch (cmd) {
case BT832_HEXDUMP: {
unsigned char *buf;
buf=kmalloc(65,GFP_KERNEL);
diff --git a/drivers/media/video/bt832.h b/drivers/media/video/bt832.h
index 9b6a8d2c96b5..1ce8fa71f7db 100644
--- a/drivers/media/video/bt832.h
+++ b/drivers/media/video/bt832.h
@@ -233,8 +233,8 @@ SetInterlaceMode( spec.interlace );
/* from web:
Video Sampling
Digital video is a sampled form of analog video. The most common sampling schemes in use today are:
- Pixel Clock Horiz Horiz Vert
- Rate Total Active
+ Pixel Clock Horiz Horiz Vert
+ Rate Total Active
NTSC square pixel 12.27 MHz 780 640 525
NTSC CCIR-601 13.5 MHz 858 720 525
NTSC 4FSc 14.32 MHz 910 768 525
diff --git a/drivers/media/video/bttv-cards.c b/drivers/media/video/bttv-cards.c
index 0881a17d5226..3413bace443a 100644
--- a/drivers/media/video/bttv-cards.c
+++ b/drivers/media/video/bttv-cards.c
@@ -6,7 +6,7 @@
like the big tvcards array for the most part
Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de)
- & Marcus Metzler (mocm@thp.uni-koeln.de)
+ & Marcus Metzler (mocm@thp.uni-koeln.de)
(c) 1999-2001 Gerd Knorr <kraxel@goldbach.in-berlin.de>
This program is free software; you can redistribute it and/or modify
@@ -145,162 +145,163 @@ static struct CARD {
int cardnr;
char *name;
} cards[] __devinitdata = {
- { 0x13eb0070, BTTV_HAUPPAUGE878, "Hauppauge WinTV" },
- { 0x39000070, BTTV_HAUPPAUGE878, "Hauppauge WinTV-D" },
- { 0x45000070, BTTV_HAUPPAUGEPVR, "Hauppauge WinTV/PVR" },
- { 0xff000070, BTTV_OSPREY1x0, "Osprey-100" },
- { 0xff010070, BTTV_OSPREY2x0_SVID,"Osprey-200" },
- { 0xff020070, BTTV_OSPREY500, "Osprey-500" },
- { 0xff030070, BTTV_OSPREY2000, "Osprey-2000" },
- { 0xff040070, BTTV_OSPREY540, "Osprey-540" },
-
- { 0x00011002, BTTV_ATI_TVWONDER, "ATI TV Wonder" },
- { 0x00031002, BTTV_ATI_TVWONDERVE,"ATI TV Wonder/VE" },
-
- { 0x6606107d, BTTV_WINFAST2000, "Leadtek WinFast TV 2000" },
- { 0x6607107d, BTTV_WINFASTVC100, "Leadtek WinFast VC 100" },
- { 0x6609107d, BTTV_WINFAST2000, "Leadtek TV 2000 XP" },
- { 0x263610b4, BTTV_STB2, "STB TV PCI FM, Gateway P/N 6000704" },
- { 0x264510b4, BTTV_STB2, "STB TV PCI FM, Gateway P/N 6000704" },
- { 0x402010fc, BTTV_GVBCTV3PCI, "I-O Data Co. GV-BCTV3/PCI" },
- { 0x405010fc, BTTV_GVBCTV4PCI, "I-O Data Co. GV-BCTV4/PCI" },
- { 0x407010fc, BTTV_GVBCTV5PCI, "I-O Data Co. GV-BCTV5/PCI" },
- { 0xd01810fc, BTTV_GVBCTV5PCI, "I-O Data Co. GV-BCTV5/PCI" },
-
- { 0x001211bd, BTTV_PINNACLE, "Pinnacle PCTV" },
+ { 0x13eb0070, BTTV_BOARD_HAUPPAUGE878, "Hauppauge WinTV" },
+ { 0x39000070, BTTV_BOARD_HAUPPAUGE878, "Hauppauge WinTV-D" },
+ { 0x45000070, BTTV_BOARD_HAUPPAUGEPVR, "Hauppauge WinTV/PVR" },
+ { 0xff000070, BTTV_BOARD_OSPREY1x0, "Osprey-100" },
+ { 0xff010070, BTTV_BOARD_OSPREY2x0_SVID,"Osprey-200" },
+ { 0xff020070, BTTV_BOARD_OSPREY500, "Osprey-500" },
+ { 0xff030070, BTTV_BOARD_OSPREY2000, "Osprey-2000" },
+ { 0xff040070, BTTV_BOARD_OSPREY540, "Osprey-540" },
+ { 0xff070070, BTTV_BOARD_OSPREY440, "Osprey-440" },
+
+ { 0x00011002, BTTV_BOARD_ATI_TVWONDER, "ATI TV Wonder" },
+ { 0x00031002, BTTV_BOARD_ATI_TVWONDERVE,"ATI TV Wonder/VE" },
+
+ { 0x6606107d, BTTV_BOARD_WINFAST2000, "Leadtek WinFast TV 2000" },
+ { 0x6607107d, BTTV_BOARD_WINFASTVC100, "Leadtek WinFast VC 100" },
+ { 0x6609107d, BTTV_BOARD_WINFAST2000, "Leadtek TV 2000 XP" },
+ { 0x263610b4, BTTV_BOARD_STB2, "STB TV PCI FM, Gateway P/N 6000704" },
+ { 0x264510b4, BTTV_BOARD_STB2, "STB TV PCI FM, Gateway P/N 6000704" },
+ { 0x402010fc, BTTV_BOARD_GVBCTV3PCI, "I-O Data Co. GV-BCTV3/PCI" },
+ { 0x405010fc, BTTV_BOARD_GVBCTV4PCI, "I-O Data Co. GV-BCTV4/PCI" },
+ { 0x407010fc, BTTV_BOARD_GVBCTV5PCI, "I-O Data Co. GV-BCTV5/PCI" },
+ { 0xd01810fc, BTTV_BOARD_GVBCTV5PCI, "I-O Data Co. GV-BCTV5/PCI" },
+
+ { 0x001211bd, BTTV_BOARD_PINNACLE, "Pinnacle PCTV" },
/* some cards ship with byteswapped IDs ... */
- { 0x1200bd11, BTTV_PINNACLE, "Pinnacle PCTV [bswap]" },
- { 0xff00bd11, BTTV_PINNACLE, "Pinnacle PCTV [bswap]" },
+ { 0x1200bd11, BTTV_BOARD_PINNACLE, "Pinnacle PCTV [bswap]" },
+ { 0xff00bd11, BTTV_BOARD_PINNACLE, "Pinnacle PCTV [bswap]" },
/* this seems to happen as well ... */
- { 0xff1211bd, BTTV_PINNACLE, "Pinnacle PCTV" },
-
- { 0x3000121a, BTTV_VOODOOTV_FM, "3Dfx VoodooTV FM/ VoodooTV 200" },
- { 0x263710b4, BTTV_VOODOOTV_FM, "3Dfx VoodooTV FM/ VoodooTV 200" },
- { 0x3060121a, BTTV_STB2, "3Dfx VoodooTV 100/ STB OEM" },
-
- { 0x3000144f, BTTV_MAGICTVIEW063, "(Askey Magic/others) TView99 CPH06x" },
- { 0xa005144f, BTTV_MAGICTVIEW063, "CPH06X TView99-Card" },
- { 0x3002144f, BTTV_MAGICTVIEW061, "(Askey Magic/others) TView99 CPH05x" },
- { 0x3005144f, BTTV_MAGICTVIEW061, "(Askey Magic/others) TView99 CPH061/06L (T1/LC)" },
- { 0x5000144f, BTTV_MAGICTVIEW061, "Askey CPH050" },
- { 0x300014ff, BTTV_MAGICTVIEW061, "TView 99 (CPH061)" },
- { 0x300214ff, BTTV_PHOEBE_TVMAS, "Phoebe TV Master (CPH060)" },
-
- { 0x00011461, BTTV_AVPHONE98, "AVerMedia TVPhone98" },
- { 0x00021461, BTTV_AVERMEDIA98, "AVermedia TVCapture 98" },
- { 0x00031461, BTTV_AVPHONE98, "AVerMedia TVPhone98" },
- { 0x00041461, BTTV_AVERMEDIA98, "AVerMedia TVCapture 98" },
- { 0x03001461, BTTV_AVERMEDIA98, "VDOMATE TV TUNER CARD" },
-
- { 0x1117153b, BTTV_TERRATVALUE, "Terratec TValue (Philips PAL B/G)" },
- { 0x1118153b, BTTV_TERRATVALUE, "Terratec TValue (Temic PAL B/G)" },
- { 0x1119153b, BTTV_TERRATVALUE, "Terratec TValue (Philips PAL I)" },
- { 0x111a153b, BTTV_TERRATVALUE, "Terratec TValue (Temic PAL I)" },
-
- { 0x1123153b, BTTV_TERRATVRADIO, "Terratec TV Radio+" },
- { 0x1127153b, BTTV_TERRATV, "Terratec TV+ (V1.05)" },
+ { 0xff1211bd, BTTV_BOARD_PINNACLE, "Pinnacle PCTV" },
+
+ { 0x3000121a, BTTV_BOARD_VOODOOTV_FM, "3Dfx VoodooTV FM/ VoodooTV 200" },
+ { 0x263710b4, BTTV_BOARD_VOODOOTV_FM, "3Dfx VoodooTV FM/ VoodooTV 200" },
+ { 0x3060121a, BTTV_BOARD_STB2, "3Dfx VoodooTV 100/ STB OEM" },
+
+ { 0x3000144f, BTTV_BOARD_MAGICTVIEW063, "(Askey Magic/others) TView99 CPH06x" },
+ { 0xa005144f, BTTV_BOARD_MAGICTVIEW063, "CPH06X TView99-Card" },
+ { 0x3002144f, BTTV_BOARD_MAGICTVIEW061, "(Askey Magic/others) TView99 CPH05x" },
+ { 0x3005144f, BTTV_BOARD_MAGICTVIEW061, "(Askey Magic/others) TView99 CPH061/06L (T1/LC)" },
+ { 0x5000144f, BTTV_BOARD_MAGICTVIEW061, "Askey CPH050" },
+ { 0x300014ff, BTTV_BOARD_MAGICTVIEW061, "TView 99 (CPH061)" },
+ { 0x300214ff, BTTV_BOARD_PHOEBE_TVMAS, "Phoebe TV Master (CPH060)" },
+
+ { 0x00011461, BTTV_BOARD_AVPHONE98, "AVerMedia TVPhone98" },
+ { 0x00021461, BTTV_BOARD_AVERMEDIA98, "AVermedia TVCapture 98" },
+ { 0x00031461, BTTV_BOARD_AVPHONE98, "AVerMedia TVPhone98" },
+ { 0x00041461, BTTV_BOARD_AVERMEDIA98, "AVerMedia TVCapture 98" },
+ { 0x03001461, BTTV_BOARD_AVERMEDIA98, "VDOMATE TV TUNER CARD" },
+
+ { 0x1117153b, BTTV_BOARD_TERRATVALUE, "Terratec TValue (Philips PAL B/G)" },
+ { 0x1118153b, BTTV_BOARD_TERRATVALUE, "Terratec TValue (Temic PAL B/G)" },
+ { 0x1119153b, BTTV_BOARD_TERRATVALUE, "Terratec TValue (Philips PAL I)" },
+ { 0x111a153b, BTTV_BOARD_TERRATVALUE, "Terratec TValue (Temic PAL I)" },
+
+ { 0x1123153b, BTTV_BOARD_TERRATVRADIO, "Terratec TV Radio+" },
+ { 0x1127153b, BTTV_BOARD_TERRATV, "Terratec TV+ (V1.05)" },
/* clashes with FlyVideo
- *{ 0x18521852, BTTV_TERRATV, "Terratec TV+ (V1.10)" }, */
- { 0x1134153b, BTTV_TERRATVALUE, "Terratec TValue (LR102)" },
- { 0x1135153b, BTTV_TERRATVALUER, "Terratec TValue Radio" }, /* LR102 */
- { 0x5018153b, BTTV_TERRATVALUE, "Terratec TValue" }, /* ?? */
- { 0xff3b153b, BTTV_TERRATVALUER, "Terratec TValue Radio" }, /* ?? */
-
- { 0x400015b0, BTTV_ZOLTRIX_GENIE, "Zoltrix Genie TV" },
- { 0x400a15b0, BTTV_ZOLTRIX_GENIE, "Zoltrix Genie TV" },
- { 0x400d15b0, BTTV_ZOLTRIX_GENIE, "Zoltrix Genie TV / Radio" },
- { 0x401015b0, BTTV_ZOLTRIX_GENIE, "Zoltrix Genie TV / Radio" },
- { 0x401615b0, BTTV_ZOLTRIX_GENIE, "Zoltrix Genie TV / Radio" },
-
- { 0x1430aa00, BTTV_PV143, "Provideo PV143A" },
- { 0x1431aa00, BTTV_PV143, "Provideo PV143B" },
- { 0x1432aa00, BTTV_PV143, "Provideo PV143C" },
- { 0x1433aa00, BTTV_PV143, "Provideo PV143D" },
- { 0x1433aa03, BTTV_PV143, "Security Eyes" },
-
- { 0x1460aa00, BTTV_PV150, "Provideo PV150A-1" },
- { 0x1461aa01, BTTV_PV150, "Provideo PV150A-2" },
- { 0x1462aa02, BTTV_PV150, "Provideo PV150A-3" },
- { 0x1463aa03, BTTV_PV150, "Provideo PV150A-4" },
-
- { 0x1464aa04, BTTV_PV150, "Provideo PV150B-1" },
- { 0x1465aa05, BTTV_PV150, "Provideo PV150B-2" },
- { 0x1466aa06, BTTV_PV150, "Provideo PV150B-3" },
- { 0x1467aa07, BTTV_PV150, "Provideo PV150B-4" },
-
- { 0xa132ff00, BTTV_IVC100, "IVC-100" },
- { 0xa1550000, BTTV_IVC200, "IVC-200" },
- { 0xa1550001, BTTV_IVC200, "IVC-200" },
- { 0xa1550002, BTTV_IVC200, "IVC-200" },
- { 0xa1550003, BTTV_IVC200, "IVC-200" },
- { 0xa1550100, BTTV_IVC200, "IVC-200G" },
- { 0xa1550101, BTTV_IVC200, "IVC-200G" },
- { 0xa1550102, BTTV_IVC200, "IVC-200G" },
- { 0xa1550103, BTTV_IVC200, "IVC-200G" },
- { 0xa182ff00, BTTV_IVC120, "IVC-120G" },
- { 0xa182ff01, BTTV_IVC120, "IVC-120G" },
- { 0xa182ff02, BTTV_IVC120, "IVC-120G" },
- { 0xa182ff03, BTTV_IVC120, "IVC-120G" },
- { 0xa182ff04, BTTV_IVC120, "IVC-120G" },
- { 0xa182ff05, BTTV_IVC120, "IVC-120G" },
- { 0xa182ff06, BTTV_IVC120, "IVC-120G" },
- { 0xa182ff07, BTTV_IVC120, "IVC-120G" },
- { 0xa182ff08, BTTV_IVC120, "IVC-120G" },
- { 0xa182ff09, BTTV_IVC120, "IVC-120G" },
- { 0xa182ff0a, BTTV_IVC120, "IVC-120G" },
- { 0xa182ff0b, BTTV_IVC120, "IVC-120G" },
- { 0xa182ff0c, BTTV_IVC120, "IVC-120G" },
- { 0xa182ff0d, BTTV_IVC120, "IVC-120G" },
- { 0xa182ff0e, BTTV_IVC120, "IVC-120G" },
- { 0xa182ff0f, BTTV_IVC120, "IVC-120G" },
-
- { 0x41424344, BTTV_GRANDTEC, "GrandTec Multi Capture" },
- { 0x01020304, BTTV_XGUARD, "Grandtec Grand X-Guard" },
-
- { 0x18501851, BTTV_CHRONOS_VS2, "FlyVideo 98 (LR50)/ Chronos Video Shuttle II" },
- { 0xa0501851, BTTV_CHRONOS_VS2, "FlyVideo 98 (LR50)/ Chronos Video Shuttle II" },
- { 0x18511851, BTTV_FLYVIDEO98EZ, "FlyVideo 98EZ (LR51)/ CyberMail AV" },
- { 0x18521852, BTTV_TYPHOON_TVIEW, "FlyVideo 98FM (LR50)/ Typhoon TView TV/FM Tuner" },
- { 0x41a0a051, BTTV_FLYVIDEO_98FM, "Lifeview FlyVideo 98 LR50 Rev Q" },
- { 0x18501f7f, BTTV_FLYVIDEO_98, "Lifeview Flyvideo 98" },
-
- { 0x010115cb, BTTV_GMV1, "AG GMV1" },
- { 0x010114c7, BTTV_MODTEC_205, "Modular Technology MM201/MM202/MM205/MM210/MM215 PCTV" },
-
- { 0x10b42636, BTTV_HAUPPAUGE878, "STB ???" },
- { 0x217d6606, BTTV_WINFAST2000, "Leadtek WinFast TV 2000" },
- { 0xfff6f6ff, BTTV_WINFAST2000, "Leadtek WinFast TV 2000" },
- { 0x03116000, BTTV_SENSORAY311, "Sensoray 311" },
- { 0x00790e11, BTTV_WINDVR, "Canopus WinDVR PCI" },
- { 0xa0fca1a0, BTTV_ZOLTRIX, "Face to Face Tvmax" },
- { 0x20007063, BTTV_PC_HDTV, "pcHDTV HD-2000 TV"},
- { 0x82b2aa6a, BTTV_SIMUS_GVC1100, "SIMUS GVC1100" },
- { 0x146caa0c, BTTV_PV951, "ituner spectra8" },
- { 0x200a1295, BTTV_PXC200, "ImageNation PXC200A" },
-
- { 0x40111554, BTTV_PV_BT878P_9B, "Prolink Pixelview PV-BT" },
- { 0x17de0a01, BTTV_KWORLD, "Mecer TV/FM/Video Tuner" },
-
- { 0x01051805, BTTV_PICOLO_TETRA_CHIP, "Picolo Tetra Chip #1" },
- { 0x01061805, BTTV_PICOLO_TETRA_CHIP, "Picolo Tetra Chip #2" },
- { 0x01071805, BTTV_PICOLO_TETRA_CHIP, "Picolo Tetra Chip #3" },
- { 0x01081805, BTTV_PICOLO_TETRA_CHIP, "Picolo Tetra Chip #4" },
-
- { 0x15409511, BTTV_ACORP_Y878F, "Acorp Y878F" },
+ *{ 0x18521852, BTTV_BOARD_TERRATV, "Terratec TV+ (V1.10)" }, */
+ { 0x1134153b, BTTV_BOARD_TERRATVALUE, "Terratec TValue (LR102)" },
+ { 0x1135153b, BTTV_BOARD_TERRATVALUER, "Terratec TValue Radio" }, /* LR102 */
+ { 0x5018153b, BTTV_BOARD_TERRATVALUE, "Terratec TValue" }, /* ?? */
+ { 0xff3b153b, BTTV_BOARD_TERRATVALUER, "Terratec TValue Radio" }, /* ?? */
+
+ { 0x400015b0, BTTV_BOARD_ZOLTRIX_GENIE, "Zoltrix Genie TV" },
+ { 0x400a15b0, BTTV_BOARD_ZOLTRIX_GENIE, "Zoltrix Genie TV" },
+ { 0x400d15b0, BTTV_BOARD_ZOLTRIX_GENIE, "Zoltrix Genie TV / Radio" },
+ { 0x401015b0, BTTV_BOARD_ZOLTRIX_GENIE, "Zoltrix Genie TV / Radio" },
+ { 0x401615b0, BTTV_BOARD_ZOLTRIX_GENIE, "Zoltrix Genie TV / Radio" },
+
+ { 0x1430aa00, BTTV_BOARD_PV143, "Provideo PV143A" },
+ { 0x1431aa00, BTTV_BOARD_PV143, "Provideo PV143B" },
+ { 0x1432aa00, BTTV_BOARD_PV143, "Provideo PV143C" },
+ { 0x1433aa00, BTTV_BOARD_PV143, "Provideo PV143D" },
+ { 0x1433aa03, BTTV_BOARD_PV143, "Security Eyes" },
+
+ { 0x1460aa00, BTTV_BOARD_PV150, "Provideo PV150A-1" },
+ { 0x1461aa01, BTTV_BOARD_PV150, "Provideo PV150A-2" },
+ { 0x1462aa02, BTTV_BOARD_PV150, "Provideo PV150A-3" },
+ { 0x1463aa03, BTTV_BOARD_PV150, "Provideo PV150A-4" },
+
+ { 0x1464aa04, BTTV_BOARD_PV150, "Provideo PV150B-1" },
+ { 0x1465aa05, BTTV_BOARD_PV150, "Provideo PV150B-2" },
+ { 0x1466aa06, BTTV_BOARD_PV150, "Provideo PV150B-3" },
+ { 0x1467aa07, BTTV_BOARD_PV150, "Provideo PV150B-4" },
+
+ { 0xa132ff00, BTTV_BOARD_IVC100, "IVC-100" },
+ { 0xa1550000, BTTV_BOARD_IVC200, "IVC-200" },
+ { 0xa1550001, BTTV_BOARD_IVC200, "IVC-200" },
+ { 0xa1550002, BTTV_BOARD_IVC200, "IVC-200" },
+ { 0xa1550003, BTTV_BOARD_IVC200, "IVC-200" },
+ { 0xa1550100, BTTV_BOARD_IVC200, "IVC-200G" },
+ { 0xa1550101, BTTV_BOARD_IVC200, "IVC-200G" },
+ { 0xa1550102, BTTV_BOARD_IVC200, "IVC-200G" },
+ { 0xa1550103, BTTV_BOARD_IVC200, "IVC-200G" },
+ { 0xa182ff00, BTTV_BOARD_IVC120, "IVC-120G" },
+ { 0xa182ff01, BTTV_BOARD_IVC120, "IVC-120G" },
+ { 0xa182ff02, BTTV_BOARD_IVC120, "IVC-120G" },
+ { 0xa182ff03, BTTV_BOARD_IVC120, "IVC-120G" },
+ { 0xa182ff04, BTTV_BOARD_IVC120, "IVC-120G" },
+ { 0xa182ff05, BTTV_BOARD_IVC120, "IVC-120G" },
+ { 0xa182ff06, BTTV_BOARD_IVC120, "IVC-120G" },
+ { 0xa182ff07, BTTV_BOARD_IVC120, "IVC-120G" },
+ { 0xa182ff08, BTTV_BOARD_IVC120, "IVC-120G" },
+ { 0xa182ff09, BTTV_BOARD_IVC120, "IVC-120G" },
+ { 0xa182ff0a, BTTV_BOARD_IVC120, "IVC-120G" },
+ { 0xa182ff0b, BTTV_BOARD_IVC120, "IVC-120G" },
+ { 0xa182ff0c, BTTV_BOARD_IVC120, "IVC-120G" },
+ { 0xa182ff0d, BTTV_BOARD_IVC120, "IVC-120G" },
+ { 0xa182ff0e, BTTV_BOARD_IVC120, "IVC-120G" },
+ { 0xa182ff0f, BTTV_BOARD_IVC120, "IVC-120G" },
+
+ { 0x41424344, BTTV_BOARD_GRANDTEC, "GrandTec Multi Capture" },
+ { 0x01020304, BTTV_BOARD_XGUARD, "Grandtec Grand X-Guard" },
+
+ { 0x18501851, BTTV_BOARD_CHRONOS_VS2, "FlyVideo 98 (LR50)/ Chronos Video Shuttle II" },
+ { 0xa0501851, BTTV_BOARD_CHRONOS_VS2, "FlyVideo 98 (LR50)/ Chronos Video Shuttle II" },
+ { 0x18511851, BTTV_BOARD_FLYVIDEO98EZ, "FlyVideo 98EZ (LR51)/ CyberMail AV" },
+ { 0x18521852, BTTV_BOARD_TYPHOON_TVIEW, "FlyVideo 98FM (LR50)/ Typhoon TView TV/FM Tuner" },
+ { 0x41a0a051, BTTV_BOARD_FLYVIDEO_98FM, "Lifeview FlyVideo 98 LR50 Rev Q" },
+ { 0x18501f7f, BTTV_BOARD_FLYVIDEO_98, "Lifeview Flyvideo 98" },
+
+ { 0x010115cb, BTTV_BOARD_GMV1, "AG GMV1" },
+ { 0x010114c7, BTTV_BOARD_MODTEC_205, "Modular Technology MM201/MM202/MM205/MM210/MM215 PCTV" },
+
+ { 0x10b42636, BTTV_BOARD_HAUPPAUGE878, "STB ???" },
+ { 0x217d6606, BTTV_BOARD_WINFAST2000, "Leadtek WinFast TV 2000" },
+ { 0xfff6f6ff, BTTV_BOARD_WINFAST2000, "Leadtek WinFast TV 2000" },
+ { 0x03116000, BTTV_BOARD_SENSORAY311, "Sensoray 311" },
+ { 0x00790e11, BTTV_BOARD_WINDVR, "Canopus WinDVR PCI" },
+ { 0xa0fca1a0, BTTV_BOARD_ZOLTRIX, "Face to Face Tvmax" },
+ { 0x20007063, BTTV_BOARD_PC_HDTV, "pcHDTV HD-2000 TV"},
+ { 0x82b2aa6a, BTTV_BOARD_SIMUS_GVC1100, "SIMUS GVC1100" },
+ { 0x146caa0c, BTTV_BOARD_PV951, "ituner spectra8" },
+ { 0x200a1295, BTTV_BOARD_PXC200, "ImageNation PXC200A" },
+
+ { 0x40111554, BTTV_BOARD_PV_BT878P_9B, "Prolink Pixelview PV-BT" },
+ { 0x17de0a01, BTTV_BOARD_KWORLD, "Mecer TV/FM/Video Tuner" },
+
+ { 0x01051805, BTTV_BOARD_PICOLO_TETRA_CHIP, "Picolo Tetra Chip #1" },
+ { 0x01061805, BTTV_BOARD_PICOLO_TETRA_CHIP, "Picolo Tetra Chip #2" },
+ { 0x01071805, BTTV_BOARD_PICOLO_TETRA_CHIP, "Picolo Tetra Chip #3" },
+ { 0x01081805, BTTV_BOARD_PICOLO_TETRA_CHIP, "Picolo Tetra Chip #4" },
+
+ { 0x15409511, BTTV_BOARD_ACORP_Y878F, "Acorp Y878F" },
/* likely broken, vendor id doesn't match the other magic views ...
- * { 0xa0fca04f, BTTV_MAGICTVIEW063, "Guillemot Maxi TV Video 3" }, */
+ * { 0xa0fca04f, BTTV_BOARD_MAGICTVIEW063, "Guillemot Maxi TV Video 3" }, */
/* DVB cards (using pci function .1 for mpeg data xfer) */
- { 0x01010071, BTTV_NEBULA_DIGITV, "Nebula Electronics DigiTV" },
- { 0x07611461, BTTV_AVDVBT_761, "AverMedia AverTV DVB-T 761" },
- { 0x001c11bd, BTTV_PINNACLESAT, "Pinnacle PCTV Sat" },
- { 0x002611bd, BTTV_TWINHAN_DST, "Pinnacle PCTV SAT CI" },
- { 0x00011822, BTTV_TWINHAN_DST, "Twinhan VisionPlus DVB" },
- { 0xfc00270f, BTTV_TWINHAN_DST, "ChainTech digitop DST-1000 DVB-S" },
- { 0x07711461, BTTV_AVDVBT_771, "AVermedia AverTV DVB-T 771" },
- { 0xdb1018ac, BTTV_DVICO_DVBT_LITE, "DViCO FusionHDTV DVB-T Lite" },
- { 0xd50018ac, BTTV_DVICO_FUSIONHDTV_5_LITE, "DViCO FusionHDTV 5 Lite" },
+ { 0x01010071, BTTV_BOARD_NEBULA_DIGITV, "Nebula Electronics DigiTV" },
+ { 0x07611461, BTTV_BOARD_AVDVBT_761, "AverMedia AverTV DVB-T 761" },
+ { 0x001c11bd, BTTV_BOARD_PINNACLESAT, "Pinnacle PCTV Sat" },
+ { 0x002611bd, BTTV_BOARD_TWINHAN_DST, "Pinnacle PCTV SAT CI" },
+ { 0x00011822, BTTV_BOARD_TWINHAN_DST, "Twinhan VisionPlus DVB" },
+ { 0xfc00270f, BTTV_BOARD_TWINHAN_DST, "ChainTech digitop DST-1000 DVB-S" },
+ { 0x07711461, BTTV_BOARD_AVDVBT_771, "AVermedia AverTV DVB-T 771" },
+ { 0xdb1018ac, BTTV_BOARD_DVICO_DVBT_LITE, "DViCO FusionHDTV DVB-T Lite" },
+ { 0xd50018ac, BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE, "DViCO FusionHDTV 5 Lite" },
{ 0, -1, NULL }
};
@@ -309,2116 +310,2494 @@ static struct CARD {
/* array with description for bt848 / bt878 tv/grabber cards */
struct tvcard bttv_tvcards[] = {
-{
-/* ---- card 0x00 ---------------------------------- */
- .name = " *** UNKNOWN/GENERIC *** ",
- .video_inputs = 4,
- .audio_inputs = 1,
- .tuner = 0,
- .svhs = 2,
- .muxsel = { 2, 3, 1, 0},
- .tuner_type = -1,
- .tuner_addr = ADDR_UNSET,
-},{
- .name = "MIRO PCTV",
- .video_inputs = 4,
- .audio_inputs = 1,
- .tuner = 0,
- .svhs = 2,
- .gpiomask = 15,
- .muxsel = { 2, 3, 1, 1},
- .audiomux = { 2, 0, 0, 0, 10},
- .needs_tvaudio = 1,
- .tuner_type = -1,
- .tuner_addr = ADDR_UNSET,
-},{
- .name = "Hauppauge (bt848)",
- .video_inputs = 4,
- .audio_inputs = 1,
- .tuner = 0,
- .svhs = 2,
- .gpiomask = 7,
- .muxsel = { 2, 3, 1, 1},
- .audiomux = { 0, 1, 2, 3, 4},
- .needs_tvaudio = 1,
- .tuner_type = -1,
- .tuner_addr = ADDR_UNSET,
-},{
- .name = "STB, Gateway P/N 6000699 (bt848)",
- .video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
- .svhs = 2,
- .gpiomask = 7,
- .muxsel = { 2, 3, 1, 1},
- .audiomux = { 4, 0, 2, 3, 1},
- .no_msp34xx = 1,
- .needs_tvaudio = 1,
- .tuner_type = TUNER_PHILIPS_NTSC,
- .tuner_addr = ADDR_UNSET,
- .pll = PLL_28,
- .has_radio = 1,
-},{
-
-/* ---- card 0x04 ---------------------------------- */
- .name = "Intel Create and Share PCI/ Smart Video Recorder III",
- .video_inputs = 4,
- .audio_inputs = 0,
- .tuner = -1,
- .svhs = 2,
- .gpiomask = 0,
- .muxsel = { 2, 3, 1, 1},
- .audiomux = { 0 },
- .needs_tvaudio = 0,
- .tuner_type = 4,
- .tuner_addr = ADDR_UNSET,
-},{
- .name = "Diamond DTV2000",
- .video_inputs = 4,
- .audio_inputs = 1,
- .tuner = 0,
- .svhs = 2,
- .gpiomask = 3,
- .muxsel = { 2, 3, 1, 0},
- .audiomux = { 0, 1, 0, 1, 3},
- .needs_tvaudio = 1,
- .tuner_type = -1,
- .tuner_addr = ADDR_UNSET,
-},{
- .name = "AVerMedia TVPhone",
- .video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
- .svhs = 3,
- .muxsel = { 2, 3, 1, 1},
- .gpiomask = 0x0f,
- .audiomux = { 0x0c, 0x04, 0x08, 0x04, 0},
- /* 0x04 for some cards ?? */
- .needs_tvaudio = 1,
- .tuner_type = -1,
- .tuner_addr = ADDR_UNSET,
- .audio_hook = avermedia_tvphone_audio,
- .has_remote = 1,
-},{
- .name = "MATRIX-Vision MV-Delta",
- .video_inputs = 5,
- .audio_inputs = 1,
- .tuner = -1,
- .svhs = 3,
- .gpiomask = 0,
- .muxsel = { 2, 3, 1, 0, 0},
- .audiomux = {0 },
- .needs_tvaudio = 1,
- .tuner_type = -1,
- .tuner_addr = ADDR_UNSET,
-},{
-
-/* ---- card 0x08 ---------------------------------- */
- .name = "Lifeview FlyVideo II (Bt848) LR26 / MAXI TV Video PCI2 LR26",
- .video_inputs = 4,
- .audio_inputs = 1,
- .tuner = 0,
- .svhs = 2,
- .gpiomask = 0xc00,
- .muxsel = { 2, 3, 1, 1},
- .audiomux = { 0, 0xc00, 0x800, 0x400, 0xc00, 0},
- .needs_tvaudio = 1,
- .pll = PLL_28,
- .tuner_type = -1,
- .tuner_addr = ADDR_UNSET,
-},{
- .name = "IMS/IXmicro TurboTV",
- .video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
- .svhs = 2,
- .gpiomask = 3,
- .muxsel = { 2, 3, 1, 1},
- .audiomux = { 1, 1, 2, 3, 0},
- .needs_tvaudio = 0,
- .pll = PLL_28,
- .tuner_type = TUNER_TEMIC_PAL,
- .tuner_addr = ADDR_UNSET,
-},{
- .name = "Hauppauge (bt878)",
- .video_inputs = 4,
- .audio_inputs = 1,
- .tuner = 0,
- .svhs = 2,
- .gpiomask = 0x0f, /* old: 7 */
- .muxsel = { 2, 0, 1, 1},
- .audiomux = { 0, 1, 2, 3, 4},
- .needs_tvaudio = 1,
- .pll = PLL_28,
- .tuner_type = -1,
- .tuner_addr = ADDR_UNSET,
-},{
- .name = "MIRO PCTV pro",
- .video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
- .svhs = 2,
- .gpiomask = 0x3014f,
- .muxsel = { 2, 3, 1, 1},
- .audiomux = { 0x20001,0x10001, 0, 0,10},
- .needs_tvaudio = 1,
- .tuner_type = -1,
- .tuner_addr = ADDR_UNSET,
-},{
-
-/* ---- card 0x0c ---------------------------------- */
- .name = "ADS Technologies Channel Surfer TV (bt848)",
- .video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
- .svhs = 2,
- .gpiomask = 15,
- .muxsel = { 2, 3, 1, 1},
- .audiomux = { 13, 14, 11, 7, 0, 0},
- .needs_tvaudio = 1,
- .tuner_type = -1,
- .tuner_addr = ADDR_UNSET,
-},{
- .name = "AVerMedia TVCapture 98",
- .video_inputs = 3,
- .audio_inputs = 4,
- .tuner = 0,
- .svhs = 2,
- .gpiomask = 15,
- .muxsel = { 2, 3, 1, 1},
- .audiomux = { 13, 14, 11, 7, 0, 0},
- .needs_tvaudio = 1,
- .msp34xx_alt = 1,
- .pll = PLL_28,
- .tuner_type = TUNER_PHILIPS_PAL,
- .tuner_addr = ADDR_UNSET,
- .audio_hook = avermedia_tv_stereo_audio,
-},{
- .name = "Aimslab Video Highway Xtreme (VHX)",
- .video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
- .svhs = 2,
- .gpiomask = 7,
- .muxsel = { 2, 3, 1, 1},
- .audiomux = { 0, 2, 1, 3, 4}, /* old: { 0, 1, 2, 3, 4} */
- .needs_tvaudio = 1,
- .pll = PLL_28,
- .tuner_type = -1,
- .tuner_addr = ADDR_UNSET,
-},{
- .name = "Zoltrix TV-Max",
- .video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
- .svhs = 2,
- .gpiomask = 15,
- .muxsel = { 2, 3, 1, 1},
- .audiomux = {0 , 0, 1 , 0, 10},
- .needs_tvaudio = 1,
- .tuner_type = -1,
- .tuner_addr = ADDR_UNSET,
-},{
-
-/* ---- card 0x10 ---------------------------------- */
- .name = "Prolink Pixelview PlayTV (bt878)",
- .video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
- .svhs = 2,
- .gpiomask = 0x01fe00,
- .muxsel = { 2, 3, 1, 1},
- /* 2003-10-20 by "Anton A. Arapov" <arapov@mail.ru> */
- .audiomux = { 0x001e00, 0, 0x018000, 0x014000, 0x002000, 0 },
- .needs_tvaudio = 1,
- .pll = PLL_28,
- .tuner_type = -1,
-},{
- .name = "Leadtek WinView 601",
- .video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
- .svhs = 2,
- .gpiomask = 0x8300f8,
- .muxsel = { 2, 3, 1, 1,0},
- .audiomux = { 0x4fa007,0xcfa007,0xcfa007,0xcfa007,0xcfa007,0xcfa007},
- .needs_tvaudio = 1,
- .tuner_type = -1,
- .tuner_addr = ADDR_UNSET,
- .audio_hook = winview_audio,
- .has_radio = 1,
-},{
- .name = "AVEC Intercapture",
- .video_inputs = 3,
- .audio_inputs = 2,
- .tuner = 0,
- .svhs = 2,
- .gpiomask = 0,
- .muxsel = {2, 3, 1, 1},
- .audiomux = {1, 0, 0, 0, 0},
- .needs_tvaudio = 1,
- .tuner_type = -1,
- .tuner_addr = ADDR_UNSET,
-},{
- .name = "Lifeview FlyVideo II EZ /FlyKit LR38 Bt848 (capture only)",
- .video_inputs = 4,
- .audio_inputs = 1,
- .tuner = -1,
- .svhs = -1,
- .gpiomask = 0x8dff00,
- .muxsel = { 2, 3, 1, 1},
- .audiomux = { 0 },
- .no_msp34xx = 1,
- .tuner_type = -1,
- .tuner_addr = ADDR_UNSET,
-},{
-
-/* ---- card 0x14 ---------------------------------- */
- .name = "CEI Raffles Card",
- .video_inputs = 3,
- .audio_inputs = 3,
- .tuner = 0,
- .svhs = 2,
- .muxsel = {2, 3, 1, 1},
- .tuner_type = -1,
- .tuner_addr = ADDR_UNSET,
-},{
- .name = "Lifeview FlyVideo 98/ Lucky Star Image World ConferenceTV LR50",
- .video_inputs = 4,
- .audio_inputs = 2, /* tuner, line in */
- .tuner = 0,
- .svhs = 2,
- .gpiomask = 0x1800,
- .muxsel = { 2, 3, 1, 1},
- .audiomux = { 0, 0x800, 0x1000, 0x1000, 0x1800},
- .pll = PLL_28,
- .tuner_type = TUNER_PHILIPS_PAL_I,
- .tuner_addr = ADDR_UNSET,
-},{
- .name = "Askey CPH050/ Phoebe Tv Master + FM",
- .video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
- .svhs = 2,
- .gpiomask = 0xc00,
- .muxsel = { 2, 3, 1, 1},
- .audiomux = {0, 1, 0x800, 0x400, 0xc00, 0},
- .needs_tvaudio = 1,
- .pll = PLL_28,
- .tuner_type = -1,
- .tuner_addr = ADDR_UNSET,
-},{
- .name = "Modular Technology MM201/MM202/MM205/MM210/MM215 PCTV, bt878",
- .video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
- .svhs = -1,
- .gpiomask = 7,
- .muxsel = { 2, 3, -1 },
- .digital_mode = DIGITAL_MODE_CAMERA,
- .audiomux = { 0, 0, 0, 0, 0 },
- .no_msp34xx = 1,
- .pll = PLL_28,
- .tuner_type = TUNER_ALPS_TSBB5_PAL_I,
- .tuner_addr = ADDR_UNSET,
-},{
-
-/* ---- card 0x18 ---------------------------------- */
- .name = "Askey CPH05X/06X (bt878) [many vendors]",
- .video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
- .svhs = 2,
- .gpiomask = 0xe00,
- .muxsel = { 2, 3, 1, 1},
- .audiomux = {0x400, 0x400, 0x400, 0x400, 0xc00},
- .needs_tvaudio = 1,
- .pll = PLL_28,
- .tuner_type = -1,
- .tuner_addr = ADDR_UNSET,
- .has_remote = 1,
-},{
- .name = "Terratec TerraTV+ Version 1.0 (Bt848)/ Terra TValue Version 1.0/ Vobis TV-Boostar",
- .video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
- .svhs = 2,
- .gpiomask = 0x1f0fff,
- .muxsel = { 2, 3, 1, 1},
- .audiomux = { 0x20000, 0x30000, 0x10000, 0, 0x40000},
- .needs_tvaudio = 0,
- .tuner_type = TUNER_PHILIPS_PAL,
- .tuner_addr = ADDR_UNSET,
- .audio_hook = terratv_audio,
-},{
- .name = "Hauppauge WinCam newer (bt878)",
- .video_inputs = 4,
- .audio_inputs = 1,
- .tuner = 0,
- .svhs = 3,
- .gpiomask = 7,
- .muxsel = { 2, 0, 1, 1},
- .audiomux = { 0, 1, 2, 3, 4},
- .needs_tvaudio = 1,
- .tuner_type = -1,
- .tuner_addr = ADDR_UNSET,
-},{
- .name = "Lifeview FlyVideo 98/ MAXI TV Video PCI2 LR50",
- .video_inputs = 4,
- .audio_inputs = 2,
- .tuner = 0,
- .svhs = 2,
- .gpiomask = 0x1800,
- .muxsel = { 2, 3, 1, 1},
- .audiomux = { 0, 0x800, 0x1000, 0x1000, 0x1800},
- .pll = PLL_28,
- .tuner_type = TUNER_PHILIPS_SECAM,
- .tuner_addr = ADDR_UNSET,
-},{
-
-/* ---- card 0x1c ---------------------------------- */
- .name = "Terratec TerraTV+ Version 1.1 (bt878)",
- .video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
- .svhs = 2,
- .gpiomask = 0x1f0fff,
- .muxsel = { 2, 3, 1, 1},
- .audiomux = { 0x20000, 0x30000, 0x10000, 0x00000, 0x40000},
- .needs_tvaudio = 0,
- .tuner_type = TUNER_PHILIPS_PAL,
- .tuner_addr = ADDR_UNSET,
- .audio_hook = terratv_audio,
- /* GPIO wiring:
- External 20 pin connector (for Active Radio Upgrade board)
- gpio00: i2c-sda
- gpio01: i2c-scl
- gpio02: om5610-data
- gpio03: om5610-clk
- gpio04: om5610-wre
- gpio05: om5610-stereo
- gpio06: rds6588-davn
- gpio07: Pin 7 n.c.
- gpio08: nIOW
- gpio09+10: nIOR, nSEL ?? (bt878)
- gpio09: nIOR (bt848)
- gpio10: nSEL (bt848)
- Sound Routing:
- gpio16: u2-A0 (1st 4052bt)
- gpio17: u2-A1
- gpio18: u2-nEN
- gpio19: u4-A0 (2nd 4052)
- gpio20: u4-A1
- u4-nEN - GND
- Btspy:
- 00000 : Cdrom (internal audio input)
- 10000 : ext. Video audio input
- 20000 : TV Mono
- a0000 : TV Mono/2
- 1a0000 : TV Stereo
- 30000 : Radio
- 40000 : Mute
-*/
-
-},{
- /* Jannik Fritsch <jannik@techfak.uni-bielefeld.de> */
- .name = "Imagenation PXC200",
- .video_inputs = 5,
- .audio_inputs = 1,
- .tuner = -1,
- .svhs = 1, /* was: 4 */
- .gpiomask = 0,
- .muxsel = { 2, 3, 1, 0, 0},
- .audiomux = { 0 },
- .needs_tvaudio = 1,
- .tuner_type = -1,
- .tuner_addr = ADDR_UNSET,
- .muxsel_hook = PXC200_muxsel,
-
-},{
- .name = "Lifeview FlyVideo 98 LR50",
- .video_inputs = 4,
- .audio_inputs = 1,
- .tuner = 0,
- .svhs = 2,
- .gpiomask = 0x1800, /* 0x8dfe00 */
- .muxsel = { 2, 3, 1, 1},
- .audiomux = { 0, 0x0800, 0x1000, 0x1000, 0x1800, 0 },
- .pll = PLL_28,
- .tuner_type = -1,
- .tuner_addr = ADDR_UNSET,
-},{
- .name = "Formac iProTV, Formac ProTV I (bt848)",
- .video_inputs = 4,
- .audio_inputs = 1,
- .tuner = 0,
- .svhs = 3,
- .gpiomask = 1,
- .muxsel = { 2, 3, 1, 1},
- .audiomux = { 1, 0, 0, 0, 0 },
- .pll = PLL_28,
- .tuner_type = TUNER_PHILIPS_PAL,
- .tuner_addr = ADDR_UNSET,
-},{
-
-/* ---- card 0x20 ---------------------------------- */
- .name = "Intel Create and Share PCI/ Smart Video Recorder III",
- .video_inputs = 4,
- .audio_inputs = 0,
- .tuner = -1,
- .svhs = 2,
- .gpiomask = 0,
- .muxsel = { 2, 3, 1, 1},
- .audiomux = { 0 },
- .needs_tvaudio = 0,
- .tuner_type = 4,
- .tuner_addr = ADDR_UNSET,
-},{
- .name = "Terratec TerraTValue Version Bt878",
- .video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
- .svhs = 2,
- .gpiomask = 0xffff00,
- .muxsel = { 2, 3, 1, 1},
- .audiomux = { 0x500, 0, 0x300, 0x900, 0x900},
- .needs_tvaudio = 1,
- .pll = PLL_28,
- .tuner_type = TUNER_PHILIPS_PAL,
- .tuner_addr = ADDR_UNSET,
-},{
- .name = "Leadtek WinFast 2000/ WinFast 2000 XP",
- .video_inputs = 4,
- .audio_inputs = 1,
- .tuner = 0,
- .svhs = 2,
- .muxsel = { 2, 3, 1, 1, 0}, /* TV, CVid, SVid, CVid over SVid connector */
- /* Alexander Varakin <avarakin@hotmail.com> [stereo version] */
- .gpiomask = 0xb33000,
- .audiomux = { 0x122000,0x1000,0x0000,0x620000,0x800000 },
- /* Audio Routing for "WinFast 2000 XP" (no tv stereo !)
- gpio23 -- hef4052:nEnable (0x800000)
- gpio12 -- hef4052:A1
- gpio13 -- hef4052:A0
- 0x0000: external audio
- 0x1000: FM
- 0x2000: TV
- 0x3000: n.c.
- Note: There exists another variant "Winfast 2000" with tv stereo !?
- Note: eeprom only contains FF and pci subsystem id 107d:6606
- */
- .needs_tvaudio = 0,
- .pll = PLL_28,
- .has_radio = 1,
- .tuner_type = 5, /* default for now, gpio reads BFFF06 for Pal bg+dk */
- .tuner_addr = ADDR_UNSET,
- .audio_hook = winfast2000_audio,
- .has_remote = 1,
-},{
- .name = "Lifeview FlyVideo 98 LR50 / Chronos Video Shuttle II",
- .video_inputs = 4,
- .audio_inputs = 3,
- .tuner = 0,
- .svhs = 2,
- .gpiomask = 0x1800,
- .muxsel = { 2, 3, 1, 1},
- .audiomux = { 0, 0x800, 0x1000, 0x1000, 0x1800},
- .pll = PLL_28,
- .tuner_type = -1,
- .tuner_addr = ADDR_UNSET,
-},{
-
-/* ---- card 0x24 ---------------------------------- */
- .name = "Lifeview FlyVideo 98FM LR50 / Typhoon TView TV/FM Tuner",
- .video_inputs = 4,
- .audio_inputs = 3,
- .tuner = 0,
- .svhs = 2,
- .gpiomask = 0x1800,
- .muxsel = { 2, 3, 1, 1},
- .audiomux = { 0, 0x800, 0x1000, 0x1000, 0x1800, 0 },
- .pll = PLL_28,
- .tuner_type = -1,
- .tuner_addr = ADDR_UNSET,
- .has_radio = 1,
-},{
- .name = "Prolink PixelView PlayTV pro",
- .video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
- .svhs = 2,
- .gpiomask = 0xff,
- .muxsel = { 2, 3, 1, 1 },
- .audiomux = { 0x21, 0x20, 0x24, 0x2c, 0x29, 0x29 },
- .no_msp34xx = 1,
- .pll = PLL_28,
- .tuner_type = -1,
- .tuner_addr = ADDR_UNSET,
-},{
- .name = "Askey CPH06X TView99",
- .video_inputs = 4,
- .audio_inputs = 1,
- .tuner = 0,
- .svhs = 2,
- .gpiomask = 0x551e00,
- .muxsel = { 2, 3, 1, 0},
- .audiomux = { 0x551400, 0x551200, 0, 0, 0x551c00, 0x551200 },
- .needs_tvaudio = 1,
- .pll = PLL_28,
- .tuner_type = 1,
- .tuner_addr = ADDR_UNSET,
- .has_remote = 1,
-},{
- .name = "Pinnacle PCTV Studio/Rave",
- .video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
- .svhs = 2,
- .gpiomask = 0x03000F,
- .muxsel = { 2, 3, 1, 1},
- .audiomux = { 2, 0xd0001, 0, 0, 1},
- .needs_tvaudio = 0,
- .pll = PLL_28,
- .tuner_type = -1,
- .tuner_addr = ADDR_UNSET,
-},{
-
-/* ---- card 0x28 ---------------------------------- */
- .name = "STB TV PCI FM, Gateway P/N 6000704 (bt878), 3Dfx VoodooTV 100",
- .video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
- .svhs = 2,
- .gpiomask = 7,
- .muxsel = { 2, 3, 1, 1},
- .audiomux = { 4, 0, 2, 3, 1},
- .no_msp34xx = 1,
- .needs_tvaudio = 1,
- .tuner_type = TUNER_PHILIPS_NTSC,
- .tuner_addr = ADDR_UNSET,
- .pll = PLL_28,
- .has_radio = 1,
-},{
- .name = "AVerMedia TVPhone 98",
- .video_inputs = 3,
- .audio_inputs = 4,
- .tuner = 0,
- .svhs = 2,
- .gpiomask = 15,
- .muxsel = { 2, 3, 1, 1},
- .audiomux = { 13, 4, 11, 7, 0, 0},
- .needs_tvaudio = 1,
- .pll = PLL_28,
- .tuner_type = -1,
- .tuner_addr = ADDR_UNSET,
- .has_radio = 1,
- .audio_hook = avermedia_tvphone_audio,
-},{
- .name = "ProVideo PV951", /* pic16c54 */
- .video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
- .svhs = 2,
- .gpiomask = 0,
- .muxsel = { 2, 3, 1, 1},
- .audiomux = { 0, 0, 0, 0, 0},
- .needs_tvaudio = 1,
- .no_msp34xx = 1,
- .pll = PLL_28,
- .tuner_type = 1,
- .tuner_addr = ADDR_UNSET,
-},{
- .name = "Little OnAir TV",
- .video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
- .svhs = 2,
- .gpiomask = 0xe00b,
- .muxsel = {2, 3, 1, 1},
- .audiomux = {0xff9ff6, 0xff9ff6, 0xff1ff7, 0, 0xff3ffc},
- .no_msp34xx = 1,
- .tuner_type = -1,
- .tuner_addr = ADDR_UNSET,
-},{
-
-/* ---- card 0x2c ---------------------------------- */
- .name = "Sigma TVII-FM",
- .video_inputs = 2,
- .audio_inputs = 1,
- .tuner = 0,
- .svhs = -1,
- .gpiomask = 3,
- .muxsel = {2, 3, 1, 1},
- .audiomux = {1, 1, 0, 2, 3},
- .no_msp34xx = 1,
- .pll = PLL_NONE,
- .tuner_type = -1,
- .tuner_addr = ADDR_UNSET,
-},{
- .name = "MATRIX-Vision MV-Delta 2",
- .video_inputs = 5,
- .audio_inputs = 1,
- .tuner = -1,
- .svhs = 3,
- .gpiomask = 0,
- .muxsel = { 2, 3, 1, 0, 0},
- .audiomux = {0 },
- .no_msp34xx = 1,
- .pll = PLL_28,
- .tuner_type = -1,
- .tuner_addr = ADDR_UNSET,
-},{
- .name = "Zoltrix Genie TV/FM",
- .video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
- .svhs = 2,
- .gpiomask = 0xbcf03f,
- .muxsel = { 2, 3, 1, 1},
- .audiomux = { 0xbc803f, 0xbc903f, 0xbcb03f, 0, 0xbcb03f},
- .no_msp34xx = 1,
- .pll = PLL_28,
- .tuner_type = 21,
- .tuner_addr = ADDR_UNSET,
-},{
- .name = "Terratec TV/Radio+",
- .video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
- .svhs = 2,
- .gpiomask = 0x70000,
- .muxsel = { 2, 3, 1, 1},
- .audiomux = { 0x20000, 0x30000, 0x10000, 0, 0x40000, 0x20000 },
- .needs_tvaudio = 1,
- .no_msp34xx = 1,
- .pll = PLL_35,
- .tuner_type = 1,
- .tuner_addr = ADDR_UNSET,
- .has_radio = 1,
-},{
-
-/* ---- card 0x30 ---------------------------------- */
- .name = "Askey CPH03x/ Dynalink Magic TView",
- .video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
- .svhs = 2,
- .gpiomask = 15,
- .muxsel = { 2, 3, 1, 1},
- .audiomux = {2,0,0,0,1},
- .needs_tvaudio = 1,
- .pll = PLL_28,
- .tuner_type = -1,
- .tuner_addr = ADDR_UNSET,
-},{
- .name = "IODATA GV-BCTV3/PCI",
- .video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
- .svhs = 2,
- .gpiomask = 0x010f00,
- .muxsel = {2, 3, 0, 0},
- .audiomux = {0x10000, 0, 0x10000, 0, 0, 0},
- .no_msp34xx = 1,
- .pll = PLL_28,
- .tuner_type = TUNER_ALPS_TSHC6_NTSC,
- .tuner_addr = ADDR_UNSET,
- .audio_hook = gvbctv3pci_audio,
-},{
- .name = "Prolink PV-BT878P+4E / PixelView PlayTV PAK / Lenco MXTV-9578 CP",
- .video_inputs = 5,
- .audio_inputs = 1,
- .tuner = 0,
- .svhs = 3,
- .gpiomask = 0xAA0000,
- .muxsel = { 2,3,1,1,-1 },
- .digital_mode = DIGITAL_MODE_CAMERA,
- .audiomux = { 0x20000, 0, 0x80000, 0x80000, 0xa8000, 0x46000 },
- .no_msp34xx = 1,
- .pll = PLL_28,
- .tuner_type = TUNER_PHILIPS_PAL_I,
- .tuner_addr = ADDR_UNSET,
- .has_remote = 1,
- /* GPIO wiring: (different from Rev.4C !)
- GPIO17: U4.A0 (first hef4052bt)
- GPIO19: U4.A1
- GPIO20: U5.A1 (second hef4052bt)
- GPIO21: U4.nEN
- GPIO22: BT832 Reset Line
- GPIO23: A5,A0, U5,nEN
- Note: At i2c=0x8a is a Bt832 chip, which changes to 0x88 after being reset via GPIO22
- */
-},{
- .name = "Eagle Wireless Capricorn2 (bt878A)",
- .video_inputs = 4,
- .audio_inputs = 1,
- .tuner = 0,
- .svhs = 2,
- .gpiomask = 7,
- .muxsel = { 2, 0, 1, 1},
- .audiomux = { 0, 1, 2, 3, 4},
- .pll = PLL_28,
- .tuner_type = -1 /* TUNER_ALPS_TMDH2_NTSC */,
- .tuner_addr = ADDR_UNSET,
-},{
-
-/* ---- card 0x34 ---------------------------------- */
- /* David Härdeman <david@2gen.com> */
- .name = "Pinnacle PCTV Studio Pro",
- .video_inputs = 4,
- .audio_inputs = 1,
- .tuner = 0,
- .svhs = 3,
- .gpiomask = 0x03000F,
- .muxsel = { 2, 3, 1, 1},
- .audiomux = { 1, 0xd0001, 0, 0, 10},
- /* sound path (5 sources):
- MUX1 (mask 0x03), Enable Pin 0x08 (0=enable, 1=disable)
- 0= ext. Audio IN
- 1= from MUX2
- 2= Mono TV sound from Tuner
- 3= not connected
- MUX2 (mask 0x30000):
- 0,2,3= from MSP34xx
- 1= FM stereo Radio from Tuner */
- .needs_tvaudio = 0,
- .pll = PLL_28,
- .tuner_type = -1,
- .tuner_addr = ADDR_UNSET,
-},{
- /* Claas Langbehn <claas@bigfoot.com>,
- Sven Grothklags <sven@upb.de> */
- .name = "Typhoon TView RDS + FM Stereo / KNC1 TV Station RDS",
- .video_inputs = 4,
- .audio_inputs = 3,
- .tuner = 0,
- .svhs = 2,
- .gpiomask = 0x1c,
- .muxsel = { 2, 3, 1, 1},
- .audiomux = { 0, 0, 0x10, 8, 4 },
- .needs_tvaudio = 1,
- .pll = PLL_28,
- .tuner_type = TUNER_PHILIPS_PAL,
- .tuner_addr = ADDR_UNSET,
- .has_radio = 1,
-},{
- /* Tim Röstermundt <rosterm@uni-muenster.de>
- in de.comp.os.unix.linux.hardware:
- options bttv card=0 pll=1 radio=1 gpiomask=0x18e0
- audiomux=0x44c71f,0x44d71f,0,0x44d71f,0x44dfff
- options tuner type=5 */
- .name = "Lifeview FlyVideo 2000 /FlyVideo A2/ Lifetec LT 9415 TV [LR90]",
- .video_inputs = 4,
- .audio_inputs = 1,
- .tuner = 0,
- .svhs = 2,
- .gpiomask = 0x18e0,
- .muxsel = { 2, 3, 1, 1},
- .audiomux = { 0x0000,0x0800,0x1000,0x1000,0x18e0 },
- /* For cards with tda9820/tda9821:
- 0x0000: Tuner normal stereo
- 0x0080: Tuner A2 SAP (second audio program = Zweikanalton)
- 0x0880: Tuner A2 stereo */
- .pll = PLL_28,
- .tuner_type = -1,
- .tuner_addr = ADDR_UNSET,
-},{
- /* Miguel Angel Alvarez <maacruz@navegalia.com>
- old Easy TV BT848 version (model CPH031) */
- .name = "Askey CPH031/ BESTBUY Easy TV",
- .video_inputs = 4,
- .audio_inputs = 1,
- .tuner = 0,
- .svhs = 2,
- .gpiomask = 0xF,
- .muxsel = { 2, 3, 1, 0},
- .audiomux = { 2, 0, 0, 0, 10},
- .needs_tvaudio = 0,
- .pll = PLL_28,
- .tuner_type = TUNER_TEMIC_PAL,
- .tuner_addr = ADDR_UNSET,
-},{
-
-/* ---- card 0x38 ---------------------------------- */
- /* Gordon Heydon <gjheydon@bigfoot.com ('98) */
- .name = "Lifeview FlyVideo 98FM LR50",
- .video_inputs = 4,
- .audio_inputs = 3,
- .tuner = 0,
- .svhs = 2,
- .gpiomask = 0x1800,
- .muxsel = { 2, 3, 1, 1},
- .audiomux = { 0, 0x800, 0x1000, 0x1000, 0x1800, 0 },
- .pll = PLL_28,
- .tuner_type = 5,
- .tuner_addr = ADDR_UNSET,
-},{
- /* This is the ultimate cheapo capture card
- * just a BT848A on a small PCB!
- * Steve Hosgood <steve@equiinet.com> */
- .name = "GrandTec 'Grand Video Capture' (Bt848)",
- .video_inputs = 2,
- .audio_inputs = 0,
- .tuner = -1,
- .svhs = 1,
- .gpiomask = 0,
- .muxsel = { 3, 1 },
- .audiomux = { 0 },
- .needs_tvaudio = 0,
- .no_msp34xx = 1,
- .pll = PLL_35,
- .tuner_type = -1,
- .tuner_addr = ADDR_UNSET,
-},{
- /* Daniel Herrington <daniel.herrington@home.com> */
- .name = "Askey CPH060/ Phoebe TV Master Only (No FM)",
- .video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
- .svhs = 2,
- .gpiomask = 0xe00,
- .muxsel = { 2, 3, 1, 1},
- .audiomux = { 0x400, 0x400, 0x400, 0x400, 0x800, 0x400 },
- .needs_tvaudio = 1,
- .pll = PLL_28,
- .tuner_type = TUNER_TEMIC_4036FY5_NTSC,
- .tuner_addr = ADDR_UNSET,
-},{
- /* Matti Mottus <mottus@physic.ut.ee> */
- .name = "Askey CPH03x TV Capturer",
- .video_inputs = 4,
- .audio_inputs = 1,
- .tuner = 0,
- .svhs = 2,
- .gpiomask = 0x03000F,
- .muxsel = { 2, 3, 1, 0},
- .audiomux = { 2,0,0,0,1 },
- .pll = PLL_28,
- .tuner_type = 0,
- .tuner_addr = ADDR_UNSET,
-},{
-
-/* ---- card 0x3c ---------------------------------- */
- /* Philip Blundell <philb@gnu.org> */
- .name = "Modular Technology MM100PCTV",
- .video_inputs = 2,
- .audio_inputs = 2,
- .tuner = 0,
- .svhs = -1,
- .gpiomask = 11,
- .muxsel = { 2, 3, 1, 1},
- .audiomux = { 2, 0, 0, 1, 8},
- .pll = PLL_35,
- .tuner_type = TUNER_TEMIC_PAL,
- .tuner_addr = ADDR_UNSET,
-},{
- /* Adrian Cox <adrian@humboldt.co.uk */
- .name = "AG Electronics GMV1",
- .video_inputs = 2,
- .audio_inputs = 0,
- .tuner = -1,
- .svhs = 1,
- .gpiomask = 0xF,
- .muxsel = { 2, 2},
- .audiomux = { },
- .no_msp34xx = 1,
- .needs_tvaudio = 0,
- .pll = PLL_28,
- .tuner_type = -1,
- .tuner_addr = ADDR_UNSET,
-},{
- /* Miguel Angel Alvarez <maacruz@navegalia.com>
- new Easy TV BT878 version (model CPH061)
- special thanks to Informatica Mieres for providing the card */
- .name = "Askey CPH061/ BESTBUY Easy TV (bt878)",
- .video_inputs = 3,
- .audio_inputs = 2,
- .tuner = 0,
- .svhs = 2,
- .gpiomask = 0xFF,
- .muxsel = { 2, 3, 1, 0},
- .audiomux = { 1, 0, 4, 4, 9},
- .needs_tvaudio = 0,
- .pll = PLL_28,
- .tuner_type = TUNER_PHILIPS_PAL,
- .tuner_addr = ADDR_UNSET,
-},{
- /* Lukas Gebauer <geby@volny.cz> */
- .name = "ATI TV-Wonder",
- .video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
- .svhs = 2,
- .gpiomask = 0xf03f,
- .muxsel = { 2, 3, 1, 0 },
- .audiomux = { 0xbffe, 0, 0xbfff, 0, 0xbffe},
- .pll = PLL_28,
- .tuner_type = TUNER_TEMIC_4006FN5_MULTI_PAL,
- .tuner_addr = ADDR_UNSET,
-},{
-
-/* ---- card 0x40 ---------------------------------- */
- /* Lukas Gebauer <geby@volny.cz> */
- .name = "ATI TV-Wonder VE",
- .video_inputs = 2,
- .audio_inputs = 1,
- .tuner = 0,
- .svhs = -1,
- .gpiomask = 1,
- .muxsel = { 2, 3, 0, 1},
- .audiomux = { 0, 0, 1, 0, 0},
- .no_msp34xx = 1,
- .pll = PLL_28,
- .tuner_type = TUNER_TEMIC_4006FN5_MULTI_PAL,
- .tuner_addr = ADDR_UNSET,
-},{
- /* DeeJay <deejay@westel900.net (2000S) */
- .name = "Lifeview FlyVideo 2000S LR90",
- .video_inputs = 3,
- .audio_inputs = 3,
- .tuner = 0,
- .svhs = 2,
- .gpiomask = 0x18e0,
- .muxsel = { 2, 3, 0, 1},
- /* Radio changed from 1e80 to 0x800 to make
- FlyVideo2000S in .hu happy (gm)*/
- /* -dk-???: set mute=0x1800 for tda9874h daughterboard */
- .audiomux = { 0x0000,0x0800,0x1000,0x1000,0x1800, 0x1080 },
- .audio_hook = fv2000s_audio,
- .no_msp34xx = 1,
- .no_tda9875 = 1,
- .needs_tvaudio = 1,
- .pll = PLL_28,
- .tuner_type = 5,
- .tuner_addr = ADDR_UNSET,
-},{
- .name = "Terratec TValueRadio",
- .video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
- .svhs = 2,
- .gpiomask = 0xffff00,
- .muxsel = { 2, 3, 1, 1},
- .audiomux = { 0x500, 0x500, 0x300, 0x900, 0x900},
- .needs_tvaudio = 1,
- .pll = PLL_28,
- .tuner_type = TUNER_PHILIPS_PAL,
- .tuner_addr = ADDR_UNSET,
- .has_radio = 1,
-},{
- /* TANAKA Kei <peg00625@nifty.com> */
- .name = "IODATA GV-BCTV4/PCI",
- .video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
- .svhs = 2,
- .gpiomask = 0x010f00,
- .muxsel = {2, 3, 0, 0},
- .audiomux = {0x10000, 0, 0x10000, 0, 0, 0},
- .no_msp34xx = 1,
- .pll = PLL_28,
- .tuner_type = TUNER_SHARP_2U5JF5540_NTSC,
- .tuner_addr = ADDR_UNSET,
- .audio_hook = gvbctv3pci_audio,
-},{
-
-/* ---- card 0x44 ---------------------------------- */
- .name = "3Dfx VoodooTV FM (Euro), VoodooTV 200 (USA)",
- /* try "insmod msp3400 simple=0" if you have
- * sound problems with this card. */
- .video_inputs = 4,
- .audio_inputs = 1,
- .tuner = 0,
- .svhs = -1,
- .gpiomask = 0x4f8a00,
- /* 0x100000: 1=MSP enabled (0=disable again)
- * 0x010000: Connected to "S0" on tda9880 (0=Pal/BG, 1=NTSC) */
- .audiomux = {0x947fff, 0x987fff,0x947fff,0x947fff, 0x947fff},
- /* tvtuner, radio, external,internal, mute, stereo
- * tuner, Composit, SVid, Composit-on-Svid-adapter */
- .muxsel = { 2, 3 ,0 ,1},
- .tuner_type = TUNER_MT2032,
- .tuner_addr = ADDR_UNSET,
- .pll = PLL_28,
- .has_radio = 1,
-},{
- /* Philip Blundell <pb@nexus.co.uk> */
- .name = "Active Imaging AIMMS",
- .video_inputs = 1,
- .audio_inputs = 0,
- .tuner = -1,
- .tuner_type = -1,
- .tuner_addr = ADDR_UNSET,
- .pll = PLL_28,
- .muxsel = { 2 },
- .gpiomask = 0
-},{
- /* Tomasz Pyra <hellfire@sedez.iq.pl> */
- .name = "Prolink Pixelview PV-BT878P+ (Rev.4C,8E)",
- .video_inputs = 3,
- .audio_inputs = 4,
- .tuner = 0,
- .svhs = 2,
- .gpiomask = 15,
- .muxsel = { 2, 3, 1, 1},
- .audiomux = { 0, 0, 11, 7, 13, 0}, /* TV and Radio with same GPIO ! */
- .needs_tvaudio = 1,
- .pll = PLL_28,
- .tuner_type = 25,
- .tuner_addr = ADDR_UNSET,
- .has_remote = 1,
- /* GPIO wiring:
- GPIO0: U4.A0 (hef4052bt)
- GPIO1: U4.A1
- GPIO2: U4.A1 (second hef4052bt)
- GPIO3: U4.nEN, U5.A0, A5.nEN
- GPIO8-15: vrd866b ?
+ /* ---- card 0x00 ---------------------------------- */
+ [BTTV_BOARD_UNKNOWN] = {
+ .name = " *** UNKNOWN/GENERIC *** ",
+ .video_inputs = 4,
+ .audio_inputs = 1,
+ .tuner = 0,
+ .svhs = 2,
+ .muxsel = { 2, 3, 1, 0},
+ .tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ },
+ [BTTV_BOARD_MIRO] = {
+ .name = "MIRO PCTV",
+ .video_inputs = 4,
+ .audio_inputs = 1,
+ .tuner = 0,
+ .svhs = 2,
+ .gpiomask = 15,
+ .muxsel = { 2, 3, 1, 1},
+ .audiomux = { 2, 0, 0, 0, 10},
+ .needs_tvaudio = 1,
+ .tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ },
+ [BTTV_BOARD_HAUPPAUGE] = {
+ .name = "Hauppauge (bt848)",
+ .video_inputs = 4,
+ .audio_inputs = 1,
+ .tuner = 0,
+ .svhs = 2,
+ .gpiomask = 7,
+ .muxsel = { 2, 3, 1, 1},
+ .audiomux = { 0, 1, 2, 3, 4},
+ .needs_tvaudio = 1,
+ .tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ },
+ [BTTV_BOARD_STB] = {
+ .name = "STB, Gateway P/N 6000699 (bt848)",
+ .video_inputs = 3,
+ .audio_inputs = 1,
+ .tuner = 0,
+ .svhs = 2,
+ .gpiomask = 7,
+ .muxsel = { 2, 3, 1, 1},
+ .audiomux = { 4, 0, 2, 3, 1},
+ .no_msp34xx = 1,
+ .needs_tvaudio = 1,
+ .tuner_type = TUNER_PHILIPS_NTSC,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .pll = PLL_28,
+ .has_radio = 1,
+ },
+
+ /* ---- card 0x04 ---------------------------------- */
+ [BTTV_BOARD_INTEL] = {
+ .name = "Intel Create and Share PCI/ Smart Video Recorder III",
+ .video_inputs = 4,
+ .audio_inputs = 0,
+ .tuner = -1,
+ .svhs = 2,
+ .gpiomask = 0,
+ .muxsel = { 2, 3, 1, 1},
+ .audiomux = { 0 },
+ .needs_tvaudio = 0,
+ .tuner_type = 4,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ },
+ [BTTV_BOARD_DIAMOND] = {
+ .name = "Diamond DTV2000",
+ .video_inputs = 4,
+ .audio_inputs = 1,
+ .tuner = 0,
+ .svhs = 2,
+ .gpiomask = 3,
+ .muxsel = { 2, 3, 1, 0},
+ .audiomux = { 0, 1, 0, 1, 3},
+ .needs_tvaudio = 1,
+ .tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ },
+ [BTTV_BOARD_AVERMEDIA] = {
+ .name = "AVerMedia TVPhone",
+ .video_inputs = 3,
+ .audio_inputs = 1,
+ .tuner = 0,
+ .svhs = 3,
+ .muxsel = { 2, 3, 1, 1},
+ .gpiomask = 0x0f,
+ .audiomux = { 0x0c, 0x04, 0x08, 0x04, 0},
+ /* 0x04 for some cards ?? */
+ .needs_tvaudio = 1,
+ .tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .audio_hook = avermedia_tvphone_audio,
+ .has_remote = 1,
+ },
+ [BTTV_BOARD_MATRIX_VISION] = {
+ .name = "MATRIX-Vision MV-Delta",
+ .video_inputs = 5,
+ .audio_inputs = 1,
+ .tuner = -1,
+ .svhs = 3,
+ .gpiomask = 0,
+ .muxsel = { 2, 3, 1, 0, 0},
+ .audiomux = {0 },
+ .needs_tvaudio = 1,
+ .tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ },
+
+ /* ---- card 0x08 ---------------------------------- */
+ [BTTV_BOARD_FLYVIDEO] = {
+ .name = "Lifeview FlyVideo II (Bt848) LR26 / MAXI TV Video PCI2 LR26",
+ .video_inputs = 4,
+ .audio_inputs = 1,
+ .tuner = 0,
+ .svhs = 2,
+ .gpiomask = 0xc00,
+ .muxsel = { 2, 3, 1, 1},
+ .audiomux = { 0, 0xc00, 0x800, 0x400, 0xc00, 0},
+ .needs_tvaudio = 1,
+ .pll = PLL_28,
+ .tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ },
+ [BTTV_BOARD_TURBOTV] = {
+ .name = "IMS/IXmicro TurboTV",
+ .video_inputs = 3,
+ .audio_inputs = 1,
+ .tuner = 0,
+ .svhs = 2,
+ .gpiomask = 3,
+ .muxsel = { 2, 3, 1, 1},
+ .audiomux = { 1, 1, 2, 3, 0},
+ .needs_tvaudio = 0,
+ .pll = PLL_28,
+ .tuner_type = TUNER_TEMIC_PAL,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ },
+ [BTTV_BOARD_HAUPPAUGE878] = {
+ .name = "Hauppauge (bt878)",
+ .video_inputs = 4,
+ .audio_inputs = 1,
+ .tuner = 0,
+ .svhs = 2,
+ .gpiomask = 0x0f, /* old: 7 */
+ .muxsel = { 2, 0, 1, 1},
+ .audiomux = { 0, 1, 2, 3, 4},
+ .needs_tvaudio = 1,
+ .pll = PLL_28,
+ .tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ },
+ [BTTV_BOARD_MIROPRO] = {
+ .name = "MIRO PCTV pro",
+ .video_inputs = 3,
+ .audio_inputs = 1,
+ .tuner = 0,
+ .svhs = 2,
+ .gpiomask = 0x3014f,
+ .muxsel = { 2, 3, 1, 1},
+ .audiomux = { 0x20001,0x10001, 0, 0,10},
+ .needs_tvaudio = 1,
+ .tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ },
+
+ /* ---- card 0x0c ---------------------------------- */
+ [BTTV_BOARD_ADSTECH_TV] = {
+ .name = "ADS Technologies Channel Surfer TV (bt848)",
+ .video_inputs = 3,
+ .audio_inputs = 1,
+ .tuner = 0,
+ .svhs = 2,
+ .gpiomask = 15,
+ .muxsel = { 2, 3, 1, 1},
+ .audiomux = { 13, 14, 11, 7, 0, 0},
+ .needs_tvaudio = 1,
+ .tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ },
+ [BTTV_BOARD_AVERMEDIA98] = {
+ .name = "AVerMedia TVCapture 98",
+ .video_inputs = 3,
+ .audio_inputs = 4,
+ .tuner = 0,
+ .svhs = 2,
+ .gpiomask = 15,
+ .muxsel = { 2, 3, 1, 1},
+ .audiomux = { 13, 14, 11, 7, 0, 0},
+ .needs_tvaudio = 1,
+ .msp34xx_alt = 1,
+ .pll = PLL_28,
+ .tuner_type = TUNER_PHILIPS_PAL,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .audio_hook = avermedia_tv_stereo_audio,
+ .no_gpioirq = 1,
+ },
+ [BTTV_BOARD_VHX] = {
+ .name = "Aimslab Video Highway Xtreme (VHX)",
+ .video_inputs = 3,
+ .audio_inputs = 1,
+ .tuner = 0,
+ .svhs = 2,
+ .gpiomask = 7,
+ .muxsel = { 2, 3, 1, 1},
+ .audiomux = { 0, 2, 1, 3, 4}, /* old: { 0, 1, 2, 3, 4} */
+ .needs_tvaudio = 1,
+ .pll = PLL_28,
+ .tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ },
+ [BTTV_BOARD_ZOLTRIX] = {
+ .name = "Zoltrix TV-Max",
+ .video_inputs = 3,
+ .audio_inputs = 1,
+ .tuner = 0,
+ .svhs = 2,
+ .gpiomask = 15,
+ .muxsel = { 2, 3, 1, 1},
+ .audiomux = {0 , 0, 1 , 0, 10},
+ .needs_tvaudio = 1,
+ .tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ },
+
+ /* ---- card 0x10 ---------------------------------- */
+ [BTTV_BOARD_PIXVIEWPLAYTV] = {
+ .name = "Prolink Pixelview PlayTV (bt878)",
+ .video_inputs = 3,
+ .audio_inputs = 1,
+ .tuner = 0,
+ .svhs = 2,
+ .gpiomask = 0x01fe00,
+ .muxsel = { 2, 3, 1, 1},
+ #if 0
+ /* old */
+ .audiomux = { 0x01c000, 0, 0x018000, 0x014000, 0x002000, 0 },
+ #else
+ /* 2003-10-20 by "Anton A. Arapov" <arapov@mail.ru> */
+ .audiomux = { 0x001e00, 0, 0x018000, 0x014000, 0x002000, 0 },
+ #endif
+ .needs_tvaudio = 1,
+ .pll = PLL_28,
+ .tuner_type = -1,
+ },
+ [BTTV_BOARD_WINVIEW_601] = {
+ .name = "Leadtek WinView 601",
+ .video_inputs = 3,
+ .audio_inputs = 1,
+ .tuner = 0,
+ .svhs = 2,
+ .gpiomask = 0x8300f8,
+ .muxsel = { 2, 3, 1, 1,0},
+ .audiomux = { 0x4fa007,0xcfa007,0xcfa007,0xcfa007,0xcfa007,0xcfa007},
+ .needs_tvaudio = 1,
+ .tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .audio_hook = winview_audio,
+ .has_radio = 1,
+ },
+ [BTTV_BOARD_AVEC_INTERCAP] = {
+ .name = "AVEC Intercapture",
+ .video_inputs = 3,
+ .audio_inputs = 2,
+ .tuner = 0,
+ .svhs = 2,
+ .gpiomask = 0,
+ .muxsel = {2, 3, 1, 1},
+ .audiomux = {1, 0, 0, 0, 0},
+ .needs_tvaudio = 1,
+ .tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ },
+ [BTTV_BOARD_LIFE_FLYKIT] = {
+ .name = "Lifeview FlyVideo II EZ /FlyKit LR38 Bt848 (capture only)",
+ .video_inputs = 4,
+ .audio_inputs = 1,
+ .tuner = -1,
+ .svhs = -1,
+ .gpiomask = 0x8dff00,
+ .muxsel = { 2, 3, 1, 1},
+ .audiomux = { 0 },
+ .no_msp34xx = 1,
+ .tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ },
+
+ /* ---- card 0x14 ---------------------------------- */
+ [BTTV_BOARD_CEI_RAFFLES] = {
+ .name = "CEI Raffles Card",
+ .video_inputs = 3,
+ .audio_inputs = 3,
+ .tuner = 0,
+ .svhs = 2,
+ .muxsel = {2, 3, 1, 1},
+ .tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ },
+ [BTTV_BOARD_CONFERENCETV] = {
+ .name = "Lifeview FlyVideo 98/ Lucky Star Image World ConferenceTV LR50",
+ .video_inputs = 4,
+ .audio_inputs = 2, /* tuner, line in */
+ .tuner = 0,
+ .svhs = 2,
+ .gpiomask = 0x1800,
+ .muxsel = { 2, 3, 1, 1},
+ .audiomux = { 0, 0x800, 0x1000, 0x1000, 0x1800},
+ .pll = PLL_28,
+ .tuner_type = TUNER_PHILIPS_PAL_I,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ },
+ [BTTV_BOARD_PHOEBE_TVMAS] = {
+ .name = "Askey CPH050/ Phoebe Tv Master + FM",
+ .video_inputs = 3,
+ .audio_inputs = 1,
+ .tuner = 0,
+ .svhs = 2,
+ .gpiomask = 0xc00,
+ .muxsel = { 2, 3, 1, 1},
+ .audiomux = {0, 1, 0x800, 0x400, 0xc00, 0},
+ .needs_tvaudio = 1,
+ .pll = PLL_28,
+ .tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ },
+ [BTTV_BOARD_MODTEC_205] = {
+ .name = "Modular Technology MM201/MM202/MM205/MM210/MM215 PCTV, bt878",
+ .video_inputs = 3,
+ .audio_inputs = 1,
+ .tuner = 0,
+ .svhs = -1,
+ .gpiomask = 7,
+ .muxsel = { 2, 3, -1 },
+ .digital_mode = DIGITAL_MODE_CAMERA,
+ .audiomux = { 0, 0, 0, 0, 0 },
+ .no_msp34xx = 1,
+ .pll = PLL_28,
+ .tuner_type = TUNER_ALPS_TSBB5_PAL_I,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ },
+
+ /* ---- card 0x18 ---------------------------------- */
+ [BTTV_BOARD_MAGICTVIEW061] = {
+ .name = "Askey CPH05X/06X (bt878) [many vendors]",
+ .video_inputs = 3,
+ .audio_inputs = 1,
+ .tuner = 0,
+ .svhs = 2,
+ .gpiomask = 0xe00,
+ .muxsel = { 2, 3, 1, 1},
+ .audiomux = {0x400, 0x400, 0x400, 0x400, 0xc00},
+ .needs_tvaudio = 1,
+ .pll = PLL_28,
+ .tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .has_remote = 1,
+ },
+ [BTTV_BOARD_VOBIS_BOOSTAR] = {
+ .name = "Terratec TerraTV+ Version 1.0 (Bt848)/ Terra TValue Version 1.0/ Vobis TV-Boostar",
+ .video_inputs = 3,
+ .audio_inputs = 1,
+ .tuner = 0,
+ .svhs = 2,
+ .gpiomask = 0x1f0fff,
+ .muxsel = { 2, 3, 1, 1},
+ .audiomux = { 0x20000, 0x30000, 0x10000, 0, 0x40000},
+ .needs_tvaudio = 0,
+ .tuner_type = TUNER_PHILIPS_PAL,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .audio_hook = terratv_audio,
+ },
+ [BTTV_BOARD_HAUPPAUG_WCAM] = {
+ .name = "Hauppauge WinCam newer (bt878)",
+ .video_inputs = 4,
+ .audio_inputs = 1,
+ .tuner = 0,
+ .svhs = 3,
+ .gpiomask = 7,
+ .muxsel = { 2, 0, 1, 1},
+ .audiomux = { 0, 1, 2, 3, 4},
+ .needs_tvaudio = 1,
+ .tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ },
+ [BTTV_BOARD_MAXI] = {
+ .name = "Lifeview FlyVideo 98/ MAXI TV Video PCI2 LR50",
+ .video_inputs = 4,
+ .audio_inputs = 2,
+ .tuner = 0,
+ .svhs = 2,
+ .gpiomask = 0x1800,
+ .muxsel = { 2, 3, 1, 1},
+ .audiomux = { 0, 0x800, 0x1000, 0x1000, 0x1800},
+ .pll = PLL_28,
+ .tuner_type = TUNER_PHILIPS_SECAM,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ },
+
+ /* ---- card 0x1c ---------------------------------- */
+ [BTTV_BOARD_TERRATV] = {
+ .name = "Terratec TerraTV+ Version 1.1 (bt878)",
+ .video_inputs = 3,
+ .audio_inputs = 1,
+ .tuner = 0,
+ .svhs = 2,
+ .gpiomask = 0x1f0fff,
+ .muxsel = { 2, 3, 1, 1},
+ .audiomux = { 0x20000, 0x30000, 0x10000, 0x00000, 0x40000},
+ .needs_tvaudio = 0,
+ .tuner_type = TUNER_PHILIPS_PAL,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .audio_hook = terratv_audio,
+ /* GPIO wiring:
+ External 20 pin connector (for Active Radio Upgrade board)
+ gpio00: i2c-sda
+ gpio01: i2c-scl
+ gpio02: om5610-data
+ gpio03: om5610-clk
+ gpio04: om5610-wre
+ gpio05: om5610-stereo
+ gpio06: rds6588-davn
+ gpio07: Pin 7 n.c.
+ gpio08: nIOW
+ gpio09+10: nIOR, nSEL ?? (bt878)
+ gpio09: nIOR (bt848)
+ gpio10: nSEL (bt848)
+ Sound Routing:
+ gpio16: u2-A0 (1st 4052bt)
+ gpio17: u2-A1
+ gpio18: u2-nEN
+ gpio19: u4-A0 (2nd 4052)
+ gpio20: u4-A1
+ u4-nEN - GND
+ Btspy:
+ 00000 : Cdrom (internal audio input)
+ 10000 : ext. Video audio input
+ 20000 : TV Mono
+ a0000 : TV Mono/2
+ 1a0000 : TV Stereo
+ 30000 : Radio
+ 40000 : Mute
*/
-},{
- .name = "Lifeview FlyVideo 98EZ (capture only) LR51",
- .video_inputs = 4,
- .audio_inputs = 0,
- .tuner = -1,
- .svhs = 2,
- .muxsel = { 2, 3, 1, 1}, /* AV1, AV2, SVHS, CVid adapter on SVHS */
- .pll = PLL_28,
- .no_msp34xx = 1,
- .tuner_type = UNSET,
- .tuner_addr = ADDR_UNSET,
-},{
-
-/* ---- card 0x48 ---------------------------------- */
- /* Dariusz Kowalewski <darekk@automex.pl> */
- .name = "Prolink Pixelview PV-BT878P+9B (PlayTV Pro rev.9B FM+NICAM)",
- .video_inputs = 4,
- .audio_inputs = 1,
- .tuner = 0,
- .svhs = 2,
- .gpiomask = 0x3f,
- .muxsel = { 2, 3, 1, 1 },
- .audiomux = { 0x01, 0x00, 0x03, 0x03, 0x09, 0x02 },
- .needs_tvaudio = 1,
- .no_msp34xx = 1,
- .no_tda9875 = 1,
- .pll = PLL_28,
- .tuner_type = 5,
- .tuner_addr = ADDR_UNSET,
- .audio_hook = pvbt878p9b_audio, /* Note: not all cards have stereo */
- .has_radio = 1, /* Note: not all cards have radio */
- .has_remote = 1,
- /* GPIO wiring:
- GPIO0: A0 hef4052
- GPIO1: A1 hef4052
- GPIO3: nEN hef4052
- GPIO8-15: vrd866b
- GPIO20,22,23: R30,R29,R28
- */
-},{
- /* Clay Kunz <ckunz@mail.arc.nasa.gov> */
- /* you must jumper JP5 for the card to work */
- .name = "Sensoray 311",
- .video_inputs = 5,
- .audio_inputs = 0,
- .tuner = -1,
- .svhs = 4,
- .gpiomask = 0,
- .muxsel = { 2, 3, 1, 0, 0},
- .audiomux = { 0 },
- .needs_tvaudio = 0,
- .tuner_type = -1,
- .tuner_addr = ADDR_UNSET,
-},{
- /* Miguel Freitas <miguel@cetuc.puc-rio.br> */
- .name = "RemoteVision MX (RV605)",
- .video_inputs = 16,
- .audio_inputs = 0,
- .tuner = -1,
- .svhs = -1,
- .gpiomask = 0x00,
- .gpiomask2 = 0x07ff,
- .muxsel = { 0x33, 0x13, 0x23, 0x43, 0xf3, 0x73, 0xe3, 0x03,
- 0xd3, 0xb3, 0xc3, 0x63, 0x93, 0x53, 0x83, 0xa3 },
- .no_msp34xx = 1,
- .no_tda9875 = 1,
- .tuner_type = -1,
- .tuner_addr = ADDR_UNSET,
- .muxsel_hook = rv605_muxsel,
-},{
- .name = "Powercolor MTV878/ MTV878R/ MTV878F",
- .video_inputs = 3,
- .audio_inputs = 2,
- .tuner = 0,
- .svhs = 2,
- .gpiomask = 0x1C800F, /* Bit0-2: Audio select, 8-12:remote control 14:remote valid 15:remote reset */
- .muxsel = { 2, 1, 1, },
- .audiomux = { 0, 1, 2, 2, 4 },
- .needs_tvaudio = 0,
- .tuner_type = TUNER_PHILIPS_PAL,
- .tuner_addr = ADDR_UNSET,
- .pll = PLL_28,
- .has_radio = 1,
-},{
-
-/* ---- card 0x4c ---------------------------------- */
- /* Masaki Suzuki <masaki@btree.org> */
- .name = "Canopus WinDVR PCI (COMPAQ Presario 3524JP, 5112JP)",
- .video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
- .svhs = 2,
- .gpiomask = 0x140007,
- .muxsel = { 2, 3, 1, 1 },
- .audiomux = { 0, 1, 2, 3, 4, 0 },
- .tuner_type = TUNER_PHILIPS_NTSC,
- .tuner_addr = ADDR_UNSET,
- .audio_hook = windvr_audio,
-},{
- .name = "GrandTec Multi Capture Card (Bt878)",
- .video_inputs = 4,
- .audio_inputs = 0,
- .tuner = -1,
- .svhs = -1,
- .gpiomask = 0,
- .muxsel = { 2, 3, 1, 0 },
- .audiomux = { 0 },
- .needs_tvaudio = 0,
- .no_msp34xx = 1,
- .pll = PLL_28,
- .tuner_type = -1,
- .tuner_addr = ADDR_UNSET,
-},{
- .name = "Jetway TV/Capture JW-TV878-FBK, Kworld KW-TV878RF",
- .video_inputs = 4,
- .audio_inputs = 3,
- .tuner = 0,
- .svhs = 2,
- .gpiomask = 7,
- .muxsel = { 2, 3, 1, 1 }, /* Tuner, SVid, SVHS, SVid to SVHS connector */
- .audiomux = { 0 ,0 ,4, 4,4,4},/* Yes, this tuner uses the same audio output for TV and FM radio!
- * This card lacks external Audio In, so we mute it on Ext. & Int.
- * The PCB can take a sbx1637/sbx1673, wiring unknown.
- * This card lacks PCI subsystem ID, sigh.
- * audiomux=1: lower volume, 2+3: mute
- * btwincap uses 0x80000/0x80003
- */
- .needs_tvaudio = 0,
- .no_msp34xx = 1,
- .pll = PLL_28,
- .tuner_type = 5,
- .tuner_addr = ADDR_UNSET,
- /* Samsung TCPA9095PC27A (BG+DK), philips compatible, w/FM, stereo and
- radio signal strength indicators work fine. */
- .has_radio = 1,
- /* GPIO Info:
- GPIO0,1: HEF4052 A0,A1
- GPIO2: HEF4052 nENABLE
- GPIO3-7: n.c.
- GPIO8-13: IRDC357 data0-5 (data6 n.c. ?) [chip not present on my card]
- GPIO14,15: ??
- GPIO16-21: n.c.
- GPIO22,23: ??
- ?? : mtu8b56ep microcontroller for IR (GPIO wiring unknown)*/
-},{
- /* Arthur Tetzlaff-Deas, DSP Design Ltd <software@dspdesign.com> */
- .name = "DSP Design TCVIDEO",
- .video_inputs = 4,
- .svhs = -1,
- .muxsel = { 2, 3, 1, 0},
- .pll = PLL_28,
- .tuner_type = -1,
- .tuner_addr = ADDR_UNSET,
-},{
-
- /* ---- card 0x50 ---------------------------------- */
- .name = "Hauppauge WinTV PVR",
- .video_inputs = 4,
- .audio_inputs = 1,
- .tuner = 0,
- .svhs = 2,
- .muxsel = { 2, 0, 1, 1},
- .needs_tvaudio = 1,
- .pll = PLL_28,
- .tuner_type = -1,
- .tuner_addr = ADDR_UNSET,
-
- .gpiomask = 7,
- .audiomux = {7},
-},{
- .name = "IODATA GV-BCTV5/PCI",
- .video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
- .svhs = 2,
- .gpiomask = 0x0f0f80,
- .muxsel = {2, 3, 1, 0},
- .audiomux = {0x030000, 0x010000, 0, 0, 0x020000, 0},
- .no_msp34xx = 1,
- .pll = PLL_28,
- .tuner_type = TUNER_PHILIPS_NTSC_M,
- .tuner_addr = ADDR_UNSET,
- .audio_hook = gvbctv5pci_audio,
- .has_radio = 1,
-},{
- .name = "Osprey 100/150 (878)", /* 0x1(2|3)-45C6-C1 */
- .video_inputs = 4, /* id-inputs-clock */
- .audio_inputs = 0,
- .tuner = -1,
- .svhs = 3,
- .muxsel = { 3, 2, 0, 1 },
- .pll = PLL_28,
- .tuner_type = -1,
- .tuner_addr = ADDR_UNSET,
- .no_msp34xx = 1,
- .no_tda9875 = 1,
- .no_tda7432 = 1,
-},{
- .name = "Osprey 100/150 (848)", /* 0x04-54C0-C1 & older boards */
- .video_inputs = 3,
- .audio_inputs = 0,
- .tuner = -1,
- .svhs = 2,
- .muxsel = { 2, 3, 1 },
- .pll = PLL_28,
- .tuner_type = -1,
- .tuner_addr = ADDR_UNSET,
- .no_msp34xx = 1,
- .no_tda9875 = 1,
- .no_tda7432 = 1,
-},{
-
- /* ---- card 0x54 ---------------------------------- */
- .name = "Osprey 101 (848)", /* 0x05-40C0-C1 */
- .video_inputs = 2,
- .audio_inputs = 0,
- .tuner = -1,
- .svhs = 1,
- .muxsel = { 3, 1 },
- .pll = PLL_28,
- .tuner_type = -1,
- .tuner_addr = ADDR_UNSET,
- .no_msp34xx = 1,
- .no_tda9875 = 1,
- .no_tda7432 = 1,
-},{
- .name = "Osprey 101/151", /* 0x1(4|5)-0004-C4 */
- .video_inputs = 1,
- .audio_inputs = 0,
- .tuner = -1,
- .svhs = -1,
- .muxsel = { 0 },
- .pll = PLL_28,
- .tuner_type = -1,
- .tuner_addr = ADDR_UNSET,
- .no_msp34xx = 1,
- .no_tda9875 = 1,
- .no_tda7432 = 1,
-},{
- .name = "Osprey 101/151 w/ svid", /* 0x(16|17|20)-00C4-C1 */
- .video_inputs = 2,
- .audio_inputs = 0,
- .tuner = -1,
- .svhs = 1,
- .muxsel = { 0, 1 },
- .pll = PLL_28,
- .tuner_type = -1,
- .tuner_addr = ADDR_UNSET,
- .no_msp34xx = 1,
- .no_tda9875 = 1,
- .no_tda7432 = 1,
-},{
- .name = "Osprey 200/201/250/251", /* 0x1(8|9|E|F)-0004-C4 */
- .video_inputs = 1,
- .audio_inputs = 1,
- .tuner = -1,
- .svhs = -1,
- .muxsel = { 0 },
- .pll = PLL_28,
- .tuner_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .no_msp34xx = 1,
- .no_tda9875 = 1,
- .no_tda7432 = 1,
-},{
-
- /* ---- card 0x58 ---------------------------------- */
- .name = "Osprey 200/250", /* 0x1(A|B)-00C4-C1 */
- .video_inputs = 2,
- .audio_inputs = 1,
- .tuner = -1,
- .svhs = 1,
- .muxsel = { 0, 1 },
- .pll = PLL_28,
- .tuner_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .no_msp34xx = 1,
- .no_tda9875 = 1,
- .no_tda7432 = 1,
-},{
- .name = "Osprey 210/220", /* 0x1(A|B)-04C0-C1 */
- .video_inputs = 2,
- .audio_inputs = 1,
- .tuner = -1,
- .svhs = 1,
- .muxsel = { 2, 3 },
- .pll = PLL_28,
- .tuner_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .no_msp34xx = 1,
- .no_tda9875 = 1,
- .no_tda7432 = 1,
-},{
- .name = "Osprey 500", /* 500 */
- .video_inputs = 2,
- .audio_inputs = 1,
- .tuner = -1,
- .svhs = 1,
- .muxsel = { 2, 3 },
- .pll = PLL_28,
- .tuner_type = -1,
- .tuner_addr = ADDR_UNSET,
- .no_msp34xx = 1,
- .no_tda9875 = 1,
- .no_tda7432 = 1,
-},{
- .name = "Osprey 540", /* 540 */
- .video_inputs = 4,
- .audio_inputs = 1,
- .tuner = -1,
- .pll = PLL_28,
- .tuner_type = -1,
- .tuner_addr = ADDR_UNSET,
- .no_msp34xx = 1,
- .no_tda9875 = 1,
- .no_tda7432 = 1,
-},{
-
- /* ---- card 0x5C ---------------------------------- */
- .name = "Osprey 2000", /* 2000 */
- .video_inputs = 2,
- .audio_inputs = 1,
- .tuner = -1,
- .svhs = 1,
- .muxsel = { 2, 3 },
- .pll = PLL_28,
- .tuner_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .no_msp34xx = 1,
- .no_tda9875 = 1,
- .no_tda7432 = 1, /* must avoid, conflicts with the bt860 */
-},{
- /* M G Berberich <berberic@forwiss.uni-passau.de> */
- .name = "IDS Eagle",
- .video_inputs = 4,
- .audio_inputs = 0,
- .tuner = -1,
- .tuner_type = -1,
- .tuner_addr = ADDR_UNSET,
- .svhs = -1,
- .gpiomask = 0,
- .muxsel = { 0, 1, 2, 3 },
- .muxsel_hook = eagle_muxsel,
- .no_msp34xx = 1,
- .no_tda9875 = 1,
- .pll = PLL_28,
-},{
- .name = "Pinnacle PCTV Sat",
- .video_inputs = 2,
- .audio_inputs = 0,
- .svhs = 1,
- .tuner = -1,
- .tuner_type = -1,
- .tuner_addr = ADDR_UNSET,
- .no_msp34xx = 1,
- .no_tda9875 = 1,
- .no_tda7432 = 1,
- .gpiomask = 0x01,
- .audiomux = { 0, 0, 0, 0, 1 },
- .muxsel = { 3, 0, 1, 2},
- .needs_tvaudio = 0,
- .pll = PLL_28,
- .no_gpioirq = 1,
- .has_dvb = 1,
-},{
- .name = "Formac ProTV II (bt878)",
- .video_inputs = 4,
- .audio_inputs = 1,
- .tuner = 0,
- .svhs = 3,
- .gpiomask = 2,
- /* TV, Comp1, Composite over SVID con, SVID */
- .muxsel = { 2, 3, 1, 1},
- .audiomux = { 2, 2, 0, 0, 0 },
- .pll = PLL_28,
- .has_radio = 1,
- .tuner_type = TUNER_PHILIPS_PAL,
- .tuner_addr = ADDR_UNSET,
-/* sound routing:
- GPIO=0x00,0x01,0x03: mute (?)
- 0x02: both TV and radio (tuner: FM1216/I)
- The card has onboard audio connectors labeled "cdrom" and "board",
- not soldered here, though unknown wiring.
- Card lacks: external audio in, pci subsystem id.
-*/
-},{
-
- /* ---- card 0x60 ---------------------------------- */
- .name = "MachTV",
- .video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
- .svhs = -1,
- .gpiomask = 7,
- .muxsel = { 2, 3, 1, 1},
- .audiomux = { 0, 1, 2, 3, 4},
- .needs_tvaudio = 1,
- .tuner_type = 5,
- .tuner_addr = ADDR_UNSET,
- .pll = 1,
-},{
- .name = "Euresys Picolo",
- .video_inputs = 3,
- .audio_inputs = 0,
- .tuner = -1,
- .svhs = 2,
- .gpiomask = 0,
- .no_msp34xx = 1,
- .no_tda9875 = 1,
- .no_tda7432 = 1,
- .muxsel = { 2, 0, 1},
- .pll = PLL_28,
- .tuner_type = UNSET,
- .tuner_addr = ADDR_UNSET,
-},{
- /* Luc Van Hoeylandt <luc@e-magic.be> */
- .name = "ProVideo PV150", /* 0x4f */
- .video_inputs = 2,
- .audio_inputs = 0,
- .tuner = -1,
- .svhs = -1,
- .gpiomask = 0,
- .muxsel = { 2, 3 },
- .audiomux = { 0 },
- .needs_tvaudio = 0,
- .no_msp34xx = 1,
- .pll = PLL_28,
- .tuner_type = UNSET,
- .tuner_addr = ADDR_UNSET,
-},{
- /* Hiroshi Takekawa <sian@big.or.jp> */
- /* This card lacks subsystem ID */
- .name = "AD-TVK503", /* 0x63 */
- .video_inputs = 4,
- .audio_inputs = 1,
- .tuner = 0,
- .svhs = 2,
- .gpiomask = 0x001e8007,
- .muxsel = { 2, 3, 1, 0 },
- /* Tuner, Radio, external, internal, off, on */
- .audiomux = { 0x08, 0x0f, 0x0a, 0x08, 0x0f, 0x08 },
- .needs_tvaudio = 0,
- .no_msp34xx = 1,
- .pll = PLL_28,
- .tuner_type = 2,
- .tuner_addr = ADDR_UNSET,
- .audio_hook = adtvk503_audio,
-},{
-
- /* ---- card 0x64 ---------------------------------- */
- .name = "Hercules Smart TV Stereo",
- .video_inputs = 4,
- .audio_inputs = 1,
- .tuner = 0,
- .svhs = 2,
- .gpiomask = 0x00,
- .muxsel = { 2, 3, 1, 1 },
- .needs_tvaudio = 1,
- .no_msp34xx = 1,
- .pll = PLL_28,
- .tuner_type = 5,
- .tuner_addr = ADDR_UNSET,
- /* Notes:
- - card lacks subsystem ID
- - stereo variant w/ daughter board with tda9874a @0xb0
- - Audio Routing:
- always from tda9874 independent of GPIO (?)
- external line in: unknown
- - Other chips: em78p156elp @ 0x96 (probably IR remote control)
- hef4053 (instead 4052) for unknown function
- */
-},{
- .name = "Pace TV & Radio Card",
- .video_inputs = 4,
- .audio_inputs = 1,
- .tuner = 0,
- .svhs = 2,
- .muxsel = { 2, 3, 1, 1}, /* Tuner, CVid, SVid, CVid over SVid connector */
- .gpiomask = 0,
- .no_tda9875 = 1,
- .no_tda7432 = 1,
- .tuner_type = 1,
- .tuner_addr = ADDR_UNSET,
- .has_radio = 1,
- .pll = PLL_28,
- /* Bt878, Bt832, FI1246 tuner; no pci subsystem id
- only internal line out: (4pin header) RGGL
- Radio must be decoded by msp3410d (not routed through)*/
- /*
- .digital_mode = DIGITAL_MODE_CAMERA, todo!
- */
-},{
- /* Chris Willing <chris@vislab.usyd.edu.au> */
- .name = "IVC-200",
- .video_inputs = 1,
- .audio_inputs = 0,
- .tuner = -1,
- .tuner_type = -1,
- .tuner_addr = ADDR_UNSET,
- .svhs = -1,
- .gpiomask = 0xdf,
- .muxsel = { 2 },
- .pll = PLL_28,
-},{
- .name = "Grand X-Guard / Trust 814PCI",
- .video_inputs = 16,
- .audio_inputs = 0,
- .tuner = -1,
- .svhs = -1,
- .tuner_type = 4,
- .tuner_addr = ADDR_UNSET,
- .gpiomask2 = 0xff,
- .muxsel = { 2,2,2,2, 3,3,3,3, 1,1,1,1, 0,0,0,0 },
- .muxsel_hook = xguard_muxsel,
- .no_msp34xx = 1,
- .no_tda9875 = 1,
- .no_tda7432 = 1,
- .pll = PLL_28,
-},{
-
- /* ---- card 0x68 ---------------------------------- */
- .name = "Nebula Electronics DigiTV",
- .video_inputs = 1,
- .tuner = -1,
- .svhs = -1,
- .muxsel = { 2, 3, 1, 0},
- .no_msp34xx = 1,
- .no_tda9875 = 1,
- .no_tda7432 = 1,
- .pll = PLL_28,
- .tuner_type = -1,
- .tuner_addr = ADDR_UNSET,
- .has_dvb = 1,
- .no_gpioirq = 1,
-},{
- /* Jorge Boncompte - DTI2 <jorge@dti2.net> */
- .name = "ProVideo PV143",
- .video_inputs = 4,
- .audio_inputs = 0,
- .tuner = -1,
- .svhs = -1,
- .gpiomask = 0,
- .muxsel = { 2, 3, 1, 0 },
- .audiomux = { 0 },
- .needs_tvaudio = 0,
- .no_msp34xx = 1,
- .pll = PLL_28,
- .tuner_type = -1,
- .tuner_addr = ADDR_UNSET,
-},{
- /* M.Klahr@phytec.de */
- .name = "PHYTEC VD-009-X1 MiniDIN (bt878)",
- .video_inputs = 4,
- .audio_inputs = 0,
- .tuner = -1, /* card has no tuner */
- .svhs = 3,
- .gpiomask = 0x00,
- .muxsel = { 2, 3, 1, 0},
- .audiomux = { 0, 0, 0, 0, 0, 0 }, /* card has no audio */
- .needs_tvaudio = 1,
- .pll = PLL_28,
- .tuner_type = -1,
- .tuner_addr = ADDR_UNSET,
-},{
- .name = "PHYTEC VD-009-X1 Combi (bt878)",
- .video_inputs = 4,
- .audio_inputs = 0,
- .tuner = -1, /* card has no tuner */
- .svhs = 3,
- .gpiomask = 0x00,
- .muxsel = { 2, 3, 1, 1},
- .audiomux = { 0, 0, 0, 0, 0, 0 }, /* card has no audio */
- .needs_tvaudio = 1,
- .pll = PLL_28,
- .tuner_type = -1,
- .tuner_addr = ADDR_UNSET,
-},{
-
- /* ---- card 0x6c ---------------------------------- */
- .name = "PHYTEC VD-009 MiniDIN (bt878)",
- .video_inputs = 10,
- .audio_inputs = 0,
- .tuner = -1, /* card has no tuner */
- .svhs = 9,
- .gpiomask = 0x00,
- .gpiomask2 = 0x03, /* gpiomask2 defines the bits used to switch audio
- via the upper nibble of muxsel. here: used for
- xternal video-mux */
- .muxsel = { 0x02, 0x12, 0x22, 0x32, 0x03, 0x13, 0x23, 0x33, 0x01, 0x00 },
- .audiomux = { 0, 0, 0, 0, 0, 0 }, /* card has no audio */
- .needs_tvaudio = 1,
- .pll = PLL_28,
- .tuner_type = -1,
- .tuner_addr = ADDR_UNSET,
-},{
- .name = "PHYTEC VD-009 Combi (bt878)",
- .video_inputs = 10,
- .audio_inputs = 0,
- .tuner = -1, /* card has no tuner */
- .svhs = 9,
- .gpiomask = 0x00,
- .gpiomask2 = 0x03, /* gpiomask2 defines the bits used to switch audio
- via the upper nibble of muxsel. here: used for
- xternal video-mux */
- .muxsel = { 0x02, 0x12, 0x22, 0x32, 0x03, 0x13, 0x23, 0x33, 0x01, 0x01 },
- .audiomux = { 0, 0, 0, 0, 0, 0 }, /* card has no audio */
- .needs_tvaudio = 1,
- .pll = PLL_28,
- .tuner_type = -1,
- .tuner_addr = ADDR_UNSET,
-},{
- .name = "IVC-100",
- .video_inputs = 4,
- .audio_inputs = 0,
- .tuner = -1,
- .tuner_type = -1,
- .tuner_addr = ADDR_UNSET,
- .svhs = -1,
- .gpiomask = 0xdf,
- .muxsel = { 2, 3, 1, 0 },
- .pll = PLL_28,
-},{
- /* IVC-120G - Alan Garfield <alan@fromorbit.com> */
- .name = "IVC-120G",
- .video_inputs = 16,
- .audio_inputs = 0, /* card has no audio */
- .tuner = -1, /* card has no tuner */
- .tuner_type = -1,
- .tuner_addr = ADDR_UNSET,
- .svhs = -1, /* card has no svhs */
- .needs_tvaudio = 0,
- .no_msp34xx = 1,
- .no_tda9875 = 1,
- .no_tda7432 = 1,
- .gpiomask = 0x00,
- .muxsel = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
- 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10 },
- .muxsel_hook = ivc120_muxsel,
- .pll = PLL_28,
-},{
-
- /* ---- card 0x70 ---------------------------------- */
- .name = "pcHDTV HD-2000 TV",
- .video_inputs = 4,
- .audio_inputs = 1,
- .tuner = 0,
- .svhs = 2,
- .muxsel = { 2, 3, 1, 0},
- .tuner_type = TUNER_PHILIPS_ATSC,
- .tuner_addr = ADDR_UNSET,
- .has_dvb = 1,
-},{
- .name = "Twinhan DST + clones",
- .no_msp34xx = 1,
- .no_tda9875 = 1,
- .no_tda7432 = 1,
- .tuner_type = TUNER_ABSENT,
- .tuner_addr = ADDR_UNSET,
- .no_video = 1,
- .has_dvb = 1,
-},{
- .name = "Winfast VC100",
- .video_inputs = 3,
- .audio_inputs = 0,
- .svhs = 1,
- .tuner = -1,
- .muxsel = { 3, 1, 1, 3}, /* Vid In, SVid In, Vid over SVid in connector */
- .no_msp34xx = 1,
- .no_tda9875 = 1,
- .no_tda7432 = 1,
- .tuner_type = TUNER_ABSENT,
- .tuner_addr = ADDR_UNSET,
- .pll = PLL_28,
-},{
- .name = "Teppro TEV-560/InterVision IV-560",
- .video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
- .svhs = 2,
- .gpiomask = 3,
- .muxsel = { 2, 3, 1, 1},
- .audiomux = { 1, 1, 1, 1, 0},
- .needs_tvaudio = 1,
- .tuner_type = TUNER_PHILIPS_PAL,
- .tuner_addr = ADDR_UNSET,
- .pll = PLL_35,
-},{
-
- /* ---- card 0x74 ---------------------------------- */
- .name = "SIMUS GVC1100",
- .video_inputs = 4,
- .audio_inputs = 0,
- .tuner = -1,
- .svhs = -1,
- .tuner_type = -1,
- .tuner_addr = ADDR_UNSET,
- .pll = PLL_28,
- .muxsel = { 2, 2, 2, 2},
- .gpiomask = 0x3F,
- .muxsel_hook = gvc1100_muxsel,
-},{
- /* Carlos Silva r3pek@r3pek.homelinux.org || card 0x75 */
- .name = "NGS NGSTV+",
- .video_inputs = 3,
- .tuner = 0,
- .svhs = 2,
- .gpiomask = 0x008007,
- .muxsel = {2, 3, 0, 0},
- .audiomux = {0, 0, 0, 0, 0x000003, 0},
- .pll = PLL_28,
- .tuner_type = TUNER_PHILIPS_PAL,
- .tuner_addr = ADDR_UNSET,
- .has_remote = 1,
-},{
- /* http://linuxmedialabs.com */
- .name = "LMLBT4",
- .video_inputs = 4, /* IN1,IN2,IN3,IN4 */
- .audio_inputs = 0,
- .tuner = -1,
- .svhs = -1,
- .muxsel = { 2, 3, 1, 0 },
- .no_msp34xx = 1,
- .no_tda9875 = 1,
- .no_tda7432 = 1,
- .needs_tvaudio = 0,
- .tuner_type = -1,
- .tuner_addr = ADDR_UNSET,
-},{
- /* Helmroos Harri <harri.helmroos@pp.inet.fi> */
- .name = "Tekram M205 PRO",
- .video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
- .tuner_type = TUNER_PHILIPS_PAL,
- .tuner_addr = ADDR_UNSET,
- .svhs = 2,
- .needs_tvaudio = 0,
- .gpiomask = 0x68,
- .muxsel = { 2, 3, 1},
- .audiomux = { 0x68, 0x68, 0x61, 0x61, 0x00 },
- .pll = PLL_28,
-},{
-
- /* ---- card 0x78 ---------------------------------- */
- /* Javier Cendan Ares <jcendan@lycos.es> */
- /* bt878 TV + FM without subsystem ID */
- .name = "Conceptronic CONTVFMi",
- .video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
- .svhs = 2,
- .gpiomask = 0x008007,
- .muxsel = { 2, 3, 1, 1 },
- .audiomux = { 0, 1, 2, 2, 3 },
- .needs_tvaudio = 0,
- .pll = PLL_28,
- .tuner_type = TUNER_PHILIPS_PAL,
- .tuner_addr = ADDR_UNSET,
- .has_remote = 1,
- .has_radio = 1,
-},{
- /*Eric DEBIEF <debief@telemsa.com>*/
- /*EURESYS Picolo Tetra : 4 Conexant Fusion 878A, no audio, video input set with analog multiplexers GPIO controled*/
- /* adds picolo_tetra_muxsel(), picolo_tetra_init(), the folowing declaration strucure, and #define BTTV_PICOLO_TETRA_CHIP*/
- /*0x79 in bttv.h*/
- .name = "Euresys Picolo Tetra",
- .video_inputs = 4,
- .audio_inputs = 0,
- .tuner = -1,
- .svhs = -1,
- .gpiomask = 0,
- .gpiomask2 = 0x3C<<16,/*Set the GPIO[18]->GPIO[21] as output pin.==> drive the video inputs through analog multiplexers*/
- .no_msp34xx = 1,
- .no_tda9875 = 1,
- .no_tda7432 = 1,
- .muxsel = {2,2,2,2},/*878A input is always MUX0, see above.*/
- .audiomux = { 0, 0, 0, 0, 0, 0 }, /* card has no audio */
- .pll = PLL_28,
- .needs_tvaudio = 0,
- .muxsel_hook = picolo_tetra_muxsel,/*Required as it doesn't follow the classic input selection policy*/
- .tuner_type = -1,
- .tuner_addr = ADDR_UNSET,
-},{
- /* Spirit TV Tuner from http://spiritmodems.com.au */
- /* Stafford Goodsell <surge@goliath.homeunix.org> */
- .name = "Spirit TV Tuner",
- .video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
- .svhs = 2,
- .gpiomask = 0x0000000f,
- .muxsel = { 2, 1, 1 },
- .audiomux = { 0x02, 0x00, 0x00, 0x00, 0x00},
- .tuner_type = TUNER_TEMIC_PAL,
- .tuner_addr = ADDR_UNSET,
- .no_msp34xx = 1,
- .no_tda9875 = 1,
-},{
- /* Wolfram Joost <wojo@frokaschwei.de> */
- .name = "AVerMedia AVerTV DVB-T 771",
- .video_inputs = 2,
- .svhs = 1,
- .tuner = -1,
- .tuner_type = TUNER_ABSENT,
- .tuner_addr = ADDR_UNSET,
- .muxsel = { 3 , 3 },
- .no_msp34xx = 1,
- .no_tda9875 = 1,
- .no_tda7432 = 1,
- .pll = PLL_28,
- .has_dvb = 1,
- .no_gpioirq = 1,
- .has_remote = 1,
-},{
- /* ---- card 0x7c ---------------------------------- */
- /* Matt Jesson <dvb@jesson.eclipse.co.uk> */
- /* Based on the Nebula card data - added remote and new card number - BTTV_AVDVBT_761, see also ir-kbd-gpio.c */
- .name = "AverMedia AverTV DVB-T 761",
- .video_inputs = 2,
- .tuner = -1,
- .svhs = 1,
- .muxsel = { 3, 1, 2, 0}, /* Comp0, S-Video, ?, ? */
- .no_msp34xx = 1,
- .no_tda9875 = 1,
- .no_tda7432 = 1,
- .pll = PLL_28,
- .tuner_type = -1,
- .tuner_addr = ADDR_UNSET,
- .has_dvb = 1,
- .no_gpioirq = 1,
- .has_remote = 1,
-},{
- /* andre.schwarz@matrix-vision.de */
- .name = "MATRIX Vision Sigma-SQ",
- .video_inputs = 16,
- .audio_inputs = 0,
- .tuner = -1,
- .svhs = -1,
- .gpiomask = 0x0,
- .muxsel = { 2, 2, 2, 2, 2, 2, 2, 2,
- 3, 3, 3, 3, 3, 3, 3, 3 },
- .muxsel_hook = sigmaSQ_muxsel,
- .audiomux = { 0 },
- .no_msp34xx = 1,
- .pll = PLL_28,
- .tuner_type = -1,
- .tuner_addr = ADDR_UNSET,
-},{
- /* andre.schwarz@matrix-vision.de */
- .name = "MATRIX Vision Sigma-SLC",
- .video_inputs = 4,
- .audio_inputs = 0,
- .tuner = -1,
- .svhs = -1,
- .gpiomask = 0x0,
- .muxsel = { 2, 2, 2, 2 },
- .muxsel_hook = sigmaSLC_muxsel,
- .audiomux = { 0 },
- .no_msp34xx = 1,
- .pll = PLL_28,
- .tuner_type = -1,
- .tuner_addr = ADDR_UNSET,
-},{
- /* BTTV_APAC_VIEWCOMP */
- /* Attila Kondoros <attila.kondoros@chello.hu> */
- /* bt878 TV + FM 0x00000000 subsystem ID */
- .name = "APAC Viewcomp 878(AMAX)",
- .video_inputs = 2,
- .audio_inputs = 1,
- .tuner = 0,
- .svhs = -1,
- .gpiomask = 0xFF,
- .muxsel = { 2, 3, 1, 1},
- .audiomux = { 2, 0, 0, 0, 10},
- .needs_tvaudio = 0,
- .pll = PLL_28,
- .tuner_type = TUNER_PHILIPS_PAL,
- .tuner_addr = ADDR_UNSET,
- .has_remote = 1, /* miniremote works, see ir-kbd-gpio.c */
- .has_radio = 1, /* not every card has radio */
-},{
-
- /* ---- card 0x80 ---------------------------------- */
- /* Chris Pascoe <c.pascoe@itee.uq.edu.au> */
- .name = "DViCO FusionHDTV DVB-T Lite",
- .tuner = -1,
- .no_msp34xx = 1,
- .no_tda9875 = 1,
- .no_tda7432 = 1,
- .pll = PLL_28,
- .no_video = 1,
- .has_dvb = 1,
- .tuner_type = -1,
- .tuner_addr = ADDR_UNSET,
-},{
- /* Steven <photon38@pchome.com.tw> */
- .name = "V-Gear MyVCD",
- .video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
- .svhs = 2,
- .gpiomask = 0x3f,
- .muxsel = {2, 3, 1, 0},
- .audiomux = {0x31, 0x31, 0x31, 0x31, 0x31, 0x31},
- .no_msp34xx = 1,
- .pll = PLL_28,
- .tuner_type = TUNER_PHILIPS_NTSC_M,
- .tuner_addr = ADDR_UNSET,
- .has_radio = 0,
-},{
- /* Rick C <cryptdragoon@gmail.com> */
- .name = "Super TV Tuner",
- .video_inputs = 4,
- .audio_inputs = 1,
- .tuner = 0,
- .svhs = 2,
- .muxsel = { 2, 3, 1, 0},
- .tuner_type = TUNER_PHILIPS_NTSC,
- .tuner_addr = ADDR_UNSET,
- .gpiomask = 0x008007,
- .audiomux = { 0, 0x000001,0,0, 0},
- .needs_tvaudio = 1,
- .has_radio = 1,
-},{
- /* Chris Fanning <video4linux@haydon.net> */
- .name = "Tibet Systems 'Progress DVR' CS16",
- .video_inputs = 16,
- .audio_inputs = 0,
- .tuner = -1,
- .svhs = -1,
- .muxsel = { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
- .pll = PLL_28,
- .no_msp34xx = 1,
- .no_tda9875 = 1,
- .no_tda7432 = 1,
- .tuner_type = -1,
- .tuner_addr = ADDR_UNSET,
- .muxsel_hook = tibetCS16_muxsel,
-},
-{
- /* Bill Brack <wbrack@mmm.com.hk> */
- /*
- * Note that, because of the card's wiring, the "master"
- * BT878A chip (i.e. the one which controls the analog switch
- * and must use this card type) is the 2nd one detected. The
- * other 3 chips should use card type 0x85, whose description
- * follows this one. There is a EEPROM on the card (which is
- * connected to the I2C of one of those other chips), but is
- * not currently handled. There is also a facility for a
- * "monitor", which is also not currently implemented.
- */
- .name = "Kodicom 4400R (master)",
- .video_inputs = 16,
- .audio_inputs = 0,
- .tuner = -1,
- .tuner_type = -1,
- .tuner_addr = ADDR_UNSET,
- .svhs = -1,
- /* GPIO bits 0-9 used for analog switch:
- * 00 - 03: camera selector
- * 04 - 06: channel (controller) selector
- * 07: data (1->on, 0->off)
- * 08: strobe
- * 09: reset
- * bit 16 is input from sync separator for the channel
- */
- .gpiomask = 0x0003ff,
- .no_gpioirq = 1,
- .muxsel = { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 },
- .pll = PLL_28,
- .no_msp34xx = 1,
- .no_tda7432 = 1,
- .no_tda9875 = 1,
- .muxsel_hook = kodicom4400r_muxsel,
-},
-{
- /* Bill Brack <wbrack@mmm.com.hk> */
- /* Note that, for reasons unknown, the "master" BT878A chip (i.e. the
- * one which controls the analog switch, and must use the card type)
- * is the 2nd one detected. The other 3 chips should use this card
- * type
+
+ },
+ [BTTV_BOARD_PXC200] = {
+ /* Jannik Fritsch <jannik@techfak.uni-bielefeld.de> */
+ .name = "Imagenation PXC200",
+ .video_inputs = 5,
+ .audio_inputs = 1,
+ .tuner = -1,
+ .svhs = 1, /* was: 4 */
+ .gpiomask = 0,
+ .muxsel = { 2, 3, 1, 0, 0},
+ .audiomux = { 0 },
+ .needs_tvaudio = 1,
+ .tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .muxsel_hook = PXC200_muxsel,
+
+ },
+ [BTTV_BOARD_FLYVIDEO_98] = {
+ .name = "Lifeview FlyVideo 98 LR50",
+ .video_inputs = 4,
+ .audio_inputs = 1,
+ .tuner = 0,
+ .svhs = 2,
+ .gpiomask = 0x1800, /* 0x8dfe00 */
+ .muxsel = { 2, 3, 1, 1},
+ .audiomux = { 0, 0x0800, 0x1000, 0x1000, 0x1800, 0 },
+ .pll = PLL_28,
+ .tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ },
+ [BTTV_BOARD_IPROTV] = {
+ .name = "Formac iProTV, Formac ProTV I (bt848)",
+ .video_inputs = 4,
+ .audio_inputs = 1,
+ .tuner = 0,
+ .svhs = 3,
+ .gpiomask = 1,
+ .muxsel = { 2, 3, 1, 1},
+ .audiomux = { 1, 0, 0, 0, 0 },
+ .pll = PLL_28,
+ .tuner_type = TUNER_PHILIPS_PAL,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ },
+
+ /* ---- card 0x20 ---------------------------------- */
+ [BTTV_BOARD_INTEL_C_S_PCI] = {
+ .name = "Intel Create and Share PCI/ Smart Video Recorder III",
+ .video_inputs = 4,
+ .audio_inputs = 0,
+ .tuner = -1,
+ .svhs = 2,
+ .gpiomask = 0,
+ .muxsel = { 2, 3, 1, 1},
+ .audiomux = { 0 },
+ .needs_tvaudio = 0,
+ .tuner_type = 4,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ },
+ [BTTV_BOARD_TERRATVALUE] = {
+ .name = "Terratec TerraTValue Version Bt878",
+ .video_inputs = 3,
+ .audio_inputs = 1,
+ .tuner = 0,
+ .svhs = 2,
+ .gpiomask = 0xffff00,
+ .muxsel = { 2, 3, 1, 1},
+ .audiomux = { 0x500, 0, 0x300, 0x900, 0x900},
+ .needs_tvaudio = 1,
+ .pll = PLL_28,
+ .tuner_type = TUNER_PHILIPS_PAL,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ },
+ [BTTV_BOARD_WINFAST2000] = {
+ .name = "Leadtek WinFast 2000/ WinFast 2000 XP",
+ .video_inputs = 4,
+ .audio_inputs = 1,
+ .tuner = 0,
+ .svhs = 2,
+ .muxsel = { 2, 3, 1, 1, 0}, /* TV, CVid, SVid, CVid over SVid connector */
+ #if 0
+ .gpiomask = 0xc33000,
+ .audiomux = { 0x422000,0x1000,0x0000,0x620000,0x800000 },
+ #else
+ /* Alexander Varakin <avarakin@hotmail.com> [stereo version] */
+ .gpiomask = 0xb33000,
+ .audiomux = { 0x122000,0x1000,0x0000,0x620000,0x800000 },
+ #endif
+ /* Audio Routing for "WinFast 2000 XP" (no tv stereo !)
+ gpio23 -- hef4052:nEnable (0x800000)
+ gpio12 -- hef4052:A1
+ gpio13 -- hef4052:A0
+ 0x0000: external audio
+ 0x1000: FM
+ 0x2000: TV
+ 0x3000: n.c.
+ Note: There exists another variant "Winfast 2000" with tv stereo !?
+ Note: eeprom only contains FF and pci subsystem id 107d:6606
+ */
+ .needs_tvaudio = 0,
+ .pll = PLL_28,
+ .has_radio = 1,
+ .tuner_type = 5, /* default for now, gpio reads BFFF06 for Pal bg+dk */
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .audio_hook = winfast2000_audio,
+ .has_remote = 1,
+ },
+ [BTTV_BOARD_CHRONOS_VS2] = {
+ .name = "Lifeview FlyVideo 98 LR50 / Chronos Video Shuttle II",
+ .video_inputs = 4,
+ .audio_inputs = 3,
+ .tuner = 0,
+ .svhs = 2,
+ .gpiomask = 0x1800,
+ .muxsel = { 2, 3, 1, 1},
+ .audiomux = { 0, 0x800, 0x1000, 0x1000, 0x1800},
+ .pll = PLL_28,
+ .tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ },
+
+ /* ---- card 0x24 ---------------------------------- */
+ [BTTV_BOARD_TYPHOON_TVIEW] = {
+ .name = "Lifeview FlyVideo 98FM LR50 / Typhoon TView TV/FM Tuner",
+ .video_inputs = 4,
+ .audio_inputs = 3,
+ .tuner = 0,
+ .svhs = 2,
+ .gpiomask = 0x1800,
+ .muxsel = { 2, 3, 1, 1},
+ .audiomux = { 0, 0x800, 0x1000, 0x1000, 0x1800, 0 },
+ .pll = PLL_28,
+ .tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .has_radio = 1,
+ },
+ [BTTV_BOARD_PXELVWPLTVPRO] = {
+ .name = "Prolink PixelView PlayTV pro",
+ .video_inputs = 3,
+ .audio_inputs = 1,
+ .tuner = 0,
+ .svhs = 2,
+ .gpiomask = 0xff,
+ .muxsel = { 2, 3, 1, 1 },
+ .audiomux = { 0x21, 0x20, 0x24, 0x2c, 0x29, 0x29 },
+ .no_msp34xx = 1,
+ .pll = PLL_28,
+ .tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ },
+ [BTTV_BOARD_MAGICTVIEW063] = {
+ .name = "Askey CPH06X TView99",
+ .video_inputs = 4,
+ .audio_inputs = 1,
+ .tuner = 0,
+ .svhs = 2,
+ .gpiomask = 0x551e00,
+ .muxsel = { 2, 3, 1, 0},
+ .audiomux = { 0x551400, 0x551200, 0, 0, 0x551c00, 0x551200 },
+ .needs_tvaudio = 1,
+ .pll = PLL_28,
+ .tuner_type = 1,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .has_remote = 1,
+ },
+ [BTTV_BOARD_PINNACLE] = {
+ .name = "Pinnacle PCTV Studio/Rave",
+ .video_inputs = 3,
+ .audio_inputs = 1,
+ .tuner = 0,
+ .svhs = 2,
+ .gpiomask = 0x03000F,
+ .muxsel = { 2, 3, 1, 1},
+ .audiomux = { 2, 0xd0001, 0, 0, 1},
+ .needs_tvaudio = 0,
+ .pll = PLL_28,
+ .tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ },
+
+ /* ---- card 0x28 ---------------------------------- */
+ [BTTV_BOARD_STB2] = {
+ .name = "STB TV PCI FM, Gateway P/N 6000704 (bt878), 3Dfx VoodooTV 100",
+ .video_inputs = 3,
+ .audio_inputs = 1,
+ .tuner = 0,
+ .svhs = 2,
+ .gpiomask = 7,
+ .muxsel = { 2, 3, 1, 1},
+ .audiomux = { 4, 0, 2, 3, 1},
+ .no_msp34xx = 1,
+ .needs_tvaudio = 1,
+ .tuner_type = TUNER_PHILIPS_NTSC,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .pll = PLL_28,
+ .has_radio = 1,
+ },
+ [BTTV_BOARD_AVPHONE98] = {
+ .name = "AVerMedia TVPhone 98",
+ .video_inputs = 3,
+ .audio_inputs = 4,
+ .tuner = 0,
+ .svhs = 2,
+ .gpiomask = 15,
+ .muxsel = { 2, 3, 1, 1},
+ .audiomux = { 13, 4, 11, 7, 0, 0},
+ .needs_tvaudio = 1,
+ .pll = PLL_28,
+ .tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .has_radio = 1,
+ .audio_hook = avermedia_tvphone_audio,
+ },
+ [BTTV_BOARD_PV951] = {
+ .name = "ProVideo PV951", /* pic16c54 */
+ .video_inputs = 3,
+ .audio_inputs = 1,
+ .tuner = 0,
+ .svhs = 2,
+ .gpiomask = 0,
+ .muxsel = { 2, 3, 1, 1},
+ .audiomux = { 0, 0, 0, 0, 0},
+ .needs_tvaudio = 1,
+ .no_msp34xx = 1,
+ .pll = PLL_28,
+ .tuner_type = 1,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ },
+ [BTTV_BOARD_ONAIR_TV] = {
+ .name = "Little OnAir TV",
+ .video_inputs = 3,
+ .audio_inputs = 1,
+ .tuner = 0,
+ .svhs = 2,
+ .gpiomask = 0xe00b,
+ .muxsel = {2, 3, 1, 1},
+ .audiomux = {0xff9ff6, 0xff9ff6, 0xff1ff7, 0, 0xff3ffc},
+ .no_msp34xx = 1,
+ .tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ },
+
+ /* ---- card 0x2c ---------------------------------- */
+ [BTTV_BOARD_SIGMA_TVII_FM] = {
+ .name = "Sigma TVII-FM",
+ .video_inputs = 2,
+ .audio_inputs = 1,
+ .tuner = 0,
+ .svhs = -1,
+ .gpiomask = 3,
+ .muxsel = {2, 3, 1, 1},
+ .audiomux = {1, 1, 0, 2, 3},
+ .no_msp34xx = 1,
+ .pll = PLL_NONE,
+ .tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ },
+ [BTTV_BOARD_MATRIX_VISION2] = {
+ .name = "MATRIX-Vision MV-Delta 2",
+ .video_inputs = 5,
+ .audio_inputs = 1,
+ .tuner = -1,
+ .svhs = 3,
+ .gpiomask = 0,
+ .muxsel = { 2, 3, 1, 0, 0},
+ .audiomux = {0 },
+ .no_msp34xx = 1,
+ .pll = PLL_28,
+ .tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ },
+ [BTTV_BOARD_ZOLTRIX_GENIE] = {
+ .name = "Zoltrix Genie TV/FM",
+ .video_inputs = 3,
+ .audio_inputs = 1,
+ .tuner = 0,
+ .svhs = 2,
+ .gpiomask = 0xbcf03f,
+ .muxsel = { 2, 3, 1, 1},
+ .audiomux = { 0xbc803f, 0xbc903f, 0xbcb03f, 0, 0xbcb03f},
+ .no_msp34xx = 1,
+ .pll = PLL_28,
+ .tuner_type = 21,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ },
+ [BTTV_BOARD_TERRATVRADIO] = {
+ .name = "Terratec TV/Radio+",
+ .video_inputs = 3,
+ .audio_inputs = 1,
+ .tuner = 0,
+ .svhs = 2,
+ .gpiomask = 0x70000,
+ .muxsel = { 2, 3, 1, 1},
+ .audiomux = { 0x20000, 0x30000, 0x10000, 0, 0x40000, 0x20000 },
+ .needs_tvaudio = 1,
+ .no_msp34xx = 1,
+ .pll = PLL_35,
+ .tuner_type = 1,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .has_radio = 1,
+ },
+
+ /* ---- card 0x30 ---------------------------------- */
+ [BTTV_BOARD_DYNALINK] = {
+ .name = "Askey CPH03x/ Dynalink Magic TView",
+ .video_inputs = 3,
+ .audio_inputs = 1,
+ .tuner = 0,
+ .svhs = 2,
+ .gpiomask = 15,
+ .muxsel = { 2, 3, 1, 1},
+ .audiomux = {2,0,0,0,1},
+ .needs_tvaudio = 1,
+ .pll = PLL_28,
+ .tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ },
+ [BTTV_BOARD_GVBCTV3PCI] = {
+ .name = "IODATA GV-BCTV3/PCI",
+ .video_inputs = 3,
+ .audio_inputs = 1,
+ .tuner = 0,
+ .svhs = 2,
+ .gpiomask = 0x010f00,
+ .muxsel = {2, 3, 0, 0},
+ .audiomux = {0x10000, 0, 0x10000, 0, 0, 0},
+ .no_msp34xx = 1,
+ .pll = PLL_28,
+ .tuner_type = TUNER_ALPS_TSHC6_NTSC,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .audio_hook = gvbctv3pci_audio,
+ },
+ [BTTV_BOARD_PXELVWPLTVPAK] = {
+ .name = "Prolink PV-BT878P+4E / PixelView PlayTV PAK / Lenco MXTV-9578 CP",
+ .video_inputs = 5,
+ .audio_inputs = 1,
+ .tuner = 0,
+ .svhs = 3,
+ .gpiomask = 0xAA0000,
+ .muxsel = { 2,3,1,1,-1 },
+ .digital_mode = DIGITAL_MODE_CAMERA,
+ .audiomux = { 0x20000, 0, 0x80000, 0x80000, 0xa8000, 0x46000 },
+ .no_msp34xx = 1,
+ .pll = PLL_28,
+ .tuner_type = TUNER_PHILIPS_PAL_I,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .has_remote = 1,
+ /* GPIO wiring: (different from Rev.4C !)
+ GPIO17: U4.A0 (first hef4052bt)
+ GPIO19: U4.A1
+ GPIO20: U5.A1 (second hef4052bt)
+ GPIO21: U4.nEN
+ GPIO22: BT832 Reset Line
+ GPIO23: A5,A0, U5,nEN
+ Note: At i2c=0x8a is a Bt832 chip, which changes to 0x88 after being reset via GPIO22
+ */
+ },
+ [BTTV_BOARD_EAGLE] = {
+ .name = "Eagle Wireless Capricorn2 (bt878A)",
+ .video_inputs = 4,
+ .audio_inputs = 1,
+ .tuner = 0,
+ .svhs = 2,
+ .gpiomask = 7,
+ .muxsel = { 2, 0, 1, 1},
+ .audiomux = { 0, 1, 2, 3, 4},
+ .pll = PLL_28,
+ .tuner_type = -1 /* TUNER_ALPS_TMDH2_NTSC */,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ },
+
+ /* ---- card 0x34 ---------------------------------- */
+ [BTTV_BOARD_PINNACLEPRO] = {
+ /* David Härdeman <david@2gen.com> */
+ .name = "Pinnacle PCTV Studio Pro",
+ .video_inputs = 4,
+ .audio_inputs = 1,
+ .tuner = 0,
+ .svhs = 3,
+ .gpiomask = 0x03000F,
+ .muxsel = { 2, 3, 1, 1},
+ .audiomux = { 1, 0xd0001, 0, 0, 10},
+ /* sound path (5 sources):
+ MUX1 (mask 0x03), Enable Pin 0x08 (0=enable, 1=disable)
+ 0= ext. Audio IN
+ 1= from MUX2
+ 2= Mono TV sound from Tuner
+ 3= not connected
+ MUX2 (mask 0x30000):
+ 0,2,3= from MSP34xx
+ 1= FM stereo Radio from Tuner */
+ .needs_tvaudio = 0,
+ .pll = PLL_28,
+ .tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ },
+ [BTTV_BOARD_TVIEW_RDS_FM] = {
+ /* Claas Langbehn <claas@bigfoot.com>,
+ Sven Grothklags <sven@upb.de> */
+ .name = "Typhoon TView RDS + FM Stereo / KNC1 TV Station RDS",
+ .video_inputs = 4,
+ .audio_inputs = 3,
+ .tuner = 0,
+ .svhs = 2,
+ .gpiomask = 0x1c,
+ .muxsel = { 2, 3, 1, 1},
+ .audiomux = { 0, 0, 0x10, 8, 4 },
+ .needs_tvaudio = 1,
+ .pll = PLL_28,
+ .tuner_type = TUNER_PHILIPS_PAL,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .has_radio = 1,
+ },
+ [BTTV_BOARD_LIFETEC_9415] = {
+ /* Tim Röstermundt <rosterm@uni-muenster.de>
+ in de.comp.os.unix.linux.hardware:
+ options bttv card=0 pll=1 radio=1 gpiomask=0x18e0
+ audiomux=0x44c71f,0x44d71f,0,0x44d71f,0x44dfff
+ options tuner type=5 */
+ .name = "Lifeview FlyVideo 2000 /FlyVideo A2/ Lifetec LT 9415 TV [LR90]",
+ .video_inputs = 4,
+ .audio_inputs = 1,
+ .tuner = 0,
+ .svhs = 2,
+ .gpiomask = 0x18e0,
+ .muxsel = { 2, 3, 1, 1},
+ .audiomux = { 0x0000,0x0800,0x1000,0x1000,0x18e0 },
+ /* For cards with tda9820/tda9821:
+ 0x0000: Tuner normal stereo
+ 0x0080: Tuner A2 SAP (second audio program = Zweikanalton)
+ 0x0880: Tuner A2 stereo */
+ .pll = PLL_28,
+ .tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ },
+ [BTTV_BOARD_BESTBUY_EASYTV] = {
+ /* Miguel Angel Alvarez <maacruz@navegalia.com>
+ old Easy TV BT848 version (model CPH031) */
+ .name = "Askey CPH031/ BESTBUY Easy TV",
+ .video_inputs = 4,
+ .audio_inputs = 1,
+ .tuner = 0,
+ .svhs = 2,
+ .gpiomask = 0xF,
+ .muxsel = { 2, 3, 1, 0},
+ .audiomux = { 2, 0, 0, 0, 10},
+ .needs_tvaudio = 0,
+ .pll = PLL_28,
+ .tuner_type = TUNER_TEMIC_PAL,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ },
+
+ /* ---- card 0x38 ---------------------------------- */
+ [BTTV_BOARD_FLYVIDEO_98FM] = {
+ /* Gordon Heydon <gjheydon@bigfoot.com ('98) */
+ .name = "Lifeview FlyVideo 98FM LR50",
+ .video_inputs = 4,
+ .audio_inputs = 3,
+ .tuner = 0,
+ .svhs = 2,
+ .gpiomask = 0x1800,
+ .muxsel = { 2, 3, 1, 1},
+ .audiomux = { 0, 0x800, 0x1000, 0x1000, 0x1800, 0 },
+ .pll = PLL_28,
+ .tuner_type = 5,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ },
+ /* This is the ultimate cheapo capture card
+ * just a BT848A on a small PCB!
+ * Steve Hosgood <steve@equiinet.com> */
+ [BTTV_BOARD_GRANDTEC] = {
+ .name = "GrandTec 'Grand Video Capture' (Bt848)",
+ .video_inputs = 2,
+ .audio_inputs = 0,
+ .tuner = -1,
+ .svhs = 1,
+ .gpiomask = 0,
+ .muxsel = { 3, 1 },
+ .audiomux = { 0 },
+ .needs_tvaudio = 0,
+ .no_msp34xx = 1,
+ .pll = PLL_35,
+ .tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ },
+ [BTTV_BOARD_ASKEY_CPH060] = {
+ /* Daniel Herrington <daniel.herrington@home.com> */
+ .name = "Askey CPH060/ Phoebe TV Master Only (No FM)",
+ .video_inputs = 3,
+ .audio_inputs = 1,
+ .tuner = 0,
+ .svhs = 2,
+ .gpiomask = 0xe00,
+ .muxsel = { 2, 3, 1, 1},
+ .audiomux = { 0x400, 0x400, 0x400, 0x400, 0x800, 0x400 },
+ .needs_tvaudio = 1,
+ .pll = PLL_28,
+ .tuner_type = TUNER_TEMIC_4036FY5_NTSC,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ },
+ [BTTV_BOARD_ASKEY_CPH03X] = {
+ /* Matti Mottus <mottus@physic.ut.ee> */
+ .name = "Askey CPH03x TV Capturer",
+ .video_inputs = 4,
+ .audio_inputs = 1,
+ .tuner = 0,
+ .svhs = 2,
+ .gpiomask = 0x03000F,
+ .muxsel = { 2, 3, 1, 0},
+ .audiomux = { 2,0,0,0,1 },
+ .pll = PLL_28,
+ .tuner_type = 0,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ },
+
+ /* ---- card 0x3c ---------------------------------- */
+ [BTTV_BOARD_MM100PCTV] = {
+ /* Philip Blundell <philb@gnu.org> */
+ .name = "Modular Technology MM100PCTV",
+ .video_inputs = 2,
+ .audio_inputs = 2,
+ .tuner = 0,
+ .svhs = -1,
+ .gpiomask = 11,
+ .muxsel = { 2, 3, 1, 1},
+ .audiomux = { 2, 0, 0, 1, 8},
+ .pll = PLL_35,
+ .tuner_type = TUNER_TEMIC_PAL,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ },
+ [BTTV_BOARD_GMV1] = {
+ /* Adrian Cox <adrian@humboldt.co.uk */
+ .name = "AG Electronics GMV1",
+ .video_inputs = 2,
+ .audio_inputs = 0,
+ .tuner = -1,
+ .svhs = 1,
+ .gpiomask = 0xF,
+ .muxsel = { 2, 2},
+ .audiomux = { },
+ .no_msp34xx = 1,
+ .needs_tvaudio = 0,
+ .pll = PLL_28,
+ .tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ },
+ [BTTV_BOARD_BESTBUY_EASYTV2] = {
+ /* Miguel Angel Alvarez <maacruz@navegalia.com>
+ new Easy TV BT878 version (model CPH061)
+ special thanks to Informatica Mieres for providing the card */
+ .name = "Askey CPH061/ BESTBUY Easy TV (bt878)",
+ .video_inputs = 3,
+ .audio_inputs = 2,
+ .tuner = 0,
+ .svhs = 2,
+ .gpiomask = 0xFF,
+ .muxsel = { 2, 3, 1, 0},
+ .audiomux = { 1, 0, 4, 4, 9},
+ .needs_tvaudio = 0,
+ .pll = PLL_28,
+ .tuner_type = TUNER_PHILIPS_PAL,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ },
+ [BTTV_BOARD_ATI_TVWONDER] = {
+ /* Lukas Gebauer <geby@volny.cz> */
+ .name = "ATI TV-Wonder",
+ .video_inputs = 3,
+ .audio_inputs = 1,
+ .tuner = 0,
+ .svhs = 2,
+ .gpiomask = 0xf03f,
+ .muxsel = { 2, 3, 1, 0 },
+ .audiomux = { 0xbffe, 0, 0xbfff, 0, 0xbffe},
+ .pll = PLL_28,
+ .tuner_type = TUNER_TEMIC_4006FN5_MULTI_PAL,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ },
+
+ /* ---- card 0x40 ---------------------------------- */
+ [BTTV_BOARD_ATI_TVWONDERVE] = {
+ /* Lukas Gebauer <geby@volny.cz> */
+ .name = "ATI TV-Wonder VE",
+ .video_inputs = 2,
+ .audio_inputs = 1,
+ .tuner = 0,
+ .svhs = -1,
+ .gpiomask = 1,
+ .muxsel = { 2, 3, 0, 1},
+ .audiomux = { 0, 0, 1, 0, 0},
+ .no_msp34xx = 1,
+ .pll = PLL_28,
+ .tuner_type = TUNER_TEMIC_4006FN5_MULTI_PAL,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ },
+ [BTTV_BOARD_FLYVIDEO2000] = {
+ /* DeeJay <deejay@westel900.net (2000S) */
+ .name = "Lifeview FlyVideo 2000S LR90",
+ .video_inputs = 3,
+ .audio_inputs = 3,
+ .tuner = 0,
+ .svhs = 2,
+ .gpiomask = 0x18e0,
+ .muxsel = { 2, 3, 0, 1},
+ /* Radio changed from 1e80 to 0x800 to make
+ FlyVideo2000S in .hu happy (gm)*/
+ /* -dk-???: set mute=0x1800 for tda9874h daughterboard */
+ .audiomux = { 0x0000,0x0800,0x1000,0x1000,0x1800, 0x1080 },
+ .audio_hook = fv2000s_audio,
+ .no_msp34xx = 1,
+ .no_tda9875 = 1,
+ .needs_tvaudio = 1,
+ .pll = PLL_28,
+ .tuner_type = 5,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ },
+ [BTTV_BOARD_TERRATVALUER] = {
+ .name = "Terratec TValueRadio",
+ .video_inputs = 3,
+ .audio_inputs = 1,
+ .tuner = 0,
+ .svhs = 2,
+ .gpiomask = 0xffff00,
+ .muxsel = { 2, 3, 1, 1},
+ .audiomux = { 0x500, 0x500, 0x300, 0x900, 0x900},
+ .needs_tvaudio = 1,
+ .pll = PLL_28,
+ .tuner_type = TUNER_PHILIPS_PAL,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .has_radio = 1,
+ },
+ [BTTV_BOARD_GVBCTV4PCI] = {
+ /* TANAKA Kei <peg00625@nifty.com> */
+ .name = "IODATA GV-BCTV4/PCI",
+ .video_inputs = 3,
+ .audio_inputs = 1,
+ .tuner = 0,
+ .svhs = 2,
+ .gpiomask = 0x010f00,
+ .muxsel = {2, 3, 0, 0},
+ .audiomux = {0x10000, 0, 0x10000, 0, 0, 0},
+ .no_msp34xx = 1,
+ .pll = PLL_28,
+ .tuner_type = TUNER_SHARP_2U5JF5540_NTSC,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .audio_hook = gvbctv3pci_audio,
+ },
+
+ /* ---- card 0x44 ---------------------------------- */
+ [BTTV_BOARD_VOODOOTV_FM] = {
+ .name = "3Dfx VoodooTV FM (Euro), VoodooTV 200 (USA)",
+ /* try "insmod msp3400 simple=0" if you have
+ * sound problems with this card. */
+ .video_inputs = 4,
+ .audio_inputs = 1,
+ .tuner = 0,
+ .svhs = -1,
+ .gpiomask = 0x4f8a00,
+ /* 0x100000: 1=MSP enabled (0=disable again)
+ * 0x010000: Connected to "S0" on tda9880 (0=Pal/BG, 1=NTSC) */
+ .audiomux = {0x947fff, 0x987fff,0x947fff,0x947fff, 0x947fff},
+ /* tvtuner, radio, external,internal, mute, stereo
+ * tuner, Composit, SVid, Composit-on-Svid-adapter */
+ .muxsel = { 2, 3 ,0 ,1},
+ .tuner_type = TUNER_MT2032,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .pll = PLL_28,
+ .has_radio = 1,
+ },
+ [BTTV_BOARD_AIMMS] = {
+ /* Philip Blundell <pb@nexus.co.uk> */
+ .name = "Active Imaging AIMMS",
+ .video_inputs = 1,
+ .audio_inputs = 0,
+ .tuner = -1,
+ .tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .pll = PLL_28,
+ .muxsel = { 2 },
+ .gpiomask = 0
+ },
+ [BTTV_BOARD_PV_BT878P_PLUS] = {
+ /* Tomasz Pyra <hellfire@sedez.iq.pl> */
+ .name = "Prolink Pixelview PV-BT878P+ (Rev.4C,8E)",
+ .video_inputs = 3,
+ .audio_inputs = 4,
+ .tuner = 0,
+ .svhs = 2,
+ .gpiomask = 15,
+ .muxsel = { 2, 3, 1, 1},
+ .audiomux = { 0, 0, 11, 7, 13, 0}, /* TV and Radio with same GPIO ! */
+ .needs_tvaudio = 1,
+ .pll = PLL_28,
+ .tuner_type = 25,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .has_remote = 1,
+ /* GPIO wiring:
+ GPIO0: U4.A0 (hef4052bt)
+ GPIO1: U4.A1
+ GPIO2: U4.A1 (second hef4052bt)
+ GPIO3: U4.nEN, U5.A0, A5.nEN
+ GPIO8-15: vrd866b ?
+ */
+ },
+ [BTTV_BOARD_FLYVIDEO98EZ] = {
+ .name = "Lifeview FlyVideo 98EZ (capture only) LR51",
+ .video_inputs = 4,
+ .audio_inputs = 0,
+ .tuner = -1,
+ .svhs = 2,
+ .muxsel = { 2, 3, 1, 1}, /* AV1, AV2, SVHS, CVid adapter on SVHS */
+ .pll = PLL_28,
+ .no_msp34xx = 1,
+ .tuner_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ },
+
+ /* ---- card 0x48 ---------------------------------- */
+ [BTTV_BOARD_PV_BT878P_9B] = {
+ /* Dariusz Kowalewski <darekk@automex.pl> */
+ .name = "Prolink Pixelview PV-BT878P+9B (PlayTV Pro rev.9B FM+NICAM)",
+ .video_inputs = 4,
+ .audio_inputs = 1,
+ .tuner = 0,
+ .svhs = 2,
+ .gpiomask = 0x3f,
+ .muxsel = { 2, 3, 1, 1 },
+ .audiomux = { 0x01, 0x00, 0x03, 0x03, 0x09, 0x02 },
+ .needs_tvaudio = 1,
+ .no_msp34xx = 1,
+ .no_tda9875 = 1,
+ .pll = PLL_28,
+ .tuner_type = 5,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .audio_hook = pvbt878p9b_audio, /* Note: not all cards have stereo */
+ .has_radio = 1, /* Note: not all cards have radio */
+ .has_remote = 1,
+ /* GPIO wiring:
+ GPIO0: A0 hef4052
+ GPIO1: A1 hef4052
+ GPIO3: nEN hef4052
+ GPIO8-15: vrd866b
+ GPIO20,22,23: R30,R29,R28
+ */
+ },
+ [BTTV_BOARD_SENSORAY311] = {
+ /* Clay Kunz <ckunz@mail.arc.nasa.gov> */
+ /* you must jumper JP5 for the card to work */
+ .name = "Sensoray 311",
+ .video_inputs = 5,
+ .audio_inputs = 0,
+ .tuner = -1,
+ .svhs = 4,
+ .gpiomask = 0,
+ .muxsel = { 2, 3, 1, 0, 0},
+ .audiomux = { 0 },
+ .needs_tvaudio = 0,
+ .tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ },
+ [BTTV_BOARD_RV605] = {
+ /* Miguel Freitas <miguel@cetuc.puc-rio.br> */
+ .name = "RemoteVision MX (RV605)",
+ .video_inputs = 16,
+ .audio_inputs = 0,
+ .tuner = -1,
+ .svhs = -1,
+ .gpiomask = 0x00,
+ .gpiomask2 = 0x07ff,
+ .muxsel = { 0x33, 0x13, 0x23, 0x43, 0xf3, 0x73, 0xe3, 0x03,
+ 0xd3, 0xb3, 0xc3, 0x63, 0x93, 0x53, 0x83, 0xa3 },
+ .no_msp34xx = 1,
+ .no_tda9875 = 1,
+ .tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .muxsel_hook = rv605_muxsel,
+ },
+ [BTTV_BOARD_POWERCLR_MTV878] = {
+ .name = "Powercolor MTV878/ MTV878R/ MTV878F",
+ .video_inputs = 3,
+ .audio_inputs = 2,
+ .tuner = 0,
+ .svhs = 2,
+ .gpiomask = 0x1C800F, /* Bit0-2: Audio select, 8-12:remote control 14:remote valid 15:remote reset */
+ .muxsel = { 2, 1, 1, },
+ .audiomux = { 0, 1, 2, 2, 4 },
+ .needs_tvaudio = 0,
+ .tuner_type = TUNER_PHILIPS_PAL,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .pll = PLL_28,
+ .has_radio = 1,
+ },
+
+ /* ---- card 0x4c ---------------------------------- */
+ [BTTV_BOARD_WINDVR] = {
+ /* Masaki Suzuki <masaki@btree.org> */
+ .name = "Canopus WinDVR PCI (COMPAQ Presario 3524JP, 5112JP)",
+ .video_inputs = 3,
+ .audio_inputs = 1,
+ .tuner = 0,
+ .svhs = 2,
+ .gpiomask = 0x140007,
+ .muxsel = { 2, 3, 1, 1 },
+ .audiomux = { 0, 1, 2, 3, 4, 0 },
+ .tuner_type = TUNER_PHILIPS_NTSC,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .audio_hook = windvr_audio,
+ },
+ [BTTV_BOARD_GRANDTEC_MULTI] = {
+ .name = "GrandTec Multi Capture Card (Bt878)",
+ .video_inputs = 4,
+ .audio_inputs = 0,
+ .tuner = -1,
+ .svhs = -1,
+ .gpiomask = 0,
+ .muxsel = { 2, 3, 1, 0 },
+ .audiomux = { 0 },
+ .needs_tvaudio = 0,
+ .no_msp34xx = 1,
+ .pll = PLL_28,
+ .tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ },
+ [BTTV_BOARD_KWORLD] = {
+ .name = "Jetway TV/Capture JW-TV878-FBK, Kworld KW-TV878RF",
+ .video_inputs = 4,
+ .audio_inputs = 3,
+ .tuner = 0,
+ .svhs = 2,
+ .gpiomask = 7,
+ .muxsel = { 2, 3, 1, 1 }, /* Tuner, SVid, SVHS, SVid to SVHS connector */
+ .audiomux = { 0 ,0 ,4, 4,4,4},/* Yes, this tuner uses the same audio output for TV and FM radio!
+ * This card lacks external Audio In, so we mute it on Ext. & Int.
+ * The PCB can take a sbx1637/sbx1673, wiring unknown.
+ * This card lacks PCI subsystem ID, sigh.
+ * audiomux=1: lower volume, 2+3: mute
+ * btwincap uses 0x80000/0x80003
+ */
+ .needs_tvaudio = 0,
+ .no_msp34xx = 1,
+ .pll = PLL_28,
+ .tuner_type = 5,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ /* Samsung TCPA9095PC27A (BG+DK), philips compatible, w/FM, stereo and
+ radio signal strength indicators work fine. */
+ .has_radio = 1,
+ /* GPIO Info:
+ GPIO0,1: HEF4052 A0,A1
+ GPIO2: HEF4052 nENABLE
+ GPIO3-7: n.c.
+ GPIO8-13: IRDC357 data0-5 (data6 n.c. ?) [chip not present on my card]
+ GPIO14,15: ??
+ GPIO16-21: n.c.
+ GPIO22,23: ??
+ ?? : mtu8b56ep microcontroller for IR (GPIO wiring unknown)*/
+ },
+ [BTTV_BOARD_DSP_TCVIDEO] = {
+ /* Arthur Tetzlaff-Deas, DSP Design Ltd <software@dspdesign.com> */
+ .name = "DSP Design TCVIDEO",
+ .video_inputs = 4,
+ .svhs = -1,
+ .muxsel = { 2, 3, 1, 0},
+ .pll = PLL_28,
+ .tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ },
+
+ /* ---- card 0x50 ---------------------------------- */
+ [BTTV_BOARD_HAUPPAUGEPVR] = {
+ .name = "Hauppauge WinTV PVR",
+ .video_inputs = 4,
+ .audio_inputs = 1,
+ .tuner = 0,
+ .svhs = 2,
+ .muxsel = { 2, 0, 1, 1},
+ .needs_tvaudio = 1,
+ .pll = PLL_28,
+ .tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+
+ .gpiomask = 7,
+ .audiomux = {7},
+ },
+ [BTTV_BOARD_GVBCTV5PCI] = {
+ .name = "IODATA GV-BCTV5/PCI",
+ .video_inputs = 3,
+ .audio_inputs = 1,
+ .tuner = 0,
+ .svhs = 2,
+ .gpiomask = 0x0f0f80,
+ .muxsel = {2, 3, 1, 0},
+ .audiomux = {0x030000, 0x010000, 0, 0, 0x020000, 0},
+ .no_msp34xx = 1,
+ .pll = PLL_28,
+ .tuner_type = TUNER_PHILIPS_NTSC_M,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .audio_hook = gvbctv5pci_audio,
+ .has_radio = 1,
+ },
+ [BTTV_BOARD_OSPREY1x0] = {
+ .name = "Osprey 100/150 (878)", /* 0x1(2|3)-45C6-C1 */
+ .video_inputs = 4, /* id-inputs-clock */
+ .audio_inputs = 0,
+ .tuner = -1,
+ .svhs = 3,
+ .muxsel = { 3, 2, 0, 1 },
+ .pll = PLL_28,
+ .tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .no_msp34xx = 1,
+ .no_tda9875 = 1,
+ .no_tda7432 = 1,
+ },
+ [BTTV_BOARD_OSPREY1x0_848] = {
+ .name = "Osprey 100/150 (848)", /* 0x04-54C0-C1 & older boards */
+ .video_inputs = 3,
+ .audio_inputs = 0,
+ .tuner = -1,
+ .svhs = 2,
+ .muxsel = { 2, 3, 1 },
+ .pll = PLL_28,
+ .tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .no_msp34xx = 1,
+ .no_tda9875 = 1,
+ .no_tda7432 = 1,
+ },
+
+ /* ---- card 0x54 ---------------------------------- */
+ [BTTV_BOARD_OSPREY101_848] = {
+ .name = "Osprey 101 (848)", /* 0x05-40C0-C1 */
+ .video_inputs = 2,
+ .audio_inputs = 0,
+ .tuner = -1,
+ .svhs = 1,
+ .muxsel = { 3, 1 },
+ .pll = PLL_28,
+ .tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .no_msp34xx = 1,
+ .no_tda9875 = 1,
+ .no_tda7432 = 1,
+ },
+ [BTTV_BOARD_OSPREY1x1] = {
+ .name = "Osprey 101/151", /* 0x1(4|5)-0004-C4 */
+ .video_inputs = 1,
+ .audio_inputs = 0,
+ .tuner = -1,
+ .svhs = -1,
+ .muxsel = { 0 },
+ .pll = PLL_28,
+ .tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .no_msp34xx = 1,
+ .no_tda9875 = 1,
+ .no_tda7432 = 1,
+ },
+ [BTTV_BOARD_OSPREY1x1_SVID] = {
+ .name = "Osprey 101/151 w/ svid", /* 0x(16|17|20)-00C4-C1 */
+ .video_inputs = 2,
+ .audio_inputs = 0,
+ .tuner = -1,
+ .svhs = 1,
+ .muxsel = { 0, 1 },
+ .pll = PLL_28,
+ .tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .no_msp34xx = 1,
+ .no_tda9875 = 1,
+ .no_tda7432 = 1,
+ },
+ [BTTV_BOARD_OSPREY2xx] = {
+ .name = "Osprey 200/201/250/251", /* 0x1(8|9|E|F)-0004-C4 */
+ .video_inputs = 1,
+ .audio_inputs = 1,
+ .tuner = -1,
+ .svhs = -1,
+ .muxsel = { 0 },
+ .pll = PLL_28,
+ .tuner_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .no_msp34xx = 1,
+ .no_tda9875 = 1,
+ .no_tda7432 = 1,
+ },
+
+ /* ---- card 0x58 ---------------------------------- */
+ [BTTV_BOARD_OSPREY2x0_SVID] = {
+ .name = "Osprey 200/250", /* 0x1(A|B)-00C4-C1 */
+ .video_inputs = 2,
+ .audio_inputs = 1,
+ .tuner = -1,
+ .svhs = 1,
+ .muxsel = { 0, 1 },
+ .pll = PLL_28,
+ .tuner_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .no_msp34xx = 1,
+ .no_tda9875 = 1,
+ .no_tda7432 = 1,
+ },
+ [BTTV_BOARD_OSPREY2x0] = {
+ .name = "Osprey 210/220", /* 0x1(A|B)-04C0-C1 */
+ .video_inputs = 2,
+ .audio_inputs = 1,
+ .tuner = -1,
+ .svhs = 1,
+ .muxsel = { 2, 3 },
+ .pll = PLL_28,
+ .tuner_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .no_msp34xx = 1,
+ .no_tda9875 = 1,
+ .no_tda7432 = 1,
+ },
+ [BTTV_BOARD_OSPREY500] = {
+ .name = "Osprey 500", /* 500 */
+ .video_inputs = 2,
+ .audio_inputs = 1,
+ .tuner = -1,
+ .svhs = 1,
+ .muxsel = { 2, 3 },
+ .pll = PLL_28,
+ .tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .no_msp34xx = 1,
+ .no_tda9875 = 1,
+ .no_tda7432 = 1,
+ },
+ [BTTV_BOARD_OSPREY540] = {
+ .name = "Osprey 540", /* 540 */
+ .video_inputs = 4,
+ .audio_inputs = 1,
+ .tuner = -1,
+ #if 0 /* TODO ... */
+ .svhs = OSPREY540_SVID_ANALOG,
+ .muxsel = { [OSPREY540_COMP_ANALOG] = 2,
+ [OSPREY540_SVID_ANALOG] = 3, },
+ #endif
+ .pll = PLL_28,
+ .tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .no_msp34xx = 1,
+ .no_tda9875 = 1,
+ .no_tda7432 = 1,
+ #if 0 /* TODO ... */
+ .muxsel_hook = osprey_540_muxsel,
+ .picture_hook = osprey_540_set_picture,
+ #endif
+ },
+
+ /* ---- card 0x5C ---------------------------------- */
+ [BTTV_BOARD_OSPREY2000] = {
+ .name = "Osprey 2000", /* 2000 */
+ .video_inputs = 2,
+ .audio_inputs = 1,
+ .tuner = -1,
+ .svhs = 1,
+ .muxsel = { 2, 3 },
+ .pll = PLL_28,
+ .tuner_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .no_msp34xx = 1,
+ .no_tda9875 = 1,
+ .no_tda7432 = 1, /* must avoid, conflicts with the bt860 */
+ },
+ [BTTV_BOARD_IDS_EAGLE] = {
+ /* M G Berberich <berberic@forwiss.uni-passau.de> */
+ .name = "IDS Eagle",
+ .video_inputs = 4,
+ .audio_inputs = 0,
+ .tuner = -1,
+ .tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .svhs = -1,
+ .gpiomask = 0,
+ .muxsel = { 0, 1, 2, 3 },
+ .muxsel_hook = eagle_muxsel,
+ .no_msp34xx = 1,
+ .no_tda9875 = 1,
+ .pll = PLL_28,
+ },
+ [BTTV_BOARD_PINNACLESAT] = {
+ .name = "Pinnacle PCTV Sat",
+ .video_inputs = 2,
+ .audio_inputs = 0,
+ .svhs = 1,
+ .tuner = -1,
+ .tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .no_msp34xx = 1,
+ .no_tda9875 = 1,
+ .no_tda7432 = 1,
+ .muxsel = { 3, 0, 1, 2},
+ .pll = PLL_28,
+ .no_gpioirq = 1,
+ .has_dvb = 1,
+ },
+ [BTTV_BOARD_FORMAC_PROTV] = {
+ .name = "Formac ProTV II (bt878)",
+ .video_inputs = 4,
+ .audio_inputs = 1,
+ .tuner = 0,
+ .svhs = 3,
+ .gpiomask = 2,
+ /* TV, Comp1, Composite over SVID con, SVID */
+ .muxsel = { 2, 3, 1, 1},
+ .audiomux = { 2, 2, 0, 0, 0 },
+ .pll = PLL_28,
+ .has_radio = 1,
+ .tuner_type = TUNER_PHILIPS_PAL,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ /* sound routing:
+ GPIO=0x00,0x01,0x03: mute (?)
+ 0x02: both TV and radio (tuner: FM1216/I)
+ The card has onboard audio connectors labeled "cdrom" and "board",
+ not soldered here, though unknown wiring.
+ Card lacks: external audio in, pci subsystem id.
*/
- .name = "Kodicom 4400R (slave)",
- .video_inputs = 16,
- .audio_inputs = 0,
- .tuner = -1,
- .tuner_type = -1,
- .tuner_addr = ADDR_UNSET,
- .svhs = -1,
- .gpiomask = 0x010000,
- .no_gpioirq = 1,
- .muxsel = { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 },
- .pll = PLL_28,
- .no_msp34xx = 1,
- .no_tda7432 = 1,
- .no_tda9875 = 1,
- .muxsel_hook = kodicom4400r_muxsel,
-},
-{
- /* ---- card 0x86---------------------------------- */
- /* Michael Henson <mhenson@clarityvi.com> */
- /* Adlink RTV24 with special unlock codes */
- .name = "Adlink RTV24",
- .video_inputs = 4,
- .audio_inputs = 1,
- .tuner = 0,
- .svhs = 2,
- .muxsel = { 2, 3, 1, 0},
- .tuner_type = -1,
- .tuner_addr = ADDR_UNSET,
- .pll = PLL_28,
-},
-{
- /* ---- card 0x87---------------------------------- */
- /* Michael Krufky <mkrufky@m1k.net> */
- .name = "DViCO FusionHDTV 5 Lite",
- .tuner = 0,
- .tuner_type = TUNER_LG_TDVS_H062F,
- .tuner_addr = ADDR_UNSET,
- .video_inputs = 3,
- .audio_inputs = 1,
- .svhs = 2,
- .muxsel = { 2, 3, 1 },
- .gpiomask = 0x00e00007,
- .audiomux = { 0x00400005, 0, 0x00000001, 0, 0x00c00007, 0 },
- .no_msp34xx = 1,
- .no_tda9875 = 1,
- .no_tda7432 = 1,
-},{
- /* ---- card 0x88---------------------------------- */
- /* Mauro Carvalho Chehab <mchehab@brturbo.com.br> */
- .name = "Acorp Y878F",
- .video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
- .svhs = 2,
- .gpiomask = 0x01fe00,
- .muxsel = { 2, 3, 1, 1},
- .audiomux = { 0x001e00, 0, 0x018000, 0x014000, 0x002000, 0 },
- .needs_tvaudio = 1,
- .pll = PLL_28,
- .tuner_type = TUNER_YMEC_TVF66T5_B_DFF,
- .tuner_addr = 0xc1 >>1,
- .has_radio = 1,
-}};
+ },
+
+ /* ---- card 0x60 ---------------------------------- */
+ [BTTV_BOARD_MACHTV] = {
+ .name = "MachTV",
+ .video_inputs = 3,
+ .audio_inputs = 1,
+ .tuner = 0,
+ .svhs = -1,
+ .gpiomask = 7,
+ .muxsel = { 2, 3, 1, 1},
+ .audiomux = { 0, 1, 2, 3, 4},
+ .needs_tvaudio = 1,
+ .tuner_type = 5,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .pll = PLL_28,
+ },
+ [BTTV_BOARD_EURESYS_PICOLO] = {
+ .name = "Euresys Picolo",
+ .video_inputs = 3,
+ .audio_inputs = 0,
+ .tuner = -1,
+ .svhs = 2,
+ .gpiomask = 0,
+ .no_msp34xx = 1,
+ .no_tda9875 = 1,
+ .no_tda7432 = 1,
+ .muxsel = { 2, 0, 1},
+ .pll = PLL_28,
+ .tuner_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ },
+ [BTTV_BOARD_PV150] = {
+ /* Luc Van Hoeylandt <luc@e-magic.be> */
+ .name = "ProVideo PV150", /* 0x4f */
+ .video_inputs = 2,
+ .audio_inputs = 0,
+ .tuner = -1,
+ .svhs = -1,
+ .gpiomask = 0,
+ .muxsel = { 2, 3 },
+ .audiomux = { 0 },
+ .needs_tvaudio = 0,
+ .no_msp34xx = 1,
+ .pll = PLL_28,
+ .tuner_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ },
+ [BTTV_BOARD_AD_TVK503] = {
+ /* Hiroshi Takekawa <sian@big.or.jp> */
+ /* This card lacks subsystem ID */
+ .name = "AD-TVK503", /* 0x63 */
+ .video_inputs = 4,
+ .audio_inputs = 1,
+ .tuner = 0,
+ .svhs = 2,
+ .gpiomask = 0x001e8007,
+ .muxsel = { 2, 3, 1, 0 },
+ /* Tuner, Radio, external, internal, off, on */
+ .audiomux = { 0x08, 0x0f, 0x0a, 0x08, 0x0f, 0x08 },
+ .needs_tvaudio = 0,
+ .no_msp34xx = 1,
+ .pll = PLL_28,
+ .tuner_type = 2,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .audio_hook = adtvk503_audio,
+ },
+
+ /* ---- card 0x64 ---------------------------------- */
+ [BTTV_BOARD_HERCULES_SM_TV] = {
+ .name = "Hercules Smart TV Stereo",
+ .video_inputs = 4,
+ .audio_inputs = 1,
+ .tuner = 0,
+ .svhs = 2,
+ .gpiomask = 0x00,
+ .muxsel = { 2, 3, 1, 1 },
+ .needs_tvaudio = 1,
+ .no_msp34xx = 1,
+ .pll = PLL_28,
+ .tuner_type = 5,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ /* Notes:
+ - card lacks subsystem ID
+ - stereo variant w/ daughter board with tda9874a @0xb0
+ - Audio Routing:
+ always from tda9874 independent of GPIO (?)
+ external line in: unknown
+ - Other chips: em78p156elp @ 0x96 (probably IR remote control)
+ hef4053 (instead 4052) for unknown function
+ */
+ },
+ [BTTV_BOARD_PACETV] = {
+ .name = "Pace TV & Radio Card",
+ .video_inputs = 4,
+ .audio_inputs = 1,
+ .tuner = 0,
+ .svhs = 2,
+ .muxsel = { 2, 3, 1, 1}, /* Tuner, CVid, SVid, CVid over SVid connector */
+ .gpiomask = 0,
+ .no_tda9875 = 1,
+ .no_tda7432 = 1,
+ .tuner_type = 1,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .has_radio = 1,
+ .pll = PLL_28,
+ /* Bt878, Bt832, FI1246 tuner; no pci subsystem id
+ only internal line out: (4pin header) RGGL
+ Radio must be decoded by msp3410d (not routed through)*/
+ /*
+ .digital_mode = DIGITAL_MODE_CAMERA, todo!
+ */
+ },
+ [BTTV_BOARD_IVC200] = {
+ /* Chris Willing <chris@vislab.usyd.edu.au> */
+ .name = "IVC-200",
+ .video_inputs = 1,
+ .audio_inputs = 0,
+ .tuner = -1,
+ .tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .svhs = -1,
+ .gpiomask = 0xdf,
+ .muxsel = { 2 },
+ .pll = PLL_28,
+ },
+ [BTTV_BOARD_XGUARD] = {
+ .name = "Grand X-Guard / Trust 814PCI",
+ .video_inputs = 16,
+ .audio_inputs = 0,
+ .tuner = -1,
+ .svhs = -1,
+ .tuner_type = 4,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .gpiomask2 = 0xff,
+ .muxsel = { 2,2,2,2, 3,3,3,3, 1,1,1,1, 0,0,0,0 },
+ .muxsel_hook = xguard_muxsel,
+ .no_msp34xx = 1,
+ .no_tda9875 = 1,
+ .no_tda7432 = 1,
+ .pll = PLL_28,
+ },
+
+ /* ---- card 0x68 ---------------------------------- */
+ [BTTV_BOARD_NEBULA_DIGITV] = {
+ .name = "Nebula Electronics DigiTV",
+ .video_inputs = 1,
+ .tuner = -1,
+ .svhs = -1,
+ .muxsel = { 2, 3, 1, 0},
+ .no_msp34xx = 1,
+ .no_tda9875 = 1,
+ .no_tda7432 = 1,
+ .pll = PLL_28,
+ .tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .has_dvb = 1,
+ .no_gpioirq = 1,
+ },
+ [BTTV_BOARD_PV143] = {
+ /* Jorge Boncompte - DTI2 <jorge@dti2.net> */
+ .name = "ProVideo PV143",
+ .video_inputs = 4,
+ .audio_inputs = 0,
+ .tuner = -1,
+ .svhs = -1,
+ .gpiomask = 0,
+ .muxsel = { 2, 3, 1, 0 },
+ .audiomux = { 0 },
+ .needs_tvaudio = 0,
+ .no_msp34xx = 1,
+ .pll = PLL_28,
+ .tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ },
+ [BTTV_BOARD_VD009X1_MINIDIN] = {
+ /* M.Klahr@phytec.de */
+ .name = "PHYTEC VD-009-X1 MiniDIN (bt878)",
+ .video_inputs = 4,
+ .audio_inputs = 0,
+ .tuner = -1, /* card has no tuner */
+ .svhs = 3,
+ .gpiomask = 0x00,
+ .muxsel = { 2, 3, 1, 0},
+ .audiomux = { 0, 0, 0, 0, 0, 0 }, /* card has no audio */
+ .needs_tvaudio = 1,
+ .pll = PLL_28,
+ .tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ },
+ [BTTV_BOARD_VD009X1_COMBI] = {
+ .name = "PHYTEC VD-009-X1 Combi (bt878)",
+ .video_inputs = 4,
+ .audio_inputs = 0,
+ .tuner = -1, /* card has no tuner */
+ .svhs = 3,
+ .gpiomask = 0x00,
+ .muxsel = { 2, 3, 1, 1},
+ .audiomux = { 0, 0, 0, 0, 0, 0 }, /* card has no audio */
+ .needs_tvaudio = 1,
+ .pll = PLL_28,
+ .tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ },
+
+ /* ---- card 0x6c ---------------------------------- */
+ [BTTV_BOARD_VD009_MINIDIN] = {
+ .name = "PHYTEC VD-009 MiniDIN (bt878)",
+ .video_inputs = 10,
+ .audio_inputs = 0,
+ .tuner = -1, /* card has no tuner */
+ .svhs = 9,
+ .gpiomask = 0x00,
+ .gpiomask2 = 0x03, /* gpiomask2 defines the bits used to switch audio
+ via the upper nibble of muxsel. here: used for
+ xternal video-mux */
+ .muxsel = { 0x02, 0x12, 0x22, 0x32, 0x03, 0x13, 0x23, 0x33, 0x01, 0x00 },
+ .audiomux = { 0, 0, 0, 0, 0, 0 }, /* card has no audio */
+ .needs_tvaudio = 1,
+ .pll = PLL_28,
+ .tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ },
+ [BTTV_BOARD_VD009_COMBI] = {
+ .name = "PHYTEC VD-009 Combi (bt878)",
+ .video_inputs = 10,
+ .audio_inputs = 0,
+ .tuner = -1, /* card has no tuner */
+ .svhs = 9,
+ .gpiomask = 0x00,
+ .gpiomask2 = 0x03, /* gpiomask2 defines the bits used to switch audio
+ via the upper nibble of muxsel. here: used for
+ xternal video-mux */
+ .muxsel = { 0x02, 0x12, 0x22, 0x32, 0x03, 0x13, 0x23, 0x33, 0x01, 0x01 },
+ .audiomux = { 0, 0, 0, 0, 0, 0 }, /* card has no audio */
+ .needs_tvaudio = 1,
+ .pll = PLL_28,
+ .tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ },
+ [BTTV_BOARD_IVC100] = {
+ .name = "IVC-100",
+ .video_inputs = 4,
+ .audio_inputs = 0,
+ .tuner = -1,
+ .tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .svhs = -1,
+ .gpiomask = 0xdf,
+ .muxsel = { 2, 3, 1, 0 },
+ .pll = PLL_28,
+ },
+ [BTTV_BOARD_IVC120] = {
+ /* IVC-120G - Alan Garfield <alan@fromorbit.com> */
+ .name = "IVC-120G",
+ .video_inputs = 16,
+ .audio_inputs = 0, /* card has no audio */
+ .tuner = -1, /* card has no tuner */
+ .tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .svhs = -1, /* card has no svhs */
+ .needs_tvaudio = 0,
+ .no_msp34xx = 1,
+ .no_tda9875 = 1,
+ .no_tda7432 = 1,
+ .gpiomask = 0x00,
+ .muxsel = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
+ 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10 },
+ .muxsel_hook = ivc120_muxsel,
+ .pll = PLL_28,
+ },
+
+ /* ---- card 0x70 ---------------------------------- */
+ [BTTV_BOARD_PC_HDTV] = {
+ .name = "pcHDTV HD-2000 TV",
+ .video_inputs = 4,
+ .audio_inputs = 1,
+ .tuner = 0,
+ .svhs = 2,
+ .muxsel = { 2, 3, 1, 0},
+ .tuner_type = TUNER_PHILIPS_ATSC,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .has_dvb = 1,
+ },
+ [BTTV_BOARD_TWINHAN_DST] = {
+ .name = "Twinhan DST + clones",
+ .no_msp34xx = 1,
+ .no_tda9875 = 1,
+ .no_tda7432 = 1,
+ .tuner_type = TUNER_ABSENT,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .no_video = 1,
+ .has_dvb = 1,
+ },
+ [BTTV_BOARD_WINFASTVC100] = {
+ .name = "Winfast VC100",
+ .video_inputs = 3,
+ .audio_inputs = 0,
+ .svhs = 1,
+ .tuner = -1,
+ .muxsel = { 3, 1, 1, 3}, /* Vid In, SVid In, Vid over SVid in connector */
+ .no_msp34xx = 1,
+ .no_tda9875 = 1,
+ .no_tda7432 = 1,
+ .tuner_type = TUNER_ABSENT,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .pll = PLL_28,
+ },
+ [BTTV_BOARD_TEV560] = {
+ .name = "Teppro TEV-560/InterVision IV-560",
+ .video_inputs = 3,
+ .audio_inputs = 1,
+ .tuner = 0,
+ .svhs = 2,
+ .gpiomask = 3,
+ .muxsel = { 2, 3, 1, 1},
+ .audiomux = { 1, 1, 1, 1, 0},
+ .needs_tvaudio = 1,
+ .tuner_type = TUNER_PHILIPS_PAL,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .pll = PLL_35,
+ },
+
+ /* ---- card 0x74 ---------------------------------- */
+ [BTTV_BOARD_SIMUS_GVC1100] = {
+ .name = "SIMUS GVC1100",
+ .video_inputs = 4,
+ .audio_inputs = 0,
+ .tuner = -1,
+ .svhs = -1,
+ .tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .pll = PLL_28,
+ .muxsel = { 2, 2, 2, 2},
+ .gpiomask = 0x3F,
+ .muxsel_hook = gvc1100_muxsel,
+ },
+ [BTTV_BOARD_NGSTV_PLUS] = {
+ /* Carlos Silva r3pek@r3pek.homelinux.org || card 0x75 */
+ .name = "NGS NGSTV+",
+ .video_inputs = 3,
+ .tuner = 0,
+ .svhs = 2,
+ .gpiomask = 0x008007,
+ .muxsel = {2, 3, 0, 0},
+ .audiomux = {0, 0, 0, 0, 0x000003, 0},
+ .pll = PLL_28,
+ .tuner_type = TUNER_PHILIPS_PAL,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .has_remote = 1,
+ },
+ [BTTV_BOARD_LMLBT4] = {
+ /* http://linuxmedialabs.com */
+ .name = "LMLBT4",
+ .video_inputs = 4, /* IN1,IN2,IN3,IN4 */
+ .audio_inputs = 0,
+ .tuner = -1,
+ .svhs = -1,
+ .muxsel = { 2, 3, 1, 0 },
+ .no_msp34xx = 1,
+ .no_tda9875 = 1,
+ .no_tda7432 = 1,
+ .needs_tvaudio = 0,
+ .tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ },
+ [BTTV_BOARD_TEKRAM_M205] = {
+ /* Helmroos Harri <harri.helmroos@pp.inet.fi> */
+ .name = "Tekram M205 PRO",
+ .video_inputs = 3,
+ .audio_inputs = 1,
+ .tuner = 0,
+ .tuner_type = TUNER_PHILIPS_PAL,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .svhs = 2,
+ .needs_tvaudio = 0,
+ .gpiomask = 0x68,
+ .muxsel = { 2, 3, 1},
+ .audiomux = { 0x68, 0x68, 0x61, 0x61, 0x00 },
+ .pll = PLL_28,
+ },
+
+ /* ---- card 0x78 ---------------------------------- */
+ [BTTV_BOARD_CONTVFMI] = {
+ /* Javier Cendan Ares <jcendan@lycos.es> */
+ /* bt878 TV + FM without subsystem ID */
+ .name = "Conceptronic CONTVFMi",
+ .video_inputs = 3,
+ .audio_inputs = 1,
+ .tuner = 0,
+ .svhs = 2,
+ .gpiomask = 0x008007,
+ .muxsel = { 2, 3, 1, 1 },
+ .audiomux = { 0, 1, 2, 2, 3 },
+ .needs_tvaudio = 0,
+ .pll = PLL_28,
+ .tuner_type = TUNER_PHILIPS_PAL,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .has_remote = 1,
+ .has_radio = 1,
+ },
+ [BTTV_BOARD_PICOLO_TETRA_CHIP] = {
+ /*Eric DEBIEF <debief@telemsa.com>*/
+ /*EURESYS Picolo Tetra : 4 Conexant Fusion 878A, no audio, video input set with analog multiplexers GPIO controled*/
+ /* adds picolo_tetra_muxsel(), picolo_tetra_init(), the folowing declaration strucure, and #define BTTV_BOARD_PICOLO_TETRA_CHIP*/
+ /*0x79 in bttv.h*/
+ .name = "Euresys Picolo Tetra",
+ .video_inputs = 4,
+ .audio_inputs = 0,
+ .tuner = -1,
+ .svhs = -1,
+ .gpiomask = 0,
+ .gpiomask2 = 0x3C<<16,/*Set the GPIO[18]->GPIO[21] as output pin.==> drive the video inputs through analog multiplexers*/
+ .no_msp34xx = 1,
+ .no_tda9875 = 1,
+ .no_tda7432 = 1,
+ .muxsel = {2,2,2,2},/*878A input is always MUX0, see above.*/
+ .audiomux = { 0, 0, 0, 0, 0, 0 }, /* card has no audio */
+ .pll = PLL_28,
+ .needs_tvaudio = 0,
+ .muxsel_hook = picolo_tetra_muxsel,/*Required as it doesn't follow the classic input selection policy*/
+ .tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ },
+ [BTTV_BOARD_SPIRIT_TV] = {
+ /* Spirit TV Tuner from http://spiritmodems.com.au */
+ /* Stafford Goodsell <surge@goliath.homeunix.org> */
+ .name = "Spirit TV Tuner",
+ .video_inputs = 3,
+ .audio_inputs = 1,
+ .tuner = 0,
+ .svhs = 2,
+ .gpiomask = 0x0000000f,
+ .muxsel = { 2, 1, 1 },
+ .audiomux = { 0x02, 0x00, 0x00, 0x00, 0x00},
+ .tuner_type = TUNER_TEMIC_PAL,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .no_msp34xx = 1,
+ .no_tda9875 = 1,
+ },
+ [BTTV_BOARD_AVDVBT_771] = {
+ /* Wolfram Joost <wojo@frokaschwei.de> */
+ .name = "AVerMedia AVerTV DVB-T 771",
+ .video_inputs = 2,
+ .svhs = 1,
+ .tuner = -1,
+ .tuner_type = TUNER_ABSENT,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .muxsel = { 3 , 3 },
+ .no_msp34xx = 1,
+ .no_tda9875 = 1,
+ .no_tda7432 = 1,
+ .pll = PLL_28,
+ .has_dvb = 1,
+ .no_gpioirq = 1,
+ .has_remote = 1,
+ },
+ /* ---- card 0x7c ---------------------------------- */
+ [BTTV_BOARD_AVDVBT_761] = {
+ /* Matt Jesson <dvb@jesson.eclipse.co.uk> */
+ /* Based on the Nebula card data - added remote and new card number - BTTV_BOARD_AVDVBT_761, see also ir-kbd-gpio.c */
+ .name = "AverMedia AverTV DVB-T 761",
+ .video_inputs = 2,
+ .tuner = -1,
+ .svhs = 1,
+ .muxsel = { 3, 1, 2, 0}, /* Comp0, S-Video, ?, ? */
+ .no_msp34xx = 1,
+ .no_tda9875 = 1,
+ .no_tda7432 = 1,
+ .pll = PLL_28,
+ .tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .has_dvb = 1,
+ .no_gpioirq = 1,
+ .has_remote = 1,
+ },
+ [BTTV_BOARD_MATRIX_VISIONSQ] = {
+ /* andre.schwarz@matrix-vision.de */
+ .name = "MATRIX Vision Sigma-SQ",
+ .video_inputs = 16,
+ .audio_inputs = 0,
+ .tuner = -1,
+ .svhs = -1,
+ .gpiomask = 0x0,
+ .muxsel = { 2, 2, 2, 2, 2, 2, 2, 2,
+ 3, 3, 3, 3, 3, 3, 3, 3 },
+ .muxsel_hook = sigmaSQ_muxsel,
+ .audiomux = { 0 },
+ .no_msp34xx = 1,
+ .pll = PLL_28,
+ .tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ },
+ [BTTV_BOARD_MATRIX_VISIONSLC] = {
+ /* andre.schwarz@matrix-vision.de */
+ .name = "MATRIX Vision Sigma-SLC",
+ .video_inputs = 4,
+ .audio_inputs = 0,
+ .tuner = -1,
+ .svhs = -1,
+ .gpiomask = 0x0,
+ .muxsel = { 2, 2, 2, 2 },
+ .muxsel_hook = sigmaSLC_muxsel,
+ .audiomux = { 0 },
+ .no_msp34xx = 1,
+ .pll = PLL_28,
+ .tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ },
+ /* BTTV_BOARD_APAC_VIEWCOMP */
+ [BTTV_BOARD_APAC_VIEWCOMP] = {
+ /* Attila Kondoros <attila.kondoros@chello.hu> */
+ /* bt878 TV + FM 0x00000000 subsystem ID */
+ .name = "APAC Viewcomp 878(AMAX)",
+ .video_inputs = 2,
+ .audio_inputs = 1,
+ .tuner = 0,
+ .svhs = -1,
+ .gpiomask = 0xFF,
+ .muxsel = { 2, 3, 1, 1},
+ .audiomux = { 2, 0, 0, 0, 10},
+ .needs_tvaudio = 0,
+ .pll = PLL_28,
+ .tuner_type = TUNER_PHILIPS_PAL,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .has_remote = 1, /* miniremote works, see ir-kbd-gpio.c */
+ .has_radio = 1, /* not every card has radio */
+ },
+
+ /* ---- card 0x80 ---------------------------------- */
+ [BTTV_BOARD_DVICO_DVBT_LITE] = {
+ /* Chris Pascoe <c.pascoe@itee.uq.edu.au> */
+ .name = "DViCO FusionHDTV DVB-T Lite",
+ .tuner = -1,
+ .no_msp34xx = 1,
+ .no_tda9875 = 1,
+ .no_tda7432 = 1,
+ .pll = PLL_28,
+ .no_video = 1,
+ .has_dvb = 1,
+ .tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ },
+ [BTTV_BOARD_VGEAR_MYVCD] = {
+ /* Steven <photon38@pchome.com.tw> */
+ .name = "V-Gear MyVCD",
+ .video_inputs = 3,
+ .audio_inputs = 1,
+ .tuner = 0,
+ .svhs = 2,
+ .gpiomask = 0x3f,
+ .muxsel = {2, 3, 1, 0},
+ .audiomux = {0x31, 0x31, 0x31, 0x31, 0x31, 0x31},
+ .no_msp34xx = 1,
+ .pll = PLL_28,
+ .tuner_type = TUNER_PHILIPS_NTSC_M,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .has_radio = 0,
+ #if 0
+ .has_remote = 1,
+ #endif
+ },
+ [BTTV_BOARD_SUPER_TV] = {
+ /* Rick C <cryptdragoon@gmail.com> */
+ .name = "Super TV Tuner",
+ .video_inputs = 4,
+ .audio_inputs = 1,
+ .tuner = 0,
+ .svhs = 2,
+ .muxsel = { 2, 3, 1, 0},
+ .tuner_type = TUNER_PHILIPS_NTSC,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .gpiomask = 0x008007,
+ .audiomux = { 0, 0x000001,0,0, 0},
+ .needs_tvaudio = 1,
+ .has_radio = 1,
+ },
+ [BTTV_BOARD_TIBET_CS16] = {
+ /* Chris Fanning <video4linux@haydon.net> */
+ .name = "Tibet Systems 'Progress DVR' CS16",
+ .video_inputs = 16,
+ .audio_inputs = 0,
+ .tuner = -1,
+ .svhs = -1,
+ .muxsel = { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
+ .pll = PLL_28,
+ .no_msp34xx = 1,
+ .no_tda9875 = 1,
+ .no_tda7432 = 1,
+ .tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .muxsel_hook = tibetCS16_muxsel,
+ },
+ [BTTV_BOARD_KODICOM_4400R] = {
+ /* Bill Brack <wbrack@mmm.com.hk> */
+ /*
+ * Note that, because of the card's wiring, the "master"
+ * BT878A chip (i.e. the one which controls the analog switch
+ * and must use this card type) is the 2nd one detected. The
+ * other 3 chips should use card type 0x85, whose description
+ * follows this one. There is a EEPROM on the card (which is
+ * connected to the I2C of one of those other chips), but is
+ * not currently handled. There is also a facility for a
+ * "monitor", which is also not currently implemented.
+ */
+ .name = "Kodicom 4400R (master)",
+ .video_inputs = 16,
+ .audio_inputs = 0,
+ .tuner = -1,
+ .tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .svhs = -1,
+ /* GPIO bits 0-9 used for analog switch:
+ * 00 - 03: camera selector
+ * 04 - 06: channel (controller) selector
+ * 07: data (1->on, 0->off)
+ * 08: strobe
+ * 09: reset
+ * bit 16 is input from sync separator for the channel
+ */
+ .gpiomask = 0x0003ff,
+ .no_gpioirq = 1,
+ .muxsel = { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 },
+ .pll = PLL_28,
+ .no_msp34xx = 1,
+ .no_tda7432 = 1,
+ .no_tda9875 = 1,
+ .muxsel_hook = kodicom4400r_muxsel,
+ },
+ [BTTV_BOARD_KODICOM_4400R_SL] = {
+ /* Bill Brack <wbrack@mmm.com.hk> */
+ /* Note that, for reasons unknown, the "master" BT878A chip (i.e. the
+ * one which controls the analog switch, and must use the card type)
+ * is the 2nd one detected. The other 3 chips should use this card
+ * type
+ */
+ .name = "Kodicom 4400R (slave)",
+ .video_inputs = 16,
+ .audio_inputs = 0,
+ .tuner = -1,
+ .tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .svhs = -1,
+ .gpiomask = 0x010000,
+ .no_gpioirq = 1,
+ .muxsel = { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 },
+ .pll = PLL_28,
+ .no_msp34xx = 1,
+ .no_tda7432 = 1,
+ .no_tda9875 = 1,
+ .muxsel_hook = kodicom4400r_muxsel,
+ },
+ /* ---- card 0x86---------------------------------- */
+ [BTTV_BOARD_ADLINK_RTV24] = {
+ /* Michael Henson <mhenson@clarityvi.com> */
+ /* Adlink RTV24 with special unlock codes */
+ .name = "Adlink RTV24",
+ .video_inputs = 4,
+ .audio_inputs = 1,
+ .tuner = 0,
+ .svhs = 2,
+ .muxsel = { 2, 3, 1, 0},
+ .tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .pll = PLL_28,
+ },
+ /* ---- card 0x87---------------------------------- */
+ [BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE] = {
+ /* Michael Krufky <mkrufky@m1k.net> */
+ .name = "DViCO FusionHDTV 5 Lite",
+ .tuner = 0,
+ .tuner_type = TUNER_LG_TDVS_H062F,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .video_inputs = 3,
+ .audio_inputs = 1,
+ .svhs = 2,
+ .muxsel = { 2, 3, 1 },
+ .gpiomask = 0x00e00007,
+ .audiomux = { 0x00400005, 0, 0x00000001, 0, 0x00c00007, 0 },
+ .no_msp34xx = 1,
+ .no_tda9875 = 1,
+ .no_tda7432 = 1,
+ .has_dvb = 1,
+ },
+ /* ---- card 0x88---------------------------------- */
+ [BTTV_BOARD_ACORP_Y878F] = {
+ /* Mauro Carvalho Chehab <mchehab@brturbo.com.br> */
+ .name = "Acorp Y878F",
+ .video_inputs = 3,
+ .audio_inputs = 1,
+ .tuner = 0,
+ .svhs = 2,
+ .gpiomask = 0x01fe00,
+ .muxsel = { 2, 3, 1, 1},
+ .audiomux = { 0x001e00, 0, 0x018000, 0x014000, 0x002000, 0 },
+ .needs_tvaudio = 1,
+ .pll = PLL_28,
+ .tuner_type = TUNER_YMEC_TVF66T5_B_DFF,
+ .tuner_addr = 0xc1 >>1,
+ .radio_addr = 0xc1 >>1,
+ .has_radio = 1,
+ },
+ /* ---- card 0x89 ---------------------------------- */
+ [BTTV_BOARD_CONCEPTRONIC_CTVFMI2] = {
+ .name = "Conceptronic CTVFMi v2",
+ .video_inputs = 3,
+ .audio_inputs = 1,
+ .tuner = 0,
+ .svhs = 2,
+ .gpiomask = 0x001c0007,
+ .muxsel = { 2, 3, 1, 1 },
+ .audiomux = { 0, 1, 2, 2, 3 },
+ .needs_tvaudio = 0,
+ .pll = PLL_28,
+ .tuner_type = TUNER_TENA_9533_DI,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .has_remote = 1,
+ .has_radio = 1,
+ },
+ /* ---- card 0x8a ---------------------------------- */
+ [BTTV_BOARD_PV_BT878P_2E] = {
+ .name = "Prolink Pixelview PV-BT878P+ (Rev.2E)",
+ .video_inputs = 5,
+ .audio_inputs = 1,
+ .tuner = 0,
+ .svhs = 3,
+ .gpiomask = 0x01fe00,
+ .muxsel = { 2,3,1,1,-1 },
+ .digital_mode = DIGITAL_MODE_CAMERA,
+ .audiomux = { 0x00400, 0x10400, 0x04400, 0x80000, 0x12400, 0x46000 },
+ .no_msp34xx = 1,
+ .pll = PLL_28,
+ .tuner_type = TUNER_LG_PAL_FM,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .has_remote = 1,
+ },
+ /* ---- card 0x8b ---------------------------------- */
+ [BTTV_BOARD_PV_M4900] = {
+ /* Sérgio Fortier <sergiofortier@yahoo.com.br> */
+ .name = "Prolink PixelView PlayTV MPEG2 PV-M4900",
+ .video_inputs = 3,
+ .audio_inputs = 1,
+ .tuner = 0,
+ .svhs = 2,
+ .gpiomask = 0x3f,
+ .muxsel = { 2, 3, 1, 1 },
+ .audiomux = { 0x21, 0x20, 0x24, 0x2c, 0x29, 0x29 },
+ .no_msp34xx = 1,
+ .pll = PLL_28,
+ .tuner_type = TUNER_YMEC_TVF_5533MF,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .has_radio = 1,
+ .has_remote = 1,
+ },
+ /* ---- card 0x8c ---------------------------------- */
+ [BTTV_BOARD_OSPREY440] = {
+ .name = "Osprey 440",
+ .video_inputs = 1,
+ .audio_inputs = 1,
+ .tuner = -1,
+ .svhs = 1,
+ .muxsel = { 2 },
+ .pll = PLL_28,
+ .tuner_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .no_msp34xx = 1,
+ .no_tda9875 = 1,
+ .no_tda7432 = 1,
+ },
+ /* ---- card 0x8d ---------------------------------- */
+ [BTTV_BOARD_ASOUND_SKYEYE] = {
+ .name = "Asound Skyeye PCTV",
+ .video_inputs = 3,
+ .audio_inputs = 1,
+ .tuner = 0,
+ .svhs = 2,
+ .gpiomask = 15,
+ .muxsel = { 2, 3, 1, 1},
+ .audiomux = {2,0,0,0,1},
+ .needs_tvaudio = 1,
+ .pll = PLL_28,
+ .tuner_type = 2,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ },
+
+};
static const unsigned int bttv_num_tvcards = ARRAY_SIZE(bttv_tvcards);
@@ -2461,7 +2840,7 @@ void __devinit bttv_idcard(struct bttv *btv)
btv->c.nr, btv->cardid & 0xffff,
(btv->cardid >> 16) & 0xffff);
printk(KERN_DEBUG "please mail id, board name and "
- "the correct card= insmod option to kraxel@bytesex.org\n");
+ "the correct card= insmod option to video4linux-list@redhat.com\n");
}
}
@@ -2510,11 +2889,11 @@ void identify_by_eeprom(struct bttv *btv, unsigned char eeprom_data[256])
int type = -1;
if (0 == strncmp(eeprom_data,"GET MM20xPCTV",13))
- type = BTTV_MODTEC_205;
+ type = BTTV_BOARD_MODTEC_205;
else if (0 == strncmp(eeprom_data+20,"Picolo",7))
- type = BTTV_EURESYS_PICOLO;
+ type = BTTV_BOARD_EURESYS_PICOLO;
else if (eeprom_data[0] == 0x84 && eeprom_data[2]== 0)
- type = BTTV_HAUPPAUGE; /* old bt848 */
+ type = BTTV_BOARD_HAUPPAUGE; /* old bt848 */
if (-1 != type) {
btv->c.type = type;
@@ -2548,7 +2927,7 @@ static void flyvideo_gpio(struct bttv *btv)
switch(ttype) {
case 0x0: tuner=2; /* NTSC, e.g. TPI8NSR11P */
break;
- case 0x2: tuner=39;/* LG NTSC (newer TAPC series) TAPC-H701P */
+ case 0x2: tuner=39;/* LG NTSC (newer TAPC series) TAPC-H701P */
break;
case 0x4: tuner=5; /* Philips PAL TPI8PSB02P, TPI8PSB12P, TPI8PSB12D or FI1216, FM1216 */
break;
@@ -2564,7 +2943,7 @@ static void flyvideo_gpio(struct bttv *btv)
has_radio = gpio & 0x400000;
/* unknown 0x200000;
* unknown2 0x100000; */
- is_capture_only = !(gpio & 0x008000); /* GPIO15 */
+ is_capture_only = !(gpio & 0x008000); /* GPIO15 */
has_tda9820_tda9821 = !(gpio & 0x004000);
is_lr90 = !(gpio & 0x002000); /* else LR26/LR50 (LR38/LR51 f. capture only) */
/*
@@ -2601,7 +2980,7 @@ static void miro_pinnacle_gpio(struct bttv *btv)
char *info;
gpio_inout(0xffffff, 0);
- gpio = gpio_read();
+ gpio = gpio_read();
id = ((gpio>>10) & 63) -1;
msp = bttv_I2CRead(btv, I2C_MSP3400, "MSP34xx");
if (id < 32) {
@@ -2620,10 +2999,10 @@ static void miro_pinnacle_gpio(struct bttv *btv)
btv->has_radio = 0;
}
if (-1 != msp) {
- if (btv->c.type == BTTV_MIRO)
- btv->c.type = BTTV_MIROPRO;
- if (btv->c.type == BTTV_PINNACLE)
- btv->c.type = BTTV_PINNACLEPRO;
+ if (btv->c.type == BTTV_BOARD_MIRO)
+ btv->c.type = BTTV_BOARD_MIROPRO;
+ if (btv->c.type == BTTV_BOARD_PINNACLE)
+ btv->c.type = BTTV_BOARD_PINNACLEPRO;
}
printk(KERN_INFO
"bttv%d: miro: id=%d tuner=%d radio=%s stereo=%s\n",
@@ -2664,7 +3043,7 @@ static void miro_pinnacle_gpio(struct bttv *btv)
break;
}
if (-1 != msp)
- btv->c.type = BTTV_PINNACLEPRO;
+ btv->c.type = BTTV_BOARD_PINNACLEPRO;
printk(KERN_INFO
"bttv%d: pinnacle/mt: id=%d info=\"%s\" radio=%s\n",
btv->c.nr, id, info, btv->has_radio ? "yes" : "no");
@@ -2712,7 +3091,7 @@ static void eagle_muxsel(struct bttv *btv, unsigned int input)
static void gvc1100_muxsel(struct bttv *btv, unsigned int input)
{
- static const int masks[] = {0x30, 0x01, 0x12, 0x23};
+ static const int masks[] = {0x30, 0x01, 0x12, 0x23};
gpio_write(masks[input%4]);
}
@@ -2778,26 +3157,27 @@ static void bttv_reset_audio(struct bttv *btv)
void __devinit bttv_init_card1(struct bttv *btv)
{
switch (btv->c.type) {
- case BTTV_HAUPPAUGE:
- case BTTV_HAUPPAUGE878:
- boot_msp34xx(btv,5);
+ case BTTV_BOARD_HAUPPAUGE:
+ case BTTV_BOARD_HAUPPAUGE878:
+ boot_msp34xx(btv,5);
break;
- case BTTV_VOODOOTV_FM:
- boot_msp34xx(btv,20);
+ case BTTV_BOARD_VOODOOTV_FM:
+ boot_msp34xx(btv,20);
break;
- case BTTV_AVERMEDIA98:
+ case BTTV_BOARD_AVERMEDIA98:
boot_msp34xx(btv,11);
break;
- case BTTV_HAUPPAUGEPVR:
+ case BTTV_BOARD_HAUPPAUGEPVR:
pvr_boot(btv);
break;
- case BTTV_TWINHAN_DST:
- case BTTV_AVDVBT_771:
+ case BTTV_BOARD_TWINHAN_DST:
+ case BTTV_BOARD_AVDVBT_771:
+ case BTTV_BOARD_PINNACLESAT:
btv->use_i2c_hw = 1;
break;
- case BTTV_ADLINK_RTV24:
- init_RTV24( btv );
- break;
+ case BTTV_BOARD_ADLINK_RTV24:
+ init_RTV24( btv );
+ break;
}
if (!bttv_tvcards[btv->c.type].has_dvb)
@@ -2810,53 +3190,53 @@ void __devinit bttv_init_card2(struct bttv *btv)
int tda9887;
int addr=ADDR_UNSET;
- btv->tuner_type = -1;
+ btv->tuner_type = -1;
- if (BTTV_UNKNOWN == btv->c.type) {
+ if (BTTV_BOARD_UNKNOWN == btv->c.type) {
bttv_readee(btv,eeprom_data,0xa0);
identify_by_eeprom(btv,eeprom_data);
}
switch (btv->c.type) {
- case BTTV_MIRO:
- case BTTV_MIROPRO:
- case BTTV_PINNACLE:
- case BTTV_PINNACLEPRO:
+ case BTTV_BOARD_MIRO:
+ case BTTV_BOARD_MIROPRO:
+ case BTTV_BOARD_PINNACLE:
+ case BTTV_BOARD_PINNACLEPRO:
/* miro/pinnacle */
miro_pinnacle_gpio(btv);
break;
- case BTTV_FLYVIDEO_98:
- case BTTV_MAXI:
- case BTTV_LIFE_FLYKIT:
- case BTTV_FLYVIDEO:
- case BTTV_TYPHOON_TVIEW:
- case BTTV_CHRONOS_VS2:
- case BTTV_FLYVIDEO_98FM:
- case BTTV_FLYVIDEO2000:
- case BTTV_FLYVIDEO98EZ:
- case BTTV_CONFERENCETV:
- case BTTV_LIFETEC_9415:
+ case BTTV_BOARD_FLYVIDEO_98:
+ case BTTV_BOARD_MAXI:
+ case BTTV_BOARD_LIFE_FLYKIT:
+ case BTTV_BOARD_FLYVIDEO:
+ case BTTV_BOARD_TYPHOON_TVIEW:
+ case BTTV_BOARD_CHRONOS_VS2:
+ case BTTV_BOARD_FLYVIDEO_98FM:
+ case BTTV_BOARD_FLYVIDEO2000:
+ case BTTV_BOARD_FLYVIDEO98EZ:
+ case BTTV_BOARD_CONFERENCETV:
+ case BTTV_BOARD_LIFETEC_9415:
flyvideo_gpio(btv);
break;
- case BTTV_HAUPPAUGE:
- case BTTV_HAUPPAUGE878:
- case BTTV_HAUPPAUGEPVR:
+ case BTTV_BOARD_HAUPPAUGE:
+ case BTTV_BOARD_HAUPPAUGE878:
+ case BTTV_BOARD_HAUPPAUGEPVR:
/* pick up some config infos from the eeprom */
bttv_readee(btv,eeprom_data,0xa0);
- hauppauge_eeprom(btv);
+ hauppauge_eeprom(btv);
break;
- case BTTV_AVERMEDIA98:
- case BTTV_AVPHONE98:
+ case BTTV_BOARD_AVERMEDIA98:
+ case BTTV_BOARD_AVPHONE98:
bttv_readee(btv,eeprom_data,0xa0);
avermedia_eeprom(btv);
break;
- case BTTV_PXC200:
+ case BTTV_BOARD_PXC200:
init_PXC200(btv);
break;
- case BTTV_PICOLO_TETRA_CHIP:
+ case BTTV_BOARD_PICOLO_TETRA_CHIP:
picolo_tetra_init(btv);
break;
- case BTTV_VHX:
+ case BTTV_BOARD_VHX:
btv->has_radio = 1;
btv->has_matchbox = 1;
btv->mbox_we = 0x20;
@@ -2865,58 +3245,58 @@ void __devinit bttv_init_card2(struct bttv *btv)
btv->mbox_data = 0x10;
btv->mbox_mask = 0x38;
break;
- case BTTV_VOBIS_BOOSTAR:
- case BTTV_TERRATV:
+ case BTTV_BOARD_VOBIS_BOOSTAR:
+ case BTTV_BOARD_TERRATV:
terratec_active_radio_upgrade(btv);
break;
- case BTTV_MAGICTVIEW061:
+ case BTTV_BOARD_MAGICTVIEW061:
if (btv->cardid == 0x3002144f) {
btv->has_radio=1;
printk("bttv%d: radio detected by subsystem id (CPH05x)\n",btv->c.nr);
}
break;
- case BTTV_STB2:
- if (btv->cardid == 0x3060121a) {
+ case BTTV_BOARD_STB2:
+ if (btv->cardid == 0x3060121a) {
/* Fix up entry for 3DFX VoodooTV 100,
which is an OEM STB card variant. */
btv->has_radio=0;
btv->tuner_type=TUNER_TEMIC_NTSC;
}
break;
- case BTTV_OSPREY1x0:
- case BTTV_OSPREY1x0_848:
- case BTTV_OSPREY101_848:
- case BTTV_OSPREY1x1:
- case BTTV_OSPREY1x1_SVID:
- case BTTV_OSPREY2xx:
- case BTTV_OSPREY2x0_SVID:
- case BTTV_OSPREY2x0:
- case BTTV_OSPREY500:
- case BTTV_OSPREY540:
- case BTTV_OSPREY2000:
+ case BTTV_BOARD_OSPREY1x0:
+ case BTTV_BOARD_OSPREY1x0_848:
+ case BTTV_BOARD_OSPREY101_848:
+ case BTTV_BOARD_OSPREY1x1:
+ case BTTV_BOARD_OSPREY1x1_SVID:
+ case BTTV_BOARD_OSPREY2xx:
+ case BTTV_BOARD_OSPREY2x0_SVID:
+ case BTTV_BOARD_OSPREY2x0:
+ case BTTV_BOARD_OSPREY500:
+ case BTTV_BOARD_OSPREY540:
+ case BTTV_BOARD_OSPREY2000:
bttv_readee(btv,eeprom_data,0xa0);
- osprey_eeprom(btv);
+ osprey_eeprom(btv);
break;
- case BTTV_IDS_EAGLE:
+ case BTTV_BOARD_IDS_EAGLE:
init_ids_eagle(btv);
break;
- case BTTV_MODTEC_205:
+ case BTTV_BOARD_MODTEC_205:
bttv_readee(btv,eeprom_data,0xa0);
modtec_eeprom(btv);
break;
- case BTTV_LMLBT4:
+ case BTTV_BOARD_LMLBT4:
init_lmlbt4x(btv);
break;
- case BTTV_TIBET_CS16:
+ case BTTV_BOARD_TIBET_CS16:
tibetCS16_init(btv);
break;
- case BTTV_KODICOM_4400R:
+ case BTTV_BOARD_KODICOM_4400R:
kodicom4400r_init(btv);
break;
}
/* pll configuration */
- if (!(btv->id==848 && btv->revision==0x11)) {
+ if (!(btv->id==848 && btv->revision==0x11)) {
/* defaults from card list */
if (PLL_28 == bttv_tvcards[btv->c.type].pll) {
btv->pll.pll_ifreq=28636363;
@@ -2927,26 +3307,26 @@ void __devinit bttv_init_card2(struct bttv *btv)
btv->pll.pll_crystal=BT848_IFORM_XT1;
}
/* insmod options can override */
- switch (pll[btv->c.nr]) {
- case 0: /* none */
+ switch (pll[btv->c.nr]) {
+ case 0: /* none */
btv->pll.pll_crystal = 0;
btv->pll.pll_ifreq = 0;
btv->pll.pll_ofreq = 0;
- break;
- case 1: /* 28 MHz */
+ break;
+ case 1: /* 28 MHz */
case 28:
- btv->pll.pll_ifreq = 28636363;
+ btv->pll.pll_ifreq = 28636363;
btv->pll.pll_ofreq = 0;
- btv->pll.pll_crystal = BT848_IFORM_XT0;
- break;
- case 2: /* 35 MHz */
+ btv->pll.pll_crystal = BT848_IFORM_XT0;
+ break;
+ case 2: /* 35 MHz */
case 35:
- btv->pll.pll_ifreq = 35468950;
+ btv->pll.pll_ifreq = 35468950;
btv->pll.pll_ofreq = 0;
- btv->pll.pll_crystal = BT848_IFORM_XT1;
- break;
- }
- }
+ btv->pll.pll_crystal = BT848_IFORM_XT1;
+ break;
+ }
+ }
btv->pll.pll_current = -1;
/* tuner configuration (from card list / autodetect / insmod option) */
@@ -2955,23 +3335,26 @@ void __devinit bttv_init_card2(struct bttv *btv)
if (UNSET != bttv_tvcards[btv->c.type].tuner_type)
if(UNSET == btv->tuner_type)
- btv->tuner_type = bttv_tvcards[btv->c.type].tuner_type;
+ btv->tuner_type = bttv_tvcards[btv->c.type].tuner_type;
if (UNSET != tuner[btv->c.nr])
btv->tuner_type = tuner[btv->c.nr];
printk("bttv%d: using tuner=%d\n",btv->c.nr,btv->tuner_type);
- if (btv->pinnacle_id != UNSET)
- bttv_call_i2c_clients(btv, AUDC_CONFIG_PINNACLE,
- &btv->pinnacle_id);
+
if (btv->tuner_type != UNSET) {
- struct tuner_setup tun_setup;
+ struct tuner_setup tun_setup;
- tun_setup.mode_mask = T_RADIO | T_ANALOG_TV | T_DIGITAL_TV;
+ tun_setup.mode_mask = T_ANALOG_TV | T_DIGITAL_TV;
tun_setup.type = btv->tuner_type;
tun_setup.addr = addr;
bttv_call_i2c_clients(btv, TUNER_SET_TYPE_ADDR, &tun_setup);
}
+ if (btv->pinnacle_id != UNSET) {
+ bttv_call_i2c_clients(btv, AUDC_CONFIG_PINNACLE,
+ &btv->pinnacle_id);
+ }
+
btv->svhs = bttv_tvcards[btv->c.type].svhs;
if (svhs[btv->c.nr] != UNSET)
btv->svhs = svhs[btv->c.nr];
@@ -2982,8 +3365,8 @@ void __devinit bttv_init_card2(struct bttv *btv)
btv->has_radio=1;
if (bttv_tvcards[btv->c.type].has_remote)
btv->has_remote=1;
- if (bttv_tvcards[btv->c.type].no_gpioirq)
- btv->gpioirq=0;
+ if (!bttv_tvcards[btv->c.type].no_gpioirq)
+ btv->gpioirq=1;
if (bttv_tvcards[btv->c.type].audio_hook)
btv->audio_hook=bttv_tvcards[btv->c.type].audio_hook;
@@ -3024,6 +3407,9 @@ void __devinit bttv_init_card2(struct bttv *btv)
if (0 == tda9887 && 0 == bttv_tvcards[btv->c.type].has_dvb &&
bttv_I2CRead(btv, I2C_TDA9887, "TDA9887") >=0)
tda9887 = 1;
+ /* Hybrid DVB card, DOES have a tda9887 */
+ if (btv->c.type == BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE)
+ tda9887 = 1;
if((btv->tuner_type == TUNER_PHILIPS_FM1216ME_MK3) ||
(btv->tuner_type == TUNER_PHILIPS_FM1236_MK3) ||
(btv->tuner_type == TUNER_PHILIPS_FM1256_IH3) ||
@@ -3045,11 +3431,11 @@ static void modtec_eeprom(struct bttv *btv)
} else if (strncmp(&(eeprom_data[0x1e]),"Alps TSBB5",10) ==0) {
btv->tuner_type=TUNER_ALPS_TSBB5_PAL_I;
printk("bttv%d: Modtec: Tuner autodetected by eeprom: %s\n",
- btv->c.nr,&eeprom_data[0x1e]);
- } else if (strncmp(&(eeprom_data[0x1e]),"Philips FM1246",14) ==0) {
- btv->tuner_type=TUNER_PHILIPS_NTSC;
- printk("bttv%d: Modtec: Tuner autodetected by eeprom: %s\n",
- btv->c.nr,&eeprom_data[0x1e]);
+ btv->c.nr,&eeprom_data[0x1e]);
+ } else if (strncmp(&(eeprom_data[0x1e]),"Philips FM1246",14) ==0) {
+ btv->tuner_type=TUNER_PHILIPS_NTSC;
+ printk("bttv%d: Modtec: Tuner autodetected by eeprom: %s\n",
+ btv->c.nr,&eeprom_data[0x1e]);
} else {
printk("bttv%d: Modtec: Unknown TunerString: %s\n",
btv->c.nr,&eeprom_data[0x1e]);
@@ -3114,7 +3500,7 @@ static int terratec_active_radio_upgrade(struct bttv *btv)
static int __devinit pvr_altera_load(struct bttv *btv, u8 *micro, u32 microlen)
{
u32 n;
- u8 bits;
+ u8 bits;
int i;
gpio_inout(0xffffff,BTTV_ALT_DATA|BTTV_ALT_DCLK|BTTV_ALT_NCONFIG);
@@ -3150,19 +3536,19 @@ static int __devinit pvr_altera_load(struct bttv *btv, u8 *micro, u32 microlen)
static int __devinit pvr_boot(struct bttv *btv)
{
- const struct firmware *fw_entry;
+ const struct firmware *fw_entry;
int rc;
rc = request_firmware(&fw_entry, "hcwamc.rbf", &btv->c.pci->dev);
if (rc != 0) {
printk(KERN_WARNING "bttv%d: no altera firmware [via hotplug]\n",
btv->c.nr);
- return rc;
- }
+ return rc;
+ }
rc = pvr_altera_load(btv, fw_entry->data, fw_entry->size);
printk(KERN_INFO "bttv%d: altera firmware upload %s\n",
btv->c.nr, (rc < 0) ? "failed" : "ok");
- release_firmware(fw_entry);
+ release_firmware(fw_entry);
return rc;
}
@@ -3176,33 +3562,33 @@ static void __devinit osprey_eeprom(struct bttv *btv)
unsigned long serial = 0;
if (btv->c.type == 0) {
- /* this might be an antique... check for MMAC label in eeprom */
- if ((ee[0]=='M') && (ee[1]=='M') && (ee[2]=='A') && (ee[3]=='C')) {
- unsigned char checksum = 0;
- for (i =0; i<21; i++)
+ /* this might be an antique... check for MMAC label in eeprom */
+ if ((ee[0]=='M') && (ee[1]=='M') && (ee[2]=='A') && (ee[3]=='C')) {
+ unsigned char checksum = 0;
+ for (i =0; i<21; i++)
checksum += ee[i];
- if (checksum != ee[21])
+ if (checksum != ee[21])
return;
- btv->c.type = BTTV_OSPREY1x0_848;
+ btv->c.type = BTTV_BOARD_OSPREY1x0_848;
for (i = 12; i < 21; i++)
serial *= 10, serial += ee[i] - '0';
- }
+ }
} else {
unsigned short type;
- int offset = 4*16;
-
- for(; offset < 8*16; offset += 16) {
- unsigned short checksum = 0;
- /* verify the checksum */
- for(i = 0; i<14; i++) checksum += ee[i+offset];
- checksum = ~checksum; /* no idea why */
- if ((((checksum>>8)&0x0FF) == ee[offset+14]) &&
- ((checksum & 0x0FF) == ee[offset+15])) {
- break;
- }
- }
-
- if (offset >= 8*16)
+ int offset = 4*16;
+
+ for(; offset < 8*16; offset += 16) {
+ unsigned short checksum = 0;
+ /* verify the checksum */
+ for(i = 0; i<14; i++) checksum += ee[i+offset];
+ checksum = ~checksum; /* no idea why */
+ if ((((checksum>>8)&0x0FF) == ee[offset+14]) &&
+ ((checksum & 0x0FF) == ee[offset+15])) {
+ break;
+ }
+ }
+
+ if (offset >= 8*16)
return;
/* found a valid descriptor */
@@ -3212,47 +3598,47 @@ static void __devinit osprey_eeprom(struct bttv *btv)
/* 848 based */
case 0x0004:
- btv->c.type = BTTV_OSPREY1x0_848;
+ btv->c.type = BTTV_BOARD_OSPREY1x0_848;
break;
case 0x0005:
- btv->c.type = BTTV_OSPREY101_848;
+ btv->c.type = BTTV_BOARD_OSPREY101_848;
break;
- /* 878 based */
+ /* 878 based */
case 0x0012:
case 0x0013:
- btv->c.type = BTTV_OSPREY1x0;
+ btv->c.type = BTTV_BOARD_OSPREY1x0;
break;
case 0x0014:
case 0x0015:
- btv->c.type = BTTV_OSPREY1x1;
+ btv->c.type = BTTV_BOARD_OSPREY1x1;
break;
case 0x0016:
case 0x0017:
case 0x0020:
- btv->c.type = BTTV_OSPREY1x1_SVID;
+ btv->c.type = BTTV_BOARD_OSPREY1x1_SVID;
break;
case 0x0018:
case 0x0019:
case 0x001E:
case 0x001F:
- btv->c.type = BTTV_OSPREY2xx;
+ btv->c.type = BTTV_BOARD_OSPREY2xx;
break;
case 0x001A:
case 0x001B:
- btv->c.type = BTTV_OSPREY2x0_SVID;
+ btv->c.type = BTTV_BOARD_OSPREY2x0_SVID;
break;
case 0x0040:
- btv->c.type = BTTV_OSPREY500;
+ btv->c.type = BTTV_BOARD_OSPREY500;
break;
case 0x0050:
case 0x0056:
- btv->c.type = BTTV_OSPREY540;
+ btv->c.type = BTTV_BOARD_OSPREY540;
/* bttv_osprey_540_init(btv); */
break;
case 0x0060:
case 0x0070:
- btv->c.type = BTTV_OSPREY2x0;
+ btv->c.type = BTTV_BOARD_OSPREY2x0;
/* enable output on select control lines */
gpio_inout(0xffffff,0x000303);
break;
@@ -3274,27 +3660,27 @@ static void __devinit osprey_eeprom(struct bttv *btv)
/* AVermedia specific stuff, from bktr_card.c */
static int tuner_0_table[] = {
- TUNER_PHILIPS_NTSC, TUNER_PHILIPS_PAL /* PAL-BG*/,
- TUNER_PHILIPS_PAL, TUNER_PHILIPS_PAL /* PAL-I*/,
- TUNER_PHILIPS_PAL, TUNER_PHILIPS_PAL,
- TUNER_PHILIPS_SECAM, TUNER_PHILIPS_SECAM,
- TUNER_PHILIPS_SECAM, TUNER_PHILIPS_PAL,
+ TUNER_PHILIPS_NTSC, TUNER_PHILIPS_PAL /* PAL-BG*/,
+ TUNER_PHILIPS_PAL, TUNER_PHILIPS_PAL /* PAL-I*/,
+ TUNER_PHILIPS_PAL, TUNER_PHILIPS_PAL,
+ TUNER_PHILIPS_SECAM, TUNER_PHILIPS_SECAM,
+ TUNER_PHILIPS_SECAM, TUNER_PHILIPS_PAL,
TUNER_PHILIPS_FM1216ME_MK3 };
static int tuner_1_table[] = {
- TUNER_TEMIC_NTSC, TUNER_TEMIC_PAL,
+ TUNER_TEMIC_NTSC, TUNER_TEMIC_PAL,
TUNER_TEMIC_PAL, TUNER_TEMIC_PAL,
TUNER_TEMIC_PAL, TUNER_TEMIC_PAL,
- TUNER_TEMIC_4012FY5, TUNER_TEMIC_4012FY5, /* TUNER_TEMIC_SECAM */
- TUNER_TEMIC_4012FY5, TUNER_TEMIC_PAL};
+ TUNER_TEMIC_4012FY5, TUNER_TEMIC_4012FY5, /* TUNER_TEMIC_SECAM */
+ TUNER_TEMIC_4012FY5, TUNER_TEMIC_PAL};
static void __devinit avermedia_eeprom(struct bttv *btv)
{
- int tuner_make,tuner_tv_fm,tuner_format,tuner=0;
+ int tuner_make,tuner_tv_fm,tuner_format,tuner=0;
tuner_make = (eeprom_data[0x41] & 0x7);
- tuner_tv_fm = (eeprom_data[0x41] & 0x18) >> 3;
- tuner_format = (eeprom_data[0x42] & 0xf0) >> 4;
+ tuner_tv_fm = (eeprom_data[0x41] & 0x18) >> 3;
+ tuner_format = (eeprom_data[0x42] & 0xf0) >> 4;
btv->has_remote = (eeprom_data[0x42] & 0x01);
if (tuner_make == 0 || tuner_make == 2)
@@ -3325,13 +3711,13 @@ void bttv_tda9880_setnorm(struct bttv *btv, int norm)
{
/* fix up our card entry */
if(norm==VIDEO_MODE_NTSC) {
- bttv_tvcards[BTTV_VOODOOTV_FM].audiomux[0]=0x957fff;
- bttv_tvcards[BTTV_VOODOOTV_FM].audiomux[4]=0x957fff;
+ bttv_tvcards[BTTV_BOARD_VOODOOTV_FM].audiomux[0]=0x957fff;
+ bttv_tvcards[BTTV_BOARD_VOODOOTV_FM].audiomux[4]=0x957fff;
dprintk("bttv_tda9880_setnorm to NTSC\n");
}
else {
- bttv_tvcards[BTTV_VOODOOTV_FM].audiomux[0]=0x947fff;
- bttv_tvcards[BTTV_VOODOOTV_FM].audiomux[4]=0x947fff;
+ bttv_tvcards[BTTV_BOARD_VOODOOTV_FM].audiomux[0]=0x947fff;
+ bttv_tvcards[BTTV_BOARD_VOODOOTV_FM].audiomux[4]=0x947fff;
dprintk("bttv_tda9880_setnorm to PAL\n");
}
/* set GPIO according */
@@ -3342,7 +3728,7 @@ void bttv_tda9880_setnorm(struct bttv *btv, int norm)
/*
* reset/enable the MSP on some Hauppauge cards
- * Thanks to Kyösti Mälkki (kmalkki@cc.hut.fi)!
+ * Thanks to Kyösti Mälkki (kmalkki@cc.hut.fi)!
*
* Hauppauge: pin 5
* Voodoo: pin 20
@@ -3353,7 +3739,7 @@ static void __devinit boot_msp34xx(struct bttv *btv, int pin)
gpio_inout(mask,mask);
gpio_bits(mask,0);
- udelay(2500);
+ udelay(2500);
gpio_bits(mask,mask);
if (bttv_gpio)
@@ -3429,7 +3815,7 @@ static void __devinit init_PXC200(struct bttv *btv)
udelay(10);
gpio_write(1<<2);
- for (i = 0; i < ARRAY_SIZE(vals); i++) {
+ for (i = 0; i < ARRAY_SIZE(vals); i++) {
tmp=bttv_I2CWrite(btv,0x1E,0,vals[i],1);
if (tmp != -1) {
printk(KERN_INFO
@@ -3872,30 +4258,30 @@ avermedia_tv_stereo_audio(struct bttv *btv, struct video_audio *v, int set)
static void
lt9415_audio(struct bttv *btv, struct video_audio *v, int set)
{
- int val = 0;
+ int val = 0;
- if (gpio_read() & 0x4000) {
+ if (gpio_read() & 0x4000) {
v->mode = VIDEO_SOUND_MONO;
return;
}
- if (set) {
- if (v->mode & VIDEO_SOUND_LANG2) /* A2 SAP */
- val = 0x0080;
+ if (set) {
+ if (v->mode & VIDEO_SOUND_LANG2) /* A2 SAP */
+ val = 0x0080;
if (v->mode & VIDEO_SOUND_STEREO) /* A2 stereo */
- val = 0x0880;
- if ((v->mode & VIDEO_SOUND_LANG1) ||
+ val = 0x0880;
+ if ((v->mode & VIDEO_SOUND_LANG1) ||
(v->mode & VIDEO_SOUND_MONO))
val = 0;
gpio_bits(0x0880, val);
- if (bttv_gpio)
- bttv_gpio_tracking(btv,"lt9415");
- } else {
+ if (bttv_gpio)
+ bttv_gpio_tracking(btv,"lt9415");
+ } else {
/* autodetect doesn't work with this card :-( */
- v->mode = VIDEO_SOUND_MONO | VIDEO_SOUND_STEREO |
+ v->mode = VIDEO_SOUND_MONO | VIDEO_SOUND_STEREO |
VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;
- return;
- }
+ return;
+ }
}
/* TDA9821 on TerraTV+ Bt848, Bt878 */
@@ -4018,26 +4404,26 @@ fv2000s_audio(struct bttv *btv, struct video_audio *v, int set)
static void
windvr_audio(struct bttv *btv, struct video_audio *v, int set)
{
- unsigned long val = 0;
-
- if (set) {
- if (v->mode & VIDEO_SOUND_MONO)
- val = 0x040000;
- if (v->mode & VIDEO_SOUND_LANG1)
- val = 0;
- if (v->mode & VIDEO_SOUND_LANG2)
- val = 0x100000;
- if (v->mode & VIDEO_SOUND_STEREO)
- val = 0;
- if (val) {
+ unsigned long val = 0;
+
+ if (set) {
+ if (v->mode & VIDEO_SOUND_MONO)
+ val = 0x040000;
+ if (v->mode & VIDEO_SOUND_LANG1)
+ val = 0;
+ if (v->mode & VIDEO_SOUND_LANG2)
+ val = 0x100000;
+ if (v->mode & VIDEO_SOUND_STEREO)
+ val = 0;
+ if (val) {
gpio_bits(0x140000, val);
- if (bttv_gpio)
- bttv_gpio_tracking(btv,"windvr");
- }
- } else {
- v->mode = VIDEO_SOUND_MONO | VIDEO_SOUND_STEREO |
- VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;
- }
+ if (bttv_gpio)
+ bttv_gpio_tracking(btv,"windvr");
+ }
+ } else {
+ v->mode = VIDEO_SOUND_MONO | VIDEO_SOUND_STEREO |
+ VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;
+ }
}
/*
@@ -4280,10 +4666,10 @@ static void kodicom4400r_init(struct bttv *btv)
static void xguard_muxsel(struct bttv *btv, unsigned int input)
{
static const int masks[] = {
- ENB0, ENB0|IN00, ENB0|IN10, ENB0|IN00|IN10,
- ENA0, ENA0|IN00, ENA0|IN10, ENA0|IN00|IN10,
- ENB1, ENB1|IN01, ENB1|IN11, ENB1|IN01|IN11,
- ENA1, ENA1|IN01, ENA1|IN11, ENA1|IN01|IN11,
+ ENB0, ENB0|IN00, ENB0|IN10, ENB0|IN00|IN10,
+ ENA0, ENA0|IN00, ENA0|IN10, ENA0|IN00|IN10,
+ ENB1, ENB1|IN01, ENB1|IN11, ENB1|IN01|IN11,
+ ENA1, ENA1|IN01, ENA1|IN11, ENA1|IN01|IN11,
};
gpio_write(masks[input%16]);
}
@@ -4388,10 +4774,10 @@ static void ivc120_muxsel(struct bttv *btv, unsigned int input)
static void PXC200_muxsel(struct bttv *btv, unsigned int input)
{
- int rc;
+ int rc;
long mux;
int bitmask;
- unsigned char buf[2];
+ unsigned char buf[2];
/* Read PIC config to determine if this is a PXC200F */
/* PX_I2C_CMD_CFG*/
@@ -4421,14 +4807,14 @@ static void PXC200_muxsel(struct bttv *btv, unsigned int input)
/* bitmask=0x30f; */
bitmask=0x302;
/* check whether we have a PXC200A */
- if (btv->cardid == PX_PXC200A_CARDID) {
+ if (btv->cardid == PX_PXC200A_CARDID) {
bitmask ^= 0x180; /* use 7 and 9, not 8 and 9 */
bitmask |= 7<<4; /* the DAC */
}
btwrite(bitmask, BT848_GPIO_OUT_EN);
bitmask = btread(BT848_GPIO_DATA);
- if (btv->cardid == PX_PXC200A_CARDID)
+ if (btv->cardid == PX_PXC200A_CARDID)
bitmask = (bitmask & ~0x280) | ((mux & 2) << 8) | ((mux & 1) << 7);
else /* older device */
bitmask = (bitmask & ~0x300) | ((mux & 3) << 8);
@@ -4441,7 +4827,7 @@ static void PXC200_muxsel(struct bttv *btv, unsigned int input)
*
* needed because bttv-driver sets mux before calling this function
*/
- if (btv->cardid == PX_PXC200A_CARDID)
+ if (btv->cardid == PX_PXC200A_CARDID)
btaor(2<<5, ~BT848_IFORM_MUXSEL, BT848_IFORM);
else /* older device */
btand(~BT848_IFORM_MUXSEL,BT848_IFORM);
@@ -4485,10 +4871,9 @@ void __devinit bttv_check_chipset(void)
}
if (UNSET != latency)
printk(KERN_INFO "bttv: pci latency fixup [%d]\n",latency);
-
- while ((dev = pci_find_device(PCI_VENDOR_ID_INTEL,
+ while ((dev = pci_get_device(PCI_VENDOR_ID_INTEL,
PCI_DEVICE_ID_INTEL_82441, dev))) {
- unsigned char b;
+ unsigned char b;
pci_read_config_byte(dev, 0x53, &b);
if (bttv_debug)
printk(KERN_INFO "bttv: Host bridge: 82441FX Natoma, "
@@ -4498,7 +4883,7 @@ void __devinit bttv_check_chipset(void)
int __devinit bttv_handle_chipset(struct bttv *btv)
{
- unsigned char command;
+ unsigned char command;
if (!triton1 && !vsfx && UNSET == latency)
return 0;
@@ -4519,13 +4904,13 @@ int __devinit bttv_handle_chipset(struct bttv *btv)
btv->triton1 = BT848_INT_ETBF;
} else {
/* bt878 has a bit in the pci config space for it */
- pci_read_config_byte(btv->c.pci, BT878_DEVCTRL, &command);
+ pci_read_config_byte(btv->c.pci, BT878_DEVCTRL, &command);
if (triton1)
command |= BT878_EN_TBFX;
if (vsfx)
command |= BT878_EN_VSFX;
- pci_write_config_byte(btv->c.pci, BT878_DEVCTRL, command);
- }
+ pci_write_config_byte(btv->c.pci, BT878_DEVCTRL, command);
+ }
if (UNSET != latency)
pci_write_config_byte(btv->c.pci, PCI_LATENCY_TIMER, latency);
return 0;
diff --git a/drivers/media/video/bttv-driver.c b/drivers/media/video/bttv-driver.c
index c062a017491e..0005741d5514 100644
--- a/drivers/media/video/bttv-driver.c
+++ b/drivers/media/video/bttv-driver.c
@@ -3,7 +3,7 @@
bttv - Bt848 frame grabber driver
Copyright (C) 1996,97,98 Ralph Metzler <rjkm@thp.uni-koeln.de>
- & Marcus Metzler <mocm@thp.uni-koeln.de>
+ & Marcus Metzler <mocm@thp.uni-koeln.de>
(c) 1999-2002 Gerd Knorr <kraxel@bytesex.org>
some v4l2 code lines are taken from Justin's bttv2 driver which is
@@ -192,8 +192,8 @@ static u8 SRAM_Table[][60] =
const struct bttv_tvnorm bttv_tvnorms[] = {
/* PAL-BDGHI */
- /* max. active video is actually 922, but 924 is divisible by 4 and 3! */
- /* actually, max active PAL with HSCALE=0 is 948, NTSC is 768 - nil */
+ /* max. active video is actually 922, but 924 is divisible by 4 and 3! */
+ /* actually, max active PAL with HSCALE=0 is 948, NTSC is 768 - nil */
{
.v4l2_id = V4L2_STD_PAL,
.name = "PAL",
@@ -806,9 +806,9 @@ static void bt848A_set_timing(struct bttv *btv)
btv->c.nr,table_idx);
/* timing change...reset timing generator address */
- btwrite(0x00, BT848_TGCTRL);
- btwrite(0x02, BT848_TGCTRL);
- btwrite(0x00, BT848_TGCTRL);
+ btwrite(0x00, BT848_TGCTRL);
+ btwrite(0x02, BT848_TGCTRL);
+ btwrite(0x00, BT848_TGCTRL);
len=SRAM_Table[table_idx][0];
for(i = 1; i <= len; i++)
@@ -847,7 +847,7 @@ static void bt848_hue(struct bttv *btv, int hue)
/* -128 to 127 */
value = (hue >> 8) - 128;
- btwrite(value & 0xff, BT848_HUE);
+ btwrite(value & 0xff, BT848_HUE);
}
static void bt848_contrast(struct bttv *btv, int cont)
@@ -859,9 +859,9 @@ static void bt848_contrast(struct bttv *btv, int cont)
/* 0-511 */
value = (cont >> 7);
hibit = (value >> 6) & 4;
- btwrite(value & 0xff, BT848_CONTRAST_LO);
- btaor(hibit, ~4, BT848_E_CONTROL);
- btaor(hibit, ~4, BT848_O_CONTROL);
+ btwrite(value & 0xff, BT848_CONTRAST_LO);
+ btaor(hibit, ~4, BT848_E_CONTROL);
+ btaor(hibit, ~4, BT848_O_CONTROL);
}
static void bt848_sat(struct bttv *btv, int color)
@@ -873,12 +873,12 @@ static void bt848_sat(struct bttv *btv, int color)
/* 0-511 for the color */
val_u = ((color * btv->opt_uv_ratio) / 50) >> 7;
val_v = (((color * (100 - btv->opt_uv_ratio) / 50) >>7)*180L)/254;
- hibits = (val_u >> 7) & 2;
+ hibits = (val_u >> 7) & 2;
hibits |= (val_v >> 8) & 1;
- btwrite(val_u & 0xff, BT848_SAT_U_LO);
- btwrite(val_v & 0xff, BT848_SAT_V_LO);
- btaor(hibits, ~3, BT848_E_CONTROL);
- btaor(hibits, ~3, BT848_O_CONTROL);
+ btwrite(val_u & 0xff, BT848_SAT_U_LO);
+ btwrite(val_v & 0xff, BT848_SAT_V_LO);
+ btaor(hibits, ~3, BT848_E_CONTROL);
+ btaor(hibits, ~3, BT848_O_CONTROL);
}
/* ----------------------------------------------------------------------- */
@@ -891,7 +891,7 @@ video_mux(struct bttv *btv, unsigned int input)
if (input >= bttv_tvcards[btv->c.type].video_inputs)
return -EINVAL;
- /* needed by RemoteVideo MX */
+ /* needed by RemoteVideo MX */
mask2 = bttv_tvcards[btv->c.type].gpiomask2;
if (mask2)
gpio_inout(mask2,mask2);
@@ -964,7 +964,7 @@ i2c_vidiocschan(struct bttv *btv)
c.norm = btv->tvnorm;
c.channel = btv->input;
bttv_call_i2c_clients(btv,VIDIOCSCHAN,&c);
- if (btv->c.type == BTTV_VOODOOTV_FM)
+ if (btv->c.type == BTTV_BOARD_VOODOOTV_FM)
bttv_tda9880_setnorm(btv,c.norm);
}
@@ -988,7 +988,7 @@ set_tvnorm(struct bttv *btv, unsigned int norm)
bt848A_set_timing(btv);
switch (btv->c.type) {
- case BTTV_VOODOOTV_FM:
+ case BTTV_BOARD_VOODOOTV_FM:
bttv_tda9880_setnorm(btv,norm);
break;
}
@@ -1055,22 +1055,22 @@ static void init_bt848(struct bttv *btv)
btwrite(BT848_COLOR_CTL_GAMMA, BT848_COLOR_CTL);
btwrite(BT848_IFORM_XTAUTO | BT848_IFORM_AUTO, BT848_IFORM);
- /* set planar and packed mode trigger points and */
- /* set rising edge of inverted GPINTR pin as irq trigger */
- btwrite(BT848_GPIO_DMA_CTL_PKTP_32|
- BT848_GPIO_DMA_CTL_PLTP1_16|
- BT848_GPIO_DMA_CTL_PLTP23_16|
- BT848_GPIO_DMA_CTL_GPINTC|
- BT848_GPIO_DMA_CTL_GPINTI,
- BT848_GPIO_DMA_CTL);
+ /* set planar and packed mode trigger points and */
+ /* set rising edge of inverted GPINTR pin as irq trigger */
+ btwrite(BT848_GPIO_DMA_CTL_PKTP_32|
+ BT848_GPIO_DMA_CTL_PLTP1_16|
+ BT848_GPIO_DMA_CTL_PLTP23_16|
+ BT848_GPIO_DMA_CTL_GPINTC|
+ BT848_GPIO_DMA_CTL_GPINTI,
+ BT848_GPIO_DMA_CTL);
val = btv->opt_chroma_agc ? BT848_SCLOOP_CAGC : 0;
- btwrite(val, BT848_E_SCLOOP);
- btwrite(val, BT848_O_SCLOOP);
+ btwrite(val, BT848_E_SCLOOP);
+ btwrite(val, BT848_O_SCLOOP);
- btwrite(0x20, BT848_E_VSCALE_HI);
- btwrite(0x20, BT848_O_VSCALE_HI);
- btwrite(BT848_ADC_RESERVED | (btv->opt_adc_crush ? BT848_ADC_CRUSH : 0),
+ btwrite(0x20, BT848_E_VSCALE_HI);
+ btwrite(0x20, BT848_O_VSCALE_HI);
+ btwrite(BT848_ADC_RESERVED | (btv->opt_adc_crush ? BT848_ADC_CRUSH : 0),
BT848_ADC);
btwrite(whitecrush_upper, BT848_WC_UP);
@@ -1089,7 +1089,7 @@ static void init_bt848(struct bttv *btv)
bt848_contrast(btv, btv->contrast);
bt848_sat(btv, btv->saturation);
- /* interrupt */
+ /* interrupt */
init_irqreg(btv);
}
@@ -1105,7 +1105,7 @@ static void bttv_reinit_bt848(struct bttv *btv)
spin_unlock_irqrestore(&btv->s_lock,flags);
init_bt848(btv);
- btv->pll.pll_current = -1;
+ btv->pll.pll_current = -1;
set_input(btv,btv->input);
}
@@ -1398,7 +1398,7 @@ bttv_switch_overlay(struct bttv *btv, struct bttv_fh *fh,
/* video4linux (1) interface */
static int bttv_prepare_buffer(struct bttv *btv, struct bttv_buffer *buf,
- const struct bttv_format *fmt,
+ const struct bttv_format *fmt,
unsigned int width, unsigned int height,
enum v4l2_field field)
{
@@ -1521,8 +1521,8 @@ static const char *v4l1_ioctls[] = {
static int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg)
{
switch (cmd) {
- case BTTV_VERSION:
- return BTTV_VERSION_CODE;
+ case BTTV_VERSION:
+ return BTTV_VERSION_CODE;
/* *** v4l1 *** ************************************************ */
case VIDIOCGFREQ:
@@ -1576,32 +1576,32 @@ static int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg)
return 0;
}
- case VIDIOCGCHAN:
- {
- struct video_channel *v = arg;
+ case VIDIOCGCHAN:
+ {
+ struct video_channel *v = arg;
unsigned int channel = v->channel;
- if (channel >= bttv_tvcards[btv->c.type].video_inputs)
- return -EINVAL;
- v->tuners=0;
- v->flags = VIDEO_VC_AUDIO;
- v->type = VIDEO_TYPE_CAMERA;
- v->norm = btv->tvnorm;
+ if (channel >= bttv_tvcards[btv->c.type].video_inputs)
+ return -EINVAL;
+ v->tuners=0;
+ v->flags = VIDEO_VC_AUDIO;
+ v->type = VIDEO_TYPE_CAMERA;
+ v->norm = btv->tvnorm;
if (channel == bttv_tvcards[btv->c.type].tuner) {
- strcpy(v->name,"Television");
- v->flags|=VIDEO_VC_TUNER;
- v->type=VIDEO_TYPE_TV;
- v->tuners=1;
- } else if (channel == btv->svhs) {
- strcpy(v->name,"S-Video");
- } else {
- sprintf(v->name,"Composite%d",channel);
+ strcpy(v->name,"Television");
+ v->flags|=VIDEO_VC_TUNER;
+ v->type=VIDEO_TYPE_TV;
+ v->tuners=1;
+ } else if (channel == btv->svhs) {
+ strcpy(v->name,"S-Video");
+ } else {
+ sprintf(v->name,"Composite%d",channel);
}
return 0;
- }
- case VIDIOCSCHAN:
- {
- struct video_channel *v = arg;
+ }
+ case VIDIOCSCHAN:
+ {
+ struct video_channel *v = arg;
unsigned int channel = v->channel;
if (channel >= bttv_tvcards[btv->c.type].video_inputs)
@@ -1623,7 +1623,7 @@ static int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg)
return 0;
}
- case VIDIOCGAUDIO:
+ case VIDIOCGAUDIO:
{
struct video_audio *v = arg;
@@ -1728,7 +1728,7 @@ static int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg)
} else if (i->index == btv->svhs) {
sprintf(i->name, "S-Video");
} else {
- sprintf(i->name,"Composite%d",i->index);
+ sprintf(i->name,"Composite%d",i->index);
}
if (i->index == btv->input) {
__u32 dstatus = btread(BT848_DSTATUS);
@@ -1851,6 +1851,11 @@ static int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg)
up(&btv->lock);
return 0;
}
+ case VIDIOC_LOG_STATUS:
+ {
+ bttv_call_i2c_clients(btv, VIDIOC_LOG_STATUS, 0);
+ return 0;
+ }
default:
return -ENOIOCTLCMD;
@@ -1951,8 +1956,7 @@ static int setup_window(struct bttv_fh *fh, struct bttv *btv,
}
down(&fh->cap.lock);
- if (fh->ov.clips)
- kfree(fh->ov.clips);
+ kfree(fh->ov.clips);
fh->ov.clips = clips;
fh->ov.nclips = n;
@@ -2164,7 +2168,7 @@ static int bttv_s_fmt(struct bttv_fh *fh, struct bttv *btv,
if (0 != retval)
return retval;
if (locked_btres(fh->btv, RESOURCE_VBI))
- return -EBUSY;
+ return -EBUSY;
bttv_vbi_try_fmt(fh,f);
bttv_vbi_setlines(fh,btv,f->fmt.vbi.count[0]);
bttv_vbi_get_fmt(fh,f);
@@ -2202,9 +2206,9 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
bttv_reinit_bt848(btv);
switch (cmd) {
- case VIDIOCSFREQ:
- case VIDIOCSTUNER:
- case VIDIOCSCHAN:
+ case VIDIOCSFREQ:
+ case VIDIOCSTUNER:
+ case VIDIOCSCHAN:
case VIDIOC_S_CTRL:
case VIDIOC_S_STD:
case VIDIOC_S_INPUT:
@@ -2220,10 +2224,10 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
/* *** v4l1 *** ************************************************ */
case VIDIOCGCAP:
{
- struct video_capability *cap = arg;
+ struct video_capability *cap = arg;
memset(cap,0,sizeof(*cap));
- strcpy(cap->name,btv->video_dev->name);
+ strcpy(cap->name,btv->video_dev->name);
if (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type) {
/* vbi */
cap->type = VID_TYPE_TUNER|VID_TYPE_TELETEXT;
@@ -2243,7 +2247,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
}
cap->channels = bttv_tvcards[btv->c.type].video_inputs;
cap->audios = bttv_tvcards[btv->c.type].audio_inputs;
- return 0;
+ return 0;
}
case VIDIOCGPICT:
@@ -2292,7 +2296,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
bt848_hue(btv,pic->hue);
bt848_sat(btv,pic->colour);
up(&fh->cap.lock);
- return 0;
+ return 0;
}
case VIDIOCGWIN:
@@ -2353,8 +2357,8 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
unsigned long end;
if(!capable(CAP_SYS_ADMIN) &&
- !capable(CAP_SYS_RAWIO))
- return -EPERM;
+ !capable(CAP_SYS_RAWIO))
+ return -EPERM;
end = (unsigned long)fbuf->base +
fbuf->height * fbuf->bytesperline;
down(&fh->cap.lock);
@@ -2428,7 +2432,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
}
/* switch over */
- retval = bttv_switch_overlay(btv,fh,new);
+ retval = bttv_switch_overlay(btv,fh,new);
up(&fh->cap.lock);
return retval;
}
@@ -2567,13 +2571,13 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
return 0;
}
- case BTTV_VERSION:
- case VIDIOCGFREQ:
- case VIDIOCSFREQ:
- case VIDIOCGTUNER:
- case VIDIOCSTUNER:
- case VIDIOCGCHAN:
- case VIDIOCSCHAN:
+ case BTTV_VERSION:
+ case VIDIOCGFREQ:
+ case VIDIOCSFREQ:
+ case VIDIOCGTUNER:
+ case VIDIOCSTUNER:
+ case VIDIOCGCHAN:
+ case VIDIOCSCHAN:
case VIDIOCGAUDIO:
case VIDIOCSAUDIO:
return bttv_common_ioctls(btv,cmd,arg);
@@ -2585,8 +2589,8 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
if (0 == v4l2)
return -EINVAL;
- strcpy(cap->driver,"bttv");
- strlcpy(cap->card,btv->video_dev->name,sizeof(cap->card));
+ strcpy(cap->driver,"bttv");
+ strlcpy(cap->card,btv->video_dev->name,sizeof(cap->card));
sprintf(cap->bus_info,"PCI:%s",pci_name(btv->c.pci));
cap->version = BTTV_VERSION_CODE;
cap->capabilities =
@@ -2723,8 +2727,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
fh->ov.w.height = fb->fmt.height;
btv->init.ov.w.width = fb->fmt.width;
btv->init.ov.w.height = fb->fmt.height;
- if (fh->ov.clips)
- kfree(fh->ov.clips);
+ kfree(fh->ov.clips);
fh->ov.clips = NULL;
fh->ov.nclips = 0;
@@ -2858,6 +2861,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
case VIDIOC_S_TUNER:
case VIDIOC_G_FREQUENCY:
case VIDIOC_S_FREQUENCY:
+ case VIDIOC_LOG_STATUS:
return bttv_common_ioctls(btv,cmd,arg);
default:
@@ -3093,7 +3097,7 @@ static struct video_device bttv_video_template =
{
.name = "UNSET",
.type = VID_TYPE_CAPTURE|VID_TYPE_TUNER|
- VID_TYPE_CLIPPING|VID_TYPE_SCALES,
+ VID_TYPE_CLIPPING|VID_TYPE_SCALES,
.hardware = VID_HARDWARE_BT848,
.fops = &bttv_fops,
.minor = -1,
@@ -3139,7 +3143,7 @@ static int radio_open(struct inode *inode, struct file *file)
audio_mux(btv,AUDIO_RADIO);
up(&btv->lock);
- return 0;
+ return 0;
}
static int radio_release(struct inode *inode, struct file *file)
@@ -3162,34 +3166,34 @@ static int radio_do_ioctl(struct inode *inode, struct file *file,
switch (cmd) {
case VIDIOCGCAP:
{
- struct video_capability *cap = arg;
+ struct video_capability *cap = arg;
memset(cap,0,sizeof(*cap));
- strcpy(cap->name,btv->radio_dev->name);
- cap->type = VID_TYPE_TUNER;
+ strcpy(cap->name,btv->radio_dev->name);
+ cap->type = VID_TYPE_TUNER;
cap->channels = 1;
cap->audios = 1;
- return 0;
+ return 0;
}
- case VIDIOCGTUNER:
- {
- struct video_tuner *v = arg;
+ case VIDIOCGTUNER:
+ {
+ struct video_tuner *v = arg;
- if(v->tuner)
- return -EINVAL;
+ if(v->tuner)
+ return -EINVAL;
memset(v,0,sizeof(*v));
- strcpy(v->name, "Radio");
- bttv_call_i2c_clients(btv,cmd,v);
- return 0;
- }
- case VIDIOCSTUNER:
+ strcpy(v->name, "Radio");
+ bttv_call_i2c_clients(btv,cmd,v);
+ return 0;
+ }
+ case VIDIOCSTUNER:
/* nothing to do */
return 0;
case BTTV_VERSION:
- case VIDIOCGFREQ:
- case VIDIOCSFREQ:
+ case VIDIOCGFREQ:
+ case VIDIOCSFREQ:
case VIDIOCGAUDIO:
case VIDIOCSAUDIO:
return bttv_common_ioctls(btv,cmd,arg);
@@ -3695,7 +3699,7 @@ static irqreturn_t bttv_irq(int irq, void *dev_id, struct pt_regs * regs)
}
if (astat&BT848_INT_VSYNC)
- btv->field_count++;
+ btv->field_count++;
if (astat & BT848_INT_GPINT) {
wake_up(&btv->gpioq);
@@ -3707,13 +3711,13 @@ static irqreturn_t bttv_irq(int irq, void *dev_id, struct pt_regs * regs)
wake_up(&btv->i2c_queue);
}
- if ((astat & BT848_INT_RISCI) && (stat & (4<<28)))
+ if ((astat & BT848_INT_RISCI) && (stat & (4<<28)))
bttv_irq_switch_vbi(btv);
- if ((astat & BT848_INT_RISCI) && (stat & (2<<28)))
+ if ((astat & BT848_INT_RISCI) && (stat & (2<<28)))
bttv_irq_wakeup_top(btv);
- if ((astat & BT848_INT_RISCI) && (stat & (1<<28)))
+ if ((astat & BT848_INT_RISCI) && (stat & (1<<28)))
bttv_irq_switch_video(btv);
if ((astat & BT848_INT_HLOCK) && btv->opt_automute)
@@ -3738,10 +3742,22 @@ static irqreturn_t bttv_irq(int irq, void *dev_id, struct pt_regs * regs)
count++;
if (count > 4) {
- btwrite(0, BT848_INT_MASK);
- printk(KERN_ERR
- "bttv%d: IRQ lockup, cleared int mask [", btv->c.nr);
+
+ if (count > 8 || !(astat & BT848_INT_GPINT)) {
+ btwrite(0, BT848_INT_MASK);
+
+ printk(KERN_ERR
+ "bttv%d: IRQ lockup, cleared int mask [", btv->c.nr);
+ } else {
+ printk(KERN_ERR
+ "bttv%d: IRQ lockup, clearing GPINT from int mask [", btv->c.nr);
+
+ btwrite(btread(BT848_INT_MASK) & (-1 ^ BT848_INT_GPINT),
+ BT848_INT_MASK);
+ };
+
bttv_print_irqbits(stat,astat);
+
printk("]\n");
}
}
@@ -3810,7 +3826,7 @@ static int __devinit bttv_register_video(struct bttv *btv)
/* video */
btv->video_dev = vdev_init(btv, &bttv_video_template, "video");
- if (NULL == btv->video_dev)
+ if (NULL == btv->video_dev)
goto err;
if (video_register_device(btv->video_dev,VFL_TYPE_GRABBER,video_nr)<0)
goto err;
@@ -3820,18 +3836,18 @@ static int __devinit bttv_register_video(struct bttv *btv)
/* vbi */
btv->vbi_dev = vdev_init(btv, &bttv_vbi_template, "vbi");
- if (NULL == btv->vbi_dev)
+ if (NULL == btv->vbi_dev)
goto err;
- if (video_register_device(btv->vbi_dev,VFL_TYPE_VBI,vbi_nr)<0)
+ if (video_register_device(btv->vbi_dev,VFL_TYPE_VBI,vbi_nr)<0)
goto err;
printk(KERN_INFO "bttv%d: registered device vbi%d\n",
btv->c.nr,btv->vbi_dev->minor & 0x1f);
- if (!btv->has_radio)
+ if (!btv->has_radio)
return 0;
/* radio */
btv->radio_dev = vdev_init(btv, &radio_template, "radio");
- if (NULL == btv->radio_dev)
+ if (NULL == btv->radio_dev)
goto err;
if (video_register_device(btv->radio_dev, VFL_TYPE_RADIO,radio_nr)<0)
goto err;
@@ -3852,11 +3868,11 @@ static int __devinit bttv_register_video(struct bttv *btv)
static void pci_set_command(struct pci_dev *dev)
{
#if defined(__powerpc__)
- unsigned int cmd;
+ unsigned int cmd;
- pci_read_config_dword(dev, PCI_COMMAND, &cmd);
- cmd = (cmd | PCI_COMMAND_MEMORY );
- pci_write_config_dword(dev, PCI_COMMAND, cmd);
+ pci_read_config_dword(dev, PCI_COMMAND, &cmd);
+ cmd = (cmd | PCI_COMMAND_MEMORY );
+ pci_write_config_dword(dev, PCI_COMMAND, cmd);
#endif
}
@@ -3870,63 +3886,62 @@ static int __devinit bttv_probe(struct pci_dev *dev,
if (bttv_num == BTTV_MAX)
return -ENOMEM;
printk(KERN_INFO "bttv: Bt8xx card found (%d).\n", bttv_num);
- btv=&bttvs[bttv_num];
+ btv=&bttvs[bttv_num];
memset(btv,0,sizeof(*btv));
btv->c.nr = bttv_num;
sprintf(btv->c.name,"bttv%d",btv->c.nr);
/* initialize structs / fill in defaults */
- init_MUTEX(&btv->lock);
- init_MUTEX(&btv->reslock);
- spin_lock_init(&btv->s_lock);
- spin_lock_init(&btv->gpio_lock);
- init_waitqueue_head(&btv->gpioq);
- init_waitqueue_head(&btv->i2c_queue);
- INIT_LIST_HEAD(&btv->c.subs);
- INIT_LIST_HEAD(&btv->capture);
- INIT_LIST_HEAD(&btv->vcapture);
+ init_MUTEX(&btv->lock);
+ init_MUTEX(&btv->reslock);
+ spin_lock_init(&btv->s_lock);
+ spin_lock_init(&btv->gpio_lock);
+ init_waitqueue_head(&btv->gpioq);
+ init_waitqueue_head(&btv->i2c_queue);
+ INIT_LIST_HEAD(&btv->c.subs);
+ INIT_LIST_HEAD(&btv->capture);
+ INIT_LIST_HEAD(&btv->vcapture);
v4l2_prio_init(&btv->prio);
init_timer(&btv->timeout);
btv->timeout.function = bttv_irq_timeout;
btv->timeout.data = (unsigned long)btv;
- btv->i2c_rc = -1;
- btv->tuner_type = UNSET;
- btv->pinnacle_id = UNSET;
+ btv->i2c_rc = -1;
+ btv->tuner_type = UNSET;
+ btv->pinnacle_id = UNSET;
btv->new_input = UNSET;
- btv->gpioirq = 1;
btv->has_radio=radio[btv->c.nr];
/* pci stuff (init, get irq/mmio, ... */
btv->c.pci = dev;
- btv->id = dev->device;
+ btv->id = dev->device;
if (pci_enable_device(dev)) {
- printk(KERN_WARNING "bttv%d: Can't enable device.\n",
+ printk(KERN_WARNING "bttv%d: Can't enable device.\n",
btv->c.nr);
return -EIO;
}
- if (pci_set_dma_mask(dev, DMA_32BIT_MASK)) {
- printk(KERN_WARNING "bttv%d: No suitable DMA available.\n",
+ if (pci_set_dma_mask(dev, DMA_32BIT_MASK)) {
+ printk(KERN_WARNING "bttv%d: No suitable DMA available.\n",
btv->c.nr);
return -EIO;
- }
+ }
if (!request_mem_region(pci_resource_start(dev,0),
pci_resource_len(dev,0),
btv->c.name)) {
- printk(KERN_WARNING "bttv%d: can't request iomem (0x%lx).\n",
+ printk(KERN_WARNING "bttv%d: can't request iomem (0x%lx).\n",
btv->c.nr, pci_resource_start(dev,0));
return -EBUSY;
}
- pci_set_master(dev);
+ pci_set_master(dev);
pci_set_command(dev);
pci_set_drvdata(dev,btv);
- pci_read_config_byte(dev, PCI_CLASS_REVISION, &btv->revision);
- pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat);
- printk(KERN_INFO "bttv%d: Bt%d (rev %d) at %s, ",
- bttv_num,btv->id, btv->revision, pci_name(dev));
- printk("irq: %d, latency: %d, mmio: 0x%lx\n",
+ pci_read_config_byte(dev, PCI_CLASS_REVISION, &btv->revision);
+ pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat);
+ printk(KERN_INFO "bttv%d: Bt%d (rev %d) at %s, ",
+ bttv_num,btv->id, btv->revision, pci_name(dev));
+ printk("irq: %d, latency: %d, mmio: 0x%lx\n",
btv->c.pci->irq, lat, pci_resource_start(dev,0));
schedule();
@@ -3937,23 +3952,23 @@ static int __devinit bttv_probe(struct pci_dev *dev,
goto fail1;
}
- /* identify card */
+ /* identify card */
bttv_idcard(btv);
- /* disable irqs, register irq handler */
+ /* disable irqs, register irq handler */
btwrite(0, BT848_INT_MASK);
- result = request_irq(btv->c.pci->irq, bttv_irq,
- SA_SHIRQ | SA_INTERRUPT,btv->c.name,(void *)btv);
- if (result < 0) {
- printk(KERN_ERR "bttv%d: can't get IRQ %d\n",
+ result = request_irq(btv->c.pci->irq, bttv_irq,
+ SA_SHIRQ | SA_INTERRUPT,btv->c.name,(void *)btv);
+ if (result < 0) {
+ printk(KERN_ERR "bttv%d: can't get IRQ %d\n",
bttv_num,btv->c.pci->irq);
goto fail1;
- }
+ }
if (0 != bttv_handle_chipset(btv)) {
result = -EIO;
goto fail2;
- }
+ }
/* init options from insmod args */
btv->opt_combfilter = combfilter;
@@ -3979,29 +3994,29 @@ static int __devinit bttv_probe(struct pci_dev *dev,
btv->input = 0;
/* initialize hardware */
- if (bttv_gpio)
- bttv_gpio_tracking(btv,"pre-init");
+ if (bttv_gpio)
+ bttv_gpio_tracking(btv,"pre-init");
bttv_risc_init_main(btv);
init_bt848(btv);
/* gpio */
- btwrite(0x00, BT848_GPIO_REG_INP);
- btwrite(0x00, BT848_GPIO_OUT_EN);
- if (bttv_verbose)
- bttv_gpio_tracking(btv,"init");
+ btwrite(0x00, BT848_GPIO_REG_INP);
+ btwrite(0x00, BT848_GPIO_OUT_EN);
+ if (bttv_verbose)
+ bttv_gpio_tracking(btv,"init");
- /* needs to be done before i2c is registered */
- bttv_init_card1(btv);
+ /* needs to be done before i2c is registered */
+ bttv_init_card1(btv);
- /* register i2c + gpio */
- init_bttv_i2c(btv);
+ /* register i2c + gpio */
+ init_bttv_i2c(btv);
- /* some card-specific stuff (needs working i2c) */
- bttv_init_card2(btv);
+ /* some card-specific stuff (needs working i2c) */
+ bttv_init_card2(btv);
init_irqreg(btv);
- /* register video4linux + input */
+ /* register video4linux + input */
if (!bttv_tvcards[btv->c.type].no_video) {
bttv_register_video(btv);
bt848_bright(btv,32768);
@@ -4020,10 +4035,10 @@ static int __devinit bttv_probe(struct pci_dev *dev,
/* everything is fine */
bttv_num++;
- return 0;
+ return 0;
fail2:
- free_irq(btv->c.pci->irq,btv);
+ free_irq(btv->c.pci->irq,btv);
fail1:
if (btv->bt848_mmio)
@@ -4036,12 +4051,12 @@ static int __devinit bttv_probe(struct pci_dev *dev,
static void __devexit bttv_remove(struct pci_dev *pci_dev)
{
- struct bttv *btv = pci_get_drvdata(pci_dev);
+ struct bttv *btv = pci_get_drvdata(pci_dev);
if (bttv_verbose)
printk("bttv%d: unloading\n",btv->c.nr);
- /* shutdown everything (DMA+IRQs) */
+ /* shutdown everything (DMA+IRQs) */
btand(~15, BT848_GPIO_DMA_CTL);
btwrite(0, BT848_INT_MASK);
btwrite(~0x0, BT848_INT_STAT);
@@ -4054,7 +4069,7 @@ static void __devexit bttv_remove(struct pci_dev *pci_dev)
wake_up(&btv->gpioq);
bttv_sub_del_devices(&btv->c);
- /* unregister i2c_bus + input */
+ /* unregister i2c_bus + input */
fini_bttv_i2c(btv);
/* unregister video4linux */
@@ -4064,18 +4079,18 @@ static void __devexit bttv_remove(struct pci_dev *pci_dev)
btcx_riscmem_free(btv->c.pci,&btv->main);
/* free ressources */
- free_irq(btv->c.pci->irq,btv);
+ free_irq(btv->c.pci->irq,btv);
iounmap(btv->bt848_mmio);
- release_mem_region(pci_resource_start(btv->c.pci,0),
- pci_resource_len(btv->c.pci,0));
+ release_mem_region(pci_resource_start(btv->c.pci,0),
+ pci_resource_len(btv->c.pci,0));
pci_set_drvdata(pci_dev, NULL);
- return;
+ return;
}
static int bttv_suspend(struct pci_dev *pci_dev, pm_message_t state)
{
- struct bttv *btv = pci_get_drvdata(pci_dev);
+ struct bttv *btv = pci_get_drvdata(pci_dev);
struct bttv_buffer_set idle;
unsigned long flags;
@@ -4110,7 +4125,7 @@ static int bttv_suspend(struct pci_dev *pci_dev, pm_message_t state)
static int bttv_resume(struct pci_dev *pci_dev)
{
- struct bttv *btv = pci_get_drvdata(pci_dev);
+ struct bttv *btv = pci_get_drvdata(pci_dev);
unsigned long flags;
int err;
@@ -4155,24 +4170,24 @@ static int bttv_resume(struct pci_dev *pci_dev)
}
static struct pci_device_id bttv_pci_tbl[] = {
- {PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT848,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT848,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
{PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT849,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
{PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT878,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
{PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT879,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
- {0,}
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0,}
};
MODULE_DEVICE_TABLE(pci, bttv_pci_tbl);
static struct pci_driver bttv_pci_driver = {
- .name = "bttv",
- .id_table = bttv_pci_tbl,
- .probe = bttv_probe,
- .remove = __devexit_p(bttv_remove),
+ .name = "bttv",
+ .id_table = bttv_pci_tbl,
+ .probe = bttv_probe,
+ .remove = __devexit_p(bttv_remove),
.suspend = bttv_suspend,
.resume = bttv_resume,
};
diff --git a/drivers/media/video/bttv-gpio.c b/drivers/media/video/bttv-gpio.c
index 6b280c03e398..575ce8b8e714 100644
--- a/drivers/media/video/bttv-gpio.c
+++ b/drivers/media/video/bttv-gpio.c
@@ -7,7 +7,7 @@
Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de)
- & Marcus Metzler (mocm@thp.uni-koeln.de)
+ & Marcus Metzler (mocm@thp.uni-koeln.de)
(c) 1999-2003 Gerd Knorr <kraxel@bytesex.org>
This program is free software; you can redistribute it and/or modify
diff --git a/drivers/media/video/bttv-i2c.c b/drivers/media/video/bttv-i2c.c
index e684df37eb0e..77619eb131f6 100644
--- a/drivers/media/video/bttv-i2c.c
+++ b/drivers/media/video/bttv-i2c.c
@@ -5,7 +5,7 @@
bttv - Bt848 frame grabber driver
Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de)
- & Marcus Metzler (mocm@thp.uni-koeln.de)
+ & Marcus Metzler (mocm@thp.uni-koeln.de)
(c) 1999-2003 Gerd Knorr <kraxel@bytesex.org>
This program is free software; you can redistribute it and/or modify
@@ -237,7 +237,7 @@ bttv_i2c_readbytes(struct bttv *btv, const struct i2c_msg *msg, int last)
err:
if (i2c_debug)
printk(" ERR: %d\n",retval);
- return retval;
+ return retval;
}
static int bttv_i2c_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, int num)
@@ -290,7 +290,13 @@ static struct i2c_adapter bttv_i2c_adap_hw_template = {
static int attach_inform(struct i2c_client *client)
{
- struct bttv *btv = i2c_get_adapdata(client->adapter);
+ struct bttv *btv = i2c_get_adapdata(client->adapter);
+ int addr=ADDR_UNSET;
+
+
+ if (ADDR_UNSET != bttv_tvcards[btv->c.type].tuner_addr)
+ addr = bttv_tvcards[btv->c.type].tuner_addr;
+
if (bttv_debug)
printk(KERN_DEBUG "bttv%d: %s i2c attach [addr=0x%x,client=%s]\n",
@@ -300,19 +306,20 @@ static int attach_inform(struct i2c_client *client)
return 0;
if (btv->tuner_type != UNSET) {
- struct tuner_setup tun_setup;
+ struct tuner_setup tun_setup;
+
+ if ((addr==ADDR_UNSET) ||
+ (addr==client->addr)) {
- tun_setup.mode_mask = T_RADIO | T_ANALOG_TV | T_DIGITAL_TV;
- tun_setup.type = btv->tuner_type;
- tun_setup.addr = ADDR_UNSET;
+ tun_setup.mode_mask = T_ANALOG_TV | T_DIGITAL_TV | T_RADIO;
+ tun_setup.type = btv->tuner_type;
+ tun_setup.addr = addr;
+ bttv_call_i2c_clients(btv, TUNER_SET_TYPE_ADDR, &tun_setup);
+ }
- client->driver->command (client, TUNER_SET_TYPE_ADDR, &tun_setup);
}
- if (btv->pinnacle_id != UNSET)
- client->driver->command(client,AUDC_CONFIG_PINNACLE,
- &btv->pinnacle_id);
- return 0;
+ return 0;
}
void bttv_call_i2c_clients(struct bttv *btv, unsigned int cmd, void *arg)
@@ -330,43 +337,43 @@ static struct i2c_client bttv_i2c_client_template = {
/* read I2C */
int bttv_I2CRead(struct bttv *btv, unsigned char addr, char *probe_for)
{
- unsigned char buffer = 0;
+ unsigned char buffer = 0;
if (0 != btv->i2c_rc)
return -1;
if (bttv_verbose && NULL != probe_for)
printk(KERN_INFO "bttv%d: i2c: checking for %s @ 0x%02x... ",
btv->c.nr,probe_for,addr);
- btv->i2c_client.addr = addr >> 1;
- if (1 != i2c_master_recv(&btv->i2c_client, &buffer, 1)) {
+ btv->i2c_client.addr = addr >> 1;
+ if (1 != i2c_master_recv(&btv->i2c_client, &buffer, 1)) {
if (NULL != probe_for) {
if (bttv_verbose)
printk("not found\n");
} else
printk(KERN_WARNING "bttv%d: i2c read 0x%x: error\n",
btv->c.nr,addr);
- return -1;
+ return -1;
}
if (bttv_verbose && NULL != probe_for)
printk("found\n");
- return buffer;
+ return buffer;
}
/* write I2C */
int bttv_I2CWrite(struct bttv *btv, unsigned char addr, unsigned char b1,
- unsigned char b2, int both)
+ unsigned char b2, int both)
{
- unsigned char buffer[2];
- int bytes = both ? 2 : 1;
+ unsigned char buffer[2];
+ int bytes = both ? 2 : 1;
if (0 != btv->i2c_rc)
return -1;
- btv->i2c_client.addr = addr >> 1;
- buffer[0] = b1;
- buffer[1] = b2;
- if (bytes != i2c_master_send(&btv->i2c_client, buffer, bytes))
+ btv->i2c_client.addr = addr >> 1;
+ buffer[0] = b1;
+ buffer[1] = b2;
+ if (bytes != i2c_master_send(&btv->i2c_client, buffer, bytes))
return -1;
- return 0;
+ return 0;
}
/* read EEPROM content */
@@ -431,8 +438,8 @@ int __devinit init_bttv_i2c(struct bttv *btv)
"bt%d #%d [%s]", btv->id, btv->c.nr,
btv->use_i2c_hw ? "hw" : "sw");
- i2c_set_adapdata(&btv->c.i2c_adap, btv);
- btv->i2c_client.adapter = &btv->c.i2c_adap;
+ i2c_set_adapdata(&btv->c.i2c_adap, btv);
+ btv->i2c_client.adapter = &btv->c.i2c_adap;
#ifdef I2C_CLASS_TV_ANALOG
if (bttv_tvcards[btv->c.type].no_video)
diff --git a/drivers/media/video/bttv-if.c b/drivers/media/video/bttv-if.c
index e8aada772b89..19b564ab0e92 100644
--- a/drivers/media/video/bttv-if.c
+++ b/drivers/media/video/bttv-if.c
@@ -1,13 +1,13 @@
/*
bttv-if.c -- old gpio interface to other kernel modules
- don't use in new code, will go away in 2.7
+ don't use in new code, will go away in 2.7
have a look at bttv-gpio.c instead.
bttv - Bt848 frame grabber driver
Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de)
- & Marcus Metzler (mocm@thp.uni-koeln.de)
+ & Marcus Metzler (mocm@thp.uni-koeln.de)
(c) 1999-2003 Gerd Knorr <kraxel@bytesex.org>
This program is free software; you can redistribute it and/or modify
diff --git a/drivers/media/video/bttv-risc.c b/drivers/media/video/bttv-risc.c
index a5ed99b89445..b40e9734bf08 100644
--- a/drivers/media/video/bttv-risc.c
+++ b/drivers/media/video/bttv-risc.c
@@ -74,27 +74,27 @@ bttv_risc_packed(struct bttv *btv, struct btcx_riscmem *risc,
}
if (bpl <= sg_dma_len(sg)-offset) {
/* fits into current chunk */
- *(rp++)=cpu_to_le32(BT848_RISC_WRITE|BT848_RISC_SOL|
+ *(rp++)=cpu_to_le32(BT848_RISC_WRITE|BT848_RISC_SOL|
BT848_RISC_EOL|bpl);
- *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset);
- offset+=bpl;
+ *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset);
+ offset+=bpl;
} else {
/* scanline needs to be splitted */
- todo = bpl;
- *(rp++)=cpu_to_le32(BT848_RISC_WRITE|BT848_RISC_SOL|
+ todo = bpl;
+ *(rp++)=cpu_to_le32(BT848_RISC_WRITE|BT848_RISC_SOL|
(sg_dma_len(sg)-offset));
- *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset);
- todo -= (sg_dma_len(sg)-offset);
- offset = 0;
- sg++;
- while (todo > sg_dma_len(sg)) {
- *(rp++)=cpu_to_le32(BT848_RISC_WRITE|
+ *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset);
+ todo -= (sg_dma_len(sg)-offset);
+ offset = 0;
+ sg++;
+ while (todo > sg_dma_len(sg)) {
+ *(rp++)=cpu_to_le32(BT848_RISC_WRITE|
sg_dma_len(sg));
- *(rp++)=cpu_to_le32(sg_dma_address(sg));
+ *(rp++)=cpu_to_le32(sg_dma_address(sg));
todo -= sg_dma_len(sg);
sg++;
}
- *(rp++)=cpu_to_le32(BT848_RISC_WRITE|BT848_RISC_EOL|
+ *(rp++)=cpu_to_le32(BT848_RISC_WRITE|BT848_RISC_EOL|
todo);
*(rp++)=cpu_to_le32(sg_dma_address(sg));
offset += todo;
@@ -201,8 +201,8 @@ bttv_risc_planar(struct bttv *btv, struct btcx_riscmem *risc,
ri |= BT848_RISC_EOL;
/* write risc instruction */
- *(rp++)=cpu_to_le32(ri | ylen);
- *(rp++)=cpu_to_le32(((ylen >> hshift) << 16) |
+ *(rp++)=cpu_to_le32(ri | ylen);
+ *(rp++)=cpu_to_le32(((ylen >> hshift) << 16) |
(ylen >> hshift));
*(rp++)=cpu_to_le32(sg_dma_address(ysg)+yoffset);
yoffset += ylen;
@@ -319,7 +319,7 @@ bttv_calc_geo(struct bttv *btv, struct bttv_geometry *geo,
int width, int height, int interleaved, int norm)
{
const struct bttv_tvnorm *tvnorm = &bttv_tvnorms[norm];
- u32 xsf, sr;
+ u32 xsf, sr;
int vdelay;
int swidth = tvnorm->swidth;
@@ -334,52 +334,52 @@ bttv_calc_geo(struct bttv *btv, struct bttv_geometry *geo,
vdelay = tvnorm->vdelay;
- xsf = (width*scaledtwidth)/swidth;
- geo->hscale = ((totalwidth*4096UL)/xsf-4096);
- geo->hdelay = tvnorm->hdelayx1;
- geo->hdelay = (geo->hdelay*width)/swidth;
- geo->hdelay &= 0x3fe;
- sr = ((tvnorm->sheight >> (interleaved?0:1))*512)/height - 512;
- geo->vscale = (0x10000UL-sr) & 0x1fff;
- geo->crop = ((width>>8)&0x03) | ((geo->hdelay>>6)&0x0c) |
- ((tvnorm->sheight>>4)&0x30) | ((vdelay>>2)&0xc0);
- geo->vscale |= interleaved ? (BT848_VSCALE_INT<<8) : 0;
- geo->vdelay = vdelay;
- geo->width = width;
- geo->sheight = tvnorm->sheight;
+ xsf = (width*scaledtwidth)/swidth;
+ geo->hscale = ((totalwidth*4096UL)/xsf-4096);
+ geo->hdelay = tvnorm->hdelayx1;
+ geo->hdelay = (geo->hdelay*width)/swidth;
+ geo->hdelay &= 0x3fe;
+ sr = ((tvnorm->sheight >> (interleaved?0:1))*512)/height - 512;
+ geo->vscale = (0x10000UL-sr) & 0x1fff;
+ geo->crop = ((width>>8)&0x03) | ((geo->hdelay>>6)&0x0c) |
+ ((tvnorm->sheight>>4)&0x30) | ((vdelay>>2)&0xc0);
+ geo->vscale |= interleaved ? (BT848_VSCALE_INT<<8) : 0;
+ geo->vdelay = vdelay;
+ geo->width = width;
+ geo->sheight = tvnorm->sheight;
geo->vtotal = tvnorm->vtotal;
- if (btv->opt_combfilter) {
- geo->vtc = (width < 193) ? 2 : ((width < 385) ? 1 : 0);
- geo->comb = (width < 769) ? 1 : 0;
- } else {
- geo->vtc = 0;
- geo->comb = 0;
- }
+ if (btv->opt_combfilter) {
+ geo->vtc = (width < 193) ? 2 : ((width < 385) ? 1 : 0);
+ geo->comb = (width < 769) ? 1 : 0;
+ } else {
+ geo->vtc = 0;
+ geo->comb = 0;
+ }
}
static void
bttv_apply_geo(struct bttv *btv, struct bttv_geometry *geo, int odd)
{
- int off = odd ? 0x80 : 0x00;
+ int off = odd ? 0x80 : 0x00;
if (geo->comb)
btor(BT848_VSCALE_COMB, BT848_E_VSCALE_HI+off);
else
btand(~BT848_VSCALE_COMB, BT848_E_VSCALE_HI+off);
- btwrite(geo->vtc, BT848_E_VTC+off);
- btwrite(geo->hscale >> 8, BT848_E_HSCALE_HI+off);
- btwrite(geo->hscale & 0xff, BT848_E_HSCALE_LO+off);
- btaor((geo->vscale>>8), 0xe0, BT848_E_VSCALE_HI+off);
- btwrite(geo->vscale & 0xff, BT848_E_VSCALE_LO+off);
- btwrite(geo->width & 0xff, BT848_E_HACTIVE_LO+off);
- btwrite(geo->hdelay & 0xff, BT848_E_HDELAY_LO+off);
- btwrite(geo->sheight & 0xff, BT848_E_VACTIVE_LO+off);
- btwrite(geo->vdelay & 0xff, BT848_E_VDELAY_LO+off);
- btwrite(geo->crop, BT848_E_CROP+off);
+ btwrite(geo->vtc, BT848_E_VTC+off);
+ btwrite(geo->hscale >> 8, BT848_E_HSCALE_HI+off);
+ btwrite(geo->hscale & 0xff, BT848_E_HSCALE_LO+off);
+ btaor((geo->vscale>>8), 0xe0, BT848_E_VSCALE_HI+off);
+ btwrite(geo->vscale & 0xff, BT848_E_VSCALE_LO+off);
+ btwrite(geo->width & 0xff, BT848_E_HACTIVE_LO+off);
+ btwrite(geo->hdelay & 0xff, BT848_E_HDELAY_LO+off);
+ btwrite(geo->sheight & 0xff, BT848_E_VACTIVE_LO+off);
+ btwrite(geo->vdelay & 0xff, BT848_E_VDELAY_LO+off);
+ btwrite(geo->crop, BT848_E_CROP+off);
btwrite(geo->vtotal>>8, BT848_VTOTAL_HI);
- btwrite(geo->vtotal & 0xff, BT848_VTOTAL_LO);
+ btwrite(geo->vtotal & 0xff, BT848_VTOTAL_LO);
}
/* ---------------------------------------------------------- */
@@ -420,7 +420,7 @@ bttv_set_dma(struct bttv *btv, int override)
} else {
del_timer(&btv->timeout);
}
- btv->main.cpu[RISC_SLOT_LOOP] = cpu_to_le32(cmd);
+ btv->main.cpu[RISC_SLOT_LOOP] = cpu_to_le32(cmd);
btaor(capctl, ~0x0f, BT848_CAP_CTL);
if (capctl) {
@@ -432,7 +432,7 @@ bttv_set_dma(struct bttv *btv, int override)
} else {
if (!btv->dma_on)
return;
- btand(~3, BT848_GPIO_DMA_CTL);
+ btand(~3, BT848_GPIO_DMA_CTL);
btv->dma_on = 0;
}
return;
@@ -460,19 +460,19 @@ bttv_risc_init_main(struct bttv *btv)
btv->main.cpu[6] = cpu_to_le32(BT848_RISC_JUMP);
btv->main.cpu[7] = cpu_to_le32(btv->main.dma + (8<<2));
- btv->main.cpu[8] = cpu_to_le32(BT848_RISC_SYNC | BT848_RISC_RESYNC |
+ btv->main.cpu[8] = cpu_to_le32(BT848_RISC_SYNC | BT848_RISC_RESYNC |
BT848_FIFO_STATUS_VRO);
- btv->main.cpu[9] = cpu_to_le32(0);
+ btv->main.cpu[9] = cpu_to_le32(0);
/* bottom field */
- btv->main.cpu[10] = cpu_to_le32(BT848_RISC_JUMP);
+ btv->main.cpu[10] = cpu_to_le32(BT848_RISC_JUMP);
btv->main.cpu[11] = cpu_to_le32(btv->main.dma + (12<<2));
- btv->main.cpu[12] = cpu_to_le32(BT848_RISC_JUMP);
+ btv->main.cpu[12] = cpu_to_le32(BT848_RISC_JUMP);
btv->main.cpu[13] = cpu_to_le32(btv->main.dma + (14<<2));
/* jump back to top field */
btv->main.cpu[14] = cpu_to_le32(BT848_RISC_JUMP);
- btv->main.cpu[15] = cpu_to_le32(btv->main.dma + (0<<2));
+ btv->main.cpu[15] = cpu_to_le32(btv->main.dma + (0<<2));
return 0;
}
diff --git a/drivers/media/video/bttv.h b/drivers/media/video/bttv.h
index d254e90e3bb9..124ea41dada4 100644
--- a/drivers/media/video/bttv.h
+++ b/drivers/media/video/bttv.h
@@ -20,123 +20,148 @@
/* ---------------------------------------------------------- */
/* exported by bttv-cards.c */
-#define BTTV_UNKNOWN 0x00
-#define BTTV_MIRO 0x01
-#define BTTV_HAUPPAUGE 0x02
-#define BTTV_STB 0x03
-#define BTTV_INTEL 0x04
-#define BTTV_DIAMOND 0x05
-#define BTTV_AVERMEDIA 0x06
-#define BTTV_MATRIX_VISION 0x07
-#define BTTV_FLYVIDEO 0x08
-#define BTTV_TURBOTV 0x09
-#define BTTV_HAUPPAUGE878 0x0a
-#define BTTV_MIROPRO 0x0b
-#define BTTV_ADSTECH_TV 0x0c
-#define BTTV_AVERMEDIA98 0x0d
-#define BTTV_VHX 0x0e
-#define BTTV_ZOLTRIX 0x0f
-#define BTTV_PIXVIEWPLAYTV 0x10
-#define BTTV_WINVIEW_601 0x11
-#define BTTV_AVEC_INTERCAP 0x12
-#define BTTV_LIFE_FLYKIT 0x13
-#define BTTV_CEI_RAFFLES 0x14
-#define BTTV_CONFERENCETV 0x15
-#define BTTV_PHOEBE_TVMAS 0x16
-#define BTTV_MODTEC_205 0x17
-#define BTTV_MAGICTVIEW061 0x18
-#define BTTV_VOBIS_BOOSTAR 0x19
-#define BTTV_HAUPPAUG_WCAM 0x1a
-#define BTTV_MAXI 0x1b
-#define BTTV_TERRATV 0x1c
-#define BTTV_PXC200 0x1d
-#define BTTV_FLYVIDEO_98 0x1e
-#define BTTV_IPROTV 0x1f
-#define BTTV_INTEL_C_S_PCI 0x20
-#define BTTV_TERRATVALUE 0x21
-#define BTTV_WINFAST2000 0x22
-#define BTTV_CHRONOS_VS2 0x23
-#define BTTV_TYPHOON_TVIEW 0x24
-#define BTTV_PXELVWPLTVPRO 0x25
-#define BTTV_MAGICTVIEW063 0x26
-#define BTTV_PINNACLE 0x27
-#define BTTV_STB2 0x28
-#define BTTV_AVPHONE98 0x29
-#define BTTV_PV951 0x2a
-#define BTTV_ONAIR_TV 0x2b
-#define BTTV_SIGMA_TVII_FM 0x2c
-#define BTTV_MATRIX_VISION2 0x2d
-#define BTTV_ZOLTRIX_GENIE 0x2e
-#define BTTV_TERRATVRADIO 0x2f
-#define BTTV_DYNALINK 0x30
-#define BTTV_GVBCTV3PCI 0x31
-#define BTTV_PXELVWPLTVPAK 0x32
-#define BTTV_EAGLE 0x33
-#define BTTV_PINNACLEPRO 0x34
-#define BTTV_TVIEW_RDS_FM 0x35
-#define BTTV_LIFETEC_9415 0x36
-#define BTTV_BESTBUY_EASYTV 0x37
-#define BTTV_FLYVIDEO_98FM 0x38
-#define BTTV_GMV1 0x3d
-#define BTTV_BESTBUY_EASYTV2 0x3e
-#define BTTV_ATI_TVWONDER 0x3f
-#define BTTV_ATI_TVWONDERVE 0x40
-#define BTTV_FLYVIDEO2000 0x41
-#define BTTV_TERRATVALUER 0x42
-#define BTTV_GVBCTV4PCI 0x43
-#define BTTV_VOODOOTV_FM 0x44
-#define BTTV_AIMMS 0x45
-#define BTTV_PV_BT878P_PLUS 0x46
-#define BTTV_FLYVIDEO98EZ 0x47
-#define BTTV_PV_BT878P_9B 0x48
-#define BTTV_SENSORAY311 0x49
-#define BTTV_RV605 0x4a
-#define BTTV_WINDVR 0x4c
-#define BTTV_GRANDTEC 0x4d
-#define BTTV_KWORLD 0x4e
-#define BTTV_HAUPPAUGEPVR 0x50
-#define BTTV_GVBCTV5PCI 0x51
-#define BTTV_OSPREY1x0 0x52
-#define BTTV_OSPREY1x0_848 0x53
-#define BTTV_OSPREY101_848 0x54
-#define BTTV_OSPREY1x1 0x55
-#define BTTV_OSPREY1x1_SVID 0x56
-#define BTTV_OSPREY2xx 0x57
-#define BTTV_OSPREY2x0_SVID 0x58
-#define BTTV_OSPREY2x0 0x59
-#define BTTV_OSPREY500 0x5a
-#define BTTV_OSPREY540 0x5b
-#define BTTV_OSPREY2000 0x5c
-#define BTTV_IDS_EAGLE 0x5d
-#define BTTV_PINNACLESAT 0x5e
-#define BTTV_FORMAC_PROTV 0x5f
-#define BTTV_EURESYS_PICOLO 0x61
-#define BTTV_PV150 0x62
-#define BTTV_AD_TVK503 0x63
-#define BTTV_IVC200 0x66
-#define BTTV_XGUARD 0x67
-#define BTTV_NEBULA_DIGITV 0x68
-#define BTTV_PV143 0x69
-#define BTTV_IVC100 0x6e
-#define BTTV_IVC120 0x6f
-#define BTTV_PC_HDTV 0x70
-#define BTTV_TWINHAN_DST 0x71
-#define BTTV_WINFASTVC100 0x72
-#define BTTV_SIMUS_GVC1100 0x74
-#define BTTV_NGSTV_PLUS 0x75
-#define BTTV_LMLBT4 0x76
-#define BTTV_PICOLO_TETRA_CHIP 0x79
-#define BTTV_AVDVBT_771 0x7b
-#define BTTV_AVDVBT_761 0x7c
-#define BTTV_MATRIX_VISIONSQ 0x7d
-#define BTTV_MATRIX_VISIONSLC 0x7e
-#define BTTV_APAC_VIEWCOMP 0x7f
-#define BTTV_DVICO_DVBT_LITE 0x80
-#define BTTV_TIBET_CS16 0x83
-#define BTTV_KODICOM_4400R 0x84
-#define BTTV_ADLINK_RTV24 0x86
-#define BTTV_DVICO_FUSIONHDTV_5_LITE 0x87
-#define BTTV_ACORP_Y878F 0x88
+#define BTTV_BOARD_UNKNOWN 0x00
+#define BTTV_BOARD_MIRO 0x01
+#define BTTV_BOARD_HAUPPAUGE 0x02
+#define BTTV_BOARD_STB 0x03
+#define BTTV_BOARD_INTEL 0x04
+#define BTTV_BOARD_DIAMOND 0x05
+#define BTTV_BOARD_AVERMEDIA 0x06
+#define BTTV_BOARD_MATRIX_VISION 0x07
+#define BTTV_BOARD_FLYVIDEO 0x08
+#define BTTV_BOARD_TURBOTV 0x09
+#define BTTV_BOARD_HAUPPAUGE878 0x0a
+#define BTTV_BOARD_MIROPRO 0x0b
+#define BTTV_BOARD_ADSTECH_TV 0x0c
+#define BTTV_BOARD_AVERMEDIA98 0x0d
+#define BTTV_BOARD_VHX 0x0e
+#define BTTV_BOARD_ZOLTRIX 0x0f
+#define BTTV_BOARD_PIXVIEWPLAYTV 0x10
+#define BTTV_BOARD_WINVIEW_601 0x11
+#define BTTV_BOARD_AVEC_INTERCAP 0x12
+#define BTTV_BOARD_LIFE_FLYKIT 0x13
+#define BTTV_BOARD_CEI_RAFFLES 0x14
+#define BTTV_BOARD_CONFERENCETV 0x15
+#define BTTV_BOARD_PHOEBE_TVMAS 0x16
+#define BTTV_BOARD_MODTEC_205 0x17
+#define BTTV_BOARD_MAGICTVIEW061 0x18
+#define BTTV_BOARD_VOBIS_BOOSTAR 0x19
+#define BTTV_BOARD_HAUPPAUG_WCAM 0x1a
+#define BTTV_BOARD_MAXI 0x1b
+#define BTTV_BOARD_TERRATV 0x1c
+#define BTTV_BOARD_PXC200 0x1d
+#define BTTV_BOARD_FLYVIDEO_98 0x1e
+#define BTTV_BOARD_IPROTV 0x1f
+#define BTTV_BOARD_INTEL_C_S_PCI 0x20
+#define BTTV_BOARD_TERRATVALUE 0x21
+#define BTTV_BOARD_WINFAST2000 0x22
+#define BTTV_BOARD_CHRONOS_VS2 0x23
+#define BTTV_BOARD_TYPHOON_TVIEW 0x24
+#define BTTV_BOARD_PXELVWPLTVPRO 0x25
+#define BTTV_BOARD_MAGICTVIEW063 0x26
+#define BTTV_BOARD_PINNACLE 0x27
+#define BTTV_BOARD_STB2 0x28
+#define BTTV_BOARD_AVPHONE98 0x29
+#define BTTV_BOARD_PV951 0x2a
+#define BTTV_BOARD_ONAIR_TV 0x2b
+#define BTTV_BOARD_SIGMA_TVII_FM 0x2c
+#define BTTV_BOARD_MATRIX_VISION2 0x2d
+#define BTTV_BOARD_ZOLTRIX_GENIE 0x2e
+#define BTTV_BOARD_TERRATVRADIO 0x2f
+#define BTTV_BOARD_DYNALINK 0x30
+#define BTTV_BOARD_GVBCTV3PCI 0x31
+#define BTTV_BOARD_PXELVWPLTVPAK 0x32
+#define BTTV_BOARD_EAGLE 0x33
+#define BTTV_BOARD_PINNACLEPRO 0x34
+#define BTTV_BOARD_TVIEW_RDS_FM 0x35
+#define BTTV_BOARD_LIFETEC_9415 0x36
+#define BTTV_BOARD_BESTBUY_EASYTV 0x37
+#define BTTV_BOARD_FLYVIDEO_98FM 0x38
+#define BTTV_BOARD_GRANDTEC 0x39
+#define BTTV_BOARD_ASKEY_CPH060 0x3a
+#define BTTV_BOARD_ASKEY_CPH03X 0x3b
+#define BTTV_BOARD_MM100PCTV 0x3c
+#define BTTV_BOARD_GMV1 0x3d
+#define BTTV_BOARD_BESTBUY_EASYTV2 0x3e
+#define BTTV_BOARD_ATI_TVWONDER 0x3f
+#define BTTV_BOARD_ATI_TVWONDERVE 0x40
+#define BTTV_BOARD_FLYVIDEO2000 0x41
+#define BTTV_BOARD_TERRATVALUER 0x42
+#define BTTV_BOARD_GVBCTV4PCI 0x43
+#define BTTV_BOARD_VOODOOTV_FM 0x44
+#define BTTV_BOARD_AIMMS 0x45
+#define BTTV_BOARD_PV_BT878P_PLUS 0x46
+#define BTTV_BOARD_FLYVIDEO98EZ 0x47
+#define BTTV_BOARD_PV_BT878P_9B 0x48
+#define BTTV_BOARD_SENSORAY311 0x49
+#define BTTV_BOARD_RV605 0x4a
+#define BTTV_BOARD_POWERCLR_MTV878 0x4b
+#define BTTV_BOARD_WINDVR 0x4c
+#define BTTV_BOARD_GRANDTEC_MULTI 0x4d
+#define BTTV_BOARD_KWORLD 0x4e
+#define BTTV_BOARD_DSP_TCVIDEO 0x4f
+#define BTTV_BOARD_HAUPPAUGEPVR 0x50
+#define BTTV_BOARD_GVBCTV5PCI 0x51
+#define BTTV_BOARD_OSPREY1x0 0x52
+#define BTTV_BOARD_OSPREY1x0_848 0x53
+#define BTTV_BOARD_OSPREY101_848 0x54
+#define BTTV_BOARD_OSPREY1x1 0x55
+#define BTTV_BOARD_OSPREY1x1_SVID 0x56
+#define BTTV_BOARD_OSPREY2xx 0x57
+#define BTTV_BOARD_OSPREY2x0_SVID 0x58
+#define BTTV_BOARD_OSPREY2x0 0x59
+#define BTTV_BOARD_OSPREY500 0x5a
+#define BTTV_BOARD_OSPREY540 0x5b
+#define BTTV_BOARD_OSPREY2000 0x5c
+#define BTTV_BOARD_IDS_EAGLE 0x5d
+#define BTTV_BOARD_PINNACLESAT 0x5e
+#define BTTV_BOARD_FORMAC_PROTV 0x5f
+#define BTTV_BOARD_MACHTV 0x60
+#define BTTV_BOARD_EURESYS_PICOLO 0x61
+#define BTTV_BOARD_PV150 0x62
+#define BTTV_BOARD_AD_TVK503 0x63
+#define BTTV_BOARD_HERCULES_SM_TV 0x64
+#define BTTV_BOARD_PACETV 0x65
+#define BTTV_BOARD_IVC200 0x66
+#define BTTV_BOARD_XGUARD 0x67
+#define BTTV_BOARD_NEBULA_DIGITV 0x68
+#define BTTV_BOARD_PV143 0x69
+#define BTTV_BOARD_VD009X1_MINIDIN 0x6a
+#define BTTV_BOARD_VD009X1_COMBI 0x6b
+#define BTTV_BOARD_VD009_MINIDIN 0x6c
+#define BTTV_BOARD_VD009_COMBI 0x6d
+#define BTTV_BOARD_IVC100 0x6e
+#define BTTV_BOARD_IVC120 0x6f
+#define BTTV_BOARD_PC_HDTV 0x70
+#define BTTV_BOARD_TWINHAN_DST 0x71
+#define BTTV_BOARD_WINFASTVC100 0x72
+#define BTTV_BOARD_TEV560 0x73
+#define BTTV_BOARD_SIMUS_GVC1100 0x74
+#define BTTV_BOARD_NGSTV_PLUS 0x75
+#define BTTV_BOARD_LMLBT4 0x76
+#define BTTV_BOARD_TEKRAM_M205 0x77
+#define BTTV_BOARD_CONTVFMI 0x78
+#define BTTV_BOARD_PICOLO_TETRA_CHIP 0x79
+#define BTTV_BOARD_SPIRIT_TV 0x7a
+#define BTTV_BOARD_AVDVBT_771 0x7b
+#define BTTV_BOARD_AVDVBT_761 0x7c
+#define BTTV_BOARD_MATRIX_VISIONSQ 0x7d
+#define BTTV_BOARD_MATRIX_VISIONSLC 0x7e
+#define BTTV_BOARD_APAC_VIEWCOMP 0x7f
+#define BTTV_BOARD_DVICO_DVBT_LITE 0x80
+#define BTTV_BOARD_VGEAR_MYVCD 0x81
+#define BTTV_BOARD_SUPER_TV 0x82
+#define BTTV_BOARD_TIBET_CS16 0x83
+#define BTTV_BOARD_KODICOM_4400R 0x84
+#define BTTV_BOARD_KODICOM_4400R_SL 0x85
+#define BTTV_BOARD_ADLINK_RTV24 0x86
+#define BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE 0x87
+#define BTTV_BOARD_ACORP_Y878F 0x88
+#define BTTV_BOARD_CONCEPTRONIC_CTVFMI2 0x89
+#define BTTV_BOARD_PV_BT878P_2E 0x8a
+#define BTTV_BOARD_PV_M4900 0x8b
+#define BTTV_BOARD_OSPREY440 0x8c
+#define BTTV_BOARD_ASOUND_SKYEYE 0x8d
/* i2c address list */
#define I2C_TSA5522 0xc2
@@ -177,7 +202,7 @@ struct bttv_core {
struct list_head subs; /* struct bttv_sub_device */
/* device config */
- unsigned int nr; /* dev nr (for printk("bttv%d: ..."); */
+ unsigned int nr; /* dev nr (for printk("bttv%d: ..."); */
unsigned int type; /* card type (pointer into tvcards[]) */
char name[8]; /* dev name */
};
@@ -186,16 +211,16 @@ struct bttv;
struct tvcard
{
- char *name;
- unsigned int video_inputs;
- unsigned int audio_inputs;
- unsigned int tuner;
- unsigned int svhs;
+ char *name;
+ unsigned int video_inputs;
+ unsigned int audio_inputs;
+ unsigned int tuner;
+ unsigned int svhs;
unsigned int digital_mode; // DIGITAL_MODE_CAMERA or DIGITAL_MODE_VIDEO
- u32 gpiomask;
- u32 muxsel[16];
- u32 audiomux[6]; /* Tuner, Radio, external, internal, mute, stereo */
- u32 gpiomask2; /* GPIO MUX mask */
+ u32 gpiomask;
+ u32 muxsel[16];
+ u32 audiomux[6]; /* Tuner, Radio, external, internal, mute, stereo */
+ u32 gpiomask2; /* GPIO MUX mask */
/* i2c audio flags */
unsigned int no_msp34xx:1;
@@ -218,6 +243,7 @@ struct tvcard
unsigned int tuner_type;
unsigned int tuner_addr;
+ unsigned int radio_addr;
unsigned int has_radio;
void (*audio_hook)(struct bttv *btv, struct video_audio *v, int set);
@@ -246,7 +272,7 @@ extern int bttv_handle_chipset(struct bttv *btv);
interface below for new code */
/* returns card type + card ID (for bt878-based ones)
- for possible values see lines below beginning with #define BTTV_UNKNOWN
+ for possible values see lines below beginning with #define BTTV_BOARD_UNKNOWN
returns negative value if error occurred
*/
extern int bttv_get_cardinfo(unsigned int card, int *type,
diff --git a/drivers/media/video/bttvp.h b/drivers/media/video/bttvp.h
index 7a312f79340a..386f546f7d11 100644
--- a/drivers/media/video/bttvp.h
+++ b/drivers/media/video/bttvp.h
@@ -77,14 +77,14 @@
struct bttv_tvnorm {
int v4l2_id;
char *name;
- u32 Fsc;
- u16 swidth, sheight; /* scaled standard width, height */
+ u32 Fsc;
+ u16 swidth, sheight; /* scaled standard width, height */
u16 totalwidth;
u8 adelay, bdelay, iform;
u32 scaledtwidth;
u16 hdelayx1, hactivex1;
u16 vdelay;
- u8 vbipack;
+ u8 vbipack;
u16 vtotal;
int sram;
};
@@ -240,7 +240,7 @@ struct bttv_pll_info {
/* for gpio-connected remote control */
struct bttv_input {
- struct input_dev dev;
+ struct input_dev *dev;
struct ir_input_state ir;
char name[32];
char phys[32];
@@ -267,8 +267,8 @@ struct bttv {
/* card configuration info */
unsigned int cardid; /* pci subsystem id (bt878 based ones) */
- unsigned int tuner_type; /* tuner chip type */
- unsigned int pinnacle_id;
+ unsigned int tuner_type; /* tuner chip type */
+ unsigned int pinnacle_id;
unsigned int svhs;
struct bttv_pll_info pll;
int triton1;
@@ -301,9 +301,9 @@ struct bttv {
/* locking */
spinlock_t s_lock;
- struct semaphore lock;
+ struct semaphore lock;
int resources;
- struct semaphore reslock;
+ struct semaphore reslock;
#ifdef VIDIOC_G_PRIORITY
struct v4l2_prio_state prio;
#endif
diff --git a/drivers/media/video/cs53l32a.c b/drivers/media/video/cs53l32a.c
new file mode 100644
index 000000000000..780b352ec119
--- /dev/null
+++ b/drivers/media/video/cs53l32a.c
@@ -0,0 +1,240 @@
+/*
+ * cs53l32a (Adaptec AVC-2010 and AVC-2410) i2c ivtv driver.
+ * Copyright (C) 2005 Martin Vaughan
+ *
+ * Audio source switching for Adaptec AVC-2410 added by Trev Jackson
+ *
+ * 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/module.h>
+#include <linux/types.h>
+#include <linux/ioctl.h>
+#include <asm/uaccess.h>
+#include <linux/i2c.h>
+#include <linux/i2c-id.h>
+#include <linux/videodev.h>
+#include <media/audiochip.h>
+
+MODULE_DESCRIPTION("i2c device driver for cs53l32a Audio ADC");
+MODULE_AUTHOR("Martin Vaughan");
+MODULE_LICENSE("GPL");
+
+static int debug = 0;
+
+module_param(debug, bool, 0644);
+
+MODULE_PARM_DESC(debug, "Debugging messages\n\t\t\t0=Off (default), 1=On");
+
+#define cs53l32a_dbg(fmt, arg...) \
+ do { \
+ if (debug) \
+ printk(KERN_INFO "%s debug %d-%04x: " fmt, client->driver->name, \
+ i2c_adapter_id(client->adapter), client->addr , ## arg); \
+ } while (0)
+
+#define cs53l32a_err(fmt, arg...) do { \
+ printk(KERN_ERR "%s %d-%04x: " fmt, client->driver->name, \
+ i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0)
+#define cs53l32a_info(fmt, arg...) do { \
+ printk(KERN_INFO "%s %d-%04x: " fmt, client->driver->name, \
+ i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0)
+
+static unsigned short normal_i2c[] = { 0x22 >> 1, I2C_CLIENT_END };
+
+
+I2C_CLIENT_INSMOD;
+
+/* ----------------------------------------------------------------------- */
+
+static int cs53l32a_write(struct i2c_client *client, u8 reg, u8 value)
+{
+ return i2c_smbus_write_byte_data(client, reg, value);
+}
+
+static int cs53l32a_read(struct i2c_client *client, u8 reg)
+{
+ return i2c_smbus_read_byte_data(client, reg);
+}
+
+static int cs53l32a_command(struct i2c_client *client, unsigned int cmd,
+ void *arg)
+{
+ int *input = arg;
+
+ switch (cmd) {
+ case AUDC_SET_INPUT:
+ switch (*input) {
+ case AUDIO_TUNER:
+ cs53l32a_write(client, 0x01, 0x01);
+ break;
+ case AUDIO_EXTERN:
+ cs53l32a_write(client, 0x01, 0x21);
+ break;
+ case AUDIO_MUTE:
+ cs53l32a_write(client, 0x03, 0xF0);
+ break;
+ case AUDIO_UNMUTE:
+ cs53l32a_write(client, 0x03, 0x30);
+ break;
+ default:
+ cs53l32a_err("Invalid input %d.\n", *input);
+ return -EINVAL;
+ }
+ break;
+
+ case VIDIOC_S_CTRL:
+ {
+ struct v4l2_control *ctrl = arg;
+
+ if (ctrl->id != V4L2_CID_AUDIO_VOLUME)
+ return -EINVAL;
+ if (ctrl->value > 12 || ctrl->value < -90)
+ return -EINVAL;
+ cs53l32a_write(client, 0x04, (u8) ctrl->value);
+ cs53l32a_write(client, 0x05, (u8) ctrl->value);
+ break;
+ }
+
+ case VIDIOC_LOG_STATUS:
+ {
+ u8 v = cs53l32a_read(client, 0x01);
+ u8 m = cs53l32a_read(client, 0x03);
+
+ cs53l32a_info("Input: %s%s\n",
+ v == 0x21 ? "external line in" : "tuner",
+ (m & 0xC0) ? " (muted)" : "");
+ break;
+ }
+
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+
+/* ----------------------------------------------------------------------- */
+
+/* i2c implementation */
+
+/*
+ * Generic i2c probe
+ * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
+ */
+
+static struct i2c_driver i2c_driver;
+
+static int cs53l32a_attach(struct i2c_adapter *adapter, int address, int kind)
+{
+ struct i2c_client *client;
+ int i;
+
+ /* Check if the adapter supports the needed features */
+ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+ return 0;
+
+ client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
+ if (client == 0)
+ return -ENOMEM;
+
+ memset(client, 0, sizeof(struct i2c_client));
+ client->addr = address;
+ client->adapter = adapter;
+ client->driver = &i2c_driver;
+ client->flags = I2C_CLIENT_ALLOW_USE;
+ snprintf(client->name, sizeof(client->name) - 1, "cs53l32a");
+
+ cs53l32a_info("chip found @ 0x%x (%s)\n", address << 1, adapter->name);
+
+ for (i = 1; i <= 7; i++) {
+ u8 v = cs53l32a_read(client, i);
+
+ cs53l32a_dbg("Read Reg %d %02x\n", i, v);
+ }
+
+ /* Set cs53l32a internal register for Adaptec 2010/2410 setup */
+
+ cs53l32a_write(client, 0x01, (u8) 0x21);
+ cs53l32a_write(client, 0x02, (u8) 0x29);
+ cs53l32a_write(client, 0x03, (u8) 0x30);
+ cs53l32a_write(client, 0x04, (u8) 0x00);
+ cs53l32a_write(client, 0x05, (u8) 0x00);
+ cs53l32a_write(client, 0x06, (u8) 0x00);
+ cs53l32a_write(client, 0x07, (u8) 0x00);
+
+ /* Display results, should be 0x21,0x29,0x30,0x00,0x00,0x00,0x00 */
+
+ for (i = 1; i <= 7; i++) {
+ u8 v = cs53l32a_read(client, i);
+
+ cs53l32a_dbg("Read Reg %d %02x\n", i, v);
+ }
+
+ i2c_attach_client(client);
+
+ return 0;
+}
+
+static int cs53l32a_probe(struct i2c_adapter *adapter)
+{
+#ifdef I2C_CLASS_TV_ANALOG
+ if (adapter->class & I2C_CLASS_TV_ANALOG)
+#else
+ if (adapter->id == I2C_HW_B_BT848)
+#endif
+ return i2c_probe(adapter, &addr_data, cs53l32a_attach);
+ return 0;
+}
+
+static int cs53l32a_detach(struct i2c_client *client)
+{
+ int err;
+
+ err = i2c_detach_client(client);
+ if (err) {
+ return err;
+ }
+ kfree(client);
+
+ return 0;
+}
+
+/* ----------------------------------------------------------------------- */
+
+/* i2c implementation */
+static struct i2c_driver i2c_driver = {
+ .name = "cs53l32a",
+ .id = I2C_DRIVERID_CS53L32A,
+ .flags = I2C_DF_NOTIFY,
+ .attach_adapter = cs53l32a_probe,
+ .detach_client = cs53l32a_detach,
+ .command = cs53l32a_command,
+ .owner = THIS_MODULE,
+};
+
+
+static int __init cs53l32a_init_module(void)
+{
+ return i2c_add_driver(&i2c_driver);
+}
+
+static void __exit cs53l32a_cleanup_module(void)
+{
+ i2c_del_driver(&i2c_driver);
+}
+
+module_init(cs53l32a_init_module);
+module_exit(cs53l32a_cleanup_module);
diff --git a/drivers/media/video/cx88/Kconfig b/drivers/media/video/cx88/Kconfig
new file mode 100644
index 000000000000..41818b6205b3
--- /dev/null
+++ b/drivers/media/video/cx88/Kconfig
@@ -0,0 +1,91 @@
+config VIDEO_CX88
+ tristate "Conexant 2388x (bt878 successor) support"
+ depends on VIDEO_DEV && PCI && I2C
+ select I2C_ALGOBIT
+ select FW_LOADER
+ select VIDEO_BTCX
+ select VIDEO_BUF
+ select VIDEO_TUNER
+ select VIDEO_TVEEPROM
+ select VIDEO_IR
+ ---help---
+ This is a video4linux driver for Conexant 2388x based
+ TV cards.
+
+ To compile this driver as a module, choose M here: the
+ module will be called cx8800
+
+config VIDEO_CX88_DVB
+ tristate "DVB/ATSC Support for cx2388x based TV cards"
+ depends on VIDEO_CX88 && DVB_CORE
+ select VIDEO_BUF_DVB
+ ---help---
+ This adds support for DVB/ATSC cards based on the
+ Connexant 2388x chip.
+
+ To compile this driver as a module, choose M here: the
+ module will be called cx88-dvb.
+
+ You must also select one or more DVB/ATSC demodulators.
+ If you are unsure which you need, choose all of them.
+
+config VIDEO_CX88_DVB_ALL_FRONTENDS
+ bool "Build all supported frontends for cx2388x based TV cards"
+ default y
+ depends on VIDEO_CX88_DVB
+ select DVB_MT352
+ select DVB_OR51132
+ select DVB_CX22702
+ select DVB_LGDT330X
+ select DVB_NXT200X
+ ---help---
+ This builds cx88-dvb with all currently supported frontend
+ demodulators. If you wish to tweak your configuration, and
+ only include support for the hardware that you need, choose N here.
+
+ If you are unsure, choose Y.
+
+config VIDEO_CX88_DVB_MT352
+ tristate "Zarlink MT352 DVB-T Support"
+ default m
+ depends on VIDEO_CX88_DVB && !VIDEO_CX88_DVB_ALL_FRONTENDS
+ select DVB_MT352
+ ---help---
+ This adds DVB-T support for cards based on the
+ Connexant 2388x chip and the MT352 demodulator.
+
+config VIDEO_CX88_DVB_OR51132
+ tristate "OR51132 ATSC Support"
+ default m
+ depends on VIDEO_CX88_DVB && !VIDEO_CX88_DVB_ALL_FRONTENDS
+ select DVB_OR51132
+ ---help---
+ This adds ATSC 8VSB and QAM64/256 support for cards based on the
+ Connexant 2388x chip and the OR51132 demodulator.
+
+config VIDEO_CX88_DVB_CX22702
+ tristate "Conexant CX22702 DVB-T Support"
+ default m
+ depends on VIDEO_CX88_DVB && !VIDEO_CX88_DVB_ALL_FRONTENDS
+ select DVB_CX22702
+ ---help---
+ This adds DVB-T support for cards based on the
+ Connexant 2388x chip and the CX22702 demodulator.
+
+config VIDEO_CX88_DVB_LGDT330X
+ tristate "LG Electronics DT3302/DT3303 ATSC Support"
+ default m
+ depends on VIDEO_CX88_DVB && !VIDEO_CX88_DVB_ALL_FRONTENDS
+ select DVB_LGDT330X
+ ---help---
+ This adds ATSC 8VSB and QAM64/256 support for cards based on the
+ Connexant 2388x chip and the LGDT3302/LGDT3303 demodulator.
+
+config VIDEO_CX88_DVB_NXT200X
+ tristate "NXT2002/NXT2004 ATSC Support"
+ default m
+ depends on VIDEO_CX88_DVB && !VIDEO_CX88_DVB_ALL_FRONTENDS
+ select DVB_NXT200X
+ ---help---
+ This adds ATSC 8VSB and QAM64/256 support for cards based on the
+ Connexant 2388x chip and the NXT2002/NXT2004 demodulator.
diff --git a/drivers/media/video/cx88/Makefile b/drivers/media/video/cx88/Makefile
index 107e48645e3a..0df40b773454 100644
--- a/drivers/media/video/cx88/Makefile
+++ b/drivers/media/video/cx88/Makefile
@@ -9,6 +9,9 @@ obj-$(CONFIG_VIDEO_CX88_DVB) += cx88-dvb.o
EXTRA_CFLAGS += -I$(src)/..
EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/dvb-core
EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/frontends
+ifneq ($(CONFIG_VIDEO_BUF_DVB),n)
+ EXTRA_CFLAGS += -DHAVE_VIDEO_BUF_DVB=1
+endif
ifneq ($(CONFIG_DVB_CX22702),n)
EXTRA_CFLAGS += -DHAVE_CX22702=1
endif
@@ -21,3 +24,6 @@ endif
ifneq ($(CONFIG_DVB_MT352),n)
EXTRA_CFLAGS += -DHAVE_MT352=1
endif
+ifneq ($(CONFIG_DVB_NXT200X),n)
+ EXTRA_CFLAGS += -DHAVE_NXT200X=1
+endif
diff --git a/drivers/media/video/cx88/cx88-blackbird.c b/drivers/media/video/cx88/cx88-blackbird.c
index 0c0c59e94774..4ae3f78cccf2 100644
--- a/drivers/media/video/cx88/cx88-blackbird.c
+++ b/drivers/media/video/cx88/cx88-blackbird.c
@@ -38,7 +38,7 @@ MODULE_AUTHOR("Jelle Foks <jelle@foks.8m.com>");
MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
MODULE_LICENSE("GPL");
-static unsigned int mpegbufs = 8;
+static unsigned int mpegbufs = 32;
module_param(mpegbufs,int,0644);
MODULE_PARM_DESC(mpegbufs,"number of mpeg buffers, range 2-32");
@@ -436,7 +436,7 @@ static int memory_write(struct cx88_core *core, u32 address, u32 value)
static int memory_read(struct cx88_core *core, u32 address, u32 *value)
{
- int retval;
+ int retval;
u32 val;
/* Warning: address is dword address (4 bytes) */
@@ -605,11 +605,11 @@ static int blackbird_load_firmware(struct cx8802_dev *dev)
u32 *dataptr;
retval = register_write(dev->core, IVTV_REG_VPU, 0xFFFFFFED);
- retval |= register_write(dev->core, IVTV_REG_HW_BLOCKS, IVTV_CMD_HW_BLOCKS_RST);
- retval |= register_write(dev->core, IVTV_REG_ENC_SDRAM_REFRESH, 0x80000640);
- retval |= register_write(dev->core, IVTV_REG_ENC_SDRAM_PRECHARGE, 0x1A);
+ retval |= register_write(dev->core, IVTV_REG_HW_BLOCKS, IVTV_CMD_HW_BLOCKS_RST);
+ retval |= register_write(dev->core, IVTV_REG_ENC_SDRAM_REFRESH, 0x80000640);
+ retval |= register_write(dev->core, IVTV_REG_ENC_SDRAM_PRECHARGE, 0x1A);
msleep(1);
- retval |= register_write(dev->core, IVTV_REG_APU, 0);
+ retval |= register_write(dev->core, IVTV_REG_APU, 0);
if (retval < 0)
dprintk(0, "Error with register_write\n");
@@ -657,13 +657,13 @@ static int blackbird_load_firmware(struct cx8802_dev *dev)
release_firmware(firmware);
dprintk(0, "Firmware upload successful.\n");
- retval |= register_write(dev->core, IVTV_REG_HW_BLOCKS, IVTV_CMD_HW_BLOCKS_RST);
- retval |= register_read(dev->core, IVTV_REG_SPU, &value);
- retval |= register_write(dev->core, IVTV_REG_SPU, value & 0xFFFFFFFE);
+ retval |= register_write(dev->core, IVTV_REG_HW_BLOCKS, IVTV_CMD_HW_BLOCKS_RST);
+ retval |= register_read(dev->core, IVTV_REG_SPU, &value);
+ retval |= register_write(dev->core, IVTV_REG_SPU, value & 0xFFFFFFFE);
msleep(1);
retval |= register_read(dev->core, IVTV_REG_VPU, &value);
- retval |= register_write(dev->core, IVTV_REG_VPU, value & 0xFFFFFFE8);
+ retval |= register_write(dev->core, IVTV_REG_VPU, value & 0xFFFFFFE8);
if (retval < 0)
dprintk(0, "Error with register_write\n");
@@ -683,84 +683,560 @@ DB* DVD | MPEG2 | 720x576PAL | CBR | 600 :Good | 6000 Kbps | 25fps | M
=================================================================================================================
*DB: "DirectBurn"
*/
-static void blackbird_codec_settings(struct cx8802_dev *dev)
+
+static struct blackbird_dnr default_dnr_params = {
+ .mode = BLACKBIRD_DNR_BITS_MANUAL,
+ .type = BLACKBIRD_MEDIAN_FILTER_DISABLED,
+ .spatial = 0,
+ .temporal = 0
+};
+static struct v4l2_mpeg_compression default_mpeg_params = {
+ .st_type = V4L2_MPEG_PS_2,
+ .st_bitrate = {
+ .mode = V4L2_BITRATE_CBR,
+ .min = 0,
+ .target = 0,
+ .max = 0
+ },
+ .ts_pid_pmt = 16,
+ .ts_pid_audio = 260,
+ .ts_pid_video = 256,
+ .ts_pid_pcr = 259,
+ .ps_size = 0,
+ .au_type = V4L2_MPEG_AU_2_II,
+ .au_bitrate = {
+ .mode = V4L2_BITRATE_CBR,
+ .min = 224,
+ .target = 224,
+ .max = 224
+ },
+ .au_sample_rate = 44100,
+ .au_pesid = 0,
+ .vi_type = V4L2_MPEG_VI_2,
+ .vi_aspect_ratio = V4L2_MPEG_ASPECT_4_3,
+ .vi_bitrate = {
+ .mode = V4L2_BITRATE_CBR,
+ .min = 4000,
+ .target = 4500,
+ .max = 6000
+ },
+ .vi_frame_rate = 25,
+ .vi_frames_per_gop = 15,
+ .vi_bframes_count = 2,
+ .vi_pesid = 0,
+ .closed_gops = 0,
+ .pulldown = 0
+};
+
+static enum blackbird_stream_type mpeg_stream_types[] = {
+ [V4L2_MPEG_SS_1] = BLACKBIRD_STREAM_MPEG1,
+ [V4L2_MPEG_PS_2] = BLACKBIRD_STREAM_PROGRAM,
+ [V4L2_MPEG_TS_2] = BLACKBIRD_STREAM_TRANSPORT,
+ [V4L2_MPEG_PS_DVD] = BLACKBIRD_STREAM_DVD,
+};
+static enum blackbird_aspect_ratio mpeg_stream_ratios[] = {
+ [V4L2_MPEG_ASPECT_SQUARE] = BLACKBIRD_ASPECT_RATIO_1_1_SQUARE,
+ [V4L2_MPEG_ASPECT_4_3] = BLACKBIRD_ASPECT_RATIO_4_3,
+ [V4L2_MPEG_ASPECT_16_9] = BLACKBIRD_ASPECT_RATIO_16_9,
+ [V4L2_MPEG_ASPECT_1_221] = BLACKBIRD_ASPECT_RATIO_221_100,
+};
+static enum blackbird_video_bitrate_type mpeg_video_bitrates[] = {
+ [V4L2_BITRATE_NONE] = BLACKBIRD_VIDEO_CBR,
+ [V4L2_BITRATE_CBR] = BLACKBIRD_VIDEO_CBR,
+ [V4L2_BITRATE_VBR] = BLACKBIRD_VIDEO_VBR,
+};
+/* find the best layer I/II bitrate to fit a given numeric value */
+struct bitrate_bits {
+ u32 bits; /* layer bits for the best fit */
+ u32 rate; /* actual numeric value for the layer best fit */
+};
+struct bitrate_approximation {
+ u32 target; /* numeric value of the rate we want */
+ struct bitrate_bits layer[2];
+};
+static struct bitrate_approximation mpeg_audio_bitrates[] = {
+ /* target layer[0].bits layer[0].rate layer[1].bits layer[1].rate */
+ { 0, { { 0, 0, }, { 0, 0, }, }, },
+ { 32, { { BLACKBIRD_AUDIO_BITS_LAYER_1_32 , 32, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_32 , 32, }, }, },
+ { 48, { { BLACKBIRD_AUDIO_BITS_LAYER_1_64 , 64, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_48 , 48, }, }, },
+ { 56, { { BLACKBIRD_AUDIO_BITS_LAYER_1_64 , 64, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_56 , 56, }, }, },
+ { 64, { { BLACKBIRD_AUDIO_BITS_LAYER_1_64 , 64, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_64 , 64, }, }, },
+ { 80, { { BLACKBIRD_AUDIO_BITS_LAYER_1_96 , 96, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_80 , 80, }, }, },
+ { 96, { { BLACKBIRD_AUDIO_BITS_LAYER_1_96 , 96, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_96 , 96, }, }, },
+ { 112, { { BLACKBIRD_AUDIO_BITS_LAYER_1_128, 128, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_112, 112, }, }, },
+ { 128, { { BLACKBIRD_AUDIO_BITS_LAYER_1_128, 128, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_128, 128, }, }, },
+ { 160, { { BLACKBIRD_AUDIO_BITS_LAYER_1_160, 160, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_160, 160, }, }, },
+ { 192, { { BLACKBIRD_AUDIO_BITS_LAYER_1_192, 192, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_192, 192, }, }, },
+ { 224, { { BLACKBIRD_AUDIO_BITS_LAYER_1_224, 224, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_224, 224, }, }, },
+ { 256, { { BLACKBIRD_AUDIO_BITS_LAYER_1_256, 256, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_256, 256, }, }, },
+ { 288, { { BLACKBIRD_AUDIO_BITS_LAYER_1_288, 288, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_320, 320, }, }, },
+ { 320, { { BLACKBIRD_AUDIO_BITS_LAYER_1_320, 320, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_320, 320, }, }, },
+ { 352, { { BLACKBIRD_AUDIO_BITS_LAYER_1_352, 352, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_384, 384, }, }, },
+ { 384, { { BLACKBIRD_AUDIO_BITS_LAYER_1_384, 384, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_384, 384, }, }, },
+ { 416, { { BLACKBIRD_AUDIO_BITS_LAYER_1_416, 416, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_384, 384, }, }, },
+ { 448, { { BLACKBIRD_AUDIO_BITS_LAYER_1_448, 448, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_384, 384, }, }, },
+};
+static const int BITRATES_SIZE = ARRAY_SIZE(mpeg_audio_bitrates);
+
+static void blackbird_set_default_params(struct cx8802_dev *dev)
{
- int bitrate_mode = 1;
- int bitrate = 7500000;
- int bitrate_peak = 7500000;
- bitrate_mode = BLACKBIRD_VIDEO_CBR;
- bitrate = 4000*1024;
- bitrate_peak = 4000*1024;
+ struct v4l2_mpeg_compression *params = &dev->params;
+ u32 au_params;
/* assign stream type */
- blackbird_api_cmd(dev, BLACKBIRD_API_SET_STREAM_TYPE, 1, 0, BLACKBIRD_STREAM_PROGRAM);
-
- /* assign output port */
- blackbird_api_cmd(dev, BLACKBIRD_API_SET_OUTPUT_PORT, 1, 0, BLACKBIRD_OUTPUT_PORT_STREAMING); /* Host */
+ if( params->st_type >= ARRAY_SIZE(mpeg_stream_types) )
+ params->st_type = V4L2_MPEG_PS_2;
+ if( params->st_type == V4L2_MPEG_SS_1 )
+ params->vi_type = V4L2_MPEG_VI_1;
+ else
+ params->vi_type = V4L2_MPEG_VI_2;
+ blackbird_api_cmd(dev, BLACKBIRD_API_SET_STREAM_TYPE, 1, 0, mpeg_stream_types[params->st_type]);
/* assign framerate */
- blackbird_api_cmd(dev, BLACKBIRD_API_SET_FRAMERATE, 1, 0, BLACKBIRD_FRAMERATE_PAL_25);
-
- /* assign frame size */
- blackbird_api_cmd(dev, BLACKBIRD_API_SET_RESOLUTION, 2, 0,
- dev->height, dev->width);
+ if( params->vi_frame_rate <= 25 )
+ {
+ params->vi_frame_rate = 25;
+ blackbird_api_cmd(dev, BLACKBIRD_API_SET_FRAMERATE, 1, 0, BLACKBIRD_FRAMERATE_PAL_25);
+ }
+ else
+ {
+ params->vi_frame_rate = 30;
+ blackbird_api_cmd(dev, BLACKBIRD_API_SET_FRAMERATE, 1, 0, BLACKBIRD_FRAMERATE_NTSC_30);
+ }
/* assign aspect ratio */
- blackbird_api_cmd(dev, BLACKBIRD_API_SET_ASPECT_RATIO, 1, 0, BLACKBIRD_ASPECT_RATIO_4_3);
-
- /* assign bitrates */
- blackbird_api_cmd(dev, BLACKBIRD_API_SET_VIDEO_BITRATE, 5, 0,
- bitrate_mode, /* mode */
- bitrate, /* bps */
- bitrate_peak / BLACKBIRD_PEAK_RATE_DIVISOR, /* peak/400 */
- BLACKBIRD_MUX_RATE_DEFAULT /*, 0x70*/); /* encoding buffer, ckennedy */
+ if( params->vi_aspect_ratio >= ARRAY_SIZE(mpeg_stream_ratios) )
+ params->vi_aspect_ratio = V4L2_MPEG_ASPECT_4_3;
+ blackbird_api_cmd(dev, BLACKBIRD_API_SET_ASPECT_RATIO, 1, 0, mpeg_stream_ratios[params->vi_aspect_ratio]);
/* assign gop properties */
- blackbird_api_cmd(dev, BLACKBIRD_API_SET_GOP_STRUCTURE, 2, 0, 15, 3);
+ blackbird_api_cmd(dev, BLACKBIRD_API_SET_GOP_STRUCTURE, 2, 0, params->vi_frames_per_gop, params->vi_bframes_count+1);
+
+ /* assign gop closure */
+ blackbird_api_cmd(dev, BLACKBIRD_API_SET_GOP_CLOSURE, 1, 0, params->closed_gops);
/* assign 3 2 pulldown */
- blackbird_api_cmd(dev, BLACKBIRD_API_SET_3_2_PULLDOWN, 1, 0, BLACKBIRD_3_2_PULLDOWN_DISABLED);
+ blackbird_api_cmd(dev, BLACKBIRD_API_SET_3_2_PULLDOWN, 1, 0, params->pulldown);
+
+ /* make sure the params are within bounds */
+ if( params->st_bitrate.mode >= ARRAY_SIZE(mpeg_video_bitrates) )
+ params->vi_bitrate.mode = V4L2_BITRATE_NONE;
+ if( params->vi_bitrate.mode >= ARRAY_SIZE(mpeg_video_bitrates) )
+ params->vi_bitrate.mode = V4L2_BITRATE_NONE;
+ if( params->au_bitrate.mode >= ARRAY_SIZE(mpeg_video_bitrates) )
+ params->au_bitrate.mode = V4L2_BITRATE_NONE;
/* assign audio properties */
/* note: it's not necessary to set the samplerate, the mpeg encoder seems to autodetect/adjust */
- /* blackbird_api_cmd(dev, IVTV_API_ASSIGN_AUDIO_PROPERTIES, 1, 0, (2<<2) | (8<<4));
- blackbird_api_cmd(dev, IVTV_API_ASSIGN_AUDIO_PROPERTIES, 1, 0, 0 | (2 << 2) | (14 << 4)); */
- blackbird_api_cmd(dev, BLACKBIRD_API_SET_AUDIO_PARAMS, 1, 0,
- BLACKBIRD_AUDIO_BITS_44100HZ |
- BLACKBIRD_AUDIO_BITS_LAYER_2 |
- BLACKBIRD_AUDIO_BITS_LAYER_2_224 |
- BLACKBIRD_AUDIO_BITS_STEREO |
+ au_params = BLACKBIRD_AUDIO_BITS_STEREO |
/* BLACKBIRD_AUDIO_BITS_BOUND_4 | */
BLACKBIRD_AUDIO_BITS_EMPHASIS_NONE |
BLACKBIRD_AUDIO_BITS_CRC_OFF |
BLACKBIRD_AUDIO_BITS_COPYRIGHT_OFF |
- BLACKBIRD_AUDIO_BITS_COPY
- );
+ BLACKBIRD_AUDIO_BITS_COPY |
+ 0;
+ if( params->au_sample_rate <= 32000 )
+ {
+ params->au_sample_rate = 32000;
+ au_params |= BLACKBIRD_AUDIO_BITS_32000HZ;
+ }
+ else if( params->au_sample_rate <= 44100 )
+ {
+ params->au_sample_rate = 44100;
+ au_params |= BLACKBIRD_AUDIO_BITS_44100HZ;
+ }
+ else
+ {
+ params->au_sample_rate = 48000;
+ au_params |= BLACKBIRD_AUDIO_BITS_48000HZ;
+ }
+ if( params->au_type == V4L2_MPEG_AU_2_I )
+ {
+ au_params |= BLACKBIRD_AUDIO_BITS_LAYER_1;
+ }
+ else
+ {
+ /* TODO: try to handle the other formats more gracefully */
+ params->au_type = V4L2_MPEG_AU_2_II;
+ au_params |= BLACKBIRD_AUDIO_BITS_LAYER_2;
+ }
+ if( params->au_bitrate.mode )
+ {
+ int layer;
+
+ if( params->au_bitrate.mode == V4L2_BITRATE_CBR )
+ params->au_bitrate.max = params->vi_bitrate.target;
+ else
+ params->au_bitrate.target = params->vi_bitrate.max;
+
+ layer = params->au_type;
+ if( params->au_bitrate.target == 0 )
+ {
+ /* TODO: use the minimum possible bitrate instead of 0 ? */
+ au_params |= 0;
+ }
+ else if( params->au_bitrate.target >=
+ mpeg_audio_bitrates[BITRATES_SIZE-1].layer[layer].rate )
+ {
+ /* clamp the bitrate to the max supported by the standard */
+ params->au_bitrate.target = mpeg_audio_bitrates[BITRATES_SIZE-1].layer[layer].rate;
+ params->au_bitrate.max = params->au_bitrate.target;
+ au_params |= mpeg_audio_bitrates[BITRATES_SIZE-1].layer[layer].bits;
+ }
+ else
+ {
+ /* round up to the nearest supported bitrate */
+ int i;
+ for(i = 1; i < BITRATES_SIZE; i++)
+ {
+ if( params->au_bitrate.target > mpeg_audio_bitrates[i-1].layer[layer].rate &&
+ params->au_bitrate.target <= mpeg_audio_bitrates[i].layer[layer].rate )
+ {
+ params->au_bitrate.target = mpeg_audio_bitrates[i].layer[layer].rate;
+ params->au_bitrate.max = params->au_bitrate.target;
+ au_params |= mpeg_audio_bitrates[i].layer[layer].bits;
+ break;
+ }
+ }
+ }
+ }
+ else
+ {
+ /* TODO: ??? */
+ params->au_bitrate.target = params->au_bitrate.max = 0;
+ au_params |= 0;
+ }
+ blackbird_api_cmd(dev, BLACKBIRD_API_SET_AUDIO_PARAMS, 1, 0, au_params );
+
+ /* assign bitrates */
+ if( params->vi_bitrate.mode )
+ {
+ /* bitrate is set, let's figure out the cbr/vbr mess */
+ if( params->vi_bitrate.max < params->vi_bitrate.target )
+ {
+ if( params->vi_bitrate.mode == V4L2_BITRATE_CBR )
+ params->vi_bitrate.max = params->vi_bitrate.target;
+ else
+ params->vi_bitrate.target = params->vi_bitrate.max;
+ }
+ }
+ else
+ {
+ if( params->st_bitrate.max < params->st_bitrate.target )
+ {
+ if( params->st_bitrate.mode == V4L2_BITRATE_VBR )
+ params->st_bitrate.target = params->st_bitrate.max;
+ else
+ params->st_bitrate.max = params->st_bitrate.target;
+ }
+ /* calculate vi_bitrate = st_bitrate - au_bitrate */
+ params->vi_bitrate.max = params->st_bitrate.max - params->au_bitrate.max;
+ params->vi_bitrate.target = params->st_bitrate.target - params->au_bitrate.target;
+ }
+ blackbird_api_cmd(dev, BLACKBIRD_API_SET_VIDEO_BITRATE, 4, 0,
+ mpeg_video_bitrates[params->vi_bitrate.mode],
+ params->vi_bitrate.target * 1000, /* kbps -> bps */
+ params->vi_bitrate.max * 1000 / BLACKBIRD_PEAK_RATE_DIVISOR, /* peak/400 */
+ BLACKBIRD_MUX_RATE_DEFAULT /*, 0x70*/); /* encoding buffer, ckennedy */
+
+ /* TODO: implement the stream ID stuff:
+ ts_pid_pmt, ts_pid_audio, ts_pid_video, ts_pid_pcr,
+ ps_size, au_pesid, vi_pesid
+ */
+}
+#define CHECK_PARAM( name ) ( dev->params.name != params->name )
+#define IF_PARAM( name ) if( CHECK_PARAM( name ) )
+#define UPDATE_PARAM( name ) dev->params.name = params->name
+void blackbird_set_params(struct cx8802_dev *dev, struct v4l2_mpeg_compression *params)
+{
+ u32 au_params;
+
+ /* assign stream type */
+ if( params->st_type >= ARRAY_SIZE(mpeg_stream_types) )
+ params->st_type = V4L2_MPEG_PS_2;
+ if( params->st_type == V4L2_MPEG_SS_1 )
+ params->vi_type = V4L2_MPEG_VI_1;
+ else
+ params->vi_type = V4L2_MPEG_VI_2;
+ if( CHECK_PARAM( st_type ) || CHECK_PARAM( vi_type ) )
+ {
+ UPDATE_PARAM( st_type );
+ UPDATE_PARAM( vi_type );
+ blackbird_api_cmd(dev, BLACKBIRD_API_SET_STREAM_TYPE, 1, 0, mpeg_stream_types[params->st_type]);
+ }
+
+ /* assign framerate */
+ if( params->vi_frame_rate <= 25 )
+ params->vi_frame_rate = 25;
+ else
+ params->vi_frame_rate = 30;
+ IF_PARAM( vi_frame_rate )
+ {
+ UPDATE_PARAM( vi_frame_rate );
+ if( params->vi_frame_rate == 25 )
+ blackbird_api_cmd(dev, BLACKBIRD_API_SET_FRAMERATE, 1, 0, BLACKBIRD_FRAMERATE_PAL_25);
+ else
+ blackbird_api_cmd(dev, BLACKBIRD_API_SET_FRAMERATE, 1, 0, BLACKBIRD_FRAMERATE_NTSC_30);
+ }
+
+ /* assign aspect ratio */
+ if( params->vi_aspect_ratio >= ARRAY_SIZE(mpeg_stream_ratios) )
+ params->vi_aspect_ratio = V4L2_MPEG_ASPECT_4_3;
+ IF_PARAM( vi_aspect_ratio )
+ {
+ UPDATE_PARAM( vi_aspect_ratio );
+ blackbird_api_cmd(dev, BLACKBIRD_API_SET_ASPECT_RATIO, 1, 0, mpeg_stream_ratios[params->vi_aspect_ratio]);
+ }
+
+ /* assign gop properties */
+ if( CHECK_PARAM( vi_frames_per_gop ) || CHECK_PARAM( vi_bframes_count ) )
+ {
+ UPDATE_PARAM( vi_frames_per_gop );
+ UPDATE_PARAM( vi_bframes_count );
+ blackbird_api_cmd(dev, BLACKBIRD_API_SET_GOP_STRUCTURE, 2, 0, params->vi_frames_per_gop, params->vi_bframes_count+1);
+ }
/* assign gop closure */
- blackbird_api_cmd(dev, BLACKBIRD_API_SET_GOP_CLOSURE, 1, 0, BLACKBIRD_GOP_CLOSURE_OFF);
+ IF_PARAM( closed_gops )
+ {
+ UPDATE_PARAM( closed_gops );
+ blackbird_api_cmd(dev, BLACKBIRD_API_SET_GOP_CLOSURE, 1, 0, params->closed_gops);
+ }
+
+ /* assign 3 2 pulldown */
+ IF_PARAM( pulldown )
+ {
+ UPDATE_PARAM( pulldown );
+ blackbird_api_cmd(dev, BLACKBIRD_API_SET_3_2_PULLDOWN, 1, 0, params->pulldown);
+ }
+
+ /* make sure the params are within bounds */
+ if( params->st_bitrate.mode >= ARRAY_SIZE(mpeg_video_bitrates) )
+ params->vi_bitrate.mode = V4L2_BITRATE_NONE;
+ if( params->vi_bitrate.mode >= ARRAY_SIZE(mpeg_video_bitrates) )
+ params->vi_bitrate.mode = V4L2_BITRATE_NONE;
+ if( params->au_bitrate.mode >= ARRAY_SIZE(mpeg_video_bitrates) )
+ params->au_bitrate.mode = V4L2_BITRATE_NONE;
+
+ /* assign audio properties */
+ /* note: it's not necessary to set the samplerate, the mpeg encoder seems to autodetect/adjust */
+ au_params = BLACKBIRD_AUDIO_BITS_STEREO |
+ /* BLACKBIRD_AUDIO_BITS_BOUND_4 | */
+ BLACKBIRD_AUDIO_BITS_EMPHASIS_NONE |
+ BLACKBIRD_AUDIO_BITS_CRC_OFF |
+ BLACKBIRD_AUDIO_BITS_COPYRIGHT_OFF |
+ BLACKBIRD_AUDIO_BITS_COPY |
+ 0;
+ if( params->au_sample_rate < 32000 )
+ {
+ params->au_sample_rate = 32000;
+ au_params |= BLACKBIRD_AUDIO_BITS_32000HZ;
+ }
+ else if( params->au_sample_rate < 44100 )
+ {
+ params->au_sample_rate = 44100;
+ au_params |= BLACKBIRD_AUDIO_BITS_44100HZ;
+ }
+ else
+ {
+ params->au_sample_rate = 48000;
+ au_params |= BLACKBIRD_AUDIO_BITS_48000HZ;
+ }
+ if( params->au_type == V4L2_MPEG_AU_2_I )
+ {
+ au_params |= BLACKBIRD_AUDIO_BITS_LAYER_1;
+ }
+ else
+ {
+ /* TODO: try to handle the other formats more gracefully */
+ params->au_type = V4L2_MPEG_AU_2_II;
+ au_params |= BLACKBIRD_AUDIO_BITS_LAYER_2;
+ }
+ if( params->au_bitrate.mode )
+ {
+ int layer;
+
+ if( params->au_bitrate.mode == V4L2_BITRATE_CBR )
+ params->au_bitrate.max = params->vi_bitrate.target;
+ else
+ params->au_bitrate.target = params->vi_bitrate.max;
+
+ layer = params->au_type;
+ if( params->au_bitrate.target == 0 )
+ {
+ /* TODO: use the minimum possible bitrate instead of 0 ? */
+ au_params |= 0;
+ }
+ else if( params->au_bitrate.target >=
+ mpeg_audio_bitrates[BITRATES_SIZE-1].layer[layer].rate )
+ {
+ /* clamp the bitrate to the max supported by the standard */
+ params->au_bitrate.target = mpeg_audio_bitrates[BITRATES_SIZE-1].layer[layer].rate;
+ params->au_bitrate.max = params->au_bitrate.target;
+ au_params |= mpeg_audio_bitrates[BITRATES_SIZE-1].layer[layer].bits;
+ }
+ else
+ {
+ /* round up to the nearest supported bitrate */
+ int i;
+ for(i = 1; i < BITRATES_SIZE; i++)
+ {
+ if( params->au_bitrate.target > mpeg_audio_bitrates[i-1].layer[layer].rate &&
+ params->au_bitrate.target <= mpeg_audio_bitrates[i].layer[layer].rate )
+ {
+ params->au_bitrate.target = mpeg_audio_bitrates[i].layer[layer].rate;
+ params->au_bitrate.max = params->au_bitrate.target;
+ au_params |= mpeg_audio_bitrates[i].layer[layer].bits;
+ break;
+ }
+ }
+ }
+ }
+ else
+ {
+ /* TODO: ??? */
+ params->au_bitrate.target = params->au_bitrate.max = 0;
+ au_params |= 0;
+ }
+ if( CHECK_PARAM( au_type ) || CHECK_PARAM( au_sample_rate )
+ || CHECK_PARAM( au_bitrate.mode ) || CHECK_PARAM( au_bitrate.max )
+ || CHECK_PARAM( au_bitrate.target )
+ )
+ {
+ UPDATE_PARAM( au_type );
+ UPDATE_PARAM( au_sample_rate );
+ UPDATE_PARAM( au_bitrate );
+ blackbird_api_cmd(dev, BLACKBIRD_API_SET_AUDIO_PARAMS, 1, 0, au_params );
+ }
+
+ /* assign bitrates */
+ if( params->vi_bitrate.mode )
+ {
+ /* bitrate is set, let's figure out the cbr/vbr mess */
+ if( params->vi_bitrate.max < params->vi_bitrate.target )
+ {
+ if( params->vi_bitrate.mode == V4L2_BITRATE_CBR )
+ params->vi_bitrate.max = params->vi_bitrate.target;
+ else
+ params->vi_bitrate.target = params->vi_bitrate.max;
+ }
+ }
+ else
+ {
+ if( params->st_bitrate.max < params->st_bitrate.target )
+ {
+ if( params->st_bitrate.mode == V4L2_BITRATE_VBR )
+ params->st_bitrate.target = params->st_bitrate.max;
+ else
+ params->st_bitrate.max = params->st_bitrate.target;
+ }
+ /* calculate vi_bitrate = st_bitrate - au_bitrate */
+ params->vi_bitrate.max = params->st_bitrate.max - params->au_bitrate.max;
+ params->vi_bitrate.target = params->st_bitrate.target - params->au_bitrate.target;
+ }
+ UPDATE_PARAM( st_bitrate );
+ if( CHECK_PARAM( vi_bitrate.mode ) || CHECK_PARAM( vi_bitrate.max )
+ || CHECK_PARAM( vi_bitrate.target )
+ )
+ {
+ UPDATE_PARAM( vi_bitrate );
+ blackbird_api_cmd(dev, BLACKBIRD_API_SET_VIDEO_BITRATE, 4, 0,
+ mpeg_video_bitrates[params->vi_bitrate.mode],
+ params->vi_bitrate.target * 1000, /* kbps -> bps */
+ params->vi_bitrate.max * 1000 / BLACKBIRD_PEAK_RATE_DIVISOR, /* peak/400 */
+ BLACKBIRD_MUX_RATE_DEFAULT /*, 0x70*/); /* encoding buffer, ckennedy */
+ }
+ /* TODO: implement the stream ID stuff:
+ ts_pid_pmt, ts_pid_audio, ts_pid_video, ts_pid_pcr,
+ ps_size, au_pesid, vi_pesid
+ */
+ UPDATE_PARAM( ts_pid_pmt );
+ UPDATE_PARAM( ts_pid_audio );
+ UPDATE_PARAM( ts_pid_video );
+ UPDATE_PARAM( ts_pid_pcr );
+ UPDATE_PARAM( ps_size );
+ UPDATE_PARAM( au_pesid );
+ UPDATE_PARAM( vi_pesid );
+}
+static void blackbird_set_default_dnr_params(struct cx8802_dev *dev)
+{
/* assign dnr filter mode */
+ if( dev->dnr_params.mode > BLACKBIRD_DNR_BITS_AUTO )
+ dev->dnr_params.mode = BLACKBIRD_DNR_BITS_MANUAL;
+ if( dev->dnr_params.type > BLACKBIRD_MEDIAN_FILTER_DIAGONAL )
+ dev->dnr_params.type = BLACKBIRD_MEDIAN_FILTER_DISABLED;
blackbird_api_cmd(dev, BLACKBIRD_API_SET_DNR_MODE, 2, 0,
- BLACKBIRD_DNR_BITS_MANUAL,
- BLACKBIRD_MEDIAN_FILTER_DISABLED
- );
+ dev->dnr_params.mode,
+ dev->dnr_params.type
+ );
/* assign dnr filter props*/
- blackbird_api_cmd(dev, BLACKBIRD_API_SET_MANUAL_DNR, 2, 0, 0, 0);
+ if( dev->dnr_params.spatial > 15 )
+ dev->dnr_params.spatial = 15;
+ if( dev->dnr_params.temporal > 31 )
+ dev->dnr_params.temporal = 31;
+ blackbird_api_cmd(dev, BLACKBIRD_API_SET_MANUAL_DNR, 2, 0,
+ dev->dnr_params.spatial,
+ dev->dnr_params.temporal
+ );
+}
+#define CHECK_DNR_PARAM( name ) ( dev->dnr_params.name != dnr_params->name )
+#define UPDATE_DNR_PARAM( name ) dev->dnr_params.name = dnr_params->name
+void blackbird_set_dnr_params(struct cx8802_dev *dev, struct blackbird_dnr* dnr_params)
+{
+ /* assign dnr filter mode */
+ /* clamp values */
+ if( dnr_params->mode > BLACKBIRD_DNR_BITS_AUTO )
+ dnr_params->mode = BLACKBIRD_DNR_BITS_MANUAL;
+ if( dnr_params->type > BLACKBIRD_MEDIAN_FILTER_DIAGONAL )
+ dnr_params->type = BLACKBIRD_MEDIAN_FILTER_DISABLED;
+ /* check if the params actually changed */
+ if( CHECK_DNR_PARAM( mode ) || CHECK_DNR_PARAM( type ) )
+ {
+ UPDATE_DNR_PARAM( mode );
+ UPDATE_DNR_PARAM( type );
+ blackbird_api_cmd(dev, BLACKBIRD_API_SET_DNR_MODE, 2, 0, dnr_params->mode, dnr_params->type);
+ }
+
+ /* assign dnr filter props*/
+ if( dnr_params->spatial > 15 )
+ dnr_params->spatial = 15;
+ if( dnr_params->temporal > 31 )
+ dnr_params->temporal = 31;
+ if( CHECK_DNR_PARAM( spatial ) || CHECK_DNR_PARAM( temporal ) )
+ {
+ UPDATE_DNR_PARAM( spatial );
+ UPDATE_DNR_PARAM( temporal );
+ blackbird_api_cmd(dev, BLACKBIRD_API_SET_MANUAL_DNR, 2, 0, dnr_params->spatial, dnr_params->temporal);
+ }
+}
+
+static void blackbird_codec_settings(struct cx8802_dev *dev)
+{
+
+ /* assign output port */
+ blackbird_api_cmd(dev, BLACKBIRD_API_SET_OUTPUT_PORT, 1, 0, BLACKBIRD_OUTPUT_PORT_STREAMING); /* Host */
+
+ /* assign frame size */
+ blackbird_api_cmd(dev, BLACKBIRD_API_SET_RESOLUTION, 2, 0,
+ dev->height, dev->width);
/* assign coring levels (luma_h, luma_l, chroma_h, chroma_l) */
blackbird_api_cmd(dev, BLACKBIRD_API_SET_DNR_MEDIAN, 4, 0, 0, 255, 0, 255);
/* assign spatial filter type: luma_t: horiz_only, chroma_t: horiz_only */
blackbird_api_cmd(dev, BLACKBIRD_API_SET_SPATIAL_FILTER, 2, 0,
- BLACKBIRD_SPATIAL_FILTER_LUMA_1D_HORIZ,
- BLACKBIRD_SPATIAL_FILTER_CHROMA_1D_HORIZ
- );
+ BLACKBIRD_SPATIAL_FILTER_LUMA_1D_HORIZ,
+ BLACKBIRD_SPATIAL_FILTER_CHROMA_1D_HORIZ
+ );
/* assign frame drop rate */
/* blackbird_api_cmd(dev, IVTV_API_ASSIGN_FRAME_DROP_RATE, 1, 0, 0); */
+
+ blackbird_set_default_params(dev);
+ blackbird_set_default_dnr_params(dev);
}
static int blackbird_initialize_codec(struct cx8802_dev *dev)
@@ -851,15 +1327,10 @@ static int bb_buf_setup(struct videobuf_queue *q,
struct cx8802_fh *fh = q->priv_data;
fh->dev->ts_packet_size = 188 * 4; /* was: 512 */
- fh->dev->ts_packet_count = 32; /* was: 100 */
+ fh->dev->ts_packet_count = mpegbufs; /* was: 100 */
*size = fh->dev->ts_packet_size * fh->dev->ts_packet_count;
- if (0 == *count)
- *count = mpegbufs;
- if (*count < 2)
- *count = 2;
- if (*count > 32)
- *count = 32;
+ *count = fh->dev->ts_packet_count;
return 0;
}
@@ -868,7 +1339,7 @@ bb_buf_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
enum v4l2_field field)
{
struct cx8802_fh *fh = q->priv_data;
- return cx8802_buf_prepare(fh->dev, (struct cx88_buffer*)vb);
+ return cx8802_buf_prepare(fh->dev, (struct cx88_buffer*)vb, field);
}
static void
@@ -920,8 +1391,6 @@ static int mpeg_do_ioctl(struct inode *inode, struct file *file,
V4L2_CAP_VIDEO_CAPTURE |
V4L2_CAP_READWRITE |
V4L2_CAP_STREAMING |
- V4L2_CAP_VBI_CAPTURE |
- V4L2_CAP_VIDEO_OVERLAY |
0;
if (UNSET != core->tuner_type)
cap->capabilities |= V4L2_CAP_TUNER;
@@ -941,27 +1410,52 @@ static int mpeg_do_ioctl(struct inode *inode, struct file *file,
memset(f,0,sizeof(*f));
f->index = index;
- strlcpy(f->description, "MPEG TS", sizeof(f->description));
+ strlcpy(f->description, "MPEG", sizeof(f->description));
f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
f->pixelformat = V4L2_PIX_FMT_MPEG;
return 0;
}
case VIDIOC_G_FMT:
- case VIDIOC_S_FMT:
- case VIDIOC_TRY_FMT:
{
- /* FIXME -- quick'n'dirty for exactly one size ... */
struct v4l2_format *f = arg;
memset(f,0,sizeof(*f));
f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
+ f->fmt.pix.bytesperline = 0;
+ f->fmt.pix.sizeimage = dev->ts_packet_size * dev->ts_packet_count; /* 188 * 4 * 1024; */
+ f->fmt.pix.colorspace = 0;
f->fmt.pix.width = dev->width;
f->fmt.pix.height = dev->height;
+ f->fmt.pix.field = fh->mpegq.field;
+ dprintk(0,"VIDIOC_G_FMT: w: %d, h: %d, f: %d\n",
+ dev->width, dev->height, fh->mpegq.field );
+ return 0;
+ }
+ case VIDIOC_TRY_FMT:
+ {
+ struct v4l2_format *f = arg;
+
+ f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
+ f->fmt.pix.bytesperline = 0;
+ f->fmt.pix.sizeimage = dev->ts_packet_size * dev->ts_packet_count; /* 188 * 4 * 1024; */;
+ f->fmt.pix.colorspace = 0;
+ dprintk(0,"VIDIOC_TRY_FMT: w: %d, h: %d, f: %d\n",
+ dev->width, dev->height, fh->mpegq.field );
+ return 0;
+ }
+ case VIDIOC_S_FMT:
+ {
+ struct v4l2_format *f = arg;
+
+ f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
- f->fmt.pix.field = V4L2_FIELD_NONE;
f->fmt.pix.bytesperline = 0;
- f->fmt.pix.sizeimage = 188 * 4 * 1024; /* 1024 * 512 */ /* FIXME: BUFFER_SIZE */;
+ f->fmt.pix.sizeimage = dev->ts_packet_size * dev->ts_packet_count; /* 188 * 4 * 1024; */;
f->fmt.pix.colorspace = 0;
+ dprintk(0,"VIDIOC_S_FMT: w: %d, h: %d, f: %d\n",
+ f->fmt.pix.width, f->fmt.pix.height, f->fmt.pix.field );
return 0;
}
@@ -985,6 +1479,22 @@ static int mpeg_do_ioctl(struct inode *inode, struct file *file,
case VIDIOC_STREAMOFF:
return videobuf_streamoff(&fh->mpegq);
+ /* --- mpeg compression -------------------------------------- */
+ case VIDIOC_G_MPEGCOMP:
+ {
+ struct v4l2_mpeg_compression *f = arg;
+
+ memcpy(f,&dev->params,sizeof(*f));
+ return 0;
+ }
+ case VIDIOC_S_MPEGCOMP:
+ {
+ struct v4l2_mpeg_compression *f = arg;
+
+ blackbird_set_params(dev, f);
+ return 0;
+ }
+
default:
return cx88_do_ioctl( inode, file, 0, dev->core, cmd, arg, cx88_ioctl_hook );
}
@@ -1034,16 +1544,17 @@ static int mpeg_open(struct inode *inode, struct file *file)
file->private_data = fh;
fh->dev = dev;
- /* FIXME: locking against other video device */
- cx88_set_scale(dev->core, dev->width, dev->height,
- V4L2_FIELD_INTERLACED);
-
videobuf_queue_init(&fh->mpegq, &blackbird_qops,
dev->pci, &dev->slock,
V4L2_BUF_TYPE_VIDEO_CAPTURE,
- V4L2_FIELD_TOP,
+ V4L2_FIELD_INTERLACED,
sizeof(struct cx88_buffer),
fh);
+
+ /* FIXME: locking against other video device */
+ cx88_set_scale(dev->core, dev->width, dev->height,
+ fh->mpegq.field);
+
return 0;
}
@@ -1173,6 +1684,8 @@ static int __devinit blackbird_probe(struct pci_dev *pci_dev,
dev->core = core;
dev->width = 720;
dev->height = 576;
+ memcpy(&dev->params,&default_mpeg_params,sizeof(default_mpeg_params));
+ memcpy(&dev->dnr_params,&default_dnr_params,sizeof(default_dnr_params));
err = cx8802_init_common(dev);
if (0 != err)
@@ -1199,7 +1712,7 @@ static int __devinit blackbird_probe(struct pci_dev *pci_dev,
static void __devexit blackbird_remove(struct pci_dev *pci_dev)
{
- struct cx8802_dev *dev = pci_get_drvdata(pci_dev);
+ struct cx8802_dev *dev = pci_get_drvdata(pci_dev);
/* blackbird */
blackbird_unregister_video(dev);
@@ -1215,8 +1728,8 @@ static struct pci_device_id cx8802_pci_tbl[] = {
{
.vendor = 0x14f1,
.device = 0x8802,
- .subvendor = PCI_ANY_ID,
- .subdevice = PCI_ANY_ID,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
},{
/* --- end of list --- */
}
@@ -1224,10 +1737,10 @@ static struct pci_device_id cx8802_pci_tbl[] = {
MODULE_DEVICE_TABLE(pci, cx8802_pci_tbl);
static struct pci_driver blackbird_pci_driver = {
- .name = "cx88-blackbird",
- .id_table = cx8802_pci_tbl,
- .probe = blackbird_probe,
- .remove = __devexit_p(blackbird_remove),
+ .name = "cx88-blackbird",
+ .id_table = cx8802_pci_tbl,
+ .probe = blackbird_probe,
+ .remove = __devexit_p(blackbird_remove),
.suspend = cx8802_suspend_common,
.resume = cx8802_resume_common,
};
@@ -1257,6 +1770,8 @@ module_exit(blackbird_fini);
EXPORT_SYMBOL(cx88_ioctl_hook);
EXPORT_SYMBOL(cx88_ioctl_translator);
+EXPORT_SYMBOL(blackbird_set_params);
+EXPORT_SYMBOL(blackbird_set_dnr_params);
/* ----------------------------------------------------------- */
/*
diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c
index 4da91d535a5b..f2268631b7c0 100644
--- a/drivers/media/video/cx88/cx88-cards.c
+++ b/drivers/media/video/cx88/cx88-cards.c
@@ -126,27 +126,27 @@ struct cx88_board cx88_boards[] = {
.input = {{
.type = CX88_VMUX_TELEVISION,
.vmux = 0,
- .gpio0 = 0x03ff,
+ .gpio0 = 0x03ff,
},{
.type = CX88_VMUX_COMPOSITE1,
.vmux = 1,
- .gpio0 = 0x03fe,
+ .gpio0 = 0x03fe,
},{
.type = CX88_VMUX_SVIDEO,
.vmux = 2,
- .gpio0 = 0x03fe,
+ .gpio0 = 0x03fe,
}},
},
- [CX88_BOARD_WINFAST2000XP_EXPERT] = {
- .name = "Leadtek Winfast 2000XP Expert",
- .tuner_type = TUNER_PHILIPS_4IN1,
+ [CX88_BOARD_WINFAST2000XP_EXPERT] = {
+ .name = "Leadtek Winfast 2000XP Expert",
+ .tuner_type = TUNER_PHILIPS_4IN1,
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
.tda9887_conf = TDA9887_PRESENT,
- .input = {{
- .type = CX88_VMUX_TELEVISION,
- .vmux = 0,
+ .input = {{
+ .type = CX88_VMUX_TELEVISION,
+ .vmux = 0,
.gpio0 = 0x00F5e700,
.gpio1 = 0x00003004,
.gpio2 = 0x00F5e700,
@@ -165,16 +165,16 @@ struct cx88_board cx88_boards[] = {
.gpio1 = 0x00003004,
.gpio2 = 0x00F5c700,
.gpio3 = 0x02000000,
- }},
- .radio = {
- .type = CX88_RADIO,
+ }},
+ .radio = {
+ .type = CX88_RADIO,
.gpio0 = 0x00F5d700,
.gpio1 = 0x00003004,
.gpio2 = 0x00F5d700,
.gpio3 = 0x02000000,
- },
- },
- [CX88_BOARD_AVERTV_303] = {
+ },
+ },
+ [CX88_BOARD_AVERTV_STUDIO_303] = {
.name = "AverTV Studio 303 (M126)",
.tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
.radio_type = UNSET,
@@ -206,7 +206,7 @@ struct cx88_board cx88_boards[] = {
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
- .tda9887_conf = TDA9887_PRESENT,
+ .tda9887_conf = TDA9887_PRESENT | TDA9887_INTERCARRIER_NTSC,
.input = {{
.type = CX88_VMUX_TELEVISION,
.vmux = 0,
@@ -214,32 +214,32 @@ struct cx88_board cx88_boards[] = {
.gpio1 = 0x000080c0,
.gpio2 = 0x0000ff40,
},{
- .type = CX88_VMUX_COMPOSITE1,
- .vmux = 1,
+ .type = CX88_VMUX_COMPOSITE1,
+ .vmux = 1,
.gpio0 = 0x000040bf,
.gpio1 = 0x000080c0,
.gpio2 = 0x0000ff40,
},{
- .type = CX88_VMUX_SVIDEO,
- .vmux = 2,
+ .type = CX88_VMUX_SVIDEO,
+ .vmux = 2,
.gpio0 = 0x000040bf,
.gpio1 = 0x000080c0,
.gpio2 = 0x0000ff40,
- }},
- .radio = {
+ }},
+ .radio = {
.type = CX88_RADIO,
- },
+ },
},
[CX88_BOARD_WINFAST_DV2000] = {
- .name = "Leadtek Winfast DV2000",
- .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
+ .name = "Leadtek Winfast DV2000",
+ .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
.tda9887_conf = TDA9887_PRESENT,
- .input = {{
- .type = CX88_VMUX_TELEVISION,
- .vmux = 0,
+ .input = {{
+ .type = CX88_VMUX_TELEVISION,
+ .vmux = 0,
.gpio0 = 0x0035e700,
.gpio1 = 0x00003004,
.gpio2 = 0x0035e700,
@@ -260,14 +260,14 @@ struct cx88_board cx88_boards[] = {
.gpio2 = 0x02000000,
.gpio3 = 0x02000000,
}},
- .radio = {
+ .radio = {
.type = CX88_RADIO,
.gpio0 = 0x0035d700,
.gpio1 = 0x00007004,
.gpio2 = 0x0035d700,
.gpio3 = 0x02000000,
},
- },
+ },
[CX88_BOARD_LEADTEK_PVR2000] = {
// gpio values for PAL version from regspy by DScaler
.name = "Leadtek PVR 2000",
@@ -296,25 +296,25 @@ struct cx88_board cx88_boards[] = {
.blackbird = 1,
},
[CX88_BOARD_IODATA_GVVCP3PCI] = {
- .name = "IODATA GV-VCP3/PCI",
+ .name = "IODATA GV-VCP3/PCI",
.tuner_type = TUNER_ABSENT,
- .radio_type = UNSET,
+ .radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
.input = {{
- .type = CX88_VMUX_COMPOSITE1,
- .vmux = 0,
- },{
- .type = CX88_VMUX_COMPOSITE2,
- .vmux = 1,
- },{
- .type = CX88_VMUX_SVIDEO,
- .vmux = 2,
- }},
- },
+ .type = CX88_VMUX_COMPOSITE1,
+ .vmux = 0,
+ },{
+ .type = CX88_VMUX_COMPOSITE2,
+ .vmux = 1,
+ },{
+ .type = CX88_VMUX_SVIDEO,
+ .vmux = 2,
+ }},
+ },
[CX88_BOARD_PROLINK_PLAYTVPVR] = {
- .name = "Prolink PlayTV PVR",
- .tuner_type = TUNER_PHILIPS_FM1236_MK3,
+ .name = "Prolink PlayTV PVR",
+ .tuner_type = TUNER_PHILIPS_FM1236_MK3,
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
@@ -348,15 +348,15 @@ struct cx88_board cx88_boards[] = {
.type = CX88_VMUX_TELEVISION,
.vmux = 0,
.gpio0 = 0x0000fde6,
- },{
+ },{
.type = CX88_VMUX_SVIDEO,
.vmux = 2,
.gpio0 = 0x0000fde6, // 0x0000fda6 L,R RCA audio in?
}},
- .radio = {
- .type = CX88_RADIO,
+ .radio = {
+ .type = CX88_RADIO,
.gpio0 = 0x0000fde2,
- },
+ },
.blackbird = 1,
},
[CX88_BOARD_MSI_TVANYWHERE] = {
@@ -372,34 +372,34 @@ struct cx88_board cx88_boards[] = {
.gpio0 = 0x00000fbf,
.gpio2 = 0x0000fc08,
},{
- .type = CX88_VMUX_COMPOSITE1,
- .vmux = 1,
+ .type = CX88_VMUX_COMPOSITE1,
+ .vmux = 1,
.gpio0 = 0x00000fbf,
.gpio2 = 0x0000fc68,
},{
- .type = CX88_VMUX_SVIDEO,
- .vmux = 2,
+ .type = CX88_VMUX_SVIDEO,
+ .vmux = 2,
.gpio0 = 0x00000fbf,
.gpio2 = 0x0000fc68,
- }},
+ }},
},
- [CX88_BOARD_KWORLD_DVB_T] = {
- .name = "KWorld/VStream XPert DVB-T",
+ [CX88_BOARD_KWORLD_DVB_T] = {
+ .name = "KWorld/VStream XPert DVB-T",
.tuner_type = TUNER_ABSENT,
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
- .input = {{
- .type = CX88_VMUX_COMPOSITE1,
- .vmux = 1,
+ .input = {{
+ .type = CX88_VMUX_COMPOSITE1,
+ .vmux = 1,
.gpio0 = 0x0700,
.gpio2 = 0x0101,
- },{
- .type = CX88_VMUX_SVIDEO,
- .vmux = 2,
+ },{
+ .type = CX88_VMUX_SVIDEO,
+ .vmux = 2,
.gpio0 = 0x0700,
.gpio2 = 0x0101,
- }},
+ }},
.dvb = 1,
},
[CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1] = {
@@ -425,27 +425,27 @@ struct cx88_board cx88_boards[] = {
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
- .input = {{
- .type = CX88_VMUX_TELEVISION,
- .vmux = 0,
- .gpio0 = 0x07f8,
+ .input = {{
+ .type = CX88_VMUX_TELEVISION,
+ .vmux = 0,
+ .gpio0 = 0x07f8,
},{
.type = CX88_VMUX_DEBUG,
.vmux = 0,
.gpio0 = 0x07f9, // mono from tuner chip
- },{
- .type = CX88_VMUX_COMPOSITE1,
- .vmux = 1,
- .gpio0 = 0x000007fa,
- },{
- .type = CX88_VMUX_SVIDEO,
- .vmux = 2,
- .gpio0 = 0x000007fa,
- }},
- .radio = {
- .type = CX88_RADIO,
- .gpio0 = 0x000007f8,
- },
+ },{
+ .type = CX88_VMUX_COMPOSITE1,
+ .vmux = 1,
+ .gpio0 = 0x000007fa,
+ },{
+ .type = CX88_VMUX_SVIDEO,
+ .vmux = 2,
+ .gpio0 = 0x000007fa,
+ }},
+ .radio = {
+ .type = CX88_RADIO,
+ .gpio0 = 0x000007f8,
+ },
},
[CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_Q] = {
.name = "DViCO FusionHDTV 3 Gold-Q",
@@ -489,28 +489,28 @@ struct cx88_board cx88_boards[] = {
}},
.dvb = 1,
},
- [CX88_BOARD_HAUPPAUGE_DVB_T1] = {
+ [CX88_BOARD_HAUPPAUGE_DVB_T1] = {
.name = "Hauppauge Nova-T DVB-T",
.tuner_type = TUNER_ABSENT,
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
.input = {{
- .type = CX88_VMUX_DVB,
- .vmux = 0,
- }},
+ .type = CX88_VMUX_DVB,
+ .vmux = 0,
+ }},
.dvb = 1,
},
- [CX88_BOARD_CONEXANT_DVB_T1] = {
+ [CX88_BOARD_CONEXANT_DVB_T1] = {
.name = "Conexant DVB-T reference design",
.tuner_type = TUNER_ABSENT,
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
- .input = {{
- .type = CX88_VMUX_DVB,
- .vmux = 0,
- }},
+ .input = {{
+ .type = CX88_VMUX_DVB,
+ .vmux = 0,
+ }},
.dvb = 1,
},
[CX88_BOARD_PROVIDEO_PV259] = {
@@ -543,12 +543,12 @@ struct cx88_board cx88_boards[] = {
.dvb = 1,
},
[CX88_BOARD_DNTV_LIVE_DVB_T] = {
- .name = "digitalnow DNTV Live! DVB-T",
+ .name = "digitalnow DNTV Live! DVB-T",
.tuner_type = TUNER_ABSENT,
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
- .input = {{
+ .input = {{
.type = CX88_VMUX_COMPOSITE1,
.vmux = 1,
.gpio0 = 0x00000700,
@@ -705,44 +705,44 @@ struct cx88_board cx88_boards[] = {
.gpio0 = 0xbf60,
},
},
- [CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T] = {
+ [CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T] = {
.name = "DViCO FusionHDTV 3 Gold-T",
.tuner_type = TUNER_THOMSON_DTT7611,
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
.input = {{
- .type = CX88_VMUX_TELEVISION,
- .vmux = 0,
- .gpio0 = 0x97ed,
- },{
- .type = CX88_VMUX_COMPOSITE1,
- .vmux = 1,
- .gpio0 = 0x97e9,
- },{
- .type = CX88_VMUX_SVIDEO,
- .vmux = 2,
- .gpio0 = 0x97e9,
- }},
+ .type = CX88_VMUX_TELEVISION,
+ .vmux = 0,
+ .gpio0 = 0x97ed,
+ },{
+ .type = CX88_VMUX_COMPOSITE1,
+ .vmux = 1,
+ .gpio0 = 0x97e9,
+ },{
+ .type = CX88_VMUX_SVIDEO,
+ .vmux = 2,
+ .gpio0 = 0x97e9,
+ }},
.dvb = 1,
- },
- [CX88_BOARD_ADSTECH_DVB_T_PCI] = {
- .name = "ADS Tech Instant TV DVB-T PCI",
+ },
+ [CX88_BOARD_ADSTECH_DVB_T_PCI] = {
+ .name = "ADS Tech Instant TV DVB-T PCI",
.tuner_type = TUNER_ABSENT,
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
.input = {{
- .type = CX88_VMUX_COMPOSITE1,
- .vmux = 1,
+ .type = CX88_VMUX_COMPOSITE1,
+ .vmux = 1,
.gpio0 = 0x0700,
.gpio2 = 0x0101,
- },{
- .type = CX88_VMUX_SVIDEO,
- .vmux = 2,
+ },{
+ .type = CX88_VMUX_SVIDEO,
+ .vmux = 2,
.gpio0 = 0x0700,
.gpio2 = 0x0101,
- }},
+ }},
.dvb = 1,
},
[CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1] = {
@@ -762,20 +762,139 @@ struct cx88_board cx88_boards[] = {
.radio_addr = ADDR_UNSET,
.tda9887_conf = TDA9887_PRESENT,
.input = {{
- .type = CX88_VMUX_TELEVISION,
- .vmux = 0,
- .gpio0 = 0x87fd,
- },{
- .type = CX88_VMUX_COMPOSITE1,
- .vmux = 1,
- .gpio0 = 0x87f9,
- },{
- .type = CX88_VMUX_SVIDEO,
- .vmux = 2,
- .gpio0 = 0x87f9,
- }},
+ .type = CX88_VMUX_TELEVISION,
+ .vmux = 0,
+ .gpio0 = 0x87fd,
+ },{
+ .type = CX88_VMUX_COMPOSITE1,
+ .vmux = 1,
+ .gpio0 = 0x87f9,
+ },{
+ .type = CX88_VMUX_SVIDEO,
+ .vmux = 2,
+ .gpio0 = 0x87f9,
+ }},
+ .dvb = 1,
+ },
+ [CX88_BOARD_AVERMEDIA_ULTRATV_MC_550] = {
+ .name = "AverMedia UltraTV Media Center PCI 550",
+ .tuner_type = TUNER_PHILIPS_FM1236_MK3,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .tda9887_conf = TDA9887_PRESENT,
+ .blackbird = 1,
+ .input = {{
+ .type = CX88_VMUX_COMPOSITE1,
+ .vmux = 0,
+ .gpio0 = 0x0000cd73,
+ },{
+ .type = CX88_VMUX_SVIDEO,
+ .vmux = 1,
+ .gpio0 = 0x0000cd73,
+ },{
+ .type = CX88_VMUX_TELEVISION,
+ .vmux = 3,
+ .gpio0 = 0x0000cdb3,
+ }},
+ .radio = {
+ .type = CX88_RADIO,
+ .vmux = 2,
+ .gpio0 = 0x0000cdf3,
+ },
+ },
+ [CX88_BOARD_KWORLD_VSTREAM_EXPERT_DVD] = {
+ /* Alexander Wold <awold@bigfoot.com> */
+ .name = "Kworld V-Stream Xpert DVD",
+ .tuner_type = UNSET,
+ .input = {{
+ .type = CX88_VMUX_COMPOSITE1,
+ .vmux = 1,
+ .gpio0 = 0x03000000,
+ .gpio1 = 0x01000000,
+ .gpio2 = 0x02000000,
+ .gpio3 = 0x00100000,
+ },{
+ .type = CX88_VMUX_SVIDEO,
+ .vmux = 2,
+ .gpio0 = 0x03000000,
+ .gpio1 = 0x01000000,
+ .gpio2 = 0x02000000,
+ .gpio3 = 0x00100000,
+ }},
+ },
+ [CX88_BOARD_ATI_HDTVWONDER] = {
+ .name = "ATI HDTV Wonder",
+ .tuner_type = TUNER_PHILIPS_TUV1236D,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .input = {{
+ .type = CX88_VMUX_TELEVISION,
+ .vmux = 0,
+ .gpio0 = 0x00000ff7,
+ .gpio1 = 0x000000ff,
+ .gpio2 = 0x00000001,
+ .gpio3 = 0x00000000,
+ },{
+ .type = CX88_VMUX_COMPOSITE1,
+ .vmux = 1,
+ .gpio0 = 0x00000ffe,
+ .gpio1 = 0x000000ff,
+ .gpio2 = 0x00000001,
+ .gpio3 = 0x00000000,
+ },{
+ .type = CX88_VMUX_SVIDEO,
+ .vmux = 2,
+ .gpio0 = 0x00000ffe,
+ .gpio1 = 0x000000ff,
+ .gpio2 = 0x00000001,
+ .gpio3 = 0x00000000,
+ }},
.dvb = 1,
},
+ [CX88_BOARD_WINFAST_DTV1000] = {
+ .name = "WinFast DTV1000-T",
+ .tuner_type = TUNER_ABSENT,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .input = {{
+ .type = CX88_VMUX_DVB,
+ .vmux = 0,
+ }},
+ .dvb = 1,
+ },
+ [CX88_BOARD_AVERTV_303] = {
+ .name = "AVerTV 303 (M126)",
+ .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .tda9887_conf = TDA9887_PRESENT,
+ .input = {{
+ .type = CX88_VMUX_TELEVISION,
+ .vmux = 0,
+ .gpio0 = 0x00ff,
+ .gpio1 = 0xe09f,
+ .gpio2 = 0x0010,
+ .gpio3 = 0x0000,
+ },{
+ .type = CX88_VMUX_COMPOSITE1,
+ .vmux = 1,
+ .gpio0 = 0x00ff,
+ .gpio1 = 0xe05f,
+ .gpio2 = 0x0010,
+ .gpio3 = 0x0000,
+ },{
+ .type = CX88_VMUX_SVIDEO,
+ .vmux = 2,
+ .gpio0 = 0x00ff,
+ .gpio1 = 0xe05f,
+ .gpio2 = 0x0010,
+ .gpio3 = 0x0000,
+ }},
+ },
};
const unsigned int cx88_bcount = ARRAY_SIZE(cx88_boards);
@@ -804,41 +923,41 @@ struct cx88_subid cx88_subids[] = {
.subdevice = 0x00f8,
.card = CX88_BOARD_ATI_WONDER_PRO,
},{
- .subvendor = 0x107d,
- .subdevice = 0x6611,
- .card = CX88_BOARD_WINFAST2000XP_EXPERT,
+ .subvendor = 0x107d,
+ .subdevice = 0x6611,
+ .card = CX88_BOARD_WINFAST2000XP_EXPERT,
+ },{
+ .subvendor = 0x107d,
+ .subdevice = 0x6613, /* NTSC */
+ .card = CX88_BOARD_WINFAST2000XP_EXPERT,
},{
- .subvendor = 0x107d,
- .subdevice = 0x6613, /* NTSC */
- .card = CX88_BOARD_WINFAST2000XP_EXPERT,
+ .subvendor = 0x107d,
+ .subdevice = 0x6620,
+ .card = CX88_BOARD_WINFAST_DV2000,
+ },{
+ .subvendor = 0x107d,
+ .subdevice = 0x663b,
+ .card = CX88_BOARD_LEADTEK_PVR2000,
},{
.subvendor = 0x107d,
- .subdevice = 0x6620,
- .card = CX88_BOARD_WINFAST_DV2000,
- },{
- .subvendor = 0x107d,
- .subdevice = 0x663b,
- .card = CX88_BOARD_LEADTEK_PVR2000,
- },{
- .subvendor = 0x107d,
- .subdevice = 0x663C,
- .card = CX88_BOARD_LEADTEK_PVR2000,
- },{
+ .subdevice = 0x663C,
+ .card = CX88_BOARD_LEADTEK_PVR2000,
+ },{
.subvendor = 0x1461,
.subdevice = 0x000b,
- .card = CX88_BOARD_AVERTV_303,
+ .card = CX88_BOARD_AVERTV_STUDIO_303,
},{
.subvendor = 0x1462,
.subdevice = 0x8606,
.card = CX88_BOARD_MSI_TVANYWHERE_MASTER,
},{
- .subvendor = 0x10fc,
- .subdevice = 0xd003,
- .card = CX88_BOARD_IODATA_GVVCP3PCI,
+ .subvendor = 0x10fc,
+ .subdevice = 0xd003,
+ .card = CX88_BOARD_IODATA_GVVCP3PCI,
},{
- .subvendor = 0x1043,
- .subdevice = 0x4823, /* with mpeg encoder */
- .card = CX88_BOARD_ASUS_PVR_416,
+ .subvendor = 0x1043,
+ .subdevice = 0x4823, /* with mpeg encoder */
+ .card = CX88_BOARD_ASUS_PVR_416,
},{
.subvendor = 0x17de,
.subdevice = 0x08a6,
@@ -852,43 +971,43 @@ struct cx88_subid cx88_subids[] = {
.subdevice = 0xd820,
.card = CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T,
},{
- .subvendor = 0x18AC,
- .subdevice = 0xDB00,
+ .subvendor = 0x18ac,
+ .subdevice = 0xdb00,
.card = CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1,
- },{
+ },{
.subvendor = 0x0070,
.subdevice = 0x9002,
.card = CX88_BOARD_HAUPPAUGE_DVB_T1,
- },{
+ },{
.subvendor = 0x14f1,
.subdevice = 0x0187,
.card = CX88_BOARD_CONEXANT_DVB_T1,
- },{
+ },{
.subvendor = 0x1540,
.subdevice = 0x2580,
.card = CX88_BOARD_PROVIDEO_PV259,
},{
- .subvendor = 0x18AC,
- .subdevice = 0xDB10,
+ .subvendor = 0x18ac,
+ .subdevice = 0xdb10,
.card = CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS,
},{
- .subvendor = 0x1554,
- .subdevice = 0x4811,
- .card = CX88_BOARD_PIXELVIEW,
+ .subvendor = 0x1554,
+ .subdevice = 0x4811,
+ .card = CX88_BOARD_PIXELVIEW,
},{
.subvendor = 0x7063,
.subdevice = 0x3000, /* HD-3000 card */
.card = CX88_BOARD_PCHDTV_HD3000,
},{
- .subvendor = 0x17DE,
- .subdevice = 0xA8A6,
+ .subvendor = 0x17de,
+ .subdevice = 0xa8a6,
.card = CX88_BOARD_DNTV_LIVE_DVB_T,
},{
.subvendor = 0x0070,
.subdevice = 0x2801,
.card = CX88_BOARD_HAUPPAUGE_ROSLYN,
},{
- .subvendor = 0x14F1,
+ .subvendor = 0x14f1,
.subdevice = 0x0342,
.card = CX88_BOARD_DIGITALLOGIC_MEC,
},{
@@ -899,14 +1018,30 @@ struct cx88_subid cx88_subids[] = {
.subvendor = 0x1421,
.subdevice = 0x0334,
.card = CX88_BOARD_ADSTECH_DVB_T_PCI,
- },{
+ },{
.subvendor = 0x153b,
.subdevice = 0x1166,
.card = CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1,
- },{
+ },{
.subvendor = 0x18ac,
.subdevice = 0xd500,
.card = CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD,
+ },{
+ .subvendor = 0x1461,
+ .subdevice = 0x8011,
+ .card = CX88_BOARD_AVERMEDIA_ULTRATV_MC_550,
+ },{
+ .subvendor = PCI_VENDOR_ID_ATI,
+ .subdevice = 0xa101,
+ .card = CX88_BOARD_ATI_HDTVWONDER,
+ },{
+ .subvendor = 0x107d,
+ .subdevice = 0x665f,
+ .card = CX88_BOARD_WINFAST_DTV1000,
+ },{
+ .subvendor = 0x1461,
+ .subdevice = 0x000a,
+ .card = CX88_BOARD_AVERTV_303,
},
};
const unsigned int cx88_idcount = ARRAY_SIZE(cx88_subids);
@@ -1108,6 +1243,19 @@ void cx88_card_setup(struct cx88_core *core)
cx_clear(MO_GP0_IO, 0x00000007);
cx_set(MO_GP2_IO, 0x00000101);
break;
+ case CX88_BOARD_ATI_HDTVWONDER:
+ if (0 == core->i2c_rc) {
+ /* enable tuner */
+ int i;
+ u8 buffer [] = { 0x10,0x12,0x13,0x04,0x16,0x00,0x14,0x04,0x017,0x00 };
+ core->i2c_client.addr = 0x0a;
+
+ for (i = 0; i < 5; i++)
+ if (2 != i2c_master_send(&core->i2c_client,&buffer[i*2],2))
+ printk(KERN_WARNING "%s: Unable to enable tuner(%i).\n",
+ core->name, i);
+ }
+ break;
}
if (cx88_boards[core->board].radio.type == CX88_RADIO)
core->has_radio = 1;
diff --git a/drivers/media/video/cx88/cx88-core.c b/drivers/media/video/cx88/cx88-core.c
index dc5c5c1f3461..eb806af17182 100644
--- a/drivers/media/video/cx88/cx88-core.c
+++ b/drivers/media/video/cx88/cx88-core.c
@@ -31,7 +31,7 @@
#include <linux/interrupt.h>
#include <linux/pci.h>
#include <linux/delay.h>
-#include <linux/videodev.h>
+#include <linux/videodev2.h>
#include "cx88.h"
@@ -153,26 +153,26 @@ static u32* cx88_risc_field(u32 *rp, struct scatterlist *sglist,
}
if (bpl <= sg_dma_len(sg)-offset) {
/* fits into current chunk */
- *(rp++)=cpu_to_le32(RISC_WRITE|RISC_SOL|RISC_EOL|bpl);
- *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset);
- offset+=bpl;
+ *(rp++)=cpu_to_le32(RISC_WRITE|RISC_SOL|RISC_EOL|bpl);
+ *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset);
+ offset+=bpl;
} else {
/* scanline needs to be splitted */
- todo = bpl;
- *(rp++)=cpu_to_le32(RISC_WRITE|RISC_SOL|
+ todo = bpl;
+ *(rp++)=cpu_to_le32(RISC_WRITE|RISC_SOL|
(sg_dma_len(sg)-offset));
- *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset);
- todo -= (sg_dma_len(sg)-offset);
- offset = 0;
- sg++;
- while (todo > sg_dma_len(sg)) {
- *(rp++)=cpu_to_le32(RISC_WRITE|
+ *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset);
+ todo -= (sg_dma_len(sg)-offset);
+ offset = 0;
+ sg++;
+ while (todo > sg_dma_len(sg)) {
+ *(rp++)=cpu_to_le32(RISC_WRITE|
sg_dma_len(sg));
- *(rp++)=cpu_to_le32(sg_dma_address(sg));
+ *(rp++)=cpu_to_le32(sg_dma_address(sg));
todo -= sg_dma_len(sg);
sg++;
}
- *(rp++)=cpu_to_le32(RISC_WRITE|RISC_EOL|todo);
+ *(rp++)=cpu_to_le32(RISC_WRITE|RISC_EOL|todo);
*(rp++)=cpu_to_le32(sg_dma_address(sg));
offset += todo;
}
@@ -309,7 +309,7 @@ struct sram_channel cx88_sram_channels[] = {
.name = "video y / packed",
.cmds_start = 0x180040,
.ctrl_start = 0x180400,
- .cdt = 0x180400 + 64,
+ .cdt = 0x180400 + 64,
.fifo_start = 0x180c00,
.fifo_size = 0x002800,
.ptr1_reg = MO_DMA21_PTR1,
@@ -321,7 +321,7 @@ struct sram_channel cx88_sram_channels[] = {
.name = "video u",
.cmds_start = 0x180080,
.ctrl_start = 0x1804a0,
- .cdt = 0x1804a0 + 64,
+ .cdt = 0x1804a0 + 64,
.fifo_start = 0x183400,
.fifo_size = 0x000800,
.ptr1_reg = MO_DMA22_PTR1,
@@ -333,7 +333,7 @@ struct sram_channel cx88_sram_channels[] = {
.name = "video v",
.cmds_start = 0x1800c0,
.ctrl_start = 0x180540,
- .cdt = 0x180540 + 64,
+ .cdt = 0x180540 + 64,
.fifo_start = 0x183c00,
.fifo_size = 0x000800,
.ptr1_reg = MO_DMA23_PTR1,
@@ -345,7 +345,7 @@ struct sram_channel cx88_sram_channels[] = {
.name = "vbi",
.cmds_start = 0x180100,
.ctrl_start = 0x1805e0,
- .cdt = 0x1805e0 + 64,
+ .cdt = 0x1805e0 + 64,
.fifo_start = 0x184400,
.fifo_size = 0x001000,
.ptr1_reg = MO_DMA24_PTR1,
@@ -357,7 +357,7 @@ struct sram_channel cx88_sram_channels[] = {
.name = "audio from",
.cmds_start = 0x180140,
.ctrl_start = 0x180680,
- .cdt = 0x180680 + 64,
+ .cdt = 0x180680 + 64,
.fifo_start = 0x185400,
.fifo_size = 0x000200,
.ptr1_reg = MO_DMA25_PTR1,
@@ -369,7 +369,7 @@ struct sram_channel cx88_sram_channels[] = {
.name = "audio to",
.cmds_start = 0x180180,
.ctrl_start = 0x180720,
- .cdt = 0x180680 + 64, /* same as audio IN */
+ .cdt = 0x180680 + 64, /* same as audio IN */
.fifo_start = 0x185400, /* same as audio IN */
.fifo_size = 0x000200, /* same as audio IN */
.ptr1_reg = MO_DMA26_PTR1,
@@ -431,7 +431,7 @@ int cx88_sram_channel_setup(struct cx88_core *core,
/* ------------------------------------------------------------------ */
/* debug helper code */
-int cx88_risc_decode(u32 risc)
+static int cx88_risc_decode(u32 risc)
{
static char *instr[16] = {
[ RISC_SYNC >> 28 ] = "sync",
@@ -845,19 +845,19 @@ static int set_tvaudio(struct cx88_core *core)
return 0;
if (V4L2_STD_PAL_BG & norm->id) {
- core->tvaudio = nicam ? WW_NICAM_BGDKL : WW_A2_BG;
+ core->tvaudio = WW_BG;
} else if (V4L2_STD_PAL_DK & norm->id) {
- core->tvaudio = nicam ? WW_NICAM_BGDKL : WW_A2_DK;
+ core->tvaudio = WW_DK;
} else if (V4L2_STD_PAL_I & norm->id) {
- core->tvaudio = WW_NICAM_I;
+ core->tvaudio = WW_I;
} else if (V4L2_STD_SECAM_L & norm->id) {
- core->tvaudio = WW_SYSTEM_L_AM;
+ core->tvaudio = WW_L;
} else if (V4L2_STD_SECAM_DK & norm->id) {
- core->tvaudio = WW_A2_DK;
+ core->tvaudio = WW_DK;
} else if ((V4L2_STD_NTSC_M & norm->id) ||
(V4L2_STD_PAL_M & norm->id)) {
@@ -1137,7 +1137,7 @@ struct cx88_core* cx88_core_get(struct pci_dev *pci)
if (!core->radio_addr)
core->radio_addr = cx88_boards[core->board].radio_addr;
- printk(KERN_INFO "TV tuner %d at 0x%02x, Radio tuner %d at 0x%02x\n",
+ printk(KERN_INFO "TV tuner %d at 0x%02x, Radio tuner %d at 0x%02x\n",
core->tuner_type, core->tuner_addr<<1,
core->radio_type, core->radio_addr<<1);
@@ -1146,6 +1146,7 @@ struct cx88_core* cx88_core_get(struct pci_dev *pci)
/* init hardware */
cx88_reset(core);
cx88_i2c_init(core,pci);
+ cx88_call_i2c_clients (core, TUNER_SET_STANDBY, NULL);
cx88_card_setup(core);
cx88_ir_init(core,pci);
diff --git a/drivers/media/video/cx88/cx88-dvb.c b/drivers/media/video/cx88/cx88-dvb.c
index 4334744652de..9cce91ec334b 100644
--- a/drivers/media/video/cx88/cx88-dvb.c
+++ b/drivers/media/video/cx88/cx88-dvb.c
@@ -29,7 +29,6 @@
#include <linux/file.h>
#include <linux/suspend.h>
-
#include "cx88.h"
#include "dvb-pll.h"
@@ -46,6 +45,9 @@
#ifdef HAVE_LGDT330X
# include "lgdt330x.h"
#endif
+#ifdef HAVE_NXT200X
+# include "nxt200x.h"
+#endif
MODULE_DESCRIPTION("driver for cx2388x based DVB cards");
MODULE_AUTHOR("Chris Pascoe <c.pascoe@itee.uq.edu.au>");
@@ -78,7 +80,7 @@ static int dvb_buf_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
enum v4l2_field field)
{
struct cx8802_dev *dev = q->priv_data;
- return cx8802_buf_prepare(dev, (struct cx88_buffer*)vb);
+ return cx8802_buf_prepare(dev, (struct cx88_buffer*)vb,field);
}
static void dvb_buf_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
@@ -129,7 +131,7 @@ static int dntv_live_dvbt_demod_init(struct dvb_frontend* fe)
static u8 reset [] = { 0x50, 0x80 };
static u8 adc_ctl_1_cfg [] = { 0x8E, 0x40 };
static u8 agc_cfg [] = { 0x67, 0x10, 0x23, 0x00, 0xFF, 0xFF,
- 0x00, 0xFF, 0x00, 0x40, 0x40 };
+ 0x00, 0xFF, 0x00, 0x40, 0x40 };
static u8 dntv_extra[] = { 0xB5, 0x7A };
static u8 capt_range_cfg[] = { 0x75, 0x32 };
@@ -285,6 +287,33 @@ static struct lgdt330x_config fusionhdtv_5_gold = {
};
#endif
+#ifdef HAVE_NXT200X
+static int nxt200x_set_ts_param(struct dvb_frontend* fe,
+ int is_punctured)
+{
+ struct cx8802_dev *dev= fe->dvb->priv;
+ dev->ts_gen_cntrl = is_punctured ? 0x04 : 0x00;
+ return 0;
+}
+
+static int nxt200x_set_pll_input(u8* buf, int input)
+{
+ if (input)
+ buf[3] |= 0x08;
+ else
+ buf[3] &= ~0x08;
+ return 0;
+}
+
+static struct nxt200x_config ati_hdtvwonder = {
+ .demod_address = 0x0a,
+ .pll_address = 0x61,
+ .pll_desc = &dvb_pll_tuv1236d,
+ .set_pll_input = nxt200x_set_pll_input,
+ .set_ts_params = nxt200x_set_ts_param,
+};
+#endif
+
static int dvb_register(struct cx8802_dev *dev)
{
/* init struct videobuf_dvb */
@@ -300,6 +329,7 @@ static int dvb_register(struct cx8802_dev *dev)
break;
case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1:
case CX88_BOARD_CONEXANT_DVB_T1:
+ case CX88_BOARD_WINFAST_DTV1000:
dev->dvb.frontend = cx22702_attach(&connexant_refboard_config,
&dev->core->i2c_adap);
break;
@@ -385,6 +415,12 @@ static int dvb_register(struct cx8802_dev *dev)
}
break;
#endif
+#ifdef HAVE_NXT200X
+ case CX88_BOARD_ATI_HDTVWONDER:
+ dev->dvb.frontend = nxt200x_attach(&ati_hdtvwonder,
+ &dev->core->i2c_adap);
+ break;
+#endif
default:
printk("%s: The frontend of your DVB/ATSC card isn't supported yet\n",
dev->core->name);
@@ -403,6 +439,9 @@ static int dvb_register(struct cx8802_dev *dev)
/* Put the analog decoder in standby to keep it quiet */
cx88_call_i2c_clients (dev->core, TUNER_SET_STANDBY, NULL);
+ /* Put the analog decoder in standby to keep it quiet */
+ cx88_call_i2c_clients (dev->core, TUNER_SET_STANDBY, NULL);
+
/* register everything */
return videobuf_dvb_register(&dev->dvb, THIS_MODULE, dev);
}
@@ -461,7 +500,7 @@ static int __devinit dvb_probe(struct pci_dev *pci_dev,
static void __devexit dvb_remove(struct pci_dev *pci_dev)
{
- struct cx8802_dev *dev = pci_get_drvdata(pci_dev);
+ struct cx8802_dev *dev = pci_get_drvdata(pci_dev);
/* dvb */
videobuf_dvb_unregister(&dev->dvb);
@@ -476,8 +515,8 @@ static struct pci_device_id cx8802_pci_tbl[] = {
{
.vendor = 0x14f1,
.device = 0x8802,
- .subvendor = PCI_ANY_ID,
- .subdevice = PCI_ANY_ID,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
},{
/* --- end of list --- */
}
@@ -485,10 +524,10 @@ static struct pci_device_id cx8802_pci_tbl[] = {
MODULE_DEVICE_TABLE(pci, cx8802_pci_tbl);
static struct pci_driver dvb_pci_driver = {
- .name = "cx88-dvb",
- .id_table = cx8802_pci_tbl,
- .probe = dvb_probe,
- .remove = __devexit_p(dvb_remove),
+ .name = "cx88-dvb",
+ .id_table = cx8802_pci_tbl,
+ .probe = dvb_probe,
+ .remove = __devexit_p(dvb_remove),
.suspend = cx8802_suspend_common,
.resume = cx8802_resume_common,
};
diff --git a/drivers/media/video/cx88/cx88-i2c.c b/drivers/media/video/cx88/cx88-i2c.c
index 761cebd40dbd..9790d412f192 100644
--- a/drivers/media/video/cx88/cx88-i2c.c
+++ b/drivers/media/video/cx88/cx88-i2c.c
@@ -3,7 +3,7 @@
cx88-i2c.c -- all the i2c code is here
Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de)
- & Marcus Metzler (mocm@thp.uni-koeln.de)
+ & Marcus Metzler (mocm@thp.uni-koeln.de)
(c) 2002 Yurij Sysoev <yurij@naturesoft.net>
(c) 1999-2003 Gerd Knorr <kraxel@bytesex.org>
@@ -90,7 +90,7 @@ static int cx8800_bit_getsda(void *data)
static int attach_inform(struct i2c_client *client)
{
- struct tuner_setup tun_setup;
+ struct tuner_setup tun_setup;
struct cx88_core *core = i2c_get_adapdata(client->adapter);
dprintk(1, "%s i2c attach [addr=0x%x,client=%s]\n",
@@ -98,7 +98,7 @@ static int attach_inform(struct i2c_client *client)
if (!client->driver->command)
return 0;
- if (core->radio_type != UNSET) {
+ if (core->radio_type != UNSET) {
if ((core->radio_addr==ADDR_UNSET)||(core->radio_addr==client->addr)) {
tun_setup.mode_mask = T_RADIO;
tun_setup.type = core->radio_type;
@@ -106,8 +106,8 @@ static int attach_inform(struct i2c_client *client)
client->driver->command (client, TUNER_SET_TYPE_ADDR, &tun_setup);
}
- }
- if (core->tuner_type != UNSET) {
+ }
+ if (core->tuner_type != UNSET) {
if ((core->tuner_addr==ADDR_UNSET)||(core->tuner_addr==client->addr)) {
tun_setup.mode_mask = T_ANALOG_TV;
@@ -116,7 +116,7 @@ static int attach_inform(struct i2c_client *client)
client->driver->command (client,TUNER_SET_TYPE_ADDR, &tun_setup);
}
- }
+ }
if (core->tda9887_conf)
client->driver->command(client, TDA9887_SET_CONFIG, &core->tda9887_conf);
@@ -159,7 +159,7 @@ static struct i2c_adapter cx8800_i2c_adap_template = {
};
static struct i2c_client cx8800_i2c_client_template = {
- .name = "cx88xx internal",
+ .name = "cx88xx internal",
};
static char *i2c_devs[128] = {
@@ -202,10 +202,10 @@ int cx88_i2c_init(struct cx88_core *core, struct pci_dev *pci)
core->i2c_adap.dev.parent = &pci->dev;
strlcpy(core->i2c_adap.name,core->name,sizeof(core->i2c_adap.name));
- core->i2c_algo.data = core;
- i2c_set_adapdata(&core->i2c_adap,core);
- core->i2c_adap.algo_data = &core->i2c_algo;
- core->i2c_client.adapter = &core->i2c_adap;
+ core->i2c_algo.data = core;
+ i2c_set_adapdata(&core->i2c_adap,core);
+ core->i2c_adap.algo_data = &core->i2c_algo;
+ core->i2c_client.adapter = &core->i2c_adap;
cx8800_bit_setscl(core,1);
cx8800_bit_setsda(core,1);
diff --git a/drivers/media/video/cx88/cx88-input.c b/drivers/media/video/cx88/cx88-input.c
index d81b21d6e05d..38b12ebaa49e 100644
--- a/drivers/media/video/cx88/cx88-input.c
+++ b/drivers/media/video/cx88/cx88-input.c
@@ -260,7 +260,7 @@ static IR_KEYTAB_TYPE ir_codes_cinergy_1400[IR_KEYTAB_SIZE] = {
struct cx88_IR {
struct cx88_core *core;
- struct input_dev input;
+ struct input_dev *input;
struct ir_input_state ir;
char name[32];
char phys[32];
@@ -315,23 +315,23 @@ static void cx88_ir_handle_key(struct cx88_IR *ir)
if (ir->mask_keydown) {
/* bit set on keydown */
if (gpio & ir->mask_keydown) {
- ir_input_keydown(&ir->input, &ir->ir, data, data);
+ ir_input_keydown(ir->input, &ir->ir, data, data);
} else {
- ir_input_nokey(&ir->input, &ir->ir);
+ ir_input_nokey(ir->input, &ir->ir);
}
} else if (ir->mask_keyup) {
/* bit cleared on keydown */
if (0 == (gpio & ir->mask_keyup)) {
- ir_input_keydown(&ir->input, &ir->ir, data, data);
+ ir_input_keydown(ir->input, &ir->ir, data, data);
} else {
- ir_input_nokey(&ir->input, &ir->ir);
+ ir_input_nokey(ir->input, &ir->ir);
}
} else {
/* can't distinguish keydown/up :-/ */
- ir_input_keydown(&ir->input, &ir->ir, data, data);
- ir_input_nokey(&ir->input, &ir->ir);
+ ir_input_keydown(ir->input, &ir->ir, data, data);
+ ir_input_nokey(ir->input, &ir->ir);
}
}
@@ -357,13 +357,19 @@ static void cx88_ir_work(void *data)
int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
{
struct cx88_IR *ir;
+ struct input_dev *input_dev;
IR_KEYTAB_TYPE *ir_codes = NULL;
int ir_type = IR_TYPE_OTHER;
- ir = kmalloc(sizeof(*ir), GFP_KERNEL);
- if (NULL == ir)
+ ir = kzalloc(sizeof(*ir), GFP_KERNEL);
+ input_dev = input_allocate_device();
+ if (!ir || !input_dev) {
+ kfree(ir);
+ input_free_device(input_dev);
return -ENOMEM;
- memset(ir, 0, sizeof(*ir));
+ }
+
+ ir->input = input_dev;
/* detect & configure */
switch (core->board) {
@@ -425,6 +431,7 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
if (NULL == ir_codes) {
kfree(ir);
+ input_free_device(input_dev);
return -ENODEV;
}
@@ -433,19 +440,19 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
cx88_boards[core->board].name);
snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0", pci_name(pci));
- ir_input_init(&ir->input, &ir->ir, ir_type, ir_codes);
- ir->input.name = ir->name;
- ir->input.phys = ir->phys;
- ir->input.id.bustype = BUS_PCI;
- ir->input.id.version = 1;
+ ir_input_init(input_dev, &ir->ir, ir_type, ir_codes);
+ input_dev->name = ir->name;
+ input_dev->phys = ir->phys;
+ input_dev->id.bustype = BUS_PCI;
+ input_dev->id.version = 1;
if (pci->subsystem_vendor) {
- ir->input.id.vendor = pci->subsystem_vendor;
- ir->input.id.product = pci->subsystem_device;
+ input_dev->id.vendor = pci->subsystem_vendor;
+ input_dev->id.product = pci->subsystem_device;
} else {
- ir->input.id.vendor = pci->vendor;
- ir->input.id.product = pci->device;
+ input_dev->id.vendor = pci->vendor;
+ input_dev->id.product = pci->device;
}
- ir->input.dev = &pci->dev;
+ input_dev->cdev.dev = &pci->dev;
/* record handles to ourself */
ir->core = core;
@@ -465,8 +472,7 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
}
/* all done */
- input_register_device(&ir->input);
- printk("%s: registered IR remote control\n", core->name);
+ input_register_device(ir->input);
return 0;
}
@@ -484,7 +490,7 @@ int cx88_ir_fini(struct cx88_core *core)
flush_scheduled_work();
}
- input_unregister_device(&ir->input);
+ input_unregister_device(ir->input);
kfree(ir);
/* done */
@@ -515,7 +521,7 @@ void cx88_ir_irq(struct cx88_core *core)
if (!ir->scount) {
/* nothing to sample */
if (ir->ir.keypressed && time_after(jiffies, ir->release))
- ir_input_nokey(&ir->input, &ir->ir);
+ ir_input_nokey(ir->input, &ir->ir);
return;
}
@@ -547,7 +553,7 @@ void cx88_ir_irq(struct cx88_core *core)
if ((ircode & 0xffff) != 0xeb04) { /* wrong address */
ir_dprintk("pulse distance decoded wrong address\n");
- break;
+ break;
}
if (((~ircode >> 24) & 0xff) != ((ircode >> 16) & 0xff)) { /* wrong checksum */
@@ -557,7 +563,7 @@ void cx88_ir_irq(struct cx88_core *core)
ir_dprintk("Key Code: %x\n", (ircode >> 16) & 0x7f);
- ir_input_keydown(&ir->input, &ir->ir, (ircode >> 16) & 0x7f, (ircode >> 16) & 0xff);
+ ir_input_keydown(ir->input, &ir->ir, (ircode >> 16) & 0x7f, (ircode >> 16) & 0xff);
ir->release = jiffies + msecs_to_jiffies(120);
break;
case CX88_BOARD_HAUPPAUGE:
@@ -566,7 +572,7 @@ void cx88_ir_irq(struct cx88_core *core)
ir_dprintk("biphase decoded: %x\n", ircode);
if ((ircode & 0xfffff000) != 0x3000)
break;
- ir_input_keydown(&ir->input, &ir->ir, ircode & 0x3f, ircode);
+ ir_input_keydown(ir->input, &ir->ir, ircode & 0x3f, ircode);
ir->release = jiffies + msecs_to_jiffies(120);
break;
}
diff --git a/drivers/media/video/cx88/cx88-mpeg.c b/drivers/media/video/cx88/cx88-mpeg.c
index ee2300e1ae0b..35e6d0c2b872 100644
--- a/drivers/media/video/cx88/cx88-mpeg.c
+++ b/drivers/media/video/cx88/cx88-mpeg.c
@@ -54,7 +54,7 @@ static int cx8802_start_dma(struct cx8802_dev *dev,
{
struct cx88_core *core = dev->core;
- dprintk(0, "cx8802_start_dma %d\n", buf->vb.width);
+ dprintk(0, "cx8802_start_dma w: %d, h: %d, f: %d\n", dev->width, dev->height, buf->vb.field);
/* setup fifo + format */
cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH28],
@@ -158,7 +158,8 @@ static int cx8802_restart_queue(struct cx8802_dev *dev,
/* ------------------------------------------------------------------ */
-int cx8802_buf_prepare(struct cx8802_dev *dev, struct cx88_buffer *buf)
+int cx8802_buf_prepare(struct cx8802_dev *dev, struct cx88_buffer *buf,
+ enum v4l2_field field)
{
int size = dev->ts_packet_size * dev->ts_packet_count;
int rc;
@@ -171,7 +172,7 @@ int cx8802_buf_prepare(struct cx8802_dev *dev, struct cx88_buffer *buf)
buf->vb.width = dev->ts_packet_size;
buf->vb.height = dev->ts_packet_count;
buf->vb.size = size;
- buf->vb.field = V4L2_FIELD_TOP;
+ buf->vb.field = field /*V4L2_FIELD_TOP*/;
if (0 != (rc = videobuf_iolock(dev->pci,&buf->vb,NULL)))
goto fail;
@@ -315,14 +316,14 @@ static void cx8802_mpeg_irq(struct cx8802_dev *dev)
spin_unlock(&dev->slock);
}
- /* other general errors */
- if (status & 0x1f0100) {
+ /* other general errors */
+ if (status & 0x1f0100) {
dprintk( 0, "general errors: 0x%08x\n", status & 0x1f0100 );
- spin_lock(&dev->slock);
+ spin_lock(&dev->slock);
cx8802_stop_dma(dev);
- cx8802_restart_queue(dev,&dev->mpegq);
- spin_unlock(&dev->slock);
- }
+ cx8802_restart_queue(dev,&dev->mpegq);
+ spin_unlock(&dev->slock);
+ }
}
#define MAX_IRQ_LOOP 10
@@ -378,8 +379,8 @@ int cx8802_init_common(struct cx8802_dev *dev)
}
pci_read_config_byte(dev->pci, PCI_CLASS_REVISION, &dev->pci_rev);
- pci_read_config_byte(dev->pci, PCI_LATENCY_TIMER, &dev->pci_lat);
- printk(KERN_INFO "%s/2: found at %s, rev: %d, irq: %d, "
+ pci_read_config_byte(dev->pci, PCI_LATENCY_TIMER, &dev->pci_lat);
+ printk(KERN_INFO "%s/2: found at %s, rev: %d, irq: %d, "
"latency: %d, mmio: 0x%lx\n", dev->core->name,
pci_name(dev->pci), dev->pci_rev, dev->pci->irq,
dev->pci_lat,pci_resource_start(dev->pci,0));
@@ -429,7 +430,7 @@ void cx8802_fini_common(struct cx8802_dev *dev)
int cx8802_suspend_common(struct pci_dev *pci_dev, pm_message_t state)
{
- struct cx8802_dev *dev = pci_get_drvdata(pci_dev);
+ struct cx8802_dev *dev = pci_get_drvdata(pci_dev);
struct cx88_core *core = dev->core;
/* stop mpeg dma */
diff --git a/drivers/media/video/cx88/cx88-reg.h b/drivers/media/video/cx88/cx88-reg.h
index 0a3a62fc9bbb..d3bf5b17b1d4 100644
--- a/drivers/media/video/cx88/cx88-reg.h
+++ b/drivers/media/video/cx88/cx88-reg.h
@@ -3,9 +3,9 @@
cx88x-hw.h - CX2388x register offsets
Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de)
- 2001 Michael Eskin
- 2002 Yurij Sysoev <yurij@naturesoft.net>
- 2003 Gerd Knorr <kraxel@bytesex.org>
+ 2001 Michael Eskin
+ 2002 Yurij Sysoev <yurij@naturesoft.net>
+ 2003 Gerd Knorr <kraxel@bytesex.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
@@ -728,13 +728,13 @@
#define ColorFormatGamma 0x1000
#define Interlaced 0x1
-#define NonInterlaced 0x0
+#define NonInterlaced 0x0
#define FieldEven 0x1
#define FieldOdd 0x0
-#define TGReadWriteMode 0x0
-#define TGEnableMode 0x1
+#define TGReadWriteMode 0x0
+#define TGEnableMode 0x1
#define DV_CbAlign 0x0
#define DV_Y0Align 0x1
diff --git a/drivers/media/video/cx88/cx88-tvaudio.c b/drivers/media/video/cx88/cx88-tvaudio.c
index 2765acee0285..6d9bec1c583b 100644
--- a/drivers/media/video/cx88/cx88-tvaudio.c
+++ b/drivers/media/video/cx88/cx88-tvaudio.c
@@ -57,39 +57,38 @@
#include "cx88.h"
static unsigned int audio_debug = 0;
-module_param(audio_debug,int,0644);
-MODULE_PARM_DESC(audio_debug,"enable debug messages [audio]");
+module_param(audio_debug, int, 0644);
+MODULE_PARM_DESC(audio_debug, "enable debug messages [audio]");
#define dprintk(fmt, arg...) if (audio_debug) \
printk(KERN_DEBUG "%s/0: " fmt, core->name , ## arg)
/* ----------------------------------------------------------- */
-static char *aud_ctl_names[64] =
-{
- [ EN_BTSC_FORCE_MONO ] = "BTSC_FORCE_MONO",
- [ EN_BTSC_FORCE_STEREO ] = "BTSC_FORCE_STEREO",
- [ EN_BTSC_FORCE_SAP ] = "BTSC_FORCE_SAP",
- [ EN_BTSC_AUTO_STEREO ] = "BTSC_AUTO_STEREO",
- [ EN_BTSC_AUTO_SAP ] = "BTSC_AUTO_SAP",
- [ EN_A2_FORCE_MONO1 ] = "A2_FORCE_MONO1",
- [ EN_A2_FORCE_MONO2 ] = "A2_FORCE_MONO2",
- [ EN_A2_FORCE_STEREO ] = "A2_FORCE_STEREO",
- [ EN_A2_AUTO_MONO2 ] = "A2_AUTO_MONO2",
- [ EN_A2_AUTO_STEREO ] = "A2_AUTO_STEREO",
- [ EN_EIAJ_FORCE_MONO1 ] = "EIAJ_FORCE_MONO1",
- [ EN_EIAJ_FORCE_MONO2 ] = "EIAJ_FORCE_MONO2",
- [ EN_EIAJ_FORCE_STEREO ] = "EIAJ_FORCE_STEREO",
- [ EN_EIAJ_AUTO_MONO2 ] = "EIAJ_AUTO_MONO2",
- [ EN_EIAJ_AUTO_STEREO ] = "EIAJ_AUTO_STEREO",
- [ EN_NICAM_FORCE_MONO1 ] = "NICAM_FORCE_MONO1",
- [ EN_NICAM_FORCE_MONO2 ] = "NICAM_FORCE_MONO2",
- [ EN_NICAM_FORCE_STEREO ] = "NICAM_FORCE_STEREO",
- [ EN_NICAM_AUTO_MONO2 ] = "NICAM_AUTO_MONO2",
- [ EN_NICAM_AUTO_STEREO ] = "NICAM_AUTO_STEREO",
- [ EN_FMRADIO_FORCE_MONO ] = "FMRADIO_FORCE_MONO",
- [ EN_FMRADIO_FORCE_STEREO ] = "FMRADIO_FORCE_STEREO",
- [ EN_FMRADIO_AUTO_STEREO ] = "FMRADIO_AUTO_STEREO",
+static char *aud_ctl_names[64] = {
+ [EN_BTSC_FORCE_MONO] = "BTSC_FORCE_MONO",
+ [EN_BTSC_FORCE_STEREO] = "BTSC_FORCE_STEREO",
+ [EN_BTSC_FORCE_SAP] = "BTSC_FORCE_SAP",
+ [EN_BTSC_AUTO_STEREO] = "BTSC_AUTO_STEREO",
+ [EN_BTSC_AUTO_SAP] = "BTSC_AUTO_SAP",
+ [EN_A2_FORCE_MONO1] = "A2_FORCE_MONO1",
+ [EN_A2_FORCE_MONO2] = "A2_FORCE_MONO2",
+ [EN_A2_FORCE_STEREO] = "A2_FORCE_STEREO",
+ [EN_A2_AUTO_MONO2] = "A2_AUTO_MONO2",
+ [EN_A2_AUTO_STEREO] = "A2_AUTO_STEREO",
+ [EN_EIAJ_FORCE_MONO1] = "EIAJ_FORCE_MONO1",
+ [EN_EIAJ_FORCE_MONO2] = "EIAJ_FORCE_MONO2",
+ [EN_EIAJ_FORCE_STEREO] = "EIAJ_FORCE_STEREO",
+ [EN_EIAJ_AUTO_MONO2] = "EIAJ_AUTO_MONO2",
+ [EN_EIAJ_AUTO_STEREO] = "EIAJ_AUTO_STEREO",
+ [EN_NICAM_FORCE_MONO1] = "NICAM_FORCE_MONO1",
+ [EN_NICAM_FORCE_MONO2] = "NICAM_FORCE_MONO2",
+ [EN_NICAM_FORCE_STEREO] = "NICAM_FORCE_STEREO",
+ [EN_NICAM_AUTO_MONO2] = "NICAM_AUTO_MONO2",
+ [EN_NICAM_AUTO_STEREO] = "NICAM_AUTO_STEREO",
+ [EN_FMRADIO_FORCE_MONO] = "FMRADIO_FORCE_MONO",
+ [EN_FMRADIO_FORCE_STEREO] = "FMRADIO_FORCE_STEREO",
+ [EN_FMRADIO_AUTO_STEREO] = "FMRADIO_AUTO_STEREO",
};
struct rlist {
@@ -97,8 +96,7 @@ struct rlist {
u32 val;
};
-static void set_audio_registers(struct cx88_core *core,
- const struct rlist *l)
+static void set_audio_registers(struct cx88_core *core, const struct rlist *l)
{
int i;
@@ -119,17 +117,18 @@ static void set_audio_registers(struct cx88_core *core,
}
}
-static void set_audio_start(struct cx88_core *core,
- u32 mode)
+static void set_audio_start(struct cx88_core *core, u32 mode)
{
// mute
- cx_write(AUD_VOL_CTL, (1 << 6));
+ cx_write(AUD_VOL_CTL, (1 << 6));
// start programming
- cx_write(AUD_CTL, 0x0000);
- cx_write(AUD_INIT, mode);
- cx_write(AUD_INIT_LD, 0x0001);
- cx_write(AUD_SOFT_RESET, 0x0001);
+ cx_write(MO_AUD_DMACNTRL, 0x0000);
+ msleep(100);
+ //cx_write(AUD_CTL, 0x0000);
+ cx_write(AUD_INIT, mode);
+ cx_write(AUD_INIT_LD, 0x0001);
+ cx_write(AUD_SOFT_RESET, 0x0001);
}
static void set_audio_finish(struct cx88_core *core, u32 ctl)
@@ -148,12 +147,13 @@ static void set_audio_finish(struct cx88_core *core, u32 ctl)
cx_write(AUD_I2SCNTL, 0);
//cx_write(AUD_APB_IN_RATE_ADJ, 0);
} else {
- ctl |= EN_DAC_ENABLE;
- cx_write(AUD_CTL, ctl);
+ ctl |= EN_DAC_ENABLE;
+ cx_write(AUD_CTL, ctl);
}
/* finish programming */
cx_write(AUD_SOFT_RESET, 0x0000);
+ cx_write(MO_AUD_DMACNTRL, 0x0003);
/* unmute */
volume = cx_sread(SHADOW_AUD_VOL_CTL);
@@ -162,486 +162,463 @@ static void set_audio_finish(struct cx88_core *core, u32 ctl)
/* ----------------------------------------------------------- */
-static void set_audio_standard_BTSC(struct cx88_core *core, unsigned int sap, u32 mode)
+static void set_audio_standard_BTSC(struct cx88_core *core, unsigned int sap,
+ u32 mode)
{
static const struct rlist btsc[] = {
- { AUD_AFE_12DB_EN, 0x00000001 },
- { AUD_OUT1_SEL, 0x00000013 },
- { AUD_OUT1_SHIFT, 0x00000000 },
- { AUD_POLY0_DDS_CONSTANT, 0x0012010c },
- { AUD_DMD_RA_DDS, 0x00c3e7aa },
- { AUD_DBX_IN_GAIN, 0x00004734 },
- { AUD_DBX_WBE_GAIN, 0x00004640 },
- { AUD_DBX_SE_GAIN, 0x00008d31 },
- { AUD_DCOC_0_SRC, 0x0000001a },
- { AUD_IIR1_4_SEL, 0x00000021 },
- { AUD_DCOC_PASS_IN, 0x00000003 },
- { AUD_DCOC_0_SHIFT_IN0, 0x0000000a },
- { AUD_DCOC_0_SHIFT_IN1, 0x00000008 },
- { AUD_DCOC_1_SHIFT_IN0, 0x0000000a },
- { AUD_DCOC_1_SHIFT_IN1, 0x00000008 },
- { AUD_DN0_FREQ, 0x0000283b },
- { AUD_DN2_SRC_SEL, 0x00000008 },
- { AUD_DN2_FREQ, 0x00003000 },
- { AUD_DN2_AFC, 0x00000002 },
- { AUD_DN2_SHFT, 0x00000000 },
- { AUD_IIR2_2_SEL, 0x00000020 },
- { AUD_IIR2_2_SHIFT, 0x00000000 },
- { AUD_IIR2_3_SEL, 0x0000001f },
- { AUD_IIR2_3_SHIFT, 0x00000000 },
- { AUD_CRDC1_SRC_SEL, 0x000003ce },
- { AUD_CRDC1_SHIFT, 0x00000000 },
- { AUD_CORDIC_SHIFT_1, 0x00000007 },
- { AUD_DCOC_1_SRC, 0x0000001b },
- { AUD_DCOC1_SHIFT, 0x00000000 },
- { AUD_RDSI_SEL, 0x00000008 },
- { AUD_RDSQ_SEL, 0x00000008 },
- { AUD_RDSI_SHIFT, 0x00000000 },
- { AUD_RDSQ_SHIFT, 0x00000000 },
- { AUD_POLYPH80SCALEFAC, 0x00000003 },
+ {AUD_AFE_12DB_EN, 0x00000001},
+ {AUD_OUT1_SEL, 0x00000013},
+ {AUD_OUT1_SHIFT, 0x00000000},
+ {AUD_POLY0_DDS_CONSTANT, 0x0012010c},
+ {AUD_DMD_RA_DDS, 0x00c3e7aa},
+ {AUD_DBX_IN_GAIN, 0x00004734},
+ {AUD_DBX_WBE_GAIN, 0x00004640},
+ {AUD_DBX_SE_GAIN, 0x00008d31},
+ {AUD_DCOC_0_SRC, 0x0000001a},
+ {AUD_IIR1_4_SEL, 0x00000021},
+ {AUD_DCOC_PASS_IN, 0x00000003},
+ {AUD_DCOC_0_SHIFT_IN0, 0x0000000a},
+ {AUD_DCOC_0_SHIFT_IN1, 0x00000008},
+ {AUD_DCOC_1_SHIFT_IN0, 0x0000000a},
+ {AUD_DCOC_1_SHIFT_IN1, 0x00000008},
+ {AUD_DN0_FREQ, 0x0000283b},
+ {AUD_DN2_SRC_SEL, 0x00000008},
+ {AUD_DN2_FREQ, 0x00003000},
+ {AUD_DN2_AFC, 0x00000002},
+ {AUD_DN2_SHFT, 0x00000000},
+ {AUD_IIR2_2_SEL, 0x00000020},
+ {AUD_IIR2_2_SHIFT, 0x00000000},
+ {AUD_IIR2_3_SEL, 0x0000001f},
+ {AUD_IIR2_3_SHIFT, 0x00000000},
+ {AUD_CRDC1_SRC_SEL, 0x000003ce},
+ {AUD_CRDC1_SHIFT, 0x00000000},
+ {AUD_CORDIC_SHIFT_1, 0x00000007},
+ {AUD_DCOC_1_SRC, 0x0000001b},
+ {AUD_DCOC1_SHIFT, 0x00000000},
+ {AUD_RDSI_SEL, 0x00000008},
+ {AUD_RDSQ_SEL, 0x00000008},
+ {AUD_RDSI_SHIFT, 0x00000000},
+ {AUD_RDSQ_SHIFT, 0x00000000},
+ {AUD_POLYPH80SCALEFAC, 0x00000003},
{ /* end of list */ },
};
static const struct rlist btsc_sap[] = {
- { AUD_AFE_12DB_EN, 0x00000001 },
- { AUD_DBX_IN_GAIN, 0x00007200 },
- { AUD_DBX_WBE_GAIN, 0x00006200 },
- { AUD_DBX_SE_GAIN, 0x00006200 },
- { AUD_IIR1_1_SEL, 0x00000000 },
- { AUD_IIR1_3_SEL, 0x00000001 },
- { AUD_DN1_SRC_SEL, 0x00000007 },
- { AUD_IIR1_4_SHIFT, 0x00000006 },
- { AUD_IIR2_1_SHIFT, 0x00000000 },
- { AUD_IIR2_2_SHIFT, 0x00000000 },
- { AUD_IIR3_0_SHIFT, 0x00000000 },
- { AUD_IIR3_1_SHIFT, 0x00000000 },
- { AUD_IIR3_0_SEL, 0x0000000d },
- { AUD_IIR3_1_SEL, 0x0000000e },
- { AUD_DEEMPH1_SRC_SEL, 0x00000014 },
- { AUD_DEEMPH1_SHIFT, 0x00000000 },
- { AUD_DEEMPH1_G0, 0x00004000 },
- { AUD_DEEMPH1_A0, 0x00000000 },
- { AUD_DEEMPH1_B0, 0x00000000 },
- { AUD_DEEMPH1_A1, 0x00000000 },
- { AUD_DEEMPH1_B1, 0x00000000 },
- { AUD_OUT0_SEL, 0x0000003f },
- { AUD_OUT1_SEL, 0x0000003f },
- { AUD_DN1_AFC, 0x00000002 },
- { AUD_DCOC_0_SHIFT_IN0, 0x0000000a },
- { AUD_DCOC_0_SHIFT_IN1, 0x00000008 },
- { AUD_DCOC_1_SHIFT_IN0, 0x0000000a },
- { AUD_DCOC_1_SHIFT_IN1, 0x00000008 },
- { AUD_IIR1_0_SEL, 0x0000001d },
- { AUD_IIR1_2_SEL, 0x0000001e },
- { AUD_IIR2_1_SEL, 0x00000002 },
- { AUD_IIR2_2_SEL, 0x00000004 },
- { AUD_IIR3_2_SEL, 0x0000000f },
- { AUD_DCOC2_SHIFT, 0x00000001 },
- { AUD_IIR3_2_SHIFT, 0x00000001 },
- { AUD_DEEMPH0_SRC_SEL, 0x00000014 },
- { AUD_CORDIC_SHIFT_1, 0x00000006 },
- { AUD_POLY0_DDS_CONSTANT, 0x000e4db2 },
- { AUD_DMD_RA_DDS, 0x00f696e6 },
- { AUD_IIR2_3_SEL, 0x00000025 },
- { AUD_IIR1_4_SEL, 0x00000021 },
- { AUD_DN1_FREQ, 0x0000c965 },
- { AUD_DCOC_PASS_IN, 0x00000003 },
- { AUD_DCOC_0_SRC, 0x0000001a },
- { AUD_DCOC_1_SRC, 0x0000001b },
- { AUD_DCOC1_SHIFT, 0x00000000 },
- { AUD_RDSI_SEL, 0x00000009 },
- { AUD_RDSQ_SEL, 0x00000009 },
- { AUD_RDSI_SHIFT, 0x00000000 },
- { AUD_RDSQ_SHIFT, 0x00000000 },
- { AUD_POLYPH80SCALEFAC, 0x00000003 },
+ {AUD_AFE_12DB_EN, 0x00000001},
+ {AUD_DBX_IN_GAIN, 0x00007200},
+ {AUD_DBX_WBE_GAIN, 0x00006200},
+ {AUD_DBX_SE_GAIN, 0x00006200},
+ {AUD_IIR1_1_SEL, 0x00000000},
+ {AUD_IIR1_3_SEL, 0x00000001},
+ {AUD_DN1_SRC_SEL, 0x00000007},
+ {AUD_IIR1_4_SHIFT, 0x00000006},
+ {AUD_IIR2_1_SHIFT, 0x00000000},
+ {AUD_IIR2_2_SHIFT, 0x00000000},
+ {AUD_IIR3_0_SHIFT, 0x00000000},
+ {AUD_IIR3_1_SHIFT, 0x00000000},
+ {AUD_IIR3_0_SEL, 0x0000000d},
+ {AUD_IIR3_1_SEL, 0x0000000e},
+ {AUD_DEEMPH1_SRC_SEL, 0x00000014},
+ {AUD_DEEMPH1_SHIFT, 0x00000000},
+ {AUD_DEEMPH1_G0, 0x00004000},
+ {AUD_DEEMPH1_A0, 0x00000000},
+ {AUD_DEEMPH1_B0, 0x00000000},
+ {AUD_DEEMPH1_A1, 0x00000000},
+ {AUD_DEEMPH1_B1, 0x00000000},
+ {AUD_OUT0_SEL, 0x0000003f},
+ {AUD_OUT1_SEL, 0x0000003f},
+ {AUD_DN1_AFC, 0x00000002},
+ {AUD_DCOC_0_SHIFT_IN0, 0x0000000a},
+ {AUD_DCOC_0_SHIFT_IN1, 0x00000008},
+ {AUD_DCOC_1_SHIFT_IN0, 0x0000000a},
+ {AUD_DCOC_1_SHIFT_IN1, 0x00000008},
+ {AUD_IIR1_0_SEL, 0x0000001d},
+ {AUD_IIR1_2_SEL, 0x0000001e},
+ {AUD_IIR2_1_SEL, 0x00000002},
+ {AUD_IIR2_2_SEL, 0x00000004},
+ {AUD_IIR3_2_SEL, 0x0000000f},
+ {AUD_DCOC2_SHIFT, 0x00000001},
+ {AUD_IIR3_2_SHIFT, 0x00000001},
+ {AUD_DEEMPH0_SRC_SEL, 0x00000014},
+ {AUD_CORDIC_SHIFT_1, 0x00000006},
+ {AUD_POLY0_DDS_CONSTANT, 0x000e4db2},
+ {AUD_DMD_RA_DDS, 0x00f696e6},
+ {AUD_IIR2_3_SEL, 0x00000025},
+ {AUD_IIR1_4_SEL, 0x00000021},
+ {AUD_DN1_FREQ, 0x0000c965},
+ {AUD_DCOC_PASS_IN, 0x00000003},
+ {AUD_DCOC_0_SRC, 0x0000001a},
+ {AUD_DCOC_1_SRC, 0x0000001b},
+ {AUD_DCOC1_SHIFT, 0x00000000},
+ {AUD_RDSI_SEL, 0x00000009},
+ {AUD_RDSQ_SEL, 0x00000009},
+ {AUD_RDSI_SHIFT, 0x00000000},
+ {AUD_RDSQ_SHIFT, 0x00000000},
+ {AUD_POLYPH80SCALEFAC, 0x00000003},
{ /* end of list */ },
};
mode |= EN_FMRADIO_EN_RDS;
if (sap) {
- dprintk("%s SAP (status: unknown)\n",__FUNCTION__);
- set_audio_start(core, SEL_SAP);
+ dprintk("%s SAP (status: unknown)\n", __FUNCTION__);
+ set_audio_start(core, SEL_SAP);
set_audio_registers(core, btsc_sap);
set_audio_finish(core, mode);
} else {
- dprintk("%s (status: known-good)\n",__FUNCTION__);
- set_audio_start(core, SEL_BTSC);
+ dprintk("%s (status: known-good)\n", __FUNCTION__);
+ set_audio_start(core, SEL_BTSC);
set_audio_registers(core, btsc);
set_audio_finish(core, mode);
}
}
-
-static void set_audio_standard_NICAM_L(struct cx88_core *core, int stereo)
+static void set_audio_standard_NICAM(struct cx88_core *core, u32 mode)
{
- /* This is probably weird..
- * Let's operate and find out. */
-
- static const struct rlist nicam_l_mono[] = {
- { AUD_ERRLOGPERIOD_R, 0x00000064 },
- { AUD_ERRINTRPTTHSHLD1_R, 0x00000FFF },
- { AUD_ERRINTRPTTHSHLD2_R, 0x0000001F },
- { AUD_ERRINTRPTTHSHLD3_R, 0x0000000F },
-
- { AUD_PDF_DDS_CNST_BYTE2, 0x48 },
- { AUD_PDF_DDS_CNST_BYTE1, 0x3D },
- { AUD_QAM_MODE, 0x00 },
- { AUD_PDF_DDS_CNST_BYTE0, 0xf5 },
- { AUD_PHACC_FREQ_8MSB, 0x3a },
- { AUD_PHACC_FREQ_8LSB, 0x4a },
-
- { AUD_DEEMPHGAIN_R, 0x6680 },
- { AUD_DEEMPHNUMER1_R, 0x353DE },
- { AUD_DEEMPHNUMER2_R, 0x1B1 },
- { AUD_DEEMPHDENOM1_R, 0x0F3D0 },
- { AUD_DEEMPHDENOM2_R, 0x0 },
- { AUD_FM_MODE_ENABLE, 0x7 },
- { AUD_POLYPH80SCALEFAC, 0x3 },
- { AUD_AFE_12DB_EN, 0x1 },
- { AAGC_GAIN, 0x0 },
- { AAGC_HYST, 0x18 },
- { AAGC_DEF, 0x20 },
- { AUD_DN0_FREQ, 0x0 },
- { AUD_POLY0_DDS_CONSTANT, 0x0E4DB2 },
- { AUD_DCOC_0_SRC, 0x21 },
- { AUD_IIR1_0_SEL, 0x0 },
- { AUD_IIR1_0_SHIFT, 0x7 },
- { AUD_IIR1_1_SEL, 0x2 },
- { AUD_IIR1_1_SHIFT, 0x0 },
- { AUD_DCOC_1_SRC, 0x3 },
- { AUD_DCOC1_SHIFT, 0x0 },
- { AUD_DCOC_PASS_IN, 0x0 },
- { AUD_IIR1_2_SEL, 0x23 },
- { AUD_IIR1_2_SHIFT, 0x0 },
- { AUD_IIR1_3_SEL, 0x4 },
- { AUD_IIR1_3_SHIFT, 0x7 },
- { AUD_IIR1_4_SEL, 0x5 },
- { AUD_IIR1_4_SHIFT, 0x7 },
- { AUD_IIR3_0_SEL, 0x7 },
- { AUD_IIR3_0_SHIFT, 0x0 },
- { AUD_DEEMPH0_SRC_SEL, 0x11 },
- { AUD_DEEMPH0_SHIFT, 0x0 },
- { AUD_DEEMPH0_G0, 0x7000 },
- { AUD_DEEMPH0_A0, 0x0 },
- { AUD_DEEMPH0_B0, 0x0 },
- { AUD_DEEMPH0_A1, 0x0 },
- { AUD_DEEMPH0_B1, 0x0 },
- { AUD_DEEMPH1_SRC_SEL, 0x11 },
- { AUD_DEEMPH1_SHIFT, 0x0 },
- { AUD_DEEMPH1_G0, 0x7000 },
- { AUD_DEEMPH1_A0, 0x0 },
- { AUD_DEEMPH1_B0, 0x0 },
- { AUD_DEEMPH1_A1, 0x0 },
- { AUD_DEEMPH1_B1, 0x0 },
- { AUD_OUT0_SEL, 0x3F },
- { AUD_OUT1_SEL, 0x3F },
- { AUD_DMD_RA_DDS, 0x0F5C285 },
- { AUD_PLL_INT, 0x1E },
- { AUD_PLL_DDS, 0x0 },
- { AUD_PLL_FRAC, 0x0E542 },
-
- // setup QAM registers
- { AUD_RATE_ADJ1, 0x00000100 },
- { AUD_RATE_ADJ2, 0x00000200 },
- { AUD_RATE_ADJ3, 0x00000300 },
- { AUD_RATE_ADJ4, 0x00000400 },
- { AUD_RATE_ADJ5, 0x00000500 },
- { AUD_RATE_THRES_DMD, 0x000000C0 },
+ static const struct rlist nicam_l[] = {
+ {AUD_AFE_12DB_EN, 0x00000001},
+ {AUD_RATE_ADJ1, 0x00000060},
+ {AUD_RATE_ADJ2, 0x000000F9},
+ {AUD_RATE_ADJ3, 0x000001CC},
+ {AUD_RATE_ADJ4, 0x000002B3},
+ {AUD_RATE_ADJ5, 0x00000726},
+ {AUD_DEEMPHDENOM1_R, 0x0000F3D0},
+ {AUD_DEEMPHDENOM2_R, 0x00000000},
+ {AUD_ERRLOGPERIOD_R, 0x00000064},
+ {AUD_ERRINTRPTTHSHLD1_R, 0x00000FFF},
+ {AUD_ERRINTRPTTHSHLD2_R, 0x0000001F},
+ {AUD_ERRINTRPTTHSHLD3_R, 0x0000000F},
+ {AUD_POLYPH80SCALEFAC, 0x00000003},
+ {AUD_DMD_RA_DDS, 0x00C00000},
+ {AUD_PLL_INT, 0x0000001E},
+ {AUD_PLL_DDS, 0x00000000},
+ {AUD_PLL_FRAC, 0x0000E542},
+ {AUD_START_TIMER, 0x00000000},
+ {AUD_DEEMPHNUMER1_R, 0x000353DE},
+ {AUD_DEEMPHNUMER2_R, 0x000001B1},
+ {AUD_PDF_DDS_CNST_BYTE2, 0x06},
+ {AUD_PDF_DDS_CNST_BYTE1, 0x82},
+ {AUD_PDF_DDS_CNST_BYTE0, 0x12},
+ {AUD_QAM_MODE, 0x05},
+ {AUD_PHACC_FREQ_8MSB, 0x34},
+ {AUD_PHACC_FREQ_8LSB, 0x4C},
+ {AUD_DEEMPHGAIN_R, 0x00006680},
+ {AUD_RATE_THRES_DMD, 0x000000C0},
{ /* end of list */ },
};
- static const struct rlist nicam_l[] = {
- // setup QAM registers
- { AUD_RATE_ADJ1, 0x00000060 },
- { AUD_RATE_ADJ2, 0x000000F9 },
- { AUD_RATE_ADJ3, 0x000001CC },
- { AUD_RATE_ADJ4, 0x000002B3 },
- { AUD_RATE_ADJ5, 0x00000726 },
- { AUD_DEEMPHDENOM1_R, 0x0000F3D0 },
- { AUD_DEEMPHDENOM2_R, 0x00000000 },
- { AUD_ERRLOGPERIOD_R, 0x00000064 },
- { AUD_ERRINTRPTTHSHLD1_R, 0x00000FFF },
- { AUD_ERRINTRPTTHSHLD2_R, 0x0000001F },
- { AUD_ERRINTRPTTHSHLD3_R, 0x0000000F },
- { AUD_POLYPH80SCALEFAC, 0x00000003 },
- { AUD_DMD_RA_DDS, 0x00C00000 },
- { AUD_PLL_INT, 0x0000001E },
- { AUD_PLL_DDS, 0x00000000 },
- { AUD_PLL_FRAC, 0x0000E542 },
- { AUD_START_TIMER, 0x00000000 },
- { AUD_DEEMPHNUMER1_R, 0x000353DE },
- { AUD_DEEMPHNUMER2_R, 0x000001B1 },
- { AUD_PDF_DDS_CNST_BYTE2, 0x06 },
- { AUD_PDF_DDS_CNST_BYTE1, 0x82 },
- { AUD_QAM_MODE, 0x05 },
- { AUD_PDF_DDS_CNST_BYTE0, 0x12 },
- { AUD_PHACC_FREQ_8MSB, 0x34 },
- { AUD_PHACC_FREQ_8LSB, 0x4C },
- { AUD_DEEMPHGAIN_R, 0x00006680 },
- { AUD_RATE_THRES_DMD, 0x000000C0 },
+ static const struct rlist nicam_bgdki_common[] = {
+ {AUD_AFE_12DB_EN, 0x00000001},
+ {AUD_RATE_ADJ1, 0x00000010},
+ {AUD_RATE_ADJ2, 0x00000040},
+ {AUD_RATE_ADJ3, 0x00000100},
+ {AUD_RATE_ADJ4, 0x00000400},
+ {AUD_RATE_ADJ5, 0x00001000},
+ //{ AUD_DMD_RA_DDS, 0x00c0d5ce },
+ {AUD_ERRLOGPERIOD_R, 0x00000fff},
+ {AUD_ERRINTRPTTHSHLD1_R, 0x000003ff},
+ {AUD_ERRINTRPTTHSHLD2_R, 0x000000ff},
+ {AUD_ERRINTRPTTHSHLD3_R, 0x0000003f},
+ {AUD_POLYPH80SCALEFAC, 0x00000003},
+ {AUD_DEEMPHGAIN_R, 0x000023c2},
+ {AUD_DEEMPHNUMER1_R, 0x0002a7bc},
+ {AUD_DEEMPHNUMER2_R, 0x0003023e},
+ {AUD_DEEMPHDENOM1_R, 0x0000f3d0},
+ {AUD_DEEMPHDENOM2_R, 0x00000000},
+ {AUD_PDF_DDS_CNST_BYTE2, 0x06},
+ {AUD_PDF_DDS_CNST_BYTE1, 0x82},
+ {AUD_QAM_MODE, 0x05},
{ /* end of list */ },
- } ;
- dprintk("%s (status: devel), stereo : %d\n",__FUNCTION__,stereo);
-
- if (!stereo) {
- /* AM Mono */
- set_audio_start(core, SEL_A2);
- set_audio_registers(core, nicam_l_mono);
- set_audio_finish(core, EN_A2_FORCE_MONO1);
- } else {
- /* Nicam Stereo */
- set_audio_start(core, SEL_NICAM);
- set_audio_registers(core, nicam_l);
- set_audio_finish(core, 0x1924); /* FIXME */
- }
-}
+ };
-static void set_audio_standard_PAL_I(struct cx88_core *core, int stereo)
-{
- static const struct rlist pal_i_fm_mono[] = {
- {AUD_ERRLOGPERIOD_R, 0x00000064},
- {AUD_ERRINTRPTTHSHLD1_R, 0x00000fff},
- {AUD_ERRINTRPTTHSHLD2_R, 0x0000001f},
- {AUD_ERRINTRPTTHSHLD3_R, 0x0000000f},
- {AUD_PDF_DDS_CNST_BYTE2, 0x06},
- {AUD_PDF_DDS_CNST_BYTE1, 0x82},
- {AUD_PDF_DDS_CNST_BYTE0, 0x12},
- {AUD_QAM_MODE, 0x05},
- {AUD_PHACC_FREQ_8MSB, 0x3a},
- {AUD_PHACC_FREQ_8LSB, 0x93},
- {AUD_DMD_RA_DDS, 0x002a4f2f},
- {AUD_PLL_INT, 0x0000001e},
- {AUD_PLL_DDS, 0x00000004},
- {AUD_PLL_FRAC, 0x0000e542},
- {AUD_RATE_ADJ1, 0x00000100},
- {AUD_RATE_ADJ2, 0x00000200},
- {AUD_RATE_ADJ3, 0x00000300},
- {AUD_RATE_ADJ4, 0x00000400},
- {AUD_RATE_ADJ5, 0x00000500},
- {AUD_THR_FR, 0x00000000},
- {AUD_PILOT_BQD_1_K0, 0x0000755b},
- {AUD_PILOT_BQD_1_K1, 0x00551340},
- {AUD_PILOT_BQD_1_K2, 0x006d30be},
- {AUD_PILOT_BQD_1_K3, 0xffd394af},
- {AUD_PILOT_BQD_1_K4, 0x00400000},
- {AUD_PILOT_BQD_2_K0, 0x00040000},
- {AUD_PILOT_BQD_2_K1, 0x002a4841},
- {AUD_PILOT_BQD_2_K2, 0x00400000},
- {AUD_PILOT_BQD_2_K3, 0x00000000},
- {AUD_PILOT_BQD_2_K4, 0x00000000},
- {AUD_MODE_CHG_TIMER, 0x00000060},
- {AUD_AFE_12DB_EN, 0x00000001},
- {AAGC_HYST, 0x0000000a},
- {AUD_CORDIC_SHIFT_0, 0x00000007},
- {AUD_CORDIC_SHIFT_1, 0x00000007},
- {AUD_C1_UP_THR, 0x00007000},
- {AUD_C1_LO_THR, 0x00005400},
- {AUD_C2_UP_THR, 0x00005400},
- {AUD_C2_LO_THR, 0x00003000},
- {AUD_DCOC_0_SRC, 0x0000001a},
- {AUD_DCOC0_SHIFT, 0x00000000},
- {AUD_DCOC_0_SHIFT_IN0, 0x0000000a},
- {AUD_DCOC_0_SHIFT_IN1, 0x00000008},
- {AUD_DCOC_PASS_IN, 0x00000003},
- {AUD_IIR3_0_SEL, 0x00000021},
- {AUD_DN2_AFC, 0x00000002},
- {AUD_DCOC_1_SRC, 0x0000001b},
- {AUD_DCOC1_SHIFT, 0x00000000},
- {AUD_DCOC_1_SHIFT_IN0, 0x0000000a},
- {AUD_DCOC_1_SHIFT_IN1, 0x00000008},
- {AUD_IIR3_1_SEL, 0x00000023},
- {AUD_DN0_FREQ, 0x000035a3},
- {AUD_DN2_FREQ, 0x000029c7},
- {AUD_CRDC0_SRC_SEL, 0x00000511},
- {AUD_IIR1_0_SEL, 0x00000001},
- {AUD_IIR1_1_SEL, 0x00000000},
- {AUD_IIR3_2_SEL, 0x00000003},
- {AUD_IIR3_2_SHIFT, 0x00000000},
- {AUD_IIR3_0_SEL, 0x00000002},
- {AUD_IIR2_0_SEL, 0x00000021},
- {AUD_IIR2_0_SHIFT, 0x00000002},
- {AUD_DEEMPH0_SRC_SEL, 0x0000000b},
- {AUD_DEEMPH1_SRC_SEL, 0x0000000b},
- {AUD_POLYPH80SCALEFAC, 0x00000001},
- {AUD_START_TIMER, 0x00000000},
- { /* end of list */ },
- };
-
- static const struct rlist pal_i_nicam[] = {
- { AUD_RATE_ADJ1, 0x00000010 },
- { AUD_RATE_ADJ2, 0x00000040 },
- { AUD_RATE_ADJ3, 0x00000100 },
- { AUD_RATE_ADJ4, 0x00000400 },
- { AUD_RATE_ADJ5, 0x00001000 },
- // { AUD_DMD_RA_DDS, 0x00c0d5ce },
- { AUD_DEEMPHGAIN_R, 0x000023c2 },
- { AUD_DEEMPHNUMER1_R, 0x0002a7bc },
- { AUD_DEEMPHNUMER2_R, 0x0003023e },
- { AUD_DEEMPHDENOM1_R, 0x0000f3d0 },
- { AUD_DEEMPHDENOM2_R, 0x00000000 },
- { AUD_DEEMPHDENOM2_R, 0x00000000 },
- { AUD_ERRLOGPERIOD_R, 0x00000fff },
- { AUD_ERRINTRPTTHSHLD1_R, 0x000003ff },
- { AUD_ERRINTRPTTHSHLD2_R, 0x000000ff },
- { AUD_ERRINTRPTTHSHLD3_R, 0x0000003f },
- { AUD_POLYPH80SCALEFAC, 0x00000003 },
- { AUD_PDF_DDS_CNST_BYTE2, 0x06 },
- { AUD_PDF_DDS_CNST_BYTE1, 0x82 },
- { AUD_PDF_DDS_CNST_BYTE0, 0x16 },
- { AUD_QAM_MODE, 0x05 },
- { AUD_PDF_DDS_CNST_BYTE0, 0x12 },
- { AUD_PHACC_FREQ_8MSB, 0x3a },
- { AUD_PHACC_FREQ_8LSB, 0x93 },
- { /* end of list */ },
+ static const struct rlist nicam_i[] = {
+ {AUD_PDF_DDS_CNST_BYTE0, 0x12},
+ {AUD_PHACC_FREQ_8MSB, 0x3a},
+ {AUD_PHACC_FREQ_8LSB, 0x93},
+ { /* end of list */ },
};
- dprintk("%s (status: devel), stereo : %d\n",__FUNCTION__,stereo);
+ static const struct rlist nicam_default[] = {
+ {AUD_PDF_DDS_CNST_BYTE0, 0x16},
+ {AUD_PHACC_FREQ_8MSB, 0x34},
+ {AUD_PHACC_FREQ_8LSB, 0x4c},
+ { /* end of list */ },
+ };
- if (!stereo) {
- /* FM Mono */
- set_audio_start(core, SEL_A2);
- set_audio_registers(core, pal_i_fm_mono);
- set_audio_finish(core, EN_DMTRX_SUMDIFF | EN_A2_FORCE_MONO1);
- } else {
- /* Nicam Stereo */
- set_audio_start(core, SEL_NICAM);
- set_audio_registers(core, pal_i_nicam);
- set_audio_finish(core, EN_DMTRX_LR | EN_DMTRX_BYPASS | EN_NICAM_AUTO_STEREO);
- }
+ set_audio_start(core,SEL_NICAM);
+ switch (core->tvaudio) {
+ case WW_L:
+ dprintk("%s SECAM-L NICAM (status: devel)\n", __FUNCTION__);
+ set_audio_registers(core, nicam_l);
+ break;
+ case WW_I:
+ dprintk("%s PAL-I NICAM (status: devel)\n", __FUNCTION__);
+ set_audio_registers(core, nicam_bgdki_common);
+ set_audio_registers(core, nicam_i);
+ break;
+ default:
+ dprintk("%s PAL-BGDK NICAM (status: unknown)\n", __FUNCTION__);
+ set_audio_registers(core, nicam_bgdki_common);
+ set_audio_registers(core, nicam_default);
+ break;
+ };
+
+ mode |= EN_DMTRX_LR | EN_DMTRX_BYPASS;
+ set_audio_finish(core, mode);
}
static void set_audio_standard_A2(struct cx88_core *core, u32 mode)
{
- static const struct rlist a2_common[] = {
- {AUD_ERRLOGPERIOD_R, 0x00000064},
- {AUD_ERRINTRPTTHSHLD1_R, 0x00000fff},
- {AUD_ERRINTRPTTHSHLD2_R, 0x0000001f},
- {AUD_ERRINTRPTTHSHLD3_R, 0x0000000f},
- {AUD_PDF_DDS_CNST_BYTE2, 0x06},
- {AUD_PDF_DDS_CNST_BYTE1, 0x82},
- {AUD_PDF_DDS_CNST_BYTE0, 0x12},
- {AUD_QAM_MODE, 0x05},
- {AUD_PHACC_FREQ_8MSB, 0x34},
- {AUD_PHACC_FREQ_8LSB, 0x4c},
- {AUD_RATE_ADJ1, 0x00000100},
- {AUD_RATE_ADJ2, 0x00000200},
- {AUD_RATE_ADJ3, 0x00000300},
- {AUD_RATE_ADJ4, 0x00000400},
- {AUD_RATE_ADJ5, 0x00000500},
- {AUD_THR_FR, 0x00000000},
- {AAGC_HYST, 0x0000001a},
- {AUD_PILOT_BQD_1_K0, 0x0000755b},
- {AUD_PILOT_BQD_1_K1, 0x00551340},
- {AUD_PILOT_BQD_1_K2, 0x006d30be},
- {AUD_PILOT_BQD_1_K3, 0xffd394af},
- {AUD_PILOT_BQD_1_K4, 0x00400000},
- {AUD_PILOT_BQD_2_K0, 0x00040000},
- {AUD_PILOT_BQD_2_K1, 0x002a4841},
- {AUD_PILOT_BQD_2_K2, 0x00400000},
- {AUD_PILOT_BQD_2_K3, 0x00000000},
- {AUD_PILOT_BQD_2_K4, 0x00000000},
- {AUD_MODE_CHG_TIMER, 0x00000040},
- {AUD_AFE_12DB_EN, 0x00000001},
- {AUD_CORDIC_SHIFT_0, 0x00000007},
- {AUD_CORDIC_SHIFT_1, 0x00000007},
- {AUD_DEEMPH0_G0, 0x00000380},
- {AUD_DEEMPH1_G0, 0x00000380},
- {AUD_DCOC_0_SRC, 0x0000001a},
- {AUD_DCOC0_SHIFT, 0x00000000},
- {AUD_DCOC_0_SHIFT_IN0, 0x0000000a},
- {AUD_DCOC_0_SHIFT_IN1, 0x00000008},
- {AUD_DCOC_PASS_IN, 0x00000003},
- {AUD_IIR3_0_SEL, 0x00000021},
- {AUD_DN2_AFC, 0x00000002},
- {AUD_DCOC_1_SRC, 0x0000001b},
- {AUD_DCOC1_SHIFT, 0x00000000},
- {AUD_DCOC_1_SHIFT_IN0, 0x0000000a},
- {AUD_DCOC_1_SHIFT_IN1, 0x00000008},
- {AUD_IIR3_1_SEL, 0x00000023},
- {AUD_RDSI_SEL, 0x00000017},
- {AUD_RDSI_SHIFT, 0x00000000},
- {AUD_RDSQ_SEL, 0x00000017},
- {AUD_RDSQ_SHIFT, 0x00000000},
- {AUD_PLL_INT, 0x0000001e},
- {AUD_PLL_DDS, 0x00000000},
- {AUD_PLL_FRAC, 0x0000e542},
- {AUD_POLYPH80SCALEFAC, 0x00000001},
- {AUD_START_TIMER, 0x00000000},
- { /* end of list */ },
+ static const struct rlist a2_bgdk_common[] = {
+ {AUD_ERRLOGPERIOD_R, 0x00000064},
+ {AUD_ERRINTRPTTHSHLD1_R, 0x00000fff},
+ {AUD_ERRINTRPTTHSHLD2_R, 0x0000001f},
+ {AUD_ERRINTRPTTHSHLD3_R, 0x0000000f},
+ {AUD_PDF_DDS_CNST_BYTE2, 0x06},
+ {AUD_PDF_DDS_CNST_BYTE1, 0x82},
+ {AUD_PDF_DDS_CNST_BYTE0, 0x12},
+ {AUD_QAM_MODE, 0x05},
+ {AUD_PHACC_FREQ_8MSB, 0x34},
+ {AUD_PHACC_FREQ_8LSB, 0x4c},
+ {AUD_RATE_ADJ1, 0x00000100},
+ {AUD_RATE_ADJ2, 0x00000200},
+ {AUD_RATE_ADJ3, 0x00000300},
+ {AUD_RATE_ADJ4, 0x00000400},
+ {AUD_RATE_ADJ5, 0x00000500},
+ {AUD_THR_FR, 0x00000000},
+ {AAGC_HYST, 0x0000001a},
+ {AUD_PILOT_BQD_1_K0, 0x0000755b},
+ {AUD_PILOT_BQD_1_K1, 0x00551340},
+ {AUD_PILOT_BQD_1_K2, 0x006d30be},
+ {AUD_PILOT_BQD_1_K3, 0xffd394af},
+ {AUD_PILOT_BQD_1_K4, 0x00400000},
+ {AUD_PILOT_BQD_2_K0, 0x00040000},
+ {AUD_PILOT_BQD_2_K1, 0x002a4841},
+ {AUD_PILOT_BQD_2_K2, 0x00400000},
+ {AUD_PILOT_BQD_2_K3, 0x00000000},
+ {AUD_PILOT_BQD_2_K4, 0x00000000},
+ {AUD_MODE_CHG_TIMER, 0x00000040},
+ {AUD_AFE_12DB_EN, 0x00000001},
+ {AUD_CORDIC_SHIFT_0, 0x00000007},
+ {AUD_CORDIC_SHIFT_1, 0x00000007},
+ {AUD_DEEMPH0_G0, 0x00000380},
+ {AUD_DEEMPH1_G0, 0x00000380},
+ {AUD_DCOC_0_SRC, 0x0000001a},
+ {AUD_DCOC0_SHIFT, 0x00000000},
+ {AUD_DCOC_0_SHIFT_IN0, 0x0000000a},
+ {AUD_DCOC_0_SHIFT_IN1, 0x00000008},
+ {AUD_DCOC_PASS_IN, 0x00000003},
+ {AUD_IIR3_0_SEL, 0x00000021},
+ {AUD_DN2_AFC, 0x00000002},
+ {AUD_DCOC_1_SRC, 0x0000001b},
+ {AUD_DCOC1_SHIFT, 0x00000000},
+ {AUD_DCOC_1_SHIFT_IN0, 0x0000000a},
+ {AUD_DCOC_1_SHIFT_IN1, 0x00000008},
+ {AUD_IIR3_1_SEL, 0x00000023},
+ {AUD_RDSI_SEL, 0x00000017},
+ {AUD_RDSI_SHIFT, 0x00000000},
+ {AUD_RDSQ_SEL, 0x00000017},
+ {AUD_RDSQ_SHIFT, 0x00000000},
+ {AUD_PLL_INT, 0x0000001e},
+ {AUD_PLL_DDS, 0x00000000},
+ {AUD_PLL_FRAC, 0x0000e542},
+ {AUD_POLYPH80SCALEFAC, 0x00000001},
+ {AUD_START_TIMER, 0x00000000},
+ { /* end of list */ },
};
static const struct rlist a2_bg[] = {
- {AUD_DMD_RA_DDS, 0x002a4f2f},
- {AUD_C1_UP_THR, 0x00007000},
- {AUD_C1_LO_THR, 0x00005400},
- {AUD_C2_UP_THR, 0x00005400},
- {AUD_C2_LO_THR, 0x00003000},
+ {AUD_DMD_RA_DDS, 0x002a4f2f},
+ {AUD_C1_UP_THR, 0x00007000},
+ {AUD_C1_LO_THR, 0x00005400},
+ {AUD_C2_UP_THR, 0x00005400},
+ {AUD_C2_LO_THR, 0x00003000},
{ /* end of list */ },
};
static const struct rlist a2_dk[] = {
- {AUD_DMD_RA_DDS, 0x002a4f2f},
- {AUD_C1_UP_THR, 0x00007000},
- {AUD_C1_LO_THR, 0x00005400},
- {AUD_C2_UP_THR, 0x00005400},
- {AUD_C2_LO_THR, 0x00003000},
- {AUD_DN0_FREQ, 0x00003a1c},
- {AUD_DN2_FREQ, 0x0000d2e0},
+ {AUD_DMD_RA_DDS, 0x002a4f2f},
+ {AUD_C1_UP_THR, 0x00007000},
+ {AUD_C1_LO_THR, 0x00005400},
+ {AUD_C2_UP_THR, 0x00005400},
+ {AUD_C2_LO_THR, 0x00003000},
+ {AUD_DN0_FREQ, 0x00003a1c},
+ {AUD_DN2_FREQ, 0x0000d2e0},
{ /* end of list */ },
};
-/* unknown, probably NTSC-M */
- static const struct rlist a2_m[] = {
- {AUD_DMD_RA_DDS, 0x002a0425},
- {AUD_C1_UP_THR, 0x00003c00},
- {AUD_C1_LO_THR, 0x00003000},
- {AUD_C2_UP_THR, 0x00006000},
- {AUD_C2_LO_THR, 0x00003c00},
- {AUD_DEEMPH0_A0, 0x00007a80},
- {AUD_DEEMPH1_A0, 0x00007a80},
- {AUD_DEEMPH0_G0, 0x00001200},
- {AUD_DEEMPH1_G0, 0x00001200},
- {AUD_DN0_FREQ, 0x0000283b},
- {AUD_DN1_FREQ, 0x00003418},
- {AUD_DN2_FREQ, 0x000029c7},
- {AUD_POLY0_DDS_CONSTANT, 0x000a7540},
+
+ static const struct rlist a1_i[] = {
+ {AUD_ERRLOGPERIOD_R, 0x00000064},
+ {AUD_ERRINTRPTTHSHLD1_R, 0x00000fff},
+ {AUD_ERRINTRPTTHSHLD2_R, 0x0000001f},
+ {AUD_ERRINTRPTTHSHLD3_R, 0x0000000f},
+ {AUD_PDF_DDS_CNST_BYTE2, 0x06},
+ {AUD_PDF_DDS_CNST_BYTE1, 0x82},
+ {AUD_PDF_DDS_CNST_BYTE0, 0x12},
+ {AUD_QAM_MODE, 0x05},
+ {AUD_PHACC_FREQ_8MSB, 0x3a},
+ {AUD_PHACC_FREQ_8LSB, 0x93},
+ {AUD_DMD_RA_DDS, 0x002a4f2f},
+ {AUD_PLL_INT, 0x0000001e},
+ {AUD_PLL_DDS, 0x00000004},
+ {AUD_PLL_FRAC, 0x0000e542},
+ {AUD_RATE_ADJ1, 0x00000100},
+ {AUD_RATE_ADJ2, 0x00000200},
+ {AUD_RATE_ADJ3, 0x00000300},
+ {AUD_RATE_ADJ4, 0x00000400},
+ {AUD_RATE_ADJ5, 0x00000500},
+ {AUD_THR_FR, 0x00000000},
+ {AUD_PILOT_BQD_1_K0, 0x0000755b},
+ {AUD_PILOT_BQD_1_K1, 0x00551340},
+ {AUD_PILOT_BQD_1_K2, 0x006d30be},
+ {AUD_PILOT_BQD_1_K3, 0xffd394af},
+ {AUD_PILOT_BQD_1_K4, 0x00400000},
+ {AUD_PILOT_BQD_2_K0, 0x00040000},
+ {AUD_PILOT_BQD_2_K1, 0x002a4841},
+ {AUD_PILOT_BQD_2_K2, 0x00400000},
+ {AUD_PILOT_BQD_2_K3, 0x00000000},
+ {AUD_PILOT_BQD_2_K4, 0x00000000},
+ {AUD_MODE_CHG_TIMER, 0x00000060},
+ {AUD_AFE_12DB_EN, 0x00000001},
+ {AAGC_HYST, 0x0000000a},
+ {AUD_CORDIC_SHIFT_0, 0x00000007},
+ {AUD_CORDIC_SHIFT_1, 0x00000007},
+ {AUD_C1_UP_THR, 0x00007000},
+ {AUD_C1_LO_THR, 0x00005400},
+ {AUD_C2_UP_THR, 0x00005400},
+ {AUD_C2_LO_THR, 0x00003000},
+ {AUD_DCOC_0_SRC, 0x0000001a},
+ {AUD_DCOC0_SHIFT, 0x00000000},
+ {AUD_DCOC_0_SHIFT_IN0, 0x0000000a},
+ {AUD_DCOC_0_SHIFT_IN1, 0x00000008},
+ {AUD_DCOC_PASS_IN, 0x00000003},
+ {AUD_IIR3_0_SEL, 0x00000021},
+ {AUD_DN2_AFC, 0x00000002},
+ {AUD_DCOC_1_SRC, 0x0000001b},
+ {AUD_DCOC1_SHIFT, 0x00000000},
+ {AUD_DCOC_1_SHIFT_IN0, 0x0000000a},
+ {AUD_DCOC_1_SHIFT_IN1, 0x00000008},
+ {AUD_IIR3_1_SEL, 0x00000023},
+ {AUD_DN0_FREQ, 0x000035a3},
+ {AUD_DN2_FREQ, 0x000029c7},
+ {AUD_CRDC0_SRC_SEL, 0x00000511},
+ {AUD_IIR1_0_SEL, 0x00000001},
+ {AUD_IIR1_1_SEL, 0x00000000},
+ {AUD_IIR3_2_SEL, 0x00000003},
+ {AUD_IIR3_2_SHIFT, 0x00000000},
+ {AUD_IIR3_0_SEL, 0x00000002},
+ {AUD_IIR2_0_SEL, 0x00000021},
+ {AUD_IIR2_0_SHIFT, 0x00000002},
+ {AUD_DEEMPH0_SRC_SEL, 0x0000000b},
+ {AUD_DEEMPH1_SRC_SEL, 0x0000000b},
+ {AUD_POLYPH80SCALEFAC, 0x00000001},
+ {AUD_START_TIMER, 0x00000000},
{ /* end of list */ },
};
- static const struct rlist a2_deemph50[] = {
- {AUD_DEEMPH0_G0, 0x00000380},
- {AUD_DEEMPH1_G0, 0x00000380},
- {AUD_DEEMPHGAIN_R, 0x000011e1},
- {AUD_DEEMPHNUMER1_R, 0x0002a7bc},
- {AUD_DEEMPHNUMER2_R, 0x0003023c},
- { /* end of list */ },
+ static const struct rlist am_l[] = {
+ {AUD_ERRLOGPERIOD_R, 0x00000064},
+ {AUD_ERRINTRPTTHSHLD1_R, 0x00000FFF},
+ {AUD_ERRINTRPTTHSHLD2_R, 0x0000001F},
+ {AUD_ERRINTRPTTHSHLD3_R, 0x0000000F},
+ {AUD_PDF_DDS_CNST_BYTE2, 0x48},
+ {AUD_PDF_DDS_CNST_BYTE1, 0x3D},
+ {AUD_QAM_MODE, 0x00},
+ {AUD_PDF_DDS_CNST_BYTE0, 0xf5},
+ {AUD_PHACC_FREQ_8MSB, 0x3a},
+ {AUD_PHACC_FREQ_8LSB, 0x4a},
+ {AUD_DEEMPHGAIN_R, 0x00006680},
+ {AUD_DEEMPHNUMER1_R, 0x000353DE},
+ {AUD_DEEMPHNUMER2_R, 0x000001B1},
+ {AUD_DEEMPHDENOM1_R, 0x0000F3D0},
+ {AUD_DEEMPHDENOM2_R, 0x00000000},
+ {AUD_FM_MODE_ENABLE, 0x00000007},
+ {AUD_POLYPH80SCALEFAC, 0x00000003},
+ {AUD_AFE_12DB_EN, 0x00000001},
+ {AAGC_GAIN, 0x00000000},
+ {AAGC_HYST, 0x00000018},
+ {AAGC_DEF, 0x00000020},
+ {AUD_DN0_FREQ, 0x00000000},
+ {AUD_POLY0_DDS_CONSTANT, 0x000E4DB2},
+ {AUD_DCOC_0_SRC, 0x00000021},
+ {AUD_IIR1_0_SEL, 0x00000000},
+ {AUD_IIR1_0_SHIFT, 0x00000007},
+ {AUD_IIR1_1_SEL, 0x00000002},
+ {AUD_IIR1_1_SHIFT, 0x00000000},
+ {AUD_DCOC_1_SRC, 0x00000003},
+ {AUD_DCOC1_SHIFT, 0x00000000},
+ {AUD_DCOC_PASS_IN, 0x00000000},
+ {AUD_IIR1_2_SEL, 0x00000023},
+ {AUD_IIR1_2_SHIFT, 0x00000000},
+ {AUD_IIR1_3_SEL, 0x00000004},
+ {AUD_IIR1_3_SHIFT, 0x00000007},
+ {AUD_IIR1_4_SEL, 0x00000005},
+ {AUD_IIR1_4_SHIFT, 0x00000007},
+ {AUD_IIR3_0_SEL, 0x00000007},
+ {AUD_IIR3_0_SHIFT, 0x00000000},
+ {AUD_DEEMPH0_SRC_SEL, 0x00000011},
+ {AUD_DEEMPH0_SHIFT, 0x00000000},
+ {AUD_DEEMPH0_G0, 0x00007000},
+ {AUD_DEEMPH0_A0, 0x00000000},
+ {AUD_DEEMPH0_B0, 0x00000000},
+ {AUD_DEEMPH0_A1, 0x00000000},
+ {AUD_DEEMPH0_B1, 0x00000000},
+ {AUD_DEEMPH1_SRC_SEL, 0x00000011},
+ {AUD_DEEMPH1_SHIFT, 0x00000000},
+ {AUD_DEEMPH1_G0, 0x00007000},
+ {AUD_DEEMPH1_A0, 0x00000000},
+ {AUD_DEEMPH1_B0, 0x00000000},
+ {AUD_DEEMPH1_A1, 0x00000000},
+ {AUD_DEEMPH1_B1, 0x00000000},
+ {AUD_OUT0_SEL, 0x0000003F},
+ {AUD_OUT1_SEL, 0x0000003F},
+ {AUD_DMD_RA_DDS, 0x00F5C285},
+ {AUD_PLL_INT, 0x0000001E},
+ {AUD_PLL_DDS, 0x00000000},
+ {AUD_PLL_FRAC, 0x0000E542},
+ {AUD_RATE_ADJ1, 0x00000100},
+ {AUD_RATE_ADJ2, 0x00000200},
+ {AUD_RATE_ADJ3, 0x00000300},
+ {AUD_RATE_ADJ4, 0x00000400},
+ {AUD_RATE_ADJ5, 0x00000500},
+ {AUD_RATE_THRES_DMD, 0x000000C0},
+ { /* end of list */ },
};
- static const struct rlist a2_deemph75[] = {
- {AUD_DEEMPH0_G0, 0x00000480},
- {AUD_DEEMPH1_G0, 0x00000480},
- {AUD_DEEMPHGAIN_R, 0x00009000},
- {AUD_DEEMPHNUMER1_R, 0x000353de},
- {AUD_DEEMPHNUMER2_R, 0x000001b1},
+ static const struct rlist a2_deemph50[] = {
+ {AUD_DEEMPH0_G0, 0x00000380},
+ {AUD_DEEMPH1_G0, 0x00000380},
+ {AUD_DEEMPHGAIN_R, 0x000011e1},
+ {AUD_DEEMPHNUMER1_R, 0x0002a7bc},
+ {AUD_DEEMPHNUMER2_R, 0x0003023c},
{ /* end of list */ },
};
set_audio_start(core, SEL_A2);
- set_audio_registers(core, a2_common);
switch (core->tvaudio) {
- case WW_A2_BG:
- dprintk("%s PAL-BG A2 (status: known-good)\n",__FUNCTION__);
- set_audio_registers(core, a2_bg);
- set_audio_registers(core, a2_deemph50);
+ case WW_BG:
+ dprintk("%s PAL-BG A1/2 (status: known-good)\n", __FUNCTION__);
+ set_audio_registers(core, a2_bgdk_common);
+ set_audio_registers(core, a2_bg);
+ set_audio_registers(core, a2_deemph50);
break;
- case WW_A2_DK:
- dprintk("%s PAL-DK A2 (status: known-good)\n",__FUNCTION__);
- set_audio_registers(core, a2_dk);
- set_audio_registers(core, a2_deemph50);
+ case WW_DK:
+ dprintk("%s PAL-DK A1/2 (status: known-good)\n", __FUNCTION__);
+ set_audio_registers(core, a2_bgdk_common);
+ set_audio_registers(core, a2_dk);
+ set_audio_registers(core, a2_deemph50);
break;
- case WW_A2_M:
- dprintk("%s NTSC-M A2 (status: unknown)\n",__FUNCTION__);
- set_audio_registers(core, a2_m);
- set_audio_registers(core, a2_deemph75);
+ case WW_I:
+ dprintk("%s PAL-I A1 (status: known-good)\n", __FUNCTION__);
+ set_audio_registers(core, a1_i);
+ set_audio_registers(core, a2_deemph50);
+ break;
+ case WW_L:
+ dprintk("%s AM-L (status: devel)\n", __FUNCTION__);
+ set_audio_registers(core, am_l);
+ break;
+ default:
+ dprintk("%s Warning: wrong value\n", __FUNCTION__);
+ return;
break;
};
@@ -656,71 +633,71 @@ static void set_audio_standard_EIAJ(struct cx88_core *core)
{ /* end of list */ },
};
- dprintk("%s (status: unknown)\n",__FUNCTION__);
+ dprintk("%s (status: unknown)\n", __FUNCTION__);
set_audio_start(core, SEL_EIAJ);
set_audio_registers(core, eiaj);
set_audio_finish(core, EN_EIAJ_AUTO_STEREO);
}
-static void set_audio_standard_FM(struct cx88_core *core, enum cx88_deemph_type deemph)
+static void set_audio_standard_FM(struct cx88_core *core,
+ enum cx88_deemph_type deemph)
{
static const struct rlist fm_deemph_50[] = {
- { AUD_DEEMPH0_G0, 0x0C45 },
- { AUD_DEEMPH0_A0, 0x6262 },
- { AUD_DEEMPH0_B0, 0x1C29 },
- { AUD_DEEMPH0_A1, 0x3FC66},
- { AUD_DEEMPH0_B1, 0x399A },
-
- { AUD_DEEMPH1_G0, 0x0D80 },
- { AUD_DEEMPH1_A0, 0x6262 },
- { AUD_DEEMPH1_B0, 0x1C29 },
- { AUD_DEEMPH1_A1, 0x3FC66},
- { AUD_DEEMPH1_B1, 0x399A},
-
- { AUD_POLYPH80SCALEFAC, 0x0003},
+ {AUD_DEEMPH0_G0, 0x0C45},
+ {AUD_DEEMPH0_A0, 0x6262},
+ {AUD_DEEMPH0_B0, 0x1C29},
+ {AUD_DEEMPH0_A1, 0x3FC66},
+ {AUD_DEEMPH0_B1, 0x399A},
+
+ {AUD_DEEMPH1_G0, 0x0D80},
+ {AUD_DEEMPH1_A0, 0x6262},
+ {AUD_DEEMPH1_B0, 0x1C29},
+ {AUD_DEEMPH1_A1, 0x3FC66},
+ {AUD_DEEMPH1_B1, 0x399A},
+
+ {AUD_POLYPH80SCALEFAC, 0x0003},
{ /* end of list */ },
};
static const struct rlist fm_deemph_75[] = {
- { AUD_DEEMPH0_G0, 0x091B },
- { AUD_DEEMPH0_A0, 0x6B68 },
- { AUD_DEEMPH0_B0, 0x11EC },
- { AUD_DEEMPH0_A1, 0x3FC66},
- { AUD_DEEMPH0_B1, 0x399A },
-
- { AUD_DEEMPH1_G0, 0x0AA0 },
- { AUD_DEEMPH1_A0, 0x6B68 },
- { AUD_DEEMPH1_B0, 0x11EC },
- { AUD_DEEMPH1_A1, 0x3FC66},
- { AUD_DEEMPH1_B1, 0x399A},
-
- { AUD_POLYPH80SCALEFAC, 0x0003},
+ {AUD_DEEMPH0_G0, 0x091B},
+ {AUD_DEEMPH0_A0, 0x6B68},
+ {AUD_DEEMPH0_B0, 0x11EC},
+ {AUD_DEEMPH0_A1, 0x3FC66},
+ {AUD_DEEMPH0_B1, 0x399A},
+
+ {AUD_DEEMPH1_G0, 0x0AA0},
+ {AUD_DEEMPH1_A0, 0x6B68},
+ {AUD_DEEMPH1_B0, 0x11EC},
+ {AUD_DEEMPH1_A1, 0x3FC66},
+ {AUD_DEEMPH1_B1, 0x399A},
+
+ {AUD_POLYPH80SCALEFAC, 0x0003},
{ /* end of list */ },
};
/* It is enough to leave default values? */
static const struct rlist fm_no_deemph[] = {
- { AUD_POLYPH80SCALEFAC, 0x0003},
+ {AUD_POLYPH80SCALEFAC, 0x0003},
{ /* end of list */ },
};
- dprintk("%s (status: unknown)\n",__FUNCTION__);
+ dprintk("%s (status: unknown)\n", __FUNCTION__);
set_audio_start(core, SEL_FMRADIO);
- switch (deemph)
- {
- case FM_NO_DEEMPH:
- set_audio_registers(core, fm_no_deemph);
- break;
+ switch (deemph) {
+ case FM_NO_DEEMPH:
+ set_audio_registers(core, fm_no_deemph);
+ break;
- case FM_DEEMPH_50:
- set_audio_registers(core, fm_deemph_50);
- break;
+ case FM_DEEMPH_50:
+ set_audio_registers(core, fm_deemph_50);
+ break;
- case FM_DEEMPH_75:
- set_audio_registers(core, fm_deemph_75);
- break;
+ case FM_DEEMPH_75:
+ set_audio_registers(core, fm_deemph_75);
+ break;
}
set_audio_finish(core, EN_FMRADIO_AUTO_STEREO);
@@ -728,36 +705,64 @@ static void set_audio_standard_FM(struct cx88_core *core, enum cx88_deemph_type
/* ----------------------------------------------------------- */
+int cx88_detect_nicam(struct cx88_core *core)
+{
+ int i, j = 0;
+
+ dprintk("start nicam autodetect.\n");
+
+ for (i = 0; i < 6; i++) {
+ /* if bit1=1 then nicam is detected */
+ j += ((cx_read(AUD_NICAM_STATUS2) & 0x02) >> 1);
+
+ /* 3x detected: absolutly sure now */
+ if (j == 3) {
+ dprintk("nicam is detected.\n");
+ return 1;
+ }
+
+ /* wait a little bit for next reading status */
+ msleep(10);
+ }
+
+ dprintk("nicam is not detected.\n");
+ return 0;
+}
+
void cx88_set_tvaudio(struct cx88_core *core)
{
switch (core->tvaudio) {
case WW_BTSC:
set_audio_standard_BTSC(core, 0, EN_BTSC_AUTO_STEREO);
break;
- case WW_NICAM_BGDKL:
- set_audio_standard_NICAM_L(core,0);
- break;
- case WW_NICAM_I:
- set_audio_standard_PAL_I(core,0);
- break;
- case WW_A2_BG:
- case WW_A2_DK:
- case WW_A2_M:
- set_audio_standard_A2(core, EN_A2_FORCE_MONO1);
+ case WW_BG:
+ case WW_DK:
+ case WW_I:
+ case WW_L:
+ /* prepare all dsp registers */
+ set_audio_standard_A2(core, EN_A2_FORCE_MONO1);
+
+ /* set nicam mode - otherwise
+ AUD_NICAM_STATUS2 contains wrong values */
+ set_audio_standard_NICAM(core, EN_NICAM_AUTO_STEREO);
+ if (0 == cx88_detect_nicam(core)) {
+ /* fall back to fm / am mono */
+ set_audio_standard_A2(core, EN_A2_FORCE_MONO1);
+ core->use_nicam = 0;
+ } else {
+ core->use_nicam = 1;
+ }
break;
case WW_EIAJ:
set_audio_standard_EIAJ(core);
break;
case WW_FM:
- set_audio_standard_FM(core,FM_NO_DEEMPH);
- break;
- case WW_SYSTEM_L_AM:
- set_audio_standard_NICAM_L(core, 1);
+ set_audio_standard_FM(core, FM_NO_DEEMPH);
break;
case WW_NONE:
default:
printk("%s/0: unknown tv audio mode [%d]\n",
- core->name, core->tvaudio);
+ core->name, core->tvaudio);
break;
}
return;
@@ -766,24 +771,16 @@ void cx88_set_tvaudio(struct cx88_core *core)
void cx88_newstation(struct cx88_core *core)
{
core->audiomode_manual = UNSET;
-
- switch (core->tvaudio) {
- case WW_SYSTEM_L_AM:
- /* try nicam ... */
- core->audiomode_current = V4L2_TUNER_MODE_STEREO;
- set_audio_standard_NICAM_L(core, 1);
- break;
- }
}
void cx88_get_stereo(struct cx88_core *core, struct v4l2_tuner *t)
{
- static char *m[] = {"stereo", "dual mono", "mono", "sap"};
- static char *p[] = {"no pilot", "pilot c1", "pilot c2", "?"};
- u32 reg,mode,pilot;
+ static char *m[] = { "stereo", "dual mono", "mono", "sap" };
+ static char *p[] = { "no pilot", "pilot c1", "pilot c2", "?" };
+ u32 reg, mode, pilot;
- reg = cx_read(AUD_STATUS);
- mode = reg & 0x03;
+ reg = cx_read(AUD_STATUS);
+ mode = reg & 0x03;
pilot = (reg >> 2) & 0x03;
if (core->astat != reg)
@@ -800,14 +797,13 @@ void cx88_get_stereo(struct cx88_core *core, struct v4l2_tuner *t)
# if 0
t->capability = V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_SAP |
- V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2;
+ V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2;
t->rxsubchans = V4L2_TUNER_SUB_MONO;
- t->audmode = V4L2_TUNER_MODE_MONO;
+ t->audmode = V4L2_TUNER_MODE_MONO;
switch (core->tvaudio) {
case WW_BTSC:
- t->capability = V4L2_TUNER_CAP_STEREO |
- V4L2_TUNER_CAP_SAP;
+ t->capability = V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_SAP;
t->rxsubchans = V4L2_TUNER_SUB_STEREO;
if (1 == pilot) {
/* SAP */
@@ -819,13 +815,15 @@ void cx88_get_stereo(struct cx88_core *core, struct v4l2_tuner *t)
case WW_A2_M:
if (1 == pilot) {
/* stereo */
- t->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
+ t->rxsubchans =
+ V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
if (0 == mode)
t->audmode = V4L2_TUNER_MODE_STEREO;
}
if (2 == pilot) {
/* dual language -- FIXME */
- t->rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
+ t->rxsubchans =
+ V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
t->audmode = V4L2_TUNER_MODE_LANG1;
}
break;
@@ -840,7 +838,7 @@ void cx88_get_stereo(struct cx88_core *core, struct v4l2_tuner *t)
t->audmode = V4L2_TUNER_MODE_STEREO;
t->rxsubchans |= V4L2_TUNER_SUB_STEREO;
}
- break ;
+ break;
default:
/* nothing */
break;
@@ -851,7 +849,7 @@ void cx88_get_stereo(struct cx88_core *core, struct v4l2_tuner *t)
void cx88_set_stereo(struct cx88_core *core, u32 mode, int manual)
{
- u32 ctl = UNSET;
+ u32 ctl = UNSET;
u32 mask = UNSET;
if (manual) {
@@ -879,68 +877,58 @@ void cx88_set_stereo(struct cx88_core *core, u32 mode, int manual)
break;
}
break;
- case WW_A2_BG:
- case WW_A2_DK:
- case WW_A2_M:
- switch (mode) {
- case V4L2_TUNER_MODE_MONO:
- case V4L2_TUNER_MODE_LANG1:
- set_audio_standard_A2(core, EN_A2_FORCE_MONO1);
- break;
- case V4L2_TUNER_MODE_LANG2:
- set_audio_standard_A2(core, EN_A2_FORCE_MONO2);
- break;
- case V4L2_TUNER_MODE_STEREO:
- set_audio_standard_A2(core, EN_A2_FORCE_STEREO);
- break;
- }
- break;
- case WW_NICAM_BGDKL:
- switch (mode) {
- case V4L2_TUNER_MODE_MONO:
- ctl = EN_NICAM_FORCE_MONO1;
- mask = 0x3f;
- break;
- case V4L2_TUNER_MODE_LANG1:
- ctl = EN_NICAM_AUTO_MONO2;
- mask = 0x3f;
- break;
- case V4L2_TUNER_MODE_STEREO:
- ctl = EN_NICAM_FORCE_STEREO | EN_DMTRX_LR;
- mask = 0x93f;
- break;
- }
- break;
- case WW_SYSTEM_L_AM:
- switch (mode) {
- case V4L2_TUNER_MODE_MONO:
- case V4L2_TUNER_MODE_LANG1: /* FIXME */
- set_audio_standard_NICAM_L(core, 0);
- break;
- case V4L2_TUNER_MODE_STEREO:
- set_audio_standard_NICAM_L(core, 1);
- break;
- }
- break;
- case WW_NICAM_I:
- switch (mode) {
- case V4L2_TUNER_MODE_MONO:
- case V4L2_TUNER_MODE_LANG1:
- set_audio_standard_PAL_I(core, 0);
- break;
- case V4L2_TUNER_MODE_STEREO:
- set_audio_standard_PAL_I(core, 1);
- break;
+ case WW_BG:
+ case WW_DK:
+ case WW_I:
+ case WW_L:
+ if (1 == core->use_nicam) {
+ switch (mode) {
+ case V4L2_TUNER_MODE_MONO:
+ case V4L2_TUNER_MODE_LANG1:
+ set_audio_standard_NICAM(core,
+ EN_NICAM_FORCE_MONO1);
+ break;
+ case V4L2_TUNER_MODE_LANG2:
+ set_audio_standard_NICAM(core,
+ EN_NICAM_FORCE_MONO2);
+ break;
+ case V4L2_TUNER_MODE_STEREO:
+ set_audio_standard_NICAM(core,
+ EN_NICAM_FORCE_STEREO);
+ break;
+ }
+ } else {
+ if ((core->tvaudio == WW_I) || (core->tvaudio == WW_L)) {
+ /* fall back to fm / am mono */
+ set_audio_standard_A2(core, EN_A2_FORCE_MONO1);
+ } else {
+ /* TODO: Add A2 autodection */
+ switch (mode) {
+ case V4L2_TUNER_MODE_MONO:
+ case V4L2_TUNER_MODE_LANG1:
+ set_audio_standard_A2(core,
+ EN_A2_FORCE_MONO1);
+ break;
+ case V4L2_TUNER_MODE_LANG2:
+ set_audio_standard_A2(core,
+ EN_A2_FORCE_MONO2);
+ break;
+ case V4L2_TUNER_MODE_STEREO:
+ set_audio_standard_A2(core,
+ EN_A2_FORCE_STEREO);
+ break;
+ }
+ }
}
break;
case WW_FM:
switch (mode) {
case V4L2_TUNER_MODE_MONO:
- ctl = EN_FMRADIO_FORCE_MONO;
+ ctl = EN_FMRADIO_FORCE_MONO;
mask = 0x3f;
break;
case V4L2_TUNER_MODE_STEREO:
- ctl = EN_FMRADIO_AUTO_STEREO;
+ ctl = EN_FMRADIO_AUTO_STEREO;
mask = 0x3f;
break;
}
@@ -970,8 +958,8 @@ int cx88_audio_thread(void *data)
break;
/* just monitor the audio status for now ... */
- memset(&t,0,sizeof(t));
- cx88_get_stereo(core,&t);
+ memset(&t, 0, sizeof(t));
+ cx88_get_stereo(core, &t);
if (UNSET != core->audiomode_manual)
/* manually set, don't do anything. */
diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c
index 3dbc074fb515..24a48f8a48c1 100644
--- a/drivers/media/video/cx88/cx88-video.c
+++ b/drivers/media/video/cx88/cx88-video.c
@@ -34,6 +34,9 @@
#include "cx88.h"
+/* Include V4L1 specific functions. Should be removed soon */
+#include <linux/videodev.h>
+
MODULE_DESCRIPTION("v4l2 driver module for cx2388x based TV cards");
MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
MODULE_LICENSE("GPL");
@@ -100,7 +103,7 @@ static struct cx88_tvnorm tvnorms[] = {
.id = V4L2_STD_PAL_I,
.cxiformat = VideoFormatPAL,
.cxoformat = 0x181f0008,
- },{
+ },{
.name = "PAL-M",
.id = V4L2_STD_PAL_M,
.cxiformat = VideoFormatPALM,
@@ -470,7 +473,7 @@ static int restart_video_queue(struct cx8800_dev *dev,
struct list_head *item;
if (!list_empty(&q->active)) {
- buf = list_entry(q->active.next, struct cx88_buffer, vb.queue);
+ buf = list_entry(q->active.next, struct cx88_buffer, vb.queue);
dprintk(2,"restart_queue [%p/%d]: restart dma\n",
buf, buf->vb.i);
start_video_dma(dev, q, buf);
@@ -486,7 +489,7 @@ static int restart_video_queue(struct cx8800_dev *dev,
for (;;) {
if (list_empty(&q->queued))
return 0;
- buf = list_entry(q->queued.next, struct cx88_buffer, vb.queue);
+ buf = list_entry(q->queued.next, struct cx88_buffer, vb.queue);
if (NULL == prev) {
list_del(&buf->vb.queue);
list_add_tail(&buf->vb.queue,&q->active);
@@ -783,11 +786,11 @@ static int video_open(struct inode *inode, struct file *file)
cx88_call_i2c_clients(core,AUDC_SET_RADIO,NULL);
}
- return 0;
+ return 0;
}
static ssize_t
-video_read(struct file *file, char *data, size_t count, loff_t *ppos)
+video_read(struct file *file, char __user *data, size_t count, loff_t *ppos)
{
struct cx8800_fh *fh = file->private_data;
@@ -922,7 +925,7 @@ static int set_control(struct cx88_core *core, struct v4l2_control *ctl)
{
/* struct cx88_core *core = dev->core; */
struct cx88_ctrl *c = NULL;
- u32 v_sat_value;
+ u32 v_sat_value;
u32 value;
int i;
@@ -1187,7 +1190,7 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
struct v4l2_format *f = arg;
return cx8800_try_fmt(dev,fh,f);
}
-
+#ifdef HAVE_V4L1
/* --- streaming capture ------------------------------------- */
case VIDIOCGMBUF:
{
@@ -1213,6 +1216,7 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
}
return 0;
}
+#endif
case VIDIOC_REQBUFS:
return videobuf_reqbufs(get_queue(fh), arg);
@@ -1244,7 +1248,6 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
res_free(dev,fh,res);
return 0;
}
-
default:
return cx88_do_ioctl( inode, file, fh->radio, core, cmd, arg, video_do_ioctl );
}
@@ -1252,15 +1255,13 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
}
int cx88_do_ioctl(struct inode *inode, struct file *file, int radio,
- struct cx88_core *core, unsigned int cmd, void *arg, v4l2_kioctl driver_ioctl)
+ struct cx88_core *core, unsigned int cmd, void *arg, v4l2_kioctl driver_ioctl)
{
int err;
+ dprintk( 1, "CORE IOCTL: 0x%x\n", cmd );
if (video_debug > 1)
cx88_print_ioctl(core->name,cmd);
- printk( KERN_INFO "CORE IOCTL: 0x%x\n", cmd );
- cx88_print_ioctl(core->name,cmd);
- dprintk( 1, "CORE IOCTL: 0x%x\n", cmd );
switch (cmd) {
/* ---------- tv norms ---------- */
@@ -1401,7 +1402,7 @@ int cx88_do_ioctl(struct inode *inode, struct file *file, int radio,
cx88_get_stereo(core ,t);
reg = cx_read(MO_DEVICE_STATUS);
- t->signal = (reg & (1<<5)) ? 0xffff : 0x0000;
+ t->signal = (reg & (1<<5)) ? 0xffff : 0x0000;
return 0;
}
case VIDIOC_S_TUNER:
@@ -1488,7 +1489,7 @@ static int radio_do_ioctl(struct inode *inode, struct file *file,
struct v4l2_capability *cap = arg;
memset(cap,0,sizeof(*cap));
- strcpy(cap->driver, "cx8800");
+ strcpy(cap->driver, "cx8800");
strlcpy(cap->card, cx88_boards[core->board].name,
sizeof(cap->card));
sprintf(cap->bus_info,"PCI:%s", pci_name(dev->pci));
@@ -1505,6 +1506,7 @@ static int radio_do_ioctl(struct inode *inode, struct file *file,
memset(t,0,sizeof(*t));
strcpy(t->name, "Radio");
+ t->type = V4L2_TUNER_RADIO;
cx88_call_i2c_clients(core,VIDIOC_G_TUNER,t);
return 0;
@@ -1539,6 +1541,7 @@ static int radio_do_ioctl(struct inode *inode, struct file *file,
*id = 0;
return 0;
}
+#ifdef HAVE_V4L1
case VIDIOCSTUNER:
{
struct video_tuner *v = arg;
@@ -1549,6 +1552,7 @@ static int radio_do_ioctl(struct inode *inode, struct file *file,
cx88_call_i2c_clients(core,VIDIOCSTUNER,v);
return 0;
}
+#endif
case VIDIOC_S_TUNER:
{
struct v4l2_tuner *t = arg;
@@ -1829,8 +1833,8 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev,
/* print pci info */
pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &dev->pci_rev);
- pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &dev->pci_lat);
- printk(KERN_INFO "%s/0: found at %s, rev: %d, irq: %d, "
+ pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &dev->pci_lat);
+ printk(KERN_INFO "%s/0: found at %s, rev: %d, irq: %d, "
"latency: %d, mmio: 0x%lx\n", core->name,
pci_name(pci_dev), dev->pci_rev, pci_dev->irq,
dev->pci_lat,pci_resource_start(pci_dev,0));
@@ -1946,7 +1950,7 @@ fail_free:
static void __devexit cx8800_finidev(struct pci_dev *pci_dev)
{
- struct cx8800_dev *dev = pci_get_drvdata(pci_dev);
+ struct cx8800_dev *dev = pci_get_drvdata(pci_dev);
struct cx88_core *core = dev->core;
/* stop thread */
diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h
index f48dd4353568..b19d3a9e2298 100644
--- a/drivers/media/video/cx88/cx88.h
+++ b/drivers/media/video/cx88/cx88.h
@@ -22,7 +22,7 @@
#include <linux/pci.h>
#include <linux/i2c.h>
#include <linux/i2c-algo-bit.h>
-#include <linux/videodev.h>
+#include <linux/videodev2.h>
#include <linux/kdev_t.h>
#include <media/tuner.h>
@@ -148,7 +148,7 @@ extern struct sram_channel cx88_sram_channels[];
#define CX88_BOARD_PIXELVIEW 3
#define CX88_BOARD_ATI_WONDER_PRO 4
#define CX88_BOARD_WINFAST2000XP_EXPERT 5
-#define CX88_BOARD_AVERTV_303 6
+#define CX88_BOARD_AVERTV_STUDIO_303 6
#define CX88_BOARD_MSI_TVANYWHERE_MASTER 7
#define CX88_BOARD_WINFAST_DV2000 8
#define CX88_BOARD_LEADTEK_PVR2000 9
@@ -174,6 +174,11 @@ extern struct sram_channel cx88_sram_channels[];
#define CX88_BOARD_ADSTECH_DVB_T_PCI 29
#define CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1 30
#define CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD 31
+#define CX88_BOARD_AVERMEDIA_ULTRATV_MC_550 32
+#define CX88_BOARD_KWORLD_VSTREAM_EXPERT_DVD 33
+#define CX88_BOARD_ATI_HDTVWONDER 34
+#define CX88_BOARD_WINFAST_DTV1000 35
+#define CX88_BOARD_AVERTV_303 36
enum cx88_itype {
CX88_VMUX_COMPOSITE1 = 1,
@@ -203,8 +208,8 @@ struct cx88_board {
int tda9887_conf;
struct cx88_input input[MAX_CX88_INPUT];
struct cx88_input radio;
- int blackbird:1;
- int dvb:1;
+ unsigned int blackbird:1;
+ unsigned int dvb:1;
};
struct cx88_subid {
@@ -255,8 +260,8 @@ struct cx88_core {
/* pci stuff */
int pci_bus;
int pci_slot;
- u32 __iomem *lmmio;
- u8 __iomem *bmmio;
+ u32 __iomem *lmmio;
+ u8 __iomem *bmmio;
u32 shadow[SHADOW_MAX];
int pci_irqmask;
@@ -287,6 +292,7 @@ struct cx88_core {
u32 audiomode_current;
u32 input;
u32 astat;
+ u32 use_nicam;
/* IR remote control state */
struct cx88_IR *ir;
@@ -370,6 +376,14 @@ struct cx8802_suspend_state {
int disabled;
};
+/* TODO: move this to struct v4l2_mpeg_compression ? */
+struct blackbird_dnr {
+ u32 mode;
+ u32 type;
+ u32 spatial;
+ u32 temporal;
+};
+
struct cx8802_dev {
struct cx88_core *core;
spinlock_t slock;
@@ -400,6 +414,10 @@ struct cx8802_dev {
/* for switching modulation types */
unsigned char ts_gen_cntrl;
+
+ /* mpeg params */
+ struct v4l2_mpeg_compression params;
+ struct blackbird_dnr dnr_params;
};
/* ----------------------------------------------------------- */
@@ -514,22 +532,20 @@ extern void cx88_card_setup(struct cx88_core *core);
#define WW_NONE 1
#define WW_BTSC 2
-#define WW_NICAM_I 3
-#define WW_NICAM_BGDKL 4
-#define WW_A1 5
-#define WW_A2_BG 6
-#define WW_A2_DK 7
-#define WW_A2_M 8
-#define WW_EIAJ 9
-#define WW_SYSTEM_L_AM 10
-#define WW_I2SPT 11
-#define WW_FM 12
+#define WW_BG 3
+#define WW_DK 4
+#define WW_I 5
+#define WW_L 6
+#define WW_EIAJ 7
+#define WW_I2SPT 8
+#define WW_FM 9
void cx88_set_tvaudio(struct cx88_core *core);
void cx88_newstation(struct cx88_core *core);
void cx88_get_stereo(struct cx88_core *core, struct v4l2_tuner *t);
void cx88_set_stereo(struct cx88_core *core, u32 mode, int manual);
int cx88_audio_thread(void *data);
+int cx88_detect_nicam(struct cx88_core *core);
/* ----------------------------------------------------------- */
/* cx88-input.c */
@@ -541,7 +557,8 @@ void cx88_ir_irq(struct cx88_core *core);
/* ----------------------------------------------------------- */
/* cx88-mpeg.c */
-int cx8802_buf_prepare(struct cx8802_dev *dev, struct cx88_buffer *buf);
+int cx8802_buf_prepare(struct cx8802_dev *dev, struct cx88_buffer *buf,
+ enum v4l2_field field);
void cx8802_buf_queue(struct cx8802_dev *dev, struct cx88_buffer *buf);
void cx8802_cancel_buffers(struct cx8802_dev *dev);
@@ -562,6 +579,10 @@ extern int cx88_do_ioctl(struct inode *inode, struct file *file, int radio,
extern int (*cx88_ioctl_hook)(struct inode *inode, struct file *file,
unsigned int cmd, void *arg);
extern unsigned int (*cx88_ioctl_translator)(unsigned int cmd);
+void blackbird_set_params(struct cx8802_dev *dev,
+ struct v4l2_mpeg_compression *params);
+void blackbird_set_dnr_params(struct cx8802_dev *dev,
+ struct blackbird_dnr* dnr_params);
/*
* Local variables:
diff --git a/drivers/media/video/em28xx/Kconfig b/drivers/media/video/em28xx/Kconfig
new file mode 100644
index 000000000000..885fd0170086
--- /dev/null
+++ b/drivers/media/video/em28xx/Kconfig
@@ -0,0 +1,12 @@
+config VIDEO_EM28XX
+ tristate "Empia EM2800/2820/2840 USB video capture support"
+ depends on VIDEO_DEV && USB && I2C
+ select VIDEO_BUF
+ select VIDEO_TUNER
+ select VIDEO_TVEEPROM
+ select VIDEO_IR
+ ---help---
+ This is a video4linux driver for Empia 28xx based TV cards.
+
+ To compile this driver as a module, choose M here: the
+ module will be called em28xx
diff --git a/drivers/media/video/em28xx/Makefile b/drivers/media/video/em28xx/Makefile
new file mode 100644
index 000000000000..da457a05b0dd
--- /dev/null
+++ b/drivers/media/video/em28xx/Makefile
@@ -0,0 +1,6 @@
+em28xx-objs := em28xx-video.o em28xx-i2c.o em28xx-cards.o em28xx-core.o \
+ em28xx-input.o
+
+obj-$(CONFIG_VIDEO_EM28XX) += em28xx.o
+
+EXTRA_CFLAGS += -I$(src)/..
diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c
new file mode 100644
index 000000000000..57779e63f35d
--- /dev/null
+++ b/drivers/media/video/em28xx/em28xx-cards.c
@@ -0,0 +1,292 @@
+/*
+ em28xx-cards.c - driver for Empia EM2800/EM2820/2840 USB video capture devices
+
+ Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it>
+ Markus Rechberger <mrechberger@gmail.com>
+ Mauro Carvalho Chehab <mchehab@brturbo.com.br>
+ Sascha Sommer <saschasommer@freenet.de>
+
+ 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/module.h>
+#include <linux/pci.h>
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/usb.h>
+#include <media/tuner.h>
+#include <media/audiochip.h>
+#include <media/tveeprom.h>
+#include "msp3400.h"
+
+#include "em28xx.h"
+
+struct em28xx_board em28xx_boards[] = {
+ [EM2800_BOARD_UNKNOWN] = {
+ .name = "Unknown EM2800 video grabber",
+ .is_em2800 = 1,
+ .vchannels = 2,
+ .norm = VIDEO_MODE_PAL,
+ .tda9887_conf = TDA9887_PRESENT,
+ .has_tuner = 1,
+ .decoder = EM28XX_SAA7113,
+ .input = {{
+ .type = EM28XX_VMUX_COMPOSITE1,
+ .vmux = 0,
+ .amux = 1,
+ },{
+ .type = EM28XX_VMUX_SVIDEO,
+ .vmux = 9,
+ .amux = 1,
+ }},
+ },
+ [EM2820_BOARD_UNKNOWN] = {
+ .name = "Unknown EM2820/2840 video grabber",
+ .is_em2800 = 0,
+ .vchannels = 2,
+ .norm = VIDEO_MODE_PAL,
+ .tda9887_conf = TDA9887_PRESENT,
+ .has_tuner = 1,
+ .decoder = EM28XX_SAA7113,
+ .input = {{
+ .type = EM28XX_VMUX_COMPOSITE1,
+ .vmux = 0,
+ .amux = 1,
+ },{
+ .type = EM28XX_VMUX_SVIDEO,
+ .vmux = 9,
+ .amux = 1,
+ }},
+ },
+ [EM2820_BOARD_TERRATEC_CINERGY_250] = {
+ .name = "Terratec Cinergy 250 USB",
+ .vchannels = 3,
+ .norm = VIDEO_MODE_PAL,
+ .tuner_type = TUNER_LG_PAL_NEW_TAPC,
+ .tda9887_conf = TDA9887_PRESENT,
+ .has_tuner = 1,
+ .decoder = EM28XX_SAA7113,
+ .input = {{
+ .type = EM28XX_VMUX_TELEVISION,
+ .vmux = 2,
+ .amux = 0,
+ },{
+ .type = EM28XX_VMUX_COMPOSITE1,
+ .vmux = 0,
+ .amux = 1,
+ },{
+ .type = EM28XX_VMUX_SVIDEO,
+ .vmux = 9,
+ .amux = 1,
+ }},
+ },
+ [EM2820_BOARD_PINNACLE_USB_2] = {
+ .name = "Pinnacle PCTV USB 2",
+ .vchannels = 3,
+ .norm = VIDEO_MODE_PAL,
+ .tuner_type = TUNER_LG_PAL_NEW_TAPC,
+ .tda9887_conf = TDA9887_PRESENT,
+ .has_tuner = 1,
+ .decoder = EM28XX_SAA7113,
+ .input = {{
+ .type = EM28XX_VMUX_TELEVISION,
+ .vmux = 2,
+ .amux = 0,
+ },{
+ .type = EM28XX_VMUX_COMPOSITE1,
+ .vmux = 0,
+ .amux = 1,
+ },{
+ .type = EM28XX_VMUX_SVIDEO,
+ .vmux = 9,
+ .amux = 1,
+ }},
+ },
+ [EM2820_BOARD_HAUPPAUGE_WINTV_USB_2] = {
+ .name = "Hauppauge WinTV USB 2",
+ .vchannels = 3,
+ .norm = VIDEO_MODE_NTSC,
+ .tuner_type = TUNER_PHILIPS_FM1236_MK3,
+ .tda9887_conf = TDA9887_PRESENT|TDA9887_PORT1_ACTIVE|TDA9887_PORT2_ACTIVE,
+ .has_tuner = 1,
+ .decoder = EM28XX_TVP5150,
+ .has_msp34xx = 1,
+ /*FIXME: S-Video not tested */
+ .input = {{
+ .type = EM28XX_VMUX_TELEVISION,
+ .vmux = 0,
+ .amux = 6,
+ },{
+ .type = EM28XX_VMUX_SVIDEO,
+ .vmux = 2,
+ .amux = 1,
+ }},
+ },
+ [EM2820_BOARD_MSI_VOX_USB_2] = {
+ .name = "MSI VOX USB 2.0",
+ .vchannels = 3,
+ .norm = VIDEO_MODE_PAL,
+ .tuner_type = TUNER_LG_PAL_NEW_TAPC,
+ .tda9887_conf = TDA9887_PRESENT|TDA9887_PORT1_ACTIVE|TDA9887_PORT2_ACTIVE,
+ .has_tuner = 1,
+ .decoder = EM28XX_SAA7114,
+ .input = {{
+ .type = EM28XX_VMUX_TELEVISION,
+ .vmux = 4,
+ .amux = 0,
+ },{
+ .type = EM28XX_VMUX_COMPOSITE1,
+ .vmux = 0,
+ .amux = 1,
+ },{
+ .type = EM28XX_VMUX_SVIDEO,
+ .vmux = 9,
+ .amux = 1,
+ }},
+ },
+ [EM2800_BOARD_TERRATEC_CINERGY_200] = {
+ .name = "Terratec Cinergy 200 USB",
+ .is_em2800 = 1,
+ .vchannels = 3,
+ .norm = VIDEO_MODE_PAL,
+ .tuner_type = TUNER_LG_PAL_NEW_TAPC,
+ .tda9887_conf = TDA9887_PRESENT,
+ .has_tuner = 1,
+ .decoder = EM28XX_SAA7113,
+ .input = {{
+ .type = EM28XX_VMUX_TELEVISION,
+ .vmux = 2,
+ .amux = 0,
+ },{
+ .type = EM28XX_VMUX_COMPOSITE1,
+ .vmux = 0,
+ .amux = 1,
+ },{
+ .type = EM28XX_VMUX_SVIDEO,
+ .vmux = 9,
+ .amux = 1,
+ }},
+ },
+ [EM2800_BOARD_LEADTEK_WINFAST_USBII] = {
+ .name = "Leadtek Winfast USB II",
+ .is_em2800 = 1,
+ .vchannels = 3,
+ .norm = VIDEO_MODE_PAL,
+ .tuner_type = TUNER_LG_PAL_NEW_TAPC,
+ .tda9887_conf = TDA9887_PRESENT,
+ .has_tuner = 1,
+ .decoder = EM28XX_SAA7113,
+ .input = {{
+ .type = EM28XX_VMUX_TELEVISION,
+ .vmux = 2,
+ .amux = 0,
+ },{
+ .type = EM28XX_VMUX_COMPOSITE1,
+ .vmux = 0,
+ .amux = 1,
+ },{
+ .type = EM28XX_VMUX_SVIDEO,
+ .vmux = 9,
+ .amux = 1,
+ }},
+ },
+ [EM2800_BOARD_KWORLD_USB2800] = {
+ .name = "Kworld USB2800",
+ .is_em2800 = 1,
+ .vchannels = 3,
+ .norm = VIDEO_MODE_PAL,
+ .tuner_type = TUNER_PHILIPS_ATSC,
+ .tda9887_conf = TDA9887_PRESENT,
+ .has_tuner = 1,
+ .decoder = EM28XX_SAA7113,
+ .input = {{
+ .type = EM28XX_VMUX_TELEVISION,
+ .vmux = 2,
+ .amux = 0,
+ },{
+ .type = EM28XX_VMUX_COMPOSITE1,
+ .vmux = 0,
+ .amux = 1,
+ },{
+ .type = EM28XX_VMUX_SVIDEO,
+ .vmux = 9,
+ .amux = 1,
+ }},
+ },
+ [EM2820_BOARD_PINNACLE_DVC_90] = {
+ .name = "Pinnacle Dazzle DVC 90",
+ .vchannels = 3,
+ .norm = VIDEO_MODE_PAL,
+ .has_tuner = 0,
+ .decoder = EM28XX_SAA7113,
+ .input = {{
+ .type = EM28XX_VMUX_COMPOSITE1,
+ .vmux = 0,
+ .amux = 1,
+ },{
+ .type = EM28XX_VMUX_SVIDEO,
+ .vmux = 9,
+ .amux = 1,
+ }},
+ },
+};
+const unsigned int em28xx_bcount = ARRAY_SIZE(em28xx_boards);
+
+/* table of devices that work with this driver */
+struct usb_device_id em28xx_id_table [] = {
+ { USB_DEVICE(0xeb1a, 0x2800), .driver_info = EM2800_BOARD_UNKNOWN },
+ { USB_DEVICE(0xeb1a, 0x2820), .driver_info = EM2820_BOARD_MSI_VOX_USB_2 },
+ { USB_DEVICE(0x0ccd, 0x0036), .driver_info = EM2820_BOARD_TERRATEC_CINERGY_250 },
+ { USB_DEVICE(0x2304, 0x0208), .driver_info = EM2820_BOARD_PINNACLE_USB_2 },
+ { USB_DEVICE(0x2040, 0x4200), .driver_info = EM2820_BOARD_HAUPPAUGE_WINTV_USB_2 },
+ { USB_DEVICE(0x2304, 0x0207), .driver_info = EM2820_BOARD_PINNACLE_DVC_90 },
+ { },
+};
+
+void em28xx_card_setup(struct em28xx *dev)
+{
+ /* request some modules */
+ if (dev->model == EM2820_BOARD_HAUPPAUGE_WINTV_USB_2) {
+ struct tveeprom tv;
+ struct v4l2_audioout ao;
+#ifdef CONFIG_MODULES
+ request_module("tveeprom");
+ request_module("ir-kbd-i2c");
+ request_module("msp3400");
+#endif
+ /* Call first TVeeprom */
+
+ dev->i2c_client.addr = 0xa0 >> 1;
+ tveeprom_hauppauge_analog(&dev->i2c_client, &tv, dev->eedata);
+
+ dev->tuner_type= tv.tuner_type;
+ if (tv.audio_processor == AUDIO_CHIP_MSP34XX) {
+ dev->has_msp34xx=1;
+ memset (&ao,0,sizeof(ao));
+
+ ao.index=2;
+ ao.mode=V4L2_AUDMODE_32BITS;
+ em28xx_i2c_call_clients(dev, VIDIOC_S_AUDOUT, &ao);
+ } else
+ dev->has_msp34xx=0;
+ }
+}
+
+EXPORT_SYMBOL(em28xx_boards);
+EXPORT_SYMBOL(em28xx_bcount);
+EXPORT_SYMBOL(em28xx_id_table);
+
+MODULE_DEVICE_TABLE (usb, em28xx_id_table);
diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c
new file mode 100644
index 000000000000..d54bc0127484
--- /dev/null
+++ b/drivers/media/video/em28xx/em28xx-core.c
@@ -0,0 +1,817 @@
+/*
+ em28xx-core.c - driver for Empia EM2800/EM2820/2840 USB video capture devices
+
+ Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it>
+ Markus Rechberger <mrechberger@gmail.com>
+ Mauro Carvalho Chehab <mchehab@brturbo.com.br>
+ Sascha Sommer <saschasommer@freenet.de>
+
+ 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/list.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/usb.h>
+#include <linux/vmalloc.h>
+
+#include "em28xx.h"
+
+/* #define ENABLE_DEBUG_ISOC_FRAMES */
+
+unsigned int core_debug;
+module_param(core_debug,int,0644);
+MODULE_PARM_DESC(core_debug,"enable debug messages [core]");
+
+#define em28xx_coredbg(fmt, arg...) do {\
+ if (core_debug) \
+ printk(KERN_INFO "%s %s :"fmt, \
+ dev->name, __FUNCTION__ , ##arg); } while (0)
+
+unsigned int reg_debug;
+module_param(reg_debug,int,0644);
+MODULE_PARM_DESC(reg_debug,"enable debug messages [URB reg]");
+
+#define em28xx_regdbg(fmt, arg...) do {\
+ if (reg_debug) \
+ printk(KERN_INFO "%s %s :"fmt, \
+ dev->name, __FUNCTION__ , ##arg); } while (0)
+
+unsigned int isoc_debug;
+module_param(isoc_debug,int,0644);
+MODULE_PARM_DESC(isoc_debug,"enable debug messages [isoc transfers]");
+
+#define em28xx_isocdbg(fmt, arg...) do {\
+ if (isoc_debug) \
+ printk(KERN_INFO "%s %s :"fmt, \
+ dev->name, __FUNCTION__ , ##arg); } while (0)
+
+static int alt = EM28XX_PINOUT;
+module_param(alt, int, 0644);
+MODULE_PARM_DESC(alt, "alternate setting to use for video endpoint");
+
+/* ------------------------------------------------------------------ */
+/* debug help functions */
+
+static const char *v4l1_ioctls[] = {
+ "0", "CGAP", "GCHAN", "SCHAN", "GTUNER", "STUNER", "GPICT", "SPICT",
+ "CCAPTURE", "GWIN", "SWIN", "GFBUF", "SFBUF", "KEY", "GFREQ",
+ "SFREQ", "GAUDIO", "SAUDIO", "SYNC", "MCAPTURE", "GMBUF", "GUNIT",
+ "GCAPTURE", "SCAPTURE", "SPLAYMODE", "SWRITEMODE", "GPLAYINFO",
+ "SMICROCODE", "GVBIFMT", "SVBIFMT" };
+#define V4L1_IOCTLS ARRAY_SIZE(v4l1_ioctls)
+
+static const char *v4l2_ioctls[] = {
+ "QUERYCAP", "1", "ENUM_PIXFMT", "ENUM_FBUFFMT", "G_FMT", "S_FMT",
+ "G_COMP", "S_COMP", "REQBUFS", "QUERYBUF", "G_FBUF", "S_FBUF",
+ "G_WIN", "S_WIN", "PREVIEW", "QBUF", "16", "DQBUF", "STREAMON",
+ "STREAMOFF", "G_PERF", "G_PARM", "S_PARM", "G_STD", "S_STD",
+ "ENUMSTD", "ENUMINPUT", "G_CTRL", "S_CTRL", "G_TUNER", "S_TUNER",
+ "G_FREQ", "S_FREQ", "G_AUDIO", "S_AUDIO", "35", "QUERYCTRL",
+ "QUERYMENU", "G_INPUT", "S_INPUT", "ENUMCVT", "41", "42", "43",
+ "44", "45", "G_OUTPUT", "S_OUTPUT", "ENUMOUTPUT", "G_AUDOUT",
+ "S_AUDOUT", "ENUMFX", "G_EFFECT", "S_EFFECT", "G_MODULATOR",
+ "S_MODULATOR"
+};
+#define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls)
+
+void em28xx_print_ioctl(char *name, unsigned int cmd)
+{
+ char *dir;
+
+ switch (_IOC_DIR(cmd)) {
+ case _IOC_NONE: dir = "--"; break;
+ case _IOC_READ: dir = "r-"; break;
+ case _IOC_WRITE: dir = "-w"; break;
+ case _IOC_READ | _IOC_WRITE: dir = "rw"; break;
+ default: dir = "??"; break;
+ }
+ switch (_IOC_TYPE(cmd)) {
+ case 'v':
+ printk(KERN_DEBUG "%s: ioctl 0x%08x (v4l1, %s, VIDIOC%s)\n",
+ name, cmd, dir, (_IOC_NR(cmd) < V4L1_IOCTLS) ?
+ v4l1_ioctls[_IOC_NR(cmd)] : "???");
+ break;
+ case 'V':
+ printk(KERN_DEBUG "%s: ioctl 0x%08x (v4l2, %s, VIDIOC_%s)\n",
+ name, cmd, dir, (_IOC_NR(cmd) < V4L2_IOCTLS) ?
+ v4l2_ioctls[_IOC_NR(cmd)] : "???");
+ break;
+ default:
+ printk(KERN_DEBUG "%s: ioctl 0x%08x (???, %s, #%d)\n",
+ name, cmd, dir, _IOC_NR(cmd));
+ }
+}
+
+static void *rvmalloc(size_t size)
+{
+ void *mem;
+ unsigned long adr;
+
+ size = PAGE_ALIGN(size);
+
+ mem = vmalloc_32((unsigned long)size);
+ if (!mem)
+ return NULL;
+
+ memset(mem, 0, size);
+
+ adr = (unsigned long)mem;
+ while (size > 0) {
+ SetPageReserved(vmalloc_to_page((void *)adr));
+ adr += PAGE_SIZE;
+ size -= PAGE_SIZE;
+ }
+
+ return mem;
+}
+
+static void rvfree(void *mem, size_t size)
+{
+ unsigned long adr;
+
+ if (!mem)
+ return;
+
+ size = PAGE_ALIGN(size);
+
+ adr = (unsigned long)mem;
+ while (size > 0) {
+ ClearPageReserved(vmalloc_to_page((void *)adr));
+ adr += PAGE_SIZE;
+ size -= PAGE_SIZE;
+ }
+
+ vfree(mem);
+}
+
+/*
+ * em28xx_request_buffers()
+ * allocate a number of buffers
+ */
+u32 em28xx_request_buffers(struct em28xx *dev, u32 count)
+{
+ const size_t imagesize = PAGE_ALIGN(dev->frame_size); /*needs to be page aligned cause the buffers can be mapped individually! */
+ void *buff = NULL;
+ u32 i;
+ em28xx_coredbg("requested %i buffers with size %i", count, imagesize);
+ if (count > EM28XX_NUM_FRAMES)
+ count = EM28XX_NUM_FRAMES;
+
+ dev->num_frames = count;
+ while (dev->num_frames > 0) {
+ if ((buff = rvmalloc(dev->num_frames * imagesize)))
+ break;
+ dev->num_frames--;
+ }
+
+ for (i = 0; i < dev->num_frames; i++) {
+ dev->frame[i].bufmem = buff + i * imagesize;
+ dev->frame[i].buf.index = i;
+ dev->frame[i].buf.m.offset = i * imagesize;
+ dev->frame[i].buf.length = dev->frame_size;
+ dev->frame[i].buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ dev->frame[i].buf.sequence = 0;
+ dev->frame[i].buf.field = V4L2_FIELD_NONE;
+ dev->frame[i].buf.memory = V4L2_MEMORY_MMAP;
+ dev->frame[i].buf.flags = 0;
+ }
+ return dev->num_frames;
+}
+
+/*
+ * em28xx_queue_unusedframes()
+ * add all frames that are not currently in use to the inbuffer queue
+ */
+void em28xx_queue_unusedframes(struct em28xx *dev)
+{
+ unsigned long lock_flags;
+ u32 i;
+
+ for (i = 0; i < dev->num_frames; i++)
+ if (dev->frame[i].state == F_UNUSED) {
+ dev->frame[i].state = F_QUEUED;
+ spin_lock_irqsave(&dev->queue_lock, lock_flags);
+ list_add_tail(&dev->frame[i].frame, &dev->inqueue);
+ spin_unlock_irqrestore(&dev->queue_lock, lock_flags);
+ }
+}
+
+/*
+ * em28xx_release_buffers()
+ * free frame buffers
+ */
+void em28xx_release_buffers(struct em28xx *dev)
+{
+ if (dev->num_frames) {
+ rvfree(dev->frame[0].bufmem,
+ dev->num_frames * PAGE_ALIGN(dev->frame[0].buf.length));
+ dev->num_frames = 0;
+ }
+}
+
+/*
+ * em28xx_read_reg_req()
+ * reads data from the usb device specifying bRequest
+ */
+int em28xx_read_reg_req_len(struct em28xx *dev, u8 req, u16 reg,
+ char *buf, int len)
+{
+ int ret, byte;
+
+ em28xx_regdbg("req=%02x, reg=%02x ", req, reg);
+
+ ret = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0), req,
+ USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ 0x0000, reg, buf, len, HZ);
+
+ if (reg_debug){
+ printk(ret < 0 ? " failed!\n" : "%02x values: ", ret);
+ for (byte = 0; byte < len; byte++) {
+ printk(" %02x", buf[byte]);
+ }
+ printk("\n");
+ }
+
+ return ret;
+}
+
+/*
+ * em28xx_read_reg_req()
+ * reads data from the usb device specifying bRequest
+ */
+int em28xx_read_reg_req(struct em28xx *dev, u8 req, u16 reg)
+{
+ u8 val;
+ int ret;
+
+ em28xx_regdbg("req=%02x, reg=%02x:", req, reg);
+
+ ret = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0), req,
+ USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ 0x0000, reg, &val, 1, HZ);
+
+ if (reg_debug)
+ printk(ret < 0 ? " failed!\n" : "%02x\n", val);
+
+ if (ret < 0)
+ return ret;
+
+ return val;
+}
+
+int em28xx_read_reg(struct em28xx *dev, u16 reg)
+{
+ return em28xx_read_reg_req(dev, USB_REQ_GET_STATUS, reg);
+}
+
+/*
+ * em28xx_write_regs_req()
+ * sends data to the usb device, specifying bRequest
+ */
+int em28xx_write_regs_req(struct em28xx *dev, u8 req, u16 reg, char *buf,
+ int len)
+{
+ int ret;
+
+ /*usb_control_msg seems to expect a kmalloced buffer */
+ unsigned char *bufs = kmalloc(len, GFP_KERNEL);
+
+ em28xx_regdbg("req=%02x reg=%02x:", req, reg);
+
+ if (reg_debug) {
+ int i;
+ for (i = 0; i < len; ++i)
+ printk (" %02x", (unsigned char)buf[i]);
+ printk ("\n");
+ }
+
+ if (!bufs)
+ return -ENOMEM;
+ memcpy(bufs, buf, len);
+ ret = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0), req,
+ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ 0x0000, reg, bufs, len, HZ);
+ mdelay(5); /* FIXME: magic number */
+ kfree(bufs);
+ return ret;
+}
+
+int em28xx_write_regs(struct em28xx *dev, u16 reg, char *buf, int len)
+{
+ return em28xx_write_regs_req(dev, USB_REQ_GET_STATUS, reg, buf, len);
+}
+
+/*
+ * em28xx_write_reg_bits()
+ * sets only some bits (specified by bitmask) of a register, by first reading
+ * the actual value
+ */
+int em28xx_write_reg_bits(struct em28xx *dev, u16 reg, u8 val,
+ u8 bitmask)
+{
+ int oldval;
+ u8 newval;
+ if ((oldval = em28xx_read_reg(dev, reg)) < 0)
+ return oldval;
+ newval = (((u8) oldval) & ~bitmask) | (val & bitmask);
+ return em28xx_write_regs(dev, reg, &newval, 1);
+}
+
+/*
+ * em28xx_write_ac97()
+ * write a 16 bit value to the specified AC97 address (LSB first!)
+ */
+int em28xx_write_ac97(struct em28xx *dev, u8 reg, u8 * val)
+{
+ int ret;
+ u8 addr = reg & 0x7f;
+ if ((ret = em28xx_write_regs(dev, AC97LSB_REG, val, 2)) < 0)
+ return ret;
+ if ((ret = em28xx_write_regs(dev, AC97ADDR_REG, &addr, 1)) < 0)
+ return ret;
+ if ((ret = em28xx_read_reg(dev, AC97BUSY_REG)) < 0)
+ return ret;
+ else if (((u8) ret) & 0x01) {
+ em28xx_warn ("AC97 command still being exectuted: not handled properly!\n");
+ }
+ return 0;
+}
+
+int em28xx_audio_analog_set(struct em28xx *dev)
+{
+ char s[2] = { 0x00, 0x00 };
+ s[0] |= 0x1f - dev->volume;
+ s[1] |= 0x1f - dev->volume;
+ if (dev->mute)
+ s[1] |= 0x80;
+ return em28xx_write_ac97(dev, MASTER_AC97, s);
+}
+
+
+int em28xx_colorlevels_set_default(struct em28xx *dev)
+{
+ em28xx_write_regs(dev, YGAIN_REG, "\x10", 1); /* contrast */
+ em28xx_write_regs(dev, YOFFSET_REG, "\x00", 1); /* brightness */
+ em28xx_write_regs(dev, UVGAIN_REG, "\x10", 1); /* saturation */
+ em28xx_write_regs(dev, UOFFSET_REG, "\x00", 1);
+ em28xx_write_regs(dev, VOFFSET_REG, "\x00", 1);
+ em28xx_write_regs(dev, SHARPNESS_REG, "\x00", 1);
+
+ em28xx_write_regs(dev, GAMMA_REG, "\x20", 1);
+ em28xx_write_regs(dev, RGAIN_REG, "\x20", 1);
+ em28xx_write_regs(dev, GGAIN_REG, "\x20", 1);
+ em28xx_write_regs(dev, BGAIN_REG, "\x20", 1);
+ em28xx_write_regs(dev, ROFFSET_REG, "\x00", 1);
+ em28xx_write_regs(dev, GOFFSET_REG, "\x00", 1);
+ return em28xx_write_regs(dev, BOFFSET_REG, "\x00", 1);
+}
+
+int em28xx_capture_start(struct em28xx *dev, int start)
+{
+ int ret;
+ /* FIXME: which is the best order? */
+ /* video registers are sampled by VREF */
+ if ((ret = em28xx_write_reg_bits(dev, USBSUSP_REG, start ? 0x10 : 0x00,
+ 0x10)) < 0)
+ return ret;
+ /* enable video capture */
+ return em28xx_write_regs(dev, VINENABLE_REG, start ? "\x67" : "\x27", 1);
+}
+
+int em28xx_outfmt_set_yuv422(struct em28xx *dev)
+{
+ em28xx_write_regs(dev, OUTFMT_REG, "\x34", 1);
+ em28xx_write_regs(dev, VINMODE_REG, "\x10", 1);
+ return em28xx_write_regs(dev, VINCTRL_REG, "\x11", 1);
+}
+
+int em28xx_accumulator_set(struct em28xx *dev, u8 xmin, u8 xmax, u8 ymin,
+ u8 ymax)
+{
+ em28xx_coredbg("em28xx Scale: (%d,%d)-(%d,%d)\n", xmin, ymin, xmax, ymax);
+
+ em28xx_write_regs(dev, XMIN_REG, &xmin, 1);
+ em28xx_write_regs(dev, XMAX_REG, &xmax, 1);
+ em28xx_write_regs(dev, YMIN_REG, &ymin, 1);
+ return em28xx_write_regs(dev, YMAX_REG, &ymax, 1);
+}
+
+int em28xx_capture_area_set(struct em28xx *dev, u8 hstart, u8 vstart,
+ u16 width, u16 height)
+{
+ u8 cwidth = width;
+ u8 cheight = height;
+ u8 overflow = (height >> 7 & 0x02) | (width >> 8 & 0x01);
+
+ em28xx_coredbg("em28xx Area Set: (%d,%d)\n", (width | (overflow & 2) << 7),
+ (height | (overflow & 1) << 8));
+
+ em28xx_write_regs(dev, HSTART_REG, &hstart, 1);
+ em28xx_write_regs(dev, VSTART_REG, &vstart, 1);
+ em28xx_write_regs(dev, CWIDTH_REG, &cwidth, 1);
+ em28xx_write_regs(dev, CHEIGHT_REG, &cheight, 1);
+ return em28xx_write_regs(dev, OFLOW_REG, &overflow, 1);
+}
+
+int em28xx_scaler_set(struct em28xx *dev, u16 h, u16 v)
+{
+ u8 mode;
+ /* the em2800 scaler only supports scaling down to 50% */
+ if(dev->is_em2800)
+ mode = (v ? 0x20 : 0x00) | (h ? 0x10 : 0x00);
+ else {
+ u8 buf[2];
+ buf[0] = h;
+ buf[1] = h >> 8;
+ em28xx_write_regs(dev, HSCALELOW_REG, (char *)buf, 2);
+ buf[0] = v;
+ buf[1] = v >> 8;
+ em28xx_write_regs(dev, VSCALELOW_REG, (char *)buf, 2);
+ /* it seems that both H and V scalers must be active to work correctly */
+ mode = (h || v)? 0x30: 0x00;
+ }
+ return em28xx_write_reg_bits(dev, COMPR_REG, mode, 0x30);
+}
+
+/* FIXME: this only function read values from dev */
+int em28xx_resolution_set(struct em28xx *dev)
+{
+ int width, height;
+ width = norm_maxw(dev);
+ height = norm_maxh(dev) >> 1;
+
+ em28xx_outfmt_set_yuv422(dev);
+ em28xx_accumulator_set(dev, 1, (width - 4) >> 2, 1, (height - 4) >> 2);
+ em28xx_capture_area_set(dev, 0, 0, width >> 2, height >> 2);
+ return em28xx_scaler_set(dev, dev->hscale, dev->vscale);
+}
+
+
+/******************* isoc transfer handling ****************************/
+
+#ifdef ENABLE_DEBUG_ISOC_FRAMES
+static void em28xx_isoc_dump(struct urb *urb, struct pt_regs *regs)
+{
+ int len = 0;
+ int ntrans = 0;
+ int i;
+
+ printk(KERN_DEBUG "isocIrq: sf=%d np=%d ec=%x\n",
+ urb->start_frame, urb->number_of_packets,
+ urb->error_count);
+ for (i = 0; i < urb->number_of_packets; i++) {
+ unsigned char *buf =
+ urb->transfer_buffer +
+ urb->iso_frame_desc[i].offset;
+ int alen = urb->iso_frame_desc[i].actual_length;
+ if (alen > 0) {
+ if (buf[0] == 0x88) {
+ ntrans++;
+ len += alen;
+ } else if (buf[0] == 0x22) {
+ printk(KERN_DEBUG
+ "= l=%d nt=%d bpp=%d\n",
+ len - 4 * ntrans, ntrans,
+ ntrans == 0 ? 0 : len / ntrans);
+ ntrans = 1;
+ len = alen;
+ } else
+ printk(KERN_DEBUG "!\n");
+ }
+ printk(KERN_DEBUG " n=%d s=%d al=%d %x\n", i,
+ urb->iso_frame_desc[i].status,
+ urb->iso_frame_desc[i].actual_length,
+ (unsigned int)
+ *((unsigned char *)(urb->transfer_buffer +
+ urb->iso_frame_desc[i].
+ offset)));
+ }
+}
+#endif
+
+static inline int em28xx_isoc_video(struct em28xx *dev,struct em28xx_frame_t **f,
+ unsigned long *lock_flags, unsigned char buf)
+{
+ if (!(buf & 0x01)) {
+ if ((*f)->state == F_GRABBING) {
+ /*previous frame is incomplete */
+ if ((*f)->fieldbytesused < dev->field_size) {
+ (*f)->state = F_ERROR;
+ em28xx_isocdbg ("dropping incomplete bottom field (%i missing bytes)",
+ dev->field_size-(*f)->fieldbytesused);
+ } else {
+ (*f)->state = F_DONE;
+ (*f)->buf.bytesused = dev->frame_size;
+ }
+ }
+ if ((*f)->state == F_DONE || (*f)->state == F_ERROR) {
+ /* move current frame to outqueue and get next free buffer from inqueue */
+ spin_lock_irqsave(&dev-> queue_lock, *lock_flags);
+ list_move_tail(&(*f)->frame, &dev->outqueue);
+ if (!list_empty(&dev->inqueue))
+ (*f) = list_entry(dev-> inqueue.next,
+ struct em28xx_frame_t,frame);
+ else
+ (*f) = NULL;
+ spin_unlock_irqrestore(&dev->queue_lock,*lock_flags);
+ }
+ if (!(*f)) {
+ em28xx_isocdbg ("new frame but no buffer is free");
+ return -1;
+ }
+ do_gettimeofday(&(*f)->buf.timestamp);
+ (*f)->buf.sequence = ++dev->frame_count;
+ (*f)->buf.field = V4L2_FIELD_INTERLACED;
+ (*f)->state = F_GRABBING;
+ (*f)->buf.bytesused = 0;
+ (*f)->top_field = 1;
+ (*f)->fieldbytesused = 0;
+ } else {
+ /* acquiring bottom field */
+ if ((*f)->state == F_GRABBING) {
+ if (!(*f)->top_field) {
+ (*f)->state = F_ERROR;
+ em28xx_isocdbg ("unexpected begin of bottom field; discarding it");
+ } else if ((*f)-> fieldbytesused < dev->field_size - 172) {
+ (*f)->state = F_ERROR;
+ em28xx_isocdbg ("dropping incomplete top field (%i missing bytes)",
+ dev->field_size-(*f)->fieldbytesused);
+ } else {
+ (*f)->top_field = 0;
+ (*f)->fieldbytesused = 0;
+ }
+ }
+ }
+ return (0);
+}
+
+static inline void em28xx_isoc_video_copy(struct em28xx *dev,
+ struct em28xx_frame_t **f, unsigned char *buf, int len)
+{
+ void *fieldstart, *startwrite, *startread;
+ int linesdone, currlinedone, offset, lencopy,remain;
+
+ if(dev->frame_size != (*f)->buf.length){
+ em28xx_err("frame_size %i and buf.length %i are different!!!\n",dev->frame_size,(*f)->buf.length);
+ return;
+ }
+
+ if ((*f)->fieldbytesused + len > dev->field_size)
+ len =dev->field_size - (*f)->fieldbytesused;
+
+ if (buf[0] != 0x88 && buf[0] != 0x22) {
+ em28xx_isocdbg("frame is not complete\n");
+ startread = buf;
+ len+=4;
+ } else
+ startread = buf + 4;
+
+ remain = len;
+
+ if ((*f)->top_field)
+ fieldstart = (*f)->bufmem;
+ else
+ fieldstart = (*f)->bufmem + dev->bytesperline;
+
+ linesdone = (*f)->fieldbytesused / dev->bytesperline;
+ currlinedone = (*f)->fieldbytesused % dev->bytesperline;
+ offset = linesdone * dev->bytesperline * 2 + currlinedone;
+ startwrite = fieldstart + offset;
+ lencopy = dev->bytesperline - currlinedone;
+ lencopy = lencopy > remain ? remain : lencopy;
+
+ memcpy(startwrite, startread, lencopy);
+ remain -= lencopy;
+
+ while (remain > 0) {
+ startwrite += lencopy + dev->bytesperline;
+ startread += lencopy;
+ if (dev->bytesperline > remain)
+ lencopy = remain;
+ else
+ lencopy = dev->bytesperline;
+
+ memcpy(startwrite, startread, lencopy);
+ remain -= lencopy;
+ }
+
+ (*f)->fieldbytesused += len;
+}
+
+/*
+ * em28xx_isoIrq()
+ * handles the incoming isoc urbs and fills the frames from our inqueue
+ */
+void em28xx_isocIrq(struct urb *urb, struct pt_regs *regs)
+{
+ struct em28xx *dev = urb->context;
+ int i, status;
+ struct em28xx_frame_t **f;
+ unsigned long lock_flags;
+
+ if (!dev)
+ return;
+#ifdef ENABLE_DEBUG_ISOC_FRAMES
+ if (isoc_debug>1)
+ em28xx_isoc_dump(urb, regs);
+#endif
+
+ if (urb->status == -ENOENT)
+ return;
+
+ f = &dev->frame_current;
+
+ if (dev->stream == STREAM_INTERRUPT) {
+ dev->stream = STREAM_OFF;
+ if ((*f))
+ (*f)->state = F_QUEUED;
+ em28xx_isocdbg("stream interrupted");
+ wake_up_interruptible(&dev->wait_stream);
+ }
+
+ if ((dev->state & DEV_DISCONNECTED) || (dev->state & DEV_MISCONFIGURED))
+ return;
+
+ if (dev->stream == STREAM_ON && !list_empty(&dev->inqueue)) {
+ if (!(*f))
+ (*f) = list_entry(dev->inqueue.next,
+ struct em28xx_frame_t, frame);
+
+ for (i = 0; i < urb->number_of_packets; i++) {
+ unsigned char *buf = urb->transfer_buffer +
+ urb->iso_frame_desc[i].offset;
+ int len = urb->iso_frame_desc[i].actual_length - 4;
+
+ if (urb->iso_frame_desc[i].status) {
+ em28xx_isocdbg("data error: [%d] len=%d, status=%d", i,
+ urb->iso_frame_desc[i].actual_length,
+ urb->iso_frame_desc[i].status);
+ if (urb->iso_frame_desc[i].status != -EPROTO)
+ continue;
+ }
+ if (urb->iso_frame_desc[i].actual_length <= 0) {
+ em28xx_isocdbg("packet %d is empty",i);
+ continue;
+ }
+ if (urb->iso_frame_desc[i].actual_length >
+ dev->max_pkt_size) {
+ em28xx_isocdbg("packet bigger than packet size");
+ continue;
+ }
+ /*new frame */
+ if (buf[0] == 0x22 && buf[1] == 0x5a) {
+ em28xx_isocdbg("Video frame, length=%i!",len);
+
+ if (em28xx_isoc_video(dev,f,&lock_flags,buf[2]))
+ break;
+ } else if (buf[0]==0x33 && buf[1]==0x95 && buf[2]==0x00) {
+ em28xx_isocdbg("VBI HEADER!!!");
+ }
+
+ /* actual copying */
+ if ((*f)->state == F_GRABBING) {
+ em28xx_isoc_video_copy(dev,f,buf, len);
+ }
+ }
+ }
+
+ for (i = 0; i < urb->number_of_packets; i++) {
+ urb->iso_frame_desc[i].status = 0;
+ urb->iso_frame_desc[i].actual_length = 0;
+ }
+
+ urb->status = 0;
+ if ((status = usb_submit_urb(urb, GFP_ATOMIC))) {
+ em28xx_errdev("resubmit of urb failed (error=%i)\n", status);
+ dev->state |= DEV_MISCONFIGURED;
+ }
+ wake_up_interruptible(&dev->wait_frame);
+ return;
+}
+
+/*
+ * em28xx_uninit_isoc()
+ * deallocates the buffers and urbs allocated during em28xx_init_iosc()
+ */
+void em28xx_uninit_isoc(struct em28xx *dev)
+{
+ int i;
+
+ for (i = 0; i < EM28XX_NUM_BUFS; i++) {
+ if (dev->urb[i]) {
+ usb_kill_urb(dev->urb[i]);
+ if (dev->transfer_buffer[i]){
+ usb_buffer_free(dev->udev,(EM28XX_NUM_PACKETS*dev->max_pkt_size),dev->transfer_buffer[i],dev->urb[i]->transfer_dma);
+ }
+ usb_free_urb(dev->urb[i]);
+ }
+ dev->urb[i] = NULL;
+ dev->transfer_buffer[i] = NULL;
+ }
+ em28xx_capture_start(dev, 0);
+}
+
+/*
+ * em28xx_init_isoc()
+ * allocates transfer buffers and submits the urbs for isoc transfer
+ */
+int em28xx_init_isoc(struct em28xx *dev)
+{
+ /* change interface to 3 which allowes the biggest packet sizes */
+ int i, errCode;
+ const int sb_size = EM28XX_NUM_PACKETS * dev->max_pkt_size;
+
+ /* reset streaming vars */
+ dev->frame_current = NULL;
+ dev->frame_count = 0;
+
+ /* allocate urbs */
+ for (i = 0; i < EM28XX_NUM_BUFS; i++) {
+ struct urb *urb;
+ int j, k;
+ /* allocate transfer buffer */
+ urb = usb_alloc_urb(EM28XX_NUM_PACKETS, GFP_KERNEL);
+ if (!urb){
+ em28xx_errdev("cannot alloc urb %i\n", i);
+ em28xx_uninit_isoc(dev);
+ return -ENOMEM;
+ }
+ dev->transfer_buffer[i] = usb_buffer_alloc(dev->udev, sb_size, GFP_KERNEL,&urb->transfer_dma);
+ if (!dev->transfer_buffer[i]) {
+ em28xx_errdev
+ ("unable to allocate %i bytes for transfer buffer %i\n",
+ sb_size, i);
+ em28xx_uninit_isoc(dev);
+ return -ENOMEM;
+ }
+ memset(dev->transfer_buffer[i], 0, sb_size);
+ urb->dev = dev->udev;
+ urb->context = dev;
+ urb->pipe = usb_rcvisocpipe(dev->udev, 0x82);
+ urb->transfer_flags = URB_ISO_ASAP;
+ urb->interval = 1;
+ urb->transfer_buffer = dev->transfer_buffer[i];
+ urb->complete = em28xx_isocIrq;
+ urb->number_of_packets = EM28XX_NUM_PACKETS;
+ urb->transfer_buffer_length = sb_size;
+ for (j = k = 0; j < EM28XX_NUM_PACKETS;
+ j++, k += dev->max_pkt_size) {
+ urb->iso_frame_desc[j].offset = k;
+ urb->iso_frame_desc[j].length =
+ dev->max_pkt_size;
+ }
+ dev->urb[i] = urb;
+ }
+
+ /* submit urbs */
+ for (i = 0; i < EM28XX_NUM_BUFS; i++) {
+ errCode = usb_submit_urb(dev->urb[i], GFP_KERNEL);
+ if (errCode) {
+ em28xx_errdev("submit of urb %i failed (error=%i)\n", i,
+ errCode);
+ em28xx_uninit_isoc(dev);
+ return errCode;
+ }
+ }
+
+ return 0;
+}
+
+int em28xx_set_alternate(struct em28xx *dev)
+{
+ int errCode, prev_alt = dev->alt;
+ dev->alt = alt;
+ if (dev->alt == 0) {
+ int i;
+ for(i=0;i< dev->num_alt; i++)
+ if(dev->alt_max_pkt_size[i]>dev->alt_max_pkt_size[dev->alt])
+ dev->alt=i;
+ }
+
+ if (dev->alt != prev_alt) {
+ dev->max_pkt_size = dev->alt_max_pkt_size[dev->alt];
+ em28xx_coredbg("setting alternate %d with wMaxPacketSize=%u\n", dev->alt,
+ dev->max_pkt_size);
+ errCode = usb_set_interface(dev->udev, 0, dev->alt);
+ if (errCode < 0) {
+ em28xx_errdev ("cannot change alternate number to %d (error=%i)\n",
+ dev->alt, errCode);
+ return errCode;
+ }
+ }
+ return 0;
+}
diff --git a/drivers/media/video/em28xx/em28xx-i2c.c b/drivers/media/video/em28xx/em28xx-i2c.c
new file mode 100644
index 000000000000..b32d9852f34c
--- /dev/null
+++ b/drivers/media/video/em28xx/em28xx-i2c.c
@@ -0,0 +1,586 @@
+/*
+ em28xx-i2c.c - driver for Empia EM2800/EM2820/2840 USB video capture devices
+
+ Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it>
+ Markus Rechberger <mrechberger@gmail.com>
+ Mauro Carvalho Chehab <mchehab@brturbo.com.br>
+ Sascha Sommer <saschasommer@freenet.de>
+
+ 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/module.h>
+#include <linux/kernel.h>
+#include <linux/usb.h>
+#include <linux/i2c.h>
+#include <linux/video_decoder.h>
+
+#include "em28xx.h"
+#include <media/tuner.h>
+
+/* ----------------------------------------------------------- */
+
+static unsigned int i2c_scan = 0;
+module_param(i2c_scan, int, 0444);
+MODULE_PARM_DESC(i2c_scan, "scan i2c bus at insmod time");
+
+static unsigned int i2c_debug = 0;
+module_param(i2c_debug, int, 0644);
+MODULE_PARM_DESC(i2c_debug, "enable debug messages [i2c]");
+
+#define dprintk1(lvl,fmt, args...) if (i2c_debug>=lvl) do {\
+ printk(fmt , ##args); } while (0)
+#define dprintk2(lvl,fmt, args...) if (i2c_debug>=lvl) do{ \
+ printk(KERN_DEBUG "%s at %s: " fmt, \
+ dev->name, __FUNCTION__ , ##args); } while (0)
+
+/*
+ * em2800_i2c_send_max4()
+ * send up to 4 bytes to the i2c device
+ */
+static int em2800_i2c_send_max4(struct em28xx *dev, unsigned char addr,
+ char *buf, int len)
+{
+ int ret;
+ int write_timeout;
+ unsigned char b2[6];
+ BUG_ON(len < 1 || len > 4);
+ b2[5] = 0x80 + len - 1;
+ b2[4] = addr;
+ b2[3] = buf[0];
+ if (len > 1)
+ b2[2] = buf[1];
+ if (len > 2)
+ b2[1] = buf[2];
+ if (len > 3)
+ b2[0] = buf[3];
+
+ ret = dev->em28xx_write_regs(dev, 4 - len, &b2[4 - len], 2 + len);
+ if (ret != 2 + len) {
+ em28xx_warn("writting to i2c device failed (error=%i)\n", ret);
+ return -EIO;
+ }
+ for (write_timeout = EM2800_I2C_WRITE_TIMEOUT; write_timeout > 0;
+ write_timeout -= 5) {
+ ret = dev->em28xx_read_reg(dev, 0x05);
+ if (ret == 0x80 + len - 1)
+ return len;
+ mdelay(5);
+ }
+ em28xx_warn("i2c write timed out\n");
+ return -EIO;
+}
+
+/*
+ * em2800_i2c_send_bytes()
+ */
+static int em2800_i2c_send_bytes(void *data, unsigned char addr, char *buf,
+ short len)
+{
+ char *bufPtr = buf;
+ int ret;
+ int wrcount = 0;
+ int count;
+ int maxLen = 4;
+ struct em28xx *dev = (struct em28xx *)data;
+ while (len > 0) {
+ count = (len > maxLen) ? maxLen : len;
+ ret = em2800_i2c_send_max4(dev, addr, bufPtr, count);
+ if (ret > 0) {
+ len -= count;
+ bufPtr += count;
+ wrcount += count;
+ } else
+ return (ret < 0) ? ret : -EFAULT;
+ }
+ return wrcount;
+}
+
+/*
+ * em2800_i2c_check_for_device()
+ * check if there is a i2c_device at the supplied address
+ */
+static int em2800_i2c_check_for_device(struct em28xx *dev, unsigned char addr)
+{
+ char msg;
+ int ret;
+ int write_timeout;
+ msg = addr;
+ ret = dev->em28xx_write_regs(dev, 0x04, &msg, 1);
+ if (ret < 0) {
+ em28xx_warn("setting i2c device address failed (error=%i)\n",
+ ret);
+ return ret;
+ }
+ msg = 0x84;
+ ret = dev->em28xx_write_regs(dev, 0x05, &msg, 1);
+ if (ret < 0) {
+ em28xx_warn("preparing i2c read failed (error=%i)\n", ret);
+ return ret;
+ }
+ for (write_timeout = EM2800_I2C_WRITE_TIMEOUT; write_timeout > 0;
+ write_timeout -= 5) {
+ unsigned msg = dev->em28xx_read_reg(dev, 0x5);
+ if (msg == 0x94)
+ return -ENODEV;
+ else if (msg == 0x84)
+ return 0;
+ mdelay(5);
+ }
+ return -ENODEV;
+}
+
+/*
+ * em2800_i2c_recv_bytes()
+ * read from the i2c device
+ */
+static int em2800_i2c_recv_bytes(struct em28xx *dev, unsigned char addr,
+ char *buf, int len)
+{
+ int ret;
+ /* check for the device and set i2c read address */
+ ret = em2800_i2c_check_for_device(dev, addr);
+ if (ret) {
+ em28xx_warn
+ ("preparing read at i2c address 0x%x failed (error=%i)\n",
+ addr, ret);
+ return ret;
+ }
+ ret = dev->em28xx_read_reg_req_len(dev, 0x0, 0x3, buf, len);
+ if (ret < 0) {
+ em28xx_warn("reading from i2c device at 0x%x failed (error=%i)",
+ addr, ret);
+ return ret;
+ }
+ return ret;
+}
+
+/*
+ * em28xx_i2c_send_bytes()
+ * untested for more than 4 bytes
+ */
+static int em28xx_i2c_send_bytes(void *data, unsigned char addr, char *buf,
+ short len, int stop)
+{
+ int wrcount = 0;
+ struct em28xx *dev = (struct em28xx *)data;
+
+ wrcount = dev->em28xx_write_regs_req(dev, stop ? 2 : 3, addr, buf, len);
+
+ return wrcount;
+}
+
+/*
+ * em28xx_i2c_recv_bytes()
+ * read a byte from the i2c device
+ */
+static int em28xx_i2c_recv_bytes(struct em28xx *dev, unsigned char addr,
+ char *buf, int len)
+{
+ int ret;
+ ret = dev->em28xx_read_reg_req_len(dev, 2, addr, buf, len);
+ if (ret < 0) {
+ em28xx_warn("reading i2c device failed (error=%i)\n", ret);
+ return ret;
+ }
+ if (dev->em28xx_read_reg(dev, 0x5) != 0)
+ return -ENODEV;
+ return ret;
+}
+
+/*
+ * em28xx_i2c_check_for_device()
+ * check if there is a i2c_device at the supplied address
+ */
+static int em28xx_i2c_check_for_device(struct em28xx *dev, unsigned char addr)
+{
+ char msg;
+ int ret;
+ msg = addr;
+
+ ret = dev->em28xx_read_reg_req(dev, 2, addr);
+ if (ret < 0) {
+ em28xx_warn("reading from i2c device failed (error=%i)\n", ret);
+ return ret;
+ }
+ if (dev->em28xx_read_reg(dev, 0x5) != 0)
+ return -ENODEV;
+ return 0;
+}
+
+/*
+ * em28xx_i2c_xfer()
+ * the main i2c transfer function
+ */
+static int em28xx_i2c_xfer(struct i2c_adapter *i2c_adap,
+ struct i2c_msg msgs[], int num)
+{
+ struct em28xx *dev = i2c_adap->algo_data;
+ int addr, rc, i, byte;
+
+ if (num <= 0)
+ return 0;
+ for (i = 0; i < num; i++) {
+ addr = msgs[i].addr << 1;
+ dprintk2(2,"%s %s addr=%x len=%d:",
+ (msgs[i].flags & I2C_M_RD) ? "read" : "write",
+ i == num - 1 ? "stop" : "nonstop", addr, msgs[i].len);
+ if (!msgs[i].len) { /* no len: check only for device presence */
+ if (dev->is_em2800)
+ rc = em2800_i2c_check_for_device(dev, addr);
+ else
+ rc = em28xx_i2c_check_for_device(dev, addr);
+ if (rc < 0) {
+ dprintk2(2," no device\n");
+ return rc;
+ }
+
+ } else if (msgs[i].flags & I2C_M_RD) {
+ /* read bytes */
+ if (dev->is_em2800)
+ rc = em2800_i2c_recv_bytes(dev, addr,
+ msgs[i].buf,
+ msgs[i].len);
+ else
+ rc = em28xx_i2c_recv_bytes(dev, addr,
+ msgs[i].buf,
+ msgs[i].len);
+ if (i2c_debug>=2) {
+ for (byte = 0; byte < msgs[i].len; byte++) {
+ printk(" %02x", msgs[i].buf[byte]);
+ }
+ }
+ } else {
+ /* write bytes */
+ if (i2c_debug>=2) {
+ for (byte = 0; byte < msgs[i].len; byte++)
+ printk(" %02x", msgs[i].buf[byte]);
+ }
+ if (dev->is_em2800)
+ rc = em2800_i2c_send_bytes(dev, addr,
+ msgs[i].buf,
+ msgs[i].len);
+ else
+ rc = em28xx_i2c_send_bytes(dev, addr,
+ msgs[i].buf,
+ msgs[i].len,
+ i == num - 1);
+ if (rc < 0)
+ goto err;
+ }
+ if (i2c_debug>=2)
+ printk("\n");
+ }
+
+ return num;
+ err:
+ dprintk2(2," ERROR: %i\n", rc);
+ return rc;
+}
+
+static int em28xx_i2c_eeprom(struct em28xx *dev, unsigned char *eedata, int len)
+{
+ unsigned char buf, *p = eedata;
+ struct em28xx_eeprom *em_eeprom = (void *)eedata;
+ int i, err, size = len, block;
+
+ dev->i2c_client.addr = 0xa0 >> 1;
+
+ /* Check if board has eeprom */
+ err = i2c_master_recv(&dev->i2c_client, &buf, 0);
+ if (err < 0)
+ return -1;
+
+ buf = 0;
+ if (1 != (err = i2c_master_send(&dev->i2c_client, &buf, 1))) {
+ printk(KERN_INFO "%s: Huh, no eeprom present (err=%d)?\n",
+ dev->name, err);
+ return -1;
+ }
+ while (size > 0) {
+ if (size > 16)
+ block = 16;
+ else
+ block = size;
+
+ if (block !=
+ (err = i2c_master_recv(&dev->i2c_client, p, block))) {
+ printk(KERN_WARNING
+ "%s: i2c eeprom read error (err=%d)\n",
+ dev->name, err);
+ return -1;
+ }
+ size -= block;
+ p += block;
+ }
+ for (i = 0; i < len; i++) {
+ if (0 == (i % 16))
+ printk(KERN_INFO "%s: i2c eeprom %02x:", dev->name, i);
+ printk(" %02x", eedata[i]);
+ if (15 == (i % 16))
+ printk("\n");
+ }
+
+ printk(KERN_INFO "EEPROM ID= 0x%08x\n", em_eeprom->id);
+ printk(KERN_INFO "Vendor/Product ID= %04x:%04x\n", em_eeprom->vendor_ID,
+ em_eeprom->product_ID);
+
+ switch (em_eeprom->chip_conf >> 4 & 0x3) {
+ case 0:
+ printk(KERN_INFO "No audio on board.\n");
+ break;
+ case 1:
+ printk(KERN_INFO "AC97 audio (5 sample rates)\n");
+ break;
+ case 2:
+ printk(KERN_INFO "I2S audio, sample rate=32k\n");
+ break;
+ case 3:
+ printk(KERN_INFO "I2S audio, 3 sample rates\n");
+ break;
+ }
+
+ if (em_eeprom->chip_conf & 1 << 3)
+ printk(KERN_INFO "USB Remote wakeup capable\n");
+
+ if (em_eeprom->chip_conf & 1 << 2)
+ printk(KERN_INFO "USB Self power capable\n");
+
+ switch (em_eeprom->chip_conf & 0x3) {
+ case 0:
+ printk(KERN_INFO "500mA max power\n");
+ break;
+ case 1:
+ printk(KERN_INFO "400mA max power\n");
+ break;
+ case 2:
+ printk(KERN_INFO "300mA max power\n");
+ break;
+ case 3:
+ printk(KERN_INFO "200mA max power\n");
+ break;
+ }
+ printk(KERN_INFO "Table at 0x%02x, strings=0x%04x, 0x%04x, 0x%04x\n",
+ em_eeprom->string_idx_table,em_eeprom->string1,
+ em_eeprom->string2,em_eeprom->string3);
+
+ return 0;
+}
+
+/* ----------------------------------------------------------- */
+
+/*
+ * algo_control()
+ */
+static int algo_control(struct i2c_adapter *adapter,
+ unsigned int cmd, unsigned long arg)
+{
+ return 0;
+}
+
+/*
+ * functionality()
+ */
+static u32 functionality(struct i2c_adapter *adap)
+{
+ return I2C_FUNC_SMBUS_EMUL;
+}
+
+#ifndef I2C_PEC
+static void inc_use(struct i2c_adapter *adap)
+{
+ MOD_INC_USE_COUNT;
+}
+
+static void dec_use(struct i2c_adapter *adap)
+{
+ MOD_DEC_USE_COUNT;
+}
+#endif
+
+static int em28xx_set_tuner(int check_eeprom, struct i2c_client *client)
+{
+ struct em28xx *dev = client->adapter->algo_data;
+ struct tuner_setup tun_setup;
+
+ if (dev->has_tuner) {
+ tun_setup.mode_mask = T_ANALOG_TV | T_RADIO;
+ tun_setup.type = dev->tuner_type;
+ tun_setup.addr = dev->tuner_addr;
+
+ em28xx_i2c_call_clients(dev, TUNER_SET_TYPE_ADDR, &tun_setup);
+ }
+
+ return (0);
+}
+
+/*
+ * 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;
+
+ switch (client->addr << 1) {
+ case 0x86:
+ em28xx_i2c_call_clients(dev, TDA9887_SET_CONFIG, &dev->tda9887_conf);
+ break;
+ case 0x42:
+ dprintk1(1,"attach_inform: saa7114 detected.\n");
+ break;
+ case 0x4a:
+ dprintk1(1,"attach_inform: saa7113 detected.\n");
+ break;
+ case 0xa0:
+ dprintk1(1,"attach_inform: eeprom detected.\n");
+ break;
+ case 0x60:
+ case 0x8e:
+ {
+ struct IR_i2c *ir = i2c_get_clientdata(client);
+ dprintk1(1,"attach_inform: IR detected (%s).\n",ir->phys);
+ em28xx_set_ir(dev,ir);
+ break;
+ }
+ case 0x80:
+ case 0x88:
+ dprintk1(1,"attach_inform: msp34xx detected.\n");
+ break;
+ case 0xb8:
+ case 0xba:
+ dprintk1(1,"attach_inform: tvp5150 detected.\n");
+ break;
+ default:
+ dprintk1(1,"attach inform: detected I2C address %x\n", client->addr << 1);
+ dev->tuner_addr = client->addr;
+ em28xx_set_tuner(-1, client);
+ }
+
+ return 0;
+}
+
+static struct i2c_algorithm em28xx_algo = {
+ .master_xfer = em28xx_i2c_xfer,
+ .algo_control = algo_control,
+ .functionality = functionality,
+};
+
+static struct i2c_adapter em28xx_adap_template = {
+#ifdef I2C_PEC
+ .owner = THIS_MODULE,
+#else
+ .inc_use = inc_use,
+ .dec_use = dec_use,
+#endif
+#ifdef I2C_CLASS_TV_ANALOG
+ .class = I2C_CLASS_TV_ANALOG,
+#endif
+ .name = "em28xx",
+ .id = I2C_HW_B_EM28XX,
+ .algo = &em28xx_algo,
+ .client_register = attach_inform,
+};
+
+static struct i2c_client em28xx_client_template = {
+ .name = "em28xx internal",
+ .flags = I2C_CLIENT_ALLOW_USE,
+};
+
+/* ----------------------------------------------------------- */
+
+/*
+ * i2c_devs
+ * incomplete list of known devices
+ */
+static char *i2c_devs[128] = {
+ [0x4a >> 1] = "saa7113h",
+ [0x60 >> 1] = "remote IR sensor",
+ [0x8e >> 1] = "remote IR sensor",
+ [0x86 >> 1] = "tda9887",
+ [0x80 >> 1] = "msp34xx",
+ [0x88 >> 1] = "msp34xx",
+ [0xa0 >> 1] = "eeprom",
+ [0xb8 >> 1] = "tvp5150a",
+ [0xba >> 1] = "tvp5150a",
+ [0xc0 >> 1] = "tuner (analog)",
+ [0xc2 >> 1] = "tuner (analog)",
+ [0xc4 >> 1] = "tuner (analog)",
+ [0xc6 >> 1] = "tuner (analog)",
+};
+
+/*
+ * do_i2c_scan()
+ * check i2c address range for devices
+ */
+static void do_i2c_scan(char *name, struct i2c_client *c)
+{
+ unsigned char buf;
+ int i, rc;
+
+ for (i = 0; i < 128; i++) {
+ c->addr = i;
+ rc = i2c_master_recv(c, &buf, 0);
+ if (rc < 0)
+ continue;
+ printk(KERN_INFO "%s: found i2c device @ 0x%x [%s]\n", name,
+ i << 1, i2c_devs[i] ? i2c_devs[i] : "???");
+ }
+}
+
+/*
+ * em28xx_i2c_call_clients()
+ * send commands to all attached i2c devices
+ */
+void em28xx_i2c_call_clients(struct em28xx *dev, unsigned int cmd, void *arg)
+{
+ BUG_ON(NULL == dev->i2c_adap.algo_data);
+ i2c_clients_command(&dev->i2c_adap, cmd, arg);
+}
+
+/*
+ * em28xx_i2c_register()
+ * register i2c bus
+ */
+int em28xx_i2c_register(struct em28xx *dev)
+{
+ BUG_ON(!dev->em28xx_write_regs || !dev->em28xx_read_reg);
+ BUG_ON(!dev->em28xx_write_regs_req || !dev->em28xx_read_reg_req);
+ dev->i2c_adap = em28xx_adap_template;
+ dev->i2c_adap.dev.parent = &dev->udev->dev;
+ strcpy(dev->i2c_adap.name, dev->name);
+ dev->i2c_adap.algo_data = dev;
+ i2c_add_adapter(&dev->i2c_adap);
+
+ dev->i2c_client = em28xx_client_template;
+ dev->i2c_client.adapter = &dev->i2c_adap;
+
+ em28xx_i2c_eeprom(dev, dev->eedata, sizeof(dev->eedata));
+
+ if (i2c_scan)
+ do_i2c_scan(dev->name, &dev->i2c_client);
+ return 0;
+}
+
+/*
+ * em28xx_i2c_unregister()
+ * unregister i2c_bus
+ */
+int em28xx_i2c_unregister(struct em28xx *dev)
+{
+ i2c_del_adapter(&dev->i2c_adap);
+ return 0;
+}
diff --git a/drivers/media/video/em28xx/em28xx-input.c b/drivers/media/video/em28xx/em28xx-input.c
new file mode 100644
index 000000000000..32c49df58adc
--- /dev/null
+++ b/drivers/media/video/em28xx/em28xx-input.c
@@ -0,0 +1,184 @@
+/*
+ handle em28xx IR remotes via linux kernel input layer.
+
+ Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it>
+ Markus Rechberger <mrechberger@gmail.com>
+ Mauro Carvalho Chehab <mchehab@brturbo.com.br>
+ Sascha Sommer <saschasommer@freenet.de>
+
+ 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/moduleparam.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/input.h>
+#include <linux/usb.h>
+
+#include "em28xx.h"
+
+static unsigned int disable_ir = 0;
+module_param(disable_ir, int, 0444);
+MODULE_PARM_DESC(disable_ir,"disable infrared remote support");
+
+static unsigned int ir_debug = 0;
+module_param(ir_debug, int, 0644);
+MODULE_PARM_DESC(ir_debug,"enable debug messages [IR]");
+
+#define dprintk(fmt, arg...) if (ir_debug) \
+ printk(KERN_DEBUG "%s/ir: " fmt, ir->c.name , ## arg)
+
+/* ---------------------------------------------------------------------- */
+
+static IR_KEYTAB_TYPE ir_codes_em_terratec[IR_KEYTAB_SIZE] = {
+ [ 0x01 ] = KEY_CHANNEL,
+ [ 0x02 ] = KEY_SELECT,
+ [ 0x03 ] = KEY_MUTE,
+ [ 0x04 ] = KEY_POWER,
+ [ 0x05 ] = KEY_KP1,
+ [ 0x06 ] = KEY_KP2,
+ [ 0x07 ] = KEY_KP3,
+ [ 0x08 ] = KEY_CHANNELUP,
+ [ 0x09 ] = KEY_KP4,
+ [ 0x0a ] = KEY_KP5,
+ [ 0x0b ] = KEY_KP6,
+ [ 0x0c ] = KEY_CHANNELDOWN,
+ [ 0x0d ] = KEY_KP7,
+ [ 0x0e ] = KEY_KP8,
+ [ 0x0f ] = KEY_KP9,
+ [ 0x10 ] = KEY_VOLUMEUP,
+ [ 0x11 ] = KEY_KP0,
+ [ 0x12 ] = KEY_MENU,
+ [ 0x13 ] = KEY_PRINT,
+ [ 0x14 ] = KEY_VOLUMEDOWN,
+ [ 0x16 ] = KEY_PAUSE,
+ [ 0x18 ] = KEY_RECORD,
+ [ 0x19 ] = KEY_REWIND,
+ [ 0x1a ] = KEY_PLAY,
+ [ 0x1b ] = KEY_FORWARD,
+ [ 0x1c ] = KEY_BACKSPACE,
+ [ 0x1e ] = KEY_STOP,
+ [ 0x40 ] = KEY_ZOOM,
+};
+
+/* ----------------------------------------------------------------------- */
+
+static int 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)) {
+ dprintk("read error\n");
+ return -EIO;
+ }
+
+ /* it seems that 0xFE indicates that a button is still hold
+ down, while 0xff indicates that no button is hold
+ down. 0xfe sequences are sometimes interrupted by 0xFF */
+
+ dprintk("key %02x\n", b);
+
+ if (b == 0xff)
+ return 0;
+
+ if (b == 0xfe)
+ /* keep old data */
+ return 1;
+
+ *ir_key = b;
+ *ir_raw = b;
+ return 1;
+}
+
+
+static int get_key_em_haup(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
+{
+ unsigned char buf[2];
+ unsigned char code;
+
+ /* poll IR chip */
+ if (2 != i2c_master_recv(&ir->c,buf,2))
+ return -EIO;
+
+ /* Does eliminate repeated parity code */
+ if (buf[1]==0xff)
+ return 0;
+
+ /* avoid fast reapeating */
+ if (buf[1]==ir->old)
+ return 0;
+ ir->old=buf[1];
+
+ /* Rearranges bits to the right order */
+ code= ((buf[0]&0x01)<<5) | /* 0010 0000 */
+ ((buf[0]&0x02)<<3) | /* 0001 0000 */
+ ((buf[0]&0x04)<<1) | /* 0000 1000 */
+ ((buf[0]&0x08)>>1) | /* 0000 0100 */
+ ((buf[0]&0x10)>>3) | /* 0000 0010 */
+ ((buf[0]&0x20)>>5); /* 0000 0001 */
+
+ dprintk("ir hauppauge (em2840): code=0x%02x (rcv=0x%02x)\n",code,buf[0]);
+
+ /* return key */
+ *ir_key = code;
+ *ir_raw = code;
+ return 1;
+}
+
+/* ----------------------------------------------------------------------- */
+void em28xx_set_ir(struct em28xx * dev,struct IR_i2c *ir)
+{
+ if (disable_ir) {
+ ir->get_key=NULL;
+ return ;
+ }
+
+ /* detect & configure */
+ switch (dev->model) {
+ case (EM2800_BOARD_UNKNOWN):
+ break;
+ case (EM2820_BOARD_UNKNOWN):
+ break;
+ case (EM2800_BOARD_TERRATEC_CINERGY_200):
+ case (EM2820_BOARD_TERRATEC_CINERGY_250):
+ ir->ir_codes = ir_codes_em_terratec;
+ ir->get_key = get_key_terratec;
+ snprintf(ir->c.name, sizeof(ir->c.name), "i2c IR (EM28XX Terratec)");
+ break;
+ case (EM2820_BOARD_PINNACLE_USB_2):
+ break;
+ case (EM2820_BOARD_HAUPPAUGE_WINTV_USB_2):
+ ir->ir_codes = ir_codes_hauppauge_new;
+ ir->get_key = get_key_em_haup;
+ snprintf(ir->c.name, sizeof(ir->c.name), "i2c IR (EM2840 Hauppauge)");
+ break;
+ case (EM2820_BOARD_MSI_VOX_USB_2):
+ break;
+ case (EM2800_BOARD_LEADTEK_WINFAST_USBII):
+ break;
+ case (EM2800_BOARD_KWORLD_USB2800):
+ break;
+ }
+}
+
+/* ----------------------------------------------------------------------
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c
new file mode 100644
index 000000000000..57c1826b928e
--- /dev/null
+++ b/drivers/media/video/em28xx/em28xx-video.c
@@ -0,0 +1,1933 @@
+/*
+ em28xx-video.c - driver for Empia EM2800/EM2820/2840 USB video capture devices
+
+ Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it>
+ Markus Rechberger <mrechberger@gmail.com>
+ Mauro Carvalho Chehab <mchehab@brturbo.com.br>
+ Sascha Sommer <saschasommer@freenet.de>
+
+ 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/list.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/usb.h>
+#include <linux/i2c.h>
+#include <linux/version.h>
+#include <linux/video_decoder.h>
+
+#include "em28xx.h"
+#include <media/tuner.h>
+
+#define DRIVER_AUTHOR "Ludovico Cavedon <cavedon@sssup.it>, " \
+ "Markus Rechberger <mrechberger@gmail.com>, " \
+ "Mauro Carvalho Chehab <mchehab@brturbo.com.br>, " \
+ "Sascha Sommer <saschasommer@freenet.de>"
+
+#define DRIVER_NAME "em28xx"
+#define DRIVER_DESC "Empia em28xx based USB video device driver"
+#define EM28XX_VERSION_CODE KERNEL_VERSION(0, 0, 1)
+
+#define em28xx_videodbg(fmt, arg...) do {\
+ if (video_debug) \
+ printk(KERN_INFO "%s %s :"fmt, \
+ dev->name, __FUNCTION__ , ##arg); } while (0)
+
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
+
+static LIST_HEAD(em28xx_devlist);
+
+static unsigned int card[] = {[0 ... (EM28XX_MAXBOARDS - 1)] = UNSET };
+module_param_array(card, int, NULL, 0444);
+MODULE_PARM_DESC(card,"card type");
+
+static int tuner = -1;
+module_param(tuner, int, 0444);
+MODULE_PARM_DESC(tuner, "tuner type");
+
+static unsigned int video_debug = 0;
+module_param(video_debug,int,0644);
+MODULE_PARM_DESC(video_debug,"enable debug messages [video]");
+
+/* supported tv norms */
+static struct em28xx_tvnorm tvnorms[] = {
+ {
+ .name = "PAL",
+ .id = V4L2_STD_PAL,
+ .mode = VIDEO_MODE_PAL,
+ }, {
+ .name = "NTSC",
+ .id = V4L2_STD_NTSC,
+ .mode = VIDEO_MODE_NTSC,
+ }, {
+ .name = "SECAM",
+ .id = V4L2_STD_SECAM,
+ .mode = VIDEO_MODE_SECAM,
+ }, {
+ .name = "PAL-M",
+ .id = V4L2_STD_PAL_M,
+ .mode = VIDEO_MODE_PAL,
+ }
+};
+
+static const unsigned char saa7114_i2c_init[] = {
+ 0x00,0x00,0x01,0x08,0x02,0xc4,0x03,0x30,0x04,0x90,0x05,0x90,0x06,0xeb,0x07,0xe0,
+ 0x08,0x88,0x09,0x40,0x0a,0x80,0x0b,0x44,0x0c,0x40,0x0d,0x00,0x0e,0x81,0x0f,0x2a,
+ 0x10,0x06,0x11,0x00,0x12,0xc8,0x13,0x80,0x14,0x00,0x15,0x11,0x16,0x01,0x17,0x42,
+ 0x18,0x40,0x19,0x80,0x40,0x00,0x41,0xff,0x42,0xff,0x43,0xff,0x44,0xff,0x45,0xff,
+ 0x46,0xff,0x47,0xff,0x48,0xff,0x49,0xff,0x4a,0xff,0x4b,0xff,0x4c,0xff,0x4d,0xff,
+ 0x4e,0xff,0x4f,0xff,0x50,0xff,0x51,0xff,0x52,0xff,0x53,0xff,0x54,0x5f,0x55,0xff,
+ 0x56,0xff,0x57,0xff,0x58,0x00,0x59,0x47,0x5a,0x03,0x5b,0x03,0x5d,0x3e,0x5e,0x00,
+ 0x80,0x1c,0x83,0x01,0x84,0xa5,0x85,0x10,0x86,0x45,0x87,0x41,0x88,0xf0,0x88,0x00,
+ 0x88,0xf0,0x90,0x00,0x91,0x08,0x92,0x00,0x93,0x80,0x94,0x08,0x95,0x00,0x96,0xc0,
+ 0x97,0x02,0x98,0x13,0x99,0x00,0x9a,0x38,0x9b,0x01,0x9c,0x80,0x9d,0x02,0x9e,0x06,
+ 0x9f,0x01,0xa0,0x01,0xa1,0x00,0xa2,0x00,0xa4,0x80,0xa5,0x36,0xa6,0x36,0xa8,0x67,
+ 0xa9,0x04,0xaa,0x00,0xac,0x33,0xad,0x02,0xae,0x00,0xb0,0xcd,0xb1,0x04,0xb2,0xcd,
+ 0xb3,0x04,0xb4,0x01,0xb8,0x00,0xb9,0x00,0xba,0x00,0xbb,0x00,0xbc,0x00,0xbd,0x00,
+ 0xbe,0x00,0xbf,0x00
+};
+
+#define TVNORMS ARRAY_SIZE(tvnorms)
+
+/* supported controls */
+static struct v4l2_queryctrl em28xx_qctrl[] = {
+ {
+ .id = V4L2_CID_BRIGHTNESS,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Brightness",
+ .minimum = -128,
+ .maximum = 127,
+ .step = 1,
+ .default_value = 0,
+ .flags = 0,
+ },{
+ .id = V4L2_CID_CONTRAST,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Contrast",
+ .minimum = 0x0,
+ .maximum = 0x1f,
+ .step = 0x1,
+ .default_value = 0x10,
+ .flags = 0,
+ },{
+ .id = V4L2_CID_SATURATION,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Saturation",
+ .minimum = 0x0,
+ .maximum = 0x1f,
+ .step = 0x1,
+ .default_value = 0x10,
+ .flags = 0,
+ },{
+ .id = V4L2_CID_AUDIO_VOLUME,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Volume",
+ .minimum = 0x0,
+ .maximum = 0x1f,
+ .step = 0x1,
+ .default_value = 0x1f,
+ .flags = 0,
+ },{
+ .id = V4L2_CID_AUDIO_MUTE,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "Mute",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 1,
+ .flags = 0,
+ },{
+ .id = V4L2_CID_RED_BALANCE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Red chroma balance",
+ .minimum = -128,
+ .maximum = 127,
+ .step = 1,
+ .default_value = 0,
+ .flags = 0,
+ },{
+ .id = V4L2_CID_BLUE_BALANCE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Blue chroma balance",
+ .minimum = -128,
+ .maximum = 127,
+ .step = 1,
+ .default_value = 0,
+ .flags = 0,
+ },{
+ .id = V4L2_CID_GAMMA,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Gamma",
+ .minimum = 0x0,
+ .maximum = 0x3f,
+ .step = 0x1,
+ .default_value = 0x20,
+ .flags = 0,
+ }
+};
+
+static struct usb_driver em28xx_usb_driver;
+
+static DECLARE_MUTEX(em28xx_sysfs_lock);
+static DECLARE_RWSEM(em28xx_disconnect);
+
+/********************* v4l2 interface ******************************************/
+
+static inline unsigned long kvirt_to_pa(unsigned long adr)
+{
+ unsigned long kva, ret;
+
+ kva = (unsigned long)page_address(vmalloc_to_page((void *)adr));
+ kva |= adr & (PAGE_SIZE - 1);
+ ret = __pa(kva);
+ return ret;
+}
+
+/*
+ * em28xx_config()
+ * inits registers with sane defaults
+ */
+static int em28xx_config(struct em28xx *dev)
+{
+
+ /* Sets I2C speed to 100 KHz */
+ em28xx_write_regs_req(dev, 0x00, 0x06, "\x40", 1);
+
+ /* enable vbi capturing */
+ em28xx_audio_usb_mute(dev, 1);
+ dev->mute = 1; /* maybe not the right place... */
+ dev->volume = 0x1f;
+ em28xx_audio_analog_set(dev);
+ em28xx_audio_analog_setup(dev);
+ em28xx_outfmt_set_yuv422(dev);
+ em28xx_colorlevels_set_default(dev);
+ em28xx_compression_disable(dev);
+
+ return 0;
+}
+
+/*
+ * em28xx_config_i2c()
+ * configure i2c attached devices
+ */
+void em28xx_config_i2c(struct em28xx *dev)
+{
+ struct v4l2_frequency f;
+ struct video_decoder_init em28xx_vdi = {.data = NULL };
+
+
+ /* configure decoder */
+ if(dev->model == EM2820_BOARD_MSI_VOX_USB_2){
+ em28xx_vdi.data=saa7114_i2c_init;
+ em28xx_vdi.len=sizeof(saa7114_i2c_init);
+ }
+
+
+ em28xx_i2c_call_clients(dev, DECODER_INIT, &em28xx_vdi);
+ em28xx_i2c_call_clients(dev, DECODER_SET_INPUT, &dev->ctl_input);
+/* em28xx_i2c_call_clients(dev,DECODER_SET_PICTURE, &dev->vpic); */
+/* em28xx_i2c_call_clients(dev,DECODER_SET_NORM,&dev->tvnorm->id); */
+/* em28xx_i2c_call_clients(dev,DECODER_ENABLE_OUTPUT,&output); */
+/* em28xx_i2c_call_clients(dev,DECODER_DUMP, NULL); */
+
+ /* configure tuner */
+ f.tuner = 0;
+ f.type = V4L2_TUNER_ANALOG_TV;
+ f.frequency = 9076; /* FIXME:remove magic number */
+ dev->ctl_freq = f.frequency;
+ em28xx_i2c_call_clients(dev, VIDIOC_S_FREQUENCY, &f);
+
+ /* configure tda9887 */
+
+
+/* em28xx_i2c_call_clients(dev,VIDIOC_S_STD,&dev->tvnorm->id); */
+}
+
+/*
+ * em28xx_empty_framequeues()
+ * prepare queues for incoming and outgoing frames
+ */
+static void em28xx_empty_framequeues(struct em28xx *dev)
+{
+ u32 i;
+
+ INIT_LIST_HEAD(&dev->inqueue);
+ INIT_LIST_HEAD(&dev->outqueue);
+
+ for (i = 0; i < EM28XX_NUM_FRAMES; i++) {
+ dev->frame[i].state = F_UNUSED;
+ dev->frame[i].buf.bytesused = 0;
+ }
+}
+
+static void video_mux(struct em28xx *dev, int index)
+{
+ int input, ainput;
+
+ input = INPUT(index)->vmux;
+ dev->ctl_input = index;
+ dev->ctl_ainput = INPUT(index)->amux;
+
+ em28xx_i2c_call_clients(dev, DECODER_SET_INPUT, &input);
+
+
+ em28xx_videodbg("Setting input index=%d, vmux=%d, amux=%d\n",index,input,dev->ctl_ainput);
+
+ if (dev->has_msp34xx) {
+ em28xx_i2c_call_clients(dev, VIDIOC_S_AUDIO, &dev->ctl_ainput);
+ ainput = EM28XX_AUDIO_SRC_TUNER;
+ em28xx_audio_source(dev, ainput);
+ } else {
+ switch (dev->ctl_ainput) {
+ case 0:
+ ainput = EM28XX_AUDIO_SRC_TUNER;
+ break;
+ default:
+ ainput = EM28XX_AUDIO_SRC_LINE;
+ }
+ em28xx_audio_source(dev, ainput);
+ }
+}
+
+/*
+ * em28xx_v4l2_open()
+ * inits the device and starts isoc transfer
+ */
+static int em28xx_v4l2_open(struct inode *inode, struct file *filp)
+{
+ int minor = iminor(inode);
+ int errCode = 0;
+ struct em28xx *h,*dev = NULL;
+ struct list_head *list;
+
+ list_for_each(list,&em28xx_devlist) {
+ h = list_entry(list, struct em28xx, devlist);
+ if (h->vdev->minor == minor) {
+ dev = h;
+ }
+ }
+
+ filp->private_data=dev;
+
+
+ em28xx_videodbg("users=%d\n", dev->users);
+
+ if (!down_read_trylock(&em28xx_disconnect))
+ return -ERESTARTSYS;
+
+ if (dev->users) {
+ em28xx_warn("this driver can be opened only once\n");
+ up_read(&em28xx_disconnect);
+ return -EBUSY;
+ }
+
+/* if(dev->vbi_dev->minor == minor){
+ dev->type=V4L2_BUF_TYPE_VBI_CAPTURE;
+ }*/
+ if (dev->vdev->minor == minor) {
+ dev->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ }
+
+ init_MUTEX(&dev->fileop_lock); /* to 1 == available */
+ spin_lock_init(&dev->queue_lock);
+ init_waitqueue_head(&dev->wait_frame);
+ init_waitqueue_head(&dev->wait_stream);
+
+ down(&dev->lock);
+
+ em28xx_set_alternate(dev);
+
+ dev->width = norm_maxw(dev);
+ dev->height = norm_maxh(dev);
+ dev->frame_size = dev->width * dev->height * 2;
+ dev->field_size = dev->frame_size >> 1; /*both_fileds ? dev->frame_size>>1 : dev->frame_size; */
+ dev->bytesperline = dev->width * 2;
+ dev->hscale = 0;
+ dev->vscale = 0;
+
+ em28xx_capture_start(dev, 1);
+ em28xx_resolution_set(dev);
+
+ /* start the transfer */
+ errCode = em28xx_init_isoc(dev);
+ if (errCode)
+ goto err;
+
+ dev->users++;
+ filp->private_data = dev;
+ dev->io = IO_NONE;
+ dev->stream = STREAM_OFF;
+ dev->num_frames = 0;
+
+ /* prepare queues */
+ em28xx_empty_framequeues(dev);
+
+ dev->state |= DEV_INITIALIZED;
+
+ video_mux(dev, 0);
+
+ err:
+ up(&dev->lock);
+ up_read(&em28xx_disconnect);
+ return errCode;
+}
+
+/*
+ * em28xx_realease_resources()
+ * unregisters the v4l2,i2c and usb devices
+ * called when the device gets disconected or at module unload
+*/
+static void em28xx_release_resources(struct em28xx *dev)
+{
+ down(&em28xx_sysfs_lock);
+
+ em28xx_info("V4L2 device /dev/video%d deregistered\n",
+ dev->vdev->minor);
+ list_del(&dev->devlist);
+ video_unregister_device(dev->vdev);
+/* video_unregister_device(dev->vbi_dev); */
+ em28xx_i2c_unregister(dev);
+ usb_put_dev(dev->udev);
+ up(&em28xx_sysfs_lock);
+}
+
+/*
+ * em28xx_v4l2_close()
+ * stops streaming and deallocates all resources allocated by the v4l2 calls and ioctls
+ */
+static int em28xx_v4l2_close(struct inode *inode, struct file *filp)
+{
+ int errCode;
+ struct em28xx *dev=filp->private_data;
+
+ em28xx_videodbg("users=%d\n", dev->users);
+
+ down(&dev->lock);
+
+ em28xx_uninit_isoc(dev);
+
+ em28xx_release_buffers(dev);
+
+ /* the device is already disconnect, free the remaining resources */
+ if (dev->state & DEV_DISCONNECTED) {
+ em28xx_release_resources(dev);
+ up(&dev->lock);
+ kfree(dev);
+ return 0;
+ }
+
+ /* set alternate 0 */
+ dev->alt = 0;
+ em28xx_videodbg("setting alternate 0\n");
+ errCode = usb_set_interface(dev->udev, 0, 0);
+ if (errCode < 0) {
+ em28xx_errdev ("cannot change alternate number to 0 (error=%i)\n",
+ errCode);
+ }
+
+ dev->users--;
+ wake_up_interruptible_nr(&dev->open, 1);
+ up(&dev->lock);
+ return 0;
+}
+
+/*
+ * em28xx_v4l2_read()
+ * will allocate buffers when called for the first time
+ */
+static ssize_t
+em28xx_v4l2_read(struct file *filp, char __user * buf, size_t count,
+ loff_t * f_pos)
+{
+ struct em28xx_frame_t *f, *i;
+ unsigned long lock_flags;
+ int ret = 0;
+ struct em28xx *dev = filp->private_data;
+
+ if (down_interruptible(&dev->fileop_lock))
+ return -ERESTARTSYS;
+
+ if (dev->state & DEV_DISCONNECTED) {
+ em28xx_videodbg("device not present\n");
+ up(&dev->fileop_lock);
+ return -ENODEV;
+ }
+
+ if (dev->state & DEV_MISCONFIGURED) {
+ em28xx_videodbg("device misconfigured; close and open it again\n");
+ up(&dev->fileop_lock);
+ return -EIO;
+ }
+
+ if (dev->io == IO_MMAP) {
+ em28xx_videodbg ("IO method is set to mmap; close and open"
+ " the device again to choose the read method\n");
+ up(&dev->fileop_lock);
+ return -EINVAL;
+ }
+
+ if (dev->io == IO_NONE) {
+ if (!em28xx_request_buffers(dev, EM28XX_NUM_READ_FRAMES)) {
+ em28xx_errdev("read failed, not enough memory\n");
+ up(&dev->fileop_lock);
+ return -ENOMEM;
+ }
+ dev->io = IO_READ;
+ dev->stream = STREAM_ON;
+ em28xx_queue_unusedframes(dev);
+ }
+
+ if (!count) {
+ up(&dev->fileop_lock);
+ return 0;
+ }
+
+ if (list_empty(&dev->outqueue)) {
+ if (filp->f_flags & O_NONBLOCK) {
+ up(&dev->fileop_lock);
+ return -EAGAIN;
+ }
+ ret = wait_event_interruptible
+ (dev->wait_frame,
+ (!list_empty(&dev->outqueue)) ||
+ (dev->state & DEV_DISCONNECTED));
+ if (ret) {
+ up(&dev->fileop_lock);
+ return ret;
+ }
+ if (dev->state & DEV_DISCONNECTED) {
+ up(&dev->fileop_lock);
+ return -ENODEV;
+ }
+ }
+
+ f = list_entry(dev->outqueue.prev, struct em28xx_frame_t, frame);
+
+ spin_lock_irqsave(&dev->queue_lock, lock_flags);
+ list_for_each_entry(i, &dev->outqueue, frame)
+ i->state = F_UNUSED;
+ INIT_LIST_HEAD(&dev->outqueue);
+ spin_unlock_irqrestore(&dev->queue_lock, lock_flags);
+
+ em28xx_queue_unusedframes(dev);
+
+ if (count > f->buf.length)
+ count = f->buf.length;
+
+ if (copy_to_user(buf, f->bufmem, count)) {
+ up(&dev->fileop_lock);
+ return -EFAULT;
+ }
+ *f_pos += count;
+
+ up(&dev->fileop_lock);
+
+ return count;
+}
+
+/*
+ * em28xx_v4l2_poll()
+ * will allocate buffers when called for the first time
+ */
+static unsigned int em28xx_v4l2_poll(struct file *filp, poll_table * wait)
+{
+ unsigned int mask = 0;
+ struct em28xx *dev = filp->private_data;
+
+ if (down_interruptible(&dev->fileop_lock))
+ return POLLERR;
+
+ if (dev->state & DEV_DISCONNECTED) {
+ em28xx_videodbg("device not present\n");
+ } else if (dev->state & DEV_MISCONFIGURED) {
+ em28xx_videodbg("device is misconfigured; close and open it again\n");
+ } else {
+ if (dev->io == IO_NONE) {
+ if (!em28xx_request_buffers
+ (dev, EM28XX_NUM_READ_FRAMES)) {
+ em28xx_warn
+ ("poll() failed, not enough memory\n");
+ } else {
+ dev->io = IO_READ;
+ dev->stream = STREAM_ON;
+ }
+ }
+
+ if (dev->io == IO_READ) {
+ em28xx_queue_unusedframes(dev);
+ poll_wait(filp, &dev->wait_frame, wait);
+
+ if (!list_empty(&dev->outqueue))
+ mask |= POLLIN | POLLRDNORM;
+
+ up(&dev->fileop_lock);
+
+ return mask;
+ }
+ }
+
+ up(&dev->fileop_lock);
+ return POLLERR;
+}
+
+/*
+ * em28xx_vm_open()
+ */
+static void em28xx_vm_open(struct vm_area_struct *vma)
+{
+ struct em28xx_frame_t *f = vma->vm_private_data;
+ f->vma_use_count++;
+}
+
+/*
+ * em28xx_vm_close()
+ */
+static void em28xx_vm_close(struct vm_area_struct *vma)
+{
+ /* NOTE: buffers are not freed here */
+ struct em28xx_frame_t *f = vma->vm_private_data;
+ f->vma_use_count--;
+}
+
+static struct vm_operations_struct em28xx_vm_ops = {
+ .open = em28xx_vm_open,
+ .close = em28xx_vm_close,
+};
+
+/*
+ * em28xx_v4l2_mmap()
+ */
+static int em28xx_v4l2_mmap(struct file *filp, struct vm_area_struct *vma)
+{
+ unsigned long size = vma->vm_end - vma->vm_start,
+ start = vma->vm_start, pos, page;
+ u32 i;
+
+ struct em28xx *dev = filp->private_data;
+
+ if (down_interruptible(&dev->fileop_lock))
+ return -ERESTARTSYS;
+
+ if (dev->state & DEV_DISCONNECTED) {
+ em28xx_videodbg("mmap: device not present\n");
+ up(&dev->fileop_lock);
+ return -ENODEV;
+ }
+
+ if (dev->state & DEV_MISCONFIGURED) {
+ em28xx_videodbg ("mmap: Device is misconfigured; close and "
+ "open it again\n");
+ up(&dev->fileop_lock);
+ return -EIO;
+ }
+
+ if (dev->io != IO_MMAP || !(vma->vm_flags & VM_WRITE) ||
+ size != PAGE_ALIGN(dev->frame[0].buf.length)) {
+ up(&dev->fileop_lock);
+ return -EINVAL;
+ }
+
+ for (i = 0; i < dev->num_frames; i++) {
+ if ((dev->frame[i].buf.m.offset >> PAGE_SHIFT) == vma->vm_pgoff)
+ break;
+ }
+ if (i == dev->num_frames) {
+ em28xx_videodbg("mmap: user supplied mapping address is out of range\n");
+ up(&dev->fileop_lock);
+ return -EINVAL;
+ }
+
+ /* VM_IO is eventually going to replace PageReserved altogether */
+ vma->vm_flags |= VM_IO;
+ vma->vm_flags |= VM_RESERVED; /* avoid to swap out this VMA */
+
+ pos = (unsigned long)dev->frame[i].bufmem;
+ while (size > 0) { /* size is page-aligned */
+ page = vmalloc_to_pfn((void *)pos);
+ if (remap_pfn_range(vma, start, page, PAGE_SIZE,
+ vma->vm_page_prot)) {
+ em28xx_videodbg("mmap: rename page map failed\n");
+ up(&dev->fileop_lock);
+ return -EAGAIN;
+ }
+ start += PAGE_SIZE;
+ pos += PAGE_SIZE;
+ size -= PAGE_SIZE;
+ }
+
+ vma->vm_ops = &em28xx_vm_ops;
+ vma->vm_private_data = &dev->frame[i];
+
+ em28xx_vm_open(vma);
+ up(&dev->fileop_lock);
+ return 0;
+}
+
+/*
+ * em28xx_get_ctrl()
+ * return the current saturation, brightness or contrast, mute state
+ */
+static int em28xx_get_ctrl(struct em28xx *dev, struct v4l2_control *ctrl)
+{
+ s32 tmp;
+ switch (ctrl->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ ctrl->value = dev->mute;
+ return 0;
+ case V4L2_CID_AUDIO_VOLUME:
+ ctrl->value = dev->volume;
+ return 0;
+ case V4L2_CID_BRIGHTNESS:
+ if ((tmp = em28xx_brightness_get(dev)) < 0)
+ return -EIO;
+ ctrl->value = (s32) ((s8) tmp); /* FIXME: clenaer way to extend sign? */
+ return 0;
+ case V4L2_CID_CONTRAST:
+ if ((ctrl->value = em28xx_contrast_get(dev)) < 0)
+ return -EIO;
+ return 0;
+ case V4L2_CID_SATURATION:
+ if ((ctrl->value = em28xx_saturation_get(dev)) < 0)
+ return -EIO;
+ return 0;
+ case V4L2_CID_RED_BALANCE:
+ if ((tmp = em28xx_v_balance_get(dev)) < 0)
+ return -EIO;
+ ctrl->value = (s32) ((s8) tmp); /* FIXME: clenaer way to extend sign? */
+ return 0;
+ case V4L2_CID_BLUE_BALANCE:
+ if ((tmp = em28xx_u_balance_get(dev)) < 0)
+ return -EIO;
+ ctrl->value = (s32) ((s8) tmp); /* FIXME: clenaer way to extend sign? */
+ return 0;
+ case V4L2_CID_GAMMA:
+ if ((ctrl->value = em28xx_gamma_get(dev)) < 0)
+ return -EIO;
+ return 0;
+ default:
+ return -EINVAL;
+ }
+}
+
+/*
+ * em28xx_set_ctrl()
+ * mute or set new saturation, brightness or contrast
+ */
+static int em28xx_set_ctrl(struct em28xx *dev, const struct v4l2_control *ctrl)
+{
+ switch (ctrl->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ if (ctrl->value != dev->mute) {
+ dev->mute = ctrl->value;
+ em28xx_audio_usb_mute(dev, ctrl->value);
+ return em28xx_audio_analog_set(dev);
+ }
+ return 0;
+ case V4L2_CID_AUDIO_VOLUME:
+ dev->volume = ctrl->value;
+ return em28xx_audio_analog_set(dev);
+ case V4L2_CID_BRIGHTNESS:
+ return em28xx_brightness_set(dev, ctrl->value);
+ case V4L2_CID_CONTRAST:
+ return em28xx_contrast_set(dev, ctrl->value);
+ case V4L2_CID_SATURATION:
+ return em28xx_saturation_set(dev, ctrl->value);
+ case V4L2_CID_RED_BALANCE:
+ return em28xx_v_balance_set(dev, ctrl->value);
+ case V4L2_CID_BLUE_BALANCE:
+ return em28xx_u_balance_set(dev, ctrl->value);
+ case V4L2_CID_GAMMA:
+ return em28xx_gamma_set(dev, ctrl->value);
+ default:
+ return -EINVAL;
+ }
+}
+
+/*
+ * em28xx_stream_interrupt()
+ * stops streaming
+ */
+static int em28xx_stream_interrupt(struct em28xx *dev)
+{
+ int ret = 0;
+
+ /* stop reading from the device */
+
+ dev->stream = STREAM_INTERRUPT;
+ ret = wait_event_timeout(dev->wait_stream,
+ (dev->stream == STREAM_OFF) ||
+ (dev->state & DEV_DISCONNECTED),
+ EM28XX_URB_TIMEOUT);
+ if (dev->state & DEV_DISCONNECTED)
+ return -ENODEV;
+ else if (ret) {
+ dev->state |= DEV_MISCONFIGURED;
+ em28xx_videodbg("device is misconfigured; close and "
+ "open /dev/video%d again\n", dev->vdev->minor);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int em28xx_set_norm(struct em28xx *dev, int width, int height)
+{
+ unsigned int hscale, vscale;
+ unsigned int maxh, maxw;
+
+ maxw = norm_maxw(dev);
+ maxh = norm_maxh(dev);
+
+ /* width must even because of the YUYV format */
+ /* height must be even because of interlacing */
+ height &= 0xfffe;
+ width &= 0xfffe;
+
+ if (height < 32)
+ height = 32;
+ if (height > maxh)
+ height = maxh;
+ if (width < 48)
+ width = 48;
+ if (width > maxw)
+ width = maxw;
+
+ if ((hscale = (((unsigned long)maxw) << 12) / width - 4096L) >= 0x4000)
+ hscale = 0x3fff;
+ width = (((unsigned long)maxw) << 12) / (hscale + 4096L);
+
+ if ((vscale = (((unsigned long)maxh) << 12) / height - 4096L) >= 0x4000)
+ vscale = 0x3fff;
+ height = (((unsigned long)maxh) << 12) / (vscale + 4096L);
+
+ /* set new image size */
+ dev->width = width;
+ dev->height = height;
+ dev->frame_size = dev->width * dev->height * 2;
+ dev->field_size = dev->frame_size >> 1; /*both_fileds ? dev->frame_size>>1 : dev->frame_size; */
+ dev->bytesperline = dev->width * 2;
+ dev->hscale = hscale;
+ dev->vscale = vscale;
+
+ em28xx_resolution_set(dev);
+
+ return 0;
+}
+
+/*
+ * em28xx_v4l2_do_ioctl()
+ * This function is _not_ called directly, but from
+ * em28xx_v4l2_ioctl. Userspace
+ * copying is done already, arg is a kernel pointer.
+ */
+static int em28xx_do_ioctl(struct inode *inode, struct file *filp,
+ struct em28xx *dev, unsigned int cmd, void *arg,
+ v4l2_kioctl driver_ioctl)
+{
+ int ret;
+
+ switch (cmd) {
+ /* ---------- tv norms ---------- */
+ case VIDIOC_ENUMSTD:
+ {
+ struct v4l2_standard *e = arg;
+ unsigned int i;
+
+ i = e->index;
+ if (i >= TVNORMS)
+ return -EINVAL;
+ ret = v4l2_video_std_construct(e, tvnorms[e->index].id,
+ tvnorms[e->index].name);
+ e->index = i;
+ if (ret < 0)
+ return ret;
+ return 0;
+ }
+ case VIDIOC_G_STD:
+ {
+ v4l2_std_id *id = arg;
+
+ *id = dev->tvnorm->id;
+ return 0;
+ }
+ case VIDIOC_S_STD:
+ {
+ v4l2_std_id *id = arg;
+ unsigned int i;
+
+ for (i = 0; i < TVNORMS; i++)
+ if (*id == tvnorms[i].id)
+ break;
+ if (i == TVNORMS)
+ for (i = 0; i < TVNORMS; i++)
+ if (*id & tvnorms[i].id)
+ break;
+ if (i == TVNORMS)
+ return -EINVAL;
+
+ down(&dev->lock);
+ dev->tvnorm = &tvnorms[i];
+
+ em28xx_set_norm(dev, dev->width, dev->height);
+
+/*
+ dev->width=norm_maxw(dev);
+ dev->height=norm_maxh(dev);
+ dev->frame_size=dev->width*dev->height*2;
+ dev->field_size=dev->frame_size>>1;
+ dev->bytesperline=dev->width*2;
+ dev->hscale=0;
+ dev->vscale=0;
+
+ em28xx_resolution_set(dev);
+*/
+/*
+ em28xx_uninit_isoc(dev);
+ em28xx_set_alternate(dev);
+ em28xx_capture_start(dev, 1);
+ em28xx_resolution_set(dev);
+ em28xx_init_isoc(dev);
+*/
+ em28xx_i2c_call_clients(dev, DECODER_SET_NORM,
+ &tvnorms[i].mode);
+ em28xx_i2c_call_clients(dev, VIDIOC_S_STD,
+ &dev->tvnorm->id);
+
+ up(&dev->lock);
+
+ return 0;
+ }
+
+ /* ------ input switching ---------- */
+ case VIDIOC_ENUMINPUT:
+ {
+ struct v4l2_input *i = arg;
+ unsigned int n;
+ static const char *iname[] = {
+ [EM28XX_VMUX_COMPOSITE1] = "Composite1",
+ [EM28XX_VMUX_COMPOSITE2] = "Composite2",
+ [EM28XX_VMUX_COMPOSITE3] = "Composite3",
+ [EM28XX_VMUX_COMPOSITE4] = "Composite4",
+ [EM28XX_VMUX_SVIDEO] = "S-Video",
+ [EM28XX_VMUX_TELEVISION] = "Television",
+ [EM28XX_VMUX_CABLE] = "Cable TV",
+ [EM28XX_VMUX_DVB] = "DVB",
+ [EM28XX_VMUX_DEBUG] = "for debug only",
+ };
+
+ n = i->index;
+ if (n >= MAX_EM28XX_INPUT)
+ return -EINVAL;
+ if (0 == INPUT(n)->type)
+ return -EINVAL;
+ memset(i, 0, sizeof(*i));
+ i->index = n;
+ i->type = V4L2_INPUT_TYPE_CAMERA;
+ strcpy(i->name, iname[INPUT(n)->type]);
+ if ((EM28XX_VMUX_TELEVISION == INPUT(n)->type) ||
+ (EM28XX_VMUX_CABLE == INPUT(n)->type))
+ i->type = V4L2_INPUT_TYPE_TUNER;
+ for (n = 0; n < ARRAY_SIZE(tvnorms); n++)
+ i->std |= tvnorms[n].id;
+ return 0;
+ }
+
+ case VIDIOC_G_INPUT:
+ {
+ int *i = arg;
+ *i = dev->ctl_input;
+
+ return 0;
+ }
+
+ case VIDIOC_S_INPUT:
+ {
+ int *index = arg;
+
+ if (*index >= MAX_EM28XX_INPUT)
+ return -EINVAL;
+ if (0 == INPUT(*index)->type)
+ return -EINVAL;
+
+ down(&dev->lock);
+ video_mux(dev, *index);
+ up(&dev->lock);
+
+ return 0;
+ }
+
+ case VIDIOC_G_AUDIO:
+ {
+ struct v4l2_audio *a = arg;
+ unsigned int index = a->index;
+
+ if (a->index > 1)
+ return -EINVAL;
+ memset(a, 0, sizeof(*a));
+ index = dev->ctl_ainput;
+
+ if (index == 0) {
+ strcpy(a->name, "Television");
+ } else {
+ strcpy(a->name, "Line In");
+ }
+ a->capability = V4L2_AUDCAP_STEREO;
+ a->index = index;
+ return 0;
+ }
+
+ case VIDIOC_S_AUDIO:
+ {
+ struct v4l2_audio *a = arg;
+ if (a->index != dev->ctl_ainput)
+ return -EINVAL;
+
+ return 0;
+ }
+
+ /* --- controls ---------------------------------------------- */
+ case VIDIOC_QUERYCTRL:
+ {
+ struct v4l2_queryctrl *qc = arg;
+ u8 i, n;
+ n = sizeof(em28xx_qctrl) / sizeof(em28xx_qctrl[0]);
+ for (i = 0; i < n; i++)
+ if (qc->id && qc->id == em28xx_qctrl[i].id) {
+ memcpy(qc, &(em28xx_qctrl[i]),
+ sizeof(*qc));
+ return 0;
+ }
+
+ return -EINVAL;
+ }
+
+ case VIDIOC_G_CTRL:
+ {
+ struct v4l2_control *ctrl = arg;
+
+
+ return em28xx_get_ctrl(dev, ctrl);
+ }
+
+ case VIDIOC_S_CTRL_OLD: /* ??? */
+ case VIDIOC_S_CTRL:
+ {
+ struct v4l2_control *ctrl = arg;
+ u8 i, n;
+
+
+ n = sizeof(em28xx_qctrl) / sizeof(em28xx_qctrl[0]);
+ for (i = 0; i < n; i++)
+ if (ctrl->id == em28xx_qctrl[i].id) {
+ if (ctrl->value <
+ em28xx_qctrl[i].minimum
+ || ctrl->value >
+ em28xx_qctrl[i].maximum)
+ return -ERANGE;
+
+ return em28xx_set_ctrl(dev, ctrl);
+ }
+ return -EINVAL;
+ }
+
+ /* --- tuner ioctls ------------------------------------------ */
+ case VIDIOC_G_TUNER:
+ {
+ struct v4l2_tuner *t = arg;
+ int status = 0;
+
+ if (0 != t->index)
+ return -EINVAL;
+
+ memset(t, 0, sizeof(*t));
+ strcpy(t->name, "Tuner");
+ t->type = V4L2_TUNER_ANALOG_TV;
+ t->capability = V4L2_TUNER_CAP_NORM;
+ t->rangehigh = 0xffffffffUL; /* FIXME: set correct range */
+/* t->signal = 0xffff;*/
+/* em28xx_i2c_call_clients(dev,VIDIOC_G_TUNER,t);*/
+ /* No way to get signal strength? */
+ down(&dev->lock);
+ em28xx_i2c_call_clients(dev, DECODER_GET_STATUS,
+ &status);
+ up(&dev->lock);
+ t->signal =
+ (status & DECODER_STATUS_GOOD) != 0 ? 0xffff : 0;
+
+ em28xx_videodbg("VIDIO_G_TUNER: signal=%x, afc=%x\n", t->signal,
+ t->afc);
+ return 0;
+ }
+ case VIDIOC_S_TUNER:
+ {
+ struct v4l2_tuner *t = arg;
+ int status = 0;
+
+ if (0 != t->index)
+ return -EINVAL;
+ memset(t, 0, sizeof(*t));
+ strcpy(t->name, "Tuner");
+ t->type = V4L2_TUNER_ANALOG_TV;
+ t->capability = V4L2_TUNER_CAP_NORM;
+ t->rangehigh = 0xffffffffUL; /* FIXME: set correct range */
+/* t->signal = 0xffff; */
+ /* No way to get signal strength? */
+ down(&dev->lock);
+ em28xx_i2c_call_clients(dev, DECODER_GET_STATUS,
+ &status);
+ up(&dev->lock);
+ t->signal =
+ (status & DECODER_STATUS_GOOD) != 0 ? 0xffff : 0;
+
+ em28xx_videodbg("VIDIO_S_TUNER: signal=%x, afc=%x\n",
+ t->signal, t->afc);
+ return 0;
+ }
+ case VIDIOC_G_FREQUENCY:
+ {
+ struct v4l2_frequency *f = arg;
+
+ memset(f, 0, sizeof(*f));
+ f->type = V4L2_TUNER_ANALOG_TV;
+ f->frequency = dev->ctl_freq;
+
+ return 0;
+ }
+ case VIDIOC_S_FREQUENCY:
+ {
+ struct v4l2_frequency *f = arg;
+
+ if (0 != f->tuner)
+ return -EINVAL;
+
+ if (V4L2_TUNER_ANALOG_TV != f->type)
+ return -EINVAL;
+
+ down(&dev->lock);
+ dev->ctl_freq = f->frequency;
+ em28xx_i2c_call_clients(dev, VIDIOC_S_FREQUENCY, f);
+ up(&dev->lock);
+ return 0;
+ }
+
+ case VIDIOC_CROPCAP:
+ {
+ struct v4l2_cropcap *cc = arg;
+
+ if (cc->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ return -EINVAL;
+ cc->bounds.left = 0;
+ cc->bounds.top = 0;
+ cc->bounds.width = dev->width;
+ cc->bounds.height = dev->height;
+ cc->defrect = cc->bounds;
+ cc->pixelaspect.numerator = 54; /* 4:3 FIXME: remove magic numbers */
+ cc->pixelaspect.denominator = 59;
+ return 0;
+ }
+ case VIDIOC_STREAMON:
+ {
+ int *type = arg;
+
+ if (*type != V4L2_BUF_TYPE_VIDEO_CAPTURE
+ || dev->io != IO_MMAP)
+ return -EINVAL;
+
+ if (list_empty(&dev->inqueue))
+ return -EINVAL;
+
+ dev->stream = STREAM_ON; /* FIXME: Start video capture here? */
+
+ em28xx_videodbg("VIDIOC_STREAMON: starting stream\n");
+
+ return 0;
+ }
+ case VIDIOC_STREAMOFF:
+ {
+ int *type = arg;
+ int ret;
+
+ if (*type != V4L2_BUF_TYPE_VIDEO_CAPTURE
+ || dev->io != IO_MMAP)
+ return -EINVAL;
+
+ if (dev->stream == STREAM_ON) {
+ em28xx_videodbg ("VIDIOC_STREAMOFF: interrupting stream\n");
+ if ((ret = em28xx_stream_interrupt(dev)))
+ return ret;
+ }
+ em28xx_empty_framequeues(dev);
+
+ return 0;
+ }
+ default:
+ return v4l_compat_translate_ioctl(inode, filp, cmd, arg,
+ driver_ioctl);
+ }
+ return 0;
+}
+
+/*
+ * em28xx_v4l2_do_ioctl()
+ * This function is _not_ called directly, but from
+ * em28xx_v4l2_ioctl. Userspace
+ * copying is done already, arg is a kernel pointer.
+ */
+static int em28xx_video_do_ioctl(struct inode *inode, struct file *filp,
+ unsigned int cmd, void *arg)
+{
+ struct em28xx *dev = filp->private_data;
+
+ if (!dev)
+ return -ENODEV;
+
+ if (video_debug > 1)
+ em28xx_print_ioctl(dev->name,cmd);
+
+ switch (cmd) {
+
+ /* --- capabilities ------------------------------------------ */
+ case VIDIOC_QUERYCAP:
+ {
+ struct v4l2_capability *cap = arg;
+
+ memset(cap, 0, sizeof(*cap));
+ strlcpy(cap->driver, "em28xx", sizeof(cap->driver));
+ strlcpy(cap->card, em28xx_boards[dev->model].name,
+ sizeof(cap->card));
+ strlcpy(cap->bus_info, dev->udev->dev.bus_id,
+ sizeof(cap->bus_info));
+ cap->version = EM28XX_VERSION_CODE;
+ cap->capabilities =
+ V4L2_CAP_VIDEO_CAPTURE |
+ V4L2_CAP_AUDIO |
+ V4L2_CAP_READWRITE | V4L2_CAP_STREAMING;
+ if (dev->has_tuner)
+ cap->capabilities |= V4L2_CAP_TUNER;
+ return 0;
+ }
+
+ /* --- capture ioctls ---------------------------------------- */
+ case VIDIOC_ENUM_FMT:
+ {
+ struct v4l2_fmtdesc *fmtd = arg;
+
+ if (fmtd->index != 0)
+ return -EINVAL;
+ memset(fmtd, 0, sizeof(*fmtd));
+ fmtd->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ strcpy(fmtd->description, "Packed YUY2");
+ fmtd->pixelformat = V4L2_PIX_FMT_YUYV;
+ memset(fmtd->reserved, 0, sizeof(fmtd->reserved));
+ return 0;
+ }
+
+ case VIDIOC_G_FMT:
+ {
+ struct v4l2_format *format = arg;
+
+ em28xx_videodbg("VIDIOC_G_FMT: type=%s\n",
+ format->type ==
+ V4L2_BUF_TYPE_VIDEO_CAPTURE ?
+ "V4L2_BUF_TYPE_VIDEO_CAPTURE" : format->type ==
+ V4L2_BUF_TYPE_VBI_CAPTURE ?
+ "V4L2_BUF_TYPE_VBI_CAPTURE " :
+ "not supported");
+
+ if (format->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ return -EINVAL;
+
+ format->fmt.pix.width = dev->width;
+ format->fmt.pix.height = dev->height;
+ format->fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
+ format->fmt.pix.bytesperline = dev->bytesperline;
+ format->fmt.pix.sizeimage = dev->frame_size;
+ format->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
+ format->fmt.pix.field = dev->interlaced ? V4L2_FIELD_INTERLACED : V4L2_FIELD_TOP; /* FIXME: TOP? NONE? BOTTOM? ALTENATE? */
+
+ em28xx_videodbg("VIDIOC_G_FMT: %dx%d\n", dev->width,
+ dev->height);
+ return 0;
+ }
+
+ case VIDIOC_TRY_FMT:
+ case VIDIOC_S_FMT:
+ {
+ struct v4l2_format *format = arg;
+ u32 i;
+ int ret = 0;
+ int width = format->fmt.pix.width;
+ int height = format->fmt.pix.height;
+ unsigned int hscale, vscale;
+ unsigned int maxh, maxw;
+
+ maxw = norm_maxw(dev);
+ maxh = norm_maxh(dev);
+
+/* int both_fields; */
+
+ em28xx_videodbg("%s: type=%s\n",
+ cmd ==
+ VIDIOC_TRY_FMT ? "VIDIOC_TRY_FMT" :
+ "VIDIOC_S_FMT",
+ format->type ==
+ V4L2_BUF_TYPE_VIDEO_CAPTURE ?
+ "V4L2_BUF_TYPE_VIDEO_CAPTURE" : format->type ==
+ V4L2_BUF_TYPE_VBI_CAPTURE ?
+ "V4L2_BUF_TYPE_VBI_CAPTURE " :
+ "not supported");
+
+ if (format->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ return -EINVAL;
+
+ em28xx_videodbg("%s: requested %dx%d\n",
+ cmd ==
+ VIDIOC_TRY_FMT ? "VIDIOC_TRY_FMT" :
+ "VIDIOC_S_FMT", format->fmt.pix.width,
+ format->fmt.pix.height);
+
+ /* FIXME: Move some code away from here */
+ /* width must even because of the YUYV format */
+ /* height must be even because of interlacing */
+ height &= 0xfffe;
+ width &= 0xfffe;
+
+ if (height < 32)
+ height = 32;
+ if (height > maxh)
+ height = maxh;
+ if (width < 48)
+ width = 48;
+ if (width > maxw)
+ width = maxw;
+
+ if(dev->is_em2800){
+ /* the em2800 can only scale down to 50% */
+ if(height % (maxh / 2))
+ height=maxh;
+ if(width % (maxw / 2))
+ width=maxw;
+ /* according to empiatech support */
+ /* the MaxPacketSize is to small to support */
+ /* framesizes larger than 640x480 @ 30 fps */
+ /* or 640x576 @ 25 fps. As this would cut */
+ /* of a part of the image we prefer */
+ /* 360x576 or 360x480 for now */
+ if(width == maxw && height == maxh)
+ width /= 2;
+ }
+
+ if ((hscale =
+ (((unsigned long)maxw) << 12) / width - 4096L) >=
+ 0x4000)
+ hscale = 0x3fff;
+ width =
+ (((unsigned long)maxw) << 12) / (hscale + 4096L);
+
+ if ((vscale =
+ (((unsigned long)maxh) << 12) / height - 4096L) >=
+ 0x4000)
+ vscale = 0x3fff;
+ height =
+ (((unsigned long)maxh) << 12) / (vscale + 4096L);
+
+ format->fmt.pix.width = width;
+ format->fmt.pix.height = height;
+ format->fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
+ format->fmt.pix.bytesperline = width * 2;
+ format->fmt.pix.sizeimage = width * 2 * height;
+ format->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
+ format->fmt.pix.field = V4L2_FIELD_INTERLACED;
+
+ em28xx_videodbg("%s: returned %dx%d (%d, %d)\n",
+ cmd ==
+ VIDIOC_TRY_FMT ? "VIDIOC_TRY_FMT" :
+ "VIDIOC_S_FMT", format->fmt.pix.width,
+ format->fmt.pix.height, hscale, vscale);
+
+ if (cmd == VIDIOC_TRY_FMT)
+ return 0;
+
+ for (i = 0; i < dev->num_frames; i++)
+ if (dev->frame[i].vma_use_count) {
+ em28xx_videodbg("VIDIOC_S_FMT failed. "
+ "Unmap the buffers first.\n");
+ return -EINVAL;
+ }
+
+ /* stop io in case it is already in progress */
+ if (dev->stream == STREAM_ON) {
+ em28xx_videodbg("VIDIOC_SET_FMT: interupting stream\n");
+ if ((ret = em28xx_stream_interrupt(dev)))
+ return ret;
+ }
+
+ em28xx_release_buffers(dev);
+ dev->io = IO_NONE;
+
+ /* set new image size */
+ dev->width = width;
+ dev->height = height;
+ dev->frame_size = dev->width * dev->height * 2;
+ dev->field_size = dev->frame_size >> 1; /*both_fileds ? dev->frame_size>>1 : dev->frame_size; */
+ dev->bytesperline = dev->width * 2;
+ dev->hscale = hscale;
+ dev->vscale = vscale;
+/* dev->both_fileds = both_fileds; */
+ em28xx_uninit_isoc(dev);
+ em28xx_set_alternate(dev);
+ em28xx_capture_start(dev, 1);
+ em28xx_resolution_set(dev);
+ em28xx_init_isoc(dev);
+
+ return 0;
+ }
+
+ /* --- streaming capture ------------------------------------- */
+ case VIDIOC_REQBUFS:
+ {
+ struct v4l2_requestbuffers *rb = arg;
+ u32 i;
+ int ret;
+
+ if (rb->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
+ rb->memory != V4L2_MEMORY_MMAP)
+ return -EINVAL;
+
+ if (dev->io == IO_READ) {
+ em28xx_videodbg ("method is set to read;"
+ " close and open the device again to"
+ " choose the mmap I/O method\n");
+ return -EINVAL;
+ }
+
+ for (i = 0; i < dev->num_frames; i++)
+ if (dev->frame[i].vma_use_count) {
+ em28xx_videodbg ("VIDIOC_REQBUFS failed; previous buffers are still mapped\n");
+ return -EINVAL;
+ }
+
+ if (dev->stream == STREAM_ON) {
+ em28xx_videodbg("VIDIOC_REQBUFS: interrupting stream\n");
+ if ((ret = em28xx_stream_interrupt(dev)))
+ return ret;
+ }
+
+ em28xx_empty_framequeues(dev);
+
+ em28xx_release_buffers(dev);
+ if (rb->count)
+ rb->count =
+ em28xx_request_buffers(dev, rb->count);
+
+ dev->frame_current = NULL;
+
+ em28xx_videodbg ("VIDIOC_REQBUFS: setting io method to mmap: num bufs %i\n",
+ rb->count);
+ dev->io = rb->count ? IO_MMAP : IO_NONE;
+ return 0;
+ }
+
+ case VIDIOC_QUERYBUF:
+ {
+ struct v4l2_buffer *b = arg;
+
+ if (b->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
+ b->index >= dev->num_frames || dev->io != IO_MMAP)
+ return -EINVAL;
+
+ memcpy(b, &dev->frame[b->index].buf, sizeof(*b));
+
+ if (dev->frame[b->index].vma_use_count) {
+ b->flags |= V4L2_BUF_FLAG_MAPPED;
+ }
+ if (dev->frame[b->index].state == F_DONE)
+ b->flags |= V4L2_BUF_FLAG_DONE;
+ else if (dev->frame[b->index].state != F_UNUSED)
+ b->flags |= V4L2_BUF_FLAG_QUEUED;
+ return 0;
+ }
+ case VIDIOC_QBUF:
+ {
+ struct v4l2_buffer *b = arg;
+ unsigned long lock_flags;
+
+ if (b->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
+ b->index >= dev->num_frames || dev->io != IO_MMAP) {
+ return -EINVAL;
+ }
+
+ if (dev->frame[b->index].state != F_UNUSED) {
+ return -EAGAIN;
+ }
+ dev->frame[b->index].state = F_QUEUED;
+
+ /* add frame to fifo */
+ spin_lock_irqsave(&dev->queue_lock, lock_flags);
+ list_add_tail(&dev->frame[b->index].frame,
+ &dev->inqueue);
+ spin_unlock_irqrestore(&dev->queue_lock, lock_flags);
+
+ return 0;
+ }
+ case VIDIOC_DQBUF:
+ {
+ struct v4l2_buffer *b = arg;
+ struct em28xx_frame_t *f;
+ unsigned long lock_flags;
+ int ret = 0;
+
+ if (b->type != V4L2_BUF_TYPE_VIDEO_CAPTURE
+ || dev->io != IO_MMAP)
+ return -EINVAL;
+
+ if (list_empty(&dev->outqueue)) {
+ if (dev->stream == STREAM_OFF)
+ return -EINVAL;
+ if (filp->f_flags & O_NONBLOCK)
+ return -EAGAIN;
+ ret = wait_event_interruptible
+ (dev->wait_frame,
+ (!list_empty(&dev->outqueue)) ||
+ (dev->state & DEV_DISCONNECTED));
+ if (ret)
+ return ret;
+ if (dev->state & DEV_DISCONNECTED)
+ return -ENODEV;
+ }
+
+ spin_lock_irqsave(&dev->queue_lock, lock_flags);
+ f = list_entry(dev->outqueue.next,
+ struct em28xx_frame_t, frame);
+ list_del(dev->outqueue.next);
+ spin_unlock_irqrestore(&dev->queue_lock, lock_flags);
+
+ f->state = F_UNUSED;
+ memcpy(b, &f->buf, sizeof(*b));
+
+ if (f->vma_use_count)
+ b->flags |= V4L2_BUF_FLAG_MAPPED;
+
+ return 0;
+ }
+ default:
+ return em28xx_do_ioctl(inode, filp, dev, cmd, arg,
+ em28xx_video_do_ioctl);
+ }
+ return 0;
+}
+
+/*
+ * em28xx_v4l2_ioctl()
+ * handle v4l2 ioctl the main action happens in em28xx_v4l2_do_ioctl()
+ */
+static int em28xx_v4l2_ioctl(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg)
+{
+ int ret = 0;
+ struct em28xx *dev = filp->private_data;
+
+ if (down_interruptible(&dev->fileop_lock))
+ return -ERESTARTSYS;
+
+ if (dev->state & DEV_DISCONNECTED) {
+ em28xx_errdev("v4l2 ioctl: device not present\n");
+ up(&dev->fileop_lock);
+ return -ENODEV;
+ }
+
+ if (dev->state & DEV_MISCONFIGURED) {
+ em28xx_errdev
+ ("v4l2 ioctl: device is misconfigured; close and open it again\n");
+ up(&dev->fileop_lock);
+ return -EIO;
+ }
+
+ ret = video_usercopy(inode, filp, cmd, arg, em28xx_video_do_ioctl);
+
+ up(&dev->fileop_lock);
+
+ return ret;
+}
+
+static struct file_operations em28xx_v4l_fops = {
+ .owner = THIS_MODULE,
+ .open = em28xx_v4l2_open,
+ .release = em28xx_v4l2_close,
+ .ioctl = em28xx_v4l2_ioctl,
+ .read = em28xx_v4l2_read,
+ .poll = em28xx_v4l2_poll,
+ .mmap = em28xx_v4l2_mmap,
+ .llseek = no_llseek,
+};
+
+/******************************** usb interface *****************************************/
+
+/*
+ * em28xx_init_dev()
+ * allocates and inits the device structs, registers i2c bus and v4l device
+ */
+static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
+ int minor, int model)
+{
+ struct em28xx *dev = *devhandle;
+ int retval = -ENOMEM;
+ int errCode, i;
+ unsigned int maxh, maxw;
+
+ dev->udev = udev;
+ dev->model = model;
+ init_MUTEX(&dev->lock);
+ init_waitqueue_head(&dev->open);
+
+ dev->em28xx_write_regs = em28xx_write_regs;
+ dev->em28xx_read_reg = em28xx_read_reg;
+ dev->em28xx_read_reg_req_len = em28xx_read_reg_req_len;
+ dev->em28xx_write_regs_req = em28xx_write_regs_req;
+ dev->em28xx_read_reg_req = em28xx_read_reg_req;
+ dev->is_em2800 = em28xx_boards[model].is_em2800;
+ dev->has_tuner = em28xx_boards[model].has_tuner;
+ dev->has_msp34xx = em28xx_boards[model].has_msp34xx;
+ dev->tda9887_conf = em28xx_boards[model].tda9887_conf;
+ dev->decoder = em28xx_boards[model].decoder;
+
+ if (tuner >= 0)
+ dev->tuner_type = tuner;
+ else
+ dev->tuner_type = em28xx_boards[model].tuner_type;
+
+ dev->video_inputs = em28xx_boards[model].vchannels;
+
+ for (i = 0; i < TVNORMS; i++)
+ if (em28xx_boards[model].norm == tvnorms[i].mode)
+ break;
+ if (i == TVNORMS)
+ i = 0;
+
+ dev->tvnorm = &tvnorms[i]; /* set default norm */
+
+ em28xx_videodbg("tvnorm=%s\n", dev->tvnorm->name);
+
+ maxw = norm_maxw(dev);
+ maxh = norm_maxh(dev);
+
+ /* set default image size */
+ dev->width = maxw;
+ dev->height = maxh;
+ dev->interlaced = EM28XX_INTERLACED_DEFAULT;
+ dev->field_size = dev->width * dev->height;
+ dev->frame_size =
+ dev->interlaced ? dev->field_size << 1 : dev->field_size;
+ dev->bytesperline = dev->width * 2;
+ dev->hscale = 0;
+ dev->vscale = 0;
+ dev->ctl_input = 2;
+
+ /* setup video picture settings for saa7113h */
+ memset(&dev->vpic, 0, sizeof(dev->vpic));
+ dev->vpic.colour = 128 << 8;
+ dev->vpic.hue = 128 << 8;
+ dev->vpic.brightness = 128 << 8;
+ dev->vpic.contrast = 192 << 8;
+ dev->vpic.whiteness = 128 << 8; /* This one isn't used */
+ dev->vpic.depth = 16;
+ dev->vpic.palette = VIDEO_PALETTE_YUV422;
+
+#ifdef CONFIG_MODULES
+ /* request some modules */
+ if (dev->decoder == EM28XX_SAA7113 || dev->decoder == EM28XX_SAA7114)
+ request_module("saa711x");
+ if (dev->decoder == EM28XX_TVP5150)
+ request_module("tvp5150");
+ if (dev->has_tuner)
+ request_module("tuner");
+ if (dev->tda9887_conf)
+ request_module("tda9887");
+#endif
+ errCode = em28xx_config(dev);
+ if (errCode) {
+ em28xx_errdev("error configuring device\n");
+ kfree(dev);
+ return -ENOMEM;
+ }
+
+ down(&dev->lock);
+ /* register i2c bus */
+ em28xx_i2c_register(dev);
+
+ /* Do board specific init and eeprom reading */
+ em28xx_card_setup(dev);
+
+ /* configure the device */
+ em28xx_config_i2c(dev);
+
+ up(&dev->lock);
+
+ errCode = em28xx_config(dev);
+
+#ifdef CONFIG_MODULES
+ if (dev->has_msp34xx)
+ request_module("msp3400");
+#endif
+ /* allocate and fill v4l2 device struct */
+ dev->vdev = video_device_alloc();
+ if (NULL == dev->vdev) {
+ em28xx_errdev("cannot allocate video_device.\n");
+ kfree(dev);
+ return -ENOMEM;
+ }
+
+ dev->vdev->type = VID_TYPE_CAPTURE;
+ if (dev->has_tuner)
+ dev->vdev->type |= VID_TYPE_TUNER;
+ dev->vdev->hardware = 0;
+ dev->vdev->fops = &em28xx_v4l_fops;
+ dev->vdev->minor = -1;
+ dev->vdev->dev = &dev->udev->dev;
+ dev->vdev->release = video_device_release;
+ snprintf(dev->vdev->name, sizeof(dev->vdev->name), "%s",
+ "em28xx video");
+ list_add_tail(&dev->devlist,&em28xx_devlist);
+
+ /* register v4l2 device */
+ down(&dev->lock);
+ if ((retval = video_register_device(dev->vdev, VFL_TYPE_GRABBER, -1))) {
+ em28xx_errdev("unable to register video device (error=%i).\n",
+ retval);
+ up(&dev->lock);
+ list_del(&dev->devlist);
+ video_device_release(dev->vdev);
+ kfree(dev);
+ return -ENODEV;
+ }
+ if (dev->has_msp34xx) {
+ /* Send a reset to other chips via gpio */
+ em28xx_write_regs_req(dev, 0x00, 0x08, "\xf7", 1);
+ udelay(2500);
+ em28xx_write_regs_req(dev, 0x00, 0x08, "\xff", 1);
+ udelay(2500);
+
+ }
+ video_mux(dev, 0);
+
+ up(&dev->lock);
+
+ em28xx_info("V4L2 device registered as /dev/video%d\n",
+ dev->vdev->minor);
+
+ return 0;
+}
+
+/*
+ * em28xx_usb_probe()
+ * checks for supported devices
+ */
+static int em28xx_usb_probe(struct usb_interface *interface,
+ const struct usb_device_id *id)
+{
+ const struct usb_endpoint_descriptor *endpoint;
+ struct usb_device *udev;
+ struct usb_interface *uif;
+ struct em28xx *dev = NULL;
+ int retval = -ENODEV;
+ int model,i,nr,ifnum;
+
+ udev = usb_get_dev(interface_to_usbdev(interface));
+ ifnum = interface->altsetting[0].desc.bInterfaceNumber;
+
+
+ /* Don't register audio interfaces */
+ if (interface->altsetting[0].desc.bInterfaceClass == USB_CLASS_AUDIO) {
+ em28xx_err(DRIVER_NAME " audio device (%04x:%04x): interface %i, class %i\n",
+ udev->descriptor.idVendor,udev->descriptor.idProduct,
+ ifnum,
+ interface->altsetting[0].desc.bInterfaceClass);
+ return -ENODEV;
+ }
+
+ em28xx_err(DRIVER_NAME " new video device (%04x:%04x): interface %i, class %i\n",
+ udev->descriptor.idVendor,udev->descriptor.idProduct,
+ ifnum,
+ interface->altsetting[0].desc.bInterfaceClass);
+
+ endpoint = &interface->cur_altsetting->endpoint[1].desc;
+
+ /* check if the the device has the iso in endpoint at the correct place */
+ if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) !=
+ USB_ENDPOINT_XFER_ISOC) {
+ em28xx_err(DRIVER_NAME " probing error: endpoint is non-ISO endpoint!\n");
+ return -ENODEV;
+ }
+ if ((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT) {
+ em28xx_err(DRIVER_NAME " probing error: endpoint is ISO OUT endpoint!\n");
+ return -ENODEV;
+ }
+
+ model=id->driver_info;
+ nr=interface->minor;
+
+ if (nr>EM28XX_MAXBOARDS) {
+ printk (DRIVER_NAME ": Supports only %i em28xx boards.\n",EM28XX_MAXBOARDS);
+ return -ENOMEM;
+ }
+
+ /* allocate memory for our device state and initialize it */
+ dev = kmalloc(sizeof(*dev), GFP_KERNEL);
+ if (dev == NULL) {
+ em28xx_err(DRIVER_NAME ": out of memory!\n");
+ return -ENOMEM;
+ }
+ memset(dev, 0, sizeof(*dev));
+
+ /* compute alternate max packet sizes */
+ uif = udev->actconfig->interface[0];
+
+ dev->num_alt=uif->num_altsetting;
+ printk(DRIVER_NAME ": Alternate settings: %i\n",dev->num_alt);
+// dev->alt_max_pkt_size = kmalloc(sizeof(*dev->alt_max_pkt_size)*
+ dev->alt_max_pkt_size = kmalloc(32*
+ dev->num_alt,GFP_KERNEL);
+ if (dev->alt_max_pkt_size == NULL) {
+ em28xx_err(DRIVER_NAME ": out of memory!\n");
+ return -ENOMEM;
+ }
+
+ for (i = 0; i < dev->num_alt ; i++) {
+ u16 tmp = le16_to_cpu(uif->altsetting[i].endpoint[1].desc.
+ wMaxPacketSize);
+ dev->alt_max_pkt_size[i] =
+ (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1);
+ printk(DRIVER_NAME ": Alternate setting %i, max size= %i\n",i,
+ dev->alt_max_pkt_size[i]);
+ }
+
+ snprintf(dev->name, 29, "em28xx #%d", nr);
+
+ if ((card[nr]>=0)&&(card[nr]<em28xx_bcount))
+ model=card[nr];
+
+ if ((model==EM2800_BOARD_UNKNOWN)||(model==EM2820_BOARD_UNKNOWN)) {
+ printk( "%s: Your board has no eeprom inside it and thus can't\n"
+ "%s: be autodetected. Please pass card=<n> insmod option to\n"
+ "%s: workaround that. Redirect complaints to the vendor of\n"
+ "%s: the TV card. Best regards,\n"
+ "%s: -- tux\n",
+ dev->name,dev->name,dev->name,dev->name,dev->name);
+ printk("%s: Here is a list of valid choices for the card=<n> insmod option:\n",
+ dev->name);
+ for (i = 0; i < em28xx_bcount; i++) {
+ printk("%s: card=%d -> %s\n",
+ dev->name, i, em28xx_boards[i].name);
+ }
+ }
+
+ /* allocate device struct */
+ retval = em28xx_init_dev(&dev, udev, nr, model);
+ if (retval)
+ return retval;
+
+ em28xx_info("Found %s\n", em28xx_boards[model].name);
+
+ /* save our data pointer in this interface device */
+ usb_set_intfdata(interface, dev);
+ return 0;
+}
+
+/*
+ * em28xx_usb_disconnect()
+ * called when the device gets diconencted
+ * video device will be unregistered on v4l2_close in case it is still open
+ */
+static void em28xx_usb_disconnect(struct usb_interface *interface)
+{
+ struct em28xx *dev = usb_get_intfdata(interface);
+ usb_set_intfdata(interface, NULL);
+
+ if (!dev)
+ return;
+
+ down_write(&em28xx_disconnect);
+
+ down(&dev->lock);
+
+ em28xx_info("disconnecting %s\n", dev->vdev->name);
+
+ wake_up_interruptible_all(&dev->open);
+
+ if (dev->users) {
+ em28xx_warn
+ ("device /dev/video%d is open! Deregistration and memory "
+ "deallocation are deferred on close.\n", dev->vdev->minor);
+ dev->state |= DEV_MISCONFIGURED;
+ em28xx_uninit_isoc(dev);
+ dev->state |= DEV_DISCONNECTED;
+ wake_up_interruptible(&dev->wait_frame);
+ wake_up_interruptible(&dev->wait_stream);
+ } else {
+ dev->state |= DEV_DISCONNECTED;
+ em28xx_release_resources(dev);
+ }
+
+ up(&dev->lock);
+
+ if (!dev->users) {
+ kfree(dev->alt_max_pkt_size);
+ kfree(dev);
+ }
+
+ up_write(&em28xx_disconnect);
+}
+
+static struct usb_driver em28xx_usb_driver = {
+ .owner = THIS_MODULE,
+ .name = "em28xx",
+ .probe = em28xx_usb_probe,
+ .disconnect = em28xx_usb_disconnect,
+ .id_table = em28xx_id_table,
+};
+
+static int __init em28xx_module_init(void)
+{
+ int result;
+
+ printk(KERN_INFO DRIVER_NAME " v4l2 driver version %d.%d.%d loaded\n",
+ (EM28XX_VERSION_CODE >> 16) & 0xff,
+ (EM28XX_VERSION_CODE >> 8) & 0xff, EM28XX_VERSION_CODE & 0xff);
+#ifdef SNAPSHOT
+ printk(KERN_INFO DRIVER_NAME " snapshot date %04d-%02d-%02d\n",
+ SNAPSHOT / 10000, (SNAPSHOT / 100) % 100, SNAPSHOT % 100);
+#endif
+
+ /* register this driver with the USB subsystem */
+ result = usb_register(&em28xx_usb_driver);
+ if (result)
+ em28xx_err(DRIVER_NAME
+ " usb_register failed. Error number %d.\n", result);
+
+ return result;
+}
+
+static void __exit em28xx_module_exit(void)
+{
+ /* deregister this driver with the USB subsystem */
+ usb_deregister(&em28xx_usb_driver);
+}
+
+module_init(em28xx_module_init);
+module_exit(em28xx_module_exit);
diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h
new file mode 100644
index 000000000000..5c7a41ce69f3
--- /dev/null
+++ b/drivers/media/video/em28xx/em28xx.h
@@ -0,0 +1,513 @@
+/*
+ em28xx-cards.c - driver for Empia EM2800/EM2820/2840 USB video capture devices
+
+ Copyright (C) 2005 Markus Rechberger <mrechberger@gmail.com>
+ Ludovico Cavedon <cavedon@sssup.it>
+ Mauro Carvalho Chehab <mchehab@brturbo.com.br>
+
+ Based on the em2800 driver from Sascha Sommer <saschasommer@freenet.de>
+
+ 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 _EM28XX_H
+#define _EM28XX_H
+
+#include <linux/videodev.h>
+#include <linux/i2c.h>
+#include <media/ir-kbd-i2c.h>
+
+/* Boards supported by driver */
+
+#define EM2800_BOARD_UNKNOWN 0
+#define EM2820_BOARD_UNKNOWN 1
+#define EM2820_BOARD_TERRATEC_CINERGY_250 2
+#define EM2820_BOARD_PINNACLE_USB_2 3
+#define EM2820_BOARD_HAUPPAUGE_WINTV_USB_2 4
+#define EM2820_BOARD_MSI_VOX_USB_2 5
+#define EM2800_BOARD_TERRATEC_CINERGY_200 6
+#define EM2800_BOARD_LEADTEK_WINFAST_USBII 7
+#define EM2800_BOARD_KWORLD_USB2800 8
+#define EM2820_BOARD_PINNACLE_DVC_90 9
+
+#define UNSET -1
+
+/* maximum number of em28xx boards */
+#define EM28XX_MAXBOARDS 1 /*FIXME: should be bigger */
+
+/* maximum number of frames that can be queued */
+#define EM28XX_NUM_FRAMES 5
+/* number of frames that get used for v4l2_read() */
+#define EM28XX_NUM_READ_FRAMES 2
+
+/* number of buffers for isoc transfers */
+#define EM28XX_NUM_BUFS 5
+
+/* number of packets for each buffer
+ windows requests only 40 packets .. so we better do the same
+ this is what I found out for all alternate numbers there!
+ */
+#define EM28XX_NUM_PACKETS 40
+
+/* default alternate; 0 means choose the best */
+#define EM28XX_PINOUT 0
+
+#define EM28XX_INTERLACED_DEFAULT 1
+
+/*
+#define (use usbview if you want to get the other alternate number infos)
+#define
+#define alternate number 2
+#define Endpoint Address: 82
+ Direction: in
+ Attribute: 1
+ Type: Isoc
+ Max Packet Size: 1448
+ Interval: 125us
+
+ alternate number 7
+
+ Endpoint Address: 82
+ Direction: in
+ Attribute: 1
+ Type: Isoc
+ Max Packet Size: 3072
+ Interval: 125us
+*/
+
+/* time to wait when stopping the isoc transfer */
+#define EM28XX_URB_TIMEOUT msecs_to_jiffies(EM28XX_NUM_BUFS * EM28XX_NUM_PACKETS)
+
+/* time in msecs to wait for i2c writes to finish */
+#define EM2800_I2C_WRITE_TIMEOUT 20
+
+/* the various frame states */
+enum em28xx_frame_state {
+ F_UNUSED = 0,
+ F_QUEUED,
+ F_GRABBING,
+ F_DONE,
+ F_ERROR,
+};
+
+/* stream states */
+enum em28xx_stream_state {
+ STREAM_OFF,
+ STREAM_INTERRUPT,
+ STREAM_ON,
+};
+
+/* frames */
+struct em28xx_frame_t {
+ void *bufmem;
+ struct v4l2_buffer buf;
+ enum em28xx_frame_state state;
+ struct list_head frame;
+ unsigned long vma_use_count;
+ int top_field;
+ int fieldbytesused;
+};
+
+/* io methods */
+enum em28xx_io_method {
+ IO_NONE,
+ IO_READ,
+ IO_MMAP,
+};
+
+/* inputs */
+
+#define MAX_EM28XX_INPUT 4
+enum enum28xx_itype {
+ EM28XX_VMUX_COMPOSITE1 = 1,
+ EM28XX_VMUX_COMPOSITE2,
+ EM28XX_VMUX_COMPOSITE3,
+ EM28XX_VMUX_COMPOSITE4,
+ EM28XX_VMUX_SVIDEO,
+ EM28XX_VMUX_TELEVISION,
+ EM28XX_VMUX_CABLE,
+ EM28XX_VMUX_DVB,
+ EM28XX_VMUX_DEBUG,
+ EM28XX_RADIO,
+};
+
+struct em28xx_input {
+ enum enum28xx_itype type;
+ unsigned int vmux;
+ unsigned int amux;
+};
+
+#define INPUT(nr) (&em28xx_boards[dev->model].input[nr])
+
+enum em28xx_decoder {
+ EM28XX_TVP5150,
+ EM28XX_SAA7113,
+ EM28XX_SAA7114
+};
+
+struct em28xx_board {
+ char *name;
+ int vchannels;
+ int norm;
+ int tuner_type;
+
+ /* i2c flags */
+ unsigned int is_em2800;
+ unsigned int tda9887_conf;
+
+ unsigned int has_tuner:1;
+ unsigned int has_msp34xx:1;
+
+ enum em28xx_decoder decoder;
+
+ struct em28xx_input input[MAX_EM28XX_INPUT];
+};
+
+struct em28xx_eeprom {
+ u32 id; /* 0x9567eb1a */
+ u16 vendor_ID;
+ u16 product_ID;
+
+ u16 chip_conf;
+
+ u16 board_conf;
+
+ u16 string1, string2, string3;
+
+ u8 string_idx_table;
+};
+
+/* device states */
+enum em28xx_dev_state {
+ DEV_INITIALIZED = 0x01,
+ DEV_DISCONNECTED = 0x02,
+ DEV_MISCONFIGURED = 0x04,
+};
+
+/* tvnorms */
+struct em28xx_tvnorm {
+ char *name;
+ v4l2_std_id id;
+ /* mode for saa7113h */
+ int mode;
+};
+
+/* main device struct */
+struct em28xx {
+ /* generic device properties */
+ char name[30]; /* name (including minor) of the device */
+ int model; /* index in the device_data struct */
+ unsigned int is_em2800;
+ int video_inputs; /* number of video inputs */
+ struct list_head devlist;
+ unsigned int has_tuner:1;
+ unsigned int has_msp34xx:1;
+ unsigned int has_tda9887:1;
+
+ enum em28xx_decoder decoder;
+
+ int tuner_type; /* type of the tuner */
+ int tuner_addr; /* tuner address */
+ int tda9887_conf;
+ /* i2c i/o */
+ struct i2c_adapter i2c_adap;
+ struct i2c_client i2c_client;
+ /* video for linux */
+ int users; /* user count for exclusive use */
+ struct video_device *vdev; /* video for linux device struct */
+ struct video_picture vpic; /* picture settings only used to init saa7113h */
+ struct em28xx_tvnorm *tvnorm; /* selected tv norm */
+ int ctl_freq; /* selected frequency */
+ unsigned int ctl_input; /* selected input */
+ unsigned int ctl_ainput; /* slected audio input */
+ int mute;
+ int volume;
+ /* frame properties */
+ struct em28xx_frame_t frame[EM28XX_NUM_FRAMES]; /* list of frames */
+ int num_frames; /* number of frames currently in use */
+ unsigned int frame_count; /* total number of transfered frames */
+ struct em28xx_frame_t *frame_current; /* the frame that is being filled */
+ int width; /* current frame width */
+ int height; /* current frame height */
+ int frame_size; /* current frame size */
+ int field_size; /* current field size */
+ int bytesperline;
+ int hscale; /* horizontal scale factor (see datasheet) */
+ int vscale; /* vertical scale factor (see datasheet) */
+ int interlaced; /* 1=interlace fileds, 0=just top fileds */
+ int type;
+
+ /* states */
+ enum em28xx_dev_state state;
+ enum em28xx_stream_state stream;
+ enum em28xx_io_method io;
+ /* locks */
+ struct semaphore lock, fileop_lock;
+ spinlock_t queue_lock;
+ struct list_head inqueue, outqueue;
+ wait_queue_head_t open, wait_frame, wait_stream;
+ struct video_device *vbi_dev;
+
+ unsigned char eedata[256];
+
+ /* usb transfer */
+ struct usb_device *udev; /* the usb device */
+ int alt; /* alternate */
+ int max_pkt_size; /* max packet size of isoc transaction */
+ int num_alt; /* Number of alternative settings */
+ unsigned int *alt_max_pkt_size; /* array of wMaxPacketSize */
+ struct urb *urb[EM28XX_NUM_BUFS]; /* urb for isoc transfers */
+ char *transfer_buffer[EM28XX_NUM_BUFS]; /* transfer buffers for isoc transfer */
+ /* helper funcs that call usb_control_msg */
+ int (*em28xx_write_regs) (struct em28xx * dev, u16 reg, char *buf,
+ int len);
+ int (*em28xx_read_reg) (struct em28xx * dev, u16 reg);
+ int (*em28xx_read_reg_req_len) (struct em28xx * dev, u8 req, u16 reg,
+ char *buf, int len);
+ int (*em28xx_write_regs_req) (struct em28xx * dev, u8 req, u16 reg,
+ char *buf, int len);
+ int (*em28xx_read_reg_req) (struct em28xx * dev, u8 req, u16 reg);
+};
+
+/* Provided by em28xx-i2c.c */
+
+void em28xx_i2c_call_clients(struct em28xx *dev, unsigned int cmd, void *arg);
+int em28xx_i2c_register(struct em28xx *dev);
+int em28xx_i2c_unregister(struct em28xx *dev);
+
+/* Provided by em28xx-input.c */
+
+void em28xx_set_ir(struct em28xx * dev,struct IR_i2c *ir);
+
+/* Provided by em28xx-core.c */
+
+void em28xx_print_ioctl(char *name, unsigned int cmd);
+
+u32 em28xx_request_buffers(struct em28xx *dev, u32 count);
+void em28xx_queue_unusedframes(struct em28xx *dev);
+void em28xx_release_buffers(struct em28xx *dev);
+
+int em28xx_read_reg_req_len(struct em28xx *dev, u8 req, u16 reg,
+ char *buf, int len);
+int em28xx_read_reg_req(struct em28xx *dev, u8 req, u16 reg);
+int em28xx_read_reg(struct em28xx *dev, u16 reg);
+int em28xx_write_regs_req(struct em28xx *dev, u8 req, u16 reg, char *buf,
+ int len);
+int em28xx_write_regs(struct em28xx *dev, u16 reg, char *buf, int len);
+int em28xx_write_reg_bits(struct em28xx *dev, u16 reg, u8 val,
+ u8 bitmask);
+int em28xx_write_ac97(struct em28xx *dev, u8 reg, u8 * val);
+int em28xx_audio_analog_set(struct em28xx *dev);
+int em28xx_colorlevels_set_default(struct em28xx *dev);
+int em28xx_capture_start(struct em28xx *dev, int start);
+int em28xx_outfmt_set_yuv422(struct em28xx *dev);
+int em28xx_accumulator_set(struct em28xx *dev, u8 xmin, u8 xmax, u8 ymin,
+ u8 ymax);
+int em28xx_capture_area_set(struct em28xx *dev, u8 hstart, u8 vstart,
+ u16 width, u16 height);
+int em28xx_scaler_set(struct em28xx *dev, u16 h, u16 v);
+int em28xx_resolution_set(struct em28xx *dev);
+void em28xx_isocIrq(struct urb *urb, struct pt_regs *regs);
+int em28xx_init_isoc(struct em28xx *dev);
+void em28xx_uninit_isoc(struct em28xx *dev);
+int em28xx_set_alternate(struct em28xx *dev);
+
+/* Provided by em28xx-cards.c */
+extern int em2800_variant_detect(struct usb_device* udev,int model);
+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;
+
+/* em28xx registers */
+#define CHIPID_REG 0x0a
+#define USBSUSP_REG 0x0c /* */
+
+#define AUDIOSRC_REG 0x0e
+#define XCLK_REG 0x0f
+
+#define VINMODE_REG 0x10
+#define VINCTRL_REG 0x11
+#define VINENABLE_REG 0x12 /* */
+
+#define GAMMA_REG 0x14
+#define RGAIN_REG 0x15
+#define GGAIN_REG 0x16
+#define BGAIN_REG 0x17
+#define ROFFSET_REG 0x18
+#define GOFFSET_REG 0x19
+#define BOFFSET_REG 0x1a
+
+#define OFLOW_REG 0x1b
+#define HSTART_REG 0x1c
+#define VSTART_REG 0x1d
+#define CWIDTH_REG 0x1e
+#define CHEIGHT_REG 0x1f
+
+#define YGAIN_REG 0x20
+#define YOFFSET_REG 0x21
+#define UVGAIN_REG 0x22
+#define UOFFSET_REG 0x23
+#define VOFFSET_REG 0x24
+#define SHARPNESS_REG 0x25
+
+#define COMPR_REG 0x26
+#define OUTFMT_REG 0x27
+
+#define XMIN_REG 0x28
+#define XMAX_REG 0x29
+#define YMIN_REG 0x2a
+#define YMAX_REG 0x2b
+
+#define HSCALELOW_REG 0x30
+#define HSCALEHIGH_REG 0x31
+#define VSCALELOW_REG 0x32
+#define VSCALEHIGH_REG 0x33
+
+#define AC97LSB_REG 0x40
+#define AC97MSB_REG 0x41
+#define AC97ADDR_REG 0x42
+#define AC97BUSY_REG 0x43
+
+/* em202 registers */
+#define MASTER_AC97 0x02
+#define VIDEO_AC97 0x14
+
+/* register settings */
+#define EM28XX_AUDIO_SRC_TUNER 0xc0
+#define EM28XX_AUDIO_SRC_LINE 0x80
+
+/* printk macros */
+
+#define em28xx_err(fmt, arg...) do {\
+ printk(KERN_ERR fmt , ##arg); } while (0)
+
+#define em28xx_errdev(fmt, arg...) do {\
+ printk(KERN_ERR "%s: "fmt,\
+ dev->name , ##arg); } while (0)
+
+#define em28xx_info(fmt, arg...) do {\
+ printk(KERN_INFO "%s: "fmt,\
+ dev->name , ##arg); } while (0)
+#define em28xx_warn(fmt, arg...) do {\
+ printk(KERN_WARNING "%s: "fmt,\
+ dev->name , ##arg); } while (0)
+
+inline static int em28xx_audio_source(struct em28xx *dev, int input)
+{
+ return em28xx_write_reg_bits(dev, AUDIOSRC_REG, input, 0xc0);
+}
+
+inline static int em28xx_audio_usb_mute(struct em28xx *dev, int mute)
+{
+ return em28xx_write_reg_bits(dev, XCLK_REG, mute ? 0x00 : 0x80, 0x80);
+}
+
+inline static int em28xx_audio_analog_setup(struct em28xx *dev)
+{
+ /* unmute video mixer with default volume level */
+ return em28xx_write_ac97(dev, VIDEO_AC97, "\x08\x08");
+}
+
+inline static int em28xx_compression_disable(struct em28xx *dev)
+{
+ /* side effect of disabling scaler and mixer */
+ return em28xx_write_regs(dev, COMPR_REG, "\x00", 1);
+}
+
+inline static int em28xx_contrast_get(struct em28xx *dev)
+{
+ return em28xx_read_reg(dev, YGAIN_REG) & 0x1f;
+}
+
+inline static int em28xx_brightness_get(struct em28xx *dev)
+{
+ return em28xx_read_reg(dev, YOFFSET_REG);
+}
+
+inline static int em28xx_saturation_get(struct em28xx *dev)
+{
+ return em28xx_read_reg(dev, UVGAIN_REG) & 0x1f;
+}
+
+inline static int em28xx_u_balance_get(struct em28xx *dev)
+{
+ return em28xx_read_reg(dev, UOFFSET_REG);
+}
+
+inline static int em28xx_v_balance_get(struct em28xx *dev)
+{
+ return em28xx_read_reg(dev, VOFFSET_REG);
+}
+
+inline static int em28xx_gamma_get(struct em28xx *dev)
+{
+ return em28xx_read_reg(dev, GAMMA_REG) & 0x3f;
+}
+
+inline static int em28xx_contrast_set(struct em28xx *dev, s32 val)
+{
+ u8 tmp = (u8) val;
+ return em28xx_write_regs(dev, YGAIN_REG, &tmp, 1);
+}
+
+inline static int em28xx_brightness_set(struct em28xx *dev, s32 val)
+{
+ u8 tmp = (u8) val;
+ return em28xx_write_regs(dev, YOFFSET_REG, &tmp, 1);
+}
+
+inline static int em28xx_saturation_set(struct em28xx *dev, s32 val)
+{
+ u8 tmp = (u8) val;
+ return em28xx_write_regs(dev, UVGAIN_REG, &tmp, 1);
+}
+
+inline static int em28xx_u_balance_set(struct em28xx *dev, s32 val)
+{
+ u8 tmp = (u8) val;
+ return em28xx_write_regs(dev, UOFFSET_REG, &tmp, 1);
+}
+
+inline static int em28xx_v_balance_set(struct em28xx *dev, s32 val)
+{
+ u8 tmp = (u8) val;
+ return em28xx_write_regs(dev, VOFFSET_REG, &tmp, 1);
+}
+
+inline static int em28xx_gamma_set(struct em28xx *dev, s32 val)
+{
+ u8 tmp = (u8) val;
+ return em28xx_write_regs(dev, GAMMA_REG, &tmp, 1);
+}
+
+/*FIXME: maxw should be dependent of alt mode */
+inline static unsigned int norm_maxw(struct em28xx *dev)
+{
+ switch(dev->model){
+ case (EM2820_BOARD_MSI_VOX_USB_2): return(640);
+ default: return(720);
+ }
+}
+
+inline static unsigned int norm_maxh(struct em28xx *dev)
+{
+ switch(dev->model){
+ case (EM2820_BOARD_MSI_VOX_USB_2): return(480);
+ default: return (dev->tvnorm->id & V4L2_STD_625_50) ? 576 : 480;
+ }
+}
+
+#endif
diff --git a/drivers/media/video/indycam.c b/drivers/media/video/indycam.c
index b2b0384cd4b9..deeef125eb92 100644
--- a/drivers/media/video/indycam.c
+++ b/drivers/media/video/indycam.c
@@ -9,16 +9,16 @@
* published by the Free Software Foundation.
*/
-#include <linux/module.h>
-#include <linux/init.h>
#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/fs.h>
+#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/major.h>
-#include <linux/slab.h>
+#include <linux/module.h>
#include <linux/mm.h>
#include <linux/sched.h>
+#include <linux/slab.h>
#include <linux/videodev.h>
/* IndyCam decodes stream of photons into digital image representation ;-) */
@@ -27,15 +27,15 @@
#include "indycam.h"
-//#define INDYCAM_DEBUG
-
-#define INDYCAM_MODULE_VERSION "0.0.3"
+#define INDYCAM_MODULE_VERSION "0.0.5"
MODULE_DESCRIPTION("SGI IndyCam driver");
MODULE_VERSION(INDYCAM_MODULE_VERSION);
MODULE_AUTHOR("Mikael Nousiainen <tmnousia@cc.hut.fi>");
MODULE_LICENSE("GPL");
+// #define INDYCAM_DEBUG
+
#ifdef INDYCAM_DEBUG
#define dprintk(x...) printk("IndyCam: " x);
#define indycam_regdump(client) indycam_regdump_debug(client)
@@ -44,18 +44,16 @@ MODULE_LICENSE("GPL");
#define indycam_regdump(client)
#endif
-#define VINO_ADAPTER (I2C_ALGO_SGI | I2C_HW_SGI_VINO)
-
struct indycam {
struct i2c_client *client;
- int version;
+ u8 version;
};
static struct i2c_driver i2c_driver_indycam;
-static const unsigned char initseq[] = {
+static const u8 initseq[] = {
INDYCAM_CONTROL_AGCENA, /* INDYCAM_CONTROL */
- INDYCAM_SHUTTER_DEFAULT, /* INDYCAM_SHUTTER */
+ INDYCAM_SHUTTER_60, /* INDYCAM_SHUTTER */
INDYCAM_GAIN_DEFAULT, /* INDYCAM_GAIN */
0x00, /* INDYCAM_BRIGHTNESS (read-only) */
INDYCAM_RED_BALANCE_DEFAULT, /* INDYCAM_RED_BALANCE */
@@ -66,12 +64,11 @@ static const unsigned char initseq[] = {
/* IndyCam register handling */
-static int indycam_read_reg(struct i2c_client *client, unsigned char reg,
- unsigned char *value)
+static int indycam_read_reg(struct i2c_client *client, u8 reg, u8 *value)
{
int ret;
- if (reg == INDYCAM_RESET) {
+ if (reg == INDYCAM_REG_RESET) {
dprintk("indycam_read_reg(): "
"skipping write-only register %d\n", reg);
*value = 0;
@@ -79,24 +76,24 @@ static int indycam_read_reg(struct i2c_client *client, unsigned char reg,
}
ret = i2c_smbus_read_byte_data(client, reg);
+
if (ret < 0) {
printk(KERN_ERR "IndyCam: indycam_read_reg(): read failed, "
"register = 0x%02x\n", reg);
return ret;
}
- *value = (unsigned char)ret;
+ *value = (u8)ret;
return 0;
}
-static int indycam_write_reg(struct i2c_client *client, unsigned char reg,
- unsigned char value)
+static int indycam_write_reg(struct i2c_client *client, u8 reg, u8 value)
{
int err;
- if ((reg == INDYCAM_BRIGHTNESS)
- || (reg == INDYCAM_VERSION)) {
+ if ((reg == INDYCAM_REG_BRIGHTNESS)
+ || (reg == INDYCAM_REG_VERSION)) {
dprintk("indycam_write_reg(): "
"skipping read-only register %d\n", reg);
return 0;
@@ -104,6 +101,7 @@ static int indycam_write_reg(struct i2c_client *client, unsigned char reg,
dprintk("Writing Reg %d = 0x%02x\n", reg, value);
err = i2c_smbus_write_byte_data(client, reg, value);
+
if (err) {
printk(KERN_ERR "IndyCam: indycam_write_reg(): write failed, "
"register = 0x%02x, value = 0x%02x\n", reg, value);
@@ -111,13 +109,12 @@ static int indycam_write_reg(struct i2c_client *client, unsigned char reg,
return err;
}
-static int indycam_write_block(struct i2c_client *client, unsigned char reg,
- unsigned char length, unsigned char *data)
+static int indycam_write_block(struct i2c_client *client, u8 reg,
+ u8 length, u8 *data)
{
- unsigned char i;
- int err;
+ int i, err;
- for (i = reg; i < length; i++) {
+ for (i = 0; i < length; i++) {
err = indycam_write_reg(client, reg + i, data[i]);
if (err)
return err;
@@ -132,7 +129,7 @@ static int indycam_write_block(struct i2c_client *client, unsigned char reg,
static void indycam_regdump_debug(struct i2c_client *client)
{
int i;
- unsigned char val;
+ u8 val;
for (i = 0; i < 9; i++) {
indycam_read_reg(client, i, &val);
@@ -141,76 +138,144 @@ static void indycam_regdump_debug(struct i2c_client *client)
}
#endif
-static int indycam_get_controls(struct i2c_client *client,
- struct indycam_control *ctrl)
+static int indycam_get_control(struct i2c_client *client,
+ struct indycam_control *ctrl)
{
- unsigned char ctrl_reg;
-
- indycam_read_reg(client, INDYCAM_CONTROL, &ctrl_reg);
- ctrl->agc = (ctrl_reg & INDYCAM_CONTROL_AGCENA)
- ? INDYCAM_VALUE_ENABLED
- : INDYCAM_VALUE_DISABLED;
- ctrl->awb = (ctrl_reg & INDYCAM_CONTROL_AWBCTL)
- ? INDYCAM_VALUE_ENABLED
- : INDYCAM_VALUE_DISABLED;
- indycam_read_reg(client, INDYCAM_SHUTTER,
- (unsigned char *)&ctrl->shutter);
- indycam_read_reg(client, INDYCAM_GAIN,
- (unsigned char *)&ctrl->gain);
- indycam_read_reg(client, INDYCAM_RED_BALANCE,
- (unsigned char *)&ctrl->red_balance);
- indycam_read_reg(client, INDYCAM_BLUE_BALANCE,
- (unsigned char *)&ctrl->blue_balance);
- indycam_read_reg(client, INDYCAM_RED_SATURATION,
- (unsigned char *)&ctrl->red_saturation);
- indycam_read_reg(client, INDYCAM_BLUE_SATURATION,
- (unsigned char *)&ctrl->blue_saturation);
- indycam_read_reg(client, INDYCAM_GAMMA,
- (unsigned char *)&ctrl->gamma);
+ struct indycam *camera = i2c_get_clientdata(client);
+ u8 reg;
+ int ret = 0;
+
+ switch (ctrl->type) {
+ case INDYCAM_CONTROL_AGC:
+ case INDYCAM_CONTROL_AWB:
+ ret = indycam_read_reg(client, INDYCAM_REG_CONTROL, &reg);
+ if (ret)
+ return -EIO;
+ if (ctrl->type == INDYCAM_CONTROL_AGC)
+ ctrl->value = (reg & INDYCAM_CONTROL_AGCENA)
+ ? 1 : 0;
+ else
+ ctrl->value = (reg & INDYCAM_CONTROL_AWBCTL)
+ ? 1 : 0;
+ break;
+ case INDYCAM_CONTROL_SHUTTER:
+ ret = indycam_read_reg(client, INDYCAM_REG_SHUTTER, &reg);
+ if (ret)
+ return -EIO;
+ ctrl->value = ((s32)reg == 0x00) ? 0xff : ((s32)reg - 1);
+ break;
+ case INDYCAM_CONTROL_GAIN:
+ ret = indycam_read_reg(client, INDYCAM_REG_GAIN, &reg);
+ if (ret)
+ return -EIO;
+ ctrl->value = (s32)reg;
+ break;
+ case INDYCAM_CONTROL_RED_BALANCE:
+ ret = indycam_read_reg(client, INDYCAM_REG_RED_BALANCE, &reg);
+ if (ret)
+ return -EIO;
+ ctrl->value = (s32)reg;
+ break;
+ case INDYCAM_CONTROL_BLUE_BALANCE:
+ ret = indycam_read_reg(client, INDYCAM_REG_BLUE_BALANCE, &reg);
+ if (ret)
+ return -EIO;
+ ctrl->value = (s32)reg;
+ break;
+ case INDYCAM_CONTROL_RED_SATURATION:
+ ret = indycam_read_reg(client,
+ INDYCAM_REG_RED_SATURATION, &reg);
+ if (ret)
+ return -EIO;
+ ctrl->value = (s32)reg;
+ break;
+ case INDYCAM_CONTROL_BLUE_SATURATION:
+ ret = indycam_read_reg(client,
+ INDYCAM_REG_BLUE_SATURATION, &reg);
+ if (ret)
+ return -EIO;
+ ctrl->value = (s32)reg;
+ break;
+ case INDYCAM_CONTROL_GAMMA:
+ if (camera->version == CAMERA_VERSION_MOOSE) {
+ ret = indycam_read_reg(client,
+ INDYCAM_REG_GAMMA, &reg);
+ if (ret)
+ return -EIO;
+ ctrl->value = (s32)reg;
+ } else {
+ ctrl->value = INDYCAM_GAMMA_DEFAULT;
+ }
+ break;
+ default:
+ ret = -EINVAL;
+ }
- return 0;
+ return ret;
}
-static int indycam_set_controls(struct i2c_client *client,
- struct indycam_control *ctrl)
+static int indycam_set_control(struct i2c_client *client,
+ struct indycam_control *ctrl)
{
- unsigned char ctrl_reg;
+ struct indycam *camera = i2c_get_clientdata(client);
+ u8 reg;
+ int ret = 0;
+
+ switch (ctrl->type) {
+ case INDYCAM_CONTROL_AGC:
+ case INDYCAM_CONTROL_AWB:
+ ret = indycam_read_reg(client, INDYCAM_REG_CONTROL, &reg);
+ if (ret)
+ break;
- indycam_read_reg(client, INDYCAM_CONTROL, &ctrl_reg);
- if (ctrl->agc != INDYCAM_VALUE_UNCHANGED) {
- if (ctrl->agc)
- ctrl_reg |= INDYCAM_CONTROL_AGCENA;
- else
- ctrl_reg &= ~INDYCAM_CONTROL_AGCENA;
- }
- if (ctrl->awb != INDYCAM_VALUE_UNCHANGED) {
- if (ctrl->awb)
- ctrl_reg |= INDYCAM_CONTROL_AWBCTL;
- else
- ctrl_reg &= ~INDYCAM_CONTROL_AWBCTL;
+ if (ctrl->type == INDYCAM_CONTROL_AGC) {
+ if (ctrl->value)
+ reg |= INDYCAM_CONTROL_AGCENA;
+ else
+ reg &= ~INDYCAM_CONTROL_AGCENA;
+ } else {
+ if (ctrl->value)
+ reg |= INDYCAM_CONTROL_AWBCTL;
+ else
+ reg &= ~INDYCAM_CONTROL_AWBCTL;
+ }
+
+ ret = indycam_write_reg(client, INDYCAM_REG_CONTROL, reg);
+ break;
+ case INDYCAM_CONTROL_SHUTTER:
+ reg = (ctrl->value == 0xff) ? 0x00 : (ctrl->value + 1);
+ ret = indycam_write_reg(client, INDYCAM_REG_SHUTTER, reg);
+ break;
+ case INDYCAM_CONTROL_GAIN:
+ ret = indycam_write_reg(client, INDYCAM_REG_GAIN, ctrl->value);
+ break;
+ case INDYCAM_CONTROL_RED_BALANCE:
+ ret = indycam_write_reg(client, INDYCAM_REG_RED_BALANCE,
+ ctrl->value);
+ break;
+ case INDYCAM_CONTROL_BLUE_BALANCE:
+ ret = indycam_write_reg(client, INDYCAM_REG_BLUE_BALANCE,
+ ctrl->value);
+ break;
+ case INDYCAM_CONTROL_RED_SATURATION:
+ ret = indycam_write_reg(client, INDYCAM_REG_RED_SATURATION,
+ ctrl->value);
+ break;
+ case INDYCAM_CONTROL_BLUE_SATURATION:
+ ret = indycam_write_reg(client, INDYCAM_REG_BLUE_SATURATION,
+ ctrl->value);
+ break;
+ case INDYCAM_CONTROL_GAMMA:
+ if (camera->version == CAMERA_VERSION_MOOSE) {
+ ret = indycam_write_reg(client, INDYCAM_REG_GAMMA,
+ ctrl->value);
+ }
+ break;
+ default:
+ ret = -EINVAL;
}
- indycam_write_reg(client, INDYCAM_CONTROL, ctrl_reg);
-
- if (ctrl->shutter >= 0)
- indycam_write_reg(client, INDYCAM_SHUTTER, ctrl->shutter);
- if (ctrl->gain >= 0)
- indycam_write_reg(client, INDYCAM_GAIN, ctrl->gain);
- if (ctrl->red_balance >= 0)
- indycam_write_reg(client, INDYCAM_RED_BALANCE,
- ctrl->red_balance);
- if (ctrl->blue_balance >= 0)
- indycam_write_reg(client, INDYCAM_BLUE_BALANCE,
- ctrl->blue_balance);
- if (ctrl->red_saturation >= 0)
- indycam_write_reg(client, INDYCAM_RED_SATURATION,
- ctrl->red_saturation);
- if (ctrl->blue_saturation >= 0)
- indycam_write_reg(client, INDYCAM_BLUE_SATURATION,
- ctrl->blue_saturation);
- if (ctrl->gamma >= 0)
- indycam_write_reg(client, INDYCAM_GAMMA, ctrl->gamma);
- return 0;
+ return ret;
}
/* I2C-interface */
@@ -249,7 +314,8 @@ static int indycam_attach(struct i2c_adapter *adap, int addr, int kind)
if (err)
goto out_free_camera;
- camera->version = i2c_smbus_read_byte_data(client, INDYCAM_VERSION);
+ camera->version = i2c_smbus_read_byte_data(client,
+ INDYCAM_REG_VERSION);
if (camera->version != CAMERA_VERSION_INDY &&
camera->version != CAMERA_VERSION_MOOSE) {
err = -ENODEV;
@@ -262,8 +328,7 @@ static int indycam_attach(struct i2c_adapter *adap, int addr, int kind)
indycam_regdump(client);
// initialize
- err = indycam_write_block(client, 0, sizeof(initseq),
- (unsigned char *)&initseq);
+ err = indycam_write_block(client, 0, sizeof(initseq), (u8 *)&initseq);
if (err) {
printk(KERN_ERR "IndyCam initalization failed\n");
err = -EIO;
@@ -273,11 +338,10 @@ static int indycam_attach(struct i2c_adapter *adap, int addr, int kind)
indycam_regdump(client);
// white balance
- err = indycam_write_reg(client, INDYCAM_CONTROL,
+ err = indycam_write_reg(client, INDYCAM_REG_CONTROL,
INDYCAM_CONTROL_AGCENA | INDYCAM_CONTROL_AWBCTL);
if (err) {
- printk(KERN_ERR "IndyCam white balance "
- "initialization failed\n");
+ printk(KERN_ERR "IndyCam: White balancing camera failed\n");
err = -EIO;
goto out_detach_client;
}
@@ -300,7 +364,7 @@ out_free_client:
static int indycam_probe(struct i2c_adapter *adap)
{
/* Indy specific crap */
- if (adap->id == VINO_ADAPTER)
+ if (adap->id == I2C_HW_SGI_VINO)
return indycam_attach(adap, INDYCAM_ADDR, 0);
/* Feel free to add probe here :-) */
return -ENODEV;
@@ -373,13 +437,11 @@ static int indycam_command(struct i2c_client *client, unsigned int cmd,
/* TODO: convert values for indycam_set_controls() */
break;
}
- case DECODER_INDYCAM_GET_CONTROLS: {
- struct indycam_control *ctrl = arg;
- indycam_get_controls(client, ctrl);
+ case DECODER_INDYCAM_GET_CONTROL: {
+ return indycam_get_control(client, arg);
}
- case DECODER_INDYCAM_SET_CONTROLS: {
- struct indycam_control *ctrl = arg;
- indycam_set_controls(client, ctrl);
+ case DECODER_INDYCAM_SET_CONTROL: {
+ return indycam_set_control(client, arg);
}
default:
return -EINVAL;
@@ -390,12 +452,12 @@ static int indycam_command(struct i2c_client *client, unsigned int cmd,
static struct i2c_driver i2c_driver_indycam = {
.owner = THIS_MODULE,
- .name = "indycam",
- .id = I2C_DRIVERID_INDYCAM,
- .flags = I2C_DF_NOTIFY,
+ .name = "indycam",
+ .id = I2C_DRIVERID_INDYCAM,
+ .flags = I2C_DF_NOTIFY,
.attach_adapter = indycam_probe,
- .detach_client = indycam_detach,
- .command = indycam_command,
+ .detach_client = indycam_detach,
+ .command = indycam_command,
};
static int __init indycam_init(void)
diff --git a/drivers/media/video/indycam.h b/drivers/media/video/indycam.h
index d9ddb6b79a03..e6ee82063ed8 100644
--- a/drivers/media/video/indycam.h
+++ b/drivers/media/video/indycam.h
@@ -22,21 +22,21 @@
#define INDYCAM_VERSION_MINOR(x) ((x) & 0x0f)
/* Register bus addresses */
-#define INDYCAM_CONTROL 0x00
-#define INDYCAM_SHUTTER 0x01
-#define INDYCAM_GAIN 0x02
-#define INDYCAM_BRIGHTNESS 0x03 /* read-only */
-#define INDYCAM_RED_BALANCE 0x04
-#define INDYCAM_BLUE_BALANCE 0x05
-#define INDYCAM_RED_SATURATION 0x06
-#define INDYCAM_BLUE_SATURATION 0x07
-#define INDYCAM_GAMMA 0x08
-#define INDYCAM_VERSION 0x0e /* read-only */
-#define INDYCAM_RESET 0x0f /* write-only */
-
-#define INDYCAM_LED 0x46
-#define INDYCAM_ORIENTATION 0x47
-#define INDYCAM_BUTTON 0x48
+#define INDYCAM_REG_CONTROL 0x00
+#define INDYCAM_REG_SHUTTER 0x01
+#define INDYCAM_REG_GAIN 0x02
+#define INDYCAM_REG_BRIGHTNESS 0x03 /* read-only */
+#define INDYCAM_REG_RED_BALANCE 0x04
+#define INDYCAM_REG_BLUE_BALANCE 0x05
+#define INDYCAM_REG_RED_SATURATION 0x06
+#define INDYCAM_REG_BLUE_SATURATION 0x07
+#define INDYCAM_REG_GAMMA 0x08
+#define INDYCAM_REG_VERSION 0x0e /* read-only */
+#define INDYCAM_REG_RESET 0x0f /* write-only */
+
+#define INDYCAM_REG_LED 0x46
+#define INDYCAM_REG_ORIENTATION 0x47
+#define INDYCAM_REG_BUTTON 0x48
/* Field definitions of registers */
#define INDYCAM_CONTROL_AGCENA (1<<0) /* automatic gain control */
@@ -59,13 +59,14 @@
#define INDYCAM_ORIENTATION_BOTTOM_TO_TOP 0x40
#define INDYCAM_BUTTON_RELEASED 0x10
+/* Values for controls */
#define INDYCAM_SHUTTER_MIN 0x00
#define INDYCAM_SHUTTER_MAX 0xff
#define INDYCAM_GAIN_MIN 0x00
#define INDYCAM_GAIN_MAX 0xff
-#define INDYCAM_RED_BALANCE_MIN 0x00 /* the effect is the opposite? */
-#define INDYCAM_RED_BALANCE_MAX 0xff
-#define INDYCAM_BLUE_BALANCE_MIN 0x00 /* the effect is the opposite? */
+#define INDYCAM_RED_BALANCE_MIN 0x00
+#define INDYCAM_RED_BALANCE_MAX 0xff
+#define INDYCAM_BLUE_BALANCE_MIN 0x00
#define INDYCAM_BLUE_BALANCE_MAX 0xff
#define INDYCAM_RED_SATURATION_MIN 0x00
#define INDYCAM_RED_SATURATION_MAX 0xff
@@ -74,34 +75,9 @@
#define INDYCAM_GAMMA_MIN 0x00
#define INDYCAM_GAMMA_MAX 0xff
-/* Driver interface definitions */
-
-#define INDYCAM_VALUE_ENABLED 1
-#define INDYCAM_VALUE_DISABLED 0
-#define INDYCAM_VALUE_UNCHANGED -1
-
-/* When setting controls, a value of -1 leaves the control unchanged. */
-struct indycam_control {
- int agc; /* boolean */
- int awb; /* boolean */
- int shutter;
- int gain;
- int red_balance;
- int blue_balance;
- int red_saturation;
- int blue_saturation;
- int gamma;
-};
-
-#define DECODER_INDYCAM_GET_CONTROLS _IOR('d', 193, struct indycam_control)
-#define DECODER_INDYCAM_SET_CONTROLS _IOW('d', 194, struct indycam_control)
-
-/* Default values for controls */
-
-#define INDYCAM_AGC_DEFAULT INDYCAM_VALUE_ENABLED
-#define INDYCAM_AWB_DEFAULT INDYCAM_VALUE_ENABLED
-
-#define INDYCAM_SHUTTER_DEFAULT INDYCAM_SHUTTER_60
+#define INDYCAM_AGC_DEFAULT 1
+#define INDYCAM_AWB_DEFAULT 0
+#define INDYCAM_SHUTTER_DEFAULT 0xff
#define INDYCAM_GAIN_DEFAULT 0x80
#define INDYCAM_RED_BALANCE_DEFAULT 0x18
#define INDYCAM_BLUE_BALANCE_DEFAULT 0xa4
@@ -109,4 +85,24 @@ struct indycam_control {
#define INDYCAM_BLUE_SATURATION_DEFAULT 0xc0
#define INDYCAM_GAMMA_DEFAULT 0x80
+/* Driver interface definitions */
+
+#define INDYCAM_CONTROL_AGC 0 /* boolean */
+#define INDYCAM_CONTROL_AWB 1 /* boolean */
+#define INDYCAM_CONTROL_SHUTTER 2
+#define INDYCAM_CONTROL_GAIN 3
+#define INDYCAM_CONTROL_RED_BALANCE 4
+#define INDYCAM_CONTROL_BLUE_BALANCE 5
+#define INDYCAM_CONTROL_RED_SATURATION 6
+#define INDYCAM_CONTROL_BLUE_SATURATION 7
+#define INDYCAM_CONTROL_GAMMA 8
+
+struct indycam_control {
+ u8 type;
+ s32 value;
+};
+
+#define DECODER_INDYCAM_GET_CONTROL _IOR('d', 193, struct indycam_control)
+#define DECODER_INDYCAM_SET_CONTROL _IOW('d', 194, struct indycam_control)
+
#endif
diff --git a/drivers/media/video/ir-kbd-gpio.c b/drivers/media/video/ir-kbd-gpio.c
index cf292da8fdd5..ed81934ef3cd 100644
--- a/drivers/media/video/ir-kbd-gpio.c
+++ b/drivers/media/video/ir-kbd-gpio.c
@@ -156,9 +156,74 @@ static IR_KEYTAB_TYPE ir_codes_apac_viewcomp[IR_KEYTAB_SIZE] = {
/* ---------------------------------------------------------------------- */
+/* Ricardo Cerqueira <v4l@cerqueira.org> */
+/* Weird matching, since the remote has "uncommon" keys */
+
+static IR_KEYTAB_TYPE ir_codes_conceptronic[IR_KEYTAB_SIZE] = {
+
+ [ 30 ] = KEY_POWER, // power
+ [ 7 ] = KEY_MEDIA, // source
+ [ 28 ] = KEY_SEARCH, // scan
+
+/* FIXME: duplicate keycodes?
+ *
+ * These four keys seem to share the same GPIO as CH+, CH-, <<< and >>>
+ * The GPIO values are
+ * 6397fb for both "Scan <" and "CH -",
+ * 639ffb for "Scan >" and "CH+",
+ * 6384fb for "Tune <" and "<<<",
+ * 638cfb for "Tune >" and ">>>", regardless of the mask.
+ *
+ * [ 23 ] = KEY_BACK, // fm scan <<
+ * [ 31 ] = KEY_FORWARD, // fm scan >>
+ *
+ * [ 4 ] = KEY_LEFT, // fm tuning <
+ * [ 12 ] = KEY_RIGHT, // fm tuning >
+ *
+ * For now, these four keys are disabled. Pressing them will generate
+ * the CH+/CH-/<<</>>> events
+ */
+
+ [ 3 ] = KEY_TUNER, // TV/FM
+
+ [ 0 ] = KEY_RECORD,
+ [ 8 ] = KEY_STOP,
+ [ 17 ] = KEY_PLAY,
+
+ [ 26 ] = KEY_PLAYPAUSE, // freeze
+ [ 25 ] = KEY_ZOOM, // zoom
+ [ 15 ] = KEY_TEXT, // min
+
+ [ 1 ] = KEY_KP1,
+ [ 11 ] = KEY_KP2,
+ [ 27 ] = KEY_KP3,
+ [ 5 ] = KEY_KP4,
+ [ 9 ] = KEY_KP5,
+ [ 21 ] = KEY_KP6,
+ [ 6 ] = KEY_KP7,
+ [ 10 ] = KEY_KP8,
+ [ 18 ] = KEY_KP9,
+ [ 2 ] = KEY_KP0,
+ [ 16 ] = KEY_LAST, // +100
+ [ 19 ] = KEY_LIST, // recall
+
+ [ 31 ] = KEY_CHANNELUP, // chn down
+ [ 23 ] = KEY_CHANNELDOWN, // chn up
+ [ 22 ] = KEY_VOLUMEUP, // vol down
+ [ 20 ] = KEY_VOLUMEDOWN, // vol up
+
+ [ 4 ] = KEY_KPMINUS, // <<<
+ [ 14 ] = KEY_SETUP, // function
+ [ 12 ] = KEY_KPPLUS, // >>>
+
+ [ 13 ] = KEY_GOTO, // mts
+ [ 29 ] = KEY_REFRESH, // reset
+ [ 24 ] = KEY_MUTE // mute/unmute
+};
+
struct IR {
struct bttv_sub_device *sub;
- struct input_dev input;
+ struct input_dev *input;
struct ir_input_state ir;
char name[32];
char phys[32];
@@ -217,23 +282,23 @@ static void ir_handle_key(struct IR *ir)
if (ir->mask_keydown) {
/* bit set on keydown */
if (gpio & ir->mask_keydown) {
- ir_input_keydown(&ir->input,&ir->ir,data,data);
+ ir_input_keydown(ir->input, &ir->ir, data, data);
} else {
- ir_input_nokey(&ir->input,&ir->ir);
+ ir_input_nokey(ir->input, &ir->ir);
}
} else if (ir->mask_keyup) {
/* bit cleared on keydown */
if (0 == (gpio & ir->mask_keyup)) {
- ir_input_keydown(&ir->input,&ir->ir,data,data);
+ ir_input_keydown(ir->input, &ir->ir, data, data);
} else {
- ir_input_nokey(&ir->input,&ir->ir);
+ ir_input_nokey(ir->input, &ir->ir);
}
} else {
/* can't disturgissh keydown/up :-/ */
- ir_input_keydown(&ir->input,&ir->ir,data,data);
- ir_input_nokey(&ir->input,&ir->ir);
+ ir_input_keydown(ir->input, &ir->ir, data, data);
+ ir_input_nokey(ir->input, &ir->ir);
}
}
@@ -268,66 +333,77 @@ static int ir_probe(struct device *dev)
{
struct bttv_sub_device *sub = to_bttv_sub_dev(dev);
struct IR *ir;
+ struct input_dev *input_dev;
IR_KEYTAB_TYPE *ir_codes = NULL;
int ir_type = IR_TYPE_OTHER;
- ir = kmalloc(sizeof(*ir),GFP_KERNEL);
- if (NULL == ir)
+ ir = kzalloc(sizeof(*ir), GFP_KERNEL);
+ input_dev = input_allocate_device();
+ if (!ir || !input_dev) {
+ kfree(ir);
+ input_free_device(input_dev);
return -ENOMEM;
- memset(ir,0,sizeof(*ir));
+ }
/* detect & configure */
switch (sub->core->type) {
- case BTTV_AVERMEDIA:
- case BTTV_AVPHONE98:
- case BTTV_AVERMEDIA98:
+ case BTTV_BOARD_AVERMEDIA:
+ case BTTV_BOARD_AVPHONE98:
+ case BTTV_BOARD_AVERMEDIA98:
ir_codes = ir_codes_avermedia;
ir->mask_keycode = 0xf88000;
ir->mask_keydown = 0x010000;
ir->polling = 50; // ms
break;
- case BTTV_AVDVBT_761:
- case BTTV_AVDVBT_771:
+ case BTTV_BOARD_AVDVBT_761:
+ case BTTV_BOARD_AVDVBT_771:
ir_codes = ir_codes_avermedia_dvbt;
ir->mask_keycode = 0x0f00c0;
ir->mask_keydown = 0x000020;
ir->polling = 50; // ms
break;
- case BTTV_PXELVWPLTVPAK:
+ case BTTV_BOARD_PXELVWPLTVPAK:
ir_codes = ir_codes_pixelview;
ir->mask_keycode = 0x003e00;
ir->mask_keyup = 0x010000;
ir->polling = 50; // ms
- break;
- case BTTV_PV_BT878P_9B:
- case BTTV_PV_BT878P_PLUS:
+ break;
+ case BTTV_BOARD_PV_BT878P_9B:
+ case BTTV_BOARD_PV_BT878P_PLUS:
ir_codes = ir_codes_pixelview;
ir->mask_keycode = 0x001f00;
ir->mask_keyup = 0x008000;
ir->polling = 50; // ms
- break;
+ break;
- case BTTV_WINFAST2000:
+ case BTTV_BOARD_WINFAST2000:
ir_codes = ir_codes_winfast;
ir->mask_keycode = 0x1f8;
break;
- case BTTV_MAGICTVIEW061:
- case BTTV_MAGICTVIEW063:
+ case BTTV_BOARD_MAGICTVIEW061:
+ case BTTV_BOARD_MAGICTVIEW063:
ir_codes = ir_codes_winfast;
ir->mask_keycode = 0x0008e000;
ir->mask_keydown = 0x00200000;
break;
- case BTTV_APAC_VIEWCOMP:
+ case BTTV_BOARD_APAC_VIEWCOMP:
ir_codes = ir_codes_apac_viewcomp;
ir->mask_keycode = 0x001f00;
ir->mask_keyup = 0x008000;
ir->polling = 50; // ms
break;
+ case BTTV_BOARD_CONCEPTRONIC_CTVFMI2:
+ ir_codes = ir_codes_conceptronic;
+ ir->mask_keycode = 0x001F00;
+ ir->mask_keyup = 0x006000;
+ ir->polling = 50; // ms
+ break;
}
if (NULL == ir_codes) {
kfree(ir);
+ input_free_device(input_dev);
return -ENODEV;
}
@@ -341,19 +417,19 @@ static int ir_probe(struct device *dev)
snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0",
pci_name(sub->core->pci));
- ir_input_init(&ir->input, &ir->ir, ir_type, ir_codes);
- ir->input.name = ir->name;
- ir->input.phys = ir->phys;
- ir->input.id.bustype = BUS_PCI;
- ir->input.id.version = 1;
+ ir_input_init(input_dev, &ir->ir, ir_type, ir_codes);
+ input_dev->name = ir->name;
+ input_dev->phys = ir->phys;
+ input_dev->id.bustype = BUS_PCI;
+ input_dev->id.version = 1;
if (sub->core->pci->subsystem_vendor) {
- ir->input.id.vendor = sub->core->pci->subsystem_vendor;
- ir->input.id.product = sub->core->pci->subsystem_device;
+ input_dev->id.vendor = sub->core->pci->subsystem_vendor;
+ input_dev->id.product = sub->core->pci->subsystem_device;
} else {
- ir->input.id.vendor = sub->core->pci->vendor;
- ir->input.id.product = sub->core->pci->device;
+ input_dev->id.vendor = sub->core->pci->vendor;
+ input_dev->id.product = sub->core->pci->device;
}
- ir->input.dev = &sub->core->pci->dev;
+ input_dev->cdev.dev = &sub->core->pci->dev;
if (ir->polling) {
INIT_WORK(&ir->work, ir_work, ir);
@@ -364,9 +440,8 @@ static int ir_probe(struct device *dev)
}
/* all done */
- dev_set_drvdata(dev,ir);
- input_register_device(&ir->input);
- printk(DEVNAME ": %s detected at %s\n",ir->input.name,ir->input.phys);
+ dev_set_drvdata(dev, ir);
+ input_register_device(ir->input);
return 0;
}
@@ -380,7 +455,7 @@ static int ir_remove(struct device *dev)
flush_scheduled_work();
}
- input_unregister_device(&ir->input);
+ input_unregister_device(ir->input);
kfree(ir);
return 0;
}
diff --git a/drivers/media/video/ir-kbd-i2c.c b/drivers/media/video/ir-kbd-i2c.c
index 67105b9804a2..0085567a1421 100644
--- a/drivers/media/video/ir-kbd-i2c.c
+++ b/drivers/media/video/ir-kbd-i2c.c
@@ -8,6 +8,8 @@
* Christoph Bartelmus <lirc@bartelmus.de>
* modified for KNC ONE TV Station/Anubis Typhoon TView Tuner by
* Ulrich Mueller <ulrich.mueller42@web.de>
+ * modified for em2820 based USB TV tuners by
+ * Markus Rechberger <mrechberger@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
@@ -37,10 +39,9 @@
#include <linux/slab.h>
#include <linux/i2c.h>
#include <linux/workqueue.h>
-
#include <asm/semaphore.h>
-
#include <media/ir-common.h>
+#include <media/ir-kbd-i2c.h>
/* Mark Phalan <phalanm@o2.ie> */
static IR_KEYTAB_TYPE ir_codes_pv951[IR_KEYTAB_SIZE] = {
@@ -81,58 +82,6 @@ static IR_KEYTAB_TYPE ir_codes_pv951[IR_KEYTAB_SIZE] = {
[ 28 ] = KEY_MEDIA, /* PC/TV */
};
-static IR_KEYTAB_TYPE ir_codes_purpletv[IR_KEYTAB_SIZE] = {
- [ 0x3 ] = KEY_POWER,
- [ 0x6f ] = KEY_MUTE,
- [ 0x10 ] = KEY_BACKSPACE, /* Recall */
-
- [ 0x11 ] = KEY_KP0,
- [ 0x4 ] = KEY_KP1,
- [ 0x5 ] = KEY_KP2,
- [ 0x6 ] = KEY_KP3,
- [ 0x8 ] = KEY_KP4,
- [ 0x9 ] = KEY_KP5,
- [ 0xa ] = KEY_KP6,
- [ 0xc ] = KEY_KP7,
- [ 0xd ] = KEY_KP8,
- [ 0xe ] = KEY_KP9,
- [ 0x12 ] = KEY_KPDOT, /* 100+ */
-
- [ 0x7 ] = KEY_VOLUMEUP,
- [ 0xb ] = KEY_VOLUMEDOWN,
- [ 0x1a ] = KEY_KPPLUS,
- [ 0x18 ] = KEY_KPMINUS,
- [ 0x15 ] = KEY_UP,
- [ 0x1d ] = KEY_DOWN,
- [ 0xf ] = KEY_CHANNELUP,
- [ 0x13 ] = KEY_CHANNELDOWN,
- [ 0x48 ] = KEY_ZOOM,
-
- [ 0x1b ] = KEY_VIDEO, /* Video source */
- [ 0x49 ] = KEY_LANGUAGE, /* MTS Select */
- [ 0x19 ] = KEY_SEARCH, /* Auto Scan */
-
- [ 0x4b ] = KEY_RECORD,
- [ 0x46 ] = KEY_PLAY,
- [ 0x45 ] = KEY_PAUSE, /* Pause */
- [ 0x44 ] = KEY_STOP,
- [ 0x40 ] = KEY_FORWARD, /* Forward ? */
- [ 0x42 ] = KEY_REWIND, /* Backward ? */
-
-};
-
-struct IR;
-struct IR {
- struct i2c_client c;
- struct input_dev input;
- struct ir_input_state ir;
-
- struct work_struct work;
- struct timer_list timer;
- char phys[32];
- int (*get_key)(struct IR*, u32*, u32*);
-};
-
/* ----------------------------------------------------------------------- */
/* insmod parameters */
@@ -145,7 +94,7 @@ module_param(debug, int, 0644); /* debug level (0,1,2) */
/* ----------------------------------------------------------------------- */
-static int get_key_haup(struct IR *ir, u32 *ir_key, u32 *ir_raw)
+static int get_key_haup(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
{
unsigned char buf[3];
int start, toggle, dev, code;
@@ -172,9 +121,9 @@ static int get_key_haup(struct IR *ir, u32 *ir_key, u32 *ir_raw)
return 1;
}
-static int get_key_pixelview(struct IR *ir, u32 *ir_key, u32 *ir_raw)
+static int get_key_pixelview(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
{
- unsigned char b;
+ unsigned char b;
/* poll IR chip */
if (1 != i2c_master_recv(&ir->c,&b,1)) {
@@ -186,9 +135,9 @@ static int get_key_pixelview(struct IR *ir, u32 *ir_key, u32 *ir_raw)
return 1;
}
-static int get_key_pv951(struct IR *ir, u32 *ir_key, u32 *ir_raw)
+static int get_key_pv951(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
{
- unsigned char b;
+ unsigned char b;
/* poll IR chip */
if (1 != i2c_master_recv(&ir->c,&b,1)) {
@@ -206,7 +155,7 @@ static int get_key_pv951(struct IR *ir, u32 *ir_key, u32 *ir_raw)
return 1;
}
-static int get_key_knc1(struct IR *ir, u32 *ir_key, u32 *ir_raw)
+static int get_key_knc1(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
{
unsigned char b;
@@ -217,15 +166,15 @@ static int get_key_knc1(struct IR *ir, u32 *ir_key, u32 *ir_raw)
}
/* it seems that 0xFE indicates that a button is still hold
- down, while 0xFF indicates that no button is hold
- down. 0xFE sequences are sometimes interrupted by 0xFF */
+ down, while 0xff indicates that no button is hold
+ down. 0xfe sequences are sometimes interrupted by 0xFF */
dprintk(2,"key %02x\n", b);
- if (b == 0xFF)
+ if (b == 0xff)
return 0;
- if (b == 0xFE)
+ if (b == 0xfe)
/* keep old data */
return 1;
@@ -234,31 +183,9 @@ static int get_key_knc1(struct IR *ir, u32 *ir_key, u32 *ir_raw)
return 1;
}
-static int get_key_purpletv(struct IR *ir, u32 *ir_key, u32 *ir_raw)
-{
- unsigned char b;
-
- /* poll IR chip */
- if (1 != i2c_master_recv(&ir->c,&b,1)) {
- dprintk(1,"read error\n");
- return -EIO;
- }
-
- /* no button press */
- if (b==0)
- return 0;
-
- /* repeating */
- if (b & 0x80)
- return 1;
-
- *ir_key = b;
- *ir_raw = b;
- return 1;
-}
/* ----------------------------------------------------------------------- */
-static void ir_key_poll(struct IR *ir)
+static void ir_key_poll(struct IR_i2c *ir)
{
static u32 ir_key, ir_raw;
int rc;
@@ -271,21 +198,21 @@ static void ir_key_poll(struct IR *ir)
}
if (0 == rc) {
- ir_input_nokey(&ir->input,&ir->ir);
+ ir_input_nokey(ir->input, &ir->ir);
} else {
- ir_input_keydown(&ir->input,&ir->ir, ir_key, ir_raw);
+ ir_input_keydown(ir->input, &ir->ir, ir_key, ir_raw);
}
}
static void ir_timer(unsigned long data)
{
- struct IR *ir = (struct IR*)data;
+ struct IR_i2c *ir = (struct IR_i2c*)data;
schedule_work(&ir->work);
}
static void ir_work(void *data)
{
- struct IR *ir = data;
+ struct IR_i2c *ir = data;
ir_key_poll(ir);
mod_timer(&ir->timer, jiffies+HZ/10);
}
@@ -298,17 +225,17 @@ static int ir_detach(struct i2c_client *client);
static int ir_probe(struct i2c_adapter *adap);
static struct i2c_driver driver = {
- .name = "ir remote kbd driver",
- .id = I2C_DRIVERID_EXP3, /* FIXME */
- .flags = I2C_DF_NOTIFY,
- .attach_adapter = ir_probe,
- .detach_client = ir_detach,
+ .name = "ir remote kbd driver",
+ .id = I2C_DRIVERID_EXP3, /* FIXME */
+ .flags = I2C_DF_NOTIFY,
+ .attach_adapter = ir_probe,
+ .detach_client = ir_detach,
};
static struct i2c_client client_template =
{
- .name = "unset",
- .driver = &driver
+ .name = "unset",
+ .driver = &driver
};
static int ir_attach(struct i2c_adapter *adap, int addr,
@@ -317,12 +244,19 @@ static int ir_attach(struct i2c_adapter *adap, int addr,
IR_KEYTAB_TYPE *ir_codes = NULL;
char *name;
int ir_type;
- struct IR *ir;
+ struct IR_i2c *ir;
+ struct input_dev *input_dev;
- if (NULL == (ir = kmalloc(sizeof(struct IR),GFP_KERNEL)))
+ ir = kzalloc(sizeof(struct IR_i2c), GFP_KERNEL);
+ input_dev = input_allocate_device();
+ if (!ir || !input_dev) {
+ kfree(ir);
+ input_free_device(input_dev);
return -ENOMEM;
- memset(ir,0,sizeof(*ir));
+ }
+
ir->c = client_template;
+ ir->input = input_dev;
i2c_set_clientdata(&ir->c, ir);
ir->c.adapter = adap;
@@ -355,10 +289,10 @@ static int ir_attach(struct i2c_adapter *adap, int addr,
ir_codes = ir_codes_empty;
break;
case 0x7a:
- name = "Purple TV";
- ir->get_key = get_key_purpletv;
+ case 0x47:
+ /* Handled by saa7134-input */
+ name = "SAA713x remote";
ir_type = IR_TYPE_OTHER;
- ir_codes = ir_codes_purpletv;
break;
default:
/* shouldn't happen */
@@ -367,21 +301,36 @@ static int ir_attach(struct i2c_adapter *adap, int addr,
return -1;
}
- /* register i2c device */
- i2c_attach_client(&ir->c);
+ /* Sets name */
snprintf(ir->c.name, sizeof(ir->c.name), "i2c IR (%s)", name);
+ ir->ir_codes=ir_codes;
+
+ /* register i2c device
+ * At device register, IR codes may be changed to be
+ * board dependent.
+ */
+ i2c_attach_client(&ir->c);
+
+ /* If IR not supported or disabled, unregisters driver */
+ if (ir->get_key == NULL) {
+ i2c_detach_client(&ir->c);
+ kfree(ir);
+ return -1;
+ }
+
+ /* Phys addr can only be set after attaching (for ir->c.dev.bus_id) */
snprintf(ir->phys, sizeof(ir->phys), "%s/%s/ir0",
ir->c.adapter->dev.bus_id,
ir->c.dev.bus_id);
/* init + register input device */
- ir_input_init(&ir->input,&ir->ir,ir_type,ir_codes);
- ir->input.id.bustype = BUS_I2C;
- ir->input.name = ir->c.name;
- ir->input.phys = ir->phys;
- input_register_device(&ir->input);
- printk(DEVNAME ": %s detected at %s [%s]\n",
- ir->input.name,ir->input.phys,adap->name);
+ ir_input_init(input_dev, &ir->ir, ir_type, ir_codes);
+ input_dev->id.bustype = BUS_I2C;
+ input_dev->name = ir->c.name;
+ input_dev->phys = ir->phys;
+
+ /* register event device */
+ input_register_device(ir->input);
/* start polling via eventd */
INIT_WORK(&ir->work, ir_work, ir);
@@ -395,14 +344,14 @@ static int ir_attach(struct i2c_adapter *adap, int addr,
static int ir_detach(struct i2c_client *client)
{
- struct IR *ir = i2c_get_clientdata(client);
+ struct IR_i2c *ir = i2c_get_clientdata(client);
/* kill outstanding polls */
del_timer(&ir->timer);
flush_scheduled_work();
/* unregister devices */
- input_unregister_device(&ir->input);
+ input_unregister_device(ir->input);
i2c_detach_client(&ir->c);
/* free memory */
@@ -423,9 +372,12 @@ static int ir_probe(struct i2c_adapter *adap)
*/
static const int probe_bttv[] = { 0x1a, 0x18, 0x4b, 0x64, 0x30, -1};
- static const int probe_saa7134[] = { 0x7a, -1 };
+ static const int probe_saa7134[] = { 0x7a, 0x47, -1 };
+ static const int probe_em28XX[] = { 0x30, 0x47, -1 };
const int *probe = NULL;
- struct i2c_client c; char buf; int i,rc;
+ struct i2c_client c;
+ unsigned char buf;
+ int i,rc;
switch (adap->id) {
case I2C_HW_B_BT848:
@@ -434,6 +386,9 @@ static int ir_probe(struct i2c_adapter *adap)
case I2C_HW_SAA7134:
probe = probe_saa7134;
break;
+ case I2C_HW_B_EM28XX:
+ probe = probe_em28XX;
+ break;
}
if (NULL == probe)
return 0;
@@ -442,11 +397,11 @@ static int ir_probe(struct i2c_adapter *adap)
c.adapter = adap;
for (i = 0; -1 != probe[i]; i++) {
c.addr = probe[i];
- rc = i2c_master_recv(&c,&buf,1);
+ rc = i2c_master_recv(&c,&buf,0);
dprintk(1,"probe 0x%02x @ %s: %s\n",
probe[i], adap->name,
- (1 == rc) ? "yes" : "no");
- if (1 == rc) {
+ (0 == rc) ? "yes" : "no");
+ if (0 == rc) {
ir_attach(adap,probe[i],0,0);
break;
}
diff --git a/drivers/media/video/msp3400.c b/drivers/media/video/msp3400.c
index f0d43fc2632f..a23fb0338986 100644
--- a/drivers/media/video/msp3400.c
+++ b/drivers/media/video/msp3400.c
@@ -54,9 +54,41 @@
#include <asm/pgtable.h>
#include <media/audiochip.h>
-#include <media/id.h>
#include "msp3400.h"
+#define msp3400_dbg(fmt, arg...) \
+ do { \
+ if (debug) \
+ printk(KERN_INFO "%s debug %d-%04x: " fmt, client->driver->name, \
+ i2c_adapter_id(client->adapter), client->addr , ## arg); \
+ } while (0)
+
+/* Medium volume debug. */
+#define msp3400_dbg_mediumvol(fmt, arg...) \
+ do { \
+ if (debug >= 2) \
+ printk(KERN_INFO "%s debug %d-%04x: " fmt, client->driver->name, \
+ i2c_adapter_id(client->adapter), client->addr , ## arg); \
+ } while (0)
+
+/* High volume debug. Use with care. */
+#define msp3400_dbg_highvol(fmt, arg...) \
+ do { \
+ if (debug >= 16) \
+ printk(KERN_INFO "%s debug %d-%04x: " fmt, client->driver->name, \
+ i2c_adapter_id(client->adapter), client->addr , ## arg); \
+ } while (0)
+
+#define msp3400_err(fmt, arg...) do { \
+ printk(KERN_ERR "%s %d-%04x: " fmt, client->driver->name, \
+ i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0)
+#define msp3400_warn(fmt, arg...) do { \
+ printk(KERN_WARNING "%s %d-%04x: " fmt, client->driver->name, \
+ i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0)
+#define msp3400_info(fmt, arg...) do { \
+ printk(KERN_INFO "%s %d-%04x: " fmt, client->driver->name, \
+ i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0)
+
#define OPMODE_AUTO -1
#define OPMODE_MANUAL 0
#define OPMODE_SIMPLE 1 /* use short programming (>= msp3410 only) */
@@ -73,15 +105,26 @@ static int dolby = 0;
static int stereo_threshold = 0x190; /* a2 threshold for stereo/bilingual
(msp34xxg only) 0x00a0-0x03c0 */
+#define DFP_COUNT 0x41
+static const int bl_dfp[] = {
+ 0x00, 0x01, 0x02, 0x03, 0x06, 0x08, 0x09, 0x0a,
+ 0x0b, 0x0d, 0x0e, 0x10
+};
+
+#define IS_MSP34XX_G(msp) ((msp)->opmode==2)
struct msp3400c {
int rev1,rev2;
int opmode;
+ int nicam;
int mode;
int norm;
+ int stereo;
int nicam_on;
int acb;
+ int in_scart;
+ int i2s_mode;
int main, second; /* sound carrier */
int input;
int source; /* see msp34xxg_set_source */
@@ -91,9 +134,12 @@ struct msp3400c {
int rxsubchans;
int muted;
- int volume, balance;
+ int left, right; /* volume */
int bass, treble;
+ /* shadow register set */
+ int dfp_regs[DFP_COUNT];
+
/* thread */
struct task_struct *kthread;
wait_queue_head_t wq;
@@ -101,6 +147,8 @@ struct msp3400c {
int watch_stereo:1;
};
+#define MIN(a,b) (((a)>(b))?(b):(a))
+#define MAX(a,b) (((a)>(b))?(a):(b))
#define HAVE_NICAM(msp) (((msp->rev2>>8) & 0xff) != 00)
#define HAVE_SIMPLE(msp) ((msp->rev1 & 0xff) >= 'D'-'@')
#define HAVE_SIMPLER(msp) ((msp->rev1 & 0xff) >= 'G'-'@')
@@ -110,9 +158,6 @@ struct msp3400c {
/* ---------------------------------------------------------------------- */
-#define dprintk if (debug >= 1) printk
-#define d2printk if (debug >= 2) printk
-
/* read-only */
module_param(opmode, int, 0444);
@@ -132,11 +177,6 @@ MODULE_PARM_DESC(standard, "Specify audio standard: 32 = NTSC, 64 = radio, Defau
MODULE_PARM_DESC(amsound, "Hardwire AM sound at 6.5Hz (France), FM can autoscan");
MODULE_PARM_DESC(dolby, "Activates Dolby processsing");
-
-MODULE_DESCRIPTION("device driver for msp34xx TV sound processor");
-MODULE_AUTHOR("Gerd Knorr");
-MODULE_LICENSE("Dual BSD/GPL"); /* FreeBSD uses this too */
-
/* ---------------------------------------------------------------------- */
#define I2C_MSP3400C 0x80
@@ -153,6 +193,10 @@ static unsigned short normal_i2c[] = {
};
I2C_CLIENT_INSMOD;
+MODULE_DESCRIPTION("device driver for msp34xx TV sound processor");
+MODULE_AUTHOR("Gerd Knorr");
+MODULE_LICENSE("GPL");
+
/* ----------------------------------------------------------------------- */
/* functions for talking to the MSP3400C Sound processor */
@@ -172,68 +216,73 @@ static int msp3400c_reset(struct i2c_client *client)
{ client->addr, I2C_M_RD, 2, read },
};
+ msp3400_dbg_highvol("msp3400c_reset\n");
if ( (1 != i2c_transfer(client->adapter,&reset[0],1)) ||
(1 != i2c_transfer(client->adapter,&reset[1],1)) ||
(2 != i2c_transfer(client->adapter,test,2)) ) {
- printk(KERN_ERR "msp3400: chip reset failed\n");
+ msp3400_err("chip reset failed\n");
return -1;
- }
+ }
return 0;
}
-static int
-msp3400c_read(struct i2c_client *client, int dev, int addr)
+static int msp3400c_read(struct i2c_client *client, int dev, int addr)
{
- int err;
+ int err,retval;
+
+ unsigned char write[3];
+ unsigned char read[2];
+ struct i2c_msg msgs[2] = {
+ { client->addr, 0, 3, write },
+ { client->addr, I2C_M_RD, 2, read }
+ };
- unsigned char write[3];
- unsigned char read[2];
- struct i2c_msg msgs[2] = {
- { client->addr, 0, 3, write },
- { client->addr, I2C_M_RD, 2, read }
- };
- write[0] = dev+1;
- write[1] = addr >> 8;
- write[2] = addr & 0xff;
+ write[0] = dev+1;
+ write[1] = addr >> 8;
+ write[2] = addr & 0xff;
for (err = 0; err < 3;) {
if (2 == i2c_transfer(client->adapter,msgs,2))
break;
err++;
- printk(KERN_WARNING "msp34xx: I/O error #%d (read 0x%02x/0x%02x)\n",
- err, dev, addr);
- msleep(10);
+ msp3400_warn("I/O error #%d (read 0x%02x/0x%02x)\n", err,
+ dev, addr);
+ current->state = TASK_INTERRUPTIBLE;
+ schedule_timeout(msecs_to_jiffies(10));
}
if (3 == err) {
- printk(KERN_WARNING "msp34xx: giving up, reseting chip. Sound will go off, sorry folks :-|\n");
+ msp3400_warn("giving up, resetting chip. Sound will go off, sorry folks :-|\n");
msp3400c_reset(client);
return -1;
}
- return read[0] << 8 | read[1];
+ retval = read[0] << 8 | read[1];
+ msp3400_dbg_highvol("msp3400c_read(0x%x, 0x%x): 0x%x\n", dev, addr, retval);
+ return retval;
}
-static int
-msp3400c_write(struct i2c_client *client, int dev, int addr, int val)
+static int msp3400c_write(struct i2c_client *client, int dev, int addr, int val)
{
int err;
- unsigned char buffer[5];
+ unsigned char buffer[5];
- buffer[0] = dev;
- buffer[1] = addr >> 8;
- buffer[2] = addr & 0xff;
- buffer[3] = val >> 8;
- buffer[4] = val & 0xff;
+ buffer[0] = dev;
+ buffer[1] = addr >> 8;
+ buffer[2] = addr & 0xff;
+ buffer[3] = val >> 8;
+ buffer[4] = val & 0xff;
+ msp3400_dbg_highvol("msp3400c_write(0x%x, 0x%x, 0x%x)\n", dev, addr, val);
for (err = 0; err < 3;) {
if (5 == i2c_master_send(client, buffer, 5))
break;
err++;
- printk(KERN_WARNING "msp34xx: I/O error #%d (write 0x%02x/0x%02x)\n",
- err, dev, addr);
- msleep(10);
+ msp3400_warn("I/O error #%d (write 0x%02x/0x%02x)\n", err,
+ dev, addr);
+ current->state = TASK_INTERRUPTIBLE;
+ schedule_timeout(msecs_to_jiffies(10));
}
if (3 == err) {
- printk(KERN_WARNING "msp34xx: giving up, reseting chip. Sound will go off, sorry folks :-|\n");
+ msp3400_warn("giving up, reseting chip. Sound will go off, sorry folks :-|\n");
msp3400c_reset(client);
return -1;
}
@@ -266,45 +315,47 @@ static struct MSP_INIT_DATA_DEM {
int dfp_src;
int dfp_matrix;
} msp_init_data[] = {
- /* AM (for carrier detect / msp3400) */
- { { 75, 19, 36, 35, 39, 40 }, { 75, 19, 36, 35, 39, 40 },
- MSP_CARRIER(5.5), MSP_CARRIER(5.5),
- 0x00d0, 0x0500, 0x0020, 0x3000},
-
- /* AM (for carrier detect / msp3410) */
- { { -1, -1, -8, 2, 59, 126 }, { -1, -1, -8, 2, 59, 126 },
- MSP_CARRIER(5.5), MSP_CARRIER(5.5),
- 0x00d0, 0x0100, 0x0020, 0x3000},
-
- /* FM Radio */
- { { -8, -8, 4, 6, 78, 107 }, { -8, -8, 4, 6, 78, 107 },
- MSP_CARRIER(10.7), MSP_CARRIER(10.7),
- 0x00d0, 0x0480, 0x0020, 0x3000 },
-
- /* Terrestial FM-mono + FM-stereo */
- { { 3, 18, 27, 48, 66, 72 }, { 3, 18, 27, 48, 66, 72 },
- MSP_CARRIER(5.5), MSP_CARRIER(5.5),
- 0x00d0, 0x0480, 0x0030, 0x3000},
-
- /* Sat FM-mono */
- { { 1, 9, 14, 24, 33, 37 }, { 3, 18, 27, 48, 66, 72 },
- MSP_CARRIER(6.5), MSP_CARRIER(6.5),
- 0x00c6, 0x0480, 0x0000, 0x3000},
-
- /* NICAM/FM -- B/G (5.5/5.85), D/K (6.5/5.85) */
- { { -2, -8, -10, 10, 50, 86 }, { 3, 18, 27, 48, 66, 72 },
- MSP_CARRIER(5.5), MSP_CARRIER(5.5),
- 0x00d0, 0x0040, 0x0120, 0x3000},
-
- /* NICAM/FM -- I (6.0/6.552) */
- { { 2, 4, -6, -4, 40, 94 }, { 3, 18, 27, 48, 66, 72 },
- MSP_CARRIER(6.0), MSP_CARRIER(6.0),
- 0x00d0, 0x0040, 0x0120, 0x3000},
-
- /* NICAM/AM -- L (6.5/5.85) */
- { { -2, -8, -10, 10, 50, 86 }, { -4, -12, -9, 23, 79, 126 },
- MSP_CARRIER(6.5), MSP_CARRIER(6.5),
- 0x00c6, 0x0140, 0x0120, 0x7c03},
+ { /* AM (for carrier detect / msp3400) */
+ {75, 19, 36, 35, 39, 40},
+ {75, 19, 36, 35, 39, 40},
+ MSP_CARRIER(5.5), MSP_CARRIER(5.5),
+ 0x00d0, 0x0500, 0x0020, 0x3000
+ },{ /* AM (for carrier detect / msp3410) */
+ {-1, -1, -8, 2, 59, 126},
+ {-1, -1, -8, 2, 59, 126},
+ MSP_CARRIER(5.5), MSP_CARRIER(5.5),
+ 0x00d0, 0x0100, 0x0020, 0x3000
+ },{ /* FM Radio */
+ {-8, -8, 4, 6, 78, 107},
+ {-8, -8, 4, 6, 78, 107},
+ MSP_CARRIER(10.7), MSP_CARRIER(10.7),
+ 0x00d0, 0x0480, 0x0020, 0x3000
+ },{ /* Terrestial FM-mono + FM-stereo */
+ {3, 18, 27, 48, 66, 72},
+ {3, 18, 27, 48, 66, 72},
+ MSP_CARRIER(5.5), MSP_CARRIER(5.5),
+ 0x00d0, 0x0480, 0x0030, 0x3000
+ },{ /* Sat FM-mono */
+ { 1, 9, 14, 24, 33, 37},
+ { 3, 18, 27, 48, 66, 72},
+ MSP_CARRIER(6.5), MSP_CARRIER(6.5),
+ 0x00c6, 0x0480, 0x0000, 0x3000
+ },{ /* NICAM/FM -- B/G (5.5/5.85), D/K (6.5/5.85) */
+ {-2, -8, -10, 10, 50, 86},
+ {3, 18, 27, 48, 66, 72},
+ MSP_CARRIER(5.5), MSP_CARRIER(5.5),
+ 0x00d0, 0x0040, 0x0120, 0x3000
+ },{ /* NICAM/FM -- I (6.0/6.552) */
+ {2, 4, -6, -4, 40, 94},
+ {3, 18, 27, 48, 66, 72},
+ MSP_CARRIER(6.0), MSP_CARRIER(6.0),
+ 0x00d0, 0x0040, 0x0120, 0x3000
+ },{ /* NICAM/AM -- L (6.5/5.85) */
+ {-2, -8, -10, 10, 50, 86},
+ {-4, -12, -9, 23, 79, 126},
+ MSP_CARRIER(6.5), MSP_CARRIER(6.5),
+ 0x00c6, 0x0140, 0x0120, 0x7c03
+ },
};
struct CARRIER_DETECT {
@@ -338,32 +389,68 @@ static struct CARRIER_DETECT carrier_detect_65[] = {
#define CARRIER_COUNT(x) (sizeof(x)/sizeof(struct CARRIER_DETECT))
-/* ----------------------------------------------------------------------- */
+/* ----------------------------------------------------------------------- *
+ * bits 9 8 5 - SCART DSP input Select:
+ * 0 0 0 - SCART 1 to DSP input (reset position)
+ * 0 1 0 - MONO to DSP input
+ * 1 0 0 - SCART 2 to DSP input
+ * 1 1 1 - Mute DSP input
+ *
+ * bits 11 10 6 - SCART 1 Output Select:
+ * 0 0 0 - undefined (reset position)
+ * 0 1 0 - SCART 2 Input to SCART 1 Output (for devices with 2 SCARTS)
+ * 1 0 0 - MONO input to SCART 1 Output
+ * 1 1 0 - SCART 1 DA to SCART 1 Output
+ * 0 0 1 - SCART 2 DA to SCART 1 Output
+ * 0 1 1 - SCART 1 Input to SCART 1 Output
+ * 1 1 1 - Mute SCART 1 Output
+ *
+ * bits 13 12 7 - SCART 2 Output Select (for devices with 2 Output SCART):
+ * 0 0 0 - SCART 1 DA to SCART 2 Output (reset position)
+ * 0 1 0 - SCART 1 Input to SCART 2 Output
+ * 1 0 0 - MONO input to SCART 2 Output
+ * 0 0 1 - SCART 2 DA to SCART 2 Output
+ * 0 1 1 - SCART 2 Input to SCART 2 Output
+ * 1 1 0 - Mute SCART 2 Output
+ *
+ * Bits 4 to 0 should be zero.
+ * ----------------------------------------------------------------------- */
static int scarts[3][9] = {
- /* MASK IN1 IN2 IN1_DA IN2_DA IN3 IN4 MONO MUTE */
- { 0x0320, 0x0000, 0x0200, -1, -1, 0x0300, 0x0020, 0x0100, 0x0320 },
- { 0x0c40, 0x0440, 0x0400, 0x0c00, 0x0040, 0x0000, 0x0840, 0x0800, 0x0c40 },
- { 0x3080, 0x1000, 0x1080, 0x0000, 0x0080, 0x2080, 0x3080, 0x2000, 0x3000 },
+ /* MASK IN1 IN2 IN1_DA IN2_DA IN3 IN4 MONO MUTE */
+ /* SCART DSP Input select */
+ { 0x0320, 0x0000, 0x0200, -1, -1, 0x0300, 0x0020, 0x0100, 0x0320 },
+ /* SCART1 Output select */
+ { 0x0c40, 0x0440, 0x0400, 0x0c00, 0x0040, 0x0000, 0x0840, 0x0800, 0x0c40 },
+ /* SCART2 Output select */
+ { 0x3080, 0x1000, 0x1080, 0x0000, 0x0080, 0x2080, 0x3080, 0x2000, 0x3000 },
};
static char *scart_names[] = {
- "mask", "in1", "in2", "in1 da", "in2 da", "in3", "in4", "mono", "mute"
+ "mask", "in1", "in2", "in1 da", "in2 da", "in3", "in4", "mono", "mute"
};
-static void
-msp3400c_set_scart(struct i2c_client *client, int in, int out)
+static void msp3400c_set_scart(struct i2c_client *client, int in, int out)
{
struct msp3400c *msp = i2c_get_clientdata(client);
- if (-1 == scarts[out][in])
- return;
+ msp->in_scart=in;
+
+ if (in >= 1 && in <= 8 && out >= 0 && out <= 2) {
+ if (-1 == scarts[out][in])
+ return;
- dprintk(KERN_DEBUG
- "msp34xx: scart switch: %s => %d\n",scart_names[in],out);
- msp->acb &= ~scarts[out][SCART_MASK];
- msp->acb |= scarts[out][in];
- msp3400c_write(client,I2C_MSP3400C_DFP, 0x0013, msp->acb);
+ msp->acb &= ~scarts[out][SCART_MASK];
+ msp->acb |= scarts[out][in];
+ } else
+ msp->acb = 0xf60; /* Mute Input and SCART 1 Output */
+
+ msp3400_dbg("scart switch: %s => %d (ACB=0x%04x)\n",
+ scart_names[in], out, msp->acb);
+ msp3400c_write(client,I2C_MSP3400C_DFP, 0x13, msp->acb);
+
+ /* Sets I2S speed 0 = 1.024 Mbps, 1 = 2.048 Mbps */
+ msp3400c_write(client,I2C_MSP3400C_DEM, 0x40, msp->i2s_mode);
}
/* ------------------------------------------------------------------------ */
@@ -378,33 +465,34 @@ static void msp3400c_setcarrier(struct i2c_client *client, int cdo1, int cdo2)
}
static void msp3400c_setvolume(struct i2c_client *client,
- int muted, int volume, int balance)
-{
- int val = 0, bal = 0;
+ int muted, int left, int right)
+ {
+ int vol = 0, val = 0, balance = 0;
if (!muted) {
/* 0x7f instead if 0x73 here has sound quality issues,
* probably due to overmodulation + clipping ... */
- val = (volume * 0x73 / 65535) << 8;
+ vol = (left > right) ? left : right;
+ val = (vol * 0x73 / 65535) << 8;
}
- if (val) {
- bal = (balance / 256) - 128;
+ if (vol > 0) {
+ balance = ((right - left) * 127) / vol;
}
- dprintk(KERN_DEBUG
- "msp34xx: setvolume: mute=%s %d:%d v=0x%02x b=0x%02x\n",
- muted ? "on" : "off", volume, balance, val>>8, bal);
+
+ msp3400_dbg("setvolume: mute=%s %d:%d v=0x%02x b=0x%02x\n",
+ muted ? "on" : "off", left, right, val >> 8, balance);
msp3400c_write(client,I2C_MSP3400C_DFP, 0x0000, val); /* loudspeaker */
msp3400c_write(client,I2C_MSP3400C_DFP, 0x0006, val); /* headphones */
msp3400c_write(client,I2C_MSP3400C_DFP, 0x0007,
- muted ? 0x01 : (val | 0x01));
- msp3400c_write(client,I2C_MSP3400C_DFP, 0x0001, bal << 8);
+ muted ? 0x1 : (val | 0x1));
+ msp3400c_write(client, I2C_MSP3400C_DFP, 0x0001, balance << 8);
}
static void msp3400c_setbass(struct i2c_client *client, int bass)
{
int val = ((bass-32768) * 0x60 / 65535) << 8;
- dprintk(KERN_DEBUG "msp34xx: setbass: %d 0x%02x\n",bass, val>>8);
+ msp3400_dbg("setbass: %d 0x%02x\n", bass, val >> 8);
msp3400c_write(client,I2C_MSP3400C_DFP, 0x0002, val); /* loudspeaker */
}
@@ -412,7 +500,7 @@ static void msp3400c_settreble(struct i2c_client *client, int treble)
{
int val = ((treble-32768) * 0x60 / 65535) << 8;
- dprintk(KERN_DEBUG "msp34xx: settreble: %d 0x%02x\n",treble, val>>8);
+ msp3400_dbg("settreble: %d 0x%02x\n",treble, val>>8);
msp3400c_write(client,I2C_MSP3400C_DFP, 0x0003, val); /* loudspeaker */
}
@@ -421,7 +509,7 @@ static void msp3400c_setmode(struct i2c_client *client, int type)
struct msp3400c *msp = i2c_get_clientdata(client);
int i;
- dprintk(KERN_DEBUG "msp3400: setmode: %d\n",type);
+ msp3400_dbg("setmode: %d\n",type);
msp->mode = type;
msp->audmode = V4L2_TUNER_MODE_MONO;
msp->rxsubchans = V4L2_TUNER_SUB_MONO;
@@ -474,7 +562,8 @@ static void msp3400c_setmode(struct i2c_client *client, int type)
}
}
-static int best_audio_mode(int rxsubchans)
+/* given a bitmask of VIDEO_SOUND_XXX returns the "best" in the bitmask */
+static int best_video_sound(int rxsubchans)
{
if (rxsubchans & V4L2_TUNER_SUB_STEREO)
return V4L2_TUNER_MODE_STEREO;
@@ -486,31 +575,31 @@ static int best_audio_mode(int rxsubchans)
}
/* turn on/off nicam + stereo */
-static void msp3400c_set_audmode(struct i2c_client *client, int audmode)
+static void msp3400c_setstereo(struct i2c_client *client, int mode)
{
- static char *strmode[16] = {
-#if __GNUC__ >= 3
- [ 0 ... 15 ] = "invalid",
-#endif
- [ V4L2_TUNER_MODE_MONO ] = "mono",
- [ V4L2_TUNER_MODE_STEREO ] = "stereo",
- [ V4L2_TUNER_MODE_LANG1 ] = "lang1",
- [ V4L2_TUNER_MODE_LANG2 ] = "lang2",
+ static char *strmode[] = { "0", "mono", "stereo", "3",
+ "lang1", "5", "6", "7", "lang2"
};
struct msp3400c *msp = i2c_get_clientdata(client);
- int nicam=0; /* channel source: FM/AM or nicam */
- int src=0;
+ int nicam = 0; /* channel source: FM/AM or nicam */
+ int src = 0;
- BUG_ON(msp->opmode == OPMODE_SIMPLER);
- msp->audmode = audmode;
+ if (IS_MSP34XX_G(msp)) {
+ /* this method would break everything, let's make sure
+ * it's never called
+ */
+ msp3400_dbg
+ ("DEBUG WARNING setstereo called with mode=%d instead of set_source (ignored)\n",
+ mode);
+ return;
+ }
/* switch demodulator */
switch (msp->mode) {
case MSP_MODE_FM_TERRA:
- dprintk(KERN_DEBUG "msp3400: FM setstereo: %s\n",
- strmode[audmode]);
+ msp3400_dbg("FM setstereo: %s\n", strmode[mode]);
msp3400c_setcarrier(client,msp->second,msp->main);
- switch (audmode) {
+ switch (mode) {
case V4L2_TUNER_MODE_STEREO:
msp3400c_write(client,I2C_MSP3400C_DFP, 0x000e, 0x3001);
break;
@@ -522,9 +611,8 @@ static void msp3400c_set_audmode(struct i2c_client *client, int audmode)
}
break;
case MSP_MODE_FM_SAT:
- dprintk(KERN_DEBUG "msp3400: SAT setstereo: %s\n",
- strmode[audmode]);
- switch (audmode) {
+ msp3400_dbg("SAT setstereo: %s\n", strmode[mode]);
+ switch (mode) {
case V4L2_TUNER_MODE_MONO:
msp3400c_setcarrier(client, MSP_CARRIER(6.5), MSP_CARRIER(6.5));
break;
@@ -542,39 +630,35 @@ static void msp3400c_set_audmode(struct i2c_client *client, int audmode)
case MSP_MODE_FM_NICAM1:
case MSP_MODE_FM_NICAM2:
case MSP_MODE_AM_NICAM:
- dprintk(KERN_DEBUG "msp3400: NICAM setstereo: %s\n",
- strmode[audmode]);
+ msp3400_dbg("NICAM setstereo: %s\n",strmode[mode]);
msp3400c_setcarrier(client,msp->second,msp->main);
if (msp->nicam_on)
nicam=0x0100;
break;
case MSP_MODE_BTSC:
- dprintk(KERN_DEBUG "msp3400: BTSC setstereo: %s\n",
- strmode[audmode]);
+ msp3400_dbg("BTSC setstereo: %s\n",strmode[mode]);
nicam=0x0300;
break;
case MSP_MODE_EXTERN:
- dprintk(KERN_DEBUG "msp3400: extern setstereo: %s\n",
- strmode[audmode]);
+ msp3400_dbg("extern setstereo: %s\n",strmode[mode]);
nicam = 0x0200;
break;
case MSP_MODE_FM_RADIO:
- dprintk(KERN_DEBUG "msp3400: FM-Radio setstereo: %s\n",
- strmode[audmode]);
+ msp3400_dbg("FM-Radio setstereo: %s\n",strmode[mode]);
break;
default:
- dprintk(KERN_DEBUG "msp3400: mono setstereo\n");
+ msp3400_dbg("mono setstereo\n");
return;
}
/* switch audio */
- switch (audmode) {
+ switch (best_video_sound(mode)) {
case V4L2_TUNER_MODE_STEREO:
src = 0x0020 | nicam;
break;
case V4L2_TUNER_MODE_MONO:
if (msp->mode == MSP_MODE_AM_NICAM) {
- dprintk("msp3400: switching to AM mono\n");
+ msp3400_dbg("switching to AM mono\n");
/* AM mono decoding is handled by tuner, not MSP chip */
/* SCART switching control register */
msp3400c_set_scart(client,SCART_MONO,0);
@@ -588,8 +672,7 @@ static void msp3400c_set_audmode(struct i2c_client *client, int audmode)
src = 0x0010 | nicam;
break;
}
- dprintk(KERN_DEBUG
- "msp3400: setstereo final source/matrix = 0x%x\n", src);
+ msp3400_dbg("setstereo final source/matrix = 0x%x\n", src);
if (dolby) {
msp3400c_write(client,I2C_MSP3400C_DFP, 0x0008,0x0520);
@@ -605,29 +688,55 @@ static void msp3400c_set_audmode(struct i2c_client *client, int audmode)
}
static void
-msp3400c_print_mode(struct msp3400c *msp)
+msp3400c_print_mode(struct i2c_client *client)
{
+ struct msp3400c *msp = i2c_get_clientdata(client);
+
if (msp->main == msp->second) {
- printk(KERN_DEBUG "msp3400: mono sound carrier: %d.%03d MHz\n",
+ msp3400_dbg("mono sound carrier: %d.%03d MHz\n",
msp->main/910000,(msp->main/910)%1000);
} else {
- printk(KERN_DEBUG "msp3400: main sound carrier: %d.%03d MHz\n",
+ msp3400_dbg("main sound carrier: %d.%03d MHz\n",
msp->main/910000,(msp->main/910)%1000);
}
- if (msp->mode == MSP_MODE_FM_NICAM1 ||
- msp->mode == MSP_MODE_FM_NICAM2)
- printk(KERN_DEBUG "msp3400: NICAM/FM carrier : %d.%03d MHz\n",
+ if (msp->mode == MSP_MODE_FM_NICAM1 || msp->mode == MSP_MODE_FM_NICAM2)
+ msp3400_dbg("NICAM/FM carrier : %d.%03d MHz\n",
msp->second/910000,(msp->second/910)%1000);
if (msp->mode == MSP_MODE_AM_NICAM)
- printk(KERN_DEBUG "msp3400: NICAM/AM carrier : %d.%03d MHz\n",
+ msp3400_dbg("NICAM/AM carrier : %d.%03d MHz\n",
msp->second/910000,(msp->second/910)%1000);
if (msp->mode == MSP_MODE_FM_TERRA &&
msp->main != msp->second) {
- printk(KERN_DEBUG "msp3400: FM-stereo carrier : %d.%03d MHz\n",
+ msp3400_dbg("FM-stereo carrier : %d.%03d MHz\n",
msp->second/910000,(msp->second/910)%1000);
}
}
+#define MSP3400_MAX 4
+static struct i2c_client *msps[MSP3400_MAX];
+static void msp3400c_restore_dfp(struct i2c_client *client)
+{
+ struct msp3400c *msp = i2c_get_clientdata(client);
+ int i;
+
+ for (i = 0; i < DFP_COUNT; i++) {
+ if (-1 == msp->dfp_regs[i])
+ continue;
+ msp3400c_write(client, I2C_MSP3400C_DFP, i, msp->dfp_regs[i]);
+ }
+}
+
+/* if the dfp_regs is set, set what's in there. Otherwise, set the default value */
+static int msp3400c_write_dfp_with_default(struct i2c_client *client,
+ int addr, int default_value)
+{
+ struct msp3400c *msp = i2c_get_clientdata(client);
+ int value = default_value;
+ if (addr < DFP_COUNT && -1 != msp->dfp_regs[addr])
+ value = msp->dfp_regs[addr];
+ return msp3400c_write(client, I2C_MSP3400C_DFP, addr, value);
+}
+
/* ----------------------------------------------------------------------- */
struct REGISTER_DUMP {
@@ -635,8 +744,15 @@ struct REGISTER_DUMP {
char *name;
};
-static int
-autodetect_stereo(struct i2c_client *client)
+struct REGISTER_DUMP d1[] = {
+ {0x007e, "autodetect"},
+ {0x0023, "C_AD_BITS "},
+ {0x0038, "ADD_BITS "},
+ {0x003e, "CIB_BITS "},
+ {0x0057, "ERROR_RATE"},
+};
+
+static int autodetect_stereo(struct i2c_client *client)
{
struct msp3400c *msp = i2c_get_clientdata(client);
int val;
@@ -649,8 +765,7 @@ autodetect_stereo(struct i2c_client *client)
val = msp3400c_read(client, I2C_MSP3400C_DFP, 0x18);
if (val > 32767)
val -= 65536;
- dprintk(KERN_DEBUG
- "msp34xx: stereo detect register: %d\n",val);
+ msp3400_dbg("stereo detect register: %d\n",val);
if (val > 4096) {
rxsubchans = V4L2_TUNER_SUB_STEREO | V4L2_TUNER_SUB_MONO;
} else if (val < -4096) {
@@ -664,8 +779,7 @@ autodetect_stereo(struct i2c_client *client)
case MSP_MODE_FM_NICAM2:
case MSP_MODE_AM_NICAM:
val = msp3400c_read(client, I2C_MSP3400C_DEM, 0x23);
- dprintk(KERN_DEBUG
- "msp34xx: nicam sync=%d, mode=%d\n",
+ msp3400_dbg("nicam sync=%d, mode=%d\n",
val & 1, (val & 0x1e) >> 1);
if (val & 1) {
@@ -698,8 +812,7 @@ autodetect_stereo(struct i2c_client *client)
break;
case MSP_MODE_BTSC:
val = msp3400c_read(client, I2C_MSP3400C_DEM, 0x200);
- dprintk(KERN_DEBUG
- "msp3410: status=0x%x (pri=%s, sec=%s, %s%s%s)\n",
+ msp3400_dbg("status=0x%x (pri=%s, sec=%s, %s%s%s)\n",
val,
(val & 0x0002) ? "no" : "yes",
(val & 0x0004) ? "no" : "yes",
@@ -713,13 +826,13 @@ autodetect_stereo(struct i2c_client *client)
}
if (rxsubchans != msp->rxsubchans) {
update = 1;
- dprintk(KERN_DEBUG "msp34xx: watch: rxsubchans %d => %d\n",
+ msp3400_dbg("watch: rxsubchans %d => %d\n",
msp->rxsubchans,rxsubchans);
msp->rxsubchans = rxsubchans;
}
if (newnicam != msp->nicam_on) {
update = 1;
- dprintk(KERN_DEBUG "msp34xx: watch: nicam %d => %d\n",
+ msp3400_dbg("watch: nicam %d => %d\n",
msp->nicam_on,newnicam);
msp->nicam_on = newnicam;
}
@@ -741,8 +854,8 @@ static int msp34xx_sleep(struct msp3400c *msp, int timeout)
set_current_state(TASK_INTERRUPTIBLE);
schedule();
} else {
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(msecs_to_jiffies(timeout));
+ schedule_timeout_interruptible
+ (msecs_to_jiffies(timeout));
}
}
@@ -756,8 +869,15 @@ static void watch_stereo(struct i2c_client *client)
{
struct msp3400c *msp = i2c_get_clientdata(client);
- if (autodetect_stereo(client))
- msp3400c_set_audmode(client,best_audio_mode(msp->rxsubchans));
+ if (autodetect_stereo(client)) {
+ if (msp->stereo & V4L2_TUNER_MODE_STEREO)
+ msp3400c_setstereo(client, V4L2_TUNER_MODE_STEREO);
+ else if (msp->stereo & VIDEO_SOUND_LANG1)
+ msp3400c_setstereo(client, V4L2_TUNER_MODE_LANG1);
+ else
+ msp3400c_setstereo(client, V4L2_TUNER_MODE_MONO);
+ }
+
if (once)
msp->watch_stereo = 0;
}
@@ -769,14 +889,14 @@ static int msp3400c_thread(void *data)
struct CARRIER_DETECT *cd;
int count, max1,max2,val1,val2, val,this;
- printk("msp3400: kthread started\n");
+ msp3400_info("msp3400 daemon started\n");
for (;;) {
- d2printk("msp3400: thread: sleep\n");
+ msp3400_dbg_mediumvol("msp3400 thread: sleep\n");
msp34xx_sleep(msp,-1);
- d2printk("msp3400: thread: wakeup\n");
+ msp3400_dbg_mediumvol("msp3400 thread: wakeup\n");
restart:
- dprintk("msp3410: thread: restart scan\n");
+ msp3400_dbg("thread: restart scan\n");
msp->restart = 0;
if (kthread_should_stop())
break;
@@ -784,9 +904,8 @@ static int msp3400c_thread(void *data)
if (VIDEO_MODE_RADIO == msp->norm ||
MSP_MODE_EXTERN == msp->mode) {
/* no carrier scan, just unmute */
- printk("msp3400: thread: no carrier scan\n");
- msp3400c_setvolume(client, msp->muted,
- msp->volume, msp->balance);
+ msp3400_info("thread: no carrier scan\n");
+ msp3400c_setvolume(client, msp->muted, msp->left, msp->right);
continue;
}
@@ -802,13 +921,14 @@ static int msp3400c_thread(void *data)
goto restart;
/* carrier detect pass #1 -- main carrier */
- cd = carrier_detect_main; count = CARRIER_COUNT(carrier_detect_main);
+ cd = carrier_detect_main;
+ count = CARRIER_COUNT(carrier_detect_main);
if (amsound && (msp->norm == VIDEO_MODE_SECAM)) {
/* autodetect doesn't work well with AM ... */
max1 = 3;
count = 0;
- dprintk("msp3400: AM sound override\n");
+ msp3400_dbg("AM sound override\n");
}
for (this = 0; this < count; this++) {
@@ -820,7 +940,7 @@ static int msp3400c_thread(void *data)
val -= 65536;
if (val1 < val)
val1 = val, max1 = this;
- dprintk("msp3400: carrier1 val: %5d / %s\n", val,cd[this].name);
+ msp3400_dbg("carrier1 val: %5d / %s\n", val,cd[this].name);
}
/* carrier detect pass #2 -- second (stereo) carrier */
@@ -836,13 +956,16 @@ static int msp3400c_thread(void *data)
case 0: /* 4.5 */
case 2: /* 6.0 */
default:
- cd = NULL; count = 0;
+ cd = NULL;
+ count = 0;
break;
}
if (amsound && (msp->norm == VIDEO_MODE_SECAM)) {
/* autodetect doesn't work well with AM ... */
- cd = NULL; count = 0; max2 = 0;
+ cd = NULL;
+ count = 0;
+ max2 = 0;
}
for (this = 0; this < count; this++) {
msp3400c_setcarrier(client, cd[this].cdo,cd[this].cdo);
@@ -853,7 +976,7 @@ static int msp3400c_thread(void *data)
val -= 65536;
if (val2 < val)
val2 = val, max2 = this;
- dprintk("msp3400: carrier2 val: %5d / %s\n", val,cd[this].name);
+ msp3400_dbg("carrier2 val: %5d / %s\n", val,cd[this].name);
}
/* programm the msp3400 according to the results */
@@ -865,7 +988,7 @@ static int msp3400c_thread(void *data)
msp->second = carrier_detect_55[max2].cdo;
msp3400c_setmode(client, MSP_MODE_FM_TERRA);
msp->nicam_on = 0;
- msp3400c_set_audmode(client, V4L2_TUNER_MODE_MONO);
+ msp3400c_setstereo(client, V4L2_TUNER_MODE_MONO);
msp->watch_stereo = 1;
} else if (max2 == 1 && HAVE_NICAM(msp)) {
/* B/G NICAM */
@@ -892,7 +1015,7 @@ static int msp3400c_thread(void *data)
msp->second = carrier_detect_65[max2].cdo;
msp3400c_setmode(client, MSP_MODE_FM_TERRA);
msp->nicam_on = 0;
- msp3400c_set_audmode(client, V4L2_TUNER_MODE_MONO);
+ msp3400c_setstereo(client, V4L2_TUNER_MODE_MONO);
msp->watch_stereo = 1;
} else if (max2 == 0 &&
msp->norm == VIDEO_MODE_SECAM) {
@@ -900,7 +1023,7 @@ static int msp3400c_thread(void *data)
msp->second = carrier_detect_65[max2].cdo;
msp3400c_setmode(client, MSP_MODE_AM_NICAM);
msp->nicam_on = 0;
- msp3400c_set_audmode(client, V4L2_TUNER_MODE_MONO);
+ msp3400c_setstereo(client, V4L2_TUNER_MODE_MONO);
msp3400c_setcarrier(client, msp->second, msp->main);
/* volume prescale for SCART (AM mono input) */
msp3400c_write(client,I2C_MSP3400C_DFP, 0x000d, 0x1900);
@@ -924,15 +1047,16 @@ static int msp3400c_thread(void *data)
msp->nicam_on = 0;
msp3400c_setcarrier(client, msp->second, msp->main);
msp->rxsubchans = V4L2_TUNER_SUB_MONO;
- msp3400c_set_audmode(client, V4L2_TUNER_MODE_MONO);
+ msp3400c_setstereo(client, V4L2_TUNER_MODE_MONO);
break;
}
/* unmute */
- msp3400c_setvolume(client, msp->muted,
- msp->volume, msp->balance);
+ msp3400c_setvolume(client, msp->muted, msp->left, msp->right);
+ msp3400c_restore_dfp(client);
+
if (debug)
- msp3400c_print_mode(msp);
+ msp3400c_print_mode(client);
/* monitor tv audio mode */
while (msp->watch_stereo) {
@@ -941,7 +1065,7 @@ static int msp3400c_thread(void *data)
watch_stereo(client);
}
}
- dprintk(KERN_DEBUG "msp3400: thread: exit\n");
+ msp3400_dbg("thread: exit\n");
return 0;
}
@@ -985,10 +1109,12 @@ static inline const char *msp34xx_standard_mode_name(int mode)
return "unknown";
}
-static int msp34xx_modus(int norm)
+static int msp34xx_modus(struct i2c_client *client, int norm)
{
switch (norm) {
case VIDEO_MODE_PAL:
+ msp3400_dbg("video mode selected to PAL\n");
+
#if 1
/* experimental: not sure this works with all chip versions */
return 0x7003;
@@ -997,12 +1123,16 @@ static int msp34xx_modus(int norm)
return 0x1003;
#endif
case VIDEO_MODE_NTSC: /* BTSC */
+ msp3400_dbg("video mode selected to NTSC\n");
return 0x2003;
case VIDEO_MODE_SECAM:
+ msp3400_dbg("video mode selected to SECAM\n");
return 0x0003;
case VIDEO_MODE_RADIO:
+ msp3400_dbg("video mode selected to Radio\n");
return 0x0003;
case VIDEO_MODE_AUTO:
+ msp3400_dbg("video mode selected to Auto\n");
return 0x2003;
default:
return 0x0003;
@@ -1031,23 +1161,22 @@ static int msp3410d_thread(void *data)
struct msp3400c *msp = i2c_get_clientdata(client);
int mode,val,i,std;
- printk("msp3410: daemon started\n");
+ msp3400_info("msp3410 daemon started\n");
for (;;) {
- d2printk(KERN_DEBUG "msp3410: thread: sleep\n");
+ msp3400_dbg_mediumvol("msp3410 thread: sleep\n");
msp34xx_sleep(msp,-1);
- d2printk(KERN_DEBUG "msp3410: thread: wakeup\n");
+ msp3400_dbg_mediumvol("msp3410 thread: wakeup\n");
restart:
- dprintk("msp3410: thread: restart scan\n");
+ msp3400_dbg("thread: restart scan\n");
msp->restart = 0;
if (kthread_should_stop())
break;
if (msp->mode == MSP_MODE_EXTERN) {
/* no carrier scan needed, just unmute */
- dprintk(KERN_DEBUG "msp3410: thread: no carrier scan\n");
- msp3400c_setvolume(client, msp->muted,
- msp->volume, msp->balance);
+ msp3400_dbg("thread: no carrier scan\n");
+ msp3400c_setvolume(client, msp->muted, msp->left, msp->right);
continue;
}
@@ -1059,14 +1188,14 @@ static int msp3410d_thread(void *data)
goto restart;
/* start autodetect */
- mode = msp34xx_modus(msp->norm);
+ mode = msp34xx_modus(client, msp->norm);
std = msp34xx_standard(msp->norm);
msp3400c_write(client, I2C_MSP3400C_DEM, 0x30, mode);
msp3400c_write(client, I2C_MSP3400C_DEM, 0x20, std);
msp->watch_stereo = 0;
if (debug)
- printk(KERN_DEBUG "msp3410: setting mode: %s (0x%04x)\n",
+ msp3400_dbg("setting mode: %s (0x%04x)\n",
msp34xx_standard_mode_name(std) ,std);
if (std != 1) {
@@ -1082,13 +1211,13 @@ static int msp3410d_thread(void *data)
val = msp3400c_read(client, I2C_MSP3400C_DEM, 0x7e);
if (val < 0x07ff)
break;
- dprintk(KERN_DEBUG "msp3410: detection still in progress\n");
+ msp3400_dbg("detection still in progress\n");
}
}
for (i = 0; modelist[i].name != NULL; i++)
if (modelist[i].retval == val)
break;
- dprintk(KERN_DEBUG "msp3410: current mode: %s (0x%04x)\n",
+ msp3400_dbg("current mode: %s (0x%04x)\n",
modelist[i].name ? modelist[i].name : "unknown",
val);
msp->main = modelist[i].main;
@@ -1096,7 +1225,7 @@ static int msp3410d_thread(void *data)
if (amsound && (msp->norm == VIDEO_MODE_SECAM) && (val != 0x0009)) {
/* autodetection has failed, let backup */
- dprintk(KERN_DEBUG "msp3410: autodetection failed,"
+ msp3400_dbg("autodetection failed,"
" switching to backup mode: %s (0x%04x)\n",
modelist[8].name ? modelist[8].name : "unknown",val);
val = 0x0009;
@@ -1120,13 +1249,13 @@ static int msp3410d_thread(void *data)
msp->rxsubchans = V4L2_TUNER_SUB_STEREO;
msp->nicam_on = 1;
msp->watch_stereo = 1;
- msp3400c_set_audmode(client,V4L2_TUNER_MODE_STEREO);
+ msp3400c_setstereo(client,V4L2_TUNER_MODE_STEREO);
break;
case 0x0009:
msp->mode = MSP_MODE_AM_NICAM;
msp->rxsubchans = V4L2_TUNER_SUB_MONO;
msp->nicam_on = 1;
- msp3400c_set_audmode(client,V4L2_TUNER_MODE_MONO);
+ msp3400c_setstereo(client,V4L2_TUNER_MODE_MONO);
msp->watch_stereo = 1;
break;
case 0x0020: /* BTSC */
@@ -1135,7 +1264,7 @@ static int msp3410d_thread(void *data)
msp->rxsubchans = V4L2_TUNER_SUB_STEREO;
msp->nicam_on = 0;
msp->watch_stereo = 1;
- msp3400c_set_audmode(client,V4L2_TUNER_MODE_STEREO);
+ msp3400c_setstereo(client,V4L2_TUNER_MODE_STEREO);
break;
case 0x0040: /* FM radio */
msp->mode = MSP_MODE_FM_RADIO;
@@ -1169,9 +1298,10 @@ static int msp3410d_thread(void *data)
/* unmute, restore misc registers */
msp3400c_setbass(client, msp->bass);
msp3400c_settreble(client, msp->treble);
- msp3400c_setvolume(client, msp->muted,
- msp->volume, msp->balance);
- msp3400c_write(client, I2C_MSP3400C_DFP, 0x0013, msp->acb);
+ msp3400c_setvolume(client, msp->muted, msp->left, msp->right);
+ msp3400c_write(client, I2C_MSP3400C_DFP, 0x13, msp->acb);
+ msp3400c_write(client,I2C_MSP3400C_DEM, 0x40, msp->i2s_mode);
+ msp3400c_restore_dfp(client);
/* monitor tv audio mode */
while (msp->watch_stereo) {
@@ -1180,7 +1310,7 @@ static int msp3410d_thread(void *data)
watch_stereo(client);
}
}
- dprintk(KERN_DEBUG "msp3410: thread: exit\n");
+ msp3400_dbg("thread: exit\n");
return 0;
}
@@ -1195,7 +1325,7 @@ static void msp34xxg_set_source(struct i2c_client *client, int source);
/* (re-)initialize the msp34xxg, according to the current norm in msp->norm
* return 0 if it worked, -1 if it failed
*/
-static int msp34xxg_init(struct i2c_client *client)
+static int msp34xxg_reset(struct i2c_client *client)
{
struct msp3400c *msp = i2c_get_clientdata(client);
int modus,std;
@@ -1210,8 +1340,10 @@ static int msp34xxg_init(struct i2c_client *client)
0x0f20 /* mute DSP input, mute SCART 1 */))
return -1;
+ msp3400c_write(client,I2C_MSP3400C_DEM, 0x40, msp->i2s_mode);
+
/* step-by-step initialisation, as described in the manual */
- modus = msp34xx_modus(msp->norm);
+ modus = msp34xx_modus(client, msp->norm);
std = msp34xx_standard(msp->norm);
modus &= ~0x03; /* STATUS_CHANGE=0 */
modus |= 0x01; /* AUTOMATIC_SOUND_DETECTION=1 */
@@ -1222,7 +1354,7 @@ static int msp34xxg_init(struct i2c_client *client)
return -1;
if (msp3400c_write(client,
I2C_MSP3400C_DEM,
- 0x20/*stanard*/,
+ 0x20/*standard*/,
std))
return -1;
@@ -1230,21 +1362,18 @@ static int msp34xxg_init(struct i2c_client *client)
standard/audio autodetection right now */
msp34xxg_set_source(client, msp->source);
- if (msp3400c_write(client, I2C_MSP3400C_DFP,
- 0x0e, /* AM/FM Prescale */
- 0x3000 /* default: [15:8] 75khz deviation */))
+ if (msp3400c_write_dfp_with_default(client, 0x0e, /* AM/FM Prescale */
+ 0x3000
+ /* default: [15:8] 75khz deviation */
+ ))
return -1;
- if (msp3400c_write(client, I2C_MSP3400C_DFP,
- 0x10, /* NICAM Prescale */
- 0x5a00 /* default: 9db gain (as recommended) */))
+ if (msp3400c_write_dfp_with_default(client, 0x10, /* NICAM Prescale */
+ 0x5a00
+ /* default: 9db gain (as recommended) */
+ ))
return -1;
- if (msp3400c_write(client,
- I2C_MSP3400C_DEM,
- 0x20, /* STANDARD SELECT */
- standard /* default: 0x01 for automatic standard select*/))
- return -1;
return 0;
}
@@ -1254,27 +1383,27 @@ static int msp34xxg_thread(void *data)
struct msp3400c *msp = i2c_get_clientdata(client);
int val, std, i;
- printk("msp34xxg: daemon started\n");
+ msp3400_info("msp34xxg daemon started\n");
msp->source = 1; /* default */
for (;;) {
- d2printk(KERN_DEBUG "msp34xxg: thread: sleep\n");
+ msp3400_dbg_mediumvol("msp34xxg thread: sleep\n");
msp34xx_sleep(msp,-1);
- d2printk(KERN_DEBUG "msp34xxg: thread: wakeup\n");
+ msp3400_dbg_mediumvol("msp34xxg thread: wakeup\n");
restart:
- dprintk("msp34xxg: thread: restart scan\n");
+ msp3400_dbg("thread: restart scan\n");
msp->restart = 0;
if (kthread_should_stop())
break;
/* setup the chip*/
- msp34xxg_init(client);
+ msp34xxg_reset(client);
std = standard;
if (std != 0x01)
goto unmute;
/* watch autodetect */
- dprintk("msp34xxg: triggered autodetect, waiting for result\n");
+ msp3400_dbg("triggered autodetect, waiting for result\n");
for (i = 0; i < 10; i++) {
if (msp34xx_sleep(msp,100))
goto restart;
@@ -1285,23 +1414,23 @@ static int msp34xxg_thread(void *data)
std = val;
break;
}
- dprintk("msp34xxg: detection still in progress\n");
+ msp3400_dbg("detection still in progress\n");
}
if (0x01 == std) {
- dprintk("msp34xxg: detection still in progress after 10 tries. giving up.\n");
+ msp3400_dbg("detection still in progress after 10 tries. giving up.\n");
continue;
}
unmute:
- dprintk("msp34xxg: current mode: %s (0x%04x)\n",
+ msp3400_dbg("current mode: %s (0x%04x)\n",
msp34xx_standard_mode_name(std), std);
/* unmute: dispatch sound to scart output, set scart volume */
- dprintk("msp34xxg: unmute\n");
+ msp3400_dbg("unmute\n");
msp3400c_setbass(client, msp->bass);
msp3400c_settreble(client, msp->treble);
- msp3400c_setvolume(client, msp->muted, msp->volume, msp->balance);
+ msp3400c_setvolume(client, msp->muted, msp->left, msp->right);
/* restore ACB */
if (msp3400c_write(client,
@@ -1309,8 +1438,10 @@ static int msp34xxg_thread(void *data)
0x13, /* ACB */
msp->acb))
return -1;
+
+ msp3400c_write(client,I2C_MSP3400C_DEM, 0x40, msp->i2s_mode);
}
- dprintk(KERN_DEBUG "msp34xxg: thread: exit\n");
+ msp3400_dbg("thread: exit\n");
return 0;
}
@@ -1329,7 +1460,7 @@ static void msp34xxg_set_source(struct i2c_client *client, int source)
* for MONO (source==0) downmixing set bit[7:0] to 0x30
*/
int value = (source&0x07)<<8|(source==0 ? 0x30:0x20);
- dprintk("msp34xxg: set source to %d (0x%x)\n", source, value);
+ msp3400_dbg("set source to %d (0x%x)\n", source, value);
msp3400c_write(client,
I2C_MSP3400C_DFP,
0x08, /* Loudspeaker Output */
@@ -1380,7 +1511,7 @@ static void msp34xxg_detect_stereo(struct i2c_client *client)
* this is a problem, I'll handle SAP just like lang1/lang2.
*/
}
- dprintk("msp34xxg: status=0x%x, stereo=%d, bilingual=%d -> rxsubchans=%d\n",
+ msp3400_dbg("status=0x%x, stereo=%d, bilingual=%d -> rxsubchans=%d\n",
status, is_stereo, is_bilingual, msp->rxsubchans);
}
@@ -1420,14 +1551,14 @@ static int msp_detach(struct i2c_client *client);
static int msp_probe(struct i2c_adapter *adap);
static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg);
-static int msp_suspend(struct device * dev, pm_message_t state, u32 level);
-static int msp_resume(struct device * dev, u32 level);
+static int msp_suspend(struct device * dev, pm_message_t state);
+static int msp_resume(struct device * dev);
static void msp_wake_thread(struct i2c_client *client);
static struct i2c_driver driver = {
.owner = THIS_MODULE,
- .name = "i2c msp3400 driver",
+ .name = "msp3400",
.id = I2C_DRIVERID_MSP3400,
.flags = I2C_DF_NOTIFY,
.attach_adapter = msp_probe,
@@ -1449,57 +1580,64 @@ static struct i2c_client client_template =
static int msp_attach(struct i2c_adapter *adap, int addr, int kind)
{
struct msp3400c *msp;
- struct i2c_client *c;
+ struct i2c_client *client = &client_template;
int (*thread_func)(void *data) = NULL;
+ int i;
- client_template.adapter = adap;
- client_template.addr = addr;
+ client_template.adapter = adap;
+ client_template.addr = addr;
- if (-1 == msp3400c_reset(&client_template)) {
- dprintk("msp34xx: no chip found\n");
- return -1;
- }
+ if (-1 == msp3400c_reset(&client_template)) {
+ msp3400_dbg("no chip found\n");
+ return -1;
+ }
- if (NULL == (c = kmalloc(sizeof(struct i2c_client),GFP_KERNEL)))
- return -ENOMEM;
- memcpy(c,&client_template,sizeof(struct i2c_client));
+ if (NULL == (client = kmalloc(sizeof(struct i2c_client),GFP_KERNEL)))
+ return -ENOMEM;
+ memcpy(client,&client_template,sizeof(struct i2c_client));
if (NULL == (msp = kmalloc(sizeof(struct msp3400c),GFP_KERNEL))) {
- kfree(c);
+ kfree(client);
return -ENOMEM;
}
memset(msp,0,sizeof(struct msp3400c));
- msp->volume = 58880; /* 0db gain */
- msp->balance = 32768;
- msp->bass = 32768;
- msp->treble = 32768;
- msp->input = -1;
- msp->muted = 1;
-
- i2c_set_clientdata(c, msp);
+ msp->norm = VIDEO_MODE_NTSC;
+ msp->left = 58880; /* 0db gain */
+ msp->right = 58880; /* 0db gain */
+ msp->bass = 32768;
+ msp->treble = 32768;
+ msp->input = -1;
+ msp->muted = 0;
+ msp->i2s_mode = 0;
+ for (i = 0; i < DFP_COUNT; i++)
+ msp->dfp_regs[i] = -1;
+
+ i2c_set_clientdata(client, msp);
init_waitqueue_head(&msp->wq);
- if (-1 == msp3400c_reset(c)) {
+ if (-1 == msp3400c_reset(client)) {
kfree(msp);
- kfree(c);
- dprintk("msp34xx: no chip found\n");
+ kfree(client);
+ msp3400_dbg("no chip found\n");
return -1;
}
- msp->rev1 = msp3400c_read(c, I2C_MSP3400C_DFP, 0x1e);
+ msp->rev1 = msp3400c_read(client, I2C_MSP3400C_DFP, 0x1e);
if (-1 != msp->rev1)
- msp->rev2 = msp3400c_read(c, I2C_MSP3400C_DFP, 0x1f);
+ msp->rev2 = msp3400c_read(client, I2C_MSP3400C_DFP, 0x1f);
if ((-1 == msp->rev1) || (0 == msp->rev1 && 0 == msp->rev2)) {
kfree(msp);
- kfree(c);
- dprintk("msp34xx: error while reading chip version\n");
+ kfree(client);
+ msp3400_dbg("error while reading chip version\n");
return -1;
}
+ msp3400_dbg("rev1=0x%04x, rev2=0x%04x\n", msp->rev1, msp->rev2);
- msp3400c_setvolume(c, msp->muted, msp->volume, msp->balance);
+ msp3400c_setvolume(client, msp->muted, msp->left, msp->right);
- snprintf(c->name, sizeof(c->name), "MSP34%02d%c-%c%d",
- (msp->rev2>>8)&0xff, (msp->rev1&0xff)+'@',
+ snprintf(client->name, sizeof(client->name), "MSP%c4%02d%c-%c%d",
+ ((msp->rev1>>4)&0x0f) + '3',
+ (msp->rev2>>8)&0xff, (msp->rev1&0x0f)+'@',
((msp->rev1>>8)&0xff)+'@', msp->rev2&0x1f);
msp->opmode = opmode;
@@ -1513,7 +1651,7 @@ static int msp_attach(struct i2c_adapter *adap, int addr, int kind)
}
/* hello world :-) */
- printk(KERN_INFO "msp34xx: init: chip=%s", c->name);
+ msp3400_info("chip=%s", client->name);
if (HAVE_NICAM(msp))
printk(" +nicam");
if (HAVE_SIMPLE(msp))
@@ -1542,29 +1680,49 @@ static int msp_attach(struct i2c_adapter *adap, int addr, int kind)
/* startup control thread if needed */
if (thread_func) {
- msp->kthread = kthread_run(thread_func, c, "msp34xx");
+ msp->kthread = kthread_run(thread_func, client, "msp34xx");
+
if (NULL == msp->kthread)
- printk(KERN_WARNING "msp34xx: kernel_thread() failed\n");
- msp_wake_thread(c);
+ msp3400_warn("kernel_thread() failed\n");
+ msp_wake_thread(client);
}
/* done */
- i2c_attach_client(c);
+ i2c_attach_client(client);
+
+ /* update our own array */
+ for (i = 0; i < MSP3400_MAX; i++) {
+ if (NULL == msps[i]) {
+ msps[i] = client;
+ break;
+ }
+ }
+
return 0;
}
static int msp_detach(struct i2c_client *client)
{
struct msp3400c *msp = i2c_get_clientdata(client);
+ int i;
/* shutdown control thread */
- if (msp->kthread >= 0) {
+ if (msp->kthread) {
msp->restart = 1;
kthread_stop(msp->kthread);
}
- msp3400c_reset(client);
+ msp3400c_reset(client);
+
+ /* update our own array */
+ for (i = 0; i < MSP3400_MAX; i++) {
+ if (client == msps[i]) {
+ msps[i] = NULL;
+ break;
+ }
+ }
i2c_detach_client(client);
+
kfree(msp);
kfree(client);
return 0;
@@ -1640,7 +1798,7 @@ static void msp_any_set_audmode(struct i2c_client *client, int audmode)
case OPMODE_MANUAL:
case OPMODE_SIMPLE:
msp->watch_stereo = 0;
- msp3400c_set_audmode(client, audmode);
+ msp3400c_setstereo(client, audmode);
break;
case OPMODE_SIMPLER:
msp34xxg_set_audmode(client, audmode);
@@ -1648,16 +1806,18 @@ static void msp_any_set_audmode(struct i2c_client *client, int audmode)
}
}
+
static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
{
struct msp3400c *msp = i2c_get_clientdata(client);
- __u16 *sarg = arg;
+ __u16 *sarg = arg;
int scart = 0;
switch (cmd) {
case AUDC_SET_INPUT:
- dprintk(KERN_DEBUG "msp34xx: AUDC_SET_INPUT(%d)\n",*sarg);
+ msp3400_dbg("AUDC_SET_INPUT(%d)\n",*sarg);
+
if (*sarg == msp->input)
break;
msp->input = *sarg;
@@ -1691,15 +1851,15 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
msp3400c_set_scart(client,scart,0);
msp3400c_write(client,I2C_MSP3400C_DFP,0x000d,0x1900);
if (msp->opmode != OPMODE_SIMPLER)
- msp3400c_set_audmode(client, msp->audmode);
+ msp3400c_setstereo(client, msp->audmode);
}
msp_wake_thread(client);
break;
case AUDC_SET_RADIO:
- dprintk(KERN_DEBUG "msp34xx: AUDC_SET_RADIO\n");
+ msp3400_dbg("AUDC_SET_RADIO\n");
msp->norm = VIDEO_MODE_RADIO;
- dprintk(KERN_DEBUG "msp34xx: switching to radio mode\n");
+ msp3400_dbg("switching to radio mode\n");
msp->watch_stereo = 0;
switch (msp->opmode) {
case OPMODE_MANUAL:
@@ -1707,8 +1867,7 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
msp3400c_setmode(client,MSP_MODE_FM_RADIO);
msp3400c_setcarrier(client, MSP_CARRIER(10.7),
MSP_CARRIER(10.7));
- msp3400c_setvolume(client, msp->muted,
- msp->volume, msp->balance);
+ msp3400c_setvolume(client, msp->muted, msp->left, msp->right);
break;
case OPMODE_SIMPLE:
case OPMODE_SIMPLER:
@@ -1717,6 +1876,30 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
break;
}
break;
+ /* work-in-progress: hook to control the DFP registers */
+ case MSP_SET_DFPREG:
+ {
+ struct msp_dfpreg *r = arg;
+ int i;
+
+ if (r->reg < 0 || r->reg >= DFP_COUNT)
+ return -EINVAL;
+ for (i = 0; i < sizeof(bl_dfp) / sizeof(int); i++)
+ if (r->reg == bl_dfp[i])
+ return -EINVAL;
+ msp->dfp_regs[r->reg] = r->value;
+ msp3400c_write(client, I2C_MSP3400C_DFP, r->reg, r->value);
+ return 0;
+ }
+ case MSP_GET_DFPREG:
+ {
+ struct msp_dfpreg *r = arg;
+
+ if (r->reg < 0 || r->reg >= DFP_COUNT)
+ return -EINVAL;
+ r->value = msp3400c_read(client, I2C_MSP3400C_DFP, r->reg);
+ return 0;
+ }
/* --- v4l ioctls --- */
/* take care: bttv does userspace copying, we'll get a
@@ -1725,7 +1908,7 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
{
struct video_audio *va = arg;
- dprintk(KERN_DEBUG "msp34xx: VIDIOCGAUDIO\n");
+ msp3400_dbg("VIDIOCGAUDIO\n");
va->flags |= VIDEO_AUDIO_VOLUME |
VIDEO_AUDIO_BASS |
VIDEO_AUDIO_TREBLE |
@@ -1733,8 +1916,15 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
if (msp->muted)
va->flags |= VIDEO_AUDIO_MUTE;
- va->volume = msp->volume;
- va->balance = (va->volume) ? msp->balance : 32768;
+ if (msp->muted)
+ va->flags |= VIDEO_AUDIO_MUTE;
+ va->volume = MAX(msp->left, msp->right);
+ va->balance = (32768 * MIN(msp->left, msp->right)) /
+ (va->volume ? va->volume : 1);
+ va->balance = (msp->left < msp->right) ?
+ (65535 - va->balance) : va->balance;
+ if (0 == va->volume)
+ va->balance = 32768;
va->bass = msp->bass;
va->treble = msp->treble;
@@ -1746,27 +1936,43 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
{
struct video_audio *va = arg;
- dprintk(KERN_DEBUG "msp34xx: VIDIOCSAUDIO\n");
+ msp3400_dbg("VIDIOCSAUDIO\n");
msp->muted = (va->flags & VIDEO_AUDIO_MUTE);
- msp->volume = va->volume;
- msp->balance = va->balance;
+ msp->left = (MIN(65536 - va->balance, 32768) *
+ va->volume) / 32768;
+ msp->right = (MIN(va->balance, 32768) * va->volume) / 32768;
msp->bass = va->bass;
msp->treble = va->treble;
-
- msp3400c_setvolume(client, msp->muted,
- msp->volume, msp->balance);
- msp3400c_setbass(client,msp->bass);
- msp3400c_settreble(client,msp->treble);
+ msp3400_dbg("VIDIOCSAUDIO setting va->volume to %d\n",
+ va->volume);
+ msp3400_dbg("VIDIOCSAUDIO setting va->balance to %d\n",
+ va->balance);
+ msp3400_dbg("VIDIOCSAUDIO setting va->flags to %d\n",
+ va->flags);
+ msp3400_dbg("VIDIOCSAUDIO setting msp->left to %d\n",
+ msp->left);
+ msp3400_dbg("VIDIOCSAUDIO setting msp->right to %d\n",
+ msp->right);
+ msp3400_dbg("VIDIOCSAUDIO setting msp->bass to %d\n",
+ msp->bass);
+ msp3400_dbg("VIDIOCSAUDIO setting msp->treble to %d\n",
+ msp->treble);
+ msp3400_dbg("VIDIOCSAUDIO setting msp->mode to %d\n",
+ msp->mode);
+ msp3400c_setvolume(client, msp->muted, msp->left, msp->right);
+ msp3400c_setbass(client, msp->bass);
+ msp3400c_settreble(client, msp->treble);
if (va->mode != 0 && msp->norm != VIDEO_MODE_RADIO)
msp_any_set_audmode(client,mode_v4l1_to_v4l2(va->mode));
break;
}
+
case VIDIOCSCHAN:
{
struct video_channel *vc = arg;
- dprintk(KERN_DEBUG "msp34xx: VIDIOCSCHAN (norm=%d)\n",vc->norm);
+ msp3400_dbg("VIDIOCSCHAN (norm=%d)\n",vc->norm);
msp->norm = vc->norm;
msp_wake_thread(client);
break;
@@ -1776,12 +1982,135 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
case VIDIOC_S_FREQUENCY:
{
/* new channel -- kick audio carrier scan */
- dprintk(KERN_DEBUG "msp34xx: VIDIOCSFREQ\n");
+ msp3400_dbg("VIDIOCSFREQ\n");
msp_wake_thread(client);
break;
}
+ /* msp34xx specific */
+ case MSP_SET_MATRIX:
+ {
+ struct msp_matrix *mspm = arg;
+
+ msp3400_dbg("MSP_SET_MATRIX\n");
+ msp3400c_set_scart(client, mspm->input, mspm->output);
+ break;
+ }
+
/* --- v4l2 ioctls --- */
+ case VIDIOC_S_STD:
+ {
+ v4l2_std_id *id = arg;
+
+ /*FIXME: use V4L2 mode flags on msp3400 instead of V4L1*/
+ if (*id & V4L2_STD_PAL) {
+ msp->norm=VIDEO_MODE_PAL;
+ } else if (*id & V4L2_STD_SECAM) {
+ msp->norm=VIDEO_MODE_SECAM;
+ } else {
+ msp->norm=VIDEO_MODE_NTSC;
+ }
+
+ msp_wake_thread(client);
+ return 0;
+ }
+
+ case VIDIOC_ENUMINPUT:
+ {
+ struct v4l2_input *i = arg;
+
+ if (i->index != 0)
+ return -EINVAL;
+
+ i->type = V4L2_INPUT_TYPE_TUNER;
+ switch (i->index) {
+ case AUDIO_RADIO:
+ strcpy(i->name,"Radio");
+ break;
+ case AUDIO_EXTERN_1:
+ strcpy(i->name,"Extern 1");
+ break;
+ case AUDIO_EXTERN_2:
+ strcpy(i->name,"Extern 2");
+ break;
+ case AUDIO_TUNER:
+ strcpy(i->name,"Television");
+ break;
+ default:
+ return -EINVAL;
+ }
+ return 0;
+ }
+
+ case VIDIOC_G_AUDIO:
+ {
+ struct v4l2_audio *a = arg;
+
+ memset(a,0,sizeof(*a));
+
+ switch (a->index) {
+ case AUDIO_RADIO:
+ strcpy(a->name,"Radio");
+ break;
+ case AUDIO_EXTERN_1:
+ strcpy(a->name,"Extern 1");
+ break;
+ case AUDIO_EXTERN_2:
+ strcpy(a->name,"Extern 2");
+ break;
+ case AUDIO_TUNER:
+ strcpy(a->name,"Television");
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ msp_any_detect_stereo(client);
+ if (msp->audmode == V4L2_TUNER_MODE_STEREO) {
+ a->capability=V4L2_AUDCAP_STEREO;
+ }
+
+ break;
+ }
+ case VIDIOC_S_AUDIO:
+ {
+ struct v4l2_audio *sarg = arg;
+
+ switch (sarg->index) {
+ case AUDIO_RADIO:
+ /* Hauppauge uses IN2 for the radio */
+ msp->mode = MSP_MODE_FM_RADIO;
+ scart = SCART_IN2;
+ break;
+ case AUDIO_EXTERN_1:
+ /* IN1 is often used for external input ... */
+ msp->mode = MSP_MODE_EXTERN;
+ scart = SCART_IN1;
+ break;
+ case AUDIO_EXTERN_2:
+ /* ... sometimes it is IN2 through ;) */
+ msp->mode = MSP_MODE_EXTERN;
+ scart = SCART_IN2;
+ break;
+ case AUDIO_TUNER:
+ msp->mode = -1;
+ break;
+ }
+ if (scart) {
+ msp->rxsubchans = V4L2_TUNER_SUB_STEREO;
+ msp->audmode = V4L2_TUNER_MODE_STEREO;
+ msp3400c_set_scart(client,scart,0);
+ msp3400c_write(client,I2C_MSP3400C_DFP,0x000d,0x1900);
+ }
+ if (sarg->capability==V4L2_AUDCAP_STEREO) {
+ msp->audmode = V4L2_TUNER_MODE_STEREO;
+ } else {
+ msp->audmode &= ~V4L2_TUNER_MODE_STEREO;
+ }
+ msp_any_set_audmode(client, msp->audmode);
+ msp_wake_thread(client);
+ break;
+ }
case VIDIOC_G_TUNER:
{
struct v4l2_tuner *vt = arg;
@@ -1804,13 +2133,46 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
break;
}
- /* msp34xx specific */
- case MSP_SET_MATRIX:
+ case VIDIOC_G_AUDOUT:
{
- struct msp_matrix *mspm = arg;
+ struct v4l2_audioout *a=(struct v4l2_audioout *)arg;
+ int idx=a->index;
+
+ memset(a,0,sizeof(*a));
+
+ switch (idx) {
+ case 0:
+ strcpy(a->name,"Scart1 Out");
+ break;
+ case 1:
+ strcpy(a->name,"Scart2 Out");
+ break;
+ case 2:
+ strcpy(a->name,"I2S Out");
+ break;
+ default:
+ return -EINVAL;
+ }
+ break;
+
+ }
+ case VIDIOC_S_AUDOUT:
+ {
+ struct v4l2_audioout *a=(struct v4l2_audioout *)arg;
+
+ if (a->index<0||a->index>2)
+ return -EINVAL;
+
+ if (a->index==2) {
+ if (a->mode == V4L2_AUDMODE_32BITS)
+ msp->i2s_mode=1;
+ else
+ msp->i2s_mode=0;
+ }
+ msp3400_dbg("Setting audio out on msp34xx to input %i, mode %i\n",
+ a->index,msp->i2s_mode);
+ msp3400c_set_scart(client,msp->in_scart,a->index+1);
- dprintk(KERN_DEBUG "msp34xx: MSP_SET_MATRIX\n");
- msp3400c_set_scart(client, mspm->input, mspm->output);
break;
}
@@ -1821,21 +2183,21 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
return 0;
}
-static int msp_suspend(struct device * dev, pm_message_t state, u32 level)
+static int msp_suspend(struct device * dev, pm_message_t state)
{
- struct i2c_client *c = container_of(dev, struct i2c_client, dev);
+ struct i2c_client *client = container_of(dev, struct i2c_client, dev);
- dprintk("msp34xx: suspend\n");
- msp3400c_reset(c);
+ msp3400_dbg("msp34xx: suspend\n");
+ msp3400c_reset(client);
return 0;
}
-static int msp_resume(struct device * dev, u32 level)
+static int msp_resume(struct device * dev)
{
- struct i2c_client *c = container_of(dev, struct i2c_client, dev);
+ struct i2c_client *client = container_of(dev, struct i2c_client, dev);
- dprintk("msp34xx: resume\n");
- msp_wake_thread(c);
+ msp3400_dbg("msp34xx: resume\n");
+ msp_wake_thread(client);
return 0;
}
diff --git a/drivers/media/video/mt20xx.c b/drivers/media/video/mt20xx.c
index 972aa5e0aeef..2180018f06de 100644
--- a/drivers/media/video/mt20xx.c
+++ b/drivers/media/video/mt20xx.c
@@ -76,17 +76,17 @@ static int mt2032_compute_freq(struct i2c_client *c,
unsigned int xogc) //all in Hz
{
struct tuner *t = i2c_get_clientdata(c);
- unsigned int fref,lo1,lo1n,lo1a,s,sel,lo1freq, desired_lo1,
+ unsigned int fref,lo1,lo1n,lo1a,s,sel,lo1freq, desired_lo1,
desired_lo2,lo2,lo2n,lo2a,lo2num,lo2freq;
- fref= 5250 *1000; //5.25MHz
+ fref= 5250 *1000; //5.25MHz
desired_lo1=rfin+if1;
lo1=(2*(desired_lo1/1000)+(fref/1000)) / (2*fref/1000);
- lo1n=lo1/8;
- lo1a=lo1-(lo1n*8);
+ lo1n=lo1/8;
+ lo1a=lo1-(lo1n*8);
- s=rfin/1000/1000+1090;
+ s=rfin/1000/1000+1090;
if(optimize_vco) {
if(s>1890) sel=0;
@@ -96,34 +96,34 @@ static int mt2032_compute_freq(struct i2c_client *c,
else sel=4; // >1090
}
else {
- if(s>1790) sel=0; // <1958
- else if(s>1617) sel=1;
- else if(s>1449) sel=2;
- else if(s>1291) sel=3;
- else sel=4; // >1090
+ if(s>1790) sel=0; // <1958
+ else if(s>1617) sel=1;
+ else if(s>1449) sel=2;
+ else if(s>1291) sel=3;
+ else sel=4; // >1090
}
*ret_sel=sel;
- lo1freq=(lo1a+8*lo1n)*fref;
+ lo1freq=(lo1a+8*lo1n)*fref;
tuner_dbg("mt2032: rfin=%d lo1=%d lo1n=%d lo1a=%d sel=%d, lo1freq=%d\n",
rfin,lo1,lo1n,lo1a,sel,lo1freq);
- desired_lo2=lo1freq-rfin-if2;
- lo2=(desired_lo2)/fref;
- lo2n=lo2/8;
- lo2a=lo2-(lo2n*8);
- lo2num=((desired_lo2/1000)%(fref/1000))* 3780/(fref/1000); //scale to fit in 32bit arith
- lo2freq=(lo2a+8*lo2n)*fref + lo2num*(fref/1000)/3780*1000;
+ desired_lo2=lo1freq-rfin-if2;
+ lo2=(desired_lo2)/fref;
+ lo2n=lo2/8;
+ lo2a=lo2-(lo2n*8);
+ lo2num=((desired_lo2/1000)%(fref/1000))* 3780/(fref/1000); //scale to fit in 32bit arith
+ lo2freq=(lo2a+8*lo2n)*fref + lo2num*(fref/1000)/3780*1000;
tuner_dbg("mt2032: rfin=%d lo2=%d lo2n=%d lo2a=%d num=%d lo2freq=%d\n",
rfin,lo2,lo2n,lo2a,lo2num,lo2freq);
- if(lo1a<0 || lo1a>7 || lo1n<17 ||lo1n>48 || lo2a<0 ||lo2a >7 ||lo2n<17 || lo2n>30) {
+ if(lo1a<0 || lo1a>7 || lo1n<17 ||lo1n>48 || lo2a<0 ||lo2a >7 ||lo2n<17 || lo2n>30) {
tuner_info("mt2032: frequency parameters out of range: %d %d %d %d\n",
lo1a, lo1n, lo2a,lo2n);
- return(-1);
- }
+ return(-1);
+ }
mt2032_spurcheck(c, lo1freq, desired_lo2, spectrum_from, spectrum_to);
// should recalculate lo1 (one step up/down)
@@ -135,10 +135,10 @@ static int mt2032_compute_freq(struct i2c_client *c,
buf[3]=0x0f; //reserved
buf[4]=0x1f;
buf[5]=(lo2n-1) | (lo2a<<5);
- if(rfin >400*1000*1000)
- buf[6]=0xe4;
- else
- buf[6]=0xf4; // set PKEN per rev 1.2
+ if(rfin >400*1000*1000)
+ buf[6]=0xe4;
+ else
+ buf[6]=0xf4; // set PKEN per rev 1.2
buf[7]=8+xogc;
buf[8]=0xc3; //reserved
buf[9]=0x4e; //reserved
@@ -168,7 +168,7 @@ static int mt2032_check_lo_lock(struct i2c_client *c)
tuner_dbg("mt2032: pll wait 1ms for lock (0x%2x)\n",buf[0]);
udelay(1000);
}
- return lock;
+ return lock;
}
static int mt2032_optimize_vco(struct i2c_client *c,int sel,int lock)
@@ -202,7 +202,7 @@ static int mt2032_optimize_vco(struct i2c_client *c,int sel,int lock)
buf[0]=0x0f;
buf[1]=sel;
- i2c_master_send(c,buf,2);
+ i2c_master_send(c,buf,2);
lock=mt2032_check_lo_lock(c);
return lock;
}
@@ -219,23 +219,23 @@ static void mt2032_set_if_freq(struct i2c_client *c, unsigned int rfin,
tuner_dbg("mt2032_set_if_freq rfin=%d if1=%d if2=%d from=%d to=%d\n",
rfin,if1,if2,from,to);
- buf[0]=0;
- ret=i2c_master_send(c,buf,1);
- i2c_master_recv(c,buf,21);
+ buf[0]=0;
+ ret=i2c_master_send(c,buf,1);
+ i2c_master_recv(c,buf,21);
buf[0]=0;
ret=mt2032_compute_freq(c,rfin,if1,if2,from,to,&buf[1],&sel,t->xogc);
if (ret<0)
return;
- // send only the relevant registers per Rev. 1.2
- buf[0]=0;
- ret=i2c_master_send(c,buf,4);
- buf[5]=5;
- ret=i2c_master_send(c,buf+5,4);
- buf[11]=11;
- ret=i2c_master_send(c,buf+11,3);
- if(ret!=3)
+ // send only the relevant registers per Rev. 1.2
+ buf[0]=0;
+ ret=i2c_master_send(c,buf,4);
+ buf[5]=5;
+ ret=i2c_master_send(c,buf+5,4);
+ buf[11]=11;
+ ret=i2c_master_send(c,buf+11,3);
+ if(ret!=3)
tuner_warn("i2c i/o error: rc == %d (should be 3)\n",ret);
// wait for PLLs to lock (per manual), retry LINT if not.
@@ -253,7 +253,7 @@ static void mt2032_set_if_freq(struct i2c_client *c, unsigned int rfin,
mdelay(10);
buf[1]=8+t->xogc;
i2c_master_send(c,buf,2);
- }
+ }
if (lock!=6)
tuner_warn("MT2032 Fatal Error: PLLs didn't lock.\n");
@@ -284,7 +284,7 @@ static void mt2032_set_tv_freq(struct i2c_client *c, unsigned int freq)
if2 = 38900*1000;
}
- mt2032_set_if_freq(c, freq*62500 /* freq*1000*1000/16 */,
+ mt2032_set_if_freq(c, freq*62500 /* freq*1000*1000/16 */,
1090*1000*1000, if2, from, to);
}
@@ -294,7 +294,7 @@ static void mt2032_set_radio_freq(struct i2c_client *c, unsigned int freq)
int if2 = t->radio_if2;
// per Manual for FM tuning: first if center freq. 1085 MHz
- mt2032_set_if_freq(c, freq * 1000 / 16,
+ mt2032_set_if_freq(c, freq * 1000 / 16,
1085*1000*1000,if2,if2,if2);
}
@@ -302,57 +302,57 @@ static void mt2032_set_radio_freq(struct i2c_client *c, unsigned int freq)
static int mt2032_init(struct i2c_client *c)
{
struct tuner *t = i2c_get_clientdata(c);
- unsigned char buf[21];
- int ret,xogc,xok=0;
+ unsigned char buf[21];
+ int ret,xogc,xok=0;
// Initialize Registers per spec.
- buf[1]=2; // Index to register 2
- buf[2]=0xff;
- buf[3]=0x0f;
- buf[4]=0x1f;
- ret=i2c_master_send(c,buf+1,4);
-
- buf[5]=6; // Index register 6
- buf[6]=0xe4;
- buf[7]=0x8f;
- buf[8]=0xc3;
- buf[9]=0x4e;
- buf[10]=0xec;
- ret=i2c_master_send(c,buf+5,6);
-
- buf[12]=13; // Index register 13
- buf[13]=0x32;
- ret=i2c_master_send(c,buf+12,2);
-
- // Adjust XOGC (register 7), wait for XOK
- xogc=7;
- do {
+ buf[1]=2; // Index to register 2
+ buf[2]=0xff;
+ buf[3]=0x0f;
+ buf[4]=0x1f;
+ ret=i2c_master_send(c,buf+1,4);
+
+ buf[5]=6; // Index register 6
+ buf[6]=0xe4;
+ buf[7]=0x8f;
+ buf[8]=0xc3;
+ buf[9]=0x4e;
+ buf[10]=0xec;
+ ret=i2c_master_send(c,buf+5,6);
+
+ buf[12]=13; // Index register 13
+ buf[13]=0x32;
+ ret=i2c_master_send(c,buf+12,2);
+
+ // Adjust XOGC (register 7), wait for XOK
+ xogc=7;
+ do {
tuner_dbg("mt2032: xogc = 0x%02x\n",xogc&0x07);
- mdelay(10);
- buf[0]=0x0e;
- i2c_master_send(c,buf,1);
- i2c_master_recv(c,buf,1);
- xok=buf[0]&0x01;
- tuner_dbg("mt2032: xok = 0x%02x\n",xok);
- if (xok == 1) break;
-
- xogc--;
- tuner_dbg("mt2032: xogc = 0x%02x\n",xogc&0x07);
- if (xogc == 3) {
- xogc=4; // min. 4 per spec
- break;
- }
- buf[0]=0x07;
- buf[1]=0x88 + xogc;
- ret=i2c_master_send(c,buf,2);
- if (ret!=2)
+ mdelay(10);
+ buf[0]=0x0e;
+ i2c_master_send(c,buf,1);
+ i2c_master_recv(c,buf,1);
+ xok=buf[0]&0x01;
+ tuner_dbg("mt2032: xok = 0x%02x\n",xok);
+ if (xok == 1) break;
+
+ xogc--;
+ tuner_dbg("mt2032: xogc = 0x%02x\n",xogc&0x07);
+ if (xogc == 3) {
+ xogc=4; // min. 4 per spec
+ break;
+ }
+ buf[0]=0x07;
+ buf[1]=0x88 + xogc;
+ ret=i2c_master_send(c,buf,2);
+ if (ret!=2)
tuner_warn("i2c i/o error: rc == %d (should be 2)\n",ret);
- } while (xok != 1 );
+ } while (xok != 1 );
t->xogc=xogc;
t->tv_freq = mt2032_set_tv_freq;
t->radio_freq = mt2032_set_radio_freq;
- return(1);
+ return(1);
}
static void mt2050_set_antenna(struct i2c_client *c, unsigned char antenna)
@@ -426,7 +426,7 @@ static void mt2050_set_if_freq(struct i2c_client *c,unsigned int freq, unsigned
}
ret=i2c_master_send(c,buf,6);
- if (ret!=6)
+ if (ret!=6)
tuner_warn("i2c i/o error: rc == %d (should be 6)\n",ret);
}
@@ -437,11 +437,11 @@ static void mt2050_set_tv_freq(struct i2c_client *c, unsigned int freq)
if (t->std & V4L2_STD_525_60) {
// NTSC
- if2 = 45750*1000;
- } else {
- // PAL
- if2 = 38900*1000;
- }
+ if2 = 45750*1000;
+ } else {
+ // PAL
+ if2 = 38900*1000;
+ }
if (V4L2_TUNER_DIGITAL_TV == t->mode) {
// DVB (pinnacle 300i)
if2 = 36150*1000;
@@ -455,7 +455,7 @@ static void mt2050_set_radio_freq(struct i2c_client *c, unsigned int freq)
struct tuner *t = i2c_get_clientdata(c);
int if2 = t->radio_if2;
- mt2050_set_if_freq(c, freq*62500, if2);
+ mt2050_set_if_freq(c, freq * 1000 / 16, if2);
mt2050_set_antenna(c, radio_antenna);
}
@@ -487,7 +487,7 @@ int microtune_init(struct i2c_client *c)
{
struct tuner *t = i2c_get_clientdata(c);
char *name;
- unsigned char buf[21];
+ unsigned char buf[21];
int company_code;
memset(buf,0,sizeof(buf));
@@ -496,17 +496,17 @@ int microtune_init(struct i2c_client *c)
t->standby = NULL;
name = "unknown";
- i2c_master_send(c,buf,1);
- i2c_master_recv(c,buf,21);
- if (tuner_debug) {
- int i;
+ i2c_master_send(c,buf,1);
+ i2c_master_recv(c,buf,21);
+ if (tuner_debug) {
+ int i;
tuner_dbg("MT20xx hexdump:");
- for(i=0;i<21;i++) {
- printk(" %02x",buf[i]);
- if(((i+1)%8)==0) printk(" ");
- }
- printk("\n");
- }
+ for(i=0;i<21;i++) {
+ printk(" %02x",buf[i]);
+ if(((i+1)%8)==0) printk(" ");
+ }
+ printk("\n");
+ }
company_code = buf[0x11] << 8 | buf[0x12];
tuner_info("microtune: companycode=%04x part=%02x rev=%02x\n",
company_code,buf[0x13],buf[0x14]);
@@ -525,8 +525,8 @@ int microtune_init(struct i2c_client *c)
default:
tuner_info("microtune %s found, not (yet?) supported, sorry :-/\n",
name);
- return 0;
- }
+ return 0;
+ }
strlcpy(c->name, name, sizeof(c->name));
tuner_info("microtune %s found, OK\n",name);
diff --git a/drivers/media/video/saa6588.c b/drivers/media/video/saa6588.c
index 72b70eb5da1d..dca3ddfd510f 100644
--- a/drivers/media/video/saa6588.c
+++ b/drivers/media/video/saa6588.c
@@ -31,7 +31,6 @@
#include <linux/wait.h>
#include <asm/uaccess.h>
-#include <media/id.h>
#include "rds.h"
@@ -246,7 +245,7 @@ static void block_to_buf(struct saa6588 *s, unsigned char *blockbuf)
s->wr_index = 0;
if (s->wr_index == s->rd_index) {
- s->rd_index++;
+ s->rd_index += 3;
if (s->rd_index >= s->buf_size)
s->rd_index = 0;
} else
@@ -328,7 +327,7 @@ static void saa6588_work(void *data)
struct saa6588 *s = (struct saa6588 *)data;
saa6588_i2c_poll(s);
- mod_timer(&s->timer, jiffies + HZ / 50); /* 20 msec */
+ mod_timer(&s->timer, jiffies + msecs_to_jiffies(20));
}
static int saa6588_configure(struct saa6588 *s)
@@ -434,9 +433,9 @@ static int saa6588_probe(struct i2c_adapter *adap)
return i2c_probe(adap, &addr_data, saa6588_attach);
#else
switch (adap->id) {
- case I2C_ALGO_BIT | I2C_HW_B_BT848:
- case I2C_ALGO_BIT | I2C_HW_B_RIVA:
- case I2C_ALGO_SAA7134:
+ case I2C_HW_B_BT848:
+ case I2C_HW_B_RIVA:
+ case I2C_HW_SAA7134:
return i2c_probe(adap, &addr_data, saa6588_attach);
break;
}
diff --git a/drivers/media/video/saa711x.c b/drivers/media/video/saa711x.c
new file mode 100644
index 000000000000..9aa8827de2c3
--- /dev/null
+++ b/drivers/media/video/saa711x.c
@@ -0,0 +1,593 @@
+/*
+ * saa711x - Philips SAA711x video decoder driver version 0.0.1
+ *
+ * To do: Now, it handles only saa7113/7114. Should be improved to
+ * handle all Philips saa711x devices.
+ *
+ * Based on saa7113 driver from Dave Perks <dperks@ibm.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.
+ *
+ * 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/module.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/fs.h>
+#include <linux/kernel.h>
+#include <linux/major.h>
+#include <linux/slab.h>
+#include <linux/mm.h>
+#include <linux/pci.h>
+#include <linux/signal.h>
+#include <asm/io.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+#include <linux/sched.h>
+#include <asm/segment.h>
+#include <linux/types.h>
+#include <asm/uaccess.h>
+#include <linux/videodev.h>
+
+MODULE_DESCRIPTION("Philips SAA711x video decoder driver");
+MODULE_AUTHOR("Dave Perks, Jose Ignacio Gijon, Joerg Heckenbach, Mark McClelland, Dwaine Garden");
+MODULE_LICENSE("GPL");
+
+#include <linux/i2c.h>
+#include <linux/i2c-dev.h>
+
+#define I2C_NAME(s) (s)->name
+
+#include <linux/video_decoder.h>
+
+static int debug = 0;
+MODULE_PARM(debug, "i");
+MODULE_PARM_DESC(debug, " Set the default Debug level. Default: 0 (Off) - (0-1)");
+
+
+#define dprintk(num, format, args...) \
+ do { \
+ if (debug >= num) \
+ printk(format , ##args); \
+ } while (0)
+
+/* ----------------------------------------------------------------------- */
+
+struct saa711x {
+ unsigned char reg[32];
+
+ int norm;
+ int input;
+ int enable;
+ int bright;
+ int contrast;
+ int hue;
+ int sat;
+};
+
+#define I2C_SAA7113 0x4A
+#define I2C_SAA7114 0x42
+
+/* ----------------------------------------------------------------------- */
+
+static inline int
+saa711x_write (struct i2c_client *client,
+ u8 reg,
+ u8 value)
+{
+ struct saa711x *decoder = i2c_get_clientdata(client);
+
+ decoder->reg[reg] = value;
+ return i2c_smbus_write_byte_data(client, reg, value);
+}
+
+static int
+saa711x_write_block (struct i2c_client *client,
+ const u8 *data,
+ unsigned int len)
+{
+ int ret = -1;
+ u8 reg;
+
+ /* the saa711x has an autoincrement function, use it if
+ * the adapter understands raw I2C */
+ if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+ /* do raw I2C, not smbus compatible */
+ struct saa711x *decoder = i2c_get_clientdata(client);
+ struct i2c_msg msg;
+ u8 block_data[32];
+
+ msg.addr = client->addr;
+ msg.flags = 0;
+ while (len >= 2) {
+ msg.buf = (char *) block_data;
+ msg.len = 0;
+ block_data[msg.len++] = reg = data[0];
+ do {
+ block_data[msg.len++] =
+ decoder->reg[reg++] = data[1];
+ len -= 2;
+ data += 2;
+ } while (len >= 2 && data[0] == reg &&
+ msg.len < 32);
+ if ((ret = i2c_transfer(client->adapter,
+ &msg, 1)) < 0)
+ break;
+ }
+ } else {
+ /* do some slow I2C emulation kind of thing */
+ while (len >= 2) {
+ reg = *data++;
+ if ((ret = saa711x_write(client, reg,
+ *data++)) < 0)
+ break;
+ len -= 2;
+ }
+ }
+
+ return ret;
+}
+
+static int
+saa711x_init_decoder (struct i2c_client *client,
+ struct video_decoder_init *init)
+{
+ return saa711x_write_block(client, init->data, init->len);
+}
+
+static inline int
+saa711x_read (struct i2c_client *client,
+ u8 reg)
+{
+ return i2c_smbus_read_byte_data(client, reg);
+}
+
+/* ----------------------------------------------------------------------- */
+
+static const unsigned char saa711x_i2c_init[] = {
+ 0x00, 0x00, /* PH711x_CHIP_VERSION 00 - ID byte */
+ 0x01, 0x08, /* PH711x_INCREMENT_DELAY - (1) (1) (1) (1) IDEL3 IDEL2 IDELL1 IDEL0 */
+ 0x02, 0xc0, /* PH711x_ANALOG_INPUT_CONTR_1 - FUSE1 FUSE0 GUDL1 GUDL0 MODE3 MODE2 MODE1 MODE0 */
+ 0x03, 0x23, /* PH711x_ANALOG_INPUT_CONTR_2 - (1) HLNRS VBSL WPOFF HOLDG GAFIX GAI28 GAI18 */
+ 0x04, 0x00, /* PH711x_ANALOG_INPUT_CONTR_3 - GAI17 GAI16 GAI15 GAI14 GAI13 GAI12 GAI11 GAI10 */
+ 0x05, 0x00, /* PH711x_ANALOG_INPUT_CONTR_4 - GAI27 GAI26 GAI25 GAI24 GAI23 GAI22 GAI21 GAI20 */
+ 0x06, 0xeb, /* PH711x_HORIZONTAL_SYNC_START - HSB7 HSB6 HSB5 HSB4 HSB3 HSB2 HSB1 HSB0 */
+ 0x07, 0xe0, /* PH711x_HORIZONTAL_SYNC_STOP - HSS7 HSS6 HSS5 HSS4 HSS3 HSS2 HSS1 HSS0 */
+ 0x08, 0x88, /* PH711x_SYNC_CONTROL - AUFD FSEL FOET HTC1 HTC0 HPLL VNOI1 VNOI0 */
+ 0x09, 0x00, /* PH711x_LUMINANCE_CONTROL - BYPS PREF BPSS1 BPSS0 VBLB UPTCV APER1 APER0 */
+ 0x0a, 0x80, /* PH711x_LUMINANCE_BRIGHTNESS - BRIG7 BRIG6 BRIG5 BRIG4 BRIG3 BRIG2 BRIG1 BRIG0 */
+ 0x0b, 0x47, /* PH711x_LUMINANCE_CONTRAST - CONT7 CONT6 CONT5 CONT4 CONT3 CONT2 CONT1 CONT0 */
+ 0x0c, 0x40, /* PH711x_CHROMA_SATURATION - SATN7 SATN6 SATN5 SATN4 SATN3 SATN2 SATN1 SATN0 */
+ 0x0d, 0x00, /* PH711x_CHROMA_HUE_CONTROL - HUEC7 HUEC6 HUEC5 HUEC4 HUEC3 HUEC2 HUEC1 HUEC0 */
+ 0x0e, 0x01, /* PH711x_CHROMA_CONTROL - CDTO CSTD2 CSTD1 CSTD0 DCCF FCTC CHBW1 CHBW0 */
+ 0x0f, 0xaa, /* PH711x_CHROMA_GAIN_CONTROL - ACGC CGAIN6 CGAIN5 CGAIN4 CGAIN3 CGAIN2 CGAIN1 CGAIN0 */
+ 0x10, 0x00, /* PH711x_FORMAT_DELAY_CONTROL - OFTS1 OFTS0 HDEL1 HDEL0 VRLN YDEL2 YDEL1 YDEL0 */
+ 0x11, 0x1C, /* PH711x_OUTPUT_CONTROL_1 - GPSW1 CM99 GPSW0 HLSEL OEYC OERT VIPB COLO */
+ 0x12, 0x01, /* PH711x_OUTPUT_CONTROL_2 - RTSE13 RTSE12 RTSE11 RTSE10 RTSE03 RTSE02 RTSE01 RTSE00 */
+ 0x13, 0x00, /* PH711x_OUTPUT_CONTROL_3 - ADLSB (1) (1) OLDSB FIDP (1) AOSL1 AOSL0 */
+ 0x14, 0x00, /* RESERVED 14 - (1) (1) (1) (1) (1) (1) (1) (1) */
+ 0x15, 0x00, /* PH711x_V_GATE1_START - VSTA7 VSTA6 VSTA5 VSTA4 VSTA3 VSTA2 VSTA1 VSTA0 */
+ 0x16, 0x00, /* PH711x_V_GATE1_STOP - VSTO7 VSTO6 VSTO5 VSTO4 VSTO3 VSTO2 VSTO1 VSTO0 */
+ 0x17, 0x00, /* PH711x_V_GATE1_MSB - (1) (1) (1) (1) (1) (1) VSTO8 VSTA8 */
+};
+
+static int
+saa711x_command (struct i2c_client *client,
+ unsigned int cmd,
+ void *arg)
+{
+ struct saa711x *decoder = i2c_get_clientdata(client);
+
+ switch (cmd) {
+
+ case 0:
+ case DECODER_INIT:
+ {
+ struct video_decoder_init *init = arg;
+ if (NULL != init)
+ return saa711x_init_decoder(client, init);
+ else {
+ struct video_decoder_init vdi;
+ vdi.data = saa711x_i2c_init;
+ vdi.len = sizeof(saa711x_i2c_init);
+ return saa711x_init_decoder(client, &vdi);
+ }
+ }
+
+ case DECODER_DUMP:
+ {
+ int i;
+
+ for (i = 0; i < 32; i += 16) {
+ int j;
+
+ printk(KERN_DEBUG "%s: %03x", I2C_NAME(client), i);
+ for (j = 0; j < 16; ++j) {
+ printk(" %02x",
+ saa711x_read(client, i + j));
+ }
+ printk("\n");
+ }
+ }
+ break;
+
+ case DECODER_GET_CAPABILITIES:
+ {
+ struct video_decoder_capability *cap = arg;
+
+ cap->flags = VIDEO_DECODER_PAL |
+ VIDEO_DECODER_NTSC |
+ VIDEO_DECODER_SECAM |
+ VIDEO_DECODER_AUTO |
+ VIDEO_DECODER_CCIR;
+ cap->inputs = 8;
+ cap->outputs = 1;
+ }
+ break;
+
+ case DECODER_GET_STATUS:
+ {
+ int *iarg = arg;
+ int status;
+ int res;
+
+ status = saa711x_read(client, 0x1f);
+ dprintk(1, KERN_DEBUG "%s status: 0x%02x\n", I2C_NAME(client),
+ status);
+ res = 0;
+ if ((status & (1 << 6)) == 0) {
+ res |= DECODER_STATUS_GOOD;
+ }
+ switch (decoder->norm) {
+ case VIDEO_MODE_NTSC:
+ res |= DECODER_STATUS_NTSC;
+ break;
+ case VIDEO_MODE_PAL:
+ res |= DECODER_STATUS_PAL;
+ break;
+ case VIDEO_MODE_SECAM:
+ res |= DECODER_STATUS_SECAM;
+ break;
+ default:
+ case VIDEO_MODE_AUTO:
+ if ((status & (1 << 5)) != 0) {
+ res |= DECODER_STATUS_NTSC;
+ } else {
+ res |= DECODER_STATUS_PAL;
+ }
+ break;
+ }
+ if ((status & (1 << 0)) != 0) {
+ res |= DECODER_STATUS_COLOR;
+ }
+ *iarg = res;
+ }
+ break;
+
+ case DECODER_SET_GPIO:
+ {
+ int *iarg = arg;
+ if (0 != *iarg) {
+ saa711x_write(client, 0x11,
+ (decoder->reg[0x11] | 0x80));
+ } else {
+ saa711x_write(client, 0x11,
+ (decoder->reg[0x11] & 0x7f));
+ }
+ break;
+ }
+
+ case DECODER_SET_VBI_BYPASS:
+ {
+ int *iarg = arg;
+ if (0 != *iarg) {
+ saa711x_write(client, 0x13,
+ (decoder->reg[0x13] & 0xf0) | 0x0a);
+ } else {
+ saa711x_write(client, 0x13,
+ (decoder->reg[0x13] & 0xf0));
+ }
+ break;
+ }
+
+ case DECODER_SET_NORM:
+ {
+ int *iarg = arg;
+
+ switch (*iarg) {
+
+ case VIDEO_MODE_NTSC:
+ saa711x_write(client, 0x08,
+ (decoder->reg[0x08] & 0x3f) | 0x40);
+ saa711x_write(client, 0x0e,
+ (decoder->reg[0x0e] & 0x8f));
+ break;
+
+ case VIDEO_MODE_PAL:
+ saa711x_write(client, 0x08,
+ (decoder->reg[0x08] & 0x3f) | 0x00);
+ saa711x_write(client, 0x0e,
+ (decoder->reg[0x0e] & 0x8f));
+ break;
+
+ case VIDEO_MODE_SECAM:
+ saa711x_write(client, 0x08,
+ (decoder->reg[0x0e] & 0x3f) | 0x00);
+ saa711x_write(client, 0x0e,
+ (decoder->reg[0x0e] & 0x8f) | 0x50);
+ break;
+
+ case VIDEO_MODE_AUTO:
+ saa711x_write(client, 0x08,
+ (decoder->reg[0x08] & 0x3f) | 0x80);
+ saa711x_write(client, 0x0e,
+ (decoder->reg[0x0e] & 0x8f));
+ break;
+
+ default:
+ return -EINVAL;
+
+ }
+ decoder->norm = *iarg;
+ }
+ break;
+
+ case DECODER_SET_INPUT:
+ {
+ int *iarg = arg;
+ if (*iarg < 0 || *iarg > 9) {
+ return -EINVAL;
+ }
+ if (decoder->input != *iarg) {
+ decoder->input = *iarg;
+ /* select mode */
+ saa711x_write(client, 0x02,
+ (decoder->reg[0x02] & 0xf0) | decoder->input);
+ /* bypass chrominance trap for modes 4..7 */
+ saa711x_write(client, 0x09,
+ (decoder->reg[0x09] & 0x7f) | ((decoder->input > 3) ? 0x80 : 0));
+ }
+ }
+ break;
+
+ case DECODER_SET_OUTPUT:
+ {
+ int *iarg = arg;
+
+ /* not much choice of outputs */
+ if (*iarg != 0) {
+ return -EINVAL;
+ }
+ }
+ break;
+
+ case DECODER_ENABLE_OUTPUT:
+ {
+ int *iarg = arg;
+ int enable = (*iarg != 0);
+
+ if (decoder->enable != enable) {
+ decoder->enable = enable;
+
+ /* RJ: If output should be disabled (for
+ * playing videos), we also need a open PLL.
+ * The input is set to 0 (where no input
+ * source is connected), although this
+ * is not necessary.
+ *
+ * If output should be enabled, we have to
+ * reverse the above.
+ */
+
+ if (decoder->enable) {
+ saa711x_write(client, 0x02,
+ (decoder->
+ reg[0x02] & 0xf8) |
+ decoder->input);
+ saa711x_write(client, 0x08,
+ (decoder->reg[0x08] & 0xfb));
+ saa711x_write(client, 0x11,
+ (decoder->
+ reg[0x11] & 0xf3) | 0x0c);
+ } else {
+ saa711x_write(client, 0x02,
+ (decoder->reg[0x02] & 0xf8));
+ saa711x_write(client, 0x08,
+ (decoder->
+ reg[0x08] & 0xfb) | 0x04);
+ saa711x_write(client, 0x11,
+ (decoder->reg[0x11] & 0xf3));
+ }
+ }
+ }
+ break;
+
+ case DECODER_SET_PICTURE:
+ {
+ struct video_picture *pic = arg;
+
+ if (decoder->bright != pic->brightness) {
+ /* We want 0 to 255 we get 0-65535 */
+ decoder->bright = pic->brightness;
+ saa711x_write(client, 0x0a, decoder->bright >> 8);
+ }
+ if (decoder->contrast != pic->contrast) {
+ /* We want 0 to 127 we get 0-65535 */
+ decoder->contrast = pic->contrast;
+ saa711x_write(client, 0x0b,
+ decoder->contrast >> 9);
+ }
+ if (decoder->sat != pic->colour) {
+ /* We want 0 to 127 we get 0-65535 */
+ decoder->sat = pic->colour;
+ saa711x_write(client, 0x0c, decoder->sat >> 9);
+ }
+ if (decoder->hue != pic->hue) {
+ /* We want -128 to 127 we get 0-65535 */
+ decoder->hue = pic->hue;
+ saa711x_write(client, 0x0d,
+ (decoder->hue - 32768) >> 8);
+ }
+ }
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+/* ----------------------------------------------------------------------- */
+
+/*
+ * Generic i2c probe
+ * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
+ */
+
+/* standard i2c insmod options */
+static unsigned short normal_i2c[] = {
+ I2C_SAA7113>>1, /* saa7113 */
+ I2C_SAA7114>>1, /* saa7114 */
+ I2C_CLIENT_END
+};
+
+I2C_CLIENT_INSMOD;
+
+
+static struct i2c_driver i2c_driver_saa711x;
+
+static int
+saa711x_detect_client (struct i2c_adapter *adapter,
+ int address,
+ int kind)
+{
+ int i;
+ struct i2c_client *client;
+ struct saa711x *decoder;
+ struct video_decoder_init vdi;
+
+ dprintk(1,
+ KERN_INFO
+ "saa711x.c: detecting saa711x client on address 0x%x\n",
+ address << 1);
+
+ /* Check if the adapter supports the needed features */
+ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+ return 0;
+
+ client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
+ if (client == 0)
+ return -ENOMEM;
+ memset(client, 0, sizeof(struct i2c_client));
+ client->addr = address;
+ client->adapter = adapter;
+ client->driver = &i2c_driver_saa711x;
+ client->flags = I2C_CLIENT_ALLOW_USE;
+ strlcpy(I2C_NAME(client), "saa711x", sizeof(I2C_NAME(client)));
+ decoder = kmalloc(sizeof(struct saa711x), GFP_KERNEL);
+ if (decoder == NULL) {
+ kfree(client);
+ return -ENOMEM;
+ }
+ memset(decoder, 0, sizeof(struct saa711x));
+ decoder->norm = VIDEO_MODE_NTSC;
+ decoder->input = 0;
+ decoder->enable = 1;
+ decoder->bright = 32768;
+ decoder->contrast = 32768;
+ decoder->hue = 32768;
+ decoder->sat = 32768;
+ i2c_set_clientdata(client, decoder);
+
+ i = i2c_attach_client(client);
+ if (i) {
+ kfree(client);
+ kfree(decoder);
+ return i;
+ }
+
+ vdi.data = saa711x_i2c_init;
+ vdi.len = sizeof(saa711x_i2c_init);
+ i = saa711x_init_decoder(client, &vdi);
+ if (i < 0) {
+ dprintk(1, KERN_ERR "%s_attach error: init status %d\n",
+ I2C_NAME(client), i);
+ } else {
+ dprintk(1,
+ KERN_INFO
+ "%s_attach: chip version %x at address 0x%x\n",
+ I2C_NAME(client), saa711x_read(client, 0x00) >> 4,
+ client->addr << 1);
+ }
+
+ return 0;
+}
+
+static int
+saa711x_attach_adapter (struct i2c_adapter *adapter)
+{
+ dprintk(1,
+ KERN_INFO
+ "saa711x.c: starting probe for adapter %s (0x%x)\n",
+ I2C_NAME(adapter), adapter->id);
+ return i2c_probe(adapter, &addr_data, &saa711x_detect_client);
+}
+
+static int
+saa711x_detach_client (struct i2c_client *client)
+{
+ struct saa711x *decoder = i2c_get_clientdata(client);
+ int err;
+
+ err = i2c_detach_client(client);
+ if (err) {
+ return err;
+ }
+
+ kfree(decoder);
+ kfree(client);
+
+ return 0;
+}
+
+/* ----------------------------------------------------------------------- */
+
+static struct i2c_driver i2c_driver_saa711x = {
+ .owner = THIS_MODULE,
+ .name = "saa711x",
+
+ .id = I2C_DRIVERID_SAA711X,
+ .flags = I2C_DF_NOTIFY,
+
+ .attach_adapter = saa711x_attach_adapter,
+ .detach_client = saa711x_detach_client,
+ .command = saa711x_command,
+};
+
+static int __init
+saa711x_init (void)
+{
+ return i2c_add_driver(&i2c_driver_saa711x);
+}
+
+static void __exit
+saa711x_exit (void)
+{
+ i2c_del_driver(&i2c_driver_saa711x);
+}
+
+module_init(saa711x_init);
+module_exit(saa711x_exit);
diff --git a/drivers/media/video/saa7134/Kconfig b/drivers/media/video/saa7134/Kconfig
new file mode 100644
index 000000000000..624e8808a517
--- /dev/null
+++ b/drivers/media/video/saa7134/Kconfig
@@ -0,0 +1,68 @@
+config VIDEO_SAA7134
+ tristate "Philips SAA7134 support"
+ depends on VIDEO_DEV && PCI && I2C && SOUND
+ select VIDEO_BUF
+ select VIDEO_IR
+ select VIDEO_TUNER
+ select CRC32
+ ---help---
+ This is a video4linux driver for Philips SAA713x based
+ TV cards.
+
+ To compile this driver as a module, choose M here: the
+ module will be called saa7134.
+
+config VIDEO_SAA7134_DVB
+ tristate "DVB/ATSC Support for saa7134 based TV cards"
+ depends on VIDEO_SAA7134 && DVB_CORE
+ select VIDEO_BUF_DVB
+ ---help---
+ This adds support for DVB cards based on the
+ Philips saa7134 chip.
+
+ To compile this driver as a module, choose M here: the
+ module will be called saa7134-dvb.
+
+ You must also select one or more DVB demodulators.
+ If you are unsure which you need, choose all of them.
+
+config VIDEO_SAA7134_DVB_ALL_FRONTENDS
+ bool "Build all supported frontends for saa7134 based TV cards"
+ default y
+ depends on VIDEO_SAA7134_DVB
+ select DVB_MT352
+ select DVB_TDA1004X
+ select DVB_NXT200X
+ ---help---
+ This builds saa7134-dvb with all currently supported frontend
+ demodulators. If you wish to tweak your configuration, and
+ only include support for the hardware that you need, choose N here.
+
+ If you are unsure, choose Y.
+
+config VIDEO_SAA7134_DVB_MT352
+ tristate "Zarlink MT352 DVB-T Support"
+ default m
+ depends on VIDEO_SAA7134_DVB && !VIDEO_SAA7134_DVB_ALL_FRONTENDS
+ select DVB_MT352
+ ---help---
+ This adds DVB-T support for cards based on the
+ Philips saa7134 chip and the MT352 demodulator.
+
+config VIDEO_SAA7134_DVB_TDA1004X
+ tristate "Phillips TDA10045H/TDA10046H DVB-T Support"
+ default m
+ depends on VIDEO_SAA7134_DVB && !VIDEO_SAA7134_DVB_ALL_FRONTENDS
+ select DVB_TDA1004X
+ ---help---
+ This adds DVB-T support for cards based on the
+ Philips saa7134 chip and the TDA10045H/TDA10046H demodulator.
+
+config VIDEO_SAA7134_DVB_NXT200X
+ tristate "NXT2002/NXT2004 ATSC Support"
+ default m
+ depends on VIDEO_SAA7134_DVB && !VIDEO_SAA7134_DVB_ALL_FRONTENDS
+ select DVB_NXT200X
+ ---help---
+ This adds ATSC 8VSB and QAM64/256 support for cards based on the
+ Philips saa7134 chip and the NXT2002/NXT2004 demodulator.
diff --git a/drivers/media/video/saa7134/Makefile b/drivers/media/video/saa7134/Makefile
index b778ffd94e65..e0b28f0533af 100644
--- a/drivers/media/video/saa7134/Makefile
+++ b/drivers/media/video/saa7134/Makefile
@@ -3,15 +3,22 @@ saa7134-objs := saa7134-cards.o saa7134-core.o saa7134-i2c.o \
saa7134-oss.o saa7134-ts.o saa7134-tvaudio.o \
saa7134-vbi.o saa7134-video.o saa7134-input.o
-obj-$(CONFIG_VIDEO_SAA7134) += saa7134.o saa7134-empress.o saa6752hs.o
+obj-$(CONFIG_VIDEO_SAA7134) += saa7134.o saa7134-empress.o \
+ saa6752hs.o saa7134-alsa.o
obj-$(CONFIG_VIDEO_SAA7134_DVB) += saa7134-dvb.o
EXTRA_CFLAGS += -I$(src)/..
EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/dvb-core
EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/frontends
+ifneq ($(CONFIG_VIDEO_BUF_DVB),n)
+ EXTRA_CFLAGS += -DHAVE_VIDEO_BUF_DVB=1
+endif
ifneq ($(CONFIG_DVB_MT352),n)
EXTRA_CFLAGS += -DHAVE_MT352=1
endif
ifneq ($(CONFIG_DVB_TDA1004X),n)
EXTRA_CFLAGS += -DHAVE_TDA1004X=1
endif
+ifneq ($(CONFIG_DVB_NXT200X),n)
+ EXTRA_CFLAGS += -DHAVE_NXT200X=1
+endif
diff --git a/drivers/media/video/saa7134/saa6752hs.c b/drivers/media/video/saa7134/saa6752hs.c
index 382911c6ef22..cdd1ed9c8065 100644
--- a/drivers/media/video/saa7134/saa6752hs.c
+++ b/drivers/media/video/saa7134/saa6752hs.c
@@ -13,7 +13,6 @@
#include <linux/init.h>
#include <linux/crc32.h>
-#include <media/id.h>
#define MPEG_VIDEO_TARGET_BITRATE_MAX 27000
#define MPEG_VIDEO_MAX_BITRATE_MAX 27000
@@ -57,6 +56,7 @@ struct saa6752hs_state {
struct i2c_client client;
struct v4l2_mpeg_compression params;
enum saa6752hs_videoformat video_format;
+ v4l2_std_id standard;
};
enum saa6752hs_command {
@@ -74,58 +74,58 @@ enum saa6752hs_command {
/* ---------------------------------------------------------------------- */
static u8 PAT[] = {
- 0xc2, // i2c register
- 0x00, // table number for encoder
+ 0xc2, /* i2c register */
+ 0x00, /* table number for encoder */
- 0x47, // sync
- 0x40, 0x00, // transport_error_indicator(0), payload_unit_start(1), transport_priority(0), pid(0)
- 0x10, // transport_scrambling_control(00), adaptation_field_control(01), continuity_counter(0)
+ 0x47, /* sync */
+ 0x40, 0x00, /* transport_error_indicator(0), payload_unit_start(1), transport_priority(0), pid(0) */
+ 0x10, /* transport_scrambling_control(00), adaptation_field_control(01), continuity_counter(0) */
- 0x00, // PSI pointer to start of table
+ 0x00, /* PSI pointer to start of table */
- 0x00, // tid(0)
- 0xb0, 0x0d, // section_syntax_indicator(1), section_length(13)
+ 0x00, /* tid(0) */
+ 0xb0, 0x0d, /* section_syntax_indicator(1), section_length(13) */
- 0x00, 0x01, // transport_stream_id(1)
+ 0x00, 0x01, /* transport_stream_id(1) */
- 0xc1, // version_number(0), current_next_indicator(1)
+ 0xc1, /* version_number(0), current_next_indicator(1) */
- 0x00, 0x00, // section_number(0), last_section_number(0)
+ 0x00, 0x00, /* section_number(0), last_section_number(0) */
- 0x00, 0x01, // program_number(1)
+ 0x00, 0x01, /* program_number(1) */
- 0xe0, 0x00, // PMT PID
+ 0xe0, 0x00, /* PMT PID */
- 0x00, 0x00, 0x00, 0x00 // CRC32
+ 0x00, 0x00, 0x00, 0x00 /* CRC32 */
};
static u8 PMT[] = {
- 0xc2, // i2c register
- 0x01, // table number for encoder
+ 0xc2, /* i2c register */
+ 0x01, /* table number for encoder */
- 0x47, // sync
- 0x40, 0x00, // transport_error_indicator(0), payload_unit_start(1), transport_priority(0), pid
- 0x10, // transport_scrambling_control(00), adaptation_field_control(01), continuity_counter(0)
+ 0x47, /* sync */
+ 0x40, 0x00, /* transport_error_indicator(0), payload_unit_start(1), transport_priority(0), pid */
+ 0x10, /* transport_scrambling_control(00), adaptation_field_control(01), continuity_counter(0) */
- 0x00, // PSI pointer to start of table
+ 0x00, /* PSI pointer to start of table */
- 0x02, // tid(2)
- 0xb0, 0x17, // section_syntax_indicator(1), section_length(23)
+ 0x02, /* tid(2) */
+ 0xb0, 0x17, /* section_syntax_indicator(1), section_length(23) */
- 0x00, 0x01, // program_number(1)
+ 0x00, 0x01, /* program_number(1) */
- 0xc1, // version_number(0), current_next_indicator(1)
+ 0xc1, /* version_number(0), current_next_indicator(1) */
- 0x00, 0x00, // section_number(0), last_section_number(0)
+ 0x00, 0x00, /* section_number(0), last_section_number(0) */
- 0xe0, 0x00, // PCR_PID
+ 0xe0, 0x00, /* PCR_PID */
- 0xf0, 0x00, // program_info_length(0)
+ 0xf0, 0x00, /* program_info_length(0) */
- 0x02, 0xe0, 0x00, 0xf0, 0x00, // video stream type(2), pid
- 0x04, 0xe0, 0x00, 0xf0, 0x00, // audio stream type(4), pid
+ 0x02, 0xe0, 0x00, 0xf0, 0x00, /* video stream type(2), pid */
+ 0x04, 0xe0, 0x00, 0xf0, 0x00, /* audio stream type(4), pid */
- 0x00, 0x00, 0x00, 0x00 // CRC32
+ 0x00, 0x00, 0x00, 0x00 /* CRC32 */
};
static struct v4l2_mpeg_compression param_defaults =
@@ -166,33 +166,33 @@ static int saa6752hs_chip_command(struct i2c_client* client,
unsigned long timeout;
int status = 0;
- // execute the command
+ /* execute the command */
switch(command) {
- case SAA6752HS_COMMAND_RESET:
- buf[0] = 0x00;
+ case SAA6752HS_COMMAND_RESET:
+ buf[0] = 0x00;
break;
case SAA6752HS_COMMAND_STOP:
- buf[0] = 0x03;
+ buf[0] = 0x03;
break;
case SAA6752HS_COMMAND_START:
- buf[0] = 0x02;
+ buf[0] = 0x02;
break;
case SAA6752HS_COMMAND_PAUSE:
- buf[0] = 0x04;
+ buf[0] = 0x04;
break;
case SAA6752HS_COMMAND_RECONFIGURE:
buf[0] = 0x05;
break;
- case SAA6752HS_COMMAND_SLEEP:
- buf[0] = 0x06;
+ case SAA6752HS_COMMAND_SLEEP:
+ buf[0] = 0x06;
break;
- case SAA6752HS_COMMAND_RECONFIGURE_FORCE:
+ case SAA6752HS_COMMAND_RECONFIGURE_FORCE:
buf[0] = 0x07;
break;
@@ -200,13 +200,13 @@ static int saa6752hs_chip_command(struct i2c_client* client,
return -EINVAL;
}
- // set it and wait for it to be so
+ /* set it and wait for it to be so */
i2c_master_send(client, buf, 1);
timeout = jiffies + HZ * 3;
for (;;) {
- // get the current status
+ /* get the current status */
buf[0] = 0x10;
- i2c_master_send(client, buf, 1);
+ i2c_master_send(client, buf, 1);
i2c_master_recv(client, buf, 1);
if (!(buf[0] & 0x20))
@@ -216,61 +216,58 @@ static int saa6752hs_chip_command(struct i2c_client* client,
break;
}
- // wait a bit
msleep(10);
}
- // delay a bit to let encoder settle
+ /* delay a bit to let encoder settle */
msleep(50);
- // done
- return status;
+ return status;
}
static int saa6752hs_set_bitrate(struct i2c_client* client,
struct v4l2_mpeg_compression* params)
{
- u8 buf[3];
+ u8 buf[3];
- // set the bitrate mode
+ /* set the bitrate mode */
buf[0] = 0x71;
buf[1] = (params->vi_bitrate.mode == V4L2_BITRATE_VBR) ? 0 : 1;
i2c_master_send(client, buf, 2);
- // set the video bitrate
+ /* set the video bitrate */
if (params->vi_bitrate.mode == V4L2_BITRATE_VBR) {
- // set the target bitrate
+ /* set the target bitrate */
buf[0] = 0x80;
buf[1] = params->vi_bitrate.target >> 8;
- buf[2] = params->vi_bitrate.target & 0xff;
+ buf[2] = params->vi_bitrate.target & 0xff;
i2c_master_send(client, buf, 3);
- // set the max bitrate
+ /* set the max bitrate */
buf[0] = 0x81;
buf[1] = params->vi_bitrate.max >> 8;
- buf[2] = params->vi_bitrate.max & 0xff;
+ buf[2] = params->vi_bitrate.max & 0xff;
i2c_master_send(client, buf, 3);
} else {
- // set the target bitrate (no max bitrate for CBR)
- buf[0] = 0x81;
+ /* set the target bitrate (no max bitrate for CBR) */
+ buf[0] = 0x81;
buf[1] = params->vi_bitrate.target >> 8;
- buf[2] = params->vi_bitrate.target & 0xff;
+ buf[2] = params->vi_bitrate.target & 0xff;
i2c_master_send(client, buf, 3);
}
- // set the audio bitrate
- buf[0] = 0x94;
+ /* set the audio bitrate */
+ buf[0] = 0x94;
buf[1] = (256 == params->au_bitrate.target) ? 0 : 1;
i2c_master_send(client, buf, 2);
- // set the total bitrate
+ /* set the total bitrate */
buf[0] = 0xb1;
- buf[1] = params->st_bitrate.target >> 8;
- buf[2] = params->st_bitrate.target & 0xff;
+ buf[1] = params->st_bitrate.target >> 8;
+ buf[2] = params->st_bitrate.target & 0xff;
i2c_master_send(client, buf, 3);
- // return success
return 0;
}
@@ -376,36 +373,43 @@ static int saa6752hs_init(struct i2c_client* client)
h = i2c_get_clientdata(client);
- // Set video format - must be done first as it resets other settings
+ /* Set video format - must be done first as it resets other settings */
buf[0] = 0x41;
buf[1] = h->video_format;
i2c_master_send(client, buf, 2);
- // set bitrate
- saa6752hs_set_bitrate(client, &h->params);
+ /* Set number of lines in input signal */
+ buf[0] = 0x40;
+ buf[1] = 0x00;
+ if (h->standard & V4L2_STD_525_60)
+ buf[1] = 0x01;
+ i2c_master_send(client, buf, 2);
+
+ /* set bitrate */
+ saa6752hs_set_bitrate(client, &h->params);
- // Set GOP structure {3, 13}
+ /* Set GOP structure {3, 13} */
buf[0] = 0x72;
buf[1] = 0x03;
buf[2] = 0x0D;
i2c_master_send(client,buf,3);
- // Set minimum Q-scale {4}
+ /* Set minimum Q-scale {4} */
buf[0] = 0x82;
buf[1] = 0x04;
i2c_master_send(client,buf,2);
- // Set maximum Q-scale {12}
+ /* Set maximum Q-scale {12} */
buf[0] = 0x83;
buf[1] = 0x0C;
i2c_master_send(client,buf,2);
- // Set Output Protocol
+ /* Set Output Protocol */
buf[0] = 0xD0;
buf[1] = 0x81;
i2c_master_send(client,buf,2);
- // Set video output stream format {TS}
+ /* Set video output stream format {TS} */
buf[0] = 0xB0;
buf[1] = 0x05;
i2c_master_send(client,buf,2);
@@ -421,9 +425,9 @@ static int saa6752hs_init(struct i2c_client* client)
localPAT[sizeof(PAT) - 1] = crc & 0xFF;
/* compute PMT */
- memcpy(localPMT, PMT, sizeof(PMT));
- localPMT[3] = 0x40 | ((h->params.ts_pid_pmt >> 8) & 0x0f);
- localPMT[4] = h->params.ts_pid_pmt & 0xff;
+ memcpy(localPMT, PMT, sizeof(PMT));
+ localPMT[3] = 0x40 | ((h->params.ts_pid_pmt >> 8) & 0x0f);
+ localPMT[4] = h->params.ts_pid_pmt & 0xff;
localPMT[15] = 0xE0 | ((h->params.ts_pid_pcr >> 8) & 0x0F);
localPMT[16] = h->params.ts_pid_pcr & 0xFF;
localPMT[20] = 0xE0 | ((h->params.ts_pid_video >> 8) & 0x0F);
@@ -436,39 +440,39 @@ static int saa6752hs_init(struct i2c_client* client)
localPMT[sizeof(PMT) - 2] = (crc >> 8) & 0xFF;
localPMT[sizeof(PMT) - 1] = crc & 0xFF;
- // Set Audio PID
+ /* Set Audio PID */
buf[0] = 0xC1;
buf[1] = (h->params.ts_pid_audio >> 8) & 0xFF;
buf[2] = h->params.ts_pid_audio & 0xFF;
i2c_master_send(client,buf,3);
- // Set Video PID
+ /* Set Video PID */
buf[0] = 0xC0;
buf[1] = (h->params.ts_pid_video >> 8) & 0xFF;
buf[2] = h->params.ts_pid_video & 0xFF;
i2c_master_send(client,buf,3);
- // Set PCR PID
+ /* Set PCR PID */
buf[0] = 0xC4;
buf[1] = (h->params.ts_pid_pcr >> 8) & 0xFF;
buf[2] = h->params.ts_pid_pcr & 0xFF;
i2c_master_send(client,buf,3);
- // Send SI tables
+ /* Send SI tables */
i2c_master_send(client,localPAT,sizeof(PAT));
i2c_master_send(client,localPMT,sizeof(PMT));
- // mute then unmute audio. This removes buzzing artefacts
+ /* mute then unmute audio. This removes buzzing artefacts */
buf[0] = 0xa4;
buf[1] = 1;
i2c_master_send(client, buf, 2);
- buf[1] = 0;
+ buf[1] = 0;
i2c_master_send(client, buf, 2);
- // start it going
+ /* start it going */
saa6752hs_chip_command(client, SAA6752HS_COMMAND_START);
- // readout current state
+ /* readout current state */
buf[0] = 0xE1;
buf[1] = 0xA7;
buf[2] = 0xFE;
@@ -477,7 +481,7 @@ static int saa6752hs_init(struct i2c_client* client)
i2c_master_send(client, buf, 5);
i2c_master_recv(client, buf2, 4);
- // change aspect ratio
+ /* change aspect ratio */
buf[0] = 0xE0;
buf[1] = 0xA7;
buf[2] = 0xFE;
@@ -498,7 +502,6 @@ static int saa6752hs_init(struct i2c_client* client)
buf[8] = buf2[3];
i2c_master_send(client, buf, 9);
- // return success
return 0;
}
@@ -506,16 +509,19 @@ static int saa6752hs_attach(struct i2c_adapter *adap, int addr, int kind)
{
struct saa6752hs_state *h;
- printk("saa6752hs: chip found @ 0x%x\n", addr<<1);
+ printk("saa6752hs: chip found @ 0x%x\n", addr<<1);
- if (NULL == (h = kmalloc(sizeof(*h), GFP_KERNEL)))
- return -ENOMEM;
+ if (NULL == (h = kmalloc(sizeof(*h), GFP_KERNEL)))
+ return -ENOMEM;
memset(h,0,sizeof(*h));
h->client = client_template;
h->params = param_defaults;
h->client.adapter = adap;
h->client.addr = addr;
+ /* Assume 625 input lines */
+ h->standard = 0;
+
i2c_set_clientdata(&h->client, h);
i2c_attach_client(&h->client);
return 0;
@@ -545,7 +551,7 @@ saa6752hs_command(struct i2c_client *client, unsigned int cmd, void *arg)
struct v4l2_mpeg_compression *params = arg;
int err = 0;
- switch (cmd) {
+ switch (cmd) {
case VIDIOC_S_MPEGCOMP:
if (NULL == params) {
/* apply settings and start encoder */
@@ -559,7 +565,7 @@ saa6752hs_command(struct i2c_client *client, unsigned int cmd, void *arg)
break;
case VIDIOC_G_FMT:
{
- struct v4l2_format *f = arg;
+ struct v4l2_format *f = arg;
if (h->video_format == SAA6752HS_VF_UNKNOWN)
h->video_format = SAA6752HS_VF_D1;
@@ -576,6 +582,9 @@ saa6752hs_command(struct i2c_client *client, unsigned int cmd, void *arg)
saa6752hs_set_subsampling(client, f);
break;
}
+ case VIDIOC_S_STD:
+ h->standard = *((v4l2_std_id *) arg);
+ break;
default:
/* nothing */
break;
diff --git a/drivers/media/video/saa7134/saa7134-alsa.c b/drivers/media/video/saa7134/saa7134-alsa.c
new file mode 100644
index 000000000000..4f3c42354329
--- /dev/null
+++ b/drivers/media/video/saa7134/saa7134-alsa.c
@@ -0,0 +1,1047 @@
+/*
+ * SAA713x ALSA support for V4L
+ *
+ *
+ * Caveats:
+ * - Volume doesn't work (it's always at max)
+ *
+ * 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
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <sound/driver.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/time.h>
+#include <linux/wait.h>
+#include <linux/moduleparam.h>
+#include <linux/module.h>
+#include <sound/core.h>
+#include <sound/control.h>
+#include <sound/pcm.h>
+#include <sound/initval.h>
+
+#include "saa7134.h"
+#include "saa7134-reg.h"
+
+static unsigned int debug = 0;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug,"enable debug messages [alsa]");
+
+/*
+ * Configuration macros
+ */
+
+/* defaults */
+#define MIXER_ADDR_TVTUNER 0
+#define MIXER_ADDR_LINE1 1
+#define MIXER_ADDR_LINE2 2
+#define MIXER_ADDR_LAST 2
+
+static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
+static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
+static int enable[SNDRV_CARDS] = {1, [1 ... (SNDRV_CARDS - 1)] = 0};
+
+module_param_array(index, int, NULL, 0444);
+MODULE_PARM_DESC(index, "Index value for SAA7134 capture interface(s).");
+
+#define dprintk(fmt, arg...) if (debug) \
+ printk(KERN_DEBUG "%s/alsa: " fmt, dev->name , ## arg)
+
+/*
+ * Main chip structure
+ */
+typedef struct snd_card_saa7134 {
+ snd_card_t *card;
+ spinlock_t mixer_lock;
+ int mixer_volume[MIXER_ADDR_LAST+1][2];
+ int capture_source[MIXER_ADDR_LAST+1][2];
+ struct pci_dev *pci;
+ struct saa7134_dev *saadev;
+
+ unsigned long iobase;
+ int irq;
+
+ spinlock_t lock;
+} snd_card_saa7134_t;
+
+
+
+/*
+ * PCM structure
+ */
+
+typedef struct snd_card_saa7134_pcm {
+ struct saa7134_dev *saadev;
+
+ spinlock_t lock;
+ unsigned int pcm_size; /* buffer size */
+ unsigned int pcm_count; /* bytes per period */
+ unsigned int pcm_bps; /* bytes per second */
+ snd_pcm_substream_t *substream;
+} snd_card_saa7134_pcm_t;
+
+static snd_card_t *snd_saa7134_cards[SNDRV_CARDS];
+
+
+/*
+ * saa7134 DMA audio stop
+ *
+ * Called when the capture device is released or the buffer overflows
+ *
+ * - Copied verbatim from saa7134-oss's dsp_dma_stop. Can be dropped
+ * if we just share dsp_dma_stop and use it here
+ *
+ */
+
+static void saa7134_dma_stop(struct saa7134_dev *dev)
+
+{
+ dev->dmasound.dma_blk = -1;
+ dev->dmasound.dma_running = 0;
+ saa7134_set_dmabits(dev);
+}
+
+/*
+ * saa7134 DMA audio start
+ *
+ * Called when preparing the capture device for use
+ *
+ * - Copied verbatim from saa7134-oss's dsp_dma_start. Can be dropped
+ * if we just share dsp_dma_start and use it here
+ *
+ */
+
+static void saa7134_dma_start(struct saa7134_dev *dev)
+{
+ dev->dmasound.dma_blk = 0;
+ dev->dmasound.dma_running = 1;
+ saa7134_set_dmabits(dev);
+}
+
+/*
+ * saa7134 audio DMA IRQ handler
+ *
+ * Called whenever we get an SAA7134_IRQ_REPORT_DONE_RA3 interrupt
+ * Handles shifting between the 2 buffers, manages the read counters,
+ * and notifies ALSA when periods elapse
+ *
+ * - Mostly copied from saa7134-oss's saa7134_irq_oss_done.
+ *
+ */
+
+void saa7134_irq_alsa_done(struct saa7134_dev *dev, unsigned long status)
+{
+ int next_blk, reg = 0;
+
+ spin_lock(&dev->slock);
+ if (UNSET == dev->dmasound.dma_blk) {
+ dprintk("irq: recording stopped\n");
+ goto done;
+ }
+ if (0 != (status & 0x0f000000))
+ dprintk("irq: lost %ld\n", (status >> 24) & 0x0f);
+ if (0 == (status & 0x10000000)) {
+ /* odd */
+ if (0 == (dev->dmasound.dma_blk & 0x01))
+ reg = SAA7134_RS_BA1(6);
+ } else {
+ /* even */
+ if (1 == (dev->dmasound.dma_blk & 0x01))
+ reg = SAA7134_RS_BA2(6);
+ }
+ if (0 == reg) {
+ dprintk("irq: field oops [%s]\n",
+ (status & 0x10000000) ? "even" : "odd");
+ goto done;
+ }
+
+ if (dev->dmasound.read_count >= dev->dmasound.blksize * (dev->dmasound.blocks-2)) {
+ dprintk("irq: overrun [full=%d/%d] - Blocks in %d\n",dev->dmasound.read_count,
+ dev->dmasound.bufsize, dev->dmasound.blocks);
+ snd_pcm_stop(dev->dmasound.substream,SNDRV_PCM_STATE_XRUN);
+ saa7134_dma_stop(dev);
+ goto done;
+ }
+
+ /* next block addr */
+ next_blk = (dev->dmasound.dma_blk + 2) % dev->dmasound.blocks;
+ saa_writel(reg,next_blk * dev->dmasound.blksize);
+ if (debug > 2)
+ dprintk("irq: ok, %s, next_blk=%d, addr=%x, blocks=%u, size=%u, read=%u\n",
+ (status & 0x10000000) ? "even" : "odd ", next_blk,
+ next_blk * dev->dmasound.blksize, dev->dmasound.blocks, dev->dmasound.blksize, dev->dmasound.read_count);
+
+ /* update status & wake waiting readers */
+ dev->dmasound.dma_blk = (dev->dmasound.dma_blk + 1) % dev->dmasound.blocks;
+ dev->dmasound.read_count += dev->dmasound.blksize;
+
+ dev->dmasound.recording_on = reg;
+
+ if (dev->dmasound.read_count >= snd_pcm_lib_period_bytes(dev->dmasound.substream)) {
+ spin_unlock(&dev->slock);
+ snd_pcm_period_elapsed(dev->dmasound.substream);
+ spin_lock(&dev->slock);
+ }
+ done:
+ spin_unlock(&dev->slock);
+
+}
+
+/*
+ * IRQ request handler
+ *
+ * Runs along with saa7134's IRQ handler, discards anything that isn't
+ * DMA sound
+ *
+ */
+
+static irqreturn_t saa7134_alsa_irq(int irq, void *dev_id, struct pt_regs *regs)
+{
+ struct saa7134_dev *dev = (struct saa7134_dev*) dev_id;
+ unsigned long report, status;
+ int loop, handled = 0;
+
+ for (loop = 0; loop < 10; loop++) {
+ report = saa_readl(SAA7134_IRQ_REPORT);
+ status = saa_readl(SAA7134_IRQ_STATUS);
+
+ if (report & SAA7134_IRQ_REPORT_DONE_RA3) {
+ handled = 1;
+ saa_writel(SAA7134_IRQ_REPORT,report);
+ saa7134_irq_alsa_done(dev, status);
+ } else {
+ goto out;
+ }
+ }
+
+ if (loop == 10) {
+ dprintk("error! looping IRQ!");
+ }
+
+out:
+ return IRQ_RETVAL(handled);
+}
+
+/*
+ * ALSA capture trigger
+ *
+ * - One of the ALSA capture callbacks.
+ *
+ * Called whenever a capture is started or stopped. Must be defined,
+ * but there's nothing we want to do here
+ *
+ */
+
+static int snd_card_saa7134_capture_trigger(snd_pcm_substream_t * substream,
+ int cmd)
+{
+ snd_pcm_runtime_t *runtime = substream->runtime;
+ snd_card_saa7134_pcm_t *saapcm = runtime->private_data;
+ struct saa7134_dev *dev=saapcm->saadev;
+ int err = 0;
+
+ spin_lock_irq(&dev->slock);
+ if (cmd == SNDRV_PCM_TRIGGER_START) {
+ /* start dma */
+ saa7134_dma_start(dev);
+ } else if (cmd == SNDRV_PCM_TRIGGER_STOP) {
+ /* stop dma */
+ saa7134_dma_stop(dev);
+ } else {
+ err = -EINVAL;
+ }
+ spin_unlock_irq(&dev->slock);
+
+ return err;
+}
+
+/*
+ * DMA buffer config
+ *
+ * Sets the values that will later be used as the size of the buffer,
+ * size of the fragments, and total number of fragments.
+ * Must be called during the preparation stage, before memory is
+ * allocated
+ *
+ * - Copied verbatim from saa7134-oss. Can be dropped
+ * if we just share dsp_buffer_conf from OSS.
+ */
+
+static int dsp_buffer_conf(struct saa7134_dev *dev, int blksize, int blocks)
+{
+ if (blksize < 0x100)
+ blksize = 0x100;
+ if (blksize > 0x10000)
+ blksize = 0x10000;
+
+ if (blocks < 2)
+ blocks = 2;
+ if ((blksize * blocks) > 1024*1024)
+ blocks = 1024*1024 / blksize;
+
+ dev->dmasound.blocks = blocks;
+ dev->dmasound.blksize = blksize;
+ dev->dmasound.bufsize = blksize * blocks;
+
+ dprintk("buffer config: %d blocks / %d bytes, %d kB total\n",
+ blocks,blksize,blksize * blocks / 1024);
+ return 0;
+}
+
+/*
+ * DMA buffer initialization
+ *
+ * Uses V4L functions to initialize the DMA. Shouldn't be necessary in
+ * ALSA, but I was unable to use ALSA's own DMA, and had to force the
+ * usage of V4L's
+ *
+ * - Copied verbatim from saa7134-oss. Can be dropped
+ * if we just share dsp_buffer_init from OSS.
+ */
+
+static int dsp_buffer_init(struct saa7134_dev *dev)
+{
+ int err;
+
+ if (!dev->dmasound.bufsize)
+ BUG();
+ videobuf_dma_init(&dev->dmasound.dma);
+ err = videobuf_dma_init_kernel(&dev->dmasound.dma, PCI_DMA_FROMDEVICE,
+ (dev->dmasound.bufsize + PAGE_SIZE) >> PAGE_SHIFT);
+ if (0 != err)
+ return err;
+ return 0;
+}
+
+/*
+ * ALSA PCM preparation
+ *
+ * - One of the ALSA capture callbacks.
+ *
+ * Called right after the capture device is opened, this function configures
+ * the buffer using the previously defined functions, allocates the memory,
+ * sets up the hardware registers, and then starts the DMA. When this function
+ * returns, the audio should be flowing.
+ *
+ */
+
+static int snd_card_saa7134_capture_prepare(snd_pcm_substream_t * substream)
+{
+ snd_pcm_runtime_t *runtime = substream->runtime;
+ int err, bswap, sign;
+ u32 fmt, control;
+ snd_card_saa7134_t *saa7134 = snd_pcm_substream_chip(substream);
+ struct saa7134_dev *dev;
+ snd_card_saa7134_pcm_t *saapcm = runtime->private_data;
+ unsigned int bps;
+ unsigned long size;
+ unsigned count;
+
+ size = snd_pcm_lib_buffer_bytes(substream);
+ count = snd_pcm_lib_period_bytes(substream);
+
+ saapcm->saadev->dmasound.substream = substream;
+ bps = runtime->rate * runtime->channels;
+ bps *= snd_pcm_format_width(runtime->format);
+ bps /= 8;
+ if (bps <= 0)
+ return -EINVAL;
+ saapcm->pcm_bps = bps;
+ saapcm->pcm_size = snd_pcm_lib_buffer_bytes(substream);
+ saapcm->pcm_count = snd_pcm_lib_period_bytes(substream);
+
+
+ dev=saa7134->saadev;
+
+ dsp_buffer_conf(dev,saapcm->pcm_count,(saapcm->pcm_size/saapcm->pcm_count));
+
+ err = dsp_buffer_init(dev);
+ if (0 != err)
+ goto fail2;
+
+ /* prepare buffer */
+ if (0 != (err = videobuf_dma_pci_map(dev->pci,&dev->dmasound.dma)))
+ return err;
+ if (0 != (err = saa7134_pgtable_alloc(dev->pci,&dev->dmasound.pt)))
+ goto fail1;
+ if (0 != (err = saa7134_pgtable_build(dev->pci,&dev->dmasound.pt,
+ dev->dmasound.dma.sglist,
+ dev->dmasound.dma.sglen,
+ 0)))
+ goto fail2;
+
+
+
+ switch (runtime->format) {
+ case SNDRV_PCM_FORMAT_U8:
+ case SNDRV_PCM_FORMAT_S8:
+ fmt = 0x00;
+ break;
+ case SNDRV_PCM_FORMAT_U16_LE:
+ case SNDRV_PCM_FORMAT_U16_BE:
+ case SNDRV_PCM_FORMAT_S16_LE:
+ case SNDRV_PCM_FORMAT_S16_BE:
+ fmt = 0x01;
+ break;
+ default:
+ err = -EINVAL;
+ return 1;
+ }
+
+ switch (runtime->format) {
+ case SNDRV_PCM_FORMAT_S8:
+ case SNDRV_PCM_FORMAT_S16_LE:
+ case SNDRV_PCM_FORMAT_S16_BE:
+ sign = 1;
+ break;
+ default:
+ sign = 0;
+ break;
+ }
+
+ switch (runtime->format) {
+ case SNDRV_PCM_FORMAT_U16_BE:
+ case SNDRV_PCM_FORMAT_S16_BE:
+ bswap = 1; break;
+ default:
+ bswap = 0; break;
+ }
+
+ switch (dev->pci->device) {
+ case PCI_DEVICE_ID_PHILIPS_SAA7134:
+ if (1 == runtime->channels)
+ fmt |= (1 << 3);
+ if (2 == runtime->channels)
+ fmt |= (3 << 3);
+ if (sign)
+ fmt |= 0x04;
+
+ fmt |= (MIXER_ADDR_TVTUNER == dev->dmasound.input) ? 0xc0 : 0x80;
+ saa_writeb(SAA7134_NUM_SAMPLES0, ((dev->dmasound.blksize - 1) & 0x0000ff));
+ saa_writeb(SAA7134_NUM_SAMPLES1, ((dev->dmasound.blksize - 1) & 0x00ff00) >> 8);
+ saa_writeb(SAA7134_NUM_SAMPLES2, ((dev->dmasound.blksize - 1) & 0xff0000) >> 16);
+ saa_writeb(SAA7134_AUDIO_FORMAT_CTRL, fmt);
+
+ break;
+ case PCI_DEVICE_ID_PHILIPS_SAA7133:
+ case PCI_DEVICE_ID_PHILIPS_SAA7135:
+ if (1 == runtime->channels)
+ fmt |= (1 << 4);
+ if (2 == runtime->channels)
+ fmt |= (2 << 4);
+ if (!sign)
+ fmt |= 0x04;
+ saa_writel(SAA7133_NUM_SAMPLES, dev->dmasound.blksize -1);
+ saa_writel(SAA7133_AUDIO_CHANNEL, 0x543210 | (fmt << 24));
+ //saa_writel(SAA7133_AUDIO_CHANNEL, 0x543210);
+ break;
+ }
+
+ dprintk("rec_start: afmt=%d ch=%d => fmt=0x%x swap=%c\n",
+ runtime->format, runtime->channels, fmt,
+ bswap ? 'b' : '-');
+ /* dma: setup channel 6 (= AUDIO) */
+ control = SAA7134_RS_CONTROL_BURST_16 |
+ SAA7134_RS_CONTROL_ME |
+ (dev->dmasound.pt.dma >> 12);
+ if (bswap)
+ control |= SAA7134_RS_CONTROL_BSWAP;
+
+ /* I should be able to use runtime->dma_addr in the control
+ byte, but it doesn't work. So I allocate the DMA using the
+ V4L functions, and force ALSA to use that as the DMA area */
+
+ runtime->dma_area = dev->dmasound.dma.vmalloc;
+
+ saa_writel(SAA7134_RS_BA1(6),0);
+ saa_writel(SAA7134_RS_BA2(6),dev->dmasound.blksize);
+ saa_writel(SAA7134_RS_PITCH(6),0);
+ saa_writel(SAA7134_RS_CONTROL(6),control);
+
+ dev->dmasound.rate = runtime->rate;
+
+ return 0;
+ fail2:
+ saa7134_pgtable_free(dev->pci,&dev->dmasound.pt);
+ fail1:
+ videobuf_dma_pci_unmap(dev->pci,&dev->dmasound.dma);
+ return err;
+
+
+}
+
+/*
+ * ALSA pointer fetching
+ *
+ * - One of the ALSA capture callbacks.
+ *
+ * Called whenever a period elapses, it must return the current hardware
+ * position of the buffer.
+ * Also resets the read counter used to prevent overruns
+ *
+ */
+
+static snd_pcm_uframes_t snd_card_saa7134_capture_pointer(snd_pcm_substream_t * substream)
+{
+ snd_pcm_runtime_t *runtime = substream->runtime;
+ snd_card_saa7134_pcm_t *saapcm = runtime->private_data;
+ struct saa7134_dev *dev=saapcm->saadev;
+
+
+
+ if (dev->dmasound.read_count) {
+ dev->dmasound.read_count -= snd_pcm_lib_period_bytes(substream);
+ dev->dmasound.read_offset += snd_pcm_lib_period_bytes(substream);
+ if (dev->dmasound.read_offset == dev->dmasound.bufsize)
+ dev->dmasound.read_offset = 0;
+ }
+
+ return bytes_to_frames(runtime, dev->dmasound.read_offset);
+}
+
+/*
+ * ALSA hardware capabilities definition
+ */
+
+static snd_pcm_hardware_t snd_card_saa7134_capture =
+{
+ .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
+ SNDRV_PCM_INFO_BLOCK_TRANSFER |
+ SNDRV_PCM_INFO_MMAP_VALID),
+ .formats = SNDRV_PCM_FMTBIT_S16_LE | \
+ SNDRV_PCM_FMTBIT_S16_BE | \
+ SNDRV_PCM_FMTBIT_S8 | \
+ SNDRV_PCM_FMTBIT_U8 | \
+ SNDRV_PCM_FMTBIT_U16_LE | \
+ SNDRV_PCM_FMTBIT_U16_BE,
+ .rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000,
+ .rate_min = 32000,
+ .rate_max = 48000,
+ .channels_min = 1,
+ .channels_max = 2,
+ .buffer_bytes_max = (256*1024),
+ .period_bytes_min = 64,
+ .period_bytes_max = (256*1024),
+ .periods_min = 2,
+ .periods_max = 1024,
+};
+
+static void snd_card_saa7134_runtime_free(snd_pcm_runtime_t *runtime)
+{
+ snd_card_saa7134_pcm_t *saapcm = runtime->private_data;
+
+ kfree(saapcm);
+}
+
+
+/*
+ * ALSA hardware params
+ *
+ * - One of the ALSA capture callbacks.
+ *
+ * Called on initialization, right before the PCM preparation
+ * Usually used in ALSA to allocate the DMA, but since we don't use the
+ * ALSA DMA it does nothing
+ *
+ */
+
+static int snd_card_saa7134_hw_params(snd_pcm_substream_t * substream,
+ snd_pcm_hw_params_t * hw_params)
+{
+
+ return 0;
+
+
+}
+
+/*
+ * ALSA hardware release
+ *
+ * - One of the ALSA capture callbacks.
+ *
+ * Called after closing the device, but before snd_card_saa7134_capture_close
+ * Usually used in ALSA to free the DMA, but since we don't use the
+ * ALSA DMA I'm almost sure this isn't necessary.
+ *
+ */
+
+static int snd_card_saa7134_hw_free(snd_pcm_substream_t * substream)
+{
+ return 0;
+}
+
+/*
+ * DMA buffer release
+ *
+ * Called after closing the device, during snd_card_saa7134_capture_close
+ *
+ */
+
+static int dsp_buffer_free(struct saa7134_dev *dev)
+{
+ if (!dev->dmasound.blksize)
+ BUG();
+
+ videobuf_dma_free(&dev->dmasound.dma);
+
+ dev->dmasound.blocks = 0;
+ dev->dmasound.blksize = 0;
+ dev->dmasound.bufsize = 0;
+
+ return 0;
+}
+
+/*
+ * ALSA capture finish
+ *
+ * - One of the ALSA capture callbacks.
+ *
+ * Called after closing the device. It stops the DMA audio and releases
+ * the buffers
+ *
+ */
+
+static int snd_card_saa7134_capture_close(snd_pcm_substream_t * substream)
+{
+ snd_card_saa7134_t *chip = snd_pcm_substream_chip(substream);
+ struct saa7134_dev *dev = chip->saadev;
+
+ /* unlock buffer */
+ saa7134_pgtable_free(dev->pci,&dev->dmasound.pt);
+ videobuf_dma_pci_unmap(dev->pci,&dev->dmasound.dma);
+
+ dsp_buffer_free(dev);
+ return 0;
+}
+
+/*
+ * ALSA capture start
+ *
+ * - One of the ALSA capture callbacks.
+ *
+ * Called when opening the device. It creates and populates the PCM
+ * structure
+ *
+ */
+
+static int snd_card_saa7134_capture_open(snd_pcm_substream_t * substream)
+{
+ snd_pcm_runtime_t *runtime = substream->runtime;
+ snd_card_saa7134_pcm_t *saapcm;
+ snd_card_saa7134_t *saa7134 = snd_pcm_substream_chip(substream);
+ struct saa7134_dev *dev = saa7134->saadev;
+ int err;
+
+ down(&dev->dmasound.lock);
+
+ dev->dmasound.afmt = SNDRV_PCM_FORMAT_U8;
+ dev->dmasound.channels = 2;
+ dev->dmasound.read_count = 0;
+ dev->dmasound.read_offset = 0;
+
+ up(&dev->dmasound.lock);
+
+ saapcm = kzalloc(sizeof(*saapcm), GFP_KERNEL);
+ if (saapcm == NULL)
+ return -ENOMEM;
+ saapcm->saadev=saa7134->saadev;
+
+ spin_lock_init(&saapcm->lock);
+
+ saapcm->substream = substream;
+ runtime->private_data = saapcm;
+ runtime->private_free = snd_card_saa7134_runtime_free;
+ runtime->hw = snd_card_saa7134_capture;
+
+ if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0)
+ return err;
+
+ return 0;
+}
+
+/*
+ * ALSA capture callbacks definition
+ */
+
+static snd_pcm_ops_t snd_card_saa7134_capture_ops = {
+ .open = snd_card_saa7134_capture_open,
+ .close = snd_card_saa7134_capture_close,
+ .ioctl = snd_pcm_lib_ioctl,
+ .hw_params = snd_card_saa7134_hw_params,
+ .hw_free = snd_card_saa7134_hw_free,
+ .prepare = snd_card_saa7134_capture_prepare,
+ .trigger = snd_card_saa7134_capture_trigger,
+ .pointer = snd_card_saa7134_capture_pointer,
+};
+
+/*
+ * ALSA PCM setup
+ *
+ * Called when initializing the board. Sets up the name and hooks up
+ * the callbacks
+ *
+ */
+
+static int snd_card_saa7134_pcm(snd_card_saa7134_t *saa7134, int device)
+{
+ snd_pcm_t *pcm;
+ int err;
+
+ if ((err = snd_pcm_new(saa7134->card, "SAA7134 PCM", device, 0, 1, &pcm)) < 0)
+ return err;
+ snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_card_saa7134_capture_ops);
+ pcm->private_data = saa7134;
+ pcm->info_flags = 0;
+ strcpy(pcm->name, "SAA7134 PCM");
+ return 0;
+}
+
+#define SAA713x_VOLUME(xname, xindex, addr) \
+{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
+ .info = snd_saa7134_volume_info, \
+ .get = snd_saa7134_volume_get, .put = snd_saa7134_volume_put, \
+ .private_value = addr }
+
+static int snd_saa7134_volume_info(snd_kcontrol_t * kcontrol, snd_ctl_elem_info_t * uinfo)
+{
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+ uinfo->count = 2;
+ uinfo->value.integer.min = 0;
+ uinfo->value.integer.max = 20;
+ return 0;
+}
+
+static int snd_saa7134_volume_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+{
+ snd_card_saa7134_t *chip = snd_kcontrol_chip(kcontrol);
+ int addr = kcontrol->private_value;
+
+ ucontrol->value.integer.value[0] = chip->mixer_volume[addr][0];
+ ucontrol->value.integer.value[1] = chip->mixer_volume[addr][1];
+ return 0;
+}
+
+static int snd_saa7134_volume_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+{
+ snd_card_saa7134_t *chip = snd_kcontrol_chip(kcontrol);
+ unsigned long flags;
+ int change, addr = kcontrol->private_value;
+ int left, right;
+
+ left = ucontrol->value.integer.value[0];
+ if (left < 0)
+ left = 0;
+ if (left > 20)
+ left = 20;
+ right = ucontrol->value.integer.value[1];
+ if (right < 0)
+ right = 0;
+ if (right > 20)
+ right = 20;
+ spin_lock_irqsave(&chip->mixer_lock, flags);
+ change = chip->mixer_volume[addr][0] != left ||
+ chip->mixer_volume[addr][1] != right;
+ chip->mixer_volume[addr][0] = left;
+ chip->mixer_volume[addr][1] = right;
+ spin_unlock_irqrestore(&chip->mixer_lock, flags);
+ return change;
+}
+
+#define SAA713x_CAPSRC(xname, xindex, addr) \
+{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
+ .info = snd_saa7134_capsrc_info, \
+ .get = snd_saa7134_capsrc_get, .put = snd_saa7134_capsrc_put, \
+ .private_value = addr }
+
+static int snd_saa7134_capsrc_info(snd_kcontrol_t * kcontrol, snd_ctl_elem_info_t * uinfo)
+{
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
+ uinfo->count = 2;
+ uinfo->value.integer.min = 0;
+ uinfo->value.integer.max = 1;
+ return 0;
+}
+
+static int snd_saa7134_capsrc_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+{
+ snd_card_saa7134_t *chip = snd_kcontrol_chip(kcontrol);
+ unsigned long flags;
+ int addr = kcontrol->private_value;
+
+ spin_lock_irqsave(&chip->mixer_lock, flags);
+ ucontrol->value.integer.value[0] = chip->capture_source[addr][0];
+ ucontrol->value.integer.value[1] = chip->capture_source[addr][1];
+ spin_unlock_irqrestore(&chip->mixer_lock, flags);
+ return 0;
+}
+
+static int snd_saa7134_capsrc_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+{
+ snd_card_saa7134_t *chip = snd_kcontrol_chip(kcontrol);
+ unsigned long flags;
+ int change, addr = kcontrol->private_value;
+ int left, right;
+ u32 anabar, xbarin;
+ int analog_io, rate;
+ struct saa7134_dev *dev;
+
+ dev = chip->saadev;
+
+ left = ucontrol->value.integer.value[0] & 1;
+ right = ucontrol->value.integer.value[1] & 1;
+ spin_lock_irqsave(&chip->mixer_lock, flags);
+
+ change = chip->capture_source[addr][0] != left ||
+ chip->capture_source[addr][1] != right;
+ chip->capture_source[addr][0] = left;
+ chip->capture_source[addr][1] = right;
+ dev->dmasound.input=addr;
+ spin_unlock_irqrestore(&chip->mixer_lock, flags);
+
+
+ if (change) {
+ switch (dev->pci->device) {
+
+ case PCI_DEVICE_ID_PHILIPS_SAA7134:
+ switch (addr) {
+ case MIXER_ADDR_TVTUNER:
+ saa_andorb(SAA7134_AUDIO_FORMAT_CTRL, 0xc0, 0xc0);
+ saa_andorb(SAA7134_SIF_SAMPLE_FREQ, 0x03, 0x00);
+ break;
+ case MIXER_ADDR_LINE1:
+ case MIXER_ADDR_LINE2:
+ analog_io = (MIXER_ADDR_LINE1 == addr) ? 0x00 : 0x08;
+ rate = (32000 == dev->dmasound.rate) ? 0x01 : 0x03;
+ saa_andorb(SAA7134_ANALOG_IO_SELECT, 0x08, analog_io);
+ saa_andorb(SAA7134_AUDIO_FORMAT_CTRL, 0xc0, 0x80);
+ saa_andorb(SAA7134_SIF_SAMPLE_FREQ, 0x03, rate);
+ break;
+ }
+
+ break;
+ case PCI_DEVICE_ID_PHILIPS_SAA7133:
+ case PCI_DEVICE_ID_PHILIPS_SAA7135:
+ xbarin = 0x03; // adc
+ anabar = 0;
+ switch (addr) {
+ case MIXER_ADDR_TVTUNER:
+ xbarin = 0; // Demodulator
+ anabar = 2; // DACs
+ break;
+ case MIXER_ADDR_LINE1:
+ anabar = 0; // aux1, aux1
+ break;
+ case MIXER_ADDR_LINE2:
+ anabar = 9; // aux2, aux2
+ break;
+ }
+
+ /* output xbar always main channel */
+ saa_dsp_writel(dev, SAA7133_DIGITAL_OUTPUT_SEL1, 0xbbbb10);
+
+ if (left || right) { // We've got data, turn the input on
+ saa_dsp_writel(dev, SAA7133_DIGITAL_INPUT_XBAR1, xbarin);
+ saa_writel(SAA7133_ANALOG_IO_SELECT, anabar);
+ } else {
+ saa_dsp_writel(dev, SAA7133_DIGITAL_INPUT_XBAR1, 0);
+ saa_writel(SAA7133_ANALOG_IO_SELECT, 0);
+ }
+ break;
+ }
+ }
+
+ return change;
+}
+
+static snd_kcontrol_new_t snd_saa7134_controls[] = {
+SAA713x_VOLUME("Video Volume", 0, MIXER_ADDR_TVTUNER),
+SAA713x_CAPSRC("Video Capture Switch", 0, MIXER_ADDR_TVTUNER),
+SAA713x_VOLUME("Line Volume", 1, MIXER_ADDR_LINE1),
+SAA713x_CAPSRC("Line Capture Switch", 1, MIXER_ADDR_LINE1),
+SAA713x_VOLUME("Line Volume", 2, MIXER_ADDR_LINE2),
+SAA713x_CAPSRC("Line Capture Switch", 2, MIXER_ADDR_LINE2),
+};
+
+/*
+ * ALSA mixer setup
+ *
+ * Called when initializing the board. Sets up the name and hooks up
+ * the callbacks
+ *
+ */
+
+static int snd_card_saa7134_new_mixer(snd_card_saa7134_t * chip)
+{
+ snd_card_t *card = chip->card;
+ unsigned int idx;
+ int err;
+
+ snd_assert(chip != NULL, return -EINVAL);
+ strcpy(card->mixername, "SAA7134 Mixer");
+
+ for (idx = 0; idx < ARRAY_SIZE(snd_saa7134_controls); idx++) {
+ if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_saa7134_controls[idx], chip))) < 0)
+ return err;
+ }
+ return 0;
+}
+
+static int snd_saa7134_free(snd_card_saa7134_t *chip)
+{
+ return 0;
+}
+
+static int snd_saa7134_dev_free(snd_device_t *device)
+{
+ snd_card_saa7134_t *chip = device->device_data;
+ return snd_saa7134_free(chip);
+}
+
+/*
+ * ALSA initialization
+ *
+ * Called by saa7134-core, it creates the basic structures and registers
+ * the ALSA devices
+ *
+ */
+
+int alsa_card_saa7134_create (struct saa7134_dev *saadev)
+{
+ static int dev;
+
+ snd_card_t *card;
+ snd_card_saa7134_t *chip;
+ int err;
+ static snd_device_ops_t ops = {
+ .dev_free = snd_saa7134_dev_free,
+ };
+
+
+ if (dev >= SNDRV_CARDS)
+ return -ENODEV;
+ if (!enable[dev])
+ return -ENODEV;
+
+ card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
+
+ if (card == NULL)
+ return -ENOMEM;
+
+ strcpy(card->driver, "SAA7134");
+
+ /* Card "creation" */
+
+ chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
+ if (chip == NULL) {
+ return -ENOMEM;
+ }
+
+ spin_lock_init(&chip->lock);
+ spin_lock_init(&chip->mixer_lock);
+
+ chip->saadev = saadev;
+
+ chip->card = card;
+
+ chip->pci = saadev->pci;
+ chip->irq = saadev->pci->irq;
+ chip->iobase = pci_resource_start(saadev->pci, 0);
+
+ err = request_irq(saadev->pci->irq, saa7134_alsa_irq,
+ SA_SHIRQ | SA_INTERRUPT, saadev->name, saadev);
+
+ if (err < 0) {
+ printk(KERN_ERR "%s: can't get IRQ %d for ALSA\n",
+ saadev->name, saadev->pci->irq);
+ goto __nodev;
+ }
+
+ if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
+ goto __nodev;
+ }
+
+ if ((err = snd_card_saa7134_new_mixer(chip)) < 0)
+ goto __nodev;
+
+ if ((err = snd_card_saa7134_pcm(chip, 0)) < 0)
+ goto __nodev;
+
+ snd_card_set_dev(card, &chip->pci->dev);
+
+ /* End of "creation" */
+
+ strcpy(card->shortname, "SAA7134");
+ sprintf(card->longname, "%s at 0x%lx irq %d",
+ chip->saadev->name, chip->iobase, chip->irq);
+
+ if ((err = snd_card_register(card)) == 0) {
+ snd_saa7134_cards[dev] = card;
+ return 0;
+ }
+
+__nodev:
+ snd_card_free(card);
+ kfree(chip);
+ return err;
+}
+
+/*
+ * Module initializer
+ *
+ * Loops through present saa7134 cards, and assigns an ALSA device
+ * to each one
+ *
+ */
+
+static int saa7134_alsa_init(void)
+{
+ struct saa7134_dev *saadev = NULL;
+ struct list_head *list;
+
+ printk(KERN_INFO "saa7134 ALSA driver for DMA sound loaded\n");
+
+ list_for_each(list,&saa7134_devlist) {
+ saadev = list_entry(list, struct saa7134_dev, devlist);
+ alsa_card_saa7134_create(saadev);
+ }
+
+ if (saadev == NULL)
+ printk(KERN_INFO "saa7134 ALSA: no saa7134 cards found\n");
+
+ return 0;
+
+}
+
+/*
+ * Module destructor
+ */
+
+void saa7134_alsa_exit(void)
+{
+ int idx;
+
+ for (idx = 0; idx < SNDRV_CARDS; idx++) {
+ snd_card_free(snd_saa7134_cards[idx]);
+ }
+
+ printk(KERN_INFO "saa7134 ALSA driver for DMA sound unloaded\n");
+
+ return;
+}
+
+module_init(saa7134_alsa_init);
+module_exit(saa7134_alsa_exit);
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Ricardo Cerqueira");
diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c
index acc7a4335e23..663d03e5bc67 100644
--- a/drivers/media/video/saa7134/saa7134-cards.c
+++ b/drivers/media/video/saa7134/saa7134-cards.c
@@ -191,10 +191,14 @@ struct saa7134_board saa7134_boards[] = {
.amux = TV,
.tv = 1,
},{
- .name = name_comp1,
+ .name = name_comp1, /* Composite signal on S-Video input */
.vmux = 0,
.amux = LINE2,
},{
+ .name = name_comp2, /* Composite input */
+ .vmux = 3,
+ .amux = LINE2,
+ },{
.name = name_svideo,
.vmux = 8,
.amux = LINE2,
@@ -2109,8 +2113,423 @@ struct saa7134_board saa7134_boards[] = {
.gpio = 0x01,
},
},
-};
+ [SAA7134_BOARD_BEHOLD_409FM] = {
+ /* <http://tuner.beholder.ru>, Sergey <skiv@orel.ru> */
+ .name = "Beholder BeholdTV 409 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_GOTVIEW_7135] = {
+ /* Mike Baikov <mike@baikov.com> */
+ /* Andrey Cvetcov <ays14@yandex.ru> */
+ .name = "GoTView 7135 PCI",
+ .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 = 0x00200003,
+ .inputs = {{
+ .name = name_tv,
+ .vmux = 1,
+ .amux = TV,
+ .tv = 1,
+ .gpio = 0x00200003,
+ },{
+ .name = name_tv_mono,
+ .vmux = 1,
+ .amux = LINE2,
+ .gpio = 0x00200003,
+ },{
+ .name = name_comp1,
+ .vmux = 3,
+ .amux = LINE1,
+ .gpio = 0x00200003,
+ },{
+ .name = name_svideo,
+ .vmux = 8,
+ .amux = LINE1,
+ .gpio = 0x00200003,
+ }},
+ .radio = {
+ .name = name_radio,
+ .amux = LINE2,
+ .gpio = 0x00200003,
+ },
+ .mute = {
+ .name = name_mute,
+ .amux = TV,
+ .gpio = 0x00200003,
+ },
+ },
+ [SAA7134_BOARD_PHILIPS_EUROPA] = {
+ .name = "Philips EUROPA V3 reference design",
+ .audio_clock = 0x00187de7,
+ .tuner_type = TUNER_PHILIPS_TD1316,
+ .radio_type = UNSET,
+ .tuner_addr = 0x61,
+ .radio_addr = ADDR_UNSET,
+ .tda9887_conf = TDA9887_PRESENT,
+ .mpeg = SAA7134_MPEG_DVB,
+ .inputs = {{
+ .name = name_tv,
+ .vmux = 3,
+ .amux = TV,
+ .tv = 1,
+ },{
+ .name = name_comp1,
+ .vmux = 0,
+ .amux = LINE2,
+ },{
+ .name = name_svideo,
+ .vmux = 8,
+ .amux = LINE2,
+ }},
+ },
+ [SAA7134_BOARD_VIDEOMATE_DVBT_300] = {
+ .name = "Compro Videomate DVB-T300",
+ .audio_clock = 0x00187de7,
+ .tuner_type = TUNER_PHILIPS_TD1316,
+ .radio_type = UNSET,
+ .tuner_addr = 0x61,
+ .radio_addr = ADDR_UNSET,
+ .tda9887_conf = TDA9887_PRESENT,
+ .mpeg = SAA7134_MPEG_DVB,
+ .inputs = {{
+ .name = name_tv,
+ .vmux = 3,
+ .amux = TV,
+ .tv = 1,
+ },{
+ .name = name_comp1,
+ .vmux = 1,
+ .amux = LINE2,
+ },{
+ .name = name_svideo,
+ .vmux = 8,
+ .amux = LINE2,
+ }},
+ },
+ [SAA7134_BOARD_VIDEOMATE_DVBT_200] = {
+ .name = "Compro Videomate DVB-T200",
+ .tuner_type = TUNER_ABSENT,
+ .audio_clock = 0x00187de7,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .mpeg = SAA7134_MPEG_DVB,
+ .inputs = {{
+ .name = name_comp1,
+ .vmux = 0,
+ .amux = LINE1,
+ },{
+ .name = name_svideo,
+ .vmux = 8,
+ .amux = LINE1,
+ }},
+ },
+ [SAA7134_BOARD_RTD_VFG7350] = {
+ .name = "RTD Embedded Technologies VFG7350",
+ .audio_clock = 0x00200000,
+ .tuner_type = TUNER_ABSENT,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .inputs = {{
+ .name = "Composite 0",
+ .vmux = 0,
+ .amux = LINE1,
+ },{
+ .name = "Composite 1",
+ .vmux = 1,
+ .amux = LINE2,
+ },{
+ .name = "Composite 2",
+ .vmux = 2,
+ .amux = LINE1,
+ },{
+ .name = "Composite 3",
+ .vmux = 3,
+ .amux = LINE2,
+ },{
+ .name = "S-Video 0",
+ .vmux = 8,
+ .amux = LINE1,
+ },{
+ .name = "S-Video 1",
+ .vmux = 9,
+ .amux = LINE2,
+ }},
+ .mpeg = SAA7134_MPEG_EMPRESS,
+ .video_out = CCIR656,
+ .vid_port_opts = ( SET_T_CODE_POLARITY_NON_INVERTED |
+ SET_CLOCK_NOT_DELAYED |
+ SET_CLOCK_INVERTED |
+ SET_VSYNC_OFF ),
+ },
+ [SAA7134_BOARD_RTD_VFG7330] = {
+ .name = "RTD Embedded Technologies VFG7330",
+ .audio_clock = 0x00200000,
+ .tuner_type = TUNER_ABSENT,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .inputs = {{
+ .name = "Composite 0",
+ .vmux = 0,
+ .amux = LINE1,
+ },{
+ .name = "Composite 1",
+ .vmux = 1,
+ .amux = LINE2,
+ },{
+ .name = "Composite 2",
+ .vmux = 2,
+ .amux = LINE1,
+ },{
+ .name = "Composite 3",
+ .vmux = 3,
+ .amux = LINE2,
+ },{
+ .name = "S-Video 0",
+ .vmux = 8,
+ .amux = LINE1,
+ },{
+ .name = "S-Video 1",
+ .vmux = 9,
+ .amux = LINE2,
+ }},
+ },
+ [SAA7134_BOARD_FLYTVPLATINUM_MINI2] = {
+ .name = "LifeView FlyTV Platinum Mini2",
+ .audio_clock = 0x00200000,
+ .tuner_type = TUNER_PHILIPS_TDA8290,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .inputs = {{
+ .name = name_tv,
+ .vmux = 1,
+ .amux = TV,
+ .tv = 1,
+ },{
+ .name = name_comp1, /* Composite signal on S-Video input */
+ .vmux = 0,
+ .amux = LINE2,
+ },{
+ .name = name_comp2, /* Composite input */
+ .vmux = 3,
+ .amux = LINE2,
+ },{
+ .name = name_svideo,
+ .vmux = 8,
+ .amux = LINE2,
+ }},
+ },
+ [SAA7134_BOARD_AVERMEDIA_AVERTVHD_A180] = {
+ /* Michael Krufky <mkrufky@m1k.net>
+ * Uses Alps Electric TDHU2, containing NXT2004 ATSC Decoder
+ * AFAIK, there is no analog demod, thus,
+ * no support for analog television.
+ */
+ .name = "AVerMedia AVerTVHD MCE A180",
+ .audio_clock = 0x00187de7,
+ .tuner_type = TUNER_ABSENT,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .mpeg = SAA7134_MPEG_DVB,
+ .inputs = {{
+ .name = name_comp1,
+ .vmux = 3,
+ .amux = LINE2,
+ },{
+ .name = name_svideo,
+ .vmux = 8,
+ .amux = LINE2,
+ }},
+ },
+ [SAA7134_BOARD_MONSTERTV_MOBILE] = {
+ .name = "SKNet MonsterTV Mobile",
+ .audio_clock = 0x00187de7,
+ .tuner_type = TUNER_PHILIPS_TDA8290,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+
+ .inputs = {{
+ .name = name_tv,
+ .vmux = 1,
+ .amux = TV,
+ .tv = 1,
+ },{
+ .name = name_comp1,
+ .vmux = 3,
+ .amux = LINE1,
+ },{
+ .name = name_svideo,
+ .vmux = 6,
+ .amux = LINE1,
+ }},
+ },
+ [SAA7134_BOARD_PINNACLE_PCTV_110i] = {
+ .name = "Pinnacle PCTV 110i (saa7133)",
+ .audio_clock = 0x00187de7,
+ .tuner_type = TUNER_PHILIPS_TDA8290,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .gpiomask = 0x080200000,
+ .inputs = {{
+ .name = name_tv,
+ .vmux = 4,
+ .amux = TV,
+ .tv = 1,
+ },{
+ .name = name_comp1,
+ .vmux = 1,
+ .amux = LINE2,
+ },{
+ .name = name_svideo,
+ .vmux = 8,
+ .amux = LINE2,
+ }},
+ .radio = {
+ .name = name_radio,
+ .amux = LINE1,
+ },
+ },
+ [SAA7134_BOARD_ASUSTeK_P7131_DUAL] = {
+ .name = "ASUSTeK P7131 Dual",
+ .audio_clock = 0x00187de7,
+ .tuner_type = TUNER_PHILIPS_TDA8290,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .gpiomask = 1 << 21,
+ .mpeg = SAA7134_MPEG_DVB,
+ .inputs = {{
+ .name = name_tv,
+ .vmux = 1,
+ .amux = TV,
+ .tv = 1,
+ },{
+ .name = name_comp1,
+ .vmux = 3,
+ .amux = LINE2,
+ },{
+ .name = name_svideo,
+ .vmux = 8,
+ .amux = LINE2,
+ }},
+ .radio = {
+ .name = name_radio,
+ .amux = TV,
+ .gpio = 0x0200000,
+ },
+ },
+ [SAA7134_BOARD_SEDNA_PC_TV_CARDBUS] = {
+ /* Paul Tom Zalac <pzalac@gmail.com> */
+ /* Pavel Mihaylov <bin@bash.info> */
+ .name = "Sedna/MuchTV PC TV Cardbus TV/Radio (ITO25 Rev:2B)",
+ /* Sedna/MuchTV (OEM) Cardbus TV Tuner */
+ .audio_clock = 0x00187de7,
+ .tuner_type = TUNER_PHILIPS_TDA8290,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .gpiomask = 0xe880c0,
+ .inputs = {{
+ .name = name_tv,
+ .vmux = 3,
+ .amux = TV,
+ .tv = 1,
+ },{
+ .name = name_comp1,
+ .vmux = 1,
+ .amux = LINE1,
+ },{
+ .name = name_svideo,
+ .vmux = 6,
+ .amux = LINE1,
+ }},
+ .radio = {
+ .name = name_radio,
+ .amux = LINE2,
+ },
+ },
+ [SAA7134_BOARD_ASUSTEK_DIGIMATRIX_TV] = {
+ /* "Cyril Lacoux (Yack)" <clacoux@ifeelgood.org> */
+ .name = "ASUS Digimatrix TV",
+ .audio_clock = 0x00200000,
+ .tuner_type = TUNER_PHILIPS_FQ1216ME,
+ .tda9887_conf = TDA9887_PRESENT,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .inputs = {{
+ .name = name_tv,
+ .vmux = 1,
+ .amux = TV,
+ .tv = 1,
+ },{
+ .name = name_comp1,
+ .vmux = 3,
+ .amux = LINE1,
+ },{
+ .name = name_svideo,
+ .vmux = 8,
+ .amux = LINE1,
+ }},
+ },
+ [SAA7134_BOARD_PHILIPS_TIGER] = {
+ .name = "Philips Tiger reference design",
+ .audio_clock = 0x00187de7,
+ .tuner_type = TUNER_PHILIPS_TDA8290,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .mpeg = SAA7134_MPEG_DVB,
+ .inputs = {{
+ .name = name_tv,
+ .vmux = 1,
+ .amux = TV,
+ .tv = 1,
+ },{
+ .name = name_comp1,
+ .vmux = 3,
+ .amux = LINE1,
+ },{
+ .name = name_svideo,
+ .vmux = 8,
+ .amux = LINE1,
+ }},
+ },
+};
const unsigned int saa7134_bcount = ARRAY_SIZE(saa7134_boards);
@@ -2145,19 +2564,19 @@ struct pci_device_id saa7134_pci_tbl[] = {
},{
.vendor = PCI_VENDOR_ID_PHILIPS,
.device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = 0x153B,
+ .subvendor = 0x153b,
.subdevice = 0x1142,
.driver_data = SAA7134_BOARD_CINERGY400,
},{
.vendor = PCI_VENDOR_ID_PHILIPS,
.device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = 0x153B,
+ .subvendor = 0x153b,
.subdevice = 0x1143,
.driver_data = SAA7134_BOARD_CINERGY600,
},{
.vendor = PCI_VENDOR_ID_PHILIPS,
.device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = 0x153B,
+ .subvendor = 0x153b,
.subdevice = 0x1158,
.driver_data = SAA7134_BOARD_CINERGY600_MK3,
},{
@@ -2193,6 +2612,18 @@ struct pci_device_id saa7134_pci_tbl[] = {
},{
.vendor = PCI_VENDOR_ID_PHILIPS,
.device = PCI_DEVICE_ID_PHILIPS_SAA7133,
+ .subvendor = 0x14c0,
+ .subdevice = 0x1212, /* minipci, LR1212 */
+ .driver_data = SAA7134_BOARD_FLYTVPLATINUM_MINI2,
+ },{
+ .vendor = PCI_VENDOR_ID_PHILIPS,
+ .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
+ .subvendor = 0x4e42,
+ .subdevice = 0x0212, /* OEM minipci, LR212 */
+ .driver_data = SAA7134_BOARD_FLYTVPLATINUM_MINI,
+ },{
+ .vendor = PCI_VENDOR_ID_PHILIPS,
+ .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
.subvendor = 0x5168, /* Animation Technologies (LifeView) */
.subdevice = 0x0214, /* Standard PCI, LR214WF */
.driver_data = SAA7134_BOARD_FLYTVPLATINUM_FM,
@@ -2369,7 +2800,7 @@ struct pci_device_id saa7134_pci_tbl[] = {
},{
.vendor = PCI_VENDOR_ID_PHILIPS,
.device = PCI_DEVICE_ID_PHILIPS_SAA7130,
- .subvendor = 0x153B,
+ .subvendor = 0x153b,
.subdevice = 0x1152,
.driver_data = SAA7134_BOARD_CINERGY200,
},{
@@ -2434,13 +2865,18 @@ struct pci_device_id saa7134_pci_tbl[] = {
.subvendor = 0x1421,
.subdevice = 0x0350, /* PCI version */
.driver_data = SAA7134_BOARD_ADS_INSTANT_TV,
-
},{
.vendor = PCI_VENDOR_ID_PHILIPS,
.device = PCI_DEVICE_ID_PHILIPS_SAA7133,
.subvendor = 0x1421,
.subdevice = 0x0370, /* cardbus version */
.driver_data = SAA7134_BOARD_ADS_INSTANT_TV,
+ },{
+ .vendor = PCI_VENDOR_ID_PHILIPS,
+ .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
+ .subvendor = 0x1421,
+ .subdevice = 0x1370, /* cardbus version */
+ .driver_data = SAA7134_BOARD_ADS_INSTANT_TV,
},{ /* Typhoon DVB-T Duo Digital/Analog Cardbus */
.vendor = PCI_VENDOR_ID_PHILIPS,
@@ -2459,9 +2895,81 @@ struct pci_device_id saa7134_pci_tbl[] = {
.device = PCI_DEVICE_ID_PHILIPS_SAA7134,
.subvendor = 0x1043,
.subdevice = 0x0210, /* mini pci PAL/SECAM version */
- .driver_data = SAA7134_BOARD_FLYTV_DIGIMATRIX,
+ .driver_data = SAA7134_BOARD_ASUSTEK_DIGIMATRIX_TV,
},{
+ .vendor = PCI_VENDOR_ID_PHILIPS,
+ .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
+ .subvendor = 0x0000, /* It shouldn't break anything, since subdevice id seems unique */
+ .subdevice = 0x4091,
+ .driver_data = SAA7134_BOARD_BEHOLD_409FM,
+ },{
+ .vendor = PCI_VENDOR_ID_PHILIPS,
+ .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
+ .subvendor = 0x5456, /* GoTView */
+ .subdevice = 0x7135,
+ .driver_data = SAA7134_BOARD_GOTVIEW_7135,
+ },{
+ .vendor = PCI_VENDOR_ID_PHILIPS,
+ .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
+ .subvendor = PCI_VENDOR_ID_PHILIPS,
+ .subdevice = 0x2004,
+ .driver_data = SAA7134_BOARD_PHILIPS_EUROPA,
+ },{
+ .vendor = PCI_VENDOR_ID_PHILIPS,
+ .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
+ .subvendor = 0x185b,
+ .subdevice = 0xc900,
+ .driver_data = SAA7134_BOARD_VIDEOMATE_DVBT_300,
+ },{
+ .vendor = PCI_VENDOR_ID_PHILIPS,
+ .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
+ .subvendor = 0x185b,
+ .subdevice = 0xc901,
+ .driver_data = SAA7134_BOARD_VIDEOMATE_DVBT_200,
+ },{
+ .vendor = PCI_VENDOR_ID_PHILIPS,
+ .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
+ .subvendor = 0x1435,
+ .subdevice = 0x7350,
+ .driver_data = SAA7134_BOARD_RTD_VFG7350,
+ },{
+ .vendor = PCI_VENDOR_ID_PHILIPS,
+ .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
+ .subvendor = 0x1435,
+ .subdevice = 0x7330,
+ .driver_data = SAA7134_BOARD_RTD_VFG7330,
+ },{
+ .vendor = PCI_VENDOR_ID_PHILIPS,
+ .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
+ .subvendor = 0x1461,
+ .subdevice = 0x1044,
+ .driver_data = SAA7134_BOARD_AVERMEDIA_AVERTVHD_A180,
+ },{
+ .vendor = PCI_VENDOR_ID_PHILIPS,
+ .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
+ .subvendor = 0x1131,
+ .subdevice = 0x4ee9,
+ .driver_data = SAA7134_BOARD_MONSTERTV_MOBILE,
+ },{
+ .vendor = PCI_VENDOR_ID_PHILIPS,
+ .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
+ .subvendor = 0x11bd,
+ .subdevice = 0x002e,
+ .driver_data = SAA7134_BOARD_PINNACLE_PCTV_110i,
+ },{
+ .vendor = PCI_VENDOR_ID_PHILIPS,
+ .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
+ .subvendor = 0x1043,
+ .subdevice = 0x4862,
+ .driver_data = SAA7134_BOARD_ASUSTeK_P7131_DUAL,
+ },{
+ .vendor = PCI_VENDOR_ID_PHILIPS,
+ .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
+ .subvendor = PCI_VENDOR_ID_PHILIPS,
+ .subdevice = 0x2018,
+ .driver_data = SAA7134_BOARD_PHILIPS_TIGER,
+ },{
/* --- boards without eeprom + subsystem ID --- */
.vendor = PCI_VENDOR_ID_PHILIPS,
.device = PCI_DEVICE_ID_PHILIPS_SAA7134,
@@ -2530,9 +3038,10 @@ int saa7134_board_init1(struct saa7134_dev *dev)
switch (dev->board) {
case SAA7134_BOARD_FLYVIDEO2000:
case SAA7134_BOARD_FLYVIDEO3000:
- dev->has_remote = 1;
+ dev->has_remote = SAA7134_REMOTE_GPIO;
board_flyvideo(dev);
break;
+ case SAA7134_BOARD_FLYTVPLATINUM_MINI2:
case SAA7134_BOARD_FLYTVPLATINUM_FM:
case SAA7134_BOARD_CINERGY400:
case SAA7134_BOARD_CINERGY600:
@@ -2550,10 +3059,16 @@ int saa7134_board_init1(struct saa7134_dev *dev)
/* case SAA7134_BOARD_SABRENT_SBTTVFM: */ /* not finished yet */
case SAA7134_BOARD_VIDEOMATE_TV_PVR:
case SAA7134_BOARD_VIDEOMATE_TV_GOLD_PLUSII:
+ case SAA7134_BOARD_VIDEOMATE_DVBT_300:
+ case SAA7134_BOARD_VIDEOMATE_DVBT_200:
case SAA7134_BOARD_MANLI_MTV001:
case SAA7134_BOARD_MANLI_MTV002:
+ case SAA7134_BOARD_BEHOLD_409FM:
case SAA7134_BOARD_AVACSSMARTTV:
- dev->has_remote = 1;
+ case SAA7134_BOARD_GOTVIEW_7135:
+ case SAA7134_BOARD_KWORLD_TERMINATOR:
+ case SAA7134_BOARD_SEDNA_PC_TV_CARDBUS:
+ dev->has_remote = SAA7134_REMOTE_GPIO;
break;
case SAA7134_BOARD_MD5044:
printk("%s: seems there are two different versions of the MD5044\n"
@@ -2565,11 +3080,14 @@ int saa7134_board_init1(struct saa7134_dev *dev)
/* power-up tuner chip */
saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x00040000, 0x00040000);
saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x00040000, 0x00000000);
- msleep(1);
+ case SAA7134_BOARD_MONSTERTV_MOBILE:
+ /* power-up tuner chip */
+ saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x00040000, 0x00040000);
+ saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x00040000, 0x00000004);
break;
case SAA7134_BOARD_FLYDVBTDUO:
case SAA7134_BOARD_THYPHOON_DVBT_DUO_CARDBUS:
- /* turn the fan on Hac: static for the time being */
+ /* turn the fan on */
saa_writeb(SAA7134_GPIO_GPMODE3, 0x08);
saa_writeb(SAA7134_GPIO_GPSTATUS3, 0x06);
break;
@@ -2579,6 +3097,22 @@ int saa7134_board_init1(struct saa7134_dev *dev)
saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0xffffffff, 0xffffffff);
msleep(1);
break;
+ case SAA7134_BOARD_RTD_VFG7350:
+
+ /*
+ * Make sure Production Test Register at offset 0x1D1 is cleared
+ * to take chip out of test mode. Clearing bit 4 (TST_EN_AOUT)
+ * prevents pin 105 from remaining low; keeping pin 105 low
+ * continually resets the SAA6752 chip.
+ */
+
+ saa_writeb (SAA7134_PRODUCTION_TEST_MODE, 0x00);
+ break;
+ /* i2c remotes */
+ case SAA7134_BOARD_PINNACLE_PCTV_110i:
+ case SAA7134_BOARD_UPMOST_PURPLE_TV:
+ dev->has_remote = SAA7134_REMOTE_I2C;
+ break;
}
return 0;
}
@@ -2613,7 +3147,7 @@ int saa7134_board_init2(struct saa7134_dev *dev)
saa7134_i2c_call_clients (dev, TUNER_SET_TYPE_ADDR, &tun_setup);
}
break;
-case SAA7134_BOARD_MD7134:
+ case SAA7134_BOARD_MD7134:
{
struct tuner_setup tun_setup;
u8 subaddr;
@@ -2680,6 +3214,33 @@ case SAA7134_BOARD_MD7134:
saa7134_i2c_call_clients (dev, TUNER_SET_TYPE_ADDR,&tun_setup);
}
break;
+ case SAA7134_BOARD_PHILIPS_EUROPA:
+ case SAA7134_BOARD_VIDEOMATE_DVBT_300:
+ /* The Philips EUROPA based hybrid boards have the tuner connected through
+ * the channel decoder. We have to make it transparent to find it
+ */
+ {
+ struct tuner_setup tun_setup;
+ u8 data[] = { 0x07, 0x02};
+ struct i2c_msg msg = {.addr=0x08, .flags=0, .buf=data, .len = sizeof(data)};
+ i2c_transfer(&dev->i2c_adap, &msg, 1);
+
+ tun_setup.mode_mask = T_ANALOG_TV | T_DIGITAL_TV;
+ tun_setup.type = dev->tuner_type;
+ tun_setup.addr = dev->tuner_addr;
+
+ saa7134_i2c_call_clients (dev, TUNER_SET_TYPE_ADDR,&tun_setup);
+ }
+ break;
+ case SAA7134_BOARD_PHILIPS_TIGER:
+ case SAA7134_BOARD_ASUSTeK_P7131_DUAL:
+ /* this is a hybrid board, initialize to analog mode */
+ {
+ u8 data[] = { 0x3c, 0x33, 0x68};
+ struct i2c_msg msg = {.addr=0x08, .flags=0, .buf=data, .len = sizeof(data)};
+ i2c_transfer(&dev->i2c_adap, &msg, 1);
+ }
+ break;
}
return 0;
}
diff --git a/drivers/media/video/saa7134/saa7134-core.c b/drivers/media/video/saa7134/saa7134-core.c
index e5e36f3c6250..19b88744fb31 100644
--- a/drivers/media/video/saa7134/saa7134-core.c
+++ b/drivers/media/video/saa7134/saa7134-core.c
@@ -57,6 +57,10 @@ static unsigned int oss = 0;
module_param(oss, int, 0444);
MODULE_PARM_DESC(oss,"register oss devices (default: no)");
+static unsigned int alsa = 0;
+module_param(alsa, int, 0444);
+MODULE_PARM_DESC(alsa,"register alsa devices (default: no)");
+
static unsigned int latency = UNSET;
module_param(latency, int, 0444);
MODULE_PARM_DESC(latency,"pci latency timer");
@@ -190,6 +194,7 @@ void saa7134_track_gpio(struct saa7134_dev *dev, char *msg)
static int need_empress;
static int need_dvb;
+static int need_alsa;
static int pending_call(struct notifier_block *self, unsigned long state,
void *module)
@@ -197,10 +202,12 @@ static int pending_call(struct notifier_block *self, unsigned long state,
if (module != THIS_MODULE || state != MODULE_STATE_LIVE)
return NOTIFY_DONE;
- if (need_empress)
- request_module("saa7134-empress");
- if (need_dvb)
- request_module("saa7134-dvb");
+ if (need_empress)
+ request_module("saa7134-empress");
+ if (need_dvb)
+ request_module("saa7134-dvb");
+ if (need_alsa)
+ request_module("saa7134-alsa");
return NOTIFY_DONE;
}
@@ -275,8 +282,8 @@ unsigned long saa7134_buffer_base(struct saa7134_buf *buf)
int saa7134_pgtable_alloc(struct pci_dev *pci, struct saa7134_pgtable *pt)
{
- __le32 *cpu;
- dma_addr_t dma_addr;
+ __le32 *cpu;
+ dma_addr_t dma_addr;
cpu = pci_alloc_consistent(pci, SAA7134_PGTABLE_SIZE, &dma_addr);
if (NULL == cpu)
@@ -436,7 +443,7 @@ int saa7134_set_dmabits(struct saa7134_dev *dev)
ctrl |= SAA7134_MAIN_CTRL_TE0;
irq |= SAA7134_IRQ1_INTE_RA0_1 |
SAA7134_IRQ1_INTE_RA0_0;
- cap = dev->video_q.curr->vb.field;
+ cap = dev->video_q.curr->vb.field;
}
/* video capture -- dma 1+2 (planar modes) */
@@ -465,7 +472,7 @@ int saa7134_set_dmabits(struct saa7134_dev *dev)
}
/* audio capture -- dma 3 */
- if (dev->oss.dma_running) {
+ if (dev->dmasound.dma_running) {
ctrl |= SAA7134_MAIN_CTRL_TE6;
irq |= SAA7134_IRQ1_INTE_RA3_1 |
SAA7134_IRQ1_INTE_RA3_0;
@@ -570,6 +577,17 @@ static irqreturn_t saa7134_irq(int irq, void *dev_id, struct pt_regs *regs)
dev->name);
goto out;
}
+
+ /* If alsa support is active and we get a sound report, exit
+ and let the saa7134-alsa module deal with it */
+
+ if ((report & SAA7134_IRQ_REPORT_DONE_RA3) && alsa) {
+ if (irq_debug > 1)
+ printk(KERN_DEBUG "%s/irq: ignoring interrupt for ALSA\n",
+ dev->name);
+ goto out;
+ }
+
handled = 1;
saa_writel(SAA7134_IRQ_REPORT,report);
if (irq_debug)
@@ -591,13 +609,17 @@ static irqreturn_t saa7134_irq(int irq, void *dev_id, struct pt_regs *regs)
card_has_mpeg(dev))
saa7134_irq_ts_done(dev,status);
- if ((report & SAA7134_IRQ_REPORT_DONE_RA3))
- saa7134_irq_oss_done(dev,status);
+ if ((report & SAA7134_IRQ_REPORT_DONE_RA3)) {
+ if (oss) {
+ saa7134_irq_oss_done(dev,status);
+ }
+ }
if ((report & (SAA7134_IRQ_REPORT_GPIO16 |
SAA7134_IRQ_REPORT_GPIO18)) &&
dev->remote)
saa7134_input_irq(dev);
+
}
if (10 == loop) {
@@ -636,7 +658,7 @@ static int saa7134_hwinit1(struct saa7134_dev *dev)
saa_writel(SAA7134_IRQ1, 0);
saa_writel(SAA7134_IRQ2, 0);
- init_MUTEX(&dev->lock);
+ init_MUTEX(&dev->lock);
spin_lock_init(&dev->slock);
saa7134_track_gpio(dev,"pre-init");
@@ -646,14 +668,6 @@ static int saa7134_hwinit1(struct saa7134_dev *dev)
saa7134_ts_init1(dev);
saa7134_input_init1(dev);
- switch (dev->pci->device) {
- case PCI_DEVICE_ID_PHILIPS_SAA7134:
- case PCI_DEVICE_ID_PHILIPS_SAA7133:
- case PCI_DEVICE_ID_PHILIPS_SAA7135:
- saa7134_oss_init1(dev);
- break;
- }
-
/* RAM FIFO config */
saa_writel(SAA7134_FIFO_SIZE, 0x08070503);
saa_writel(SAA7134_THRESHOULD,0x02020202);
@@ -668,6 +682,21 @@ static int saa7134_hwinit1(struct saa7134_dev *dev)
SAA7134_MAIN_CTRL_ESFE |
SAA7134_MAIN_CTRL_EBDAC);
+ /*
+ * Initialize OSS _after_ enabling audio clock PLL and audio processing.
+ * OSS initialization writes to registers via the audio DSP; these
+ * writes will fail unless the audio clock has been started. At worst,
+ * audio will not work.
+ */
+
+ switch (dev->pci->device) {
+ case PCI_DEVICE_ID_PHILIPS_SAA7134:
+ case PCI_DEVICE_ID_PHILIPS_SAA7133:
+ case PCI_DEVICE_ID_PHILIPS_SAA7135:
+ saa7134_oss_init1(dev);
+ break;
+ }
+
/* enable peripheral devices */
saa_writeb(SAA7134_SPECIAL_MODE, 0x01);
@@ -687,7 +716,7 @@ static int saa7134_hwinit2(struct saa7134_dev *dev)
saa7134_tvaudio_init2(dev);
/* enable IRQ's */
- irq2_mask =
+ irq2_mask =
SAA7134_IRQ2_INTE_DEC3 |
SAA7134_IRQ2_INTE_DEC2 |
SAA7134_IRQ2_INTE_DEC1 |
@@ -695,10 +724,12 @@ static int saa7134_hwinit2(struct saa7134_dev *dev)
SAA7134_IRQ2_INTE_PE |
SAA7134_IRQ2_INTE_AR;
- if (dev->has_remote)
+ if (dev->has_remote == SAA7134_REMOTE_GPIO)
irq2_mask |= (SAA7134_IRQ2_INTE_GPIO18 |
SAA7134_IRQ2_INTE_GPIO18A |
SAA7134_IRQ2_INTE_GPIO16 );
+ else if (dev->has_remote == SAA7134_REMOTE_I2C)
+ request_module("ir-kbd-i2c");
saa_writel(SAA7134_IRQ1, 0);
saa_writel(SAA7134_IRQ2, irq2_mask);
@@ -872,8 +903,8 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
/* print pci info */
pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &dev->pci_rev);
- pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &dev->pci_lat);
- printk(KERN_INFO "%s: found at %s, rev: %d, irq: %d, "
+ pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &dev->pci_lat);
+ printk(KERN_INFO "%s: found at %s, rev: %d, irq: %d, "
"latency: %d, mmio: 0x%lx\n", dev->name,
pci_name(pci_dev), dev->pci_rev, pci_dev->irq,
dev->pci_lat,pci_resource_start(pci_dev,0));
@@ -897,7 +928,7 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
dev->tda9887_conf = saa7134_boards[dev->board].tda9887_conf;
if (UNSET != tuner[dev->nr])
dev->tuner_type = tuner[dev->nr];
- printk(KERN_INFO "%s: subsystem: %04x:%04x, board: %s [card=%d,%s]\n",
+ printk(KERN_INFO "%s: subsystem: %04x:%04x, board: %s [card=%d,%s]\n",
dev->name,pci_dev->subsystem_vendor,
pci_dev->subsystem_device,saa7134_boards[dev->board].name,
dev->board, card[dev->nr] == dev->board ?
@@ -947,14 +978,20 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
request_module("tuner");
if (dev->tda9887_conf)
request_module("tda9887");
- if (card_is_empress(dev)) {
+ if (card_is_empress(dev)) {
request_module("saa6752hs");
request_module_depend("saa7134-empress",&need_empress);
}
- if (card_is_dvb(dev))
+ if (card_is_dvb(dev))
request_module_depend("saa7134-dvb",&need_dvb);
+ if (!oss && alsa) {
+ dprintk("Requesting ALSA module\n");
+ request_module_depend("saa7134-alsa",&need_alsa);
+ }
+
+
v4l2_prio_init(&dev->prio);
/* register v4l devices */
@@ -993,22 +1030,22 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
case PCI_DEVICE_ID_PHILIPS_SAA7133:
case PCI_DEVICE_ID_PHILIPS_SAA7135:
if (oss) {
- err = dev->oss.minor_dsp =
+ err = dev->dmasound.minor_dsp =
register_sound_dsp(&saa7134_dsp_fops,
dsp_nr[dev->nr]);
if (err < 0) {
goto fail4;
}
printk(KERN_INFO "%s: registered device dsp%d\n",
- dev->name,dev->oss.minor_dsp >> 4);
+ dev->name,dev->dmasound.minor_dsp >> 4);
- err = dev->oss.minor_mixer =
+ err = dev->dmasound.minor_mixer =
register_sound_mixer(&saa7134_mixer_fops,
mixer_nr[dev->nr]);
if (err < 0)
goto fail5;
printk(KERN_INFO "%s: registered device mixer%d\n",
- dev->name,dev->oss.minor_mixer >> 4);
+ dev->name,dev->dmasound.minor_mixer >> 4);
}
break;
}
@@ -1035,7 +1072,7 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
case PCI_DEVICE_ID_PHILIPS_SAA7133:
case PCI_DEVICE_ID_PHILIPS_SAA7135:
if (oss)
- unregister_sound_dsp(dev->oss.minor_dsp);
+ unregister_sound_dsp(dev->dmasound.minor_dsp);
break;
}
fail4:
@@ -1055,7 +1092,7 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
static void __devexit saa7134_finidev(struct pci_dev *pci_dev)
{
- struct saa7134_dev *dev = pci_get_drvdata(pci_dev);
+ struct saa7134_dev *dev = pci_get_drvdata(pci_dev);
struct list_head *item;
struct saa7134_mpeg_ops *mops;
@@ -1093,8 +1130,8 @@ static void __devexit saa7134_finidev(struct pci_dev *pci_dev)
case PCI_DEVICE_ID_PHILIPS_SAA7133:
case PCI_DEVICE_ID_PHILIPS_SAA7135:
if (oss) {
- unregister_sound_mixer(dev->oss.minor_mixer);
- unregister_sound_dsp(dev->oss.minor_dsp);
+ unregister_sound_mixer(dev->dmasound.minor_mixer);
+ unregister_sound_dsp(dev->dmasound.minor_dsp);
}
break;
}
@@ -1149,10 +1186,10 @@ EXPORT_SYMBOL(saa7134_ts_unregister);
/* ----------------------------------------------------------- */
static struct pci_driver saa7134_pci_driver = {
- .name = "saa7134",
- .id_table = saa7134_pci_tbl,
- .probe = saa7134_initdev,
- .remove = __devexit_p(saa7134_finidev),
+ .name = "saa7134",
+ .id_table = saa7134_pci_tbl,
+ .probe = saa7134_initdev,
+ .remove = __devexit_p(saa7134_finidev),
};
static int saa7134_init(void)
@@ -1188,6 +1225,13 @@ EXPORT_SYMBOL(saa7134_i2c_call_clients);
EXPORT_SYMBOL(saa7134_devlist);
EXPORT_SYMBOL(saa7134_boards);
+/* ----------------- For ALSA -------------------------------- */
+
+EXPORT_SYMBOL(saa7134_pgtable_free);
+EXPORT_SYMBOL(saa7134_pgtable_build);
+EXPORT_SYMBOL(saa7134_pgtable_alloc);
+EXPORT_SYMBOL(saa7134_set_dmabits);
+
/* ----------------------------------------------------------- */
/*
* Local variables:
diff --git a/drivers/media/video/saa7134/saa7134-dvb.c b/drivers/media/video/saa7134/saa7134-dvb.c
index 639ae51a052d..e016480c3468 100644
--- a/drivers/media/video/saa7134/saa7134-dvb.c
+++ b/drivers/media/video/saa7134/saa7134-dvb.c
@@ -29,7 +29,6 @@
#include <linux/kthread.h>
#include <linux/suspend.h>
-
#include "saa7134-reg.h"
#include "saa7134.h"
@@ -40,6 +39,10 @@
#ifdef HAVE_TDA1004X
# include "tda1004x.h"
#endif
+#ifdef HAVE_NXT200X
+# include "nxt200x.h"
+# include "dvb-pll.h"
+#endif
MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
MODULE_LICENSE("GPL");
@@ -151,25 +154,12 @@ static struct mt352_config pinnacle_300i = {
/* ------------------------------------------------------------------ */
#ifdef HAVE_TDA1004X
-static int philips_tu1216_pll_init(struct dvb_frontend *fe)
-{
- struct saa7134_dev *dev = fe->dvb->priv;
- static u8 tu1216_init[] = { 0x0b, 0xf5, 0x85, 0xab };
- struct i2c_msg tuner_msg = {.addr = 0x60,.flags = 0,.buf = tu1216_init,.len = sizeof(tu1216_init) };
-
- /* setup PLL configuration */
- if (i2c_transfer(&dev->i2c_adap, &tuner_msg, 1) != 1)
- return -EIO;
- msleep(1);
- return 0;
-}
-
-static int philips_tu1216_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
+static int philips_tda6651_pll_set(u8 addr, struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
{
struct saa7134_dev *dev = fe->dvb->priv;
u8 tuner_buf[4];
- struct i2c_msg tuner_msg = {.addr = 0x60,.flags = 0,.buf = tuner_buf,.len =
+ struct i2c_msg tuner_msg = {.addr = addr,.flags = 0,.buf = tuner_buf,.len =
sizeof(tuner_buf) };
int tuner_frequency = 0;
u8 band, cp, filter;
@@ -242,11 +232,36 @@ static int philips_tu1216_pll_set(struct dvb_frontend *fe, struct dvb_frontend_p
if (i2c_transfer(&dev->i2c_adap, &tuner_msg, 1) != 1)
return -EIO;
+ msleep(1);
+ return 0;
+}
+static int philips_tda6651_pll_init(u8 addr, struct dvb_frontend *fe)
+{
+ struct saa7134_dev *dev = fe->dvb->priv;
+ static u8 tu1216_init[] = { 0x0b, 0xf5, 0x85, 0xab };
+ struct i2c_msg tuner_msg = {.addr = addr,.flags = 0,.buf = tu1216_init,.len = sizeof(tu1216_init) };
+
+ /* setup PLL configuration */
+ if (i2c_transfer(&dev->i2c_adap, &tuner_msg, 1) != 1)
+ return -EIO;
msleep(1);
+
return 0;
}
+/* ------------------------------------------------------------------ */
+
+static int philips_tu1216_pll_60_init(struct dvb_frontend *fe)
+{
+ return philips_tda6651_pll_init(0x60, fe);
+}
+
+static int philips_tu1216_pll_60_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
+{
+ return philips_tda6651_pll_set(0x60, fe, params);
+}
+
static int philips_tu1216_request_firmware(struct dvb_frontend *fe,
const struct firmware **fw, char *name)
{
@@ -254,22 +269,108 @@ static int philips_tu1216_request_firmware(struct dvb_frontend *fe,
return request_firmware(fw, name, &dev->pci->dev);
}
-static struct tda1004x_config philips_tu1216_config = {
+static struct tda1004x_config philips_tu1216_60_config = {
+
+ .demod_address = 0x8,
+ .invert = 1,
+ .invert_oclk = 0,
+ .xtal_freq = TDA10046_XTAL_4M,
+ .agc_config = TDA10046_AGC_DEFAULT,
+ .if_freq = TDA10046_FREQ_3617,
+ .pll_init = philips_tu1216_pll_60_init,
+ .pll_set = philips_tu1216_pll_60_set,
+ .pll_sleep = NULL,
+ .request_firmware = philips_tu1216_request_firmware,
+};
+
+/* ------------------------------------------------------------------ */
+
+static int philips_tu1216_pll_61_init(struct dvb_frontend *fe)
+{
+ return philips_tda6651_pll_init(0x61, fe);
+}
+
+static int philips_tu1216_pll_61_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
+{
+ return philips_tda6651_pll_set(0x61, fe, params);
+}
+
+static struct tda1004x_config philips_tu1216_61_config = {
.demod_address = 0x8,
.invert = 1,
- .invert_oclk = 1,
+ .invert_oclk = 0,
.xtal_freq = TDA10046_XTAL_4M,
.agc_config = TDA10046_AGC_DEFAULT,
.if_freq = TDA10046_FREQ_3617,
- .pll_init = philips_tu1216_pll_init,
- .pll_set = philips_tu1216_pll_set,
+ .pll_init = philips_tu1216_pll_61_init,
+ .pll_set = philips_tu1216_pll_61_set,
.pll_sleep = NULL,
.request_firmware = philips_tu1216_request_firmware,
};
/* ------------------------------------------------------------------ */
+static int philips_europa_pll_init(struct dvb_frontend *fe)
+{
+ struct saa7134_dev *dev = fe->dvb->priv;
+ static u8 msg[] = { 0x0b, 0xf5, 0x86, 0xab };
+ struct i2c_msg init_msg = {.addr = 0x61,.flags = 0,.buf = msg,.len = sizeof(msg) };
+
+ /* setup PLL configuration */
+ if (i2c_transfer(&dev->i2c_adap, &init_msg, 1) != 1)
+ return -EIO;
+ msleep(1);
+
+ /* switch the board to dvb mode */
+ init_msg.addr = 0x43;
+ init_msg.len = 0x02;
+ msg[0] = 0x00;
+ msg[1] = 0x40;
+ if (i2c_transfer(&dev->i2c_adap, &init_msg, 1) != 1)
+ return -EIO;
+
+ return 0;
+}
+
+static int philips_td1316_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
+{
+ return philips_tda6651_pll_set(0x61, fe, params);
+}
+
+static void philips_europa_analog(struct dvb_frontend *fe)
+{
+ struct saa7134_dev *dev = fe->dvb->priv;
+ /* this message actually turns the tuner back to analog mode */
+ static u8 msg[] = { 0x0b, 0xdc, 0x86, 0xa4 };
+ struct i2c_msg analog_msg = {.addr = 0x61,.flags = 0,.buf = msg,.len = sizeof(msg) };
+
+ i2c_transfer(&dev->i2c_adap, &analog_msg, 1);
+ msleep(1);
+
+ /* switch the board to analog mode */
+ analog_msg.addr = 0x43;
+ analog_msg.len = 0x02;
+ msg[0] = 0x00;
+ msg[1] = 0x14;
+ i2c_transfer(&dev->i2c_adap, &analog_msg, 1);
+}
+
+static struct tda1004x_config philips_europa_config = {
+
+ .demod_address = 0x8,
+ .invert = 0,
+ .invert_oclk = 0,
+ .xtal_freq = TDA10046_XTAL_4M,
+ .agc_config = TDA10046_AGC_IFO_AUTO_POS,
+ .if_freq = TDA10046_FREQ_052,
+ .pll_init = philips_europa_pll_init,
+ .pll_set = philips_td1316_pll_set,
+ .pll_sleep = philips_europa_analog,
+ .request_firmware = NULL,
+};
+
+/* ------------------------------------------------------------------ */
static int philips_fmd1216_pll_init(struct dvb_frontend *fe)
{
@@ -382,7 +483,6 @@ static int philips_fmd1216_pll_set(struct dvb_frontend *fe, struct dvb_frontend_
return 0;
}
-#ifdef HAVE_TDA1004X
static struct tda1004x_config medion_cardbus = {
.demod_address = 0x08,
.invert = 1,
@@ -395,7 +495,6 @@ static struct tda1004x_config medion_cardbus = {
.pll_sleep = philips_fmd1216_analog,
.request_firmware = NULL,
};
-#endif
/* ------------------------------------------------------------------ */
@@ -452,7 +551,7 @@ static int philips_tda827x_pll_set(struct dvb_frontend *fe, struct dvb_frontend_
u8 tuner_buf[14];
struct i2c_msg tuner_msg = {.addr = 0x60,.flags = 0,.buf = tuner_buf,
- .len = sizeof(tuner_buf) };
+ .len = sizeof(tuner_buf) };
int i, tuner_freq, if_freq;
u32 N;
switch (params->u.ofdm.bandwidth) {
@@ -511,7 +610,7 @@ static void philips_tda827x_pll_sleep(struct dvb_frontend *fe)
struct saa7134_dev *dev = fe->dvb->priv;
static u8 tda827x_sleep[] = { 0x30, 0xd0};
struct i2c_msg tuner_msg = {.addr = 0x60,.flags = 0,.buf = tda827x_sleep,
- .len = sizeof(tda827x_sleep) };
+ .len = sizeof(tda827x_sleep) };
i2c_transfer(&dev->i2c_adap, &tuner_msg, 1);
}
@@ -527,6 +626,202 @@ static struct tda1004x_config tda827x_lifeview_config = {
.pll_sleep = philips_tda827x_pll_sleep,
.request_firmware = NULL,
};
+
+/* ------------------------------------------------------------------ */
+
+struct tda827xa_data {
+ u32 lomax;
+ u8 svco;
+ u8 spd;
+ u8 scr;
+ u8 sbs;
+ u8 gc3;
+};
+
+static struct tda827xa_data tda827xa_dvbt[] = {
+ { .lomax = 56875000, .svco = 3, .spd = 4, .scr = 0, .sbs = 0, .gc3 = 1},
+ { .lomax = 67250000, .svco = 0, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 1},
+ { .lomax = 81250000, .svco = 1, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 1},
+ { .lomax = 97500000, .svco = 2, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 1},
+ { .lomax = 113750000, .svco = 3, .spd = 3, .scr = 0, .sbs = 1, .gc3 = 1},
+ { .lomax = 134500000, .svco = 0, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1},
+ { .lomax = 154000000, .svco = 1, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1},
+ { .lomax = 162500000, .svco = 1, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1},
+ { .lomax = 183000000, .svco = 2, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1},
+ { .lomax = 195000000, .svco = 2, .spd = 2, .scr = 0, .sbs = 2, .gc3 = 1},
+ { .lomax = 227500000, .svco = 3, .spd = 2, .scr = 0, .sbs = 2, .gc3 = 1},
+ { .lomax = 269000000, .svco = 0, .spd = 1, .scr = 0, .sbs = 2, .gc3 = 1},
+ { .lomax = 290000000, .svco = 1, .spd = 1, .scr = 0, .sbs = 2, .gc3 = 1},
+ { .lomax = 325000000, .svco = 1, .spd = 1, .scr = 0, .sbs = 3, .gc3 = 1},
+ { .lomax = 390000000, .svco = 2, .spd = 1, .scr = 0, .sbs = 3, .gc3 = 1},
+ { .lomax = 455000000, .svco = 3, .spd = 1, .scr = 0, .sbs = 3, .gc3 = 1},
+ { .lomax = 520000000, .svco = 0, .spd = 0, .scr = 0, .sbs = 3, .gc3 = 1},
+ { .lomax = 538000000, .svco = 0, .spd = 0, .scr = 1, .sbs = 3, .gc3 = 1},
+ { .lomax = 550000000, .svco = 1, .spd = 0, .scr = 0, .sbs = 3, .gc3 = 1},
+ { .lomax = 620000000, .svco = 1, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0},
+ { .lomax = 650000000, .svco = 1, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0},
+ { .lomax = 700000000, .svco = 2, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0},
+ { .lomax = 780000000, .svco = 2, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0},
+ { .lomax = 820000000, .svco = 3, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0},
+ { .lomax = 870000000, .svco = 3, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0},
+ { .lomax = 911000000, .svco = 3, .spd = 0, .scr = 2, .sbs = 4, .gc3 = 0},
+ { .lomax = 0, .svco = 0, .spd = 0, .scr = 0, .sbs = 0, .gc3 = 0}};
+
+
+static int philips_tda827xa_pll_set(u8 addr, struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
+{
+ struct saa7134_dev *dev = fe->dvb->priv;
+ u8 tuner_buf[14];
+ unsigned char reg2[2];
+
+ struct i2c_msg msg = {.addr = addr,.flags = 0,.buf = tuner_buf};
+ int i, tuner_freq, if_freq;
+ u32 N;
+
+ switch (params->u.ofdm.bandwidth) {
+ case BANDWIDTH_6_MHZ:
+ if_freq = 4000000;
+ break;
+ case BANDWIDTH_7_MHZ:
+ if_freq = 4500000;
+ break;
+ default: /* 8 MHz or Auto */
+ if_freq = 5000000;
+ break;
+ }
+ tuner_freq = params->frequency + if_freq;
+
+ i = 0;
+ while (tda827xa_dvbt[i].lomax < tuner_freq) {
+ if(tda827xa_dvbt[i + 1].lomax == 0)
+ break;
+ i++;
+ }
+
+ N = ((tuner_freq + 31250) / 62500) << tda827xa_dvbt[i].spd;
+ tuner_buf[0] = 0; // subaddress
+ tuner_buf[1] = N >> 8;
+ tuner_buf[2] = N & 0xff;
+ tuner_buf[3] = 0;
+ tuner_buf[4] = 0x16;
+ tuner_buf[5] = (tda827xa_dvbt[i].spd << 5) + (tda827xa_dvbt[i].svco << 3) +
+ tda827xa_dvbt[i].sbs;
+ tuner_buf[6] = 0x4b + (tda827xa_dvbt[i].gc3 << 4);
+ tuner_buf[7] = 0x0c;
+ tuner_buf[8] = 0x06;
+ tuner_buf[9] = 0x24;
+ tuner_buf[10] = 0xff;
+ tuner_buf[11] = 0x60;
+ tuner_buf[12] = 0x00;
+ tuner_buf[13] = 0x39; // lpsel
+ msg.len = 14;
+ if (i2c_transfer(&dev->i2c_adap, &msg, 1) != 1)
+ return -EIO;
+
+ msg.buf= reg2;
+ msg.len = 2;
+ reg2[0] = 0x60;
+ reg2[1] = 0x3c;
+ i2c_transfer(&dev->i2c_adap, &msg, 1);
+
+ reg2[0] = 0xa0;
+ reg2[1] = 0x40;
+ i2c_transfer(&dev->i2c_adap, &msg, 1);
+
+ msleep(2);
+ /* correct CP value */
+ reg2[0] = 0x30;
+ reg2[1] = 0x10 + tda827xa_dvbt[i].scr;
+ msg.len = 2;
+ i2c_transfer(&dev->i2c_adap, &msg, 1);
+
+ msleep(550);
+ reg2[0] = 0x50;
+ reg2[1] = 0x4f + (tda827xa_dvbt[i].gc3 << 4);
+ i2c_transfer(&dev->i2c_adap, &msg, 1);
+
+ return 0;
+
+}
+
+static void philips_tda827xa_pll_sleep(u8 addr, struct dvb_frontend *fe)
+{
+ struct saa7134_dev *dev = fe->dvb->priv;
+ static u8 tda827xa_sleep[] = { 0x30, 0x90};
+ struct i2c_msg tuner_msg = {.addr = addr,.flags = 0,.buf = tda827xa_sleep,
+ .len = sizeof(tda827xa_sleep) };
+ i2c_transfer(&dev->i2c_adap, &tuner_msg, 1);
+
+}
+
+/* ------------------------------------------------------------------ */
+
+static int philips_tiger_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
+{
+ int ret;
+ struct saa7134_dev *dev = fe->dvb->priv;
+ static u8 tda8290_close[] = { 0x21, 0xc0};
+ static u8 tda8290_open[] = { 0x21, 0x80};
+ struct i2c_msg tda8290_msg = {.addr = 0x4b,.flags = 0, .len = 2};
+ /* close tda8290 i2c bridge */
+ tda8290_msg.buf = tda8290_close;
+ ret = i2c_transfer(&dev->i2c_adap, &tda8290_msg, 1);
+ if (ret != 1)
+ return -EIO;
+ msleep(20);
+ ret = philips_tda827xa_pll_set(0x61, fe, params);
+ if (ret != 0)
+ return ret;
+ /* open tda8290 i2c bridge */
+ tda8290_msg.buf = tda8290_open;
+ i2c_transfer(&dev->i2c_adap, &tda8290_msg, 1);
+ return ret;
+};
+
+static int philips_tiger_dvb_mode(struct dvb_frontend *fe)
+{
+ struct saa7134_dev *dev = fe->dvb->priv;
+ static u8 data[] = { 0x3c, 0x33, 0x6a};
+ struct i2c_msg msg = {.addr=0x08, .flags=0, .buf=data, .len = sizeof(data)};
+
+ if (i2c_transfer(&dev->i2c_adap, &msg, 1) != 1)
+ return -EIO;
+ return 0;
+}
+
+static void philips_tiger_analog_mode(struct dvb_frontend *fe)
+{
+ struct saa7134_dev *dev = fe->dvb->priv;
+ static u8 data[] = { 0x3c, 0x33, 0x68};
+ struct i2c_msg msg = {.addr=0x08, .flags=0, .buf=data, .len = sizeof(data)};
+
+ i2c_transfer(&dev->i2c_adap, &msg, 1);
+ philips_tda827xa_pll_sleep( 0x61, fe);
+}
+
+static struct tda1004x_config philips_tiger_config = {
+ .demod_address = 0x08,
+ .invert = 1,
+ .invert_oclk = 0,
+ .xtal_freq = TDA10046_XTAL_16M,
+ .agc_config = TDA10046_AGC_TDA827X,
+ .if_freq = TDA10046_FREQ_045,
+ .pll_init = philips_tiger_dvb_mode,
+ .pll_set = philips_tiger_pll_set,
+ .pll_sleep = philips_tiger_analog_mode,
+ .request_firmware = NULL,
+};
+
+#endif
+
+/* ------------------------------------------------------------------ */
+
+#ifdef HAVE_NXT200X
+static struct nxt200x_config avertvhda180 = {
+ .demod_address = 0x0a,
+ .pll_address = 0x61,
+ .pll_desc = &dvb_pll_tdhu2,
+};
#endif
/* ------------------------------------------------------------------ */
@@ -558,7 +853,7 @@ static int dvb_init(struct saa7134_dev *dev)
&dev->i2c_adap);
break;
case SAA7134_BOARD_PHILIPS_TOUGH:
- dev->dvb.frontend = tda10046_attach(&philips_tu1216_config,
+ dev->dvb.frontend = tda10046_attach(&philips_tu1216_60_config,
&dev->i2c_adap);
break;
case SAA7134_BOARD_FLYDVBTDUO:
@@ -569,6 +864,31 @@ static int dvb_init(struct saa7134_dev *dev)
dev->dvb.frontend = tda10046_attach(&tda827x_lifeview_config,
&dev->i2c_adap);
break;
+ case SAA7134_BOARD_PHILIPS_EUROPA:
+ dev->dvb.frontend = tda10046_attach(&philips_europa_config,
+ &dev->i2c_adap);
+ break;
+ case SAA7134_BOARD_VIDEOMATE_DVBT_300:
+ dev->dvb.frontend = tda10046_attach(&philips_europa_config,
+ &dev->i2c_adap);
+ break;
+ case SAA7134_BOARD_VIDEOMATE_DVBT_200:
+ dev->dvb.frontend = tda10046_attach(&philips_tu1216_61_config,
+ &dev->i2c_adap);
+ break;
+ case SAA7134_BOARD_PHILIPS_TIGER:
+ dev->dvb.frontend = tda10046_attach(&philips_tiger_config,
+ &dev->i2c_adap);
+ break;
+ case SAA7134_BOARD_ASUSTeK_P7131_DUAL:
+ dev->dvb.frontend = tda10046_attach(&philips_tiger_config,
+ &dev->i2c_adap);
+ break;
+#endif
+#ifdef HAVE_NXT200X
+ case SAA7134_BOARD_AVERMEDIA_AVERTVHD_A180:
+ dev->dvb.frontend = nxt200x_attach(&avertvhda180, &dev->i2c_adap);
+ break;
#endif
default:
printk("%s: Huh? unknown DVB card?\n",dev->name);
diff --git a/drivers/media/video/saa7134/saa7134-empress.c b/drivers/media/video/saa7134/saa7134-empress.c
index 77b627eb6483..e9ec69efb4c9 100644
--- a/drivers/media/video/saa7134/saa7134-empress.c
+++ b/drivers/media/video/saa7134/saa7134-empress.c
@@ -55,7 +55,7 @@ static void ts_reset_encoder(struct saa7134_dev* dev)
saa_writeb(SAA7134_SPECIAL_MODE, 0x00);
msleep(10);
- saa_writeb(SAA7134_SPECIAL_MODE, 0x01);
+ saa_writeb(SAA7134_SPECIAL_MODE, 0x01);
msleep(100);
dev->empress_started = 0;
}
@@ -65,7 +65,7 @@ static int ts_init_encoder(struct saa7134_dev* dev)
ts_reset_encoder(dev);
saa7134_i2c_call_clients(dev, VIDIOC_S_MPEGCOMP, NULL);
dev->empress_started = 1;
- return 0;
+ return 0;
}
/* ------------------------------------------------------------------ */
@@ -169,7 +169,7 @@ static int ts_do_ioctl(struct inode *inode, struct file *file,
struct v4l2_capability *cap = arg;
memset(cap,0,sizeof(*cap));
- strcpy(cap->driver, "saa7134");
+ strcpy(cap->driver, "saa7134");
strlcpy(cap->card, saa7134_boards[dev->board].name,
sizeof(cap->card));
sprintf(cap->bus_info,"PCI:%s",pci_name(dev->pci));
diff --git a/drivers/media/video/saa7134/saa7134-i2c.c b/drivers/media/video/saa7134/saa7134-i2c.c
index 711aa8e85fac..7575043f0874 100644
--- a/drivers/media/video/saa7134/saa7134-i2c.c
+++ b/drivers/media/video/saa7134/saa7134-i2c.c
@@ -239,7 +239,7 @@ static int saa7134_i2c_xfer(struct i2c_adapter *i2c_adap,
unsigned char data;
int addr,rc,i,byte;
- status = i2c_get_status(dev);
+ status = i2c_get_status(dev);
if (!i2c_is_idle(status))
if (!i2c_reset(dev))
return -EIO;
@@ -296,7 +296,7 @@ static int saa7134_i2c_xfer(struct i2c_adapter *i2c_adap,
rc = -EIO;
if (!i2c_is_busy_wait(dev))
goto err;
- status = i2c_get_status(dev);
+ status = i2c_get_status(dev);
if (i2c_is_error(status))
goto err;
/* ensure that the bus is idle for at least one bit slot */
@@ -335,6 +335,20 @@ static int attach_inform(struct i2c_client *client)
d1printk( "%s i2c attach [addr=0x%x,client=%s]\n",
client->driver->name, client->addr, client->name);
+ /* Am I an i2c remote control? */
+
+ switch (client->addr) {
+ case 0x7a:
+ case 0x47:
+ {
+ struct IR_i2c *ir = i2c_get_clientdata(client);
+ d1printk("%s i2c IR detected (%s).\n",
+ client->driver->name,ir->phys);
+ saa7134_set_i2c_ir(dev,ir);
+ break;
+ }
+ }
+
if (!client->driver->command)
return 0;
@@ -348,12 +362,12 @@ static int attach_inform(struct i2c_client *client)
client->driver->command(client, TUNER_SET_TYPE_ADDR, &tun_setup);
}
- }
+ }
if (tuner != UNSET) {
- tun_setup.type = tuner;
- tun_setup.addr = saa7134_boards[dev->board].tuner_addr;
+ tun_setup.type = tuner;
+ tun_setup.addr = saa7134_boards[dev->board].tuner_addr;
if ((tun_setup.addr == ADDR_UNSET)||(tun_setup.addr == client->addr)) {
@@ -361,11 +375,11 @@ static int attach_inform(struct i2c_client *client)
client->driver->command(client,TUNER_SET_TYPE_ADDR, &tun_setup);
}
- }
+ }
client->driver->command(client, TDA9887_SET_CONFIG, &conf);
- return 0;
+ return 0;
}
static struct i2c_algorithm saa7134_algo = {
diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c
index 1f456c4d76f2..329accda6d45 100644
--- a/drivers/media/video/saa7134/saa7134-input.c
+++ b/drivers/media/video/saa7134/saa7134-input.c
@@ -39,6 +39,8 @@ MODULE_PARM_DESC(ir_debug,"enable debug messages [IR]");
#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)
/* ---------------------------------------------------------------------- */
@@ -114,24 +116,24 @@ static IR_KEYTAB_TYPE cinergy_codes[IR_KEYTAB_SIZE] = {
/* Alfons Geser <a.geser@cox.net>
* updates from Job D. R. Borges <jobdrb@ig.com.br> */
static IR_KEYTAB_TYPE eztv_codes[IR_KEYTAB_SIZE] = {
- [ 18 ] = KEY_POWER,
- [ 1 ] = KEY_TV, // DVR
- [ 21 ] = KEY_DVD, // DVD
- [ 23 ] = KEY_AUDIO, // music
- // DVR mode / DVD mode / music mode
-
- [ 27 ] = KEY_MUTE, // mute
- [ 2 ] = KEY_LANGUAGE, // MTS/SAP / audio / autoseek
- [ 30 ] = KEY_SUBTITLE, // closed captioning / subtitle / seek
- [ 22 ] = KEY_ZOOM, // full screen
- [ 28 ] = KEY_VIDEO, // video source / eject / delall
- [ 29 ] = KEY_RESTART, // playback / angle / del
- [ 47 ] = KEY_SEARCH, // scan / menu / playlist
- [ 48 ] = KEY_CHANNEL, // CH surfing / bookmark / memo
-
- [ 49 ] = KEY_HELP, // help
- [ 50 ] = KEY_MODE, // num/memo
- [ 51 ] = KEY_ESC, // cancel
+ [ 18 ] = KEY_POWER,
+ [ 1 ] = KEY_TV, // DVR
+ [ 21 ] = KEY_DVD, // DVD
+ [ 23 ] = KEY_AUDIO, // music
+ // DVR mode / DVD mode / music mode
+
+ [ 27 ] = KEY_MUTE, // mute
+ [ 2 ] = KEY_LANGUAGE, // MTS/SAP / audio / autoseek
+ [ 30 ] = KEY_SUBTITLE, // closed captioning / subtitle / seek
+ [ 22 ] = KEY_ZOOM, // full screen
+ [ 28 ] = KEY_VIDEO, // video source / eject / delall
+ [ 29 ] = KEY_RESTART, // playback / angle / del
+ [ 47 ] = KEY_SEARCH, // scan / menu / playlist
+ [ 48 ] = KEY_CHANNEL, // CH surfing / bookmark / memo
+
+ [ 49 ] = KEY_HELP, // help
+ [ 50 ] = KEY_MODE, // num/memo
+ [ 51 ] = KEY_ESC, // cancel
[ 12 ] = KEY_UP, // up
[ 16 ] = KEY_DOWN, // down
@@ -148,24 +150,24 @@ static IR_KEYTAB_TYPE eztv_codes[IR_KEYTAB_SIZE] = {
[ 45 ] = KEY_PLAY, // play
[ 46 ] = KEY_SHUFFLE, // snapshot / shuffle
- [ 0 ] = KEY_KP0,
- [ 5 ] = KEY_KP1,
- [ 6 ] = KEY_KP2,
- [ 7 ] = KEY_KP3,
- [ 9 ] = KEY_KP4,
- [ 10 ] = KEY_KP5,
- [ 11 ] = KEY_KP6,
- [ 13 ] = KEY_KP7,
- [ 14 ] = KEY_KP8,
- [ 15 ] = KEY_KP9,
-
- [ 42 ] = KEY_VOLUMEUP,
- [ 17 ] = KEY_VOLUMEDOWN,
- [ 24 ] = KEY_CHANNELUP, // CH.tracking up
- [ 25 ] = KEY_CHANNELDOWN, // CH.tracking down
-
- [ 19 ] = KEY_KPENTER, // enter
- [ 33 ] = KEY_KPDOT, // . (decimal dot)
+ [ 0 ] = KEY_KP0,
+ [ 5 ] = KEY_KP1,
+ [ 6 ] = KEY_KP2,
+ [ 7 ] = KEY_KP3,
+ [ 9 ] = KEY_KP4,
+ [ 10 ] = KEY_KP5,
+ [ 11 ] = KEY_KP6,
+ [ 13 ] = KEY_KP7,
+ [ 14 ] = KEY_KP8,
+ [ 15 ] = KEY_KP9,
+
+ [ 42 ] = KEY_VOLUMEUP,
+ [ 17 ] = KEY_VOLUMEDOWN,
+ [ 24 ] = KEY_CHANNELUP, // CH.tracking up
+ [ 25 ] = KEY_CHANNELDOWN, // CH.tracking down
+
+ [ 19 ] = KEY_KPENTER, // enter
+ [ 33 ] = KEY_KPDOT, // . (decimal dot)
};
static IR_KEYTAB_TYPE avacssmart_codes[IR_KEYTAB_SIZE] = {
@@ -401,7 +403,183 @@ static IR_KEYTAB_TYPE manli_codes[IR_KEYTAB_SIZE] = {
// 0x1d unused ?
};
-/* ---------------------------------------------------------------------- */
+
+
+/* Mike Baikov <mike@baikov.com> */
+static IR_KEYTAB_TYPE gotview7135_codes[IR_KEYTAB_SIZE] = {
+
+ [ 33 ] = KEY_POWER,
+ [ 105] = KEY_TV,
+ [ 51 ] = KEY_KP0,
+ [ 81 ] = KEY_KP1,
+ [ 49 ] = KEY_KP2,
+ [ 113] = KEY_KP3,
+ [ 59 ] = KEY_KP4,
+ [ 88 ] = KEY_KP5,
+ [ 65 ] = KEY_KP6,
+ [ 72 ] = KEY_KP7,
+ [ 48 ] = KEY_KP8,
+ [ 83 ] = KEY_KP9,
+ [ 115] = KEY_AGAIN, /* LOOP */
+ [ 10 ] = KEY_AUDIO,
+ [ 97 ] = KEY_PRINT, /* PREVIEW */
+ [ 122] = KEY_VIDEO,
+ [ 32 ] = KEY_CHANNELUP,
+ [ 64 ] = KEY_CHANNELDOWN,
+ [ 24 ] = KEY_VOLUMEDOWN,
+ [ 80 ] = KEY_VOLUMEUP,
+ [ 16 ] = KEY_MUTE,
+ [ 74 ] = KEY_SEARCH,
+ [ 123] = KEY_SHUFFLE, /* SNAPSHOT */
+ [ 34 ] = KEY_RECORD,
+ [ 98 ] = KEY_STOP,
+ [ 120] = KEY_PLAY,
+ [ 57 ] = KEY_REWIND,
+ [ 89 ] = KEY_PAUSE,
+ [ 25 ] = KEY_FORWARD,
+ [ 9 ] = KEY_ZOOM,
+
+ [ 82 ] = KEY_F21, /* LIVE TIMESHIFT */
+ [ 26 ] = KEY_F22, /* MIN TIMESHIFT */
+ [ 58 ] = KEY_F23, /* TIMESHIFT */
+ [ 112] = KEY_F24, /* NORMAL TIMESHIFT */
+};
+
+static IR_KEYTAB_TYPE ir_codes_purpletv[IR_KEYTAB_SIZE] = {
+ [ 0x3 ] = KEY_POWER,
+ [ 0x6f ] = KEY_MUTE,
+ [ 0x10 ] = KEY_BACKSPACE, /* Recall */
+
+ [ 0x11 ] = KEY_KP0,
+ [ 0x4 ] = KEY_KP1,
+ [ 0x5 ] = KEY_KP2,
+ [ 0x6 ] = KEY_KP3,
+ [ 0x8 ] = KEY_KP4,
+ [ 0x9 ] = KEY_KP5,
+ [ 0xa ] = KEY_KP6,
+ [ 0xc ] = KEY_KP7,
+ [ 0xd ] = KEY_KP8,
+ [ 0xe ] = KEY_KP9,
+ [ 0x12 ] = KEY_KPDOT, /* 100+ */
+
+ [ 0x7 ] = KEY_VOLUMEUP,
+ [ 0xb ] = KEY_VOLUMEDOWN,
+ [ 0x1a ] = KEY_KPPLUS,
+ [ 0x18 ] = KEY_KPMINUS,
+ [ 0x15 ] = KEY_UP,
+ [ 0x1d ] = KEY_DOWN,
+ [ 0xf ] = KEY_CHANNELUP,
+ [ 0x13 ] = KEY_CHANNELDOWN,
+ [ 0x48 ] = KEY_ZOOM,
+
+ [ 0x1b ] = KEY_VIDEO, /* Video source */
+ [ 0x49 ] = KEY_LANGUAGE, /* MTS Select */
+ [ 0x19 ] = KEY_SEARCH, /* Auto Scan */
+
+ [ 0x4b ] = KEY_RECORD,
+ [ 0x46 ] = KEY_PLAY,
+ [ 0x45 ] = KEY_PAUSE, /* Pause */
+ [ 0x44 ] = KEY_STOP,
+ [ 0x40 ] = KEY_FORWARD, /* Forward ? */
+ [ 0x42 ] = KEY_REWIND, /* Backward ? */
+
+};
+
+static IR_KEYTAB_TYPE ir_codes_pinnacle[IR_KEYTAB_SIZE] = {
+ [ 0x59 ] = KEY_MUTE,
+ [ 0x4a ] = KEY_POWER,
+
+ [ 0x18 ] = KEY_TEXT,
+ [ 0x26 ] = KEY_TV,
+ [ 0x3d ] = KEY_PRINT,
+
+ [ 0x48 ] = KEY_RED,
+ [ 0x04 ] = KEY_GREEN,
+ [ 0x11 ] = KEY_YELLOW,
+ [ 0x00 ] = KEY_BLUE,
+
+ [ 0x2d ] = KEY_VOLUMEUP,
+ [ 0x1e ] = KEY_VOLUMEDOWN,
+
+ [ 0x49 ] = KEY_MENU,
+
+ [ 0x16 ] = KEY_CHANNELUP,
+ [ 0x17 ] = KEY_CHANNELDOWN,
+
+ [ 0x20 ] = KEY_UP,
+ [ 0x21 ] = KEY_DOWN,
+ [ 0x22 ] = KEY_LEFT,
+ [ 0x23 ] = KEY_RIGHT,
+ [ 0x0d ] = KEY_SELECT,
+
+
+
+ [ 0x08 ] = KEY_BACK,
+ [ 0x07 ] = KEY_REFRESH,
+
+ [ 0x2f ] = KEY_ZOOM,
+ [ 0x29 ] = KEY_RECORD,
+
+ [ 0x4b ] = KEY_PAUSE,
+ [ 0x4d ] = KEY_REWIND,
+ [ 0x2e ] = KEY_PLAY,
+ [ 0x4e ] = KEY_FORWARD,
+ [ 0x53 ] = KEY_PREVIOUS,
+ [ 0x4c ] = KEY_STOP,
+ [ 0x54 ] = KEY_NEXT,
+
+ [ 0x69 ] = KEY_KP0,
+ [ 0x6a ] = KEY_KP1,
+ [ 0x6b ] = KEY_KP2,
+ [ 0x6c ] = KEY_KP3,
+ [ 0x6d ] = KEY_KP4,
+ [ 0x6e ] = KEY_KP5,
+ [ 0x6f ] = KEY_KP6,
+ [ 0x70 ] = KEY_KP7,
+ [ 0x71 ] = KEY_KP8,
+ [ 0x72 ] = KEY_KP9,
+
+ [ 0x74 ] = KEY_CHANNEL,
+ [ 0x0a ] = KEY_BACKSPACE,
+};
+
+/* Mapping for the 28 key remote control as seen at
+ http://www.sednacomputer.com/photo/cardbus-tv.jpg
+ Pavel Mihaylov <bin@bash.info> */
+static IR_KEYTAB_TYPE pctv_sedna_codes[IR_KEYTAB_SIZE] = {
+ [ 0 ] = KEY_KP0,
+ [ 1 ] = KEY_KP1,
+ [ 2 ] = KEY_KP2,
+ [ 3 ] = KEY_KP3,
+ [ 4 ] = KEY_KP4,
+ [ 5 ] = KEY_KP5,
+ [ 6 ] = KEY_KP6,
+ [ 7 ] = KEY_KP7,
+ [ 8 ] = KEY_KP8,
+ [ 9 ] = KEY_KP9,
+
+ [ 0x0a ] = KEY_AGAIN, /* Recall */
+ [ 0x0b ] = KEY_CHANNELUP,
+ [ 0x0c ] = KEY_VOLUMEUP,
+ [ 0x0d ] = KEY_MODE, /* Stereo */
+ [ 0x0e ] = KEY_STOP,
+ [ 0x0f ] = KEY_PREVIOUSSONG,
+ [ 0x10 ] = KEY_ZOOM,
+ [ 0x11 ] = KEY_TUNER, /* Source */
+ [ 0x12 ] = KEY_POWER,
+ [ 0x13 ] = KEY_MUTE,
+ [ 0x15 ] = KEY_CHANNELDOWN,
+ [ 0x18 ] = KEY_VOLUMEDOWN,
+ [ 0x19 ] = KEY_SHUFFLE, /* Snapshot */
+ [ 0x1a ] = KEY_NEXTSONG,
+ [ 0x1b ] = KEY_TEXT, /* Time Shift */
+ [ 0x1c ] = KEY_RADIO, /* FM Radio */
+ [ 0x1d ] = KEY_RECORD,
+ [ 0x1e ] = KEY_PAUSE,
+};
+
+
+/* -------------------- GPIO generic keycode builder -------------------- */
static int build_key(struct saa7134_dev *dev)
{
@@ -413,32 +591,106 @@ static int build_key(struct saa7134_dev *dev)
saa_setb(SAA7134_GPIO_GPMODE3,SAA7134_GPIO_GPRESCAN);
gpio = saa_readl(SAA7134_GPIO_GPSTATUS0 >> 2);
- if (ir->polling) {
- if (ir->last_gpio == gpio)
- return 0;
- ir->last_gpio = gpio;
- }
+ if (ir->polling) {
+ if (ir->last_gpio == gpio)
+ return 0;
+ ir->last_gpio = gpio;
+ }
- data = ir_extract_bits(gpio, ir->mask_keycode);
+ data = ir_extract_bits(gpio, ir->mask_keycode);
dprintk("build_key gpio=0x%x mask=0x%x data=%d\n",
gpio, ir->mask_keycode, data);
if ((ir->mask_keydown && (0 != (gpio & ir->mask_keydown))) ||
(ir->mask_keyup && (0 == (gpio & ir->mask_keyup)))) {
- ir_input_keydown(&ir->dev,&ir->ir,data,data);
+ ir_input_keydown(ir->dev, &ir->ir, data, data);
} else {
- ir_input_nokey(&ir->dev,&ir->ir);
+ ir_input_nokey(ir->dev, &ir->ir);
}
return 0;
}
-/* ---------------------------------------------------------------------- */
+/* --------------------- Chip specific I2C key builders ----------------- */
+
+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)) {
+ i2cdprintk("read error\n");
+ return -EIO;
+ }
+
+ /* no button press */
+ if (b==0)
+ return 0;
+
+ /* repeating */
+ if (b & 0x80)
+ return 1;
+
+ *ir_key = b;
+ *ir_raw = b;
+ return 1;
+}
+
+/* The new pinnacle PCTV remote (with the colored buttons)
+ *
+ * Ricardo Cerqueira <v4l@cerqueira.org>
+ */
+
+static int get_key_pinnacle(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
+{
+ unsigned char b[4];
+ unsigned int start = 0,parity = 0,code = 0;
+
+ /* poll IR chip */
+ if (4 != i2c_master_recv(&ir->c,b,4)) {
+ i2cdprintk("read error\n");
+ return -EIO;
+ }
+
+ for (start = 0; start<4; start++) {
+ if (b[start] == 0x80) {
+ code=b[(start+3)%4];
+ parity=b[(start+2)%4];
+ }
+ }
+
+ /* Empty Request */
+ if (parity==0)
+ return 0;
+
+ /* Repeating... */
+ if (ir->old == parity)
+ return 0;
+
+
+ ir->old = parity;
+
+ /* Reduce code value to fit inside IR_KEYTAB_SIZE
+ *
+ * this is the only value that results in 42 unique
+ * codes < 128
+ */
+
+ code %= 0x88;
+
+ *ir_raw = code;
+ *ir_key = code;
+
+ i2cdprintk("Pinnacle PCTV key %02x\n", code);
+
+ return 1;
+}
+
void saa7134_input_irq(struct saa7134_dev *dev)
{
- struct saa7134_ir *ir = dev->remote;
+ struct saa7134_ir *ir = dev->remote;
- if (!ir->polling)
+ if (!ir->polling)
build_key(dev);
}
@@ -456,6 +708,7 @@ static void saa7134_input_timer(unsigned long data)
int saa7134_input_init1(struct saa7134_dev *dev)
{
struct saa7134_ir *ir;
+ struct input_dev *input_dev;
IR_KEYTAB_TYPE *ir_codes = NULL;
u32 mask_keycode = 0;
u32 mask_keydown = 0;
@@ -463,7 +716,7 @@ int saa7134_input_init1(struct saa7134_dev *dev)
int polling = 0;
int ir_type = IR_TYPE_OTHER;
- if (!dev->has_remote)
+ if (dev->has_remote != SAA7134_REMOTE_GPIO)
return -ENODEV;
if (disable_ir)
return -ENODEV;
@@ -472,7 +725,8 @@ int saa7134_input_init1(struct saa7134_dev *dev)
switch (dev->board) {
case SAA7134_BOARD_FLYVIDEO2000:
case SAA7134_BOARD_FLYVIDEO3000:
- case SAA7134_BOARD_FLYTVPLATINUM_FM:
+ case SAA7134_BOARD_FLYTVPLATINUM_FM:
+ case SAA7134_BOARD_FLYTVPLATINUM_MINI2:
ir_codes = flyvideo_codes;
mask_keycode = 0xEC00000;
mask_keydown = 0x0040000;
@@ -513,14 +767,33 @@ int saa7134_input_init1(struct saa7134_dev *dev)
saa_setb(SAA7134_GPIO_GPMODE0, 0x4);
saa_setb(SAA7134_GPIO_GPSTATUS0, 0x4);
break;
+ case SAA7134_BOARD_KWORLD_TERMINATOR:
+ ir_codes = avacssmart_codes;
+ mask_keycode = 0x00001f;
+ mask_keyup = 0x000060;
+ polling = 50; // ms
+ break;
case SAA7134_BOARD_MANLI_MTV001:
case SAA7134_BOARD_MANLI_MTV002:
+ case SAA7134_BOARD_BEHOLD_409FM:
ir_codes = manli_codes;
mask_keycode = 0x001f00;
mask_keyup = 0x004000;
- mask_keydown = 0x002000;
polling = 50; // ms
break;
+ case SAA7134_BOARD_SEDNA_PC_TV_CARDBUS:
+ ir_codes = pctv_sedna_codes;
+ mask_keycode = 0x001f00;
+ mask_keyup = 0x004000;
+ polling = 50; // ms
+ break;
+ case SAA7134_BOARD_GOTVIEW_7135:
+ ir_codes = gotview7135_codes;
+ mask_keycode = 0x0003EC;
+ mask_keyup = 0x008000;
+ mask_keydown = 0x000010;
+ polling = 50; // ms
+ break;
case SAA7134_BOARD_VIDEOMATE_TV_PVR:
case SAA7134_BOARD_VIDEOMATE_TV_GOLD_PLUSII:
ir_codes = videomate_tv_pvr_codes;
@@ -528,6 +801,12 @@ int saa7134_input_init1(struct saa7134_dev *dev)
mask_keyup = 0x400000;
polling = 50; // ms
break;
+ case SAA7134_BOARD_VIDEOMATE_DVBT_300:
+ case SAA7134_BOARD_VIDEOMATE_DVBT_200:
+ ir_codes = videomate_tv_pvr_codes;
+ mask_keycode = 0x003F00;
+ mask_keyup = 0x040000;
+ break;
}
if (NULL == ir_codes) {
printk("%s: Oops: IR config error [card=%d]\n",
@@ -535,16 +814,19 @@ int saa7134_input_init1(struct saa7134_dev *dev)
return -ENODEV;
}
- ir = kmalloc(sizeof(*ir),GFP_KERNEL);
- if (NULL == ir)
+ ir = kzalloc(sizeof(*ir), GFP_KERNEL);
+ input_dev = input_allocate_device();
+ if (!ir || !input_dev) {
+ kfree(ir);
+ input_free_device(input_dev);
return -ENOMEM;
- memset(ir,0,sizeof(*ir));
+ }
/* init hardware-specific stuff */
ir->mask_keycode = mask_keycode;
ir->mask_keydown = mask_keydown;
ir->mask_keyup = mask_keyup;
- ir->polling = polling;
+ ir->polling = polling;
/* init input device */
snprintf(ir->name, sizeof(ir->name), "saa7134 IR (%s)",
@@ -552,19 +834,19 @@ int saa7134_input_init1(struct saa7134_dev *dev)
snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0",
pci_name(dev->pci));
- ir_input_init(&ir->dev, &ir->ir, ir_type, ir_codes);
- ir->dev.name = ir->name;
- ir->dev.phys = ir->phys;
- ir->dev.id.bustype = BUS_PCI;
- ir->dev.id.version = 1;
+ ir_input_init(input_dev, &ir->ir, ir_type, ir_codes);
+ input_dev->name = ir->name;
+ input_dev->phys = ir->phys;
+ input_dev->id.bustype = BUS_PCI;
+ input_dev->id.version = 1;
if (dev->pci->subsystem_vendor) {
- ir->dev.id.vendor = dev->pci->subsystem_vendor;
- ir->dev.id.product = dev->pci->subsystem_device;
+ input_dev->id.vendor = dev->pci->subsystem_vendor;
+ input_dev->id.product = dev->pci->subsystem_device;
} else {
- ir->dev.id.vendor = dev->pci->vendor;
- ir->dev.id.product = dev->pci->device;
+ input_dev->id.vendor = dev->pci->vendor;
+ input_dev->id.product = dev->pci->device;
}
- ir->dev.dev = &dev->pci->dev;
+ input_dev->cdev.dev = &dev->pci->dev;
/* all done */
dev->remote = ir;
@@ -576,8 +858,7 @@ int saa7134_input_init1(struct saa7134_dev *dev)
add_timer(&ir->timer);
}
- input_register_device(&dev->remote->dev);
- printk("%s: registered input device for IR\n",dev->name);
+ input_register_device(ir->dev);
return 0;
}
@@ -586,13 +867,38 @@ void saa7134_input_fini(struct saa7134_dev *dev)
if (NULL == dev->remote)
return;
- input_unregister_device(&dev->remote->dev);
if (dev->remote->polling)
del_timer_sync(&dev->remote->timer);
+ input_unregister_device(dev->remote->dev);
kfree(dev->remote);
dev->remote = NULL;
}
+void saa7134_set_i2c_ir(struct saa7134_dev *dev, struct IR_i2c *ir)
+{
+ if (disable_ir) {
+ dprintk("Found supported i2c remote, but IR has been disabled\n");
+ ir->get_key=NULL;
+ return;
+ }
+
+ switch (dev->board) {
+ case SAA7134_BOARD_PINNACLE_PCTV_110i:
+ snprintf(ir->c.name, sizeof(ir->c.name), "Pinnacle PCTV");
+ ir->get_key = get_key_pinnacle;
+ ir->ir_codes = ir_codes_pinnacle;
+ 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;
+ break;
+ default:
+ dprintk("Shouldn't get here: Unknown board %x for I2C IR?\n",dev->board);
+ break;
+ }
+
+}
/* ----------------------------------------------------------------------
* Local variables:
* c-basic-offset: 8
diff --git a/drivers/media/video/saa7134/saa7134-oss.c b/drivers/media/video/saa7134/saa7134-oss.c
index c20630c82f1c..fd53dfcc1644 100644
--- a/drivers/media/video/saa7134/saa7134-oss.c
+++ b/drivers/media/video/saa7134/saa7134-oss.c
@@ -44,6 +44,7 @@ MODULE_PARM_DESC(oss_rate,"sample rate (valid are: 32000,48000)");
#define dprintk(fmt, arg...) if (oss_debug) \
printk(KERN_DEBUG "%s/oss: " fmt, dev->name , ## arg)
+
/* ------------------------------------------------------------------ */
static int dsp_buffer_conf(struct saa7134_dev *dev, int blksize, int blocks)
@@ -58,12 +59,12 @@ static int dsp_buffer_conf(struct saa7134_dev *dev, int blksize, int blocks)
if ((blksize * blocks) > 1024*1024)
blocks = 1024*1024 / blksize;
- dev->oss.blocks = blocks;
- dev->oss.blksize = blksize;
- dev->oss.bufsize = blksize * blocks;
+ dev->dmasound.blocks = blocks;
+ dev->dmasound.blksize = blksize;
+ dev->dmasound.bufsize = blksize * blocks;
dprintk("buffer config: %d blocks / %d bytes, %d kB total\n",
- blocks,blksize,blksize * blocks / 1024);
+ blocks,blksize,blksize * blocks / 1024);
return 0;
}
@@ -71,11 +72,11 @@ static int dsp_buffer_init(struct saa7134_dev *dev)
{
int err;
- if (!dev->oss.bufsize)
+ if (!dev->dmasound.bufsize)
BUG();
- videobuf_dma_init(&dev->oss.dma);
- err = videobuf_dma_init_kernel(&dev->oss.dma, PCI_DMA_FROMDEVICE,
- (dev->oss.bufsize + PAGE_SIZE) >> PAGE_SHIFT);
+ videobuf_dma_init(&dev->dmasound.dma);
+ err = videobuf_dma_init_kernel(&dev->dmasound.dma, PCI_DMA_FROMDEVICE,
+ (dev->dmasound.bufsize + PAGE_SIZE) >> PAGE_SHIFT);
if (0 != err)
return err;
return 0;
@@ -83,26 +84,26 @@ static int dsp_buffer_init(struct saa7134_dev *dev)
static int dsp_buffer_free(struct saa7134_dev *dev)
{
- if (!dev->oss.blksize)
+ if (!dev->dmasound.blksize)
BUG();
- videobuf_dma_free(&dev->oss.dma);
- dev->oss.blocks = 0;
- dev->oss.blksize = 0;
- dev->oss.bufsize = 0;
+ videobuf_dma_free(&dev->dmasound.dma);
+ dev->dmasound.blocks = 0;
+ dev->dmasound.blksize = 0;
+ dev->dmasound.bufsize = 0;
return 0;
}
static void dsp_dma_start(struct saa7134_dev *dev)
{
- dev->oss.dma_blk = 0;
- dev->oss.dma_running = 1;
+ dev->dmasound.dma_blk = 0;
+ dev->dmasound.dma_running = 1;
saa7134_set_dmabits(dev);
}
static void dsp_dma_stop(struct saa7134_dev *dev)
{
- dev->oss.dma_blk = -1;
- dev->oss.dma_running = 0;
+ dev->dmasound.dma_blk = -1;
+ dev->dmasound.dma_running = 0;
saa7134_set_dmabits(dev);
}
@@ -113,18 +114,18 @@ static int dsp_rec_start(struct saa7134_dev *dev)
unsigned long flags;
/* prepare buffer */
- if (0 != (err = videobuf_dma_pci_map(dev->pci,&dev->oss.dma)))
+ if (0 != (err = videobuf_dma_pci_map(dev->pci,&dev->dmasound.dma)))
return err;
- if (0 != (err = saa7134_pgtable_alloc(dev->pci,&dev->oss.pt)))
+ if (0 != (err = saa7134_pgtable_alloc(dev->pci,&dev->dmasound.pt)))
goto fail1;
- if (0 != (err = saa7134_pgtable_build(dev->pci,&dev->oss.pt,
- dev->oss.dma.sglist,
- dev->oss.dma.sglen,
+ if (0 != (err = saa7134_pgtable_build(dev->pci,&dev->dmasound.pt,
+ dev->dmasound.dma.sglist,
+ dev->dmasound.dma.sglen,
0)))
goto fail2;
/* sample format */
- switch (dev->oss.afmt) {
+ switch (dev->dmasound.afmt) {
case AFMT_U8:
case AFMT_S8: fmt = 0x00; break;
case AFMT_U16_LE:
@@ -136,14 +137,14 @@ static int dsp_rec_start(struct saa7134_dev *dev)
goto fail2;
}
- switch (dev->oss.afmt) {
+ switch (dev->dmasound.afmt) {
case AFMT_S8:
case AFMT_S16_LE:
case AFMT_S16_BE: sign = 1; break;
default: sign = 0; break;
}
- switch (dev->oss.afmt) {
+ switch (dev->dmasound.afmt) {
case AFMT_U16_BE:
case AFMT_S16_BE: bswap = 1; break;
default: bswap = 0; break;
@@ -151,58 +152,58 @@ static int dsp_rec_start(struct saa7134_dev *dev)
switch (dev->pci->device) {
case PCI_DEVICE_ID_PHILIPS_SAA7134:
- if (1 == dev->oss.channels)
+ if (1 == dev->dmasound.channels)
fmt |= (1 << 3);
- if (2 == dev->oss.channels)
+ if (2 == dev->dmasound.channels)
fmt |= (3 << 3);
if (sign)
fmt |= 0x04;
- fmt |= (TV == dev->oss.input) ? 0xc0 : 0x80;
+ fmt |= (TV == dev->dmasound.input) ? 0xc0 : 0x80;
- saa_writeb(SAA7134_NUM_SAMPLES0, ((dev->oss.blksize - 1) & 0x0000ff));
- saa_writeb(SAA7134_NUM_SAMPLES1, ((dev->oss.blksize - 1) & 0x00ff00) >> 8);
- saa_writeb(SAA7134_NUM_SAMPLES2, ((dev->oss.blksize - 1) & 0xff0000) >> 16);
+ saa_writeb(SAA7134_NUM_SAMPLES0, ((dev->dmasound.blksize - 1) & 0x0000ff));
+ saa_writeb(SAA7134_NUM_SAMPLES1, ((dev->dmasound.blksize - 1) & 0x00ff00) >> 8);
+ saa_writeb(SAA7134_NUM_SAMPLES2, ((dev->dmasound.blksize - 1) & 0xff0000) >> 16);
saa_writeb(SAA7134_AUDIO_FORMAT_CTRL, fmt);
break;
case PCI_DEVICE_ID_PHILIPS_SAA7133:
case PCI_DEVICE_ID_PHILIPS_SAA7135:
- if (1 == dev->oss.channels)
+ if (1 == dev->dmasound.channels)
fmt |= (1 << 4);
- if (2 == dev->oss.channels)
+ if (2 == dev->dmasound.channels)
fmt |= (2 << 4);
if (!sign)
fmt |= 0x04;
- saa_writel(0x588 >> 2, dev->oss.blksize -4);
- saa_writel(0x58c >> 2, 0x543210 | (fmt << 24));
+ saa_writel(SAA7133_NUM_SAMPLES, dev->dmasound.blksize -4);
+ saa_writel(SAA7133_AUDIO_CHANNEL, 0x543210 | (fmt << 24));
break;
}
dprintk("rec_start: afmt=%d ch=%d => fmt=0x%x swap=%c\n",
- dev->oss.afmt, dev->oss.channels, fmt,
+ dev->dmasound.afmt, dev->dmasound.channels, fmt,
bswap ? 'b' : '-');
/* dma: setup channel 6 (= AUDIO) */
control = SAA7134_RS_CONTROL_BURST_16 |
SAA7134_RS_CONTROL_ME |
- (dev->oss.pt.dma >> 12);
+ (dev->dmasound.pt.dma >> 12);
if (bswap)
control |= SAA7134_RS_CONTROL_BSWAP;
saa_writel(SAA7134_RS_BA1(6),0);
- saa_writel(SAA7134_RS_BA2(6),dev->oss.blksize);
+ saa_writel(SAA7134_RS_BA2(6),dev->dmasound.blksize);
saa_writel(SAA7134_RS_PITCH(6),0);
saa_writel(SAA7134_RS_CONTROL(6),control);
/* start dma */
- dev->oss.recording_on = 1;
+ dev->dmasound.recording_on = 1;
spin_lock_irqsave(&dev->slock,flags);
dsp_dma_start(dev);
spin_unlock_irqrestore(&dev->slock,flags);
return 0;
fail2:
- saa7134_pgtable_free(dev->pci,&dev->oss.pt);
+ saa7134_pgtable_free(dev->pci,&dev->dmasound.pt);
fail1:
- videobuf_dma_pci_unmap(dev->pci,&dev->oss.dma);
+ videobuf_dma_pci_unmap(dev->pci,&dev->dmasound.dma);
return err;
}
@@ -210,17 +211,17 @@ static int dsp_rec_stop(struct saa7134_dev *dev)
{
unsigned long flags;
- dprintk("rec_stop dma_blk=%d\n",dev->oss.dma_blk);
+ dprintk("rec_stop dma_blk=%d\n",dev->dmasound.dma_blk);
/* stop dma */
- dev->oss.recording_on = 0;
+ dev->dmasound.recording_on = 0;
spin_lock_irqsave(&dev->slock,flags);
dsp_dma_stop(dev);
spin_unlock_irqrestore(&dev->slock,flags);
/* unlock buffer */
- saa7134_pgtable_free(dev->pci,&dev->oss.pt);
- videobuf_dma_pci_unmap(dev->pci,&dev->oss.dma);
+ saa7134_pgtable_free(dev->pci,&dev->dmasound.pt);
+ videobuf_dma_pci_unmap(dev->pci,&dev->dmasound.dma);
return 0;
}
@@ -235,35 +236,35 @@ static int dsp_open(struct inode *inode, struct file *file)
list_for_each(list,&saa7134_devlist) {
h = list_entry(list, struct saa7134_dev, devlist);
- if (h->oss.minor_dsp == minor)
+ if (h->dmasound.minor_dsp == minor)
dev = h;
}
if (NULL == dev)
return -ENODEV;
- down(&dev->oss.lock);
+ down(&dev->dmasound.lock);
err = -EBUSY;
- if (dev->oss.users_dsp)
+ if (dev->dmasound.users_dsp)
goto fail1;
- dev->oss.users_dsp++;
+ dev->dmasound.users_dsp++;
file->private_data = dev;
- dev->oss.afmt = AFMT_U8;
- dev->oss.channels = 1;
- dev->oss.read_count = 0;
- dev->oss.read_offset = 0;
+ dev->dmasound.afmt = AFMT_U8;
+ dev->dmasound.channels = 1;
+ dev->dmasound.read_count = 0;
+ dev->dmasound.read_offset = 0;
dsp_buffer_conf(dev,PAGE_SIZE,64);
err = dsp_buffer_init(dev);
if (0 != err)
goto fail2;
- up(&dev->oss.lock);
+ up(&dev->dmasound.lock);
return 0;
fail2:
- dev->oss.users_dsp--;
+ dev->dmasound.users_dsp--;
fail1:
- up(&dev->oss.lock);
+ up(&dev->dmasound.lock);
return err;
}
@@ -271,13 +272,13 @@ static int dsp_release(struct inode *inode, struct file *file)
{
struct saa7134_dev *dev = file->private_data;
- down(&dev->oss.lock);
- if (dev->oss.recording_on)
+ down(&dev->dmasound.lock);
+ if (dev->dmasound.recording_on)
dsp_rec_stop(dev);
dsp_buffer_free(dev);
- dev->oss.users_dsp--;
+ dev->dmasound.users_dsp--;
file->private_data = NULL;
- up(&dev->oss.lock);
+ up(&dev->dmasound.lock);
return 0;
}
@@ -290,12 +291,12 @@ static ssize_t dsp_read(struct file *file, char __user *buffer,
unsigned long flags;
int err,ret = 0;
- add_wait_queue(&dev->oss.wq, &wait);
- down(&dev->oss.lock);
+ add_wait_queue(&dev->dmasound.wq, &wait);
+ down(&dev->dmasound.lock);
while (count > 0) {
/* wait for data if needed */
- if (0 == dev->oss.read_count) {
- if (!dev->oss.recording_on) {
+ if (0 == dev->dmasound.read_count) {
+ if (!dev->dmasound.recording_on) {
err = dsp_rec_start(dev);
if (err < 0) {
if (0 == ret)
@@ -303,8 +304,8 @@ static ssize_t dsp_read(struct file *file, char __user *buffer,
break;
}
}
- if (dev->oss.recording_on &&
- !dev->oss.dma_running) {
+ if (dev->dmasound.recording_on &&
+ !dev->dmasound.dma_running) {
/* recover from overruns */
spin_lock_irqsave(&dev->slock,flags);
dsp_dma_start(dev);
@@ -315,12 +316,12 @@ static ssize_t dsp_read(struct file *file, char __user *buffer,
ret = -EAGAIN;
break;
}
- up(&dev->oss.lock);
+ up(&dev->dmasound.lock);
set_current_state(TASK_INTERRUPTIBLE);
- if (0 == dev->oss.read_count)
+ if (0 == dev->dmasound.read_count)
schedule();
set_current_state(TASK_RUNNING);
- down(&dev->oss.lock);
+ down(&dev->dmasound.lock);
if (signal_pending(current)) {
if (0 == ret)
ret = -EINTR;
@@ -330,12 +331,12 @@ static ssize_t dsp_read(struct file *file, char __user *buffer,
/* copy data to userspace */
bytes = count;
- if (bytes > dev->oss.read_count)
- bytes = dev->oss.read_count;
- if (bytes > dev->oss.bufsize - dev->oss.read_offset)
- bytes = dev->oss.bufsize - dev->oss.read_offset;
+ if (bytes > dev->dmasound.read_count)
+ bytes = dev->dmasound.read_count;
+ if (bytes > dev->dmasound.bufsize - dev->dmasound.read_offset)
+ bytes = dev->dmasound.bufsize - dev->dmasound.read_offset;
if (copy_to_user(buffer + ret,
- dev->oss.dma.vmalloc + dev->oss.read_offset,
+ dev->dmasound.dma.vmalloc + dev->dmasound.read_offset,
bytes)) {
if (0 == ret)
ret = -EFAULT;
@@ -344,13 +345,13 @@ static ssize_t dsp_read(struct file *file, char __user *buffer,
ret += bytes;
count -= bytes;
- dev->oss.read_count -= bytes;
- dev->oss.read_offset += bytes;
- if (dev->oss.read_offset == dev->oss.bufsize)
- dev->oss.read_offset = 0;
+ dev->dmasound.read_count -= bytes;
+ dev->dmasound.read_offset += bytes;
+ if (dev->dmasound.read_offset == dev->dmasound.bufsize)
+ dev->dmasound.read_offset = 0;
}
- up(&dev->oss.lock);
- remove_wait_queue(&dev->oss.wq, &wait);
+ up(&dev->dmasound.lock);
+ remove_wait_queue(&dev->dmasound.wq, &wait);
return ret;
}
@@ -370,53 +371,53 @@ static int dsp_ioctl(struct inode *inode, struct file *file,
if (oss_debug > 1)
saa7134_print_ioctl(dev->name,cmd);
- switch (cmd) {
- case OSS_GETVERSION:
- return put_user(SOUND_VERSION, p);
- case SNDCTL_DSP_GETCAPS:
+ switch (cmd) {
+ case OSS_GETVERSION:
+ return put_user(SOUND_VERSION, p);
+ case SNDCTL_DSP_GETCAPS:
return 0;
- case SNDCTL_DSP_SPEED:
+ case SNDCTL_DSP_SPEED:
if (get_user(val, p))
return -EFAULT;
/* fall through */
- case SOUND_PCM_READ_RATE:
- return put_user(dev->oss.rate, p);
+ case SOUND_PCM_READ_RATE:
+ return put_user(dev->dmasound.rate, p);
- case SNDCTL_DSP_STEREO:
+ case SNDCTL_DSP_STEREO:
if (get_user(val, p))
return -EFAULT;
- down(&dev->oss.lock);
- dev->oss.channels = val ? 2 : 1;
- if (dev->oss.recording_on) {
+ down(&dev->dmasound.lock);
+ dev->dmasound.channels = val ? 2 : 1;
+ if (dev->dmasound.recording_on) {
dsp_rec_stop(dev);
dsp_rec_start(dev);
}
- up(&dev->oss.lock);
- return put_user(dev->oss.channels-1, p);
+ up(&dev->dmasound.lock);
+ return put_user(dev->dmasound.channels-1, p);
- case SNDCTL_DSP_CHANNELS:
+ case SNDCTL_DSP_CHANNELS:
if (get_user(val, p))
return -EFAULT;
if (val != 1 && val != 2)
return -EINVAL;
- down(&dev->oss.lock);
- dev->oss.channels = val;
- if (dev->oss.recording_on) {
+ down(&dev->dmasound.lock);
+ dev->dmasound.channels = val;
+ if (dev->dmasound.recording_on) {
dsp_rec_stop(dev);
dsp_rec_start(dev);
}
- up(&dev->oss.lock);
+ up(&dev->dmasound.lock);
/* fall through */
- case SOUND_PCM_READ_CHANNELS:
- return put_user(dev->oss.channels, p);
+ case SOUND_PCM_READ_CHANNELS:
+ return put_user(dev->dmasound.channels, p);
- case SNDCTL_DSP_GETFMTS: /* Returns a mask */
+ case SNDCTL_DSP_GETFMTS: /* Returns a mask */
return put_user(AFMT_U8 | AFMT_S8 |
AFMT_U16_LE | AFMT_U16_BE |
AFMT_S16_LE | AFMT_S16_BE, p);
- case SNDCTL_DSP_SETFMT: /* Selects ONE fmt */
+ case SNDCTL_DSP_SETFMT: /* Selects ONE fmt */
if (get_user(val, p))
return -EFAULT;
switch (val) {
@@ -429,20 +430,20 @@ static int dsp_ioctl(struct inode *inode, struct file *file,
case AFMT_U16_BE:
case AFMT_S16_LE:
case AFMT_S16_BE:
- down(&dev->oss.lock);
- dev->oss.afmt = val;
- if (dev->oss.recording_on) {
+ down(&dev->dmasound.lock);
+ dev->dmasound.afmt = val;
+ if (dev->dmasound.recording_on) {
dsp_rec_stop(dev);
dsp_rec_start(dev);
}
- up(&dev->oss.lock);
- return put_user(dev->oss.afmt, p);
+ up(&dev->dmasound.lock);
+ return put_user(dev->dmasound.afmt, p);
default:
return -EINVAL;
}
- case SOUND_PCM_READ_BITS:
- switch (dev->oss.afmt) {
+ case SOUND_PCM_READ_BITS:
+ switch (dev->dmasound.afmt) {
case AFMT_U8:
case AFMT_S8:
return put_user(8, p);
@@ -455,23 +456,23 @@ static int dsp_ioctl(struct inode *inode, struct file *file,
return -EINVAL;
}
- case SNDCTL_DSP_NONBLOCK:
- file->f_flags |= O_NONBLOCK;
- return 0;
+ case SNDCTL_DSP_NONBLOCK:
+ file->f_flags |= O_NONBLOCK;
+ return 0;
- case SNDCTL_DSP_RESET:
- down(&dev->oss.lock);
- if (dev->oss.recording_on)
+ case SNDCTL_DSP_RESET:
+ down(&dev->dmasound.lock);
+ if (dev->dmasound.recording_on)
dsp_rec_stop(dev);
- up(&dev->oss.lock);
+ up(&dev->dmasound.lock);
return 0;
- case SNDCTL_DSP_GETBLKSIZE:
- return put_user(dev->oss.blksize, p);
+ case SNDCTL_DSP_GETBLKSIZE:
+ return put_user(dev->dmasound.blksize, p);
- case SNDCTL_DSP_SETFRAGMENT:
+ case SNDCTL_DSP_SETFRAGMENT:
if (get_user(val, p))
return -EFAULT;
- if (dev->oss.recording_on)
+ if (dev->dmasound.recording_on)
return -EBUSY;
dsp_buffer_free(dev);
/* used to be arg >> 16 instead of val >> 16; fixed */
@@ -479,16 +480,16 @@ static int dsp_ioctl(struct inode *inode, struct file *file,
dsp_buffer_init(dev);
return 0;
- case SNDCTL_DSP_SYNC:
+ case SNDCTL_DSP_SYNC:
/* NOP */
return 0;
case SNDCTL_DSP_GETISPACE:
{
audio_buf_info info;
- info.fragsize = dev->oss.blksize;
- info.fragstotal = dev->oss.blocks;
- info.bytes = dev->oss.read_count;
+ info.fragsize = dev->dmasound.blksize;
+ info.fragstotal = dev->dmasound.blocks;
+ info.bytes = dev->dmasound.read_count;
info.fragments = info.bytes / info.fragsize;
if (copy_to_user(argp, &info, sizeof(info)))
return -EFAULT;
@@ -504,13 +505,13 @@ static unsigned int dsp_poll(struct file *file, struct poll_table_struct *wait)
struct saa7134_dev *dev = file->private_data;
unsigned int mask = 0;
- poll_wait(file, &dev->oss.wq, wait);
+ poll_wait(file, &dev->dmasound.wq, wait);
- if (0 == dev->oss.read_count) {
- down(&dev->oss.lock);
- if (!dev->oss.recording_on)
+ if (0 == dev->dmasound.read_count) {
+ down(&dev->dmasound.lock);
+ if (!dev->dmasound.recording_on)
dsp_rec_start(dev);
- up(&dev->oss.lock);
+ up(&dev->dmasound.lock);
} else
mask |= (POLLIN | POLLRDNORM);
return mask;
@@ -534,7 +535,7 @@ mixer_recsrc_7134(struct saa7134_dev *dev)
{
int analog_io,rate;
- switch (dev->oss.input) {
+ switch (dev->dmasound.input) {
case TV:
saa_andorb(SAA7134_AUDIO_FORMAT_CTRL, 0xc0, 0xc0);
saa_andorb(SAA7134_SIF_SAMPLE_FREQ, 0x03, 0x00);
@@ -542,8 +543,8 @@ mixer_recsrc_7134(struct saa7134_dev *dev)
case LINE1:
case LINE2:
case LINE2_LEFT:
- analog_io = (LINE1 == dev->oss.input) ? 0x00 : 0x08;
- rate = (32000 == dev->oss.rate) ? 0x01 : 0x03;
+ analog_io = (LINE1 == dev->dmasound.input) ? 0x00 : 0x08;
+ rate = (32000 == dev->dmasound.rate) ? 0x01 : 0x03;
saa_andorb(SAA7134_ANALOG_IO_SELECT, 0x08, analog_io);
saa_andorb(SAA7134_AUDIO_FORMAT_CTRL, 0xc0, 0x80);
saa_andorb(SAA7134_SIF_SAMPLE_FREQ, 0x03, rate);
@@ -559,10 +560,10 @@ mixer_recsrc_7133(struct saa7134_dev *dev)
xbarin = 0x03; // adc
anabar = 0;
- switch (dev->oss.input) {
+ switch (dev->dmasound.input) {
case TV:
xbarin = 0; // Demodulator
- anabar = 2; // DACs
+ anabar = 2; // DACs
break;
case LINE1:
anabar = 0; // aux1, aux1
@@ -585,9 +586,9 @@ mixer_recsrc(struct saa7134_dev *dev, enum saa7134_audio_in src)
{
static const char *iname[] = { "Oops", "TV", "LINE1", "LINE2" };
- dev->oss.count++;
- dev->oss.input = src;
- dprintk("mixer input = %s\n",iname[dev->oss.input]);
+ dev->dmasound.count++;
+ dev->dmasound.input = src;
+ dprintk("mixer input = %s\n",iname[dev->dmasound.input]);
switch (dev->pci->device) {
case PCI_DEVICE_ID_PHILIPS_SAA7134:
@@ -639,7 +640,7 @@ static int mixer_open(struct inode *inode, struct file *file)
list_for_each(list,&saa7134_devlist) {
h = list_entry(list, struct saa7134_dev, devlist);
- if (h->oss.minor_mixer == minor)
+ if (h->dmasound.minor_mixer == minor)
dev = h;
}
if (NULL == dev)
@@ -666,28 +667,28 @@ static int mixer_ioctl(struct inode *inode, struct file *file,
if (oss_debug > 1)
saa7134_print_ioctl(dev->name,cmd);
- switch (cmd) {
- case OSS_GETVERSION:
- return put_user(SOUND_VERSION, p);
+ switch (cmd) {
+ case OSS_GETVERSION:
+ return put_user(SOUND_VERSION, p);
case SOUND_MIXER_INFO:
{
mixer_info info;
memset(&info,0,sizeof(info));
- strlcpy(info.id, "TV audio", sizeof(info.id));
- strlcpy(info.name, dev->name, sizeof(info.name));
- info.modify_counter = dev->oss.count;
- if (copy_to_user(argp, &info, sizeof(info)))
- return -EFAULT;
+ strlcpy(info.id, "TV audio", sizeof(info.id));
+ strlcpy(info.name, dev->name, sizeof(info.name));
+ info.modify_counter = dev->dmasound.count;
+ if (copy_to_user(argp, &info, sizeof(info)))
+ return -EFAULT;
return 0;
}
case SOUND_OLD_MIXER_INFO:
{
_old_mixer_info info;
memset(&info,0,sizeof(info));
- strlcpy(info.id, "TV audio", sizeof(info.id));
- strlcpy(info.name, dev->name, sizeof(info.name));
- if (copy_to_user(argp, &info, sizeof(info)))
- return -EFAULT;
+ strlcpy(info.id, "TV audio", sizeof(info.id));
+ strlcpy(info.name, dev->name, sizeof(info.name));
+ if (copy_to_user(argp, &info, sizeof(info)))
+ return -EFAULT;
return 0;
}
case MIXER_READ(SOUND_MIXER_CAPS):
@@ -697,26 +698,26 @@ static int mixer_ioctl(struct inode *inode, struct file *file,
case MIXER_READ(SOUND_MIXER_RECMASK):
case MIXER_READ(SOUND_MIXER_DEVMASK):
val = SOUND_MASK_LINE1 | SOUND_MASK_LINE2;
- if (32000 == dev->oss.rate)
+ if (32000 == dev->dmasound.rate)
val |= SOUND_MASK_VIDEO;
return put_user(val, p);
case MIXER_WRITE(SOUND_MIXER_RECSRC):
if (get_user(val, p))
return -EFAULT;
- input = dev->oss.input;
- if (32000 == dev->oss.rate &&
- val & SOUND_MASK_VIDEO && dev->oss.input != TV)
+ input = dev->dmasound.input;
+ if (32000 == dev->dmasound.rate &&
+ val & SOUND_MASK_VIDEO && dev->dmasound.input != TV)
input = TV;
- if (val & SOUND_MASK_LINE1 && dev->oss.input != LINE1)
+ if (val & SOUND_MASK_LINE1 && dev->dmasound.input != LINE1)
input = LINE1;
- if (val & SOUND_MASK_LINE2 && dev->oss.input != LINE2)
+ if (val & SOUND_MASK_LINE2 && dev->dmasound.input != LINE2)
input = LINE2;
- if (input != dev->oss.input)
+ if (input != dev->dmasound.input)
mixer_recsrc(dev,input);
/* fall throuth */
case MIXER_READ(SOUND_MIXER_RECSRC):
- switch (dev->oss.input) {
+ switch (dev->dmasound.input) {
case TV: ret = SOUND_MASK_VIDEO; break;
case LINE1: ret = SOUND_MASK_LINE1; break;
case LINE2: ret = SOUND_MASK_LINE2; break;
@@ -726,7 +727,7 @@ static int mixer_ioctl(struct inode *inode, struct file *file,
case MIXER_WRITE(SOUND_MIXER_VIDEO):
case MIXER_READ(SOUND_MIXER_VIDEO):
- if (32000 != dev->oss.rate)
+ if (32000 != dev->dmasound.rate)
return -EINVAL;
return put_user(100 | 100 << 8, p);
@@ -735,22 +736,22 @@ static int mixer_ioctl(struct inode *inode, struct file *file,
return -EFAULT;
val &= 0xff;
val = (val <= 50) ? 50 : 100;
- dev->oss.line1 = val;
- mixer_level(dev,LINE1,dev->oss.line1);
+ dev->dmasound.line1 = val;
+ mixer_level(dev,LINE1,dev->dmasound.line1);
/* fall throuth */
case MIXER_READ(SOUND_MIXER_LINE1):
- return put_user(dev->oss.line1 | dev->oss.line1 << 8, p);
+ return put_user(dev->dmasound.line1 | dev->dmasound.line1 << 8, p);
case MIXER_WRITE(SOUND_MIXER_LINE2):
if (get_user(val, p))
return -EFAULT;
val &= 0xff;
val = (val <= 50) ? 50 : 100;
- dev->oss.line2 = val;
- mixer_level(dev,LINE2,dev->oss.line2);
+ dev->dmasound.line2 = val;
+ mixer_level(dev,LINE2,dev->dmasound.line2);
/* fall throuth */
case MIXER_READ(SOUND_MIXER_LINE2):
- return put_user(dev->oss.line2 | dev->oss.line2 << 8, p);
+ return put_user(dev->dmasound.line2 | dev->dmasound.line2 << 8, p);
default:
return -EINVAL;
@@ -770,8 +771,8 @@ struct file_operations saa7134_mixer_fops = {
int saa7134_oss_init1(struct saa7134_dev *dev)
{
/* general */
- init_MUTEX(&dev->oss.lock);
- init_waitqueue_head(&dev->oss.wq);
+ init_MUTEX(&dev->dmasound.lock);
+ init_waitqueue_head(&dev->dmasound.wq);
switch (dev->pci->device) {
case PCI_DEVICE_ID_PHILIPS_SAA7133:
@@ -783,17 +784,17 @@ int saa7134_oss_init1(struct saa7134_dev *dev)
}
/* dsp */
- dev->oss.rate = 32000;
+ dev->dmasound.rate = 32000;
if (oss_rate)
- dev->oss.rate = oss_rate;
- dev->oss.rate = (dev->oss.rate > 40000) ? 48000 : 32000;
+ dev->dmasound.rate = oss_rate;
+ dev->dmasound.rate = (dev->dmasound.rate > 40000) ? 48000 : 32000;
/* mixer */
- dev->oss.line1 = 50;
- dev->oss.line2 = 50;
- mixer_level(dev,LINE1,dev->oss.line1);
- mixer_level(dev,LINE2,dev->oss.line2);
- mixer_recsrc(dev, (dev->oss.rate == 32000) ? TV : LINE2);
+ dev->dmasound.line1 = 50;
+ dev->dmasound.line2 = 50;
+ mixer_level(dev,LINE1,dev->dmasound.line1);
+ mixer_level(dev,LINE2,dev->dmasound.line2);
+ mixer_recsrc(dev, (dev->dmasound.rate == 32000) ? TV : LINE2);
return 0;
}
@@ -809,7 +810,7 @@ void saa7134_irq_oss_done(struct saa7134_dev *dev, unsigned long status)
int next_blk, reg = 0;
spin_lock(&dev->slock);
- if (UNSET == dev->oss.dma_blk) {
+ if (UNSET == dev->dmasound.dma_blk) {
dprintk("irq: recording stopped\n");
goto done;
}
@@ -817,11 +818,11 @@ void saa7134_irq_oss_done(struct saa7134_dev *dev, unsigned long status)
dprintk("irq: lost %ld\n", (status >> 24) & 0x0f);
if (0 == (status & 0x10000000)) {
/* odd */
- if (0 == (dev->oss.dma_blk & 0x01))
+ if (0 == (dev->dmasound.dma_blk & 0x01))
reg = SAA7134_RS_BA1(6);
} else {
/* even */
- if (1 == (dev->oss.dma_blk & 0x01))
+ if (1 == (dev->dmasound.dma_blk & 0x01))
reg = SAA7134_RS_BA2(6);
}
if (0 == reg) {
@@ -829,25 +830,25 @@ void saa7134_irq_oss_done(struct saa7134_dev *dev, unsigned long status)
(status & 0x10000000) ? "even" : "odd");
goto done;
}
- if (dev->oss.read_count >= dev->oss.blksize * (dev->oss.blocks-2)) {
- dprintk("irq: overrun [full=%d/%d]\n",dev->oss.read_count,
- dev->oss.bufsize);
+ if (dev->dmasound.read_count >= dev->dmasound.blksize * (dev->dmasound.blocks-2)) {
+ dprintk("irq: overrun [full=%d/%d]\n",dev->dmasound.read_count,
+ dev->dmasound.bufsize);
dsp_dma_stop(dev);
goto done;
}
/* next block addr */
- next_blk = (dev->oss.dma_blk + 2) % dev->oss.blocks;
- saa_writel(reg,next_blk * dev->oss.blksize);
+ next_blk = (dev->dmasound.dma_blk + 2) % dev->dmasound.blocks;
+ saa_writel(reg,next_blk * dev->dmasound.blksize);
if (oss_debug > 2)
dprintk("irq: ok, %s, next_blk=%d, addr=%x\n",
(status & 0x10000000) ? "even" : "odd ", next_blk,
- next_blk * dev->oss.blksize);
+ next_blk * dev->dmasound.blksize);
/* update status & wake waiting readers */
- dev->oss.dma_blk = (dev->oss.dma_blk + 1) % dev->oss.blocks;
- dev->oss.read_count += dev->oss.blksize;
- wake_up(&dev->oss.wq);
+ dev->dmasound.dma_blk = (dev->dmasound.dma_blk + 1) % dev->dmasound.blocks;
+ dev->dmasound.read_count += dev->dmasound.blksize;
+ wake_up(&dev->dmasound.wq);
done:
spin_unlock(&dev->slock);
diff --git a/drivers/media/video/saa7134/saa7134-reg.h b/drivers/media/video/saa7134/saa7134-reg.h
index ae0c7a165390..ac6431ba4fc3 100644
--- a/drivers/media/video/saa7134/saa7134-reg.h
+++ b/drivers/media/video/saa7134/saa7134-reg.h
@@ -27,7 +27,7 @@
/* DMA channels, n = 0 ... 6 */
#define SAA7134_RS_BA1(n) ((0x200 >> 2) + 4*n)
-#define SAA7134_RS_BA2(n) ((0x204 >> 2) + 4*n)
+#define SAA7134_RS_BA2(n) ((0x204 >> 2) + 4*n)
#define SAA7134_RS_PITCH(n) ((0x208 >> 2) + 4*n)
#define SAA7134_RS_CONTROL(n) ((0x20c >> 2) + 4*n)
#define SAA7134_RS_CONTROL_WSWAP (0x01 << 25)
@@ -43,16 +43,24 @@
#define SAA7134_FIFO_SIZE (0x2a0 >> 2)
#define SAA7134_THRESHOULD (0x2a4 >> 2)
+#define SAA7133_NUM_SAMPLES (0x588 >> 2)
+#define SAA7133_AUDIO_CHANNEL (0x58c >> 2)
+#define SAA7133_AUDIO_FORMAT (0x58f >> 2)
+#define SAA7133_DIGITAL_OUTPUT_SEL1 (0x46c >> 2)
+#define SAA7133_DIGITAL_OUTPUT_SEL2 (0x470 >> 2)
+#define SAA7133_DIGITAL_INPUT_XBAR1 (0x464 >> 2)
+#define SAA7133_ANALOG_IO_SELECT (0x594 >> 2)
+
/* main control */
#define SAA7134_MAIN_CTRL (0x2a8 >> 2)
-#define SAA7134_MAIN_CTRL_VPLLE (1 << 15)
-#define SAA7134_MAIN_CTRL_APLLE (1 << 14)
-#define SAA7134_MAIN_CTRL_EXOSC (1 << 13)
-#define SAA7134_MAIN_CTRL_EVFE1 (1 << 12)
-#define SAA7134_MAIN_CTRL_EVFE2 (1 << 11)
-#define SAA7134_MAIN_CTRL_ESFE (1 << 10)
-#define SAA7134_MAIN_CTRL_EBADC (1 << 9)
-#define SAA7134_MAIN_CTRL_EBDAC (1 << 8)
+#define SAA7134_MAIN_CTRL_VPLLE (1 << 15)
+#define SAA7134_MAIN_CTRL_APLLE (1 << 14)
+#define SAA7134_MAIN_CTRL_EXOSC (1 << 13)
+#define SAA7134_MAIN_CTRL_EVFE1 (1 << 12)
+#define SAA7134_MAIN_CTRL_EVFE2 (1 << 11)
+#define SAA7134_MAIN_CTRL_ESFE (1 << 10)
+#define SAA7134_MAIN_CTRL_EBADC (1 << 9)
+#define SAA7134_MAIN_CTRL_EBDAC (1 << 8)
#define SAA7134_MAIN_CTRL_TE6 (1 << 6)
#define SAA7134_MAIN_CTRL_TE5 (1 << 5)
#define SAA7134_MAIN_CTRL_TE4 (1 << 4)
@@ -348,6 +356,7 @@
/* test modes */
#define SAA7134_SPECIAL_MODE 0x1d0
+#define SAA7134_PRODUCTION_TEST_MODE 0x1d1
/* audio -- saa7133 + saa7135 only */
#define SAA7135_DSP_RWSTATE 0x580
diff --git a/drivers/media/video/saa7134/saa7134-ts.c b/drivers/media/video/saa7134/saa7134-ts.c
index 463885601ab4..470903e2f5e5 100644
--- a/drivers/media/video/saa7134/saa7134-ts.c
+++ b/drivers/media/video/saa7134/saa7134-ts.c
@@ -46,17 +46,11 @@ static int buffer_activate(struct saa7134_dev *dev,
struct saa7134_buf *buf,
struct saa7134_buf *next)
{
- u32 control;
dprintk("buffer_activate [%p]",buf);
buf->vb.state = STATE_ACTIVE;
buf->top_seen = 0;
- /* dma: setup channel 5 (= TS) */
- control = SAA7134_RS_CONTROL_BURST_16 |
- SAA7134_RS_CONTROL_ME |
- (buf->pt->dma >> 12);
-
if (NULL == next)
next = buf;
if (V4L2_FIELD_TOP == buf->vb.field) {
@@ -68,8 +62,6 @@ static int buffer_activate(struct saa7134_dev *dev,
saa_writel(SAA7134_RS_BA1(5),saa7134_buffer_base(next));
saa_writel(SAA7134_RS_BA2(5),saa7134_buffer_base(buf));
}
- saa_writel(SAA7134_RS_PITCH(5),TS_PACKET_SIZE);
- saa_writel(SAA7134_RS_CONTROL(5),control);
/* start DMA */
saa7134_set_dmabits(dev);
@@ -84,6 +76,7 @@ static int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
struct saa7134_dev *dev = q->priv_data;
struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb);
unsigned int lines, llength, size;
+ u32 control;
int err;
dprintk("buffer_prepare [%p,%s]\n",buf,v4l2_field_names[field]);
@@ -115,6 +108,18 @@ static int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
if (err)
goto oops;
}
+
+ /* dma: setup channel 5 (= TS) */
+ control = SAA7134_RS_CONTROL_BURST_16 |
+ SAA7134_RS_CONTROL_ME |
+ (buf->pt->dma >> 12);
+
+ saa_writeb(SAA7134_TS_DMA0, ((lines-1)&0xff));
+ saa_writeb(SAA7134_TS_DMA1, (((lines-1)>>8)&0xff));
+ saa_writeb(SAA7134_TS_DMA2, ((((lines-1)>>16)&0x3f) | 0x00)); /* TSNOPIT=0, TSCOLAP=0 */
+ saa_writel(SAA7134_RS_PITCH(5),TS_PACKET_SIZE);
+ saa_writel(SAA7134_RS_CONTROL(5),control);
+
buf->vb.state = STATE_PREPARED;
buf->activate = buffer_activate;
buf->vb.field = field;
@@ -164,11 +169,11 @@ EXPORT_SYMBOL_GPL(saa7134_ts_qops);
/* ----------------------------------------------------------- */
/* exported stuff */
-static unsigned int tsbufs = 4;
+static unsigned int tsbufs = 8;
module_param(tsbufs, int, 0444);
MODULE_PARM_DESC(tsbufs,"number of ts buffers, range 2-32");
-static unsigned int ts_nr_packets = 30;
+static unsigned int ts_nr_packets = 64;
module_param(ts_nr_packets, int, 0444);
MODULE_PARM_DESC(ts_nr_packets,"size of a ts buffers (in ts packets)");
@@ -220,10 +225,10 @@ void saa7134_irq_ts_done(struct saa7134_dev *dev, unsigned long status)
if (dev->ts_q.curr) {
field = dev->ts_q.curr->vb.field;
if (field == V4L2_FIELD_TOP) {
- if ((status & 0x100000) != 0x100000)
+ if ((status & 0x100000) != 0x000000)
goto done;
} else {
- if ((status & 0x100000) != 0x000000)
+ if ((status & 0x100000) != 0x100000)
goto done;
}
saa7134_buffer_finish(dev,&dev->ts_q,STATE_DONE);
diff --git a/drivers/media/video/saa7134/saa7134-tvaudio.c b/drivers/media/video/saa7134/saa7134-tvaudio.c
index badf2f9e3072..93268427750d 100644
--- a/drivers/media/video/saa7134/saa7134-tvaudio.c
+++ b/drivers/media/video/saa7134/saa7134-tvaudio.c
@@ -207,6 +207,10 @@ static void tvaudio_setcarrier(struct saa7134_dev *dev,
saa_writel(SAA7134_CARRIER2_FREQ0 >> 2, tvaudio_carr2reg(secondary));
}
+#define SAA7134_MUTE_MASK 0xbb
+#define SAA7134_MUTE_ANALOG 0x04
+#define SAA7134_MUTE_I2S 0x40
+
static void mute_input_7134(struct saa7134_dev *dev)
{
unsigned int mute;
@@ -241,7 +245,11 @@ static void mute_input_7134(struct saa7134_dev *dev)
if (PCI_DEVICE_ID_PHILIPS_SAA7134 == dev->pci->device)
/* 7134 mute */
- saa_writeb(SAA7134_AUDIO_MUTE_CTRL, mute ? 0xbf : 0xbb);
+ saa_writeb(SAA7134_AUDIO_MUTE_CTRL, mute ?
+ SAA7134_MUTE_MASK |
+ SAA7134_MUTE_ANALOG |
+ SAA7134_MUTE_I2S :
+ SAA7134_MUTE_MASK);
/* switch internal audio mux */
switch (in->amux) {
@@ -342,8 +350,8 @@ static int tvaudio_sleep(struct saa7134_dev *dev, int timeout)
set_current_state(TASK_INTERRUPTIBLE);
schedule();
} else {
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(msecs_to_jiffies(timeout));
+ schedule_timeout_interruptible
+ (msecs_to_jiffies(timeout));
}
}
remove_wait_queue(&dev->thread.wq, &wait);
@@ -753,17 +761,17 @@ static int mute_input_7133(struct saa7134_dev *dev)
/* switch gpio-connected external audio mux */
- if (0 != card(dev).gpiomask) {
- mask = card(dev).gpiomask;
+ if (0 != card(dev).gpiomask) {
+ mask = card(dev).gpiomask;
if (card(dev).mute.name && dev->ctl_mute)
in = &card(dev).mute;
else
in = dev->input;
- saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, mask, mask);
- saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, mask, in->gpio);
- saa7134_track_gpio(dev,in->name);
+ saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, mask, mask);
+ saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, mask, in->gpio);
+ saa7134_track_gpio(dev,in->name);
}
return 0;
@@ -1016,9 +1024,12 @@ int saa7134_tvaudio_do_scan(struct saa7134_dev *dev)
return 0;
}
+EXPORT_SYMBOL(saa_dsp_writel);
+
/* ----------------------------------------------------------- */
/*
* Local variables:
* c-basic-offset: 8
* End:
*/
+
diff --git a/drivers/media/video/saa7134/saa7134-video.c b/drivers/media/video/saa7134/saa7134-video.c
index 35e5e85f669a..45c852df13ed 100644
--- a/drivers/media/video/saa7134/saa7134-video.c
+++ b/drivers/media/video/saa7134/saa7134-video.c
@@ -30,6 +30,9 @@
#include "saa7134-reg.h"
#include "saa7134.h"
+/* Include V4L1 specific functions. Should be removed soon */
+#include <linux/videodev.h>
+
/* ------------------------------------------------------------------ */
static unsigned int video_debug = 0;
@@ -48,6 +51,43 @@ MODULE_PARM_DESC(noninterlaced,"video input is noninterlaced");
printk(KERN_DEBUG "%s/video: " fmt, dev->name , ## arg)
/* ------------------------------------------------------------------ */
+/* Defines for Video Output Port Register at address 0x191 */
+
+/* Bit 0: VIP code T bit polarity */
+
+#define VP_T_CODE_P_NON_INVERTED 0x00
+#define VP_T_CODE_P_INVERTED 0x01
+
+/* ------------------------------------------------------------------ */
+/* Defines for Video Output Port Register at address 0x195 */
+
+/* Bit 2: Video output clock delay control */
+
+#define VP_CLK_CTRL2_NOT_DELAYED 0x00
+#define VP_CLK_CTRL2_DELAYED 0x04
+
+/* Bit 1: Video output clock invert control */
+
+#define VP_CLK_CTRL1_NON_INVERTED 0x00
+#define VP_CLK_CTRL1_INVERTED 0x02
+
+/* ------------------------------------------------------------------ */
+/* Defines for Video Output Port Register at address 0x196 */
+
+/* Bits 2 to 0: VSYNC pin video vertical sync type */
+
+#define VP_VS_TYPE_MASK 0x07
+
+#define VP_VS_TYPE_OFF 0x00
+#define VP_VS_TYPE_V123 0x01
+#define VP_VS_TYPE_V_ITU 0x02
+#define VP_VS_TYPE_VGATE_L 0x03
+#define VP_VS_TYPE_RESERVED1 0x04
+#define VP_VS_TYPE_RESERVED2 0x05
+#define VP_VS_TYPE_F_ITU 0x06
+#define VP_VS_TYPE_SC_FID 0x07
+
+/* ------------------------------------------------------------------ */
/* data structs for video */
static int video_out[][9] = {
@@ -273,12 +313,12 @@ static struct saa7134_tvnorm tvnorms[] = {
.h_start = 0,
.h_stop = 719,
- .video_v_start = 23,
- .video_v_stop = 262,
- .vbi_v_start_0 = 10,
- .vbi_v_stop_0 = 21,
- .vbi_v_start_1 = 273,
- .src_timing = 7,
+ .video_v_start = 23,
+ .video_v_stop = 262,
+ .vbi_v_start_0 = 10,
+ .vbi_v_stop_0 = 21,
+ .vbi_v_start_1 = 273,
+ .src_timing = 7,
.sync_control = 0x18,
.luma_control = 0x40,
@@ -622,7 +662,7 @@ static void set_size(struct saa7134_dev *dev, int task,
prescale = 1;
xscale = 1024 * dev->crop_current.width / prescale / width;
yscale = 512 * div * dev->crop_current.height / height;
- dprintk("prescale=%d xscale=%d yscale=%d\n",prescale,xscale,yscale);
+ dprintk("prescale=%d xscale=%d yscale=%d\n",prescale,xscale,yscale);
set_h_prescale(dev,task,prescale);
saa_writeb(SAA7134_H_SCALE_INC1(task), xscale & 0xff);
saa_writeb(SAA7134_H_SCALE_INC2(task), xscale >> 8);
@@ -752,20 +792,20 @@ static int verify_preview(struct saa7134_dev *dev, struct v4l2_window *win)
maxh = dev->crop_current.height;
if (V4L2_FIELD_ANY == field) {
- field = (win->w.height > maxh/2)
- ? V4L2_FIELD_INTERLACED
- : V4L2_FIELD_TOP;
- }
- switch (field) {
- case V4L2_FIELD_TOP:
- case V4L2_FIELD_BOTTOM:
- maxh = maxh / 2;
- break;
- case V4L2_FIELD_INTERLACED:
- break;
- default:
- return -EINVAL;
- }
+ field = (win->w.height > maxh/2)
+ ? V4L2_FIELD_INTERLACED
+ : V4L2_FIELD_TOP;
+ }
+ switch (field) {
+ case V4L2_FIELD_TOP:
+ case V4L2_FIELD_BOTTOM:
+ maxh = maxh / 2;
+ break;
+ case V4L2_FIELD_INTERLACED:
+ break;
+ default:
+ return -EINVAL;
+ }
win->field = field;
if (win->w.width > maxw)
@@ -1306,13 +1346,13 @@ video_poll(struct file *file, struct poll_table_struct *wait)
if (res_locked(fh->dev,RESOURCE_VIDEO)) {
up(&fh->cap.lock);
return POLLERR;
- }
- if (0 != fh->cap.ops->buf_prepare(&fh->cap,fh->cap.read_buf,fh->cap.field)) {
- up(&fh->cap.lock);
- return POLLERR;
- }
- fh->cap.ops->buf_queue(&fh->cap,fh->cap.read_buf);
- fh->cap.read_off = 0;
+ }
+ if (0 != fh->cap.ops->buf_prepare(&fh->cap,fh->cap.read_buf,fh->cap.field)) {
+ up(&fh->cap.lock);
+ return POLLERR;
+ }
+ fh->cap.ops->buf_queue(&fh->cap,fh->cap.read_buf);
+ fh->cap.read_off = 0;
}
up(&fh->cap.lock);
buf = fh->cap.read_buf;
@@ -1666,9 +1706,10 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
case VIDIOC_QUERYCAP:
{
struct v4l2_capability *cap = arg;
+ unsigned int tuner_type = dev->tuner_type;
memset(cap,0,sizeof(*cap));
- strcpy(cap->driver, "saa7134");
+ strcpy(cap->driver, "saa7134");
strlcpy(cap->card, saa7134_boards[dev->board].name,
sizeof(cap->card));
sprintf(cap->bus_info,"PCI:%s",pci_name(dev->pci));
@@ -1677,9 +1718,13 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
V4L2_CAP_VIDEO_CAPTURE |
V4L2_CAP_VIDEO_OVERLAY |
V4L2_CAP_VBI_CAPTURE |
- V4L2_CAP_TUNER |
V4L2_CAP_READWRITE |
- V4L2_CAP_STREAMING;
+ V4L2_CAP_STREAMING |
+ V4L2_CAP_TUNER;
+
+ if ((tuner_type == TUNER_ABSENT) || (tuner_type == UNSET))
+ cap->capabilities &= ~V4L2_CAP_TUNER;
+
return 0;
}
@@ -1793,9 +1838,9 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
crop->c.height = b->top - crop->c.top + b->height;
if (crop->c.left < b->left)
- crop->c.top = b->left;
+ crop->c.left = b->left;
if (crop->c.left > b->left + b->width)
- crop->c.top = b->left + b->width;
+ crop->c.left = b->left + b->width;
if (crop->c.width > b->left - crop->c.left + b->width)
crop->c.width = b->left - crop->c.left + b->width;
@@ -1817,6 +1862,7 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
break;
if (NULL != card_in(dev,n).name) {
strcpy(t->name, "Television");
+ t->type = V4L2_TUNER_ANALOG_TV;
t->capability = V4L2_TUNER_CAP_NORM |
V4L2_TUNER_CAP_STEREO |
V4L2_TUNER_CAP_LANG1 |
@@ -1892,26 +1938,26 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
}
case VIDIOC_S_AUDIO:
return 0;
- case VIDIOC_G_PARM:
- {
- struct v4l2_captureparm *parm = arg;
- memset(parm,0,sizeof(*parm));
- return 0;
- }
-
- case VIDIOC_G_PRIORITY:
- {
- enum v4l2_priority *p = arg;
-
- *p = v4l2_prio_max(&dev->prio);
- return 0;
- }
- case VIDIOC_S_PRIORITY:
- {
- enum v4l2_priority *prio = arg;
-
- return v4l2_prio_change(&dev->prio, &fh->prio, *prio);
- }
+ case VIDIOC_G_PARM:
+ {
+ struct v4l2_captureparm *parm = arg;
+ memset(parm,0,sizeof(*parm));
+ return 0;
+ }
+
+ case VIDIOC_G_PRIORITY:
+ {
+ enum v4l2_priority *p = arg;
+
+ *p = v4l2_prio_max(&dev->prio);
+ return 0;
+ }
+ case VIDIOC_S_PRIORITY:
+ {
+ enum v4l2_priority *prio = arg;
+
+ return v4l2_prio_change(&dev->prio, &fh->prio, *prio);
+ }
/* --- preview ioctls ---------------------------------------- */
case VIDIOC_ENUM_FMT:
@@ -2018,7 +2064,7 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
struct v4l2_format *f = arg;
return saa7134_try_fmt(dev,fh,f);
}
-
+#ifdef HAVE_V4L1
case VIDIOCGMBUF:
{
struct video_mbuf *mbuf = arg;
@@ -2043,6 +2089,7 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
}
return 0;
}
+#endif
case VIDIOC_REQBUFS:
return videobuf_reqbufs(saa7134_queue(fh),arg);
@@ -2060,7 +2107,7 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
{
int res = saa7134_resource(fh);
- if (!res_get(dev,fh,res))
+ if (!res_get(dev,fh,res))
return -EBUSY;
return videobuf_streamon(saa7134_queue(fh));
}
@@ -2102,7 +2149,7 @@ static int radio_do_ioctl(struct inode *inode, struct file *file,
struct v4l2_capability *cap = arg;
memset(cap,0,sizeof(*cap));
- strcpy(cap->driver, "saa7134");
+ strcpy(cap->driver, "saa7134");
strlcpy(cap->card, saa7134_boards[dev->board].name,
sizeof(cap->card));
sprintf(cap->bus_info,"PCI:%s",pci_name(dev->pci));
@@ -2119,6 +2166,7 @@ static int radio_do_ioctl(struct inode *inode, struct file *file,
memset(t,0,sizeof(*t));
strcpy(t->name, "Radio");
+ t->type = V4L2_TUNER_RADIO;
saa7134_i2c_call_clients(dev, VIDIOC_G_TUNER, t);
@@ -2233,7 +2281,7 @@ struct video_device saa7134_video_template =
{
.name = "saa7134-video",
.type = VID_TYPE_CAPTURE|VID_TYPE_TUNER|VID_TYPE_OVERLAY|
- VID_TYPE_CLIPPING|VID_TYPE_SCALES,
+ VID_TYPE_CLIPPING|VID_TYPE_SCALES,
.hardware = 0,
.fops = &video_fops,
.minor = -1,
@@ -2280,7 +2328,7 @@ int saa7134_video_init1(struct saa7134_dev *dev)
dev->tda9887_conf |= TDA9887_AUTOMUTE;
dev->automute = 0;
- INIT_LIST_HEAD(&dev->video_q.queue);
+ INIT_LIST_HEAD(&dev->video_q.queue);
init_timer(&dev->video_q.timeout);
dev->video_q.timeout.function = saa7134_buffer_timeout;
dev->video_q.timeout.data = (unsigned long)(&dev->video_q);
@@ -2289,13 +2337,28 @@ int saa7134_video_init1(struct saa7134_dev *dev)
if (saa7134_boards[dev->board].video_out) {
/* enable video output */
int vo = saa7134_boards[dev->board].video_out;
+ int video_reg;
+ unsigned int vid_port_opts = saa7134_boards[dev->board].vid_port_opts;
saa_writeb(SAA7134_VIDEO_PORT_CTRL0, video_out[vo][0]);
- saa_writeb(SAA7134_VIDEO_PORT_CTRL1, video_out[vo][1]);
+ video_reg = video_out[vo][1];
+ if (vid_port_opts & SET_T_CODE_POLARITY_NON_INVERTED)
+ video_reg &= ~VP_T_CODE_P_INVERTED;
+ saa_writeb(SAA7134_VIDEO_PORT_CTRL1, video_reg);
saa_writeb(SAA7134_VIDEO_PORT_CTRL2, video_out[vo][2]);
saa_writeb(SAA7134_VIDEO_PORT_CTRL3, video_out[vo][3]);
saa_writeb(SAA7134_VIDEO_PORT_CTRL4, video_out[vo][4]);
- saa_writeb(SAA7134_VIDEO_PORT_CTRL5, video_out[vo][5]);
- saa_writeb(SAA7134_VIDEO_PORT_CTRL6, video_out[vo][6]);
+ video_reg = video_out[vo][5];
+ if (vid_port_opts & SET_CLOCK_NOT_DELAYED)
+ video_reg &= ~VP_CLK_CTRL2_DELAYED;
+ if (vid_port_opts & SET_CLOCK_INVERTED)
+ video_reg |= VP_CLK_CTRL1_INVERTED;
+ saa_writeb(SAA7134_VIDEO_PORT_CTRL5, video_reg);
+ video_reg = video_out[vo][6];
+ if (vid_port_opts & SET_VSYNC_OFF) {
+ video_reg &= ~VP_VS_TYPE_MASK;
+ video_reg |= VP_VS_TYPE_OFF;
+ }
+ saa_writeb(SAA7134_VIDEO_PORT_CTRL6, video_reg);
saa_writeb(SAA7134_VIDEO_PORT_CTRL7, video_out[vo][7]);
saa_writeb(SAA7134_VIDEO_PORT_CTRL8, video_out[vo][8]);
}
diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h
index 3ea09142ec9c..fb9727471661 100644
--- a/drivers/media/video/saa7134/saa7134.h
+++ b/drivers/media/video/saa7134/saa7134.h
@@ -24,16 +24,18 @@
#include <linux/pci.h>
#include <linux/i2c.h>
-#include <linux/videodev.h>
+#include <linux/videodev2.h>
#include <linux/kdev_t.h>
#include <linux/input.h>
+#include <linux/notifier.h>
+#include <linux/delay.h>
#include <asm/io.h>
#include <media/tuner.h>
#include <media/audiochip.h>
-#include <media/id.h>
#include <media/ir-common.h>
+#include <media/ir-kbd-i2c.h>
#include <media/video-buf.h>
#include <media/video-buf-dvb.h>
@@ -45,6 +47,10 @@
#endif
#define UNSET (-1U)
+#include <sound/driver.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+
/* ----------------------------------------------------------- */
/* enums */
@@ -187,10 +193,39 @@ struct saa7134_format {
#define SAA7134_BOARD_FLYTV_DIGIMATRIX 64
#define SAA7134_BOARD_KWORLD_TERMINATOR 65
#define SAA7134_BOARD_YUAN_TUN900 66
+#define SAA7134_BOARD_BEHOLD_409FM 67
+#define SAA7134_BOARD_GOTVIEW_7135 68
+#define SAA7134_BOARD_PHILIPS_EUROPA 69
+#define SAA7134_BOARD_VIDEOMATE_DVBT_300 70
+#define SAA7134_BOARD_VIDEOMATE_DVBT_200 71
+#define SAA7134_BOARD_RTD_VFG7350 72
+#define SAA7134_BOARD_RTD_VFG7330 73
+#define SAA7134_BOARD_FLYTVPLATINUM_MINI2 74
+#define SAA7134_BOARD_AVERMEDIA_AVERTVHD_A180 75
+#define SAA7134_BOARD_MONSTERTV_MOBILE 76
+#define SAA7134_BOARD_PINNACLE_PCTV_110i 77
+#define SAA7134_BOARD_ASUSTeK_P7131_DUAL 78
+#define SAA7134_BOARD_SEDNA_PC_TV_CARDBUS 79
+#define SAA7134_BOARD_ASUSTEK_DIGIMATRIX_TV 80
+#define SAA7134_BOARD_PHILIPS_TIGER 81
#define SAA7134_MAXBOARDS 8
#define SAA7134_INPUT_MAX 8
+/* ----------------------------------------------------------- */
+/* Since we support 2 remote types, lets tell them apart */
+
+#define SAA7134_REMOTE_GPIO 1
+#define SAA7134_REMOTE_I2C 2
+
+/* ----------------------------------------------------------- */
+/* Video Output Port Register Initialization Options */
+
+#define SET_T_CODE_POLARITY_NON_INVERTED (1 << 0)
+#define SET_CLOCK_NOT_DELAYED (1 << 1)
+#define SET_CLOCK_INVERTED (1 << 2)
+#define SET_VSYNC_OFF (1 << 3)
+
struct saa7134_input {
char *name;
unsigned int vmux;
@@ -226,6 +261,7 @@ struct saa7134_board {
/* peripheral I/O */
enum saa7134_video_out video_out;
enum saa7134_mpeg_type mpeg;
+ unsigned int vid_port_opts;
};
#define card_has_radio(dev) (NULL != saa7134_boards[dev->board].radio.name)
@@ -319,9 +355,9 @@ struct saa7134_fh {
struct saa7134_pgtable pt_vbi;
};
-/* oss dsp status */
-struct saa7134_oss {
- struct semaphore lock;
+/* dmasound dsp status */
+struct saa7134_dmasound {
+ struct semaphore lock;
int minor_mixer;
int minor_dsp;
unsigned int users_dsp;
@@ -347,20 +383,21 @@ struct saa7134_oss {
unsigned int dma_blk;
unsigned int read_offset;
unsigned int read_count;
+ snd_pcm_substream_t *substream;
};
/* IR input */
struct saa7134_ir {
- struct input_dev dev;
+ struct input_dev *dev;
struct ir_input_state ir;
char name[32];
char phys[32];
u32 mask_keycode;
u32 mask_keydown;
u32 mask_keyup;
- int polling;
- u32 last_gpio;
- struct timer_list timer;
+ int polling;
+ u32 last_gpio;
+ struct timer_list timer;
};
/* ts/mpeg status */
@@ -383,8 +420,8 @@ struct saa7134_mpeg_ops {
/* global device status */
struct saa7134_dev {
struct list_head devlist;
- struct semaphore lock;
- spinlock_t slock;
+ struct semaphore lock;
+ spinlock_t slock;
#ifdef VIDIOC_G_PRIORITY
struct v4l2_prio_state prio;
#endif
@@ -394,7 +431,7 @@ struct saa7134_dev {
struct video_device *video_dev;
struct video_device *radio_dev;
struct video_device *vbi_dev;
- struct saa7134_oss oss;
+ struct saa7134_dmasound dmasound;
/* infrared remote */
int has_remote;
@@ -421,7 +458,7 @@ struct saa7134_dev {
/* i2c i/o */
struct i2c_adapter i2c_adap;
struct i2c_client i2c_client;
- unsigned char eedata[64];
+ unsigned char eedata[128];
/* video overlay */
struct v4l2_framebuffer ovbuf;
@@ -626,6 +663,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);
/*
* Local variables:
diff --git a/drivers/media/video/saa7191.c b/drivers/media/video/saa7191.c
index 454f5c1199b4..cbca896e8cfa 100644
--- a/drivers/media/video/saa7191.c
+++ b/drivers/media/video/saa7191.c
@@ -9,16 +9,16 @@
* published by the Free Software Foundation.
*/
-#include <linux/module.h>
-#include <linux/init.h>
#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/fs.h>
+#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/major.h>
-#include <linux/slab.h>
+#include <linux/module.h>
#include <linux/mm.h>
#include <linux/sched.h>
+#include <linux/slab.h>
#include <linux/videodev.h>
#include <linux/video_decoder.h>
@@ -26,73 +26,95 @@
#include "saa7191.h"
-#define SAA7191_MODULE_VERSION "0.0.3"
+#define SAA7191_MODULE_VERSION "0.0.5"
MODULE_DESCRIPTION("Philips SAA7191 video decoder driver");
MODULE_VERSION(SAA7191_MODULE_VERSION);
MODULE_AUTHOR("Mikael Nousiainen <tmnousia@cc.hut.fi>");
MODULE_LICENSE("GPL");
-#define VINO_ADAPTER (I2C_ALGO_SGI | I2C_HW_SGI_VINO)
+// #define SAA7191_DEBUG
+
+#ifdef SAA7191_DEBUG
+#define dprintk(x...) printk("SAA7191: " x);
+#else
+#define dprintk(x...)
+#endif
+
+#define SAA7191_SYNC_COUNT 30
+#define SAA7191_SYNC_DELAY 100 /* milliseconds */
struct saa7191 {
struct i2c_client *client;
/* the register values are stored here as the actual
* I2C-registers are write-only */
- unsigned char reg[25];
+ u8 reg[25];
- unsigned char norm;
- unsigned char input;
+ int input;
+ int norm;
};
static struct i2c_driver i2c_driver_saa7191;
-static const unsigned char initseq[] = {
+static const u8 initseq[] = {
0, /* Subaddress */
- 0x50, /* SAA7191_REG_IDEL */
- 0x30, /* SAA7191_REG_HSYB */
- 0x00, /* SAA7191_REG_HSYS */
- 0xe8, /* SAA7191_REG_HCLB */
- 0xb6, /* SAA7191_REG_HCLS */
- 0xf4, /* SAA7191_REG_HPHI */
- 0x01, /* SAA7191_REG_LUMA - chrominance trap active (CVBS) */
- 0x00, /* SAA7191_REG_HUEC */
- 0xf8, /* SAA7191_REG_CKTQ */
- 0xf8, /* SAA7191_REG_CKTS */
- 0x90, /* SAA7191_REG_PLSE */
- 0x90, /* SAA7191_REG_SESE */
- 0x00, /* SAA7191_REG_GAIN */
- 0x0c, /* SAA7191_REG_STDC - not SECAM, slow time constant */
- 0x78, /* SAA7191_REG_IOCK - chrominance from CVBS, GPSW1 & 2 off */
- 0x99, /* SAA7191_REG_CTL3 - automatic field detection */
- 0x00, /* SAA7191_REG_CTL4 */
- 0x2c, /* SAA7191_REG_CHCV */
+
+ 0x50, /* (0x50) SAA7191_REG_IDEL */
+
+ /* 50 Hz signal timing */
+ 0x30, /* (0x30) SAA7191_REG_HSYB */
+ 0x00, /* (0x00) SAA7191_REG_HSYS */
+ 0xe8, /* (0xe8) SAA7191_REG_HCLB */
+ 0xb6, /* (0xb6) SAA7191_REG_HCLS */
+ 0xf4, /* (0xf4) SAA7191_REG_HPHI */
+
+ /* control */
+ SAA7191_LUMA_APER_1, /* (0x01) SAA7191_REG_LUMA - CVBS mode */
+ 0x00, /* (0x00) SAA7191_REG_HUEC */
+ 0xf8, /* (0xf8) SAA7191_REG_CKTQ */
+ 0xf8, /* (0xf8) SAA7191_REG_CKTS */
+ 0x90, /* (0x90) SAA7191_REG_PLSE */
+ 0x90, /* (0x90) SAA7191_REG_SESE */
+ 0x00, /* (0x00) SAA7191_REG_GAIN */
+ SAA7191_STDC_NFEN | SAA7191_STDC_HRMV, /* (0x0c) SAA7191_REG_STDC
+ * - not SECAM,
+ * slow time constant */
+ SAA7191_IOCK_OEDC | SAA7191_IOCK_OEHS | SAA7191_IOCK_OEVS
+ | SAA7191_IOCK_OEDY, /* (0x78) SAA7191_REG_IOCK
+ * - chroma from CVBS, GPSW1 & 2 off */
+ SAA7191_CTL3_AUFD | SAA7191_CTL3_SCEN | SAA7191_CTL3_OFTS
+ | SAA7191_CTL3_YDEL0, /* (0x99) SAA7191_REG_CTL3
+ * - automatic field detection */
+ 0x00, /* (0x00) SAA7191_REG_CTL4 */
+ 0x2c, /* (0x2c) SAA7191_REG_CHCV - PAL nominal value */
0x00, /* unused */
0x00, /* unused */
- 0x34, /* SAA7191_REG_HS6B */
- 0x0a, /* SAA7191_REG_HS6S */
- 0xf4, /* SAA7191_REG_HC6B */
- 0xce, /* SAA7191_REG_HC6S */
- 0xf4, /* SAA7191_REG_HP6I */
+
+ /* 60 Hz signal timing */
+ 0x34, /* (0x34) SAA7191_REG_HS6B */
+ 0x0a, /* (0x0a) SAA7191_REG_HS6S */
+ 0xf4, /* (0xf4) SAA7191_REG_HC6B */
+ 0xce, /* (0xce) SAA7191_REG_HC6S */
+ 0xf4, /* (0xf4) SAA7191_REG_HP6I */
};
/* SAA7191 register handling */
-static unsigned char saa7191_read_reg(struct i2c_client *client,
- unsigned char reg)
+static u8 saa7191_read_reg(struct i2c_client *client,
+ u8 reg)
{
return ((struct saa7191 *)i2c_get_clientdata(client))->reg[reg];
}
static int saa7191_read_status(struct i2c_client *client,
- unsigned char *value)
+ u8 *value)
{
int ret;
ret = i2c_master_recv(client, value, 1);
if (ret < 0) {
- printk(KERN_ERR "SAA7191: saa7191_read_status(): read failed");
+ printk(KERN_ERR "SAA7191: saa7191_read_status(): read failed\n");
return ret;
}
@@ -100,17 +122,16 @@ static int saa7191_read_status(struct i2c_client *client,
}
-static int saa7191_write_reg(struct i2c_client *client, unsigned char reg,
- unsigned char value)
+static int saa7191_write_reg(struct i2c_client *client, u8 reg,
+ u8 value)
{
-
((struct saa7191 *)i2c_get_clientdata(client))->reg[reg] = value;
return i2c_smbus_write_byte_data(client, reg, value);
}
/* the first byte of data must be the first subaddress number (register) */
static int saa7191_write_block(struct i2c_client *client,
- unsigned char length, unsigned char *data)
+ u8 length, u8 *data)
{
int i;
int ret;
@@ -123,7 +144,7 @@ static int saa7191_write_block(struct i2c_client *client,
ret = i2c_master_send(client, data, length);
if (ret < 0) {
printk(KERN_ERR "SAA7191: saa7191_write_block(): "
- "write failed");
+ "write failed\n");
return ret;
}
@@ -134,8 +155,9 @@ static int saa7191_write_block(struct i2c_client *client,
static int saa7191_set_input(struct i2c_client *client, int input)
{
- unsigned char luma = saa7191_read_reg(client, SAA7191_REG_LUMA);
- unsigned char iock = saa7191_read_reg(client, SAA7191_REG_IOCK);
+ struct saa7191 *decoder = i2c_get_clientdata(client);
+ u8 luma = saa7191_read_reg(client, SAA7191_REG_LUMA);
+ u8 iock = saa7191_read_reg(client, SAA7191_REG_IOCK);
int err;
switch (input) {
@@ -161,32 +183,20 @@ static int saa7191_set_input(struct i2c_client *client, int input)
if (err)
return -EIO;
+ decoder->input = input;
+
return 0;
}
static int saa7191_set_norm(struct i2c_client *client, int norm)
{
struct saa7191 *decoder = i2c_get_clientdata(client);
- unsigned char stdc = saa7191_read_reg(client, SAA7191_REG_STDC);
- unsigned char ctl3 = saa7191_read_reg(client, SAA7191_REG_CTL3);
- unsigned char chcv = saa7191_read_reg(client, SAA7191_REG_CHCV);
+ u8 stdc = saa7191_read_reg(client, SAA7191_REG_STDC);
+ u8 ctl3 = saa7191_read_reg(client, SAA7191_REG_CTL3);
+ u8 chcv = saa7191_read_reg(client, SAA7191_REG_CHCV);
int err;
switch(norm) {
- case SAA7191_NORM_AUTO: {
- unsigned char status;
-
- // does status depend on current norm ?
- if (saa7191_read_status(client, &status))
- return -EIO;
-
- stdc &= ~SAA7191_STDC_SECS;
- ctl3 &= ~SAA7191_CTL3_FSEL;
- ctl3 |= SAA7191_CTL3_AUFD;
- chcv = (status & SAA7191_STATUS_FIDT)
- ? SAA7191_CHCV_NTSC : SAA7191_CHCV_PAL;
- break;
- }
case SAA7191_NORM_PAL:
stdc &= ~SAA7191_STDC_SECS;
ctl3 &= ~(SAA7191_CTL3_AUFD | SAA7191_CTL3_FSEL);
@@ -219,60 +229,335 @@ static int saa7191_set_norm(struct i2c_client *client, int norm)
decoder->norm = norm;
+ dprintk("ctl3: %02x stdc: %02x chcv: %02x\n", ctl3,
+ stdc, chcv);
+ dprintk("norm: %d\n", norm);
+
return 0;
}
-static int saa7191_get_controls(struct i2c_client *client,
- struct saa7191_control *ctrl)
+static int saa7191_wait_for_signal(struct i2c_client *client, u8 *status)
{
- unsigned char hue = saa7191_read_reg(client, SAA7191_REG_HUEC);
- unsigned char stdc = saa7191_read_reg(client, SAA7191_REG_STDC);
+ int i = 0;
- if (hue < 0x80) {
- hue += 0x80;
- } else {
- hue -= 0x80;
+ dprintk("Checking for signal...\n");
+
+ for (i = 0; i < SAA7191_SYNC_COUNT; i++) {
+ if (saa7191_read_status(client, status))
+ return -EIO;
+
+ if (((*status) & SAA7191_STATUS_HLCK) == 0) {
+ dprintk("Signal found\n");
+ return 0;
+ }
+
+ msleep(SAA7191_SYNC_DELAY);
}
- ctrl->hue = hue;
- ctrl->vtrc = (stdc & SAA7191_STDC_VTRC)
- ? SAA7191_VALUE_ENABLED : SAA7191_VALUE_DISABLED;
+ dprintk("No signal\n");
- return 0;
+ return -EBUSY;
}
-static int saa7191_set_controls(struct i2c_client *client,
- struct saa7191_control *ctrl)
+static int saa7191_autodetect_norm_extended(struct i2c_client *client)
{
- int err;
+ u8 stdc = saa7191_read_reg(client, SAA7191_REG_STDC);
+ u8 ctl3 = saa7191_read_reg(client, SAA7191_REG_CTL3);
+ u8 status;
+ int err = 0;
- if (ctrl->hue >= 0) {
- unsigned char hue = ctrl->hue & 0xff;
- if (hue < 0x80) {
- hue += 0x80;
- } else {
- hue -= 0x80;
+ dprintk("SAA7191 extended signal auto-detection...\n");
+
+ stdc &= ~SAA7191_STDC_SECS;
+ ctl3 &= ~(SAA7191_CTL3_FSEL);
+
+ err = saa7191_write_reg(client, SAA7191_REG_STDC, stdc);
+ if (err) {
+ err = -EIO;
+ goto out;
+ }
+ err = saa7191_write_reg(client, SAA7191_REG_CTL3, ctl3);
+ if (err) {
+ err = -EIO;
+ goto out;
+ }
+
+ ctl3 |= SAA7191_CTL3_AUFD;
+ err = saa7191_write_reg(client, SAA7191_REG_CTL3, ctl3);
+ if (err) {
+ err = -EIO;
+ goto out;
+ }
+
+ msleep(SAA7191_SYNC_DELAY);
+
+ err = saa7191_wait_for_signal(client, &status);
+ if (err)
+ goto out;
+
+ if (status & SAA7191_STATUS_FIDT) {
+ /* 60Hz signal -> NTSC */
+ dprintk("60Hz signal: NTSC\n");
+ return saa7191_set_norm(client, SAA7191_NORM_NTSC);
+ }
+
+ /* 50Hz signal */
+ dprintk("50Hz signal: Trying PAL...\n");
+
+ /* try PAL first */
+ err = saa7191_set_norm(client, SAA7191_NORM_PAL);
+ if (err)
+ goto out;
+
+ msleep(SAA7191_SYNC_DELAY);
+
+ err = saa7191_wait_for_signal(client, &status);
+ if (err)
+ goto out;
+
+ /* not 50Hz ? */
+ if (status & SAA7191_STATUS_FIDT) {
+ dprintk("No 50Hz signal\n");
+ err = -EAGAIN;
+ goto out;
+ }
+
+ if (status & SAA7191_STATUS_CODE) {
+ dprintk("PAL\n");
+ return 0;
+ }
+
+ dprintk("No color detected with PAL - Trying SECAM...\n");
+
+ /* no color detected ? -> try SECAM */
+ err = saa7191_set_norm(client,
+ SAA7191_NORM_SECAM);
+ if (err)
+ goto out;
+
+ msleep(SAA7191_SYNC_DELAY);
+
+ err = saa7191_wait_for_signal(client, &status);
+ if (err)
+ goto out;
+
+ /* not 50Hz ? */
+ if (status & SAA7191_STATUS_FIDT) {
+ dprintk("No 50Hz signal\n");
+ err = -EAGAIN;
+ goto out;
+ }
+
+ if (status & SAA7191_STATUS_CODE) {
+ /* Color detected -> SECAM */
+ dprintk("SECAM\n");
+ return 0;
+ }
+
+ dprintk("No color detected with SECAM - Going back to PAL.\n");
+
+ /* still no color detected ?
+ * -> set norm back to PAL */
+ err = saa7191_set_norm(client,
+ SAA7191_NORM_PAL);
+ if (err)
+ goto out;
+
+out:
+ ctl3 = saa7191_read_reg(client, SAA7191_REG_CTL3);
+ if (ctl3 & SAA7191_CTL3_AUFD) {
+ ctl3 &= ~(SAA7191_CTL3_AUFD);
+ err = saa7191_write_reg(client, SAA7191_REG_CTL3, ctl3);
+ if (err) {
+ err = -EIO;
}
- err = saa7191_write_reg(client, SAA7191_REG_HUEC, hue);
- if (err)
- return -EIO;
}
- if (ctrl->vtrc >= 0) {
- unsigned char stdc =
- saa7191_read_reg(client, SAA7191_REG_STDC);
- if (ctrl->vtrc) {
- stdc |= SAA7191_STDC_VTRC;
- } else {
- stdc &= ~SAA7191_STDC_VTRC;
+ return err;
+}
+
+static int saa7191_autodetect_norm(struct i2c_client *client)
+{
+ u8 status;
+
+ dprintk("SAA7191 signal auto-detection...\n");
+
+ dprintk("Reading status...\n");
+
+ if (saa7191_read_status(client, &status))
+ return -EIO;
+
+ dprintk("Checking for signal...\n");
+
+ /* no signal ? */
+ if (status & SAA7191_STATUS_HLCK) {
+ dprintk("No signal\n");
+ return -EBUSY;
+ }
+
+ dprintk("Signal found\n");
+
+ if (status & SAA7191_STATUS_FIDT) {
+ /* 60hz signal -> NTSC */
+ dprintk("NTSC\n");
+ return saa7191_set_norm(client, SAA7191_NORM_NTSC);
+ } else {
+ /* 50hz signal -> PAL */
+ dprintk("PAL\n");
+ return saa7191_set_norm(client, SAA7191_NORM_PAL);
+ }
+}
+
+static int saa7191_get_control(struct i2c_client *client,
+ struct saa7191_control *ctrl)
+{
+ u8 reg;
+ int ret = 0;
+
+ switch (ctrl->type) {
+ case SAA7191_CONTROL_BANDPASS:
+ case SAA7191_CONTROL_BANDPASS_WEIGHT:
+ case SAA7191_CONTROL_CORING:
+ reg = saa7191_read_reg(client, SAA7191_REG_LUMA);
+ switch (ctrl->type) {
+ case SAA7191_CONTROL_BANDPASS:
+ ctrl->value = ((s32)reg & SAA7191_LUMA_BPSS_MASK)
+ >> SAA7191_LUMA_BPSS_SHIFT;
+ break;
+ case SAA7191_CONTROL_BANDPASS_WEIGHT:
+ ctrl->value = ((s32)reg & SAA7191_LUMA_APER_MASK)
+ >> SAA7191_LUMA_APER_SHIFT;
+ break;
+ case SAA7191_CONTROL_CORING:
+ ctrl->value = ((s32)reg & SAA7191_LUMA_CORI_MASK)
+ >> SAA7191_LUMA_CORI_SHIFT;
+ break;
}
+ break;
+ case SAA7191_CONTROL_FORCE_COLOUR:
+ case SAA7191_CONTROL_CHROMA_GAIN:
+ reg = saa7191_read_reg(client, SAA7191_REG_GAIN);
+ if (ctrl->type == SAA7191_CONTROL_FORCE_COLOUR)
+ ctrl->value = ((s32)reg & SAA7191_GAIN_COLO) ? 1 : 0;
+ else
+ ctrl->value = ((s32)reg & SAA7191_GAIN_LFIS_MASK)
+ >> SAA7191_GAIN_LFIS_SHIFT;
+ break;
+ case SAA7191_CONTROL_HUE:
+ reg = saa7191_read_reg(client, SAA7191_REG_HUEC);
+ if (reg < 0x80)
+ reg += 0x80;
+ else
+ reg -= 0x80;
+ ctrl->value = (s32)reg;
+ break;
+ case SAA7191_CONTROL_VTRC:
+ reg = saa7191_read_reg(client, SAA7191_REG_STDC);
+ ctrl->value = ((s32)reg & SAA7191_STDC_VTRC) ? 1 : 0;
+ break;
+ case SAA7191_CONTROL_LUMA_DELAY:
+ reg = saa7191_read_reg(client, SAA7191_REG_CTL3);
+ ctrl->value = ((s32)reg & SAA7191_CTL3_YDEL_MASK)
+ >> SAA7191_CTL3_YDEL_SHIFT;
+ if (ctrl->value >= 4)
+ ctrl->value -= 8;
+ break;
+ case SAA7191_CONTROL_VNR:
+ reg = saa7191_read_reg(client, SAA7191_REG_CTL4);
+ ctrl->value = ((s32)reg & SAA7191_CTL4_VNOI_MASK)
+ >> SAA7191_CTL4_VNOI_SHIFT;
+ break;
+ default:
+ ret = -EINVAL;
+ }
- err = saa7191_write_reg(client, SAA7191_REG_STDC, stdc);
- if (err)
- return -EIO;
+ return ret;
+}
+
+static int saa7191_set_control(struct i2c_client *client,
+ struct saa7191_control *ctrl)
+{
+ u8 reg;
+ int ret = 0;
+
+ switch (ctrl->type) {
+ case SAA7191_CONTROL_BANDPASS:
+ case SAA7191_CONTROL_BANDPASS_WEIGHT:
+ case SAA7191_CONTROL_CORING:
+ reg = saa7191_read_reg(client, SAA7191_REG_LUMA);
+ switch (ctrl->type) {
+ case SAA7191_CONTROL_BANDPASS:
+ reg &= ~SAA7191_LUMA_BPSS_MASK;
+ reg |= (ctrl->value << SAA7191_LUMA_BPSS_SHIFT)
+ & SAA7191_LUMA_BPSS_MASK;
+ break;
+ case SAA7191_CONTROL_BANDPASS_WEIGHT:
+ reg &= ~SAA7191_LUMA_APER_MASK;
+ reg |= (ctrl->value << SAA7191_LUMA_APER_SHIFT)
+ & SAA7191_LUMA_APER_MASK;
+ break;
+ case SAA7191_CONTROL_CORING:
+ reg &= ~SAA7191_LUMA_CORI_MASK;
+ reg |= (ctrl->value << SAA7191_LUMA_CORI_SHIFT)
+ & SAA7191_LUMA_CORI_MASK;
+ break;
+ }
+ ret = saa7191_write_reg(client, SAA7191_REG_LUMA, reg);
+ break;
+ case SAA7191_CONTROL_FORCE_COLOUR:
+ case SAA7191_CONTROL_CHROMA_GAIN:
+ reg = saa7191_read_reg(client, SAA7191_REG_GAIN);
+ if (ctrl->type == SAA7191_CONTROL_FORCE_COLOUR) {
+ if (ctrl->value)
+ reg |= SAA7191_GAIN_COLO;
+ else
+ reg &= ~SAA7191_GAIN_COLO;
+ } else {
+ reg &= ~SAA7191_GAIN_LFIS_MASK;
+ reg |= (ctrl->value << SAA7191_GAIN_LFIS_SHIFT)
+ & SAA7191_GAIN_LFIS_MASK;
+ }
+ ret = saa7191_write_reg(client, SAA7191_REG_GAIN, reg);
+ break;
+ case SAA7191_CONTROL_HUE:
+ reg = ctrl->value & 0xff;
+ if (reg < 0x80)
+ reg += 0x80;
+ else
+ reg -= 0x80;
+ ret = saa7191_write_reg(client, SAA7191_REG_HUEC, reg);
+ break;
+ case SAA7191_CONTROL_VTRC:
+ reg = saa7191_read_reg(client, SAA7191_REG_STDC);
+ if (ctrl->value)
+ reg |= SAA7191_STDC_VTRC;
+ else
+ reg &= ~SAA7191_STDC_VTRC;
+ ret = saa7191_write_reg(client, SAA7191_REG_STDC, reg);
+ break;
+ case SAA7191_CONTROL_LUMA_DELAY: {
+ s32 value = ctrl->value;
+ if (value < 0)
+ value += 8;
+ reg = saa7191_read_reg(client, SAA7191_REG_CTL3);
+ reg &= ~SAA7191_CTL3_YDEL_MASK;
+ reg |= (value << SAA7191_CTL3_YDEL_SHIFT)
+ & SAA7191_CTL3_YDEL_MASK;
+ ret = saa7191_write_reg(client, SAA7191_REG_CTL3, reg);
+ break;
+ }
+ case SAA7191_CONTROL_VNR:
+ reg = saa7191_read_reg(client, SAA7191_REG_CTL4);
+ reg &= ~SAA7191_CTL4_VNOI_MASK;
+ reg |= (ctrl->value << SAA7191_CTL4_VNOI_SHIFT)
+ & SAA7191_CTL4_VNOI_MASK;
+ ret = saa7191_write_reg(client, SAA7191_REG_CTL4, reg);
+ break;
+ default:
+ ret = -EINVAL;
}
- return 0;
+ return ret;
}
/* I2C-interface */
@@ -311,11 +596,7 @@ static int saa7191_attach(struct i2c_adapter *adap, int addr, int kind)
if (err)
goto out_free_decoder;
- decoder->input = SAA7191_INPUT_COMPOSITE;
- decoder->norm = SAA7191_NORM_AUTO;
-
- err = saa7191_write_block(client, sizeof(initseq),
- (unsigned char *)initseq);
+ err = saa7191_write_block(client, sizeof(initseq), (u8 *)initseq);
if (err) {
printk(KERN_ERR "SAA7191 initialization failed\n");
goto out_detach_client;
@@ -323,6 +604,14 @@ static int saa7191_attach(struct i2c_adapter *adap, int addr, int kind)
printk(KERN_INFO "SAA7191 initialized\n");
+ decoder->input = SAA7191_INPUT_COMPOSITE;
+ decoder->norm = SAA7191_NORM_PAL;
+
+ err = saa7191_autodetect_norm(client);
+ if (err && (err != -EBUSY)) {
+ printk(KERN_ERR "SAA7191: Signal auto-detection failed\n");
+ }
+
return 0;
out_detach_client:
@@ -337,7 +626,7 @@ out_free_client:
static int saa7191_probe(struct i2c_adapter *adap)
{
/* Always connected to VINO */
- if (adap->id == VINO_ADAPTER)
+ if (adap->id == I2C_HW_SGI_VINO)
return saa7191_attach(adap, SAA7191_ADDR, 0);
/* Feel free to add probe here :-) */
return -ENODEV;
@@ -364,13 +653,13 @@ static int saa7191_command(struct i2c_client *client, unsigned int cmd,
cap->flags = VIDEO_DECODER_PAL | VIDEO_DECODER_NTSC |
VIDEO_DECODER_SECAM | VIDEO_DECODER_AUTO;
- cap->inputs = (client->adapter->id == VINO_ADAPTER) ? 2 : 1;
+ cap->inputs = (client->adapter->id == I2C_HW_SGI_VINO) ? 2 : 1;
cap->outputs = 1;
break;
}
case DECODER_GET_STATUS: {
int *iarg = arg;
- unsigned char status;
+ u8 status;
int res = 0;
if (saa7191_read_status(client, &status)) {
@@ -406,7 +695,7 @@ static int saa7191_command(struct i2c_client *client, unsigned int cmd,
switch (*iarg) {
case VIDEO_MODE_AUTO:
- return saa7191_set_norm(client, SAA7191_NORM_AUTO);
+ return saa7191_autodetect_norm(client);
case VIDEO_MODE_PAL:
return saa7191_set_norm(client, SAA7191_NORM_PAL);
case VIDEO_MODE_NTSC:
@@ -422,7 +711,7 @@ static int saa7191_command(struct i2c_client *client, unsigned int cmd,
int *iarg = arg;
switch (client->adapter->id) {
- case VINO_ADAPTER:
+ case I2C_HW_SGI_VINO:
return saa7191_set_input(client, *iarg);
default:
if (*iarg != 0)
@@ -448,38 +737,48 @@ static int saa7191_command(struct i2c_client *client, unsigned int cmd,
int err;
val = (pic->hue >> 8) - 0x80;
+
err = saa7191_write_reg(client, SAA7191_REG_HUEC, val);
if (err)
return -EIO;
+
break;
}
case DECODER_SAA7191_GET_STATUS: {
struct saa7191_status *status = arg;
- unsigned char status_reg;
+ u8 status_reg;
if (saa7191_read_status(client, &status_reg))
return -EIO;
+
status->signal = ((status_reg & SAA7191_STATUS_HLCK) == 0)
- ? SAA7191_VALUE_ENABLED : SAA7191_VALUE_DISABLED;
- status->ntsc = (status_reg & SAA7191_STATUS_FIDT)
- ? SAA7191_VALUE_ENABLED : SAA7191_VALUE_DISABLED;
- status->color = (status_reg & SAA7191_STATUS_CODE)
- ? SAA7191_VALUE_ENABLED : SAA7191_VALUE_DISABLED;
+ ? 1 : 0;
+ status->signal_60hz = (status_reg & SAA7191_STATUS_FIDT)
+ ? 1 : 0;
+ status->color = (status_reg & SAA7191_STATUS_CODE) ? 1 : 0;
status->input = decoder->input;
status->norm = decoder->norm;
+
+ break;
}
case DECODER_SAA7191_SET_NORM: {
int *norm = arg;
- return saa7191_set_norm(client, *norm);
+
+ switch (*norm) {
+ case SAA7191_NORM_AUTO:
+ return saa7191_autodetect_norm(client);
+ case SAA7191_NORM_AUTO_EXT:
+ return saa7191_autodetect_norm_extended(client);
+ default:
+ return saa7191_set_norm(client, *norm);
+ }
}
- case DECODER_SAA7191_GET_CONTROLS: {
- struct saa7191_control *ctrl = arg;
- return saa7191_get_controls(client, ctrl);
+ case DECODER_SAA7191_GET_CONTROL: {
+ return saa7191_get_control(client, arg);
}
- case DECODER_SAA7191_SET_CONTROLS: {
- struct saa7191_control *ctrl = arg;
- return saa7191_set_controls(client, ctrl);
+ case DECODER_SAA7191_SET_CONTROL: {
+ return saa7191_set_control(client, arg);
}
default:
return -EINVAL;
@@ -490,12 +789,12 @@ static int saa7191_command(struct i2c_client *client, unsigned int cmd,
static struct i2c_driver i2c_driver_saa7191 = {
.owner = THIS_MODULE,
- .name = "saa7191",
- .id = I2C_DRIVERID_SAA7191,
- .flags = I2C_DF_NOTIFY,
+ .name = "saa7191",
+ .id = I2C_DRIVERID_SAA7191,
+ .flags = I2C_DF_NOTIFY,
.attach_adapter = saa7191_probe,
- .detach_client = saa7191_detach,
- .command = saa7191_command
+ .detach_client = saa7191_detach,
+ .command = saa7191_command
};
static int saa7191_init(void)
diff --git a/drivers/media/video/saa7191.h b/drivers/media/video/saa7191.h
index 272045031435..a2310da1940d 100644
--- a/drivers/media/video/saa7191.h
+++ b/drivers/media/video/saa7191.h
@@ -24,8 +24,8 @@
#define SAA7191_REG_HPHI 0x05
#define SAA7191_REG_LUMA 0x06
#define SAA7191_REG_HUEC 0x07
-#define SAA7191_REG_CKTQ 0x08
-#define SAA7191_REG_CKTS 0x09
+#define SAA7191_REG_CKTQ 0x08 /* bits 3-7 */
+#define SAA7191_REG_CKTS 0x09 /* bits 3-7 */
#define SAA7191_REG_PLSE 0x0a
#define SAA7191_REG_SESE 0x0b
#define SAA7191_REG_GAIN 0x0c
@@ -43,30 +43,82 @@
/* Status Register definitions */
#define SAA7191_STATUS_CODE 0x01 /* color detected flag */
-#define SAA7191_STATUS_FIDT 0x20 /* format type NTSC/PAL */
-#define SAA7191_STATUS_HLCK 0x40 /* PLL unlocked/locked */
+#define SAA7191_STATUS_FIDT 0x20 /* signal type 50/60 Hz */
+#define SAA7191_STATUS_HLCK 0x40 /* PLL unlocked(1)/locked(0) */
#define SAA7191_STATUS_STTC 0x80 /* tv/vtr time constant */
/* Luminance Control Register definitions */
+/* input mode select bit:
+ * 0=CVBS (chrominance trap active), 1=S-Video (trap bypassed) */
#define SAA7191_LUMA_BYPS 0x80
-
-/* Chroma Gain Control Settings Register definitions */
-/* 0=automatic colour-killer enabled, 1=forced colour on */
+/* pre-filter (only when chrominance trap is active) */
+#define SAA7191_LUMA_PREF 0x40
+/* aperture bandpass to select different characteristics with maximums
+ * (bits 4-5) */
+#define SAA7191_LUMA_BPSS_MASK 0x30
+#define SAA7191_LUMA_BPSS_SHIFT 4
+#define SAA7191_LUMA_BPSS_3 0x30
+#define SAA7191_LUMA_BPSS_2 0x20
+#define SAA7191_LUMA_BPSS_1 0x10
+#define SAA7191_LUMA_BPSS_0 0x00
+/* coring range for high frequency components according to 8-bit luminance
+ * (bits 2-3)
+ * 0=coring off, n= (+-)n LSB */
+#define SAA7191_LUMA_CORI_MASK 0x0c
+#define SAA7191_LUMA_CORI_SHIFT 2
+#define SAA7191_LUMA_CORI_3 0x0c
+#define SAA7191_LUMA_CORI_2 0x08
+#define SAA7191_LUMA_CORI_1 0x04
+#define SAA7191_LUMA_CORI_0 0x00
+/* aperture bandpass filter weights high frequency components of luminance
+ * signal (bits 0-1)
+ * 0=factor 0, 1=0.25, 2=0.5, 3=1 */
+#define SAA7191_LUMA_APER_MASK 0x03
+#define SAA7191_LUMA_APER_SHIFT 0
+#define SAA7191_LUMA_APER_3 0x03
+#define SAA7191_LUMA_APER_2 0x02
+#define SAA7191_LUMA_APER_1 0x01
+#define SAA7191_LUMA_APER_0 0x00
+
+/* Chrominance Gain Control Settings Register definitions */
+/* colour on: 0=automatic colour-killer enabled, 1=forced colour on */
#define SAA7191_GAIN_COLO 0x80
+/* chrominance gain control (AGC filter)
+ * 0=loop filter time constant slow, 1=medium, 2=fast, 3=actual gain */
+#define SAA7191_GAIN_LFIS_MASK 0x60
+#define SAA7191_GAIN_LFIS_SHIFT 5
+#define SAA7191_GAIN_LFIS_3 0x60
+#define SAA7191_GAIN_LFIS_2 0x40
+#define SAA7191_GAIN_LFIS_1 0x20
+#define SAA7191_GAIN_LFIS_0 0x00
/* Standard/Mode Control Register definitions */
/* tv/vtr mode bit: 0=TV mode (slow time constant),
* 1=VTR mode (fast time constant) */
#define SAA7191_STDC_VTRC 0x80
+/* SAA7191B-specific functions enable (RTCO, ODD and GPSW0 outputs)
+ * 0=outputs set to high-impedance (circuit equals SAA7191), 1=enabled */
+#define SAA7191_STDC_NFEN 0x08
+/* HREF generation: 0=like SAA7191, 1=HREF is 8xLLC2 clocks earlier */
+#define SAA7191_STDC_HRMV 0x04
+/* general purpose switch 0
+ * (not used with VINO afaik) */
+#define SAA7191_STDC_GPSW0 0x02
/* SECAM mode bit: 0=other standards, 1=SECAM */
#define SAA7191_STDC_SECS 0x01
-/* the bit fields above must be or'd with this value */
-#define SAA7191_STDC_VALUE 0x0c
/* I/O and Clock Control Register definitions */
/* horizontal clock PLL: 0=PLL closed,
* 1=PLL circuit open and horizontal freq fixed */
#define SAA7191_IOCK_HPLL 0x80
+/* colour-difference output enable (outputs UV0-UV7) */
+#define SAA7191_IOCK_OEDC 0x40
+/* H-sync output enable */
+#define SAA7191_IOCK_OEHS 0x20
+/* V-sync output enable */
+#define SAA7191_IOCK_OEVS 0x10
+/* luminance output enable (outputs Y0-Y7) */
+#define SAA7191_IOCK_OEDY 0x08
/* S-VHS bit (chrominance from CVBS or from chrominance input):
* 0=controlled by BYPS-bit, 1=from chrominance input */
#define SAA7191_IOCK_CHRS 0x04
@@ -83,11 +135,40 @@
/* field select: (if AUFD=0)
* 0=50Hz (625 lines), 1=60Hz (525 lines) */
#define SAA7191_CTL3_FSEL 0x40
-/* the bit fields above must be or'd with this value */
-#define SAA7191_CTL3_VALUE 0x19
+/* SECAM cross-colour reduction enable */
+#define SAA7191_CTL3_SXCR 0x20
+/* sync and clamping pulse enable (HCL and HSY outputs) */
+#define SAA7191_CTL3_SCEN 0x10
+/* output format: 0=4:1:1, 1=4:2:2 (4:2:2 for VINO) */
+#define SAA7191_CTL3_OFTS 0x08
+/* luminance delay compensation
+ * 0=0*2/LLC, 1=+1*2/LLC, 2=+2*2/LLC, 3=+3*2/LLC,
+ * 4=-4*2/LLC, 5=-3*2/LLC, 6=-2*2/LLC, 7=-1*2/LLC
+ * step size = 2/LLC = 67.8ns for 50Hz, 81.5ns for 60Hz */
+#define SAA7191_CTL3_YDEL_MASK 0x07
+#define SAA7191_CTL3_YDEL_SHIFT 0
+#define SAA7191_CTL3_YDEL2 0x04
+#define SAA7191_CTL3_YDEL1 0x02
+#define SAA7191_CTL3_YDEL0 0x01
+
+/* Miscellaneous Control #2 Register definitions */
+/* select HREF position
+ * 0=normal, HREF is matched to YUV output port,
+ * 1=HREF is matched to CVBS input port */
+#define SAA7191_CTL4_HRFS 0x04
+/* vertical noise reduction
+ * 0=normal, 1=searching window, 2=auto-deflection, 3=reduction bypassed */
+#define SAA7191_CTL4_VNOI_MASK 0x03
+#define SAA7191_CTL4_VNOI_SHIFT 0
+#define SAA7191_CTL4_VNOI_3 0x03
+#define SAA7191_CTL4_VNOI_2 0x02
+#define SAA7191_CTL4_VNOI_1 0x01
+#define SAA7191_CTL4_VNOI_0 0x00
/* Chrominance Gain Control Register definitions
- * (nominal value for UV CCIR level) */
+ * - for QAM-modulated input signals, effects output amplitude
+ * (SECAM gain fixed)
+ * (nominal values for UV CCIR level) */
#define SAA7191_CHCV_NTSC 0x2c
#define SAA7191_CHCV_PAL 0x59
@@ -99,16 +180,13 @@
#define SAA7191_NORM_PAL 1
#define SAA7191_NORM_NTSC 2
#define SAA7191_NORM_SECAM 3
-
-#define SAA7191_VALUE_ENABLED 1
-#define SAA7191_VALUE_DISABLED 0
-#define SAA7191_VALUE_UNCHANGED -1
+#define SAA7191_NORM_AUTO_EXT 4 /* extended auto-detection */
struct saa7191_status {
- /* 0=no signal, 1=signal active*/
+ /* 0=no signal, 1=signal detected */
int signal;
/* 0=50hz (pal) signal, 1=60hz (ntsc) signal */
- int ntsc;
+ int signal_60hz;
/* 0=no color detected, 1=color detected */
int color;
@@ -118,22 +196,60 @@ struct saa7191_status {
int norm;
};
-#define SAA7191_HUE_MIN 0x00
-#define SAA7191_HUE_MAX 0xff
-#define SAA7191_HUE_DEFAULT 0x80
+#define SAA7191_BANDPASS_MIN 0x00
+#define SAA7191_BANDPASS_MAX 0x03
+#define SAA7191_BANDPASS_DEFAULT 0x00
+
+#define SAA7191_BANDPASS_WEIGHT_MIN 0x00
+#define SAA7191_BANDPASS_WEIGHT_MAX 0x03
+#define SAA7191_BANDPASS_WEIGHT_DEFAULT 0x01
+
+#define SAA7191_CORING_MIN 0x00
+#define SAA7191_CORING_MAX 0x03
+#define SAA7191_CORING_DEFAULT 0x00
+
+#define SAA7191_HUE_MIN 0x00
+#define SAA7191_HUE_MAX 0xff
+#define SAA7191_HUE_DEFAULT 0x80
+
+#define SAA7191_VTRC_MIN 0x00
+#define SAA7191_VTRC_MAX 0x01
+#define SAA7191_VTRC_DEFAULT 0x00
+
+#define SAA7191_FORCE_COLOUR_MIN 0x00
+#define SAA7191_FORCE_COLOUR_MAX 0x01
+#define SAA7191_FORCE_COLOUR_DEFAULT 0x00
+
+#define SAA7191_CHROMA_GAIN_MIN 0x00
+#define SAA7191_CHROMA_GAIN_MAX 0x03
+#define SAA7191_CHROMA_GAIN_DEFAULT 0x00
+
+#define SAA7191_LUMA_DELAY_MIN -0x04
+#define SAA7191_LUMA_DELAY_MAX 0x03
+#define SAA7191_LUMA_DELAY_DEFAULT 0x01
+
+#define SAA7191_VNR_MIN 0x00
+#define SAA7191_VNR_MAX 0x03
+#define SAA7191_VNR_DEFAULT 0x00
-#define SAA7191_VTRC_MIN 0x00
-#define SAA7191_VTRC_MAX 0x01
-#define SAA7191_VTRC_DEFAULT 0x00
+#define SAA7191_CONTROL_BANDPASS 0
+#define SAA7191_CONTROL_BANDPASS_WEIGHT 1
+#define SAA7191_CONTROL_CORING 2
+#define SAA7191_CONTROL_FORCE_COLOUR 3 /* boolean */
+#define SAA7191_CONTROL_CHROMA_GAIN 4
+#define SAA7191_CONTROL_HUE 5
+#define SAA7191_CONTROL_VTRC 6 /* boolean */
+#define SAA7191_CONTROL_LUMA_DELAY 7
+#define SAA7191_CONTROL_VNR 8
struct saa7191_control {
- int hue;
- int vtrc;
+ u8 type;
+ s32 value;
};
#define DECODER_SAA7191_GET_STATUS _IOR('d', 195, struct saa7191_status)
#define DECODER_SAA7191_SET_NORM _IOW('d', 196, int)
-#define DECODER_SAA7191_GET_CONTROLS _IOR('d', 197, struct saa7191_control)
-#define DECODER_SAA7191_SET_CONTROLS _IOW('d', 198, struct saa7191_control)
+#define DECODER_SAA7191_GET_CONTROL _IOR('d', 197, struct saa7191_control)
+#define DECODER_SAA7191_SET_CONTROL _IOW('d', 198, struct saa7191_control)
#endif
diff --git a/drivers/media/video/tda7432.c b/drivers/media/video/tda7432.c
index 255b6088ebf9..d32737dd2142 100644
--- a/drivers/media/video/tda7432.c
+++ b/drivers/media/video/tda7432.c
@@ -50,7 +50,6 @@
#include "bttv.h"
#include <media/audiochip.h>
-#include <media/id.h>
#ifndef VIDEO_AUDIO_BALANCE
# define VIDEO_AUDIO_BALANCE 32
@@ -310,9 +309,9 @@ static int tda7432_attach(struct i2c_adapter *adap, int addr, int kind)
memset(t,0,sizeof *t);
client = &t->c;
- memcpy(client,&client_template,sizeof(struct i2c_client));
- client->adapter = adap;
- client->addr = addr;
+ memcpy(client,&client_template,sizeof(struct i2c_client));
+ client->adapter = adap;
+ client->addr = addr;
i2c_set_clientdata(client, t);
do_tda7432_init(client);
@@ -472,7 +471,7 @@ static int tda7432_command(struct i2c_client *client,
}
}
- t->muted=(va->flags & VIDEO_AUDIO_MUTE);
+ t->muted=(va->flags & VIDEO_AUDIO_MUTE);
if (t->muted)
{
/* Mute & update balance*/
@@ -503,12 +502,12 @@ static int tda7432_command(struct i2c_client *client,
static struct i2c_driver driver = {
.owner = THIS_MODULE,
- .name = "i2c tda7432 driver",
+ .name = "i2c tda7432 driver",
.id = I2C_DRIVERID_TDA7432,
- .flags = I2C_DF_NOTIFY,
+ .flags = I2C_DF_NOTIFY,
.attach_adapter = tda7432_probe,
- .detach_client = tda7432_detach,
- .command = tda7432_command,
+ .detach_client = tda7432_detach,
+ .command = tda7432_command,
};
static struct i2c_client client_template =
diff --git a/drivers/media/video/tda8290.c b/drivers/media/video/tda8290.c
index c65f0c7680a2..b2dfe07e9f9d 100644
--- a/drivers/media/video/tda8290.c
+++ b/drivers/media/video/tda8290.c
@@ -1,172 +1,406 @@
/*
- *
- * i2c tv tuner chip device driver
- * controls the philips tda8290+75 tuner chip combo.
- */
+
+ i2c tv tuner chip device driver
+ controls the philips tda8290+75 tuner chip combo.
+
+ 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/i2c.h>
#include <linux/videodev.h>
#include <linux/delay.h>
#include <media/tuner.h>
-#define I2C_ADDR_TDA8290 0x4b
-#define I2C_ADDR_TDA8275 0x61
-
/* ---------------------------------------------------------------------- */
-struct freq_entry {
- u16 freq;
- u8 value;
+struct tda827x_data {
+ u32 lomax;
+ u8 spd;
+ u8 bs;
+ u8 bp;
+ u8 cp;
+ u8 gc3;
+ u8 div1p5;
};
-static struct freq_entry band_table[] = {
- { 0x2DF4, 0x1C },
- { 0x2574, 0x14 },
- { 0x22B4, 0x0C },
- { 0x20D4, 0x0B },
- { 0x1E74, 0x3B },
- { 0x1C34, 0x33 },
- { 0x16F4, 0x5B },
- { 0x1454, 0x53 },
- { 0x12D4, 0x52 },
- { 0x1034, 0x4A },
- { 0x0EE4, 0x7A },
- { 0x0D34, 0x72 },
- { 0x0B54, 0x9A },
- { 0x0914, 0x91 },
- { 0x07F4, 0x89 },
- { 0x0774, 0xB9 },
- { 0x067B, 0xB1 },
- { 0x0634, 0xD9 },
- { 0x05A4, 0xD8 }, // FM radio
- { 0x0494, 0xD0 },
- { 0x03BC, 0xC8 },
- { 0x0394, 0xF8 }, // 57250000 Hz
- { 0x0000, 0xF0 }, // 0
+ /* Note lomax entry is lo / 62500 */
+
+static struct tda827x_data tda827x_analog[] = {
+ { .lomax = 992, .spd = 3, .bs = 2, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 1}, /* 62 MHz */
+ { .lomax = 1056, .spd = 3, .bs = 3, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 1}, /* 66 MHz */
+ { .lomax = 1216, .spd = 3, .bs = 1, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 0}, /* 76 MHz */
+ { .lomax = 1344, .spd = 3, .bs = 2, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 0}, /* 84 MHz */
+ { .lomax = 1488, .spd = 3, .bs = 2, .bp = 0, .cp = 0, .gc3 = 1, .div1p5 = 0}, /* 93 MHz */
+ { .lomax = 1568, .spd = 3, .bs = 3, .bp = 0, .cp = 0, .gc3 = 1, .div1p5 = 0}, /* 98 MHz */
+ { .lomax = 1744, .spd = 3, .bs = 3, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 0}, /* 109 MHz */
+ { .lomax = 1968, .spd = 2, .bs = 2, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 1}, /* 123 MHz */
+ { .lomax = 2128, .spd = 2, .bs = 3, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 1}, /* 133 MHz */
+ { .lomax = 2416, .spd = 2, .bs = 1, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 0}, /* 151 MHz */
+ { .lomax = 2464, .spd = 2, .bs = 2, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 0}, /* 154 MHz */
+ { .lomax = 2896, .spd = 2, .bs = 2, .bp = 1, .cp = 0, .gc3 = 0, .div1p5 = 0}, /* 181 MHz */
+ { .lomax = 2960, .spd = 2, .bs = 2, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 0}, /* 185 MHz */
+ { .lomax = 3472, .spd = 2, .bs = 3, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 0}, /* 217 MHz */
+ { .lomax = 3904, .spd = 1, .bs = 2, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 1}, /* 244 MHz */
+ { .lomax = 4240, .spd = 1, .bs = 3, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 1}, /* 265 MHz */
+ { .lomax = 4832, .spd = 1, .bs = 1, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 0}, /* 302 MHz */
+ { .lomax = 5184, .spd = 1, .bs = 2, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 0}, /* 324 MHz */
+ { .lomax = 5920, .spd = 1, .bs = 2, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 0}, /* 370 MHz */
+ { .lomax = 7264, .spd = 1, .bs = 3, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 0}, /* 454 MHz */
+ { .lomax = 7888, .spd = 0, .bs = 2, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 1}, /* 493 MHz */
+ { .lomax = 8480, .spd = 0, .bs = 3, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 1}, /* 530 MHz */
+ { .lomax = 8864, .spd = 0, .bs = 1, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 0}, /* 554 MHz */
+ { .lomax = 9664, .spd = 0, .bs = 1, .bp = 4, .cp = 0, .gc3 = 0, .div1p5 = 0}, /* 604 MHz */
+ { .lomax = 11088, .spd = 0, .bs = 2, .bp = 4, .cp = 0, .gc3 = 0, .div1p5 = 0}, /* 696 MHz */
+ { .lomax = 11840, .spd = 0, .bs = 2, .bp = 4, .cp = 1, .gc3 = 0, .div1p5 = 0}, /* 740 MHz */
+ { .lomax = 13120, .spd = 0, .bs = 3, .bp = 4, .cp = 0, .gc3 = 0, .div1p5 = 0}, /* 820 MHz */
+ { .lomax = 13840, .spd = 0, .bs = 3, .bp = 4, .cp = 1, .gc3 = 0, .div1p5 = 0}, /* 865 MHz */
+ { .lomax = 0, .spd = 0, .bs = 0, .bp = 0, .cp = 0, .gc3 = 0, .div1p5 = 0} /* End */
};
-static struct freq_entry div_table[] = {
- { 0x1C34, 3 },
- { 0x0D34, 2 },
- { 0x067B, 1 },
- { 0x0000, 0 },
-};
+static void tda827x_tune(struct i2c_client *c, u16 ifc, unsigned int freq)
+{
+ unsigned char tuner_reg[8];
+ unsigned char reg2[2];
+ u32 N;
+ int i;
+ struct tuner *t = i2c_get_clientdata(c);
+ struct i2c_msg msg = {.addr = t->tda827x_addr, .flags = 0};
-static struct freq_entry agc_table[] = {
- { 0x22B4, 0x8F },
- { 0x0B54, 0x9F },
- { 0x09A4, 0x8F },
- { 0x0554, 0x9F },
- { 0x0000, 0xBF },
-};
+ if (t->mode == V4L2_TUNER_RADIO)
+ freq = freq / 1000;
-static __u8 get_freq_entry( struct freq_entry* table, __u16 freq)
-{
- while(table->freq && table->freq > freq)
- table++;
- return table->value;
-}
+ N = freq + ifc;
+ i = 0;
+ while (tda827x_analog[i].lomax < N) {
+ if(tda827x_analog[i + 1].lomax == 0)
+ break;
+ i++;
+ }
+
+ N = N << tda827x_analog[i].spd;
+
+ tuner_reg[0] = 0;
+ tuner_reg[1] = (unsigned char)(N>>8);
+ tuner_reg[2] = (unsigned char) N;
+ tuner_reg[3] = 0x40;
+ tuner_reg[4] = 0x52 + (t->tda827x_lpsel << 5);
+ tuner_reg[5] = (tda827x_analog[i].spd << 6) + (tda827x_analog[i].div1p5 <<5) +
+ (tda827x_analog[i].bs <<3) + tda827x_analog[i].bp;
+ tuner_reg[6] = 0x8f + (tda827x_analog[i].gc3 << 4);
+ tuner_reg[7] = 0x8f;
+
+ msg.buf = tuner_reg;
+ msg.len = 8;
+ i2c_transfer(c->adapter, &msg, 1);
+
+ msg.buf= reg2;
+ msg.len = 2;
+ reg2[0] = 0x80;
+ reg2[1] = 0;
+ i2c_transfer(c->adapter, &msg, 1);
+
+ reg2[0] = 0x60;
+ reg2[1] = 0xbf;
+ i2c_transfer(c->adapter, &msg, 1);
+
+ reg2[0] = 0x30;
+ reg2[1] = tuner_reg[4] + 0x80;
+ i2c_transfer(c->adapter, &msg, 1);
+
+ msleep(1);
+ reg2[0] = 0x30;
+ reg2[1] = tuner_reg[4] + 4;
+ i2c_transfer(c->adapter, &msg, 1);
+
+ msleep(1);
+ reg2[0] = 0x30;
+ reg2[1] = tuner_reg[4];
+ i2c_transfer(c->adapter, &msg, 1);
-/* ---------------------------------------------------------------------- */
+ msleep(550);
+ reg2[0] = 0x30;
+ reg2[1] = (tuner_reg[4] & 0xfc) + tda827x_analog[i].cp ;
+ i2c_transfer(c->adapter, &msg, 1);
-static unsigned char i2c_enable_bridge[2] = { 0x21, 0xC0 };
-static unsigned char i2c_disable_bridge[2] = { 0x21, 0x80 };
-static unsigned char i2c_init_tda8275[14] = { 0x00, 0x00, 0x00, 0x00,
- 0xfC, 0x04, 0xA3, 0x3F,
- 0x2A, 0x04, 0xFF, 0x00,
- 0x00, 0x40 };
-static unsigned char i2c_set_VS[2] = { 0x30, 0x6F };
-static unsigned char i2c_set_GP01_CF[2] = { 0x20, 0x0B };
-static unsigned char i2c_tda8290_reset[2] = { 0x00, 0x00 };
-static unsigned char i2c_tda8290_standby[2] = { 0x00, 0x02 };
-static unsigned char i2c_gainset_off[2] = { 0x28, 0x14 };
-static unsigned char i2c_gainset_on[2] = { 0x28, 0x54 };
-static unsigned char i2c_agc3_00[2] = { 0x80, 0x00 };
-static unsigned char i2c_agc2_BF[2] = { 0x60, 0xBF };
-static unsigned char i2c_cb1_D0[2] = { 0x30, 0xD0 };
-static unsigned char i2c_cb1_D2[2] = { 0x30, 0xD2 };
-static unsigned char i2c_cb1_56[2] = { 0x30, 0x56 };
-static unsigned char i2c_cb1_52[2] = { 0x30, 0x52 };
-static unsigned char i2c_cb1_50[2] = { 0x30, 0x50 };
-static unsigned char i2c_agc2_7F[2] = { 0x60, 0x7F };
-static unsigned char i2c_agc3_08[2] = { 0x80, 0x08 };
-
-static struct i2c_msg i2c_msg_init[] = {
- { I2C_ADDR_TDA8275, 0, ARRAY_SIZE(i2c_init_tda8275), i2c_init_tda8275 },
- { I2C_ADDR_TDA8290, 0, ARRAY_SIZE(i2c_disable_bridge), i2c_disable_bridge },
- { I2C_ADDR_TDA8290, 0, ARRAY_SIZE(i2c_set_VS), i2c_set_VS },
- { I2C_ADDR_TDA8290, 0, ARRAY_SIZE(i2c_set_GP01_CF), i2c_set_GP01_CF },
-};
+ reg2[0] = 0x60;
+ reg2[1] = 0x3f;
+ i2c_transfer(c->adapter, &msg, 1);
-static struct i2c_msg i2c_msg_prolog[] = {
-// { I2C_ADDR_TDA8290, 0, ARRAY_SIZE(i2c_easy_mode), i2c_easy_mode },
- { I2C_ADDR_TDA8290, 0, ARRAY_SIZE(i2c_gainset_off), i2c_gainset_off },
- { I2C_ADDR_TDA8290, 0, ARRAY_SIZE(i2c_tda8290_reset), i2c_tda8290_reset },
- { I2C_ADDR_TDA8290, 0, ARRAY_SIZE(i2c_enable_bridge), i2c_enable_bridge },
-};
+ reg2[0] = 0x80;
+ reg2[1] = 0x08; // Vsync en
+ i2c_transfer(c->adapter, &msg, 1);
+}
-static struct i2c_msg i2c_msg_config[] = {
-// { I2C_ADDR_TDA8275, 0, ARRAY_SIZE(i2c_set_freq), i2c_set_freq },
- { I2C_ADDR_TDA8275, 0, ARRAY_SIZE(i2c_agc3_00), i2c_agc3_00 },
- { I2C_ADDR_TDA8275, 0, ARRAY_SIZE(i2c_agc2_BF), i2c_agc2_BF },
- { I2C_ADDR_TDA8275, 0, ARRAY_SIZE(i2c_cb1_D2), i2c_cb1_D2 },
- { I2C_ADDR_TDA8275, 0, ARRAY_SIZE(i2c_cb1_56), i2c_cb1_56 },
- { I2C_ADDR_TDA8275, 0, ARRAY_SIZE(i2c_cb1_52), i2c_cb1_52 },
-};
+static void tda827x_agcf(struct i2c_client *c)
+{
+ struct tuner *t = i2c_get_clientdata(c);
+ unsigned char data[] = {0x80, 0x0c};
+ struct i2c_msg msg = {.addr = t->tda827x_addr, .buf = data,
+ .flags = 0, .len = 2};
+ i2c_transfer(c->adapter, &msg, 1);
+}
-static struct i2c_msg i2c_msg_epilog[] = {
- { I2C_ADDR_TDA8275, 0, ARRAY_SIZE(i2c_cb1_50), i2c_cb1_50 },
- { I2C_ADDR_TDA8275, 0, ARRAY_SIZE(i2c_agc2_7F), i2c_agc2_7F },
- { I2C_ADDR_TDA8275, 0, ARRAY_SIZE(i2c_agc3_08), i2c_agc3_08 },
- { I2C_ADDR_TDA8290, 0, ARRAY_SIZE(i2c_disable_bridge), i2c_disable_bridge },
- { I2C_ADDR_TDA8290, 0, ARRAY_SIZE(i2c_gainset_on), i2c_gainset_on },
+/* ---------------------------------------------------------------------- */
+
+struct tda827xa_data {
+ u32 lomax;
+ u8 svco;
+ u8 spd;
+ u8 scr;
+ u8 sbs;
+ u8 gc3;
};
-static struct i2c_msg i2c_msg_standby[] = {
- { I2C_ADDR_TDA8290, 0, ARRAY_SIZE(i2c_enable_bridge), i2c_enable_bridge },
- { I2C_ADDR_TDA8275, 0, ARRAY_SIZE(i2c_cb1_D0), i2c_cb1_D0 },
- { I2C_ADDR_TDA8290, 0, ARRAY_SIZE(i2c_disable_bridge), i2c_disable_bridge },
- { I2C_ADDR_TDA8290, 0, ARRAY_SIZE(i2c_tda8290_standby), i2c_tda8290_standby },
+static struct tda827xa_data tda827xa_analog[] = {
+ { .lomax = 910, .svco = 3, .spd = 4, .scr = 0, .sbs = 0, .gc3 = 3}, /* 56.875 MHz */
+ { .lomax = 1076, .svco = 0, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 3}, /* 67.25 MHz */
+ { .lomax = 1300, .svco = 1, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 3}, /* 81.25 MHz */
+ { .lomax = 1560, .svco = 2, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 3}, /* 97.5 MHz */
+ { .lomax = 1820, .svco = 3, .spd = 3, .scr = 0, .sbs = 1, .gc3 = 1}, /* 113.75 MHz */
+ { .lomax = 2152, .svco = 0, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1}, /* 134.5 MHz */
+ { .lomax = 2464, .svco = 1, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1}, /* 154 MHz */
+ { .lomax = 2600, .svco = 1, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1}, /* 162.5 MHz */
+ { .lomax = 2928, .svco = 2, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1}, /* 183 MHz */
+ { .lomax = 3120, .svco = 2, .spd = 2, .scr = 0, .sbs = 2, .gc3 = 1}, /* 195 MHz */
+ { .lomax = 3640, .svco = 3, .spd = 2, .scr = 0, .sbs = 2, .gc3 = 3}, /* 227.5 MHz */
+ { .lomax = 4304, .svco = 0, .spd = 1, .scr = 0, .sbs = 2, .gc3 = 3}, /* 269 MHz */
+ { .lomax = 5200, .svco = 1, .spd = 1, .scr = 0, .sbs = 2, .gc3 = 1}, /* 325 MHz */
+ { .lomax = 6240, .svco = 2, .spd = 1, .scr = 0, .sbs = 3, .gc3 = 3}, /* 390 MHz */
+ { .lomax = 7280, .svco = 3, .spd = 1, .scr = 0, .sbs = 3, .gc3 = 3}, /* 455 MHz */
+ { .lomax = 8320, .svco = 0, .spd = 0, .scr = 0, .sbs = 3, .gc3 = 1}, /* 520 MHz */
+ { .lomax = 8608, .svco = 0, .spd = 0, .scr = 1, .sbs = 3, .gc3 = 1}, /* 538 MHz */
+ { .lomax = 8864, .svco = 1, .spd = 0, .scr = 0, .sbs = 3, .gc3 = 1}, /* 554 MHz */
+ { .lomax = 9920, .svco = 1, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0}, /* 620 MHz */
+ { .lomax = 10400, .svco = 1, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0}, /* 650 MHz */
+ { .lomax = 11200, .svco = 2, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0}, /* 700 MHz */
+ { .lomax = 12480, .svco = 2, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0}, /* 780 MHz */
+ { .lomax = 13120, .svco = 3, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0}, /* 820 MHz */
+ { .lomax = 13920, .svco = 3, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0}, /* 870 MHz */
+ { .lomax = 14576, .svco = 3, .spd = 0, .scr = 2, .sbs = 4, .gc3 = 0}, /* 911 MHz */
+ { .lomax = 0, .svco = 0, .spd = 0, .scr = 0, .sbs = 0, .gc3 = 0} /* End */
};
-static int tda8290_tune(struct i2c_client *c)
+static void tda827xa_tune(struct i2c_client *c, u16 ifc, unsigned int freq)
{
+ unsigned char tuner_reg[14];
+ unsigned char reg2[2];
+ u32 N;
+ int i;
struct tuner *t = i2c_get_clientdata(c);
- struct i2c_msg easy_mode =
- { I2C_ADDR_TDA8290, 0, 2, t->i2c_easy_mode };
- struct i2c_msg set_freq =
- { I2C_ADDR_TDA8275, 0, 8, t->i2c_set_freq };
+ struct i2c_msg msg = {.addr = t->tda827x_addr, .flags = 0};
- i2c_transfer(c->adapter, &easy_mode, 1);
- i2c_transfer(c->adapter, i2c_msg_prolog, ARRAY_SIZE(i2c_msg_prolog));
+ if (t->mode == V4L2_TUNER_RADIO)
+ freq = freq / 1000;
- i2c_transfer(c->adapter, &set_freq, 1);
- i2c_transfer(c->adapter, i2c_msg_config, ARRAY_SIZE(i2c_msg_config));
+ N = freq + ifc;
+ i = 0;
+ while (tda827xa_analog[i].lomax < N) {
+ if(tda827xa_analog[i + 1].lomax == 0)
+ break;
+ i++;
+ }
+
+ N = N << tda827xa_analog[i].spd;
+
+ tuner_reg[0] = 0;
+ tuner_reg[1] = (unsigned char)(N>>8);
+ tuner_reg[2] = (unsigned char) N;
+ tuner_reg[3] = 0;
+ tuner_reg[4] = 0x16;
+ tuner_reg[5] = (tda827xa_analog[i].spd << 5) + (tda827xa_analog[i].svco << 3) +
+ tda827xa_analog[i].sbs;
+ tuner_reg[6] = 0x8b + (tda827xa_analog[i].gc3 << 4);
+ tuner_reg[7] = 0x0c;
+ tuner_reg[8] = 4;
+ tuner_reg[9] = 0x20;
+ tuner_reg[10] = 0xff;
+ tuner_reg[11] = 0xe0;
+ tuner_reg[12] = 0;
+ tuner_reg[13] = 0x39 + (t->tda827x_lpsel << 1);
+
+ msg.buf = tuner_reg;
+ msg.len = 14;
+ i2c_transfer(c->adapter, &msg, 1);
+
+ msg.buf= reg2;
+ msg.len = 2;
+ reg2[0] = 0x60;
+ reg2[1] = 0x3c;
+ i2c_transfer(c->adapter, &msg, 1);
+
+ reg2[0] = 0xa0;
+ reg2[1] = 0xc0;
+ i2c_transfer(c->adapter, &msg, 1);
+
+ msleep(2);
+ reg2[0] = 0x30;
+ reg2[1] = 0x10 + tda827xa_analog[i].scr;
+ i2c_transfer(c->adapter, &msg, 1);
msleep(550);
- i2c_transfer(c->adapter, i2c_msg_epilog, ARRAY_SIZE(i2c_msg_epilog));
- return 0;
+ reg2[0] = 0x50;
+ reg2[1] = 0x8f + (tda827xa_analog[i].gc3 << 4);
+ i2c_transfer(c->adapter, &msg, 1);
+
+ reg2[0] = 0x80;
+ reg2[1] = 0x28;
+ i2c_transfer(c->adapter, &msg, 1);
+
+ reg2[0] = 0xb0;
+ reg2[1] = 0x01;
+ i2c_transfer(c->adapter, &msg, 1);
+
+ reg2[0] = 0xc0;
+ reg2[1] = 0x19 + (t->tda827x_lpsel << 1);
+ i2c_transfer(c->adapter, &msg, 1);
}
-static void set_frequency(struct tuner *t, u16 ifc, unsigned int freq)
+static void tda827xa_agcf(struct i2c_client *c)
{
- u32 N;
+ struct tuner *t = i2c_get_clientdata(c);
+ unsigned char data[] = {0x80, 0x2c};
+ struct i2c_msg msg = {.addr = t->tda827x_addr, .buf = data,
+ .flags = 0, .len = 2};
+ i2c_transfer(c->adapter, &msg, 1);
+}
- if (t->mode == V4L2_TUNER_RADIO)
- freq = freq / 1000;
+/*---------------------------------------------------------------------*/
- N = (((freq<<3)+ifc)&0x3fffc);
-
- N = N >> get_freq_entry(div_table, freq);
- t->i2c_set_freq[0] = 0;
- t->i2c_set_freq[1] = (unsigned char)(N>>8);
- t->i2c_set_freq[2] = (unsigned char) N;
- t->i2c_set_freq[3] = 0x40;
- t->i2c_set_freq[4] = 0x52;
- t->i2c_set_freq[5] = get_freq_entry(band_table, freq);
- t->i2c_set_freq[6] = get_freq_entry(agc_table, freq);
- t->i2c_set_freq[7] = 0x8f;
+static void tda8290_i2c_bridge(struct i2c_client *c, int close)
+{
+ unsigned char enable[2] = { 0x21, 0xC0 };
+ unsigned char disable[2] = { 0x21, 0x80 };
+ unsigned char *msg;
+ if(close) {
+ msg = enable;
+ i2c_master_send(c, msg, 2);
+ /* let the bridge stabilize */
+ msleep(20);
+ } else {
+ msg = disable;
+ i2c_master_send(c, msg, 2);
+ }
}
+/*---------------------------------------------------------------------*/
+
+static int tda8290_tune(struct i2c_client *c, u16 ifc, unsigned int freq)
+{
+ struct tuner *t = i2c_get_clientdata(c);
+ unsigned char soft_reset[] = { 0x00, 0x00 };
+ unsigned char easy_mode[] = { 0x01, t->tda8290_easy_mode };
+ unsigned char expert_mode[] = { 0x01, 0x80 };
+ unsigned char gainset_off[] = { 0x28, 0x14 };
+ unsigned char if_agc_spd[] = { 0x0f, 0x88 };
+ unsigned char adc_head_6[] = { 0x05, 0x04 };
+ unsigned char adc_head_9[] = { 0x05, 0x02 };
+ unsigned char adc_head_12[] = { 0x05, 0x01 };
+ unsigned char pll_bw_nom[] = { 0x0d, 0x47 };
+ unsigned char pll_bw_low[] = { 0x0d, 0x27 };
+ unsigned char gainset_2[] = { 0x28, 0x64 };
+ unsigned char agc_rst_on[] = { 0x0e, 0x0b };
+ unsigned char agc_rst_off[] = { 0x0e, 0x09 };
+ unsigned char if_agc_set[] = { 0x0f, 0x81 };
+ unsigned char addr_adc_sat = 0x1a;
+ unsigned char addr_agc_stat = 0x1d;
+ unsigned char addr_pll_stat = 0x1b;
+ unsigned char adc_sat, agc_stat,
+ pll_stat;
+
+ i2c_master_send(c, easy_mode, 2);
+ i2c_master_send(c, soft_reset, 2);
+ msleep(1);
+
+ expert_mode[1] = t->tda8290_easy_mode + 0x80;
+ i2c_master_send(c, expert_mode, 2);
+ i2c_master_send(c, gainset_off, 2);
+ i2c_master_send(c, if_agc_spd, 2);
+ if (t->tda8290_easy_mode & 0x60)
+ i2c_master_send(c, adc_head_9, 2);
+ else
+ i2c_master_send(c, adc_head_6, 2);
+ i2c_master_send(c, pll_bw_nom, 2);
+
+ tda8290_i2c_bridge(c, 1);
+ if (t->tda827x_ver != 0)
+ tda827xa_tune(c, ifc, freq);
+ else
+ tda827x_tune(c, ifc, freq);
+ /* adjust headroom resp. gain */
+ i2c_master_send(c, &addr_adc_sat, 1);
+ i2c_master_recv(c, &adc_sat, 1);
+ i2c_master_send(c, &addr_agc_stat, 1);
+ i2c_master_recv(c, &agc_stat, 1);
+ i2c_master_send(c, &addr_pll_stat, 1);
+ i2c_master_recv(c, &pll_stat, 1);
+ if (pll_stat & 0x80)
+ tuner_dbg("tda8290 is locked, AGC: %d\n", agc_stat);
+ else
+ tuner_dbg("tda8290 not locked, no signal?\n");
+ if ((agc_stat > 115) || (!(pll_stat & 0x80) && (adc_sat < 20))) {
+ tuner_dbg("adjust gain, step 1. Agc: %d, ADC stat: %d, lock: %d\n",
+ agc_stat, adc_sat, pll_stat & 0x80);
+ i2c_master_send(c, gainset_2, 2);
+ msleep(100);
+ i2c_master_send(c, &addr_agc_stat, 1);
+ i2c_master_recv(c, &agc_stat, 1);
+ i2c_master_send(c, &addr_pll_stat, 1);
+ i2c_master_recv(c, &pll_stat, 1);
+ if ((agc_stat > 115) || !(pll_stat & 0x80)) {
+ tuner_dbg("adjust gain, step 2. Agc: %d, lock: %d\n",
+ agc_stat, pll_stat & 0x80);
+ if (t->tda827x_ver != 0)
+ tda827xa_agcf(c);
+ else
+ tda827x_agcf(c);
+ msleep(100);
+ i2c_master_send(c, &addr_agc_stat, 1);
+ i2c_master_recv(c, &agc_stat, 1);
+ i2c_master_send(c, &addr_pll_stat, 1);
+ i2c_master_recv(c, &pll_stat, 1);
+ if((agc_stat > 115) || !(pll_stat & 0x80)) {
+ tuner_dbg("adjust gain, step 3. Agc: %d\n", agc_stat);
+ i2c_master_send(c, adc_head_12, 2);
+ i2c_master_send(c, pll_bw_low, 2);
+ msleep(100);
+ }
+ }
+ }
+
+ /* l/ l' deadlock? */
+ if(t->tda8290_easy_mode & 0x60) {
+ i2c_master_send(c, &addr_adc_sat, 1);
+ i2c_master_recv(c, &adc_sat, 1);
+ i2c_master_send(c, &addr_pll_stat, 1);
+ i2c_master_recv(c, &pll_stat, 1);
+ if ((adc_sat > 20) || !(pll_stat & 0x80)) {
+ tuner_dbg("trying to resolve SECAM L deadlock\n");
+ i2c_master_send(c, agc_rst_on, 2);
+ msleep(40);
+ i2c_master_send(c, agc_rst_off, 2);
+ }
+ }
+
+ tda8290_i2c_bridge(c, 0);
+ i2c_master_send(c, if_agc_set, 2);
+ return 0;
+}
+
+
+/*---------------------------------------------------------------------*/
+
#define V4L2_STD_MN (V4L2_STD_PAL_M|V4L2_STD_PAL_N|V4L2_STD_PAL_Nc|V4L2_STD_NTSC)
#define V4L2_STD_B (V4L2_STD_PAL_B|V4L2_STD_PAL_B1|V4L2_STD_SECAM_B)
#define V4L2_STD_GH (V4L2_STD_PAL_G|V4L2_STD_PAL_H|V4L2_STD_SECAM_G|V4L2_STD_SECAM_H)
@@ -174,20 +408,37 @@ static void set_frequency(struct tuner *t, u16 ifc, unsigned int freq)
static void set_audio(struct tuner *t)
{
- t->i2c_easy_mode[0] = 0x01;
-
- if (t->std & V4L2_STD_MN)
- t->i2c_easy_mode[1] = 0x01;
- else if (t->std & V4L2_STD_B)
- t->i2c_easy_mode[1] = 0x02;
- else if (t->std & V4L2_STD_GH)
- t->i2c_easy_mode[1] = 0x04;
- else if (t->std & V4L2_STD_PAL_I)
- t->i2c_easy_mode[1] = 0x08;
- else if (t->std & V4L2_STD_DK)
- t->i2c_easy_mode[1] = 0x10;
- else if (t->std & V4L2_STD_SECAM_L)
- t->i2c_easy_mode[1] = 0x20;
+ char* mode;
+
+ t->tda827x_lpsel = 0;
+ mode = "xx";
+ if (t->std & V4L2_STD_MN) {
+ t->sgIF = 92;
+ t->tda8290_easy_mode = 0x01;
+ t->tda827x_lpsel = 1;
+ mode = "MN";
+ } else if (t->std & V4L2_STD_B) {
+ t->sgIF = 108;
+ t->tda8290_easy_mode = 0x02;
+ mode = "B";
+ } else if (t->std & V4L2_STD_GH) {
+ t->sgIF = 124;
+ t->tda8290_easy_mode = 0x04;
+ mode = "GH";
+ } else if (t->std & V4L2_STD_PAL_I) {
+ t->sgIF = 124;
+ t->tda8290_easy_mode = 0x08;
+ mode = "I";
+ } else if (t->std & V4L2_STD_DK) {
+ t->sgIF = 124;
+ t->tda8290_easy_mode = 0x10;
+ mode = "DK";
+ } else if (t->std & V4L2_STD_SECAM_L) {
+ t->sgIF = 124;
+ t->tda8290_easy_mode = 0x20;
+ mode = "L";
+ }
+ tuner_dbg("setting tda8290 to system %s\n", mode);
}
static void set_tv_freq(struct i2c_client *c, unsigned int freq)
@@ -195,15 +446,13 @@ static void set_tv_freq(struct i2c_client *c, unsigned int freq)
struct tuner *t = i2c_get_clientdata(c);
set_audio(t);
- set_frequency(t, 864, freq);
- tda8290_tune(c);
+ tda8290_tune(c, t->sgIF, freq);
}
static void set_radio_freq(struct i2c_client *c, unsigned int freq)
{
- struct tuner *t = i2c_get_clientdata(c);
- set_frequency(t, 704, freq);
- tda8290_tune(c);
+ /* if frequency is 5.5 MHz */
+ tda8290_tune(c, 88, freq);
}
static int has_signal(struct i2c_client *c)
@@ -216,27 +465,145 @@ static int has_signal(struct i2c_client *c)
return (afc & 0x80)? 65535:0;
}
+/*---------------------------------------------------------------------*/
+
static void standby(struct i2c_client *c)
{
- i2c_transfer(c->adapter, i2c_msg_standby, ARRAY_SIZE(i2c_msg_standby));
+ struct tuner *t = i2c_get_clientdata(c);
+ unsigned char cb1[] = { 0x30, 0xD0 };
+ unsigned char tda8290_standby[] = { 0x00, 0x02 };
+ struct i2c_msg msg = {.addr = t->tda827x_addr, .flags=0, .buf=cb1, .len = 2};
+
+ tda8290_i2c_bridge(c, 1);
+ if (t->tda827x_ver != 0)
+ cb1[1] = 0x90;
+ i2c_transfer(c->adapter, &msg, 1);
+ tda8290_i2c_bridge(c, 0);
+ i2c_master_send(c, tda8290_standby, 2);
}
-int tda8290_init(struct i2c_client *c)
+
+static void tda8290_init_if(struct i2c_client *c)
+{
+ unsigned char set_VS[] = { 0x30, 0x6F };
+ unsigned char set_GP01_CF[] = { 0x20, 0x0B };
+
+ i2c_master_send(c, set_VS, 2);
+ i2c_master_send(c, set_GP01_CF, 2);
+}
+
+static void tda8290_init_tuner(struct i2c_client *c)
{
struct tuner *t = i2c_get_clientdata(c);
+ unsigned char tda8275_init[] = { 0x00, 0x00, 0x00, 0x40, 0xdC, 0x04, 0xAf,
+ 0x3F, 0x2A, 0x04, 0xFF, 0x00, 0x00, 0x40 };
+ unsigned char tda8275a_init[] = { 0x00, 0x00, 0x00, 0x00, 0xdC, 0x05, 0x8b,
+ 0x0c, 0x04, 0x20, 0xFF, 0x00, 0x00, 0x4b };
+ struct i2c_msg msg = {.addr = t->tda827x_addr, .flags=0,
+ .buf=tda8275_init, .len = 14};
+ if (t->tda827x_ver != 0)
+ msg.buf = tda8275a_init;
+
+ tda8290_i2c_bridge(c, 1);
+ i2c_transfer(c->adapter, &msg, 1);
+ tda8290_i2c_bridge(c, 0);
+}
- strlcpy(c->name, "tda8290+75", sizeof(c->name));
+/*---------------------------------------------------------------------*/
+
+int tda8290_init(struct i2c_client *c)
+{
+ struct tuner *t = i2c_get_clientdata(c);
+ u8 data;
+ int i, ret, tuners_found;
+ u32 tuner_addrs;
+ struct i2c_msg msg = {.flags=I2C_M_RD, .buf=&data, .len = 1};
+
+ tda8290_i2c_bridge(c, 1);
+ /* probe for tuner chip */
+ tuners_found = 0;
+ tuner_addrs = 0;
+ for (i=0x60; i<= 0x63; i++) {
+ msg.addr = i;
+ ret = i2c_transfer(c->adapter, &msg, 1);
+ if (ret == 1) {
+ tuners_found++;
+ tuner_addrs = (tuner_addrs << 8) + i;
+ }
+ }
+ /* if there is more than one tuner, we expect the right one is
+ behind the bridge and we choose the highest address that doesn't
+ give a response now
+ */
+ tda8290_i2c_bridge(c, 0);
+ if(tuners_found > 1)
+ for (i = 0; i < tuners_found; i++) {
+ msg.addr = tuner_addrs & 0xff;
+ ret = i2c_transfer(c->adapter, &msg, 1);
+ if(ret == 1)
+ tuner_addrs = tuner_addrs >> 8;
+ else
+ break;
+ }
+ if (tuner_addrs == 0) {
+ tuner_addrs = 0x61;
+ tuner_info ("could not clearly identify tuner address, defaulting to %x\n",
+ tuner_addrs);
+ } else {
+ tuner_addrs = tuner_addrs & 0xff;
+ tuner_info ("setting tuner address to %x\n", tuner_addrs);
+ }
+ t->tda827x_addr = tuner_addrs;
+ msg.addr = tuner_addrs;
+
+ tda8290_i2c_bridge(c, 1);
+ ret = i2c_transfer(c->adapter, &msg, 1);
+ if( ret != 1)
+ tuner_warn ("TDA827x access failed!\n");
+ if ((data & 0x3c) == 0) {
+ strlcpy(c->name, "tda8290+75", sizeof(c->name));
+ t->tda827x_ver = 0;
+ } else {
+ strlcpy(c->name, "tda8290+75a", sizeof(c->name));
+ t->tda827x_ver = 2;
+ }
tuner_info("tuner: type set to %s\n", c->name);
+
t->tv_freq = set_tv_freq;
t->radio_freq = set_radio_freq;
t->has_signal = has_signal;
t->standby = standby;
+ t->tda827x_lpsel = 0;
- i2c_master_send(c, i2c_enable_bridge, ARRAY_SIZE(i2c_enable_bridge));
- i2c_transfer(c->adapter, i2c_msg_init, ARRAY_SIZE(i2c_msg_init));
+ tda8290_init_tuner(c);
+ tda8290_init_if(c);
return 0;
}
+int tda8290_probe(struct i2c_client *c)
+{
+ unsigned char soft_reset[] = { 0x00, 0x00 };
+ unsigned char easy_mode_b[] = { 0x01, 0x02 };
+ unsigned char easy_mode_g[] = { 0x01, 0x04 };
+ unsigned char addr_dto_lsb = 0x07;
+ unsigned char data;
+
+ i2c_master_send(c, easy_mode_b, 2);
+ i2c_master_send(c, soft_reset, 2);
+ i2c_master_send(c, &addr_dto_lsb, 1);
+ i2c_master_recv(c, &data, 1);
+ if (data == 0) {
+ i2c_master_send(c, easy_mode_g, 2);
+ i2c_master_send(c, soft_reset, 2);
+ i2c_master_send(c, &addr_dto_lsb, 1);
+ i2c_master_recv(c, &data, 1);
+ if (data == 0x7b) {
+ return 0;
+ }
+ }
+ return -1;
+}
+
/*
* Overrides for Emacs so that we follow Linus's tabbing style.
* ---------------------------------------------------------------------------
diff --git a/drivers/media/video/tda9875.c b/drivers/media/video/tda9875.c
index 7e3dcdb262b0..a5e37dc91f39 100644
--- a/drivers/media/video/tda9875.c
+++ b/drivers/media/video/tda9875.c
@@ -32,7 +32,6 @@
#include "bttv.h"
#include <media/audiochip.h>
-#include <media/id.h>
static int debug; /* insmod parameter */
module_param(debug, int, S_IRUGO | S_IWUSR);
@@ -126,20 +125,20 @@ static int tda9875_write(struct i2c_client *client, int subaddr, unsigned char v
static int i2c_read_register(struct i2c_adapter *adap, int addr, int reg)
{
- unsigned char write[1];
- unsigned char read[1];
- struct i2c_msg msgs[2] = {
- { addr, 0, 1, write },
- { addr, I2C_M_RD, 1, read }
- };
- write[0] = reg;
-
- if (2 != i2c_transfer(adap,msgs,2)) {
- printk(KERN_WARNING "tda9875: I/O error (read2)\n");
- return -1;
- }
- dprintk("tda9875: chip_read2: reg%d=0x%x\n",reg,read[0]);
- return read[0];
+ unsigned char write[1];
+ unsigned char read[1];
+ struct i2c_msg msgs[2] = {
+ { addr, 0, 1, write },
+ { addr, I2C_M_RD, 1, read }
+ };
+ write[0] = reg;
+
+ if (2 != i2c_transfer(adap,msgs,2)) {
+ printk(KERN_WARNING "tda9875: I/O error (read2)\n");
+ return -1;
+ }
+ dprintk("tda9875: chip_read2: reg%d=0x%x\n",reg,read[0]);
+ return read[0];
}
static void tda9875_set(struct i2c_client *client)
@@ -184,7 +183,7 @@ static void do_tda9875_init(struct i2c_client *client)
tda9875_write(client, TDA9875_DACOS, 0x02 ); /* sig DAC i/o(in:nicam)*/
tda9875_write(client, TDA9875_ADCIS, 0x6f ); /* sig ADC input(in:mono)*/
tda9875_write(client, TDA9875_LOSR, 0x00 ); /* line out (in:mono)*/
- tda9875_write(client, TDA9875_AER, 0x00 ); /*06 Effect (AVL+PSEUDO) */
+ tda9875_write(client, TDA9875_AER, 0x00 ); /*06 Effect (AVL+PSEUDO) */
tda9875_write(client, TDA9875_MCS, 0x44 ); /* Main ch select (DAC) */
tda9875_write(client, TDA9875_MVL, 0x03 ); /* Vol Main left 10dB */
tda9875_write(client, TDA9875_MVR, 0x03 ); /* Vol Main right 10dB*/
@@ -200,7 +199,7 @@ static void do_tda9875_init(struct i2c_client *client)
t->mode=AUDIO_UNMUTE;
t->lvol=t->rvol =0; /* 0dB */
- t->bass=0; /* 0dB */
+ t->bass=0; /* 0dB */
t->treble=0; /* 0dB */
tda9875_set(client);
@@ -239,9 +238,9 @@ static int tda9875_attach(struct i2c_adapter *adap, int addr, int kind)
memset(t,0,sizeof *t);
client = &t->c;
- memcpy(client,&client_template,sizeof(struct i2c_client));
- client->adapter = adap;
- client->addr = addr;
+ memcpy(client,&client_template,sizeof(struct i2c_client));
+ client->adapter = adap;
+ client->addr = addr;
i2c_set_clientdata(client, t);
if(!tda9875_checkit(adap,addr)) {
@@ -287,7 +286,7 @@ static int tda9875_command(struct i2c_client *client,
dprintk("In tda9875_command...\n");
switch (cmd) {
- /* --- v4l ioctls --- */
+ /* --- v4l ioctls --- */
/* take care: bttv does userspace copying, we'll get a
kernel pointer here... */
case VIDIOCGAUDIO:
@@ -355,7 +354,7 @@ static int tda9875_command(struct i2c_client *client,
//printk("tda9875 bal:%04x vol:%04x bass:%04x treble:%04x\n",va->balance,va->volume,va->bass,va->treble);
- tda9875_set(client);
+ tda9875_set(client);
break;
@@ -374,18 +373,18 @@ static int tda9875_command(struct i2c_client *client,
static struct i2c_driver driver = {
.owner = THIS_MODULE,
- .name = "i2c tda9875 driver",
- .id = I2C_DRIVERID_TDA9875,
- .flags = I2C_DF_NOTIFY,
+ .name = "i2c tda9875 driver",
+ .id = I2C_DRIVERID_TDA9875,
+ .flags = I2C_DF_NOTIFY,
.attach_adapter = tda9875_probe,
- .detach_client = tda9875_detach,
- .command = tda9875_command,
+ .detach_client = tda9875_detach,
+ .command = tda9875_command,
};
static struct i2c_client client_template =
{
- .name = "tda9875",
- .driver = &driver,
+ .name = "tda9875",
+ .driver = &driver,
};
static int __init tda9875_init(void)
diff --git a/drivers/media/video/tda9887.c b/drivers/media/video/tda9887.c
index 0456dda2624d..4249127c0a1d 100644
--- a/drivers/media/video/tda9887.c
+++ b/drivers/media/video/tda9887.c
@@ -11,7 +11,6 @@
#include <media/audiochip.h>
#include <media/tuner.h>
-#include <media/id.h>
/* Chips:
TDA9885 (PAL, NTSC)
@@ -44,8 +43,13 @@ MODULE_LICENSE("GPL");
/* ---------------------------------------------------------------------- */
#define UNSET (-1U)
-#define PREFIX "tda9885/6/7: "
-#define dprintk if (debug) printk
+#define tda9887_info(fmt, arg...) do {\
+ printk(KERN_INFO "%s %d-%04x: " fmt, t->client.name, \
+ i2c_adapter_id(t->client.adapter), t->client.addr , ##arg); } while (0)
+#define tda9887_dbg(fmt, arg...) do {\
+ if (debug) \
+ printk(KERN_INFO "%s %d-%04x: " fmt, t->client.name, \
+ i2c_adapter_id(t->client.adapter), t->client.addr , ##arg); } while (0)
struct tda9887 {
struct i2c_client client;
@@ -55,6 +59,7 @@ struct tda9887 {
unsigned int pinnacle_id;
unsigned int using_v4l2;
unsigned int radio_mode;
+ unsigned char data[4];
};
struct tvnorm {
@@ -180,7 +185,8 @@ static struct tvnorm tvnorms[] = {
.name = "SECAM-L",
.b = ( cPositiveAmTV |
cQSS ),
- .e = ( cAudioIF_6_5 |
+ .e = ( cGating_36 |
+ cAudioIF_6_5 |
cVideoIF_38_90 ),
},{
.std = V4L2_STD_SECAM_DK,
@@ -236,7 +242,7 @@ static struct tvnorm radio_mono = {
/* ---------------------------------------------------------------------- */
-static void dump_read_message(unsigned char *buf)
+static void dump_read_message(struct tda9887 *t, unsigned char *buf)
{
static char *afc[16] = {
"- 12.5 kHz",
@@ -256,15 +262,15 @@ static void dump_read_message(unsigned char *buf)
"+ 37.5 kHz",
"+ 12.5 kHz",
};
- printk(PREFIX "read: 0x%2x\n", buf[0]);
- printk(" after power on : %s\n", (buf[0] & 0x01) ? "yes" : "no");
- printk(" afc : %s\n", afc[(buf[0] >> 1) & 0x0f]);
- printk(" fmif level : %s\n", (buf[0] & 0x20) ? "high" : "low");
- printk(" afc window : %s\n", (buf[0] & 0x40) ? "in" : "out");
- printk(" vfi level : %s\n", (buf[0] & 0x80) ? "high" : "low");
+ tda9887_info("read: 0x%2x\n", buf[0]);
+ tda9887_info(" after power on : %s\n", (buf[0] & 0x01) ? "yes" : "no");
+ tda9887_info(" afc : %s\n", afc[(buf[0] >> 1) & 0x0f]);
+ tda9887_info(" fmif level : %s\n", (buf[0] & 0x20) ? "high" : "low");
+ tda9887_info(" afc window : %s\n", (buf[0] & 0x40) ? "in" : "out");
+ tda9887_info(" vfi level : %s\n", (buf[0] & 0x80) ? "high" : "low");
}
-static void dump_write_message(unsigned char *buf)
+static void dump_write_message(struct tda9887 *t, unsigned char *buf)
{
static char *sound[4] = {
"AM/TV",
@@ -304,58 +310,58 @@ static void dump_write_message(unsigned char *buf)
"44 MHz",
};
- printk(PREFIX "write: byte B 0x%02x\n",buf[1]);
- printk(" B0 video mode : %s\n",
+ tda9887_info("write: byte B 0x%02x\n",buf[1]);
+ tda9887_info(" B0 video mode : %s\n",
(buf[1] & 0x01) ? "video trap" : "sound trap");
- printk(" B1 auto mute fm : %s\n",
+ tda9887_info(" B1 auto mute fm : %s\n",
(buf[1] & 0x02) ? "yes" : "no");
- printk(" B2 carrier mode : %s\n",
+ tda9887_info(" B2 carrier mode : %s\n",
(buf[1] & 0x04) ? "QSS" : "Intercarrier");
- printk(" B3-4 tv sound/radio : %s\n",
+ tda9887_info(" B3-4 tv sound/radio : %s\n",
sound[(buf[1] & 0x18) >> 3]);
- printk(" B5 force mute audio: %s\n",
+ tda9887_info(" B5 force mute audio: %s\n",
(buf[1] & 0x20) ? "yes" : "no");
- printk(" B6 output port 1 : %s\n",
+ tda9887_info(" B6 output port 1 : %s\n",
(buf[1] & 0x40) ? "high (inactive)" : "low (active)");
- printk(" B7 output port 2 : %s\n",
+ tda9887_info(" B7 output port 2 : %s\n",
(buf[1] & 0x80) ? "high (inactive)" : "low (active)");
- printk(PREFIX "write: byte C 0x%02x\n",buf[2]);
- printk(" C0-4 top adjustment : %s dB\n", adjust[buf[2] & 0x1f]);
- printk(" C5-6 de-emphasis : %s\n", deemph[(buf[2] & 0x60) >> 5]);
- printk(" C7 audio gain : %s\n",
+ tda9887_info("write: byte C 0x%02x\n",buf[2]);
+ tda9887_info(" C0-4 top adjustment : %s dB\n", adjust[buf[2] & 0x1f]);
+ tda9887_info(" C5-6 de-emphasis : %s\n", deemph[(buf[2] & 0x60) >> 5]);
+ tda9887_info(" C7 audio gain : %s\n",
(buf[2] & 0x80) ? "-6" : "0");
- printk(PREFIX "write: byte E 0x%02x\n",buf[3]);
- printk(" E0-1 sound carrier : %s\n",
+ tda9887_info("write: byte E 0x%02x\n",buf[3]);
+ tda9887_info(" E0-1 sound carrier : %s\n",
carrier[(buf[3] & 0x03)]);
- printk(" E6 l pll ganting : %s\n",
+ tda9887_info(" E6 l pll gating : %s\n",
(buf[3] & 0x40) ? "36" : "13");
if (buf[1] & 0x08) {
/* radio */
- printk(" E2-4 video if : %s\n",
+ tda9887_info(" E2-4 video if : %s\n",
rif[(buf[3] & 0x0c) >> 2]);
- printk(" E7 vif agc output : %s\n",
+ tda9887_info(" E7 vif agc output : %s\n",
(buf[3] & 0x80)
? ((buf[3] & 0x10) ? "fm-agc radio" : "sif-agc radio")
: "fm radio carrier afc");
} else {
/* video */
- printk(" E2-4 video if : %s\n",
+ tda9887_info(" E2-4 video if : %s\n",
vif[(buf[3] & 0x1c) >> 2]);
- printk(" E5 tuner gain : %s\n",
+ tda9887_info(" E5 tuner gain : %s\n",
(buf[3] & 0x80)
? ((buf[3] & 0x20) ? "external" : "normal")
: ((buf[3] & 0x20) ? "minimum" : "normal"));
- printk(" E7 vif agc output : %s\n",
+ tda9887_info(" E7 vif agc output : %s\n",
(buf[3] & 0x80)
? ((buf[3] & 0x20)
? "pin3 port, pin22 vif agc out"
: "pin22 port, pin3 vif acg ext in")
: "pin3+pin22 port");
}
- printk("--\n");
+ tda9887_info("--\n");
}
/* ---------------------------------------------------------------------- */
@@ -379,11 +385,11 @@ static int tda9887_set_tvnorm(struct tda9887 *t, char *buf)
}
}
if (NULL == norm) {
- dprintk(PREFIX "Unsupported tvnorm entry - audio muted\n");
+ tda9887_dbg("Unsupported tvnorm entry - audio muted\n");
return -1;
}
- dprintk(PREFIX "configure for: %s\n",norm->name);
+ tda9887_dbg("configure for: %s\n",norm->name);
buf[1] = norm->b;
buf[2] = norm->c;
buf[3] = norm->e;
@@ -458,6 +464,8 @@ static int tda9887_set_config(struct tda9887 *t, char *buf)
break;
}
}
+ if ((t->config & TDA9887_INTERCARRIER_NTSC) && (t->std & V4L2_STD_NTSC))
+ buf[1] &= ~cQSS;
return 0;
}
@@ -475,11 +483,11 @@ static int tda9887_set_pinnacle(struct tda9887 *t, char *buf)
}
}
if (t->std & V4L2_STD_525_60) {
- if ((5 == t->pinnacle_id) || (6 == t->pinnacle_id)) {
+ if ((5 == t->pinnacle_id) || (6 == t->pinnacle_id)) {
bCarrierMode = cIntercarrier;
} else {
bCarrierMode = cQSS;
- }
+ }
}
if (bCarrierMode != UNSET) {
@@ -505,26 +513,26 @@ static int tda9887_fixup_std(struct tda9887 *t)
case 'B':
case 'g':
case 'G':
- dprintk(PREFIX "insmod fixup: PAL => PAL-BG\n");
+ tda9887_dbg("insmod fixup: PAL => PAL-BG\n");
t->std = V4L2_STD_PAL_BG;
break;
case 'i':
case 'I':
- dprintk(PREFIX "insmod fixup: PAL => PAL-I\n");
+ tda9887_dbg("insmod fixup: PAL => PAL-I\n");
t->std = V4L2_STD_PAL_I;
break;
case 'd':
case 'D':
case 'k':
case 'K':
- dprintk(PREFIX "insmod fixup: PAL => PAL-DK\n");
+ tda9887_dbg("insmod fixup: PAL => PAL-DK\n");
t->std = V4L2_STD_PAL_DK;
break;
case '-':
/* default parameter, do nothing */
break;
default:
- printk(PREFIX "pal= argument not recognised\n");
+ tda9887_info("pal= argument not recognised\n");
break;
}
}
@@ -534,19 +542,19 @@ static int tda9887_fixup_std(struct tda9887 *t)
case 'D':
case 'k':
case 'K':
- dprintk(PREFIX "insmod fixup: SECAM => SECAM-DK\n");
+ tda9887_dbg("insmod fixup: SECAM => SECAM-DK\n");
t->std = V4L2_STD_SECAM_DK;
break;
case 'l':
case 'L':
- dprintk(PREFIX "insmod fixup: SECAM => SECAM-L\n");
+ tda9887_dbg("insmod fixup: SECAM => SECAM-L\n");
t->std = V4L2_STD_SECAM_L;
break;
case '-':
/* default parameter, do nothing */
break;
default:
- printk(PREFIX "secam= argument not recognised\n");
+ tda9887_info("secam= argument not recognised\n");
break;
}
}
@@ -559,41 +567,40 @@ static int tda9887_status(struct tda9887 *t)
int rc;
memset(buf,0,sizeof(buf));
- if (1 != (rc = i2c_master_recv(&t->client,buf,1)))
- printk(PREFIX "i2c i/o error: rc == %d (should be 1)\n",rc);
- dump_read_message(buf);
+ if (1 != (rc = i2c_master_recv(&t->client,buf,1)))
+ tda9887_info("i2c i/o error: rc == %d (should be 1)\n",rc);
+ dump_read_message(t, buf);
return 0;
}
static int tda9887_configure(struct tda9887 *t)
{
- unsigned char buf[4];
int rc;
- memset(buf,0,sizeof(buf));
- tda9887_set_tvnorm(t,buf);
+ memset(t->data,0,sizeof(t->data));
+ tda9887_set_tvnorm(t,t->data);
- buf[1] |= cOutputPort1Inactive;
- buf[1] |= cOutputPort2Inactive;
+ t->data[1] |= cOutputPort1Inactive;
+ t->data[1] |= cOutputPort2Inactive;
if (UNSET != t->pinnacle_id) {
- tda9887_set_pinnacle(t,buf);
+ tda9887_set_pinnacle(t,t->data);
}
- tda9887_set_config(t,buf);
- tda9887_set_insmod(t,buf);
+ tda9887_set_config(t,t->data);
+ tda9887_set_insmod(t,t->data);
if (t->mode == T_STANDBY) {
- buf[1] |= cForcedMuteAudioON;
+ t->data[1] |= cForcedMuteAudioON;
}
- dprintk(PREFIX "writing: b=0x%02x c=0x%02x e=0x%02x\n",
- buf[1],buf[2],buf[3]);
+ tda9887_dbg("writing: b=0x%02x c=0x%02x e=0x%02x\n",
+ t->data[1],t->data[2],t->data[3]);
if (debug > 1)
- dump_write_message(buf);
+ dump_write_message(t, t->data);
- if (4 != (rc = i2c_master_send(&t->client,buf,4)))
- printk(PREFIX "i2c i/o error: rc == %d (should be 4)\n",rc);
+ if (4 != (rc = i2c_master_send(&t->client,t->data,4)))
+ tda9887_info("i2c i/o error: rc == %d (should be 4)\n",rc);
if (debug > 2) {
msleep_interruptible(1000);
@@ -608,13 +615,11 @@ static int tda9887_attach(struct i2c_adapter *adap, int addr, int kind)
{
struct tda9887 *t;
- client_template.adapter = adap;
- client_template.addr = addr;
-
- printk(PREFIX "chip found @ 0x%x\n", addr<<1);
+ client_template.adapter = adap;
+ client_template.addr = addr;
- if (NULL == (t = kmalloc(sizeof(*t), GFP_KERNEL)))
- return -ENOMEM;
+ if (NULL == (t = kmalloc(sizeof(*t), GFP_KERNEL)))
+ return -ENOMEM;
memset(t,0,sizeof(*t));
t->client = client_template;
@@ -622,6 +627,8 @@ static int tda9887_attach(struct i2c_adapter *adap, int addr, int kind)
t->pinnacle_id = UNSET;
t->radio_mode = V4L2_TUNER_MODE_STEREO;
+ tda9887_info("chip found @ 0x%x (%s)\n", addr<<1, adap->name);
+
i2c_set_clientdata(&t->client, t);
i2c_attach_client(&t->client);
@@ -655,18 +662,18 @@ static int tda9887_detach(struct i2c_client *client)
}
#define SWITCH_V4L2 if (!t->using_v4l2 && debug) \
- printk(PREFIX "switching to v4l2\n"); \
- t->using_v4l2 = 1;
+ tda9887_info("switching to v4l2\n"); \
+ t->using_v4l2 = 1;
#define CHECK_V4L2 if (t->using_v4l2) { if (debug) \
- printk(PREFIX "ignore v4l1 call\n"); \
- return 0; }
+ tda9887_info("ignore v4l1 call\n"); \
+ return 0; }
static int
tda9887_command(struct i2c_client *client, unsigned int cmd, void *arg)
{
struct tda9887 *t = i2c_get_clientdata(client);
- switch (cmd) {
+ switch (cmd) {
/* --- configuration --- */
case AUDC_SET_RADIO:
@@ -777,6 +784,11 @@ tda9887_command(struct i2c_client *client, unsigned int cmd, void *arg)
}
break;
}
+ case VIDIOC_LOG_STATUS:
+ {
+ tda9887_info("Data bytes: b=%02x c=%02x e=%02x\n", t->data[1], t->data[2], t->data[3]);
+ break;
+ }
default:
/* nothing */
break;
@@ -784,18 +796,21 @@ tda9887_command(struct i2c_client *client, unsigned int cmd, void *arg)
return 0;
}
-static int tda9887_suspend(struct device * dev, pm_message_t state, u32 level)
+static int tda9887_suspend(struct device * dev, pm_message_t state)
{
- dprintk("tda9887: suspend\n");
+ struct i2c_client *c = container_of(dev, struct i2c_client, dev);
+ struct tda9887 *t = i2c_get_clientdata(c);
+
+ tda9887_dbg("suspend\n");
return 0;
}
-static int tda9887_resume(struct device * dev, u32 level)
+static int tda9887_resume(struct device * dev)
{
struct i2c_client *c = container_of(dev, struct i2c_client, dev);
struct tda9887 *t = i2c_get_clientdata(c);
- dprintk("tda9887: resume\n");
+ tda9887_dbg("resume\n");
tda9887_configure(t);
return 0;
}
diff --git a/drivers/media/video/tea5767.c b/drivers/media/video/tea5767.c
index 38bf50943798..a9375ef05de1 100644
--- a/drivers/media/video/tea5767.c
+++ b/drivers/media/video/tea5767.c
@@ -117,10 +117,10 @@
#define TEA5767_RESERVED_MASK 0xff
enum tea5767_xtal_freq {
- TEA5767_LOW_LO_32768 = 0,
- TEA5767_HIGH_LO_32768 = 1,
- TEA5767_LOW_LO_13MHz = 2,
- TEA5767_HIGH_LO_13MHz = 3,
+ TEA5767_LOW_LO_32768 = 0,
+ TEA5767_HIGH_LO_32768 = 1,
+ TEA5767_LOW_LO_13MHz = 2,
+ TEA5767_HIGH_LO_13MHz = 3,
};
diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c
index 05572020af4d..73c4041c35d7 100644
--- a/drivers/media/video/tuner-core.c
+++ b/drivers/media/video/tuner-core.c
@@ -28,7 +28,7 @@
/* standard i2c insmod options */
static unsigned short normal_i2c[] = {
- 0x4b, /* tda8290 */
+ 0x42, 0x43, 0x4a, 0x4b, /* tda8290 */
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
I2C_CLIENT_END
@@ -189,6 +189,13 @@ static void set_type(struct i2c_client *c, unsigned int type,
i2c_master_send(c, buffer, 4);
default_tuner_init(c);
break;
+ case TUNER_PHILIPS_TD1316:
+ buffer[0] = 0x0b;
+ buffer[1] = 0xdc;
+ buffer[2] = 0x86;
+ buffer[3] = 0xa4;
+ i2c_master_send(c,buffer,4);
+ default_tuner_init(c);
default:
default_tuner_init(c);
break;
@@ -215,9 +222,9 @@ static void set_addr(struct i2c_client *c, struct tuner_setup *tun_setup)
{
struct tuner *t = i2c_get_clientdata(c);
- if ((tun_setup->addr == ADDR_UNSET &&
+ if ( t->type == UNSET && ((tun_setup->addr == ADDR_UNSET &&
(t->mode_mask & tun_setup->mode_mask)) ||
- tun_setup->addr == c->addr) {
+ tun_setup->addr == c->addr)) {
set_type(c, tun_setup->type, tun_setup->mode_mask);
}
}
@@ -341,23 +348,33 @@ static int tuner_attach(struct i2c_adapter *adap, int addr, int kind)
t->audmode = V4L2_TUNER_MODE_STEREO;
t->mode_mask = T_UNINITIALIZED;
-
- tuner_info("chip found @ 0x%x (%s)\n", addr << 1, adap->name);
-
if (show_i2c) {
unsigned char buffer[16];
int i,rc;
memset(buffer, 0, sizeof(buffer));
rc = i2c_master_recv(&t->i2c, buffer, sizeof(buffer));
- printk("tuner-%04x I2C RECV = ",addr);
+ tuner_info("I2C RECV = ");
for (i=0;i<rc;i++)
printk("%02x ",buffer[i]);
printk("\n");
}
/* TEA5767 autodetection code - only for addr = 0xc0 */
if (!no_autodetect) {
- if (addr == 0x60) {
+ switch (addr) {
+ case 0x42:
+ case 0x43:
+ case 0x4a:
+ case 0x4b:
+ /* If chip is not tda8290, don't register.
+ since it can be tda9887*/
+ if (tda8290_probe(&t->i2c) != 0) {
+ tuner_dbg("chip at addr %x is not a tda8290\n", addr);
+ kfree(t);
+ return 0;
+ }
+ break;
+ case 0x60:
if (tea5767_autodetection(&t->i2c) != EINVAL) {
t->type = TUNER_TEA5767;
t->mode_mask = T_RADIO;
@@ -365,10 +382,9 @@ static int tuner_attach(struct i2c_adapter *adap, int addr, int kind)
t->freq = 87.5 * 16; /* Sets freq to FM range */
default_mode_mask &= ~T_RADIO;
- i2c_attach_client (&t->i2c);
- set_type(&t->i2c,t->type, t->mode_mask);
- return 0;
+ goto register_client;
}
+ break;
}
}
@@ -381,6 +397,8 @@ static int tuner_attach(struct i2c_adapter *adap, int addr, int kind)
}
/* Should be just before return */
+register_client:
+ tuner_info("chip found @ 0x%x (%s)\n", addr << 1, adap->name);
i2c_attach_client (&t->i2c);
set_type (&t->i2c,t->type, t->mode_mask);
return 0;
@@ -425,23 +443,23 @@ static int tuner_detach(struct i2c_client *client)
static inline int set_mode(struct i2c_client *client, struct tuner *t, int mode, char *cmd)
{
- if (mode == t->mode)
- return 0;
-
- t->mode = mode;
-
- if (check_mode(t, cmd) == EINVAL) {
- t->mode = T_STANDBY;
- if (t->standby)
- t->standby (client);
- return EINVAL;
- }
- return 0;
+ if (mode == t->mode)
+ return 0;
+
+ t->mode = mode;
+
+ if (check_mode(t, cmd) == EINVAL) {
+ t->mode = T_STANDBY;
+ if (t->standby)
+ t->standby (client);
+ return EINVAL;
+ }
+ return 0;
}
#define switch_v4l2() if (!t->using_v4l2) \
- tuner_dbg("switching to v4l2\n"); \
- t->using_v4l2 = 1;
+ tuner_dbg("switching to v4l2\n"); \
+ t->using_v4l2 = 1;
static inline int check_v4l2(struct tuner *t)
{
@@ -479,8 +497,6 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
break;
}
case AUDC_CONFIG_PINNACLE:
- if (check_mode(t, "AUDC_CONFIG_PINNACLE") == EINVAL)
- return 0;
switch (*iarg) {
case 2:
tuner_dbg("pinnacle pal\n");
@@ -616,7 +632,7 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
switch_v4l2();
if (V4L2_TUNER_RADIO == f->type &&
V4L2_TUNER_RADIO != t->mode) {
- if (set_mode (client, t, f->type, "VIDIOC_S_FREQUENCY")
+ if (set_mode (client, t, f->type, "VIDIOC_S_FREQUENCY")
== EINVAL)
return 0;
}
@@ -688,7 +704,7 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
break;
}
default:
- tuner_dbg("Unimplemented IOCTL 0x%08x(dir=%d,tp=0x%02x,nr=%d,sz=%d)\n",
+ tuner_dbg("Unimplemented IOCTL 0x%08x(dir=%d,tp='%c',nr=%d,sz=%d)\n",
cmd, _IOC_DIR(cmd), _IOC_TYPE(cmd),
_IOC_NR(cmd), _IOC_SIZE(cmd));
break;
@@ -697,7 +713,7 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
return 0;
}
-static int tuner_suspend(struct device *dev, pm_message_t state, u32 level)
+static int tuner_suspend(struct device *dev, pm_message_t state)
{
struct i2c_client *c = container_of (dev, struct i2c_client, dev);
struct tuner *t = i2c_get_clientdata (c);
@@ -707,7 +723,7 @@ static int tuner_suspend(struct device *dev, pm_message_t state, u32 level)
return 0;
}
-static int tuner_resume(struct device *dev, u32 level)
+static int tuner_resume(struct device *dev)
{
struct i2c_client *c = container_of (dev, struct i2c_client, dev);
struct tuner *t = i2c_get_clientdata (c);
diff --git a/drivers/media/video/tuner-simple.c b/drivers/media/video/tuner-simple.c
index 8edd73abe1d8..d832205818f2 100644
--- a/drivers/media/video/tuner-simple.c
+++ b/drivers/media/video/tuner-simple.c
@@ -102,7 +102,7 @@ struct tunertype
*/
static struct tunertype tuners[] = {
/* 0-9 */
- { "Temic PAL (4002 FH5)", TEMIC, PAL,
+ { "Temic PAL (4002 FH5)", TEMIC, PAL,
16*140.25,16*463.25,0x02,0x04,0x01,0x8e,623},
{ "Philips PAL_I (FI1246 and compatibles)", Philips, PAL_I,
16*140.25,16*463.25,0xa0,0x90,0x30,0x8e,623},
@@ -118,41 +118,41 @@ static struct tunertype tuners[] = {
16*157.25,16*463.25,0x02,0x04,0x01,0x8e,732},
{ "Temic PAL_I (4062 FY5)", TEMIC, PAL_I,
16*170.00,16*450.00,0x02,0x04,0x01,0x8e,623},
- { "Temic NTSC (4036 FY5)", TEMIC, NTSC,
+ { "Temic NTSC (4036 FY5)", TEMIC, NTSC,
16*157.25,16*463.25,0xa0,0x90,0x30,0x8e,732},
- { "Alps HSBH1", TEMIC, NTSC,
+ { "Alps HSBH1", TEMIC, NTSC,
16*137.25,16*385.25,0x01,0x02,0x08,0x8e,732},
/* 10-19 */
- { "Alps TSBE1", TEMIC, PAL,
+ { "Alps TSBE1", TEMIC, PAL,
16*137.25,16*385.25,0x01,0x02,0x08,0x8e,732},
- { "Alps TSBB5", Alps, PAL_I, /* tested (UK UHF) with Modulartech MM205 */
+ { "Alps TSBB5", Alps, PAL_I, /* tested (UK UHF) with Modulartech MM205 */
16*133.25,16*351.25,0x01,0x02,0x08,0x8e,632},
- { "Alps TSBE5", Alps, PAL, /* untested - data sheet guess. Only IF differs. */
+ { "Alps TSBE5", Alps, PAL, /* untested - data sheet guess. Only IF differs. */
16*133.25,16*351.25,0x01,0x02,0x08,0x8e,622},
- { "Alps TSBC5", Alps, PAL, /* untested - data sheet guess. Only IF differs. */
+ { "Alps TSBC5", Alps, PAL, /* untested - data sheet guess. Only IF differs. */
16*133.25,16*351.25,0x01,0x02,0x08,0x8e,608},
{ "Temic PAL_BG (4006FH5)", TEMIC, PAL,
16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623},
- { "Alps TSCH6", Alps, NTSC,
- 16*137.25,16*385.25,0x14,0x12,0x11,0x8e,732},
- { "Temic PAL_DK (4016 FY5)", TEMIC, PAL,
- 16*168.25,16*456.25,0xa0,0x90,0x30,0x8e,623},
- { "Philips NTSC_M (MK2)", Philips, NTSC,
- 16*160.00,16*454.00,0xa0,0x90,0x30,0x8e,732},
- { "Temic PAL_I (4066 FY5)", TEMIC, PAL_I,
- 16*169.00, 16*454.00, 0xa0,0x90,0x30,0x8e,623},
- { "Temic PAL* auto (4006 FN5)", TEMIC, PAL,
- 16*169.00, 16*454.00, 0xa0,0x90,0x30,0x8e,623},
+ { "Alps TSCH6", Alps, NTSC,
+ 16*137.25,16*385.25,0x14,0x12,0x11,0x8e,732},
+ { "Temic PAL_DK (4016 FY5)", TEMIC, PAL,
+ 16*168.25,16*456.25,0xa0,0x90,0x30,0x8e,623},
+ { "Philips NTSC_M (MK2)", Philips, NTSC,
+ 16*160.00,16*454.00,0xa0,0x90,0x30,0x8e,732},
+ { "Temic PAL_I (4066 FY5)", TEMIC, PAL_I,
+ 16*169.00, 16*454.00, 0xa0,0x90,0x30,0x8e,623},
+ { "Temic PAL* auto (4006 FN5)", TEMIC, PAL,
+ 16*169.00, 16*454.00, 0xa0,0x90,0x30,0x8e,623},
/* 20-29 */
- { "Temic PAL_BG (4009 FR5) or PAL_I (4069 FR5)", TEMIC, PAL,
- 16*141.00, 16*464.00, 0xa0,0x90,0x30,0x8e,623},
- { "Temic NTSC (4039 FR5)", TEMIC, NTSC,
- 16*158.00, 16*453.00, 0xa0,0x90,0x30,0x8e,732},
- { "Temic PAL/SECAM multi (4046 FM5)", TEMIC, PAL,
- 16*169.00, 16*454.00, 0xa0,0x90,0x30,0x8e,623},
- { "Philips PAL_DK (FI1256 and compatibles)", Philips, PAL,
+ { "Temic PAL_BG (4009 FR5) or PAL_I (4069 FR5)", TEMIC, PAL,
+ 16*141.00, 16*464.00, 0xa0,0x90,0x30,0x8e,623},
+ { "Temic NTSC (4039 FR5)", TEMIC, NTSC,
+ 16*158.00, 16*453.00, 0xa0,0x90,0x30,0x8e,732},
+ { "Temic PAL/SECAM multi (4046 FM5)", TEMIC, PAL,
+ 16*169.00, 16*454.00, 0xa0,0x90,0x30,0x8e,623},
+ { "Philips PAL_DK (FI1256 and compatibles)", Philips, PAL,
16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623},
{ "Philips PAL/SECAM multi (FQ1216ME)", Philips, PAL,
16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623},
@@ -173,21 +173,21 @@ static struct tunertype tuners[] = {
{ "SHARP NTSC_JP (2U5JF5540)", SHARP, NTSC, /* 940=16*58.75 NTSC@Japan */
16*137.25,16*317.25,0x01,0x02,0x08,0x8e,940 },
{ "Samsung PAL TCPM9091PD27", Samsung, PAL, /* from sourceforge v3tv */
- 16*169,16*464,0xA0,0x90,0x30,0x8e,623},
+ 16*169,16*464,0xA0,0x90,0x30,0x8e,623},
{ "MT20xx universal", Microtune, PAL|NTSC,
/* see mt20xx.c for details */ },
{ "Temic PAL_BG (4106 FH5)", TEMIC, PAL,
- 16*141.00, 16*464.00, 0xa0,0x90,0x30,0x8e,623},
+ 16*141.00, 16*464.00, 0xa0,0x90,0x30,0x8e,623},
{ "Temic PAL_DK/SECAM_L (4012 FY5)", TEMIC, PAL,
- 16*140.25, 16*463.25, 0x02,0x04,0x01,0x8e,623},
+ 16*140.25, 16*463.25, 0x02,0x04,0x01,0x8e,623},
{ "Temic NTSC (4136 FY5)", TEMIC, NTSC,
- 16*158.00, 16*453.00, 0xa0,0x90,0x30,0x8e,732},
- { "LG PAL (newer TAPC series)", LGINNOTEK, PAL,
- 16*170.00, 16*450.00, 0x01,0x02,0x08,0x8e,623},
+ 16*158.00, 16*453.00, 0xa0,0x90,0x30,0x8e,732},
+ { "LG PAL (newer TAPC series)", LGINNOTEK, PAL,
+ 16*170.00, 16*450.00, 0x01,0x02,0x08,0x8e,623},
{ "Philips PAL/SECAM multi (FM1216ME MK3)", Philips, PAL,
- 16*160.00,16*442.00,0x01,0x02,0x04,0x8e,623 },
+ 16*158.00,16*442.00,0x01,0x02,0x04,0x8e,623 },
{ "LG NTSC (newer TAPC series)", LGINNOTEK, NTSC,
- 16*170.00, 16*450.00, 0x01,0x02,0x08,0x8e,732},
+ 16*170.00, 16*450.00, 0x01,0x02,0x08,0x8e,732},
/* 40-49 */
{ "HITACHI V7-J180AT", HITACHI, NTSC,
@@ -196,24 +196,24 @@ static struct tunertype tuners[] = {
16*140.25,16*463.25,0x01,0xc2,0xcf,0x8e,623},
{ "Philips 1236D ATSC/NTSC daul in", Philips, ATSC,
16*157.25,16*454.00,0xa0,0x90,0x30,0x8e,732},
- { "Philips NTSC MK3 (FM1236MK3 or FM1236/F)", Philips, NTSC,
- 16*160.00,16*442.00,0x01,0x02,0x04,0x8e,732},
- { "Philips 4 in 1 (ATI TV Wonder Pro/Conexant)", Philips, NTSC,
- 16*160.00,16*442.00,0x01,0x02,0x04,0x8e,732},
+ { "Philips NTSC MK3 (FM1236MK3 or FM1236/F)", Philips, NTSC,
+ 16*160.00,16*442.00,0x01,0x02,0x04,0x8e,732},
+ { "Philips 4 in 1 (ATI TV Wonder Pro/Conexant)", Philips, NTSC,
+ 16*160.00,16*442.00,0x01,0x02,0x04,0x8e,732},
{ "Microtune 4049 FM5", Microtune, PAL,
16*141.00,16*464.00,0xa0,0x90,0x30,0x8e,623},
{ "Panasonic VP27s/ENGE4324D", Panasonic, NTSC,
16*160.00,16*454.00,0x01,0x02,0x08,0xce,940},
- { "LG NTSC (TAPE series)", LGINNOTEK, NTSC,
- 16*160.00,16*442.00,0x01,0x02,0x04,0x8e,732 },
- { "Tenna TNF 8831 BGFF)", Philips, PAL,
- 16*161.25,16*463.25,0xa0,0x90,0x30,0x8e,623},
+ { "LG NTSC (TAPE series)", LGINNOTEK, NTSC,
+ 16*160.00,16*442.00,0x01,0x02,0x04,0x8e,732 },
+ { "Tenna TNF 8831 BGFF)", Philips, PAL,
+ 16*161.25,16*463.25,0xa0,0x90,0x30,0x8e,623},
{ "Microtune 4042 FI5 ATSC/NTSC dual in", Microtune, NTSC,
16*162.00,16*457.00,0xa2,0x94,0x31,0x8e,732},
/* 50-59 */
- { "TCL 2002N", TCL, NTSC,
- 16*172.00,16*448.00,0x01,0x02,0x08,0x8e,732},
+ { "TCL 2002N", TCL, NTSC,
+ 16*172.00,16*448.00,0x01,0x02,0x08,0x8e,732},
{ "Philips PAL/SECAM_D (FM 1256 I-H3)", Philips, PAL,
16*160.00,16*442.00,0x01,0x02,0x04,0x8e,623 },
{ "Thomson DDT 7610 (ATSC/NTSC)", THOMSON, ATSC,
@@ -222,8 +222,8 @@ static struct tunertype tuners[] = {
16*160.00,16*454.00,0x41,0x42,0x04,0x8e,940}, /* UHF band untested */
{ "tda8290+75", Philips, PAL|NTSC,
/* see tda8290.c for details */ },
- { "LG PAL (TAPE series)", LGINNOTEK, PAL,
- 16*170.00, 16*450.00, 0x01,0x02,0x08,0xce,623},
+ { "TCL 2002MB", TCL, PAL,
+ 16*170.00, 16*450.00, 0x01,0x02,0x08,0xce,623},
{ "Philips PAL/SECAM multi (FQ1216AME MK4)", Philips, PAL,
16*160.00,16*442.00,0x01,0x02,0x04,0xce,623 },
{ "Philips FQ1236A MK4", Philips, NTSC,
@@ -233,21 +233,25 @@ static struct tunertype tuners[] = {
{ "Ymec TVision TVF-5533MF", Philips, NTSC,
16*160.00,16*454.00,0x01,0x02,0x04,0x8e,732},
- /* 60-66 */
+ /* 60-68 */
{ "Thomson DDT 7611 (ATSC/NTSC)", THOMSON, ATSC,
16*157.25,16*454.00,0x39,0x3a,0x3c,0x8e,732},
{ "Tena TNF9533-D/IF/TNF9533-B/DF", Philips, PAL,
- 16*160.25,16*464.25,0x01,0x02,0x04,0x8e,623},
+ 16*160.25,16*464.25,0x01,0x02,0x04,0x8e,623},
{ "Philips TEA5767HN FM Radio", Philips, RADIO,
- /* see tea5767.c for details */},
+ /* see tea5767.c for details */},
{ "Philips FMD1216ME MK3 Hybrid Tuner", Philips, PAL,
16*160.00,16*442.00,0x51,0x52,0x54,0x86,623 },
{ "LG TDVS-H062F/TUA6034", LGINNOTEK, ATSC,
16*160.00,16*455.00,0x01,0x02,0x04,0x8e,732},
{ "Ymec TVF66T5-B/DFF", Philips, PAL,
- 16*160.25,16*464.25,0x01,0x02,0x08,0x8e,623},
- { "LG NTSC (TALN mini series)", LGINNOTEK, NTSC,
+ 16*160.25,16*464.25,0x01,0x02,0x08,0x8e,623},
+ { "LG NTSC (TALN mini series)", LGINNOTEK, NTSC,
16*137.25,16*373.25,0x01,0x02,0x08,0x8e,732 },
+ { "Philips TD1316 Hybrid Tuner", Philips, PAL,
+ 16*160.00,16*442.00,0xa1,0xa2,0xa4,0xc8,623 },
+ { "Philips TUV1236D ATSC/NTSC dual in", Philips, ATSC,
+ 16*157.25,16*454.00,0x01,0x02,0x04,0xce,732 },
};
unsigned const int tuner_count = ARRAY_SIZE(tuners);
@@ -277,7 +281,7 @@ static int tuner_stereo(struct i2c_client *c)
status = tuner_getstatus (c);
switch (t->type) {
- case TUNER_PHILIPS_FM1216ME_MK3:
+ case TUNER_PHILIPS_FM1216ME_MK3:
case TUNER_PHILIPS_FM1236_MK3:
case TUNER_PHILIPS_FM1256_IH3:
stereo = ((status & TUNER_SIGNAL) == TUNER_STEREO_MK3);
@@ -295,10 +299,10 @@ static int tuner_stereo(struct i2c_client *c)
static void default_set_tv_freq(struct i2c_client *c, unsigned int freq)
{
struct tuner *t = i2c_get_clientdata(c);
- u8 config;
+ u8 config, tuneraddr;
u16 div;
struct tunertype *tun;
- unsigned char buffer[4];
+ unsigned char buffer[4];
int rc;
tun = &tuners[t->type];
@@ -373,6 +377,31 @@ static void default_set_tv_freq(struct i2c_client *c, unsigned int freq)
/* Set the charge pump for fast tuning */
tun->config |= TUNER_CHARGE_PUMP;
break;
+
+ case TUNER_PHILIPS_TUV1236D:
+ /* 0x40 -> ATSC antenna input 1 */
+ /* 0x48 -> ATSC antenna input 2 */
+ /* 0x00 -> NTSC antenna input 1 */
+ /* 0x08 -> NTSC antenna input 2 */
+ buffer[0] = 0x14;
+ buffer[1] = 0x00;
+ buffer[2] = 0x17;
+ buffer[3] = 0x00;
+ config &= ~0x40;
+ if (t->std & V4L2_STD_ATSC) {
+ config |= 0x40;
+ buffer[1] = 0x04;
+ }
+ /* set to the correct mode (analog or digital) */
+ tuneraddr = c->addr;
+ c->addr = 0x0a;
+ if (2 != (rc = i2c_master_send(c,&buffer[0],2)))
+ tuner_warn("i2c i/o error: rc == %d (should be 2)\n",rc);
+ if (2 != (rc = i2c_master_send(c,&buffer[2],2)))
+ tuner_warn("i2c i/o error: rc == %d (should be 2)\n",rc);
+ c->addr = tuneraddr;
+ /* FIXME: input */
+ break;
}
/*
@@ -404,7 +433,7 @@ static void default_set_tv_freq(struct i2c_client *c, unsigned int freq)
tuner_dbg("tv 0x%02x 0x%02x 0x%02x 0x%02x\n",
buffer[0],buffer[1],buffer[2],buffer[3]);
- if (4 != (rc = i2c_master_send(c,buffer,4)))
+ if (4 != (rc = i2c_master_send(c,buffer,4)))
tuner_warn("i2c i/o error: rc == %d (should be 4)\n",rc);
if (t->type == TUNER_MICROTUNE_4042FI5) {
@@ -443,7 +472,7 @@ static void default_set_radio_freq(struct i2c_client *c, unsigned int freq)
{
struct tunertype *tun;
struct tuner *t = i2c_get_clientdata(c);
- unsigned char buffer[4];
+ unsigned char buffer[4];
unsigned div;
int rc;
@@ -476,13 +505,13 @@ static void default_set_radio_freq(struct i2c_client *c, unsigned int freq)
buffer[3] = 0xa4;
break;
}
- buffer[0] = (div>>8) & 0x7f;
- buffer[1] = div & 0xff;
+ buffer[0] = (div>>8) & 0x7f;
+ buffer[1] = div & 0xff;
tuner_dbg("radio 0x%02x 0x%02x 0x%02x 0x%02x\n",
buffer[0],buffer[1],buffer[2],buffer[3]);
- if (4 != (rc = i2c_master_send(c,buffer,4)))
+ if (4 != (rc = i2c_master_send(c,buffer,4)))
tuner_warn("i2c i/o error: rc == %d (should be 4)\n",rc);
}
diff --git a/drivers/media/video/tvaudio.c b/drivers/media/video/tvaudio.c
index 1c31ef52f863..c31bf28b73fe 100644
--- a/drivers/media/video/tvaudio.c
+++ b/drivers/media/video/tvaudio.c
@@ -31,7 +31,6 @@
#include <linux/smp_lock.h>
#include <media/audiochip.h>
-#include <media/id.h>
#include "tvaudio.h"
@@ -458,8 +457,8 @@ static void tda9840_setmode(struct CHIPSTATE *chip, int mode)
#define TDA9855_LOUD 1<<5 /* Loudness, 1==off */
#define TDA9855_SUR 1<<3 /* Surround / Subwoofer 1==.5(L-R) 0==.5(L+R) */
/* Bits 0 to 3 select various combinations
- * of line in and line out, only the
- * interesting ones are defined */
+ * of line in and line out, only the
+ * interesting ones are defined */
#define TDA9855_EXT 1<<2 /* Selects inputs LIR and LIL. Pins 41 & 12 */
#define TDA9855_INT 0 /* Selects inputs LOR and LOL. (internal) */
@@ -1028,7 +1027,7 @@ static int tda9874a_initialize(struct CHIPSTATE *chip)
#define TEA6300_TR 0x03 /* treble */
#define TEA6300_FA 0x04 /* fader control */
#define TEA6300_S 0x05 /* switch register */
- /* values for those registers: */
+ /* values for those registers: */
#define TEA6300_S_SA 0x01 /* stereo A input */
#define TEA6300_S_SB 0x02 /* stereo B */
#define TEA6300_S_SC 0x04 /* stereo C */
@@ -1042,7 +1041,7 @@ static int tda9874a_initialize(struct CHIPSTATE *chip)
#define TEA6320_BA 0x05 /* bass (0-4) */
#define TEA6320_TR 0x06 /* treble (0-4) */
#define TEA6320_S 0x07 /* switch register */
- /* values for those registers: */
+ /* values for those registers: */
#define TEA6320_S_SA 0x07 /* stereo A input */
#define TEA6320_S_SB 0x06 /* stereo B */
#define TEA6320_S_SC 0x05 /* stereo C */
@@ -1082,7 +1081,7 @@ static int tea6320_initialize(struct CHIPSTATE * chip)
#define TDA8425_BA 0x02 /* bass */
#define TDA8425_TR 0x03 /* treble */
#define TDA8425_S1 0x08 /* switch functions */
- /* values for those registers: */
+ /* values for those registers: */
#define TDA8425_S1_OFF 0xEE /* audio off (mute on) */
#define TDA8425_S1_CH1 0xCE /* audio channel 1 (mute off) - "linear stereo" mode */
#define TDA8425_S1_CH2 0xCF /* audio channel 2 (mute off) - "linear stereo" mode */
@@ -1148,7 +1147,7 @@ static void tda8425_setmode(struct CHIPSTATE *chip, int mode)
/* bit definition of the RESET register, I2C data. */
#define PIC16C54_MISC_RESET_REMOTE_CTL 0x01 /* bit 0, Reset to receive the key */
- /* code of remote controller */
+ /* code of remote controller */
#define PIC16C54_MISC_MTS_MAIN 0x02 /* bit 1 */
#define PIC16C54_MISC_MTS_SAP 0x04 /* bit 2 */
#define PIC16C54_MISC_MTS_BOTH 0x08 /* bit 3 */
@@ -1281,7 +1280,7 @@ static struct CHIPDESC chiplist[] = {
.setmode = tda9840_setmode,
.checkmode = generic_checkmode,
- .init = { 2, { TDA9840_TEST, TDA9840_TEST_INT1SN
+ .init = { 2, { TDA9840_TEST, TDA9840_TEST_INT1SN
/* ,TDA9840_SW, TDA9840_MONO */} }
},
{
@@ -1438,7 +1437,7 @@ static struct CHIPDESC chiplist[] = {
},
{
.name = "pic16c54 (PV951)",
- .id = I2C_DRIVERID_PIC16C54_PV951,
+ .id = I2C_DRIVERID_PIC16C54_PV9,
.insmodopt = &pic16c54,
.addr_lo = I2C_PIC16C54 >> 1,
.addr_hi = I2C_PIC16C54>> 1,
@@ -1467,7 +1466,7 @@ static struct CHIPDESC chiplist[] = {
.setmode = ta8874z_setmode,
.checkmode = generic_checkmode,
- .init = {2, { TA8874Z_MONO_SET, TA8874Z_SEPARATION_DEFAULT}},
+ .init = {2, { TA8874Z_MONO_SET, TA8874Z_SEPARATION_DEFAULT}},
},
{ .name = NULL } /* EOF */
};
@@ -1486,8 +1485,8 @@ static int chip_attach(struct i2c_adapter *adap, int addr, int kind)
return -ENOMEM;
memset(chip,0,sizeof(*chip));
memcpy(&chip->c,&client_template,sizeof(struct i2c_client));
- chip->c.adapter = adap;
- chip->c.addr = addr;
+ chip->c.adapter = adap;
+ chip->c.addr = addr;
i2c_set_clientdata(&chip->c, chip);
/* find description for the chip */
diff --git a/drivers/media/video/tveeprom.c b/drivers/media/video/tveeprom.c
index 5344d5592199..72e8741e8b59 100644
--- a/drivers/media/video/tveeprom.c
+++ b/drivers/media/video/tveeprom.c
@@ -6,12 +6,12 @@
* which are:
Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de)
- & Marcus Metzler (mocm@thp.uni-koeln.de)
+ & Marcus Metzler (mocm@thp.uni-koeln.de)
(c) 1999-2001 Gerd Knorr <kraxel@goldbach.in-berlin.de>
* Adjustments to fit a more general model and all bugs:
- Copyright (C) 2003 John Klar <linpvr at projectplasma.com>
+ Copyright (C) 2003 John Klar <linpvr at projectplasma.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
@@ -40,6 +40,7 @@
#include <media/tuner.h>
#include <media/tveeprom.h>
+#include <media/audiochip.h>
MODULE_DESCRIPTION("i2c Hauppauge eeprom decoder driver");
MODULE_AUTHOR("John Klar");
@@ -53,14 +54,14 @@ MODULE_PARM_DESC(debug, "Debug level (0-1)");
#define tveeprom_info(fmt, arg...) do {\
printk(KERN_INFO "tveeprom %d-%04x: " fmt, \
- c->adapter->nr, c->addr , ##arg); } while (0)
+ c->adapter->nr, c->addr , ##arg); } while (0)
#define tveeprom_warn(fmt, arg...) do {\
printk(KERN_WARNING "tveeprom %d-%04x: " fmt, \
- c->adapter->nr, c->addr , ##arg); } while (0)
+ c->adapter->nr, c->addr , ##arg); } while (0)
#define tveeprom_dbg(fmt, arg...) do {\
if (debug) \
- printk(KERN_INFO "tveeprom %d-%04x: " fmt, \
- c->adapter->nr, c->addr , ##arg); } while (0)
+ printk(KERN_INFO "tveeprom %d-%04x: " fmt, \
+ c->adapter->nr, c->addr , ##arg); } while (0)
/* ----------------------------------------------------------------------- */
@@ -134,8 +135,8 @@ hauppauge_tuner[] =
{ TUNER_TEMIC_4039FR5_NTSC, "Temic 4039FR5" },
{ TUNER_PHILIPS_FQ1216ME, "Philips FQ1216 ME" },
{ TUNER_TEMIC_4066FY5_PAL_I, "Temic 4066FY5" },
- { TUNER_PHILIPS_NTSC, "Philips TD1536" },
- { TUNER_PHILIPS_NTSC, "Philips TD1536D" },
+ { TUNER_PHILIPS_NTSC, "Philips TD1536" },
+ { TUNER_PHILIPS_NTSC, "Philips TD1536D" },
{ TUNER_PHILIPS_NTSC, "Philips FMR1236" }, /* mono radio */
{ TUNER_ABSENT, "Philips FI1256MP" },
/* 40-49 */
@@ -189,7 +190,7 @@ hauppauge_tuner[] =
{ TUNER_LG_PAL_NEW_TAPC, "TCL 2002MB 3"},
{ TUNER_LG_PAL_NEW_TAPC, "TCL 2002MI 3"},
{ TUNER_TCL_2002N, "TCL 2002N 6A"},
- { TUNER_ABSENT, "Philips FQ1236 MK3"},
+ { TUNER_PHILIPS_FM1236_MK3, "Philips FQ1236 MK3"},
{ TUNER_ABSENT, "Samsung TCPN 2121P30A"},
{ TUNER_ABSENT, "Samsung TCPE 4121P30A"},
{ TUNER_PHILIPS_FM1216ME_MK3, "TCL MFPE05 2"},
@@ -200,95 +201,137 @@ hauppauge_tuner[] =
{ TUNER_ABSENT, "Philips FQ1286A MK4"},
{ TUNER_ABSENT, "Philips FQ1216ME MK5"},
{ TUNER_ABSENT, "Philips FQ1236 MK5"},
- { TUNER_ABSENT, "Unspecified"},
- { TUNER_LG_PAL_TAPE, "LG PAL (TAPE Series)"},
- { TUNER_ABSENT, "Unspecified"},
- { TUNER_TCL_2002N, "TCL 2002N 5H"},
- /* 100-103 */
- { TUNER_ABSENT, "Unspecified"},
- { TUNER_TEA5767, "Philips TEA5767HN FM Radio"},
- { TUNER_ABSENT, "Unspecified"},
- { TUNER_PHILIPS_FM1236_MK3, "TCL MFNM05 4"},
+ { TUNER_ABSENT, "Samsung TCPG_6121P30A"},
+ { TUNER_TCL_2002MB, "TCL 2002MB_3H"},
+ { TUNER_ABSENT, "TCL 2002MI_3H"},
+ { TUNER_TCL_2002N, "TCL 2002N 5H"},
+ /* 100-109 */
+ { TUNER_ABSENT, "Philips FMD1216ME"},
+ { TUNER_TEA5767, "Philips TEA5768HL FM Radio"},
+ { TUNER_ABSENT, "Panasonic ENV57H12D5"},
+ { TUNER_ABSENT, "TCL MFNM05-4"},
+ { TUNER_ABSENT, "TCL MNM05-4"},
+ { TUNER_PHILIPS_FM1216ME_MK3, "TCL MPE05-2"},
+ { TUNER_ABSENT, "TCL MQNM05-4"},
+ { TUNER_ABSENT, "LG TAPC-W701D"},
+ { TUNER_ABSENT, "TCL 9886P-WM"},
+ { TUNER_ABSENT, "TCL 1676NM-WM"},
};
-/* This list is supplied by Hauppauge. Thanks! */
-static const char *audioIC[] = {
- /* 0-4 */
- "None", "TEA6300", "TEA6320", "TDA9850", "MSP3400C",
- /* 5-9 */
- "MSP3410D", "MSP3415", "MSP3430", "MSP3438", "CS5331",
- /* 10-14 */
- "MSP3435", "MSP3440", "MSP3445", "MSP3411", "MSP3416",
- /* 15-19 */
- "MSP3425", "MSP3451", "MSP3418", "Type 0x12", "OKI7716",
- /* 20-24 */
- "MSP4410", "MSP4420", "MSP4440", "MSP4450", "MSP4408",
- /* 25-29 */
- "MSP4418", "MSP4428", "MSP4448", "MSP4458", "Type 0x1d",
- /* 30-34 */
- "CX880", "CX881", "CX883", "CX882", "CX25840",
- /* 35-38 */
- "CX25841", "CX25842", "CX25843", "CX23418",
+static struct HAUPPAUGE_AUDIOIC
+{
+ enum audiochip id;
+ char *name;
+}
+audioIC[] =
+{
+ /* 0-4 */
+ {AUDIO_CHIP_NONE, "None"},
+ {AUDIO_CHIP_TEA6300, "TEA6300"},
+ {AUDIO_CHIP_TEA6300, "TEA6320"},
+ {AUDIO_CHIP_TDA985X, "TDA9850"},
+ {AUDIO_CHIP_MSP34XX, "MSP3400C"},
+ /* 5-9 */
+ {AUDIO_CHIP_MSP34XX, "MSP3410D"},
+ {AUDIO_CHIP_MSP34XX, "MSP3415"},
+ {AUDIO_CHIP_MSP34XX, "MSP3430"},
+ {AUDIO_CHIP_UNKNOWN, "MSP3438"},
+ {AUDIO_CHIP_UNKNOWN, "CS5331"},
+ /* 10-14 */
+ {AUDIO_CHIP_MSP34XX, "MSP3435"},
+ {AUDIO_CHIP_MSP34XX, "MSP3440"},
+ {AUDIO_CHIP_MSP34XX, "MSP3445"},
+ {AUDIO_CHIP_UNKNOWN, "MSP3411"},
+ {AUDIO_CHIP_UNKNOWN, "MSP3416"},
+ /* 15-19 */
+ {AUDIO_CHIP_MSP34XX, "MSP3425"},
+ {AUDIO_CHIP_UNKNOWN, "MSP3451"},
+ {AUDIO_CHIP_UNKNOWN, "MSP3418"},
+ {AUDIO_CHIP_UNKNOWN, "Type 0x12"},
+ {AUDIO_CHIP_UNKNOWN, "OKI7716"},
+ /* 20-24 */
+ {AUDIO_CHIP_UNKNOWN, "MSP4410"},
+ {AUDIO_CHIP_UNKNOWN, "MSP4420"},
+ {AUDIO_CHIP_UNKNOWN, "MSP4440"},
+ {AUDIO_CHIP_UNKNOWN, "MSP4450"},
+ {AUDIO_CHIP_UNKNOWN, "MSP4408"},
+ /* 25-29 */
+ {AUDIO_CHIP_UNKNOWN, "MSP4418"},
+ {AUDIO_CHIP_UNKNOWN, "MSP4428"},
+ {AUDIO_CHIP_UNKNOWN, "MSP4448"},
+ {AUDIO_CHIP_UNKNOWN, "MSP4458"},
+ {AUDIO_CHIP_UNKNOWN, "Type 0x1d"},
+ /* 30-34 */
+ {AUDIO_CHIP_INTERNAL, "CX880"},
+ {AUDIO_CHIP_INTERNAL, "CX881"},
+ {AUDIO_CHIP_INTERNAL, "CX883"},
+ {AUDIO_CHIP_INTERNAL, "CX882"},
+ {AUDIO_CHIP_INTERNAL, "CX25840"},
+ /* 35-38 */
+ {AUDIO_CHIP_INTERNAL, "CX25841"},
+ {AUDIO_CHIP_INTERNAL, "CX25842"},
+ {AUDIO_CHIP_INTERNAL, "CX25843"},
+ {AUDIO_CHIP_INTERNAL, "CX23418"},
};
/* This list is supplied by Hauppauge. Thanks! */
static const char *decoderIC[] = {
- /* 0-4 */
- "None", "BT815", "BT817", "BT819", "BT815A",
- /* 5-9 */
- "BT817A", "BT819A", "BT827", "BT829", "BT848",
- /* 10-14 */
- "BT848A", "BT849A", "BT829A", "BT827A", "BT878",
- /* 15-19 */
- "BT879", "BT880", "VPX3226E", "SAA7114", "SAA7115",
- /* 20-24 */
- "CX880", "CX881", "CX883", "SAA7111", "SAA7113",
- /* 25-29 */
- "CX882", "TVP5150A", "CX25840", "CX25841", "CX25842",
- /* 30-31 */
- "CX25843", "CX23418",
+ /* 0-4 */
+ "None", "BT815", "BT817", "BT819", "BT815A",
+ /* 5-9 */
+ "BT817A", "BT819A", "BT827", "BT829", "BT848",
+ /* 10-14 */
+ "BT848A", "BT849A", "BT829A", "BT827A", "BT878",
+ /* 15-19 */
+ "BT879", "BT880", "VPX3226E", "SAA7114", "SAA7115",
+ /* 20-24 */
+ "CX880", "CX881", "CX883", "SAA7111", "SAA7113",
+ /* 25-29 */
+ "CX882", "TVP5150A", "CX25840", "CX25841", "CX25842",
+ /* 30-31 */
+ "CX25843", "CX23418",
};
static int hasRadioTuner(int tunerType)
{
- switch (tunerType) {
- case 18: //PNPEnv_TUNER_FR1236_MK2:
- case 23: //PNPEnv_TUNER_FM1236:
- case 38: //PNPEnv_TUNER_FMR1236:
- case 16: //PNPEnv_TUNER_FR1216_MK2:
- case 19: //PNPEnv_TUNER_FR1246_MK2:
- case 21: //PNPEnv_TUNER_FM1216:
- case 24: //PNPEnv_TUNER_FM1246:
- case 17: //PNPEnv_TUNER_FR1216MF_MK2:
- case 22: //PNPEnv_TUNER_FM1216MF:
- case 20: //PNPEnv_TUNER_FR1256_MK2:
- case 25: //PNPEnv_TUNER_FM1256:
- case 33: //PNPEnv_TUNER_4039FR5:
- case 42: //PNPEnv_TUNER_4009FR5:
- case 52: //PNPEnv_TUNER_4049FM5:
- case 54: //PNPEnv_TUNER_4049FM5_AltI2C:
- case 44: //PNPEnv_TUNER_4009FN5:
- case 31: //PNPEnv_TUNER_TCPB9085P:
- case 30: //PNPEnv_TUNER_TCPN9085D:
- case 46: //PNPEnv_TUNER_TP18NSR01F:
- case 47: //PNPEnv_TUNER_TP18PSB01D:
- case 49: //PNPEnv_TUNER_TAPC_I001D:
- case 60: //PNPEnv_TUNER_TAPE_S001D_MK3:
- case 57: //PNPEnv_TUNER_FM1216ME_MK3:
- case 59: //PNPEnv_TUNER_FM1216MP_MK3:
- case 58: //PNPEnv_TUNER_FM1236_MK3:
- case 68: //PNPEnv_TUNER_TAPE_H001F_MK3:
- case 61: //PNPEnv_TUNER_TAPE_M001D_MK3:
- case 78: //PNPEnv_TUNER_TDA8275C1_8290_FM:
- case 89: //PNPEnv_TUNER_TCL_MFPE05_2:
- case 92: //PNPEnv_TUNER_PHILIPS_FQ1236A_MK4:
- return 1;
- }
- return 0;
+ switch (tunerType) {
+ case 18: //PNPEnv_TUNER_FR1236_MK2:
+ case 23: //PNPEnv_TUNER_FM1236:
+ case 38: //PNPEnv_TUNER_FMR1236:
+ case 16: //PNPEnv_TUNER_FR1216_MK2:
+ case 19: //PNPEnv_TUNER_FR1246_MK2:
+ case 21: //PNPEnv_TUNER_FM1216:
+ case 24: //PNPEnv_TUNER_FM1246:
+ case 17: //PNPEnv_TUNER_FR1216MF_MK2:
+ case 22: //PNPEnv_TUNER_FM1216MF:
+ case 20: //PNPEnv_TUNER_FR1256_MK2:
+ case 25: //PNPEnv_TUNER_FM1256:
+ case 33: //PNPEnv_TUNER_4039FR5:
+ case 42: //PNPEnv_TUNER_4009FR5:
+ case 52: //PNPEnv_TUNER_4049FM5:
+ case 54: //PNPEnv_TUNER_4049FM5_AltI2C:
+ case 44: //PNPEnv_TUNER_4009FN5:
+ case 31: //PNPEnv_TUNER_TCPB9085P:
+ case 30: //PNPEnv_TUNER_TCPN9085D:
+ case 46: //PNPEnv_TUNER_TP18NSR01F:
+ case 47: //PNPEnv_TUNER_TP18PSB01D:
+ case 49: //PNPEnv_TUNER_TAPC_I001D:
+ case 60: //PNPEnv_TUNER_TAPE_S001D_MK3:
+ case 57: //PNPEnv_TUNER_FM1216ME_MK3:
+ case 59: //PNPEnv_TUNER_FM1216MP_MK3:
+ case 58: //PNPEnv_TUNER_FM1236_MK3:
+ case 68: //PNPEnv_TUNER_TAPE_H001F_MK3:
+ case 61: //PNPEnv_TUNER_TAPE_M001D_MK3:
+ case 78: //PNPEnv_TUNER_TDA8275C1_8290_FM:
+ case 89: //PNPEnv_TUNER_TCL_MFPE05_2:
+ case 92: //PNPEnv_TUNER_PHILIPS_FQ1236A_MK4:
+ return 1;
+ }
+ return 0;
}
void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee,
- unsigned char *eeprom_data)
+ unsigned char *eeprom_data)
{
/* ----------------------------------------------
** The hauppauge eeprom format is tagged
@@ -312,19 +355,27 @@ void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee,
** # of inputs/outputs ???
*/
- int i, j, len, done, beenhere, tag;
+ int i, j, len, done, beenhere, tag,start;
- int tuner1 = 0, t_format1 = 0;
+ int tuner1 = 0, t_format1 = 0, audioic=-1;
char *t_name1 = NULL;
- const char *t_fmt_name1[8] = { " none", "", "", "", "", "", "", "" };
+ const char *t_fmt_name1[8] = { " none", "", "", "", "", "", "", "" };
- int tuner2 = 0, t_format2 = 0;
+ int tuner2 = 0, t_format2 = 0;
char *t_name2 = NULL;
- const char *t_fmt_name2[8] = { " none", "", "", "", "", "", "", "" };
+ const char *t_fmt_name2[8] = { " none", "", "", "", "", "", "", "" };
- memset(tvee, 0, sizeof(*tvee));
+ memset(tvee, 0, sizeof(*tvee));
done = len = beenhere = 0;
- for (i = 0; !done && i < 256; i += len) {
+
+ /* Hack for processing eeprom for em28xx */
+ if ((eeprom_data[0]==0x1a)&&(eeprom_data[1]==0xeb)&&
+ (eeprom_data[2]==0x67)&&(eeprom_data[3]==0x95))
+ start=0xa0;
+ else
+ start=0;
+
+ for (i = start; !done && i < 256; i += len) {
if (eeprom_data[i] == 0x84) {
len = eeprom_data[i + 1] + (eeprom_data[i + 2] << 8);
i += 3;
@@ -338,28 +389,28 @@ void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee,
++i;
} else {
tveeprom_warn("Encountered bad packet header [%02x]. "
- "Corrupt or not a Hauppauge eeprom.\n", eeprom_data[i]);
+ "Corrupt or not a Hauppauge eeprom.\n", eeprom_data[i]);
return;
}
- if (debug) {
- tveeprom_info("Tag [%02x] + %d bytes:", eeprom_data[i], len - 1);
- for(j = 1; j < len; j++) {
- printk(" %02x", eeprom_data[i + j]);
- }
- printk("\n");
- }
+ if (debug) {
+ tveeprom_info("Tag [%02x] + %d bytes:", eeprom_data[i], len - 1);
+ for(j = 1; j < len; j++) {
+ printk(" %02x", eeprom_data[i + j]);
+ }
+ printk("\n");
+ }
/* process by tag */
tag = eeprom_data[i];
switch (tag) {
case 0x00:
- /* tag: 'Comprehensive' */
+ /* tag: 'Comprehensive' */
tuner1 = eeprom_data[i+6];
t_format1 = eeprom_data[i+5];
tvee->has_radio = eeprom_data[i+len-1];
- /* old style tag, don't know how to detect
- IR presence, mark as unknown. */
+ /* old style tag, don't know how to detect
+ IR presence, mark as unknown. */
tvee->has_ir = 2;
tvee->model =
eeprom_data[i+8] +
@@ -370,7 +421,7 @@ void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee,
break;
case 0x01:
- /* tag: 'SerialID' */
+ /* tag: 'SerialID' */
tvee->serial_number =
eeprom_data[i+6] +
(eeprom_data[i+7] << 8) +
@@ -378,17 +429,21 @@ void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee,
break;
case 0x02:
- /* tag 'AudioInfo'
- Note mask with 0x7F, high bit used on some older models
- to indicate 4052 mux was removed in favor of using MSP
- inputs directly. */
- tvee->audio_processor = eeprom_data[i+2] & 0x7f;
+ /* tag 'AudioInfo'
+ Note mask with 0x7F, high bit used on some older models
+ to indicate 4052 mux was removed in favor of using MSP
+ inputs directly. */
+ audioic = eeprom_data[i+2] & 0x7f;
+ if (audioic < sizeof(audioIC)/sizeof(*audioIC))
+ tvee->audio_processor = audioIC[audioic].id;
+ else
+ tvee->audio_processor = AUDIO_CHIP_UNKNOWN;
break;
- /* case 0x03: tag 'EEInfo' */
+ /* case 0x03: tag 'EEInfo' */
case 0x04:
- /* tag 'SerialID2' */
+ /* tag 'SerialID2' */
tvee->serial_number =
eeprom_data[i+5] +
(eeprom_data[i+6] << 8) +
@@ -396,15 +451,20 @@ void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee,
break;
case 0x05:
- /* tag 'Audio2'
- Note mask with 0x7F, high bit used on some older models
- to indicate 4052 mux was removed in favor of using MSP
- inputs directly. */
- tvee->audio_processor = eeprom_data[i+1] & 0x7f;
+ /* tag 'Audio2'
+ Note mask with 0x7F, high bit used on some older models
+ to indicate 4052 mux was removed in favor of using MSP
+ inputs directly. */
+ audioic = eeprom_data[i+1] & 0x7f;
+ if (audioic < sizeof(audioIC)/sizeof(*audioIC))
+ tvee->audio_processor = audioIC[audioic].id;
+ else
+ tvee->audio_processor = AUDIO_CHIP_UNKNOWN;
+
break;
case 0x06:
- /* tag 'ModelRev' */
+ /* tag 'ModelRev' */
tvee->model =
eeprom_data[i+1] +
(eeprom_data[i+2] << 8);
@@ -414,55 +474,55 @@ void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee,
break;
case 0x07:
- /* tag 'Details': according to Hauppauge not interesting
- on any PCI-era or later boards. */
+ /* tag 'Details': according to Hauppauge not interesting
+ on any PCI-era or later boards. */
break;
- /* there is no tag 0x08 defined */
+ /* there is no tag 0x08 defined */
case 0x09:
- /* tag 'Video' */
+ /* tag 'Video' */
tvee->decoder_processor = eeprom_data[i + 1];
break;
case 0x0a:
- /* tag 'Tuner' */
+ /* tag 'Tuner' */
if (beenhere == 0) {
tuner1 = eeprom_data[i+2];
t_format1 = eeprom_data[i+1];
beenhere = 1;
} else {
- /* a second (radio) tuner may be present */
+ /* a second (radio) tuner may be present */
tuner2 = eeprom_data[i+2];
t_format2 = eeprom_data[i+1];
- if (t_format2 == 0) { /* not a TV tuner? */
- tvee->has_radio = 1; /* must be radio */
- }
- }
+ if (t_format2 == 0) { /* not a TV tuner? */
+ tvee->has_radio = 1; /* must be radio */
+ }
+ }
break;
- case 0x0b:
- /* tag 'Inputs': according to Hauppauge this is specific
- to each driver family, so no good assumptions can be
- made. */
- break;
+ case 0x0b:
+ /* tag 'Inputs': according to Hauppauge this is specific
+ to each driver family, so no good assumptions can be
+ made. */
+ break;
- /* case 0x0c: tag 'Balun' */
- /* case 0x0d: tag 'Teletext' */
+ /* case 0x0c: tag 'Balun' */
+ /* case 0x0d: tag 'Teletext' */
case 0x0e:
- /* tag: 'Radio' */
+ /* tag: 'Radio' */
tvee->has_radio = eeprom_data[i+1];
break;
- case 0x0f:
- /* tag 'IRInfo' */
- tvee->has_ir = eeprom_data[i+1];
- break;
+ case 0x0f:
+ /* tag 'IRInfo' */
+ tvee->has_ir = eeprom_data[i+1];
+ break;
- /* case 0x10: tag 'VBIInfo' */
- /* case 0x11: tag 'QCInfo' */
- /* case 0x12: tag 'InfoBits' */
+ /* case 0x10: tag 'VBIInfo' */
+ /* case 0x11: tag 'QCInfo' */
+ /* case 0x12: tag 'InfoBits' */
default:
tveeprom_dbg("Not sure what to do with tag [%02x]\n", tag);
@@ -483,11 +543,11 @@ void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee,
tvee->rev_str[4] = 0;
}
- if (hasRadioTuner(tuner1) && !tvee->has_radio) {
- tveeprom_info("The eeprom says no radio is present, but the tuner type\n");
- tveeprom_info("indicates otherwise. I will assume that radio is present.\n");
- tvee->has_radio = 1;
- }
+ if (hasRadioTuner(tuner1) && !tvee->has_radio) {
+ tveeprom_info("The eeprom says no radio is present, but the tuner type\n");
+ tveeprom_info("indicates otherwise. I will assume that radio is present.\n");
+ tvee->has_radio = 1;
+ }
if (tuner1 < sizeof(hauppauge_tuner)/sizeof(struct HAUPPAUGE_TUNER)) {
tvee->tuner_type = hauppauge_tuner[tuner1].id;
@@ -510,45 +570,53 @@ void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee,
tvee->tuner_formats |= hauppauge_tuner_fmt[i].id;
t_fmt_name1[j++] = hauppauge_tuner_fmt[i].name;
}
- if (t_format2 & (1 << i)) {
- tvee->tuner2_formats |= hauppauge_tuner_fmt[i].id;
- t_fmt_name2[j++] = hauppauge_tuner_fmt[i].name;
- }
+ if (t_format2 & (1 << i)) {
+ tvee->tuner2_formats |= hauppauge_tuner_fmt[i].id;
+ t_fmt_name2[j++] = hauppauge_tuner_fmt[i].name;
+ }
}
tveeprom_info("Hauppauge model %d, rev %s, serial# %d\n",
- tvee->model, tvee->rev_str, tvee->serial_number);
+ tvee->model, tvee->rev_str, tvee->serial_number);
tveeprom_info("tuner model is %s (idx %d, type %d)\n",
- t_name1, tuner1, tvee->tuner_type);
+ t_name1, tuner1, tvee->tuner_type);
tveeprom_info("TV standards%s%s%s%s%s%s%s%s (eeprom 0x%02x)\n",
- t_fmt_name1[0], t_fmt_name1[1], t_fmt_name1[2], t_fmt_name1[3],
- t_fmt_name1[4], t_fmt_name1[5], t_fmt_name1[6], t_fmt_name1[7],
- t_format1);
- if (tuner2) {
- tveeprom_info("second tuner model is %s (idx %d, type %d)\n",
- t_name2, tuner2, tvee->tuner2_type);
- }
- if (t_format2) {
- tveeprom_info("TV standards%s%s%s%s%s%s%s%s (eeprom 0x%02x)\n",
- t_fmt_name2[0], t_fmt_name2[1], t_fmt_name2[2], t_fmt_name2[3],
- t_fmt_name2[4], t_fmt_name2[5], t_fmt_name2[6], t_fmt_name2[7],
- t_format2);
- }
- tveeprom_info("audio processor is %s (idx %d)\n",
- STRM(audioIC, tvee->audio_processor),
- tvee->audio_processor);
- if (tvee->decoder_processor) {
- tveeprom_info("decoder processor is %s (idx %d)\n",
- STRM(decoderIC, tvee->decoder_processor),
- tvee->decoder_processor);
- }
- if (tvee->has_ir == 2)
- tveeprom_info("has %sradio\n",
- tvee->has_radio ? "" : "no ");
- else
- tveeprom_info("has %sradio, has %sIR remote\n",
- tvee->has_radio ? "" : "no ",
- tvee->has_ir ? "" : "no ");
+ t_fmt_name1[0], t_fmt_name1[1], t_fmt_name1[2], t_fmt_name1[3],
+ t_fmt_name1[4], t_fmt_name1[5], t_fmt_name1[6], t_fmt_name1[7],
+ t_format1);
+ if (tuner2) {
+ tveeprom_info("second tuner model is %s (idx %d, type %d)\n",
+ t_name2, tuner2, tvee->tuner2_type);
+ }
+ if (t_format2) {
+ tveeprom_info("TV standards%s%s%s%s%s%s%s%s (eeprom 0x%02x)\n",
+ t_fmt_name2[0], t_fmt_name2[1], t_fmt_name2[2], t_fmt_name2[3],
+ t_fmt_name2[4], t_fmt_name2[5], t_fmt_name2[6], t_fmt_name2[7],
+ t_format2);
+ }
+ if (audioic<0) {
+ tveeprom_info("audio processor is unknown (no idx)\n");
+ tvee->audio_processor=AUDIO_CHIP_UNKNOWN;
+ } else {
+ if (audioic < sizeof(audioIC)/sizeof(*audioIC))
+ tveeprom_info("audio processor is %s (idx %d)\n",
+ audioIC[audioic].name,audioic);
+ else
+ tveeprom_info("audio processor is unknown (idx %d)\n",
+ audioic);
+ }
+ if (tvee->decoder_processor) {
+ tveeprom_info("decoder processor is %s (idx %d)\n",
+ STRM(decoderIC, tvee->decoder_processor),
+ tvee->decoder_processor);
+ }
+ if (tvee->has_ir == 2)
+ tveeprom_info("has %sradio\n",
+ tvee->has_radio ? "" : "no ");
+ else
+ tveeprom_info("has %sradio, has %sIR remote\n",
+ tvee->has_radio ? "" : "no ",
+ tvee->has_ir ? "" : "no ");
}
EXPORT_SYMBOL(tveeprom_hauppauge_analog);
@@ -569,18 +637,18 @@ int tveeprom_read(struct i2c_client *c, unsigned char *eedata, int len)
tveeprom_warn("i2c eeprom read error (err=%d)\n", err);
return -1;
}
- if (debug) {
- int i;
-
- tveeprom_info("full 256-byte eeprom dump:\n");
- for (i = 0; i < len; i++) {
- if (0 == (i % 16))
- tveeprom_info("%02x:", i);
- printk(" %02x", eedata[i]);
- if (15 == (i % 16))
- printk("\n");
- }
- }
+ if (debug) {
+ int i;
+
+ tveeprom_info("full 256-byte eeprom dump:\n");
+ for (i = 0; i < len; i++) {
+ if (0 == (i % 16))
+ tveeprom_info("%02x:", i);
+ printk(" %02x", eedata[i]);
+ if (15 == (i % 16))
+ printk("\n");
+ }
+ }
return 0;
}
EXPORT_SYMBOL(tveeprom_read);
@@ -590,10 +658,6 @@ EXPORT_SYMBOL(tveeprom_read);
/* run, just call the exported tveeprom_* directly, there is no point in */
/* using the indirect way via i2c_driver->command() */
-#ifndef I2C_DRIVERID_TVEEPROM
-# define I2C_DRIVERID_TVEEPROM I2C_DRIVERID_EXP2
-#endif
-
static unsigned short normal_i2c[] = {
0xa0 >> 1,
I2C_CLIENT_END,
diff --git a/drivers/media/video/tvmixer.c b/drivers/media/video/tvmixer.c
index d86e08ebddfc..8318bd1aad00 100644
--- a/drivers/media/video/tvmixer.c
+++ b/drivers/media/video/tvmixer.c
@@ -79,7 +79,7 @@ static int tvmixer_ioctl(struct inode *inode, struct file *file, unsigned int cm
{
struct video_audio va;
int left,right,ret,val = 0;
- struct TVMIXER *mix = file->private_data;
+ struct TVMIXER *mix = file->private_data;
struct i2c_client *client = mix->dev;
void __user *argp = (void __user *)arg;
int __user *p = argp;
@@ -87,25 +87,25 @@ static int tvmixer_ioctl(struct inode *inode, struct file *file, unsigned int cm
if (NULL == client)
return -ENODEV;
- if (cmd == SOUND_MIXER_INFO) {
- mixer_info info;
- strlcpy(info.id, "tv card", sizeof(info.id));
- strlcpy(info.name, client->name, sizeof(info.name));
- info.modify_counter = 42 /* FIXME */;
- if (copy_to_user(argp, &info, sizeof(info)))
- return -EFAULT;
- return 0;
- }
- if (cmd == SOUND_OLD_MIXER_INFO) {
- _old_mixer_info info;
- strlcpy(info.id, "tv card", sizeof(info.id));
- strlcpy(info.name, client->name, sizeof(info.name));
- if (copy_to_user(argp, &info, sizeof(info)))
- return -EFAULT;
- return 0;
- }
- if (cmd == OSS_GETVERSION)
- return put_user(SOUND_VERSION, p);
+ if (cmd == SOUND_MIXER_INFO) {
+ mixer_info info;
+ strlcpy(info.id, "tv card", sizeof(info.id));
+ strlcpy(info.name, client->name, sizeof(info.name));
+ info.modify_counter = 42 /* FIXME */;
+ if (copy_to_user(argp, &info, sizeof(info)))
+ return -EFAULT;
+ return 0;
+ }
+ if (cmd == SOUND_OLD_MIXER_INFO) {
+ _old_mixer_info info;
+ strlcpy(info.id, "tv card", sizeof(info.id));
+ strlcpy(info.name, client->name, sizeof(info.name));
+ if (copy_to_user(argp, &info, sizeof(info)))
+ return -EFAULT;
+ return 0;
+ }
+ if (cmd == OSS_GETVERSION)
+ return put_user(SOUND_VERSION, p);
if (_SIOC_DIR(cmd) & _SIOC_WRITE)
if (get_user(val, p))
@@ -181,8 +181,8 @@ static int tvmixer_ioctl(struct inode *inode, struct file *file, unsigned int cm
static int tvmixer_open(struct inode *inode, struct file *file)
{
- int i, minor = iminor(inode);
- struct TVMIXER *mix = NULL;
+ int i, minor = iminor(inode);
+ struct TVMIXER *mix = NULL;
struct i2c_client *client = NULL;
for (i = 0; i < DEV_MAX; i++) {
@@ -204,7 +204,7 @@ static int tvmixer_open(struct inode *inode, struct file *file)
#endif
if (client->adapter->owner)
try_module_get(client->adapter->owner);
- return 0;
+ return 0;
}
static int tvmixer_release(struct inode *inode, struct file *file)
@@ -231,15 +231,15 @@ static struct i2c_driver driver = {
.owner = THIS_MODULE,
#endif
.name = "tv card mixer driver",
- .id = I2C_DRIVERID_TVMIXER,
+ .id = I2C_DRIVERID_TVMIXER,
#ifdef I2C_DF_DUMMY
.flags = I2C_DF_DUMMY,
#else
.flags = I2C_DF_NOTIFY,
- .detach_adapter = tvmixer_adapters,
+ .detach_adapter = tvmixer_adapters,
#endif
- .attach_adapter = tvmixer_adapters,
- .detach_client = tvmixer_clients,
+ .attach_adapter = tvmixer_adapters,
+ .detach_client = tvmixer_clients,
};
static struct file_operations tvmixer_fops = {
diff --git a/drivers/media/video/tvp5150.c b/drivers/media/video/tvp5150.c
new file mode 100644
index 000000000000..81e6d4494e7d
--- /dev/null
+++ b/drivers/media/video/tvp5150.c
@@ -0,0 +1,829 @@
+/*
+ * tvp5150 - Texas Instruments TVP5150A(M) video decoder driver
+ *
+ * Copyright (c) 2005 Mauro Carvalho Chehab (mchehab@brturbo.com.br)
+ * This code is placed under the terms of the GNU General Public License
+ */
+
+#include <linux/i2c.h>
+#include <linux/videodev.h>
+#include <linux/delay.h>
+#include <linux/video_decoder.h>
+
+#include "tvp5150_reg.h"
+
+MODULE_DESCRIPTION("Texas Instruments TVP5150A video decoder driver"); /* standard i2c insmod options */
+MODULE_AUTHOR("Mauro Carvalho Chehab");
+MODULE_LICENSE("GPL");
+
+static unsigned short normal_i2c[] = {
+ 0xb8 >> 1,
+ 0xba >> 1,
+ I2C_CLIENT_END
+};
+
+I2C_CLIENT_INSMOD;
+
+static int debug = 0;
+module_param(debug, int, 0);
+MODULE_PARM_DESC(debug, "Debug level (0-1)");
+
+#define dprintk(num, format, args...) \
+ do { \
+ if (debug >= num) \
+ printk(format , ##args); \
+ } while (0)
+
+/* supported controls */
+static struct v4l2_queryctrl tvp5150_qctrl[] = {
+ {
+ .id = V4L2_CID_BRIGHTNESS,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Brightness",
+ .minimum = 0,
+ .maximum = 255,
+ .step = 1,
+ .default_value = 0,
+ .flags = 0,
+ }, {
+ .id = V4L2_CID_CONTRAST,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Contrast",
+ .minimum = 0,
+ .maximum = 255,
+ .step = 0x1,
+ .default_value = 0x10,
+ .flags = 0,
+ }, {
+ .id = V4L2_CID_SATURATION,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Saturation",
+ .minimum = 0,
+ .maximum = 255,
+ .step = 0x1,
+ .default_value = 0x10,
+ .flags = 0,
+ }, {
+ .id = V4L2_CID_HUE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Hue",
+ .minimum = -128,
+ .maximum = 127,
+ .step = 0x1,
+ .default_value = 0x10,
+ .flags = 0,
+ }
+};
+
+struct tvp5150 {
+ struct i2c_client *client;
+
+ int norm;
+ int input;
+ int enable;
+ int bright;
+ int contrast;
+ int hue;
+ int sat;
+};
+
+static inline int tvp5150_read(struct i2c_client *c, unsigned char addr)
+{
+ unsigned char buffer[1];
+ int rc;
+
+ buffer[0] = addr;
+ if (1 != (rc = i2c_master_send(c, buffer, 1)))
+ dprintk(0, "i2c i/o error: rc == %d (should be 1)\n", rc);
+
+ msleep(10);
+
+ if (1 != (rc = i2c_master_recv(c, buffer, 1)))
+ dprintk(0, "i2c i/o error: rc == %d (should be 1)\n", rc);
+
+ return (buffer[0]);
+}
+
+static inline void tvp5150_write(struct i2c_client *c, unsigned char addr,
+ unsigned char value)
+{
+ unsigned char buffer[2];
+ int rc;
+/* struct tvp5150 *core = i2c_get_clientdata(c); */
+
+ buffer[0] = addr;
+ buffer[1] = value;
+ dprintk(1, "tvp5150: writing 0x%02x 0x%02x\n", buffer[0], buffer[1]);
+ if (2 != (rc = i2c_master_send(c, buffer, 2)))
+ dprintk(0, "i2c i/o error: rc == %d (should be 2)\n", rc);
+}
+
+static void dump_reg(struct i2c_client *c)
+{
+ printk("tvp5150: Video input source selection #1 = 0x%02x\n",
+ tvp5150_read(c, TVP5150_VD_IN_SRC_SEL_1));
+ printk("tvp5150: Analog channel controls = 0x%02x\n",
+ tvp5150_read(c, TVP5150_ANAL_CHL_CTL));
+ printk("tvp5150: Operation mode controls = 0x%02x\n",
+ tvp5150_read(c, TVP5150_OP_MODE_CTL));
+ printk("tvp5150: Miscellaneous controls = 0x%02x\n",
+ tvp5150_read(c, TVP5150_MISC_CTL));
+ printk("tvp5150: Autoswitch mask: TVP5150A / TVP5150AM = 0x%02x\n",
+ tvp5150_read(c, TVP5150_AUTOSW_MSK));
+ printk("tvp5150: Color killer threshold control = 0x%02x\n",
+ tvp5150_read(c, TVP5150_COLOR_KIL_THSH_CTL));
+ printk("tvp5150: Luminance processing control #1 = 0x%02x\n",
+ tvp5150_read(c, TVP5150_LUMA_PROC_CTL_1));
+ printk("tvp5150: Luminance processing control #2 = 0x%02x\n",
+ tvp5150_read(c, TVP5150_LUMA_PROC_CTL_2));
+ printk("tvp5150: Brightness control = 0x%02x\n",
+ tvp5150_read(c, TVP5150_BRIGHT_CTL));
+ printk("tvp5150: Color saturation control = 0x%02x\n",
+ tvp5150_read(c, TVP5150_SATURATION_CTL));
+ printk("tvp5150: Hue control = 0x%02x\n",
+ tvp5150_read(c, TVP5150_HUE_CTL));
+ printk("tvp5150: Contrast control = 0x%02x\n",
+ tvp5150_read(c, TVP5150_CONTRAST_CTL));
+ printk("tvp5150: Outputs and data rates select = 0x%02x\n",
+ tvp5150_read(c, TVP5150_DATA_RATE_SEL));
+ printk("tvp5150: Luminance processing control #3 = 0x%02x\n",
+ tvp5150_read(c, TVP5150_LUMA_PROC_CTL_3));
+ printk("tvp5150: Configuration shared pins = 0x%02x\n",
+ tvp5150_read(c, TVP5150_CONF_SHARED_PIN));
+ printk("tvp5150: Active video cropping start MSB = 0x%02x\n",
+ tvp5150_read(c, TVP5150_ACT_VD_CROP_ST_MSB));
+ printk("tvp5150: Active video cropping start LSB = 0x%02x\n",
+ tvp5150_read(c, TVP5150_ACT_VD_CROP_ST_LSB));
+ printk("tvp5150: Active video cropping stop MSB = 0x%02x\n",
+ tvp5150_read(c, TVP5150_ACT_VD_CROP_STP_MSB));
+ printk("tvp5150: Active video cropping stop LSB = 0x%02x\n",
+ tvp5150_read(c, TVP5150_ACT_VD_CROP_STP_LSB));
+ printk("tvp5150: Genlock/RTC = 0x%02x\n",
+ tvp5150_read(c, TVP5150_GENLOCK));
+ printk("tvp5150: Horizontal sync start = 0x%02x\n",
+ tvp5150_read(c, TVP5150_HORIZ_SYNC_START));
+ printk("tvp5150: Vertical blanking start = 0x%02x\n",
+ tvp5150_read(c, TVP5150_VERT_BLANKING_START));
+ printk("tvp5150: Vertical blanking stop = 0x%02x\n",
+ tvp5150_read(c, TVP5150_VERT_BLANKING_STOP));
+ printk("tvp5150: Chrominance processing control #1 = 0x%02x\n",
+ tvp5150_read(c, TVP5150_CHROMA_PROC_CTL_1));
+ printk("tvp5150: Chrominance processing control #2 = 0x%02x\n",
+ tvp5150_read(c, TVP5150_CHROMA_PROC_CTL_2));
+ printk("tvp5150: Interrupt reset register B = 0x%02x\n",
+ tvp5150_read(c, TVP5150_INT_RESET_REG_B));
+ printk("tvp5150: Interrupt enable register B = 0x%02x\n",
+ tvp5150_read(c, TVP5150_INT_ENABLE_REG_B));
+ printk("tvp5150: Interrupt configuration register B = 0x%02x\n",
+ tvp5150_read(c, TVP5150_INTT_CONFIG_REG_B));
+ printk("tvp5150: Video standard = 0x%02x\n",
+ tvp5150_read(c, TVP5150_VIDEO_STD));
+ printk("tvp5150: Cb gain factor = 0x%02x\n",
+ tvp5150_read(c, TVP5150_CB_GAIN_FACT));
+ printk("tvp5150: Cr gain factor = 0x%02x\n",
+ tvp5150_read(c, TVP5150_CR_GAIN_FACTOR));
+ printk("tvp5150: Macrovision on counter = 0x%02x\n",
+ tvp5150_read(c, TVP5150_MACROVISION_ON_CTR));
+ printk("tvp5150: Macrovision off counter = 0x%02x\n",
+ tvp5150_read(c, TVP5150_MACROVISION_OFF_CTR));
+ printk("tvp5150: revision select (TVP5150AM1 only) = 0x%02x\n",
+ tvp5150_read(c, TVP5150_REV_SELECT));
+ printk("tvp5150: MSB of device ID = 0x%02x\n",
+ tvp5150_read(c, TVP5150_MSB_DEV_ID));
+ printk("tvp5150: LSB of device ID = 0x%02x\n",
+ tvp5150_read(c, TVP5150_LSB_DEV_ID));
+ printk("tvp5150: ROM major version = 0x%02x\n",
+ tvp5150_read(c, TVP5150_ROM_MAJOR_VER));
+ printk("tvp5150: ROM minor version = 0x%02x\n",
+ tvp5150_read(c, TVP5150_ROM_MINOR_VER));
+ printk("tvp5150: Vertical line count MSB = 0x%02x\n",
+ tvp5150_read(c, TVP5150_VERT_LN_COUNT_MSB));
+ printk("tvp5150: Vertical line count LSB = 0x%02x\n",
+ tvp5150_read(c, TVP5150_VERT_LN_COUNT_LSB));
+ printk("tvp5150: Interrupt status register B = 0x%02x\n",
+ tvp5150_read(c, TVP5150_INT_STATUS_REG_B));
+ printk("tvp5150: Interrupt active register B = 0x%02x\n",
+ tvp5150_read(c, TVP5150_INT_ACTIVE_REG_B));
+ printk("tvp5150: Status register #1 = 0x%02x\n",
+ tvp5150_read(c, TVP5150_STATUS_REG_1));
+ printk("tvp5150: Status register #2 = 0x%02x\n",
+ tvp5150_read(c, TVP5150_STATUS_REG_2));
+ printk("tvp5150: Status register #3 = 0x%02x\n",
+ tvp5150_read(c, TVP5150_STATUS_REG_3));
+ printk("tvp5150: Status register #4 = 0x%02x\n",
+ tvp5150_read(c, TVP5150_STATUS_REG_4));
+ printk("tvp5150: Status register #5 = 0x%02x\n",
+ tvp5150_read(c, TVP5150_STATUS_REG_5));
+ printk("tvp5150: Closed caption data registers = 0x%02x\n",
+ tvp5150_read(c, TVP5150_CC_DATA_REG1));
+ printk("tvp5150: Closed caption data registers = 0x%02x\n",
+ tvp5150_read(c, TVP5150_CC_DATA_REG2));
+ printk("tvp5150: Closed caption data registers = 0x%02x\n",
+ tvp5150_read(c, TVP5150_CC_DATA_REG3));
+ printk("tvp5150: Closed caption data registers = 0x%02x\n",
+ tvp5150_read(c, TVP5150_CC_DATA_REG4));
+ printk("tvp5150: WSS data registers = 0x%02x\n",
+ tvp5150_read(c, TVP5150_WSS_DATA_REG1));
+ printk("tvp5150: WSS data registers = 0x%02x\n",
+ tvp5150_read(c, TVP5150_WSS_DATA_REG2));
+ printk("tvp5150: WSS data registers = 0x%02x\n",
+ tvp5150_read(c, TVP5150_WSS_DATA_REG3));
+ printk("tvp5150: WSS data registers = 0x%02x\n",
+ tvp5150_read(c, TVP5150_WSS_DATA_REG4));
+ printk("tvp5150: WSS data registers = 0x%02x\n",
+ tvp5150_read(c, TVP5150_WSS_DATA_REG5));
+ printk("tvp5150: WSS data registers = 0x%02x\n",
+ tvp5150_read(c, TVP5150_WSS_DATA_REG6));
+ printk("tvp5150: VPS data registers = 0x%02x\n",
+ tvp5150_read(c, TVP5150_VPS_DATA_REG1));
+ printk("tvp5150: VPS data registers = 0x%02x\n",
+ tvp5150_read(c, TVP5150_VPS_DATA_REG2));
+ printk("tvp5150: VPS data registers = 0x%02x\n",
+ tvp5150_read(c, TVP5150_VPS_DATA_REG3));
+ printk("tvp5150: VPS data registers = 0x%02x\n",
+ tvp5150_read(c, TVP5150_VPS_DATA_REG4));
+ printk("tvp5150: VPS data registers = 0x%02x\n",
+ tvp5150_read(c, TVP5150_VPS_DATA_REG5));
+ printk("tvp5150: VPS data registers = 0x%02x\n",
+ tvp5150_read(c, TVP5150_VPS_DATA_REG6));
+ printk("tvp5150: VPS data registers = 0x%02x\n",
+ tvp5150_read(c, TVP5150_VPS_DATA_REG7));
+ printk("tvp5150: VPS data registers = 0x%02x\n",
+ tvp5150_read(c, TVP5150_VPS_DATA_REG8));
+ printk("tvp5150: VPS data registers = 0x%02x\n",
+ tvp5150_read(c, TVP5150_VPS_DATA_REG9));
+ printk("tvp5150: VPS data registers = 0x%02x\n",
+ tvp5150_read(c, TVP5150_VPS_DATA_REG10));
+ printk("tvp5150: VPS data registers = 0x%02x\n",
+ tvp5150_read(c, TVP5150_VPS_DATA_REG11));
+ printk("tvp5150: VPS data registers = 0x%02x\n",
+ tvp5150_read(c, TVP5150_VPS_DATA_REG12));
+ printk("tvp5150: VPS data registers = 0x%02x\n",
+ tvp5150_read(c, TVP5150_VPS_DATA_REG13));
+ printk("tvp5150: VITC data registers = 0x%02x\n",
+ tvp5150_read(c, TVP5150_VITC_DATA_REG1));
+ printk("tvp5150: VITC data registers = 0x%02x\n",
+ tvp5150_read(c, TVP5150_VITC_DATA_REG2));
+ printk("tvp5150: VITC data registers = 0x%02x\n",
+ tvp5150_read(c, TVP5150_VITC_DATA_REG3));
+ printk("tvp5150: VITC data registers = 0x%02x\n",
+ tvp5150_read(c, TVP5150_VITC_DATA_REG4));
+ printk("tvp5150: VITC data registers = 0x%02x\n",
+ tvp5150_read(c, TVP5150_VITC_DATA_REG5));
+ printk("tvp5150: VITC data registers = 0x%02x\n",
+ tvp5150_read(c, TVP5150_VITC_DATA_REG6));
+ printk("tvp5150: VITC data registers = 0x%02x\n",
+ tvp5150_read(c, TVP5150_VITC_DATA_REG7));
+ printk("tvp5150: VITC data registers = 0x%02x\n",
+ tvp5150_read(c, TVP5150_VITC_DATA_REG8));
+ printk("tvp5150: VITC data registers = 0x%02x\n",
+ tvp5150_read(c, TVP5150_VITC_DATA_REG9));
+ printk("tvp5150: VBI FIFO read data = 0x%02x\n",
+ tvp5150_read(c, TVP5150_VBI_FIFO_READ_DATA));
+ printk("tvp5150: Teletext filter 1 = 0x%02x\n",
+ tvp5150_read(c, TVP5150_TELETEXT_FIL_1_1));
+ printk("tvp5150: Teletext filter 1 = 0x%02x\n",
+ tvp5150_read(c, TVP5150_TELETEXT_FIL_1_2));
+ printk("tvp5150: Teletext filter 1 = 0x%02x\n",
+ tvp5150_read(c, TVP5150_TELETEXT_FIL_1_3));
+ printk("tvp5150: Teletext filter 1 = 0x%02x\n",
+ tvp5150_read(c, TVP5150_TELETEXT_FIL_1_4));
+ printk("tvp5150: Teletext filter 1 = 0x%02x\n",
+ tvp5150_read(c, TVP5150_TELETEXT_FIL_1_5));
+ printk("tvp5150: Teletext filter 2 = 0x%02x\n",
+ tvp5150_read(c, TVP5150_TELETEXT_FIL_2_1));
+ printk("tvp5150: Teletext filter 2 = 0x%02x\n",
+ tvp5150_read(c, TVP5150_TELETEXT_FIL_2_2));
+ printk("tvp5150: Teletext filter 2 = 0x%02x\n",
+ tvp5150_read(c, TVP5150_TELETEXT_FIL_2_3));
+ printk("tvp5150: Teletext filter 2 = 0x%02x\n",
+ tvp5150_read(c, TVP5150_TELETEXT_FIL_2_4));
+ printk("tvp5150: Teletext filter 2 = 0x%02x\n",
+ tvp5150_read(c, TVP5150_TELETEXT_FIL_2_5));
+ printk("tvp5150: Teletext filter enable = 0x%02x\n",
+ tvp5150_read(c, TVP5150_TELETEXT_FIL_ENA));
+ printk("tvp5150: Interrupt status register A = 0x%02x\n",
+ tvp5150_read(c, TVP5150_INT_STATUS_REG_A));
+ printk("tvp5150: Interrupt enable register A = 0x%02x\n",
+ tvp5150_read(c, TVP5150_INT_ENABLE_REG_A));
+ printk("tvp5150: Interrupt configuration = 0x%02x\n",
+ tvp5150_read(c, TVP5150_INT_CONF));
+ printk("tvp5150: VDP configuration RAM data = 0x%02x\n",
+ tvp5150_read(c, TVP5150_VDP_CONF_RAM_DATA));
+ printk("tvp5150: Configuration RAM address low byte = 0x%02x\n",
+ tvp5150_read(c, TVP5150_CONF_RAM_ADDR_LOW));
+ printk("tvp5150: Configuration RAM address high byte = 0x%02x\n",
+ tvp5150_read(c, TVP5150_CONF_RAM_ADDR_HIGH));
+ printk("tvp5150: VDP status register = 0x%02x\n",
+ tvp5150_read(c, TVP5150_VDP_STATUS_REG));
+ printk("tvp5150: FIFO word count = 0x%02x\n",
+ tvp5150_read(c, TVP5150_FIFO_WORD_COUNT));
+ printk("tvp5150: FIFO interrupt threshold = 0x%02x\n",
+ tvp5150_read(c, TVP5150_FIFO_INT_THRESHOLD));
+ printk("tvp5150: FIFO reset = 0x%02x\n",
+ tvp5150_read(c, TVP5150_FIFO_RESET));
+ printk("tvp5150: Line number interrupt = 0x%02x\n",
+ tvp5150_read(c, TVP5150_LINE_NUMBER_INT));
+ printk("tvp5150: Pixel alignment register low byte = 0x%02x\n",
+ tvp5150_read(c, TVP5150_PIX_ALIGN_REG_LOW));
+ printk("tvp5150: Pixel alignment register high byte = 0x%02x\n",
+ tvp5150_read(c, TVP5150_PIX_ALIGN_REG_HIGH));
+ printk("tvp5150: FIFO output control = 0x%02x\n",
+ tvp5150_read(c, TVP5150_FIFO_OUT_CTRL));
+ printk("tvp5150: Full field enable 1 = 0x%02x\n",
+ tvp5150_read(c, TVP5150_FULL_FIELD_ENA_1));
+ printk("tvp5150: Full field enable 2 = 0x%02x\n",
+ tvp5150_read(c, TVP5150_FULL_FIELD_ENA_2));
+ printk("tvp5150: Line mode registers = 0x%02x\n",
+ tvp5150_read(c, TVP5150_LINE_MODE_REG_1));
+ printk("tvp5150: Line mode registers = 0x%02x\n",
+ tvp5150_read(c, TVP5150_LINE_MODE_REG_2));
+ printk("tvp5150: Line mode registers = 0x%02x\n",
+ tvp5150_read(c, TVP5150_LINE_MODE_REG_3));
+ printk("tvp5150: Line mode registers = 0x%02x\n",
+ tvp5150_read(c, TVP5150_LINE_MODE_REG_4));
+ printk("tvp5150: Line mode registers = 0x%02x\n",
+ tvp5150_read(c, TVP5150_LINE_MODE_REG_5));
+ printk("tvp5150: Line mode registers = 0x%02x\n",
+ tvp5150_read(c, TVP5150_LINE_MODE_REG_6));
+ printk("tvp5150: Line mode registers = 0x%02x\n",
+ tvp5150_read(c, TVP5150_LINE_MODE_REG_7));
+ printk("tvp5150: Line mode registers = 0x%02x\n",
+ tvp5150_read(c, TVP5150_LINE_MODE_REG_8));
+ printk("tvp5150: Line mode registers = 0x%02x\n",
+ tvp5150_read(c, TVP5150_LINE_MODE_REG_9));
+ printk("tvp5150: Line mode registers = 0x%02x\n",
+ tvp5150_read(c, TVP5150_LINE_MODE_REG_10));
+ printk("tvp5150: Line mode registers = 0x%02x\n",
+ tvp5150_read(c, TVP5150_LINE_MODE_REG_11));
+ printk("tvp5150: Line mode registers = 0x%02x\n",
+ tvp5150_read(c, TVP5150_LINE_MODE_REG_12));
+ printk("tvp5150: Line mode registers = 0x%02x\n",
+ tvp5150_read(c, TVP5150_LINE_MODE_REG_13));
+ printk("tvp5150: Line mode registers = 0x%02x\n",
+ tvp5150_read(c, TVP5150_LINE_MODE_REG_14));
+ printk("tvp5150: Line mode registers = 0x%02x\n",
+ tvp5150_read(c, TVP5150_LINE_MODE_REG_15));
+ printk("tvp5150: Line mode registers = 0x%02x\n",
+ tvp5150_read(c, TVP5150_LINE_MODE_REG_16));
+ printk("tvp5150: Line mode registers = 0x%02x\n",
+ tvp5150_read(c, TVP5150_LINE_MODE_REG_17));
+ printk("tvp5150: Line mode registers = 0x%02x\n",
+ tvp5150_read(c, TVP5150_LINE_MODE_REG_18));
+ printk("tvp5150: Line mode registers = 0x%02x\n",
+ tvp5150_read(c, TVP5150_LINE_MODE_REG_19));
+ printk("tvp5150: Line mode registers = 0x%02x\n",
+ tvp5150_read(c, TVP5150_LINE_MODE_REG_20));
+ printk("tvp5150: Line mode registers = 0x%02x\n",
+ tvp5150_read(c, TVP5150_LINE_MODE_REG_21));
+ printk("tvp5150: Line mode registers = 0x%02x\n",
+ tvp5150_read(c, TVP5150_LINE_MODE_REG_22));
+ printk("tvp5150: Line mode registers = 0x%02x\n",
+ tvp5150_read(c, TVP5150_LINE_MODE_REG_23));
+ printk("tvp5150: Line mode registers = 0x%02x\n",
+ tvp5150_read(c, TVP5150_LINE_MODE_REG_24));
+ printk("tvp5150: Line mode registers = 0x%02x\n",
+ tvp5150_read(c, TVP5150_LINE_MODE_REG_25));
+ printk("tvp5150: Line mode registers = 0x%02x\n",
+ tvp5150_read(c, TVP5150_LINE_MODE_REG_27));
+ printk("tvp5150: Line mode registers = 0x%02x\n",
+ tvp5150_read(c, TVP5150_LINE_MODE_REG_28));
+ printk("tvp5150: Line mode registers = 0x%02x\n",
+ tvp5150_read(c, TVP5150_LINE_MODE_REG_29));
+ printk("tvp5150: Line mode registers = 0x%02x\n",
+ tvp5150_read(c, TVP5150_LINE_MODE_REG_30));
+ printk("tvp5150: Line mode registers = 0x%02x\n",
+ tvp5150_read(c, TVP5150_LINE_MODE_REG_31));
+ printk("tvp5150: Line mode registers = 0x%02x\n",
+ tvp5150_read(c, TVP5150_LINE_MODE_REG_32));
+ printk("tvp5150: Line mode registers = 0x%02x\n",
+ tvp5150_read(c, TVP5150_LINE_MODE_REG_33));
+ printk("tvp5150: Line mode registers = 0x%02x\n",
+ tvp5150_read(c, TVP5150_LINE_MODE_REG_34));
+ printk("tvp5150: Line mode registers = 0x%02x\n",
+ tvp5150_read(c, TVP5150_LINE_MODE_REG_35));
+ printk("tvp5150: Line mode registers = 0x%02x\n",
+ tvp5150_read(c, TVP5150_LINE_MODE_REG_36));
+ printk("tvp5150: Line mode registers = 0x%02x\n",
+ tvp5150_read(c, TVP5150_LINE_MODE_REG_37));
+ printk("tvp5150: Line mode registers = 0x%02x\n",
+ tvp5150_read(c, TVP5150_LINE_MODE_REG_38));
+ printk("tvp5150: Line mode registers = 0x%02x\n",
+ tvp5150_read(c, TVP5150_LINE_MODE_REG_39));
+ printk("tvp5150: Line mode registers = 0x%02x\n",
+ tvp5150_read(c, TVP5150_LINE_MODE_REG_40));
+ printk("tvp5150: Line mode registers = 0x%02x\n",
+ tvp5150_read(c, TVP5150_LINE_MODE_REG_41));
+ printk("tvp5150: Line mode registers = 0x%02x\n",
+ tvp5150_read(c, TVP5150_LINE_MODE_REG_42));
+ printk("tvp5150: Line mode registers = 0x%02x\n",
+ tvp5150_read(c, TVP5150_LINE_MODE_REG_43));
+ printk("tvp5150: Line mode registers = 0x%02x\n",
+ tvp5150_read(c, TVP5150_LINE_MODE_REG_44));
+ printk("tvp5150: Full field mode register = 0x%02x\n",
+ tvp5150_read(c, TVP5150_FULL_FIELD_MODE_REG));
+}
+
+/****************************************************************************
+ Basic functions
+ ****************************************************************************/
+enum tvp5150_input {
+ TVP5150_ANALOG_CH0 = 0,
+ TVP5150_SVIDEO = 1,
+ TVP5150_ANALOG_CH1 = 2,
+ TVP5150_BLACK_SCREEN = 8
+};
+
+static inline void tvp5150_selmux(struct i2c_client *c,
+ enum tvp5150_input input)
+{
+ struct tvp5150 *decoder = i2c_get_clientdata(c);
+
+ if (!decoder->enable)
+ input |= TVP5150_BLACK_SCREEN;
+
+ tvp5150_write(c, TVP5150_VD_IN_SRC_SEL_1, input);
+};
+
+static inline void tvp5150_reset(struct i2c_client *c)
+{
+ struct tvp5150 *decoder = i2c_get_clientdata(c);
+
+ tvp5150_write(c, TVP5150_CONF_SHARED_PIN, 2);
+
+ /* Automatic offset and AGC enabled */
+ tvp5150_write(c, TVP5150_ANAL_CHL_CTL, 0x15);
+
+ /* Normal Operation */
+// tvp5150_write(c, TVP5150_OP_MODE_CTL, 0x00);
+
+ /* Activate YCrCb output 0x9 or 0xd ? */
+ tvp5150_write(c, TVP5150_MISC_CTL, 0x6f);
+
+ /* Activates video std autodetection for all standards */
+ tvp5150_write(c, TVP5150_AUTOSW_MSK, 0x0);
+
+ /* Default format: 0x47, 4:2:2: 0x40 */
+ tvp5150_write(c, TVP5150_DATA_RATE_SEL, 0x47);
+
+ tvp5150_selmux(c, decoder->input);
+
+ tvp5150_write(c, TVP5150_CHROMA_PROC_CTL_1, 0x0c);
+ tvp5150_write(c, TVP5150_CHROMA_PROC_CTL_2, 0x54);
+
+ tvp5150_write(c, 0x27, 0x20); /* ?????????? */
+
+ tvp5150_write(c, TVP5150_VIDEO_STD, 0x0); /* Auto switch */
+
+ tvp5150_write(c, TVP5150_BRIGHT_CTL, decoder->bright >> 8);
+ tvp5150_write(c, TVP5150_CONTRAST_CTL, decoder->contrast >> 8);
+ tvp5150_write(c, TVP5150_SATURATION_CTL, decoder->contrast >> 8);
+ tvp5150_write(c, TVP5150_HUE_CTL, (decoder->hue - 32768) >> 8);
+};
+
+static int tvp5150_get_ctrl(struct i2c_client *c, struct v4l2_control *ctrl)
+{
+/* struct tvp5150 *decoder = i2c_get_clientdata(c); */
+
+ switch (ctrl->id) {
+ case V4L2_CID_BRIGHTNESS:
+ ctrl->value = tvp5150_read(c, TVP5150_BRIGHT_CTL);
+ return 0;
+ case V4L2_CID_CONTRAST:
+ ctrl->value = tvp5150_read(c, TVP5150_CONTRAST_CTL);
+ return 0;
+ case V4L2_CID_SATURATION:
+ ctrl->value = tvp5150_read(c, TVP5150_SATURATION_CTL);
+ return 0;
+ case V4L2_CID_HUE:
+ ctrl->value = tvp5150_read(c, TVP5150_HUE_CTL);
+ return 0;
+ default:
+ return -EINVAL;
+ }
+}
+
+static int tvp5150_set_ctrl(struct i2c_client *c, struct v4l2_control *ctrl)
+{
+/* struct tvp5150 *decoder = i2c_get_clientdata(c); */
+
+ switch (ctrl->id) {
+ case V4L2_CID_BRIGHTNESS:
+ tvp5150_write(c, TVP5150_BRIGHT_CTL, ctrl->value);
+ return 0;
+ case V4L2_CID_CONTRAST:
+ tvp5150_write(c, TVP5150_CONTRAST_CTL, ctrl->value);
+ return 0;
+ case V4L2_CID_SATURATION:
+ tvp5150_write(c, TVP5150_SATURATION_CTL, ctrl->value);
+ return 0;
+ case V4L2_CID_HUE:
+ tvp5150_write(c, TVP5150_HUE_CTL, ctrl->value);
+ return 0;
+ default:
+ return -EINVAL;
+ }
+}
+
+/****************************************************************************
+ I2C Command
+ ****************************************************************************/
+static int tvp5150_command(struct i2c_client *client,
+ unsigned int cmd, void *arg)
+{
+ struct tvp5150 *decoder = i2c_get_clientdata(client);
+
+ switch (cmd) {
+
+ case 0:
+ case DECODER_INIT:
+ tvp5150_reset(client);
+ break;
+
+ case DECODER_DUMP:
+ dump_reg(client);
+ break;
+
+ case DECODER_GET_CAPABILITIES:
+ {
+ struct video_decoder_capability *cap = arg;
+
+ cap->flags = VIDEO_DECODER_PAL |
+ VIDEO_DECODER_NTSC |
+ VIDEO_DECODER_SECAM |
+ VIDEO_DECODER_AUTO | VIDEO_DECODER_CCIR;
+ cap->inputs = 3;
+ cap->outputs = 1;
+ break;
+ }
+ case DECODER_GET_STATUS:
+ {
+ break;
+ }
+
+ case DECODER_SET_GPIO:
+ break;
+
+ case DECODER_SET_VBI_BYPASS:
+ break;
+
+ case DECODER_SET_NORM:
+ {
+ int *iarg = arg;
+
+ switch (*iarg) {
+
+ case VIDEO_MODE_NTSC:
+ break;
+
+ case VIDEO_MODE_PAL:
+ break;
+
+ case VIDEO_MODE_SECAM:
+ break;
+
+ case VIDEO_MODE_AUTO:
+ break;
+
+ default:
+ return -EINVAL;
+
+ }
+ decoder->norm = *iarg;
+ break;
+ }
+ case DECODER_SET_INPUT:
+ {
+ int *iarg = arg;
+ if (*iarg < 0 || *iarg > 3) {
+ return -EINVAL;
+ }
+
+ decoder->input = *iarg;
+ tvp5150_selmux(client, decoder->input);
+
+ break;
+ }
+ case DECODER_SET_OUTPUT:
+ {
+ int *iarg = arg;
+
+ /* not much choice of outputs */
+ if (*iarg != 0) {
+ return -EINVAL;
+ }
+ break;
+ }
+ case DECODER_ENABLE_OUTPUT:
+ {
+ int *iarg = arg;
+
+ decoder->enable = (*iarg != 0);
+
+ tvp5150_selmux(client, decoder->input);
+
+ break;
+ }
+ case VIDIOC_QUERYCTRL:
+ {
+ struct v4l2_queryctrl *qc = arg;
+ u8 i, n;
+
+ dprintk(1, KERN_DEBUG "VIDIOC_QUERYCTRL");
+
+ n = sizeof(tvp5150_qctrl) / sizeof(tvp5150_qctrl[0]);
+ for (i = 0; i < n; i++)
+ if (qc->id && qc->id == tvp5150_qctrl[i].id) {
+ memcpy(qc, &(tvp5150_qctrl[i]),
+ sizeof(*qc));
+ return 0;
+ }
+
+ return -EINVAL;
+ }
+ case VIDIOC_G_CTRL:
+ {
+ struct v4l2_control *ctrl = arg;
+ dprintk(1, KERN_DEBUG "VIDIOC_G_CTRL");
+
+ return tvp5150_get_ctrl(client, ctrl);
+ }
+ case VIDIOC_S_CTRL_OLD: /* ??? */
+ case VIDIOC_S_CTRL:
+ {
+ struct v4l2_control *ctrl = arg;
+ u8 i, n;
+ dprintk(1, KERN_DEBUG "VIDIOC_S_CTRL");
+ n = sizeof(tvp5150_qctrl) / sizeof(tvp5150_qctrl[0]);
+ for (i = 0; i < n; i++)
+ if (ctrl->id == tvp5150_qctrl[i].id) {
+ if (ctrl->value <
+ tvp5150_qctrl[i].minimum
+ || ctrl->value >
+ tvp5150_qctrl[i].maximum)
+ return -ERANGE;
+ dprintk(1,
+ KERN_DEBUG
+ "VIDIOC_S_CTRL: id=%d, value=%d",
+ ctrl->id, ctrl->value);
+ return tvp5150_set_ctrl(client, ctrl);
+ }
+ return -EINVAL;
+ }
+
+ case DECODER_SET_PICTURE:
+ {
+ struct video_picture *pic = arg;
+ if (decoder->bright != pic->brightness) {
+ /* We want 0 to 255 we get 0-65535 */
+ decoder->bright = pic->brightness;
+ tvp5150_write(client, TVP5150_BRIGHT_CTL,
+ decoder->bright >> 8);
+ }
+ if (decoder->contrast != pic->contrast) {
+ /* We want 0 to 255 we get 0-65535 */
+ decoder->contrast = pic->contrast;
+ tvp5150_write(client, TVP5150_CONTRAST_CTL,
+ decoder->contrast >> 8);
+ }
+ if (decoder->sat != pic->colour) {
+ /* We want 0 to 255 we get 0-65535 */
+ decoder->sat = pic->colour;
+ tvp5150_write(client, TVP5150_SATURATION_CTL,
+ decoder->contrast >> 8);
+ }
+ if (decoder->hue != pic->hue) {
+ /* We want -128 to 127 we get 0-65535 */
+ decoder->hue = pic->hue;
+ tvp5150_write(client, TVP5150_HUE_CTL,
+ (decoder->hue - 32768) >> 8);
+ }
+ break;
+ }
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+/****************************************************************************
+ I2C Client & Driver
+ ****************************************************************************/
+static struct i2c_driver driver;
+
+static struct i2c_client client_template = {
+ .name = "(unset)",
+ .flags = I2C_CLIENT_ALLOW_USE,
+ .driver = &driver,
+};
+
+static int tvp5150_detect_client(struct i2c_adapter *adapter,
+ int address, int kind)
+{
+ struct i2c_client *client;
+ struct tvp5150 *core;
+ int rv;
+
+ dprintk(1,
+ KERN_INFO
+ "tvp5150.c: detecting tvp5150 client on address 0x%x\n",
+ address << 1);
+
+ client_template.adapter = adapter;
+ client_template.addr = address;
+
+ /* Check if the adapter supports the needed features */
+ if (!i2c_check_functionality
+ (adapter,
+ I2C_FUNC_SMBUS_READ_BYTE | I2C_FUNC_SMBUS_WRITE_BYTE_DATA))
+ return 0;
+
+ client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
+ if (client == 0)
+ return -ENOMEM;
+ memcpy(client, &client_template, sizeof(struct i2c_client));
+
+ core = kmalloc(sizeof(struct tvp5150), GFP_KERNEL);
+ if (core == 0) {
+ kfree(client);
+ return -ENOMEM;
+ }
+ memset(core, 0, sizeof(struct tvp5150));
+ i2c_set_clientdata(client, core);
+
+ rv = i2c_attach_client(client);
+
+ core->norm = VIDEO_MODE_AUTO;
+ core->input = 2;
+ core->enable = 1;
+ core->bright = 32768;
+ core->contrast = 32768;
+ core->hue = 32768;
+ core->sat = 32768;
+
+ if (rv) {
+ kfree(client);
+ kfree(core);
+ return rv;
+ }
+
+ if (debug > 1)
+ dump_reg(client);
+
+ return 0;
+}
+
+static int tvp5150_attach_adapter(struct i2c_adapter *adapter)
+{
+ dprintk(1,
+ KERN_INFO
+ "tvp5150.c: starting probe for adapter %s (0x%x)\n",
+ adapter->name, adapter->id);
+ return i2c_probe(adapter, &addr_data, &tvp5150_detect_client);
+}
+
+static int tvp5150_detach_client(struct i2c_client *client)
+{
+ struct tvp5150 *decoder = i2c_get_clientdata(client);
+ int err;
+
+ err = i2c_detach_client(client);
+ if (err) {
+ return err;
+ }
+
+ kfree(decoder);
+ kfree(client);
+
+ return 0;
+}
+
+/* ----------------------------------------------------------------------- */
+
+static struct i2c_driver driver = {
+ .owner = THIS_MODULE,
+ .name = "tvp5150",
+
+ /* FIXME */
+ .id = I2C_DRIVERID_SAA7110,
+ .flags = I2C_DF_NOTIFY,
+
+ .attach_adapter = tvp5150_attach_adapter,
+ .detach_client = tvp5150_detach_client,
+
+ .command = tvp5150_command,
+};
+
+static int __init tvp5150_init(void)
+{
+ return i2c_add_driver(&driver);
+}
+
+static void __exit tvp5150_exit(void)
+{
+ i2c_del_driver(&driver);
+}
+
+module_init(tvp5150_init);
+module_exit(tvp5150_exit);
diff --git a/drivers/media/video/tvp5150_reg.h b/drivers/media/video/tvp5150_reg.h
new file mode 100644
index 000000000000..cd45c1ded786
--- /dev/null
+++ b/drivers/media/video/tvp5150_reg.h
@@ -0,0 +1,173 @@
+#define TVP5150_VD_IN_SRC_SEL_1 0x00 /* Video input source selection #1 */
+#define TVP5150_ANAL_CHL_CTL 0x01 /* Analog channel controls */
+#define TVP5150_OP_MODE_CTL 0x02 /* Operation mode controls */
+#define TVP5150_MISC_CTL 0x03 /* Miscellaneous controls */
+#define TVP5150_AUTOSW_MSK 0x04 /* Autoswitch mask: TVP5150A / TVP5150AM */
+
+/* Reserved 05h */
+
+#define TVP5150_COLOR_KIL_THSH_CTL 0x06 /* Color killer threshold control */
+#define TVP5150_LUMA_PROC_CTL_1 0x07 /* Luminance processing control #1 */
+#define TVP5150_LUMA_PROC_CTL_2 0x08 /* Luminance processing control #2 */
+#define TVP5150_BRIGHT_CTL 0x09 /* Brightness control */
+#define TVP5150_SATURATION_CTL 0x0a /* Color saturation control */
+#define TVP5150_HUE_CTL 0x0b /* Hue control */
+#define TVP5150_CONTRAST_CTL 0x0c /* Contrast control */
+#define TVP5150_DATA_RATE_SEL 0x0d /* Outputs and data rates select */
+#define TVP5150_LUMA_PROC_CTL_3 0x0e /* Luminance processing control #3 */
+#define TVP5150_CONF_SHARED_PIN 0x0f /* Configuration shared pins */
+
+/* Reserved 10h */
+
+#define TVP5150_ACT_VD_CROP_ST_MSB 0x11 /* Active video cropping start MSB */
+#define TVP5150_ACT_VD_CROP_ST_LSB 0x12 /* Active video cropping start LSB */
+#define TVP5150_ACT_VD_CROP_STP_MSB 0x13 /* Active video cropping stop MSB */
+#define TVP5150_ACT_VD_CROP_STP_LSB 0x14 /* Active video cropping stop LSB */
+#define TVP5150_GENLOCK 0x15 /* Genlock/RTC */
+#define TVP5150_HORIZ_SYNC_START 0x16 /* Horizontal sync start */
+
+/* Reserved 17h */
+
+#define TVP5150_VERT_BLANKING_START 0x18 /* Vertical blanking start */
+#define TVP5150_VERT_BLANKING_STOP 0x19 /* Vertical blanking stop */
+#define TVP5150_CHROMA_PROC_CTL_1 0x1a /* Chrominance processing control #1 */
+#define TVP5150_CHROMA_PROC_CTL_2 0x1b /* Chrominance processing control #2 */
+#define TVP5150_INT_RESET_REG_B 0x1c /* Interrupt reset register B */
+#define TVP5150_INT_ENABLE_REG_B 0x1d /* Interrupt enable register B */
+#define TVP5150_INTT_CONFIG_REG_B 0x1e /* Interrupt configuration register B */
+
+/* Reserved 1Fh-27h */
+
+#define TVP5150_VIDEO_STD 0x28 /* Video standard */
+
+/* Reserved 29h-2bh */
+
+#define TVP5150_CB_GAIN_FACT 0x2c /* Cb gain factor */
+#define TVP5150_CR_GAIN_FACTOR 0x2d /* Cr gain factor */
+#define TVP5150_MACROVISION_ON_CTR 0x2e /* Macrovision on counter */
+#define TVP5150_MACROVISION_OFF_CTR 0x2f /* Macrovision off counter */
+#define TVP5150_REV_SELECT 0x30 /* revision select (TVP5150AM1 only) */
+
+/* Reserved 31h-7Fh */
+
+#define TVP5150_MSB_DEV_ID 0x80 /* MSB of device ID */
+#define TVP5150_LSB_DEV_ID 0x81 /* LSB of device ID */
+#define TVP5150_ROM_MAJOR_VER 0x82 /* ROM major version */
+#define TVP5150_ROM_MINOR_VER 0x83 /* ROM minor version */
+#define TVP5150_VERT_LN_COUNT_MSB 0x84 /* Vertical line count MSB */
+#define TVP5150_VERT_LN_COUNT_LSB 0x85 /* Vertical line count LSB */
+#define TVP5150_INT_STATUS_REG_B 0x86 /* Interrupt status register B */
+#define TVP5150_INT_ACTIVE_REG_B 0x87 /* Interrupt active register B */
+#define TVP5150_STATUS_REG_1 0x88 /* Status register #1 */
+#define TVP5150_STATUS_REG_2 0x89 /* Status register #2 */
+#define TVP5150_STATUS_REG_3 0x8a /* Status register #3 */
+#define TVP5150_STATUS_REG_4 0x8b /* Status register #4 */
+#define TVP5150_STATUS_REG_5 0x8c /* Status register #5 */
+/* Reserved 8Dh-8Fh */
+#define TVP5150_CC_DATA_REG1 0x90 /* Closed caption data registers */
+#define TVP5150_CC_DATA_REG2 0x91 /* Closed caption data registers */
+#define TVP5150_CC_DATA_REG3 0x92 /* Closed caption data registers */
+#define TVP5150_CC_DATA_REG4 0x93 /* Closed caption data registers */
+#define TVP5150_WSS_DATA_REG1 0X94 /* WSS data registers */
+#define TVP5150_WSS_DATA_REG2 0X95 /* WSS data registers */
+#define TVP5150_WSS_DATA_REG3 0X96 /* WSS data registers */
+#define TVP5150_WSS_DATA_REG4 0X97 /* WSS data registers */
+#define TVP5150_WSS_DATA_REG5 0X98 /* WSS data registers */
+#define TVP5150_WSS_DATA_REG6 0X99 /* WSS data registers */
+#define TVP5150_VPS_DATA_REG1 0x9a /* VPS data registers */
+#define TVP5150_VPS_DATA_REG2 0x9b /* VPS data registers */
+#define TVP5150_VPS_DATA_REG3 0x9c /* VPS data registers */
+#define TVP5150_VPS_DATA_REG4 0x9d /* VPS data registers */
+#define TVP5150_VPS_DATA_REG5 0x9e /* VPS data registers */
+#define TVP5150_VPS_DATA_REG6 0x9f /* VPS data registers */
+#define TVP5150_VPS_DATA_REG7 0xa0 /* VPS data registers */
+#define TVP5150_VPS_DATA_REG8 0xa1 /* VPS data registers */
+#define TVP5150_VPS_DATA_REG9 0xa2 /* VPS data registers */
+#define TVP5150_VPS_DATA_REG10 0xa3 /* VPS data registers */
+#define TVP5150_VPS_DATA_REG11 0xa4 /* VPS data registers */
+#define TVP5150_VPS_DATA_REG12 0xa5 /* VPS data registers */
+#define TVP5150_VPS_DATA_REG13 0xa6 /* VPS data registers */
+#define TVP5150_VITC_DATA_REG1 0xa7 /* VITC data registers */
+#define TVP5150_VITC_DATA_REG2 0xa8 /* VITC data registers */
+#define TVP5150_VITC_DATA_REG3 0xa9 /* VITC data registers */
+#define TVP5150_VITC_DATA_REG4 0xaa /* VITC data registers */
+#define TVP5150_VITC_DATA_REG5 0xab /* VITC data registers */
+#define TVP5150_VITC_DATA_REG6 0xac /* VITC data registers */
+#define TVP5150_VITC_DATA_REG7 0xad /* VITC data registers */
+#define TVP5150_VITC_DATA_REG8 0xae /* VITC data registers */
+#define TVP5150_VITC_DATA_REG9 0xaf /* VITC data registers */
+#define TVP5150_VBI_FIFO_READ_DATA 0xb0 /* VBI FIFO read data */
+#define TVP5150_TELETEXT_FIL_1_1 0xb1 /* Teletext filter 1 */
+#define TVP5150_TELETEXT_FIL_1_2 0xb2 /* Teletext filter 1 */
+#define TVP5150_TELETEXT_FIL_1_3 0xb3 /* Teletext filter 1 */
+#define TVP5150_TELETEXT_FIL_1_4 0xb4 /* Teletext filter 1 */
+#define TVP5150_TELETEXT_FIL_1_5 0xb5 /* Teletext filter 1 */
+#define TVP5150_TELETEXT_FIL_2_1 0xb6 /* Teletext filter 2 */
+#define TVP5150_TELETEXT_FIL_2_2 0xb7 /* Teletext filter 2 */
+#define TVP5150_TELETEXT_FIL_2_3 0xb8 /* Teletext filter 2 */
+#define TVP5150_TELETEXT_FIL_2_4 0xb9 /* Teletext filter 2 */
+#define TVP5150_TELETEXT_FIL_2_5 0xba /* Teletext filter 2 */
+#define TVP5150_TELETEXT_FIL_ENA 0xbb /* Teletext filter enable */
+/* Reserved BCh-BFh */
+#define TVP5150_INT_STATUS_REG_A 0xc0 /* Interrupt status register A */
+#define TVP5150_INT_ENABLE_REG_A 0xc1 /* Interrupt enable register A */
+#define TVP5150_INT_CONF 0xc2 /* Interrupt configuration */
+#define TVP5150_VDP_CONF_RAM_DATA 0xc3 /* VDP configuration RAM data */
+#define TVP5150_CONF_RAM_ADDR_LOW 0xc4 /* Configuration RAM address low byte */
+#define TVP5150_CONF_RAM_ADDR_HIGH 0xc5 /* Configuration RAM address high byte */
+#define TVP5150_VDP_STATUS_REG 0xc6 /* VDP status register */
+#define TVP5150_FIFO_WORD_COUNT 0xc7 /* FIFO word count */
+#define TVP5150_FIFO_INT_THRESHOLD 0xc8 /* FIFO interrupt threshold */
+#define TVP5150_FIFO_RESET 0xc9 /* FIFO reset */
+#define TVP5150_LINE_NUMBER_INT 0xca /* Line number interrupt */
+#define TVP5150_PIX_ALIGN_REG_LOW 0xcb /* Pixel alignment register low byte */
+#define TVP5150_PIX_ALIGN_REG_HIGH 0xcc /* Pixel alignment register high byte */
+#define TVP5150_FIFO_OUT_CTRL 0xcd /* FIFO output control */
+/* Reserved CEh */
+#define TVP5150_FULL_FIELD_ENA_1 0xcf /* Full field enable 1 */
+#define TVP5150_FULL_FIELD_ENA_2 0xd0 /* Full field enable 2 */
+#define TVP5150_LINE_MODE_REG_1 0xd1 /* Line mode registers */
+#define TVP5150_LINE_MODE_REG_2 0xd2 /* Line mode registers */
+#define TVP5150_LINE_MODE_REG_3 0xd3 /* Line mode registers */
+#define TVP5150_LINE_MODE_REG_4 0xd4 /* Line mode registers */
+#define TVP5150_LINE_MODE_REG_5 0xd5 /* Line mode registers */
+#define TVP5150_LINE_MODE_REG_6 0xd6 /* Line mode registers */
+#define TVP5150_LINE_MODE_REG_7 0xd7 /* Line mode registers */
+#define TVP5150_LINE_MODE_REG_8 0xd8 /* Line mode registers */
+#define TVP5150_LINE_MODE_REG_9 0xd9 /* Line mode registers */
+#define TVP5150_LINE_MODE_REG_10 0xda /* Line mode registers */
+#define TVP5150_LINE_MODE_REG_11 0xdb /* Line mode registers */
+#define TVP5150_LINE_MODE_REG_12 0xdc /* Line mode registers */
+#define TVP5150_LINE_MODE_REG_13 0xdd /* Line mode registers */
+#define TVP5150_LINE_MODE_REG_14 0xde /* Line mode registers */
+#define TVP5150_LINE_MODE_REG_15 0xdf /* Line mode registers */
+#define TVP5150_LINE_MODE_REG_16 0xe0 /* Line mode registers */
+#define TVP5150_LINE_MODE_REG_17 0xe1 /* Line mode registers */
+#define TVP5150_LINE_MODE_REG_18 0xe2 /* Line mode registers */
+#define TVP5150_LINE_MODE_REG_19 0xe3 /* Line mode registers */
+#define TVP5150_LINE_MODE_REG_20 0xe4 /* Line mode registers */
+#define TVP5150_LINE_MODE_REG_21 0xe5 /* Line mode registers */
+#define TVP5150_LINE_MODE_REG_22 0xe6 /* Line mode registers */
+#define TVP5150_LINE_MODE_REG_23 0xe7 /* Line mode registers */
+#define TVP5150_LINE_MODE_REG_24 0xe8 /* Line mode registers */
+#define TVP5150_LINE_MODE_REG_25 0xe9 /* Line mode registers */
+#define TVP5150_LINE_MODE_REG_27 0xea /* Line mode registers */
+#define TVP5150_LINE_MODE_REG_28 0xeb /* Line mode registers */
+#define TVP5150_LINE_MODE_REG_29 0xec /* Line mode registers */
+#define TVP5150_LINE_MODE_REG_30 0xed /* Line mode registers */
+#define TVP5150_LINE_MODE_REG_31 0xee /* Line mode registers */
+#define TVP5150_LINE_MODE_REG_32 0xef /* Line mode registers */
+#define TVP5150_LINE_MODE_REG_33 0xf0 /* Line mode registers */
+#define TVP5150_LINE_MODE_REG_34 0xf1 /* Line mode registers */
+#define TVP5150_LINE_MODE_REG_35 0xf2 /* Line mode registers */
+#define TVP5150_LINE_MODE_REG_36 0xf3 /* Line mode registers */
+#define TVP5150_LINE_MODE_REG_37 0xf4 /* Line mode registers */
+#define TVP5150_LINE_MODE_REG_38 0xf5 /* Line mode registers */
+#define TVP5150_LINE_MODE_REG_39 0xf6 /* Line mode registers */
+#define TVP5150_LINE_MODE_REG_40 0xf7 /* Line mode registers */
+#define TVP5150_LINE_MODE_REG_41 0xf8 /* Line mode registers */
+#define TVP5150_LINE_MODE_REG_42 0xf9 /* Line mode registers */
+#define TVP5150_LINE_MODE_REG_43 0xfa /* Line mode registers */
+#define TVP5150_LINE_MODE_REG_44 0xfb /* Line mode registers */
+#define TVP5150_FULL_FIELD_MODE_REG 0xfc /* Full field mode register */
+/* Reserved FDh-FFh */
diff --git a/drivers/media/video/v4l1-compat.c b/drivers/media/video/v4l1-compat.c
index 59bb71381a1b..4134549d11a8 100644
--- a/drivers/media/video/v4l1-compat.c
+++ b/drivers/media/video/v4l1-compat.c
@@ -708,7 +708,7 @@ v4l_compat_translate_ioctl(struct inode *inode,
}
case VIDIOCGFREQ: /* get frequency */
{
- int *freq = arg;
+ unsigned long *freq = arg;
freq2.tuner = 0;
err = drv(inode, file, VIDIOC_G_FREQUENCY, &freq2);
@@ -720,7 +720,7 @@ v4l_compat_translate_ioctl(struct inode *inode,
}
case VIDIOCSFREQ: /* set frequency */
{
- int *freq = arg;
+ unsigned long *freq = arg;
freq2.tuner = 0;
drv(inode, file, VIDIOC_G_FREQUENCY, &freq2);
@@ -960,7 +960,7 @@ v4l_compat_translate_ioctl(struct inode *inode,
fmt->start[1] = fmt2->fmt.vbi.start[1];
fmt->count[1] = fmt2->fmt.vbi.count[1];
fmt->flags = fmt2->fmt.vbi.flags & 0x03;
- break;
+ break;
}
case VIDIOCSVBIFMT:
{
@@ -1006,10 +1006,8 @@ v4l_compat_translate_ioctl(struct inode *inode,
break;
}
- if (cap2)
- kfree(cap2);
- if (fmt2)
- kfree(fmt2);
+ kfree(cap2);
+ kfree(fmt2);
return err;
}
diff --git a/drivers/media/video/video-buf.c b/drivers/media/video/video-buf.c
index 574b8e36f3c6..acfd3a103f35 100644
--- a/drivers/media/video/video-buf.c
+++ b/drivers/media/video/video-buf.c
@@ -147,7 +147,7 @@ int videobuf_dma_init_user(struct videobuf_dmabuf *dma, int direction,
data,size,dma->nr_pages);
down_read(&current->mm->mmap_sem);
- err = get_user_pages(current,current->mm,
+ err = get_user_pages(current,current->mm,
data & PAGE_MASK, dma->nr_pages,
rw == READ, 1, /* force */
dma->pages, NULL);
@@ -750,9 +750,9 @@ videobuf_read_zerocopy(struct videobuf_queue *q, char __user *data,
{
enum v4l2_field field;
unsigned long flags;
- int retval;
+ int retval;
- /* setup stuff */
+ /* setup stuff */
retval = -ENOMEM;
q->read_buf = videobuf_alloc(q->msize);
if (NULL == q->read_buf)
@@ -760,18 +760,18 @@ videobuf_read_zerocopy(struct videobuf_queue *q, char __user *data,
q->read_buf->memory = V4L2_MEMORY_USERPTR;
q->read_buf->baddr = (unsigned long)data;
- q->read_buf->bsize = count;
+ q->read_buf->bsize = count;
field = videobuf_next_field(q);
retval = q->ops->buf_prepare(q,q->read_buf,field);
if (0 != retval)
goto done;
- /* start capture & wait */
+ /* start capture & wait */
spin_lock_irqsave(q->irqlock,flags);
q->ops->buf_queue(q,q->read_buf);
spin_unlock_irqrestore(q->irqlock,flags);
- retval = videobuf_waiton(q->read_buf,0,0);
- if (0 == retval) {
+ retval = videobuf_waiton(q->read_buf,0,0);
+ if (0 == retval) {
videobuf_dma_pci_sync(q->pci,&q->read_buf->dma);
if (STATE_ERROR == q->read_buf->state)
retval = -EIO;
@@ -828,7 +828,7 @@ ssize_t videobuf_read_one(struct videobuf_queue *q,
}
/* wait until capture is done */
- retval = videobuf_waiton(q->read_buf, nonblocking, 1);
+ retval = videobuf_waiton(q->read_buf, nonblocking, 1);
if (0 != retval)
goto done;
videobuf_dma_pci_sync(q->pci,&q->read_buf->dma);
@@ -1096,7 +1096,7 @@ videobuf_vm_nopage(struct vm_area_struct *vma, unsigned long vaddr,
dprintk(3,"nopage: fault @ %08lx [vma %08lx-%08lx]\n",
vaddr,vma->vm_start,vma->vm_end);
- if (vaddr > vma->vm_end)
+ if (vaddr > vma->vm_end)
return NOPAGE_SIGBUS;
page = alloc_page(GFP_USER);
if (!page)
diff --git a/drivers/media/video/videocodec.c b/drivers/media/video/videocodec.c
index c9d5f1a873cc..839db622040d 100644
--- a/drivers/media/video/videocodec.c
+++ b/drivers/media/video/videocodec.c
@@ -353,8 +353,7 @@ videocodec_build_table (void)
dprintk(3, "videocodec_build table: %d entries, %d bytes\n", i,
size);
- if (videocodec_buf)
- kfree(videocodec_buf);
+ kfree(videocodec_buf);
videocodec_buf = (char *) kmalloc(size, GFP_KERNEL);
i = 0;
@@ -471,8 +470,7 @@ videocodec_exit (void)
{
#ifdef CONFIG_PROC_FS
remove_proc_entry("videocodecs", NULL);
- if (videocodec_buf)
- kfree(videocodec_buf);
+ kfree(videocodec_buf);
#endif
}
diff --git a/drivers/media/video/videodev.c b/drivers/media/video/videodev.c
index 06df15f75de9..83c49f9610d0 100644
--- a/drivers/media/video/videodev.c
+++ b/drivers/media/video/videodev.c
@@ -215,8 +215,7 @@ video_usercopy(struct inode *inode, struct file *file,
}
out:
- if (mbuf)
- kfree(mbuf);
+ kfree(mbuf);
return err;
}
diff --git a/drivers/media/video/vino.c b/drivers/media/video/vino.c
index d8a0f763ca10..71b28e9e0850 100644
--- a/drivers/media/video/vino.c
+++ b/drivers/media/video/vino.c
@@ -12,28 +12,25 @@
/*
* TODO:
- * - remove "hacks" from memory allocation code and implement nopage()
+ * - remove "mark pages reserved-hacks" from memory allocation code
+ * and implement nopage()
* - check decimation, calculating and reporting image size when
* using decimation
- * - check vino_acquire_input(), vino_set_input() and channel
- * ownership handling
- * - report VINO error-interrupts via ioctls ?
- * - implement picture controls (all implemented?)
- * - use macros for boolean values (?)
- * - implement user mode buffers and overlay (?)
+ * - implement read(), user mode buffers and overlay (?)
*/
#include <linux/init.h>
#include <linux/module.h>
#include <linux/delay.h>
+#include <linux/dma-mapping.h>
#include <linux/errno.h>
#include <linux/fs.h>
+#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/mm.h>
-#include <linux/interrupt.h>
-#include <linux/dma-mapping.h>
-#include <linux/time.h>
#include <linux/moduleparam.h>
+#include <linux/time.h>
+#include <linux/version.h>
#ifdef CONFIG_KMOD
#include <linux/kmod.h>
@@ -59,18 +56,16 @@
* debug info.
* Note that the debug output also slows down the driver significantly */
// #define VINO_DEBUG
+// #define VINO_DEBUG_INT
-#define VINO_MODULE_VERSION "0.0.3"
-#define VINO_VERSION_CODE KERNEL_VERSION(0, 0, 3)
+#define VINO_MODULE_VERSION "0.0.5"
+#define VINO_VERSION_CODE KERNEL_VERSION(0, 0, 5)
MODULE_DESCRIPTION("SGI VINO Video4Linux2 driver");
MODULE_VERSION(VINO_MODULE_VERSION);
MODULE_AUTHOR("Mikael Nousiainen <tmnousia@cc.hut.fi>");
MODULE_LICENSE("GPL");
-#define mem_map_reserve(p) set_bit(PG_reserved, &((p)->flags))
-#define mem_map_unreserve(p) clear_bit(PG_reserved, &((p)->flags))
-
#ifdef VINO_DEBUG
#define dprintk(x...) printk("VINO: " x);
#else
@@ -90,15 +85,16 @@ MODULE_LICENSE("GPL");
#define VINO_MIN_HEIGHT 32
#define VINO_CLIPPING_START_ODD_D1 1
-#define VINO_CLIPPING_START_ODD_PAL 1
-#define VINO_CLIPPING_START_ODD_NTSC 1
+#define VINO_CLIPPING_START_ODD_PAL 15
+#define VINO_CLIPPING_START_ODD_NTSC 12
#define VINO_CLIPPING_START_EVEN_D1 2
-#define VINO_CLIPPING_START_EVEN_PAL 2
-#define VINO_CLIPPING_START_EVEN_NTSC 2
+#define VINO_CLIPPING_START_EVEN_PAL 15
+#define VINO_CLIPPING_START_EVEN_NTSC 12
#define VINO_INPUT_CHANNEL_COUNT 3
+/* the number is the index for vino_inputs */
#define VINO_INPUT_NONE -1
#define VINO_INPUT_COMPOSITE 0
#define VINO_INPUT_SVIDEO 1
@@ -106,15 +102,13 @@ MODULE_LICENSE("GPL");
#define VINO_PAGE_RATIO (PAGE_SIZE / VINO_PAGE_SIZE)
-#define VINO_FIFO_THRESHOLD_DEFAULT 512
+#define VINO_FIFO_THRESHOLD_DEFAULT 16
-/*#define VINO_FRAMEBUFFER_SIZE (VINO_PAL_WIDTH * VINO_PAL_HEIGHT * 4 \
- + 2 * PAGE_SIZE)*/
#define VINO_FRAMEBUFFER_SIZE ((VINO_PAL_WIDTH \
* VINO_PAL_HEIGHT * 4 \
+ 3 * PAGE_SIZE) & ~(PAGE_SIZE - 1))
-#define VINO_FRAMEBUFFER_MAX_COUNT 8
+#define VINO_FRAMEBUFFER_COUNT_MAX 8
#define VINO_FRAMEBUFFER_UNUSED 0
#define VINO_FRAMEBUFFER_IN_USE 1
@@ -130,24 +124,27 @@ MODULE_LICENSE("GPL");
#define VINO_DUMMY_DESC_COUNT 4
#define VINO_DESC_FETCH_DELAY 5 /* microseconds */
+#define VINO_MAX_FRAME_SKIP_COUNT 128
+
/* the number is the index for vino_data_formats */
#define VINO_DATA_FMT_NONE -1
#define VINO_DATA_FMT_GREY 0
#define VINO_DATA_FMT_RGB332 1
#define VINO_DATA_FMT_RGB32 2
#define VINO_DATA_FMT_YUV 3
-//#define VINO_DATA_FMT_RGB24 4
#define VINO_DATA_FMT_COUNT 4
+/* the number is the index for vino_data_norms */
#define VINO_DATA_NORM_NONE -1
#define VINO_DATA_NORM_NTSC 0
#define VINO_DATA_NORM_PAL 1
#define VINO_DATA_NORM_SECAM 2
#define VINO_DATA_NORM_D1 3
-/* The following is a special entry that can be used to
+/* The following are special entries that can be used to
* autodetect the norm. */
-#define VINO_DATA_NORM_AUTO 0xff
+#define VINO_DATA_NORM_AUTO 0xfe
+#define VINO_DATA_NORM_AUTO_EXT 0xff
#define VINO_DATA_NORM_COUNT 4
@@ -231,7 +228,7 @@ struct vino_framebuffer_fifo {
unsigned int head;
unsigned int tail;
- unsigned int data[VINO_FRAMEBUFFER_MAX_COUNT];
+ unsigned int data[VINO_FRAMEBUFFER_COUNT_MAX];
};
struct vino_framebuffer_queue {
@@ -245,13 +242,20 @@ struct vino_framebuffer_queue {
struct vino_framebuffer_fifo in;
struct vino_framebuffer_fifo out;
- struct vino_framebuffer *buffer[VINO_FRAMEBUFFER_MAX_COUNT];
+ struct vino_framebuffer *buffer[VINO_FRAMEBUFFER_COUNT_MAX];
spinlock_t queue_lock;
struct semaphore queue_sem;
wait_queue_head_t frame_wait_queue;
};
+struct vino_interrupt_data {
+ struct timeval timestamp;
+ unsigned int frame_counter;
+ unsigned int skip_count;
+ unsigned int skip;
+};
+
struct vino_channel_settings {
unsigned int channel;
@@ -284,6 +288,8 @@ struct vino_channel_settings {
unsigned int users;
+ struct vino_interrupt_data int_data;
+
/* V4L support */
struct video_device *v4l_device;
};
@@ -314,7 +320,7 @@ struct vino_settings {
/* Module parameters */
/*
- * Using vino_pixel_conversion the ARGB32-format pixels supplied
+ * Using vino_pixel_conversion the ABGR32-format pixels supplied
* by the VINO chip can be converted to more common formats
* like RGBA32 (or probably RGB24 in the future). This way we
* can give out data that can be specified correctly with
@@ -328,7 +334,9 @@ struct vino_settings {
* Use non-zero value to enable conversion.
*/
static int vino_pixel_conversion = 0;
+
module_param_named(pixelconv, vino_pixel_conversion, int, 0);
+
MODULE_PARM_DESC(pixelconv,
"enable pixel conversion (non-zero value enables)");
@@ -344,15 +352,22 @@ static const char *vino_bus_name = "GIO64 bus";
static const char *vino_v4l_device_name_a = "SGI VINO Channel A";
static const char *vino_v4l_device_name_b = "SGI VINO Channel B";
+static void vino_capture_tasklet(unsigned long channel);
+
+DECLARE_TASKLET(vino_tasklet_a, vino_capture_tasklet, VINO_CHANNEL_A);
+DECLARE_TASKLET(vino_tasklet_b, vino_capture_tasklet, VINO_CHANNEL_B);
+
static const struct vino_input vino_inputs[] = {
{
.name = "Composite",
- .std = V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM,
+ .std = V4L2_STD_NTSC | V4L2_STD_PAL
+ | V4L2_STD_SECAM,
},{
.name = "S-Video",
- .std = V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM,
+ .std = V4L2_STD_NTSC | V4L2_STD_PAL
+ | V4L2_STD_SECAM,
},{
- .name = "D1 (IndyCam)",
+ .name = "D1/IndyCam",
.std = V4L2_STD_NTSC,
}
};
@@ -375,15 +390,10 @@ static const struct vino_data_format vino_data_formats[] = {
.colorspace = V4L2_COLORSPACE_SRGB,
},{
.description = "YUV 4:2:2",
- .bpp = 4,
+ .bpp = 2,
.pixelformat = V4L2_PIX_FMT_YUYV, // XXX: swapped?
.colorspace = V4L2_COLORSPACE_SMPTE170M,
- }/*,{
- .description = "24-bit RGB",
- .bpp = 3,
- .pixelformat = V4L2_PIX_FMT_RGB24,
- .colorspace = V4L2_COLORSPACE_SRGB,
- }*/
+ }
};
static const struct vino_data_norm vino_data_norms[] = {
@@ -396,18 +406,18 @@ static const struct vino_data_norm vino_data_norms[] = {
.width = VINO_NTSC_WIDTH,
.height = VINO_NTSC_HEIGHT,
.odd = {
- .top = VINO_CLIPPING_START_ODD_NTSC,
- .left = 0,
+ .top = VINO_CLIPPING_START_ODD_NTSC,
+ .left = 0,
.bottom = VINO_CLIPPING_START_ODD_NTSC
+ VINO_NTSC_HEIGHT / 2 - 1,
- .right = VINO_NTSC_WIDTH,
+ .right = VINO_NTSC_WIDTH,
},
.even = {
- .top = VINO_CLIPPING_START_EVEN_NTSC,
- .left = 0,
+ .top = VINO_CLIPPING_START_EVEN_NTSC,
+ .left = 0,
.bottom = VINO_CLIPPING_START_EVEN_NTSC
+ VINO_NTSC_HEIGHT / 2 - 1,
- .right = VINO_NTSC_WIDTH,
+ .right = VINO_NTSC_WIDTH,
},
},{
.description = "PAL",
@@ -418,18 +428,18 @@ static const struct vino_data_norm vino_data_norms[] = {
.width = VINO_PAL_WIDTH,
.height = VINO_PAL_HEIGHT,
.odd = {
- .top = VINO_CLIPPING_START_ODD_PAL,
- .left = 0,
+ .top = VINO_CLIPPING_START_ODD_PAL,
+ .left = 0,
.bottom = VINO_CLIPPING_START_ODD_PAL
+ VINO_PAL_HEIGHT / 2 - 1,
- .right = VINO_PAL_WIDTH,
+ .right = VINO_PAL_WIDTH,
},
.even = {
- .top = VINO_CLIPPING_START_EVEN_PAL,
- .left = 0,
+ .top = VINO_CLIPPING_START_EVEN_PAL,
+ .left = 0,
.bottom = VINO_CLIPPING_START_EVEN_PAL
+ VINO_PAL_HEIGHT / 2 - 1,
- .right = VINO_PAL_WIDTH,
+ .right = VINO_PAL_WIDTH,
},
},{
.description = "SECAM",
@@ -440,21 +450,21 @@ static const struct vino_data_norm vino_data_norms[] = {
.width = VINO_PAL_WIDTH,
.height = VINO_PAL_HEIGHT,
.odd = {
- .top = VINO_CLIPPING_START_ODD_PAL,
- .left = 0,
+ .top = VINO_CLIPPING_START_ODD_PAL,
+ .left = 0,
.bottom = VINO_CLIPPING_START_ODD_PAL
+ VINO_PAL_HEIGHT / 2 - 1,
- .right = VINO_PAL_WIDTH,
+ .right = VINO_PAL_WIDTH,
},
.even = {
- .top = VINO_CLIPPING_START_EVEN_PAL,
- .left = 0,
+ .top = VINO_CLIPPING_START_EVEN_PAL,
+ .left = 0,
.bottom = VINO_CLIPPING_START_EVEN_PAL
+ VINO_PAL_HEIGHT / 2 - 1,
- .right = VINO_PAL_WIDTH,
+ .right = VINO_PAL_WIDTH,
},
},{
- .description = "NTSC (D1 input)",
+ .description = "NTSC/D1",
.std = V4L2_STD_NTSC,
.fps_min = 6,
.fps_max = 30,
@@ -462,18 +472,18 @@ static const struct vino_data_norm vino_data_norms[] = {
.width = VINO_NTSC_WIDTH,
.height = VINO_NTSC_HEIGHT,
.odd = {
- .top = VINO_CLIPPING_START_ODD_D1,
- .left = 0,
+ .top = VINO_CLIPPING_START_ODD_D1,
+ .left = 0,
.bottom = VINO_CLIPPING_START_ODD_D1
+ VINO_NTSC_HEIGHT / 2 - 1,
- .right = VINO_NTSC_WIDTH,
+ .right = VINO_NTSC_WIDTH,
},
.even = {
- .top = VINO_CLIPPING_START_EVEN_D1,
- .left = 0,
+ .top = VINO_CLIPPING_START_EVEN_D1,
+ .left = 0,
.bottom = VINO_CLIPPING_START_EVEN_D1
+ VINO_NTSC_HEIGHT / 2 - 1,
- .right = VINO_NTSC_WIDTH,
+ .right = VINO_NTSC_WIDTH,
},
}
};
@@ -490,7 +500,7 @@ struct v4l2_queryctrl vino_indycam_v4l2_controls[] = {
.step = 1,
.default_value = INDYCAM_AGC_DEFAULT,
.flags = 0,
- .reserved = { 0, 0 },
+ .reserved = { INDYCAM_CONTROL_AGC, 0 },
},{
.id = V4L2_CID_AUTO_WHITE_BALANCE,
.type = V4L2_CTRL_TYPE_BOOLEAN,
@@ -500,7 +510,7 @@ struct v4l2_queryctrl vino_indycam_v4l2_controls[] = {
.step = 1,
.default_value = INDYCAM_AWB_DEFAULT,
.flags = 0,
- .reserved = { 0, 0 },
+ .reserved = { INDYCAM_CONTROL_AWB, 0 },
},{
.id = V4L2_CID_GAIN,
.type = V4L2_CTRL_TYPE_INTEGER,
@@ -510,7 +520,7 @@ struct v4l2_queryctrl vino_indycam_v4l2_controls[] = {
.step = 1,
.default_value = INDYCAM_GAIN_DEFAULT,
.flags = 0,
- .reserved = { 0, 0 },
+ .reserved = { INDYCAM_CONTROL_GAIN, 0 },
},{
.id = V4L2_CID_PRIVATE_BASE,
.type = V4L2_CTRL_TYPE_INTEGER,
@@ -520,7 +530,7 @@ struct v4l2_queryctrl vino_indycam_v4l2_controls[] = {
.step = 1,
.default_value = INDYCAM_RED_SATURATION_DEFAULT,
.flags = 0,
- .reserved = { 0, 0 },
+ .reserved = { INDYCAM_CONTROL_RED_SATURATION, 0 },
},{
.id = V4L2_CID_PRIVATE_BASE + 1,
.type = V4L2_CTRL_TYPE_INTEGER,
@@ -530,7 +540,7 @@ struct v4l2_queryctrl vino_indycam_v4l2_controls[] = {
.step = 1,
.default_value = INDYCAM_BLUE_SATURATION_DEFAULT,
.flags = 0,
- .reserved = { 0, 0 },
+ .reserved = { INDYCAM_CONTROL_BLUE_SATURATION, 0 },
},{
.id = V4L2_CID_RED_BALANCE,
.type = V4L2_CTRL_TYPE_INTEGER,
@@ -540,7 +550,7 @@ struct v4l2_queryctrl vino_indycam_v4l2_controls[] = {
.step = 1,
.default_value = INDYCAM_RED_BALANCE_DEFAULT,
.flags = 0,
- .reserved = { 0, 0 },
+ .reserved = { INDYCAM_CONTROL_RED_BALANCE, 0 },
},{
.id = V4L2_CID_BLUE_BALANCE,
.type = V4L2_CTRL_TYPE_INTEGER,
@@ -550,7 +560,7 @@ struct v4l2_queryctrl vino_indycam_v4l2_controls[] = {
.step = 1,
.default_value = INDYCAM_BLUE_BALANCE_DEFAULT,
.flags = 0,
- .reserved = { 0, 0 },
+ .reserved = { INDYCAM_CONTROL_BLUE_BALANCE, 0 },
},{
.id = V4L2_CID_EXPOSURE,
.type = V4L2_CTRL_TYPE_INTEGER,
@@ -560,7 +570,7 @@ struct v4l2_queryctrl vino_indycam_v4l2_controls[] = {
.step = 1,
.default_value = INDYCAM_SHUTTER_DEFAULT,
.flags = 0,
- .reserved = { 0, 0 },
+ .reserved = { INDYCAM_CONTROL_SHUTTER, 0 },
},{
.id = V4L2_CID_GAMMA,
.type = V4L2_CTRL_TYPE_INTEGER,
@@ -570,11 +580,11 @@ struct v4l2_queryctrl vino_indycam_v4l2_controls[] = {
.step = 1,
.default_value = INDYCAM_GAMMA_DEFAULT,
.flags = 0,
- .reserved = { 0, 0 },
+ .reserved = { INDYCAM_CONTROL_GAMMA, 0 },
}
};
-#define VINO_SAA7191_V4L2_CONTROL_COUNT 2
+#define VINO_SAA7191_V4L2_CONTROL_COUNT 9
struct v4l2_queryctrl vino_saa7191_v4l2_controls[] = {
{
@@ -586,9 +596,59 @@ struct v4l2_queryctrl vino_saa7191_v4l2_controls[] = {
.step = 1,
.default_value = SAA7191_HUE_DEFAULT,
.flags = 0,
- .reserved = { 0, 0 },
+ .reserved = { SAA7191_CONTROL_HUE, 0 },
},{
.id = V4L2_CID_PRIVATE_BASE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Luminance Bandpass",
+ .minimum = SAA7191_BANDPASS_MIN,
+ .maximum = SAA7191_BANDPASS_MAX,
+ .step = 1,
+ .default_value = SAA7191_BANDPASS_DEFAULT,
+ .flags = 0,
+ .reserved = { SAA7191_CONTROL_BANDPASS, 0 },
+ },{
+ .id = V4L2_CID_PRIVATE_BASE + 1,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Luminance Bandpass Weight",
+ .minimum = SAA7191_BANDPASS_WEIGHT_MIN,
+ .maximum = SAA7191_BANDPASS_WEIGHT_MAX,
+ .step = 1,
+ .default_value = SAA7191_BANDPASS_WEIGHT_DEFAULT,
+ .flags = 0,
+ .reserved = { SAA7191_CONTROL_BANDPASS_WEIGHT, 0 },
+ },{
+ .id = V4L2_CID_PRIVATE_BASE + 2,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "HF Luminance Coring",
+ .minimum = SAA7191_CORING_MIN,
+ .maximum = SAA7191_CORING_MAX,
+ .step = 1,
+ .default_value = SAA7191_CORING_DEFAULT,
+ .flags = 0,
+ .reserved = { SAA7191_CONTROL_CORING, 0 },
+ },{
+ .id = V4L2_CID_PRIVATE_BASE + 3,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "Force Colour",
+ .minimum = SAA7191_FORCE_COLOUR_MIN,
+ .maximum = SAA7191_FORCE_COLOUR_MAX,
+ .step = 1,
+ .default_value = SAA7191_FORCE_COLOUR_DEFAULT,
+ .flags = 0,
+ .reserved = { SAA7191_CONTROL_FORCE_COLOUR, 0 },
+ },{
+ .id = V4L2_CID_PRIVATE_BASE + 4,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Chrominance Gain Control",
+ .minimum = SAA7191_CHROMA_GAIN_MIN,
+ .maximum = SAA7191_CHROMA_GAIN_MAX,
+ .step = 1,
+ .default_value = SAA7191_CHROMA_GAIN_DEFAULT,
+ .flags = 0,
+ .reserved = { SAA7191_CONTROL_CHROMA_GAIN, 0 },
+ },{
+ .id = V4L2_CID_PRIVATE_BASE + 5,
.type = V4L2_CTRL_TYPE_BOOLEAN,
.name = "VTR Time Constant",
.minimum = SAA7191_VTRC_MIN,
@@ -596,7 +656,27 @@ struct v4l2_queryctrl vino_saa7191_v4l2_controls[] = {
.step = 1,
.default_value = SAA7191_VTRC_DEFAULT,
.flags = 0,
- .reserved = { 0, 0 },
+ .reserved = { SAA7191_CONTROL_VTRC, 0 },
+ },{
+ .id = V4L2_CID_PRIVATE_BASE + 6,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Luminance Delay Compensation",
+ .minimum = SAA7191_LUMA_DELAY_MIN,
+ .maximum = SAA7191_LUMA_DELAY_MAX,
+ .step = 1,
+ .default_value = SAA7191_LUMA_DELAY_DEFAULT,
+ .flags = 0,
+ .reserved = { SAA7191_CONTROL_LUMA_DELAY, 0 },
+ },{
+ .id = V4L2_CID_PRIVATE_BASE + 7,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Vertical Noise Reduction",
+ .minimum = SAA7191_VNR_MIN,
+ .maximum = SAA7191_VNR_MAX,
+ .step = 1,
+ .default_value = SAA7191_VNR_DEFAULT,
+ .flags = 0,
+ .reserved = { SAA7191_CONTROL_VNR, 0 },
}
};
@@ -638,9 +718,10 @@ static struct i2c_algo_sgi_data i2c_sgi_vino_data =
*/
static int i2c_vino_client_reg(struct i2c_client *client)
{
+ unsigned long flags;
int ret = 0;
- spin_lock(&vino_drvdata->input_lock);
+ spin_lock_irqsave(&vino_drvdata->input_lock, flags);
switch (client->driver->id) {
case I2C_DRIVERID_SAA7191:
if (vino_drvdata->decoder.driver)
@@ -657,16 +738,17 @@ static int i2c_vino_client_reg(struct i2c_client *client)
default:
ret = -ENODEV;
}
- spin_unlock(&vino_drvdata->input_lock);
+ spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
return ret;
}
static int i2c_vino_client_unreg(struct i2c_client *client)
{
+ unsigned long flags;
int ret = 0;
- spin_lock(&vino_drvdata->input_lock);
+ spin_lock_irqsave(&vino_drvdata->input_lock, flags);
if (client == vino_drvdata->decoder.driver) {
if (vino_drvdata->decoder.owner != VINO_NO_CHANNEL)
ret = -EBUSY;
@@ -678,7 +760,7 @@ static int i2c_vino_client_unreg(struct i2c_client *client)
else
vino_drvdata->camera.driver = NULL;
}
- spin_unlock(&vino_drvdata->input_lock);
+ spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
return ret;
}
@@ -726,7 +808,7 @@ static void vino_free_buffer_with_count(struct vino_framebuffer *fb,
dprintk("vino_free_buffer_with_count(): count = %d\n", count);
for (i = 0; i < count; i++) {
- mem_map_unreserve(virt_to_page(fb->desc_table.virtual[i]));
+ ClearPageReserved(virt_to_page(fb->desc_table.virtual[i]));
dma_unmap_single(NULL,
fb->desc_table.dma_cpu[VINO_PAGE_RATIO * i],
PAGE_SIZE, DMA_FROM_DEVICE);
@@ -804,7 +886,7 @@ static int vino_allocate_buffer(struct vino_framebuffer *fb,
dma_data_addr + VINO_PAGE_SIZE * j;
}
- mem_map_reserve(virt_to_page(fb->desc_table.virtual[i]));
+ SetPageReserved(virt_to_page(fb->desc_table.virtual[i]));
}
/* page_count needs to be set anyway, because the descriptor table has
@@ -891,7 +973,7 @@ static int vino_prepare_user_buffer(struct vino_framebuffer *fb,
dma_data_addr + VINO_PAGE_SIZE * j;
}
- mem_map_reserve(virt_to_page(fb->desc_table.virtual[i]));
+ SetPageReserved(virt_to_page(fb->desc_table.virtual[i]));
}
/* page_count needs to be set anyway, because the descriptor table has
@@ -932,7 +1014,7 @@ static void vino_sync_buffer(struct vino_framebuffer *fb)
/* Framebuffer fifo functions (need to be locked externally) */
-static void vino_fifo_init(struct vino_framebuffer_fifo *f,
+static inline void vino_fifo_init(struct vino_framebuffer_fifo *f,
unsigned int length)
{
f->length = 0;
@@ -940,16 +1022,18 @@ static void vino_fifo_init(struct vino_framebuffer_fifo *f,
f->head = 0;
f->tail = 0;
- if (length > VINO_FRAMEBUFFER_MAX_COUNT)
- length = VINO_FRAMEBUFFER_MAX_COUNT;
+ if (length > VINO_FRAMEBUFFER_COUNT_MAX)
+ length = VINO_FRAMEBUFFER_COUNT_MAX;
f->length = length;
}
/* returns true/false */
-static int vino_fifo_has_id(struct vino_framebuffer_fifo *f, unsigned int id)
+static inline int vino_fifo_has_id(struct vino_framebuffer_fifo *f,
+ unsigned int id)
{
unsigned int i;
+
for (i = f->head; i == (f->tail - 1); i = (i + 1) % f->length) {
if (f->data[i] == id)
return 1;
@@ -958,13 +1042,15 @@ static int vino_fifo_has_id(struct vino_framebuffer_fifo *f, unsigned int id)
return 0;
}
+#if 0
/* returns true/false */
-static int vino_fifo_full(struct vino_framebuffer_fifo *f)
+static inline int vino_fifo_full(struct vino_framebuffer_fifo *f)
{
return (f->used == f->length);
}
+#endif
-static unsigned int vino_fifo_get_used(struct vino_framebuffer_fifo *f)
+static inline unsigned int vino_fifo_get_used(struct vino_framebuffer_fifo *f)
{
return f->used;
}
@@ -1075,8 +1161,8 @@ static int vino_queue_init(struct vino_framebuffer_queue *q,
down(&q->queue_sem);
- if (*length > VINO_FRAMEBUFFER_MAX_COUNT)
- *length = VINO_FRAMEBUFFER_MAX_COUNT;
+ if (*length > VINO_FRAMEBUFFER_COUNT_MAX)
+ *length = VINO_FRAMEBUFFER_COUNT_MAX;
q->length = 0;
@@ -1312,6 +1398,7 @@ out:
return ret;
}
+#if 0
static int vino_queue_get_total(struct vino_framebuffer_queue *q,
unsigned int *total)
{
@@ -1337,6 +1424,7 @@ out:
return ret;
}
+#endif
static struct vino_framebuffer *vino_queue_peek(struct
vino_framebuffer_queue *q,
@@ -1470,12 +1558,14 @@ static void vino_update_line_size(struct vino_channel_settings *vcs)
dprintk("update_line_size(): before: w = %d, d = %d, "
"line_size = %d\n", w, d, vcs->line_size);
+
/* line size must be multiple of 8 bytes */
lsize = (bpp * (w / d)) & ~7;
w = (lsize / bpp) * d;
vcs->clipping.right = vcs->clipping.left + w;
vcs->line_size = lsize;
+
dprintk("update_line_size(): after: w = %d, d = %d, "
"line_size = %d\n", w, d, vcs->line_size);
}
@@ -1531,7 +1621,7 @@ static void vino_set_clipping(struct vino_channel_settings *vcs,
}
/* execute with input_lock locked */
-static void vino_set_default_clipping(struct vino_channel_settings *vcs)
+static inline void vino_set_default_clipping(struct vino_channel_settings *vcs)
{
vino_set_clipping(vcs, 0, 0, vino_data_norms[vcs->data_norm].width,
vino_data_norms[vcs->data_norm].height);
@@ -1555,8 +1645,7 @@ static void vino_set_scaling(struct vino_channel_settings *vcs,
if (d < 1) {
d = 1;
- }
- if (d > 8) {
+ } else if (d > 8) {
d = 8;
}
@@ -1569,7 +1658,7 @@ static void vino_set_scaling(struct vino_channel_settings *vcs,
}
/* execute with input_lock locked */
-static void vino_reset_scaling(struct vino_channel_settings *vcs)
+static inline void vino_set_default_scaling(struct vino_channel_settings *vcs)
{
vino_set_scaling(vcs, vcs->clipping.right - vcs->clipping.left,
vcs->clipping.bottom - vcs->clipping.top);
@@ -1648,7 +1737,8 @@ static void vino_set_framerate(struct vino_channel_settings *vcs,
}
/* execute with input_lock locked */
-static void vino_set_default_framerate(struct vino_channel_settings *vcs)
+static inline void vino_set_default_framerate(struct
+ vino_channel_settings *vcs)
{
vino_set_framerate(vcs, vino_data_norms[vcs->data_norm].fps_max);
}
@@ -1686,6 +1776,9 @@ static int vino_dma_setup(struct vino_channel_settings *vcs,
* should be more than enough time */
udelay(VINO_DESC_FETCH_DELAY);
+ dprintk("vino_dma_setup(): start desc = %08x, next 4 desc = %08x\n",
+ ch->start_desc_tbl, ch->next_4_desc);
+
/* set the alpha register */
ch->alpha = vcs->alpha;
@@ -1699,9 +1792,6 @@ static int vino_dma_setup(struct vino_channel_settings *vcs,
VINO_CLIP_EVEN(norm->even.top +
vcs->clipping.bottom / 2 - 1) |
VINO_CLIP_X(vcs->clipping.right);
- /* FIXME: end-of-field bug workaround
- VINO_CLIP_X(VINO_PAL_WIDTH);
- */
/* set the size of actual content in the buffer (DECIMATION !) */
fb->data_size = ((vcs->clipping.right - vcs->clipping.left) /
@@ -1801,7 +1891,7 @@ static int vino_dma_setup(struct vino_channel_settings *vcs,
}
/* (execute only with vino_lock locked) */
-static void vino_dma_start(struct vino_channel_settings *vcs)
+static inline void vino_dma_start(struct vino_channel_settings *vcs)
{
u32 ctrl = vino->control;
@@ -1812,12 +1902,14 @@ static void vino_dma_start(struct vino_channel_settings *vcs)
}
/* (execute only with vino_lock locked) */
-static void vino_dma_stop(struct vino_channel_settings *vcs)
+static inline void vino_dma_stop(struct vino_channel_settings *vcs)
{
u32 ctrl = vino->control;
ctrl &= (vcs->channel == VINO_CHANNEL_A) ?
~VINO_CTRL_A_DMA_ENBL : ~VINO_CTRL_B_DMA_ENBL;
+ ctrl &= (vcs->channel == VINO_CHANNEL_A) ?
+ ~VINO_CTRL_A_INT : ~VINO_CTRL_B_INT;
vino->control = ctrl;
dprintk("vino_dma_stop():\n");
}
@@ -1901,7 +1993,7 @@ static int vino_capture_next(struct vino_channel_settings *vcs, int start)
struct vino_framebuffer *fb;
unsigned int incoming, id;
int err = 0;
- unsigned long flags, flags2;
+ unsigned long flags;
dprintk("vino_capture_next():\n");
@@ -1942,10 +2034,6 @@ static int vino_capture_next(struct vino_channel_settings *vcs, int start)
goto out;
}
- spin_lock_irqsave(&fb->state_lock, flags2);
- fb->state = VINO_FRAMEBUFFER_UNUSED;
- spin_unlock_irqrestore(&fb->state_lock, flags2);
-
if (start) {
vcs->capturing = 1;
}
@@ -1963,7 +2051,7 @@ out:
return err;
}
-static int vino_is_capturing(struct vino_channel_settings *vcs)
+static inline int vino_is_capturing(struct vino_channel_settings *vcs)
{
int ret;
unsigned long flags;
@@ -2075,6 +2163,7 @@ static void vino_capture_stop(struct vino_channel_settings *vcs)
dprintk("vino_capture_stop():\n");
spin_lock_irqsave(&vcs->capture_lock, flags);
+
/* unset capturing to stop queue processing */
vcs->capturing = 0;
@@ -2120,6 +2209,7 @@ out:
spin_unlock_irqrestore(&vcs->capture_lock, flags);
}
+#if 0
static int vino_capture_failed(struct vino_channel_settings *vcs)
{
struct vino_framebuffer *fb;
@@ -2164,9 +2254,31 @@ static int vino_capture_failed(struct vino_channel_settings *vcs)
return 0;
}
+#endif
+
+static void vino_skip_frame(struct vino_channel_settings *vcs)
+{
+ struct vino_framebuffer *fb;
+ unsigned long flags;
+ unsigned int id;
+
+ spin_lock_irqsave(&vcs->capture_lock, flags);
+ fb = vino_queue_peek(&vcs->fb_queue, &id);
+ if (!fb) {
+ spin_unlock_irqrestore(&vcs->capture_lock, flags);
+ dprintk("vino_skip_frame(): vino_queue_peek() failed!\n");
+ return;
+ }
+ spin_unlock_irqrestore(&vcs->capture_lock, flags);
+
+ spin_lock_irqsave(&fb->state_lock, flags);
+ fb->state = VINO_FRAMEBUFFER_UNUSED;
+ spin_unlock_irqrestore(&fb->state_lock, flags);
+
+ vino_capture_next(vcs, 0);
+}
-static void vino_frame_done(struct vino_channel_settings *vcs,
- unsigned int fc)
+static void vino_frame_done(struct vino_channel_settings *vcs)
{
struct vino_framebuffer *fb;
unsigned long flags;
@@ -2180,8 +2292,9 @@ static void vino_frame_done(struct vino_channel_settings *vcs,
}
spin_unlock_irqrestore(&vcs->capture_lock, flags);
- fb->frame_counter = fc;
- do_gettimeofday(&fb->timestamp);
+ fb->frame_counter = vcs->int_data.frame_counter;
+ memcpy(&fb->timestamp, &vcs->int_data.timestamp,
+ sizeof(struct timeval));
spin_lock_irqsave(&fb->state_lock, flags);
if (fb->state == VINO_FRAMEBUFFER_IN_USE)
@@ -2193,72 +2306,175 @@ static void vino_frame_done(struct vino_channel_settings *vcs,
vino_capture_next(vcs, 0);
}
+static void vino_capture_tasklet(unsigned long channel) {
+ struct vino_channel_settings *vcs;
+
+ vcs = (channel == VINO_CHANNEL_A)
+ ? &vino_drvdata->a : &vino_drvdata->b;
+
+ if (vcs->int_data.skip)
+ vcs->int_data.skip_count++;
+
+ if (vcs->int_data.skip && (vcs->int_data.skip_count
+ <= VINO_MAX_FRAME_SKIP_COUNT)) {
+ vino_skip_frame(vcs);
+ } else {
+ vcs->int_data.skip_count = 0;
+ vino_frame_done(vcs);
+ }
+}
+
static irqreturn_t vino_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
- u32 intr;
+ u32 ctrl, intr;
unsigned int fc_a, fc_b;
- int done_a = 0;
- int done_b = 0;
+ int handled_a = 0, skip_a = 0, done_a = 0;
+ int handled_b = 0, skip_b = 0, done_b = 0;
+
+#ifdef VINO_DEBUG_INT
+ int loop = 0;
+ unsigned int line_count = vino->a.line_count,
+ page_index = vino->a.page_index,
+ field_counter = vino->a.field_counter,
+ start_desc_tbl = vino->a.start_desc_tbl,
+ next_4_desc = vino->a.next_4_desc;
+ unsigned int line_count_2,
+ page_index_2,
+ field_counter_2,
+ start_desc_tbl_2,
+ next_4_desc_2;
+#endif
spin_lock(&vino_drvdata->vino_lock);
- intr = vino->intr_status;
- fc_a = vino->a.field_counter / 2;
- fc_b = vino->b.field_counter / 2;
-
- // TODO: handle error-interrupts in some special way ?
-
- if (intr & VINO_INTSTAT_A) {
- if (intr & VINO_INTSTAT_A_EOF) {
- vino_drvdata->a.field++;
- if (vino_drvdata->a.field > 1) {
+ while ((intr = vino->intr_status)) {
+ fc_a = vino->a.field_counter >> 1;
+ fc_b = vino->b.field_counter >> 1;
+
+ /* handle error-interrupts in some special way ?
+ * --> skips frames */
+ if (intr & VINO_INTSTAT_A) {
+ if (intr & VINO_INTSTAT_A_EOF) {
+ vino_drvdata->a.field++;
+ if (vino_drvdata->a.field > 1) {
+ vino_dma_stop(&vino_drvdata->a);
+ vino_clear_interrupt(&vino_drvdata->a);
+ vino_drvdata->a.field = 0;
+ done_a = 1;
+ } else {
+ if (vino->a.page_index
+ != vino_drvdata->a.line_size) {
+ vino->a.line_count = 0;
+ vino->a.page_index =
+ vino_drvdata->
+ a.line_size;
+ vino->a.next_4_desc =
+ vino->a.start_desc_tbl;
+ }
+ }
+ dprintk("channel A end-of-field "
+ "interrupt: %04x\n", intr);
+ } else {
vino_dma_stop(&vino_drvdata->a);
vino_clear_interrupt(&vino_drvdata->a);
vino_drvdata->a.field = 0;
- done_a = 1;
+ skip_a = 1;
+ dprintk("channel A error interrupt: %04x\n",
+ intr);
}
- dprintk("intr: channel A end-of-field interrupt: "
- "%04x\n", intr);
- } else {
- vino_dma_stop(&vino_drvdata->a);
- vino_clear_interrupt(&vino_drvdata->a);
- done_a = 1;
- dprintk("channel A error interrupt: %04x\n", intr);
+
+#ifdef VINO_DEBUG_INT
+ line_count_2 = vino->a.line_count;
+ page_index_2 = vino->a.page_index;
+ field_counter_2 = vino->a.field_counter;
+ start_desc_tbl_2 = vino->a.start_desc_tbl;
+ next_4_desc_2 = vino->a.next_4_desc;
+
+ printk("intr = %04x, loop = %d, field = %d\n",
+ intr, loop, vino_drvdata->a.field);
+ printk("1- line count = %04d, page index = %04d, "
+ "start = %08x, next = %08x\n"
+ " fieldc = %d, framec = %d\n",
+ line_count, page_index, start_desc_tbl,
+ next_4_desc, field_counter, fc_a);
+ printk("12-line count = %04d, page index = %04d, "
+ " start = %08x, next = %08x\n",
+ line_count_2, page_index_2, start_desc_tbl_2,
+ next_4_desc_2);
+
+ if (done_a)
+ printk("\n");
+#endif
}
- }
- if (intr & VINO_INTSTAT_B) {
- if (intr & VINO_INTSTAT_B_EOF) {
- vino_drvdata->b.field++;
- if (vino_drvdata->b.field > 1) {
+
+ if (intr & VINO_INTSTAT_B) {
+ if (intr & VINO_INTSTAT_B_EOF) {
+ vino_drvdata->b.field++;
+ if (vino_drvdata->b.field > 1) {
+ vino_dma_stop(&vino_drvdata->b);
+ vino_clear_interrupt(&vino_drvdata->b);
+ vino_drvdata->b.field = 0;
+ done_b = 1;
+ }
+ dprintk("channel B end-of-field "
+ "interrupt: %04x\n", intr);
+ } else {
vino_dma_stop(&vino_drvdata->b);
vino_clear_interrupt(&vino_drvdata->b);
vino_drvdata->b.field = 0;
- done_b = 1;
+ skip_b = 1;
+ dprintk("channel B error interrupt: %04x\n",
+ intr);
}
- dprintk("intr: channel B end-of-field interrupt: "
- "%04x\n", intr);
- } else {
- vino_dma_stop(&vino_drvdata->b);
- vino_clear_interrupt(&vino_drvdata->b);
- done_b = 1;
- dprintk("channel B error interrupt: %04x\n", intr);
}
- }
- /* always remember to clear interrupt status */
- vino->intr_status = ~intr;
+ /* Always remember to clear interrupt status.
+ * Disable VINO interrupts while we do this. */
+ ctrl = vino->control;
+ vino->control = ctrl & ~(VINO_CTRL_A_INT | VINO_CTRL_B_INT);
+ vino->intr_status = ~intr;
+ vino->control = ctrl;
- spin_unlock(&vino_drvdata->vino_lock);
+ spin_unlock(&vino_drvdata->vino_lock);
- if (done_a) {
- vino_frame_done(&vino_drvdata->a, fc_a);
- dprintk("channel A frame done, interrupt: %d\n", intr);
- }
- if (done_b) {
- vino_frame_done(&vino_drvdata->b, fc_b);
- dprintk("channel B frame done, interrupt: %d\n", intr);
+ if ((!handled_a) && (done_a || skip_a)) {
+ if (!skip_a) {
+ do_gettimeofday(&vino_drvdata->
+ a.int_data.timestamp);
+ vino_drvdata->a.int_data.frame_counter = fc_a;
+ }
+ vino_drvdata->a.int_data.skip = skip_a;
+
+ dprintk("channel A %s, interrupt: %d\n",
+ skip_a ? "skipping frame" : "frame done",
+ intr);
+ tasklet_hi_schedule(&vino_tasklet_a);
+ handled_a = 1;
+ }
+
+ if ((!handled_b) && (done_b || skip_b)) {
+ if (!skip_b) {
+ do_gettimeofday(&vino_drvdata->
+ b.int_data.timestamp);
+ vino_drvdata->b.int_data.frame_counter = fc_b;
+ }
+ vino_drvdata->b.int_data.skip = skip_b;
+
+ dprintk("channel B %s, interrupt: %d\n",
+ skip_b ? "skipping frame" : "frame done",
+ intr);
+ tasklet_hi_schedule(&vino_tasklet_b);
+ handled_b = 1;
+ }
+
+#ifdef VINO_DEBUG_INT
+ loop++;
+#endif
+ spin_lock(&vino_drvdata->vino_lock);
}
+ spin_unlock(&vino_drvdata->vino_lock);
+
return IRQ_HANDLED;
}
@@ -2278,11 +2494,13 @@ static int vino_get_saa7191_input(int input)
}
}
-static int vino_get_saa7191_norm(int norm)
+static int vino_get_saa7191_norm(unsigned int data_norm)
{
- switch (norm) {
+ switch (data_norm) {
case VINO_DATA_NORM_AUTO:
return SAA7191_NORM_AUTO;
+ case VINO_DATA_NORM_AUTO_EXT:
+ return SAA7191_NORM_AUTO_EXT;
case VINO_DATA_NORM_PAL:
return SAA7191_NORM_PAL;
case VINO_DATA_NORM_NTSC:
@@ -2296,6 +2514,57 @@ static int vino_get_saa7191_norm(int norm)
}
}
+static int vino_get_from_saa7191_norm(int saa7191_norm)
+{
+ switch (saa7191_norm) {
+ case SAA7191_NORM_PAL:
+ return VINO_DATA_NORM_PAL;
+ case SAA7191_NORM_NTSC:
+ return VINO_DATA_NORM_NTSC;
+ case SAA7191_NORM_SECAM:
+ return VINO_DATA_NORM_SECAM;
+ default:
+ printk(KERN_ERR "VINO: vino_get_from_saa7191_norm(): "
+ "invalid norm!\n");
+ return VINO_DATA_NORM_NONE;
+ }
+}
+
+static int vino_saa7191_set_norm(unsigned int *data_norm)
+{
+ int saa7191_norm, new_data_norm;
+ int err = 0;
+
+ saa7191_norm = vino_get_saa7191_norm(*data_norm);
+
+ err = i2c_decoder_command(DECODER_SAA7191_SET_NORM,
+ &saa7191_norm);
+ if (err)
+ goto out;
+
+ if ((*data_norm == VINO_DATA_NORM_AUTO)
+ || (*data_norm == VINO_DATA_NORM_AUTO_EXT)) {
+ struct saa7191_status status;
+
+ err = i2c_decoder_command(DECODER_SAA7191_GET_STATUS,
+ &status);
+ if (err)
+ goto out;
+
+ new_data_norm =
+ vino_get_from_saa7191_norm(status.norm);
+ if (new_data_norm == VINO_DATA_NORM_NONE) {
+ err = -EINVAL;
+ goto out;
+ }
+
+ *data_norm = (unsigned int)new_data_norm;
+ }
+
+out:
+ return err;
+}
+
/* execute with input_lock locked */
static int vino_is_input_owner(struct vino_channel_settings *vcs)
{
@@ -2312,11 +2581,12 @@ static int vino_is_input_owner(struct vino_channel_settings *vcs)
static int vino_acquire_input(struct vino_channel_settings *vcs)
{
+ unsigned long flags;
int ret = 0;
dprintk("vino_acquire_input():\n");
- spin_lock(&vino_drvdata->input_lock);
+ spin_lock_irqsave(&vino_drvdata->input_lock, flags);
/* First try D1 and then SAA7191 */
if (vino_drvdata->camera.driver
@@ -2331,23 +2601,48 @@ static int vino_acquire_input(struct vino_channel_settings *vcs)
vcs->data_norm = VINO_DATA_NORM_D1;
} else if (vino_drvdata->decoder.driver
&& (vino_drvdata->decoder.owner == VINO_NO_CHANNEL)) {
+ int input, data_norm;
int saa7191_input;
- int saa7191_norm;
if (i2c_use_client(vino_drvdata->decoder.driver)) {
ret = -ENODEV;
goto out;
}
- vino_drvdata->decoder.owner = vcs->channel;
- vcs->input = VINO_INPUT_COMPOSITE;
- vcs->data_norm = VINO_DATA_NORM_PAL;
+ input = VINO_INPUT_COMPOSITE;
- saa7191_input = vino_get_saa7191_input(vcs->input);
- i2c_decoder_command(DECODER_SET_INPUT, &saa7191_input);
+ saa7191_input = vino_get_saa7191_input(input);
+ ret = i2c_decoder_command(DECODER_SET_INPUT,
+ &saa7191_input);
+ if (ret) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
- saa7191_norm = vino_get_saa7191_norm(vcs->data_norm);
- i2c_decoder_command(DECODER_SAA7191_SET_NORM, &saa7191_norm);
+ /* Don't hold spinlocks while auto-detecting norm
+ * as it may take a while... */
+
+ data_norm = VINO_DATA_NORM_AUTO_EXT;
+
+ ret = vino_saa7191_set_norm(&data_norm);
+ if ((ret == -EBUSY) || (ret == -EAGAIN)) {
+ data_norm = VINO_DATA_NORM_PAL;
+ ret = vino_saa7191_set_norm(&data_norm);
+ }
+
+ spin_lock_irqsave(&vino_drvdata->input_lock, flags);
+
+ if (ret) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ vino_drvdata->decoder.owner = vcs->channel;
+
+ vcs->input = input;
+ vcs->data_norm = data_norm;
} else {
vcs->input = (vcs->channel == VINO_CHANNEL_A) ?
vino_drvdata->b.input : vino_drvdata->a.input;
@@ -2360,15 +2655,14 @@ static int vino_acquire_input(struct vino_channel_settings *vcs)
goto out;
}
- if (vino_is_input_owner(vcs)) {
- vino_set_default_clipping(vcs);
- vino_set_default_framerate(vcs);
- }
+ vino_set_default_clipping(vcs);
+ vino_set_default_scaling(vcs);
+ vino_set_default_framerate(vcs);
dprintk("vino_acquire_input(): %s\n", vino_inputs[vcs->input].name);
out:
- spin_unlock(&vino_drvdata->input_lock);
+ spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
return ret;
}
@@ -2377,16 +2671,17 @@ static int vino_set_input(struct vino_channel_settings *vcs, int input)
{
struct vino_channel_settings *vcs2 = (vcs->channel == VINO_CHANNEL_A) ?
&vino_drvdata->b : &vino_drvdata->a;
+ unsigned long flags;
int ret = 0;
dprintk("vino_set_input():\n");
- spin_lock(&vino_drvdata->input_lock);
+ spin_lock_irqsave(&vino_drvdata->input_lock, flags);
if (vcs->input == input)
goto out;
- switch(input) {
+ switch (input) {
case VINO_INPUT_COMPOSITE:
case VINO_INPUT_SVIDEO:
if (!vino_drvdata->decoder.driver) {
@@ -2403,19 +2698,43 @@ static int vino_set_input(struct vino_channel_settings *vcs, int input)
}
if (vino_drvdata->decoder.owner == vcs->channel) {
+ int data_norm;
int saa7191_input;
- int saa7191_norm;
- vcs->input = input;
- vcs->data_norm = VINO_DATA_NORM_PAL;
+ saa7191_input = vino_get_saa7191_input(input);
+ ret = i2c_decoder_command(DECODER_SET_INPUT,
+ &saa7191_input);
+ if (ret) {
+ vino_drvdata->decoder.owner = VINO_NO_CHANNEL;
+ ret = -EINVAL;
+ goto out;
+ }
+
+ spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
+
+ /* Don't hold spinlocks while auto-detecting norm
+ * as it may take a while... */
- saa7191_input = vino_get_saa7191_input(vcs->input);
- i2c_decoder_command(DECODER_SET_INPUT, &saa7191_input);
- saa7191_norm = vino_get_saa7191_norm(vcs->data_norm);
- i2c_decoder_command(DECODER_SAA7191_SET_NORM,
- &saa7191_norm);
+ data_norm = VINO_DATA_NORM_AUTO_EXT;
+
+ ret = vino_saa7191_set_norm(&data_norm);
+ if ((ret == -EBUSY) || (ret == -EAGAIN)) {
+ data_norm = VINO_DATA_NORM_PAL;
+ ret = vino_saa7191_set_norm(&data_norm);
+ }
+
+ spin_lock_irqsave(&vino_drvdata->input_lock, flags);
+
+ if (ret) {
+ vino_drvdata->decoder.owner = VINO_NO_CHANNEL;
+ ret = -EINVAL;
+ goto out;
+ }
+
+ vcs->input = input;
+ vcs->data_norm = data_norm;
} else {
- if (vcs2->input != input) {
+ if (input != vcs2->input) {
ret = -EBUSY;
goto out;
}
@@ -2470,12 +2789,13 @@ static int vino_set_input(struct vino_channel_settings *vcs, int input)
}
vino_set_default_clipping(vcs);
+ vino_set_default_scaling(vcs);
vino_set_default_framerate(vcs);
dprintk("vino_set_input(): %s\n", vino_inputs[vcs->input].name);
out:
- spin_unlock(&vino_drvdata->input_lock);
+ spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
return ret;
}
@@ -2484,10 +2804,11 @@ static void vino_release_input(struct vino_channel_settings *vcs)
{
struct vino_channel_settings *vcs2 = (vcs->channel == VINO_CHANNEL_A) ?
&vino_drvdata->b : &vino_drvdata->a;
+ unsigned long flags;
dprintk("vino_release_input():\n");
- spin_lock(&vino_drvdata->input_lock);
+ spin_lock_irqsave(&vino_drvdata->input_lock, flags);
/* Release ownership of the channel
* and if the other channel takes input from
@@ -2510,34 +2831,61 @@ static void vino_release_input(struct vino_channel_settings *vcs)
}
vcs->input = VINO_INPUT_NONE;
- spin_unlock(&vino_drvdata->input_lock);
+ spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
}
/* execute with input_lock locked */
static int vino_set_data_norm(struct vino_channel_settings *vcs,
- unsigned int data_norm)
+ unsigned int data_norm,
+ unsigned long *flags)
{
- int saa7191_norm;
+ int err = 0;
+
+ if (data_norm == vcs->data_norm)
+ return 0;
switch (vcs->input) {
case VINO_INPUT_D1:
/* only one "norm" supported */
- if (data_norm != VINO_DATA_NORM_D1)
+ if ((data_norm != VINO_DATA_NORM_D1)
+ && (data_norm != VINO_DATA_NORM_AUTO)
+ && (data_norm != VINO_DATA_NORM_AUTO_EXT))
return -EINVAL;
break;
case VINO_INPUT_COMPOSITE:
- case VINO_INPUT_SVIDEO:
+ case VINO_INPUT_SVIDEO: {
+ if ((data_norm != VINO_DATA_NORM_PAL)
+ && (data_norm != VINO_DATA_NORM_NTSC)
+ && (data_norm != VINO_DATA_NORM_SECAM)
+ && (data_norm != VINO_DATA_NORM_AUTO)
+ && (data_norm != VINO_DATA_NORM_AUTO_EXT))
+ return -EINVAL;
+
+ spin_unlock_irqrestore(&vino_drvdata->input_lock, *flags);
- saa7191_norm = vino_get_saa7191_norm(data_norm);
+ /* Don't hold spinlocks while setting norm
+ * as it may take a while... */
+
+ err = vino_saa7191_set_norm(&data_norm);
+
+ spin_lock_irqsave(&vino_drvdata->input_lock, *flags);
+
+ if (err)
+ goto out;
- i2c_decoder_command(DECODER_SAA7191_SET_NORM, &saa7191_norm);
vcs->data_norm = data_norm;
+
+ vino_set_default_clipping(vcs);
+ vino_set_default_scaling(vcs);
+ vino_set_default_framerate(vcs);
break;
+ }
default:
return -EINVAL;
}
- return 0;
+out:
+ return err;
}
/* V4L2 helper functions */
@@ -2557,8 +2905,9 @@ static int vino_find_data_format(__u32 pixelformat)
static int vino_enum_data_norm(struct vino_channel_settings *vcs, __u32 index)
{
int data_norm = VINO_DATA_NORM_NONE;
+ unsigned long flags;
- spin_lock(&vino_drvdata->input_lock);
+ spin_lock_irqsave(&vino_drvdata->input_lock, flags);
switch(vcs->input) {
case VINO_INPUT_COMPOSITE:
case VINO_INPUT_SVIDEO:
@@ -2576,7 +2925,7 @@ static int vino_enum_data_norm(struct vino_channel_settings *vcs, __u32 index)
}
break;
}
- spin_unlock(&vino_drvdata->input_lock);
+ spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
return data_norm;
}
@@ -2584,8 +2933,9 @@ static int vino_enum_data_norm(struct vino_channel_settings *vcs, __u32 index)
static int vino_enum_input(struct vino_channel_settings *vcs, __u32 index)
{
int input = VINO_INPUT_NONE;
+ unsigned long flags;
- spin_lock(&vino_drvdata->input_lock);
+ spin_lock_irqsave(&vino_drvdata->input_lock, flags);
if (vino_drvdata->decoder.driver && vino_drvdata->camera.driver) {
switch (index) {
case 0:
@@ -2614,7 +2964,7 @@ static int vino_enum_input(struct vino_channel_settings *vcs, __u32 index)
break;
}
}
- spin_unlock(&vino_drvdata->input_lock);
+ spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
return input;
}
@@ -2703,15 +3053,16 @@ static int vino_v4l2_enuminput(struct vino_channel_settings *vcs,
}
static int vino_v4l2_g_input(struct vino_channel_settings *vcs,
- struct v4l2_input *i)
+ unsigned int *i)
{
__u32 index;
int input;
+ unsigned long flags;
- spin_lock(&vino_drvdata->input_lock);
+ spin_lock_irqsave(&vino_drvdata->input_lock, flags);
input = vcs->input;
index = vino_find_input_index(vcs);
- spin_unlock(&vino_drvdata->input_lock);
+ spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
dprintk("input = %d\n", input);
@@ -2719,23 +3070,18 @@ static int vino_v4l2_g_input(struct vino_channel_settings *vcs,
return -EINVAL;
}
- memset(i, 0, sizeof(struct v4l2_input));
-
- i->index = index;
- i->type = V4L2_INPUT_TYPE_CAMERA;
- i->std = vino_inputs[input].std;
- strcpy(i->name, vino_inputs[input].name);
+ *i = index;
return 0;
}
static int vino_v4l2_s_input(struct vino_channel_settings *vcs,
- struct v4l2_input *i)
+ unsigned int *i)
{
int input;
- dprintk("requested input = %d\n", i->index);
+ dprintk("requested input = %d\n", *i);
- input = vino_enum_input(vcs, i->index);
+ input = vino_enum_input(vcs, *i);
if (input == VINO_INPUT_NONE)
return -EINVAL;
@@ -2746,7 +3092,9 @@ static int vino_v4l2_enumstd(struct vino_channel_settings *vcs,
struct v4l2_standard *s)
{
int index = s->index;
- int data_norm = vino_enum_data_norm(vcs, index);
+ int data_norm;
+
+ data_norm = vino_enum_data_norm(vcs, index);
dprintk("standard index = %d\n", index);
if (data_norm == VINO_DATA_NORM_NONE)
@@ -2770,13 +3118,55 @@ static int vino_v4l2_enumstd(struct vino_channel_settings *vcs,
return 0;
}
+static int vino_v4l2_querystd(struct vino_channel_settings *vcs,
+ v4l2_std_id *std)
+{
+ unsigned long flags;
+ int err = 0;
+
+ spin_lock_irqsave(&vino_drvdata->input_lock, flags);
+
+ switch (vcs->input) {
+ case VINO_INPUT_D1:
+ *std = vino_inputs[vcs->input].std;
+ break;
+ case VINO_INPUT_COMPOSITE:
+ case VINO_INPUT_SVIDEO: {
+ struct saa7191_status status;
+
+ i2c_decoder_command(DECODER_SAA7191_GET_STATUS, &status);
+
+ if (status.signal) {
+ if (status.signal_60hz) {
+ *std = V4L2_STD_NTSC;
+ } else {
+ *std = V4L2_STD_PAL | V4L2_STD_SECAM;
+ }
+ } else {
+ *std = vino_inputs[vcs->input].std;
+ }
+ break;
+ }
+ default:
+ err = -EINVAL;
+ }
+
+ spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
+
+ return err;
+}
+
static int vino_v4l2_g_std(struct vino_channel_settings *vcs,
v4l2_std_id *std)
{
- spin_lock(&vino_drvdata->input_lock);
- dprintk("current standard = %d\n", vcs->data_norm);
+ unsigned long flags;
+
+ spin_lock_irqsave(&vino_drvdata->input_lock, flags);
+
*std = vino_data_norms[vcs->data_norm].std;
- spin_unlock(&vino_drvdata->input_lock);
+ dprintk("current standard = %d\n", vcs->data_norm);
+
+ spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
return 0;
}
@@ -2784,13 +3174,18 @@ static int vino_v4l2_g_std(struct vino_channel_settings *vcs,
static int vino_v4l2_s_std(struct vino_channel_settings *vcs,
v4l2_std_id *std)
{
+ unsigned long flags;
int ret = 0;
- spin_lock(&vino_drvdata->input_lock);
+ spin_lock_irqsave(&vino_drvdata->input_lock, flags);
+
+ if (!vino_is_input_owner(vcs)) {
+ ret = -EBUSY;
+ goto out;
+ }
/* check if the standard is valid for the current input */
- if (vino_is_input_owner(vcs)
- && (vino_inputs[vcs->input].std & (*std))) {
+ if ((*std) & vino_inputs[vcs->input].std) {
dprintk("standard accepted\n");
/* change the video norm for SAA7191
@@ -2799,24 +3194,33 @@ static int vino_v4l2_s_std(struct vino_channel_settings *vcs,
if (vcs->input == VINO_INPUT_D1)
goto out;
- if ((*std) & V4L2_STD_PAL) {
- vino_set_data_norm(vcs, VINO_DATA_NORM_PAL);
- vcs->data_norm = VINO_DATA_NORM_PAL;
+ if (((*std) & V4L2_STD_PAL)
+ && ((*std) & V4L2_STD_NTSC)
+ && ((*std) & V4L2_STD_SECAM)) {
+ ret = vino_set_data_norm(vcs, VINO_DATA_NORM_AUTO_EXT,
+ &flags);
+ } else if ((*std) & V4L2_STD_PAL) {
+ ret = vino_set_data_norm(vcs, VINO_DATA_NORM_PAL,
+ &flags);
} else if ((*std) & V4L2_STD_NTSC) {
- vino_set_data_norm(vcs, VINO_DATA_NORM_NTSC);
- vcs->data_norm = VINO_DATA_NORM_NTSC;
+ ret = vino_set_data_norm(vcs, VINO_DATA_NORM_NTSC,
+ &flags);
} else if ((*std) & V4L2_STD_SECAM) {
- vino_set_data_norm(vcs, VINO_DATA_NORM_SECAM);
- vcs->data_norm = VINO_DATA_NORM_SECAM;
+ ret = vino_set_data_norm(vcs, VINO_DATA_NORM_SECAM,
+ &flags);
} else {
ret = -EINVAL;
}
+
+ if (ret) {
+ ret = -EINVAL;
+ }
} else {
ret = -EINVAL;
}
out:
- spin_unlock(&vino_drvdata->input_lock);
+ spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
return ret;
}
@@ -2854,6 +3258,7 @@ static int vino_v4l2_try_fmt(struct vino_channel_settings *vcs,
struct v4l2_format *f)
{
struct vino_channel_settings tempvcs;
+ unsigned long flags;
switch (f->type) {
case V4L2_BUF_TYPE_VIDEO_CAPTURE: {
@@ -2862,13 +3267,13 @@ static int vino_v4l2_try_fmt(struct vino_channel_settings *vcs,
dprintk("requested: w = %d, h = %d\n",
pf->width, pf->height);
- spin_lock(&vino_drvdata->input_lock);
+ spin_lock_irqsave(&vino_drvdata->input_lock, flags);
memcpy(&tempvcs, vcs, sizeof(struct vino_channel_settings));
- spin_unlock(&vino_drvdata->input_lock);
+ spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
tempvcs.data_format = vino_find_data_format(pf->pixelformat);
if (tempvcs.data_format == VINO_DATA_FMT_NONE) {
- tempvcs.data_format = VINO_DATA_FMT_RGB32;
+ tempvcs.data_format = VINO_DATA_FMT_GREY;
pf->pixelformat =
vino_data_formats[tempvcs.data_format].
pixelformat;
@@ -2907,10 +3312,13 @@ static int vino_v4l2_try_fmt(struct vino_channel_settings *vcs,
static int vino_v4l2_g_fmt(struct vino_channel_settings *vcs,
struct v4l2_format *f)
{
+ unsigned long flags;
+
switch (f->type) {
case V4L2_BUF_TYPE_VIDEO_CAPTURE: {
struct v4l2_pix_format *pf = &f->fmt.pix;
- spin_lock(&vino_drvdata->input_lock);
+
+ spin_lock_irqsave(&vino_drvdata->input_lock, flags);
pf->width = (vcs->clipping.right - vcs->clipping.left) /
vcs->decimation;
@@ -2929,7 +3337,7 @@ static int vino_v4l2_g_fmt(struct vino_channel_settings *vcs,
pf->priv = 0;
- spin_unlock(&vino_drvdata->input_lock);
+ spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
break;
}
case V4L2_BUF_TYPE_VIDEO_OVERLAY:
@@ -2944,20 +3352,18 @@ static int vino_v4l2_s_fmt(struct vino_channel_settings *vcs,
struct v4l2_format *f)
{
int data_format;
+ unsigned long flags;
switch (f->type) {
case V4L2_BUF_TYPE_VIDEO_CAPTURE: {
struct v4l2_pix_format *pf = &f->fmt.pix;
- spin_lock(&vino_drvdata->input_lock);
- if (!vino_is_input_owner(vcs)) {
- spin_unlock(&vino_drvdata->input_lock);
- return -EINVAL;
- }
+ spin_lock_irqsave(&vino_drvdata->input_lock, flags);
data_format = vino_find_data_format(pf->pixelformat);
+
if (data_format == VINO_DATA_FMT_NONE) {
- vcs->data_format = VINO_DATA_FMT_RGB32;
+ vcs->data_format = VINO_DATA_FMT_GREY;
pf->pixelformat =
vino_data_formats[vcs->data_format].
pixelformat;
@@ -2984,7 +3390,7 @@ static int vino_v4l2_s_fmt(struct vino_channel_settings *vcs,
pf->priv = 0;
- spin_unlock(&vino_drvdata->input_lock);
+ spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
break;
}
case V4L2_BUF_TYPE_VIDEO_OVERLAY:
@@ -2999,12 +3405,15 @@ static int vino_v4l2_cropcap(struct vino_channel_settings *vcs,
struct v4l2_cropcap *ccap)
{
const struct vino_data_norm *norm;
+ unsigned long flags;
switch (ccap->type) {
case V4L2_BUF_TYPE_VIDEO_CAPTURE:
- spin_lock(&vino_drvdata->input_lock);
+ spin_lock_irqsave(&vino_drvdata->input_lock, flags);
+
norm = &vino_data_norms[vcs->data_norm];
- spin_unlock(&vino_drvdata->input_lock);
+
+ spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
ccap->bounds.left = 0;
ccap->bounds.top = 0;
@@ -3027,16 +3436,18 @@ static int vino_v4l2_cropcap(struct vino_channel_settings *vcs,
static int vino_v4l2_g_crop(struct vino_channel_settings *vcs,
struct v4l2_crop *c)
{
+ unsigned long flags;
+
switch (c->type) {
case V4L2_BUF_TYPE_VIDEO_CAPTURE:
- spin_lock(&vino_drvdata->input_lock);
+ spin_lock_irqsave(&vino_drvdata->input_lock, flags);
c->c.left = vcs->clipping.left;
c->c.top = vcs->clipping.top;
c->c.width = vcs->clipping.right - vcs->clipping.left;
c->c.height = vcs->clipping.bottom - vcs->clipping.top;
- spin_unlock(&vino_drvdata->input_lock);
+ spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
break;
case V4L2_BUF_TYPE_VIDEO_OVERLAY:
default:
@@ -3049,18 +3460,16 @@ static int vino_v4l2_g_crop(struct vino_channel_settings *vcs,
static int vino_v4l2_s_crop(struct vino_channel_settings *vcs,
struct v4l2_crop *c)
{
+ unsigned long flags;
+
switch (c->type) {
case V4L2_BUF_TYPE_VIDEO_CAPTURE:
- spin_lock(&vino_drvdata->input_lock);
+ spin_lock_irqsave(&vino_drvdata->input_lock, flags);
- if (!vino_is_input_owner(vcs)) {
- spin_unlock(&vino_drvdata->input_lock);
- return -EINVAL;
- }
vino_set_clipping(vcs, c->c.left, c->c.top,
c->c.width, c->c.height);
- spin_unlock(&vino_drvdata->input_lock);
+ spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
break;
case V4L2_BUF_TYPE_VIDEO_OVERLAY:
default:
@@ -3073,6 +3482,8 @@ static int vino_v4l2_s_crop(struct vino_channel_settings *vcs,
static int vino_v4l2_g_parm(struct vino_channel_settings *vcs,
struct v4l2_streamparm *sp)
{
+ unsigned long flags;
+
switch (sp->type) {
case V4L2_BUF_TYPE_VIDEO_CAPTURE: {
struct v4l2_captureparm *cp = &sp->parm.capture;
@@ -3081,9 +3492,11 @@ static int vino_v4l2_g_parm(struct vino_channel_settings *vcs,
cp->capability = V4L2_CAP_TIMEPERFRAME;
cp->timeperframe.numerator = 1;
- spin_lock(&vino_drvdata->input_lock);
+ spin_lock_irqsave(&vino_drvdata->input_lock, flags);
+
cp->timeperframe.denominator = vcs->fps;
- spin_unlock(&vino_drvdata->input_lock);
+
+ spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
// TODO: cp->readbuffers = xxx;
break;
@@ -3099,15 +3512,13 @@ static int vino_v4l2_g_parm(struct vino_channel_settings *vcs,
static int vino_v4l2_s_parm(struct vino_channel_settings *vcs,
struct v4l2_streamparm *sp)
{
+ unsigned long flags;
+
switch (sp->type) {
case V4L2_BUF_TYPE_VIDEO_CAPTURE: {
struct v4l2_captureparm *cp = &sp->parm.capture;
- spin_lock(&vino_drvdata->input_lock);
- if (!vino_is_input_owner(vcs)) {
- spin_unlock(&vino_drvdata->input_lock);
- return -EINVAL;
- }
+ spin_lock_irqsave(&vino_drvdata->input_lock, flags);
if ((cp->timeperframe.numerator == 0) ||
(cp->timeperframe.denominator == 0)) {
@@ -3117,7 +3528,8 @@ static int vino_v4l2_s_parm(struct vino_channel_settings *vcs,
vino_set_framerate(vcs, cp->timeperframe.denominator /
cp->timeperframe.numerator);
}
- spin_unlock(&vino_drvdata->input_lock);
+
+ spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
// TODO: set buffers according to cp->readbuffers
break;
@@ -3144,21 +3556,23 @@ static int vino_v4l2_reqbufs(struct vino_channel_settings *vcs,
return -EINVAL;
}
- if (vino_is_capturing(vcs)) {
- dprintk("busy, capturing\n");
- return -EBUSY;
- }
-
dprintk("count = %d\n", rb->count);
if (rb->count > 0) {
+ if (vino_is_capturing(vcs)) {
+ dprintk("busy, capturing\n");
+ return -EBUSY;
+ }
+
if (vino_queue_has_mapped_buffers(&vcs->fb_queue)) {
dprintk("busy, buffers still mapped\n");
return -EBUSY;
} else {
+ vcs->streaming = 0;
vino_queue_free(&vcs->fb_queue);
vino_queue_init(&vcs->fb_queue, &rb->count);
}
} else {
+ vcs->streaming = 0;
vino_capture_stop(vcs);
vino_queue_free(&vcs->fb_queue);
}
@@ -3301,12 +3715,12 @@ static int vino_v4l2_dqbuf(struct vino_channel_settings *vcs,
err = vino_queue_get_incoming(&vcs->fb_queue, &incoming);
if (err) {
dprintk("vino_queue_get_incoming() failed\n");
- return -EIO;
+ return -EINVAL;
}
err = vino_queue_get_outgoing(&vcs->fb_queue, &outgoing);
if (err) {
dprintk("vino_queue_get_outgoing() failed\n");
- return -EIO;
+ return -EINVAL;
}
dprintk("incoming = %d, outgoing = %d\n", incoming, outgoing);
@@ -3326,8 +3740,10 @@ static int vino_v4l2_dqbuf(struct vino_channel_settings *vcs,
if (err) {
err = vino_wait_for_frame(vcs);
if (err) {
- /* interrupted */
- vino_capture_failed(vcs);
+ /* interrupted or
+ * no frames captured because
+ * of frame skipping */
+ // vino_capture_failed(vcs);
return -EIO;
}
}
@@ -3340,10 +3756,12 @@ static int vino_v4l2_dqbuf(struct vino_channel_settings *vcs,
}
err = vino_check_buffer(vcs, fb);
+
+ vino_v4l2_get_buffer_status(vcs, fb, b);
+
if (err)
return -EIO;
- vino_v4l2_get_buffer_status(vcs, fb, b);
break;
}
case V4L2_BUF_TYPE_VIDEO_OVERLAY:
@@ -3400,8 +3818,8 @@ static int vino_v4l2_streamoff(struct vino_channel_settings *vcs)
if (!vcs->streaming)
return 0;
- vino_capture_stop(vcs);
vcs->streaming = 0;
+ vino_capture_stop(vcs);
return 0;
}
@@ -3409,10 +3827,11 @@ static int vino_v4l2_streamoff(struct vino_channel_settings *vcs)
static int vino_v4l2_queryctrl(struct vino_channel_settings *vcs,
struct v4l2_queryctrl *queryctrl)
{
+ unsigned long flags;
int i;
int err = 0;
- spin_lock(&vino_drvdata->input_lock);
+ spin_lock_irqsave(&vino_drvdata->input_lock, flags);
switch (vcs->input) {
case VINO_INPUT_D1:
@@ -3422,6 +3841,7 @@ static int vino_v4l2_queryctrl(struct vino_channel_settings *vcs,
memcpy(queryctrl,
&vino_indycam_v4l2_controls[i],
sizeof(struct v4l2_queryctrl));
+ queryctrl->reserved[0] = 0;
goto found;
}
}
@@ -3436,6 +3856,7 @@ static int vino_v4l2_queryctrl(struct vino_channel_settings *vcs,
memcpy(queryctrl,
&vino_saa7191_v4l2_controls[i],
sizeof(struct v4l2_queryctrl));
+ queryctrl->reserved[0] = 0;
goto found;
}
}
@@ -3447,7 +3868,7 @@ static int vino_v4l2_queryctrl(struct vino_channel_settings *vcs,
}
found:
- spin_unlock(&vino_drvdata->input_lock);
+ spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
return err;
}
@@ -3455,70 +3876,72 @@ static int vino_v4l2_queryctrl(struct vino_channel_settings *vcs,
static int vino_v4l2_g_ctrl(struct vino_channel_settings *vcs,
struct v4l2_control *control)
{
- struct indycam_control indycam_ctrl;
- struct saa7191_control saa7191_ctrl;
+ unsigned long flags;
+ int i;
int err = 0;
- spin_lock(&vino_drvdata->input_lock);
+ spin_lock_irqsave(&vino_drvdata->input_lock, flags);
switch (vcs->input) {
- case VINO_INPUT_D1:
- i2c_camera_command(DECODER_INDYCAM_GET_CONTROLS,
- &indycam_ctrl);
+ case VINO_INPUT_D1: {
+ struct indycam_control indycam_ctrl;
- switch(control->id) {
- case V4L2_CID_AUTOGAIN:
- control->value = indycam_ctrl.agc;
- break;
- case V4L2_CID_AUTO_WHITE_BALANCE:
- control->value = indycam_ctrl.awb;
- break;
- case V4L2_CID_GAIN:
- control->value = indycam_ctrl.gain;
- break;
- case V4L2_CID_PRIVATE_BASE:
- control->value = indycam_ctrl.red_saturation;
- break;
- case V4L2_CID_PRIVATE_BASE + 1:
- control->value = indycam_ctrl.blue_saturation;
- break;
- case V4L2_CID_RED_BALANCE:
- control->value = indycam_ctrl.red_balance;
- break;
- case V4L2_CID_BLUE_BALANCE:
- control->value = indycam_ctrl.blue_balance;
- break;
- case V4L2_CID_EXPOSURE:
- control->value = indycam_ctrl.shutter;
- break;
- case V4L2_CID_GAMMA:
- control->value = indycam_ctrl.gamma;
- break;
- default:
+ for (i = 0; i < VINO_INDYCAM_V4L2_CONTROL_COUNT; i++) {
+ if (vino_indycam_v4l2_controls[i].id ==
+ control->id) {
+ goto found1;
+ }
+ }
+
+ err = -EINVAL;
+ goto out;
+
+found1:
+ indycam_ctrl.type = vino_indycam_v4l2_controls[i].reserved[0];
+
+ err = i2c_camera_command(DECODER_INDYCAM_GET_CONTROL,
+ &indycam_ctrl);
+ if (err) {
err = -EINVAL;
+ goto out;
}
+
+ control->value = indycam_ctrl.value;
break;
+ }
case VINO_INPUT_COMPOSITE:
- case VINO_INPUT_SVIDEO:
- i2c_decoder_command(DECODER_SAA7191_GET_CONTROLS,
- &saa7191_ctrl);
+ case VINO_INPUT_SVIDEO: {
+ struct saa7191_control saa7191_ctrl;
- switch(control->id) {
- case V4L2_CID_HUE:
- control->value = saa7191_ctrl.hue;
- break;
- case V4L2_CID_PRIVATE_BASE:
- control->value = saa7191_ctrl.vtrc;
- break;
- default:
+ for (i = 0; i < VINO_SAA7191_V4L2_CONTROL_COUNT; i++) {
+ if (vino_saa7191_v4l2_controls[i].id ==
+ control->id) {
+ goto found2;
+ }
+ }
+
+ err = -EINVAL;
+ goto out;
+
+found2:
+ saa7191_ctrl.type = vino_saa7191_v4l2_controls[i].reserved[0];
+
+ err = i2c_decoder_command(DECODER_SAA7191_GET_CONTROL,
+ &saa7191_ctrl);
+ if (err) {
err = -EINVAL;
+ goto out;
}
+
+ control->value = saa7191_ctrl.value;
break;
+ }
default:
err = -EINVAL;
}
- spin_unlock(&vino_drvdata->input_lock);
+out:
+ spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
return err;
}
@@ -3526,15 +3949,21 @@ static int vino_v4l2_g_ctrl(struct vino_channel_settings *vcs,
static int vino_v4l2_s_ctrl(struct vino_channel_settings *vcs,
struct v4l2_control *control)
{
- struct indycam_control indycam_ctrl;
- struct saa7191_control saa7191_ctrl;
+ unsigned long flags;
int i;
int err = 0;
- spin_lock(&vino_drvdata->input_lock);
+ spin_lock_irqsave(&vino_drvdata->input_lock, flags);
+
+ if (!vino_is_input_owner(vcs)) {
+ err = -EBUSY;
+ goto out;
+ }
switch (vcs->input) {
- case VINO_INPUT_D1:
+ case VINO_INPUT_D1: {
+ struct indycam_control indycam_ctrl;
+
for (i = 0; i < VINO_INDYCAM_V4L2_CONTROL_COUNT; i++) {
if (vino_indycam_v4l2_controls[i].id ==
control->id) {
@@ -3543,65 +3972,31 @@ static int vino_v4l2_s_ctrl(struct vino_channel_settings *vcs,
&& (control->value <=
vino_indycam_v4l2_controls[i].
maximum)) {
- goto ok1;
+ goto found1;
} else {
err = -ERANGE;
- goto error;
+ goto out;
}
}
}
+
err = -EINVAL;
- goto error;
+ goto out;
-ok1:
- indycam_ctrl.agc = INDYCAM_VALUE_UNCHANGED;
- indycam_ctrl.awb = INDYCAM_VALUE_UNCHANGED;
- indycam_ctrl.shutter = INDYCAM_VALUE_UNCHANGED;
- indycam_ctrl.gain = INDYCAM_VALUE_UNCHANGED;
- indycam_ctrl.red_balance = INDYCAM_VALUE_UNCHANGED;
- indycam_ctrl.blue_balance = INDYCAM_VALUE_UNCHANGED;
- indycam_ctrl.red_saturation = INDYCAM_VALUE_UNCHANGED;
- indycam_ctrl.blue_saturation = INDYCAM_VALUE_UNCHANGED;
- indycam_ctrl.gamma = INDYCAM_VALUE_UNCHANGED;
-
- switch(control->id) {
- case V4L2_CID_AUTOGAIN:
- indycam_ctrl.agc = control->value;
- break;
- case V4L2_CID_AUTO_WHITE_BALANCE:
- indycam_ctrl.awb = control->value;
- break;
- case V4L2_CID_GAIN:
- indycam_ctrl.gain = control->value;
- break;
- case V4L2_CID_PRIVATE_BASE:
- indycam_ctrl.red_saturation = control->value;
- break;
- case V4L2_CID_PRIVATE_BASE + 1:
- indycam_ctrl.blue_saturation = control->value;
- break;
- case V4L2_CID_RED_BALANCE:
- indycam_ctrl.red_balance = control->value;
- break;
- case V4L2_CID_BLUE_BALANCE:
- indycam_ctrl.blue_balance = control->value;
- break;
- case V4L2_CID_EXPOSURE:
- indycam_ctrl.shutter = control->value;
- break;
- case V4L2_CID_GAMMA:
- indycam_ctrl.gamma = control->value;
- break;
- default:
- err = -EINVAL;
- }
+found1:
+ indycam_ctrl.type = vino_indycam_v4l2_controls[i].reserved[0];
+ indycam_ctrl.value = control->value;
- if (!err)
- i2c_camera_command(DECODER_INDYCAM_SET_CONTROLS,
- &indycam_ctrl);
+ err = i2c_camera_command(DECODER_INDYCAM_SET_CONTROL,
+ &indycam_ctrl);
+ if (err)
+ err = -EINVAL;
break;
+ }
case VINO_INPUT_COMPOSITE:
- case VINO_INPUT_SVIDEO:
+ case VINO_INPUT_SVIDEO: {
+ struct saa7191_control saa7191_ctrl;
+
for (i = 0; i < VINO_SAA7191_V4L2_CONTROL_COUNT; i++) {
if (vino_saa7191_v4l2_controls[i].id ==
control->id) {
@@ -3610,41 +4005,32 @@ ok1:
&& (control->value <=
vino_saa7191_v4l2_controls[i].
maximum)) {
- goto ok2;
+ goto found2;
} else {
err = -ERANGE;
- goto error;
+ goto out;
}
}
}
err = -EINVAL;
- goto error;
+ goto out;
-ok2:
- saa7191_ctrl.hue = SAA7191_VALUE_UNCHANGED;
- saa7191_ctrl.vtrc = SAA7191_VALUE_UNCHANGED;
+found2:
+ saa7191_ctrl.type = vino_saa7191_v4l2_controls[i].reserved[0];
+ saa7191_ctrl.value = control->value;
- switch(control->id) {
- case V4L2_CID_HUE:
- saa7191_ctrl.hue = control->value;
- break;
- case V4L2_CID_PRIVATE_BASE:
- saa7191_ctrl.vtrc = control->value;
- break;
- default:
- err = -EINVAL;
- }
-
- if (!err)
- i2c_decoder_command(DECODER_SAA7191_SET_CONTROLS,
- &saa7191_ctrl);
+ err = i2c_decoder_command(DECODER_SAA7191_SET_CONTROL,
+ &saa7191_ctrl);
+ if (err)
+ err = -EINVAL;
break;
+ }
default:
err = -EINVAL;
}
-error:
- spin_unlock(&vino_drvdata->input_lock);
+out:
+ spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
return err;
}
@@ -3864,9 +4250,9 @@ static unsigned int vino_poll(struct file *file, poll_table *pt)
over:
dprintk("poll(): data %savailable\n",
(outgoing > 0) ? "" : "not ");
- if (outgoing > 0) {
+
+ if (outgoing > 0)
ret = POLLIN | POLLRDNORM;
- }
error:
@@ -3879,6 +4265,7 @@ static int vino_do_ioctl(struct inode *inode, struct file *file,
struct video_device *dev = video_devdata(file);
struct vino_channel_settings *vcs = video_get_drvdata(dev);
+#ifdef VINO_DEBUG
switch (_IOC_TYPE(cmd)) {
case 'v':
dprintk("ioctl(): V4L1 unsupported (0x%08x)\n", cmd);
@@ -3890,9 +4277,9 @@ static int vino_do_ioctl(struct inode *inode, struct file *file,
default:
dprintk("ioctl(): unsupported command 0x%08x\n", cmd);
}
+#endif
switch (cmd) {
- /* TODO: V4L1 interface (use compatibility layer?) */
/* V4L2 interface */
case VIDIOC_QUERYCAP: {
vino_v4l2_querycap(arg);
@@ -3910,6 +4297,9 @@ static int vino_do_ioctl(struct inode *inode, struct file *file,
case VIDIOC_ENUMSTD: {
return vino_v4l2_enumstd(vcs, arg);
}
+ case VIDIOC_QUERYSTD: {
+ return vino_v4l2_querystd(vcs, arg);
+ }
case VIDIOC_G_STD: {
return vino_v4l2_g_std(vcs, arg);
}
@@ -4099,8 +4489,7 @@ static int vino_probe(void)
return -ENODEV;
}
- printk(KERN_INFO "VINO with chip ID %ld, revision %ld found\n",
- VINO_ID_VALUE(rev_id), VINO_REV_NUM(rev_id));
+ printk(KERN_INFO "VINO revision %ld found\n", VINO_REV_NUM(rev_id));
return 0;
}
diff --git a/drivers/media/video/wm8775.c b/drivers/media/video/wm8775.c
new file mode 100644
index 000000000000..22f286222004
--- /dev/null
+++ b/drivers/media/video/wm8775.c
@@ -0,0 +1,254 @@
+/*
+ * wm8775 - driver version 0.0.1
+ *
+ * Copyright (C) 2004 Ulf Eklund <ivtv at eklund.to>
+ *
+ * Based on saa7115 driver
+ *
+ * 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/module.h>
+#include <linux/types.h>
+#include <linux/ioctl.h>
+#include <asm/uaccess.h>
+#include <linux/i2c.h>
+#include <linux/i2c-id.h>
+#include <linux/videodev.h>
+#include <media/audiochip.h>
+
+MODULE_DESCRIPTION("wm8775 driver");
+MODULE_AUTHOR("Ulf Eklund");
+MODULE_LICENSE("GPL");
+
+#define wm8775_err(fmt, arg...) do { \
+ printk(KERN_ERR "%s %d-%04x: " fmt, client->driver->name, \
+ i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0)
+#define wm8775_info(fmt, arg...) do { \
+ printk(KERN_INFO "%s %d-%04x: " fmt, client->driver->name, \
+ i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0)
+
+
+static unsigned short normal_i2c[] = { 0x36 >> 1, I2C_CLIENT_END };
+
+
+I2C_CLIENT_INSMOD;
+
+/* ----------------------------------------------------------------------- */
+
+enum {
+ R7 = 7, R11 = 11,
+ R12, R13, R14, R15, R16, R17, R18, R19, R20, R21, R23 = 23,
+ TOT_REGS
+};
+
+struct wm8775_state {
+ u8 input; /* Last selected input (0-0xf) */
+ u8 muted;
+};
+
+static int wm8775_write(struct i2c_client *client, int reg, u16 val)
+{
+ int i;
+
+ if (reg < 0 || reg >= TOT_REGS) {
+ wm8775_err("Invalid register R%d\n", reg);
+ return -1;
+ }
+
+ for (i = 0; i < 3; i++) {
+ if (i2c_smbus_write_byte_data(client, (reg << 1) |
+ (val >> 8), val & 0xff) == 0) {
+ return 0;
+ }
+ }
+ wm8775_err("I2C: cannot write %03x to register R%d\n", val, reg);
+ return -1;
+}
+
+static int wm8775_command(struct i2c_client *client, unsigned int cmd,
+ void *arg)
+{
+ struct wm8775_state *state = i2c_get_clientdata(client);
+ int *input = arg;
+
+ switch (cmd) {
+ case AUDC_SET_INPUT:
+ wm8775_write(client, R21, 0x0c0);
+ wm8775_write(client, R14, 0x1d4);
+ wm8775_write(client, R15, 0x1d4);
+
+ if (*input == AUDIO_RADIO) {
+ wm8775_write(client, R21, 0x108);
+ state->input = 8;
+ state->muted = 0;
+ break;
+ }
+ if (*input == AUDIO_MUTE) {
+ state->muted = 1;
+ break;
+ }
+ if (*input == AUDIO_UNMUTE) {
+ wm8775_write(client, R21, 0x100 + state->input);
+ state->muted = 0;
+ break;
+ }
+ /* All other inputs... */
+ wm8775_write(client, R21, 0x102);
+ state->input = 2;
+ state->muted = 0;
+ break;
+
+ case VIDIOC_LOG_STATUS:
+ wm8775_info("Input: %s%s\n",
+ state->input == 8 ? "radio" : "default",
+ state->muted ? " (muted)" : "");
+ break;
+
+ case VIDIOC_S_FREQUENCY:
+ /* If I remove this, then it can happen that I have no
+ sound the first time I tune from static to a valid channel.
+ It's difficult to reproduce and is almost certainly related
+ to the zero cross detect circuit. */
+ wm8775_write(client, R21, 0x0c0);
+ wm8775_write(client, R14, 0x1d4);
+ wm8775_write(client, R15, 0x1d4);
+ wm8775_write(client, R21, 0x100 + state->input);
+ break;
+
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+
+/* ----------------------------------------------------------------------- */
+
+/* i2c implementation */
+
+/*
+ * Generic i2c probe
+ * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
+ */
+
+static struct i2c_driver i2c_driver;
+
+static int wm8775_attach(struct i2c_adapter *adapter, int address, int kind)
+{
+ struct i2c_client *client;
+ struct wm8775_state *state;
+
+ /* Check if the adapter supports the needed features */
+ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+ return 0;
+
+ client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
+ if (client == 0)
+ return -ENOMEM;
+
+ memset(client, 0, sizeof(struct i2c_client));
+ client->addr = address;
+ client->adapter = adapter;
+ client->driver = &i2c_driver;
+ client->flags = I2C_CLIENT_ALLOW_USE;
+ snprintf(client->name, sizeof(client->name) - 1, "wm8775");
+
+ wm8775_info("chip found @ 0x%x (%s)\n", address << 1, adapter->name);
+
+ state = kmalloc(sizeof(struct wm8775_state), GFP_KERNEL);
+ if (state == NULL) {
+ kfree(client);
+ return -ENOMEM;
+ }
+ state->input = 2;
+ state->muted = 0;
+ i2c_set_clientdata(client, state);
+
+ /* initialize wm8775 */
+ wm8775_write(client, R23, 0x000); /* RESET */
+ wm8775_write(client, R7, 0x000); /* Disable zero cross detect timeout */
+ wm8775_write(client, R11, 0x021); /* Left justified, 24-bit mode */
+ wm8775_write(client, R12, 0x102); /* Master mode, clock ratio 256fs */
+ wm8775_write(client, R13, 0x000); /* Powered up */
+ wm8775_write(client, R14, 0x1d4); /* ADC gain +2.5dB, enable zero cross */
+ wm8775_write(client, R15, 0x1d4); /* ADC gain +2.5dB, enable zero cross */
+ wm8775_write(client, R16, 0x1bf); /* ALC Stereo, ALC target level -1dB FS */
+ /* max gain +8dB */
+ wm8775_write(client, R17, 0x185); /* Enable gain control, use zero cross */
+ /* detection, ALC hold time 42.6 ms */
+ wm8775_write(client, R18, 0x0a2); /* ALC gain ramp up delay 34 s, */
+ /* ALC gain ramp down delay 33 ms */
+ wm8775_write(client, R19, 0x005); /* Enable noise gate, threshold -72dBfs */
+ wm8775_write(client, R20, 0x07a); /* Transient window 4ms, lower PGA gain */
+ /* limit -1dB */
+ wm8775_write(client, R21, 0x102); /* LRBOTH = 1, use input 2. */
+ i2c_attach_client(client);
+
+ return 0;
+}
+
+static int wm8775_probe(struct i2c_adapter *adapter)
+{
+#ifdef I2C_CLASS_TV_ANALOG
+ if (adapter->class & I2C_CLASS_TV_ANALOG)
+#else
+ if (adapter->id == I2C_HW_B_BT848)
+#endif
+ return i2c_probe(adapter, &addr_data, wm8775_attach);
+ return 0;
+}
+
+static int wm8775_detach(struct i2c_client *client)
+{
+ int err;
+
+ err = i2c_detach_client(client);
+ if (err) {
+ return err;
+ }
+ kfree(client);
+
+ return 0;
+}
+
+/* ----------------------------------------------------------------------- */
+
+/* i2c implementation */
+static struct i2c_driver i2c_driver = {
+ .name = "wm8775",
+
+ .id = I2C_DRIVERID_WM8775,
+ .flags = I2C_DF_NOTIFY,
+
+ .attach_adapter = wm8775_probe,
+ .detach_client = wm8775_detach,
+ .command = wm8775_command,
+ .owner = THIS_MODULE,
+};
+
+
+static int __init wm8775_init_module(void)
+{
+ return i2c_add_driver(&i2c_driver);
+}
+
+static void __exit wm8775_cleanup_module(void)
+{
+ i2c_del_driver(&i2c_driver);
+}
+
+module_init(wm8775_init_module);
+module_exit(wm8775_cleanup_module);
diff --git a/drivers/media/video/zoran_card.c b/drivers/media/video/zoran_card.c
index eed2acea1779..39a0d238900e 100644
--- a/drivers/media/video/zoran_card.c
+++ b/drivers/media/video/zoran_card.c
@@ -1057,10 +1057,8 @@ zr36057_init (struct zoran *zr)
KERN_ERR
"%s: zr36057_init() - kmalloc (STAT_COM) failed\n",
ZR_DEVNAME(zr));
- if (vdev)
- kfree(vdev);
- if (mem)
- kfree((void *)mem);
+ kfree(vdev);
+ kfree((void *)mem);
return -ENOMEM;
}
memset((void *) mem, 0, mem_needed);
@@ -1105,15 +1103,15 @@ zoran_release (struct zoran *zr)
/* unregister videocodec bus */
if (zr->codec) {
struct videocodec_master *master = zr->codec->master_data;
+
videocodec_detach(zr->codec);
- if (master)
- kfree(master);
+ kfree(master);
}
if (zr->vfe) {
struct videocodec_master *master = zr->vfe->master_data;
+
videocodec_detach(zr->vfe);
- if (master)
- kfree(master);
+ kfree(master);
}
/* unregister i2c bus */
diff --git a/drivers/media/video/zoran_driver.c b/drivers/media/video/zoran_driver.c
index 53adeb70f2ca..07bde9acd672 100644
--- a/drivers/media/video/zoran_driver.c
+++ b/drivers/media/video/zoran_driver.c
@@ -996,8 +996,6 @@ zoran_jpg_queue_frame (struct file *file,
return -EINVAL;
}
- spin_lock_irqsave(&zr->spinlock, flags);
-
if (fh->jpg_buffers.active == ZORAN_FREE) {
if (zr->jpg_buffers.active == ZORAN_FREE) {
zr->jpg_buffers = fh->jpg_buffers;
@@ -1016,6 +1014,8 @@ zoran_jpg_queue_frame (struct file *file,
zr36057_enable_jpg(zr, mode);
}
+ spin_lock_irqsave(&zr->spinlock, flags);
+
if (!res) {
switch (zr->jpg_buffers.buffer[num].state) {
case BUZ_STATE_DONE:
diff --git a/drivers/media/video/zr36016.c b/drivers/media/video/zr36016.c
index d4740a89cea1..4ed898585c70 100644
--- a/drivers/media/video/zr36016.c
+++ b/drivers/media/video/zr36016.c
@@ -26,7 +26,6 @@
#define ZR016_VERSION "v0.7"
-#include <linux/version.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
diff --git a/drivers/media/video/zr36050.c b/drivers/media/video/zr36050.c
index 13b1e7b6fd6e..0144576a6123 100644
--- a/drivers/media/video/zr36050.c
+++ b/drivers/media/video/zr36050.c
@@ -26,7 +26,6 @@
#define ZR050_VERSION "v0.7.1"
-#include <linux/version.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
diff --git a/drivers/media/video/zr36060.c b/drivers/media/video/zr36060.c
index b50dc403e6db..129744a07abd 100644
--- a/drivers/media/video/zr36060.c
+++ b/drivers/media/video/zr36060.c
@@ -26,7 +26,6 @@
#define ZR060_VERSION "v0.7"
-#include <linux/version.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c
index 790a2932ded9..74022316fc63 100644
--- a/drivers/message/fusion/mptbase.c
+++ b/drivers/message/fusion/mptbase.c
@@ -47,7 +47,6 @@
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
#include <linux/config.h>
-#include <linux/version.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/errno.h>
@@ -92,9 +91,9 @@ static int mfcounter = 0;
* Public data...
*/
int mpt_lan_index = -1;
-int mpt_stm_index = -1;
+static int mpt_stm_index = -1;
-struct proc_dir_entry *mpt_proc_root_dir;
+static struct proc_dir_entry *mpt_proc_root_dir;
#define WHOINIT_UNKNOWN 0xAA
@@ -6272,7 +6271,6 @@ EXPORT_SYMBOL(mpt_resume);
EXPORT_SYMBOL(mpt_suspend);
#endif
EXPORT_SYMBOL(ioc_list);
-EXPORT_SYMBOL(mpt_proc_root_dir);
EXPORT_SYMBOL(mpt_register);
EXPORT_SYMBOL(mpt_deregister);
EXPORT_SYMBOL(mpt_event_register);
@@ -6290,7 +6288,6 @@ EXPORT_SYMBOL(mpt_verify_adapter);
EXPORT_SYMBOL(mpt_GetIocState);
EXPORT_SYMBOL(mpt_print_ioc_summary);
EXPORT_SYMBOL(mpt_lan_index);
-EXPORT_SYMBOL(mpt_stm_index);
EXPORT_SYMBOL(mpt_HardResetHandler);
EXPORT_SYMBOL(mpt_config);
EXPORT_SYMBOL(mpt_toolbox);
diff --git a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h
index 75105277e22f..8ad277a9afa1 100644
--- a/drivers/message/fusion/mptbase.h
+++ b/drivers/message/fusion/mptbase.h
@@ -49,7 +49,6 @@
#define MPTBASE_H_INCLUDED
/*{-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-#include <linux/version.h>
#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/pci.h>
@@ -77,8 +76,8 @@
#define COPYRIGHT "Copyright (c) 1999-2005 " MODULEAUTHOR
#endif
-#define MPT_LINUX_VERSION_COMMON "3.03.03"
-#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.03.03"
+#define MPT_LINUX_VERSION_COMMON "3.03.04"
+#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.03.04"
#define WHAT_MAGIC_STRING "@" "(" "#" ")"
#define show_mptmod_ver(s,ver) \
@@ -421,6 +420,17 @@ typedef struct _MPT_IOCTL {
struct semaphore sem_ioc;
} MPT_IOCTL;
+#define MPT_SAS_MGMT_STATUS_RF_VALID 0x02 /* The Reply Frame is VALID */
+#define MPT_SAS_MGMT_STATUS_COMMAND_GOOD 0x10 /* Command Status GOOD */
+#define MPT_SAS_MGMT_STATUS_TM_FAILED 0x40 /* User TM request failed */
+
+typedef struct _MPT_SAS_MGMT {
+ struct semaphore mutex;
+ struct completion done;
+ u8 reply[MPT_DEFAULT_FRAME_SIZE]; /* reply frame data */
+ u8 status; /* current command status */
+}MPT_SAS_MGMT;
+
/*
* Event Structure and define
*/
@@ -604,6 +614,7 @@ typedef struct _MPT_ADAPTER
struct list_head list;
struct net_device *netdev;
struct list_head sas_topology;
+ MPT_SAS_MGMT sas_mgmt;
} MPT_ADAPTER;
/*
@@ -995,10 +1006,8 @@ extern int mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode);
* Public data decl's...
*/
extern struct list_head ioc_list;
-extern struct proc_dir_entry *mpt_proc_root_dir;
extern int mpt_lan_index; /* needed by mptlan.c */
-extern int mpt_stm_index; /* needed by mptstm.c */
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
#endif /* } __KERNEL__ */
diff --git a/drivers/message/fusion/mptctl.c b/drivers/message/fusion/mptctl.c
index cb2d59d5f5af..602138f8544d 100644
--- a/drivers/message/fusion/mptctl.c
+++ b/drivers/message/fusion/mptctl.c
@@ -45,7 +45,6 @@
*/
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-#include <linux/version.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/errno.h>
diff --git a/drivers/message/fusion/mptctl.h b/drivers/message/fusion/mptctl.h
index 28754a9cb803..518996e03481 100644
--- a/drivers/message/fusion/mptctl.h
+++ b/drivers/message/fusion/mptctl.h
@@ -49,7 +49,6 @@
#define MPTCTL_H_INCLUDED
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-#include "linux/version.h"
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
diff --git a/drivers/message/fusion/mptlan.c b/drivers/message/fusion/mptlan.c
index ed3c891e388f..014085d8ec85 100644
--- a/drivers/message/fusion/mptlan.c
+++ b/drivers/message/fusion/mptlan.c
@@ -511,7 +511,7 @@ mpt_lan_close(struct net_device *dev)
{
struct mpt_lan_priv *priv = netdev_priv(dev);
MPT_ADAPTER *mpt_dev = priv->mpt_dev;
- unsigned int timeout;
+ unsigned long timeout;
int i;
dlprintk((KERN_INFO MYNAM ": mpt_lan_close called\n"));
@@ -526,11 +526,9 @@ mpt_lan_close(struct net_device *dev)
mpt_lan_reset(dev);
- timeout = 2 * HZ;
- while (atomic_read(&priv->buckets_out) && --timeout) {
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(1);
- }
+ timeout = jiffies + 2 * HZ;
+ while (atomic_read(&priv->buckets_out) && time_before(jiffies, timeout))
+ schedule_timeout_interruptible(1);
for (i = 0; i < priv->max_buckets_out; i++) {
if (priv->RcvCtl[i].skb != NULL) {
diff --git a/drivers/message/fusion/mptlan.h b/drivers/message/fusion/mptlan.h
index 750e343eb981..3726ecba5707 100644
--- a/drivers/message/fusion/mptlan.h
+++ b/drivers/message/fusion/mptlan.h
@@ -66,7 +66,6 @@
#include <linux/slab.h>
#include <linux/miscdevice.h>
#include <linux/spinlock.h>
-#include <linux/version.h>
#include <linux/workqueue.h>
#include <linux/delay.h>
// #include <linux/trdevice.h>
diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c
index 7de19a84dc74..e0a8bb8ba7d8 100644
--- a/drivers/message/fusion/mptsas.c
+++ b/drivers/message/fusion/mptsas.c
@@ -83,6 +83,7 @@ MODULE_PARM_DESC(mpt_pt_clear,
static int mptsasDoneCtx = -1;
static int mptsasTaskCtx = -1;
static int mptsasInternalCtx = -1; /* Used only for internal commands */
+static int mptsasMgmtCtx = -1;
/*
@@ -123,6 +124,104 @@ struct mptsas_portinfo {
struct mptsas_phyinfo *phy_info;
};
+
+#ifdef SASDEBUG
+static void mptsas_print_phy_data(MPI_SAS_IO_UNIT0_PHY_DATA *phy_data)
+{
+ printk("---- IO UNIT PAGE 0 ------------\n");
+ printk("Handle=0x%X\n",
+ le16_to_cpu(phy_data->AttachedDeviceHandle));
+ printk("Controller Handle=0x%X\n",
+ le16_to_cpu(phy_data->ControllerDevHandle));
+ printk("Port=0x%X\n", phy_data->Port);
+ printk("Port Flags=0x%X\n", phy_data->PortFlags);
+ printk("PHY Flags=0x%X\n", phy_data->PhyFlags);
+ printk("Negotiated Link Rate=0x%X\n", phy_data->NegotiatedLinkRate);
+ printk("Controller PHY Device Info=0x%X\n",
+ le32_to_cpu(phy_data->ControllerPhyDeviceInfo));
+ printk("DiscoveryStatus=0x%X\n",
+ le32_to_cpu(phy_data->DiscoveryStatus));
+ printk("\n");
+}
+
+static void mptsas_print_phy_pg0(SasPhyPage0_t *pg0)
+{
+ __le64 sas_address;
+
+ memcpy(&sas_address, &pg0->SASAddress, sizeof(__le64));
+
+ printk("---- SAS PHY PAGE 0 ------------\n");
+ printk("Attached Device Handle=0x%X\n",
+ le16_to_cpu(pg0->AttachedDevHandle));
+ printk("SAS Address=0x%llX\n",
+ (unsigned long long)le64_to_cpu(sas_address));
+ printk("Attached PHY Identifier=0x%X\n", pg0->AttachedPhyIdentifier);
+ printk("Attached Device Info=0x%X\n",
+ le32_to_cpu(pg0->AttachedDeviceInfo));
+ printk("Programmed Link Rate=0x%X\n", pg0->ProgrammedLinkRate);
+ printk("Change Count=0x%X\n", pg0->ChangeCount);
+ printk("PHY Info=0x%X\n", le32_to_cpu(pg0->PhyInfo));
+ printk("\n");
+}
+
+static void mptsas_print_phy_pg1(SasPhyPage1_t *pg1)
+{
+ printk("---- SAS PHY PAGE 1 ------------\n");
+ printk("Invalid Dword Count=0x%x\n", pg1->InvalidDwordCount);
+ printk("Running Disparity Error Count=0x%x\n",
+ pg1->RunningDisparityErrorCount);
+ printk("Loss Dword Synch Count=0x%x\n", pg1->LossDwordSynchCount);
+ printk("PHY Reset Problem Count=0x%x\n", pg1->PhyResetProblemCount);
+ printk("\n");
+}
+
+static void mptsas_print_device_pg0(SasDevicePage0_t *pg0)
+{
+ __le64 sas_address;
+
+ memcpy(&sas_address, &pg0->SASAddress, sizeof(__le64));
+
+ printk("---- SAS DEVICE PAGE 0 ---------\n");
+ printk("Handle=0x%X\n" ,le16_to_cpu(pg0->DevHandle));
+ printk("Enclosure Handle=0x%X\n", le16_to_cpu(pg0->EnclosureHandle));
+ printk("Slot=0x%X\n", le16_to_cpu(pg0->Slot));
+ printk("SAS Address=0x%llX\n", le64_to_cpu(sas_address));
+ printk("Target ID=0x%X\n", pg0->TargetID);
+ printk("Bus=0x%X\n", pg0->Bus);
+ /* The PhyNum field specifies the PHY number of the parent
+ * device this device is linked to
+ */
+ printk("Parent Phy Num=0x%X\n", pg0->PhyNum);
+ printk("Access Status=0x%X\n", le16_to_cpu(pg0->AccessStatus));
+ printk("Device Info=0x%X\n", le32_to_cpu(pg0->DeviceInfo));
+ printk("Flags=0x%X\n", le16_to_cpu(pg0->Flags));
+ printk("Physical Port=0x%X\n", pg0->PhysicalPort);
+ printk("\n");
+}
+
+static void mptsas_print_expander_pg1(SasExpanderPage1_t *pg1)
+{
+ printk("---- SAS EXPANDER PAGE 1 ------------\n");
+
+ printk("Physical Port=0x%X\n", pg1->PhysicalPort);
+ printk("PHY Identifier=0x%X\n", pg1->PhyIdentifier);
+ printk("Negotiated Link Rate=0x%X\n", pg1->NegotiatedLinkRate);
+ printk("Programmed Link Rate=0x%X\n", pg1->ProgrammedLinkRate);
+ printk("Hardware Link Rate=0x%X\n", pg1->HwLinkRate);
+ printk("Owner Device Handle=0x%X\n",
+ le16_to_cpu(pg1->OwnerDevHandle));
+ printk("Attached Device Handle=0x%X\n",
+ le16_to_cpu(pg1->AttachedDevHandle));
+}
+#else
+#define mptsas_print_phy_data(phy_data) do { } while (0)
+#define mptsas_print_phy_pg0(pg0) do { } while (0)
+#define mptsas_print_phy_pg1(pg1) do { } while (0)
+#define mptsas_print_device_pg0(pg0) do { } while (0)
+#define mptsas_print_expander_pg1(pg1) do { } while (0)
+#endif
+
+
/*
* This is pretty ugly. We will be able to seriously clean it up
* once the DV code in mptscsih goes away and we can properly
@@ -200,91 +299,159 @@ static struct scsi_host_template mptsas_driver_template = {
.use_clustering = ENABLE_CLUSTERING,
};
-static struct sas_function_template mptsas_transport_functions = {
-};
-
-static struct scsi_transport_template *mptsas_transport_template;
-
-#ifdef SASDEBUG
-static void mptsas_print_phy_data(MPI_SAS_IO_UNIT0_PHY_DATA *phy_data)
+static inline MPT_ADAPTER *phy_to_ioc(struct sas_phy *phy)
{
- printk("---- IO UNIT PAGE 0 ------------\n");
- printk("Handle=0x%X\n",
- le16_to_cpu(phy_data->AttachedDeviceHandle));
- printk("Controller Handle=0x%X\n",
- le16_to_cpu(phy_data->ControllerDevHandle));
- printk("Port=0x%X\n", phy_data->Port);
- printk("Port Flags=0x%X\n", phy_data->PortFlags);
- printk("PHY Flags=0x%X\n", phy_data->PhyFlags);
- printk("Negotiated Link Rate=0x%X\n", phy_data->NegotiatedLinkRate);
- printk("Controller PHY Device Info=0x%X\n",
- le32_to_cpu(phy_data->ControllerPhyDeviceInfo));
- printk("DiscoveryStatus=0x%X\n",
- le32_to_cpu(phy_data->DiscoveryStatus));
- printk("\n");
+ struct Scsi_Host *shost = dev_to_shost(phy->dev.parent);
+ return ((MPT_SCSI_HOST *)shost->hostdata)->ioc;
}
-static void mptsas_print_phy_pg0(SasPhyPage0_t *pg0)
+static int mptsas_get_linkerrors(struct sas_phy *phy)
{
- __le64 sas_address;
+ MPT_ADAPTER *ioc = phy_to_ioc(phy);
+ ConfigExtendedPageHeader_t hdr;
+ CONFIGPARMS cfg;
+ SasPhyPage1_t *buffer;
+ dma_addr_t dma_handle;
+ int error;
- memcpy(&sas_address, &pg0->SASAddress, sizeof(__le64));
+ hdr.PageVersion = MPI_SASPHY1_PAGEVERSION;
+ hdr.ExtPageLength = 0;
+ hdr.PageNumber = 1 /* page number 1*/;
+ hdr.Reserved1 = 0;
+ hdr.Reserved2 = 0;
+ hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
+ hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_PHY;
- printk("---- SAS PHY PAGE 0 ------------\n");
- printk("Attached Device Handle=0x%X\n",
- le16_to_cpu(pg0->AttachedDevHandle));
- printk("SAS Address=0x%llX\n",
- (unsigned long long)le64_to_cpu(sas_address));
- printk("Attached PHY Identifier=0x%X\n", pg0->AttachedPhyIdentifier);
- printk("Attached Device Info=0x%X\n",
- le32_to_cpu(pg0->AttachedDeviceInfo));
- printk("Programmed Link Rate=0x%X\n", pg0->ProgrammedLinkRate);
- printk("Change Count=0x%X\n", pg0->ChangeCount);
- printk("PHY Info=0x%X\n", le32_to_cpu(pg0->PhyInfo));
- printk("\n");
-}
+ cfg.cfghdr.ehdr = &hdr;
+ cfg.physAddr = -1;
+ cfg.pageAddr = phy->identify.phy_identifier;
+ cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
+ cfg.dir = 0; /* read */
+ cfg.timeout = 10;
-static void mptsas_print_device_pg0(SasDevicePage0_t *pg0)
-{
- __le64 sas_address;
+ error = mpt_config(ioc, &cfg);
+ if (error)
+ return error;
+ if (!hdr.ExtPageLength)
+ return -ENXIO;
- memcpy(&sas_address, &pg0->SASAddress, sizeof(__le64));
+ buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
+ &dma_handle);
+ if (!buffer)
+ return -ENOMEM;
- printk("---- SAS DEVICE PAGE 0 ---------\n");
- printk("Handle=0x%X\n" ,le16_to_cpu(pg0->DevHandle));
- printk("Enclosure Handle=0x%X\n", le16_to_cpu(pg0->EnclosureHandle));
- printk("Slot=0x%X\n", le16_to_cpu(pg0->Slot));
- printk("SAS Address=0x%llX\n", le64_to_cpu(sas_address));
- printk("Target ID=0x%X\n", pg0->TargetID);
- printk("Bus=0x%X\n", pg0->Bus);
- printk("Parent Phy Num=0x%X\n", pg0->PhyNum);
- printk("Access Status=0x%X\n", le16_to_cpu(pg0->AccessStatus));
- printk("Device Info=0x%X\n", le32_to_cpu(pg0->DeviceInfo));
- printk("Flags=0x%X\n", le16_to_cpu(pg0->Flags));
- printk("Physical Port=0x%X\n", pg0->PhysicalPort);
- printk("\n");
+ cfg.physAddr = dma_handle;
+ cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
+
+ error = mpt_config(ioc, &cfg);
+ if (error)
+ goto out_free_consistent;
+
+ mptsas_print_phy_pg1(buffer);
+
+ phy->invalid_dword_count = le32_to_cpu(buffer->InvalidDwordCount);
+ phy->running_disparity_error_count =
+ le32_to_cpu(buffer->RunningDisparityErrorCount);
+ phy->loss_of_dword_sync_count =
+ le32_to_cpu(buffer->LossDwordSynchCount);
+ phy->phy_reset_problem_count =
+ le32_to_cpu(buffer->PhyResetProblemCount);
+
+ out_free_consistent:
+ pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
+ buffer, dma_handle);
+ return error;
}
-static void mptsas_print_expander_pg1(SasExpanderPage1_t *pg1)
+static int mptsas_mgmt_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req,
+ MPT_FRAME_HDR *reply)
{
- printk("---- SAS EXPANDER PAGE 1 ------------\n");
+ ioc->sas_mgmt.status |= MPT_SAS_MGMT_STATUS_COMMAND_GOOD;
+ if (reply != NULL) {
+ ioc->sas_mgmt.status |= MPT_SAS_MGMT_STATUS_RF_VALID;
+ memcpy(ioc->sas_mgmt.reply, reply,
+ min(ioc->reply_sz, 4 * reply->u.reply.MsgLength));
+ }
+ complete(&ioc->sas_mgmt.done);
+ return 1;
+}
- printk("Physical Port=0x%X\n", pg1->PhysicalPort);
- printk("PHY Identifier=0x%X\n", pg1->PhyIdentifier);
- printk("Negotiated Link Rate=0x%X\n", pg1->NegotiatedLinkRate);
- printk("Programmed Link Rate=0x%X\n", pg1->ProgrammedLinkRate);
- printk("Hardware Link Rate=0x%X\n", pg1->HwLinkRate);
- printk("Owner Device Handle=0x%X\n",
- le16_to_cpu(pg1->OwnerDevHandle));
- printk("Attached Device Handle=0x%X\n",
- le16_to_cpu(pg1->AttachedDevHandle));
+static int mptsas_phy_reset(struct sas_phy *phy, int hard_reset)
+{
+ MPT_ADAPTER *ioc = phy_to_ioc(phy);
+ SasIoUnitControlRequest_t *req;
+ SasIoUnitControlReply_t *reply;
+ MPT_FRAME_HDR *mf;
+ MPIHeader_t *hdr;
+ unsigned long timeleft;
+ int error = -ERESTARTSYS;
+
+ /* not implemented for expanders */
+ if (phy->identify.target_port_protocols & SAS_PROTOCOL_SMP)
+ return -ENXIO;
+
+ if (down_interruptible(&ioc->sas_mgmt.mutex))
+ goto out;
+
+ mf = mpt_get_msg_frame(mptsasMgmtCtx, ioc);
+ if (!mf) {
+ error = -ENOMEM;
+ goto out_unlock;
+ }
+
+ hdr = (MPIHeader_t *) mf;
+ req = (SasIoUnitControlRequest_t *)mf;
+ memset(req, 0, sizeof(SasIoUnitControlRequest_t));
+ req->Function = MPI_FUNCTION_SAS_IO_UNIT_CONTROL;
+ req->MsgContext = hdr->MsgContext;
+ req->Operation = hard_reset ?
+ MPI_SAS_OP_PHY_HARD_RESET : MPI_SAS_OP_PHY_LINK_RESET;
+ req->PhyNum = phy->identify.phy_identifier;
+
+ mpt_put_msg_frame(mptsasMgmtCtx, ioc, mf);
+
+ timeleft = wait_for_completion_timeout(&ioc->sas_mgmt.done,
+ 10 * HZ);
+ if (!timeleft) {
+ /* On timeout reset the board */
+ mpt_free_msg_frame(ioc, mf);
+ mpt_HardResetHandler(ioc, CAN_SLEEP);
+ error = -ETIMEDOUT;
+ goto out_unlock;
+ }
+
+ /* a reply frame is expected */
+ if ((ioc->sas_mgmt.status &
+ MPT_IOCTL_STATUS_RF_VALID) == 0) {
+ error = -ENXIO;
+ goto out_unlock;
+ }
+
+ /* process the completed Reply Message Frame */
+ reply = (SasIoUnitControlReply_t *)ioc->sas_mgmt.reply;
+ if (reply->IOCStatus != MPI_IOCSTATUS_SUCCESS) {
+ printk("%s: IOCStatus=0x%X IOCLogInfo=0x%X\n",
+ __FUNCTION__,
+ reply->IOCStatus,
+ reply->IOCLogInfo);
+ error = -ENXIO;
+ goto out_unlock;
+ }
+
+ error = 0;
+
+ out_unlock:
+ up(&ioc->sas_mgmt.mutex);
+ out:
+ return error;
}
-#else
-#define mptsas_print_phy_data(phy_data) do { } while (0)
-#define mptsas_print_phy_pg0(pg0) do { } while (0)
-#define mptsas_print_device_pg0(pg0) do { } while (0)
-#define mptsas_print_expander_pg1(pg1) do { } while (0)
-#endif
+
+static struct sas_function_template mptsas_transport_functions = {
+ .get_linkerrors = mptsas_get_linkerrors,
+ .phy_reset = mptsas_phy_reset,
+};
+
+static struct scsi_transport_template *mptsas_transport_template;
static int
mptsas_sas_io_unit_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info)
@@ -680,7 +847,7 @@ mptsas_parse_device_info(struct sas_identify *identify,
}
static int mptsas_probe_one_phy(struct device *dev,
- struct mptsas_phyinfo *phy_info, int index)
+ struct mptsas_phyinfo *phy_info, int index, int local)
{
struct sas_phy *port;
int error;
@@ -773,6 +940,9 @@ static int mptsas_probe_one_phy(struct device *dev,
break;
}
+ if (local)
+ port->local_attached = 1;
+
error = sas_phy_add(port);
if (error) {
sas_phy_free(port);
@@ -838,7 +1008,7 @@ mptsas_probe_hba_phys(MPT_ADAPTER *ioc, int *index)
}
mptsas_probe_one_phy(&ioc->sh->shost_gendev,
- &port_info->phy_info[i], *index);
+ &port_info->phy_info[i], *index, 1);
(*index)++;
}
@@ -909,7 +1079,8 @@ mptsas_probe_expander_phys(MPT_ADAPTER *ioc, u32 *handle, int *index)
}
}
- mptsas_probe_one_phy(parent, &port_info->phy_info[i], *index);
+ mptsas_probe_one_phy(parent, &port_info->phy_info[i],
+ *index, 0);
(*index)++;
}
@@ -1021,6 +1192,8 @@ mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id)
sh->unique_id = ioc->id;
INIT_LIST_HEAD(&ioc->sas_topology);
+ init_MUTEX(&ioc->sas_mgmt.mutex);
+ init_completion(&ioc->sas_mgmt.done);
/* Verify that we won't exceed the maximum
* number of chain buffers
@@ -1207,6 +1380,7 @@ mptsas_init(void)
mptsasTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTSAS_DRIVER);
mptsasInternalCtx =
mpt_register(mptscsih_scandv_complete, MPTSAS_DRIVER);
+ mptsasMgmtCtx = mpt_register(mptsas_mgmt_done, MPTSAS_DRIVER);
if (mpt_event_register(mptsasDoneCtx, mptscsih_event_process) == 0) {
devtprintk((KERN_INFO MYNAM
@@ -1230,6 +1404,7 @@ mptsas_exit(void)
mpt_reset_deregister(mptsasDoneCtx);
mpt_event_deregister(mptsasDoneCtx);
+ mpt_deregister(mptsasMgmtCtx);
mpt_deregister(mptsasInternalCtx);
mpt_deregister(mptsasTaskCtx);
mpt_deregister(mptsasDoneCtx);
diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c
index 5cb07eb224d7..4330ed0cedaa 100644
--- a/drivers/message/fusion/mptscsih.c
+++ b/drivers/message/fusion/mptscsih.c
@@ -1013,10 +1013,8 @@ mptscsih_remove(struct pci_dev *pdev)
spin_lock_irqsave(&dvtaskQ_lock, flags);
if (dvtaskQ_active) {
spin_unlock_irqrestore(&dvtaskQ_lock, flags);
- while(dvtaskQ_active && --count) {
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(1);
- }
+ while(dvtaskQ_active && --count)
+ schedule_timeout_interruptible(1);
} else {
spin_unlock_irqrestore(&dvtaskQ_lock, flags);
}
diff --git a/drivers/message/i2o/core.h b/drivers/message/i2o/core.h
index c5bcfd70f711..9eefedb16211 100644
--- a/drivers/message/i2o/core.h
+++ b/drivers/message/i2o/core.h
@@ -36,9 +36,6 @@ extern void __exit i2o_pci_exit(void);
extern void i2o_device_remove(struct i2o_device *);
extern int i2o_device_parse_lct(struct i2o_controller *);
-extern int i2o_device_init(void);
-extern void i2o_device_exit(void);
-
/* IOP */
extern struct i2o_controller *i2o_iop_alloc(void);
extern void i2o_iop_free(struct i2o_controller *);
diff --git a/drivers/message/i2o/debug.c b/drivers/message/i2o/debug.c
index 018ca887ca85..40d4ea898dbc 100644
--- a/drivers/message/i2o/debug.c
+++ b/drivers/message/i2o/debug.c
@@ -90,7 +90,7 @@ static void i2o_report_fail_status(u8 req_status, u32 * msg)
};
if (req_status == I2O_FSC_TRANSPORT_UNKNOWN_FAILURE)
- printk(KERN_DEBUG "TRANSPORT_UNKNOWN_FAILURE (%0#2x)\n.",
+ printk(KERN_DEBUG "TRANSPORT_UNKNOWN_FAILURE (%0#2x).\n",
req_status);
else
printk(KERN_DEBUG "TRANSPORT_%s.\n",
diff --git a/drivers/message/i2o/device.c b/drivers/message/i2o/device.c
index 21f16ba3ac38..8eb50cdb8ae1 100644
--- a/drivers/message/i2o/device.c
+++ b/drivers/message/i2o/device.c
@@ -16,6 +16,8 @@
#include <linux/module.h>
#include <linux/i2o.h>
#include <linux/delay.h>
+#include <linux/string.h>
+#include <linux/slab.h>
#include "core.h"
/**
@@ -45,10 +47,10 @@ static inline int i2o_device_issue_claim(struct i2o_device *dev, u32 cmd,
writel(type, &msg->body[0]);
return i2o_msg_post_wait(dev->iop, m, 60);
-};
+}
/**
- * i2o_device_claim - claim a device for use by an OSM
+ * i2o_device_claim - claim a device for use by an OSM
* @dev: I2O device to claim
* @drv: I2O driver which wants to claim the device
*
@@ -73,7 +75,7 @@ int i2o_device_claim(struct i2o_device *dev)
up(&dev->lock);
return rc;
-};
+}
/**
* i2o_device_claim_release - release a device that the OSM is using
@@ -119,7 +121,8 @@ int i2o_device_claim_release(struct i2o_device *dev)
up(&dev->lock);
return rc;
-};
+}
+
/**
* i2o_device_release - release the memory for a I2O device
@@ -135,39 +138,47 @@ static void i2o_device_release(struct device *dev)
pr_debug("i2o: device %s released\n", dev->bus_id);
kfree(i2o_dev);
-};
+}
+
/**
- * i2o_device_class_release - Remove I2O device attributes
- * @cd: I2O class device which is added to the I2O device class
+ * i2o_device_class_show_class_id - Displays class id of I2O device
+ * @cd: class device of which the class id should be displayed
+ * @buf: buffer into which the class id should be printed
*
- * Removes attributes from the I2O device again. Also search each device
- * on the controller for I2O devices which refert to this device as parent
- * or user and remove this links also.
+ * Returns the number of bytes which are printed into the buffer.
*/
-static void i2o_device_class_release(struct class_device *cd)
+static ssize_t i2o_device_show_class_id(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
{
- struct i2o_device *i2o_dev, *tmp;
- struct i2o_controller *c;
+ struct i2o_device *i2o_dev = to_i2o_device(dev);
- i2o_dev = to_i2o_device(cd->dev);
- c = i2o_dev->iop;
+ sprintf(buf, "0x%03x\n", i2o_dev->lct_data.class_id);
+ return strlen(buf) + 1;
+}
- sysfs_remove_link(&i2o_dev->device.kobj, "parent");
- sysfs_remove_link(&i2o_dev->device.kobj, "user");
+/**
+ * i2o_device_class_show_tid - Displays TID of I2O device
+ * @cd: class device of which the TID should be displayed
+ * @buf: buffer into which the class id should be printed
+ *
+ * Returns the number of bytes which are printed into the buffer.
+ */
+static ssize_t i2o_device_show_tid(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct i2o_device *i2o_dev = to_i2o_device(dev);
- list_for_each_entry(tmp, &c->devices, list) {
- if (tmp->lct_data.parent_tid == i2o_dev->lct_data.tid)
- sysfs_remove_link(&tmp->device.kobj, "parent");
- if (tmp->lct_data.user_tid == i2o_dev->lct_data.tid)
- sysfs_remove_link(&tmp->device.kobj, "user");
- }
-};
+ sprintf(buf, "0x%03x\n", i2o_dev->lct_data.tid);
+ return strlen(buf) + 1;
+}
-/* I2O device class */
-static struct class i2o_device_class = {
- .name = "i2o_device",
- .release = i2o_device_class_release
+struct device_attribute i2o_device_attrs[] = {
+ __ATTR(class_id, S_IRUGO, i2o_device_show_class_id, NULL),
+ __ATTR(tid, S_IRUGO, i2o_device_show_tid, NULL),
+ __ATTR_NULL
};
/**
@@ -193,11 +204,69 @@ static struct i2o_device *i2o_device_alloc(void)
dev->device.bus = &i2o_bus_type;
dev->device.release = &i2o_device_release;
- dev->classdev.class = &i2o_device_class;
- dev->classdev.dev = &dev->device;
return dev;
-};
+}
+
+/**
+ * i2o_setup_sysfs_links - Adds attributes to the I2O device
+ * @cd: I2O class device which is added to the I2O device class
+ *
+ * This function get called when a I2O device is added to the class. It
+ * creates the attributes for each device and creates user/parent symlink
+ * if necessary.
+ *
+ * Returns 0 on success or negative error code on failure.
+ */
+static void i2o_setup_sysfs_links(struct i2o_device *i2o_dev)
+{
+ struct i2o_controller *c = i2o_dev->iop;
+ struct i2o_device *tmp;
+
+ /* create user entries for this device */
+ tmp = i2o_iop_find_device(i2o_dev->iop, i2o_dev->lct_data.user_tid);
+ if (tmp && tmp != i2o_dev)
+ sysfs_create_link(&i2o_dev->device.kobj,
+ &tmp->device.kobj, "user");
+
+ /* create user entries refering to this device */
+ list_for_each_entry(tmp, &c->devices, list)
+ if (tmp->lct_data.user_tid == i2o_dev->lct_data.tid &&
+ tmp != i2o_dev)
+ sysfs_create_link(&tmp->device.kobj,
+ &i2o_dev->device.kobj, "user");
+
+ /* create parent entries for this device */
+ tmp = i2o_iop_find_device(i2o_dev->iop, i2o_dev->lct_data.parent_tid);
+ if (tmp && tmp != i2o_dev)
+ sysfs_create_link(&i2o_dev->device.kobj,
+ &tmp->device.kobj, "parent");
+
+ /* create parent entries refering to this device */
+ list_for_each_entry(tmp, &c->devices, list)
+ if (tmp->lct_data.parent_tid == i2o_dev->lct_data.tid &&
+ tmp != i2o_dev)
+ sysfs_create_link(&tmp->device.kobj,
+ &i2o_dev->device.kobj, "parent");
+}
+
+static void i2o_remove_sysfs_links(struct i2o_device *i2o_dev)
+{
+ struct i2o_controller *c = i2o_dev->iop;
+ struct i2o_device *tmp;
+
+ sysfs_remove_link(&i2o_dev->device.kobj, "parent");
+ sysfs_remove_link(&i2o_dev->device.kobj, "user");
+
+ list_for_each_entry(tmp, &c->devices, list) {
+ if (tmp->lct_data.parent_tid == i2o_dev->lct_data.tid)
+ sysfs_remove_link(&tmp->device.kobj, "parent");
+ if (tmp->lct_data.user_tid == i2o_dev->lct_data.tid)
+ sysfs_remove_link(&tmp->device.kobj, "user");
+ }
+}
+
+
/**
* i2o_device_add - allocate a new I2O device and add it to the IOP
@@ -222,28 +291,25 @@ static struct i2o_device *i2o_device_add(struct i2o_controller *c,
}
dev->lct_data = *entry;
+ dev->iop = c;
snprintf(dev->device.bus_id, BUS_ID_SIZE, "%d:%03x", c->unit,
dev->lct_data.tid);
- snprintf(dev->classdev.class_id, BUS_ID_SIZE, "%d:%03x", c->unit,
- dev->lct_data.tid);
-
- dev->iop = c;
dev->device.parent = &c->device;
device_register(&dev->device);
list_add_tail(&dev->list, &c->devices);
- class_device_register(&dev->classdev);
+ i2o_setup_sysfs_links(dev);
i2o_driver_notify_device_add_all(dev);
pr_debug("i2o: device %s added\n", dev->device.bus_id);
return dev;
-};
+}
/**
* i2o_device_remove - remove an I2O device from the I2O core
@@ -256,10 +322,10 @@ static struct i2o_device *i2o_device_add(struct i2o_controller *c,
void i2o_device_remove(struct i2o_device *i2o_dev)
{
i2o_driver_notify_device_remove_all(i2o_dev);
- class_device_unregister(&i2o_dev->classdev);
+ i2o_remove_sysfs_links(i2o_dev);
list_del(&i2o_dev->list);
device_unregister(&i2o_dev->device);
-};
+}
/**
* i2o_device_parse_lct - Parse a previously fetched LCT and create devices
@@ -337,99 +403,8 @@ int i2o_device_parse_lct(struct i2o_controller *c)
up(&c->lct_lock);
return 0;
-};
-
-/**
- * i2o_device_class_show_class_id - Displays class id of I2O device
- * @cd: class device of which the class id should be displayed
- * @buf: buffer into which the class id should be printed
- *
- * Returns the number of bytes which are printed into the buffer.
- */
-static ssize_t i2o_device_class_show_class_id(struct class_device *cd,
- char *buf)
-{
- struct i2o_device *dev = to_i2o_device(cd->dev);
-
- sprintf(buf, "0x%03x\n", dev->lct_data.class_id);
- return strlen(buf) + 1;
-};
-
-/**
- * i2o_device_class_show_tid - Displays TID of I2O device
- * @cd: class device of which the TID should be displayed
- * @buf: buffer into which the class id should be printed
- *
- * Returns the number of bytes which are printed into the buffer.
- */
-static ssize_t i2o_device_class_show_tid(struct class_device *cd, char *buf)
-{
- struct i2o_device *dev = to_i2o_device(cd->dev);
-
- sprintf(buf, "0x%03x\n", dev->lct_data.tid);
- return strlen(buf) + 1;
-};
-
-/* I2O device class attributes */
-static CLASS_DEVICE_ATTR(class_id, S_IRUGO, i2o_device_class_show_class_id,
- NULL);
-static CLASS_DEVICE_ATTR(tid, S_IRUGO, i2o_device_class_show_tid, NULL);
-
-/**
- * i2o_device_class_add - Adds attributes to the I2O device
- * @cd: I2O class device which is added to the I2O device class
- *
- * This function get called when a I2O device is added to the class. It
- * creates the attributes for each device and creates user/parent symlink
- * if necessary.
- *
- * Returns 0 on success or negative error code on failure.
- */
-static int i2o_device_class_add(struct class_device *cd)
-{
- struct i2o_device *i2o_dev, *tmp;
- struct i2o_controller *c;
-
- i2o_dev = to_i2o_device(cd->dev);
- c = i2o_dev->iop;
-
- class_device_create_file(cd, &class_device_attr_class_id);
- class_device_create_file(cd, &class_device_attr_tid);
-
- /* create user entries for this device */
- tmp = i2o_iop_find_device(i2o_dev->iop, i2o_dev->lct_data.user_tid);
- if (tmp && (tmp != i2o_dev))
- sysfs_create_link(&i2o_dev->device.kobj, &tmp->device.kobj,
- "user");
-
- /* create user entries refering to this device */
- list_for_each_entry(tmp, &c->devices, list)
- if ((tmp->lct_data.user_tid == i2o_dev->lct_data.tid)
- && (tmp != i2o_dev))
- sysfs_create_link(&tmp->device.kobj,
- &i2o_dev->device.kobj, "user");
-
- /* create parent entries for this device */
- tmp = i2o_iop_find_device(i2o_dev->iop, i2o_dev->lct_data.parent_tid);
- if (tmp && (tmp != i2o_dev))
- sysfs_create_link(&i2o_dev->device.kobj, &tmp->device.kobj,
- "parent");
-
- /* create parent entries refering to this device */
- list_for_each_entry(tmp, &c->devices, list)
- if ((tmp->lct_data.parent_tid == i2o_dev->lct_data.tid)
- && (tmp != i2o_dev))
- sysfs_create_link(&tmp->device.kobj,
- &i2o_dev->device.kobj, "parent");
-
- return 0;
-};
+}
-/* I2O device class interface */
-static struct class_interface i2o_device_class_interface = {
- .class = &i2o_device_class,
- .add = i2o_device_class_add
-};
/*
* Run time support routines
@@ -553,11 +528,11 @@ int i2o_parm_field_get(struct i2o_device *i2o_dev, int group, int field,
}
/*
- * if oper == I2O_PARAMS_TABLE_GET, get from all rows
- * if fieldcount == -1 return all fields
+ * if oper == I2O_PARAMS_TABLE_GET, get from all rows
+ * if fieldcount == -1 return all fields
* ibuf and ibuflen are unused (use NULL, 0)
- * else return specific fields
- * ibuf contains fieldindexes
+ * else return specific fields
+ * ibuf contains fieldindexes
*
* if oper == I2O_PARAMS_LIST_GET, get from specific rows
* if fieldcount == -1 return all fields
@@ -602,35 +577,6 @@ int i2o_parm_table_get(struct i2o_device *dev, int oper, int group,
return size;
}
-/**
- * i2o_device_init - Initialize I2O devices
- *
- * Registers the I2O device class.
- *
- * Returns 0 on success or negative error code on failure.
- */
-int i2o_device_init(void)
-{
- int rc;
-
- rc = class_register(&i2o_device_class);
- if (rc)
- return rc;
-
- return class_interface_register(&i2o_device_class_interface);
-};
-
-/**
- * i2o_device_exit - I2O devices exit function
- *
- * Unregisters the I2O device class.
- */
-void i2o_device_exit(void)
-{
- class_interface_register(&i2o_device_class_interface);
- class_unregister(&i2o_device_class);
-};
-
EXPORT_SYMBOL(i2o_device_claim);
EXPORT_SYMBOL(i2o_device_claim_release);
EXPORT_SYMBOL(i2o_parm_field_get);
diff --git a/drivers/message/i2o/driver.c b/drivers/message/i2o/driver.c
index 739bfdef0c6d..0fb9c4e2ad4c 100644
--- a/drivers/message/i2o/driver.c
+++ b/drivers/message/i2o/driver.c
@@ -17,6 +17,9 @@
#include <linux/module.h>
#include <linux/rwsem.h>
#include <linux/i2o.h>
+#include <linux/workqueue.h>
+#include <linux/string.h>
+#include <linux/slab.h>
#include "core.h"
#define OSM_NAME "i2o"
@@ -58,9 +61,12 @@ static int i2o_bus_match(struct device *dev, struct device_driver *drv)
};
/* I2O bus type */
+extern struct device_attribute i2o_device_attrs[];
+
struct bus_type i2o_bus_type = {
.name = "i2o",
.match = i2o_bus_match,
+ .dev_attrs = i2o_device_attrs,
};
/**
diff --git a/drivers/message/i2o/exec-osm.c b/drivers/message/i2o/exec-osm.c
index bda2c62648ba..9c339a2505b0 100644
--- a/drivers/message/i2o/exec-osm.c
+++ b/drivers/message/i2o/exec-osm.c
@@ -30,6 +30,11 @@
#include <linux/module.h>
#include <linux/i2o.h>
#include <linux/delay.h>
+#include <linux/workqueue.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/sched.h> /* wait_event_interruptible_timeout() needs this */
+#include <asm/param.h> /* HZ */
#include "core.h"
#define OSM_NAME "exec-osm"
diff --git a/drivers/message/i2o/iop.c b/drivers/message/i2o/iop.c
index 42f8b810d6e5..4eb53258842e 100644
--- a/drivers/message/i2o/iop.c
+++ b/drivers/message/i2o/iop.c
@@ -28,6 +28,7 @@
#include <linux/module.h>
#include <linux/i2o.h>
#include <linux/delay.h>
+#include <linux/sched.h>
#include "core.h"
#define OSM_NAME "i2o"
@@ -92,8 +93,7 @@ u32 i2o_msg_get_wait(struct i2o_controller *c,
c->name);
return I2O_QUEUE_EMPTY;
}
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(1);
+ schedule_timeout_uninterruptible(1);
}
return m;
@@ -484,8 +484,7 @@ static int i2o_iop_init_outbound_queue(struct i2o_controller *c)
osm_warn("%s: Timeout Initializing\n", c->name);
return -ETIMEDOUT;
}
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(1);
+ schedule_timeout_uninterruptible(1);
}
m = c->out_queue.phys;
@@ -547,8 +546,7 @@ static int i2o_iop_reset(struct i2o_controller *c)
if (time_after(jiffies, timeout))
break;
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(1);
+ schedule_timeout_uninterruptible(1);
}
switch (*status) {
@@ -576,8 +574,7 @@ static int i2o_iop_reset(struct i2o_controller *c)
rc = -ETIMEDOUT;
goto exit;
}
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(1);
+ schedule_timeout_uninterruptible(1);
m = i2o_msg_get_wait(c, &msg, I2O_TIMEOUT_RESET);
}
@@ -833,6 +830,7 @@ void i2o_iop_remove(struct i2o_controller *c)
list_for_each_entry_safe(dev, tmp, &c->devices, list)
i2o_device_remove(dev);
+ class_device_unregister(c->classdev);
device_del(&c->device);
/* Ask the IOP to switch to RESET state */
@@ -987,8 +985,7 @@ int i2o_status_get(struct i2o_controller *c)
return -ETIMEDOUT;
}
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(1);
+ schedule_timeout_uninterruptible(1);
}
#ifdef DEBUG
@@ -1077,9 +1074,7 @@ static void i2o_iop_release(struct device *dev)
};
/* I2O controller class */
-static struct class i2o_controller_class = {
- .name = "i2o_controller",
-};
+static struct class *i2o_controller_class;
/**
* i2o_iop_alloc - Allocate and initialize a i2o_controller struct
@@ -1110,14 +1105,10 @@ struct i2o_controller *i2o_iop_alloc(void)
sprintf(c->name, "iop%d", c->unit);
device_initialize(&c->device);
- class_device_initialize(&c->classdev);
c->device.release = &i2o_iop_release;
- c->classdev.class = &i2o_controller_class;
- c->classdev.dev = &c->device;
snprintf(c->device.bus_id, BUS_ID_SIZE, "iop%d", c->unit);
- snprintf(c->classdev.class_id, BUS_ID_SIZE, "iop%d", c->unit);
#if BITS_PER_LONG == 64
spin_lock_init(&c->context_list_lock);
@@ -1146,7 +1137,9 @@ int i2o_iop_add(struct i2o_controller *c)
goto iop_reset;
}
- if ((rc = class_device_add(&c->classdev))) {
+ c->classdev = class_device_create(i2o_controller_class, NULL, MKDEV(0,0),
+ &c->device, "iop%d", c->unit);
+ if (IS_ERR(c->classdev)) {
osm_err("%s: could not add controller class\n", c->name);
goto device_del;
}
@@ -1184,7 +1177,7 @@ int i2o_iop_add(struct i2o_controller *c)
return 0;
class_del:
- class_device_del(&c->classdev);
+ class_device_unregister(c->classdev);
device_del:
device_del(&c->device);
@@ -1246,13 +1239,10 @@ static int __init i2o_iop_init(void)
printk(KERN_INFO OSM_DESCRIPTION " v" OSM_VERSION "\n");
- rc = i2o_device_init();
- if (rc)
- goto exit;
-
- if ((rc = class_register(&i2o_controller_class))) {
+ i2o_controller_class = class_create(THIS_MODULE, "i2o_controller");
+ if (IS_ERR(i2o_controller_class)) {
osm_err("can't register class i2o_controller\n");
- goto device_exit;
+ goto exit;
}
if ((rc = i2o_driver_init()))
@@ -1273,10 +1263,7 @@ static int __init i2o_iop_init(void)
i2o_driver_exit();
class_exit:
- class_unregister(&i2o_controller_class);
-
- device_exit:
- i2o_device_exit();
+ class_destroy(i2o_controller_class);
exit:
return rc;
@@ -1292,8 +1279,7 @@ static void __exit i2o_iop_exit(void)
i2o_pci_exit();
i2o_exec_exit();
i2o_driver_exit();
- class_unregister(&i2o_controller_class);
- i2o_device_exit();
+ class_destroy(i2o_controller_class);
};
module_init(i2o_iop_init);
diff --git a/drivers/mfd/mcp-core.c b/drivers/mfd/mcp-core.c
index c75d713c01e4..55ba23075c90 100644
--- a/drivers/mfd/mcp-core.c
+++ b/drivers/mfd/mcp-core.c
@@ -15,6 +15,8 @@
#include <linux/errno.h>
#include <linux/smp.h>
#include <linux/device.h>
+#include <linux/slab.h>
+#include <linux/string.h>
#include <asm/dma.h>
#include <asm/system.h>
diff --git a/drivers/mfd/mcp-sa11x0.c b/drivers/mfd/mcp-sa11x0.c
index e9806fbbe696..7daa0ed7331c 100644
--- a/drivers/mfd/mcp-sa11x0.c
+++ b/drivers/mfd/mcp-sa11x0.c
@@ -18,7 +18,7 @@
#include <linux/delay.h>
#include <linux/spinlock.h>
#include <linux/slab.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <asm/dma.h>
#include <asm/hardware.h>
@@ -219,26 +219,24 @@ static int mcp_sa11x0_remove(struct device *dev)
return 0;
}
-static int mcp_sa11x0_suspend(struct device *dev, pm_message_t state, u32 level)
+static int mcp_sa11x0_suspend(struct device *dev, pm_message_t state)
{
struct mcp *mcp = dev_get_drvdata(dev);
- if (level == SUSPEND_DISABLE) {
- priv(mcp)->mccr0 = Ser4MCCR0;
- priv(mcp)->mccr1 = Ser4MCCR1;
- Ser4MCCR0 &= ~MCCR0_MCE;
- }
+ priv(mcp)->mccr0 = Ser4MCCR0;
+ priv(mcp)->mccr1 = Ser4MCCR1;
+ Ser4MCCR0 &= ~MCCR0_MCE;
+
return 0;
}
-static int mcp_sa11x0_resume(struct device *dev, u32 level)
+static int mcp_sa11x0_resume(struct device *dev)
{
struct mcp *mcp = dev_get_drvdata(dev);
- if (level == RESUME_RESTORE_STATE) {
- Ser4MCCR1 = priv(mcp)->mccr1;
- Ser4MCCR0 = priv(mcp)->mccr0;
- }
+ Ser4MCCR1 = priv(mcp)->mccr1;
+ Ser4MCCR0 = priv(mcp)->mccr0;
+
return 0;
}
diff --git a/drivers/mfd/ucb1x00-ts.c b/drivers/mfd/ucb1x00-ts.c
index a260f83bcb02..a984c0efabf0 100644
--- a/drivers/mfd/ucb1x00-ts.c
+++ b/drivers/mfd/ucb1x00-ts.c
@@ -32,15 +32,18 @@
#include <linux/suspend.h>
#include <linux/slab.h>
#include <linux/kthread.h>
+#include <linux/delay.h>
#include <asm/dma.h>
#include <asm/semaphore.h>
+#include <asm/arch/collie.h>
+#include <asm/mach-types.h>
#include "ucb1x00.h"
struct ucb1x00_ts {
- struct input_dev idev;
+ struct input_dev *idev;
struct ucb1x00 *ucb;
wait_queue_head_t irq_wait;
@@ -56,16 +59,16 @@ static int adcsync;
static inline void ucb1x00_ts_evt_add(struct ucb1x00_ts *ts, u16 pressure, u16 x, u16 y)
{
- input_report_abs(&ts->idev, ABS_X, x);
- input_report_abs(&ts->idev, ABS_Y, y);
- input_report_abs(&ts->idev, ABS_PRESSURE, pressure);
- input_sync(&ts->idev);
+ input_report_abs(ts->idev, ABS_X, x);
+ input_report_abs(ts->idev, ABS_Y, y);
+ input_report_abs(ts->idev, ABS_PRESSURE, pressure);
+ input_sync(ts->idev);
}
static inline void ucb1x00_ts_event_release(struct ucb1x00_ts *ts)
{
- input_report_abs(&ts->idev, ABS_PRESSURE, 0);
- input_sync(&ts->idev);
+ input_report_abs(ts->idev, ABS_PRESSURE, 0);
+ input_sync(ts->idev);
}
/*
@@ -85,12 +88,23 @@ static inline void ucb1x00_ts_mode_int(struct ucb1x00_ts *ts)
*/
static inline unsigned int ucb1x00_ts_read_pressure(struct ucb1x00_ts *ts)
{
- ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
- UCB_TS_CR_TSMX_POW | UCB_TS_CR_TSPX_POW |
- UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_GND |
- UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
+ if (machine_is_collie()) {
+ ucb1x00_io_write(ts->ucb, COLLIE_TC35143_GPIO_TBL_CHK, 0);
+ ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
+ UCB_TS_CR_TSPX_POW | UCB_TS_CR_TSMX_POW |
+ UCB_TS_CR_MODE_POS | UCB_TS_CR_BIAS_ENA);
- return ucb1x00_adc_read(ts->ucb, UCB_ADC_INP_TSPY, ts->adcsync);
+ udelay(55);
+
+ return ucb1x00_adc_read(ts->ucb, UCB_ADC_INP_AD2, ts->adcsync);
+ } else {
+ ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
+ UCB_TS_CR_TSMX_POW | UCB_TS_CR_TSPX_POW |
+ UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_GND |
+ UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
+
+ return ucb1x00_adc_read(ts->ucb, UCB_ADC_INP_TSPY, ts->adcsync);
+ }
}
/*
@@ -101,12 +115,16 @@ static inline unsigned int ucb1x00_ts_read_pressure(struct ucb1x00_ts *ts)
*/
static inline unsigned int ucb1x00_ts_read_xpos(struct ucb1x00_ts *ts)
{
- ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
- UCB_TS_CR_TSMX_GND | UCB_TS_CR_TSPX_POW |
- UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
- ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
- UCB_TS_CR_TSMX_GND | UCB_TS_CR_TSPX_POW |
- UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
+ if (machine_is_collie())
+ ucb1x00_io_write(ts->ucb, 0, COLLIE_TC35143_GPIO_TBL_CHK);
+ else {
+ ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
+ UCB_TS_CR_TSMX_GND | UCB_TS_CR_TSPX_POW |
+ UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
+ ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
+ UCB_TS_CR_TSMX_GND | UCB_TS_CR_TSPX_POW |
+ UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
+ }
ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
UCB_TS_CR_TSMX_GND | UCB_TS_CR_TSPX_POW |
UCB_TS_CR_MODE_POS | UCB_TS_CR_BIAS_ENA);
@@ -124,12 +142,17 @@ static inline unsigned int ucb1x00_ts_read_xpos(struct ucb1x00_ts *ts)
*/
static inline unsigned int ucb1x00_ts_read_ypos(struct ucb1x00_ts *ts)
{
- ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
- UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_POW |
- UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
- ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
- UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_POW |
- UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
+ if (machine_is_collie())
+ ucb1x00_io_write(ts->ucb, 0, COLLIE_TC35143_GPIO_TBL_CHK);
+ else {
+ ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
+ UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_POW |
+ UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
+ ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
+ UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_POW |
+ UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
+ }
+
ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_POW |
UCB_TS_CR_MODE_POS | UCB_TS_CR_BIAS_ENA);
@@ -163,6 +186,15 @@ static inline unsigned int ucb1x00_ts_read_yres(struct ucb1x00_ts *ts)
return ucb1x00_adc_read(ts->ucb, 0, ts->adcsync);
}
+static inline int ucb1x00_ts_pen_down(struct ucb1x00_ts *ts)
+{
+ unsigned int val = ucb1x00_reg_read(ts->ucb, UCB_TS_CR);
+ if (machine_is_collie())
+ return (!(val & (UCB_TS_CR_TSPX_LOW)));
+ else
+ return (val & (UCB_TS_CR_TSPX_LOW | UCB_TS_CR_TSMX_LOW));
+}
+
/*
* This is a RT kernel thread that handles the ADC accesses
* (mainly so we can use semaphores in the UCB1200 core code
@@ -186,7 +218,7 @@ static int ucb1x00_thread(void *_ts)
add_wait_queue(&ts->irq_wait, &wait);
while (!kthread_should_stop()) {
- unsigned int x, y, p, val;
+ unsigned int x, y, p;
signed long timeout;
ts->restart = 0;
@@ -206,12 +238,12 @@ static int ucb1x00_thread(void *_ts)
msleep(10);
ucb1x00_enable(ts->ucb);
- val = ucb1x00_reg_read(ts->ucb, UCB_TS_CR);
- if (val & (UCB_TS_CR_TSPX_LOW | UCB_TS_CR_TSMX_LOW)) {
+
+ if (ucb1x00_ts_pen_down(ts)) {
set_task_state(tsk, TASK_INTERRUPTIBLE);
- ucb1x00_enable_irq(ts->ucb, UCB_IRQ_TSPX, UCB_FALLING);
+ ucb1x00_enable_irq(ts->ucb, UCB_IRQ_TSPX, machine_is_collie() ? UCB_RISING : UCB_FALLING);
ucb1x00_disable(ts->ucb);
/*
@@ -341,26 +373,30 @@ static int ucb1x00_ts_add(struct ucb1x00_dev *dev)
{
struct ucb1x00_ts *ts;
- ts = kmalloc(sizeof(struct ucb1x00_ts), GFP_KERNEL);
+ ts = kzalloc(sizeof(struct ucb1x00_ts), GFP_KERNEL);
if (!ts)
return -ENOMEM;
- memset(ts, 0, sizeof(struct ucb1x00_ts));
+ ts->idev = input_allocate_device();
+ if (!ts->idev) {
+ kfree(ts);
+ return -ENOMEM;
+ }
ts->ucb = dev->ucb;
ts->adcsync = adcsync ? UCB_SYNC : UCB_NOSYNC;
- ts->idev.name = "Touchscreen panel";
- ts->idev.id.product = ts->ucb->id;
- ts->idev.open = ucb1x00_ts_open;
- ts->idev.close = ucb1x00_ts_close;
+ ts->idev->name = "Touchscreen panel";
+ ts->idev->id.product = ts->ucb->id;
+ ts->idev->open = ucb1x00_ts_open;
+ ts->idev->close = ucb1x00_ts_close;
- __set_bit(EV_ABS, ts->idev.evbit);
- __set_bit(ABS_X, ts->idev.absbit);
- __set_bit(ABS_Y, ts->idev.absbit);
- __set_bit(ABS_PRESSURE, ts->idev.absbit);
+ __set_bit(EV_ABS, ts->idev->evbit);
+ __set_bit(ABS_X, ts->idev->absbit);
+ __set_bit(ABS_Y, ts->idev->absbit);
+ __set_bit(ABS_PRESSURE, ts->idev->absbit);
- input_register_device(&ts->idev);
+ input_register_device(ts->idev);
dev->priv = ts;
@@ -370,7 +406,8 @@ static int ucb1x00_ts_add(struct ucb1x00_dev *dev)
static void ucb1x00_ts_remove(struct ucb1x00_dev *dev)
{
struct ucb1x00_ts *ts = dev->priv;
- input_unregister_device(&ts->idev);
+
+ input_unregister_device(ts->idev);
kfree(ts);
}
diff --git a/drivers/misc/hdpuftrs/hdpu_cpustate.c b/drivers/misc/hdpuftrs/hdpu_cpustate.c
index 46de5c940555..bc2b72b32905 100644
--- a/drivers/misc/hdpuftrs/hdpu_cpustate.c
+++ b/drivers/misc/hdpuftrs/hdpu_cpustate.c
@@ -14,14 +14,13 @@
*
*/
-#include <linux/version.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/spinlock.h>
#include <linux/miscdevice.h>
#include <linux/pci.h>
#include <linux/proc_fs.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <asm/uaccess.h>
#include <linux/hdpu_features.h>
diff --git a/drivers/misc/hdpuftrs/hdpu_nexus.c b/drivers/misc/hdpuftrs/hdpu_nexus.c
index c203b27269ea..4bb461793851 100644
--- a/drivers/misc/hdpuftrs/hdpu_nexus.c
+++ b/drivers/misc/hdpuftrs/hdpu_nexus.c
@@ -14,14 +14,13 @@
*
*/
-#include <linux/version.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/proc_fs.h>
#include <linux/hdpu_features.h>
#include <linux/pci.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
static int hdpu_nexus_probe(struct device *ddev);
static int hdpu_nexus_remove(struct device *ddev);
diff --git a/drivers/misc/ibmasm/ibmasm.h b/drivers/misc/ibmasm/ibmasm.h
index ecce4ffd3e23..d7e20a34f88d 100644
--- a/drivers/misc/ibmasm/ibmasm.h
+++ b/drivers/misc/ibmasm/ibmasm.h
@@ -31,7 +31,6 @@
#include <linux/slab.h>
#include <linux/config.h>
#include <linux/module.h>
-#include <linux/version.h>
#include <linux/interrupt.h>
#include <linux/device.h>
#include <linux/input.h>
diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig
index 4991bbd054f3..c483a863b116 100644
--- a/drivers/mmc/Kconfig
+++ b/drivers/mmc/Kconfig
@@ -60,4 +60,13 @@ config MMC_WBSD
If unsure, say N.
+config MMC_AU1X
+ tristate "Alchemy AU1XX0 MMC Card Interface support"
+ depends on SOC_AU1X00 && MMC
+ help
+ This selects the AMD Alchemy(R) Multimedia card interface.
+ iIf you have a Alchemy platform with a MMC slot, say Y or M here.
+
+ If unsure, say N.
+
endmenu
diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile
index 89510c2086c7..e351e71146e9 100644
--- a/drivers/mmc/Makefile
+++ b/drivers/mmc/Makefile
@@ -18,5 +18,6 @@ obj-$(CONFIG_MMC_BLOCK) += mmc_block.o
obj-$(CONFIG_MMC_ARMMMCI) += mmci.o
obj-$(CONFIG_MMC_PXA) += pxamci.o
obj-$(CONFIG_MMC_WBSD) += wbsd.o
+obj-$(CONFIG_MMC_AU1X) += au1xmmc.o
mmc_core-y := mmc.o mmc_queue.o mmc_sysfs.o
diff --git a/drivers/mmc/au1xmmc.c b/drivers/mmc/au1xmmc.c
new file mode 100644
index 000000000000..aaf04638054e
--- /dev/null
+++ b/drivers/mmc/au1xmmc.c
@@ -0,0 +1,1026 @@
+/*
+ * linux/drivers/mmc/au1xmmc.c - AU1XX0 MMC driver
+ *
+ * Copyright (c) 2005, Advanced Micro Devices, Inc.
+ *
+ * Developed with help from the 2.4.30 MMC AU1XXX controller including
+ * the following copyright notices:
+ * Copyright (c) 2003-2004 Embedded Edge, LLC.
+ * Portions Copyright (C) 2002 Embedix, Inc
+ * Copyright 2002 Hewlett-Packard Company
+
+ * 2.6 version of this driver inspired by:
+ * (drivers/mmc/wbsd.c) Copyright (C) 2004-2005 Pierre Ossman,
+ * All Rights Reserved.
+ * (drivers/mmc/pxa.c) Copyright (C) 2003 Russell King,
+ * 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.
+ */
+
+/* Why is a timer used to detect insert events?
+ *
+ * From the AU1100 MMC application guide:
+ * If the Au1100-based design is intended to support both MultiMediaCards
+ * and 1- or 4-data bit SecureDigital cards, then the solution is to
+ * connect a weak (560KOhm) pull-up resistor to connector pin 1.
+ * In doing so, a MMC card never enters SPI-mode communications,
+ * but now the SecureDigital card-detect feature of CD/DAT3 is ineffective
+ * (the low to high transition will not occur).
+ *
+ * So we use the timer to check the status manually.
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/mm.h>
+#include <linux/interrupt.h>
+#include <linux/dma-mapping.h>
+
+#include <linux/mmc/host.h>
+#include <linux/mmc/protocol.h>
+#include <asm/io.h>
+#include <asm/mach-au1x00/au1000.h>
+#include <asm/mach-au1x00/au1xxx_dbdma.h>
+#include <asm/mach-au1x00/au1100_mmc.h>
+#include <asm/scatterlist.h>
+
+#include <au1xxx.h>
+#include "au1xmmc.h"
+
+#define DRIVER_NAME "au1xxx-mmc"
+
+/* Set this to enable special debugging macros */
+/* #define MMC_DEBUG */
+
+#ifdef MMC_DEBUG
+#define DEBUG(fmt, idx, args...) printk("au1xx(%d): DEBUG: " fmt, idx, ##args)
+#else
+#define DEBUG(fmt, idx, args...)
+#endif
+
+const struct {
+ u32 iobase;
+ u32 tx_devid, rx_devid;
+ u16 bcsrpwr;
+ u16 bcsrstatus;
+ u16 wpstatus;
+} au1xmmc_card_table[] = {
+ { SD0_BASE, DSCR_CMD0_SDMS_TX0, DSCR_CMD0_SDMS_RX0,
+ BCSR_BOARD_SD0PWR, BCSR_INT_SD0INSERT, BCSR_STATUS_SD0WP },
+#ifndef CONFIG_MIPS_DB1200
+ { SD1_BASE, DSCR_CMD0_SDMS_TX1, DSCR_CMD0_SDMS_RX1,
+ BCSR_BOARD_DS1PWR, BCSR_INT_SD1INSERT, BCSR_STATUS_SD1WP }
+#endif
+};
+
+#define AU1XMMC_CONTROLLER_COUNT \
+ (sizeof(au1xmmc_card_table) / sizeof(au1xmmc_card_table[0]))
+
+/* This array stores pointers for the hosts (used by the IRQ handler) */
+struct au1xmmc_host *au1xmmc_hosts[AU1XMMC_CONTROLLER_COUNT];
+static int dma = 1;
+
+#ifdef MODULE
+MODULE_PARM(dma, "i");
+MODULE_PARM_DESC(dma, "Use DMA engine for data transfers (0 = disabled)");
+#endif
+
+static inline void IRQ_ON(struct au1xmmc_host *host, u32 mask)
+{
+ u32 val = au_readl(HOST_CONFIG(host));
+ val |= mask;
+ au_writel(val, HOST_CONFIG(host));
+ au_sync();
+}
+
+static inline void FLUSH_FIFO(struct au1xmmc_host *host)
+{
+ u32 val = au_readl(HOST_CONFIG2(host));
+
+ au_writel(val | SD_CONFIG2_FF, HOST_CONFIG2(host));
+ au_sync_delay(1);
+
+ /* SEND_STOP will turn off clock control - this re-enables it */
+ val &= ~SD_CONFIG2_DF;
+
+ au_writel(val, HOST_CONFIG2(host));
+ au_sync();
+}
+
+static inline void IRQ_OFF(struct au1xmmc_host *host, u32 mask)
+{
+ u32 val = au_readl(HOST_CONFIG(host));
+ val &= ~mask;
+ au_writel(val, HOST_CONFIG(host));
+ au_sync();
+}
+
+static inline void SEND_STOP(struct au1xmmc_host *host)
+{
+
+ /* We know the value of CONFIG2, so avoid a read we don't need */
+ u32 mask = SD_CONFIG2_EN;
+
+ WARN_ON(host->status != HOST_S_DATA);
+ host->status = HOST_S_STOP;
+
+ au_writel(mask | SD_CONFIG2_DF, HOST_CONFIG2(host));
+ au_sync();
+
+ /* Send the stop commmand */
+ au_writel(STOP_CMD, HOST_CMD(host));
+}
+
+static void au1xmmc_set_power(struct au1xmmc_host *host, int state)
+{
+
+ u32 val = au1xmmc_card_table[host->id].bcsrpwr;
+
+ bcsr->board &= ~val;
+ if (state) bcsr->board |= val;
+
+ au_sync_delay(1);
+}
+
+static inline int au1xmmc_card_inserted(struct au1xmmc_host *host)
+{
+ return (bcsr->sig_status & au1xmmc_card_table[host->id].bcsrstatus)
+ ? 1 : 0;
+}
+
+static inline int au1xmmc_card_readonly(struct au1xmmc_host *host)
+{
+ return (bcsr->status & au1xmmc_card_table[host->id].wpstatus)
+ ? 1 : 0;
+}
+
+static void au1xmmc_finish_request(struct au1xmmc_host *host)
+{
+
+ struct mmc_request *mrq = host->mrq;
+
+ host->mrq = NULL;
+ host->flags &= HOST_F_ACTIVE;
+
+ host->dma.len = 0;
+ host->dma.dir = 0;
+
+ host->pio.index = 0;
+ host->pio.offset = 0;
+ host->pio.len = 0;
+
+ host->status = HOST_S_IDLE;
+
+ bcsr->disk_leds |= (1 << 8);
+
+ mmc_request_done(host->mmc, mrq);
+}
+
+static void au1xmmc_tasklet_finish(unsigned long param)
+{
+ struct au1xmmc_host *host = (struct au1xmmc_host *) param;
+ au1xmmc_finish_request(host);
+}
+
+static int au1xmmc_send_command(struct au1xmmc_host *host, int wait,
+ struct mmc_command *cmd)
+{
+
+ u32 mmccmd = (cmd->opcode << SD_CMD_CI_SHIFT);
+
+ switch(cmd->flags) {
+ case MMC_RSP_R1:
+ mmccmd |= SD_CMD_RT_1;
+ break;
+ case MMC_RSP_R1B:
+ mmccmd |= SD_CMD_RT_1B;
+ break;
+ case MMC_RSP_R2:
+ mmccmd |= SD_CMD_RT_2;
+ break;
+ case MMC_RSP_R3:
+ mmccmd |= SD_CMD_RT_3;
+ break;
+ }
+
+ switch(cmd->opcode) {
+ case MMC_READ_SINGLE_BLOCK:
+ case SD_APP_SEND_SCR:
+ mmccmd |= SD_CMD_CT_2;
+ break;
+ case MMC_READ_MULTIPLE_BLOCK:
+ mmccmd |= SD_CMD_CT_4;
+ break;
+ case MMC_WRITE_BLOCK:
+ mmccmd |= SD_CMD_CT_1;
+ break;
+
+ case MMC_WRITE_MULTIPLE_BLOCK:
+ mmccmd |= SD_CMD_CT_3;
+ break;
+ case MMC_STOP_TRANSMISSION:
+ mmccmd |= SD_CMD_CT_7;
+ break;
+ }
+
+ au_writel(cmd->arg, HOST_CMDARG(host));
+ au_sync();
+
+ if (wait)
+ IRQ_OFF(host, SD_CONFIG_CR);
+
+ au_writel((mmccmd | SD_CMD_GO), HOST_CMD(host));
+ au_sync();
+
+ /* Wait for the command to go on the line */
+
+ while(1) {
+ if (!(au_readl(HOST_CMD(host)) & SD_CMD_GO))
+ break;
+ }
+
+ /* Wait for the command to come back */
+
+ if (wait) {
+ u32 status = au_readl(HOST_STATUS(host));
+
+ while(!(status & SD_STATUS_CR))
+ status = au_readl(HOST_STATUS(host));
+
+ /* Clear the CR status */
+ au_writel(SD_STATUS_CR, HOST_STATUS(host));
+
+ IRQ_ON(host, SD_CONFIG_CR);
+ }
+
+ return MMC_ERR_NONE;
+}
+
+static void au1xmmc_data_complete(struct au1xmmc_host *host, u32 status)
+{
+
+ struct mmc_request *mrq = host->mrq;
+ struct mmc_data *data;
+ u32 crc;
+
+ WARN_ON(host->status != HOST_S_DATA && host->status != HOST_S_STOP);
+
+ if (host->mrq == NULL)
+ return;
+
+ data = mrq->cmd->data;
+
+ if (status == 0)
+ status = au_readl(HOST_STATUS(host));
+
+ /* The transaction is really over when the SD_STATUS_DB bit is clear */
+
+ while((host->flags & HOST_F_XMIT) && (status & SD_STATUS_DB))
+ status = au_readl(HOST_STATUS(host));
+
+ data->error = MMC_ERR_NONE;
+ dma_unmap_sg(mmc_dev(host->mmc), data->sg, data->sg_len, host->dma.dir);
+
+ /* Process any errors */
+
+ crc = (status & (SD_STATUS_WC | SD_STATUS_RC));
+ if (host->flags & HOST_F_XMIT)
+ crc |= ((status & 0x07) == 0x02) ? 0 : 1;
+
+ if (crc)
+ data->error = MMC_ERR_BADCRC;
+
+ /* Clear the CRC bits */
+ au_writel(SD_STATUS_WC | SD_STATUS_RC, HOST_STATUS(host));
+
+ data->bytes_xfered = 0;
+
+ if (data->error == MMC_ERR_NONE) {
+ if (host->flags & HOST_F_DMA) {
+ u32 chan = DMA_CHANNEL(host);
+
+ chan_tab_t *c = *((chan_tab_t **) chan);
+ au1x_dma_chan_t *cp = c->chan_ptr;
+ data->bytes_xfered = cp->ddma_bytecnt;
+ }
+ else
+ data->bytes_xfered =
+ (data->blocks * (1 << data->blksz_bits)) -
+ host->pio.len;
+ }
+
+ au1xmmc_finish_request(host);
+}
+
+static void au1xmmc_tasklet_data(unsigned long param)
+{
+ struct au1xmmc_host *host = (struct au1xmmc_host *) param;
+
+ u32 status = au_readl(HOST_STATUS(host));
+ au1xmmc_data_complete(host, status);
+}
+
+#define AU1XMMC_MAX_TRANSFER 8
+
+static void au1xmmc_send_pio(struct au1xmmc_host *host)
+{
+
+ struct mmc_data *data = 0;
+ int sg_len, max, count = 0;
+ unsigned char *sg_ptr;
+ u32 status = 0;
+ struct scatterlist *sg;
+
+ data = host->mrq->data;
+
+ if (!(host->flags & HOST_F_XMIT))
+ return;
+
+ /* This is the pointer to the data buffer */
+ sg = &data->sg[host->pio.index];
+ sg_ptr = page_address(sg->page) + sg->offset + host->pio.offset;
+
+ /* This is the space left inside the buffer */
+ sg_len = data->sg[host->pio.index].length - host->pio.offset;
+
+ /* Check to if we need less then the size of the sg_buffer */
+
+ max = (sg_len > host->pio.len) ? host->pio.len : sg_len;
+ if (max > AU1XMMC_MAX_TRANSFER) max = AU1XMMC_MAX_TRANSFER;
+
+ for(count = 0; count < max; count++ ) {
+ unsigned char val;
+
+ status = au_readl(HOST_STATUS(host));
+
+ if (!(status & SD_STATUS_TH))
+ break;
+
+ val = *sg_ptr++;
+
+ au_writel((unsigned long) val, HOST_TXPORT(host));
+ au_sync();
+ }
+
+ host->pio.len -= count;
+ host->pio.offset += count;
+
+ if (count == sg_len) {
+ host->pio.index++;
+ host->pio.offset = 0;
+ }
+
+ if (host->pio.len == 0) {
+ IRQ_OFF(host, SD_CONFIG_TH);
+
+ if (host->flags & HOST_F_STOP)
+ SEND_STOP(host);
+
+ tasklet_schedule(&host->data_task);
+ }
+}
+
+static void au1xmmc_receive_pio(struct au1xmmc_host *host)
+{
+
+ struct mmc_data *data = 0;
+ int sg_len = 0, max = 0, count = 0;
+ unsigned char *sg_ptr = 0;
+ u32 status = 0;
+ struct scatterlist *sg;
+
+ data = host->mrq->data;
+
+ if (!(host->flags & HOST_F_RECV))
+ return;
+
+ max = host->pio.len;
+
+ if (host->pio.index < host->dma.len) {
+ sg = &data->sg[host->pio.index];
+ sg_ptr = page_address(sg->page) + sg->offset + host->pio.offset;
+
+ /* This is the space left inside the buffer */
+ sg_len = sg_dma_len(&data->sg[host->pio.index]) - host->pio.offset;
+
+ /* Check to if we need less then the size of the sg_buffer */
+ if (sg_len < max) max = sg_len;
+ }
+
+ if (max > AU1XMMC_MAX_TRANSFER)
+ max = AU1XMMC_MAX_TRANSFER;
+
+ for(count = 0; count < max; count++ ) {
+ u32 val;
+ status = au_readl(HOST_STATUS(host));
+
+ if (!(status & SD_STATUS_NE))
+ break;
+
+ if (status & SD_STATUS_RC) {
+ DEBUG("RX CRC Error [%d + %d].\n", host->id,
+ host->pio.len, count);
+ break;
+ }
+
+ if (status & SD_STATUS_RO) {
+ DEBUG("RX Overrun [%d + %d]\n", host->id,
+ host->pio.len, count);
+ break;
+ }
+ else if (status & SD_STATUS_RU) {
+ DEBUG("RX Underrun [%d + %d]\n", host->id,
+ host->pio.len, count);
+ break;
+ }
+
+ val = au_readl(HOST_RXPORT(host));
+
+ if (sg_ptr)
+ *sg_ptr++ = (unsigned char) (val & 0xFF);
+ }
+
+ host->pio.len -= count;
+ host->pio.offset += count;
+
+ if (sg_len && count == sg_len) {
+ host->pio.index++;
+ host->pio.offset = 0;
+ }
+
+ if (host->pio.len == 0) {
+ //IRQ_OFF(host, SD_CONFIG_RA | SD_CONFIG_RF);
+ IRQ_OFF(host, SD_CONFIG_NE);
+
+ if (host->flags & HOST_F_STOP)
+ SEND_STOP(host);
+
+ tasklet_schedule(&host->data_task);
+ }
+}
+
+/* static void au1xmmc_cmd_complete
+ This is called when a command has been completed - grab the response
+ and check for errors. Then start the data transfer if it is indicated.
+*/
+
+static void au1xmmc_cmd_complete(struct au1xmmc_host *host, u32 status)
+{
+
+ struct mmc_request *mrq = host->mrq;
+ struct mmc_command *cmd;
+ int trans;
+
+ if (!host->mrq)
+ return;
+
+ cmd = mrq->cmd;
+ cmd->error = MMC_ERR_NONE;
+
+ if ((cmd->flags & MMC_RSP_MASK) == MMC_RSP_SHORT) {
+
+ /* Techincally, we should be getting all 48 bits of the response
+ * (SD_RESP1 + SD_RESP2), but because our response omits the CRC,
+ * our data ends up being shifted 8 bits to the right. In this case,
+ * that means that the OSR data starts at bit 31, so we can just
+ * read RESP0 and return that
+ */
+
+ cmd->resp[0] = au_readl(host->iobase + SD_RESP0);
+ }
+ else if ((cmd->flags & MMC_RSP_MASK) == MMC_RSP_LONG) {
+ u32 r[4];
+ int i;
+
+ r[0] = au_readl(host->iobase + SD_RESP3);
+ r[1] = au_readl(host->iobase + SD_RESP2);
+ r[2] = au_readl(host->iobase + SD_RESP1);
+ r[3] = au_readl(host->iobase + SD_RESP0);
+
+ /* The CRC is omitted from the response, so really we only got
+ * 120 bytes, but the engine expects 128 bits, so we have to shift
+ * things up
+ */
+
+ for(i = 0; i < 4; i++) {
+ cmd->resp[i] = (r[i] & 0x00FFFFFF) << 8;
+ if (i != 3) cmd->resp[i] |= (r[i + 1] & 0xFF000000) >> 24;
+ }
+ }
+
+ /* Figure out errors */
+
+ if (status & (SD_STATUS_SC | SD_STATUS_WC | SD_STATUS_RC))
+ cmd->error = MMC_ERR_BADCRC;
+
+ trans = host->flags & (HOST_F_XMIT | HOST_F_RECV);
+
+ if (!trans || cmd->error != MMC_ERR_NONE) {
+
+ IRQ_OFF(host, SD_CONFIG_TH | SD_CONFIG_RA|SD_CONFIG_RF);
+ tasklet_schedule(&host->finish_task);
+ return;
+ }
+
+ host->status = HOST_S_DATA;
+
+ if (host->flags & HOST_F_DMA) {
+ u32 channel = DMA_CHANNEL(host);
+
+ /* Start the DMA as soon as the buffer gets something in it */
+
+ if (host->flags & HOST_F_RECV) {
+ u32 mask = SD_STATUS_DB | SD_STATUS_NE;
+
+ while((status & mask) != mask)
+ status = au_readl(HOST_STATUS(host));
+ }
+
+ au1xxx_dbdma_start(channel);
+ }
+}
+
+static void au1xmmc_set_clock(struct au1xmmc_host *host, int rate)
+{
+
+ unsigned int pbus = get_au1x00_speed();
+ unsigned int divisor;
+ u32 config;
+
+ /* From databook:
+ divisor = ((((cpuclock / sbus_divisor) / 2) / mmcclock) / 2) - 1
+ */
+
+ pbus /= ((au_readl(SYS_POWERCTRL) & 0x3) + 2);
+ pbus /= 2;
+
+ divisor = ((pbus / rate) / 2) - 1;
+
+ config = au_readl(HOST_CONFIG(host));
+
+ config &= ~(SD_CONFIG_DIV);
+ config |= (divisor & SD_CONFIG_DIV) | SD_CONFIG_DE;
+
+ au_writel(config, HOST_CONFIG(host));
+ au_sync();
+}
+
+static int
+au1xmmc_prepare_data(struct au1xmmc_host *host, struct mmc_data *data)
+{
+
+ int datalen = data->blocks * (1 << data->blksz_bits);
+
+ if (dma != 0)
+ host->flags |= HOST_F_DMA;
+
+ if (data->flags & MMC_DATA_READ)
+ host->flags |= HOST_F_RECV;
+ else
+ host->flags |= HOST_F_XMIT;
+
+ if (host->mrq->stop)
+ host->flags |= HOST_F_STOP;
+
+ host->dma.dir = DMA_BIDIRECTIONAL;
+
+ host->dma.len = dma_map_sg(mmc_dev(host->mmc), data->sg,
+ data->sg_len, host->dma.dir);
+
+ if (host->dma.len == 0)
+ return MMC_ERR_TIMEOUT;
+
+ au_writel((1 << data->blksz_bits) - 1, HOST_BLKSIZE(host));
+
+ if (host->flags & HOST_F_DMA) {
+ int i;
+ u32 channel = DMA_CHANNEL(host);
+
+ au1xxx_dbdma_stop(channel);
+
+ for(i = 0; i < host->dma.len; i++) {
+ u32 ret = 0, flags = DDMA_FLAGS_NOIE;
+ struct scatterlist *sg = &data->sg[i];
+ int sg_len = sg->length;
+
+ int len = (datalen > sg_len) ? sg_len : datalen;
+
+ if (i == host->dma.len - 1)
+ flags = DDMA_FLAGS_IE;
+
+ if (host->flags & HOST_F_XMIT){
+ ret = au1xxx_dbdma_put_source_flags(channel,
+ (void *) (page_address(sg->page) +
+ sg->offset),
+ len, flags);
+ }
+ else {
+ ret = au1xxx_dbdma_put_dest_flags(channel,
+ (void *) (page_address(sg->page) +
+ sg->offset),
+ len, flags);
+ }
+
+ if (!ret)
+ goto dataerr;
+
+ datalen -= len;
+ }
+ }
+ else {
+ host->pio.index = 0;
+ host->pio.offset = 0;
+ host->pio.len = datalen;
+
+ if (host->flags & HOST_F_XMIT)
+ IRQ_ON(host, SD_CONFIG_TH);
+ else
+ IRQ_ON(host, SD_CONFIG_NE);
+ //IRQ_ON(host, SD_CONFIG_RA|SD_CONFIG_RF);
+ }
+
+ return MMC_ERR_NONE;
+
+ dataerr:
+ dma_unmap_sg(mmc_dev(host->mmc),data->sg,data->sg_len,host->dma.dir);
+ return MMC_ERR_TIMEOUT;
+}
+
+/* static void au1xmmc_request
+ This actually starts a command or data transaction
+*/
+
+static void au1xmmc_request(struct mmc_host* mmc, struct mmc_request* mrq)
+{
+
+ struct au1xmmc_host *host = mmc_priv(mmc);
+ int ret = MMC_ERR_NONE;
+
+ WARN_ON(irqs_disabled());
+ WARN_ON(host->status != HOST_S_IDLE);
+
+ host->mrq = mrq;
+ host->status = HOST_S_CMD;
+
+ bcsr->disk_leds &= ~(1 << 8);
+
+ if (mrq->data) {
+ FLUSH_FIFO(host);
+ ret = au1xmmc_prepare_data(host, mrq->data);
+ }
+
+ if (ret == MMC_ERR_NONE)
+ ret = au1xmmc_send_command(host, 0, mrq->cmd);
+
+ if (ret != MMC_ERR_NONE) {
+ mrq->cmd->error = ret;
+ au1xmmc_finish_request(host);
+ }
+}
+
+static void au1xmmc_reset_controller(struct au1xmmc_host *host)
+{
+
+ /* Apply the clock */
+ au_writel(SD_ENABLE_CE, HOST_ENABLE(host));
+ au_sync_delay(1);
+
+ au_writel(SD_ENABLE_R | SD_ENABLE_CE, HOST_ENABLE(host));
+ au_sync_delay(5);
+
+ au_writel(~0, HOST_STATUS(host));
+ au_sync();
+
+ au_writel(0, HOST_BLKSIZE(host));
+ au_writel(0x001fffff, HOST_TIMEOUT(host));
+ au_sync();
+
+ au_writel(SD_CONFIG2_EN, HOST_CONFIG2(host));
+ au_sync();
+
+ au_writel(SD_CONFIG2_EN | SD_CONFIG2_FF, HOST_CONFIG2(host));
+ au_sync_delay(1);
+
+ au_writel(SD_CONFIG2_EN, HOST_CONFIG2(host));
+ au_sync();
+
+ /* Configure interrupts */
+ au_writel(AU1XMMC_INTERRUPTS, HOST_CONFIG(host));
+ au_sync();
+}
+
+
+static void au1xmmc_set_ios(struct mmc_host* mmc, struct mmc_ios* ios)
+{
+ struct au1xmmc_host *host = mmc_priv(mmc);
+
+ DEBUG("set_ios (power=%u, clock=%uHz, vdd=%u, mode=%u)\n",
+ host->id, ios->power_mode, ios->clock, ios->vdd,
+ ios->bus_mode);
+
+ if (ios->power_mode == MMC_POWER_OFF)
+ au1xmmc_set_power(host, 0);
+ else if (ios->power_mode == MMC_POWER_ON) {
+ au1xmmc_set_power(host, 1);
+ }
+
+ if (ios->clock && ios->clock != host->clock) {
+ au1xmmc_set_clock(host, ios->clock);
+ host->clock = ios->clock;
+ }
+}
+
+static void au1xmmc_dma_callback(int irq, void *dev_id, struct pt_regs *regs)
+{
+ struct au1xmmc_host *host = (struct au1xmmc_host *) dev_id;
+ u32 status;
+
+ /* Avoid spurious interrupts */
+
+ if (!host->mrq)
+ return;
+
+ if (host->flags & HOST_F_STOP)
+ SEND_STOP(host);
+
+ tasklet_schedule(&host->data_task);
+}
+
+#define STATUS_TIMEOUT (SD_STATUS_RAT | SD_STATUS_DT)
+#define STATUS_DATA_IN (SD_STATUS_NE)
+#define STATUS_DATA_OUT (SD_STATUS_TH)
+
+static irqreturn_t au1xmmc_irq(int irq, void *dev_id, struct pt_regs *regs)
+{
+
+ u32 status;
+ int i, ret = 0;
+
+ disable_irq(AU1100_SD_IRQ);
+
+ for(i = 0; i < AU1XMMC_CONTROLLER_COUNT; i++) {
+ struct au1xmmc_host * host = au1xmmc_hosts[i];
+ u32 handled = 1;
+
+ status = au_readl(HOST_STATUS(host));
+
+ if (host->mrq && (status & STATUS_TIMEOUT)) {
+ if (status & SD_STATUS_RAT)
+ host->mrq->cmd->error = MMC_ERR_TIMEOUT;
+
+ else if (status & SD_STATUS_DT)
+ host->mrq->data->error = MMC_ERR_TIMEOUT;
+
+ /* In PIO mode, interrupts might still be enabled */
+ IRQ_OFF(host, SD_CONFIG_NE | SD_CONFIG_TH);
+
+ //IRQ_OFF(host, SD_CONFIG_TH|SD_CONFIG_RA|SD_CONFIG_RF);
+ tasklet_schedule(&host->finish_task);
+ }
+#if 0
+ else if (status & SD_STATUS_DD) {
+
+ /* Sometimes we get a DD before a NE in PIO mode */
+
+ if (!(host->flags & HOST_F_DMA) &&
+ (status & SD_STATUS_NE))
+ au1xmmc_receive_pio(host);
+ else {
+ au1xmmc_data_complete(host, status);
+ //tasklet_schedule(&host->data_task);
+ }
+ }
+#endif
+ else if (status & (SD_STATUS_CR)) {
+ if (host->status == HOST_S_CMD)
+ au1xmmc_cmd_complete(host,status);
+ }
+ else if (!(host->flags & HOST_F_DMA)) {
+ if ((host->flags & HOST_F_XMIT) &&
+ (status & STATUS_DATA_OUT))
+ au1xmmc_send_pio(host);
+ else if ((host->flags & HOST_F_RECV) &&
+ (status & STATUS_DATA_IN))
+ au1xmmc_receive_pio(host);
+ }
+ else if (status & 0x203FBC70) {
+ DEBUG("Unhandled status %8.8x\n", host->id, status);
+ handled = 0;
+ }
+
+ au_writel(status, HOST_STATUS(host));
+ au_sync();
+
+ ret |= handled;
+ }
+
+ enable_irq(AU1100_SD_IRQ);
+ return ret;
+}
+
+static void au1xmmc_poll_event(unsigned long arg)
+{
+ struct au1xmmc_host *host = (struct au1xmmc_host *) arg;
+
+ int card = au1xmmc_card_inserted(host);
+ int controller = (host->flags & HOST_F_ACTIVE) ? 1 : 0;
+
+ if (card != controller) {
+ host->flags &= ~HOST_F_ACTIVE;
+ if (card) host->flags |= HOST_F_ACTIVE;
+ mmc_detect_change(host->mmc, 0);
+ }
+
+ if (host->mrq != NULL) {
+ u32 status = au_readl(HOST_STATUS(host));
+ DEBUG("PENDING - %8.8x\n", host->id, status);
+ }
+
+ mod_timer(&host->timer, jiffies + AU1XMMC_DETECT_TIMEOUT);
+}
+
+static dbdev_tab_t au1xmmc_mem_dbdev =
+{
+ DSCR_CMD0_ALWAYS, DEV_FLAGS_ANYUSE, 0, 8, 0x00000000, 0, 0
+};
+
+static void au1xmmc_init_dma(struct au1xmmc_host *host)
+{
+
+ u32 rxchan, txchan;
+
+ int txid = au1xmmc_card_table[host->id].tx_devid;
+ int rxid = au1xmmc_card_table[host->id].rx_devid;
+
+ /* DSCR_CMD0_ALWAYS has a stride of 32 bits, we need a stride
+ of 8 bits. And since devices are shared, we need to create
+ our own to avoid freaking out other devices
+ */
+
+ int memid = au1xxx_ddma_add_device(&au1xmmc_mem_dbdev);
+
+ txchan = au1xxx_dbdma_chan_alloc(memid, txid,
+ au1xmmc_dma_callback, (void *) host);
+
+ rxchan = au1xxx_dbdma_chan_alloc(rxid, memid,
+ au1xmmc_dma_callback, (void *) host);
+
+ au1xxx_dbdma_set_devwidth(txchan, 8);
+ au1xxx_dbdma_set_devwidth(rxchan, 8);
+
+ au1xxx_dbdma_ring_alloc(txchan, AU1XMMC_DESCRIPTOR_COUNT);
+ au1xxx_dbdma_ring_alloc(rxchan, AU1XMMC_DESCRIPTOR_COUNT);
+
+ host->tx_chan = txchan;
+ host->rx_chan = rxchan;
+}
+
+struct mmc_host_ops au1xmmc_ops = {
+ .request = au1xmmc_request,
+ .set_ios = au1xmmc_set_ios,
+};
+
+static int au1xmmc_probe(struct device *dev)
+{
+
+ int i, ret = 0;
+
+ /* THe interrupt is shared among all controllers */
+ ret = request_irq(AU1100_SD_IRQ, au1xmmc_irq, SA_INTERRUPT, "MMC", 0);
+
+ if (ret) {
+ printk(DRIVER_NAME "ERROR: Couldn't get int %d: %d\n",
+ AU1100_SD_IRQ, ret);
+ return -ENXIO;
+ }
+
+ disable_irq(AU1100_SD_IRQ);
+
+ for(i = 0; i < AU1XMMC_CONTROLLER_COUNT; i++) {
+ struct mmc_host *mmc = mmc_alloc_host(sizeof(struct au1xmmc_host), dev);
+ struct au1xmmc_host *host = 0;
+
+ if (!mmc) {
+ printk(DRIVER_NAME "ERROR: no mem for host %d\n", i);
+ au1xmmc_hosts[i] = 0;
+ continue;
+ }
+
+ mmc->ops = &au1xmmc_ops;
+
+ mmc->f_min = 450000;
+ mmc->f_max = 24000000;
+
+ mmc->max_seg_size = AU1XMMC_DESCRIPTOR_SIZE;
+ mmc->max_phys_segs = AU1XMMC_DESCRIPTOR_COUNT;
+
+ mmc->ocr_avail = AU1XMMC_OCR;
+
+ host = mmc_priv(mmc);
+ host->mmc = mmc;
+
+ host->id = i;
+ host->iobase = au1xmmc_card_table[host->id].iobase;
+ host->clock = 0;
+ host->power_mode = MMC_POWER_OFF;
+
+ host->flags = au1xmmc_card_inserted(host) ? HOST_F_ACTIVE : 0;
+ host->status = HOST_S_IDLE;
+
+ init_timer(&host->timer);
+
+ host->timer.function = au1xmmc_poll_event;
+ host->timer.data = (unsigned long) host;
+ host->timer.expires = jiffies + AU1XMMC_DETECT_TIMEOUT;
+
+ tasklet_init(&host->data_task, au1xmmc_tasklet_data,
+ (unsigned long) host);
+
+ tasklet_init(&host->finish_task, au1xmmc_tasklet_finish,
+ (unsigned long) host);
+
+ spin_lock_init(&host->lock);
+
+ if (dma != 0)
+ au1xmmc_init_dma(host);
+
+ au1xmmc_reset_controller(host);
+
+ mmc_add_host(mmc);
+ au1xmmc_hosts[i] = host;
+
+ add_timer(&host->timer);
+
+ printk(KERN_INFO DRIVER_NAME ": MMC Controller %d set up at %8.8X (mode=%s)\n",
+ host->id, host->iobase, dma ? "dma" : "pio");
+ }
+
+ enable_irq(AU1100_SD_IRQ);
+
+ return 0;
+}
+
+static int au1xmmc_remove(struct device *dev)
+{
+
+ int i;
+
+ disable_irq(AU1100_SD_IRQ);
+
+ for(i = 0; i < AU1XMMC_CONTROLLER_COUNT; i++) {
+ struct au1xmmc_host *host = au1xmmc_hosts[i];
+ if (!host) continue;
+
+ tasklet_kill(&host->data_task);
+ tasklet_kill(&host->finish_task);
+
+ del_timer_sync(&host->timer);
+ au1xmmc_set_power(host, 0);
+
+ mmc_remove_host(host->mmc);
+
+ au1xxx_dbdma_chan_free(host->tx_chan);
+ au1xxx_dbdma_chan_free(host->rx_chan);
+
+ au_writel(0x0, HOST_ENABLE(host));
+ au_sync();
+ }
+
+ free_irq(AU1100_SD_IRQ, 0);
+ return 0;
+}
+
+static struct device_driver au1xmmc_driver = {
+ .name = DRIVER_NAME,
+ .bus = &platform_bus_type,
+ .probe = au1xmmc_probe,
+ .remove = au1xmmc_remove,
+ .suspend = NULL,
+ .resume = NULL
+};
+
+static int __init au1xmmc_init(void)
+{
+ return driver_register(&au1xmmc_driver);
+}
+
+static void __exit au1xmmc_exit(void)
+{
+ driver_unregister(&au1xmmc_driver);
+}
+
+module_init(au1xmmc_init);
+module_exit(au1xmmc_exit);
+
+#ifdef MODULE
+MODULE_AUTHOR("Advanced Micro Devices, Inc");
+MODULE_DESCRIPTION("MMC/SD driver for the Alchemy Au1XXX");
+MODULE_LICENSE("GPL");
+#endif
+
diff --git a/drivers/mmc/au1xmmc.h b/drivers/mmc/au1xmmc.h
new file mode 100644
index 000000000000..341cbdf0baca
--- /dev/null
+++ b/drivers/mmc/au1xmmc.h
@@ -0,0 +1,96 @@
+#ifndef _AU1XMMC_H_
+#define _AU1XMMC_H_
+
+/* Hardware definitions */
+
+#define AU1XMMC_DESCRIPTOR_COUNT 1
+#define AU1XMMC_DESCRIPTOR_SIZE 2048
+
+#define AU1XMMC_OCR ( MMC_VDD_27_28 | MMC_VDD_28_29 | MMC_VDD_29_30 | \
+ MMC_VDD_30_31 | MMC_VDD_31_32 | MMC_VDD_32_33 | \
+ MMC_VDD_33_34 | MMC_VDD_34_35 | MMC_VDD_35_36)
+
+/* Easy access macros */
+
+#define HOST_STATUS(h) ((h)->iobase + SD_STATUS)
+#define HOST_CONFIG(h) ((h)->iobase + SD_CONFIG)
+#define HOST_ENABLE(h) ((h)->iobase + SD_ENABLE)
+#define HOST_TXPORT(h) ((h)->iobase + SD_TXPORT)
+#define HOST_RXPORT(h) ((h)->iobase + SD_RXPORT)
+#define HOST_CMDARG(h) ((h)->iobase + SD_CMDARG)
+#define HOST_BLKSIZE(h) ((h)->iobase + SD_BLKSIZE)
+#define HOST_CMD(h) ((h)->iobase + SD_CMD)
+#define HOST_CONFIG2(h) ((h)->iobase + SD_CONFIG2)
+#define HOST_TIMEOUT(h) ((h)->iobase + SD_TIMEOUT)
+#define HOST_DEBUG(h) ((h)->iobase + SD_DEBUG)
+
+#define DMA_CHANNEL(h) \
+ ( ((h)->flags & HOST_F_XMIT) ? (h)->tx_chan : (h)->rx_chan)
+
+/* This gives us a hard value for the stop command that we can write directly
+ * to the command register
+ */
+
+#define STOP_CMD (SD_CMD_RT_1B|SD_CMD_CT_7|(0xC << SD_CMD_CI_SHIFT)|SD_CMD_GO)
+
+/* This is the set of interrupts that we configure by default */
+
+#if 0
+#define AU1XMMC_INTERRUPTS (SD_CONFIG_SC | SD_CONFIG_DT | SD_CONFIG_DD | \
+ SD_CONFIG_RAT | SD_CONFIG_CR | SD_CONFIG_I)
+#endif
+
+#define AU1XMMC_INTERRUPTS (SD_CONFIG_SC | SD_CONFIG_DT | \
+ SD_CONFIG_RAT | SD_CONFIG_CR | SD_CONFIG_I)
+/* The poll event (looking for insert/remove events runs twice a second */
+#define AU1XMMC_DETECT_TIMEOUT (HZ/2)
+
+struct au1xmmc_host {
+ struct mmc_host *mmc;
+ struct mmc_request *mrq;
+
+ u32 id;
+
+ u32 flags;
+ u32 iobase;
+ u32 clock;
+ u32 bus_width;
+ u32 power_mode;
+
+ int status;
+
+ struct {
+ int len;
+ int dir;
+ } dma;
+
+ struct {
+ int index;
+ int offset;
+ int len;
+ } pio;
+
+ u32 tx_chan;
+ u32 rx_chan;
+
+ struct timer_list timer;
+ struct tasklet_struct finish_task;
+ struct tasklet_struct data_task;
+
+ spinlock_t lock;
+};
+
+/* Status flags used by the host structure */
+
+#define HOST_F_XMIT 0x0001
+#define HOST_F_RECV 0x0002
+#define HOST_F_DMA 0x0010
+#define HOST_F_ACTIVE 0x0100
+#define HOST_F_STOP 0x1000
+
+#define HOST_S_IDLE 0x0001
+#define HOST_S_CMD 0x0002
+#define HOST_S_DATA 0x0003
+#define HOST_S_STOP 0x0004
+
+#endif
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index ceae379a4d4c..da528390acf8 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -1263,7 +1263,7 @@ EXPORT_SYMBOL(mmc_suspend_host);
*/
int mmc_resume_host(struct mmc_host *host)
{
- mmc_detect_change(host, 0);
+ mmc_rescan(host);
return 0;
}
diff --git a/drivers/mmc/mmc_block.c b/drivers/mmc/mmc_block.c
index fa83f15fdf16..d91fcf7c3178 100644
--- a/drivers/mmc/mmc_block.c
+++ b/drivers/mmc/mmc_block.c
@@ -85,6 +85,12 @@ static void mmc_blk_put(struct mmc_blk_data *md)
up(&open_lock);
}
+static inline int mmc_blk_readonly(struct mmc_card *card)
+{
+ return mmc_card_readonly(card) ||
+ !(card->csd.cmdclass & CCC_BLOCK_WRITE);
+}
+
static int mmc_blk_open(struct inode *inode, struct file *filp)
{
struct mmc_blk_data *md;
@@ -97,7 +103,7 @@ static int mmc_blk_open(struct inode *inode, struct file *filp)
ret = 0;
if ((filp->f_mode & FMODE_WRITE) &&
- mmc_card_readonly(md->queue.card))
+ mmc_blk_readonly(md->queue.card))
ret = -EROFS;
}
@@ -197,7 +203,6 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
brq.data.flags |= MMC_DATA_READ;
} else {
brq.cmd.opcode = MMC_WRITE_BLOCK;
- brq.cmd.flags = MMC_RSP_R1B;
brq.data.flags |= MMC_DATA_WRITE;
brq.data.blocks = 1;
}
@@ -410,7 +415,7 @@ static int mmc_blk_probe(struct mmc_card *card)
printk(KERN_INFO "%s: %s %s %dKiB %s\n",
md->disk->disk_name, mmc_card_id(card), mmc_card_name(card),
(card->csd.capacity << card->csd.read_blkbits) / 1024,
- mmc_card_readonly(card)?"(ro)":"");
+ mmc_blk_readonly(card)?"(ro)":"");
mmc_set_drvdata(card, md);
add_disk(md->disk);
diff --git a/drivers/mmc/mmci.c b/drivers/mmc/mmci.c
index 91c74843dc0d..1e6bdba26756 100644
--- a/drivers/mmc/mmci.c
+++ b/drivers/mmc/mmci.c
@@ -24,6 +24,7 @@
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/scatterlist.h>
+#include <asm/sizes.h>
#include <asm/hardware/amba.h>
#include <asm/hardware/clock.h>
#include <asm/mach/mmc.h>
diff --git a/drivers/mmc/pxamci.c b/drivers/mmc/pxamci.c
index b53af57074e3..f31e247b2cbe 100644
--- a/drivers/mmc/pxamci.c
+++ b/drivers/mmc/pxamci.c
@@ -20,7 +20,7 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/ioport.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/dma-mapping.h>
@@ -29,7 +29,6 @@
#include <asm/dma.h>
#include <asm/io.h>
-#include <asm/irq.h>
#include <asm/scatterlist.h>
#include <asm/sizes.h>
@@ -571,23 +570,23 @@ static int pxamci_remove(struct device *dev)
}
#ifdef CONFIG_PM
-static int pxamci_suspend(struct device *dev, pm_message_t state, u32 level)
+static int pxamci_suspend(struct device *dev, pm_message_t state)
{
struct mmc_host *mmc = dev_get_drvdata(dev);
int ret = 0;
- if (mmc && level == SUSPEND_DISABLE)
+ if (mmc)
ret = mmc_suspend_host(mmc, state);
return ret;
}
-static int pxamci_resume(struct device *dev, u32 level)
+static int pxamci_resume(struct device *dev)
{
struct mmc_host *mmc = dev_get_drvdata(dev);
int ret = 0;
- if (mmc && level == RESUME_ENABLE)
+ if (mmc)
ret = mmc_resume_host(mmc);
return ret;
diff --git a/drivers/mmc/wbsd.c b/drivers/mmc/wbsd.c
index 3cbca7cbea80..e954b8354fef 100644
--- a/drivers/mmc/wbsd.c
+++ b/drivers/mmc/wbsd.c
@@ -26,7 +26,7 @@
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/ioport.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <linux/interrupt.h>
#include <linux/dma-mapping.h>
#include <linux/delay.h>
@@ -201,7 +201,7 @@ static void wbsd_reset(struct wbsd_host* host)
{
u8 setup;
- printk(KERN_ERR DRIVER_NAME ": Resetting chip\n");
+ printk(KERN_ERR "%s: Resetting chip\n", mmc_hostname(host->mmc));
/*
* Soft reset of chip (SD/MMC part).
@@ -880,8 +880,9 @@ static void wbsd_finish_data(struct wbsd_host* host, struct mmc_data* data)
*/
if (count)
{
- printk(KERN_ERR DRIVER_NAME ": Incomplete DMA "
- "transfer. %d bytes left.\n", count);
+ printk(KERN_ERR "%s: Incomplete DMA transfer. "
+ "%d bytes left.\n",
+ mmc_hostname(host->mmc), count);
data->error = MMC_ERR_FAILED;
}
@@ -1033,13 +1034,16 @@ static void wbsd_set_ios(struct mmc_host* mmc, struct mmc_ios* ios)
}
else
{
- setup &= ~WBSD_DAT3_H;
+ if (setup & WBSD_DAT3_H)
+ {
+ setup &= ~WBSD_DAT3_H;
- /*
- * We cannot resume card detection immediatly
- * because of capacitance and delays in the chip.
- */
- mod_timer(&host->ignore_timer, jiffies + HZ/100);
+ /*
+ * We cannot resume card detection immediatly
+ * because of capacitance and delays in the chip.
+ */
+ mod_timer(&host->ignore_timer, jiffies + HZ/100);
+ }
}
wbsd_write_index(host, WBSD_IDX_SETUP, setup);
@@ -1166,8 +1170,8 @@ static void wbsd_tasklet_card(unsigned long param)
if (host->mrq)
{
- printk(KERN_ERR DRIVER_NAME
- ": Card removed during transfer!\n");
+ printk(KERN_ERR "%s: Card removed during transfer!\n",
+ mmc_hostname(host->mmc));
wbsd_reset(host);
host->mrq->cmd->error = MMC_ERR_FAILED;
@@ -1461,8 +1465,10 @@ static int __devinit wbsd_scan(struct wbsd_host* host)
{
id = 0xFFFF;
- outb(unlock_codes[j], config_ports[i]);
- outb(unlock_codes[j], config_ports[i]);
+ host->config = config_ports[i];
+ host->unlock_code = unlock_codes[j];
+
+ wbsd_unlock_config(host);
outb(WBSD_CONF_ID_HI, config_ports[i]);
id = inb(config_ports[i] + 1) << 8;
@@ -1470,13 +1476,13 @@ static int __devinit wbsd_scan(struct wbsd_host* host)
outb(WBSD_CONF_ID_LO, config_ports[i]);
id |= inb(config_ports[i] + 1);
+ wbsd_lock_config(host);
+
for (k = 0;k < sizeof(valid_ids)/sizeof(int);k++)
{
if (id == valid_ids[k])
{
host->chip_id = id;
- host->config = config_ports[i];
- host->unlock_code = unlock_codes[i];
return 0;
}
@@ -1487,13 +1493,14 @@ static int __devinit wbsd_scan(struct wbsd_host* host)
DBG("Unknown hardware (id %x) found at %x\n",
id, config_ports[i]);
}
-
- outb(LOCK_CODE, config_ports[i]);
}
release_region(config_ports[i], 2);
}
+ host->config = 0;
+ host->unlock_code = 0;
+
return -ENODEV;
}
@@ -1595,8 +1602,7 @@ static void __devexit wbsd_release_dma(struct wbsd_host* host)
if (host->dma_addr)
dma_unmap_single(host->mmc->dev, host->dma_addr, WBSD_DMA_SIZE,
DMA_BIDIRECTIONAL);
- if (host->dma_buffer)
- kfree(host->dma_buffer);
+ kfree(host->dma_buffer);
if (host->dma >= 0)
free_dma(host->dma);
@@ -1699,8 +1705,10 @@ static void __devexit wbsd_release_resources(struct wbsd_host* host)
* Configure the resources the chip should use.
*/
-static void __devinit wbsd_chip_config(struct wbsd_host* host)
+static void wbsd_chip_config(struct wbsd_host* host)
{
+ wbsd_unlock_config(host);
+
/*
* Reset the chip.
*/
@@ -1733,16 +1741,20 @@ static void __devinit wbsd_chip_config(struct wbsd_host* host)
*/
wbsd_write_config(host, WBSD_CONF_ENABLE, 1);
wbsd_write_config(host, WBSD_CONF_POWER, 0x20);
+
+ wbsd_lock_config(host);
}
/*
* Check that configured resources are correct.
*/
-static int __devinit wbsd_chip_validate(struct wbsd_host* host)
+static int wbsd_chip_validate(struct wbsd_host* host)
{
int base, irq, dma;
+ wbsd_unlock_config(host);
+
/*
* Select SD/MMC function.
*/
@@ -1758,6 +1770,8 @@ static int __devinit wbsd_chip_validate(struct wbsd_host* host)
dma = wbsd_read_config(host, WBSD_CONF_DRQ);
+ wbsd_lock_config(host);
+
/*
* Validate against given configuration.
*/
@@ -1771,6 +1785,20 @@ static int __devinit wbsd_chip_validate(struct wbsd_host* host)
return 1;
}
+/*
+ * Powers down the SD function
+ */
+
+static void wbsd_chip_poweroff(struct wbsd_host* host)
+{
+ wbsd_unlock_config(host);
+
+ wbsd_write_config(host, WBSD_CONF_DEVICE, DEVICE_SD);
+ wbsd_write_config(host, WBSD_CONF_ENABLE, 0);
+
+ wbsd_lock_config(host);
+}
+
/*****************************************************************************\
* *
* Devices setup and shutdown *
@@ -1824,9 +1852,9 @@ static int __devinit wbsd_init(struct device* dev, int base, int irq, int dma,
/*
* See if chip needs to be configured.
*/
- if (pnp && (host->config != 0))
+ if (pnp)
{
- if (!wbsd_chip_validate(host))
+ if ((host->config != 0) && !wbsd_chip_validate(host))
{
printk(KERN_WARNING DRIVER_NAME
": PnP active but chip not configured! "
@@ -1844,7 +1872,11 @@ static int __devinit wbsd_init(struct device* dev, int base, int irq, int dma,
*/
#ifdef CONFIG_PM
if (host->config)
+ {
+ wbsd_unlock_config(host);
wbsd_write_config(host, WBSD_CONF_PME, 0xA0);
+ wbsd_lock_config(host);
+ }
#endif
/*
* Allow device to initialise itself properly.
@@ -1885,16 +1917,11 @@ static void __devexit wbsd_shutdown(struct device* dev, int pnp)
mmc_remove_host(mmc);
+ /*
+ * Power down the SD/MMC function.
+ */
if (!pnp)
- {
- /*
- * Power down the SD/MMC function.
- */
- wbsd_unlock_config(host);
- wbsd_write_config(host, WBSD_CONF_DEVICE, DEVICE_SD);
- wbsd_write_config(host, WBSD_CONF_ENABLE, 0);
- wbsd_lock_config(host);
- }
+ wbsd_chip_poweroff(host);
wbsd_release_resources(host);
@@ -1955,23 +1982,59 @@ static void __devexit wbsd_pnp_remove(struct pnp_dev * dev)
*/
#ifdef CONFIG_PM
-static int wbsd_suspend(struct device *dev, pm_message_t state, u32 level)
+
+static int wbsd_suspend(struct device *dev, pm_message_t state)
{
- DBGF("Not yet supported\n");
+ struct mmc_host *mmc = dev_get_drvdata(dev);
+ struct wbsd_host *host;
+ int ret;
+
+ if (!mmc)
+ return 0;
+
+ DBG("Suspending...\n");
+
+ ret = mmc_suspend_host(mmc, state);
+ if (!ret)
+ return ret;
+
+ host = mmc_priv(mmc);
+
+ wbsd_chip_poweroff(host);
return 0;
}
-static int wbsd_resume(struct device *dev, u32 level)
+static int wbsd_resume(struct device *dev)
{
- DBGF("Not yet supported\n");
+ struct mmc_host *mmc = dev_get_drvdata(dev);
+ struct wbsd_host *host;
- return 0;
+ if (!mmc)
+ return 0;
+
+ DBG("Resuming...\n");
+
+ host = mmc_priv(mmc);
+
+ wbsd_chip_config(host);
+
+ /*
+ * Allow device to initialise itself properly.
+ */
+ mdelay(5);
+
+ wbsd_init_device(host);
+
+ return mmc_resume_host(mmc);
}
-#else
+
+#else /* CONFIG_PM */
+
#define wbsd_suspend NULL
#define wbsd_resume NULL
-#endif
+
+#endif /* CONFIG_PM */
static struct platform_device *wbsd_device;
diff --git a/drivers/mtd/Kconfig b/drivers/mtd/Kconfig
index 027054dea032..f6b775e63ac8 100644
--- a/drivers/mtd/Kconfig
+++ b/drivers/mtd/Kconfig
@@ -1,4 +1,4 @@
-# $Id: Kconfig,v 1.7 2004/11/22 11:33:56 ijc Exp $
+# $Id: Kconfig,v 1.11 2005/11/07 11:14:19 gleixner Exp $
menu "Memory Technology Devices (MTD)"
@@ -10,7 +10,7 @@ config MTD
will provide the generic support for MTD drivers to register
themselves with the kernel and for potential users of MTD devices
to enumerate the devices which are present and obtain a handle on
- them. It will also allow you to select individual drivers for
+ them. It will also allow you to select individual drivers for
particular hardware and users of MTD devices. If unsure, say N.
config MTD_DEBUG
@@ -61,11 +61,11 @@ config MTD_REDBOOT_PARTS
If you need code which can detect and parse this table, and register
MTD 'partitions' corresponding to each image in the table, enable
- this option.
+ this option.
You will still need the parsing functions to be called by the driver
- for your particular device. It won't happen automatically. The
- SA1100 map driver (CONFIG_MTD_SA1100) has an option for this, for
+ for your particular device. It won't happen automatically. The
+ SA1100 map driver (CONFIG_MTD_SA1100) has an option for this, for
example.
config MTD_REDBOOT_DIRECTORY_BLOCK
@@ -81,10 +81,10 @@ config MTD_REDBOOT_DIRECTORY_BLOCK
partition table. A zero or positive value gives an absolete
erase block number. A negative value specifies a number of
sectors before the end of the device.
-
+
For example "2" means block number 2, "-1" means the last
block and "-2" means the penultimate block.
-
+
config MTD_REDBOOT_PARTS_UNALLOCATED
bool " Include unallocated flash regions"
depends on MTD_REDBOOT_PARTS
@@ -105,11 +105,11 @@ config MTD_CMDLINE_PARTS
---help---
Allow generic configuration of the MTD paritition tables via the kernel
command line. Multiple flash resources are supported for hardware where
- different kinds of flash memory are available.
+ different kinds of flash memory are available.
You will still need the parsing functions to be called by the driver
- for your particular device. It won't happen automatically. The
- SA1100 map driver (CONFIG_MTD_SA1100) has an option for this, for
+ for your particular device. It won't happen automatically. The
+ SA1100 map driver (CONFIG_MTD_SA1100) has an option for this, for
example.
The format for the command line is as follows:
@@ -118,12 +118,12 @@ config MTD_CMDLINE_PARTS
<mtddef> := <mtd-id>:<partdef>[,<partdef>]
<partdef> := <size>[@offset][<name>][ro]
<mtd-id> := unique id used in mapping driver/device
- <size> := standard linux memsize OR "-" to denote all
+ <size> := standard linux memsize OR "-" to denote all
remaining space
<name> := (NAME)
- Due to the way Linux handles the command line, no spaces are
- allowed in the partition definition, including mtd id's and partition
+ Due to the way Linux handles the command line, no spaces are
+ allowed in the partition definition, including mtd id's and partition
names.
Examples:
@@ -240,7 +240,7 @@ config INFTL
tristate "INFTL (Inverse NAND Flash Translation Layer) support"
depends on MTD
---help---
- This provides support for the Inverse NAND Flash Translation
+ This provides support for the Inverse NAND Flash Translation
Layer which is used on M-Systems' newer DiskOnChip devices. It
uses a kind of pseudo-file system on a flash device to emulate
a block device with 512-byte sectors, on top of which you put
@@ -253,6 +253,16 @@ config INFTL
permitted to copy, modify and distribute the code as you wish. Just
not use it.
+config RFD_FTL
+ tristate "Resident Flash Disk (Flash Translation Layer) support"
+ depends on MTD
+ ---help---
+ This provides support for the flash translation layer known
+ as the Resident Flash Disk (RFD), as used by the Embedded BIOS
+ of General Software. There is a blurb at:
+
+ http://www.gensw.com/pages/prod/bios/rfd.htm
+
source "drivers/mtd/chips/Kconfig"
source "drivers/mtd/maps/Kconfig"
@@ -261,5 +271,7 @@ source "drivers/mtd/devices/Kconfig"
source "drivers/mtd/nand/Kconfig"
+source "drivers/mtd/onenand/Kconfig"
+
endmenu
diff --git a/drivers/mtd/Makefile b/drivers/mtd/Makefile
index e4ad588327f7..fc9374407c2b 100644
--- a/drivers/mtd/Makefile
+++ b/drivers/mtd/Makefile
@@ -1,7 +1,7 @@
#
# Makefile for the memory technology device drivers.
#
-# $Id: Makefile.common,v 1.5 2004/08/10 20:51:49 dwmw2 Exp $
+# $Id: Makefile.common,v 1.7 2005/07/11 10:39:27 gleixner Exp $
# Core functionality.
mtd-y := mtdcore.o
@@ -20,8 +20,9 @@ obj-$(CONFIG_MTD_BLOCK_RO) += mtdblock_ro.o mtd_blkdevs.o
obj-$(CONFIG_FTL) += ftl.o mtd_blkdevs.o
obj-$(CONFIG_NFTL) += nftl.o mtd_blkdevs.o
obj-$(CONFIG_INFTL) += inftl.o mtd_blkdevs.o
+obj-$(CONFIG_RFD_FTL) += rfd_ftl.o mtd_blkdevs.o
nftl-objs := nftlcore.o nftlmount.o
inftl-objs := inftlcore.o inftlmount.o
-obj-y += chips/ maps/ devices/ nand/
+obj-y += chips/ maps/ devices/ nand/ onenand/
diff --git a/drivers/mtd/afs.c b/drivers/mtd/afs.c
index 7363e101eb0f..6a45be04564b 100644
--- a/drivers/mtd/afs.c
+++ b/drivers/mtd/afs.c
@@ -1,27 +1,27 @@
/*======================================================================
drivers/mtd/afs.c: ARM Flash Layout/Partitioning
-
+
Copyright (C) 2000 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
-
- This is access code for flashes using ARM's flash partitioning
+
+ This is access code for flashes using ARM's flash partitioning
standards.
- $Id: afs.c,v 1.13 2004/02/27 22:09:59 rmk Exp $
+ $Id: afs.c,v 1.15 2005/11/07 11:14:19 gleixner Exp $
======================================================================*/
@@ -163,7 +163,7 @@ afs_read_iis(struct mtd_info *mtd, struct image_info_struct *iis, u_int ptr)
return ret;
}
-static int parse_afs_partitions(struct mtd_info *mtd,
+static int parse_afs_partitions(struct mtd_info *mtd,
struct mtd_partition **pparts,
unsigned long origin)
{
diff --git a/drivers/mtd/chips/Kconfig b/drivers/mtd/chips/Kconfig
index df95d2158b16..eafa23f5cbd6 100644
--- a/drivers/mtd/chips/Kconfig
+++ b/drivers/mtd/chips/Kconfig
@@ -1,5 +1,5 @@
# drivers/mtd/chips/Kconfig
-# $Id: Kconfig,v 1.15 2005/06/06 23:04:35 tpoynor Exp $
+# $Id: Kconfig,v 1.18 2005/11/07 11:14:22 gleixner Exp $
menu "RAM/ROM/Flash chip drivers"
depends on MTD!=n
@@ -39,7 +39,7 @@ config MTD_CFI_ADV_OPTIONS
If you need to specify a specific endianness for access to flash
chips, or if you wish to reduce the size of the kernel by including
support for only specific arrangements of flash chips, say 'Y'. This
- option does not directly affect the code, but will enable other
+ option does not directly affect the code, but will enable other
configuration options which allow you to do so.
If unsure, say 'N'.
@@ -56,7 +56,7 @@ config MTD_CFI_NOSWAP
data bits when writing the 'magic' commands to the chips. Saying
'NO', which is the default when CONFIG_MTD_CFI_ADV_OPTIONS isn't
enabled, means that the CPU will not do any swapping; the chips
- are expected to be wired to the CPU in 'host-endian' form.
+ are expected to be wired to the CPU in 'host-endian' form.
Specific arrangements are possible with the BIG_ENDIAN_BYTE and
LITTLE_ENDIAN_BYTE, if the bytes are reversed.
@@ -79,10 +79,10 @@ config MTD_CFI_GEOMETRY
bool "Specific CFI Flash geometry selection"
depends on MTD_CFI_ADV_OPTIONS
help
- This option does not affect the code directly, but will enable
+ This option does not affect the code directly, but will enable
some other configuration options which would allow you to reduce
- the size of the kernel by including support for only certain
- arrangements of CFI chips. If unsure, say 'N' and all options
+ the size of the kernel by including support for only certain
+ arrangements of CFI chips. If unsure, say 'N' and all options
which are supported by the current code will be enabled.
config MTD_MAP_BANK_WIDTH_1
@@ -197,7 +197,7 @@ config MTD_CFI_AMDSTD
help
The Common Flash Interface defines a number of different command
sets which a CFI-compliant chip may claim to implement. This code
- provides support for one of those command sets, used on chips
+ provides support for one of those command sets, used on chips
including the AMD Am29LV320.
config MTD_CFI_AMDSTD_RETRY
@@ -237,14 +237,14 @@ config MTD_RAM
tristate "Support for RAM chips in bus mapping"
depends on MTD
help
- This option enables basic support for RAM chips accessed through
+ This option enables basic support for RAM chips accessed through
a bus mapping driver.
config MTD_ROM
tristate "Support for ROM chips in bus mapping"
depends on MTD
help
- This option enables basic support for ROM chips accessed through
+ This option enables basic support for ROM chips accessed through
a bus mapping driver.
config MTD_ABSENT
@@ -275,7 +275,7 @@ config MTD_AMDSTD
depends on MTD && MTD_OBSOLETE_CHIPS
help
This option enables support for flash chips using AMD-compatible
- commands, including some which are not CFI-compatible and hence
+ commands, including some which are not CFI-compatible and hence
cannot be used with the CONFIG_MTD_CFI_AMDSTD option.
It also works on AMD compatible chips that do conform to CFI.
@@ -285,7 +285,7 @@ config MTD_SHARP
depends on MTD && MTD_OBSOLETE_CHIPS
help
This option enables support for flash chips using Sharp-compatible
- commands, including some which are not CFI-compatible and hence
+ commands, including some which are not CFI-compatible and hence
cannot be used with the CONFIG_MTD_CFI_INTELxxx options.
config MTD_JEDEC
diff --git a/drivers/mtd/chips/Makefile b/drivers/mtd/chips/Makefile
index 6830489828c6..8afe3092c4e3 100644
--- a/drivers/mtd/chips/Makefile
+++ b/drivers/mtd/chips/Makefile
@@ -1,7 +1,7 @@
#
# linux/drivers/chips/Makefile
#
-# $Id: Makefile.common,v 1.4 2004/07/12 16:07:30 dwmw2 Exp $
+# $Id: Makefile.common,v 1.5 2005/11/07 11:14:22 gleixner Exp $
# *** BIG UGLY NOTE ***
#
@@ -11,7 +11,7 @@
# the CFI command set drivers are linked before gen_probe.o
obj-$(CONFIG_MTD) += chipreg.o
-obj-$(CONFIG_MTD_AMDSTD) += amd_flash.o
+obj-$(CONFIG_MTD_AMDSTD) += amd_flash.o
obj-$(CONFIG_MTD_CFI) += cfi_probe.o
obj-$(CONFIG_MTD_CFI_UTIL) += cfi_util.o
obj-$(CONFIG_MTD_CFI_STAA) += cfi_cmdset_0020.o
diff --git a/drivers/mtd/chips/amd_flash.c b/drivers/mtd/chips/amd_flash.c
index 2dafeba3f3d5..fdb91b6f1d97 100644
--- a/drivers/mtd/chips/amd_flash.c
+++ b/drivers/mtd/chips/amd_flash.c
@@ -3,7 +3,7 @@
*
* Author: Jonas Holmberg <jonas.holmberg@axis.com>
*
- * $Id: amd_flash.c,v 1.27 2005/02/04 07:43:09 jonashg Exp $
+ * $Id: amd_flash.c,v 1.28 2005/11/07 11:14:22 gleixner Exp $
*
* Copyright (c) 2001 Axis Communications AB
*
@@ -93,9 +93,9 @@
#define D6_MASK 0x40
struct amd_flash_private {
- int device_type;
- int interleave;
- int numchips;
+ int device_type;
+ int interleave;
+ int numchips;
unsigned long chipshift;
// const char *im_name;
struct flchip chips[0];
@@ -253,7 +253,7 @@ static int amd_flash_do_unlock(struct mtd_info *mtd, loff_t ofs, size_t len,
int i;
int retval = 0;
int lock_status;
-
+
map = mtd->priv;
/* Pass the whole chip through sector by sector and check for each
@@ -273,7 +273,7 @@ static int amd_flash_do_unlock(struct mtd_info *mtd, loff_t ofs, size_t len,
unlock_sector(map, eraseoffset, is_unlock);
lock_status = is_sector_locked(map, eraseoffset);
-
+
if (is_unlock && lock_status) {
printk("Cannot unlock sector at address %x length %xx\n",
eraseoffset, merip->erasesize);
@@ -305,7 +305,7 @@ static int amd_flash_lock(struct mtd_info *mtd, loff_t ofs, size_t len)
/*
* Reads JEDEC manufacturer ID and device ID and returns the index of the first
* matching table entry (-1 if not found or alias for already found chip).
- */
+ */
static int probe_new_chip(struct mtd_info *mtd, __u32 base,
struct flchip *chips,
struct amd_flash_private *private,
@@ -636,7 +636,7 @@ static struct mtd_info *amd_flash_probe(struct map_info *map)
{ .offset = 0x000000, .erasesize = 0x10000, .numblocks = 31 },
{ .offset = 0x1F0000, .erasesize = 0x02000, .numblocks = 8 }
}
- }
+ }
};
struct mtd_info *mtd;
@@ -701,7 +701,7 @@ static struct mtd_info *amd_flash_probe(struct map_info *map)
mtd->eraseregions = kmalloc(sizeof(struct mtd_erase_region_info) *
mtd->numeraseregions, GFP_KERNEL);
- if (!mtd->eraseregions) {
+ if (!mtd->eraseregions) {
printk(KERN_WARNING "%s: Failed to allocate "
"memory for MTD erase region info\n", map->name);
kfree(mtd);
@@ -739,12 +739,12 @@ static struct mtd_info *amd_flash_probe(struct map_info *map)
mtd->type = MTD_NORFLASH;
mtd->flags = MTD_CAP_NORFLASH;
mtd->name = map->name;
- mtd->erase = amd_flash_erase;
- mtd->read = amd_flash_read;
- mtd->write = amd_flash_write;
- mtd->sync = amd_flash_sync;
- mtd->suspend = amd_flash_suspend;
- mtd->resume = amd_flash_resume;
+ mtd->erase = amd_flash_erase;
+ mtd->read = amd_flash_read;
+ mtd->write = amd_flash_write;
+ mtd->sync = amd_flash_sync;
+ mtd->suspend = amd_flash_suspend;
+ mtd->resume = amd_flash_resume;
mtd->lock = amd_flash_lock;
mtd->unlock = amd_flash_unlock;
@@ -789,7 +789,7 @@ retry:
map->name, chip->state);
set_current_state(TASK_UNINTERRUPTIBLE);
add_wait_queue(&chip->wq, &wait);
-
+
spin_unlock_bh(chip->mutex);
schedule();
@@ -802,7 +802,7 @@ retry:
timeo = jiffies + HZ;
goto retry;
- }
+ }
adr += chip->start;
@@ -889,7 +889,7 @@ retry:
map->name, chip->state);
set_current_state(TASK_UNINTERRUPTIBLE);
add_wait_queue(&chip->wq, &wait);
-
+
spin_unlock_bh(chip->mutex);
schedule();
@@ -901,7 +901,7 @@ retry:
timeo = jiffies + HZ;
goto retry;
- }
+ }
chip->state = FL_WRITING;
@@ -911,7 +911,7 @@ retry:
wide_write(map, datum, adr);
times_left = 500000;
- while (times_left-- && flash_is_busy(map, adr, private->interleave)) {
+ while (times_left-- && flash_is_busy(map, adr, private->interleave)) {
if (need_resched()) {
spin_unlock_bh(chip->mutex);
schedule();
@@ -989,7 +989,7 @@ static int amd_flash_write(struct mtd_info *mtd, loff_t to , size_t len,
if (ret) {
return ret;
}
-
+
ofs += n;
buf += n;
(*retlen) += n;
@@ -1002,7 +1002,7 @@ static int amd_flash_write(struct mtd_info *mtd, loff_t to , size_t len,
}
}
}
-
+
/* We are now aligned, write as much as possible. */
while(len >= map->buswidth) {
__u32 datum;
@@ -1063,7 +1063,7 @@ static int amd_flash_write(struct mtd_info *mtd, loff_t to , size_t len,
if (ret) {
return ret;
}
-
+
(*retlen) += n;
}
@@ -1085,7 +1085,7 @@ retry:
if (chip->state != FL_READY){
set_current_state(TASK_UNINTERRUPTIBLE);
add_wait_queue(&chip->wq, &wait);
-
+
spin_unlock_bh(chip->mutex);
schedule();
@@ -1098,7 +1098,7 @@ retry:
timeo = jiffies + HZ;
goto retry;
- }
+ }
chip->state = FL_ERASING;
@@ -1106,30 +1106,30 @@ retry:
ENABLE_VPP(map);
send_cmd(map, chip->start, CMD_SECTOR_ERASE_UNLOCK_DATA);
send_cmd_to_addr(map, chip->start, CMD_SECTOR_ERASE_UNLOCK_DATA_2, adr);
-
+
timeo = jiffies + (HZ * 20);
spin_unlock_bh(chip->mutex);
msleep(1000);
spin_lock_bh(chip->mutex);
-
+
while (flash_is_busy(map, adr, private->interleave)) {
if (chip->state != FL_ERASING) {
/* Someone's suspended the erase. Sleep */
set_current_state(TASK_UNINTERRUPTIBLE);
add_wait_queue(&chip->wq, &wait);
-
+
spin_unlock_bh(chip->mutex);
printk(KERN_INFO "%s: erase suspended. Sleeping\n",
map->name);
schedule();
remove_wait_queue(&chip->wq, &wait);
-
+
if (signal_pending(current)) {
return -EINTR;
}
-
+
timeo = jiffies + (HZ*2); /* FIXME */
spin_lock_bh(chip->mutex);
continue;
@@ -1145,7 +1145,7 @@ retry:
return -EIO;
}
-
+
/* Latency issues. Drop the lock, wait a while and retry */
spin_unlock_bh(chip->mutex);
@@ -1153,7 +1153,7 @@ retry:
schedule();
else
udelay(1);
-
+
spin_lock_bh(chip->mutex);
}
@@ -1180,7 +1180,7 @@ retry:
return -EIO;
}
}
-
+
DISABLE_VPP(map);
chip->state = FL_READY;
wake_up(&chip->wq);
@@ -1246,7 +1246,7 @@ static int amd_flash_erase(struct mtd_info *mtd, struct erase_info *instr)
* with the erase region at that address.
*/
- while ((i < mtd->numeraseregions) &&
+ while ((i < mtd->numeraseregions) &&
((instr->addr + instr->len) >= regions[i].offset)) {
i++;
}
@@ -1293,10 +1293,10 @@ static int amd_flash_erase(struct mtd_info *mtd, struct erase_info *instr)
}
}
}
-
+
instr->state = MTD_ERASE_DONE;
mtd_erase_callback(instr);
-
+
return 0;
}
@@ -1324,7 +1324,7 @@ static void amd_flash_sync(struct mtd_info *mtd)
case FL_JEDEC_QUERY:
chip->oldstate = chip->state;
chip->state = FL_SYNCING;
- /* No need to wake_up() on this state change -
+ /* No need to wake_up() on this state change -
* as the whole point is that nobody can do anything
* with the chip now anyway.
*/
@@ -1335,13 +1335,13 @@ static void amd_flash_sync(struct mtd_info *mtd)
default:
/* Not an idle state */
add_wait_queue(&chip->wq, &wait);
-
+
spin_unlock_bh(chip->mutex);
schedule();
remove_wait_queue(&chip->wq, &wait);
-
+
goto retry;
}
}
@@ -1351,7 +1351,7 @@ static void amd_flash_sync(struct mtd_info *mtd)
chip = &private->chips[i];
spin_lock_bh(chip->mutex);
-
+
if (chip->state == FL_SYNCING) {
chip->state = chip->oldstate;
wake_up(&chip->wq);
diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c
index 0cfcd88468e0..143f01a4c170 100644
--- a/drivers/mtd/chips/cfi_cmdset_0001.c
+++ b/drivers/mtd/chips/cfi_cmdset_0001.c
@@ -4,9 +4,9 @@
*
* (C) 2000 Red Hat. GPL'd
*
- * $Id: cfi_cmdset_0001.c,v 1.178 2005/05/19 17:05:43 nico Exp $
+ * $Id: cfi_cmdset_0001.c,v 1.185 2005/11/07 11:14:22 gleixner Exp $
+ *
*
- *
* 10/10/2000 Nicolas Pitre <nico@cam.org>
* - completely revamped method functions so they are aware and
* independent of the flash geometry (buswidth, interleave, etc.)
@@ -51,6 +51,7 @@
static int cfi_intelext_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *);
static int cfi_intelext_write_words(struct mtd_info *, loff_t, size_t, size_t *, const u_char *);
static int cfi_intelext_write_buffers(struct mtd_info *, loff_t, size_t, size_t *, const u_char *);
+static int cfi_intelext_writev(struct mtd_info *, const struct kvec *, unsigned long, loff_t, size_t *);
static int cfi_intelext_erase_varsize(struct mtd_info *, struct erase_info *);
static void cfi_intelext_sync (struct mtd_info *);
static int cfi_intelext_lock(struct mtd_info *mtd, loff_t ofs, size_t len);
@@ -105,6 +106,7 @@ static struct mtd_chip_driver cfi_intelext_chipdrv = {
static void cfi_tell_features(struct cfi_pri_intelext *extp)
{
int i;
+ printk(" Extended Query version %c.%c\n", extp->MajorVersion, extp->MinorVersion);
printk(" Feature/Command Support: %4.4X\n", extp->FeatureSupport);
printk(" - Chip Erase: %s\n", extp->FeatureSupport&1?"supported":"unsupported");
printk(" - Suspend Erase: %s\n", extp->FeatureSupport&2?"supported":"unsupported");
@@ -116,36 +118,43 @@ static void cfi_tell_features(struct cfi_pri_intelext *extp)
printk(" - Page-mode read: %s\n", extp->FeatureSupport&128?"supported":"unsupported");
printk(" - Synchronous read: %s\n", extp->FeatureSupport&256?"supported":"unsupported");
printk(" - Simultaneous operations: %s\n", extp->FeatureSupport&512?"supported":"unsupported");
- for (i=10; i<32; i++) {
- if (extp->FeatureSupport & (1<<i))
+ printk(" - Extended Flash Array: %s\n", extp->FeatureSupport&1024?"supported":"unsupported");
+ for (i=11; i<32; i++) {
+ if (extp->FeatureSupport & (1<<i))
printk(" - Unknown Bit %X: supported\n", i);
}
-
+
printk(" Supported functions after Suspend: %2.2X\n", extp->SuspendCmdSupport);
printk(" - Program after Erase Suspend: %s\n", extp->SuspendCmdSupport&1?"supported":"unsupported");
for (i=1; i<8; i++) {
if (extp->SuspendCmdSupport & (1<<i))
printk(" - Unknown Bit %X: supported\n", i);
}
-
+
printk(" Block Status Register Mask: %4.4X\n", extp->BlkStatusRegMask);
printk(" - Lock Bit Active: %s\n", extp->BlkStatusRegMask&1?"yes":"no");
- printk(" - Valid Bit Active: %s\n", extp->BlkStatusRegMask&2?"yes":"no");
- for (i=2; i<16; i++) {
+ printk(" - Lock-Down Bit Active: %s\n", extp->BlkStatusRegMask&2?"yes":"no");
+ for (i=2; i<3; i++) {
if (extp->BlkStatusRegMask & (1<<i))
printk(" - Unknown Bit %X Active: yes\n",i);
}
-
- printk(" Vcc Logic Supply Optimum Program/Erase Voltage: %d.%d V\n",
+ printk(" - EFA Lock Bit: %s\n", extp->BlkStatusRegMask&16?"yes":"no");
+ printk(" - EFA Lock-Down Bit: %s\n", extp->BlkStatusRegMask&32?"yes":"no");
+ for (i=6; i<16; i++) {
+ if (extp->BlkStatusRegMask & (1<<i))
+ printk(" - Unknown Bit %X Active: yes\n",i);
+ }
+
+ printk(" Vcc Logic Supply Optimum Program/Erase Voltage: %d.%d V\n",
extp->VccOptimal >> 4, extp->VccOptimal & 0xf);
if (extp->VppOptimal)
- printk(" Vpp Programming Supply Optimum Program/Erase Voltage: %d.%d V\n",
+ printk(" Vpp Programming Supply Optimum Program/Erase Voltage: %d.%d V\n",
extp->VppOptimal >> 4, extp->VppOptimal & 0xf);
}
#endif
#ifdef CMDSET0001_DISABLE_ERASE_SUSPEND_ON_WRITE
-/* Some Intel Strata Flash prior to FPO revision C has bugs in this area */
+/* Some Intel Strata Flash prior to FPO revision C has bugs in this area */
static void fixup_intel_strataflash(struct mtd_info *mtd, void* param)
{
struct map_info *map = mtd->priv;
@@ -176,7 +185,7 @@ static void fixup_st_m28w320ct(struct mtd_info *mtd, void* param)
{
struct map_info *map = mtd->priv;
struct cfi_private *cfi = map->fldrv_priv;
-
+
cfi->cfiq->BufWriteTimeoutTyp = 0; /* Not supported */
cfi->cfiq->BufWriteTimeoutMax = 0; /* Not supported */
}
@@ -185,7 +194,7 @@ static void fixup_st_m28w320cb(struct mtd_info *mtd, void* param)
{
struct map_info *map = mtd->priv;
struct cfi_private *cfi = map->fldrv_priv;
-
+
/* Note this is done after the region info is endian swapped */
cfi->cfiq->EraseRegionInfo[1] =
(cfi->cfiq->EraseRegionInfo[1] & 0xffff0000) | 0x3e;
@@ -207,12 +216,13 @@ static void fixup_use_write_buffers(struct mtd_info *mtd, void *param)
if (cfi->cfiq->BufWriteTimeoutTyp) {
printk(KERN_INFO "Using buffer write method\n" );
mtd->write = cfi_intelext_write_buffers;
+ mtd->writev = cfi_intelext_writev;
}
}
static struct cfi_fixup cfi_fixup_table[] = {
#ifdef CMDSET0001_DISABLE_ERASE_SUSPEND_ON_WRITE
- { CFI_MFR_ANY, CFI_ID_ANY, fixup_intel_strataflash, NULL },
+ { CFI_MFR_ANY, CFI_ID_ANY, fixup_intel_strataflash, NULL },
#endif
#ifdef CMDSET0001_DISABLE_WRITE_SUSPEND
{ CFI_MFR_ANY, CFI_ID_ANY, fixup_no_write_suspend, NULL },
@@ -252,12 +262,21 @@ read_pri_intelext(struct map_info *map, __u16 adr)
if (!extp)
return NULL;
+ if (extp->MajorVersion != '1' ||
+ (extp->MinorVersion < '0' || extp->MinorVersion > '4')) {
+ printk(KERN_ERR " Unknown Intel/Sharp Extended Query "
+ "version %c.%c.\n", extp->MajorVersion,
+ extp->MinorVersion);
+ kfree(extp);
+ return NULL;
+ }
+
/* Do some byteswapping if necessary */
extp->FeatureSupport = le32_to_cpu(extp->FeatureSupport);
extp->BlkStatusRegMask = le16_to_cpu(extp->BlkStatusRegMask);
extp->ProtRegAddr = le16_to_cpu(extp->ProtRegAddr);
- if (extp->MajorVersion == '1' && extp->MinorVersion == '3') {
+ if (extp->MajorVersion == '1' && extp->MinorVersion >= '3') {
unsigned int extra_size = 0;
int nb_parts, i;
@@ -266,7 +285,10 @@ read_pri_intelext(struct map_info *map, __u16 adr)
sizeof(struct cfi_intelext_otpinfo);
/* Burst Read info */
- extra_size += 6;
+ extra_size += 2;
+ if (extp_size < sizeof(*extp) + extra_size)
+ goto need_more;
+ extra_size += extp->extra[extra_size-1];
/* Number of hardware-partitions */
extra_size += 1;
@@ -274,6 +296,10 @@ read_pri_intelext(struct map_info *map, __u16 adr)
goto need_more;
nb_parts = extp->extra[extra_size - 1];
+ /* skip the sizeof(partregion) field in CFI 1.4 */
+ if (extp->MinorVersion >= '4')
+ extra_size += 2;
+
for (i = 0; i < nb_parts; i++) {
struct cfi_intelext_regioninfo *rinfo;
rinfo = (struct cfi_intelext_regioninfo *)&extp->extra[extra_size];
@@ -285,6 +311,9 @@ read_pri_intelext(struct map_info *map, __u16 adr)
* sizeof(struct cfi_intelext_blockinfo);
}
+ if (extp->MinorVersion >= '4')
+ extra_size += sizeof(struct cfi_intelext_programming_regioninfo);
+
if (extp_size < sizeof(*extp) + extra_size) {
need_more:
extp_size = sizeof(*extp) + extra_size;
@@ -298,7 +327,7 @@ read_pri_intelext(struct map_info *map, __u16 adr)
goto again;
}
}
-
+
return extp;
}
@@ -339,7 +368,7 @@ struct mtd_info *cfi_cmdset_0001(struct map_info *map, int primary)
mtd->reboot_notifier.notifier_call = cfi_intelext_reboot;
if (cfi->cfi_mode == CFI_MODE_CFI) {
- /*
+ /*
* It's a real CFI chip, not one for which the probe
* routine faked a CFI structure. So we read the feature
* table from it.
@@ -354,14 +383,14 @@ struct mtd_info *cfi_cmdset_0001(struct map_info *map, int primary)
}
/* Install our own private info structure */
- cfi->cmdset_priv = extp;
+ cfi->cmdset_priv = extp;
cfi_fixup(mtd, cfi_fixup_table);
#ifdef DEBUG_CFI_FEATURES
/* Tell the user about it in lots of lovely detail */
cfi_tell_features(extp);
-#endif
+#endif
if(extp->SuspendCmdSupport & 1) {
printk(KERN_NOTICE "cfi_cmdset_0001: Erase suspend on write enabled\n");
@@ -379,10 +408,10 @@ struct mtd_info *cfi_cmdset_0001(struct map_info *map, int primary)
cfi->chips[i].buffer_write_time = 1<<cfi->cfiq->BufWriteTimeoutTyp;
cfi->chips[i].erase_time = 1<<cfi->cfiq->BlockEraseTimeoutTyp;
cfi->chips[i].ref_point_counter = 0;
- }
+ }
map->fldrv = &cfi_intelext_chipdrv;
-
+
return cfi_intelext_setup(mtd);
}
@@ -399,13 +428,13 @@ static struct mtd_info *cfi_intelext_setup(struct mtd_info *mtd)
mtd->size = devsize * cfi->numchips;
mtd->numeraseregions = cfi->cfiq->NumEraseRegions * cfi->numchips;
- mtd->eraseregions = kmalloc(sizeof(struct mtd_erase_region_info)
+ mtd->eraseregions = kmalloc(sizeof(struct mtd_erase_region_info)
* mtd->numeraseregions, GFP_KERNEL);
- if (!mtd->eraseregions) {
+ if (!mtd->eraseregions) {
printk(KERN_ERR "Failed to allocate memory for MTD erase region info\n");
goto setup_err;
}
-
+
for (i=0; i<cfi->cfiq->NumEraseRegions; i++) {
unsigned long ernum, ersize;
ersize = ((cfi->cfiq->EraseRegionInfo[i] >> 8) & ~0xff) * cfi->interleave;
@@ -429,7 +458,7 @@ static struct mtd_info *cfi_intelext_setup(struct mtd_info *mtd)
}
for (i=0; i<mtd->numeraseregions;i++){
- printk(KERN_DEBUG "%d: offset=0x%x,size=0x%x,blocks=%d\n",
+ printk(KERN_DEBUG "erase region %d: offset=0x%x,size=0x%x,blocks=%d\n",
i,mtd->eraseregions[i].offset,
mtd->eraseregions[i].erasesize,
mtd->eraseregions[i].numblocks);
@@ -455,8 +484,7 @@ static struct mtd_info *cfi_intelext_setup(struct mtd_info *mtd)
setup_err:
if(mtd) {
- if(mtd->eraseregions)
- kfree(mtd->eraseregions);
+ kfree(mtd->eraseregions);
kfree(mtd);
}
kfree(cfi->cmdset_priv);
@@ -481,7 +509,7 @@ static int cfi_intelext_partition_fixup(struct mtd_info *mtd,
* arrangement at this point. This can be rearranged in the future
* if someone feels motivated enough. --nico
*/
- if (extp && extp->MajorVersion == '1' && extp->MinorVersion == '3'
+ if (extp && extp->MajorVersion == '1' && extp->MinorVersion >= '3'
&& extp->FeatureSupport & (1 << 9)) {
struct cfi_private *newcfi;
struct flchip *chip;
@@ -493,12 +521,16 @@ static int cfi_intelext_partition_fixup(struct mtd_info *mtd,
sizeof(struct cfi_intelext_otpinfo);
/* Burst Read info */
- offs += 6;
+ offs += extp->extra[offs+1]+2;
/* Number of partition regions */
numregions = extp->extra[offs];
offs += 1;
+ /* skip the sizeof(partregion) field in CFI 1.4 */
+ if (extp->MinorVersion >= '4')
+ offs += 2;
+
/* Number of hardware partitions */
numparts = 0;
for (i = 0; i < numregions; i++) {
@@ -510,6 +542,20 @@ static int cfi_intelext_partition_fixup(struct mtd_info *mtd,
sizeof(struct cfi_intelext_blockinfo);
}
+ /* Programming Region info */
+ if (extp->MinorVersion >= '4') {
+ struct cfi_intelext_programming_regioninfo *prinfo;
+ prinfo = (struct cfi_intelext_programming_regioninfo *)&extp->extra[offs];
+ MTD_PROGREGION_SIZE(mtd) = cfi->interleave << prinfo->ProgRegShift;
+ MTD_PROGREGION_CTRLMODE_VALID(mtd) = cfi->interleave * prinfo->ControlValid;
+ MTD_PROGREGION_CTRLMODE_INVALID(mtd) = cfi->interleave * prinfo->ControlInvalid;
+ mtd->flags |= MTD_PROGRAM_REGIONS;
+ printk(KERN_DEBUG "%s: program region size/ctrl_valid/ctrl_inval = %d/%d/%d\n",
+ map->name, MTD_PROGREGION_SIZE(mtd),
+ MTD_PROGREGION_CTRLMODE_VALID(mtd),
+ MTD_PROGREGION_CTRLMODE_INVALID(mtd));
+ }
+
/*
* All functions below currently rely on all chips having
* the same geometry so we'll just assume that all hardware
@@ -654,8 +700,8 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr
break;
if (time_after(jiffies, timeo)) {
- printk(KERN_ERR "Waiting for chip to be ready timed out. Status %lx\n",
- status.x[0]);
+ printk(KERN_ERR "%s: Waiting for chip to be ready timed out. Status %lx\n",
+ map->name, status.x[0]);
return -EIO;
}
spin_unlock(chip->mutex);
@@ -664,7 +710,7 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr
/* Someone else might have been playing with it. */
goto retry;
}
-
+
case FL_READY:
case FL_CFI_QUERY:
case FL_JEDEC_QUERY:
@@ -702,8 +748,8 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr
map_write(map, CMD(0x70), adr);
chip->state = FL_ERASING;
chip->oldstate = FL_READY;
- printk(KERN_ERR "Chip not ready after erase "
- "suspended: status = 0x%lx\n", status.x[0]);
+ printk(KERN_ERR "%s: Chip not ready after erase "
+ "suspended: status = 0x%lx\n", map->name, status.x[0]);
return -EIO;
}
@@ -783,14 +829,14 @@ static void put_chip(struct map_info *map, struct flchip *chip, unsigned long ad
switch(chip->oldstate) {
case FL_ERASING:
chip->state = chip->oldstate;
- /* What if one interleaved chip has finished and the
+ /* What if one interleaved chip has finished and the
other hasn't? The old code would leave the finished
- one in READY mode. That's bad, and caused -EROFS
+ one in READY mode. That's bad, and caused -EROFS
errors to be returned from do_erase_oneblock because
that's the only bit it checked for at the time.
- As the state machine appears to explicitly allow
+ As the state machine appears to explicitly allow
sending the 0x70 (Read Status) command to an erasing
- chip and expecting it to be ignored, that's what we
+ chip and expecting it to be ignored, that's what we
do. */
map_write(map, CMD(0xd0), adr);
map_write(map, CMD(0x70), adr);
@@ -810,7 +856,7 @@ static void put_chip(struct map_info *map, struct flchip *chip, unsigned long ad
DISABLE_VPP(map);
break;
default:
- printk(KERN_ERR "put_chip() called with oldstate %d!!\n", chip->oldstate);
+ printk(KERN_ERR "%s: put_chip() called with oldstate %d!!\n", map->name, chip->oldstate);
}
wake_up(&chip->wq);
}
@@ -1026,8 +1072,8 @@ static int do_point_onechip (struct map_info *map, struct flchip *chip, loff_t a
adr += chip->start;
- /* Ensure cmd read/writes are aligned. */
- cmd_addr = adr & ~(map_bankwidth(map)-1);
+ /* Ensure cmd read/writes are aligned. */
+ cmd_addr = adr & ~(map_bankwidth(map)-1);
spin_lock(chip->mutex);
@@ -1055,7 +1101,7 @@ static int cfi_intelext_point (struct mtd_info *mtd, loff_t from, size_t len, si
if (!map->virt || (from + len > mtd->size))
return -EINVAL;
-
+
*mtdbuf = (void *)map->virt + from;
*retlen = 0;
@@ -1082,7 +1128,7 @@ static int cfi_intelext_point (struct mtd_info *mtd, loff_t from, size_t len, si
*retlen += thislen;
len -= thislen;
-
+
ofs = 0;
chipnum++;
}
@@ -1121,7 +1167,7 @@ static void cfi_intelext_unpoint (struct mtd_info *mtd, u_char *addr, loff_t fro
if(chip->ref_point_counter == 0)
chip->state = FL_READY;
} else
- printk(KERN_ERR "Warning: unpoint called on non pointed region\n"); /* Should this give an error? */
+ printk(KERN_ERR "%s: Warning: unpoint called on non pointed region\n", map->name); /* Should this give an error? */
put_chip(map, chip, chip->start);
spin_unlock(chip->mutex);
@@ -1140,8 +1186,8 @@ static inline int do_read_onechip(struct map_info *map, struct flchip *chip, lof
adr += chip->start;
- /* Ensure cmd read/writes are aligned. */
- cmd_addr = adr & ~(map_bankwidth(map)-1);
+ /* Ensure cmd read/writes are aligned. */
+ cmd_addr = adr & ~(map_bankwidth(map)-1);
spin_lock(chip->mutex);
ret = get_chip(map, chip, cmd_addr, FL_READY);
@@ -1196,7 +1242,7 @@ static int cfi_intelext_read (struct mtd_info *mtd, loff_t from, size_t len, siz
*retlen += thislen;
len -= thislen;
buf += thislen;
-
+
ofs = 0;
chipnum++;
}
@@ -1213,12 +1259,17 @@ static int __xipram do_write_oneword(struct map_info *map, struct flchip *chip,
adr += chip->start;
- /* Let's determine this according to the interleave only once */
+ /* Let's determine those according to the interleave only once */
status_OK = CMD(0x80);
switch (mode) {
- case FL_WRITING: write_cmd = CMD(0x40); break;
- case FL_OTP_WRITE: write_cmd = CMD(0xc0); break;
- default: return -EINVAL;
+ case FL_WRITING:
+ write_cmd = (cfi->cfiq->P_ID != 0x0200) ? CMD(0x40) : CMD(0x41);
+ break;
+ case FL_OTP_WRITE:
+ write_cmd = CMD(0xc0);
+ break;
+ default:
+ return -EINVAL;
}
spin_lock(chip->mutex);
@@ -1259,12 +1310,13 @@ static int __xipram do_write_oneword(struct map_info *map, struct flchip *chip,
status = map_read(map, adr);
if (map_word_andequal(map, status, status_OK, status_OK))
break;
-
+
/* OK Still waiting */
if (time_after(jiffies, timeo)) {
+ map_write(map, CMD(0x70), adr);
chip->state = FL_STATUS;
xip_enable(map, chip, adr);
- printk(KERN_ERR "waiting for chip to be ready timed out in word write\n");
+ printk(KERN_ERR "%s: word write error (status timeout)\n", map->name);
ret = -EIO;
goto out;
}
@@ -1276,27 +1328,39 @@ static int __xipram do_write_oneword(struct map_info *map, struct flchip *chip,
if (!z) {
chip->word_write_time--;
if (!chip->word_write_time)
- chip->word_write_time++;
+ chip->word_write_time = 1;
}
- if (z > 1)
+ if (z > 1)
chip->word_write_time++;
/* Done and happy. */
chip->state = FL_STATUS;
- /* check for lock bit */
- if (map_word_bitsset(map, status, CMD(0x02))) {
- /* clear status */
+ /* check for errors */
+ if (map_word_bitsset(map, status, CMD(0x1a))) {
+ unsigned long chipstatus = MERGESTATUS(status);
+
+ /* reset status */
map_write(map, CMD(0x50), adr);
- /* put back into read status register mode */
map_write(map, CMD(0x70), adr);
- ret = -EROFS;
+ xip_enable(map, chip, adr);
+
+ if (chipstatus & 0x02) {
+ ret = -EROFS;
+ } else if (chipstatus & 0x08) {
+ printk(KERN_ERR "%s: word write error (bad VPP)\n", map->name);
+ ret = -EIO;
+ } else {
+ printk(KERN_ERR "%s: word write error (status 0x%lx)\n", map->name, chipstatus);
+ ret = -EINVAL;
+ }
+
+ goto out;
}
xip_enable(map, chip, adr);
out: put_chip(map, chip, adr);
spin_unlock(chip->mutex);
-
return ret;
}
@@ -1329,7 +1393,7 @@ static int cfi_intelext_write_words (struct mtd_info *mtd, loff_t to , size_t le
ret = do_write_oneword(map, &cfi->chips[chipnum],
bus_ofs, datum, FL_WRITING);
- if (ret)
+ if (ret)
return ret;
len -= n;
@@ -1338,13 +1402,13 @@ static int cfi_intelext_write_words (struct mtd_info *mtd, loff_t to , size_t le
(*retlen) += n;
if (ofs >> cfi->chipshift) {
- chipnum ++;
+ chipnum ++;
ofs = 0;
if (chipnum == cfi->numchips)
return 0;
}
}
-
+
while(len >= map_bankwidth(map)) {
map_word datum = map_word_load(map, buf);
@@ -1359,7 +1423,7 @@ static int cfi_intelext_write_words (struct mtd_info *mtd, loff_t to , size_t le
len -= map_bankwidth(map);
if (ofs >> cfi->chipshift) {
- chipnum ++;
+ chipnum ++;
ofs = 0;
if (chipnum == cfi->numchips)
return 0;
@@ -1374,9 +1438,9 @@ static int cfi_intelext_write_words (struct mtd_info *mtd, loff_t to , size_t le
ret = do_write_oneword(map, &cfi->chips[chipnum],
ofs, datum, FL_WRITING);
- if (ret)
+ if (ret)
return ret;
-
+
(*retlen) += len;
}
@@ -1384,20 +1448,24 @@ static int cfi_intelext_write_words (struct mtd_info *mtd, loff_t to , size_t le
}
-static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
- unsigned long adr, const u_char *buf, int len)
+static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
+ unsigned long adr, const struct kvec **pvec,
+ unsigned long *pvec_seek, int len)
{
struct cfi_private *cfi = map->fldrv_priv;
- map_word status, status_OK;
+ map_word status, status_OK, write_cmd, datum;
unsigned long cmd_adr, timeo;
- int wbufsize, z, ret=0, bytes, words;
+ int wbufsize, z, ret=0, word_gap, words;
+ const struct kvec *vec;
+ unsigned long vec_seek;
wbufsize = cfi_interleave(cfi) << cfi->cfiq->MaxBufWriteSize;
adr += chip->start;
cmd_adr = adr & ~(wbufsize-1);
-
+
/* Let's determine this according to the interleave only once */
status_OK = CMD(0x80);
+ write_cmd = (cfi->cfiq->P_ID != 0x0200) ? CMD(0xe8) : CMD(0xe9);
spin_lock(chip->mutex);
ret = get_chip(map, chip, cmd_adr, FL_WRITING);
@@ -1411,7 +1479,7 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
xip_disable(map, chip, cmd_adr);
/* §4.8 of the 28FxxxJ3A datasheet says "Any time SR.4 and/or SR.5 is set
- [...], the device will not accept any more Write to Buffer commands".
+ [...], the device will not accept any more Write to Buffer commands".
So we must check here and reset those bits if they're set. Otherwise
we're just pissing in the wind */
if (chip->state != FL_STATUS)
@@ -1429,7 +1497,7 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
z = 0;
for (;;) {
- map_write(map, CMD(0xe8), cmd_adr);
+ map_write(map, write_cmd, cmd_adr);
status = map_read(map, cmd_adr);
if (map_word_andequal(map, status, status_OK, status_OK))
@@ -1447,41 +1515,66 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
map_write(map, CMD(0x50), cmd_adr);
map_write(map, CMD(0x70), cmd_adr);
xip_enable(map, chip, cmd_adr);
- printk(KERN_ERR "Chip not ready for buffer write. status = %lx, Xstatus = %lx\n",
- status.x[0], Xstatus.x[0]);
+ printk(KERN_ERR "%s: Chip not ready for buffer write. status = %lx, Xstatus = %lx\n",
+ map->name, status.x[0], Xstatus.x[0]);
ret = -EIO;
goto out;
}
}
+ /* Figure out the number of words to write */
+ word_gap = (-adr & (map_bankwidth(map)-1));
+ words = (len - word_gap + map_bankwidth(map) - 1) / map_bankwidth(map);
+ if (!word_gap) {
+ words--;
+ } else {
+ word_gap = map_bankwidth(map) - word_gap;
+ adr -= word_gap;
+ datum = map_word_ff(map);
+ }
+
/* Write length of data to come */
- bytes = len & (map_bankwidth(map)-1);
- words = len / map_bankwidth(map);
- map_write(map, CMD(words - !bytes), cmd_adr );
+ map_write(map, CMD(words), cmd_adr );
/* Write data */
- z = 0;
- while(z < words * map_bankwidth(map)) {
- map_word datum = map_word_load(map, buf);
- map_write(map, datum, adr+z);
+ vec = *pvec;
+ vec_seek = *pvec_seek;
+ do {
+ int n = map_bankwidth(map) - word_gap;
+ if (n > vec->iov_len - vec_seek)
+ n = vec->iov_len - vec_seek;
+ if (n > len)
+ n = len;
- z += map_bankwidth(map);
- buf += map_bankwidth(map);
- }
+ if (!word_gap && len < map_bankwidth(map))
+ datum = map_word_ff(map);
- if (bytes) {
- map_word datum;
+ datum = map_word_load_partial(map, datum,
+ vec->iov_base + vec_seek,
+ word_gap, n);
- datum = map_word_ff(map);
- datum = map_word_load_partial(map, datum, buf, 0, bytes);
- map_write(map, datum, adr+z);
- }
+ len -= n;
+ word_gap += n;
+ if (!len || word_gap == map_bankwidth(map)) {
+ map_write(map, datum, adr);
+ adr += map_bankwidth(map);
+ word_gap = 0;
+ }
+
+ vec_seek += n;
+ if (vec_seek == vec->iov_len) {
+ vec++;
+ vec_seek = 0;
+ }
+ } while (len);
+ *pvec = vec;
+ *pvec_seek = vec_seek;
/* GO GO GO */
map_write(map, CMD(0xd0), cmd_adr);
chip->state = FL_WRITING;
- INVALIDATE_CACHE_UDELAY(map, chip,
+ INVALIDATE_CACHE_UDELAY(map, chip,
cmd_adr, len,
chip->buffer_write_time);
@@ -1507,13 +1600,14 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
/* OK Still waiting */
if (time_after(jiffies, timeo)) {
+ map_write(map, CMD(0x70), cmd_adr);
chip->state = FL_STATUS;
xip_enable(map, chip, cmd_adr);
- printk(KERN_ERR "waiting for chip to be ready timed out in bufwrite\n");
+ printk(KERN_ERR "%s: buffer write error (status timeout)\n", map->name);
ret = -EIO;
goto out;
}
-
+
/* Latency issues. Drop the lock, wait a while and retry */
z++;
UDELAY(map, chip, cmd_adr, 1);
@@ -1521,21 +1615,34 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
if (!z) {
chip->buffer_write_time--;
if (!chip->buffer_write_time)
- chip->buffer_write_time++;
+ chip->buffer_write_time = 1;
}
- if (z > 1)
+ if (z > 1)
chip->buffer_write_time++;
/* Done and happy. */
chip->state = FL_STATUS;
- /* check for lock bit */
- if (map_word_bitsset(map, status, CMD(0x02))) {
- /* clear status */
+ /* check for errors */
+ if (map_word_bitsset(map, status, CMD(0x1a))) {
+ unsigned long chipstatus = MERGESTATUS(status);
+
+ /* reset status */
map_write(map, CMD(0x50), cmd_adr);
- /* put back into read status register mode */
- map_write(map, CMD(0x70), adr);
- ret = -EROFS;
+ map_write(map, CMD(0x70), cmd_adr);
+ xip_enable(map, chip, cmd_adr);
+
+ if (chipstatus & 0x02) {
+ ret = -EROFS;
+ } else if (chipstatus & 0x08) {
+ printk(KERN_ERR "%s: buffer write error (bad VPP)\n", map->name);
+ ret = -EIO;
+ } else {
+ printk(KERN_ERR "%s: buffer write error (status 0x%lx)\n", map->name, chipstatus);
+ ret = -EINVAL;
+ }
+
+ goto out;
}
xip_enable(map, chip, cmd_adr);
@@ -1544,70 +1651,65 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
return ret;
}
-static int cfi_intelext_write_buffers (struct mtd_info *mtd, loff_t to,
- size_t len, size_t *retlen, const u_char *buf)
+static int cfi_intelext_writev (struct mtd_info *mtd, const struct kvec *vecs,
+ unsigned long count, loff_t to, size_t *retlen)
{
struct map_info *map = mtd->priv;
struct cfi_private *cfi = map->fldrv_priv;
int wbufsize = cfi_interleave(cfi) << cfi->cfiq->MaxBufWriteSize;
int ret = 0;
int chipnum;
- unsigned long ofs;
+ unsigned long ofs, vec_seek, i;
+ size_t len = 0;
+
+ for (i = 0; i < count; i++)
+ len += vecs[i].iov_len;
*retlen = 0;
if (!len)
return 0;
chipnum = to >> cfi->chipshift;
- ofs = to - (chipnum << cfi->chipshift);
-
- /* If it's not bus-aligned, do the first word write */
- if (ofs & (map_bankwidth(map)-1)) {
- size_t local_len = (-ofs)&(map_bankwidth(map)-1);
- if (local_len > len)
- local_len = len;
- ret = cfi_intelext_write_words(mtd, to, local_len,
- retlen, buf);
- if (ret)
- return ret;
- ofs += local_len;
- buf += local_len;
- len -= local_len;
-
- if (ofs >> cfi->chipshift) {
- chipnum ++;
- ofs = 0;
- if (chipnum == cfi->numchips)
- return 0;
- }
- }
+ ofs = to - (chipnum << cfi->chipshift);
+ vec_seek = 0;
- while(len) {
+ do {
/* We must not cross write block boundaries */
int size = wbufsize - (ofs & (wbufsize-1));
if (size > len)
size = len;
- ret = do_write_buffer(map, &cfi->chips[chipnum],
- ofs, buf, size);
+ ret = do_write_buffer(map, &cfi->chips[chipnum],
+ ofs, &vecs, &vec_seek, size);
if (ret)
return ret;
ofs += size;
- buf += size;
(*retlen) += size;
len -= size;
if (ofs >> cfi->chipshift) {
- chipnum ++;
+ chipnum ++;
ofs = 0;
if (chipnum == cfi->numchips)
return 0;
}
- }
+ } while (len);
+
return 0;
}
+static int cfi_intelext_write_buffers (struct mtd_info *mtd, loff_t to,
+ size_t len, size_t *retlen, const u_char *buf)
+{
+ struct kvec vec;
+
+ vec.iov_base = (void *) buf;
+ vec.iov_len = len;
+
+ return cfi_intelext_writev(mtd, &vec, 1, to, retlen);
+}
+
static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip,
unsigned long adr, int len, void *thunk)
{
@@ -1673,23 +1775,17 @@ static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip,
status = map_read(map, adr);
if (map_word_andequal(map, status, status_OK, status_OK))
break;
-
+
/* OK Still waiting */
if (time_after(jiffies, timeo)) {
- map_word Xstatus;
map_write(map, CMD(0x70), adr);
chip->state = FL_STATUS;
- Xstatus = map_read(map, adr);
- /* Clear status bits */
- map_write(map, CMD(0x50), adr);
- map_write(map, CMD(0x70), adr);
xip_enable(map, chip, adr);
- printk(KERN_ERR "waiting for erase at %08lx to complete timed out. status = %lx, Xstatus = %lx.\n",
- adr, status.x[0], Xstatus.x[0]);
+ printk(KERN_ERR "%s: block erase error: (status timeout)\n", map->name);
ret = -EIO;
goto out;
}
-
+
/* Latency issues. Drop the lock, wait a while and retry */
UDELAY(map, chip, adr, 1000000/HZ);
}
@@ -1699,43 +1795,40 @@ static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip,
chip->state = FL_STATUS;
status = map_read(map, adr);
- /* check for lock bit */
+ /* check for errors */
if (map_word_bitsset(map, status, CMD(0x3a))) {
- unsigned long chipstatus;
+ unsigned long chipstatus = MERGESTATUS(status);
/* Reset the error bits */
map_write(map, CMD(0x50), adr);
map_write(map, CMD(0x70), adr);
xip_enable(map, chip, adr);
- chipstatus = MERGESTATUS(status);
-
if ((chipstatus & 0x30) == 0x30) {
- printk(KERN_NOTICE "Chip reports improper command sequence: status 0x%lx\n", chipstatus);
- ret = -EIO;
+ printk(KERN_ERR "%s: block erase error: (bad command sequence, status 0x%lx)\n", map->name, chipstatus);
+ ret = -EINVAL;
} else if (chipstatus & 0x02) {
/* Protection bit set */
ret = -EROFS;
} else if (chipstatus & 0x8) {
/* Voltage */
- printk(KERN_WARNING "Chip reports voltage low on erase: status 0x%lx\n", chipstatus);
+ printk(KERN_ERR "%s: block erase error: (bad VPP)\n", map->name);
ret = -EIO;
- } else if (chipstatus & 0x20) {
- if (retries--) {
- printk(KERN_DEBUG "Chip erase failed at 0x%08lx: status 0x%lx. Retrying...\n", adr, chipstatus);
- timeo = jiffies + HZ;
- put_chip(map, chip, adr);
- spin_unlock(chip->mutex);
- goto retry;
- }
- printk(KERN_DEBUG "Chip erase failed at 0x%08lx: status 0x%lx\n", adr, chipstatus);
+ } else if (chipstatus & 0x20 && retries--) {
+ printk(KERN_DEBUG "block erase failed at 0x%08lx: status 0x%lx. Retrying...\n", adr, chipstatus);
+ timeo = jiffies + HZ;
+ put_chip(map, chip, adr);
+ spin_unlock(chip->mutex);
+ goto retry;
+ } else {
+ printk(KERN_ERR "%s: block erase failed at 0x%08lx (status 0x%lx)\n", map->name, adr, chipstatus);
ret = -EIO;
}
- } else {
- xip_enable(map, chip, adr);
- ret = 0;
+
+ goto out;
}
+ xip_enable(map, chip, adr);
out: put_chip(map, chip, adr);
spin_unlock(chip->mutex);
return ret;
@@ -1755,7 +1848,7 @@ int cfi_intelext_erase_varsize(struct mtd_info *mtd, struct erase_info *instr)
instr->state = MTD_ERASE_DONE;
mtd_erase_callback(instr);
-
+
return 0;
}
@@ -1776,7 +1869,7 @@ static void cfi_intelext_sync (struct mtd_info *mtd)
if (!ret) {
chip->oldstate = chip->state;
chip->state = FL_SYNCING;
- /* No need to wake_up() on this state change -
+ /* No need to wake_up() on this state change -
* as the whole point is that nobody can do anything
* with the chip now anyway.
*/
@@ -1790,7 +1883,7 @@ static void cfi_intelext_sync (struct mtd_info *mtd)
chip = &cfi->chips[i];
spin_lock(chip->mutex);
-
+
if (chip->state == FL_SYNCING) {
chip->state = chip->oldstate;
chip->oldstate = FL_READY;
@@ -1847,7 +1940,7 @@ static int __xipram do_xxlock_oneblock(struct map_info *map, struct flchip *chip
ENABLE_VPP(map);
xip_disable(map, chip, adr);
-
+
map_write(map, CMD(0x60), adr);
if (thunk == DO_XXLOCK_ONEBLOCK_LOCK) {
map_write(map, CMD(0x01), adr);
@@ -1875,25 +1968,22 @@ static int __xipram do_xxlock_oneblock(struct map_info *map, struct flchip *chip
status = map_read(map, adr);
if (map_word_andequal(map, status, status_OK, status_OK))
break;
-
+
/* OK Still waiting */
if (time_after(jiffies, timeo)) {
- map_word Xstatus;
map_write(map, CMD(0x70), adr);
chip->state = FL_STATUS;
- Xstatus = map_read(map, adr);
xip_enable(map, chip, adr);
- printk(KERN_ERR "waiting for unlock to complete timed out. status = %lx, Xstatus = %lx.\n",
- status.x[0], Xstatus.x[0]);
+ printk(KERN_ERR "%s: block unlock error: (status timeout)\n", map->name);
put_chip(map, chip, adr);
spin_unlock(chip->mutex);
return -EIO;
}
-
+
/* Latency issues. Drop the lock, wait a while and retry */
UDELAY(map, chip, adr, 1);
}
-
+
/* Done and happy. */
chip->state = FL_STATUS;
xip_enable(map, chip, adr);
@@ -1913,9 +2003,9 @@ static int cfi_intelext_lock(struct mtd_info *mtd, loff_t ofs, size_t len)
ofs, len, 0);
#endif
- ret = cfi_varsize_frob(mtd, do_xxlock_oneblock,
+ ret = cfi_varsize_frob(mtd, do_xxlock_oneblock,
ofs, len, DO_XXLOCK_ONEBLOCK_LOCK);
-
+
#ifdef DEBUG_LOCK_BITS
printk(KERN_DEBUG "%s: lock status after, ret=%d\n",
__FUNCTION__, ret);
@@ -1939,20 +2029,20 @@ static int cfi_intelext_unlock(struct mtd_info *mtd, loff_t ofs, size_t len)
ret = cfi_varsize_frob(mtd, do_xxlock_oneblock,
ofs, len, DO_XXLOCK_ONEBLOCK_UNLOCK);
-
+
#ifdef DEBUG_LOCK_BITS
printk(KERN_DEBUG "%s: lock status after, ret=%d\n",
__FUNCTION__, ret);
- cfi_varsize_frob(mtd, do_printlockstatus_oneblock,
+ cfi_varsize_frob(mtd, do_printlockstatus_oneblock,
ofs, len, 0);
#endif
-
+
return ret;
}
#ifdef CONFIG_MTD_OTP
-typedef int (*otp_op_t)(struct map_info *map, struct flchip *chip,
+typedef int (*otp_op_t)(struct map_info *map, struct flchip *chip,
u_long data_offset, u_char *buf, u_int size,
u_long prot_offset, u_int groupno, u_int groupsize);
@@ -2003,7 +2093,7 @@ do_otp_write(struct map_info *map, struct flchip *chip, u_long offset,
datum = map_word_load_partial(map, datum, buf, gap, n);
ret = do_write_oneword(map, chip, bus_ofs, datum, FL_OTP_WRITE);
- if (ret)
+ if (ret)
return ret;
offset += n;
@@ -2196,7 +2286,7 @@ static int cfi_intelext_lock_user_prot_reg(struct mtd_info *mtd,
NULL, do_otp_lock, 1);
}
-static int cfi_intelext_get_fact_prot_info(struct mtd_info *mtd,
+static int cfi_intelext_get_fact_prot_info(struct mtd_info *mtd,
struct otp_info *buf, size_t len)
{
size_t retlen;
@@ -2239,7 +2329,7 @@ static int cfi_intelext_suspend(struct mtd_info *mtd)
if (chip->oldstate == FL_READY) {
chip->oldstate = chip->state;
chip->state = FL_PM_SUSPENDED;
- /* No need to wake_up() on this state change -
+ /* No need to wake_up() on this state change -
* as the whole point is that nobody can do anything
* with the chip now anyway.
*/
@@ -2267,9 +2357,9 @@ static int cfi_intelext_suspend(struct mtd_info *mtd)
if (ret) {
for (i--; i >=0; i--) {
chip = &cfi->chips[i];
-
+
spin_lock(chip->mutex);
-
+
if (chip->state == FL_PM_SUSPENDED) {
/* No need to force it into a known state here,
because we're returning failure, and it didn't
@@ -2280,8 +2370,8 @@ static int cfi_intelext_suspend(struct mtd_info *mtd)
}
spin_unlock(chip->mutex);
}
- }
-
+ }
+
return ret;
}
@@ -2293,11 +2383,11 @@ static void cfi_intelext_resume(struct mtd_info *mtd)
struct flchip *chip;
for (i=0; i<cfi->numchips; i++) {
-
+
chip = &cfi->chips[i];
spin_lock(chip->mutex);
-
+
/* Go to known state. Chip may have been power cycled */
if (chip->state == FL_PM_SUSPENDED) {
map_write(map, CMD(0xFF), cfi->chips[i].start);
@@ -2319,7 +2409,7 @@ static int cfi_intelext_reset(struct mtd_info *mtd)
struct flchip *chip = &cfi->chips[i];
/* force the completion of any ongoing operation
- and switch to array mode so any bootloader in
+ and switch to array mode so any bootloader in
flash is accessible for soft reboot. */
spin_lock(chip->mutex);
ret = get_chip(map, chip, chip->start, FL_SYNCING);
@@ -2356,20 +2446,23 @@ static void cfi_intelext_destroy(struct mtd_info *mtd)
kfree(mtd->eraseregions);
}
-static char im_name_1[]="cfi_cmdset_0001";
-static char im_name_3[]="cfi_cmdset_0003";
+static char im_name_0001[] = "cfi_cmdset_0001";
+static char im_name_0003[] = "cfi_cmdset_0003";
+static char im_name_0200[] = "cfi_cmdset_0200";
static int __init cfi_intelext_init(void)
{
- inter_module_register(im_name_1, THIS_MODULE, &cfi_cmdset_0001);
- inter_module_register(im_name_3, THIS_MODULE, &cfi_cmdset_0001);
+ inter_module_register(im_name_0001, THIS_MODULE, &cfi_cmdset_0001);
+ inter_module_register(im_name_0003, THIS_MODULE, &cfi_cmdset_0001);
+ inter_module_register(im_name_0200, THIS_MODULE, &cfi_cmdset_0001);
return 0;
}
static void __exit cfi_intelext_exit(void)
{
- inter_module_unregister(im_name_1);
- inter_module_unregister(im_name_3);
+ inter_module_unregister(im_name_0001);
+ inter_module_unregister(im_name_0003);
+ inter_module_unregister(im_name_0200);
}
module_init(cfi_intelext_init);
diff --git a/drivers/mtd/chips/cfi_cmdset_0002.c b/drivers/mtd/chips/cfi_cmdset_0002.c
index 8505f118f2db..aed10bd5c3c3 100644
--- a/drivers/mtd/chips/cfi_cmdset_0002.c
+++ b/drivers/mtd/chips/cfi_cmdset_0002.c
@@ -10,14 +10,14 @@
*
* 4_by_16 work by Carolyn J. Smith
*
- * XIP support hooks by Vitaly Wool (based on code for Intel flash
+ * XIP support hooks by Vitaly Wool (based on code for Intel flash
* by Nicolas Pitre)
- *
+ *
* Occasionally maintained by Thayne Harbaugh tharbaugh at lnxi dot com
*
* This code is GPL
*
- * $Id: cfi_cmdset_0002.c,v 1.118 2005/07/04 22:34:29 gleixner Exp $
+ * $Id: cfi_cmdset_0002.c,v 1.122 2005/11/07 11:14:22 gleixner Exp $
*
*/
@@ -93,7 +93,7 @@ static void cfi_tell_features(struct cfi_pri_amdstd *extp)
};
printk(" Silicon revision: %d\n", extp->SiliconRevision >> 1);
- printk(" Address sensitive unlock: %s\n",
+ printk(" Address sensitive unlock: %s\n",
(extp->SiliconRevision & 1) ? "Not required" : "Required");
if (extp->EraseSuspend < ARRAY_SIZE(erase_suspend))
@@ -118,9 +118,9 @@ static void cfi_tell_features(struct cfi_pri_amdstd *extp)
else
printk(" Page mode: %d word page\n", extp->PageMode << 2);
- printk(" Vpp Supply Minimum Program/Erase Voltage: %d.%d V\n",
+ printk(" Vpp Supply Minimum Program/Erase Voltage: %d.%d V\n",
extp->VppMin >> 4, extp->VppMin & 0xf);
- printk(" Vpp Supply Maximum Program/Erase Voltage: %d.%d V\n",
+ printk(" Vpp Supply Maximum Program/Erase Voltage: %d.%d V\n",
extp->VppMax >> 4, extp->VppMax & 0xf);
if (extp->TopBottom < ARRAY_SIZE(top_bottom))
@@ -177,7 +177,7 @@ static void fixup_use_erase_chip(struct mtd_info *mtd, void *param)
((cfi->cfiq->EraseRegionInfo[0] & 0xffff) == 0)) {
mtd->erase = cfi_amdstd_erase_chip;
}
-
+
}
static struct cfi_fixup cfi_fixup_table[] = {
@@ -239,7 +239,7 @@ struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary)
if (cfi->cfi_mode==CFI_MODE_CFI){
unsigned char bootloc;
- /*
+ /*
* It's a real CFI chip, not one for which the probe
* routine faked a CFI structure. So we read the feature
* table from it.
@@ -253,8 +253,18 @@ struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary)
return NULL;
}
+ if (extp->MajorVersion != '1' ||
+ (extp->MinorVersion < '0' || extp->MinorVersion > '4')) {
+ printk(KERN_ERR " Unknown Amd/Fujitsu Extended Query "
+ "version %c.%c.\n", extp->MajorVersion,
+ extp->MinorVersion);
+ kfree(extp);
+ kfree(mtd);
+ return NULL;
+ }
+
/* Install our own private info structure */
- cfi->cmdset_priv = extp;
+ cfi->cmdset_priv = extp;
/* Apply cfi device specific fixups */
cfi_fixup(mtd, cfi_fixup_table);
@@ -262,7 +272,7 @@ struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary)
#ifdef DEBUG_CFI_FEATURES
/* Tell the user about it in lots of lovely detail */
cfi_tell_features(extp);
-#endif
+#endif
bootloc = extp->TopBottom;
if ((bootloc != 2) && (bootloc != 3)) {
@@ -273,11 +283,11 @@ struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary)
if (bootloc == 3 && cfi->cfiq->NumEraseRegions > 1) {
printk(KERN_WARNING "%s: Swapping erase regions for broken CFI table.\n", map->name);
-
+
for (i=0; i<cfi->cfiq->NumEraseRegions / 2; i++) {
int j = (cfi->cfiq->NumEraseRegions-1)-i;
__u32 swap;
-
+
swap = cfi->cfiq->EraseRegionInfo[i];
cfi->cfiq->EraseRegionInfo[i] = cfi->cfiq->EraseRegionInfo[j];
cfi->cfiq->EraseRegionInfo[j] = swap;
@@ -288,11 +298,11 @@ struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary)
cfi->addr_unlock2 = 0x2aa;
/* Modify the unlock address if we are in compatibility mode */
if ( /* x16 in x8 mode */
- ((cfi->device_type == CFI_DEVICETYPE_X8) &&
+ ((cfi->device_type == CFI_DEVICETYPE_X8) &&
(cfi->cfiq->InterfaceDesc == 2)) ||
/* x32 in x16 mode */
((cfi->device_type == CFI_DEVICETYPE_X16) &&
- (cfi->cfiq->InterfaceDesc == 4)))
+ (cfi->cfiq->InterfaceDesc == 4)))
{
cfi->addr_unlock1 = 0xaaa;
cfi->addr_unlock2 = 0x555;
@@ -310,10 +320,10 @@ struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary)
cfi->chips[i].word_write_time = 1<<cfi->cfiq->WordWriteTimeoutTyp;
cfi->chips[i].buffer_write_time = 1<<cfi->cfiq->BufWriteTimeoutTyp;
cfi->chips[i].erase_time = 1<<cfi->cfiq->BlockEraseTimeoutTyp;
- }
-
+ }
+
map->fldrv = &cfi_amdstd_chipdrv;
-
+
return cfi_amdstd_setup(mtd);
}
@@ -326,24 +336,24 @@ static struct mtd_info *cfi_amdstd_setup(struct mtd_info *mtd)
unsigned long offset = 0;
int i,j;
- printk(KERN_NOTICE "number of %s chips: %d\n",
+ printk(KERN_NOTICE "number of %s chips: %d\n",
(cfi->cfi_mode == CFI_MODE_CFI)?"CFI":"JEDEC",cfi->numchips);
- /* Select the correct geometry setup */
+ /* Select the correct geometry setup */
mtd->size = devsize * cfi->numchips;
mtd->numeraseregions = cfi->cfiq->NumEraseRegions * cfi->numchips;
mtd->eraseregions = kmalloc(sizeof(struct mtd_erase_region_info)
* mtd->numeraseregions, GFP_KERNEL);
- if (!mtd->eraseregions) {
+ if (!mtd->eraseregions) {
printk(KERN_WARNING "Failed to allocate memory for MTD erase region info\n");
goto setup_err;
}
-
+
for (i=0; i<cfi->cfiq->NumEraseRegions; i++) {
unsigned long ernum, ersize;
ersize = ((cfi->cfiq->EraseRegionInfo[i] >> 8) & ~0xff) * cfi->interleave;
ernum = (cfi->cfiq->EraseRegionInfo[i] & 0xffff) + 1;
-
+
if (mtd->erasesize < ersize) {
mtd->erasesize = ersize;
}
@@ -378,8 +388,7 @@ static struct mtd_info *cfi_amdstd_setup(struct mtd_info *mtd)
setup_err:
if(mtd) {
- if(mtd->eraseregions)
- kfree(mtd->eraseregions);
+ kfree(mtd->eraseregions);
kfree(mtd);
}
kfree(cfi->cmdset_priv);
@@ -430,7 +439,7 @@ static int __xipram chip_good(struct map_info *map, unsigned long addr, map_word
oldd = map_read(map, addr);
curd = map_read(map, addr);
- return map_word_equal(map, oldd, curd) &&
+ return map_word_equal(map, oldd, curd) &&
map_word_equal(map, curd, expected);
}
@@ -462,7 +471,7 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr
/* Someone else might have been playing with it. */
goto retry;
}
-
+
case FL_READY:
case FL_CFI_QUERY:
case FL_JEDEC_QUERY:
@@ -505,7 +514,7 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr
printk(KERN_ERR "MTD %s(): chip not ready after erase suspend\n", __func__);
return -EIO;
}
-
+
spin_unlock(chip->mutex);
cfi_udelay(1);
spin_lock(chip->mutex);
@@ -608,7 +617,7 @@ static void __xipram xip_enable(struct map_info *map, struct flchip *chip,
* When a delay is required for the flash operation to complete, the
* xip_udelay() function is polling for both the given timeout and pending
* (but still masked) hardware interrupts. Whenever there is an interrupt
- * pending then the flash erase operation is suspended, array mode restored
+ * pending then the flash erase operation is suspended, array mode restored
* and interrupts unmasked. Task scheduling might also happen at that
* point. The CPU eventually returns from the interrupt or the call to
* schedule() and the suspended flash operation is resumed for the remaining
@@ -632,9 +641,9 @@ static void __xipram xip_udelay(struct map_info *map, struct flchip *chip,
((chip->state == FL_ERASING && (extp->EraseSuspend & 2))) &&
(cfi_interleave_is_1(cfi) || chip->oldstate == FL_READY)) {
/*
- * Let's suspend the erase operation when supported.
- * Note that we currently don't try to suspend
- * interleaved chips if there is already another
+ * Let's suspend the erase operation when supported.
+ * Note that we currently don't try to suspend
+ * interleaved chips if there is already another
* operation suspended (imagine what happens
* when one chip was already done with the current
* operation while another chip suspended it, then
@@ -770,8 +779,8 @@ static inline int do_read_onechip(struct map_info *map, struct flchip *chip, lof
adr += chip->start;
- /* Ensure cmd read/writes are aligned. */
- cmd_addr = adr & ~(map_bankwidth(map)-1);
+ /* Ensure cmd read/writes are aligned. */
+ cmd_addr = adr & ~(map_bankwidth(map)-1);
spin_lock(chip->mutex);
ret = get_chip(map, chip, cmd_addr, FL_READY);
@@ -851,7 +860,7 @@ static inline int do_read_secsi_onechip(struct map_info *map, struct flchip *chi
#endif
set_current_state(TASK_UNINTERRUPTIBLE);
add_wait_queue(&chip->wq, &wait);
-
+
spin_unlock(chip->mutex);
schedule();
@@ -863,7 +872,7 @@ static inline int do_read_secsi_onechip(struct map_info *map, struct flchip *chi
timeo = jiffies + HZ;
goto retry;
- }
+ }
adr += chip->start;
@@ -872,14 +881,14 @@ static inline int do_read_secsi_onechip(struct map_info *map, struct flchip *chi
cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, cfi->device_type, NULL);
cfi_send_gen_cmd(0x88, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
-
+
map_copy_from(map, buf, adr, len);
cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, cfi->device_type, NULL);
cfi_send_gen_cmd(0x90, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
cfi_send_gen_cmd(0x00, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
-
+
wake_up(&chip->wq);
spin_unlock(chip->mutex);
@@ -988,7 +997,7 @@ static int __xipram do_write_oneword(struct map_info *map, struct flchip *chip,
chip->word_write_time);
/* See comment above for timeout value. */
- timeo = jiffies + uWriteTimeout;
+ timeo = jiffies + uWriteTimeout;
for (;;) {
if (chip->state != FL_WRITING) {
/* Someone's suspended the write. Sleep */
@@ -1004,16 +1013,16 @@ static int __xipram do_write_oneword(struct map_info *map, struct flchip *chip,
continue;
}
- if (chip_ready(map, adr))
- break;
-
- if (time_after(jiffies, timeo)) {
+ if (time_after(jiffies, timeo) && !chip_ready(map, adr)){
xip_enable(map, chip, adr);
printk(KERN_WARNING "MTD %s(): software timeout\n", __func__);
xip_disable(map, chip, adr);
- break;
+ break;
}
+ if (chip_ready(map, adr))
+ break;
+
/* Latency issues. Drop the lock, wait a while and retry */
UDELAY(map, chip, adr, 1);
}
@@ -1023,7 +1032,7 @@ static int __xipram do_write_oneword(struct map_info *map, struct flchip *chip,
map_write( map, CMD(0xF0), chip->start );
/* FIXME - should have reset delay before continuing */
- if (++retry_cnt <= MAX_WORD_RETRIES)
+ if (++retry_cnt <= MAX_WORD_RETRIES)
goto retry;
ret = -EIO;
@@ -1091,27 +1100,27 @@ static int cfi_amdstd_write_words(struct mtd_info *mtd, loff_t to, size_t len,
/* Number of bytes to copy from buffer */
n = min_t(int, len, map_bankwidth(map)-i);
-
+
tmp_buf = map_word_load_partial(map, tmp_buf, buf, i, n);
- ret = do_write_oneword(map, &cfi->chips[chipnum],
+ ret = do_write_oneword(map, &cfi->chips[chipnum],
bus_ofs, tmp_buf);
- if (ret)
+ if (ret)
return ret;
-
+
ofs += n;
buf += n;
(*retlen) += n;
len -= n;
if (ofs >> cfi->chipshift) {
- chipnum ++;
+ chipnum ++;
ofs = 0;
if (chipnum == cfi->numchips)
return 0;
}
}
-
+
/* We are now aligned, write as much as possible */
while(len >= map_bankwidth(map)) {
map_word datum;
@@ -1129,7 +1138,7 @@ static int cfi_amdstd_write_words(struct mtd_info *mtd, loff_t to, size_t len,
len -= map_bankwidth(map);
if (ofs >> cfi->chipshift) {
- chipnum ++;
+ chipnum ++;
ofs = 0;
if (chipnum == cfi->numchips)
return 0;
@@ -1167,12 +1176,12 @@ static int cfi_amdstd_write_words(struct mtd_info *mtd, loff_t to, size_t len,
spin_unlock(cfi->chips[chipnum].mutex);
tmp_buf = map_word_load_partial(map, tmp_buf, buf, 0, len);
-
- ret = do_write_oneword(map, &cfi->chips[chipnum],
+
+ ret = do_write_oneword(map, &cfi->chips[chipnum],
ofs, tmp_buf);
- if (ret)
+ if (ret)
return ret;
-
+
(*retlen) += len;
}
@@ -1184,7 +1193,7 @@ static int cfi_amdstd_write_words(struct mtd_info *mtd, loff_t to, size_t len,
* FIXME: interleaved mode not tested, and probably not supported!
*/
static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
- unsigned long adr, const u_char *buf,
+ unsigned long adr, const u_char *buf,
int len)
{
struct cfi_private *cfi = map->fldrv_priv;
@@ -1214,7 +1223,7 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
XIP_INVAL_CACHED_RANGE(map, adr, len);
ENABLE_VPP(map);
xip_disable(map, chip, cmd_adr);
-
+
cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, cfi->device_type, NULL);
//cfi_send_gen_cmd(0xA0, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
@@ -1248,8 +1257,8 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
adr, map_bankwidth(map),
chip->word_write_time);
- timeo = jiffies + uWriteTimeout;
-
+ timeo = jiffies + uWriteTimeout;
+
for (;;) {
if (chip->state != FL_WRITING) {
/* Someone's suspended the write. Sleep */
@@ -1265,13 +1274,13 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
continue;
}
+ if (time_after(jiffies, timeo) && !chip_ready(map, adr))
+ break;
+
if (chip_ready(map, adr)) {
xip_enable(map, chip, adr);
goto op_done;
}
-
- if( time_after(jiffies, timeo))
- break;
/* Latency issues. Drop the lock, wait a while and retry */
UDELAY(map, chip, adr, 1);
@@ -1343,7 +1352,7 @@ static int cfi_amdstd_write_buffers(struct mtd_info *mtd, loff_t to, size_t len,
if (size % map_bankwidth(map))
size -= size % map_bankwidth(map);
- ret = do_write_buffer(map, &cfi->chips[chipnum],
+ ret = do_write_buffer(map, &cfi->chips[chipnum],
ofs, buf, size);
if (ret)
return ret;
@@ -1354,7 +1363,7 @@ static int cfi_amdstd_write_buffers(struct mtd_info *mtd, loff_t to, size_t len,
len -= size;
if (ofs >> cfi->chipshift) {
- chipnum ++;
+ chipnum ++;
ofs = 0;
if (chipnum == cfi->numchips)
return 0;
@@ -1571,7 +1580,7 @@ int cfi_amdstd_erase_varsize(struct mtd_info *mtd, struct erase_info *instr)
instr->state = MTD_ERASE_DONE;
mtd_erase_callback(instr);
-
+
return 0;
}
@@ -1594,7 +1603,7 @@ static int cfi_amdstd_erase_chip(struct mtd_info *mtd, struct erase_info *instr)
instr->state = MTD_ERASE_DONE;
mtd_erase_callback(instr);
-
+
return 0;
}
@@ -1621,7 +1630,7 @@ static void cfi_amdstd_sync (struct mtd_info *mtd)
case FL_JEDEC_QUERY:
chip->oldstate = chip->state;
chip->state = FL_SYNCING;
- /* No need to wake_up() on this state change -
+ /* No need to wake_up() on this state change -
* as the whole point is that nobody can do anything
* with the chip now anyway.
*/
@@ -1632,13 +1641,13 @@ static void cfi_amdstd_sync (struct mtd_info *mtd)
default:
/* Not an idle state */
add_wait_queue(&chip->wq, &wait);
-
+
spin_unlock(chip->mutex);
schedule();
remove_wait_queue(&chip->wq, &wait);
-
+
goto retry;
}
}
@@ -1649,7 +1658,7 @@ static void cfi_amdstd_sync (struct mtd_info *mtd)
chip = &cfi->chips[i];
spin_lock(chip->mutex);
-
+
if (chip->state == FL_SYNCING) {
chip->state = chip->oldstate;
wake_up(&chip->wq);
@@ -1679,7 +1688,7 @@ static int cfi_amdstd_suspend(struct mtd_info *mtd)
case FL_JEDEC_QUERY:
chip->oldstate = chip->state;
chip->state = FL_PM_SUSPENDED;
- /* No need to wake_up() on this state change -
+ /* No need to wake_up() on this state change -
* as the whole point is that nobody can do anything
* with the chip now anyway.
*/
@@ -1700,7 +1709,7 @@ static int cfi_amdstd_suspend(struct mtd_info *mtd)
chip = &cfi->chips[i];
spin_lock(chip->mutex);
-
+
if (chip->state == FL_PM_SUSPENDED) {
chip->state = chip->oldstate;
wake_up(&chip->wq);
@@ -1708,7 +1717,7 @@ static int cfi_amdstd_suspend(struct mtd_info *mtd)
spin_unlock(chip->mutex);
}
}
-
+
return ret;
}
@@ -1721,11 +1730,11 @@ static void cfi_amdstd_resume(struct mtd_info *mtd)
struct flchip *chip;
for (i=0; i<cfi->numchips; i++) {
-
+
chip = &cfi->chips[i];
spin_lock(chip->mutex);
-
+
if (chip->state == FL_PM_SUSPENDED) {
chip->state = FL_READY;
map_write(map, CMD(0xF0), chip->start);
@@ -1742,6 +1751,7 @@ static void cfi_amdstd_destroy(struct mtd_info *mtd)
{
struct map_info *map = mtd->priv;
struct cfi_private *cfi = map->fldrv_priv;
+
kfree(cfi->cmdset_priv);
kfree(cfi->cfiq);
kfree(cfi);
diff --git a/drivers/mtd/chips/cfi_cmdset_0020.c b/drivers/mtd/chips/cfi_cmdset_0020.c
index c894f8801578..0807c1c91e55 100644
--- a/drivers/mtd/chips/cfi_cmdset_0020.c
+++ b/drivers/mtd/chips/cfi_cmdset_0020.c
@@ -4,8 +4,8 @@
*
* (C) 2000 Red Hat. GPL'd
*
- * $Id: cfi_cmdset_0020.c,v 1.19 2005/07/13 15:52:45 dwmw2 Exp $
- *
+ * $Id: cfi_cmdset_0020.c,v 1.22 2005/11/07 11:14:22 gleixner Exp $
+ *
* 10/10/2000 Nicolas Pitre <nico@cam.org>
* - completely revamped method functions so they are aware and
* independent of the flash geometry (buswidth, interleave, etc.)
@@ -20,7 +20,6 @@
* - Plugged memory leak in cfi_staa_writev().
*/
-#include <linux/version.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/kernel.h>
@@ -81,17 +80,17 @@ static void cfi_tell_features(struct cfi_pri_intelext *extp)
printk(" - Page-mode read: %s\n", extp->FeatureSupport&128?"supported":"unsupported");
printk(" - Synchronous read: %s\n", extp->FeatureSupport&256?"supported":"unsupported");
for (i=9; i<32; i++) {
- if (extp->FeatureSupport & (1<<i))
+ if (extp->FeatureSupport & (1<<i))
printk(" - Unknown Bit %X: supported\n", i);
}
-
+
printk(" Supported functions after Suspend: %2.2X\n", extp->SuspendCmdSupport);
printk(" - Program after Erase Suspend: %s\n", extp->SuspendCmdSupport&1?"supported":"unsupported");
for (i=1; i<8; i++) {
if (extp->SuspendCmdSupport & (1<<i))
printk(" - Unknown Bit %X: supported\n", i);
}
-
+
printk(" Block Status Register Mask: %4.4X\n", extp->BlkStatusRegMask);
printk(" - Lock Bit Active: %s\n", extp->BlkStatusRegMask&1?"yes":"no");
printk(" - Valid Bit Active: %s\n", extp->BlkStatusRegMask&2?"yes":"no");
@@ -99,11 +98,11 @@ static void cfi_tell_features(struct cfi_pri_intelext *extp)
if (extp->BlkStatusRegMask & (1<<i))
printk(" - Unknown Bit %X Active: yes\n",i);
}
-
- printk(" Vcc Logic Supply Optimum Program/Erase Voltage: %d.%d V\n",
+
+ printk(" Vcc Logic Supply Optimum Program/Erase Voltage: %d.%d V\n",
extp->VccOptimal >> 8, extp->VccOptimal & 0xf);
if (extp->VppOptimal)
- printk(" Vpp Programming Supply Optimum Program/Erase Voltage: %d.%d V\n",
+ printk(" Vpp Programming Supply Optimum Program/Erase Voltage: %d.%d V\n",
extp->VppOptimal >> 8, extp->VppOptimal & 0xf);
}
#endif
@@ -121,7 +120,7 @@ struct mtd_info *cfi_cmdset_0020(struct map_info *map, int primary)
int i;
if (cfi->cfi_mode) {
- /*
+ /*
* It's a real CFI chip, not one for which the probe
* routine faked a CFI structure. So we read the feature
* table from it.
@@ -133,24 +132,33 @@ struct mtd_info *cfi_cmdset_0020(struct map_info *map, int primary)
if (!extp)
return NULL;
+ if (extp->MajorVersion != '1' ||
+ (extp->MinorVersion < '0' || extp->MinorVersion > '3')) {
+ printk(KERN_ERR " Unknown ST Microelectronics"
+ " Extended Query version %c.%c.\n",
+ extp->MajorVersion, extp->MinorVersion);
+ kfree(extp);
+ return NULL;
+ }
+
/* Do some byteswapping if necessary */
extp->FeatureSupport = cfi32_to_cpu(extp->FeatureSupport);
extp->BlkStatusRegMask = cfi32_to_cpu(extp->BlkStatusRegMask);
-
+
#ifdef DEBUG_CFI_FEATURES
/* Tell the user about it in lots of lovely detail */
cfi_tell_features(extp);
-#endif
+#endif
/* Install our own private info structure */
cfi->cmdset_priv = extp;
- }
+ }
for (i=0; i< cfi->numchips; i++) {
cfi->chips[i].word_write_time = 128;
cfi->chips[i].buffer_write_time = 128;
cfi->chips[i].erase_time = 1024;
- }
+ }
return cfi_staa_setup(map);
}
@@ -178,15 +186,15 @@ static struct mtd_info *cfi_staa_setup(struct map_info *map)
mtd->size = devsize * cfi->numchips;
mtd->numeraseregions = cfi->cfiq->NumEraseRegions * cfi->numchips;
- mtd->eraseregions = kmalloc(sizeof(struct mtd_erase_region_info)
+ mtd->eraseregions = kmalloc(sizeof(struct mtd_erase_region_info)
* mtd->numeraseregions, GFP_KERNEL);
- if (!mtd->eraseregions) {
+ if (!mtd->eraseregions) {
printk(KERN_ERR "Failed to allocate memory for MTD erase region info\n");
kfree(cfi->cmdset_priv);
kfree(mtd);
return NULL;
}
-
+
for (i=0; i<cfi->cfiq->NumEraseRegions; i++) {
unsigned long ernum, ersize;
ersize = ((cfi->cfiq->EraseRegionInfo[i] >> 8) & ~0xff) * cfi->interleave;
@@ -219,7 +227,7 @@ static struct mtd_info *cfi_staa_setup(struct map_info *map)
mtd->eraseregions[i].numblocks);
}
- /* Also select the correct geometry setup too */
+ /* Also select the correct geometry setup too */
mtd->erase = cfi_staa_erase_varsize;
mtd->read = cfi_staa_read;
mtd->write = cfi_staa_write_buffers;
@@ -250,8 +258,8 @@ static inline int do_read_onechip(struct map_info *map, struct flchip *chip, lof
adr += chip->start;
- /* Ensure cmd read/writes are aligned. */
- cmd_addr = adr & ~(map_bankwidth(map)-1);
+ /* Ensure cmd read/writes are aligned. */
+ cmd_addr = adr & ~(map_bankwidth(map)-1);
/* Let's determine this according to the interleave only once */
status_OK = CMD(0x80);
@@ -267,7 +275,7 @@ static inline int do_read_onechip(struct map_info *map, struct flchip *chip, lof
case FL_ERASING:
if (!(((struct cfi_pri_intelext *)cfi->cmdset_priv)->FeatureSupport & 2))
goto sleep; /* We don't support erase suspend */
-
+
map_write (map, CMD(0xb0), cmd_addr);
/* If the flash has finished erasing, then 'erase suspend'
* appears to make some (28F320) flash devices switch to
@@ -282,7 +290,7 @@ static inline int do_read_onechip(struct map_info *map, struct flchip *chip, lof
status = map_read(map, cmd_addr);
if (map_word_andequal(map, status, status_OK, status_OK))
break;
-
+
if (time_after(jiffies, timeo)) {
/* Urgh */
map_write(map, CMD(0xd0), cmd_addr);
@@ -294,17 +302,17 @@ static inline int do_read_onechip(struct map_info *map, struct flchip *chip, lof
"suspended: status = 0x%lx\n", status.x[0]);
return -EIO;
}
-
+
spin_unlock_bh(chip->mutex);
cfi_udelay(1);
spin_lock_bh(chip->mutex);
}
-
+
suspended = 1;
map_write(map, CMD(0xff), cmd_addr);
chip->state = FL_READY;
break;
-
+
#if 0
case FL_WRITING:
/* Not quite yet */
@@ -325,7 +333,7 @@ static inline int do_read_onechip(struct map_info *map, struct flchip *chip, lof
chip->state = FL_READY;
break;
}
-
+
/* Urgh. Chip not yet ready to talk to us. */
if (time_after(jiffies, timeo)) {
spin_unlock_bh(chip->mutex);
@@ -355,17 +363,17 @@ static inline int do_read_onechip(struct map_info *map, struct flchip *chip, lof
if (suspended) {
chip->state = chip->oldstate;
- /* What if one interleaved chip has finished and the
+ /* What if one interleaved chip has finished and the
other hasn't? The old code would leave the finished
- one in READY mode. That's bad, and caused -EROFS
+ one in READY mode. That's bad, and caused -EROFS
errors to be returned from do_erase_oneblock because
that's the only bit it checked for at the time.
- As the state machine appears to explicitly allow
+ As the state machine appears to explicitly allow
sending the 0x70 (Read Status) command to an erasing
- chip and expecting it to be ignored, that's what we
+ chip and expecting it to be ignored, that's what we
do. */
map_write(map, CMD(0xd0), cmd_addr);
- map_write(map, CMD(0x70), cmd_addr);
+ map_write(map, CMD(0x70), cmd_addr);
}
wake_up(&chip->wq);
@@ -405,14 +413,14 @@ static int cfi_staa_read (struct mtd_info *mtd, loff_t from, size_t len, size_t
*retlen += thislen;
len -= thislen;
buf += thislen;
-
+
ofs = 0;
chipnum++;
}
return ret;
}
-static inline int do_write_buffer(struct map_info *map, struct flchip *chip,
+static inline int do_write_buffer(struct map_info *map, struct flchip *chip,
unsigned long adr, const u_char *buf, int len)
{
struct cfi_private *cfi = map->fldrv_priv;
@@ -420,7 +428,7 @@ static inline int do_write_buffer(struct map_info *map, struct flchip *chip,
unsigned long cmd_adr, timeo;
DECLARE_WAITQUEUE(wait, current);
int wbufsize, z;
-
+
/* M58LW064A requires bus alignment for buffer wriets -- saw */
if (adr & (map_bankwidth(map)-1))
return -EINVAL;
@@ -428,10 +436,10 @@ static inline int do_write_buffer(struct map_info *map, struct flchip *chip,
wbufsize = cfi_interleave(cfi) << cfi->cfiq->MaxBufWriteSize;
adr += chip->start;
cmd_adr = adr & ~(wbufsize-1);
-
+
/* Let's determine this according to the interleave only once */
status_OK = CMD(0x80);
-
+
timeo = jiffies + HZ;
retry:
@@ -439,7 +447,7 @@ static inline int do_write_buffer(struct map_info *map, struct flchip *chip,
printk("%s: chip->state[%d]\n", __FUNCTION__, chip->state);
#endif
spin_lock_bh(chip->mutex);
-
+
/* Check that the chip's ready to talk to us.
* Later, we can actually think about interrupting it
* if it's in FL_ERASING state.
@@ -448,7 +456,7 @@ static inline int do_write_buffer(struct map_info *map, struct flchip *chip,
switch (chip->state) {
case FL_READY:
break;
-
+
case FL_CFI_QUERY:
case FL_JEDEC_QUERY:
map_write(map, CMD(0x70), cmd_adr);
@@ -513,7 +521,7 @@ static inline int do_write_buffer(struct map_info *map, struct flchip *chip,
/* Write length of data to come */
map_write(map, CMD(len/map_bankwidth(map)-1), cmd_adr );
-
+
/* Write data */
for (z = 0; z < len;
z += map_bankwidth(map), buf += map_bankwidth(map)) {
@@ -560,7 +568,7 @@ static inline int do_write_buffer(struct map_info *map, struct flchip *chip,
printk(KERN_ERR "waiting for chip to be ready timed out in bufwrite\n");
return -EIO;
}
-
+
/* Latency issues. Drop the lock, wait a while and retry */
spin_unlock_bh(chip->mutex);
cfi_udelay(1);
@@ -572,9 +580,9 @@ static inline int do_write_buffer(struct map_info *map, struct flchip *chip,
if (!chip->buffer_write_time)
chip->buffer_write_time++;
}
- if (z > 1)
+ if (z > 1)
chip->buffer_write_time++;
-
+
/* Done and happy. */
DISABLE_VPP(map);
chip->state = FL_STATUS;
@@ -598,7 +606,7 @@ static inline int do_write_buffer(struct map_info *map, struct flchip *chip,
return 0;
}
-static int cfi_staa_write_buffers (struct mtd_info *mtd, loff_t to,
+static int cfi_staa_write_buffers (struct mtd_info *mtd, loff_t to,
size_t len, size_t *retlen, const u_char *buf)
{
struct map_info *map = mtd->priv;
@@ -620,7 +628,7 @@ static int cfi_staa_write_buffers (struct mtd_info *mtd, loff_t to,
printk("%s: chipnum[%x] wbufsize[%x]\n", __FUNCTION__, chipnum, wbufsize);
printk("%s: ofs[%x] len[%x]\n", __FUNCTION__, ofs, len);
#endif
-
+
/* Write buffer is worth it only if more than one word to write... */
while (len > 0) {
/* We must not cross write block boundaries */
@@ -629,7 +637,7 @@ static int cfi_staa_write_buffers (struct mtd_info *mtd, loff_t to,
if (size > len)
size = len;
- ret = do_write_buffer(map, &cfi->chips[chipnum],
+ ret = do_write_buffer(map, &cfi->chips[chipnum],
ofs, buf, size);
if (ret)
return ret;
@@ -640,13 +648,13 @@ static int cfi_staa_write_buffers (struct mtd_info *mtd, loff_t to,
len -= size;
if (ofs >> cfi->chipshift) {
- chipnum ++;
+ chipnum ++;
ofs = 0;
if (chipnum == cfi->numchips)
return 0;
}
}
-
+
return 0;
}
@@ -756,7 +764,7 @@ retry:
status = map_read(map, adr);
if (map_word_andequal(map, status, status_OK, status_OK))
break;
-
+
/* Urgh. Chip not yet ready to talk to us. */
if (time_after(jiffies, timeo)) {
spin_unlock_bh(chip->mutex);
@@ -789,7 +797,7 @@ retry:
map_write(map, CMD(0x20), adr);
map_write(map, CMD(0xD0), adr);
chip->state = FL_ERASING;
-
+
spin_unlock_bh(chip->mutex);
msleep(1000);
spin_lock_bh(chip->mutex);
@@ -814,7 +822,7 @@ retry:
status = map_read(map, adr);
if (map_word_andequal(map, status, status_OK, status_OK))
break;
-
+
/* OK Still waiting */
if (time_after(jiffies, timeo)) {
map_write(map, CMD(0x70), adr);
@@ -824,13 +832,13 @@ retry:
spin_unlock_bh(chip->mutex);
return -EIO;
}
-
+
/* Latency issues. Drop the lock, wait a while and retry */
spin_unlock_bh(chip->mutex);
cfi_udelay(1);
spin_lock_bh(chip->mutex);
}
-
+
DISABLE_VPP(map);
ret = 0;
@@ -855,7 +863,7 @@ retry:
/* Reset the error bits */
map_write(map, CMD(0x50), adr);
map_write(map, CMD(0x70), adr);
-
+
if ((chipstatus & 0x30) == 0x30) {
printk(KERN_NOTICE "Chip reports improper command sequence: status 0x%x\n", chipstatus);
ret = -EIO;
@@ -904,17 +912,17 @@ int cfi_staa_erase_varsize(struct mtd_info *mtd, struct erase_info *instr)
i = 0;
- /* Skip all erase regions which are ended before the start of
+ /* Skip all erase regions which are ended before the start of
the requested erase. Actually, to save on the calculations,
we skip to the first erase region which starts after the
start of the requested erase, and then go back one.
*/
-
+
while (i < mtd->numeraseregions && instr->addr >= regions[i].offset)
i++;
i--;
- /* OK, now i is pointing at the erase region in which this
+ /* OK, now i is pointing at the erase region in which this
erase request starts. Check the start of the requested
erase range is aligned with the erase size which is in
effect here.
@@ -937,7 +945,7 @@ int cfi_staa_erase_varsize(struct mtd_info *mtd, struct erase_info *instr)
the address actually falls
*/
i--;
-
+
if ((instr->addr + instr->len) & (regions[i].erasesize-1))
return -EINVAL;
@@ -949,7 +957,7 @@ int cfi_staa_erase_varsize(struct mtd_info *mtd, struct erase_info *instr)
while(len) {
ret = do_erase_oneblock(map, &cfi->chips[chipnum], adr);
-
+
if (ret)
return ret;
@@ -962,15 +970,15 @@ int cfi_staa_erase_varsize(struct mtd_info *mtd, struct erase_info *instr)
if (adr >> cfi->chipshift) {
adr = 0;
chipnum++;
-
+
if (chipnum >= cfi->numchips)
break;
}
}
-
+
instr->state = MTD_ERASE_DONE;
mtd_erase_callback(instr);
-
+
return 0;
}
@@ -996,7 +1004,7 @@ static void cfi_staa_sync (struct mtd_info *mtd)
case FL_JEDEC_QUERY:
chip->oldstate = chip->state;
chip->state = FL_SYNCING;
- /* No need to wake_up() on this state change -
+ /* No need to wake_up() on this state change -
* as the whole point is that nobody can do anything
* with the chip now anyway.
*/
@@ -1007,11 +1015,11 @@ static void cfi_staa_sync (struct mtd_info *mtd)
default:
/* Not an idle state */
add_wait_queue(&chip->wq, &wait);
-
+
spin_unlock_bh(chip->mutex);
schedule();
remove_wait_queue(&chip->wq, &wait);
-
+
goto retry;
}
}
@@ -1022,7 +1030,7 @@ static void cfi_staa_sync (struct mtd_info *mtd)
chip = &cfi->chips[i];
spin_lock_bh(chip->mutex);
-
+
if (chip->state == FL_SYNCING) {
chip->state = chip->oldstate;
wake_up(&chip->wq);
@@ -1057,9 +1065,9 @@ retry:
case FL_STATUS:
status = map_read(map, adr);
- if (map_word_andequal(map, status, status_OK, status_OK))
+ if (map_word_andequal(map, status, status_OK, status_OK))
break;
-
+
/* Urgh. Chip not yet ready to talk to us. */
if (time_after(jiffies, timeo)) {
spin_unlock_bh(chip->mutex);
@@ -1088,7 +1096,7 @@ retry:
map_write(map, CMD(0x60), adr);
map_write(map, CMD(0x01), adr);
chip->state = FL_LOCKING;
-
+
spin_unlock_bh(chip->mutex);
msleep(1000);
spin_lock_bh(chip->mutex);
@@ -1102,7 +1110,7 @@ retry:
status = map_read(map, adr);
if (map_word_andequal(map, status, status_OK, status_OK))
break;
-
+
/* OK Still waiting */
if (time_after(jiffies, timeo)) {
map_write(map, CMD(0x70), adr);
@@ -1112,13 +1120,13 @@ retry:
spin_unlock_bh(chip->mutex);
return -EIO;
}
-
+
/* Latency issues. Drop the lock, wait a while and retry */
spin_unlock_bh(chip->mutex);
cfi_udelay(1);
spin_lock_bh(chip->mutex);
}
-
+
/* Done and happy. */
chip->state = FL_STATUS;
DISABLE_VPP(map);
@@ -1162,8 +1170,8 @@ static int cfi_staa_lock(struct mtd_info *mtd, loff_t ofs, size_t len)
cfi_send_gen_cmd(0x90, 0x55, 0, map, cfi, cfi->device_type, NULL);
printk("after lock: block status register is %x\n",cfi_read_query(map, adr+(2*ofs_factor)));
cfi_send_gen_cmd(0xff, 0x55, 0, map, cfi, cfi->device_type, NULL);
-#endif
-
+#endif
+
if (ret)
return ret;
@@ -1173,7 +1181,7 @@ static int cfi_staa_lock(struct mtd_info *mtd, loff_t ofs, size_t len)
if (adr >> cfi->chipshift) {
adr = 0;
chipnum++;
-
+
if (chipnum >= cfi->numchips)
break;
}
@@ -1208,7 +1216,7 @@ retry:
status = map_read(map, adr);
if (map_word_andequal(map, status, status_OK, status_OK))
break;
-
+
/* Urgh. Chip not yet ready to talk to us. */
if (time_after(jiffies, timeo)) {
spin_unlock_bh(chip->mutex);
@@ -1237,7 +1245,7 @@ retry:
map_write(map, CMD(0x60), adr);
map_write(map, CMD(0xD0), adr);
chip->state = FL_UNLOCKING;
-
+
spin_unlock_bh(chip->mutex);
msleep(1000);
spin_lock_bh(chip->mutex);
@@ -1251,7 +1259,7 @@ retry:
status = map_read(map, adr);
if (map_word_andequal(map, status, status_OK, status_OK))
break;
-
+
/* OK Still waiting */
if (time_after(jiffies, timeo)) {
map_write(map, CMD(0x70), adr);
@@ -1261,13 +1269,13 @@ retry:
spin_unlock_bh(chip->mutex);
return -EIO;
}
-
+
/* Latency issues. Drop the unlock, wait a while and retry */
spin_unlock_bh(chip->mutex);
cfi_udelay(1);
spin_lock_bh(chip->mutex);
}
-
+
/* Done and happy. */
chip->state = FL_STATUS;
DISABLE_VPP(map);
@@ -1292,7 +1300,7 @@ static int cfi_staa_unlock(struct mtd_info *mtd, loff_t ofs, size_t len)
{
unsigned long temp_adr = adr;
unsigned long temp_len = len;
-
+
cfi_send_gen_cmd(0x90, 0x55, 0, map, cfi, cfi->device_type, NULL);
while (temp_len) {
printk("before unlock %x: block status register is %x\n",temp_adr,cfi_read_query(map, temp_adr+(2*ofs_factor)));
@@ -1310,7 +1318,7 @@ static int cfi_staa_unlock(struct mtd_info *mtd, loff_t ofs, size_t len)
printk("after unlock: block status register is %x\n",cfi_read_query(map, adr+(2*ofs_factor)));
cfi_send_gen_cmd(0xff, 0x55, 0, map, cfi, cfi->device_type, NULL);
#endif
-
+
return ret;
}
@@ -1334,7 +1342,7 @@ static int cfi_staa_suspend(struct mtd_info *mtd)
case FL_JEDEC_QUERY:
chip->oldstate = chip->state;
chip->state = FL_PM_SUSPENDED;
- /* No need to wake_up() on this state change -
+ /* No need to wake_up() on this state change -
* as the whole point is that nobody can do anything
* with the chip now anyway.
*/
@@ -1353,9 +1361,9 @@ static int cfi_staa_suspend(struct mtd_info *mtd)
if (ret) {
for (i--; i >=0; i--) {
chip = &cfi->chips[i];
-
+
spin_lock_bh(chip->mutex);
-
+
if (chip->state == FL_PM_SUSPENDED) {
/* No need to force it into a known state here,
because we're returning failure, and it didn't
@@ -1365,8 +1373,8 @@ static int cfi_staa_suspend(struct mtd_info *mtd)
}
spin_unlock_bh(chip->mutex);
}
- }
-
+ }
+
return ret;
}
@@ -1378,11 +1386,11 @@ static void cfi_staa_resume(struct mtd_info *mtd)
struct flchip *chip;
for (i=0; i<cfi->numchips; i++) {
-
+
chip = &cfi->chips[i];
spin_lock_bh(chip->mutex);
-
+
/* Go to known state. Chip may have been power cycled */
if (chip->state == FL_PM_SUSPENDED) {
map_write(map, CMD(0xFF), 0);
diff --git a/drivers/mtd/chips/cfi_probe.c b/drivers/mtd/chips/cfi_probe.c
index cf750038ce6a..90eb30e06b7c 100644
--- a/drivers/mtd/chips/cfi_probe.c
+++ b/drivers/mtd/chips/cfi_probe.c
@@ -1,7 +1,7 @@
-/*
+/*
Common Flash Interface probe code.
(C) 2000 Red Hat. GPL'd.
- $Id: cfi_probe.c,v 1.83 2004/11/16 18:19:02 nico Exp $
+ $Id: cfi_probe.c,v 1.84 2005/11/07 11:14:23 gleixner Exp $
*/
#include <linux/config.h>
@@ -20,7 +20,7 @@
#include <linux/mtd/cfi.h>
#include <linux/mtd/gen_probe.h>
-//#define DEBUG_CFI
+//#define DEBUG_CFI
#ifdef DEBUG_CFI
static void print_cfi_ident(struct cfi_ident *);
@@ -103,7 +103,7 @@ static int __xipram cfi_probe_chip(struct map_info *map, __u32 base,
unsigned long *chip_map, struct cfi_private *cfi)
{
int i;
-
+
if ((base + 0) >= map->size) {
printk(KERN_NOTICE
"Probe at base[0x00](0x%08lx) past the end of the map(0x%08lx)\n",
@@ -128,7 +128,7 @@ static int __xipram cfi_probe_chip(struct map_info *map, __u32 base,
}
if (!cfi->numchips) {
- /* This is the first time we're called. Set up the CFI
+ /* This is the first time we're called. Set up the CFI
stuff accordingly and return */
return cfi_chip_setup(map, cfi);
}
@@ -138,13 +138,13 @@ static int __xipram cfi_probe_chip(struct map_info *map, __u32 base,
unsigned long start;
if(!test_bit(i, chip_map)) {
/* Skip location; no valid chip at this address */
- continue;
+ continue;
}
start = i << cfi->chipshift;
/* This chip should be in read mode if it's one
we've already touched. */
if (qry_present(map, start, cfi)) {
- /* Eep. This chip also had the QRY marker.
+ /* Eep. This chip also had the QRY marker.
* Is it an alias for the new one? */
cfi_send_gen_cmd(0xF0, 0, start, map, cfi, cfi->device_type, NULL);
cfi_send_gen_cmd(0xFF, 0, start, map, cfi, cfi->device_type, NULL);
@@ -156,13 +156,13 @@ static int __xipram cfi_probe_chip(struct map_info *map, __u32 base,
map->name, base, start);
return 0;
}
- /* Yes, it's actually got QRY for data. Most
+ /* Yes, it's actually got QRY for data. Most
* unfortunate. Stick the new chip in read mode
* too and if it's the same, assume it's an alias. */
/* FIXME: Use other modes to do a proper check */
cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL);
cfi_send_gen_cmd(0xFF, 0, start, map, cfi, cfi->device_type, NULL);
-
+
if (qry_present(map, base, cfi)) {
xip_allowed(base, map);
printk(KERN_DEBUG "%s: Found an alias at 0x%x for the chip at 0x%lx\n",
@@ -171,12 +171,12 @@ static int __xipram cfi_probe_chip(struct map_info *map, __u32 base,
}
}
}
-
+
/* OK, if we got to here, then none of the previous chips appear to
be aliases for the current one. */
set_bit((base >> cfi->chipshift), chip_map); /* Update chip map */
cfi->numchips++;
-
+
/* Put it back into Read Mode */
cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL);
cfi_send_gen_cmd(0xFF, 0, base, map, cfi, cfi->device_type, NULL);
@@ -185,11 +185,11 @@ static int __xipram cfi_probe_chip(struct map_info *map, __u32 base,
printk(KERN_INFO "%s: Found %d x%d devices at 0x%x in %d-bit bank\n",
map->name, cfi->interleave, cfi->device_type*8, base,
map->bankwidth*8);
-
+
return 1;
}
-static int __xipram cfi_chip_setup(struct map_info *map,
+static int __xipram cfi_chip_setup(struct map_info *map,
struct cfi_private *cfi)
{
int ofs_factor = cfi->interleave*cfi->device_type;
@@ -209,11 +209,11 @@ static int __xipram cfi_chip_setup(struct map_info *map,
printk(KERN_WARNING "%s: kmalloc failed for CFI ident structure\n", map->name);
return 0;
}
-
- memset(cfi->cfiq,0,sizeof(struct cfi_ident));
-
+
+ memset(cfi->cfiq,0,sizeof(struct cfi_ident));
+
cfi->cfi_mode = CFI_MODE_CFI;
-
+
/* Read the CFI info structure */
xip_disable_qry(base, map, cfi);
for (i=0; i<(sizeof(struct cfi_ident) + num_erase_regions * 4); i++)
@@ -231,7 +231,7 @@ static int __xipram cfi_chip_setup(struct map_info *map,
cfi_send_gen_cmd(0x55, 0x2aa, base, map, cfi, cfi->device_type, NULL);
cfi_send_gen_cmd(0x90, 0x555, base, map, cfi, cfi->device_type, NULL);
cfi->mfr = cfi_read_query(map, base);
- cfi->id = cfi_read_query(map, base + ofs_factor);
+ cfi->id = cfi_read_query(map, base + ofs_factor);
/* Put it back into Read Mode */
cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL);
@@ -255,10 +255,10 @@ static int __xipram cfi_chip_setup(struct map_info *map,
for (i=0; i<cfi->cfiq->NumEraseRegions; i++) {
cfi->cfiq->EraseRegionInfo[i] = le32_to_cpu(cfi->cfiq->EraseRegionInfo[i]);
-
-#ifdef DEBUG_CFI
+
+#ifdef DEBUG_CFI
printk(" Erase Region #%d: BlockSize 0x%4.4X bytes, %d blocks\n",
- i, (cfi->cfiq->EraseRegionInfo[i] >> 8) & ~0xff,
+ i, (cfi->cfiq->EraseRegionInfo[i] >> 8) & ~0xff,
(cfi->cfiq->EraseRegionInfo[i] & 0xffff) + 1);
#endif
}
@@ -271,33 +271,33 @@ static int __xipram cfi_chip_setup(struct map_info *map,
}
#ifdef DEBUG_CFI
-static char *vendorname(__u16 vendor)
+static char *vendorname(__u16 vendor)
{
switch (vendor) {
case P_ID_NONE:
return "None";
-
+
case P_ID_INTEL_EXT:
return "Intel/Sharp Extended";
-
+
case P_ID_AMD_STD:
return "AMD/Fujitsu Standard";
-
+
case P_ID_INTEL_STD:
return "Intel/Sharp Standard";
-
+
case P_ID_AMD_EXT:
return "AMD/Fujitsu Extended";
case P_ID_WINBOND:
return "Winbond Standard";
-
+
case P_ID_ST_ADV:
return "ST Advanced";
case P_ID_MITSUBISHI_STD:
return "Mitsubishi Standard";
-
+
case P_ID_MITSUBISHI_EXT:
return "Mitsubishi Extended";
@@ -306,13 +306,13 @@ static char *vendorname(__u16 vendor)
case P_ID_INTEL_PERFORMANCE:
return "Intel Performance Code";
-
+
case P_ID_INTEL_DATA:
return "Intel Data";
-
+
case P_ID_RESERVED:
return "Not Allowed / Reserved for Future Use";
-
+
default:
return "Unknown";
}
@@ -325,21 +325,21 @@ static void print_cfi_ident(struct cfi_ident *cfip)
if (cfip->qry[0] != 'Q' || cfip->qry[1] != 'R' || cfip->qry[2] != 'Y') {
printk("Invalid CFI ident structure.\n");
return;
- }
-#endif
+ }
+#endif
printk("Primary Vendor Command Set: %4.4X (%s)\n", cfip->P_ID, vendorname(cfip->P_ID));
if (cfip->P_ADR)
printk("Primary Algorithm Table at %4.4X\n", cfip->P_ADR);
else
printk("No Primary Algorithm Table\n");
-
+
printk("Alternative Vendor Command Set: %4.4X (%s)\n", cfip->A_ID, vendorname(cfip->A_ID));
if (cfip->A_ADR)
printk("Alternate Algorithm Table at %4.4X\n", cfip->A_ADR);
else
printk("No Alternate Algorithm Table\n");
-
-
+
+
printk("Vcc Minimum: %2d.%d V\n", cfip->VccMin >> 4, cfip->VccMin & 0xf);
printk("Vcc Maximum: %2d.%d V\n", cfip->VccMax >> 4, cfip->VccMax & 0xf);
if (cfip->VppMin) {
@@ -348,61 +348,61 @@ static void print_cfi_ident(struct cfi_ident *cfip)
}
else
printk("No Vpp line\n");
-
+
printk("Typical byte/word write timeout: %d µs\n", 1<<cfip->WordWriteTimeoutTyp);
printk("Maximum byte/word write timeout: %d µs\n", (1<<cfip->WordWriteTimeoutMax) * (1<<cfip->WordWriteTimeoutTyp));
-
+
if (cfip->BufWriteTimeoutTyp || cfip->BufWriteTimeoutMax) {
printk("Typical full buffer write timeout: %d µs\n", 1<<cfip->BufWriteTimeoutTyp);
printk("Maximum full buffer write timeout: %d µs\n", (1<<cfip->BufWriteTimeoutMax) * (1<<cfip->BufWriteTimeoutTyp));
}
else
printk("Full buffer write not supported\n");
-
+
printk("Typical block erase timeout: %d ms\n", 1<<cfip->BlockEraseTimeoutTyp);
printk("Maximum block erase timeout: %d ms\n", (1<<cfip->BlockEraseTimeoutMax) * (1<<cfip->BlockEraseTimeoutTyp));
if (cfip->ChipEraseTimeoutTyp || cfip->ChipEraseTimeoutMax) {
- printk("Typical chip erase timeout: %d ms\n", 1<<cfip->ChipEraseTimeoutTyp);
+ printk("Typical chip erase timeout: %d ms\n", 1<<cfip->ChipEraseTimeoutTyp);
printk("Maximum chip erase timeout: %d ms\n", (1<<cfip->ChipEraseTimeoutMax) * (1<<cfip->ChipEraseTimeoutTyp));
}
else
printk("Chip erase not supported\n");
-
+
printk("Device size: 0x%X bytes (%d MiB)\n", 1 << cfip->DevSize, 1<< (cfip->DevSize - 20));
printk("Flash Device Interface description: 0x%4.4X\n", cfip->InterfaceDesc);
switch(cfip->InterfaceDesc) {
case 0:
printk(" - x8-only asynchronous interface\n");
break;
-
+
case 1:
printk(" - x16-only asynchronous interface\n");
break;
-
+
case 2:
printk(" - supports x8 and x16 via BYTE# with asynchronous interface\n");
break;
-
+
case 3:
printk(" - x32-only asynchronous interface\n");
break;
-
+
case 4:
printk(" - supports x16 and x32 via Word# with asynchronous interface\n");
break;
-
+
case 65535:
printk(" - Not Allowed / Reserved\n");
break;
-
+
default:
printk(" - Unknown\n");
break;
}
-
+
printk("Max. bytes in buffer write: 0x%x\n", 1<< cfip->MaxBufWriteSize);
printk("Number of Erase Block Regions: %d\n", cfip->NumEraseRegions);
-
+
}
#endif /* DEBUG_CFI */
diff --git a/drivers/mtd/chips/cfi_util.c b/drivers/mtd/chips/cfi_util.c
index 2b2ede2bfcca..d8e7a026ba5a 100644
--- a/drivers/mtd/chips/cfi_util.c
+++ b/drivers/mtd/chips/cfi_util.c
@@ -7,7 +7,7 @@
*
* This code is covered by the GPL.
*
- * $Id: cfi_util.c,v 1.8 2004/12/14 19:55:56 nico Exp $
+ * $Id: cfi_util.c,v 1.10 2005/11/07 11:14:23 gleixner Exp $
*
*/
@@ -56,7 +56,7 @@ __xipram cfi_read_pri(struct map_info *map, __u16 adr, __u16 size, const char* n
/* Read in the Extended Query Table */
for (i=0; i<size; i++) {
- ((unsigned char *)extp)[i] =
+ ((unsigned char *)extp)[i] =
cfi_read_query(map, base+((adr+i)*ofs_factor));
}
@@ -70,15 +70,6 @@ __xipram cfi_read_pri(struct map_info *map, __u16 adr, __u16 size, const char* n
local_irq_enable();
#endif
- if (extp->MajorVersion != '1' ||
- (extp->MinorVersion < '0' || extp->MinorVersion > '3')) {
- printk(KERN_WARNING " Unknown %s Extended Query "
- "version %c.%c.\n", name, extp->MajorVersion,
- extp->MinorVersion);
- kfree(extp);
- extp = NULL;
- }
-
out: return extp;
}
@@ -122,17 +113,17 @@ int cfi_varsize_frob(struct mtd_info *mtd, varsize_frob_t frob,
i = 0;
- /* Skip all erase regions which are ended before the start of
+ /* Skip all erase regions which are ended before the start of
the requested erase. Actually, to save on the calculations,
we skip to the first erase region which starts after the
start of the requested erase, and then go back one.
*/
-
+
while (i < mtd->numeraseregions && ofs >= regions[i].offset)
i++;
i--;
- /* OK, now i is pointing at the erase region in which this
+ /* OK, now i is pointing at the erase region in which this
erase request starts. Check the start of the requested
erase range is aligned with the erase size which is in
effect here.
@@ -155,7 +146,7 @@ int cfi_varsize_frob(struct mtd_info *mtd, varsize_frob_t frob,
the address actually falls
*/
i--;
-
+
if ((ofs + len) & (regions[i].erasesize-1))
return -EINVAL;
@@ -168,7 +159,7 @@ int cfi_varsize_frob(struct mtd_info *mtd, varsize_frob_t frob,
int size = regions[i].erasesize;
ret = (*frob)(map, &cfi->chips[chipnum], adr, size, thunk);
-
+
if (ret)
return ret;
@@ -182,7 +173,7 @@ int cfi_varsize_frob(struct mtd_info *mtd, varsize_frob_t frob,
if (adr >> cfi->chipshift) {
adr = 0;
chipnum++;
-
+
if (chipnum >= cfi->numchips)
break;
}
diff --git a/drivers/mtd/chips/chipreg.c b/drivers/mtd/chips/chipreg.c
index d7d739a108ae..c2127840a183 100644
--- a/drivers/mtd/chips/chipreg.c
+++ b/drivers/mtd/chips/chipreg.c
@@ -41,7 +41,7 @@ static struct mtd_chip_driver *get_mtd_chip_driver (const char *name)
list_for_each(pos, &chip_drvs_list) {
this = list_entry(pos, typeof(*this), list);
-
+
if (!strcmp(this->name, name)) {
ret = this;
break;
@@ -73,7 +73,7 @@ struct mtd_info *do_map_probe(const char *name, struct map_info *map)
ret = drv->probe(map);
- /* We decrease the use count here. It may have been a
+ /* We decrease the use count here. It may have been a
probe-only module, which is no longer required from this
point, having given us a handle on (and increased the use
count of) the actual driver code.
@@ -82,7 +82,7 @@ struct mtd_info *do_map_probe(const char *name, struct map_info *map)
if (ret)
return ret;
-
+
return NULL;
}
/*
diff --git a/drivers/mtd/chips/fwh_lock.h b/drivers/mtd/chips/fwh_lock.h
index e1a5b76596c5..77303ce5dcf1 100644
--- a/drivers/mtd/chips/fwh_lock.h
+++ b/drivers/mtd/chips/fwh_lock.h
@@ -25,7 +25,7 @@ struct fwh_xxlock_thunk {
* so this code has not been tested with interleaved chips,
* and will likely fail in that context.
*/
-static int fwh_xxlock_oneblock(struct map_info *map, struct flchip *chip,
+static int fwh_xxlock_oneblock(struct map_info *map, struct flchip *chip,
unsigned long adr, int len, void *thunk)
{
struct cfi_private *cfi = map->fldrv_priv;
@@ -44,7 +44,7 @@ static int fwh_xxlock_oneblock(struct map_info *map, struct flchip *chip,
* - on 64k boundariesand
* - bit 1 set high
* - block lock registers are 4MiB lower - overflow subtract (danger)
- *
+ *
* The address manipulation is first done on the logical address
* which is 0 at the start of the chip, and then the offset of
* the individual chip is addted to it. Any other order a weird
@@ -93,7 +93,7 @@ static int fwh_unlock_varsize(struct mtd_info *mtd, loff_t ofs, size_t len)
ret = cfi_varsize_frob(mtd, fwh_xxlock_oneblock, ofs, len,
(void *)&FWH_XXLOCK_ONEBLOCK_UNLOCK);
-
+
return ret;
}
diff --git a/drivers/mtd/chips/gen_probe.c b/drivers/mtd/chips/gen_probe.c
index dc065b22f79e..41bd59d20d85 100644
--- a/drivers/mtd/chips/gen_probe.c
+++ b/drivers/mtd/chips/gen_probe.c
@@ -2,7 +2,7 @@
* Routines common to all CFI-type probes.
* (C) 2001-2003 Red Hat, Inc.
* GPL'd
- * $Id: gen_probe.c,v 1.22 2005/01/24 23:49:50 rmk Exp $
+ * $Id: gen_probe.c,v 1.24 2005/11/07 11:14:23 gleixner Exp $
*/
#include <linux/kernel.h>
@@ -26,7 +26,7 @@ struct mtd_info *mtd_do_chip_probe(struct map_info *map, struct chip_probe *cp)
/* First probe the map to see if we have CFI stuff there. */
cfi = genprobe_ident_chips(map, cp);
-
+
if (!cfi)
return NULL;
@@ -36,12 +36,12 @@ struct mtd_info *mtd_do_chip_probe(struct map_info *map, struct chip_probe *cp)
mtd = check_cmd_set(map, 1); /* First the primary cmdset */
if (!mtd)
mtd = check_cmd_set(map, 0); /* Then the secondary */
-
+
if (mtd)
return mtd;
printk(KERN_WARNING"gen_probe: No supported Vendor Command Set found\n");
-
+
kfree(cfi->cfiq);
kfree(cfi);
map->fldrv_priv = NULL;
@@ -60,14 +60,14 @@ static struct cfi_private *genprobe_ident_chips(struct map_info *map, struct chi
memset(&cfi, 0, sizeof(cfi));
- /* Call the probetype-specific code with all permutations of
+ /* Call the probetype-specific code with all permutations of
interleave and device type, etc. */
if (!genprobe_new_chip(map, cp, &cfi)) {
/* The probe didn't like it */
printk(KERN_DEBUG "%s: Found no %s device at location zero\n",
cp->name, map->name);
return NULL;
- }
+ }
#if 0 /* Let the CFI probe routine do this sanity check. The Intel and AMD
probe routines won't ever return a broken CFI structure anyway,
@@ -92,13 +92,13 @@ static struct cfi_private *genprobe_ident_chips(struct map_info *map, struct chi
} else {
BUG();
}
-
+
cfi.numchips = 1;
- /*
- * Allocate memory for bitmap of valid chips.
- * Align bitmap storage size to full byte.
- */
+ /*
+ * Allocate memory for bitmap of valid chips.
+ * Align bitmap storage size to full byte.
+ */
max_chips = map->size >> cfi.chipshift;
mapsize = (max_chips / 8) + ((max_chips % 8) ? 1 : 0);
chip_map = kmalloc(mapsize, GFP_KERNEL);
@@ -122,7 +122,7 @@ static struct cfi_private *genprobe_ident_chips(struct map_info *map, struct chi
}
/*
- * Now allocate the space for the structures we need to return to
+ * Now allocate the space for the structures we need to return to
* our caller, and copy the appropriate data into them.
*/
@@ -154,7 +154,7 @@ static struct cfi_private *genprobe_ident_chips(struct map_info *map, struct chi
return retcfi;
}
-
+
static int genprobe_new_chip(struct map_info *map, struct chip_probe *cp,
struct cfi_private *cfi)
{
@@ -189,7 +189,7 @@ extern cfi_cmdset_fn_t cfi_cmdset_0001;
extern cfi_cmdset_fn_t cfi_cmdset_0002;
extern cfi_cmdset_fn_t cfi_cmdset_0020;
-static inline struct mtd_info *cfi_cmdset_unknown(struct map_info *map,
+static inline struct mtd_info *cfi_cmdset_unknown(struct map_info *map,
int primary)
{
struct cfi_private *cfi = map->fldrv_priv;
@@ -199,7 +199,7 @@ static inline struct mtd_info *cfi_cmdset_unknown(struct map_info *map,
cfi_cmdset_fn_t *probe_function;
sprintf(probename, "cfi_cmdset_%4.4X", type);
-
+
probe_function = inter_module_get_request(probename, probename);
if (probe_function) {
@@ -221,7 +221,7 @@ static struct mtd_info *check_cmd_set(struct map_info *map, int primary)
{
struct cfi_private *cfi = map->fldrv_priv;
__u16 type = primary?cfi->cfiq->P_ID:cfi->cfiq->A_ID;
-
+
if (type == P_ID_NONE || type == P_ID_RESERVED)
return NULL;
@@ -235,6 +235,7 @@ static struct mtd_info *check_cmd_set(struct map_info *map, int primary)
#ifdef CONFIG_MTD_CFI_INTELEXT
case 0x0001:
case 0x0003:
+ case 0x0200:
return cfi_cmdset_0001(map, primary);
#endif
#ifdef CONFIG_MTD_CFI_AMDSTD
diff --git a/drivers/mtd/chips/jedec.c b/drivers/mtd/chips/jedec.c
index 62d235a9a4e2..c40b48dabed3 100644
--- a/drivers/mtd/chips/jedec.c
+++ b/drivers/mtd/chips/jedec.c
@@ -1,6 +1,6 @@
/* JEDEC Flash Interface.
- * This is an older type of interface for self programming flash. It is
+ * This is an older type of interface for self programming flash. It is
* commonly use in older AMD chips and is obsolete compared with CFI.
* It is called JEDEC because the JEDEC association distributes the ID codes
* for the chips.
@@ -17,6 +17,7 @@
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <linux/mtd/jedec.h>
#include <linux/mtd/map.h>
#include <linux/mtd/mtd.h>
@@ -87,9 +88,9 @@ static const struct JEDECTable JEDEC_table[] = {
static const struct JEDECTable *jedec_idtoinf(__u8 mfr,__u8 id);
static void jedec_sync(struct mtd_info *mtd) {};
-static int jedec_read(struct mtd_info *mtd, loff_t from, size_t len,
+static int jedec_read(struct mtd_info *mtd, loff_t from, size_t len,
size_t *retlen, u_char *buf);
-static int jedec_read_banked(struct mtd_info *mtd, loff_t from, size_t len,
+static int jedec_read_banked(struct mtd_info *mtd, loff_t from, size_t len,
size_t *retlen, u_char *buf);
static struct mtd_info *jedec_probe(struct map_info *map);
@@ -121,7 +122,7 @@ static struct mtd_info *jedec_probe(struct map_info *map)
memset(MTD, 0, sizeof(struct mtd_info) + sizeof(struct jedec_private));
priv = (struct jedec_private *)&MTD[1];
-
+
my_bank_size = map->size;
if (map->size/my_bank_size > MAX_JEDEC_CHIPS)
@@ -130,13 +131,13 @@ static struct mtd_info *jedec_probe(struct map_info *map)
kfree(MTD);
return NULL;
}
-
+
for (Base = 0; Base < map->size; Base += my_bank_size)
{
// Perhaps zero could designate all tests?
if (map->buswidth == 0)
map->buswidth = 1;
-
+
if (map->buswidth == 1){
if (jedec_probe8(map,Base,priv) == 0) {
printk("did recognize jedec chip\n");
@@ -149,7 +150,7 @@ static struct mtd_info *jedec_probe(struct map_info *map)
if (map->buswidth == 4)
jedec_probe32(map,Base,priv);
}
-
+
// Get the biggest sector size
SectorSize = 0;
for (I = 0; priv->chips[I].jedec != 0 && I < MAX_JEDEC_CHIPS; I++)
@@ -159,7 +160,7 @@ static struct mtd_info *jedec_probe(struct map_info *map)
if (priv->chips[I].sectorsize > SectorSize)
SectorSize = priv->chips[I].sectorsize;
}
-
+
// Quickly ensure that the other sector sizes are factors of the largest
for (I = 0; priv->chips[I].jedec != 0 && I < MAX_JEDEC_CHIPS; I++)
{
@@ -168,9 +169,9 @@ static struct mtd_info *jedec_probe(struct map_info *map)
printk("mtd: Failed. Device has incompatible mixed sector sizes\n");
kfree(MTD);
return NULL;
- }
+ }
}
-
+
/* Generate a part name that includes the number of different chips and
other configuration information */
count = 1;
@@ -180,13 +181,13 @@ static struct mtd_info *jedec_probe(struct map_info *map)
for (I = 0; priv->chips[I].jedec != 0 && I < MAX_JEDEC_CHIPS; I++)
{
const struct JEDECTable *JEDEC;
-
+
if (priv->chips[I+1].jedec == priv->chips[I].jedec)
{
count++;
continue;
}
-
+
// Locate the chip in the jedec table
JEDEC = jedec_idtoinf(priv->chips[I].jedec >> 8,priv->chips[I].jedec);
if (JEDEC == 0)
@@ -195,11 +196,11 @@ static struct mtd_info *jedec_probe(struct map_info *map)
kfree(MTD);
return NULL;
}
-
+
if (Uniq != 0)
strcat(Part,",");
Uniq++;
-
+
if (count != 1)
sprintf(Part+strlen(Part),"%x*[%s]",count,JEDEC->name);
else
@@ -207,7 +208,7 @@ static struct mtd_info *jedec_probe(struct map_info *map)
if (strlen(Part) > sizeof(Part)*2/3)
break;
count = 1;
- }
+ }
/* Determine if the chips are organized in a linear fashion, or if there
are empty banks. Note, the last bank does not count here, only the
@@ -232,7 +233,7 @@ static struct mtd_info *jedec_probe(struct map_info *map)
{
if (priv->bank_fill[I] != my_bank_size)
priv->is_banked = 1;
-
+
/* This even could be eliminated, but new de-optimized read/write
functions have to be written */
printk("priv->bank_fill[%d] is %lx, priv->bank_fill[0] is %lx\n",I,priv->bank_fill[I],priv->bank_fill[0]);
@@ -241,7 +242,7 @@ static struct mtd_info *jedec_probe(struct map_info *map)
printk("mtd: Failed. Cannot handle unsymmetric banking\n");
kfree(MTD);
return NULL;
- }
+ }
}
}
}
@@ -249,7 +250,7 @@ static struct mtd_info *jedec_probe(struct map_info *map)
strcat(Part,", banked");
// printk("Part: '%s'\n",Part);
-
+
memset(MTD,0,sizeof(*MTD));
// strlcpy(MTD->name,Part,sizeof(MTD->name));
MTD->name = map->name;
@@ -290,7 +291,7 @@ static int checkparity(u_char C)
/* Take an array of JEDEC numbers that represent interleved flash chips
and process them. Check to make sure they are good JEDEC numbers, look
- them up and then add them to the chip list */
+ them up and then add them to the chip list */
static int handle_jedecs(struct map_info *map,__u8 *Mfg,__u8 *Id,unsigned Count,
unsigned long base,struct jedec_private *priv)
{
@@ -305,16 +306,16 @@ static int handle_jedecs(struct map_info *map,__u8 *Mfg,__u8 *Id,unsigned Count,
if (checkparity(Mfg[I]) == 0 || checkparity(Id[I]) == 0)
return 0;
}
-
+
// Finally, just make sure all the chip sizes are the same
JEDEC = jedec_idtoinf(Mfg[0],Id[0]);
-
+
if (JEDEC == 0)
{
printk("mtd: Found JEDEC flash chip, but do not have a table entry for %x:%x\n",Mfg[0],Mfg[1]);
return 0;
}
-
+
Size = JEDEC->size;
SectorSize = JEDEC->sectorsize;
for (I = 0; I != Count; I++)
@@ -330,7 +331,7 @@ static int handle_jedecs(struct map_info *map,__u8 *Mfg,__u8 *Id,unsigned Count,
{
printk("mtd: Failed. Interleved flash does not have matching characteristics\n");
return 0;
- }
+ }
}
// Load the Chips
@@ -344,13 +345,13 @@ static int handle_jedecs(struct map_info *map,__u8 *Mfg,__u8 *Id,unsigned Count,
{
printk("mtd: Device has too many chips. Increase MAX_JEDEC_CHIPS\n");
return 0;
- }
-
+ }
+
// Add them to the table
for (J = 0; J != Count; J++)
{
unsigned long Bank;
-
+
JEDEC = jedec_idtoinf(Mfg[J],Id[J]);
priv->chips[I].jedec = (Mfg[J] << 8) | Id[J];
priv->chips[I].size = JEDEC->size;
@@ -363,17 +364,17 @@ static int handle_jedecs(struct map_info *map,__u8 *Mfg,__u8 *Id,unsigned Count,
// log2 n :|
priv->chips[I].addrshift = 0;
for (Bank = Count; Bank != 1; Bank >>= 1, priv->chips[I].addrshift++);
-
+
// Determine how filled this bank is.
Bank = base & (~(my_bank_size-1));
- if (priv->bank_fill[Bank/my_bank_size] < base +
+ if (priv->bank_fill[Bank/my_bank_size] < base +
(JEDEC->size << priv->chips[I].addrshift) - Bank)
priv->bank_fill[Bank/my_bank_size] = base + (JEDEC->size << priv->chips[I].addrshift) - Bank;
I++;
}
priv->size += priv->chips[I-1].size*Count;
-
+
return priv->chips[I-1].size;
}
@@ -391,7 +392,7 @@ static const struct JEDECTable *jedec_idtoinf(__u8 mfr,__u8 id)
// Look for flash using an 8 bit bus interface
static int jedec_probe8(struct map_info *map,unsigned long base,
struct jedec_private *priv)
-{
+{
#define flread(x) map_read8(map,base+x)
#define flwrite(v,x) map_write8(map,v,base+x)
@@ -409,20 +410,20 @@ static int jedec_probe8(struct map_info *map,unsigned long base,
OldVal = flread(base);
for (I = 0; OldVal != flread(base) && I < 10000; I++)
OldVal = flread(base);
-
+
// Reset the chip
- flwrite(Reset,0x555);
-
+ flwrite(Reset,0x555);
+
// Send the sequence
flwrite(AutoSel1,0x555);
flwrite(AutoSel2,0x2AA);
flwrite(AutoSel3,0x555);
-
+
// Get the JEDEC numbers
Mfg[0] = flread(0);
Id[0] = flread(1);
// printk("Mfg is %x, Id is %x\n",Mfg[0],Id[0]);
-
+
Size = handle_jedecs(map,Mfg,Id,1,base,priv);
// printk("handle_jedecs Size is %x\n",(unsigned int)Size);
if (Size == 0)
@@ -430,13 +431,13 @@ static int jedec_probe8(struct map_info *map,unsigned long base,
flwrite(Reset,0x555);
return 0;
}
-
+
// Reset.
flwrite(Reset,0x555);
-
+
return 1;
-
+
#undef flread
#undef flwrite
}
@@ -469,17 +470,17 @@ static int jedec_probe32(struct map_info *map,unsigned long base,
OldVal = flread(base);
for (I = 0; OldVal != flread(base) && I < 10000; I++)
OldVal = flread(base);
-
+
// Reset the chip
- flwrite(Reset,0x555);
-
+ flwrite(Reset,0x555);
+
// Send the sequence
flwrite(AutoSel1,0x555);
flwrite(AutoSel2,0x2AA);
flwrite(AutoSel3,0x555);
-
+
// Test #1, JEDEC numbers are readable from 0x??00/0x??01
- if (flread(0) != flread(0x100) ||
+ if (flread(0) != flread(0x100) ||
flread(1) != flread(0x101))
{
flwrite(Reset,0x555);
@@ -493,14 +494,14 @@ static int jedec_probe32(struct map_info *map,unsigned long base,
OldVal = flread(1);
for (I = 0; I != 4; I++)
Id[I] = (OldVal >> (I*8));
-
+
Size = handle_jedecs(map,Mfg,Id,4,base,priv);
if (Size == 0)
{
flwrite(Reset,0x555);
return 0;
}
-
+
/* Check if there is address wrap around within a single bank, if this
returns JEDEC numbers then we assume that it is wrap around. Notice
we call this routine with the JEDEC return still enabled, if two or
@@ -518,27 +519,27 @@ static int jedec_probe32(struct map_info *map,unsigned long base,
// Reset.
flwrite(0xF0F0F0F0,0x555);
-
+
return 1;
-
+
#undef flread
#undef flwrite
}
/* Linear read. */
-static int jedec_read(struct mtd_info *mtd, loff_t from, size_t len,
+static int jedec_read(struct mtd_info *mtd, loff_t from, size_t len,
size_t *retlen, u_char *buf)
{
struct map_info *map = mtd->priv;
-
+
map_copy_from(map, buf, from, len);
*retlen = len;
- return 0;
+ return 0;
}
/* Banked read. Take special care to jump past the holes in the bank
mapping. This version assumes symetry in the holes.. */
-static int jedec_read_banked(struct mtd_info *mtd, loff_t from, size_t len,
+static int jedec_read_banked(struct mtd_info *mtd, loff_t from, size_t len,
size_t *retlen, u_char *buf)
{
struct map_info *map = mtd->priv;
@@ -554,17 +555,17 @@ static int jedec_read_banked(struct mtd_info *mtd, loff_t from, size_t len,
if (priv->bank_fill[0] - offset < len)
get = priv->bank_fill[0] - offset;
- bank /= priv->bank_fill[0];
+ bank /= priv->bank_fill[0];
map_copy_from(map,buf + *retlen,bank*my_bank_size + offset,get);
-
+
len -= get;
*retlen += get;
from += get;
- }
- return 0;
+ }
+ return 0;
}
-/* Pass the flags value that the flash return before it re-entered read
+/* Pass the flags value that the flash return before it re-entered read
mode. */
static void jedec_flash_failed(unsigned char code)
{
@@ -578,17 +579,17 @@ static void jedec_flash_failed(unsigned char code)
printk("mtd: Programming didn't take\n");
}
-/* This uses the erasure function described in the AMD Flash Handbook,
+/* This uses the erasure function described in the AMD Flash Handbook,
it will work for flashes with a fixed sector size only. Flashes with
a selection of sector sizes (ie the AMD Am29F800B) will need a different
- routine. This routine tries to parallize erasing multiple chips/sectors
+ routine. This routine tries to parallize erasing multiple chips/sectors
where possible */
static int flash_erase(struct mtd_info *mtd, struct erase_info *instr)
{
// Does IO to the currently selected chip
#define flread(x) map_read8(map,chip->base+((x)<<chip->addrshift))
#define flwrite(v,x) map_write8(map,v,chip->base+((x)<<chip->addrshift))
-
+
unsigned long Time = 0;
unsigned long NoTime = 0;
unsigned long start = instr->addr, len = instr->len;
@@ -602,7 +603,7 @@ static int flash_erase(struct mtd_info *mtd, struct erase_info *instr)
(len % mtd->erasesize) != 0 ||
(len/mtd->erasesize) == 0)
return -EINVAL;
-
+
jedec_flash_chip_scan(priv,start,len);
// Start the erase sequence on each chip
@@ -610,16 +611,16 @@ static int flash_erase(struct mtd_info *mtd, struct erase_info *instr)
{
unsigned long off;
struct jedec_flash_chip *chip = priv->chips + I;
-
+
if (chip->length == 0)
continue;
-
+
if (chip->start + chip->length > chip->size)
{
printk("DIE\n");
return -EIO;
- }
-
+ }
+
flwrite(0xF0,chip->start + 0x555);
flwrite(0xAA,chip->start + 0x555);
flwrite(0x55,chip->start + 0x2AA);
@@ -627,8 +628,8 @@ static int flash_erase(struct mtd_info *mtd, struct erase_info *instr)
flwrite(0xAA,chip->start + 0x555);
flwrite(0x55,chip->start + 0x2AA);
- /* Once we start selecting the erase sectors the delay between each
- command must not exceed 50us or it will immediately start erasing
+ /* Once we start selecting the erase sectors the delay between each
+ command must not exceed 50us or it will immediately start erasing
and ignore the other sectors */
for (off = 0; off < len; off += chip->sectorsize)
{
@@ -640,19 +641,19 @@ static int flash_erase(struct mtd_info *mtd, struct erase_info *instr)
{
printk("mtd: Ack! We timed out the erase timer!\n");
return -EIO;
- }
+ }
}
- }
+ }
/* We could split this into a timer routine and return early, performing
background erasure.. Maybe later if the need warrents */
/* Poll the flash for erasure completion, specs say this can take as long
- as 480 seconds to do all the sectors (for a 2 meg flash).
+ as 480 seconds to do all the sectors (for a 2 meg flash).
Erasure time is dependent on chip age, temp and wear.. */
-
+
/* This being a generic routine assumes a 32 bit bus. It does read32s
- and bundles interleved chips into the same grouping. This will work
+ and bundles interleved chips into the same grouping. This will work
for all bus widths */
Time = 0;
NoTime = 0;
@@ -663,20 +664,20 @@ static int flash_erase(struct mtd_info *mtd, struct erase_info *instr)
unsigned todo[4] = {0,0,0,0};
unsigned todo_left = 0;
unsigned J;
-
+
if (chip->length == 0)
continue;
- /* Find all chips in this data line, realistically this is all
+ /* Find all chips in this data line, realistically this is all
or nothing up to the interleve count */
for (J = 0; priv->chips[J].jedec != 0 && J < MAX_JEDEC_CHIPS; J++)
{
- if ((priv->chips[J].base & (~((1<<chip->addrshift)-1))) ==
+ if ((priv->chips[J].base & (~((1<<chip->addrshift)-1))) ==
(chip->base & (~((1<<chip->addrshift)-1))))
{
todo_left++;
todo[priv->chips[J].base & ((1<<chip->addrshift)-1)] = 1;
- }
+ }
}
/* printk("todo: %x %x %x %x\n",(short)todo[0],(short)todo[1],
@@ -686,7 +687,7 @@ static int flash_erase(struct mtd_info *mtd, struct erase_info *instr)
{
__u32 Last[4];
unsigned long Count = 0;
-
+
/* During erase bit 7 is held low and bit 6 toggles, we watch this,
should it stop toggling or go high then the erase is completed,
or this is not really flash ;> */
@@ -717,23 +718,23 @@ static int flash_erase(struct mtd_info *mtd, struct erase_info *instr)
__u8 Byte3 = (Last[(Count-3)%4] >> (J*8)) & 0xFF;
if (todo[J] == 0)
continue;
-
+
if ((Byte1 & (1 << 7)) == 0 && Byte1 != Byte2)
{
// printk("Check %x %x %x\n",(short)J,(short)Byte1,(short)Byte2);
continue;
}
-
+
if (Byte1 == Byte2)
{
jedec_flash_failed(Byte3);
return -EIO;
}
-
+
todo[J] = 0;
todo_left--;
}
-
+
/* if (NoTime == 0)
Time += HZ/10 - schedule_timeout(HZ/10);*/
NoTime = 0;
@@ -750,7 +751,7 @@ static int flash_erase(struct mtd_info *mtd, struct erase_info *instr)
break;
}
Count++;
-
+
/* // Count time, max of 15s per sector (according to AMD)
if (Time > 15*len/mtd->erasesize*HZ)
{
@@ -758,38 +759,38 @@ static int flash_erase(struct mtd_info *mtd, struct erase_info *instr)
return -EIO;
} */
}
-
+
// Skip to the next chip if we used chip erase
if (chip->length == chip->size)
off = chip->size;
else
off += chip->sectorsize;
-
+
if (off >= chip->length)
break;
NoTime = 1;
}
-
+
for (J = 0; priv->chips[J].jedec != 0 && J < MAX_JEDEC_CHIPS; J++)
{
if ((priv->chips[J].base & (~((1<<chip->addrshift)-1))) ==
(chip->base & (~((1<<chip->addrshift)-1))))
priv->chips[J].length = 0;
- }
+ }
}
-
+
//printk("done\n");
instr->state = MTD_ERASE_DONE;
mtd_erase_callback(instr);
return 0;
-
+
#undef flread
#undef flwrite
}
/* This is the simple flash writing function. It writes to every byte, in
sequence. It takes care of how to properly address the flash if
- the flash is interleved. It can only be used if all the chips in the
+ the flash is interleved. It can only be used if all the chips in the
array are identical!*/
static int flash_write(struct mtd_info *mtd, loff_t start, size_t len,
size_t *retlen, const u_char *buf)
@@ -799,25 +800,25 @@ static int flash_write(struct mtd_info *mtd, loff_t start, size_t len,
of addrshift (interleave index) and then adds the control register index. */
#define flread(x) map_read8(map,base+(off&((1<<chip->addrshift)-1))+((x)<<chip->addrshift))
#define flwrite(v,x) map_write8(map,v,base+(off&((1<<chip->addrshift)-1))+((x)<<chip->addrshift))
-
+
struct map_info *map = mtd->priv;
struct jedec_private *priv = map->fldrv_priv;
unsigned long base;
unsigned long off;
size_t save_len = len;
-
+
if (start + len > mtd->size)
return -EIO;
-
+
//printk("Here");
-
+
//printk("flash_write: start is %x, len is %x\n",start,(unsigned long)len);
while (len != 0)
{
struct jedec_flash_chip *chip = priv->chips;
unsigned long bank;
unsigned long boffset;
-
+
// Compute the base of the flash.
off = ((unsigned long)start) % (chip->size << chip->addrshift);
base = start - off;
@@ -827,10 +828,10 @@ static int flash_write(struct mtd_info *mtd, loff_t start, size_t len,
boffset = base & (priv->bank_fill[0]-1);
bank = (bank/priv->bank_fill[0])*my_bank_size;
base = bank + boffset;
-
+
// printk("Flasing %X %X %X\n",base,chip->size,len);
// printk("off is %x, compare with %x\n",off,chip->size << chip->addrshift);
-
+
// Loop over this page
for (; off != (chip->size << chip->addrshift) && len != 0; start++, len--, off++,buf++)
{
@@ -844,7 +845,7 @@ static int flash_write(struct mtd_info *mtd, loff_t start, size_t len,
}
if (((~oldbyte) & *buf) != 0)
printk("mtd: warn: Trying to set a 0 to a 1\n");
-
+
// Write
flwrite(0xAA,0x555);
flwrite(0x55,0x2AA);
@@ -853,10 +854,10 @@ static int flash_write(struct mtd_info *mtd, loff_t start, size_t len,
Last[0] = map_read8(map,base + off);
Last[1] = map_read8(map,base + off);
Last[2] = map_read8(map,base + off);
-
+
/* Wait for the flash to finish the operation. We store the last 4
status bytes that have been retrieved so we can determine why
- it failed. The toggle bits keep toggling when there is a
+ it failed. The toggle bits keep toggling when there is a
failure */
for (Count = 3; Last[(Count - 1) % 4] != Last[(Count - 2) % 4] &&
Count < 10000; Count++)
@@ -865,7 +866,7 @@ static int flash_write(struct mtd_info *mtd, loff_t start, size_t len,
{
jedec_flash_failed(Last[(Count - 3) % 4]);
return -EIO;
- }
+ }
}
}
*retlen = save_len;
@@ -884,24 +885,24 @@ static void jedec_flash_chip_scan(struct jedec_private *priv,unsigned long start
// Zero the records
for (I = 0; priv->chips[I].jedec != 0 && I < MAX_JEDEC_CHIPS; I++)
priv->chips[I].start = priv->chips[I].length = 0;
-
+
// Intersect the region with each chip
for (I = 0; priv->chips[I].jedec != 0 && I < MAX_JEDEC_CHIPS; I++)
{
struct jedec_flash_chip *chip = priv->chips + I;
unsigned long ByteStart;
unsigned long ChipEndByte = chip->offset + (chip->size << chip->addrshift);
-
+
// End is before this chip or the start is after it
if (start+len < chip->offset ||
ChipEndByte - (1 << chip->addrshift) < start)
continue;
-
+
if (start < chip->offset)
{
ByteStart = chip->offset;
chip->start = 0;
- }
+ }
else
{
chip->start = (start - chip->offset + (1 << chip->addrshift)-1) >> chip->addrshift;
diff --git a/drivers/mtd/chips/jedec_probe.c b/drivers/mtd/chips/jedec_probe.c
index 30da428eb7b9..edb306c03c0a 100644
--- a/drivers/mtd/chips/jedec_probe.c
+++ b/drivers/mtd/chips/jedec_probe.c
@@ -1,7 +1,7 @@
-/*
+/*
Common Flash Interface probe code.
(C) 2000 Red Hat. GPL'd.
- $Id: jedec_probe.c,v 1.63 2005/02/14 16:30:32 bjd Exp $
+ $Id: jedec_probe.c,v 1.66 2005/11/07 11:14:23 gleixner Exp $
See JEDEC (http://www.jedec.org/) standard JESD21C (section 3.5)
for the standard this probe goes back to.
@@ -1719,7 +1719,7 @@ static int jedec_probe_chip(struct map_info *map, __u32 base,
static struct mtd_info *jedec_probe(struct map_info *map);
-static inline u32 jedec_read_mfr(struct map_info *map, __u32 base,
+static inline u32 jedec_read_mfr(struct map_info *map, __u32 base,
struct cfi_private *cfi)
{
map_word result;
@@ -1730,7 +1730,7 @@ static inline u32 jedec_read_mfr(struct map_info *map, __u32 base,
return result.x[0] & mask;
}
-static inline u32 jedec_read_id(struct map_info *map, __u32 base,
+static inline u32 jedec_read_id(struct map_info *map, __u32 base,
struct cfi_private *cfi)
{
map_word result;
@@ -1741,7 +1741,7 @@ static inline u32 jedec_read_id(struct map_info *map, __u32 base,
return result.x[0] & mask;
}
-static inline void jedec_reset(u32 base, struct map_info *map,
+static inline void jedec_reset(u32 base, struct map_info *map,
struct cfi_private *cfi)
{
/* Reset */
@@ -1765,7 +1765,7 @@ static inline void jedec_reset(u32 base, struct map_info *map,
* so ensure we're in read mode. Send both the Intel and the AMD command
* for this. Intel uses 0xff for this, AMD uses 0xff for NOP, so
* this should be safe.
- */
+ */
cfi_send_gen_cmd(0xFF, 0, base, map, cfi, cfi->device_type, NULL);
/* FIXME - should have reset delay before continuing */
}
@@ -1807,14 +1807,14 @@ static int cfi_jedec_setup(struct cfi_private *p_cfi, int index)
printk("Found: %s\n",jedec_table[index].name);
num_erase_regions = jedec_table[index].NumEraseRegions;
-
+
p_cfi->cfiq = kmalloc(sizeof(struct cfi_ident) + num_erase_regions * 4, GFP_KERNEL);
if (!p_cfi->cfiq) {
//xx printk(KERN_WARNING "%s: kmalloc failed for CFI ident structure\n", map->name);
return 0;
}
- memset(p_cfi->cfiq,0,sizeof(struct cfi_ident));
+ memset(p_cfi->cfiq,0,sizeof(struct cfi_ident));
p_cfi->cfiq->P_ID = jedec_table[index].CmdSet;
p_cfi->cfiq->NumEraseRegions = jedec_table[index].NumEraseRegions;
@@ -1969,7 +1969,7 @@ static inline int jedec_match( __u32 base,
cfi_send_gen_cmd(0x90, cfi->addr_unlock1, base, map, cfi, cfi->device_type, NULL);
/* FIXME - should have a delay before continuing */
- match_done:
+ match_done:
return rc;
}
@@ -1998,23 +1998,23 @@ static int jedec_probe_chip(struct map_info *map, __u32 base,
"Probe at base(0x%08x) past the end of the map(0x%08lx)\n",
base, map->size -1);
return 0;
-
+
}
/* Ensure the unlock addresses we try stay inside the map */
probe_offset1 = cfi_build_cmd_addr(
- cfi->addr_unlock1,
- cfi_interleave(cfi),
+ cfi->addr_unlock1,
+ cfi_interleave(cfi),
cfi->device_type);
probe_offset2 = cfi_build_cmd_addr(
- cfi->addr_unlock1,
- cfi_interleave(cfi),
+ cfi->addr_unlock1,
+ cfi_interleave(cfi),
cfi->device_type);
if ( ((base + probe_offset1 + map_bankwidth(map)) >= map->size) ||
((base + probe_offset2 + map_bankwidth(map)) >= map->size))
{
goto retry;
}
-
+
/* Reset */
jedec_reset(base, map, cfi);
@@ -2027,13 +2027,13 @@ static int jedec_probe_chip(struct map_info *map, __u32 base,
/* FIXME - should have a delay before continuing */
if (!cfi->numchips) {
- /* This is the first time we're called. Set up the CFI
+ /* This is the first time we're called. Set up the CFI
stuff accordingly and return */
-
+
cfi->mfr = jedec_read_mfr(map, base, cfi);
cfi->id = jedec_read_id(map, base, cfi);
DEBUG(MTD_DEBUG_LEVEL3,
- "Search for id:(%02x %02x) interleave(%d) type(%d)\n",
+ "Search for id:(%02x %02x) interleave(%d) type(%d)\n",
cfi->mfr, cfi->id, cfi_interleave(cfi), cfi->device_type);
for (i=0; i<sizeof(jedec_table)/sizeof(jedec_table[0]); i++) {
if ( jedec_match( base, map, cfi, &jedec_table[i] ) ) {
@@ -2062,7 +2062,7 @@ static int jedec_probe_chip(struct map_info *map, __u32 base,
return 0;
}
}
-
+
/* Check each previous chip locations to see if it's an alias */
for (i=0; i < (base >> cfi->chipshift); i++) {
unsigned long start;
@@ -2083,7 +2083,7 @@ static int jedec_probe_chip(struct map_info *map, __u32 base,
map->name, base, start);
return 0;
}
-
+
/* Yes, it's actually got the device IDs as data. Most
* unfortunate. Stick the new chip in read mode
* too and if it's the same, assume it's an alias. */
@@ -2097,20 +2097,20 @@ static int jedec_probe_chip(struct map_info *map, __u32 base,
}
}
}
-
+
/* OK, if we got to here, then none of the previous chips appear to
be aliases for the current one. */
set_bit((base >> cfi->chipshift), chip_map); /* Update chip map */
cfi->numchips++;
-
+
ok_out:
/* Put it back into Read Mode */
jedec_reset(base, map, cfi);
printk(KERN_INFO "%s: Found %d x%d devices at 0x%x in %d-bit bank\n",
- map->name, cfi_interleave(cfi), cfi->device_type*8, base,
+ map->name, cfi_interleave(cfi), cfi->device_type*8, base,
map->bankwidth*8);
-
+
return 1;
}
diff --git a/drivers/mtd/chips/map_absent.c b/drivers/mtd/chips/map_absent.c
index c6c83833cc32..a611de9b1515 100644
--- a/drivers/mtd/chips/map_absent.c
+++ b/drivers/mtd/chips/map_absent.c
@@ -1,11 +1,11 @@
/*
* Common code to handle absent "placeholder" devices
* Copyright 2001 Resilience Corporation <ebrower@resilience.com>
- * $Id: map_absent.c,v 1.5 2004/11/16 18:29:00 dwmw2 Exp $
+ * $Id: map_absent.c,v 1.6 2005/11/07 11:14:23 gleixner Exp $
*
* This map driver is used to allocate "placeholder" MTD
- * devices on systems that have socketed/removable media.
- * Use of this driver as a fallback preserves the expected
+ * devices on systems that have socketed/removable media.
+ * Use of this driver as a fallback preserves the expected
* registration of MTD device nodes regardless of probe outcome.
* A usage example is as follows:
*
@@ -80,7 +80,7 @@ static int map_absent_read(struct mtd_info *mtd, loff_t from, size_t len, size_t
static int map_absent_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf)
{
*retlen = 0;
- return -ENODEV;
+ return -ENODEV;
}
static int map_absent_erase(struct mtd_info *mtd, struct erase_info *instr)
diff --git a/drivers/mtd/chips/sharp.c b/drivers/mtd/chips/sharp.c
index c3cf0f63bc93..2d26bdef82d5 100644
--- a/drivers/mtd/chips/sharp.c
+++ b/drivers/mtd/chips/sharp.c
@@ -4,7 +4,7 @@
* Copyright 2000,2001 David A. Schleef <ds@schleef.org>
* 2000,2001 Lineo, Inc.
*
- * $Id: sharp.c,v 1.14 2004/08/09 13:19:43 dwmw2 Exp $
+ * $Id: sharp.c,v 1.16 2005/11/07 11:14:23 gleixner Exp $
*
* Devices supported:
* LH28F016SCT Symmetrical block flash memory, 2Mx8
@@ -31,6 +31,7 @@
#include <linux/mtd/cfi.h>
#include <linux/delay.h>
#include <linux/init.h>
+#include <linux/slab.h>
#define CMD_RESET 0xffffffff
#define CMD_READ_ID 0x90909090
@@ -214,7 +215,7 @@ static int sharp_probe_map(struct map_info *map,struct mtd_info *mtd)
/* This function returns with the chip->mutex lock held. */
static int sharp_wait(struct map_info *map, struct flchip *chip)
{
- __u16 status;
+ int status, i;
unsigned long timeo = jiffies + HZ;
DECLARE_WAITQUEUE(wait, current);
int adr = 0;
@@ -227,13 +228,11 @@ retry:
map_write32(map,CMD_READ_STATUS,adr);
chip->state = FL_STATUS;
case FL_STATUS:
- status = map_read32(map,adr);
-//printk("status=%08x\n",status);
-
- udelay(100);
- if((status & SR_READY)!=SR_READY){
-//printk(".status=%08x\n",status);
- udelay(100);
+ for(i=0;i<100;i++){
+ status = map_read32(map,adr);
+ if((status & SR_READY)==SR_READY)
+ break;
+ udelay(1);
}
break;
default:
@@ -460,12 +459,12 @@ static int sharp_do_wait_for_ready(struct map_info *map, struct flchip *chip,
remove_wait_queue(&chip->wq, &wait);
//spin_lock_bh(chip->mutex);
-
+
if (signal_pending(current)){
ret = -EINTR;
goto out;
}
-
+
}
ret = -ETIME;
out:
@@ -564,7 +563,7 @@ static int sharp_suspend(struct mtd_info *mtd)
static void sharp_resume(struct mtd_info *mtd)
{
printk("sharp_resume()\n");
-
+
}
static void sharp_destroy(struct mtd_info *mtd)
diff --git a/drivers/mtd/cmdlinepart.c b/drivers/mtd/cmdlinepart.c
index ef24837019d3..6b8bb2e4dcfd 100644
--- a/drivers/mtd/cmdlinepart.c
+++ b/drivers/mtd/cmdlinepart.c
@@ -1,24 +1,24 @@
/*
- * $Id: cmdlinepart.c,v 1.18 2005/06/07 15:04:26 joern Exp $
+ * $Id: cmdlinepart.c,v 1.19 2005/11/07 11:14:19 gleixner Exp $
*
* Read flash partition table from command line
*
* Copyright 2002 SYSGO Real-Time Solutions GmbH
*
* The format for the command line is as follows:
- *
+ *
* mtdparts=<mtddef>[;<mtddef]
* <mtddef> := <mtd-id>:<partdef>[,<partdef>]
* <partdef> := <size>[@offset][<name>][ro]
* <mtd-id> := unique name used in mapping driver/device (mtd->name)
* <size> := standard linux memsize OR "-" to denote all remaining space
* <name> := '(' NAME ')'
- *
+ *
* Examples:
- *
+ *
* 1 NOR Flash, with 1 single writable partition:
* edb7312-nor:-
- *
+ *
* 1 NOR Flash with 2 partitions, 1 NAND with one
* edb7312-nor:256k(ARMboot)ro,-(root);edb7312-nand:-(home)
*/
@@ -60,17 +60,17 @@ static int cmdline_parsed = 0;
/*
* Parse one partition definition for an MTD. Since there can be many
- * comma separated partition definitions, this function calls itself
+ * comma separated partition definitions, this function calls itself
* recursively until no more partition definitions are found. Nice side
* effect: the memory to keep the mtd_partition structs and the names
* is allocated upon the last definition being found. At that point the
* syntax has been verified ok.
*/
-static struct mtd_partition * newpart(char *s,
+static struct mtd_partition * newpart(char *s,
char **retptr,
int *num_parts,
- int this_part,
- unsigned char **extra_mem_ptr,
+ int this_part,
+ unsigned char **extra_mem_ptr,
int extra_mem_size)
{
struct mtd_partition *parts;
@@ -102,7 +102,7 @@ static struct mtd_partition * newpart(char *s,
mask_flags = 0; /* this is going to be a regular partition */
delim = 0;
/* check for offset */
- if (*s == '@')
+ if (*s == '@')
{
s++;
offset = memparse(s, &s);
@@ -112,7 +112,7 @@ static struct mtd_partition * newpart(char *s,
{
delim = ')';
}
-
+
if (delim)
{
char *p;
@@ -131,12 +131,12 @@ static struct mtd_partition * newpart(char *s,
name = NULL;
name_len = 13; /* Partition_000 */
}
-
+
/* record name length for memory allocation later */
extra_mem_size += name_len + 1;
/* test for options */
- if (strncmp(s, "ro", 2) == 0)
+ if (strncmp(s, "ro", 2) == 0)
{
mask_flags |= MTD_WRITEABLE;
s += 2;
@@ -151,7 +151,7 @@ static struct mtd_partition * newpart(char *s,
return NULL;
}
/* more partitions follow, parse them */
- if ((parts = newpart(s + 1, &s, num_parts,
+ if ((parts = newpart(s + 1, &s, num_parts,
this_part + 1, &extra_mem, extra_mem_size)) == 0)
return NULL;
}
@@ -187,7 +187,7 @@ static struct mtd_partition * newpart(char *s,
extra_mem += name_len + 1;
dbg(("partition %d: name <%s>, offset %x, size %x, mask flags %x\n",
- this_part,
+ this_part,
parts[this_part].name,
parts[this_part].offset,
parts[this_part].size,
@@ -204,8 +204,8 @@ static struct mtd_partition * newpart(char *s,
return parts;
}
-/*
- * Parse the command line.
+/*
+ * Parse the command line.
*/
static int mtdpart_setup_real(char *s)
{
@@ -230,7 +230,7 @@ static int mtdpart_setup_real(char *s)
dbg(("parsing <%s>\n", p+1));
- /*
+ /*
* parse one mtd. have it reserve memory for the
* struct cmdline_mtd_partition and the mtd-id string.
*/
@@ -239,7 +239,7 @@ static int mtdpart_setup_real(char *s)
&num_parts, /* out: number of parts */
0, /* first partition */
(unsigned char**)&this_mtd, /* out: extra mem */
- mtd_id_len + 1 + sizeof(*this_mtd) +
+ mtd_id_len + 1 + sizeof(*this_mtd) +
sizeof(void*)-1 /*alignment*/);
if(!parts)
{
@@ -254,21 +254,21 @@ static int mtdpart_setup_real(char *s)
}
/* align this_mtd */
- this_mtd = (struct cmdline_mtd_partition *)
+ this_mtd = (struct cmdline_mtd_partition *)
ALIGN((unsigned long)this_mtd, sizeof(void*));
- /* enter results */
+ /* enter results */
this_mtd->parts = parts;
this_mtd->num_parts = num_parts;
this_mtd->mtd_id = (char*)(this_mtd + 1);
strlcpy(this_mtd->mtd_id, mtd_id, mtd_id_len + 1);
/* link into chain */
- this_mtd->next = partitions;
+ this_mtd->next = partitions;
partitions = this_mtd;
- dbg(("mtdid=<%s> num_parts=<%d>\n",
+ dbg(("mtdid=<%s> num_parts=<%d>\n",
this_mtd->mtd_id, this_mtd->num_parts));
-
+
/* EOS - we're done */
if (*s == 0)
@@ -292,7 +292,7 @@ static int mtdpart_setup_real(char *s)
* information. It returns partitions for the requested mtd device, or
* the first one in the chain if a NULL mtd_id is passed in.
*/
-static int parse_cmdline_partitions(struct mtd_info *master,
+static int parse_cmdline_partitions(struct mtd_info *master,
struct mtd_partition **pparts,
unsigned long origin)
{
@@ -322,7 +322,7 @@ static int parse_cmdline_partitions(struct mtd_info *master,
part->parts[i].size = master->size - offset;
if (offset + part->parts[i].size > master->size)
{
- printk(KERN_WARNING ERRP
+ printk(KERN_WARNING ERRP
"%s: partitioning exceeds flash size, truncating\n",
part->mtd_id);
part->parts[i].size = master->size - offset;
@@ -338,8 +338,8 @@ static int parse_cmdline_partitions(struct mtd_info *master,
}
-/*
- * This is the handler for our kernel parameter, called from
+/*
+ * This is the handler for our kernel parameter, called from
* main.c::checksetup(). Note that we can not yet kmalloc() anything,
* so we only save the commandline for later processing.
*
diff --git a/drivers/mtd/devices/Kconfig b/drivers/mtd/devices/Kconfig
index c4a56a4ac5e2..9a2aa4033c6a 100644
--- a/drivers/mtd/devices/Kconfig
+++ b/drivers/mtd/devices/Kconfig
@@ -1,5 +1,5 @@
# drivers/mtd/maps/Kconfig
-# $Id: Kconfig,v 1.15 2004/12/22 17:51:15 joern Exp $
+# $Id: Kconfig,v 1.18 2005/11/07 11:14:24 gleixner Exp $
menu "Self-contained MTD device drivers"
depends on MTD!=n
@@ -110,7 +110,7 @@ config MTDRAM_ABS_POS
If you have system RAM accessible by the CPU but not used by Linux
in normal operation, you can give the physical address at which the
available RAM starts, and the MTDRAM driver will use it instead of
- allocating space from Linux's available memory. Otherwise, leave
+ allocating space from Linux's available memory. Otherwise, leave
this set to zero. Most people will want to leave this as zero.
config MTD_BLKMTD
@@ -165,7 +165,7 @@ config MTD_DOC2001
select MTD_DOCPROBE
select MTD_NAND_IDS
---help---
- This provides an alternative MTD device driver for the M-Systems
+ This provides an alternative MTD device driver for the M-Systems
DiskOnChip Millennium devices. Use this if you have problems with
the combined DiskOnChip 2000 and Millennium driver above. To get
the DiskOnChip probe code to load and use this driver instead of
@@ -192,7 +192,7 @@ config MTD_DOC2001PLUS
If you use this device, you probably also want to enable the INFTL
'Inverse NAND Flash Translation Layer' option below, which is used
- to emulate a block device by using a kind of file system on the
+ to emulate a block device by using a kind of file system on the
flash chips.
NOTE: This driver will soon be replaced by the new DiskOnChip driver
diff --git a/drivers/mtd/devices/blkmtd.c b/drivers/mtd/devices/blkmtd.c
index 662e807801ed..f9db52f6bf00 100644
--- a/drivers/mtd/devices/blkmtd.c
+++ b/drivers/mtd/devices/blkmtd.c
@@ -1,5 +1,5 @@
/*
- * $Id: blkmtd.c,v 1.24 2004/11/16 18:29:01 dwmw2 Exp $
+ * $Id: blkmtd.c,v 1.27 2005/11/07 11:14:24 gleixner Exp $
*
* blkmtd.c - use a block device as a fake MTD
*
@@ -39,7 +39,7 @@
/* Default erase size in K, always make it a multiple of PAGE_SIZE */
#define CONFIG_MTD_BLKDEV_ERASESIZE (128 << 10) /* 128KiB */
-#define VERSION "$Revision: 1.24 $"
+#define VERSION "$Revision: 1.27 $"
/* Info for the block device */
struct blkmtd_dev {
@@ -117,7 +117,7 @@ static int bi_write_complete(struct bio *bio, unsigned int bytes_done, int error
unlock_page(page);
page_cache_release(page);
} while (bvec >= bio->bi_io_vec);
-
+
complete((struct completion*)bio->bi_private);
return 0;
}
@@ -135,7 +135,7 @@ static int blkmtd_readpage(struct blkmtd_dev *dev, struct page *page)
unlock_page(page);
return 0;
}
-
+
ClearPageUptodate(page);
ClearPageError(page);
@@ -539,11 +539,8 @@ static void free_device(struct blkmtd_dev *dev)
{
DEBUG(2, "blkmtd: free_device() dev = %p\n", dev);
if(dev) {
- if(dev->mtd_info.eraseregions)
- kfree(dev->mtd_info.eraseregions);
- if(dev->mtd_info.name)
- kfree(dev->mtd_info.name);
-
+ kfree(dev->mtd_info.eraseregions);
+ kfree(dev->mtd_info.name);
if(dev->blkdev) {
invalidate_inode_pages(dev->blkdev->bd_inode->i_mapping);
close_bdev_excl(dev->blkdev);
@@ -710,7 +707,7 @@ static struct blkmtd_dev *add_device(char *devname, int readonly, int erase_size
dev->mtd_info.erasesize >> 10,
readonly ? "(read-only)" : "");
}
-
+
return dev;
devinit_err:
diff --git a/drivers/mtd/devices/block2mtd.c b/drivers/mtd/devices/block2mtd.c
index 4a7a805e7564..0aaa0ced9aba 100644
--- a/drivers/mtd/devices/block2mtd.c
+++ b/drivers/mtd/devices/block2mtd.c
@@ -1,5 +1,5 @@
/*
- * $Id: block2mtd.c,v 1.28 2005/03/19 22:40:44 gleixner Exp $
+ * $Id: block2mtd.c,v 1.29 2005/11/07 11:14:24 gleixner Exp $
*
* block2mtd.c - create an mtd from a block device
*
@@ -19,7 +19,7 @@
#include <linux/mtd/mtd.h>
#include <linux/buffer_head.h>
-#define VERSION "$Revision: 1.28 $"
+#define VERSION "$Revision: 1.29 $"
#define ERROR(fmt, args...) printk(KERN_ERR "block2mtd: " fmt "\n" , ## args)
@@ -111,7 +111,7 @@ static int _block2mtd_erase(struct block2mtd_dev *dev, loff_t to, size_t len)
return PTR_ERR(page);
max = (u_long*)page_address(page) + PAGE_SIZE;
- for (p=(u_long*)page_address(page); p<max; p++)
+ for (p=(u_long*)page_address(page); p<max; p++)
if (*p != -1UL) {
lock_page(page);
memset(page_address(page), 0xff, PAGE_SIZE);
@@ -206,7 +206,7 @@ static int _block2mtd_write(struct block2mtd_dev *dev, const u_char *buf,
if (retlen)
*retlen = 0;
while (len) {
- if ((offset+len) > PAGE_SIZE)
+ if ((offset+len) > PAGE_SIZE)
cpylen = PAGE_SIZE - offset; // multiple pages
else
cpylen = len; // this page
diff --git a/drivers/mtd/devices/doc2000.c b/drivers/mtd/devices/doc2000.c
index 5fc532895a24..be5e88b3888d 100644
--- a/drivers/mtd/devices/doc2000.c
+++ b/drivers/mtd/devices/doc2000.c
@@ -4,7 +4,7 @@
* (c) 1999 Machine Vision Holdings, Inc.
* (c) 1999, 2000 David Woodhouse <dwmw2@infradead.org>
*
- * $Id: doc2000.c,v 1.66 2005/01/05 18:05:12 dwmw2 Exp $
+ * $Id: doc2000.c,v 1.67 2005/11/07 11:14:24 gleixner Exp $
*/
#include <linux/kernel.h>
@@ -58,7 +58,7 @@ static int doc_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,
size_t *retlen, u_char *buf, u_char *eccbuf, struct nand_oobinfo *oobsel);
static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
size_t *retlen, const u_char *buf, u_char *eccbuf, struct nand_oobinfo *oobsel);
-static int doc_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs,
+static int doc_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs,
unsigned long count, loff_t to, size_t *retlen,
u_char *eccbuf, struct nand_oobinfo *oobsel);
static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
@@ -76,14 +76,14 @@ static void DoC_Delay(struct DiskOnChip *doc, unsigned short cycles)
{
volatile char dummy;
int i;
-
+
for (i = 0; i < cycles; i++) {
if (DoC_is_Millennium(doc))
dummy = ReadDOC(doc->virtadr, NOP);
else
dummy = ReadDOC(doc->virtadr, DOCStatus);
}
-
+
}
/* DOC_WaitReady: Wait for RDY line to be asserted by the flash chip */
@@ -220,8 +220,8 @@ static int DoC_Address(struct DiskOnChip *doc, int numbytes, unsigned long ofs,
WriteDOC(ofs & 0xff, docptr, WritePipeTerm);
DoC_Delay(doc, 2); /* Needed for some slow flash chips. mf. */
-
- /* FIXME: The SlowIO's for millennium could be replaced by
+
+ /* FIXME: The SlowIO's for millennium could be replaced by
a single WritePipeTerm here. mf. */
/* Lower the ALE line */
@@ -377,9 +377,9 @@ static int DoC_IdentChip(struct DiskOnChip *doc, int floor, int chip)
if (mfr == 0xff || mfr == 0)
return 0;
- /* Check it's the same as the first chip we identified.
+ /* Check it's the same as the first chip we identified.
* M-Systems say that any given DiskOnChip device should only
- * contain _one_ type of flash part, although that's not a
+ * contain _one_ type of flash part, although that's not a
* hardware restriction. */
if (doc->mfr) {
if (doc->mfr == mfr && doc->id == id)
@@ -397,7 +397,7 @@ static int DoC_IdentChip(struct DiskOnChip *doc, int floor, int chip)
for (j = 0; nand_manuf_ids[j].id != 0x0; j++) {
if (nand_manuf_ids[j].id == mfr)
break;
- }
+ }
printk(KERN_INFO
"Flash chip found: Manufacturer ID: %2.2X, "
"Chip ID: %2.2X (%s:%s)\n", mfr, id,
@@ -405,7 +405,7 @@ static int DoC_IdentChip(struct DiskOnChip *doc, int floor, int chip)
if (!doc->mfr) {
doc->mfr = mfr;
doc->id = id;
- doc->chipshift =
+ doc->chipshift =
ffs((nand_flash_ids[i].chipsize << 20)) - 1;
doc->page256 = (nand_flash_ids[i].pagesize == 256) ? 1 : 0;
doc->pageadrlen = doc->chipshift > 25 ? 3 : 2;
@@ -467,7 +467,7 @@ static void DoC_ScanChips(struct DiskOnChip *this, int maxchips)
ret = 0;
- /* Fill out the chip array with {floor, chipno} for each
+ /* Fill out the chip array with {floor, chipno} for each
* detected chip in the device. */
for (floor = 0; floor < MAX_FLOORS; floor++) {
for (chip = 0; chip < numchips[floor]; chip++) {
@@ -757,12 +757,12 @@ static int doc_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,
(long)from, eccbuf[0], eccbuf[1], eccbuf[2],
eccbuf[3], eccbuf[4], eccbuf[5]);
#endif
-
+
/* disable the ECC engine */
WriteDOC(DOC_ECC_DIS, docptr , ECCConf);
}
- /* according to 11.4.1, we need to wait for the busy line
+ /* according to 11.4.1, we need to wait for the busy line
* drop if we read to the end of the page. */
if(0 == ((from + len) & 0x1ff))
{
@@ -941,7 +941,7 @@ static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
/* Let the caller know we completed it */
*retlen += len;
-
+
if (eccbuf) {
unsigned char x[8];
size_t dummy;
@@ -950,10 +950,10 @@ static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
/* Write the ECC data to flash */
for (di=0; di<6; di++)
x[di] = eccbuf[di];
-
+
x[6]=0x55;
x[7]=0x55;
-
+
ret = doc_write_oob_nolock(mtd, to, 8, &dummy, x);
if (ret) {
up(&this->lock);
@@ -970,7 +970,7 @@ static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
return 0;
}
-static int doc_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs,
+static int doc_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs,
unsigned long count, loff_t to, size_t *retlen,
u_char *eccbuf, struct nand_oobinfo *oobsel)
{
@@ -1022,7 +1022,7 @@ static int doc_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs,
break;
to += thislen;
- }
+ }
up(&writev_buf_sem);
*retlen = totretlen;
@@ -1080,7 +1080,7 @@ static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
/* Reading the full OOB data drops us off of the end of the page,
* causing the flash device to go into busy mode, so we need
* to wait until ready 11.4.1 and Toshiba TC58256FT docs */
-
+
ret = DoC_WaitReady(this);
up(&this->lock);
@@ -1190,7 +1190,7 @@ static int doc_write_oob_nolock(struct mtd_info *mtd, loff_t ofs, size_t len,
return 0;
}
-
+
static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
size_t * retlen, const u_char * buf)
{
@@ -1222,7 +1222,7 @@ static int doc_erase(struct mtd_info *mtd, struct erase_info *instr)
}
instr->state = MTD_ERASING;
-
+
/* FIXME: Do this in the background. Use timers or schedule_task() */
while(len) {
mychip = &this->chips[ofs >> this->chipshift];
diff --git a/drivers/mtd/devices/doc2001.c b/drivers/mtd/devices/doc2001.c
index 1e704915ef08..fcb28a6fd89f 100644
--- a/drivers/mtd/devices/doc2001.c
+++ b/drivers/mtd/devices/doc2001.c
@@ -4,7 +4,7 @@
* (c) 1999 Machine Vision Holdings, Inc.
* (c) 1999, 2000 David Woodhouse <dwmw2@infradead.org>
*
- * $Id: doc2001.c,v 1.48 2005/01/05 18:05:12 dwmw2 Exp $
+ * $Id: doc2001.c,v 1.49 2005/11/07 11:14:24 gleixner Exp $
*/
#include <linux/kernel.h>
@@ -196,10 +196,10 @@ static int DoC_IdentChip(struct DiskOnChip *doc, int floor, int chip)
DoC_Command(doc->virtadr, NAND_CMD_RESET, CDSN_CTRL_WP);
DoC_WaitReady(doc->virtadr);
- /* Read the NAND chip ID: 1. Send ReadID command */
+ /* Read the NAND chip ID: 1. Send ReadID command */
DoC_Command(doc->virtadr, NAND_CMD_READID, CDSN_CTRL_WP);
- /* Read the NAND chip ID: 2. Send address byte zero */
+ /* Read the NAND chip ID: 2. Send address byte zero */
DoC_Address(doc->virtadr, 1, 0x00, CDSN_CTRL_WP, 0x00);
/* Read the manufacturer and device id codes of the flash device through
@@ -223,7 +223,7 @@ static int DoC_IdentChip(struct DiskOnChip *doc, int floor, int chip)
for (j = 0; nand_manuf_ids[j].id != 0x0; j++) {
if (nand_manuf_ids[j].id == mfr)
break;
- }
+ }
printk(KERN_INFO "Flash chip found: Manufacturer ID: %2.2X, "
"Chip ID: %2.2X (%s:%s)\n",
mfr, id, nand_manuf_ids[j].name, nand_flash_ids[i].name);
@@ -275,7 +275,7 @@ static void DoC_ScanChips(struct DiskOnChip *this)
return;
}
- /* Fill out the chip array with {floor, chipno} for each
+ /* Fill out the chip array with {floor, chipno} for each
* detected chip in the device. */
for (floor = 0, ret = 0; floor < MAX_FLOORS_MIL; floor++) {
for (chip = 0 ; chip < numchips[floor] ; chip++) {
@@ -309,7 +309,7 @@ static int DoCMil_is_alias(struct DiskOnChip *doc1, struct DiskOnChip *doc2)
tmp2 = ReadDOC(doc2->virtadr, AliasResolution);
if (tmp1 != tmp2)
return 0;
-
+
WriteDOC((tmp1+1) % 0xff, doc1->virtadr, AliasResolution);
tmp2 = ReadDOC(doc2->virtadr, AliasResolution);
if (tmp2 == (tmp1+1) % 0xff)
@@ -425,7 +425,7 @@ static int doc_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
return -EINVAL;
/* Don't allow a single read to cross a 512-byte block boundary */
- if (from + len > ((from | 0x1ff) + 1))
+ if (from + len > ((from | 0x1ff) + 1))
len = ((from | 0x1ff) + 1) - from;
/* Find the chip which is to be used and select it */
@@ -552,7 +552,7 @@ static int doc_write_ecc (struct mtd_info *mtd, loff_t to, size_t len,
#if 0
/* Don't allow a single write to cross a 512-byte block boundary */
- if (to + len > ( (to | 0x1ff) + 1))
+ if (to + len > ( (to | 0x1ff) + 1))
len = ((to | 0x1ff) + 1) - to;
#else
/* Don't allow writes which aren't exactly one block */
@@ -632,7 +632,7 @@ static int doc_write_ecc (struct mtd_info *mtd, loff_t to, size_t len,
/* write the block status BLOCK_USED (0x5555) at the end of ECC data
FIXME: this is only a hack for programming the IPL area for LinuxBIOS
- and should be replace with proper codes in user space utilities */
+ and should be replace with proper codes in user space utilities */
WriteDOC(0x55, docptr, Mil_CDSN_IO);
WriteDOC(0x55, docptr, Mil_CDSN_IO + 1);
@@ -802,7 +802,7 @@ int doc_erase (struct mtd_info *mtd, struct erase_info *instr)
void __iomem *docptr = this->virtadr;
struct Nand *mychip = &this->chips[ofs >> this->chipshift];
- if (len != mtd->erasesize)
+ if (len != mtd->erasesize)
printk(KERN_WARNING "Erase not right size (%x != %x)n",
len, mtd->erasesize);
@@ -870,9 +870,9 @@ static void __exit cleanup_doc2001(void)
while ((mtd=docmillist)) {
this = mtd->priv;
docmillist = this->nextdoc;
-
+
del_mtd_device(mtd);
-
+
iounmap(this->virtadr);
kfree(this->chips);
kfree(mtd);
diff --git a/drivers/mtd/devices/doc2001plus.c b/drivers/mtd/devices/doc2001plus.c
index ed47bafb2ce2..0595cc7324b2 100644
--- a/drivers/mtd/devices/doc2001plus.c
+++ b/drivers/mtd/devices/doc2001plus.c
@@ -6,7 +6,7 @@
* (c) 1999 Machine Vision Holdings, Inc.
* (c) 1999, 2000 David Woodhouse <dwmw2@infradead.org>
*
- * $Id: doc2001plus.c,v 1.13 2005/01/05 18:05:12 dwmw2 Exp $
+ * $Id: doc2001plus.c,v 1.14 2005/11/07 11:14:24 gleixner Exp $
*
* Released under GPL
*/
@@ -293,10 +293,10 @@ static int DoC_IdentChip(struct DiskOnChip *doc, int floor, int chip)
DoC_Command(docptr, NAND_CMD_RESET, 0);
DoC_WaitReady(docptr);
- /* Read the NAND chip ID: 1. Send ReadID command */
+ /* Read the NAND chip ID: 1. Send ReadID command */
DoC_Command(docptr, NAND_CMD_READID, 0);
- /* Read the NAND chip ID: 2. Send address byte zero */
+ /* Read the NAND chip ID: 2. Send address byte zero */
DoC_Address(doc, 1, 0x00, 0, 0x00);
WriteDOC(0, docptr, Mplus_FlashControl);
@@ -365,7 +365,7 @@ static void DoC_ScanChips(struct DiskOnChip *this)
this->interleave = 1;
/* Check the ASIC agrees */
- if ( (this->interleave << 2) !=
+ if ( (this->interleave << 2) !=
(ReadDOC(this->virtadr, Mplus_Configuration) & 4)) {
u_char conf = ReadDOC(this->virtadr, Mplus_Configuration);
printk(KERN_NOTICE "Setting DiskOnChip Millennium Plus interleave to %s\n",
@@ -398,7 +398,7 @@ static void DoC_ScanChips(struct DiskOnChip *this)
return;
}
- /* Fill out the chip array with {floor, chipno} for each
+ /* Fill out the chip array with {floor, chipno} for each
* detected chip in the device. */
for (floor = 0, ret = 0; floor < MAX_FLOORS_MPLUS; floor++) {
for (chip = 0 ; chip < numchips[floor] ; chip++) {
@@ -432,7 +432,7 @@ static int DoCMilPlus_is_alias(struct DiskOnChip *doc1, struct DiskOnChip *doc2)
tmp2 = ReadDOC(doc2->virtadr, Mplus_AliasResolution);
if (tmp1 != tmp2)
return 0;
-
+
WriteDOC((tmp1+1) % 0xff, doc1->virtadr, Mplus_AliasResolution);
tmp2 = ReadDOC(doc2->virtadr, Mplus_AliasResolution);
if (tmp2 == (tmp1+1) % 0xff)
@@ -624,7 +624,7 @@ static int doc_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,
return -EINVAL;
/* Don't allow a single read to cross a 512-byte block boundary */
- if (from + len > ((from | 0x1ff) + 1))
+ if (from + len > ((from | 0x1ff) + 1))
len = ((from | 0x1ff) + 1) - from;
DoC_CheckASIC(docptr);
@@ -1066,7 +1066,7 @@ int doc_erase(struct mtd_info *mtd, struct erase_info *instr)
DoC_CheckASIC(docptr);
- if (len != mtd->erasesize)
+ if (len != mtd->erasesize)
printk(KERN_WARNING "MTD: Erase not right size (%x != %x)n",
len, mtd->erasesize);
@@ -1136,9 +1136,9 @@ static void __exit cleanup_doc2001plus(void)
while ((mtd=docmilpluslist)) {
this = mtd->priv;
docmilpluslist = this->nextdoc;
-
+
del_mtd_device(mtd);
-
+
iounmap(this->virtadr);
kfree(this->chips);
kfree(mtd);
diff --git a/drivers/mtd/devices/docecc.c b/drivers/mtd/devices/docecc.c
index 24f670b5a4f3..cd3db72bef96 100644
--- a/drivers/mtd/devices/docecc.c
+++ b/drivers/mtd/devices/docecc.c
@@ -4,10 +4,10 @@
* GNU GPL License. The rest is simply to convert the disk on chip
* syndrom into a standard syndom.
*
- * Author: Fabrice Bellard (fabrice.bellard@netgem.com)
+ * Author: Fabrice Bellard (fabrice.bellard@netgem.com)
* Copyright (C) 2000 Netgem S.A.
*
- * $Id: docecc.c,v 1.5 2003/05/21 15:15:06 dwmw2 Exp $
+ * $Id: docecc.c,v 1.7 2005/11/07 11:14:25 gleixner Exp $
*
* 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
@@ -122,7 +122,7 @@ for(ci=(n)-1;ci >=0;ci--)\
a(0) + a(1) @ + a(2) @^2 + ... + a(m-1) @^(m-1)
we consider the integer "i" whose binary representation with a(0) being LSB
and a(m-1) MSB is (a(0),a(1),...,a(m-1)) and locate the entry
- "index_of[i]". Now, @^index_of[i] is that element whose polynomial
+ "index_of[i]". Now, @^index_of[i] is that element whose polynomial
representation is (a(0),a(1),a(2),...,a(m-1)).
NOTE:
The element alpha_to[2^m-1] = 0 always signifying that the
@@ -130,7 +130,7 @@ for(ci=(n)-1;ci >=0;ci--)\
Similarily, the element index_of[0] = A0 always signifying
that the power of alpha which has the polynomial representation
(0,0,...,0) is "infinity".
-
+
*/
static void
@@ -176,7 +176,7 @@ generate_gf(dtype Alpha_to[NN + 1], dtype Index_of[NN + 1])
* are written back. NOTE! This array must be at least NN-KK elements long.
* The corrected data are written in eras_val[]. They must be xor with the data
* to retrieve the correct data : data[erase_pos[i]] ^= erase_val[i] .
- *
+ *
* First "no_eras" erasures are declared by the calling program. Then, the
* maximum # of errors correctable is t_after_eras = floor((NN-KK-no_eras)/2).
* If the number of channel errors is not greater than "t_after_eras" the
@@ -189,7 +189,7 @@ generate_gf(dtype Alpha_to[NN + 1], dtype Index_of[NN + 1])
* */
static int
eras_dec_rs(dtype Alpha_to[NN + 1], dtype Index_of[NN + 1],
- gf bb[NN - KK + 1], gf eras_val[NN-KK], int eras_pos[NN-KK],
+ gf bb[NN - KK + 1], gf eras_val[NN-KK], int eras_pos[NN-KK],
int no_eras)
{
int deg_lambda, el, deg_omega;
@@ -212,7 +212,7 @@ eras_dec_rs(dtype Alpha_to[NN + 1], dtype Index_of[NN + 1],
count = 0;
goto finish;
}
-
+
for(i=1;i<=NN-KK;i++){
s[i] = bb[0];
}
@@ -220,7 +220,7 @@ eras_dec_rs(dtype Alpha_to[NN + 1], dtype Index_of[NN + 1],
if(bb[j] == 0)
continue;
tmp = Index_of[bb[j]];
-
+
for(i=1;i<=NN-KK;i++)
s[i] ^= Alpha_to[modnn(tmp + (B0+i-1)*PRIM*j)];
}
@@ -234,7 +234,7 @@ eras_dec_rs(dtype Alpha_to[NN + 1], dtype Index_of[NN + 1],
tmp = modnn(tmp + 2 * KK * (B0+i-1)*PRIM);
s[i] = tmp;
}
-
+
CLEAR(&lambda[1],NN-KK);
lambda[0] = 1;
@@ -252,7 +252,7 @@ eras_dec_rs(dtype Alpha_to[NN + 1], dtype Index_of[NN + 1],
#if DEBUG_ECC >= 1
/* Test code that verifies the erasure locator polynomial just constructed
Needed only for decoder debugging. */
-
+
/* find roots of the erasure location polynomial */
for(i=1;i<=no_eras;i++)
reg[i] = Index_of[lambda[i]];
@@ -286,7 +286,7 @@ eras_dec_rs(dtype Alpha_to[NN + 1], dtype Index_of[NN + 1],
}
for(i=0;i<NN-KK+1;i++)
b[i] = Index_of[lambda[i]];
-
+
/*
* Begin Berlekamp-Massey algorithm to determine error+erasure
* locator polynomial
@@ -389,7 +389,7 @@ eras_dec_rs(dtype Alpha_to[NN + 1], dtype Index_of[NN + 1],
omega[i] = Index_of[tmp];
}
omega[NN-KK] = A0;
-
+
/*
* Compute error values in poly-form. num1 = omega(inv(X(l))), num2 =
* inv(X(l))**(B0-1) and den = lambda_pr(inv(X(l))) all in poly-form
@@ -402,7 +402,7 @@ eras_dec_rs(dtype Alpha_to[NN + 1], dtype Index_of[NN + 1],
}
num2 = Alpha_to[modnn(root[j] * (B0 - 1) + NN)];
den = 0;
-
+
/* lambda[i+1] for i even is the formal derivative lambda_pr of lambda[i] */
for (i = min(deg_lambda,NN-KK-1) & ~1; i >= 0; i -=2) {
if(lambda[i+1] != A0)
@@ -436,11 +436,11 @@ eras_dec_rs(dtype Alpha_to[NN + 1], dtype Index_of[NN + 1],
/* The sector bytes are packed into NB_DATA MM bits words */
#define NB_DATA (((SECTOR_SIZE + 1) * 8 + 6) / MM)
-/*
+/*
* Correct the errors in 'sector[]' by using 'ecc1[]' which is the
* content of the feedback shift register applyied to the sector and
* the ECC. Return the number of errors corrected (and correct them in
- * sector), or -1 if error
+ * sector), or -1 if error
*/
int doc_decode_ecc(unsigned char sector[SECTOR_SIZE], unsigned char ecc1[6])
{
@@ -454,7 +454,7 @@ int doc_decode_ecc(unsigned char sector[SECTOR_SIZE], unsigned char ecc1[6])
Alpha_to = kmalloc((NN + 1) * sizeof(dtype), GFP_KERNEL);
if (!Alpha_to)
return -1;
-
+
Index_of = kmalloc((NN + 1) * sizeof(dtype), GFP_KERNEL);
if (!Index_of) {
kfree(Alpha_to);
@@ -470,7 +470,7 @@ int doc_decode_ecc(unsigned char sector[SECTOR_SIZE], unsigned char ecc1[6])
bb[2] = ((ecc1[2] & 0xf0) >> 4) | ((ecc1[3] & 0x3f) << 4);
bb[3] = ((ecc1[3] & 0xc0) >> 6) | ((ecc1[0] & 0xff) << 2);
- nb_errors = eras_dec_rs(Alpha_to, Index_of, bb,
+ nb_errors = eras_dec_rs(Alpha_to, Index_of, bb,
error_val, error_pos, 0);
if (nb_errors <= 0)
goto the_end;
@@ -489,7 +489,7 @@ int doc_decode_ecc(unsigned char sector[SECTOR_SIZE], unsigned char ecc1[6])
can be modified since pos is even */
index = (pos >> 3) ^ 1;
bitpos = pos & 7;
- if ((index >= 0 && index < SECTOR_SIZE) ||
+ if ((index >= 0 && index < SECTOR_SIZE) ||
index == (SECTOR_SIZE + 1)) {
val = error_val[i] >> (2 + bitpos);
parity ^= val;
@@ -500,7 +500,7 @@ int doc_decode_ecc(unsigned char sector[SECTOR_SIZE], unsigned char ecc1[6])
bitpos = (bitpos + 10) & 7;
if (bitpos == 0)
bitpos = 8;
- if ((index >= 0 && index < SECTOR_SIZE) ||
+ if ((index >= 0 && index < SECTOR_SIZE) ||
index == (SECTOR_SIZE + 1)) {
val = error_val[i] << (8 - bitpos);
parity ^= val;
@@ -509,7 +509,7 @@ int doc_decode_ecc(unsigned char sector[SECTOR_SIZE], unsigned char ecc1[6])
}
}
}
-
+
/* use parity to test extra errors */
if ((parity & 0xff) != 0)
nb_errors = -1;
diff --git a/drivers/mtd/devices/docprobe.c b/drivers/mtd/devices/docprobe.c
index 197d67045e1e..13178b9dd00a 100644
--- a/drivers/mtd/devices/docprobe.c
+++ b/drivers/mtd/devices/docprobe.c
@@ -4,22 +4,22 @@
/* (C) 1999 Machine Vision Holdings, Inc. */
/* (C) 1999-2003 David Woodhouse <dwmw2@infradead.org> */
-/* $Id: docprobe.c,v 1.44 2005/01/05 12:40:36 dwmw2 Exp $ */
+/* $Id: docprobe.c,v 1.46 2005/11/07 11:14:25 gleixner Exp $ */
/* DOC_PASSIVE_PROBE:
- In order to ensure that the BIOS checksum is correct at boot time, and
- hence that the onboard BIOS extension gets executed, the DiskOnChip
- goes into reset mode when it is read sequentially: all registers
- return 0xff until the chip is woken up again by writing to the
- DOCControl register.
-
- Unfortunately, this means that the probe for the DiskOnChip is unsafe,
- because one of the first things it does is write to where it thinks
- the DOCControl register should be - which may well be shared memory
- for another device. I've had machines which lock up when this is
- attempted. Hence the possibility to do a passive probe, which will fail
+ In order to ensure that the BIOS checksum is correct at boot time, and
+ hence that the onboard BIOS extension gets executed, the DiskOnChip
+ goes into reset mode when it is read sequentially: all registers
+ return 0xff until the chip is woken up again by writing to the
+ DOCControl register.
+
+ Unfortunately, this means that the probe for the DiskOnChip is unsafe,
+ because one of the first things it does is write to where it thinks
+ the DOCControl register should be - which may well be shared memory
+ for another device. I've had machines which lock up when this is
+ attempted. Hence the possibility to do a passive probe, which will fail
to detect a chip in reset mode, but is at least guaranteed not to lock
the machine.
@@ -33,9 +33,9 @@
The old Millennium-only driver has been retained just in case there
are problems with the new code. If the combined driver doesn't work
- for you, you can try the old one by undefining DOC_SINGLE_DRIVER
+ for you, you can try the old one by undefining DOC_SINGLE_DRIVER
below and also enabling it in your configuration. If this fixes the
- problems, please send a report to the MTD mailing list at
+ problems, please send a report to the MTD mailing list at
<linux-mtd@lists.infradead.org>.
*/
#define DOC_SINGLE_DRIVER
@@ -68,16 +68,16 @@ MODULE_PARM_DESC(doc_config_location, "Physical memory address at which to probe
static unsigned long __initdata doc_locations[] = {
#if defined (__alpha__) || defined(__i386__) || defined(__x86_64__)
#ifdef CONFIG_MTD_DOCPROBE_HIGH
- 0xfffc8000, 0xfffca000, 0xfffcc000, 0xfffce000,
+ 0xfffc8000, 0xfffca000, 0xfffcc000, 0xfffce000,
0xfffd0000, 0xfffd2000, 0xfffd4000, 0xfffd6000,
- 0xfffd8000, 0xfffda000, 0xfffdc000, 0xfffde000,
- 0xfffe0000, 0xfffe2000, 0xfffe4000, 0xfffe6000,
+ 0xfffd8000, 0xfffda000, 0xfffdc000, 0xfffde000,
+ 0xfffe0000, 0xfffe2000, 0xfffe4000, 0xfffe6000,
0xfffe8000, 0xfffea000, 0xfffec000, 0xfffee000,
#else /* CONFIG_MTD_DOCPROBE_HIGH */
- 0xc8000, 0xca000, 0xcc000, 0xce000,
+ 0xc8000, 0xca000, 0xcc000, 0xce000,
0xd0000, 0xd2000, 0xd4000, 0xd6000,
- 0xd8000, 0xda000, 0xdc000, 0xde000,
- 0xe0000, 0xe2000, 0xe4000, 0xe6000,
+ 0xd8000, 0xda000, 0xdc000, 0xde000,
+ 0xe0000, 0xe2000, 0xe4000, 0xe6000,
0xe8000, 0xea000, 0xec000, 0xee000,
#endif /* CONFIG_MTD_DOCPROBE_HIGH */
#elif defined(__PPC__)
@@ -111,35 +111,35 @@ static inline int __init doccheck(void __iomem *potential, unsigned long physadr
return 0;
#endif /* CONFIG_MTD_DOCPROBE_55AA */
-#ifndef DOC_PASSIVE_PROBE
+#ifndef DOC_PASSIVE_PROBE
/* It's not possible to cleanly detect the DiskOnChip - the
* bootup procedure will put the device into reset mode, and
* it's not possible to talk to it without actually writing
* to the DOCControl register. So we store the current contents
* of the DOCControl register's location, in case we later decide
* that it's not a DiskOnChip, and want to put it back how we
- * found it.
+ * found it.
*/
tmp2 = ReadDOC(window, DOCControl);
-
+
/* Reset the DiskOnChip ASIC */
- WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_RESET,
+ WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_RESET,
window, DOCControl);
- WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_RESET,
+ WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_RESET,
window, DOCControl);
-
+
/* Enable the DiskOnChip ASIC */
- WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_NORMAL,
+ WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_NORMAL,
window, DOCControl);
- WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_NORMAL,
+ WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_NORMAL,
window, DOCControl);
-#endif /* !DOC_PASSIVE_PROBE */
+#endif /* !DOC_PASSIVE_PROBE */
/* We need to read the ChipID register four times. For some
newer DiskOnChip 2000 units, the first three reads will
return the DiskOnChip Millennium ident. Don't ask. */
ChipID = ReadDOC(window, ChipID);
-
+
switch (ChipID) {
case DOC_ChipID_Doc2k:
/* Check the TOGGLE bit in the ECC register */
@@ -149,7 +149,7 @@ static inline int __init doccheck(void __iomem *potential, unsigned long physadr
if (tmp != tmpb && tmp == tmpc)
return ChipID;
break;
-
+
case DOC_ChipID_DocMil:
/* Check for the new 2000 with Millennium ASIC */
ReadDOC(window, ChipID);
@@ -164,7 +164,7 @@ static inline int __init doccheck(void __iomem *potential, unsigned long physadr
if (tmp != tmpb && tmp == tmpc)
return ChipID;
break;
-
+
case DOC_ChipID_DocMilPlus16:
case DOC_ChipID_DocMilPlus32:
case 0:
@@ -179,7 +179,7 @@ static inline int __init doccheck(void __iomem *potential, unsigned long physadr
DOC_MODE_BDECT;
WriteDOC(tmp, window, Mplus_DOCControl);
WriteDOC(~tmp, window, Mplus_CtrlConfirm);
-
+
mdelay(1);
/* Enable the DiskOnChip ASIC */
tmp = DOC_MODE_NORMAL | DOC_MODE_MDWREN | DOC_MODE_RST_LAT |
@@ -187,7 +187,7 @@ static inline int __init doccheck(void __iomem *potential, unsigned long physadr
WriteDOC(tmp, window, Mplus_DOCControl);
WriteDOC(~tmp, window, Mplus_CtrlConfirm);
mdelay(1);
-#endif /* !DOC_PASSIVE_PROBE */
+#endif /* !DOC_PASSIVE_PROBE */
ChipID = ReadDOC(window, ChipID);
@@ -227,7 +227,7 @@ static inline int __init doccheck(void __iomem *potential, unsigned long physadr
WriteDOC(tmp2, window, DOCControl);
#endif
return 0;
-}
+}
static int docfound;
@@ -244,10 +244,10 @@ static void __init DoC_Probe(unsigned long physadr)
void (*initroutine)(struct mtd_info *) = NULL;
docptr = ioremap(physadr, DOC_IOREMAP_LEN);
-
+
if (!docptr)
return;
-
+
if ((ChipID = doccheck(docptr, physadr))) {
if (ChipID == DOC_ChipID_Doc2kTSOP) {
/* Remove this at your own peril. The hardware driver works but nothing prevents you from erasing bad blocks */
@@ -263,9 +263,9 @@ static void __init DoC_Probe(unsigned long physadr)
iounmap(docptr);
return;
}
-
+
this = (struct DiskOnChip *)(&mtd[1]);
-
+
memset((char *)mtd,0, sizeof(struct mtd_info));
memset((char *)this, 0, sizeof(struct DiskOnChip));
@@ -281,13 +281,13 @@ static void __init DoC_Probe(unsigned long physadr)
im_funcname = "DoC2k_init";
im_modname = "doc2000";
break;
-
+
case DOC_ChipID_Doc2k:
name="2000";
im_funcname = "DoC2k_init";
im_modname = "doc2000";
break;
-
+
case DOC_ChipID_DocMil:
name="Millennium";
#ifdef DOC_SINGLE_DRIVER
@@ -331,7 +331,7 @@ static void __init DoC_Probe(unsigned long physadr)
static int __init init_doc(void)
{
int i;
-
+
if (doc_config_location) {
printk(KERN_INFO "Using configured DiskOnChip probe address 0x%lx\n", doc_config_location);
DoC_Probe(doc_config_location);
diff --git a/drivers/mtd/devices/lart.c b/drivers/mtd/devices/lart.c
index dfd335e4a2a8..1e876fcb0408 100644
--- a/drivers/mtd/devices/lart.c
+++ b/drivers/mtd/devices/lart.c
@@ -2,7 +2,7 @@
/*
* MTD driver for the 28F160F3 Flash Memory (non-CFI) on LART.
*
- * $Id: lart.c,v 1.7 2004/08/09 13:19:44 dwmw2 Exp $
+ * $Id: lart.c,v 1.9 2005/11/07 11:14:25 gleixner Exp $
*
* Author: Abraham vd Merwe <abraham@2d3d.co.za>
*
@@ -44,6 +44,7 @@
#include <linux/types.h>
#include <linux/init.h>
#include <linux/errno.h>
+#include <linux/string.h>
#include <linux/mtd/mtd.h>
#ifdef HAVE_PARTITIONS
#include <linux/mtd/partitions.h>
@@ -121,7 +122,7 @@ static char module_name[] = "lart";
/*
* The data line mapping on LART is as follows:
- *
+ *
* U2 CPU | U3 CPU
* -------------------
* 0 20 | 0 12
@@ -180,7 +181,7 @@ static char module_name[] = "lart";
(((x) & 0x00004000) >> 13) \
)
-/*
+/*
* The address line mapping on LART is as follows:
*
* U3 CPU | U2 CPU
@@ -203,7 +204,7 @@ static char module_name[] = "lart";
* 12 15 | 12 15
* 13 14 | 13 14
* 14 16 | 14 16
- *
+ *
* MAIN BLOCK BOUNDARY
*
* 15 17 | 15 18
diff --git a/drivers/mtd/devices/phram.c b/drivers/mtd/devices/phram.c
index a423a382095a..e8685ee6c1e4 100644
--- a/drivers/mtd/devices/phram.c
+++ b/drivers/mtd/devices/phram.c
@@ -1,5 +1,5 @@
/**
- * $Id: phram.c,v 1.14 2005/03/07 21:43:38 joern Exp $
+ * $Id: phram.c,v 1.16 2005/11/07 11:14:25 gleixner Exp $
*
* Copyright (c) ???? Jochen Schäuble <psionic@psionic.de>
* Copyright (c) 2003-2004 Jörn Engel <joern@wh.fh-wedel.de>
@@ -22,6 +22,7 @@
#include <linux/list.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
+#include <linux/slab.h>
#include <linux/mtd/mtd.h>
#define ERROR(fmt, args...) printk(KERN_ERR "phram: " fmt , ## args)
@@ -40,10 +41,10 @@ static int phram_erase(struct mtd_info *mtd, struct erase_info *instr)
if (instr->addr + instr->len > mtd->size)
return -EINVAL;
-
+
memset(start + instr->addr, 0xff, instr->len);
- /* This'll catch a few races. Free the thing before returning :)
+ /* This'll catch a few races. Free the thing before returning :)
* I don't feel at all ashamed. This kind of thing is possible anyway
* with flash, but unlikely.
*/
@@ -62,7 +63,7 @@ static int phram_point(struct mtd_info *mtd, loff_t from, size_t len,
if (from + len > mtd->size)
return -EINVAL;
-
+
*mtdbuf = start + from;
*retlen = len;
return 0;
@@ -83,7 +84,7 @@ static int phram_read(struct mtd_info *mtd, loff_t from, size_t len,
if (len > mtd->size - from)
len = mtd->size - from;
-
+
memcpy(buf, start + from, len);
*retlen = len;
@@ -100,7 +101,7 @@ static int phram_write(struct mtd_info *mtd, loff_t to, size_t len,
if (len > mtd->size - to)
len = mtd->size - to;
-
+
memcpy(start + to, buf, len);
*retlen = len;
@@ -158,7 +159,7 @@ static int register_device(char *name, unsigned long start, unsigned long len)
}
list_add_tail(&new->list, &phram_list);
- return 0;
+ return 0;
out2:
iounmap(new->mtd.priv);
diff --git a/drivers/mtd/devices/pmc551.c b/drivers/mtd/devices/pmc551.c
index 5b3defadf884..666cce1bf60c 100644
--- a/drivers/mtd/devices/pmc551.c
+++ b/drivers/mtd/devices/pmc551.c
@@ -1,5 +1,5 @@
/*
- * $Id: pmc551.c,v 1.30 2005/01/05 18:05:13 dwmw2 Exp $
+ * $Id: pmc551.c,v 1.32 2005/11/07 11:14:25 gleixner Exp $
*
* PMC551 PCI Mezzanine Ram Device
*
@@ -27,7 +27,7 @@
* it as high speed swap or for a high speed disk device of some
* sort. Which becomes very useful on diskless systems in the
* embedded market I might add.
- *
+ *
* Notes:
* Due to what I assume is more buggy SROM, the 64M PMC551 I
* have available claims that all 4 of it's DRAM banks have 64M
@@ -63,10 +63,10 @@
* Minyard set up the card to utilize a 1M sliding apature.
*
* Corey Minyard <minyard@nortelnetworks.com>
- * * Modified driver to utilize a sliding aperture instead of
+ * * Modified driver to utilize a sliding aperture instead of
* mapping all memory into kernel space which turned out to
* be very wasteful.
- * * Located a bug in the SROM's initialization sequence that
+ * * Located a bug in the SROM's initialization sequence that
* made the memory unusable, added a fix to code to touch up
* the DRAM some.
*
@@ -82,7 +82,6 @@
* * Comb the init routine. It's still a bit cludgy on a few things.
*/
-#include <linux/version.h>
#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/module.h>
@@ -390,7 +389,7 @@ static u32 fixup_pmc551 (struct pci_dev *dev)
bcmd |= (0x40|0x20);
pci_write_config_byte(dev, PMC551_SYS_CTRL_REG, bcmd);
- /*
+ /*
* Take care and turn off the memory on the device while we
* tweak the configurations
*/
@@ -408,7 +407,7 @@ static u32 fixup_pmc551 (struct pci_dev *dev)
* Grab old BAR0 config so that we can figure out memory size
* This is another bit of kludge going on. The reason for the
* redundancy is I am hoping to retain the original configuration
- * previously assigned to the card by the BIOS or some previous
+ * previously assigned to the card by the BIOS or some previous
* fixup routine in the kernel. So we read the old config into cfg,
* then write all 1's to the memory space, read back the result into
* "size", and then write back all the old config.
@@ -480,7 +479,7 @@ static u32 fixup_pmc551 (struct pci_dev *dev)
} while ( (PCI_COMMAND_IO) & cmd );
/*
- * Turn on auto refresh
+ * Turn on auto refresh
* The loop is taken directly from Ramix's example code. I assume that
* this must be held high for some duration of time, but I can find no
* documentation refrencing the reasons why.
@@ -615,7 +614,7 @@ static u32 fixup_pmc551 (struct pci_dev *dev)
pci_read_config_byte(dev, PMC551_SYS_CTRL_REG, &bcmd );
printk( KERN_DEBUG "pmc551: EEPROM is under %s control\n"
"pmc551: System Control Register is %slocked to PCI access\n"
- "pmc551: System Control Register is %slocked to EEPROM access\n",
+ "pmc551: System Control Register is %slocked to EEPROM access\n",
(bcmd&0x1)?"software":"hardware",
(bcmd&0x20)?"":"un", (bcmd&0x40)?"":"un");
#endif
@@ -744,7 +743,7 @@ static int __init init_pmc551(void)
priv->start = ioremap(((PCI_Device->resource[0].start)
& PCI_BASE_ADDRESS_MEM_MASK),
priv->asize);
-
+
if (!priv->start) {
printk(KERN_NOTICE "pmc551: Unable to map IO space\n");
kfree(mtd->priv);
@@ -765,7 +764,7 @@ static int __init init_pmc551(void)
priv->curr_map0 );
#ifdef CONFIG_MTD_PMC551_DEBUG
- printk( KERN_DEBUG "pmc551: aperture set to %d\n",
+ printk( KERN_DEBUG "pmc551: aperture set to %d\n",
(priv->base_map0 & 0xF0)>>4 );
#endif
@@ -823,13 +822,13 @@ static void __exit cleanup_pmc551(void)
while((mtd=pmc551list)) {
priv = mtd->priv;
pmc551list = priv->nextpmc551;
-
+
if(priv->start) {
printk (KERN_DEBUG "pmc551: unmapping %dM starting at 0x%p\n",
priv->asize>>20, priv->start);
iounmap (priv->start);
}
-
+
kfree (mtd->priv);
del_mtd_device (mtd);
kfree (mtd);
diff --git a/drivers/mtd/devices/slram.c b/drivers/mtd/devices/slram.c
index 84fa91392a8c..6faee6c6958c 100644
--- a/drivers/mtd/devices/slram.c
+++ b/drivers/mtd/devices/slram.c
@@ -1,6 +1,6 @@
/*======================================================================
- $Id: slram.c,v 1.34 2005/01/06 21:16:42 jwboyer Exp $
+ $Id: slram.c,v 1.36 2005/11/07 11:14:25 gleixner Exp $
This driver provides a method to access memory not used by the kernel
itself (i.e. if the kernel commandline mem=xxx is used). To actually
@@ -18,14 +18,14 @@
<start>: start of the memory region, decimal or hex (0xabcdef)
<end/offset>: end of the memory region. It's possible to use +0x1234
to specify the offset instead of the absolute address
-
+
NOTE:
With slram it's only possible to map a contigous memory region. Therfore
if there's a device mapped somewhere in the region specified slram will
fail to load (see kernel log if modprobe fails).
-
-
+
Jochen Schaeuble <psionic@psionic.de>
======================================================================*/
@@ -89,10 +89,10 @@ static int slram_erase(struct mtd_info *mtd, struct erase_info *instr)
if (instr->addr + instr->len > mtd->size) {
return(-EINVAL);
}
-
+
memset(priv->start + instr->addr, 0xff, instr->len);
- /* This'll catch a few races. Free the thing before returning :)
+ /* This'll catch a few races. Free the thing before returning :)
* I don't feel at all ashamed. This kind of thing is possible anyway
* with flash, but unlikely.
*/
@@ -170,12 +170,12 @@ static int register_device(char *name, unsigned long start, unsigned long length
}
(*curmtd)->mtdinfo = kmalloc(sizeof(struct mtd_info), GFP_KERNEL);
(*curmtd)->next = NULL;
-
+
if ((*curmtd)->mtdinfo) {
memset((char *)(*curmtd)->mtdinfo, 0, sizeof(struct mtd_info));
(*curmtd)->mtdinfo->priv =
kmalloc(sizeof(slram_priv_t), GFP_KERNEL);
-
+
if (!(*curmtd)->mtdinfo->priv) {
kfree((*curmtd)->mtdinfo);
(*curmtd)->mtdinfo = NULL;
@@ -188,7 +188,7 @@ static int register_device(char *name, unsigned long start, unsigned long length
E("slram: Cannot allocate new MTD device.\n");
return(-ENOMEM);
}
-
+
if (!(((slram_priv_t *)(*curmtd)->mtdinfo->priv)->start =
ioremap(start, length))) {
E("slram: ioremap failed\n");
@@ -223,7 +223,7 @@ static int register_device(char *name, unsigned long start, unsigned long length
T("slram: Mapped from 0x%p to 0x%p\n",
((slram_priv_t *)(*curmtd)->mtdinfo->priv)->start,
((slram_priv_t *)(*curmtd)->mtdinfo->priv)->end);
- return(0);
+ return(0);
}
static void unregister_devices(void)
@@ -256,7 +256,7 @@ static int parse_cmdline(char *devname, char *szstart, char *szlength)
char *buffer;
unsigned long devstart;
unsigned long devlength;
-
+
if ((!devname) || (!szstart) || (!szlength)) {
unregister_devices();
return(-EINVAL);
@@ -264,7 +264,7 @@ static int parse_cmdline(char *devname, char *szstart, char *szlength)
devstart = simple_strtoul(szstart, &buffer, 0);
devstart = handle_unit(devstart, buffer);
-
+
if (*(szlength) != '+') {
devlength = simple_strtoul(szlength, &buffer, 0);
devlength = handle_unit(devlength, buffer) - devstart;
@@ -278,7 +278,7 @@ static int parse_cmdline(char *devname, char *szstart, char *szlength)
E("slram: Illegal start / length parameter.\n");
return(-EINVAL);
}
-
+
if ((devstart = register_device(devname, devstart, devlength))){
unregister_devices();
return((int)devstart);
@@ -335,7 +335,7 @@ static int init_slram(void)
}
#else
int count;
-
+
for (count = 0; (map[count]) && (count < SLRAM_MAX_DEVICES_PARAMS);
count++) {
}
@@ -350,10 +350,10 @@ static int init_slram(void)
if (parse_cmdline(devname, map[i * 3 + 1], map[i * 3 + 2])!=0) {
return(-EINVAL);
}
-
+
}
#endif /* !MODULE */
-
+
return(0);
}
diff --git a/drivers/mtd/ftl.c b/drivers/mtd/ftl.c
index d32c1b3a8ce3..de7e231d6d18 100644
--- a/drivers/mtd/ftl.c
+++ b/drivers/mtd/ftl.c
@@ -1,5 +1,5 @@
/* This version ported to the Linux-MTD system by dwmw2@infradead.org
- * $Id: ftl.c,v 1.55 2005/01/17 13:47:21 hvr Exp $
+ * $Id: ftl.c,v 1.58 2005/11/07 11:14:19 gleixner Exp $
*
* Fixes: Arnaldo Carvalho de Melo <acme@conectiva.com.br>
* - fixes some leaks on failure in build_maps and ftl_notify_add, cleanups
@@ -53,7 +53,7 @@
Use of the FTL format for non-PCMCIA applications may be an
infringement of these patents. For additional information,
contact M-Systems (http://www.m-sys.com) directly.
-
+
======================================================================*/
#include <linux/mtd/blktrans.h>
#include <linux/module.h>
@@ -160,7 +160,7 @@ static void ftl_erase_callback(struct erase_info *done);
Scan_header() checks to see if a memory region contains an FTL
partition. build_maps() reads all the erase unit headers, builds
the erase unit map, and then builds the virtual page map.
-
+
======================================================================*/
static int scan_header(partition_t *part)
@@ -176,10 +176,10 @@ static int scan_header(partition_t *part)
(offset + sizeof(header)) < max_offset;
offset += part->mbd.mtd->erasesize ? : 0x2000) {
- err = part->mbd.mtd->read(part->mbd.mtd, offset, sizeof(header), &ret,
+ err = part->mbd.mtd->read(part->mbd.mtd, offset, sizeof(header), &ret,
(unsigned char *)&header);
-
- if (err)
+
+ if (err)
return err;
if (strcmp(header.DataOrgTuple+3, "FTL100") == 0) break;
@@ -232,10 +232,10 @@ static int build_maps(partition_t *part)
for (i = 0; i < le16_to_cpu(part->header.NumEraseUnits); i++) {
offset = ((i + le16_to_cpu(part->header.FirstPhysicalEUN))
<< part->header.EraseUnitSize);
- ret = part->mbd.mtd->read(part->mbd.mtd, offset, sizeof(header), &retval,
+ ret = part->mbd.mtd->read(part->mbd.mtd, offset, sizeof(header), &retval,
(unsigned char *)&header);
-
- if (ret)
+
+ if (ret)
goto out_XferInfo;
ret = -1;
@@ -274,7 +274,7 @@ static int build_maps(partition_t *part)
"don't add up!\n");
goto out_XferInfo;
}
-
+
/* Set up virtual page map */
blocks = le32_to_cpu(header.FormattedSize) >> header.BlockSize;
part->VirtualBlockMap = vmalloc(blocks * sizeof(u_int32_t));
@@ -296,12 +296,12 @@ static int build_maps(partition_t *part)
part->EUNInfo[i].Free = 0;
part->EUNInfo[i].Deleted = 0;
offset = part->EUNInfo[i].Offset + le32_to_cpu(header.BAMOffset);
-
- ret = part->mbd.mtd->read(part->mbd.mtd, offset,
- part->BlocksPerUnit * sizeof(u_int32_t), &retval,
+
+ ret = part->mbd.mtd->read(part->mbd.mtd, offset,
+ part->BlocksPerUnit * sizeof(u_int32_t), &retval,
(unsigned char *)part->bam_cache);
-
- if (ret)
+
+ if (ret)
goto out_bam_cache;
for (j = 0; j < part->BlocksPerUnit; j++) {
@@ -316,7 +316,7 @@ static int build_maps(partition_t *part)
part->EUNInfo[i].Deleted++;
}
}
-
+
ret = 0;
goto out;
@@ -336,7 +336,7 @@ out:
Erase_xfer() schedules an asynchronous erase operation for a
transfer unit.
-
+
======================================================================*/
static int erase_xfer(partition_t *part,
@@ -351,10 +351,10 @@ static int erase_xfer(partition_t *part,
xfer->state = XFER_ERASING;
/* Is there a free erase slot? Always in MTD. */
-
-
+
+
erase=kmalloc(sizeof(struct erase_info), GFP_KERNEL);
- if (!erase)
+ if (!erase)
return -ENOMEM;
erase->mtd = part->mbd.mtd;
@@ -362,7 +362,7 @@ static int erase_xfer(partition_t *part,
erase->addr = xfer->Offset;
erase->len = 1 << part->header.EraseUnitSize;
erase->priv = (u_long)part;
-
+
ret = part->mbd.mtd->erase(part->mbd.mtd, erase);
if (!ret)
@@ -377,7 +377,7 @@ static int erase_xfer(partition_t *part,
Prepare_xfer() takes a freshly erased transfer unit and gives
it an appropriate header.
-
+
======================================================================*/
static void ftl_erase_callback(struct erase_info *erase)
@@ -385,7 +385,7 @@ static void ftl_erase_callback(struct erase_info *erase)
partition_t *part;
struct xfer_info_t *xfer;
int i;
-
+
/* Look up the transfer unit */
part = (partition_t *)(erase->priv);
@@ -422,7 +422,7 @@ static int prepare_xfer(partition_t *part, int i)
xfer = &part->XferInfo[i];
xfer->state = XFER_FAILED;
-
+
DEBUG(1, "ftl_cs: preparing xfer unit at 0x%x\n", xfer->Offset);
/* Write the transfer unit header */
@@ -446,7 +446,7 @@ static int prepare_xfer(partition_t *part, int i)
for (i = 0; i < nbam; i++, offset += sizeof(u_int32_t)) {
- ret = part->mbd.mtd->write(part->mbd.mtd, offset, sizeof(u_int32_t),
+ ret = part->mbd.mtd->write(part->mbd.mtd, offset, sizeof(u_int32_t),
&retlen, (u_char *)&ctl);
if (ret)
@@ -454,7 +454,7 @@ static int prepare_xfer(partition_t *part, int i)
}
xfer->state = XFER_PREPARED;
return 0;
-
+
} /* prepare_xfer */
/*======================================================================
@@ -466,7 +466,7 @@ static int prepare_xfer(partition_t *part, int i)
All data blocks are copied to the corresponding blocks in the
target unit, so the virtual block map does not need to be
updated.
-
+
======================================================================*/
static int copy_erase_unit(partition_t *part, u_int16_t srcunit,
@@ -486,14 +486,14 @@ static int copy_erase_unit(partition_t *part, u_int16_t srcunit,
xfer = &part->XferInfo[xferunit];
DEBUG(2, "ftl_cs: copying block 0x%x to 0x%x\n",
eun->Offset, xfer->Offset);
-
-
+
+
/* Read current BAM */
if (part->bam_index != srcunit) {
offset = eun->Offset + le32_to_cpu(part->header.BAMOffset);
- ret = part->mbd.mtd->read(part->mbd.mtd, offset,
+ ret = part->mbd.mtd->read(part->mbd.mtd, offset,
part->BlocksPerUnit * sizeof(u_int32_t),
&retlen, (u_char *) (part->bam_cache));
@@ -501,11 +501,11 @@ static int copy_erase_unit(partition_t *part, u_int16_t srcunit,
part->bam_index = 0xffff;
if (ret) {
- printk( KERN_WARNING "ftl: Failed to read BAM cache in copy_erase_unit()!\n");
+ printk( KERN_WARNING "ftl: Failed to read BAM cache in copy_erase_unit()!\n");
return ret;
}
}
-
+
/* Write the LogicalEUN for the transfer unit */
xfer->state = XFER_UNKNOWN;
offset = xfer->Offset + 20; /* Bad! */
@@ -513,12 +513,12 @@ static int copy_erase_unit(partition_t *part, u_int16_t srcunit,
ret = part->mbd.mtd->write(part->mbd.mtd, offset, sizeof(u_int16_t),
&retlen, (u_char *) &unit);
-
+
if (ret) {
printk( KERN_WARNING "ftl: Failed to write back to BAM cache in copy_erase_unit()!\n");
return ret;
}
-
+
/* Copy all data blocks from source unit to transfer unit */
src = eun->Offset; dest = xfer->Offset;
@@ -558,15 +558,15 @@ static int copy_erase_unit(partition_t *part, u_int16_t srcunit,
}
/* Write the BAM to the transfer unit */
- ret = part->mbd.mtd->write(part->mbd.mtd, xfer->Offset + le32_to_cpu(part->header.BAMOffset),
- part->BlocksPerUnit * sizeof(int32_t), &retlen,
+ ret = part->mbd.mtd->write(part->mbd.mtd, xfer->Offset + le32_to_cpu(part->header.BAMOffset),
+ part->BlocksPerUnit * sizeof(int32_t), &retlen,
(u_char *)part->bam_cache);
if (ret) {
printk( KERN_WARNING "ftl: Error writing BAM in copy_erase_unit\n");
return ret;
}
-
+
/* All clear? Then update the LogicalEUN again */
ret = part->mbd.mtd->write(part->mbd.mtd, xfer->Offset + 20, sizeof(u_int16_t),
&retlen, (u_char *)&srcunitswap);
@@ -574,9 +574,9 @@ static int copy_erase_unit(partition_t *part, u_int16_t srcunit,
if (ret) {
printk(KERN_WARNING "ftl: Error writing new LogicalEUN in copy_erase_unit\n");
return ret;
- }
-
-
+ }
+
+
/* Update the maps and usage stats*/
i = xfer->EraseCount;
xfer->EraseCount = eun->EraseCount;
@@ -588,10 +588,10 @@ static int copy_erase_unit(partition_t *part, u_int16_t srcunit,
part->FreeTotal += free;
eun->Free = free;
eun->Deleted = 0;
-
+
/* Now, the cache should be valid for the new block */
part->bam_index = srcunit;
-
+
return 0;
} /* copy_erase_unit */
@@ -608,7 +608,7 @@ static int copy_erase_unit(partition_t *part, u_int16_t srcunit,
oldest data unit instead. This means that we generally postpone
the next reclaimation as long as possible, but shuffle static
stuff around a bit for wear leveling.
-
+
======================================================================*/
static int reclaim_block(partition_t *part)
@@ -666,7 +666,7 @@ static int reclaim_block(partition_t *part)
else
DEBUG(1, "ftl_cs: reclaim failed: no "
"suitable transfer units!\n");
-
+
return -EIO;
}
}
@@ -715,7 +715,7 @@ static int reclaim_block(partition_t *part)
returns the block index -- the erase unit is just the currently
cached unit. If there are no free blocks, it returns 0 -- this
is never a valid data block because it contains the header.
-
+
======================================================================*/
#ifdef PSYCHO_DEBUG
@@ -737,7 +737,7 @@ static u_int32_t find_free(partition_t *part)
u_int32_t blk;
size_t retlen;
int ret;
-
+
/* Find an erase unit with some free space */
stop = (part->bam_index == 0xffff) ? 0 : part->bam_index;
eun = stop;
@@ -749,17 +749,17 @@ static u_int32_t find_free(partition_t *part)
if (part->EUNInfo[eun].Free == 0)
return 0;
-
+
/* Is this unit's BAM cached? */
if (eun != part->bam_index) {
/* Invalidate cache */
part->bam_index = 0xffff;
- ret = part->mbd.mtd->read(part->mbd.mtd,
+ ret = part->mbd.mtd->read(part->mbd.mtd,
part->EUNInfo[eun].Offset + le32_to_cpu(part->header.BAMOffset),
part->BlocksPerUnit * sizeof(u_int32_t),
&retlen, (u_char *) (part->bam_cache));
-
+
if (ret) {
printk(KERN_WARNING"ftl: Error reading BAM in find_free\n");
return 0;
@@ -781,14 +781,14 @@ static u_int32_t find_free(partition_t *part)
}
DEBUG(2, "ftl_cs: found free block at %d in %d\n", blk, eun);
return blk;
-
+
} /* find_free */
/*======================================================================
Read a series of sectors from an FTL partition.
-
+
======================================================================*/
static int ftl_read(partition_t *part, caddr_t buffer,
@@ -798,7 +798,7 @@ static int ftl_read(partition_t *part, caddr_t buffer,
u_long i;
int ret;
size_t offset, retlen;
-
+
DEBUG(2, "ftl_cs: ftl_read(0x%p, 0x%lx, %ld)\n",
part, sector, nblocks);
if (!(part->state & FTL_FORMATTED)) {
@@ -834,7 +834,7 @@ static int ftl_read(partition_t *part, caddr_t buffer,
/*======================================================================
Write a series of sectors to an FTL partition
-
+
======================================================================*/
static int set_bam_entry(partition_t *part, u_int32_t log_addr,
@@ -855,7 +855,7 @@ static int set_bam_entry(partition_t *part, u_int32_t log_addr,
blk = (log_addr % bsize) / SECTOR_SIZE;
offset = (part->EUNInfo[eun].Offset + blk * sizeof(u_int32_t) +
le32_to_cpu(part->header.BAMOffset));
-
+
#ifdef PSYCHO_DEBUG
ret = part->mbd.mtd->read(part->mbd.mtd, offset, sizeof(u_int32_t),
&retlen, (u_char *)&old_addr);
@@ -925,7 +925,7 @@ static int ftl_write(partition_t *part, caddr_t buffer,
if (ret)
return ret;
}
-
+
bsize = 1 << part->header.EraseUnitSize;
virt_addr = sector * SECTOR_SIZE | BLOCK_DATA;
@@ -949,12 +949,12 @@ static int ftl_write(partition_t *part, caddr_t buffer,
log_addr = part->bam_index * bsize + blk * SECTOR_SIZE;
part->EUNInfo[part->bam_index].Free--;
part->FreeTotal--;
- if (set_bam_entry(part, log_addr, 0xfffffffe))
+ if (set_bam_entry(part, log_addr, 0xfffffffe))
return -EIO;
part->EUNInfo[part->bam_index].Deleted++;
offset = (part->EUNInfo[part->bam_index].Offset +
blk * SECTOR_SIZE);
- ret = part->mbd.mtd->write(part->mbd.mtd, offset, SECTOR_SIZE, &retlen,
+ ret = part->mbd.mtd->write(part->mbd.mtd, offset, SECTOR_SIZE, &retlen,
buffer);
if (ret) {
@@ -964,7 +964,7 @@ static int ftl_write(partition_t *part, caddr_t buffer,
offset);
return -EIO;
}
-
+
/* Only delete the old entry when the new entry is ready */
old_addr = part->VirtualBlockMap[sector+i];
if (old_addr != 0xffffffff) {
@@ -979,7 +979,7 @@ static int ftl_write(partition_t *part, caddr_t buffer,
return -EIO;
part->VirtualBlockMap[sector+i] = log_addr;
part->EUNInfo[part->bam_index].Deleted--;
-
+
buffer += SECTOR_SIZE;
virt_addr += SECTOR_SIZE;
}
@@ -1034,20 +1034,20 @@ static void ftl_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
partition_t *partition;
partition = kmalloc(sizeof(partition_t), GFP_KERNEL);
-
+
if (!partition) {
printk(KERN_WARNING "No memory to scan for FTL on %s\n",
mtd->name);
return;
- }
+ }
memset(partition, 0, sizeof(partition_t));
partition->mbd.mtd = mtd;
- if ((scan_header(partition) == 0) &&
+ if ((scan_header(partition) == 0) &&
(build_maps(partition) == 0)) {
-
+
partition->state = FTL_FORMATTED;
#ifdef PCMCIA_DEBUG
printk(KERN_INFO "ftl_cs: opening %d KiB FTL partition\n",
@@ -1086,7 +1086,7 @@ struct mtd_blktrans_ops ftl_tr = {
int init_ftl(void)
{
- DEBUG(0, "$Id: ftl.c,v 1.55 2005/01/17 13:47:21 hvr Exp $\n");
+ DEBUG(0, "$Id: ftl.c,v 1.58 2005/11/07 11:14:19 gleixner Exp $\n");
return register_mtd_blktrans(&ftl_tr);
}
diff --git a/drivers/mtd/inftlcore.c b/drivers/mtd/inftlcore.c
index 39eb53f6551f..8a544890173d 100644
--- a/drivers/mtd/inftlcore.c
+++ b/drivers/mtd/inftlcore.c
@@ -1,4 +1,4 @@
-/*
+/*
* inftlcore.c -- Linux driver for Inverse Flash Translation Layer (INFTL)
*
* (C) Copyright 2002, Greg Ungerer (gerg@snapgear.com)
@@ -7,7 +7,7 @@
* (c) 1999 Machine Vision Holdings, Inc.
* Author: David Woodhouse <dwmw2@infradead.org>
*
- * $Id: inftlcore.c,v 1.18 2004/11/16 18:28:59 dwmw2 Exp $
+ * $Id: inftlcore.c,v 1.19 2005/11/07 11:14:20 gleixner Exp $
*
* 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
@@ -113,23 +113,21 @@ static void inftl_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
if (inftl->mbd.size != inftl->heads * inftl->cylinders * inftl->sectors) {
/*
- Oh no we don't have
+ Oh no we don't have
mbd.size == heads * cylinders * sectors
*/
printk(KERN_WARNING "INFTL: cannot calculate a geometry to "
"match size of 0x%lx.\n", inftl->mbd.size);
printk(KERN_WARNING "INFTL: using C:%d H:%d S:%d "
"(== 0x%lx sects)\n",
- inftl->cylinders, inftl->heads , inftl->sectors,
+ inftl->cylinders, inftl->heads , inftl->sectors,
(long)inftl->cylinders * (long)inftl->heads *
(long)inftl->sectors );
}
if (add_mtd_blktrans_dev(&inftl->mbd)) {
- if (inftl->PUtable)
- kfree(inftl->PUtable);
- if (inftl->VUtable)
- kfree(inftl->VUtable);
+ kfree(inftl->PUtable);
+ kfree(inftl->VUtable);
kfree(inftl);
return;
}
@@ -147,10 +145,8 @@ static void inftl_remove_dev(struct mtd_blktrans_dev *dev)
del_mtd_blktrans_dev(dev);
- if (inftl->PUtable)
- kfree(inftl->PUtable);
- if (inftl->VUtable)
- kfree(inftl->VUtable);
+ kfree(inftl->PUtable);
+ kfree(inftl->VUtable);
kfree(inftl);
}
@@ -223,7 +219,7 @@ static u16 INFTL_foldchain(struct INFTLrecord *inftl, unsigned thisVUC, unsigned
"Virtual Unit Chain %d!\n", thisVUC);
return BLOCK_NIL;
}
-
+
/*
* Scan to find the Erase Unit which holds the actual data for each
* 512-byte block within the Chain.
@@ -264,7 +260,7 @@ static u16 INFTL_foldchain(struct INFTLrecord *inftl, unsigned thisVUC, unsigned
"Unit Chain 0x%x\n", thisVUC);
return BLOCK_NIL;
}
-
+
thisEUN = inftl->PUtable[thisEUN];
}
@@ -295,15 +291,15 @@ static u16 INFTL_foldchain(struct INFTLrecord *inftl, unsigned thisVUC, unsigned
*/
if (BlockMap[block] == BLOCK_NIL)
continue;
-
+
ret = MTD_READ(inftl->mbd.mtd, (inftl->EraseSize *
BlockMap[block]) + (block * SECTORSIZE), SECTORSIZE,
- &retlen, movebuf);
+ &retlen, movebuf);
if (ret < 0) {
ret = MTD_READ(inftl->mbd.mtd, (inftl->EraseSize *
BlockMap[block]) + (block * SECTORSIZE),
SECTORSIZE, &retlen, movebuf);
- if (ret != -EIO)
+ if (ret != -EIO)
DEBUG(MTD_DEBUG_LEVEL1, "INFTL: error went "
"away on retry?\n");
}
@@ -355,7 +351,7 @@ static u16 INFTL_foldchain(struct INFTLrecord *inftl, unsigned thisVUC, unsigned
static u16 INFTL_makefreeblock(struct INFTLrecord *inftl, unsigned pendingblock)
{
/*
- * This is the part that needs some cleverness applied.
+ * This is the part that needs some cleverness applied.
* For now, I'm doing the minimum applicable to actually
* get the thing to work.
* Wear-levelling and other clever stuff needs to be implemented
@@ -414,7 +410,7 @@ static int nrbits(unsigned int val, int bitcount)
}
/*
- * INFTL_findwriteunit: Return the unit number into which we can write
+ * INFTL_findwriteunit: Return the unit number into which we can write
* for this block. Make it available if it isn't already.
*/
static inline u16 INFTL_findwriteunit(struct INFTLrecord *inftl, unsigned block)
@@ -463,10 +459,10 @@ static inline u16 INFTL_findwriteunit(struct INFTLrecord *inftl, unsigned block)
* Invalid block. Don't use it any more.
* Must implement.
*/
- break;
+ break;
}
-
- if (!silly--) {
+
+ if (!silly--) {
printk(KERN_WARNING "INFTL: infinite loop in "
"Virtual Unit Chain 0x%x\n", thisVUC);
return 0xffff;
@@ -482,7 +478,7 @@ hitused:
/*
- * OK. We didn't find one in the existing chain, or there
+ * OK. We didn't find one in the existing chain, or there
* is no existing chain. Allocate a new one.
*/
writeEUN = INFTL_findfreeblock(inftl, 0);
@@ -506,8 +502,8 @@ hitused:
if (writeEUN == BLOCK_NIL) {
/*
* Ouch. This should never happen - we should
- * always be able to make some room somehow.
- * If we get here, we've allocated more storage
+ * always be able to make some room somehow.
+ * If we get here, we've allocated more storage
* space than actual media, or our makefreeblock
* routine is missing something.
*/
@@ -518,7 +514,7 @@ hitused:
INFTL_dumpVUchains(inftl);
#endif
return BLOCK_NIL;
- }
+ }
}
/*
@@ -543,7 +539,7 @@ hitused:
parity |= (nrbits(prev_block, 16) & 0x1) ? 0x2 : 0;
parity |= (nrbits(anac, 8) & 0x1) ? 0x4 : 0;
parity |= (nrbits(nacs, 8) & 0x1) ? 0x8 : 0;
-
+
oob.u.a.virtualUnitNo = cpu_to_le16(thisVUC);
oob.u.a.prevUnitNo = cpu_to_le16(prev_block);
oob.u.a.ANAC = anac;
@@ -562,7 +558,7 @@ hitused:
oob.u.b.parityPerField = parity;
oob.u.b.discarded = 0xaa;
- MTD_WRITEOOB(inftl->mbd.mtd, writeEUN * inftl->EraseSize +
+ MTD_WRITEOOB(inftl->mbd.mtd, writeEUN * inftl->EraseSize +
SECTORSIZE * 4 + 8, 8, &retlen, (char *)&oob.u);
inftl->PUtable[writeEUN] = inftl->VUtable[thisVUC];
@@ -602,7 +598,7 @@ static void INFTL_trydeletechain(struct INFTLrecord *inftl, unsigned thisVUC)
"Virtual Unit Chain %d!\n", thisVUC);
return;
}
-
+
/*
* Scan through the Erase Units to determine whether any data is in
* each of the 512-byte blocks within the Chain.
@@ -642,7 +638,7 @@ static void INFTL_trydeletechain(struct INFTLrecord *inftl, unsigned thisVUC)
"Unit Chain 0x%x\n", thisVUC);
return;
}
-
+
thisEUN = inftl->PUtable[thisEUN];
}
@@ -758,7 +754,7 @@ foundit:
return 0;
}
-static int inftl_writeblock(struct mtd_blktrans_dev *mbd, unsigned long block,
+static int inftl_writeblock(struct mtd_blktrans_dev *mbd, unsigned long block,
char *buffer)
{
struct INFTLrecord *inftl = (void *)mbd;
@@ -893,7 +889,7 @@ extern char inftlmountrev[];
static int __init init_inftl(void)
{
- printk(KERN_INFO "INFTL: inftlcore.c $Revision: 1.18 $, "
+ printk(KERN_INFO "INFTL: inftlcore.c $Revision: 1.19 $, "
"inftlmount.c %s\n", inftlmountrev);
return register_mtd_blktrans(&inftl_tr);
diff --git a/drivers/mtd/inftlmount.c b/drivers/mtd/inftlmount.c
index b5dda47395a7..43fdc9433882 100644
--- a/drivers/mtd/inftlmount.c
+++ b/drivers/mtd/inftlmount.c
@@ -1,14 +1,14 @@
-/*
+/*
* inftlmount.c -- INFTL mount code with extensive checks.
*
* Author: Greg Ungerer (gerg@snapgear.com)
* (C) Copyright 2002-2003, Greg Ungerer (gerg@snapgear.com)
*
* Based heavily on the nftlmount.c code which is:
- * Author: Fabrice Bellard (fabrice.bellard@netgem.com)
+ * Author: Fabrice Bellard (fabrice.bellard@netgem.com)
* Copyright (C) 2000 Netgem S.A.
*
- * $Id: inftlmount.c,v 1.16 2004/11/22 13:50:53 kalev Exp $
+ * $Id: inftlmount.c,v 1.18 2005/11/07 11:14:20 gleixner Exp $
*
* 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
@@ -41,7 +41,7 @@
#include <linux/mtd/inftl.h>
#include <linux/mtd/compatmac.h>
-char inftlmountrev[]="$Revision: 1.16 $";
+char inftlmountrev[]="$Revision: 1.18 $";
/*
* find_boot_record: Find the INFTL Media Header and its Spare copy which
@@ -273,7 +273,7 @@ static int find_boot_record(struct INFTLrecord *inftl)
inftl->nb_boot_blocks);
return -1;
}
-
+
inftl->mbd.size = inftl->numvunits *
(inftl->EraseSize / SECTORSIZE);
@@ -302,7 +302,7 @@ static int find_boot_record(struct INFTLrecord *inftl)
inftl->nb_blocks * sizeof(u16));
return -ENOMEM;
}
-
+
/* Mark the blocks before INFTL MediaHeader as reserved */
for (i = 0; i < inftl->nb_boot_blocks; i++)
inftl->PUtable[i] = BLOCK_RESERVED;
@@ -380,7 +380,7 @@ static int check_free_sectors(struct INFTLrecord *inftl, unsigned int address,
*
* Return: 0 when succeed, -1 on error.
*
- * ToDo: 1. Is it neceressary to check_free_sector after erasing ??
+ * ToDo: 1. Is it neceressary to check_free_sector after erasing ??
*/
int INFTL_formatblock(struct INFTLrecord *inftl, int block)
{
@@ -563,7 +563,7 @@ int INFTL_mount(struct INFTLrecord *s)
/* Search for INFTL MediaHeader and Spare INFTL Media Header */
if (find_boot_record(s) < 0) {
printk(KERN_WARNING "INFTL: could not find valid boot record?\n");
- return -1;
+ return -ENXIO;
}
/* Init the logical to physical table */
@@ -574,6 +574,12 @@ int INFTL_mount(struct INFTLrecord *s)
/* Temporary buffer to store ANAC numbers. */
ANACtable = kmalloc(s->nb_blocks * sizeof(u8), GFP_KERNEL);
+ if (!ANACtable) {
+ printk(KERN_WARNING "INFTL: allocation of ANACtable "
+ "failed (%zd bytes)\n",
+ s->nb_blocks * sizeof(u8));
+ return -ENOMEM;
+ }
memset(ANACtable, 0, s->nb_blocks);
/*
@@ -595,7 +601,7 @@ int INFTL_mount(struct INFTLrecord *s)
for (chain_length = 0; ; chain_length++) {
- if ((chain_length == 0) &&
+ if ((chain_length == 0) &&
(s->PUtable[block] != BLOCK_NOTEXPLORED)) {
/* Nothing to do here, onto next block */
break;
@@ -742,7 +748,7 @@ int INFTL_mount(struct INFTLrecord *s)
"in virtual chain %d\n",
s->PUtable[block], logical_block);
s->PUtable[block] = BLOCK_NIL;
-
+
}
if (ANACtable[block] != ANAC) {
/*
diff --git a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig
index 44781a83b2e7..48638c8097a5 100644
--- a/drivers/mtd/maps/Kconfig
+++ b/drivers/mtd/maps/Kconfig
@@ -1,5 +1,5 @@
# drivers/mtd/maps/Kconfig
-# $Id: Kconfig,v 1.55 2005/07/02 01:53:24 tpoynor Exp $
+# $Id: Kconfig,v 1.61 2005/11/07 11:14:26 gleixner Exp $
menu "Mapping drivers for chip access"
depends on MTD!=n
@@ -64,9 +64,9 @@ config MTD_SUN_UFLASH
tristate "Sun Microsystems userflash support"
depends on (SPARC32 || SPARC64) && MTD_CFI
help
- This provides a 'mapping' driver which supports the way in
- which user-programmable flash chips are connected on various
- Sun Microsystems boardsets. This driver will require CFI support
+ This provides a 'mapping' driver which supports the way in
+ which user-programmable flash chips are connected on various
+ Sun Microsystems boardsets. This driver will require CFI support
in the kernel, so if you did not enable CFI previously, do that now.
config MTD_PNC2000
@@ -89,22 +89,22 @@ config MTD_NETSC520
depends on X86 && MTD_CFI && MTD_PARTITIONS
help
This enables access routines for the flash chips on the AMD NetSc520
- demonstration board. If you have one of these boards and would like
+ demonstration board. If you have one of these boards and would like
to use the flash chips on it, say 'Y'.
config MTD_TS5500
tristate "JEDEC Flash device mapped on Technologic Systems TS-5500"
- depends on X86 && MTD_JEDECPROBE && MTD_PARTITIONS
+ depends on ELAN
+ select MTD_PARTITIONS
+ select MTD_JEDECPROBE
+ select MTD_CFI_AMDSTD
help
This provides a driver for the on-board flash of the Technologic
- System's TS-5500 board. The flash is split into 3 partitions
+ System's TS-5500 board. The 2MB flash is split into 3 partitions
which are accessed as separate MTD devices.
- mtd0 and mtd2 are the two BIOS drives. Unfortunately the BIOS
- uses a proprietary flash translation layer from General Software,
- which is not supported (the drives cannot be mounted). You can
- create your own file system (jffs for example), but the BIOS
- won't be able to boot from it.
+ mtd0 and mtd2 are the two BIOS drives, which use the resident
+ flash disk (RFD) flash translation layer.
mtd1 allows you to reprogram your BIOS. BE VERY CAREFUL.
@@ -212,11 +212,18 @@ config MTD_NETtel
Support for flash chips on NETtel/SecureEdge/SnapGear boards.
config MTD_ALCHEMY
- tristate ' AMD Alchemy Pb1xxx/Db1xxx/RDK MTD support'
- depends on MIPS && SOC_AU1X00
+ tristate ' AMD Alchemy Pb1xxx/Db1xxx/RDK MTD support'
+ depends on SOC_AU1X00
help
Flash memory access on AMD Alchemy Pb/Db/RDK Reference Boards
+config MTD_MTX1
+ tristate "4G Systems MTX-1 Flash device"
+ depends on MIPS && MIPS_MTX1
+ help
+ Flash memory access on 4G Systems MTX-1 Board. If you have one of
+ these boards and would like to use the flash chips on it, say 'Y'.
+
config MTD_DILNETPC
tristate "CFI Flash device mapped on DIL/Net PC"
depends on X86 && MTD_CONCAT && MTD_PARTITIONS && MTD_CFI_INTELEXT
@@ -244,14 +251,14 @@ config MTD_L440GX
config MTD_SBC8240
tristate "Flash device on SBC8240"
- depends on PPC32 && MTD_JEDECPROBE && 6xx && 8260
+ depends on MTD_JEDECPROBE && 8260
help
Flash access on the SBC8240 board from Wind River. See
<http://www.windriver.com/products/sbc8240/>
config MTD_TQM8XXL
tristate "CFI Flash device mapped on TQM8XXL"
- depends on MTD_CFI && PPC32 && 8xx && TQM8xxL
+ depends on MTD_CFI && TQM8xxL
help
The TQM8xxL PowerPC board has up to two banks of CFI-compliant
chips, currently uses AMD one. This 'mapping' driver supports
@@ -261,7 +268,7 @@ config MTD_TQM8XXL
config MTD_RPXLITE
tristate "CFI Flash device mapped on RPX Lite or CLLF"
- depends on MTD_CFI && PPC32 && 8xx && (RPXCLASSIC || RPXLITE)
+ depends on MTD_CFI && (RPXCLASSIC || RPXLITE)
help
The RPXLite PowerPC board has CFI-compliant chips mapped in
a strange sparse mapping. This 'mapping' driver supports that
@@ -271,7 +278,7 @@ config MTD_RPXLITE
config MTD_MBX860
tristate "System flash on MBX860 board"
- depends on MTD_CFI && PPC32 && 8xx && MBX
+ depends on MTD_CFI && MBX
help
This enables access routines for the flash chips on the Motorola
MBX860 board. If you have one of these boards and would like
@@ -279,7 +286,7 @@ config MTD_MBX860
config MTD_DBOX2
tristate "CFI Flash device mapped on D-Box2"
- depends on PPC32 && 8xx && DBOX2 && MTD_CFI_INTELSTD && MTD_CFI_INTELEXT && MTD_CFI_AMDSTD
+ depends on DBOX2 && MTD_CFI_INTELSTD && MTD_CFI_INTELEXT && MTD_CFI_AMDSTD
help
This enables access routines for the flash chips on the Nokia/Sagem
D-Box 2 board. If you have one of these boards and would like to use
@@ -287,14 +294,14 @@ config MTD_DBOX2
config MTD_CFI_FLAGADM
tristate "CFI Flash device mapping on FlagaDM"
- depends on PPC32 && 8xx && MTD_CFI
+ depends on 8xx && MTD_CFI
help
Mapping for the Flaga digital module. If you don't have one, ignore
this setting.
config MTD_BEECH
tristate "CFI Flash device mapped on IBM 405LP Beech"
- depends on MTD_CFI && PPC32 && 40x && BEECH
+ depends on MTD_CFI && BEECH
help
This enables access routines for the flash chips on the IBM
405LP Beech board. If you have one of these boards and would like
@@ -302,7 +309,7 @@ config MTD_BEECH
config MTD_ARCTIC
tristate "CFI Flash device mapped on IBM 405LP Arctic"
- depends on MTD_CFI && PPC32 && 40x && ARCTIC2
+ depends on MTD_CFI && ARCTIC2
help
This enables access routines for the flash chips on the IBM 405LP
Arctic board. If you have one of these boards and would like to
@@ -310,7 +317,7 @@ config MTD_ARCTIC
config MTD_WALNUT
tristate "Flash device mapped on IBM 405GP Walnut"
- depends on MTD_JEDECPROBE && PPC32 && 40x && WALNUT
+ depends on MTD_JEDECPROBE && WALNUT
help
This enables access routines for the flash chips on the IBM 405GP
Walnut board. If you have one of these boards and would like to
@@ -318,7 +325,7 @@ config MTD_WALNUT
config MTD_EBONY
tristate "Flash devices mapped on IBM 440GP Ebony"
- depends on MTD_JEDECPROBE && PPC32 && 44x && EBONY
+ depends on MTD_JEDECPROBE && EBONY
help
This enables access routines for the flash chips on the IBM 440GP
Ebony board. If you have one of these boards and would like to
@@ -326,7 +333,7 @@ config MTD_EBONY
config MTD_OCOTEA
tristate "Flash devices mapped on IBM 440GX Ocotea"
- depends on MTD_CFI && PPC32 && 44x && OCOTEA
+ depends on MTD_CFI && OCOTEA
help
This enables access routines for the flash chips on the IBM 440GX
Ocotea board. If you have one of these boards and would like to
@@ -334,12 +341,20 @@ config MTD_OCOTEA
config MTD_REDWOOD
tristate "CFI Flash devices mapped on IBM Redwood"
- depends on MTD_CFI && PPC32 && 4xx && 40x && ( REDWOOD_4 || REDWOOD_5 || REDWOOD_6 )
+ depends on MTD_CFI && ( REDWOOD_4 || REDWOOD_5 || REDWOOD_6 )
help
This enables access routines for the flash chips on the IBM
Redwood board. If you have one of these boards and would like to
use the flash chips on it, say 'Y'.
+config MTD_TQM834x
+ tristate "Flash device mapped on TQ Components TQM834x Boards"
+ depends on MTD_CFI && TQM834x
+ help
+ This enables access routines for the flash chips on the
+ TQ Components TQM834x boards. If you have one of these boards
+ and would like to use the flash chips on it, say 'Y'.
+
config MTD_CSTM_MIPS_IXX
tristate "Flash chip mapping on ITE QED-4N-S01B, Globespan IVR or custom board"
depends on MIPS && MTD_CFI && MTD_JEDECPROBE && MTD_PARTITIONS
@@ -362,8 +377,8 @@ config MTD_CSTM_MIPS_IXX_START
default "0x8000000"
help
This is the physical memory location that the MTD driver will
- use for the flash chips on your particular target board.
- Refer to the memory map which should hopefully be in the
+ use for the flash chips on your particular target board.
+ Refer to the memory map which should hopefully be in the
documentation for your board.
config MTD_CSTM_MIPS_IXX_LEN
@@ -371,7 +386,7 @@ config MTD_CSTM_MIPS_IXX_LEN
depends on MTD_CSTM_MIPS_IXX
default "0x4000000"
help
- This is the total length that the MTD driver will use for the
+ This is the total length that the MTD driver will use for the
flash chips on your particular board. Refer to the memory
map which should hopefully be in the documentation for your
board.
@@ -405,14 +420,14 @@ config MTD_ARM_INTEGRATOR
config MTD_CDB89712
tristate "Cirrus CDB89712 evaluation board mappings"
- depends on ARM && MTD_CFI && ARCH_CDB89712
+ depends on MTD_CFI && ARCH_CDB89712
help
This enables access to the flash or ROM chips on the CDB89712 board.
If you have such a board, say 'Y'.
config MTD_SA1100
tristate "CFI Flash device mapped on StrongARM SA11x0"
- depends on ARM && MTD_CFI && ARCH_SA1100 && MTD_PARTITIONS
+ depends on MTD_CFI && ARCH_SA1100 && MTD_PARTITIONS
help
This enables access to the flash chips on most platforms based on
the SA1100 and SA1110, including the Assabet and the Compaq iPAQ.
@@ -420,13 +435,13 @@ config MTD_SA1100
config MTD_IPAQ
tristate "CFI Flash device mapped on Compaq/HP iPAQ"
- depends on ARM && IPAQ_HANDHELD && MTD_CFI
+ depends on IPAQ_HANDHELD && MTD_CFI
help
This provides a driver for the on-board flash of the iPAQ.
config MTD_DC21285
tristate "CFI Flash device mapped on DC21285 Footbridge"
- depends on ARM && MTD_CFI && ARCH_FOOTBRIDGE && MTD_COMPLEX_MAPPINGS
+ depends on MTD_CFI && ARCH_FOOTBRIDGE && MTD_COMPLEX_MAPPINGS
help
This provides a driver for the flash accessed using Intel's
21285 bridge used with Intel's StrongARM processors. More info at
@@ -434,33 +449,33 @@ config MTD_DC21285
config MTD_IQ80310
tristate "CFI Flash device mapped on the XScale IQ80310 board"
- depends on ARM && MTD_CFI && ARCH_IQ80310
+ depends on MTD_CFI && ARCH_IQ80310
help
This enables access routines for the flash chips on the Intel XScale
- IQ80310 evaluation board. If you have one of these boards and would
+ IQ80310 evaluation board. If you have one of these boards and would
like to use the flash chips on it, say 'Y'.
config MTD_IXP4XX
tristate "CFI Flash device mapped on Intel IXP4xx based systems"
- depends on ARM && MTD_CFI && MTD_COMPLEX_MAPPINGS && ARCH_IXP4XX
+ depends on MTD_CFI && MTD_COMPLEX_MAPPINGS && ARCH_IXP4XX
help
- This enables MTD access to flash devices on platforms based
+ This enables MTD access to flash devices on platforms based
on Intel's IXP4xx family of network processors such as the
IXDP425 and Coyote. If you have an IXP4xx based board and
would like to use the flash chips on it, say 'Y'.
config MTD_IXP2000
tristate "CFI Flash device mapped on Intel IXP2000 based systems"
- depends on ARM && MTD_CFI && MTD_COMPLEX_MAPPINGS && ARCH_IXP2000
+ depends on MTD_CFI && MTD_COMPLEX_MAPPINGS && ARCH_IXP2000
help
- This enables MTD access to flash devices on platforms based
+ This enables MTD access to flash devices on platforms based
on Intel's IXP2000 family of network processors such as the
IXDP425 and Coyote. If you have an IXP2000 based board and
would like to use the flash chips on it, say 'Y'.
config MTD_EPXA10DB
tristate "CFI Flash device mapped on Epxa10db"
- depends on ARM && MTD_CFI && MTD_PARTITIONS && ARCH_CAMELOT
+ depends on MTD_CFI && MTD_PARTITIONS && ARCH_CAMELOT
help
This enables support for the flash devices on the Altera
Excalibur XA10 Development Board. If you are building a kernel
@@ -468,21 +483,21 @@ config MTD_EPXA10DB
config MTD_FORTUNET
tristate "CFI Flash device mapped on the FortuNet board"
- depends on ARM && MTD_CFI && MTD_PARTITIONS && SA1100_FORTUNET
+ depends on MTD_CFI && MTD_PARTITIONS && SA1100_FORTUNET
help
This enables access to the Flash on the FortuNet board. If you
have such a board, say 'Y'.
config MTD_AUTCPU12
tristate "NV-RAM mapping AUTCPU12 board"
- depends on ARM && ARCH_AUTCPU12
+ depends on ARCH_AUTCPU12
help
This enables access to the NV-RAM on autronix autcpu12 board.
If you have such a board, say 'Y'.
config MTD_EDB7312
tristate "CFI Flash device mapped on EDB7312"
- depends on ARM && MTD_CFI
+ depends on ARCH_EDB7312 && MTD_CFI
help
This enables access to the CFI Flash on the Cogent EDB7312 board.
If you have such a board, say 'Y' here.
@@ -496,7 +511,7 @@ config MTD_IMPA7
config MTD_CEIVA
tristate "JEDEC Flash device mapped on Ceiva/Polaroid PhotoMax Digital Picture Frame"
- depends on ARM && MTD_JEDECPROBE && ARCH_CEIVA
+ depends on MTD_JEDECPROBE && ARCH_CEIVA
help
This enables access to the flash chips on the Ceiva/Polaroid
PhotoMax Digital Picture Frame.
@@ -504,25 +519,31 @@ config MTD_CEIVA
config MTD_NOR_TOTO
tristate "NOR Flash device on TOTO board"
- depends on ARM && ARCH_OMAP && OMAP_TOTO
+ depends on ARCH_OMAP && OMAP_TOTO
help
This enables access to the NOR flash on the Texas Instruments
TOTO board.
config MTD_H720X
tristate "Hynix evaluation board mappings"
- depends on ARM && MTD_CFI && ( ARCH_H7201 || ARCH_H7202 )
+ depends on MTD_CFI && ( ARCH_H7201 || ARCH_H7202 )
help
This enables access to the flash chips on the Hynix evaluation boards.
If you have such a board, say 'Y'.
config MTD_MPC1211
tristate "CFI Flash device mapped on Interface MPC-1211"
- depends on SUPERH && SH_MPC1211 && MTD_CFI
+ depends on SH_MPC1211 && MTD_CFI
help
This enables access to the flash chips on the Interface MPC-1211(CTP/PCI/MPC-SH02).
If you have such a board, say 'Y'.
+config MTD_PQ2FADS
+ tristate "JEDEC flash SIMM mapped on PQ2FADS and 8272ADS boards"
+ depends on (ADS8272 || PQ2FADS) && MTD_PARTITIONS && MTD_JEDECPROBE && MTD_PHYSMAP && MTD_CFI_GEOMETRY && MTD_CFI_INTELEXT
+ help
+ This enables access to flash SIMM on PQ2FADS-like boards
+
config MTD_OMAP_NOR
tristate "TI OMAP board mappings"
depends on MTD_CFI && ARCH_OMAP
diff --git a/drivers/mtd/maps/Makefile b/drivers/mtd/maps/Makefile
index 7bcbc49e329f..7d9e940a1dcd 100644
--- a/drivers/mtd/maps/Makefile
+++ b/drivers/mtd/maps/Makefile
@@ -1,7 +1,7 @@
#
# linux/drivers/maps/Makefile
#
-# $Id: Makefile.common,v 1.30 2005/07/02 01:53:24 tpoynor Exp $
+# $Id: Makefile.common,v 1.34 2005/11/07 11:14:26 gleixner Exp $
ifeq ($(CONFIG_MTD_COMPLEX_MAPPINGS),y)
obj-$(CONFIG_MTD) += map_funcs.o
@@ -26,7 +26,7 @@ obj-$(CONFIG_MTD_MAINSTONE) += mainstone-flash.o
obj-$(CONFIG_MTD_MBX860) += mbx860.o
obj-$(CONFIG_MTD_CEIVA) += ceiva.o
obj-$(CONFIG_MTD_OCTAGON) += octagon-5066.o
-obj-$(CONFIG_MTD_PHYSMAP) += physmap.o
+obj-$(CONFIG_MTD_PHYSMAP) += physmap.o
obj-$(CONFIG_MTD_PNC2000) += pnc2000.o
obj-$(CONFIG_MTD_PCMCIA) += pcmciamtd.o
obj-$(CONFIG_MTD_RPXLITE) += rpxlite.o
@@ -70,3 +70,6 @@ obj-$(CONFIG_MTD_DMV182) += dmv182.o
obj-$(CONFIG_MTD_SHARP_SL) += sharpsl-flash.o
obj-$(CONFIG_MTD_PLATRAM) += plat-ram.o
obj-$(CONFIG_MTD_OMAP_NOR) += omap_nor.o
+obj-$(CONFIG_MTD_PQ2FADS) += pq2fads.o
+obj-$(CONFIG_MTD_MTX1) += mtx-1_flash.o
+obj-$(CONFIG_MTD_TQM834x) += tqm834x.o
diff --git a/drivers/mtd/maps/alchemy-flash.c b/drivers/mtd/maps/alchemy-flash.c
index 27fd2a3c3b60..a57791a6ce40 100644
--- a/drivers/mtd/maps/alchemy-flash.c
+++ b/drivers/mtd/maps/alchemy-flash.c
@@ -1,10 +1,10 @@
/*
* Flash memory access on AMD Alchemy evaluation boards
- *
- * $Id: alchemy-flash.c,v 1.1 2005/02/27 21:50:21 ppopov Exp $
+ *
+ * $Id: alchemy-flash.c,v 1.2 2005/11/07 11:14:26 gleixner Exp $
*
* (C) 2003, 2004 Pete Popov <ppopov@embeddedalley.com>
- *
+ *
*/
#include <linux/config.h>
@@ -22,7 +22,7 @@
#ifdef DEBUG_RW
#define DBG(x...) printk(x)
#else
-#define DBG(x...)
+#define DBG(x...)
#endif
#ifdef CONFIG_MIPS_PB1000
@@ -136,7 +136,7 @@ int __init alchemy_mtd_init(void)
int nb_parts = 0;
unsigned long window_addr;
unsigned long window_size;
-
+
/* Default flash buswidth */
alchemy_map.bankwidth = BOARD_FLASH_WIDTH;
@@ -161,7 +161,7 @@ int __init alchemy_mtd_init(void)
* Now let's probe for the actual flash. Do it here since
* specific machine settings might have been set above.
*/
- printk(KERN_NOTICE BOARD_MAP_NAME ": probing %d-bit flash bus\n",
+ printk(KERN_NOTICE BOARD_MAP_NAME ": probing %d-bit flash bus\n",
alchemy_map.bankwidth*8);
alchemy_map.virt = ioremap(window_addr, window_size);
mymtd = do_map_probe("cfi_probe", &alchemy_map);
diff --git a/drivers/mtd/maps/amd76xrom.c b/drivers/mtd/maps/amd76xrom.c
index e8a900a77685..c350878d4592 100644
--- a/drivers/mtd/maps/amd76xrom.c
+++ b/drivers/mtd/maps/amd76xrom.c
@@ -2,7 +2,7 @@
* amd76xrom.c
*
* Normal mappings of chips in physical memory
- * $Id: amd76xrom.c,v 1.20 2005/03/18 14:04:35 gleixner Exp $
+ * $Id: amd76xrom.c,v 1.21 2005/11/07 11:14:26 gleixner Exp $
*/
#include <linux/module.h>
@@ -70,7 +70,7 @@ static void amd76xrom_cleanup(struct amd76xrom_window *window)
list_del(&map->list);
kfree(map);
}
- if (window->rsrc.parent)
+ if (window->rsrc.parent)
release_resource(&window->rsrc);
if (window->virt) {
@@ -107,7 +107,7 @@ static int __devinit amd76xrom_init_one (struct pci_dev *pdev,
window->phys = 0xffff0000; /* 64KiB */
}
window->size = 0xffffffffUL - window->phys + 1UL;
-
+
/*
* Try to reserve the window mem region. If this fails then
* it is likely due to a fragment of the window being
@@ -138,7 +138,7 @@ static int __devinit amd76xrom_init_one (struct pci_dev *pdev,
/* Enable writes through the rom window */
pci_read_config_byte(pdev, 0x40, &byte);
pci_write_config_byte(pdev, 0x40, byte | 1);
-
+
/* FIXME handle registers 0x80 - 0x8C the bios region locks */
/* For write accesses caches are useless */
@@ -186,7 +186,7 @@ static int __devinit amd76xrom_init_one (struct pci_dev *pdev,
MOD_NAME, map->map.phys);
/* There is no generic VPP support */
- for(map->map.bankwidth = 32; map->map.bankwidth;
+ for(map->map.bankwidth = 32; map->map.bankwidth;
map->map.bankwidth >>= 1)
{
char **probe_type;
@@ -239,7 +239,7 @@ static int __devinit amd76xrom_init_one (struct pci_dev *pdev,
for(i = 0; i < cfi->numchips; i++) {
cfi->chips[i].start += offset;
}
-
+
/* Now that the mtd devices is complete claim and export it */
map->mtd->owner = THIS_MODULE;
if (add_mtd_device(map->mtd)) {
@@ -259,9 +259,7 @@ static int __devinit amd76xrom_init_one (struct pci_dev *pdev,
out:
/* Free any left over map structures */
- if (map) {
- kfree(map);
- }
+ kfree(map);
/* See if I have any map structures */
if (list_empty(&window->maps)) {
amd76xrom_cleanup(window);
@@ -279,9 +277,9 @@ static void __devexit amd76xrom_remove_one (struct pci_dev *pdev)
}
static struct pci_device_id amd76xrom_pci_tbl[] = {
- { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_7410,
+ { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_7410,
PCI_ANY_ID, PCI_ANY_ID, },
- { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_7440,
+ { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_7440,
PCI_ANY_ID, PCI_ANY_ID, },
{ PCI_VENDOR_ID_AMD, 0x7468 }, /* amd8111 support */
{ 0, }
diff --git a/drivers/mtd/maps/arctic-mtd.c b/drivers/mtd/maps/arctic-mtd.c
index 777276fd0e15..d95ae582fbe9 100644
--- a/drivers/mtd/maps/arctic-mtd.c
+++ b/drivers/mtd/maps/arctic-mtd.c
@@ -1,7 +1,7 @@
/*
- * $Id: arctic-mtd.c,v 1.13 2004/11/04 13:24:14 gleixner Exp $
- *
- * drivers/mtd/maps/arctic-mtd.c MTD mappings and partition tables for
+ * $Id: arctic-mtd.c,v 1.14 2005/11/07 11:14:26 gleixner Exp $
+ *
+ * drivers/mtd/maps/arctic-mtd.c MTD mappings and partition tables for
* IBM 405LP Arctic boards.
*
* This program is free software; you can redistribute it and/or modify
diff --git a/drivers/mtd/maps/autcpu12-nvram.c b/drivers/mtd/maps/autcpu12-nvram.c
index cf362ccc3c8e..7ed3424dd959 100644
--- a/drivers/mtd/maps/autcpu12-nvram.c
+++ b/drivers/mtd/maps/autcpu12-nvram.c
@@ -1,8 +1,8 @@
/*
- * NV-RAM memory access on autcpu12
+ * NV-RAM memory access on autcpu12
* (C) 2002 Thomas Gleixner (gleixner@autronix.de)
*
- * $Id: autcpu12-nvram.c,v 1.8 2004/11/04 13:24:14 gleixner Exp $
+ * $Id: autcpu12-nvram.c,v 1.9 2005/11/07 11:14:26 gleixner Exp $
*
* 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
@@ -55,10 +55,10 @@ static int __init init_autcpu12_sram (void)
}
simple_map_init(&autcpu_sram_map);
- /*
- * Check for 32K/128K
- * read ofs 0
- * read ofs 0x10000
+ /*
+ * Check for 32K/128K
+ * read ofs 0
+ * read ofs 0x10000
* Write complement to ofs 0x100000
* Read and check result on ofs 0x0
* Restore contents
@@ -66,7 +66,7 @@ static int __init init_autcpu12_sram (void)
save0 = map_read32(&autcpu12_sram_map,0);
save1 = map_read32(&autcpu12_sram_map,0x10000);
map_write32(&autcpu12_sram_map,~save0,0x10000);
- /* if we find this pattern on 0x0, we have 32K size
+ /* if we find this pattern on 0x0, we have 32K size
* restore contents and exit
*/
if ( map_read32(&autcpu12_sram_map,0) != save0) {
@@ -89,7 +89,7 @@ map:
sram_mtd->owner = THIS_MODULE;
sram_mtd->erasesize = 16;
-
+
if (add_mtd_device(sram_mtd)) {
printk("NV-RAM device addition failed\n");
err = -ENOMEM;
@@ -97,7 +97,7 @@ map:
}
printk("NV-RAM device size %ldKiB registered on AUTCPU12\n",autcpu12_sram_map.size/SZ_1K);
-
+
return 0;
out_probe:
diff --git a/drivers/mtd/maps/bast-flash.c b/drivers/mtd/maps/bast-flash.c
index 0ba0ff7d43b9..b7858eb93534 100644
--- a/drivers/mtd/maps/bast-flash.c
+++ b/drivers/mtd/maps/bast-flash.c
@@ -9,7 +9,7 @@
* 20-Sep-2004 BJD Initial version
* 17-Jan-2005 BJD Add whole device if no partitions found
*
- * $Id: bast-flash.c,v 1.2 2005/01/18 11:13:47 bjd Exp $
+ * $Id: bast-flash.c,v 1.5 2005/11/07 11:14:26 gleixner Exp $
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -33,7 +33,8 @@
#include <linux/string.h>
#include <linux/ioport.h>
#include <linux/device.h>
-
+#include <linux/slab.h>
+#include <linux/platform_device.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/map.h>
#include <linux/mtd/partitions.h>
@@ -74,7 +75,7 @@ static void bast_flash_setrw(int to)
local_irq_save(flags);
val = __raw_readb(BAST_VA_CTRL3);
-
+
if (to)
val |= BAST_CPLD_CTRL3_ROMWEN;
else
@@ -92,7 +93,7 @@ static int bast_flash_remove(struct device *dev)
dev_set_drvdata(dev, NULL);
- if (info == NULL)
+ if (info == NULL)
return 0;
if (info->map.virt != NULL)
@@ -103,14 +104,13 @@ static int bast_flash_remove(struct device *dev)
map_destroy(info->mtd);
}
- if (info->partitions)
- kfree(info->partitions);
+ kfree(info->partitions);
if (info->area) {
release_resource(info->area);
kfree(info->area);
}
-
+
kfree(info);
return 0;
@@ -137,15 +137,15 @@ static int bast_flash_probe(struct device *dev)
info->map.phys = res->start;
info->map.size = res->end - res->start + 1;
- info->map.name = dev->bus_id;
+ info->map.name = dev->bus_id;
info->map.bankwidth = 2;
-
+
if (info->map.size > AREA_MAXSIZE)
info->map.size = AREA_MAXSIZE;
pr_debug("%s: area %08lx, size %ld\n", __FUNCTION__,
info->map.phys, info->map.size);
-
+
info->area = request_mem_region(res->start, info->map.size,
pdev->name);
if (info->area == NULL) {
@@ -162,7 +162,7 @@ static int bast_flash_probe(struct device *dev)
err = -EIO;
goto exit_error;
}
-
+
simple_map_init(&info->map);
/* enable the write to the flash area */
@@ -187,7 +187,7 @@ static int bast_flash_probe(struct device *dev)
err = parse_mtd_partitions(info->mtd, probes, &info->partitions, 0);
if (err > 0) {
err = add_mtd_partitions(info->mtd, info->partitions, err);
- if (err)
+ if (err)
printk(KERN_ERR PFX "cannot add/parse partitions\n");
} else {
err = add_mtd_device(info->mtd);
@@ -205,6 +205,7 @@ static int bast_flash_probe(struct device *dev)
static struct device_driver bast_flash_driver = {
.name = "bast-nor",
+ .owner = THIS_MODULE,
.bus = &platform_bus_type,
.probe = bast_flash_probe,
.remove = bast_flash_remove,
diff --git a/drivers/mtd/maps/beech-mtd.c b/drivers/mtd/maps/beech-mtd.c
index 5e79c9d5da2b..5df7361d1407 100644
--- a/drivers/mtd/maps/beech-mtd.c
+++ b/drivers/mtd/maps/beech-mtd.c
@@ -1,7 +1,7 @@
/*
- * $Id: beech-mtd.c,v 1.10 2004/11/04 13:24:14 gleixner Exp $
- *
- * drivers/mtd/maps/beech-mtd.c MTD mappings and partition tables for
+ * $Id: beech-mtd.c,v 1.11 2005/11/07 11:14:26 gleixner Exp $
+ *
+ * drivers/mtd/maps/beech-mtd.c MTD mappings and partition tables for
* IBM 405LP Beech boards.
*
* This program is free software; you can redistribute it and/or modify
diff --git a/drivers/mtd/maps/cdb89712.c b/drivers/mtd/maps/cdb89712.c
index ab15dac2f936..9f17bb6c5a9d 100644
--- a/drivers/mtd/maps/cdb89712.c
+++ b/drivers/mtd/maps/cdb89712.c
@@ -1,7 +1,7 @@
/*
* Flash on Cirrus CDB89712
*
- * $Id: cdb89712.c,v 1.10 2004/11/04 13:24:14 gleixner Exp $
+ * $Id: cdb89712.c,v 1.11 2005/11/07 11:14:26 gleixner Exp $
*/
#include <linux/module.h>
@@ -37,13 +37,13 @@ struct resource cdb89712_flash_resource = {
static int __init init_cdb89712_flash (void)
{
int err;
-
+
if (request_resource (&ioport_resource, &cdb89712_flash_resource)) {
printk(KERN_NOTICE "Failed to reserve Cdb89712 FLASH space\n");
err = -EBUSY;
goto out;
}
-
+
cdb89712_flash_map.virt = ioremap(FLASH_START, FLASH_SIZE);
if (!cdb89712_flash_map.virt) {
printk(KERN_NOTICE "Failed to ioremap Cdb89712 FLASH space\n");
@@ -64,13 +64,13 @@ static int __init init_cdb89712_flash (void)
}
flash_mtd->owner = THIS_MODULE;
-
+
if (add_mtd_device(flash_mtd)) {
printk("FLASH device addition failed\n");
err = -ENOMEM;
goto out_probe;
}
-
+
return 0;
out_probe:
@@ -107,13 +107,13 @@ struct resource cdb89712_sram_resource = {
static int __init init_cdb89712_sram (void)
{
int err;
-
+
if (request_resource (&ioport_resource, &cdb89712_sram_resource)) {
printk(KERN_NOTICE "Failed to reserve Cdb89712 SRAM space\n");
err = -EBUSY;
goto out;
}
-
+
cdb89712_sram_map.virt = ioremap(SRAM_START, SRAM_SIZE);
if (!cdb89712_sram_map.virt) {
printk(KERN_NOTICE "Failed to ioremap Cdb89712 SRAM space\n");
@@ -130,13 +130,13 @@ static int __init init_cdb89712_sram (void)
sram_mtd->owner = THIS_MODULE;
sram_mtd->erasesize = 16;
-
+
if (add_mtd_device(sram_mtd)) {
printk("SRAM device addition failed\n");
err = -ENOMEM;
goto out_probe;
}
-
+
return 0;
out_probe:
@@ -175,13 +175,13 @@ struct resource cdb89712_bootrom_resource = {
static int __init init_cdb89712_bootrom (void)
{
int err;
-
+
if (request_resource (&ioport_resource, &cdb89712_bootrom_resource)) {
printk(KERN_NOTICE "Failed to reserve Cdb89712 BOOTROM space\n");
err = -EBUSY;
goto out;
}
-
+
cdb89712_bootrom_map.virt = ioremap(BOOTROM_START, BOOTROM_SIZE);
if (!cdb89712_bootrom_map.virt) {
printk(KERN_NOTICE "Failed to ioremap Cdb89712 BootROM space\n");
@@ -198,13 +198,13 @@ static int __init init_cdb89712_bootrom (void)
bootrom_mtd->owner = THIS_MODULE;
bootrom_mtd->erasesize = 0x10000;
-
+
if (add_mtd_device(bootrom_mtd)) {
printk("BootROM device addition failed\n");
err = -ENOMEM;
goto out_probe;
}
-
+
return 0;
out_probe:
@@ -225,16 +225,16 @@ out:
static int __init init_cdb89712_maps(void)
{
- printk(KERN_INFO "Cirrus CDB89712 MTD mappings:\n Flash 0x%x at 0x%x\n SRAM 0x%x at 0x%x\n BootROM 0x%x at 0x%x\n",
+ printk(KERN_INFO "Cirrus CDB89712 MTD mappings:\n Flash 0x%x at 0x%x\n SRAM 0x%x at 0x%x\n BootROM 0x%x at 0x%x\n",
FLASH_SIZE, FLASH_START, SRAM_SIZE, SRAM_START, BOOTROM_SIZE, BOOTROM_START);
init_cdb89712_flash();
init_cdb89712_sram();
init_cdb89712_bootrom();
-
+
return 0;
}
-
+
static void __exit cleanup_cdb89712_maps(void)
{
@@ -244,7 +244,7 @@ static void __exit cleanup_cdb89712_maps(void)
iounmap((void *)cdb89712_sram_map.virt);
release_resource (&cdb89712_sram_resource);
}
-
+
if (flash_mtd) {
del_mtd_device(flash_mtd);
map_destroy(flash_mtd);
diff --git a/drivers/mtd/maps/ceiva.c b/drivers/mtd/maps/ceiva.c
index da8584a662f4..5a95ab370a97 100644
--- a/drivers/mtd/maps/ceiva.c
+++ b/drivers/mtd/maps/ceiva.c
@@ -20,6 +20,7 @@
#include <linux/ioport.h>
#include <linux/kernel.h>
#include <linux/init.h>
+#include <linux/slab.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/map.h>
@@ -312,8 +313,7 @@ static void __init clps_locate_partitions(struct mtd_info *mtd)
static void __exit clps_destroy_partitions(void)
{
- if (parsed_parts)
- kfree(parsed_parts);
+ kfree(parsed_parts);
}
static struct mtd_info *mymtd;
diff --git a/drivers/mtd/maps/cfi_flagadm.c b/drivers/mtd/maps/cfi_flagadm.c
index f72e4f894b32..6a8c0415bde8 100644
--- a/drivers/mtd/maps/cfi_flagadm.c
+++ b/drivers/mtd/maps/cfi_flagadm.c
@@ -1,8 +1,8 @@
/*
* Copyright © 2001 Flaga hf. Medical Devices, Kári Davíðsson <kd@flaga.is>
*
- * $Id: cfi_flagadm.c,v 1.14 2004/11/04 13:24:14 gleixner Exp $
- *
+ * $Id: cfi_flagadm.c,v 1.15 2005/11/07 11:14:26 gleixner Exp $
+ *
* 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
@@ -42,7 +42,7 @@
*/
#define FLASH_PHYS_ADDR 0x40000000
-#define FLASH_SIZE 0x400000
+#define FLASH_SIZE 0x400000
#define FLASH_PARTITION0_ADDR 0x00000000
#define FLASH_PARTITION0_SIZE 0x00020000
@@ -79,7 +79,7 @@ struct mtd_partition flagadm_parts[] = {
.offset = FLASH_PARTITION2_ADDR,
.size = FLASH_PARTITION2_SIZE
},
- {
+ {
.name = "Persistant storage",
.offset = FLASH_PARTITION3_ADDR,
.size = FLASH_PARTITION3_SIZE
@@ -91,10 +91,10 @@ struct mtd_partition flagadm_parts[] = {
static struct mtd_info *mymtd;
int __init init_flagadm(void)
-{
+{
printk(KERN_NOTICE "FlagaDM flash device: %x at %x\n",
FLASH_SIZE, FLASH_PHYS_ADDR);
-
+
flagadm_map.phys = FLASH_PHYS_ADDR;
flagadm_map.virt = ioremap(FLASH_PHYS_ADDR,
FLASH_SIZE);
diff --git a/drivers/mtd/maps/cstm_mips_ixx.c b/drivers/mtd/maps/cstm_mips_ixx.c
index ae9252fbf176..a370953c1513 100644
--- a/drivers/mtd/maps/cstm_mips_ixx.c
+++ b/drivers/mtd/maps/cstm_mips_ixx.c
@@ -1,10 +1,10 @@
/*
- * $Id: cstm_mips_ixx.c,v 1.12 2004/11/04 13:24:14 gleixner Exp $
+ * $Id: cstm_mips_ixx.c,v 1.14 2005/11/07 11:14:26 gleixner Exp $
*
* Mapping of a custom board with both AMD CFI and JEDEC flash in partitions.
* Config with both CFI and JEDEC device support.
*
- * Basically physmap.c with the addition of partitions and
+ * Basically physmap.c with the addition of partitions and
* an array of mapping info to accomodate more than one flash type per board.
*
* Copyright 2000 MontaVista Software Inc.
@@ -69,7 +69,7 @@ void cstm_mips_ixx_set_vpp(struct map_info *map,int vpp)
__u16 data;
__u8 data1;
static u8 first = 1;
-
+
// Set GPIO port B pin3 to high
data = *(__u16 *)(CC_GPBCR);
data = (data & 0xff0f) | 0x0040;
@@ -85,7 +85,7 @@ void cstm_mips_ixx_set_vpp(struct map_info *map,int vpp)
} else {
if (!--vpp_count) {
__u16 data;
-
+
// Set GPIO port B pin3 to high
data = *(__u16 *)(CC_GPBCR);
data = (data & 0xff3f) | 0x0040;
@@ -109,8 +109,8 @@ struct cstm_mips_ixx_info {
};
#if defined(CONFIG_MIPS_ITE8172) || defined(CONFIG_MIPS_IVR)
-#define PHYSMAP_NUMBER 1 // number of board desc structs needed, one per contiguous flash type
-const struct cstm_mips_ixx_info cstm_mips_ixx_board_desc[PHYSMAP_NUMBER] =
+#define PHYSMAP_NUMBER 1 // number of board desc structs needed, one per contiguous flash type
+const struct cstm_mips_ixx_info cstm_mips_ixx_board_desc[PHYSMAP_NUMBER] =
{
{ // 28F128J3A in 2x16 configuration
"big flash", // name
@@ -131,10 +131,10 @@ static struct mtd_partition cstm_mips_ixx_partitions[PHYSMAP_NUMBER][MAX_PHYSMAP
},
};
#else /* defined(CONFIG_MIPS_ITE8172) || defined(CONFIG_MIPS_IVR) */
-#define PHYSMAP_NUMBER 1 // number of board desc structs needed, one per contiguous flash type
-const struct cstm_mips_ixx_info cstm_mips_ixx_board_desc[PHYSMAP_NUMBER] =
+#define PHYSMAP_NUMBER 1 // number of board desc structs needed, one per contiguous flash type
+const struct cstm_mips_ixx_info cstm_mips_ixx_board_desc[PHYSMAP_NUMBER] =
{
- {
+ {
"MTD flash", // name
CONFIG_MTD_CSTM_MIPS_IXX_START, // window_addr
CONFIG_MTD_CSTM_MIPS_IXX_LEN, // window_size
@@ -144,7 +144,7 @@ const struct cstm_mips_ixx_info cstm_mips_ixx_board_desc[PHYSMAP_NUMBER] =
};
static struct mtd_partition cstm_mips_ixx_partitions[PHYSMAP_NUMBER][MAX_PHYSMAP_PARTITIONS] = {
-{
+{
{
.name = "main partition",
.size = CONFIG_MTD_CSTM_MIPS_IXX_LEN,
@@ -165,7 +165,7 @@ int __init init_cstm_mips_ixx(void)
/* Initialize mapping */
for (i=0;i<PHYSMAP_NUMBER;i++) {
- printk(KERN_NOTICE "cstm_mips_ixx flash device: 0x%lx at 0x%lx\n",
+ printk(KERN_NOTICE "cstm_mips_ixx flash device: 0x%lx at 0x%lx\n",
cstm_mips_ixx_board_desc[i].window_size, cstm_mips_ixx_board_desc[i].window_addr);
@@ -235,7 +235,7 @@ void PCISetULongByOffset(__u32 DevNumber, __u32 FuncNumber, __u32 Offset, __u32
offset = ( unsigned long )( 0x80000000 | ( DevNumber << 11 ) + ( FuncNumber << 8 ) + Offset) ;
- *(__u32 *)CC_CONFADDR = offset;
+ *(__u32 *)CC_CONFADDR = offset;
*(__u32 *)CC_CONFDATA = data;
}
void setup_ITE_IVR_flash()
diff --git a/drivers/mtd/maps/dbox2-flash.c b/drivers/mtd/maps/dbox2-flash.c
index d850a27a4b59..49d90542fc75 100644
--- a/drivers/mtd/maps/dbox2-flash.c
+++ b/drivers/mtd/maps/dbox2-flash.c
@@ -1,5 +1,5 @@
/*
- * $Id: dbox2-flash.c,v 1.13 2004/11/04 13:24:14 gleixner Exp $
+ * $Id: dbox2-flash.c,v 1.14 2005/11/07 11:14:26 gleixner Exp $
*
* D-Box 2 flash driver
*/
@@ -21,38 +21,38 @@
static struct mtd_partition partition_info[]= {
{
.name = "BR bootloader",
- .size = 128 * 1024,
- .offset = 0,
+ .size = 128 * 1024,
+ .offset = 0,
.mask_flags = MTD_WRITEABLE
},
{
.name = "FLFS (U-Boot)",
- .size = 128 * 1024,
- .offset = MTDPART_OFS_APPEND,
+ .size = 128 * 1024,
+ .offset = MTDPART_OFS_APPEND,
.mask_flags = 0
},
{
- .name = "Root (SquashFS)",
- .size = 7040 * 1024,
- .offset = MTDPART_OFS_APPEND,
+ .name = "Root (SquashFS)",
+ .size = 7040 * 1024,
+ .offset = MTDPART_OFS_APPEND,
.mask_flags = 0
},
{
.name = "var (JFFS2)",
- .size = 896 * 1024,
- .offset = MTDPART_OFS_APPEND,
+ .size = 896 * 1024,
+ .offset = MTDPART_OFS_APPEND,
.mask_flags = 0
},
{
- .name = "Flash without bootloader",
- .size = MTDPART_SIZ_FULL,
- .offset = 128 * 1024,
+ .name = "Flash without bootloader",
+ .size = MTDPART_SIZ_FULL,
+ .offset = 128 * 1024,
.mask_flags = 0
},
{
- .name = "Complete Flash",
- .size = MTDPART_SIZ_FULL,
- .offset = 0,
+ .name = "Complete Flash",
+ .size = MTDPART_SIZ_FULL,
+ .offset = 0,
.mask_flags = MTD_WRITEABLE
}
};
@@ -88,16 +88,16 @@ int __init init_dbox2_flash(void)
if (!mymtd) {
// Probe for single Intel 28F640
dbox2_flash_map.bankwidth = 2;
-
+
mymtd = do_map_probe("cfi_probe", &dbox2_flash_map);
}
-
+
if (mymtd) {
mymtd->owner = THIS_MODULE;
/* Create MTD devices for each partition. */
add_mtd_partitions(mymtd, partition_info, NUM_PARTITIONS);
-
+
return 0;
}
diff --git a/drivers/mtd/maps/dc21285.c b/drivers/mtd/maps/dc21285.c
index 938c41f2f056..701620b6baed 100644
--- a/drivers/mtd/maps/dc21285.c
+++ b/drivers/mtd/maps/dc21285.c
@@ -4,8 +4,8 @@
* (C) 2000 Nicolas Pitre <nico@cam.org>
*
* This code is GPL
- *
- * $Id: dc21285.c,v 1.22 2004/11/01 13:39:21 rmk Exp $
+ *
+ * $Id: dc21285.c,v 1.24 2005/11/07 11:14:26 gleixner Exp $
*/
#include <linux/config.h>
#include <linux/module.h>
@@ -13,6 +13,7 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/delay.h>
+#include <linux/slab.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/map.h>
@@ -26,9 +27,9 @@
static struct mtd_info *dc21285_mtd;
#ifdef CONFIG_ARCH_NETWINDER
-/*
+/*
* This is really ugly, but it seams to be the only
- * realiable way to do it, as the cpld state machine
+ * realiable way to do it, as the cpld state machine
* is unpredictible. So we have a 25us penalty per
* write access.
*/
@@ -149,7 +150,7 @@ static struct map_info dc21285_map = {
static struct mtd_partition *dc21285_parts;
static const char *probes[] = { "RedBoot", "cmdlinepart", NULL };
#endif
-
+
static int __init init_dc21285(void)
{
@@ -159,20 +160,20 @@ static int __init init_dc21285(void)
/* Determine bankwidth */
switch (*CSR_SA110_CNTL & (3<<14)) {
- case SA110_CNTL_ROMWIDTH_8:
+ case SA110_CNTL_ROMWIDTH_8:
dc21285_map.bankwidth = 1;
dc21285_map.read = dc21285_read8;
dc21285_map.write = dc21285_write8;
dc21285_map.copy_to = dc21285_copy_to_8;
break;
- case SA110_CNTL_ROMWIDTH_16:
- dc21285_map.bankwidth = 2;
+ case SA110_CNTL_ROMWIDTH_16:
+ dc21285_map.bankwidth = 2;
dc21285_map.read = dc21285_read16;
dc21285_map.write = dc21285_write16;
dc21285_map.copy_to = dc21285_copy_to_16;
break;
- case SA110_CNTL_ROMWIDTH_32:
- dc21285_map.bankwidth = 4;
+ case SA110_CNTL_ROMWIDTH_32:
+ dc21285_map.bankwidth = 4;
dc21285_map.read = dc21285_read32;
dc21285_map.write = dc21285_write32;
dc21285_map.copy_to = dc21285_copy_to_32;
@@ -200,20 +201,20 @@ static int __init init_dc21285(void)
if (!dc21285_mtd) {
iounmap(dc21285_map.virt);
return -ENXIO;
- }
-
+ }
+
dc21285_mtd->owner = THIS_MODULE;
#ifdef CONFIG_MTD_PARTITIONS
nrparts = parse_mtd_partitions(dc21285_mtd, probes, &dc21285_parts, 0);
if (nrparts > 0)
add_mtd_partitions(dc21285_mtd, dc21285_parts, nrparts);
- else
-#endif
+ else
+#endif
add_mtd_device(dc21285_mtd);
-
+
if(machine_is_ebsa285()) {
- /*
+ /*
* Flash timing is determined with bits 19-16 of the
* CSR_SA110_CNTL. The value is the number of wait cycles, or
* 0 for 16 cycles (the default). Cycles are 20 ns.
@@ -226,7 +227,7 @@ static int __init init_dc21285(void)
/* tristate time */
*CSR_SA110_CNTL = ((*CSR_SA110_CNTL & ~0x0f000000) | (7 << 24));
}
-
+
return 0;
}
diff --git a/drivers/mtd/maps/dilnetpc.c b/drivers/mtd/maps/dilnetpc.c
index 0bc79c93a584..b51c757817d8 100644
--- a/drivers/mtd/maps/dilnetpc.c
+++ b/drivers/mtd/maps/dilnetpc.c
@@ -14,7 +14,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: dilnetpc.c,v 1.17 2004/11/28 09:40:39 dwmw2 Exp $
+ * $Id: dilnetpc.c,v 1.20 2005/11/07 11:14:26 gleixner Exp $
*
* The DIL/Net PC is a tiny embedded PC board made by SSV Embedded Systems
* featuring the AMD Elan SC410 processor. There are two variants of this
@@ -30,12 +30,15 @@
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/init.h>
-#include <asm/io.h>
+#include <linux/string.h>
+
#include <linux/mtd/mtd.h>
#include <linux/mtd/map.h>
#include <linux/mtd/partitions.h>
#include <linux/mtd/concat.h>
+#include <asm/io.h>
+
/*
** The DIL/NetPC keeps its BIOS in two distinct flash blocks.
** Destroying any of these blocks transforms the DNPC into
@@ -269,13 +272,13 @@ static struct map_info dnpc_map = {
static struct mtd_partition partition_info[]=
{
- {
- .name = "ADNP boot",
- .offset = 0,
+ {
+ .name = "ADNP boot",
+ .offset = 0,
.size = 0xf0000,
},
- {
- .name = "ADNP system BIOS",
+ {
+ .name = "ADNP system BIOS",
.offset = MTDPART_OFS_NXTBLK,
.size = 0x10000,
#ifdef DNPC_BIOS_BLOCKS_WRITEPROTECTED
@@ -288,7 +291,7 @@ static struct mtd_partition partition_info[]=
.size = 0x2f0000,
},
{
- .name = "ADNP system BIOS entry",
+ .name = "ADNP system BIOS entry",
.offset = MTDPART_OFS_NXTBLK,
.size = MTDPART_SIZ_FULL,
#ifdef DNPC_BIOS_BLOCKS_WRITEPROTECTED
@@ -322,9 +325,9 @@ static struct mtd_info *merged_mtd;
static struct mtd_partition higlvl_partition_info[]=
{
- {
- .name = "ADNP boot block",
- .offset = 0,
+ {
+ .name = "ADNP boot block",
+ .offset = 0,
.size = CONFIG_MTD_DILNETPC_BOOTSIZE,
},
{
@@ -332,8 +335,8 @@ static struct mtd_partition higlvl_partition_info[]=
.offset = MTDPART_OFS_NXTBLK,
.size = ADNP_WINDOW_SIZE-CONFIG_MTD_DILNETPC_BOOTSIZE-0x20000,
},
- {
- .name = "ADNP system BIOS + BIOS Entry",
+ {
+ .name = "ADNP system BIOS + BIOS Entry",
.offset = MTDPART_OFS_NXTBLK,
.size = MTDPART_SIZ_FULL,
#ifdef DNPC_BIOS_BLOCKS_WRITEPROTECTED
@@ -368,7 +371,7 @@ static int __init init_dnpc(void)
/*
** determine hardware (DNP/ADNP/invalid)
- */
+ */
if((is_dnp = dnp_adnp_probe()) < 0)
return -ENXIO;
@@ -394,13 +397,13 @@ static int __init init_dnpc(void)
++dnpc_map.name;
for(i = 0; i < NUM_PARTITIONS; i++)
++partition_info[i].name;
- higlvl_partition_info[1].size = DNP_WINDOW_SIZE -
+ higlvl_partition_info[1].size = DNP_WINDOW_SIZE -
CONFIG_MTD_DILNETPC_BOOTSIZE - 0x20000;
for(i = 0; i < NUM_HIGHLVL_PARTITIONS; i++)
++higlvl_partition_info[i].name;
}
- printk(KERN_NOTICE "DIL/Net %s flash: 0x%lx at 0x%lx\n",
+ printk(KERN_NOTICE "DIL/Net %s flash: 0x%lx at 0x%lx\n",
is_dnp ? "DNPC" : "ADNP", dnpc_map.size, dnpc_map.phys);
dnpc_map.virt = ioremap_nocache(dnpc_map.phys, dnpc_map.size);
@@ -433,7 +436,7 @@ static int __init init_dnpc(void)
iounmap(dnpc_map.virt);
return -ENXIO;
}
-
+
mymtd->owner = THIS_MODULE;
/*
diff --git a/drivers/mtd/maps/dmv182.c b/drivers/mtd/maps/dmv182.c
index b9bc63503e26..b993ac01a9a5 100644
--- a/drivers/mtd/maps/dmv182.c
+++ b/drivers/mtd/maps/dmv182.c
@@ -1,10 +1,10 @@
/*
* drivers/mtd/maps/svme182.c
- *
+ *
* Flash map driver for the Dy4 SVME182 board
- *
- * $Id: dmv182.c,v 1.5 2004/11/04 13:24:14 gleixner Exp $
+ *
+ * $Id: dmv182.c,v 1.6 2005/11/07 11:14:26 gleixner Exp $
*
* Copyright 2003-2004, TimeSys Corporation
*
@@ -104,7 +104,7 @@ static int __init init_svme182(void)
partitions = svme182_partitions;
svme182_map.virt = ioremap(FLASH_BASE_ADDR, svme182_map.size);
-
+
if (svme182_map.virt == 0) {
printk("Failed to ioremap FLASH memory area.\n");
return -EIO;
diff --git a/drivers/mtd/maps/ebony.c b/drivers/mtd/maps/ebony.c
index b9d9cf4854b6..60a6e51d662f 100644
--- a/drivers/mtd/maps/ebony.c
+++ b/drivers/mtd/maps/ebony.c
@@ -1,6 +1,6 @@
/*
- * $Id: ebony.c,v 1.15 2004/12/09 18:39:54 holindho Exp $
- *
+ * $Id: ebony.c,v 1.16 2005/11/07 11:14:26 gleixner Exp $
+ *
* Mapping for Ebony user flash
*
* Matt Porter <mporter@kernel.crashing.org>
@@ -21,7 +21,6 @@
#include <linux/mtd/map.h>
#include <linux/mtd/partitions.h>
#include <linux/config.h>
-#include <linux/version.h>
#include <asm/io.h>
#include <asm/ibm44x.h>
#include <platforms/4xx/ebony.h>
@@ -85,7 +84,7 @@ int __init init_ebony(void)
small_flash_base = EBONY_SMALL_FLASH_LOW2;
else
small_flash_base = EBONY_SMALL_FLASH_LOW1;
-
+
if (EBONY_BOOT_SMALL_FLASH(fpga0_reg) &&
!EBONY_ONBRD_FLASH_EN(fpga0_reg))
large_flash_base = EBONY_LARGE_FLASH_LOW;
diff --git a/drivers/mtd/maps/edb7312.c b/drivers/mtd/maps/edb7312.c
index 8b0da394f3fa..b48a3473ffc1 100644
--- a/drivers/mtd/maps/edb7312.c
+++ b/drivers/mtd/maps/edb7312.c
@@ -1,10 +1,10 @@
/*
- * $Id: edb7312.c,v 1.13 2004/11/04 13:24:14 gleixner Exp $
+ * $Id: edb7312.c,v 1.14 2005/11/07 11:14:27 gleixner Exp $
*
* Handle mapping of the NOR flash on Cogent EDB7312 boards
*
* Copyright 2002 SYSGO Real-Time Solutions GmbH
- *
+ *
* 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.
@@ -46,7 +46,7 @@ struct map_info edb7312nor_map = {
#ifdef CONFIG_MTD_PARTITIONS
/*
- * MTD partitioning stuff
+ * MTD partitioning stuff
*/
static struct mtd_partition static_partitions[3] =
{
@@ -80,7 +80,7 @@ int __init init_edb7312nor(void)
const char **type;
const char *part_type = 0;
- printk(KERN_NOTICE MSG_PREFIX "0x%08x at 0x%08x\n",
+ printk(KERN_NOTICE MSG_PREFIX "0x%08x at 0x%08x\n",
WINDOW_SIZE, WINDOW_ADDR);
edb7312nor_map.virt = ioremap(WINDOW_ADDR, WINDOW_SIZE);
@@ -88,7 +88,7 @@ int __init init_edb7312nor(void)
printk(MSG_PREFIX "failed to ioremap\n");
return -EIO;
}
-
+
simple_map_init(&edb7312nor_map);
mymtd = 0;
diff --git a/drivers/mtd/maps/epxa10db-flash.c b/drivers/mtd/maps/epxa10db-flash.c
index ab6dbe2b8cce..265b079fe934 100644
--- a/drivers/mtd/maps/epxa10db-flash.c
+++ b/drivers/mtd/maps/epxa10db-flash.c
@@ -5,7 +5,7 @@
* Copyright (C) 2001 Altera Corporation
* Copyright (C) 2001 Red Hat, Inc.
*
- * $Id: epxa10db-flash.c,v 1.13 2004/11/04 13:24:14 gleixner Exp $
+ * $Id: epxa10db-flash.c,v 1.15 2005/11/07 11:14:27 gleixner Exp $
*
* 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
@@ -27,12 +27,15 @@
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/init.h>
-#include <asm/io.h>
+#include <linux/slab.h>
+
#include <linux/mtd/mtd.h>
#include <linux/mtd/map.h>
#include <linux/mtd/partitions.h>
+#include <asm/io.h>
#include <asm/hardware.h>
+
#ifdef CONFIG_EPXA10DB
#define BOARD_NAME "EPXA10DB"
#else
@@ -59,7 +62,7 @@ static const char *probes[] = { "RedBoot", "afs", NULL };
static int __init epxa_mtd_init(void)
{
int i;
-
+
printk(KERN_NOTICE "%s flash device: 0x%x at 0x%x\n", BOARD_NAME, FLASH_SIZE, FLASH_START);
epxa_map.virt = ioremap(FLASH_START, FLASH_SIZE);
@@ -123,8 +126,8 @@ static void __exit epxa_mtd_cleanup(void)
}
-/*
- * This will do for now, once we decide which bootldr we're finally
+/*
+ * This will do for now, once we decide which bootldr we're finally
* going to use then we'll remove this function and do it properly
*
* Partions are currently (as offsets from base of flash):
@@ -137,7 +140,7 @@ static int __init epxa_default_partitions(struct mtd_info *master, struct mtd_pa
struct mtd_partition *parts;
int ret, i;
int npartitions = 0;
- char *names;
+ char *names;
const char *name = "jffs";
printk("Using default partitions for %s\n",BOARD_NAME);
@@ -149,7 +152,7 @@ static int __init epxa_default_partitions(struct mtd_info *master, struct mtd_pa
goto out;
}
i=0;
- names = (char *)&parts[npartitions];
+ names = (char *)&parts[npartitions];
parts[i].name = names;
names += strlen(name) + 1;
strcpy(parts[i].name, name);
diff --git a/drivers/mtd/maps/fortunet.c b/drivers/mtd/maps/fortunet.c
index 068bb6a54520..c6bf4e1219ef 100644
--- a/drivers/mtd/maps/fortunet.c
+++ b/drivers/mtd/maps/fortunet.c
@@ -1,17 +1,20 @@
/* fortunet.c memory map
*
- * $Id: fortunet.c,v 1.9 2004/11/04 13:24:14 gleixner Exp $
+ * $Id: fortunet.c,v 1.11 2005/11/07 11:14:27 gleixner Exp $
*/
#include <linux/module.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/init.h>
-#include <asm/io.h>
+#include <linux/string.h>
+
#include <linux/mtd/mtd.h>
#include <linux/mtd/map.h>
#include <linux/mtd/partitions.h>
+#include <asm/io.h>
+
#define MAX_NUM_REGIONS 4
#define MAX_NUM_PARTITIONS 8
@@ -209,7 +212,7 @@ int __init init_fortunet(void)
map_regions[ix].map_info.phys = map_regions[ix].window_addr_physical,
- map_regions[ix].map_info.virt =
+ map_regions[ix].map_info.virt =
ioremap_nocache(
map_regions[ix].window_addr_physical,
map_regions[ix].map_info.size);
diff --git a/drivers/mtd/maps/h720x-flash.c b/drivers/mtd/maps/h720x-flash.c
index c73828171d9b..319094821101 100644
--- a/drivers/mtd/maps/h720x-flash.c
+++ b/drivers/mtd/maps/h720x-flash.c
@@ -1,11 +1,11 @@
/*
- * Flash memory access on Hynix GMS30C7201/HMS30C7202 based
+ * Flash memory access on Hynix GMS30C7201/HMS30C7202 based
* evaluation boards
- *
- * $Id: h720x-flash.c,v 1.11 2004/11/04 13:24:14 gleixner Exp $
+ *
+ * $Id: h720x-flash.c,v 1.12 2005/11/07 11:14:27 gleixner Exp $
*
* (C) 2002 Jungjun Kim <jungjun.kim@hynix.com>
- * 2003 Thomas Gleixner <tglx@linutronix.de>
+ * 2003 Thomas Gleixner <tglx@linutronix.de>
*/
#include <linux/config.h>
@@ -72,7 +72,7 @@ int __init h720x_mtd_init(void)
{
char *part_type = NULL;
-
+
h720x_map.virt = ioremap(FLASH_PHYS, FLASH_SIZE);
if (!h720x_map.virt) {
@@ -91,7 +91,7 @@ int __init h720x_mtd_init(void)
h720x_map.bankwidth = 2;
mymtd = do_map_probe("cfi_probe", &h720x_map);
}
-
+
if (mymtd) {
mymtd->owner = THIS_MODULE;
@@ -124,11 +124,11 @@ static void __exit h720x_mtd_cleanup(void)
del_mtd_partitions(mymtd);
map_destroy(mymtd);
}
-
+
/* Free partition info, if commandline partition was used */
if (mtd_parts && (mtd_parts != h720x_partitions))
kfree (mtd_parts);
-
+
if (h720x_map.virt) {
iounmap((void *)h720x_map.virt);
h720x_map.virt = 0;
diff --git a/drivers/mtd/maps/ichxrom.c b/drivers/mtd/maps/ichxrom.c
index e505207cd489..ea5073781b3a 100644
--- a/drivers/mtd/maps/ichxrom.c
+++ b/drivers/mtd/maps/ichxrom.c
@@ -2,7 +2,7 @@
* ichxrom.c
*
* Normal mappings of chips in physical memory
- * $Id: ichxrom.c,v 1.18 2005/07/07 10:26:20 dwmw2 Exp $
+ * $Id: ichxrom.c,v 1.19 2005/11/07 11:14:27 gleixner Exp $
*/
#include <linux/module.h>
@@ -101,7 +101,7 @@ static int __devinit ichxrom_init_one (struct pci_dev *pdev,
* you can only really attach a FWH to an ICHX there
* a number of simplifications you can make.
*
- * Also you can page firmware hubs if an 8MB window isn't enough
+ * Also you can page firmware hubs if an 8MB window isn't enough
* but don't currently handle that case either.
*/
window->pdev = pdev;
@@ -144,7 +144,7 @@ static int __devinit ichxrom_init_one (struct pci_dev *pdev,
window->phys = 0xfff00000;
}
else if ((byte & 0x80) == 0x80) {
- window->phys = 0xfff80000;
+ window->phys = 0xfff80000;
}
if (window->phys == 0) {
@@ -233,7 +233,7 @@ static int __devinit ichxrom_init_one (struct pci_dev *pdev,
* in a factory setting. So in-place programming
* needs to use a different method.
*/
- for(map->map.bankwidth = 32; map->map.bankwidth;
+ for(map->map.bankwidth = 32; map->map.bankwidth;
map->map.bankwidth >>= 1)
{
char **probe_type;
@@ -286,7 +286,7 @@ static int __devinit ichxrom_init_one (struct pci_dev *pdev,
for(i = 0; i < cfi->numchips; i++) {
cfi->chips[i].start += offset;
}
-
+
/* Now that the mtd devices is complete claim and export it */
map->mtd->owner = THIS_MODULE;
if (add_mtd_device(map->mtd)) {
@@ -306,9 +306,8 @@ static int __devinit ichxrom_init_one (struct pci_dev *pdev,
out:
/* Free any left over map structures */
- if (map) {
- kfree(map);
- }
+ kfree(map);
+
/* See if I have any map structures */
if (list_empty(&window->maps)) {
ichxrom_cleanup(window);
@@ -325,11 +324,11 @@ static void __devexit ichxrom_remove_one (struct pci_dev *pdev)
}
static struct pci_device_id ichxrom_pci_tbl[] __devinitdata = {
- { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0,
+ { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0,
PCI_ANY_ID, PCI_ANY_ID, },
- { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_0,
+ { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_0,
PCI_ANY_ID, PCI_ANY_ID, },
- { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0,
+ { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0,
PCI_ANY_ID, PCI_ANY_ID, },
{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0,
PCI_ANY_ID, PCI_ANY_ID, },
diff --git a/drivers/mtd/maps/impa7.c b/drivers/mtd/maps/impa7.c
index cb39172c81d2..ba7f40311a7e 100644
--- a/drivers/mtd/maps/impa7.c
+++ b/drivers/mtd/maps/impa7.c
@@ -1,10 +1,10 @@
/*
- * $Id: impa7.c,v 1.13 2004/11/04 13:24:14 gleixner Exp $
+ * $Id: impa7.c,v 1.14 2005/11/07 11:14:27 gleixner Exp $
*
* Handle mapping of the NOR flash on implementa A7 boards
*
* Copyright 2002 SYSGO Real-Time Solutions GmbH
- *
+ *
* 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.
@@ -55,7 +55,7 @@ static struct map_info impa7_map[NUM_FLASHBANKS] = {
#ifdef CONFIG_MTD_PARTITIONS
/*
- * MTD partitioning stuff
+ * MTD partitioning stuff
*/
static struct mtd_partition static_partitions[] =
{
@@ -108,9 +108,9 @@ int __init init_impa7(void)
impa7_mtd[i]->owner = THIS_MODULE;
devicesfound++;
#ifdef CONFIG_MTD_PARTITIONS
- mtd_parts_nb[i] = parse_mtd_partitions(impa7_mtd[i],
+ mtd_parts_nb[i] = parse_mtd_partitions(impa7_mtd[i],
probes,
- &mtd_parts[i],
+ &mtd_parts[i],
0);
if (mtd_parts_nb[i] > 0) {
part_type = "command line";
@@ -121,16 +121,16 @@ int __init init_impa7(void)
}
printk(KERN_NOTICE MSG_PREFIX
- "using %s partition definition\n",
+ "using %s partition definition\n",
part_type);
- add_mtd_partitions(impa7_mtd[i],
+ add_mtd_partitions(impa7_mtd[i],
mtd_parts[i], mtd_parts_nb[i]);
#else
add_mtd_device(impa7_mtd[i]);
#endif
}
- else
+ else
iounmap((void *)impa7_map[i].virt);
}
return devicesfound == 0 ? -ENXIO : 0;
diff --git a/drivers/mtd/maps/integrator-flash.c b/drivers/mtd/maps/integrator-flash.c
index e39a98a0171c..fe738fd8d6f8 100644
--- a/drivers/mtd/maps/integrator-flash.c
+++ b/drivers/mtd/maps/integrator-flash.c
@@ -1,28 +1,28 @@
/*======================================================================
drivers/mtd/maps/integrator-flash.c: ARM Integrator flash map driver
-
+
Copyright (C) 2000 ARM Limited
Copyright (C) 2003 Deep Blue Solutions Ltd.
-
+
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
-
- This is access code for flashes using ARM's flash partitioning
+
+ This is access code for flashes using ARM's flash partitioning
standards.
- $Id: integrator-flash.c,v 1.18 2004/11/01 13:26:15 rmk Exp $
+ $Id: integrator-flash.c,v 1.20 2005/11/07 11:14:27 gleixner Exp $
======================================================================*/
@@ -32,7 +32,7 @@
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/ioport.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <linux/init.h>
#include <linux/mtd/mtd.h>
@@ -148,8 +148,7 @@ static int armflash_probe(struct device *_dev)
del_mtd_partitions(info->mtd);
map_destroy(info->mtd);
}
- if (info->parts)
- kfree(info->parts);
+ kfree(info->parts);
no_device:
iounmap(base);
@@ -176,8 +175,7 @@ static int armflash_remove(struct device *_dev)
del_mtd_partitions(info->mtd);
map_destroy(info->mtd);
}
- if (info->parts)
- kfree(info->parts);
+ kfree(info->parts);
iounmap(info->map.virt);
release_resource(info->res);
diff --git a/drivers/mtd/maps/ipaq-flash.c b/drivers/mtd/maps/ipaq-flash.c
index 712401810841..35097c9bbf50 100644
--- a/drivers/mtd/maps/ipaq-flash.c
+++ b/drivers/mtd/maps/ipaq-flash.c
@@ -1,11 +1,11 @@
/*
* Flash memory access on iPAQ Handhelds (either SA1100 or PXA250 based)
- *
+ *
* (C) 2000 Nicolas Pitre <nico@cam.org>
* (C) 2002 Hewlett-Packard Company <jamey.hicks@hp.com>
* (C) 2003 Christian Pellegrin <chri@ascensit.com>, <chri@infis.univ.ts.it>: concatenation of multiple flashes
- *
- * $Id: ipaq-flash.c,v 1.3 2004/11/04 13:24:15 gleixner Exp $
+ *
+ * $Id: ipaq-flash.c,v 1.5 2005/11/07 11:14:27 gleixner Exp $
*/
#include <linux/config.h>
@@ -107,7 +107,7 @@ static struct mtd_partition h3xxx_partitions[] = {
#ifndef CONFIG_LAB
mask_flags: MTD_WRITEABLE, /* force read-only */
#endif
- },
+ },
{
name: "H3XXX root jffs2",
#ifndef CONFIG_LAB
@@ -148,7 +148,7 @@ static DEFINE_SPINLOCK(ipaq_vpp_lock);
static void h3xxx_set_vpp(struct map_info *map, int vpp)
{
static int nest = 0;
-
+
spin_lock(&ipaq_vpp_lock);
if (vpp)
nest++;
@@ -191,7 +191,7 @@ static unsigned long cs_phys[] = {
SA1100_CS3_PHYS,
SA1100_CS4_PHYS,
SA1100_CS5_PHYS,
-#else
+#else
PXA_CS0_PHYS,
PXA_CS1_PHYS,
PXA_CS2_PHYS,
@@ -216,7 +216,7 @@ int __init ipaq_mtd_init(void)
/* Default flash bankwidth */
// ipaq_map.bankwidth = (MSC0 & MSC_RBW) ? 2 : 4;
-
+
if (machine_is_h1900())
{
/* For our intents, the h1900 is not a real iPAQ, so we special-case it. */
@@ -229,7 +229,7 @@ int __init ipaq_mtd_init(void)
else
for(i=0; i<MAX_IPAQ_CS; i++)
ipaq_map[i].bankwidth = 4;
-
+
/*
* Static partition definition selection
*/
@@ -309,7 +309,7 @@ int __init ipaq_mtd_init(void)
return -ENXIO;
} else
printk(KERN_NOTICE "iPAQ flash: found %d bytes\n", my_sub_mtd[i]->size);
-
+
/* do we really need this debugging? --joshua 20030703 */
// printk("my_sub_mtd[%d]=%p\n", i, my_sub_mtd[i]);
my_sub_mtd[i]->owner = THIS_MODULE;
@@ -333,11 +333,11 @@ int __init ipaq_mtd_init(void)
#else
mymtd = my_sub_mtd[0];
- /*
+ /*
*In the very near future, command line partition parsing
* will use the device name as 'mtd-id' instead of a value
* passed to the parse_cmdline_partitions() routine. Since
- * the bootldr says 'ipaq', make sure it continues to work.
+ * the bootldr says 'ipaq', make sure it continues to work.
*/
mymtd->name = "ipaq";
@@ -385,7 +385,7 @@ int __init ipaq_mtd_init(void)
*/
i = parse_mtd_partitions(mymtd, part_probes, &parsed_parts, 0);
-
+
if (i > 0) {
nb_parts = parsed_nr_parts = i;
parts = parsed_parts;
@@ -423,16 +423,15 @@ static void __exit ipaq_mtd_cleanup(void)
#endif
map_destroy(mymtd);
#ifdef CONFIG_MTD_CONCAT
- for(i=0; i<MAX_IPAQ_CS; i++)
+ for(i=0; i<MAX_IPAQ_CS; i++)
#else
- for(i=1; i<MAX_IPAQ_CS; i++)
-#endif
+ for(i=1; i<MAX_IPAQ_CS; i++)
+#endif
{
if (my_sub_mtd[i])
map_destroy(my_sub_mtd[i]);
}
- if (parsed_parts)
- kfree(parsed_parts);
+ kfree(parsed_parts);
}
}
@@ -445,14 +444,14 @@ static int __init h1900_special_case(void)
ipaq_map[0].phys = 0x0;
ipaq_map[0].virt = __ioremap(0x0, 0x04000000, 0, 1);
ipaq_map[0].bankwidth = 2;
-
+
printk(KERN_NOTICE "iPAQ flash: probing %d-bit flash bus, window=%lx with JEDEC.\n", ipaq_map[0].bankwidth*8, ipaq_map[0].virt);
mymtd = do_map_probe("jedec_probe", &ipaq_map[0]);
if (!mymtd)
return -ENODEV;
add_mtd_device(mymtd);
printk(KERN_NOTICE "iPAQ flash: registered h1910 flash\n");
-
+
return 0;
}
diff --git a/drivers/mtd/maps/iq80310.c b/drivers/mtd/maps/iq80310.c
index 558d014e7acc..62d9e87d84e2 100644
--- a/drivers/mtd/maps/iq80310.c
+++ b/drivers/mtd/maps/iq80310.c
@@ -1,11 +1,11 @@
/*
- * $Id: iq80310.c,v 1.20 2004/11/04 13:24:15 gleixner Exp $
+ * $Id: iq80310.c,v 1.21 2005/11/07 11:14:27 gleixner Exp $
*
* Mapping for the Intel XScale IQ80310 evaluation board
*
* Author: Nicolas Pitre
* Copyright: (C) 2001 MontaVista Software 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.
@@ -103,8 +103,7 @@ static void __exit cleanup_iq80310(void)
if (mymtd) {
del_mtd_partitions(mymtd);
map_destroy(mymtd);
- if (parsed_parts)
- kfree(parsed_parts);
+ kfree(parsed_parts);
}
if (iq80310_map.virt)
iounmap((void *)iq80310_map.virt);
diff --git a/drivers/mtd/maps/ixp2000.c b/drivers/mtd/maps/ixp2000.c
index a9f86c7fbd52..641eb2b55e9f 100644
--- a/drivers/mtd/maps/ixp2000.c
+++ b/drivers/mtd/maps/ixp2000.c
@@ -1,5 +1,5 @@
/*
- * $Id: ixp2000.c,v 1.6 2005/03/18 14:07:46 gleixner Exp $
+ * $Id: ixp2000.c,v 1.9 2005/11/07 11:14:27 gleixner Exp $
*
* drivers/mtd/maps/ixp2000.c
*
@@ -14,7 +14,7 @@
* 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>
@@ -22,11 +22,14 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/ioport.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+
#include <linux/mtd/mtd.h>
#include <linux/mtd/map.h>
#include <linux/mtd/partitions.h>
-#include <linux/ioport.h>
-#include <linux/device.h>
#include <asm/io.h>
#include <asm/hardware.h>
@@ -43,8 +46,8 @@ struct ixp2000_flash_info {
};
static inline unsigned long flash_bank_setup(struct map_info *map, unsigned long ofs)
-{
- unsigned long (*set_bank)(unsigned long) =
+{
+ unsigned long (*set_bank)(unsigned long) =
(unsigned long(*)(unsigned long))map->map_priv_2;
return (set_bank ? set_bank(ofs) : ofs);
@@ -52,8 +55,8 @@ static inline unsigned long flash_bank_setup(struct map_info *map, unsigned long
#ifdef __ARMEB__
/*
- * Rev A0 and A1 of IXP2400 silicon have a broken addressing unit which
- * causes the lower address bits to be XORed with 0x11 on 8 bit accesses
+ * Rev A0 and A1 of IXP2400 silicon have a broken addressing unit which
+ * causes the lower address bits to be XORed with 0x11 on 8 bit accesses
* and XORed with 0x10 on 16 bit accesses. See the spec update, erratum 44.
*/
static int erratum44_workaround = 0;
@@ -87,7 +90,7 @@ static void ixp2000_flash_copy_from(struct map_info *map, void *to,
unsigned long from, ssize_t len)
{
from = flash_bank_setup(map, from);
- while(len--)
+ while(len--)
*(__u8 *) to++ = *(__u8 *)(map->map_priv_1 + from++);
}
@@ -126,8 +129,7 @@ static int ixp2000_flash_remove(struct device *_dev)
if (info->map.map_priv_1)
iounmap((void *) info->map.map_priv_1);
- if (info->partitions) {
- kfree(info->partitions); }
+ kfree(info->partitions);
if (info->res) {
release_resource(info->res);
@@ -146,11 +148,11 @@ static int ixp2000_flash_probe(struct device *_dev)
static const char *probes[] = { "RedBoot", "cmdlinepart", NULL };
struct platform_device *dev = to_platform_device(_dev);
struct ixp2000_flash_data *ixp_data = dev->dev.platform_data;
- struct flash_platform_data *plat;
+ struct flash_platform_data *plat;
struct ixp2000_flash_info *info;
unsigned long window_size;
int err = -1;
-
+
if (!ixp_data)
return -ENODEV;
@@ -159,7 +161,7 @@ static int ixp2000_flash_probe(struct device *_dev)
return -ENODEV;
window_size = dev->resource->end - dev->resource->start + 1;
- dev_info(_dev, "Probe of IXP2000 flash(%d banks x %dMiB)\n",
+ dev_info(_dev, "Probe of IXP2000 flash(%d banks x %dMiB)\n",
ixp_data->nr_banks, ((u32)window_size >> 20));
if (plat->width != 1) {
@@ -172,7 +174,7 @@ static int ixp2000_flash_probe(struct device *_dev)
if(!info) {
err = -ENOMEM;
goto Error;
- }
+ }
memzero(info, sizeof(struct ixp2000_flash_info));
dev_set_drvdata(&dev->dev, info);
@@ -182,7 +184,7 @@ static int ixp2000_flash_probe(struct device *_dev)
* not attempt to do a direct access on us.
*/
info->map.phys = NO_XIP;
-
+
info->nr_banks = ixp_data->nr_banks;
info->map.size = ixp_data->nr_banks * window_size;
info->map.bankwidth = 1;
@@ -190,7 +192,7 @@ static int ixp2000_flash_probe(struct device *_dev)
/*
* map_priv_2 is used to store a ptr to to the bank_setup routine
*/
- info->map.map_priv_2 = (void __iomem *) ixp_data->bank_setup;
+ info->map.map_priv_2 = (unsigned long) ixp_data->bank_setup;
info->map.name = dev->dev.bus_id;
info->map.read = ixp2000_flash_read8;
@@ -198,8 +200,8 @@ static int ixp2000_flash_probe(struct device *_dev)
info->map.copy_from = ixp2000_flash_copy_from;
info->map.copy_to = ixp2000_flash_copy_to;
- info->res = request_mem_region(dev->resource->start,
- dev->resource->end - dev->resource->start + 1,
+ info->res = request_mem_region(dev->resource->start,
+ dev->resource->end - dev->resource->start + 1,
dev->dev.bus_id);
if (!info->res) {
dev_err(_dev, "Could not reserve memory region\n");
@@ -207,7 +209,7 @@ static int ixp2000_flash_probe(struct device *_dev)
goto Error;
}
- info->map.map_priv_1 = ioremap(dev->resource->start,
+ info->map.map_priv_1 = (unsigned long) ioremap(dev->resource->start,
dev->resource->end - dev->resource->start + 1);
if (!info->map.map_priv_1) {
dev_err(_dev, "Failed to ioremap flash region\n");
diff --git a/drivers/mtd/maps/ixp4xx.c b/drivers/mtd/maps/ixp4xx.c
index 3fcc32884074..56b3a355bf7b 100644
--- a/drivers/mtd/maps/ixp4xx.c
+++ b/drivers/mtd/maps/ixp4xx.c
@@ -1,5 +1,5 @@
/*
- * $Id: ixp4xx.c,v 1.7 2004/11/04 13:24:15 gleixner Exp $
+ * $Id: ixp4xx.c,v 1.12 2005/11/07 11:14:27 gleixner Exp $
*
* drivers/mtd/maps/ixp4xx.c
*
@@ -20,11 +20,15 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/ioport.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+
#include <linux/mtd/mtd.h>
#include <linux/mtd/map.h>
#include <linux/mtd/partitions.h>
-#include <linux/ioport.h>
-#include <linux/device.h>
+
#include <asm/io.h>
#include <asm/mach/flash.h>
@@ -41,7 +45,7 @@
static map_word ixp4xx_read16(struct map_info *map, unsigned long ofs)
{
map_word val;
- val.x[0] = *(__u16 *) (map->map_priv_1 + ofs);
+ val.x[0] = le16_to_cpu(readw(map->virt + ofs));
return val;
}
@@ -55,35 +59,35 @@ static void ixp4xx_copy_from(struct map_info *map, void *to,
{
int i;
u8 *dest = (u8 *) to;
- u16 *src = (u16 *) (map->map_priv_1 + from);
+ void __iomem *src = map->virt + from;
u16 data;
for (i = 0; i < (len / 2); i++) {
- data = src[i];
+ data = le16_to_cpu(readw(src + 2*i));
dest[i * 2] = BYTE0(data);
dest[i * 2 + 1] = BYTE1(data);
}
if (len & 1)
- dest[len - 1] = BYTE0(src[i]);
+ dest[len - 1] = BYTE0(le16_to_cpu(readw(src + 2*i)));
}
-/*
+/*
* Unaligned writes are ignored, causing the 8-bit
* probe to fail and proceed to the 16-bit probe (which succeeds).
*/
static void ixp4xx_probe_write16(struct map_info *map, map_word d, unsigned long adr)
{
if (!(adr & 1))
- *(__u16 *) (map->map_priv_1 + adr) = d.x[0];
+ writew(cpu_to_le16(d.x[0]), map->virt + adr);
}
-/*
+/*
* Fast write16 function without the probing check above
*/
static void ixp4xx_write16(struct map_info *map, map_word d, unsigned long adr)
{
- *(__u16 *) (map->map_priv_1 + adr) = d.x[0];
+ writew(cpu_to_le16(d.x[0]), map->virt + adr);
}
struct ixp4xx_flash_info {
@@ -100,28 +104,20 @@ static int ixp4xx_flash_remove(struct device *_dev)
struct platform_device *dev = to_platform_device(_dev);
struct flash_platform_data *plat = dev->dev.platform_data;
struct ixp4xx_flash_info *info = dev_get_drvdata(&dev->dev);
- map_word d;
dev_set_drvdata(&dev->dev, NULL);
if(!info)
return 0;
- /*
- * This is required for a soft reboot to work.
- */
- d.x[0] = 0xff;
- ixp4xx_write16(&info->map, d, 0x55 * 0x2);
-
if (info->mtd) {
del_mtd_partitions(info->mtd);
map_destroy(info->mtd);
}
- if (info->map.map_priv_1)
- iounmap((void *) info->map.map_priv_1);
+ if (info->map.virt)
+ iounmap(info->map.virt);
- if (info->partitions)
- kfree(info->partitions);
+ kfree(info->partitions);
if (info->res) {
release_resource(info->res);
@@ -131,9 +127,6 @@ static int ixp4xx_flash_remove(struct device *_dev)
if (plat->exit)
plat->exit();
- /* Disable flash write */
- *IXP4XX_EXP_CS0 &= ~IXP4XX_FLASH_WRITABLE;
-
return 0;
}
@@ -157,17 +150,11 @@ static int ixp4xx_flash_probe(struct device *_dev)
if(!info) {
err = -ENOMEM;
goto Error;
- }
+ }
memzero(info, sizeof(struct ixp4xx_flash_info));
dev_set_drvdata(&dev->dev, info);
- /*
- * Enable flash write
- * TODO: Move this out to board specific code
- */
- *IXP4XX_EXP_CS0 |= IXP4XX_FLASH_WRITABLE;
-
/*
* Tell the MTD layer we're not 1:1 mapped so that it does
* not attempt to do a direct access on us.
@@ -186,8 +173,8 @@ static int ixp4xx_flash_probe(struct device *_dev)
info->map.write = ixp4xx_probe_write16,
info->map.copy_from = ixp4xx_copy_from,
- info->res = request_mem_region(dev->resource->start,
- dev->resource->end - dev->resource->start + 1,
+ info->res = request_mem_region(dev->resource->start,
+ dev->resource->end - dev->resource->start + 1,
"IXP4XXFlash");
if (!info->res) {
printk(KERN_ERR "IXP4XXFlash: Could not reserve memory region\n");
@@ -195,9 +182,9 @@ static int ixp4xx_flash_probe(struct device *_dev)
goto Error;
}
- info->map.map_priv_1 = ioremap(dev->resource->start,
- dev->resource->end - dev->resource->start + 1);
- if (!info->map.map_priv_1) {
+ info->map.virt = ioremap(dev->resource->start,
+ dev->resource->end - dev->resource->start + 1);
+ if (!info->map.virt) {
printk(KERN_ERR "IXP4XXFlash: Failed to ioremap region\n");
err = -EIO;
goto Error;
@@ -210,7 +197,7 @@ static int ixp4xx_flash_probe(struct device *_dev)
goto Error;
}
info->mtd->owner = THIS_MODULE;
-
+
/* Use the fast version */
info->map.write = ixp4xx_write16,
@@ -255,4 +242,3 @@ module_exit(ixp4xx_flash_exit);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("MTD map driver for Intel IXP4xx systems");
MODULE_AUTHOR("Deepak Saxena");
-
diff --git a/drivers/mtd/maps/l440gx.c b/drivers/mtd/maps/l440gx.c
index b08668212ab7..851bf9576052 100644
--- a/drivers/mtd/maps/l440gx.c
+++ b/drivers/mtd/maps/l440gx.c
@@ -1,5 +1,5 @@
/*
- * $Id: l440gx.c,v 1.17 2004/11/28 09:40:39 dwmw2 Exp $
+ * $Id: l440gx.c,v 1.18 2005/11/07 11:14:27 gleixner Exp $
*
* BIOS Flash chip on Intel 440GX board.
*
@@ -49,7 +49,7 @@ static struct map_info l440gx_map = {
.bankwidth = BUSWIDTH,
.phys = WINDOW_ADDR,
#if 0
- /* FIXME verify that this is the
+ /* FIXME verify that this is the
* appripriate code for vpp enable/disable
*/
.set_vpp = l440gx_set_vpp
@@ -62,10 +62,10 @@ static int __init init_l440gx(void)
struct resource *pm_iobase;
__u16 word;
- dev = pci_find_device(PCI_VENDOR_ID_INTEL,
+ dev = pci_find_device(PCI_VENDOR_ID_INTEL,
PCI_DEVICE_ID_INTEL_82371AB_0, NULL);
- pm_dev = pci_find_device(PCI_VENDOR_ID_INTEL,
+ pm_dev = pci_find_device(PCI_VENDOR_ID_INTEL,
PCI_DEVICE_ID_INTEL_82371AB_3, NULL);
if (!dev || !pm_dev) {
@@ -82,10 +82,10 @@ static int __init init_l440gx(void)
simple_map_init(&l440gx_map);
printk(KERN_NOTICE "window_addr = 0x%08lx\n", (unsigned long)l440gx_map.virt);
- /* Setup the pm iobase resource
+ /* Setup the pm iobase resource
* This code should move into some kind of generic bridge
* driver but for the moment I'm content with getting the
- * allocation correct.
+ * allocation correct.
*/
pm_iobase = &pm_dev->resource[PIIXE_IOBASE_RESOURCE];
if (!(pm_iobase->flags & IORESOURCE_IO)) {
@@ -110,7 +110,7 @@ static int __init init_l440gx(void)
/* Set the iobase */
iobase = pm_iobase->start;
pci_write_config_dword(pm_dev, 0x40, iobase | 1);
-
+
/* Set XBCS# */
pci_read_config_word(dev, 0x4e, &word);
@@ -122,7 +122,7 @@ static int __init init_l440gx(void)
/* Enable the gate on the WE line */
outb(inb(TRIBUF_PORT) & ~1, TRIBUF_PORT);
-
+
printk(KERN_NOTICE "Enabled WE line to L440GX BIOS flash chip.\n");
mymtd = do_map_probe("jedec_probe", &l440gx_map);
@@ -145,7 +145,7 @@ static void __exit cleanup_l440gx(void)
{
del_mtd_device(mymtd);
map_destroy(mymtd);
-
+
iounmap(l440gx_map.virt);
}
diff --git a/drivers/mtd/maps/lubbock-flash.c b/drivers/mtd/maps/lubbock-flash.c
index 1298de475c9a..1aa0447c5e66 100644
--- a/drivers/mtd/maps/lubbock-flash.c
+++ b/drivers/mtd/maps/lubbock-flash.c
@@ -1,11 +1,11 @@
/*
- * $Id: lubbock-flash.c,v 1.19 2004/11/04 13:24:15 gleixner Exp $
+ * $Id: lubbock-flash.c,v 1.21 2005/11/07 11:14:27 gleixner Exp $
*
* Map driver for the Lubbock developer platform.
*
* Author: Nicolas Pitre
* Copyright: (C) 2001 MontaVista Software 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.
@@ -15,10 +15,13 @@
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/init.h>
+#include <linux/slab.h>
+
#include <linux/dma-mapping.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/map.h>
#include <linux/mtd/partitions.h>
+
#include <asm/io.h>
#include <asm/hardware.h>
#include <asm/arch/pxa-regs.h>
@@ -73,7 +76,7 @@ static int __init init_lubbock(void)
int flashboot = (LUB_CONF_SWITCHES & 1);
int ret = 0, i;
- lubbock_maps[0].bankwidth = lubbock_maps[1].bankwidth =
+ lubbock_maps[0].bankwidth = lubbock_maps[1].bankwidth =
(BOOT_DEF & 1) ? 2 : 4;
/* Compensate for the nROMBT switch which swaps the flash banks */
@@ -97,11 +100,11 @@ static int __init init_lubbock(void)
simple_map_init(&lubbock_maps[i]);
printk(KERN_NOTICE "Probing %s at physical address 0x%08lx (%d-bit bankwidth)\n",
- lubbock_maps[i].name, lubbock_maps[i].phys,
+ lubbock_maps[i].name, lubbock_maps[i].phys,
lubbock_maps[i].bankwidth * 8);
mymtds[i] = do_map_probe("cfi_probe", &lubbock_maps[i]);
-
+
if (!mymtds[i]) {
iounmap((void *)lubbock_maps[i].virt);
if (lubbock_maps[i].cached)
@@ -121,7 +124,7 @@ static int __init init_lubbock(void)
if (!mymtds[0] && !mymtds[1])
return ret;
-
+
for (i = 0; i < 2; i++) {
if (!mymtds[i]) {
printk(KERN_WARNING "%s is absent. Skipping\n", lubbock_maps[i].name);
@@ -148,15 +151,14 @@ static void __exit cleanup_lubbock(void)
if (nr_parsed_parts[i] || !i)
del_mtd_partitions(mymtds[i]);
else
- del_mtd_device(mymtds[i]);
+ del_mtd_device(mymtds[i]);
map_destroy(mymtds[i]);
iounmap((void *)lubbock_maps[i].virt);
if (lubbock_maps[i].cached)
iounmap(lubbock_maps[i].cached);
- if (parsed_parts[i])
- kfree(parsed_parts[i]);
+ kfree(parsed_parts[i]);
}
}
diff --git a/drivers/mtd/maps/mainstone-flash.c b/drivers/mtd/maps/mainstone-flash.c
index 87e93fa60588..eaa4bbb868a3 100644
--- a/drivers/mtd/maps/mainstone-flash.c
+++ b/drivers/mtd/maps/mainstone-flash.c
@@ -5,7 +5,7 @@
*
* Author: Nicolas Pitre
* Copyright: (C) 2001 MontaVista Software 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.
@@ -16,9 +16,12 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/dma-mapping.h>
+#include <linux/slab.h>
+
#include <linux/mtd/mtd.h>
#include <linux/mtd/map.h>
#include <linux/mtd/partitions.h>
+
#include <asm/io.h>
#include <asm/hardware.h>
#include <asm/arch/pxa-regs.h>
@@ -88,27 +91,27 @@ static int __init init_mainstone(void)
mainstone_maps[i].virt = ioremap(mainstone_maps[i].phys,
WINDOW_SIZE);
if (!mainstone_maps[i].virt) {
- printk(KERN_WARNING "Failed to ioremap %s\n",
+ printk(KERN_WARNING "Failed to ioremap %s\n",
mainstone_maps[i].name);
if (!ret)
ret = -ENOMEM;
continue;
}
- mainstone_maps[i].cached =
+ mainstone_maps[i].cached =
ioremap_cached(mainstone_maps[i].phys, WINDOW_SIZE);
if (!mainstone_maps[i].cached)
printk(KERN_WARNING "Failed to ioremap cached %s\n",
mainstone_maps[i].name);
simple_map_init(&mainstone_maps[i]);
- printk(KERN_NOTICE
+ printk(KERN_NOTICE
"Probing %s at physical address 0x%08lx"
" (%d-bit bankwidth)\n",
- mainstone_maps[i].name, mainstone_maps[i].phys,
+ mainstone_maps[i].name, mainstone_maps[i].phys,
mainstone_maps[i].bankwidth * 8);
mymtds[i] = do_map_probe("cfi_probe", &mainstone_maps[i]);
-
+
if (!mymtds[i]) {
iounmap((void *)mainstone_maps[i].virt);
if (mainstone_maps[i].cached)
@@ -128,21 +131,21 @@ static int __init init_mainstone(void)
if (!mymtds[0] && !mymtds[1])
return ret;
-
+
for (i = 0; i < 2; i++) {
if (!mymtds[i]) {
- printk(KERN_WARNING "%s is absent. Skipping\n",
+ printk(KERN_WARNING "%s is absent. Skipping\n",
mainstone_maps[i].name);
} else if (nr_parsed_parts[i]) {
- add_mtd_partitions(mymtds[i], parsed_parts[i],
+ add_mtd_partitions(mymtds[i], parsed_parts[i],
nr_parsed_parts[i]);
} else if (!i) {
printk("Using static partitions on %s\n",
mainstone_maps[i].name);
- add_mtd_partitions(mymtds[i], mainstone_partitions,
+ add_mtd_partitions(mymtds[i], mainstone_partitions,
ARRAY_SIZE(mainstone_partitions));
} else {
- printk("Registering %s as whole device\n",
+ printk("Registering %s as whole device\n",
mainstone_maps[i].name);
add_mtd_device(mymtds[i]);
}
diff --git a/drivers/mtd/maps/mbx860.c b/drivers/mtd/maps/mbx860.c
index c5c6901a4763..06b118727846 100644
--- a/drivers/mtd/maps/mbx860.c
+++ b/drivers/mtd/maps/mbx860.c
@@ -1,11 +1,11 @@
/*
- * $Id: mbx860.c,v 1.8 2004/11/04 13:24:15 gleixner Exp $
+ * $Id: mbx860.c,v 1.9 2005/11/07 11:14:27 gleixner Exp $
*
* Handle mapping of the flash on MBX860 boards
*
* Author: Anton Todorov
* Copyright: (C) 2001 Emness Technology
- *
+ *
* 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.
@@ -46,7 +46,7 @@ static struct mtd_partition partition_info[]={
{ .name = "MBX flash APPLICATION partition",
.offset = (BOOT_PARTITION_SIZE_KiB+KERNEL_PARTITION_SIZE_KiB)*1024 }
};
-
+
static struct mtd_info *mymtd;
diff --git a/drivers/mtd/maps/mtx-1_flash.c b/drivers/mtd/maps/mtx-1_flash.c
new file mode 100644
index 000000000000..d1e66e186746
--- /dev/null
+++ b/drivers/mtd/maps/mtx-1_flash.c
@@ -0,0 +1,96 @@
+/*
+ * Flash memory access on 4G Systems MTX-1 boards
+ *
+ * $Id: mtx-1_flash.c,v 1.2 2005/11/07 11:14:27 gleixner Exp $
+ *
+ * (C) 2005 Bruno Randolf <bruno.randolf@4g-systems.biz>
+ * (C) 2005 Jörn Engel <joern@wohnheim.fh-wedel.de>
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/partitions.h>
+
+#include <asm/io.h>
+
+static struct map_info mtx1_map = {
+ .name = "MTX-1 flash",
+ .bankwidth = 4,
+ .size = 0x2000000,
+ .phys = 0x1E000000,
+};
+
+static struct mtd_partition mtx1_partitions[] = {
+ {
+ .name = "filesystem",
+ .size = 0x01C00000,
+ .offset = 0,
+ },{
+ .name = "yamon",
+ .size = 0x00100000,
+ .offset = MTDPART_OFS_APPEND,
+ .mask_flags = MTD_WRITEABLE,
+ },{
+ .name = "kernel",
+ .size = 0x002c0000,
+ .offset = MTDPART_OFS_APPEND,
+ },{
+ .name = "yamon env",
+ .size = 0x00040000,
+ .offset = MTDPART_OFS_APPEND,
+ }
+};
+
+static struct mtd_info *mtx1_mtd;
+
+int __init mtx1_mtd_init(void)
+{
+ int ret = -ENXIO;
+
+ simple_map_init(&mtx1_map);
+
+ mtx1_map.virt = ioremap(mtx1_map.phys, mtx1_map.size);
+ if (!mtx1_map.virt)
+ return -EIO;
+
+ mtx1_mtd = do_map_probe("cfi_probe", &mtx1_map);
+ if (!mtx1_mtd)
+ goto err;
+
+ mtx1_mtd->owner = THIS_MODULE;
+
+ ret = add_mtd_partitions(mtx1_mtd, mtx1_partitions,
+ ARRAY_SIZE(mtx1_partitions));
+ if (ret)
+ goto err;
+
+ return 0;
+
+err:
+ iounmap(mtx1_map.virt);
+ return ret;
+}
+
+static void __exit mtx1_mtd_cleanup(void)
+{
+ if (mtx1_mtd) {
+ del_mtd_partitions(mtx1_mtd);
+ map_destroy(mtx1_mtd);
+ }
+ if (mtx1_map.virt)
+ iounmap(mtx1_map.virt);
+}
+
+module_init(mtx1_mtd_init);
+module_exit(mtx1_mtd_cleanup);
+
+MODULE_AUTHOR("Bruno Randolf <bruno.randolf@4g-systems.biz>");
+MODULE_DESCRIPTION("MTX-1 flash map");
+MODULE_LICENSE("GPL");
diff --git a/drivers/mtd/maps/netsc520.c b/drivers/mtd/maps/netsc520.c
index ab7e6358d281..33060a315722 100644
--- a/drivers/mtd/maps/netsc520.c
+++ b/drivers/mtd/maps/netsc520.c
@@ -3,7 +3,7 @@
* Copyright (C) 2001 Mark Langsdorf (mark.langsdorf@amd.com)
* based on sc520cdp.c by Sysgo Real-Time Solutions GmbH
*
- * $Id: netsc520.c,v 1.13 2004/11/28 09:40:40 dwmw2 Exp $
+ * $Id: netsc520.c,v 1.14 2005/11/07 11:14:27 gleixner Exp $
*
* 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
@@ -38,7 +38,7 @@
** The single, 16 megabyte flash bank is divided into four virtual
** partitions. The first partition is 768 KiB and is intended to
** store the kernel image loaded by the bootstrap loader. The second
-** partition is 256 KiB and holds the BIOS image. The third
+** partition is 256 KiB and holds the BIOS image. The third
** partition is 14.5 MiB and is intended for the flash file system
** image. The last partition is 512 KiB and contains another copy
** of the BIOS image and the reset vector.
@@ -51,28 +51,28 @@
** recoverable afterwards.
*/
-/* partition_info gives details on the logical partitions that the split the
+/* partition_info gives details on the logical partitions that the split the
* single flash device into. If the size if zero we use up to the end of the
* device. */
static struct mtd_partition partition_info[]={
- {
- .name = "NetSc520 boot kernel",
- .offset = 0,
+ {
+ .name = "NetSc520 boot kernel",
+ .offset = 0,
.size = 0xc0000
},
- {
- .name = "NetSc520 Low BIOS",
- .offset = 0xc0000,
+ {
+ .name = "NetSc520 Low BIOS",
+ .offset = 0xc0000,
.size = 0x40000
},
- {
- .name = "NetSc520 file system",
- .offset = 0x100000,
+ {
+ .name = "NetSc520 file system",
+ .offset = 0x100000,
.size = 0xe80000
},
- {
- .name = "NetSc520 High BIOS",
- .offset = 0xf80000,
+ {
+ .name = "NetSc520 High BIOS",
+ .offset = 0xf80000,
.size = 0x80000
},
};
@@ -114,7 +114,7 @@ static int __init init_netsc520(void)
iounmap(netsc520_map.virt);
return -ENXIO;
}
-
+
mymtd->owner = THIS_MODULE;
add_mtd_partitions( mymtd, partition_info, NUM_PARTITIONS );
return 0;
diff --git a/drivers/mtd/maps/nettel.c b/drivers/mtd/maps/nettel.c
index 61be5a4148c9..f00ee7e54dba 100644
--- a/drivers/mtd/maps/nettel.c
+++ b/drivers/mtd/maps/nettel.c
@@ -6,7 +6,7 @@
* (C) Copyright 2000-2001, Greg Ungerer (gerg@snapgear.com)
* (C) Copyright 2001-2002, SnapGear (www.snapgear.com)
*
- * $Id: nettel.c,v 1.10 2005/01/05 17:11:29 dwmw2 Exp $
+ * $Id: nettel.c,v 1.11 2005/11/07 11:14:27 gleixner Exp $
*/
/****************************************************************************/
@@ -143,7 +143,7 @@ static int nettel_reboot_notifier(struct notifier_block *nb, unsigned long val,
{
struct cfi_private *cfi = nettel_intel_map.fldrv_priv;
unsigned long b;
-
+
/* Make sure all FLASH chips are put back into read mode */
for (b = 0; (b < nettel_intel_partitions[3].size); b += 0x100000) {
cfi_send_gen_cmd(0xff, 0x55, b, &nettel_intel_map, cfi,
@@ -199,7 +199,7 @@ int nettel_eraseconfig(void)
schedule(); /* Wait for erase to finish. */
remove_wait_queue(&wait_q, &wait);
-
+
put_mtd_device(mtd);
}
@@ -430,7 +430,7 @@ int __init nettel_init(void)
nettel_intel_partitions[1].size = (intel0size + intel1size) -
(1024*1024 + intel_mtd->erasesize);
nettel_intel_partitions[3].size = intel0size + intel1size;
- nettel_intel_partitions[4].offset =
+ nettel_intel_partitions[4].offset =
(intel0size + intel1size) - intel_mtd->erasesize;
nettel_intel_partitions[4].size = intel_mtd->erasesize;
nettel_intel_partitions[5].offset =
diff --git a/drivers/mtd/maps/ocelot.c b/drivers/mtd/maps/ocelot.c
index 82c3070678c5..6977963d7897 100644
--- a/drivers/mtd/maps/ocelot.c
+++ b/drivers/mtd/maps/ocelot.c
@@ -1,5 +1,5 @@
/*
- * $Id: ocelot.c,v 1.16 2005/01/05 18:05:13 dwmw2 Exp $
+ * $Id: ocelot.c,v 1.17 2005/11/07 11:14:27 gleixner Exp $
*
* Flash on Momenco Ocelot
*/
@@ -31,7 +31,7 @@ static void ocelot_ram_write(struct mtd_info *mtd, loff_t to, size_t len, size_t
struct map_info *map = mtd->priv;
size_t done = 0;
- /* If we use memcpy, it does word-wide writes. Even though we told the
+ /* If we use memcpy, it does word-wide writes. Even though we told the
GT64120A that it's an 8-bit wide region, word-wide writes don't work.
We end up just writing the first byte of the four to all four bytes.
So we have this loop instead */
@@ -68,7 +68,7 @@ static int __init init_ocelot_maps(void)
int nr_parts;
unsigned char brd_status;
- printk(KERN_INFO "Momenco Ocelot MTD mappings: Flash 0x%x at 0x%x, NVRAM 0x%x at 0x%x\n",
+ printk(KERN_INFO "Momenco Ocelot MTD mappings: Flash 0x%x at 0x%x, NVRAM 0x%x at 0x%x\n",
FLASH_WINDOW_SIZE, FLASH_WINDOW_ADDR, NVRAM_WINDOW_SIZE, NVRAM_WINDOW_ADDR);
/* First check whether the flash jumper is present */
@@ -138,8 +138,8 @@ static int __init init_ocelot_maps(void)
add_mtd_device(flash_mtd);
return 0;
-
- fail3:
+
+ fail3:
iounmap((void *)ocelot_flash_map.virt);
if (ocelot_flash_map.cached)
iounmap((void *)ocelot_flash_map.cached);
diff --git a/drivers/mtd/maps/ocotea.c b/drivers/mtd/maps/ocotea.c
index 6e559bc14636..c223514ca2eb 100644
--- a/drivers/mtd/maps/ocotea.c
+++ b/drivers/mtd/maps/ocotea.c
@@ -19,7 +19,6 @@
#include <linux/mtd/map.h>
#include <linux/mtd/partitions.h>
#include <linux/config.h>
-#include <linux/version.h>
#include <asm/io.h>
#include <asm/ibm44x.h>
#include <platforms/4xx/ocotea.h>
diff --git a/drivers/mtd/maps/octagon-5066.c b/drivers/mtd/maps/octagon-5066.c
index e5ff83de420e..a6642db3d325 100644
--- a/drivers/mtd/maps/octagon-5066.c
+++ b/drivers/mtd/maps/octagon-5066.c
@@ -1,12 +1,12 @@
-// $Id: octagon-5066.c,v 1.26 2004/07/12 22:38:29 dwmw2 Exp $
+// $Id: octagon-5066.c,v 1.28 2005/11/07 11:14:27 gleixner Exp $
/* ######################################################################
- Octagon 5066 MTD Driver.
-
+ Octagon 5066 MTD Driver.
+
The Octagon 5066 is a SBC based on AMD's 586-WB running at 133 MHZ. It
comes with a builtin AMD 29F016 flash chip and a socketed EEPROM that
is replacable by flash. Both units are mapped through a multiplexer
- into a 32k memory window at 0xe8000. The control register for the
+ into a 32k memory window at 0xe8000. The control register for the
multiplexing unit is located at IO 0x208 with a bit map of
0-5 Page Selection in 32k increments
6-7 Device selection:
@@ -14,14 +14,14 @@
01 SSD 0 (Socket)
10 SSD 1 (Flash chip)
11 undefined
-
+
On each SSD, the first 128k is reserved for use by the bios
- (actually it IS the bios..) This only matters if you are booting off the
+ (actually it IS the bios..) This only matters if you are booting off the
flash, you must not put a file system starting there.
-
+
The driver tries to do a detection algorithm to guess what sort of devices
are plugged into the sockets.
-
+
##################################################################### */
#include <linux/module.h>
@@ -56,7 +56,7 @@ static void __oct5066_page(struct map_info *map, __u8 byte)
static inline void oct5066_page(struct map_info *map, unsigned long ofs)
{
__u8 byte = map->map_priv_1 | (ofs >> WINDOW_SHIFT);
-
+
if (page_n_dev != byte)
__oct5066_page(map, byte);
}
@@ -78,7 +78,7 @@ static void oct5066_copy_from(struct map_info *map, void *to, unsigned long from
unsigned long thislen = len;
if (len > (WINDOW_LENGTH - (from & WINDOW_MASK)))
thislen = WINDOW_LENGTH-(from & WINDOW_MASK);
-
+
spin_lock(&oct5066_spin);
oct5066_page(map, from);
memcpy_fromio(to, iomapadr + from, thislen);
@@ -103,7 +103,7 @@ static void oct5066_copy_to(struct map_info *map, unsigned long to, const void *
unsigned long thislen = len;
if (len > (WINDOW_LENGTH - (to & WINDOW_MASK)))
thislen = WINDOW_LENGTH-(to & WINDOW_MASK);
-
+
spin_lock(&oct5066_spin);
oct5066_page(map, to);
memcpy_toio(iomapadr + to, from, thislen);
@@ -144,7 +144,7 @@ static struct mtd_info *oct5066_mtd[2] = {NULL, NULL};
// OctProbe - Sense if this is an octagon card
// ---------------------------------------------------------------------
/* Perform a simple validity test, we map the window select SSD0 and
- change pages while monitoring the window. A change in the window,
+ change pages while monitoring the window. A change in the window,
controlled by the PAGE_IO port is a functioning 5066 board. This will
fail if the thing in the socket is set to a uniform value. */
static int __init OctProbe(void)
@@ -161,13 +161,13 @@ static int __init OctProbe(void)
Values[I%10] = readl(iomapadr);
if (I > 0 && Values[I%10] == Values[0])
return -EAGAIN;
- }
+ }
else
{
// Make sure we get the same values on the second pass
if (Values[I%10] != readl(iomapadr))
return -EAGAIN;
- }
+ }
}
return 0;
}
@@ -207,11 +207,11 @@ int __init init_oct5066(void)
ret = -EAGAIN;
goto out_unmap;
}
-
+
// Print out our little header..
printk("Octagon 5066 SSD IO:0x%x MEM:0x%x-0x%x\n",PAGE_IO,WINDOW_START,
WINDOW_START+WINDOW_LENGTH);
-
+
for (i=0; i<2; i++) {
oct5066_mtd[i] = do_map_probe("cfi_probe", &oct5066_map[i]);
if (!oct5066_mtd[i])
@@ -225,11 +225,11 @@ int __init init_oct5066(void)
add_mtd_device(oct5066_mtd[i]);
}
}
-
+
if (!oct5066_mtd[0] && !oct5066_mtd[1]) {
cleanup_oct5066();
return -ENXIO;
- }
+ }
return 0;
diff --git a/drivers/mtd/maps/omap-toto-flash.c b/drivers/mtd/maps/omap-toto-flash.c
index 496109071cb1..dc3765270057 100644
--- a/drivers/mtd/maps/omap-toto-flash.c
+++ b/drivers/mtd/maps/omap-toto-flash.c
@@ -5,16 +5,16 @@
*
* (C) 2002 MontVista Software, Inc.
*
- * $Id: omap-toto-flash.c,v 1.3 2004/09/16 23:27:13 gleixner Exp $
+ * $Id: omap-toto-flash.c,v 1.5 2005/11/07 11:14:27 gleixner Exp $
*/
#include <linux/config.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/kernel.h>
-
#include <linux/errno.h>
#include <linux/init.h>
+#include <linux/slab.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/map.h>
@@ -38,7 +38,7 @@ static struct map_info omap_toto_map_flash = {
.virt = (void __iomem *)OMAP_TOTO_FLASH_BASE,
};
-
+
static struct mtd_partition toto_flash_partitions[] = {
{
.name = "BootLoader",
@@ -54,21 +54,21 @@ static struct mtd_partition toto_flash_partitions[] = {
.name = "EnvArea", /* bottom 64KiB for env vars */
.size = MTDPART_SIZ_FULL,
.offset = MTDPART_OFS_APPEND,
- }
+ }
};
static struct mtd_partition *parsed_parts;
static struct mtd_info *flash_mtd;
-
-static int __init init_flash (void)
+
+static int __init init_flash (void)
{
struct mtd_partition *parts;
int nb_parts = 0;
int parsed_nr_parts = 0;
const char *part_type;
-
+
/*
* Static partition definition selection
*/
@@ -89,7 +89,7 @@ static int __init init_flash (void)
flash_mtd = do_map_probe("jedec_probe", &omap_toto_map_flash);
if (!flash_mtd)
return -ENXIO;
-
+
if (parsed_nr_parts > 0) {
parts = parsed_parts;
nb_parts = parsed_nr_parts;
@@ -108,8 +108,8 @@ static int __init init_flash (void)
}
return 0;
}
-
-int __init omap_toto_mtd_init(void)
+
+int __init omap_toto_mtd_init(void)
{
int status;
@@ -119,13 +119,12 @@ int __init omap_toto_mtd_init(void)
return status;
}
-static void __exit omap_toto_mtd_cleanup(void)
+static void __exit omap_toto_mtd_cleanup(void)
{
if (flash_mtd) {
del_mtd_partitions(flash_mtd);
map_destroy(flash_mtd);
- if (parsed_parts)
- kfree(parsed_parts);
+ kfree(parsed_parts);
}
}
diff --git a/drivers/mtd/maps/omap_nor.c b/drivers/mtd/maps/omap_nor.c
index b17bca657daf..fd3b4a5fc207 100644
--- a/drivers/mtd/maps/omap_nor.c
+++ b/drivers/mtd/maps/omap_nor.c
@@ -3,7 +3,7 @@
*
* Copyright (C) 2001-2002 MontaVista Software Inc.
* Copyright (C) 2003-2004 Texas Instruments
- * Copyright (C) 2004 Nokia Corporation
+ * Copyright (C) 2004 Nokia Corporation
*
* Assembled using driver code copyright the companies above
* and written by David Brownell, Jian Zhang <jzhang@ti.com>,
@@ -30,12 +30,14 @@
* 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/ioport.h>
+#include <linux/slab.h>
+
#include <linux/mtd/mtd.h>
#include <linux/mtd/map.h>
#include <linux/mtd/partitions.h>
diff --git a/drivers/mtd/maps/pci.c b/drivers/mtd/maps/pci.c
index 18dbd3af1eaa..8b3570b09095 100644
--- a/drivers/mtd/maps/pci.c
+++ b/drivers/mtd/maps/pci.c
@@ -7,8 +7,8 @@
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
- * $Id: pci.c,v 1.10 2005/03/18 14:04:35 gleixner Exp $
- *
+ * $Id: pci.c,v 1.13 2005/11/07 11:14:27 gleixner Exp $
+ *
* Generic PCI memory map driver. We support the following boards:
* - Intel IQ80310 ATU.
* - Intel EBSA285 (blank rom programming mode). Tested working 27/09/2001
@@ -17,6 +17,7 @@
#include <linux/kernel.h>
#include <linux/pci.h>
#include <linux/init.h>
+#include <linux/slab.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/map.h>
@@ -37,7 +38,7 @@ struct map_pci_info {
void (*exit)(struct pci_dev *dev, struct map_pci_info *map);
unsigned long (*translate)(struct map_pci_info *map, unsigned long ofs);
struct pci_dev *dev;
-};
+};
static map_word mtd_pci_read8(struct map_info *_map, unsigned long ofs)
{
diff --git a/drivers/mtd/maps/pcmciamtd.c b/drivers/mtd/maps/pcmciamtd.c
index ff7c50d10180..af24216a0626 100644
--- a/drivers/mtd/maps/pcmciamtd.c
+++ b/drivers/mtd/maps/pcmciamtd.c
@@ -1,5 +1,5 @@
/*
- * $Id: pcmciamtd.c,v 1.51 2004/07/12 22:38:29 dwmw2 Exp $
+ * $Id: pcmciamtd.c,v 1.55 2005/11/07 11:14:28 gleixner Exp $
*
* pcmciamtd.c - MTD driver for PCMCIA flash memory cards
*
@@ -48,7 +48,7 @@ static const int debug = 0;
#define DRIVER_DESC "PCMCIA Flash memory card driver"
-#define DRIVER_VERSION "$Revision: 1.51 $"
+#define DRIVER_VERSION "$Revision: 1.55 $"
/* Size of the PCMCIA address space: 26 bits = 64 MB */
#define MAX_PCMCIA_ADDR 0x4000000
@@ -176,7 +176,7 @@ static void pcmcia_copy_from_remap(struct map_info *map, void *to, unsigned long
if(toread > len)
toread = len;
-
+
addr = remap_window(map, from);
if(!addr)
return;
@@ -386,7 +386,7 @@ static void card_settings(struct pcmciamtd_dev *dev, dev_link_t *link, int *new_
cs_error(link->handle, ParseTuple, rc);
break;
}
-
+
switch(tuple.TupleCode) {
case CISTPL_FORMAT: {
cistpl_format_t *t = &parse.format;
@@ -394,9 +394,9 @@ static void card_settings(struct pcmciamtd_dev *dev, dev_link_t *link, int *new_
DEBUG(2, "Format type: %u, Error Detection: %u, offset = %u, length =%u",
t->type, t->edc, t->offset, t->length);
break;
-
+
}
-
+
case CISTPL_DEVICE: {
cistpl_device_t *t = &parse.device;
int i;
@@ -410,7 +410,7 @@ static void card_settings(struct pcmciamtd_dev *dev, dev_link_t *link, int *new_
}
break;
}
-
+
case CISTPL_VERS_1: {
cistpl_vers_1_t *t = &parse.version_1;
int i;
@@ -425,7 +425,7 @@ static void card_settings(struct pcmciamtd_dev *dev, dev_link_t *link, int *new_
DEBUG(2, "Found name: %s", dev->mtd_name);
break;
}
-
+
case CISTPL_JEDEC_C: {
cistpl_jedec_t *t = &parse.jedec;
int i;
@@ -434,7 +434,7 @@ static void card_settings(struct pcmciamtd_dev *dev, dev_link_t *link, int *new_
}
break;
}
-
+
case CISTPL_DEVICE_GEO: {
cistpl_device_geo_t *t = &parse.device_geo;
int i;
@@ -449,11 +449,11 @@ static void card_settings(struct pcmciamtd_dev *dev, dev_link_t *link, int *new_
}
break;
}
-
+
default:
DEBUG(2, "Unknown tuple code %d", tuple.TupleCode);
}
-
+
rc = pcmcia_get_next_tuple(link->handle, &tuple);
}
if(!dev->pcmcia_map.size)
@@ -470,7 +470,7 @@ static void card_settings(struct pcmciamtd_dev *dev, dev_link_t *link, int *new_
if(bankwidth) {
dev->pcmcia_map.bankwidth = bankwidth;
DEBUG(2, "bankwidth forced to %d", bankwidth);
- }
+ }
dev->pcmcia_map.name = dev->mtd_name;
if(!dev->mtd_name[0]) {
@@ -568,7 +568,7 @@ static void pcmciamtd_config(dev_link_t *link)
return;
}
DEBUG(1, "Allocated a window of %dKiB", dev->win_size >> 10);
-
+
/* Get write protect status */
CS_CHECK(GetStatus, pcmcia_get_status(link->handle, &status));
DEBUG(2, "status value: 0x%x window handle = 0x%8.8lx",
@@ -624,11 +624,11 @@ static void pcmciamtd_config(dev_link_t *link)
mtd = do_map_probe(probes[i], &dev->pcmcia_map);
if(mtd)
break;
-
+
DEBUG(1, "FAILED: %s", probes[i]);
}
}
-
+
if(!mtd) {
DEBUG(1, "Cant find an MTD");
pcmciamtd_release(link);
diff --git a/drivers/mtd/maps/physmap.c b/drivers/mtd/maps/physmap.c
index b853670bfb81..9ee760f97bc6 100644
--- a/drivers/mtd/maps/physmap.c
+++ b/drivers/mtd/maps/physmap.c
@@ -1,5 +1,5 @@
/*
- * $Id: physmap.c,v 1.37 2004/11/28 09:40:40 dwmw2 Exp $
+ * $Id: physmap.c,v 1.38 2005/11/07 11:14:28 gleixner Exp $
*
* Normal mappings of chips in physical memory
*
@@ -69,7 +69,7 @@ static int __init init_physmap(void)
mymtd->owner = THIS_MODULE;
#ifdef CONFIG_MTD_PARTITIONS
- mtd_parts_nb = parse_mtd_partitions(mymtd, part_probes,
+ mtd_parts_nb = parse_mtd_partitions(mymtd, part_probes,
&mtd_parts, 0);
if (mtd_parts_nb > 0)
@@ -78,9 +78,9 @@ static int __init init_physmap(void)
return 0;
}
- if (num_physmap_partitions != 0)
+ if (num_physmap_partitions != 0)
{
- printk(KERN_NOTICE
+ printk(KERN_NOTICE
"Using physmap partition definition\n");
add_mtd_partitions (mymtd, physmap_partitions, num_physmap_partitions);
return 0;
diff --git a/drivers/mtd/maps/plat-ram.c b/drivers/mtd/maps/plat-ram.c
index 118b04544cad..a02eed94a231 100644
--- a/drivers/mtd/maps/plat-ram.c
+++ b/drivers/mtd/maps/plat-ram.c
@@ -6,7 +6,7 @@
*
* Generic platfrom device based RAM map
*
- * $Id: plat-ram.c,v 1.3 2005/03/19 22:41:27 gleixner Exp $
+ * $Id: plat-ram.c,v 1.7 2005/11/07 11:14:28 gleixner Exp $
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -30,6 +30,8 @@
#include <linux/string.h>
#include <linux/ioport.h>
#include <linux/device.h>
+#include <linux/slab.h>
+#include <linux/platform_device.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/map.h>
@@ -89,7 +91,7 @@ static int platram_remove(struct device *dev)
dev_dbg(dev, "removing device\n");
- if (info == NULL)
+ if (info == NULL)
return 0;
if (info->mtd) {
@@ -116,7 +118,7 @@ static int platram_remove(struct device *dev)
if (info->map.virt != NULL)
iounmap(info->map.virt);
-
+
kfree(info);
return 0;
@@ -137,7 +139,7 @@ static int platram_probe(struct device *dev)
int err = 0;
dev_dbg(dev, "probe entered\n");
-
+
if (dev->platform_data == NULL) {
dev_err(dev, "no platform data supplied\n");
err = -ENOENT;
@@ -175,7 +177,7 @@ static int platram_probe(struct device *dev)
info->map.phys = res->start;
info->map.size = (res->end - res->start) + 1;
- info->map.name = pdata->mapname != NULL ? pdata->mapname : pd->name;
+ info->map.name = pdata->mapname != NULL ? pdata->mapname : (char *)pd->name;
info->map.bankwidth = pdata->bankwidth;
/* register our usage of the memory area */
@@ -238,7 +240,7 @@ static int platram_probe(struct device *dev)
dev_err(dev, "add_mtd_device() failed\n");
err = -ENOMEM;
}
-
+
dev_info(dev, "registered mtd device\n");
return err;
@@ -252,6 +254,7 @@ static int platram_probe(struct device *dev)
static struct device_driver platram_driver = {
.name = "mtd-ram",
+ .owner = THIS_MODULE,
.bus = &platform_bus_type,
.probe = platram_probe,
.remove = platram_remove,
diff --git a/drivers/mtd/maps/pnc2000.c b/drivers/mtd/maps/pnc2000.c
index a0f43dad8985..d7e16c2d5c44 100644
--- a/drivers/mtd/maps/pnc2000.c
+++ b/drivers/mtd/maps/pnc2000.c
@@ -5,7 +5,7 @@
*
* This code is GPL
*
- * $Id: pnc2000.c,v 1.17 2004/11/16 18:29:02 dwmw2 Exp $
+ * $Id: pnc2000.c,v 1.18 2005/11/07 11:14:28 gleixner Exp $
*/
#include <linux/module.h>
@@ -21,7 +21,7 @@
#define WINDOW_ADDR 0xbf000000
#define WINDOW_SIZE 0x00400000
-/*
+/*
* MAP DRIVER STUFF
*/
@@ -36,7 +36,7 @@ static struct map_info pnc_map = {
/*
- * MTD 'PARTITIONING' STUFF
+ * MTD 'PARTITIONING' STUFF
*/
static struct mtd_partition pnc_partitions[3] = {
{
@@ -56,7 +56,7 @@ static struct mtd_partition pnc_partitions[3] = {
}
};
-/*
+/*
* This is the master MTD device for which all the others are just
* auto-relocating aliases.
*/
diff --git a/drivers/mtd/maps/pq2fads.c b/drivers/mtd/maps/pq2fads.c
new file mode 100644
index 000000000000..fb78d87cc130
--- /dev/null
+++ b/drivers/mtd/maps/pq2fads.c
@@ -0,0 +1,88 @@
+/*
+ * drivers/mtd/maps/pq2fads.c
+ *
+ * Mapping for the flash SIMM on 8272ADS and PQ2FADS board
+ *
+ * Author: Vitaly Bordug <vbordug@ru.mvista.com>
+ *
+ * 2005 (c) MontaVista Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <asm/io.h>
+#include <asm/ppcboot.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+
+/*
+ NOTE: bank width and interleave relative to the installed flash
+ should have been chosen within MTD_CFI_GEOMETRY options.
+ */
+#define PQ2FADS_BANK_WIDTH 4
+
+static struct mtd_partition pq2fads_partitions[] = {
+ {
+#ifdef CONFIG_ADS8272
+ .name = "HRCW",
+ .size = 0x40000,
+ .offset = 0,
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ }, {
+ .name = "User FS",
+ .size = 0x5c0000,
+ .offset = 0x40000,
+#else
+ .name = "User FS",
+ .size = 0x600000,
+ .offset = 0,
+#endif
+ }, {
+ .name = "uImage",
+ .size = 0x100000,
+ .offset = 0x600000,
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ }, {
+ .name = "bootloader",
+ .size = 0x40000,
+ .offset = 0x700000,
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ }, {
+ .name = "bootloader env",
+ .size = 0x40000,
+ .offset = 0x740000,
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ }
+};
+
+
+/* pointer to MPC885ADS board info data */
+extern unsigned char __res[];
+
+static int __init init_pq2fads_mtd(void)
+{
+ bd_t *bd = (bd_t *)__res;
+ physmap_configure(bd->bi_flashstart, bd->bi_flashsize, PQ2FADS_BANK_WIDTH, NULL);
+
+ physmap_set_partitions(pq2fads_partitions,
+ sizeof (pq2fads_partitions) /
+ sizeof (pq2fads_partitions[0]));
+ return 0;
+}
+
+static void __exit cleanup_pq2fads_mtd(void)
+{
+}
+
+module_init(init_pq2fads_mtd);
+module_exit(cleanup_pq2fads_mtd);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("MTD map and partitions for MPC8272ADS boards");
diff --git a/drivers/mtd/maps/redwood.c b/drivers/mtd/maps/redwood.c
index edd01ee4f90b..5b76ed886185 100644
--- a/drivers/mtd/maps/redwood.c
+++ b/drivers/mtd/maps/redwood.c
@@ -1,5 +1,5 @@
/*
- * $Id: redwood.c,v 1.10 2004/11/04 13:24:15 gleixner Exp $
+ * $Id: redwood.c,v 1.11 2005/11/07 11:14:28 gleixner Exp $
*
* drivers/mtd/maps/redwood.c
*
@@ -79,7 +79,7 @@ static struct mtd_partition redwood_flash_partitions[] = {
#define RW_PART0_OF 0
#define RW_PART0_SZ 0x400000 /* 4 MiB data */
-#define RW_PART1_OF RW_PART0_OF + RW_PART0_SZ
+#define RW_PART1_OF RW_PART0_OF + RW_PART0_SZ
#define RW_PART1_SZ 0x10000 /* 64K VPD */
#define RW_PART2_OF RW_PART1_OF + RW_PART1_SZ
#define RW_PART2_SZ 0x400000 - (0x10000 + 0x20000)
diff --git a/drivers/mtd/maps/sa1100-flash.c b/drivers/mtd/maps/sa1100-flash.c
index 8dcaa357b4bb..9e8bb1782be0 100644
--- a/drivers/mtd/maps/sa1100-flash.c
+++ b/drivers/mtd/maps/sa1100-flash.c
@@ -1,9 +1,9 @@
/*
* Flash memory access on SA11x0 based devices
- *
+ *
* (C) 2000 Nicolas Pitre <nico@cam.org>
- *
- * $Id: sa1100-flash.c,v 1.47 2004/11/01 13:44:36 rmk Exp $
+ *
+ * $Id: sa1100-flash.c,v 1.51 2005/11/07 11:14:28 gleixner Exp $
*/
#include <linux/config.h>
#include <linux/module.h>
@@ -13,7 +13,7 @@
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/slab.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <linux/err.h>
#include <linux/mtd/mtd.h>
@@ -21,6 +21,7 @@
#include <linux/mtd/partitions.h>
#include <linux/mtd/concat.h>
+#include <asm/hardware.h>
#include <asm/io.h>
#include <asm/sizes.h>
#include <asm/mach/flash.h>
@@ -129,20 +130,21 @@ struct sa_subdev_info {
char name[16];
struct map_info map;
struct mtd_info *mtd;
- struct flash_platform_data *data;
+ struct flash_platform_data *plat;
};
struct sa_info {
struct mtd_partition *parts;
struct mtd_info *mtd;
int num_subdev;
+ unsigned int nr_parts;
struct sa_subdev_info subdev[0];
};
static void sa1100_set_vpp(struct map_info *map, int on)
{
struct sa_subdev_info *subdev = container_of(map, struct sa_subdev_info, map);
- subdev->data->set_vpp(on);
+ subdev->plat->set_vpp(on);
}
static void sa1100_destroy_subdev(struct sa_subdev_info *subdev)
@@ -186,7 +188,7 @@ static int sa1100_probe_subdev(struct sa_subdev_info *subdev, struct resource *r
goto out;
}
- if (subdev->data->set_vpp)
+ if (subdev->plat->set_vpp)
subdev->map.set_vpp = sa1100_set_vpp;
subdev->map.phys = phys;
@@ -203,7 +205,7 @@ static int sa1100_probe_subdev(struct sa_subdev_info *subdev, struct resource *r
* Now let's probe for the actual flash. Do it here since
* specific machine settings might have been set above.
*/
- subdev->mtd = do_map_probe(subdev->data->map_name, &subdev->map);
+ subdev->mtd = do_map_probe(subdev->plat->map_name, &subdev->map);
if (subdev->mtd == NULL) {
ret = -ENXIO;
goto err;
@@ -222,29 +224,35 @@ static int sa1100_probe_subdev(struct sa_subdev_info *subdev, struct resource *r
return ret;
}
-static void sa1100_destroy(struct sa_info *info)
+static void sa1100_destroy(struct sa_info *info, struct flash_platform_data *plat)
{
int i;
if (info->mtd) {
- del_mtd_partitions(info->mtd);
-
+ if (info->nr_parts == 0)
+ del_mtd_device(info->mtd);
+#ifdef CONFIG_MTD_PARTITIONS
+ else
+ del_mtd_partitions(info->mtd);
+#endif
#ifdef CONFIG_MTD_CONCAT
if (info->mtd != info->subdev[0].mtd)
mtd_concat_destroy(info->mtd);
#endif
}
- if (info->parts)
- kfree(info->parts);
+ kfree(info->parts);
for (i = info->num_subdev - 1; i >= 0; i--)
sa1100_destroy_subdev(&info->subdev[i]);
kfree(info);
+
+ if (plat->exit)
+ plat->exit();
}
static struct sa_info *__init
-sa1100_setup_mtd(struct platform_device *pdev, struct flash_platform_data *flash)
+sa1100_setup_mtd(struct platform_device *pdev, struct flash_platform_data *plat)
{
struct sa_info *info;
int nr, size, i, ret = 0;
@@ -274,6 +282,12 @@ sa1100_setup_mtd(struct platform_device *pdev, struct flash_platform_data *flash
memset(info, 0, size);
+ if (plat->init) {
+ ret = plat->init();
+ if (ret)
+ goto err;
+ }
+
/*
* Claim and then map the memory regions.
*/
@@ -286,8 +300,8 @@ sa1100_setup_mtd(struct platform_device *pdev, struct flash_platform_data *flash
break;
subdev->map.name = subdev->name;
- sprintf(subdev->name, "sa1100-%d", i);
- subdev->data = flash;
+ sprintf(subdev->name, "%s-%d", plat->name, i);
+ subdev->plat = plat;
ret = sa1100_probe_subdev(subdev, res);
if (ret)
@@ -308,7 +322,7 @@ sa1100_setup_mtd(struct platform_device *pdev, struct flash_platform_data *flash
* otherwise fail. Either way, it'll be called "sa1100".
*/
if (info->num_subdev == 1) {
- strcpy(info->subdev[0].name, "sa1100");
+ strcpy(info->subdev[0].name, plat->name);
info->mtd = info->subdev[0].mtd;
ret = 0;
} else if (info->num_subdev > 1) {
@@ -321,7 +335,7 @@ sa1100_setup_mtd(struct platform_device *pdev, struct flash_platform_data *flash
cdev[i] = info->subdev[i].mtd;
info->mtd = mtd_concat_create(cdev, info->num_subdev,
- "sa1100");
+ plat->name);
if (info->mtd == NULL)
ret = -ENXIO;
#else
@@ -335,7 +349,7 @@ sa1100_setup_mtd(struct platform_device *pdev, struct flash_platform_data *flash
return info;
err:
- sa1100_destroy(info);
+ sa1100_destroy(info, plat);
out:
return ERR_PTR(ret);
}
@@ -345,16 +359,16 @@ static const char *part_probes[] = { "cmdlinepart", "RedBoot", NULL };
static int __init sa1100_mtd_probe(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
- struct flash_platform_data *flash = pdev->dev.platform_data;
+ struct flash_platform_data *plat = pdev->dev.platform_data;
struct mtd_partition *parts;
const char *part_type = NULL;
struct sa_info *info;
int err, nr_parts = 0;
- if (!flash)
+ if (!plat)
return -ENODEV;
- info = sa1100_setup_mtd(pdev, flash);
+ info = sa1100_setup_mtd(pdev, plat);
if (IS_ERR(info)) {
err = PTR_ERR(info);
goto out;
@@ -371,8 +385,8 @@ static int __init sa1100_mtd_probe(struct device *dev)
} else
#endif
{
- parts = flash->parts;
- nr_parts = flash->nr_parts;
+ parts = plat->parts;
+ nr_parts = plat->nr_parts;
part_type = "static";
}
@@ -386,6 +400,8 @@ static int __init sa1100_mtd_probe(struct device *dev)
add_mtd_partitions(info->mtd, parts, nr_parts);
}
+ info->nr_parts = nr_parts;
+
dev_set_drvdata(dev, info);
err = 0;
@@ -396,33 +412,44 @@ static int __init sa1100_mtd_probe(struct device *dev)
static int __exit sa1100_mtd_remove(struct device *dev)
{
struct sa_info *info = dev_get_drvdata(dev);
+ struct flash_platform_data *plat = dev->platform_data;
+
dev_set_drvdata(dev, NULL);
- sa1100_destroy(info);
+ sa1100_destroy(info, plat);
+
return 0;
}
#ifdef CONFIG_PM
-static int sa1100_mtd_suspend(struct device *dev, pm_message_t state, u32 level)
+static int sa1100_mtd_suspend(struct device *dev, pm_message_t state)
{
struct sa_info *info = dev_get_drvdata(dev);
int ret = 0;
- if (info && level == SUSPEND_SAVE_STATE)
+ if (info)
ret = info->mtd->suspend(info->mtd);
return ret;
}
-static int sa1100_mtd_resume(struct device *dev, u32 level)
+static int sa1100_mtd_resume(struct device *dev)
{
struct sa_info *info = dev_get_drvdata(dev);
- if (info && level == RESUME_RESTORE_STATE)
+ if (info)
info->mtd->resume(info->mtd);
return 0;
}
+
+static void sa1100_mtd_shutdown(struct device *dev)
+{
+ struct sa_info *info = dev_get_drvdata(dev);
+ if (info && info->mtd->suspend(info->mtd) == 0)
+ info->mtd->resume(info->mtd);
+}
#else
#define sa1100_mtd_suspend NULL
#define sa1100_mtd_resume NULL
+#define sa1100_mtd_shutdown NULL
#endif
static struct device_driver sa1100_mtd_driver = {
@@ -432,6 +459,7 @@ static struct device_driver sa1100_mtd_driver = {
.remove = __exit_p(sa1100_mtd_remove),
.suspend = sa1100_mtd_suspend,
.resume = sa1100_mtd_resume,
+ .shutdown = sa1100_mtd_shutdown,
};
static int __init sa1100_mtd_init(void)
diff --git a/drivers/mtd/maps/sbc8240.c b/drivers/mtd/maps/sbc8240.c
index da684d3384e9..225cdd9ba5b2 100644
--- a/drivers/mtd/maps/sbc8240.c
+++ b/drivers/mtd/maps/sbc8240.c
@@ -5,7 +5,7 @@
*
* This code is GPLed
*
- * $Id: sbc8240.c,v 1.4 2004/07/12 22:38:29 dwmw2 Exp $
+ * $Id: sbc8240.c,v 1.5 2005/11/07 11:14:28 gleixner Exp $
*
*/
@@ -205,7 +205,7 @@ int __init init_sbc8240_mtd (void)
} else {
printk (KERN_NOTICE MSG_PREFIX
"Using %s partition definition\n", sbc8240_part_banks[i].mtd_part->name);
- add_mtd_partitions (sbc8240_mtd[i],
+ add_mtd_partitions (sbc8240_mtd[i],
sbc8240_part_banks[i].mtd_part,
sbc8240_part_banks[i].nums);
}
diff --git a/drivers/mtd/maps/sbc_gxx.c b/drivers/mtd/maps/sbc_gxx.c
index 65add28bde14..7cc4041d096d 100644
--- a/drivers/mtd/maps/sbc_gxx.c
+++ b/drivers/mtd/maps/sbc_gxx.c
@@ -1,35 +1,35 @@
/* sbc_gxx.c -- MTD map driver for Arcom Control Systems SBC-MediaGX,
SBC-GXm and SBC-GX1 series boards.
-
+
Copyright (C) 2001 Arcom Control System Ltd
-
+
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
- $Id: sbc_gxx.c,v 1.33 2004/11/28 09:40:40 dwmw2 Exp $
+ $Id: sbc_gxx.c,v 1.35 2005/11/07 11:14:28 gleixner Exp $
-The SBC-MediaGX / SBC-GXx has up to 16 MiB of
-Intel StrataFlash (28F320/28F640) in x8 mode.
+The SBC-MediaGX / SBC-GXx has up to 16 MiB of
+Intel StrataFlash (28F320/28F640) in x8 mode.
This driver uses the CFI probe and Intel Extended Command Set drivers.
The flash is accessed as follows:
16 KiB memory window at 0xdc000-0xdffff
-
+
Two IO address locations for paging
-
+
0x258
bit 0-7: address bit 14-21
0x259
@@ -37,7 +37,7 @@ The flash is accessed as follows:
bit 7: 0 - reset/powered down
1 - device enabled
-The single flash device is divided into 3 partition which appear as
+The single flash device is divided into 3 partition which appear as
separate MTD devices.
25/04/2001 AJL (Arcom) Modified signon strings and partition sizes
@@ -87,17 +87,17 @@ static volatile int page_in_window = -1; // Current page in window.
static void __iomem *iomapadr;
static DEFINE_SPINLOCK(sbc_gxx_spin);
-/* partition_info gives details on the logical partitions that the split the
+/* partition_info gives details on the logical partitions that the split the
* single flash device into. If the size if zero we use up to the end of the
* device. */
static struct mtd_partition partition_info[]={
- { .name = "SBC-GXx flash boot partition",
- .offset = 0,
+ { .name = "SBC-GXx flash boot partition",
+ .offset = 0,
.size = BOOT_PARTITION_SIZE_KiB*1024 },
- { .name = "SBC-GXx flash data partition",
- .offset = BOOT_PARTITION_SIZE_KiB*1024,
+ { .name = "SBC-GXx flash data partition",
+ .offset = BOOT_PARTITION_SIZE_KiB*1024,
.size = (DATA_PARTITION_SIZE_KiB)*1024 },
- { .name = "SBC-GXx flash application partition",
+ { .name = "SBC-GXx flash application partition",
.offset = (BOOT_PARTITION_SIZE_KiB+DATA_PARTITION_SIZE_KiB)*1024 }
};
@@ -130,7 +130,7 @@ static void sbc_gxx_copy_from(struct map_info *map, void *to, unsigned long from
unsigned long thislen = len;
if (len > (WINDOW_LENGTH - (from & WINDOW_MASK)))
thislen = WINDOW_LENGTH-(from & WINDOW_MASK);
-
+
spin_lock(&sbc_gxx_spin);
sbc_gxx_page(map, from);
memcpy_fromio(to, iomapadr + (from & WINDOW_MASK), thislen);
@@ -150,12 +150,12 @@ static void sbc_gxx_write8(struct map_info *map, map_word d, unsigned long adr)
}
static void sbc_gxx_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
-{
+{
while(len) {
unsigned long thislen = len;
if (len > (WINDOW_LENGTH - (to & WINDOW_MASK)))
thislen = WINDOW_LENGTH-(to & WINDOW_MASK);
-
+
spin_lock(&sbc_gxx_spin);
sbc_gxx_page(map, to);
memcpy_toio(iomapadr + (to & WINDOW_MASK), from, thislen);
@@ -201,7 +201,7 @@ static int __init init_sbc_gxx(void)
sbc_gxx_map.name );
return -EIO;
}
-
+
if (!request_region( PAGE_IO, PAGE_IO_SIZE, "SBC-GXx flash")) {
printk( KERN_ERR"%s: IO ports 0x%x-0x%x in use\n",
sbc_gxx_map.name,
@@ -209,8 +209,8 @@ static int __init init_sbc_gxx(void)
iounmap(iomapadr);
return -EAGAIN;
}
-
-
+
+
printk( KERN_INFO"%s: IO:0x%x-0x%x MEM:0x%x-0x%x\n",
sbc_gxx_map.name,
PAGE_IO, PAGE_IO+PAGE_IO_SIZE-1,
@@ -222,7 +222,7 @@ static int __init init_sbc_gxx(void)
cleanup_sbc_gxx();
return -ENXIO;
}
-
+
all_mtd->owner = THIS_MODULE;
/* Create MTD devices for each partition. */
diff --git a/drivers/mtd/maps/sc520cdp.c b/drivers/mtd/maps/sc520cdp.c
index a06ed21e7ed1..6fb9f3c57aab 100644
--- a/drivers/mtd/maps/sc520cdp.c
+++ b/drivers/mtd/maps/sc520cdp.c
@@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: sc520cdp.c,v 1.21 2004/12/13 10:27:08 dedekind Exp $
+ * $Id: sc520cdp.c,v 1.22 2005/11/07 11:14:28 gleixner Exp $
*
*
* The SC520CDP is an evaluation board for the Elan SC520 processor available
@@ -231,7 +231,7 @@ static void sc520cdp_setup_par(void)
static int __init init_sc520cdp(void)
{
int i, devices_found = 0;
-
+
#ifdef REPROGRAM_PAR
/* reprogram PAR registers so flash appears at the desired addresses */
sc520cdp_setup_par();
@@ -278,7 +278,7 @@ static int __init init_sc520cdp(void)
static void __exit cleanup_sc520cdp(void)
{
int i;
-
+
if (merged_mtd) {
del_mtd_device(merged_mtd);
mtd_concat_destroy(merged_mtd);
diff --git a/drivers/mtd/maps/scx200_docflash.c b/drivers/mtd/maps/scx200_docflash.c
index 0ece3786d6ea..2c91dff8bb60 100644
--- a/drivers/mtd/maps/scx200_docflash.c
+++ b/drivers/mtd/maps/scx200_docflash.c
@@ -1,8 +1,8 @@
-/* linux/drivers/mtd/maps/scx200_docflash.c
+/* linux/drivers/mtd/maps/scx200_docflash.c
Copyright (c) 2001,2002 Christer Weinigel <wingel@nano-system.com>
- $Id: scx200_docflash.c,v 1.10 2004/11/28 09:40:40 dwmw2 Exp $
+ $Id: scx200_docflash.c,v 1.12 2005/11/07 11:14:28 gleixner Exp $
National Semiconductor SCx200 flash mapped with DOCCS
*/
@@ -49,23 +49,23 @@ static struct mtd_info *mymtd;
#ifdef CONFIG_MTD_PARTITIONS
static struct mtd_partition partition_info[] = {
- {
- .name = "DOCCS Boot kernel",
- .offset = 0,
+ {
+ .name = "DOCCS Boot kernel",
+ .offset = 0,
.size = 0xc0000
},
- {
- .name = "DOCCS Low BIOS",
- .offset = 0xc0000,
+ {
+ .name = "DOCCS Low BIOS",
+ .offset = 0xc0000,
.size = 0x40000
},
- {
- .name = "DOCCS File system",
- .offset = 0x100000,
+ {
+ .name = "DOCCS File system",
+ .offset = 0x100000,
.size = ~0 /* calculate from flash size */
},
- {
- .name = "DOCCS High BIOS",
+ {
+ .name = "DOCCS High BIOS",
.offset = ~0, /* calculate from flash size */
.size = 0x80000
},
@@ -88,7 +88,7 @@ static int __init init_scx200_docflash(void)
printk(KERN_DEBUG NAME ": NatSemi SCx200 DOCCS Flash Driver\n");
- if ((bridge = pci_find_device(PCI_VENDOR_ID_NS,
+ if ((bridge = pci_find_device(PCI_VENDOR_ID_NS,
PCI_DEVICE_ID_NS_SCx200_BRIDGE,
NULL)) == NULL)
return -ENODEV;
@@ -134,28 +134,28 @@ static int __init init_scx200_docflash(void)
printk(KERN_ERR NAME ": invalid size for flash mapping\n");
return -EINVAL;
}
-
+
if (width != 8 && width != 16) {
printk(KERN_ERR NAME ": invalid bus width for flash mapping\n");
return -EINVAL;
}
-
- if (allocate_resource(&iomem_resource, &docmem,
+
+ if (allocate_resource(&iomem_resource, &docmem,
size,
- 0xc0000000, 0xffffffff,
+ 0xc0000000, 0xffffffff,
size, NULL, NULL)) {
printk(KERN_ERR NAME ": unable to allocate memory for flash mapping\n");
return -ENOMEM;
}
-
+
ctrl = 0x07000000 | ((size-1) >> 13);
printk(KERN_INFO "DOCCS BASE=0x%08lx, CTRL=0x%08lx\n", (long)docmem.start, (long)ctrl);
-
+
pci_write_config_dword(bridge, SCx200_DOCCS_BASE, docmem.start);
pci_write_config_dword(bridge, SCx200_DOCCS_CTRL, ctrl);
pmr = inl(scx200_cb_base + SCx200_PMR);
-
+
if (width == 8) {
pmr &= ~(1<<6);
} else {
@@ -163,8 +163,8 @@ static int __init init_scx200_docflash(void)
}
outl(pmr, scx200_cb_base + SCx200_PMR);
}
-
- printk(KERN_INFO NAME ": DOCCS mapped at 0x%lx-0x%lx, width %d\n",
+
+ printk(KERN_INFO NAME ": DOCCS mapped at 0x%lx-0x%lx, width %d\n",
docmem.start, docmem.end, width);
scx200_docflash_map.size = size;
diff --git a/drivers/mtd/maps/sharpsl-flash.c b/drivers/mtd/maps/sharpsl-flash.c
index b7f093fbf9b0..999f4bb3d845 100644
--- a/drivers/mtd/maps/sharpsl-flash.c
+++ b/drivers/mtd/maps/sharpsl-flash.c
@@ -1,10 +1,10 @@
/*
* sharpsl-flash.c
- *
+ *
* Copyright (C) 2001 Lineo Japan, Inc.
* Copyright (C) 2002 SHARP
*
- * $Id: sharpsl-flash.c,v 1.5 2005/03/21 08:42:11 rpurdie Exp $
+ * $Id: sharpsl-flash.c,v 1.7 2005/11/07 11:14:28 gleixner Exp $
*
* based on rpxlite.c,v 1.15 2001/10/02 15:05:14 dwmw2 Exp
* Handle mapping of the flash on the RPX Lite and CLLF boards
@@ -57,7 +57,7 @@ int __init init_sharpsl(void)
int nb_parts = 0;
char *part_type = "static";
- printk(KERN_NOTICE "Sharp SL series flash device: %x at %x\n",
+ printk(KERN_NOTICE "Sharp SL series flash device: %x at %x\n",
WINDOW_SIZE, WINDOW_ADDR);
sharpsl_map.virt = ioremap(WINDOW_ADDR, WINDOW_SIZE);
if (!sharpsl_map.virt) {
@@ -75,7 +75,7 @@ int __init init_sharpsl(void)
mymtd->owner = THIS_MODULE;
- if (machine_is_corgi() || machine_is_shepherd() || machine_is_husky()
+ if (machine_is_corgi() || machine_is_shepherd() || machine_is_husky()
|| machine_is_poodle()) {
sharpsl_partitions[0].size=0x006d0000;
sharpsl_partitions[0].offset=0x00120000;
@@ -87,10 +87,10 @@ int __init init_sharpsl(void)
sharpsl_partitions[0].offset=0x00140000;
} else {
map_destroy(mymtd);
- iounmap(sharpsl_map.virt);
+ iounmap(sharpsl_map.virt);
return -ENODEV;
}
-
+
parts = sharpsl_partitions;
nb_parts = NB_OF(sharpsl_partitions);
diff --git a/drivers/mtd/maps/solutionengine.c b/drivers/mtd/maps/solutionengine.c
index 8ce5d897645c..c53c2c369c9d 100644
--- a/drivers/mtd/maps/solutionengine.c
+++ b/drivers/mtd/maps/solutionengine.c
@@ -1,5 +1,5 @@
/*
- * $Id: solutionengine.c,v 1.14 2004/09/16 23:27:14 gleixner Exp $
+ * $Id: solutionengine.c,v 1.15 2005/11/07 11:14:28 gleixner Exp $
*
* Flash and EPROM on Hitachi Solution Engine and similar boards.
*
@@ -67,7 +67,7 @@ static int __init init_soleng_maps(void)
soleng_eprom_map.virt = (void __iomem *)P1SEGADDR(0x01000000);
simple_map_init(&soleng_eprom_map);
simple_map_init(&soleng_flash_map);
-
+
printk(KERN_NOTICE "Probing for flash chips at 0x00000000:\n");
flash_mtd = do_map_probe("cfi_probe", &soleng_flash_map);
if (!flash_mtd) {
diff --git a/drivers/mtd/maps/sun_uflash.c b/drivers/mtd/maps/sun_uflash.c
index 29091d10030a..0758cb1d0105 100644
--- a/drivers/mtd/maps/sun_uflash.c
+++ b/drivers/mtd/maps/sun_uflash.c
@@ -1,4 +1,4 @@
-/* $Id: sun_uflash.c,v 1.11 2004/11/04 13:24:15 gleixner Exp $
+/* $Id: sun_uflash.c,v 1.13 2005/11/07 11:14:28 gleixner Exp $
*
* sun_uflash - Driver implementation for user-programmable flash
* present on many Sun Microsystems SME boardsets.
@@ -63,7 +63,7 @@ int uflash_devinit(struct linux_ebus_device* edev)
iTmp = prom_getproperty(
edev->prom_node, "reg", (void *)regs, sizeof(regs));
if ((iTmp % sizeof(regs[0])) != 0) {
- printk("%s: Strange reg property size %d\n",
+ printk("%s: Strange reg property size %d\n",
UFLASH_DEVNAME, iTmp);
return -ENODEV;
}
@@ -75,7 +75,7 @@ int uflash_devinit(struct linux_ebus_device* edev)
* can work on supporting it.
*/
printk("%s: unsupported device at 0x%lx (%d regs): " \
- "email ebrower@usa.net\n",
+ "email ebrower@usa.net\n",
UFLASH_DEVNAME, edev->resource[0].start, nregs);
return -ENODEV;
}
@@ -84,7 +84,7 @@ int uflash_devinit(struct linux_ebus_device* edev)
printk("%s: unable to kmalloc new device\n", UFLASH_DEVNAME);
return(-ENOMEM);
}
-
+
/* copy defaults and tweak parameters */
memcpy(&pdev->map, &uflash_map_templ, sizeof(uflash_map_templ));
pdev->map.size = regs[0].reg_size;
@@ -155,7 +155,7 @@ static void __exit uflash_cleanup(void)
list_for_each(udevlist, &device_list) {
udev = list_entry(udevlist, struct uflash_dev, list);
- DEBUG(2, "%s: removing device %s\n",
+ DEBUG(2, "%s: removing device %s\n",
UFLASH_DEVNAME, udev->name);
if(0 != udev->mtd) {
@@ -166,11 +166,9 @@ static void __exit uflash_cleanup(void)
iounmap(udev->map.virt);
udev->map.virt = NULL;
}
- if(0 != udev->name) {
- kfree(udev->name);
- }
+ kfree(udev->name);
kfree(udev);
- }
+ }
}
module_init(uflash_init);
diff --git a/drivers/mtd/maps/tqm834x.c b/drivers/mtd/maps/tqm834x.c
new file mode 100644
index 000000000000..c7ae9a515c1a
--- /dev/null
+++ b/drivers/mtd/maps/tqm834x.c
@@ -0,0 +1,291 @@
+/*
+ * drivers/mtd/maps/tqm834x.c
+ *
+ * MTD mapping driver for TQM834x boards
+ *
+ * Copyright 2005 Wolfgang Denk, DENX Software Engineering, <wd@denx.de>.
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <asm/io.h>
+#include <asm/ppcboot.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/partitions.h>
+
+#define FLASH_BANK_MAX 2
+
+extern unsigned char __res[];
+
+/* trivial struct to describe partition information */
+struct mtd_part_def
+{
+ int nums;
+ unsigned char *type;
+ struct mtd_partition* mtd_part;
+};
+
+static struct mtd_info* mtd_banks[FLASH_BANK_MAX];
+static struct map_info* map_banks[FLASH_BANK_MAX];
+static struct mtd_part_def part_banks[FLASH_BANK_MAX];
+
+static unsigned long num_banks;
+static unsigned long start_scan_addr;
+
+#ifdef CONFIG_MTD_PARTITIONS
+/*
+ * The following defines the partition layout of TQM834x boards.
+ *
+ * See include/linux/mtd/partitions.h for definition of the
+ * mtd_partition structure.
+ *
+ * Assume minimal initial size of 4 MiB per bank, will be updated
+ * later in init_tqm834x_mtd() routine.
+ */
+
+/* Partition definition for the first flash bank which is always present. */
+static struct mtd_partition tqm834x_partitions_bank1[] = {
+ {
+ .name = "u-boot", /* u-boot firmware */
+ .offset = 0x00000000,
+ .size = 0x00040000, /* 256 KiB */
+ /*mask_flags: MTD_WRITEABLE, * force read-only */
+ },
+ {
+ .name = "env", /* u-boot environment */
+ .offset = 0x00040000,
+ .size = 0x00020000, /* 128 KiB */
+ /*mask_flags: MTD_WRITEABLE, * force read-only */
+ },
+ {
+ .name = "kernel", /* linux kernel image */
+ .offset = 0x00060000,
+ .size = 0x00100000, /* 1 MiB */
+ /*mask_flags: MTD_WRITEABLE, * force read-only */
+ },
+ {
+ .name = "initrd", /* ramdisk image */
+ .offset = 0x00160000,
+ .size = 0x00200000, /* 2 MiB */
+ },
+ {
+ .name = "user", /* user data */
+ .offset = 0x00360000,
+ .size = 0x000a0000, /* remaining space */
+ /* NOTE: this parttion size is re-calcated in */
+ /* init_tqm834x_mtd() to cover actual remaining space. */
+ },
+};
+
+/* Partition definition for the second flash bank which may be present on some
+ * TQM834x boards.
+ */
+static struct mtd_partition tqm834x_partitions_bank2[] = {
+ {
+ .name = "jffs2", /* jffs2 filesystem */
+ .offset = 0x00000000,
+ .size = 0x00400000, /* whole device */
+ /* NOTE: this parttion size is re-calcated in */
+ /* init_tqm834x_mtd() to cover actual device size. */
+ },
+};
+
+#endif /* CONFIG_MTD_PARTITIONS */
+
+static int __init init_tqm834x_mtd(void)
+{
+ int idx = 0, ret = 0;
+ unsigned long flash_addr, flash_size, mtd_size = 0;
+
+ /* pointer to TQM834x board info data */
+ bd_t *bd = (bd_t *)__res;
+#ifdef CONFIG_MTD_CMDLINE_PARTS
+ int n;
+ char mtdid[4];
+ const char *part_probes[] = { "cmdlinepart", NULL };
+#endif
+
+ flash_addr = bd->bi_flashstart;
+ flash_size = bd->bi_flashsize;
+
+ /* request maximum flash size address space */
+ start_scan_addr = (unsigned long)ioremap(flash_addr, flash_size);
+ if (!start_scan_addr) {
+ printk("%s: Failed to ioremap address: 0x%lx\n",
+ __FUNCTION__, flash_addr);
+ return -EIO;
+ }
+
+ for(idx = 0 ; idx < FLASH_BANK_MAX ; idx++) {
+ if (mtd_size >= flash_size)
+ break;
+
+ pr_debug("%s: chip probing count %d\n", __FUNCTION__, idx);
+
+ map_banks[idx] =
+ (struct map_info *)kmalloc(sizeof(struct map_info),
+ GFP_KERNEL);
+ if (map_banks[idx] == NULL) {
+ ret = -ENOMEM;
+ goto error_mem;
+ }
+ memset((void *)map_banks[idx], 0, sizeof(struct map_info));
+ map_banks[idx]->name = (char *)kmalloc(16, GFP_KERNEL);
+ if (map_banks[idx]->name == NULL) {
+ ret = -ENOMEM;
+ goto error_mem;
+ }
+ memset((void *)map_banks[idx]->name, 0, 16);
+
+ sprintf(map_banks[idx]->name, "TQM834x-%d", idx);
+ map_banks[idx]->size = flash_size;
+ map_banks[idx]->bankwidth = 4;
+
+ simple_map_init(map_banks[idx]);
+
+ map_banks[idx]->virt = (void __iomem *)
+ (start_scan_addr + ((idx > 0) ?
+ (mtd_banks[idx-1] ? mtd_banks[idx-1]->size : 0) : 0));
+ map_banks[idx]->phys =
+ flash_addr + ((idx > 0) ?
+ (mtd_banks[idx-1] ? mtd_banks[idx-1]->size : 0) : 0);
+
+ /* start to probe flash chips */
+ mtd_banks[idx] = do_map_probe("cfi_probe", map_banks[idx]);
+ if (mtd_banks[idx]) {
+ mtd_banks[idx]->owner = THIS_MODULE;
+ mtd_size += mtd_banks[idx]->size;
+ num_banks++;
+ pr_debug("%s: bank %ld, name: %s, size: %d bytes \n",
+ __FUNCTION__, num_banks,
+ mtd_banks[idx]->name, mtd_banks[idx]->size);
+ }
+ }
+
+ /* no supported flash chips found */
+ if (!num_banks) {
+ printk("TQM834x: No supported flash chips found!\n");
+ ret = -ENXIO;
+ goto error_mem;
+ }
+
+#ifdef CONFIG_MTD_PARTITIONS
+ /*
+ * Select static partition definitions
+ */
+ n = ARRAY_SIZE(tqm834x_partitions_bank1);
+ part_banks[0].mtd_part = tqm834x_partitions_bank1;
+ part_banks[0].type = "static image bank1";
+ part_banks[0].nums = n;
+
+ /* update last partition size to cover actual remaining space */
+ tqm834x_partitions_bank1[n - 1].size =
+ mtd_banks[0]->size -
+ tqm834x_partitions_bank1[n - 1].offset;
+
+ /* check if we have second bank? */
+ if (num_banks == 2) {
+ n = ARRAY_SIZE(tqm834x_partitions_bank2);
+ part_banks[1].mtd_part = tqm834x_partitions_bank2;
+ part_banks[1].type = "static image bank2";
+ part_banks[1].nums = n;
+
+ /* update last partition size to cover actual remaining space */
+ tqm834x_partitions_bank2[n - 1].size =
+ mtd_banks[1]->size -
+ tqm834x_partitions_bank2[n - 1].offset;
+ }
+
+ for(idx = 0; idx < num_banks ; idx++) {
+#ifdef CONFIG_MTD_CMDLINE_PARTS
+ sprintf(mtdid, "%d", idx);
+ n = parse_mtd_partitions(mtd_banks[idx],
+ part_probes,
+ &part_banks[idx].mtd_part,
+ 0);
+ pr_debug("%s: %d command line partitions on bank %s\n",
+ __FUNCTION__, n, mtdid);
+ if (n > 0) {
+ part_banks[idx].type = "command line";
+ part_banks[idx].nums = n;
+ }
+#endif /* CONFIG_MTD_CMDLINE_PARTS */
+ if (part_banks[idx].nums == 0) {
+ printk(KERN_NOTICE
+ "TQM834x flash bank %d: no partition info "
+ "available, registering whole device\n", idx);
+ add_mtd_device(mtd_banks[idx]);
+ } else {
+ printk(KERN_NOTICE
+ "TQM834x flash bank %d: Using %s partition "
+ "definition\n", idx, part_banks[idx].type);
+ add_mtd_partitions(mtd_banks[idx],
+ part_banks[idx].mtd_part,
+ part_banks[idx].nums);
+ }
+ }
+#else /* ! CONFIG_MTD_PARTITIONS */
+ printk(KERN_NOTICE "TQM834x flash: registering %d flash banks "
+ "at once\n", num_banks);
+
+ for(idx = 0 ; idx < num_banks ; idx++)
+ add_mtd_device(mtd_banks[idx]);
+
+#endif /* CONFIG_MTD_PARTITIONS */
+
+ return 0;
+error_mem:
+ for (idx = 0 ; idx < FLASH_BANK_MAX ; idx++) {
+ if (map_banks[idx] != NULL) {
+ if (map_banks[idx]->name != NULL) {
+ kfree(map_banks[idx]->name);
+ map_banks[idx]->name = NULL;
+ }
+ kfree(map_banks[idx]);
+ map_banks[idx] = NULL;
+ }
+ }
+
+ iounmap((void *)start_scan_addr);
+
+ return ret;
+}
+
+static void __exit cleanup_tqm834x_mtd(void)
+{
+ unsigned int idx = 0;
+ for(idx = 0 ; idx < num_banks ; idx++) {
+ /* destroy mtd_info previously allocated */
+ if (mtd_banks[idx]) {
+ del_mtd_partitions(mtd_banks[idx]);
+ map_destroy(mtd_banks[idx]);
+ }
+
+ /* release map_info not used anymore */
+ kfree(map_banks[idx]->name);
+ kfree(map_banks[idx]);
+ }
+
+ if (start_scan_addr) {
+ iounmap((void *)start_scan_addr);
+ start_scan_addr = 0;
+ }
+}
+
+module_init(init_tqm834x_mtd);
+module_exit(cleanup_tqm834x_mtd);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Wolfgang Denk <wd@denx.de>");
+MODULE_DESCRIPTION("MTD map driver for TQM834x boards");
diff --git a/drivers/mtd/maps/tqm8xxl.c b/drivers/mtd/maps/tqm8xxl.c
index 995e9991cb8d..a43517053e7c 100644
--- a/drivers/mtd/maps/tqm8xxl.c
+++ b/drivers/mtd/maps/tqm8xxl.c
@@ -1,15 +1,15 @@
/*
- * Handle mapping of the flash memory access routines
+ * Handle mapping of the flash memory access routines
* on TQM8xxL based devices.
*
- * $Id: tqm8xxl.c,v 1.13 2004/10/20 22:21:53 dwmw2 Exp $
+ * $Id: tqm8xxl.c,v 1.15 2005/11/07 11:14:28 gleixner Exp $
*
* based on rpxlite.c
*
* Copyright(C) 2001 Kirk Lee <kirk@hpc.ee.ntu.edu.tw>
*
* This code is GPLed
- *
+ *
*/
/*
@@ -19,7 +19,7 @@
* 2MiB 512Kx16 2MiB 0
* 4MiB 1Mx16 4MiB 0
* 8MiB 1Mx16 4MiB 4MiB
- * Thus, we choose CONFIG_MTD_CFI_I2 & CONFIG_MTD_CFI_B4 at
+ * Thus, we choose CONFIG_MTD_CFI_I2 & CONFIG_MTD_CFI_B4 at
* kernel configuration.
*/
#include <linux/config.h>
@@ -27,12 +27,14 @@
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/init.h>
-#include <asm/io.h>
+#include <linux/slab.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/map.h>
#include <linux/mtd/partitions.h>
+#include <asm/io.h>
+
#define FLASH_ADDR 0x40000000
#define FLASH_SIZE 0x00800000
#define FLASH_BANK_MAX 4
@@ -56,9 +58,9 @@ static void __iomem *start_scan_addr;
* Here are partition information for all known TQM8xxL series devices.
* See include/linux/mtd/partitions.h for definition of the mtd_partition
* structure.
- *
+ *
* The *_max_flash_size is the maximum possible mapped flash size which
- * is not necessarily the actual flash size. It must correspond to the
+ * is not necessarily the actual flash size. It must correspond to the
* value specified in the mapping definition defined by the
* "struct map_desc *_io_desc" for the corresponding machine.
*/
@@ -130,9 +132,9 @@ int __init init_tqm_mtd(void)
for (idx = 0 ; idx < FLASH_BANK_MAX ; idx++) {
if(mtd_size >= flash_size)
break;
-
+
printk(KERN_INFO "%s: chip probing count %d\n", __FUNCTION__, idx);
-
+
map_banks[idx] = (struct map_info *)kmalloc(sizeof(struct map_info), GFP_KERNEL);
if(map_banks[idx] == NULL) {
ret = -ENOMEM;
@@ -178,7 +180,7 @@ int __init init_tqm_mtd(void)
mtd_size += mtd_banks[idx]->size;
num_banks++;
- printk(KERN_INFO "%s: bank%d, name:%s, size:%dbytes \n", __FUNCTION__, num_banks,
+ printk(KERN_INFO "%s: bank%d, name:%s, size:%dbytes \n", __FUNCTION__, num_banks,
mtd_banks[idx]->name, mtd_banks[idx]->size);
}
}
@@ -209,7 +211,7 @@ int __init init_tqm_mtd(void)
} else {
printk(KERN_NOTICE "TQM flash%d: Using %s partition definition\n",
idx, part_banks[idx].type);
- add_mtd_partitions(mtd_banks[idx], part_banks[idx].mtd_part,
+ add_mtd_partitions(mtd_banks[idx], part_banks[idx].mtd_part,
part_banks[idx].nums);
}
}
@@ -222,10 +224,8 @@ int __init init_tqm_mtd(void)
error_mem:
for(idx = 0 ; idx < FLASH_BANK_MAX ; idx++) {
if(map_banks[idx] != NULL) {
- if(map_banks[idx]->name != NULL) {
- kfree(map_banks[idx]->name);
- map_banks[idx]->name = NULL;
- }
+ kfree(map_banks[idx]->name);
+ map_banks[idx]->name = NULL;
kfree(map_banks[idx]);
map_banks[idx] = NULL;
}
diff --git a/drivers/mtd/maps/ts5500_flash.c b/drivers/mtd/maps/ts5500_flash.c
index 3ebd90f56503..4b372bcb17f1 100644
--- a/drivers/mtd/maps/ts5500_flash.c
+++ b/drivers/mtd/maps/ts5500_flash.c
@@ -19,26 +19,22 @@
*
* Note:
* - In order for detection to work, jumper 3 must be set.
- * - Drive A and B use a proprietary FTL from General Software which isn't
- * supported as of yet so standard drives can't be mounted; you can create
- * your own (e.g. jffs) file system.
- * - If you have created your own jffs file system and the bios overwrites
+ * - Drive A and B use the resident flash disk (RFD) flash translation layer.
+ * - If you have created your own jffs file system and the bios overwrites
* it during boot, try disabling Drive A: and B: in the boot order.
*
- * $Id: ts5500_flash.c,v 1.2 2004/11/28 09:40:40 dwmw2 Exp $
+ * $Id: ts5500_flash.c,v 1.5 2005/11/07 11:14:28 gleixner Exp $
*/
#include <linux/config.h>
+#include <linux/init.h>
#include <linux/module.h>
-#include <linux/types.h>
#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/mtd/mtd.h>
#include <linux/mtd/map.h>
-
-#ifdef CONFIG_MTD_PARTITIONS
+#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
-#endif
+#include <linux/types.h>
+
#define WINDOW_ADDR 0x09400000
#define WINDOW_SIZE 0x00200000
@@ -50,7 +46,6 @@ static struct map_info ts5500_map = {
.phys = WINDOW_ADDR
};
-#ifdef CONFIG_MTD_PARTITIONS
static struct mtd_partition ts5500_partitions[] = {
{
.name = "Drive A",
@@ -71,8 +66,6 @@ static struct mtd_partition ts5500_partitions[] = {
#define NUM_PARTITIONS (sizeof(ts5500_partitions)/sizeof(struct mtd_partition))
-#endif
-
static struct mtd_info *mymtd;
static int __init init_ts5500_map(void)
@@ -81,48 +74,39 @@ static int __init init_ts5500_map(void)
ts5500_map.virt = ioremap_nocache(ts5500_map.phys, ts5500_map.size);
- if(!ts5500_map.virt) {
+ if (!ts5500_map.virt) {
printk(KERN_ERR "Failed to ioremap_nocache\n");
rc = -EIO;
- goto err_out_ioremap;
+ goto err2;
}
simple_map_init(&ts5500_map);
mymtd = do_map_probe("jedec_probe", &ts5500_map);
- if(!mymtd)
+ if (!mymtd)
mymtd = do_map_probe("map_rom", &ts5500_map);
- if(!mymtd) {
+ if (!mymtd) {
rc = -ENXIO;
- goto err_out_map;
+ goto err1;
}
mymtd->owner = THIS_MODULE;
-#ifdef CONFIG_MTD_PARTITIONS
add_mtd_partitions(mymtd, ts5500_partitions, NUM_PARTITIONS);
-#else
- add_mtd_device(mymtd);
-#endif
return 0;
-err_out_map:
+err1:
map_destroy(mymtd);
-err_out_ioremap:
iounmap(ts5500_map.virt);
-
+err2:
return rc;
}
static void __exit cleanup_ts5500_map(void)
{
if (mymtd) {
-#ifdef CONFIG_MTD_PARTITIONS
del_mtd_partitions(mymtd);
-#else
- del_mtd_device(mymtd);
-#endif
map_destroy(mymtd);
}
diff --git a/drivers/mtd/maps/tsunami_flash.c b/drivers/mtd/maps/tsunami_flash.c
index 170d71239e5e..9e21e6c02f80 100644
--- a/drivers/mtd/maps/tsunami_flash.c
+++ b/drivers/mtd/maps/tsunami_flash.c
@@ -2,7 +2,7 @@
* tsunami_flash.c
*
* flash chip on alpha ds10...
- * $Id: tsunami_flash.c,v 1.9 2004/07/14 09:52:55 dwmw2 Exp $
+ * $Id: tsunami_flash.c,v 1.10 2005/11/07 11:14:29 gleixner Exp $
*/
#include <asm/io.h>
#include <asm/core_tsunami.h>
@@ -41,7 +41,7 @@ static void tsunami_flash_copy_from(
}
static void tsunami_flash_copy_to(
- struct map_info *map, unsigned long offset,
+ struct map_info *map, unsigned long offset,
const void *addr, ssize_t len)
{
const unsigned char *src;
@@ -90,7 +90,7 @@ static int __init init_tsunami_flash(void)
char **type;
tsunami_tig_writeb(FLASH_ENABLE_BYTE, FLASH_ENABLE_PORT);
-
+
tsunami_flash_mtd = 0;
type = rom_probe_types;
for(; !tsunami_flash_mtd && *type; type++) {
diff --git a/drivers/mtd/maps/uclinux.c b/drivers/mtd/maps/uclinux.c
index cc372136e852..79d92808b766 100644
--- a/drivers/mtd/maps/uclinux.c
+++ b/drivers/mtd/maps/uclinux.c
@@ -5,7 +5,7 @@
*
* (C) Copyright 2002, Greg Ungerer (gerg@snapgear.com)
*
- * $Id: uclinux.c,v 1.10 2005/01/05 18:05:13 dwmw2 Exp $
+ * $Id: uclinux.c,v 1.12 2005/11/07 11:14:29 gleixner Exp $
*/
/****************************************************************************/
@@ -82,7 +82,7 @@ int __init uclinux_mtd_init(void)
iounmap(mapp->virt);
return(-ENXIO);
}
-
+
mtd->owner = THIS_MODULE;
mtd->point = uclinux_point;
mtd->priv = mapp;
diff --git a/drivers/mtd/maps/vmax301.c b/drivers/mtd/maps/vmax301.c
index c8c74110ed1b..e0063941c0df 100644
--- a/drivers/mtd/maps/vmax301.c
+++ b/drivers/mtd/maps/vmax301.c
@@ -1,19 +1,19 @@
-// $Id: vmax301.c,v 1.30 2004/07/12 22:38:29 dwmw2 Exp $
+// $Id: vmax301.c,v 1.32 2005/11/07 11:14:29 gleixner Exp $
/* ######################################################################
Tempustech VMAX SBC301 MTD Driver.
-
+
The VMAx 301 is a SBC based on . It
comes with three builtin AMD 29F016B flash chips and a socket for SRAM or
- more flash. Each unit has it's own 8k mapping into a settable region
+ more flash. Each unit has it's own 8k mapping into a settable region
(0xD8000). There are two 8k mappings for each MTD, the first is always set
to the lower 8k of the device the second is paged. Writing a 16 bit page
value to anywhere in the first 8k will cause the second 8k to page around.
- To boot the device a bios extension must be installed into the first 8k
- of flash that is smart enough to copy itself down, page in the rest of
+ To boot the device a bios extension must be installed into the first 8k
+ of flash that is smart enough to copy itself down, page in the rest of
itself and begin executing.
-
+
##################################################################### */
#include <linux/module.h>
@@ -35,7 +35,7 @@
/* Actually we could use two spinlocks, but we'd have to have
more private space in the struct map_info. We lose a little
performance like this, but we'd probably lose more by having
- the extra indirection from having one of the map->map_priv
+ the extra indirection from having one of the map->map_priv
fields pointing to yet another private struct.
*/
static DEFINE_SPINLOCK(vmax301_spin);
@@ -98,7 +98,7 @@ static void vmax301_copy_to(struct map_info *map, unsigned long to, const void *
spin_lock(&vmax301_spin);
vmax301_page(map, to);
memcpy_toio(map->map_priv_2 + to, from, thislen);
- spin_unlock(&vmax301_spin);
+ spin_unlock(&vmax301_spin);
to += thislen;
from += thislen;
len -= thislen;
@@ -137,7 +137,7 @@ static struct mtd_info *vmax_mtd[2] = {NULL, NULL};
static void __exit cleanup_vmax301(void)
{
int i;
-
+
for (i=0; i<2; i++) {
if (vmax_mtd[i]) {
del_mtd_device(vmax_mtd[i]);
@@ -161,13 +161,13 @@ int __init init_vmax301(void)
return -EIO;
}
/* Put the address in the map's private data area.
- We store the actual MTD IO address rather than the
+ We store the actual MTD IO address rather than the
address of the first half, because it's used more
- often.
+ often.
*/
vmax_map[0].map_priv_2 = iomapadr + WINDOW_START;
vmax_map[1].map_priv_2 = iomapadr + (3*WINDOW_START);
-
+
for (i=0; i<2; i++) {
vmax_mtd[i] = do_map_probe("cfi_probe", &vmax_map[i]);
if (!vmax_mtd[i])
diff --git a/drivers/mtd/maps/walnut.c b/drivers/mtd/maps/walnut.c
index d6137b1b5670..f46bec66150f 100644
--- a/drivers/mtd/maps/walnut.c
+++ b/drivers/mtd/maps/walnut.c
@@ -1,12 +1,12 @@
/*
- * $Id: walnut.c,v 1.2 2004/12/10 12:07:42 holindho Exp $
- *
+ * $Id: walnut.c,v 1.3 2005/11/07 11:14:29 gleixner Exp $
+ *
* Mapping for Walnut flash
* (used ebony.c as a "framework")
- *
+ *
* Heikki Lindholm <holindho@infradead.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
@@ -21,7 +21,6 @@
#include <linux/mtd/map.h>
#include <linux/mtd/partitions.h>
#include <linux/config.h>
-#include <linux/version.h>
#include <asm/io.h>
#include <asm/ibm4xx.h>
#include <platforms/4xx/walnut.h>
@@ -48,7 +47,7 @@ static struct mtd_partition walnut_partitions[] = {
.name = "OpenBIOS",
.offset = 0x0,
.size = WALNUT_FLASH_SIZE,
- /*.mask_flags = MTD_WRITEABLE, */ /* force read-only */
+ /*.mask_flags = MTD_WRITEABLE, */ /* force read-only */
}
};
@@ -72,11 +71,11 @@ int __init init_walnut(void)
printk("The on-board flash is disabled (U79 sw 5)!");
return -EIO;
}
- if (WALNUT_FLASH_SRAM_SEL(fpga_brds1))
+ if (WALNUT_FLASH_SRAM_SEL(fpga_brds1))
flash_base = WALNUT_FLASH_LOW;
else
flash_base = WALNUT_FLASH_HIGH;
-
+
walnut_map.phys = flash_base;
walnut_map.virt =
(void __iomem *)ioremap(flash_base, walnut_map.size);
diff --git a/drivers/mtd/maps/wr_sbc82xx_flash.c b/drivers/mtd/maps/wr_sbc82xx_flash.c
index 82b887b05707..60c197ec455b 100644
--- a/drivers/mtd/maps/wr_sbc82xx_flash.c
+++ b/drivers/mtd/maps/wr_sbc82xx_flash.c
@@ -1,5 +1,5 @@
/*
- * $Id: wr_sbc82xx_flash.c,v 1.7 2004/11/04 13:24:15 gleixner Exp $
+ * $Id: wr_sbc82xx_flash.c,v 1.8 2005/11/07 11:14:29 gleixner Exp $
*
* Map for flash chips on Wind River PowerQUICC II SBC82xx board.
*
@@ -163,10 +163,10 @@ static void __exit cleanup_sbc82xx_flash(void)
del_mtd_partitions(sbcmtd[i]);
else
del_mtd_device(sbcmtd[i]);
-
+
kfree(sbcmtd_parts[i]);
map_destroy(sbcmtd[i]);
-
+
iounmap((void *)sbc82xx_flash_map[i].virt);
sbc82xx_flash_map[i].virt = 0;
}
diff --git a/drivers/mtd/mtd_blkdevs.c b/drivers/mtd/mtd_blkdevs.c
index f8d2185819e7..339cb1218eaa 100644
--- a/drivers/mtd/mtd_blkdevs.c
+++ b/drivers/mtd/mtd_blkdevs.c
@@ -1,5 +1,5 @@
/*
- * $Id: mtd_blkdevs.c,v 1.24 2004/11/16 18:28:59 dwmw2 Exp $
+ * $Id: mtd_blkdevs.c,v 1.27 2005/11/07 11:14:20 gleixner Exp $
*
* (C) 2003 David Woodhouse <dwmw2@infradead.org>
*
@@ -21,7 +21,6 @@
#include <linux/init.h>
#include <asm/semaphore.h>
#include <asm/uaccess.h>
-#include <linux/devfs_fs_kernel.h>
static LIST_HEAD(blktrans_majors);
@@ -86,7 +85,7 @@ static int mtd_blktrans_thread(void *arg)
daemonize("%sd", tr->name);
/* daemonize() doesn't do this for us since some kernel threads
- actually want to deal with signals. We can't just call
+ actually want to deal with signals. We can't just call
exit_sighand() since that'll cause an oops when we finally
do exit. */
spin_lock_irq(&current->sighand->siglock);
@@ -95,7 +94,7 @@ static int mtd_blktrans_thread(void *arg)
spin_unlock_irq(&current->sighand->siglock);
spin_lock_irq(rq->queue_lock);
-
+
while (!tr->blkcore_priv->exiting) {
struct request *req;
struct mtd_blktrans_dev *dev;
@@ -158,7 +157,7 @@ static int blktrans_open(struct inode *i, struct file *f)
if (!try_module_get(tr->owner))
goto out_tr;
- /* FIXME: Locking. A hot pluggable device can go away
+ /* FIXME: Locking. A hot pluggable device can go away
(del_mtd_device can be called for it) without its module
being unloaded. */
dev->mtd->usecount++;
@@ -196,7 +195,7 @@ static int blktrans_release(struct inode *i, struct file *f)
}
-static int blktrans_ioctl(struct inode *inode, struct file *file,
+static int blktrans_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
{
struct mtd_blktrans_dev *dev = inode->i_bdev->bd_disk->private_data;
@@ -265,7 +264,7 @@ int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new)
/* Required number was free */
list_add_tail(&new->list, &d->list);
goto added;
- }
+ }
last_devnum = d->devnum;
}
if (new->devnum == -1)
@@ -289,11 +288,19 @@ int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new)
gd->major = tr->major;
gd->first_minor = (new->devnum) << tr->part_bits;
gd->fops = &mtd_blktrans_ops;
-
- snprintf(gd->disk_name, sizeof(gd->disk_name),
- "%s%c", tr->name, (tr->part_bits?'a':'0') + new->devnum);
- snprintf(gd->devfs_name, sizeof(gd->devfs_name),
- "%s/%c", tr->name, (tr->part_bits?'a':'0') + new->devnum);
+
+ if (tr->part_bits)
+ if (new->devnum < 26)
+ snprintf(gd->disk_name, sizeof(gd->disk_name),
+ "%s%c", tr->name, 'a' + new->devnum);
+ else
+ snprintf(gd->disk_name, sizeof(gd->disk_name),
+ "%s%c%c", tr->name,
+ 'a' - 1 + new->devnum / 26,
+ 'a' + new->devnum % 26);
+ else
+ snprintf(gd->disk_name, sizeof(gd->disk_name),
+ "%s%d", tr->name, new->devnum);
/* 2.5 has capacity in units of 512 bytes while still
having BLOCK_SIZE_BITS set to 10. Just to keep us amused. */
@@ -307,7 +314,7 @@ int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new)
set_disk_ro(gd, 1);
add_disk(gd);
-
+
return 0;
}
@@ -322,7 +329,7 @@ int del_mtd_blktrans_dev(struct mtd_blktrans_dev *old)
del_gendisk(old->blkcore_priv);
put_disk(old->blkcore_priv);
-
+
return 0;
}
@@ -361,12 +368,12 @@ static struct mtd_notifier blktrans_notifier = {
.add = blktrans_notify_add,
.remove = blktrans_notify_remove,
};
-
+
int register_mtd_blktrans(struct mtd_blktrans_ops *tr)
{
int ret, i;
- /* Register the notifier if/when the first device type is
+ /* Register the notifier if/when the first device type is
registered, to prevent the link/init ordering from fucking
us over. */
if (!blktrans_notifier.list.next)
@@ -409,9 +416,7 @@ int register_mtd_blktrans(struct mtd_blktrans_ops *tr)
kfree(tr->blkcore_priv);
up(&mtd_table_mutex);
return ret;
- }
-
- devfs_mk_dir(tr->name);
+ }
INIT_LIST_HEAD(&tr->devs);
list_add(&tr->list, &blktrans_majors);
@@ -445,7 +450,6 @@ int deregister_mtd_blktrans(struct mtd_blktrans_ops *tr)
tr->remove_dev(dev);
}
- devfs_remove(tr->name);
blk_cleanup_queue(tr->blkcore_priv->rq);
unregister_blkdev(tr->major, tr->name);
diff --git a/drivers/mtd/mtdblock.c b/drivers/mtd/mtdblock.c
index b7c32c242bc7..e84756644fd1 100644
--- a/drivers/mtd/mtdblock.c
+++ b/drivers/mtd/mtdblock.c
@@ -1,20 +1,22 @@
-/*
+/*
* Direct MTD block device access
*
- * $Id: mtdblock.c,v 1.66 2004/11/25 13:52:52 joern Exp $
+ * $Id: mtdblock.c,v 1.68 2005/11/07 11:14:20 gleixner Exp $
*
* (C) 2000-2003 Nicolas Pitre <nico@cam.org>
* (C) 1999-2003 David Woodhouse <dwmw2@infradead.org>
*/
#include <linux/config.h>
-#include <linux/types.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/sched.h>
#include <linux/slab.h>
+#include <linux/types.h>
#include <linux/vmalloc.h>
+
#include <linux/mtd/mtd.h>
#include <linux/mtd/blktrans.h>
@@ -30,7 +32,7 @@ static struct mtdblk_dev {
/*
* Cache stuff...
- *
+ *
* Since typical flash erasable sectors are much larger than what Linux's
* buffer cache can handle, we must implement read-modify-write on flash
* sectors for each block write requests. To avoid over-erasing flash sectors
@@ -44,7 +46,7 @@ static void erase_callback(struct erase_info *done)
wake_up(wait_q);
}
-static int erase_write (struct mtd_info *mtd, unsigned long pos,
+static int erase_write (struct mtd_info *mtd, unsigned long pos,
int len, const char *buf)
{
struct erase_info erase;
@@ -102,18 +104,18 @@ static int write_cached_data (struct mtdblk_dev *mtdblk)
return 0;
DEBUG(MTD_DEBUG_LEVEL2, "mtdblock: writing cached data for \"%s\" "
- "at 0x%lx, size 0x%x\n", mtd->name,
+ "at 0x%lx, size 0x%x\n", mtd->name,
mtdblk->cache_offset, mtdblk->cache_size);
-
- ret = erase_write (mtd, mtdblk->cache_offset,
+
+ ret = erase_write (mtd, mtdblk->cache_offset,
mtdblk->cache_size, mtdblk->cache_data);
if (ret)
return ret;
/*
* Here we could argubly set the cache state to STATE_CLEAN.
- * However this could lead to inconsistency since we will not
- * be notified if this content is altered on the flash by other
+ * However this could lead to inconsistency since we will not
+ * be notified if this content is altered on the flash by other
* means. Let's declare it empty and leave buffering tasks to
* the buffer cache instead.
*/
@@ -122,7 +124,7 @@ static int write_cached_data (struct mtdblk_dev *mtdblk)
}
-static int do_cached_write (struct mtdblk_dev *mtdblk, unsigned long pos,
+static int do_cached_write (struct mtdblk_dev *mtdblk, unsigned long pos,
int len, const char *buf)
{
struct mtd_info *mtd = mtdblk->mtd;
@@ -132,7 +134,7 @@ static int do_cached_write (struct mtdblk_dev *mtdblk, unsigned long pos,
DEBUG(MTD_DEBUG_LEVEL2, "mtdblock: write on \"%s\" at 0x%lx, size 0x%x\n",
mtd->name, pos, len);
-
+
if (!sect_size)
return MTD_WRITE (mtd, pos, len, &retlen, buf);
@@ -140,11 +142,11 @@ static int do_cached_write (struct mtdblk_dev *mtdblk, unsigned long pos,
unsigned long sect_start = (pos/sect_size)*sect_size;
unsigned int offset = pos - sect_start;
unsigned int size = sect_size - offset;
- if( size > len )
+ if( size > len )
size = len;
if (size == sect_size) {
- /*
+ /*
* We are covering a whole sector. Thus there is no
* need to bother with the cache while it may still be
* useful for other partial writes.
@@ -158,7 +160,7 @@ static int do_cached_write (struct mtdblk_dev *mtdblk, unsigned long pos,
if (mtdblk->cache_state == STATE_DIRTY &&
mtdblk->cache_offset != sect_start) {
ret = write_cached_data(mtdblk);
- if (ret)
+ if (ret)
return ret;
}
@@ -191,7 +193,7 @@ static int do_cached_write (struct mtdblk_dev *mtdblk, unsigned long pos,
}
-static int do_cached_read (struct mtdblk_dev *mtdblk, unsigned long pos,
+static int do_cached_read (struct mtdblk_dev *mtdblk, unsigned long pos,
int len, char *buf)
{
struct mtd_info *mtd = mtdblk->mtd;
@@ -199,9 +201,9 @@ static int do_cached_read (struct mtdblk_dev *mtdblk, unsigned long pos,
size_t retlen;
int ret;
- DEBUG(MTD_DEBUG_LEVEL2, "mtdblock: read on \"%s\" at 0x%lx, size 0x%x\n",
+ DEBUG(MTD_DEBUG_LEVEL2, "mtdblock: read on \"%s\" at 0x%lx, size 0x%x\n",
mtd->name, pos, len);
-
+
if (!sect_size)
return MTD_READ (mtd, pos, len, &retlen, buf);
@@ -209,7 +211,7 @@ static int do_cached_read (struct mtdblk_dev *mtdblk, unsigned long pos,
unsigned long sect_start = (pos/sect_size)*sect_size;
unsigned int offset = pos - sect_start;
unsigned int size = sect_size - offset;
- if (size > len)
+ if (size > len)
size = len;
/*
@@ -267,12 +269,12 @@ static int mtdblock_open(struct mtd_blktrans_dev *mbd)
int dev = mbd->devnum;
DEBUG(MTD_DEBUG_LEVEL1,"mtdblock_open\n");
-
+
if (mtdblks[dev]) {
mtdblks[dev]->count++;
return 0;
}
-
+
/* OK, it's not open. Create cache info for it */
mtdblk = kmalloc(sizeof(struct mtdblk_dev), GFP_KERNEL);
if (!mtdblk)
@@ -291,7 +293,7 @@ static int mtdblock_open(struct mtd_blktrans_dev *mbd)
}
mtdblks[dev] = mtdblk;
-
+
DEBUG(MTD_DEBUG_LEVEL1, "ok\n");
return 0;
@@ -319,7 +321,7 @@ static int mtdblock_release(struct mtd_blktrans_dev *mbd)
DEBUG(MTD_DEBUG_LEVEL1, "ok\n");
return 0;
-}
+}
static int mtdblock_flush(struct mtd_blktrans_dev *dev)
{
diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c
index 1ed602a0f24c..6f044584bdc6 100644
--- a/drivers/mtd/mtdchar.c
+++ b/drivers/mtd/mtdchar.c
@@ -1,21 +1,23 @@
/*
- * $Id: mtdchar.c,v 1.73 2005/07/04 17:36:41 gleixner Exp $
+ * $Id: mtdchar.c,v 1.76 2005/11/07 11:14:20 gleixner Exp $
*
* Character-device access to raw MTD devices.
*
*/
#include <linux/config.h>
+#include <linux/device.h>
+#include <linux/fs.h>
+#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/sched.h>
+
#include <linux/mtd/mtd.h>
#include <linux/mtd/compatmac.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-#include <linux/fs.h>
-#include <asm/uaccess.h>
-#include <linux/device.h>
+#include <asm/uaccess.h>
static struct class *mtd_class;
@@ -24,10 +26,10 @@ static void mtd_notify_add(struct mtd_info* mtd)
if (!mtd)
return;
- class_device_create(mtd_class, MKDEV(MTD_CHAR_MAJOR, mtd->index*2),
+ class_device_create(mtd_class, NULL, MKDEV(MTD_CHAR_MAJOR, mtd->index*2),
NULL, "mtd%d", mtd->index);
-
- class_device_create(mtd_class,
+
+ class_device_create(mtd_class, NULL,
MKDEV(MTD_CHAR_MAJOR, mtd->index*2+1),
NULL, "mtd%dro", mtd->index);
}
@@ -69,26 +71,23 @@ static loff_t mtd_lseek (struct file *file, loff_t offset, int orig)
switch (orig) {
case 0:
/* SEEK_SET */
- file->f_pos = offset;
break;
case 1:
/* SEEK_CUR */
- file->f_pos += offset;
+ offset += file->f_pos;
break;
case 2:
/* SEEK_END */
- file->f_pos =mtd->size + offset;
+ offset += mtd->size;
break;
default:
return -EINVAL;
}
- if (file->f_pos < 0)
- file->f_pos = 0;
- else if (file->f_pos >= mtd->size)
- file->f_pos = mtd->size - 1;
+ if (offset >= 0 && offset < mtd->size)
+ return file->f_pos = offset;
- return file->f_pos;
+ return -EINVAL;
}
@@ -109,23 +108,23 @@ static int mtd_open(struct inode *inode, struct file *file)
return -EACCES;
mtd = get_mtd_device(NULL, devnum);
-
+
if (!mtd)
return -ENODEV;
-
+
if (MTD_ABSENT == mtd->type) {
put_mtd_device(mtd);
return -ENODEV;
}
file->private_data = mtd;
-
+
/* You can't open it RW if it's not a writeable device */
if ((file->f_mode & 2) && !(mtd->flags & MTD_WRITEABLE)) {
put_mtd_device(mtd);
return -EACCES;
}
-
+
return 0;
} /* mtd_open */
@@ -138,10 +137,10 @@ static int mtd_close(struct inode *inode, struct file *file)
DEBUG(MTD_DEBUG_LEVEL0, "MTD_close\n");
mtd = TO_MTD(file);
-
+
if (mtd->sync)
mtd->sync(mtd);
-
+
put_mtd_device(mtd);
return 0;
@@ -160,7 +159,7 @@ static ssize_t mtd_read(struct file *file, char __user *buf, size_t count,loff_t
int ret=0;
int len;
char *kbuf;
-
+
DEBUG(MTD_DEBUG_LEVEL0,"MTD_read\n");
if (*ppos + count > mtd->size)
@@ -168,11 +167,11 @@ static ssize_t mtd_read(struct file *file, char __user *buf, size_t count,loff_t
if (!count)
return 0;
-
+
/* FIXME: Use kiovec in 2.5 to lock down the user's buffers
and pass them directly to the MTD functions */
while (count) {
- if (count > MAX_KMALLOC_SIZE)
+ if (count > MAX_KMALLOC_SIZE)
len = MAX_KMALLOC_SIZE;
else
len = count;
@@ -180,7 +179,7 @@ static ssize_t mtd_read(struct file *file, char __user *buf, size_t count,loff_t
kbuf=kmalloc(len,GFP_KERNEL);
if (!kbuf)
return -ENOMEM;
-
+
switch (MTD_MODE(file)) {
case MTD_MODE_OTP_FACT:
ret = mtd->read_fact_prot_reg(mtd, *ppos, len, &retlen, kbuf);
@@ -193,7 +192,7 @@ static ssize_t mtd_read(struct file *file, char __user *buf, size_t count,loff_t
}
/* Nand returns -EBADMSG on ecc errors, but it returns
* the data. For our userspace tools it is important
- * to dump areas with ecc errors !
+ * to dump areas with ecc errors !
* Userspace software which accesses NAND this way
* must be aware of the fact that it deals with NAND
*/
@@ -215,7 +214,7 @@ static ssize_t mtd_read(struct file *file, char __user *buf, size_t count,loff_t
kfree(kbuf);
return ret;
}
-
+
kfree(kbuf);
}
@@ -232,10 +231,10 @@ static ssize_t mtd_write(struct file *file, const char __user *buf, size_t count
int len;
DEBUG(MTD_DEBUG_LEVEL0,"MTD_write\n");
-
+
if (*ppos == mtd->size)
return -ENOSPC;
-
+
if (*ppos + count > mtd->size)
count = mtd->size - *ppos;
@@ -243,7 +242,7 @@ static ssize_t mtd_write(struct file *file, const char __user *buf, size_t count
return 0;
while (count) {
- if (count > MAX_KMALLOC_SIZE)
+ if (count > MAX_KMALLOC_SIZE)
len = MAX_KMALLOC_SIZE;
else
len = count;
@@ -258,7 +257,7 @@ static ssize_t mtd_write(struct file *file, const char __user *buf, size_t count
kfree(kbuf);
return -EFAULT;
}
-
+
switch (MTD_MODE(file)) {
case MTD_MODE_OTP_FACT:
ret = -EROFS;
@@ -283,7 +282,7 @@ static ssize_t mtd_write(struct file *file, const char __user *buf, size_t count
kfree(kbuf);
return ret;
}
-
+
kfree(kbuf);
}
@@ -307,7 +306,7 @@ static int mtd_ioctl(struct inode *inode, struct file *file,
void __user *argp = (void __user *)arg;
int ret = 0;
u_long size;
-
+
DEBUG(MTD_DEBUG_LEVEL0, "MTD_ioctl\n");
size = (cmd & IOCSIZE_MASK) >> IOCSIZE_SHIFT;
@@ -319,7 +318,7 @@ static int mtd_ioctl(struct inode *inode, struct file *file,
if (!access_ok(VERIFY_WRITE, argp, size))
return -EFAULT;
}
-
+
switch (cmd) {
case MEMGETREGIONCOUNT:
if (copy_to_user(argp, &(mtd->numeraseregions), sizeof(int)))
@@ -371,11 +370,11 @@ static int mtd_ioctl(struct inode *inode, struct file *file,
erase->mtd = mtd;
erase->callback = mtdchar_erase_callback;
erase->priv = (unsigned long)&waitq;
-
+
/*
FIXME: Allow INTERRUPTIBLE. Which means
not having the wait_queue head on the stack.
-
+
If the wq_head is on the stack, and we
leave because we got interrupted, then the
wq_head is no longer there when the
@@ -403,13 +402,13 @@ static int mtd_ioctl(struct inode *inode, struct file *file,
struct mtd_oob_buf buf;
void *databuf;
ssize_t retlen;
-
+
if(!(file->f_mode & 2))
return -EPERM;
if (copy_from_user(&buf, argp, sizeof(struct mtd_oob_buf)))
return -EFAULT;
-
+
if (buf.length > 0x4096)
return -EINVAL;
@@ -425,7 +424,7 @@ static int mtd_ioctl(struct inode *inode, struct file *file,
databuf = kmalloc(buf.length, GFP_KERNEL);
if (!databuf)
return -ENOMEM;
-
+
if (copy_from_user(databuf, buf.ptr, buf.length)) {
kfree(databuf);
return -EFAULT;
@@ -449,7 +448,7 @@ static int mtd_ioctl(struct inode *inode, struct file *file,
if (copy_from_user(&buf, argp, sizeof(struct mtd_oob_buf)))
return -EFAULT;
-
+
if (buf.length > 0x4096)
return -EINVAL;
@@ -465,14 +464,14 @@ static int mtd_ioctl(struct inode *inode, struct file *file,
databuf = kmalloc(buf.length, GFP_KERNEL);
if (!databuf)
return -ENOMEM;
-
+
ret = (mtd->read_oob)(mtd, buf.start, buf.length, &retlen, databuf);
if (put_user(retlen, (uint32_t __user *)argp))
ret = -EFAULT;
else if (retlen && copy_to_user(buf.ptr, databuf, retlen))
ret = -EFAULT;
-
+
kfree(databuf);
break;
}
@@ -522,7 +521,7 @@ static int mtd_ioctl(struct inode *inode, struct file *file,
case MEMGETBADBLOCK:
{
loff_t offs;
-
+
if (copy_from_user(&offs, argp, sizeof(loff_t)))
return -EFAULT;
if (!mtd->block_isbad)
diff --git a/drivers/mtd/mtdconcat.c b/drivers/mtd/mtdconcat.c
index 8f66d093c80d..b1bf8c411de7 100644
--- a/drivers/mtd/mtdconcat.c
+++ b/drivers/mtd/mtdconcat.c
@@ -7,13 +7,14 @@
*
* This code is GPL
*
- * $Id: mtdconcat.c,v 1.9 2004/06/30 15:17:41 dbrown Exp $
+ * $Id: mtdconcat.c,v 1.11 2005/11/07 11:14:20 gleixner Exp $
*/
-#include <linux/module.h>
-#include <linux/types.h>
#include <linux/kernel.h>
+#include <linux/module.h>
#include <linux/slab.h>
+#include <linux/sched.h>
+#include <linux/types.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/concat.h>
@@ -43,7 +44,7 @@ struct mtd_concat {
*/
#define CONCAT(x) ((struct mtd_concat *)(x))
-/*
+/*
* MTD methods which look up the relevant subdevice, translate the
* effective address and pass through to the subdevice.
*/
@@ -877,7 +878,7 @@ struct mtd_info *mtd_concat_create(struct mtd_info *subdev[], /* subdevices to c
return &concat->mtd;
}
-/*
+/*
* This function destroys an MTD object obtained from concat_mtd_devs()
*/
diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
index dc86df18e94b..dade02ab0687 100644
--- a/drivers/mtd/mtdcore.c
+++ b/drivers/mtd/mtdcore.c
@@ -1,5 +1,5 @@
/*
- * $Id: mtdcore.c,v 1.45 2005/02/18 14:34:50 dedekind Exp $
+ * $Id: mtdcore.c,v 1.47 2005/11/07 11:14:20 gleixner Exp $
*
* Core registration and callback routines for MTD
* drivers and users.
@@ -25,7 +25,7 @@
#include <linux/mtd/mtd.h>
-/* These are exported solely for the purpose of mtd_blkdevs.c. You
+/* These are exported solely for the purpose of mtd_blkdevs.c. You
should not use them for _anything_ else */
DECLARE_MUTEX(mtd_table_mutex);
struct mtd_info *mtd_table[MAX_MTD_DEVICES];
@@ -66,7 +66,7 @@ int add_mtd_device(struct mtd_info *mtd)
struct mtd_notifier *not = list_entry(this, struct mtd_notifier, list);
not->add(mtd);
}
-
+
up(&mtd_table_mutex);
/* We _know_ we aren't being removed, because
our caller is still holding us here. So none
@@ -75,7 +75,7 @@ int add_mtd_device(struct mtd_info *mtd)
__module_get(THIS_MODULE);
return 0;
}
-
+
up(&mtd_table_mutex);
return 1;
}
@@ -93,13 +93,13 @@ int add_mtd_device(struct mtd_info *mtd)
int del_mtd_device (struct mtd_info *mtd)
{
int ret;
-
+
down(&mtd_table_mutex);
if (mtd_table[mtd->index] != mtd) {
ret = -ENODEV;
} else if (mtd->usecount) {
- printk(KERN_NOTICE "Removing MTD device #%d (%s) with use count %d\n",
+ printk(KERN_NOTICE "Removing MTD device #%d (%s) with use count %d\n",
mtd->index, mtd->name, mtd->usecount);
ret = -EBUSY;
} else {
@@ -140,7 +140,7 @@ void register_mtd_user (struct mtd_notifier *new)
list_add(&new->list, &mtd_notifiers);
__module_get(THIS_MODULE);
-
+
for (i=0; i< MAX_MTD_DEVICES; i++)
if (mtd_table[i])
new->add(mtd_table[i]);
@@ -169,7 +169,7 @@ int unregister_mtd_user (struct mtd_notifier *old)
for (i=0; i< MAX_MTD_DEVICES; i++)
if (mtd_table[i])
old->remove(mtd_table[i]);
-
+
list_del(&old->list);
up(&mtd_table_mutex);
return 0;
@@ -187,7 +187,7 @@ int unregister_mtd_user (struct mtd_notifier *old)
* both, return the num'th driver only if its address matches. Return NULL
* if not.
*/
-
+
struct mtd_info *get_mtd_device(struct mtd_info *mtd, int num)
{
struct mtd_info *ret = NULL;
@@ -297,39 +297,6 @@ EXPORT_SYMBOL(default_mtd_writev);
EXPORT_SYMBOL(default_mtd_readv);
/*====================================================================*/
-/* Power management code */
-
-#ifdef CONFIG_PM
-
-#include <linux/pm.h>
-
-static struct pm_dev *mtd_pm_dev = NULL;
-
-static int mtd_pm_callback(struct pm_dev *dev, pm_request_t rqst, void *data)
-{
- int ret = 0, i;
-
- if (down_trylock(&mtd_table_mutex))
- return -EAGAIN;
- if (rqst == PM_SUSPEND) {
- for (i = 0; ret == 0 && i < MAX_MTD_DEVICES; i++) {
- if (mtd_table[i] && mtd_table[i]->suspend)
- ret = mtd_table[i]->suspend(mtd_table[i]);
- }
- } else i = MAX_MTD_DEVICES-1;
-
- if (rqst == PM_RESUME || ret) {
- for ( ; i >= 0; i--) {
- if (mtd_table[i] && mtd_table[i]->resume)
- mtd_table[i]->resume(mtd_table[i]);
- }
- }
- up(&mtd_table_mutex);
- return ret;
-}
-#endif
-
-/*====================================================================*/
/* Support for /proc/mtd */
#ifdef CONFIG_PROC_FS
@@ -388,22 +355,11 @@ static int __init init_mtd(void)
if ((proc_mtd = create_proc_entry( "mtd", 0, NULL )))
proc_mtd->read_proc = mtd_read_proc;
#endif
-
-#ifdef CONFIG_PM
- mtd_pm_dev = pm_register(PM_UNKNOWN_DEV, 0, mtd_pm_callback);
-#endif
return 0;
}
static void __exit cleanup_mtd(void)
{
-#ifdef CONFIG_PM
- if (mtd_pm_dev) {
- pm_unregister(mtd_pm_dev);
- mtd_pm_dev = NULL;
- }
-#endif
-
#ifdef CONFIG_PROC_FS
if (proc_mtd)
remove_proc_entry( "mtd", NULL);
diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c
index b92e6bfffaf2..99395911d26f 100644
--- a/drivers/mtd/mtdpart.c
+++ b/drivers/mtd/mtdpart.c
@@ -5,11 +5,11 @@
*
* This code is GPL
*
- * $Id: mtdpart.c,v 1.53 2005/02/08 17:11:13 nico Exp $
+ * $Id: mtdpart.c,v 1.55 2005/11/07 11:14:20 gleixner Exp $
*
* 02-21-2002 Thomas Gleixner <gleixner@autronix.de>
* added support for read_oob, write_oob
- */
+ */
#include <linux/module.h>
#include <linux/types.h>
@@ -41,13 +41,13 @@ struct mtd_part {
*/
#define PART(x) ((struct mtd_part *)(x))
-
-/*
+
+/*
* MTD methods which simply translate the effective address and pass through
* to the _real_ device.
*/
-static int part_read (struct mtd_info *mtd, loff_t from, size_t len,
+static int part_read (struct mtd_info *mtd, loff_t from, size_t len,
size_t *retlen, u_char *buf)
{
struct mtd_part *part = PART(mtd);
@@ -55,15 +55,15 @@ static int part_read (struct mtd_info *mtd, loff_t from, size_t len,
len = 0;
else if (from + len > mtd->size)
len = mtd->size - from;
- if (part->master->read_ecc == NULL)
- return part->master->read (part->master, from + part->offset,
+ if (part->master->read_ecc == NULL)
+ return part->master->read (part->master, from + part->offset,
len, retlen, buf);
else
- return part->master->read_ecc (part->master, from + part->offset,
+ return part->master->read_ecc (part->master, from + part->offset,
len, retlen, buf, NULL, &mtd->oobinfo);
}
-static int part_point (struct mtd_info *mtd, loff_t from, size_t len,
+static int part_point (struct mtd_info *mtd, loff_t from, size_t len,
size_t *retlen, u_char **buf)
{
struct mtd_part *part = PART(mtd);
@@ -71,7 +71,7 @@ static int part_point (struct mtd_info *mtd, loff_t from, size_t len,
len = 0;
else if (from + len > mtd->size)
len = mtd->size - from;
- return part->master->point (part->master, from + part->offset,
+ return part->master->point (part->master, from + part->offset,
len, retlen, buf);
}
static void part_unpoint (struct mtd_info *mtd, u_char *addr, loff_t from, size_t len)
@@ -82,7 +82,7 @@ static void part_unpoint (struct mtd_info *mtd, u_char *addr, loff_t from, size_
}
-static int part_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
+static int part_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
size_t *retlen, u_char *buf, u_char *eccbuf, struct nand_oobinfo *oobsel)
{
struct mtd_part *part = PART(mtd);
@@ -92,11 +92,11 @@ static int part_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
len = 0;
else if (from + len > mtd->size)
len = mtd->size - from;
- return part->master->read_ecc (part->master, from + part->offset,
+ return part->master->read_ecc (part->master, from + part->offset,
len, retlen, buf, eccbuf, oobsel);
}
-static int part_read_oob (struct mtd_info *mtd, loff_t from, size_t len,
+static int part_read_oob (struct mtd_info *mtd, loff_t from, size_t len,
size_t *retlen, u_char *buf)
{
struct mtd_part *part = PART(mtd);
@@ -104,15 +104,15 @@ static int part_read_oob (struct mtd_info *mtd, loff_t from, size_t len,
len = 0;
else if (from + len > mtd->size)
len = mtd->size - from;
- return part->master->read_oob (part->master, from + part->offset,
+ return part->master->read_oob (part->master, from + part->offset,
len, retlen, buf);
}
-static int part_read_user_prot_reg (struct mtd_info *mtd, loff_t from, size_t len,
+static int part_read_user_prot_reg (struct mtd_info *mtd, loff_t from, size_t len,
size_t *retlen, u_char *buf)
{
struct mtd_part *part = PART(mtd);
- return part->master->read_user_prot_reg (part->master, from,
+ return part->master->read_user_prot_reg (part->master, from,
len, retlen, buf);
}
@@ -123,11 +123,11 @@ static int part_get_user_prot_info (struct mtd_info *mtd,
return part->master->get_user_prot_info (part->master, buf, len);
}
-static int part_read_fact_prot_reg (struct mtd_info *mtd, loff_t from, size_t len,
+static int part_read_fact_prot_reg (struct mtd_info *mtd, loff_t from, size_t len,
size_t *retlen, u_char *buf)
{
struct mtd_part *part = PART(mtd);
- return part->master->read_fact_prot_reg (part->master, from,
+ return part->master->read_fact_prot_reg (part->master, from,
len, retlen, buf);
}
@@ -148,13 +148,13 @@ static int part_write (struct mtd_info *mtd, loff_t to, size_t len,
len = 0;
else if (to + len > mtd->size)
len = mtd->size - to;
- if (part->master->write_ecc == NULL)
- return part->master->write (part->master, to + part->offset,
+ if (part->master->write_ecc == NULL)
+ return part->master->write (part->master, to + part->offset,
len, retlen, buf);
else
- return part->master->write_ecc (part->master, to + part->offset,
+ return part->master->write_ecc (part->master, to + part->offset,
len, retlen, buf, NULL, &mtd->oobinfo);
-
+
}
static int part_write_ecc (struct mtd_info *mtd, loff_t to, size_t len,
@@ -170,7 +170,7 @@ static int part_write_ecc (struct mtd_info *mtd, loff_t to, size_t len,
len = 0;
else if (to + len > mtd->size)
len = mtd->size - to;
- return part->master->write_ecc (part->master, to + part->offset,
+ return part->master->write_ecc (part->master, to + part->offset,
len, retlen, buf, eccbuf, oobsel);
}
@@ -184,19 +184,19 @@ static int part_write_oob (struct mtd_info *mtd, loff_t to, size_t len,
len = 0;
else if (to + len > mtd->size)
len = mtd->size - to;
- return part->master->write_oob (part->master, to + part->offset,
+ return part->master->write_oob (part->master, to + part->offset,
len, retlen, buf);
}
-static int part_write_user_prot_reg (struct mtd_info *mtd, loff_t from, size_t len,
+static int part_write_user_prot_reg (struct mtd_info *mtd, loff_t from, size_t len,
size_t *retlen, u_char *buf)
{
struct mtd_part *part = PART(mtd);
- return part->master->write_user_prot_reg (part->master, from,
+ return part->master->write_user_prot_reg (part->master, from,
len, retlen, buf);
}
-static int part_lock_user_prot_reg (struct mtd_info *mtd, loff_t from, size_t len)
+static int part_lock_user_prot_reg (struct mtd_info *mtd, loff_t from, size_t len)
{
struct mtd_part *part = PART(mtd);
return part->master->lock_user_prot_reg (part->master, from, len);
@@ -208,7 +208,7 @@ static int part_writev (struct mtd_info *mtd, const struct kvec *vecs,
struct mtd_part *part = PART(mtd);
if (!(mtd->flags & MTD_WRITEABLE))
return -EROFS;
- if (part->master->writev_ecc == NULL)
+ if (part->master->writev_ecc == NULL)
return part->master->writev (part->master, vecs, count,
to + part->offset, retlen);
else
@@ -221,12 +221,12 @@ static int part_readv (struct mtd_info *mtd, struct kvec *vecs,
unsigned long count, loff_t from, size_t *retlen)
{
struct mtd_part *part = PART(mtd);
- if (part->master->readv_ecc == NULL)
+ if (part->master->readv_ecc == NULL)
return part->master->readv (part->master, vecs, count,
from + part->offset, retlen);
else
return part->master->readv_ecc (part->master, vecs, count,
- from + part->offset, retlen,
+ from + part->offset, retlen,
NULL, &mtd->oobinfo);
}
@@ -252,7 +252,7 @@ static int part_readv_ecc (struct mtd_info *mtd, struct kvec *vecs,
if (oobsel == NULL)
oobsel = &mtd->oobinfo;
return part->master->readv_ecc (part->master, vecs, count,
- from + part->offset, retlen,
+ from + part->offset, retlen,
eccbuf, oobsel);
}
@@ -286,7 +286,7 @@ EXPORT_SYMBOL_GPL(mtd_erase_callback);
static int part_lock (struct mtd_info *mtd, loff_t ofs, size_t len)
{
struct mtd_part *part = PART(mtd);
- if ((len + ofs) > mtd->size)
+ if ((len + ofs) > mtd->size)
return -EINVAL;
return part->master->lock(part->master, ofs + part->offset, len);
}
@@ -294,7 +294,7 @@ static int part_lock (struct mtd_info *mtd, loff_t ofs, size_t len)
static int part_unlock (struct mtd_info *mtd, loff_t ofs, size_t len)
{
struct mtd_part *part = PART(mtd);
- if ((len + ofs) > mtd->size)
+ if ((len + ofs) > mtd->size)
return -EINVAL;
return part->master->unlock(part->master, ofs + part->offset, len);
}
@@ -337,8 +337,8 @@ static int part_block_markbad (struct mtd_info *mtd, loff_t ofs)
return part->master->block_markbad(part->master, ofs);
}
-/*
- * This function unregisters and destroy all slave MTD objects which are
+/*
+ * This function unregisters and destroy all slave MTD objects which are
* attached to the given master MTD object.
*/
@@ -371,7 +371,7 @@ int del_mtd_partitions(struct mtd_info *master)
* (Q: should we register the master MTD object as well?)
*/
-int add_mtd_partitions(struct mtd_info *master,
+int add_mtd_partitions(struct mtd_info *master,
const struct mtd_partition *parts,
int nbparts)
{
@@ -414,7 +414,7 @@ int add_mtd_partitions(struct mtd_info *master,
slave->mtd.point = part_point;
slave->mtd.unpoint = part_unpoint;
}
-
+
if (master->read_ecc)
slave->mtd.read_ecc = part_read_ecc;
if (master->write_ecc)
@@ -465,9 +465,10 @@ int add_mtd_partitions(struct mtd_info *master,
if (slave->offset == MTDPART_OFS_APPEND)
slave->offset = cur_offset;
if (slave->offset == MTDPART_OFS_NXTBLK) {
- u_int32_t emask = master->erasesize-1;
- slave->offset = (cur_offset + emask) & ~emask;
- if (slave->offset != cur_offset) {
+ slave->offset = cur_offset;
+ if ((cur_offset % master->erasesize) != 0) {
+ /* Round up to next erasesize */
+ slave->offset = ((cur_offset / master->erasesize) + 1) * master->erasesize;
printk(KERN_NOTICE "Moving partition %d: "
"0x%08x -> 0x%08x\n", i,
cur_offset, slave->offset);
@@ -476,8 +477,8 @@ int add_mtd_partitions(struct mtd_info *master,
if (slave->mtd.size == MTDPART_SIZ_FULL)
slave->mtd.size = master->size - slave->offset;
cur_offset = slave->offset + slave->mtd.size;
-
- printk (KERN_NOTICE "0x%08x-0x%08x : \"%s\"\n", slave->offset,
+
+ printk (KERN_NOTICE "0x%08x-0x%08x : \"%s\"\n", slave->offset,
slave->offset + slave->mtd.size, slave->mtd.name);
/* let's do some sanity checks */
@@ -497,7 +498,7 @@ int add_mtd_partitions(struct mtd_info *master,
/* Deal with variable erase size stuff */
int i;
struct mtd_erase_region_info *regions = master->eraseregions;
-
+
/* Find the first erase regions which is part of this partition. */
for (i=0; i < master->numeraseregions && slave->offset >= regions[i].offset; i++)
;
@@ -512,7 +513,7 @@ int add_mtd_partitions(struct mtd_info *master,
slave->mtd.erasesize = master->erasesize;
}
- if ((slave->mtd.flags & MTD_WRITEABLE) &&
+ if ((slave->mtd.flags & MTD_WRITEABLE) &&
(slave->offset % slave->mtd.erasesize)) {
/* Doesn't start on a boundary of major erase size */
/* FIXME: Let it be writable if it is on a boundary of _minor_ erase size though */
@@ -520,14 +521,14 @@ int add_mtd_partitions(struct mtd_info *master,
printk ("mtd: partition \"%s\" doesn't start on an erase block boundary -- force read-only\n",
parts[i].name);
}
- if ((slave->mtd.flags & MTD_WRITEABLE) &&
+ if ((slave->mtd.flags & MTD_WRITEABLE) &&
(slave->mtd.size % slave->mtd.erasesize)) {
slave->mtd.flags &= ~MTD_WRITEABLE;
printk ("mtd: partition \"%s\" doesn't end on an erase block -- force read-only\n",
parts[i].name);
}
- /* copy oobinfo from master */
+ /* copy oobinfo from master */
memcpy(&slave->mtd.oobinfo, &master->oobinfo, sizeof(slave->mtd.oobinfo));
if(parts[i].mtdp)
@@ -588,12 +589,12 @@ int deregister_mtd_parser(struct mtd_part_parser *p)
return 0;
}
-int parse_mtd_partitions(struct mtd_info *master, const char **types,
+int parse_mtd_partitions(struct mtd_info *master, const char **types,
struct mtd_partition **pparts, unsigned long origin)
{
struct mtd_part_parser *parser;
int ret = 0;
-
+
for ( ; ret <= 0 && *types; types++) {
parser = get_partition_parser(*types);
#ifdef CONFIG_KMOD
@@ -607,7 +608,7 @@ int parse_mtd_partitions(struct mtd_info *master, const char **types,
}
ret = (*parser->parse_fn)(master, pparts, origin);
if (ret > 0) {
- printk(KERN_NOTICE "%d %s partitions found on MTD device %s\n",
+ printk(KERN_NOTICE "%d %s partitions found on MTD device %s\n",
ret, parser->name, master->name);
}
put_partition_parser(parser);
diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
index 36d34e5e5a5a..1fc4c134d939 100644
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -1,5 +1,5 @@
# drivers/mtd/nand/Kconfig
-# $Id: Kconfig,v 1.31 2005/06/20 12:03:21 bjd Exp $
+# $Id: Kconfig,v 1.35 2005/11/07 11:14:30 gleixner Exp $
menu "NAND Flash Device Drivers"
depends on MTD!=n
@@ -25,33 +25,33 @@ config MTD_NAND_VERIFY_WRITE
config MTD_NAND_AUTCPU12
tristate "SmartMediaCard on autronix autcpu12 board"
- depends on ARM && MTD_NAND && ARCH_AUTCPU12
+ depends on MTD_NAND && ARCH_AUTCPU12
help
- This enables the driver for the autronix autcpu12 board to
+ This enables the driver for the autronix autcpu12 board to
access the SmartMediaCard.
config MTD_NAND_EDB7312
tristate "Support for Cirrus Logic EBD7312 evaluation board"
- depends on ARM && MTD_NAND && ARCH_EDB7312
+ depends on MTD_NAND && ARCH_EDB7312
help
- This enables the driver for the Cirrus Logic EBD7312 evaluation
+ This enables the driver for the Cirrus Logic EBD7312 evaluation
board to access the onboard NAND Flash.
config MTD_NAND_H1900
tristate "iPAQ H1900 flash"
- depends on ARM && MTD_NAND && ARCH_PXA && MTD_PARTITIONS
+ depends on MTD_NAND && ARCH_PXA && MTD_PARTITIONS
help
This enables the driver for the iPAQ h1900 flash.
config MTD_NAND_SPIA
tristate "NAND Flash device on SPIA board"
- depends on ARM && ARCH_P720T && MTD_NAND
+ depends on ARCH_P720T && MTD_NAND
help
If you had to ask, you don't have one. Say 'N'.
config MTD_NAND_TOTO
tristate "NAND Flash device on TOTO board"
- depends on ARM && ARCH_OMAP && MTD_NAND
+ depends on ARCH_OMAP && MTD_NAND
help
Support for NAND flash on Texas Instruments Toto platform.
@@ -59,8 +59,8 @@ config MTD_NAND_IDS
tristate
config MTD_NAND_AU1550
- tristate "Au1550 NAND support"
- depends on SOC_AU1550 && MTD_NAND
+ tristate "Au1550/1200 NAND support"
+ depends on (SOC_AU1200 || SOC_AU1550) && MTD_NAND
help
This enables the driver for the NAND flash controller on the
AMD/Alchemy 1550 SOC.
@@ -71,7 +71,7 @@ config MTD_NAND_RTC_FROM4
select REED_SOLOMON
select REED_SOLOMON_DEC8
help
- This enables the driver for the Renesas Technology AG-AND
+ This enables the driver for the Renesas Technology AG-AND
flash interface board (FROM_BOARD4)
config MTD_NAND_PPCHAMELEONEVB
@@ -88,7 +88,7 @@ config MTD_NAND_S3C2410
SoCs
No board specfic support is done by this driver, each board
- must advertise a platform_device for the driver to attach.
+ must advertise a platform_device for the driver to attach.
config MTD_NAND_S3C2410_DEBUG
bool "S3C2410 NAND driver debug"
@@ -181,7 +181,7 @@ config MTD_NAND_DISKONCHIP_BBTWRITE
config MTD_NAND_SHARPSL
bool "Support for NAND Flash on Sharp SL Series (C7xx + others)"
- depends on MTD_NAND && ARCH_PXA
+ depends on MTD_NAND && ARCH_PXA
config MTD_NAND_NANDSIM
bool "Support for NAND Flash Simulator"
diff --git a/drivers/mtd/nand/au1550nd.c b/drivers/mtd/nand/au1550nd.c
index 4c7719ce3f48..9c5945d6df88 100644
--- a/drivers/mtd/nand/au1550nd.c
+++ b/drivers/mtd/nand/au1550nd.c
@@ -3,7 +3,7 @@
*
* Copyright (C) 2004 Embedded Edge, LLC
*
- * $Id: au1550nd.c,v 1.11 2004/11/04 12:53:10 gleixner Exp $
+ * $Id: au1550nd.c,v 1.13 2005/11/07 11:14:30 gleixner Exp $
*
* 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
@@ -17,24 +17,19 @@
#include <linux/mtd/mtd.h>
#include <linux/mtd/nand.h>
#include <linux/mtd/partitions.h>
+#include <linux/version.h>
#include <asm/io.h>
/* fixme: this is ugly */
#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 0)
-#include <asm/mach-au1x00/au1000.h>
-#ifdef CONFIG_MIPS_PB1550
-#include <asm/mach-pb1x00/pb1550.h>
-#endif
-#ifdef CONFIG_MIPS_DB1550
-#include <asm/mach-db1x00/db1x00.h>
-#endif
+#include <asm/mach-au1x00/au1xxx.h>
#else
#include <asm/au1000.h>
#ifdef CONFIG_MIPS_PB1550
-#include <asm/pb1550.h>
+#include <asm/pb1550.h>
#endif
#ifdef CONFIG_MIPS_DB1550
-#include <asm/db1x00.h>
+#include <asm/db1x00.h>
#endif
#endif
@@ -45,39 +40,22 @@ static struct mtd_info *au1550_mtd = NULL;
static void __iomem *p_nand;
static int nand_width = 1; /* default x8*/
-#define NAND_CS 1
-
/*
* Define partitions for flash device
*/
const static struct mtd_partition partition_info[] = {
-#ifdef CONFIG_MIPS_PB1550
-#define NUM_PARTITIONS 2
- {
- .name = "Pb1550 NAND FS 0",
+ {
+ .name = "NAND FS 0",
.offset = 0,
- .size = 8*1024*1024
+ .size = 8*1024*1024
},
- {
- .name = "Pb1550 NAND FS 1",
+ {
+ .name = "NAND FS 1",
.offset = MTDPART_OFS_APPEND,
- .size = MTDPART_SIZ_FULL
+ .size = MTDPART_SIZ_FULL
}
-#endif
-#ifdef CONFIG_MIPS_DB1550
-#define NUM_PARTITIONS 2
- {
- .name = "Db1550 NAND FS 0",
- .offset = 0,
- .size = 8*1024*1024
- },
- {
- .name = "Db1550 NAND FS 1",
- .offset = MTDPART_OFS_APPEND,
- .size = MTDPART_SIZ_FULL
- }
-#endif
};
+#define NB_OF(x) (sizeof(x)/sizeof(x[0]))
/**
@@ -112,7 +90,7 @@ static void au_write_byte(struct mtd_info *mtd, u_char byte)
* au_read_byte16 - read one byte endianess aware from the chip
* @mtd: MTD device structure
*
- * read function for 16bit buswith with
+ * read function for 16bit buswith with
* endianess conversion
*/
static u_char au_read_byte16(struct mtd_info *mtd)
@@ -142,7 +120,7 @@ static void au_write_byte16(struct mtd_info *mtd, u_char byte)
* au_read_word - read one word from the chip
* @mtd: MTD device structure
*
- * read function for 16bit buswith without
+ * read function for 16bit buswith without
* endianess conversion
*/
static u16 au_read_word(struct mtd_info *mtd)
@@ -158,7 +136,7 @@ static u16 au_read_word(struct mtd_info *mtd)
* @mtd: MTD device structure
* @word: data word to write
*
- * write function for 16bit buswith without
+ * write function for 16bit buswith without
* endianess conversion
*/
static void au_write_word(struct mtd_info *mtd, u16 word)
@@ -188,7 +166,7 @@ static void au_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
}
/**
- * au_read_buf - read chip data into buffer
+ * au_read_buf - read chip data into buffer
* @mtd: MTD device structure
* @buf: buffer to store date
* @len: number of bytes to read
@@ -202,12 +180,12 @@ static void au_read_buf(struct mtd_info *mtd, u_char *buf, int len)
for (i=0; i<len; i++) {
buf[i] = readb(this->IO_ADDR_R);
- au_sync();
+ au_sync();
}
}
/**
- * au_verify_buf - Verify chip data against buffer
+ * au_verify_buf - Verify chip data against buffer
* @mtd: MTD device structure
* @buf: buffer containing the data to compare
* @len: number of bytes to compare
@@ -242,16 +220,16 @@ static void au_write_buf16(struct mtd_info *mtd, const u_char *buf, int len)
struct nand_chip *this = mtd->priv;
u16 *p = (u16 *) buf;
len >>= 1;
-
+
for (i=0; i<len; i++) {
writew(p[i], this->IO_ADDR_W);
au_sync();
}
-
+
}
/**
- * au_read_buf16 - read chip data into buffer
+ * au_read_buf16 - read chip data into buffer
* @mtd: MTD device structure
* @buf: buffer to store date
* @len: number of bytes to read
@@ -272,7 +250,7 @@ static void au_read_buf16(struct mtd_info *mtd, u_char *buf, int len)
}
/**
- * au_verify_buf16 - Verify chip data against buffer
+ * au_verify_buf16 - Verify chip data against buffer
* @mtd: MTD device structure
* @buf: buffer containing the data to compare
* @len: number of bytes to compare
@@ -305,26 +283,26 @@ static void au1550_hwcontrol(struct mtd_info *mtd, int cmd)
case NAND_CTL_CLRCLE: this->IO_ADDR_W = p_nand + MEM_STNAND_DATA; break;
case NAND_CTL_SETALE: this->IO_ADDR_W = p_nand + MEM_STNAND_ADDR; break;
- case NAND_CTL_CLRALE:
- this->IO_ADDR_W = p_nand + MEM_STNAND_DATA;
- /* FIXME: Nobody knows why this is neccecary,
+ case NAND_CTL_CLRALE:
+ this->IO_ADDR_W = p_nand + MEM_STNAND_DATA;
+ /* FIXME: Nobody knows why this is neccecary,
* but it works only that way */
- udelay(1);
+ udelay(1);
break;
- case NAND_CTL_SETNCE:
+ case NAND_CTL_SETNCE:
/* assert (force assert) chip enable */
au_writel((1<<(4+NAND_CS)) , MEM_STNDCTL); break;
break;
- case NAND_CTL_CLRNCE:
+ case NAND_CTL_CLRNCE:
/* deassert chip enable */
au_writel(0, MEM_STNDCTL); break;
break;
}
this->IO_ADDR_R = this->IO_ADDR_W;
-
+
/* Drain the writebuffer */
au_sync();
}
@@ -339,14 +317,16 @@ int au1550_device_ready(struct mtd_info *mtd)
/*
* Main initialization routine
*/
-int __init au1550_init (void)
+int __init au1xxx_nand_init (void)
{
struct nand_chip *this;
u16 boot_swapboot = 0; /* default value */
int retval;
+ u32 mem_staddr;
+ u32 nand_phys;
/* Allocate memory for MTD device structure and private data */
- au1550_mtd = kmalloc (sizeof(struct mtd_info) +
+ au1550_mtd = kmalloc (sizeof(struct mtd_info) +
sizeof (struct nand_chip), GFP_KERNEL);
if (!au1550_mtd) {
printk ("Unable to allocate NAND MTD dev structure.\n");
@@ -364,14 +344,17 @@ int __init au1550_init (void)
au1550_mtd->priv = this;
- /* MEM_STNDCTL: disable ints, disable nand boot */
- au_writel(0, MEM_STNDCTL);
+ /* disable interrupts */
+ au_writel(au_readl(MEM_STNDCTL) & ~(1<<8), MEM_STNDCTL);
+
+ /* disable NAND boot */
+ au_writel(au_readl(MEM_STNDCTL) & ~(1<<0), MEM_STNDCTL);
#ifdef CONFIG_MIPS_PB1550
/* set gpio206 high */
au_writel(au_readl(GPIO2_DIR) & ~(1<<6), GPIO2_DIR);
- boot_swapboot = (au_readl(MEM_STSTAT) & (0x7<<1)) |
+ boot_swapboot = (au_readl(MEM_STSTAT) & (0x7<<1)) |
((bcsr->status >> 6) & 0x1);
switch (boot_swapboot) {
case 0:
@@ -397,25 +380,66 @@ int __init au1550_init (void)
}
#endif
- /* Configure RCE1 - should be done by YAMON */
- au_writel(0x5 | (nand_width << 22), 0xB4001010); /* MEM_STCFG1 */
- au_writel(NAND_TIMING, 0xB4001014); /* MEM_STTIME1 */
- au_sync();
+ /* Configure chip-select; normally done by boot code, e.g. YAMON */
+#ifdef NAND_STCFG
+ if (NAND_CS == 0) {
+ au_writel(NAND_STCFG, MEM_STCFG0);
+ au_writel(NAND_STTIME, MEM_STTIME0);
+ au_writel(NAND_STADDR, MEM_STADDR0);
+ }
+ if (NAND_CS == 1) {
+ au_writel(NAND_STCFG, MEM_STCFG1);
+ au_writel(NAND_STTIME, MEM_STTIME1);
+ au_writel(NAND_STADDR, MEM_STADDR1);
+ }
+ if (NAND_CS == 2) {
+ au_writel(NAND_STCFG, MEM_STCFG2);
+ au_writel(NAND_STTIME, MEM_STTIME2);
+ au_writel(NAND_STADDR, MEM_STADDR2);
+ }
+ if (NAND_CS == 3) {
+ au_writel(NAND_STCFG, MEM_STCFG3);
+ au_writel(NAND_STTIME, MEM_STTIME3);
+ au_writel(NAND_STADDR, MEM_STADDR3);
+ }
+#endif
- /* setup and enable chip select, MEM_STADDR1 */
- /* we really need to decode offsets only up till 0x20 */
- au_writel((1<<28) | (NAND_PHYS_ADDR>>4) |
- (((NAND_PHYS_ADDR + 0x1000)-1) & (0x3fff<<18)>>18),
- MEM_STADDR1);
- au_sync();
+ /* Locate NAND chip-select in order to determine NAND phys address */
+ mem_staddr = 0x00000000;
+ if (((au_readl(MEM_STCFG0) & 0x7) == 0x5) && (NAND_CS == 0))
+ mem_staddr = au_readl(MEM_STADDR0);
+ else if (((au_readl(MEM_STCFG1) & 0x7) == 0x5) && (NAND_CS == 1))
+ mem_staddr = au_readl(MEM_STADDR1);
+ else if (((au_readl(MEM_STCFG2) & 0x7) == 0x5) && (NAND_CS == 2))
+ mem_staddr = au_readl(MEM_STADDR2);
+ else if (((au_readl(MEM_STCFG3) & 0x7) == 0x5) && (NAND_CS == 3))
+ mem_staddr = au_readl(MEM_STADDR3);
+
+ if (mem_staddr == 0x00000000) {
+ printk("Au1xxx NAND: ERROR WITH NAND CHIP-SELECT\n");
+ kfree(au1550_mtd);
+ return 1;
+ }
+ nand_phys = (mem_staddr << 4) & 0xFFFC0000;
+
+ p_nand = (void __iomem *)ioremap(nand_phys, 0x1000);
+
+ /* make controller and MTD agree */
+ if (NAND_CS == 0)
+ nand_width = au_readl(MEM_STCFG0) & (1<<22);
+ if (NAND_CS == 1)
+ nand_width = au_readl(MEM_STCFG1) & (1<<22);
+ if (NAND_CS == 2)
+ nand_width = au_readl(MEM_STCFG2) & (1<<22);
+ if (NAND_CS == 3)
+ nand_width = au_readl(MEM_STCFG3) & (1<<22);
- p_nand = ioremap(NAND_PHYS_ADDR, 0x1000);
/* Set address of hardware control function */
this->hwcontrol = au1550_hwcontrol;
this->dev_ready = au1550_device_ready;
/* 30 us command delay time */
- this->chip_delay = 30;
+ this->chip_delay = 30;
this->eccmode = NAND_ECC_SOFT;
this->options = NAND_NO_AUTOINCR;
@@ -438,19 +462,19 @@ int __init au1550_init (void)
}
/* Register the partitions */
- add_mtd_partitions(au1550_mtd, partition_info, NUM_PARTITIONS);
+ add_mtd_partitions(au1550_mtd, partition_info, NB_OF(partition_info));
return 0;
outio:
iounmap ((void *)p_nand);
-
+
outmem:
kfree (au1550_mtd);
return retval;
}
-module_init(au1550_init);
+module_init(au1xxx_nand_init);
/*
* Clean up routine
diff --git a/drivers/mtd/nand/autcpu12.c b/drivers/mtd/nand/autcpu12.c
index 4afa8ced05ad..a3c7fea404d0 100644
--- a/drivers/mtd/nand/autcpu12.c
+++ b/drivers/mtd/nand/autcpu12.c
@@ -5,8 +5,8 @@
*
* Derived from drivers/mtd/spia.c
* Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com)
- *
- * $Id: autcpu12.c,v 1.22 2004/11/04 12:53:10 gleixner Exp $
+ *
+ * $Id: autcpu12.c,v 1.23 2005/11/07 11:14:30 gleixner Exp $
*
* 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
@@ -14,7 +14,7 @@
*
* Overview:
* This is a device driver for the NAND flash device found on the
- * autronix autcpu12 board, which is a SmartMediaCard. It supports
+ * autronix autcpu12 board, which is a SmartMediaCard. It supports
* 16MiB, 32MiB and 64MiB cards.
*
*
@@ -27,7 +27,6 @@
* 10-06-2002 TG 128K card support added
*/
-#include <linux/version.h>
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/module.h>
@@ -93,7 +92,7 @@ static struct mtd_partition partition_info128k[] = {
#define NUM_PARTITIONS32K 2
#define NUM_PARTITIONS64K 2
#define NUM_PARTITIONS128K 2
-/*
+/*
* hardware specific access to control-lines
*/
static void autcpu12_hwcontrol(struct mtd_info *mtd, int cmd)
@@ -163,7 +162,7 @@ int __init autcpu12_init (void)
this->hwcontrol = autcpu12_hwcontrol;
this->dev_ready = autcpu12_device_ready;
/* 20 us command delay time */
- this->chip_delay = 20;
+ this->chip_delay = 20;
this->eccmode = NAND_ECC_SOFT;
/* Enable the following for a flash based bad block table */
@@ -171,21 +170,21 @@ int __init autcpu12_init (void)
this->options = NAND_USE_FLASH_BBT;
*/
this->options = NAND_USE_FLASH_BBT;
-
+
/* Scan to find existance of the device */
if (nand_scan (autcpu12_mtd, 1)) {
err = -ENXIO;
goto out_ior;
}
-
+
/* Register the partitions */
switch(autcpu12_mtd->size){
case SZ_16M: add_mtd_partitions(autcpu12_mtd, partition_info16k, NUM_PARTITIONS16K); break;
case SZ_32M: add_mtd_partitions(autcpu12_mtd, partition_info32k, NUM_PARTITIONS32K); break;
- case SZ_64M: add_mtd_partitions(autcpu12_mtd, partition_info64k, NUM_PARTITIONS64K); break;
- case SZ_128M: add_mtd_partitions(autcpu12_mtd, partition_info128k, NUM_PARTITIONS128K); break;
+ case SZ_64M: add_mtd_partitions(autcpu12_mtd, partition_info64k, NUM_PARTITIONS64K); break;
+ case SZ_128M: add_mtd_partitions(autcpu12_mtd, partition_info128k, NUM_PARTITIONS128K); break;
default: {
- printk ("Unsupported SmartMedia device\n");
+ printk ("Unsupported SmartMedia device\n");
err = -ENXIO;
goto out_ior;
}
@@ -213,7 +212,7 @@ static void __exit autcpu12_cleanup (void)
/* unmap physical adress */
iounmap((void *)autcpu12_fio_base);
-
+
/* Free the MTD device structure */
kfree (autcpu12_mtd);
}
diff --git a/drivers/mtd/nand/diskonchip.c b/drivers/mtd/nand/diskonchip.c
index fdb5d4ad3d52..21d4e8f4b7af 100644
--- a/drivers/mtd/nand/diskonchip.c
+++ b/drivers/mtd/nand/diskonchip.c
@@ -1,4 +1,4 @@
-/*
+/*
* drivers/mtd/nand/diskonchip.c
*
* (C) 2003 Red Hat, Inc.
@@ -8,15 +8,15 @@
* Author: David Woodhouse <dwmw2@infradead.org>
* Additional Diskonchip 2000 and Millennium support by Dan Brown <dan_brown@ieee.org>
* Diskonchip Millennium Plus support by Kalev Lember <kalev@smartlink.ee>
- *
+ *
* Error correction code lifted from the old docecc code
- * Author: Fabrice Bellard (fabrice.bellard@netgem.com)
+ * Author: Fabrice Bellard (fabrice.bellard@netgem.com)
* Copyright (C) 2000 Netgem S.A.
* converted to the generic Reed-Solomon library by Thomas Gleixner <tglx@linutronix.de>
- *
+ *
* Interface to generic NAND code for M-Systems DiskOnChip devices
*
- * $Id: diskonchip.c,v 1.54 2005/04/07 14:22:55 dbrown Exp $
+ * $Id: diskonchip.c,v 1.55 2005/11/07 11:14:30 gleixner Exp $
*/
#include <linux/kernel.h>
@@ -42,16 +42,16 @@
static unsigned long __initdata doc_locations[] = {
#if defined (__alpha__) || defined(__i386__) || defined(__x86_64__)
#ifdef CONFIG_MTD_NAND_DISKONCHIP_PROBE_HIGH
- 0xfffc8000, 0xfffca000, 0xfffcc000, 0xfffce000,
+ 0xfffc8000, 0xfffca000, 0xfffcc000, 0xfffce000,
0xfffd0000, 0xfffd2000, 0xfffd4000, 0xfffd6000,
- 0xfffd8000, 0xfffda000, 0xfffdc000, 0xfffde000,
- 0xfffe0000, 0xfffe2000, 0xfffe4000, 0xfffe6000,
+ 0xfffd8000, 0xfffda000, 0xfffdc000, 0xfffde000,
+ 0xfffe0000, 0xfffe2000, 0xfffe4000, 0xfffe6000,
0xfffe8000, 0xfffea000, 0xfffec000, 0xfffee000,
#else /* CONFIG_MTD_DOCPROBE_HIGH */
- 0xc8000, 0xca000, 0xcc000, 0xce000,
+ 0xc8000, 0xca000, 0xcc000, 0xce000,
0xd0000, 0xd2000, 0xd4000, 0xd6000,
- 0xd8000, 0xda000, 0xdc000, 0xde000,
- 0xe0000, 0xe2000, 0xe4000, 0xe6000,
+ 0xd8000, 0xda000, 0xdc000, 0xde000,
+ 0xe0000, 0xe2000, 0xe4000, 0xe6000,
0xe8000, 0xea000, 0xec000, 0xee000,
#endif /* CONFIG_MTD_DOCPROBE_HIGH */
#elif defined(__PPC__)
@@ -138,7 +138,7 @@ MODULE_PARM_DESC(doc_config_location, "Physical memory address at which to probe
/* the Reed Solomon control structure */
static struct rs_control *rs_decoder;
-/*
+/*
* The HW decoder in the DoC ASIC's provides us a error syndrome,
* which we must convert to a standard syndrom usable by the generic
* Reed-Solomon library code.
@@ -163,8 +163,8 @@ static int doc_ecc_decode (struct rs_control *rs, uint8_t *data, uint8_t *ecc)
/* Initialize the syndrom buffer */
for (i = 0; i < NROOTS; i++)
s[i] = ds[0];
- /*
- * Evaluate
+ /*
+ * Evaluate
* s[i] = ds[3]x^3 + ds[2]x^2 + ds[1]x^1 + ds[0]
* where x = alpha^(FCR + i)
*/
@@ -188,7 +188,7 @@ static int doc_ecc_decode (struct rs_control *rs, uint8_t *data, uint8_t *ecc)
if (nerr < 0)
return nerr;
- /*
+ /*
* Correct the errors. The bitpositions are a bit of magic,
* but they are given by the design of the de/encoder circuit
* in the DoC ASIC's.
@@ -205,7 +205,7 @@ static int doc_ecc_decode (struct rs_control *rs, uint8_t *data, uint8_t *ecc)
can be modified since pos is even */
index = (pos >> 3) ^ 1;
bitpos = pos & 7;
- if ((index >= 0 && index < SECTOR_SIZE) ||
+ if ((index >= 0 && index < SECTOR_SIZE) ||
index == (SECTOR_SIZE + 1)) {
val = (uint8_t) (errval[i] >> (2 + bitpos));
parity ^= val;
@@ -216,7 +216,7 @@ static int doc_ecc_decode (struct rs_control *rs, uint8_t *data, uint8_t *ecc)
bitpos = (bitpos + 10) & 7;
if (bitpos == 0)
bitpos = 8;
- if ((index >= 0 && index < SECTOR_SIZE) ||
+ if ((index >= 0 && index < SECTOR_SIZE) ||
index == (SECTOR_SIZE + 1)) {
val = (uint8_t)(errval[i] << (8 - bitpos));
parity ^= val;
@@ -233,7 +233,7 @@ static void DoC_Delay(struct doc_priv *doc, unsigned short cycles)
{
volatile char dummy;
int i;
-
+
for (i = 0; i < cycles; i++) {
if (DoC_is_Millennium(doc))
dummy = ReadDOC(doc->virtadr, NOP);
@@ -242,7 +242,7 @@ static void DoC_Delay(struct doc_priv *doc, unsigned short cycles)
else
dummy = ReadDOC(doc->virtadr, DOCStatus);
}
-
+
}
#define CDSN_CTRL_FR_B_MASK (CDSN_CTRL_FR_B0 | CDSN_CTRL_FR_B1)
@@ -327,7 +327,7 @@ static u_char doc2000_read_byte(struct mtd_info *mtd)
return ret;
}
-static void doc2000_writebuf(struct mtd_info *mtd,
+static void doc2000_writebuf(struct mtd_info *mtd,
const u_char *buf, int len)
{
struct nand_chip *this = mtd->priv;
@@ -343,7 +343,7 @@ static void doc2000_writebuf(struct mtd_info *mtd,
if (debug) printk("\n");
}
-static void doc2000_readbuf(struct mtd_info *mtd,
+static void doc2000_readbuf(struct mtd_info *mtd,
u_char *buf, int len)
{
struct nand_chip *this = mtd->priv;
@@ -358,7 +358,7 @@ static void doc2000_readbuf(struct mtd_info *mtd,
}
}
-static void doc2000_readbuf_dword(struct mtd_info *mtd,
+static void doc2000_readbuf_dword(struct mtd_info *mtd,
u_char *buf, int len)
{
struct nand_chip *this = mtd->priv;
@@ -379,7 +379,7 @@ static void doc2000_readbuf_dword(struct mtd_info *mtd,
}
}
-static int doc2000_verifybuf(struct mtd_info *mtd,
+static int doc2000_verifybuf(struct mtd_info *mtd,
const u_char *buf, int len)
{
struct nand_chip *this = mtd->priv;
@@ -406,12 +406,12 @@ static uint16_t __init doc200x_ident_chip(struct mtd_info *mtd, int nr)
doc200x_hwcontrol(mtd, NAND_CTL_SETALE);
this->write_byte(mtd, 0);
doc200x_hwcontrol(mtd, NAND_CTL_CLRALE);
-
+
/* We cant' use dev_ready here, but at least we wait for the
- * command to complete
+ * command to complete
*/
udelay(50);
-
+
ret = this->read_byte(mtd) << 8;
ret |= this->read_byte(mtd);
@@ -438,7 +438,7 @@ static uint16_t __init doc200x_ident_chip(struct mtd_info *mtd, int nr)
this->read_buf = &doc2000_readbuf_dword;
}
}
-
+
return ret;
}
@@ -469,7 +469,7 @@ static int doc200x_wait(struct mtd_info *mtd, struct nand_chip *this, int state)
struct doc_priv *doc = this->priv;
int status;
-
+
DoC_WaitReady(doc);
this->cmdfunc(mtd, NAND_CMD_STATUS, -1, -1);
DoC_WaitReady(doc);
@@ -503,7 +503,7 @@ static u_char doc2001_read_byte(struct mtd_info *mtd)
return ReadDOC(docptr, LastDataRead);
}
-static void doc2001_writebuf(struct mtd_info *mtd,
+static void doc2001_writebuf(struct mtd_info *mtd,
const u_char *buf, int len)
{
struct nand_chip *this = mtd->priv;
@@ -517,7 +517,7 @@ static void doc2001_writebuf(struct mtd_info *mtd,
WriteDOC(0x00, docptr, WritePipeTerm);
}
-static void doc2001_readbuf(struct mtd_info *mtd,
+static void doc2001_readbuf(struct mtd_info *mtd,
u_char *buf, int len)
{
struct nand_chip *this = mtd->priv;
@@ -535,7 +535,7 @@ static void doc2001_readbuf(struct mtd_info *mtd,
buf[i] = ReadDOC(docptr, LastDataRead);
}
-static int doc2001_verifybuf(struct mtd_info *mtd,
+static int doc2001_verifybuf(struct mtd_info *mtd,
const u_char *buf, int len)
{
struct nand_chip *this = mtd->priv;
@@ -570,7 +570,7 @@ static u_char doc2001plus_read_byte(struct mtd_info *mtd)
return ret;
}
-static void doc2001plus_writebuf(struct mtd_info *mtd,
+static void doc2001plus_writebuf(struct mtd_info *mtd,
const u_char *buf, int len)
{
struct nand_chip *this = mtd->priv;
@@ -587,7 +587,7 @@ static void doc2001plus_writebuf(struct mtd_info *mtd,
if (debug) printk("\n");
}
-static void doc2001plus_readbuf(struct mtd_info *mtd,
+static void doc2001plus_readbuf(struct mtd_info *mtd,
u_char *buf, int len)
{
struct nand_chip *this = mtd->priv;
@@ -617,7 +617,7 @@ static void doc2001plus_readbuf(struct mtd_info *mtd,
if (debug) printk("\n");
}
-static int doc2001plus_verifybuf(struct mtd_info *mtd,
+static int doc2001plus_verifybuf(struct mtd_info *mtd,
const u_char *buf, int len)
{
struct nand_chip *this = mtd->priv;
@@ -797,7 +797,7 @@ static void doc2001plus_command (struct mtd_info *mtd, unsigned command, int col
WriteDOC(0, docptr, Mplus_FlashControl);
}
- /*
+ /*
* program and erase have their own busy handlers
* status and sequential in needs no delay
*/
@@ -822,7 +822,7 @@ static void doc2001plus_command (struct mtd_info *mtd, unsigned command, int col
/* This applies to read commands */
default:
- /*
+ /*
* If we don't have access to the busy pin, we apply the given
* command delay
*/
@@ -945,7 +945,7 @@ static int doc200x_calculate_ecc(struct mtd_info *mtd, const u_char *dat,
for (i = 0; i < 6; i++) {
if (DoC_is_MillenniumPlus(doc))
ecc_code[i] = ReadDOC_(docptr, DoC_Mplus_ECCSyndrome0 + i);
- else
+ else
ecc_code[i] = ReadDOC_(docptr, DoC_ECCSyndrome0 + i);
if (ecc_code[i] != empty_write_ecc[i])
emptymatch = 0;
@@ -982,7 +982,7 @@ static int doc200x_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_
void __iomem *docptr = doc->virtadr;
volatile u_char dummy;
int emptymatch = 1;
-
+
/* flush the pipeline */
if (DoC_is_2000(doc)) {
dummy = ReadDOC(docptr, 2k_ECCStatus);
@@ -997,7 +997,7 @@ static int doc200x_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_
dummy = ReadDOC(docptr, ECCConf);
dummy = ReadDOC(docptr, ECCConf);
}
-
+
/* Error occured ? */
if (dummy & 0x80) {
for (i = 0; i < 6; i++) {
@@ -1035,7 +1035,7 @@ static int doc200x_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_
if (!emptymatch) ret = doc_ecc_decode (rs_decoder, dat, calc_ecc);
if (ret > 0)
printk(KERN_ERR "doc200x_correct_data corrected %d errors\n", ret);
- }
+ }
if (DoC_is_MillenniumPlus(doc))
WriteDOC(DOC_ECC_DIS, docptr, Mplus_ECCConf);
else
@@ -1046,7 +1046,7 @@ static int doc200x_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_
}
return ret;
}
-
+
//u_char mydatabuf[528];
/* The strange out-of-order .oobfree list below is a (possibly unneeded)
@@ -1065,7 +1065,7 @@ static struct nand_oobinfo doc200x_oobinfo = {
.eccpos = {0, 1, 2, 3, 4, 5},
.oobfree = { {8, 8}, {6, 2} }
};
-
+
/* Find the (I)NFTL Media Header, and optionally also the mirror media header.
On sucessful return, buf will contain a copy of the media header for
further processing. id is the string to scan for, and will presumably be
@@ -1251,7 +1251,7 @@ static inline int __init inftl_partscan(struct mtd_info *mtd,
mh->BlockMultiplierBits = le32_to_cpu(mh->BlockMultiplierBits);
mh->FormatFlags = le32_to_cpu(mh->FormatFlags);
mh->PercentUsed = le32_to_cpu(mh->PercentUsed);
-
+
printk(KERN_INFO " bootRecordID = %s\n"
" NoOfBootImageBlocks = %d\n"
" NoOfBinaryPartitions = %d\n"
@@ -1468,7 +1468,7 @@ static inline int __init doc2001_init(struct mtd_info *mtd)
ReadDOC(doc->virtadr, ChipID);
if (ReadDOC(doc->virtadr, ChipID) != DOC_ChipID_DocMil) {
/* It's not a Millennium; it's one of the newer
- DiskOnChip 2000 units with a similar ASIC.
+ DiskOnChip 2000 units with a similar ASIC.
Treat it like a Millennium, except that it
can have multiple chips. */
doc2000_count_chips(mtd);
@@ -1530,20 +1530,20 @@ static inline int __init doc_probe(unsigned long physadr)
* to the DOCControl register. So we store the current contents
* of the DOCControl register's location, in case we later decide
* that it's not a DiskOnChip, and want to put it back how we
- * found it.
+ * found it.
*/
save_control = ReadDOC(virtadr, DOCControl);
/* Reset the DiskOnChip ASIC */
- WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_RESET,
+ WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_RESET,
virtadr, DOCControl);
- WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_RESET,
+ WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_RESET,
virtadr, DOCControl);
/* Enable the DiskOnChip ASIC */
- WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_NORMAL,
+ WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_NORMAL,
virtadr, DOCControl);
- WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_NORMAL,
+ WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_NORMAL,
virtadr, DOCControl);
ChipID = ReadDOC(virtadr, ChipID);
@@ -1738,7 +1738,7 @@ static int __init init_nanddoc(void)
int i, ret = 0;
/* We could create the decoder on demand, if memory is a concern.
- * This way we have it handy, if an error happens
+ * This way we have it handy, if an error happens
*
* Symbolsize is 10 (bits)
* Primitve polynomial is x^10+x^3+1
diff --git a/drivers/mtd/nand/edb7312.c b/drivers/mtd/nand/edb7312.c
index 5549681ccdce..9b1fd2f387fa 100644
--- a/drivers/mtd/nand/edb7312.c
+++ b/drivers/mtd/nand/edb7312.c
@@ -6,7 +6,7 @@
* Derived from drivers/mtd/nand/autcpu12.c
* Copyright (c) 2001 Thomas Gleixner (gleixner@autronix.de)
*
- * $Id: edb7312.c,v 1.11 2004/11/04 12:53:10 gleixner Exp $
+ * $Id: edb7312.c,v 1.12 2005/11/07 11:14:30 gleixner Exp $
*
* 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
@@ -71,27 +71,27 @@ static struct mtd_partition partition_info[] = {
#endif
-/*
+/*
* hardware specific access to control-lines
*/
-static void ep7312_hwcontrol(struct mtd_info *mtd, int cmd)
+static void ep7312_hwcontrol(struct mtd_info *mtd, int cmd)
{
switch(cmd) {
-
- case NAND_CTL_SETCLE:
- clps_writeb(clps_readb(ep7312_pxdr) | 0x10, ep7312_pxdr);
+
+ case NAND_CTL_SETCLE:
+ clps_writeb(clps_readb(ep7312_pxdr) | 0x10, ep7312_pxdr);
break;
- case NAND_CTL_CLRCLE:
+ case NAND_CTL_CLRCLE:
clps_writeb(clps_readb(ep7312_pxdr) & ~0x10, ep7312_pxdr);
break;
-
+
case NAND_CTL_SETALE:
clps_writeb(clps_readb(ep7312_pxdr) | 0x20, ep7312_pxdr);
break;
case NAND_CTL_CLRALE:
clps_writeb(clps_readb(ep7312_pxdr) & ~0x20, ep7312_pxdr);
break;
-
+
case NAND_CTL_SETNCE:
clps_writeb((clps_readb(ep7312_pxdr) | 0x80) & ~0x40, ep7312_pxdr);
break;
@@ -122,16 +122,16 @@ static int __init ep7312_init (void)
int mtd_parts_nb = 0;
struct mtd_partition *mtd_parts = 0;
void __iomem * ep7312_fio_base;
-
+
/* Allocate memory for MTD device structure and private data */
- ep7312_mtd = kmalloc(sizeof(struct mtd_info) +
+ ep7312_mtd = kmalloc(sizeof(struct mtd_info) +
sizeof(struct nand_chip),
GFP_KERNEL);
if (!ep7312_mtd) {
printk("Unable to allocate EDB7312 NAND MTD device structure.\n");
return -ENOMEM;
}
-
+
/* map physical adress */
ep7312_fio_base = ioremap(ep7312_fio_pbase, SZ_1K);
if(!ep7312_fio_base) {
@@ -139,23 +139,23 @@ static int __init ep7312_init (void)
kfree(ep7312_mtd);
return -EIO;
}
-
+
/* Get pointer to private data */
this = (struct nand_chip *) (&ep7312_mtd[1]);
-
+
/* Initialize structures */
memset((char *) ep7312_mtd, 0, sizeof(struct mtd_info));
memset((char *) this, 0, sizeof(struct nand_chip));
-
+
/* Link the private data with the MTD structure */
ep7312_mtd->priv = this;
-
+
/*
* Set GPIO Port B control register so that the pins are configured
* to be outputs for controlling the NAND flash.
*/
clps_writeb(0xf0, ep7312_pxddr);
-
+
/* insert callbacks */
this->IO_ADDR_R = ep7312_fio_base;
this->IO_ADDR_W = ep7312_fio_base;
@@ -163,14 +163,14 @@ static int __init ep7312_init (void)
this->dev_ready = ep7312_device_ready;
/* 15 us command delay time */
this->chip_delay = 15;
-
+
/* Scan to find existence of the device */
if (nand_scan (ep7312_mtd, 1)) {
iounmap((void *)ep7312_fio_base);
kfree (ep7312_mtd);
return -ENXIO;
}
-
+
#ifdef CONFIG_MTD_PARTITIONS
ep7312_mtd->name = "edb7312-nand";
mtd_parts_nb = parse_mtd_partitions(ep7312_mtd, part_probes,
@@ -185,11 +185,11 @@ static int __init ep7312_init (void)
mtd_parts_nb = NUM_PARTITIONS;
part_type = "static";
}
-
+
/* Register the partitions */
printk(KERN_NOTICE "Using %s partition definition\n", part_type);
add_mtd_partitions(ep7312_mtd, mtd_parts, mtd_parts_nb);
-
+
/* Return happy */
return 0;
}
@@ -201,13 +201,13 @@ module_init(ep7312_init);
static void __exit ep7312_cleanup (void)
{
struct nand_chip *this = (struct nand_chip *) &ep7312_mtd[1];
-
+
/* Release resources, unregister device */
nand_release (ap7312_mtd);
-
+
/* Free internal data buffer */
kfree (this->data_buf);
-
+
/* Free the MTD device structure */
kfree (ep7312_mtd);
}
diff --git a/drivers/mtd/nand/h1910.c b/drivers/mtd/nand/h1910.c
index 3825a7a0900c..041e4b3358fb 100644
--- a/drivers/mtd/nand/h1910.c
+++ b/drivers/mtd/nand/h1910.c
@@ -7,7 +7,7 @@
* Copyright (C) 2002 Marius Gröger (mag@sysgo.de)
* Copyright (c) 2001 Thomas Gleixner (gleixner@autronix.de)
*
- * $Id: h1910.c,v 1.5 2004/11/04 12:53:10 gleixner Exp $
+ * $Id: h1910.c,v 1.6 2005/11/07 11:14:30 gleixner Exp $
*
* 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
@@ -54,24 +54,24 @@ static struct mtd_partition partition_info[] = {
#endif
-/*
+/*
* hardware specific access to control-lines
*/
-static void h1910_hwcontrol(struct mtd_info *mtd, int cmd)
+static void h1910_hwcontrol(struct mtd_info *mtd, int cmd)
{
struct nand_chip* this = (struct nand_chip *) (mtd->priv);
-
+
switch(cmd) {
-
- case NAND_CTL_SETCLE:
+
+ case NAND_CTL_SETCLE:
this->IO_ADDR_R |= (1 << 2);
this->IO_ADDR_W |= (1 << 2);
break;
- case NAND_CTL_CLRCLE:
+ case NAND_CTL_CLRCLE:
this->IO_ADDR_R &= ~(1 << 2);
this->IO_ADDR_W &= ~(1 << 2);
break;
-
+
case NAND_CTL_SETALE:
this->IO_ADDR_R |= (1 << 3);
this->IO_ADDR_W |= (1 << 3);
@@ -80,7 +80,7 @@ static void h1910_hwcontrol(struct mtd_info *mtd, int cmd)
this->IO_ADDR_R &= ~(1 << 3);
this->IO_ADDR_W &= ~(1 << 3);
break;
-
+
case NAND_CTL_SETNCE:
break;
case NAND_CTL_CLRNCE:
@@ -108,18 +108,18 @@ static int __init h1910_init (void)
int mtd_parts_nb = 0;
struct mtd_partition *mtd_parts = 0;
void __iomem *nandaddr;
-
+
if (!machine_is_h1900())
return -ENODEV;
-
+
nandaddr = __ioremap(0x08000000, 0x1000, 0, 1);
if (!nandaddr) {
printk("Failed to ioremap nand flash.\n");
return -ENOMEM;
}
-
+
/* Allocate memory for MTD device structure and private data */
- h1910_nand_mtd = kmalloc(sizeof(struct mtd_info) +
+ h1910_nand_mtd = kmalloc(sizeof(struct mtd_info) +
sizeof(struct nand_chip),
GFP_KERNEL);
if (!h1910_nand_mtd) {
@@ -127,22 +127,22 @@ static int __init h1910_init (void)
iounmap ((void *) nandaddr);
return -ENOMEM;
}
-
+
/* Get pointer to private data */
this = (struct nand_chip *) (&h1910_nand_mtd[1]);
-
+
/* Initialize structures */
memset((char *) h1910_nand_mtd, 0, sizeof(struct mtd_info));
memset((char *) this, 0, sizeof(struct nand_chip));
-
+
/* Link the private data with the MTD structure */
h1910_nand_mtd->priv = this;
-
+
/*
* Enable VPEN
*/
GPSR(37) = GPIO_bit(37);
-
+
/* insert callbacks */
this->IO_ADDR_R = nandaddr;
this->IO_ADDR_W = nandaddr;
@@ -152,7 +152,7 @@ static int __init h1910_init (void)
this->chip_delay = 50;
this->eccmode = NAND_ECC_SOFT;
this->options = NAND_NO_AUTOINCR;
-
+
/* Scan to find existence of the device */
if (nand_scan (h1910_nand_mtd, 1)) {
printk(KERN_NOTICE "No NAND device - returning -ENXIO\n");
@@ -160,9 +160,9 @@ static int __init h1910_init (void)
iounmap ((void *) nandaddr);
return -ENXIO;
}
-
+
#ifdef CONFIG_MTD_CMDLINE_PARTS
- mtd_parts_nb = parse_cmdline_partitions(h1910_nand_mtd, &mtd_parts,
+ mtd_parts_nb = parse_cmdline_partitions(h1910_nand_mtd, &mtd_parts,
"h1910-nand");
if (mtd_parts_nb > 0)
part_type = "command line";
@@ -175,11 +175,11 @@ static int __init h1910_init (void)
mtd_parts_nb = NUM_PARTITIONS;
part_type = "static";
}
-
+
/* Register the partitions */
printk(KERN_NOTICE "Using %s partition definition\n", part_type);
add_mtd_partitions(h1910_nand_mtd, mtd_parts, mtd_parts_nb);
-
+
/* Return happy */
return 0;
}
@@ -191,7 +191,7 @@ module_init(h1910_init);
static void __exit h1910_cleanup (void)
{
struct nand_chip *this = (struct nand_chip *) &h1910_nand_mtd[1];
-
+
/* Release resources, unregister device */
nand_release (h1910_nand_mtd);
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index 04e54318bc6a..5d222460b42a 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -5,14 +5,14 @@
* This is the generic MTD driver for NAND flash devices. It should be
* capable of working with almost all NAND chips currently available.
* Basic support for AG-AND chips is provided.
- *
+ *
* Additional technical information is available on
* http://www.linux-mtd.infradead.org/tech/nand.html
- *
+ *
* Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com)
* 2002 Thomas Gleixner (tglx@linutronix.de)
*
- * 02-08-2004 tglx: support for strange chips, which cannot auto increment
+ * 02-08-2004 tglx: support for strange chips, which cannot auto increment
* pages on read / read_oob
*
* 03-17-2004 tglx: Check ready before auto increment check. Simon Bayes
@@ -21,7 +21,7 @@
* Make reads over block boundaries work too
*
* 04-14-2004 tglx: first working version for 2k page size chips
- *
+ *
* 05-19-2004 tglx: Basic support for Renesas AG-AND chips
*
* 09-24-2004 tglx: add support for hardware controllers (e.g. ECC) shared
@@ -30,25 +30,27 @@
*
* 12-05-2004 dmarlin: add workaround for Renesas AG-AND chips "disturb" issue.
* Basically, any block not rewritten may lose data when surrounding blocks
- * are rewritten many times. JFFS2 ensures this doesn't happen for blocks
+ * are rewritten many times. JFFS2 ensures this doesn't happen for blocks
* it uses, but the Bad Block Table(s) may not be rewritten. To ensure they
* do not lose data, force them to be rewritten when some of the surrounding
- * blocks are erased. Rather than tracking a specific nearby block (which
- * could itself go bad), use a page address 'mask' to select several blocks
+ * blocks are erased. Rather than tracking a specific nearby block (which
+ * could itself go bad), use a page address 'mask' to select several blocks
* in the same area, and rewrite the BBT when any of them are erased.
*
- * 01-03-2005 dmarlin: added support for the device recovery command sequence for Renesas
+ * 01-03-2005 dmarlin: added support for the device recovery command sequence for Renesas
* AG-AND chips. If there was a sudden loss of power during an erase operation,
* a "device recovery" operation must be performed when power is restored
* to ensure correct operation.
*
- * 01-20-2005 dmarlin: added support for optional hardware specific callback routine to
+ * 01-20-2005 dmarlin: added support for optional hardware specific callback routine to
* perform extra error status checks on erase and write failures. This required
* adding a wrapper function for nand_read_ecc.
*
+ * 08-20-2005 vwool: suspend/resume added
+ *
* Credits:
- * David Woodhouse for adding multichip support
- *
+ * David Woodhouse for adding multichip support
+ *
* Aleph One Ltd. and Toby Churchill Ltd. for supporting the
* rework for 2K page size chips
*
@@ -59,7 +61,7 @@
* The AG-AND chips have nice features for speed improvement,
* which are not supported yet. Read / program 4 pages in one go.
*
- * $Id: nand_base.c,v 1.147 2005/07/15 07:18:06 gleixner Exp $
+ * $Id: nand_base.c,v 1.150 2005/09/15 13:58:48 vwool Exp $
*
* 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
@@ -103,8 +105,8 @@ static struct nand_oobinfo nand_oob_64 = {
.useecc = MTD_NANDECC_AUTOPLACE,
.eccbytes = 24,
.eccpos = {
- 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, 53, 54, 55,
+ 40, 41, 42, 43, 44, 45, 46, 47,
+ 48, 49, 50, 51, 52, 53, 54, 55,
56, 57, 58, 59, 60, 61, 62, 63},
.oobfree = { {2, 38} }
};
@@ -147,19 +149,19 @@ static void nand_sync (struct mtd_info *mtd);
static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this, int page, u_char *oob_buf,
struct nand_oobinfo *oobsel, int mode);
#ifdef CONFIG_MTD_NAND_VERIFY_WRITE
-static int nand_verify_pages (struct mtd_info *mtd, struct nand_chip *this, int page, int numpages,
+static int nand_verify_pages (struct mtd_info *mtd, struct nand_chip *this, int page, int numpages,
u_char *oob_buf, struct nand_oobinfo *oobsel, int chipnr, int oobmode);
#else
#define nand_verify_pages(...) (0)
#endif
-
-static void nand_get_device (struct nand_chip *this, struct mtd_info *mtd, int new_state);
+
+static int nand_get_device (struct nand_chip *this, struct mtd_info *mtd, int new_state);
/**
* nand_release_device - [GENERIC] release chip
* @mtd: MTD device structure
- *
- * Deselect, release chip lock and wake up anyone waiting on the device
+ *
+ * Deselect, release chip lock and wake up anyone waiting on the device
*/
static void nand_release_device (struct mtd_info *mtd)
{
@@ -213,7 +215,7 @@ static void nand_write_byte(struct mtd_info *mtd, u_char byte)
* nand_read_byte16 - [DEFAULT] read one byte endianess aware from the chip
* @mtd: MTD device structure
*
- * Default read function for 16bit buswith with
+ * Default read function for 16bit buswith with
* endianess conversion
*/
static u_char nand_read_byte16(struct mtd_info *mtd)
@@ -240,7 +242,7 @@ static void nand_write_byte16(struct mtd_info *mtd, u_char byte)
* nand_read_word - [DEFAULT] read one word from the chip
* @mtd: MTD device structure
*
- * Default read function for 16bit buswith without
+ * Default read function for 16bit buswith without
* endianess conversion
*/
static u16 nand_read_word(struct mtd_info *mtd)
@@ -254,7 +256,7 @@ static u16 nand_read_word(struct mtd_info *mtd)
* @mtd: MTD device structure
* @word: data word to write
*
- * Default write function for 16bit buswith without
+ * Default write function for 16bit buswith without
* endianess conversion
*/
static void nand_write_word(struct mtd_info *mtd, u16 word)
@@ -275,7 +277,7 @@ static void nand_select_chip(struct mtd_info *mtd, int chip)
struct nand_chip *this = mtd->priv;
switch(chip) {
case -1:
- this->hwcontrol(mtd, NAND_CTL_CLRNCE);
+ this->hwcontrol(mtd, NAND_CTL_CLRNCE);
break;
case 0:
this->hwcontrol(mtd, NAND_CTL_SETNCE);
@@ -304,7 +306,7 @@ static void nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
}
/**
- * nand_read_buf - [DEFAULT] read chip data into buffer
+ * nand_read_buf - [DEFAULT] read chip data into buffer
* @mtd: MTD device structure
* @buf: buffer to store date
* @len: number of bytes to read
@@ -321,7 +323,7 @@ static void nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)
}
/**
- * nand_verify_buf - [DEFAULT] Verify chip data against buffer
+ * nand_verify_buf - [DEFAULT] Verify chip data against buffer
* @mtd: MTD device structure
* @buf: buffer containing the data to compare
* @len: number of bytes to compare
@@ -354,14 +356,14 @@ static void nand_write_buf16(struct mtd_info *mtd, const u_char *buf, int len)
struct nand_chip *this = mtd->priv;
u16 *p = (u16 *) buf;
len >>= 1;
-
+
for (i=0; i<len; i++)
writew(p[i], this->IO_ADDR_W);
-
+
}
/**
- * nand_read_buf16 - [DEFAULT] read chip data into buffer
+ * nand_read_buf16 - [DEFAULT] read chip data into buffer
* @mtd: MTD device structure
* @buf: buffer to store date
* @len: number of bytes to read
@@ -380,7 +382,7 @@ static void nand_read_buf16(struct mtd_info *mtd, u_char *buf, int len)
}
/**
- * nand_verify_buf16 - [DEFAULT] Verify chip data against buffer
+ * nand_verify_buf16 - [DEFAULT] Verify chip data against buffer
* @mtd: MTD device structure
* @buf: buffer containing the data to compare
* @len: number of bytes to compare
@@ -407,7 +409,7 @@ static int nand_verify_buf16(struct mtd_info *mtd, const u_char *buf, int len)
* @ofs: offset from device start
* @getchip: 0, if the chip is already selected
*
- * Check, if the block is bad.
+ * Check, if the block is bad.
*/
static int nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip)
{
@@ -424,14 +426,14 @@ static int nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip)
/* Select the NAND device */
this->select_chip(mtd, chipnr);
- } else
- page = (int) ofs;
+ } else
+ page = (int) ofs;
if (this->options & NAND_BUSWIDTH_16) {
this->cmdfunc (mtd, NAND_CMD_READOOB, this->badblockpos & 0xFE, page & this->pagemask);
bad = cpu_to_le16(this->read_word(mtd));
if (this->badblockpos & 0x1)
- bad >>= 1;
+ bad >>= 8;
if ((bad & 0xFF) != 0xff)
res = 1;
} else {
@@ -439,12 +441,12 @@ static int nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip)
if (this->read_byte(mtd) != 0xff)
res = 1;
}
-
+
if (getchip) {
/* Deselect and wake up anyone waiting on the device */
nand_release_device(mtd);
- }
-
+ }
+
return res;
}
@@ -462,7 +464,7 @@ static int nand_default_block_markbad(struct mtd_info *mtd, loff_t ofs)
u_char buf[2] = {0, 0};
size_t retlen;
int block;
-
+
/* Get block number */
block = ((int) ofs) >> this->bbt_erase_shift;
if (this->bbt)
@@ -471,25 +473,25 @@ static int nand_default_block_markbad(struct mtd_info *mtd, loff_t ofs)
/* Do we have a flash based bad block table ? */
if (this->options & NAND_USE_FLASH_BBT)
return nand_update_bbt (mtd, ofs);
-
+
/* We write two bytes, so we dont have to mess with 16 bit access */
ofs += mtd->oobsize + (this->badblockpos & ~0x01);
return nand_write_oob (mtd, ofs , 2, &retlen, buf);
}
-/**
+/**
* nand_check_wp - [GENERIC] check if the chip is write protected
* @mtd: MTD device structure
- * Check, if the device is write protected
+ * Check, if the device is write protected
*
- * The function expects, that the device is already selected
+ * The function expects, that the device is already selected
*/
static int nand_check_wp (struct mtd_info *mtd)
{
struct nand_chip *this = mtd->priv;
/* Check the WP bit */
this->cmdfunc (mtd, NAND_CMD_STATUS, -1, -1);
- return (this->read_byte(mtd) & NAND_STATUS_WP) ? 0 : 1;
+ return (this->read_byte(mtd) & NAND_STATUS_WP) ? 0 : 1;
}
/**
@@ -505,15 +507,15 @@ static int nand_check_wp (struct mtd_info *mtd)
static int nand_block_checkbad (struct mtd_info *mtd, loff_t ofs, int getchip, int allowbbt)
{
struct nand_chip *this = mtd->priv;
-
+
if (!this->bbt)
return this->block_bad(mtd, ofs, getchip);
-
+
/* Return info from the table */
return nand_isbad_bbt (mtd, ofs, allowbbt);
}
-/*
+/*
* Wait for the ready pin, after a command
* The timeout is catched later.
*/
@@ -527,7 +529,7 @@ static void nand_wait_ready(struct mtd_info *mtd)
if (this->dev_ready(mtd))
return;
touch_softlockup_watchdog();
- } while (time_before(jiffies, timeo));
+ } while (time_before(jiffies, timeo));
}
/**
@@ -590,13 +592,13 @@ static void nand_command (struct mtd_info *mtd, unsigned command, int column, in
/* Latch in address */
this->hwcontrol(mtd, NAND_CTL_CLRALE);
}
-
- /*
- * program and erase have their own busy handlers
+
+ /*
+ * program and erase have their own busy handlers
* status and sequential in needs no delay
*/
switch (command) {
-
+
case NAND_CMD_PAGEPROG:
case NAND_CMD_ERASE1:
case NAND_CMD_ERASE2:
@@ -605,7 +607,7 @@ static void nand_command (struct mtd_info *mtd, unsigned command, int column, in
return;
case NAND_CMD_RESET:
- if (this->dev_ready)
+ if (this->dev_ready)
break;
udelay(this->chip_delay);
this->hwcontrol(mtd, NAND_CTL_SETCLE);
@@ -614,16 +616,16 @@ static void nand_command (struct mtd_info *mtd, unsigned command, int column, in
while ( !(this->read_byte(mtd) & NAND_STATUS_READY));
return;
- /* This applies to read commands */
+ /* This applies to read commands */
default:
- /*
+ /*
* If we don't have access to the busy pin, we apply the given
* command delay
*/
if (!this->dev_ready) {
udelay (this->chip_delay);
return;
- }
+ }
}
/* Apply this short delay always to ensure that we do wait tWB in
* any case on any machine. */
@@ -653,8 +655,8 @@ static void nand_command_lp (struct mtd_info *mtd, unsigned command, int column,
column += mtd->oobblock;
command = NAND_CMD_READ0;
}
-
-
+
+
/* Begin command latch cycle */
this->hwcontrol(mtd, NAND_CTL_SETCLE);
/* Write out the command to the device. */
@@ -672,7 +674,7 @@ static void nand_command_lp (struct mtd_info *mtd, unsigned command, int column,
column >>= 1;
this->write_byte(mtd, column & 0xff);
this->write_byte(mtd, column >> 8);
- }
+ }
if (page_addr != -1) {
this->write_byte(mtd, (unsigned char) (page_addr & 0xff));
this->write_byte(mtd, (unsigned char) ((page_addr >> 8) & 0xff));
@@ -683,13 +685,13 @@ static void nand_command_lp (struct mtd_info *mtd, unsigned command, int column,
/* Latch in address */
this->hwcontrol(mtd, NAND_CTL_CLRALE);
}
-
- /*
- * program and erase have their own busy handlers
+
+ /*
+ * program and erase have their own busy handlers
* status, sequential in, and deplete1 need no delay
*/
switch (command) {
-
+
case NAND_CMD_CACHEDPROG:
case NAND_CMD_PAGEPROG:
case NAND_CMD_ERASE1:
@@ -699,7 +701,7 @@ static void nand_command_lp (struct mtd_info *mtd, unsigned command, int column,
case NAND_CMD_DEPLETE1:
return;
- /*
+ /*
* read error status commands require only a short delay
*/
case NAND_CMD_STATUS_ERROR:
@@ -711,7 +713,7 @@ static void nand_command_lp (struct mtd_info *mtd, unsigned command, int column,
return;
case NAND_CMD_RESET:
- if (this->dev_ready)
+ if (this->dev_ready)
break;
udelay(this->chip_delay);
this->hwcontrol(mtd, NAND_CTL_SETCLE);
@@ -728,17 +730,17 @@ static void nand_command_lp (struct mtd_info *mtd, unsigned command, int column,
/* End command latch cycle */
this->hwcontrol(mtd, NAND_CTL_CLRCLE);
/* Fall through into ready check */
-
- /* This applies to read commands */
+
+ /* This applies to read commands */
default:
- /*
+ /*
* If we don't have access to the busy pin, we apply the given
* command delay
*/
if (!this->dev_ready) {
udelay (this->chip_delay);
return;
- }
+ }
}
/* Apply this short delay always to ensure that we do wait tWB in
@@ -752,11 +754,11 @@ static void nand_command_lp (struct mtd_info *mtd, unsigned command, int column,
* nand_get_device - [GENERIC] Get chip for selected access
* @this: the nand chip descriptor
* @mtd: MTD device structure
- * @new_state: the state which is requested
+ * @new_state: the state which is requested
*
* Get the device and lock it for exclusive access
*/
-static void nand_get_device (struct nand_chip *this, struct mtd_info *mtd, int new_state)
+static int nand_get_device (struct nand_chip *this, struct mtd_info *mtd, int new_state)
{
struct nand_chip *active;
spinlock_t *lock;
@@ -779,7 +781,11 @@ retry:
if (active == this && this->state == FL_READY) {
this->state = new_state;
spin_unlock(lock);
- return;
+ return 0;
+ }
+ if (new_state == FL_PM_SUSPENDED) {
+ spin_unlock(lock);
+ return (this->state == FL_PM_SUSPENDED) ? 0 : -EAGAIN;
}
set_current_state(TASK_UNINTERRUPTIBLE);
add_wait_queue(wq, &wait);
@@ -796,7 +802,7 @@ retry:
* @state: state to select the max. timeout value
*
* Wait for command done. This applies to erase and program only
- * Erase can take up to 400ms and program up to 20ms according to
+ * Erase can take up to 400ms and program up to 20ms according to
* general NAND and SmartMedia specs
*
*/
@@ -805,7 +811,7 @@ static int nand_wait(struct mtd_info *mtd, struct nand_chip *this, int state)
unsigned long timeo = jiffies;
int status;
-
+
if (state == FL_ERASING)
timeo += (HZ * 400) / 1000;
else
@@ -817,17 +823,17 @@ static int nand_wait(struct mtd_info *mtd, struct nand_chip *this, int state)
if ((state == FL_ERASING) && (this->options & NAND_IS_AND))
this->cmdfunc (mtd, NAND_CMD_STATUS_MULTI, -1, -1);
- else
+ else
this->cmdfunc (mtd, NAND_CMD_STATUS, -1, -1);
- while (time_before(jiffies, timeo)) {
+ while (time_before(jiffies, timeo)) {
/* Check, if we were interrupted */
if (this->state != state)
return 0;
if (this->dev_ready) {
if (this->dev_ready(mtd))
- break;
+ break;
} else {
if (this->read_byte(mtd) & NAND_STATUS_READY)
break;
@@ -853,7 +859,7 @@ static int nand_wait(struct mtd_info *mtd, struct nand_chip *this, int state)
*
* Cached programming is not supported yet.
*/
-static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this, int page,
+static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this, int page,
u_char *oob_buf, struct nand_oobinfo *oobsel, int cached)
{
int i, status;
@@ -862,10 +868,10 @@ static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this, int pa
int *oob_config = oobsel->eccpos;
int datidx = 0, eccidx = 0, eccsteps = this->eccsteps;
int eccbytes = 0;
-
+
/* FIXME: Enable cached programming */
cached = 0;
-
+
/* Send command to begin auto page programming */
this->cmdfunc (mtd, NAND_CMD_SEQIN, 0x00, page);
@@ -876,7 +882,7 @@ static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this, int pa
printk (KERN_WARNING "Writing data without ECC to NAND-FLASH is not recommended\n");
this->write_buf(mtd, this->data_poi, mtd->oobblock);
break;
-
+
/* Software ecc 3/256, write all */
case NAND_ECC_SOFT:
for (; eccsteps; eccsteps--) {
@@ -905,11 +911,11 @@ static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this, int pa
}
break;
}
-
+
/* Write out OOB data */
if (this->options & NAND_HWECC_SYNDROME)
this->write_buf(mtd, &oob_buf[oobsel->eccbytes], mtd->oobsize - oobsel->eccbytes);
- else
+ else
this->write_buf(mtd, oob_buf, mtd->oobsize);
/* Send command to actually program the data */
@@ -934,7 +940,7 @@ static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this, int pa
/* wait until cache is ready*/
// status = this->waitfunc (mtd, this, FL_CACHEDRPG);
}
- return 0;
+ return 0;
}
#ifdef CONFIG_MTD_NAND_VERIFY_WRITE
@@ -950,19 +956,19 @@ static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this, int pa
* @oobmode: 1 = full buffer verify, 0 = ecc only
*
* The NAND device assumes that it is always writing to a cleanly erased page.
- * Hence, it performs its internal write verification only on bits that
+ * Hence, it performs its internal write verification only on bits that
* transitioned from 1 to 0. The device does NOT verify the whole page on a
- * byte by byte basis. It is possible that the page was not completely erased
- * or the page is becoming unusable due to wear. The read with ECC would catch
- * the error later when the ECC page check fails, but we would rather catch
+ * byte by byte basis. It is possible that the page was not completely erased
+ * or the page is becoming unusable due to wear. The read with ECC would catch
+ * the error later when the ECC page check fails, but we would rather catch
* it early in the page write stage. Better to write no data than invalid data.
*/
-static int nand_verify_pages (struct mtd_info *mtd, struct nand_chip *this, int page, int numpages,
+static int nand_verify_pages (struct mtd_info *mtd, struct nand_chip *this, int page, int numpages,
u_char *oob_buf, struct nand_oobinfo *oobsel, int chipnr, int oobmode)
{
int i, j, datidx = 0, oobofs = 0, res = -EIO;
int eccsteps = this->eccsteps;
- int hweccbytes;
+ int hweccbytes;
u_char oobdata[64];
hweccbytes = (this->options & NAND_HWECC_SYNDROME) ? (oobsel->eccbytes / eccsteps) : 0;
@@ -1002,7 +1008,7 @@ static int nand_verify_pages (struct mtd_info *mtd, struct nand_chip *this, int
if (oobsel->useecc != MTD_NANDECC_OFF && !hweccbytes) {
int ecccnt = oobsel->eccbytes;
-
+
for (i = 0; i < ecccnt; i++) {
int idx = oobsel->eccpos[i];
if (oobdata[idx] != oob_buf[oobofs + idx] ) {
@@ -1012,20 +1018,20 @@ static int nand_verify_pages (struct mtd_info *mtd, struct nand_chip *this, int
goto out;
}
}
- }
+ }
}
oobofs += mtd->oobsize - hweccbytes * eccsteps;
page++;
numpages--;
- /* Apply delay or wait for ready/busy pin
+ /* Apply delay or wait for ready/busy pin
* Do this before the AUTOINCR check, so no problems
* arise if a chip which does auto increment
* is marked as NOAUTOINCR by the board driver.
* Do this also before returning, so the chip is
* ready for the next command.
*/
- if (!this->dev_ready)
+ if (!this->dev_ready)
udelay (this->chip_delay);
else
nand_wait_ready(mtd);
@@ -1033,17 +1039,17 @@ static int nand_verify_pages (struct mtd_info *mtd, struct nand_chip *this, int
/* All done, return happy */
if (!numpages)
return 0;
-
-
- /* Check, if the chip supports auto page increment */
+
+
+ /* Check, if the chip supports auto page increment */
if (!NAND_CANAUTOINCR(this))
this->cmdfunc (mtd, NAND_CMD_READ0, 0x00, page);
}
- /*
+ /*
* Terminate the read command. We come here in case of an error
* So we must issue a reset command.
*/
-out:
+out:
this->cmdfunc (mtd, NAND_CMD_RESET, -1, -1);
return res;
}
@@ -1105,7 +1111,7 @@ static int nand_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
* NAND read with ECC
*/
int nand_do_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
- size_t * retlen, u_char * buf, u_char * oob_buf,
+ size_t * retlen, u_char * buf, u_char * oob_buf,
struct nand_oobinfo *oobsel, int flags)
{
@@ -1139,7 +1145,7 @@ int nand_do_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
/* Autoplace of oob data ? Use the default placement scheme */
if (oobsel->useecc == MTD_NANDECC_AUTOPLACE)
oobsel = this->autooob;
-
+
eccmode = oobsel->useecc ? this->eccmode : NAND_ECC_NONE;
oob_config = oobsel->eccpos;
@@ -1157,28 +1163,28 @@ int nand_do_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
end = mtd->oobblock;
ecc = this->eccsize;
eccbytes = this->eccbytes;
-
+
if ((eccmode == NAND_ECC_NONE) || (this->options & NAND_HWECC_SYNDROME))
compareecc = 0;
oobreadlen = mtd->oobsize;
- if (this->options & NAND_HWECC_SYNDROME)
+ if (this->options & NAND_HWECC_SYNDROME)
oobreadlen -= oobsel->eccbytes;
/* Loop until all data read */
while (read < len) {
-
+
int aligned = (!col && (len - read) >= end);
- /*
+ /*
* If the read is not page aligned, we have to read into data buffer
* due to ecc, else we read into return buffer direct
*/
if (aligned)
data_poi = &buf[read];
- else
+ else
data_poi = this->data_buf;
-
- /* Check, if we have this page in the buffer
+
+ /* Check, if we have this page in the buffer
*
* FIXME: Make it work when we must provide oob data too,
* check the usage of data_buf oob field
@@ -1194,7 +1200,7 @@ int nand_do_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
if (sndcmd) {
this->cmdfunc (mtd, NAND_CMD_READ0, 0x00, page);
sndcmd = 0;
- }
+ }
/* get oob area, if we have no oob buffer from fs-driver */
if (!oob_buf || oobsel->useecc == MTD_NANDECC_AUTOPLACE ||
@@ -1202,7 +1208,7 @@ int nand_do_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
oob_data = &this->data_buf[end];
eccsteps = this->eccsteps;
-
+
switch (eccmode) {
case NAND_ECC_NONE: { /* No ECC, Read in a page */
static unsigned long lastwhinge = 0;
@@ -1213,12 +1219,12 @@ int nand_do_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
this->read_buf(mtd, data_poi, end);
break;
}
-
+
case NAND_ECC_SOFT: /* Software ECC 3/256: Read in a page + oob data */
this->read_buf(mtd, data_poi, end);
- for (i = 0, datidx = 0; eccsteps; eccsteps--, i+=3, datidx += ecc)
+ for (i = 0, datidx = 0; eccsteps; eccsteps--, i+=3, datidx += ecc)
this->calculate_ecc(mtd, &data_poi[datidx], &ecc_calc[i]);
- break;
+ break;
default:
for (i = 0, datidx = 0; eccsteps; eccsteps--, i+=eccbytes, datidx += ecc) {
@@ -1237,15 +1243,15 @@ int nand_do_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
* does the error correction on the fly */
ecc_status = this->correct_data(mtd, &data_poi[datidx], &oob_data[i], &ecc_code[i]);
if ((ecc_status == -1) || (ecc_status > (flags && 0xff))) {
- DEBUG (MTD_DEBUG_LEVEL0, "nand_read_ecc: "
+ DEBUG (MTD_DEBUG_LEVEL0, "nand_read_ecc: "
"Failed ECC read, page 0x%08x on chip %d\n", page, chipnr);
ecc_failed++;
}
} else {
this->calculate_ecc(mtd, &data_poi[datidx], &ecc_calc[i]);
- }
+ }
}
- break;
+ break;
}
/* read oobdata */
@@ -1253,8 +1259,8 @@ int nand_do_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
/* Skip ECC check, if not requested (ECC_NONE or HW_ECC with syndromes) */
if (!compareecc)
- goto readoob;
-
+ goto readoob;
+
/* Pick the ECC bytes out of the oob data */
for (j = 0; j < oobsel->eccbytes; j++)
ecc_code[j] = oob_data[oob_config[j]];
@@ -1262,24 +1268,24 @@ int nand_do_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
/* correct data, if neccecary */
for (i = 0, j = 0, datidx = 0; i < this->eccsteps; i++, datidx += ecc) {
ecc_status = this->correct_data(mtd, &data_poi[datidx], &ecc_code[j], &ecc_calc[j]);
-
+
/* Get next chunk of ecc bytes */
j += eccbytes;
-
- /* Check, if we have a fs supplied oob-buffer,
+
+ /* Check, if we have a fs supplied oob-buffer,
* This is the legacy mode. Used by YAFFS1
* Should go away some day
*/
- if (oob_buf && oobsel->useecc == MTD_NANDECC_PLACE) {
+ if (oob_buf && oobsel->useecc == MTD_NANDECC_PLACE) {
int *p = (int *)(&oob_data[mtd->oobsize]);
p[i] = ecc_status;
}
-
- if ((ecc_status == -1) || (ecc_status > (flags && 0xff))) {
+
+ if ((ecc_status == -1) || (ecc_status > (flags && 0xff))) {
DEBUG (MTD_DEBUG_LEVEL0, "nand_read_ecc: " "Failed ECC read, page 0x%08x\n", page);
ecc_failed++;
}
- }
+ }
readoob:
/* check, if we have a fs supplied oob-buffer */
@@ -1305,25 +1311,25 @@ int nand_do_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
}
readdata:
/* Partial page read, transfer data into fs buffer */
- if (!aligned) {
+ if (!aligned) {
for (j = col; j < end && read < len; j++)
buf[read++] = data_poi[j];
- this->pagebuf = realpage;
- } else
+ this->pagebuf = realpage;
+ } else
read += mtd->oobblock;
- /* Apply delay or wait for ready/busy pin
+ /* Apply delay or wait for ready/busy pin
* Do this before the AUTOINCR check, so no problems
* arise if a chip which does auto increment
* is marked as NOAUTOINCR by the board driver.
*/
- if (!this->dev_ready)
+ if (!this->dev_ready)
udelay (this->chip_delay);
else
nand_wait_ready(mtd);
-
+
if (read == len)
- break;
+ break;
/* For subsequent reads align to page boundary. */
col = 0;
@@ -1337,11 +1343,11 @@ int nand_do_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
this->select_chip(mtd, -1);
this->select_chip(mtd, chipnr);
}
- /* Check, if the chip supports auto page increment
- * or if we have hit a block boundary.
- */
+ /* Check, if the chip supports auto page increment
+ * or if we have hit a block boundary.
+ */
if (!NAND_CANAUTOINCR(this) || !(page & blockcheck))
- sndcmd = 1;
+ sndcmd = 1;
}
/* Deselect and wake up anyone waiting on the device */
@@ -1378,7 +1384,7 @@ static int nand_read_oob (struct mtd_info *mtd, loff_t from, size_t len, size_t
/* Shift to get page */
page = (int)(from >> this->page_shift);
chipnr = (int)(from >> this->chip_shift);
-
+
/* Mask to get column */
col = from & (mtd->oobsize - 1);
@@ -1400,7 +1406,7 @@ static int nand_read_oob (struct mtd_info *mtd, loff_t from, size_t len, size_t
/* Send the read command */
this->cmdfunc (mtd, NAND_CMD_READOOB, col, page & this->pagemask);
- /*
+ /*
* Read the data, if we read more than one page
* oob data, let the device transfer the data !
*/
@@ -1422,20 +1428,20 @@ static int nand_read_oob (struct mtd_info *mtd, loff_t from, size_t len, size_t
this->select_chip(mtd, -1);
this->select_chip(mtd, chipnr);
}
-
- /* Apply delay or wait for ready/busy pin
+
+ /* Apply delay or wait for ready/busy pin
* Do this before the AUTOINCR check, so no problems
* arise if a chip which does auto increment
* is marked as NOAUTOINCR by the board driver.
*/
- if (!this->dev_ready)
+ if (!this->dev_ready)
udelay (this->chip_delay);
else
nand_wait_ready(mtd);
- /* Check, if the chip supports auto page increment
- * or if we have hit a block boundary.
- */
+ /* Check, if the chip supports auto page increment
+ * or if we have hit a block boundary.
+ */
if (!NAND_CANAUTOINCR(this) || !(page & blockcheck)) {
/* For subsequent page reads set offset to 0 */
this->cmdfunc (mtd, NAND_CMD_READOOB, 0x0, page & this->pagemask);
@@ -1481,27 +1487,27 @@ int nand_read_raw (struct mtd_info *mtd, uint8_t *buf, loff_t from, size_t len,
nand_get_device (this, mtd , FL_READING);
this->select_chip (mtd, chip);
-
+
/* Add requested oob length */
len += ooblen;
-
+
while (len) {
if (sndcmd)
this->cmdfunc (mtd, NAND_CMD_READ0, 0, page & this->pagemask);
- sndcmd = 0;
+ sndcmd = 0;
this->read_buf (mtd, &buf[cnt], pagesize);
len -= pagesize;
cnt += pagesize;
page++;
-
- if (!this->dev_ready)
+
+ if (!this->dev_ready)
udelay (this->chip_delay);
else
nand_wait_ready(mtd);
-
- /* Check, if the chip supports auto page increment */
+
+ /* Check, if the chip supports auto page increment */
if (!NAND_CANAUTOINCR(this) || !(page & blockcheck))
sndcmd = 1;
}
@@ -1512,8 +1518,8 @@ int nand_read_raw (struct mtd_info *mtd, uint8_t *buf, loff_t from, size_t len,
}
-/**
- * nand_prepare_oobbuf - [GENERIC] Prepare the out of band buffer
+/**
+ * nand_prepare_oobbuf - [GENERIC] Prepare the out of band buffer
* @mtd: MTD device structure
* @fsbuf: buffer given by fs driver
* @oobsel: out of band selection structre
@@ -1542,20 +1548,20 @@ static u_char * nand_prepare_oobbuf (struct mtd_info *mtd, u_char *fsbuf, struct
int i, len, ofs;
/* Zero copy fs supplied buffer */
- if (fsbuf && !autoplace)
+ if (fsbuf && !autoplace)
return fsbuf;
/* Check, if the buffer must be filled with ff again */
- if (this->oobdirty) {
- memset (this->oob_buf, 0xff,
+ if (this->oobdirty) {
+ memset (this->oob_buf, 0xff,
mtd->oobsize << (this->phys_erase_shift - this->page_shift));
this->oobdirty = 0;
- }
-
+ }
+
/* If we have no autoplacement or no fs buffer use the internal one */
if (!autoplace || !fsbuf)
return this->oob_buf;
-
+
/* Walk through the pages and place the data */
this->oobdirty = 1;
ofs = 0;
@@ -1589,7 +1595,7 @@ static int nand_write (struct mtd_info *mtd, loff_t to, size_t len, size_t * ret
{
return (nand_write_ecc (mtd, to, len, retlen, buf, NULL, NULL));
}
-
+
/**
* nand_write_ecc - [MTD Interface] NAND write with ECC
* @mtd: MTD device structure
@@ -1622,7 +1628,7 @@ static int nand_write_ecc (struct mtd_info *mtd, loff_t to, size_t len,
return -EINVAL;
}
- /* reject writes, which are not page aligned */
+ /* reject writes, which are not page aligned */
if (NOTALIGNED (to) || NOTALIGNED(len)) {
printk (KERN_NOTICE "nand_write_ecc: Attempt to write not page aligned data\n");
return -EINVAL;
@@ -1641,14 +1647,14 @@ static int nand_write_ecc (struct mtd_info *mtd, loff_t to, size_t len,
goto out;
/* if oobsel is NULL, use chip defaults */
- if (oobsel == NULL)
- oobsel = &mtd->oobinfo;
-
+ if (oobsel == NULL)
+ oobsel = &mtd->oobinfo;
+
/* Autoplace of oob data ? Use the default placement scheme */
if (oobsel->useecc == MTD_NANDECC_AUTOPLACE) {
oobsel = this->autooob;
autoplace = 1;
- }
+ }
if (oobsel->useecc == MTD_NANDECC_AUTOPL_USR)
autoplace = 1;
@@ -1656,9 +1662,9 @@ static int nand_write_ecc (struct mtd_info *mtd, loff_t to, size_t len,
totalpages = len >> this->page_shift;
page = (int) (to >> this->page_shift);
/* Invalidate the page cache, if we write to the cached page */
- if (page <= this->pagebuf && this->pagebuf < (page + totalpages))
+ if (page <= this->pagebuf && this->pagebuf < (page + totalpages))
this->pagebuf = -1;
-
+
/* Set it relative to chip */
page &= this->pagemask;
startpage = page;
@@ -1680,14 +1686,14 @@ static int nand_write_ecc (struct mtd_info *mtd, loff_t to, size_t len,
if (ret) {
DEBUG (MTD_DEBUG_LEVEL0, "nand_write_ecc: write_page failed %d\n", ret);
goto out;
- }
+ }
/* Next oob page */
oob += mtd->oobsize;
/* Update written bytes count */
written += mtd->oobblock;
- if (written == len)
+ if (written == len)
goto cmp;
-
+
/* Increment page address */
page++;
@@ -1698,13 +1704,13 @@ static int nand_write_ecc (struct mtd_info *mtd, loff_t to, size_t len,
if (!(page & (ppblock - 1))){
int ofs;
this->data_poi = bufstart;
- ret = nand_verify_pages (mtd, this, startpage,
+ ret = nand_verify_pages (mtd, this, startpage,
page - startpage,
oobbuf, oobsel, chipnr, (eccbuf != NULL));
if (ret) {
DEBUG (MTD_DEBUG_LEVEL0, "nand_write_ecc: verify_pages failed %d\n", ret);
goto out;
- }
+ }
*retlen = written;
ofs = autoplace ? mtd->oobavail : mtd->oobsize;
@@ -1714,8 +1720,9 @@ static int nand_write_ecc (struct mtd_info *mtd, loff_t to, size_t len,
numpages = min (totalpages, ppblock);
page &= this->pagemask;
startpage = page;
- oobbuf = nand_prepare_oobbuf (mtd, eccbuf, oobsel,
+ oobbuf = nand_prepare_oobbuf (mtd, eccbuf, oobsel,
autoplace, numpages);
+ oob = 0;
/* Check, if we cross a chip boundary */
if (!page) {
chipnr++;
@@ -1731,7 +1738,7 @@ cmp:
oobbuf, oobsel, chipnr, (eccbuf != NULL));
if (!ret)
*retlen = written;
- else
+ else
DEBUG (MTD_DEBUG_LEVEL0, "nand_write_ecc: verify_pages failed %d\n", ret);
out:
@@ -1791,7 +1798,7 @@ static int nand_write_oob (struct mtd_info *mtd, loff_t to, size_t len, size_t *
/* Check, if it is write protected */
if (nand_check_wp(mtd))
goto out;
-
+
/* Invalidate the page cache, if we write to the cached page */
if (page == this->pagebuf)
this->pagebuf = -1;
@@ -1854,10 +1861,10 @@ out:
*
* NAND write with kvec. This just calls the ecc function
*/
-static int nand_writev (struct mtd_info *mtd, const struct kvec *vecs, unsigned long count,
+static int nand_writev (struct mtd_info *mtd, const struct kvec *vecs, unsigned long count,
loff_t to, size_t * retlen)
{
- return (nand_writev_ecc (mtd, vecs, count, to, retlen, NULL, NULL));
+ return (nand_writev_ecc (mtd, vecs, count, to, retlen, NULL, NULL));
}
/**
@@ -1872,7 +1879,7 @@ static int nand_writev (struct mtd_info *mtd, const struct kvec *vecs, unsigned
*
* NAND write with iovec with ecc
*/
-static int nand_writev_ecc (struct mtd_info *mtd, const struct kvec *vecs, unsigned long count,
+static int nand_writev_ecc (struct mtd_info *mtd, const struct kvec *vecs, unsigned long count,
loff_t to, size_t * retlen, u_char *eccbuf, struct nand_oobinfo *oobsel)
{
int i, page, len, total_len, ret = -EIO, written = 0, chipnr;
@@ -1898,7 +1905,7 @@ static int nand_writev_ecc (struct mtd_info *mtd, const struct kvec *vecs, unsig
return -EINVAL;
}
- /* reject writes, which are not page aligned */
+ /* reject writes, which are not page aligned */
if (NOTALIGNED (to) || NOTALIGNED(total_len)) {
printk (KERN_NOTICE "nand_write_ecc: Attempt to write not page aligned data\n");
return -EINVAL;
@@ -1917,21 +1924,21 @@ static int nand_writev_ecc (struct mtd_info *mtd, const struct kvec *vecs, unsig
goto out;
/* if oobsel is NULL, use chip defaults */
- if (oobsel == NULL)
- oobsel = &mtd->oobinfo;
+ if (oobsel == NULL)
+ oobsel = &mtd->oobinfo;
/* Autoplace of oob data ? Use the default placement scheme */
if (oobsel->useecc == MTD_NANDECC_AUTOPLACE) {
oobsel = this->autooob;
autoplace = 1;
- }
+ }
if (oobsel->useecc == MTD_NANDECC_AUTOPL_USR)
autoplace = 1;
/* Setup start page */
page = (int) (to >> this->page_shift);
/* Invalidate the page cache, if we write to the cached page */
- if (page <= this->pagebuf && this->pagebuf < ((to + total_len) >> this->page_shift))
+ if (page <= this->pagebuf && this->pagebuf < ((to + total_len) >> this->page_shift))
this->pagebuf = -1;
startpage = page & this->pagemask;
@@ -1955,10 +1962,10 @@ static int nand_writev_ecc (struct mtd_info *mtd, const struct kvec *vecs, unsig
oob = 0;
for (i = 1; i <= numpages; i++) {
/* Write one page. If this is the last page to write
- * then use the real pageprogram command, else select
+ * then use the real pageprogram command, else select
* cached programming if supported by the chip.
*/
- ret = nand_write_page (mtd, this, page & this->pagemask,
+ ret = nand_write_page (mtd, this, page & this->pagemask,
&oobbuf[oob], oobsel, i != numpages);
if (ret)
goto out;
@@ -1974,12 +1981,12 @@ static int nand_writev_ecc (struct mtd_info *mtd, const struct kvec *vecs, unsig
count--;
}
} else {
- /* We must use the internal buffer, read data out of each
+ /* We must use the internal buffer, read data out of each
* tuple until we have a full page to write
*/
int cnt = 0;
while (cnt < mtd->oobblock) {
- if (vecs->iov_base != NULL && vecs->iov_len)
+ if (vecs->iov_base != NULL && vecs->iov_len)
this->data_buf[cnt++] = ((u_char *) vecs->iov_base)[len++];
/* Check, if we have to switch to the next tuple */
if (len >= (int) vecs->iov_len) {
@@ -1988,10 +1995,10 @@ static int nand_writev_ecc (struct mtd_info *mtd, const struct kvec *vecs, unsig
count--;
}
}
- this->pagebuf = page;
- this->data_poi = this->data_buf;
+ this->pagebuf = page;
+ this->data_poi = this->data_buf;
bufstart = this->data_poi;
- numpages = 1;
+ numpages = 1;
oobbuf = nand_prepare_oobbuf (mtd, NULL, oobsel, autoplace, numpages);
ret = nand_write_page (mtd, this, page & this->pagemask,
oobbuf, oobsel, 0);
@@ -2004,7 +2011,7 @@ static int nand_writev_ecc (struct mtd_info *mtd, const struct kvec *vecs, unsig
ret = nand_verify_pages (mtd, this, startpage, numpages, oobbuf, oobsel, chipnr, 0);
if (ret)
goto out;
-
+
written += mtd->oobblock * numpages;
/* All done ? */
if (!count)
@@ -2072,7 +2079,7 @@ static int nand_erase (struct mtd_info *mtd, struct erase_info *instr)
{
return nand_erase_nand (mtd, instr, 0);
}
-
+
#define BBT_PAGE_MASK 0xffffff3f
/**
* nand_erase_intern - [NAND Interface] erase block(s)
@@ -2154,14 +2161,14 @@ int nand_erase_nand (struct mtd_info *mtd, struct erase_info *instr, int allowbb
instr->state = MTD_ERASE_FAILED;
goto erase_exit;
}
-
- /* Invalidate the page cache, if we erase the block which contains
+
+ /* Invalidate the page cache, if we erase the block which contains
the current cached page */
if (page <= this->pagebuf && this->pagebuf < (page + pages_per_block))
this->pagebuf = -1;
this->erase_cmd (mtd, page & this->pagemask);
-
+
status = this->waitfunc (mtd, this, FL_ERASING);
/* See if operation failed and additional status checks are available */
@@ -2179,12 +2186,12 @@ int nand_erase_nand (struct mtd_info *mtd, struct erase_info *instr, int allowbb
/* if BBT requires refresh, set the BBT rewrite flag to the page being erased */
if (this->options & BBT_AUTO_REFRESH) {
- if (((page & BBT_PAGE_MASK) == bbt_masked_page) &&
+ if (((page & BBT_PAGE_MASK) == bbt_masked_page) &&
(page != this->bbt_td->pages[chipnr])) {
rewrite_bbt[chipnr] = (page << this->page_shift);
}
}
-
+
/* Increment page address and decrement length */
len -= (1 << this->phys_erase_shift);
page += pages_per_block;
@@ -2195,7 +2202,7 @@ int nand_erase_nand (struct mtd_info *mtd, struct erase_info *instr, int allowbb
this->select_chip(mtd, -1);
this->select_chip(mtd, chipnr);
- /* if BBT requires refresh and BBT-PERCHIP,
+ /* if BBT requires refresh and BBT-PERCHIP,
* set the BBT page mask to see if this BBT should be rewritten */
if ((this->options & BBT_AUTO_REFRESH) && (this->bbt_td->options & NAND_BBT_PERCHIP)) {
bbt_masked_page = this->bbt_td->pages[chipnr] & BBT_PAGE_MASK;
@@ -2220,7 +2227,7 @@ erase_exit:
for (chipnr = 0; chipnr < this->numchips; chipnr++) {
if (rewrite_bbt[chipnr]) {
/* update the BBT for chip */
- DEBUG (MTD_DEBUG_LEVEL0, "nand_erase_nand: nand_update_bbt (%d:0x%0x 0x%0x)\n",
+ DEBUG (MTD_DEBUG_LEVEL0, "nand_erase_nand: nand_update_bbt (%d:0x%0x 0x%0x)\n",
chipnr, rewrite_bbt[chipnr], this->bbt_td->pages[chipnr]);
nand_update_bbt (mtd, rewrite_bbt[chipnr]);
}
@@ -2258,9 +2265,9 @@ static void nand_sync (struct mtd_info *mtd)
static int nand_block_isbad (struct mtd_info *mtd, loff_t ofs)
{
/* Check for invalid offset */
- if (ofs > mtd->size)
+ if (ofs > mtd->size)
return -EINVAL;
-
+
return nand_block_checkbad (mtd, ofs, 1, 0);
}
@@ -2285,6 +2292,34 @@ static int nand_block_markbad (struct mtd_info *mtd, loff_t ofs)
}
/**
+ * nand_suspend - [MTD Interface] Suspend the NAND flash
+ * @mtd: MTD device structure
+ */
+static int nand_suspend(struct mtd_info *mtd)
+{
+ struct nand_chip *this = mtd->priv;
+
+ return nand_get_device (this, mtd, FL_PM_SUSPENDED);
+}
+
+/**
+ * nand_resume - [MTD Interface] Resume the NAND flash
+ * @mtd: MTD device structure
+ */
+static void nand_resume(struct mtd_info *mtd)
+{
+ struct nand_chip *this = mtd->priv;
+
+ if (this->state == FL_PM_SUSPENDED)
+ nand_release_device(mtd);
+ else
+ printk(KERN_ERR "resume() called for the chip which is not "
+ "in suspended state\n");
+
+}
+
+
+/**
* nand_scan - [NAND Interface] Scan for the NAND device
* @mtd: MTD device structure
* @maxchips: Number of chips to scan for
@@ -2351,13 +2386,13 @@ int nand_scan (struct mtd_info *mtd, int maxchips)
/* Print and store flash device information */
for (i = 0; nand_flash_ids[i].name != NULL; i++) {
-
- if (nand_dev_id != nand_flash_ids[i].id)
+
+ if (nand_dev_id != nand_flash_ids[i].id)
continue;
if (!mtd->name) mtd->name = nand_flash_ids[i].name;
this->chipsize = nand_flash_ids[i].chipsize << 20;
-
+
/* New devices have all the information in additional id bytes */
if (!nand_flash_ids[i].pagesize) {
int extid;
@@ -2369,14 +2404,14 @@ int nand_scan (struct mtd_info *mtd, int maxchips)
mtd->oobblock = 1024 << (extid & 0x3);
extid >>= 2;
/* Calc oobsize */
- mtd->oobsize = (8 << (extid & 0x03)) * (mtd->oobblock / 512);
+ mtd->oobsize = (8 << (extid & 0x01)) * (mtd->oobblock >> 9);
extid >>= 2;
/* Calc blocksize. Blocksize is multiples of 64KiB */
mtd->erasesize = (64 * 1024) << (extid & 0x03);
extid >>= 2;
/* Get buswidth information */
busw = (extid & 0x01) ? NAND_BUSWIDTH_16 : 0;
-
+
} else {
/* Old devices have this data hardcoded in the
* device id table */
@@ -2396,23 +2431,23 @@ int nand_scan (struct mtd_info *mtd, int maxchips)
* this correct ! */
if (busw != (this->options & NAND_BUSWIDTH_16)) {
printk (KERN_INFO "NAND device: Manufacturer ID:"
- " 0x%02x, Chip ID: 0x%02x (%s %s)\n", nand_maf_id, nand_dev_id,
+ " 0x%02x, Chip ID: 0x%02x (%s %s)\n", nand_maf_id, nand_dev_id,
nand_manuf_ids[maf_id].name , mtd->name);
- printk (KERN_WARNING
- "NAND bus width %d instead %d bit\n",
+ printk (KERN_WARNING
+ "NAND bus width %d instead %d bit\n",
(this->options & NAND_BUSWIDTH_16) ? 16 : 8,
busw ? 16 : 8);
this->select_chip(mtd, -1);
- return 1;
+ return 1;
}
-
- /* Calculate the address shift from the page size */
+
+ /* Calculate the address shift from the page size */
this->page_shift = ffs(mtd->oobblock) - 1;
this->bbt_erase_shift = this->phys_erase_shift = ffs(mtd->erasesize) - 1;
this->chip_shift = ffs(this->chipsize) - 1;
/* Set the bad block position */
- this->badblockpos = mtd->oobblock > 512 ?
+ this->badblockpos = mtd->oobblock > 512 ?
NAND_LARGE_BADBLOCK_POS : NAND_SMALL_BADBLOCK_POS;
/* Get chip options, preserve non chip based options */
@@ -2422,10 +2457,10 @@ int nand_scan (struct mtd_info *mtd, int maxchips)
this->options |= NAND_NO_AUTOINCR;
/* Check if this is a not a samsung device. Do not clear the options
* for chips which are not having an extended id.
- */
+ */
if (nand_maf_id != NAND_MFR_SAMSUNG && !nand_flash_ids[i].pagesize)
this->options &= ~NAND_SAMSUNG_LP_OPTIONS;
-
+
/* Check for AND chips with 4 page planes */
if (this->options & NAND_4PAGE_ARRAY)
this->erase_cmd = multi_erase_cmd;
@@ -2435,9 +2470,9 @@ int nand_scan (struct mtd_info *mtd, int maxchips)
/* Do not replace user supplied command function ! */
if (mtd->oobblock > 512 && this->cmdfunc == nand_command)
this->cmdfunc = nand_command_lp;
-
+
printk (KERN_INFO "NAND device: Manufacturer ID:"
- " 0x%02x, Chip ID: 0x%02x (%s %s)\n", nand_maf_id, nand_dev_id,
+ " 0x%02x, Chip ID: 0x%02x (%s %s)\n", nand_maf_id, nand_dev_id,
nand_manuf_ids[maf_id].name , nand_flash_ids[i].name);
break;
}
@@ -2461,7 +2496,7 @@ int nand_scan (struct mtd_info *mtd, int maxchips)
}
if (i > 1)
printk(KERN_INFO "%d NAND chips detected\n", i);
-
+
/* Allocate buffers, if neccecary */
if (!this->oob_buf) {
size_t len;
@@ -2473,7 +2508,7 @@ int nand_scan (struct mtd_info *mtd, int maxchips)
}
this->options |= NAND_OOBBUF_ALLOC;
}
-
+
if (!this->data_buf) {
size_t len;
len = mtd->oobblock + mtd->oobsize;
@@ -2500,7 +2535,7 @@ int nand_scan (struct mtd_info *mtd, int maxchips)
if (!this->autooob) {
/* Select the appropriate default oob placement scheme for
* placement agnostic filesystems */
- switch (mtd->oobsize) {
+ switch (mtd->oobsize) {
case 8:
this->autooob = &nand_oob_8;
break;
@@ -2516,19 +2551,19 @@ int nand_scan (struct mtd_info *mtd, int maxchips)
BUG();
}
}
-
+
/* The number of bytes available for the filesystem to place fs dependend
* oob data */
mtd->oobavail = 0;
for (i = 0; this->autooob->oobfree[i][1]; i++)
mtd->oobavail += this->autooob->oobfree[i][1];
- /*
+ /*
* check ECC mode, default to software
* if 3byte/512byte hardware ECC is selected and we have 256 byte pagesize
- * fallback to software ECC
+ * fallback to software ECC
*/
- this->eccsize = 256; /* set default eccsize */
+ this->eccsize = 256; /* set default eccsize */
this->eccbytes = 3;
switch (this->eccmode) {
@@ -2543,56 +2578,56 @@ int nand_scan (struct mtd_info *mtd, int maxchips)
this->eccsize = 2048;
break;
- case NAND_ECC_HW3_512:
- case NAND_ECC_HW6_512:
- case NAND_ECC_HW8_512:
+ case NAND_ECC_HW3_512:
+ case NAND_ECC_HW6_512:
+ case NAND_ECC_HW8_512:
if (mtd->oobblock == 256) {
printk (KERN_WARNING "512 byte HW ECC not possible on 256 Byte pagesize, fallback to SW ECC \n");
this->eccmode = NAND_ECC_SOFT;
this->calculate_ecc = nand_calculate_ecc;
this->correct_data = nand_correct_data;
- } else
+ } else
this->eccsize = 512; /* set eccsize to 512 */
break;
-
+
case NAND_ECC_HW3_256:
break;
-
- case NAND_ECC_NONE:
+
+ case NAND_ECC_NONE:
printk (KERN_WARNING "NAND_ECC_NONE selected by board driver. This is not recommended !!\n");
this->eccmode = NAND_ECC_NONE;
break;
- case NAND_ECC_SOFT:
+ case NAND_ECC_SOFT:
this->calculate_ecc = nand_calculate_ecc;
this->correct_data = nand_correct_data;
break;
default:
printk (KERN_WARNING "Invalid NAND_ECC_MODE %d\n", this->eccmode);
- BUG();
- }
+ BUG();
+ }
- /* Check hardware ecc function availability and adjust number of ecc bytes per
+ /* Check hardware ecc function availability and adjust number of ecc bytes per
* calculation step
*/
switch (this->eccmode) {
case NAND_ECC_HW12_2048:
this->eccbytes += 4;
- case NAND_ECC_HW8_512:
+ case NAND_ECC_HW8_512:
this->eccbytes += 2;
- case NAND_ECC_HW6_512:
+ case NAND_ECC_HW6_512:
this->eccbytes += 3;
- case NAND_ECC_HW3_512:
+ case NAND_ECC_HW3_512:
case NAND_ECC_HW3_256:
if (this->calculate_ecc && this->correct_data && this->enable_hwecc)
break;
printk (KERN_WARNING "No ECC functions supplied, Hardware ECC not possible\n");
- BUG();
+ BUG();
}
-
+
mtd->eccsize = this->eccsize;
-
+
/* Set the number of read / write steps for one page to ensure ECC generation */
switch (this->eccmode) {
case NAND_ECC_HW12_2048:
@@ -2604,15 +2639,15 @@ int nand_scan (struct mtd_info *mtd, int maxchips)
this->eccsteps = mtd->oobblock / 512;
break;
case NAND_ECC_HW3_256:
- case NAND_ECC_SOFT:
+ case NAND_ECC_SOFT:
this->eccsteps = mtd->oobblock / 256;
break;
-
- case NAND_ECC_NONE:
+
+ case NAND_ECC_NONE:
this->eccsteps = 1;
break;
}
-
+
/* Initialize state, waitqueue and spinlock */
this->state = FL_READY;
init_waitqueue_head (&this->wq);
@@ -2643,8 +2678,8 @@ int nand_scan (struct mtd_info *mtd, int maxchips)
mtd->sync = nand_sync;
mtd->lock = NULL;
mtd->unlock = NULL;
- mtd->suspend = NULL;
- mtd->resume = NULL;
+ mtd->suspend = nand_suspend;
+ mtd->resume = nand_resume;
mtd->block_isbad = nand_block_isbad;
mtd->block_markbad = nand_block_markbad;
@@ -2652,7 +2687,7 @@ int nand_scan (struct mtd_info *mtd, int maxchips)
memcpy(&mtd->oobinfo, this->autooob, sizeof(mtd->oobinfo));
mtd->owner = THIS_MODULE;
-
+
/* Check, if we should skip the bad block table scan */
if (this->options & NAND_SKIP_BBTSCAN)
return 0;
@@ -2662,7 +2697,7 @@ int nand_scan (struct mtd_info *mtd, int maxchips)
}
/**
- * nand_release - [NAND Interface] Free resources held by the NAND device
+ * nand_release - [NAND Interface] Free resources held by the NAND device
* @mtd: MTD device structure
*/
void nand_release (struct mtd_info *mtd)
@@ -2676,9 +2711,8 @@ void nand_release (struct mtd_info *mtd)
/* Deregister the device */
del_mtd_device (mtd);
- /* Free bad block table memory, if allocated */
- if (this->bbt)
- kfree (this->bbt);
+ /* Free bad block table memory */
+ kfree (this->bbt);
/* Buffer allocated by nand_scan ? */
if (this->options & NAND_OOBBUF_ALLOC)
kfree (this->oob_buf);
diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c
index 7535ef53685e..ca286999fe08 100644
--- a/drivers/mtd/nand/nand_bbt.c
+++ b/drivers/mtd/nand/nand_bbt.c
@@ -3,10 +3,10 @@
*
* Overview:
* Bad block table support for the NAND driver
- *
+ *
* Copyright (C) 2004 Thomas Gleixner (tglx@linutronix.de)
*
- * $Id: nand_bbt.c,v 1.35 2005/07/15 13:53:47 gleixner Exp $
+ * $Id: nand_bbt.c,v 1.36 2005/11/07 11:14:30 gleixner Exp $
*
* 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
@@ -14,23 +14,23 @@
*
* Description:
*
- * When nand_scan_bbt is called, then it tries to find the bad block table
- * depending on the options in the bbt descriptor(s). If a bbt is found
- * then the contents are read and the memory based bbt is created. If a
+ * When nand_scan_bbt is called, then it tries to find the bad block table
+ * depending on the options in the bbt descriptor(s). If a bbt is found
+ * then the contents are read and the memory based bbt is created. If a
* mirrored bbt is selected then the mirror is searched too and the
- * versions are compared. If the mirror has a greater version number
+ * versions are compared. If the mirror has a greater version number
* than the mirror bbt is used to build the memory based bbt.
* If the tables are not versioned, then we "or" the bad block information.
- * If one of the bbt's is out of date or does not exist it is (re)created.
- * If no bbt exists at all then the device is scanned for factory marked
- * good / bad blocks and the bad block tables are created.
+ * If one of the bbt's is out of date or does not exist it is (re)created.
+ * If no bbt exists at all then the device is scanned for factory marked
+ * good / bad blocks and the bad block tables are created.
*
- * For manufacturer created bbts like the one found on M-SYS DOC devices
+ * For manufacturer created bbts like the one found on M-SYS DOC devices
* the bbt is searched and read but never created
*
- * The autogenerated bad block table is located in the last good blocks
- * of the device. The table is mirrored, so it can be updated eventually.
- * The table is marked in the oob area with an ident pattern and a version
+ * The autogenerated bad block table is located in the last good blocks
+ * of the device. The table is mirrored, so it can be updated eventually.
+ * The table is marked in the oob area with an ident pattern and a version
* number which indicates which of both tables is more up to date.
*
* The table uses 2 bits per block
@@ -43,13 +43,13 @@
* 01b: block is marked bad due to wear
* 10b: block is reserved (to protect the bbt area)
* 11b: block is factory marked bad
- *
+ *
* Multichip devices like DOC store the bad block info per floor.
*
* Following assumptions are made:
* - bbts start at a page boundary, if autolocated on a block boundary
* - the space neccecary for a bbt in FLASH does not exceed a block boundary
- *
+ *
*/
#include <linux/slab.h>
@@ -62,7 +62,7 @@
#include <linux/delay.h>
-/**
+/**
* check_pattern - [GENERIC] check if a pattern is in the buffer
* @buf: the buffer to search
* @len: the length of buffer to search
@@ -86,9 +86,9 @@ static int check_pattern (uint8_t *buf, int len, int paglen, struct nand_bbt_des
if (p[i] != 0xff)
return -1;
}
- }
+ }
p += end;
-
+
/* Compare the pattern */
for (i = 0; i < td->len; i++) {
if (p[i] != td->pattern[i])
@@ -106,13 +106,13 @@ static int check_pattern (uint8_t *buf, int len, int paglen, struct nand_bbt_des
return 0;
}
-/**
+/**
* check_short_pattern - [GENERIC] check if a pattern is in the buffer
* @buf: the buffer to search
* @td: search pattern descriptor
*
* Check for a pattern at the given place. Used to search bad block
- * tables and good / bad block identifiers. Same as check_pattern, but
+ * tables and good / bad block identifiers. Same as check_pattern, but
* no optional empty check
*
*/
@@ -142,7 +142,7 @@ static int check_short_pattern (uint8_t *buf, struct nand_bbt_descr *td)
* Read the bad block table starting from page.
*
*/
-static int read_bbt (struct mtd_info *mtd, uint8_t *buf, int page, int num,
+static int read_bbt (struct mtd_info *mtd, uint8_t *buf, int page, int num,
int bits, int offs, int reserved_block_code)
{
int res, i, j, act = 0;
@@ -153,7 +153,7 @@ static int read_bbt (struct mtd_info *mtd, uint8_t *buf, int page, int num,
totlen = (num * bits) >> 3;
from = ((loff_t)page) << this->page_shift;
-
+
while (totlen) {
len = min (totlen, (size_t) (1 << this->bbt_erase_shift));
res = mtd->read_ecc (mtd, from, len, &retlen, buf, NULL, this->autooob);
@@ -163,7 +163,7 @@ static int read_bbt (struct mtd_info *mtd, uint8_t *buf, int page, int num,
return res;
}
printk (KERN_WARNING "nand_bbt: ECC error while reading bad block table\n");
- }
+ }
/* Analyse data */
for (i = 0; i < len; i++) {
@@ -183,12 +183,12 @@ static int read_bbt (struct mtd_info *mtd, uint8_t *buf, int page, int num,
* message to MTD_DEBUG_LEVEL0 */
printk (KERN_DEBUG "nand_read_bbt: Bad block at 0x%08x\n",
((offs << 2) + (act >> 1)) << this->bbt_erase_shift);
- /* Factory marked bad or worn out ? */
+ /* Factory marked bad or worn out ? */
if (tmp == 0)
this->bbt[offs + (act >> 3)] |= 0x3 << (act & 0x06);
else
this->bbt[offs + (act >> 3)] |= 0x1 << (act & 0x06);
- }
+ }
}
totlen -= len;
from += len;
@@ -200,7 +200,7 @@ static int read_bbt (struct mtd_info *mtd, uint8_t *buf, int page, int num,
* read_abs_bbt - [GENERIC] Read the bad block table starting at a given page
* @mtd: MTD device structure
* @buf: temporary buffer
- * @td: descriptor for the bad block table
+ * @td: descriptor for the bad block table
* @chip: read the table for a specific chip, -1 read all chips.
* Applies only if NAND_BBT_PERCHIP option is set
*
@@ -235,7 +235,7 @@ static int read_abs_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_des
* read_abs_bbts - [GENERIC] Read the bad block table(s) for all chips starting at a given page
* @mtd: MTD device structure
* @buf: temporary buffer
- * @td: descriptor for the bad block table
+ * @td: descriptor for the bad block table
* @md: descriptor for the bad block table mirror
*
* Read the bad block table(s) for all chips starting at a given page
@@ -247,16 +247,16 @@ static int read_abs_bbts (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_de
{
struct nand_chip *this = mtd->priv;
- /* Read the primary version, if available */
+ /* Read the primary version, if available */
if (td->options & NAND_BBT_VERSION) {
- nand_read_raw (mtd, buf, td->pages[0] << this->page_shift, mtd->oobblock, mtd->oobsize);
+ nand_read_raw (mtd, buf, td->pages[0] << this->page_shift, mtd->oobblock, mtd->oobsize);
td->version[0] = buf[mtd->oobblock + td->veroffs];
printk (KERN_DEBUG "Bad block table at page %d, version 0x%02X\n", td->pages[0], td->version[0]);
}
- /* Read the mirror version, if available */
+ /* Read the mirror version, if available */
if (md && (md->options & NAND_BBT_VERSION)) {
- nand_read_raw (mtd, buf, md->pages[0] << this->page_shift, mtd->oobblock, mtd->oobsize);
+ nand_read_raw (mtd, buf, md->pages[0] << this->page_shift, mtd->oobblock, mtd->oobsize);
md->version[0] = buf[mtd->oobblock + md->veroffs];
printk (KERN_DEBUG "Bad block table at page %d, version 0x%02X\n", md->pages[0], md->version[0]);
}
@@ -290,7 +290,7 @@ static int create_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
else {
if (bd->options & NAND_BBT_SCAN2NDPAGE)
len = 2;
- else
+ else
len = 1;
}
@@ -322,10 +322,10 @@ static int create_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
numblocks += startblock;
from = startblock << (this->bbt_erase_shift - 1);
}
-
+
for (i = startblock; i < numblocks;) {
int ret;
-
+
if (bd->options & NAND_BBT_SCANEMPTY)
if ((ret = nand_read_raw (mtd, buf, from, readlen, ooblen)))
return ret;
@@ -333,8 +333,8 @@ static int create_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
for (j = 0; j < len; j++) {
if (!(bd->options & NAND_BBT_SCANEMPTY)) {
size_t retlen;
-
- /* Read the full oob until read_oob is fixed to
+
+ /* Read the full oob until read_oob is fixed to
* handle single byte reads for 16 bit buswidth */
ret = mtd->read_oob(mtd, from + j * mtd->oobblock,
mtd->oobsize, &retlen, buf);
@@ -343,14 +343,14 @@ static int create_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
if (check_short_pattern (buf, bd)) {
this->bbt[i >> 3] |= 0x03 << (i & 0x6);
- printk (KERN_WARNING "Bad eraseblock %d at 0x%08x\n",
+ printk (KERN_WARNING "Bad eraseblock %d at 0x%08x\n",
i >> 1, (unsigned int) from);
break;
}
} else {
if (check_pattern (&buf[j * scanlen], scanlen, mtd->oobblock, bd)) {
this->bbt[i >> 3] |= 0x03 << (i & 0x6);
- printk (KERN_WARNING "Bad eraseblock %d at 0x%08x\n",
+ printk (KERN_WARNING "Bad eraseblock %d at 0x%08x\n",
i >> 1, (unsigned int) from);
break;
}
@@ -369,15 +369,15 @@ static int create_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
* @td: descriptor for the bad block table
*
* Read the bad block table by searching for a given ident pattern.
- * Search is preformed either from the beginning up or from the end of
+ * Search is preformed either from the beginning up or from the end of
* the device downwards. The search starts always at the start of a
* block.
- * If the option NAND_BBT_PERCHIP is given, each chip is searched
+ * If the option NAND_BBT_PERCHIP is given, each chip is searched
* for a bbt, which contains the bad block information of this chip.
* This is neccecary to provide support for certain DOC devices.
*
- * The bbt ident pattern resides in the oob area of the first page
- * in a block.
+ * The bbt ident pattern resides in the oob area of the first page
+ * in a block.
*/
static int search_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *td)
{
@@ -392,10 +392,10 @@ static int search_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
startblock = (mtd->size >> this->bbt_erase_shift) -1;
dir = -1;
} else {
- startblock = 0;
+ startblock = 0;
dir = 1;
- }
-
+ }
+
/* Do we have a bbt per chip ? */
if (td->options & NAND_BBT_PERCHIP) {
chips = this->numchips;
@@ -405,19 +405,19 @@ static int search_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
chips = 1;
bbtblocks = mtd->size >> this->bbt_erase_shift;
}
-
+
/* Number of bits for each erase block in the bbt */
bits = td->options & NAND_BBT_NRBITS_MSK;
-
+
for (i = 0; i < chips; i++) {
/* Reset version information */
- td->version[i] = 0;
+ td->version[i] = 0;
td->pages[i] = -1;
/* Scan the maximum number of blocks */
for (block = 0; block < td->maxblocks; block++) {
int actblock = startblock + dir * block;
/* Read first page */
- nand_read_raw (mtd, buf, actblock << this->bbt_erase_shift, mtd->oobblock, mtd->oobsize);
+ nand_read_raw (mtd, buf, actblock << this->bbt_erase_shift, mtd->oobblock, mtd->oobsize);
if (!check_pattern(buf, scanlen, mtd->oobblock, td)) {
td->pages[i] = actblock << (this->bbt_erase_shift - this->page_shift);
if (td->options & NAND_BBT_VERSION) {
@@ -435,46 +435,46 @@ static int search_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
else
printk (KERN_DEBUG "Bad block table found at page %d, version 0x%02X\n", td->pages[i], td->version[i]);
}
- return 0;
+ return 0;
}
/**
* search_read_bbts - [GENERIC] scan the device for bad block table(s)
* @mtd: MTD device structure
* @buf: temporary buffer
- * @td: descriptor for the bad block table
+ * @td: descriptor for the bad block table
* @md: descriptor for the bad block table mirror
*
* Search and read the bad block table(s)
*/
-static int search_read_bbts (struct mtd_info *mtd, uint8_t *buf,
+static int search_read_bbts (struct mtd_info *mtd, uint8_t *buf,
struct nand_bbt_descr *td, struct nand_bbt_descr *md)
{
/* Search the primary table */
search_bbt (mtd, buf, td);
-
+
/* Search the mirror table */
if (md)
search_bbt (mtd, buf, md);
-
+
/* Force result check */
- return 1;
+ return 1;
}
-
-/**
+
+/**
* write_bbt - [GENERIC] (Re)write the bad block table
*
* @mtd: MTD device structure
* @buf: temporary buffer
- * @td: descriptor for the bad block table
+ * @td: descriptor for the bad block table
* @md: descriptor for the bad block table mirror
* @chipsel: selector for a specific chip, -1 for all
*
* (Re)write the bad block table
*
*/
-static int write_bbt (struct mtd_info *mtd, uint8_t *buf,
+static int write_bbt (struct mtd_info *mtd, uint8_t *buf,
struct nand_bbt_descr *td, struct nand_bbt_descr *md, int chipsel)
{
struct nand_chip *this = mtd->priv;
@@ -493,7 +493,7 @@ static int write_bbt (struct mtd_info *mtd, uint8_t *buf,
/* Write bad block table per chip rather than per device ? */
if (td->options & NAND_BBT_PERCHIP) {
numblocks = (int) (this->chipsize >> this->bbt_erase_shift);
- /* Full device write or specific chip ? */
+ /* Full device write or specific chip ? */
if (chipsel == -1) {
nrchips = this->numchips;
} else {
@@ -503,19 +503,19 @@ static int write_bbt (struct mtd_info *mtd, uint8_t *buf,
} else {
numblocks = (int) (mtd->size >> this->bbt_erase_shift);
nrchips = 1;
- }
-
+ }
+
/* Loop through the chips */
for (; chip < nrchips; chip++) {
-
- /* There was already a version of the table, reuse the page
- * This applies for absolute placement too, as we have the
+
+ /* There was already a version of the table, reuse the page
+ * This applies for absolute placement too, as we have the
* page nr. in td->pages.
*/
if (td->pages[chip] != -1) {
page = td->pages[chip];
goto write;
- }
+ }
/* Automatic placement of the bad block table */
/* Search direction top -> down ? */
@@ -525,7 +525,7 @@ static int write_bbt (struct mtd_info *mtd, uint8_t *buf,
} else {
startblock = chip * numblocks;
dir = 1;
- }
+ }
for (i = 0; i < td->maxblocks; i++) {
int block = startblock + dir * i;
@@ -542,7 +542,7 @@ static int write_bbt (struct mtd_info *mtd, uint8_t *buf,
}
printk (KERN_ERR "No space left to write bad block table\n");
return -ENOSPC;
-write:
+write:
/* Set up shift count and masks for the flash table */
bits = td->options & NAND_BBT_NRBITS_MSK;
@@ -553,14 +553,14 @@ write:
case 8: sft = 0; sftmsk = 0x00; msk[0] = 0x00; msk[1] = 0x0F; msk[2] = ~rcode; msk[3] = 0xff; break;
default: return -EINVAL;
}
-
+
bbtoffs = chip * (numblocks >> 2);
-
+
to = ((loff_t) page) << this->page_shift;
memcpy (&oobinfo, this->autooob, sizeof(oobinfo));
oobinfo.useecc = MTD_NANDECC_PLACEONLY;
-
+
/* Must we save the block contents ? */
if (td->options & NAND_BBT_SAVECONTENT) {
/* Make it block aligned */
@@ -599,7 +599,7 @@ write:
buf[len + td->veroffs] = td->version[chip];
}
}
-
+
/* walk through the memory table */
for (i = 0; i < numblocks; ) {
uint8_t dat;
@@ -611,7 +611,7 @@ write:
dat >>= 2;
}
}
-
+
memset (&einfo, 0, sizeof (einfo));
einfo.mtd = mtd;
einfo.addr = (unsigned long) to;
@@ -621,18 +621,18 @@ write:
printk (KERN_WARNING "nand_bbt: Error during block erase: %d\n", res);
return res;
}
-
+
res = mtd->write_ecc (mtd, to, len, &retlen, buf, &buf[len], &oobinfo);
if (res < 0) {
printk (KERN_WARNING "nand_bbt: Error while writing bad block table %d\n", res);
return res;
}
- printk (KERN_DEBUG "Bad block table written to 0x%08x, version 0x%02X\n",
+ printk (KERN_DEBUG "Bad block table written to 0x%08x, version 0x%02X\n",
(unsigned int) to, td->version[chip]);
-
+
/* Mark it as used */
td->pages[chip] = page;
- }
+ }
return 0;
}
@@ -641,7 +641,7 @@ write:
* @mtd: MTD device structure
* @bd: descriptor for the good/bad block search pattern
*
- * The function creates a memory based bbt by scanning the device
+ * The function creates a memory based bbt by scanning the device
* for manufacturer / software marked good / bad blocks
*/
static inline int nand_memory_bbt (struct mtd_info *mtd, struct nand_bbt_descr *bd)
@@ -673,11 +673,11 @@ static int check_create (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_des
struct nand_bbt_descr *rd, *rd2;
/* Do we have a bbt per chip ? */
- if (td->options & NAND_BBT_PERCHIP)
+ if (td->options & NAND_BBT_PERCHIP)
chips = this->numchips;
- else
+ else
chips = 1;
-
+
for (i = 0; i < chips; i++) {
writeops = 0;
rd = NULL;
@@ -692,7 +692,7 @@ static int check_create (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_des
}
if (td->pages[i] == -1) {
- rd = md;
+ rd = md;
td->version[i] = md->version[i];
writeops = 1;
goto writecheck;
@@ -710,7 +710,7 @@ static int check_create (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_des
if (!(td->options & NAND_BBT_VERSION))
rd2 = md;
goto writecheck;
- }
+ }
if (((int8_t) (td->version[i] - md->version[i])) > 0) {
rd = td;
@@ -735,15 +735,15 @@ static int check_create (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_des
create:
/* Create the bad block table by scanning the device ? */
if (!(td->options & NAND_BBT_CREATE))
- continue;
-
+ continue;
+
/* Create the table in memory by scanning the chip(s) */
create_bbt (mtd, buf, bd, chipsel);
-
+
td->version[i] = 1;
if (md)
- md->version[i] = 1;
-writecheck:
+ md->version[i] = 1;
+writecheck:
/* read back first ? */
if (rd)
read_abs_bbt (mtd, buf, rd, chipsel);
@@ -757,7 +757,7 @@ writecheck:
if (res < 0)
return res;
}
-
+
/* Write the mirror bad block table to the device ? */
if ((writeops & 0x02) && md && (md->options & NAND_BBT_WRITE)) {
res = write_bbt (mtd, buf, md, td, chipsel);
@@ -765,11 +765,11 @@ writecheck:
return res;
}
}
- return 0;
+ return 0;
}
/**
- * mark_bbt_regions - [GENERIC] mark the bad block table regions
+ * mark_bbt_regions - [GENERIC] mark the bad block table regions
* @mtd: MTD device structure
* @td: bad block table descriptor
*
@@ -790,14 +790,14 @@ static void mark_bbt_region (struct mtd_info *mtd, struct nand_bbt_descr *td)
} else {
chips = 1;
nrblocks = (int)(mtd->size >> this->bbt_erase_shift);
- }
-
+ }
+
for (i = 0; i < chips; i++) {
if ((td->options & NAND_BBT_ABSPAGE) ||
!(td->options & NAND_BBT_WRITE)) {
if (td->pages[i] == -1) continue;
block = td->pages[i] >> (this->bbt_erase_shift - this->page_shift);
- block <<= 1;
+ block <<= 1;
oldval = this->bbt[(block >> 3)];
newval = oldval | (0x2 << (block & 0x06));
this->bbt[(block >> 3)] = newval;
@@ -808,16 +808,16 @@ static void mark_bbt_region (struct mtd_info *mtd, struct nand_bbt_descr *td)
update = 0;
if (td->options & NAND_BBT_LASTBLOCK)
block = ((i + 1) * nrblocks) - td->maxblocks;
- else
+ else
block = i * nrblocks;
- block <<= 1;
+ block <<= 1;
for (j = 0; j < td->maxblocks; j++) {
oldval = this->bbt[(block >> 3)];
newval = oldval | (0x2 << (block & 0x06));
this->bbt[(block >> 3)] = newval;
if (oldval != newval) update = 1;
block += 2;
- }
+ }
/* If we want reserved blocks to be recorded to flash, and some
new ones have been marked, then we need to update the stored
bbts. This should only happen once. */
@@ -831,7 +831,7 @@ static void mark_bbt_region (struct mtd_info *mtd, struct nand_bbt_descr *td)
* @mtd: MTD device structure
* @bd: descriptor for the good/bad block search pattern
*
- * The function checks, if a bad block table(s) is/are already
+ * The function checks, if a bad block table(s) is/are already
* available. If not it scans the device for manufacturer
* marked good / bad blocks and writes the bad block table(s) to
* the selected place.
@@ -880,30 +880,30 @@ int nand_scan_bbt (struct mtd_info *mtd, struct nand_bbt_descr *bd)
this->bbt = NULL;
return -ENOMEM;
}
-
+
/* Is the bbt at a given page ? */
if (td->options & NAND_BBT_ABSPAGE) {
res = read_abs_bbts (mtd, buf, td, md);
- } else {
+ } else {
/* Search the bad block table using a pattern in oob */
res = search_read_bbts (mtd, buf, td, md);
- }
+ }
- if (res)
+ if (res)
res = check_create (mtd, buf, bd);
-
+
/* Prevent the bbt regions from erasing / writing */
mark_bbt_region (mtd, td);
if (md)
mark_bbt_region (mtd, md);
-
+
kfree (buf);
return res;
}
/**
- * nand_update_bbt - [NAND Interface] update bad block table(s)
+ * nand_update_bbt - [NAND Interface] update bad block table(s)
* @mtd: MTD device structure
* @offs: the offset of the newly marked block
*
@@ -930,7 +930,7 @@ int nand_update_bbt (struct mtd_info *mtd, loff_t offs)
printk (KERN_ERR "nand_update_bbt: Out of memory\n");
return -ENOMEM;
}
-
+
writeops = md != NULL ? 0x03 : 0x01;
/* Do we have a bbt per chip ? */
@@ -944,7 +944,7 @@ int nand_update_bbt (struct mtd_info *mtd, loff_t offs)
td->version[chip]++;
if (md)
- md->version[chip]++;
+ md->version[chip]++;
/* Write the bad block table to the device ? */
if ((writeops & 0x01) && (td->options & NAND_BBT_WRITE)) {
@@ -957,12 +957,12 @@ int nand_update_bbt (struct mtd_info *mtd, loff_t offs)
res = write_bbt (mtd, buf, md, td, chipsel);
}
-out:
+out:
kfree (buf);
return res;
}
-/* Define some generic bad / good block scan pattern which are used
+/* Define some generic bad / good block scan pattern which are used
* while scanning a device for factory marked good / bad blocks. */
static uint8_t scan_ff_pattern[] = { 0xff, 0xff };
@@ -1009,7 +1009,7 @@ static uint8_t bbt_pattern[] = {'B', 'b', 't', '0' };
static uint8_t mirror_pattern[] = {'1', 't', 'b', 'B' };
static struct nand_bbt_descr bbt_main_descr = {
- .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE
+ .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE
| NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP,
.offs = 8,
.len = 4,
@@ -1019,7 +1019,7 @@ static struct nand_bbt_descr bbt_main_descr = {
};
static struct nand_bbt_descr bbt_mirror_descr = {
- .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE
+ .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE
| NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP,
.offs = 8,
.len = 4,
@@ -1029,7 +1029,7 @@ static struct nand_bbt_descr bbt_mirror_descr = {
};
/**
- * nand_default_bbt - [NAND Interface] Select a default bad block table for the device
+ * nand_default_bbt - [NAND Interface] Select a default bad block table for the device
* @mtd: MTD device structure
*
* This function selects the default bad block table
@@ -1039,29 +1039,29 @@ static struct nand_bbt_descr bbt_mirror_descr = {
int nand_default_bbt (struct mtd_info *mtd)
{
struct nand_chip *this = mtd->priv;
-
- /* Default for AG-AND. We must use a flash based
+
+ /* Default for AG-AND. We must use a flash based
* bad block table as the devices have factory marked
* _good_ blocks. Erasing those blocks leads to loss
* of the good / bad information, so we _must_ store
- * this information in a good / bad table during
+ * this information in a good / bad table during
* startup
*/
if (this->options & NAND_IS_AND) {
/* Use the default pattern descriptors */
- if (!this->bbt_td) {
+ if (!this->bbt_td) {
this->bbt_td = &bbt_main_descr;
this->bbt_md = &bbt_mirror_descr;
- }
+ }
this->options |= NAND_USE_FLASH_BBT;
return nand_scan_bbt (mtd, &agand_flashbased);
}
-
-
+
+
/* Is a flash based bad block table requested ? */
if (this->options & NAND_USE_FLASH_BBT) {
- /* Use the default pattern descriptors */
- if (!this->bbt_td) {
+ /* Use the default pattern descriptors */
+ if (!this->bbt_td) {
this->bbt_td = &bbt_main_descr;
this->bbt_md = &bbt_mirror_descr;
}
@@ -1081,7 +1081,7 @@ int nand_default_bbt (struct mtd_info *mtd)
}
/**
- * nand_isbad_bbt - [NAND Interface] Check if a block is bad
+ * nand_isbad_bbt - [NAND Interface] Check if a block is bad
* @mtd: MTD device structure
* @offs: offset in the device
* @allowbbt: allow access to bad block table region
@@ -1092,12 +1092,12 @@ int nand_isbad_bbt (struct mtd_info *mtd, loff_t offs, int allowbbt)
struct nand_chip *this = mtd->priv;
int block;
uint8_t res;
-
+
/* Get block number * 2 */
block = (int) (offs >> (this->bbt_erase_shift - 1));
res = (this->bbt[block >> 3] >> (block & 0x06)) & 0x03;
- DEBUG (MTD_DEBUG_LEVEL2, "nand_isbad_bbt(): bbt info for offs 0x%08x: (block %d) 0x%02x\n",
+ DEBUG (MTD_DEBUG_LEVEL2, "nand_isbad_bbt(): bbt info for offs 0x%08x: (block %d) 0x%02x\n",
(unsigned int)offs, block >> 1, res);
switch ((int)res) {
diff --git a/drivers/mtd/nand/nand_ecc.c b/drivers/mtd/nand/nand_ecc.c
index 2e341b75437a..40ac909150a3 100644
--- a/drivers/mtd/nand/nand_ecc.c
+++ b/drivers/mtd/nand/nand_ecc.c
@@ -7,22 +7,22 @@
* Copyright (C) 2000-2004 Steven J. Hill (sjhill@realitydiluted.com)
* Toshiba America Electronics Components, Inc.
*
- * $Id: nand_ecc.c,v 1.14 2004/06/16 15:34:37 gleixner Exp $
+ * $Id: nand_ecc.c,v 1.15 2005/11/07 11:14:30 gleixner Exp $
*
* This file is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 or (at your option) any
* later version.
- *
+ *
* This file 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 file; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- *
+ *
* As a special exception, if other files instantiate templates or use
* macros or inline functions from these files, or you compile these
* files and link them with other works to produce a work based on these
@@ -30,7 +30,7 @@
* covered by the GNU General Public License. However the source code for
* these files must still be made available in accordance with section (3)
* of the GNU General Public License.
- *
+ *
* This exception does not invalidate any other reasons why a work based on
* this file might be covered by the GNU General Public License.
*/
@@ -67,7 +67,7 @@ static const u_char nand_ecc_precalc_table[] = {
* nand_trans_result - [GENERIC] create non-inverted ECC
* @reg2: line parity reg 2
* @reg3: line parity reg 3
- * @ecc_code: ecc
+ * @ecc_code: ecc
*
* Creates non-inverted ECC code from line parity
*/
@@ -75,11 +75,11 @@ static void nand_trans_result(u_char reg2, u_char reg3,
u_char *ecc_code)
{
u_char a, b, i, tmp1, tmp2;
-
+
/* Initialize variables */
a = b = 0x80;
tmp1 = tmp2 = 0;
-
+
/* Calculate first ECC byte */
for (i = 0; i < 4; i++) {
if (reg3 & a) /* LP15,13,11,9 --> ecc_code[0] */
@@ -90,7 +90,7 @@ static void nand_trans_result(u_char reg2, u_char reg3,
b >>= 1;
a >>= 1;
}
-
+
/* Calculate second ECC byte */
b = 0x80;
for (i = 0; i < 4; i++) {
@@ -102,7 +102,7 @@ static void nand_trans_result(u_char reg2, u_char reg3,
b >>= 1;
a >>= 1;
}
-
+
/* Store two of the ECC bytes */
ecc_code[0] = tmp1;
ecc_code[1] = tmp2;
@@ -118,28 +118,28 @@ int nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code
{
u_char idx, reg1, reg2, reg3;
int j;
-
+
/* Initialize variables */
reg1 = reg2 = reg3 = 0;
ecc_code[0] = ecc_code[1] = ecc_code[2] = 0;
-
- /* Build up column parity */
+
+ /* Build up column parity */
for(j = 0; j < 256; j++) {
-
+
/* Get CP0 - CP5 from table */
idx = nand_ecc_precalc_table[dat[j]];
reg1 ^= (idx & 0x3f);
-
+
/* All bit XOR = 1 ? */
if (idx & 0x40) {
reg3 ^= (u_char) j;
reg2 ^= ~((u_char) j);
}
}
-
+
/* Create non-inverted ECC code from line parity */
nand_trans_result(reg2, reg3, ecc_code);
-
+
/* Calculate final ECC code */
ecc_code[0] = ~ecc_code[0];
ecc_code[1] = ~ecc_code[1];
@@ -159,12 +159,12 @@ int nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code
int nand_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc)
{
u_char a, b, c, d1, d2, d3, add, bit, i;
-
- /* Do error detection */
+
+ /* Do error detection */
d1 = calc_ecc[0] ^ read_ecc[0];
d2 = calc_ecc[1] ^ read_ecc[1];
d3 = calc_ecc[2] ^ read_ecc[2];
-
+
if ((d1 | d2 | d3) == 0) {
/* No errors */
return 0;
@@ -173,7 +173,7 @@ int nand_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_cha
a = (d1 ^ (d1 >> 1)) & 0x55;
b = (d2 ^ (d2 >> 1)) & 0x55;
c = (d3 ^ (d3 >> 1)) & 0x54;
-
+
/* Found and will correct single bit error in the data */
if ((a == 0x55) && (b == 0x55) && (c == 0x54)) {
c = 0x80;
@@ -237,7 +237,7 @@ int nand_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_cha
}
}
}
-
+
/* Should never happen */
return -1;
}
diff --git a/drivers/mtd/nand/nand_ids.c b/drivers/mtd/nand/nand_ids.c
index efe246961b69..dbc7e55a4247 100644
--- a/drivers/mtd/nand/nand_ids.c
+++ b/drivers/mtd/nand/nand_ids.c
@@ -3,7 +3,7 @@
*
* Copyright (C) 2002 Thomas Gleixner (tglx@linutronix.de)
*
- * $Id: nand_ids.c,v 1.14 2005/06/23 09:38:50 gleixner Exp $
+ * $Id: nand_ids.c,v 1.16 2005/11/07 11:14:31 gleixner Exp $
*
* 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
@@ -14,14 +14,14 @@
#include <linux/mtd/nand.h>
/*
* Chip ID list
-*
+*
* Name. ID code, pagesize, chipsize in MegaByte, eraseblock size,
* options
-*
+*
* Pagesize; 0, 256, 512
* 0 get this information from the extended chip ID
+ 256 256 Byte page size
-* 512 512 Byte page size
+* 512 512 Byte page size
*/
struct nand_flash_dev nand_flash_ids[] = {
{"NAND 1MiB 5V 8-bit", 0x6e, 256, 1, 0x1000, 0},
@@ -34,27 +34,27 @@ struct nand_flash_dev nand_flash_ids[] = {
{"NAND 4MiB 3,3V 8-bit", 0xe3, 512, 4, 0x2000, 0},
{"NAND 4MiB 3,3V 8-bit", 0xe5, 512, 4, 0x2000, 0},
{"NAND 8MiB 3,3V 8-bit", 0xd6, 512, 8, 0x2000, 0},
-
+
{"NAND 8MiB 1,8V 8-bit", 0x39, 512, 8, 0x2000, 0},
{"NAND 8MiB 3,3V 8-bit", 0xe6, 512, 8, 0x2000, 0},
{"NAND 8MiB 1,8V 16-bit", 0x49, 512, 8, 0x2000, NAND_BUSWIDTH_16},
{"NAND 8MiB 3,3V 16-bit", 0x59, 512, 8, 0x2000, NAND_BUSWIDTH_16},
-
+
{"NAND 16MiB 1,8V 8-bit", 0x33, 512, 16, 0x4000, 0},
{"NAND 16MiB 3,3V 8-bit", 0x73, 512, 16, 0x4000, 0},
{"NAND 16MiB 1,8V 16-bit", 0x43, 512, 16, 0x4000, NAND_BUSWIDTH_16},
{"NAND 16MiB 3,3V 16-bit", 0x53, 512, 16, 0x4000, NAND_BUSWIDTH_16},
-
+
{"NAND 32MiB 1,8V 8-bit", 0x35, 512, 32, 0x4000, 0},
{"NAND 32MiB 3,3V 8-bit", 0x75, 512, 32, 0x4000, 0},
{"NAND 32MiB 1,8V 16-bit", 0x45, 512, 32, 0x4000, NAND_BUSWIDTH_16},
{"NAND 32MiB 3,3V 16-bit", 0x55, 512, 32, 0x4000, NAND_BUSWIDTH_16},
-
+
{"NAND 64MiB 1,8V 8-bit", 0x36, 512, 64, 0x4000, 0},
{"NAND 64MiB 3,3V 8-bit", 0x76, 512, 64, 0x4000, 0},
{"NAND 64MiB 1,8V 16-bit", 0x46, 512, 64, 0x4000, NAND_BUSWIDTH_16},
{"NAND 64MiB 3,3V 16-bit", 0x56, 512, 64, 0x4000, NAND_BUSWIDTH_16},
-
+
{"NAND 128MiB 1,8V 8-bit", 0x78, 512, 128, 0x4000, 0},
{"NAND 128MiB 1,8V 8-bit", 0x39, 512, 128, 0x4000, 0},
{"NAND 128MiB 3,3V 8-bit", 0x79, 512, 128, 0x4000, 0},
@@ -62,7 +62,7 @@ struct nand_flash_dev nand_flash_ids[] = {
{"NAND 128MiB 1,8V 16-bit", 0x49, 512, 128, 0x4000, NAND_BUSWIDTH_16},
{"NAND 128MiB 3,3V 16-bit", 0x74, 512, 128, 0x4000, NAND_BUSWIDTH_16},
{"NAND 128MiB 3,3V 16-bit", 0x59, 512, 128, 0x4000, NAND_BUSWIDTH_16},
-
+
{"NAND 256MiB 3,3V 8-bit", 0x71, 512, 256, 0x4000, 0},
/* These are the new chips with large page size. The pagesize
@@ -73,7 +73,7 @@ struct nand_flash_dev nand_flash_ids[] = {
{"NAND 64MiB 3,3V 8-bit", 0xF2, 0, 64, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
{"NAND 64MiB 1,8V 16-bit", 0xB2, 0, 64, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR},
{"NAND 64MiB 3,3V 16-bit", 0xC2, 0, 64, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR},
-
+
/* 1 Gigabit */
{"NAND 128MiB 1,8V 8-bit", 0xA1, 0, 128, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
{"NAND 128MiB 3,3V 8-bit", 0xF1, 0, 128, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
@@ -85,13 +85,13 @@ struct nand_flash_dev nand_flash_ids[] = {
{"NAND 256MiB 3,3V 8-bit", 0xDA, 0, 256, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
{"NAND 256MiB 1,8V 16-bit", 0xBA, 0, 256, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR},
{"NAND 256MiB 3,3V 16-bit", 0xCA, 0, 256, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR},
-
+
/* 4 Gigabit */
{"NAND 512MiB 1,8V 8-bit", 0xAC, 0, 512, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
{"NAND 512MiB 3,3V 8-bit", 0xDC, 0, 512, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
{"NAND 512MiB 1,8V 16-bit", 0xBC, 0, 512, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR},
{"NAND 512MiB 3,3V 16-bit", 0xCC, 0, 512, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR},
-
+
/* 8 Gigabit */
{"NAND 1GiB 1,8V 8-bit", 0xA3, 0, 1024, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
{"NAND 1GiB 3,3V 8-bit", 0xD3, 0, 1024, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
@@ -104,11 +104,11 @@ struct nand_flash_dev nand_flash_ids[] = {
{"NAND 2GiB 1,8V 16-bit", 0xB5, 0, 2048, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR},
{"NAND 2GiB 3,3V 16-bit", 0xC5, 0, 2048, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR},
- /* Renesas AND 1 Gigabit. Those chips do not support extended id and have a strange page/block layout !
+ /* Renesas AND 1 Gigabit. Those chips do not support extended id and have a strange page/block layout !
* The chosen minimum erasesize is 4 * 2 * 2048 = 16384 Byte, as those chips have an array of 4 page planes
* 1 block = 2 pages, but due to plane arrangement the blocks 0-3 consists of page 0 + 4,1 + 5, 2 + 6, 3 + 7
* Anyway JFFS2 would increase the eraseblock size so we chose a combined one which can be erased in one go
- * There are more speed improvements for reads and writes possible, but not implemented now
+ * There are more speed improvements for reads and writes possible, but not implemented now
*/
{"AND 128MiB 3,3V 8-bit", 0x01, 2048, 128, 0x4000, NAND_IS_AND | NAND_NO_AUTOINCR | NAND_4PAGE_ARRAY | BBT_AUTO_REFRESH},
diff --git a/drivers/mtd/nand/nandsim.c b/drivers/mtd/nand/nandsim.c
index 754b6ed7ce14..de4500395300 100644
--- a/drivers/mtd/nand/nandsim.c
+++ b/drivers/mtd/nand/nandsim.c
@@ -3,7 +3,7 @@
*
* Author: Artem B. Bityuckiy <dedekind@oktetlabs.ru>, <dedekind@infradead.org>
*
- * Copyright (C) 2004 Nokia Corporation
+ * Copyright (C) 2004 Nokia Corporation
*
* Note: NS means "NAND Simulator".
* Note: Input means input TO flash chip, output means output FROM chip.
@@ -126,7 +126,7 @@ MODULE_PARM_DESC(dbg, "Output debug information if not zero");
/* The largest possible page size */
#define NS_LARGEST_PAGE_SIZE 2048
-
+
/* The prefix for simulator output */
#define NS_OUTPUT_PREFIX "[nandsim]"
@@ -145,7 +145,7 @@ MODULE_PARM_DESC(dbg, "Output debug information if not zero");
do { if (do_delays) udelay(us); } while(0)
#define NS_MDELAY(us) \
do { if (do_delays) mdelay(us); } while(0)
-
+
/* Is the nandsim structure initialized ? */
#define NS_IS_INITIALIZED(ns) ((ns)->geom.totsz != 0)
@@ -153,12 +153,12 @@ MODULE_PARM_DESC(dbg, "Output debug information if not zero");
#define NS_STATUS_OK(ns) (NAND_STATUS_READY | (NAND_STATUS_WP * ((ns)->lines.wp == 0)))
/* Operation failed completion status */
-#define NS_STATUS_FAILED(ns) (NAND_STATUS_FAIL | NS_STATUS_OK(ns))
+#define NS_STATUS_FAILED(ns) (NAND_STATUS_FAIL | NS_STATUS_OK(ns))
/* Calculate the page offset in flash RAM image by (row, column) address */
#define NS_RAW_OFFSET(ns) \
(((ns)->regs.row << (ns)->geom.pgshift) + ((ns)->regs.row * (ns)->geom.oobsz) + (ns)->regs.column)
-
+
/* Calculate the OOB offset in flash RAM image by (row, column) address */
#define NS_RAW_OFFSET_OOB(ns) (NS_RAW_OFFSET(ns) + ns->geom.pgsz)
@@ -223,15 +223,15 @@ MODULE_PARM_DESC(dbg, "Output debug information if not zero");
/* Remove action bits ftom state */
#define NS_STATE(x) ((x) & ~ACTION_MASK)
-
-/*
+
+/*
* Maximum previous states which need to be saved. Currently saving is
* only needed for page programm operation with preceeded read command
* (which is only valid for 512-byte pages).
*/
#define NS_MAX_PREVSTATES 1
-/*
+/*
* The structure which describes all the internal simulator data.
*/
struct nandsim {
@@ -242,7 +242,7 @@ struct nandsim {
uint32_t options; /* chip's characteristic bits */
uint32_t state; /* current chip state */
uint32_t nxstate; /* next expected state */
-
+
uint32_t *op; /* current operation, NULL operations isn't known yet */
uint32_t pstates[NS_MAX_PREVSTATES]; /* previous states */
uint16_t npstates; /* number of previous states saved */
@@ -413,7 +413,7 @@ init_nandsim(struct mtd_info *mtd)
ns->geom.secaddrbytes = 3;
}
}
-
+
/* Detect how many ID bytes the NAND chip outputs */
for (i = 0; nand_flash_ids[i].name != NULL; i++) {
if (second_id_byte != nand_flash_ids[i].id)
@@ -444,7 +444,7 @@ init_nandsim(struct mtd_info *mtd)
#ifdef CONFIG_NS_ABS_POS
ns->mem.byte = ioremap(CONFIG_NS_ABS_POS, ns->geom.totszoob);
if (!ns->mem.byte) {
- NS_ERR("init_nandsim: failed to map the NAND flash image at address %p\n",
+ NS_ERR("init_nandsim: failed to map the NAND flash image at address %p\n",
(void *)CONFIG_NS_ABS_POS);
return -ENOMEM;
}
@@ -567,7 +567,7 @@ static int
check_command(int cmd)
{
switch (cmd) {
-
+
case NAND_CMD_READ0:
case NAND_CMD_READSTART:
case NAND_CMD_PAGEPROG:
@@ -580,7 +580,7 @@ check_command(int cmd)
case NAND_CMD_RESET:
case NAND_CMD_READ1:
return 0;
-
+
case NAND_CMD_STATUS_MULTI:
default:
return 1;
@@ -631,7 +631,7 @@ static inline void
accept_addr_byte(struct nandsim *ns, u_char bt)
{
uint byte = (uint)bt;
-
+
if (ns->regs.count < (ns->geom.pgaddrbytes - ns->geom.secaddrbytes))
ns->regs.column |= (byte << 8 * ns->regs.count);
else {
@@ -642,11 +642,11 @@ accept_addr_byte(struct nandsim *ns, u_char bt)
return;
}
-
+
/*
* Switch to STATE_READY state.
*/
-static inline void
+static inline void
switch_to_ready_state(struct nandsim *ns, u_char status)
{
NS_DBG("switch_to_ready_state: switch to %s state\n", get_state_name(STATE_READY));
@@ -675,7 +675,7 @@ switch_to_ready_state(struct nandsim *ns, u_char status)
* (for example program from the second half and read from the
* second half operations both begin with the READ1 command). In this
* case the ns->pstates[] array contains previous states.
- *
+ *
* Thus, the function tries to find operation containing the following
* states (if the 'flag' parameter is 0):
* ns->pstates[0], ... ns->pstates[ns->npstates], ns->state
@@ -683,7 +683,7 @@ switch_to_ready_state(struct nandsim *ns, u_char status)
* If (one and only one) matching operation is found, it is accepted (
* ns->ops, ns->state, ns->nxstate are initialized, ns->npstate is
* zeroed).
- *
+ *
* If there are several maches, the current state is pushed to the
* ns->pstates.
*
@@ -692,7 +692,7 @@ switch_to_ready_state(struct nandsim *ns, u_char status)
* In such situation the function is called with 'flag' != 0, and the
* operation is searched using the following pattern:
* ns->pstates[0], ... ns->pstates[ns->npstates], <address input>
- *
+ *
* It is supposed that this pattern must either match one operation on
* none. There can't be ambiguity in that case.
*
@@ -711,15 +711,15 @@ find_operation(struct nandsim *ns, uint32_t flag)
{
int opsfound = 0;
int i, j, idx = 0;
-
+
for (i = 0; i < NS_OPER_NUM; i++) {
int found = 1;
-
+
if (!(ns->options & ops[i].reqopts))
/* Ignore operations we can't perform */
continue;
-
+
if (flag) {
if (!(ops[i].states[ns->npstates] & STATE_ADDR_MASK))
continue;
@@ -728,7 +728,7 @@ find_operation(struct nandsim *ns, uint32_t flag)
continue;
}
- for (j = 0; j < ns->npstates; j++)
+ for (j = 0; j < ns->npstates; j++)
if (NS_STATE(ops[i].states[j]) != NS_STATE(ns->pstates[j])
&& (ns->options & ops[idx].reqopts)) {
found = 0;
@@ -745,7 +745,7 @@ find_operation(struct nandsim *ns, uint32_t flag)
/* Exact match */
ns->op = &ops[idx].states[0];
if (flag) {
- /*
+ /*
* In this case the find_operation function was
* called when address has just began input. But it isn't
* yet fully input and the current state must
@@ -763,7 +763,7 @@ find_operation(struct nandsim *ns, uint32_t flag)
idx, get_state_name(ns->state), get_state_name(ns->nxstate));
return 0;
}
-
+
if (opsfound == 0) {
/* Nothing was found. Try to ignore previous commands (if any) and search again */
if (ns->npstates != 0) {
@@ -777,13 +777,13 @@ find_operation(struct nandsim *ns, uint32_t flag)
switch_to_ready_state(ns, NS_STATUS_FAILED(ns));
return -2;
}
-
+
if (flag) {
/* This shouldn't happen */
NS_DBG("find_operation: BUG, operation must be known if address is input\n");
return -2;
}
-
+
NS_DBG("find_operation: there is still ambiguity\n");
ns->pstates[ns->npstates++] = ns->state;
@@ -803,7 +803,7 @@ do_state_action(struct nandsim *ns, uint32_t action)
int busdiv = ns->busw == 8 ? 1 : 2;
action &= ACTION_MASK;
-
+
/* Check that page address input is correct */
if (action != ACTION_SECERASE && ns->regs.row >= ns->geom.pgnum) {
NS_WARN("do_state_action: wrong page number (%#x)\n", ns->regs.row);
@@ -827,14 +827,14 @@ do_state_action(struct nandsim *ns, uint32_t action)
NS_DBG("do_state_action: (ACTION_CPY:) copy %d bytes to int buf, raw offset %d\n",
num, NS_RAW_OFFSET(ns) + ns->regs.off);
-
+
if (ns->regs.off == 0)
NS_LOG("read page %d\n", ns->regs.row);
else if (ns->regs.off < ns->geom.pgsz)
NS_LOG("read page %d (second half)\n", ns->regs.row);
else
NS_LOG("read OOB of page %d\n", ns->regs.row);
-
+
NS_UDELAY(access_delay);
NS_UDELAY(input_cycle * ns->geom.pgsz / 1000 / busdiv);
@@ -844,30 +844,30 @@ do_state_action(struct nandsim *ns, uint32_t action)
/*
* Erase sector.
*/
-
+
if (ns->lines.wp) {
NS_ERR("do_state_action: device is write-protected, ignore sector erase\n");
return -1;
}
-
+
if (ns->regs.row >= ns->geom.pgnum - ns->geom.pgsec
|| (ns->regs.row & ~(ns->geom.secsz - 1))) {
NS_ERR("do_state_action: wrong sector address (%#x)\n", ns->regs.row);
return -1;
}
-
+
ns->regs.row = (ns->regs.row <<
8 * (ns->geom.pgaddrbytes - ns->geom.secaddrbytes)) | ns->regs.column;
ns->regs.column = 0;
-
+
NS_DBG("do_state_action: erase sector at address %#x, off = %d\n",
ns->regs.row, NS_RAW_OFFSET(ns));
NS_LOG("erase sector %d\n", ns->regs.row >> (ns->geom.secshift - ns->geom.pgshift));
memset(ns->mem.byte + NS_RAW_OFFSET(ns), 0xFF, ns->geom.secszoob);
-
+
NS_MDELAY(erase_delay);
-
+
break;
case ACTION_PRGPAGE:
@@ -893,12 +893,12 @@ do_state_action(struct nandsim *ns, uint32_t action)
NS_DBG("do_state_action: copy %d bytes from int buf to (%#x, %#x), raw off = %d\n",
num, ns->regs.row, ns->regs.column, NS_RAW_OFFSET(ns) + ns->regs.off);
NS_LOG("programm page %d\n", ns->regs.row);
-
+
NS_UDELAY(programm_delay);
NS_UDELAY(output_cycle * ns->geom.pgsz / 1000 / busdiv);
-
+
break;
-
+
case ACTION_ZEROOFF:
NS_DBG("do_state_action: set internal offset to 0\n");
ns->regs.off = 0;
@@ -918,7 +918,7 @@ do_state_action(struct nandsim *ns, uint32_t action)
NS_DBG("do_state_action: set internal offset to %d\n", ns->geom.pgsz);
ns->regs.off = ns->geom.pgsz;
break;
-
+
default:
NS_DBG("do_state_action: BUG! unknown action\n");
}
@@ -937,7 +937,7 @@ switch_state(struct nandsim *ns)
* The current operation have already been identified.
* Just follow the states chain.
*/
-
+
ns->stateidx += 1;
ns->state = ns->nxstate;
ns->nxstate = ns->op[ns->stateidx + 1];
@@ -951,14 +951,14 @@ switch_state(struct nandsim *ns)
switch_to_ready_state(ns, NS_STATUS_FAILED(ns));
return;
}
-
+
} else {
/*
* We don't yet know which operation we perform.
* Try to identify it.
*/
- /*
+ /*
* The only event causing the switch_state function to
* be called with yet unknown operation is new command.
*/
@@ -987,7 +987,7 @@ switch_state(struct nandsim *ns)
*/
u_char status = NS_STATUS_OK(ns);
-
+
/* In case of data states, see if all bytes were input/output */
if ((ns->state & (STATE_DATAIN_MASK | STATE_DATAOUT_MASK))
&& ns->regs.count != ns->regs.num) {
@@ -995,17 +995,17 @@ switch_state(struct nandsim *ns)
ns->regs.num - ns->regs.count);
status = NS_STATUS_FAILED(ns);
}
-
+
NS_DBG("switch_state: operation complete, switch to STATE_READY state\n");
switch_to_ready_state(ns, status);
return;
} else if (ns->nxstate & (STATE_DATAIN_MASK | STATE_DATAOUT_MASK)) {
- /*
+ /*
* If the next state is data input/output, switch to it now
*/
-
+
ns->state = ns->nxstate;
ns->nxstate = ns->op[++ns->stateidx + 1];
ns->regs.num = ns->regs.count = 0;
@@ -1023,16 +1023,16 @@ switch_state(struct nandsim *ns)
case STATE_DATAOUT:
ns->regs.num = ns->geom.pgszoob - ns->regs.off - ns->regs.column;
break;
-
+
case STATE_DATAOUT_ID:
ns->regs.num = ns->geom.idbytes;
break;
-
+
case STATE_DATAOUT_STATUS:
case STATE_DATAOUT_STATUS_M:
ns->regs.count = ns->regs.num = 0;
break;
-
+
default:
NS_ERR("switch_state: BUG! unknown data state\n");
}
@@ -1044,16 +1044,16 @@ switch_state(struct nandsim *ns)
*/
ns->regs.count = 0;
-
+
switch (NS_STATE(ns->nxstate)) {
case STATE_ADDR_PAGE:
ns->regs.num = ns->geom.pgaddrbytes;
-
+
break;
case STATE_ADDR_SEC:
ns->regs.num = ns->geom.secaddrbytes;
break;
-
+
case STATE_ADDR_ZERO:
ns->regs.num = 1;
break;
@@ -1062,7 +1062,7 @@ switch_state(struct nandsim *ns)
NS_ERR("switch_state: BUG! unknown address state\n");
}
} else {
- /*
+ /*
* Just reset internal counters.
*/
@@ -1184,7 +1184,7 @@ ns_nand_read_byte(struct mtd_info *mtd)
default:
BUG();
}
-
+
if (ns->regs.count == ns->regs.num) {
NS_DBG("read_byte: all bytes were read\n");
@@ -1201,9 +1201,9 @@ ns_nand_read_byte(struct mtd_info *mtd)
}
else if (NS_STATE(ns->nxstate) == STATE_READY)
switch_state(ns);
-
+
}
-
+
return outb;
}
@@ -1211,7 +1211,7 @@ static void
ns_nand_write_byte(struct mtd_info *mtd, u_char byte)
{
struct nandsim *ns = (struct nandsim *)((struct nand_chip *)mtd->priv)->priv;
-
+
/* Sanity and correctness checks */
if (!ns->lines.ce) {
NS_ERR("write_byte: chip is disabled, ignore write\n");
@@ -1221,7 +1221,7 @@ ns_nand_write_byte(struct mtd_info *mtd, u_char byte)
NS_ERR("write_byte: ALE and CLE pins are high simultaneously, ignore write\n");
return;
}
-
+
if (ns->lines.cle == 1) {
/*
* The byte written is a command.
@@ -1233,7 +1233,7 @@ ns_nand_write_byte(struct mtd_info *mtd, u_char byte)
return;
}
- /*
+ /*
* Chip might still be in STATE_DATAOUT
* (if OPT_AUTOINCR feature is supported), STATE_DATAOUT_STATUS or
* STATE_DATAOUT_STATUS_M state. If so, switch state.
@@ -1254,13 +1254,13 @@ ns_nand_write_byte(struct mtd_info *mtd, u_char byte)
"ignore previous states\n", (uint)byte, get_state_name(ns->nxstate));
switch_to_ready_state(ns, NS_STATUS_FAILED(ns));
}
-
+
/* Check that the command byte is correct */
if (check_command(byte)) {
NS_ERR("write_byte: unknown command %#x\n", (uint)byte);
return;
}
-
+
NS_DBG("command byte corresponding to %s state accepted\n",
get_state_name(get_state_by_command(byte)));
ns->regs.command = byte;
@@ -1277,12 +1277,12 @@ ns_nand_write_byte(struct mtd_info *mtd, u_char byte)
if (find_operation(ns, 1) < 0)
return;
-
+
if ((ns->state & ACTION_MASK) && do_state_action(ns, ns->state) < 0) {
switch_to_ready_state(ns, NS_STATUS_FAILED(ns));
return;
}
-
+
ns->regs.count = 0;
switch (NS_STATE(ns->nxstate)) {
case STATE_ADDR_PAGE:
@@ -1306,7 +1306,7 @@ ns_nand_write_byte(struct mtd_info *mtd, u_char byte)
switch_to_ready_state(ns, NS_STATUS_FAILED(ns));
return;
}
-
+
/* Check if this is expected byte */
if (ns->regs.count == ns->regs.num) {
NS_ERR("write_byte: no more address bytes expected\n");
@@ -1325,12 +1325,12 @@ ns_nand_write_byte(struct mtd_info *mtd, u_char byte)
NS_DBG("address (%#x, %#x) is accepted\n", ns->regs.row, ns->regs.column);
switch_state(ns);
}
-
+
} else {
/*
* The byte written is an input data.
*/
-
+
/* Check that chip is expecting data input */
if (!(ns->state & STATE_DATAIN_MASK)) {
NS_ERR("write_byte: data input (%#x) isn't expected, state is %s, "
@@ -1372,7 +1372,7 @@ ns_nand_read_word(struct mtd_info *mtd)
struct nand_chip *chip = (struct nand_chip *)mtd->priv;
NS_DBG("read_word\n");
-
+
return chip->read_byte(mtd) | (chip->read_byte(mtd) << 8);
}
@@ -1380,14 +1380,14 @@ static void
ns_nand_write_word(struct mtd_info *mtd, uint16_t word)
{
struct nand_chip *chip = (struct nand_chip *)mtd->priv;
-
+
NS_DBG("write_word\n");
-
+
chip->write_byte(mtd, word & 0xFF);
chip->write_byte(mtd, word >> 8);
}
-static void
+static void
ns_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
{
struct nandsim *ns = (struct nandsim *)((struct nand_chip *)mtd->priv)->priv;
@@ -1409,13 +1409,13 @@ ns_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
memcpy(ns->buf.byte + ns->regs.count, buf, len);
ns->regs.count += len;
-
+
if (ns->regs.count == ns->regs.num) {
NS_DBG("write_buf: %d bytes were written\n", ns->regs.count);
}
}
-static void
+static void
ns_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)
{
struct nandsim *ns = (struct nandsim *)((struct nand_chip *)mtd->priv)->priv;
@@ -1453,7 +1453,7 @@ ns_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)
memcpy(buf, ns->buf.byte + ns->regs.count, len);
ns->regs.count += len;
-
+
if (ns->regs.count == ns->regs.num) {
if ((ns->options & OPT_AUTOINCR) && NS_STATE(ns->state) == STATE_DATAOUT) {
ns->regs.count = 0;
@@ -1465,11 +1465,11 @@ ns_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)
else if (NS_STATE(ns->nxstate) == STATE_READY)
switch_state(ns);
}
-
+
return;
}
-static int
+static int
ns_nand_verify_buf(struct mtd_info *mtd, const u_char *buf, int len)
{
ns_nand_read_buf(mtd, (u_char *)&ns_verify_buf[0], len);
@@ -1496,7 +1496,7 @@ int __init ns_init_module(void)
NS_ERR("wrong bus width (%d), use only 8 or 16\n", bus_width);
return -EINVAL;
}
-
+
/* Allocate and initialize mtd_info, nand_chip and nandsim structures */
nsmtd = kmalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip)
+ sizeof(struct nandsim), GFP_KERNEL);
@@ -1509,7 +1509,7 @@ int __init ns_init_module(void)
chip = (struct nand_chip *)(nsmtd + 1);
nsmtd->priv = (void *)chip;
nand = (struct nandsim *)(chip + 1);
- chip->priv = (void *)nand;
+ chip->priv = (void *)nand;
/*
* Register simulator's callbacks.
@@ -1526,9 +1526,9 @@ int __init ns_init_module(void)
chip->eccmode = NAND_ECC_SOFT;
chip->options |= NAND_SKIP_BBTSCAN;
- /*
+ /*
* Perform minimum nandsim structure initialization to handle
- * the initial ID read command correctly
+ * the initial ID read command correctly
*/
if (third_id_byte != 0xFF || fourth_id_byte != 0xFF)
nand->geom.idbytes = 4;
@@ -1557,7 +1557,7 @@ int __init ns_init_module(void)
NS_ERR("scan_bbt: can't initialize the nandsim structure\n");
goto error;
}
-
+
if ((retval = nand_default_bbt(nsmtd)) != 0) {
free_nandsim(nand);
goto error;
diff --git a/drivers/mtd/nand/ppchameleonevb.c b/drivers/mtd/nand/ppchameleonevb.c
index e510a83d7bdb..91a95f34a6ee 100644
--- a/drivers/mtd/nand/ppchameleonevb.c
+++ b/drivers/mtd/nand/ppchameleonevb.c
@@ -6,7 +6,7 @@
* Derived from drivers/mtd/nand/edb7312.c
*
*
- * $Id: ppchameleonevb.c,v 1.6 2004/11/05 16:07:16 kalev Exp $
+ * $Id: ppchameleonevb.c,v 1.7 2005/11/07 11:14:31 gleixner Exp $
*
* 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
@@ -338,7 +338,7 @@ nand_evb_init:
out_be32((volatile unsigned*)GPIO0_TSRH, in_be32((volatile unsigned*)GPIO0_TSRH) & 0xFFFFFFF0);
out_be32((volatile unsigned*)GPIO0_TSRL, in_be32((volatile unsigned*)GPIO0_TSRL) & 0x3FFFFFFF);
/* enable output driver */
- out_be32((volatile unsigned*)GPIO0_TCR, in_be32((volatile unsigned*)GPIO0_TCR) | NAND_EVB_nCE_GPIO_PIN |
+ out_be32((volatile unsigned*)GPIO0_TCR, in_be32((volatile unsigned*)GPIO0_TCR) | NAND_EVB_nCE_GPIO_PIN |
NAND_EVB_CLE_GPIO_PIN | NAND_EVB_ALE_GPIO_PIN);
#ifdef USE_READY_BUSY_PIN
/* three-state select */
@@ -402,7 +402,7 @@ static void __exit ppchameleonevb_cleanup (void)
/* Release resources, unregister device(s) */
nand_release (ppchameleon_mtd);
nand_release (ppchameleonevb_mtd);
-
+
/* Release iomaps */
this = (struct nand_chip *) &ppchameleon_mtd[1];
iounmap((void *) this->IO_ADDR_R;
diff --git a/drivers/mtd/nand/rtc_from4.c b/drivers/mtd/nand/rtc_from4.c
index 031051cbde76..3a5841c9d950 100644
--- a/drivers/mtd/nand/rtc_from4.c
+++ b/drivers/mtd/nand/rtc_from4.c
@@ -2,11 +2,11 @@
* drivers/mtd/nand/rtc_from4.c
*
* Copyright (C) 2004 Red Hat, Inc.
- *
+ *
* Derived from drivers/mtd/nand/spia.c
* Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com)
*
- * $Id: rtc_from4.c,v 1.9 2005/01/24 20:40:11 dmarlin Exp $
+ * $Id: rtc_from4.c,v 1.10 2005/11/07 11:14:31 gleixner Exp $
*
* 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
@@ -14,8 +14,8 @@
*
* Overview:
* This is a device driver for the AG-AND flash device found on the
- * Renesas Technology Corp. Flash ROM 4-slot interface board (FROM_BOARD4),
- * which utilizes the Renesas HN29V1G91T-30 part.
+ * Renesas Technology Corp. Flash ROM 4-slot interface board (FROM_BOARD4),
+ * which utilizes the Renesas HN29V1G91T-30 part.
* This chip is a 1 GBibit (128MiB x 8 bits) AG-AND flash device.
*/
@@ -105,9 +105,9 @@ const static struct mtd_partition partition_info[] = {
};
#define NUM_PARTITIONS 1
-/*
+/*
* hardware specific flash bbt decriptors
- * Note: this is to allow debugging by disabling
+ * Note: this is to allow debugging by disabling
* NAND_BBT_CREATE and/or NAND_BBT_WRITE
*
*/
@@ -141,7 +141,7 @@ static struct nand_bbt_descr rtc_from4_bbt_mirror_descr = {
/* the Reed Solomon control structure */
static struct rs_control *rs_decoder;
-/*
+/*
* hardware specific Out Of Band information
*/
static struct nand_oobinfo rtc_from4_nand_oobinfo = {
@@ -200,38 +200,38 @@ static uint8_t revbits[256] = {
-/*
+/*
* rtc_from4_hwcontrol - hardware specific access to control-lines
* @mtd: MTD device structure
* @cmd: hardware control command
*
- * Address lines (A5 and A4) are used to control Command and Address Latch
+ * Address lines (A5 and A4) are used to control Command and Address Latch
* Enable on this board, so set the read/write address appropriately.
*
- * Chip Enable is also controlled by the Chip Select (CS5) and
+ * Chip Enable is also controlled by the Chip Select (CS5) and
* Address lines (A24-A22), so no action is required here.
*
*/
static void rtc_from4_hwcontrol(struct mtd_info *mtd, int cmd)
{
struct nand_chip* this = (struct nand_chip *) (mtd->priv);
-
+
switch(cmd) {
-
- case NAND_CTL_SETCLE:
+
+ case NAND_CTL_SETCLE:
this->IO_ADDR_W = (void __iomem *)((unsigned long)this->IO_ADDR_W | RTC_FROM4_CLE);
break;
- case NAND_CTL_CLRCLE:
+ case NAND_CTL_CLRCLE:
this->IO_ADDR_W = (void __iomem *)((unsigned long)this->IO_ADDR_W & ~RTC_FROM4_CLE);
break;
-
+
case NAND_CTL_SETALE:
this->IO_ADDR_W = (void __iomem *)((unsigned long)this->IO_ADDR_W | RTC_FROM4_ALE);
break;
case NAND_CTL_CLRALE:
this->IO_ADDR_W = (void __iomem *)((unsigned long)this->IO_ADDR_W & ~RTC_FROM4_ALE);
break;
-
+
case NAND_CTL_SETNCE:
break;
case NAND_CTL_CLRNCE:
@@ -296,7 +296,7 @@ static int rtc_from4_nand_device_ready(struct mtd_info *mtd)
* @mtd: MTD device structure
* @chip: Chip to select (0 == slot 3, 1 == slot 4)
*
- * If there was a sudden loss of power during an erase operation, a
+ * If there was a sudden loss of power during an erase operation, a
* "device recovery" operation must be performed when power is restored
* to ensure correct operation. This routine performs the required steps
* for the requested chip.
@@ -312,7 +312,7 @@ static void deplete(struct mtd_info *mtd, int chip)
while (!this->dev_ready(mtd));
this->select_chip(mtd, chip);
-
+
/* Send the commands for device recovery, phase 1 */
this->cmdfunc (mtd, NAND_CMD_DEPLETE1, 0x0000, 0x0000);
this->cmdfunc (mtd, NAND_CMD_DEPLETE2, -1, -1);
@@ -330,7 +330,7 @@ static void deplete(struct mtd_info *mtd, int chip)
* @mtd: MTD device structure
* @mode: I/O mode; read or write
*
- * enable hardware ECC for data read or write
+ * enable hardware ECC for data read or write
*
*/
static void rtc_from4_enable_hwecc(struct mtd_info *mtd, int mode)
@@ -340,7 +340,7 @@ static void rtc_from4_enable_hwecc(struct mtd_info *mtd, int mode)
switch (mode) {
case NAND_ECC_READ :
- status = RTC_FROM4_RS_ECC_CTL_CLR
+ status = RTC_FROM4_RS_ECC_CTL_CLR
| RTC_FROM4_RS_ECC_CTL_FD_E;
*rs_ecc_ctl = status;
@@ -353,8 +353,8 @@ static void rtc_from4_enable_hwecc(struct mtd_info *mtd, int mode)
break;
case NAND_ECC_WRITE :
- status = RTC_FROM4_RS_ECC_CTL_CLR
- | RTC_FROM4_RS_ECC_CTL_GEN
+ status = RTC_FROM4_RS_ECC_CTL_CLR
+ | RTC_FROM4_RS_ECC_CTL_GEN
| RTC_FROM4_RS_ECC_CTL_FD_E;
*rs_ecc_ctl = status;
@@ -411,7 +411,7 @@ static void rtc_from4_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_c
static int rtc_from4_correct_data(struct mtd_info *mtd, const u_char *buf, u_char *ecc1, u_char *ecc2)
{
int i, j, res;
- unsigned short status;
+ unsigned short status;
uint16_t par[6], syn[6];
uint8_t ecc[8];
volatile unsigned short *rs_ecc;
@@ -430,7 +430,7 @@ static int rtc_from4_correct_data(struct mtd_info *mtd, const u_char *buf, u_cha
}
/* convert into 6 10bit syndrome fields */
- par[5] = rs_decoder->index_of[(((uint16_t)ecc[0] >> 0) & 0x0ff) |
+ par[5] = rs_decoder->index_of[(((uint16_t)ecc[0] >> 0) & 0x0ff) |
(((uint16_t)ecc[1] << 8) & 0x300)];
par[4] = rs_decoder->index_of[(((uint16_t)ecc[1] >> 2) & 0x03f) |
(((uint16_t)ecc[2] << 6) & 0x3c0)];
@@ -456,7 +456,7 @@ static int rtc_from4_correct_data(struct mtd_info *mtd, const u_char *buf, u_cha
/* Let the library code do its magic.*/
res = decode_rs8(rs_decoder, (uint8_t *)buf, par, 512, syn, 0, NULL, 0xff, NULL);
if (res > 0) {
- DEBUG (MTD_DEBUG_LEVEL0, "rtc_from4_correct_data: "
+ DEBUG (MTD_DEBUG_LEVEL0, "rtc_from4_correct_data: "
"ECC corrected %d errors on read\n", res);
}
return res;
@@ -470,9 +470,9 @@ static int rtc_from4_correct_data(struct mtd_info *mtd, const u_char *buf, u_cha
* @state: state or the operation
* @status: status code returned from read status
* @page: startpage inside the chip, must be called with (page & this->pagemask)
- *
- * Perform additional error status checks on erase and write failures
- * to determine if errors are correctable. For this device, correctable
+ *
+ * Perform additional error status checks on erase and write failures
+ * to determine if errors are correctable. For this device, correctable
* 1-bit errors on erase and write are considered acceptable.
*
* note: see pages 34..37 of data sheet for details.
@@ -633,7 +633,7 @@ int __init rtc_from4_init (void)
#ifdef RTC_FROM4_HWECC
/* We could create the decoder on demand, if memory is a concern.
- * This way we have it handy, if an error happens
+ * This way we have it handy, if an error happens
*
* Symbolsize is 10 (bits)
* Primitve polynomial is x^10+x^3+1
diff --git a/drivers/mtd/nand/s3c2410.c b/drivers/mtd/nand/s3c2410.c
index b47ebcb31e0f..97e9b7892d29 100644
--- a/drivers/mtd/nand/s3c2410.c
+++ b/drivers/mtd/nand/s3c2410.c
@@ -17,8 +17,9 @@
* 02-May-2005 BJD Reduced hwcontrol decode
* 20-Jun-2005 BJD Updated s3c2440 support, fixed timing bug
* 08-Jul-2005 BJD Fix OOPS when no platform data supplied
+ * 20-Oct-2005 BJD Fix timing calculation bug
*
- * $Id: s3c2410.c,v 1.14 2005/07/06 20:05:06 bjd Exp $
+ * $Id: s3c2410.c,v 1.20 2005/11/07 11:14:31 gleixner Exp $
*
* 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
@@ -48,9 +49,10 @@
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/ioport.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <linux/delay.h>
#include <linux/err.h>
+#include <linux/slab.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/nand.h>
@@ -135,13 +137,13 @@ static struct s3c2410_platform_nand *to_nand_plat(struct device *dev)
/* timing calculations */
-#define NS_IN_KHZ 10000000
+#define NS_IN_KHZ 1000000
static int s3c2410_nand_calc_rate(int wanted, unsigned long clk, int max)
{
int result;
- result = (wanted * NS_IN_KHZ) / clk;
+ result = (wanted * clk) / NS_IN_KHZ;
result++;
pr_debug("result %d from %ld, %d\n", result, clk, wanted);
@@ -158,20 +160,22 @@ static int s3c2410_nand_calc_rate(int wanted, unsigned long clk, int max)
return result;
}
-#define to_ns(ticks,clk) (((clk) * (ticks)) / NS_IN_KHZ)
+#define to_ns(ticks,clk) (((ticks) * NS_IN_KHZ) / (unsigned int)(clk))
/* controller setup */
-static int s3c2410_nand_inithw(struct s3c2410_nand_info *info,
+static int s3c2410_nand_inithw(struct s3c2410_nand_info *info,
struct device *dev)
{
struct s3c2410_platform_nand *plat = to_nand_plat(dev);
- unsigned int tacls, twrph0, twrph1;
unsigned long clkrate = clk_get_rate(info->clk);
+ int tacls, twrph0, twrph1;
unsigned long cfg;
/* calculate the timing information for the controller */
+ clkrate /= 1000; /* turn clock into kHz for ease of use */
+
if (plat != NULL) {
tacls = s3c2410_nand_calc_rate(plat->tacls, clkrate, 4);
twrph0 = s3c2410_nand_calc_rate(plat->twrph0, clkrate, 8);
@@ -182,16 +186,16 @@ static int s3c2410_nand_inithw(struct s3c2410_nand_info *info,
twrph0 = 8;
twrph1 = 8;
}
-
+
if (tacls < 0 || twrph0 < 0 || twrph1 < 0) {
printk(KERN_ERR PFX "cannot get timings suitable for board\n");
return -EINVAL;
}
- printk(KERN_INFO PFX "timing: Tacls %ldns, Twrph0 %ldns, Twrph1 %ldns\n",
- to_ns(tacls, clkrate),
- to_ns(twrph0, clkrate),
- to_ns(twrph1, clkrate));
+ printk(KERN_INFO PFX "Tacls=%d, %dns Twrph0=%d %dns, Twrph1=%d %dns\n",
+ tacls, to_ns(tacls, clkrate),
+ twrph0, to_ns(twrph0, clkrate),
+ twrph1, to_ns(twrph1, clkrate));
if (!info->is_s3c2440) {
cfg = S3C2410_NFCONF_EN;
@@ -215,7 +219,7 @@ static int s3c2410_nand_inithw(struct s3c2410_nand_info *info,
static void s3c2410_nand_select_chip(struct mtd_info *mtd, int chip)
{
struct s3c2410_nand_info *info;
- struct s3c2410_nand_mtd *nmtd;
+ struct s3c2410_nand_mtd *nmtd;
struct nand_chip *this = mtd->priv;
void __iomem *reg;
unsigned long cur;
@@ -248,7 +252,7 @@ static void s3c2410_nand_select_chip(struct mtd_info *mtd, int chip)
writel(cur, reg);
}
-/* command and control functions
+/* command and control functions
*
* Note, these all use tglx's method of changing the IO_ADDR_W field
* to make the code simpler, and use the nand layer's code to issue the
@@ -320,7 +324,7 @@ static void s3c2440_nand_hwcontrol(struct mtd_info *mtd, int cmd)
static int s3c2410_nand_devready(struct mtd_info *mtd)
{
struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd);
-
+
if (info->is_s3c2440)
return readb(info->regs + S3C2440_NFSTAT) & S3C2440_NFSTAT_READY;
return readb(info->regs + S3C2410_NFSTAT) & S3C2410_NFSTAT_BUSY;
@@ -341,7 +345,7 @@ static int s3c2410_nand_correct_data(struct mtd_info *mtd, u_char *dat,
if (read_ecc[0] == calc_ecc[0] &&
read_ecc[1] == calc_ecc[1] &&
- read_ecc[2] == calc_ecc[2])
+ read_ecc[2] == calc_ecc[2])
return 0;
/* we curently have no method for correcting the error */
@@ -432,14 +436,14 @@ static int s3c2410_nand_remove(struct device *dev)
dev_set_drvdata(dev, NULL);
- if (info == NULL)
+ if (info == NULL)
return 0;
/* first thing we need to do is release all our mtds
* and their partitions, then go through freeing the
- * resources used
+ * resources used
*/
-
+
if (info->mtds != NULL) {
struct s3c2410_nand_mtd *ptr = info->mtds;
int mtdno;
@@ -503,7 +507,7 @@ static int s3c2410_nand_add_partition(struct s3c2410_nand_info *info,
/* s3c2410_nand_init_chip
*
- * init a single instance of an chip
+ * init a single instance of an chip
*/
static void s3c2410_nand_init_chip(struct s3c2410_nand_info *info,
@@ -575,7 +579,7 @@ static int s3c24xx_nand_probe(struct device *dev, int is_s3c2440)
info = kmalloc(sizeof(*info), GFP_KERNEL);
if (info == NULL) {
- printk(KERN_ERR PFX "no memory for flash info\n");
+ dev_err(dev, "no memory for flash info\n");
err = -ENOMEM;
goto exit_error;
}
@@ -590,7 +594,7 @@ static int s3c24xx_nand_probe(struct device *dev, int is_s3c2440)
info->clk = clk_get(dev, "nand");
if (IS_ERR(info->clk)) {
- printk(KERN_ERR PFX "failed to get clock");
+ dev_err(dev, "failed to get clock");
err = -ENOENT;
goto exit_error;
}
@@ -607,7 +611,7 @@ static int s3c24xx_nand_probe(struct device *dev, int is_s3c2440)
info->area = request_mem_region(res->start, size, pdev->name);
if (info->area == NULL) {
- printk(KERN_ERR PFX "cannot reserve register region\n");
+ dev_err(dev, "cannot reserve register region\n");
err = -ENOENT;
goto exit_error;
}
@@ -618,12 +622,12 @@ static int s3c24xx_nand_probe(struct device *dev, int is_s3c2440)
info->is_s3c2440 = is_s3c2440;
if (info->regs == NULL) {
- printk(KERN_ERR PFX "cannot reserve register region\n");
+ dev_err(dev, "cannot reserve register region\n");
err = -EIO;
goto exit_error;
- }
+ }
- printk(KERN_INFO PFX "mapped registers at %p\n", info->regs);
+ dev_dbg(dev, "mapped registers at %p\n", info->regs);
/* initialise the hardware */
@@ -641,7 +645,7 @@ static int s3c24xx_nand_probe(struct device *dev, int is_s3c2440)
size = nr_sets * sizeof(*info->mtds);
info->mtds = kmalloc(size, GFP_KERNEL);
if (info->mtds == NULL) {
- printk(KERN_ERR PFX "failed to allocate mtd storage\n");
+ dev_err(dev, "failed to allocate mtd storage\n");
err = -ENOMEM;
goto exit_error;
}
@@ -655,7 +659,7 @@ static int s3c24xx_nand_probe(struct device *dev, int is_s3c2440)
for (setno = 0; setno < nr_sets; setno++, nmtd++) {
pr_debug("initialising set %d (%p, info %p)\n",
setno, nmtd, info);
-
+
s3c2410_nand_init_chip(info, nmtd, sets);
nmtd->scan_res = nand_scan(&nmtd->mtd,
@@ -668,7 +672,7 @@ static int s3c24xx_nand_probe(struct device *dev, int is_s3c2440)
if (sets != NULL)
sets++;
}
-
+
pr_debug("initialised ok\n");
return 0;
@@ -694,6 +698,7 @@ static int s3c2440_nand_probe(struct device *dev)
static struct device_driver s3c2410_nand_driver = {
.name = "s3c2410-nand",
+ .owner = THIS_MODULE,
.bus = &platform_bus_type,
.probe = s3c2410_nand_probe,
.remove = s3c2410_nand_remove,
@@ -701,6 +706,7 @@ static struct device_driver s3c2410_nand_driver = {
static struct device_driver s3c2440_nand_driver = {
.name = "s3c2440-nand",
+ .owner = THIS_MODULE,
.bus = &platform_bus_type,
.probe = s3c2440_nand_probe,
.remove = s3c2410_nand_remove,
diff --git a/drivers/mtd/nand/sharpsl.c b/drivers/mtd/nand/sharpsl.c
index 88b5b5b40b43..1924a4f137c7 100644
--- a/drivers/mtd/nand/sharpsl.c
+++ b/drivers/mtd/nand/sharpsl.c
@@ -3,7 +3,7 @@
*
* Copyright (C) 2004 Richard Purdie
*
- * $Id: sharpsl.c,v 1.4 2005/01/23 11:09:19 rpurdie Exp $
+ * $Id: sharpsl.c,v 1.7 2005/11/07 11:14:31 gleixner Exp $
*
* Based on Sharp's NAND driver sharp_sl.c
*
@@ -76,14 +76,14 @@ static struct mtd_partition sharpsl_nand_default_partition_info[] = {
},
};
-/*
+/*
* hardware specific access to control-lines
*/
static void
sharpsl_nand_hwcontrol(struct mtd_info* mtd, int cmd)
{
switch (cmd) {
- case NAND_CTL_SETCLE:
+ case NAND_CTL_SETCLE:
writeb(readb(FLASHCTL) | FLCLE, FLASHCTL);
break;
case NAND_CTL_CLRCLE:
@@ -97,10 +97,10 @@ sharpsl_nand_hwcontrol(struct mtd_info* mtd, int cmd)
writeb(readb(FLASHCTL) & ~FLALE, FLASHCTL);
break;
- case NAND_CTL_SETNCE:
+ case NAND_CTL_SETNCE:
writeb(readb(FLASHCTL) & ~(FLCE0|FLCE1), FLASHCTL);
break;
- case NAND_CTL_CLRNCE:
+ case NAND_CTL_CLRNCE:
writeb(readb(FLASHCTL) | (FLCE0|FLCE1), FLASHCTL);
break;
}
@@ -115,6 +115,23 @@ static struct nand_bbt_descr sharpsl_bbt = {
.pattern = scan_ff_pattern
};
+static struct nand_bbt_descr sharpsl_akita_bbt = {
+ .options = 0,
+ .offs = 4,
+ .len = 1,
+ .pattern = scan_ff_pattern
+};
+
+static struct nand_oobinfo akita_oobinfo = {
+ .useecc = MTD_NANDECC_AUTOPLACE,
+ .eccbytes = 24,
+ .eccpos = {
+ 0x5, 0x1, 0x2, 0x3, 0x6, 0x7, 0x15, 0x11,
+ 0x12, 0x13, 0x16, 0x17, 0x25, 0x21, 0x22, 0x23,
+ 0x26, 0x27, 0x35, 0x31, 0x32, 0x33, 0x36, 0x37},
+ .oobfree = { {0x08, 0x09} }
+};
+
static int
sharpsl_nand_dev_ready(struct mtd_info* mtd)
{
@@ -160,7 +177,7 @@ sharpsl_nand_init(void)
printk ("Unable to allocate SharpSL NAND MTD device structure.\n");
return -ENOMEM;
}
-
+
/* map physical adress */
sharpsl_io_base = ioremap(sharpsl_phys_base, 0x1000);
if(!sharpsl_io_base){
@@ -168,7 +185,7 @@ sharpsl_nand_init(void)
kfree(sharpsl_mtd);
return -EIO;
}
-
+
/* Get pointer to private data */
this = (struct nand_chip *) (&sharpsl_mtd[1]);
@@ -194,10 +211,14 @@ sharpsl_nand_init(void)
this->chip_delay = 15;
/* set eccmode using hardware ECC */
this->eccmode = NAND_ECC_HW3_256;
+ this->badblock_pattern = &sharpsl_bbt;
+ if (machine_is_akita() || machine_is_borzoi()) {
+ this->badblock_pattern = &sharpsl_akita_bbt;
+ this->autooob = &akita_oobinfo;
+ }
this->enable_hwecc = sharpsl_nand_enable_hwecc;
this->calculate_ecc = sharpsl_nand_calculate_ecc;
this->correct_data = nand_correct_data;
- this->badblock_pattern = &sharpsl_bbt;
/* Scan to find existence of the device */
err=nand_scan(sharpsl_mtd,1);
@@ -211,7 +232,7 @@ sharpsl_nand_init(void)
sharpsl_mtd->name = "sharpsl-nand";
nr_partitions = parse_mtd_partitions(sharpsl_mtd, part_probes,
&sharpsl_partition_info, 0);
-
+
if (nr_partitions <= 0) {
nr_partitions = DEFAULT_NUM_PARTITIONS;
sharpsl_partition_info = sharpsl_nand_default_partition_info;
@@ -230,7 +251,7 @@ sharpsl_nand_init(void)
}
}
- if (machine_is_husky() || machine_is_borzoi()) {
+ if (machine_is_husky() || machine_is_borzoi() || machine_is_akita()) {
/* Need to use small eraseblock size for backward compatibility */
sharpsl_mtd->flags |= MTD_NO_VIRTBLOCKS;
}
diff --git a/drivers/mtd/nand/spia.c b/drivers/mtd/nand/spia.c
index b777c412b758..32541cbb0103 100644
--- a/drivers/mtd/nand/spia.c
+++ b/drivers/mtd/nand/spia.c
@@ -8,7 +8,7 @@
* to controllines (due to change in nand.c)
* page_cache added
*
- * $Id: spia.c,v 1.24 2004/11/04 12:53:10 gleixner Exp $
+ * $Id: spia.c,v 1.25 2005/11/07 11:14:31 gleixner Exp $
*
* 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
@@ -82,7 +82,7 @@ const static struct mtd_partition partition_info[] = {
#define NUM_PARTITIONS 2
-/*
+/*
* hardware specific access to control-lines
*/
static void spia_hwcontrol(struct mtd_info *mtd, int cmd){
@@ -137,7 +137,7 @@ int __init spia_init (void)
/* Set address of hardware control function */
this->hwcontrol = spia_hwcontrol;
/* 15 us command delay time */
- this->chip_delay = 15;
+ this->chip_delay = 15;
/* Scan to find existence of the device */
if (nand_scan (spia_mtd, 1)) {
diff --git a/drivers/mtd/nand/toto.c b/drivers/mtd/nand/toto.c
index 52c808fb5fa9..7609c43cb3ec 100644
--- a/drivers/mtd/nand/toto.c
+++ b/drivers/mtd/nand/toto.c
@@ -15,7 +15,7 @@
* This is a device driver for the NAND flash device found on the
* TI fido board. It supports 32MiB and 64MiB cards
*
- * $Id: toto.c,v 1.4 2004/10/05 13:50:20 gleixner Exp $
+ * $Id: toto.c,v 1.5 2005/11/07 11:14:31 gleixner Exp $
*/
#include <linux/slab.h>
@@ -57,7 +57,7 @@ static unsigned long toto_io_base = OMAP_FLASH_1_BASE;
#endif
#define T_NAND_CTL_SETNCE(iob) gpiosetout(NAND_NCE, 0)
#define T_NAND_CTL_CLRNCE(iob) gpiosetout(NAND_NCE, NAND_NCE)
-
+
/*
* Define partitions for flash devices
*/
@@ -91,7 +91,7 @@ static struct mtd_partition partition_info32M[] = {
#define NUM_PARTITIONS32M 3
#define NUM_PARTITIONS64M 4
-/*
+/*
* hardware specific access to control-lines
*/
@@ -146,7 +146,7 @@ int __init toto_init (void)
this->hwcontrol = toto_hwcontrol;
this->dev_ready = NULL;
/* 25 us command delay time */
- this->chip_delay = 30;
+ this->chip_delay = 30;
this->eccmode = NAND_ECC_SOFT;
/* Scan to find existance of the device */
@@ -157,10 +157,10 @@ int __init toto_init (void)
/* Register the partitions */
switch(toto_mtd->size){
- case SZ_64M: add_mtd_partitions(toto_mtd, partition_info64M, NUM_PARTITIONS64M); break;
- case SZ_32M: add_mtd_partitions(toto_mtd, partition_info32M, NUM_PARTITIONS32M); break;
+ case SZ_64M: add_mtd_partitions(toto_mtd, partition_info64M, NUM_PARTITIONS64M); break;
+ case SZ_32M: add_mtd_partitions(toto_mtd, partition_info32M, NUM_PARTITIONS32M); break;
default: {
- printk (KERN_WARNING "Unsupported Nand device\n");
+ printk (KERN_WARNING "Unsupported Nand device\n");
err = -ENXIO;
goto out_buf;
}
@@ -170,9 +170,9 @@ int __init toto_init (void)
archflashwp(0,0); /* open up flash for writing */
goto out;
-
+
out_buf:
- kfree (this->data_buf);
+ kfree (this->data_buf);
out_mtd:
kfree (toto_mtd);
out:
@@ -194,7 +194,7 @@ static void __exit toto_cleanup (void)
/* stop flash writes */
archflashwp(0,1);
-
+
/* release gpios to system */
gpiorelease(NAND_MASK);
}
diff --git a/drivers/mtd/nftlcore.c b/drivers/mtd/nftlcore.c
index b2014043634f..d7cd5fa16ba4 100644
--- a/drivers/mtd/nftlcore.c
+++ b/drivers/mtd/nftlcore.c
@@ -1,7 +1,7 @@
/* Linux driver for NAND Flash Translation Layer */
/* (c) 1999 Machine Vision Holdings, Inc. */
/* Author: David Woodhouse <dwmw2@infradead.org> */
-/* $Id: nftlcore.c,v 1.97 2004/11/16 18:28:59 dwmw2 Exp $ */
+/* $Id: nftlcore.c,v 1.98 2005/11/07 11:14:21 gleixner Exp $ */
/*
The contents of this file are distributed under the GNU General
@@ -101,23 +101,21 @@ static void nftl_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
if (nftl->mbd.size != nftl->heads * nftl->cylinders * nftl->sectors) {
/*
- Oh no we don't have
+ Oh no we don't have
mbd.size == heads * cylinders * sectors
*/
printk(KERN_WARNING "NFTL: cannot calculate a geometry to "
"match size of 0x%lx.\n", nftl->mbd.size);
printk(KERN_WARNING "NFTL: using C:%d H:%d S:%d "
"(== 0x%lx sects)\n",
- nftl->cylinders, nftl->heads , nftl->sectors,
+ nftl->cylinders, nftl->heads , nftl->sectors,
(long)nftl->cylinders * (long)nftl->heads *
(long)nftl->sectors );
}
if (add_mtd_blktrans_dev(&nftl->mbd)) {
- if (nftl->ReplUnitTable)
- kfree(nftl->ReplUnitTable);
- if (nftl->EUNtable)
- kfree(nftl->EUNtable);
+ kfree(nftl->ReplUnitTable);
+ kfree(nftl->EUNtable);
kfree(nftl);
return;
}
@@ -133,10 +131,8 @@ static void nftl_remove_dev(struct mtd_blktrans_dev *dev)
DEBUG(MTD_DEBUG_LEVEL1, "NFTL: remove_dev (i=%d)\n", dev->devnum);
del_mtd_blktrans_dev(dev);
- if (nftl->ReplUnitTable)
- kfree(nftl->ReplUnitTable);
- if (nftl->EUNtable)
- kfree(nftl->EUNtable);
+ kfree(nftl->ReplUnitTable);
+ kfree(nftl->EUNtable);
kfree(nftl);
}
@@ -178,7 +174,7 @@ static u16 NFTL_findfreeblock(struct NFTLrecord *nftl, int desperate )
if (!silly--) {
printk("Argh! No free blocks found! LastFreeEUN = %d, "
- "FirstEUN = %d\n", nftl->LastFreeEUN,
+ "FirstEUN = %d\n", nftl->LastFreeEUN,
le16_to_cpu(nftl->MediaHdr.FirstPhysicalEUN));
return 0xffff;
}
@@ -210,7 +206,7 @@ static u16 NFTL_foldchain (struct NFTLrecord *nftl, unsigned thisVUC, unsigned p
"Virtual Unit Chain %d!\n", thisVUC);
return BLOCK_NIL;
}
-
+
/* Scan to find the Erase Unit which holds the actual data for each
512-byte block within the Chain.
*/
@@ -227,7 +223,7 @@ static u16 NFTL_foldchain (struct NFTLrecord *nftl, unsigned thisVUC, unsigned p
if (block == 2) {
foldmark = oob.u.c.FoldMark | oob.u.c.FoldMark1;
if (foldmark == FOLD_MARK_IN_PROGRESS) {
- DEBUG(MTD_DEBUG_LEVEL1,
+ DEBUG(MTD_DEBUG_LEVEL1,
"Write Inhibited on EUN %d\n", thisEUN);
inplace = 0;
} else {
@@ -249,7 +245,7 @@ static u16 NFTL_foldchain (struct NFTLrecord *nftl, unsigned thisVUC, unsigned p
if (!BlockFreeFound[block])
BlockMap[block] = thisEUN;
else
- printk(KERN_WARNING
+ printk(KERN_WARNING
"SECTOR_USED found after SECTOR_FREE "
"in Virtual Unit Chain %d for block %d\n",
thisVUC, block);
@@ -258,7 +254,7 @@ static u16 NFTL_foldchain (struct NFTLrecord *nftl, unsigned thisVUC, unsigned p
if (!BlockFreeFound[block])
BlockMap[block] = BLOCK_NIL;
else
- printk(KERN_WARNING
+ printk(KERN_WARNING
"SECTOR_DELETED found after SECTOR_FREE "
"in Virtual Unit Chain %d for block %d\n",
thisVUC, block);
@@ -277,14 +273,14 @@ static u16 NFTL_foldchain (struct NFTLrecord *nftl, unsigned thisVUC, unsigned p
thisVUC);
return BLOCK_NIL;
}
-
+
thisEUN = nftl->ReplUnitTable[thisEUN];
}
if (inplace) {
/* We're being asked to be a fold-in-place. Check
that all blocks which actually have data associated
- with them (i.e. BlockMap[block] != BLOCK_NIL) are
+ with them (i.e. BlockMap[block] != BLOCK_NIL) are
either already present or SECTOR_FREE in the target
block. If not, we're going to have to fold out-of-place
anyway.
@@ -297,7 +293,7 @@ static u16 NFTL_foldchain (struct NFTLrecord *nftl, unsigned thisVUC, unsigned p
"block %d was %x lastEUN, "
"and is in EUN %d (%s) %d\n",
thisVUC, block, BlockLastState[block],
- BlockMap[block],
+ BlockMap[block],
BlockMap[block]== targetEUN ? "==" : "!=",
targetEUN);
inplace = 0;
@@ -314,17 +310,17 @@ static u16 NFTL_foldchain (struct NFTLrecord *nftl, unsigned thisVUC, unsigned p
inplace = 0;
}
}
-
+
if (!inplace) {
DEBUG(MTD_DEBUG_LEVEL1, "Cannot fold Virtual Unit Chain %d in place. "
"Trying out-of-place\n", thisVUC);
/* We need to find a targetEUN to fold into. */
targetEUN = NFTL_findfreeblock(nftl, 1);
if (targetEUN == BLOCK_NIL) {
- /* Ouch. Now we're screwed. We need to do a
+ /* Ouch. Now we're screwed. We need to do a
fold-in-place of another chain to make room
for this one. We need a better way of selecting
- which chain to fold, because makefreeblock will
+ which chain to fold, because makefreeblock will
only ask us to fold the same one again.
*/
printk(KERN_WARNING
@@ -338,7 +334,7 @@ static u16 NFTL_foldchain (struct NFTLrecord *nftl, unsigned thisVUC, unsigned p
chain by selecting the longer one */
oob.u.c.FoldMark = oob.u.c.FoldMark1 = cpu_to_le16(FOLD_MARK_IN_PROGRESS);
oob.u.c.unused = 0xffffffff;
- MTD_WRITEOOB(nftl->mbd.mtd, (nftl->EraseSize * targetEUN) + 2 * 512 + 8,
+ MTD_WRITEOOB(nftl->mbd.mtd, (nftl->EraseSize * targetEUN) + 2 * 512 + 8,
8, &retlen, (char *)&oob.u);
}
@@ -361,14 +357,14 @@ static u16 NFTL_foldchain (struct NFTLrecord *nftl, unsigned thisVUC, unsigned p
happen in case of media errors or deleted blocks) */
if (BlockMap[block] == BLOCK_NIL)
continue;
-
+
ret = MTD_READ(nftl->mbd.mtd, (nftl->EraseSize * BlockMap[block]) + (block * 512),
- 512, &retlen, movebuf);
+ 512, &retlen, movebuf);
if (ret < 0) {
ret = MTD_READ(nftl->mbd.mtd, (nftl->EraseSize * BlockMap[block])
+ (block * 512), 512, &retlen,
- movebuf);
- if (ret != -EIO)
+ movebuf);
+ if (ret != -EIO)
printk("Error went away on retry.\n");
}
memset(&oob, 0xff, sizeof(struct nftl_oob));
@@ -376,18 +372,18 @@ static u16 NFTL_foldchain (struct NFTLrecord *nftl, unsigned thisVUC, unsigned p
MTD_WRITEECC(nftl->mbd.mtd, (nftl->EraseSize * targetEUN) + (block * 512),
512, &retlen, movebuf, (char *)&oob, &nftl->oobinfo);
}
-
+
/* add the header so that it is now a valid chain */
oob.u.a.VirtUnitNum = oob.u.a.SpareVirtUnitNum
= cpu_to_le16(thisVUC);
oob.u.a.ReplUnitNum = oob.u.a.SpareReplUnitNum = 0xffff;
-
- MTD_WRITEOOB(nftl->mbd.mtd, (nftl->EraseSize * targetEUN) + 8,
+
+ MTD_WRITEOOB(nftl->mbd.mtd, (nftl->EraseSize * targetEUN) + 8,
8, &retlen, (char *)&oob.u);
/* OK. We've moved the whole lot into the new block. Now we have to free the original blocks. */
- /* At this point, we have two different chains for this Virtual Unit, and no way to tell
+ /* At this point, we have two different chains for this Virtual Unit, and no way to tell
them apart. If we crash now, we get confused. However, both contain the same data, so we
shouldn't actually lose data in this case. It's just that when we load up on a medium which
has duplicate chains, we need to free one of the chains because it's not necessary any more.
@@ -395,7 +391,7 @@ static u16 NFTL_foldchain (struct NFTLrecord *nftl, unsigned thisVUC, unsigned p
thisEUN = nftl->EUNtable[thisVUC];
DEBUG(MTD_DEBUG_LEVEL1,"Want to erase\n");
- /* For each block in the old chain (except the targetEUN of course),
+ /* For each block in the old chain (except the targetEUN of course),
free it and make it available for future use */
while (thisEUN <= nftl->lastEUN && thisEUN != targetEUN) {
unsigned int EUNtmp;
@@ -413,7 +409,7 @@ static u16 NFTL_foldchain (struct NFTLrecord *nftl, unsigned thisVUC, unsigned p
}
thisEUN = EUNtmp;
}
-
+
/* Make this the new start of chain for thisVUC */
nftl->ReplUnitTable[targetEUN] = BLOCK_NIL;
nftl->EUNtable[thisVUC] = targetEUN;
@@ -423,7 +419,7 @@ static u16 NFTL_foldchain (struct NFTLrecord *nftl, unsigned thisVUC, unsigned p
static u16 NFTL_makefreeblock( struct NFTLrecord *nftl , unsigned pendingblock)
{
- /* This is the part that needs some cleverness applied.
+ /* This is the part that needs some cleverness applied.
For now, I'm doing the minimum applicable to actually
get the thing to work.
Wear-levelling and other clever stuff needs to be implemented
@@ -470,7 +466,7 @@ static u16 NFTL_makefreeblock( struct NFTLrecord *nftl , unsigned pendingblock)
return NFTL_foldchain (nftl, LongestChain, pendingblock);
}
-/* NFTL_findwriteunit: Return the unit number into which we can write
+/* NFTL_findwriteunit: Return the unit number into which we can write
for this block. Make it available if it isn't already
*/
static inline u16 NFTL_findwriteunit(struct NFTLrecord *nftl, unsigned block)
@@ -488,7 +484,7 @@ static inline u16 NFTL_findwriteunit(struct NFTLrecord *nftl, unsigned block)
a free space for the block in question.
*/
- /* This condition catches the 0x[7f]fff cases, as well as
+ /* This condition catches the 0x[7f]fff cases, as well as
being a sanity check for past-end-of-media access
*/
lastEUN = BLOCK_NIL;
@@ -503,7 +499,7 @@ static inline u16 NFTL_findwriteunit(struct NFTLrecord *nftl, unsigned block)
MTD_READOOB(nftl->mbd.mtd, (writeEUN * nftl->EraseSize) + blockofs,
8, &retlen, (char *)&bci);
-
+
DEBUG(MTD_DEBUG_LEVEL2, "Status of block %d in EUN %d is %x\n",
block , writeEUN, le16_to_cpu(bci.Status));
@@ -518,10 +514,10 @@ static inline u16 NFTL_findwriteunit(struct NFTLrecord *nftl, unsigned block)
break;
default:
// Invalid block. Don't use it any more. Must implement.
- break;
+ break;
}
-
- if (!silly--) {
+
+ if (!silly--) {
printk(KERN_WARNING
"Infinite loop in Virtual Unit Chain 0x%x\n",
thisVUC);
@@ -532,7 +528,7 @@ static inline u16 NFTL_findwriteunit(struct NFTLrecord *nftl, unsigned block)
writeEUN = nftl->ReplUnitTable[writeEUN];
}
- /* OK. We didn't find one in the existing chain, or there
+ /* OK. We didn't find one in the existing chain, or there
is no existing chain. */
/* Try to find an already-free block */
@@ -546,12 +542,12 @@ static inline u16 NFTL_findwriteunit(struct NFTLrecord *nftl, unsigned block)
/* First remember the start of this chain */
//u16 startEUN = nftl->EUNtable[thisVUC];
-
+
//printk("Write to VirtualUnitChain %d, calling makefreeblock()\n", thisVUC);
writeEUN = NFTL_makefreeblock(nftl, 0xffff);
if (writeEUN == BLOCK_NIL) {
- /* OK, we accept that the above comment is
+ /* OK, we accept that the above comment is
lying - there may have been free blocks
last time we called NFTL_findfreeblock(),
but they are reserved for when we're
@@ -562,21 +558,21 @@ static inline u16 NFTL_findwriteunit(struct NFTLrecord *nftl, unsigned block)
}
if (writeEUN == BLOCK_NIL) {
/* Ouch. This should never happen - we should
- always be able to make some room somehow.
- If we get here, we've allocated more storage
+ always be able to make some room somehow.
+ If we get here, we've allocated more storage
space than actual media, or our makefreeblock
routine is missing something.
*/
printk(KERN_WARNING "Cannot make free space.\n");
return BLOCK_NIL;
- }
+ }
//printk("Restarting scan\n");
lastEUN = BLOCK_NIL;
continue;
}
/* We've found a free block. Insert it into the chain. */
-
+
if (lastEUN != BLOCK_NIL) {
thisVUC |= 0x8000; /* It's a replacement block */
} else {
@@ -749,7 +745,7 @@ extern char nftlmountrev[];
static int __init init_nftl(void)
{
- printk(KERN_INFO "NFTL driver: nftlcore.c $Revision: 1.97 $, nftlmount.c %s\n", nftlmountrev);
+ printk(KERN_INFO "NFTL driver: nftlcore.c $Revision: 1.98 $, nftlmount.c %s\n", nftlmountrev);
return register_mtd_blktrans(&nftl_tr);
}
diff --git a/drivers/mtd/nftlmount.c b/drivers/mtd/nftlmount.c
index 84afd9029f53..3b104ebb219a 100644
--- a/drivers/mtd/nftlmount.c
+++ b/drivers/mtd/nftlmount.c
@@ -1,10 +1,10 @@
-/*
+/*
* NFTL mount code with extensive checks
*
- * Author: Fabrice Bellard (fabrice.bellard@netgem.com)
+ * Author: Fabrice Bellard (fabrice.bellard@netgem.com)
* Copyright (C) 2000 Netgem S.A.
*
- * $Id: nftlmount.c,v 1.40 2004/11/22 14:38:29 kalev Exp $
+ * $Id: nftlmount.c,v 1.41 2005/11/07 11:14:21 gleixner Exp $
*
* 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
@@ -31,7 +31,7 @@
#define SECTORSIZE 512
-char nftlmountrev[]="$Revision: 1.40 $";
+char nftlmountrev[]="$Revision: 1.41 $";
/* find_boot_record: Find the NFTL Media Header and its Spare copy which contains the
* various device information of the NFTL partition and Bad Unit Table. Update
@@ -47,7 +47,7 @@ static int find_boot_record(struct NFTLrecord *nftl)
struct NFTLMediaHeader *mh = &nftl->MediaHdr;
unsigned int i;
- /* Assume logical EraseSize == physical erasesize for starting the scan.
+ /* Assume logical EraseSize == physical erasesize for starting the scan.
We'll sort it out later if we find a MediaHeader which says otherwise */
/* Actually, we won't. The new DiskOnChip driver has already scanned
the MediaHeader and adjusted the virtual erasesize it presents in
@@ -83,9 +83,9 @@ static int find_boot_record(struct NFTLrecord *nftl)
if (retlen < 6 || memcmp(buf, "ANAND", 6)) {
/* ANAND\0 not found. Continue */
#if 0
- printk(KERN_DEBUG "ANAND header not found at 0x%x in mtd%d\n",
+ printk(KERN_DEBUG "ANAND header not found at 0x%x in mtd%d\n",
block * nftl->EraseSize, nftl->mbd.mtd->index);
-#endif
+#endif
continue;
}
@@ -103,7 +103,7 @@ static int find_boot_record(struct NFTLrecord *nftl)
*/
if (le16_to_cpu(h1.EraseMark | h1.EraseMark1) != ERASE_MARK) {
printk(KERN_NOTICE "ANAND header found at 0x%x in mtd%d, but erase mark not present (0x%04x,0x%04x instead)\n",
- block * nftl->EraseSize, nftl->mbd.mtd->index,
+ block * nftl->EraseSize, nftl->mbd.mtd->index,
le16_to_cpu(h1.EraseMark), le16_to_cpu(h1.EraseMark1));
continue;
}
@@ -175,7 +175,7 @@ device is already correct.
nftl->nb_boot_blocks = le16_to_cpu(mh->FirstPhysicalEUN);
if ((nftl->nb_boot_blocks + 2) >= nftl->nb_blocks) {
printk(KERN_NOTICE "NFTL Media Header sanity check failed:\n");
- printk(KERN_NOTICE "nb_boot_blocks (%d) + 2 > nb_blocks (%d)\n",
+ printk(KERN_NOTICE "nb_boot_blocks (%d) + 2 > nb_blocks (%d)\n",
nftl->nb_boot_blocks, nftl->nb_blocks);
return -1;
}
@@ -187,7 +187,7 @@ device is already correct.
nftl->numvunits, nftl->nb_blocks, nftl->nb_boot_blocks);
return -1;
}
-
+
nftl->mbd.size = nftl->numvunits * (nftl->EraseSize / SECTORSIZE);
/* If we're not using the last sectors in the device for some reason,
@@ -210,12 +210,12 @@ device is already correct.
printk(KERN_NOTICE "NFTL: allocation of ReplUnitTable failed\n");
return -ENOMEM;
}
-
+
/* mark the bios blocks (blocks before NFTL MediaHeader) as reserved */
for (i = 0; i < nftl->nb_boot_blocks; i++)
nftl->ReplUnitTable[i] = BLOCK_RESERVED;
/* mark all remaining blocks as potentially containing data */
- for (; i < nftl->nb_blocks; i++) {
+ for (; i < nftl->nb_blocks; i++) {
nftl->ReplUnitTable[i] = BLOCK_NOTEXPLORED;
}
@@ -245,12 +245,12 @@ The new DiskOnChip driver already scanned the bad block table. Just query it.
if (nftl->mbd.mtd->block_isbad(nftl->mbd.mtd, i * nftl->EraseSize))
nftl->ReplUnitTable[i] = BLOCK_RESERVED;
}
-
+
nftl->MediaUnit = block;
boot_record_count++;
-
+
} /* foreach (block) */
-
+
return boot_record_count?0:-1;
}
@@ -265,7 +265,7 @@ static int memcmpb(void *a, int c, int n)
}
/* check_free_sector: check if a free sector is actually FREE, i.e. All 0xff in data and oob area */
-static int check_free_sectors(struct NFTLrecord *nftl, unsigned int address, int len,
+static int check_free_sectors(struct NFTLrecord *nftl, unsigned int address, int len,
int check_oob)
{
int i;
@@ -293,7 +293,7 @@ static int check_free_sectors(struct NFTLrecord *nftl, unsigned int address, int
*
* Return: 0 when succeed, -1 on error.
*
- * ToDo: 1. Is it neceressary to check_free_sector after erasing ??
+ * ToDo: 1. Is it neceressary to check_free_sector after erasing ??
*/
int NFTL_formatblock(struct NFTLrecord *nftl, int block)
{
@@ -385,7 +385,7 @@ static void check_sectors_in_chain(struct NFTLrecord *nftl, unsigned int first_b
/* verify that the sector is really free. If not, mark
as ignore */
if (memcmpb(&bci, 0xff, 8) != 0 ||
- check_free_sectors(nftl, block * nftl->EraseSize + i * SECTORSIZE,
+ check_free_sectors(nftl, block * nftl->EraseSize + i * SECTORSIZE,
SECTORSIZE, 0) != 0) {
printk("Incorrect free sector %d in block %d: "
"marking it as ignored\n",
@@ -486,7 +486,7 @@ static int check_and_mark_free_block(struct NFTLrecord *nftl, int block)
size_t retlen;
/* check erase mark. */
- if (MTD_READOOB(nftl->mbd.mtd, block * nftl->EraseSize + SECTORSIZE + 8, 8,
+ if (MTD_READOOB(nftl->mbd.mtd, block * nftl->EraseSize + SECTORSIZE + 8, 8,
&retlen, (char *)&h1) < 0)
return -1;
@@ -501,7 +501,7 @@ static int check_and_mark_free_block(struct NFTLrecord *nftl, int block)
h1.EraseMark = cpu_to_le16(ERASE_MARK);
h1.EraseMark1 = cpu_to_le16(ERASE_MARK);
h1.WearInfo = cpu_to_le32(0);
- if (MTD_WRITEOOB(nftl->mbd.mtd, block * nftl->EraseSize + SECTORSIZE + 8, 8,
+ if (MTD_WRITEOOB(nftl->mbd.mtd, block * nftl->EraseSize + SECTORSIZE + 8, 8,
&retlen, (char *)&h1) < 0)
return -1;
} else {
@@ -582,9 +582,9 @@ int NFTL_mount(struct NFTLrecord *s)
for (;;) {
/* read the block header. If error, we format the chain */
- if (MTD_READOOB(s->mbd.mtd, block * s->EraseSize + 8, 8,
+ if (MTD_READOOB(s->mbd.mtd, block * s->EraseSize + 8, 8,
&retlen, (char *)&h0) < 0 ||
- MTD_READOOB(s->mbd.mtd, block * s->EraseSize + SECTORSIZE + 8, 8,
+ MTD_READOOB(s->mbd.mtd, block * s->EraseSize + SECTORSIZE + 8, 8,
&retlen, (char *)&h1) < 0) {
s->ReplUnitTable[block] = BLOCK_NIL;
do_format_chain = 1;
@@ -639,7 +639,7 @@ int NFTL_mount(struct NFTLrecord *s)
first_logical_block = logical_block;
} else {
if (logical_block != first_logical_block) {
- printk("Block %d: incorrect logical block: %d expected: %d\n",
+ printk("Block %d: incorrect logical block: %d expected: %d\n",
block, logical_block, first_logical_block);
/* the chain is incorrect : we must format it,
but we need to read it completly */
@@ -668,7 +668,7 @@ int NFTL_mount(struct NFTLrecord *s)
s->ReplUnitTable[block] = BLOCK_NIL;
break;
} else if (rep_block >= s->nb_blocks) {
- printk("Block %d: referencing invalid block %d\n",
+ printk("Block %d: referencing invalid block %d\n",
block, rep_block);
do_format_chain = 1;
s->ReplUnitTable[block] = BLOCK_NIL;
@@ -688,7 +688,7 @@ int NFTL_mount(struct NFTLrecord *s)
s->ReplUnitTable[block] = rep_block;
s->EUNtable[first_logical_block] = BLOCK_NIL;
} else {
- printk("Block %d: referencing block %d already in another chain\n",
+ printk("Block %d: referencing block %d already in another chain\n",
block, rep_block);
/* XXX: should handle correctly fold in progress chains */
do_format_chain = 1;
@@ -710,7 +710,7 @@ int NFTL_mount(struct NFTLrecord *s)
} else {
unsigned int first_block1, chain_to_format, chain_length1;
int fold_mark;
-
+
/* valid chain : get foldmark */
fold_mark = get_fold_mark(s, first_block);
if (fold_mark == 0) {
@@ -729,9 +729,9 @@ int NFTL_mount(struct NFTLrecord *s)
if (first_block1 != BLOCK_NIL) {
/* XXX: what to do if same length ? */
chain_length1 = calc_chain_length(s, first_block1);
- printk("Two chains at blocks %d (len=%d) and %d (len=%d)\n",
+ printk("Two chains at blocks %d (len=%d) and %d (len=%d)\n",
first_block1, chain_length1, first_block, chain_length);
-
+
if (chain_length >= chain_length1) {
chain_to_format = first_block1;
s->EUNtable[first_logical_block] = first_block;
diff --git a/drivers/mtd/onenand/Kconfig b/drivers/mtd/onenand/Kconfig
new file mode 100644
index 000000000000..126ff6bf63d5
--- /dev/null
+++ b/drivers/mtd/onenand/Kconfig
@@ -0,0 +1,38 @@
+#
+# linux/drivers/mtd/onenand/Kconfig
+#
+
+menu "OneNAND Flash Device Drivers"
+ depends on MTD != n
+
+config MTD_ONENAND
+ tristate "OneNAND Device Support"
+ depends on MTD
+ help
+ This enables support for accessing all type of OneNAND flash
+ devices. For further information see
+ <http://www.samsung.com/Products/Semiconductor/Flash/OneNAND_TM/index.htm>.
+
+config MTD_ONENAND_VERIFY_WRITE
+ bool "Verify OneNAND page writes"
+ depends on MTD_ONENAND
+ help
+ This adds an extra check when data is written to the flash. The
+ OneNAND flash device internally checks only bits transitioning
+ from 1 to 0. There is a rare possibility that even though the
+ device thinks the write was successful, a bit could have been
+ flipped accidentaly due to device wear or something else.
+
+config MTD_ONENAND_GENERIC
+ tristate "OneNAND Flash device via platform device driver"
+ depends on MTD_ONENAND && ARM
+ help
+ Support for OneNAND flash via platform device driver.
+
+config MTD_ONENAND_SYNC_READ
+ bool "OneNAND Sync. Burst Read Support"
+ depends on ARCH_OMAP
+ help
+ This enables support for Sync. Burst Read.
+
+endmenu
diff --git a/drivers/mtd/onenand/Makefile b/drivers/mtd/onenand/Makefile
new file mode 100644
index 000000000000..269cfe467345
--- /dev/null
+++ b/drivers/mtd/onenand/Makefile
@@ -0,0 +1,11 @@
+#
+# Makefile for the OneNAND MTD
+#
+
+# Core functionality.
+obj-$(CONFIG_MTD_ONENAND) += onenand.o
+
+# Board specific.
+obj-$(CONFIG_MTD_ONENAND_GENERIC) += generic.o
+
+onenand-objs = onenand_base.o onenand_bbt.o
diff --git a/drivers/mtd/onenand/generic.c b/drivers/mtd/onenand/generic.c
new file mode 100644
index 000000000000..48cce431f89f
--- /dev/null
+++ b/drivers/mtd/onenand/generic.c
@@ -0,0 +1,147 @@
+/*
+ * linux/drivers/mtd/onenand/generic.c
+ *
+ * Copyright (c) 2005 Samsung Electronics
+ * Kyungmin Park <kyungmin.park@samsung.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.
+ *
+ * Overview:
+ * This is a device driver for the OneNAND flash for generic boards.
+ */
+
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/onenand.h>
+#include <linux/mtd/partitions.h>
+
+#include <asm/io.h>
+#include <asm/mach/flash.h>
+
+#define DRIVER_NAME "onenand"
+
+
+#ifdef CONFIG_MTD_PARTITIONS
+static const char *part_probes[] = { "cmdlinepart", NULL, };
+#endif
+
+struct onenand_info {
+ struct mtd_info mtd;
+ struct mtd_partition *parts;
+ struct onenand_chip onenand;
+};
+
+static int __devinit generic_onenand_probe(struct device *dev)
+{
+ struct onenand_info *info;
+ struct platform_device *pdev = to_platform_device(dev);
+ struct onenand_platform_data *pdata = pdev->dev.platform_data;
+ struct resource *res = pdev->resource;
+ unsigned long size = res->end - res->start + 1;
+ int err;
+
+ info = kmalloc(sizeof(struct onenand_info), GFP_KERNEL);
+ if (!info)
+ return -ENOMEM;
+
+ memset(info, 0, sizeof(struct onenand_info));
+
+ if (!request_mem_region(res->start, size, dev->driver->name)) {
+ err = -EBUSY;
+ goto out_free_info;
+ }
+
+ info->onenand.base = ioremap(res->start, size);
+ if (!info->onenand.base) {
+ err = -ENOMEM;
+ goto out_release_mem_region;
+ }
+
+ info->onenand.mmcontrol = pdata->mmcontrol;
+
+ info->mtd.name = pdev->dev.bus_id;
+ info->mtd.priv = &info->onenand;
+ info->mtd.owner = THIS_MODULE;
+
+ if (onenand_scan(&info->mtd, 1)) {
+ err = -ENXIO;
+ goto out_iounmap;
+ }
+
+#ifdef CONFIG_MTD_PARTITIONS
+ err = parse_mtd_partitions(&info->mtd, part_probes, &info->parts, 0);
+ if (err > 0)
+ add_mtd_partitions(&info->mtd, info->parts, err);
+ else if (err < 0 && pdata->parts)
+ add_mtd_partitions(&info->mtd, pdata->parts, pdata->nr_parts);
+ else
+#endif
+ err = add_mtd_device(&info->mtd);
+
+ dev_set_drvdata(&pdev->dev, info);
+
+ return 0;
+
+out_iounmap:
+ iounmap(info->onenand.base);
+out_release_mem_region:
+ release_mem_region(res->start, size);
+out_free_info:
+ kfree(info);
+
+ return err;
+}
+
+static int __devexit generic_onenand_remove(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct onenand_info *info = dev_get_drvdata(&pdev->dev);
+ struct resource *res = pdev->resource;
+ unsigned long size = res->end - res->start + 1;
+
+ dev_set_drvdata(&pdev->dev, NULL);
+
+ if (info) {
+ if (info->parts)
+ del_mtd_partitions(&info->mtd);
+ else
+ del_mtd_device(&info->mtd);
+
+ onenand_release(&info->mtd);
+ release_mem_region(res->start, size);
+ iounmap(info->onenand.base);
+ kfree(info);
+ }
+
+ return 0;
+}
+
+static struct device_driver generic_onenand_driver = {
+ .name = DRIVER_NAME,
+ .bus = &platform_bus_type,
+ .probe = generic_onenand_probe,
+ .remove = __devexit_p(generic_onenand_remove),
+};
+
+MODULE_ALIAS(DRIVER_NAME);
+
+static int __init generic_onenand_init(void)
+{
+ return driver_register(&generic_onenand_driver);
+}
+
+static void __exit generic_onenand_exit(void)
+{
+ driver_unregister(&generic_onenand_driver);
+}
+
+module_init(generic_onenand_init);
+module_exit(generic_onenand_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Kyungmin Park <kyungmin.park@samsung.com>");
+MODULE_DESCRIPTION("Glue layer for OneNAND flash on generic boards");
diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c
new file mode 100644
index 000000000000..f67d5d6eb9a6
--- /dev/null
+++ b/drivers/mtd/onenand/onenand_base.c
@@ -0,0 +1,1590 @@
+/*
+ * linux/drivers/mtd/onenand/onenand_base.c
+ *
+ * Copyright (C) 2005 Samsung Electronics
+ * Kyungmin Park <kyungmin.park@samsung.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/init.h>
+#include <linux/sched.h>
+#include <linux/jiffies.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/onenand.h>
+#include <linux/mtd/partitions.h>
+
+#include <asm/io.h>
+
+/**
+ * onenand_oob_64 - oob info for large (2KB) page
+ */
+static struct nand_oobinfo onenand_oob_64 = {
+ .useecc = MTD_NANDECC_AUTOPLACE,
+ .eccbytes = 20,
+ .eccpos = {
+ 8, 9, 10, 11, 12,
+ 24, 25, 26, 27, 28,
+ 40, 41, 42, 43, 44,
+ 56, 57, 58, 59, 60,
+ },
+ .oobfree = {
+ {2, 3}, {14, 2}, {18, 3}, {30, 2},
+ {24, 3}, {46, 2}, {40, 3}, {62, 2} }
+};
+
+/**
+ * onenand_oob_32 - oob info for middle (1KB) page
+ */
+static struct nand_oobinfo onenand_oob_32 = {
+ .useecc = MTD_NANDECC_AUTOPLACE,
+ .eccbytes = 10,
+ .eccpos = {
+ 8, 9, 10, 11, 12,
+ 24, 25, 26, 27, 28,
+ },
+ .oobfree = { {2, 3}, {14, 2}, {18, 3}, {30, 2} }
+};
+
+static const unsigned char ffchars[] = {
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 16 */
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 32 */
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 48 */
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 64 */
+};
+
+/**
+ * onenand_readw - [OneNAND Interface] Read OneNAND register
+ * @param addr address to read
+ *
+ * Read OneNAND register
+ */
+static unsigned short onenand_readw(void __iomem *addr)
+{
+ return readw(addr);
+}
+
+/**
+ * onenand_writew - [OneNAND Interface] Write OneNAND register with value
+ * @param value value to write
+ * @param addr address to write
+ *
+ * Write OneNAND register with value
+ */
+static void onenand_writew(unsigned short value, void __iomem *addr)
+{
+ writew(value, addr);
+}
+
+/**
+ * onenand_block_address - [DEFAULT] Get block address
+ * @param this onenand chip data structure
+ * @param block the block
+ * @return translated block address if DDP, otherwise same
+ *
+ * Setup Start Address 1 Register (F100h)
+ */
+static int onenand_block_address(struct onenand_chip *this, int block)
+{
+ if (this->device_id & ONENAND_DEVICE_IS_DDP) {
+ /* Device Flash Core select, NAND Flash Block Address */
+ int dfs = 0;
+
+ if (block & this->density_mask)
+ dfs = 1;
+
+ return (dfs << ONENAND_DDP_SHIFT) |
+ (block & (this->density_mask - 1));
+ }
+
+ return block;
+}
+
+/**
+ * onenand_bufferram_address - [DEFAULT] Get bufferram address
+ * @param this onenand chip data structure
+ * @param block the block
+ * @return set DBS value if DDP, otherwise 0
+ *
+ * Setup Start Address 2 Register (F101h) for DDP
+ */
+static int onenand_bufferram_address(struct onenand_chip *this, int block)
+{
+ if (this->device_id & ONENAND_DEVICE_IS_DDP) {
+ /* Device BufferRAM Select */
+ int dbs = 0;
+
+ if (block & this->density_mask)
+ dbs = 1;
+
+ return (dbs << ONENAND_DDP_SHIFT);
+ }
+
+ return 0;
+}
+
+/**
+ * onenand_page_address - [DEFAULT] Get page address
+ * @param page the page address
+ * @param sector the sector address
+ * @return combined page and sector address
+ *
+ * Setup Start Address 8 Register (F107h)
+ */
+static int onenand_page_address(int page, int sector)
+{
+ /* Flash Page Address, Flash Sector Address */
+ int fpa, fsa;
+
+ fpa = page & ONENAND_FPA_MASK;
+ fsa = sector & ONENAND_FSA_MASK;
+
+ return ((fpa << ONENAND_FPA_SHIFT) | fsa);
+}
+
+/**
+ * onenand_buffer_address - [DEFAULT] Get buffer address
+ * @param dataram1 DataRAM index
+ * @param sectors the sector address
+ * @param count the number of sectors
+ * @return the start buffer value
+ *
+ * Setup Start Buffer Register (F200h)
+ */
+static int onenand_buffer_address(int dataram1, int sectors, int count)
+{
+ int bsa, bsc;
+
+ /* BufferRAM Sector Address */
+ bsa = sectors & ONENAND_BSA_MASK;
+
+ if (dataram1)
+ bsa |= ONENAND_BSA_DATARAM1; /* DataRAM1 */
+ else
+ bsa |= ONENAND_BSA_DATARAM0; /* DataRAM0 */
+
+ /* BufferRAM Sector Count */
+ bsc = count & ONENAND_BSC_MASK;
+
+ return ((bsa << ONENAND_BSA_SHIFT) | bsc);
+}
+
+/**
+ * onenand_command - [DEFAULT] Send command to OneNAND device
+ * @param mtd MTD device structure
+ * @param cmd the command to be sent
+ * @param addr offset to read from or write to
+ * @param len number of bytes to read or write
+ *
+ * Send command to OneNAND device. This function is used for middle/large page
+ * devices (1KB/2KB Bytes per page)
+ */
+static int onenand_command(struct mtd_info *mtd, int cmd, loff_t addr, size_t len)
+{
+ struct onenand_chip *this = mtd->priv;
+ int value, readcmd = 0;
+ int block, page;
+ /* Now we use page size operation */
+ int sectors = 4, count = 4;
+
+ /* Address translation */
+ switch (cmd) {
+ case ONENAND_CMD_UNLOCK:
+ case ONENAND_CMD_LOCK:
+ case ONENAND_CMD_LOCK_TIGHT:
+ block = -1;
+ page = -1;
+ break;
+
+ case ONENAND_CMD_ERASE:
+ case ONENAND_CMD_BUFFERRAM:
+ block = (int) (addr >> this->erase_shift);
+ page = -1;
+ break;
+
+ default:
+ block = (int) (addr >> this->erase_shift);
+ page = (int) (addr >> this->page_shift);
+ page &= this->page_mask;
+ break;
+ }
+
+ /* NOTE: The setting order of the registers is very important! */
+ if (cmd == ONENAND_CMD_BUFFERRAM) {
+ /* Select DataRAM for DDP */
+ value = onenand_bufferram_address(this, block);
+ this->write_word(value, this->base + ONENAND_REG_START_ADDRESS2);
+
+ /* Switch to the next data buffer */
+ ONENAND_SET_NEXT_BUFFERRAM(this);
+
+ return 0;
+ }
+
+ if (block != -1) {
+ /* Write 'DFS, FBA' of Flash */
+ value = onenand_block_address(this, block);
+ this->write_word(value, this->base + ONENAND_REG_START_ADDRESS1);
+ }
+
+ if (page != -1) {
+ int dataram;
+
+ switch (cmd) {
+ case ONENAND_CMD_READ:
+ case ONENAND_CMD_READOOB:
+ dataram = ONENAND_SET_NEXT_BUFFERRAM(this);
+ readcmd = 1;
+ break;
+
+ default:
+ dataram = ONENAND_CURRENT_BUFFERRAM(this);
+ break;
+ }
+
+ /* Write 'FPA, FSA' of Flash */
+ value = onenand_page_address(page, sectors);
+ this->write_word(value, this->base + ONENAND_REG_START_ADDRESS8);
+
+ /* Write 'BSA, BSC' of DataRAM */
+ value = onenand_buffer_address(dataram, sectors, count);
+ this->write_word(value, this->base + ONENAND_REG_START_BUFFER);
+
+ if (readcmd) {
+ /* Select DataRAM for DDP */
+ value = onenand_bufferram_address(this, block);
+ this->write_word(value, this->base + ONENAND_REG_START_ADDRESS2);
+ }
+ }
+
+ /* Interrupt clear */
+ this->write_word(ONENAND_INT_CLEAR, this->base + ONENAND_REG_INTERRUPT);
+
+ /* Write command */
+ this->write_word(cmd, this->base + ONENAND_REG_COMMAND);
+
+ return 0;
+}
+
+/**
+ * onenand_wait - [DEFAULT] wait until the command is done
+ * @param mtd MTD device structure
+ * @param state state to select the max. timeout value
+ *
+ * Wait for command done. This applies to all OneNAND command
+ * Read can take up to 30us, erase up to 2ms and program up to 350us
+ * according to general OneNAND specs
+ */
+static int onenand_wait(struct mtd_info *mtd, int state)
+{
+ struct onenand_chip * this = mtd->priv;
+ unsigned long timeout;
+ unsigned int flags = ONENAND_INT_MASTER;
+ unsigned int interrupt = 0;
+ unsigned int ctrl, ecc;
+
+ /* The 20 msec is enough */
+ timeout = jiffies + msecs_to_jiffies(20);
+ while (time_before(jiffies, timeout)) {
+ interrupt = this->read_word(this->base + ONENAND_REG_INTERRUPT);
+
+ if (interrupt & flags)
+ break;
+
+ if (state != FL_READING)
+ cond_resched();
+ }
+ /* To get correct interrupt status in timeout case */
+ interrupt = this->read_word(this->base + ONENAND_REG_INTERRUPT);
+
+ ctrl = this->read_word(this->base + ONENAND_REG_CTRL_STATUS);
+
+ if (ctrl & ONENAND_CTRL_ERROR) {
+ /* It maybe occur at initial bad block */
+ DEBUG(MTD_DEBUG_LEVEL0, "onenand_wait: controller error = 0x%04x\n", ctrl);
+ /* Clear other interrupt bits for preventing ECC error */
+ interrupt &= ONENAND_INT_MASTER;
+ }
+
+ if (ctrl & ONENAND_CTRL_LOCK) {
+ DEBUG(MTD_DEBUG_LEVEL0, "onenand_wait: it's locked error = 0x%04x\n", ctrl);
+ return -EACCES;
+ }
+
+ if (interrupt & ONENAND_INT_READ) {
+ ecc = this->read_word(this->base + ONENAND_REG_ECC_STATUS);
+ if (ecc & ONENAND_ECC_2BIT_ALL) {
+ DEBUG(MTD_DEBUG_LEVEL0, "onenand_wait: ECC error = 0x%04x\n", ecc);
+ return -EBADMSG;
+ }
+ }
+
+ return 0;
+}
+
+/**
+ * onenand_bufferram_offset - [DEFAULT] BufferRAM offset
+ * @param mtd MTD data structure
+ * @param area BufferRAM area
+ * @return offset given area
+ *
+ * Return BufferRAM offset given area
+ */
+static inline int onenand_bufferram_offset(struct mtd_info *mtd, int area)
+{
+ struct onenand_chip *this = mtd->priv;
+
+ if (ONENAND_CURRENT_BUFFERRAM(this)) {
+ if (area == ONENAND_DATARAM)
+ return mtd->oobblock;
+ if (area == ONENAND_SPARERAM)
+ return mtd->oobsize;
+ }
+
+ return 0;
+}
+
+/**
+ * onenand_read_bufferram - [OneNAND Interface] Read the bufferram area
+ * @param mtd MTD data structure
+ * @param area BufferRAM area
+ * @param buffer the databuffer to put/get data
+ * @param offset offset to read from or write to
+ * @param count number of bytes to read/write
+ *
+ * Read the BufferRAM area
+ */
+static int onenand_read_bufferram(struct mtd_info *mtd, int area,
+ unsigned char *buffer, int offset, size_t count)
+{
+ struct onenand_chip *this = mtd->priv;
+ void __iomem *bufferram;
+
+ bufferram = this->base + area;
+
+ bufferram += onenand_bufferram_offset(mtd, area);
+
+ memcpy(buffer, bufferram + offset, count);
+
+ return 0;
+}
+
+/**
+ * onenand_sync_read_bufferram - [OneNAND Interface] Read the bufferram area with Sync. Burst mode
+ * @param mtd MTD data structure
+ * @param area BufferRAM area
+ * @param buffer the databuffer to put/get data
+ * @param offset offset to read from or write to
+ * @param count number of bytes to read/write
+ *
+ * Read the BufferRAM area with Sync. Burst Mode
+ */
+static int onenand_sync_read_bufferram(struct mtd_info *mtd, int area,
+ unsigned char *buffer, int offset, size_t count)
+{
+ struct onenand_chip *this = mtd->priv;
+ void __iomem *bufferram;
+
+ bufferram = this->base + area;
+
+ bufferram += onenand_bufferram_offset(mtd, area);
+
+ this->mmcontrol(mtd, ONENAND_SYS_CFG1_SYNC_READ);
+
+ memcpy(buffer, bufferram + offset, count);
+
+ this->mmcontrol(mtd, 0);
+
+ return 0;
+}
+
+/**
+ * onenand_write_bufferram - [OneNAND Interface] Write the bufferram area
+ * @param mtd MTD data structure
+ * @param area BufferRAM area
+ * @param buffer the databuffer to put/get data
+ * @param offset offset to read from or write to
+ * @param count number of bytes to read/write
+ *
+ * Write the BufferRAM area
+ */
+static int onenand_write_bufferram(struct mtd_info *mtd, int area,
+ const unsigned char *buffer, int offset, size_t count)
+{
+ struct onenand_chip *this = mtd->priv;
+ void __iomem *bufferram;
+
+ bufferram = this->base + area;
+
+ bufferram += onenand_bufferram_offset(mtd, area);
+
+ memcpy(bufferram + offset, buffer, count);
+
+ return 0;
+}
+
+/**
+ * onenand_check_bufferram - [GENERIC] Check BufferRAM information
+ * @param mtd MTD data structure
+ * @param addr address to check
+ * @return 1 if there are valid data, otherwise 0
+ *
+ * Check bufferram if there is data we required
+ */
+static int onenand_check_bufferram(struct mtd_info *mtd, loff_t addr)
+{
+ struct onenand_chip *this = mtd->priv;
+ int block, page;
+ int i;
+
+ block = (int) (addr >> this->erase_shift);
+ page = (int) (addr >> this->page_shift);
+ page &= this->page_mask;
+
+ i = ONENAND_CURRENT_BUFFERRAM(this);
+
+ /* Is there valid data? */
+ if (this->bufferram[i].block == block &&
+ this->bufferram[i].page == page &&
+ this->bufferram[i].valid)
+ return 1;
+
+ return 0;
+}
+
+/**
+ * onenand_update_bufferram - [GENERIC] Update BufferRAM information
+ * @param mtd MTD data structure
+ * @param addr address to update
+ * @param valid valid flag
+ *
+ * Update BufferRAM information
+ */
+static int onenand_update_bufferram(struct mtd_info *mtd, loff_t addr,
+ int valid)
+{
+ struct onenand_chip *this = mtd->priv;
+ int block, page;
+ int i;
+
+ block = (int) (addr >> this->erase_shift);
+ page = (int) (addr >> this->page_shift);
+ page &= this->page_mask;
+
+ /* Invalidate BufferRAM */
+ for (i = 0; i < MAX_BUFFERRAM; i++) {
+ if (this->bufferram[i].block == block &&
+ this->bufferram[i].page == page)
+ this->bufferram[i].valid = 0;
+ }
+
+ /* Update BufferRAM */
+ i = ONENAND_CURRENT_BUFFERRAM(this);
+ this->bufferram[i].block = block;
+ this->bufferram[i].page = page;
+ this->bufferram[i].valid = valid;
+
+ return 0;
+}
+
+/**
+ * onenand_get_device - [GENERIC] Get chip for selected access
+ * @param mtd MTD device structure
+ * @param new_state the state which is requested
+ *
+ * Get the device and lock it for exclusive access
+ */
+static int onenand_get_device(struct mtd_info *mtd, int new_state)
+{
+ struct onenand_chip *this = mtd->priv;
+ DECLARE_WAITQUEUE(wait, current);
+
+ /*
+ * Grab the lock and see if the device is available
+ */
+ while (1) {
+ spin_lock(&this->chip_lock);
+ if (this->state == FL_READY) {
+ this->state = new_state;
+ spin_unlock(&this->chip_lock);
+ break;
+ }
+ if (new_state == FL_PM_SUSPENDED) {
+ spin_unlock(&this->chip_lock);
+ return (this->state == FL_PM_SUSPENDED) ? 0 : -EAGAIN;
+ }
+ set_current_state(TASK_UNINTERRUPTIBLE);
+ add_wait_queue(&this->wq, &wait);
+ spin_unlock(&this->chip_lock);
+ schedule();
+ remove_wait_queue(&this->wq, &wait);
+ }
+
+ return 0;
+}
+
+/**
+ * onenand_release_device - [GENERIC] release chip
+ * @param mtd MTD device structure
+ *
+ * Deselect, release chip lock and wake up anyone waiting on the device
+ */
+static void onenand_release_device(struct mtd_info *mtd)
+{
+ struct onenand_chip *this = mtd->priv;
+
+ /* Release the chip */
+ spin_lock(&this->chip_lock);
+ this->state = FL_READY;
+ wake_up(&this->wq);
+ spin_unlock(&this->chip_lock);
+}
+
+/**
+ * onenand_read_ecc - [MTD Interface] Read data with ECC
+ * @param mtd MTD device structure
+ * @param from offset to read from
+ * @param len number of bytes to read
+ * @param retlen pointer to variable to store the number of read bytes
+ * @param buf the databuffer to put data
+ * @param oob_buf filesystem supplied oob data buffer
+ * @param oobsel oob selection structure
+ *
+ * OneNAND read with ECC
+ */
+static int onenand_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,
+ size_t *retlen, u_char *buf,
+ u_char *oob_buf, struct nand_oobinfo *oobsel)
+{
+ struct onenand_chip *this = mtd->priv;
+ int read = 0, column;
+ int thislen;
+ int ret = 0;
+
+ DEBUG(MTD_DEBUG_LEVEL3, "onenand_read_ecc: from = 0x%08x, len = %i\n", (unsigned int) from, (int) len);
+
+ /* Do not allow reads past end of device */
+ if ((from + len) > mtd->size) {
+ DEBUG(MTD_DEBUG_LEVEL0, "onenand_read_ecc: Attempt read beyond end of device\n");
+ *retlen = 0;
+ return -EINVAL;
+ }
+
+ /* Grab the lock and see if the device is available */
+ onenand_get_device(mtd, FL_READING);
+
+ /* TODO handling oob */
+
+ while (read < len) {
+ thislen = min_t(int, mtd->oobblock, len - read);
+
+ column = from & (mtd->oobblock - 1);
+ if (column + thislen > mtd->oobblock)
+ thislen = mtd->oobblock - column;
+
+ if (!onenand_check_bufferram(mtd, from)) {
+ this->command(mtd, ONENAND_CMD_READ, from, mtd->oobblock);
+
+ ret = this->wait(mtd, FL_READING);
+ /* First copy data and check return value for ECC handling */
+ onenand_update_bufferram(mtd, from, 1);
+ }
+
+ this->read_bufferram(mtd, ONENAND_DATARAM, buf, column, thislen);
+
+ read += thislen;
+
+ if (read == len)
+ break;
+
+ if (ret) {
+ DEBUG(MTD_DEBUG_LEVEL0, "onenand_read_ecc: read failed = %d\n", ret);
+ goto out;
+ }
+
+ from += thislen;
+ buf += thislen;
+ }
+
+out:
+ /* Deselect and wake up anyone waiting on the device */
+ onenand_release_device(mtd);
+
+ /*
+ * Return success, if no ECC failures, else -EBADMSG
+ * fs driver will take care of that, because
+ * retlen == desired len and result == -EBADMSG
+ */
+ *retlen = read;
+ return ret;
+}
+
+/**
+ * onenand_read - [MTD Interface] MTD compability function for onenand_read_ecc
+ * @param mtd MTD device structure
+ * @param from offset to read from
+ * @param len number of bytes to read
+ * @param retlen pointer to variable to store the number of read bytes
+ * @param buf the databuffer to put data
+ *
+ * This function simply calls onenand_read_ecc with oob buffer and oobsel = NULL
+*/
+static int onenand_read(struct mtd_info *mtd, loff_t from, size_t len,
+ size_t *retlen, u_char *buf)
+{
+ return onenand_read_ecc(mtd, from, len, retlen, buf, NULL, NULL);
+}
+
+/**
+ * onenand_read_oob - [MTD Interface] OneNAND read out-of-band
+ * @param mtd MTD device structure
+ * @param from offset to read from
+ * @param len number of bytes to read
+ * @param retlen pointer to variable to store the number of read bytes
+ * @param buf the databuffer to put data
+ *
+ * OneNAND read out-of-band data from the spare area
+ */
+static int onenand_read_oob(struct mtd_info *mtd, loff_t from, size_t len,
+ size_t *retlen, u_char *buf)
+{
+ struct onenand_chip *this = mtd->priv;
+ int read = 0, thislen, column;
+ int ret = 0;
+
+ DEBUG(MTD_DEBUG_LEVEL3, "onenand_read_oob: from = 0x%08x, len = %i\n", (unsigned int) from, (int) len);
+
+ /* Initialize return length value */
+ *retlen = 0;
+
+ /* Do not allow reads past end of device */
+ if (unlikely((from + len) > mtd->size)) {
+ DEBUG(MTD_DEBUG_LEVEL0, "onenand_read_oob: Attempt read beyond end of device\n");
+ return -EINVAL;
+ }
+
+ /* Grab the lock and see if the device is available */
+ onenand_get_device(mtd, FL_READING);
+
+ column = from & (mtd->oobsize - 1);
+
+ while (read < len) {
+ thislen = mtd->oobsize - column;
+ thislen = min_t(int, thislen, len);
+
+ this->command(mtd, ONENAND_CMD_READOOB, from, mtd->oobsize);
+
+ onenand_update_bufferram(mtd, from, 0);
+
+ ret = this->wait(mtd, FL_READING);
+ /* First copy data and check return value for ECC handling */
+
+ this->read_bufferram(mtd, ONENAND_SPARERAM, buf, column, thislen);
+
+ read += thislen;
+
+ if (read == len)
+ break;
+
+ if (ret) {
+ DEBUG(MTD_DEBUG_LEVEL0, "onenand_read_oob: read failed = %d\n", ret);
+ goto out;
+ }
+
+ buf += thislen;
+
+ /* Read more? */
+ if (read < len) {
+ /* Page size */
+ from += mtd->oobblock;
+ column = 0;
+ }
+ }
+
+out:
+ /* Deselect and wake up anyone waiting on the device */
+ onenand_release_device(mtd);
+
+ *retlen = read;
+ return ret;
+}
+
+#ifdef CONFIG_MTD_ONENAND_VERIFY_WRITE
+/**
+ * onenand_verify_page - [GENERIC] verify the chip contents after a write
+ * @param mtd MTD device structure
+ * @param buf the databuffer to verify
+ *
+ * Check DataRAM area directly
+ */
+static int onenand_verify_page(struct mtd_info *mtd, u_char *buf, loff_t addr)
+{
+ struct onenand_chip *this = mtd->priv;
+ void __iomem *dataram0, *dataram1;
+ int ret = 0;
+
+ this->command(mtd, ONENAND_CMD_READ, addr, mtd->oobblock);
+
+ ret = this->wait(mtd, FL_READING);
+ if (ret)
+ return ret;
+
+ onenand_update_bufferram(mtd, addr, 1);
+
+ /* Check, if the two dataram areas are same */
+ dataram0 = this->base + ONENAND_DATARAM;
+ dataram1 = dataram0 + mtd->oobblock;
+
+ if (memcmp(dataram0, dataram1, mtd->oobblock))
+ return -EBADMSG;
+
+ return 0;
+}
+#else
+#define onenand_verify_page(...) (0)
+#endif
+
+#define NOTALIGNED(x) ((x & (mtd->oobblock - 1)) != 0)
+
+/**
+ * onenand_write_ecc - [MTD Interface] OneNAND write with ECC
+ * @param mtd MTD device structure
+ * @param to offset to write to
+ * @param len number of bytes to write
+ * @param retlen pointer to variable to store the number of written bytes
+ * @param buf the data to write
+ * @param eccbuf filesystem supplied oob data buffer
+ * @param oobsel oob selection structure
+ *
+ * OneNAND write with ECC
+ */
+static int onenand_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
+ size_t *retlen, const u_char *buf,
+ u_char *eccbuf, struct nand_oobinfo *oobsel)
+{
+ struct onenand_chip *this = mtd->priv;
+ int written = 0;
+ int ret = 0;
+
+ DEBUG(MTD_DEBUG_LEVEL3, "onenand_write_ecc: to = 0x%08x, len = %i\n", (unsigned int) to, (int) len);
+
+ /* Initialize retlen, in case of early exit */
+ *retlen = 0;
+
+ /* Do not allow writes past end of device */
+ if (unlikely((to + len) > mtd->size)) {
+ DEBUG(MTD_DEBUG_LEVEL0, "onenand_write_ecc: Attempt write to past end of device\n");
+ return -EINVAL;
+ }
+
+ /* Reject writes, which are not page aligned */
+ if (unlikely(NOTALIGNED(to)) || unlikely(NOTALIGNED(len))) {
+ DEBUG(MTD_DEBUG_LEVEL0, "onenand_write_ecc: Attempt to write not page aligned data\n");
+ return -EINVAL;
+ }
+
+ /* Grab the lock and see if the device is available */
+ onenand_get_device(mtd, FL_WRITING);
+
+ /* Loop until all data write */
+ while (written < len) {
+ int thislen = min_t(int, mtd->oobblock, len - written);
+
+ this->command(mtd, ONENAND_CMD_BUFFERRAM, to, mtd->oobblock);
+
+ this->write_bufferram(mtd, ONENAND_DATARAM, buf, 0, thislen);
+ this->write_bufferram(mtd, ONENAND_SPARERAM, ffchars, 0, mtd->oobsize);
+
+ this->command(mtd, ONENAND_CMD_PROG, to, mtd->oobblock);
+
+ onenand_update_bufferram(mtd, to, 1);
+
+ ret = this->wait(mtd, FL_WRITING);
+ if (ret) {
+ DEBUG(MTD_DEBUG_LEVEL0, "onenand_write_ecc: write filaed %d\n", ret);
+ goto out;
+ }
+
+ written += thislen;
+
+ /* Only check verify write turn on */
+ ret = onenand_verify_page(mtd, (u_char *) buf, to);
+ if (ret) {
+ DEBUG(MTD_DEBUG_LEVEL0, "onenand_write_ecc: verify failed %d\n", ret);
+ goto out;
+ }
+
+ if (written == len)
+ break;
+
+ to += thislen;
+ buf += thislen;
+ }
+
+out:
+ /* Deselect and wake up anyone waiting on the device */
+ onenand_release_device(mtd);
+
+ *retlen = written;
+
+ return ret;
+}
+
+/**
+ * onenand_write - [MTD Interface] compability function for onenand_write_ecc
+ * @param mtd MTD device structure
+ * @param to offset to write to
+ * @param len number of bytes to write
+ * @param retlen pointer to variable to store the number of written bytes
+ * @param buf the data to write
+ *
+ * This function simply calls onenand_write_ecc
+ * with oob buffer and oobsel = NULL
+ */
+static int onenand_write(struct mtd_info *mtd, loff_t to, size_t len,
+ size_t *retlen, const u_char *buf)
+{
+ return onenand_write_ecc(mtd, to, len, retlen, buf, NULL, NULL);
+}
+
+/**
+ * onenand_write_oob - [MTD Interface] OneNAND write out-of-band
+ * @param mtd MTD device structure
+ * @param to offset to write to
+ * @param len number of bytes to write
+ * @param retlen pointer to variable to store the number of written bytes
+ * @param buf the data to write
+ *
+ * OneNAND write out-of-band
+ */
+static int onenand_write_oob(struct mtd_info *mtd, loff_t to, size_t len,
+ size_t *retlen, const u_char *buf)
+{
+ struct onenand_chip *this = mtd->priv;
+ int column, status;
+ int written = 0;
+
+ DEBUG(MTD_DEBUG_LEVEL3, "onenand_write_oob: to = 0x%08x, len = %i\n", (unsigned int) to, (int) len);
+
+ /* Initialize retlen, in case of early exit */
+ *retlen = 0;
+
+ /* Do not allow writes past end of device */
+ if (unlikely((to + len) > mtd->size)) {
+ DEBUG(MTD_DEBUG_LEVEL0, "onenand_write_oob: Attempt write to past end of device\n");
+ return -EINVAL;
+ }
+
+ /* Grab the lock and see if the device is available */
+ onenand_get_device(mtd, FL_WRITING);
+
+ /* Loop until all data write */
+ while (written < len) {
+ int thislen = min_t(int, mtd->oobsize, len - written);
+
+ column = to & (mtd->oobsize - 1);
+
+ this->command(mtd, ONENAND_CMD_BUFFERRAM, to, mtd->oobsize);
+
+ this->write_bufferram(mtd, ONENAND_SPARERAM, ffchars, 0, mtd->oobsize);
+ this->write_bufferram(mtd, ONENAND_SPARERAM, buf, column, thislen);
+
+ this->command(mtd, ONENAND_CMD_PROGOOB, to, mtd->oobsize);
+
+ onenand_update_bufferram(mtd, to, 0);
+
+ status = this->wait(mtd, FL_WRITING);
+ if (status)
+ goto out;
+
+ written += thislen;
+
+ if (written == len)
+ break;
+
+ to += thislen;
+ buf += thislen;
+ }
+
+out:
+ /* Deselect and wake up anyone waiting on the device */
+ onenand_release_device(mtd);
+
+ *retlen = written;
+
+ return 0;
+}
+
+/**
+ * onenand_writev_ecc - [MTD Interface] write with iovec with ecc
+ * @param mtd MTD device structure
+ * @param vecs the iovectors to write
+ * @param count number of vectors
+ * @param to offset to write to
+ * @param retlen pointer to variable to store the number of written bytes
+ * @param eccbuf filesystem supplied oob data buffer
+ * @param oobsel oob selection structure
+ *
+ * OneNAND write with iovec with ecc
+ */
+static int onenand_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs,
+ unsigned long count, loff_t to, size_t *retlen,
+ u_char *eccbuf, struct nand_oobinfo *oobsel)
+{
+ struct onenand_chip *this = mtd->priv;
+ unsigned char buffer[MAX_ONENAND_PAGESIZE], *pbuf;
+ size_t total_len, len;
+ int i, written = 0;
+ int ret = 0;
+
+ /* Preset written len for early exit */
+ *retlen = 0;
+
+ /* Calculate total length of data */
+ total_len = 0;
+ for (i = 0; i < count; i++)
+ total_len += vecs[i].iov_len;
+
+ DEBUG(MTD_DEBUG_LEVEL3, "onenand_writev_ecc: to = 0x%08x, len = %i, count = %ld\n", (unsigned int) to, (unsigned int) total_len, count);
+
+ /* Do not allow write past end of the device */
+ if (unlikely((to + total_len) > mtd->size)) {
+ DEBUG(MTD_DEBUG_LEVEL0, "onenand_writev_ecc: Attempted write past end of device\n");
+ return -EINVAL;
+ }
+
+ /* Reject writes, which are not page aligned */
+ if (unlikely(NOTALIGNED(to)) || unlikely(NOTALIGNED(total_len))) {
+ DEBUG(MTD_DEBUG_LEVEL0, "onenand_writev_ecc: Attempt to write not page aligned data\n");
+ return -EINVAL;
+ }
+
+ /* Grab the lock and see if the device is available */
+ onenand_get_device(mtd, FL_WRITING);
+
+ /* TODO handling oob */
+
+ /* Loop until all keve's data has been written */
+ len = 0;
+ while (count) {
+ pbuf = buffer;
+ /*
+ * If the given tuple is >= pagesize then
+ * write it out from the iov
+ */
+ if ((vecs->iov_len - len) >= mtd->oobblock) {
+ pbuf = vecs->iov_base + len;
+
+ len += mtd->oobblock;
+
+ /* Check, if we have to switch to the next tuple */
+ if (len >= (int) vecs->iov_len) {
+ vecs++;
+ len = 0;
+ count--;
+ }
+ } else {
+ int cnt = 0, thislen;
+ while (cnt < mtd->oobblock) {
+ thislen = min_t(int, mtd->oobblock - cnt, vecs->iov_len - len);
+ memcpy(buffer + cnt, vecs->iov_base + len, thislen);
+ cnt += thislen;
+ len += thislen;
+
+ /* Check, if we have to switch to the next tuple */
+ if (len >= (int) vecs->iov_len) {
+ vecs++;
+ len = 0;
+ count--;
+ }
+ }
+ }
+
+ this->command(mtd, ONENAND_CMD_BUFFERRAM, to, mtd->oobblock);
+
+ this->write_bufferram(mtd, ONENAND_DATARAM, pbuf, 0, mtd->oobblock);
+ this->write_bufferram(mtd, ONENAND_SPARERAM, ffchars, 0, mtd->oobsize);
+
+ this->command(mtd, ONENAND_CMD_PROG, to, mtd->oobblock);
+
+ onenand_update_bufferram(mtd, to, 1);
+
+ ret = this->wait(mtd, FL_WRITING);
+ if (ret) {
+ DEBUG(MTD_DEBUG_LEVEL0, "onenand_writev_ecc: write failed %d\n", ret);
+ goto out;
+ }
+
+
+ /* Only check verify write turn on */
+ ret = onenand_verify_page(mtd, (u_char *) pbuf, to);
+ if (ret) {
+ DEBUG(MTD_DEBUG_LEVEL0, "onenand_writev_ecc: verify failed %d\n", ret);
+ goto out;
+ }
+
+ written += mtd->oobblock;
+
+ to += mtd->oobblock;
+ }
+
+out:
+ /* Deselect and wakt up anyone waiting on the device */
+ onenand_release_device(mtd);
+
+ *retlen = written;
+
+ return 0;
+}
+
+/**
+ * onenand_writev - [MTD Interface] compabilty function for onenand_writev_ecc
+ * @param mtd MTD device structure
+ * @param vecs the iovectors to write
+ * @param count number of vectors
+ * @param to offset to write to
+ * @param retlen pointer to variable to store the number of written bytes
+ *
+ * OneNAND write with kvec. This just calls the ecc function
+ */
+static int onenand_writev(struct mtd_info *mtd, const struct kvec *vecs,
+ unsigned long count, loff_t to, size_t *retlen)
+{
+ return onenand_writev_ecc(mtd, vecs, count, to, retlen, NULL, NULL);
+}
+
+/**
+ * onenand_block_checkbad - [GENERIC] Check if a block is marked bad
+ * @param mtd MTD device structure
+ * @param ofs offset from device start
+ * @param getchip 0, if the chip is already selected
+ * @param allowbbt 1, if its allowed to access the bbt area
+ *
+ * Check, if the block is bad. Either by reading the bad block table or
+ * calling of the scan function.
+ */
+static int onenand_block_checkbad(struct mtd_info *mtd, loff_t ofs, int getchip, int allowbbt)
+{
+ struct onenand_chip *this = mtd->priv;
+ struct bbm_info *bbm = this->bbm;
+
+ /* Return info from the table */
+ return bbm->isbad_bbt(mtd, ofs, allowbbt);
+}
+
+/**
+ * onenand_erase - [MTD Interface] erase block(s)
+ * @param mtd MTD device structure
+ * @param instr erase instruction
+ *
+ * Erase one ore more blocks
+ */
+static int onenand_erase(struct mtd_info *mtd, struct erase_info *instr)
+{
+ struct onenand_chip *this = mtd->priv;
+ unsigned int block_size;
+ loff_t addr;
+ int len;
+ int ret = 0;
+
+ DEBUG(MTD_DEBUG_LEVEL3, "onenand_erase: start = 0x%08x, len = %i\n", (unsigned int) instr->addr, (unsigned int) instr->len);
+
+ block_size = (1 << this->erase_shift);
+
+ /* Start address must align on block boundary */
+ if (unlikely(instr->addr & (block_size - 1))) {
+ DEBUG(MTD_DEBUG_LEVEL0, "onenand_erase: Unaligned address\n");
+ return -EINVAL;
+ }
+
+ /* Length must align on block boundary */
+ if (unlikely(instr->len & (block_size - 1))) {
+ DEBUG(MTD_DEBUG_LEVEL0, "onenand_erase: Length not block aligned\n");
+ return -EINVAL;
+ }
+
+ /* Do not allow erase past end of device */
+ if (unlikely((instr->len + instr->addr) > mtd->size)) {
+ DEBUG(MTD_DEBUG_LEVEL0, "onenand_erase: Erase past end of device\n");
+ return -EINVAL;
+ }
+
+ instr->fail_addr = 0xffffffff;
+
+ /* Grab the lock and see if the device is available */
+ onenand_get_device(mtd, FL_ERASING);
+
+ /* Loop throught the pages */
+ len = instr->len;
+ addr = instr->addr;
+
+ instr->state = MTD_ERASING;
+
+ while (len) {
+
+ /* Check if we have a bad block, we do not erase bad blocks */
+ if (onenand_block_checkbad(mtd, addr, 0, 0)) {
+ printk (KERN_WARNING "onenand_erase: attempt to erase a bad block at addr 0x%08x\n", (unsigned int) addr);
+ instr->state = MTD_ERASE_FAILED;
+ goto erase_exit;
+ }
+
+ this->command(mtd, ONENAND_CMD_ERASE, addr, block_size);
+
+ ret = this->wait(mtd, FL_ERASING);
+ /* Check, if it is write protected */
+ if (ret) {
+ if (ret == -EPERM)
+ DEBUG(MTD_DEBUG_LEVEL0, "onenand_erase: Device is write protected!!!\n");
+ else
+ DEBUG(MTD_DEBUG_LEVEL0, "onenand_erase: Failed erase, block %d\n", (unsigned) (addr >> this->erase_shift));
+ instr->state = MTD_ERASE_FAILED;
+ instr->fail_addr = addr;
+ goto erase_exit;
+ }
+
+ len -= block_size;
+ addr += block_size;
+ }
+
+ instr->state = MTD_ERASE_DONE;
+
+erase_exit:
+
+ ret = instr->state == MTD_ERASE_DONE ? 0 : -EIO;
+ /* Do call back function */
+ if (!ret)
+ mtd_erase_callback(instr);
+
+ /* Deselect and wake up anyone waiting on the device */
+ onenand_release_device(mtd);
+
+ return ret;
+}
+
+/**
+ * onenand_sync - [MTD Interface] sync
+ * @param mtd MTD device structure
+ *
+ * Sync is actually a wait for chip ready function
+ */
+static void onenand_sync(struct mtd_info *mtd)
+{
+ DEBUG(MTD_DEBUG_LEVEL3, "onenand_sync: called\n");
+
+ /* Grab the lock and see if the device is available */
+ onenand_get_device(mtd, FL_SYNCING);
+
+ /* Release it and go back */
+ onenand_release_device(mtd);
+}
+
+
+/**
+ * onenand_block_isbad - [MTD Interface] Check whether the block at the given offset is bad
+ * @param mtd MTD device structure
+ * @param ofs offset relative to mtd start
+ *
+ * Check whether the block is bad
+ */
+static int onenand_block_isbad(struct mtd_info *mtd, loff_t ofs)
+{
+ /* Check for invalid offset */
+ if (ofs > mtd->size)
+ return -EINVAL;
+
+ return onenand_block_checkbad(mtd, ofs, 1, 0);
+}
+
+/**
+ * onenand_default_block_markbad - [DEFAULT] mark a block bad
+ * @param mtd MTD device structure
+ * @param ofs offset from device start
+ *
+ * This is the default implementation, which can be overridden by
+ * a hardware specific driver.
+ */
+static int onenand_default_block_markbad(struct mtd_info *mtd, loff_t ofs)
+{
+ struct onenand_chip *this = mtd->priv;
+ struct bbm_info *bbm = this->bbm;
+ u_char buf[2] = {0, 0};
+ size_t retlen;
+ int block;
+
+ /* Get block number */
+ block = ((int) ofs) >> bbm->bbt_erase_shift;
+ if (bbm->bbt)
+ bbm->bbt[block >> 2] |= 0x01 << ((block & 0x03) << 1);
+
+ /* We write two bytes, so we dont have to mess with 16 bit access */
+ ofs += mtd->oobsize + (bbm->badblockpos & ~0x01);
+ return mtd->write_oob(mtd, ofs , 2, &retlen, buf);
+}
+
+/**
+ * onenand_block_markbad - [MTD Interface] Mark the block at the given offset as bad
+ * @param mtd MTD device structure
+ * @param ofs offset relative to mtd start
+ *
+ * Mark the block as bad
+ */
+static int onenand_block_markbad(struct mtd_info *mtd, loff_t ofs)
+{
+ struct onenand_chip *this = mtd->priv;
+ int ret;
+
+ ret = onenand_block_isbad(mtd, ofs);
+ if (ret) {
+ /* If it was bad already, return success and do nothing */
+ if (ret > 0)
+ return 0;
+ return ret;
+ }
+
+ return this->block_markbad(mtd, ofs);
+}
+
+/**
+ * onenand_unlock - [MTD Interface] Unlock block(s)
+ * @param mtd MTD device structure
+ * @param ofs offset relative to mtd start
+ * @param len number of bytes to unlock
+ *
+ * Unlock one or more blocks
+ */
+static int onenand_unlock(struct mtd_info *mtd, loff_t ofs, size_t len)
+{
+ struct onenand_chip *this = mtd->priv;
+ int start, end, block, value, status;
+
+ start = ofs >> this->erase_shift;
+ end = len >> this->erase_shift;
+
+ /* Continuous lock scheme */
+ if (this->options & ONENAND_CONT_LOCK) {
+ /* Set start block address */
+ this->write_word(start, this->base + ONENAND_REG_START_BLOCK_ADDRESS);
+ /* Set end block address */
+ this->write_word(end - 1, this->base + ONENAND_REG_END_BLOCK_ADDRESS);
+ /* Write unlock command */
+ this->command(mtd, ONENAND_CMD_UNLOCK, 0, 0);
+
+ /* There's no return value */
+ this->wait(mtd, FL_UNLOCKING);
+
+ /* Sanity check */
+ while (this->read_word(this->base + ONENAND_REG_CTRL_STATUS)
+ & ONENAND_CTRL_ONGO)
+ continue;
+
+ /* Check lock status */
+ status = this->read_word(this->base + ONENAND_REG_WP_STATUS);
+ if (!(status & ONENAND_WP_US))
+ printk(KERN_ERR "wp status = 0x%x\n", status);
+
+ return 0;
+ }
+
+ /* Block lock scheme */
+ for (block = start; block < end; block++) {
+ /* Set start block address */
+ this->write_word(block, this->base + ONENAND_REG_START_BLOCK_ADDRESS);
+ /* Write unlock command */
+ this->command(mtd, ONENAND_CMD_UNLOCK, 0, 0);
+
+ /* There's no return value */
+ this->wait(mtd, FL_UNLOCKING);
+
+ /* Sanity check */
+ while (this->read_word(this->base + ONENAND_REG_CTRL_STATUS)
+ & ONENAND_CTRL_ONGO)
+ continue;
+
+ /* Set block address for read block status */
+ value = onenand_block_address(this, block);
+ this->write_word(value, this->base + ONENAND_REG_START_ADDRESS1);
+
+ /* Check lock status */
+ status = this->read_word(this->base + ONENAND_REG_WP_STATUS);
+ if (!(status & ONENAND_WP_US))
+ printk(KERN_ERR "block = %d, wp status = 0x%x\n", block, status);
+ }
+
+ return 0;
+}
+
+/**
+ * onenand_print_device_info - Print device ID
+ * @param device device ID
+ *
+ * Print device ID
+ */
+static void onenand_print_device_info(int device)
+{
+ int vcc, demuxed, ddp, density;
+
+ vcc = device & ONENAND_DEVICE_VCC_MASK;
+ demuxed = device & ONENAND_DEVICE_IS_DEMUX;
+ ddp = device & ONENAND_DEVICE_IS_DDP;
+ density = device >> ONENAND_DEVICE_DENSITY_SHIFT;
+ printk(KERN_INFO "%sOneNAND%s %dMB %sV 16-bit (0x%02x)\n",
+ demuxed ? "" : "Muxed ",
+ ddp ? "(DDP)" : "",
+ (16 << density),
+ vcc ? "2.65/3.3" : "1.8",
+ device);
+}
+
+static const struct onenand_manufacturers onenand_manuf_ids[] = {
+ {ONENAND_MFR_SAMSUNG, "Samsung"},
+ {ONENAND_MFR_UNKNOWN, "Unknown"}
+};
+
+/**
+ * onenand_check_maf - Check manufacturer ID
+ * @param manuf manufacturer ID
+ *
+ * Check manufacturer ID
+ */
+static int onenand_check_maf(int manuf)
+{
+ int i;
+
+ for (i = 0; onenand_manuf_ids[i].id; i++) {
+ if (manuf == onenand_manuf_ids[i].id)
+ break;
+ }
+
+ printk(KERN_DEBUG "OneNAND Manufacturer: %s (0x%0x)\n",
+ onenand_manuf_ids[i].name, manuf);
+
+ return (i != ONENAND_MFR_UNKNOWN);
+}
+
+/**
+ * onenand_probe - [OneNAND Interface] Probe the OneNAND device
+ * @param mtd MTD device structure
+ *
+ * OneNAND detection method:
+ * Compare the the values from command with ones from register
+ */
+static int onenand_probe(struct mtd_info *mtd)
+{
+ struct onenand_chip *this = mtd->priv;
+ int bram_maf_id, bram_dev_id, maf_id, dev_id;
+ int version_id;
+ int density;
+
+ /* Send the command for reading device ID from BootRAM */
+ this->write_word(ONENAND_CMD_READID, this->base + ONENAND_BOOTRAM);
+
+ /* Read manufacturer and device IDs from BootRAM */
+ bram_maf_id = this->read_word(this->base + ONENAND_BOOTRAM + 0x0);
+ bram_dev_id = this->read_word(this->base + ONENAND_BOOTRAM + 0x2);
+
+ /* Check manufacturer ID */
+ if (onenand_check_maf(bram_maf_id))
+ return -ENXIO;
+
+ /* Reset OneNAND to read default register values */
+ this->write_word(ONENAND_CMD_RESET, this->base + ONENAND_BOOTRAM);
+
+ /* Read manufacturer and device IDs from Register */
+ maf_id = this->read_word(this->base + ONENAND_REG_MANUFACTURER_ID);
+ dev_id = this->read_word(this->base + ONENAND_REG_DEVICE_ID);
+
+ /* Check OneNAND device */
+ if (maf_id != bram_maf_id || dev_id != bram_dev_id)
+ return -ENXIO;
+
+ /* Flash device information */
+ onenand_print_device_info(dev_id);
+ this->device_id = dev_id;
+
+ density = dev_id >> ONENAND_DEVICE_DENSITY_SHIFT;
+ this->chipsize = (16 << density) << 20;
+ /* Set density mask. it is used for DDP */
+ this->density_mask = (1 << (density + 6));
+
+ /* OneNAND page size & block size */
+ /* The data buffer size is equal to page size */
+ mtd->oobblock = this->read_word(this->base + ONENAND_REG_DATA_BUFFER_SIZE);
+ mtd->oobsize = mtd->oobblock >> 5;
+ /* Pagers per block is always 64 in OneNAND */
+ mtd->erasesize = mtd->oobblock << 6;
+
+ this->erase_shift = ffs(mtd->erasesize) - 1;
+ this->page_shift = ffs(mtd->oobblock) - 1;
+ this->ppb_shift = (this->erase_shift - this->page_shift);
+ this->page_mask = (mtd->erasesize / mtd->oobblock) - 1;
+
+ /* REVIST: Multichip handling */
+
+ mtd->size = this->chipsize;
+
+ /* Version ID */
+ version_id = this->read_word(this->base + ONENAND_REG_VERSION_ID);
+ printk(KERN_DEBUG "OneNAND version = 0x%04x\n", version_id);
+
+ /* Lock scheme */
+ if (density <= ONENAND_DEVICE_DENSITY_512Mb &&
+ !(version_id >> ONENAND_VERSION_PROCESS_SHIFT)) {
+ printk(KERN_INFO "Lock scheme is Continues Lock\n");
+ this->options |= ONENAND_CONT_LOCK;
+ }
+
+ return 0;
+}
+
+/**
+ * onenand_suspend - [MTD Interface] Suspend the OneNAND flash
+ * @param mtd MTD device structure
+ */
+static int onenand_suspend(struct mtd_info *mtd)
+{
+ return onenand_get_device(mtd, FL_PM_SUSPENDED);
+}
+
+/**
+ * onenand_resume - [MTD Interface] Resume the OneNAND flash
+ * @param mtd MTD device structure
+ */
+static void onenand_resume(struct mtd_info *mtd)
+{
+ struct onenand_chip *this = mtd->priv;
+
+ if (this->state == FL_PM_SUSPENDED)
+ onenand_release_device(mtd);
+ else
+ printk(KERN_ERR "resume() called for the chip which is not"
+ "in suspended state\n");
+}
+
+
+/**
+ * onenand_scan - [OneNAND Interface] Scan for the OneNAND device
+ * @param mtd MTD device structure
+ * @param maxchips Number of chips to scan for
+ *
+ * This fills out all the not initialized function pointers
+ * with the defaults.
+ * The flash ID is read and the mtd/chip structures are
+ * filled with the appropriate values.
+ */
+int onenand_scan(struct mtd_info *mtd, int maxchips)
+{
+ struct onenand_chip *this = mtd->priv;
+
+ if (!this->read_word)
+ this->read_word = onenand_readw;
+ if (!this->write_word)
+ this->write_word = onenand_writew;
+
+ if (!this->command)
+ this->command = onenand_command;
+ if (!this->wait)
+ this->wait = onenand_wait;
+
+ if (!this->read_bufferram)
+ this->read_bufferram = onenand_read_bufferram;
+ if (!this->write_bufferram)
+ this->write_bufferram = onenand_write_bufferram;
+
+ if (!this->block_markbad)
+ this->block_markbad = onenand_default_block_markbad;
+ if (!this->scan_bbt)
+ this->scan_bbt = onenand_default_bbt;
+
+ if (onenand_probe(mtd))
+ return -ENXIO;
+
+ /* Set Sync. Burst Read after probing */
+ if (this->mmcontrol) {
+ printk(KERN_INFO "OneNAND Sync. Burst Read support\n");
+ this->read_bufferram = onenand_sync_read_bufferram;
+ }
+
+ this->state = FL_READY;
+ init_waitqueue_head(&this->wq);
+ spin_lock_init(&this->chip_lock);
+
+ switch (mtd->oobsize) {
+ case 64:
+ this->autooob = &onenand_oob_64;
+ break;
+
+ case 32:
+ this->autooob = &onenand_oob_32;
+ break;
+
+ default:
+ printk(KERN_WARNING "No OOB scheme defined for oobsize %d\n",
+ mtd->oobsize);
+ /* To prevent kernel oops */
+ this->autooob = &onenand_oob_32;
+ break;
+ }
+
+ memcpy(&mtd->oobinfo, this->autooob, sizeof(mtd->oobinfo));
+
+ /* Fill in remaining MTD driver data */
+ mtd->type = MTD_NANDFLASH;
+ mtd->flags = MTD_CAP_NANDFLASH | MTD_ECC;
+ mtd->ecctype = MTD_ECC_SW;
+ mtd->erase = onenand_erase;
+ mtd->point = NULL;
+ mtd->unpoint = NULL;
+ mtd->read = onenand_read;
+ mtd->write = onenand_write;
+ mtd->read_ecc = onenand_read_ecc;
+ mtd->write_ecc = onenand_write_ecc;
+ mtd->read_oob = onenand_read_oob;
+ mtd->write_oob = onenand_write_oob;
+ mtd->readv = NULL;
+ mtd->readv_ecc = NULL;
+ mtd->writev = onenand_writev;
+ mtd->writev_ecc = onenand_writev_ecc;
+ mtd->sync = onenand_sync;
+ mtd->lock = NULL;
+ mtd->unlock = onenand_unlock;
+ mtd->suspend = onenand_suspend;
+ mtd->resume = onenand_resume;
+ mtd->block_isbad = onenand_block_isbad;
+ mtd->block_markbad = onenand_block_markbad;
+ mtd->owner = THIS_MODULE;
+
+ /* Unlock whole block */
+ mtd->unlock(mtd, 0x0, this->chipsize);
+
+ return this->scan_bbt(mtd);
+}
+
+/**
+ * onenand_release - [OneNAND Interface] Free resources held by the OneNAND device
+ * @param mtd MTD device structure
+ */
+void onenand_release(struct mtd_info *mtd)
+{
+#ifdef CONFIG_MTD_PARTITIONS
+ /* Deregister partitions */
+ del_mtd_partitions (mtd);
+#endif
+ /* Deregister the device */
+ del_mtd_device (mtd);
+}
+
+EXPORT_SYMBOL_GPL(onenand_scan);
+EXPORT_SYMBOL_GPL(onenand_release);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Kyungmin Park <kyungmin.park@samsung.com>");
+MODULE_DESCRIPTION("Generic OneNAND flash driver code");
diff --git a/drivers/mtd/onenand/onenand_bbt.c b/drivers/mtd/onenand/onenand_bbt.c
new file mode 100644
index 000000000000..f40190f499e1
--- /dev/null
+++ b/drivers/mtd/onenand/onenand_bbt.c
@@ -0,0 +1,246 @@
+/*
+ * linux/drivers/mtd/onenand/onenand_bbt.c
+ *
+ * Bad Block Table support for the OneNAND driver
+ *
+ * Copyright(c) 2005 Samsung Electronics
+ * Kyungmin Park <kyungmin.park@samsung.com>
+ *
+ * Derived from nand_bbt.c
+ *
+ * TODO:
+ * Split BBT core and chip specific BBT.
+ */
+
+#include <linux/slab.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/onenand.h>
+#include <linux/mtd/compatmac.h>
+
+/**
+ * check_short_pattern - [GENERIC] check if a pattern is in the buffer
+ * @param buf the buffer to search
+ * @param len the length of buffer to search
+ * @param paglen the pagelength
+ * @param td search pattern descriptor
+ *
+ * Check for a pattern at the given place. Used to search bad block
+ * tables and good / bad block identifiers. Same as check_pattern, but
+ * no optional empty check and the pattern is expected to start
+ * at offset 0.
+ *
+ */
+static int check_short_pattern(uint8_t *buf, int len, int paglen, struct nand_bbt_descr *td)
+{
+ int i;
+ uint8_t *p = buf;
+
+ /* Compare the pattern */
+ for (i = 0; i < td->len; i++) {
+ if (p[i] != td->pattern[i])
+ return -1;
+ }
+ return 0;
+}
+
+/**
+ * create_bbt - [GENERIC] Create a bad block table by scanning the device
+ * @param mtd MTD device structure
+ * @param buf temporary buffer
+ * @param bd descriptor for the good/bad block search pattern
+ * @param chip create the table for a specific chip, -1 read all chips.
+ * Applies only if NAND_BBT_PERCHIP option is set
+ *
+ * Create a bad block table by scanning the device
+ * for the given good/bad block identify pattern
+ */
+static int create_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *bd, int chip)
+{
+ struct onenand_chip *this = mtd->priv;
+ struct bbm_info *bbm = this->bbm;
+ int i, j, numblocks, len, scanlen;
+ int startblock;
+ loff_t from;
+ size_t readlen, ooblen;
+
+ printk(KERN_INFO "Scanning device for bad blocks\n");
+
+ len = 1;
+
+ /* We need only read few bytes from the OOB area */
+ scanlen = ooblen = 0;
+ readlen = bd->len;
+
+ /* chip == -1 case only */
+ /* Note that numblocks is 2 * (real numblocks) here;
+ * see i += 2 below as it makses shifting and masking less painful
+ */
+ numblocks = mtd->size >> (bbm->bbt_erase_shift - 1);
+ startblock = 0;
+ from = 0;
+
+ for (i = startblock; i < numblocks; ) {
+ int ret;
+
+ for (j = 0; j < len; j++) {
+ size_t retlen;
+
+ /* No need to read pages fully,
+ * just read required OOB bytes */
+ ret = mtd->read_oob(mtd, from + j * mtd->oobblock + bd->offs,
+ readlen, &retlen, &buf[0]);
+
+ if (ret)
+ return ret;
+
+ if (check_short_pattern(&buf[j * scanlen], scanlen, mtd->oobblock, bd)) {
+ bbm->bbt[i >> 3] |= 0x03 << (i & 0x6);
+ printk(KERN_WARNING "Bad eraseblock %d at 0x%08x\n",
+ i >> 1, (unsigned int) from);
+ break;
+ }
+ }
+ i += 2;
+ from += (1 << bbm->bbt_erase_shift);
+ }
+
+ return 0;
+}
+
+
+/**
+ * onenand_memory_bbt - [GENERIC] create a memory based bad block table
+ * @param mtd MTD device structure
+ * @param bd descriptor for the good/bad block search pattern
+ *
+ * The function creates a memory based bbt by scanning the device
+ * for manufacturer / software marked good / bad blocks
+ */
+static inline int onenand_memory_bbt (struct mtd_info *mtd, struct nand_bbt_descr *bd)
+{
+ unsigned char data_buf[MAX_ONENAND_PAGESIZE];
+
+ bd->options &= ~NAND_BBT_SCANEMPTY;
+ return create_bbt(mtd, data_buf, bd, -1);
+}
+
+/**
+ * onenand_isbad_bbt - [OneNAND Interface] Check if a block is bad
+ * @param mtd MTD device structure
+ * @param offs offset in the device
+ * @param allowbbt allow access to bad block table region
+ */
+static int onenand_isbad_bbt(struct mtd_info *mtd, loff_t offs, int allowbbt)
+{
+ struct onenand_chip *this = mtd->priv;
+ struct bbm_info *bbm = this->bbm;
+ int block;
+ uint8_t res;
+
+ /* Get block number * 2 */
+ block = (int) (offs >> (bbm->bbt_erase_shift - 1));
+ res = (bbm->bbt[block >> 3] >> (block & 0x06)) & 0x03;
+
+ DEBUG(MTD_DEBUG_LEVEL2, "onenand_isbad_bbt: bbt info for offs 0x%08x: (block %d) 0x%02x\n",
+ (unsigned int) offs, block >> 1, res);
+
+ switch ((int) res) {
+ case 0x00: return 0;
+ case 0x01: return 1;
+ case 0x02: return allowbbt ? 0 : 1;
+ }
+
+ return 1;
+}
+
+/**
+ * onenand_scan_bbt - [OneNAND Interface] scan, find, read and maybe create bad block table(s)
+ * @param mtd MTD device structure
+ * @param bd descriptor for the good/bad block search pattern
+ *
+ * The function checks, if a bad block table(s) is/are already
+ * available. If not it scans the device for manufacturer
+ * marked good / bad blocks and writes the bad block table(s) to
+ * the selected place.
+ *
+ * The bad block table memory is allocated here. It must be freed
+ * by calling the onenand_free_bbt function.
+ *
+ */
+int onenand_scan_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd)
+{
+ struct onenand_chip *this = mtd->priv;
+ struct bbm_info *bbm = this->bbm;
+ int len, ret = 0;
+
+ len = mtd->size >> (this->erase_shift + 2);
+ /* Allocate memory (2bit per block) */
+ bbm->bbt = kmalloc(len, GFP_KERNEL);
+ if (!bbm->bbt) {
+ printk(KERN_ERR "onenand_scan_bbt: Out of memory\n");
+ return -ENOMEM;
+ }
+ /* Clear the memory bad block table */
+ memset(bbm->bbt, 0x00, len);
+
+ /* Set the bad block position */
+ bbm->badblockpos = ONENAND_BADBLOCK_POS;
+
+ /* Set erase shift */
+ bbm->bbt_erase_shift = this->erase_shift;
+
+ if (!bbm->isbad_bbt)
+ bbm->isbad_bbt = onenand_isbad_bbt;
+
+ /* Scan the device to build a memory based bad block table */
+ if ((ret = onenand_memory_bbt(mtd, bd))) {
+ printk(KERN_ERR "onenand_scan_bbt: Can't scan flash and build the RAM-based BBT\n");
+ kfree(bbm->bbt);
+ bbm->bbt = NULL;
+ }
+
+ return ret;
+}
+
+/*
+ * Define some generic bad / good block scan pattern which are used
+ * while scanning a device for factory marked good / bad blocks.
+ */
+static uint8_t scan_ff_pattern[] = { 0xff, 0xff };
+
+static struct nand_bbt_descr largepage_memorybased = {
+ .options = 0,
+ .offs = 0,
+ .len = 2,
+ .pattern = scan_ff_pattern,
+};
+
+/**
+ * onenand_default_bbt - [OneNAND Interface] Select a default bad block table for the device
+ * @param mtd MTD device structure
+ *
+ * This function selects the default bad block table
+ * support for the device and calls the onenand_scan_bbt function
+ */
+int onenand_default_bbt(struct mtd_info *mtd)
+{
+ struct onenand_chip *this = mtd->priv;
+ struct bbm_info *bbm;
+
+ this->bbm = kmalloc(sizeof(struct bbm_info), GFP_KERNEL);
+ if (!this->bbm)
+ return -ENOMEM;
+
+ bbm = this->bbm;
+
+ memset(bbm, 0, sizeof(struct bbm_info));
+
+ /* 1KB page has same configuration as 2KB page */
+ if (!bbm->badblock_pattern)
+ bbm->badblock_pattern = &largepage_memorybased;
+
+ return onenand_scan_bbt(mtd, bbm->badblock_pattern);
+}
+
+EXPORT_SYMBOL(onenand_scan_bbt);
+EXPORT_SYMBOL(onenand_default_bbt);
diff --git a/drivers/mtd/redboot.c b/drivers/mtd/redboot.c
index 13f9e992bef8..7b7ca5ab5ae4 100644
--- a/drivers/mtd/redboot.c
+++ b/drivers/mtd/redboot.c
@@ -1,5 +1,5 @@
/*
- * $Id: redboot.c,v 1.17 2004/11/22 11:33:56 ijc Exp $
+ * $Id: redboot.c,v 1.18 2005/11/07 11:14:21 gleixner Exp $
*
* Parse RedBoot-style Flash Image System (FIS) tables and
* produce a Linux partition array to match.
@@ -39,7 +39,7 @@ static inline int redboot_checksum(struct fis_image_desc *img)
return 1;
}
-static int parse_redboot_partitions(struct mtd_info *master,
+static int parse_redboot_partitions(struct mtd_info *master,
struct mtd_partition **pparts,
unsigned long fis_origin)
{
diff --git a/drivers/mtd/rfd_ftl.c b/drivers/mtd/rfd_ftl.c
new file mode 100644
index 000000000000..0ab8d29caeea
--- /dev/null
+++ b/drivers/mtd/rfd_ftl.c
@@ -0,0 +1,856 @@
+/*
+ * rfd_ftl.c -- resident flash disk (flash translation layer)
+ *
+ * Copyright (C) 2005 Sean Young <sean@mess.org>
+ *
+ * $Id: rfd_ftl.c,v 1.5 2005/11/07 11:14:21 gleixner Exp $
+ *
+ * This type of flash translation layer (FTL) is used by the Embedded BIOS
+ * by General Software. It is known as the Resident Flash Disk (RFD), see:
+ *
+ * http://www.gensw.com/pages/prod/bios/rfd.htm
+ *
+ * based on ftl.c
+ */
+
+#include <linux/hdreg.h>
+#include <linux/init.h>
+#include <linux/mtd/blktrans.h>
+#include <linux/mtd/mtd.h>
+#include <linux/vmalloc.h>
+#include <linux/jiffies.h>
+
+#include <asm/types.h>
+
+#define const_cpu_to_le16 __constant_cpu_to_le16
+
+static int block_size = 0;
+module_param(block_size, int, 0);
+MODULE_PARM_DESC(block_size, "Block size to use by RFD, defaults to erase unit size");
+
+#define PREFIX "rfd_ftl: "
+
+/* Major device # for FTL device */
+
+/* A request for this major has been sent to device@lanana.org */
+#ifndef RFD_FTL_MAJOR
+#define RFD_FTL_MAJOR 95
+#endif
+
+/* Maximum number of partitions in an FTL region */
+#define PART_BITS 4
+
+/* An erase unit should start with this value */
+#define RFD_MAGIC 0x9193
+
+/* the second value is 0xffff or 0xffc8; function unknown */
+
+/* the third value is always 0xffff, ignored */
+
+/* next is an array of mapping for each corresponding sector */
+#define HEADER_MAP_OFFSET 3
+#define SECTOR_DELETED 0x0000
+#define SECTOR_ZERO 0xfffe
+#define SECTOR_FREE 0xffff
+
+#define SECTOR_SIZE 512
+
+#define SECTORS_PER_TRACK 63
+
+struct block {
+ enum {
+ BLOCK_OK,
+ BLOCK_ERASING,
+ BLOCK_ERASED,
+ BLOCK_FAILED
+ } state;
+ int free_sectors;
+ int used_sectors;
+ int erases;
+ u_long offset;
+};
+
+struct partition {
+ struct mtd_blktrans_dev mbd;
+
+ u_int block_size; /* size of erase unit */
+ u_int total_blocks; /* number of erase units */
+ u_int header_sectors_per_block; /* header sectors in erase unit */
+ u_int data_sectors_per_block; /* data sectors in erase unit */
+ u_int sector_count; /* sectors in translated disk */
+ u_int header_size; /* bytes in header sector */
+ int reserved_block; /* block next up for reclaim */
+ int current_block; /* block to write to */
+ u16 *header_cache; /* cached header */
+
+ int is_reclaiming;
+ int cylinders;
+ int errors;
+ u_long *sector_map;
+ struct block *blocks;
+};
+
+static int rfd_ftl_writesect(struct mtd_blktrans_dev *dev, u_long sector, char *buf);
+
+static int build_block_map(struct partition *part, int block_no)
+{
+ struct block *block = &part->blocks[block_no];
+ int i;
+
+ block->offset = part->block_size * block_no;
+
+ if (le16_to_cpu(part->header_cache[0]) != RFD_MAGIC) {
+ block->state = BLOCK_ERASED; /* assumption */
+ block->free_sectors = part->data_sectors_per_block;
+ part->reserved_block = block_no;
+ return 1;
+ }
+
+ block->state = BLOCK_OK;
+
+ for (i=0; i<part->data_sectors_per_block; i++) {
+ u16 entry;
+
+ entry = le16_to_cpu(part->header_cache[HEADER_MAP_OFFSET + i]);
+
+ if (entry == SECTOR_DELETED)
+ continue;
+
+ if (entry == SECTOR_FREE) {
+ block->free_sectors++;
+ continue;
+ }
+
+ if (entry == SECTOR_ZERO)
+ entry = 0;
+
+ if (entry >= part->sector_count) {
+ printk(KERN_NOTICE PREFIX
+ "'%s': unit #%d: entry %d corrupt, "
+ "sector %d out of range\n",
+ part->mbd.mtd->name, block_no, i, entry);
+ continue;
+ }
+
+ if (part->sector_map[entry] != -1) {
+ printk(KERN_NOTICE PREFIX
+ "'%s': more than one entry for sector %d\n",
+ part->mbd.mtd->name, entry);
+ part->errors = 1;
+ continue;
+ }
+
+ part->sector_map[entry] = block->offset +
+ (i + part->header_sectors_per_block) * SECTOR_SIZE;
+
+ block->used_sectors++;
+ }
+
+ if (block->free_sectors == part->data_sectors_per_block)
+ part->reserved_block = block_no;
+
+ return 0;
+}
+
+static int scan_header(struct partition *part)
+{
+ int sectors_per_block;
+ int i, rc = -ENOMEM;
+ int blocks_found;
+ size_t retlen;
+
+ sectors_per_block = part->block_size / SECTOR_SIZE;
+ part->total_blocks = part->mbd.mtd->size / part->block_size;
+
+ if (part->total_blocks < 2)
+ return -ENOENT;
+
+ /* each erase block has three bytes header, followed by the map */
+ part->header_sectors_per_block =
+ ((HEADER_MAP_OFFSET + sectors_per_block) *
+ sizeof(u16) + SECTOR_SIZE - 1) / SECTOR_SIZE;
+
+ part->data_sectors_per_block = sectors_per_block -
+ part->header_sectors_per_block;
+
+ part->header_size = (HEADER_MAP_OFFSET +
+ part->data_sectors_per_block) * sizeof(u16);
+
+ part->cylinders = (part->data_sectors_per_block *
+ (part->total_blocks - 1) - 1) / SECTORS_PER_TRACK;
+
+ part->sector_count = part->cylinders * SECTORS_PER_TRACK;
+
+ part->current_block = -1;
+ part->reserved_block = -1;
+ part->is_reclaiming = 0;
+
+ part->header_cache = kmalloc(part->header_size, GFP_KERNEL);
+ if (!part->header_cache)
+ goto err;
+
+ part->blocks = kcalloc(part->total_blocks, sizeof(struct block),
+ GFP_KERNEL);
+ if (!part->blocks)
+ goto err;
+
+ part->sector_map = vmalloc(part->sector_count * sizeof(u_long));
+ if (!part->sector_map) {
+ printk(KERN_ERR PREFIX "'%s': unable to allocate memory for "
+ "sector map", part->mbd.mtd->name);
+ goto err;
+ }
+
+ for (i=0; i<part->sector_count; i++)
+ part->sector_map[i] = -1;
+
+ for (i=0, blocks_found=0; i<part->total_blocks; i++) {
+ rc = part->mbd.mtd->read(part->mbd.mtd,
+ i * part->block_size, part->header_size,
+ &retlen, (u_char*)part->header_cache);
+
+ if (!rc && retlen != part->header_size)
+ rc = -EIO;
+
+ if (rc)
+ goto err;
+
+ if (!build_block_map(part, i))
+ blocks_found++;
+ }
+
+ if (blocks_found == 0) {
+ printk(KERN_NOTICE PREFIX "no RFD magic found in '%s'\n",
+ part->mbd.mtd->name);
+ rc = -ENOENT;
+ goto err;
+ }
+
+ if (part->reserved_block == -1) {
+ printk(KERN_NOTICE PREFIX "'%s': no empty erase unit found\n",
+ part->mbd.mtd->name);
+
+ part->errors = 1;
+ }
+
+ return 0;
+
+err:
+ vfree(part->sector_map);
+ kfree(part->header_cache);
+ kfree(part->blocks);
+
+ return rc;
+}
+
+static int rfd_ftl_readsect(struct mtd_blktrans_dev *dev, u_long sector, char *buf)
+{
+ struct partition *part = (struct partition*)dev;
+ u_long addr;
+ size_t retlen;
+ int rc;
+
+ if (sector >= part->sector_count)
+ return -EIO;
+
+ addr = part->sector_map[sector];
+ if (addr != -1) {
+ rc = part->mbd.mtd->read(part->mbd.mtd, addr, SECTOR_SIZE,
+ &retlen, (u_char*)buf);
+ if (!rc && retlen != SECTOR_SIZE)
+ rc = -EIO;
+
+ if (rc) {
+ printk(KERN_WARNING PREFIX "error reading '%s' at "
+ "0x%lx\n", part->mbd.mtd->name, addr);
+ return rc;
+ }
+ } else
+ memset(buf, 0, SECTOR_SIZE);
+
+ return 0;
+}
+
+static void erase_callback(struct erase_info *erase)
+{
+ struct partition *part;
+ u16 magic;
+ int i, rc;
+ size_t retlen;
+
+ part = (struct partition*)erase->priv;
+
+ i = erase->addr / part->block_size;
+ if (i >= part->total_blocks || part->blocks[i].offset != erase->addr) {
+ printk(KERN_ERR PREFIX "erase callback for unknown offset %x "
+ "on '%s'\n", erase->addr, part->mbd.mtd->name);
+ return;
+ }
+
+ if (erase->state != MTD_ERASE_DONE) {
+ printk(KERN_WARNING PREFIX "erase failed at 0x%x on '%s', "
+ "state %d\n", erase->addr,
+ part->mbd.mtd->name, erase->state);
+
+ part->blocks[i].state = BLOCK_FAILED;
+ part->blocks[i].free_sectors = 0;
+ part->blocks[i].used_sectors = 0;
+
+ kfree(erase);
+
+ return;
+ }
+
+ magic = const_cpu_to_le16(RFD_MAGIC);
+
+ part->blocks[i].state = BLOCK_ERASED;
+ part->blocks[i].free_sectors = part->data_sectors_per_block;
+ part->blocks[i].used_sectors = 0;
+ part->blocks[i].erases++;
+
+ rc = part->mbd.mtd->write(part->mbd.mtd,
+ part->blocks[i].offset, sizeof(magic), &retlen,
+ (u_char*)&magic);
+
+ if (!rc && retlen != sizeof(magic))
+ rc = -EIO;
+
+ if (rc) {
+ printk(KERN_NOTICE PREFIX "'%s': unable to write RFD "
+ "header at 0x%lx\n",
+ part->mbd.mtd->name,
+ part->blocks[i].offset);
+ part->blocks[i].state = BLOCK_FAILED;
+ }
+ else
+ part->blocks[i].state = BLOCK_OK;
+
+ kfree(erase);
+}
+
+static int erase_block(struct partition *part, int block)
+{
+ struct erase_info *erase;
+ int rc = -ENOMEM;
+
+ erase = kmalloc(sizeof(struct erase_info), GFP_KERNEL);
+ if (!erase)
+ goto err;
+
+ erase->mtd = part->mbd.mtd;
+ erase->callback = erase_callback;
+ erase->addr = part->blocks[block].offset;
+ erase->len = part->block_size;
+ erase->priv = (u_long)part;
+
+ part->blocks[block].state = BLOCK_ERASING;
+ part->blocks[block].free_sectors = 0;
+
+ rc = part->mbd.mtd->erase(part->mbd.mtd, erase);
+
+ if (rc) {
+ printk(KERN_WARNING PREFIX "erase of region %x,%x on '%s' "
+ "failed\n", erase->addr, erase->len,
+ part->mbd.mtd->name);
+ kfree(erase);
+ }
+
+err:
+ return rc;
+}
+
+static int move_block_contents(struct partition *part, int block_no, u_long *old_sector)
+{
+ void *sector_data;
+ u16 *map;
+ size_t retlen;
+ int i, rc = -ENOMEM;
+
+ part->is_reclaiming = 1;
+
+ sector_data = kmalloc(SECTOR_SIZE, GFP_KERNEL);
+ if (!sector_data)
+ goto err3;
+
+ map = kmalloc(part->header_size, GFP_KERNEL);
+ if (!map)
+ goto err2;
+
+ rc = part->mbd.mtd->read(part->mbd.mtd,
+ part->blocks[block_no].offset, part->header_size,
+ &retlen, (u_char*)map);
+
+ if (!rc && retlen != part->header_size)
+ rc = -EIO;
+
+ if (rc) {
+ printk(KERN_NOTICE PREFIX "error reading '%s' at "
+ "0x%lx\n", part->mbd.mtd->name,
+ part->blocks[block_no].offset);
+
+ goto err;
+ }
+
+ for (i=0; i<part->data_sectors_per_block; i++) {
+ u16 entry = le16_to_cpu(map[HEADER_MAP_OFFSET + i]);
+ u_long addr;
+
+
+ if (entry == SECTOR_FREE || entry == SECTOR_DELETED)
+ continue;
+
+ if (entry == SECTOR_ZERO)
+ entry = 0;
+
+ /* already warned about and ignored in build_block_map() */
+ if (entry >= part->sector_count)
+ continue;
+
+ addr = part->blocks[block_no].offset +
+ (i + part->header_sectors_per_block) * SECTOR_SIZE;
+
+ if (*old_sector == addr) {
+ *old_sector = -1;
+ if (!part->blocks[block_no].used_sectors--) {
+ rc = erase_block(part, block_no);
+ break;
+ }
+ continue;
+ }
+ rc = part->mbd.mtd->read(part->mbd.mtd, addr,
+ SECTOR_SIZE, &retlen, sector_data);
+
+ if (!rc && retlen != SECTOR_SIZE)
+ rc = -EIO;
+
+ if (rc) {
+ printk(KERN_NOTICE PREFIX "'%s': Unable to "
+ "read sector for relocation\n",
+ part->mbd.mtd->name);
+
+ goto err;
+ }
+
+ rc = rfd_ftl_writesect((struct mtd_blktrans_dev*)part,
+ entry, sector_data);
+
+ if (rc)
+ goto err;
+ }
+
+err:
+ kfree(map);
+err2:
+ kfree(sector_data);
+err3:
+ part->is_reclaiming = 0;
+
+ return rc;
+}
+
+static int reclaim_block(struct partition *part, u_long *old_sector)
+{
+ int block, best_block, score, old_sector_block;
+ int rc;
+
+ /* we have a race if sync doesn't exist */
+ if (part->mbd.mtd->sync)
+ part->mbd.mtd->sync(part->mbd.mtd);
+
+ score = 0x7fffffff; /* MAX_INT */
+ best_block = -1;
+ if (*old_sector != -1)
+ old_sector_block = *old_sector / part->block_size;
+ else
+ old_sector_block = -1;
+
+ for (block=0; block<part->total_blocks; block++) {
+ int this_score;
+
+ if (block == part->reserved_block)
+ continue;
+
+ /*
+ * Postpone reclaiming if there is a free sector as
+ * more removed sectors is more efficient (have to move
+ * less).
+ */
+ if (part->blocks[block].free_sectors)
+ return 0;
+
+ this_score = part->blocks[block].used_sectors;
+
+ if (block == old_sector_block)
+ this_score--;
+ else {
+ /* no point in moving a full block */
+ if (part->blocks[block].used_sectors ==
+ part->data_sectors_per_block)
+ continue;
+ }
+
+ this_score += part->blocks[block].erases;
+
+ if (this_score < score) {
+ best_block = block;
+ score = this_score;
+ }
+ }
+
+ if (best_block == -1)
+ return -ENOSPC;
+
+ part->current_block = -1;
+ part->reserved_block = best_block;
+
+ pr_debug("reclaim_block: reclaiming block #%d with %d used "
+ "%d free sectors\n", best_block,
+ part->blocks[best_block].used_sectors,
+ part->blocks[best_block].free_sectors);
+
+ if (part->blocks[best_block].used_sectors)
+ rc = move_block_contents(part, best_block, old_sector);
+ else
+ rc = erase_block(part, best_block);
+
+ return rc;
+}
+
+/*
+ * IMPROVE: It would be best to choose the block with the most deleted sectors,
+ * because if we fill that one up first it'll have the most chance of having
+ * the least live sectors at reclaim.
+ */
+static int find_free_block(const struct partition *part)
+{
+ int block, stop;
+
+ block = part->current_block == -1 ?
+ jiffies % part->total_blocks : part->current_block;
+ stop = block;
+
+ do {
+ if (part->blocks[block].free_sectors &&
+ block != part->reserved_block)
+ return block;
+
+ if (++block >= part->total_blocks)
+ block = 0;
+
+ } while (block != stop);
+
+ return -1;
+}
+
+static int find_writeable_block(struct partition *part, u_long *old_sector)
+{
+ int rc, block;
+ size_t retlen;
+
+ block = find_free_block(part);
+
+ if (block == -1) {
+ if (!part->is_reclaiming) {
+ rc = reclaim_block(part, old_sector);
+ if (rc)
+ goto err;
+
+ block = find_free_block(part);
+ }
+
+ if (block == -1) {
+ rc = -ENOSPC;
+ goto err;
+ }
+ }
+
+ rc = part->mbd.mtd->read(part->mbd.mtd, part->blocks[block].offset,
+ part->header_size, &retlen, (u_char*)part->header_cache);
+
+ if (!rc && retlen != part->header_size)
+ rc = -EIO;
+
+ if (rc) {
+ printk(KERN_NOTICE PREFIX "'%s': unable to read header at "
+ "0x%lx\n", part->mbd.mtd->name,
+ part->blocks[block].offset);
+ goto err;
+ }
+
+ part->current_block = block;
+
+err:
+ return rc;
+}
+
+static int mark_sector_deleted(struct partition *part, u_long old_addr)
+{
+ int block, offset, rc;
+ u_long addr;
+ size_t retlen;
+ u16 del = const_cpu_to_le16(SECTOR_DELETED);
+
+ block = old_addr / part->block_size;
+ offset = (old_addr % part->block_size) / SECTOR_SIZE -
+ part->header_sectors_per_block;
+
+ addr = part->blocks[block].offset +
+ (HEADER_MAP_OFFSET + offset) * sizeof(u16);
+ rc = part->mbd.mtd->write(part->mbd.mtd, addr,
+ sizeof(del), &retlen, (u_char*)&del);
+
+ if (!rc && retlen != sizeof(del))
+ rc = -EIO;
+
+ if (rc) {
+ printk(KERN_WARNING PREFIX "error writing '%s' at "
+ "0x%lx\n", part->mbd.mtd->name, addr);
+ if (rc)
+ goto err;
+ }
+ if (block == part->current_block)
+ part->header_cache[offset + HEADER_MAP_OFFSET] = del;
+
+ part->blocks[block].used_sectors--;
+
+ if (!part->blocks[block].used_sectors &&
+ !part->blocks[block].free_sectors)
+ rc = erase_block(part, block);
+
+err:
+ return rc;
+}
+
+static int find_free_sector(const struct partition *part, const struct block *block)
+{
+ int i, stop;
+
+ i = stop = part->data_sectors_per_block - block->free_sectors;
+
+ do {
+ if (le16_to_cpu(part->header_cache[HEADER_MAP_OFFSET + i])
+ == SECTOR_FREE)
+ return i;
+
+ if (++i == part->data_sectors_per_block)
+ i = 0;
+ }
+ while(i != stop);
+
+ return -1;
+}
+
+static int do_writesect(struct mtd_blktrans_dev *dev, u_long sector, char *buf, ulong *old_addr)
+{
+ struct partition *part = (struct partition*)dev;
+ struct block *block;
+ u_long addr;
+ int i;
+ int rc;
+ size_t retlen;
+ u16 entry;
+
+ if (part->current_block == -1 ||
+ !part->blocks[part->current_block].free_sectors) {
+
+ rc = find_writeable_block(part, old_addr);
+ if (rc)
+ goto err;
+ }
+
+ block = &part->blocks[part->current_block];
+
+ i = find_free_sector(part, block);
+
+ if (i < 0) {
+ rc = -ENOSPC;
+ goto err;
+ }
+
+ addr = (i + part->header_sectors_per_block) * SECTOR_SIZE +
+ block->offset;
+ rc = part->mbd.mtd->write(part->mbd.mtd,
+ addr, SECTOR_SIZE, &retlen, (u_char*)buf);
+
+ if (!rc && retlen != SECTOR_SIZE)
+ rc = -EIO;
+
+ if (rc) {
+ printk(KERN_WARNING PREFIX "error writing '%s' at 0x%lx\n",
+ part->mbd.mtd->name, addr);
+ if (rc)
+ goto err;
+ }
+
+ part->sector_map[sector] = addr;
+
+ entry = cpu_to_le16(sector == 0 ? SECTOR_ZERO : sector);
+
+ part->header_cache[i + HEADER_MAP_OFFSET] = entry;
+
+ addr = block->offset + (HEADER_MAP_OFFSET + i) * sizeof(u16);
+ rc = part->mbd.mtd->write(part->mbd.mtd, addr,
+ sizeof(entry), &retlen, (u_char*)&entry);
+
+ if (!rc && retlen != sizeof(entry))
+ rc = -EIO;
+
+ if (rc) {
+ printk(KERN_WARNING PREFIX "error writing '%s' at 0x%lx\n",
+ part->mbd.mtd->name, addr);
+ if (rc)
+ goto err;
+ }
+ block->used_sectors++;
+ block->free_sectors--;
+
+err:
+ return rc;
+}
+
+static int rfd_ftl_writesect(struct mtd_blktrans_dev *dev, u_long sector, char *buf)
+{
+ struct partition *part = (struct partition*)dev;
+ u_long old_addr;
+ int i;
+ int rc = 0;
+
+ pr_debug("rfd_ftl_writesect(sector=0x%lx)\n", sector);
+
+ if (part->reserved_block == -1) {
+ rc = -EACCES;
+ goto err;
+ }
+
+ if (sector >= part->sector_count) {
+ rc = -EIO;
+ goto err;
+ }
+
+ old_addr = part->sector_map[sector];
+
+ for (i=0; i<SECTOR_SIZE; i++) {
+ if (!buf[i])
+ continue;
+
+ rc = do_writesect(dev, sector, buf, &old_addr);
+ if (rc)
+ goto err;
+ break;
+ }
+
+ if (i == SECTOR_SIZE)
+ part->sector_map[sector] = -1;
+
+ if (old_addr != -1)
+ rc = mark_sector_deleted(part, old_addr);
+
+err:
+ return rc;
+}
+
+static int rfd_ftl_getgeo(struct mtd_blktrans_dev *dev, struct hd_geometry *geo)
+{
+ struct partition *part = (struct partition*)dev;
+
+ geo->heads = 1;
+ geo->sectors = SECTORS_PER_TRACK;
+ geo->cylinders = part->cylinders;
+
+ return 0;
+}
+
+static void rfd_ftl_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
+{
+ struct partition *part;
+
+ if (mtd->type != MTD_NORFLASH)
+ return;
+
+ part = kcalloc(1, sizeof(struct partition), GFP_KERNEL);
+ if (!part)
+ return;
+
+ part->mbd.mtd = mtd;
+
+ if (block_size)
+ part->block_size = block_size;
+ else {
+ if (!mtd->erasesize) {
+ printk(KERN_NOTICE PREFIX "please provide block_size");
+ return;
+ }
+ else
+ part->block_size = mtd->erasesize;
+ }
+
+ if (scan_header(part) == 0) {
+ part->mbd.size = part->sector_count;
+ part->mbd.blksize = SECTOR_SIZE;
+ part->mbd.tr = tr;
+ part->mbd.devnum = -1;
+ if (!(mtd->flags & MTD_WRITEABLE))
+ part->mbd.readonly = 1;
+ else if (part->errors) {
+ printk(KERN_NOTICE PREFIX "'%s': errors found, "
+ "setting read-only", mtd->name);
+ part->mbd.readonly = 1;
+ }
+
+ printk(KERN_INFO PREFIX "name: '%s' type: %d flags %x\n",
+ mtd->name, mtd->type, mtd->flags);
+
+ if (!add_mtd_blktrans_dev((void*)part))
+ return;
+ }
+
+ kfree(part);
+}
+
+static void rfd_ftl_remove_dev(struct mtd_blktrans_dev *dev)
+{
+ struct partition *part = (struct partition*)dev;
+ int i;
+
+ for (i=0; i<part->total_blocks; i++) {
+ pr_debug("rfd_ftl_remove_dev:'%s': erase unit #%02d: %d erases\n",
+ part->mbd.mtd->name, i, part->blocks[i].erases);
+ }
+
+ del_mtd_blktrans_dev(dev);
+ vfree(part->sector_map);
+ kfree(part->header_cache);
+ kfree(part->blocks);
+ kfree(part);
+}
+
+struct mtd_blktrans_ops rfd_ftl_tr = {
+ .name = "rfd",
+ .major = RFD_FTL_MAJOR,
+ .part_bits = PART_BITS,
+ .readsect = rfd_ftl_readsect,
+ .writesect = rfd_ftl_writesect,
+ .getgeo = rfd_ftl_getgeo,
+ .add_mtd = rfd_ftl_add_mtd,
+ .remove_dev = rfd_ftl_remove_dev,
+ .owner = THIS_MODULE,
+};
+
+static int __init init_rfd_ftl(void)
+{
+ return register_mtd_blktrans(&rfd_ftl_tr);
+}
+
+static void __exit cleanup_rfd_ftl(void)
+{
+ deregister_mtd_blktrans(&rfd_ftl_tr);
+}
+
+module_init(init_rfd_ftl);
+module_exit(cleanup_rfd_ftl);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Sean Young <sean@mess.org>");
+MODULE_DESCRIPTION("Support code for RFD Flash Translation Layer, "
+ "used by General Software's Embedded BIOS");
+
diff --git a/drivers/net/3c59x.c b/drivers/net/3c59x.c
index 455ba915ede7..7488ee7f7caf 100644
--- a/drivers/net/3c59x.c
+++ b/drivers/net/3c59x.c
@@ -602,7 +602,7 @@ MODULE_DEVICE_TABLE(pci, vortex_pci_tbl);
First the windows. There are eight register windows, with the command
and status registers available in each.
*/
-#define EL3WINDOW(win_num) outw(SelectWindow + (win_num), ioaddr + EL3_CMD)
+#define EL3WINDOW(win_num) iowrite16(SelectWindow + (win_num), ioaddr + EL3_CMD)
#define EL3_CMD 0x0e
#define EL3_STATUS 0x0e
@@ -776,7 +776,8 @@ struct vortex_private {
/* PCI configuration space information. */
struct device *gendev;
- char __iomem *cb_fn_base; /* CardBus function status addr space. */
+ void __iomem *ioaddr; /* IO address space */
+ void __iomem *cb_fn_base; /* CardBus function status addr space. */
/* Some values here only for performance evaluation and path-coverage */
int rx_nocopy, rx_copy, queued_packet, rx_csumhits;
@@ -869,12 +870,12 @@ static struct {
/* number of ETHTOOL_GSTATS u64's */
#define VORTEX_NUM_STATS 3
-static int vortex_probe1(struct device *gendev, long ioaddr, int irq,
+static int vortex_probe1(struct device *gendev, void __iomem *ioaddr, int irq,
int chip_idx, int card_idx);
static void vortex_up(struct net_device *dev);
static void vortex_down(struct net_device *dev, int final);
static int vortex_open(struct net_device *dev);
-static void mdio_sync(long ioaddr, int bits);
+static void mdio_sync(void __iomem *ioaddr, int bits);
static int mdio_read(struct net_device *dev, int phy_id, int location);
static void mdio_write(struct net_device *vp, int phy_id, int location, int value);
static void vortex_timer(unsigned long arg);
@@ -887,7 +888,7 @@ static irqreturn_t vortex_interrupt(int irq, void *dev_id, struct pt_regs *regs)
static irqreturn_t boomerang_interrupt(int irq, void *dev_id, struct pt_regs *regs);
static int vortex_close(struct net_device *dev);
static void dump_tx_ring(struct net_device *dev);
-static void update_stats(long ioaddr, struct net_device *dev);
+static void update_stats(void __iomem *ioaddr, struct net_device *dev);
static struct net_device_stats *vortex_get_stats(struct net_device *dev);
static void set_rx_mode(struct net_device *dev);
#ifdef CONFIG_PCI
@@ -902,14 +903,16 @@ static void set_8021q_mode(struct net_device *dev, int enable);
/* This driver uses 'options' to pass the media type, full-duplex flag, etc. */
/* Option count limit only -- unlimited interfaces are supported. */
#define MAX_UNITS 8
-static int options[MAX_UNITS] = { -1, -1, -1, -1, -1, -1, -1, -1,};
-static int full_duplex[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1};
-static int hw_checksums[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1};
-static int flow_ctrl[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1};
-static int enable_wol[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1};
+static int options[MAX_UNITS] = { [0 ... MAX_UNITS-1] = -1 };
+static int full_duplex[MAX_UNITS] = {[0 ... MAX_UNITS-1] = -1 };
+static int hw_checksums[MAX_UNITS] = {[0 ... MAX_UNITS-1] = -1 };
+static int flow_ctrl[MAX_UNITS] = {[0 ... MAX_UNITS-1] = -1 };
+static int enable_wol[MAX_UNITS] = {[0 ... MAX_UNITS-1] = -1 };
+static int use_mmio[MAX_UNITS] = {[0 ... MAX_UNITS-1] = -1 };
static int global_options = -1;
static int global_full_duplex = -1;
static int global_enable_wol = -1;
+static int global_use_mmio = -1;
/* #define dev_alloc_skb dev_alloc_skb_debug */
@@ -934,21 +937,25 @@ module_param(compaq_ioaddr, int, 0);
module_param(compaq_irq, int, 0);
module_param(compaq_device_id, int, 0);
module_param(watchdog, int, 0);
+module_param(global_use_mmio, int, 0);
+module_param_array(use_mmio, int, NULL, 0);
MODULE_PARM_DESC(debug, "3c59x debug level (0-6)");
MODULE_PARM_DESC(options, "3c59x: Bits 0-3: media type, bit 4: bus mastering, bit 9: full duplex");
MODULE_PARM_DESC(global_options, "3c59x: same as options, but applies to all NICs if options is unset");
MODULE_PARM_DESC(full_duplex, "3c59x full duplex setting(s) (1)");
-MODULE_PARM_DESC(global_full_duplex, "3c59x: same as full_duplex, but applies to all NICs if options is unset");
+MODULE_PARM_DESC(global_full_duplex, "3c59x: same as full_duplex, but applies to all NICs if full_duplex is unset");
MODULE_PARM_DESC(hw_checksums, "3c59x Hardware checksum checking by adapter(s) (0-1)");
MODULE_PARM_DESC(flow_ctrl, "3c59x 802.3x flow control usage (PAUSE only) (0-1)");
MODULE_PARM_DESC(enable_wol, "3c59x: Turn on Wake-on-LAN for adapter(s) (0-1)");
-MODULE_PARM_DESC(global_enable_wol, "3c59x: same as enable_wol, but applies to all NICs if options is unset");
+MODULE_PARM_DESC(global_enable_wol, "3c59x: same as enable_wol, but applies to all NICs if enable_wol is unset");
MODULE_PARM_DESC(rx_copybreak, "3c59x copy breakpoint for copy-only-tiny-frames");
MODULE_PARM_DESC(max_interrupt_work, "3c59x maximum events handled per interrupt");
MODULE_PARM_DESC(compaq_ioaddr, "3c59x PCI I/O base address (Compaq BIOS problem workaround)");
MODULE_PARM_DESC(compaq_irq, "3c59x PCI IRQ number (Compaq BIOS problem workaround)");
MODULE_PARM_DESC(compaq_device_id, "3c59x PCI device ID (Compaq BIOS problem workaround)");
MODULE_PARM_DESC(watchdog, "3c59x transmit timeout in milliseconds");
+MODULE_PARM_DESC(global_use_mmio, "3c59x: same as use_mmio, but applies to all NICs if options is unset");
+MODULE_PARM_DESC(use_mmio, "3c59x: use memory-mapped PCI I/O resource (0-1)");
#ifdef CONFIG_NET_POLL_CONTROLLER
static void poll_vortex(struct net_device *dev)
@@ -1029,18 +1036,19 @@ static struct eisa_driver vortex_eisa_driver = {
static int vortex_eisa_probe (struct device *device)
{
- long ioaddr;
+ void __iomem *ioaddr;
struct eisa_device *edev;
edev = to_eisa_device (device);
- ioaddr = edev->base_addr;
- if (!request_region(ioaddr, VORTEX_TOTAL_SIZE, DRV_NAME))
+ if (!request_region(edev->base_addr, VORTEX_TOTAL_SIZE, DRV_NAME))
return -EBUSY;
- if (vortex_probe1(device, ioaddr, inw(ioaddr + 0xC88) >> 12,
+ ioaddr = ioport_map(edev->base_addr, VORTEX_TOTAL_SIZE);
+
+ if (vortex_probe1(device, ioaddr, ioread16(ioaddr + 0xC88) >> 12,
edev->id.driver_data, vortex_cards_found)) {
- release_region (ioaddr, VORTEX_TOTAL_SIZE);
+ release_region (edev->base_addr, VORTEX_TOTAL_SIZE);
return -ENODEV;
}
@@ -1054,7 +1062,7 @@ static int vortex_eisa_remove (struct device *device)
struct eisa_device *edev;
struct net_device *dev;
struct vortex_private *vp;
- long ioaddr;
+ void __iomem *ioaddr;
edev = to_eisa_device (device);
dev = eisa_get_drvdata (edev);
@@ -1065,11 +1073,11 @@ static int vortex_eisa_remove (struct device *device)
}
vp = netdev_priv(dev);
- ioaddr = dev->base_addr;
+ ioaddr = vp->ioaddr;
unregister_netdev (dev);
- outw (TotalReset|0x14, ioaddr + EL3_CMD);
- release_region (ioaddr, VORTEX_TOTAL_SIZE);
+ iowrite16 (TotalReset|0x14, ioaddr + EL3_CMD);
+ release_region (dev->base_addr, VORTEX_TOTAL_SIZE);
free_netdev (dev);
return 0;
@@ -1096,8 +1104,8 @@ static int __init vortex_eisa_init (void)
/* Special code to work-around the Compaq PCI BIOS32 problem. */
if (compaq_ioaddr) {
- vortex_probe1(NULL, compaq_ioaddr, compaq_irq,
- compaq_device_id, vortex_cards_found++);
+ vortex_probe1(NULL, ioport_map(compaq_ioaddr, VORTEX_TOTAL_SIZE),
+ compaq_irq, compaq_device_id, vortex_cards_found++);
}
return vortex_cards_found - orig_cards_found + eisa_found;
@@ -1107,15 +1115,32 @@ static int __init vortex_eisa_init (void)
static int __devinit vortex_init_one (struct pci_dev *pdev,
const struct pci_device_id *ent)
{
- int rc;
+ int rc, unit, pci_bar;
+ struct vortex_chip_info *vci;
+ void __iomem *ioaddr;
/* wake up and enable device */
rc = pci_enable_device (pdev);
if (rc < 0)
goto out;
- rc = vortex_probe1 (&pdev->dev, pci_resource_start (pdev, 0),
- pdev->irq, ent->driver_data, vortex_cards_found);
+ unit = vortex_cards_found;
+
+ if (global_use_mmio < 0 && (unit >= MAX_UNITS || use_mmio[unit] < 0)) {
+ /* Determine the default if the user didn't override us */
+ vci = &vortex_info_tbl[ent->driver_data];
+ pci_bar = vci->drv_flags & (IS_CYCLONE | IS_TORNADO) ? 1 : 0;
+ } else if (unit < MAX_UNITS && use_mmio[unit] >= 0)
+ pci_bar = use_mmio[unit] ? 1 : 0;
+ else
+ pci_bar = global_use_mmio ? 1 : 0;
+
+ ioaddr = pci_iomap(pdev, pci_bar, 0);
+ if (!ioaddr) /* If mapping fails, fall-back to BAR 0... */
+ ioaddr = pci_iomap(pdev, 0, 0);
+
+ rc = vortex_probe1(&pdev->dev, ioaddr, pdev->irq,
+ ent->driver_data, unit);
if (rc < 0) {
pci_disable_device (pdev);
goto out;
@@ -1134,7 +1159,7 @@ out:
* NOTE: pdev can be NULL, for the case of a Compaq device
*/
static int __devinit vortex_probe1(struct device *gendev,
- long ioaddr, int irq,
+ void __iomem *ioaddr, int irq,
int chip_idx, int card_idx)
{
struct vortex_private *vp;
@@ -1202,15 +1227,16 @@ static int __devinit vortex_probe1(struct device *gendev,
if (print_info)
printk (KERN_INFO "See Documentation/networking/vortex.txt\n");
- printk(KERN_INFO "%s: 3Com %s %s at 0x%lx. Vers " DRV_VERSION "\n",
+ printk(KERN_INFO "%s: 3Com %s %s at %p. Vers " DRV_VERSION "\n",
print_name,
pdev ? "PCI" : "EISA",
vci->name,
ioaddr);
- dev->base_addr = ioaddr;
+ dev->base_addr = (unsigned long)ioaddr;
dev->irq = irq;
dev->mtu = mtu;
+ vp->ioaddr = ioaddr;
vp->large_frames = mtu > 1500;
vp->drv_flags = vci->drv_flags;
vp->has_nway = (vci->drv_flags & HAS_NWAY) ? 1 : 0;
@@ -1226,7 +1252,7 @@ static int __devinit vortex_probe1(struct device *gendev,
if (pdev) {
/* EISA resources already marked, so only PCI needs to do this here */
/* Ignore return value, because Cardbus drivers already allocate for us */
- if (request_region(ioaddr, vci->io_size, print_name) != NULL)
+ if (request_region(dev->base_addr, vci->io_size, print_name) != NULL)
vp->must_free_region = 1;
/* enable bus-mastering if necessary */
@@ -1316,14 +1342,14 @@ static int __devinit vortex_probe1(struct device *gendev,
for (i = 0; i < 0x40; i++) {
int timer;
- outw(base + i, ioaddr + Wn0EepromCmd);
+ iowrite16(base + i, ioaddr + Wn0EepromCmd);
/* Pause for at least 162 us. for the read to take place. */
for (timer = 10; timer >= 0; timer--) {
udelay(162);
- if ((inw(ioaddr + Wn0EepromCmd) & 0x8000) == 0)
+ if ((ioread16(ioaddr + Wn0EepromCmd) & 0x8000) == 0)
break;
}
- eeprom[i] = inw(ioaddr + Wn0EepromData);
+ eeprom[i] = ioread16(ioaddr + Wn0EepromData);
}
}
for (i = 0; i < 0x18; i++)
@@ -1338,6 +1364,7 @@ static int __devinit vortex_probe1(struct device *gendev,
printk(" ***INVALID CHECKSUM %4.4x*** ", checksum);
for (i = 0; i < 3; i++)
((u16 *)dev->dev_addr)[i] = htons(eeprom[i + 10]);
+ memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
if (print_info) {
for (i = 0; i < 6; i++)
printk("%c%2.2x", i ? ':' : ' ', dev->dev_addr[i]);
@@ -1351,7 +1378,7 @@ static int __devinit vortex_probe1(struct device *gendev,
}
EL3WINDOW(2);
for (i = 0; i < 6; i++)
- outb(dev->dev_addr[i], ioaddr + i);
+ iowrite8(dev->dev_addr[i], ioaddr + i);
#ifdef __sparc__
if (print_info)
@@ -1366,7 +1393,7 @@ static int __devinit vortex_probe1(struct device *gendev,
#endif
EL3WINDOW(4);
- step = (inb(ioaddr + Wn4_NetDiag) & 0x1e) >> 1;
+ step = (ioread8(ioaddr + Wn4_NetDiag) & 0x1e) >> 1;
if (print_info) {
printk(KERN_INFO " product code %02x%02x rev %02x.%d date %02d-"
"%02d-%02d\n", eeprom[6]&0xff, eeprom[6]>>8, eeprom[0x14],
@@ -1375,31 +1402,30 @@ static int __devinit vortex_probe1(struct device *gendev,
if (pdev && vci->drv_flags & HAS_CB_FNS) {
- unsigned long fn_st_addr; /* Cardbus function status space */
unsigned short n;
- fn_st_addr = pci_resource_start (pdev, 2);
- if (fn_st_addr) {
- vp->cb_fn_base = ioremap(fn_st_addr, 128);
+ vp->cb_fn_base = pci_iomap(pdev, 2, 0);
+ if (!vp->cb_fn_base) {
retval = -ENOMEM;
- if (!vp->cb_fn_base)
- goto free_ring;
+ goto free_ring;
}
+
if (print_info) {
printk(KERN_INFO "%s: CardBus functions mapped %8.8lx->%p\n",
- print_name, fn_st_addr, vp->cb_fn_base);
+ print_name, pci_resource_start(pdev, 2),
+ vp->cb_fn_base);
}
EL3WINDOW(2);
- n = inw(ioaddr + Wn2_ResetOptions) & ~0x4010;
+ n = ioread16(ioaddr + Wn2_ResetOptions) & ~0x4010;
if (vp->drv_flags & INVERT_LED_PWR)
n |= 0x10;
if (vp->drv_flags & INVERT_MII_PWR)
n |= 0x4000;
- outw(n, ioaddr + Wn2_ResetOptions);
+ iowrite16(n, ioaddr + Wn2_ResetOptions);
if (vp->drv_flags & WNO_XCVR_PWR) {
EL3WINDOW(0);
- outw(0x0800, ioaddr);
+ iowrite16(0x0800, ioaddr);
}
}
@@ -1418,13 +1444,13 @@ static int __devinit vortex_probe1(struct device *gendev,
static const char * ram_split[] = {"5:3", "3:1", "1:1", "3:5"};
unsigned int config;
EL3WINDOW(3);
- vp->available_media = inw(ioaddr + Wn3_Options);
+ vp->available_media = ioread16(ioaddr + Wn3_Options);
if ((vp->available_media & 0xff) == 0) /* Broken 3c916 */
vp->available_media = 0x40;
- config = inl(ioaddr + Wn3_Config);
+ config = ioread32(ioaddr + Wn3_Config);
if (print_info) {
printk(KERN_DEBUG " Internal config register is %4.4x, "
- "transceivers %#x.\n", config, inw(ioaddr + Wn3_Options));
+ "transceivers %#x.\n", config, ioread16(ioaddr + Wn3_Options));
printk(KERN_INFO " %dK %s-wide RAM %s Rx:Tx split, %s%s interface.\n",
8 << RAM_SIZE(config),
RAM_WIDTH(config) ? "word" : "byte",
@@ -1455,7 +1481,7 @@ static int __devinit vortex_probe1(struct device *gendev,
if (vp->drv_flags & EXTRA_PREAMBLE)
mii_preamble_required++;
mdio_sync(ioaddr, 32);
- mdio_read(dev, 24, 1);
+ mdio_read(dev, 24, MII_BMSR);
for (phy = 0; phy < 32 && phy_idx < 1; phy++) {
int mii_status, phyx;
@@ -1469,7 +1495,7 @@ static int __devinit vortex_probe1(struct device *gendev,
phyx = phy - 1;
else
phyx = phy;
- mii_status = mdio_read(dev, phyx, 1);
+ mii_status = mdio_read(dev, phyx, MII_BMSR);
if (mii_status && mii_status != 0xffff) {
vp->phys[phy_idx++] = phyx;
if (print_info) {
@@ -1485,7 +1511,7 @@ static int __devinit vortex_probe1(struct device *gendev,
printk(KERN_WARNING" ***WARNING*** No MII transceivers found!\n");
vp->phys[0] = 24;
} else {
- vp->advertising = mdio_read(dev, vp->phys[0], 4);
+ vp->advertising = mdio_read(dev, vp->phys[0], MII_ADVERTISE);
if (vp->full_duplex) {
/* Only advertise the FD media types. */
vp->advertising &= ~0x02A0;
@@ -1510,10 +1536,10 @@ static int __devinit vortex_probe1(struct device *gendev,
if (vp->full_bus_master_tx) {
dev->hard_start_xmit = boomerang_start_xmit;
/* Actually, it still should work with iommu. */
- dev->features |= NETIF_F_SG;
- if (((hw_checksums[card_idx] == -1) && (vp->drv_flags & HAS_HWCKSM)) ||
- (hw_checksums[card_idx] == 1)) {
- dev->features |= NETIF_F_IP_CSUM;
+ if (card_idx < MAX_UNITS &&
+ ((hw_checksums[card_idx] == -1 && (vp->drv_flags & HAS_HWCKSM)) ||
+ hw_checksums[card_idx] == 1)) {
+ dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG;
}
} else {
dev->hard_start_xmit = vortex_start_xmit;
@@ -1555,7 +1581,7 @@ free_ring:
vp->rx_ring_dma);
free_region:
if (vp->must_free_region)
- release_region(ioaddr, vci->io_size);
+ release_region(dev->base_addr, vci->io_size);
free_netdev(dev);
printk(KERN_ERR PFX "vortex_probe1 fails. Returns %d\n", retval);
out:
@@ -1565,17 +1591,19 @@ out:
static void
issue_and_wait(struct net_device *dev, int cmd)
{
+ struct vortex_private *vp = netdev_priv(dev);
+ void __iomem *ioaddr = vp->ioaddr;
int i;
- outw(cmd, dev->base_addr + EL3_CMD);
+ iowrite16(cmd, ioaddr + EL3_CMD);
for (i = 0; i < 2000; i++) {
- if (!(inw(dev->base_addr + EL3_STATUS) & CmdInProgress))
+ if (!(ioread16(ioaddr + EL3_STATUS) & CmdInProgress))
return;
}
/* OK, that didn't work. Do it the slow way. One second */
for (i = 0; i < 100000; i++) {
- if (!(inw(dev->base_addr + EL3_STATUS) & CmdInProgress)) {
+ if (!(ioread16(ioaddr + EL3_STATUS) & CmdInProgress)) {
if (vortex_debug > 1)
printk(KERN_INFO "%s: command 0x%04x took %d usecs\n",
dev->name, cmd, i * 10);
@@ -1584,14 +1612,14 @@ issue_and_wait(struct net_device *dev, int cmd)
udelay(10);
}
printk(KERN_ERR "%s: command 0x%04x did not complete! Status=0x%x\n",
- dev->name, cmd, inw(dev->base_addr + EL3_STATUS));
+ dev->name, cmd, ioread16(ioaddr + EL3_STATUS));
}
static void
vortex_up(struct net_device *dev)
{
- long ioaddr = dev->base_addr;
struct vortex_private *vp = netdev_priv(dev);
+ void __iomem *ioaddr = vp->ioaddr;
unsigned int config;
int i;
@@ -1604,7 +1632,7 @@ vortex_up(struct net_device *dev)
/* Before initializing select the active media port. */
EL3WINDOW(3);
- config = inl(ioaddr + Wn3_Config);
+ config = ioread32(ioaddr + Wn3_Config);
if (vp->media_override != 7) {
printk(KERN_INFO "%s: Media override to transceiver %d (%s).\n",
@@ -1651,14 +1679,14 @@ vortex_up(struct net_device *dev)
config = BFINS(config, dev->if_port, 20, 4);
if (vortex_debug > 6)
printk(KERN_DEBUG "vortex_up(): writing 0x%x to InternalConfig\n", config);
- outl(config, ioaddr + Wn3_Config);
+ iowrite32(config, ioaddr + Wn3_Config);
if (dev->if_port == XCVR_MII || dev->if_port == XCVR_NWAY) {
int mii_reg1, mii_reg5;
EL3WINDOW(4);
/* Read BMSR (reg1) only to clear old status. */
- mii_reg1 = mdio_read(dev, vp->phys[0], 1);
- mii_reg5 = mdio_read(dev, vp->phys[0], 5);
+ mii_reg1 = mdio_read(dev, vp->phys[0], MII_BMSR);
+ mii_reg5 = mdio_read(dev, vp->phys[0], MII_LPA);
if (mii_reg5 == 0xffff || mii_reg5 == 0x0000) {
netif_carrier_off(dev); /* No MII device or no link partner report */
} else {
@@ -1679,7 +1707,7 @@ vortex_up(struct net_device *dev)
}
/* Set the full-duplex bit. */
- outw( ((vp->info1 & 0x8000) || vp->full_duplex ? 0x20 : 0) |
+ iowrite16( ((vp->info1 & 0x8000) || vp->full_duplex ? 0x20 : 0) |
(vp->large_frames ? 0x40 : 0) |
((vp->full_duplex && vp->flow_ctrl && vp->partner_flow_ctrl) ? 0x100 : 0),
ioaddr + Wn3_MAC_Ctrl);
@@ -1695,51 +1723,51 @@ vortex_up(struct net_device *dev)
*/
issue_and_wait(dev, RxReset|0x04);
- outw(SetStatusEnb | 0x00, ioaddr + EL3_CMD);
+ iowrite16(SetStatusEnb | 0x00, ioaddr + EL3_CMD);
if (vortex_debug > 1) {
EL3WINDOW(4);
printk(KERN_DEBUG "%s: vortex_up() irq %d media status %4.4x.\n",
- dev->name, dev->irq, inw(ioaddr + Wn4_Media));
+ dev->name, dev->irq, ioread16(ioaddr + Wn4_Media));
}
/* Set the station address and mask in window 2 each time opened. */
EL3WINDOW(2);
for (i = 0; i < 6; i++)
- outb(dev->dev_addr[i], ioaddr + i);
+ iowrite8(dev->dev_addr[i], ioaddr + i);
for (; i < 12; i+=2)
- outw(0, ioaddr + i);
+ iowrite16(0, ioaddr + i);
if (vp->cb_fn_base) {
- unsigned short n = inw(ioaddr + Wn2_ResetOptions) & ~0x4010;
+ unsigned short n = ioread16(ioaddr + Wn2_ResetOptions) & ~0x4010;
if (vp->drv_flags & INVERT_LED_PWR)
n |= 0x10;
if (vp->drv_flags & INVERT_MII_PWR)
n |= 0x4000;
- outw(n, ioaddr + Wn2_ResetOptions);
+ iowrite16(n, ioaddr + Wn2_ResetOptions);
}
if (dev->if_port == XCVR_10base2)
/* Start the thinnet transceiver. We should really wait 50ms...*/
- outw(StartCoax, ioaddr + EL3_CMD);
+ iowrite16(StartCoax, ioaddr + EL3_CMD);
if (dev->if_port != XCVR_NWAY) {
EL3WINDOW(4);
- outw((inw(ioaddr + Wn4_Media) & ~(Media_10TP|Media_SQE)) |
+ iowrite16((ioread16(ioaddr + Wn4_Media) & ~(Media_10TP|Media_SQE)) |
media_tbl[dev->if_port].media_bits, ioaddr + Wn4_Media);
}
/* Switch to the stats window, and clear all stats by reading. */
- outw(StatsDisable, ioaddr + EL3_CMD);
+ iowrite16(StatsDisable, ioaddr + EL3_CMD);
EL3WINDOW(6);
for (i = 0; i < 10; i++)
- inb(ioaddr + i);
- inw(ioaddr + 10);
- inw(ioaddr + 12);
+ ioread8(ioaddr + i);
+ ioread16(ioaddr + 10);
+ ioread16(ioaddr + 12);
/* New: On the Vortex we must also clear the BadSSD counter. */
EL3WINDOW(4);
- inb(ioaddr + 12);
+ ioread8(ioaddr + 12);
/* ..and on the Boomerang we enable the extra statistics bits. */
- outw(0x0040, ioaddr + Wn4_NetDiag);
+ iowrite16(0x0040, ioaddr + Wn4_NetDiag);
/* Switch to register set 7 for normal use. */
EL3WINDOW(7);
@@ -1747,30 +1775,30 @@ vortex_up(struct net_device *dev)
if (vp->full_bus_master_rx) { /* Boomerang bus master. */
vp->cur_rx = vp->dirty_rx = 0;
/* Initialize the RxEarly register as recommended. */
- outw(SetRxThreshold + (1536>>2), ioaddr + EL3_CMD);
- outl(0x0020, ioaddr + PktStatus);
- outl(vp->rx_ring_dma, ioaddr + UpListPtr);
+ iowrite16(SetRxThreshold + (1536>>2), ioaddr + EL3_CMD);
+ iowrite32(0x0020, ioaddr + PktStatus);
+ iowrite32(vp->rx_ring_dma, ioaddr + UpListPtr);
}
if (vp->full_bus_master_tx) { /* Boomerang bus master Tx. */
vp->cur_tx = vp->dirty_tx = 0;
if (vp->drv_flags & IS_BOOMERANG)
- outb(PKT_BUF_SZ>>8, ioaddr + TxFreeThreshold); /* Room for a packet. */
+ iowrite8(PKT_BUF_SZ>>8, ioaddr + TxFreeThreshold); /* Room for a packet. */
/* Clear the Rx, Tx rings. */
for (i = 0; i < RX_RING_SIZE; i++) /* AKPM: this is done in vortex_open, too */
vp->rx_ring[i].status = 0;
for (i = 0; i < TX_RING_SIZE; i++)
vp->tx_skbuff[i] = NULL;
- outl(0, ioaddr + DownListPtr);
+ iowrite32(0, ioaddr + DownListPtr);
}
/* Set receiver mode: presumably accept b-case and phys addr only. */
set_rx_mode(dev);
/* enable 802.1q tagged frames */
set_8021q_mode(dev, 1);
- outw(StatsEnable, ioaddr + EL3_CMD); /* Turn on statistics. */
+ iowrite16(StatsEnable, ioaddr + EL3_CMD); /* Turn on statistics. */
// issue_and_wait(dev, SetTxStart|0x07ff);
- outw(RxEnable, ioaddr + EL3_CMD); /* Enable the receiver. */
- outw(TxEnable, ioaddr + EL3_CMD); /* Enable transmitter. */
+ iowrite16(RxEnable, ioaddr + EL3_CMD); /* Enable the receiver. */
+ iowrite16(TxEnable, ioaddr + EL3_CMD); /* Enable transmitter. */
/* Allow status bits to be seen. */
vp->status_enable = SetStatusEnb | HostError|IntReq|StatsFull|TxComplete|
(vp->full_bus_master_tx ? DownComplete : TxAvailable) |
@@ -1780,13 +1808,13 @@ vortex_up(struct net_device *dev)
(vp->full_bus_master_rx ? 0 : RxComplete) |
StatsFull | HostError | TxComplete | IntReq
| (vp->bus_master ? DMADone : 0) | UpComplete | DownComplete;
- outw(vp->status_enable, ioaddr + EL3_CMD);
+ iowrite16(vp->status_enable, ioaddr + EL3_CMD);
/* Ack all pending events, and set active indicator mask. */
- outw(AckIntr | IntLatch | TxAvailable | RxEarly | IntReq,
+ iowrite16(AckIntr | IntLatch | TxAvailable | RxEarly | IntReq,
ioaddr + EL3_CMD);
- outw(vp->intr_enable, ioaddr + EL3_CMD);
+ iowrite16(vp->intr_enable, ioaddr + EL3_CMD);
if (vp->cb_fn_base) /* The PCMCIA people are idiots. */
- writel(0x8000, vp->cb_fn_base + 4);
+ iowrite32(0x8000, vp->cb_fn_base + 4);
netif_start_queue (dev);
}
@@ -1852,7 +1880,7 @@ vortex_timer(unsigned long data)
{
struct net_device *dev = (struct net_device *)data;
struct vortex_private *vp = netdev_priv(dev);
- long ioaddr = dev->base_addr;
+ void __iomem *ioaddr = vp->ioaddr;
int next_tick = 60*HZ;
int ok = 0;
int media_status, mii_status, old_window;
@@ -1866,9 +1894,9 @@ vortex_timer(unsigned long data)
if (vp->medialock)
goto leave_media_alone;
disable_irq(dev->irq);
- old_window = inw(ioaddr + EL3_CMD) >> 13;
+ old_window = ioread16(ioaddr + EL3_CMD) >> 13;
EL3WINDOW(4);
- media_status = inw(ioaddr + Wn4_Media);
+ media_status = ioread16(ioaddr + Wn4_Media);
switch (dev->if_port) {
case XCVR_10baseT: case XCVR_100baseTx: case XCVR_100baseFx:
if (media_status & Media_LnkBeat) {
@@ -1888,14 +1916,17 @@ vortex_timer(unsigned long data)
case XCVR_MII: case XCVR_NWAY:
{
spin_lock_bh(&vp->lock);
- mii_status = mdio_read(dev, vp->phys[0], 1);
- mii_status = mdio_read(dev, vp->phys[0], 1);
+ mii_status = mdio_read(dev, vp->phys[0], MII_BMSR);
+ if (!(mii_status & BMSR_LSTATUS)) {
+ /* Re-read to get actual link status */
+ mii_status = mdio_read(dev, vp->phys[0], MII_BMSR);
+ }
ok = 1;
if (vortex_debug > 2)
printk(KERN_DEBUG "%s: MII transceiver has status %4.4x.\n",
dev->name, mii_status);
if (mii_status & BMSR_LSTATUS) {
- int mii_reg5 = mdio_read(dev, vp->phys[0], 5);
+ int mii_reg5 = mdio_read(dev, vp->phys[0], MII_LPA);
if (! vp->force_fd && mii_reg5 != 0xffff) {
int duplex;
@@ -1909,7 +1940,7 @@ vortex_timer(unsigned long data)
vp->phys[0], mii_reg5);
/* Set the full-duplex bit. */
EL3WINDOW(3);
- outw( (vp->full_duplex ? 0x20 : 0) |
+ iowrite16( (vp->full_duplex ? 0x20 : 0) |
(vp->large_frames ? 0x40 : 0) |
((vp->full_duplex && vp->flow_ctrl && vp->partner_flow_ctrl) ? 0x100 : 0),
ioaddr + Wn3_MAC_Ctrl);
@@ -1950,15 +1981,15 @@ vortex_timer(unsigned long data)
dev->name, media_tbl[dev->if_port].name);
next_tick = media_tbl[dev->if_port].wait;
}
- outw((media_status & ~(Media_10TP|Media_SQE)) |
+ iowrite16((media_status & ~(Media_10TP|Media_SQE)) |
media_tbl[dev->if_port].media_bits, ioaddr + Wn4_Media);
EL3WINDOW(3);
- config = inl(ioaddr + Wn3_Config);
+ config = ioread32(ioaddr + Wn3_Config);
config = BFINS(config, dev->if_port, 20, 4);
- outl(config, ioaddr + Wn3_Config);
+ iowrite32(config, ioaddr + Wn3_Config);
- outw(dev->if_port == XCVR_10base2 ? StartCoax : StopCoax,
+ iowrite16(dev->if_port == XCVR_10base2 ? StartCoax : StopCoax,
ioaddr + EL3_CMD);
if (vortex_debug > 1)
printk(KERN_DEBUG "wrote 0x%08x to Wn3_Config\n", config);
@@ -1974,29 +2005,29 @@ leave_media_alone:
mod_timer(&vp->timer, RUN_AT(next_tick));
if (vp->deferred)
- outw(FakeIntr, ioaddr + EL3_CMD);
+ iowrite16(FakeIntr, ioaddr + EL3_CMD);
return;
}
static void vortex_tx_timeout(struct net_device *dev)
{
struct vortex_private *vp = netdev_priv(dev);
- long ioaddr = dev->base_addr;
+ void __iomem *ioaddr = vp->ioaddr;
printk(KERN_ERR "%s: transmit timed out, tx_status %2.2x status %4.4x.\n",
- dev->name, inb(ioaddr + TxStatus),
- inw(ioaddr + EL3_STATUS));
+ dev->name, ioread8(ioaddr + TxStatus),
+ ioread16(ioaddr + EL3_STATUS));
EL3WINDOW(4);
printk(KERN_ERR " diagnostics: net %04x media %04x dma %08x fifo %04x\n",
- inw(ioaddr + Wn4_NetDiag),
- inw(ioaddr + Wn4_Media),
- inl(ioaddr + PktStatus),
- inw(ioaddr + Wn4_FIFODiag));
+ ioread16(ioaddr + Wn4_NetDiag),
+ ioread16(ioaddr + Wn4_Media),
+ ioread32(ioaddr + PktStatus),
+ ioread16(ioaddr + Wn4_FIFODiag));
/* Slight code bloat to be user friendly. */
- if ((inb(ioaddr + TxStatus) & 0x88) == 0x88)
+ if ((ioread8(ioaddr + TxStatus) & 0x88) == 0x88)
printk(KERN_ERR "%s: Transmitter encountered 16 collisions --"
" network cable problem?\n", dev->name);
- if (inw(ioaddr + EL3_STATUS) & IntLatch) {
+ if (ioread16(ioaddr + EL3_STATUS) & IntLatch) {
printk(KERN_ERR "%s: Interrupt posted but not delivered --"
" IRQ blocked by another device?\n", dev->name);
/* Bad idea here.. but we might as well handle a few events. */
@@ -2022,21 +2053,21 @@ static void vortex_tx_timeout(struct net_device *dev)
vp->stats.tx_errors++;
if (vp->full_bus_master_tx) {
printk(KERN_DEBUG "%s: Resetting the Tx ring pointer.\n", dev->name);
- if (vp->cur_tx - vp->dirty_tx > 0 && inl(ioaddr + DownListPtr) == 0)
- outl(vp->tx_ring_dma + (vp->dirty_tx % TX_RING_SIZE) * sizeof(struct boom_tx_desc),
+ if (vp->cur_tx - vp->dirty_tx > 0 && ioread32(ioaddr + DownListPtr) == 0)
+ iowrite32(vp->tx_ring_dma + (vp->dirty_tx % TX_RING_SIZE) * sizeof(struct boom_tx_desc),
ioaddr + DownListPtr);
if (vp->cur_tx - vp->dirty_tx < TX_RING_SIZE)
netif_wake_queue (dev);
if (vp->drv_flags & IS_BOOMERANG)
- outb(PKT_BUF_SZ>>8, ioaddr + TxFreeThreshold);
- outw(DownUnstall, ioaddr + EL3_CMD);
+ iowrite8(PKT_BUF_SZ>>8, ioaddr + TxFreeThreshold);
+ iowrite16(DownUnstall, ioaddr + EL3_CMD);
} else {
vp->stats.tx_dropped++;
netif_wake_queue(dev);
}
/* Issue Tx Enable */
- outw(TxEnable, ioaddr + EL3_CMD);
+ iowrite16(TxEnable, ioaddr + EL3_CMD);
dev->trans_start = jiffies;
/* Switch to register set 7 for normal use. */
@@ -2051,7 +2082,7 @@ static void
vortex_error(struct net_device *dev, int status)
{
struct vortex_private *vp = netdev_priv(dev);
- long ioaddr = dev->base_addr;
+ void __iomem *ioaddr = vp->ioaddr;
int do_tx_reset = 0, reset_mask = 0;
unsigned char tx_status = 0;
@@ -2060,7 +2091,7 @@ vortex_error(struct net_device *dev, int status)
}
if (status & TxComplete) { /* Really "TxError" for us. */
- tx_status = inb(ioaddr + TxStatus);
+ tx_status = ioread8(ioaddr + TxStatus);
/* Presumably a tx-timeout. We must merely re-enable. */
if (vortex_debug > 2
|| (tx_status != 0x88 && vortex_debug > 0)) {
@@ -2074,20 +2105,20 @@ vortex_error(struct net_device *dev, int status)
}
if (tx_status & 0x14) vp->stats.tx_fifo_errors++;
if (tx_status & 0x38) vp->stats.tx_aborted_errors++;
- outb(0, ioaddr + TxStatus);
+ iowrite8(0, ioaddr + TxStatus);
if (tx_status & 0x30) { /* txJabber or txUnderrun */
do_tx_reset = 1;
} else if ((tx_status & 0x08) && (vp->drv_flags & MAX_COLLISION_RESET)) { /* maxCollisions */
do_tx_reset = 1;
reset_mask = 0x0108; /* Reset interface logic, but not download logic */
} else { /* Merely re-enable the transmitter. */
- outw(TxEnable, ioaddr + EL3_CMD);
+ iowrite16(TxEnable, ioaddr + EL3_CMD);
}
}
if (status & RxEarly) { /* Rx early is unused. */
vortex_rx(dev);
- outw(AckIntr | RxEarly, ioaddr + EL3_CMD);
+ iowrite16(AckIntr | RxEarly, ioaddr + EL3_CMD);
}
if (status & StatsFull) { /* Empty statistics. */
static int DoneDidThat;
@@ -2097,29 +2128,29 @@ vortex_error(struct net_device *dev, int status)
/* HACK: Disable statistics as an interrupt source. */
/* This occurs when we have the wrong media type! */
if (DoneDidThat == 0 &&
- inw(ioaddr + EL3_STATUS) & StatsFull) {
+ ioread16(ioaddr + EL3_STATUS) & StatsFull) {
printk(KERN_WARNING "%s: Updating statistics failed, disabling "
"stats as an interrupt source.\n", dev->name);
EL3WINDOW(5);
- outw(SetIntrEnb | (inw(ioaddr + 10) & ~StatsFull), ioaddr + EL3_CMD);
+ iowrite16(SetIntrEnb | (ioread16(ioaddr + 10) & ~StatsFull), ioaddr + EL3_CMD);
vp->intr_enable &= ~StatsFull;
EL3WINDOW(7);
DoneDidThat++;
}
}
if (status & IntReq) { /* Restore all interrupt sources. */
- outw(vp->status_enable, ioaddr + EL3_CMD);
- outw(vp->intr_enable, ioaddr + EL3_CMD);
+ iowrite16(vp->status_enable, ioaddr + EL3_CMD);
+ iowrite16(vp->intr_enable, ioaddr + EL3_CMD);
}
if (status & HostError) {
u16 fifo_diag;
EL3WINDOW(4);
- fifo_diag = inw(ioaddr + Wn4_FIFODiag);
+ fifo_diag = ioread16(ioaddr + Wn4_FIFODiag);
printk(KERN_ERR "%s: Host error, FIFO diagnostic register %4.4x.\n",
dev->name, fifo_diag);
/* Adapter failure requires Tx/Rx reset and reinit. */
if (vp->full_bus_master_tx) {
- int bus_status = inl(ioaddr + PktStatus);
+ int bus_status = ioread32(ioaddr + PktStatus);
/* 0x80000000 PCI master abort. */
/* 0x40000000 PCI target abort. */
if (vortex_debug)
@@ -2139,14 +2170,14 @@ vortex_error(struct net_device *dev, int status)
set_rx_mode(dev);
/* enable 802.1q VLAN tagged frames */
set_8021q_mode(dev, 1);
- outw(RxEnable, ioaddr + EL3_CMD); /* Re-enable the receiver. */
- outw(AckIntr | HostError, ioaddr + EL3_CMD);
+ iowrite16(RxEnable, ioaddr + EL3_CMD); /* Re-enable the receiver. */
+ iowrite16(AckIntr | HostError, ioaddr + EL3_CMD);
}
}
if (do_tx_reset) {
issue_and_wait(dev, TxReset|reset_mask);
- outw(TxEnable, ioaddr + EL3_CMD);
+ iowrite16(TxEnable, ioaddr + EL3_CMD);
if (!vp->full_bus_master_tx)
netif_wake_queue(dev);
}
@@ -2156,29 +2187,29 @@ static int
vortex_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct vortex_private *vp = netdev_priv(dev);
- long ioaddr = dev->base_addr;
+ void __iomem *ioaddr = vp->ioaddr;
/* Put out the doubleword header... */
- outl(skb->len, ioaddr + TX_FIFO);
+ iowrite32(skb->len, ioaddr + TX_FIFO);
if (vp->bus_master) {
/* Set the bus-master controller to transfer the packet. */
int len = (skb->len + 3) & ~3;
- outl( vp->tx_skb_dma = pci_map_single(VORTEX_PCI(vp), skb->data, len, PCI_DMA_TODEVICE),
+ iowrite32( vp->tx_skb_dma = pci_map_single(VORTEX_PCI(vp), skb->data, len, PCI_DMA_TODEVICE),
ioaddr + Wn7_MasterAddr);
- outw(len, ioaddr + Wn7_MasterLen);
+ iowrite16(len, ioaddr + Wn7_MasterLen);
vp->tx_skb = skb;
- outw(StartDMADown, ioaddr + EL3_CMD);
+ iowrite16(StartDMADown, ioaddr + EL3_CMD);
/* netif_wake_queue() will be called at the DMADone interrupt. */
} else {
/* ... and the packet rounded to a doubleword. */
- outsl(ioaddr + TX_FIFO, skb->data, (skb->len + 3) >> 2);
+ iowrite32_rep(ioaddr + TX_FIFO, skb->data, (skb->len + 3) >> 2);
dev_kfree_skb (skb);
- if (inw(ioaddr + TxFree) > 1536) {
+ if (ioread16(ioaddr + TxFree) > 1536) {
netif_start_queue (dev); /* AKPM: redundant? */
} else {
/* Interrupt us when the FIFO has room for max-sized packet. */
netif_stop_queue(dev);
- outw(SetTxThreshold + (1536>>2), ioaddr + EL3_CMD);
+ iowrite16(SetTxThreshold + (1536>>2), ioaddr + EL3_CMD);
}
}
@@ -2189,7 +2220,7 @@ vortex_start_xmit(struct sk_buff *skb, struct net_device *dev)
int tx_status;
int i = 32;
- while (--i > 0 && (tx_status = inb(ioaddr + TxStatus)) > 0) {
+ while (--i > 0 && (tx_status = ioread8(ioaddr + TxStatus)) > 0) {
if (tx_status & 0x3C) { /* A Tx-disabling error occurred. */
if (vortex_debug > 2)
printk(KERN_DEBUG "%s: Tx error, status %2.2x.\n",
@@ -2199,9 +2230,9 @@ vortex_start_xmit(struct sk_buff *skb, struct net_device *dev)
if (tx_status & 0x30) {
issue_and_wait(dev, TxReset);
}
- outw(TxEnable, ioaddr + EL3_CMD);
+ iowrite16(TxEnable, ioaddr + EL3_CMD);
}
- outb(0x00, ioaddr + TxStatus); /* Pop the status stack. */
+ iowrite8(0x00, ioaddr + TxStatus); /* Pop the status stack. */
}
}
return 0;
@@ -2211,7 +2242,7 @@ static int
boomerang_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct vortex_private *vp = netdev_priv(dev);
- long ioaddr = dev->base_addr;
+ void __iomem *ioaddr = vp->ioaddr;
/* Calculate the next Tx descriptor entry. */
int entry = vp->cur_tx % TX_RING_SIZE;
struct boom_tx_desc *prev_entry = &vp->tx_ring[(vp->cur_tx-1) % TX_RING_SIZE];
@@ -2275,8 +2306,8 @@ boomerang_start_xmit(struct sk_buff *skb, struct net_device *dev)
/* Wait for the stall to complete. */
issue_and_wait(dev, DownStall);
prev_entry->next = cpu_to_le32(vp->tx_ring_dma + entry * sizeof(struct boom_tx_desc));
- if (inl(ioaddr + DownListPtr) == 0) {
- outl(vp->tx_ring_dma + entry * sizeof(struct boom_tx_desc), ioaddr + DownListPtr);
+ if (ioread32(ioaddr + DownListPtr) == 0) {
+ iowrite32(vp->tx_ring_dma + entry * sizeof(struct boom_tx_desc), ioaddr + DownListPtr);
vp->queued_packet++;
}
@@ -2291,7 +2322,7 @@ boomerang_start_xmit(struct sk_buff *skb, struct net_device *dev)
prev_entry->status &= cpu_to_le32(~TxIntrUploaded);
#endif
}
- outw(DownUnstall, ioaddr + EL3_CMD);
+ iowrite16(DownUnstall, ioaddr + EL3_CMD);
spin_unlock_irqrestore(&vp->lock, flags);
dev->trans_start = jiffies;
return 0;
@@ -2310,15 +2341,15 @@ vortex_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
struct net_device *dev = dev_id;
struct vortex_private *vp = netdev_priv(dev);
- long ioaddr;
+ void __iomem *ioaddr;
int status;
int work_done = max_interrupt_work;
int handled = 0;
- ioaddr = dev->base_addr;
+ ioaddr = vp->ioaddr;
spin_lock(&vp->lock);
- status = inw(ioaddr + EL3_STATUS);
+ status = ioread16(ioaddr + EL3_STATUS);
if (vortex_debug > 6)
printk("vortex_interrupt(). status=0x%4x\n", status);
@@ -2337,7 +2368,7 @@ vortex_interrupt(int irq, void *dev_id, struct pt_regs *regs)
if (vortex_debug > 4)
printk(KERN_DEBUG "%s: interrupt, status %4.4x, latency %d ticks.\n",
- dev->name, status, inb(ioaddr + Timer));
+ dev->name, status, ioread8(ioaddr + Timer));
do {
if (vortex_debug > 5)
@@ -2350,16 +2381,16 @@ vortex_interrupt(int irq, void *dev_id, struct pt_regs *regs)
if (vortex_debug > 5)
printk(KERN_DEBUG " TX room bit was handled.\n");
/* There's room in the FIFO for a full-sized packet. */
- outw(AckIntr | TxAvailable, ioaddr + EL3_CMD);
+ iowrite16(AckIntr | TxAvailable, ioaddr + EL3_CMD);
netif_wake_queue (dev);
}
if (status & DMADone) {
- if (inw(ioaddr + Wn7_MasterStatus) & 0x1000) {
- outw(0x1000, ioaddr + Wn7_MasterStatus); /* Ack the event. */
+ if (ioread16(ioaddr + Wn7_MasterStatus) & 0x1000) {
+ iowrite16(0x1000, ioaddr + Wn7_MasterStatus); /* Ack the event. */
pci_unmap_single(VORTEX_PCI(vp), vp->tx_skb_dma, (vp->tx_skb->len + 3) & ~3, PCI_DMA_TODEVICE);
dev_kfree_skb_irq(vp->tx_skb); /* Release the transferred buffer */
- if (inw(ioaddr + TxFree) > 1536) {
+ if (ioread16(ioaddr + TxFree) > 1536) {
/*
* AKPM: FIXME: I don't think we need this. If the queue was stopped due to
* insufficient FIFO room, the TxAvailable test will succeed and call
@@ -2367,7 +2398,7 @@ vortex_interrupt(int irq, void *dev_id, struct pt_regs *regs)
*/
netif_wake_queue(dev);
} else { /* Interrupt when FIFO has room for max-sized packet. */
- outw(SetTxThreshold + (1536>>2), ioaddr + EL3_CMD);
+ iowrite16(SetTxThreshold + (1536>>2), ioaddr + EL3_CMD);
netif_stop_queue(dev);
}
}
@@ -2385,17 +2416,17 @@ vortex_interrupt(int irq, void *dev_id, struct pt_regs *regs)
/* Disable all pending interrupts. */
do {
vp->deferred |= status;
- outw(SetStatusEnb | (~vp->deferred & vp->status_enable),
+ iowrite16(SetStatusEnb | (~vp->deferred & vp->status_enable),
ioaddr + EL3_CMD);
- outw(AckIntr | (vp->deferred & 0x7ff), ioaddr + EL3_CMD);
- } while ((status = inw(ioaddr + EL3_CMD)) & IntLatch);
+ iowrite16(AckIntr | (vp->deferred & 0x7ff), ioaddr + EL3_CMD);
+ } while ((status = ioread16(ioaddr + EL3_CMD)) & IntLatch);
/* The timer will reenable interrupts. */
mod_timer(&vp->timer, jiffies + 1*HZ);
break;
}
/* Acknowledge the IRQ. */
- outw(AckIntr | IntReq | IntLatch, ioaddr + EL3_CMD);
- } while ((status = inw(ioaddr + EL3_STATUS)) & (IntLatch | RxComplete));
+ iowrite16(AckIntr | IntReq | IntLatch, ioaddr + EL3_CMD);
+ } while ((status = ioread16(ioaddr + EL3_STATUS)) & (IntLatch | RxComplete));
if (vortex_debug > 4)
printk(KERN_DEBUG "%s: exiting interrupt, status %4.4x.\n",
@@ -2415,11 +2446,11 @@ boomerang_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
struct net_device *dev = dev_id;
struct vortex_private *vp = netdev_priv(dev);
- long ioaddr;
+ void __iomem *ioaddr;
int status;
int work_done = max_interrupt_work;
- ioaddr = dev->base_addr;
+ ioaddr = vp->ioaddr;
/*
* It seems dopey to put the spinlock this early, but we could race against vortex_tx_timeout
@@ -2427,7 +2458,7 @@ boomerang_interrupt(int irq, void *dev_id, struct pt_regs *regs)
*/
spin_lock(&vp->lock);
- status = inw(ioaddr + EL3_STATUS);
+ status = ioread16(ioaddr + EL3_STATUS);
if (vortex_debug > 6)
printk(KERN_DEBUG "boomerang_interrupt. status=0x%4x\n", status);
@@ -2448,13 +2479,13 @@ boomerang_interrupt(int irq, void *dev_id, struct pt_regs *regs)
if (vortex_debug > 4)
printk(KERN_DEBUG "%s: interrupt, status %4.4x, latency %d ticks.\n",
- dev->name, status, inb(ioaddr + Timer));
+ dev->name, status, ioread8(ioaddr + Timer));
do {
if (vortex_debug > 5)
printk(KERN_DEBUG "%s: In interrupt loop, status %4.4x.\n",
dev->name, status);
if (status & UpComplete) {
- outw(AckIntr | UpComplete, ioaddr + EL3_CMD);
+ iowrite16(AckIntr | UpComplete, ioaddr + EL3_CMD);
if (vortex_debug > 5)
printk(KERN_DEBUG "boomerang_interrupt->boomerang_rx\n");
boomerang_rx(dev);
@@ -2463,11 +2494,11 @@ boomerang_interrupt(int irq, void *dev_id, struct pt_regs *regs)
if (status & DownComplete) {
unsigned int dirty_tx = vp->dirty_tx;
- outw(AckIntr | DownComplete, ioaddr + EL3_CMD);
+ iowrite16(AckIntr | DownComplete, ioaddr + EL3_CMD);
while (vp->cur_tx - dirty_tx > 0) {
int entry = dirty_tx % TX_RING_SIZE;
#if 1 /* AKPM: the latter is faster, but cyclone-only */
- if (inl(ioaddr + DownListPtr) ==
+ if (ioread32(ioaddr + DownListPtr) ==
vp->tx_ring_dma + entry * sizeof(struct boom_tx_desc))
break; /* It still hasn't been processed. */
#else
@@ -2514,20 +2545,20 @@ boomerang_interrupt(int irq, void *dev_id, struct pt_regs *regs)
/* Disable all pending interrupts. */
do {
vp->deferred |= status;
- outw(SetStatusEnb | (~vp->deferred & vp->status_enable),
+ iowrite16(SetStatusEnb | (~vp->deferred & vp->status_enable),
ioaddr + EL3_CMD);
- outw(AckIntr | (vp->deferred & 0x7ff), ioaddr + EL3_CMD);
- } while ((status = inw(ioaddr + EL3_CMD)) & IntLatch);
+ iowrite16(AckIntr | (vp->deferred & 0x7ff), ioaddr + EL3_CMD);
+ } while ((status = ioread16(ioaddr + EL3_CMD)) & IntLatch);
/* The timer will reenable interrupts. */
mod_timer(&vp->timer, jiffies + 1*HZ);
break;
}
/* Acknowledge the IRQ. */
- outw(AckIntr | IntReq | IntLatch, ioaddr + EL3_CMD);
+ iowrite16(AckIntr | IntReq | IntLatch, ioaddr + EL3_CMD);
if (vp->cb_fn_base) /* The PCMCIA people are idiots. */
- writel(0x8000, vp->cb_fn_base + 4);
+ iowrite32(0x8000, vp->cb_fn_base + 4);
- } while ((status = inw(ioaddr + EL3_STATUS)) & IntLatch);
+ } while ((status = ioread16(ioaddr + EL3_STATUS)) & IntLatch);
if (vortex_debug > 4)
printk(KERN_DEBUG "%s: exiting interrupt, status %4.4x.\n",
@@ -2540,16 +2571,16 @@ handler_exit:
static int vortex_rx(struct net_device *dev)
{
struct vortex_private *vp = netdev_priv(dev);
- long ioaddr = dev->base_addr;
+ void __iomem *ioaddr = vp->ioaddr;
int i;
short rx_status;
if (vortex_debug > 5)
printk(KERN_DEBUG "vortex_rx(): status %4.4x, rx_status %4.4x.\n",
- inw(ioaddr+EL3_STATUS), inw(ioaddr+RxStatus));
- while ((rx_status = inw(ioaddr + RxStatus)) > 0) {
+ ioread16(ioaddr+EL3_STATUS), ioread16(ioaddr+RxStatus));
+ while ((rx_status = ioread16(ioaddr + RxStatus)) > 0) {
if (rx_status & 0x4000) { /* Error, update stats. */
- unsigned char rx_error = inb(ioaddr + RxErrors);
+ unsigned char rx_error = ioread8(ioaddr + RxErrors);
if (vortex_debug > 2)
printk(KERN_DEBUG " Rx error: status %2.2x.\n", rx_error);
vp->stats.rx_errors++;
@@ -2572,34 +2603,35 @@ static int vortex_rx(struct net_device *dev)
skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */
/* 'skb_put()' points to the start of sk_buff data area. */
if (vp->bus_master &&
- ! (inw(ioaddr + Wn7_MasterStatus) & 0x8000)) {
+ ! (ioread16(ioaddr + Wn7_MasterStatus) & 0x8000)) {
dma_addr_t dma = pci_map_single(VORTEX_PCI(vp), skb_put(skb, pkt_len),
pkt_len, PCI_DMA_FROMDEVICE);
- outl(dma, ioaddr + Wn7_MasterAddr);
- outw((skb->len + 3) & ~3, ioaddr + Wn7_MasterLen);
- outw(StartDMAUp, ioaddr + EL3_CMD);
- while (inw(ioaddr + Wn7_MasterStatus) & 0x8000)
+ iowrite32(dma, ioaddr + Wn7_MasterAddr);
+ iowrite16((skb->len + 3) & ~3, ioaddr + Wn7_MasterLen);
+ iowrite16(StartDMAUp, ioaddr + EL3_CMD);
+ while (ioread16(ioaddr + Wn7_MasterStatus) & 0x8000)
;
pci_unmap_single(VORTEX_PCI(vp), dma, pkt_len, PCI_DMA_FROMDEVICE);
} else {
- insl(ioaddr + RX_FIFO, skb_put(skb, pkt_len),
- (pkt_len + 3) >> 2);
+ ioread32_rep(ioaddr + RX_FIFO,
+ skb_put(skb, pkt_len),
+ (pkt_len + 3) >> 2);
}
- outw(RxDiscard, ioaddr + EL3_CMD); /* Pop top Rx packet. */
+ iowrite16(RxDiscard, ioaddr + EL3_CMD); /* Pop top Rx packet. */
skb->protocol = eth_type_trans(skb, dev);
netif_rx(skb);
dev->last_rx = jiffies;
vp->stats.rx_packets++;
/* Wait a limited time to go to next packet. */
for (i = 200; i >= 0; i--)
- if ( ! (inw(ioaddr + EL3_STATUS) & CmdInProgress))
+ if ( ! (ioread16(ioaddr + EL3_STATUS) & CmdInProgress))
break;
continue;
} else if (vortex_debug > 0)
printk(KERN_NOTICE "%s: No memory to allocate a sk_buff of "
"size %d.\n", dev->name, pkt_len);
+ vp->stats.rx_dropped++;
}
- vp->stats.rx_dropped++;
issue_and_wait(dev, RxDiscard);
}
@@ -2611,12 +2643,12 @@ boomerang_rx(struct net_device *dev)
{
struct vortex_private *vp = netdev_priv(dev);
int entry = vp->cur_rx % RX_RING_SIZE;
- long ioaddr = dev->base_addr;
+ void __iomem *ioaddr = vp->ioaddr;
int rx_status;
int rx_work_limit = vp->dirty_rx + RX_RING_SIZE - vp->cur_rx;
if (vortex_debug > 5)
- printk(KERN_DEBUG "boomerang_rx(): status %4.4x\n", inw(ioaddr+EL3_STATUS));
+ printk(KERN_DEBUG "boomerang_rx(): status %4.4x\n", ioread16(ioaddr+EL3_STATUS));
while ((rx_status = le32_to_cpu(vp->rx_ring[entry].status)) & RxDComplete){
if (--rx_work_limit < 0)
@@ -2699,7 +2731,7 @@ boomerang_rx(struct net_device *dev)
vp->rx_skbuff[entry] = skb;
}
vp->rx_ring[entry].status = 0; /* Clear complete bit. */
- outw(UpUnstall, ioaddr + EL3_CMD);
+ iowrite16(UpUnstall, ioaddr + EL3_CMD);
}
return 0;
}
@@ -2728,7 +2760,7 @@ static void
vortex_down(struct net_device *dev, int final_down)
{
struct vortex_private *vp = netdev_priv(dev);
- long ioaddr = dev->base_addr;
+ void __iomem *ioaddr = vp->ioaddr;
netif_stop_queue (dev);
@@ -2736,26 +2768,26 @@ vortex_down(struct net_device *dev, int final_down)
del_timer_sync(&vp->timer);
/* Turn off statistics ASAP. We update vp->stats below. */
- outw(StatsDisable, ioaddr + EL3_CMD);
+ iowrite16(StatsDisable, ioaddr + EL3_CMD);
/* Disable the receiver and transmitter. */
- outw(RxDisable, ioaddr + EL3_CMD);
- outw(TxDisable, ioaddr + EL3_CMD);
+ iowrite16(RxDisable, ioaddr + EL3_CMD);
+ iowrite16(TxDisable, ioaddr + EL3_CMD);
/* Disable receiving 802.1q tagged frames */
set_8021q_mode(dev, 0);
if (dev->if_port == XCVR_10base2)
/* Turn off thinnet power. Green! */
- outw(StopCoax, ioaddr + EL3_CMD);
+ iowrite16(StopCoax, ioaddr + EL3_CMD);
- outw(SetIntrEnb | 0x0000, ioaddr + EL3_CMD);
+ iowrite16(SetIntrEnb | 0x0000, ioaddr + EL3_CMD);
update_stats(ioaddr, dev);
if (vp->full_bus_master_rx)
- outl(0, ioaddr + UpListPtr);
+ iowrite32(0, ioaddr + UpListPtr);
if (vp->full_bus_master_tx)
- outl(0, ioaddr + DownListPtr);
+ iowrite32(0, ioaddr + DownListPtr);
if (final_down && VORTEX_PCI(vp)) {
vp->pm_state_valid = 1;
@@ -2768,7 +2800,7 @@ static int
vortex_close(struct net_device *dev)
{
struct vortex_private *vp = netdev_priv(dev);
- long ioaddr = dev->base_addr;
+ void __iomem *ioaddr = vp->ioaddr;
int i;
if (netif_device_present(dev))
@@ -2776,17 +2808,18 @@ vortex_close(struct net_device *dev)
if (vortex_debug > 1) {
printk(KERN_DEBUG"%s: vortex_close() status %4.4x, Tx status %2.2x.\n",
- dev->name, inw(ioaddr + EL3_STATUS), inb(ioaddr + TxStatus));
+ dev->name, ioread16(ioaddr + EL3_STATUS), ioread8(ioaddr + TxStatus));
printk(KERN_DEBUG "%s: vortex close stats: rx_nocopy %d rx_copy %d"
" tx_queued %d Rx pre-checksummed %d.\n",
dev->name, vp->rx_nocopy, vp->rx_copy, vp->queued_packet, vp->rx_csumhits);
}
#if DO_ZEROCOPY
- if ( vp->rx_csumhits &&
- ((vp->drv_flags & HAS_HWCKSM) == 0) &&
- (hw_checksums[vp->card_idx] == -1)) {
- printk(KERN_WARNING "%s supports hardware checksums, and we're not using them!\n", dev->name);
+ if (vp->rx_csumhits &&
+ (vp->drv_flags & HAS_HWCKSM) == 0 &&
+ (vp->card_idx >= MAX_UNITS || hw_checksums[vp->card_idx] == -1)) {
+ printk(KERN_WARNING "%s supports hardware checksums, and we're "
+ "not using them!\n", dev->name);
}
#endif
@@ -2830,18 +2863,18 @@ dump_tx_ring(struct net_device *dev)
{
if (vortex_debug > 0) {
struct vortex_private *vp = netdev_priv(dev);
- long ioaddr = dev->base_addr;
+ void __iomem *ioaddr = vp->ioaddr;
if (vp->full_bus_master_tx) {
int i;
- int stalled = inl(ioaddr + PktStatus) & 0x04; /* Possible racy. But it's only debug stuff */
+ int stalled = ioread32(ioaddr + PktStatus) & 0x04; /* Possible racy. But it's only debug stuff */
printk(KERN_ERR " Flags; bus-master %d, dirty %d(%d) current %d(%d)\n",
vp->full_bus_master_tx,
vp->dirty_tx, vp->dirty_tx % TX_RING_SIZE,
vp->cur_tx, vp->cur_tx % TX_RING_SIZE);
printk(KERN_ERR " Transmit list %8.8x vs. %p.\n",
- inl(ioaddr + DownListPtr),
+ ioread32(ioaddr + DownListPtr),
&vp->tx_ring[vp->dirty_tx % TX_RING_SIZE]);
issue_and_wait(dev, DownStall);
for (i = 0; i < TX_RING_SIZE; i++) {
@@ -2855,7 +2888,7 @@ dump_tx_ring(struct net_device *dev)
le32_to_cpu(vp->tx_ring[i].status));
}
if (!stalled)
- outw(DownUnstall, ioaddr + EL3_CMD);
+ iowrite16(DownUnstall, ioaddr + EL3_CMD);
}
}
}
@@ -2863,11 +2896,12 @@ dump_tx_ring(struct net_device *dev)
static struct net_device_stats *vortex_get_stats(struct net_device *dev)
{
struct vortex_private *vp = netdev_priv(dev);
+ void __iomem *ioaddr = vp->ioaddr;
unsigned long flags;
if (netif_device_present(dev)) { /* AKPM: Used to be netif_running */
spin_lock_irqsave (&vp->lock, flags);
- update_stats(dev->base_addr, dev);
+ update_stats(ioaddr, dev);
spin_unlock_irqrestore (&vp->lock, flags);
}
return &vp->stats;
@@ -2880,37 +2914,37 @@ static struct net_device_stats *vortex_get_stats(struct net_device *dev)
table. This is done by checking that the ASM (!) code generated uses
atomic updates with '+='.
*/
-static void update_stats(long ioaddr, struct net_device *dev)
+static void update_stats(void __iomem *ioaddr, struct net_device *dev)
{
struct vortex_private *vp = netdev_priv(dev);
- int old_window = inw(ioaddr + EL3_CMD);
+ int old_window = ioread16(ioaddr + EL3_CMD);
if (old_window == 0xffff) /* Chip suspended or ejected. */
return;
/* Unlike the 3c5x9 we need not turn off stats updates while reading. */
/* Switch to the stats window, and read everything. */
EL3WINDOW(6);
- vp->stats.tx_carrier_errors += inb(ioaddr + 0);
- vp->stats.tx_heartbeat_errors += inb(ioaddr + 1);
- vp->stats.collisions += inb(ioaddr + 3);
- vp->stats.tx_window_errors += inb(ioaddr + 4);
- vp->stats.rx_fifo_errors += inb(ioaddr + 5);
- vp->stats.tx_packets += inb(ioaddr + 6);
- vp->stats.tx_packets += (inb(ioaddr + 9)&0x30) << 4;
- /* Rx packets */ inb(ioaddr + 7); /* Must read to clear */
+ vp->stats.tx_carrier_errors += ioread8(ioaddr + 0);
+ vp->stats.tx_heartbeat_errors += ioread8(ioaddr + 1);
+ vp->stats.collisions += ioread8(ioaddr + 3);
+ vp->stats.tx_window_errors += ioread8(ioaddr + 4);
+ vp->stats.rx_fifo_errors += ioread8(ioaddr + 5);
+ vp->stats.tx_packets += ioread8(ioaddr + 6);
+ vp->stats.tx_packets += (ioread8(ioaddr + 9)&0x30) << 4;
+ /* Rx packets */ ioread8(ioaddr + 7); /* Must read to clear */
/* Don't bother with register 9, an extension of registers 6&7.
If we do use the 6&7 values the atomic update assumption above
is invalid. */
- vp->stats.rx_bytes += inw(ioaddr + 10);
- vp->stats.tx_bytes += inw(ioaddr + 12);
+ vp->stats.rx_bytes += ioread16(ioaddr + 10);
+ vp->stats.tx_bytes += ioread16(ioaddr + 12);
/* Extra stats for get_ethtool_stats() */
- vp->xstats.tx_multiple_collisions += inb(ioaddr + 2);
- vp->xstats.tx_deferred += inb(ioaddr + 8);
+ vp->xstats.tx_multiple_collisions += ioread8(ioaddr + 2);
+ vp->xstats.tx_deferred += ioread8(ioaddr + 8);
EL3WINDOW(4);
- vp->xstats.rx_bad_ssd += inb(ioaddr + 12);
+ vp->xstats.rx_bad_ssd += ioread8(ioaddr + 12);
{
- u8 up = inb(ioaddr + 13);
+ u8 up = ioread8(ioaddr + 13);
vp->stats.rx_bytes += (up & 0x0f) << 16;
vp->stats.tx_bytes += (up & 0xf0) << 12;
}
@@ -2922,7 +2956,7 @@ static void update_stats(long ioaddr, struct net_device *dev)
static int vortex_nway_reset(struct net_device *dev)
{
struct vortex_private *vp = netdev_priv(dev);
- long ioaddr = dev->base_addr;
+ void __iomem *ioaddr = vp->ioaddr;
unsigned long flags;
int rc;
@@ -2936,7 +2970,7 @@ static int vortex_nway_reset(struct net_device *dev)
static u32 vortex_get_link(struct net_device *dev)
{
struct vortex_private *vp = netdev_priv(dev);
- long ioaddr = dev->base_addr;
+ void __iomem *ioaddr = vp->ioaddr;
unsigned long flags;
int rc;
@@ -2950,7 +2984,7 @@ static u32 vortex_get_link(struct net_device *dev)
static int vortex_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
{
struct vortex_private *vp = netdev_priv(dev);
- long ioaddr = dev->base_addr;
+ void __iomem *ioaddr = vp->ioaddr;
unsigned long flags;
int rc;
@@ -2964,7 +2998,7 @@ static int vortex_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
static int vortex_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
{
struct vortex_private *vp = netdev_priv(dev);
- long ioaddr = dev->base_addr;
+ void __iomem *ioaddr = vp->ioaddr;
unsigned long flags;
int rc;
@@ -2994,10 +3028,11 @@ static void vortex_get_ethtool_stats(struct net_device *dev,
struct ethtool_stats *stats, u64 *data)
{
struct vortex_private *vp = netdev_priv(dev);
+ void __iomem *ioaddr = vp->ioaddr;
unsigned long flags;
spin_lock_irqsave(&vp->lock, flags);
- update_stats(dev->base_addr, dev);
+ update_stats(ioaddr, dev);
spin_unlock_irqrestore(&vp->lock, flags);
data[0] = vp->xstats.tx_deferred;
@@ -3047,6 +3082,7 @@ static struct ethtool_ops vortex_ethtool_ops = {
.set_settings = vortex_set_settings,
.get_link = vortex_get_link,
.nway_reset = vortex_nway_reset,
+ .get_perm_addr = ethtool_op_get_perm_addr,
};
#ifdef CONFIG_PCI
@@ -3057,7 +3093,7 @@ static int vortex_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
{
int err;
struct vortex_private *vp = netdev_priv(dev);
- long ioaddr = dev->base_addr;
+ void __iomem *ioaddr = vp->ioaddr;
unsigned long flags;
int state = 0;
@@ -3085,7 +3121,8 @@ static int vortex_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
the chip has a very clean way to set the mode, unlike many others. */
static void set_rx_mode(struct net_device *dev)
{
- long ioaddr = dev->base_addr;
+ struct vortex_private *vp = netdev_priv(dev);
+ void __iomem *ioaddr = vp->ioaddr;
int new_mode;
if (dev->flags & IFF_PROMISC) {
@@ -3097,7 +3134,7 @@ static void set_rx_mode(struct net_device *dev)
} else
new_mode = SetRxFilter | RxStation | RxBroadcast;
- outw(new_mode, ioaddr + EL3_CMD);
+ iowrite16(new_mode, ioaddr + EL3_CMD);
}
#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
@@ -3111,8 +3148,8 @@ static void set_rx_mode(struct net_device *dev)
static void set_8021q_mode(struct net_device *dev, int enable)
{
struct vortex_private *vp = netdev_priv(dev);
- long ioaddr = dev->base_addr;
- int old_window = inw(ioaddr + EL3_CMD);
+ void __iomem *ioaddr = vp->ioaddr;
+ int old_window = ioread16(ioaddr + EL3_CMD);
int mac_ctrl;
if ((vp->drv_flags&IS_CYCLONE) || (vp->drv_flags&IS_TORNADO)) {
@@ -3124,24 +3161,24 @@ static void set_8021q_mode(struct net_device *dev, int enable)
max_pkt_size += 4; /* 802.1Q VLAN tag */
EL3WINDOW(3);
- outw(max_pkt_size, ioaddr+Wn3_MaxPktSize);
+ iowrite16(max_pkt_size, ioaddr+Wn3_MaxPktSize);
/* set VlanEtherType to let the hardware checksumming
treat tagged frames correctly */
EL3WINDOW(7);
- outw(VLAN_ETHER_TYPE, ioaddr+Wn7_VlanEtherType);
+ iowrite16(VLAN_ETHER_TYPE, ioaddr+Wn7_VlanEtherType);
} else {
/* on older cards we have to enable large frames */
vp->large_frames = dev->mtu > 1500 || enable;
EL3WINDOW(3);
- mac_ctrl = inw(ioaddr+Wn3_MAC_Ctrl);
+ mac_ctrl = ioread16(ioaddr+Wn3_MAC_Ctrl);
if (vp->large_frames)
mac_ctrl |= 0x40;
else
mac_ctrl &= ~0x40;
- outw(mac_ctrl, ioaddr+Wn3_MAC_Ctrl);
+ iowrite16(mac_ctrl, ioaddr+Wn3_MAC_Ctrl);
}
EL3WINDOW(old_window);
@@ -3163,7 +3200,7 @@ static void set_8021q_mode(struct net_device *dev, int enable)
/* The maximum data clock rate is 2.5 Mhz. The minimum timing is usually
met by back-to-back PCI I/O cycles, but we insert a delay to avoid
"overclocking" issues. */
-#define mdio_delay() inl(mdio_addr)
+#define mdio_delay() ioread32(mdio_addr)
#define MDIO_SHIFT_CLK 0x01
#define MDIO_DIR_WRITE 0x04
@@ -3174,15 +3211,15 @@ static void set_8021q_mode(struct net_device *dev, int enable)
/* Generate the preamble required for initial synchronization and
a few older transceivers. */
-static void mdio_sync(long ioaddr, int bits)
+static void mdio_sync(void __iomem *ioaddr, int bits)
{
- long mdio_addr = ioaddr + Wn4_PhysicalMgmt;
+ void __iomem *mdio_addr = ioaddr + Wn4_PhysicalMgmt;
/* Establish sync by sending at least 32 logic ones. */
while (-- bits >= 0) {
- outw(MDIO_DATA_WRITE1, mdio_addr);
+ iowrite16(MDIO_DATA_WRITE1, mdio_addr);
mdio_delay();
- outw(MDIO_DATA_WRITE1 | MDIO_SHIFT_CLK, mdio_addr);
+ iowrite16(MDIO_DATA_WRITE1 | MDIO_SHIFT_CLK, mdio_addr);
mdio_delay();
}
}
@@ -3190,10 +3227,11 @@ static void mdio_sync(long ioaddr, int bits)
static int mdio_read(struct net_device *dev, int phy_id, int location)
{
int i;
- long ioaddr = dev->base_addr;
+ struct vortex_private *vp = netdev_priv(dev);
+ void __iomem *ioaddr = vp->ioaddr;
int read_cmd = (0xf6 << 10) | (phy_id << 5) | location;
unsigned int retval = 0;
- long mdio_addr = ioaddr + Wn4_PhysicalMgmt;
+ void __iomem *mdio_addr = ioaddr + Wn4_PhysicalMgmt;
if (mii_preamble_required)
mdio_sync(ioaddr, 32);
@@ -3201,17 +3239,17 @@ static int mdio_read(struct net_device *dev, int phy_id, int location)
/* Shift the read command bits out. */
for (i = 14; i >= 0; i--) {
int dataval = (read_cmd&(1<<i)) ? MDIO_DATA_WRITE1 : MDIO_DATA_WRITE0;
- outw(dataval, mdio_addr);
+ iowrite16(dataval, mdio_addr);
mdio_delay();
- outw(dataval | MDIO_SHIFT_CLK, mdio_addr);
+ iowrite16(dataval | MDIO_SHIFT_CLK, mdio_addr);
mdio_delay();
}
/* Read the two transition, 16 data, and wire-idle bits. */
for (i = 19; i > 0; i--) {
- outw(MDIO_ENB_IN, mdio_addr);
+ iowrite16(MDIO_ENB_IN, mdio_addr);
mdio_delay();
- retval = (retval << 1) | ((inw(mdio_addr) & MDIO_DATA_READ) ? 1 : 0);
- outw(MDIO_ENB_IN | MDIO_SHIFT_CLK, mdio_addr);
+ retval = (retval << 1) | ((ioread16(mdio_addr) & MDIO_DATA_READ) ? 1 : 0);
+ iowrite16(MDIO_ENB_IN | MDIO_SHIFT_CLK, mdio_addr);
mdio_delay();
}
return retval & 0x20000 ? 0xffff : retval>>1 & 0xffff;
@@ -3219,9 +3257,10 @@ static int mdio_read(struct net_device *dev, int phy_id, int location)
static void mdio_write(struct net_device *dev, int phy_id, int location, int value)
{
- long ioaddr = dev->base_addr;
+ struct vortex_private *vp = netdev_priv(dev);
+ void __iomem *ioaddr = vp->ioaddr;
int write_cmd = 0x50020000 | (phy_id << 23) | (location << 18) | value;
- long mdio_addr = ioaddr + Wn4_PhysicalMgmt;
+ void __iomem *mdio_addr = ioaddr + Wn4_PhysicalMgmt;
int i;
if (mii_preamble_required)
@@ -3230,16 +3269,16 @@ static void mdio_write(struct net_device *dev, int phy_id, int location, int val
/* Shift the command bits out. */
for (i = 31; i >= 0; i--) {
int dataval = (write_cmd&(1<<i)) ? MDIO_DATA_WRITE1 : MDIO_DATA_WRITE0;
- outw(dataval, mdio_addr);
+ iowrite16(dataval, mdio_addr);
mdio_delay();
- outw(dataval | MDIO_SHIFT_CLK, mdio_addr);
+ iowrite16(dataval | MDIO_SHIFT_CLK, mdio_addr);
mdio_delay();
}
/* Leave the interface idle. */
for (i = 1; i >= 0; i--) {
- outw(MDIO_ENB_IN, mdio_addr);
+ iowrite16(MDIO_ENB_IN, mdio_addr);
mdio_delay();
- outw(MDIO_ENB_IN | MDIO_SHIFT_CLK, mdio_addr);
+ iowrite16(MDIO_ENB_IN | MDIO_SHIFT_CLK, mdio_addr);
mdio_delay();
}
return;
@@ -3250,15 +3289,15 @@ static void mdio_write(struct net_device *dev, int phy_id, int location, int val
static void acpi_set_WOL(struct net_device *dev)
{
struct vortex_private *vp = netdev_priv(dev);
- long ioaddr = dev->base_addr;
+ void __iomem *ioaddr = vp->ioaddr;
if (vp->enable_wol) {
/* Power up on: 1==Downloaded Filter, 2==Magic Packets, 4==Link Status. */
EL3WINDOW(7);
- outw(2, ioaddr + 0x0c);
+ iowrite16(2, ioaddr + 0x0c);
/* The RxFilter must accept the WOL frames. */
- outw(SetRxFilter|RxStation|RxMulticast|RxBroadcast, ioaddr + EL3_CMD);
- outw(RxEnable, ioaddr + EL3_CMD);
+ iowrite16(SetRxFilter|RxStation|RxMulticast|RxBroadcast, ioaddr + EL3_CMD);
+ iowrite16(RxEnable, ioaddr + EL3_CMD);
pci_enable_wake(VORTEX_PCI(vp), 0, 1);
@@ -3280,10 +3319,9 @@ static void __devexit vortex_remove_one (struct pci_dev *pdev)
vp = netdev_priv(dev);
- /* AKPM: FIXME: we should have
- * if (vp->cb_fn_base) iounmap(vp->cb_fn_base);
- * here
- */
+ if (vp->cb_fn_base)
+ pci_iounmap(VORTEX_PCI(vp), vp->cb_fn_base);
+
unregister_netdev(dev);
if (VORTEX_PCI(vp)) {
@@ -3293,8 +3331,10 @@ static void __devexit vortex_remove_one (struct pci_dev *pdev)
pci_disable_device(VORTEX_PCI(vp));
}
/* Should really use issue_and_wait() here */
- outw(TotalReset | ((vp->drv_flags & EEPROM_RESET) ? 0x04 : 0x14),
- dev->base_addr + EL3_CMD);
+ iowrite16(TotalReset | ((vp->drv_flags & EEPROM_RESET) ? 0x04 : 0x14),
+ vp->ioaddr + EL3_CMD);
+
+ pci_iounmap(VORTEX_PCI(vp), vp->ioaddr);
pci_free_consistent(pdev,
sizeof(struct boom_rx_desc) * RX_RING_SIZE
@@ -3342,7 +3382,7 @@ static int __init vortex_init (void)
static void __exit vortex_eisa_cleanup (void)
{
struct vortex_private *vp;
- long ioaddr;
+ void __iomem *ioaddr;
#ifdef CONFIG_EISA
/* Take care of the EISA devices */
@@ -3351,11 +3391,13 @@ static void __exit vortex_eisa_cleanup (void)
if (compaq_net_device) {
vp = compaq_net_device->priv;
- ioaddr = compaq_net_device->base_addr;
+ ioaddr = ioport_map(compaq_net_device->base_addr,
+ VORTEX_TOTAL_SIZE);
unregister_netdev (compaq_net_device);
- outw (TotalReset, ioaddr + EL3_CMD);
- release_region (ioaddr, VORTEX_TOTAL_SIZE);
+ iowrite16 (TotalReset, ioaddr + EL3_CMD);
+ release_region(compaq_net_device->base_addr,
+ VORTEX_TOTAL_SIZE);
free_netdev (compaq_net_device);
}
diff --git a/drivers/net/8139cp.c b/drivers/net/8139cp.c
index bc537440ca02..f822cd3025ff 100644
--- a/drivers/net/8139cp.c
+++ b/drivers/net/8139cp.c
@@ -1027,8 +1027,7 @@ static void cp_reset_hw (struct cp_private *cp)
if (!(cpr8(Cmd) & CmdReset))
return;
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(10);
+ schedule_timeout_uninterruptible(10);
}
printk(KERN_ERR "%s: hardware reset timeout\n", cp->dev->name);
@@ -1575,6 +1574,7 @@ static struct ethtool_ops cp_ethtool_ops = {
.set_wol = cp_set_wol,
.get_strings = cp_get_strings,
.get_ethtool_stats = cp_get_ethtool_stats,
+ .get_perm_addr = ethtool_op_get_perm_addr,
};
static int cp_ioctl (struct net_device *dev, struct ifreq *rq, int cmd)
@@ -1773,6 +1773,7 @@ static int cp_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
for (i = 0; i < 3; i++)
((u16 *) (dev->dev_addr))[i] =
le16_to_cpu (read_eeprom (regs, i + 7, addr_len));
+ memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
dev->open = cp_open;
dev->stop = cp_close;
diff --git a/drivers/net/8139too.c b/drivers/net/8139too.c
index 4c2cf7bbd252..30bee11c48bd 100644
--- a/drivers/net/8139too.c
+++ b/drivers/net/8139too.c
@@ -552,7 +552,8 @@ const static struct {
{ "RTL-8100B/8139D",
HW_REVID(1, 1, 1, 0, 1, 0, 1),
- HasLWake,
+ HasHltClk /* XXX undocumented? */
+ | HasLWake,
},
{ "RTL-8101",
@@ -970,6 +971,7 @@ static int __devinit rtl8139_init_one (struct pci_dev *pdev,
for (i = 0; i < 3; i++)
((u16 *) (dev->dev_addr))[i] =
le16_to_cpu (read_eeprom (ioaddr, i + 7, addr_len));
+ memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
/* The Rtl8139-specific entries in the device structure. */
dev->open = rtl8139_open;
@@ -2465,6 +2467,7 @@ static struct ethtool_ops rtl8139_ethtool_ops = {
.get_strings = rtl8139_get_strings,
.get_stats_count = rtl8139_get_stats_count,
.get_ethtool_stats = rtl8139_get_ethtool_stats,
+ .get_perm_addr = ethtool_op_get_perm_addr,
};
static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index c748b0e16419..5c69d57f8548 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -447,7 +447,7 @@ config NET_SB1250_MAC
config SGI_IOC3_ETH
bool "SGI IOC3 Ethernet"
- depends on NET_ETHERNET && PCI && SGI_IP27 && BROKEN
+ depends on NET_ETHERNET && PCI && SGI_IP27
select CRC32
select MII
help
@@ -475,6 +475,14 @@ config SGI_IOC3_ETH_HW_TX_CSUM
the moment only acceleration of IPv4 is supported. This option
enables offloading for checksums on transmit. If unsure, say Y.
+config MIPS_SIM_NET
+ tristate "MIPS simulator Network device (EXPERIMENTAL)"
+ depends on NETDEVICES && MIPS_SIM && EXPERIMENTAL
+ help
+ The MIPSNET device is a simple Ethernet network device which is
+ emulated by the MIPS Simulator.
+ If you are not using a MIPSsim or are unsure, say N.
+
config SGI_O2MACE_ETH
tristate "SGI O2 MACE Fast Ethernet support"
depends on NET_ETHERNET && SGI_IP32=y
@@ -1155,38 +1163,74 @@ config IBMVETH
be called ibmveth.
config IBM_EMAC
- bool "IBM PPC4xx EMAC driver support"
+ tristate "PowerPC 4xx on-chip Ethernet support"
depends on 4xx
- select CRC32
- ---help---
- This driver supports the IBM PPC4xx EMAC family of on-chip
- Ethernet controllers.
-
-config IBM_EMAC_ERRMSG
- bool "Verbose error messages"
- depends on IBM_EMAC && BROKEN
+ help
+ This driver supports the PowerPC 4xx EMAC family of on-chip
+ Ethernet controllers.
config IBM_EMAC_RXB
int "Number of receive buffers"
depends on IBM_EMAC
- default "128" if IBM_EMAC4
- default "64"
+ default "128"
config IBM_EMAC_TXB
int "Number of transmit buffers"
depends on IBM_EMAC
- default "128" if IBM_EMAC4
- default "8"
+ default "64"
+
+config IBM_EMAC_POLL_WEIGHT
+ int "MAL NAPI polling weight"
+ depends on IBM_EMAC
+ default "32"
-config IBM_EMAC_FGAP
- int "Frame gap"
+config IBM_EMAC_RX_COPY_THRESHOLD
+ int "RX skb copy threshold (bytes)"
depends on IBM_EMAC
- default "8"
+ default "256"
-config IBM_EMAC_SKBRES
- int "Skb reserve amount"
+config IBM_EMAC_RX_SKB_HEADROOM
+ int "Additional RX skb headroom (bytes)"
depends on IBM_EMAC
default "0"
+ help
+ Additional receive skb headroom. Note, that driver
+ will always reserve at least 2 bytes to make IP header
+ aligned, so usualy there is no need to add any additional
+ headroom.
+
+ If unsure, set to 0.
+
+config IBM_EMAC_PHY_RX_CLK_FIX
+ bool "PHY Rx clock workaround"
+ depends on IBM_EMAC && (405EP || 440GX || 440EP || 440GR)
+ help
+ Enable this if EMAC attached to a PHY which doesn't generate
+ RX clock if there is no link, if this is the case, you will
+ see "TX disable timeout" or "RX disable timeout" in the system
+ log.
+
+ If unsure, say N.
+
+config IBM_EMAC_DEBUG
+ bool "Debugging"
+ depends on IBM_EMAC
+ default n
+
+config IBM_EMAC_ZMII
+ bool
+ depends on IBM_EMAC && (NP405H || NP405L || 44x)
+ default y
+
+config IBM_EMAC_RGMII
+ bool
+ depends on IBM_EMAC && 440GX
+ default y
+
+config IBM_EMAC_TAH
+ bool
+ depends on IBM_EMAC && 440GX
+ default y
config NET_PCI
bool "EISA, VLB, PCI and on board controllers"
@@ -1767,6 +1811,7 @@ config NE_H8300
controller on the Renesas H8/300 processor.
source "drivers/net/fec_8xx/Kconfig"
+source "drivers/net/fs_enet/Kconfig"
endmenu
@@ -2083,6 +2128,7 @@ config SPIDER_NET
config GIANFAR
tristate "Gianfar Ethernet"
depends on 85xx || 83xx
+ select PHYLIB
help
This driver supports the Gigabit TSEC on the MPC85xx
family of chips, and the FEC on the 8540
@@ -2192,8 +2238,8 @@ config S2IO
depends on PCI
---help---
This driver supports the 10Gbe XFrame NIC of S2IO.
- For help regarding driver compilation, installation and
- tuning please look into ~/drivers/net/s2io/README.txt.
+ More specific information on configuring the driver is in
+ <file:Documentation/networking/s2io.txt>.
config S2IO_NAPI
bool "Use Rx Polling (NAPI) (EXPERIMENTAL)"
@@ -2212,17 +2258,6 @@ config S2IO_NAPI
If in doubt, say N.
-config 2BUFF_MODE
- bool "Use 2 Buffer Mode on Rx side."
- depends on S2IO
- ---help---
- On enabling the 2 buffer mode, the received frame will be
- split into 2 parts before being DMA'ed to the hosts memory.
- The parts are the ethernet header and ethernet payload.
- This is useful on systems where DMA'ing to to unaligned
- physical memory loactions comes with a heavy price.
- If not sure please say N.
-
endmenu
if !UML
@@ -2243,6 +2278,20 @@ config ISERIES_VETH
tristate "iSeries Virtual Ethernet driver support"
depends on PPC_ISERIES
+config RIONET
+ tristate "RapidIO Ethernet over messaging driver support"
+ depends on NETDEVICES && RAPIDIO
+
+config RIONET_TX_SIZE
+ int "Number of outbound queue entries"
+ depends on RIONET
+ default "128"
+
+config RIONET_RX_SIZE
+ int "Number of inbound queue entries"
+ depends on RIONET
+ default "128"
+
config FDDI
bool "FDDI driver support"
depends on (PCI || EISA)
@@ -2474,6 +2523,19 @@ config PPP_BSDCOMP
module; it is called bsd_comp and will show up in the directory
modules once you have said "make modules". If unsure, say N.
+config PPP_MPPE
+ tristate "PPP MPPE compression (encryption) (EXPERIMENTAL)"
+ depends on PPP && EXPERIMENTAL
+ select CRYPTO
+ select CRYPTO_SHA1
+ select CRYPTO_ARC4
+ ---help---
+ Support for the MPPE Encryption protocol, as employed by the
+ Microsoft Point-to-Point Tunneling Protocol.
+
+ See http://pptpclient.sourceforge.net/ for information on
+ configuring PPTP clients and servers to utilize this method.
+
config PPPOE
tristate "PPP over Ethernet (EXPERIMENTAL)"
depends on EXPERIMENTAL && PPP
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 8aeec9f2495b..4cffd34442aa 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -13,7 +13,7 @@ obj-$(CONFIG_CHELSIO_T1) += chelsio/
obj-$(CONFIG_BONDING) += bonding/
obj-$(CONFIG_GIANFAR) += gianfar_driver.o
-gianfar_driver-objs := gianfar.o gianfar_ethtool.o gianfar_phy.o
+gianfar_driver-objs := gianfar.o gianfar_ethtool.o gianfar_mii.o
#
# link order important here
@@ -64,6 +64,7 @@ obj-$(CONFIG_SKFP) += skfp/
obj-$(CONFIG_VIA_RHINE) += via-rhine.o
obj-$(CONFIG_VIA_VELOCITY) += via-velocity.o
obj-$(CONFIG_ADAPTEC_STARFIRE) += starfire.o
+obj-$(CONFIG_RIONET) += rionet.o
#
# end link order section
@@ -111,6 +112,7 @@ obj-$(CONFIG_PPP_ASYNC) += ppp_async.o
obj-$(CONFIG_PPP_SYNC_TTY) += ppp_synctty.o
obj-$(CONFIG_PPP_DEFLATE) += ppp_deflate.o
obj-$(CONFIG_PPP_BSDCOMP) += bsd_comp.o
+obj-$(CONFIG_PPP_MPPE) += ppp_mppe.o
obj-$(CONFIG_PPPOE) += pppox.o pppoe.o
obj-$(CONFIG_SLIP) += slip.o
@@ -166,6 +168,7 @@ obj-$(CONFIG_EQUALIZER) += eql.o
obj-$(CONFIG_MIPS_JAZZ_SONIC) += jazzsonic.o
obj-$(CONFIG_MIPS_GT96100ETH) += gt96100eth.o
obj-$(CONFIG_MIPS_AU1X00_ENET) += au1000_eth.o
+obj-$(CONFIG_MIPS_SIM_NET) += mipsnet.o
obj-$(CONFIG_SGI_IOC3_ETH) += ioc3-eth.o
obj-$(CONFIG_DECLANCE) += declance.o
obj-$(CONFIG_ATARILANCE) += atarilance.o
@@ -201,3 +204,6 @@ obj-$(CONFIG_IRDA) += irda/
obj-$(CONFIG_ETRAX_ETHERNET) += cris/
obj-$(CONFIG_NETCONSOLE) += netconsole.o
+
+obj-$(CONFIG_FS_ENET) += fs_enet/
+
diff --git a/drivers/net/acenic.c b/drivers/net/acenic.c
index dbecc6bf7851..b8953de5664a 100644
--- a/drivers/net/acenic.c
+++ b/drivers/net/acenic.c
@@ -871,10 +871,8 @@ static void ace_init_cleanup(struct net_device *dev)
if (ap->info)
pci_free_consistent(ap->pdev, sizeof(struct ace_info),
ap->info, ap->info_dma);
- if (ap->skb)
- kfree(ap->skb);
- if (ap->trace_buf)
- kfree(ap->trace_buf);
+ kfree(ap->skb);
+ kfree(ap->trace_buf);
if (dev->irq)
free_irq(dev->irq, dev);
diff --git a/drivers/net/amd8111e.c b/drivers/net/amd8111e.c
index d9ba8be72af8..d9ba8be72af8 100755..100644
--- a/drivers/net/amd8111e.c
+++ b/drivers/net/amd8111e.c
diff --git a/drivers/net/amd8111e.h b/drivers/net/amd8111e.h
index cfe3a4298822..cfe3a4298822 100755..100644
--- a/drivers/net/amd8111e.h
+++ b/drivers/net/amd8111e.h
diff --git a/drivers/net/arm/am79c961a.c b/drivers/net/arm/am79c961a.c
index c56d86d371a9..877891a29aaa 100644
--- a/drivers/net/arm/am79c961a.c
+++ b/drivers/net/arm/am79c961a.c
@@ -26,10 +26,11 @@
#include <linux/init.h>
#include <linux/crc32.h>
#include <linux/bitops.h>
+#include <linux/platform_device.h>
-#include <asm/system.h>
-#include <asm/irq.h>
+#include <asm/hardware.h>
#include <asm/io.h>
+#include <asm/system.h>
#define TX_BUFFERS 15
#define RX_BUFFERS 25
@@ -279,10 +280,13 @@ static void am79c961_timer(unsigned long data)
lnkstat = read_ireg(dev->base_addr, ISALED0) & ISALED0_LNKST;
carrier = netif_carrier_ok(dev);
- if (lnkstat && !carrier)
+ if (lnkstat && !carrier) {
netif_carrier_on(dev);
- else if (!lnkstat && carrier)
+ printk("%s: link up\n", dev->name);
+ } else if (!lnkstat && carrier) {
netif_carrier_off(dev);
+ printk("%s: link down\n", dev->name);
+ }
mod_timer(&priv->timer, jiffies + msecs_to_jiffies(500));
}
@@ -664,17 +668,25 @@ static void __init am79c961_banner(void)
printk(KERN_INFO "%s", version);
}
-static int __init am79c961_init(void)
+static int __init am79c961_probe(struct device *_dev)
{
+ struct platform_device *pdev = to_platform_device(_dev);
+ struct resource *res;
struct net_device *dev;
struct dev_priv *priv;
int i, ret;
+ res = platform_get_resource(pdev, IORESOURCE_IO, 0);
+ if (!res)
+ return -ENODEV;
+
dev = alloc_etherdev(sizeof(struct dev_priv));
ret = -ENOMEM;
if (!dev)
goto out;
+ SET_NETDEV_DEV(dev, &pdev->dev);
+
priv = netdev_priv(dev);
/*
@@ -682,8 +694,8 @@ static int __init am79c961_init(void)
* The PNP initialisation should have been
* done by the ether bootp loader.
*/
- dev->base_addr = 0x220;
- dev->irq = IRQ_EBSA110_ETHERNET;
+ dev->base_addr = res->start;
+ dev->irq = platform_get_irq(pdev, 0);
ret = -ENODEV;
if (!request_region(dev->base_addr, 0x18, dev->name))
@@ -704,11 +716,11 @@ static int __init am79c961_init(void)
inb(dev->base_addr + 4) != 0x2b)
goto release;
- am79c961_banner();
-
for (i = 0; i < 6; i++)
dev->dev_addr[i] = inb(dev->base_addr + i * 2) & 0xff;
+ am79c961_banner();
+
spin_lock_init(&priv->chip_lock);
init_timer(&priv->timer);
priv->timer.data = (unsigned long)dev;
@@ -731,6 +743,7 @@ static int __init am79c961_init(void)
if (ret == 0) {
printk(KERN_INFO "%s: ether address ", dev->name);
+ /* Retrive and print the ethernet address. */
for (i = 0; i < 6; i++)
printk (i == 5 ? "%02x\n" : "%02x:", dev->dev_addr[i]);
@@ -745,4 +758,15 @@ out:
return ret;
}
+static struct device_driver am79c961_driver = {
+ .name = "am79c961",
+ .bus = &platform_bus_type,
+ .probe = am79c961_probe,
+};
+
+static int __init am79c961_init(void)
+{
+ return driver_register(&am79c961_driver);
+}
+
__initcall(am79c961_init);
diff --git a/drivers/net/arm/am79c961a.h b/drivers/net/arm/am79c961a.h
index 1e9b05050cbe..6a49ac7f6d46 100644
--- a/drivers/net/arm/am79c961a.h
+++ b/drivers/net/arm/am79c961a.h
@@ -143,6 +143,4 @@ struct dev_priv {
struct timer_list timer;
};
-extern int am79c961_probe (struct net_device *dev);
-
#endif
diff --git a/drivers/net/au1000_eth.c b/drivers/net/au1000_eth.c
index c82b9cd1c924..332e9953c55c 100644
--- a/drivers/net/au1000_eth.c
+++ b/drivers/net/au1000_eth.c
@@ -151,13 +151,6 @@ struct au1000_private *au_macs[NUM_ETH_INTERFACES];
SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full | \
SUPPORTED_Autoneg
-static char *phy_link[] =
-{ "unknown",
- "10Base2", "10BaseT",
- "AUI",
- "100BaseT", "100BaseTX", "100BaseFX"
-};
-
int bcm_5201_init(struct net_device *dev, int phy_addr)
{
s16 data;
@@ -785,6 +778,7 @@ static struct mii_chip_info {
{"Broadcom BCM5201 10/100 BaseT PHY",0x0040,0x6212, &bcm_5201_ops,0},
{"Broadcom BCM5221 10/100 BaseT PHY",0x0040,0x61e4, &bcm_5201_ops,0},
{"Broadcom BCM5222 10/100 BaseT PHY",0x0040,0x6322, &bcm_5201_ops,1},
+ {"NS DP83847 PHY", 0x2000, 0x5c30, &bcm_5201_ops ,0},
{"AMD 79C901 HomePNA PHY",0x0000,0x35c8, &am79c901_ops,0},
{"AMD 79C874 10/100 BaseT PHY",0x0022,0x561b, &am79c874_ops,0},
{"LSI 80227 10/100 BaseT PHY",0x0016,0xf840, &lsi_80227_ops,0},
@@ -1045,7 +1039,7 @@ found:
#endif
if (aup->mii->chip_info == NULL) {
- printk(KERN_ERR "%s: Au1x No MII transceivers found!\n",
+ printk(KERN_ERR "%s: Au1x No known MII transceivers found!\n",
dev->name);
return -1;
}
@@ -1546,6 +1540,9 @@ au1000_probe(u32 ioaddr, int irq, int port_num)
printk(KERN_ERR "%s: out of memory\n", dev->name);
goto err_out;
}
+ aup->mii->next = NULL;
+ aup->mii->chip_info = NULL;
+ aup->mii->status = 0;
aup->mii->mii_control_reg = 0;
aup->mii->mii_data_reg = 0;
@@ -1609,8 +1606,7 @@ err_out:
/* here we should have a valid dev plus aup-> register addresses
* so we can reset the mac properly.*/
reset_mac(dev);
- if (aup->mii)
- kfree(aup->mii);
+ kfree(aup->mii);
for (i = 0; i < NUM_RX_DMA; i++) {
if (aup->rx_db_inuse[i])
ReleaseDB(aup, aup->rx_db_inuse[i]);
@@ -1809,8 +1805,7 @@ static void __exit au1000_cleanup_module(void)
if (dev) {
aup = (struct au1000_private *) dev->priv;
unregister_netdev(dev);
- if (aup->mii)
- kfree(aup->mii);
+ kfree(aup->mii);
for (j = 0; j < NUM_RX_DMA; j++) {
if (aup->rx_db_inuse[j])
ReleaseDB(aup, aup->rx_db_inuse[j]);
diff --git a/drivers/net/b44.c b/drivers/net/b44.c
index 94939f570f78..c53848f787eb 100644
--- a/drivers/net/b44.c
+++ b/drivers/net/b44.c
@@ -18,7 +18,7 @@
#include <linux/pci.h>
#include <linux/delay.h>
#include <linux/init.h>
-#include <linux/version.h>
+#include <linux/dma-mapping.h>
#include <asm/uaccess.h>
#include <asm/io.h>
@@ -28,8 +28,8 @@
#define DRV_MODULE_NAME "b44"
#define PFX DRV_MODULE_NAME ": "
-#define DRV_MODULE_VERSION "0.95"
-#define DRV_MODULE_RELDATE "Aug 3, 2004"
+#define DRV_MODULE_VERSION "0.96"
+#define DRV_MODULE_RELDATE "Nov 8, 2005"
#define B44_DEF_MSG_ENABLE \
(NETIF_MSG_DRV | \
@@ -101,10 +101,35 @@ MODULE_DEVICE_TABLE(pci, b44_pci_tbl);
static void b44_halt(struct b44 *);
static void b44_init_rings(struct b44 *);
static void b44_init_hw(struct b44 *);
-static int b44_poll(struct net_device *dev, int *budget);
-#ifdef CONFIG_NET_POLL_CONTROLLER
-static void b44_poll_controller(struct net_device *dev);
-#endif
+
+static int dma_desc_align_mask;
+static int dma_desc_sync_size;
+
+static const char b44_gstrings[][ETH_GSTRING_LEN] = {
+#define _B44(x...) # x,
+B44_STAT_REG_DECLARE
+#undef _B44
+};
+
+static inline void b44_sync_dma_desc_for_device(struct pci_dev *pdev,
+ dma_addr_t dma_base,
+ unsigned long offset,
+ enum dma_data_direction dir)
+{
+ dma_sync_single_range_for_device(&pdev->dev, dma_base,
+ offset & dma_desc_align_mask,
+ dma_desc_sync_size, dir);
+}
+
+static inline void b44_sync_dma_desc_for_cpu(struct pci_dev *pdev,
+ dma_addr_t dma_base,
+ unsigned long offset,
+ enum dma_data_direction dir)
+{
+ dma_sync_single_range_for_cpu(&pdev->dev, dma_base,
+ offset & dma_desc_align_mask,
+ dma_desc_sync_size, dir);
+}
static inline unsigned long br32(const struct b44 *bp, unsigned long reg)
{
@@ -478,7 +503,10 @@ static void b44_stats_update(struct b44 *bp)
for (reg = B44_TX_GOOD_O; reg <= B44_TX_PAUSE; reg += 4UL) {
*val++ += br32(bp, reg);
}
- val = &bp->hw_stats.rx_good_octets;
+
+ /* Pad */
+ reg += 8*4UL;
+
for (reg = B44_RX_GOOD_O; reg <= B44_RX_NPAUSE; reg += 4UL) {
*val++ += br32(bp, reg);
}
@@ -629,7 +657,7 @@ static int b44_alloc_rx_skb(struct b44 *bp, int src_idx, u32 dest_idx_unmasked)
/* Hardware bug work-around, the chip is unable to do PCI DMA
to/from anything above 1GB :-( */
- if(mapping+RX_PKT_BUF_SZ > B44_DMA_MASK) {
+ if (mapping + RX_PKT_BUF_SZ > B44_DMA_MASK) {
/* Sigh... */
pci_unmap_single(bp->pdev, mapping, RX_PKT_BUF_SZ,PCI_DMA_FROMDEVICE);
dev_kfree_skb_any(skb);
@@ -639,7 +667,7 @@ static int b44_alloc_rx_skb(struct b44 *bp, int src_idx, u32 dest_idx_unmasked)
mapping = pci_map_single(bp->pdev, skb->data,
RX_PKT_BUF_SZ,
PCI_DMA_FROMDEVICE);
- if(mapping+RX_PKT_BUF_SZ > B44_DMA_MASK) {
+ if (mapping + RX_PKT_BUF_SZ > B44_DMA_MASK) {
pci_unmap_single(bp->pdev, mapping, RX_PKT_BUF_SZ,PCI_DMA_FROMDEVICE);
dev_kfree_skb_any(skb);
return -ENOMEM;
@@ -668,6 +696,11 @@ static int b44_alloc_rx_skb(struct b44 *bp, int src_idx, u32 dest_idx_unmasked)
dp->ctrl = cpu_to_le32(ctrl);
dp->addr = cpu_to_le32((u32) mapping + bp->rx_offset + bp->dma_offset);
+ if (bp->flags & B44_FLAG_RX_RING_HACK)
+ b44_sync_dma_desc_for_device(bp->pdev, bp->rx_ring_dma,
+ dest_idx * sizeof(dp),
+ DMA_BIDIRECTIONAL);
+
return RX_PKT_BUF_SZ;
}
@@ -692,6 +725,11 @@ static void b44_recycle_rx(struct b44 *bp, int src_idx, u32 dest_idx_unmasked)
pci_unmap_addr_set(dest_map, mapping,
pci_unmap_addr(src_map, mapping));
+ if (bp->flags & B44_FLAG_RX_RING_HACK)
+ b44_sync_dma_desc_for_cpu(bp->pdev, bp->rx_ring_dma,
+ src_idx * sizeof(src_desc),
+ DMA_BIDIRECTIONAL);
+
ctrl = src_desc->ctrl;
if (dest_idx == (B44_RX_RING_SIZE - 1))
ctrl |= cpu_to_le32(DESC_CTRL_EOT);
@@ -700,8 +738,14 @@ static void b44_recycle_rx(struct b44 *bp, int src_idx, u32 dest_idx_unmasked)
dest_desc->ctrl = ctrl;
dest_desc->addr = src_desc->addr;
+
src_map->skb = NULL;
+ if (bp->flags & B44_FLAG_RX_RING_HACK)
+ b44_sync_dma_desc_for_device(bp->pdev, bp->rx_ring_dma,
+ dest_idx * sizeof(dest_desc),
+ DMA_BIDIRECTIONAL);
+
pci_dma_sync_single_for_device(bp->pdev, src_desc->addr,
RX_PKT_BUF_SZ,
PCI_DMA_FROMDEVICE);
@@ -850,11 +894,10 @@ static irqreturn_t b44_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
struct net_device *dev = dev_id;
struct b44 *bp = netdev_priv(dev);
- unsigned long flags;
u32 istat, imask;
int handled = 0;
- spin_lock_irqsave(&bp->lock, flags);
+ spin_lock(&bp->lock);
istat = br32(bp, B44_ISTAT);
imask = br32(bp, B44_IMASK);
@@ -865,6 +908,12 @@ static irqreturn_t b44_interrupt(int irq, void *dev_id, struct pt_regs *regs)
istat &= imask;
if (istat) {
handled = 1;
+
+ if (unlikely(!netif_running(dev))) {
+ printk(KERN_INFO "%s: late interrupt.\n", dev->name);
+ goto irq_ack;
+ }
+
if (netif_rx_schedule_prep(dev)) {
/* NOTE: These writes are posted by the readback of
* the ISTAT register below.
@@ -877,10 +926,11 @@ static irqreturn_t b44_interrupt(int irq, void *dev_id, struct pt_regs *regs)
dev->name);
}
+irq_ack:
bw32(bp, B44_ISTAT, istat);
br32(bp, B44_ISTAT);
}
- spin_unlock_irqrestore(&bp->lock, flags);
+ spin_unlock(&bp->lock);
return IRQ_RETVAL(handled);
}
@@ -908,6 +958,7 @@ static int b44_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct b44 *bp = netdev_priv(dev);
struct sk_buff *bounce_skb;
+ int rc = NETDEV_TX_OK;
dma_addr_t mapping;
u32 len, entry, ctrl;
@@ -917,29 +968,28 @@ static int b44_start_xmit(struct sk_buff *skb, struct net_device *dev)
/* This is a hard error, log it. */
if (unlikely(TX_BUFFS_AVAIL(bp) < 1)) {
netif_stop_queue(dev);
- spin_unlock_irq(&bp->lock);
printk(KERN_ERR PFX "%s: BUG! Tx Ring full when queue awake!\n",
dev->name);
- return 1;
+ goto err_out;
}
mapping = pci_map_single(bp->pdev, skb->data, len, PCI_DMA_TODEVICE);
- if(mapping+len > B44_DMA_MASK) {
+ if (mapping + len > B44_DMA_MASK) {
/* Chip can't handle DMA to/from >1GB, use bounce buffer */
pci_unmap_single(bp->pdev, mapping, len, PCI_DMA_TODEVICE);
bounce_skb = __dev_alloc_skb(TX_PKT_BUF_SZ,
GFP_ATOMIC|GFP_DMA);
if (!bounce_skb)
- return NETDEV_TX_BUSY;
+ goto err_out;
mapping = pci_map_single(bp->pdev, bounce_skb->data,
len, PCI_DMA_TODEVICE);
- if(mapping+len > B44_DMA_MASK) {
+ if (mapping + len > B44_DMA_MASK) {
pci_unmap_single(bp->pdev, mapping,
len, PCI_DMA_TODEVICE);
dev_kfree_skb_any(bounce_skb);
- return NETDEV_TX_BUSY;
+ goto err_out;
}
memcpy(skb_put(bounce_skb, len), skb->data, skb->len);
@@ -959,6 +1009,11 @@ static int b44_start_xmit(struct sk_buff *skb, struct net_device *dev)
bp->tx_ring[entry].ctrl = cpu_to_le32(ctrl);
bp->tx_ring[entry].addr = cpu_to_le32((u32) mapping+bp->dma_offset);
+ if (bp->flags & B44_FLAG_TX_RING_HACK)
+ b44_sync_dma_desc_for_device(bp->pdev, bp->tx_ring_dma,
+ entry * sizeof(bp->tx_ring[0]),
+ DMA_TO_DEVICE);
+
entry = NEXT_TX(entry);
bp->tx_prod = entry;
@@ -974,11 +1029,16 @@ static int b44_start_xmit(struct sk_buff *skb, struct net_device *dev)
if (TX_BUFFS_AVAIL(bp) < 1)
netif_stop_queue(dev);
+ dev->trans_start = jiffies;
+
+out_unlock:
spin_unlock_irq(&bp->lock);
- dev->trans_start = jiffies;
+ return rc;
- return 0;
+err_out:
+ rc = NETDEV_TX_BUSY;
+ goto out_unlock;
}
static int b44_change_mtu(struct net_device *dev, int new_mtu)
@@ -1052,8 +1112,7 @@ static void b44_free_rings(struct b44 *bp)
*
* The chip has been shut down and the driver detached from
* the networking, so no interrupts or new tx packets will
- * end up in the driver. bp->lock is not held and we are not
- * in an interrupt context and thus may sleep.
+ * end up in the driver.
*/
static void b44_init_rings(struct b44 *bp)
{
@@ -1064,6 +1123,16 @@ static void b44_init_rings(struct b44 *bp)
memset(bp->rx_ring, 0, B44_RX_RING_BYTES);
memset(bp->tx_ring, 0, B44_TX_RING_BYTES);
+ if (bp->flags & B44_FLAG_RX_RING_HACK)
+ dma_sync_single_for_device(&bp->pdev->dev, bp->rx_ring_dma,
+ DMA_TABLE_BYTES,
+ PCI_DMA_BIDIRECTIONAL);
+
+ if (bp->flags & B44_FLAG_TX_RING_HACK)
+ dma_sync_single_for_device(&bp->pdev->dev, bp->tx_ring_dma,
+ DMA_TABLE_BYTES,
+ PCI_DMA_TODEVICE);
+
for (i = 0; i < bp->rx_pending; i++) {
if (b44_alloc_rx_skb(bp, -1, i) < 0)
break;
@@ -1076,23 +1145,33 @@ static void b44_init_rings(struct b44 *bp)
*/
static void b44_free_consistent(struct b44 *bp)
{
- if (bp->rx_buffers) {
- kfree(bp->rx_buffers);
- bp->rx_buffers = NULL;
- }
- if (bp->tx_buffers) {
- kfree(bp->tx_buffers);
- bp->tx_buffers = NULL;
- }
+ kfree(bp->rx_buffers);
+ bp->rx_buffers = NULL;
+ kfree(bp->tx_buffers);
+ bp->tx_buffers = NULL;
if (bp->rx_ring) {
- pci_free_consistent(bp->pdev, DMA_TABLE_BYTES,
- bp->rx_ring, bp->rx_ring_dma);
+ if (bp->flags & B44_FLAG_RX_RING_HACK) {
+ dma_unmap_single(&bp->pdev->dev, bp->rx_ring_dma,
+ DMA_TABLE_BYTES,
+ DMA_BIDIRECTIONAL);
+ kfree(bp->rx_ring);
+ } else
+ pci_free_consistent(bp->pdev, DMA_TABLE_BYTES,
+ bp->rx_ring, bp->rx_ring_dma);
bp->rx_ring = NULL;
+ bp->flags &= ~B44_FLAG_RX_RING_HACK;
}
if (bp->tx_ring) {
- pci_free_consistent(bp->pdev, DMA_TABLE_BYTES,
- bp->tx_ring, bp->tx_ring_dma);
+ if (bp->flags & B44_FLAG_TX_RING_HACK) {
+ dma_unmap_single(&bp->pdev->dev, bp->tx_ring_dma,
+ DMA_TABLE_BYTES,
+ DMA_TO_DEVICE);
+ kfree(bp->tx_ring);
+ } else
+ pci_free_consistent(bp->pdev, DMA_TABLE_BYTES,
+ bp->tx_ring, bp->tx_ring_dma);
bp->tx_ring = NULL;
+ bp->flags &= ~B44_FLAG_TX_RING_HACK;
}
}
@@ -1105,25 +1184,67 @@ static int b44_alloc_consistent(struct b44 *bp)
int size;
size = B44_RX_RING_SIZE * sizeof(struct ring_info);
- bp->rx_buffers = kmalloc(size, GFP_KERNEL);
+ bp->rx_buffers = kzalloc(size, GFP_KERNEL);
if (!bp->rx_buffers)
goto out_err;
- memset(bp->rx_buffers, 0, size);
size = B44_TX_RING_SIZE * sizeof(struct ring_info);
- bp->tx_buffers = kmalloc(size, GFP_KERNEL);
+ bp->tx_buffers = kzalloc(size, GFP_KERNEL);
if (!bp->tx_buffers)
goto out_err;
- memset(bp->tx_buffers, 0, size);
size = DMA_TABLE_BYTES;
bp->rx_ring = pci_alloc_consistent(bp->pdev, size, &bp->rx_ring_dma);
- if (!bp->rx_ring)
- goto out_err;
+ if (!bp->rx_ring) {
+ /* Allocation may have failed due to pci_alloc_consistent
+ insisting on use of GFP_DMA, which is more restrictive
+ than necessary... */
+ struct dma_desc *rx_ring;
+ dma_addr_t rx_ring_dma;
+
+ rx_ring = kzalloc(size, GFP_KERNEL);
+ if (!rx_ring)
+ goto out_err;
+
+ rx_ring_dma = dma_map_single(&bp->pdev->dev, rx_ring,
+ DMA_TABLE_BYTES,
+ DMA_BIDIRECTIONAL);
+
+ if (rx_ring_dma + size > B44_DMA_MASK) {
+ kfree(rx_ring);
+ goto out_err;
+ }
+
+ bp->rx_ring = rx_ring;
+ bp->rx_ring_dma = rx_ring_dma;
+ bp->flags |= B44_FLAG_RX_RING_HACK;
+ }
bp->tx_ring = pci_alloc_consistent(bp->pdev, size, &bp->tx_ring_dma);
- if (!bp->tx_ring)
- goto out_err;
+ if (!bp->tx_ring) {
+ /* Allocation may have failed due to pci_alloc_consistent
+ insisting on use of GFP_DMA, which is more restrictive
+ than necessary... */
+ struct dma_desc *tx_ring;
+ dma_addr_t tx_ring_dma;
+
+ tx_ring = kzalloc(size, GFP_KERNEL);
+ if (!tx_ring)
+ goto out_err;
+
+ tx_ring_dma = dma_map_single(&bp->pdev->dev, tx_ring,
+ DMA_TABLE_BYTES,
+ DMA_TO_DEVICE);
+
+ if (tx_ring_dma + size > B44_DMA_MASK) {
+ kfree(tx_ring);
+ goto out_err;
+ }
+
+ bp->tx_ring = tx_ring;
+ bp->tx_ring_dma = tx_ring_dma;
+ bp->flags |= B44_FLAG_TX_RING_HACK;
+ }
return 0;
@@ -1273,22 +1394,21 @@ static int b44_open(struct net_device *dev)
err = b44_alloc_consistent(bp);
if (err)
- return err;
-
- err = request_irq(dev->irq, b44_interrupt, SA_SHIRQ, dev->name, dev);
- if (err)
- goto err_out_free;
-
- spin_lock_irq(&bp->lock);
+ goto out;
b44_init_rings(bp);
b44_init_hw(bp);
- bp->flags |= B44_FLAG_INIT_COMPLETE;
netif_carrier_off(dev);
b44_check_phy(bp);
- spin_unlock_irq(&bp->lock);
+ err = request_irq(dev->irq, b44_interrupt, SA_SHIRQ, dev->name, dev);
+ if (unlikely(err < 0)) {
+ b44_chip_reset(bp);
+ b44_free_rings(bp);
+ b44_free_consistent(bp);
+ goto out;
+ }
init_timer(&bp->timer);
bp->timer.expires = jiffies + HZ;
@@ -1297,11 +1417,7 @@ static int b44_open(struct net_device *dev)
add_timer(&bp->timer);
b44_enable_ints(bp);
-
- return 0;
-
-err_out_free:
- b44_free_consistent(bp);
+out:
return err;
}
@@ -1336,6 +1452,8 @@ static int b44_close(struct net_device *dev)
netif_stop_queue(dev);
+ netif_poll_disable(dev);
+
del_timer_sync(&bp->timer);
spin_lock_irq(&bp->lock);
@@ -1345,13 +1463,14 @@ static int b44_close(struct net_device *dev)
#endif
b44_halt(bp);
b44_free_rings(bp);
- bp->flags &= ~B44_FLAG_INIT_COMPLETE;
netif_carrier_off(bp->dev);
spin_unlock_irq(&bp->lock);
free_irq(dev->irq, dev);
+ netif_poll_enable(dev);
+
b44_free_consistent(bp);
return 0;
@@ -1416,8 +1535,6 @@ static void __b44_set_rx_mode(struct net_device *dev)
{
struct b44 *bp = netdev_priv(dev);
u32 val;
- int i=0;
- unsigned char zero[6] = {0,0,0,0,0,0};
val = br32(bp, B44_RXCONFIG);
val &= ~(RXCONFIG_PROMISC | RXCONFIG_ALLMULTI);
@@ -1425,14 +1542,17 @@ static void __b44_set_rx_mode(struct net_device *dev)
val |= RXCONFIG_PROMISC;
bw32(bp, B44_RXCONFIG, val);
} else {
+ unsigned char zero[6] = {0, 0, 0, 0, 0, 0};
+ int i = 0;
+
__b44_set_mac_addr(bp);
if (dev->flags & IFF_ALLMULTI)
val |= RXCONFIG_ALLMULTI;
else
- i=__b44_load_mcast(bp, dev);
+ i = __b44_load_mcast(bp, dev);
- for(;i<64;i++) {
+ for (; i < 64; i++) {
__b44_cam_write(bp, zero, i);
}
bw32(bp, B44_RXCONFIG, val);
@@ -1496,7 +1616,7 @@ static int b44_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
{
struct b44 *bp = netdev_priv(dev);
- if (!(bp->flags & B44_FLAG_INIT_COMPLETE))
+ if (!netif_running(dev))
return -EAGAIN;
cmd->supported = (SUPPORTED_Autoneg);
cmd->supported |= (SUPPORTED_100baseT_Half |
@@ -1507,14 +1627,14 @@ static int b44_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
cmd->advertising = 0;
if (bp->flags & B44_FLAG_ADV_10HALF)
- cmd->advertising |= ADVERTISE_10HALF;
+ cmd->advertising |= ADVERTISED_10baseT_Half;
if (bp->flags & B44_FLAG_ADV_10FULL)
- cmd->advertising |= ADVERTISE_10FULL;
+ cmd->advertising |= ADVERTISED_10baseT_Full;
if (bp->flags & B44_FLAG_ADV_100HALF)
- cmd->advertising |= ADVERTISE_100HALF;
+ cmd->advertising |= ADVERTISED_100baseT_Half;
if (bp->flags & B44_FLAG_ADV_100FULL)
- cmd->advertising |= ADVERTISE_100FULL;
- cmd->advertising |= ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM;
+ cmd->advertising |= ADVERTISED_100baseT_Full;
+ cmd->advertising |= ADVERTISED_Pause | ADVERTISED_Asym_Pause;
cmd->speed = (bp->flags & B44_FLAG_100_BASE_T) ?
SPEED_100 : SPEED_10;
cmd->duplex = (bp->flags & B44_FLAG_FULL_DUPLEX) ?
@@ -1534,7 +1654,7 @@ static int b44_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
{
struct b44 *bp = netdev_priv(dev);
- if (!(bp->flags & B44_FLAG_INIT_COMPLETE))
+ if (!netif_running(dev))
return -EAGAIN;
/* We do not support gigabit. */
@@ -1664,6 +1784,37 @@ static int b44_set_pauseparam(struct net_device *dev,
return 0;
}
+static void b44_get_strings(struct net_device *dev, u32 stringset, u8 *data)
+{
+ switch(stringset) {
+ case ETH_SS_STATS:
+ memcpy(data, *b44_gstrings, sizeof(b44_gstrings));
+ break;
+ }
+}
+
+static int b44_get_stats_count(struct net_device *dev)
+{
+ return ARRAY_SIZE(b44_gstrings);
+}
+
+static void b44_get_ethtool_stats(struct net_device *dev,
+ struct ethtool_stats *stats, u64 *data)
+{
+ struct b44 *bp = netdev_priv(dev);
+ u32 *val = &bp->hw_stats.tx_good_octets;
+ u32 i;
+
+ spin_lock_irq(&bp->lock);
+
+ b44_stats_update(bp);
+
+ for (i = 0; i < ARRAY_SIZE(b44_gstrings); i++)
+ *data++ = *val++;
+
+ spin_unlock_irq(&bp->lock);
+}
+
static struct ethtool_ops b44_ethtool_ops = {
.get_drvinfo = b44_get_drvinfo,
.get_settings = b44_get_settings,
@@ -1676,6 +1827,10 @@ static struct ethtool_ops b44_ethtool_ops = {
.set_pauseparam = b44_set_pauseparam,
.get_msglevel = b44_get_msglevel,
.set_msglevel = b44_set_msglevel,
+ .get_strings = b44_get_strings,
+ .get_stats_count = b44_get_stats_count,
+ .get_ethtool_stats = b44_get_ethtool_stats,
+ .get_perm_addr = ethtool_op_get_perm_addr,
};
static int b44_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
@@ -1718,6 +1873,7 @@ static int __devinit b44_get_invariants(struct b44 *bp)
bp->dev->dev_addr[3] = eeprom[80];
bp->dev->dev_addr[4] = eeprom[83];
bp->dev->dev_addr[5] = eeprom[82];
+ memcpy(bp->dev->perm_addr, bp->dev->dev_addr, bp->dev->addr_len);
bp->phy_addr = eeprom[90] & 0x1f;
@@ -1782,9 +1938,9 @@ static int __devinit b44_init_one(struct pci_dev *pdev,
err = pci_set_consistent_dma_mask(pdev, (u64) B44_DMA_MASK);
if (err) {
- printk(KERN_ERR PFX "No usable DMA configuration, "
- "aborting.\n");
- goto err_out_free_res;
+ printk(KERN_ERR PFX "No usable DMA configuration, "
+ "aborting.\n");
+ goto err_out_free_res;
}
b44reg_base = pci_resource_start(pdev, 0);
@@ -1806,10 +1962,8 @@ static int __devinit b44_init_one(struct pci_dev *pdev,
bp = netdev_priv(dev);
bp->pdev = pdev;
bp->dev = dev;
- if (b44_debug >= 0)
- bp->msg_enable = (1 << b44_debug) - 1;
- else
- bp->msg_enable = B44_DEF_MSG_ENABLE;
+
+ bp->msg_enable = netif_msg_init(b44_debug, B44_DEF_MSG_ENABLE);
spin_lock_init(&bp->lock);
@@ -1899,17 +2053,14 @@ err_out_disable_pdev:
static void __devexit b44_remove_one(struct pci_dev *pdev)
{
struct net_device *dev = pci_get_drvdata(pdev);
+ struct b44 *bp = netdev_priv(dev);
- if (dev) {
- struct b44 *bp = netdev_priv(dev);
-
- unregister_netdev(dev);
- iounmap(bp->regs);
- free_netdev(dev);
- pci_release_regions(pdev);
- pci_disable_device(pdev);
- pci_set_drvdata(pdev, NULL);
- }
+ unregister_netdev(dev);
+ iounmap(bp->regs);
+ free_netdev(dev);
+ pci_release_regions(pdev);
+ pci_disable_device(pdev);
+ pci_set_drvdata(pdev, NULL);
}
static int b44_suspend(struct pci_dev *pdev, pm_message_t state)
@@ -1930,6 +2081,8 @@ static int b44_suspend(struct pci_dev *pdev, pm_message_t state)
b44_free_rings(bp);
spin_unlock_irq(&bp->lock);
+
+ free_irq(dev->irq, dev);
pci_disable_device(pdev);
return 0;
}
@@ -1946,6 +2099,9 @@ static int b44_resume(struct pci_dev *pdev)
if (!netif_running(dev))
return 0;
+ if (request_irq(dev->irq, b44_interrupt, SA_SHIRQ, dev->name, dev))
+ printk(KERN_ERR PFX "%s: request_irq failed\n", dev->name);
+
spin_lock_irq(&bp->lock);
b44_init_rings(bp);
@@ -1971,6 +2127,12 @@ static struct pci_driver b44_driver = {
static int __init b44_init(void)
{
+ unsigned int dma_desc_align_size = dma_get_cache_alignment();
+
+ /* Setup paramaters for syncing RX/TX DMA descriptors */
+ dma_desc_align_mask = ~(dma_desc_align_size - 1);
+ dma_desc_sync_size = max(dma_desc_align_size, sizeof(struct dma_desc));
+
return pci_module_init(&b44_driver);
}
diff --git a/drivers/net/b44.h b/drivers/net/b44.h
index 11c40a2e71c7..b178662978f3 100644
--- a/drivers/net/b44.h
+++ b/drivers/net/b44.h
@@ -346,29 +346,63 @@ struct ring_info {
#define B44_MCAST_TABLE_SIZE 32
+#define B44_STAT_REG_DECLARE \
+ _B44(tx_good_octets) \
+ _B44(tx_good_pkts) \
+ _B44(tx_octets) \
+ _B44(tx_pkts) \
+ _B44(tx_broadcast_pkts) \
+ _B44(tx_multicast_pkts) \
+ _B44(tx_len_64) \
+ _B44(tx_len_65_to_127) \
+ _B44(tx_len_128_to_255) \
+ _B44(tx_len_256_to_511) \
+ _B44(tx_len_512_to_1023) \
+ _B44(tx_len_1024_to_max) \
+ _B44(tx_jabber_pkts) \
+ _B44(tx_oversize_pkts) \
+ _B44(tx_fragment_pkts) \
+ _B44(tx_underruns) \
+ _B44(tx_total_cols) \
+ _B44(tx_single_cols) \
+ _B44(tx_multiple_cols) \
+ _B44(tx_excessive_cols) \
+ _B44(tx_late_cols) \
+ _B44(tx_defered) \
+ _B44(tx_carrier_lost) \
+ _B44(tx_pause_pkts) \
+ _B44(rx_good_octets) \
+ _B44(rx_good_pkts) \
+ _B44(rx_octets) \
+ _B44(rx_pkts) \
+ _B44(rx_broadcast_pkts) \
+ _B44(rx_multicast_pkts) \
+ _B44(rx_len_64) \
+ _B44(rx_len_65_to_127) \
+ _B44(rx_len_128_to_255) \
+ _B44(rx_len_256_to_511) \
+ _B44(rx_len_512_to_1023) \
+ _B44(rx_len_1024_to_max) \
+ _B44(rx_jabber_pkts) \
+ _B44(rx_oversize_pkts) \
+ _B44(rx_fragment_pkts) \
+ _B44(rx_missed_pkts) \
+ _B44(rx_crc_align_errs) \
+ _B44(rx_undersize) \
+ _B44(rx_crc_errs) \
+ _B44(rx_align_errs) \
+ _B44(rx_symbol_errs) \
+ _B44(rx_pause_pkts) \
+ _B44(rx_nonpause_pkts)
+
/* SW copy of device statistics, kept up to date by periodic timer
- * which probes HW values. Must have same relative layout as HW
- * register above, because b44_stats_update depends upon this.
+ * which probes HW values. Check b44_stats_update if you mess with
+ * the layout
*/
struct b44_hw_stats {
- u32 tx_good_octets, tx_good_pkts, tx_octets;
- u32 tx_pkts, tx_broadcast_pkts, tx_multicast_pkts;
- u32 tx_len_64, tx_len_65_to_127, tx_len_128_to_255;
- u32 tx_len_256_to_511, tx_len_512_to_1023, tx_len_1024_to_max;
- u32 tx_jabber_pkts, tx_oversize_pkts, tx_fragment_pkts;
- u32 tx_underruns, tx_total_cols, tx_single_cols;
- u32 tx_multiple_cols, tx_excessive_cols, tx_late_cols;
- u32 tx_defered, tx_carrier_lost, tx_pause_pkts;
- u32 __pad1[8];
-
- u32 rx_good_octets, rx_good_pkts, rx_octets;
- u32 rx_pkts, rx_broadcast_pkts, rx_multicast_pkts;
- u32 rx_len_64, rx_len_65_to_127, rx_len_128_to_255;
- u32 rx_len_256_to_511, rx_len_512_to_1023, rx_len_1024_to_max;
- u32 rx_jabber_pkts, rx_oversize_pkts, rx_fragment_pkts;
- u32 rx_missed_pkts, rx_crc_align_errs, rx_undersize;
- u32 rx_crc_errs, rx_align_errs, rx_symbol_errs;
- u32 rx_pause_pkts, rx_nonpause_pkts;
+#define _B44(x) u32 x;
+B44_STAT_REG_DECLARE
+#undef _B44
};
struct b44 {
@@ -386,7 +420,6 @@ struct b44 {
u32 dma_offset;
u32 flags;
-#define B44_FLAG_INIT_COMPLETE 0x00000001
#define B44_FLAG_BUGGY_TXPTR 0x00000002
#define B44_FLAG_REORDER_BUG 0x00000004
#define B44_FLAG_PAUSE_AUTO 0x00008000
@@ -400,6 +433,8 @@ struct b44 {
#define B44_FLAG_ADV_100HALF 0x04000000
#define B44_FLAG_ADV_100FULL 0x08000000
#define B44_FLAG_INTERNAL_PHY 0x10000000
+#define B44_FLAG_RX_RING_HACK 0x20000000
+#define B44_FLAG_TX_RING_HACK 0x40000000
u32 rx_offset;
diff --git a/drivers/net/bmac.c b/drivers/net/bmac.c
index 60dba4a1ca5c..bbca8ae8018c 100644
--- a/drivers/net/bmac.c
+++ b/drivers/net/bmac.c
@@ -1658,6 +1658,7 @@ static struct of_device_id bmac_match[] =
},
{},
};
+MODULE_DEVICE_TABLE (of, bmac_match);
static struct macio_driver bmac_driver =
{
@@ -1689,10 +1690,8 @@ static void __exit bmac_exit(void)
{
macio_unregister_driver(&bmac_driver);
- if (bmac_emergency_rxbuf != NULL) {
- kfree(bmac_emergency_rxbuf);
- bmac_emergency_rxbuf = NULL;
- }
+ kfree(bmac_emergency_rxbuf);
+ bmac_emergency_rxbuf = NULL;
}
MODULE_AUTHOR("Randy Gobbel/Paul Mackerras");
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c
index 3a2ace01e444..49fa1e4413fa 100644
--- a/drivers/net/bnx2.c
+++ b/drivers/net/bnx2.c
@@ -14,8 +14,8 @@
#define DRV_MODULE_NAME "bnx2"
#define PFX DRV_MODULE_NAME ": "
-#define DRV_MODULE_VERSION "1.2.21"
-#define DRV_MODULE_RELDATE "September 7, 2005"
+#define DRV_MODULE_VERSION "1.4.30"
+#define DRV_MODULE_RELDATE "October 11, 2005"
#define RUN_AT(x) (jiffies + (x))
@@ -26,7 +26,7 @@ static char version[] __devinitdata =
"Broadcom NetXtreme II Gigabit Ethernet Driver " DRV_MODULE_NAME " v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n";
MODULE_AUTHOR("Michael Chan <mchan@broadcom.com>");
-MODULE_DESCRIPTION("Broadcom NetXtreme II BCM5706 Driver");
+MODULE_DESCRIPTION("Broadcom NetXtreme II BCM5706/5708 Driver");
MODULE_LICENSE("GPL");
MODULE_VERSION(DRV_MODULE_VERSION);
@@ -41,6 +41,8 @@ typedef enum {
NC370I,
BCM5706S,
NC370F,
+ BCM5708,
+ BCM5708S,
} board_t;
/* indexed by board_t, above */
@@ -52,6 +54,8 @@ static struct {
{ "HP NC370i Multifunction Gigabit Server Adapter" },
{ "Broadcom NetXtreme II BCM5706 1000Base-SX" },
{ "HP NC370F Multifunction Gigabit Server Adapter" },
+ { "Broadcom NetXtreme II BCM5708 1000Base-T" },
+ { "Broadcom NetXtreme II BCM5708 1000Base-SX" },
};
static struct pci_device_id bnx2_pci_tbl[] = {
@@ -61,48 +65,102 @@ static struct pci_device_id bnx2_pci_tbl[] = {
PCI_VENDOR_ID_HP, 0x3106, 0, 0, NC370I },
{ PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_NX2_5706,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5706 },
+ { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_NX2_5708,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5708 },
{ PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_NX2_5706S,
PCI_VENDOR_ID_HP, 0x3102, 0, 0, NC370F },
{ PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_NX2_5706S,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5706S },
+ { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_NX2_5708S,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5708S },
{ 0, }
};
static struct flash_spec flash_table[] =
{
/* Slow EEPROM */
- {0x00000000, 0x40030380, 0x009f0081, 0xa184a053, 0xaf000400,
+ {0x00000000, 0x40830380, 0x009f0081, 0xa184a053, 0xaf000400,
1, SEEPROM_PAGE_BITS, SEEPROM_PAGE_SIZE,
SEEPROM_BYTE_ADDR_MASK, SEEPROM_TOTAL_SIZE,
"EEPROM - slow"},
- /* Fast EEPROM */
- {0x02000000, 0x62008380, 0x009f0081, 0xa184a053, 0xaf000400,
- 1, SEEPROM_PAGE_BITS, SEEPROM_PAGE_SIZE,
- SEEPROM_BYTE_ADDR_MASK, SEEPROM_TOTAL_SIZE,
- "EEPROM - fast"},
- /* ATMEL AT45DB011B (buffered flash) */
- {0x02000003, 0x6e008173, 0x00570081, 0x68848353, 0xaf000400,
- 1, BUFFERED_FLASH_PAGE_BITS, BUFFERED_FLASH_PAGE_SIZE,
- BUFFERED_FLASH_BYTE_ADDR_MASK, BUFFERED_FLASH_TOTAL_SIZE,
- "Buffered flash"},
- /* Saifun SA25F005 (non-buffered flash) */
- /* strap, cfg1, & write1 need updates */
- {0x01000003, 0x5f008081, 0x00050081, 0x03840253, 0xaf020406,
+ /* Expansion entry 0001 */
+ {0x08000002, 0x4b808201, 0x00050081, 0x03840253, 0xaf020406,
0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
- SAIFUN_FLASH_BYTE_ADDR_MASK, SAIFUN_FLASH_BASE_TOTAL_SIZE,
- "Non-buffered flash (64kB)"},
+ SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
+ "Entry 0001"},
/* Saifun SA25F010 (non-buffered flash) */
/* strap, cfg1, & write1 need updates */
- {0x00000001, 0x47008081, 0x00050081, 0x03840253, 0xaf020406,
+ {0x04000001, 0x47808201, 0x00050081, 0x03840253, 0xaf020406,
0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
SAIFUN_FLASH_BYTE_ADDR_MASK, SAIFUN_FLASH_BASE_TOTAL_SIZE*2,
"Non-buffered flash (128kB)"},
/* Saifun SA25F020 (non-buffered flash) */
/* strap, cfg1, & write1 need updates */
- {0x00000003, 0x4f008081, 0x00050081, 0x03840253, 0xaf020406,
+ {0x0c000003, 0x4f808201, 0x00050081, 0x03840253, 0xaf020406,
0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
SAIFUN_FLASH_BYTE_ADDR_MASK, SAIFUN_FLASH_BASE_TOTAL_SIZE*4,
"Non-buffered flash (256kB)"},
+ /* Expansion entry 0100 */
+ {0x11000000, 0x53808201, 0x00050081, 0x03840253, 0xaf020406,
+ 0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
+ SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
+ "Entry 0100"},
+ /* Entry 0101: ST M45PE10 (non-buffered flash, TetonII B0) */
+ {0x19000002, 0x5b808201, 0x000500db, 0x03840253, 0xaf020406,
+ 0, ST_MICRO_FLASH_PAGE_BITS, ST_MICRO_FLASH_PAGE_SIZE,
+ ST_MICRO_FLASH_BYTE_ADDR_MASK, ST_MICRO_FLASH_BASE_TOTAL_SIZE*2,
+ "Entry 0101: ST M45PE10 (128kB non-bufferred)"},
+ /* Entry 0110: ST M45PE20 (non-buffered flash)*/
+ {0x15000001, 0x57808201, 0x000500db, 0x03840253, 0xaf020406,
+ 0, ST_MICRO_FLASH_PAGE_BITS, ST_MICRO_FLASH_PAGE_SIZE,
+ ST_MICRO_FLASH_BYTE_ADDR_MASK, ST_MICRO_FLASH_BASE_TOTAL_SIZE*4,
+ "Entry 0110: ST M45PE20 (256kB non-bufferred)"},
+ /* Saifun SA25F005 (non-buffered flash) */
+ /* strap, cfg1, & write1 need updates */
+ {0x1d000003, 0x5f808201, 0x00050081, 0x03840253, 0xaf020406,
+ 0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
+ SAIFUN_FLASH_BYTE_ADDR_MASK, SAIFUN_FLASH_BASE_TOTAL_SIZE,
+ "Non-buffered flash (64kB)"},
+ /* Fast EEPROM */
+ {0x22000000, 0x62808380, 0x009f0081, 0xa184a053, 0xaf000400,
+ 1, SEEPROM_PAGE_BITS, SEEPROM_PAGE_SIZE,
+ SEEPROM_BYTE_ADDR_MASK, SEEPROM_TOTAL_SIZE,
+ "EEPROM - fast"},
+ /* Expansion entry 1001 */
+ {0x2a000002, 0x6b808201, 0x00050081, 0x03840253, 0xaf020406,
+ 0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
+ SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
+ "Entry 1001"},
+ /* Expansion entry 1010 */
+ {0x26000001, 0x67808201, 0x00050081, 0x03840253, 0xaf020406,
+ 0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
+ SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
+ "Entry 1010"},
+ /* ATMEL AT45DB011B (buffered flash) */
+ {0x2e000003, 0x6e808273, 0x00570081, 0x68848353, 0xaf000400,
+ 1, BUFFERED_FLASH_PAGE_BITS, BUFFERED_FLASH_PAGE_SIZE,
+ BUFFERED_FLASH_BYTE_ADDR_MASK, BUFFERED_FLASH_TOTAL_SIZE,
+ "Buffered flash (128kB)"},
+ /* Expansion entry 1100 */
+ {0x33000000, 0x73808201, 0x00050081, 0x03840253, 0xaf020406,
+ 0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
+ SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
+ "Entry 1100"},
+ /* Expansion entry 1101 */
+ {0x3b000002, 0x7b808201, 0x00050081, 0x03840253, 0xaf020406,
+ 0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
+ SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
+ "Entry 1101"},
+ /* Ateml Expansion entry 1110 */
+ {0x37000001, 0x76808273, 0x00570081, 0x68848353, 0xaf000400,
+ 1, BUFFERED_FLASH_PAGE_BITS, BUFFERED_FLASH_PAGE_SIZE,
+ BUFFERED_FLASH_BYTE_ADDR_MASK, 0,
+ "Entry 1110 (Atmel)"},
+ /* ATMEL AT45DB021B (buffered flash) */
+ {0x3f000003, 0x7e808273, 0x00570081, 0x68848353, 0xaf000400,
+ 1, BUFFERED_FLASH_PAGE_BITS, BUFFERED_FLASH_PAGE_SIZE,
+ BUFFERED_FLASH_BYTE_ADDR_MASK, BUFFERED_FLASH_TOTAL_SIZE*2,
+ "Buffered flash (256kB)"},
};
MODULE_DEVICE_TABLE(pci, bnx2_pci_tbl);
@@ -314,20 +372,16 @@ bnx2_free_mem(struct bnx2 *bp)
bp->tx_desc_ring, bp->tx_desc_mapping);
bp->tx_desc_ring = NULL;
}
- if (bp->tx_buf_ring) {
- kfree(bp->tx_buf_ring);
- bp->tx_buf_ring = NULL;
- }
+ kfree(bp->tx_buf_ring);
+ bp->tx_buf_ring = NULL;
if (bp->rx_desc_ring) {
pci_free_consistent(bp->pdev,
sizeof(struct rx_bd) * RX_DESC_CNT,
bp->rx_desc_ring, bp->rx_desc_mapping);
bp->rx_desc_ring = NULL;
}
- if (bp->rx_buf_ring) {
- kfree(bp->rx_buf_ring);
- bp->rx_buf_ring = NULL;
- }
+ kfree(bp->rx_buf_ring);
+ bp->rx_buf_ring = NULL;
}
static int
@@ -383,6 +437,62 @@ alloc_mem_err:
}
static void
+bnx2_report_fw_link(struct bnx2 *bp)
+{
+ u32 fw_link_status = 0;
+
+ if (bp->link_up) {
+ u32 bmsr;
+
+ switch (bp->line_speed) {
+ case SPEED_10:
+ if (bp->duplex == DUPLEX_HALF)
+ fw_link_status = BNX2_LINK_STATUS_10HALF;
+ else
+ fw_link_status = BNX2_LINK_STATUS_10FULL;
+ break;
+ case SPEED_100:
+ if (bp->duplex == DUPLEX_HALF)
+ fw_link_status = BNX2_LINK_STATUS_100HALF;
+ else
+ fw_link_status = BNX2_LINK_STATUS_100FULL;
+ break;
+ case SPEED_1000:
+ if (bp->duplex == DUPLEX_HALF)
+ fw_link_status = BNX2_LINK_STATUS_1000HALF;
+ else
+ fw_link_status = BNX2_LINK_STATUS_1000FULL;
+ break;
+ case SPEED_2500:
+ if (bp->duplex == DUPLEX_HALF)
+ fw_link_status = BNX2_LINK_STATUS_2500HALF;
+ else
+ fw_link_status = BNX2_LINK_STATUS_2500FULL;
+ break;
+ }
+
+ fw_link_status |= BNX2_LINK_STATUS_LINK_UP;
+
+ if (bp->autoneg) {
+ fw_link_status |= BNX2_LINK_STATUS_AN_ENABLED;
+
+ bnx2_read_phy(bp, MII_BMSR, &bmsr);
+ bnx2_read_phy(bp, MII_BMSR, &bmsr);
+
+ if (!(bmsr & BMSR_ANEGCOMPLETE) ||
+ bp->phy_flags & PHY_PARALLEL_DETECT_FLAG)
+ fw_link_status |= BNX2_LINK_STATUS_PARALLEL_DET;
+ else
+ fw_link_status |= BNX2_LINK_STATUS_AN_COMPLETE;
+ }
+ }
+ else
+ fw_link_status = BNX2_LINK_STATUS_LINK_DOWN;
+
+ REG_WR_IND(bp, bp->shmem_base + BNX2_LINK_STATUS, fw_link_status);
+}
+
+static void
bnx2_report_link(struct bnx2 *bp)
{
if (bp->link_up) {
@@ -413,6 +523,8 @@ bnx2_report_link(struct bnx2 *bp)
netif_carrier_off(bp->dev);
printk(KERN_ERR PFX "%s NIC Link is Down\n", bp->dev->name);
}
+
+ bnx2_report_fw_link(bp);
}
static void
@@ -434,6 +546,18 @@ bnx2_resolve_flow_ctrl(struct bnx2 *bp)
return;
}
+ if ((bp->phy_flags & PHY_SERDES_FLAG) &&
+ (CHIP_NUM(bp) == CHIP_NUM_5708)) {
+ u32 val;
+
+ bnx2_read_phy(bp, BCM5708S_1000X_STAT1, &val);
+ if (val & BCM5708S_1000X_STAT1_TX_PAUSE)
+ bp->flow_ctrl |= FLOW_CTRL_TX;
+ if (val & BCM5708S_1000X_STAT1_RX_PAUSE)
+ bp->flow_ctrl |= FLOW_CTRL_RX;
+ return;
+ }
+
bnx2_read_phy(bp, MII_ADVERTISE, &local_adv);
bnx2_read_phy(bp, MII_LPA, &remote_adv);
@@ -480,7 +604,36 @@ bnx2_resolve_flow_ctrl(struct bnx2 *bp)
}
static int
-bnx2_serdes_linkup(struct bnx2 *bp)
+bnx2_5708s_linkup(struct bnx2 *bp)
+{
+ u32 val;
+
+ bp->link_up = 1;
+ bnx2_read_phy(bp, BCM5708S_1000X_STAT1, &val);
+ switch (val & BCM5708S_1000X_STAT1_SPEED_MASK) {
+ case BCM5708S_1000X_STAT1_SPEED_10:
+ bp->line_speed = SPEED_10;
+ break;
+ case BCM5708S_1000X_STAT1_SPEED_100:
+ bp->line_speed = SPEED_100;
+ break;
+ case BCM5708S_1000X_STAT1_SPEED_1G:
+ bp->line_speed = SPEED_1000;
+ break;
+ case BCM5708S_1000X_STAT1_SPEED_2G5:
+ bp->line_speed = SPEED_2500;
+ break;
+ }
+ if (val & BCM5708S_1000X_STAT1_FD)
+ bp->duplex = DUPLEX_FULL;
+ else
+ bp->duplex = DUPLEX_HALF;
+
+ return 0;
+}
+
+static int
+bnx2_5706s_linkup(struct bnx2 *bp)
{
u32 bmcr, local_adv, remote_adv, common;
@@ -597,13 +750,27 @@ bnx2_set_mac_link(struct bnx2 *bp)
val = REG_RD(bp, BNX2_EMAC_MODE);
val &= ~(BNX2_EMAC_MODE_PORT | BNX2_EMAC_MODE_HALF_DUPLEX |
- BNX2_EMAC_MODE_MAC_LOOP | BNX2_EMAC_MODE_FORCE_LINK);
+ BNX2_EMAC_MODE_MAC_LOOP | BNX2_EMAC_MODE_FORCE_LINK |
+ BNX2_EMAC_MODE_25G);
if (bp->link_up) {
- if (bp->line_speed != SPEED_1000)
- val |= BNX2_EMAC_MODE_PORT_MII;
- else
- val |= BNX2_EMAC_MODE_PORT_GMII;
+ switch (bp->line_speed) {
+ case SPEED_10:
+ if (CHIP_NUM(bp) == CHIP_NUM_5708) {
+ val |= BNX2_EMAC_MODE_PORT_MII_10;
+ break;
+ }
+ /* fall through */
+ case SPEED_100:
+ val |= BNX2_EMAC_MODE_PORT_MII;
+ break;
+ case SPEED_2500:
+ val |= BNX2_EMAC_MODE_25G;
+ /* fall through */
+ case SPEED_1000:
+ val |= BNX2_EMAC_MODE_PORT_GMII;
+ break;
+ }
}
else {
val |= BNX2_EMAC_MODE_PORT_GMII;
@@ -666,7 +833,10 @@ bnx2_set_link(struct bnx2 *bp)
bp->link_up = 1;
if (bp->phy_flags & PHY_SERDES_FLAG) {
- bnx2_serdes_linkup(bp);
+ if (CHIP_NUM(bp) == CHIP_NUM_5706)
+ bnx2_5706s_linkup(bp);
+ else if (CHIP_NUM(bp) == CHIP_NUM_5708)
+ bnx2_5708s_linkup(bp);
}
else {
bnx2_copper_linkup(bp);
@@ -759,39 +929,61 @@ bnx2_phy_get_pause_adv(struct bnx2 *bp)
static int
bnx2_setup_serdes_phy(struct bnx2 *bp)
{
- u32 adv, bmcr;
+ u32 adv, bmcr, up1;
u32 new_adv = 0;
if (!(bp->autoneg & AUTONEG_SPEED)) {
u32 new_bmcr;
+ int force_link_down = 0;
+
+ if (CHIP_NUM(bp) == CHIP_NUM_5708) {
+ bnx2_read_phy(bp, BCM5708S_UP1, &up1);
+ if (up1 & BCM5708S_UP1_2G5) {
+ up1 &= ~BCM5708S_UP1_2G5;
+ bnx2_write_phy(bp, BCM5708S_UP1, up1);
+ force_link_down = 1;
+ }
+ }
+
+ bnx2_read_phy(bp, MII_ADVERTISE, &adv);
+ adv &= ~(ADVERTISE_1000XFULL | ADVERTISE_1000XHALF);
bnx2_read_phy(bp, MII_BMCR, &bmcr);
new_bmcr = bmcr & ~BMCR_ANENABLE;
new_bmcr |= BMCR_SPEED1000;
if (bp->req_duplex == DUPLEX_FULL) {
+ adv |= ADVERTISE_1000XFULL;
new_bmcr |= BMCR_FULLDPLX;
}
else {
+ adv |= ADVERTISE_1000XHALF;
new_bmcr &= ~BMCR_FULLDPLX;
}
- if (new_bmcr != bmcr) {
+ if ((new_bmcr != bmcr) || (force_link_down)) {
/* Force a link down visible on the other side */
if (bp->link_up) {
- bnx2_read_phy(bp, MII_ADVERTISE, &adv);
- adv &= ~(ADVERTISE_1000XFULL |
- ADVERTISE_1000XHALF);
- bnx2_write_phy(bp, MII_ADVERTISE, adv);
+ bnx2_write_phy(bp, MII_ADVERTISE, adv &
+ ~(ADVERTISE_1000XFULL |
+ ADVERTISE_1000XHALF));
bnx2_write_phy(bp, MII_BMCR, bmcr |
BMCR_ANRESTART | BMCR_ANENABLE);
bp->link_up = 0;
netif_carrier_off(bp->dev);
+ bnx2_write_phy(bp, MII_BMCR, new_bmcr);
}
+ bnx2_write_phy(bp, MII_ADVERTISE, adv);
bnx2_write_phy(bp, MII_BMCR, new_bmcr);
}
return 0;
}
+ if (bp->phy_flags & PHY_2_5G_CAPABLE_FLAG) {
+ bnx2_read_phy(bp, BCM5708S_UP1, &up1);
+ up1 |= BCM5708S_UP1_2G5;
+ bnx2_write_phy(bp, BCM5708S_UP1, up1);
+ }
+
if (bp->advertising & ADVERTISED_1000baseT_Full)
new_adv |= ADVERTISE_1000XFULL;
@@ -956,7 +1148,60 @@ bnx2_setup_phy(struct bnx2 *bp)
}
static int
-bnx2_init_serdes_phy(struct bnx2 *bp)
+bnx2_init_5708s_phy(struct bnx2 *bp)
+{
+ u32 val;
+
+ bnx2_write_phy(bp, BCM5708S_BLK_ADDR, BCM5708S_BLK_ADDR_DIG3);
+ bnx2_write_phy(bp, BCM5708S_DIG_3_0, BCM5708S_DIG_3_0_USE_IEEE);
+ bnx2_write_phy(bp, BCM5708S_BLK_ADDR, BCM5708S_BLK_ADDR_DIG);
+
+ bnx2_read_phy(bp, BCM5708S_1000X_CTL1, &val);
+ val |= BCM5708S_1000X_CTL1_FIBER_MODE | BCM5708S_1000X_CTL1_AUTODET_EN;
+ bnx2_write_phy(bp, BCM5708S_1000X_CTL1, val);
+
+ bnx2_read_phy(bp, BCM5708S_1000X_CTL2, &val);
+ val |= BCM5708S_1000X_CTL2_PLLEL_DET_EN;
+ bnx2_write_phy(bp, BCM5708S_1000X_CTL2, val);
+
+ if (bp->phy_flags & PHY_2_5G_CAPABLE_FLAG) {
+ bnx2_read_phy(bp, BCM5708S_UP1, &val);
+ val |= BCM5708S_UP1_2G5;
+ bnx2_write_phy(bp, BCM5708S_UP1, val);
+ }
+
+ if ((CHIP_ID(bp) == CHIP_ID_5708_A0) ||
+ (CHIP_ID(bp) == CHIP_ID_5708_B0)) {
+ /* increase tx signal amplitude */
+ bnx2_write_phy(bp, BCM5708S_BLK_ADDR,
+ BCM5708S_BLK_ADDR_TX_MISC);
+ bnx2_read_phy(bp, BCM5708S_TX_ACTL1, &val);
+ val &= ~BCM5708S_TX_ACTL1_DRIVER_VCM;
+ bnx2_write_phy(bp, BCM5708S_TX_ACTL1, val);
+ bnx2_write_phy(bp, BCM5708S_BLK_ADDR, BCM5708S_BLK_ADDR_DIG);
+ }
+
+ val = REG_RD_IND(bp, bp->shmem_base + BNX2_PORT_HW_CFG_CONFIG) &
+ BNX2_PORT_HW_CFG_CFG_TXCTL3_MASK;
+
+ if (val) {
+ u32 is_backplane;
+
+ is_backplane = REG_RD_IND(bp, bp->shmem_base +
+ BNX2_SHARED_HW_CFG_CONFIG);
+ if (is_backplane & BNX2_SHARED_HW_CFG_PHY_BACKPLANE) {
+ bnx2_write_phy(bp, BCM5708S_BLK_ADDR,
+ BCM5708S_BLK_ADDR_TX_MISC);
+ bnx2_write_phy(bp, BCM5708S_TX_ACTL3, val);
+ bnx2_write_phy(bp, BCM5708S_BLK_ADDR,
+ BCM5708S_BLK_ADDR_DIG);
+ }
+ }
+ return 0;
+}
+
+static int
+bnx2_init_5706s_phy(struct bnx2 *bp)
{
bp->phy_flags &= ~PHY_PARALLEL_DETECT_FLAG;
@@ -994,6 +1239,8 @@ bnx2_init_serdes_phy(struct bnx2 *bp)
static int
bnx2_init_copper_phy(struct bnx2 *bp)
{
+ u32 val;
+
bp->phy_flags |= PHY_CRC_FIX_FLAG;
if (bp->phy_flags & PHY_CRC_FIX_FLAG) {
@@ -1008,8 +1255,6 @@ bnx2_init_copper_phy(struct bnx2 *bp)
}
if (bp->dev->mtu > 1500) {
- u32 val;
-
/* Set extended packet length bit */
bnx2_write_phy(bp, 0x18, 0x7);
bnx2_read_phy(bp, 0x18, &val);
@@ -1019,8 +1264,6 @@ bnx2_init_copper_phy(struct bnx2 *bp)
bnx2_write_phy(bp, 0x10, val | 0x1);
}
else {
- u32 val;
-
bnx2_write_phy(bp, 0x18, 0x7);
bnx2_read_phy(bp, 0x18, &val);
bnx2_write_phy(bp, 0x18, val & ~0x4007);
@@ -1029,6 +1272,10 @@ bnx2_init_copper_phy(struct bnx2 *bp)
bnx2_write_phy(bp, 0x10, val & ~0x1);
}
+ /* ethernet@wirespeed */
+ bnx2_write_phy(bp, 0x18, 0x7007);
+ bnx2_read_phy(bp, 0x18, &val);
+ bnx2_write_phy(bp, 0x18, val | (1 << 15) | (1 << 4));
return 0;
}
@@ -1052,7 +1299,10 @@ bnx2_init_phy(struct bnx2 *bp)
bp->phy_id |= val & 0xffff;
if (bp->phy_flags & PHY_SERDES_FLAG) {
- rc = bnx2_init_serdes_phy(bp);
+ if (CHIP_NUM(bp) == CHIP_NUM_5706)
+ rc = bnx2_init_5706s_phy(bp);
+ else if (CHIP_NUM(bp) == CHIP_NUM_5708)
+ rc = bnx2_init_5708s_phy(bp);
}
else {
rc = bnx2_init_copper_phy(bp);
@@ -1088,13 +1338,13 @@ bnx2_fw_sync(struct bnx2 *bp, u32 msg_data)
bp->fw_wr_seq++;
msg_data |= bp->fw_wr_seq;
- REG_WR_IND(bp, HOST_VIEW_SHMEM_BASE + BNX2_DRV_MB, msg_data);
+ REG_WR_IND(bp, bp->shmem_base + BNX2_DRV_MB, msg_data);
/* wait for an acknowledgement. */
for (i = 0; i < (FW_ACK_TIME_OUT_MS * 1000)/5; i++) {
udelay(5);
- val = REG_RD_IND(bp, HOST_VIEW_SHMEM_BASE + BNX2_FW_MB);
+ val = REG_RD_IND(bp, bp->shmem_base + BNX2_FW_MB);
if ((val & BNX2_FW_MSG_ACK) == (msg_data & BNX2_DRV_MSG_SEQ))
break;
@@ -1107,7 +1357,7 @@ bnx2_fw_sync(struct bnx2 *bp, u32 msg_data)
msg_data &= ~BNX2_DRV_MSG_CODE;
msg_data |= BNX2_DRV_MSG_CODE_FW_TIMEOUT;
- REG_WR_IND(bp, HOST_VIEW_SHMEM_BASE + BNX2_DRV_MB, msg_data);
+ REG_WR_IND(bp, bp->shmem_base + BNX2_DRV_MB, msg_data);
bp->fw_timed_out = 1;
@@ -1283,10 +1533,11 @@ bnx2_phy_int(struct bnx2 *bp)
static void
bnx2_tx_int(struct bnx2 *bp)
{
+ struct status_block *sblk = bp->status_blk;
u16 hw_cons, sw_cons, sw_ring_cons;
int tx_free_bd = 0;
- hw_cons = bp->status_blk->status_tx_quick_consumer_index0;
+ hw_cons = bp->hw_tx_cons = sblk->status_tx_quick_consumer_index0;
if ((hw_cons & MAX_TX_DESC_CNT) == MAX_TX_DESC_CNT) {
hw_cons++;
}
@@ -1341,7 +1592,9 @@ bnx2_tx_int(struct bnx2 *bp)
dev_kfree_skb_irq(skb);
- hw_cons = bp->status_blk->status_tx_quick_consumer_index0;
+ hw_cons = bp->hw_tx_cons =
+ sblk->status_tx_quick_consumer_index0;
+
if ((hw_cons & MAX_TX_DESC_CNT) == MAX_TX_DESC_CNT) {
hw_cons++;
}
@@ -1386,11 +1639,12 @@ bnx2_reuse_rx_skb(struct bnx2 *bp, struct sk_buff *skb,
static int
bnx2_rx_int(struct bnx2 *bp, int budget)
{
+ struct status_block *sblk = bp->status_blk;
u16 hw_cons, sw_cons, sw_ring_cons, sw_prod, sw_ring_prod;
struct l2_fhdr *rx_hdr;
int rx_pkt = 0;
- hw_cons = bp->status_blk->status_rx_quick_consumer_index0;
+ hw_cons = bp->hw_rx_cons = sblk->status_rx_quick_consumer_index0;
if ((hw_cons & MAX_RX_DESC_CNT) == MAX_RX_DESC_CNT) {
hw_cons++;
}
@@ -1510,6 +1764,15 @@ next_rx:
if ((rx_pkt == budget))
break;
+
+ /* Refresh hw_cons to see if there is new work */
+ if (sw_cons == hw_cons) {
+ hw_cons = bp->hw_rx_cons =
+ sblk->status_rx_quick_consumer_index0;
+ if ((hw_cons & MAX_RX_DESC_CNT) == MAX_RX_DESC_CNT)
+ hw_cons++;
+ rmb();
+ }
}
bp->rx_cons = sw_cons;
bp->rx_prod = sw_prod;
@@ -1577,15 +1840,27 @@ bnx2_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
return IRQ_HANDLED;
}
+static inline int
+bnx2_has_work(struct bnx2 *bp)
+{
+ struct status_block *sblk = bp->status_blk;
+
+ if ((sblk->status_rx_quick_consumer_index0 != bp->hw_rx_cons) ||
+ (sblk->status_tx_quick_consumer_index0 != bp->hw_tx_cons))
+ return 1;
+
+ if (((sblk->status_attn_bits & STATUS_ATTN_BITS_LINK_STATE) != 0) !=
+ bp->link_up)
+ return 1;
+
+ return 0;
+}
+
static int
bnx2_poll(struct net_device *dev, int *budget)
{
struct bnx2 *bp = dev->priv;
- int rx_done = 1;
- bp->last_status_idx = bp->status_blk->status_idx;
-
- rmb();
if ((bp->status_blk->status_attn_bits &
STATUS_ATTN_BITS_LINK_STATE) !=
(bp->status_blk->status_attn_bits_ack &
@@ -1596,11 +1871,10 @@ bnx2_poll(struct net_device *dev, int *budget)
spin_unlock(&bp->phy_lock);
}
- if (bp->status_blk->status_tx_quick_consumer_index0 != bp->tx_cons) {
+ if (bp->status_blk->status_tx_quick_consumer_index0 != bp->hw_tx_cons)
bnx2_tx_int(bp);
- }
- if (bp->status_blk->status_rx_quick_consumer_index0 != bp->rx_cons) {
+ if (bp->status_blk->status_rx_quick_consumer_index0 != bp->hw_rx_cons) {
int orig_budget = *budget;
int work_done;
@@ -1610,13 +1884,12 @@ bnx2_poll(struct net_device *dev, int *budget)
work_done = bnx2_rx_int(bp, orig_budget);
*budget -= work_done;
dev->quota -= work_done;
-
- if (work_done >= orig_budget) {
- rx_done = 0;
- }
}
- if (rx_done) {
+ bp->last_status_idx = bp->status_blk->status_idx;
+ rmb();
+
+ if (!bnx2_has_work(bp)) {
netif_rx_complete(dev);
REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD,
BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID |
@@ -2387,21 +2660,27 @@ bnx2_init_nvram(struct bnx2 *bp)
/* Flash interface has been reconfigured */
for (j = 0, flash = &flash_table[0]; j < entry_count;
- j++, flash++) {
-
- if (val == flash->config1) {
+ j++, flash++) {
+ if ((val & FLASH_BACKUP_STRAP_MASK) ==
+ (flash->config1 & FLASH_BACKUP_STRAP_MASK)) {
bp->flash_info = flash;
break;
}
}
}
else {
+ u32 mask;
/* Not yet been reconfigured */
+ if (val & (1 << 23))
+ mask = FLASH_BACKUP_STRAP_MASK;
+ else
+ mask = FLASH_STRAP_MASK;
+
for (j = 0, flash = &flash_table[0]; j < entry_count;
j++, flash++) {
- if ((val & FLASH_STRAP_MASK) == flash->strapping) {
+ if ((val & mask) == (flash->strapping & mask)) {
bp->flash_info = flash;
/* Request access to the flash interface. */
@@ -2428,7 +2707,7 @@ bnx2_init_nvram(struct bnx2 *bp)
if (j == entry_count) {
bp->flash_info = NULL;
- printk(KERN_ALERT "Unknown flash/EEPROM type.\n");
+ printk(KERN_ALERT PFX "Unknown flash/EEPROM type.\n");
rc = -ENODEV;
}
@@ -2737,7 +3016,7 @@ bnx2_reset_chip(struct bnx2 *bp, u32 reset_code)
/* Deposit a driver reset signature so the firmware knows that
* this is a soft reset. */
- REG_WR_IND(bp, HOST_VIEW_SHMEM_BASE + BNX2_DRV_RESET_SIGNATURE,
+ REG_WR_IND(bp, bp->shmem_base + BNX2_DRV_RESET_SIGNATURE,
BNX2_DRV_RESET_SIGNATURE_MAGIC);
bp->fw_timed_out = 0;
@@ -2966,6 +3245,7 @@ bnx2_init_tx_ring(struct bnx2 *bp)
bp->tx_prod = 0;
bp->tx_cons = 0;
+ bp->hw_tx_cons = 0;
bp->tx_prod_bseq = 0;
val = BNX2_L2CTX_TYPE_TYPE_L2;
@@ -2998,6 +3278,7 @@ bnx2_init_rx_ring(struct bnx2 *bp)
ring_prod = prod = bp->rx_prod = 0;
bp->rx_cons = 0;
+ bp->hw_rx_cons = 0;
bp->rx_prod_bseq = 0;
rxbd = &bp->rx_desc_ring[0];
@@ -3083,7 +3364,7 @@ bnx2_free_rx_skbs(struct bnx2 *bp)
struct sw_bd *rx_buf = &bp->rx_buf_ring[i];
struct sk_buff *skb = rx_buf->skb;
- if (skb == 0)
+ if (skb == NULL)
continue;
pci_unmap_single(bp->pdev, pci_unmap_addr(rx_buf, mapping),
@@ -3238,7 +3519,7 @@ bnx2_test_registers(struct bnx2 *bp)
{ 0x1408, 0, 0x01c00800, 0x00000000 },
{ 0x149c, 0, 0x8000ffff, 0x00000000 },
{ 0x14a8, 0, 0x00000000, 0x000001ff },
- { 0x14ac, 0, 0x4fffffff, 0x10000000 },
+ { 0x14ac, 0, 0x0fffffff, 0x10000000 },
{ 0x14b0, 0, 0x00000002, 0x00000001 },
{ 0x14b8, 0, 0x00000000, 0x00000000 },
{ 0x14c0, 0, 0x00000000, 0x00000009 },
@@ -3581,7 +3862,7 @@ bnx2_test_memory(struct bnx2 *bp)
u32 len;
} mem_tbl[] = {
{ 0x60000, 0x4000 },
- { 0xa0000, 0x4000 },
+ { 0xa0000, 0x3000 },
{ 0xe0000, 0x4000 },
{ 0x120000, 0x4000 },
{ 0x1a0000, 0x4000 },
@@ -3622,6 +3903,8 @@ bnx2_test_loopback(struct bnx2 *bp)
pkt_size = 1514;
skb = dev_alloc_skb(pkt_size);
+ if (!skb)
+ return -ENOMEM;
packet = skb_put(skb, pkt_size);
memcpy(packet, bp->mac_addr, 6);
memset(packet + 6, 0x0, 8);
@@ -3814,7 +4097,7 @@ bnx2_timer(unsigned long data)
goto bnx2_restart_timer;
msg = (u32) ++bp->fw_drv_pulse_wr_seq;
- REG_WR_IND(bp, HOST_VIEW_SHMEM_BASE + BNX2_DRV_PULSE_MB, msg);
+ REG_WR_IND(bp, bp->shmem_base + BNX2_DRV_PULSE_MB, msg);
if ((bp->phy_flags & PHY_SERDES_FLAG) &&
(CHIP_NUM(bp) == CHIP_NUM_5706)) {
@@ -4268,7 +4551,8 @@ bnx2_get_stats(struct net_device *dev)
(unsigned long) (stats_blk->stat_Dot3StatsExcessiveCollisions +
stats_blk->stat_Dot3StatsLateCollisions);
- if (CHIP_NUM(bp) == CHIP_NUM_5706)
+ if ((CHIP_NUM(bp) == CHIP_NUM_5706) ||
+ (CHIP_ID(bp) == CHIP_ID_5708_A0))
net_stats->tx_carrier_errors = 0;
else {
net_stats->tx_carrier_errors =
@@ -4516,11 +4800,7 @@ bnx2_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
struct bnx2 *bp = dev->priv;
int rc;
- if (eeprom->offset > bp->flash_info->total_size)
- return -EINVAL;
-
- if ((eeprom->offset + eeprom->len) > bp->flash_info->total_size)
- eeprom->len = bp->flash_info->total_size - eeprom->offset;
+ /* parameters already validated in ethtool_get_eeprom */
rc = bnx2_nvram_read(bp, eeprom->offset, eebuf, eeprom->len);
@@ -4534,11 +4814,7 @@ bnx2_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
struct bnx2 *bp = dev->priv;
int rc;
- if (eeprom->offset > bp->flash_info->total_size)
- return -EINVAL;
-
- if ((eeprom->offset + eeprom->len) > bp->flash_info->total_size)
- eeprom->len = bp->flash_info->total_size - eeprom->offset;
+ /* parameters already validated in ethtool_set_eeprom */
rc = bnx2_nvram_write(bp, eeprom->offset, eebuf, eeprom->len);
@@ -4818,6 +5094,14 @@ static u8 bnx2_5706_stats_len_arr[BNX2_NUM_STATS] = {
4,4,4,4,4,
};
+static u8 bnx2_5708_stats_len_arr[BNX2_NUM_STATS] = {
+ 8,0,8,8,8,8,8,8,8,8,
+ 4,4,4,4,4,4,4,4,4,4,
+ 4,4,4,4,4,4,4,4,4,4,
+ 4,4,4,4,4,4,4,4,4,4,
+ 4,4,4,4,4,
+};
+
#define BNX2_NUM_TESTS 6
static struct {
@@ -4926,8 +5210,13 @@ bnx2_get_ethtool_stats(struct net_device *dev,
return;
}
- if (CHIP_NUM(bp) == CHIP_NUM_5706)
+ if ((CHIP_ID(bp) == CHIP_ID_5706_A0) ||
+ (CHIP_ID(bp) == CHIP_ID_5706_A1) ||
+ (CHIP_ID(bp) == CHIP_ID_5706_A2) ||
+ (CHIP_ID(bp) == CHIP_ID_5708_A0))
stats_len_arr = bnx2_5706_stats_len_arr;
+ else
+ stats_len_arr = bnx2_5708_stats_len_arr;
for (i = 0; i < BNX2_NUM_STATS; i++) {
if (stats_len_arr[i] == 0) {
@@ -5209,8 +5498,6 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
bp->chip_id = REG_RD(bp, BNX2_MISC_ID);
- bp->phy_addr = 1;
-
/* Get bus information. */
reg = REG_RD(bp, BNX2_PCICFG_MISC_STATUS);
if (reg & BNX2_PCICFG_MISC_STATUS_PCIX_DET) {
@@ -5273,10 +5560,18 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
bnx2_init_nvram(bp);
+ reg = REG_RD_IND(bp, BNX2_SHM_HDR_SIGNATURE);
+
+ if ((reg & BNX2_SHM_HDR_SIGNATURE_SIG_MASK) ==
+ BNX2_SHM_HDR_SIGNATURE_SIG)
+ bp->shmem_base = REG_RD_IND(bp, BNX2_SHM_HDR_ADDR_0);
+ else
+ bp->shmem_base = HOST_VIEW_SHMEM_BASE;
+
/* Get the permanent MAC address. First we need to make sure the
* firmware is actually running.
*/
- reg = REG_RD_IND(bp, HOST_VIEW_SHMEM_BASE + BNX2_DEV_INFO_SIGNATURE);
+ reg = REG_RD_IND(bp, bp->shmem_base + BNX2_DEV_INFO_SIGNATURE);
if ((reg & BNX2_DEV_INFO_SIGNATURE_MAGIC_MASK) !=
BNX2_DEV_INFO_SIGNATURE_MAGIC) {
@@ -5285,14 +5580,13 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
goto err_out_unmap;
}
- bp->fw_ver = REG_RD_IND(bp, HOST_VIEW_SHMEM_BASE +
- BNX2_DEV_INFO_BC_REV);
+ bp->fw_ver = REG_RD_IND(bp, bp->shmem_base + BNX2_DEV_INFO_BC_REV);
- reg = REG_RD_IND(bp, HOST_VIEW_SHMEM_BASE + BNX2_PORT_HW_CFG_MAC_UPPER);
+ reg = REG_RD_IND(bp, bp->shmem_base + BNX2_PORT_HW_CFG_MAC_UPPER);
bp->mac_addr[0] = (u8) (reg >> 8);
bp->mac_addr[1] = (u8) reg;
- reg = REG_RD_IND(bp, HOST_VIEW_SHMEM_BASE + BNX2_PORT_HW_CFG_MAC_LOWER);
+ reg = REG_RD_IND(bp, bp->shmem_base + BNX2_PORT_HW_CFG_MAC_LOWER);
bp->mac_addr[2] = (u8) (reg >> 24);
bp->mac_addr[3] = (u8) (reg >> 16);
bp->mac_addr[4] = (u8) (reg >> 8);
@@ -5320,10 +5614,19 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
bp->timer_interval = HZ;
bp->current_interval = HZ;
+ bp->phy_addr = 1;
+
/* Disable WOL support if we are running on a SERDES chip. */
if (CHIP_BOND_ID(bp) & CHIP_BOND_ID_SERDES_BIT) {
bp->phy_flags |= PHY_SERDES_FLAG;
bp->flags |= NO_WOL_FLAG;
+ if (CHIP_NUM(bp) == CHIP_NUM_5708) {
+ bp->phy_addr = 2;
+ reg = REG_RD_IND(bp, bp->shmem_base +
+ BNX2_SHARED_HW_CFG_CONFIG);
+ if (reg & BNX2_SHARED_HW_CFG_PHY_2_5G)
+ bp->phy_flags |= PHY_2_5G_CAPABLE_FLAG;
+ }
}
if (CHIP_ID(bp) == CHIP_ID_5706_A0) {
@@ -5343,8 +5646,7 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
if (bp->phy_flags & PHY_SERDES_FLAG) {
bp->advertising = ETHTOOL_ALL_FIBRE_SPEED | ADVERTISED_Autoneg;
- reg = REG_RD_IND(bp, HOST_VIEW_SHMEM_BASE +
- BNX2_PORT_HW_CFG_CONFIG);
+ reg = REG_RD_IND(bp, bp->shmem_base + BNX2_PORT_HW_CFG_CONFIG);
reg &= BNX2_PORT_HW_CFG_CFG_DFLT_LINK_MASK;
if (reg == BNX2_PORT_HW_CFG_CFG_DFLT_LINK_1G) {
bp->autoneg = 0;
diff --git a/drivers/net/bnx2.h b/drivers/net/bnx2.h
index 62857b6a6ee4..76bb5f1a250b 100644
--- a/drivers/net/bnx2.h
+++ b/drivers/net/bnx2.h
@@ -1449,8 +1449,9 @@ struct l2_fhdr {
#define BNX2_EMAC_MODE_PORT_NONE (0L<<2)
#define BNX2_EMAC_MODE_PORT_MII (1L<<2)
#define BNX2_EMAC_MODE_PORT_GMII (2L<<2)
-#define BNX2_EMAC_MODE_PORT_UNDEF (3L<<2)
+#define BNX2_EMAC_MODE_PORT_MII_10 (3L<<2)
#define BNX2_EMAC_MODE_MAC_LOOP (1L<<4)
+#define BNX2_EMAC_MODE_25G (1L<<5)
#define BNX2_EMAC_MODE_TAGGED_MAC_CTL (1L<<7)
#define BNX2_EMAC_MODE_TX_BURST (1L<<8)
#define BNX2_EMAC_MODE_MAX_DEFER_DROP_ENA (1L<<9)
@@ -3714,6 +3715,15 @@ struct l2_fhdr {
#define BNX2_MCP_ROM 0x00150000
#define BNX2_MCP_SCRATCH 0x00160000
+#define BNX2_SHM_HDR_SIGNATURE BNX2_MCP_SCRATCH
+#define BNX2_SHM_HDR_SIGNATURE_SIG_MASK 0xffff0000
+#define BNX2_SHM_HDR_SIGNATURE_SIG 0x53530000
+#define BNX2_SHM_HDR_SIGNATURE_VER_MASK 0x000000ff
+#define BNX2_SHM_HDR_SIGNATURE_VER_ONE 0x00000001
+
+#define BNX2_SHM_HDR_ADDR_0 BNX2_MCP_SCRATCH + 4
+#define BNX2_SHM_HDR_ADDR_1 BNX2_MCP_SCRATCH + 8
+
#define NUM_MC_HASH_REGISTERS 8
@@ -3724,6 +3734,53 @@ struct l2_fhdr {
#define PHY_ID(id) ((id) & 0xfffffff0)
#define PHY_REV_ID(id) ((id) & 0xf)
+/* 5708 Serdes PHY registers */
+
+#define BCM5708S_UP1 0xb
+
+#define BCM5708S_UP1_2G5 0x1
+
+#define BCM5708S_BLK_ADDR 0x1f
+
+#define BCM5708S_BLK_ADDR_DIG 0x0000
+#define BCM5708S_BLK_ADDR_DIG3 0x0002
+#define BCM5708S_BLK_ADDR_TX_MISC 0x0005
+
+/* Digital Block */
+#define BCM5708S_1000X_CTL1 0x10
+
+#define BCM5708S_1000X_CTL1_FIBER_MODE 0x0001
+#define BCM5708S_1000X_CTL1_AUTODET_EN 0x0010
+
+#define BCM5708S_1000X_CTL2 0x11
+
+#define BCM5708S_1000X_CTL2_PLLEL_DET_EN 0x0001
+
+#define BCM5708S_1000X_STAT1 0x14
+
+#define BCM5708S_1000X_STAT1_SGMII 0x0001
+#define BCM5708S_1000X_STAT1_LINK 0x0002
+#define BCM5708S_1000X_STAT1_FD 0x0004
+#define BCM5708S_1000X_STAT1_SPEED_MASK 0x0018
+#define BCM5708S_1000X_STAT1_SPEED_10 0x0000
+#define BCM5708S_1000X_STAT1_SPEED_100 0x0008
+#define BCM5708S_1000X_STAT1_SPEED_1G 0x0010
+#define BCM5708S_1000X_STAT1_SPEED_2G5 0x0018
+#define BCM5708S_1000X_STAT1_TX_PAUSE 0x0020
+#define BCM5708S_1000X_STAT1_RX_PAUSE 0x0040
+
+/* Digital3 Block */
+#define BCM5708S_DIG_3_0 0x10
+
+#define BCM5708S_DIG_3_0_USE_IEEE 0x0001
+
+/* Tx/Misc Block */
+#define BCM5708S_TX_ACTL1 0x15
+
+#define BCM5708S_TX_ACTL1_DRIVER_VCM 0x30
+
+#define BCM5708S_TX_ACTL3 0x17
+
#define MIN_ETHERNET_PACKET_SIZE 60
#define MAX_ETHERNET_PACKET_SIZE 1514
#define MAX_ETHERNET_JUMBO_PACKET_SIZE 9014
@@ -3799,7 +3856,7 @@ struct sw_bd {
#define BUFFERED_FLASH_PHY_PAGE_SIZE (1 << BUFFERED_FLASH_PAGE_BITS)
#define BUFFERED_FLASH_BYTE_ADDR_MASK (BUFFERED_FLASH_PHY_PAGE_SIZE-1)
#define BUFFERED_FLASH_PAGE_SIZE 264
-#define BUFFERED_FLASH_TOTAL_SIZE 131072
+#define BUFFERED_FLASH_TOTAL_SIZE 0x21000
#define SAIFUN_FLASH_PAGE_BITS 8
#define SAIFUN_FLASH_PHY_PAGE_SIZE (1 << SAIFUN_FLASH_PAGE_BITS)
@@ -3807,6 +3864,12 @@ struct sw_bd {
#define SAIFUN_FLASH_PAGE_SIZE 256
#define SAIFUN_FLASH_BASE_TOTAL_SIZE 65536
+#define ST_MICRO_FLASH_PAGE_BITS 8
+#define ST_MICRO_FLASH_PHY_PAGE_SIZE (1 << ST_MICRO_FLASH_PAGE_BITS)
+#define ST_MICRO_FLASH_BYTE_ADDR_MASK (ST_MICRO_FLASH_PHY_PAGE_SIZE-1)
+#define ST_MICRO_FLASH_PAGE_SIZE 256
+#define ST_MICRO_FLASH_BASE_TOTAL_SIZE 65536
+
#define NVRAM_TIMEOUT_COUNT 30000
@@ -3815,6 +3878,8 @@ struct sw_bd {
BNX2_NVM_CFG1_PROTECT_MODE | \
BNX2_NVM_CFG1_FLASH_SIZE)
+#define FLASH_BACKUP_STRAP_MASK (0xf << 26)
+
struct flash_spec {
u32 strapping;
u32 config1;
@@ -3849,6 +3914,9 @@ struct bnx2 {
u16 tx_cons;
int tx_ring_size;
+ u16 hw_tx_cons;
+ u16 hw_rx_cons;
+
#ifdef BCM_VLAN
struct vlan_group *vlgrp;
#endif
@@ -3893,6 +3961,7 @@ struct bnx2 {
#define PHY_SERDES_FLAG 1
#define PHY_CRC_FIX_FLAG 2
#define PHY_PARALLEL_DETECT_FLAG 4
+#define PHY_2_5G_CAPABLE_FLAG 8
#define PHY_INT_MODE_MASK_FLAG 0x300
#define PHY_INT_MODE_AUTO_POLLING_FLAG 0x100
#define PHY_INT_MODE_LINK_READY_FLAG 0x200
@@ -3901,6 +3970,7 @@ struct bnx2 {
/* chip num:16-31, rev:12-15, metal:4-11, bond_id:0-3 */
#define CHIP_NUM(bp) (((bp)->chip_id) & 0xffff0000)
#define CHIP_NUM_5706 0x57060000
+#define CHIP_NUM_5708 0x57080000
#define CHIP_REV(bp) (((bp)->chip_id) & 0x0000f000)
#define CHIP_REV_Ax 0x00000000
@@ -3913,6 +3983,9 @@ struct bnx2 {
#define CHIP_ID(bp) (((bp)->chip_id) & 0xfffffff0)
#define CHIP_ID_5706_A0 0x57060000
#define CHIP_ID_5706_A1 0x57060010
+#define CHIP_ID_5706_A2 0x57060020
+#define CHIP_ID_5708_A0 0x57080000
+#define CHIP_ID_5708_B0 0x57081000
#define CHIP_BOND_ID(bp) (((bp)->chip_id) & 0xf)
@@ -3991,6 +4064,8 @@ struct bnx2 {
u8 mac_addr[8];
+ u32 shmem_base;
+
u32 fw_ver;
int pm_cap;
@@ -4130,14 +4205,46 @@ struct fw_info {
#define BNX2_FW_MSG_STATUS_FAILURE 0x00ff0000
#define BNX2_LINK_STATUS 0x0000000c
+#define BNX2_LINK_STATUS_INIT_VALUE 0xffffffff
+#define BNX2_LINK_STATUS_LINK_UP 0x1
+#define BNX2_LINK_STATUS_LINK_DOWN 0x0
+#define BNX2_LINK_STATUS_SPEED_MASK 0x1e
+#define BNX2_LINK_STATUS_AN_INCOMPLETE (0<<1)
+#define BNX2_LINK_STATUS_10HALF (1<<1)
+#define BNX2_LINK_STATUS_10FULL (2<<1)
+#define BNX2_LINK_STATUS_100HALF (3<<1)
+#define BNX2_LINK_STATUS_100BASE_T4 (4<<1)
+#define BNX2_LINK_STATUS_100FULL (5<<1)
+#define BNX2_LINK_STATUS_1000HALF (6<<1)
+#define BNX2_LINK_STATUS_1000FULL (7<<1)
+#define BNX2_LINK_STATUS_2500HALF (8<<1)
+#define BNX2_LINK_STATUS_2500FULL (9<<1)
+#define BNX2_LINK_STATUS_AN_ENABLED (1<<5)
+#define BNX2_LINK_STATUS_AN_COMPLETE (1<<6)
+#define BNX2_LINK_STATUS_PARALLEL_DET (1<<7)
+#define BNX2_LINK_STATUS_RESERVED (1<<8)
+#define BNX2_LINK_STATUS_PARTNER_AD_1000FULL (1<<9)
+#define BNX2_LINK_STATUS_PARTNER_AD_1000HALF (1<<10)
+#define BNX2_LINK_STATUS_PARTNER_AD_100BT4 (1<<11)
+#define BNX2_LINK_STATUS_PARTNER_AD_100FULL (1<<12)
+#define BNX2_LINK_STATUS_PARTNER_AD_100HALF (1<<13)
+#define BNX2_LINK_STATUS_PARTNER_AD_10FULL (1<<14)
+#define BNX2_LINK_STATUS_PARTNER_AD_10HALF (1<<15)
+#define BNX2_LINK_STATUS_TX_FC_ENABLED (1<<16)
+#define BNX2_LINK_STATUS_RX_FC_ENABLED (1<<17)
+#define BNX2_LINK_STATUS_PARTNER_SYM_PAUSE_CAP (1<<18)
+#define BNX2_LINK_STATUS_PARTNER_ASYM_PAUSE_CAP (1<<19)
+#define BNX2_LINK_STATUS_SERDES_LINK (1<<20)
+#define BNX2_LINK_STATUS_PARTNER_AD_2500FULL (1<<21)
+#define BNX2_LINK_STATUS_PARTNER_AD_2500HALF (1<<22)
#define BNX2_DRV_PULSE_MB 0x00000010
-#define BNX2_DRV_PULSE_SEQ_MASK 0x0000ffff
+#define BNX2_DRV_PULSE_SEQ_MASK 0x00007fff
/* Indicate to the firmware not to go into the
* OS absent when it is not getting driver pulse.
* This is used for debugging. */
-#define BNX2_DRV_MSG_DATA_PULSE_CODE_ALWAYS_ALIVE 0x00010000
+#define BNX2_DRV_MSG_DATA_PULSE_CODE_ALWAYS_ALIVE 0x00080000
#define BNX2_DEV_INFO_SIGNATURE 0x00000020
#define BNX2_DEV_INFO_SIGNATURE_MAGIC 0x44564900
@@ -4160,6 +4267,8 @@ struct fw_info {
#define BNX2_SHARED_HW_CFG_DESIGN_LOM 0x1
#define BNX2_SHARED_HW_CFG_PHY_COPPER 0
#define BNX2_SHARED_HW_CFG_PHY_FIBER 0x2
+#define BNX2_SHARED_HW_CFG_PHY_2_5G 0x20
+#define BNX2_SHARED_HW_CFG_PHY_BACKPLANE 0x40
#define BNX2_SHARED_HW_CFG_LED_MODE_SHIFT_BITS 8
#define BNX2_SHARED_HW_CFG_LED_MODE_MASK 0x300
#define BNX2_SHARED_HW_CFG_LED_MODE_MAC 0
@@ -4173,9 +4282,11 @@ struct fw_info {
#define BNX2_PORT_HW_CFG_MAC_LOWER 0x00000054
#define BNX2_PORT_HW_CFG_CONFIG 0x00000058
+#define BNX2_PORT_HW_CFG_CFG_TXCTL3_MASK 0x0000ffff
#define BNX2_PORT_HW_CFG_CFG_DFLT_LINK_MASK 0x001f0000
#define BNX2_PORT_HW_CFG_CFG_DFLT_LINK_AN 0x00000000
#define BNX2_PORT_HW_CFG_CFG_DFLT_LINK_1G 0x00030000
+#define BNX2_PORT_HW_CFG_CFG_DFLT_LINK_2_5G 0x00040000
#define BNX2_PORT_HW_CFG_IMD_MAC_A_UPPER 0x00000068
#define BNX2_PORT_HW_CFG_IMD_MAC_A_LOWER 0x0000006c
diff --git a/drivers/net/bnx2_fw.h b/drivers/net/bnx2_fw.h
index 35f3a2ae5ef1..ab07a4900e9a 100644
--- a/drivers/net/bnx2_fw.h
+++ b/drivers/net/bnx2_fw.h
@@ -14,24 +14,23 @@
* accompanying it.
*/
-
-static int bnx2_COM_b06FwReleaseMajor = 0x0;
+static int bnx2_COM_b06FwReleaseMajor = 0x1;
static int bnx2_COM_b06FwReleaseMinor = 0x0;
static int bnx2_COM_b06FwReleaseFix = 0x0;
-static u32 bnx2_COM_b06FwStartAddr = 0x080004a0;
+static u32 bnx2_COM_b06FwStartAddr = 0x080008b4;
static u32 bnx2_COM_b06FwTextAddr = 0x08000000;
-static int bnx2_COM_b06FwTextLen = 0x4594;
-static u32 bnx2_COM_b06FwDataAddr = 0x080045e0;
+static int bnx2_COM_b06FwTextLen = 0x57bc;
+static u32 bnx2_COM_b06FwDataAddr = 0x08005840;
static int bnx2_COM_b06FwDataLen = 0x0;
-static u32 bnx2_COM_b06FwRodataAddr = 0x08004598;
-static int bnx2_COM_b06FwRodataLen = 0x18;
-static u32 bnx2_COM_b06FwBssAddr = 0x08004600;
+static u32 bnx2_COM_b06FwRodataAddr = 0x080057c0;
+static int bnx2_COM_b06FwRodataLen = 0x58;
+static u32 bnx2_COM_b06FwBssAddr = 0x08005860;
static int bnx2_COM_b06FwBssLen = 0x88;
-static u32 bnx2_COM_b06FwSbssAddr = 0x080045e0;
+static u32 bnx2_COM_b06FwSbssAddr = 0x08005840;
static int bnx2_COM_b06FwSbssLen = 0x1c;
-static u32 bnx2_COM_b06FwText[(0x4594/4) + 1] = {
- 0x0a000128, 0x00000000, 0x00000000, 0x0000000d, 0x636f6d20, 0x302e362e,
- 0x39000000, 0x00060902, 0x00000000, 0x00000003, 0x00000014, 0x00000032,
+static u32 bnx2_COM_b06FwText[(0x57bc/4) + 1] = {
+ 0x0a00022d, 0x00000000, 0x00000000, 0x0000000d, 0x636f6d20, 0x322e352e,
+ 0x38000000, 0x02050802, 0x00000000, 0x00000003, 0x00000014, 0x00000032,
0x00000003, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000010, 0x000003e8, 0x0000ea60, 0x00000001, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
@@ -79,70 +78,117 @@ static u32 bnx2_COM_b06FwText[(0x4594/4) + 1] = {
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x10000003, 0x00000000, 0x0000000d,
- 0x0000000d, 0x3c020800, 0x244245e0, 0x3c030800, 0x24634688, 0xac400000,
- 0x0043202b, 0x1480fffd, 0x24420004, 0x3c1d0800, 0x37bd7ffc, 0x03a0f021,
- 0x3c100800, 0x261004a0, 0x3c1c0800, 0x279c45e0, 0x0e0001f2, 0x00000000,
- 0x0000000d, 0x27bdffe8, 0x3c1a8000, 0x3c020008, 0x0342d825, 0x3c036010,
- 0xafbf0010, 0x8c655000, 0x3c020800, 0x24470ac8, 0x3c040800, 0x24864600,
- 0x2402ff7f, 0x00a22824, 0x34a5380c, 0xac655000, 0x00002821, 0x24020037,
- 0x24030c80, 0xaf420008, 0xaf430024, 0xacc70000, 0x24a50001, 0x2ca20016,
- 0x1440fffc, 0x24c60004, 0x24844600, 0x3c020800, 0x24420ad4, 0x3c030800,
- 0x246309d4, 0xac820004, 0x3c020800, 0x24420618, 0x3c050800, 0x24a50ca0,
- 0xac82000c, 0x3c020800, 0x24423100, 0xac830008, 0x3c030800, 0x246325c8,
- 0xac820014, 0x3c020800, 0x24422b0c, 0xac830018, 0xac83001c, 0x3c030800,
- 0x24630adc, 0xac820024, 0x3c020800, 0x24423040, 0xac83002c, 0x3c030800,
- 0x24633060, 0xac820030, 0x3c020800, 0x24422f6c, 0xac830034, 0x3c030800,
- 0x24632c60, 0xac82003c, 0x3c020800, 0x24420b6c, 0xac850010, 0xac850020,
- 0xac830040, 0x0e000bd6, 0xac820050, 0x8fbf0010, 0x03e00008, 0x27bd0018,
- 0x27bdffe0, 0xafb00010, 0x27500100, 0xafbf0018, 0xafb10014, 0x9203000b,
- 0x24020003, 0x1462005b, 0x96110008, 0x32220001, 0x10400009, 0x27430080,
- 0x8e020000, 0x96040014, 0x000211c2, 0x00021040, 0x00621821, 0xa4640000,
- 0x0a0001cb, 0x3c020800, 0x3c020800, 0x8c430020, 0x1060002a, 0x3c030800,
- 0x0e001006, 0x00000000, 0x97420108, 0x8f850018, 0x9743010c, 0x3042003e,
- 0x00021400, 0x00621825, 0xaca30000, 0x8f840018, 0x8f420100, 0xac820004,
- 0x97430116, 0x9742010e, 0x8f840018, 0x00031c00, 0x00431025, 0xac820008,
- 0x97430110, 0x97440112, 0x8f850018, 0x00031c00, 0x00832025, 0xaca4000c,
- 0x97420114, 0x8f840018, 0x3042ffff, 0xac820010, 0x8f830018, 0xac600014,
- 0x8f820018, 0x3c030800, 0xac400018, 0x9462466e, 0x8f840018, 0x3c032000,
- 0x00431025, 0xac82001c, 0x0e001044, 0x24040001, 0x3c030800, 0x8c620040,
- 0x24420001, 0xac620040, 0x3c020800, 0x8c430044, 0x32240004, 0x24630001,
- 0x10800017, 0xac430044, 0x8f4202b8, 0x04430007, 0x8e020020, 0x3c040800,
- 0x8c830060, 0x24020001, 0x24630001, 0x0a0001ed, 0xac830060, 0x3c060800,
- 0x8cc4005c, 0xaf420280, 0x96030016, 0x00001021, 0xa7430284, 0x8e050004,
- 0x24840001, 0x3c031000, 0xaf450288, 0xaf4302b8, 0x0a0001ed, 0xacc4005c,
- 0x32220002, 0x0a0001ed, 0x0002102b, 0x3c026000, 0xac400808, 0x0000000d,
- 0x00001021, 0x8fbf0018, 0x8fb10014, 0x8fb00010, 0x03e00008, 0x27bd0020,
- 0x27bdffc8, 0xafbf0034, 0xafbe0030, 0xafb7002c, 0xafb60028, 0xafb50024,
- 0xafb40020, 0xafb3001c, 0xafb20018, 0xafb10014, 0x0e00013f, 0xafb00010,
- 0x24110020, 0x24150030, 0x2794000c, 0x27930008, 0x3c124000, 0x3c1e0800,
- 0x3c170800, 0x3c160800, 0x8f820004, 0x3c040800, 0x8c830020, 0x10430004,
- 0x00000000, 0xaf830004, 0x0e00110b, 0x00000000, 0x8f500000, 0x32020007,
- 0x1040fff5, 0x32020001, 0x1040002b, 0x32020002, 0x8f420100, 0xaf420020,
- 0x8f430104, 0xaf4300a8, 0x9342010b, 0x93630000, 0x306300ff, 0x10710005,
- 0x304400ff, 0x10750006, 0x2c820016, 0x0a000227, 0x00000000, 0xaf940000,
- 0x0a000228, 0x2c820016, 0xaf930000, 0x0a000228, 0x00000000, 0xaf800000,
- 0x14400005, 0x00041880, 0x0e0002b2, 0x00000000, 0x0a000234, 0x00000000,
- 0x3c020800, 0x24424600, 0x00621821, 0x8c620000, 0x0040f809, 0x00000000,
- 0x10400005, 0x8fc20034, 0x8f420104, 0x3c016020, 0xac220014, 0x8fc20034,
- 0xaf520138, 0x24420001, 0xafc20034, 0x32020002, 0x10400019, 0x32020004,
- 0x8f420140, 0xaf420020, 0x93630000, 0x306300ff, 0x10710005, 0x00000000,
- 0x10750006, 0x00000000, 0x0a000250, 0x00000000, 0xaf940000, 0x0a000251,
- 0x00000000, 0xaf930000, 0x0a000251, 0x00000000, 0xaf800000, 0x0e0008b9,
- 0x00000000, 0x8ee20038, 0xaf520178, 0x24420001, 0xaee20038, 0x32020004,
- 0x1040ffad, 0x00000000, 0x8f420180, 0xaf420020, 0x93630000, 0x306300ff,
- 0x10710005, 0x00000000, 0x10750006, 0x00000000, 0x0a00026a, 0x00000000,
- 0xaf940000, 0x0a00026b, 0x00000000, 0xaf930000, 0x0a00026b, 0x00000000,
- 0xaf800000, 0x93620000, 0x14510004, 0x8ec2003c, 0x0e000835, 0x00000000,
- 0x8ec2003c, 0xaf5201b8, 0x24420001, 0x0a000206, 0xaec2003c, 0x27bdffe8,
- 0xafbf0010, 0x97420108, 0x24033000, 0x30447000, 0x10830012, 0x28823001,
- 0x10400007, 0x24024000, 0x1080000b, 0x24022000, 0x1082001a, 0x24020001,
- 0x0a000299, 0x00000000, 0x1082000c, 0x24025000, 0x1082000e, 0x00000000,
- 0x0a000299, 0x00000000, 0x0000000d, 0x0a00029b, 0x00001021, 0x0e000300,
- 0x00000000, 0x0a00029b, 0x00001021, 0x0e00048f, 0x00000000, 0x0a00029b,
- 0x00001021, 0x0e000fdf, 0x00000000, 0x0a00029b, 0x00001021, 0x0000000d,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x10000003, 0x00000000, 0x0000000d, 0x0000000d, 0x3c020800, 0x24425840,
+ 0x3c030800, 0x246358e8, 0xac400000, 0x0043202b, 0x1480fffd, 0x24420004,
+ 0x3c1d0800, 0x37bd7ffc, 0x03a0f021, 0x3c100800, 0x261008b4, 0x3c1c0800,
+ 0x279c5840, 0x0e0002f7, 0x00000000, 0x0000000d, 0x27bdffe8, 0x3c1a8000,
+ 0x3c020008, 0x0342d825, 0x3c036010, 0xafbf0010, 0x8c655000, 0x3c020800,
+ 0x24470f30, 0x3c040800, 0x24865860, 0x2402ff7f, 0x00a22824, 0x34a5380c,
+ 0xac655000, 0x00002821, 0x24020037, 0x24030c80, 0xaf420008, 0xaf430024,
+ 0xacc70000, 0x24a50001, 0x2ca20016, 0x1440fffc, 0x24c60004, 0x24845860,
+ 0x3c020800, 0x24420f3c, 0x3c030800, 0x24630e2c, 0xac820004, 0x3c020800,
+ 0x24420a2c, 0x3c050800, 0x24a51268, 0xac82000c, 0x3c020800, 0x244243dc,
+ 0xac830008, 0x3c030800, 0x24633698, 0xac820014, 0x3c020800, 0x24423c24,
+ 0xac830018, 0xac83001c, 0x3c030800, 0x24630f44, 0xac820024, 0x3c020800,
+ 0x244243ac, 0xac83002c, 0x3c030800, 0x246343cc, 0xac820030, 0x3c020800,
+ 0x244242f0, 0xac830034, 0x3c030800, 0x24633d78, 0xac82003c, 0x3c020800,
+ 0x24420fd4, 0xac850010, 0xac850020, 0xac830040, 0x0e0010b7, 0xac820050,
+ 0x8fbf0010, 0x03e00008, 0x27bd0018, 0x27bdffe0, 0xafb00010, 0x27500100,
+ 0xafbf0018, 0xafb10014, 0x9203000b, 0x24020003, 0x1462005b, 0x96110008,
+ 0x32220001, 0x10400009, 0x27430080, 0x8e020000, 0x96040014, 0x000211c2,
+ 0x00021040, 0x00621821, 0xa4640000, 0x0a0002d0, 0x3c020800, 0x3c020800,
+ 0x8c430020, 0x1060002a, 0x3c030800, 0x0e00148e, 0x00000000, 0x97420108,
+ 0x8f850018, 0x9743010c, 0x3042003e, 0x00021400, 0x00621825, 0xaca30000,
+ 0x8f840018, 0x8f420100, 0xac820004, 0x97430116, 0x9742010e, 0x8f840018,
+ 0x00031c00, 0x00431025, 0xac820008, 0x97430110, 0x97440112, 0x8f850018,
+ 0x00031c00, 0x00832025, 0xaca4000c, 0x97420114, 0x8f840018, 0x3042ffff,
+ 0xac820010, 0x8f830018, 0xac600014, 0x8f820018, 0x3c030800, 0xac400018,
+ 0x946258ce, 0x8f840018, 0x3c032000, 0x00431025, 0xac82001c, 0x0e0014cc,
+ 0x24040001, 0x3c030800, 0x8c620040, 0x24420001, 0xac620040, 0x3c020800,
+ 0x8c430044, 0x32240004, 0x24630001, 0x10800017, 0xac430044, 0x8f4202b8,
+ 0x04430007, 0x8e020020, 0x3c040800, 0x8c830060, 0x24020001, 0x24630001,
+ 0x0a0002f2, 0xac830060, 0x3c060800, 0x8cc4005c, 0xaf420280, 0x96030016,
+ 0x00001021, 0xa7430284, 0x8e050004, 0x24840001, 0x3c031000, 0xaf450288,
+ 0xaf4302b8, 0x0a0002f2, 0xacc4005c, 0x32220002, 0x0a0002f2, 0x0002102b,
+ 0x3c026000, 0xac400808, 0x0000000d, 0x00001021, 0x8fbf0018, 0x8fb10014,
+ 0x8fb00010, 0x03e00008, 0x27bd0020, 0x27bdffc8, 0xafbf0034, 0xafbe0030,
+ 0xafb7002c, 0xafb60028, 0xafb50024, 0xafb40020, 0xafb3001c, 0xafb20018,
+ 0xafb10014, 0x0e000244, 0xafb00010, 0x3c170800, 0x3c160800, 0x24110020,
+ 0x24150030, 0x2794000c, 0x27930008, 0x3c124000, 0x3c1e0800, 0x8f820004,
+ 0x3c040800, 0x8c830020, 0x10430005, 0x8ee200a4, 0xaf830004, 0x0e001593,
+ 0x00000000, 0x8ee200a4, 0x8ec300a0, 0x10430004, 0x26c400a0, 0x94820002,
+ 0xa742009e, 0xaee300a4, 0x8f500000, 0x32020007, 0x1040ffee, 0x32020001,
+ 0x1040002c, 0x32020002, 0x8f420100, 0xaf420020, 0x8f430104, 0xaf4300a8,
+ 0x9342010b, 0x93630000, 0x306300ff, 0x10710005, 0x304400ff, 0x10750006,
+ 0x2c820016, 0x0a000333, 0x00000000, 0xaf940000, 0x0a000334, 0x2c820016,
+ 0xaf930000, 0x0a000334, 0x00000000, 0xaf800000, 0x14400005, 0x00041880,
+ 0x0e0003cc, 0x00000000, 0x0a000340, 0x00000000, 0x3c020800, 0x24425860,
+ 0x00621821, 0x8c620000, 0x0040f809, 0x00000000, 0x10400005, 0x3c030800,
+ 0x8f420104, 0x3c016020, 0xac220014, 0x3c030800, 0x8c620034, 0xaf520138,
+ 0x24420001, 0xac620034, 0x32020002, 0x1040001a, 0x32020004, 0x8f420140,
+ 0xaf420020, 0x93630000, 0x306300ff, 0x10710005, 0x00000000, 0x10750006,
+ 0x00000000, 0x0a00035d, 0x00000000, 0xaf940000, 0x0a00035e, 0x00000000,
+ 0xaf930000, 0x0a00035e, 0x00000000, 0xaf800000, 0x0e000c7b, 0x00000000,
+ 0x3c040800, 0x8c820038, 0xaf520178, 0x24420001, 0xac820038, 0x32020004,
+ 0x1040ffa4, 0x00000000, 0x8f420180, 0xaf420020, 0x93630000, 0x306300ff,
+ 0x10710005, 0x00000000, 0x10750006, 0x00000000, 0x0a000378, 0x00000000,
+ 0xaf940000, 0x0a000379, 0x00000000, 0xaf930000, 0x0a000379, 0x00000000,
+ 0xaf800000, 0x8f430180, 0x24020f00, 0x14620005, 0x00000000, 0x8f420188,
+ 0xa742009c, 0x0a000387, 0x8fc2003c, 0x93620000, 0x14510004, 0x8fc2003c,
+ 0x0e000bad, 0x00000000, 0x8fc2003c, 0xaf5201b8, 0x24420001, 0x0a00030b,
+ 0xafc2003c, 0x27bdffe8, 0xafbf0010, 0x97420108, 0x24033000, 0x30447000,
+ 0x10830016, 0x28823001, 0x10400007, 0x24024000, 0x1080000b, 0x24022000,
+ 0x1082000c, 0x00000000, 0x0a0003b3, 0x00000000, 0x10820010, 0x24025000,
+ 0x10820012, 0x00000000, 0x0a0003b3, 0x00000000, 0x0000000d, 0x0a0003b5,
+ 0x00001021, 0x0e000442, 0x00000000, 0x0a0003b6, 0x8fbf0010, 0x0e00041a,
+ 0x00000000, 0x0a0003b5, 0x00001021, 0x0e000669, 0x00000000, 0x0a0003b5,
+ 0x00001021, 0x0e001467, 0x00000000, 0x0a0003b5, 0x00001021, 0x0000000d,
0x00001021, 0x8fbf0010, 0x03e00008, 0x27bd0018, 0x93620000, 0x24030020,
- 0x304400ff, 0x10830005, 0x24020030, 0x10820007, 0x00000000, 0x0a0002af,
+ 0x304400ff, 0x10830005, 0x24020030, 0x10820007, 0x00000000, 0x0a0003c9,
0x00000000, 0x2782000c, 0xaf820000, 0x03e00008, 0x00000000, 0x27820008,
0xaf820000, 0x03e00008, 0x00000000, 0xaf800000, 0x03e00008, 0x00000000,
0x0000000d, 0x03e00008, 0x00001021, 0x03e00008, 0x00001021, 0x27440100,
@@ -159,1000 +205,1716 @@ static u32 bnx2_COM_b06FwText[(0x4594/4) + 1] = {
0x3c020006, 0x34420001, 0xaf420030, 0x00000000, 0x00000000, 0x00000000,
0x8f420000, 0x30420010, 0x1040fffd, 0x00001021, 0x03e00008, 0x00000000,
0x3c020800, 0x8c430020, 0x27bdffe8, 0xafb00010, 0x27500100, 0x1060001e,
- 0xafbf0014, 0x0e001006, 0x00000000, 0x8f830018, 0x8e020018, 0xac620000,
+ 0xafbf0014, 0x0e00148e, 0x00000000, 0x8f830018, 0x8e020018, 0xac620000,
0x8f840018, 0x9602000c, 0xac820004, 0x8f830018, 0xac600008, 0x8f820018,
0xac40000c, 0x8f830018, 0xac600010, 0x8f820018, 0xac400014, 0x8f840018,
- 0x3c026000, 0x8c434448, 0xac830018, 0x96020008, 0x3c030800, 0x9464466e,
- 0x8f850018, 0x00021400, 0x00441025, 0x24040001, 0x0e001044, 0xaca2001c,
- 0x8fbf0014, 0x8fb00010, 0x03e00008, 0x27bd0018, 0x27bdffc8, 0xafb3001c,
- 0x00009821, 0xafb7002c, 0x0000b821, 0xafbe0030, 0x0000f021, 0xafb50024,
- 0x27550100, 0xafbf0034, 0xafb60028, 0xafb40020, 0xafb20018, 0xafb10014,
- 0xafb00010, 0x96a20008, 0x8f540100, 0x8eb20018, 0x30420001, 0x10400037,
- 0x02a0b021, 0x8f630054, 0x2642ffff, 0x00431023, 0x18400006, 0x00000000,
- 0x0000000d, 0x00000000, 0x24000128, 0x0a000372, 0x00002021, 0x8f62004c,
- 0x02421023, 0x18400028, 0x00002021, 0x93650120, 0x93640121, 0x3c030800,
- 0x8c62008c, 0x308400ff, 0x24420001, 0x30a500ff, 0x00803821, 0x1485000b,
- 0xac62008c, 0x3c040800, 0x8c830090, 0x24630001, 0xac830090, 0x93620122,
- 0x30420001, 0x00021023, 0x30420005, 0x0a000372, 0x34440004, 0x27660100,
- 0x00041080, 0x00c21021, 0x8c430000, 0x02431823, 0x04600004, 0x24820001,
- 0x30440007, 0x1485fff9, 0x00041080, 0x10870007, 0x3c030800, 0xa3640121,
- 0x8c620094, 0x24040005, 0x24420001, 0x0a000372, 0xac620094, 0x24040004,
- 0x00809821, 0x9362003f, 0x304400ff, 0x38830016, 0x2c630001, 0x38820010,
- 0x2c420001, 0x00621825, 0x1460000c, 0x24020001, 0x38830008, 0x2c630001,
- 0x38820014, 0x2c420001, 0x00621825, 0x14600005, 0x24020001, 0x24020012,
- 0x14820002, 0x00001021, 0x24020001, 0x50400007, 0x8eb10020, 0x8ea20020,
- 0x8f630040, 0x00408821, 0x00431023, 0x5c400001, 0x8f710040, 0x9343010b,
- 0x24020004, 0x54620005, 0x36730080, 0x96a20008, 0x36730002, 0x24170001,
- 0x305e0020, 0x2402fffb, 0x02628024, 0x1200002a, 0x3c030800, 0x8c620030,
- 0x02021024, 0x10400026, 0x3c020800, 0x8c430020, 0x10600024, 0x32620004,
- 0x0e001006, 0x00000000, 0x8f830018, 0x8f420100, 0xac620000, 0x8f840018,
- 0x02201821, 0x32620002, 0xac900004, 0x8f840018, 0x50400001, 0x8ec30014,
- 0xac830008, 0x8f830018, 0x8ec20020, 0xac62000c, 0x8f840018, 0x8f620040,
- 0xac820010, 0x8f830018, 0x8ec20018, 0xac620014, 0x8f840018, 0x3c026000,
- 0x8c434448, 0x3c020800, 0xac830018, 0x9443466e, 0x8f840018, 0x3c024010,
- 0x00621825, 0xac83001c, 0x0e001044, 0x24040001, 0x32620004, 0x10400076,
- 0x00003821, 0x3c029000, 0x34420001, 0x3c038000, 0x02821025, 0xa360007c,
- 0xaf420020, 0x8f420020, 0x00431024, 0x1440fffd, 0x00000000, 0x93620023,
- 0x30420080, 0x10400011, 0x00000000, 0x8f65005c, 0x8f63004c, 0x9764003c,
- 0x8f620064, 0x00a32823, 0x00852821, 0x00a2102b, 0x54400006, 0x3c023fff,
- 0x93620023, 0x3042007f, 0xa3620023, 0xaf720064, 0x3c023fff, 0x0a0003f1,
- 0x3442ffff, 0x8f62005c, 0x02421023, 0x04400011, 0x00000000, 0x8f65005c,
- 0x8f630064, 0x9764003c, 0x3c023fff, 0x3442ffff, 0xaf720064, 0x00a32823,
- 0x00852821, 0x0045102b, 0x10400004, 0x02451021, 0x3c053fff, 0x34a5ffff,
- 0x02451021, 0xaf62005c, 0x24070001, 0xaf72004c, 0x8f620054, 0x16420005,
+ 0x3c026000, 0x8c434448, 0xac830018, 0x96020008, 0x3c030800, 0x946458ce,
+ 0x8f850018, 0x00021400, 0x00441025, 0x24040001, 0x0e0014cc, 0xaca2001c,
+ 0x8fbf0014, 0x8fb00010, 0x03e00008, 0x27bd0018, 0x27bdffe8, 0xafb00010,
+ 0x27500100, 0xafbf0014, 0x92020009, 0x14400003, 0x3c020800, 0x0a00046c,
+ 0x24020001, 0x8c430020, 0x1060001f, 0x00001021, 0x0e00148e, 0x00000000,
+ 0x8f830018, 0x8e020018, 0xac620000, 0x8f840018, 0x9602000c, 0xac820004,
+ 0x8f830018, 0xac600008, 0x8f820018, 0xac40000c, 0x8f830018, 0xac600010,
+ 0x8f820018, 0xac400014, 0x8f840018, 0x3c026000, 0x8c434448, 0xac830018,
+ 0x96020008, 0x3c030800, 0x946458ce, 0x8f850018, 0x00021400, 0x00441025,
+ 0x24040001, 0x0e0014cc, 0xaca2001c, 0x00001021, 0x8fbf0014, 0x8fb00010,
+ 0x03e00008, 0x27bd0018, 0x3c0b0800, 0x8d6808b0, 0x3c070800, 0x24e700b0,
+ 0x00084900, 0x01271821, 0xac640000, 0x93620005, 0x97660008, 0x00e95021,
+ 0x93630023, 0x9364003f, 0x25080001, 0x00021600, 0x00063400, 0x00461025,
+ 0x00031a00, 0x00431025, 0x00822025, 0xad440004, 0x9362007e, 0x9366007f,
+ 0x8f630178, 0x9364007a, 0x00021600, 0x00063400, 0x00461025, 0x00031a00,
+ 0x00431025, 0x00822025, 0xad440008, 0x93620080, 0x9363007d, 0x3108007f,
+ 0x01403821, 0xad6808b0, 0x00021600, 0x00031c00, 0x00431025, 0x00451025,
+ 0x03e00008, 0xace2000c, 0x27bdffb8, 0xafb3002c, 0x00009821, 0xafbe0040,
+ 0x0000f021, 0xafb50034, 0x27550100, 0xafbf0044, 0xafb7003c, 0xafb60038,
+ 0xafb40030, 0xafb20028, 0xafb10024, 0xafb00020, 0xafa00010, 0xafa00014,
+ 0x96a20008, 0x8f540100, 0x8eb10018, 0x30420001, 0x10400037, 0x02a0b821,
+ 0x8f630054, 0x2622ffff, 0x00431023, 0x18400006, 0x00000000, 0x0000000d,
+ 0x00000000, 0x2400015c, 0x0a0004e5, 0x00002021, 0x8f62004c, 0x02221023,
+ 0x18400028, 0x00002021, 0x93650120, 0x93640121, 0x3c030800, 0x8c62008c,
+ 0x308400ff, 0x24420001, 0x30a500ff, 0x00803821, 0x1485000b, 0xac62008c,
+ 0x3c040800, 0x8c830090, 0x24630001, 0xac830090, 0x93620122, 0x30420001,
+ 0x00021023, 0x30420005, 0x0a0004e5, 0x34440004, 0x27660100, 0x00041080,
+ 0x00c21021, 0x8c430000, 0x02231823, 0x04600004, 0x24820001, 0x30440007,
+ 0x1485fff9, 0x00041080, 0x10870007, 0x3c030800, 0xa3640121, 0x8c620094,
+ 0x24040005, 0x24420001, 0x0a0004e5, 0xac620094, 0x24040004, 0x00809821,
+ 0x9362003f, 0x304400ff, 0x38830016, 0x2c630001, 0x38820010, 0x2c420001,
+ 0x00621825, 0x1460000c, 0x24020001, 0x38830008, 0x2c630001, 0x38820014,
+ 0x2c420001, 0x00621825, 0x14600005, 0x24020001, 0x24020012, 0x14820002,
+ 0x00001021, 0x24020001, 0x10400009, 0x00000000, 0x8ea20020, 0x8f630040,
+ 0x0040b021, 0x00431023, 0x5c400010, 0x8f760040, 0x0a000511, 0x00000000,
+ 0x9343010b, 0x24020004, 0x1462000a, 0x8eb60020, 0x8f630040, 0x3c021000,
+ 0x00761823, 0x0043102a, 0x10400004, 0x00000000, 0x0000000d, 0x00000000,
+ 0x240002fa, 0x9343010b, 0x24020004, 0x5462000b, 0x96a20008, 0x24020001,
+ 0xafa20010, 0x96a20008, 0x24030001, 0xafa30018, 0x8eb2001c, 0x36730002,
+ 0x30420020, 0x0a000526, 0xafa20014, 0x36730080, 0x30420002, 0x10400003,
+ 0xafa00018, 0x0a000526, 0x8eb2001c, 0x8eb20014, 0x2402fffb, 0x02628024,
+ 0x1200002a, 0x3c030800, 0x8c620030, 0x02021024, 0x10400026, 0x3c020800,
+ 0x8c430020, 0x10600024, 0x32620004, 0x0e00148e, 0x00000000, 0x8f830018,
+ 0x8f420100, 0xac620000, 0x8f840018, 0x02401821, 0x32620002, 0xac900004,
+ 0x8f840018, 0x54400001, 0x02c01821, 0xac830008, 0x8f830018, 0x8ee20020,
+ 0xac62000c, 0x8f840018, 0x8f620040, 0xac820010, 0x8f830018, 0x8ee20018,
+ 0xac620014, 0x8f850018, 0x3c026000, 0x8c434448, 0x24040001, 0x3c020800,
+ 0xaca30018, 0x944358ce, 0x8f850018, 0x3c024010, 0x00621825, 0x0e0014cc,
+ 0xaca3001c, 0x32620004, 0x10400063, 0x00003821, 0x3c029000, 0x34420001,
+ 0x3c038000, 0x02821025, 0xa360007c, 0xaf420020, 0x8f420020, 0x00431024,
+ 0x1440fffd, 0x00000000, 0x93620023, 0x30420080, 0x10400011, 0x00000000,
+ 0x8f65005c, 0x8f63004c, 0x9764003c, 0x8f620064, 0x00a32823, 0x00852821,
+ 0x00a2102b, 0x54400006, 0x3c023fff, 0x93620023, 0x3042007f, 0xa3620023,
+ 0xaf710064, 0x3c023fff, 0x0a000580, 0x3442ffff, 0x8f62005c, 0x02221023,
+ 0x04400011, 0x00000000, 0x8f65005c, 0x8f630064, 0x9764003c, 0x3c023fff,
+ 0x3442ffff, 0xaf710064, 0x00a32823, 0x00852821, 0x0045102b, 0x10400004,
+ 0x02251021, 0x3c053fff, 0x34a5ffff, 0x02251021, 0xaf62005c, 0x24070001,
+ 0xaf71004c, 0x8f620054, 0x16220005, 0x00000000, 0x93620023, 0x30420040,
+ 0x10400017, 0x24020001, 0x9762006a, 0x00022880, 0x50a00001, 0x24050001,
+ 0x97630068, 0x93640081, 0x3c020800, 0x8c46004c, 0x00652821, 0x00852804,
+ 0x00c5102b, 0x54400001, 0x00a03021, 0x3c020800, 0x8c440050, 0x00c4182b,
+ 0x54600001, 0x00c02021, 0x8f420074, 0x2403fffe, 0x00832824, 0x00a21021,
+ 0xaf62000c, 0x93620082, 0x30420080, 0x50400001, 0xa3600081, 0x3c028000,
+ 0x34420001, 0x02821025, 0xaf420020, 0x9363007e, 0x9362007a, 0x10620004,
+ 0x00000000, 0x0e0013c4, 0x00000000, 0x00403821, 0x54e00001, 0x241e0001,
+ 0x8f700040, 0x8f620040, 0x14520003, 0x00521023, 0x0a0005bf, 0x00001021,
+ 0x28420001, 0x10400041, 0x8fa20010, 0x0e000fae, 0x02402021, 0xaf720040,
+ 0x9362003e, 0x30420001, 0x1440000b, 0x3c029000, 0x93620022, 0x24420001,
+ 0xa3620022, 0x93630022, 0x3c020800, 0x8c440098, 0x0064182b, 0x14600027,
+ 0x3c020800, 0x3c029000, 0x34420001, 0x02821025, 0xaf420020, 0x3c038000,
+ 0x8f420020, 0x00431024, 0x1440fffd, 0x00000000, 0x9362007d, 0x3c038000,
+ 0x34420001, 0xa362007d, 0x8f640074, 0x34630001, 0x02831825, 0xaf430020,
+ 0x04810006, 0x3c038000, 0x02802021, 0x0e000470, 0x24050273, 0x0a0005f2,
+ 0x24050001, 0x8f4201f8, 0x00431024, 0x1440fffd, 0x24020002, 0x3c031000,
+ 0xaf5401c0, 0xa34201c4, 0xaf4301f8, 0x24050001, 0x24020001, 0xa7620012,
+ 0xa3600022, 0x0a0005fe, 0x2ca20001, 0x9743007a, 0x9444002a, 0x00002821,
+ 0x00641821, 0x3063fffe, 0xa7630012, 0x2ca20001, 0x00021023, 0x03c2f024,
+ 0x8fa20010, 0x10400004, 0x8fa30014, 0x0e0013c1, 0x00000000, 0x8fa30014,
+ 0x10600003, 0x00000000, 0x0e0010eb, 0x00000000, 0x13c0001f, 0x3c029000,
+ 0x34420001, 0x02821025, 0xaf420020, 0x3c038000, 0x8f420020, 0x00431024,
+ 0x1440fffd, 0x00000000, 0x9362007d, 0x3c038000, 0xa362007d, 0x8f640074,
+ 0x34630001, 0x02831825, 0xaf430020, 0x04810006, 0x3c038000, 0x02802021,
+ 0x0e000470, 0x2405036c, 0x0a00062b, 0x8fa20018, 0x8f4201f8, 0x00431024,
+ 0x1440fffd, 0x24020002, 0x3c031000, 0xaf5401c0, 0xa34201c4, 0xaf4301f8,
+ 0x8fa20018, 0x5040002f, 0x96a20008, 0x8f620048, 0x8f630024, 0x00761821,
+ 0xaf630048, 0x9764003c, 0x00501023, 0x0044102b, 0x10400025, 0x3c029000,
+ 0x34420001, 0x3c040800, 0x8c830080, 0x8f450100, 0x3c068000, 0x24630001,
+ 0x00a21025, 0xac830080, 0xaf420020, 0x8f420020, 0x00461024, 0x1440fffd,
+ 0x00000000, 0x9362007d, 0x3c038000, 0x34420004, 0xa362007d, 0x8f640074,
+ 0x34630001, 0x00a31825, 0xaf430020, 0x04810006, 0x3c038000, 0x00a02021,
+ 0x0e000470, 0x2405038a, 0x0a00065b, 0x96a20008, 0x8f4201f8, 0x00431024,
+ 0x1440fffd, 0x24020002, 0x3c031000, 0xaf4501c0, 0xa34201c4, 0xaf4301f8,
+ 0x96a20008, 0x8fbf0044, 0x8fbe0040, 0x8fb7003c, 0x8fb60038, 0x8fb50034,
+ 0x8fb40030, 0x8fb3002c, 0x8fb20028, 0x8fb10024, 0x8fb00020, 0x00021042,
+ 0x30420001, 0x03e00008, 0x27bd0048, 0x27bdffe0, 0xafbf0018, 0x97420108,
+ 0x24030019, 0x304400ff, 0x10830065, 0x2882001a, 0x1040001a, 0x2882000a,
+ 0x1040000f, 0x28820008, 0x10400040, 0x24020001, 0x1082003a, 0x28820002,
+ 0x50400005, 0x24020006, 0x10800032, 0x3c026000, 0x0a0006fb, 0x00000000,
+ 0x1082003d, 0x00000000, 0x0a0006fb, 0x00000000, 0x2402000b, 0x10820044,
+ 0x2882000b, 0x1440004b, 0x2402000e, 0x10820045, 0x00000000, 0x0a0006fb,
+ 0x00000000, 0x24020020, 0x10820062, 0x28820021, 0x1040000e, 0x2402001c,
+ 0x1082004c, 0x2882001d, 0x10400005, 0x2402001b, 0x10820043, 0x00000000,
+ 0x0a0006fb, 0x00000000, 0x2402001f, 0x10820050, 0x00000000, 0x0a0006fb,
+ 0x00000000, 0x240200c1, 0x10820042, 0x288200c2, 0x10400005, 0x24020080,
+ 0x10820021, 0x00000000, 0x0a0006fb, 0x00000000, 0x240200c2, 0x1082003d,
+ 0x240200c9, 0x50820049, 0xafa00010, 0x0a0006fb, 0x00000000, 0x0e001163,
+ 0xac400808, 0x0a0006fd, 0x8fbf0018, 0x3c026000, 0x8c444448, 0x3c030800,
+ 0xac640064, 0x0e001163, 0x00000000, 0x3c026000, 0x8c444448, 0x3c030800,
+ 0x0a0006fc, 0xac640068, 0x8f440100, 0x0e0006ff, 0x00000000, 0x3c026000,
+ 0x8c444448, 0x3c030800, 0x0a0006fc, 0xac64006c, 0x0e001191, 0x00000000,
+ 0x0a0006fd, 0x8fbf0018, 0x8f440100, 0x0e0011bb, 0x00000000, 0x0a0006fd,
+ 0x8fbf0018, 0x0e001202, 0x00000000, 0x0a0006fd, 0x8fbf0018, 0x0000000d,
+ 0x0a0006fd, 0x8fbf0018, 0x0e000826, 0x00000000, 0x0a0006fd, 0x8fbf0018,
+ 0x8f440100, 0x0e001264, 0x00000000, 0x0a0006fd, 0x8fbf0018, 0x0e00134e,
+ 0x00000000, 0x0a0006fd, 0x8fbf0018, 0x0e00087c, 0x27440100, 0x0a0006fd,
+ 0x8fbf0018, 0x8f640040, 0x0e000fae, 0x00000000, 0x0a0006fd, 0x8fbf0018,
+ 0x8f440100, 0x0e001059, 0x00000000, 0x0a0006fd, 0x8fbf0018, 0x0e001417,
+ 0x00000000, 0x0a0006fd, 0x8fbf0018, 0xafa00014, 0x8f440100, 0x8f450118,
+ 0x8f46011c, 0x0e001439, 0x8f470120, 0x0a0006fd, 0x8fbf0018, 0x0000000d,
+ 0x8fbf0018, 0x03e00008, 0x27bd0020, 0x27bdffe8, 0xafbf0010, 0x9742010c,
+ 0x1440005e, 0x00803821, 0x3c029000, 0x34420001, 0x00e21025, 0xaf420020,
+ 0x3c038000, 0x8f420020, 0x00431024, 0x1440fffd, 0x00000000, 0x93620023,
+ 0x30420010, 0x14400026, 0x3c030800, 0x8f630074, 0x3c027fff, 0x3442ffff,
+ 0x00621824, 0xaf630074, 0x93620005, 0x34420001, 0xa3620005, 0x8f63004c,
+ 0x8f620054, 0x10620021, 0x24040001, 0x9762006a, 0x00022880, 0x50a00001,
+ 0x24050001, 0x97630068, 0x93640081, 0x3c020800, 0x8c46004c, 0x00652821,
+ 0x00852804, 0x00c5102b, 0x54400001, 0x00a03021, 0x3c020800, 0x8c440050,
+ 0x00c4182b, 0x54600001, 0x00c02021, 0x8f420074, 0x2403fffe, 0x00832824,
+ 0x00a21021, 0xaf62000c, 0x0a00073d, 0x24040001, 0x8c6200a8, 0x00002021,
+ 0x24420001, 0xac6200a8, 0x0000000d, 0x00000000, 0x2400044d, 0x3c028000,
+ 0x34420001, 0x00e21025, 0xaf420020, 0x1080001f, 0x3c029000, 0x34420001,
+ 0x00e21025, 0xaf420020, 0x3c038000, 0x8f420020, 0x00431024, 0x1440fffd,
+ 0x00000000, 0x9362007d, 0x3c038000, 0xa362007d, 0x8f640074, 0x34630001,
+ 0x00e31825, 0xaf430020, 0x04810006, 0x3c038000, 0x00e02021, 0x0e000470,
+ 0x24050455, 0x0a000761, 0x00000000, 0x8f4201f8, 0x00431024, 0x1440fffd,
+ 0x24020002, 0x3c031000, 0xaf4701c0, 0xa34201c4, 0xaf4301f8, 0x0e001163,
+ 0x00000000, 0x8fbf0010, 0x03e00008, 0x27bd0018, 0x27bdffd8, 0xafbf0024,
+ 0xafb40020, 0xafb3001c, 0xafb20018, 0xafb10014, 0xafb00010, 0x93630005,
+ 0x00809821, 0x24020030, 0x30630030, 0x146200ac, 0x00a0a021, 0x3c020800,
+ 0x8c430020, 0x106000a6, 0x00000000, 0x0e00148e, 0x00000000, 0x8f830018,
+ 0xac730000, 0x936200c4, 0x30420002, 0x10400004, 0x24020001, 0x8f830018,
+ 0x0a000784, 0x00000000, 0x8f830018, 0x24020003, 0xac620004, 0x8f6200dc,
+ 0x8f630040, 0x00431023, 0x18400004, 0x00000000, 0x0000000d, 0x00000000,
+ 0x24000509, 0x8f840018, 0x8f6200dc, 0xac820008, 0x8f830018, 0xac60000c,
+ 0x8f820018, 0xac400010, 0x8f830018, 0x8f62004c, 0x3c100800, 0xac620014,
+ 0x8f850018, 0x3c026000, 0x8c434448, 0x261258c0, 0x00002021, 0xaca30018,
+ 0x9642000e, 0x8f850018, 0x3c034010, 0x00431025, 0x0e0014cc, 0xaca2001c,
+ 0x8f830018, 0xac730000, 0x9362003e, 0x9363003f, 0x8f840018, 0x00021200,
+ 0x00621825, 0xac830004, 0x93620081, 0x93630082, 0x8f840018, 0x00021600,
+ 0x00031c00, 0x00431025, 0xac820008, 0x8f830018, 0x8f620040, 0xac62000c,
+ 0x8f840018, 0x8f620048, 0xac820010, 0x8f71004c, 0x8f820018, 0xac510014,
+ 0x8f620050, 0x8f850018, 0x00401821, 0x02221023, 0x5c400001, 0x02201821,
+ 0x00002021, 0xaca30018, 0x9642000e, 0x8f850018, 0x3c03c00b, 0x00431025,
+ 0x0e0014cc, 0xaca2001c, 0x8f620054, 0x8f840018, 0x00401821, 0x02221023,
+ 0x5c400001, 0x02201821, 0xac830000, 0x8f840018, 0x8f630058, 0xac830004,
+ 0x93620023, 0x30420010, 0x10400004, 0x00000000, 0x8f830018, 0x0a0007dd,
+ 0x8f620148, 0x8f830018, 0x8f62005c, 0xac620008, 0x8f830018, 0x8f620060,
+ 0xac62000c, 0x8f840018, 0x8f620064, 0xac820010, 0x97630068, 0x9762006a,
+ 0x8f840018, 0x00031c00, 0x00431025, 0xac820014, 0x8f850018, 0x00002021,
+ 0x2402ffff, 0x260358c0, 0xaca20018, 0x9462000e, 0x8f850018, 0x3c03c00c,
+ 0x00431025, 0x0e0014cc, 0xaca2001c, 0x8f840018, 0x8f630018, 0xac830000,
+ 0x936200c4, 0x30420002, 0x10400006, 0x00000000, 0x976200c8, 0x8f830018,
+ 0x3042ffff, 0x0a000803, 0xac620004, 0x8f820018, 0xac400004, 0x8f830018,
+ 0x8f62006c, 0xac620008, 0x8f840018, 0x8f6200dc, 0xac82000c, 0x8f830018,
+ 0xac600010, 0x93620005, 0x8f830018, 0x00021600, 0x00541025, 0xac620014,
+ 0x8f850018, 0x3c026000, 0x8c434448, 0x24040001, 0x260258c0, 0xaca30018,
+ 0x9443000e, 0x8f850018, 0x3c02400d, 0x00621825, 0x0e0014cc, 0xaca3001c,
+ 0x0e00122e, 0x02602021, 0x8fbf0024, 0x8fb40020, 0x8fb3001c, 0x8fb20018,
+ 0x8fb10014, 0x8fb00010, 0x03e00008, 0x27bd0028, 0x27bdffe0, 0xafb00010,
+ 0x27500100, 0xafbf0018, 0xafb10014, 0x9603000c, 0x240200c1, 0x54620024,
+ 0x8e040000, 0x3c029000, 0x8f450100, 0x34420001, 0x3c038000, 0x00a21025,
+ 0xaf420020, 0x8f420020, 0x00431024, 0x1440fffd, 0x00000000, 0x9362007d,
+ 0x3c038000, 0x34420004, 0xa362007d, 0x8f640074, 0x34630001, 0x00a31825,
+ 0xaf430020, 0x04810006, 0x3c038000, 0x00a02021, 0x0e000470, 0x240505b2,
+ 0x0a000878, 0x8fbf0018, 0x8f4201f8, 0x00431024, 0x1440fffd, 0x24020002,
+ 0x3c031000, 0xaf4501c0, 0xa34201c4, 0xaf4301f8, 0x0a000878, 0x8fbf0018,
+ 0x8f65004c, 0x24060001, 0x0e0012a3, 0x240705be, 0x3c020800, 0x8c430020,
+ 0x9611000c, 0x1060001d, 0x8e100000, 0x0e00148e, 0x00000000, 0x8f820018,
+ 0xac500000, 0x8f840018, 0x00111400, 0xac820004, 0x8f830018, 0xac600008,
+ 0x8f820018, 0xac40000c, 0x8f830018, 0xac600010, 0x8f840018, 0x240205c1,
+ 0xac820014, 0x8f850018, 0x3c026000, 0x8c434448, 0x24040001, 0x3c020800,
+ 0xaca30018, 0x944358ce, 0x8f850018, 0x3c024019, 0x00621825, 0x0e0014cc,
+ 0xaca3001c, 0x8fbf0018, 0x8fb10014, 0x8fb00010, 0x03e00008, 0x27bd0020,
+ 0x27bdffb0, 0xafb5003c, 0x0000a821, 0xafbe0048, 0x0000f021, 0xafb70044,
+ 0x0000b821, 0xafb30034, 0x00009821, 0xafb60040, 0x0080b021, 0xafbf004c,
+ 0xafb40038, 0xafb20030, 0xafb1002c, 0xafb00028, 0xafa00010, 0x8f620040,
+ 0x8ec30014, 0x96d1000c, 0x00431023, 0x04410025, 0x8ed40000, 0x32220401,
+ 0x1040030c, 0x3c029000, 0x34420001, 0x02821025, 0xaf420020, 0x3c038000,
+ 0x8f420020, 0x00431024, 0x1440fffd, 0x00000000, 0x9362007d, 0x3c038000,
+ 0x34420004, 0xa362007d, 0x8f640074, 0x34630001, 0x02831825, 0xaf430020,
+ 0x04810006, 0x3c038000, 0x02802021, 0x0e000470, 0x24050664, 0x0a000ba2,
+ 0x8fbf004c, 0x8f4201f8, 0x00431024, 0x1440fffd, 0x24020002, 0x3c031000,
+ 0xaf5401c0, 0xa34201c4, 0xaf4301f8, 0x0a000ba2, 0x8fbf004c, 0x32220010,
+ 0x1040006b, 0x00003021, 0x9362003f, 0x92c6000f, 0x304500ff, 0x24c3fff8,
+ 0x2c62000f, 0x10400057, 0x3c020800, 0x244257c0, 0x00031880, 0x00621821,
+ 0x8c640000, 0x00800008, 0x00000000, 0x38a20012, 0x0a000924, 0x0002a82b,
+ 0x2402000e, 0x14a20004, 0x2402000c, 0x24150001, 0x0a000924, 0x24060010,
+ 0x10a20049, 0x38a30010, 0x2c630001, 0x38a20016, 0x2c420001, 0x00621825,
+ 0x1460004d, 0x0000a821, 0x24020014, 0x10a2004a, 0x00000000, 0x0000000d,
+ 0x00000000, 0x2400069c, 0x0a000924, 0x0000a821, 0x24020016, 0x14a20005,
+ 0x2402000c, 0x24150001, 0x24060010, 0x0a000924, 0x3231fffd, 0x10a20032,
+ 0x38a30010, 0x2c630001, 0x38a2000e, 0x2c420001, 0x00621825, 0x14600036,
+ 0x0000a821, 0x24020014, 0x14a20003, 0x24150001, 0x0a000924, 0x24060012,
+ 0x0000000d, 0x00000000, 0x240006bc, 0x0a000924, 0x0000a821, 0x2402000e,
+ 0x14a20004, 0x24020016, 0x24150001, 0x0a000924, 0x3231fffb, 0x14a20004,
+ 0x24020014, 0x24150001, 0x0a000924, 0x3231fffd, 0x54a20013, 0x92c2000e,
+ 0x24150001, 0x24060012, 0x0a000924, 0x3231fffd, 0x2402000c, 0x54a2000c,
+ 0x92c2000e, 0x92c3000e, 0x2402000a, 0x10620005, 0x24150001, 0x0000000d,
+ 0x00000000, 0x240006e8, 0x24150001, 0x0a000924, 0x24060014, 0x92c2000e,
+ 0x14a20003, 0x00000000, 0x0a000924, 0x24150001, 0x10a6ffc1, 0x24020012,
+ 0x10a20005, 0x0000a821, 0x0000000d, 0x00000000, 0x24000704, 0x0000a821,
+ 0x12a00022, 0x32220004, 0x10400002, 0x24020001, 0xafa20010, 0x32230102,
+ 0x24020002, 0x1462000f, 0x00000000, 0x92c2000a, 0x30420020, 0x1440000b,
+ 0x00000000, 0x8f630048, 0x8f620040, 0x14620004, 0x00000000, 0x8f620048,
+ 0x24420001, 0xaf620048, 0x8f620040, 0x24420001, 0xaf620040, 0xa366003f,
+ 0x38c30012, 0x2c630001, 0x38c20010, 0x2c420001, 0x00621825, 0x10600005,
+ 0x3c030800, 0x8c620074, 0x24420001, 0x0e00140d, 0xac620074, 0x32220040,
+ 0x32230020, 0xafa30020, 0x32230080, 0xafa30024, 0x32230001, 0xafa30018,
+ 0x32230008, 0xafa3001c, 0x32230100, 0x104000c4, 0xafa30014, 0x8ec60010,
+ 0x8f630054, 0x24c2ffff, 0x00431023, 0x18400006, 0x00000000, 0x0000000d,
+ 0x00000000, 0x2400015c, 0x0a000989, 0x00009021, 0x8f62004c, 0x00c21023,
+ 0x18400028, 0x00009021, 0x93650120, 0x93640121, 0x3c030800, 0x8c62008c,
+ 0x308400ff, 0x24420001, 0x30a500ff, 0x00804021, 0x1485000b, 0xac62008c,
+ 0x3c040800, 0x8c830090, 0x24630001, 0xac830090, 0x93620122, 0x30420001,
+ 0x00021023, 0x30420005, 0x0a000989, 0x34520004, 0x27670100, 0x00041080,
+ 0x00e21021, 0x8c430000, 0x00c31823, 0x04600004, 0x24820001, 0x30440007,
+ 0x1485fff9, 0x00041080, 0x10880007, 0x3c030800, 0xa3640121, 0x8c620094,
+ 0x24120005, 0x24420001, 0x0a000989, 0xac620094, 0x24120004, 0x32420001,
+ 0x10400021, 0x3c020800, 0x8c430020, 0x8ed00000, 0x1060001c, 0x8ed30010,
+ 0x0e00148e, 0x00000000, 0x8f820018, 0xac500000, 0x8f840018, 0x24020001,
+ 0xac820004, 0x8f830018, 0xac600008, 0x8f820018, 0xac40000c, 0x8f830018,
+ 0xac600010, 0x8f820018, 0xac530014, 0x8f850018, 0x3c026000, 0x8c434448,
+ 0x24040001, 0x3c020800, 0xaca30018, 0x944358ce, 0x8f850018, 0x3c024010,
+ 0x00621825, 0x0e0014cc, 0xaca3001c, 0x24130001, 0x32420004, 0x10400068,
+ 0x00003821, 0x3c029000, 0x8ec60010, 0x34420001, 0x3c038000, 0x02821025,
+ 0xa360007c, 0xaf420020, 0x8f420020, 0x00431024, 0x1440fffd, 0x00000000,
+ 0x93620023, 0x30420080, 0x10400011, 0x00000000, 0x8f65005c, 0x8f63004c,
+ 0x9764003c, 0x8f620064, 0x00a32823, 0x00852821, 0x00a2102b, 0x54400006,
+ 0x3c023fff, 0x93620023, 0x3042007f, 0xa3620023, 0xaf660064, 0x3c023fff,
+ 0x0a0009da, 0x3442ffff, 0x8f62005c, 0x00c21023, 0x04400011, 0x00000000,
+ 0x8f65005c, 0x8f630064, 0x9764003c, 0x3c023fff, 0x3442ffff, 0xaf660064,
+ 0x00a32823, 0x00852821, 0x0045102b, 0x10400004, 0x00c51021, 0x3c053fff,
+ 0x34a5ffff, 0x00c51021, 0xaf62005c, 0x24070001, 0xaf66004c, 0x8fa20010,
+ 0x10400003, 0x00000000, 0xaf660050, 0xaf660054, 0x8f620054, 0x14c20005,
0x00000000, 0x93620023, 0x30420040, 0x10400017, 0x24020001, 0x9762006a,
0x00022880, 0x50a00001, 0x24050001, 0x97630068, 0x93640081, 0x3c020800,
0x8c46004c, 0x00652821, 0x00852804, 0x00c5102b, 0x54400001, 0x00a03021,
0x3c020800, 0x8c440050, 0x00c4182b, 0x54600001, 0x00c02021, 0x8f420074,
- 0x2403fffe, 0x00832824, 0x00a21021, 0xaf62000c, 0x3c028000, 0x34420001,
- 0x02821025, 0xa3600081, 0xaf420020, 0x9363007e, 0x9362007a, 0x10620004,
- 0x00000000, 0x0e000f2a, 0x00000000, 0x00403821, 0x10e00017, 0x3c029000,
+ 0x2403fffe, 0x00832824, 0x00a21021, 0xaf62000c, 0x93620082, 0x30420080,
+ 0x50400001, 0xa3600081, 0x3c028000, 0x34420001, 0x02821025, 0xaf420020,
+ 0x9363007e, 0x9362007a, 0x10620005, 0x00e0b821, 0x0e0013c4, 0x00000000,
+ 0x00403821, 0x00e0b821, 0x8fa30020, 0x10600009, 0x8fa20010, 0x8ec20018,
+ 0xaf620018, 0x8ec3001c, 0xaf63001c, 0x8ec20020, 0x24170001, 0xaf620058,
+ 0x8fa20010, 0x10400057, 0x8fa30024, 0x93620023, 0x30420040, 0x10400053,
+ 0x00000000, 0x16600021, 0x3c120800, 0x8e420020, 0x8f70004c, 0x1040001e,
+ 0x24130001, 0x0e00148e, 0x00000000, 0x8f820018, 0xac540000, 0x8f840018,
+ 0x24020001, 0xac820004, 0x8f830018, 0xac600008, 0x8f820018, 0xac40000c,
+ 0x8f830018, 0xac600010, 0x8f820018, 0xac500014, 0x8f850018, 0x3c026000,
+ 0x8c434448, 0x24040001, 0x3c020800, 0xaca30018, 0x944358ce, 0x8f850018,
+ 0x3c024010, 0x00621825, 0xaca3001c, 0x0e0014cc, 0x24130001, 0x8e420020,
+ 0x1040001c, 0x8ed00000, 0x0e00148e, 0x00000000, 0x8f820018, 0xac500000,
+ 0x8f830018, 0xac600004, 0x8f820018, 0xac400008, 0x8f830018, 0xac60000c,
+ 0x8f820018, 0xac400010, 0x8f830018, 0x24020798, 0xac620014, 0x8f850018,
+ 0x3c026000, 0x8c434448, 0x24040001, 0x3c020800, 0xaca30018, 0x944358ce,
+ 0x8f850018, 0x3c024019, 0x00621825, 0x0e0014cc, 0xaca3001c, 0x3c029000,
0x34420001, 0x02821025, 0xaf420020, 0x3c038000, 0x8f420020, 0x00431024,
- 0x1440fffd, 0x3c028000, 0x9363007d, 0x34420001, 0x3c048000, 0x02821025,
- 0xa363007d, 0xaf420020, 0x8f4201f8, 0x00441024, 0x1440fffd, 0x24020002,
- 0x3c031000, 0xaf5401c0, 0xa34201c4, 0xaf4301f8, 0x8ea30014, 0x8f620040,
- 0x14430003, 0x00431023, 0x0a000443, 0x00001021, 0x28420001, 0x10400034,
- 0x00000000, 0x8f620040, 0xaf630040, 0x9362003e, 0x30420001, 0x1440000b,
- 0x3c029000, 0x93620022, 0x24420001, 0xa3620022, 0x93630022, 0x3c020800,
- 0x8c440098, 0x0064182b, 0x1460001e, 0x3c020800, 0x3c029000, 0x34420001,
+ 0x1440fffd, 0x24020001, 0xaf62000c, 0x93630023, 0x3c028000, 0x34420001,
+ 0x02821025, 0x306300bf, 0xa3630023, 0xaf420020, 0x8fa30024, 0x10600012,
+ 0x8fa30018, 0x9362007c, 0x24420001, 0xa362007c, 0x9363007e, 0x9362007a,
+ 0x1462000b, 0x8fa30018, 0x9362007c, 0x3c030800, 0x8c640024, 0x0044102b,
+ 0x14400005, 0x8fa30018, 0x0e0013c4, 0x00000000, 0x02e2b825, 0x8fa30018,
+ 0x3062ffff, 0x10400003, 0x32220200, 0x0a000a94, 0x241e0004, 0x10400003,
+ 0x00000000, 0x241e0040, 0x24170001, 0x12a000d0, 0x32220002, 0x104000cf,
+ 0x8fa2001c, 0x92c2000a, 0x30420002, 0x5040003b, 0x92c2000a, 0x93620023,
+ 0x30420008, 0x54400037, 0x92c2000a, 0x3c020800, 0x8c430020, 0x10600023,
+ 0x3c029000, 0x0e00148e, 0x00000000, 0x8f840018, 0x8ec30000, 0xac830000,
+ 0x92c2000a, 0x8f830018, 0x00021600, 0xac620004, 0x8f840018, 0x8f620040,
+ 0xac820008, 0x8f850018, 0x8f63004c, 0xaca3000c, 0x9362003f, 0x8f840018,
+ 0x304200ff, 0xac820010, 0x8f830018, 0x3c026000, 0xac600014, 0x8f850018,
+ 0x8c434448, 0x24040001, 0x3c020800, 0xaca30018, 0x944358ce, 0x8f850018,
+ 0x3c02401a, 0x00621825, 0x0e0014cc, 0xaca3001c, 0x3c029000, 0x34420001,
0x02821025, 0xaf420020, 0x3c038000, 0x8f420020, 0x00431024, 0x1440fffd,
- 0x00000000, 0x3c038000, 0x9362007d, 0x34630001, 0x3c048000, 0x02831825,
- 0x34420001, 0xa362007d, 0xaf430020, 0x8f4201f8, 0x00441024, 0x1440fffd,
- 0x24020002, 0x3c031000, 0xaf5401c0, 0xa34201c4, 0x24020001, 0xaf4301f8,
- 0xa7620012, 0x0a000476, 0xa3600022, 0x9743007a, 0x9444002a, 0x00641821,
- 0x3063fffe, 0xa7630012, 0x0e000b68, 0x00000000, 0x12e00003, 0x00000000,
- 0x0e000f27, 0x00000000, 0x53c00004, 0x96a20008, 0x0e000c10, 0x00000000,
- 0x96a20008, 0x8fbf0034, 0x8fbe0030, 0x8fb7002c, 0x8fb60028, 0x8fb50024,
- 0x8fb40020, 0x8fb3001c, 0x8fb20018, 0x8fb10014, 0x8fb00010, 0x00021042,
- 0x30420001, 0x03e00008, 0x27bd0038, 0x27bdffe8, 0xafbf0010, 0x97420108,
- 0x2403000b, 0x304400ff, 0x1083004e, 0x2882000c, 0x10400011, 0x24020006,
- 0x1082003e, 0x28820007, 0x10400007, 0x28820008, 0x1080002b, 0x24020001,
- 0x1082002e, 0x3c026000, 0x0a000504, 0x00000000, 0x14400061, 0x2882000a,
- 0x1440002b, 0x00000000, 0x0a0004ec, 0x00000000, 0x2402001c, 0x1082004e,
- 0x2882001d, 0x1040000e, 0x24020019, 0x10820041, 0x2882001a, 0x10400005,
- 0x2402000e, 0x10820036, 0x00000000, 0x0a000504, 0x00000000, 0x2402001b,
- 0x1082003c, 0x00000000, 0x0a000504, 0x00000000, 0x240200c1, 0x10820040,
- 0x288200c2, 0x10400005, 0x24020080, 0x1082001f, 0x00000000, 0x0a000504,
- 0x00000000, 0x240200c2, 0x1082003b, 0x00000000, 0x0a000504, 0x00000000,
- 0x3c026000, 0x0e000c7d, 0xac400808, 0x0a000506, 0x8fbf0010, 0x8c444448,
- 0x3c030800, 0xac640064, 0x0e000c7d, 0x00000000, 0x3c026000, 0x8c444448,
- 0x3c030800, 0x0a000505, 0xac640068, 0x8f440100, 0x0e000508, 0x00000000,
- 0x3c026000, 0x8c444448, 0x3c030800, 0x0a000505, 0xac64006c, 0x0e000cab,
- 0x00000000, 0x0a000506, 0x8fbf0010, 0x8f440100, 0x0e000cd5, 0x00000000,
- 0x0a000506, 0x8fbf0010, 0x0e000d1c, 0x00000000, 0x0a000506, 0x8fbf0010,
- 0x0000000d, 0x0a000506, 0x8fbf0010, 0x0e0005d7, 0x00000000, 0x0a000506,
- 0x8fbf0010, 0x8f440100, 0x0e000d7e, 0x00000000, 0x0a000506, 0x8fbf0010,
- 0x0e000e95, 0x00000000, 0x0a000506, 0x8fbf0010, 0x0e000626, 0x00000000,
- 0x0a000506, 0x8fbf0010, 0x0e000b68, 0x00000000, 0x0a000506, 0x8fbf0010,
- 0x0000000d, 0x8fbf0010, 0x03e00008, 0x27bd0018, 0x27bdffe8, 0x3c029000,
- 0x34420001, 0xafb00010, 0x00808021, 0x02021025, 0x3c038000, 0xafbf0014,
- 0xaf420020, 0x8f420020, 0x00431024, 0x1440fffd, 0x00000000, 0x93620005,
- 0x34420001, 0xa3620005, 0x8f63004c, 0x8f620054, 0x10620019, 0x3c028000,
- 0x9762006a, 0x00022880, 0x50a00001, 0x24050001, 0x97630068, 0x93640081,
- 0x3c020800, 0x8c46004c, 0x00652821, 0x00852804, 0x00c5102b, 0x54400001,
- 0x00a03021, 0x3c020800, 0x8c440050, 0x00c4182b, 0x54600001, 0x00c02021,
- 0x8f420074, 0x2403fffe, 0x00832824, 0x00a21021, 0xaf62000c, 0x3c028000,
- 0x34420001, 0x02021025, 0x0e000c7d, 0xaf420020, 0x3c029000, 0x34420001,
- 0x3c038000, 0x02021025, 0xaf420020, 0x8f420020, 0x00431024, 0x1440fffd,
- 0x3c028000, 0x9363007d, 0x34420001, 0x3c048000, 0x02021025, 0xa363007d,
- 0xaf420020, 0x8f4201f8, 0x00441024, 0x1440fffd, 0x8fbf0014, 0xaf5001c0,
- 0x8fb00010, 0x24020002, 0x3c031000, 0xa34201c4, 0xaf4301f8, 0x03e00008,
- 0x27bd0018, 0x27bdffd8, 0xafbf0020, 0xafb3001c, 0xafb20018, 0xafb10014,
- 0xafb00010, 0x93630005, 0x00809021, 0x24020030, 0x30630030, 0x14620072,
- 0x00a09821, 0x3c020800, 0x8c430020, 0x1060006c, 0x00000000, 0x0e001006,
- 0x00000000, 0x8f820018, 0xac520000, 0x9363003e, 0x9362003f, 0x8f840018,
- 0x00031a00, 0x00431025, 0xac820004, 0x93630081, 0x93620082, 0x8f850018,
- 0x00031e00, 0x00021400, 0x00621825, 0xaca30008, 0x8f840018, 0x8f620040,
- 0xac82000c, 0x8f830018, 0x8f620048, 0xac620010, 0x8f840018, 0x8f62004c,
- 0x3c110800, 0xac820014, 0x8f830018, 0x8f620050, 0x26304660, 0x00002021,
- 0xac620018, 0x9602000e, 0x8f850018, 0x3c03c00b, 0x00431025, 0x0e001044,
- 0xaca2001c, 0x8f830018, 0x8f620054, 0xac620000, 0x8f840018, 0x8f620058,
- 0xac820004, 0x8f830018, 0x8f62005c, 0xac620008, 0x8f840018, 0x8f620060,
- 0xac82000c, 0x8f850018, 0x8f620064, 0xaca20010, 0x97630068, 0x9762006a,
- 0x8f840018, 0x00031c00, 0x00431025, 0xac820014, 0x8f830018, 0x00002021,
- 0xac600018, 0x9602000e, 0x8f850018, 0x3c03c00c, 0x00431025, 0x0e001044,
- 0xaca2001c, 0x8f840018, 0x8f630018, 0xac830000, 0x936200c4, 0x30420002,
- 0x10400006, 0x00000000, 0x976200c8, 0x8f830018, 0x3042ffff, 0x0a0005b5,
- 0xac620004, 0x8f820018, 0xac400004, 0x8f830018, 0x8f62006c, 0xac620008,
- 0x8f840018, 0x8f6200dc, 0xac82000c, 0x8f830018, 0xac600010, 0x93620005,
- 0x8f830018, 0x00021600, 0x00531025, 0xac620014, 0x8f850018, 0x3c026000,
- 0x8c434448, 0x24040001, 0x26224660, 0xaca30018, 0x9443000e, 0x8f850018,
- 0x3c02400d, 0x00621825, 0x0e001044, 0xaca3001c, 0x0e000d48, 0x02402021,
- 0x8fbf0020, 0x8fb3001c, 0x8fb20018, 0x8fb10014, 0x8fb00010, 0x03e00008,
- 0x27bd0028, 0x27bdffe0, 0xafb00010, 0x27500100, 0xafbf0018, 0xafb10014,
- 0x9603000c, 0x240200c1, 0x5462001d, 0x8e040000, 0x3c029000, 0x8f440100,
- 0x34420001, 0x3c038000, 0x00821025, 0xaf420020, 0x8f420020, 0x00431024,
- 0x1440fffd, 0x00000000, 0x3c038000, 0x9362007d, 0x34630001, 0x3c058000,
- 0x00831825, 0x34420004, 0xa362007d, 0xaf430020, 0x8f4201f8, 0x00451024,
- 0x1440fffd, 0x24020002, 0x3c031000, 0xaf4401c0, 0xa34201c4, 0xaf4301f8,
- 0x0a000622, 0x8fbf0018, 0x8f65004c, 0x24060001, 0x0e000db5, 0x2407049f,
- 0x3c020800, 0x8c430020, 0x9611000c, 0x1060001d, 0x8e100000, 0x0e001006,
- 0x00000000, 0x8f820018, 0xac500000, 0x8f840018, 0x00111400, 0xac820004,
- 0x8f830018, 0xac600008, 0x8f820018, 0xac40000c, 0x8f830018, 0xac600010,
- 0x8f840018, 0x240204a2, 0xac820014, 0x8f850018, 0x3c026000, 0x8c434448,
- 0x24040001, 0x3c020800, 0xaca30018, 0x9443466e, 0x8f850018, 0x3c024019,
- 0x00621825, 0x0e001044, 0xaca3001c, 0x8fbf0018, 0x8fb10014, 0x8fb00010,
- 0x03e00008, 0x27bd0020, 0x27bdffb0, 0xafb1002c, 0x27510100, 0xafbf004c,
- 0xafbe0048, 0xafb70044, 0xafb60040, 0xafb5003c, 0xafb40038, 0xafb30034,
- 0xafb20030, 0xafb00028, 0x8e350000, 0x9634000c, 0x3c026000, 0x8c434448,
- 0x0000f021, 0xaf630170, 0x8f620040, 0x8e230014, 0x0000b821, 0x00431023,
- 0x044001ec, 0x0000b021, 0x32820010, 0x1040002e, 0x3c026000, 0x9363003f,
- 0x9222000e, 0x10430006, 0x2402000c, 0x9223000f, 0x10620003, 0x24020014,
- 0x14620025, 0x3c026000, 0x32820004, 0x10400007, 0x241e0001, 0x8f620050,
- 0x24420001, 0xaf620050, 0x8f630054, 0x24630001, 0xaf630054, 0x32830102,
- 0x24020002, 0x5462000d, 0x9222000f, 0x8f620040, 0x24420001, 0xaf620040,
- 0x8f630048, 0x8f620040, 0x24630001, 0x54620005, 0x9222000f, 0x8f620048,
- 0x24420001, 0xaf620048, 0x9222000f, 0xa362003f, 0x9223000f, 0x24020012,
- 0x14620007, 0x3c026000, 0x3c030800, 0x8c620074, 0x24420001, 0x0e000f6e,
- 0xac620074, 0x3c026000, 0x8c434448, 0x32820040, 0xaf630174, 0x32830020,
- 0xafa30010, 0x32830080, 0xafa30014, 0x32830001, 0xafa3001c, 0x32830008,
- 0xafa30020, 0x32830100, 0x104000bb, 0xafa30018, 0x8e260010, 0x8f630054,
- 0x24c2ffff, 0x00431023, 0x18400006, 0x00000000, 0x0000000d, 0x00000000,
- 0x24000128, 0x0a0006b2, 0x00009021, 0x8f62004c, 0x00c21023, 0x18400028,
- 0x00009021, 0x93650120, 0x93640121, 0x3c030800, 0x8c62008c, 0x308400ff,
- 0x24420001, 0x30a500ff, 0x00804021, 0x1485000b, 0xac62008c, 0x3c040800,
- 0x8c830090, 0x24630001, 0xac830090, 0x93620122, 0x30420001, 0x00021023,
- 0x30420005, 0x0a0006b2, 0x34520004, 0x27670100, 0x00041080, 0x00e21021,
- 0x8c430000, 0x00c31823, 0x04600004, 0x24820001, 0x30440007, 0x1485fff9,
- 0x00041080, 0x10880007, 0x3c030800, 0xa3640121, 0x8c620094, 0x24120005,
- 0x24420001, 0x0a0006b2, 0xac620094, 0x24120004, 0x32420001, 0x10400020,
- 0x3c020800, 0x8c430020, 0x8e300000, 0x1060001c, 0x8e330010, 0x0e001006,
- 0x00000000, 0x8f820018, 0xac500000, 0x8f840018, 0x24020001, 0xac820004,
- 0x8f830018, 0xac600008, 0x8f820018, 0xac40000c, 0x8f830018, 0xac600010,
- 0x8f820018, 0xac530014, 0x8f850018, 0x3c026000, 0x8c434448, 0x24040001,
- 0x3c020800, 0xaca30018, 0x9443466e, 0x8f850018, 0x3c024010, 0x00621825,
- 0x0e001044, 0xaca3001c, 0x32420004, 0x10400060, 0x00003821, 0x3c029000,
- 0x8e260010, 0x34420001, 0x3c038000, 0x02a21025, 0xa360007c, 0xaf420020,
- 0x8f420020, 0x00431024, 0x1440fffd, 0x00000000, 0x93620023, 0x30420080,
- 0x10400011, 0x00000000, 0x8f65005c, 0x8f63004c, 0x9764003c, 0x8f620064,
- 0x00a32823, 0x00852821, 0x00a2102b, 0x54400006, 0x3c023fff, 0x93620023,
- 0x3042007f, 0xa3620023, 0xaf660064, 0x3c023fff, 0x0a000702, 0x3442ffff,
- 0x8f62005c, 0x00c21023, 0x04400011, 0x00000000, 0x8f65005c, 0x8f630064,
- 0x9764003c, 0x3c023fff, 0x3442ffff, 0xaf660064, 0x00a32823, 0x00852821,
- 0x0045102b, 0x10400004, 0x00c51021, 0x3c053fff, 0x34a5ffff, 0x00c51021,
- 0xaf62005c, 0x24070001, 0xaf66004c, 0x8f620054, 0x14c20005, 0x00000000,
- 0x93620023, 0x30420040, 0x10400017, 0x24020001, 0x9762006a, 0x00022880,
- 0x50a00001, 0x24050001, 0x97630068, 0x93640081, 0x3c020800, 0x8c46004c,
- 0x00652821, 0x00852804, 0x00c5102b, 0x54400001, 0x00a03021, 0x3c020800,
- 0x8c440050, 0x00c4182b, 0x54600001, 0x00c02021, 0x8f420074, 0x2403fffe,
- 0x00832824, 0x00a21021, 0xaf62000c, 0x3c028000, 0x34420001, 0x02a21025,
- 0xa3600081, 0xaf420020, 0x9363007e, 0x9362007a, 0x10620005, 0x00e0b021,
- 0x0e000f2a, 0x00000000, 0x00403821, 0x00e0b021, 0x8fa20010, 0x10400008,
- 0x00000000, 0x8e220018, 0xaf620018, 0x8e23001c, 0xaf63001c, 0x8e220020,
- 0x24160001, 0xaf620058, 0x13c00036, 0x32820004, 0x10400035, 0x8fa30014,
- 0x93620023, 0x30420040, 0x10400031, 0x3c020800, 0x8c430020, 0x1060001c,
- 0x8e300000, 0x0e001006, 0x00000000, 0x8f820018, 0xac500000, 0x8f830018,
- 0xac600004, 0x8f820018, 0xac400008, 0x8f830018, 0xac60000c, 0x8f820018,
- 0xac400010, 0x8f830018, 0x24020587, 0xac620014, 0x8f850018, 0x3c026000,
- 0x8c434448, 0x24040001, 0x3c020800, 0xaca30018, 0x9443466e, 0x8f850018,
- 0x3c024019, 0x00621825, 0x0e001044, 0xaca3001c, 0x3c029000, 0x34420001,
- 0x02a21025, 0xaf420020, 0x3c038000, 0x8f420020, 0x00431024, 0x1440fffd,
- 0x24020001, 0xaf62000c, 0x93630023, 0x3c028000, 0x34420001, 0x02a21025,
- 0x306300bf, 0xa3630023, 0xaf420020, 0x8fa30014, 0x10600012, 0x8fa3001c,
- 0x9362007c, 0x24420001, 0xa362007c, 0x9363007e, 0x9362007a, 0x1462000b,
- 0x8fa3001c, 0x9362007c, 0x3c030800, 0x8c640024, 0x0044102b, 0x14400005,
- 0x8fa3001c, 0x0e000f2a, 0x00000000, 0x02c2b025, 0x8fa3001c, 0x3062ffff,
- 0x10400003, 0x32820200, 0x0a000793, 0x24170004, 0x10400003, 0x00000000,
- 0x24170040, 0x24160001, 0x13c0005d, 0x32820002, 0x1040005c, 0x8fa20020,
- 0x9222000a, 0x30420020, 0x10400033, 0x3c100800, 0x93620023, 0x30420040,
- 0x1040002f, 0x8e020020, 0x1040001e, 0x3c029000, 0x0e001006, 0x00000000,
- 0x8f820018, 0xac550000, 0x8f840018, 0x3c02008d, 0xac820004, 0x8f830018,
- 0xac600008, 0x8f820018, 0xac40000c, 0x8f830018, 0xac600010, 0x8f840018,
- 0x240205bf, 0xac820014, 0x8f850018, 0x3c026000, 0x8c434448, 0x24040001,
- 0x3c020800, 0xaca30018, 0x9443466e, 0x8f850018, 0x3c024019, 0x00621825,
- 0x0e001044, 0xaca3001c, 0x3c029000, 0x34420001, 0x02a21025, 0xaf420020,
- 0x3c038000, 0x8f420020, 0x00431024, 0x1440fffd, 0x00000000, 0x93630023,
- 0x3c028000, 0x34420001, 0x02a21025, 0x306300bf, 0xa3630023, 0xaf420020,
- 0x8e020020, 0x10400023, 0x8fa20020, 0x0e001006, 0x00000000, 0x8f840018,
- 0x8e230000, 0xac830000, 0x9222000a, 0x8f830018, 0x00021600, 0xac620004,
- 0x8f840018, 0x8f620040, 0xac820008, 0x8f850018, 0x8f63004c, 0xaca3000c,
- 0x9362003f, 0x8f840018, 0x304200ff, 0xac820010, 0x8f830018, 0x3c026000,
- 0xac600014, 0x8f850018, 0x8c434448, 0x24040001, 0x3c020800, 0xaca30018,
- 0x9443466e, 0x8f850018, 0x3c02401a, 0x00621825, 0x0e001044, 0xaca3001c,
- 0x8fa20020, 0x1040000e, 0x8fa20018, 0x9222000a, 0xa3620082, 0x56e00005,
- 0x36f70008, 0x8fa30018, 0x10600004, 0x00000000, 0x36f70008, 0x0a000801,
- 0x24160001, 0x0e000de1, 0x02a02021, 0x8fa20018, 0x10400003, 0x00000000,
- 0x36f70010, 0x24160001, 0x12c00019, 0x3c029000, 0x34420001, 0x02a21025,
- 0xaf420020, 0x3c038000, 0x8f420020, 0x00431024, 0x1440fffd, 0x00000000,
- 0x3c038000, 0x9362007d, 0x34630001, 0x3c048000, 0x02a31825, 0x02e21025,
- 0xa362007d, 0xaf430020, 0x8f4201f8, 0x00441024, 0x1440fffd, 0x24020002,
- 0x3c031000, 0xaf5501c0, 0xa34201c4, 0xaf4301f8, 0x9363003f, 0x24020012,
- 0x14620004, 0x3c026000, 0x0e000f6e, 0x00000000, 0x3c026000, 0x8c434448,
- 0xaf630178, 0x8fbf004c, 0x8fbe0048, 0x8fb70044, 0x8fb60040, 0x8fb5003c,
+ 0x00000000, 0x93630023, 0x3c028000, 0x34420001, 0x02821025, 0x34630008,
+ 0xa3630023, 0xaf420020, 0x92c2000a, 0x30420020, 0x1040008e, 0x8fa2001c,
+ 0x93620023, 0x30420001, 0x14400035, 0x3c020800, 0x8c430020, 0x10600023,
+ 0x3c029000, 0x0e00148e, 0x00000000, 0x8f840018, 0x8ec30000, 0xac830000,
+ 0x92c2000a, 0x8f830018, 0x00021600, 0xac620004, 0x8f840018, 0x8f620040,
+ 0xac820008, 0x8f850018, 0x8f63004c, 0xaca3000c, 0x9362003f, 0x8f840018,
+ 0x304200ff, 0xac820010, 0x8f830018, 0x3c026000, 0xac600014, 0x8f850018,
+ 0x8c434448, 0x24040001, 0x3c020800, 0xaca30018, 0x944358ce, 0x8f850018,
+ 0x3c02401a, 0x00621825, 0x0e0014cc, 0xaca3001c, 0x3c029000, 0x34420001,
+ 0x02821025, 0xaf420020, 0x3c038000, 0x8f420020, 0x00431024, 0x1440fffd,
+ 0x00000000, 0x93630023, 0x3c028000, 0x34420001, 0x02821025, 0x34630001,
+ 0xa3630023, 0xaf420020, 0x93620023, 0x30420040, 0x10400052, 0x8fa2001c,
+ 0x16600020, 0x3c120800, 0x8e420020, 0x8f70004c, 0x1040003c, 0x3c029000,
+ 0x0e00148e, 0x00000000, 0x8f820018, 0xac540000, 0x8f840018, 0x24020001,
+ 0xac820004, 0x8f830018, 0xac600008, 0x8f820018, 0xac40000c, 0x8f830018,
+ 0xac600010, 0x8f820018, 0xac500014, 0x8f850018, 0x3c026000, 0x8c434448,
+ 0x24040001, 0x3c020800, 0xaca30018, 0x944358ce, 0x8f850018, 0x3c024010,
+ 0x00621825, 0x0e0014cc, 0xaca3001c, 0x8e420020, 0x1040001e, 0x3c029000,
+ 0x0e00148e, 0x00000000, 0x8f820018, 0xac540000, 0x8f840018, 0x3c02008d,
+ 0xac820004, 0x8f830018, 0xac600008, 0x8f820018, 0xac40000c, 0x8f830018,
+ 0xac600010, 0x8f840018, 0x240207ee, 0xac820014, 0x8f850018, 0x3c026000,
+ 0x8c434448, 0x24040001, 0x3c020800, 0xaca30018, 0x944358ce, 0x8f850018,
+ 0x3c024019, 0x00621825, 0x0e0014cc, 0xaca3001c, 0x3c029000, 0x34420001,
+ 0x02821025, 0xaf420020, 0x3c038000, 0x8f420020, 0x00431024, 0x1440fffd,
+ 0x00000000, 0x93630023, 0x3c028000, 0x34420001, 0x02821025, 0x306300bf,
+ 0xa3630023, 0xaf420020, 0x8fa2001c, 0x1040000e, 0x8fa20014, 0x92c2000a,
+ 0xa3620082, 0x57c00005, 0x37de0008, 0x8fa30014, 0x10600004, 0x00000000,
+ 0x37de0008, 0x0a000b75, 0x24170001, 0x0e0012cf, 0x02802021, 0x8fa20014,
+ 0x10400003, 0x00000000, 0x37de0010, 0x24170001, 0x12e00020, 0x3c029000,
+ 0x34420001, 0x02821025, 0xaf420020, 0x3c038000, 0x8f420020, 0x00431024,
+ 0x1440fffd, 0x00000000, 0x9362007d, 0x3c038000, 0x03c21025, 0xa362007d,
+ 0x8f640074, 0x34630001, 0x02831825, 0xaf430020, 0x04810006, 0x3c038000,
+ 0x02802021, 0x0e000470, 0x2405082a, 0x0a000b9b, 0x00000000, 0x8f4201f8,
+ 0x00431024, 0x1440fffd, 0x24020002, 0x3c031000, 0xaf5401c0, 0xa34201c4,
+ 0xaf4301f8, 0x9363003f, 0x24020012, 0x14620004, 0x8fbf004c, 0x0e00140d,
+ 0x00000000, 0x8fbf004c, 0x8fbe0048, 0x8fb70044, 0x8fb60040, 0x8fb5003c,
0x8fb40038, 0x8fb30034, 0x8fb20030, 0x8fb1002c, 0x8fb00028, 0x03e00008,
0x27bd0050, 0x27bdffe8, 0xafbf0014, 0xafb00010, 0x8f500180, 0x97420184,
0x30420200, 0x14400015, 0x00000000, 0x8f430188, 0x3c02ff00, 0x00621824,
0x3c020200, 0x10620031, 0x0043102b, 0x14400007, 0x3c020300, 0x1060000b,
- 0x3c020100, 0x1062000d, 0x00000000, 0x0a0008b4, 0x00000000, 0x10620027,
- 0x3c020400, 0x1062003e, 0x02002021, 0x0a0008b4, 0x00000000, 0x0e000e1e,
- 0x02002021, 0x0a0008b6, 0x8fbf0014, 0x93620005, 0x30420020, 0x1440005e,
+ 0x3c020100, 0x1062000d, 0x00000000, 0x0a000c2c, 0x00000000, 0x10620027,
+ 0x3c020400, 0x1062003e, 0x02002021, 0x0a000c2c, 0x00000000, 0x0e000c31,
+ 0x02002021, 0x0a000c2e, 0x8fbf0014, 0x93620005, 0x30420020, 0x1440005e,
0x8fbf0014, 0x3c029000, 0x34420001, 0x02021025, 0xaf420020, 0x3c038000,
0x8f420020, 0x00431024, 0x1440fffd, 0x00000000, 0x93620005, 0x3c038000,
0x34630001, 0x02031825, 0x34420020, 0xa3620005, 0xaf430020, 0x93620005,
- 0x30420020, 0x14400003, 0x02002021, 0x0000000d, 0x02002021, 0x0e000553,
- 0x24055854, 0x0a0008b6, 0x8fbf0014, 0x93620005, 0x30420001, 0x1040003f,
+ 0x30420020, 0x14400003, 0x02002021, 0x0000000d, 0x02002021, 0x0e000766,
+ 0x24055854, 0x0a000c2e, 0x8fbf0014, 0x93620005, 0x30420001, 0x1040003f,
0x3c029000, 0x34420001, 0x02021025, 0xaf420020, 0x3c038000, 0x8f420020,
- 0x00431024, 0x1440fffd, 0x00000000, 0x93620005, 0x3c048000, 0x3c030800,
- 0x304200fe, 0xa3620005, 0x8c620020, 0x34840001, 0x02042025, 0xaf440020,
- 0x1040002d, 0x8fbf0014, 0x0a000894, 0x00000000, 0x00002821, 0x00003021,
- 0x0e000f78, 0x240706a4, 0x3c020800, 0x8c430020, 0x10600023, 0x8fbf0014,
- 0x0e001006, 0x00000000, 0x8f820018, 0xac500000, 0x93630082, 0x9362003f,
+ 0x00431024, 0x1440fffd, 0x00000000, 0x93620023, 0x34420004, 0xa3620023,
+ 0x93630005, 0x3c048000, 0x3c020800, 0x306300fe, 0xa3630005, 0x8c430020,
+ 0x34840001, 0x02042025, 0x0a000c0a, 0xaf440020, 0x00002821, 0x00003021,
+ 0x0e000fb1, 0x240708d9, 0x3c020800, 0x8c430020, 0x10600023, 0x8fbf0014,
+ 0x0e00148e, 0x00000000, 0x8f820018, 0xac500000, 0x93630082, 0x9362003f,
0x8f840018, 0x00031a00, 0x00431025, 0xac820004, 0x8f830018, 0xac600008,
0x8f820018, 0xac40000c, 0x8f830018, 0xac600010, 0x8f820018, 0xac400014,
0x8f850018, 0x3c026000, 0x8c434448, 0x24040001, 0x3c020800, 0xaca30018,
- 0x9443466e, 0x8f850018, 0x3c02400a, 0x00621825, 0x0e001044, 0xaca3001c,
- 0x0a0008b6, 0x8fbf0014, 0x0000000d, 0x8fbf0014, 0x8fb00010, 0x03e00008,
- 0x27bd0018, 0x27bdffe8, 0xafbf0010, 0x93420148, 0x2444ffff, 0x2c830005,
- 0x10600047, 0x3c020800, 0x24424598, 0x00041880, 0x00621821, 0x8c640000,
- 0x00800008, 0x00000000, 0x8f430144, 0x8f62000c, 0x14620006, 0x24020001,
- 0xaf62000c, 0x0e000909, 0x00000000, 0x0a000907, 0x8fbf0010, 0x8f62000c,
- 0x0a000900, 0x00000000, 0x97630010, 0x8f420144, 0x14430006, 0x24020001,
- 0xa7620010, 0x0e000eeb, 0x00000000, 0x0a000907, 0x8fbf0010, 0x97620010,
- 0x0a000900, 0x00000000, 0x97630012, 0x8f420144, 0x14430006, 0x24020001,
- 0xa7620012, 0x0e000f06, 0x00000000, 0x0a000907, 0x8fbf0010, 0x97620012,
- 0x0a000900, 0x00000000, 0x97630014, 0x8f420144, 0x14430006, 0x24020001,
- 0xa7620014, 0x0e000f21, 0x00000000, 0x0a000907, 0x8fbf0010, 0x97620014,
- 0x0a000900, 0x00000000, 0x97630016, 0x8f420144, 0x14430006, 0x24020001,
- 0xa7620016, 0x0e000f24, 0x00000000, 0x0a000907, 0x8fbf0010, 0x97620016,
- 0x14400006, 0x8fbf0010, 0x3c030800, 0x8c620070, 0x24420001, 0xac620070,
- 0x8fbf0010, 0x03e00008, 0x27bd0018, 0x27bdffe8, 0xafbf0010, 0x93620081,
- 0x3c030800, 0x8c640048, 0x0044102b, 0x14400028, 0x3c029000, 0x8f460140,
- 0x34420001, 0x3c038000, 0x00c21025, 0xaf420020, 0x8f420020, 0x00431024,
- 0x1440fffd, 0x3c048000, 0x34840001, 0x3c059000, 0x34a50001, 0x3c078000,
- 0x24020012, 0x24030080, 0x00c42025, 0x00c52825, 0xa362003f, 0xa3630082,
- 0xaf440020, 0xaf450020, 0x8f420020, 0x00471024, 0x1440fffd, 0x3c038000,
- 0x9362007d, 0x34630001, 0x3c048000, 0x00c31825, 0x34420020, 0xa362007d,
- 0xaf430020, 0x8f4201f8, 0x00441024, 0x1440fffd, 0x24020002, 0x3c031000,
- 0x0a00096d, 0xaf4601c0, 0x93620081, 0x24420001, 0x0e000f2a, 0xa3620081,
- 0x9763006a, 0x00032880, 0x14a00002, 0x00403821, 0x24050001, 0x97630068,
+ 0x944358ce, 0x8f850018, 0x3c02400a, 0x00621825, 0x0e0014cc, 0xaca3001c,
+ 0x0a000c2e, 0x8fbf0014, 0x0000000d, 0x8fbf0014, 0x8fb00010, 0x03e00008,
+ 0x27bd0018, 0x27bdffe8, 0xafbf0010, 0x8f420188, 0x00803021, 0x93640000,
+ 0x24030020, 0x00021402, 0x10830008, 0x304500ff, 0x3c036018, 0x8c625000,
+ 0x34420400, 0xac625000, 0x0000000d, 0x00000000, 0x24000955, 0x9363003f,
+ 0x24020012, 0x14620023, 0x3c029000, 0x34420001, 0x3c038000, 0x00c21025,
+ 0xaf650178, 0xa365007a, 0xaf420020, 0x8f420020, 0x00431024, 0x1440fffd,
+ 0x00000000, 0x9362007d, 0x3c038000, 0xa362007d, 0x8f640074, 0x34630001,
+ 0x00c31825, 0xaf430020, 0x04810006, 0x3c038000, 0x00c02021, 0x0e000470,
+ 0x24050963, 0x0a000c79, 0x8fbf0010, 0x8f4201f8, 0x00431024, 0x1440fffd,
+ 0x24020002, 0x3c031000, 0xaf4601c0, 0xa34201c4, 0xaf4301f8, 0x0a000c79,
+ 0x8fbf0010, 0x9362007e, 0x1445000e, 0x00000000, 0x8f620178, 0x1045000b,
+ 0x00000000, 0x8f820000, 0xaf650178, 0x8f660178, 0x8f440180, 0x8f65004c,
+ 0x8c430000, 0x0060f809, 0x30c600ff, 0x0a000c79, 0x8fbf0010, 0xaf650178,
+ 0x8fbf0010, 0x03e00008, 0x27bd0018, 0x27bdffe8, 0xafbf0010, 0x93630000,
+ 0x24020020, 0x10620005, 0x00000000, 0x93630000, 0x24020030, 0x1462004d,
+ 0x8fbf0010, 0x93420148, 0x2444ffff, 0x2c830005, 0x10600047, 0x3c020800,
+ 0x24425800, 0x00041880, 0x00621821, 0x8c640000, 0x00800008, 0x00000000,
+ 0x8f430144, 0x8f62000c, 0x14620006, 0x24020001, 0xaf62000c, 0x0e000d59,
+ 0x00000000, 0x0a000cd1, 0x8fbf0010, 0x8f62000c, 0x0a000cca, 0x00000000,
+ 0x97630010, 0x8f420144, 0x14430006, 0x24020001, 0xa7620010, 0x0e00137a,
+ 0x00000000, 0x0a000cd1, 0x8fbf0010, 0x97620010, 0x0a000cca, 0x00000000,
+ 0x97630012, 0x8f420144, 0x14430006, 0x24020001, 0xa7620012, 0x0e001395,
+ 0x00000000, 0x0a000cd1, 0x8fbf0010, 0x97620012, 0x0a000cca, 0x00000000,
+ 0x97630014, 0x8f420144, 0x14430006, 0x24020001, 0xa7620014, 0x0e0013bb,
+ 0x00000000, 0x0a000cd1, 0x8fbf0010, 0x97620014, 0x0a000cca, 0x00000000,
+ 0x97630016, 0x8f420144, 0x14430006, 0x24020001, 0xa7620016, 0x0e0013be,
+ 0x00000000, 0x0a000cd1, 0x8fbf0010, 0x97620016, 0x14400006, 0x8fbf0010,
+ 0x3c030800, 0x8c620070, 0x24420001, 0xac620070, 0x8fbf0010, 0x03e00008,
+ 0x27bd0018, 0x27bdffe0, 0x3c029000, 0xafbf001c, 0xafb20018, 0xafb10014,
+ 0xafb00010, 0x8f500140, 0x34420001, 0x3c038000, 0x02021025, 0xaf420020,
+ 0x8f420020, 0x00431024, 0x1440fffd, 0x24020012, 0x24030080, 0xa362003f,
+ 0xa3630082, 0x93620023, 0x30420040, 0x10400007, 0x00008821, 0x93620023,
+ 0x24110001, 0x304200bf, 0xa3620023, 0x0a000cf0, 0x3c028000, 0x3c028000,
+ 0x34420001, 0x3c039000, 0x34630001, 0x3c048000, 0x02021025, 0x02031825,
+ 0xaf420020, 0xaf430020, 0x8f420020, 0x00441024, 0x1440fffd, 0x00000000,
+ 0x9362007d, 0x3c038000, 0x34420020, 0xa362007d, 0x8f640074, 0x34630001,
+ 0x02031825, 0xaf430020, 0x04810006, 0x3c038000, 0x02002021, 0x0e000470,
+ 0x24050a63, 0x0a000d13, 0x00000000, 0x8f4201f8, 0x00431024, 0x1440fffd,
+ 0x24020002, 0x3c031000, 0xaf5001c0, 0xa34201c4, 0xaf4301f8, 0x1220003f,
+ 0x3c120800, 0x8e420020, 0x8f71004c, 0x1040003c, 0x8fbf001c, 0x0e00148e,
+ 0x00000000, 0x8f820018, 0xac500000, 0x8f840018, 0x24020001, 0xac820004,
+ 0x8f830018, 0xac600008, 0x8f820018, 0xac40000c, 0x8f830018, 0xac600010,
+ 0x8f820018, 0xac510014, 0x8f850018, 0x3c026000, 0x8c434448, 0x24040001,
+ 0x3c020800, 0xaca30018, 0x944358ce, 0x8f850018, 0x3c024010, 0x00621825,
+ 0x0e0014cc, 0xaca3001c, 0x8e420020, 0x1040001e, 0x8fbf001c, 0x0e00148e,
+ 0x00000000, 0x8f820018, 0xac500000, 0x8f840018, 0x3c02008d, 0xac820004,
+ 0x8f830018, 0xac600008, 0x8f820018, 0xac40000c, 0x8f830018, 0xac600010,
+ 0x8f840018, 0x24020a6a, 0xac820014, 0x8f850018, 0x3c026000, 0x8c434448,
+ 0x24040001, 0x3c020800, 0xaca30018, 0x944358ce, 0x8f850018, 0x3c024019,
+ 0x00621825, 0x0e0014cc, 0xaca3001c, 0x8fbf001c, 0x8fb20018, 0x8fb10014,
+ 0x8fb00010, 0x03e00008, 0x27bd0020, 0x27bdffe8, 0xafbf0010, 0x93620081,
+ 0x3c030800, 0x8c640048, 0x0044102b, 0x14400005, 0x00000000, 0x0e000cd3,
+ 0x00000000, 0x0a000da4, 0x8fbf0010, 0x93620081, 0x24420001, 0x0e0013c4,
+ 0xa3620081, 0x9763006a, 0x00032880, 0x14a00002, 0x00403821, 0x24050001,
+ 0x97630068, 0x93640081, 0x3c020800, 0x8c46004c, 0x00652821, 0x00852804,
+ 0x00c5102b, 0x54400001, 0x00a03021, 0x3c020800, 0x8c440050, 0x00c4182b,
+ 0x54600001, 0x00c02021, 0x8f420074, 0x2403fffe, 0x00832824, 0x00a21021,
+ 0xaf62000c, 0x10e00021, 0x3c029000, 0x8f450140, 0x34420001, 0x3c038000,
+ 0x00a21025, 0xaf420020, 0x8f420020, 0x00431024, 0x1440fffd, 0x00000000,
+ 0x9362007d, 0x3c038000, 0x34420004, 0xa362007d, 0x8f640074, 0x34630001,
+ 0x00a31825, 0xaf430020, 0x04810006, 0x3c038000, 0x00a02021, 0x0e000470,
+ 0x24050a92, 0x0a000da4, 0x8fbf0010, 0x8f4201f8, 0x00431024, 0x1440fffd,
+ 0x24020002, 0x3c031000, 0xaf4501c0, 0xa34201c4, 0xaf4301f8, 0x8fbf0010,
+ 0x03e00008, 0x27bd0018, 0x27bdffd8, 0xafb3001c, 0x27530100, 0xafbf0024,
+ 0xafb40020, 0xafb20018, 0xafb10014, 0xafb00010, 0x96620008, 0x3c140800,
+ 0x8f520100, 0x30420001, 0x104000da, 0x00000000, 0x8e700018, 0x8f630054,
+ 0x2602ffff, 0x00431023, 0x18400006, 0x00000000, 0x0000000d, 0x00000000,
+ 0x2400015c, 0x0a000dea, 0x00008821, 0x8f62004c, 0x02021023, 0x18400028,
+ 0x00008821, 0x93650120, 0x93640121, 0x3c030800, 0x8c62008c, 0x308400ff,
+ 0x24420001, 0x30a500ff, 0x00803821, 0x1485000b, 0xac62008c, 0x3c040800,
+ 0x8c830090, 0x24630001, 0xac830090, 0x93620122, 0x30420001, 0x00021023,
+ 0x30420005, 0x0a000dea, 0x34510004, 0x27660100, 0x00041080, 0x00c21021,
+ 0x8c430000, 0x02031823, 0x04600004, 0x24820001, 0x30440007, 0x1485fff9,
+ 0x00041080, 0x10870007, 0x3c030800, 0xa3640121, 0x8c620094, 0x24110005,
+ 0x24420001, 0x0a000dea, 0xac620094, 0x24110004, 0x32220001, 0x1040001e,
+ 0x8e820020, 0x1040001d, 0x32220004, 0x0e00148e, 0x00000000, 0x8f820018,
+ 0xac520000, 0x8f840018, 0x24020001, 0xac820004, 0x8f830018, 0xac600008,
+ 0x8f820018, 0xac40000c, 0x8f830018, 0xac600010, 0x8f820018, 0xac500014,
+ 0x8f850018, 0x3c026000, 0x8c434448, 0x24040001, 0x3c020800, 0xaca30018,
+ 0x944358ce, 0x8f850018, 0x3c024010, 0x00621825, 0x0e0014cc, 0xaca3001c,
+ 0x32220004, 0x10400081, 0x00003821, 0x3c029000, 0x34420001, 0x3c038000,
+ 0x02421025, 0xa360007c, 0xaf420020, 0x8f420020, 0x00431024, 0x1440fffd,
+ 0x00000000, 0x93620023, 0x30420080, 0x10400011, 0x00000000, 0x8f65005c,
+ 0x8f63004c, 0x9764003c, 0x8f620064, 0x00a32823, 0x00852821, 0x00a2102b,
+ 0x54400006, 0x3c023fff, 0x93620023, 0x3042007f, 0xa3620023, 0xaf700064,
+ 0x3c023fff, 0x0a000e37, 0x3442ffff, 0x8f62005c, 0x02021023, 0x04400011,
+ 0x00000000, 0x8f65005c, 0x8f630064, 0x9764003c, 0x3c023fff, 0x3442ffff,
+ 0xaf700064, 0x00a32823, 0x00852821, 0x0045102b, 0x10400004, 0x02051021,
+ 0x3c053fff, 0x34a5ffff, 0x02051021, 0xaf62005c, 0x24070001, 0xaf70004c,
+ 0x8f620054, 0x16020005, 0x00000000, 0x93620023, 0x30420040, 0x10400017,
+ 0x24020001, 0x9762006a, 0x00022880, 0x50a00001, 0x24050001, 0x97630068,
0x93640081, 0x3c020800, 0x8c46004c, 0x00652821, 0x00852804, 0x00c5102b,
0x54400001, 0x00a03021, 0x3c020800, 0x8c440050, 0x00c4182b, 0x54600001,
0x00c02021, 0x8f420074, 0x2403fffe, 0x00832824, 0x00a21021, 0xaf62000c,
- 0x10e0001a, 0x3c029000, 0x8f440140, 0x34420001, 0x3c038000, 0x00821025,
- 0xaf420020, 0x8f420020, 0x00431024, 0x1440fffd, 0x00000000, 0x3c038000,
- 0x9362007d, 0x34630001, 0x3c058000, 0x00831825, 0x34420004, 0xa362007d,
- 0xaf430020, 0x8f4201f8, 0x00451024, 0x1440fffd, 0x24020002, 0x3c031000,
- 0xaf4401c0, 0xa34201c4, 0xaf4301f8, 0x8fbf0010, 0x03e00008, 0x27bd0018,
- 0x27bdffd8, 0xafb3001c, 0x27530100, 0xafbf0024, 0xafb40020, 0xafb20018,
- 0xafb10014, 0xafb00010, 0x96620008, 0x3c140800, 0x8f520100, 0x30420001,
- 0x104000cf, 0x00000000, 0x8e700018, 0x8f630054, 0x2602ffff, 0x00431023,
- 0x18400006, 0x00000000, 0x0000000d, 0x00000000, 0x24000128, 0x0a0009b6,
- 0x00008821, 0x8f62004c, 0x02021023, 0x18400028, 0x00008821, 0x93650120,
- 0x93640121, 0x3c030800, 0x8c62008c, 0x308400ff, 0x24420001, 0x30a500ff,
- 0x00803821, 0x1485000b, 0xac62008c, 0x3c040800, 0x8c830090, 0x24630001,
- 0xac830090, 0x93620122, 0x30420001, 0x00021023, 0x30420005, 0x0a0009b6,
- 0x34510004, 0x27660100, 0x00041080, 0x00c21021, 0x8c430000, 0x02031823,
- 0x04600004, 0x24820001, 0x30440007, 0x1485fff9, 0x00041080, 0x10870007,
- 0x3c030800, 0xa3640121, 0x8c620094, 0x24110005, 0x24420001, 0x0a0009b6,
- 0xac620094, 0x24110004, 0x32220001, 0x1040001e, 0x8e820020, 0x1040001d,
- 0x32220004, 0x0e001006, 0x00000000, 0x8f820018, 0xac520000, 0x8f840018,
- 0x24020001, 0xac820004, 0x8f830018, 0xac600008, 0x8f820018, 0xac40000c,
- 0x8f830018, 0xac600010, 0x8f820018, 0xac500014, 0x8f850018, 0x3c026000,
- 0x8c434448, 0x24040001, 0x3c020800, 0xaca30018, 0x9443466e, 0x8f850018,
- 0x3c024010, 0x00621825, 0x0e001044, 0xaca3001c, 0x32220004, 0x10400076,
- 0x00003821, 0x3c029000, 0x34420001, 0x3c038000, 0x02421025, 0xa360007c,
- 0xaf420020, 0x8f420020, 0x00431024, 0x1440fffd, 0x00000000, 0x93620023,
- 0x30420080, 0x10400011, 0x00000000, 0x8f65005c, 0x8f63004c, 0x9764003c,
- 0x8f620064, 0x00a32823, 0x00852821, 0x00a2102b, 0x54400006, 0x3c023fff,
- 0x93620023, 0x3042007f, 0xa3620023, 0xaf700064, 0x3c023fff, 0x0a000a03,
- 0x3442ffff, 0x8f62005c, 0x02021023, 0x04400011, 0x00000000, 0x8f65005c,
- 0x8f630064, 0x9764003c, 0x3c023fff, 0x3442ffff, 0xaf700064, 0x00a32823,
- 0x00852821, 0x0045102b, 0x10400004, 0x02051021, 0x3c053fff, 0x34a5ffff,
- 0x02051021, 0xaf62005c, 0x24070001, 0xaf70004c, 0x8f620054, 0x16020005,
- 0x00000000, 0x93620023, 0x30420040, 0x10400017, 0x24020001, 0x9762006a,
- 0x00022880, 0x50a00001, 0x24050001, 0x97630068, 0x93640081, 0x3c020800,
- 0x8c46004c, 0x00652821, 0x00852804, 0x00c5102b, 0x54400001, 0x00a03021,
- 0x3c020800, 0x8c440050, 0x00c4182b, 0x54600001, 0x00c02021, 0x8f420074,
- 0x2403fffe, 0x00832824, 0x00a21021, 0xaf62000c, 0x3c028000, 0x34420001,
- 0x02421025, 0xa3600081, 0xaf420020, 0x9363007e, 0x9362007a, 0x10620004,
- 0x00000000, 0x0e000f2a, 0x00000000, 0x00403821, 0x10e00017, 0x3c029000,
+ 0x93620082, 0x30420080, 0x50400001, 0xa3600081, 0x3c028000, 0x34420001,
+ 0x02421025, 0xaf420020, 0x9363007e, 0x9362007a, 0x10620004, 0x00000000,
+ 0x0e0013c4, 0x00000000, 0x00403821, 0x10e0001f, 0x3c029000, 0x34420001,
+ 0x02421025, 0xaf420020, 0x3c038000, 0x8f420020, 0x00431024, 0x1440fffd,
+ 0x00000000, 0x9362007d, 0x3c038000, 0xa362007d, 0x8f640074, 0x34630001,
+ 0x02431825, 0xaf430020, 0x04810006, 0x3c038000, 0x02402021, 0x0e000470,
+ 0x24050b3d, 0x0a000e8d, 0x00000000, 0x8f4201f8, 0x00431024, 0x1440fffd,
+ 0x24020002, 0x3c031000, 0xaf5201c0, 0xa34201c4, 0xaf4301f8, 0x9342010b,
+ 0x9343010b, 0x8e820020, 0x27500100, 0x38630006, 0x10400029, 0x2c710001,
+ 0x0e00148e, 0x00000000, 0x8f830018, 0x8e020000, 0xac620000, 0x8f840018,
+ 0x96020008, 0xac820004, 0x8f830018, 0x8e020014, 0xac620008, 0x8f850018,
+ 0x3c026000, 0x8c434448, 0xaca3000c, 0x8f840018, 0x96020012, 0xac820010,
+ 0x8f850018, 0x8e030020, 0xaca30014, 0x9602000c, 0x9603000e, 0x8f840018,
+ 0x00021400, 0x00431025, 0xac820018, 0x12200005, 0x3c020800, 0x944358ce,
+ 0x8f840018, 0x0a000eb8, 0x3c024013, 0x944358ce, 0x8f840018, 0x3c024014,
+ 0x00621825, 0xac83001c, 0x0e0014cc, 0x24040001, 0x8e700014, 0x8f620040,
+ 0x14500003, 0x00501023, 0x0a000ec3, 0x00001021, 0x28420001, 0x1040003a,
+ 0x00000000, 0x0e000fae, 0x02002021, 0xaf700040, 0x9362003e, 0x30420001,
+ 0x1440000b, 0x3c029000, 0x93620022, 0x24420001, 0xa3620022, 0x93630022,
+ 0x3c020800, 0x8c440098, 0x0064182b, 0x14600025, 0x3c020800, 0x3c029000,
0x34420001, 0x02421025, 0xaf420020, 0x3c038000, 0x8f420020, 0x00431024,
- 0x1440fffd, 0x3c028000, 0x9363007d, 0x34420001, 0x3c048000, 0x02421025,
- 0xa363007d, 0xaf420020, 0x8f4201f8, 0x00441024, 0x1440fffd, 0x24020002,
- 0x3c031000, 0xaf5201c0, 0xa34201c4, 0xaf4301f8, 0x9342010b, 0x8e830020,
- 0x27500100, 0x38420006, 0x10600029, 0x2c510001, 0x0e001006, 0x00000000,
- 0x8f830018, 0x8e020000, 0xac620000, 0x8f840018, 0x96020008, 0xac820004,
- 0x8f830018, 0x8e020014, 0xac620008, 0x8f850018, 0x3c026000, 0x8c434448,
- 0xaca3000c, 0x8f840018, 0x96020012, 0xac820010, 0x8f850018, 0x8e030020,
- 0xaca30014, 0x9602000c, 0x9603000e, 0x8f840018, 0x00021400, 0x00431025,
- 0xac820018, 0x12200005, 0x3c020800, 0x9443466e, 0x8f840018, 0x0a000a78,
- 0x3c024013, 0x9443466e, 0x8f840018, 0x3c024014, 0x00621825, 0xac83001c,
- 0x0e001044, 0x24040001, 0x8e630014, 0x8f620040, 0x14430003, 0x00431023,
- 0x0a000a83, 0x00001021, 0x28420001, 0x10400034, 0x00000000, 0x8f620040,
- 0xaf630040, 0x9362003e, 0x30420001, 0x1440000b, 0x3c029000, 0x93620022,
- 0x24420001, 0xa3620022, 0x93630022, 0x3c020800, 0x8c440098, 0x0064182b,
- 0x1460001e, 0x3c020800, 0x3c029000, 0x34420001, 0x02421025, 0xaf420020,
- 0x3c038000, 0x8f420020, 0x00431024, 0x1440fffd, 0x00000000, 0x3c038000,
- 0x9362007d, 0x34630001, 0x3c048000, 0x02431825, 0x34420001, 0xa362007d,
- 0xaf430020, 0x8f4201f8, 0x00441024, 0x1440fffd, 0x24020002, 0x3c031000,
- 0xaf5201c0, 0xa34201c4, 0x24020001, 0xaf4301f8, 0xa7620012, 0x0a000ab6,
- 0xa3600022, 0x9743007a, 0x9444002a, 0x00641821, 0x3063fffe, 0xa7630012,
- 0x0e000b68, 0x00000000, 0x97420108, 0x8fbf0024, 0x8fb40020, 0x8fb3001c,
- 0x8fb20018, 0x8fb10014, 0x8fb00010, 0x00021042, 0x30420001, 0x03e00008,
- 0x27bd0028, 0x27bdffe0, 0xafb20018, 0x3c120800, 0x8e420020, 0xafb00010,
- 0x27500100, 0xafbf001c, 0x10400046, 0xafb10014, 0x0e001006, 0x00000000,
- 0x8f840018, 0x8e020000, 0xac820000, 0x936300b1, 0x936200c5, 0x8f850018,
- 0x00031e00, 0x00021400, 0x34420100, 0x00621825, 0xaca30004, 0x8f840018,
- 0x8e02001c, 0xac820008, 0x8f830018, 0x8f620048, 0xac62000c, 0x8f840018,
- 0x96020012, 0xac820010, 0x8f830018, 0x8f620040, 0x24040001, 0xac620014,
- 0x8f850018, 0x3c026000, 0x8c434448, 0x3c020800, 0x24514660, 0xaca30018,
- 0x9623000e, 0x8f850018, 0x3c024016, 0x00621825, 0x0e001044, 0xaca3001c,
- 0x96030008, 0x30630010, 0x1060001c, 0x8e420020, 0x1040001a, 0x8e100000,
- 0x0e001006, 0x00000000, 0x8f820018, 0xac500000, 0x8f830018, 0xac600004,
- 0x8f820018, 0xac400008, 0x8f830018, 0xac60000c, 0x8f820018, 0xac400010,
- 0x8f830018, 0xac600014, 0x8f850018, 0x3c036000, 0x8c634448, 0x24040001,
- 0xaca30018, 0x9622000e, 0x8f850018, 0x3c034015, 0x00431025, 0x0e001044,
- 0xaca2001c, 0x00001021, 0x8fbf001c, 0x8fb20018, 0x8fb10014, 0x8fb00010,
- 0x03e00008, 0x27bd0020, 0x27bdffe0, 0xafb20018, 0x3c120800, 0x8e420020,
- 0xafb00010, 0x27500100, 0xafbf001c, 0x10400041, 0xafb10014, 0x0e001006,
- 0x00000000, 0x8f830018, 0x8e020000, 0xac620000, 0x8f840018, 0x24020100,
- 0xac820004, 0x8f830018, 0x8e02001c, 0xac620008, 0x8f840018, 0x8e020018,
- 0xac82000c, 0x8f830018, 0x96020012, 0xac620010, 0x8f840018, 0x96020008,
- 0xac820014, 0x8f850018, 0x3c026000, 0x8c434448, 0x24040001, 0x3c020800,
- 0x24514660, 0xaca30018, 0x9623000e, 0x8f850018, 0x3c024017, 0x00621825,
- 0x0e001044, 0xaca3001c, 0x96030008, 0x30630010, 0x1060001c, 0x8e420020,
- 0x1040001a, 0x8e100000, 0x0e001006, 0x00000000, 0x8f820018, 0xac500000,
+ 0x1440fffd, 0x00000000, 0x9362007d, 0x3c038000, 0x34420001, 0xa362007d,
+ 0x8f640074, 0x34630001, 0x02431825, 0xaf430020, 0x04810006, 0x3c038000,
+ 0x02402021, 0x0e000470, 0x24050273, 0x0a000ef6, 0x24020001, 0x8f4201f8,
+ 0x00431024, 0x1440fffd, 0x24020002, 0x3c031000, 0xaf5201c0, 0xa34201c4,
+ 0xaf4301f8, 0x24020001, 0xa7620012, 0x0a000efe, 0xa3600022, 0x9743007a,
+ 0x9444002a, 0x00641821, 0x3063fffe, 0xa7630012, 0x97420108, 0x8fbf0024,
+ 0x8fb40020, 0x8fb3001c, 0x8fb20018, 0x8fb10014, 0x8fb00010, 0x00021042,
+ 0x30420001, 0x03e00008, 0x27bd0028, 0x27bdffe0, 0xafb20018, 0x3c120800,
+ 0x8e420020, 0xafb00010, 0x27500100, 0xafbf001c, 0x10400046, 0xafb10014,
+ 0x0e00148e, 0x00000000, 0x8f840018, 0x8e020000, 0xac820000, 0x936300b1,
+ 0x936200c5, 0x8f850018, 0x00031e00, 0x00021400, 0x34420100, 0x00621825,
+ 0xaca30004, 0x8f840018, 0x8e02001c, 0xac820008, 0x8f830018, 0x8f620048,
+ 0xac62000c, 0x8f840018, 0x96020012, 0xac820010, 0x8f830018, 0x8f620040,
+ 0x24040001, 0xac620014, 0x8f850018, 0x3c026000, 0x8c434448, 0x3c020800,
+ 0x245158c0, 0xaca30018, 0x9623000e, 0x8f850018, 0x3c024016, 0x00621825,
+ 0x0e0014cc, 0xaca3001c, 0x96030008, 0x30630010, 0x1060001c, 0x8e420020,
+ 0x1040001a, 0x8e100000, 0x0e00148e, 0x00000000, 0x8f820018, 0xac500000,
0x8f830018, 0xac600004, 0x8f820018, 0xac400008, 0x8f830018, 0xac60000c,
0x8f820018, 0xac400010, 0x8f830018, 0xac600014, 0x8f850018, 0x3c036000,
0x8c634448, 0x24040001, 0xaca30018, 0x9622000e, 0x8f850018, 0x3c034015,
- 0x00431025, 0x0e001044, 0xaca2001c, 0x00001021, 0x8fbf001c, 0x8fb20018,
- 0x8fb10014, 0x8fb00010, 0x03e00008, 0x27bd0020, 0x27bdffe8, 0xafbf0010,
- 0x936200c4, 0x30420002, 0x10400019, 0x00000000, 0x936200c5, 0x936300b1,
- 0x00431023, 0x304400ff, 0x30830080, 0x10600004, 0x00000000, 0x0000000d,
- 0x00000000, 0x24000a6a, 0x93620004, 0x00441023, 0x304400ff, 0x30830080,
- 0x10600004, 0x2482ffff, 0x8f650024, 0x0a000b82, 0x00000000, 0x00022b00,
- 0x8f620024, 0x0045102b, 0x10400002, 0x00000000, 0x8f650024, 0x8f620048,
- 0x8f630040, 0x00431823, 0x0065202b, 0x10800004, 0x00000000, 0x8f620040,
- 0x00451021, 0xaf620048, 0x9762003c, 0x0062102b, 0x10400041, 0x8fbf0010,
- 0x10a0003f, 0x3c029000, 0x34420001, 0x3c040800, 0x8c830080, 0x8f450100,
- 0x3c068000, 0x24630001, 0x00a21025, 0xac830080, 0xaf420020, 0x8f420020,
- 0x00461024, 0x1440fffd, 0x3c038000, 0x9362007d, 0x34630001, 0x3c048000,
- 0x00a31825, 0x34420004, 0xa362007d, 0xaf430020, 0x8f4201f8, 0x00441024,
- 0x1440fffd, 0x24020002, 0x3c030800, 0xaf4501c0, 0xa34201c4, 0x8c640020,
- 0x3c021000, 0xaf4201f8, 0x1080001f, 0x8fbf0010, 0x0e001006, 0x00000000,
- 0x8f830018, 0x8f420100, 0xac620000, 0x8f840018, 0x8f620040, 0xac820004,
- 0x8f850018, 0x8f620048, 0xaca20008, 0x8f830018, 0xac60000c, 0x8f820018,
- 0xac400010, 0x8f830018, 0x3c026000, 0xac600014, 0x8f840018, 0x8c434448,
- 0x3c020800, 0xac830018, 0x9443466e, 0x8f840018, 0x3c0240c2, 0x00621825,
- 0xac83001c, 0x0e001044, 0x24040001, 0x8fbf0010, 0x03e00008, 0x27bd0018,
- 0x3c020800, 0x24423958, 0xaf82000c, 0x03e00008, 0x00000000, 0x27bdffe8,
- 0xafb00010, 0x27500100, 0xafbf0014, 0x8e02001c, 0x14400003, 0x3c020800,
- 0x0000000d, 0x3c020800, 0x8c430020, 0x10600026, 0x00001021, 0x0e001006,
- 0x00000000, 0x8f830018, 0x8e020000, 0xac620000, 0x8f840018, 0x8e02001c,
- 0xac820004, 0x8f830018, 0xac600008, 0x8f840018, 0x8e020018, 0xac82000c,
- 0x8f850018, 0x96020012, 0xaca20010, 0x8f830018, 0x3c106000, 0xac600014,
- 0x8f840018, 0x8e024448, 0x3c030800, 0xac820018, 0x9462466e, 0x8f840018,
- 0x3c034012, 0x00431025, 0xac82001c, 0x0e001044, 0x24040001, 0x8e036800,
- 0x00001021, 0x3c040001, 0x00641825, 0xae036800, 0x0a000c0d, 0x8fbf0014,
- 0x8fbf0014, 0x8fb00010, 0x03e00008, 0x27bd0018, 0x3c020800, 0x97430078,
- 0x9444002e, 0x00001021, 0x00641821, 0x3063fffe, 0x03e00008, 0xa7630010,
- 0x27450100, 0x8f640048, 0x8ca30018, 0x00641023, 0x18400021, 0x00000000,
- 0xaf630048, 0x8f620040, 0x9763003c, 0x00821023, 0x0043102a, 0x1040001a,
- 0x3c029000, 0x8ca40000, 0x34420001, 0x3c038000, 0x00821025, 0xaf420020,
- 0x8f420020, 0x00431024, 0x1440fffd, 0x00000000, 0x3c038000, 0x9362007d,
- 0x34630001, 0x3c058000, 0x00831825, 0x34420004, 0xa362007d, 0xaf430020,
- 0x8f4201f8, 0x00451024, 0x1440fffd, 0x24020002, 0x3c031000, 0xaf4401c0,
- 0xa34201c4, 0xaf4301f8, 0x03e00008, 0x00001021, 0x8f420100, 0x34420001,
- 0xaf4200a4, 0x03e00008, 0x00001021, 0x27bdffe0, 0xafbf0018, 0xafb10014,
- 0xafb00010, 0x9362007e, 0x30d000ff, 0x16020029, 0x00808821, 0x93620080,
- 0x16020026, 0x00000000, 0x9362007f, 0x16020023, 0x00000000, 0x9362007a,
- 0x16020004, 0x00000000, 0x0000000d, 0x00000000, 0x24000771, 0x0e000f49,
- 0x00000000, 0x3c039000, 0x34630001, 0x3c048000, 0x02231825, 0xa370007a,
- 0xaf430020, 0x8f420020, 0x00441024, 0x1440fffd, 0x3c028000, 0x9363007d,
- 0x34420001, 0x3c048000, 0x02221025, 0xa363007d, 0xaf420020, 0x8f4201f8,
- 0x00441024, 0x1440fffd, 0x24020002, 0x3c031000, 0xaf5101c0, 0xa34201c4,
- 0xaf4301f8, 0x0a000c79, 0x8fbf0018, 0x0000000d, 0x00000000, 0x24000781,
- 0x8fbf0018, 0x8fb10014, 0x8fb00010, 0x03e00008, 0x27bd0020, 0x3c020800,
+ 0x00431025, 0x0e0014cc, 0xaca2001c, 0x00001021, 0x8fbf001c, 0x8fb20018,
+ 0x8fb10014, 0x8fb00010, 0x03e00008, 0x27bd0020, 0x27bdffe0, 0xafb20018,
+ 0x3c120800, 0x8e420020, 0xafb00010, 0x27500100, 0xafbf001c, 0x10400041,
+ 0xafb10014, 0x0e00148e, 0x00000000, 0x8f830018, 0x8e020000, 0xac620000,
+ 0x8f840018, 0x24020100, 0xac820004, 0x8f830018, 0x8e02001c, 0xac620008,
+ 0x8f840018, 0x8e020018, 0xac82000c, 0x8f830018, 0x96020012, 0xac620010,
+ 0x8f840018, 0x96020008, 0xac820014, 0x8f850018, 0x3c026000, 0x8c434448,
+ 0x24040001, 0x3c020800, 0x245158c0, 0xaca30018, 0x9623000e, 0x8f850018,
+ 0x3c024017, 0x00621825, 0x0e0014cc, 0xaca3001c, 0x96030008, 0x30630010,
+ 0x1060001c, 0x8e420020, 0x1040001a, 0x8e100000, 0x0e00148e, 0x00000000,
+ 0x8f820018, 0xac500000, 0x8f830018, 0xac600004, 0x8f820018, 0xac400008,
+ 0x8f830018, 0xac60000c, 0x8f820018, 0xac400010, 0x8f830018, 0xac600014,
+ 0x8f850018, 0x3c036000, 0x8c634448, 0x24040001, 0xaca30018, 0x9622000e,
+ 0x8f850018, 0x3c034015, 0x00431025, 0x0e0014cc, 0xaca2001c, 0x00001021,
+ 0x8fbf001c, 0x8fb20018, 0x8fb10014, 0x8fb00010, 0x03e00008, 0x27bd0020,
+ 0x27bdfff0, 0x03e00008, 0x27bd0010, 0x27bdffd0, 0xafb10014, 0x00808821,
+ 0xafb40020, 0x00c0a021, 0xafbf0028, 0xafb50024, 0xafb3001c, 0xafb20018,
+ 0xafb00010, 0x93620023, 0x00e0a821, 0x30420040, 0x1040003e, 0x30b3ffff,
+ 0x3c120800, 0x8e420020, 0x1040003a, 0x8f70004c, 0x0e00148e, 0x00000000,
+ 0x8f820018, 0xac510000, 0x8f840018, 0x24020001, 0xac820004, 0x8f830018,
+ 0xac600008, 0x8f820018, 0xac40000c, 0x8f830018, 0xac600010, 0x8f820018,
+ 0x24040001, 0xac500014, 0x8f850018, 0x3c026000, 0x8c434448, 0x3c020800,
+ 0x245058c0, 0xaca30018, 0x9603000e, 0x8f850018, 0x3c024010, 0x00621825,
+ 0x0e0014cc, 0xaca3001c, 0x8e430020, 0x1060001b, 0x00000000, 0x0e00148e,
+ 0x00000000, 0x8f820018, 0xac510000, 0x8f840018, 0x3c02008d, 0xac820004,
+ 0x8f830018, 0xac600008, 0x8f820018, 0xac40000c, 0x8f830018, 0xac600010,
+ 0x8f820018, 0xac550014, 0x8f850018, 0x3c036000, 0x8c634448, 0x24040001,
+ 0xaca30018, 0x9602000e, 0x8f850018, 0x3c034019, 0x00431025, 0x0e0014cc,
+ 0xaca2001c, 0x93620023, 0x30420020, 0x14400003, 0x3c120800, 0x1280003f,
+ 0x3c029000, 0x8e420020, 0x8f70004c, 0x1040003b, 0x3c029000, 0x0e00148e,
+ 0x00000000, 0x8f820018, 0xac510000, 0x8f840018, 0x24020001, 0xac820004,
+ 0x8f830018, 0xac600008, 0x8f820018, 0xac40000c, 0x8f830018, 0xac600010,
+ 0x8f820018, 0x24040001, 0xac500014, 0x8f850018, 0x3c026000, 0x8c434448,
+ 0x3c020800, 0x245058c0, 0xaca30018, 0x9603000e, 0x8f850018, 0x3c024010,
+ 0x00621825, 0x0e0014cc, 0xaca3001c, 0x8e430020, 0x1060001c, 0x3c029000,
+ 0x0e00148e, 0x00000000, 0x8f820018, 0xac510000, 0x8f840018, 0x00131400,
+ 0xac820004, 0x8f830018, 0xac750008, 0x8f820018, 0xac40000c, 0x8f830018,
+ 0xac600010, 0x8f820018, 0xac400014, 0x8f850018, 0x3c036000, 0x8c634448,
+ 0x24040001, 0xaca30018, 0x9602000e, 0x8f850018, 0x3c03401b, 0x00431025,
+ 0x0e0014cc, 0xaca2001c, 0x3c029000, 0x34420001, 0x02221025, 0xaf420020,
+ 0x3c038000, 0x8f420020, 0x00431024, 0x1440fffd, 0x00000000, 0x93630023,
+ 0x3c028000, 0x34420001, 0x02221025, 0x8fbf0028, 0x8fb50024, 0x8fb40020,
+ 0x8fb3001c, 0x8fb20018, 0x8fb10014, 0x8fb00010, 0x3063009f, 0xa3630023,
+ 0xaf420020, 0x03e00008, 0x27bd0030, 0x27bdffe0, 0xafb10014, 0x27510100,
+ 0x3c029000, 0x34420001, 0xafb00010, 0x00808021, 0x02021025, 0x3c038000,
+ 0xafbf0018, 0xaf420020, 0x8f420020, 0x00431024, 0x1440fffd, 0x00000000,
+ 0xa7600008, 0x8f63005c, 0x3c028000, 0x34420001, 0xaf630148, 0x8f640050,
+ 0x02021025, 0x3c039000, 0xaf64017c, 0xaf420020, 0x8f450100, 0x34630001,
+ 0x3c048000, 0x00a31825, 0xaf430020, 0x8f420020, 0x00441024, 0x1440fffd,
+ 0x00000000, 0x9362007d, 0x3c038000, 0x34420001, 0xa362007d, 0x8f640074,
+ 0x34630001, 0x00a31825, 0xaf430020, 0x04810006, 0x3c038000, 0x00a02021,
+ 0x0e000470, 0x24050de5, 0x0a001093, 0x3c020800, 0x8f4201f8, 0x00431024,
+ 0x1440fffd, 0x24020002, 0x3c031000, 0xaf4501c0, 0xa34201c4, 0xaf4301f8,
+ 0x3c020800, 0x8c430020, 0x1060001e, 0x8fbf0018, 0x0e00148e, 0x00000000,
+ 0x8f830018, 0xac700000, 0x9622000c, 0x8f840018, 0x00021400, 0xac820004,
+ 0x8f830018, 0xac600008, 0x8f820018, 0xac40000c, 0x8f830018, 0xac600010,
+ 0x8f820018, 0xac400014, 0x8f850018, 0x3c026000, 0x8c434448, 0x24040001,
+ 0x3c020800, 0xaca30018, 0x944358ce, 0x8f850018, 0x3c02401f, 0x00621825,
+ 0x0e0014cc, 0xaca3001c, 0x8fbf0018, 0x8fb10014, 0x8fb00010, 0x03e00008,
+ 0x27bd0020, 0x3c020800, 0x24424c3c, 0xaf82000c, 0x03e00008, 0x00000000,
+ 0x27bdffe8, 0xafb00010, 0x27500100, 0xafbf0014, 0x8e02001c, 0x14400003,
+ 0x3c020800, 0x0000000d, 0x3c020800, 0x8c430020, 0x10600020, 0x00001021,
+ 0x0e00148e, 0x00000000, 0x8f830018, 0x8e020000, 0xac620000, 0x8f840018,
+ 0x8e02001c, 0xac820004, 0x8f830018, 0xac600008, 0x8f840018, 0x8e020018,
+ 0xac82000c, 0x8f850018, 0x96020012, 0xaca20010, 0x8f830018, 0x3c026000,
+ 0xac600014, 0x8f840018, 0x8c434448, 0x3c020800, 0xac830018, 0x944358ce,
+ 0x8f840018, 0x3c024012, 0x00621825, 0xac83001c, 0x0e0014cc, 0x24040001,
+ 0x00001021, 0x8fbf0014, 0x8fb00010, 0x03e00008, 0x27bd0018, 0x3c020800,
+ 0x97430078, 0x9444002e, 0x00001021, 0x00641821, 0x3063fffe, 0x03e00008,
+ 0xa7630010, 0x27bdfff0, 0x00001021, 0x03e00008, 0x27bd0010, 0x8f420100,
+ 0x34420001, 0xaf4200a4, 0x03e00008, 0x00001021, 0x27bdffe0, 0xafbf0018,
+ 0xafb10014, 0xafb00010, 0x9362007e, 0x30d000ff, 0x16020031, 0x00808821,
+ 0x8f620178, 0x1602002e, 0x00000000, 0x9362007f, 0x1602002b, 0x00000000,
+ 0x9362007a, 0x16020004, 0x00000000, 0x0000000d, 0x00000000, 0x240009d2,
+ 0x0e0013e6, 0x00000000, 0x3c039000, 0x34630001, 0x3c048000, 0x02231825,
+ 0xa370007a, 0xaf430020, 0x8f420020, 0x00441024, 0x1440fffd, 0x00000000,
+ 0x9362007d, 0x3c038000, 0xa362007d, 0x8f640074, 0x34630001, 0x02231825,
+ 0xaf430020, 0x04810006, 0x3c038000, 0x02202021, 0x0e000470, 0x240509dd,
+ 0x0a001138, 0x8fbf0018, 0x8f4201f8, 0x00431024, 0x1440fffd, 0x24020002,
+ 0x3c031000, 0xaf5101c0, 0xa34201c4, 0xaf4301f8, 0x0a001138, 0x8fbf0018,
+ 0x0000000d, 0x00000000, 0x240009e2, 0x8fbf0018, 0x8fb10014, 0x8fb00010,
+ 0x03e00008, 0x27bd0020, 0x27bdffe8, 0x30a500ff, 0x3c029000, 0x34420001,
+ 0x00803821, 0x00e21025, 0x3c038000, 0xafbf0010, 0xaf420020, 0x8f420020,
+ 0x00431024, 0x1440fffd, 0x00000000, 0x9362007d, 0x3c038000, 0x00a21025,
+ 0xa362007d, 0x8f640074, 0x34630001, 0x00e31825, 0xaf430020, 0x04810006,
+ 0x3c038000, 0x00e02021, 0x0e000470, 0x00c02821, 0x0a001161, 0x8fbf0010,
+ 0x8f4201f8, 0x00431024, 0x1440fffd, 0x24020002, 0x3c031000, 0xaf4701c0,
+ 0xa34201c4, 0xaf4301f8, 0x8fbf0010, 0x03e00008, 0x27bd0018, 0x3c020800,
0x8c430020, 0x27bdffe8, 0xafb00010, 0x27500100, 0x10600024, 0xafbf0014,
- 0x0e001006, 0x00000000, 0x8f830018, 0x8e020000, 0xac620000, 0x8f840018,
+ 0x0e00148e, 0x00000000, 0x8f830018, 0x8e020000, 0xac620000, 0x8f840018,
0x8e020004, 0xac820004, 0x8f830018, 0x8e020018, 0xac620008, 0x8f840018,
0x8e03001c, 0xac83000c, 0x9602000c, 0x9203000a, 0x8f840018, 0x00021400,
0x00431025, 0xac820010, 0x8f830018, 0x3c026000, 0xac600014, 0x8f840018,
- 0x8c434448, 0xac830018, 0x96020008, 0x3c030800, 0x9464466e, 0x8f850018,
- 0x00021400, 0x00441025, 0x24040001, 0x0e001044, 0xaca2001c, 0x8fbf0014,
+ 0x8c434448, 0xac830018, 0x96020008, 0x3c030800, 0x946458ce, 0x8f850018,
+ 0x00021400, 0x00441025, 0x24040001, 0x0e0014cc, 0xaca2001c, 0x8fbf0014,
0x8fb00010, 0x03e00008, 0x27bd0018, 0x3c020800, 0x8c430020, 0x27bdffe8,
- 0xafb00010, 0x27500100, 0x10600020, 0xafbf0014, 0x0e001006, 0x00000000,
+ 0xafb00010, 0x27500100, 0x10600020, 0xafbf0014, 0x0e00148e, 0x00000000,
0x8f820018, 0xac400000, 0x8f830018, 0xac600004, 0x8f820018, 0xac400008,
0x8f830018, 0xac60000c, 0x9602000c, 0x9603000e, 0x8f840018, 0x00021400,
0x00431025, 0xac820010, 0x8f830018, 0x3c026000, 0xac600014, 0x8f840018,
- 0x8c434448, 0xac830018, 0x96020008, 0x3c030800, 0x9464466e, 0x8f850018,
- 0x00021400, 0x00441025, 0x24040001, 0x0e001044, 0xaca2001c, 0x8fbf0014,
+ 0x8c434448, 0xac830018, 0x96020008, 0x3c030800, 0x946458ce, 0x8f850018,
+ 0x00021400, 0x00441025, 0x24040001, 0x0e0014cc, 0xaca2001c, 0x8fbf0014,
0x8fb00010, 0x03e00008, 0x27bd0018, 0x27bdffe8, 0xafb00010, 0x27500100,
0xafbf0014, 0x9602000c, 0x10400024, 0x00802821, 0x3c020800, 0x8c430020,
- 0x1060003a, 0x8fbf0014, 0x0e001006, 0x00000000, 0x8f840018, 0x8e030000,
+ 0x1060003a, 0x8fbf0014, 0x0e00148e, 0x00000000, 0x8f840018, 0x8e030000,
0xac830000, 0x9602000c, 0x8f840018, 0x00021400, 0xac820004, 0x8f830018,
0xac600008, 0x8f820018, 0xac40000c, 0x8f830018, 0xac600010, 0x8f820018,
0xac400014, 0x8f850018, 0x3c026000, 0x8c434448, 0x24040001, 0x3c020800,
- 0xaca30018, 0x9443466e, 0x8f850018, 0x3c02400b, 0x00621825, 0x0e001044,
- 0xaca3001c, 0x0a000d19, 0x8fbf0014, 0x93620005, 0x30420010, 0x14400015,
+ 0xaca30018, 0x944358ce, 0x8f850018, 0x3c02400b, 0x00621825, 0x0e0014cc,
+ 0xaca3001c, 0x0a0011ff, 0x8fbf0014, 0x93620005, 0x30420010, 0x14400015,
0x3c029000, 0x34420001, 0x00a21025, 0xaf420020, 0x3c038000, 0x8f420020,
0x00431024, 0x1440fffd, 0x00000000, 0x3c038000, 0x93620005, 0x34630001,
- 0x00a02021, 0x00a31825, 0x24055852, 0x34420010, 0xa3620005, 0x0e000553,
- 0xaf430020, 0x0a000d19, 0x8fbf0014, 0x0000000d, 0x8fbf0014, 0x8fb00010,
+ 0x00a02021, 0x00a31825, 0x24055852, 0x34420010, 0xa3620005, 0x0e000766,
+ 0xaf430020, 0x0a0011ff, 0x8fbf0014, 0x0000000d, 0x8fbf0014, 0x8fb00010,
0x03e00008, 0x27bd0018, 0x3c020800, 0x8c430020, 0x27bdffe8, 0xafb00010,
- 0x27500100, 0x10600022, 0xafbf0014, 0x0e001006, 0x00000000, 0x8f840018,
+ 0x27500100, 0x10600022, 0xafbf0014, 0x0e00148e, 0x00000000, 0x8f840018,
0x8e020004, 0xac820000, 0x9603000c, 0x9762002c, 0x8f840018, 0x00031c00,
0x00431025, 0xac820004, 0x8f830018, 0xac600008, 0x8f820018, 0xac40000c,
0x8f830018, 0xac600010, 0x8f820018, 0xac400014, 0x8f850018, 0x3c026000,
- 0x8c434448, 0x24040001, 0x3c020800, 0xaca30018, 0x9443466e, 0x8f850018,
- 0x3c02400e, 0x00621825, 0x0e001044, 0xaca3001c, 0x0e000d48, 0x8e040000,
+ 0x8c434448, 0x24040001, 0x3c020800, 0xaca30018, 0x944358ce, 0x8f850018,
+ 0x3c02400e, 0x00621825, 0x0e0014cc, 0xaca3001c, 0x0e00122e, 0x8e040000,
0x8fbf0014, 0x8fb00010, 0x03e00008, 0x27bd0018, 0x3c038000, 0x8f420278,
0x00431024, 0x1440fffd, 0x24020002, 0x3c031000, 0xaf440240, 0xa3420244,
0x03e00008, 0xaf430278, 0x3c020800, 0x8c430020, 0x27bdffe0, 0xafb10014,
0x00808821, 0xafb20018, 0x00c09021, 0xafb00010, 0x30b0ffff, 0x1060001c,
- 0xafbf001c, 0x0e001006, 0x00000000, 0x8f820018, 0xac510000, 0x8f840018,
+ 0xafbf001c, 0x0e00148e, 0x00000000, 0x8f820018, 0xac510000, 0x8f840018,
0x00101400, 0xac820004, 0x8f830018, 0xac600008, 0x8f820018, 0xac40000c,
0x8f830018, 0xac600010, 0x8f820018, 0xac520014, 0x8f840018, 0x3c026000,
- 0x8c434448, 0x3c020800, 0xac830018, 0x9443466e, 0x8f840018, 0x3c024019,
- 0x00621825, 0xac83001c, 0x0e001044, 0x24040001, 0x8fbf001c, 0x8fb20018,
+ 0x8c434448, 0x3c020800, 0xac830018, 0x944358ce, 0x8f840018, 0x3c024019,
+ 0x00621825, 0xac83001c, 0x0e0014cc, 0x24040001, 0x8fbf001c, 0x8fb20018,
0x8fb10014, 0x8fb00010, 0x03e00008, 0x27bd0020, 0x27bdffe8, 0x27450100,
- 0xafbf0010, 0x94a3000c, 0x240200c1, 0x14620029, 0x00803021, 0x3c029000,
+ 0xafbf0010, 0x94a3000c, 0x240200c1, 0x14620031, 0x00803021, 0x3c029000,
0x34420001, 0x00c21025, 0xaf420020, 0x3c038000, 0x8f420020, 0x00431024,
0x1440fffd, 0x3c028000, 0x34420001, 0x3c049000, 0x34840001, 0x3c058000,
0x24030012, 0x00c21025, 0x00c42025, 0xa363003f, 0xaf420020, 0xaf440020,
- 0x8f420020, 0x00451024, 0x1440fffd, 0x3c038000, 0x9362007d, 0x34630001,
- 0x3c048000, 0x00c31825, 0x34420020, 0xa362007d, 0xaf430020, 0x8f4201f8,
- 0x00441024, 0x1440fffd, 0x24020002, 0x3c031000, 0xaf4601c0, 0xa34201c4,
- 0xaf4301f8, 0x0a000db3, 0x8fbf0010, 0x00c02021, 0x94a5000c, 0x24060001,
- 0x0e000f78, 0x240706d8, 0x8fbf0010, 0x03e00008, 0x27bd0018, 0x3c020800,
- 0x8c430020, 0x27bdffe0, 0xafb00010, 0x00808021, 0xafb20018, 0x00a09021,
- 0xafb10014, 0x30d100ff, 0x1060001c, 0xafbf001c, 0x0e001006, 0x00000000,
- 0x8f820018, 0xac500000, 0x8f840018, 0x24020001, 0xac820004, 0x8f830018,
- 0xac600008, 0x8f820018, 0xac40000c, 0x8f830018, 0xac600010, 0x8f820018,
- 0xac520014, 0x8f840018, 0x3c026000, 0x8c434448, 0x3c020800, 0xac830018,
- 0x9443466e, 0x8f840018, 0x3c024010, 0x00621825, 0xac83001c, 0x0e001044,
- 0x02202021, 0x8fbf001c, 0x8fb20018, 0x8fb10014, 0x8fb00010, 0x03e00008,
- 0x27bd0020, 0x27bdffe8, 0xafbf0014, 0xafb00010, 0x93620005, 0x30420001,
- 0x10400033, 0x00808021, 0x3c029000, 0x34420001, 0x02021025, 0xaf420020,
- 0x3c038000, 0x8f420020, 0x00431024, 0x1440fffd, 0x00000000, 0x93620005,
- 0x3c048000, 0x3c030800, 0x304200fe, 0xa3620005, 0x8c620020, 0x34840001,
- 0x02042025, 0xaf440020, 0x10400020, 0x8fbf0014, 0x0e001006, 0x00000000,
- 0x8f820018, 0xac500000, 0x93630082, 0x9362003f, 0x8f840018, 0x00031a00,
- 0x00431025, 0xac820004, 0x8f830018, 0xac600008, 0x8f820018, 0xac40000c,
- 0x8f830018, 0xac600010, 0x8f820018, 0xac400014, 0x8f840018, 0x3c026000,
- 0x8c434448, 0x3c020800, 0xac830018, 0x9443466e, 0x8f840018, 0x3c02400a,
- 0x00621825, 0xac83001c, 0x0e001044, 0x24040001, 0x8fbf0014, 0x8fb00010,
- 0x03e00008, 0x27bd0018, 0x27bdffe8, 0xafbf0010, 0x8f420188, 0x00803021,
- 0x9364003f, 0x24030012, 0x00021402, 0x1483001c, 0x304500ff, 0x3c029000,
- 0x34420001, 0x3c038000, 0x00c21025, 0xa3650080, 0xa365007a, 0xaf420020,
- 0x8f420020, 0x00431024, 0x1440fffd, 0x3c028000, 0x9363007d, 0x34420001,
- 0x3c048000, 0x00c21025, 0xa363007d, 0xaf420020, 0x8f4201f8, 0x00441024,
- 0x1440fffd, 0x24020002, 0x3c031000, 0xaf4601c0, 0xa34201c4, 0xaf4301f8,
- 0x0a000e54, 0x8fbf0010, 0x9362007e, 0x1445000e, 0x00000000, 0x93620080,
- 0x1045000b, 0x00000000, 0xa3650080, 0x8f820000, 0x93660080, 0x8f440180,
- 0x8f65004c, 0x8c430000, 0x0060f809, 0x00000000, 0x0a000e54, 0x8fbf0010,
- 0xa3650080, 0x8fbf0010, 0x03e00008, 0x27bd0018, 0x3c020800, 0x8c430020,
- 0x27bdffe0, 0xafb10014, 0x00808821, 0xafb20018, 0x00a09021, 0xafb00010,
- 0x30d000ff, 0x1060002f, 0xafbf001c, 0x0e001006, 0x00000000, 0x8f820018,
- 0xac510000, 0x8f830018, 0xac700004, 0x8f820018, 0xac520008, 0x8f830018,
- 0xac60000c, 0x8f820018, 0xac400010, 0x9763006a, 0x00032880, 0x50a00001,
- 0x24050001, 0x97630068, 0x93640081, 0x3c020800, 0x8c46004c, 0x00652821,
- 0x00852804, 0x00c5102b, 0x54400001, 0x00a03021, 0x3c020800, 0x8c440050,
- 0x00c4182b, 0x54600001, 0x00c02021, 0x8f830018, 0x2402fffe, 0x00822824,
- 0x3c026000, 0xac650014, 0x8f840018, 0x8c434448, 0x3c020800, 0xac830018,
- 0x9443466e, 0x8f840018, 0x3c024011, 0x00621825, 0xac83001c, 0x0e001044,
- 0x24040001, 0x8fbf001c, 0x8fb20018, 0x8fb10014, 0x8fb00010, 0x03e00008,
- 0x27bd0020, 0x27bdffe8, 0xafbf0014, 0xafb00010, 0x8f440100, 0x27500100,
- 0x8f650050, 0x0e000c45, 0x9206001b, 0x3c020800, 0x8c430020, 0x1060001d,
- 0x8e100018, 0x0e001006, 0x00000000, 0x8f840018, 0x8f420100, 0xac820000,
- 0x8f830018, 0xac700004, 0x8f840018, 0x8f620050, 0xac820008, 0x8f830018,
- 0xac60000c, 0x8f820018, 0xac400010, 0x8f830018, 0x3c026000, 0xac600014,
- 0x8f850018, 0x8c434448, 0x24040001, 0x3c020800, 0xaca30018, 0x9443466e,
- 0x8f850018, 0x3c02401c, 0x00621825, 0x0e001044, 0xaca3001c, 0x8fbf0014,
- 0x8fb00010, 0x03e00008, 0x27bd0018, 0x3c029000, 0x8f460140, 0x34420001,
- 0x3c038000, 0x00c21025, 0xaf420020, 0x8f420020, 0x00431024, 0x1440fffd,
- 0x3c048000, 0x34840001, 0x3c059000, 0x34a50001, 0x3c078000, 0x24020012,
- 0x24030080, 0x00c42025, 0x00c52825, 0xa362003f, 0xa3630082, 0xaf440020,
- 0xaf450020, 0x8f420020, 0x00471024, 0x1440fffd, 0x3c038000, 0x9362007d,
- 0x34630001, 0x3c048000, 0x00c31825, 0x34420020, 0xa362007d, 0xaf430020,
- 0x8f4201f8, 0x00441024, 0x1440fffd, 0x24020002, 0x3c031000, 0xaf4601c0,
- 0xa34201c4, 0x03e00008, 0xaf4301f8, 0x8f430238, 0x3c020800, 0x04610013,
- 0x8c44009c, 0x2406fffe, 0x3c050800, 0x3c038000, 0x2484ffff, 0x14800009,
- 0x00000000, 0x97420078, 0x8ca3007c, 0x24420001, 0x00461024, 0x24630001,
- 0xa7620010, 0x03e00008, 0xaca3007c, 0x8f420238, 0x00431024, 0x1440fff3,
- 0x2484ffff, 0x8f420140, 0x3c031000, 0xaf420200, 0x03e00008, 0xaf430238,
- 0x3c029000, 0x8f440140, 0x34420001, 0x3c038000, 0x00821025, 0xaf420020,
- 0x8f420020, 0x00431024, 0x1440fffd, 0x00000000, 0x3c038000, 0x9362007d,
- 0x34630001, 0x3c058000, 0x00831825, 0x34420001, 0xa362007d, 0xaf430020,
- 0x8f4201f8, 0x00451024, 0x1440fffd, 0x24020002, 0x3c031000, 0xaf4401c0,
- 0xa34201c4, 0x03e00008, 0xaf4301f8, 0x0000000d, 0x03e00008, 0x00000000,
- 0x0000000d, 0x03e00008, 0x00000000, 0x24020001, 0x03e00008, 0xa7620010,
- 0x9362003f, 0x304400ff, 0x3883000e, 0x2c630001, 0x38820010, 0x2c420001,
- 0x00621825, 0x14600003, 0x24020012, 0x14820003, 0x00000000, 0x03e00008,
- 0x00001021, 0x9363007e, 0x9362007a, 0x14620006, 0x00000000, 0x9363007e,
- 0x24020001, 0x24630001, 0x03e00008, 0xa363007e, 0x9363007e, 0x93620080,
- 0x14620004, 0x24020001, 0xa362000b, 0x03e00008, 0x24020001, 0x03e00008,
- 0x00001021, 0x9362000b, 0x10400021, 0x00001021, 0xa360000b, 0x9362003f,
- 0x304400ff, 0x3883000e, 0x2c630001, 0x38820010, 0x2c420001, 0x00621825,
- 0x14600015, 0x00001821, 0x24020012, 0x10820012, 0x00000000, 0x9363007e,
- 0x9362007a, 0x14620007, 0x00000000, 0x9362007e, 0x24030001, 0x24420001,
- 0xa362007e, 0x03e00008, 0x00601021, 0x9363007e, 0x93620080, 0x14620004,
- 0x00001821, 0x24020001, 0xa362000b, 0x24030001, 0x03e00008, 0x00601021,
- 0x03e00008, 0x00000000, 0x24040001, 0xaf64000c, 0x8f6300dc, 0x8f6200cc,
- 0x50620001, 0xa7640010, 0xa7640012, 0xa7640014, 0x03e00008, 0xa7640016,
- 0x27bdffd8, 0xafb00010, 0x00808021, 0xafb3001c, 0x00c09821, 0xafbf0020,
- 0xafb20018, 0xafb10014, 0x93620023, 0x00e09021, 0x30420040, 0x10400020,
- 0x30b1ffff, 0x3c020800, 0x8c430020, 0x1060001c, 0x00000000, 0x0e001006,
- 0x00000000, 0x8f820018, 0xac500000, 0x8f840018, 0x3c02008d, 0xac820004,
- 0x8f830018, 0xac600008, 0x8f820018, 0xac40000c, 0x8f830018, 0xac600010,
- 0x8f820018, 0xac520014, 0x8f850018, 0x3c026000, 0x8c434448, 0x24040001,
- 0x3c020800, 0xaca30018, 0x9443466e, 0x8f850018, 0x3c024019, 0x00621825,
- 0x0e001044, 0xaca3001c, 0x93620023, 0x30420020, 0x14400003, 0x3c020800,
- 0x52600020, 0x3c029000, 0x8c430020, 0x1060001d, 0x3c029000, 0x0e001006,
- 0x00000000, 0x8f820018, 0xac500000, 0x8f840018, 0x00111400, 0xac820004,
- 0x8f830018, 0xac720008, 0x8f820018, 0xac40000c, 0x8f830018, 0xac600010,
- 0x8f820018, 0xac400014, 0x8f850018, 0x3c026000, 0x8c434448, 0x24040001,
- 0x3c020800, 0xaca30018, 0x9443466e, 0x8f850018, 0x3c02401b, 0x00621825,
- 0x0e001044, 0xaca3001c, 0x3c029000, 0x34420001, 0x02021025, 0xaf420020,
- 0x3c038000, 0x8f420020, 0x00431024, 0x1440fffd, 0x00000000, 0x93630023,
- 0x3c028000, 0x34420001, 0x02021025, 0x8fbf0020, 0x8fb3001c, 0x8fb20018,
- 0x8fb10014, 0x8fb00010, 0x3063009f, 0xa3630023, 0xaf420020, 0x03e00008,
- 0x27bd0028, 0x3c020800, 0x8c430020, 0x27bdffe8, 0xafb00010, 0x27500100,
- 0x1060001d, 0xafbf0014, 0x0e001006, 0x00000000, 0x8f830018, 0x8e020004,
- 0xac620000, 0x8f840018, 0x8e020018, 0xac820004, 0x8f850018, 0x8e020000,
- 0xaca20008, 0x8f830018, 0xac60000c, 0x8f820018, 0xac400010, 0x8f830018,
- 0xac600014, 0x8f820018, 0xac400018, 0x96030008, 0x3c020800, 0x9444466e,
- 0x8f850018, 0x00031c00, 0x00641825, 0x24040001, 0x0e001044, 0xaca3001c,
- 0x8fbf0014, 0x8fb00010, 0x03e00008, 0x27bd0018, 0x3c060800, 0x24c54660,
- 0x3c02000a, 0x03421821, 0x94640006, 0x94a2000a, 0x00441023, 0x00021400,
- 0x00021c03, 0x04610006, 0xa4a40006, 0x0000000d, 0x00000000, 0x2400005a,
- 0x0a00101b, 0x24020001, 0x8f820014, 0x0062102b, 0x14400002, 0x00001021,
- 0x24020001, 0x304200ff, 0x1040001c, 0x274a0400, 0x3c07000a, 0x3c020800,
- 0x24454660, 0x94a9000a, 0x8f880014, 0x03471021, 0x94430006, 0x00402021,
- 0xa4a30006, 0x94820006, 0xa4a20006, 0x01221023, 0x00021400, 0x00021403,
- 0x04410006, 0x0048102b, 0x0000000d, 0x00000000, 0x2400005a, 0x0a001036,
- 0x24020001, 0x14400002, 0x00001021, 0x24020001, 0x304200ff, 0x1440ffec,
- 0x03471021, 0x24c44660, 0x8c820010, 0xaf420038, 0x8c830014, 0x3c020005,
- 0xaf43003c, 0xaf420030, 0xaf800010, 0xaf8a0018, 0x03e00008, 0x00000000,
- 0x27bdffe0, 0x8f820010, 0x8f850018, 0x3c070800, 0x24e84660, 0xafbf001c,
- 0xafb20018, 0xafb10014, 0xafb00010, 0x9503000a, 0x8d060014, 0x00009021,
- 0x309000ff, 0x00e08821, 0x24420001, 0x24a50020, 0x24630001, 0xaf820010,
- 0xaf850018, 0xa503000a, 0x24c30020, 0x3c028000, 0x04c10007, 0xad030014,
- 0x00621024, 0x14400005, 0x26224660, 0x8d020010, 0x24420001, 0xad020010,
- 0x26224660, 0x9444000a, 0x94450018, 0x0010102b, 0x00a41826, 0x2c630001,
- 0x00621825, 0x1060001c, 0x3c030006, 0x8f820010, 0x24120001, 0x00021140,
- 0x00431025, 0xaf420030, 0x00000000, 0x00000000, 0x00000000, 0x27450400,
- 0x8f420000, 0x30420010, 0x1040fffd, 0x26224660, 0x9444000a, 0x94430018,
- 0xaf800010, 0xaf850018, 0x14830012, 0x26274660, 0x0e0010d2, 0x00000000,
- 0x1600000e, 0x26274660, 0x0e001006, 0x00000000, 0x0a00108f, 0x26274660,
- 0x00041c00, 0x00031c03, 0x00051400, 0x00021403, 0x00621823, 0x18600002,
- 0x3c026000, 0xac400808, 0x26274660, 0x94e2000e, 0x94e3000c, 0x24420001,
- 0xa4e2000e, 0x3042ffff, 0x50430001, 0xa4e0000e, 0x12000005, 0x3c02000a,
- 0x94e2000a, 0xa74200a2, 0x0a0010cc, 0x02401021, 0x03421821, 0x94640006,
- 0x94e2000a, 0x00441023, 0x00021400, 0x00021c03, 0x04610006, 0xa4e40006,
- 0x0000000d, 0x00000000, 0x2400005a, 0x0a0010ae, 0x24020001, 0x8f820014,
- 0x0062102b, 0x14400002, 0x00001021, 0x24020001, 0x304200ff, 0x1040001b,
- 0x3c020800, 0x3c06000a, 0x24454660, 0x94a8000a, 0x8f870014, 0x03461021,
- 0x94430006, 0x00402021, 0xa4a30006, 0x94820006, 0xa4a20006, 0x01021023,
- 0x00021400, 0x00021403, 0x04410006, 0x0047102b, 0x0000000d, 0x00000000,
- 0x2400005a, 0x0a0010c8, 0x24020001, 0x14400002, 0x00001021, 0x24020001,
- 0x304200ff, 0x1440ffec, 0x03461021, 0x02401021, 0x8fbf001c, 0x8fb20018,
- 0x8fb10014, 0x8fb00010, 0x03e00008, 0x27bd0020, 0x3c020800, 0x24454660,
- 0x94a3001a, 0x8ca40024, 0x00403021, 0x000318c0, 0x00832021, 0xaf44003c,
- 0x8ca20020, 0xaf420038, 0x3c020050, 0x34420008, 0xaf420030, 0x00000000,
- 0x00000000, 0x00000000, 0x8f420000, 0x30420020, 0x1040fffd, 0x00000000,
- 0x8f430400, 0x24c64660, 0xacc30010, 0x8f420404, 0x3c030020, 0xacc20014,
- 0xaf430030, 0x94c40018, 0x94c3001c, 0x94c2001a, 0x94c5001e, 0x00832021,
- 0x24420001, 0xa4c2001a, 0x3042ffff, 0x14450002, 0xa4c40018, 0xa4c0001a,
- 0x03e00008, 0x00000000, 0x8f820010, 0x3c030006, 0x00021140, 0x00431025,
- 0xaf420030, 0x00000000, 0x00000000, 0x00000000, 0x27430400, 0x8f420000,
- 0x30420010, 0x1040fffd, 0x00000000, 0xaf800010, 0xaf830018, 0x03e00008,
- 0x00000000, 0x27bdffe8, 0xafb00010, 0x3c100800, 0x26104660, 0x3c05000a,
- 0x02002021, 0x03452821, 0xafbf0014, 0x0e001128, 0x2406000a, 0x96020002,
- 0x9603001e, 0x3042000f, 0x24420003, 0x00431804, 0x24027fff, 0x0043102b,
- 0xaf830014, 0x10400004, 0x00000000, 0x0000000d, 0x00000000, 0x24000043,
- 0x0e0010d2, 0x00000000, 0x8fbf0014, 0x8fb00010, 0x03e00008, 0x27bd0018,
- 0x10c00007, 0x00000000, 0x8ca20000, 0x24c6ffff, 0x24a50004, 0xac820000,
- 0x14c0fffb, 0x24840004, 0x03e00008, 0x00000000, 0x0a001137, 0x00a01021,
- 0xac860000, 0x24840004, 0x00a01021, 0x1440fffc, 0x24a5ffff, 0x03e00008,
- 0x00000000, 0x3c036000, 0x8c642b7c, 0x3c036010, 0x8c6553fc, 0x00041582,
- 0x00042302, 0x308403ff, 0x00052d82, 0x00441026, 0x0002102b, 0x0005282b,
- 0x00451025, 0x1440000d, 0x3c020050, 0x34420004, 0xaf400038, 0xaf40003c,
- 0xaf420030, 0x00000000, 0x00000000, 0x8f420000, 0x30420020, 0x1040fffd,
- 0x3c020020, 0xaf420030, 0x0000000d, 0x03e00008, 0x00000000, 0x3c020050,
- 0x34420004, 0xaf440038, 0xaf45003c, 0xaf420030, 0x00000000, 0x00000000,
- 0x8f420000, 0x30420020, 0x1040fffd, 0x3c020020, 0xaf420030, 0x03e00008,
- 0x00000000, 0x00000000 };
-
-static u32 bnx2_COM_b06FwData[(0x0/4) + 1] = { 0x00000000 };
-static u32 bnx2_COM_b06FwRodata[(0x18/4) + 1] = {
- 0x08002318, 0x08002348, 0x08002378, 0x080023a8, 0x080023d8, 0x00000000,
- 0x00000000 };
+ 0x8f420020, 0x00451024, 0x1440fffd, 0x00000000, 0x9362007d, 0x3c038000,
+ 0x34420020, 0xa362007d, 0x8f640074, 0x34630001, 0x00c31825, 0xaf430020,
+ 0x04810006, 0x3c038000, 0x00c02021, 0x0e000470, 0x24050906, 0x0a0012a1,
+ 0x8fbf0010, 0x8f4201f8, 0x00431024, 0x1440fffd, 0x24020002, 0x3c031000,
+ 0xaf4601c0, 0xa34201c4, 0xaf4301f8, 0x0a0012a1, 0x8fbf0010, 0x00c02021,
+ 0x94a5000c, 0x24060001, 0x0e000fb1, 0x2407090e, 0x8fbf0010, 0x03e00008,
+ 0x27bd0018, 0x3c020800, 0x8c430020, 0x27bdffe0, 0xafb00010, 0x00808021,
+ 0xafb20018, 0x00a09021, 0xafb10014, 0x30d100ff, 0x1060001c, 0xafbf001c,
+ 0x0e00148e, 0x00000000, 0x8f820018, 0xac500000, 0x8f840018, 0x24020001,
+ 0xac820004, 0x8f830018, 0xac600008, 0x8f820018, 0xac40000c, 0x8f830018,
+ 0xac600010, 0x8f820018, 0xac520014, 0x8f840018, 0x3c026000, 0x8c434448,
+ 0x3c020800, 0xac830018, 0x944358ce, 0x8f840018, 0x3c024010, 0x00621825,
+ 0xac83001c, 0x0e0014cc, 0x02202021, 0x8fbf001c, 0x8fb20018, 0x8fb10014,
+ 0x8fb00010, 0x03e00008, 0x27bd0020, 0x27bdffe8, 0xafbf0014, 0xafb00010,
+ 0x93620005, 0x30420001, 0x10400036, 0x00808021, 0x3c029000, 0x34420001,
+ 0x02021025, 0xaf420020, 0x3c038000, 0x8f420020, 0x00431024, 0x1440fffd,
+ 0x00000000, 0x93620023, 0x34420004, 0xa3620023, 0x93630005, 0x3c048000,
+ 0x3c020800, 0x306300fe, 0xa3630005, 0x8c430020, 0x34840001, 0x02042025,
+ 0xaf440020, 0x10600020, 0x8fbf0014, 0x0e00148e, 0x00000000, 0x8f820018,
+ 0xac500000, 0x93630082, 0x9362003f, 0x8f840018, 0x00031a00, 0x00431025,
+ 0xac820004, 0x8f830018, 0xac600008, 0x8f820018, 0xac40000c, 0x8f830018,
+ 0xac600010, 0x8f820018, 0xac400014, 0x8f840018, 0x3c026000, 0x8c434448,
+ 0x3c020800, 0xac830018, 0x944358ce, 0x8f840018, 0x3c02400a, 0x00621825,
+ 0xac83001c, 0x0e0014cc, 0x24040001, 0x8fbf0014, 0x8fb00010, 0x03e00008,
+ 0x27bd0018, 0x3c020800, 0x8c430020, 0x27bdffe0, 0xafb10014, 0x00808821,
+ 0xafb20018, 0x00a09021, 0xafb00010, 0x30d000ff, 0x1060002f, 0xafbf001c,
+ 0x0e00148e, 0x00000000, 0x8f820018, 0xac510000, 0x8f830018, 0xac700004,
+ 0x8f820018, 0xac520008, 0x8f830018, 0xac60000c, 0x8f820018, 0xac400010,
+ 0x9763006a, 0x00032880, 0x50a00001, 0x24050001, 0x97630068, 0x93640081,
+ 0x3c020800, 0x8c46004c, 0x00652821, 0x00852804, 0x00c5102b, 0x54400001,
+ 0x00a03021, 0x3c020800, 0x8c440050, 0x00c4182b, 0x54600001, 0x00c02021,
+ 0x8f830018, 0x2402fffe, 0x00822824, 0x3c026000, 0xac650014, 0x8f840018,
+ 0x8c434448, 0x3c020800, 0xac830018, 0x944358ce, 0x8f840018, 0x3c024011,
+ 0x00621825, 0xac83001c, 0x0e0014cc, 0x24040001, 0x8fbf001c, 0x8fb20018,
+ 0x8fb10014, 0x8fb00010, 0x03e00008, 0x27bd0020, 0x27bdffe8, 0xafbf0014,
+ 0xafb00010, 0x8f440100, 0x27500100, 0x8f650050, 0x0e0010fc, 0x9206001b,
+ 0x3c020800, 0x8c430020, 0x1060001d, 0x8e100018, 0x0e00148e, 0x00000000,
+ 0x8f840018, 0x8f420100, 0xac820000, 0x8f830018, 0xac700004, 0x8f840018,
+ 0x8f620050, 0xac820008, 0x8f830018, 0xac60000c, 0x8f820018, 0xac400010,
+ 0x8f830018, 0x3c026000, 0xac600014, 0x8f850018, 0x8c434448, 0x24040001,
+ 0x3c020800, 0xaca30018, 0x944358ce, 0x8f850018, 0x3c02401c, 0x00621825,
+ 0x0e0014cc, 0xaca3001c, 0x8fbf0014, 0x8fb00010, 0x03e00008, 0x27bd0018,
+ 0x8f430238, 0x3c020800, 0x04610013, 0x8c44009c, 0x2406fffe, 0x3c050800,
+ 0x3c038000, 0x2484ffff, 0x14800009, 0x00000000, 0x97420078, 0x8ca3007c,
+ 0x24420001, 0x00461024, 0x24630001, 0xa7620010, 0x03e00008, 0xaca3007c,
+ 0x8f420238, 0x00431024, 0x1440fff3, 0x2484ffff, 0x8f420140, 0x3c031000,
+ 0xaf420200, 0x03e00008, 0xaf430238, 0x27bdffe8, 0x3c029000, 0xafbf0010,
+ 0x8f450140, 0x34420001, 0x3c038000, 0x00a21025, 0xaf420020, 0x8f420020,
+ 0x00431024, 0x1440fffd, 0x00000000, 0x9362007d, 0x3c038000, 0x34420001,
+ 0xa362007d, 0x8f640074, 0x34630001, 0x00a31825, 0xaf430020, 0x04810006,
+ 0x3c038000, 0x00a02021, 0x0e000470, 0x24050ac7, 0x0a0013b9, 0x8fbf0010,
+ 0x8f4201f8, 0x00431024, 0x1440fffd, 0x24020002, 0x3c031000, 0xaf4501c0,
+ 0xa34201c4, 0xaf4301f8, 0x8fbf0010, 0x03e00008, 0x27bd0018, 0x0000000d,
+ 0x03e00008, 0x00000000, 0x0000000d, 0x03e00008, 0x00000000, 0x24020001,
+ 0x03e00008, 0xa7620010, 0x9362003f, 0x304400ff, 0x3883000e, 0x2c630001,
+ 0x38820010, 0x2c420001, 0x00621825, 0x14600003, 0x24020012, 0x14820003,
+ 0x00000000, 0x03e00008, 0x00001021, 0x9363007e, 0x9362007a, 0x14620006,
+ 0x00000000, 0x9363007e, 0x24020001, 0x24630001, 0x03e00008, 0xa363007e,
+ 0x9362007e, 0x8f630178, 0x304200ff, 0x14430006, 0x00000000, 0x9363000b,
+ 0x24020001, 0x24630001, 0x03e00008, 0xa363000b, 0x03e00008, 0x00001021,
+ 0x9362000b, 0x10400023, 0x00001021, 0xa360000b, 0x9362003f, 0x304400ff,
+ 0x3883000e, 0x2c630001, 0x38820010, 0x2c420001, 0x00621825, 0x14600017,
+ 0x00001821, 0x24020012, 0x10820014, 0x00000000, 0x9363007e, 0x9362007a,
+ 0x14620007, 0x00000000, 0x9362007e, 0x24030001, 0x24420001, 0xa362007e,
+ 0x03e00008, 0x00601021, 0x9362007e, 0x8f630178, 0x304200ff, 0x14430005,
+ 0x00001821, 0x9362000b, 0x24030001, 0x24420001, 0xa362000b, 0x03e00008,
+ 0x00601021, 0x03e00008, 0x00000000, 0x24040001, 0xaf64000c, 0x8f6300dc,
+ 0x8f6200cc, 0x50620001, 0xa7640010, 0xa7640012, 0xa7640014, 0x03e00008,
+ 0xa7640016, 0x3c020800, 0x8c430020, 0x27bdffe8, 0x1060001b, 0xafbf0010,
+ 0x0e00148e, 0x00000000, 0x8f820018, 0xac400000, 0x8f830018, 0xac600004,
+ 0x8f820018, 0xac400008, 0x8f830018, 0xac60000c, 0x8f820018, 0xac400010,
+ 0x8f830018, 0x3c026000, 0xac600014, 0x8f840018, 0x8c434448, 0x3c020800,
+ 0xac830018, 0x944358ce, 0x8f840018, 0x3c024020, 0x00621825, 0xac83001c,
+ 0x0e0014cc, 0x24040001, 0x8fbf0010, 0x03e00008, 0x27bd0018, 0x3c020800,
+ 0x8c430020, 0x27bdffe0, 0xafb00010, 0x00a08021, 0xafb10014, 0x00c08821,
+ 0xafb20018, 0x00e09021, 0x1060001e, 0xafbf001c, 0x0e00148e, 0x00000000,
+ 0x8f840018, 0x8f420100, 0xac820000, 0x8f830018, 0xac700004, 0x8f820018,
+ 0xac510008, 0x8f830018, 0xac72000c, 0x8f840018, 0x8fa20030, 0xac820010,
+ 0x8f830018, 0x8fa20034, 0xac620014, 0x8f840018, 0x3c026000, 0x8c434448,
+ 0x3c020800, 0xac830018, 0x944358ce, 0x8f840018, 0x3c0240c9, 0x00621825,
+ 0xac83001c, 0x0e0014cc, 0x24040001, 0x8fbf001c, 0x8fb20018, 0x8fb10014,
+ 0x8fb00010, 0x03e00008, 0x27bd0020, 0x3c020800, 0x8c430020, 0x27bdffe8,
+ 0xafb00010, 0x27500100, 0x1060001d, 0xafbf0014, 0x0e00148e, 0x00000000,
+ 0x8f830018, 0x8e020004, 0xac620000, 0x8f840018, 0x8e020018, 0xac820004,
+ 0x8f850018, 0x8e020000, 0xaca20008, 0x8f830018, 0xac60000c, 0x8f820018,
+ 0xac400010, 0x8f830018, 0xac600014, 0x8f820018, 0xac400018, 0x96030008,
+ 0x3c020800, 0x944458ce, 0x8f850018, 0x00031c00, 0x00641825, 0x24040001,
+ 0x0e0014cc, 0xaca3001c, 0x8fbf0014, 0x8fb00010, 0x03e00008, 0x27bd0018,
+ 0x3c060800, 0x24c558c0, 0x3c02000a, 0x03421821, 0x94640006, 0x94a2000a,
+ 0x00441023, 0x00021400, 0x00021c03, 0x04610006, 0xa4a40006, 0x0000000d,
+ 0x00000000, 0x2400005a, 0x0a0014a3, 0x24020001, 0x8f820014, 0x0062102b,
+ 0x14400002, 0x00001021, 0x24020001, 0x304200ff, 0x1040001c, 0x274a0400,
+ 0x3c07000a, 0x3c020800, 0x244558c0, 0x94a9000a, 0x8f880014, 0x03471021,
+ 0x94430006, 0x00402021, 0xa4a30006, 0x94820006, 0xa4a20006, 0x01221023,
+ 0x00021400, 0x00021403, 0x04410006, 0x0048102b, 0x0000000d, 0x00000000,
+ 0x2400005a, 0x0a0014be, 0x24020001, 0x14400002, 0x00001021, 0x24020001,
+ 0x304200ff, 0x1440ffec, 0x03471021, 0x24c458c0, 0x8c820010, 0xaf420038,
+ 0x8c830014, 0x3c020005, 0xaf43003c, 0xaf420030, 0xaf800010, 0xaf8a0018,
+ 0x03e00008, 0x00000000, 0x27bdffe0, 0x8f820010, 0x8f850018, 0x3c070800,
+ 0x24e858c0, 0xafbf001c, 0xafb20018, 0xafb10014, 0xafb00010, 0x9503000a,
+ 0x8d060014, 0x00009021, 0x309000ff, 0x00e08821, 0x24420001, 0x24a50020,
+ 0x24630001, 0xaf820010, 0xaf850018, 0xa503000a, 0x24c30020, 0x3c028000,
+ 0x04c10007, 0xad030014, 0x00621024, 0x14400005, 0x262258c0, 0x8d020010,
+ 0x24420001, 0xad020010, 0x262258c0, 0x9444000a, 0x94450018, 0x0010102b,
+ 0x00a41826, 0x2c630001, 0x00621825, 0x1060001c, 0x3c030006, 0x8f820010,
+ 0x24120001, 0x00021140, 0x00431025, 0xaf420030, 0x00000000, 0x00000000,
+ 0x00000000, 0x27450400, 0x8f420000, 0x30420010, 0x1040fffd, 0x262258c0,
+ 0x9444000a, 0x94430018, 0xaf800010, 0xaf850018, 0x14830012, 0x262758c0,
+ 0x0e00155a, 0x00000000, 0x1600000e, 0x262758c0, 0x0e00148e, 0x00000000,
+ 0x0a001517, 0x262758c0, 0x00041c00, 0x00031c03, 0x00051400, 0x00021403,
+ 0x00621823, 0x18600002, 0x3c026000, 0xac400808, 0x262758c0, 0x94e2000e,
+ 0x94e3000c, 0x24420001, 0xa4e2000e, 0x3042ffff, 0x50430001, 0xa4e0000e,
+ 0x12000005, 0x3c02000a, 0x94e2000a, 0xa74200a2, 0x0a001554, 0x02401021,
+ 0x03421821, 0x94640006, 0x94e2000a, 0x00441023, 0x00021400, 0x00021c03,
+ 0x04610006, 0xa4e40006, 0x0000000d, 0x00000000, 0x2400005a, 0x0a001536,
+ 0x24020001, 0x8f820014, 0x0062102b, 0x14400002, 0x00001021, 0x24020001,
+ 0x304200ff, 0x1040001b, 0x3c020800, 0x3c06000a, 0x244558c0, 0x94a8000a,
+ 0x8f870014, 0x03461021, 0x94430006, 0x00402021, 0xa4a30006, 0x94820006,
+ 0xa4a20006, 0x01021023, 0x00021400, 0x00021403, 0x04410006, 0x0047102b,
+ 0x0000000d, 0x00000000, 0x2400005a, 0x0a001550, 0x24020001, 0x14400002,
+ 0x00001021, 0x24020001, 0x304200ff, 0x1440ffec, 0x03461021, 0x02401021,
+ 0x8fbf001c, 0x8fb20018, 0x8fb10014, 0x8fb00010, 0x03e00008, 0x27bd0020,
+ 0x3c020800, 0x244558c0, 0x94a3001a, 0x8ca40024, 0x00403021, 0x000318c0,
+ 0x00832021, 0xaf44003c, 0x8ca20020, 0xaf420038, 0x3c020050, 0x34420008,
+ 0xaf420030, 0x00000000, 0x00000000, 0x00000000, 0x8f420000, 0x30420020,
+ 0x1040fffd, 0x00000000, 0x8f430400, 0x24c658c0, 0xacc30010, 0x8f420404,
+ 0x3c030020, 0xacc20014, 0xaf430030, 0x94c40018, 0x94c3001c, 0x94c2001a,
+ 0x94c5001e, 0x00832021, 0x24420001, 0xa4c2001a, 0x3042ffff, 0x14450002,
+ 0xa4c40018, 0xa4c0001a, 0x03e00008, 0x00000000, 0x8f820010, 0x3c030006,
+ 0x00021140, 0x00431025, 0xaf420030, 0x00000000, 0x00000000, 0x00000000,
+ 0x27430400, 0x8f420000, 0x30420010, 0x1040fffd, 0x00000000, 0xaf800010,
+ 0xaf830018, 0x03e00008, 0x00000000, 0x27bdffe8, 0xafb00010, 0x3c100800,
+ 0x261058c0, 0x3c05000a, 0x02002021, 0x03452821, 0xafbf0014, 0x0e0015b0,
+ 0x2406000a, 0x96020002, 0x9603001e, 0x3042000f, 0x24420003, 0x00431804,
+ 0x24027fff, 0x0043102b, 0xaf830014, 0x10400004, 0x00000000, 0x0000000d,
+ 0x00000000, 0x24000043, 0x0e00155a, 0x00000000, 0x8fbf0014, 0x8fb00010,
+ 0x03e00008, 0x27bd0018, 0x10c00007, 0x00000000, 0x8ca20000, 0x24c6ffff,
+ 0x24a50004, 0xac820000, 0x14c0fffb, 0x24840004, 0x03e00008, 0x00000000,
+ 0x0a0015c1, 0x00a01021, 0xac860000, 0x00000000, 0x00000000, 0x24840004,
+ 0x00a01021, 0x1440fffa, 0x24a5ffff, 0x03e00008, 0x00000000, 0x3c036000,
+ 0x8c642b7c, 0x3c036010, 0x8c6553fc, 0x00041582, 0x00042302, 0x308403ff,
+ 0x00052d82, 0x00441026, 0x0002102b, 0x0005282b, 0x00451025, 0x1440000d,
+ 0x3c020050, 0x34420004, 0xaf400038, 0xaf40003c, 0xaf420030, 0x00000000,
+ 0x00000000, 0x8f420000, 0x30420020, 0x1040fffd, 0x3c020020, 0xaf420030,
+ 0x0000000d, 0x03e00008, 0x00000000, 0x3c020050, 0x34420004, 0xaf440038,
+ 0xaf45003c, 0xaf420030, 0x00000000, 0x00000000, 0x8f420000, 0x30420020,
+ 0x1040fffd, 0x3c020020, 0xaf420030, 0x03e00008, 0x00000000, 0x00000000};
-static u32 bnx2_COM_b06FwBss[(0x88/4) + 1] = { 0x00000000 };
-static u32 bnx2_COM_b06FwSbss[(0x1c/4) + 1] = { 0x00000000 };
+static u32 bnx2_COM_b06FwData[(0x0/4) + 1] = { 0x0 };
+static u32 bnx2_COM_b06FwRodata[(0x58/4) + 1] = {
+ 0x08002428, 0x0800245c, 0x0800245c, 0x0800245c, 0x0800245c, 0x0800245c,
+ 0x08002380, 0x0800245c, 0x080023e4, 0x0800245c, 0x0800231c, 0x0800245c,
+ 0x0800245c, 0x0800245c, 0x08002328, 0x00000000, 0x08003240, 0x08003270,
+ 0x080032a0, 0x080032d0, 0x08003300, 0x00000000, 0x00000000 };
+static u32 bnx2_COM_b06FwBss[(0x88/4) + 1] = { 0x0 };
+static u32 bnx2_COM_b06FwSbss[(0x1c/4) + 1] = { 0x0 };
-static int bnx2_RXP_b06FwReleaseMajor = 0x0;
+static int bnx2_RXP_b06FwReleaseMajor = 0x1;
static int bnx2_RXP_b06FwReleaseMinor = 0x0;
static int bnx2_RXP_b06FwReleaseFix = 0x0;
-static u32 bnx2_RXP_b06FwStartAddr = 0x08000060;
+static u32 bnx2_RXP_b06FwStartAddr = 0x08003104;
static u32 bnx2_RXP_b06FwTextAddr = 0x08000000;
-static int bnx2_RXP_b06FwTextLen = 0x20b8;
-static u32 bnx2_RXP_b06FwDataAddr = 0x080020e0;
+static int bnx2_RXP_b06FwTextLen = 0x562c;
+static u32 bnx2_RXP_b06FwDataAddr = 0x08005660;
static int bnx2_RXP_b06FwDataLen = 0x0;
static u32 bnx2_RXP_b06FwRodataAddr = 0x00000000;
static int bnx2_RXP_b06FwRodataLen = 0x0;
-static u32 bnx2_RXP_b06FwBssAddr = 0x08002100;
-static int bnx2_RXP_b06FwBssLen = 0x239c;
-static u32 bnx2_RXP_b06FwSbssAddr = 0x080020e0;
-static int bnx2_RXP_b06FwSbssLen = 0x14;
-
-static u32 bnx2_RXP_b06FwText[(0x20b8/4) + 1] = {
- 0x0a000018, 0x00000000, 0x00000000, 0x0000000d, 0x72787020, 0x302e362e,
- 0x39000000, 0x00060903, 0x00000000, 0x0000000d, 0x00000000, 0x00000000,
+static u32 bnx2_RXP_b06FwBssAddr = 0x08005680;
+static int bnx2_RXP_b06FwBssLen = 0x1394;
+static u32 bnx2_RXP_b06FwSbssAddr = 0x08005660;
+static int bnx2_RXP_b06FwSbssLen = 0x18;
+static u32 bnx2_RXP_b06FwText[(0x562c/4) + 1] = {
+ 0x0a000c41, 0x00000000, 0x00000000, 0x0000000d, 0x72787020, 0x322e352e,
+ 0x38000000, 0x02050803, 0x00000000, 0x0000000d, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x10000003, 0x00000000, 0x0000000d, 0x0000000d, 0x3c020800,
- 0x244220e0, 0x3c030800, 0x2463449c, 0xac400000, 0x0043202b, 0x1480fffd,
- 0x24420004, 0x3c1d0800, 0x37bd3ffc, 0x03a0f021, 0x3c100800, 0x26100060,
- 0x3c1c0800, 0x279c20e0, 0x0e000329, 0x00000000, 0x0000000d, 0x8f870008,
- 0x2ce20080, 0x10400018, 0x3c030800, 0x24633490, 0x8f460100, 0x00072140,
- 0x00831021, 0xac460000, 0x8f450104, 0x00641021, 0xac450004, 0x8f460108,
- 0xac460008, 0x8f45010c, 0xac45000c, 0x8f460114, 0xac460010, 0x8f450118,
- 0xac450014, 0x8f460124, 0xac460018, 0x8f450128, 0x00641821, 0x24e20001,
- 0xaf820008, 0xac65001c, 0x03e00008, 0x00000000, 0x00804021, 0x8f830000,
- 0x24070001, 0x3c020001, 0x00621024, 0x10400037, 0x00603021, 0x9742010e,
- 0x3c038000, 0x3045ffff, 0x8f4201b8, 0x00431024, 0x1440fffd, 0x24020003,
- 0xa342018b, 0x8f840004, 0x24020080, 0x24030002, 0xaf420180, 0xa743018c,
- 0x10800005, 0xa745018e, 0x9743011c, 0x9742011e, 0x0a000069, 0x00021400,
- 0x9743011e, 0x9742011c, 0x00021400, 0x00621825, 0xaf4301a8, 0x8f84000c,
- 0x24020003, 0x30838000, 0x1060000d, 0xa7420188, 0x93420116, 0x304200fc,
- 0x005a1021, 0x24424004, 0x8c430000, 0x3063ffff, 0x14600005, 0x00000000,
- 0x3c02ffff, 0x34427fff, 0x00821024, 0xaf82000c, 0x9782000e, 0x9743010c,
- 0x8f440104, 0x3042bfff, 0x00031c00, 0x3084ffff, 0x00641825, 0xa74201a6,
- 0xaf4301ac, 0x3c021000, 0xaf4201b8, 0x03e00008, 0x00001021, 0x30c21000,
- 0x1040000f, 0x00000000, 0x9742010c, 0x3042fc00, 0x5440000b, 0x24070005,
- 0x3c021000, 0x00c21024, 0x10400007, 0x3c030dff, 0x3463ffff, 0x3c020e00,
- 0x00c21024, 0x0062182b, 0x54600001, 0x24070005, 0x8f82000c, 0x30434000,
- 0x10600016, 0x00404821, 0x3c020f00, 0x00c21024, 0x14400012, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x10000003, 0x00000000, 0x0000000d, 0x0000000d, 0x3c020800, 0x24425660,
+ 0x3c030800, 0x24636a14, 0xac400000, 0x0043202b, 0x1480fffd, 0x24420004,
+ 0x3c1d0800, 0x37bd7ffc, 0x03a0f021, 0x3c100800, 0x26103104, 0x3c1c0800,
+ 0x279c5660, 0x0e001035, 0x00000000, 0x0000000d, 0x3c080800, 0x8d023100,
+ 0x2c420080, 0x50400001, 0xad003100, 0x8d073100, 0x3c040800, 0x24840100,
+ 0x8f460100, 0x00071840, 0x00671821, 0x00031940, 0x00641021, 0xac460000,
+ 0x8f450104, 0x00831021, 0xac450004, 0x8f460108, 0xac460008, 0x8f45010c,
+ 0xac45000c, 0x8f460114, 0xac460010, 0x8f450118, 0xac450014, 0x8f460124,
+ 0xac460018, 0x8f450128, 0xac45001c, 0x8f464010, 0xac460020, 0x8f454014,
+ 0xac450024, 0x8f464018, 0xac460028, 0x8f45401c, 0xac45002c, 0x8f464020,
+ 0xac460030, 0x8f454024, 0xac450034, 0x8f464028, 0xac460038, 0x8f45402c,
+ 0xac45003c, 0x8f464030, 0xac460040, 0x8f454034, 0xac450044, 0x8f464038,
+ 0xac460048, 0x8f45403c, 0xac45004c, 0x8f464040, 0xac460050, 0x8f454044,
+ 0xac450054, 0x8f464048, 0xac460058, 0x8f45404c, 0x24e70001, 0x00402021,
+ 0xad073100, 0x03e00008, 0xac85005c, 0x8f820004, 0x9743010c, 0x00804821,
+ 0x00403021, 0x30421000, 0x10400010, 0x306affff, 0x30c20020, 0x1440000e,
+ 0x24070005, 0x3c021000, 0x00c21024, 0x10400009, 0x3c030dff, 0x3463ffff,
+ 0x3c020e00, 0x00c21024, 0x0062182b, 0x50600004, 0x24070001, 0x0a000cb1,
+ 0x3c020800, 0x24070001, 0x3c020800, 0x8c430034, 0x1460001d, 0x00405821,
+ 0x8f820010, 0x30424000, 0x1440001a, 0x3c020001, 0x3c021f01, 0x00c24024,
+ 0x3c031000, 0x15030015, 0x3c020001, 0x31420200, 0x54400012, 0x3c020001,
+ 0x9744010e, 0x24020003, 0xa342018b, 0x97850012, 0x24020002, 0x34e30002,
+ 0xaf400180, 0xa742018c, 0xa7430188, 0x24840004, 0x30a5bfff, 0xa744018e,
+ 0xa74501a6, 0xaf4801b8, 0x03e00008, 0x00001021, 0x3c020001, 0x00c21024,
+ 0x10400039, 0x00000000, 0x9742010e, 0x3c038000, 0x3046ffff, 0x8f4201b8,
+ 0x00431024, 0x1440fffd, 0x24020003, 0xa342018b, 0x97840006, 0x8f85000c,
+ 0x24020080, 0x24030002, 0xaf420180, 0xa743018c, 0xa746018e, 0x10a00005,
+ 0xa7440190, 0x9743011c, 0x9742011e, 0x0a000cec, 0x00021400, 0x9743011e,
+ 0x9742011c, 0x00021400, 0x00621825, 0xaf4301a8, 0x8f840010, 0x24020003,
+ 0x30838000, 0x1060000d, 0xa7420188, 0x93420116, 0x304200fc, 0x005a1021,
+ 0x24424004, 0x8c430000, 0x3063ffff, 0x14600005, 0x00000000, 0x3c02ffff,
+ 0x34427fff, 0x00821024, 0xaf820010, 0x97820012, 0x9743010c, 0x8f440104,
+ 0x3042bfff, 0x00031c00, 0x3084ffff, 0x00641825, 0xa74201a6, 0xaf4301ac,
+ 0x3c021000, 0xaf4201b8, 0x03e00008, 0x00001021, 0x8f820010, 0x30434000,
+ 0x10600016, 0x00404021, 0x3c020f00, 0x00c21024, 0x14400012, 0x00000000,
0x93420116, 0x34424000, 0x03421821, 0x94650002, 0x2ca21389, 0x1040000b,
- 0x3c020800, 0x24422100, 0x00051942, 0x00031880, 0x00621821, 0x30a5001f,
- 0x8c640000, 0x24020001, 0x00a21004, 0x00822024, 0x01044025, 0x11000037,
- 0x3c021000, 0x9742010e, 0x34e60002, 0x3c038000, 0x24420004, 0x3045ffff,
- 0x8f4201b8, 0x00431024, 0x1440fffd, 0x24020003, 0xa342018b, 0x8f840004,
- 0x24020180, 0x24030002, 0xaf420180, 0xa743018c, 0x10800005, 0xa745018e,
- 0x9743011c, 0x9742011e, 0x0a0000cd, 0x00021400, 0x9743011e, 0x9742011c,
- 0x00021400, 0x00621825, 0xaf4301a8, 0x8f84000c, 0x30828000, 0x1040000c,
- 0xa7460188, 0x93420116, 0x304200fc, 0x005a1021, 0x24424004, 0x8c430000,
- 0x3063ffff, 0x14600004, 0x3c02ffff, 0x34427fff, 0x00821024, 0xaf82000c,
- 0x9782000e, 0x9743010c, 0x8f440104, 0x3042bfff, 0x00031c00, 0x3084ffff,
- 0x00641825, 0xa74201a6, 0xaf4301ac, 0x3c021000, 0xaf4201b8, 0x03e00008,
- 0x00001021, 0x00c21024, 0x104000ba, 0x3c020800, 0x8c430030, 0x1060003e,
- 0x31224000, 0x1040003c, 0x3c030f00, 0x00c31824, 0x3c020100, 0x0043102b,
- 0x14400038, 0x3c030800, 0x9742010e, 0x34e60002, 0x3c038000, 0x24420004,
- 0x3045ffff, 0x8f4201b8, 0x00431024, 0x1440fffd, 0x24020003, 0xa342018b,
- 0x8f840004, 0x24020080, 0x24030002, 0xaf420180, 0xa743018c, 0x10800005,
- 0xa745018e, 0x9743011c, 0x9742011e, 0x0a000110, 0x00021400, 0x9743011e,
- 0x9742011c, 0x00021400, 0x00621825, 0xaf4301a8, 0x8f84000c, 0x30828000,
- 0x1040000c, 0xa7460188, 0x93420116, 0x304200fc, 0x005a1021, 0x24424004,
- 0x8c430000, 0x3063ffff, 0x14600004, 0x3c02ffff, 0x34427fff, 0x00821024,
- 0xaf82000c, 0x9782000e, 0x9743010c, 0x8f440104, 0x3042bfff, 0x00031c00,
- 0x3084ffff, 0x00641825, 0xa74201a6, 0xaf4301ac, 0x3c021000, 0xaf4201b8,
- 0x03e00008, 0x00001021, 0x3c030800, 0x8c620024, 0x30420008, 0x1040003d,
- 0x34e80002, 0x3c020f00, 0x00c21024, 0x5440003a, 0x3107ffff, 0x9742010c,
- 0x30420200, 0x50400036, 0x3107ffff, 0x9742010e, 0x30e6fffb, 0x3c038000,
- 0x24420004, 0x3045ffff, 0x8f4201b8, 0x00431024, 0x1440fffd, 0x24020003,
- 0xa342018b, 0x8f840004, 0x24020180, 0x24030002, 0xaf420180, 0xa743018c,
- 0x10800005, 0xa745018e, 0x9743011c, 0x9742011e, 0x0a000153, 0x00021400,
- 0x9743011e, 0x9742011c, 0x00021400, 0x00621825, 0xaf4301a8, 0x8f84000c,
- 0x30828000, 0x1040000c, 0xa7460188, 0x93420116, 0x304200fc, 0x005a1021,
- 0x24424004, 0x8c430000, 0x3063ffff, 0x14600004, 0x3c02ffff, 0x34427fff,
- 0x00821024, 0xaf82000c, 0x9782000e, 0x9743010c, 0x8f440104, 0x3042bfff,
- 0x00031c00, 0x3084ffff, 0x00641825, 0xa74201a6, 0xaf4301ac, 0x3c021000,
- 0xaf4201b8, 0x3107ffff, 0x8f820000, 0x3c068000, 0x9743010e, 0x00021442,
- 0x30440780, 0x24630004, 0x3065ffff, 0x8f4201b8, 0x00461024, 0x1440fffd,
- 0x24020003, 0xa342018b, 0x8f830004, 0x24020002, 0xaf440180, 0xa742018c,
- 0x10600005, 0xa745018e, 0x9743011c, 0x9742011e, 0x0a000189, 0x00021400,
- 0x9743011e, 0x9742011c, 0x00021400, 0x00621825, 0xaf4301a8, 0x8f84000c,
+ 0x3c020800, 0x24425680, 0x00051942, 0x00031880, 0x00621821, 0x30a5001f,
+ 0x8c640000, 0x24020001, 0x00a21004, 0x00822024, 0x01244825, 0x11200039,
+ 0x3c021000, 0x9742010e, 0x34e70002, 0x3c038000, 0x24420004, 0x3046ffff,
+ 0x8f4201b8, 0x00431024, 0x1440fffd, 0x24020003, 0xa342018b, 0x97840006,
+ 0x8f85000c, 0x24020180, 0x24030002, 0xaf420180, 0xa743018c, 0xa746018e,
+ 0x10a00005, 0xa7440190, 0x9743011c, 0x9742011e, 0x0a000d41, 0x00021400,
+ 0x9743011e, 0x9742011c, 0x00021400, 0x00621825, 0xaf4301a8, 0x8f840010,
0x30828000, 0x1040000c, 0xa7470188, 0x93420116, 0x304200fc, 0x005a1021,
0x24424004, 0x8c430000, 0x3063ffff, 0x14600004, 0x3c02ffff, 0x34427fff,
- 0x00821024, 0xaf82000c, 0x9782000e, 0x9743010c, 0x8f440104, 0x3042bfff,
+ 0x00821024, 0xaf820010, 0x97820012, 0x9743010c, 0x8f440104, 0x3042bfff,
0x00031c00, 0x3084ffff, 0x00641825, 0xa74201a6, 0xaf4301ac, 0x3c021000,
- 0xaf4201b8, 0x03e00008, 0x00001021, 0x8f424000, 0x30420100, 0x104000ef,
- 0x3c020800, 0x8c440024, 0x24030001, 0x14830036, 0x00404021, 0x9742010e,
- 0x34e50002, 0x3c038000, 0x24420004, 0x3044ffff, 0x8f4201b8, 0x00431024,
- 0x1440fffd, 0x24020003, 0xa342018b, 0x8f830004, 0x24020002, 0xaf400180,
- 0xa742018c, 0x10600005, 0xa744018e, 0x9743011c, 0x9742011e, 0x0a0001c6,
+ 0xaf4201b8, 0x03e00008, 0x00001021, 0x00c21024, 0x104000e3, 0x3c020800,
+ 0x8c430030, 0x10600040, 0x31024000, 0x1040003e, 0x3c030f00, 0x00c31824,
+ 0x3c020100, 0x0043102b, 0x1440003a, 0x3c030800, 0x9742010e, 0x34e70002,
+ 0x3c038000, 0x24420004, 0x3046ffff, 0x8f4201b8, 0x00431024, 0x1440fffd,
+ 0x24020003, 0xa342018b, 0x97840006, 0x8f85000c, 0x24020080, 0x24030002,
+ 0xaf420180, 0xa743018c, 0xa746018e, 0x10a00005, 0xa7440190, 0x9743011c,
+ 0x9742011e, 0x0a000d86, 0x00021400, 0x9743011e, 0x9742011c, 0x00021400,
+ 0x00621825, 0xaf4301a8, 0x8f840010, 0x30828000, 0x1040000c, 0xa7470188,
+ 0x93420116, 0x304200fc, 0x005a1021, 0x24424004, 0x8c430000, 0x3063ffff,
+ 0x14600004, 0x3c02ffff, 0x34427fff, 0x00821024, 0xaf820010, 0x97820012,
+ 0x9743010c, 0x8f440104, 0x3042bfff, 0x00031c00, 0x3084ffff, 0x00641825,
+ 0xa74201a6, 0xaf4301ac, 0x3c021000, 0xaf4201b8, 0x03e00008, 0x00001021,
+ 0x3c030800, 0x8c620024, 0x30420008, 0x1040003e, 0x34e80002, 0x3c020f00,
+ 0x00c21024, 0x1440003b, 0x8d620034, 0x31420200, 0x10400038, 0x8d620034,
+ 0x9742010e, 0x30e7fffb, 0x3c038000, 0x24420004, 0x3046ffff, 0x8f4201b8,
+ 0x00431024, 0x1440fffd, 0x24020003, 0xa342018b, 0x97840006, 0x8f85000c,
+ 0x24020180, 0x24030002, 0xaf420180, 0xa743018c, 0xa746018e, 0x10a00005,
+ 0xa7440190, 0x9743011c, 0x9742011e, 0x0a000dca, 0x00021400, 0x9743011e,
+ 0x9742011c, 0x00021400, 0x00621825, 0xaf4301a8, 0x8f840010, 0x30828000,
+ 0x1040000c, 0xa7470188, 0x93420116, 0x304200fc, 0x005a1021, 0x24424004,
+ 0x8c430000, 0x3063ffff, 0x14600004, 0x3c02ffff, 0x34427fff, 0x00821024,
+ 0xaf820010, 0x97820012, 0x9743010c, 0x8f440104, 0x3042bfff, 0x00031c00,
+ 0x3084ffff, 0x00641825, 0xa74201a6, 0xaf4301ac, 0x3c021000, 0xaf4201b8,
+ 0x8d620034, 0x8f860004, 0x1040001a, 0x30c20100, 0x10400018, 0x3c020f00,
+ 0x00c21024, 0x3c030200, 0x10430014, 0x00000000, 0x8f82000c, 0x10400004,
+ 0x00000000, 0x9742011c, 0x0a000df8, 0x3044ffff, 0x9742011e, 0x3044ffff,
+ 0x3c030800, 0x8c620038, 0x3c030800, 0x2463003c, 0x2442ffff, 0x00822024,
+ 0x00831821, 0x90620000, 0x24420004, 0x0a000e0d, 0x000229c0, 0x00000000,
+ 0x00061602, 0x3042000f, 0x000229c0, 0x3c04fc00, 0x00441021, 0x3c030300,
+ 0x0062182b, 0x50600001, 0x24050800, 0x9742010e, 0x3107ffff, 0x3c038000,
+ 0x24420004, 0x3046ffff, 0x8f4201b8, 0x00431024, 0x1440fffd, 0x24020003,
+ 0xa342018b, 0x97830006, 0x8f84000c, 0x24020002, 0xaf450180, 0xa742018c,
+ 0xa746018e, 0x10800005, 0xa7430190, 0x9743011c, 0x9742011e, 0x0a000e26,
0x00021400, 0x9743011e, 0x9742011c, 0x00021400, 0x00621825, 0xaf4301a8,
- 0x8f84000c, 0x30828000, 0x1040000c, 0xa7450188, 0x93420116, 0x304200fc,
+ 0x8f840010, 0x30828000, 0x1040000c, 0xa7470188, 0x93420116, 0x304200fc,
0x005a1021, 0x24424004, 0x8c430000, 0x3063ffff, 0x14600004, 0x3c02ffff,
- 0x34427fff, 0x00821024, 0xaf82000c, 0x9782000e, 0x9743010c, 0x8f440104,
+ 0x34427fff, 0x00821024, 0xaf820010, 0x97820012, 0x9743010c, 0x8f440104,
0x3042bfff, 0x00031c00, 0x3084ffff, 0x00641825, 0xa74201a6, 0xaf4301ac,
- 0x3c021000, 0xaf4201b8, 0x03e00008, 0x00001021, 0x30820001, 0x10400035,
- 0x30e90004, 0x9742010e, 0x30e6fffb, 0x3c038000, 0x24420004, 0x3044ffff,
- 0x8f4201b8, 0x00431024, 0x1440fffd, 0x24020003, 0xa342018b, 0x8f830004,
- 0x24020002, 0xaf400180, 0xa742018c, 0x10600005, 0xa744018e, 0x9743011c,
- 0x9742011e, 0x0a0001fe, 0x00021400, 0x9743011e, 0x9742011c, 0x00021400,
- 0x00621825, 0xaf4301a8, 0x8f84000c, 0x30828000, 0x1040000c, 0xa7470188,
- 0x93420116, 0x304200fc, 0x005a1021, 0x24424004, 0x8c430000, 0x3063ffff,
- 0x14600004, 0x3c02ffff, 0x34427fff, 0x00821024, 0xaf82000c, 0x9782000e,
- 0x9743010c, 0x8f440104, 0x3042bfff, 0x00031c00, 0x3084ffff, 0x00641825,
- 0xa74201a6, 0xaf4301ac, 0x3c021000, 0xaf4201b8, 0x30c7ffff, 0x8d020024,
- 0x30420004, 0x10400037, 0x8d020024, 0x9742010e, 0x30e6fffb, 0x3c038000,
- 0x24420004, 0x3045ffff, 0x8f4201b8, 0x00431024, 0x1440fffd, 0x24020003,
- 0xa342018b, 0x8f840004, 0x24020100, 0x24030002, 0xaf420180, 0xa743018c,
- 0x10800005, 0xa745018e, 0x9743011c, 0x9742011e, 0x0a000237, 0x00021400,
- 0x9743011e, 0x9742011c, 0x00021400, 0x00621825, 0xaf4301a8, 0x8f84000c,
- 0x30828000, 0x1040000c, 0xa7470188, 0x93420116, 0x304200fc, 0x005a1021,
- 0x24424004, 0x8c430000, 0x3063ffff, 0x14600004, 0x3c02ffff, 0x34427fff,
- 0x00821024, 0xaf82000c, 0x9782000e, 0x9743010c, 0x8f440104, 0x3042bfff,
- 0x00031c00, 0x3084ffff, 0x00641825, 0xa74201a6, 0xaf4301ac, 0x3c021000,
- 0xaf4201b8, 0x30c7ffff, 0x8d020024, 0x30420008, 0x10400034, 0x00000000,
- 0x9742010e, 0x3c038000, 0x24420004, 0x3045ffff, 0x8f4201b8, 0x00431024,
- 0x1440fffd, 0x24020003, 0xa342018b, 0x8f840004, 0x24020180, 0x24030002,
- 0xaf420180, 0xa743018c, 0x10800005, 0xa745018e, 0x9743011c, 0x9742011e,
- 0x0a00026f, 0x00021400, 0x9743011e, 0x9742011c, 0x00021400, 0x00621825,
- 0xaf4301a8, 0x8f84000c, 0x30828000, 0x1040000c, 0xa7470188, 0x93420116,
+ 0x3c021000, 0xaf4201b8, 0x03e00008, 0x00001021, 0x8f424000, 0x30420100,
+ 0x104000f9, 0x3c020800, 0x8c440024, 0x24030001, 0x14830038, 0x00404821,
+ 0x9742010e, 0x34e60002, 0x3c038000, 0x24420004, 0x3045ffff, 0x8f4201b8,
+ 0x00431024, 0x1440fffd, 0x24020003, 0xa342018b, 0x97830006, 0x8f84000c,
+ 0x24020002, 0xaf400180, 0xa742018c, 0xa745018e, 0x10800005, 0xa7430190,
+ 0x9743011c, 0x9742011e, 0x0a000e65, 0x00021400, 0x9743011e, 0x9742011c,
+ 0x00021400, 0x00621825, 0xaf4301a8, 0x8f840010, 0x30828000, 0x1040000c,
+ 0xa7460188, 0x93420116, 0x304200fc, 0x005a1021, 0x24424004, 0x8c430000,
+ 0x3063ffff, 0x14600004, 0x3c02ffff, 0x34427fff, 0x00821024, 0xaf820010,
+ 0x97820012, 0x9743010c, 0x8f440104, 0x3042bfff, 0x00031c00, 0x3084ffff,
+ 0x00641825, 0xa74201a6, 0xaf4301ac, 0x3c021000, 0xaf4201b8, 0x03e00008,
+ 0x00001021, 0x30820001, 0x10400037, 0x30ea0004, 0x9742010e, 0x30e8fffb,
+ 0x3c038000, 0x24420004, 0x3045ffff, 0x8f4201b8, 0x00431024, 0x1440fffd,
+ 0x24020003, 0xa342018b, 0x97830006, 0x8f84000c, 0x24020002, 0xaf400180,
+ 0xa742018c, 0xa745018e, 0x10800005, 0xa7430190, 0x9743011c, 0x9742011e,
+ 0x0a000e9f, 0x00021400, 0x9743011e, 0x9742011c, 0x00021400, 0x00621825,
+ 0xaf4301a8, 0x8f840010, 0x30828000, 0x1040000c, 0xa7470188, 0x93420116,
0x304200fc, 0x005a1021, 0x24424004, 0x8c430000, 0x3063ffff, 0x14600004,
- 0x3c02ffff, 0x34427fff, 0x00821024, 0xaf82000c, 0x9782000e, 0x9743010c,
+ 0x3c02ffff, 0x34427fff, 0x00821024, 0xaf820010, 0x97820012, 0x9743010c,
0x8f440104, 0x3042bfff, 0x00031c00, 0x3084ffff, 0x00641825, 0xa74201a6,
- 0xaf4301ac, 0x3c021000, 0xaf4201b8, 0x15200046, 0x00001021, 0x3c038000,
- 0x8f4201b8, 0x00431024, 0x1440fffd, 0x24020002, 0x24032000, 0xa342018b,
- 0xa7430188, 0x3c021000, 0xaf4201b8, 0x03e00008, 0x00001021, 0x3c030800,
- 0x8c620024, 0x30420001, 0x10400035, 0x00001021, 0x9742010e, 0x34e50002,
- 0x3c038000, 0x24420004, 0x3044ffff, 0x8f4201b8, 0x00431024, 0x1440fffd,
- 0x24020003, 0xa342018b, 0x8f830004, 0x24020002, 0xaf400180, 0xa742018c,
- 0x10600005, 0xa744018e, 0x9743011c, 0x9742011e, 0x0a0002b5, 0x00021400,
- 0x9743011e, 0x9742011c, 0x00021400, 0x00621825, 0xaf4301a8, 0x8f84000c,
- 0x30828000, 0x1040000c, 0xa7450188, 0x93420116, 0x304200fc, 0x005a1021,
- 0x24424004, 0x8c430000, 0x3063ffff, 0x14600004, 0x3c02ffff, 0x34427fff,
- 0x00821024, 0xaf82000c, 0x9782000e, 0x9743010c, 0x8f440104, 0x3042bfff,
- 0x00031c00, 0x3084ffff, 0x00641825, 0xa74201a6, 0xaf4301ac, 0x3c021000,
- 0xaf4201b8, 0x00001021, 0x03e00008, 0x00000000, 0x27bdffe0, 0xafbf0018,
- 0xafb10014, 0xafb00010, 0x8f420140, 0xaf420020, 0x8f430148, 0x3c027000,
- 0x00621824, 0x3c024000, 0x1062000c, 0x0043102b, 0x14400006, 0x3c025000,
- 0x3c023000, 0x1062000b, 0x3c024000, 0x0a00031f, 0x00000000, 0x10620034,
- 0x3c024000, 0x0a00031f, 0x00000000, 0x0e00067c, 0x00000000, 0x0a00031f,
+ 0xaf4301ac, 0x3c021000, 0xaf4201b8, 0x3107ffff, 0x8d220024, 0x30420004,
+ 0x10400039, 0x8d220024, 0x9742010e, 0x30e8fffb, 0x3c038000, 0x24420004,
+ 0x3046ffff, 0x8f4201b8, 0x00431024, 0x1440fffd, 0x24020003, 0xa342018b,
+ 0x97840006, 0x8f85000c, 0x24020100, 0x24030002, 0xaf420180, 0xa743018c,
+ 0xa746018e, 0x10a00005, 0xa7440190, 0x9743011c, 0x9742011e, 0x0a000eda,
+ 0x00021400, 0x9743011e, 0x9742011c, 0x00021400, 0x00621825, 0xaf4301a8,
+ 0x8f840010, 0x30828000, 0x1040000c, 0xa7470188, 0x93420116, 0x304200fc,
+ 0x005a1021, 0x24424004, 0x8c430000, 0x3063ffff, 0x14600004, 0x3c02ffff,
+ 0x34427fff, 0x00821024, 0xaf820010, 0x97820012, 0x9743010c, 0x8f440104,
+ 0x3042bfff, 0x00031c00, 0x3084ffff, 0x00641825, 0xa74201a6, 0xaf4301ac,
+ 0x3c021000, 0xaf4201b8, 0x3107ffff, 0x8d220024, 0x30420008, 0x10400036,
+ 0x00000000, 0x9742010e, 0x3c038000, 0x24420004, 0x3046ffff, 0x8f4201b8,
+ 0x00431024, 0x1440fffd, 0x24020003, 0xa342018b, 0x97840006, 0x8f85000c,
+ 0x24020180, 0x24030002, 0xaf420180, 0xa743018c, 0xa746018e, 0x10a00005,
+ 0xa7440190, 0x9743011c, 0x9742011e, 0x0a000f14, 0x00021400, 0x9743011e,
+ 0x9742011c, 0x00021400, 0x00621825, 0xaf4301a8, 0x8f840010, 0x30828000,
+ 0x1040000c, 0xa7470188, 0x93420116, 0x304200fc, 0x005a1021, 0x24424004,
+ 0x8c430000, 0x3063ffff, 0x14600004, 0x3c02ffff, 0x34427fff, 0x00821024,
+ 0xaf820010, 0x97820012, 0x9743010c, 0x8f440104, 0x3042bfff, 0x00031c00,
+ 0x3084ffff, 0x00641825, 0xa74201a6, 0xaf4301ac, 0x3c021000, 0xaf4201b8,
+ 0x1540004a, 0x00001021, 0x27440180, 0x3c038000, 0x8f4201b8, 0x00431024,
+ 0x1440fffd, 0x24022000, 0x24030002, 0xa4820008, 0xa083000b, 0xa4800010,
+ 0x3c021000, 0xaf4201b8, 0x03e00008, 0x00001021, 0x3c030800, 0x8c620024,
+ 0x30420001, 0x10400037, 0x00001021, 0x9742010e, 0x34e60002, 0x3c038000,
+ 0x24420004, 0x3045ffff, 0x8f4201b8, 0x00431024, 0x1440fffd, 0x24020003,
+ 0xa342018b, 0x97830006, 0x8f84000c, 0x24020002, 0xaf400180, 0xa742018c,
+ 0xa745018e, 0x10800005, 0xa7430190, 0x9743011c, 0x9742011e, 0x0a000f5e,
+ 0x00021400, 0x9743011e, 0x9742011c, 0x00021400, 0x00621825, 0xaf4301a8,
+ 0x8f840010, 0x30828000, 0x1040000c, 0xa7460188, 0x93420116, 0x304200fc,
+ 0x005a1021, 0x24424004, 0x8c430000, 0x3063ffff, 0x14600004, 0x3c02ffff,
+ 0x34427fff, 0x00821024, 0xaf820010, 0x97820012, 0x9743010c, 0x8f440104,
+ 0x3042bfff, 0x00031c00, 0x3084ffff, 0x00641825, 0xa74201a6, 0xaf4301ac,
+ 0x3c021000, 0xaf4201b8, 0x00001021, 0x03e00008, 0x00000000, 0x27bdffe8,
+ 0xafbf0010, 0x8f460128, 0x8f84000c, 0xaf460020, 0x8f450104, 0x8f420100,
+ 0x24030800, 0xaf850004, 0xaf820010, 0xaf4301b8, 0x1080000a, 0x3c020800,
+ 0x8c430034, 0x10600007, 0x30a22000, 0x10400005, 0x34a30100, 0x8f820008,
+ 0xaf830004, 0x24420001, 0xaf820008, 0x3c020800, 0x8c4300c0, 0x10600006,
+ 0x3c030800, 0x8c6200c4, 0x24040001, 0x24420001, 0x0a000fc0, 0xac6200c4,
+ 0x8f820004, 0x3c030010, 0x00431024, 0x14400009, 0x3c02001f, 0x3c030800,
+ 0x8c620020, 0x00002021, 0x24420001, 0x0e000c99, 0xac620020, 0x0a000fc0,
+ 0x00402021, 0x3442ff00, 0x14c20009, 0x2403bfff, 0x3c030800, 0x8c620020,
+ 0x24040001, 0x24420001, 0x0e000c99, 0xac620020, 0x0a000fc0, 0x00402021,
+ 0x8f820010, 0x00431024, 0x14400006, 0x00000000, 0xaf400048, 0x0e001144,
+ 0xaf400040, 0x0a000fc0, 0x00402021, 0x0e0014c9, 0x00000000, 0x00402021,
+ 0x10800005, 0x3c024000, 0x8f430124, 0x3c026020, 0xac430014, 0x3c024000,
+ 0xaf420138, 0x00000000, 0x8fbf0010, 0x03e00008, 0x27bd0018, 0x27bdffe0,
+ 0xafbf0018, 0xafb10014, 0xafb00010, 0x8f420140, 0xaf420020, 0x8f430148,
+ 0x3c027000, 0x00621824, 0x3c023000, 0x10620021, 0x0043102b, 0x14400006,
+ 0x3c024000, 0x3c022000, 0x10620009, 0x3c024000, 0x0a00102b, 0x00000000,
+ 0x10620045, 0x3c025000, 0x10620047, 0x3c024000, 0x0a00102b, 0x00000000,
+ 0x27440180, 0x3c038000, 0x8f4201b8, 0x00431024, 0x1440fffd, 0x00000000,
+ 0x8f420148, 0x24030002, 0xa083000b, 0x00021402, 0xa4820008, 0x8f430148,
+ 0xa4830010, 0x8f420144, 0x3c031000, 0xac820024, 0xaf4301b8, 0x0a00102b,
0x3c024000, 0x8f420148, 0x24030002, 0x3044ffff, 0x00021402, 0x305000ff,
0x1203000c, 0x27510180, 0x2a020003, 0x10400005, 0x24020003, 0x0600001d,
- 0x36053000, 0x0a00030a, 0x3c038000, 0x12020007, 0x00000000, 0x0a000317,
- 0x00000000, 0x0e000423, 0x00000000, 0x0a000308, 0x00402021, 0x0e000435,
+ 0x36053000, 0x0a001012, 0x3c038000, 0x12020007, 0x00000000, 0x0a00101f,
+ 0x00000000, 0x0e00111f, 0x00000000, 0x0a001010, 0x00402021, 0x0e001131,
0x00000000, 0x00402021, 0x36053000, 0x3c038000, 0x8f4201b8, 0x00431024,
0x1440fffd, 0x24020002, 0xa6250008, 0xa222000b, 0xa6240010, 0x8f420144,
- 0x3c031000, 0xae220024, 0xaf4301b8, 0x0a00031f, 0x3c024000, 0x0000000d,
- 0x00000000, 0x240001c3, 0x0a00031f, 0x3c024000, 0x0e0007f7, 0x00000000,
- 0x3c024000, 0xaf420178, 0x00000000, 0x8fbf0018, 0x8fb10014, 0x8fb00010,
- 0x03e00008, 0x27bd0020, 0x24020800, 0x03e00008, 0xaf4201b8, 0x27bdffe8,
- 0x3c04600c, 0xafbf0014, 0xafb00010, 0x8c825000, 0x3c1a8000, 0x2403ff7f,
- 0x3c106000, 0x00431024, 0x3442380c, 0x24030003, 0xac825000, 0x3c040008,
- 0xaf430008, 0x8e020808, 0x3c030800, 0xac600020, 0x3042fff0, 0x2c420001,
- 0xaf820004, 0x0e000819, 0x0344d825, 0x0e000781, 0x00000000, 0x3c020400,
- 0x3442000c, 0x3c03ffff, 0x34630806, 0xae021948, 0xae03194c, 0x8e021980,
- 0x34420200, 0xae021980, 0x8f500000, 0x32020003, 0x1040fffd, 0x32020001,
- 0x10400004, 0x32020002, 0x0e0003bd, 0x00000000, 0x32020002, 0x1040fff6,
- 0x00000000, 0x0e0002d4, 0x00000000, 0x0a00034a, 0x00000000, 0x27bdffe8,
- 0x3c04600c, 0xafbf0014, 0xafb00010, 0x8c825000, 0x3c1a8000, 0x2403ff7f,
- 0x3c106000, 0x00431024, 0x3442380c, 0x24030003, 0xac825000, 0x3c040008,
- 0xaf430008, 0x8e020808, 0x3c030800, 0xac600020, 0x3042fff0, 0x2c420001,
- 0xaf820004, 0x0e000819, 0x0344d825, 0x0e000781, 0x00000000, 0x3c020400,
- 0x3442000c, 0x3c03ffff, 0x34630806, 0xae021948, 0xae03194c, 0x8e021980,
- 0x8fbf0014, 0x34420200, 0xae021980, 0x8fb00010, 0x03e00008, 0x27bd0018,
- 0x30a5ffff, 0x30c6ffff, 0x30e7ffff, 0x3c038000, 0x8f4201b8, 0x00431024,
- 0x1440fffd, 0x24020003, 0xa342018b, 0x8f830004, 0xaf440180, 0xa745018c,
- 0x10600005, 0xa746018e, 0x9743011c, 0x9742011e, 0x0a000393, 0x00021400,
- 0x9743011e, 0x9742011c, 0x00021400, 0x00621825, 0xaf4301a8, 0x8f84000c,
+ 0x3c031000, 0xae220024, 0xaf4301b8, 0x0a00102b, 0x3c024000, 0x0000000d,
+ 0x00000000, 0x24000295, 0x0a00102b, 0x3c024000, 0x0e0013a7, 0x00000000,
+ 0x0a00102b, 0x3c024000, 0x0e001552, 0x00000000, 0x3c024000, 0xaf420178,
+ 0x00000000, 0x8fbf0018, 0x8fb10014, 0x8fb00010, 0x03e00008, 0x27bd0020,
+ 0x24020800, 0x03e00008, 0xaf4201b8, 0x27bdffe8, 0x3c04600c, 0xafbf0014,
+ 0xafb00010, 0x8c825000, 0x3c1a8000, 0x2403ff7f, 0x3c106000, 0x00431024,
+ 0x3442380c, 0x24030003, 0xac825000, 0x3c020008, 0xaf430008, 0x8e040808,
+ 0x0342d825, 0x8e020808, 0x3c030800, 0xac600020, 0x3084fff0, 0x2c840001,
+ 0x3042fff0, 0x38420010, 0x2c420001, 0xaf84000c, 0xaf820000, 0x0e001574,
+ 0x00000000, 0x0e0014c7, 0x00000000, 0x3c020400, 0x3442000c, 0x3c03ffff,
+ 0x34630806, 0xae021948, 0xae03194c, 0x8e021980, 0x34420200, 0xae021980,
+ 0x8f500000, 0x32020003, 0x1040fffd, 0x32020001, 0x10400004, 0x32020002,
+ 0x0e000f7d, 0x00000000, 0x32020002, 0x1040fff6, 0x00000000, 0x0e000fcb,
+ 0x00000000, 0x0a00105c, 0x00000000, 0x27bdffe8, 0x3c04600c, 0xafbf0014,
+ 0xafb00010, 0x8c825000, 0x3c1a8000, 0x2403ff7f, 0x3c106000, 0x00431024,
+ 0x3442380c, 0x24030003, 0xac825000, 0x3c020008, 0xaf430008, 0x8e040808,
+ 0x0342d825, 0x8e020808, 0x3c030800, 0xac600020, 0x3084fff0, 0x2c840001,
+ 0x3042fff0, 0x38420010, 0x2c420001, 0xaf84000c, 0xaf820000, 0x0e001574,
+ 0x00000000, 0x0e0014c7, 0x00000000, 0x3c020400, 0x3442000c, 0x3c03ffff,
+ 0x34630806, 0xae021948, 0xae03194c, 0x8e021980, 0x8fbf0014, 0x34420200,
+ 0xae021980, 0x8fb00010, 0x03e00008, 0x27bd0018, 0x30a5ffff, 0x30c6ffff,
+ 0x30e7ffff, 0x3c038000, 0x8f4201b8, 0x00431024, 0x1440fffd, 0x24020003,
+ 0xa342018b, 0x97830006, 0x8f82000c, 0xaf440180, 0xa745018c, 0xa746018e,
+ 0x10400005, 0xa7430190, 0x9743011c, 0x9742011e, 0x0a0010ad, 0x00021400,
+ 0x9743011e, 0x9742011c, 0x00021400, 0x00621825, 0xaf4301a8, 0x8f840010,
0x30828000, 0x1040000c, 0xa7470188, 0x93420116, 0x304200fc, 0x005a1021,
0x24424004, 0x8c430000, 0x3063ffff, 0x14600004, 0x3c02ffff, 0x34427fff,
- 0x00821024, 0xaf82000c, 0x9782000e, 0x9743010c, 0x8f440104, 0x3042bfff,
+ 0x00821024, 0xaf820010, 0x97820012, 0x9743010c, 0x8f440104, 0x3042bfff,
0x00031c00, 0x3084ffff, 0x00641825, 0xa74201a6, 0xaf4301ac, 0x3c021000,
- 0xaf4201b8, 0x03e00008, 0x00000000, 0x3c038000, 0x8f4201b8, 0x00431024,
- 0x1440fffd, 0x24020002, 0x24032000, 0xa342018b, 0xa7430188, 0x3c021000,
- 0xaf4201b8, 0x03e00008, 0x00000000, 0x27bdffe8, 0xafbf0010, 0x8f460128,
- 0xaf460020, 0x8f420104, 0x8f450100, 0x24030800, 0x3c040010, 0xaf820000,
- 0x00441024, 0xaf85000c, 0xaf4301b8, 0x14400005, 0x3c02001f, 0x3c030800,
- 0x8c620020, 0x0a0003d5, 0x00002021, 0x3442ff00, 0x14c20009, 0x2402bfff,
- 0x3c030800, 0x8c620020, 0x24040001, 0x24420001, 0x0e00004c, 0xac620020,
- 0x0a0003e4, 0x00000000, 0x00a21024, 0x14400006, 0x00000000, 0xaf400048,
- 0x0e000448, 0xaf400040, 0x0a0003e4, 0x00000000, 0x0e000783, 0x00000000,
- 0x10400005, 0x3c024000, 0x8f430124, 0x3c026020, 0xac430014, 0x3c024000,
- 0xaf420138, 0x00000000, 0x8fbf0010, 0x03e00008, 0x27bd0018, 0x27bdffe0,
+ 0xaf4201b8, 0x03e00008, 0x00000000, 0x27440180, 0x3c038000, 0x8f4201b8,
+ 0x00431024, 0x1440fffd, 0x24022000, 0x24030002, 0xa4820008, 0xa083000b,
+ 0xa4800010, 0x3c021000, 0xaf4201b8, 0x03e00008, 0x00000000, 0x27440180,
+ 0x3c038000, 0x8f4201b8, 0x00431024, 0x1440fffd, 0x00000000, 0x8f420148,
+ 0x24030002, 0xa083000b, 0x00021402, 0xa4820008, 0x8f430148, 0xa4830010,
+ 0x8f420144, 0x3c031000, 0xac820024, 0x03e00008, 0xaf4301b8, 0x27bdffe0,
0xafbf0018, 0xafb10014, 0xafb00010, 0x8f420148, 0x24030002, 0x3044ffff,
0x00021402, 0x305000ff, 0x1203000c, 0x27510180, 0x2a020003, 0x10400005,
- 0x24020003, 0x0600001d, 0x36053000, 0x0a00040e, 0x3c038000, 0x12020007,
- 0x00000000, 0x0a00041b, 0x00000000, 0x0e000423, 0x00000000, 0x0a00040c,
- 0x00402021, 0x0e000435, 0x00000000, 0x00402021, 0x36053000, 0x3c038000,
+ 0x24020003, 0x0600001d, 0x36053000, 0x0a00110a, 0x3c038000, 0x12020007,
+ 0x00000000, 0x0a001117, 0x00000000, 0x0e00111f, 0x00000000, 0x0a001108,
+ 0x00402021, 0x0e001131, 0x00000000, 0x00402021, 0x36053000, 0x3c038000,
0x8f4201b8, 0x00431024, 0x1440fffd, 0x24020002, 0xa6250008, 0xa222000b,
- 0xa6240010, 0x8f420144, 0x3c031000, 0xae220024, 0xaf4301b8, 0x0a00041f,
- 0x8fbf0018, 0x0000000d, 0x00000000, 0x240001c3, 0x8fbf0018, 0x8fb10014,
+ 0xa6240010, 0x8f420144, 0x3c031000, 0xae220024, 0xaf4301b8, 0x0a00111b,
+ 0x8fbf0018, 0x0000000d, 0x00000000, 0x24000295, 0x8fbf0018, 0x8fb10014,
0x8fb00010, 0x03e00008, 0x27bd0020, 0x3084ffff, 0x2c821389, 0x1040000d,
- 0x00001021, 0x3c030800, 0x24632100, 0x00042942, 0x00052880, 0x00a32821,
+ 0x00001021, 0x3c030800, 0x24635680, 0x00042942, 0x00052880, 0x00a32821,
0x3086001f, 0x8ca40000, 0x24030001, 0x00c31804, 0x00832025, 0x03e00008,
0xaca40000, 0x03e00008, 0x24020091, 0x3084ffff, 0x2c821389, 0x1040000e,
- 0x00001021, 0x3c030800, 0x24632100, 0x00042942, 0x00052880, 0x00a32821,
+ 0x00001021, 0x3c030800, 0x24635680, 0x00042942, 0x00052880, 0x00a32821,
0x3086001f, 0x24030001, 0x8ca40000, 0x00c31804, 0x00031827, 0x00832024,
- 0x03e00008, 0xaca40000, 0x03e00008, 0x24020091, 0x27bdffb0, 0x3c026000,
- 0xafbf0048, 0x8c434448, 0xaf630140, 0x93620005, 0x30420001, 0x14400005,
- 0x00000000, 0x0e0007ed, 0x00000000, 0x0a00067a, 0x8fbf0048, 0x93420116,
- 0x93430112, 0x8f430104, 0x3c040020, 0x34424000, 0x00641824, 0x1060000d,
- 0x03426021, 0x8f430128, 0x27420180, 0xac430000, 0x8f650040, 0x24040008,
- 0x240340c1, 0xa4430008, 0x24030002, 0xa043000b, 0x3c031000, 0x0a000563,
- 0xa044000a, 0x8f420104, 0x3c030040, 0x00431024, 0x10400007, 0x00000000,
- 0x8f430128, 0x27420180, 0xac430000, 0x8f650040, 0x0a00055c, 0x24040010,
- 0xaf400048, 0xaf400054, 0xaf400040, 0x8f630048, 0x8f620040, 0x00624823,
- 0x05210004, 0x00000000, 0x0000000d, 0x00000000, 0x24000132, 0x9742011a,
- 0x3046ffff, 0x10c00004, 0x8d880004, 0x01061021, 0x0a000487, 0x2445ffff,
- 0x01002821, 0x918a000d, 0xa7a00020, 0xafa00028, 0x9364003f, 0x3c026000,
- 0x8c434448, 0x308700ff, 0x31420004, 0x10400033, 0xaf630144, 0x24090012,
- 0x14e90006, 0x3c040800, 0x8c830028, 0x24020001, 0x24630001, 0x0a00054e,
- 0xac830028, 0x8f620044, 0x15020012, 0x97a20020, 0x27a60010, 0x27450180,
- 0x3442001a, 0xa7a20020, 0x8f630040, 0x3c048000, 0x24020020, 0xa3a70022,
- 0xa3a90023, 0xa3a2001a, 0xafa30028, 0x8f4201b8, 0x00441024, 0x1440fffd,
- 0x00000000, 0x0a000533, 0x00000000, 0x8f620044, 0x01021023, 0x0440009e,
- 0x24020001, 0x8f620048, 0x01021023, 0x0441009a, 0x24020001, 0x97a20020,
- 0x27a60010, 0x34420001, 0xa7a20020, 0x8f630040, 0x27450180, 0x3c048000,
- 0xafa30028, 0x8f4201b8, 0x00441024, 0x1440fffd, 0x00000000, 0x0a000533,
- 0x00000000, 0x3c026000, 0x8c424448, 0xaf620148, 0x8f630040, 0x00685823,
- 0x19600013, 0x00cb102a, 0x54400007, 0x314a00fe, 0x5566000c, 0x010b4021,
- 0x31420001, 0x54400009, 0x010b4021, 0x314a00fe, 0x24020001, 0xa7a20020,
- 0x8f630040, 0x00c05821, 0x00003021, 0x0a0004dd, 0xafa30028, 0x00cb1023,
- 0x0a0004dd, 0x3046ffff, 0x00005821, 0x8f620048, 0x2442ffff, 0x00a21823,
- 0x18600019, 0x0066102a, 0x14400013, 0x24020001, 0xa7a20020, 0x8f630040,
- 0xafa30028, 0x8f620040, 0x55020005, 0x27a60010, 0x55200003, 0x27a60010,
- 0x0a0004f6, 0x00c01821, 0x27450180, 0x3c038000, 0x8f4201b8, 0x00431024,
- 0x1440fffd, 0x00000000, 0x0a000533, 0x00000000, 0x8f650048, 0x00c31023,
- 0x3046ffff, 0x314a00f6, 0x3c046000, 0x8c824448, 0x31430002, 0x1060001e,
- 0xaf62014c, 0x8f620044, 0x1502000e, 0x97a20020, 0x27a60010, 0x34420200,
- 0xa7a20020, 0x8f630040, 0x27450180, 0x3c048000, 0xafa30028, 0x8f4201b8,
- 0x00441024, 0x1440fffd, 0x00000000, 0x0a000533, 0x00000000, 0x27a60010,
- 0x34420001, 0xa7a20020, 0x8f630040, 0x27450180, 0x3c048000, 0xafa30028,
- 0x8f4201b8, 0x00441024, 0x1440fffd, 0x00000000, 0x0a000533, 0x00000000,
- 0x3c026000, 0x8c424448, 0x31430010, 0xaf620150, 0x54600003, 0x8d890008,
- 0x0a00054e, 0x24020001, 0x8f630054, 0x2522ffff, 0x00431023, 0x1840002a,
- 0x24020001, 0x27a60010, 0xa7a20020, 0x8f630040, 0x27450180, 0x3c048000,
- 0xafa30028, 0x8f4201b8, 0x00441024, 0x1440fffd, 0x00000000, 0x8f420128,
- 0xaca20000, 0x8cc30018, 0x240240c1, 0xa4a20008, 0xaca30018, 0x90c4000a,
- 0x24020002, 0xa0a2000b, 0xa0a4000a, 0x94c20010, 0xa4a20010, 0x90c30012,
- 0xa0a30012, 0x90c20013, 0xa0a20013, 0x8cc30014, 0xaca30014, 0x8cc20024,
- 0xaca20024, 0x8cc30028, 0xaca30028, 0x8cc4002c, 0x24020001, 0x3c031000,
- 0xaca4002c, 0xaf4301b8, 0xaf400044, 0xaf400050, 0x0a00067a, 0x8fbf0048,
- 0x3c026000, 0x8c424448, 0x31430020, 0x10600019, 0xaf620154, 0x8f430128,
- 0x27420180, 0xac430000, 0x8f650040, 0x24040004, 0x240340c1, 0xa4430008,
- 0x24030002, 0xa044000a, 0x24040008, 0xa043000b, 0x3c031000, 0xa4440010,
- 0xa0400012, 0xa0400013, 0xac400014, 0xac400024, 0xac400028, 0xac40002c,
- 0xac450018, 0x0e0007ed, 0xaf4301b8, 0x0a00067a, 0x8fbf0048, 0x8f430104,
- 0x8c824448, 0x38e3000a, 0x2c630001, 0xaf620158, 0x38e2000c, 0x2c420001,
- 0x00621825, 0x14600003, 0x2402000e, 0x14e2002a, 0x00000000, 0x50c00008,
- 0x9584000e, 0x10c00004, 0xa7a60040, 0x01061021, 0x0a000583, 0x2445ffff,
- 0x01002821, 0x9584000e, 0x93630035, 0x8f62004c, 0x00642004, 0x00892021,
- 0x00821023, 0x1840001f, 0x3c026000, 0x8f620018, 0x01021023, 0x1c40000f,
- 0x97a20020, 0x8f620018, 0x15020018, 0x3c026000, 0x8f62001c, 0x01221023,
- 0x1c400008, 0x97a20020, 0x8f62001c, 0x15220011, 0x3c026000, 0x8f620058,
- 0x00821023, 0x1840000c, 0x97a20020, 0xafa50028, 0xafa80034, 0xafa90038,
- 0xafa4003c, 0x34420020, 0x0a0005a8, 0xa7a20020, 0x8f680040, 0x00003021,
- 0x8f640058, 0x01002821, 0x3c026000, 0x8c434448, 0xaf63015c, 0x8f62004c,
- 0x01221023, 0x18400009, 0x00000000, 0x8f620054, 0x01221023, 0x1c400005,
- 0x97a20020, 0xafa50028, 0xafa90024, 0x0a0005c3, 0x34420040, 0x9742011a,
- 0x1440000c, 0x24020014, 0x8f620058, 0x14820009, 0x24020014, 0x8f63004c,
- 0x8f620054, 0x10620004, 0x97a20020, 0xafa50028, 0x34420080, 0xa7a20020,
- 0x24020014, 0x10e2000a, 0x28e20015, 0x10400005, 0x2402000c, 0x10e20006,
- 0x3c026000, 0x0a000600, 0x00000000, 0x24020016, 0x14e20031, 0x3c026000,
- 0x8f620054, 0x24420001, 0x1522002d, 0x3c026000, 0x24020014, 0x10e2001e,
- 0x28e20015, 0x10400005, 0x2402000c, 0x10e20008, 0x3c026000, 0x0a000600,
- 0x00000000, 0x24020016, 0x10e2000c, 0x97a20020, 0x0a000600, 0x3c026000,
- 0x97a30020, 0x2402000e, 0xafa50028, 0xa3a70022, 0xa3a20023, 0xafa90024,
- 0x34630054, 0x0a0005ff, 0xa7a30020, 0x24030010, 0x24040002, 0xafa50028,
- 0xa3a70022, 0xa3a30023, 0xa3a4001a, 0xafa90024, 0x0a0005fe, 0x3442005d,
- 0x97a20020, 0x24030012, 0x24040002, 0xafa50028, 0xa3a70022, 0xa3a30023,
- 0xa3a4001a, 0xafa90024, 0x3042fffe, 0x3442005c, 0xa7a20020, 0x3c026000,
- 0x8c434448, 0x31420001, 0xaf630160, 0x1040002c, 0x2402000c, 0x10e20014,
- 0x28e2000d, 0x10400005, 0x2402000a, 0x10e20008, 0x97a20020, 0x0a000631,
- 0x3c026000, 0x2402000e, 0x10e20018, 0x3c026000, 0x0a000631, 0x00000000,
- 0x24030008, 0x24040002, 0xafa50028, 0xa3a70022, 0xa3a30023, 0xa3a4001a,
- 0x0a00062f, 0x34420013, 0x97a30020, 0x30620004, 0x1440000b, 0x97a20020,
- 0x3462001b, 0xa7a20020, 0x24020016, 0x24030002, 0xafa50028, 0xa3a70022,
- 0xa3a20023, 0x0a000630, 0xa3a3001a, 0x97a20020, 0x24030010, 0x24040002,
- 0xafa50028, 0xa3a70022, 0xa3a30023, 0xa3a4001a, 0x3442001b, 0xa7a20020,
- 0x3c026000, 0x8c434448, 0x31420009, 0x0002102b, 0x00021023, 0x30420007,
- 0x34440003, 0xaf630164, 0x10c00016, 0x24030800, 0x8f820010, 0x27450180,
- 0x24420001, 0xaf820010, 0x24020004, 0xaf4301b8, 0xa4a40008, 0xa0a2000b,
- 0x93440120, 0x3c031000, 0xa4a6000e, 0xaca90024, 0xaca80028, 0x008b2021,
- 0xa4a4000c, 0xaf4301b8, 0x97a20020, 0x00003021, 0x3042ffbf, 0x0a000650,
- 0xa7a20020, 0x24060001, 0x3c026000, 0x8c434448, 0xaf630168, 0x97a20020,
- 0x10400020, 0x27450180, 0x3c038000, 0x8f4201b8, 0x00431024, 0x1440fffd,
- 0x00000000, 0x8f420128, 0xaca20000, 0x8fa30028, 0x240240c1, 0xa4a20008,
- 0xaca30018, 0x93a4001a, 0x24020002, 0xa0a2000b, 0xa0a4000a, 0x97a20020,
- 0xa4a20010, 0x93a30022, 0xa0a30012, 0x93a20023, 0xa0a20013, 0x8fa30024,
- 0xaca30014, 0x8fa20034, 0xaca20024, 0x8fa30038, 0xaca30028, 0x8fa2003c,
- 0x3c031000, 0xaca2002c, 0xaf4301b8, 0x3c026000, 0x8c434448, 0x00c01021,
- 0xaf63016c, 0x8fbf0048, 0x03e00008, 0x27bd0050, 0x8f460140, 0x8f470148,
- 0x3c028000, 0x00e24024, 0x00072c02, 0x30a300ff, 0x2402000b, 0x1062008f,
- 0x27440180, 0x2862000c, 0x10400011, 0x24020006, 0x1062005a, 0x28620007,
- 0x10400007, 0x24020008, 0x10600024, 0x24020001, 0x10620037, 0x00000000,
- 0x0a00077e, 0x00000000, 0x106200a9, 0x24020009, 0x106200bb, 0x00071c02,
- 0x0a00077e, 0x00000000, 0x2402001b, 0x106200c7, 0x2862001c, 0x10400007,
- 0x2402000e, 0x106200b1, 0x24020019, 0x106200c2, 0x00071c02, 0x0a00077e,
- 0x00000000, 0x24020080, 0x10620060, 0x28620081, 0x10400005, 0x2402001c,
- 0x10620094, 0x00071c02, 0x0a00077e, 0x00000000, 0x240200c2, 0x106200c5,
- 0x00a01821, 0x0a00077e, 0x00000000, 0x00a01821, 0x3c058000, 0x8f4201b8,
- 0x00451024, 0x1440fffd, 0x24020001, 0xa4830008, 0x24030002, 0xac860000,
- 0xac800004, 0xa082000a, 0xa083000b, 0xa4870010, 0x8f430144, 0x3c021000,
+ 0x03e00008, 0xaca40000, 0x03e00008, 0x24020091, 0x27bdffb0, 0xafbf0048,
+ 0x93620023, 0x30420010, 0x1440025b, 0x24020001, 0x93420116, 0x93630005,
+ 0x34424000, 0x30630001, 0x14600005, 0x03425821, 0x0e001548, 0x00000000,
+ 0x0a0013a5, 0x8fbf0048, 0x93420112, 0x8f430104, 0x3c040020, 0x34424000,
+ 0x00641824, 0x10600012, 0x03422821, 0x27450180, 0x3c038000, 0x8f4201b8,
+ 0x00431024, 0x1440fffd, 0x00000000, 0x8f420128, 0xaca20000, 0x8f640040,
+ 0x24030008, 0x240240c1, 0xa4a20008, 0x24020002, 0xa0a2000b, 0x3c021000,
+ 0x0a001181, 0xa0a3000a, 0x8f420104, 0x3c030040, 0x00431024, 0x1040001d,
+ 0x3c038000, 0x27450180, 0x8f4201b8, 0x00431024, 0x1440fffd, 0x00000000,
+ 0x8f420128, 0xaca20000, 0x8f640040, 0x24030010, 0x240240c1, 0xa4a20008,
+ 0x24020002, 0xa0a3000a, 0x24030008, 0xa0a2000b, 0x3c021000, 0xa4a30010,
+ 0xa0a00012, 0xa0a00013, 0xaca00014, 0xaca00024, 0xaca00028, 0xaca0002c,
+ 0xaca40018, 0x0e001548, 0xaf4201b8, 0x0a0013a5, 0x8fbf0048, 0x8f820000,
+ 0x10400016, 0x00000000, 0x8f420104, 0x3c030001, 0x00431024, 0x10400011,
+ 0x00000000, 0x8ca3000c, 0x8f620030, 0x1462020c, 0x24020001, 0x8ca30010,
+ 0x8f62002c, 0x14620208, 0x24020001, 0x9763003a, 0x95620000, 0x14430204,
+ 0x24020001, 0x97630038, 0x95620002, 0x14430200, 0x24020001, 0xaf400048,
+ 0xaf400054, 0xaf400040, 0x8f690040, 0x8f6a0048, 0x01497023, 0x05c10004,
+ 0x00000000, 0x0000000d, 0x00000000, 0x24000169, 0x9742011a, 0x3046ffff,
+ 0x10c00004, 0x8d680004, 0x01061021, 0x0a0011b8, 0x2445ffff, 0x01002821,
+ 0x916c000d, 0xa7a00020, 0xa3a0001a, 0xafa00028, 0x9362003f, 0x31830004,
+ 0x1060003a, 0x304700ff, 0x24040012, 0x14e40006, 0x24020001, 0x3c040800,
+ 0x8c830028, 0x24630001, 0x0a00128d, 0xac830028, 0x8f620044, 0x15020010,
+ 0x27a60010, 0x27450180, 0x3c038000, 0x2402001a, 0xa7a20020, 0x24020020,
+ 0xafa90028, 0xa3a70022, 0xa3a40023, 0xa3a2001a, 0x8f4201b8, 0x00431024,
+ 0x1440fffd, 0x00000000, 0x0a001272, 0x00000000, 0x8f620044, 0x01021023,
+ 0x0440001a, 0x010a1023, 0x044100ae, 0x24020001, 0x3c020800, 0x8c4300d8,
+ 0x10600004, 0x24020001, 0xa7a20020, 0x0a0011ee, 0xafa90028, 0x2402001a,
+ 0xa7a20020, 0x24020020, 0xafa90028, 0xa3a70022, 0xa3a40023, 0xa3a2001a,
+ 0x27a60010, 0x27450180, 0x3c038000, 0x8f4201b8, 0x00431024, 0x1440fffd,
+ 0x00000000, 0x0a001272, 0x00000000, 0x0a00128d, 0x24020001, 0x01286823,
+ 0x19a00016, 0x00cd102a, 0x54400007, 0x318c00fe, 0x55a6000f, 0x010d4021,
+ 0x31820001, 0x5440000c, 0x010d4021, 0x318c00fe, 0x00c06821, 0x3c040800,
+ 0x8c8300c8, 0x00003021, 0x24020001, 0xa7a20020, 0xafa90028, 0x24630001,
+ 0x0a001212, 0xac8300c8, 0x00cd1023, 0x0a001212, 0x3046ffff, 0x00006821,
+ 0x2542ffff, 0x00a21823, 0x1860001e, 0x0066102a, 0x14400018, 0x01402821,
+ 0x97a20020, 0x3c040800, 0x8c8300cc, 0xafa90028, 0x34420001, 0x24630001,
+ 0xa7a20020, 0x01091026, 0x2c420001, 0xac8300cc, 0x2dc30001, 0x00431024,
+ 0x1440000a, 0x00c01821, 0x27a60010, 0x27450180, 0x3c038000, 0x8f4201b8,
+ 0x00431024, 0x1440fffd, 0x00000000, 0x0a001272, 0x00000000, 0x00c31023,
+ 0x3046ffff, 0x0a00123d, 0x318c00f6, 0x01091023, 0x18400008, 0x97a20020,
+ 0x3c040800, 0x8c8300d4, 0xafa80028, 0x34420400, 0x24630001, 0xa7a20020,
+ 0xac8300d4, 0x31820002, 0x1040001c, 0x31820010, 0x8f620044, 0x1502000d,
+ 0x27a60010, 0x97a20020, 0x27450180, 0x3c038000, 0xafa90028, 0x34420001,
+ 0xa7a20020, 0x8f4201b8, 0x00431024, 0x1440fffd, 0x00000000, 0x0a001272,
+ 0x00000000, 0x97a20020, 0x27450180, 0x3c038000, 0xafa90028, 0x34420001,
+ 0xa7a20020, 0x8f4201b8, 0x00431024, 0x1440fffd, 0x00000000, 0x0a001272,
+ 0x00000000, 0x54400003, 0x8d6a0008, 0x0a00128d, 0x24020001, 0x8f630054,
+ 0x2542ffff, 0x00431023, 0x1840002e, 0x97a20020, 0x27a60010, 0x3c040800,
+ 0x8c8300d0, 0x27450180, 0x3c078000, 0xafa90028, 0x34420001, 0x24630001,
+ 0xa7a20020, 0xac8300d0, 0x8f4201b8, 0x00471024, 0x1440fffd, 0x00000000,
+ 0x8f420128, 0xaca20000, 0x8cc30018, 0x240240c1, 0xa4a20008, 0xaca30018,
+ 0x90c4000a, 0x24020002, 0xa0a2000b, 0xa0a4000a, 0x94c20010, 0xa4a20010,
+ 0x90c30012, 0xa0a30012, 0x90c20013, 0xa0a20013, 0x8cc30014, 0xaca30014,
+ 0x8cc20024, 0xaca20024, 0x8cc30028, 0xaca30028, 0x8cc4002c, 0x24020001,
+ 0x3c031000, 0xaca4002c, 0xaf4301b8, 0xaf400044, 0xaf400050, 0x0a0013a5,
+ 0x8fbf0048, 0x31820020, 0x10400011, 0x00000000, 0x95620012, 0x0046102b,
+ 0x10400008, 0x97a20020, 0x95660012, 0x10c00003, 0x01061021, 0x0a00129e,
+ 0x2445ffff, 0x01002821, 0x97a20020, 0x93a3001a, 0x34420008, 0x34630004,
+ 0xa7a20020, 0xa3a3001a, 0x8f420104, 0x38e3000a, 0x2c630001, 0x38e2000c,
+ 0x2c420001, 0x00621825, 0x14600003, 0x2402000e, 0x54e2002a, 0x00003021,
+ 0x50c00008, 0x9564000e, 0x10c00004, 0xa7a60040, 0x01061021, 0x0a0012b6,
+ 0x2445ffff, 0x01002821, 0x9564000e, 0x93630035, 0x8f62004c, 0x00642004,
+ 0x008a2021, 0x00821023, 0x1840001d, 0x00000000, 0x8f620018, 0x01021023,
+ 0x1c40000f, 0x97a20020, 0x8f620018, 0x15020016, 0x00000000, 0x8f62001c,
+ 0x01421023, 0x1c400008, 0x97a20020, 0x8f62001c, 0x1542000f, 0x00000000,
+ 0x8f620058, 0x00821023, 0x1840000b, 0x97a20020, 0xafa50028, 0xafa80034,
+ 0xafaa0038, 0xafa4003c, 0x34420020, 0x0a0012da, 0xa7a20020, 0x01204021,
+ 0x01002821, 0x8f640058, 0x8f62004c, 0x01421023, 0x18400009, 0x00000000,
+ 0x8f620054, 0x01421023, 0x1c400005, 0x97a20020, 0xafa50028, 0xafaa0024,
+ 0x0a0012f2, 0x34420040, 0x9742011a, 0x1440000c, 0x24020014, 0x8f620058,
+ 0x14820009, 0x24020014, 0x8f63004c, 0x8f620054, 0x10620004, 0x97a20020,
+ 0xafa50028, 0x34420080, 0xa7a20020, 0x24020014, 0x10e2000a, 0x28e20015,
+ 0x10400005, 0x2402000c, 0x10e20006, 0x31820001, 0x0a001333, 0x00000000,
+ 0x24020016, 0x14e20035, 0x31820001, 0x8f620084, 0x24420001, 0x15420031,
+ 0x31820001, 0x24020014, 0x10e20021, 0x28e20015, 0x10400005, 0x2402000c,
+ 0x10e20008, 0x31820001, 0x0a001333, 0x00000000, 0x24020016, 0x10e2000c,
+ 0x31820001, 0x0a001333, 0x00000000, 0x97a30020, 0x2402000e, 0xafa50028,
+ 0xa3a70022, 0xa3a20023, 0xafaa0024, 0x34630054, 0x0a001332, 0xa7a30020,
+ 0x97a20020, 0x93a4001a, 0x24030010, 0xafa50028, 0xa3a70022, 0xa3a30023,
+ 0xafaa0024, 0x3442005d, 0x34840002, 0xa7a20020, 0x0a001332, 0xa3a4001a,
+ 0x97a20020, 0x24030012, 0xa3a30023, 0x93a3001a, 0xafa50028, 0xa3a70022,
+ 0xafaa0024, 0x3042fffe, 0x3442005c, 0x34630002, 0xa7a20020, 0xa3a3001a,
+ 0x31820001, 0x10400030, 0x2402000c, 0x10e20013, 0x28e2000d, 0x10400005,
+ 0x2402000a, 0x10e20008, 0x97a20020, 0x0a001365, 0x31820009, 0x2402000e,
+ 0x10e2001b, 0x31820009, 0x0a001366, 0x0002102b, 0x93a4001a, 0x24030008,
+ 0xafa50028, 0xa3a70022, 0xa3a30023, 0x0a001361, 0x34420013, 0x97a30020,
+ 0x30620004, 0x14400005, 0x93a2001a, 0x3463001b, 0xa7a30020, 0x0a001354,
+ 0x24030016, 0x3463001b, 0xa7a30020, 0x24030010, 0xafa50028, 0xa3a70022,
+ 0xa3a30023, 0x34420002, 0x0a001364, 0xa3a2001a, 0x97a20020, 0x93a4001a,
+ 0x24030010, 0xafa50028, 0xa3a70022, 0xa3a30023, 0x3442001b, 0x34840002,
+ 0xa7a20020, 0xa3a4001a, 0x31820009, 0x0002102b, 0x00021023, 0x30420007,
+ 0x10c00017, 0x34440003, 0x8f820014, 0x24030800, 0x27450180, 0x24420001,
+ 0xaf820014, 0x24020004, 0xaf4301b8, 0xa4a40008, 0xa0a2000b, 0x93440120,
+ 0x3c031000, 0xa4a6000e, 0xacaa0024, 0xaca80028, 0x008d2021, 0xa4a4000c,
+ 0xaf4301b8, 0x97a20020, 0x00003021, 0x3042ffbf, 0x0a001381, 0xa7a20020,
+ 0x24060001, 0x97a20020, 0x10400020, 0x27450180, 0x3c038000, 0x8f4201b8,
+ 0x00431024, 0x1440fffd, 0x00000000, 0x8f420128, 0xaca20000, 0x8fa30028,
+ 0x240240c1, 0xa4a20008, 0xaca30018, 0x93a4001a, 0x24020002, 0xa0a2000b,
+ 0xa0a4000a, 0x97a20020, 0xa4a20010, 0x93a30022, 0xa0a30012, 0x93a20023,
+ 0xa0a20013, 0x8fa30024, 0xaca30014, 0x8fa20034, 0xaca20024, 0x8fa30038,
+ 0xaca30028, 0x8fa2003c, 0x3c031000, 0xaca2002c, 0xaf4301b8, 0x00c01021,
+ 0x8fbf0048, 0x03e00008, 0x27bd0050, 0x8f470140, 0x8f460148, 0x3c028000,
+ 0x00c24024, 0x00062c02, 0x30a300ff, 0x24020019, 0x106200e7, 0x27440180,
+ 0x2862001a, 0x1040001f, 0x24020008, 0x106200be, 0x28620009, 0x1040000d,
+ 0x24020001, 0x10620046, 0x28620002, 0x50400005, 0x24020006, 0x1060002e,
+ 0x00a01821, 0x0a0014c4, 0x00000000, 0x1062005b, 0x00a01821, 0x0a0014c4,
+ 0x00000000, 0x2402000b, 0x10620084, 0x2862000c, 0x10400005, 0x24020009,
+ 0x106200bc, 0x00061c02, 0x0a0014c4, 0x00000000, 0x2402000e, 0x106200b7,
+ 0x00061c02, 0x0a0014c4, 0x00000000, 0x28620021, 0x10400009, 0x2862001f,
+ 0x104000c1, 0x2402001b, 0x106200bf, 0x2402001c, 0x1062009a, 0x00061c02,
+ 0x0a0014c4, 0x00000000, 0x240200c2, 0x106200ca, 0x286200c3, 0x10400005,
+ 0x24020080, 0x1062005a, 0x00a01821, 0x0a0014c4, 0x00000000, 0x240200c9,
+ 0x106200cd, 0x30c5ffff, 0x0a0014c4, 0x00000000, 0x3c058000, 0x8f4201b8,
+ 0x00451024, 0x1440fffd, 0x24020001, 0xa4830008, 0x24030002, 0xac870000,
+ 0xac800004, 0xa082000a, 0xa083000b, 0xa4860010, 0x8f430144, 0x3c021000,
0xac800028, 0xac830024, 0x3c036000, 0xaf4201b8, 0x03e00008, 0xac600808,
- 0x11000009, 0x00a01821, 0x3c020800, 0x24030002, 0xa0434490, 0x24424490,
- 0xac460008, 0x8f430144, 0x03e00008, 0xac430004, 0x3c058000, 0x8f4201b8,
- 0x00451024, 0x1440fffd, 0x24020002, 0xac800000, 0xac860004, 0xa4830008,
- 0xa082000a, 0xa082000b, 0xa4870010, 0xac800024, 0x8f420144, 0x3c031000,
- 0xac820028, 0x3c026000, 0xaf4301b8, 0x03e00008, 0xac400808, 0x00a01821,
- 0x3c080800, 0x3c058000, 0x8f4201b8, 0x00451024, 0x1440fffd, 0x00000000,
- 0xac860000, 0x91024490, 0x00002821, 0x10400002, 0x25064490, 0x8cc50008,
- 0xac850004, 0xa4830008, 0x91034490, 0x24020002, 0xa082000b, 0xa4870010,
- 0x34630001, 0xa083000a, 0x8f420144, 0xac820024, 0x91034490, 0x10600002,
- 0x00001021, 0x8cc20004, 0xac820028, 0x3c021000, 0xaf4201b8, 0x3c026000,
- 0xa1004490, 0x03e00008, 0xac400808, 0x00a01821, 0x3c058000, 0x8f4201b8,
- 0x00451024, 0x1440fffd, 0x24020002, 0xa082000b, 0xa4830008, 0xa4870010,
- 0x8f420144, 0x3c031000, 0xa4820012, 0x03e00008, 0xaf4301b8, 0x30e2ffff,
- 0x14400028, 0x00071c02, 0x93620005, 0x30420004, 0x14400020, 0x3c029000,
- 0x34420001, 0x00c21025, 0xaf420020, 0x3c038000, 0x8f420020, 0x00431024,
- 0x1440fffd, 0x00000000, 0x93620005, 0x3c038000, 0x34630001, 0x00c31825,
- 0x34420004, 0xa3620005, 0xaf430020, 0x93620005, 0x30420004, 0x14400003,
- 0x3c038000, 0x0000000d, 0x3c038000, 0x8f4201b8, 0x00431024, 0x1440fffd,
- 0x24020005, 0x3c031000, 0xac860000, 0xa082000b, 0xaf4301b8, 0x0a00073d,
- 0x00071c02, 0x0000000d, 0x03e00008, 0x00000000, 0x00071c02, 0x3c058000,
- 0x8f4201b8, 0x00451024, 0x1440fffd, 0x24020001, 0xa4830008, 0x24030002,
- 0xac860000, 0xac800004, 0xa082000a, 0xa083000b, 0xa4870010, 0x8f430144,
- 0x3c021000, 0xac800028, 0xac830024, 0x03e00008, 0xaf4201b8, 0x00071c02,
- 0x3c058000, 0x8f4201b8, 0x00451024, 0x1440fffd, 0x24020002, 0xac800000,
- 0xac860004, 0xa4830008, 0xa082000a, 0xa082000b, 0xa4870010, 0xac800024,
- 0x8f420144, 0x3c031000, 0xac820028, 0x03e00008, 0xaf4301b8, 0x00071c02,
- 0x3c058000, 0x8f4201b8, 0x00451024, 0x1440fffd, 0x24020001, 0xa4830008,
- 0x24030002, 0xa082000a, 0x3c021000, 0xac860000, 0xac800004, 0xa083000b,
- 0xa4870010, 0xac800024, 0xac800028, 0x03e00008, 0xaf4201b8, 0x3c058000,
- 0x8f4201b8, 0x00451024, 0x1440fffd, 0x24020002, 0xac860000, 0xac800004,
- 0xa4830008, 0xa080000a, 0x0a000748, 0xa082000b, 0x0000000d, 0x03e00008,
- 0x00000000, 0x03e00008, 0x00000000, 0x8f420100, 0x3042003e, 0x14400011,
- 0x24020001, 0xaf400048, 0x8f420100, 0x304207c0, 0x10400005, 0x00000000,
- 0xaf40004c, 0xaf400050, 0x03e00008, 0x24020001, 0xaf400054, 0xaf400040,
- 0x8f420100, 0x30423800, 0x54400001, 0xaf400044, 0x24020001, 0x03e00008,
- 0x00000000, 0x3c029000, 0x34420001, 0x00822025, 0xaf440020, 0x3c038000,
- 0x8f420020, 0x00431024, 0x1440fffd, 0x00000000, 0x03e00008, 0x00000000,
- 0x3c028000, 0x34420001, 0x00822025, 0x03e00008, 0xaf440020, 0x8f430128,
- 0x27420180, 0xac430000, 0x8f650040, 0x240340c1, 0xa4430008, 0x24030002,
- 0xa044000a, 0x24040008, 0xa043000b, 0x3c031000, 0xa4440010, 0xa0400012,
- 0xa0400013, 0xac400014, 0xac400024, 0xac400028, 0xac40002c, 0xac450018,
- 0x03e00008, 0xaf4301b8, 0x24020001, 0xacc40000, 0x03e00008, 0xa4e50000,
- 0x03e00008, 0x24020001, 0x24020001, 0xaf400044, 0x03e00008, 0xaf400050,
- 0x00803021, 0x27450180, 0x3c038000, 0x8f4201b8, 0x00431024, 0x1440fffd,
- 0x00000000, 0x8f420128, 0xaca20000, 0x8cc30018, 0x240240c1, 0xa4a20008,
- 0xaca30018, 0x90c4000a, 0x24020002, 0xa0a2000b, 0xa0a4000a, 0x94c20010,
- 0xa4a20010, 0x90c30012, 0xa0a30012, 0x90c20013, 0xa0a20013, 0x8cc30014,
- 0xaca30014, 0x8cc20024, 0xaca20024, 0x8cc30028, 0xaca30028, 0x8cc2002c,
- 0x3c031000, 0xaca2002c, 0x24020001, 0xaf4301b8, 0xaf400044, 0x03e00008,
- 0xaf400050, 0x27bdffe8, 0xafbf0010, 0x0e000326, 0x00000000, 0x00002021,
- 0x0e00004c, 0xaf400180, 0x8fbf0010, 0x03e00008, 0x27bd0018, 0x8f460148,
- 0x27450180, 0x3c038000, 0x00061402, 0x304700ff, 0x8f4201b8, 0x00431024,
- 0x1440fffd, 0x00000000, 0x8f440140, 0x00061202, 0x304200ff, 0x00061c02,
- 0xaca20004, 0x24020002, 0xa4a30008, 0x30c300ff, 0xa0a2000b, 0xaca30024,
- 0x10e0000a, 0xaca40000, 0x28e20004, 0x14400005, 0x24020001, 0x24020005,
- 0x54e20005, 0xa0a0000a, 0x24020001, 0x0a000816, 0xa0a2000a, 0xa0a0000a,
- 0x3c021000, 0x03e00008, 0xaf4201b8, 0x03e00008, 0x00001021, 0x10c00007,
- 0x00000000, 0x8ca20000, 0x24c6ffff, 0x24a50004, 0xac820000, 0x14c0fffb,
- 0x24840004, 0x03e00008, 0x00000000, 0x0a00082a, 0x00a01021, 0xac860000,
- 0x24840004, 0x00a01021, 0x1440fffc, 0x24a5ffff, 0x03e00008, 0x00000000,
- 0x00000000 };
+ 0x11000009, 0x00a01821, 0x3c020800, 0x24030002, 0xa0436a08, 0x24426a08,
+ 0xac470008, 0x8f430144, 0x03e00008, 0xac430004, 0x3c058000, 0x8f4201b8,
+ 0x00451024, 0x1440fffd, 0x24020002, 0xac800000, 0xac870004, 0xa4830008,
+ 0xa082000a, 0xa082000b, 0xa4860010, 0xac800024, 0x8f420144, 0x3c031000,
+ 0xac820028, 0x3c026000, 0xaf4301b8, 0x03e00008, 0xac400808, 0x3c080800,
+ 0x3c058000, 0x8f4201b8, 0x00451024, 0x1440fffd, 0x00000000, 0xac870000,
+ 0x91026a08, 0x00002821, 0x10400002, 0x25076a08, 0x8ce50008, 0xac850004,
+ 0xa4830008, 0x91036a08, 0x24020002, 0xa082000b, 0xa4860010, 0x34630001,
+ 0xa083000a, 0x8f420144, 0xac820024, 0x91036a08, 0x10600002, 0x00001021,
+ 0x8ce20004, 0xac820028, 0x3c021000, 0xaf4201b8, 0x3c026000, 0xa1006a08,
+ 0x03e00008, 0xac400808, 0x3c058000, 0x8f4201b8, 0x00451024, 0x1440fffd,
+ 0x24020002, 0xa082000b, 0xa4830008, 0xa4860010, 0x8f420144, 0x3c031000,
+ 0xa4820012, 0x03e00008, 0xaf4301b8, 0x30c2ffff, 0x14400028, 0x00061c02,
+ 0x93620005, 0x30420004, 0x14400020, 0x3c029000, 0x34420001, 0x00e21025,
+ 0xaf420020, 0x3c038000, 0x8f420020, 0x00431024, 0x1440fffd, 0x00000000,
+ 0x93620005, 0x3c038000, 0x34630001, 0x00e31825, 0x34420004, 0xa3620005,
+ 0xaf430020, 0x93620005, 0x30420004, 0x14400003, 0x3c038000, 0x0000000d,
+ 0x3c038000, 0x8f4201b8, 0x00431024, 0x1440fffd, 0x24020005, 0x3c031000,
+ 0xac870000, 0xa082000b, 0xaf4301b8, 0x0a001473, 0x00061c02, 0x0000000d,
+ 0x03e00008, 0x00000000, 0x00061c02, 0x3c058000, 0x8f4201b8, 0x00451024,
+ 0x1440fffd, 0x24020001, 0xa4830008, 0x24030002, 0xac870000, 0xac800004,
+ 0xa082000a, 0xa083000b, 0xa4860010, 0x8f430144, 0x3c021000, 0xac800028,
+ 0xac830024, 0x03e00008, 0xaf4201b8, 0x3c058000, 0x8f4201b8, 0x00451024,
+ 0x1440fffd, 0x24020002, 0xac800000, 0xac870004, 0xa4830008, 0xa082000a,
+ 0xa082000b, 0xa4860010, 0xac800024, 0x8f420144, 0x3c031000, 0xac820028,
+ 0x03e00008, 0xaf4301b8, 0x00061c02, 0x3c058000, 0x8f4201b8, 0x00451024,
+ 0x1440fffd, 0x24020001, 0xa4830008, 0x24030002, 0xa082000a, 0x3c021000,
+ 0xac870000, 0xac800004, 0xa083000b, 0xa4860010, 0xac800024, 0xac800028,
+ 0x03e00008, 0xaf4201b8, 0x00a01821, 0x3c058000, 0x8f4201b8, 0x00451024,
+ 0x1440fffd, 0x24020002, 0xac870000, 0xac800004, 0xa4830008, 0xa080000a,
+ 0x0a00147e, 0xa082000b, 0x8f440144, 0x3c038000, 0x8f4201b8, 0x00431024,
+ 0x1440fffd, 0x24020002, 0x240340c9, 0xaf470180, 0xa342018b, 0x3c021000,
+ 0xa7430188, 0xaf4401a4, 0xaf4501a8, 0xaf4001ac, 0x03e00008, 0xaf4201b8,
+ 0x0000000d, 0x03e00008, 0x00000000, 0x03e00008, 0x00000000, 0x8f420100,
+ 0x3042003e, 0x14400011, 0x24020001, 0xaf400048, 0x8f420100, 0x304207c0,
+ 0x10400005, 0x00000000, 0xaf40004c, 0xaf400050, 0x03e00008, 0x24020001,
+ 0xaf400054, 0xaf400040, 0x8f420100, 0x30423800, 0x54400001, 0xaf400044,
+ 0x24020001, 0x03e00008, 0x00000000, 0x3c038000, 0x8f4201b8, 0x00431024,
+ 0x1440fffd, 0x24020002, 0x240340c9, 0xaf440180, 0xa342018b, 0x3c021000,
+ 0xa7430188, 0xaf4501a4, 0xaf4601a8, 0xaf4701ac, 0x03e00008, 0xaf4201b8,
+ 0x3c029000, 0x34420001, 0x00822025, 0xaf440020, 0x3c038000, 0x8f420020,
+ 0x00431024, 0x1440fffd, 0x00000000, 0x03e00008, 0x00000000, 0x3c028000,
+ 0x34420001, 0x00822025, 0x03e00008, 0xaf440020, 0x308600ff, 0x27450180,
+ 0x3c038000, 0x8f4201b8, 0x00431024, 0x1440fffd, 0x00000000, 0x8f420128,
+ 0xaca20000, 0x8f640040, 0x24030008, 0x240240c1, 0xa4a20008, 0x24020002,
+ 0xa0a2000b, 0x3c021000, 0xa0a6000a, 0xa4a30010, 0xa0a00012, 0xa0a00013,
+ 0xaca00014, 0xaca00024, 0xaca00028, 0xaca0002c, 0xaca40018, 0x03e00008,
+ 0xaf4201b8, 0x24020001, 0xacc40000, 0x03e00008, 0xa4e50000, 0x03e00008,
+ 0x24020001, 0x24020001, 0xaf400044, 0x03e00008, 0xaf400050, 0x00803021,
+ 0x27450180, 0x3c038000, 0x8f4201b8, 0x00431024, 0x1440fffd, 0x00000000,
+ 0x8f420128, 0xaca20000, 0x8cc30018, 0x240240c1, 0xa4a20008, 0xaca30018,
+ 0x90c4000a, 0x24020002, 0xa0a2000b, 0xa0a4000a, 0x94c20010, 0xa4a20010,
+ 0x90c30012, 0xa0a30012, 0x90c20013, 0xa0a20013, 0x8cc30014, 0xaca30014,
+ 0x8cc20024, 0xaca20024, 0x8cc30028, 0xaca30028, 0x8cc2002c, 0x3c031000,
+ 0xaca2002c, 0x24020001, 0xaf4301b8, 0xaf400044, 0x03e00008, 0xaf400050,
+ 0x27bdffe8, 0xafbf0010, 0x0e001032, 0x00000000, 0x00002021, 0x0e000c99,
+ 0xaf400180, 0x8fbf0010, 0x03e00008, 0x27bd0018, 0x8f460148, 0x27450180,
+ 0x3c038000, 0x00061402, 0x304700ff, 0x8f4201b8, 0x00431024, 0x1440fffd,
+ 0x00000000, 0x8f440140, 0x00061202, 0x304200ff, 0x00061c02, 0xaca20004,
+ 0x24020002, 0xa4a30008, 0x30c300ff, 0xa0a2000b, 0xaca30024, 0x10e0000a,
+ 0xaca40000, 0x28e20004, 0x14400005, 0x24020001, 0x24020005, 0x54e20005,
+ 0xa0a0000a, 0x24020001, 0x0a001571, 0xa0a2000a, 0xa0a0000a, 0x3c021000,
+ 0x03e00008, 0xaf4201b8, 0x03e00008, 0x00001021, 0x10c00007, 0x00000000,
+ 0x8ca20000, 0x24c6ffff, 0x24a50004, 0xac820000, 0x14c0fffb, 0x24840004,
+ 0x03e00008, 0x00000000, 0x0a001587, 0x00a01021, 0xac860000, 0x00000000,
+ 0x00000000, 0x24840004, 0x00a01021, 0x1440fffa, 0x24a5ffff, 0x03e00008,
+ 0x00000000, 0x00000000 };
-static u32 bnx2_RXP_b06FwData[(0x0/4) + 1] = { 0x00000000 };
-static u32 bnx2_RXP_b06FwRodata[(0x0/4) + 1] = { 0x00000000 };
-static u32 bnx2_RXP_b06FwBss[(0x239c/4) + 1] = { 0x00000000 };
-static u32 bnx2_RXP_b06FwSbss[(0x14/4) + 1] = { 0x00000000 };
+static u32 bnx2_RXP_b06FwData[(0x0/4) + 1] = { 0x0 };
+static u32 bnx2_RXP_b06FwRodata[(0x0/4) + 1] = { 0x0 };
+static u32 bnx2_RXP_b06FwBss[(0x1394/4) + 1] = { 0x0 };
+static u32 bnx2_RXP_b06FwSbss[(0x18/4) + 1] = { 0x0 };
static u32 bnx2_rv2p_proc1[] = {
0x00000008, 0xac000001, 0x0000000c, 0x2f800001, 0x00000010, 0x213f0004,
@@ -1536,249 +2298,346 @@ static u32 bnx2_rv2p_proc2[] = {
0x0000000c, 0x29520000, 0x00000018, 0x80000002, 0x0000000c, 0x29800000,
0x00000018, 0x00570000 };
-static int bnx2_TPAT_b06FwReleaseMajor = 0x0;
+static int bnx2_TPAT_b06FwReleaseMajor = 0x1;
static int bnx2_TPAT_b06FwReleaseMinor = 0x0;
static int bnx2_TPAT_b06FwReleaseFix = 0x0;
-static u32 bnx2_TPAT_b06FwStartAddr = 0x08000858;
+static u32 bnx2_TPAT_b06FwStartAddr = 0x08000860;
static u32 bnx2_TPAT_b06FwTextAddr = 0x08000800;
-static int bnx2_TPAT_b06FwTextLen = 0x1314;
-static u32 bnx2_TPAT_b06FwDataAddr = 0x08001b40;
+static int bnx2_TPAT_b06FwTextLen = 0x122c;
+static u32 bnx2_TPAT_b06FwDataAddr = 0x08001a60;
static int bnx2_TPAT_b06FwDataLen = 0x0;
static u32 bnx2_TPAT_b06FwRodataAddr = 0x00000000;
static int bnx2_TPAT_b06FwRodataLen = 0x0;
-static u32 bnx2_TPAT_b06FwBssAddr = 0x08001b90;
-static int bnx2_TPAT_b06FwBssLen = 0x80;
-static u32 bnx2_TPAT_b06FwSbssAddr = 0x08001b40;
-static int bnx2_TPAT_b06FwSbssLen = 0x48;
-
-static u32 bnx2_TPAT_b06FwText[(0x1314/4) + 1] = {
- 0x0a000216, 0x00000000, 0x00000000, 0x0000000d, 0x74706174, 0x20302e36,
- 0x2e390000, 0x00060901, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x10000003,
- 0x00000000, 0x0000000d, 0x0000000d, 0x3c020800, 0x24421b40, 0x3c030800,
- 0x24631c10, 0xac400000, 0x0043202b, 0x1480fffd, 0x24420004, 0x3c1d0800,
- 0x37bd3ffc, 0x03a0f021, 0x3c100800, 0x26100858, 0x3c1c0800, 0x279c1b40,
- 0x0e00051f, 0x00000000, 0x0000000d, 0x8f820024, 0x27bdffe8, 0xafbf0014,
- 0x10400004, 0xafb00010, 0x0000000d, 0x00000000, 0x2400015f, 0x8f82001c,
+static u32 bnx2_TPAT_b06FwBssAddr = 0x08001aa0;
+static int bnx2_TPAT_b06FwBssLen = 0x250;
+static u32 bnx2_TPAT_b06FwSbssAddr = 0x08001a60;
+static int bnx2_TPAT_b06FwSbssLen = 0x34;
+static u32 bnx2_TPAT_b06FwText[(0x122c/4) + 1] = {
+ 0x0a000218, 0x00000000, 0x00000000, 0x0000000d, 0x74706174, 0x20322e35,
+ 0x2e313100, 0x02050b01, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x10000003, 0x00000000, 0x0000000d, 0x0000000d, 0x3c020800,
+ 0x24421a60, 0x3c030800, 0x24631cf0, 0xac400000, 0x0043202b, 0x1480fffd,
+ 0x24420004, 0x3c1d0800, 0x37bd2ffc, 0x03a0f021, 0x3c100800, 0x26100860,
+ 0x3c1c0800, 0x279c1a60, 0x0e000546, 0x00000000, 0x0000000d, 0x8f820010,
0x8c450008, 0x24030800, 0xaf430178, 0x97430104, 0x3c020008, 0xaf420140,
- 0x8f820034, 0x30420001, 0x10400006, 0x3070ffff, 0x24020002, 0x2603fffe,
- 0xa7420146, 0x0a000246, 0xa7430148, 0xa7400146, 0x8f850034, 0x30a20020,
- 0x0002102b, 0x00021023, 0x30460009, 0x30a30c00, 0x24020400, 0x14620002,
- 0x34c40001, 0x34c40005, 0xa744014a, 0x3c020800, 0x8c440820, 0x3c030048,
- 0x24020002, 0x00832025, 0x30a30006, 0x1062000d, 0x2c620003, 0x50400005,
- 0x24020004, 0x10600012, 0x3c020001, 0x0a000271, 0x00000000, 0x10620007,
- 0x24020006, 0x1462000f, 0x3c020111, 0x0a000269, 0x00821025, 0x0a000268,
- 0x3c020101, 0x3c020011, 0x00821025, 0x24030001, 0xaf421000, 0xaf830030,
- 0x0a000271, 0x00000000, 0x00821025, 0xaf421000, 0xaf800030, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x8f830030, 0x1060003f, 0x3c048000,
- 0x8f421000, 0x00441024, 0x1040fffd, 0x00000000, 0x10600039, 0x00000000,
- 0x8f421000, 0x3c030020, 0x00431024, 0x10400034, 0x00000000, 0x97421014,
- 0x14400031, 0x00000000, 0x97421008, 0x8f84001c, 0x24420006, 0x00024082,
- 0x00081880, 0x00643821, 0x8ce50000, 0x30430003, 0x30420001, 0x10400004,
- 0x00000000, 0x0000000d, 0x0a0002b0, 0x00081080, 0x5460000f, 0x30a5ffff,
- 0x3c06ffff, 0x00a62824, 0x0005182b, 0x00a61026, 0x0002102b, 0x00621824,
- 0x10600004, 0x00000000, 0x0000000d, 0x00000000, 0x240001fc, 0x8ce20000,
- 0x0a0002af, 0x00462825, 0x0005182b, 0x38a2ffff, 0x0002102b, 0x00621824,
- 0x10600004, 0x00000000, 0x0000000d, 0x00000000, 0x24000206, 0x8ce20000,
- 0x3445ffff, 0x00081080, 0x00441021, 0x3c030800, 0xac450000, 0x8c620840,
- 0x24420001, 0xac620840, 0x8f820008, 0x10400003, 0x00000000, 0x0e000660,
- 0x00000000, 0x8f840028, 0x02002821, 0x24820008, 0x30421fff, 0x24434000,
- 0x0343d821, 0x30a30007, 0xaf840018, 0xaf820028, 0xaf420084, 0x10600002,
- 0x24a20007, 0x3045fff8, 0x8f820044, 0x8f840004, 0x00451821, 0xaf82002c,
- 0x0064102b, 0xaf830044, 0x14400002, 0x00641023, 0xaf820044, 0x8f840044,
- 0x34028000, 0x8fbf0014, 0x8fb00010, 0x00821021, 0x03421821, 0x3c021000,
- 0xaf83001c, 0xaf440080, 0xaf420178, 0x03e00008, 0x27bd0018, 0x8f820024,
- 0x27bdffe8, 0xafbf0014, 0x10400004, 0xafb00010, 0x0000000d, 0x00000000,
- 0x24000249, 0x8f85001c, 0x24020001, 0xaf820024, 0x8ca70008, 0xa3800023,
- 0x8f620004, 0x3c100800, 0x26041b90, 0x00021402, 0xa3820010, 0x304600ff,
- 0x24c60005, 0x0e00064a, 0x00063082, 0x8f640004, 0x8f430108, 0x3c021000,
- 0x00621824, 0xa7840020, 0x10600008, 0x00000000, 0x97420104, 0x93830023,
- 0x2442ffec, 0x34630002, 0xa3830023, 0x0a000304, 0x3045ffff, 0x97420104,
- 0x2442fff0, 0x3045ffff, 0x8f620004, 0x3042ffff, 0x2c420013, 0x14400004,
- 0x00000000, 0x93820023, 0x34420001, 0xa3820023, 0x93830023, 0x24020001,
- 0x10620009, 0x28620002, 0x14400014, 0x24020002, 0x10620012, 0x24020003,
- 0x1062000a, 0x00000000, 0x0a000325, 0x00000000, 0x8f82001c, 0x8c43000c,
- 0x3c04ffff, 0x00641824, 0x00651825, 0x0a000325, 0xac43000c, 0x8f82001c,
- 0x8c430010, 0x3c04ffff, 0x00641824, 0x00651825, 0xac430010, 0x8f620004,
- 0x3042ffff, 0x24420002, 0x00021083, 0xa3820038, 0x304500ff, 0x8f82001c,
- 0x3c04ffff, 0x00052880, 0x00a22821, 0x8ca70000, 0x97820020, 0x97430104,
- 0x00e42024, 0x24420002, 0x00621823, 0x00833825, 0xaca70000, 0x93840038,
- 0x26061b90, 0x00041080, 0x00461021, 0x90430000, 0x3063000f, 0x00832021,
- 0xa3840022, 0x308200ff, 0x3c04fff6, 0x24420003, 0x00021080, 0x00461021,
- 0x8c450000, 0x93830022, 0x8f82001c, 0x3484ffff, 0x00a43824, 0x00031880,
- 0x00621821, 0xaf850000, 0xac67000c, 0x93820022, 0x93830022, 0x8f84001c,
- 0x24420003, 0x00021080, 0x00461021, 0x24630004, 0x00031880, 0xac470000,
- 0x93820022, 0x00661821, 0x94670002, 0x00021080, 0x00441021, 0xac670000,
- 0x24030010, 0xac470010, 0xa7430140, 0x24030002, 0xa7400142, 0xa7400144,
- 0xa7430146, 0x97420104, 0x8f840034, 0x24030001, 0x2442fffe, 0x30840006,
- 0xa7420148, 0x24020002, 0xa743014a, 0x1082000d, 0x2c820003, 0x10400005,
- 0x24020004, 0x10800011, 0x3c020009, 0x0a000383, 0x00000000, 0x10820007,
- 0x24020006, 0x1482000d, 0x3c020119, 0x0a00037d, 0x24030001, 0x0a00037c,
- 0x3c020109, 0x3c020019, 0x24030001, 0xaf421000, 0xaf830030, 0x0a000383,
- 0x00000000, 0xaf421000, 0xaf800030, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x93820010, 0x24030008, 0x8f840030, 0x24420002, 0x30420007,
- 0x00621823, 0x30630007, 0xaf83000c, 0x10800005, 0x3c038000, 0x8f421000,
- 0x00431024, 0x1040fffd, 0x00000000, 0x8f820028, 0xaf820018, 0x24420010,
- 0x30421fff, 0xaf820028, 0xaf420084, 0x97430104, 0x24424000, 0x0342d821,
- 0x3063ffff, 0x30620007, 0x10400002, 0x24620007, 0x3043fff8, 0x8f820044,
- 0x8f840004, 0x00431821, 0xaf82002c, 0x0064102b, 0xaf830044, 0x14400002,
- 0x00641023, 0xaf820044, 0x8f840044, 0x34028000, 0x8fbf0014, 0x8fb00010,
- 0x00821021, 0x03421821, 0x3c021000, 0xaf83001c, 0xaf440080, 0xaf420178,
- 0x03e00008, 0x27bd0018, 0x8f820024, 0x27bdffe8, 0xafbf0014, 0x14400004,
- 0xafb00010, 0x0000000d, 0x00000000, 0x240002db, 0x8f620004, 0x04410009,
- 0x3c050800, 0x93820022, 0x8f830000, 0x24a41b90, 0xaf800024, 0x24420003,
- 0x00021080, 0x00441021, 0xac430000, 0x93820038, 0x24a51b90, 0x93860010,
- 0x3c040001, 0x27700008, 0x24420001, 0x00021080, 0x00451021, 0x8c430000,
- 0x24c60005, 0x00063082, 0x00641821, 0x02002021, 0x0e00064a, 0xac430000,
- 0x93840022, 0x3c057fff, 0x8f620004, 0x00042080, 0x00902021, 0x8c830004,
- 0x34a5ffff, 0x00451024, 0x00621821, 0xac830004, 0x93850038, 0x3c07ffff,
- 0x93840010, 0x00052880, 0x00b02821, 0x8ca30000, 0x97420104, 0x97860020,
- 0x00671824, 0x00441021, 0x00461023, 0x3042ffff, 0x00621825, 0xaca30000,
- 0x93830023, 0x24020001, 0x10620009, 0x28620002, 0x1440001a, 0x24020002,
- 0x10620018, 0x24020003, 0x1062000d, 0x00000000, 0x0a000411, 0x00000000,
- 0x93820010, 0x97430104, 0x8e04000c, 0x00621821, 0x2463fff2, 0x3063ffff,
- 0x00872024, 0x00832025, 0x0a000411, 0xae04000c, 0x93820010, 0x97430104,
- 0x8e040010, 0x00621821, 0x2463ffee, 0x3063ffff, 0x00872024, 0x00832025,
- 0xae040010, 0x9783000e, 0x8f840034, 0x2402000a, 0xa7420140, 0xa7430142,
- 0x93820010, 0xa7420144, 0xa7400146, 0x97430104, 0x30840006, 0x24020001,
- 0xa7430148, 0xa742014a, 0x24020002, 0x1082000d, 0x2c820003, 0x10400005,
- 0x24020004, 0x10800011, 0x3c020041, 0x0a000437, 0x00000000, 0x10820007,
- 0x24020006, 0x1482000d, 0x3c020151, 0x0a000431, 0x24030001, 0x0a000430,
- 0x3c020141, 0x3c020051, 0x24030001, 0xaf421000, 0xaf830030, 0x0a000437,
- 0x00000000, 0xaf421000, 0xaf800030, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x8f820030, 0x93840010, 0x8f850028, 0x10400005, 0x3c038000,
- 0x8f421000, 0x00431024, 0x1040fffd, 0x00000000, 0x2483000a, 0x30620007,
- 0x10400002, 0x24620007, 0x304303f8, 0x00a31021, 0x30421fff, 0xaf850018,
- 0xaf820028, 0xaf420084, 0x97430104, 0x24424000, 0x0342d821, 0x3063ffff,
- 0x30620007, 0x10400002, 0x24620007, 0x3043fff8, 0x8f820044, 0x8f840004,
- 0x00431821, 0xaf82002c, 0x0064102b, 0xaf830044, 0x14400002, 0x00641023,
- 0xaf820044, 0x8f840044, 0x34028000, 0x8fbf0014, 0x8fb00010, 0x00821021,
- 0x03421821, 0x3c021000, 0xaf83001c, 0xaf440080, 0xaf420178, 0x03e00008,
- 0x27bd0018, 0x3c026000, 0x8c444448, 0x3c030800, 0xac64082c, 0x8f620000,
- 0x97430104, 0x3c048000, 0x3046ffff, 0x3067ffff, 0x8f420178, 0x00441024,
- 0x1440fffd, 0x2402000a, 0x30c30007, 0xa7420140, 0x24020008, 0x00431023,
- 0x30420007, 0x24c3fffe, 0xa7420142, 0xa7430144, 0xa7400146, 0xa7470148,
- 0x8f420108, 0x3c036000, 0x8f850034, 0x30420020, 0x0002102b, 0x00021023,
- 0x30420009, 0x34420001, 0xa742014a, 0x8c644448, 0x3c020800, 0x30a50006,
- 0xac440830, 0x24020002, 0x10a2000d, 0x2ca20003, 0x10400005, 0x24020004,
- 0x10a00011, 0x3c020041, 0x0a0004a8, 0x00000000, 0x10a20007, 0x24020006,
- 0x14a2000d, 0x3c020151, 0x0a0004a2, 0x24030001, 0x0a0004a1, 0x3c020141,
- 0x3c020051, 0x24030001, 0xaf421000, 0xaf830030, 0x0a0004a8, 0x00000000,
- 0xaf421000, 0xaf800030, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x8f820030, 0x24c30008, 0x10400006, 0x30e6ffff, 0x3c048000, 0x8f421000,
- 0x00441024, 0x1040fffd, 0x00000000, 0x3c026000, 0x8c444448, 0x3065ffff,
- 0x3c020800, 0x30a30007, 0x10600003, 0xac440834, 0x24a20007, 0x3045fff8,
- 0x8f840028, 0x00851021, 0x30421fff, 0x24434000, 0x0343d821, 0x30c30007,
- 0xaf840018, 0xaf820028, 0xaf420084, 0x10600002, 0x24c20007, 0x3046fff8,
- 0x8f820044, 0x8f840004, 0x00461821, 0xaf82002c, 0x0064102b, 0xaf830044,
- 0x14400002, 0x00641023, 0xaf820044, 0x8f840044, 0x34028000, 0x3c030800,
- 0x8c650844, 0x00821021, 0x03421821, 0xaf83001c, 0xaf440080, 0x10a00006,
- 0x2402000e, 0x93830043, 0x14620004, 0x3c021000, 0x2402043f, 0xa7420148,
- 0x3c021000, 0x3c036000, 0xaf420178, 0x8c644448, 0x3c020800, 0x03e00008,
- 0xac440838, 0x8f820034, 0x30424000, 0x10400005, 0x24020800, 0x0000000d,
- 0x00000000, 0x24000405, 0x24020800, 0xaf420178, 0x97440104, 0x3c030008,
- 0xaf430140, 0x8f820034, 0x30420001, 0x10400006, 0x3085ffff, 0x24020002,
- 0x24a3fffe, 0xa7420146, 0x0a0004ff, 0xa7430148, 0xa7400146, 0x8f840028,
- 0x2402000d, 0xa742014a, 0x24830008, 0x30631fff, 0x24624000, 0x0342d821,
- 0x30a20007, 0xaf840018, 0xaf830028, 0xaf430084, 0x10400002, 0x24a20007,
- 0x3045fff8, 0x8f820044, 0x8f840004, 0x00451821, 0xaf82002c, 0x0064102b,
- 0xaf830044, 0x14400002, 0x00641023, 0xaf820044, 0x8f840044, 0x34028000,
- 0x00821021, 0x03421821, 0x3c021000, 0xaf83001c, 0xaf440080, 0x03e00008,
- 0xaf420178, 0x27bdffe8, 0x3c046008, 0xafbf0014, 0xafb00010, 0x8c825000,
- 0x3c1a8000, 0x2403ff7f, 0x375b4000, 0x00431024, 0x3442380c, 0xac825000,
- 0x8f430008, 0x3c100800, 0x37428000, 0x34630001, 0xaf430008, 0xaf82001c,
- 0x3c02601c, 0xaf800028, 0xaf400080, 0xaf400084, 0x8c450008, 0x3c036000,
- 0x8c620808, 0x3c040800, 0x3c030080, 0xac830820, 0x3042fff0, 0x38420010,
- 0x2c420001, 0xaf850004, 0xaf820008, 0x0e00062f, 0x00000000, 0x8f420000,
- 0x30420001, 0x1040fffb, 0x00000000, 0x8f440108, 0x30822000, 0xaf840034,
- 0x10400004, 0x8e02083c, 0x24420001, 0x0a00059d, 0xae02083c, 0x30820200,
- 0x10400027, 0x00000000, 0x97420104, 0x1040001c, 0x30824000, 0x14400005,
- 0x00000000, 0x0e00022d, 0x00000000, 0x0a000592, 0x00000000, 0x8f620008,
- 0x8f630000, 0x24020030, 0x00031e02, 0x306300f0, 0x10620007, 0x28620031,
- 0x14400031, 0x24020040, 0x10620007, 0x00000000, 0x0a000592, 0x00000000,
- 0x0e0002dd, 0x00000000, 0x0a000592, 0x00000000, 0x0e0003b8, 0x00000000,
- 0x0a000592, 0x00000000, 0x30820040, 0x1440002d, 0x00000000, 0x0000000d,
- 0x00000000, 0x240004a6, 0x0a00059d, 0x00000000, 0x8f430100, 0x24020d00,
- 0x1462000f, 0x30820006, 0x97420104, 0x10400005, 0x30820040, 0x0e0004e9,
- 0x00000000, 0x0a000592, 0x00000000, 0x1440001b, 0x00000000, 0x0000000d,
- 0x00000000, 0x240004b8, 0x0a00059d, 0x00000000, 0x1040000e, 0x30821000,
- 0x10400005, 0x00000000, 0x0e00065d, 0x00000000, 0x0a000592, 0x00000000,
- 0x0e00046b, 0x00000000, 0x8f820040, 0x24420001, 0xaf820040, 0x0a00059d,
- 0x00000000, 0x30820040, 0x14400004, 0x00000000, 0x0000000d, 0x00000000,
- 0x240004cf, 0x8f420138, 0x3c034000, 0x00431025, 0xaf420138, 0x0a00053f,
- 0x00000000, 0x3c046008, 0x8c835000, 0x3c1a8000, 0x2402ff7f, 0x375b4000,
- 0x00621824, 0x3463380c, 0xac835000, 0x8f420008, 0x3c056000, 0x3c03601c,
- 0x34420001, 0xaf420008, 0x37428000, 0xaf800028, 0xaf82001c, 0xaf400080,
- 0xaf400084, 0x8c660008, 0x8ca20808, 0x3c040800, 0x3c030080, 0xac830820,
- 0x3042fff0, 0x38420010, 0x2c420001, 0xaf860004, 0xaf820008, 0x03e00008,
- 0x00000000, 0x3084ffff, 0x30820007, 0x10400002, 0x24820007, 0x3044fff8,
- 0x8f820028, 0x00441821, 0x30631fff, 0x24644000, 0x0344d821, 0xaf820018,
- 0xaf830028, 0x03e00008, 0xaf430084, 0x3084ffff, 0x30820007, 0x10400002,
- 0x24820007, 0x3044fff8, 0x8f820044, 0x8f830004, 0x00442021, 0xaf82002c,
- 0x0083102b, 0xaf840044, 0x14400002, 0x00831023, 0xaf820044, 0x8f820044,
- 0x34038000, 0x00431821, 0x03432021, 0xaf84001c, 0x03e00008, 0xaf420080,
- 0x8f830034, 0x24020002, 0x30630006, 0x1062000d, 0x2c620003, 0x50400005,
- 0x24020004, 0x10600012, 0x3c020001, 0x0a000601, 0x00000000, 0x10620007,
- 0x24020006, 0x1462000f, 0x3c020111, 0x0a0005f9, 0x00821025, 0x0a0005f8,
- 0x3c020101, 0x3c020011, 0x00821025, 0x24030001, 0xaf421000, 0xaf830030,
- 0x0a000601, 0x00000000, 0x00821025, 0xaf421000, 0xaf800030, 0x00000000,
- 0x00000000, 0x00000000, 0x03e00008, 0x00000000, 0x8f820030, 0x10400005,
- 0x3c038000, 0x8f421000, 0x00431024, 0x1040fffd, 0x00000000, 0x03e00008,
- 0x00000000, 0x8f820034, 0x27bdffe8, 0x30424000, 0x14400005, 0xafbf0010,
- 0x0e00022d, 0x00000000, 0x0a00062d, 0x8fbf0010, 0x8f620008, 0x8f630000,
- 0x24020030, 0x00031e02, 0x306300f0, 0x10620008, 0x28620031, 0x1440000d,
- 0x8fbf0010, 0x24020040, 0x10620007, 0x00000000, 0x0a00062d, 0x00000000,
- 0x0e0002dd, 0x00000000, 0x0a00062d, 0x8fbf0010, 0x0e0003b8, 0x00000000,
- 0x8fbf0010, 0x03e00008, 0x27bd0018, 0x8f84003c, 0x1080000f, 0x3c026000,
- 0x8c430c3c, 0x30630fff, 0xaf830014, 0x14600011, 0x3082000f, 0x10400005,
- 0x308200f0, 0x10400003, 0x30820f00, 0x14400006, 0x00000000, 0x0000000d,
- 0x00000000, 0x2400050e, 0x03e00008, 0x00000000, 0x0000000d, 0x00000000,
- 0x24000513, 0x03e00008, 0x00000000, 0xaf83003c, 0x03e00008, 0x00000000,
- 0x10c00007, 0x00000000, 0x8ca20000, 0x24c6ffff, 0x24a50004, 0xac820000,
- 0x14c0fffb, 0x24840004, 0x03e00008, 0x00000000, 0x0a000659, 0x00a01021,
- 0xac860000, 0x24840004, 0x00a01021, 0x1440fffc, 0x24a5ffff, 0x03e00008,
- 0x00000000, 0x0000000d, 0x03e00008, 0x00000000, 0x3c040800, 0x8c82084c,
- 0x54400007, 0xac80084c, 0x8f820034, 0x24030400, 0x30420c00, 0x1443005b,
- 0x00000000, 0xac80084c, 0x0000000d, 0x00000000, 0x2400003c, 0x3c026000,
- 0x8c444448, 0x3c030800, 0xac640850, 0x24000043, 0x97420104, 0x3045ffff,
- 0x000530c2, 0x24a2007f, 0x000239c2, 0x2400004e, 0x3c046020, 0x24030020,
- 0xac830000, 0x8c820000, 0x30420020, 0x10400005, 0x3c036020, 0x8c620000,
- 0x30420020, 0x1440fffd, 0x00000000, 0x3c026020, 0x8c430010, 0x24040001,
- 0x0087102b, 0x30ea007f, 0x24abfffe, 0x10400010, 0x00034240, 0x3c056020,
- 0x24090020, 0xaca90000, 0x8ca20000, 0x30420020, 0x10400006, 0x24840001,
- 0x3c036020, 0x8c620000, 0x30420020, 0x1440fffd, 0x00000000, 0x0087102b,
- 0x1440fff4, 0x00000000, 0x8f85001c, 0x3c026020, 0x8c430010, 0x3c046020,
- 0x34848000, 0x006a1825, 0x01034025, 0x2400006b, 0x10c0000b, 0x00000000,
- 0x8ca30000, 0x24a50004, 0x8ca20000, 0x24a50004, 0x24c6ffff, 0xac820000,
- 0x24840004, 0xac830000, 0x14c0fff7, 0x24840004, 0x24000077, 0x3c020007,
- 0x34427700, 0x3c036000, 0xac6223c8, 0xac6b23cc, 0xac6823e4, 0x24000086,
- 0x3c046000, 0x3c038000, 0x8c8223f8, 0x00431024, 0x1440fffd, 0x3c021000,
- 0x3c056000, 0x24030019, 0xaca223f8, 0xa743014a, 0x8ca44448, 0x3c020800,
- 0xac440854, 0x03e00008, 0x00000000, 0x00000000 };
+ 0x8f820024, 0x30420001, 0x10400007, 0x3069ffff, 0x24020002, 0x2523fffe,
+ 0xa7420146, 0xa7430148, 0x0a000242, 0x3c020800, 0xa7400146, 0x3c020800,
+ 0x8c43083c, 0x1460000e, 0x24020f00, 0x8f820024, 0x30430020, 0x0003182b,
+ 0x00031823, 0x30650009, 0x30420c00, 0x24030400, 0x14430002, 0x34a40001,
+ 0x34a40005, 0xa744014a, 0x0a000264, 0x3c020800, 0x8f830014, 0x14620008,
+ 0x00000000, 0x8f820024, 0x30420020, 0x0002102b, 0x00021023, 0x3042000d,
+ 0x0a000262, 0x34420005, 0x8f820024, 0x30420020, 0x0002102b, 0x00021023,
+ 0x30420009, 0x34420001, 0xa742014a, 0x3c020800, 0x8c430820, 0x8f840024,
+ 0x3c020048, 0x00621825, 0x30840006, 0x24020002, 0x1082000d, 0x2c820003,
+ 0x50400005, 0x24020004, 0x10800012, 0x3c020001, 0x0a000284, 0x00000000,
+ 0x10820007, 0x24020006, 0x1482000f, 0x3c020111, 0x0a00027c, 0x00621025,
+ 0x0a00027b, 0x3c020101, 0x3c020011, 0x00621025, 0x24030001, 0xaf421000,
+ 0xaf830020, 0x0a000284, 0x00000000, 0x00621025, 0xaf421000, 0xaf800020,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x8f830020, 0x1060003f,
+ 0x3c048000, 0x8f421000, 0x00441024, 0x1040fffd, 0x00000000, 0x10600039,
+ 0x00000000, 0x8f421000, 0x3c030020, 0x00431024, 0x10400034, 0x00000000,
+ 0x97421014, 0x14400031, 0x00000000, 0x97421008, 0x8f840010, 0x24420006,
+ 0x00024082, 0x00081880, 0x00643821, 0x8ce50000, 0x30430003, 0x30420001,
+ 0x10400004, 0x00000000, 0x0000000d, 0x0a0002c3, 0x00081080, 0x5460000f,
+ 0x30a5ffff, 0x3c06ffff, 0x00a62824, 0x0005182b, 0x00a61026, 0x0002102b,
+ 0x00621824, 0x10600004, 0x00000000, 0x0000000d, 0x00000000, 0x240001fb,
+ 0x8ce20000, 0x0a0002c2, 0x00462825, 0x0005182b, 0x38a2ffff, 0x0002102b,
+ 0x00621824, 0x10600004, 0x00000000, 0x0000000d, 0x00000000, 0x24000205,
+ 0x8ce20000, 0x3445ffff, 0x00081080, 0x00441021, 0x3c030800, 0xac450000,
+ 0x8c620830, 0x24420001, 0xac620830, 0x8f840018, 0x01202821, 0x24820008,
+ 0x30421fff, 0x24434000, 0x0343d821, 0x30a30007, 0xaf84000c, 0xaf820018,
+ 0xaf420084, 0x10600002, 0x24a20007, 0x3045fff8, 0x8f820030, 0x8f840000,
+ 0x00451821, 0xaf82001c, 0x0064102b, 0xaf830030, 0x14400002, 0x00641023,
+ 0xaf820030, 0x8f840030, 0x34028000, 0x00821021, 0x03421821, 0x3c021000,
+ 0xaf830010, 0xaf440080, 0x03e00008, 0xaf420178, 0x8f830024, 0x27bdffe0,
+ 0xafbf0018, 0xafb10014, 0x30620200, 0x14400004, 0xafb00010, 0x0000000d,
+ 0x00000000, 0x24000242, 0x00031a82, 0x30630003, 0x000310c0, 0x00431021,
+ 0x00021080, 0x00431021, 0x00021080, 0x3c030800, 0x24631aa0, 0x00438821,
+ 0x8e240000, 0x10800004, 0x00000000, 0x0000000d, 0x00000000, 0x2400024d,
+ 0x8f850010, 0x24020001, 0xae220000, 0x8ca70008, 0xa2200007, 0x8f620004,
+ 0x26300014, 0x02002021, 0x00021402, 0xa2220004, 0x304600ff, 0x24c60005,
+ 0x0e000673, 0x00063082, 0x8f620004, 0xa6220008, 0x8f430108, 0x3c021000,
+ 0x00621824, 0x10600008, 0x00000000, 0x97420104, 0x92230007, 0x2442ffec,
+ 0x3045ffff, 0x34630002, 0x0a000321, 0xa2230007, 0x97420104, 0x2442fff0,
+ 0x3045ffff, 0x8f620004, 0x3042ffff, 0x2c420013, 0x54400005, 0x92230007,
+ 0x92220007, 0x34420001, 0xa2220007, 0x92230007, 0x24020001, 0x10620009,
+ 0x28620002, 0x14400014, 0x24020002, 0x10620012, 0x24020003, 0x1062000a,
+ 0x00000000, 0x0a000342, 0x00000000, 0x8f820010, 0x8c43000c, 0x3c04ffff,
+ 0x00641824, 0x00651825, 0x0a000342, 0xac43000c, 0x8f820010, 0x8c430010,
+ 0x3c04ffff, 0x00641824, 0x00651825, 0xac430010, 0x8f620004, 0x3042ffff,
+ 0x24420002, 0x00021083, 0xa2220005, 0x304500ff, 0x8f820010, 0x3c04ffff,
+ 0x00052880, 0x00a22821, 0x8ca70000, 0x96220008, 0x97430104, 0x00e42024,
+ 0x24420002, 0x00621823, 0x00833825, 0xaca70000, 0x92240005, 0x00041080,
+ 0x02021021, 0x90430000, 0x3c05fff6, 0x34a5ffff, 0x3063000f, 0x00832021,
+ 0xa2240006, 0x308200ff, 0x24420003, 0x00021080, 0x02021021, 0x8c460000,
+ 0x308300ff, 0x8f820010, 0x3c04ff3f, 0x00031880, 0x00c53824, 0x00621821,
+ 0xae26000c, 0xac67000c, 0x8e22000c, 0x92230006, 0x3484ffff, 0x00441024,
+ 0x24630003, 0x00031880, 0x02031821, 0x00e42024, 0xae22000c, 0xac640000,
+ 0x92220006, 0x24420004, 0x00021080, 0x02021021, 0x94470002, 0xac470000,
+ 0x92230006, 0x8f820010, 0x00031880, 0x00621821, 0x24020010, 0xac670010,
+ 0x24030002, 0xa7420140, 0xa7400142, 0xa7400144, 0xa7430146, 0x97420104,
+ 0x24030001, 0x2442fffe, 0xa7420148, 0xa743014a, 0x8f820024, 0x24030002,
+ 0x30440006, 0x1083000d, 0x2c820003, 0x10400005, 0x24020004, 0x10800011,
+ 0x3c020009, 0x0a0003a5, 0x00000000, 0x10820007, 0x24020006, 0x1482000d,
+ 0x3c020119, 0x0a00039f, 0x24030001, 0x0a00039e, 0x3c020109, 0x3c020019,
+ 0x24030001, 0xaf421000, 0xaf830020, 0x0a0003a5, 0x00000000, 0xaf421000,
+ 0xaf800020, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x92220004,
+ 0x24030008, 0x8f840020, 0x24420002, 0x30420007, 0x00621823, 0x30630007,
+ 0x10800006, 0xae230010, 0x3c038000, 0x8f421000, 0x00431024, 0x1040fffd,
+ 0x00000000, 0x8f820018, 0xaf82000c, 0x24420010, 0x30421fff, 0xaf820018,
+ 0xaf420084, 0x97430104, 0x24424000, 0x0342d821, 0x3063ffff, 0x30620007,
+ 0x10400002, 0x24620007, 0x3043fff8, 0x8f820030, 0x8f840000, 0x00431821,
+ 0xaf82001c, 0x0064102b, 0xaf830030, 0x14400002, 0x00641023, 0xaf820030,
+ 0x8f840030, 0x34028000, 0x8fbf0018, 0x8fb10014, 0x8fb00010, 0x00821021,
+ 0x03421821, 0x3c021000, 0xaf830010, 0xaf440080, 0xaf420178, 0x03e00008,
+ 0x27bd0020, 0x8f830024, 0x27bdffe0, 0xafbf0018, 0xafb10014, 0x30620200,
+ 0x14400004, 0xafb00010, 0x0000000d, 0x00000000, 0x240002e4, 0x00031a82,
+ 0x30630003, 0x000310c0, 0x00431021, 0x00021080, 0x00431021, 0x00021080,
+ 0x3c030800, 0x24631aa0, 0x00438021, 0x8e040000, 0x14800004, 0x00000000,
+ 0x0000000d, 0x00000000, 0x240002e9, 0x8f620004, 0x04410008, 0x26050014,
+ 0x92020006, 0x8e03000c, 0x24420003, 0x00021080, 0x00a21021, 0xac430000,
+ 0xae000000, 0x92020005, 0x24420001, 0x00021080, 0x00a21021, 0x8c430000,
+ 0x3c040001, 0x00641821, 0xac430000, 0x92060004, 0x27710008, 0x02202021,
+ 0x24c60005, 0x0e000673, 0x00063082, 0x92040006, 0x3c057fff, 0x8f620004,
+ 0x00042080, 0x00912021, 0x8c830004, 0x34a5ffff, 0x00451024, 0x00621821,
+ 0xac830004, 0x92050005, 0x3c07ffff, 0x92040004, 0x00052880, 0x00b12821,
+ 0x8ca30000, 0x97420104, 0x96060008, 0x00671824, 0x00441021, 0x00461023,
+ 0x3042ffff, 0x00621825, 0xaca30000, 0x92030007, 0x24020001, 0x1062000a,
+ 0x28620002, 0x1440001d, 0x2402000a, 0x24020002, 0x10620019, 0x24020003,
+ 0x1062000e, 0x2402000a, 0x0a000447, 0x00000000, 0x92020004, 0x97430104,
+ 0x8e24000c, 0x00621821, 0x2463fff2, 0x3063ffff, 0x00872024, 0x00832025,
+ 0xae24000c, 0x0a000447, 0x2402000a, 0x92020004, 0x97430104, 0x8e240010,
+ 0x00621821, 0x2463ffee, 0x3063ffff, 0x00872024, 0x00832025, 0xae240010,
+ 0x2402000a, 0xa7420140, 0x96030012, 0x8f840024, 0xa7430142, 0x92020004,
+ 0xa7420144, 0xa7400146, 0x97430104, 0x30840006, 0x24020001, 0xa7430148,
+ 0xa742014a, 0x24020002, 0x1082000d, 0x2c820003, 0x10400005, 0x24020004,
+ 0x10800011, 0x3c020041, 0x0a00046c, 0x00000000, 0x10820007, 0x24020006,
+ 0x1482000d, 0x3c020151, 0x0a000466, 0x24030001, 0x0a000465, 0x3c020141,
+ 0x3c020051, 0x24030001, 0xaf421000, 0xaf830020, 0x0a00046c, 0x00000000,
+ 0xaf421000, 0xaf800020, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x8f820020, 0x8f840018, 0x10400006, 0x92030004, 0x3c058000, 0x8f421000,
+ 0x00451024, 0x1040fffd, 0x00000000, 0x2463000a, 0x30620007, 0x10400002,
+ 0x24620007, 0x304303f8, 0x00831021, 0x30421fff, 0xaf84000c, 0xaf820018,
+ 0xaf420084, 0x97430104, 0x24424000, 0x0342d821, 0x3063ffff, 0x30620007,
+ 0x10400002, 0x24620007, 0x3043fff8, 0x8f820030, 0x8f840000, 0x00431821,
+ 0xaf82001c, 0x0064102b, 0xaf830030, 0x14400002, 0x00641023, 0xaf820030,
+ 0x8f840030, 0x34028000, 0x8fbf0018, 0x8fb10014, 0x8fb00010, 0x00821021,
+ 0x03421821, 0x3c021000, 0xaf830010, 0xaf440080, 0xaf420178, 0x03e00008,
+ 0x27bd0020, 0x8f620000, 0x97430104, 0x3c048000, 0x3045ffff, 0x3066ffff,
+ 0x8f420178, 0x00441024, 0x1440fffd, 0x2402000a, 0x30a30007, 0xa7420140,
+ 0x24020008, 0x00431023, 0x30420007, 0x24a3fffe, 0xa7420142, 0xa7430144,
+ 0xa7400146, 0xa7460148, 0x8f420108, 0x8f830024, 0x30420020, 0x0002102b,
+ 0x00021023, 0x30420009, 0x34420001, 0x30630006, 0xa742014a, 0x24020002,
+ 0x1062000d, 0x2c620003, 0x10400005, 0x24020004, 0x10600011, 0x3c020041,
+ 0x0a0004d6, 0x00000000, 0x10620007, 0x24020006, 0x1462000d, 0x3c020151,
+ 0x0a0004d0, 0x24030001, 0x0a0004cf, 0x3c020141, 0x3c020051, 0x24030001,
+ 0xaf421000, 0xaf830020, 0x0a0004d6, 0x00000000, 0xaf421000, 0xaf800020,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x8f820020, 0x24a30008,
+ 0x8f850018, 0x10400006, 0x30c6ffff, 0x3c048000, 0x8f421000, 0x00441024,
+ 0x1040fffd, 0x00000000, 0x3063ffff, 0x30620007, 0x10400002, 0x24620007,
+ 0x3043fff8, 0x00a31021, 0x30421fff, 0x24434000, 0x0343d821, 0x00c02021,
+ 0x30830007, 0xaf85000c, 0xaf820018, 0xaf420084, 0x10600002, 0x24820007,
+ 0x3044fff8, 0x8f820030, 0x8f850000, 0x00441821, 0xaf82001c, 0x0065102b,
+ 0xaf830030, 0x14400002, 0x00651023, 0xaf820030, 0x8f840030, 0x34028000,
+ 0x3c030800, 0x8c650834, 0x00821021, 0x03421821, 0xaf830010, 0xaf440080,
+ 0x10a00006, 0x2402000e, 0x9383002f, 0x14620004, 0x3c021000, 0x2402043f,
+ 0xa7420148, 0x3c021000, 0x03e00008, 0xaf420178, 0x8f820024, 0x30424000,
+ 0x10400005, 0x24020800, 0x0000000d, 0x00000000, 0x2400040e, 0x24020800,
+ 0xaf420178, 0x97440104, 0x3c030008, 0xaf430140, 0x8f820024, 0x30420001,
+ 0x10400006, 0x3085ffff, 0x24020002, 0x24a3fffe, 0xa7420146, 0x0a000526,
+ 0xa7430148, 0xa7400146, 0x8f840018, 0x2402000d, 0xa742014a, 0x24830008,
+ 0x30631fff, 0x24624000, 0x0342d821, 0x30a20007, 0xaf84000c, 0xaf830018,
+ 0xaf430084, 0x10400002, 0x24a20007, 0x3045fff8, 0x8f820030, 0x8f840000,
+ 0x00451821, 0xaf82001c, 0x0064102b, 0xaf830030, 0x14400002, 0x00641023,
+ 0xaf820030, 0x8f840030, 0x34028000, 0x00821021, 0x03421821, 0x3c021000,
+ 0xaf830010, 0xaf440080, 0x03e00008, 0xaf420178, 0x27bdffe8, 0x3c046008,
+ 0xafbf0014, 0xafb00010, 0x8c825000, 0x3c1a8000, 0x2403ff7f, 0x375b4000,
+ 0x00431024, 0x3442380c, 0xac825000, 0x8f430008, 0x3c100800, 0x37428000,
+ 0x34630001, 0xaf430008, 0xaf820010, 0x3c02601c, 0xaf800018, 0xaf400080,
+ 0xaf400084, 0x8c450008, 0x3c036000, 0x8c620808, 0x3c040800, 0x3c030080,
+ 0xac830820, 0x3042fff0, 0x38420010, 0x2c420001, 0xaf850000, 0xaf820004,
+ 0x0e000658, 0x00000000, 0x8f420000, 0x30420001, 0x1040fffb, 0x00000000,
+ 0x8f430108, 0x8f440100, 0x30622000, 0xaf830024, 0xaf840014, 0x10400004,
+ 0x8e02082c, 0x24420001, 0x0a0005c6, 0xae02082c, 0x30620200, 0x14400003,
+ 0x24020f00, 0x14820027, 0x24020d00, 0x97420104, 0x1040001c, 0x30624000,
+ 0x14400005, 0x00000000, 0x0e00022f, 0x00000000, 0x0a0005bb, 0x00000000,
+ 0x8f620008, 0x8f630000, 0x24020030, 0x00031e02, 0x306300f0, 0x10620007,
+ 0x28620031, 0x1440002f, 0x24020040, 0x10620007, 0x00000000, 0x0a0005bb,
+ 0x00000000, 0x0e0002e8, 0x00000000, 0x0a0005bb, 0x00000000, 0x0e0003db,
+ 0x00000000, 0x0a0005bb, 0x00000000, 0x30620040, 0x1440002b, 0x00000000,
+ 0x0000000d, 0x00000000, 0x240004b2, 0x0a0005c6, 0x00000000, 0x1482000f,
+ 0x30620006, 0x97420104, 0x10400005, 0x30620040, 0x0e000510, 0x00000000,
+ 0x0a0005bb, 0x00000000, 0x1440001b, 0x00000000, 0x0000000d, 0x00000000,
+ 0x240004c4, 0x0a0005c6, 0x00000000, 0x1040000e, 0x30621000, 0x10400005,
+ 0x00000000, 0x0e000688, 0x00000000, 0x0a0005bb, 0x00000000, 0x0e0004a1,
+ 0x00000000, 0x8f82002c, 0x24420001, 0xaf82002c, 0x0a0005c6, 0x00000000,
+ 0x30620040, 0x14400004, 0x00000000, 0x0000000d, 0x00000000, 0x240004db,
+ 0x8f420138, 0x3c034000, 0x00431025, 0xaf420138, 0x0a000566, 0x00000000,
+ 0x3c046008, 0x8c835000, 0x3c1a8000, 0x2402ff7f, 0x375b4000, 0x00621824,
+ 0x3463380c, 0xac835000, 0x8f420008, 0x3c056000, 0x3c03601c, 0x34420001,
+ 0xaf420008, 0x37428000, 0xaf800018, 0xaf820010, 0xaf400080, 0xaf400084,
+ 0x8c660008, 0x8ca20808, 0x3c040800, 0x3c030080, 0xac830820, 0x3042fff0,
+ 0x38420010, 0x2c420001, 0xaf860000, 0xaf820004, 0x03e00008, 0x00000000,
+ 0x3084ffff, 0x30820007, 0x10400002, 0x24820007, 0x3044fff8, 0x8f820018,
+ 0x00441821, 0x30631fff, 0x24644000, 0x0344d821, 0xaf82000c, 0xaf830018,
+ 0x03e00008, 0xaf430084, 0x3084ffff, 0x30820007, 0x10400002, 0x24820007,
+ 0x3044fff8, 0x8f820030, 0x8f830000, 0x00442021, 0xaf82001c, 0x0083102b,
+ 0xaf840030, 0x14400002, 0x00831023, 0xaf820030, 0x8f820030, 0x34038000,
+ 0x00431821, 0x03432021, 0xaf840010, 0x03e00008, 0xaf420080, 0x8f830024,
+ 0x24020002, 0x30630006, 0x1062000d, 0x2c620003, 0x50400005, 0x24020004,
+ 0x10600012, 0x3c020001, 0x0a00062a, 0x00000000, 0x10620007, 0x24020006,
+ 0x1462000f, 0x3c020111, 0x0a000622, 0x00821025, 0x0a000621, 0x3c020101,
+ 0x3c020011, 0x00821025, 0x24030001, 0xaf421000, 0xaf830020, 0x0a00062a,
+ 0x00000000, 0x00821025, 0xaf421000, 0xaf800020, 0x00000000, 0x00000000,
+ 0x00000000, 0x03e00008, 0x00000000, 0x8f820020, 0x10400005, 0x3c038000,
+ 0x8f421000, 0x00431024, 0x1040fffd, 0x00000000, 0x03e00008, 0x00000000,
+ 0x8f820024, 0x27bdffe8, 0x30424000, 0x14400005, 0xafbf0010, 0x0e00022f,
+ 0x00000000, 0x0a000656, 0x8fbf0010, 0x8f620008, 0x8f630000, 0x24020030,
+ 0x00031e02, 0x306300f0, 0x10620008, 0x28620031, 0x1440000d, 0x8fbf0010,
+ 0x24020040, 0x10620007, 0x00000000, 0x0a000656, 0x00000000, 0x0e0002e8,
+ 0x00000000, 0x0a000656, 0x8fbf0010, 0x0e0003db, 0x00000000, 0x8fbf0010,
+ 0x03e00008, 0x27bd0018, 0x8f840028, 0x1080000f, 0x3c026000, 0x8c430c3c,
+ 0x30630fff, 0xaf830008, 0x14600011, 0x3082000f, 0x10400005, 0x308200f0,
+ 0x10400003, 0x30820f00, 0x14400006, 0x00000000, 0x0000000d, 0x00000000,
+ 0x2400051a, 0x03e00008, 0x00000000, 0x0000000d, 0x00000000, 0x2400051f,
+ 0x03e00008, 0x00000000, 0xaf830028, 0x03e00008, 0x00000000, 0x10c00007,
+ 0x00000000, 0x8ca20000, 0x24c6ffff, 0x24a50004, 0xac820000, 0x14c0fffb,
+ 0x24840004, 0x03e00008, 0x00000000, 0x0a000684, 0x00a01021, 0xac860000,
+ 0x00000000, 0x00000000, 0x24840004, 0x00a01021, 0x1440fffa, 0x24a5ffff,
+ 0x03e00008, 0x00000000, 0x0000000d, 0x03e00008, 0x00000000, 0x00000000};
-static u32 bnx2_TPAT_b06FwData[(0x0/4) + 1] = { 0x00000000 };
-static u32 bnx2_TPAT_b06FwRodata[(0x0/4) + 1] = { 0x00000000 };
-static u32 bnx2_TPAT_b06FwBss[(0x80/4) + 1] = { 0x00000000 };
-static u32 bnx2_TPAT_b06FwSbss[(0x48/4) + 1] = { 0x00000000 };
+static u32 bnx2_TPAT_b06FwData[(0x0/4) + 1] = { 0x0 };
+static u32 bnx2_TPAT_b06FwRodata[(0x0/4) + 1] = { 0x0 };
+static u32 bnx2_TPAT_b06FwBss[(0x250/4) + 1] = { 0x0 };
+static u32 bnx2_TPAT_b06FwSbss[(0x34/4) + 1] = { 0x0 };
-static int bnx2_TXP_b06FwReleaseMajor = 0x0;
+static int bnx2_TXP_b06FwReleaseMajor = 0x1;
static int bnx2_TXP_b06FwReleaseMinor = 0x0;
static int bnx2_TXP_b06FwReleaseFix = 0x0;
-static u32 bnx2_TXP_b06FwStartAddr = 0x08002090;
+static u32 bnx2_TXP_b06FwStartAddr = 0x080034b0;
static u32 bnx2_TXP_b06FwTextAddr = 0x08000000;
-static int bnx2_TXP_b06FwTextLen = 0x3ffc;
-static u32 bnx2_TXP_b06FwDataAddr = 0x08004020;
+static int bnx2_TXP_b06FwTextLen = 0x5748;
+static u32 bnx2_TXP_b06FwDataAddr = 0x08005760;
static int bnx2_TXP_b06FwDataLen = 0x0;
static u32 bnx2_TXP_b06FwRodataAddr = 0x00000000;
static int bnx2_TXP_b06FwRodataLen = 0x0;
-static u32 bnx2_TXP_b06FwBssAddr = 0x08004060;
-static int bnx2_TXP_b06FwBssLen = 0x194;
-static u32 bnx2_TXP_b06FwSbssAddr = 0x08004020;
-static int bnx2_TXP_b06FwSbssLen = 0x34;
-static u32 bnx2_TXP_b06FwText[(0x3ffc/4) + 1] = {
- 0x0a000824, 0x00000000, 0x00000000, 0x0000000d, 0x74787020, 0x302e362e,
- 0x39000000, 0x00060900, 0x0000000a, 0x000003e8, 0x0000ea60, 0x00000000,
+static u32 bnx2_TXP_b06FwBssAddr = 0x080057a0;
+static int bnx2_TXP_b06FwBssLen = 0x1c4;
+static u32 bnx2_TXP_b06FwSbssAddr = 0x08005760;
+static int bnx2_TXP_b06FwSbssLen = 0x38;
+static u32 bnx2_TXP_b06FwText[(0x5748/4) + 1] = {
+ 0x0a000d2c, 0x00000000, 0x00000000, 0x0000000d, 0x74787020, 0x322e352e,
+ 0x38000000, 0x02050800, 0x0000000a, 0x000003e8, 0x0000ea60, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
@@ -2124,55 +2983,164 @@ static u32 bnx2_TXP_b06FwText[(0x3ffc/4) + 1] = {
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x10000003, 0x00000000, 0x0000000d,
- 0x0000000d, 0x3c020800, 0x24424020, 0x3c030800, 0x246341f4, 0xac400000,
- 0x0043202b, 0x1480fffd, 0x24420004, 0x3c1d0800, 0x37bd7ffc, 0x03a0f021,
- 0x3c100800, 0x26102090, 0x3c1c0800, 0x279c4020, 0x0e000a0e, 0x00000000,
- 0x0000000d, 0x8f840014, 0x27bdffe8, 0xafb00010, 0x8f460104, 0x8f830008,
- 0x8c8500ac, 0xaf430080, 0x948200a8, 0xa7420e10, 0x948300aa, 0xa7430e12,
- 0x8c8200ac, 0xaf420e18, 0x97430e10, 0xa7430e14, 0x97420e12, 0xa7420e16,
- 0x8f430e18, 0x00005021, 0x00c53023, 0x10c001a3, 0xaf430e1c, 0x240f0800,
- 0x3c0e1000, 0x2419fff8, 0x24100010, 0x3c188100, 0x93620008, 0x10400009,
- 0x00000000, 0x97620010, 0x00c2102b, 0x14400005, 0x00000000, 0x97620010,
- 0x3042ffff, 0x0a000862, 0xaf420e00, 0xaf460e00, 0x8f420000, 0x30420008,
- 0x1040fffd, 0x00000000, 0x97420e08, 0x8f450e04, 0x3044ffff, 0x30820001,
- 0x14400005, 0x00000000, 0x14a00005, 0x3083a040, 0x0a0009e6, 0x00000000,
- 0x0000000d, 0x3083a040, 0x24020040, 0x14620049, 0x3082a000, 0x8f87000c,
- 0x30880036, 0x30890008, 0xaf4f0178, 0x00e01821, 0x9742008a, 0x00431023,
- 0x2442ffff, 0x30421fff, 0x2c420008, 0x1440fffa, 0x00000000, 0x8f830018,
- 0x00a05021, 0x00c53023, 0x24e24000, 0x03422821, 0x306b00ff, 0x24630001,
- 0xaf830018, 0x93840012, 0x000b1400, 0x3c030100, 0x00431025, 0xaca20000,
- 0x8f820018, 0x30840007, 0x00042240, 0x34870001, 0x00e83825, 0x1120000f,
- 0xaca20004, 0x97430e0a, 0x8f84000c, 0x00ee3825, 0x2402000e, 0x00781825,
- 0xaf430160, 0x25430006, 0x24840008, 0x30841fff, 0xa742015a, 0xa7430158,
- 0xaf84000c, 0x0a0008a9, 0x00000000, 0x8f83000c, 0x25420002, 0xa7420158,
- 0x24630008, 0x30631fff, 0xaf83000c, 0x54c0000c, 0x8f420e14, 0x97420e10,
- 0x97430e12, 0x8f840014, 0x00021400, 0x00621825, 0xac8300a8, 0x8f850014,
- 0x8f420e18, 0x34e70040, 0xaca200ac, 0x8f420e14, 0x8f430e1c, 0xaf420144,
- 0xaf430148, 0xa34b0152, 0xaf470154, 0x0a0009f1, 0xaf4e0178, 0x10400128,
- 0x00000000, 0x97620010, 0x00a2102b, 0x10400003, 0x30820040, 0x10400122,
- 0x00000000, 0xafa60008, 0xa7840010, 0xaf850004, 0x93620008, 0x1440005e,
- 0x27ac0008, 0xaf60000c, 0x97820010, 0x30424000, 0x10400002, 0x2403000e,
- 0x24030016, 0xa363000a, 0x24034007, 0xaf630014, 0x93820012, 0x8f630014,
- 0x30420007, 0x00021240, 0x00621825, 0xaf630014, 0x97820010, 0x8f630014,
- 0x30420010, 0x00621825, 0xaf630014, 0x97820010, 0x30420008, 0x5040000e,
- 0x00002821, 0x8f620014, 0x004e1025, 0xaf620014, 0x97430e0a, 0x2402000e,
- 0x00781825, 0xaf630004, 0xa3620002, 0x9363000a, 0x3405fffc, 0x24630004,
- 0x0a0008f2, 0xa363000a, 0xaf600004, 0xa3600002, 0x97820010, 0x9363000a,
- 0x30421f00, 0x00021182, 0x24420028, 0x00621821, 0xa3630009, 0x97420e0c,
- 0xa7620010, 0x93630009, 0x24020008, 0x24630002, 0x30630007, 0x00431023,
- 0x30420007, 0xa362000b, 0x93640009, 0x97620010, 0x8f890004, 0x97830010,
- 0x00441021, 0x00a21021, 0x30630040, 0x10600006, 0x3045ffff, 0x15250005,
- 0x0125102b, 0x3c068000, 0x0a000925, 0x00005821, 0x0125102b, 0x144000c8,
- 0x00005021, 0x97420e14, 0xa7420e10, 0x97430e16, 0xa7430e12, 0x8f420e1c,
- 0xaf420e18, 0xaf450e00, 0x8f420000, 0x30420008, 0x1040fffd, 0x00000000,
- 0x97420e08, 0x00a04821, 0xa7820010, 0x8f430e04, 0x00003021, 0x240b0001,
- 0xaf830004, 0x97620010, 0x0a000936, 0x304dffff, 0x8f890004, 0x97820010,
- 0x30420040, 0x10400004, 0x01206821, 0x3c068000, 0x0a000936, 0x00005821,
- 0x97630010, 0x8f820004, 0x144300a7, 0x00005021, 0x00003021, 0x240b0001,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x10000003, 0x00000000, 0x0000000d, 0x0000000d, 0x3c020800,
+ 0x24425760, 0x3c030800, 0x24635964, 0xac400000, 0x0043202b, 0x1480fffd,
+ 0x24420004, 0x3c1d0800, 0x37bd7ffc, 0x03a0f021, 0x3c100800, 0x261034b0,
+ 0x3c1c0800, 0x279c5760, 0x0e000f5b, 0x00000000, 0x0000000d, 0x8f840014,
+ 0x27bdffe8, 0xafb10014, 0xafb00010, 0x8f460104, 0x8f830008, 0x8c8500ac,
+ 0xaf430080, 0x948200a8, 0xa7420e10, 0x948300aa, 0xa7430e12, 0x8c8200ac,
+ 0xaf420e18, 0x97430e10, 0xa7430e14, 0x97420e12, 0x00008021, 0xa7420e16,
+ 0x8f430e18, 0x00006021, 0x00c53023, 0xaf430e1c, 0x10c001a2, 0x2d820001,
+ 0x3c0e1000, 0x2419fff8, 0x24110010, 0x240f0f00, 0x3c188100, 0x93620008,
+ 0x10400009, 0x00000000, 0x97620010, 0x00c2102b, 0x14400005, 0x00000000,
+ 0x97620010, 0x3042ffff, 0x0a000d6d, 0xaf420e00, 0xaf460e00, 0x8f420000,
+ 0x30420008, 0x1040fffd, 0x00000000, 0x97420e08, 0x8f450e04, 0x3044ffff,
+ 0x30820001, 0x14400005, 0x00000000, 0x14a00005, 0x3083a040, 0x0a000f34,
+ 0x00000000, 0x0000000d, 0x3083a040, 0x24020040, 0x1462004f, 0x3082a000,
+ 0x308a0036, 0x8f88000c, 0x30890008, 0x24020800, 0xaf420178, 0x01001821,
+ 0x9742008a, 0x00431023, 0x2442ffff, 0x30421fff, 0x2c420008, 0x1440fffa,
+ 0x00a06021, 0x8f820018, 0x00cc3023, 0x24070001, 0x8f830008, 0x304b00ff,
+ 0x24420001, 0xaf820018, 0x25024000, 0x106f0005, 0x03422021, 0x93820012,
+ 0x30420007, 0x00021240, 0x34470001, 0x000b1400, 0x3c030100, 0x00431025,
+ 0xac820000, 0x8f830018, 0x00ea3825, 0x1120000f, 0xac830004, 0x97430e0a,
+ 0x8f84000c, 0x00ee3825, 0x2402000e, 0x00781825, 0xaf430160, 0x25830006,
+ 0x24840008, 0x30841fff, 0xa742015a, 0xa7430158, 0xaf84000c, 0x0a000db7,
+ 0x00000000, 0x8f83000c, 0x25820002, 0xa7420158, 0x24630008, 0x30631fff,
+ 0xaf83000c, 0x54c0000f, 0x8f420e14, 0x8f820008, 0x504f0002, 0x24100001,
+ 0x34e70040, 0x97420e10, 0x97430e12, 0x8f850014, 0x00021400, 0x00621825,
+ 0xaca300a8, 0x8f840014, 0x8f420e18, 0xac8200ac, 0x8f420e14, 0x8f430e1c,
+ 0xaf420144, 0xaf430148, 0xa34b0152, 0xaf470154, 0x0a000efb, 0xaf4e0178,
+ 0x10400165, 0x00000000, 0x93620008, 0x50400008, 0xafa60008, 0x97620010,
+ 0x00a2102b, 0x10400003, 0x30820040, 0x1040015c, 0x00000000, 0xafa60008,
+ 0xa7840010, 0xaf850004, 0x93620008, 0x1440005f, 0x27ac0008, 0xaf60000c,
+ 0x97820010, 0x30424000, 0x10400002, 0x2403000e, 0x24030016, 0xa363000a,
+ 0x24034007, 0xaf630014, 0x93820012, 0x8f630014, 0x30420007, 0x00021240,
+ 0x00621825, 0xaf630014, 0x97820010, 0x8f630014, 0x30420010, 0x00621825,
+ 0xaf630014, 0x97820010, 0x30420008, 0x5040000e, 0x00002821, 0x8f620014,
+ 0x004e1025, 0xaf620014, 0x97430e0a, 0x2402000e, 0x00781825, 0xaf630004,
+ 0xa3620002, 0x9363000a, 0x3405fffc, 0x24630004, 0x0a000e06, 0xa363000a,
+ 0xaf600004, 0xa3600002, 0x97820010, 0x9363000a, 0x30421f00, 0x00021182,
+ 0x24420028, 0x00621821, 0xa3630009, 0x97420e0c, 0xa7620010, 0x93630009,
+ 0x24020008, 0x24630002, 0x30630007, 0x00431023, 0x30420007, 0xa362000b,
+ 0x93640009, 0x97620010, 0x8f890004, 0x97830010, 0x00441021, 0x00a21021,
+ 0x30630040, 0x10600007, 0x3045ffff, 0x00a9102b, 0x14400005, 0x0125102b,
+ 0x3c068000, 0x0a000e3a, 0x00005821, 0x0125102b, 0x544000c7, 0x00006021,
+ 0x97420e14, 0xa7420e10, 0x97430e16, 0xa7430e12, 0x8f420e1c, 0xaf420e18,
+ 0xaf450e00, 0x8f420000, 0x30420008, 0x1040fffd, 0x00000000, 0x97420e08,
+ 0x00a04821, 0xa7820010, 0x8f430e04, 0x00003021, 0x240b0001, 0xaf830004,
+ 0x97620010, 0x0a000e4c, 0x304dffff, 0x8f890004, 0x97820010, 0x30420040,
+ 0x10400004, 0x01206821, 0x3c068000, 0x0a000e4c, 0x00005821, 0x97630010,
+ 0x8f820004, 0x10430003, 0x00003021, 0x0a000eee, 0x00006021, 0x240b0001,
0x8d820000, 0x00491023, 0x1440000d, 0xad820000, 0x8f620014, 0x34420040,
0xaf620014, 0x97430e10, 0x97420e12, 0x8f840014, 0x00031c00, 0x00431025,
- 0xac8200a8, 0x8f830014, 0x8f420e18, 0xac6200ac, 0x93620008, 0x1440003f,
+ 0xac8200a8, 0x8f830014, 0x8f420e18, 0xac6200ac, 0x93620008, 0x1440003e,
0x00000000, 0x25260002, 0x8f84000c, 0x9743008a, 0x3063ffff, 0xafa30000,
0x8fa20000, 0x00441023, 0x2442ffff, 0x30421fff, 0x2c420010, 0x1440fff7,
0x00000000, 0x8f82000c, 0x8f830018, 0x00021082, 0x00021080, 0x24424000,
@@ -2180,289 +3148,320 @@ static u32 bnx2_TXP_b06FwText[(0x3ffc/4) + 1] = {
0x3c033200, 0x00431025, 0xaca20000, 0x93630009, 0x9362000a, 0x00031c00,
0x00431025, 0xaca20004, 0x8f830018, 0xaca30008, 0x97820010, 0x30420008,
0x10400002, 0x00c04021, 0x25280006, 0x97430e14, 0x93640002, 0x8f450e1c,
- 0x8f660004, 0x8f670014, 0xaf4f0178, 0x3063ffff, 0xa7430144, 0x97420e16,
- 0xa7420146, 0xaf450148, 0xa34a0152, 0x8f82000c, 0x308400ff, 0xa744015a,
- 0xaf460160, 0xa7480158, 0xaf470154, 0xaf4e0178, 0x00501021, 0x30421fff,
- 0xaf82000c, 0x0a0009c5, 0x8d820000, 0x93620009, 0x9363000b, 0x8f85000c,
- 0x2463000a, 0x00435021, 0x25440007, 0x00992024, 0x9743008a, 0x3063ffff,
- 0xafa30000, 0x8fa20000, 0x00451023, 0x2442ffff, 0x30421fff, 0x0044102b,
- 0x1440fff7, 0x00000000, 0x8f82000c, 0x8f840018, 0x00021082, 0x00021080,
- 0x24424000, 0x03422821, 0x00804021, 0x24840001, 0xaf840018, 0x93630009,
- 0x310200ff, 0x00022400, 0x3c024100, 0x24630002, 0x00621825, 0x00832025,
- 0xaca40000, 0x8f62000c, 0x00461025, 0xaca20004, 0x97430e14, 0x93640002,
- 0x8f450e1c, 0x8f660004, 0x8f670014, 0xaf4f0178, 0x3063ffff, 0xa7430144,
- 0x97420e16, 0x308400ff, 0xa7420146, 0xaf450148, 0xa3480152, 0x8f83000c,
- 0x25420007, 0x00591024, 0xa744015a, 0xaf460160, 0xa7490158, 0xaf470154,
- 0xaf4e0178, 0x00621821, 0x30631fff, 0xaf83000c, 0x8d820000, 0x14400005,
- 0x00000000, 0x8f620014, 0x2403ffbf, 0x00431024, 0xaf620014, 0x8f62000c,
- 0x004d1021, 0xaf62000c, 0x93630008, 0x14600008, 0x00000000, 0x11600006,
- 0x00000000, 0x8f630014, 0x3c02efff, 0x3442fffe, 0x00621824, 0xaf630014,
- 0xa36b0008, 0x01205021, 0x15400016, 0x8fa60008, 0x97420e14, 0x97430e16,
- 0x8f850014, 0x00021400, 0x00621825, 0xaca300a8, 0x8f840014, 0x8f420e1c,
- 0x0a0009f3, 0xac8200ac, 0x97420e14, 0x97430e16, 0x8f840014, 0x00021400,
- 0x00621825, 0xac8300a8, 0x8f850014, 0x8f420e1c, 0x00005021, 0x0a0009f3,
- 0xaca200ac, 0x14c0fe64, 0x00000000, 0x55400018, 0x8fb00010, 0x3c038000,
- 0x8f420178, 0x00431024, 0x1440fffd, 0x00000000, 0x97430e14, 0x8f440e1c,
- 0x24020800, 0xaf420178, 0x3063ffff, 0xa7430144, 0x97420e16, 0x3c031000,
- 0xa7420146, 0x24020240, 0xaf440148, 0xa3400152, 0xa740015a, 0xaf400160,
- 0xa7400158, 0xaf420154, 0xaf430178, 0x8fb00010, 0x03e00008, 0x27bd0018,
- 0x27bdffd8, 0x3c1a8000, 0x3c0420ff, 0x3484fffd, 0x3c020008, 0x03421821,
- 0xafbf0020, 0xafb3001c, 0xafb20018, 0xafb10014, 0xafb00010, 0xaf830014,
- 0xaf440e00, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x3c0200ff, 0x3442fffd, 0x3c046004, 0xaf420e00, 0x8c835000, 0x24130d00,
- 0x3c120800, 0x3c114000, 0x2402ff7f, 0x00621824, 0x3463380c, 0x24020009,
- 0xac835000, 0xaf420008, 0xaf800018, 0xaf80000c, 0x0e000fa1, 0x00000000,
- 0x0e000a96, 0x00000000, 0x3c020800, 0x24504080, 0x8f420000, 0x30420001,
- 0x1040fffd, 0x00000000, 0x8f440100, 0xaf840008, 0xaf440020, 0x93430108,
- 0xa3830012, 0x93820012, 0x30420001, 0x10400008, 0x00000000, 0x93820012,
- 0x30420006, 0x00021100, 0x0e00083b, 0x0050d821, 0x0a000a52, 0x00000000,
- 0x14930005, 0x00000000, 0x0e00083b, 0x265b4100, 0x0a000a52, 0x00000000,
- 0x0e000ba3, 0x00000000, 0xaf510138, 0x0a000a36, 0x00000000, 0x27bdfff8,
- 0x3084ffff, 0x24820007, 0x3044fff8, 0x8f85000c, 0x9743008a, 0x3063ffff,
- 0xafa30000, 0x8fa20000, 0x00451023, 0x2442ffff, 0x30421fff, 0x0044102b,
- 0x1440fff7, 0x00000000, 0x8f82000c, 0x00021082, 0x00021080, 0x24424000,
- 0x03421021, 0x03e00008, 0x27bd0008, 0x3084ffff, 0x8f82000c, 0x24840007,
- 0x3084fff8, 0x00441021, 0x30421fff, 0xaf82000c, 0x03e00008, 0x00000000,
- 0x27bdffe8, 0x3c1a8000, 0x3c0420ff, 0x3484fffd, 0x3c020008, 0x03421821,
- 0xafbf0010, 0xaf830014, 0xaf440e00, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x3c0200ff, 0x3442fffd, 0x3c046004, 0xaf420e00,
- 0x8c825000, 0x2403ff7f, 0x00431024, 0x3442380c, 0x24030009, 0xac825000,
- 0xaf430008, 0xaf800018, 0xaf80000c, 0x0e000fa1, 0x00000000, 0x0e000a96,
- 0x00000000, 0x8fbf0010, 0x03e00008, 0x27bd0018, 0x27bdffe8, 0x3c02000a,
- 0x03421821, 0x3c040800, 0x24844120, 0x24050018, 0xafbf0010, 0xaf830024,
- 0x0e000fad, 0x00003021, 0x3c050800, 0x3c020800, 0x24423d60, 0xaca24180,
- 0x24a54180, 0x3c020800, 0x24423e18, 0x3c030800, 0x24633e2c, 0x3c040800,
- 0xaca20004, 0x3c020800, 0x24423d68, 0xaca30008, 0xac824190, 0x24844190,
- 0x3c020800, 0x24423da4, 0x3c070800, 0x24e73de4, 0x3c060800, 0x24c63e40,
- 0x3c050800, 0x24a52b28, 0x3c030800, 0xac820004, 0x3c020800, 0x24423e48,
- 0xac870008, 0xac86000c, 0xac850010, 0xac6241b0, 0x246341b0, 0x8fbf0010,
- 0x3c020800, 0x24423e60, 0xac620004, 0xac670008, 0xac66000c, 0xac650010,
- 0x03e00008, 0x27bd0018, 0x27bdffc8, 0x3c020800, 0x24424120, 0xafbf0030,
- 0xafb3002c, 0xafb20028, 0xafb10024, 0xafb00020, 0x90470021, 0x8c510008,
- 0x8c45001c, 0x8f900020, 0x3c060800, 0x3c038000, 0x8f420178, 0x00431024,
- 0x1440fffd, 0x8cc2414c, 0x24c3414c, 0x2473ffd4, 0xaf420144, 0x8e620030,
- 0x30b22000, 0xaf420148, 0x3c021000, 0xaf50014c, 0xa3470152, 0xa7510158,
- 0xaf450154, 0xaf420178, 0x12400004, 0x3c030800, 0x8c620030, 0x24420001,
- 0xac620030, 0x93420109, 0x9344010a, 0x00111c00, 0xafa30018, 0x00071a00,
- 0xafa50014, 0x8cc5414c, 0x00021600, 0x00042400, 0x00441025, 0x00431025,
- 0xafa20010, 0x8f440100, 0x8e660030, 0x0e000fe1, 0x02003821, 0x1640000e,
- 0x8fbf0030, 0x8f820000, 0x8e630030, 0x8c44017c, 0x02031823, 0x00711823,
- 0x00641823, 0x2c630002, 0x14600006, 0x8fb3002c, 0x0000000d, 0x00000000,
- 0x240000ca, 0x8fbf0030, 0x8fb3002c, 0x8fb20028, 0x8fb10024, 0x8fb00020,
- 0x03e00008, 0x27bd0038, 0x974309da, 0x00804021, 0xad030000, 0x8f4209dc,
- 0xad020004, 0x8f4309e0, 0xad030008, 0x934409d9, 0x24020001, 0x30840003,
- 0x1082001f, 0x30a900ff, 0x28820002, 0x10400005, 0x24020002, 0x10800009,
- 0x3c0a0800, 0x0a000b64, 0x93420934, 0x1082000b, 0x24020003, 0x10820026,
- 0x3c0a0800, 0x0a000b64, 0x93420934, 0x974209e4, 0x00021400, 0x34420800,
- 0xad02000c, 0x0a000b63, 0x25080010, 0x974209e4, 0x00021400, 0x34428100,
- 0xad02000c, 0x974309e8, 0x3c0a0800, 0x00031c00, 0x34630800, 0xad030010,
- 0x0a000b63, 0x25080014, 0x974409e4, 0x3c050800, 0x24a24120, 0x94430018,
- 0x94460010, 0x9447000c, 0x00a05021, 0x24020800, 0xad000010, 0xad020014,
- 0x00042400, 0x00661821, 0x00671823, 0x2463fff2, 0x00832025, 0xad04000c,
- 0x0a000b63, 0x25080018, 0x974209e4, 0x3c050800, 0x00021400, 0x34428100,
- 0xad02000c, 0x974409e8, 0x24a24120, 0x94430018, 0x94460010, 0x9447000c,
- 0x00a05021, 0x24020800, 0xad000014, 0xad020018, 0x00042400, 0x00661821,
- 0x00671823, 0x2463ffee, 0x00832025, 0xad040010, 0x2508001c, 0x93420934,
- 0x93450921, 0x3c074000, 0x25444120, 0x94830014, 0x94860010, 0x00021082,
- 0x00021600, 0x00052c00, 0x00a72825, 0x00451025, 0x00661821, 0x00431025,
- 0xad020000, 0x97830028, 0x974209ea, 0x00621821, 0x00031c00, 0xad030004,
- 0x97820028, 0x24420001, 0x30427fff, 0xa7820028, 0x93430920, 0x3c020006,
- 0x00031e00, 0x00621825, 0xad030008, 0x8f42092c, 0xad02000c, 0x8f430930,
- 0xad030010, 0x8f440938, 0x25080014, 0xad040000, 0x8f820020, 0x11200004,
- 0xad020004, 0x8f420940, 0x0a000b8d, 0x2442ffff, 0x8f420940, 0xad020008,
- 0x8f440948, 0x8f420940, 0x93430936, 0x00822823, 0x00652806, 0x3402ffff,
- 0x0045102b, 0x54400001, 0x3405ffff, 0x93420937, 0x25444120, 0x90830020,
- 0xad000010, 0x00021700, 0x34630010, 0x00031c00, 0x00431025, 0x00451025,
- 0xad02000c, 0x03e00008, 0x25020014, 0x27bdffb0, 0x3c020008, 0x03421821,
- 0xafbf004c, 0xafbe0048, 0xafb70044, 0xafb60040, 0xafb5003c, 0xafb40038,
- 0xafb30034, 0xafb20030, 0xafb1002c, 0xafb00028, 0xaf830000, 0x24020040,
- 0xaf420814, 0xaf400810, 0x8f420944, 0x8f430950, 0x8f440954, 0x8f45095c,
- 0xaf820030, 0xaf830020, 0xaf84001c, 0xaf85002c, 0x93430900, 0x24020020,
- 0x10620005, 0x24020030, 0x10620022, 0x3c030800, 0x0a000bf1, 0x8c62002c,
- 0x24020088, 0xaf420818, 0x3c020800, 0x24424180, 0xafa20020, 0x93430109,
- 0x3c020800, 0x10600009, 0x24574190, 0x3c026000, 0x24030100, 0xac43081c,
- 0x3c030001, 0xac43081c, 0x0000000d, 0x00000000, 0x2400031d, 0x9342010a,
- 0x30420080, 0x1440001c, 0x00000000, 0x3c026000, 0x24030100, 0xac43081c,
- 0x3c030001, 0xac43081c, 0x0000000d, 0x00000000, 0x24000324, 0x0a000bf4,
- 0x00000000, 0x93430109, 0x3063007f, 0x00031140, 0x000318c0, 0x00431021,
- 0x24430088, 0xaf430818, 0x0000000d, 0x3c020800, 0x244241d0, 0x3c030800,
- 0x247741e0, 0x0a000bf4, 0xafa20020, 0x24420001, 0x0a000f4c, 0xac62002c,
- 0x8f840000, 0x8f850020, 0x24020800, 0xaf420178, 0x8f4209a4, 0x8c83017c,
- 0x00a21023, 0x00431023, 0x2c420002, 0x14400004, 0x00000000, 0x0000000d,
- 0x00000000, 0x24000349, 0x8f420104, 0x8f430988, 0x00431023, 0x58400005,
- 0x8f4209a0, 0x0000000d, 0x00000000, 0x2400034d, 0x8f4209a0, 0x3c100800,
- 0xae02414c, 0x8f4309a4, 0x2604414c, 0x2491ffd4, 0xae230030, 0x8f420104,
- 0xae250024, 0x00431023, 0xac82ffd4, 0x8fa30020, 0x8c620000, 0x0040f809,
+ 0x8f660004, 0x8f670014, 0x3063ffff, 0xa7430144, 0x97420e16, 0xa7420146,
+ 0xaf450148, 0xa34a0152, 0x8f82000c, 0x308400ff, 0xa744015a, 0xaf460160,
+ 0xa7480158, 0xaf470154, 0xaf4e0178, 0x00511021, 0x30421fff, 0xaf82000c,
+ 0x0a000ed9, 0x8d820000, 0x93620009, 0x9363000b, 0x8f85000c, 0x2463000a,
+ 0x00435021, 0x25440007, 0x00992024, 0x9743008a, 0x3063ffff, 0xafa30000,
+ 0x8fa20000, 0x00451023, 0x2442ffff, 0x30421fff, 0x0044102b, 0x1440fff7,
+ 0x00000000, 0x8f82000c, 0x8f840018, 0x00021082, 0x00021080, 0x24424000,
+ 0x03422821, 0x00804021, 0x24840001, 0xaf840018, 0x93630009, 0x310200ff,
+ 0x00022400, 0x3c024100, 0x24630002, 0x00621825, 0x00832025, 0xaca40000,
+ 0x8f62000c, 0x00461025, 0xaca20004, 0x97430e14, 0x93640002, 0x8f450e1c,
+ 0x8f660004, 0x8f670014, 0x3063ffff, 0xa7430144, 0x97420e16, 0x308400ff,
+ 0xa7420146, 0xaf450148, 0xa3480152, 0x8f83000c, 0x25420007, 0x00591024,
+ 0xa744015a, 0xaf460160, 0xa7490158, 0xaf470154, 0xaf4e0178, 0x00621821,
+ 0x30631fff, 0xaf83000c, 0x8d820000, 0x14400005, 0x00000000, 0x8f620014,
+ 0x2403ffbf, 0x00431024, 0xaf620014, 0x8f62000c, 0x004d1021, 0xaf62000c,
+ 0x93630008, 0x14600008, 0x00000000, 0x11600006, 0x00000000, 0x8f630014,
+ 0x3c02efff, 0x3442fffe, 0x00621824, 0xaf630014, 0xa36b0008, 0x01206021,
+ 0x1580000c, 0x8fa60008, 0x97420e14, 0x97430e16, 0x8f850014, 0x00021400,
+ 0x00621825, 0xaca300a8, 0x8f840014, 0x8f420e1c, 0xac8200ac, 0x0a000efd,
+ 0x2d820001, 0x14c0fe65, 0x2d820001, 0x00501025, 0x10400058, 0x24020f00,
+ 0x8f830008, 0x14620023, 0x3c048000, 0x11800009, 0x3c038000, 0x97420e08,
+ 0x30420040, 0x14400005, 0x00000000, 0x0000000d, 0x00000000, 0x2400032c,
+ 0x3c038000, 0x8f420178, 0x00431024, 0x1440fffd, 0x00000000, 0x97420e10,
+ 0x3c030500, 0x00431025, 0xaf42014c, 0x97430e14, 0xa7430144, 0x97420e16,
+ 0xa7420146, 0x8f430e1c, 0x24022000, 0xaf430148, 0x3c031000, 0xa3400152,
+ 0xa740015a, 0xaf400160, 0xa7400158, 0xaf420154, 0xaf430178, 0x8f830008,
+ 0x3c048000, 0x8f420178, 0x00441024, 0x1440fffd, 0x24020f00, 0x10620016,
+ 0x00000000, 0x97420e14, 0xa7420144, 0x97430e16, 0xa7430146, 0x8f420e1c,
+ 0x3c031000, 0xaf420148, 0x0a000f51, 0x24020240, 0x97420e14, 0x97430e16,
+ 0x8f840014, 0x00021400, 0x00621825, 0xac8300a8, 0x8f850014, 0x8f420e1c,
+ 0x00006021, 0xaca200ac, 0x0a000efd, 0x2d820001, 0xaf40014c, 0x11800007,
+ 0x00000000, 0x97420e10, 0xa7420144, 0x97430e12, 0xa7430146, 0x0a000f4e,
+ 0x8f420e18, 0x97420e14, 0xa7420144, 0x97430e16, 0xa7430146, 0x8f420e1c,
+ 0xaf420148, 0x24020040, 0x3c031000, 0xa3400152, 0xa740015a, 0xaf400160,
+ 0xa7400158, 0xaf420154, 0xaf430178, 0x8fb10014, 0x8fb00010, 0x03e00008,
+ 0x27bd0018, 0x27bdffd0, 0x3c1a8000, 0x3c0420ff, 0x3484fffd, 0x3c020008,
+ 0x03421821, 0xafbf002c, 0xafb60028, 0xafb50024, 0xafb40020, 0xafb3001c,
+ 0xafb20018, 0xafb10014, 0xafb00010, 0xaf830014, 0xaf440e00, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x3c0200ff, 0x3442fffd,
+ 0x3c046004, 0xaf420e00, 0x8c835000, 0x24160800, 0x24150d00, 0x3c140800,
+ 0x24130f00, 0x3c120800, 0x3c114000, 0x2402ff7f, 0x00621824, 0x3463380c,
+ 0x24020009, 0xac835000, 0xaf420008, 0xaf800018, 0xaf80000c, 0x0e001559,
+ 0x00000000, 0x0e000ff0, 0x00000000, 0x3c020800, 0x245057c0, 0x8f420000,
+ 0x30420001, 0x1040fffd, 0x00000000, 0x8f440100, 0xaf840008, 0xaf440020,
+ 0xaf560178, 0x93430108, 0xa3830012, 0x93820012, 0x30420001, 0x10400008,
+ 0x00000000, 0x93820012, 0x30420006, 0x00021100, 0x0e000d43, 0x0050d821,
+ 0x0a000fac, 0x00000000, 0x14950005, 0x00000000, 0x0e000d43, 0x269b5840,
+ 0x0a000fac, 0x00000000, 0x14930005, 0x00000000, 0x0e000d43, 0x265b5860,
+ 0x0a000fac, 0x00000000, 0x0e0010ea, 0x00000000, 0xaf510138, 0x0a000f89,
+ 0x00000000, 0x27bdfff8, 0x3084ffff, 0x24820007, 0x3044fff8, 0x8f85000c,
+ 0x9743008a, 0x3063ffff, 0xafa30000, 0x8fa20000, 0x00451023, 0x2442ffff,
+ 0x30421fff, 0x0044102b, 0x1440fff7, 0x00000000, 0x8f82000c, 0x00021082,
+ 0x00021080, 0x24424000, 0x03421021, 0x03e00008, 0x27bd0008, 0x3084ffff,
+ 0x8f82000c, 0x24840007, 0x3084fff8, 0x00441021, 0x30421fff, 0xaf82000c,
+ 0x03e00008, 0x00000000, 0x27bdffe8, 0x3c1a8000, 0x3c0420ff, 0x3484fffd,
+ 0x3c020008, 0x03421821, 0xafbf0010, 0xaf830014, 0xaf440e00, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x3c0200ff, 0x3442fffd,
+ 0x3c046004, 0xaf420e00, 0x8c825000, 0x2403ff7f, 0x00431024, 0x3442380c,
+ 0x24030009, 0xac825000, 0xaf430008, 0xaf800018, 0xaf80000c, 0x0e001559,
+ 0x00000000, 0x0e000ff0, 0x00000000, 0x8fbf0010, 0x03e00008, 0x27bd0018,
+ 0x27bdffe8, 0x3c02000a, 0x03421821, 0x3c040800, 0x24845880, 0x24050019,
+ 0xafbf0010, 0xaf830024, 0x0e001565, 0x00003021, 0x3c050800, 0x3c020800,
+ 0x24425330, 0xaca258e8, 0x24a558e8, 0x3c020800, 0x244254f8, 0x3c030800,
+ 0x2463550c, 0x3c040800, 0xaca20004, 0x3c020800, 0x24425338, 0xaca30008,
+ 0xac825900, 0x24845900, 0x3c020800, 0x244253c4, 0x3c070800, 0x24e75404,
+ 0x3c060800, 0x24c65520, 0x3c050800, 0x24a55438, 0x3c030800, 0xac820004,
+ 0x3c020800, 0x24425528, 0xac870008, 0xac86000c, 0xac850010, 0xac625920,
+ 0x24635920, 0x8fbf0010, 0x3c020800, 0x24425540, 0xac620004, 0x3c020800,
+ 0xac670008, 0xac66000c, 0xac650010, 0xac400048, 0x03e00008, 0x27bd0018,
+ 0x974309da, 0x00804021, 0xad030000, 0x8f4209dc, 0xad020004, 0x8f4309e0,
+ 0xad030008, 0x934409d9, 0x24020001, 0x30840003, 0x1082001f, 0x30a900ff,
+ 0x28820002, 0x10400005, 0x24020002, 0x10800009, 0x3c0a0800, 0x0a001078,
+ 0x93420934, 0x1082000b, 0x24020003, 0x10820026, 0x3c0a0800, 0x0a001078,
+ 0x93420934, 0x974209e4, 0x00021400, 0x34420800, 0xad02000c, 0x0a001077,
+ 0x25080010, 0x974209e4, 0x00021400, 0x34428100, 0xad02000c, 0x974309e8,
+ 0x3c0a0800, 0x00031c00, 0x34630800, 0xad030010, 0x0a001077, 0x25080014,
+ 0x974409e4, 0x3c050800, 0x24a25880, 0x9443001c, 0x94460014, 0x94470010,
+ 0x00a05021, 0x24020800, 0xad000010, 0xad020014, 0x00042400, 0x00661821,
+ 0x00671823, 0x2463fff2, 0x00832025, 0xad04000c, 0x0a001077, 0x25080018,
+ 0x974209e4, 0x3c050800, 0x00021400, 0x34428100, 0xad02000c, 0x974409e8,
+ 0x24a25880, 0x9443001c, 0x94460014, 0x94470010, 0x00a05021, 0x24020800,
+ 0xad000014, 0xad020018, 0x00042400, 0x00661821, 0x00671823, 0x2463ffee,
+ 0x00832025, 0xad040010, 0x2508001c, 0x93420934, 0x93450921, 0x3c074000,
+ 0x25445880, 0x94830018, 0x94860014, 0x00021082, 0x00021600, 0x00052c00,
+ 0x00a72825, 0x00451025, 0x00661821, 0x00431025, 0xad020000, 0x9783002c,
+ 0x974209ea, 0x00621821, 0x00031c00, 0xad030004, 0x9782002c, 0x24420001,
+ 0x30427fff, 0xa782002c, 0x93430920, 0x3c020006, 0x00031e00, 0x00621825,
+ 0xad030008, 0x8f42092c, 0xad02000c, 0x8f430930, 0xad030010, 0x8f440938,
+ 0x25080014, 0xad040000, 0x8f820020, 0x11200004, 0xad020004, 0x8f420940,
+ 0x0a0010a1, 0x2442ffff, 0x8f420940, 0xad020008, 0x8f440948, 0x8f420940,
+ 0x93430936, 0x00823023, 0x00663006, 0x3402ffff, 0x0046102b, 0x54400001,
+ 0x3406ffff, 0x93420937, 0x25445880, 0x90830024, 0xad000010, 0x00021700,
+ 0x34630010, 0x00031c00, 0x00431025, 0x00461025, 0xad02000c, 0x8c830008,
+ 0x14600031, 0x25080014, 0x3c020800, 0x8c430048, 0x1060002d, 0x00000000,
+ 0x9342010b, 0xad020000, 0x8f830000, 0x8c6200b0, 0xad020004, 0x8f830000,
+ 0x8c6200b4, 0xad020008, 0x8f830000, 0x8c6200c0, 0xad02000c, 0x8f830000,
+ 0x8c6200c4, 0xad020010, 0x8f830000, 0x8c6200c8, 0xad020014, 0x8f830000,
+ 0x8c6200cc, 0xad020018, 0x8f830000, 0x8c6200e0, 0xad02001c, 0x8f830000,
+ 0x8c6200e8, 0xad020020, 0x8f830000, 0x8c6200f0, 0x3c04600e, 0xad020024,
+ 0x8c8200d0, 0xad020028, 0x8c8300d4, 0xad03002c, 0x8f820028, 0x3c046012,
+ 0xad020030, 0x8c8200a8, 0xad020034, 0x8c8300ac, 0x3c026000, 0xad030038,
+ 0x8c434448, 0xad03003c, 0x03e00008, 0x01001021, 0x27bdffa8, 0x3c020008,
+ 0x03423021, 0xafbf0054, 0xafbe0050, 0xafb7004c, 0xafb60048, 0xafb50044,
+ 0xafb40040, 0xafb3003c, 0xafb20038, 0xafb10034, 0xafb00030, 0xaf860000,
+ 0x24020040, 0xaf420814, 0xaf400810, 0x8f420944, 0x8f430950, 0x8f440954,
+ 0x8f45095c, 0xaf820034, 0xaf830020, 0xaf84001c, 0xaf850030, 0x90c20000,
+ 0x24030020, 0x304400ff, 0x10830005, 0x24020030, 0x10820022, 0x3c030800,
+ 0x0a001139, 0x8c62002c, 0x24020088, 0xaf420818, 0x3c020800, 0x244258e8,
+ 0xafa20020, 0x93430109, 0x3c020800, 0x10600009, 0x24575900, 0x3c026000,
+ 0x24030100, 0xac43081c, 0x3c030001, 0xac43081c, 0x0000000d, 0x00000000,
+ 0x24000376, 0x9342010a, 0x30420080, 0x14400021, 0x24020800, 0x3c026000,
+ 0x24030100, 0xac43081c, 0x3c030001, 0xac43081c, 0x0000000d, 0x00000000,
+ 0x2400037d, 0x0a001141, 0x24020800, 0x93430109, 0x3063007f, 0x00031140,
+ 0x000318c0, 0x00431021, 0x24430088, 0xaf430818, 0x0000000d, 0x3c020800,
+ 0x24425940, 0x3c030800, 0x24775950, 0x0a001140, 0xafa20020, 0x24420001,
+ 0xac62002c, 0x0000000d, 0x00000000, 0x24000395, 0x0a0014c1, 0x8fbf0054,
+ 0x24020800, 0xaf420178, 0x8f450104, 0x8f420988, 0x00a21023, 0x58400005,
+ 0x8f4309a0, 0x0000000d, 0x00000000, 0x240003b1, 0x8f4309a0, 0x3c100800,
+ 0xae0358b0, 0x8f4209a4, 0x8f830020, 0x260458b0, 0x2491ffd0, 0xae220034,
+ 0x00a21023, 0xae230028, 0xac82ffd0, 0x8fa30020, 0x8c620000, 0x0040f809,
0x0200b021, 0x00409021, 0x32440010, 0x32420002, 0x10400007, 0xafa40024,
- 0x8e22001c, 0x32500040, 0x2403ffbf, 0x00431024, 0x0a000f13, 0xae22001c,
- 0x32420020, 0x10400002, 0x3c020800, 0x245741b0, 0x32420001, 0x14400007,
- 0x00000000, 0x8f820008, 0xaf420080, 0x8ec3414c, 0xaf430e10, 0x8e220030,
+ 0x8e220020, 0x32530040, 0x2403ffbf, 0x00431024, 0x0a001493, 0xae220020,
+ 0x32420020, 0x10400002, 0x3c020800, 0x24575920, 0x32420001, 0x14400007,
+ 0x00000000, 0x8f820008, 0xaf420080, 0x8ec358b0, 0xaf430e10, 0x8e220034,
0xaf420e18, 0x9343010b, 0x93420905, 0x30420008, 0x1040003c, 0x307400ff,
0x8f820000, 0x8c430074, 0x0460000a, 0x00000000, 0x3c026000, 0x24030100,
- 0xac43081c, 0x3c030001, 0xac43081c, 0x0000000d, 0x00000000, 0x24000384,
- 0x8f820000, 0x9044007b, 0x9343010a, 0x14830027, 0x32500040, 0x24072000,
- 0x3c090800, 0x3c038000, 0x8f420178, 0x00431024, 0x1440fffd, 0x8ec2414c,
- 0x26c4414c, 0x2484ffd4, 0xaf420144, 0x8c820030, 0x3c030100, 0xaf420148,
- 0x24020047, 0xaf43014c, 0x00001821, 0xa3420152, 0x3c021000, 0xa7430158,
- 0xaf470154, 0xaf420178, 0x8ec5414c, 0x8d230030, 0x8c860030, 0x24630001,
- 0xad230030, 0x93420109, 0x9343010a, 0xafa70014, 0xafa00018, 0x00021600,
- 0x00031c00, 0x00431025, 0x34424700, 0xafa20010, 0x8f440100, 0x0e000fe1,
- 0x3c070100, 0x3c030800, 0x24624120, 0x0a000d01, 0x8c43001c, 0x32820002,
- 0x10400047, 0x3c039000, 0x34630001, 0x8f820008, 0x32500040, 0x3c048000,
- 0x00431025, 0xaf420020, 0x8f420020, 0x00441024, 0x1440fffd, 0x00000000,
- 0x8f830000, 0x90620005, 0x3c058000, 0x34420008, 0xa0620005, 0x8f860000,
- 0x34a50001, 0x8f840008, 0x8cc20074, 0x3c038000, 0x00852025, 0x00431025,
- 0xacc20074, 0xaf440020, 0x90c3007b, 0x9342010a, 0x14620028, 0x3c040800,
- 0x24072000, 0x3c090800, 0x3c038000, 0x8f420178, 0x00431024, 0x1440fffd,
- 0x8ec2414c, 0x26c4414c, 0x2484ffd4, 0xaf420144, 0x8c820030, 0x3c030100,
- 0xaf420148, 0x24020046, 0xaf43014c, 0x00001821, 0xa3420152, 0x3c021000,
- 0xa7430158, 0xaf470154, 0xaf420178, 0x8ec5414c, 0x8d230030, 0x8c860030,
- 0x24630001, 0xad230030, 0x93420109, 0x9343010a, 0xafa70014, 0xafa00018,
- 0x00021600, 0x00031c00, 0x00431025, 0x34424600, 0xafa20010, 0x8f440100,
- 0x0e000fe1, 0x3c070100, 0x3c040800, 0x24824120, 0x0a000d01, 0x8c43001c,
- 0x93420108, 0x30420010, 0x50400050, 0x9343093f, 0x8f860000, 0x90c3007f,
- 0x90c2007e, 0x90c40080, 0x306800ff, 0x00021600, 0x00081c00, 0x00431025,
- 0x00042200, 0x90c3007a, 0x90c5000a, 0x00441025, 0x11050028, 0x00623825,
- 0xa0c8000a, 0x24086000, 0x3c090800, 0x3c038000, 0x8f420178, 0x00431024,
- 0x1440fffd, 0x8ec2414c, 0x26c4414c, 0x2484ffd4, 0xaf420144, 0x8c820030,
- 0x00001821, 0xaf420148, 0x24020052, 0xaf47014c, 0xa3420152, 0x3c021000,
- 0xa7430158, 0xaf480154, 0xaf420178, 0x8ec5414c, 0x8d230030, 0x8c860030,
- 0x24630001, 0xad230030, 0x93420109, 0x9343010a, 0xafa80014, 0xafa00018,
- 0x00021600, 0x00031c00, 0x00431025, 0x34425200, 0xafa20010, 0x0e000fe1,
- 0x8f440100, 0x0a000cfb, 0x00000000, 0x3c026000, 0x24030100, 0xac43081c,
- 0x3c030001, 0xac43081c, 0x0000000d, 0x00000000, 0x240003cd, 0x16800009,
- 0x3c040800, 0x3c030800, 0x24624120, 0x8c43001c, 0x32500040, 0x2404ffbf,
- 0x00641824, 0x0a000f13, 0xac43001c, 0x8c824120, 0x10400005, 0x3c030800,
- 0x8c620034, 0xac804120, 0x24420001, 0xac620034, 0x9343093f, 0x24020012,
- 0x1462000f, 0x329e0038, 0x17c0000c, 0x3c030800, 0x8f830000, 0x8c62004c,
- 0xac62005c, 0x3c020800, 0x24444120, 0x8c82001c, 0x32500040, 0x2403ffbf,
- 0x00431024, 0x0a000f13, 0xac82001c, 0xac604120, 0x97420908, 0x000211c0,
+ 0xac43081c, 0x3c030001, 0xac43081c, 0x0000000d, 0x00000000, 0x240003ed,
+ 0x8f820000, 0x9044007b, 0x9343010a, 0x14830027, 0x32530040, 0x00003821,
+ 0x24052000, 0x3c090800, 0x3c038000, 0x8f420178, 0x00431024, 0x1440fffd,
+ 0x8ec258b0, 0x26c458b0, 0x2484ffd0, 0xaf420144, 0x8c820034, 0x3c030100,
+ 0xaf420148, 0x24020047, 0xaf43014c, 0xa3420152, 0x8d230030, 0x3c021000,
+ 0xa7470158, 0xaf450154, 0xaf420178, 0x8c860034, 0x24630001, 0xad230030,
+ 0x9342010a, 0x3c030047, 0xafa50014, 0x00021600, 0x00431025, 0x00471025,
+ 0xafa20010, 0x9343010b, 0xafa30018, 0x8f440100, 0x8f450104, 0x0e00159b,
+ 0x3c070100, 0x3c050800, 0x24a25880, 0x0a001250, 0x8c430020, 0x32820002,
+ 0x10400050, 0x00000000, 0x0e0015b9, 0x32530040, 0x3c039000, 0x34630001,
+ 0x8f820008, 0x3c048000, 0x00431025, 0xaf420020, 0x8f420020, 0x00441024,
+ 0x1440fffd, 0x00000000, 0x8f830000, 0x90620005, 0x34420008, 0xa0620005,
+ 0x8f840000, 0x8c820074, 0x3c038000, 0x00431025, 0xac820074, 0x90830000,
+ 0x24020020, 0x10620004, 0x00000000, 0x0000000d, 0x00000000, 0x2400040b,
+ 0x8f830008, 0x3c028000, 0x34420001, 0x00621825, 0xaf430020, 0x9084007b,
+ 0x9342010a, 0x14820028, 0x3c030800, 0x00003821, 0x24052000, 0x3c090800,
+ 0x3c038000, 0x8f420178, 0x00431024, 0x1440fffd, 0x8ec258b0, 0x26c458b0,
+ 0x2484ffd0, 0xaf420144, 0x8c820034, 0x3c030100, 0xaf420148, 0x24020046,
+ 0xaf43014c, 0xa3420152, 0x8d230030, 0x3c021000, 0xa7470158, 0xaf450154,
+ 0xaf420178, 0x8c860034, 0x24630001, 0xad230030, 0x9342010a, 0x3c030046,
+ 0xafa50014, 0x00021600, 0x00431025, 0x00471025, 0xafa20010, 0x9343010b,
+ 0xafa30018, 0x8f440100, 0x8f450104, 0x0e00159b, 0x3c070100, 0x3c030800,
+ 0x24625880, 0x0a001250, 0x8c430020, 0x93420108, 0x30420010, 0x50400056,
+ 0x9343093f, 0x8f860000, 0x90c2007f, 0x8cc30178, 0x304800ff, 0x15030004,
+ 0x00000000, 0x0000000d, 0x00000000, 0x24000425, 0x90c2007e, 0x90c40080,
+ 0x00081c00, 0x00021600, 0x00431025, 0x00042200, 0x90c3007a, 0x90c5000a,
+ 0x00441025, 0x11050028, 0x00623825, 0xa0c8000a, 0x00004021, 0x24056000,
+ 0x3c090800, 0x3c038000, 0x8f420178, 0x00431024, 0x1440fffd, 0x8ec258b0,
+ 0x26c458b0, 0x2484ffd0, 0xaf420144, 0x8c820034, 0xaf420148, 0x24020052,
+ 0xaf47014c, 0xa3420152, 0x8d230030, 0x3c021000, 0xa7480158, 0xaf450154,
+ 0xaf420178, 0x8c860034, 0x24630001, 0xad230030, 0x9342010a, 0x3c030052,
+ 0xafa50014, 0x00021600, 0x00431025, 0x00481025, 0xafa20010, 0x9343010b,
+ 0xafa30018, 0x8f440100, 0x0e00159b, 0x8f450104, 0x0a00124a, 0x00000000,
+ 0x3c026000, 0x24030100, 0xac43081c, 0x3c030001, 0xac43081c, 0x0000000d,
+ 0x00000000, 0x2400043e, 0x16800009, 0x3c050800, 0x3c040800, 0x24825880,
+ 0x8c430020, 0x32530040, 0x2404ffbf, 0x00641824, 0x0a001493, 0xac430020,
+ 0x8ca25880, 0x10400005, 0x3c030800, 0x8c620034, 0xaca05880, 0x24420001,
+ 0xac620034, 0x9343093f, 0x24020012, 0x5462000e, 0x97420908, 0x32820038,
+ 0x14400009, 0x3c030800, 0x8f830000, 0x8c62004c, 0xac62005c, 0x3c020800,
+ 0x24445880, 0x8c820020, 0x0a001285, 0x32530040, 0xac605880, 0x97420908,
+ 0x5440001c, 0x97420908, 0x3c039000, 0x34630001, 0x8f820008, 0x32530040,
+ 0x3c048000, 0x00431025, 0xaf420020, 0x8f420020, 0x00441024, 0x1440fffd,
+ 0x3c028000, 0x8f840000, 0x8f850008, 0x8c830050, 0x34420001, 0x00a22825,
+ 0xaf830020, 0xac830070, 0xac83005c, 0xaf450020, 0x3c050800, 0x24a45880,
+ 0x8c820020, 0x2403ffbf, 0x00431024, 0x0a001493, 0xac820020, 0x000211c0,
0xaf420024, 0x97420908, 0x3c030080, 0x34630003, 0x000211c0, 0xaf42080c,
- 0xaf43081c, 0x974209ec, 0x8f4309a4, 0xa7820028, 0x3c020800, 0x24444120,
- 0xac830028, 0x93420937, 0x93430934, 0x00021080, 0x00621821, 0xa4830014,
- 0x934209d8, 0x00621821, 0xa4830016, 0x934209d8, 0x93430934, 0x00809821,
- 0x00431021, 0x24420010, 0xa4820012, 0x0000a821, 0x24020006, 0x13c00003,
- 0xae62001c, 0x0a000d82, 0x24120008, 0x8f420958, 0x8f830020, 0x8f84002c,
- 0x00431023, 0x00832023, 0x04800003, 0xae620004, 0x04410003, 0x0082102b,
- 0x0a000d4e, 0xae600004, 0x54400001, 0xae640004, 0x8ee20000, 0x0040f809,
- 0x00000000, 0x00409021, 0x32420001, 0x5440001e, 0x8ee20004, 0x8e630008,
- 0x1060002b, 0x3c02c000, 0x00621025, 0xaf420e00, 0x8f420000, 0x30420008,
- 0x1040fffd, 0x00000000, 0x97420e08, 0xa7820010, 0x8f430e04, 0x8e620008,
- 0xaf830004, 0x8f840004, 0x0044102b, 0x1040000b, 0x24150001, 0x24020100,
- 0x3c016000, 0xac22081c, 0x3c020001, 0x3c016000, 0xac22081c, 0x0000000d,
- 0x00000000, 0x24000449, 0x24150001, 0x8ee20004, 0x0040f809, 0x00000000,
- 0x02429025, 0x32420002, 0x5040001d, 0x8f470940, 0x12a00006, 0x8ec2414c,
- 0x8f830000, 0xac6200a8, 0x8f840000, 0x8e620030, 0xac8200ac, 0x32420004,
- 0x50400013, 0x8f470940, 0x3c020800, 0x3283007d, 0x106000fe, 0x245741b0,
- 0x32820001, 0x50400006, 0x36520002, 0x8f830030, 0x8f420940, 0x106200f7,
- 0x00000000, 0x36520002, 0x24020008, 0xa660000c, 0xa662000e, 0xae600008,
- 0xa2600020, 0x8f470940, 0x3c030800, 0x24684120, 0x8d020028, 0x8d050008,
- 0x9504000c, 0x9506000a, 0x95030022, 0x00451021, 0x00862021, 0x00641821,
- 0xaf870030, 0xad020028, 0x32820030, 0x10400006, 0xa5030010, 0x91020020,
- 0x32910040, 0x34420004, 0x0a000dd4, 0xa1020020, 0x93420923, 0x30420040,
+ 0xaf43081c, 0x974209ec, 0x8f4309a4, 0xa782002c, 0x3c020800, 0x24445880,
+ 0xac83002c, 0x93420937, 0x93430934, 0x00021080, 0x00621821, 0xa4830018,
+ 0x934209d8, 0x32850038, 0xafa50028, 0x00621821, 0xa483001a, 0x934209d8,
+ 0x93430934, 0x3c1e0800, 0x00809821, 0x00431021, 0x24420010, 0xa4820016,
+ 0x24020006, 0xae620020, 0x8fa20028, 0x10400003, 0x0000a821, 0x0a0012f0,
+ 0x24120008, 0x8f420958, 0x8f830020, 0x8f840030, 0x00431023, 0x00832023,
+ 0x04800003, 0xae620004, 0x04410003, 0x0082102b, 0x0a0012bc, 0xae600004,
+ 0x54400001, 0xae640004, 0x8ee20000, 0x0040f809, 0x00000000, 0x00409021,
+ 0x32420001, 0x5440001e, 0x8ee20004, 0x8e630008, 0x1060002b, 0x3c02c000,
+ 0x00621025, 0xaf420e00, 0x8f420000, 0x30420008, 0x1040fffd, 0x00000000,
+ 0x97420e08, 0xa7820010, 0x8f430e04, 0x8e620008, 0xaf830004, 0x8f840004,
+ 0x0044102b, 0x1040000b, 0x24150001, 0x24020100, 0x3c016000, 0xac22081c,
+ 0x3c020001, 0x3c016000, 0xac22081c, 0x0000000d, 0x00000000, 0x240004cd,
+ 0x24150001, 0x8ee20004, 0x0040f809, 0x00000000, 0x02429025, 0x32420002,
+ 0x5040001d, 0x8f470940, 0x12a00006, 0x8ec258b0, 0x8f830000, 0xac6200a8,
+ 0x8f840000, 0x8e620034, 0xac8200ac, 0x32420004, 0x50400013, 0x8f470940,
+ 0x3c020800, 0x3283007d, 0x10600110, 0x24575920, 0x32820001, 0x50400006,
+ 0x36520002, 0x8f830034, 0x8f420940, 0x10620109, 0x00000000, 0x36520002,
+ 0x24020008, 0xa6600010, 0xa6620012, 0xae600008, 0xa2600024, 0x8f470940,
+ 0x3c030800, 0x24685880, 0x8d02002c, 0x8d050008, 0x95040010, 0x9506000a,
+ 0x95030026, 0x00451021, 0x00862021, 0x00641821, 0xaf870034, 0xad02002c,
+ 0x32820030, 0x10400008, 0xa5030014, 0x91020024, 0x32910040, 0x34420004,
+ 0xa1020024, 0xaf400048, 0x0a001345, 0x3c040800, 0x93420923, 0x30420002,
0x10400029, 0x32910040, 0x8f830000, 0x8f840020, 0x8c620084, 0x00441023,
- 0x0442000a, 0x3c039000, 0x95020010, 0x8c630084, 0x00821021, 0x00621823,
- 0x1c600004, 0x3c039000, 0x91020020, 0x34420001, 0xa1020020, 0x34630001,
+ 0x0442000a, 0x3c039000, 0x95020014, 0x8c630084, 0x00821021, 0x00621823,
+ 0x1c600004, 0x3c039000, 0x91020024, 0x34420001, 0xa1020024, 0x34630001,
0x8f820008, 0x32910040, 0x3c048000, 0x00431025, 0xaf420020, 0x8f420020,
0x00441024, 0x1440fffd, 0x00000000, 0x8f840000, 0x9083003f, 0x2402000a,
0x10620005, 0x2402000c, 0x9083003f, 0x24020008, 0x14620002, 0x24020014,
0xa082003f, 0x8f830008, 0x3c028000, 0x34420001, 0x00621825, 0xaf430020,
- 0x3c040800, 0x24904120, 0x9602000c, 0x96030016, 0x9604000e, 0x00431021,
- 0x00442021, 0x24840002, 0x3084ffff, 0x0e000a55, 0xa6020018, 0x8f850018,
- 0x00a01821, 0xa2030021, 0x8ee60008, 0x00402021, 0x24a50001, 0xaf850018,
- 0x00c0f809, 0x00000000, 0x00402021, 0x0e000b12, 0x02202821, 0x8ee3000c,
- 0x0060f809, 0x00402021, 0x96040018, 0x9602000e, 0x00822021, 0x24840002,
- 0x0e000a6b, 0x3084ffff, 0x3c030800, 0x8c624120, 0x8e030008, 0x3c040800,
- 0x00431023, 0x14400012, 0xac824120, 0x54600006, 0x8e02001c, 0x3243004a,
- 0x24020002, 0x14620005, 0x00000000, 0x8e02001c, 0x34420040, 0x0a000e0b,
- 0xae02001c, 0x52a00006, 0x36520002, 0x8e02002c, 0xaf420e10, 0x8e030030,
- 0xaf430e18, 0x36520002, 0x52a00008, 0x96670010, 0x8f830000, 0x8f420e10,
- 0xac6200a8, 0x8f840000, 0x8f420e18, 0xac8200ac, 0x96670010, 0x92680020,
- 0x24020040, 0xaf420814, 0x8f830020, 0x8f82001c, 0x00671821, 0x00621023,
- 0xaf830020, 0x58400005, 0x8f42095c, 0x8f820000, 0xaf83001c, 0xac430054,
- 0x8f42095c, 0x31030008, 0xaf82002c, 0x1060001a, 0x00000000, 0x8f840000,
- 0x90820120, 0x90830121, 0x304600ff, 0x00c31823, 0x30630007, 0x24020007,
- 0x1062000e, 0x00000000, 0x90820122, 0x304200fe, 0xa0820122, 0x8f850000,
- 0x00061880, 0x8f840020, 0x24a20100, 0x00431021, 0x24c30001, 0x30630007,
- 0xac440000, 0x0a000e40, 0xa0a30120, 0x90820122, 0x34420001, 0xa0820122,
- 0x14e00003, 0x31020001, 0x10400031, 0x32510002, 0x8f820000, 0x8c43000c,
- 0x30630001, 0x1060002c, 0x32510002, 0x3c029000, 0x8f830008, 0x34420001,
- 0x3c048000, 0x00621825, 0xaf430020, 0x8f420020, 0x00441024, 0x1440fffd,
- 0x00000000, 0x8f870000, 0x8ce2000c, 0x30420001, 0x10400018, 0x00000000,
- 0x94e2006a, 0x00022880, 0x50a00001, 0x24050001, 0x94e30068, 0x90e40081,
- 0x3c020800, 0x8c460024, 0x00652821, 0x00852804, 0x00c5102b, 0x54400001,
- 0x00a03021, 0x3c020800, 0x8c440028, 0x00c4182b, 0x54600001, 0x00c02021,
- 0x8f430074, 0x2402fffe, 0x00822824, 0x00a31821, 0xace3000c, 0x8f830008,
- 0x3c028000, 0x34420001, 0x00621825, 0xaf430020, 0x8f830020, 0x3c020800,
- 0x24504120, 0xae030024, 0x8ee20010, 0x0040f809, 0x00000000, 0x12a00005,
- 0x00000000, 0x8f420e10, 0xae02002c, 0x8f430e18, 0xae030030, 0x1220feba,
- 0x0000a821, 0x8f870024, 0x97860028, 0x8f830000, 0x8f820030, 0x8f840020,
- 0x8f85001c, 0x32500040, 0xa4e6002c, 0xac620044, 0x32420008, 0xac640050,
- 0xac650054, 0x1040007a, 0x32820020, 0x10400027, 0x32910010, 0x24072000,
- 0x3c090800, 0x3c038000, 0x8f420178, 0x00431024, 0x1440fffd, 0x8ec2414c,
- 0x26c4414c, 0x2484ffd4, 0xaf420144, 0x8c820030, 0x3c030400, 0xaf420148,
- 0x24020041, 0xaf43014c, 0x00001821, 0xa3420152, 0x3c021000, 0xa7430158,
- 0xaf470154, 0xaf420178, 0x8ec5414c, 0x8d230030, 0x8c860030, 0x24630001,
- 0xad230030, 0x93420109, 0x9343010a, 0xafa70014, 0xafa00018, 0x00021600,
- 0x00031c00, 0x00431025, 0x34424100, 0xafa20010, 0x8f440100, 0x0e000fe1,
- 0x3c070400, 0x12200028, 0x24072000, 0x3c090800, 0x3c038000, 0x8f420178,
- 0x00431024, 0x1440fffd, 0x8ec2414c, 0x26c4414c, 0x2484ffd4, 0xaf420144,
- 0x8c820030, 0x3c030300, 0xaf420148, 0x2402004e, 0xaf43014c, 0x00001821,
- 0xa3420152, 0x3c021000, 0xa7430158, 0xaf470154, 0xaf420178, 0x8ec5414c,
- 0x8d230030, 0x8c860030, 0x24630001, 0xad230030, 0x93420109, 0x9343010a,
- 0xafa70014, 0xafa00018, 0x00021600, 0x00031c00, 0x00431025, 0x34424e00,
- 0xafa20010, 0x8f440100, 0x0e000fe1, 0x3c070300, 0x0a000f0b, 0x8fa30024,
- 0x32820008, 0x10400026, 0x3c090800, 0x24072000, 0x3c038000, 0x8f420178,
- 0x00431024, 0x1440fffd, 0x8ec2414c, 0x26c4414c, 0x2484ffd4, 0xaf420144,
- 0x8c820030, 0x3c030200, 0xaf420148, 0x2402004b, 0xaf43014c, 0x00001821,
- 0xa3420152, 0x3c021000, 0xa7430158, 0xaf470154, 0xaf420178, 0x8ec5414c,
- 0x8d230030, 0x8c860030, 0x24630001, 0xad230030, 0x93420109, 0x9343010a,
- 0xafa70014, 0xafa00018, 0x00021600, 0x00031c00, 0x00431025, 0x34424b00,
- 0xafa20010, 0x8f440100, 0x0e000fe1, 0x3c070200, 0x8fa30024, 0x14600004,
- 0x8fa40020, 0x32420010, 0x10400004, 0x00000000, 0x8c820004, 0x0040f809,
- 0x00000000, 0x12000006, 0x8fa30020, 0x8c620008, 0x0040f809, 0x00000000,
- 0x0a000f4d, 0x8fbf004c, 0x3c030800, 0x8c62413c, 0x30420040, 0x1440002f,
- 0x8fbf004c, 0x24040040, 0x8f910020, 0x3c038000, 0x8f420178, 0x00431024,
- 0x1440fffd, 0x8ec2414c, 0x26d0414c, 0x2610ffd4, 0xaf420144, 0x8e020030,
- 0x00001821, 0xaf420148, 0x24020049, 0xaf51014c, 0xa3420152, 0x3c021000,
- 0xa7430158, 0xaf440154, 0xaf420178, 0x8ec5414c, 0x8e060030, 0x93420109,
- 0x9343010a, 0xafa40014, 0xafa00018, 0x00021600, 0x00031c00, 0x00431025,
- 0x34424900, 0xafa20010, 0x8f440100, 0x0e000fe1, 0x02203821, 0x8f830000,
- 0x8e020030, 0x8c64017c, 0x02221023, 0x00441023, 0x2c420002, 0x14400005,
- 0x8fbf004c, 0x0000000d, 0x00000000, 0x240000ca, 0x8fbf004c, 0x8fbe0048,
- 0x8fb70044, 0x8fb60040, 0x8fb5003c, 0x8fb40038, 0x8fb30034, 0x8fb20030,
- 0x8fb1002c, 0x8fb00028, 0x03e00008, 0x27bd0050, 0x03e00008, 0x00001021,
- 0x3c030800, 0x24654120, 0x8ca40004, 0x8c634120, 0x0064102b, 0x54400001,
- 0x00602021, 0x9743093c, 0x0083102b, 0x54400001, 0x00801821, 0x00001021,
- 0xaca30008, 0x03e00008, 0xa4a00022, 0x8f850004, 0x97840010, 0x3c030800,
- 0x24634120, 0x24020008, 0xa462000e, 0x8f820004, 0xa460000c, 0x000420c2,
+ 0x3c040800, 0x24865880, 0x94c20010, 0x94c3001a, 0x8cc40008, 0x00432821,
+ 0x14800006, 0xa4c5001c, 0x3c020800, 0x8c430048, 0x10600002, 0x24a20040,
+ 0xa4c2001c, 0x27d05880, 0x9604001c, 0x96020012, 0x00822021, 0x24840002,
+ 0x0e000faf, 0x3084ffff, 0x8f850018, 0x00a01821, 0xa2030025, 0x8ee60008,
+ 0x00402021, 0x24a50001, 0xaf850018, 0x00c0f809, 0x00000000, 0x00402021,
+ 0x0e001026, 0x02202821, 0x8ee3000c, 0x0060f809, 0x00402021, 0x9604001c,
+ 0x96020012, 0x00822021, 0x24840002, 0x0e000fc5, 0x3084ffff, 0x8fc25880,
+ 0x8e030008, 0x00431023, 0x14400012, 0xafc25880, 0x54600006, 0x8e020020,
+ 0x3243004a, 0x24020002, 0x14620005, 0x00000000, 0x8e020020, 0x34420040,
+ 0x0a001382, 0xae020020, 0x52a00006, 0x36520002, 0x8e020030, 0xaf420e10,
+ 0x8e030034, 0xaf430e18, 0x36520002, 0x52a00008, 0x96670014, 0x8f830000,
+ 0x8f420e10, 0xac6200a8, 0x8f840000, 0x8f420e18, 0xac8200ac, 0x96670014,
+ 0x92680024, 0x24020040, 0xaf420814, 0x8f830020, 0x8f82001c, 0x00671821,
+ 0x00621023, 0xaf830020, 0x18400008, 0x00000000, 0x8f820000, 0xaf83001c,
+ 0xac430054, 0x54e00005, 0xaf400040, 0x0a0013a0, 0x8f42095c, 0x54e00001,
+ 0xaf400044, 0x8f42095c, 0x31030008, 0xaf820030, 0x1060001a, 0x00000000,
+ 0x8f840000, 0x90820120, 0x90830121, 0x304600ff, 0x00c31823, 0x30630007,
+ 0x24020007, 0x1062000e, 0x00000000, 0x90820122, 0x304200fe, 0xa0820122,
+ 0x8f850000, 0x00061880, 0x8f840020, 0x24a20100, 0x00431021, 0x24c30001,
+ 0x30630007, 0xac440000, 0x0a0013bd, 0xa0a30120, 0x90820122, 0x34420001,
+ 0xa0820122, 0x14e00003, 0x31020001, 0x10400031, 0x32510002, 0x8f820000,
+ 0x8c43000c, 0x30630001, 0x1060002c, 0x32510002, 0x3c029000, 0x8f830008,
+ 0x34420001, 0x3c048000, 0x00621825, 0xaf430020, 0x8f420020, 0x00441024,
+ 0x1440fffd, 0x00000000, 0x8f870000, 0x8ce2000c, 0x30420001, 0x10400018,
+ 0x00000000, 0x94e2006a, 0x00022880, 0x50a00001, 0x24050001, 0x94e30068,
+ 0x90e40081, 0x3c020800, 0x8c460024, 0x00652821, 0x00852804, 0x00c5102b,
+ 0x54400001, 0x00a03021, 0x3c020800, 0x8c440028, 0x00c4182b, 0x54600001,
+ 0x00c02021, 0x8f430074, 0x2402fffe, 0x00822824, 0x00a31821, 0xace3000c,
+ 0x8f830008, 0x3c028000, 0x34420001, 0x00621825, 0xaf430020, 0x8f820020,
+ 0x3c050800, 0x24b05880, 0xae020028, 0x8ee30010, 0x0060f809, 0x00000000,
+ 0x8f820028, 0x24420001, 0xaf820028, 0x12a00005, 0xaf40004c, 0x8f420e10,
+ 0xae020030, 0x8f430e18, 0xae030034, 0x1220fea7, 0x24020006, 0x8f870024,
+ 0x9786002c, 0x8f830000, 0x8f820034, 0x8f840020, 0x8f85001c, 0x32530040,
+ 0xa4e6002c, 0xac620044, 0x32420008, 0xac640050, 0xac650054, 0x1040007a,
+ 0x32820020, 0x10400027, 0x32910010, 0x00003821, 0x24052000, 0x3c090800,
+ 0x3c038000, 0x8f420178, 0x00431024, 0x1440fffd, 0x8ec258b0, 0x26c458b0,
+ 0x2484ffd0, 0xaf420144, 0x8c820034, 0x3c030400, 0xaf420148, 0x24020041,
+ 0xaf43014c, 0xa3420152, 0x8d230030, 0x3c021000, 0xa7470158, 0xaf450154,
+ 0xaf420178, 0x8c860034, 0x24630001, 0xad230030, 0x9342010a, 0x3c030041,
+ 0xafa50014, 0x00021600, 0x00431025, 0x00471025, 0xafa20010, 0x9343010b,
+ 0xafa30018, 0x8f440100, 0x8f450104, 0x0e00159b, 0x3c070400, 0x12200028,
+ 0x00003821, 0x24052000, 0x3c090800, 0x3c038000, 0x8f420178, 0x00431024,
+ 0x1440fffd, 0x8ec258b0, 0x26c458b0, 0x2484ffd0, 0xaf420144, 0x8c820034,
+ 0x3c030300, 0xaf420148, 0x2402004e, 0xaf43014c, 0xa3420152, 0x8d230030,
+ 0x3c021000, 0xa7470158, 0xaf450154, 0xaf420178, 0x8c860034, 0x24630001,
+ 0xad230030, 0x9342010a, 0x3c03004e, 0xafa50014, 0x00021600, 0x00431025,
+ 0x00471025, 0xafa20010, 0x9343010b, 0xafa30018, 0x8f440100, 0x8f450104,
+ 0x0e00159b, 0x3c070300, 0x0a00148b, 0x8fa20024, 0x32820008, 0x10400026,
+ 0x24052000, 0x00003821, 0x3c090800, 0x3c038000, 0x8f420178, 0x00431024,
+ 0x1440fffd, 0x8ec258b0, 0x26c458b0, 0x2484ffd0, 0xaf420144, 0x8c820034,
+ 0x3c030200, 0xaf420148, 0x2402004b, 0xaf43014c, 0xa3420152, 0x8d230030,
+ 0x3c021000, 0xa7470158, 0xaf450154, 0xaf420178, 0x8c860034, 0x24630001,
+ 0xad230030, 0x9342010a, 0x3c03004b, 0xafa50014, 0x00021600, 0x00431025,
+ 0x00471025, 0xafa20010, 0x9343010b, 0xafa30018, 0x8f440100, 0x8f450104,
+ 0x0e00159b, 0x3c070200, 0x8fa20024, 0x14400004, 0x8fa30020, 0x32420010,
+ 0x10400004, 0x00000000, 0x8c620004, 0x0040f809, 0x00000000, 0x12600006,
+ 0x8fa40020, 0x8c820008, 0x0040f809, 0x00000000, 0x0a0014c1, 0x8fbf0054,
+ 0x3c030800, 0x8c6258a0, 0x30420040, 0x14400023, 0x8fbf0054, 0x00002821,
+ 0x24040040, 0x8f870020, 0x3c038000, 0x8f420178, 0x00431024, 0x1440fffd,
+ 0x8ec258b0, 0x26c358b0, 0x2463ffd0, 0xaf420144, 0x8c620034, 0xaf420148,
+ 0x24020049, 0xaf47014c, 0xa3420152, 0x3c021000, 0xa7450158, 0xaf440154,
+ 0xaf420178, 0x8c660034, 0x9342010a, 0x3c030049, 0xafa40014, 0x00021600,
+ 0x00431025, 0x00451025, 0xafa20010, 0x9343010b, 0xafa30018, 0x8f440100,
+ 0x0e00159b, 0x8f450104, 0x8fbf0054, 0x8fbe0050, 0x8fb7004c, 0x8fb60048,
+ 0x8fb50044, 0x8fb40040, 0x8fb3003c, 0x8fb20038, 0x8fb10034, 0x8fb00030,
+ 0x03e00008, 0x27bd0058, 0x03e00008, 0x00001021, 0x3c020800, 0x24435880,
+ 0x8c650004, 0x8c445880, 0x0085182b, 0x10600002, 0x00403021, 0x00802821,
+ 0x9744093c, 0x00a4102b, 0x54400001, 0x00a02021, 0x93420923, 0x0004182b,
+ 0x00021042, 0x30420001, 0x00431024, 0x1040000d, 0x24c25880, 0x8f850000,
+ 0x8f830020, 0x8ca20084, 0x00431023, 0x04420007, 0x24c25880, 0x8ca20084,
+ 0x00641821, 0x00431023, 0x28420001, 0x00822023, 0x24c25880, 0xac440008,
+ 0xa4400026, 0x03e00008, 0x00001021, 0x8f850004, 0x97840010, 0x3c030800,
+ 0x24635880, 0x24020008, 0xa4620012, 0x8f820004, 0xa4600010, 0x000420c2,
0x30840008, 0x2c420001, 0x00021023, 0x30420006, 0xac650008, 0x03e00008,
- 0xa0640020, 0x3c020800, 0x24424120, 0x90450021, 0x94430018, 0x3c021100,
+ 0xa0640024, 0x3c020800, 0x24425880, 0x90450025, 0x9443001c, 0x3c021100,
0xac800004, 0x00052c00, 0x24630002, 0x00621825, 0x00a32825, 0x24820008,
- 0x03e00008, 0xac850000, 0x0000000d, 0x00000000, 0x2400016f, 0x03e00008,
- 0x00000000, 0x0000000d, 0x00000000, 0x2400017b, 0x03e00008, 0x00000000,
- 0x03e00008, 0x00000000, 0x3c020800, 0x24424120, 0xac400008, 0xa4400022,
- 0x03e00008, 0x24020001, 0x3c020800, 0x24424120, 0x24030008, 0xac400008,
- 0xa440000c, 0xa443000e, 0xa0400020, 0x03e00008, 0x24020004, 0x03e00008,
+ 0x03e00008, 0xac850000, 0x27bdffd8, 0x3c020800, 0x24425880, 0xafbf0020,
+ 0x90480025, 0x8c440008, 0x8c460020, 0x8f870020, 0x3c030800, 0x3c058000,
+ 0x8f420178, 0x00451024, 0x1440fffd, 0x8c6258b0, 0x246358b0, 0x2469ffd0,
+ 0xaf420144, 0x8d220034, 0x30c32000, 0xaf420148, 0x3c021000, 0xaf47014c,
+ 0xa3480152, 0xa7440158, 0xaf460154, 0xaf420178, 0x10600004, 0x3c030800,
+ 0x8c620030, 0x24420001, 0xac620030, 0x9342010a, 0x00081c00, 0x3084ffff,
+ 0xafa60014, 0x00021600, 0x00431025, 0x00441025, 0xafa20010, 0x9343010b,
+ 0xafa30018, 0x8f440100, 0x8f450104, 0x0e00159b, 0x8d260034, 0x8fbf0020,
+ 0x03e00008, 0x27bd0028, 0x0000000d, 0x00000000, 0x2400019d, 0x03e00008,
+ 0x00000000, 0x0000000d, 0x00000000, 0x240001a9, 0x03e00008, 0x00000000,
+ 0x03e00008, 0x00000000, 0x3c020800, 0x24425880, 0xac400008, 0xa4400026,
+ 0x03e00008, 0x24020001, 0x3c020800, 0x24425880, 0x24030008, 0xac400008,
+ 0xa4400010, 0xa4430012, 0xa0400024, 0x03e00008, 0x24020004, 0x03e00008,
0x00001021, 0x10c00007, 0x00000000, 0x8ca20000, 0x24c6ffff, 0x24a50004,
- 0xac820000, 0x14c0fffb, 0x24840004, 0x03e00008, 0x00000000, 0x0a000fb2,
- 0x00a01021, 0xac860000, 0x24840004, 0x00a01021, 0x1440fffc, 0x24a5ffff,
- 0x03e00008, 0x00000000, 0x3c0a0800, 0x8d490068, 0x3c050800, 0x24a51090,
- 0x00093140, 0x00c51021, 0xac440000, 0x8f440e04, 0x00a61021, 0xac440004,
- 0x97430e08, 0x97420e0c, 0x00a62021, 0x00031c00, 0x00431025, 0xac820008,
- 0x8f430e10, 0x00801021, 0xac43000c, 0x8f440e14, 0xac440010, 0x8f430e18,
- 0x3c0800ff, 0xac430014, 0x8f470e1c, 0x3508ffff, 0x25290001, 0xac470018,
- 0x3c070800, 0x8ce3006c, 0x9344010a, 0x3c026000, 0x24630001, 0xace3006c,
- 0x8c434448, 0x3129007f, 0x00a62821, 0xad490068, 0x00042600, 0x00681824,
- 0x00832025, 0x03e00008, 0xaca4001c, 0x8fac0010, 0x8fad0014, 0x8fae0018,
- 0x3c0b0800, 0x8d6a0060, 0x3c080800, 0x25080078, 0x000a4940, 0x01281021,
- 0x01091821, 0xac440000, 0x00601021, 0xac650004, 0xac460008, 0xac67000c,
- 0xac4c0010, 0xac6d0014, 0x3c036000, 0xac4e0018, 0x8c654448, 0x3c040800,
- 0x8c820064, 0x254a0001, 0x314a007f, 0x01094021, 0xad6a0060, 0x24420001,
- 0xac820064, 0x03e00008, 0xad05001c, 0x00000000 };
-
-static u32 bnx2_TXP_b06FwData[(0x0/4) + 1] = { 0x00000000 };
-static u32 bnx2_TXP_b06FwRodata[(0x0/4) + 1] = { 0x00000000 };
-static u32 bnx2_TXP_b06FwBss[(0x194/4) + 1] = { 0x00000000 };
-static u32 bnx2_TXP_b06FwSbss[(0x34/4) + 1] = { 0x00000000 };
+ 0xac820000, 0x14c0fffb, 0x24840004, 0x03e00008, 0x00000000, 0x0a00156c,
+ 0x00a01021, 0xac860000, 0x00000000, 0x00000000, 0x24840004, 0x00a01021,
+ 0x1440fffa, 0x24a5ffff, 0x03e00008, 0x00000000, 0x3c0a0800, 0x8d490068,
+ 0x3c050800, 0x24a52098, 0x00093140, 0x00c51021, 0xac440000, 0x8f440e04,
+ 0x00a61021, 0xac440004, 0x97430e08, 0x97420e0c, 0x00a62021, 0x00031c00,
+ 0x00431025, 0xac820008, 0x8f430e10, 0x00801021, 0xac43000c, 0x8f440e14,
+ 0xac440010, 0x8f430e18, 0x3c0800ff, 0xac430014, 0x8f470e1c, 0x3508ffff,
+ 0x25290001, 0xac470018, 0x3c070800, 0x8ce3006c, 0x9344010a, 0x3c026000,
+ 0x24630001, 0xace3006c, 0x8c434448, 0x3129007f, 0x00a62821, 0xad490068,
+ 0x00042600, 0x00681824, 0x00832025, 0x03e00008, 0xaca4001c, 0x8fac0010,
+ 0x8fad0014, 0x8fae0018, 0x3c0b0800, 0x8d6a0060, 0x3c080800, 0x25080080,
+ 0x000a4940, 0x01281021, 0x01091821, 0xac440000, 0x00601021, 0xac650004,
+ 0xac460008, 0xac67000c, 0xac4c0010, 0xac6d0014, 0x3c036000, 0xac4e0018,
+ 0x8c654448, 0x3c040800, 0x8c820064, 0x254a0001, 0x314a00ff, 0x01094021,
+ 0xad6a0060, 0x24420001, 0xac820064, 0x03e00008, 0xad05001c, 0x3c030800,
+ 0x3c090800, 0x8d250070, 0x246330b0, 0x8f460100, 0x00053900, 0x00e31021,
+ 0xac460000, 0x8f440104, 0x00671021, 0xac440004, 0x8f460108, 0x8f840014,
+ 0x24a50001, 0xac460008, 0x8c880074, 0x3c060800, 0x8cc20074, 0x30a5003f,
+ 0x00671821, 0xad250070, 0x24420001, 0xacc20074, 0x03e00008, 0xac68000c,
+ 0x00000000 };
+static u32 bnx2_TXP_b06FwData[(0x0/4) + 1] = { 0x0 };
+static u32 bnx2_TXP_b06FwRodata[(0x0/4) + 1] = { 0x0 };
+static u32 bnx2_TXP_b06FwBss[(0x1c4/4) + 1] = { 0x0 };
+static u32 bnx2_TXP_b06FwSbss[(0x38/4) + 1] = { 0x0 };
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index f264ff162979..94cec3cf2a13 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -1604,35 +1604,27 @@ static int bond_sethwaddr(struct net_device *bond_dev, struct net_device *slave_
(NETIF_F_SG|NETIF_F_IP_CSUM|NETIF_F_NO_CSUM|NETIF_F_HW_CSUM)
/*
- * Compute the features available to the bonding device by
- * intersection of all of the slave devices' BOND_INTERSECT_FEATURES.
- * Call this after attaching or detaching a slave to update the
- * bond's features.
+ * Compute the common dev->feature set available to all slaves. Some
+ * feature bits are managed elsewhere, so preserve feature bits set on
+ * master device that are not part of the examined set.
*/
static int bond_compute_features(struct bonding *bond)
{
- int i;
+ unsigned long features = BOND_INTERSECT_FEATURES;
struct slave *slave;
struct net_device *bond_dev = bond->dev;
- int features = bond->bond_features;
+ int i;
- bond_for_each_slave(bond, slave, i) {
- struct net_device * slave_dev = slave->dev;
- if (i == 0) {
- features |= BOND_INTERSECT_FEATURES;
- }
- features &=
- ~(~slave_dev->features & BOND_INTERSECT_FEATURES);
- }
+ bond_for_each_slave(bond, slave, i)
+ features &= (slave->dev->features & BOND_INTERSECT_FEATURES);
- /* turn off NETIF_F_SG if we need a csum and h/w can't do it */
if ((features & NETIF_F_SG) &&
- !(features & (NETIF_F_IP_CSUM |
- NETIF_F_NO_CSUM |
- NETIF_F_HW_CSUM))) {
+ !(features & (NETIF_F_IP_CSUM |
+ NETIF_F_NO_CSUM |
+ NETIF_F_HW_CSUM)))
features &= ~NETIF_F_SG;
- }
+ features |= (bond_dev->features & ~BOND_INTERSECT_FEATURES);
bond_dev->features = features;
return 0;
@@ -4241,6 +4233,43 @@ out:
return 0;
}
+static void bond_activebackup_xmit_copy(struct sk_buff *skb,
+ struct bonding *bond,
+ struct slave *slave)
+{
+ struct sk_buff *skb2 = skb_copy(skb, GFP_ATOMIC);
+ struct ethhdr *eth_data;
+ u8 *hwaddr;
+ int res;
+
+ if (!skb2) {
+ printk(KERN_ERR DRV_NAME ": Error: "
+ "bond_activebackup_xmit_copy(): skb_copy() failed\n");
+ return;
+ }
+
+ skb2->mac.raw = (unsigned char *)skb2->data;
+ eth_data = eth_hdr(skb2);
+
+ /* Pick an appropriate source MAC address
+ * -- use slave's perm MAC addr, unless used by bond
+ * -- otherwise, borrow active slave's perm MAC addr
+ * since that will not be used
+ */
+ hwaddr = slave->perm_hwaddr;
+ if (!memcmp(eth_data->h_source, hwaddr, ETH_ALEN))
+ hwaddr = bond->curr_active_slave->perm_hwaddr;
+
+ /* Set source MAC address appropriately */
+ memcpy(eth_data->h_source, hwaddr, ETH_ALEN);
+
+ res = bond_dev_queue_xmit(bond, skb2, slave->dev);
+ if (res)
+ dev_kfree_skb(skb2);
+
+ return;
+}
+
/*
* in active-backup mode, we know that bond->curr_active_slave is always valid if
* the bond has a usable interface.
@@ -4257,10 +4286,26 @@ static int bond_xmit_activebackup(struct sk_buff *skb, struct net_device *bond_d
goto out;
}
- if (bond->curr_active_slave) { /* one usable interface */
- res = bond_dev_queue_xmit(bond, skb, bond->curr_active_slave->dev);
+ if (!bond->curr_active_slave)
+ goto out;
+
+ /* Xmit IGMP frames on all slaves to ensure rapid fail-over
+ for multicast traffic on snooping switches */
+ if (skb->protocol == __constant_htons(ETH_P_IP) &&
+ skb->nh.iph->protocol == IPPROTO_IGMP) {
+ struct slave *slave, *active_slave;
+ int i;
+
+ active_slave = bond->curr_active_slave;
+ bond_for_each_slave_from_to(bond, slave, i, active_slave->next,
+ active_slave->prev)
+ if (IS_UP(slave->dev) &&
+ (slave->link == BOND_LINK_UP))
+ bond_activebackup_xmit_copy(skb, bond, slave);
}
+ res = bond_dev_queue_xmit(bond, skb, bond->curr_active_slave->dev);
+
out:
if (res) {
/* no suitable interface, frame not sent */
@@ -4508,8 +4553,6 @@ static int __init bond_init(struct net_device *bond_dev, struct bond_params *par
NETIF_F_HW_VLAN_RX |
NETIF_F_HW_VLAN_FILTER);
- bond->bond_features = bond_dev->features;
-
#ifdef CONFIG_PROC_FS
bond_create_proc_entry(bond);
#endif
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
index bbf9da8af624..1433e91db0f7 100644
--- a/drivers/net/bonding/bonding.h
+++ b/drivers/net/bonding/bonding.h
@@ -40,8 +40,8 @@
#include "bond_3ad.h"
#include "bond_alb.h"
-#define DRV_VERSION "2.6.4"
-#define DRV_RELDATE "September 26, 2005"
+#define DRV_VERSION "2.6.5"
+#define DRV_RELDATE "November 4, 2005"
#define DRV_NAME "bonding"
#define DRV_DESCRIPTION "Ethernet Channel Bonding Driver"
@@ -211,9 +211,6 @@ struct bonding {
struct bond_params params;
struct list_head vlan_list;
struct vlan_group *vlgrp;
- /* the features the bonding device supports, independently
- * of any slaves */
- int bond_features;
};
/**
diff --git a/drivers/net/cassini.c b/drivers/net/cassini.c
index 2e617424d3fb..1f7ca453bb4a 100644
--- a/drivers/net/cassini.c
+++ b/drivers/net/cassini.c
@@ -67,7 +67,6 @@
*/
#include <linux/config.h>
-#include <linux/version.h>
#include <linux/module.h>
#include <linux/kernel.h>
@@ -489,7 +488,7 @@ static int cas_page_free(struct cas *cp, cas_page_t *page)
/* local page allocation routines for the receive buffers. jumbo pages
* require at least 8K contiguous and 8K aligned buffers.
*/
-static cas_page_t *cas_page_alloc(struct cas *cp, const int flags)
+static cas_page_t *cas_page_alloc(struct cas *cp, const gfp_t flags)
{
cas_page_t *page;
@@ -561,7 +560,7 @@ static void cas_spare_free(struct cas *cp)
}
/* replenish spares if needed */
-static void cas_spare_recover(struct cas *cp, const int flags)
+static void cas_spare_recover(struct cas *cp, const gfp_t flags)
{
struct list_head list, *elem, *tmp;
int needed, i;
diff --git a/drivers/net/cris/eth_v10.c b/drivers/net/cris/eth_v10.c
index b68b9cad76e9..64105e4eaf31 100644
--- a/drivers/net/cris/eth_v10.c
+++ b/drivers/net/cris/eth_v10.c
@@ -409,7 +409,6 @@ static irqreturn_t e100nw_interrupt(int irq, void *dev_id, struct pt_regs *regs)
static void e100_rx(struct net_device *dev);
static int e100_close(struct net_device *dev);
static int e100_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd);
-static int e100_ethtool_ioctl(struct net_device* dev, struct ifreq *ifr);
static int e100_set_config(struct net_device* dev, struct ifmap* map);
static void e100_tx_timeout(struct net_device *dev);
static struct net_device_stats *e100_get_stats(struct net_device *dev);
@@ -436,6 +435,8 @@ static void e100_reset_transceiver(struct net_device* net);
static void e100_clear_network_leds(unsigned long dummy);
static void e100_set_network_leds(int active);
+static struct ethtool_ops e100_ethtool_ops;
+
static void broadcom_check_speed(struct net_device* dev);
static void broadcom_check_duplex(struct net_device* dev);
static void tdk_check_speed(struct net_device* dev);
@@ -495,6 +496,7 @@ etrax_ethernet_init(void)
dev->get_stats = e100_get_stats;
dev->set_multicast_list = set_multicast_list;
dev->set_mac_address = e100_set_mac_address;
+ dev->ethtool_ops = &e100_ethtool_ops;
dev->do_ioctl = e100_ioctl;
dev->set_config = e100_set_config;
dev->tx_timeout = e100_tx_timeout;
@@ -1448,8 +1450,6 @@ e100_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
spin_lock(&np->lock); /* Preempt protection */
switch (cmd) {
- case SIOCETHTOOL:
- return e100_ethtool_ioctl(dev,ifr);
case SIOCGMIIPHY: /* Get PHY address */
data->phy_id = mdio_phy_addr;
break;
@@ -1486,88 +1486,81 @@ e100_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
return 0;
}
-static int
-e100_ethtool_ioctl(struct net_device *dev, struct ifreq *ifr)
+static int e100_set_settings(struct net_device *dev,
+ struct ethtool_cmd *ecmd)
{
- struct ethtool_cmd ecmd;
-
- if (copy_from_user(&ecmd, ifr->ifr_data, sizeof (ecmd)))
- return -EFAULT;
-
- switch (ecmd.cmd) {
- case ETHTOOL_GSET:
- {
- memset((void *) &ecmd, 0, sizeof (ecmd));
- ecmd.supported =
- SUPPORTED_Autoneg | SUPPORTED_TP | SUPPORTED_MII |
+ ecmd->supported = SUPPORTED_Autoneg | SUPPORTED_TP | SUPPORTED_MII |
SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full |
SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full;
- ecmd.port = PORT_TP;
- ecmd.transceiver = XCVR_EXTERNAL;
- ecmd.phy_address = mdio_phy_addr;
- ecmd.speed = current_speed;
- ecmd.duplex = full_duplex ? DUPLEX_FULL : DUPLEX_HALF;
- ecmd.advertising = ADVERTISED_TP;
- if (current_duplex == autoneg && current_speed_selection == 0)
- ecmd.advertising |= ADVERTISED_Autoneg;
- else {
- ecmd.advertising |=
- ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full |
- ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full;
- if (current_speed_selection == 10)
- ecmd.advertising &= ~(ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full);
- else if (current_speed_selection == 100)
- ecmd.advertising &= ~(ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full);
- if (current_duplex == half)
- ecmd.advertising &= ~(ADVERTISED_10baseT_Full | ADVERTISED_100baseT_Full);
- else if (current_duplex == full)
- ecmd.advertising &= ~(ADVERTISED_10baseT_Half | ADVERTISED_100baseT_Half);
- }
- ecmd.autoneg = AUTONEG_ENABLE;
- if (copy_to_user(ifr->ifr_data, &ecmd, sizeof (ecmd)))
- return -EFAULT;
- }
- break;
- case ETHTOOL_SSET:
- {
- if (!capable(CAP_NET_ADMIN)) {
- return -EPERM;
- }
- if (ecmd.autoneg == AUTONEG_ENABLE) {
- e100_set_duplex(dev, autoneg);
- e100_set_speed(dev, 0);
- } else {
- e100_set_duplex(dev, ecmd.duplex == DUPLEX_HALF ? half : full);
- e100_set_speed(dev, ecmd.speed == SPEED_10 ? 10: 100);
- }
- }
- break;
- case ETHTOOL_GDRVINFO:
- {
- struct ethtool_drvinfo info;
- memset((void *) &info, 0, sizeof (info));
- strncpy(info.driver, "ETRAX 100LX", sizeof(info.driver) - 1);
- strncpy(info.version, "$Revision: 1.31 $", sizeof(info.version) - 1);
- strncpy(info.fw_version, "N/A", sizeof(info.fw_version) - 1);
- strncpy(info.bus_info, "N/A", sizeof(info.bus_info) - 1);
- info.regdump_len = 0;
- info.eedump_len = 0;
- info.testinfo_len = 0;
- if (copy_to_user(ifr->ifr_data, &info, sizeof (info)))
- return -EFAULT;
- }
- break;
- case ETHTOOL_NWAY_RST:
- if (current_duplex == autoneg && current_speed_selection == 0)
- e100_negotiate(dev);
- break;
- default:
- return -EOPNOTSUPP;
- break;
+ ecmd->port = PORT_TP;
+ ecmd->transceiver = XCVR_EXTERNAL;
+ ecmd->phy_address = mdio_phy_addr;
+ ecmd->speed = current_speed;
+ ecmd->duplex = full_duplex ? DUPLEX_FULL : DUPLEX_HALF;
+ ecmd->advertising = ADVERTISED_TP;
+
+ if (current_duplex == autoneg && current_speed_selection == 0)
+ ecmd->advertising |= ADVERTISED_Autoneg;
+ else {
+ ecmd->advertising |=
+ ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full |
+ ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full;
+ if (current_speed_selection == 10)
+ ecmd->advertising &= ~(ADVERTISED_100baseT_Half |
+ ADVERTISED_100baseT_Full);
+ else if (current_speed_selection == 100)
+ ecmd->advertising &= ~(ADVERTISED_10baseT_Half |
+ ADVERTISED_10baseT_Full);
+ if (current_duplex == half)
+ ecmd->advertising &= ~(ADVERTISED_10baseT_Full |
+ ADVERTISED_100baseT_Full);
+ else if (current_duplex == full)
+ ecmd->advertising &= ~(ADVERTISED_10baseT_Half |
+ ADVERTISED_100baseT_Half);
+ }
+
+ ecmd->autoneg = AUTONEG_ENABLE;
+ return 0;
+}
+
+static int e100_set_settings(struct net_device *dev,
+ struct ethtool_cmd *ecmd)
+{
+ if (ecmd->autoneg == AUTONEG_ENABLE) {
+ e100_set_duplex(dev, autoneg);
+ e100_set_speed(dev, 0);
+ } else {
+ e100_set_duplex(dev, ecmd->duplex == DUPLEX_HALF ? half : full);
+ e100_set_speed(dev, ecmd->speed == SPEED_10 ? 10: 100);
}
+
+ return 0;
+}
+
+static void e100_get_drvinfo(struct net_device *dev,
+ struct ethtool_drvinfo *info)
+{
+ strncpy(info->driver, "ETRAX 100LX", sizeof(info->driver) - 1);
+ strncpy(info->version, "$Revision: 1.31 $", sizeof(info->version) - 1);
+ strncpy(info->fw_version, "N/A", sizeof(info->fw_version) - 1);
+ strncpy(info->bus_info, "N/A", sizeof(info->bus_info) - 1);
+}
+
+static int e100_nway_reset(struct net_device *dev)
+{
+ if (current_duplex == autoneg && current_speed_selection == 0)
+ e100_negotiate(dev);
return 0;
}
+static struct ethtool_ops e100_ethtool_ops = {
+ .get_settings = e100_get_settings,
+ .set_settings = e100_set_settings,
+ .get_drvinfo = e100_get_drvinfo,
+ .nway_reset = e100_nway_reset,
+ .get_link = ethtool_op_get_link,
+};
+
static int
e100_set_config(struct net_device *dev, struct ifmap *map)
{
diff --git a/drivers/net/declance.c b/drivers/net/declance.c
index 521c83137bf6..f130bdab3fd3 100644
--- a/drivers/net/declance.c
+++ b/drivers/net/declance.c
@@ -5,7 +5,7 @@
*
* adopted from sunlance.c by Richard van den Berg
*
- * Copyright (C) 2002, 2003 Maciej W. Rozycki
+ * Copyright (C) 2002, 2003, 2005 Maciej W. Rozycki
*
* additional sources:
* - PMAD-AA TURBOchannel Ethernet Module Functional Specification,
@@ -57,13 +57,15 @@
#include <linux/string.h>
#include <asm/addrspace.h>
+#include <asm/system.h>
+
#include <asm/dec/interrupts.h>
#include <asm/dec/ioasic.h>
#include <asm/dec/ioasic_addrs.h>
#include <asm/dec/kn01.h>
#include <asm/dec/machtype.h>
+#include <asm/dec/system.h>
#include <asm/dec/tc.h>
-#include <asm/system.h>
static char version[] __devinitdata =
"declance.c: v0.009 by Linux MIPS DECstation task force\n";
@@ -79,10 +81,6 @@ MODULE_LICENSE("GPL");
#define PMAD_LANCE 2
#define PMAX_LANCE 3
-#ifndef CONFIG_TC
-unsigned long system_base;
-unsigned long dmaptr;
-#endif
#define LE_CSR0 0
#define LE_CSR1 1
@@ -237,7 +235,7 @@ struct lance_init_block {
/*
* This works *only* for the ring descriptors
*/
-#define LANCE_ADDR(x) (PHYSADDR(x) >> 1)
+#define LANCE_ADDR(x) (CPHYSADDR(x) >> 1)
struct lance_private {
struct net_device *next;
@@ -697,12 +695,13 @@ out:
spin_unlock(&lp->lock);
}
-static void lance_dma_merr_int(const int irq, void *dev_id,
- struct pt_regs *regs)
+static irqreturn_t lance_dma_merr_int(const int irq, void *dev_id,
+ struct pt_regs *regs)
{
struct net_device *dev = (struct net_device *) dev_id;
printk("%s: DMA error\n", dev->name);
+ return IRQ_HANDLED;
}
static irqreturn_t
@@ -1026,10 +1025,6 @@ static int __init dec_lance_init(const int type, const int slot)
unsigned long esar_base;
unsigned char *esar;
-#ifndef CONFIG_TC
- system_base = KN01_LANCE_BASE;
-#endif
-
if (dec_lance_debug && version_printed++ == 0)
printk(version);
@@ -1062,16 +1057,16 @@ static int __init dec_lance_init(const int type, const int slot)
switch (type) {
#ifdef CONFIG_TC
case ASIC_LANCE:
- dev->base_addr = system_base + IOASIC_LANCE;
+ dev->base_addr = CKSEG1ADDR(dec_kn_slot_base + IOASIC_LANCE);
/* buffer space for the on-board LANCE shared memory */
/*
* FIXME: ugly hack!
*/
- dev->mem_start = KSEG1ADDR(0x00020000);
+ dev->mem_start = CKSEG1ADDR(0x00020000);
dev->mem_end = dev->mem_start + 0x00020000;
dev->irq = dec_interrupt[DEC_IRQ_LANCE];
- esar_base = system_base + IOASIC_ESAR;
+ esar_base = CKSEG1ADDR(dec_kn_slot_base + IOASIC_ESAR);
/* Workaround crash with booting KN04 2.1k from Disk */
memset((void *)dev->mem_start, 0,
@@ -1101,14 +1096,14 @@ static int __init dec_lance_init(const int type, const int slot)
/* Setup I/O ASIC LANCE DMA. */
lp->dma_irq = dec_interrupt[DEC_IRQ_LANCE_MERR];
ioasic_write(IO_REG_LANCE_DMA_P,
- PHYSADDR(dev->mem_start) << 3);
+ CPHYSADDR(dev->mem_start) << 3);
break;
case PMAD_LANCE:
claim_tc_card(slot);
- dev->mem_start = get_tc_base_addr(slot);
+ dev->mem_start = CKSEG1ADDR(get_tc_base_addr(slot));
dev->base_addr = dev->mem_start + 0x100000;
dev->irq = get_tc_irq_nr(slot);
esar_base = dev->mem_start + 0x1c0002;
@@ -1137,9 +1132,9 @@ static int __init dec_lance_init(const int type, const int slot)
case PMAX_LANCE:
dev->irq = dec_interrupt[DEC_IRQ_LANCE];
- dev->base_addr = KN01_LANCE_BASE;
- dev->mem_start = KN01_LANCE_BASE + 0x01000000;
- esar_base = KN01_RTC_BASE + 1;
+ dev->base_addr = CKSEG1ADDR(KN01_SLOT_BASE + KN01_LANCE);
+ dev->mem_start = CKSEG1ADDR(KN01_SLOT_BASE + KN01_LANCE_MEM);
+ esar_base = CKSEG1ADDR(KN01_SLOT_BASE + KN01_ESAR + 1);
lp->dma_irq = -1;
/*
diff --git a/drivers/net/depca.c b/drivers/net/depca.c
index c4aa5fe2840e..0d33a93df96b 100644
--- a/drivers/net/depca.c
+++ b/drivers/net/depca.c
@@ -254,7 +254,7 @@
#include <linux/unistd.h>
#include <linux/ctype.h>
#include <linux/moduleparam.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <linux/bitops.h>
#include <asm/uaccess.h>
@@ -1470,15 +1470,6 @@ static int __init depca_mca_probe(struct device *device)
** ISA bus I/O device probe
*/
-static void depca_platform_release (struct device *device)
-{
- struct platform_device *pldev;
-
- /* free device */
- pldev = to_platform_device (device);
- kfree (pldev);
-}
-
static void __init depca_platform_probe (void)
{
int i;
@@ -1491,19 +1482,16 @@ static void __init depca_platform_probe (void)
* line, use it (if valid) */
if (io && io != depca_io_ports[i].iobase)
continue;
-
- if (!(pldev = kmalloc (sizeof (*pldev), GFP_KERNEL)))
+
+ pldev = platform_device_alloc(depca_string, i);
+ if (!pldev)
continue;
- memset (pldev, 0, sizeof (*pldev));
- pldev->name = depca_string;
- pldev->id = i;
pldev->dev.platform_data = (void *) depca_io_ports[i].iobase;
- pldev->dev.release = depca_platform_release;
depca_io_ports[i].device = pldev;
- if (platform_device_register (pldev)) {
- kfree (pldev);
+ if (platform_device_add(pldev)) {
+ platform_device_put(pldev);
depca_io_ports[i].device = NULL;
continue;
}
@@ -1515,6 +1503,7 @@ static void __init depca_platform_probe (void)
* allocated structure */
depca_io_ports[i].device = NULL;
+ pldev->dev.platform_data = NULL;
platform_device_unregister (pldev);
}
}
@@ -2112,6 +2101,7 @@ static void __exit depca_module_exit (void)
for (i = 0; depca_io_ports[i].iobase; i++) {
if (depca_io_ports[i].device) {
+ depca_io_ports[i].device->dev.platform_data = NULL;
platform_device_unregister (depca_io_ports[i].device);
depca_io_ports[i].device = NULL;
}
diff --git a/drivers/net/dgrs.c b/drivers/net/dgrs.c
index 7809838e6c4c..2a290cc397ad 100644
--- a/drivers/net/dgrs.c
+++ b/drivers/net/dgrs.c
@@ -1549,7 +1549,7 @@ MODULE_PARM_DESC(nicmode, "Digi RightSwitch operating mode (1: switch, 2: multi-
static int __init dgrs_init_module (void)
{
int i;
- int eisacount = 0, pcicount = 0;
+ int cardcount = 0;
/*
* Command line variable overrides
@@ -1591,15 +1591,13 @@ static int __init dgrs_init_module (void)
* Find and configure all the cards
*/
#ifdef CONFIG_EISA
- eisacount = eisa_driver_register(&dgrs_eisa_driver);
- if (eisacount < 0)
- return eisacount;
-#endif
-#ifdef CONFIG_PCI
- pcicount = pci_register_driver(&dgrs_pci_driver);
- if (pcicount)
- return pcicount;
+ cardcount = eisa_driver_register(&dgrs_eisa_driver);
+ if (cardcount < 0)
+ return cardcount;
#endif
+ cardcount = pci_register_driver(&dgrs_pci_driver);
+ if (cardcount)
+ return cardcount;
return 0;
}
diff --git a/drivers/net/dm9000.c b/drivers/net/dm9000.c
index e54fc10f6846..f8c9bcdab68b 100644
--- a/drivers/net/dm9000.c
+++ b/drivers/net/dm9000.c
@@ -60,12 +60,12 @@
#include <linux/etherdevice.h>
#include <linux/init.h>
#include <linux/skbuff.h>
-#include <linux/version.h>
#include <linux/spinlock.h>
#include <linux/crc32.h>
#include <linux/mii.h>
#include <linux/dm9000.h>
#include <linux/delay.h>
+#include <linux/platform_device.h>
#include <asm/delay.h>
#include <asm/irq.h>
@@ -1140,11 +1140,11 @@ dm9000_phy_write(struct net_device *dev, int phyaddr_unused, int reg, int value)
}
static int
-dm9000_drv_suspend(struct device *dev, pm_message_t state, u32 level)
+dm9000_drv_suspend(struct device *dev, pm_message_t state)
{
struct net_device *ndev = dev_get_drvdata(dev);
- if (ndev && level == SUSPEND_DISABLE) {
+ if (ndev) {
if (netif_running(ndev)) {
netif_device_detach(ndev);
dm9000_shutdown(ndev);
@@ -1154,12 +1154,12 @@ dm9000_drv_suspend(struct device *dev, pm_message_t state, u32 level)
}
static int
-dm9000_drv_resume(struct device *dev, u32 level)
+dm9000_drv_resume(struct device *dev)
{
struct net_device *ndev = dev_get_drvdata(dev);
board_info_t *db = (board_info_t *) ndev->priv;
- if (ndev && level == RESUME_ENABLE) {
+ if (ndev) {
if (netif_running(ndev)) {
dm9000_reset(db);
diff --git a/drivers/net/e100.c b/drivers/net/e100.c
index 40887f09b681..7a6aeae2c9fa 100644
--- a/drivers/net/e100.c
+++ b/drivers/net/e100.c
@@ -1478,7 +1478,7 @@ static inline int e100_rx_alloc_skb(struct nic *nic, struct rx *rx)
if(pci_dma_mapping_error(rx->dma_addr)) {
dev_kfree_skb_any(rx->skb);
- rx->skb = 0;
+ rx->skb = NULL;
rx->dma_addr = 0;
return -ENOMEM;
}
@@ -1764,7 +1764,7 @@ static int e100_up(struct nic *nic)
if((err = e100_hw_init(nic)))
goto err_clean_cbs;
e100_set_multicast_list(nic->netdev);
- e100_start_receiver(nic, 0);
+ e100_start_receiver(nic, NULL);
mod_timer(&nic->watchdog, jiffies);
if((err = request_irq(nic->pdev->irq, e100_intr, SA_SHIRQ,
nic->netdev->name, nic->netdev)))
@@ -1844,7 +1844,7 @@ static int e100_loopback_test(struct nic *nic, enum loopback loopback_mode)
mdio_write(nic->netdev, nic->mii.phy_id, MII_BMCR,
BMCR_LOOPBACK);
- e100_start_receiver(nic, 0);
+ e100_start_receiver(nic, NULL);
if(!(skb = dev_alloc_skb(ETH_DATA_LEN))) {
err = -ENOMEM;
@@ -2201,6 +2201,7 @@ static struct ethtool_ops e100_ethtool_ops = {
.phys_id = e100_phys_id,
.get_stats_count = e100_get_stats_count,
.get_ethtool_stats = e100_get_ethtool_stats,
+ .get_perm_addr = ethtool_op_get_perm_addr,
};
static int e100_do_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
@@ -2351,7 +2352,8 @@ static int __devinit e100_probe(struct pci_dev *pdev,
e100_phy_init(nic);
memcpy(netdev->dev_addr, nic->eeprom, ETH_ALEN);
- if(!is_valid_ether_addr(netdev->dev_addr)) {
+ memcpy(netdev->perm_addr, nic->eeprom, ETH_ALEN);
+ if(!is_valid_ether_addr(netdev->perm_addr)) {
DPRINTK(PROBE, ERR, "Invalid MAC address from "
"EEPROM, aborting.\n");
err = -EAGAIN;
diff --git a/drivers/net/e1000/e1000.h b/drivers/net/e1000/e1000.h
index 092757bc721f..3f653a93e1bc 100644
--- a/drivers/net/e1000/e1000.h
+++ b/drivers/net/e1000/e1000.h
@@ -72,6 +72,10 @@
#include <linux/mii.h>
#include <linux/ethtool.h>
#include <linux/if_vlan.h>
+#ifdef CONFIG_E1000_MQ
+#include <linux/cpu.h>
+#include <linux/smp.h>
+#endif
#define BAR_0 0
#define BAR_1 1
@@ -165,10 +169,33 @@ struct e1000_buffer {
uint16_t next_to_watch;
};
-struct e1000_ps_page { struct page *ps_page[MAX_PS_BUFFERS]; };
-struct e1000_ps_page_dma { uint64_t ps_page_dma[MAX_PS_BUFFERS]; };
+struct e1000_ps_page { struct page *ps_page[PS_PAGE_BUFFERS]; };
+struct e1000_ps_page_dma { uint64_t ps_page_dma[PS_PAGE_BUFFERS]; };
+
+struct e1000_tx_ring {
+ /* pointer to the descriptor ring memory */
+ void *desc;
+ /* physical address of the descriptor ring */
+ dma_addr_t dma;
+ /* length of descriptor ring in bytes */
+ unsigned int size;
+ /* number of descriptors in the ring */
+ unsigned int count;
+ /* next descriptor to associate a buffer with */
+ unsigned int next_to_use;
+ /* next descriptor to check for DD status bit */
+ unsigned int next_to_clean;
+ /* array of buffer information structs */
+ struct e1000_buffer *buffer_info;
+
+ struct e1000_buffer previous_buffer_info;
+ spinlock_t tx_lock;
+ uint16_t tdh;
+ uint16_t tdt;
+ uint64_t pkt;
+};
-struct e1000_desc_ring {
+struct e1000_rx_ring {
/* pointer to the descriptor ring memory */
void *desc;
/* physical address of the descriptor ring */
@@ -186,6 +213,10 @@ struct e1000_desc_ring {
/* arrays of page information for packet split */
struct e1000_ps_page *ps_page;
struct e1000_ps_page_dma *ps_page_dma;
+
+ uint16_t rdh;
+ uint16_t rdt;
+ uint64_t pkt;
};
#define E1000_DESC_UNUSED(R) \
@@ -227,9 +258,10 @@ struct e1000_adapter {
unsigned long led_status;
/* TX */
- struct e1000_desc_ring tx_ring;
- struct e1000_buffer previous_buffer_info;
- spinlock_t tx_lock;
+ struct e1000_tx_ring *tx_ring; /* One per active queue */
+#ifdef CONFIG_E1000_MQ
+ struct e1000_tx_ring **cpu_tx_ring; /* per-cpu */
+#endif
uint32_t txd_cmd;
uint32_t tx_int_delay;
uint32_t tx_abs_int_delay;
@@ -246,19 +278,33 @@ struct e1000_adapter {
/* RX */
#ifdef CONFIG_E1000_NAPI
- boolean_t (*clean_rx) (struct e1000_adapter *adapter, int *work_done,
- int work_to_do);
+ boolean_t (*clean_rx) (struct e1000_adapter *adapter,
+ struct e1000_rx_ring *rx_ring,
+ int *work_done, int work_to_do);
#else
- boolean_t (*clean_rx) (struct e1000_adapter *adapter);
+ boolean_t (*clean_rx) (struct e1000_adapter *adapter,
+ struct e1000_rx_ring *rx_ring);
#endif
- void (*alloc_rx_buf) (struct e1000_adapter *adapter);
- struct e1000_desc_ring rx_ring;
+ void (*alloc_rx_buf) (struct e1000_adapter *adapter,
+ struct e1000_rx_ring *rx_ring);
+ struct e1000_rx_ring *rx_ring; /* One per active queue */
+#ifdef CONFIG_E1000_NAPI
+ struct net_device *polling_netdev; /* One per active queue */
+#endif
+#ifdef CONFIG_E1000_MQ
+ struct net_device **cpu_netdev; /* per-cpu */
+ struct call_async_data_struct rx_sched_call_data;
+ int cpu_for_queue[4];
+#endif
+ int num_queues;
+
uint64_t hw_csum_err;
uint64_t hw_csum_good;
+ uint64_t rx_hdr_split;
uint32_t rx_int_delay;
uint32_t rx_abs_int_delay;
boolean_t rx_csum;
- boolean_t rx_ps;
+ unsigned int rx_ps_pages;
uint32_t gorcl;
uint64_t gorcl_old;
uint16_t rx_ps_bsize0;
@@ -278,8 +324,8 @@ struct e1000_adapter {
struct e1000_phy_stats phy_stats;
uint32_t test_icr;
- struct e1000_desc_ring test_tx_ring;
- struct e1000_desc_ring test_rx_ring;
+ struct e1000_tx_ring test_tx_ring;
+ struct e1000_rx_ring test_rx_ring;
int msg_enable;
diff --git a/drivers/net/e1000/e1000_ethtool.c b/drivers/net/e1000/e1000_ethtool.c
index f133ff0b0b94..8eae8ba27e84 100644
--- a/drivers/net/e1000/e1000_ethtool.c
+++ b/drivers/net/e1000/e1000_ethtool.c
@@ -39,10 +39,10 @@ extern int e1000_up(struct e1000_adapter *adapter);
extern void e1000_down(struct e1000_adapter *adapter);
extern void e1000_reset(struct e1000_adapter *adapter);
extern int e1000_set_spd_dplx(struct e1000_adapter *adapter, uint16_t spddplx);
-extern int e1000_setup_rx_resources(struct e1000_adapter *adapter);
-extern int e1000_setup_tx_resources(struct e1000_adapter *adapter);
-extern void e1000_free_rx_resources(struct e1000_adapter *adapter);
-extern void e1000_free_tx_resources(struct e1000_adapter *adapter);
+extern int e1000_setup_all_rx_resources(struct e1000_adapter *adapter);
+extern int e1000_setup_all_tx_resources(struct e1000_adapter *adapter);
+extern void e1000_free_all_rx_resources(struct e1000_adapter *adapter);
+extern void e1000_free_all_tx_resources(struct e1000_adapter *adapter);
extern void e1000_update_stats(struct e1000_adapter *adapter);
struct e1000_stats {
@@ -91,7 +91,8 @@ static const struct e1000_stats e1000_gstrings_stats[] = {
{ "tx_flow_control_xoff", E1000_STAT(stats.xofftxc) },
{ "rx_long_byte_count", E1000_STAT(stats.gorcl) },
{ "rx_csum_offload_good", E1000_STAT(hw_csum_good) },
- { "rx_csum_offload_errors", E1000_STAT(hw_csum_err) }
+ { "rx_csum_offload_errors", E1000_STAT(hw_csum_err) },
+ { "rx_header_split", E1000_STAT(rx_hdr_split) },
};
#define E1000_STATS_LEN \
sizeof(e1000_gstrings_stats) / sizeof(struct e1000_stats)
@@ -546,8 +547,10 @@ e1000_set_eeprom(struct net_device *netdev,
ret_val = e1000_write_eeprom(hw, first_word,
last_word - first_word + 1, eeprom_buff);
- /* Update the checksum over the first part of the EEPROM if needed */
- if((ret_val == 0) && first_word <= EEPROM_CHECKSUM_REG)
+ /* Update the checksum over the first part of the EEPROM if needed
+ * and flush shadow RAM for 82573 conrollers */
+ if((ret_val == 0) && ((first_word <= EEPROM_CHECKSUM_REG) ||
+ (hw->mac_type == e1000_82573)))
e1000_update_eeprom_checksum(hw);
kfree(eeprom_buff);
@@ -576,8 +579,8 @@ e1000_get_ringparam(struct net_device *netdev,
{
struct e1000_adapter *adapter = netdev_priv(netdev);
e1000_mac_type mac_type = adapter->hw.mac_type;
- struct e1000_desc_ring *txdr = &adapter->tx_ring;
- struct e1000_desc_ring *rxdr = &adapter->rx_ring;
+ struct e1000_tx_ring *txdr = adapter->tx_ring;
+ struct e1000_rx_ring *rxdr = adapter->rx_ring;
ring->rx_max_pending = (mac_type < e1000_82544) ? E1000_MAX_RXD :
E1000_MAX_82544_RXD;
@@ -597,20 +600,40 @@ e1000_set_ringparam(struct net_device *netdev,
{
struct e1000_adapter *adapter = netdev_priv(netdev);
e1000_mac_type mac_type = adapter->hw.mac_type;
- struct e1000_desc_ring *txdr = &adapter->tx_ring;
- struct e1000_desc_ring *rxdr = &adapter->rx_ring;
- struct e1000_desc_ring tx_old, tx_new, rx_old, rx_new;
- int err;
+ struct e1000_tx_ring *txdr, *tx_old, *tx_new;
+ struct e1000_rx_ring *rxdr, *rx_old, *rx_new;
+ int i, err, tx_ring_size, rx_ring_size;
+
+ tx_ring_size = sizeof(struct e1000_tx_ring) * adapter->num_queues;
+ rx_ring_size = sizeof(struct e1000_rx_ring) * adapter->num_queues;
+
+ if (netif_running(adapter->netdev))
+ e1000_down(adapter);
tx_old = adapter->tx_ring;
rx_old = adapter->rx_ring;
+ adapter->tx_ring = kmalloc(tx_ring_size, GFP_KERNEL);
+ if (!adapter->tx_ring) {
+ err = -ENOMEM;
+ goto err_setup_rx;
+ }
+ memset(adapter->tx_ring, 0, tx_ring_size);
+
+ adapter->rx_ring = kmalloc(rx_ring_size, GFP_KERNEL);
+ if (!adapter->rx_ring) {
+ kfree(adapter->tx_ring);
+ err = -ENOMEM;
+ goto err_setup_rx;
+ }
+ memset(adapter->rx_ring, 0, rx_ring_size);
+
+ txdr = adapter->tx_ring;
+ rxdr = adapter->rx_ring;
+
if((ring->rx_mini_pending) || (ring->rx_jumbo_pending))
return -EINVAL;
- if(netif_running(adapter->netdev))
- e1000_down(adapter);
-
rxdr->count = max(ring->rx_pending,(uint32_t)E1000_MIN_RXD);
rxdr->count = min(rxdr->count,(uint32_t)(mac_type < e1000_82544 ?
E1000_MAX_RXD : E1000_MAX_82544_RXD));
@@ -621,11 +644,16 @@ e1000_set_ringparam(struct net_device *netdev,
E1000_MAX_TXD : E1000_MAX_82544_TXD));
E1000_ROUNDUP(txdr->count, REQ_TX_DESCRIPTOR_MULTIPLE);
+ for (i = 0; i < adapter->num_queues; i++) {
+ txdr[i].count = txdr->count;
+ rxdr[i].count = rxdr->count;
+ }
+
if(netif_running(adapter->netdev)) {
/* Try to get new resources before deleting old */
- if((err = e1000_setup_rx_resources(adapter)))
+ if ((err = e1000_setup_all_rx_resources(adapter)))
goto err_setup_rx;
- if((err = e1000_setup_tx_resources(adapter)))
+ if ((err = e1000_setup_all_tx_resources(adapter)))
goto err_setup_tx;
/* save the new, restore the old in order to free it,
@@ -635,8 +663,10 @@ e1000_set_ringparam(struct net_device *netdev,
tx_new = adapter->tx_ring;
adapter->rx_ring = rx_old;
adapter->tx_ring = tx_old;
- e1000_free_rx_resources(adapter);
- e1000_free_tx_resources(adapter);
+ e1000_free_all_rx_resources(adapter);
+ e1000_free_all_tx_resources(adapter);
+ kfree(tx_old);
+ kfree(rx_old);
adapter->rx_ring = rx_new;
adapter->tx_ring = tx_new;
if((err = e1000_up(adapter)))
@@ -645,7 +675,7 @@ e1000_set_ringparam(struct net_device *netdev,
return 0;
err_setup_tx:
- e1000_free_rx_resources(adapter);
+ e1000_free_all_rx_resources(adapter);
err_setup_rx:
adapter->rx_ring = rx_old;
adapter->tx_ring = tx_old;
@@ -696,6 +726,11 @@ e1000_reg_test(struct e1000_adapter *adapter, uint64_t *data)
* Some bits that get toggled are ignored.
*/
switch (adapter->hw.mac_type) {
+ /* there are several bits on newer hardware that are r/w */
+ case e1000_82571:
+ case e1000_82572:
+ toggle = 0x7FFFF3FF;
+ break;
case e1000_82573:
toggle = 0x7FFFF033;
break;
@@ -898,8 +933,8 @@ e1000_intr_test(struct e1000_adapter *adapter, uint64_t *data)
static void
e1000_free_desc_rings(struct e1000_adapter *adapter)
{
- struct e1000_desc_ring *txdr = &adapter->test_tx_ring;
- struct e1000_desc_ring *rxdr = &adapter->test_rx_ring;
+ struct e1000_tx_ring *txdr = &adapter->test_tx_ring;
+ struct e1000_rx_ring *rxdr = &adapter->test_rx_ring;
struct pci_dev *pdev = adapter->pdev;
int i;
@@ -930,19 +965,16 @@ e1000_free_desc_rings(struct e1000_adapter *adapter)
if(rxdr->desc)
pci_free_consistent(pdev, rxdr->size, rxdr->desc, rxdr->dma);
- if(txdr->buffer_info)
- kfree(txdr->buffer_info);
- if(rxdr->buffer_info)
- kfree(rxdr->buffer_info);
-
+ kfree(txdr->buffer_info);
+ kfree(rxdr->buffer_info);
return;
}
static int
e1000_setup_desc_rings(struct e1000_adapter *adapter)
{
- struct e1000_desc_ring *txdr = &adapter->test_tx_ring;
- struct e1000_desc_ring *rxdr = &adapter->test_rx_ring;
+ struct e1000_tx_ring *txdr = &adapter->test_tx_ring;
+ struct e1000_rx_ring *rxdr = &adapter->test_rx_ring;
struct pci_dev *pdev = adapter->pdev;
uint32_t rctl;
int size, i, ret_val;
@@ -1245,6 +1277,8 @@ e1000_set_phy_loopback(struct e1000_adapter *adapter)
case e1000_82541_rev_2:
case e1000_82547:
case e1000_82547_rev_2:
+ case e1000_82571:
+ case e1000_82572:
case e1000_82573:
return e1000_integrated_phy_loopback(adapter);
break;
@@ -1340,8 +1374,8 @@ e1000_check_lbtest_frame(struct sk_buff *skb, unsigned int frame_size)
static int
e1000_run_loopback_test(struct e1000_adapter *adapter)
{
- struct e1000_desc_ring *txdr = &adapter->test_tx_ring;
- struct e1000_desc_ring *rxdr = &adapter->test_rx_ring;
+ struct e1000_tx_ring *txdr = &adapter->test_tx_ring;
+ struct e1000_rx_ring *rxdr = &adapter->test_rx_ring;
struct pci_dev *pdev = adapter->pdev;
int i, j, k, l, lc, good_cnt, ret_val=0;
unsigned long time;
@@ -1509,6 +1543,7 @@ e1000_diag_test(struct net_device *netdev,
data[2] = 0;
data[3] = 0;
}
+ msleep_interruptible(4 * 1000);
}
static void
@@ -1625,7 +1660,7 @@ e1000_phys_id(struct net_device *netdev, uint32_t data)
if(!data || data > (uint32_t)(MAX_SCHEDULE_TIMEOUT / HZ))
data = (uint32_t)(MAX_SCHEDULE_TIMEOUT / HZ);
- if(adapter->hw.mac_type < e1000_82573) {
+ if(adapter->hw.mac_type < e1000_82571) {
if(!adapter->blink_timer.function) {
init_timer(&adapter->blink_timer);
adapter->blink_timer.function = e1000_led_blink_callback;
@@ -1704,7 +1739,7 @@ e1000_get_strings(struct net_device *netdev, uint32_t stringset, uint8_t *data)
}
}
-struct ethtool_ops e1000_ethtool_ops = {
+static struct ethtool_ops e1000_ethtool_ops = {
.get_settings = e1000_get_settings,
.set_settings = e1000_set_settings,
.get_drvinfo = e1000_get_drvinfo,
@@ -1739,6 +1774,7 @@ struct ethtool_ops e1000_ethtool_ops = {
.phys_id = e1000_phys_id,
.get_stats_count = e1000_get_stats_count,
.get_ethtool_stats = e1000_get_ethtool_stats,
+ .get_perm_addr = ethtool_op_get_perm_addr,
};
void e1000_set_ethtool_ops(struct net_device *netdev)
diff --git a/drivers/net/e1000/e1000_hw.c b/drivers/net/e1000/e1000_hw.c
index 045f5426ab9a..a267c5235fc0 100644
--- a/drivers/net/e1000/e1000_hw.c
+++ b/drivers/net/e1000/e1000_hw.c
@@ -68,6 +68,38 @@ static int32_t e1000_polarity_reversal_workaround(struct e1000_hw *hw);
static int32_t e1000_set_phy_mode(struct e1000_hw *hw);
static int32_t e1000_host_if_read_cookie(struct e1000_hw *hw, uint8_t *buffer);
static uint8_t e1000_calculate_mng_checksum(char *buffer, uint32_t length);
+static uint8_t e1000_arc_subsystem_valid(struct e1000_hw *hw);
+static int32_t e1000_check_downshift(struct e1000_hw *hw);
+static int32_t e1000_check_polarity(struct e1000_hw *hw, uint16_t *polarity);
+static void e1000_clear_hw_cntrs(struct e1000_hw *hw);
+static void e1000_clear_vfta(struct e1000_hw *hw);
+static int32_t e1000_commit_shadow_ram(struct e1000_hw *hw);
+static int32_t e1000_config_dsp_after_link_change(struct e1000_hw *hw,
+ boolean_t link_up);
+static int32_t e1000_config_fc_after_link_up(struct e1000_hw *hw);
+static int32_t e1000_detect_gig_phy(struct e1000_hw *hw);
+static int32_t e1000_get_auto_rd_done(struct e1000_hw *hw);
+static int32_t e1000_get_cable_length(struct e1000_hw *hw,
+ uint16_t *min_length,
+ uint16_t *max_length);
+static int32_t e1000_get_hw_eeprom_semaphore(struct e1000_hw *hw);
+static int32_t e1000_get_phy_cfg_done(struct e1000_hw *hw);
+static int32_t e1000_id_led_init(struct e1000_hw * hw);
+static void e1000_init_rx_addrs(struct e1000_hw *hw);
+static boolean_t e1000_is_onboard_nvm_eeprom(struct e1000_hw *hw);
+static int32_t e1000_poll_eerd_eewr_done(struct e1000_hw *hw, int eerd);
+static void e1000_put_hw_eeprom_semaphore(struct e1000_hw *hw);
+static int32_t e1000_read_eeprom_eerd(struct e1000_hw *hw, uint16_t offset,
+ uint16_t words, uint16_t *data);
+static int32_t e1000_set_d0_lplu_state(struct e1000_hw *hw, boolean_t active);
+static int32_t e1000_set_d3_lplu_state(struct e1000_hw *hw, boolean_t active);
+static int32_t e1000_wait_autoneg(struct e1000_hw *hw);
+
+static void e1000_write_reg_io(struct e1000_hw *hw, uint32_t offset,
+ uint32_t value);
+
+#define E1000_WRITE_REG_IO(a, reg, val) \
+ e1000_write_reg_io((a), E1000_##reg, val)
/* IGP cable length table */
static const
@@ -83,14 +115,14 @@ uint16_t e1000_igp_cable_length_table[IGP01E1000_AGC_LENGTH_TABLE_SIZE] =
static const
uint16_t e1000_igp_2_cable_length_table[IGP02E1000_AGC_LENGTH_TABLE_SIZE] =
- { 8, 13, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41, 43,
- 22, 24, 27, 30, 32, 35, 37, 40, 42, 44, 47, 49, 51, 54, 56, 58,
- 32, 35, 38, 41, 44, 47, 50, 53, 55, 58, 61, 63, 66, 69, 71, 74,
- 43, 47, 51, 54, 58, 61, 64, 67, 71, 74, 77, 80, 82, 85, 88, 90,
- 57, 62, 66, 70, 74, 77, 81, 85, 88, 91, 94, 97, 100, 103, 106, 108,
- 73, 78, 82, 87, 91, 95, 98, 102, 105, 109, 112, 114, 117, 119, 122, 124,
- 91, 96, 101, 105, 109, 113, 116, 119, 122, 125, 127, 128, 128, 128, 128, 128,
- 108, 113, 117, 121, 124, 127, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128};
+ { 0, 0, 0, 0, 0, 0, 0, 0, 3, 5, 8, 11, 13, 16, 18, 21,
+ 0, 0, 0, 3, 6, 10, 13, 16, 19, 23, 26, 29, 32, 35, 38, 41,
+ 6, 10, 14, 18, 22, 26, 30, 33, 37, 41, 44, 48, 51, 54, 58, 61,
+ 21, 26, 31, 35, 40, 44, 49, 53, 57, 61, 65, 68, 72, 75, 79, 82,
+ 40, 45, 51, 56, 61, 66, 70, 75, 79, 83, 87, 91, 94, 98, 101, 104,
+ 60, 66, 72, 77, 82, 87, 92, 96, 100, 104, 108, 111, 114, 117, 119, 121,
+ 83, 89, 95, 100, 105, 109, 113, 116, 119, 122, 124,
+ 104, 109, 114, 118, 121, 124};
/******************************************************************************
@@ -286,7 +318,6 @@ e1000_set_mac_type(struct e1000_hw *hw)
case E1000_DEV_ID_82546GB_FIBER:
case E1000_DEV_ID_82546GB_SERDES:
case E1000_DEV_ID_82546GB_PCIE:
- case E1000_DEV_ID_82546GB_QUAD_COPPER:
hw->mac_type = e1000_82546_rev_3;
break;
case E1000_DEV_ID_82541EI:
@@ -305,8 +336,19 @@ e1000_set_mac_type(struct e1000_hw *hw)
case E1000_DEV_ID_82547GI:
hw->mac_type = e1000_82547_rev_2;
break;
+ case E1000_DEV_ID_82571EB_COPPER:
+ case E1000_DEV_ID_82571EB_FIBER:
+ case E1000_DEV_ID_82571EB_SERDES:
+ hw->mac_type = e1000_82571;
+ break;
+ case E1000_DEV_ID_82572EI_COPPER:
+ case E1000_DEV_ID_82572EI_FIBER:
+ case E1000_DEV_ID_82572EI_SERDES:
+ hw->mac_type = e1000_82572;
+ break;
case E1000_DEV_ID_82573E:
case E1000_DEV_ID_82573E_IAMT:
+ case E1000_DEV_ID_82573L:
hw->mac_type = e1000_82573;
break;
default:
@@ -315,6 +357,8 @@ e1000_set_mac_type(struct e1000_hw *hw)
}
switch(hw->mac_type) {
+ case e1000_82571:
+ case e1000_82572:
case e1000_82573:
hw->eeprom_semaphore_present = TRUE;
/* fall through */
@@ -351,6 +395,8 @@ e1000_set_media_type(struct e1000_hw *hw)
switch (hw->device_id) {
case E1000_DEV_ID_82545GM_SERDES:
case E1000_DEV_ID_82546GB_SERDES:
+ case E1000_DEV_ID_82571EB_SERDES:
+ case E1000_DEV_ID_82572EI_SERDES:
hw->media_type = e1000_media_type_internal_serdes;
break;
default:
@@ -523,6 +569,8 @@ e1000_reset_hw(struct e1000_hw *hw)
E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext);
E1000_WRITE_FLUSH(hw);
/* fall through */
+ case e1000_82571:
+ case e1000_82572:
ret_val = e1000_get_auto_rd_done(hw);
if(ret_val)
/* We don't want to continue accessing MAC registers. */
@@ -683,6 +731,9 @@ e1000_init_hw(struct e1000_hw *hw)
switch (hw->mac_type) {
default:
break;
+ case e1000_82571:
+ case e1000_82572:
+ ctrl |= (1 << 22);
case e1000_82573:
ctrl |= E1000_TXDCTL_COUNT_DESC;
break;
@@ -694,6 +745,26 @@ e1000_init_hw(struct e1000_hw *hw)
e1000_enable_tx_pkt_filtering(hw);
}
+ switch (hw->mac_type) {
+ default:
+ break;
+ case e1000_82571:
+ case e1000_82572:
+ ctrl = E1000_READ_REG(hw, TXDCTL1);
+ ctrl &= ~E1000_TXDCTL_WTHRESH;
+ ctrl |= E1000_TXDCTL_COUNT_DESC | E1000_TXDCTL_FULL_TX_DESC_WB;
+ ctrl |= (1 << 22);
+ E1000_WRITE_REG(hw, TXDCTL1, ctrl);
+ break;
+ }
+
+
+
+ if (hw->mac_type == e1000_82573) {
+ uint32_t gcr = E1000_READ_REG(hw, GCR);
+ gcr |= E1000_GCR_L1_ACT_WITHOUT_L0S_RX;
+ E1000_WRITE_REG(hw, GCR, gcr);
+ }
/* Clear all of the statistics registers (clear on read). It is
* important that we do this after we have tried to establish link
@@ -878,6 +949,14 @@ e1000_setup_fiber_serdes_link(struct e1000_hw *hw)
DEBUGFUNC("e1000_setup_fiber_serdes_link");
+ /* On 82571 and 82572 Fiber connections, SerDes loopback mode persists
+ * until explicitly turned off or a power cycle is performed. A read to
+ * the register does not indicate its status. Therefore, we ensure
+ * loopback mode is disabled during initialization.
+ */
+ if (hw->mac_type == e1000_82571 || hw->mac_type == e1000_82572)
+ E1000_WRITE_REG(hw, SCTL, E1000_DISABLE_SERDES_LOOPBACK);
+
/* On adapters with a MAC newer than 82544, SW Defineable pin 1 will be
* set when the optics detect a signal. On older adapters, it will be
* cleared when there is a signal. This applies to fiber media only.
@@ -1988,7 +2067,7 @@ e1000_force_mac_fc(struct e1000_hw *hw)
* based on the flow control negotiated by the PHY. In TBI mode, the TFCE
* and RFCE bits will be automaticaly set to the negotiated flow control mode.
*****************************************************************************/
-int32_t
+static int32_t
e1000_config_fc_after_link_up(struct e1000_hw *hw)
{
int32_t ret_val;
@@ -2490,7 +2569,7 @@ e1000_get_speed_and_duplex(struct e1000_hw *hw,
*
* hw - Struct containing variables accessed by shared code
******************************************************************************/
-int32_t
+static int32_t
e1000_wait_autoneg(struct e1000_hw *hw)
{
int32_t ret_val;
@@ -2943,6 +3022,8 @@ e1000_phy_reset(struct e1000_hw *hw)
switch (hw->mac_type) {
case e1000_82541_rev_2:
+ case e1000_82571:
+ case e1000_82572:
ret_val = e1000_phy_hw_reset(hw);
if(ret_val)
return ret_val;
@@ -2972,7 +3053,7 @@ e1000_phy_reset(struct e1000_hw *hw)
*
* hw - Struct containing variables accessed by shared code
******************************************************************************/
-int32_t
+static int32_t
e1000_detect_gig_phy(struct e1000_hw *hw)
{
int32_t phy_init_status, ret_val;
@@ -2981,6 +3062,16 @@ e1000_detect_gig_phy(struct e1000_hw *hw)
DEBUGFUNC("e1000_detect_gig_phy");
+ /* The 82571 firmware may still be configuring the PHY. In this
+ * case, we cannot access the PHY until the configuration is done. So
+ * we explicitly set the PHY values. */
+ if(hw->mac_type == e1000_82571 ||
+ hw->mac_type == e1000_82572) {
+ hw->phy_id = IGP01E1000_I_PHY_ID;
+ hw->phy_type = e1000_phy_igp_2;
+ return E1000_SUCCESS;
+ }
+
/* Read the PHY ID Registers to identify which PHY is onboard. */
ret_val = e1000_read_phy_reg(hw, PHY_ID1, &phy_id_high);
if(ret_val)
@@ -3062,7 +3153,7 @@ e1000_phy_reset_dsp(struct e1000_hw *hw)
* hw - Struct containing variables accessed by shared code
* phy_info - PHY information structure
******************************************************************************/
-int32_t
+static int32_t
e1000_phy_igp_get_info(struct e1000_hw *hw,
struct e1000_phy_info *phy_info)
{
@@ -3136,7 +3227,7 @@ e1000_phy_igp_get_info(struct e1000_hw *hw,
* hw - Struct containing variables accessed by shared code
* phy_info - PHY information structure
******************************************************************************/
-int32_t
+static int32_t
e1000_phy_m88_get_info(struct e1000_hw *hw,
struct e1000_phy_info *phy_info)
{
@@ -3334,6 +3425,21 @@ e1000_init_eeprom_params(struct e1000_hw *hw)
eeprom->use_eerd = FALSE;
eeprom->use_eewr = FALSE;
break;
+ case e1000_82571:
+ case e1000_82572:
+ eeprom->type = e1000_eeprom_spi;
+ eeprom->opcode_bits = 8;
+ eeprom->delay_usec = 1;
+ if (eecd & E1000_EECD_ADDR_BITS) {
+ eeprom->page_size = 32;
+ eeprom->address_bits = 16;
+ } else {
+ eeprom->page_size = 8;
+ eeprom->address_bits = 8;
+ }
+ eeprom->use_eerd = FALSE;
+ eeprom->use_eewr = FALSE;
+ break;
case e1000_82573:
eeprom->type = e1000_eeprom_spi;
eeprom->opcode_bits = 8;
@@ -3543,25 +3649,26 @@ e1000_acquire_eeprom(struct e1000_hw *hw)
eecd = E1000_READ_REG(hw, EECD);
if (hw->mac_type != e1000_82573) {
- /* Request EEPROM Access */
- if(hw->mac_type > e1000_82544) {
- eecd |= E1000_EECD_REQ;
- E1000_WRITE_REG(hw, EECD, eecd);
- eecd = E1000_READ_REG(hw, EECD);
- while((!(eecd & E1000_EECD_GNT)) &&
- (i < E1000_EEPROM_GRANT_ATTEMPTS)) {
- i++;
- udelay(5);
- eecd = E1000_READ_REG(hw, EECD);
- }
- if(!(eecd & E1000_EECD_GNT)) {
- eecd &= ~E1000_EECD_REQ;
+ /* Request EEPROM Access */
+ if(hw->mac_type > e1000_82544) {
+ eecd |= E1000_EECD_REQ;
E1000_WRITE_REG(hw, EECD, eecd);
- DEBUGOUT("Could not acquire EEPROM grant\n");
- return -E1000_ERR_EEPROM;
+ eecd = E1000_READ_REG(hw, EECD);
+ while((!(eecd & E1000_EECD_GNT)) &&
+ (i < E1000_EEPROM_GRANT_ATTEMPTS)) {
+ i++;
+ udelay(5);
+ eecd = E1000_READ_REG(hw, EECD);
+ }
+ if(!(eecd & E1000_EECD_GNT)) {
+ eecd &= ~E1000_EECD_REQ;
+ E1000_WRITE_REG(hw, EECD, eecd);
+ DEBUGOUT("Could not acquire EEPROM grant\n");
+ e1000_put_hw_eeprom_semaphore(hw);
+ return -E1000_ERR_EEPROM;
+ }
}
}
- }
/* Setup EEPROM for Read/Write */
@@ -3830,7 +3937,7 @@ e1000_read_eeprom(struct e1000_hw *hw,
* data - word read from the EEPROM
* words - number of words to read
*****************************************************************************/
-int32_t
+static int32_t
e1000_read_eeprom_eerd(struct e1000_hw *hw,
uint16_t offset,
uint16_t words,
@@ -3864,7 +3971,7 @@ e1000_read_eeprom_eerd(struct e1000_hw *hw,
* data - word read from the EEPROM
* words - number of words to read
*****************************************************************************/
-int32_t
+static int32_t
e1000_write_eeprom_eewr(struct e1000_hw *hw,
uint16_t offset,
uint16_t words,
@@ -3901,7 +4008,7 @@ e1000_write_eeprom_eewr(struct e1000_hw *hw,
*
* hw - Struct containing variables accessed by shared code
*****************************************************************************/
-int32_t
+static int32_t
e1000_poll_eerd_eewr_done(struct e1000_hw *hw, int eerd)
{
uint32_t attempts = 100000;
@@ -3929,7 +4036,7 @@ e1000_poll_eerd_eewr_done(struct e1000_hw *hw, int eerd)
*
* hw - Struct containing variables accessed by shared code
****************************************************************************/
-boolean_t
+static boolean_t
e1000_is_onboard_nvm_eeprom(struct e1000_hw *hw)
{
uint32_t eecd = 0;
@@ -4064,7 +4171,7 @@ e1000_write_eeprom(struct e1000_hw *hw,
return -E1000_ERR_EEPROM;
}
- /* 82573 reads only through eerd */
+ /* 82573 writes only through eewr */
if(eeprom->use_eewr == TRUE)
return e1000_write_eeprom_eewr(hw, offset, words, data);
@@ -4247,7 +4354,7 @@ e1000_write_eeprom_microwire(struct e1000_hw *hw,
* data - word read from the EEPROM
* words - number of words to read
*****************************************************************************/
-int32_t
+static int32_t
e1000_commit_shadow_ram(struct e1000_hw *hw)
{
uint32_t attempts = 100000;
@@ -4353,9 +4460,16 @@ e1000_read_mac_addr(struct e1000_hw * hw)
hw->perm_mac_addr[i] = (uint8_t) (eeprom_data & 0x00FF);
hw->perm_mac_addr[i+1] = (uint8_t) (eeprom_data >> 8);
}
- if(((hw->mac_type == e1000_82546) || (hw->mac_type == e1000_82546_rev_3)) &&
- (E1000_READ_REG(hw, STATUS) & E1000_STATUS_FUNC_1))
+ switch (hw->mac_type) {
+ default:
+ break;
+ case e1000_82546:
+ case e1000_82546_rev_3:
+ case e1000_82571:
+ if(E1000_READ_REG(hw, STATUS) & E1000_STATUS_FUNC_1)
hw->perm_mac_addr[5] ^= 0x01;
+ break;
+ }
for(i = 0; i < NODE_ADDRESS_SIZE; i++)
hw->mac_addr[i] = hw->perm_mac_addr[i];
@@ -4371,7 +4485,7 @@ e1000_read_mac_addr(struct e1000_hw * hw)
* of the receive addresss registers. Clears the multicast table. Assumes
* the receiver is in reset when the routine is called.
*****************************************************************************/
-void
+static void
e1000_init_rx_addrs(struct e1000_hw *hw)
{
uint32_t i;
@@ -4385,6 +4499,12 @@ e1000_init_rx_addrs(struct e1000_hw *hw)
e1000_rar_set(hw, hw->mac_addr, 0);
rar_num = E1000_RAR_ENTRIES;
+
+ /* Reserve a spot for the Locally Administered Address to work around
+ * an 82571 issue in which a reset on one port will reload the MAC on
+ * the other port. */
+ if ((hw->mac_type == e1000_82571) && (hw->laa_is_present == TRUE))
+ rar_num -= 1;
/* Zero out the other 15 receive addresses. */
DEBUGOUT("Clearing RAR[1-15]\n");
for(i = 1; i < rar_num; i++) {
@@ -4393,6 +4513,7 @@ e1000_init_rx_addrs(struct e1000_hw *hw)
}
}
+#if 0
/******************************************************************************
* Updates the MAC's list of multicast addresses.
*
@@ -4427,6 +4548,12 @@ e1000_mc_addr_list_update(struct e1000_hw *hw,
/* Clear RAR[1-15] */
DEBUGOUT(" Clearing RAR[1-15]\n");
num_rar_entry = E1000_RAR_ENTRIES;
+ /* Reserve a spot for the Locally Administered Address to work around
+ * an 82571 issue in which a reset on one port will reload the MAC on
+ * the other port. */
+ if ((hw->mac_type == e1000_82571) && (hw->laa_is_present == TRUE))
+ num_rar_entry -= 1;
+
for(i = rar_used_count; i < num_rar_entry; i++) {
E1000_WRITE_REG_ARRAY(hw, RA, (i << 1), 0);
E1000_WRITE_REG_ARRAY(hw, RA, ((i << 1) + 1), 0);
@@ -4470,6 +4597,7 @@ e1000_mc_addr_list_update(struct e1000_hw *hw,
}
DEBUGOUT("MC Update Complete\n");
}
+#endif /* 0 */
/******************************************************************************
* Hashes an address to determine its location in the multicast table
@@ -4611,7 +4739,7 @@ e1000_write_vfta(struct e1000_hw *hw,
*
* hw - Struct containing variables accessed by shared code
*****************************************************************************/
-void
+static void
e1000_clear_vfta(struct e1000_hw *hw)
{
uint32_t offset;
@@ -4641,7 +4769,7 @@ e1000_clear_vfta(struct e1000_hw *hw)
}
}
-int32_t
+static int32_t
e1000_id_led_init(struct e1000_hw * hw)
{
uint32_t ledctl;
@@ -4903,7 +5031,7 @@ e1000_led_off(struct e1000_hw *hw)
*
* hw - Struct containing variables accessed by shared code
*****************************************************************************/
-void
+static void
e1000_clear_hw_cntrs(struct e1000_hw *hw)
{
volatile uint32_t temp;
@@ -4984,7 +5112,6 @@ e1000_clear_hw_cntrs(struct e1000_hw *hw)
temp = E1000_READ_REG(hw, ICTXQEC);
temp = E1000_READ_REG(hw, ICTXQMTC);
temp = E1000_READ_REG(hw, ICRXDMTC);
-
}
/******************************************************************************
@@ -5151,6 +5278,8 @@ e1000_get_bus_info(struct e1000_hw *hw)
hw->bus_speed = e1000_bus_speed_unknown;
hw->bus_width = e1000_bus_width_unknown;
break;
+ case e1000_82571:
+ case e1000_82572:
case e1000_82573:
hw->bus_type = e1000_bus_type_pci_express;
hw->bus_speed = e1000_bus_speed_2500;
@@ -5188,6 +5317,8 @@ e1000_get_bus_info(struct e1000_hw *hw)
break;
}
}
+
+#if 0
/******************************************************************************
* Reads a value from one of the devices registers using port I/O (as opposed
* memory mapped I/O). Only 82544 and newer devices support port I/O.
@@ -5205,6 +5336,7 @@ e1000_read_reg_io(struct e1000_hw *hw,
e1000_io_write(hw, io_addr, offset);
return e1000_io_read(hw, io_data);
}
+#endif /* 0 */
/******************************************************************************
* Writes a value to one of the devices registers using port I/O (as opposed to
@@ -5214,7 +5346,7 @@ e1000_read_reg_io(struct e1000_hw *hw,
* offset - offset to write to
* value - value to write
*****************************************************************************/
-void
+static void
e1000_write_reg_io(struct e1000_hw *hw,
uint32_t offset,
uint32_t value)
@@ -5242,7 +5374,7 @@ e1000_write_reg_io(struct e1000_hw *hw,
* register to the minimum and maximum range.
* For IGP phy's, the function calculates the range by the AGC registers.
*****************************************************************************/
-int32_t
+static int32_t
e1000_get_cable_length(struct e1000_hw *hw,
uint16_t *min_length,
uint16_t *max_length)
@@ -5250,6 +5382,7 @@ e1000_get_cable_length(struct e1000_hw *hw,
int32_t ret_val;
uint16_t agc_value = 0;
uint16_t cur_agc, min_agc = IGP01E1000_AGC_LENGTH_TABLE_SIZE;
+ uint16_t max_agc = 0;
uint16_t i, phy_data;
uint16_t cable_length;
@@ -5338,6 +5471,40 @@ e1000_get_cable_length(struct e1000_hw *hw,
IGP01E1000_AGC_RANGE) : 0;
*max_length = e1000_igp_cable_length_table[agc_value] +
IGP01E1000_AGC_RANGE;
+ } else if (hw->phy_type == e1000_phy_igp_2) {
+ uint16_t agc_reg_array[IGP02E1000_PHY_CHANNEL_NUM] =
+ {IGP02E1000_PHY_AGC_A,
+ IGP02E1000_PHY_AGC_B,
+ IGP02E1000_PHY_AGC_C,
+ IGP02E1000_PHY_AGC_D};
+ /* Read the AGC registers for all channels */
+ for (i = 0; i < IGP02E1000_PHY_CHANNEL_NUM; i++) {
+ ret_val = e1000_read_phy_reg(hw, agc_reg_array[i], &phy_data);
+ if (ret_val)
+ return ret_val;
+
+ /* Getting bits 15:9, which represent the combination of course and
+ * fine gain values. The result is a number that can be put into
+ * the lookup table to obtain the approximate cable length. */
+ cur_agc = (phy_data >> IGP02E1000_AGC_LENGTH_SHIFT) &
+ IGP02E1000_AGC_LENGTH_MASK;
+
+ /* Remove min & max AGC values from calculation. */
+ if (e1000_igp_2_cable_length_table[min_agc] > e1000_igp_2_cable_length_table[cur_agc])
+ min_agc = cur_agc;
+ if (e1000_igp_2_cable_length_table[max_agc] < e1000_igp_2_cable_length_table[cur_agc])
+ max_agc = cur_agc;
+
+ agc_value += e1000_igp_2_cable_length_table[cur_agc];
+ }
+
+ agc_value -= (e1000_igp_2_cable_length_table[min_agc] + e1000_igp_2_cable_length_table[max_agc]);
+ agc_value /= (IGP02E1000_PHY_CHANNEL_NUM - 2);
+
+ /* Calculate cable length with the error range of +/- 10 meters. */
+ *min_length = ((agc_value - IGP02E1000_AGC_RANGE) > 0) ?
+ (agc_value - IGP02E1000_AGC_RANGE) : 0;
+ *max_length = agc_value + IGP02E1000_AGC_RANGE;
}
return E1000_SUCCESS;
@@ -5359,7 +5526,7 @@ e1000_get_cable_length(struct e1000_hw *hw,
* return 0. If the link speed is 1000 Mbps the polarity status is in the
* IGP01E1000_PHY_PCS_INIT_REG.
*****************************************************************************/
-int32_t
+static int32_t
e1000_check_polarity(struct e1000_hw *hw,
uint16_t *polarity)
{
@@ -5421,7 +5588,7 @@ e1000_check_polarity(struct e1000_hw *hw,
* Link Health register. In IGP this bit is latched high, so the driver must
* read it immediately after link is established.
*****************************************************************************/
-int32_t
+static int32_t
e1000_check_downshift(struct e1000_hw *hw)
{
int32_t ret_val;
@@ -5462,7 +5629,7 @@ e1000_check_downshift(struct e1000_hw *hw)
*
****************************************************************************/
-int32_t
+static int32_t
e1000_config_dsp_after_link_change(struct e1000_hw *hw,
boolean_t link_up)
{
@@ -5693,7 +5860,7 @@ e1000_set_phy_mode(struct e1000_hw *hw)
*
****************************************************************************/
-int32_t
+static int32_t
e1000_set_d3_lplu_state(struct e1000_hw *hw,
boolean_t active)
{
@@ -5806,7 +5973,7 @@ e1000_set_d3_lplu_state(struct e1000_hw *hw,
*
****************************************************************************/
-int32_t
+static int32_t
e1000_set_d0_lplu_state(struct e1000_hw *hw,
boolean_t active)
{
@@ -5973,7 +6140,7 @@ e1000_host_if_read_cookie(struct e1000_hw * hw, uint8_t *buffer)
* timeout
* - E1000_SUCCESS for success.
****************************************************************************/
-int32_t
+static int32_t
e1000_mng_enable_host_if(struct e1000_hw * hw)
{
uint32_t hicr;
@@ -6007,7 +6174,7 @@ e1000_mng_enable_host_if(struct e1000_hw * hw)
*
* returns - E1000_SUCCESS for success.
****************************************************************************/
-int32_t
+static int32_t
e1000_mng_host_if_write(struct e1000_hw * hw, uint8_t *buffer,
uint16_t length, uint16_t offset, uint8_t *sum)
{
@@ -6075,7 +6242,7 @@ e1000_mng_host_if_write(struct e1000_hw * hw, uint8_t *buffer,
*
* returns - E1000_SUCCESS for success.
****************************************************************************/
-int32_t
+static int32_t
e1000_mng_write_cmd_header(struct e1000_hw * hw,
struct e1000_host_mng_command_header * hdr)
{
@@ -6113,7 +6280,7 @@ e1000_mng_write_cmd_header(struct e1000_hw * hw,
*
* returns - E1000_SUCCESS for success.
****************************************************************************/
-int32_t
+static int32_t
e1000_mng_write_commit(
struct e1000_hw * hw)
{
@@ -6366,7 +6533,7 @@ e1000_polarity_reversal_workaround(struct e1000_hw *hw)
* returns: - none.
*
***************************************************************************/
-void
+static void
e1000_set_pci_express_master_disable(struct e1000_hw *hw)
{
uint32_t ctrl;
@@ -6381,6 +6548,7 @@ e1000_set_pci_express_master_disable(struct e1000_hw *hw)
E1000_WRITE_REG(hw, CTRL, ctrl);
}
+#if 0
/***************************************************************************
*
* Enables PCI-Express master access.
@@ -6404,6 +6572,7 @@ e1000_enable_pciex_master(struct e1000_hw *hw)
ctrl &= ~E1000_CTRL_GIO_MASTER_DISABLE;
E1000_WRITE_REG(hw, CTRL, ctrl);
}
+#endif /* 0 */
/*******************************************************************************
*
@@ -6454,7 +6623,7 @@ e1000_disable_pciex_master(struct e1000_hw *hw)
* E1000_SUCCESS at any other case.
*
******************************************************************************/
-int32_t
+static int32_t
e1000_get_auto_rd_done(struct e1000_hw *hw)
{
int32_t timeout = AUTO_READ_DONE_TIMEOUT;
@@ -6465,6 +6634,8 @@ e1000_get_auto_rd_done(struct e1000_hw *hw)
default:
msec_delay(5);
break;
+ case e1000_82571:
+ case e1000_82572:
case e1000_82573:
while(timeout) {
if (E1000_READ_REG(hw, EECD) & E1000_EECD_AUTO_RD) break;
@@ -6491,13 +6662,34 @@ e1000_get_auto_rd_done(struct e1000_hw *hw)
* E1000_SUCCESS at any other case.
*
***************************************************************************/
-int32_t
+static int32_t
e1000_get_phy_cfg_done(struct e1000_hw *hw)
{
+ int32_t timeout = PHY_CFG_TIMEOUT;
+ uint32_t cfg_mask = E1000_EEPROM_CFG_DONE;
+
DEBUGFUNC("e1000_get_phy_cfg_done");
- /* Simply wait for 10ms */
- msec_delay(10);
+ switch (hw->mac_type) {
+ default:
+ msec_delay(10);
+ break;
+ case e1000_82571:
+ case e1000_82572:
+ while (timeout) {
+ if (E1000_READ_REG(hw, EEMNGCTL) & cfg_mask)
+ break;
+ else
+ msec_delay(1);
+ timeout--;
+ }
+
+ if (!timeout) {
+ DEBUGOUT("MNG configuration cycle has not completed.\n");
+ return -E1000_ERR_RESET;
+ }
+ break;
+ }
return E1000_SUCCESS;
}
@@ -6513,7 +6705,7 @@ e1000_get_phy_cfg_done(struct e1000_hw *hw)
* E1000_SUCCESS at any other case.
*
***************************************************************************/
-int32_t
+static int32_t
e1000_get_hw_eeprom_semaphore(struct e1000_hw *hw)
{
int32_t timeout;
@@ -6558,7 +6750,7 @@ e1000_get_hw_eeprom_semaphore(struct e1000_hw *hw)
* returns: - None.
*
***************************************************************************/
-void
+static void
e1000_put_hw_eeprom_semaphore(struct e1000_hw *hw)
{
uint32_t swsm;
@@ -6569,8 +6761,7 @@ e1000_put_hw_eeprom_semaphore(struct e1000_hw *hw)
return;
swsm = E1000_READ_REG(hw, SWSM);
- /* Release both semaphores. */
- swsm &= ~(E1000_SWSM_SMBI | E1000_SWSM_SWESMBI);
+ swsm &= ~(E1000_SWSM_SWESMBI);
E1000_WRITE_REG(hw, SWSM, swsm);
}
@@ -6595,7 +6786,7 @@ e1000_check_phy_reset_block(struct e1000_hw *hw)
E1000_BLK_PHY_RESET : E1000_SUCCESS;
}
-uint8_t
+static uint8_t
e1000_arc_subsystem_valid(struct e1000_hw *hw)
{
uint32_t fwsm;
@@ -6606,6 +6797,8 @@ e1000_arc_subsystem_valid(struct e1000_hw *hw)
* if this is the case. We read FWSM to determine the manageability mode.
*/
switch (hw->mac_type) {
+ case e1000_82571:
+ case e1000_82572:
case e1000_82573:
fwsm = E1000_READ_REG(hw, FWSM);
if((fwsm & E1000_FWSM_MODE_MASK) != 0)
diff --git a/drivers/net/e1000/e1000_hw.h b/drivers/net/e1000/e1000_hw.h
index 51c2b3a18b6f..76ce12809a11 100644
--- a/drivers/net/e1000/e1000_hw.h
+++ b/drivers/net/e1000/e1000_hw.h
@@ -57,6 +57,8 @@ typedef enum {
e1000_82541_rev_2,
e1000_82547,
e1000_82547_rev_2,
+ e1000_82571,
+ e1000_82572,
e1000_82573,
e1000_num_macs
} e1000_mac_type;
@@ -282,7 +284,6 @@ typedef enum {
/* Initialization */
int32_t e1000_reset_hw(struct e1000_hw *hw);
int32_t e1000_init_hw(struct e1000_hw *hw);
-int32_t e1000_id_led_init(struct e1000_hw * hw);
int32_t e1000_set_mac_type(struct e1000_hw *hw);
void e1000_set_media_type(struct e1000_hw *hw);
@@ -290,10 +291,8 @@ void e1000_set_media_type(struct e1000_hw *hw);
int32_t e1000_setup_link(struct e1000_hw *hw);
int32_t e1000_phy_setup_autoneg(struct e1000_hw *hw);
void e1000_config_collision_dist(struct e1000_hw *hw);
-int32_t e1000_config_fc_after_link_up(struct e1000_hw *hw);
int32_t e1000_check_for_link(struct e1000_hw *hw);
int32_t e1000_get_speed_and_duplex(struct e1000_hw *hw, uint16_t * speed, uint16_t * duplex);
-int32_t e1000_wait_autoneg(struct e1000_hw *hw);
int32_t e1000_force_mac_fc(struct e1000_hw *hw);
/* PHY */
@@ -301,21 +300,11 @@ int32_t e1000_read_phy_reg(struct e1000_hw *hw, uint32_t reg_addr, uint16_t *phy
int32_t e1000_write_phy_reg(struct e1000_hw *hw, uint32_t reg_addr, uint16_t data);
int32_t e1000_phy_hw_reset(struct e1000_hw *hw);
int32_t e1000_phy_reset(struct e1000_hw *hw);
-int32_t e1000_detect_gig_phy(struct e1000_hw *hw);
int32_t e1000_phy_get_info(struct e1000_hw *hw, struct e1000_phy_info *phy_info);
-int32_t e1000_phy_m88_get_info(struct e1000_hw *hw, struct e1000_phy_info *phy_info);
-int32_t e1000_phy_igp_get_info(struct e1000_hw *hw, struct e1000_phy_info *phy_info);
-int32_t e1000_get_cable_length(struct e1000_hw *hw, uint16_t *min_length, uint16_t *max_length);
-int32_t e1000_check_polarity(struct e1000_hw *hw, uint16_t *polarity);
-int32_t e1000_check_downshift(struct e1000_hw *hw);
int32_t e1000_validate_mdi_setting(struct e1000_hw *hw);
/* EEPROM Functions */
int32_t e1000_init_eeprom_params(struct e1000_hw *hw);
-boolean_t e1000_is_onboard_nvm_eeprom(struct e1000_hw *hw);
-int32_t e1000_read_eeprom_eerd(struct e1000_hw *hw, uint16_t offset, uint16_t words, uint16_t *data);
-int32_t e1000_write_eeprom_eewr(struct e1000_hw *hw, uint16_t offset, uint16_t words, uint16_t *data);
-int32_t e1000_poll_eerd_eewr_done(struct e1000_hw *hw, int eerd);
/* MNG HOST IF functions */
uint32_t e1000_enable_mng_pass_thru(struct e1000_hw *hw);
@@ -375,13 +364,6 @@ int32_t e1000_mng_write_dhcp_info(struct e1000_hw *hw, uint8_t *buffer,
uint16_t length);
boolean_t e1000_check_mng_mode(struct e1000_hw *hw);
boolean_t e1000_enable_tx_pkt_filtering(struct e1000_hw *hw);
-int32_t e1000_mng_enable_host_if(struct e1000_hw *hw);
-int32_t e1000_mng_host_if_write(struct e1000_hw *hw, uint8_t *buffer,
- uint16_t length, uint16_t offset, uint8_t *sum);
-int32_t e1000_mng_write_cmd_header(struct e1000_hw* hw,
- struct e1000_host_mng_command_header* hdr);
-
-int32_t e1000_mng_write_commit(struct e1000_hw *hw);
int32_t e1000_read_eeprom(struct e1000_hw *hw, uint16_t reg, uint16_t words, uint16_t *data);
int32_t e1000_validate_eeprom_checksum(struct e1000_hw *hw);
@@ -393,13 +375,10 @@ int32_t e1000_swfw_sync_acquire(struct e1000_hw *hw, uint16_t mask);
void e1000_swfw_sync_release(struct e1000_hw *hw, uint16_t mask);
/* Filters (multicast, vlan, receive) */
-void e1000_init_rx_addrs(struct e1000_hw *hw);
-void e1000_mc_addr_list_update(struct e1000_hw *hw, uint8_t * mc_addr_list, uint32_t mc_addr_count, uint32_t pad, uint32_t rar_used_count);
uint32_t e1000_hash_mc_addr(struct e1000_hw *hw, uint8_t * mc_addr);
void e1000_mta_set(struct e1000_hw *hw, uint32_t hash_value);
void e1000_rar_set(struct e1000_hw *hw, uint8_t * mc_addr, uint32_t rar_index);
void e1000_write_vfta(struct e1000_hw *hw, uint32_t offset, uint32_t value);
-void e1000_clear_vfta(struct e1000_hw *hw);
/* LED functions */
int32_t e1000_setup_led(struct e1000_hw *hw);
@@ -410,7 +389,6 @@ int32_t e1000_led_off(struct e1000_hw *hw);
/* Adaptive IFS Functions */
/* Everything else */
-void e1000_clear_hw_cntrs(struct e1000_hw *hw);
void e1000_reset_adaptive(struct e1000_hw *hw);
void e1000_update_adaptive(struct e1000_hw *hw);
void e1000_tbi_adjust_stats(struct e1000_hw *hw, struct e1000_hw_stats *stats, uint32_t frame_len, uint8_t * mac_addr);
@@ -421,29 +399,11 @@ void e1000_read_pci_cfg(struct e1000_hw *hw, uint32_t reg, uint16_t * value);
void e1000_write_pci_cfg(struct e1000_hw *hw, uint32_t reg, uint16_t * value);
/* Port I/O is only supported on 82544 and newer */
uint32_t e1000_io_read(struct e1000_hw *hw, unsigned long port);
-uint32_t e1000_read_reg_io(struct e1000_hw *hw, uint32_t offset);
void e1000_io_write(struct e1000_hw *hw, unsigned long port, uint32_t value);
-void e1000_write_reg_io(struct e1000_hw *hw, uint32_t offset, uint32_t value);
-int32_t e1000_config_dsp_after_link_change(struct e1000_hw *hw, boolean_t link_up);
-int32_t e1000_set_d3_lplu_state(struct e1000_hw *hw, boolean_t active);
-int32_t e1000_set_d0_lplu_state(struct e1000_hw *hw, boolean_t active);
-void e1000_set_pci_express_master_disable(struct e1000_hw *hw);
-void e1000_enable_pciex_master(struct e1000_hw *hw);
int32_t e1000_disable_pciex_master(struct e1000_hw *hw);
-int32_t e1000_get_auto_rd_done(struct e1000_hw *hw);
-int32_t e1000_get_phy_cfg_done(struct e1000_hw *hw);
int32_t e1000_get_software_semaphore(struct e1000_hw *hw);
void e1000_release_software_semaphore(struct e1000_hw *hw);
int32_t e1000_check_phy_reset_block(struct e1000_hw *hw);
-int32_t e1000_get_hw_eeprom_semaphore(struct e1000_hw *hw);
-void e1000_put_hw_eeprom_semaphore(struct e1000_hw *hw);
-int32_t e1000_commit_shadow_ram(struct e1000_hw *hw);
-uint8_t e1000_arc_subsystem_valid(struct e1000_hw *hw);
-
-#define E1000_READ_REG_IO(a, reg) \
- e1000_read_reg_io((a), E1000_##reg)
-#define E1000_WRITE_REG_IO(a, reg, val) \
- e1000_write_reg_io((a), E1000_##reg, val)
/* PCI Device IDs */
#define E1000_DEV_ID_82542 0x1000
@@ -478,10 +438,16 @@ uint8_t e1000_arc_subsystem_valid(struct e1000_hw *hw);
#define E1000_DEV_ID_82546GB_SERDES 0x107B
#define E1000_DEV_ID_82546GB_PCIE 0x108A
#define E1000_DEV_ID_82547EI 0x1019
+#define E1000_DEV_ID_82571EB_COPPER 0x105E
+#define E1000_DEV_ID_82571EB_FIBER 0x105F
+#define E1000_DEV_ID_82571EB_SERDES 0x1060
+#define E1000_DEV_ID_82572EI_COPPER 0x107D
+#define E1000_DEV_ID_82572EI_FIBER 0x107E
+#define E1000_DEV_ID_82572EI_SERDES 0x107F
#define E1000_DEV_ID_82573E 0x108B
#define E1000_DEV_ID_82573E_IAMT 0x108C
+#define E1000_DEV_ID_82573L 0x109A
-#define E1000_DEV_ID_82546GB_QUAD_COPPER 0x1099
#define NODE_ADDRESS_SIZE 6
#define ETH_LENGTH_OF_ADDRESS 6
@@ -833,6 +799,8 @@ struct e1000_ffvt_entry {
#define E1000_FFMT_SIZE E1000_FLEXIBLE_FILTER_SIZE_MAX
#define E1000_FFVT_SIZE E1000_FLEXIBLE_FILTER_SIZE_MAX
+#define E1000_DISABLE_SERDES_LOOPBACK 0x0400
+
/* Register Set. (82543, 82544)
*
* Registers are defined to be 32 bits and should be accessed as 32 bit values.
@@ -853,6 +821,7 @@ struct e1000_ffvt_entry {
#define E1000_CTRL_EXT 0x00018 /* Extended Device Control - RW */
#define E1000_FLA 0x0001C /* Flash Access - RW */
#define E1000_MDIC 0x00020 /* MDI Control - RW */
+#define E1000_SCTL 0x00024 /* SerDes Control - RW */
#define E1000_FCAL 0x00028 /* Flow Control Address Low - RW */
#define E1000_FCAH 0x0002C /* Flow Control Address High -RW */
#define E1000_FCT 0x00030 /* Flow Control Type - RW */
@@ -864,6 +833,12 @@ struct e1000_ffvt_entry {
#define E1000_IMC 0x000D8 /* Interrupt Mask Clear - WO */
#define E1000_IAM 0x000E0 /* Interrupt Acknowledge Auto Mask */
#define E1000_RCTL 0x00100 /* RX Control - RW */
+#define E1000_RDTR1 0x02820 /* RX Delay Timer (1) - RW */
+#define E1000_RDBAL1 0x02900 /* RX Descriptor Base Address Low (1) - RW */
+#define E1000_RDBAH1 0x02904 /* RX Descriptor Base Address High (1) - RW */
+#define E1000_RDLEN1 0x02908 /* RX Descriptor Length (1) - RW */
+#define E1000_RDH1 0x02910 /* RX Descriptor Head (1) - RW */
+#define E1000_RDT1 0x02918 /* RX Descriptor Tail (1) - RW */
#define E1000_FCTTV 0x00170 /* Flow Control Transmit Timer Value - RW */
#define E1000_TXCW 0x00178 /* TX Configuration Word - RW */
#define E1000_RXCW 0x00180 /* RX Configuration Word - RO */
@@ -895,6 +870,12 @@ struct e1000_ffvt_entry {
#define E1000_RDH 0x02810 /* RX Descriptor Head - RW */
#define E1000_RDT 0x02818 /* RX Descriptor Tail - RW */
#define E1000_RDTR 0x02820 /* RX Delay Timer - RW */
+#define E1000_RDBAL0 E1000_RDBAL /* RX Desc Base Address Low (0) - RW */
+#define E1000_RDBAH0 E1000_RDBAH /* RX Desc Base Address High (0) - RW */
+#define E1000_RDLEN0 E1000_RDLEN /* RX Desc Length (0) - RW */
+#define E1000_RDH0 E1000_RDH /* RX Desc Head (0) - RW */
+#define E1000_RDT0 E1000_RDT /* RX Desc Tail (0) - RW */
+#define E1000_RDTR0 E1000_RDTR /* RX Delay Timer (0) - RW */
#define E1000_RXDCTL 0x02828 /* RX Descriptor Control - RW */
#define E1000_RADV 0x0282C /* RX Interrupt Absolute Delay Timer - RW */
#define E1000_RSRPD 0x02C00 /* RX Small Packet Detect - RW */
@@ -980,15 +961,15 @@ struct e1000_ffvt_entry {
#define E1000_BPTC 0x040F4 /* Broadcast Packets TX Count - R/clr */
#define E1000_TSCTC 0x040F8 /* TCP Segmentation Context TX - R/clr */
#define E1000_TSCTFC 0x040FC /* TCP Segmentation Context TX Fail - R/clr */
-#define E1000_IAC 0x4100 /* Interrupt Assertion Count */
-#define E1000_ICRXPTC 0x4104 /* Interrupt Cause Rx Packet Timer Expire Count */
-#define E1000_ICRXATC 0x4108 /* Interrupt Cause Rx Absolute Timer Expire Count */
-#define E1000_ICTXPTC 0x410C /* Interrupt Cause Tx Packet Timer Expire Count */
-#define E1000_ICTXATC 0x4110 /* Interrupt Cause Tx Absolute Timer Expire Count */
-#define E1000_ICTXQEC 0x4118 /* Interrupt Cause Tx Queue Empty Count */
-#define E1000_ICTXQMTC 0x411C /* Interrupt Cause Tx Queue Minimum Threshold Count */
-#define E1000_ICRXDMTC 0x4120 /* Interrupt Cause Rx Descriptor Minimum Threshold Count */
-#define E1000_ICRXOC 0x4124 /* Interrupt Cause Receiver Overrun Count */
+#define E1000_IAC 0x04100 /* Interrupt Assertion Count */
+#define E1000_ICRXPTC 0x04104 /* Interrupt Cause Rx Packet Timer Expire Count */
+#define E1000_ICRXATC 0x04108 /* Interrupt Cause Rx Absolute Timer Expire Count */
+#define E1000_ICTXPTC 0x0410C /* Interrupt Cause Tx Packet Timer Expire Count */
+#define E1000_ICTXATC 0x04110 /* Interrupt Cause Tx Absolute Timer Expire Count */
+#define E1000_ICTXQEC 0x04118 /* Interrupt Cause Tx Queue Empty Count */
+#define E1000_ICTXQMTC 0x0411C /* Interrupt Cause Tx Queue Minimum Threshold Count */
+#define E1000_ICRXDMTC 0x04120 /* Interrupt Cause Rx Descriptor Minimum Threshold Count */
+#define E1000_ICRXOC 0x04124 /* Interrupt Cause Receiver Overrun Count */
#define E1000_RXCSUM 0x05000 /* RX Checksum Control - RW */
#define E1000_RFCTL 0x05008 /* Receive Filter Control*/
#define E1000_MTA 0x05200 /* Multicast Table Array - RW Array */
@@ -1018,6 +999,14 @@ struct e1000_ffvt_entry {
#define E1000_FWSM 0x05B54 /* FW Semaphore */
#define E1000_FFLT_DBG 0x05F04 /* Debug Register */
#define E1000_HICR 0x08F00 /* Host Inteface Control */
+
+/* RSS registers */
+#define E1000_CPUVEC 0x02C10 /* CPU Vector Register - RW */
+#define E1000_MRQC 0x05818 /* Multiple Receive Control - RW */
+#define E1000_RETA 0x05C00 /* Redirection Table - RW Array */
+#define E1000_RSSRK 0x05C80 /* RSS Random Key - RW Array */
+#define E1000_RSSIM 0x05864 /* RSS Interrupt Mask */
+#define E1000_RSSIR 0x05868 /* RSS Interrupt Request */
/* Register Set (82542)
*
* Some of the 82542 registers are located at different offsets than they are
@@ -1032,6 +1021,7 @@ struct e1000_ffvt_entry {
#define E1000_82542_CTRL_EXT E1000_CTRL_EXT
#define E1000_82542_FLA E1000_FLA
#define E1000_82542_MDIC E1000_MDIC
+#define E1000_82542_SCTL E1000_SCTL
#define E1000_82542_FCAL E1000_FCAL
#define E1000_82542_FCAH E1000_FCAH
#define E1000_82542_FCT E1000_FCT
@@ -1049,6 +1039,18 @@ struct e1000_ffvt_entry {
#define E1000_82542_RDLEN 0x00118
#define E1000_82542_RDH 0x00120
#define E1000_82542_RDT 0x00128
+#define E1000_82542_RDTR0 E1000_82542_RDTR
+#define E1000_82542_RDBAL0 E1000_82542_RDBAL
+#define E1000_82542_RDBAH0 E1000_82542_RDBAH
+#define E1000_82542_RDLEN0 E1000_82542_RDLEN
+#define E1000_82542_RDH0 E1000_82542_RDH
+#define E1000_82542_RDT0 E1000_82542_RDT
+#define E1000_82542_RDTR1 0x00130
+#define E1000_82542_RDBAL1 0x00138
+#define E1000_82542_RDBAH1 0x0013C
+#define E1000_82542_RDLEN1 0x00140
+#define E1000_82542_RDH1 0x00148
+#define E1000_82542_RDT1 0x00150
#define E1000_82542_FCRTH 0x00160
#define E1000_82542_FCRTL 0x00168
#define E1000_82542_FCTTV E1000_FCTTV
@@ -1197,6 +1199,13 @@ struct e1000_ffvt_entry {
#define E1000_82542_ICRXOC E1000_ICRXOC
#define E1000_82542_HICR E1000_HICR
+#define E1000_82542_CPUVEC E1000_CPUVEC
+#define E1000_82542_MRQC E1000_MRQC
+#define E1000_82542_RETA E1000_RETA
+#define E1000_82542_RSSRK E1000_RSSRK
+#define E1000_82542_RSSIM E1000_RSSIM
+#define E1000_82542_RSSIR E1000_RSSIR
+
/* Statistics counters collected by the MAC */
struct e1000_hw_stats {
uint64_t crcerrs;
@@ -1336,6 +1345,7 @@ struct e1000_hw {
boolean_t serdes_link_down;
boolean_t tbi_compatibility_en;
boolean_t tbi_compatibility_on;
+ boolean_t laa_is_present;
boolean_t phy_reset_disable;
boolean_t fc_send_xon;
boolean_t fc_strict_ieee;
@@ -1374,6 +1384,7 @@ struct e1000_hw {
#define E1000_CTRL_BEM32 0x00000400 /* Big Endian 32 mode */
#define E1000_CTRL_FRCSPD 0x00000800 /* Force Speed */
#define E1000_CTRL_FRCDPX 0x00001000 /* Force Duplex */
+#define E1000_CTRL_D_UD_EN 0x00002000 /* Dock/Undock enable */
#define E1000_CTRL_D_UD_POLARITY 0x00004000 /* Defined polarity of Dock/Undock indication in SDP[0] */
#define E1000_CTRL_SWDPIN0 0x00040000 /* SWDPIN 0 value */
#define E1000_CTRL_SWDPIN1 0x00080000 /* SWDPIN 1 value */
@@ -1491,6 +1502,8 @@ struct e1000_hw {
#define E1000_CTRL_EXT_WR_WMARK_320 0x01000000
#define E1000_CTRL_EXT_WR_WMARK_384 0x02000000
#define E1000_CTRL_EXT_WR_WMARK_448 0x03000000
+#define E1000_CTRL_EXT_CANC 0x04000000 /* Interrupt delay cancellation */
+#define E1000_CTRL_EXT_DRV_LOAD 0x10000000 /* Driver loaded bit for FW */
#define E1000_CTRL_EXT_IAME 0x08000000 /* Interrupt acknowledge Auto-mask */
#define E1000_CTRL_EXT_INT_TIMER_CLR 0x20000000 /* Clear Interrupt timers after IMS clear */
@@ -1524,6 +1537,7 @@ struct e1000_hw {
#define E1000_LEDCTL_LED2_BLINK 0x00800000
#define E1000_LEDCTL_LED3_MODE_MASK 0x0F000000
#define E1000_LEDCTL_LED3_MODE_SHIFT 24
+#define E1000_LEDCTL_LED3_BLINK_RATE 0x20000000
#define E1000_LEDCTL_LED3_IVRT 0x40000000
#define E1000_LEDCTL_LED3_BLINK 0x80000000
@@ -1784,6 +1798,16 @@ struct e1000_hw {
#define E1000_RXCSUM_IPPCSE 0x00001000 /* IP payload checksum enable */
#define E1000_RXCSUM_PCSD 0x00002000 /* packet checksum disabled */
+/* Multiple Receive Queue Control */
+#define E1000_MRQC_ENABLE_MASK 0x00000003
+#define E1000_MRQC_ENABLE_RSS_2Q 0x00000001
+#define E1000_MRQC_ENABLE_RSS_INT 0x00000004
+#define E1000_MRQC_RSS_FIELD_MASK 0xFFFF0000
+#define E1000_MRQC_RSS_FIELD_IPV4_TCP 0x00010000
+#define E1000_MRQC_RSS_FIELD_IPV4 0x00020000
+#define E1000_MRQC_RSS_FIELD_IPV6_TCP 0x00040000
+#define E1000_MRQC_RSS_FIELD_IPV6_EX 0x00080000
+#define E1000_MRQC_RSS_FIELD_IPV6 0x00100000
/* Definitions for power management and wakeup registers */
/* Wake Up Control */
@@ -1928,6 +1952,7 @@ struct e1000_host_command_info {
#define E1000_MDALIGN 4096
#define E1000_GCR_BEM32 0x00400000
+#define E1000_GCR_L1_ACT_WITHOUT_L0S_RX 0x08000000
/* Function Active and Power State to MNG */
#define E1000_FACTPS_FUNC0_POWER_STATE_MASK 0x00000003
#define E1000_FACTPS_LAN0_VALID 0x00000004
@@ -1980,6 +2005,7 @@ struct e1000_host_command_info {
/* EEPROM Word Offsets */
#define EEPROM_COMPAT 0x0003
#define EEPROM_ID_LED_SETTINGS 0x0004
+#define EEPROM_VERSION 0x0005
#define EEPROM_SERDES_AMPLITUDE 0x0006 /* For SERDES output amplitude adjustment. */
#define EEPROM_PHY_CLASS_WORD 0x0007
#define EEPROM_INIT_CONTROL1_REG 0x000A
@@ -1990,6 +2016,8 @@ struct e1000_host_command_info {
#define EEPROM_FLASH_VERSION 0x0032
#define EEPROM_CHECKSUM_REG 0x003F
+#define E1000_EEPROM_CFG_DONE 0x00040000 /* MNG config cycle done */
+
/* Word definitions for ID LED Settings */
#define ID_LED_RESERVED_0000 0x0000
#define ID_LED_RESERVED_FFFF 0xFFFF
@@ -2108,6 +2136,8 @@ struct e1000_host_command_info {
#define E1000_PBA_22K 0x0016
#define E1000_PBA_24K 0x0018
#define E1000_PBA_30K 0x001E
+#define E1000_PBA_32K 0x0020
+#define E1000_PBA_38K 0x0026
#define E1000_PBA_40K 0x0028
#define E1000_PBA_48K 0x0030 /* 48KB, default RX allocation */
@@ -2592,11 +2622,11 @@ struct e1000_host_command_info {
/* 7 bits (3 Coarse + 4 Fine) --> 128 optional values */
#define IGP01E1000_AGC_LENGTH_TABLE_SIZE 128
-#define IGP02E1000_AGC_LENGTH_TABLE_SIZE 128
+#define IGP02E1000_AGC_LENGTH_TABLE_SIZE 113
/* The precision error of the cable length is +/- 10 meters */
#define IGP01E1000_AGC_RANGE 10
-#define IGP02E1000_AGC_RANGE 10
+#define IGP02E1000_AGC_RANGE 15
/* IGP01E1000 PCS Initialization register */
/* bits 3:6 in the PCS registers stores the channels polarity */
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index ee687c902a20..8b207f0e139e 100644
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -37,15 +37,15 @@
*/
char e1000_driver_name[] = "e1000";
-char e1000_driver_string[] = "Intel(R) PRO/1000 Network Driver";
+static char e1000_driver_string[] = "Intel(R) PRO/1000 Network Driver";
#ifndef CONFIG_E1000_NAPI
#define DRIVERNAPI
#else
#define DRIVERNAPI "-NAPI"
#endif
-#define DRV_VERSION "6.0.60-k2"DRIVERNAPI
+#define DRV_VERSION "6.1.16-k2"DRIVERNAPI
char e1000_driver_version[] = DRV_VERSION;
-char e1000_copyright[] = "Copyright (c) 1999-2005 Intel Corporation.";
+static char e1000_copyright[] = "Copyright (c) 1999-2005 Intel Corporation.";
/* e1000_pci_tbl - PCI Device ID Table
*
@@ -80,6 +80,9 @@ static struct pci_device_id e1000_pci_tbl[] = {
INTEL_E1000_ETHERNET_DEVICE(0x1026),
INTEL_E1000_ETHERNET_DEVICE(0x1027),
INTEL_E1000_ETHERNET_DEVICE(0x1028),
+ INTEL_E1000_ETHERNET_DEVICE(0x105E),
+ INTEL_E1000_ETHERNET_DEVICE(0x105F),
+ INTEL_E1000_ETHERNET_DEVICE(0x1060),
INTEL_E1000_ETHERNET_DEVICE(0x1075),
INTEL_E1000_ETHERNET_DEVICE(0x1076),
INTEL_E1000_ETHERNET_DEVICE(0x1077),
@@ -88,10 +91,13 @@ static struct pci_device_id e1000_pci_tbl[] = {
INTEL_E1000_ETHERNET_DEVICE(0x107A),
INTEL_E1000_ETHERNET_DEVICE(0x107B),
INTEL_E1000_ETHERNET_DEVICE(0x107C),
+ INTEL_E1000_ETHERNET_DEVICE(0x107D),
+ INTEL_E1000_ETHERNET_DEVICE(0x107E),
+ INTEL_E1000_ETHERNET_DEVICE(0x107F),
INTEL_E1000_ETHERNET_DEVICE(0x108A),
INTEL_E1000_ETHERNET_DEVICE(0x108B),
INTEL_E1000_ETHERNET_DEVICE(0x108C),
- INTEL_E1000_ETHERNET_DEVICE(0x1099),
+ INTEL_E1000_ETHERNET_DEVICE(0x109A),
/* required last entry */
{0,}
};
@@ -102,10 +108,18 @@ int e1000_up(struct e1000_adapter *adapter);
void e1000_down(struct e1000_adapter *adapter);
void e1000_reset(struct e1000_adapter *adapter);
int e1000_set_spd_dplx(struct e1000_adapter *adapter, uint16_t spddplx);
-int e1000_setup_tx_resources(struct e1000_adapter *adapter);
-int e1000_setup_rx_resources(struct e1000_adapter *adapter);
-void e1000_free_tx_resources(struct e1000_adapter *adapter);
-void e1000_free_rx_resources(struct e1000_adapter *adapter);
+int e1000_setup_all_tx_resources(struct e1000_adapter *adapter);
+int e1000_setup_all_rx_resources(struct e1000_adapter *adapter);
+void e1000_free_all_tx_resources(struct e1000_adapter *adapter);
+void e1000_free_all_rx_resources(struct e1000_adapter *adapter);
+static int e1000_setup_tx_resources(struct e1000_adapter *adapter,
+ struct e1000_tx_ring *txdr);
+static int e1000_setup_rx_resources(struct e1000_adapter *adapter,
+ struct e1000_rx_ring *rxdr);
+static void e1000_free_tx_resources(struct e1000_adapter *adapter,
+ struct e1000_tx_ring *tx_ring);
+static void e1000_free_rx_resources(struct e1000_adapter *adapter,
+ struct e1000_rx_ring *rx_ring);
void e1000_update_stats(struct e1000_adapter *adapter);
/* Local Function Prototypes */
@@ -114,14 +128,22 @@ static int e1000_init_module(void);
static void e1000_exit_module(void);
static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent);
static void __devexit e1000_remove(struct pci_dev *pdev);
+static int e1000_alloc_queues(struct e1000_adapter *adapter);
+#ifdef CONFIG_E1000_MQ
+static void e1000_setup_queue_mapping(struct e1000_adapter *adapter);
+#endif
static int e1000_sw_init(struct e1000_adapter *adapter);
static int e1000_open(struct net_device *netdev);
static int e1000_close(struct net_device *netdev);
static void e1000_configure_tx(struct e1000_adapter *adapter);
static void e1000_configure_rx(struct e1000_adapter *adapter);
static void e1000_setup_rctl(struct e1000_adapter *adapter);
-static void e1000_clean_tx_ring(struct e1000_adapter *adapter);
-static void e1000_clean_rx_ring(struct e1000_adapter *adapter);
+static void e1000_clean_all_tx_rings(struct e1000_adapter *adapter);
+static void e1000_clean_all_rx_rings(struct e1000_adapter *adapter);
+static void e1000_clean_tx_ring(struct e1000_adapter *adapter,
+ struct e1000_tx_ring *tx_ring);
+static void e1000_clean_rx_ring(struct e1000_adapter *adapter,
+ struct e1000_rx_ring *rx_ring);
static void e1000_set_multi(struct net_device *netdev);
static void e1000_update_phy_info(unsigned long data);
static void e1000_watchdog(unsigned long data);
@@ -132,19 +154,26 @@ static struct net_device_stats * e1000_get_stats(struct net_device *netdev);
static int e1000_change_mtu(struct net_device *netdev, int new_mtu);
static int e1000_set_mac(struct net_device *netdev, void *p);
static irqreturn_t e1000_intr(int irq, void *data, struct pt_regs *regs);
-static boolean_t e1000_clean_tx_irq(struct e1000_adapter *adapter);
+static boolean_t e1000_clean_tx_irq(struct e1000_adapter *adapter,
+ struct e1000_tx_ring *tx_ring);
#ifdef CONFIG_E1000_NAPI
-static int e1000_clean(struct net_device *netdev, int *budget);
+static int e1000_clean(struct net_device *poll_dev, int *budget);
static boolean_t e1000_clean_rx_irq(struct e1000_adapter *adapter,
+ struct e1000_rx_ring *rx_ring,
int *work_done, int work_to_do);
static boolean_t e1000_clean_rx_irq_ps(struct e1000_adapter *adapter,
+ struct e1000_rx_ring *rx_ring,
int *work_done, int work_to_do);
#else
-static boolean_t e1000_clean_rx_irq(struct e1000_adapter *adapter);
-static boolean_t e1000_clean_rx_irq_ps(struct e1000_adapter *adapter);
+static boolean_t e1000_clean_rx_irq(struct e1000_adapter *adapter,
+ struct e1000_rx_ring *rx_ring);
+static boolean_t e1000_clean_rx_irq_ps(struct e1000_adapter *adapter,
+ struct e1000_rx_ring *rx_ring);
#endif
-static void e1000_alloc_rx_buffers(struct e1000_adapter *adapter);
-static void e1000_alloc_rx_buffers_ps(struct e1000_adapter *adapter);
+static void e1000_alloc_rx_buffers(struct e1000_adapter *adapter,
+ struct e1000_rx_ring *rx_ring);
+static void e1000_alloc_rx_buffers_ps(struct e1000_adapter *adapter,
+ struct e1000_rx_ring *rx_ring);
static int e1000_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd);
static int e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr,
int cmd);
@@ -162,8 +191,8 @@ static void e1000_vlan_rx_add_vid(struct net_device *netdev, uint16_t vid);
static void e1000_vlan_rx_kill_vid(struct net_device *netdev, uint16_t vid);
static void e1000_restore_vlan(struct e1000_adapter *adapter);
-static int e1000_suspend(struct pci_dev *pdev, pm_message_t state);
#ifdef CONFIG_PM
+static int e1000_suspend(struct pci_dev *pdev, pm_message_t state);
static int e1000_resume(struct pci_dev *pdev);
#endif
@@ -172,6 +201,11 @@ static int e1000_resume(struct pci_dev *pdev);
static void e1000_netpoll (struct net_device *netdev);
#endif
+#ifdef CONFIG_E1000_MQ
+/* for multiple Rx queues */
+void e1000_rx_schedule(void *data);
+#endif
+
/* Exported from other modules */
extern void e1000_check_options(struct e1000_adapter *adapter);
@@ -262,7 +296,8 @@ e1000_irq_enable(struct e1000_adapter *adapter)
E1000_WRITE_FLUSH(&adapter->hw);
}
}
-void
+
+static void
e1000_update_mng_vlan(struct e1000_adapter *adapter)
{
struct net_device *netdev = adapter->netdev;
@@ -289,7 +324,7 @@ int
e1000_up(struct e1000_adapter *adapter)
{
struct net_device *netdev = adapter->netdev;
- int err;
+ int i, err;
/* hardware has been reset, we need to reload some things */
@@ -308,7 +343,8 @@ e1000_up(struct e1000_adapter *adapter)
e1000_configure_tx(adapter);
e1000_setup_rctl(adapter);
e1000_configure_rx(adapter);
- adapter->alloc_rx_buf(adapter);
+ for (i = 0; i < adapter->num_queues; i++)
+ adapter->alloc_rx_buf(adapter, &adapter->rx_ring[i]);
#ifdef CONFIG_PCI_MSI
if(adapter->hw.mac_type > e1000_82547_rev_2) {
@@ -344,6 +380,9 @@ e1000_down(struct e1000_adapter *adapter)
struct net_device *netdev = adapter->netdev;
e1000_irq_disable(adapter);
+#ifdef CONFIG_E1000_MQ
+ while (atomic_read(&adapter->rx_sched_call_data.count) != 0);
+#endif
free_irq(adapter->pdev->irq, netdev);
#ifdef CONFIG_PCI_MSI
if(adapter->hw.mac_type > e1000_82547_rev_2 &&
@@ -363,11 +402,10 @@ e1000_down(struct e1000_adapter *adapter)
netif_stop_queue(netdev);
e1000_reset(adapter);
- e1000_clean_tx_ring(adapter);
- e1000_clean_rx_ring(adapter);
+ e1000_clean_all_tx_rings(adapter);
+ e1000_clean_all_rx_rings(adapter);
- /* If WoL is not enabled
- * and management mode is not IAMT
+ /* If WoL is not enabled and management mode is not IAMT
* Power down the PHY so no link is implied when interface is down */
if(!adapter->wol && adapter->hw.mac_type >= e1000_82540 &&
adapter->hw.media_type == e1000_media_type_copper &&
@@ -398,6 +436,10 @@ e1000_reset(struct e1000_adapter *adapter)
case e1000_82547_rev_2:
pba = E1000_PBA_30K;
break;
+ case e1000_82571:
+ case e1000_82572:
+ pba = E1000_PBA_38K;
+ break;
case e1000_82573:
pba = E1000_PBA_12K;
break;
@@ -475,6 +517,7 @@ e1000_probe(struct pci_dev *pdev,
struct net_device *netdev;
struct e1000_adapter *adapter;
unsigned long mmio_start, mmio_len;
+ uint32_t ctrl_ext;
uint32_t swsm;
static int cards_found = 0;
@@ -614,8 +657,9 @@ e1000_probe(struct pci_dev *pdev,
if(e1000_read_mac_addr(&adapter->hw))
DPRINTK(PROBE, ERR, "EEPROM Read Error\n");
memcpy(netdev->dev_addr, adapter->hw.mac_addr, netdev->addr_len);
+ memcpy(netdev->perm_addr, adapter->hw.mac_addr, netdev->addr_len);
- if(!is_valid_ether_addr(netdev->dev_addr)) {
+ if(!is_valid_ether_addr(netdev->perm_addr)) {
DPRINTK(PROBE, ERR, "Invalid MAC Address\n");
err = -EIO;
goto err_eeprom;
@@ -687,6 +731,12 @@ e1000_probe(struct pci_dev *pdev,
/* Let firmware know the driver has taken over */
switch(adapter->hw.mac_type) {
+ case e1000_82571:
+ case e1000_82572:
+ ctrl_ext = E1000_READ_REG(&adapter->hw, CTRL_EXT);
+ E1000_WRITE_REG(&adapter->hw, CTRL_EXT,
+ ctrl_ext | E1000_CTRL_EXT_DRV_LOAD);
+ break;
case e1000_82573:
swsm = E1000_READ_REG(&adapter->hw, SWSM);
E1000_WRITE_REG(&adapter->hw, SWSM,
@@ -731,7 +781,11 @@ e1000_remove(struct pci_dev *pdev)
{
struct net_device *netdev = pci_get_drvdata(pdev);
struct e1000_adapter *adapter = netdev_priv(netdev);
+ uint32_t ctrl_ext;
uint32_t manc, swsm;
+#ifdef CONFIG_E1000_NAPI
+ int i;
+#endif
flush_scheduled_work();
@@ -745,6 +799,12 @@ e1000_remove(struct pci_dev *pdev)
}
switch(adapter->hw.mac_type) {
+ case e1000_82571:
+ case e1000_82572:
+ ctrl_ext = E1000_READ_REG(&adapter->hw, CTRL_EXT);
+ E1000_WRITE_REG(&adapter->hw, CTRL_EXT,
+ ctrl_ext & ~E1000_CTRL_EXT_DRV_LOAD);
+ break;
case e1000_82573:
swsm = E1000_READ_REG(&adapter->hw, SWSM);
E1000_WRITE_REG(&adapter->hw, SWSM,
@@ -756,13 +816,27 @@ e1000_remove(struct pci_dev *pdev)
}
unregister_netdev(netdev);
+#ifdef CONFIG_E1000_NAPI
+ for (i = 0; i < adapter->num_queues; i++)
+ __dev_put(&adapter->polling_netdev[i]);
+#endif
if(!e1000_check_phy_reset_block(&adapter->hw))
e1000_phy_hw_reset(&adapter->hw);
+ kfree(adapter->tx_ring);
+ kfree(adapter->rx_ring);
+#ifdef CONFIG_E1000_NAPI
+ kfree(adapter->polling_netdev);
+#endif
+
iounmap(adapter->hw.hw_addr);
pci_release_regions(pdev);
+#ifdef CONFIG_E1000_MQ
+ free_percpu(adapter->cpu_netdev);
+ free_percpu(adapter->cpu_tx_ring);
+#endif
free_netdev(netdev);
pci_disable_device(pdev);
@@ -783,6 +857,9 @@ e1000_sw_init(struct e1000_adapter *adapter)
struct e1000_hw *hw = &adapter->hw;
struct net_device *netdev = adapter->netdev;
struct pci_dev *pdev = adapter->pdev;
+#ifdef CONFIG_E1000_NAPI
+ int i;
+#endif
/* PCI config space info */
@@ -840,14 +917,123 @@ e1000_sw_init(struct e1000_adapter *adapter)
hw->master_slave = E1000_MASTER_SLAVE;
}
+#ifdef CONFIG_E1000_MQ
+ /* Number of supported queues */
+ switch (hw->mac_type) {
+ case e1000_82571:
+ case e1000_82572:
+ adapter->num_queues = 2;
+ break;
+ default:
+ adapter->num_queues = 1;
+ break;
+ }
+ adapter->num_queues = min(adapter->num_queues, num_online_cpus());
+#else
+ adapter->num_queues = 1;
+#endif
+
+ if (e1000_alloc_queues(adapter)) {
+ DPRINTK(PROBE, ERR, "Unable to allocate memory for queues\n");
+ return -ENOMEM;
+ }
+
+#ifdef CONFIG_E1000_NAPI
+ for (i = 0; i < adapter->num_queues; i++) {
+ adapter->polling_netdev[i].priv = adapter;
+ adapter->polling_netdev[i].poll = &e1000_clean;
+ adapter->polling_netdev[i].weight = 64;
+ dev_hold(&adapter->polling_netdev[i]);
+ set_bit(__LINK_STATE_START, &adapter->polling_netdev[i].state);
+ }
+#endif
+
+#ifdef CONFIG_E1000_MQ
+ e1000_setup_queue_mapping(adapter);
+#endif
+
atomic_set(&adapter->irq_sem, 1);
spin_lock_init(&adapter->stats_lock);
- spin_lock_init(&adapter->tx_lock);
return 0;
}
/**
+ * e1000_alloc_queues - Allocate memory for all rings
+ * @adapter: board private structure to initialize
+ *
+ * We allocate one ring per queue at run-time since we don't know the
+ * number of queues at compile-time. The polling_netdev array is
+ * intended for Multiqueue, but should work fine with a single queue.
+ **/
+
+static int __devinit
+e1000_alloc_queues(struct e1000_adapter *adapter)
+{
+ int size;
+
+ size = sizeof(struct e1000_tx_ring) * adapter->num_queues;
+ adapter->tx_ring = kmalloc(size, GFP_KERNEL);
+ if (!adapter->tx_ring)
+ return -ENOMEM;
+ memset(adapter->tx_ring, 0, size);
+
+ size = sizeof(struct e1000_rx_ring) * adapter->num_queues;
+ adapter->rx_ring = kmalloc(size, GFP_KERNEL);
+ if (!adapter->rx_ring) {
+ kfree(adapter->tx_ring);
+ return -ENOMEM;
+ }
+ memset(adapter->rx_ring, 0, size);
+
+#ifdef CONFIG_E1000_NAPI
+ size = sizeof(struct net_device) * adapter->num_queues;
+ adapter->polling_netdev = kmalloc(size, GFP_KERNEL);
+ if (!adapter->polling_netdev) {
+ kfree(adapter->tx_ring);
+ kfree(adapter->rx_ring);
+ return -ENOMEM;
+ }
+ memset(adapter->polling_netdev, 0, size);
+#endif
+
+ return E1000_SUCCESS;
+}
+
+#ifdef CONFIG_E1000_MQ
+static void __devinit
+e1000_setup_queue_mapping(struct e1000_adapter *adapter)
+{
+ int i, cpu;
+
+ adapter->rx_sched_call_data.func = e1000_rx_schedule;
+ adapter->rx_sched_call_data.info = adapter->netdev;
+ cpus_clear(adapter->rx_sched_call_data.cpumask);
+
+ adapter->cpu_netdev = alloc_percpu(struct net_device *);
+ adapter->cpu_tx_ring = alloc_percpu(struct e1000_tx_ring *);
+
+ lock_cpu_hotplug();
+ i = 0;
+ for_each_online_cpu(cpu) {
+ *per_cpu_ptr(adapter->cpu_tx_ring, cpu) = &adapter->tx_ring[i % adapter->num_queues];
+ /* This is incomplete because we'd like to assign separate
+ * physical cpus to these netdev polling structures and
+ * avoid saturating a subset of cpus.
+ */
+ if (i < adapter->num_queues) {
+ *per_cpu_ptr(adapter->cpu_netdev, cpu) = &adapter->polling_netdev[i];
+ adapter->cpu_for_queue[i] = cpu;
+ } else
+ *per_cpu_ptr(adapter->cpu_netdev, cpu) = NULL;
+
+ i++;
+ }
+ unlock_cpu_hotplug();
+}
+#endif
+
+/**
* e1000_open - Called when a network interface is made active
* @netdev: network interface device structure
*
@@ -868,12 +1054,12 @@ e1000_open(struct net_device *netdev)
/* allocate transmit descriptors */
- if((err = e1000_setup_tx_resources(adapter)))
+ if ((err = e1000_setup_all_tx_resources(adapter)))
goto err_setup_tx;
/* allocate receive descriptors */
- if((err = e1000_setup_rx_resources(adapter)))
+ if ((err = e1000_setup_all_rx_resources(adapter)))
goto err_setup_rx;
if((err = e1000_up(adapter)))
@@ -887,9 +1073,9 @@ e1000_open(struct net_device *netdev)
return E1000_SUCCESS;
err_up:
- e1000_free_rx_resources(adapter);
+ e1000_free_all_rx_resources(adapter);
err_setup_rx:
- e1000_free_tx_resources(adapter);
+ e1000_free_all_tx_resources(adapter);
err_setup_tx:
e1000_reset(adapter);
@@ -915,8 +1101,8 @@ e1000_close(struct net_device *netdev)
e1000_down(adapter);
- e1000_free_tx_resources(adapter);
- e1000_free_rx_resources(adapter);
+ e1000_free_all_tx_resources(adapter);
+ e1000_free_all_rx_resources(adapter);
if((adapter->hw.mng_cookie.status &
E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT)) {
@@ -951,25 +1137,28 @@ e1000_check_64k_bound(struct e1000_adapter *adapter,
/**
* e1000_setup_tx_resources - allocate Tx resources (Descriptors)
* @adapter: board private structure
+ * @txdr: tx descriptor ring (for a specific queue) to setup
*
* Return 0 on success, negative on failure
**/
-int
-e1000_setup_tx_resources(struct e1000_adapter *adapter)
+static int
+e1000_setup_tx_resources(struct e1000_adapter *adapter,
+ struct e1000_tx_ring *txdr)
{
- struct e1000_desc_ring *txdr = &adapter->tx_ring;
struct pci_dev *pdev = adapter->pdev;
int size;
size = sizeof(struct e1000_buffer) * txdr->count;
- txdr->buffer_info = vmalloc(size);
+
+ txdr->buffer_info = vmalloc_node(size, pcibus_to_node(pdev->bus));
if(!txdr->buffer_info) {
DPRINTK(PROBE, ERR,
"Unable to allocate memory for the transmit descriptor ring\n");
return -ENOMEM;
}
memset(txdr->buffer_info, 0, size);
+ memset(&txdr->previous_buffer_info, 0, sizeof(struct e1000_buffer));
/* round up to nearest 4K */
@@ -1018,11 +1207,41 @@ setup_tx_desc_die:
txdr->next_to_use = 0;
txdr->next_to_clean = 0;
+ spin_lock_init(&txdr->tx_lock);
return 0;
}
/**
+ * e1000_setup_all_tx_resources - wrapper to allocate Tx resources
+ * (Descriptors) for all queues
+ * @adapter: board private structure
+ *
+ * If this function returns with an error, then it's possible one or
+ * more of the rings is populated (while the rest are not). It is the
+ * callers duty to clean those orphaned rings.
+ *
+ * Return 0 on success, negative on failure
+ **/
+
+int
+e1000_setup_all_tx_resources(struct e1000_adapter *adapter)
+{
+ int i, err = 0;
+
+ for (i = 0; i < adapter->num_queues; i++) {
+ err = e1000_setup_tx_resources(adapter, &adapter->tx_ring[i]);
+ if (err) {
+ DPRINTK(PROBE, ERR,
+ "Allocation for Tx Queue %u failed\n", i);
+ break;
+ }
+ }
+
+ return err;
+}
+
+/**
* e1000_configure_tx - Configure 8254x Transmit Unit after Reset
* @adapter: board private structure
*
@@ -1032,23 +1251,43 @@ setup_tx_desc_die:
static void
e1000_configure_tx(struct e1000_adapter *adapter)
{
- uint64_t tdba = adapter->tx_ring.dma;
- uint32_t tdlen = adapter->tx_ring.count * sizeof(struct e1000_tx_desc);
- uint32_t tctl, tipg;
-
- E1000_WRITE_REG(&adapter->hw, TDBAL, (tdba & 0x00000000ffffffffULL));
- E1000_WRITE_REG(&adapter->hw, TDBAH, (tdba >> 32));
-
- E1000_WRITE_REG(&adapter->hw, TDLEN, tdlen);
+ uint64_t tdba;
+ struct e1000_hw *hw = &adapter->hw;
+ uint32_t tdlen, tctl, tipg, tarc;
/* Setup the HW Tx Head and Tail descriptor pointers */
- E1000_WRITE_REG(&adapter->hw, TDH, 0);
- E1000_WRITE_REG(&adapter->hw, TDT, 0);
+ switch (adapter->num_queues) {
+ case 2:
+ tdba = adapter->tx_ring[1].dma;
+ tdlen = adapter->tx_ring[1].count *
+ sizeof(struct e1000_tx_desc);
+ E1000_WRITE_REG(hw, TDBAL1, (tdba & 0x00000000ffffffffULL));
+ E1000_WRITE_REG(hw, TDBAH1, (tdba >> 32));
+ E1000_WRITE_REG(hw, TDLEN1, tdlen);
+ E1000_WRITE_REG(hw, TDH1, 0);
+ E1000_WRITE_REG(hw, TDT1, 0);
+ adapter->tx_ring[1].tdh = E1000_TDH1;
+ adapter->tx_ring[1].tdt = E1000_TDT1;
+ /* Fall Through */
+ case 1:
+ default:
+ tdba = adapter->tx_ring[0].dma;
+ tdlen = adapter->tx_ring[0].count *
+ sizeof(struct e1000_tx_desc);
+ E1000_WRITE_REG(hw, TDBAL, (tdba & 0x00000000ffffffffULL));
+ E1000_WRITE_REG(hw, TDBAH, (tdba >> 32));
+ E1000_WRITE_REG(hw, TDLEN, tdlen);
+ E1000_WRITE_REG(hw, TDH, 0);
+ E1000_WRITE_REG(hw, TDT, 0);
+ adapter->tx_ring[0].tdh = E1000_TDH;
+ adapter->tx_ring[0].tdt = E1000_TDT;
+ break;
+ }
/* Set the default values for the Tx Inter Packet Gap timer */
- switch (adapter->hw.mac_type) {
+ switch (hw->mac_type) {
case e1000_82542_rev2_0:
case e1000_82542_rev2_1:
tipg = DEFAULT_82542_TIPG_IPGT;
@@ -1056,67 +1295,81 @@ e1000_configure_tx(struct e1000_adapter *adapter)
tipg |= DEFAULT_82542_TIPG_IPGR2 << E1000_TIPG_IPGR2_SHIFT;
break;
default:
- if(adapter->hw.media_type == e1000_media_type_fiber ||
- adapter->hw.media_type == e1000_media_type_internal_serdes)
+ if (hw->media_type == e1000_media_type_fiber ||
+ hw->media_type == e1000_media_type_internal_serdes)
tipg = DEFAULT_82543_TIPG_IPGT_FIBER;
else
tipg = DEFAULT_82543_TIPG_IPGT_COPPER;
tipg |= DEFAULT_82543_TIPG_IPGR1 << E1000_TIPG_IPGR1_SHIFT;
tipg |= DEFAULT_82543_TIPG_IPGR2 << E1000_TIPG_IPGR2_SHIFT;
}
- E1000_WRITE_REG(&adapter->hw, TIPG, tipg);
+ E1000_WRITE_REG(hw, TIPG, tipg);
/* Set the Tx Interrupt Delay register */
- E1000_WRITE_REG(&adapter->hw, TIDV, adapter->tx_int_delay);
- if(adapter->hw.mac_type >= e1000_82540)
- E1000_WRITE_REG(&adapter->hw, TADV, adapter->tx_abs_int_delay);
+ E1000_WRITE_REG(hw, TIDV, adapter->tx_int_delay);
+ if (hw->mac_type >= e1000_82540)
+ E1000_WRITE_REG(hw, TADV, adapter->tx_abs_int_delay);
/* Program the Transmit Control Register */
- tctl = E1000_READ_REG(&adapter->hw, TCTL);
+ tctl = E1000_READ_REG(hw, TCTL);
tctl &= ~E1000_TCTL_CT;
- tctl |= E1000_TCTL_EN | E1000_TCTL_PSP |
+ tctl |= E1000_TCTL_EN | E1000_TCTL_PSP | E1000_TCTL_RTLC |
(E1000_COLLISION_THRESHOLD << E1000_CT_SHIFT);
- E1000_WRITE_REG(&adapter->hw, TCTL, tctl);
+ E1000_WRITE_REG(hw, TCTL, tctl);
- e1000_config_collision_dist(&adapter->hw);
+ if (hw->mac_type == e1000_82571 || hw->mac_type == e1000_82572) {
+ tarc = E1000_READ_REG(hw, TARC0);
+ tarc |= ((1 << 25) | (1 << 21));
+ E1000_WRITE_REG(hw, TARC0, tarc);
+ tarc = E1000_READ_REG(hw, TARC1);
+ tarc |= (1 << 25);
+ if (tctl & E1000_TCTL_MULR)
+ tarc &= ~(1 << 28);
+ else
+ tarc |= (1 << 28);
+ E1000_WRITE_REG(hw, TARC1, tarc);
+ }
+
+ e1000_config_collision_dist(hw);
/* Setup Transmit Descriptor Settings for eop descriptor */
adapter->txd_cmd = E1000_TXD_CMD_IDE | E1000_TXD_CMD_EOP |
E1000_TXD_CMD_IFCS;
- if(adapter->hw.mac_type < e1000_82543)
+ if (hw->mac_type < e1000_82543)
adapter->txd_cmd |= E1000_TXD_CMD_RPS;
else
adapter->txd_cmd |= E1000_TXD_CMD_RS;
/* Cache if we're 82544 running in PCI-X because we'll
* need this to apply a workaround later in the send path. */
- if(adapter->hw.mac_type == e1000_82544 &&
- adapter->hw.bus_type == e1000_bus_type_pcix)
+ if (hw->mac_type == e1000_82544 &&
+ hw->bus_type == e1000_bus_type_pcix)
adapter->pcix_82544 = 1;
}
/**
* e1000_setup_rx_resources - allocate Rx resources (Descriptors)
* @adapter: board private structure
+ * @rxdr: rx descriptor ring (for a specific queue) to setup
*
* Returns 0 on success, negative on failure
**/
-int
-e1000_setup_rx_resources(struct e1000_adapter *adapter)
+static int
+e1000_setup_rx_resources(struct e1000_adapter *adapter,
+ struct e1000_rx_ring *rxdr)
{
- struct e1000_desc_ring *rxdr = &adapter->rx_ring;
struct pci_dev *pdev = adapter->pdev;
int size, desc_len;
size = sizeof(struct e1000_buffer) * rxdr->count;
- rxdr->buffer_info = vmalloc(size);
- if(!rxdr->buffer_info) {
+ rxdr->buffer_info = vmalloc_node(size, pcibus_to_node(pdev->bus));
+ if (!rxdr->buffer_info) {
DPRINTK(PROBE, ERR,
"Unable to allocate memory for the receive descriptor ring\n");
return -ENOMEM;
@@ -1156,13 +1409,13 @@ e1000_setup_rx_resources(struct e1000_adapter *adapter)
rxdr->desc = pci_alloc_consistent(pdev, rxdr->size, &rxdr->dma);
- if(!rxdr->desc) {
+ if (!rxdr->desc) {
+ DPRINTK(PROBE, ERR,
+ "Unable to allocate memory for the receive descriptor ring\n");
setup_rx_desc_die:
vfree(rxdr->buffer_info);
kfree(rxdr->ps_page);
kfree(rxdr->ps_page_dma);
- DPRINTK(PROBE, ERR,
- "Unable to allocate memory for the receive descriptor ring\n");
return -ENOMEM;
}
@@ -1174,9 +1427,12 @@ setup_rx_desc_die:
"at %p\n", rxdr->size, rxdr->desc);
/* Try again, without freeing the previous */
rxdr->desc = pci_alloc_consistent(pdev, rxdr->size, &rxdr->dma);
- if(!rxdr->desc) {
/* Failed allocation, critical failure */
+ if (!rxdr->desc) {
pci_free_consistent(pdev, rxdr->size, olddesc, olddma);
+ DPRINTK(PROBE, ERR,
+ "Unable to allocate memory "
+ "for the receive descriptor ring\n");
goto setup_rx_desc_die;
}
@@ -1188,10 +1444,7 @@ setup_rx_desc_die:
DPRINTK(PROBE, ERR,
"Unable to allocate aligned memory "
"for the receive descriptor ring\n");
- vfree(rxdr->buffer_info);
- kfree(rxdr->ps_page);
- kfree(rxdr->ps_page_dma);
- return -ENOMEM;
+ goto setup_rx_desc_die;
} else {
/* Free old allocation, new allocation was successful */
pci_free_consistent(pdev, rxdr->size, olddesc, olddma);
@@ -1206,15 +1459,48 @@ setup_rx_desc_die:
}
/**
+ * e1000_setup_all_rx_resources - wrapper to allocate Rx resources
+ * (Descriptors) for all queues
+ * @adapter: board private structure
+ *
+ * If this function returns with an error, then it's possible one or
+ * more of the rings is populated (while the rest are not). It is the
+ * callers duty to clean those orphaned rings.
+ *
+ * Return 0 on success, negative on failure
+ **/
+
+int
+e1000_setup_all_rx_resources(struct e1000_adapter *adapter)
+{
+ int i, err = 0;
+
+ for (i = 0; i < adapter->num_queues; i++) {
+ err = e1000_setup_rx_resources(adapter, &adapter->rx_ring[i]);
+ if (err) {
+ DPRINTK(PROBE, ERR,
+ "Allocation for Rx Queue %u failed\n", i);
+ break;
+ }
+ }
+
+ return err;
+}
+
+/**
* e1000_setup_rctl - configure the receive control registers
* @adapter: Board private structure
**/
-
+#define PAGE_USE_COUNT(S) (((S) >> PAGE_SHIFT) + \
+ (((S) & (PAGE_SIZE - 1)) ? 1 : 0))
static void
e1000_setup_rctl(struct e1000_adapter *adapter)
{
uint32_t rctl, rfctl;
uint32_t psrctl = 0;
+#ifdef CONFIG_E1000_PACKET_SPLIT
+ uint32_t pages = 0;
+#endif
rctl = E1000_READ_REG(&adapter->hw, RCTL);
@@ -1235,7 +1521,7 @@ e1000_setup_rctl(struct e1000_adapter *adapter)
rctl |= E1000_RCTL_LPE;
/* Setup buffer sizes */
- if(adapter->hw.mac_type == e1000_82573) {
+ if(adapter->hw.mac_type >= e1000_82571) {
/* We can now specify buffers in 1K increments.
* BSIZE and BSEX are ignored in this case. */
rctl |= adapter->rx_buffer_len << 0x11;
@@ -1268,11 +1554,14 @@ e1000_setup_rctl(struct e1000_adapter *adapter)
* followed by the page buffers. Therefore, skb->data is
* sized to hold the largest protocol header.
*/
- adapter->rx_ps = (adapter->hw.mac_type > e1000_82547_rev_2)
- && (adapter->netdev->mtu
- < ((3 * PAGE_SIZE) + adapter->rx_ps_bsize0));
+ pages = PAGE_USE_COUNT(adapter->netdev->mtu);
+ if ((adapter->hw.mac_type > e1000_82547_rev_2) && (pages <= 3) &&
+ PAGE_SIZE <= 16384)
+ adapter->rx_ps_pages = pages;
+ else
+ adapter->rx_ps_pages = 0;
#endif
- if(adapter->rx_ps) {
+ if (adapter->rx_ps_pages) {
/* Configure extra packet-split registers */
rfctl = E1000_READ_REG(&adapter->hw, RFCTL);
rfctl |= E1000_RFCTL_EXTEN;
@@ -1284,12 +1573,19 @@ e1000_setup_rctl(struct e1000_adapter *adapter)
psrctl |= adapter->rx_ps_bsize0 >>
E1000_PSRCTL_BSIZE0_SHIFT;
- psrctl |= PAGE_SIZE >>
- E1000_PSRCTL_BSIZE1_SHIFT;
- psrctl |= PAGE_SIZE <<
- E1000_PSRCTL_BSIZE2_SHIFT;
- psrctl |= PAGE_SIZE <<
- E1000_PSRCTL_BSIZE3_SHIFT;
+
+ switch (adapter->rx_ps_pages) {
+ case 3:
+ psrctl |= PAGE_SIZE <<
+ E1000_PSRCTL_BSIZE3_SHIFT;
+ case 2:
+ psrctl |= PAGE_SIZE <<
+ E1000_PSRCTL_BSIZE2_SHIFT;
+ case 1:
+ psrctl |= PAGE_SIZE >>
+ E1000_PSRCTL_BSIZE1_SHIFT;
+ break;
+ }
E1000_WRITE_REG(&adapter->hw, PSRCTL, psrctl);
}
@@ -1307,91 +1603,181 @@ e1000_setup_rctl(struct e1000_adapter *adapter)
static void
e1000_configure_rx(struct e1000_adapter *adapter)
{
- uint64_t rdba = adapter->rx_ring.dma;
- uint32_t rdlen, rctl, rxcsum;
+ uint64_t rdba;
+ struct e1000_hw *hw = &adapter->hw;
+ uint32_t rdlen, rctl, rxcsum, ctrl_ext;
+#ifdef CONFIG_E1000_MQ
+ uint32_t reta, mrqc;
+ int i;
+#endif
- if(adapter->rx_ps) {
- rdlen = adapter->rx_ring.count *
+ if (adapter->rx_ps_pages) {
+ rdlen = adapter->rx_ring[0].count *
sizeof(union e1000_rx_desc_packet_split);
adapter->clean_rx = e1000_clean_rx_irq_ps;
adapter->alloc_rx_buf = e1000_alloc_rx_buffers_ps;
} else {
- rdlen = adapter->rx_ring.count * sizeof(struct e1000_rx_desc);
+ rdlen = adapter->rx_ring[0].count *
+ sizeof(struct e1000_rx_desc);
adapter->clean_rx = e1000_clean_rx_irq;
adapter->alloc_rx_buf = e1000_alloc_rx_buffers;
}
/* disable receives while setting up the descriptors */
- rctl = E1000_READ_REG(&adapter->hw, RCTL);
- E1000_WRITE_REG(&adapter->hw, RCTL, rctl & ~E1000_RCTL_EN);
+ rctl = E1000_READ_REG(hw, RCTL);
+ E1000_WRITE_REG(hw, RCTL, rctl & ~E1000_RCTL_EN);
/* set the Receive Delay Timer Register */
- E1000_WRITE_REG(&adapter->hw, RDTR, adapter->rx_int_delay);
+ E1000_WRITE_REG(hw, RDTR, adapter->rx_int_delay);
- if(adapter->hw.mac_type >= e1000_82540) {
- E1000_WRITE_REG(&adapter->hw, RADV, adapter->rx_abs_int_delay);
+ if (hw->mac_type >= e1000_82540) {
+ E1000_WRITE_REG(hw, RADV, adapter->rx_abs_int_delay);
if(adapter->itr > 1)
- E1000_WRITE_REG(&adapter->hw, ITR,
+ E1000_WRITE_REG(hw, ITR,
1000000000 / (adapter->itr * 256));
}
- /* Setup the Base and Length of the Rx Descriptor Ring */
- E1000_WRITE_REG(&adapter->hw, RDBAL, (rdba & 0x00000000ffffffffULL));
- E1000_WRITE_REG(&adapter->hw, RDBAH, (rdba >> 32));
+ if (hw->mac_type >= e1000_82571) {
+ /* Reset delay timers after every interrupt */
+ ctrl_ext = E1000_READ_REG(hw, CTRL_EXT);
+ ctrl_ext |= E1000_CTRL_EXT_CANC;
+ E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext);
+ E1000_WRITE_FLUSH(hw);
+ }
+
+ /* Setup the HW Rx Head and Tail Descriptor Pointers and
+ * the Base and Length of the Rx Descriptor Ring */
+ switch (adapter->num_queues) {
+#ifdef CONFIG_E1000_MQ
+ case 2:
+ rdba = adapter->rx_ring[1].dma;
+ E1000_WRITE_REG(hw, RDBAL1, (rdba & 0x00000000ffffffffULL));
+ E1000_WRITE_REG(hw, RDBAH1, (rdba >> 32));
+ E1000_WRITE_REG(hw, RDLEN1, rdlen);
+ E1000_WRITE_REG(hw, RDH1, 0);
+ E1000_WRITE_REG(hw, RDT1, 0);
+ adapter->rx_ring[1].rdh = E1000_RDH1;
+ adapter->rx_ring[1].rdt = E1000_RDT1;
+ /* Fall Through */
+#endif
+ case 1:
+ default:
+ rdba = adapter->rx_ring[0].dma;
+ E1000_WRITE_REG(hw, RDBAL, (rdba & 0x00000000ffffffffULL));
+ E1000_WRITE_REG(hw, RDBAH, (rdba >> 32));
+ E1000_WRITE_REG(hw, RDLEN, rdlen);
+ E1000_WRITE_REG(hw, RDH, 0);
+ E1000_WRITE_REG(hw, RDT, 0);
+ adapter->rx_ring[0].rdh = E1000_RDH;
+ adapter->rx_ring[0].rdt = E1000_RDT;
+ break;
+ }
+
+#ifdef CONFIG_E1000_MQ
+ if (adapter->num_queues > 1) {
+ uint32_t random[10];
+
+ get_random_bytes(&random[0], 40);
+
+ if (hw->mac_type <= e1000_82572) {
+ E1000_WRITE_REG(hw, RSSIR, 0);
+ E1000_WRITE_REG(hw, RSSIM, 0);
+ }
+
+ switch (adapter->num_queues) {
+ case 2:
+ default:
+ reta = 0x00800080;
+ mrqc = E1000_MRQC_ENABLE_RSS_2Q;
+ break;
+ }
+
+ /* Fill out redirection table */
+ for (i = 0; i < 32; i++)
+ E1000_WRITE_REG_ARRAY(hw, RETA, i, reta);
+ /* Fill out hash function seeds */
+ for (i = 0; i < 10; i++)
+ E1000_WRITE_REG_ARRAY(hw, RSSRK, i, random[i]);
- E1000_WRITE_REG(&adapter->hw, RDLEN, rdlen);
+ mrqc |= (E1000_MRQC_RSS_FIELD_IPV4 |
+ E1000_MRQC_RSS_FIELD_IPV4_TCP);
+ E1000_WRITE_REG(hw, MRQC, mrqc);
+ }
- /* Setup the HW Rx Head and Tail Descriptor Pointers */
- E1000_WRITE_REG(&adapter->hw, RDH, 0);
- E1000_WRITE_REG(&adapter->hw, RDT, 0);
+ /* Multiqueue and packet checksumming are mutually exclusive. */
+ if (hw->mac_type >= e1000_82571) {
+ rxcsum = E1000_READ_REG(hw, RXCSUM);
+ rxcsum |= E1000_RXCSUM_PCSD;
+ E1000_WRITE_REG(hw, RXCSUM, rxcsum);
+ }
+
+#else
/* Enable 82543 Receive Checksum Offload for TCP and UDP */
- if(adapter->hw.mac_type >= e1000_82543) {
- rxcsum = E1000_READ_REG(&adapter->hw, RXCSUM);
+ if (hw->mac_type >= e1000_82543) {
+ rxcsum = E1000_READ_REG(hw, RXCSUM);
if(adapter->rx_csum == TRUE) {
rxcsum |= E1000_RXCSUM_TUOFL;
- /* Enable 82573 IPv4 payload checksum for UDP fragments
+ /* Enable 82571 IPv4 payload checksum for UDP fragments
* Must be used in conjunction with packet-split. */
- if((adapter->hw.mac_type > e1000_82547_rev_2) &&
- (adapter->rx_ps)) {
+ if ((hw->mac_type >= e1000_82571) &&
+ (adapter->rx_ps_pages)) {
rxcsum |= E1000_RXCSUM_IPPCSE;
}
} else {
rxcsum &= ~E1000_RXCSUM_TUOFL;
/* don't need to clear IPPCSE as it defaults to 0 */
}
- E1000_WRITE_REG(&adapter->hw, RXCSUM, rxcsum);
+ E1000_WRITE_REG(hw, RXCSUM, rxcsum);
}
+#endif /* CONFIG_E1000_MQ */
- if (adapter->hw.mac_type == e1000_82573)
- E1000_WRITE_REG(&adapter->hw, ERT, 0x0100);
+ if (hw->mac_type == e1000_82573)
+ E1000_WRITE_REG(hw, ERT, 0x0100);
/* Enable Receives */
- E1000_WRITE_REG(&adapter->hw, RCTL, rctl);
+ E1000_WRITE_REG(hw, RCTL, rctl);
}
/**
- * e1000_free_tx_resources - Free Tx Resources
+ * e1000_free_tx_resources - Free Tx Resources per Queue
* @adapter: board private structure
+ * @tx_ring: Tx descriptor ring for a specific queue
*
* Free all transmit software resources
**/
-void
-e1000_free_tx_resources(struct e1000_adapter *adapter)
+static void
+e1000_free_tx_resources(struct e1000_adapter *adapter,
+ struct e1000_tx_ring *tx_ring)
{
struct pci_dev *pdev = adapter->pdev;
- e1000_clean_tx_ring(adapter);
+ e1000_clean_tx_ring(adapter, tx_ring);
- vfree(adapter->tx_ring.buffer_info);
- adapter->tx_ring.buffer_info = NULL;
+ vfree(tx_ring->buffer_info);
+ tx_ring->buffer_info = NULL;
+
+ pci_free_consistent(pdev, tx_ring->size, tx_ring->desc, tx_ring->dma);
+
+ tx_ring->desc = NULL;
+}
+
+/**
+ * e1000_free_all_tx_resources - Free Tx Resources for All Queues
+ * @adapter: board private structure
+ *
+ * Free all transmit software resources
+ **/
- pci_free_consistent(pdev, adapter->tx_ring.size,
- adapter->tx_ring.desc, adapter->tx_ring.dma);
+void
+e1000_free_all_tx_resources(struct e1000_adapter *adapter)
+{
+ int i;
- adapter->tx_ring.desc = NULL;
+ for (i = 0; i < adapter->num_queues; i++)
+ e1000_free_tx_resources(adapter, &adapter->tx_ring[i]);
}
static inline void
@@ -1414,21 +1800,22 @@ e1000_unmap_and_free_tx_resource(struct e1000_adapter *adapter,
/**
* e1000_clean_tx_ring - Free Tx Buffers
* @adapter: board private structure
+ * @tx_ring: ring to be cleaned
**/
static void
-e1000_clean_tx_ring(struct e1000_adapter *adapter)
+e1000_clean_tx_ring(struct e1000_adapter *adapter,
+ struct e1000_tx_ring *tx_ring)
{
- struct e1000_desc_ring *tx_ring = &adapter->tx_ring;
struct e1000_buffer *buffer_info;
unsigned long size;
unsigned int i;
/* Free all the Tx ring sk_buffs */
- if (likely(adapter->previous_buffer_info.skb != NULL)) {
+ if (likely(tx_ring->previous_buffer_info.skb != NULL)) {
e1000_unmap_and_free_tx_resource(adapter,
- &adapter->previous_buffer_info);
+ &tx_ring->previous_buffer_info);
}
for(i = 0; i < tx_ring->count; i++) {
@@ -1446,24 +1833,39 @@ e1000_clean_tx_ring(struct e1000_adapter *adapter)
tx_ring->next_to_use = 0;
tx_ring->next_to_clean = 0;
- E1000_WRITE_REG(&adapter->hw, TDH, 0);
- E1000_WRITE_REG(&adapter->hw, TDT, 0);
+ writel(0, adapter->hw.hw_addr + tx_ring->tdh);
+ writel(0, adapter->hw.hw_addr + tx_ring->tdt);
+}
+
+/**
+ * e1000_clean_all_tx_rings - Free Tx Buffers for all queues
+ * @adapter: board private structure
+ **/
+
+static void
+e1000_clean_all_tx_rings(struct e1000_adapter *adapter)
+{
+ int i;
+
+ for (i = 0; i < adapter->num_queues; i++)
+ e1000_clean_tx_ring(adapter, &adapter->tx_ring[i]);
}
/**
* e1000_free_rx_resources - Free Rx Resources
* @adapter: board private structure
+ * @rx_ring: ring to clean the resources from
*
* Free all receive software resources
**/
-void
-e1000_free_rx_resources(struct e1000_adapter *adapter)
+static void
+e1000_free_rx_resources(struct e1000_adapter *adapter,
+ struct e1000_rx_ring *rx_ring)
{
- struct e1000_desc_ring *rx_ring = &adapter->rx_ring;
struct pci_dev *pdev = adapter->pdev;
- e1000_clean_rx_ring(adapter);
+ e1000_clean_rx_ring(adapter, rx_ring);
vfree(rx_ring->buffer_info);
rx_ring->buffer_info = NULL;
@@ -1478,14 +1880,31 @@ e1000_free_rx_resources(struct e1000_adapter *adapter)
}
/**
- * e1000_clean_rx_ring - Free Rx Buffers
+ * e1000_free_all_rx_resources - Free Rx Resources for All Queues
+ * @adapter: board private structure
+ *
+ * Free all receive software resources
+ **/
+
+void
+e1000_free_all_rx_resources(struct e1000_adapter *adapter)
+{
+ int i;
+
+ for (i = 0; i < adapter->num_queues; i++)
+ e1000_free_rx_resources(adapter, &adapter->rx_ring[i]);
+}
+
+/**
+ * e1000_clean_rx_ring - Free Rx Buffers per Queue
* @adapter: board private structure
+ * @rx_ring: ring to free buffers from
**/
static void
-e1000_clean_rx_ring(struct e1000_adapter *adapter)
+e1000_clean_rx_ring(struct e1000_adapter *adapter,
+ struct e1000_rx_ring *rx_ring)
{
- struct e1000_desc_ring *rx_ring = &adapter->rx_ring;
struct e1000_buffer *buffer_info;
struct e1000_ps_page *ps_page;
struct e1000_ps_page_dma *ps_page_dma;
@@ -1508,7 +1927,7 @@ e1000_clean_rx_ring(struct e1000_adapter *adapter)
dev_kfree_skb(buffer_info->skb);
buffer_info->skb = NULL;
- for(j = 0; j < PS_PAGE_BUFFERS; j++) {
+ for(j = 0; j < adapter->rx_ps_pages; j++) {
if(!ps_page->ps_page[j]) break;
pci_unmap_single(pdev,
ps_page_dma->ps_page_dma[j],
@@ -1534,8 +1953,22 @@ e1000_clean_rx_ring(struct e1000_adapter *adapter)
rx_ring->next_to_clean = 0;
rx_ring->next_to_use = 0;
- E1000_WRITE_REG(&adapter->hw, RDH, 0);
- E1000_WRITE_REG(&adapter->hw, RDT, 0);
+ writel(0, adapter->hw.hw_addr + rx_ring->rdh);
+ writel(0, adapter->hw.hw_addr + rx_ring->rdt);
+}
+
+/**
+ * e1000_clean_all_rx_rings - Free Rx Buffers for all queues
+ * @adapter: board private structure
+ **/
+
+static void
+e1000_clean_all_rx_rings(struct e1000_adapter *adapter)
+{
+ int i;
+
+ for (i = 0; i < adapter->num_queues; i++)
+ e1000_clean_rx_ring(adapter, &adapter->rx_ring[i]);
}
/* The 82542 2.0 (revision 2) needs to have the receive unit in reset
@@ -1556,7 +1989,7 @@ e1000_enter_82542_rst(struct e1000_adapter *adapter)
mdelay(5);
if(netif_running(netdev))
- e1000_clean_rx_ring(adapter);
+ e1000_clean_all_rx_rings(adapter);
}
static void
@@ -1576,7 +2009,7 @@ e1000_leave_82542_rst(struct e1000_adapter *adapter)
if(netif_running(netdev)) {
e1000_configure_rx(adapter);
- e1000_alloc_rx_buffers(adapter);
+ e1000_alloc_rx_buffers(adapter, &adapter->rx_ring[0]);
}
}
@@ -1607,6 +2040,22 @@ e1000_set_mac(struct net_device *netdev, void *p)
e1000_rar_set(&adapter->hw, adapter->hw.mac_addr, 0);
+ /* With 82571 controllers, LAA may be overwritten (with the default)
+ * due to controller reset from the other port. */
+ if (adapter->hw.mac_type == e1000_82571) {
+ /* activate the work around */
+ adapter->hw.laa_is_present = 1;
+
+ /* Hold a copy of the LAA in RAR[14] This is done so that
+ * between the time RAR[0] gets clobbered and the time it
+ * gets fixed (in e1000_watchdog), the actual LAA is in one
+ * of the RARs and no incoming packets directed to this port
+ * are dropped. Eventaully the LAA will be in RAR[0] and
+ * RAR[14] */
+ e1000_rar_set(&adapter->hw, adapter->hw.mac_addr,
+ E1000_RAR_ENTRIES - 1);
+ }
+
if(adapter->hw.mac_type == e1000_82542_rev2_0)
e1000_leave_82542_rst(adapter);
@@ -1629,12 +2078,13 @@ e1000_set_multi(struct net_device *netdev)
struct e1000_adapter *adapter = netdev_priv(netdev);
struct e1000_hw *hw = &adapter->hw;
struct dev_mc_list *mc_ptr;
- unsigned long flags;
uint32_t rctl;
uint32_t hash_value;
- int i;
+ int i, rar_entries = E1000_RAR_ENTRIES;
- spin_lock_irqsave(&adapter->tx_lock, flags);
+ /* reserve RAR[14] for LAA over-write work-around */
+ if (adapter->hw.mac_type == e1000_82571)
+ rar_entries--;
/* Check for Promiscuous and All Multicast modes */
@@ -1659,11 +2109,12 @@ e1000_set_multi(struct net_device *netdev)
/* load the first 14 multicast address into the exact filters 1-14
* RAR 0 is used for the station MAC adddress
* if there are not 14 addresses, go ahead and clear the filters
+ * -- with 82571 controllers only 0-13 entries are filled here
*/
mc_ptr = netdev->mc_list;
- for(i = 1; i < E1000_RAR_ENTRIES; i++) {
- if(mc_ptr) {
+ for(i = 1; i < rar_entries; i++) {
+ if (mc_ptr) {
e1000_rar_set(hw, mc_ptr->dmi_addr, i);
mc_ptr = mc_ptr->next;
} else {
@@ -1686,8 +2137,6 @@ e1000_set_multi(struct net_device *netdev)
if(hw->mac_type == e1000_82542_rev2_0)
e1000_leave_82542_rst(adapter);
-
- spin_unlock_irqrestore(&adapter->tx_lock, flags);
}
/* Need to wait a few seconds after link up to get diagnostic information from
@@ -1759,7 +2208,7 @@ static void
e1000_watchdog_task(struct e1000_adapter *adapter)
{
struct net_device *netdev = adapter->netdev;
- struct e1000_desc_ring *txdr = &adapter->tx_ring;
+ struct e1000_tx_ring *txdr = &adapter->tx_ring[0];
uint32_t link;
e1000_check_for_link(&adapter->hw);
@@ -1818,8 +2267,8 @@ e1000_watchdog_task(struct e1000_adapter *adapter)
e1000_update_adaptive(&adapter->hw);
- if(!netif_carrier_ok(netdev)) {
- if(E1000_DESC_UNUSED(txdr) + 1 < txdr->count) {
+ if (adapter->num_queues == 1 && !netif_carrier_ok(netdev)) {
+ if (E1000_DESC_UNUSED(txdr) + 1 < txdr->count) {
/* 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.
@@ -1847,6 +2296,11 @@ e1000_watchdog_task(struct e1000_adapter *adapter)
/* Force detection of hung controller every watchdog period */
adapter->detect_tx_hung = TRUE;
+ /* With 82571 controllers, LAA may be overwritten due to controller
+ * reset from the other port. Set the appropriate LAA in RAR[0] */
+ if (adapter->hw.mac_type == e1000_82571 && adapter->hw.laa_is_present)
+ e1000_rar_set(&adapter->hw, adapter->hw.mac_addr, 0);
+
/* Reset the timer */
mod_timer(&adapter->watchdog_timer, jiffies + 2 * HZ);
}
@@ -1859,7 +2313,8 @@ e1000_watchdog_task(struct e1000_adapter *adapter)
#define E1000_TX_FLAGS_VLAN_SHIFT 16
static inline int
-e1000_tso(struct e1000_adapter *adapter, struct sk_buff *skb)
+e1000_tso(struct e1000_adapter *adapter, struct e1000_tx_ring *tx_ring,
+ struct sk_buff *skb)
{
#ifdef NETIF_F_TSO
struct e1000_context_desc *context_desc;
@@ -1910,8 +2365,8 @@ e1000_tso(struct e1000_adapter *adapter, struct sk_buff *skb)
cmd_length |= (E1000_TXD_CMD_DEXT | E1000_TXD_CMD_TSE |
E1000_TXD_CMD_TCP | (skb->len - (hdr_len)));
- i = adapter->tx_ring.next_to_use;
- context_desc = E1000_CONTEXT_DESC(adapter->tx_ring, i);
+ i = tx_ring->next_to_use;
+ context_desc = E1000_CONTEXT_DESC(*tx_ring, i);
context_desc->lower_setup.ip_fields.ipcss = ipcss;
context_desc->lower_setup.ip_fields.ipcso = ipcso;
@@ -1923,8 +2378,8 @@ e1000_tso(struct e1000_adapter *adapter, struct sk_buff *skb)
context_desc->tcp_seg_setup.fields.hdr_len = hdr_len;
context_desc->cmd_and_length = cpu_to_le32(cmd_length);
- if(++i == adapter->tx_ring.count) i = 0;
- adapter->tx_ring.next_to_use = i;
+ if (++i == tx_ring->count) i = 0;
+ tx_ring->next_to_use = i;
return 1;
}
@@ -1934,7 +2389,8 @@ e1000_tso(struct e1000_adapter *adapter, struct sk_buff *skb)
}
static inline boolean_t
-e1000_tx_csum(struct e1000_adapter *adapter, struct sk_buff *skb)
+e1000_tx_csum(struct e1000_adapter *adapter, struct e1000_tx_ring *tx_ring,
+ struct sk_buff *skb)
{
struct e1000_context_desc *context_desc;
unsigned int i;
@@ -1943,8 +2399,8 @@ e1000_tx_csum(struct e1000_adapter *adapter, struct sk_buff *skb)
if(likely(skb->ip_summed == CHECKSUM_HW)) {
css = skb->h.raw - skb->data;
- i = adapter->tx_ring.next_to_use;
- context_desc = E1000_CONTEXT_DESC(adapter->tx_ring, i);
+ i = tx_ring->next_to_use;
+ context_desc = E1000_CONTEXT_DESC(*tx_ring, i);
context_desc->upper_setup.tcp_fields.tucss = css;
context_desc->upper_setup.tcp_fields.tucso = css + skb->csum;
@@ -1952,8 +2408,8 @@ e1000_tx_csum(struct e1000_adapter *adapter, struct sk_buff *skb)
context_desc->tcp_seg_setup.data = 0;
context_desc->cmd_and_length = cpu_to_le32(E1000_TXD_CMD_DEXT);
- if(unlikely(++i == adapter->tx_ring.count)) i = 0;
- adapter->tx_ring.next_to_use = i;
+ if (unlikely(++i == tx_ring->count)) i = 0;
+ tx_ring->next_to_use = i;
return TRUE;
}
@@ -1965,11 +2421,10 @@ e1000_tx_csum(struct e1000_adapter *adapter, struct sk_buff *skb)
#define E1000_MAX_DATA_PER_TXD (1<<E1000_MAX_TXD_PWR)
static inline int
-e1000_tx_map(struct e1000_adapter *adapter, struct sk_buff *skb,
- unsigned int first, unsigned int max_per_txd,
- unsigned int nr_frags, unsigned int mss)
+e1000_tx_map(struct e1000_adapter *adapter, struct e1000_tx_ring *tx_ring,
+ struct sk_buff *skb, unsigned int first, unsigned int max_per_txd,
+ unsigned int nr_frags, unsigned int mss)
{
- struct e1000_desc_ring *tx_ring = &adapter->tx_ring;
struct e1000_buffer *buffer_info;
unsigned int len = skb->len;
unsigned int offset = 0, size, count = 0, i;
@@ -2065,9 +2520,9 @@ e1000_tx_map(struct e1000_adapter *adapter, struct sk_buff *skb,
}
static inline void
-e1000_tx_queue(struct e1000_adapter *adapter, int count, int tx_flags)
+e1000_tx_queue(struct e1000_adapter *adapter, struct e1000_tx_ring *tx_ring,
+ int tx_flags, int count)
{
- struct e1000_desc_ring *tx_ring = &adapter->tx_ring;
struct e1000_tx_desc *tx_desc = NULL;
struct e1000_buffer *buffer_info;
uint32_t txd_upper = 0, txd_lower = E1000_TXD_CMD_IFCS;
@@ -2113,7 +2568,7 @@ e1000_tx_queue(struct e1000_adapter *adapter, int count, int tx_flags)
wmb();
tx_ring->next_to_use = i;
- E1000_WRITE_REG(&adapter->hw, TDT, i);
+ writel(i, adapter->hw.hw_addr + tx_ring->tdt);
}
/**
@@ -2206,6 +2661,7 @@ static int
e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
{
struct e1000_adapter *adapter = netdev_priv(netdev);
+ struct e1000_tx_ring *tx_ring;
unsigned int first, max_per_txd = E1000_MAX_DATA_PER_TXD;
unsigned int max_txd_pwr = E1000_MAX_TXD_PWR;
unsigned int tx_flags = 0;
@@ -2218,7 +2674,13 @@ e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
unsigned int f;
len -= skb->data_len;
- if(unlikely(skb->len <= 0)) {
+#ifdef CONFIG_E1000_MQ
+ tx_ring = *per_cpu_ptr(adapter->cpu_tx_ring, smp_processor_id());
+#else
+ tx_ring = adapter->tx_ring;
+#endif
+
+ if (unlikely(skb->len <= 0)) {
dev_kfree_skb_any(skb);
return NETDEV_TX_OK;
}
@@ -2262,21 +2724,42 @@ e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
if(adapter->pcix_82544)
count += nr_frags;
- local_irq_save(flags);
- if (!spin_trylock(&adapter->tx_lock)) {
- /* Collision - tell upper layer to requeue */
- local_irq_restore(flags);
- return NETDEV_TX_LOCKED;
- }
+#ifdef NETIF_F_TSO
+ /* TSO Workaround for 82571/2 Controllers -- if skb->data
+ * points to just header, pull a few bytes of payload from
+ * frags into skb->data */
+ if (skb_shinfo(skb)->tso_size) {
+ uint8_t hdr_len;
+ hdr_len = ((skb->h.raw - skb->data) + (skb->h.th->doff << 2));
+ if (skb->data_len && (hdr_len < (skb->len - skb->data_len)) &&
+ (adapter->hw.mac_type == e1000_82571 ||
+ adapter->hw.mac_type == e1000_82572)) {
+ unsigned int pull_size;
+ pull_size = min((unsigned int)4, skb->data_len);
+ if (!__pskb_pull_tail(skb, pull_size)) {
+ printk(KERN_ERR "__pskb_pull_tail failed.\n");
+ dev_kfree_skb_any(skb);
+ return -EFAULT;
+ }
+ }
+ }
+#endif
+
if(adapter->hw.tx_pkt_filtering && (adapter->hw.mac_type == e1000_82573) )
e1000_transfer_dhcp_info(adapter, skb);
+ local_irq_save(flags);
+ if (!spin_trylock(&tx_ring->tx_lock)) {
+ /* Collision - tell upper layer to requeue */
+ local_irq_restore(flags);
+ return NETDEV_TX_LOCKED;
+ }
/* need: count + 2 desc gap to keep tail from touching
* head, otherwise try next time */
- if(unlikely(E1000_DESC_UNUSED(&adapter->tx_ring) < count + 2)) {
+ if (unlikely(E1000_DESC_UNUSED(tx_ring) < count + 2)) {
netif_stop_queue(netdev);
- spin_unlock_irqrestore(&adapter->tx_lock, flags);
+ spin_unlock_irqrestore(&tx_ring->tx_lock, flags);
return NETDEV_TX_BUSY;
}
@@ -2284,7 +2767,7 @@ e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
if(unlikely(e1000_82547_fifo_workaround(adapter, skb))) {
netif_stop_queue(netdev);
mod_timer(&adapter->tx_fifo_stall_timer, jiffies);
- spin_unlock_irqrestore(&adapter->tx_lock, flags);
+ spin_unlock_irqrestore(&tx_ring->tx_lock, flags);
return NETDEV_TX_BUSY;
}
}
@@ -2294,37 +2777,37 @@ e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
tx_flags |= (vlan_tx_tag_get(skb) << E1000_TX_FLAGS_VLAN_SHIFT);
}
- first = adapter->tx_ring.next_to_use;
+ first = tx_ring->next_to_use;
- tso = e1000_tso(adapter, skb);
+ tso = e1000_tso(adapter, tx_ring, skb);
if (tso < 0) {
dev_kfree_skb_any(skb);
- spin_unlock_irqrestore(&adapter->tx_lock, flags);
+ spin_unlock_irqrestore(&tx_ring->tx_lock, flags);
return NETDEV_TX_OK;
}
if (likely(tso))
tx_flags |= E1000_TX_FLAGS_TSO;
- else if(likely(e1000_tx_csum(adapter, skb)))
+ else if (likely(e1000_tx_csum(adapter, tx_ring, skb)))
tx_flags |= E1000_TX_FLAGS_CSUM;
/* Old method was to assume IPv4 packet by default if TSO was enabled.
- * 82573 hardware supports TSO capabilities for IPv6 as well...
+ * 82571 hardware supports TSO capabilities for IPv6 as well...
* no longer assume, we must. */
- if(likely(skb->protocol == ntohs(ETH_P_IP)))
+ if (likely(skb->protocol == ntohs(ETH_P_IP)))
tx_flags |= E1000_TX_FLAGS_IPV4;
- e1000_tx_queue(adapter,
- e1000_tx_map(adapter, skb, first, max_per_txd, nr_frags, mss),
- tx_flags);
+ e1000_tx_queue(adapter, tx_ring, tx_flags,
+ e1000_tx_map(adapter, tx_ring, skb, first,
+ max_per_txd, nr_frags, mss));
netdev->trans_start = jiffies;
/* Make sure there is space in the ring for the next send. */
- if(unlikely(E1000_DESC_UNUSED(&adapter->tx_ring) < MAX_SKB_FRAGS + 2))
+ if (unlikely(E1000_DESC_UNUSED(tx_ring) < MAX_SKB_FRAGS + 2))
netif_stop_queue(netdev);
- spin_unlock_irqrestore(&adapter->tx_lock, flags);
+ spin_unlock_irqrestore(&tx_ring->tx_lock, flags);
return NETDEV_TX_OK;
}
@@ -2388,9 +2871,18 @@ e1000_change_mtu(struct net_device *netdev, int new_mtu)
return -EINVAL;
}
-#define MAX_STD_JUMBO_FRAME_SIZE 9216
+#define MAX_STD_JUMBO_FRAME_SIZE 9234
/* might want this to be bigger enum check... */
- if (adapter->hw.mac_type == e1000_82573 &&
+ /* 82571 controllers limit jumbo frame size to 10500 bytes */
+ if ((adapter->hw.mac_type == e1000_82571 ||
+ adapter->hw.mac_type == e1000_82572) &&
+ max_frame > MAX_STD_JUMBO_FRAME_SIZE) {
+ DPRINTK(PROBE, ERR, "MTU > 9216 bytes not supported "
+ "on 82571 and 82572 controllers.\n");
+ return -EINVAL;
+ }
+
+ if(adapter->hw.mac_type == e1000_82573 &&
max_frame > MAXIMUM_ETHERNET_FRAME_SIZE) {
DPRINTK(PROBE, ERR, "Jumbo Frames not supported "
"on 82573\n");
@@ -2578,6 +3070,29 @@ e1000_update_stats(struct e1000_adapter *adapter)
spin_unlock_irqrestore(&adapter->stats_lock, flags);
}
+#ifdef CONFIG_E1000_MQ
+void
+e1000_rx_schedule(void *data)
+{
+ struct net_device *poll_dev, *netdev = data;
+ struct e1000_adapter *adapter = netdev->priv;
+ int this_cpu = get_cpu();
+
+ poll_dev = *per_cpu_ptr(adapter->cpu_netdev, this_cpu);
+ if (poll_dev == NULL) {
+ put_cpu();
+ return;
+ }
+
+ if (likely(netif_rx_schedule_prep(poll_dev)))
+ __netif_rx_schedule(poll_dev);
+ else
+ e1000_irq_enable(adapter);
+
+ put_cpu();
+}
+#endif
+
/**
* e1000_intr - Interrupt Handler
* @irq: interrupt number
@@ -2592,8 +3107,8 @@ e1000_intr(int irq, void *data, struct pt_regs *regs)
struct e1000_adapter *adapter = netdev_priv(netdev);
struct e1000_hw *hw = &adapter->hw;
uint32_t icr = E1000_READ_REG(hw, ICR);
-#ifndef CONFIG_E1000_NAPI
- unsigned int i;
+#if defined(CONFIG_E1000_NAPI) && defined(CONFIG_E1000_MQ) || !defined(CONFIG_E1000_NAPI)
+ int i;
#endif
if(unlikely(!icr))
@@ -2605,17 +3120,31 @@ e1000_intr(int irq, void *data, struct pt_regs *regs)
}
#ifdef CONFIG_E1000_NAPI
- if(likely(netif_rx_schedule_prep(netdev))) {
-
- /* Disable interrupts and register for poll. The flush
- of the posted write is intentionally left out.
- */
-
- atomic_inc(&adapter->irq_sem);
- E1000_WRITE_REG(hw, IMC, ~0);
- __netif_rx_schedule(netdev);
+ atomic_inc(&adapter->irq_sem);
+ E1000_WRITE_REG(hw, IMC, ~0);
+ E1000_WRITE_FLUSH(hw);
+#ifdef CONFIG_E1000_MQ
+ if (atomic_read(&adapter->rx_sched_call_data.count) == 0) {
+ cpu_set(adapter->cpu_for_queue[0],
+ adapter->rx_sched_call_data.cpumask);
+ for (i = 1; i < adapter->num_queues; i++) {
+ cpu_set(adapter->cpu_for_queue[i],
+ adapter->rx_sched_call_data.cpumask);
+ atomic_inc(&adapter->irq_sem);
+ }
+ atomic_set(&adapter->rx_sched_call_data.count, i);
+ smp_call_async_mask(&adapter->rx_sched_call_data);
+ } else {
+ printk("call_data.count == %u\n", atomic_read(&adapter->rx_sched_call_data.count));
}
-#else
+#else /* if !CONFIG_E1000_MQ */
+ if (likely(netif_rx_schedule_prep(&adapter->polling_netdev[0])))
+ __netif_rx_schedule(&adapter->polling_netdev[0]);
+ else
+ e1000_irq_enable(adapter);
+#endif /* CONFIG_E1000_MQ */
+
+#else /* if !CONFIG_E1000_NAPI */
/* Writing IMC and IMS is needed for 82547.
Due to Hub Link bus being occupied, an interrupt
de-assertion message is not able to be sent.
@@ -2632,13 +3161,14 @@ e1000_intr(int irq, void *data, struct pt_regs *regs)
}
for(i = 0; i < E1000_MAX_INTR; i++)
- if(unlikely(!adapter->clean_rx(adapter) &
- !e1000_clean_tx_irq(adapter)))
+ if(unlikely(!adapter->clean_rx(adapter, adapter->rx_ring) &
+ !e1000_clean_tx_irq(adapter, adapter->tx_ring)))
break;
if(hw->mac_type == e1000_82547 || hw->mac_type == e1000_82547_rev_2)
e1000_irq_enable(adapter);
-#endif
+
+#endif /* CONFIG_E1000_NAPI */
return IRQ_HANDLED;
}
@@ -2650,22 +3180,37 @@ e1000_intr(int irq, void *data, struct pt_regs *regs)
**/
static int
-e1000_clean(struct net_device *netdev, int *budget)
+e1000_clean(struct net_device *poll_dev, int *budget)
{
- struct e1000_adapter *adapter = netdev_priv(netdev);
- int work_to_do = min(*budget, netdev->quota);
- int tx_cleaned;
- int work_done = 0;
+ struct e1000_adapter *adapter;
+ int work_to_do = min(*budget, poll_dev->quota);
+ int tx_cleaned, i = 0, work_done = 0;
+
+ /* Must NOT use netdev_priv macro here. */
+ adapter = poll_dev->priv;
- tx_cleaned = e1000_clean_tx_irq(adapter);
- adapter->clean_rx(adapter, &work_done, work_to_do);
+ /* Keep link state information with original netdev */
+ if (!netif_carrier_ok(adapter->netdev))
+ goto quit_polling;
+
+ while (poll_dev != &adapter->polling_netdev[i]) {
+ i++;
+ if (unlikely(i == adapter->num_queues))
+ BUG();
+ }
+
+ tx_cleaned = e1000_clean_tx_irq(adapter, &adapter->tx_ring[i]);
+ adapter->clean_rx(adapter, &adapter->rx_ring[i],
+ &work_done, work_to_do);
*budget -= work_done;
- netdev->quota -= work_done;
+ poll_dev->quota -= work_done;
- if ((!tx_cleaned && (work_done == 0)) || !netif_running(netdev)) {
/* If no Tx and not enough Rx work done, exit the polling mode */
- netif_rx_complete(netdev);
+ if((!tx_cleaned && (work_done == 0)) ||
+ !netif_running(adapter->netdev)) {
+quit_polling:
+ netif_rx_complete(poll_dev);
e1000_irq_enable(adapter);
return 0;
}
@@ -2680,9 +3225,9 @@ e1000_clean(struct net_device *netdev, int *budget)
**/
static boolean_t
-e1000_clean_tx_irq(struct e1000_adapter *adapter)
+e1000_clean_tx_irq(struct e1000_adapter *adapter,
+ struct e1000_tx_ring *tx_ring)
{
- struct e1000_desc_ring *tx_ring = &adapter->tx_ring;
struct net_device *netdev = adapter->netdev;
struct e1000_tx_desc *tx_desc, *eop_desc;
struct e1000_buffer *buffer_info;
@@ -2693,12 +3238,12 @@ e1000_clean_tx_irq(struct e1000_adapter *adapter)
eop = tx_ring->buffer_info[i].next_to_watch;
eop_desc = E1000_TX_DESC(*tx_ring, eop);
- while(eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) {
+ while (eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) {
/* Premature writeback of Tx descriptors clear (free buffers
* and unmap pci_mapping) previous_buffer_info */
- if (likely(adapter->previous_buffer_info.skb != NULL)) {
+ if (likely(tx_ring->previous_buffer_info.skb != NULL)) {
e1000_unmap_and_free_tx_resource(adapter,
- &adapter->previous_buffer_info);
+ &tx_ring->previous_buffer_info);
}
for(cleaned = FALSE; !cleaned; ) {
@@ -2714,7 +3259,7 @@ e1000_clean_tx_irq(struct e1000_adapter *adapter)
#ifdef NETIF_F_TSO
} else {
if (cleaned) {
- memcpy(&adapter->previous_buffer_info,
+ memcpy(&tx_ring->previous_buffer_info,
buffer_info,
sizeof(struct e1000_buffer));
memset(buffer_info, 0,
@@ -2732,6 +3277,8 @@ e1000_clean_tx_irq(struct e1000_adapter *adapter)
if(unlikely(++i == tx_ring->count)) i = 0;
}
+
+ tx_ring->pkt++;
eop = tx_ring->buffer_info[i].next_to_watch;
eop_desc = E1000_TX_DESC(*tx_ring, eop);
@@ -2739,15 +3286,15 @@ e1000_clean_tx_irq(struct e1000_adapter *adapter)
tx_ring->next_to_clean = i;
- spin_lock(&adapter->tx_lock);
+ spin_lock(&tx_ring->tx_lock);
if(unlikely(cleaned && netif_queue_stopped(netdev) &&
netif_carrier_ok(netdev)))
netif_wake_queue(netdev);
- spin_unlock(&adapter->tx_lock);
- if(adapter->detect_tx_hung) {
+ spin_unlock(&tx_ring->tx_lock);
+ if (adapter->detect_tx_hung) {
/* Detect a transmit hang in hardware, this serializes the
* check with the clearing of time_stamp and movement of i */
adapter->detect_tx_hung = FALSE;
@@ -2771,8 +3318,8 @@ e1000_clean_tx_irq(struct e1000_adapter *adapter)
" next_to_watch <%x>\n"
" jiffies <%lx>\n"
" next_to_watch.status <%x>\n",
- E1000_READ_REG(&adapter->hw, TDH),
- E1000_READ_REG(&adapter->hw, TDT),
+ readl(adapter->hw.hw_addr + tx_ring->tdh),
+ readl(adapter->hw.hw_addr + tx_ring->tdt),
tx_ring->next_to_use,
i,
(unsigned long long)tx_ring->buffer_info[i].dma,
@@ -2784,12 +3331,10 @@ e1000_clean_tx_irq(struct e1000_adapter *adapter)
}
}
#ifdef NETIF_F_TSO
-
- if( unlikely(!(eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) &&
- time_after(jiffies, adapter->previous_buffer_info.time_stamp + HZ)))
+ if (unlikely(!(eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) &&
+ time_after(jiffies, tx_ring->previous_buffer_info.time_stamp + HZ)))
e1000_unmap_and_free_tx_resource(
- adapter, &adapter->previous_buffer_info);
-
+ adapter, &tx_ring->previous_buffer_info);
#endif
return cleaned;
}
@@ -2852,13 +3397,14 @@ e1000_rx_checksum(struct e1000_adapter *adapter,
static boolean_t
#ifdef CONFIG_E1000_NAPI
-e1000_clean_rx_irq(struct e1000_adapter *adapter, int *work_done,
- int work_to_do)
+e1000_clean_rx_irq(struct e1000_adapter *adapter,
+ struct e1000_rx_ring *rx_ring,
+ int *work_done, int work_to_do)
#else
-e1000_clean_rx_irq(struct e1000_adapter *adapter)
+e1000_clean_rx_irq(struct e1000_adapter *adapter,
+ struct e1000_rx_ring *rx_ring)
#endif
{
- struct e1000_desc_ring *rx_ring = &adapter->rx_ring;
struct net_device *netdev = adapter->netdev;
struct pci_dev *pdev = adapter->pdev;
struct e1000_rx_desc *rx_desc;
@@ -2944,6 +3490,7 @@ e1000_clean_rx_irq(struct e1000_adapter *adapter)
}
#endif /* CONFIG_E1000_NAPI */
netdev->last_rx = jiffies;
+ rx_ring->pkt++;
next_desc:
rx_desc->status = 0;
@@ -2953,7 +3500,7 @@ next_desc:
rx_desc = E1000_RX_DESC(*rx_ring, i);
}
rx_ring->next_to_clean = i;
- adapter->alloc_rx_buf(adapter);
+ adapter->alloc_rx_buf(adapter, rx_ring);
return cleaned;
}
@@ -2965,13 +3512,14 @@ next_desc:
static boolean_t
#ifdef CONFIG_E1000_NAPI
-e1000_clean_rx_irq_ps(struct e1000_adapter *adapter, int *work_done,
- int work_to_do)
+e1000_clean_rx_irq_ps(struct e1000_adapter *adapter,
+ struct e1000_rx_ring *rx_ring,
+ int *work_done, int work_to_do)
#else
-e1000_clean_rx_irq_ps(struct e1000_adapter *adapter)
+e1000_clean_rx_irq_ps(struct e1000_adapter *adapter,
+ struct e1000_rx_ring *rx_ring)
#endif
{
- struct e1000_desc_ring *rx_ring = &adapter->rx_ring;
union e1000_rx_desc_packet_split *rx_desc;
struct net_device *netdev = adapter->netdev;
struct pci_dev *pdev = adapter->pdev;
@@ -3027,7 +3575,7 @@ e1000_clean_rx_irq_ps(struct e1000_adapter *adapter)
/* Good Receive */
skb_put(skb, length);
- for(j = 0; j < PS_PAGE_BUFFERS; j++) {
+ for(j = 0; j < adapter->rx_ps_pages; j++) {
if(!(length = le16_to_cpu(rx_desc->wb.upper.length[j])))
break;
@@ -3048,11 +3596,13 @@ e1000_clean_rx_irq_ps(struct e1000_adapter *adapter)
rx_desc->wb.lower.hi_dword.csum_ip.csum, skb);
skb->protocol = eth_type_trans(skb, netdev);
-#ifdef HAVE_RX_ZERO_COPY
if(likely(rx_desc->wb.upper.header_status &
- E1000_RXDPS_HDRSTAT_HDRSP))
+ E1000_RXDPS_HDRSTAT_HDRSP)) {
+ adapter->rx_hdr_split++;
+#ifdef HAVE_RX_ZERO_COPY
skb_shinfo(skb)->zero_copy = TRUE;
#endif
+ }
#ifdef CONFIG_E1000_NAPI
if(unlikely(adapter->vlgrp && (staterr & E1000_RXD_STAT_VP))) {
vlan_hwaccel_receive_skb(skb, adapter->vlgrp,
@@ -3071,6 +3621,7 @@ e1000_clean_rx_irq_ps(struct e1000_adapter *adapter)
}
#endif /* CONFIG_E1000_NAPI */
netdev->last_rx = jiffies;
+ rx_ring->pkt++;
next_desc:
rx_desc->wb.middle.status_error &= ~0xFF;
@@ -3081,7 +3632,7 @@ next_desc:
staterr = le32_to_cpu(rx_desc->wb.middle.status_error);
}
rx_ring->next_to_clean = i;
- adapter->alloc_rx_buf(adapter);
+ adapter->alloc_rx_buf(adapter, rx_ring);
return cleaned;
}
@@ -3092,9 +3643,9 @@ next_desc:
**/
static void
-e1000_alloc_rx_buffers(struct e1000_adapter *adapter)
+e1000_alloc_rx_buffers(struct e1000_adapter *adapter,
+ struct e1000_rx_ring *rx_ring)
{
- struct e1000_desc_ring *rx_ring = &adapter->rx_ring;
struct net_device *netdev = adapter->netdev;
struct pci_dev *pdev = adapter->pdev;
struct e1000_rx_desc *rx_desc;
@@ -3178,7 +3729,7 @@ e1000_alloc_rx_buffers(struct e1000_adapter *adapter)
* applicable for weak-ordered memory model archs,
* such as IA-64). */
wmb();
- E1000_WRITE_REG(&adapter->hw, RDT, i);
+ writel(i, adapter->hw.hw_addr + rx_ring->rdt);
}
if(unlikely(++i == rx_ring->count)) i = 0;
@@ -3194,9 +3745,9 @@ e1000_alloc_rx_buffers(struct e1000_adapter *adapter)
**/
static void
-e1000_alloc_rx_buffers_ps(struct e1000_adapter *adapter)
+e1000_alloc_rx_buffers_ps(struct e1000_adapter *adapter,
+ struct e1000_rx_ring *rx_ring)
{
- struct e1000_desc_ring *rx_ring = &adapter->rx_ring;
struct net_device *netdev = adapter->netdev;
struct pci_dev *pdev = adapter->pdev;
union e1000_rx_desc_packet_split *rx_desc;
@@ -3215,22 +3766,26 @@ e1000_alloc_rx_buffers_ps(struct e1000_adapter *adapter)
rx_desc = E1000_RX_DESC_PS(*rx_ring, i);
for(j = 0; j < PS_PAGE_BUFFERS; j++) {
- if(unlikely(!ps_page->ps_page[j])) {
- ps_page->ps_page[j] =
- alloc_page(GFP_ATOMIC);
- if(unlikely(!ps_page->ps_page[j]))
- goto no_buffers;
- ps_page_dma->ps_page_dma[j] =
- pci_map_page(pdev,
- ps_page->ps_page[j],
- 0, PAGE_SIZE,
- PCI_DMA_FROMDEVICE);
- }
- /* Refresh the desc even if buffer_addrs didn't
- * change because each write-back erases this info.
- */
- rx_desc->read.buffer_addr[j+1] =
- cpu_to_le64(ps_page_dma->ps_page_dma[j]);
+ if (j < adapter->rx_ps_pages) {
+ if (likely(!ps_page->ps_page[j])) {
+ ps_page->ps_page[j] =
+ alloc_page(GFP_ATOMIC);
+ if (unlikely(!ps_page->ps_page[j]))
+ goto no_buffers;
+ ps_page_dma->ps_page_dma[j] =
+ pci_map_page(pdev,
+ ps_page->ps_page[j],
+ 0, PAGE_SIZE,
+ PCI_DMA_FROMDEVICE);
+ }
+ /* Refresh the desc even if buffer_addrs didn't
+ * change because each write-back erases
+ * this info.
+ */
+ rx_desc->read.buffer_addr[j+1] =
+ cpu_to_le64(ps_page_dma->ps_page_dma[j]);
+ } else
+ rx_desc->read.buffer_addr[j+1] = ~0;
}
skb = dev_alloc_skb(adapter->rx_ps_bsize0 + NET_IP_ALIGN);
@@ -3264,7 +3819,7 @@ e1000_alloc_rx_buffers_ps(struct e1000_adapter *adapter)
* descriptors are 32 bytes...so we increment tail
* twice as much.
*/
- E1000_WRITE_REG(&adapter->hw, RDT, i<<1);
+ writel(i<<1, adapter->hw.hw_addr + rx_ring->rdt);
}
if(unlikely(++i == rx_ring->count)) i = 0;
@@ -3640,6 +4195,7 @@ e1000_set_spd_dplx(struct e1000_adapter *adapter, uint16_t spddplx)
return 0;
}
+#ifdef CONFIG_PM
static int
e1000_suspend(struct pci_dev *pdev, pm_message_t state)
{
@@ -3715,6 +4271,12 @@ e1000_suspend(struct pci_dev *pdev, pm_message_t state)
}
switch(adapter->hw.mac_type) {
+ case e1000_82571:
+ case e1000_82572:
+ ctrl_ext = E1000_READ_REG(&adapter->hw, CTRL_EXT);
+ E1000_WRITE_REG(&adapter->hw, CTRL_EXT,
+ ctrl_ext & ~E1000_CTRL_EXT_DRV_LOAD);
+ break;
case e1000_82573:
swsm = E1000_READ_REG(&adapter->hw, SWSM);
E1000_WRITE_REG(&adapter->hw, SWSM,
@@ -3730,13 +4292,13 @@ e1000_suspend(struct pci_dev *pdev, pm_message_t state)
return 0;
}
-#ifdef CONFIG_PM
static int
e1000_resume(struct pci_dev *pdev)
{
struct net_device *netdev = pci_get_drvdata(pdev);
struct e1000_adapter *adapter = netdev_priv(netdev);
uint32_t manc, ret_val, swsm;
+ uint32_t ctrl_ext;
pci_set_power_state(pdev, PCI_D0);
pci_restore_state(pdev);
@@ -3762,6 +4324,12 @@ e1000_resume(struct pci_dev *pdev)
}
switch(adapter->hw.mac_type) {
+ case e1000_82571:
+ case e1000_82572:
+ ctrl_ext = E1000_READ_REG(&adapter->hw, CTRL_EXT);
+ E1000_WRITE_REG(&adapter->hw, CTRL_EXT,
+ ctrl_ext | E1000_CTRL_EXT_DRV_LOAD);
+ break;
case e1000_82573:
swsm = E1000_READ_REG(&adapter->hw, SWSM);
E1000_WRITE_REG(&adapter->hw, SWSM,
@@ -3786,7 +4354,7 @@ e1000_netpoll(struct net_device *netdev)
struct e1000_adapter *adapter = netdev_priv(netdev);
disable_irq(adapter->pdev->irq);
e1000_intr(adapter->pdev->irq, netdev, NULL);
- e1000_clean_tx_irq(adapter);
+ e1000_clean_tx_irq(adapter, adapter->tx_ring);
enable_irq(adapter->pdev->irq);
}
#endif
diff --git a/drivers/net/e1000/e1000_param.c b/drivers/net/e1000/e1000_param.c
index 676247f9f1cc..38695d5b4637 100644
--- a/drivers/net/e1000/e1000_param.c
+++ b/drivers/net/e1000/e1000_param.c
@@ -306,7 +306,8 @@ e1000_check_options(struct e1000_adapter *adapter)
.def = E1000_DEFAULT_TXD,
.arg = { .r = { .min = E1000_MIN_TXD }}
};
- struct e1000_desc_ring *tx_ring = &adapter->tx_ring;
+ struct e1000_tx_ring *tx_ring = adapter->tx_ring;
+ int i;
e1000_mac_type mac_type = adapter->hw.mac_type;
opt.arg.r.max = mac_type < e1000_82544 ?
E1000_MAX_TXD : E1000_MAX_82544_TXD;
@@ -319,6 +320,8 @@ e1000_check_options(struct e1000_adapter *adapter)
} else {
tx_ring->count = opt.def;
}
+ for (i = 0; i < adapter->num_queues; i++)
+ tx_ring[i].count = tx_ring->count;
}
{ /* Receive Descriptor Count */
struct e1000_option opt = {
@@ -329,7 +332,8 @@ e1000_check_options(struct e1000_adapter *adapter)
.def = E1000_DEFAULT_RXD,
.arg = { .r = { .min = E1000_MIN_RXD }}
};
- struct e1000_desc_ring *rx_ring = &adapter->rx_ring;
+ struct e1000_rx_ring *rx_ring = adapter->rx_ring;
+ int i;
e1000_mac_type mac_type = adapter->hw.mac_type;
opt.arg.r.max = mac_type < e1000_82544 ? E1000_MAX_RXD :
E1000_MAX_82544_RXD;
@@ -342,6 +346,8 @@ e1000_check_options(struct e1000_adapter *adapter)
} else {
rx_ring->count = opt.def;
}
+ for (i = 0; i < adapter->num_queues; i++)
+ rx_ring[i].count = rx_ring->count;
}
{ /* Checksum Offload Enable/Disable */
struct e1000_option opt = {
diff --git a/drivers/net/eepro.c b/drivers/net/eepro.c
index dcb3028bb60f..a806dfe54d23 100644
--- a/drivers/net/eepro.c
+++ b/drivers/net/eepro.c
@@ -552,8 +552,7 @@ static int __init do_eepro_probe(struct net_device *dev)
{
unsigned short int WS[32]=WakeupSeq;
- if (check_region(WakeupPort, 2)==0) {
-
+ if (request_region(WakeupPort, 2, "eepro wakeup")) {
if (net_debug>5)
printk(KERN_DEBUG "Waking UP\n");
@@ -563,7 +562,10 @@ static int __init do_eepro_probe(struct net_device *dev)
outb_p(WS[i],WakeupPort);
if (net_debug>5) printk(KERN_DEBUG ": %#x ",WS[i]);
}
- } else printk(KERN_WARNING "Checkregion Failed!\n");
+
+ release_region(WakeupPort, 2);
+ } else
+ printk(KERN_WARNING "PnP wakeup region busy!\n");
}
#endif
@@ -705,7 +707,7 @@ static void __init eepro_print_info (struct net_device *dev)
dev->name, (unsigned)dev->base_addr);
break;
case LAN595FX:
- printk("%s: Intel EtherExpress Pro/10+ ISA\n at %#x,",
+ printk("%s: Intel EtherExpress Pro/10+ ISA\n at %#x,",
dev->name, (unsigned)dev->base_addr);
break;
case LAN595TX:
@@ -713,7 +715,7 @@ static void __init eepro_print_info (struct net_device *dev)
dev->name, (unsigned)dev->base_addr);
break;
case LAN595:
- printk("%s: Intel 82595-based lan card at %#x,",
+ printk("%s: Intel 82595-based lan card at %#x,",
dev->name, (unsigned)dev->base_addr);
}
@@ -726,7 +728,7 @@ static void __init eepro_print_info (struct net_device *dev)
if (dev->irq > 2)
printk(", IRQ %d, %s.\n", dev->irq, ifmap[dev->if_port]);
- else
+ else
printk(", %s.\n", ifmap[dev->if_port]);
if (net_debug > 3) {
@@ -756,7 +758,7 @@ static int __init eepro_probe1(struct net_device *dev, int autoprobe)
int err;
/* Grab the region so we can find another board if autoIRQ fails. */
- if (!request_region(ioaddr, EEPRO_IO_EXTENT, DRV_NAME)) {
+ if (!request_region(ioaddr, EEPRO_IO_EXTENT, DRV_NAME)) {
if (!autoprobe)
printk(KERN_WARNING "EEPRO: io-port 0x%04x in use \n",
ioaddr);
@@ -838,15 +840,15 @@ static int __init eepro_probe1(struct net_device *dev, int autoprobe)
/* Mask off INT number */
int count = lp->word[1] & 7;
unsigned irqMask = lp->word[7];
-
+
while (count--)
irqMask &= irqMask - 1;
-
+
count = ffs(irqMask);
-
+
if (count)
dev->irq = count - 1;
-
+
if (dev->irq < 2) {
printk(KERN_ERR " Duh! illegal interrupt vector stored in EEPROM.\n");
goto exit;
@@ -854,7 +856,7 @@ static int __init eepro_probe1(struct net_device *dev, int autoprobe)
dev->irq = 9;
}
}
-
+
dev->open = eepro_open;
dev->stop = eepro_close;
dev->hard_start_xmit = eepro_send_packet;
@@ -863,7 +865,7 @@ static int __init eepro_probe1(struct net_device *dev, int autoprobe)
dev->tx_timeout = eepro_tx_timeout;
dev->watchdog_timeo = TX_TIMEOUT;
dev->ethtool_ops = &eepro_ethtool_ops;
-
+
/* print boot time info */
eepro_print_info(dev);
@@ -1047,8 +1049,8 @@ static int eepro_open(struct net_device *dev)
/* Initialize the RCV and XMT upper and lower limits */
- outb(lp->rcv_lower_limit >> 8, ioaddr + RCV_LOWER_LIMIT_REG);
- outb(lp->rcv_upper_limit >> 8, ioaddr + RCV_UPPER_LIMIT_REG);
+ outb(lp->rcv_lower_limit >> 8, ioaddr + RCV_LOWER_LIMIT_REG);
+ outb(lp->rcv_upper_limit >> 8, ioaddr + RCV_UPPER_LIMIT_REG);
outb(lp->xmt_lower_limit >> 8, ioaddr + lp->xmt_lower_limit_reg);
outb(lp->xmt_upper_limit >> 8, ioaddr + lp->xmt_upper_limit_reg);
@@ -1065,12 +1067,12 @@ static int eepro_open(struct net_device *dev)
eepro_clear_int(ioaddr);
/* Initialize RCV */
- outw(lp->rcv_lower_limit, ioaddr + RCV_BAR);
+ outw(lp->rcv_lower_limit, ioaddr + RCV_BAR);
lp->rx_start = lp->rcv_lower_limit;
- outw(lp->rcv_upper_limit | 0xfe, ioaddr + RCV_STOP);
+ outw(lp->rcv_upper_limit | 0xfe, ioaddr + RCV_STOP);
/* Initialize XMT */
- outw(lp->xmt_lower_limit, ioaddr + lp->xmt_bar);
+ outw(lp->xmt_lower_limit, ioaddr + lp->xmt_bar);
lp->tx_start = lp->tx_end = lp->xmt_lower_limit;
lp->tx_last = 0;
@@ -1411,7 +1413,7 @@ set_multicast_list(struct net_device *dev)
outb(0x08, ioaddr + STATUS_REG);
if (i & 0x20) { /* command ABORTed */
- printk(KERN_NOTICE "%s: multicast setup failed.\n",
+ printk(KERN_NOTICE "%s: multicast setup failed.\n",
dev->name);
break;
} else if ((i & 0x0f) == 0x03) { /* MC-Done */
@@ -1512,7 +1514,7 @@ hardware_send_packet(struct net_device *dev, void *buf, short length)
end = last + (((length + 3) >> 1) << 1) + XMT_HEADER;
if (end >= lp->xmt_upper_limit + 2) { /* the transmit buffer is wrapped around */
- if ((lp->xmt_upper_limit + 2 - last) <= XMT_HEADER) {
+ if ((lp->xmt_upper_limit + 2 - last) <= XMT_HEADER) {
/* Arrrr!!!, must keep the xmt header together,
several days were lost to chase this one down. */
last = lp->xmt_lower_limit;
@@ -1643,7 +1645,7 @@ eepro_rx(struct net_device *dev)
else if (rcv_status & 0x0800)
lp->stats.rx_crc_errors++;
- printk(KERN_DEBUG "%s: event = %#x, status = %#x, next = %#x, size = %#x\n",
+ printk(KERN_DEBUG "%s: event = %#x, status = %#x, next = %#x, size = %#x\n",
dev->name, rcv_event, rcv_status, rcv_next_frame, rcv_size);
}
@@ -1674,10 +1676,10 @@ eepro_transmit_interrupt(struct net_device *dev)
{
struct eepro_local *lp = netdev_priv(dev);
short ioaddr = dev->base_addr;
- short boguscount = 25;
+ short boguscount = 25;
short xmt_status;
- while ((lp->tx_start != lp->tx_end) && boguscount--) {
+ while ((lp->tx_start != lp->tx_end) && boguscount--) {
outw(lp->tx_start, ioaddr + HOST_ADDRESS_REG);
xmt_status = inw(ioaddr+IO_PORT);
@@ -1723,7 +1725,7 @@ static int eepro_ethtool_get_settings(struct net_device *dev,
{
struct eepro_local *lp = (struct eepro_local *)dev->priv;
- cmd->supported = SUPPORTED_10baseT_Half |
+ cmd->supported = SUPPORTED_10baseT_Half |
SUPPORTED_10baseT_Full |
SUPPORTED_Autoneg;
cmd->advertising = ADVERTISED_10baseT_Half |
@@ -1797,10 +1799,9 @@ MODULE_AUTHOR("Pascal Dupuis and others");
MODULE_DESCRIPTION("Intel i82595 ISA EtherExpressPro10/10+ driver");
MODULE_LICENSE("GPL");
-static int num_params;
-module_param_array(io, int, &num_params, 0);
-module_param_array(irq, int, &num_params, 0);
-module_param_array(mem, int, &num_params, 0);
+module_param_array(io, int, NULL, 0);
+module_param_array(irq, int, NULL, 0);
+module_param_array(mem, int, NULL, 0);
module_param(autodetect, int, 0);
MODULE_PARM_DESC(io, "EtherExpress Pro/10 I/O base addres(es)");
MODULE_PARM_DESC(irq, "EtherExpress Pro/10 IRQ number(s)");
diff --git a/drivers/net/epic100.c b/drivers/net/epic100.c
index 87f522738bfc..f119ec4e89ea 100644
--- a/drivers/net/epic100.c
+++ b/drivers/net/epic100.c
@@ -1334,7 +1334,7 @@ static void epic_rx_err(struct net_device *dev, struct epic_private *ep)
static int epic_poll(struct net_device *dev, int *budget)
{
struct epic_private *ep = dev->priv;
- int work_done, orig_budget;
+ int work_done = 0, orig_budget;
long ioaddr = dev->base_addr;
orig_budget = (*budget > dev->quota) ? dev->quota : *budget;
@@ -1343,7 +1343,7 @@ rx_action:
epic_tx(dev, ep);
- work_done = epic_rx(dev, *budget);
+ work_done += epic_rx(dev, *budget);
epic_rx_err(dev, ep);
diff --git a/drivers/net/fec.c b/drivers/net/fec.c
index 85504fb900da..bd6983d1afba 100644
--- a/drivers/net/fec.c
+++ b/drivers/net/fec.c
@@ -18,8 +18,8 @@
* Much better multiple PHY support by Magnus Damm.
* Copyright (c) 2000 Ericsson Radio Systems AB.
*
- * Support for FEC controller of ColdFire/5270/5271/5272/5274/5275/5280/5282.
- * Copyright (c) 2001-2004 Greg Ungerer (gerg@snapgear.com)
+ * Support for FEC controller of ColdFire processors.
+ * Copyright (c) 2001-2005 Greg Ungerer (gerg@snapgear.com)
*
* Bug fixes and cleanup by Philippe De Muyter (phdm@macqel.be)
* Copyright (c) 2004-2005 Macq Electronique SA.
@@ -50,7 +50,8 @@
#include <asm/pgtable.h>
#if defined(CONFIG_M523x) || defined(CONFIG_M527x) || \
- defined(CONFIG_M5272) || defined(CONFIG_M528x)
+ defined(CONFIG_M5272) || defined(CONFIG_M528x) || \
+ defined(CONFIG_M520x)
#include <asm/coldfire.h>
#include <asm/mcfsim.h>
#include "fec.h"
@@ -77,6 +78,8 @@ static unsigned int fec_hw[] = {
(MCF_MBAR + 0x1800),
#elif defined(CONFIG_M523x) || defined(CONFIG_M528x)
(MCF_MBAR + 0x1000),
+#elif defined(CONFIG_M520x)
+ (MCF_MBAR+0x30000),
#else
&(((immap_t *)IMAP_ADDR)->im_cpm.cp_fec),
#endif
@@ -139,6 +142,10 @@ typedef struct {
#define TX_RING_SIZE 16 /* Must be power of two */
#define TX_RING_MOD_MASK 15 /* for this to work */
+#if (((RX_RING_SIZE + TX_RING_SIZE) * 8) > PAGE_SIZE)
+#error "FEC: descriptor ring size contants too large"
+#endif
+
/* Interrupt events/masks.
*/
#define FEC_ENET_HBERR ((uint)0x80000000) /* Heartbeat error */
@@ -164,7 +171,8 @@ typedef struct {
* size bits. Other FEC hardware does not, so we need to take that into
* account when setting it.
*/
-#if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x)
+#if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) || \
+ defined(CONFIG_M520x)
#define OPT_FRAME_SIZE (PKT_MAXBUF_SIZE << 16)
#else
#define OPT_FRAME_SIZE 0
@@ -1137,6 +1145,65 @@ static phy_info_t const phy_info_ks8721bl = {
};
/* ------------------------------------------------------------------------- */
+/* register definitions for the DP83848 */
+
+#define MII_DP8384X_PHYSTST 16 /* PHY Status Register */
+
+static void mii_parse_dp8384x_sr2(uint mii_reg, struct net_device *dev)
+{
+ struct fec_enet_private *fep = dev->priv;
+ volatile uint *s = &(fep->phy_status);
+
+ *s &= ~(PHY_STAT_SPMASK | PHY_STAT_LINK | PHY_STAT_ANC);
+
+ /* Link up */
+ if (mii_reg & 0x0001) {
+ fep->link = 1;
+ *s |= PHY_STAT_LINK;
+ } else
+ fep->link = 0;
+ /* Status of link */
+ if (mii_reg & 0x0010) /* Autonegotioation complete */
+ *s |= PHY_STAT_ANC;
+ if (mii_reg & 0x0002) { /* 10MBps? */
+ if (mii_reg & 0x0004) /* Full Duplex? */
+ *s |= PHY_STAT_10FDX;
+ else
+ *s |= PHY_STAT_10HDX;
+ } else { /* 100 Mbps? */
+ if (mii_reg & 0x0004) /* Full Duplex? */
+ *s |= PHY_STAT_100FDX;
+ else
+ *s |= PHY_STAT_100HDX;
+ }
+ if (mii_reg & 0x0008)
+ *s |= PHY_STAT_FAULT;
+}
+
+static phy_info_t phy_info_dp83848= {
+ 0x020005c9,
+ "DP83848",
+
+ (const phy_cmd_t []) { /* config */
+ { mk_mii_read(MII_REG_CR), mii_parse_cr },
+ { mk_mii_read(MII_REG_ANAR), mii_parse_anar },
+ { mk_mii_read(MII_DP8384X_PHYSTST), mii_parse_dp8384x_sr2 },
+ { mk_mii_end, }
+ },
+ (const phy_cmd_t []) { /* startup - enable interrupts */
+ { mk_mii_write(MII_REG_CR, 0x1200), NULL }, /* autonegotiate */
+ { mk_mii_read(MII_REG_SR), mii_parse_sr },
+ { mk_mii_end, }
+ },
+ (const phy_cmd_t []) { /* ack_int - never happens, no interrupt */
+ { mk_mii_end, }
+ },
+ (const phy_cmd_t []) { /* shutdown */
+ { mk_mii_end, }
+ },
+};
+
+/* ------------------------------------------------------------------------- */
static phy_info_t const * const phy_info[] = {
&phy_info_lxt970,
@@ -1144,6 +1211,7 @@ static phy_info_t const * const phy_info[] = {
&phy_info_qs6612,
&phy_info_am79c874,
&phy_info_ks8721bl,
+ &phy_info_dp83848,
NULL
};
@@ -1422,6 +1490,134 @@ static void __inline__ fec_uncache(unsigned long addr)
/* ------------------------------------------------------------------------- */
+#elif defined(CONFIG_M520x)
+
+/*
+ * Code specific to Coldfire 520x
+ */
+static void __inline__ fec_request_intrs(struct net_device *dev)
+{
+ struct fec_enet_private *fep;
+ int b;
+ static const struct idesc {
+ char *name;
+ unsigned short irq;
+ } *idp, id[] = {
+ { "fec(TXF)", 23 },
+ { "fec(TXB)", 24 },
+ { "fec(TXFIFO)", 25 },
+ { "fec(TXCR)", 26 },
+ { "fec(RXF)", 27 },
+ { "fec(RXB)", 28 },
+ { "fec(MII)", 29 },
+ { "fec(LC)", 30 },
+ { "fec(HBERR)", 31 },
+ { "fec(GRA)", 32 },
+ { "fec(EBERR)", 33 },
+ { "fec(BABT)", 34 },
+ { "fec(BABR)", 35 },
+ { NULL },
+ };
+
+ fep = netdev_priv(dev);
+ b = 64 + 13;
+
+ /* Setup interrupt handlers. */
+ for (idp = id; idp->name; idp++) {
+ if (request_irq(b+idp->irq,fec_enet_interrupt,0,idp->name,dev)!=0)
+ printk("FEC: Could not allocate %s IRQ(%d)!\n", idp->name, b+idp->irq);
+ }
+
+ /* Unmask interrupts at ColdFire interrupt controller */
+ {
+ volatile unsigned char *icrp;
+ volatile unsigned long *imrp;
+
+ icrp = (volatile unsigned char *) (MCF_IPSBAR + MCFICM_INTC0 +
+ MCFINTC_ICR0);
+ for (b = 36; (b < 49); b++)
+ icrp[b] = 0x04;
+ imrp = (volatile unsigned long *) (MCF_IPSBAR + MCFICM_INTC0 +
+ MCFINTC_IMRH);
+ *imrp &= ~0x0001FFF0;
+ }
+ *(volatile unsigned char *)(MCF_IPSBAR + MCF_GPIO_PAR_FEC) |= 0xf0;
+ *(volatile unsigned char *)(MCF_IPSBAR + MCF_GPIO_PAR_FECI2C) |= 0x0f;
+}
+
+static void __inline__ fec_set_mii(struct net_device *dev, struct fec_enet_private *fep)
+{
+ volatile fec_t *fecp;
+
+ fecp = fep->hwp;
+ fecp->fec_r_cntrl = OPT_FRAME_SIZE | 0x04;
+ fecp->fec_x_cntrl = 0x00;
+
+ /*
+ * Set MII speed to 2.5 MHz
+ * See 5282 manual section 17.5.4.7: MSCR
+ */
+ fep->phy_speed = ((((MCF_CLK / 2) / (2500000 / 10)) + 5) / 10) * 2;
+ fecp->fec_mii_speed = fep->phy_speed;
+
+ fec_restart(dev, 0);
+}
+
+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.
+ * If it is all 1's or 0's, use the default.
+ */
+ iap = FEC_FLASHMAC;
+ if ((iap[0] == 0) && (iap[1] == 0) && (iap[2] == 0) &&
+ (iap[3] == 0) && (iap[4] == 0) && (iap[5] == 0))
+ iap = fec_mac_default;
+ if ((iap[0] == 0xff) && (iap[1] == 0xff) && (iap[2] == 0xff) &&
+ (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);
+ iap = &tmpaddr[0];
+ }
+
+ memcpy(dev->dev_addr, iap, ETH_ALEN);
+
+ /* Adjust MAC if using default MAC address */
+ if (iap == fec_mac_default)
+ dev->dev_addr[ETH_ALEN-1] = fec_mac_default[ETH_ALEN-1] + fep->index;
+}
+
+static void __inline__ fec_enable_phy_intr(void)
+{
+}
+
+static void __inline__ fec_disable_phy_intr(void)
+{
+}
+
+static void __inline__ fec_phy_ack_intr(void)
+{
+}
+
+static void __inline__ fec_localhw_setup(void)
+{
+}
+
+static void __inline__ fec_uncache(unsigned long addr)
+{
+}
+
+/* ------------------------------------------------------------------------- */
+
#else
/*
@@ -1952,6 +2148,14 @@ int __init fec_enet_init(struct net_device *dev)
if (index >= FEC_MAX_PORTS)
return -ENXIO;
+ /* Allocate memory for buffer descriptors.
+ */
+ mem_addr = __get_free_page(GFP_KERNEL);
+ if (mem_addr == 0) {
+ printk("FEC: allocate descriptor memory failed?\n");
+ return -ENOMEM;
+ }
+
/* Create an Ethernet device instance.
*/
fecp = (volatile fec_t *) fec_hw[index];
@@ -1964,16 +2168,6 @@ int __init fec_enet_init(struct net_device *dev)
fecp->fec_ecntrl = 1;
udelay(10);
- /* Clear and enable interrupts */
- fecp->fec_ievent = 0xffc00000;
- fecp->fec_imask = (FEC_ENET_TXF | FEC_ENET_TXB |
- FEC_ENET_RXF | FEC_ENET_RXB | FEC_ENET_MII);
- fecp->fec_hash_table_high = 0;
- fecp->fec_hash_table_low = 0;
- fecp->fec_r_buff_size = PKT_MAXBLR_SIZE;
- fecp->fec_ecntrl = 2;
- fecp->fec_r_des_active = 0x01000000;
-
/* Set the Ethernet address. If using multiple Enets on the 8xx,
* this needs some work to get unique addresses.
*
@@ -1982,14 +2176,6 @@ int __init fec_enet_init(struct net_device *dev)
*/
fec_get_mac(dev);
- /* Allocate memory for buffer descriptors.
- */
- if (((RX_RING_SIZE + TX_RING_SIZE) * sizeof(cbd_t)) > PAGE_SIZE) {
- printk("FEC init error. Need more space.\n");
- printk("FEC initialization failed.\n");
- return 1;
- }
- mem_addr = __get_free_page(GFP_KERNEL);
cbd_base = (cbd_t *)mem_addr;
/* XXX: missing check for allocation failure */
@@ -2067,6 +2253,16 @@ int __init fec_enet_init(struct net_device *dev)
*/
fec_request_intrs(dev);
+ /* Clear and enable interrupts */
+ fecp->fec_ievent = 0xffc00000;
+ fecp->fec_imask = (FEC_ENET_TXF | FEC_ENET_TXB |
+ FEC_ENET_RXF | FEC_ENET_RXB | FEC_ENET_MII);
+ fecp->fec_hash_table_high = 0;
+ fecp->fec_hash_table_low = 0;
+ fecp->fec_r_buff_size = PKT_MAXBLR_SIZE;
+ fecp->fec_ecntrl = 2;
+ fecp->fec_r_des_active = 0x01000000;
+
dev->base_addr = (unsigned long)fecp;
/* The FEC Ethernet specific entries in the device structure. */
diff --git a/drivers/net/fec.h b/drivers/net/fec.h
index 045761b8a600..965c5c49fcdc 100644
--- a/drivers/net/fec.h
+++ b/drivers/net/fec.h
@@ -1,11 +1,10 @@
/****************************************************************************/
/*
- * fec.h -- Fast Ethernet Controller for Motorola ColdFire 5230,
- * 5231, 5232, 5234, 5235, 5270, 5271, 5272, 5274, 5275,
- * 5280 and 5282.
+ * fec.h -- Fast Ethernet Controller for Motorola ColdFire SoC
+ * processors.
*
- * (C) Copyright 2000-2003, Greg Ungerer (gerg@snapgear.com)
+ * (C) Copyright 2000-2005, Greg Ungerer (gerg@snapgear.com)
* (C) Copyright 2000-2001, Lineo (www.lineo.com)
*/
@@ -14,7 +13,8 @@
#define FEC_H
/****************************************************************************/
-#if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x)
+#if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) || \
+ defined(CONFIG_M520x)
/*
* Just figures, Motorola would have to change the offsets for
* registers in the same peripheral device on different models
diff --git a/drivers/net/fec_8xx/Kconfig b/drivers/net/fec_8xx/Kconfig
index db36ac3ea453..94e7a9af8705 100644
--- a/drivers/net/fec_8xx/Kconfig
+++ b/drivers/net/fec_8xx/Kconfig
@@ -1,6 +1,6 @@
config FEC_8XX
tristate "Motorola 8xx FEC driver"
- depends on NET_ETHERNET && 8xx && (NETTA || NETPHONE)
+ depends on NET_ETHERNET && FEC
select MII
config FEC_8XX_GENERIC_PHY
@@ -12,3 +12,9 @@ config FEC_8XX_DM9161_PHY
bool "Support DM9161 PHY"
depends on FEC_8XX
default n
+
+config FEC_8XX_LXT971_PHY
+ bool "Support LXT971/LXT972 PHY"
+ depends on FEC_8XX
+ default n
+
diff --git a/drivers/net/fec_8xx/fec_mii.c b/drivers/net/fec_8xx/fec_mii.c
index 803eb095cf8e..3b44ac1a7bfe 100644
--- a/drivers/net/fec_8xx/fec_mii.c
+++ b/drivers/net/fec_8xx/fec_mii.c
@@ -203,6 +203,39 @@ static void dm9161_shutdown(struct net_device *dev)
#endif
+#ifdef CONFIG_FEC_8XX_LXT971_PHY
+
+/* Support for LXT971/972 PHY */
+
+#define MII_LXT971_PCR 16 /* Port Control Register */
+#define MII_LXT971_SR2 17 /* Status Register 2 */
+#define MII_LXT971_IER 18 /* Interrupt Enable Register */
+#define MII_LXT971_ISR 19 /* Interrupt Status Register */
+#define MII_LXT971_LCR 20 /* LED Control Register */
+#define MII_LXT971_TCR 30 /* Transmit Control Register */
+
+static void lxt971_startup(struct net_device *dev)
+{
+ struct fec_enet_private *fep = netdev_priv(dev);
+
+ fec_mii_write(dev, fep->mii_if.phy_id, MII_LXT971_IER, 0x00F2);
+}
+
+static void lxt971_ack_int(struct net_device *dev)
+{
+ struct fec_enet_private *fep = netdev_priv(dev);
+
+ fec_mii_read(dev, fep->mii_if.phy_id, MII_LXT971_ISR);
+}
+
+static void lxt971_shutdown(struct net_device *dev)
+{
+ struct fec_enet_private *fep = netdev_priv(dev);
+
+ fec_mii_write(dev, fep->mii_if.phy_id, MII_LXT971_IER, 0x0000);
+}
+#endif
+
/**********************************************************************************/
static const struct phy_info phy_info[] = {
@@ -215,6 +248,15 @@ static const struct phy_info phy_info[] = {
.shutdown = dm9161_shutdown,
},
#endif
+#ifdef CONFIG_FEC_8XX_LXT971_PHY
+ {
+ .id = 0x0001378e,
+ .name = "LXT971/972",
+ .startup = lxt971_startup,
+ .ack_int = lxt971_ack_int,
+ .shutdown = lxt971_shutdown,
+ },
+#endif
#ifdef CONFIG_FEC_8XX_GENERIC_PHY
{
.id = 0,
diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c
index d6eefdb71c17..22aec6ed80f5 100644
--- a/drivers/net/forcedeth.c
+++ b/drivers/net/forcedeth.c
@@ -95,6 +95,8 @@
* of nv_remove
* 0.42: 06 Aug 2005: Fix lack of link speed initialization
* in the second (and later) nv_open call
+ * 0.43: 10 Aug 2005: Add support for tx checksum.
+ * 0.44: 20 Aug 2005: Add support for scatter gather and segmentation.
*
* Known bugs:
* We suspect that on some hardware no TX done interrupts are generated.
@@ -106,7 +108,7 @@
* DEV_NEED_TIMERIRQ will not harm you on sane hardware, only generating a few
* superfluous timer interrupts from the nic.
*/
-#define FORCEDETH_VERSION "0.41"
+#define FORCEDETH_VERSION "0.44"
#define DRV_NAME "forcedeth"
#include <linux/module.h>
@@ -145,6 +147,7 @@
#define DEV_NEED_LINKTIMER 0x0002 /* poll link settings. Relies on the timer irq */
#define DEV_HAS_LARGEDESC 0x0004 /* device supports jumbo frames and needs packet format 2 */
#define DEV_HAS_HIGH_DMA 0x0008 /* device supports 64bit dma */
+#define DEV_HAS_CHECKSUM 0x0010 /* device supports tx and rx checksum offloads */
enum {
NvRegIrqStatus = 0x000,
@@ -241,6 +244,9 @@ enum {
#define NVREG_TXRXCTL_IDLE 0x0008
#define NVREG_TXRXCTL_RESET 0x0010
#define NVREG_TXRXCTL_RXCHECK 0x0400
+#define NVREG_TXRXCTL_DESC_1 0
+#define NVREG_TXRXCTL_DESC_2 0x02100
+#define NVREG_TXRXCTL_DESC_3 0x02200
NvRegMIIStatus = 0x180,
#define NVREG_MIISTAT_ERROR 0x0001
#define NVREG_MIISTAT_LINKCHANGE 0x0008
@@ -335,6 +341,10 @@ typedef union _ring_type {
/* error and valid are the same for both */
#define NV_TX2_ERROR (1<<30)
#define NV_TX2_VALID (1<<31)
+#define NV_TX2_TSO (1<<28)
+#define NV_TX2_TSO_SHIFT 14
+#define NV_TX2_CHECKSUM_L3 (1<<27)
+#define NV_TX2_CHECKSUM_L4 (1<<26)
#define NV_RX_DESCRIPTORVALID (1<<16)
#define NV_RX_MISSEDFRAME (1<<17)
@@ -417,14 +427,14 @@ typedef union _ring_type {
/*
* desc_ver values:
- * This field has two purposes:
- * - Newer nics uses a different ring layout. The layout is selected by
- * comparing np->desc_ver with DESC_VER_xy.
- * - It contains bits that are forced on when writing to NvRegTxRxControl.
+ * The nic supports three different descriptor types:
+ * - DESC_VER_1: Original
+ * - DESC_VER_2: support for jumbo frames.
+ * - DESC_VER_3: 64-bit format.
*/
-#define DESC_VER_1 0x0
-#define DESC_VER_2 (0x02100|NVREG_TXRXCTL_RXCHECK)
-#define DESC_VER_3 (0x02200|NVREG_TXRXCTL_RXCHECK)
+#define DESC_VER_1 1
+#define DESC_VER_2 2
+#define DESC_VER_3 3
/* PHY defines */
#define PHY_OUI_MARVELL 0x5043
@@ -491,6 +501,7 @@ struct fe_priv {
u32 orig_mac[2];
u32 irqmask;
u32 desc_ver;
+ u32 txrxctl_bits;
void __iomem *base;
@@ -534,7 +545,7 @@ static inline struct fe_priv *get_nvpriv(struct net_device *dev)
static inline u8 __iomem *get_hwbase(struct net_device *dev)
{
- return get_nvpriv(dev)->base;
+ return ((struct fe_priv *)netdev_priv(dev))->base;
}
static inline void pci_push(u8 __iomem *base)
@@ -623,7 +634,7 @@ static int mii_rw(struct net_device *dev, int addr, int miireg, int value)
static int phy_reset(struct net_device *dev)
{
- struct fe_priv *np = get_nvpriv(dev);
+ struct fe_priv *np = netdev_priv(dev);
u32 miicontrol;
unsigned int tries = 0;
@@ -726,7 +737,7 @@ static int phy_init(struct net_device *dev)
static void nv_start_rx(struct net_device *dev)
{
- struct fe_priv *np = get_nvpriv(dev);
+ struct fe_priv *np = netdev_priv(dev);
u8 __iomem *base = get_hwbase(dev);
dprintk(KERN_DEBUG "%s: nv_start_rx\n", dev->name);
@@ -782,14 +793,14 @@ static void nv_stop_tx(struct net_device *dev)
static void nv_txrx_reset(struct net_device *dev)
{
- struct fe_priv *np = get_nvpriv(dev);
+ struct fe_priv *np = netdev_priv(dev);
u8 __iomem *base = get_hwbase(dev);
dprintk(KERN_DEBUG "%s: nv_txrx_reset\n", dev->name);
- writel(NVREG_TXRXCTL_BIT2 | NVREG_TXRXCTL_RESET | np->desc_ver, base + NvRegTxRxControl);
+ writel(NVREG_TXRXCTL_BIT2 | NVREG_TXRXCTL_RESET | np->txrxctl_bits, base + NvRegTxRxControl);
pci_push(base);
udelay(NV_TXRX_RESET_DELAY);
- writel(NVREG_TXRXCTL_BIT2 | np->desc_ver, base + NvRegTxRxControl);
+ writel(NVREG_TXRXCTL_BIT2 | np->txrxctl_bits, base + NvRegTxRxControl);
pci_push(base);
}
@@ -801,7 +812,7 @@ static void nv_txrx_reset(struct net_device *dev)
*/
static struct net_device_stats *nv_get_stats(struct net_device *dev)
{
- struct fe_priv *np = get_nvpriv(dev);
+ struct fe_priv *np = netdev_priv(dev);
/* It seems that the nic always generates interrupts and doesn't
* accumulate errors internally. Thus the current values in np->stats
@@ -817,7 +828,7 @@ static struct net_device_stats *nv_get_stats(struct net_device *dev)
*/
static int nv_alloc_rx(struct net_device *dev)
{
- struct fe_priv *np = get_nvpriv(dev);
+ struct fe_priv *np = netdev_priv(dev);
unsigned int refill_rx = np->refill_rx;
int nr;
@@ -861,7 +872,7 @@ static int nv_alloc_rx(struct net_device *dev)
static void nv_do_rx_refill(unsigned long data)
{
struct net_device *dev = (struct net_device *) data;
- struct fe_priv *np = get_nvpriv(dev);
+ struct fe_priv *np = netdev_priv(dev);
disable_irq(dev->irq);
if (nv_alloc_rx(dev)) {
@@ -875,7 +886,7 @@ static void nv_do_rx_refill(unsigned long data)
static void nv_init_rx(struct net_device *dev)
{
- struct fe_priv *np = get_nvpriv(dev);
+ struct fe_priv *np = netdev_priv(dev);
int i;
np->cur_rx = RX_RING;
@@ -889,15 +900,17 @@ static void nv_init_rx(struct net_device *dev)
static void nv_init_tx(struct net_device *dev)
{
- struct fe_priv *np = get_nvpriv(dev);
+ struct fe_priv *np = netdev_priv(dev);
int i;
np->next_tx = np->nic_tx = 0;
- for (i = 0; i < TX_RING; i++)
+ for (i = 0; i < TX_RING; i++) {
if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2)
np->tx_ring.orig[i].FlagLen = 0;
else
np->tx_ring.ex[i].FlagLen = 0;
+ np->tx_skbuff[i] = NULL;
+ }
}
static int nv_init_ring(struct net_device *dev)
@@ -907,21 +920,44 @@ static int nv_init_ring(struct net_device *dev)
return nv_alloc_rx(dev);
}
+static void nv_release_txskb(struct net_device *dev, unsigned int skbnr)
+{
+ struct fe_priv *np = netdev_priv(dev);
+ struct sk_buff *skb = np->tx_skbuff[skbnr];
+ unsigned int j, entry, fragments;
+
+ dprintk(KERN_INFO "%s: nv_release_txskb for skbnr %d, skb %p\n",
+ dev->name, skbnr, np->tx_skbuff[skbnr]);
+
+ entry = skbnr;
+ if ((fragments = skb_shinfo(skb)->nr_frags) != 0) {
+ for (j = fragments; j >= 1; j--) {
+ skb_frag_t *frag = &skb_shinfo(skb)->frags[j-1];
+ pci_unmap_page(np->pci_dev, np->tx_dma[entry],
+ frag->size,
+ PCI_DMA_TODEVICE);
+ entry = (entry - 1) % TX_RING;
+ }
+ }
+ pci_unmap_single(np->pci_dev, np->tx_dma[entry],
+ skb->len - skb->data_len,
+ PCI_DMA_TODEVICE);
+ dev_kfree_skb_irq(skb);
+ np->tx_skbuff[skbnr] = NULL;
+}
+
static void nv_drain_tx(struct net_device *dev)
{
- struct fe_priv *np = get_nvpriv(dev);
- int i;
+ struct fe_priv *np = netdev_priv(dev);
+ unsigned int i;
+
for (i = 0; i < TX_RING; i++) {
if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2)
np->tx_ring.orig[i].FlagLen = 0;
else
np->tx_ring.ex[i].FlagLen = 0;
if (np->tx_skbuff[i]) {
- pci_unmap_single(np->pci_dev, np->tx_dma[i],
- np->tx_skbuff[i]->len,
- PCI_DMA_TODEVICE);
- dev_kfree_skb(np->tx_skbuff[i]);
- np->tx_skbuff[i] = NULL;
+ nv_release_txskb(dev, i);
np->stats.tx_dropped++;
}
}
@@ -929,7 +965,7 @@ static void nv_drain_tx(struct net_device *dev)
static void nv_drain_rx(struct net_device *dev)
{
- struct fe_priv *np = get_nvpriv(dev);
+ struct fe_priv *np = netdev_priv(dev);
int i;
for (i = 0; i < RX_RING; i++) {
if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2)
@@ -959,28 +995,69 @@ static void drain_ring(struct net_device *dev)
*/
static int nv_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
- struct fe_priv *np = get_nvpriv(dev);
- int nr = np->next_tx % TX_RING;
+ struct fe_priv *np = netdev_priv(dev);
+ u32 tx_flags_extra = (np->desc_ver == DESC_VER_1 ? NV_TX_LASTPACKET : NV_TX2_LASTPACKET);
+ unsigned int fragments = skb_shinfo(skb)->nr_frags;
+ unsigned int nr = (np->next_tx + fragments) % TX_RING;
+ unsigned int i;
+
+ spin_lock_irq(&np->lock);
+
+ if ((np->next_tx - np->nic_tx + fragments) > TX_LIMIT_STOP) {
+ spin_unlock_irq(&np->lock);
+ netif_stop_queue(dev);
+ return NETDEV_TX_BUSY;
+ }
np->tx_skbuff[nr] = skb;
- np->tx_dma[nr] = pci_map_single(np->pci_dev, skb->data,skb->len,
- PCI_DMA_TODEVICE);
+
+ if (fragments) {
+ dprintk(KERN_DEBUG "%s: nv_start_xmit: buffer contains %d fragments\n", dev->name, fragments);
+ /* setup descriptors in reverse order */
+ for (i = fragments; i >= 1; i--) {
+ skb_frag_t *frag = &skb_shinfo(skb)->frags[i-1];
+ np->tx_dma[nr] = pci_map_page(np->pci_dev, frag->page, frag->page_offset, frag->size,
+ PCI_DMA_TODEVICE);
- if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2)
+ if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) {
+ np->tx_ring.orig[nr].PacketBuffer = cpu_to_le32(np->tx_dma[nr]);
+ np->tx_ring.orig[nr].FlagLen = cpu_to_le32( (frag->size-1) | np->tx_flags | tx_flags_extra);
+ } else {
+ np->tx_ring.ex[nr].PacketBufferHigh = cpu_to_le64(np->tx_dma[nr]) >> 32;
+ np->tx_ring.ex[nr].PacketBufferLow = cpu_to_le64(np->tx_dma[nr]) & 0x0FFFFFFFF;
+ np->tx_ring.ex[nr].FlagLen = cpu_to_le32( (frag->size-1) | np->tx_flags | tx_flags_extra);
+ }
+
+ nr = (nr - 1) % TX_RING;
+
+ if (np->desc_ver == DESC_VER_1)
+ tx_flags_extra &= ~NV_TX_LASTPACKET;
+ else
+ tx_flags_extra &= ~NV_TX2_LASTPACKET;
+ }
+ }
+
+#ifdef NETIF_F_TSO
+ if (skb_shinfo(skb)->tso_size)
+ tx_flags_extra |= NV_TX2_TSO | (skb_shinfo(skb)->tso_size << NV_TX2_TSO_SHIFT);
+ else
+#endif
+ tx_flags_extra |= (skb->ip_summed == CHECKSUM_HW ? (NV_TX2_CHECKSUM_L3|NV_TX2_CHECKSUM_L4) : 0);
+
+ np->tx_dma[nr] = pci_map_single(np->pci_dev, skb->data, skb->len-skb->data_len,
+ PCI_DMA_TODEVICE);
+
+ if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) {
np->tx_ring.orig[nr].PacketBuffer = cpu_to_le32(np->tx_dma[nr]);
- else {
+ np->tx_ring.orig[nr].FlagLen = cpu_to_le32( (skb->len-skb->data_len-1) | np->tx_flags | tx_flags_extra);
+ } else {
np->tx_ring.ex[nr].PacketBufferHigh = cpu_to_le64(np->tx_dma[nr]) >> 32;
np->tx_ring.ex[nr].PacketBufferLow = cpu_to_le64(np->tx_dma[nr]) & 0x0FFFFFFFF;
- }
+ np->tx_ring.ex[nr].FlagLen = cpu_to_le32( (skb->len-skb->data_len-1) | np->tx_flags | tx_flags_extra);
+ }
- spin_lock_irq(&np->lock);
- wmb();
- if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2)
- np->tx_ring.orig[nr].FlagLen = cpu_to_le32( (skb->len-1) | np->tx_flags );
- else
- np->tx_ring.ex[nr].FlagLen = cpu_to_le32( (skb->len-1) | np->tx_flags );
- dprintk(KERN_DEBUG "%s: nv_start_xmit: packet packet %d queued for transmission.\n",
- dev->name, np->next_tx);
+ dprintk(KERN_DEBUG "%s: nv_start_xmit: packet packet %d queued for transmission. tx_flags_extra: %x\n",
+ dev->name, np->next_tx, tx_flags_extra);
{
int j;
for (j=0; j<64; j++) {
@@ -991,15 +1068,13 @@ static int nv_start_xmit(struct sk_buff *skb, struct net_device *dev)
dprintk("\n");
}
- np->next_tx++;
+ np->next_tx += 1 + fragments;
dev->trans_start = jiffies;
- if (np->next_tx - np->nic_tx >= TX_LIMIT_STOP)
- netif_stop_queue(dev);
spin_unlock_irq(&np->lock);
- writel(NVREG_TXRXCTL_KICK|np->desc_ver, get_hwbase(dev) + NvRegTxRxControl);
+ writel(NVREG_TXRXCTL_KICK|np->txrxctl_bits, get_hwbase(dev) + NvRegTxRxControl);
pci_push(get_hwbase(dev));
- return 0;
+ return NETDEV_TX_OK;
}
/*
@@ -1009,9 +1084,10 @@ static int nv_start_xmit(struct sk_buff *skb, struct net_device *dev)
*/
static void nv_tx_done(struct net_device *dev)
{
- struct fe_priv *np = get_nvpriv(dev);
+ struct fe_priv *np = netdev_priv(dev);
u32 Flags;
- int i;
+ unsigned int i;
+ struct sk_buff *skb;
while (np->nic_tx != np->next_tx) {
i = np->nic_tx % TX_RING;
@@ -1026,35 +1102,38 @@ static void nv_tx_done(struct net_device *dev)
if (Flags & NV_TX_VALID)
break;
if (np->desc_ver == DESC_VER_1) {
- if (Flags & (NV_TX_RETRYERROR|NV_TX_CARRIERLOST|NV_TX_LATECOLLISION|
- NV_TX_UNDERFLOW|NV_TX_ERROR)) {
- if (Flags & NV_TX_UNDERFLOW)
- np->stats.tx_fifo_errors++;
- if (Flags & NV_TX_CARRIERLOST)
- np->stats.tx_carrier_errors++;
- np->stats.tx_errors++;
- } else {
- np->stats.tx_packets++;
- np->stats.tx_bytes += np->tx_skbuff[i]->len;
+ if (Flags & NV_TX_LASTPACKET) {
+ skb = np->tx_skbuff[i];
+ if (Flags & (NV_TX_RETRYERROR|NV_TX_CARRIERLOST|NV_TX_LATECOLLISION|
+ NV_TX_UNDERFLOW|NV_TX_ERROR)) {
+ if (Flags & NV_TX_UNDERFLOW)
+ np->stats.tx_fifo_errors++;
+ if (Flags & NV_TX_CARRIERLOST)
+ np->stats.tx_carrier_errors++;
+ np->stats.tx_errors++;
+ } else {
+ np->stats.tx_packets++;
+ np->stats.tx_bytes += skb->len;
+ }
+ nv_release_txskb(dev, i);
}
} else {
- if (Flags & (NV_TX2_RETRYERROR|NV_TX2_CARRIERLOST|NV_TX2_LATECOLLISION|
- NV_TX2_UNDERFLOW|NV_TX2_ERROR)) {
- if (Flags & NV_TX2_UNDERFLOW)
- np->stats.tx_fifo_errors++;
- if (Flags & NV_TX2_CARRIERLOST)
- np->stats.tx_carrier_errors++;
- np->stats.tx_errors++;
- } else {
- np->stats.tx_packets++;
- np->stats.tx_bytes += np->tx_skbuff[i]->len;
+ if (Flags & NV_TX2_LASTPACKET) {
+ skb = np->tx_skbuff[i];
+ if (Flags & (NV_TX2_RETRYERROR|NV_TX2_CARRIERLOST|NV_TX2_LATECOLLISION|
+ NV_TX2_UNDERFLOW|NV_TX2_ERROR)) {
+ if (Flags & NV_TX2_UNDERFLOW)
+ np->stats.tx_fifo_errors++;
+ if (Flags & NV_TX2_CARRIERLOST)
+ np->stats.tx_carrier_errors++;
+ np->stats.tx_errors++;
+ } else {
+ np->stats.tx_packets++;
+ np->stats.tx_bytes += skb->len;
+ }
+ nv_release_txskb(dev, i);
}
}
- pci_unmap_single(np->pci_dev, np->tx_dma[i],
- np->tx_skbuff[i]->len,
- PCI_DMA_TODEVICE);
- dev_kfree_skb_irq(np->tx_skbuff[i]);
- np->tx_skbuff[i] = NULL;
np->nic_tx++;
}
if (np->next_tx - np->nic_tx < TX_LIMIT_START)
@@ -1067,7 +1146,7 @@ static void nv_tx_done(struct net_device *dev)
*/
static void nv_tx_timeout(struct net_device *dev)
{
- struct fe_priv *np = get_nvpriv(dev);
+ struct fe_priv *np = netdev_priv(dev);
u8 __iomem *base = get_hwbase(dev);
printk(KERN_INFO "%s: Got tx_timeout. irq: %08x\n", dev->name,
@@ -1200,7 +1279,7 @@ static int nv_getlen(struct net_device *dev, void *packet, int datalen)
static void nv_rx_process(struct net_device *dev)
{
- struct fe_priv *np = get_nvpriv(dev);
+ struct fe_priv *np = netdev_priv(dev);
u32 Flags;
for (;;) {
@@ -1355,7 +1434,7 @@ static void set_bufsize(struct net_device *dev)
*/
static int nv_change_mtu(struct net_device *dev, int new_mtu)
{
- struct fe_priv *np = get_nvpriv(dev);
+ struct fe_priv *np = netdev_priv(dev);
int old_mtu;
if (new_mtu < 64 || new_mtu > np->pkt_limit)
@@ -1408,7 +1487,7 @@ static int nv_change_mtu(struct net_device *dev, int new_mtu)
writel( ((RX_RING-1) << NVREG_RINGSZ_RXSHIFT) + ((TX_RING-1) << NVREG_RINGSZ_TXSHIFT),
base + NvRegRingSizes);
pci_push(base);
- writel(NVREG_TXRXCTL_KICK|np->desc_ver, get_hwbase(dev) + NvRegTxRxControl);
+ writel(NVREG_TXRXCTL_KICK|np->txrxctl_bits, get_hwbase(dev) + NvRegTxRxControl);
pci_push(base);
/* restart rx engine */
@@ -1440,7 +1519,7 @@ static void nv_copy_mac_to_hw(struct net_device *dev)
*/
static int nv_set_mac_address(struct net_device *dev, void *addr)
{
- struct fe_priv *np = get_nvpriv(dev);
+ struct fe_priv *np = netdev_priv(dev);
struct sockaddr *macaddr = (struct sockaddr*)addr;
if(!is_valid_ether_addr(macaddr->sa_data))
@@ -1475,7 +1554,7 @@ static int nv_set_mac_address(struct net_device *dev, void *addr)
*/
static void nv_set_multicast(struct net_device *dev)
{
- struct fe_priv *np = get_nvpriv(dev);
+ struct fe_priv *np = netdev_priv(dev);
u8 __iomem *base = get_hwbase(dev);
u32 addr[2];
u32 mask[2];
@@ -1535,7 +1614,7 @@ static void nv_set_multicast(struct net_device *dev)
static int nv_update_linkspeed(struct net_device *dev)
{
- struct fe_priv *np = get_nvpriv(dev);
+ struct fe_priv *np = netdev_priv(dev);
u8 __iomem *base = get_hwbase(dev);
int adv, lpa;
int newls = np->linkspeed;
@@ -1705,7 +1784,7 @@ static void nv_link_irq(struct net_device *dev)
static irqreturn_t nv_nic_irq(int foo, void *data, struct pt_regs *regs)
{
struct net_device *dev = (struct net_device *) data;
- struct fe_priv *np = get_nvpriv(dev);
+ struct fe_priv *np = netdev_priv(dev);
u8 __iomem *base = get_hwbase(dev);
u32 events;
int i;
@@ -1777,7 +1856,7 @@ static irqreturn_t nv_nic_irq(int foo, void *data, struct pt_regs *regs)
static void nv_do_nic_poll(unsigned long data)
{
struct net_device *dev = (struct net_device *) data;
- struct fe_priv *np = get_nvpriv(dev);
+ struct fe_priv *np = netdev_priv(dev);
u8 __iomem *base = get_hwbase(dev);
disable_irq(dev->irq);
@@ -1801,7 +1880,7 @@ static void nv_poll_controller(struct net_device *dev)
static void nv_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
{
- struct fe_priv *np = get_nvpriv(dev);
+ struct fe_priv *np = netdev_priv(dev);
strcpy(info->driver, "forcedeth");
strcpy(info->version, FORCEDETH_VERSION);
strcpy(info->bus_info, pci_name(np->pci_dev));
@@ -1809,7 +1888,7 @@ static void nv_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
static void nv_get_wol(struct net_device *dev, struct ethtool_wolinfo *wolinfo)
{
- struct fe_priv *np = get_nvpriv(dev);
+ struct fe_priv *np = netdev_priv(dev);
wolinfo->supported = WAKE_MAGIC;
spin_lock_irq(&np->lock);
@@ -1820,7 +1899,7 @@ static void nv_get_wol(struct net_device *dev, struct ethtool_wolinfo *wolinfo)
static int nv_set_wol(struct net_device *dev, struct ethtool_wolinfo *wolinfo)
{
- struct fe_priv *np = get_nvpriv(dev);
+ struct fe_priv *np = netdev_priv(dev);
u8 __iomem *base = get_hwbase(dev);
spin_lock_irq(&np->lock);
@@ -2021,7 +2100,7 @@ static int nv_get_regs_len(struct net_device *dev)
static void nv_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *buf)
{
- struct fe_priv *np = get_nvpriv(dev);
+ struct fe_priv *np = netdev_priv(dev);
u8 __iomem *base = get_hwbase(dev);
u32 *rbuf = buf;
int i;
@@ -2035,7 +2114,7 @@ static void nv_get_regs(struct net_device *dev, struct ethtool_regs *regs, void
static int nv_nway_reset(struct net_device *dev)
{
- struct fe_priv *np = get_nvpriv(dev);
+ struct fe_priv *np = netdev_priv(dev);
int ret;
spin_lock_irq(&np->lock);
@@ -2065,11 +2144,12 @@ static struct ethtool_ops ops = {
.get_regs_len = nv_get_regs_len,
.get_regs = nv_get_regs,
.nway_reset = nv_nway_reset,
+ .get_perm_addr = ethtool_op_get_perm_addr,
};
static int nv_open(struct net_device *dev)
{
- struct fe_priv *np = get_nvpriv(dev);
+ struct fe_priv *np = netdev_priv(dev);
u8 __iomem *base = get_hwbase(dev);
int ret, oom, i;
@@ -2114,9 +2194,9 @@ static int nv_open(struct net_device *dev)
/* 5) continue setup */
writel(np->linkspeed, base + NvRegLinkSpeed);
writel(NVREG_UNKSETUP3_VAL1, base + NvRegUnknownSetupReg3);
- writel(np->desc_ver, base + NvRegTxRxControl);
+ writel(np->txrxctl_bits, base + NvRegTxRxControl);
pci_push(base);
- writel(NVREG_TXRXCTL_BIT1|np->desc_ver, base + NvRegTxRxControl);
+ writel(NVREG_TXRXCTL_BIT1|np->txrxctl_bits, base + NvRegTxRxControl);
reg_delay(dev, NvRegUnknownSetupReg5, NVREG_UNKSETUP5_BIT31, NVREG_UNKSETUP5_BIT31,
NV_SETUP5_DELAY, NV_SETUP5_DELAYMAX,
KERN_INFO "open: SetupReg5, Bit 31 remained off\n");
@@ -2205,7 +2285,7 @@ out_drain:
static int nv_close(struct net_device *dev)
{
- struct fe_priv *np = get_nvpriv(dev);
+ struct fe_priv *np = netdev_priv(dev);
u8 __iomem *base;
spin_lock_irq(&np->lock);
@@ -2261,7 +2341,7 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
if (!dev)
goto out;
- np = get_nvpriv(dev);
+ np = netdev_priv(dev);
np->pci_dev = pci_dev;
spin_lock_init(&np->lock);
SET_MODULE_OWNER(dev);
@@ -2313,19 +2393,32 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
if (pci_set_dma_mask(pci_dev, 0x0000007fffffffffULL)) {
printk(KERN_INFO "forcedeth: 64-bit DMA failed, using 32-bit addressing for device %s.\n",
pci_name(pci_dev));
+ } else {
+ dev->features |= NETIF_F_HIGHDMA;
}
+ np->txrxctl_bits = NVREG_TXRXCTL_DESC_3;
} else if (id->driver_data & DEV_HAS_LARGEDESC) {
/* packet format 2: supports jumbo frames */
np->desc_ver = DESC_VER_2;
+ np->txrxctl_bits = NVREG_TXRXCTL_DESC_2;
} else {
/* original packet format */
np->desc_ver = DESC_VER_1;
+ np->txrxctl_bits = NVREG_TXRXCTL_DESC_1;
}
np->pkt_limit = NV_PKTLIMIT_1;
if (id->driver_data & DEV_HAS_LARGEDESC)
np->pkt_limit = NV_PKTLIMIT_2;
+ if (id->driver_data & DEV_HAS_CHECKSUM) {
+ np->txrxctl_bits |= NVREG_TXRXCTL_RXCHECK;
+ dev->features |= NETIF_F_HW_CSUM | NETIF_F_SG;
+#ifdef NETIF_F_TSO
+ dev->features |= NETIF_F_TSO;
+#endif
+ }
+
err = -ENOMEM;
np->base = ioremap(addr, NV_PCI_REGSZ);
if (!np->base)
@@ -2377,8 +2470,9 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
dev->dev_addr[3] = (np->orig_mac[0] >> 16) & 0xff;
dev->dev_addr[4] = (np->orig_mac[0] >> 8) & 0xff;
dev->dev_addr[5] = (np->orig_mac[0] >> 0) & 0xff;
+ memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
- if (!is_valid_ether_addr(dev->dev_addr)) {
+ if (!is_valid_ether_addr(dev->perm_addr)) {
/*
* Bad mac address. At least one bios sets the mac address
* to 01:23:45:67:89:ab
@@ -2403,9 +2497,9 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
np->wolenabled = 0;
if (np->desc_ver == DESC_VER_1) {
- np->tx_flags = NV_TX_LASTPACKET|NV_TX_VALID;
+ np->tx_flags = NV_TX_VALID;
} else {
- np->tx_flags = NV_TX2_LASTPACKET|NV_TX2_VALID;
+ np->tx_flags = NV_TX2_VALID;
}
np->irqmask = NVREG_IRQMASK_WANTED;
if (id->driver_data & DEV_NEED_TIMERIRQ)
@@ -2494,7 +2588,7 @@ out:
static void __devexit nv_remove(struct pci_dev *pci_dev)
{
struct net_device *dev = pci_get_drvdata(pci_dev);
- struct fe_priv *np = get_nvpriv(dev);
+ struct fe_priv *np = netdev_priv(dev);
unregister_netdev(dev);
@@ -2525,35 +2619,35 @@ static struct pci_device_id pci_tbl[] = {
},
{ /* nForce3 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_4),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC,
+ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM,
},
{ /* nForce3 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_5),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC,
+ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM,
},
{ /* nForce3 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_6),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC,
+ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM,
},
{ /* nForce3 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_7),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC,
+ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM,
},
{ /* CK804 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_8),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA,
+ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA,
},
{ /* CK804 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_9),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA,
+ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA,
},
{ /* MCP04 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_10),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA,
+ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA,
},
{ /* MCP04 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_11),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA,
+ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA,
},
{ /* MCP51 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_12),
@@ -2565,11 +2659,11 @@ static struct pci_device_id pci_tbl[] = {
},
{ /* MCP55 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_14),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA,
+ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA,
},
{ /* MCP55 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_15),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA,
+ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA,
},
{0,},
};
diff --git a/drivers/net/fs_enet/Kconfig b/drivers/net/fs_enet/Kconfig
new file mode 100644
index 000000000000..6aaee67dd4b7
--- /dev/null
+++ b/drivers/net/fs_enet/Kconfig
@@ -0,0 +1,20 @@
+config FS_ENET
+ tristate "Freescale Ethernet Driver"
+ depends on NET_ETHERNET && (CPM1 || CPM2)
+ select MII
+
+config FS_ENET_HAS_SCC
+ bool "Chip has an SCC usable for ethernet"
+ depends on FS_ENET && (CPM1 || CPM2)
+ default y
+
+config FS_ENET_HAS_FCC
+ bool "Chip has an FCC usable for ethernet"
+ depends on FS_ENET && CPM2
+ default y
+
+config FS_ENET_HAS_FEC
+ bool "Chip has an FEC usable for ethernet"
+ depends on FS_ENET && CPM1
+ default y
+
diff --git a/drivers/net/fs_enet/Makefile b/drivers/net/fs_enet/Makefile
new file mode 100644
index 000000000000..d6dd3f2fb43e
--- /dev/null
+++ b/drivers/net/fs_enet/Makefile
@@ -0,0 +1,10 @@
+#
+# Makefile for the Freescale Ethernet controllers
+#
+
+obj-$(CONFIG_FS_ENET) += fs_enet.o
+
+obj-$(CONFIG_8xx) += mac-fec.o mac-scc.o
+obj-$(CONFIG_8260) += mac-fcc.o
+
+fs_enet-objs := fs_enet-main.o fs_enet-mii.o mii-bitbang.o mii-fixed.o
diff --git a/drivers/net/fs_enet/fs_enet-main.c b/drivers/net/fs_enet/fs_enet-main.c
new file mode 100644
index 000000000000..f5d49a110654
--- /dev/null
+++ b/drivers/net/fs_enet/fs_enet-main.c
@@ -0,0 +1,1230 @@
+/*
+ * Combined Ethernet driver for Motorola MPC8xx and MPC82xx.
+ *
+ * Copyright (c) 2003 Intracom S.A.
+ * by Pantelis Antoniou <panto@intracom.gr>
+ *
+ * 2005 (c) MontaVista Software, Inc.
+ * Vitaly Bordug <vbordug@ru.mvista.com>
+ *
+ * Heavily based on original FEC driver by Dan Malek <dan@embeddededge.com>
+ * and modifications by Joakim Tjernlund <joakim.tjernlund@lumentis.se>
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/string.h>
+#include <linux/ptrace.h>
+#include <linux/errno.h>
+#include <linux/ioport.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/spinlock.h>
+#include <linux/mii.h>
+#include <linux/ethtool.h>
+#include <linux/bitops.h>
+#include <linux/fs.h>
+#include <linux/platform_device.h>
+
+#include <linux/vmalloc.h>
+#include <asm/pgtable.h>
+
+#include <asm/pgtable.h>
+#include <asm/irq.h>
+#include <asm/uaccess.h>
+
+#include "fs_enet.h"
+
+/*************************************************/
+
+static char version[] __devinitdata =
+ DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")" "\n";
+
+MODULE_AUTHOR("Pantelis Antoniou <panto@intracom.gr>");
+MODULE_DESCRIPTION("Freescale Ethernet Driver");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(DRV_MODULE_VERSION);
+
+MODULE_PARM(fs_enet_debug, "i");
+MODULE_PARM_DESC(fs_enet_debug,
+ "Freescale bitmapped debugging message enable value");
+
+int fs_enet_debug = -1; /* -1 == use FS_ENET_DEF_MSG_ENABLE as value */
+
+static void fs_set_multicast_list(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+
+ (*fep->ops->set_multicast_list)(dev);
+}
+
+/* NAPI receive function */
+static int fs_enet_rx_napi(struct net_device *dev, int *budget)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ const struct fs_platform_info *fpi = fep->fpi;
+ cbd_t *bdp;
+ struct sk_buff *skb, *skbn, *skbt;
+ int received = 0;
+ u16 pkt_len, sc;
+ int curidx;
+ int rx_work_limit = 0; /* pacify gcc */
+
+ rx_work_limit = min(dev->quota, *budget);
+
+ if (!netif_running(dev))
+ return 0;
+
+ /*
+ * First, grab all of the stats for the incoming packet.
+ * These get messed up if we get called due to a busy condition.
+ */
+ bdp = fep->cur_rx;
+
+ /* clear RX status bits for napi*/
+ (*fep->ops->napi_clear_rx_event)(dev);
+
+ while (((sc = CBDR_SC(bdp)) & BD_ENET_RX_EMPTY) == 0) {
+
+ curidx = bdp - fep->rx_bd_base;
+
+ /*
+ * Since we have allocated space to hold a complete frame,
+ * the last indicator should be set.
+ */
+ if ((sc & BD_ENET_RX_LAST) == 0)
+ printk(KERN_WARNING DRV_MODULE_NAME
+ ": %s rcv is not +last\n",
+ dev->name);
+
+ /*
+ * Check for errors.
+ */
+ if (sc & (BD_ENET_RX_LG | BD_ENET_RX_SH | BD_ENET_RX_CL |
+ BD_ENET_RX_NO | BD_ENET_RX_CR | BD_ENET_RX_OV)) {
+ fep->stats.rx_errors++;
+ /* Frame too long or too short. */
+ if (sc & (BD_ENET_RX_LG | BD_ENET_RX_SH))
+ fep->stats.rx_length_errors++;
+ /* Frame alignment */
+ if (sc & (BD_ENET_RX_NO | BD_ENET_RX_CL))
+ fep->stats.rx_frame_errors++;
+ /* CRC Error */
+ if (sc & BD_ENET_RX_CR)
+ fep->stats.rx_crc_errors++;
+ /* FIFO overrun */
+ if (sc & BD_ENET_RX_OV)
+ fep->stats.rx_crc_errors++;
+
+ skb = fep->rx_skbuff[curidx];
+
+ dma_unmap_single(fep->dev, CBDR_BUFADDR(bdp),
+ L1_CACHE_ALIGN(PKT_MAXBUF_SIZE),
+ DMA_FROM_DEVICE);
+
+ skbn = skb;
+
+ } else {
+
+ /* napi, got packet but no quota */
+ if (--rx_work_limit < 0)
+ break;
+
+ skb = fep->rx_skbuff[curidx];
+
+ dma_unmap_single(fep->dev, CBDR_BUFADDR(bdp),
+ L1_CACHE_ALIGN(PKT_MAXBUF_SIZE),
+ DMA_FROM_DEVICE);
+
+ /*
+ * Process the incoming frame.
+ */
+ fep->stats.rx_packets++;
+ pkt_len = CBDR_DATLEN(bdp) - 4; /* remove CRC */
+ fep->stats.rx_bytes += pkt_len + 4;
+
+ if (pkt_len <= fpi->rx_copybreak) {
+ /* +2 to make IP header L1 cache aligned */
+ skbn = dev_alloc_skb(pkt_len + 2);
+ if (skbn != NULL) {
+ skb_reserve(skbn, 2); /* align IP header */
+ memcpy(skbn->data, skb->data, pkt_len);
+ /* swap */
+ skbt = skb;
+ skb = skbn;
+ skbn = skbt;
+ }
+ } else
+ skbn = dev_alloc_skb(ENET_RX_FRSIZE);
+
+ if (skbn != NULL) {
+ skb->dev = dev;
+ skb_put(skb, pkt_len); /* Make room */
+ skb->protocol = eth_type_trans(skb, dev);
+ received++;
+ netif_receive_skb(skb);
+ } else {
+ printk(KERN_WARNING DRV_MODULE_NAME
+ ": %s Memory squeeze, dropping packet.\n",
+ dev->name);
+ fep->stats.rx_dropped++;
+ skbn = skb;
+ }
+ }
+
+ fep->rx_skbuff[curidx] = skbn;
+ CBDW_BUFADDR(bdp, dma_map_single(fep->dev, skbn->data,
+ L1_CACHE_ALIGN(PKT_MAXBUF_SIZE),
+ DMA_FROM_DEVICE));
+ CBDW_DATLEN(bdp, 0);
+ CBDW_SC(bdp, (sc & ~BD_ENET_RX_STATS) | BD_ENET_RX_EMPTY);
+
+ /*
+ * Update BD pointer to next entry.
+ */
+ if ((sc & BD_ENET_RX_WRAP) == 0)
+ bdp++;
+ else
+ bdp = fep->rx_bd_base;
+
+ (*fep->ops->rx_bd_done)(dev);
+ }
+
+ fep->cur_rx = bdp;
+
+ dev->quota -= received;
+ *budget -= received;
+
+ if (rx_work_limit < 0)
+ return 1; /* not done */
+
+ /* done */
+ netif_rx_complete(dev);
+
+ (*fep->ops->napi_enable_rx)(dev);
+
+ return 0;
+}
+
+/* non NAPI receive function */
+static int fs_enet_rx_non_napi(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ const struct fs_platform_info *fpi = fep->fpi;
+ cbd_t *bdp;
+ struct sk_buff *skb, *skbn, *skbt;
+ int received = 0;
+ u16 pkt_len, sc;
+ int curidx;
+ /*
+ * First, grab all of the stats for the incoming packet.
+ * These get messed up if we get called due to a busy condition.
+ */
+ bdp = fep->cur_rx;
+
+ while (((sc = CBDR_SC(bdp)) & BD_ENET_RX_EMPTY) == 0) {
+
+ curidx = bdp - fep->rx_bd_base;
+
+ /*
+ * Since we have allocated space to hold a complete frame,
+ * the last indicator should be set.
+ */
+ if ((sc & BD_ENET_RX_LAST) == 0)
+ printk(KERN_WARNING DRV_MODULE_NAME
+ ": %s rcv is not +last\n",
+ dev->name);
+
+ /*
+ * Check for errors.
+ */
+ if (sc & (BD_ENET_RX_LG | BD_ENET_RX_SH | BD_ENET_RX_CL |
+ BD_ENET_RX_NO | BD_ENET_RX_CR | BD_ENET_RX_OV)) {
+ fep->stats.rx_errors++;
+ /* Frame too long or too short. */
+ if (sc & (BD_ENET_RX_LG | BD_ENET_RX_SH))
+ fep->stats.rx_length_errors++;
+ /* Frame alignment */
+ if (sc & (BD_ENET_RX_NO | BD_ENET_RX_CL))
+ fep->stats.rx_frame_errors++;
+ /* CRC Error */
+ if (sc & BD_ENET_RX_CR)
+ fep->stats.rx_crc_errors++;
+ /* FIFO overrun */
+ if (sc & BD_ENET_RX_OV)
+ fep->stats.rx_crc_errors++;
+
+ skb = fep->rx_skbuff[curidx];
+
+ dma_unmap_single(fep->dev, CBDR_BUFADDR(bdp),
+ L1_CACHE_ALIGN(PKT_MAXBUF_SIZE),
+ DMA_FROM_DEVICE);
+
+ skbn = skb;
+
+ } else {
+
+ skb = fep->rx_skbuff[curidx];
+
+ dma_unmap_single(fep->dev, CBDR_BUFADDR(bdp),
+ L1_CACHE_ALIGN(PKT_MAXBUF_SIZE),
+ DMA_FROM_DEVICE);
+
+ /*
+ * Process the incoming frame.
+ */
+ fep->stats.rx_packets++;
+ pkt_len = CBDR_DATLEN(bdp) - 4; /* remove CRC */
+ fep->stats.rx_bytes += pkt_len + 4;
+
+ if (pkt_len <= fpi->rx_copybreak) {
+ /* +2 to make IP header L1 cache aligned */
+ skbn = dev_alloc_skb(pkt_len + 2);
+ if (skbn != NULL) {
+ skb_reserve(skbn, 2); /* align IP header */
+ memcpy(skbn->data, skb->data, pkt_len);
+ /* swap */
+ skbt = skb;
+ skb = skbn;
+ skbn = skbt;
+ }
+ } else
+ skbn = dev_alloc_skb(ENET_RX_FRSIZE);
+
+ if (skbn != NULL) {
+ skb->dev = dev;
+ skb_put(skb, pkt_len); /* Make room */
+ skb->protocol = eth_type_trans(skb, dev);
+ received++;
+ netif_rx(skb);
+ } else {
+ printk(KERN_WARNING DRV_MODULE_NAME
+ ": %s Memory squeeze, dropping packet.\n",
+ dev->name);
+ fep->stats.rx_dropped++;
+ skbn = skb;
+ }
+ }
+
+ fep->rx_skbuff[curidx] = skbn;
+ CBDW_BUFADDR(bdp, dma_map_single(fep->dev, skbn->data,
+ L1_CACHE_ALIGN(PKT_MAXBUF_SIZE),
+ DMA_FROM_DEVICE));
+ CBDW_DATLEN(bdp, 0);
+ CBDW_SC(bdp, (sc & ~BD_ENET_RX_STATS) | BD_ENET_RX_EMPTY);
+
+ /*
+ * Update BD pointer to next entry.
+ */
+ if ((sc & BD_ENET_RX_WRAP) == 0)
+ bdp++;
+ else
+ bdp = fep->rx_bd_base;
+
+ (*fep->ops->rx_bd_done)(dev);
+ }
+
+ fep->cur_rx = bdp;
+
+ return 0;
+}
+
+static void fs_enet_tx(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ cbd_t *bdp;
+ struct sk_buff *skb;
+ int dirtyidx, do_wake, do_restart;
+ u16 sc;
+
+ spin_lock(&fep->lock);
+ bdp = fep->dirty_tx;
+
+ do_wake = do_restart = 0;
+ while (((sc = CBDR_SC(bdp)) & BD_ENET_TX_READY) == 0) {
+
+ dirtyidx = bdp - fep->tx_bd_base;
+
+ if (fep->tx_free == fep->tx_ring)
+ break;
+
+ skb = fep->tx_skbuff[dirtyidx];
+
+ /*
+ * Check for errors.
+ */
+ if (sc & (BD_ENET_TX_HB | BD_ENET_TX_LC |
+ BD_ENET_TX_RL | BD_ENET_TX_UN | BD_ENET_TX_CSL)) {
+
+ if (sc & BD_ENET_TX_HB) /* No heartbeat */
+ fep->stats.tx_heartbeat_errors++;
+ if (sc & BD_ENET_TX_LC) /* Late collision */
+ fep->stats.tx_window_errors++;
+ if (sc & BD_ENET_TX_RL) /* Retrans limit */
+ fep->stats.tx_aborted_errors++;
+ if (sc & BD_ENET_TX_UN) /* Underrun */
+ fep->stats.tx_fifo_errors++;
+ if (sc & BD_ENET_TX_CSL) /* Carrier lost */
+ fep->stats.tx_carrier_errors++;
+
+ if (sc & (BD_ENET_TX_LC | BD_ENET_TX_RL | BD_ENET_TX_UN)) {
+ fep->stats.tx_errors++;
+ do_restart = 1;
+ }
+ } else
+ fep->stats.tx_packets++;
+
+ if (sc & BD_ENET_TX_READY)
+ printk(KERN_WARNING DRV_MODULE_NAME
+ ": %s HEY! Enet xmit interrupt and TX_READY.\n",
+ dev->name);
+
+ /*
+ * Deferred means some collisions occurred during transmit,
+ * but we eventually sent the packet OK.
+ */
+ if (sc & BD_ENET_TX_DEF)
+ fep->stats.collisions++;
+
+ /* unmap */
+ dma_unmap_single(fep->dev, CBDR_BUFADDR(bdp),
+ skb->len, DMA_TO_DEVICE);
+
+ /*
+ * Free the sk buffer associated with this last transmit.
+ */
+ dev_kfree_skb_irq(skb);
+ fep->tx_skbuff[dirtyidx] = NULL;
+
+ /*
+ * Update pointer to next buffer descriptor to be transmitted.
+ */
+ if ((sc & BD_ENET_TX_WRAP) == 0)
+ bdp++;
+ else
+ bdp = fep->tx_bd_base;
+
+ /*
+ * Since we have freed up a buffer, the ring is no longer
+ * full.
+ */
+ if (!fep->tx_free++)
+ do_wake = 1;
+ }
+
+ fep->dirty_tx = bdp;
+
+ if (do_restart)
+ (*fep->ops->tx_restart)(dev);
+
+ spin_unlock(&fep->lock);
+
+ if (do_wake)
+ netif_wake_queue(dev);
+}
+
+/*
+ * The interrupt handler.
+ * This is called from the MPC core interrupt.
+ */
+static irqreturn_t
+fs_enet_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+ struct net_device *dev = dev_id;
+ struct fs_enet_private *fep;
+ const struct fs_platform_info *fpi;
+ u32 int_events;
+ u32 int_clr_events;
+ int nr, napi_ok;
+ int handled;
+
+ fep = netdev_priv(dev);
+ fpi = fep->fpi;
+
+ nr = 0;
+ while ((int_events = (*fep->ops->get_int_events)(dev)) != 0) {
+
+ nr++;
+
+ int_clr_events = int_events;
+ if (fpi->use_napi)
+ int_clr_events &= ~fep->ev_napi_rx;
+
+ (*fep->ops->clear_int_events)(dev, int_clr_events);
+
+ if (int_events & fep->ev_err)
+ (*fep->ops->ev_error)(dev, int_events);
+
+ if (int_events & fep->ev_rx) {
+ if (!fpi->use_napi)
+ fs_enet_rx_non_napi(dev);
+ else {
+ napi_ok = netif_rx_schedule_prep(dev);
+
+ (*fep->ops->napi_disable_rx)(dev);
+ (*fep->ops->clear_int_events)(dev, fep->ev_napi_rx);
+
+ /* NOTE: it is possible for FCCs in NAPI mode */
+ /* to submit a spurious interrupt while in poll */
+ if (napi_ok)
+ __netif_rx_schedule(dev);
+ }
+ }
+
+ if (int_events & fep->ev_tx)
+ fs_enet_tx(dev);
+ }
+
+ handled = nr > 0;
+ return IRQ_RETVAL(handled);
+}
+
+void fs_init_bds(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ cbd_t *bdp;
+ struct sk_buff *skb;
+ int i;
+
+ fs_cleanup_bds(dev);
+
+ fep->dirty_tx = fep->cur_tx = fep->tx_bd_base;
+ fep->tx_free = fep->tx_ring;
+ fep->cur_rx = fep->rx_bd_base;
+
+ /*
+ * Initialize the receive buffer descriptors.
+ */
+ for (i = 0, bdp = fep->rx_bd_base; i < fep->rx_ring; i++, bdp++) {
+ skb = dev_alloc_skb(ENET_RX_FRSIZE);
+ if (skb == NULL) {
+ printk(KERN_WARNING DRV_MODULE_NAME
+ ": %s Memory squeeze, unable to allocate skb\n",
+ dev->name);
+ break;
+ }
+ fep->rx_skbuff[i] = skb;
+ skb->dev = dev;
+ CBDW_BUFADDR(bdp,
+ dma_map_single(fep->dev, skb->data,
+ L1_CACHE_ALIGN(PKT_MAXBUF_SIZE),
+ DMA_FROM_DEVICE));
+ CBDW_DATLEN(bdp, 0); /* zero */
+ CBDW_SC(bdp, BD_ENET_RX_EMPTY |
+ ((i < fep->rx_ring - 1) ? 0 : BD_SC_WRAP));
+ }
+ /*
+ * if we failed, fillup remainder
+ */
+ for (; i < fep->rx_ring; i++, bdp++) {
+ fep->rx_skbuff[i] = NULL;
+ CBDW_SC(bdp, (i < fep->rx_ring - 1) ? 0 : BD_SC_WRAP);
+ }
+
+ /*
+ * ...and the same for transmit.
+ */
+ for (i = 0, bdp = fep->tx_bd_base; i < fep->tx_ring; i++, bdp++) {
+ fep->tx_skbuff[i] = NULL;
+ CBDW_BUFADDR(bdp, 0);
+ CBDW_DATLEN(bdp, 0);
+ CBDW_SC(bdp, (i < fep->tx_ring - 1) ? 0 : BD_SC_WRAP);
+ }
+}
+
+void fs_cleanup_bds(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ struct sk_buff *skb;
+ cbd_t *bdp;
+ int i;
+
+ /*
+ * Reset SKB transmit buffers.
+ */
+ for (i = 0, bdp = fep->tx_bd_base; i < fep->tx_ring; i++, bdp++) {
+ if ((skb = fep->tx_skbuff[i]) == NULL)
+ continue;
+
+ /* unmap */
+ dma_unmap_single(fep->dev, CBDR_BUFADDR(bdp),
+ skb->len, DMA_TO_DEVICE);
+
+ fep->tx_skbuff[i] = NULL;
+ dev_kfree_skb(skb);
+ }
+
+ /*
+ * Reset SKB receive buffers
+ */
+ for (i = 0, bdp = fep->rx_bd_base; i < fep->rx_ring; i++, bdp++) {
+ if ((skb = fep->rx_skbuff[i]) == NULL)
+ continue;
+
+ /* unmap */
+ dma_unmap_single(fep->dev, CBDR_BUFADDR(bdp),
+ L1_CACHE_ALIGN(PKT_MAXBUF_SIZE),
+ DMA_FROM_DEVICE);
+
+ fep->rx_skbuff[i] = NULL;
+
+ dev_kfree_skb(skb);
+ }
+}
+
+/**********************************************************************************/
+
+static int fs_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ cbd_t *bdp;
+ int curidx;
+ u16 sc;
+ unsigned long flags;
+
+ spin_lock_irqsave(&fep->tx_lock, flags);
+
+ /*
+ * Fill in a Tx ring entry
+ */
+ bdp = fep->cur_tx;
+
+ if (!fep->tx_free || (CBDR_SC(bdp) & BD_ENET_TX_READY)) {
+ netif_stop_queue(dev);
+ spin_unlock_irqrestore(&fep->tx_lock, flags);
+
+ /*
+ * Ooops. All transmit buffers are full. Bail out.
+ * This should not happen, since the tx queue should be stopped.
+ */
+ printk(KERN_WARNING DRV_MODULE_NAME
+ ": %s tx queue full!.\n", dev->name);
+ return NETDEV_TX_BUSY;
+ }
+
+ curidx = bdp - fep->tx_bd_base;
+ /*
+ * Clear all of the status flags.
+ */
+ CBDC_SC(bdp, BD_ENET_TX_STATS);
+
+ /*
+ * Save skb pointer.
+ */
+ fep->tx_skbuff[curidx] = skb;
+
+ fep->stats.tx_bytes += skb->len;
+
+ /*
+ * Push the data cache so the CPM does not get stale memory data.
+ */
+ CBDW_BUFADDR(bdp, dma_map_single(fep->dev,
+ skb->data, skb->len, DMA_TO_DEVICE));
+ CBDW_DATLEN(bdp, skb->len);
+
+ dev->trans_start = jiffies;
+
+ /*
+ * If this was the last BD in the ring, start at the beginning again.
+ */
+ if ((CBDR_SC(bdp) & BD_ENET_TX_WRAP) == 0)
+ fep->cur_tx++;
+ else
+ fep->cur_tx = fep->tx_bd_base;
+
+ if (!--fep->tx_free)
+ netif_stop_queue(dev);
+
+ /* Trigger transmission start */
+ sc = BD_ENET_TX_READY | BD_ENET_TX_INTR |
+ BD_ENET_TX_LAST | BD_ENET_TX_TC;
+
+ /* note that while FEC does not have this bit
+ * it marks it as available for software use
+ * yay for hw reuse :) */
+ if (skb->len <= 60)
+ sc |= BD_ENET_TX_PAD;
+ CBDS_SC(bdp, sc);
+
+ (*fep->ops->tx_kickstart)(dev);
+
+ spin_unlock_irqrestore(&fep->tx_lock, flags);
+
+ return NETDEV_TX_OK;
+}
+
+static int fs_request_irq(struct net_device *dev, int irq, const char *name,
+ irqreturn_t (*irqf)(int irq, void *dev_id, struct pt_regs *regs))
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+
+ (*fep->ops->pre_request_irq)(dev, irq);
+ return request_irq(irq, irqf, SA_SHIRQ, name, dev);
+}
+
+static void fs_free_irq(struct net_device *dev, int irq)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+
+ free_irq(irq, dev);
+ (*fep->ops->post_free_irq)(dev, irq);
+}
+
+/**********************************************************************************/
+
+/* This interrupt occurs when the PHY detects a link change. */
+static irqreturn_t
+fs_mii_link_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+ struct net_device *dev = dev_id;
+ struct fs_enet_private *fep;
+ const struct fs_platform_info *fpi;
+
+ fep = netdev_priv(dev);
+ fpi = fep->fpi;
+
+ /*
+ * Acknowledge the interrupt if possible. If we have not
+ * found the PHY yet we can't process or acknowledge the
+ * interrupt now. Instead we ignore this interrupt for now,
+ * which we can do since it is edge triggered. It will be
+ * acknowledged later by fs_enet_open().
+ */
+ if (!fep->phy)
+ return IRQ_NONE;
+
+ fs_mii_ack_int(dev);
+ fs_mii_link_status_change_check(dev, 0);
+
+ return IRQ_HANDLED;
+}
+
+static void fs_timeout(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ unsigned long flags;
+ int wake = 0;
+
+ fep->stats.tx_errors++;
+
+ spin_lock_irqsave(&fep->lock, flags);
+
+ if (dev->flags & IFF_UP) {
+ (*fep->ops->stop)(dev);
+ (*fep->ops->restart)(dev);
+ }
+
+ wake = fep->tx_free && !(CBDR_SC(fep->cur_tx) & BD_ENET_TX_READY);
+ spin_unlock_irqrestore(&fep->lock, flags);
+
+ if (wake)
+ netif_wake_queue(dev);
+}
+
+static int fs_enet_open(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ const struct fs_platform_info *fpi = fep->fpi;
+ int r;
+
+ /* Install our interrupt handler. */
+ r = fs_request_irq(dev, fep->interrupt, "fs_enet-mac", fs_enet_interrupt);
+ if (r != 0) {
+ printk(KERN_ERR DRV_MODULE_NAME
+ ": %s Could not allocate FEC IRQ!", dev->name);
+ return -EINVAL;
+ }
+
+ /* Install our phy interrupt handler */
+ if (fpi->phy_irq != -1) {
+
+ r = fs_request_irq(dev, fpi->phy_irq, "fs_enet-phy", fs_mii_link_interrupt);
+ if (r != 0) {
+ printk(KERN_ERR DRV_MODULE_NAME
+ ": %s Could not allocate PHY IRQ!", dev->name);
+ fs_free_irq(dev, fep->interrupt);
+ return -EINVAL;
+ }
+ }
+
+ fs_mii_startup(dev);
+ netif_carrier_off(dev);
+ fs_mii_link_status_change_check(dev, 1);
+
+ return 0;
+}
+
+static int fs_enet_close(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ const struct fs_platform_info *fpi = fep->fpi;
+ unsigned long flags;
+
+ netif_stop_queue(dev);
+ netif_carrier_off(dev);
+ fs_mii_shutdown(dev);
+
+ spin_lock_irqsave(&fep->lock, flags);
+ (*fep->ops->stop)(dev);
+ spin_unlock_irqrestore(&fep->lock, flags);
+
+ /* release any irqs */
+ if (fpi->phy_irq != -1)
+ fs_free_irq(dev, fpi->phy_irq);
+ fs_free_irq(dev, fep->interrupt);
+
+ return 0;
+}
+
+static struct net_device_stats *fs_enet_get_stats(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ return &fep->stats;
+}
+
+/*************************************************************************/
+
+static void fs_get_drvinfo(struct net_device *dev,
+ struct ethtool_drvinfo *info)
+{
+ strcpy(info->driver, DRV_MODULE_NAME);
+ strcpy(info->version, DRV_MODULE_VERSION);
+}
+
+static int fs_get_regs_len(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+
+ return (*fep->ops->get_regs_len)(dev);
+}
+
+static void fs_get_regs(struct net_device *dev, struct ethtool_regs *regs,
+ void *p)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ unsigned long flags;
+ int r, len;
+
+ len = regs->len;
+
+ spin_lock_irqsave(&fep->lock, flags);
+ r = (*fep->ops->get_regs)(dev, p, &len);
+ spin_unlock_irqrestore(&fep->lock, flags);
+
+ if (r == 0)
+ regs->version = 0;
+}
+
+static int fs_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ unsigned long flags;
+ int rc;
+
+ spin_lock_irqsave(&fep->lock, flags);
+ rc = mii_ethtool_gset(&fep->mii_if, cmd);
+ spin_unlock_irqrestore(&fep->lock, flags);
+
+ return rc;
+}
+
+static int fs_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ unsigned long flags;
+ int rc;
+
+ spin_lock_irqsave(&fep->lock, flags);
+ rc = mii_ethtool_sset(&fep->mii_if, cmd);
+ spin_unlock_irqrestore(&fep->lock, flags);
+
+ return rc;
+}
+
+static int fs_nway_reset(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ return mii_nway_restart(&fep->mii_if);
+}
+
+static u32 fs_get_msglevel(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ return fep->msg_enable;
+}
+
+static void fs_set_msglevel(struct net_device *dev, u32 value)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ fep->msg_enable = value;
+}
+
+static struct ethtool_ops fs_ethtool_ops = {
+ .get_drvinfo = fs_get_drvinfo,
+ .get_regs_len = fs_get_regs_len,
+ .get_settings = fs_get_settings,
+ .set_settings = fs_set_settings,
+ .nway_reset = fs_nway_reset,
+ .get_link = ethtool_op_get_link,
+ .get_msglevel = fs_get_msglevel,
+ .set_msglevel = fs_set_msglevel,
+ .get_tx_csum = ethtool_op_get_tx_csum,
+ .set_tx_csum = ethtool_op_set_tx_csum, /* local! */
+ .get_sg = ethtool_op_get_sg,
+ .set_sg = ethtool_op_set_sg,
+ .get_regs = fs_get_regs,
+};
+
+static int fs_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ struct mii_ioctl_data *mii = (struct mii_ioctl_data *)&rq->ifr_data;
+ unsigned long flags;
+ int rc;
+
+ if (!netif_running(dev))
+ return -EINVAL;
+
+ spin_lock_irqsave(&fep->lock, flags);
+ rc = generic_mii_ioctl(&fep->mii_if, mii, cmd, NULL);
+ spin_unlock_irqrestore(&fep->lock, flags);
+ return rc;
+}
+
+extern int fs_mii_connect(struct net_device *dev);
+extern void fs_mii_disconnect(struct net_device *dev);
+
+static struct net_device *fs_init_instance(struct device *dev,
+ const struct fs_platform_info *fpi)
+{
+ struct net_device *ndev = NULL;
+ struct fs_enet_private *fep = NULL;
+ int privsize, i, r, err = 0, registered = 0;
+
+ /* guard */
+ if ((unsigned int)fpi->fs_no >= FS_MAX_INDEX)
+ return ERR_PTR(-EINVAL);
+
+ privsize = sizeof(*fep) + (sizeof(struct sk_buff **) *
+ (fpi->rx_ring + fpi->tx_ring));
+
+ ndev = alloc_etherdev(privsize);
+ if (!ndev) {
+ err = -ENOMEM;
+ goto err;
+ }
+ SET_MODULE_OWNER(ndev);
+
+ fep = netdev_priv(ndev);
+ memset(fep, 0, privsize); /* clear everything */
+
+ fep->dev = dev;
+ dev_set_drvdata(dev, ndev);
+ fep->fpi = fpi;
+ if (fpi->init_ioports)
+ fpi->init_ioports();
+
+#ifdef CONFIG_FS_ENET_HAS_FEC
+ if (fs_get_fec_index(fpi->fs_no) >= 0)
+ fep->ops = &fs_fec_ops;
+#endif
+
+#ifdef CONFIG_FS_ENET_HAS_SCC
+ if (fs_get_scc_index(fpi->fs_no) >=0 )
+ fep->ops = &fs_scc_ops;
+#endif
+
+#ifdef CONFIG_FS_ENET_HAS_FCC
+ if (fs_get_fcc_index(fpi->fs_no) >= 0)
+ fep->ops = &fs_fcc_ops;
+#endif
+
+ if (fep->ops == NULL) {
+ printk(KERN_ERR DRV_MODULE_NAME
+ ": %s No matching ops found (%d).\n",
+ ndev->name, fpi->fs_no);
+ err = -EINVAL;
+ goto err;
+ }
+
+ r = (*fep->ops->setup_data)(ndev);
+ if (r != 0) {
+ printk(KERN_ERR DRV_MODULE_NAME
+ ": %s setup_data failed\n",
+ ndev->name);
+ err = r;
+ goto err;
+ }
+
+ /* point rx_skbuff, tx_skbuff */
+ fep->rx_skbuff = (struct sk_buff **)&fep[1];
+ fep->tx_skbuff = fep->rx_skbuff + fpi->rx_ring;
+
+ /* init locks */
+ spin_lock_init(&fep->lock);
+ spin_lock_init(&fep->tx_lock);
+
+ /*
+ * Set the Ethernet address.
+ */
+ for (i = 0; i < 6; i++)
+ ndev->dev_addr[i] = fpi->macaddr[i];
+
+ r = (*fep->ops->allocate_bd)(ndev);
+
+ if (fep->ring_base == NULL) {
+ printk(KERN_ERR DRV_MODULE_NAME
+ ": %s buffer descriptor alloc failed (%d).\n", ndev->name, r);
+ err = r;
+ goto err;
+ }
+
+ /*
+ * Set receive and transmit descriptor base.
+ */
+ fep->rx_bd_base = fep->ring_base;
+ fep->tx_bd_base = fep->rx_bd_base + fpi->rx_ring;
+
+ /* initialize ring size variables */
+ fep->tx_ring = fpi->tx_ring;
+ fep->rx_ring = fpi->rx_ring;
+
+ /*
+ * The FEC Ethernet specific entries in the device structure.
+ */
+ ndev->open = fs_enet_open;
+ ndev->hard_start_xmit = fs_enet_start_xmit;
+ ndev->tx_timeout = fs_timeout;
+ ndev->watchdog_timeo = 2 * HZ;
+ ndev->stop = fs_enet_close;
+ ndev->get_stats = fs_enet_get_stats;
+ ndev->set_multicast_list = fs_set_multicast_list;
+ if (fpi->use_napi) {
+ ndev->poll = fs_enet_rx_napi;
+ ndev->weight = fpi->napi_weight;
+ }
+ ndev->ethtool_ops = &fs_ethtool_ops;
+ ndev->do_ioctl = fs_ioctl;
+
+ init_timer(&fep->phy_timer_list);
+
+ netif_carrier_off(ndev);
+
+ err = register_netdev(ndev);
+ if (err != 0) {
+ printk(KERN_ERR DRV_MODULE_NAME
+ ": %s register_netdev failed.\n", ndev->name);
+ goto err;
+ }
+ registered = 1;
+
+ err = fs_mii_connect(ndev);
+ if (err != 0) {
+ printk(KERN_ERR DRV_MODULE_NAME
+ ": %s fs_mii_connect failed.\n", ndev->name);
+ goto err;
+ }
+
+ return ndev;
+
+ err:
+ if (ndev != NULL) {
+
+ if (registered)
+ unregister_netdev(ndev);
+
+ if (fep != NULL) {
+ (*fep->ops->free_bd)(ndev);
+ (*fep->ops->cleanup_data)(ndev);
+ }
+
+ free_netdev(ndev);
+ }
+
+ dev_set_drvdata(dev, NULL);
+
+ return ERR_PTR(err);
+}
+
+static int fs_cleanup_instance(struct net_device *ndev)
+{
+ struct fs_enet_private *fep;
+ const struct fs_platform_info *fpi;
+ struct device *dev;
+
+ if (ndev == NULL)
+ return -EINVAL;
+
+ fep = netdev_priv(ndev);
+ if (fep == NULL)
+ return -EINVAL;
+
+ fpi = fep->fpi;
+
+ fs_mii_disconnect(ndev);
+
+ unregister_netdev(ndev);
+
+ dma_free_coherent(fep->dev, (fpi->tx_ring + fpi->rx_ring) * sizeof(cbd_t),
+ fep->ring_base, fep->ring_mem_addr);
+
+ /* reset it */
+ (*fep->ops->cleanup_data)(ndev);
+
+ dev = fep->dev;
+ if (dev != NULL) {
+ dev_set_drvdata(dev, NULL);
+ fep->dev = NULL;
+ }
+
+ free_netdev(ndev);
+
+ return 0;
+}
+
+/**************************************************************************************/
+
+/* handy pointer to the immap */
+void *fs_enet_immap = NULL;
+
+static int setup_immap(void)
+{
+ phys_addr_t paddr = 0;
+ unsigned long size = 0;
+
+#ifdef CONFIG_CPM1
+ paddr = IMAP_ADDR;
+ size = 0x10000; /* map 64K */
+#endif
+
+#ifdef CONFIG_CPM2
+ paddr = CPM_MAP_ADDR;
+ size = 0x40000; /* map 256 K */
+#endif
+ fs_enet_immap = ioremap(paddr, size);
+ if (fs_enet_immap == NULL)
+ return -EBADF; /* XXX ahem; maybe just BUG_ON? */
+
+ return 0;
+}
+
+static void cleanup_immap(void)
+{
+ if (fs_enet_immap != NULL) {
+ iounmap(fs_enet_immap);
+ fs_enet_immap = NULL;
+ }
+}
+
+/**************************************************************************************/
+
+static int __devinit fs_enet_probe(struct device *dev)
+{
+ struct net_device *ndev;
+
+ /* no fixup - no device */
+ if (dev->platform_data == NULL) {
+ printk(KERN_INFO "fs_enet: "
+ "probe called with no platform data; "
+ "remove unused devices\n");
+ return -ENODEV;
+ }
+
+ ndev = fs_init_instance(dev, dev->platform_data);
+ if (IS_ERR(ndev))
+ return PTR_ERR(ndev);
+ return 0;
+}
+
+static int fs_enet_remove(struct device *dev)
+{
+ return fs_cleanup_instance(dev_get_drvdata(dev));
+}
+
+static struct device_driver fs_enet_fec_driver = {
+ .name = "fsl-cpm-fec",
+ .bus = &platform_bus_type,
+ .probe = fs_enet_probe,
+ .remove = fs_enet_remove,
+#ifdef CONFIG_PM
+/* .suspend = fs_enet_suspend, TODO */
+/* .resume = fs_enet_resume, TODO */
+#endif
+};
+
+static struct device_driver fs_enet_scc_driver = {
+ .name = "fsl-cpm-scc",
+ .bus = &platform_bus_type,
+ .probe = fs_enet_probe,
+ .remove = fs_enet_remove,
+#ifdef CONFIG_PM
+/* .suspend = fs_enet_suspend, TODO */
+/* .resume = fs_enet_resume, TODO */
+#endif
+};
+
+static struct device_driver fs_enet_fcc_driver = {
+ .name = "fsl-cpm-fcc",
+ .bus = &platform_bus_type,
+ .probe = fs_enet_probe,
+ .remove = fs_enet_remove,
+#ifdef CONFIG_PM
+/* .suspend = fs_enet_suspend, TODO */
+/* .resume = fs_enet_resume, TODO */
+#endif
+};
+
+static int __init fs_init(void)
+{
+ int r;
+
+ printk(KERN_INFO
+ "%s", version);
+
+ r = setup_immap();
+ if (r != 0)
+ return r;
+ r = driver_register(&fs_enet_fec_driver);
+ if (r != 0)
+ goto err;
+
+ r = driver_register(&fs_enet_fcc_driver);
+ if (r != 0)
+ goto err;
+
+ r = driver_register(&fs_enet_scc_driver);
+ if (r != 0)
+ goto err;
+
+ return 0;
+err:
+ cleanup_immap();
+ return r;
+
+}
+
+static void __exit fs_cleanup(void)
+{
+ driver_unregister(&fs_enet_fec_driver);
+ driver_unregister(&fs_enet_fcc_driver);
+ driver_unregister(&fs_enet_scc_driver);
+ cleanup_immap();
+}
+
+/**************************************************************************************/
+
+module_init(fs_init);
+module_exit(fs_cleanup);
diff --git a/drivers/net/fs_enet/fs_enet-mii.c b/drivers/net/fs_enet/fs_enet-mii.c
new file mode 100644
index 000000000000..c6770377ef87
--- /dev/null
+++ b/drivers/net/fs_enet/fs_enet-mii.c
@@ -0,0 +1,507 @@
+/*
+ * Combined Ethernet driver for Motorola MPC8xx and MPC82xx.
+ *
+ * Copyright (c) 2003 Intracom S.A.
+ * by Pantelis Antoniou <panto@intracom.gr>
+ *
+ * 2005 (c) MontaVista Software, Inc.
+ * Vitaly Bordug <vbordug@ru.mvista.com>
+ *
+ * Heavily based on original FEC driver by Dan Malek <dan@embeddededge.com>
+ * and modifications by Joakim Tjernlund <joakim.tjernlund@lumentis.se>
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/string.h>
+#include <linux/ptrace.h>
+#include <linux/errno.h>
+#include <linux/ioport.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/spinlock.h>
+#include <linux/mii.h>
+#include <linux/ethtool.h>
+#include <linux/bitops.h>
+
+#include <asm/pgtable.h>
+#include <asm/irq.h>
+#include <asm/uaccess.h>
+
+#include "fs_enet.h"
+
+/*************************************************/
+
+/*
+ * Generic PHY support.
+ * Should work for all PHYs, but link change is detected by polling
+ */
+
+static void generic_timer_callback(unsigned long data)
+{
+ struct net_device *dev = (struct net_device *)data;
+ struct fs_enet_private *fep = netdev_priv(dev);
+
+ fep->phy_timer_list.expires = jiffies + HZ / 2;
+
+ add_timer(&fep->phy_timer_list);
+
+ fs_mii_link_status_change_check(dev, 0);
+}
+
+static void generic_startup(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+
+ fep->phy_timer_list.expires = jiffies + HZ / 2; /* every 500ms */
+ fep->phy_timer_list.data = (unsigned long)dev;
+ fep->phy_timer_list.function = generic_timer_callback;
+ add_timer(&fep->phy_timer_list);
+}
+
+static void generic_shutdown(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+
+ del_timer_sync(&fep->phy_timer_list);
+}
+
+/* ------------------------------------------------------------------------- */
+/* The Davicom DM9161 is used on the NETTA board */
+
+/* register definitions */
+
+#define MII_DM9161_ANAR 4 /* Aux. Config Register */
+#define MII_DM9161_ACR 16 /* Aux. Config Register */
+#define MII_DM9161_ACSR 17 /* Aux. Config/Status Register */
+#define MII_DM9161_10TCSR 18 /* 10BaseT Config/Status Reg. */
+#define MII_DM9161_INTR 21 /* Interrupt Register */
+#define MII_DM9161_RECR 22 /* Receive Error Counter Reg. */
+#define MII_DM9161_DISCR 23 /* Disconnect Counter Register */
+
+static void dm9161_startup(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+
+ fs_mii_write(dev, fep->mii_if.phy_id, MII_DM9161_INTR, 0x0000);
+ /* Start autonegotiation */
+ fs_mii_write(dev, fep->mii_if.phy_id, MII_BMCR, 0x1200);
+
+ set_current_state(TASK_UNINTERRUPTIBLE);
+ schedule_timeout(HZ*8);
+}
+
+static void dm9161_ack_int(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+
+ fs_mii_read(dev, fep->mii_if.phy_id, MII_DM9161_INTR);
+}
+
+static void dm9161_shutdown(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+
+ fs_mii_write(dev, fep->mii_if.phy_id, MII_DM9161_INTR, 0x0f00);
+}
+
+/**********************************************************************************/
+
+static const struct phy_info phy_info[] = {
+ {
+ .id = 0x00181b88,
+ .name = "DM9161",
+ .startup = dm9161_startup,
+ .ack_int = dm9161_ack_int,
+ .shutdown = dm9161_shutdown,
+ }, {
+ .id = 0,
+ .name = "GENERIC",
+ .startup = generic_startup,
+ .shutdown = generic_shutdown,
+ },
+};
+
+/**********************************************************************************/
+
+static int phy_id_detect(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ const struct fs_platform_info *fpi = fep->fpi;
+ struct fs_enet_mii_bus *bus = fep->mii_bus;
+ int i, r, start, end, phytype, physubtype;
+ const struct phy_info *phy;
+ int phy_hwid, phy_id;
+
+ phy_hwid = -1;
+ fep->phy = NULL;
+
+ /* auto-detect? */
+ if (fpi->phy_addr == -1) {
+ start = 1;
+ end = 32;
+ } else { /* direct */
+ start = fpi->phy_addr;
+ end = start + 1;
+ }
+
+ for (phy_id = start; phy_id < end; phy_id++) {
+ /* skip already used phy addresses on this bus */
+ if (bus->usage_map & (1 << phy_id))
+ continue;
+ r = fs_mii_read(dev, phy_id, MII_PHYSID1);
+ if (r == -1 || (phytype = (r & 0xffff)) == 0xffff)
+ continue;
+ r = fs_mii_read(dev, phy_id, MII_PHYSID2);
+ if (r == -1 || (physubtype = (r & 0xffff)) == 0xffff)
+ continue;
+ phy_hwid = (phytype << 16) | physubtype;
+ if (phy_hwid != -1)
+ break;
+ }
+
+ if (phy_hwid == -1) {
+ printk(KERN_ERR DRV_MODULE_NAME
+ ": %s No PHY detected! range=0x%02x-0x%02x\n",
+ dev->name, start, end);
+ return -1;
+ }
+
+ for (i = 0, phy = phy_info; i < ARRAY_SIZE(phy_info); i++, phy++)
+ if (phy->id == (phy_hwid >> 4) || phy->id == 0)
+ break;
+
+ if (i >= ARRAY_SIZE(phy_info)) {
+ printk(KERN_ERR DRV_MODULE_NAME
+ ": %s PHY id 0x%08x is not supported!\n",
+ dev->name, phy_hwid);
+ return -1;
+ }
+
+ fep->phy = phy;
+
+ /* mark this address as used */
+ bus->usage_map |= (1 << phy_id);
+
+ printk(KERN_INFO DRV_MODULE_NAME
+ ": %s Phy @ 0x%x, type %s (0x%08x)%s\n",
+ dev->name, phy_id, fep->phy->name, phy_hwid,
+ fpi->phy_addr == -1 ? " (auto-detected)" : "");
+
+ return phy_id;
+}
+
+void fs_mii_startup(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+
+ if (fep->phy->startup)
+ (*fep->phy->startup) (dev);
+}
+
+void fs_mii_shutdown(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+
+ if (fep->phy->shutdown)
+ (*fep->phy->shutdown) (dev);
+}
+
+void fs_mii_ack_int(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+
+ if (fep->phy->ack_int)
+ (*fep->phy->ack_int) (dev);
+}
+
+#define MII_LINK 0x0001
+#define MII_HALF 0x0002
+#define MII_FULL 0x0004
+#define MII_BASE4 0x0008
+#define MII_10M 0x0010
+#define MII_100M 0x0020
+#define MII_1G 0x0040
+#define MII_10G 0x0080
+
+/* return full mii info at one gulp, with a usable form */
+static unsigned int mii_full_status(struct mii_if_info *mii)
+{
+ unsigned int status;
+ int bmsr, adv, lpa, neg;
+ struct fs_enet_private* fep = netdev_priv(mii->dev);
+
+ /* first, a dummy read, needed to latch some MII phys */
+ (void)mii->mdio_read(mii->dev, mii->phy_id, MII_BMSR);
+ bmsr = mii->mdio_read(mii->dev, mii->phy_id, MII_BMSR);
+
+ /* no link */
+ if ((bmsr & BMSR_LSTATUS) == 0)
+ return 0;
+
+ status = MII_LINK;
+
+ /* Lets look what ANEG says if it's supported - otherwize we shall
+ take the right values from the platform info*/
+ if(!mii->force_media) {
+ /* autoneg not completed; don't bother */
+ if ((bmsr & BMSR_ANEGCOMPLETE) == 0)
+ return 0;
+
+ adv = (*mii->mdio_read)(mii->dev, mii->phy_id, MII_ADVERTISE);
+ lpa = (*mii->mdio_read)(mii->dev, mii->phy_id, MII_LPA);
+
+ neg = lpa & adv;
+ } else {
+ neg = fep->fpi->bus_info->lpa;
+ }
+
+ if (neg & LPA_100FULL)
+ status |= MII_FULL | MII_100M;
+ else if (neg & LPA_100BASE4)
+ status |= MII_FULL | MII_BASE4 | MII_100M;
+ else if (neg & LPA_100HALF)
+ status |= MII_HALF | MII_100M;
+ else if (neg & LPA_10FULL)
+ status |= MII_FULL | MII_10M;
+ else
+ status |= MII_HALF | MII_10M;
+
+ return status;
+}
+
+void fs_mii_link_status_change_check(struct net_device *dev, int init_media)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ struct mii_if_info *mii = &fep->mii_if;
+ unsigned int mii_status;
+ int ok_to_print, link, duplex, speed;
+ unsigned long flags;
+
+ ok_to_print = netif_msg_link(fep);
+
+ mii_status = mii_full_status(mii);
+
+ if (!init_media && mii_status == fep->last_mii_status)
+ return;
+
+ fep->last_mii_status = mii_status;
+
+ link = !!(mii_status & MII_LINK);
+ duplex = !!(mii_status & MII_FULL);
+ speed = (mii_status & MII_100M) ? 100 : 10;
+
+ if (link == 0) {
+ netif_carrier_off(mii->dev);
+ netif_stop_queue(dev);
+ if (!init_media) {
+ spin_lock_irqsave(&fep->lock, flags);
+ (*fep->ops->stop)(dev);
+ spin_unlock_irqrestore(&fep->lock, flags);
+ }
+
+ if (ok_to_print)
+ printk(KERN_INFO "%s: link down\n", mii->dev->name);
+
+ } else {
+
+ mii->full_duplex = duplex;
+
+ netif_carrier_on(mii->dev);
+
+ spin_lock_irqsave(&fep->lock, flags);
+ fep->duplex = duplex;
+ fep->speed = speed;
+ (*fep->ops->restart)(dev);
+ spin_unlock_irqrestore(&fep->lock, flags);
+
+ netif_start_queue(dev);
+
+ if (ok_to_print)
+ printk(KERN_INFO "%s: link up, %dMbps, %s-duplex\n",
+ dev->name, speed, duplex ? "full" : "half");
+ }
+}
+
+/**********************************************************************************/
+
+int fs_mii_read(struct net_device *dev, int phy_id, int location)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ struct fs_enet_mii_bus *bus = fep->mii_bus;
+
+ unsigned long flags;
+ int ret;
+
+ spin_lock_irqsave(&bus->mii_lock, flags);
+ ret = (*bus->mii_read)(bus, phy_id, location);
+ spin_unlock_irqrestore(&bus->mii_lock, flags);
+
+ return ret;
+}
+
+void fs_mii_write(struct net_device *dev, int phy_id, int location, int value)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ struct fs_enet_mii_bus *bus = fep->mii_bus;
+ unsigned long flags;
+
+ spin_lock_irqsave(&bus->mii_lock, flags);
+ (*bus->mii_write)(bus, phy_id, location, value);
+ spin_unlock_irqrestore(&bus->mii_lock, flags);
+}
+
+/*****************************************************************************/
+
+/* list of all registered mii buses */
+static LIST_HEAD(fs_mii_bus_list);
+
+static struct fs_enet_mii_bus *lookup_bus(int method, int id)
+{
+ struct list_head *ptr;
+ struct fs_enet_mii_bus *bus;
+
+ list_for_each(ptr, &fs_mii_bus_list) {
+ bus = list_entry(ptr, struct fs_enet_mii_bus, list);
+ if (bus->bus_info->method == method &&
+ bus->bus_info->id == id)
+ return bus;
+ }
+ return NULL;
+}
+
+static struct fs_enet_mii_bus *create_bus(const struct fs_mii_bus_info *bi)
+{
+ struct fs_enet_mii_bus *bus;
+ int ret = 0;
+
+ bus = kmalloc(sizeof(*bus), GFP_KERNEL);
+ if (bus == NULL) {
+ ret = -ENOMEM;
+ goto err;
+ }
+ memset(bus, 0, sizeof(*bus));
+ spin_lock_init(&bus->mii_lock);
+ bus->bus_info = bi;
+ bus->refs = 0;
+ bus->usage_map = 0;
+
+ /* perform initialization */
+ switch (bi->method) {
+
+ case fsmii_fixed:
+ ret = fs_mii_fixed_init(bus);
+ if (ret != 0)
+ goto err;
+ break;
+
+ case fsmii_bitbang:
+ ret = fs_mii_bitbang_init(bus);
+ if (ret != 0)
+ goto err;
+ break;
+#ifdef CONFIG_FS_ENET_HAS_FEC
+ case fsmii_fec:
+ ret = fs_mii_fec_init(bus);
+ if (ret != 0)
+ goto err;
+ break;
+#endif
+ default:
+ ret = -EINVAL;
+ goto err;
+ }
+
+ list_add(&bus->list, &fs_mii_bus_list);
+
+ return bus;
+
+err:
+ if (bus)
+ kfree(bus);
+ return ERR_PTR(ret);
+}
+
+static void destroy_bus(struct fs_enet_mii_bus *bus)
+{
+ /* remove from bus list */
+ list_del(&bus->list);
+
+ /* nothing more needed */
+ kfree(bus);
+}
+
+int fs_mii_connect(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ const struct fs_platform_info *fpi = fep->fpi;
+ struct fs_enet_mii_bus *bus = NULL;
+
+ /* check method validity */
+ switch (fpi->bus_info->method) {
+ case fsmii_fixed:
+ case fsmii_bitbang:
+ break;
+#ifdef CONFIG_FS_ENET_HAS_FEC
+ case fsmii_fec:
+ break;
+#endif
+ default:
+ printk(KERN_ERR DRV_MODULE_NAME
+ ": %s Unknown MII bus method (%d)!\n",
+ dev->name, fpi->bus_info->method);
+ return -EINVAL;
+ }
+
+ bus = lookup_bus(fpi->bus_info->method, fpi->bus_info->id);
+
+ /* if not found create new bus */
+ if (bus == NULL) {
+ bus = create_bus(fpi->bus_info);
+ if (IS_ERR(bus)) {
+ printk(KERN_ERR DRV_MODULE_NAME
+ ": %s MII bus creation failure!\n", dev->name);
+ return PTR_ERR(bus);
+ }
+ }
+
+ bus->refs++;
+
+ fep->mii_bus = bus;
+
+ fep->mii_if.dev = dev;
+ fep->mii_if.phy_id_mask = 0x1f;
+ fep->mii_if.reg_num_mask = 0x1f;
+ fep->mii_if.mdio_read = fs_mii_read;
+ fep->mii_if.mdio_write = fs_mii_write;
+ fep->mii_if.force_media = fpi->bus_info->disable_aneg;
+ fep->mii_if.phy_id = phy_id_detect(dev);
+
+ return 0;
+}
+
+void fs_mii_disconnect(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ struct fs_enet_mii_bus *bus = NULL;
+
+ bus = fep->mii_bus;
+ fep->mii_bus = NULL;
+
+ if (--bus->refs <= 0)
+ destroy_bus(bus);
+}
diff --git a/drivers/net/fs_enet/fs_enet.h b/drivers/net/fs_enet/fs_enet.h
new file mode 100644
index 000000000000..e7ec96c964a9
--- /dev/null
+++ b/drivers/net/fs_enet/fs_enet.h
@@ -0,0 +1,244 @@
+#ifndef FS_ENET_H
+#define FS_ENET_H
+
+#include <linux/mii.h>
+#include <linux/netdevice.h>
+#include <linux/types.h>
+#include <linux/list.h>
+
+#include <linux/fs_enet_pd.h>
+
+#include <asm/dma-mapping.h>
+
+#ifdef CONFIG_CPM1
+#include <asm/commproc.h>
+#endif
+
+#ifdef CONFIG_CPM2
+#include <asm/cpm2.h>
+#endif
+
+/* hw driver ops */
+struct fs_ops {
+ int (*setup_data)(struct net_device *dev);
+ int (*allocate_bd)(struct net_device *dev);
+ void (*free_bd)(struct net_device *dev);
+ void (*cleanup_data)(struct net_device *dev);
+ void (*set_multicast_list)(struct net_device *dev);
+ void (*restart)(struct net_device *dev);
+ void (*stop)(struct net_device *dev);
+ void (*pre_request_irq)(struct net_device *dev, int irq);
+ void (*post_free_irq)(struct net_device *dev, int irq);
+ void (*napi_clear_rx_event)(struct net_device *dev);
+ void (*napi_enable_rx)(struct net_device *dev);
+ void (*napi_disable_rx)(struct net_device *dev);
+ void (*rx_bd_done)(struct net_device *dev);
+ void (*tx_kickstart)(struct net_device *dev);
+ u32 (*get_int_events)(struct net_device *dev);
+ void (*clear_int_events)(struct net_device *dev, u32 int_events);
+ void (*ev_error)(struct net_device *dev, u32 int_events);
+ int (*get_regs)(struct net_device *dev, void *p, int *sizep);
+ int (*get_regs_len)(struct net_device *dev);
+ void (*tx_restart)(struct net_device *dev);
+};
+
+struct phy_info {
+ unsigned int id;
+ const char *name;
+ void (*startup) (struct net_device * dev);
+ void (*shutdown) (struct net_device * dev);
+ void (*ack_int) (struct net_device * dev);
+};
+
+/* The FEC stores dest/src/type, data, and checksum for receive packets.
+ */
+#define MAX_MTU 1508 /* Allow fullsized pppoe packets over VLAN */
+#define MIN_MTU 46 /* this is data size */
+#define CRC_LEN 4
+
+#define PKT_MAXBUF_SIZE (MAX_MTU+ETH_HLEN+CRC_LEN)
+#define PKT_MINBUF_SIZE (MIN_MTU+ETH_HLEN+CRC_LEN)
+
+/* Must be a multiple of 32 (to cover both FEC & FCC) */
+#define PKT_MAXBLR_SIZE ((PKT_MAXBUF_SIZE + 31) & ~31)
+/* This is needed so that invalidate_xxx wont invalidate too much */
+#define ENET_RX_FRSIZE L1_CACHE_ALIGN(PKT_MAXBUF_SIZE)
+
+struct fs_enet_mii_bus {
+ struct list_head list;
+ spinlock_t mii_lock;
+ const struct fs_mii_bus_info *bus_info;
+ int refs;
+ u32 usage_map;
+
+ int (*mii_read)(struct fs_enet_mii_bus *bus,
+ int phy_id, int location);
+
+ void (*mii_write)(struct fs_enet_mii_bus *bus,
+ int phy_id, int location, int value);
+
+ union {
+ struct {
+ unsigned int mii_speed;
+ void *fecp;
+ } fec;
+
+ struct {
+ /* note that the actual port size may */
+ /* be different; cpm(s) handle it OK */
+ u8 mdio_msk;
+ u8 *mdio_dir;
+ u8 *mdio_dat;
+ u8 mdc_msk;
+ u8 *mdc_dir;
+ u8 *mdc_dat;
+ } bitbang;
+
+ struct {
+ u16 lpa;
+ } fixed;
+ };
+};
+
+int fs_mii_bitbang_init(struct fs_enet_mii_bus *bus);
+int fs_mii_fixed_init(struct fs_enet_mii_bus *bus);
+int fs_mii_fec_init(struct fs_enet_mii_bus *bus);
+
+struct fs_enet_private {
+ struct device *dev; /* pointer back to the device (must be initialized first) */
+ spinlock_t lock; /* during all ops except TX pckt processing */
+ spinlock_t tx_lock; /* during fs_start_xmit and fs_tx */
+ const struct fs_platform_info *fpi;
+ const struct fs_ops *ops;
+ int rx_ring, tx_ring;
+ dma_addr_t ring_mem_addr;
+ void *ring_base;
+ struct sk_buff **rx_skbuff;
+ struct sk_buff **tx_skbuff;
+ cbd_t *rx_bd_base; /* Address of Rx and Tx buffers. */
+ cbd_t *tx_bd_base;
+ cbd_t *dirty_tx; /* ring entries to be free()ed. */
+ cbd_t *cur_rx;
+ cbd_t *cur_tx;
+ int tx_free;
+ struct net_device_stats stats;
+ struct timer_list phy_timer_list;
+ const struct phy_info *phy;
+ u32 msg_enable;
+ struct mii_if_info mii_if;
+ unsigned int last_mii_status;
+ struct fs_enet_mii_bus *mii_bus;
+ int interrupt;
+
+ int duplex, speed; /* current settings */
+
+ /* event masks */
+ u32 ev_napi_rx; /* mask of NAPI rx events */
+ u32 ev_rx; /* rx event mask */
+ u32 ev_tx; /* tx event mask */
+ u32 ev_err; /* error event mask */
+
+ u16 bd_rx_empty; /* mask of BD rx empty */
+ u16 bd_rx_err; /* mask of BD rx errors */
+
+ union {
+ struct {
+ int idx; /* FEC1 = 0, FEC2 = 1 */
+ void *fecp; /* hw registers */
+ u32 hthi, htlo; /* state for multicast */
+ } fec;
+
+ struct {
+ int idx; /* FCC1-3 = 0-2 */
+ void *fccp; /* hw registers */
+ void *ep; /* parameter ram */
+ void *fcccp; /* hw registers cont. */
+ void *mem; /* FCC DPRAM */
+ u32 gaddrh, gaddrl; /* group address */
+ } fcc;
+
+ struct {
+ int idx; /* FEC1 = 0, FEC2 = 1 */
+ void *sccp; /* hw registers */
+ void *ep; /* parameter ram */
+ u32 hthi, htlo; /* state for multicast */
+ } scc;
+
+ };
+};
+
+/***************************************************************************/
+
+int fs_mii_read(struct net_device *dev, int phy_id, int location);
+void fs_mii_write(struct net_device *dev, int phy_id, int location, int value);
+
+void fs_mii_startup(struct net_device *dev);
+void fs_mii_shutdown(struct net_device *dev);
+void fs_mii_ack_int(struct net_device *dev);
+
+void fs_mii_link_status_change_check(struct net_device *dev, int init_media);
+
+void fs_init_bds(struct net_device *dev);
+void fs_cleanup_bds(struct net_device *dev);
+
+/***************************************************************************/
+
+#define DRV_MODULE_NAME "fs_enet"
+#define PFX DRV_MODULE_NAME ": "
+#define DRV_MODULE_VERSION "1.0"
+#define DRV_MODULE_RELDATE "Aug 8, 2005"
+
+/***************************************************************************/
+
+int fs_enet_platform_init(void);
+void fs_enet_platform_cleanup(void);
+
+/***************************************************************************/
+
+/* buffer descriptor access macros */
+
+/* access macros */
+#if defined(CONFIG_CPM1)
+/* for a a CPM1 __raw_xxx's are sufficient */
+#define __cbd_out32(addr, x) __raw_writel(x, addr)
+#define __cbd_out16(addr, x) __raw_writew(x, addr)
+#define __cbd_in32(addr) __raw_readl(addr)
+#define __cbd_in16(addr) __raw_readw(addr)
+#else
+/* for others play it safe */
+#define __cbd_out32(addr, x) out_be32(addr, x)
+#define __cbd_out16(addr, x) out_be16(addr, x)
+#define __cbd_in32(addr) in_be32(addr)
+#define __cbd_in16(addr) in_be16(addr)
+#endif
+
+/* write */
+#define CBDW_SC(_cbd, _sc) __cbd_out16(&(_cbd)->cbd_sc, (_sc))
+#define CBDW_DATLEN(_cbd, _datlen) __cbd_out16(&(_cbd)->cbd_datlen, (_datlen))
+#define CBDW_BUFADDR(_cbd, _bufaddr) __cbd_out32(&(_cbd)->cbd_bufaddr, (_bufaddr))
+
+/* read */
+#define CBDR_SC(_cbd) __cbd_in16(&(_cbd)->cbd_sc)
+#define CBDR_DATLEN(_cbd) __cbd_in16(&(_cbd)->cbd_datlen)
+#define CBDR_BUFADDR(_cbd) __cbd_in32(&(_cbd)->cbd_bufaddr)
+
+/* set bits */
+#define CBDS_SC(_cbd, _sc) CBDW_SC(_cbd, CBDR_SC(_cbd) | (_sc))
+
+/* clear bits */
+#define CBDC_SC(_cbd, _sc) CBDW_SC(_cbd, CBDR_SC(_cbd) & ~(_sc))
+
+/*******************************************************************/
+
+extern const struct fs_ops fs_fec_ops;
+extern const struct fs_ops fs_fcc_ops;
+extern const struct fs_ops fs_scc_ops;
+
+/*******************************************************************/
+
+/* handy pointer to the immap */
+extern void *fs_enet_immap;
+
+/*******************************************************************/
+
+#endif
diff --git a/drivers/net/fs_enet/mac-fcc.c b/drivers/net/fs_enet/mac-fcc.c
new file mode 100644
index 000000000000..e67b1d06611c
--- /dev/null
+++ b/drivers/net/fs_enet/mac-fcc.c
@@ -0,0 +1,579 @@
+/*
+ * FCC driver for Motorola MPC82xx (PQ2).
+ *
+ * Copyright (c) 2003 Intracom S.A.
+ * by Pantelis Antoniou <panto@intracom.gr>
+ *
+ * 2005 (c) MontaVista Software, Inc.
+ * Vitaly Bordug <vbordug@ru.mvista.com>
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/string.h>
+#include <linux/ptrace.h>
+#include <linux/errno.h>
+#include <linux/ioport.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/spinlock.h>
+#include <linux/mii.h>
+#include <linux/ethtool.h>
+#include <linux/bitops.h>
+#include <linux/fs.h>
+#include <linux/platform_device.h>
+
+#include <asm/immap_cpm2.h>
+#include <asm/mpc8260.h>
+#include <asm/cpm2.h>
+
+#include <asm/pgtable.h>
+#include <asm/irq.h>
+#include <asm/uaccess.h>
+
+#include "fs_enet.h"
+
+/*************************************************/
+
+/* FCC access macros */
+
+#define __fcc_out32(addr, x) out_be32((unsigned *)addr, x)
+#define __fcc_out16(addr, x) out_be16((unsigned short *)addr, x)
+#define __fcc_out8(addr, x) out_8((unsigned char *)addr, x)
+#define __fcc_in32(addr) in_be32((unsigned *)addr)
+#define __fcc_in16(addr) in_be16((unsigned short *)addr)
+#define __fcc_in8(addr) in_8((unsigned char *)addr)
+
+/* parameter space */
+
+/* write, read, set bits, clear bits */
+#define W32(_p, _m, _v) __fcc_out32(&(_p)->_m, (_v))
+#define R32(_p, _m) __fcc_in32(&(_p)->_m)
+#define S32(_p, _m, _v) W32(_p, _m, R32(_p, _m) | (_v))
+#define C32(_p, _m, _v) W32(_p, _m, R32(_p, _m) & ~(_v))
+
+#define W16(_p, _m, _v) __fcc_out16(&(_p)->_m, (_v))
+#define R16(_p, _m) __fcc_in16(&(_p)->_m)
+#define S16(_p, _m, _v) W16(_p, _m, R16(_p, _m) | (_v))
+#define C16(_p, _m, _v) W16(_p, _m, R16(_p, _m) & ~(_v))
+
+#define W8(_p, _m, _v) __fcc_out8(&(_p)->_m, (_v))
+#define R8(_p, _m) __fcc_in8(&(_p)->_m)
+#define S8(_p, _m, _v) W8(_p, _m, R8(_p, _m) | (_v))
+#define C8(_p, _m, _v) W8(_p, _m, R8(_p, _m) & ~(_v))
+
+/*************************************************/
+
+#define FCC_MAX_MULTICAST_ADDRS 64
+
+#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
+
+#define MAX_CR_CMD_LOOPS 10000
+
+static inline int fcc_cr_cmd(struct fs_enet_private *fep, u32 mcn, u32 op)
+{
+ const struct fs_platform_info *fpi = fep->fpi;
+
+ cpm2_map_t *immap = fs_enet_immap;
+ cpm_cpm2_t *cpmp = &immap->im_cpm;
+ u32 v;
+ int i;
+
+ /* Currently I don't know what feature call will look like. But
+ I guess there'd be something like do_cpm_cmd() which will require page & sblock */
+ v = mk_cr_cmd(fpi->cp_page, fpi->cp_block, mcn, op);
+ W32(cpmp, cp_cpcr, v | CPM_CR_FLG);
+ for (i = 0; i < MAX_CR_CMD_LOOPS; i++)
+ if ((R32(cpmp, cp_cpcr) & CPM_CR_FLG) == 0)
+ break;
+
+ if (i >= MAX_CR_CMD_LOOPS) {
+ printk(KERN_ERR "%s(): Not able to issue CPM command\n",
+ __FUNCTION__);
+ return 1;
+ }
+
+ return 0;
+}
+
+static int do_pd_setup(struct fs_enet_private *fep)
+{
+ struct platform_device *pdev = to_platform_device(fep->dev);
+ struct resource *r;
+
+ /* Fill out IRQ field */
+ fep->interrupt = platform_get_irq(pdev, 0);
+
+ /* Attach the memory for the FCC Parameter RAM */
+ r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "fcc_pram");
+ fep->fcc.ep = (void *)r->start;
+
+ if (fep->fcc.ep == NULL)
+ return -EINVAL;
+
+ r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "fcc_regs");
+ fep->fcc.fccp = (void *)r->start;
+
+ if (fep->fcc.fccp == NULL)
+ return -EINVAL;
+
+ fep->fcc.fcccp = (void *)fep->fpi->fcc_regs_c;
+
+ if (fep->fcc.fcccp == NULL)
+ return -EINVAL;
+
+ return 0;
+}
+
+#define FCC_NAPI_RX_EVENT_MSK (FCC_ENET_RXF | FCC_ENET_RXB)
+#define FCC_RX_EVENT (FCC_ENET_RXF)
+#define FCC_TX_EVENT (FCC_ENET_TXB)
+#define FCC_ERR_EVENT_MSK (FCC_ENET_TXE | FCC_ENET_BSY)
+
+static int setup_data(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ const struct fs_platform_info *fpi = fep->fpi;
+
+ fep->fcc.idx = fs_get_fcc_index(fpi->fs_no);
+ if ((unsigned int)fep->fcc.idx >= 3) /* max 3 FCCs */
+ return -EINVAL;
+
+ fep->fcc.mem = (void *)fpi->mem_offset;
+
+ if (do_pd_setup(fep) != 0)
+ return -EINVAL;
+
+ fep->ev_napi_rx = FCC_NAPI_RX_EVENT_MSK;
+ fep->ev_rx = FCC_RX_EVENT;
+ fep->ev_tx = FCC_TX_EVENT;
+ fep->ev_err = FCC_ERR_EVENT_MSK;
+
+ return 0;
+}
+
+static int allocate_bd(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ const struct fs_platform_info *fpi = fep->fpi;
+
+ fep->ring_base = dma_alloc_coherent(fep->dev,
+ (fpi->tx_ring + fpi->rx_ring) *
+ sizeof(cbd_t), &fep->ring_mem_addr,
+ GFP_KERNEL);
+ if (fep->ring_base == NULL)
+ return -ENOMEM;
+
+ return 0;
+}
+
+static void free_bd(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ const struct fs_platform_info *fpi = fep->fpi;
+
+ if (fep->ring_base)
+ dma_free_coherent(fep->dev,
+ (fpi->tx_ring + fpi->rx_ring) * sizeof(cbd_t),
+ fep->ring_base, fep->ring_mem_addr);
+}
+
+static void cleanup_data(struct net_device *dev)
+{
+ /* nothing */
+}
+
+static void set_promiscuous_mode(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ fcc_t *fccp = fep->fcc.fccp;
+
+ S32(fccp, fcc_fpsmr, FCC_PSMR_PRO);
+}
+
+static void set_multicast_start(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ fcc_enet_t *ep = fep->fcc.ep;
+
+ W32(ep, fen_gaddrh, 0);
+ W32(ep, fen_gaddrl, 0);
+}
+
+static void set_multicast_one(struct net_device *dev, const u8 *mac)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ fcc_enet_t *ep = fep->fcc.ep;
+ u16 taddrh, taddrm, taddrl;
+
+ taddrh = ((u16)mac[5] << 8) | mac[4];
+ taddrm = ((u16)mac[3] << 8) | mac[2];
+ taddrl = ((u16)mac[1] << 8) | mac[0];
+
+ W16(ep, fen_taddrh, taddrh);
+ W16(ep, fen_taddrm, taddrm);
+ W16(ep, fen_taddrl, taddrl);
+ fcc_cr_cmd(fep, 0x0C, CPM_CR_SET_GADDR);
+}
+
+static void set_multicast_finish(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ fcc_t *fccp = fep->fcc.fccp;
+ fcc_enet_t *ep = fep->fcc.ep;
+
+ /* clear promiscuous always */
+ C32(fccp, fcc_fpsmr, FCC_PSMR_PRO);
+
+ /* if all multi or too many multicasts; just enable all */
+ if ((dev->flags & IFF_ALLMULTI) != 0 ||
+ dev->mc_count > FCC_MAX_MULTICAST_ADDRS) {
+
+ W32(ep, fen_gaddrh, 0xffffffff);
+ W32(ep, fen_gaddrl, 0xffffffff);
+ }
+
+ /* read back */
+ fep->fcc.gaddrh = R32(ep, fen_gaddrh);
+ fep->fcc.gaddrl = R32(ep, fen_gaddrl);
+}
+
+static void set_multicast_list(struct net_device *dev)
+{
+ struct dev_mc_list *pmc;
+
+ if ((dev->flags & IFF_PROMISC) == 0) {
+ set_multicast_start(dev);
+ for (pmc = dev->mc_list; pmc != NULL; pmc = pmc->next)
+ set_multicast_one(dev, pmc->dmi_addr);
+ set_multicast_finish(dev);
+ } else
+ set_promiscuous_mode(dev);
+}
+
+static void restart(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ const struct fs_platform_info *fpi = fep->fpi;
+ fcc_t *fccp = fep->fcc.fccp;
+ fcc_c_t *fcccp = fep->fcc.fcccp;
+ fcc_enet_t *ep = fep->fcc.ep;
+ dma_addr_t rx_bd_base_phys, tx_bd_base_phys;
+ u16 paddrh, paddrm, paddrl;
+ u16 mem_addr;
+ const unsigned char *mac;
+ int i;
+
+ C32(fccp, fcc_gfmr, FCC_GFMR_ENR | FCC_GFMR_ENT);
+
+ /* clear everything (slow & steady does it) */
+ for (i = 0; i < sizeof(*ep); i++)
+ __fcc_out8((char *)ep + i, 0);
+
+ /* get physical address */
+ rx_bd_base_phys = fep->ring_mem_addr;
+ tx_bd_base_phys = rx_bd_base_phys + sizeof(cbd_t) * fpi->rx_ring;
+
+ /* point to bds */
+ W32(ep, fen_genfcc.fcc_rbase, rx_bd_base_phys);
+ W32(ep, fen_genfcc.fcc_tbase, tx_bd_base_phys);
+
+ /* Set maximum bytes per receive buffer.
+ * It must be a multiple of 32.
+ */
+ W16(ep, fen_genfcc.fcc_mrblr, PKT_MAXBLR_SIZE);
+
+ W32(ep, fen_genfcc.fcc_rstate, (CPMFCR_GBL | CPMFCR_EB) << 24);
+ W32(ep, fen_genfcc.fcc_tstate, (CPMFCR_GBL | CPMFCR_EB) << 24);
+
+ /* Allocate space in the reserved FCC area of DPRAM for the
+ * internal buffers. No one uses this space (yet), so we
+ * can do this. Later, we will add resource management for
+ * this area.
+ */
+
+ mem_addr = (u32) fep->fcc.mem; /* de-fixup dpram offset */
+
+ W16(ep, fen_genfcc.fcc_riptr, (mem_addr & 0xffff));
+ W16(ep, fen_genfcc.fcc_tiptr, ((mem_addr + 32) & 0xffff));
+ W16(ep, fen_padptr, mem_addr + 64);
+
+ /* fill with special symbol... */
+ memset(fep->fcc.mem + fpi->dpram_offset + 64, 0x88, 32);
+
+ W32(ep, fen_genfcc.fcc_rbptr, 0);
+ W32(ep, fen_genfcc.fcc_tbptr, 0);
+ W32(ep, fen_genfcc.fcc_rcrc, 0);
+ W32(ep, fen_genfcc.fcc_tcrc, 0);
+ W16(ep, fen_genfcc.fcc_res1, 0);
+ W32(ep, fen_genfcc.fcc_res2, 0);
+
+ /* no CAM */
+ W32(ep, fen_camptr, 0);
+
+ /* Set CRC preset and mask */
+ W32(ep, fen_cmask, 0xdebb20e3);
+ W32(ep, fen_cpres, 0xffffffff);
+
+ W32(ep, fen_crcec, 0); /* CRC Error counter */
+ W32(ep, fen_alec, 0); /* alignment error counter */
+ W32(ep, fen_disfc, 0); /* discard frame counter */
+ W16(ep, fen_retlim, 15); /* Retry limit threshold */
+ W16(ep, fen_pper, 0); /* Normal persistence */
+
+ /* set group address */
+ W32(ep, fen_gaddrh, fep->fcc.gaddrh);
+ W32(ep, fen_gaddrl, fep->fcc.gaddrh);
+
+ /* Clear hash filter tables */
+ W32(ep, fen_iaddrh, 0);
+ W32(ep, fen_iaddrl, 0);
+
+ /* Clear the Out-of-sequence TxBD */
+ W16(ep, fen_tfcstat, 0);
+ W16(ep, fen_tfclen, 0);
+ W32(ep, fen_tfcptr, 0);
+
+ W16(ep, fen_mflr, PKT_MAXBUF_SIZE); /* maximum frame length register */
+ W16(ep, fen_minflr, PKT_MINBUF_SIZE); /* minimum frame length register */
+
+ /* set address */
+ mac = dev->dev_addr;
+ paddrh = ((u16)mac[5] << 8) | mac[4];
+ paddrm = ((u16)mac[3] << 8) | mac[2];
+ paddrl = ((u16)mac[1] << 8) | mac[0];
+
+ W16(ep, fen_paddrh, paddrh);
+ W16(ep, fen_paddrm, paddrm);
+ W16(ep, fen_paddrl, paddrl);
+
+ W16(ep, fen_taddrh, 0);
+ W16(ep, fen_taddrm, 0);
+ W16(ep, fen_taddrl, 0);
+
+ W16(ep, fen_maxd1, 1520); /* maximum DMA1 length */
+ W16(ep, fen_maxd2, 1520); /* maximum DMA2 length */
+
+ /* Clear stat counters, in case we ever enable RMON */
+ W32(ep, fen_octc, 0);
+ W32(ep, fen_colc, 0);
+ W32(ep, fen_broc, 0);
+ W32(ep, fen_mulc, 0);
+ W32(ep, fen_uspc, 0);
+ W32(ep, fen_frgc, 0);
+ W32(ep, fen_ospc, 0);
+ W32(ep, fen_jbrc, 0);
+ W32(ep, fen_p64c, 0);
+ W32(ep, fen_p65c, 0);
+ W32(ep, fen_p128c, 0);
+ W32(ep, fen_p256c, 0);
+ W32(ep, fen_p512c, 0);
+ W32(ep, fen_p1024c, 0);
+
+ W16(ep, fen_rfthr, 0); /* Suggested by manual */
+ W16(ep, fen_rfcnt, 0);
+ W16(ep, fen_cftype, 0);
+
+ fs_init_bds(dev);
+
+ /* adjust to speed (for RMII mode) */
+ if (fpi->use_rmii) {
+ if (fep->speed == 100)
+ C8(fcccp, fcc_gfemr, 0x20);
+ else
+ S8(fcccp, fcc_gfemr, 0x20);
+ }
+
+ fcc_cr_cmd(fep, 0x0c, CPM_CR_INIT_TRX);
+
+ /* clear events */
+ W16(fccp, fcc_fcce, 0xffff);
+
+ /* Enable interrupts we wish to service */
+ W16(fccp, fcc_fccm, FCC_ENET_TXE | FCC_ENET_RXF | FCC_ENET_TXB);
+
+ /* Set GFMR to enable Ethernet operating mode */
+ W32(fccp, fcc_gfmr, FCC_GFMR_TCI | FCC_GFMR_MODE_ENET);
+
+ /* set sync/delimiters */
+ W16(fccp, fcc_fdsr, 0xd555);
+
+ W32(fccp, fcc_fpsmr, FCC_PSMR_ENCRC);
+
+ if (fpi->use_rmii)
+ S32(fccp, fcc_fpsmr, FCC_PSMR_RMII);
+
+ /* adjust to duplex mode */
+ if (fep->duplex)
+ S32(fccp, fcc_fpsmr, FCC_PSMR_FDE | FCC_PSMR_LPB);
+ else
+ C32(fccp, fcc_fpsmr, FCC_PSMR_FDE | FCC_PSMR_LPB);
+
+ S32(fccp, fcc_gfmr, FCC_GFMR_ENR | FCC_GFMR_ENT);
+}
+
+static void stop(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ fcc_t *fccp = fep->fcc.fccp;
+
+ /* stop ethernet */
+ C32(fccp, fcc_gfmr, FCC_GFMR_ENR | FCC_GFMR_ENT);
+
+ /* clear events */
+ W16(fccp, fcc_fcce, 0xffff);
+
+ /* clear interrupt mask */
+ W16(fccp, fcc_fccm, 0);
+
+ fs_cleanup_bds(dev);
+}
+
+static void pre_request_irq(struct net_device *dev, int irq)
+{
+ /* nothing */
+}
+
+static void post_free_irq(struct net_device *dev, int irq)
+{
+ /* nothing */
+}
+
+static void napi_clear_rx_event(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ fcc_t *fccp = fep->fcc.fccp;
+
+ W16(fccp, fcc_fcce, FCC_NAPI_RX_EVENT_MSK);
+}
+
+static void napi_enable_rx(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ fcc_t *fccp = fep->fcc.fccp;
+
+ S16(fccp, fcc_fccm, FCC_NAPI_RX_EVENT_MSK);
+}
+
+static void napi_disable_rx(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ fcc_t *fccp = fep->fcc.fccp;
+
+ C16(fccp, fcc_fccm, FCC_NAPI_RX_EVENT_MSK);
+}
+
+static void rx_bd_done(struct net_device *dev)
+{
+ /* nothing */
+}
+
+static void tx_kickstart(struct net_device *dev)
+{
+ /* nothing */
+}
+
+static u32 get_int_events(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ fcc_t *fccp = fep->fcc.fccp;
+
+ return (u32)R16(fccp, fcc_fcce);
+}
+
+static void clear_int_events(struct net_device *dev, u32 int_events)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ fcc_t *fccp = fep->fcc.fccp;
+
+ W16(fccp, fcc_fcce, int_events & 0xffff);
+}
+
+static void ev_error(struct net_device *dev, u32 int_events)
+{
+ printk(KERN_WARNING DRV_MODULE_NAME
+ ": %s FS_ENET ERROR(s) 0x%x\n", dev->name, int_events);
+}
+
+int get_regs(struct net_device *dev, void *p, int *sizep)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+
+ if (*sizep < sizeof(fcc_t) + sizeof(fcc_c_t) + sizeof(fcc_enet_t))
+ return -EINVAL;
+
+ memcpy_fromio(p, fep->fcc.fccp, sizeof(fcc_t));
+ p = (char *)p + sizeof(fcc_t);
+
+ memcpy_fromio(p, fep->fcc.fcccp, sizeof(fcc_c_t));
+ p = (char *)p + sizeof(fcc_c_t);
+
+ memcpy_fromio(p, fep->fcc.ep, sizeof(fcc_enet_t));
+
+ return 0;
+}
+
+int get_regs_len(struct net_device *dev)
+{
+ return sizeof(fcc_t) + sizeof(fcc_c_t) + sizeof(fcc_enet_t);
+}
+
+/* Some transmit errors cause the transmitter to shut
+ * down. We now issue a restart transmit. Since the
+ * errors close the BD and update the pointers, the restart
+ * _should_ pick up without having to reset any of our
+ * pointers either. Also, To workaround 8260 device erratum
+ * CPM37, we must disable and then re-enable the transmitter
+ * following a Late Collision, Underrun, or Retry Limit error.
+ */
+void tx_restart(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ fcc_t *fccp = fep->fcc.fccp;
+
+ C32(fccp, fcc_gfmr, FCC_GFMR_ENT);
+ udelay(10);
+ S32(fccp, fcc_gfmr, FCC_GFMR_ENT);
+
+ fcc_cr_cmd(fep, 0x0C, CPM_CR_RESTART_TX);
+}
+
+/*************************************************************************/
+
+const struct fs_ops fs_fcc_ops = {
+ .setup_data = setup_data,
+ .cleanup_data = cleanup_data,
+ .set_multicast_list = set_multicast_list,
+ .restart = restart,
+ .stop = stop,
+ .pre_request_irq = pre_request_irq,
+ .post_free_irq = post_free_irq,
+ .napi_clear_rx_event = napi_clear_rx_event,
+ .napi_enable_rx = napi_enable_rx,
+ .napi_disable_rx = napi_disable_rx,
+ .rx_bd_done = rx_bd_done,
+ .tx_kickstart = tx_kickstart,
+ .get_int_events = get_int_events,
+ .clear_int_events = clear_int_events,
+ .ev_error = ev_error,
+ .get_regs = get_regs,
+ .get_regs_len = get_regs_len,
+ .tx_restart = tx_restart,
+ .allocate_bd = allocate_bd,
+ .free_bd = free_bd,
+};
diff --git a/drivers/net/fs_enet/mac-fec.c b/drivers/net/fs_enet/mac-fec.c
new file mode 100644
index 000000000000..2e8f44469699
--- /dev/null
+++ b/drivers/net/fs_enet/mac-fec.c
@@ -0,0 +1,654 @@
+/*
+ * Freescale Ethernet controllers
+ *
+ * Copyright (c) 2005 Intracom S.A.
+ * by Pantelis Antoniou <panto@intracom.gr>
+ *
+ * 2005 (c) MontaVista Software, Inc.
+ * Vitaly Bordug <vbordug@ru.mvista.com>
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/string.h>
+#include <linux/ptrace.h>
+#include <linux/errno.h>
+#include <linux/ioport.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/spinlock.h>
+#include <linux/mii.h>
+#include <linux/ethtool.h>
+#include <linux/bitops.h>
+#include <linux/fs.h>
+#include <linux/platform_device.h>
+
+#include <asm/irq.h>
+#include <asm/uaccess.h>
+
+#ifdef CONFIG_8xx
+#include <asm/8xx_immap.h>
+#include <asm/pgtable.h>
+#include <asm/mpc8xx.h>
+#include <asm/commproc.h>
+#endif
+
+#include "fs_enet.h"
+
+/*************************************************/
+
+#if defined(CONFIG_CPM1)
+/* for a CPM1 __raw_xxx's are sufficient */
+#define __fs_out32(addr, x) __raw_writel(x, addr)
+#define __fs_out16(addr, x) __raw_writew(x, addr)
+#define __fs_in32(addr) __raw_readl(addr)
+#define __fs_in16(addr) __raw_readw(addr)
+#else
+/* for others play it safe */
+#define __fs_out32(addr, x) out_be32(addr, x)
+#define __fs_out16(addr, x) out_be16(addr, x)
+#define __fs_in32(addr) in_be32(addr)
+#define __fs_in16(addr) in_be16(addr)
+#endif
+
+/* write */
+#define FW(_fecp, _reg, _v) __fs_out32(&(_fecp)->fec_ ## _reg, (_v))
+
+/* read */
+#define FR(_fecp, _reg) __fs_in32(&(_fecp)->fec_ ## _reg)
+
+/* set bits */
+#define FS(_fecp, _reg, _v) FW(_fecp, _reg, FR(_fecp, _reg) | (_v))
+
+/* clear bits */
+#define FC(_fecp, _reg, _v) FW(_fecp, _reg, FR(_fecp, _reg) & ~(_v))
+
+
+/* CRC polynomium used by the FEC for the multicast group filtering */
+#define FEC_CRC_POLY 0x04C11DB7
+
+#define FEC_MAX_MULTICAST_ADDRS 64
+
+/* Interrupt events/masks.
+*/
+#define FEC_ENET_HBERR 0x80000000U /* Heartbeat error */
+#define FEC_ENET_BABR 0x40000000U /* Babbling receiver */
+#define FEC_ENET_BABT 0x20000000U /* Babbling transmitter */
+#define FEC_ENET_GRA 0x10000000U /* Graceful stop complete */
+#define FEC_ENET_TXF 0x08000000U /* Full frame transmitted */
+#define FEC_ENET_TXB 0x04000000U /* A buffer was transmitted */
+#define FEC_ENET_RXF 0x02000000U /* Full frame received */
+#define FEC_ENET_RXB 0x01000000U /* A buffer was received */
+#define FEC_ENET_MII 0x00800000U /* MII interrupt */
+#define FEC_ENET_EBERR 0x00400000U /* SDMA bus error */
+
+#define FEC_ECNTRL_PINMUX 0x00000004
+#define FEC_ECNTRL_ETHER_EN 0x00000002
+#define FEC_ECNTRL_RESET 0x00000001
+
+#define FEC_RCNTRL_BC_REJ 0x00000010
+#define FEC_RCNTRL_PROM 0x00000008
+#define FEC_RCNTRL_MII_MODE 0x00000004
+#define FEC_RCNTRL_DRT 0x00000002
+#define FEC_RCNTRL_LOOP 0x00000001
+
+#define FEC_TCNTRL_FDEN 0x00000004
+#define FEC_TCNTRL_HBC 0x00000002
+#define FEC_TCNTRL_GTS 0x00000001
+
+
+/* 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
+
+#define FEC_MII_LOOPS 10000
+
+/*
+ * Delay to wait for FEC reset command to complete (in us)
+ */
+#define FEC_RESET_DELAY 50
+
+static int whack_reset(fec_t * fecp)
+{
+ int i;
+
+ FW(fecp, ecntrl, FEC_ECNTRL_PINMUX | FEC_ECNTRL_RESET);
+ for (i = 0; i < FEC_RESET_DELAY; i++) {
+ if ((FR(fecp, ecntrl) & FEC_ECNTRL_RESET) == 0)
+ return 0; /* OK */
+ udelay(1);
+ }
+
+ return -1;
+}
+
+static int do_pd_setup(struct fs_enet_private *fep)
+{
+ struct platform_device *pdev = to_platform_device(fep->dev);
+ struct resource *r;
+
+ /* Fill out IRQ field */
+ fep->interrupt = platform_get_irq_byname(pdev,"interrupt");
+
+ r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "regs");
+ fep->fec.fecp =(void*)r->start;
+
+ if(fep->fec.fecp == NULL)
+ return -EINVAL;
+
+ return 0;
+
+}
+
+#define FEC_NAPI_RX_EVENT_MSK (FEC_ENET_RXF | FEC_ENET_RXB)
+#define FEC_RX_EVENT (FEC_ENET_RXF)
+#define FEC_TX_EVENT (FEC_ENET_TXF)
+#define FEC_ERR_EVENT_MSK (FEC_ENET_HBERR | FEC_ENET_BABR | \
+ FEC_ENET_BABT | FEC_ENET_EBERR)
+
+static int setup_data(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+
+ if (do_pd_setup(fep) != 0)
+ return -EINVAL;
+
+ fep->fec.hthi = 0;
+ fep->fec.htlo = 0;
+
+ fep->ev_napi_rx = FEC_NAPI_RX_EVENT_MSK;
+ fep->ev_rx = FEC_RX_EVENT;
+ fep->ev_tx = FEC_TX_EVENT;
+ fep->ev_err = FEC_ERR_EVENT_MSK;
+
+ return 0;
+}
+
+static int allocate_bd(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ const struct fs_platform_info *fpi = fep->fpi;
+
+ fep->ring_base = dma_alloc_coherent(fep->dev,
+ (fpi->tx_ring + fpi->rx_ring) *
+ sizeof(cbd_t), &fep->ring_mem_addr,
+ GFP_KERNEL);
+ if (fep->ring_base == NULL)
+ return -ENOMEM;
+
+ return 0;
+}
+
+static void free_bd(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ const struct fs_platform_info *fpi = fep->fpi;
+
+ if(fep->ring_base)
+ dma_free_coherent(fep->dev, (fpi->tx_ring + fpi->rx_ring)
+ * sizeof(cbd_t),
+ fep->ring_base,
+ fep->ring_mem_addr);
+}
+
+static void cleanup_data(struct net_device *dev)
+{
+ /* nothing */
+}
+
+static void set_promiscuous_mode(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ fec_t *fecp = fep->fec.fecp;
+
+ FS(fecp, r_cntrl, FEC_RCNTRL_PROM);
+}
+
+static void set_multicast_start(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+
+ fep->fec.hthi = 0;
+ fep->fec.htlo = 0;
+}
+
+static void set_multicast_one(struct net_device *dev, const u8 *mac)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ int temp, hash_index, i, j;
+ u32 crc, csrVal;
+ u8 byte, msb;
+
+ crc = 0xffffffff;
+ for (i = 0; i < 6; i++) {
+ byte = mac[i];
+ for (j = 0; j < 8; j++) {
+ msb = crc >> 31;
+ crc <<= 1;
+ if (msb ^ (byte & 0x1))
+ crc ^= FEC_CRC_POLY;
+ byte >>= 1;
+ }
+ }
+
+ temp = (crc & 0x3f) >> 1;
+ hash_index = ((temp & 0x01) << 4) |
+ ((temp & 0x02) << 2) |
+ ((temp & 0x04)) |
+ ((temp & 0x08) >> 2) |
+ ((temp & 0x10) >> 4);
+ csrVal = 1 << hash_index;
+ if (crc & 1)
+ fep->fec.hthi |= csrVal;
+ else
+ fep->fec.htlo |= csrVal;
+}
+
+static void set_multicast_finish(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ fec_t *fecp = fep->fec.fecp;
+
+ /* if all multi or too many multicasts; just enable all */
+ if ((dev->flags & IFF_ALLMULTI) != 0 ||
+ dev->mc_count > FEC_MAX_MULTICAST_ADDRS) {
+ fep->fec.hthi = 0xffffffffU;
+ fep->fec.htlo = 0xffffffffU;
+ }
+
+ FC(fecp, r_cntrl, FEC_RCNTRL_PROM);
+ FW(fecp, hash_table_high, fep->fec.hthi);
+ FW(fecp, hash_table_low, fep->fec.htlo);
+}
+
+static void set_multicast_list(struct net_device *dev)
+{
+ struct dev_mc_list *pmc;
+
+ if ((dev->flags & IFF_PROMISC) == 0) {
+ set_multicast_start(dev);
+ for (pmc = dev->mc_list; pmc != NULL; pmc = pmc->next)
+ set_multicast_one(dev, pmc->dmi_addr);
+ set_multicast_finish(dev);
+ } else
+ set_promiscuous_mode(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 *fecp = fep->fec.fecp;
+ const struct fs_platform_info *fpi = fep->fpi;
+ dma_addr_t rx_bd_base_phys, tx_bd_base_phys;
+ int r;
+ u32 addrhi, addrlo;
+
+ r = whack_reset(fep->fec.fecp);
+ if (r != 0)
+ printk(KERN_ERR DRV_MODULE_NAME
+ ": %s FEC Reset FAILED!\n", dev->name);
+
+ /*
+ * Set station address.
+ */
+ addrhi = ((u32) dev->dev_addr[0] << 24) |
+ ((u32) dev->dev_addr[1] << 16) |
+ ((u32) dev->dev_addr[2] << 8) |
+ (u32) dev->dev_addr[3];
+ addrlo = ((u32) dev->dev_addr[4] << 24) |
+ ((u32) dev->dev_addr[5] << 16);
+ FW(fecp, addr_low, addrhi);
+ FW(fecp, addr_high, addrlo);
+
+ /*
+ * Reset all multicast.
+ */
+ FW(fecp, hash_table_high, fep->fec.hthi);
+ FW(fecp, hash_table_low, fep->fec.htlo);
+
+ /*
+ * Set maximum receive buffer size.
+ */
+ FW(fecp, r_buff_size, PKT_MAXBLR_SIZE);
+ FW(fecp, r_hash, PKT_MAXBUF_SIZE);
+
+ /* get physical address */
+ rx_bd_base_phys = fep->ring_mem_addr;
+ tx_bd_base_phys = rx_bd_base_phys + sizeof(cbd_t) * fpi->rx_ring;
+
+ /*
+ * Set receive and transmit descriptor base.
+ */
+ FW(fecp, r_des_start, rx_bd_base_phys);
+ FW(fecp, x_des_start, tx_bd_base_phys);
+
+ fs_init_bds(dev);
+
+ /*
+ * Enable big endian and don't care about SDMA FC.
+ */
+ FW(fecp, fun_code, 0x78000000);
+
+ /*
+ * Set MII speed.
+ */
+ FW(fecp, mii_speed, fep->mii_bus->fec.mii_speed);
+
+ /*
+ * Clear any outstanding interrupt.
+ */
+ FW(fecp, ievent, 0xffc0);
+ FW(fecp, ivec, (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
+ */
+ if (fep->duplex) {
+ FC(fecp, r_cntrl, FEC_RCNTRL_DRT);
+ FS(fecp, x_cntrl, FEC_TCNTRL_FDEN); /* FD enable */
+ } else {
+ FS(fecp, r_cntrl, FEC_RCNTRL_DRT);
+ FC(fecp, x_cntrl, FEC_TCNTRL_FDEN); /* FD disable */
+ }
+
+ /*
+ * Enable interrupts we wish to service.
+ */
+ FW(fecp, imask, FEC_ENET_TXF | FEC_ENET_TXB |
+ FEC_ENET_RXF | FEC_ENET_RXB);
+
+ /*
+ * And last, enable the transmit and receive processing.
+ */
+ FW(fecp, ecntrl, FEC_ECNTRL_PINMUX | FEC_ECNTRL_ETHER_EN);
+ FW(fecp, r_des_active, 0x01000000);
+}
+
+static void stop(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ fec_t *fecp = fep->fec.fecp;
+ struct fs_enet_mii_bus *bus = fep->mii_bus;
+ const struct fs_mii_bus_info *bi = bus->bus_info;
+ int i;
+
+ if ((FR(fecp, ecntrl) & FEC_ECNTRL_ETHER_EN) == 0)
+ return; /* already down */
+
+ FW(fecp, x_cntrl, 0x01); /* Graceful transmit stop */
+ for (i = 0; ((FR(fecp, ievent) & 0x10000000) == 0) &&
+ i < FEC_RESET_DELAY; i++)
+ udelay(1);
+
+ if (i == FEC_RESET_DELAY)
+ printk(KERN_WARNING DRV_MODULE_NAME
+ ": %s FEC timeout on graceful transmit stop\n",
+ dev->name);
+ /*
+ * Disable FEC. Let only MII interrupts.
+ */
+ FW(fecp, imask, 0);
+ FC(fecp, ecntrl, FEC_ECNTRL_ETHER_EN);
+
+ fs_cleanup_bds(dev);
+
+ /* shut down FEC1? that's where the mii bus is */
+ if (fep->fec.idx == 0 && bus->refs > 1 && bi->method == fsmii_fec) {
+ FS(fecp, r_cntrl, FEC_RCNTRL_MII_MODE); /* MII enable */
+ FS(fecp, ecntrl, FEC_ECNTRL_PINMUX | FEC_ECNTRL_ETHER_EN);
+ FW(fecp, ievent, FEC_ENET_MII);
+ FW(fecp, mii_speed, bus->fec.mii_speed);
+ }
+}
+
+static void pre_request_irq(struct net_device *dev, int irq)
+{
+ immap_t *immap = fs_enet_immap;
+ u32 siel;
+
+ /* SIU interrupt */
+ if (irq >= SIU_IRQ0 && irq < SIU_LEVEL7) {
+
+ siel = in_be32(&immap->im_siu_conf.sc_siel);
+ if ((irq & 1) == 0)
+ siel |= (0x80000000 >> irq);
+ else
+ siel &= ~(0x80000000 >> (irq & ~1));
+ out_be32(&immap->im_siu_conf.sc_siel, siel);
+ }
+}
+
+static void post_free_irq(struct net_device *dev, int irq)
+{
+ /* nothing */
+}
+
+static void napi_clear_rx_event(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ fec_t *fecp = fep->fec.fecp;
+
+ FW(fecp, ievent, FEC_NAPI_RX_EVENT_MSK);
+}
+
+static void napi_enable_rx(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ fec_t *fecp = fep->fec.fecp;
+
+ FS(fecp, imask, FEC_NAPI_RX_EVENT_MSK);
+}
+
+static void napi_disable_rx(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ fec_t *fecp = fep->fec.fecp;
+
+ FC(fecp, imask, FEC_NAPI_RX_EVENT_MSK);
+}
+
+static void rx_bd_done(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ fec_t *fecp = fep->fec.fecp;
+
+ FW(fecp, r_des_active, 0x01000000);
+}
+
+static void tx_kickstart(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ fec_t *fecp = fep->fec.fecp;
+
+ FW(fecp, x_des_active, 0x01000000);
+}
+
+static u32 get_int_events(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ fec_t *fecp = fep->fec.fecp;
+
+ return FR(fecp, ievent) & FR(fecp, imask);
+}
+
+static void clear_int_events(struct net_device *dev, u32 int_events)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ fec_t *fecp = fep->fec.fecp;
+
+ FW(fecp, ievent, int_events);
+}
+
+static void ev_error(struct net_device *dev, u32 int_events)
+{
+ printk(KERN_WARNING DRV_MODULE_NAME
+ ": %s FEC ERROR(s) 0x%x\n", dev->name, int_events);
+}
+
+int get_regs(struct net_device *dev, void *p, int *sizep)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+
+ if (*sizep < sizeof(fec_t))
+ return -EINVAL;
+
+ memcpy_fromio(p, fep->fec.fecp, sizeof(fec_t));
+
+ return 0;
+}
+
+int get_regs_len(struct net_device *dev)
+{
+ return sizeof(fec_t);
+}
+
+void tx_restart(struct net_device *dev)
+{
+ /* nothing */
+}
+
+/*************************************************************************/
+
+const struct fs_ops fs_fec_ops = {
+ .setup_data = setup_data,
+ .cleanup_data = cleanup_data,
+ .set_multicast_list = set_multicast_list,
+ .restart = restart,
+ .stop = stop,
+ .pre_request_irq = pre_request_irq,
+ .post_free_irq = post_free_irq,
+ .napi_clear_rx_event = napi_clear_rx_event,
+ .napi_enable_rx = napi_enable_rx,
+ .napi_disable_rx = napi_disable_rx,
+ .rx_bd_done = rx_bd_done,
+ .tx_kickstart = tx_kickstart,
+ .get_int_events = get_int_events,
+ .clear_int_events = clear_int_events,
+ .ev_error = ev_error,
+ .get_regs = get_regs,
+ .get_regs_len = get_regs_len,
+ .tx_restart = tx_restart,
+ .allocate_bd = allocate_bd,
+ .free_bd = free_bd,
+};
+
+/***********************************************************************/
+
+static int mii_read(struct fs_enet_mii_bus *bus, int phy_id, int location)
+{
+ fec_t *fecp = bus->fec.fecp;
+ int i, ret = -1;
+
+ if ((FR(fecp, r_cntrl) & FEC_RCNTRL_MII_MODE) == 0)
+ BUG();
+
+ /* Add PHY address to register command. */
+ FW(fecp, mii_data, (phy_id << 23) | mk_mii_read(location));
+
+ for (i = 0; i < FEC_MII_LOOPS; i++)
+ if ((FR(fecp, ievent) & FEC_ENET_MII) != 0)
+ break;
+
+ if (i < FEC_MII_LOOPS) {
+ FW(fecp, ievent, FEC_ENET_MII);
+ ret = FR(fecp, mii_data) & 0xffff;
+ }
+
+ return ret;
+}
+
+static void mii_write(struct fs_enet_mii_bus *bus, int phy_id, int location, int value)
+{
+ fec_t *fecp = bus->fec.fecp;
+ int i;
+
+ /* this must never happen */
+ if ((FR(fecp, r_cntrl) & FEC_RCNTRL_MII_MODE) == 0)
+ BUG();
+
+ /* Add PHY address to register command. */
+ FW(fecp, mii_data, (phy_id << 23) | mk_mii_write(location, value));
+
+ for (i = 0; i < FEC_MII_LOOPS; i++)
+ if ((FR(fecp, ievent) & FEC_ENET_MII) != 0)
+ break;
+
+ if (i < FEC_MII_LOOPS)
+ FW(fecp, ievent, FEC_ENET_MII);
+}
+
+int fs_mii_fec_init(struct fs_enet_mii_bus *bus)
+{
+ bd_t *bd = (bd_t *)__res;
+ const struct fs_mii_bus_info *bi = bus->bus_info;
+ fec_t *fecp;
+
+ if (bi->id != 0)
+ return -1;
+
+ bus->fec.fecp = &((immap_t *)fs_enet_immap)->im_cpm.cp_fec;
+ bus->fec.mii_speed = ((((bd->bi_intfreq + 4999999) / 2500000) / 2)
+ & 0x3F) << 1;
+
+ fecp = bus->fec.fecp;
+
+ FS(fecp, r_cntrl, FEC_RCNTRL_MII_MODE); /* MII enable */
+ FS(fecp, ecntrl, FEC_ECNTRL_PINMUX | FEC_ECNTRL_ETHER_EN);
+ FW(fecp, ievent, FEC_ENET_MII);
+ FW(fecp, mii_speed, bus->fec.mii_speed);
+
+ bus->mii_read = mii_read;
+ bus->mii_write = mii_write;
+
+ return 0;
+}
diff --git a/drivers/net/fs_enet/mac-scc.c b/drivers/net/fs_enet/mac-scc.c
new file mode 100644
index 000000000000..a3897fda71fa
--- /dev/null
+++ b/drivers/net/fs_enet/mac-scc.c
@@ -0,0 +1,525 @@
+/*
+ * Ethernet on Serial Communications Controller (SCC) driver for Motorola MPC8xx and MPC82xx.
+ *
+ * Copyright (c) 2003 Intracom S.A.
+ * by Pantelis Antoniou <panto@intracom.gr>
+ *
+ * 2005 (c) MontaVista Software, Inc.
+ * Vitaly Bordug <vbordug@ru.mvista.com>
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/string.h>
+#include <linux/ptrace.h>
+#include <linux/errno.h>
+#include <linux/ioport.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/spinlock.h>
+#include <linux/mii.h>
+#include <linux/ethtool.h>
+#include <linux/bitops.h>
+#include <linux/fs.h>
+#include <linux/platform_device.h>
+
+#include <asm/irq.h>
+#include <asm/uaccess.h>
+
+#ifdef CONFIG_8xx
+#include <asm/8xx_immap.h>
+#include <asm/pgtable.h>
+#include <asm/mpc8xx.h>
+#include <asm/commproc.h>
+#endif
+
+#include "fs_enet.h"
+
+/*************************************************/
+
+#if defined(CONFIG_CPM1)
+/* for a 8xx __raw_xxx's are sufficient */
+#define __fs_out32(addr, x) __raw_writel(x, addr)
+#define __fs_out16(addr, x) __raw_writew(x, addr)
+#define __fs_out8(addr, x) __raw_writeb(x, addr)
+#define __fs_in32(addr) __raw_readl(addr)
+#define __fs_in16(addr) __raw_readw(addr)
+#define __fs_in8(addr) __raw_readb(addr)
+#else
+/* for others play it safe */
+#define __fs_out32(addr, x) out_be32(addr, x)
+#define __fs_out16(addr, x) out_be16(addr, x)
+#define __fs_in32(addr) in_be32(addr)
+#define __fs_in16(addr) in_be16(addr)
+#endif
+
+/* write, read, set bits, clear bits */
+#define W32(_p, _m, _v) __fs_out32(&(_p)->_m, (_v))
+#define R32(_p, _m) __fs_in32(&(_p)->_m)
+#define S32(_p, _m, _v) W32(_p, _m, R32(_p, _m) | (_v))
+#define C32(_p, _m, _v) W32(_p, _m, R32(_p, _m) & ~(_v))
+
+#define W16(_p, _m, _v) __fs_out16(&(_p)->_m, (_v))
+#define R16(_p, _m) __fs_in16(&(_p)->_m)
+#define S16(_p, _m, _v) W16(_p, _m, R16(_p, _m) | (_v))
+#define C16(_p, _m, _v) W16(_p, _m, R16(_p, _m) & ~(_v))
+
+#define W8(_p, _m, _v) __fs_out8(&(_p)->_m, (_v))
+#define R8(_p, _m) __fs_in8(&(_p)->_m)
+#define S8(_p, _m, _v) W8(_p, _m, R8(_p, _m) | (_v))
+#define C8(_p, _m, _v) W8(_p, _m, R8(_p, _m) & ~(_v))
+
+#define SCC_MAX_MULTICAST_ADDRS 64
+
+/*
+ * Delay to wait for SCC reset command to complete (in us)
+ */
+#define SCC_RESET_DELAY 50
+#define MAX_CR_CMD_LOOPS 10000
+
+static inline int scc_cr_cmd(struct fs_enet_private *fep, u32 op)
+{
+ cpm8xx_t *cpmp = &((immap_t *)fs_enet_immap)->im_cpm;
+ u32 v, ch;
+ int i = 0;
+
+ ch = fep->scc.idx << 2;
+ v = mk_cr_cmd(ch, op);
+ W16(cpmp, cp_cpcr, v | CPM_CR_FLG);
+ for (i = 0; i < MAX_CR_CMD_LOOPS; i++)
+ if ((R16(cpmp, cp_cpcr) & CPM_CR_FLG) == 0)
+ break;
+
+ if (i >= MAX_CR_CMD_LOOPS) {
+ printk(KERN_ERR "%s(): Not able to issue CPM command\n",
+ __FUNCTION__);
+ return 1;
+ }
+ return 0;
+}
+
+static int do_pd_setup(struct fs_enet_private *fep)
+{
+ struct platform_device *pdev = to_platform_device(fep->dev);
+ struct resource *r;
+
+ /* Fill out IRQ field */
+ fep->interrupt = platform_get_irq_byname(pdev, "interrupt");
+
+ r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "regs");
+ fep->scc.sccp = (void *)r->start;
+
+ if (fep->scc.sccp == NULL)
+ return -EINVAL;
+
+ r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pram");
+ fep->scc.ep = (void *)r->start;
+
+ if (fep->scc.ep == NULL)
+ return -EINVAL;
+
+ return 0;
+}
+
+#define SCC_NAPI_RX_EVENT_MSK (SCCE_ENET_RXF | SCCE_ENET_RXB)
+#define SCC_RX_EVENT (SCCE_ENET_RXF)
+#define SCC_TX_EVENT (SCCE_ENET_TXB)
+#define SCC_ERR_EVENT_MSK (SCCE_ENET_TXE | SCCE_ENET_BSY)
+
+static int setup_data(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ const struct fs_platform_info *fpi = fep->fpi;
+
+ fep->scc.idx = fs_get_scc_index(fpi->fs_no);
+ if ((unsigned int)fep->fcc.idx > 4) /* max 4 SCCs */
+ return -EINVAL;
+
+ do_pd_setup(fep);
+
+ fep->scc.hthi = 0;
+ fep->scc.htlo = 0;
+
+ fep->ev_napi_rx = SCC_NAPI_RX_EVENT_MSK;
+ fep->ev_rx = SCC_RX_EVENT;
+ fep->ev_tx = SCC_TX_EVENT;
+ fep->ev_err = SCC_ERR_EVENT_MSK;
+
+ return 0;
+}
+
+static int allocate_bd(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ const struct fs_platform_info *fpi = fep->fpi;
+
+ fep->ring_mem_addr = cpm_dpalloc((fpi->tx_ring + fpi->rx_ring) *
+ sizeof(cbd_t), 8);
+ if (IS_DPERR(fep->ring_mem_addr))
+ return -ENOMEM;
+
+ fep->ring_base = cpm_dpram_addr(fep->ring_mem_addr);
+
+ return 0;
+}
+
+static void free_bd(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+
+ if (fep->ring_base)
+ cpm_dpfree(fep->ring_mem_addr);
+}
+
+static void cleanup_data(struct net_device *dev)
+{
+ /* nothing */
+}
+
+static void set_promiscuous_mode(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ scc_t *sccp = fep->scc.sccp;
+
+ S16(sccp, scc_psmr, SCC_PSMR_PRO);
+}
+
+static void set_multicast_start(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ scc_enet_t *ep = fep->scc.ep;
+
+ W16(ep, sen_gaddr1, 0);
+ W16(ep, sen_gaddr2, 0);
+ W16(ep, sen_gaddr3, 0);
+ W16(ep, sen_gaddr4, 0);
+}
+
+static void set_multicast_one(struct net_device *dev, const u8 * mac)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ scc_enet_t *ep = fep->scc.ep;
+ u16 taddrh, taddrm, taddrl;
+
+ taddrh = ((u16) mac[5] << 8) | mac[4];
+ taddrm = ((u16) mac[3] << 8) | mac[2];
+ taddrl = ((u16) mac[1] << 8) | mac[0];
+
+ W16(ep, sen_taddrh, taddrh);
+ W16(ep, sen_taddrm, taddrm);
+ W16(ep, sen_taddrl, taddrl);
+ scc_cr_cmd(fep, CPM_CR_SET_GADDR);
+}
+
+static void set_multicast_finish(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ scc_t *sccp = fep->scc.sccp;
+ scc_enet_t *ep = fep->scc.ep;
+
+ /* clear promiscuous always */
+ C16(sccp, scc_psmr, SCC_PSMR_PRO);
+
+ /* if all multi or too many multicasts; just enable all */
+ if ((dev->flags & IFF_ALLMULTI) != 0 ||
+ dev->mc_count > SCC_MAX_MULTICAST_ADDRS) {
+
+ W16(ep, sen_gaddr1, 0xffff);
+ W16(ep, sen_gaddr2, 0xffff);
+ W16(ep, sen_gaddr3, 0xffff);
+ W16(ep, sen_gaddr4, 0xffff);
+ }
+}
+
+static void set_multicast_list(struct net_device *dev)
+{
+ struct dev_mc_list *pmc;
+
+ if ((dev->flags & IFF_PROMISC) == 0) {
+ set_multicast_start(dev);
+ for (pmc = dev->mc_list; pmc != NULL; pmc = pmc->next)
+ set_multicast_one(dev, pmc->dmi_addr);
+ set_multicast_finish(dev);
+ } else
+ set_promiscuous_mode(dev);
+}
+
+/*
+ * This function is called to start or restart the FEC during a link
+ * change. This only happens when switching between half and full
+ * duplex.
+ */
+static void restart(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ scc_t *sccp = fep->scc.sccp;
+ scc_enet_t *ep = fep->scc.ep;
+ const struct fs_platform_info *fpi = fep->fpi;
+ u16 paddrh, paddrm, paddrl;
+ const unsigned char *mac;
+ int i;
+
+ C32(sccp, scc_gsmrl, SCC_GSMRL_ENR | SCC_GSMRL_ENT);
+
+ /* clear everything (slow & steady does it) */
+ for (i = 0; i < sizeof(*ep); i++)
+ __fs_out8((char *)ep + i, 0);
+
+ /* point to bds */
+ W16(ep, sen_genscc.scc_rbase, fep->ring_mem_addr);
+ W16(ep, sen_genscc.scc_tbase,
+ fep->ring_mem_addr + sizeof(cbd_t) * fpi->rx_ring);
+
+ /* Initialize function code registers for big-endian.
+ */
+ W8(ep, sen_genscc.scc_rfcr, SCC_EB);
+ W8(ep, sen_genscc.scc_tfcr, SCC_EB);
+
+ /* Set maximum bytes per receive buffer.
+ * This appears to be an Ethernet frame size, not the buffer
+ * fragment size. It must be a multiple of four.
+ */
+ W16(ep, sen_genscc.scc_mrblr, 0x5f0);
+
+ /* Set CRC preset and mask.
+ */
+ W32(ep, sen_cpres, 0xffffffff);
+ W32(ep, sen_cmask, 0xdebb20e3);
+
+ W32(ep, sen_crcec, 0); /* CRC Error counter */
+ W32(ep, sen_alec, 0); /* alignment error counter */
+ W32(ep, sen_disfc, 0); /* discard frame counter */
+
+ W16(ep, sen_pads, 0x8888); /* Tx short frame pad character */
+ W16(ep, sen_retlim, 15); /* Retry limit threshold */
+
+ W16(ep, sen_maxflr, 0x5ee); /* maximum frame length register */
+
+ W16(ep, sen_minflr, PKT_MINBUF_SIZE); /* minimum frame length register */
+
+ W16(ep, sen_maxd1, 0x000005f0); /* maximum DMA1 length */
+ W16(ep, sen_maxd2, 0x000005f0); /* maximum DMA2 length */
+
+ /* Clear hash tables.
+ */
+ W16(ep, sen_gaddr1, 0);
+ W16(ep, sen_gaddr2, 0);
+ W16(ep, sen_gaddr3, 0);
+ W16(ep, sen_gaddr4, 0);
+ W16(ep, sen_iaddr1, 0);
+ W16(ep, sen_iaddr2, 0);
+ W16(ep, sen_iaddr3, 0);
+ W16(ep, sen_iaddr4, 0);
+
+ /* set address
+ */
+ mac = dev->dev_addr;
+ paddrh = ((u16) mac[5] << 8) | mac[4];
+ paddrm = ((u16) mac[3] << 8) | mac[2];
+ paddrl = ((u16) mac[1] << 8) | mac[0];
+
+ W16(ep, sen_paddrh, paddrh);
+ W16(ep, sen_paddrm, paddrm);
+ W16(ep, sen_paddrl, paddrl);
+
+ W16(ep, sen_pper, 0);
+ W16(ep, sen_taddrl, 0);
+ W16(ep, sen_taddrm, 0);
+ W16(ep, sen_taddrh, 0);
+
+ fs_init_bds(dev);
+
+ scc_cr_cmd(fep, CPM_CR_INIT_TRX);
+
+ W16(sccp, scc_scce, 0xffff);
+
+ /* Enable interrupts we wish to service.
+ */
+ W16(sccp, scc_sccm, SCCE_ENET_TXE | SCCE_ENET_RXF | SCCE_ENET_TXB);
+
+ /* Set GSMR_H to enable all normal operating modes.
+ * Set GSMR_L to enable Ethernet to MC68160.
+ */
+ W32(sccp, scc_gsmrh, 0);
+ W32(sccp, scc_gsmrl,
+ SCC_GSMRL_TCI | SCC_GSMRL_TPL_48 | SCC_GSMRL_TPP_10 |
+ SCC_GSMRL_MODE_ENET);
+
+ /* Set sync/delimiters.
+ */
+ W16(sccp, scc_dsr, 0xd555);
+
+ /* Set processing mode. Use Ethernet CRC, catch broadcast, and
+ * start frame search 22 bit times after RENA.
+ */
+ W16(sccp, scc_psmr, SCC_PSMR_ENCRC | SCC_PSMR_NIB22);
+
+ /* Set full duplex mode if needed */
+ if (fep->duplex)
+ S16(sccp, scc_psmr, SCC_PSMR_LPB | SCC_PSMR_FDE);
+
+ S32(sccp, scc_gsmrl, SCC_GSMRL_ENR | SCC_GSMRL_ENT);
+}
+
+static void stop(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ scc_t *sccp = fep->scc.sccp;
+ int i;
+
+ for (i = 0; (R16(sccp, scc_sccm) == 0) && i < SCC_RESET_DELAY; i++)
+ udelay(1);
+
+ if (i == SCC_RESET_DELAY)
+ printk(KERN_WARNING DRV_MODULE_NAME
+ ": %s SCC timeout on graceful transmit stop\n",
+ dev->name);
+
+ W16(sccp, scc_sccm, 0);
+ C32(sccp, scc_gsmrl, SCC_GSMRL_ENR | SCC_GSMRL_ENT);
+
+ fs_cleanup_bds(dev);
+}
+
+static void pre_request_irq(struct net_device *dev, int irq)
+{
+ immap_t *immap = fs_enet_immap;
+ u32 siel;
+
+ /* SIU interrupt */
+ if (irq >= SIU_IRQ0 && irq < SIU_LEVEL7) {
+
+ siel = in_be32(&immap->im_siu_conf.sc_siel);
+ if ((irq & 1) == 0)
+ siel |= (0x80000000 >> irq);
+ else
+ siel &= ~(0x80000000 >> (irq & ~1));
+ out_be32(&immap->im_siu_conf.sc_siel, siel);
+ }
+}
+
+static void post_free_irq(struct net_device *dev, int irq)
+{
+ /* nothing */
+}
+
+static void napi_clear_rx_event(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ scc_t *sccp = fep->scc.sccp;
+
+ W16(sccp, scc_scce, SCC_NAPI_RX_EVENT_MSK);
+}
+
+static void napi_enable_rx(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ scc_t *sccp = fep->scc.sccp;
+
+ S16(sccp, scc_sccm, SCC_NAPI_RX_EVENT_MSK);
+}
+
+static void napi_disable_rx(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ scc_t *sccp = fep->scc.sccp;
+
+ C16(sccp, scc_sccm, SCC_NAPI_RX_EVENT_MSK);
+}
+
+static void rx_bd_done(struct net_device *dev)
+{
+ /* nothing */
+}
+
+static void tx_kickstart(struct net_device *dev)
+{
+ /* nothing */
+}
+
+static u32 get_int_events(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ scc_t *sccp = fep->scc.sccp;
+
+ return (u32) R16(sccp, scc_scce);
+}
+
+static void clear_int_events(struct net_device *dev, u32 int_events)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+ scc_t *sccp = fep->scc.sccp;
+
+ W16(sccp, scc_scce, int_events & 0xffff);
+}
+
+static void ev_error(struct net_device *dev, u32 int_events)
+{
+ printk(KERN_WARNING DRV_MODULE_NAME
+ ": %s SCC ERROR(s) 0x%x\n", dev->name, int_events);
+}
+
+static int get_regs(struct net_device *dev, void *p, int *sizep)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+
+ if (*sizep < sizeof(scc_t) + sizeof(scc_enet_t))
+ return -EINVAL;
+
+ memcpy_fromio(p, fep->scc.sccp, sizeof(scc_t));
+ p = (char *)p + sizeof(scc_t);
+
+ memcpy_fromio(p, fep->scc.ep, sizeof(scc_enet_t));
+
+ return 0;
+}
+
+static int get_regs_len(struct net_device *dev)
+{
+ return sizeof(scc_t) + sizeof(scc_enet_t);
+}
+
+static void tx_restart(struct net_device *dev)
+{
+ struct fs_enet_private *fep = netdev_priv(dev);
+
+ scc_cr_cmd(fep, CPM_CR_RESTART_TX);
+}
+
+/*************************************************************************/
+
+const struct fs_ops fs_scc_ops = {
+ .setup_data = setup_data,
+ .cleanup_data = cleanup_data,
+ .set_multicast_list = set_multicast_list,
+ .restart = restart,
+ .stop = stop,
+ .pre_request_irq = pre_request_irq,
+ .post_free_irq = post_free_irq,
+ .napi_clear_rx_event = napi_clear_rx_event,
+ .napi_enable_rx = napi_enable_rx,
+ .napi_disable_rx = napi_disable_rx,
+ .rx_bd_done = rx_bd_done,
+ .tx_kickstart = tx_kickstart,
+ .get_int_events = get_int_events,
+ .clear_int_events = clear_int_events,
+ .ev_error = ev_error,
+ .get_regs = get_regs,
+ .get_regs_len = get_regs_len,
+ .tx_restart = tx_restart,
+ .allocate_bd = allocate_bd,
+ .free_bd = free_bd,
+};
diff --git a/drivers/net/fs_enet/mii-bitbang.c b/drivers/net/fs_enet/mii-bitbang.c
new file mode 100644
index 000000000000..24a5e2e23d18
--- /dev/null
+++ b/drivers/net/fs_enet/mii-bitbang.c
@@ -0,0 +1,405 @@
+/*
+ * Combined Ethernet driver for Motorola MPC8xx and MPC82xx.
+ *
+ * Copyright (c) 2003 Intracom S.A.
+ * by Pantelis Antoniou <panto@intracom.gr>
+ *
+ * 2005 (c) MontaVista Software, Inc.
+ * Vitaly Bordug <vbordug@ru.mvista.com>
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/string.h>
+#include <linux/ptrace.h>
+#include <linux/errno.h>
+#include <linux/ioport.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/spinlock.h>
+#include <linux/mii.h>
+#include <linux/ethtool.h>
+#include <linux/bitops.h>
+
+#include <asm/pgtable.h>
+#include <asm/irq.h>
+#include <asm/uaccess.h>
+
+#include "fs_enet.h"
+
+#ifdef CONFIG_8xx
+static int bitbang_prep_bit(u8 **dirp, u8 **datp, u8 *mskp, int port, int bit)
+{
+ immap_t *im = (immap_t *)fs_enet_immap;
+ void *dir, *dat, *ppar;
+ int adv;
+ u8 msk;
+
+ switch (port) {
+ case fsiop_porta:
+ dir = &im->im_ioport.iop_padir;
+ dat = &im->im_ioport.iop_padat;
+ ppar = &im->im_ioport.iop_papar;
+ break;
+
+ case fsiop_portb:
+ dir = &im->im_cpm.cp_pbdir;
+ dat = &im->im_cpm.cp_pbdat;
+ ppar = &im->im_cpm.cp_pbpar;
+ break;
+
+ case fsiop_portc:
+ dir = &im->im_ioport.iop_pcdir;
+ dat = &im->im_ioport.iop_pcdat;
+ ppar = &im->im_ioport.iop_pcpar;
+ break;
+
+ case fsiop_portd:
+ dir = &im->im_ioport.iop_pddir;
+ dat = &im->im_ioport.iop_pddat;
+ ppar = &im->im_ioport.iop_pdpar;
+ break;
+
+ case fsiop_porte:
+ dir = &im->im_cpm.cp_pedir;
+ dat = &im->im_cpm.cp_pedat;
+ ppar = &im->im_cpm.cp_pepar;
+ break;
+
+ default:
+ printk(KERN_ERR DRV_MODULE_NAME
+ "Illegal port value %d!\n", port);
+ return -EINVAL;
+ }
+
+ adv = bit >> 3;
+ dir = (char *)dir + adv;
+ dat = (char *)dat + adv;
+ ppar = (char *)ppar + adv;
+
+ msk = 1 << (7 - (bit & 7));
+ if ((in_8(ppar) & msk) != 0) {
+ printk(KERN_ERR DRV_MODULE_NAME
+ "pin %d on port %d is not general purpose!\n", bit, port);
+ return -EINVAL;
+ }
+
+ *dirp = dir;
+ *datp = dat;
+ *mskp = msk;
+
+ return 0;
+}
+#endif
+
+#ifdef CONFIG_8260
+static int bitbang_prep_bit(u8 **dirp, u8 **datp, u8 *mskp, int port, int bit)
+{
+ iop_cpm2_t *io = &((cpm2_map_t *)fs_enet_immap)->im_ioport;
+ void *dir, *dat, *ppar;
+ int adv;
+ u8 msk;
+
+ switch (port) {
+ case fsiop_porta:
+ dir = &io->iop_pdira;
+ dat = &io->iop_pdata;
+ ppar = &io->iop_ppara;
+ break;
+
+ case fsiop_portb:
+ dir = &io->iop_pdirb;
+ dat = &io->iop_pdatb;
+ ppar = &io->iop_pparb;
+ break;
+
+ case fsiop_portc:
+ dir = &io->iop_pdirc;
+ dat = &io->iop_pdatc;
+ ppar = &io->iop_pparc;
+ break;
+
+ case fsiop_portd:
+ dir = &io->iop_pdird;
+ dat = &io->iop_pdatd;
+ ppar = &io->iop_ppard;
+ break;
+
+ default:
+ printk(KERN_ERR DRV_MODULE_NAME
+ "Illegal port value %d!\n", port);
+ return -EINVAL;
+ }
+
+ adv = bit >> 3;
+ dir = (char *)dir + adv;
+ dat = (char *)dat + adv;
+ ppar = (char *)ppar + adv;
+
+ msk = 1 << (7 - (bit & 7));
+ if ((in_8(ppar) & msk) != 0) {
+ printk(KERN_ERR DRV_MODULE_NAME
+ "pin %d on port %d is not general purpose!\n", bit, port);
+ return -EINVAL;
+ }
+
+ *dirp = dir;
+ *datp = dat;
+ *mskp = msk;
+
+ return 0;
+}
+#endif
+
+static inline void bb_set(u8 *p, u8 m)
+{
+ out_8(p, in_8(p) | m);
+}
+
+static inline void bb_clr(u8 *p, u8 m)
+{
+ out_8(p, in_8(p) & ~m);
+}
+
+static inline int bb_read(u8 *p, u8 m)
+{
+ return (in_8(p) & m) != 0;
+}
+
+static inline void mdio_active(struct fs_enet_mii_bus *bus)
+{
+ bb_set(bus->bitbang.mdio_dir, bus->bitbang.mdio_msk);
+}
+
+static inline void mdio_tristate(struct fs_enet_mii_bus *bus)
+{
+ bb_clr(bus->bitbang.mdio_dir, bus->bitbang.mdio_msk);
+}
+
+static inline int mdio_read(struct fs_enet_mii_bus *bus)
+{
+ return bb_read(bus->bitbang.mdio_dat, bus->bitbang.mdio_msk);
+}
+
+static inline void mdio(struct fs_enet_mii_bus *bus, int what)
+{
+ if (what)
+ bb_set(bus->bitbang.mdio_dat, bus->bitbang.mdio_msk);
+ else
+ bb_clr(bus->bitbang.mdio_dat, bus->bitbang.mdio_msk);
+}
+
+static inline void mdc(struct fs_enet_mii_bus *bus, int what)
+{
+ if (what)
+ bb_set(bus->bitbang.mdc_dat, bus->bitbang.mdc_msk);
+ else
+ bb_clr(bus->bitbang.mdc_dat, bus->bitbang.mdc_msk);
+}
+
+static inline void mii_delay(struct fs_enet_mii_bus *bus)
+{
+ udelay(bus->bus_info->i.bitbang.delay);
+}
+
+/* Utility to send the preamble, address, and register (common to read and write). */
+static void bitbang_pre(struct fs_enet_mii_bus *bus, int read, u8 addr, u8 reg)
+{
+ int j;
+
+ /*
+ * Send a 32 bit preamble ('1's) with an extra '1' bit for good measure.
+ * The IEEE spec says this is a PHY optional requirement. The AMD
+ * 79C874 requires one after power up and one after a MII communications
+ * error. This means that we are doing more preambles than we need,
+ * but it is safer and will be much more robust.
+ */
+
+ mdio_active(bus);
+ mdio(bus, 1);
+ for (j = 0; j < 32; j++) {
+ mdc(bus, 0);
+ mii_delay(bus);
+ mdc(bus, 1);
+ mii_delay(bus);
+ }
+
+ /* send the start bit (01) and the read opcode (10) or write (10) */
+ mdc(bus, 0);
+ mdio(bus, 0);
+ mii_delay(bus);
+ mdc(bus, 1);
+ mii_delay(bus);
+ mdc(bus, 0);
+ mdio(bus, 1);
+ mii_delay(bus);
+ mdc(bus, 1);
+ mii_delay(bus);
+ mdc(bus, 0);
+ mdio(bus, read);
+ mii_delay(bus);
+ mdc(bus, 1);
+ mii_delay(bus);
+ mdc(bus, 0);
+ mdio(bus, !read);
+ mii_delay(bus);
+ mdc(bus, 1);
+ mii_delay(bus);
+
+ /* send the PHY address */
+ for (j = 0; j < 5; j++) {
+ mdc(bus, 0);
+ mdio(bus, (addr & 0x10) != 0);
+ mii_delay(bus);
+ mdc(bus, 1);
+ mii_delay(bus);
+ addr <<= 1;
+ }
+
+ /* send the register address */
+ for (j = 0; j < 5; j++) {
+ mdc(bus, 0);
+ mdio(bus, (reg & 0x10) != 0);
+ mii_delay(bus);
+ mdc(bus, 1);
+ mii_delay(bus);
+ reg <<= 1;
+ }
+}
+
+static int mii_read(struct fs_enet_mii_bus *bus, int phy_id, int location)
+{
+ u16 rdreg;
+ int ret, j;
+ u8 addr = phy_id & 0xff;
+ u8 reg = location & 0xff;
+
+ bitbang_pre(bus, 1, addr, reg);
+
+ /* tri-state our MDIO I/O pin so we can read */
+ mdc(bus, 0);
+ mdio_tristate(bus);
+ mii_delay(bus);
+ mdc(bus, 1);
+ mii_delay(bus);
+
+ /* check the turnaround bit: the PHY should be driving it to zero */
+ if (mdio_read(bus) != 0) {
+ /* PHY didn't drive TA low */
+ for (j = 0; j < 32; j++) {
+ mdc(bus, 0);
+ mii_delay(bus);
+ mdc(bus, 1);
+ mii_delay(bus);
+ }
+ ret = -1;
+ goto out;
+ }
+
+ mdc(bus, 0);
+ mii_delay(bus);
+
+ /* read 16 bits of register data, MSB first */
+ rdreg = 0;
+ for (j = 0; j < 16; j++) {
+ mdc(bus, 1);
+ mii_delay(bus);
+ rdreg <<= 1;
+ rdreg |= mdio_read(bus);
+ mdc(bus, 0);
+ mii_delay(bus);
+ }
+
+ mdc(bus, 1);
+ mii_delay(bus);
+ mdc(bus, 0);
+ mii_delay(bus);
+ mdc(bus, 1);
+ mii_delay(bus);
+
+ ret = rdreg;
+out:
+ return ret;
+}
+
+static void mii_write(struct fs_enet_mii_bus *bus, int phy_id, int location, int val)
+{
+ int j;
+ u8 addr = phy_id & 0xff;
+ u8 reg = location & 0xff;
+ u16 value = val & 0xffff;
+
+ bitbang_pre(bus, 0, addr, reg);
+
+ /* send the turnaround (10) */
+ mdc(bus, 0);
+ mdio(bus, 1);
+ mii_delay(bus);
+ mdc(bus, 1);
+ mii_delay(bus);
+ mdc(bus, 0);
+ mdio(bus, 0);
+ mii_delay(bus);
+ mdc(bus, 1);
+ mii_delay(bus);
+
+ /* write 16 bits of register data, MSB first */
+ for (j = 0; j < 16; j++) {
+ mdc(bus, 0);
+ mdio(bus, (value & 0x8000) != 0);
+ mii_delay(bus);
+ mdc(bus, 1);
+ mii_delay(bus);
+ value <<= 1;
+ }
+
+ /*
+ * Tri-state the MDIO line.
+ */
+ mdio_tristate(bus);
+ mdc(bus, 0);
+ mii_delay(bus);
+ mdc(bus, 1);
+ mii_delay(bus);
+}
+
+int fs_mii_bitbang_init(struct fs_enet_mii_bus *bus)
+{
+ const struct fs_mii_bus_info *bi = bus->bus_info;
+ int r;
+
+ r = bitbang_prep_bit(&bus->bitbang.mdio_dir,
+ &bus->bitbang.mdio_dat,
+ &bus->bitbang.mdio_msk,
+ bi->i.bitbang.mdio_port,
+ bi->i.bitbang.mdio_bit);
+ if (r != 0)
+ return r;
+
+ r = bitbang_prep_bit(&bus->bitbang.mdc_dir,
+ &bus->bitbang.mdc_dat,
+ &bus->bitbang.mdc_msk,
+ bi->i.bitbang.mdc_port,
+ bi->i.bitbang.mdc_bit);
+ if (r != 0)
+ return r;
+
+ bus->mii_read = mii_read;
+ bus->mii_write = mii_write;
+
+ return 0;
+}
diff --git a/drivers/net/fs_enet/mii-fixed.c b/drivers/net/fs_enet/mii-fixed.c
new file mode 100644
index 000000000000..b3e192d612e5
--- /dev/null
+++ b/drivers/net/fs_enet/mii-fixed.c
@@ -0,0 +1,92 @@
+/*
+ * Combined Ethernet driver for Motorola MPC8xx and MPC82xx.
+ *
+ * Copyright (c) 2003 Intracom S.A.
+ * by Pantelis Antoniou <panto@intracom.gr>
+ *
+ * 2005 (c) MontaVista Software, Inc.
+ * Vitaly Bordug <vbordug@ru.mvista.com>
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/string.h>
+#include <linux/ptrace.h>
+#include <linux/errno.h>
+#include <linux/ioport.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/spinlock.h>
+#include <linux/mii.h>
+#include <linux/ethtool.h>
+#include <linux/bitops.h>
+
+#include <asm/pgtable.h>
+#include <asm/irq.h>
+#include <asm/uaccess.h>
+
+#include "fs_enet.h"
+
+static const u16 mii_regs[7] = {
+ 0x3100,
+ 0x786d,
+ 0x0fff,
+ 0x0fff,
+ 0x01e1,
+ 0x45e1,
+ 0x0003,
+};
+
+static int mii_read(struct fs_enet_mii_bus *bus, int phy_id, int location)
+{
+ int ret = 0;
+
+ if ((unsigned int)location >= ARRAY_SIZE(mii_regs))
+ return -1;
+
+ if (location != 5)
+ ret = mii_regs[location];
+ else
+ ret = bus->fixed.lpa;
+
+ return ret;
+}
+
+static void mii_write(struct fs_enet_mii_bus *bus, int phy_id, int location, int val)
+{
+ /* do nothing */
+}
+
+int fs_mii_fixed_init(struct fs_enet_mii_bus *bus)
+{
+ const struct fs_mii_bus_info *bi = bus->bus_info;
+
+ bus->fixed.lpa = 0x45e1; /* default 100Mb, full duplex */
+
+ /* if speed is fixed at 10Mb, remove 100Mb modes */
+ if (bi->i.fixed.speed == 10)
+ bus->fixed.lpa &= ~LPA_100;
+
+ /* if duplex is half, remove full duplex modes */
+ if (bi->i.fixed.duplex == 0)
+ bus->fixed.lpa &= ~LPA_DUPLEX;
+
+ bus->mii_read = mii_read;
+ bus->mii_write = mii_write;
+
+ return 0;
+}
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
index 6518334b9280..54d294ad6df5 100644
--- a/drivers/net/gianfar.c
+++ b/drivers/net/gianfar.c
@@ -29,12 +29,7 @@
* define the configuration needed by the board are defined in a
* board structure in arch/ppc/platforms (though I do not
* discount the possibility that other architectures could one
- * day be supported. One assumption the driver currently makes
- * is that the PHY is configured in such a way to advertise all
- * capabilities. This is a sensible default, and on certain
- * PHYs, changing this default encounters substantial errata
- * issues. Future versions may remove this requirement, but for
- * now, it is best for the firmware to ensure this is the case.
+ * day be supported.
*
* The Gianfar Ethernet Controller uses a ring of buffer
* descriptors. The beginning is indicated by a register
@@ -47,7 +42,7 @@
* corresponding bit in the IMASK register is also set (if
* interrupt coalescing is active, then the interrupt may not
* happen immediately, but will wait until either a set number
- * of frames or amount of time have passed.). In NAPI, the
+ * of frames or amount of time have passed). In NAPI, the
* interrupt handler will signal there is work to be done, and
* exit. Without NAPI, the packet(s) will be handled
* immediately. Both methods will start at the last known empty
@@ -75,6 +70,7 @@
#include <linux/sched.h>
#include <linux/string.h>
#include <linux/errno.h>
+#include <linux/unistd.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/init.h>
@@ -85,7 +81,7 @@
#include <linux/if_vlan.h>
#include <linux/spinlock.h>
#include <linux/mm.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <linux/ip.h>
#include <linux/tcp.h>
#include <linux/udp.h>
@@ -94,12 +90,13 @@
#include <asm/irq.h>
#include <asm/uaccess.h>
#include <linux/module.h>
-#include <linux/version.h>
#include <linux/dma-mapping.h>
#include <linux/crc32.h>
+#include <linux/mii.h>
+#include <linux/phy.h>
#include "gianfar.h"
-#include "gianfar_phy.h"
+#include "gianfar_mii.h"
#define TX_TIMEOUT (1*HZ)
#define SKB_ALLOC_TIMEOUT 1000000
@@ -113,9 +110,8 @@
#endif
const char gfar_driver_name[] = "Gianfar Ethernet";
-const char gfar_driver_version[] = "1.1";
+const char gfar_driver_version[] = "1.2";
-int startup_gfar(struct net_device *dev);
static int gfar_enet_open(struct net_device *dev);
static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev);
static void gfar_timeout(struct net_device *dev);
@@ -126,17 +122,13 @@ static int gfar_set_mac_address(struct net_device *dev);
static int gfar_change_mtu(struct net_device *dev, int new_mtu);
static irqreturn_t gfar_error(int irq, void *dev_id, struct pt_regs *regs);
static irqreturn_t gfar_transmit(int irq, void *dev_id, struct pt_regs *regs);
-static irqreturn_t gfar_receive(int irq, void *dev_id, struct pt_regs *regs);
static irqreturn_t gfar_interrupt(int irq, void *dev_id, struct pt_regs *regs);
-static irqreturn_t phy_interrupt(int irq, void *dev_id, struct pt_regs *regs);
-static void gfar_phy_change(void *data);
-static void gfar_phy_timer(unsigned long data);
static void adjust_link(struct net_device *dev);
static void init_registers(struct net_device *dev);
static int init_phy(struct net_device *dev);
static int gfar_probe(struct device *device);
static int gfar_remove(struct device *device);
-void free_skb_resources(struct gfar_private *priv);
+static void free_skb_resources(struct gfar_private *priv);
static void gfar_set_multi(struct net_device *dev);
static void gfar_set_hash_for_addr(struct net_device *dev, u8 *addr);
#ifdef CONFIG_GFAR_NAPI
@@ -144,7 +136,6 @@ static int gfar_poll(struct net_device *dev, int *budget);
#endif
int gfar_clean_rx_ring(struct net_device *dev, int rx_work_limit);
static int gfar_process_frame(struct net_device *dev, struct sk_buff *skb, int length);
-static void gfar_phy_startup_timer(unsigned long data);
static void gfar_vlan_rx_register(struct net_device *netdev,
struct vlan_group *grp);
static void gfar_vlan_rx_kill_vid(struct net_device *netdev, uint16_t vid);
@@ -162,6 +153,9 @@ int gfar_uses_fcb(struct gfar_private *priv)
else
return 0;
}
+
+/* Set up the ethernet device structure, private data,
+ * and anything else we need before we start */
static int gfar_probe(struct device *device)
{
u32 tempval;
@@ -175,7 +169,7 @@ static int gfar_probe(struct device *device)
einfo = (struct gianfar_platform_data *) pdev->dev.platform_data;
- if (einfo == NULL) {
+ if (NULL == einfo) {
printk(KERN_ERR "gfar %d: Missing additional data!\n",
pdev->id);
@@ -185,7 +179,7 @@ static int gfar_probe(struct device *device)
/* Create an ethernet device instance */
dev = alloc_etherdev(sizeof (*priv));
- if (dev == NULL)
+ if (NULL == dev)
return -ENOMEM;
priv = netdev_priv(dev);
@@ -207,20 +201,11 @@ static int gfar_probe(struct device *device)
priv->regs = (struct gfar *)
ioremap(r->start, sizeof (struct gfar));
- if (priv->regs == NULL) {
+ if (NULL == priv->regs) {
err = -ENOMEM;
goto regs_fail;
}
- /* Set the PHY base address */
- priv->phyregs = (struct gfar *)
- ioremap(einfo->phy_reg_addr, sizeof (struct gfar));
-
- if (priv->phyregs == NULL) {
- err = -ENOMEM;
- goto phy_regs_fail;
- }
-
spin_lock_init(&priv->lock);
dev_set_drvdata(device, dev);
@@ -386,12 +371,10 @@ static int gfar_probe(struct device *device)
return 0;
register_fail:
- iounmap((void *) priv->phyregs);
-phy_regs_fail:
iounmap((void *) priv->regs);
regs_fail:
free_netdev(dev);
- return -ENOMEM;
+ return err;
}
static int gfar_remove(struct device *device)
@@ -402,108 +385,41 @@ static int gfar_remove(struct device *device)
dev_set_drvdata(device, NULL);
iounmap((void *) priv->regs);
- iounmap((void *) priv->phyregs);
free_netdev(dev);
return 0;
}
-/* Configure the PHY for dev.
- * returns 0 if success. -1 if failure
+/* Initializes driver's PHY state, and attaches to the PHY.
+ * Returns 0 on success.
*/
static int init_phy(struct net_device *dev)
{
struct gfar_private *priv = netdev_priv(dev);
- struct phy_info *curphy;
- unsigned int timeout = PHY_INIT_TIMEOUT;
- struct gfar *phyregs = priv->phyregs;
- struct gfar_mii_info *mii_info;
- int err;
+ uint gigabit_support =
+ priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_GIGABIT ?
+ SUPPORTED_1000baseT_Full : 0;
+ struct phy_device *phydev;
priv->oldlink = 0;
priv->oldspeed = 0;
priv->oldduplex = -1;
- mii_info = kmalloc(sizeof(struct gfar_mii_info),
- GFP_KERNEL);
-
- if(NULL == mii_info) {
- if (netif_msg_ifup(priv))
- printk(KERN_ERR "%s: Could not allocate mii_info\n",
- dev->name);
- return -ENOMEM;
- }
-
- mii_info->speed = SPEED_1000;
- mii_info->duplex = DUPLEX_FULL;
- mii_info->pause = 0;
- mii_info->link = 1;
-
- mii_info->advertising = (ADVERTISED_10baseT_Half |
- ADVERTISED_10baseT_Full |
- ADVERTISED_100baseT_Half |
- ADVERTISED_100baseT_Full |
- ADVERTISED_1000baseT_Full);
- mii_info->autoneg = 1;
+ phydev = phy_connect(dev, priv->einfo->bus_id, &adjust_link, 0);
- spin_lock_init(&mii_info->mdio_lock);
-
- mii_info->mii_id = priv->einfo->phyid;
-
- mii_info->dev = dev;
-
- mii_info->mdio_read = &read_phy_reg;
- mii_info->mdio_write = &write_phy_reg;
-
- priv->mii_info = mii_info;
-
- /* Reset the management interface */
- gfar_write(&phyregs->miimcfg, MIIMCFG_RESET);
-
- /* Setup the MII Mgmt clock speed */
- gfar_write(&phyregs->miimcfg, MIIMCFG_INIT_VALUE);
-
- /* Wait until the bus is free */
- while ((gfar_read(&phyregs->miimind) & MIIMIND_BUSY) &&
- timeout--)
- cpu_relax();
-
- if(timeout <= 0) {
- printk(KERN_ERR "%s: The MII Bus is stuck!\n",
- dev->name);
- err = -1;
- goto bus_fail;
- }
-
- /* get info for this PHY */
- curphy = get_phy_info(priv->mii_info);
-
- if (curphy == NULL) {
- if (netif_msg_ifup(priv))
- printk(KERN_ERR "%s: No PHY found\n", dev->name);
- err = -1;
- goto no_phy;
+ if (IS_ERR(phydev)) {
+ printk(KERN_ERR "%s: Could not attach to PHY\n", dev->name);
+ return PTR_ERR(phydev);
}
- mii_info->phyinfo = curphy;
+ /* Remove any features not supported by the controller */
+ phydev->supported &= (GFAR_SUPPORTED | gigabit_support);
+ phydev->advertising = phydev->supported;
- /* Run the commands which initialize the PHY */
- if(curphy->init) {
- err = curphy->init(priv->mii_info);
-
- if (err)
- goto phy_init_fail;
- }
+ priv->phydev = phydev;
return 0;
-
-phy_init_fail:
-no_phy:
-bus_fail:
- kfree(mii_info);
-
- return err;
}
static void init_registers(struct net_device *dev)
@@ -603,24 +519,13 @@ void stop_gfar(struct net_device *dev)
struct gfar *regs = priv->regs;
unsigned long flags;
+ phy_stop(priv->phydev);
+
/* Lock it down */
spin_lock_irqsave(&priv->lock, flags);
- /* Tell the kernel the link is down */
- priv->mii_info->link = 0;
- adjust_link(dev);
-
gfar_halt(dev);
- if (priv->einfo->board_flags & FSL_GIANFAR_BRD_HAS_PHY_INTR) {
- /* Clear any pending interrupts */
- mii_clear_phy_interrupt(priv->mii_info);
-
- /* Disable PHY Interrupts */
- mii_configure_phy_interrupt(priv->mii_info,
- MII_INTERRUPT_DISABLED);
- }
-
spin_unlock_irqrestore(&priv->lock, flags);
/* Free the IRQs */
@@ -629,13 +534,7 @@ void stop_gfar(struct net_device *dev)
free_irq(priv->interruptTransmit, dev);
free_irq(priv->interruptReceive, dev);
} else {
- free_irq(priv->interruptTransmit, dev);
- }
-
- if (priv->einfo->board_flags & FSL_GIANFAR_BRD_HAS_PHY_INTR) {
- free_irq(priv->einfo->interruptPHY, dev);
- } else {
- del_timer_sync(&priv->phy_info_timer);
+ free_irq(priv->interruptTransmit, dev);
}
free_skb_resources(priv);
@@ -649,7 +548,7 @@ void stop_gfar(struct net_device *dev)
/* If there are any tx skbs or rx skbs still around, free them.
* Then free tx_skbuff and rx_skbuff */
-void free_skb_resources(struct gfar_private *priv)
+static void free_skb_resources(struct gfar_private *priv)
{
struct rxbd8 *rxbdp;
struct txbd8 *txbdp;
@@ -770,7 +669,7 @@ int startup_gfar(struct net_device *dev)
(struct sk_buff **) kmalloc(sizeof (struct sk_buff *) *
priv->tx_ring_size, GFP_KERNEL);
- if (priv->tx_skbuff == NULL) {
+ if (NULL == priv->tx_skbuff) {
if (netif_msg_ifup(priv))
printk(KERN_ERR "%s: Could not allocate tx_skbuff\n",
dev->name);
@@ -785,7 +684,7 @@ int startup_gfar(struct net_device *dev)
(struct sk_buff **) kmalloc(sizeof (struct sk_buff *) *
priv->rx_ring_size, GFP_KERNEL);
- if (priv->rx_skbuff == NULL) {
+ if (NULL == priv->rx_skbuff) {
if (netif_msg_ifup(priv))
printk(KERN_ERR "%s: Could not allocate rx_skbuff\n",
dev->name);
@@ -879,13 +778,7 @@ int startup_gfar(struct net_device *dev)
}
}
- /* Set up the PHY change work queue */
- INIT_WORK(&priv->tq, gfar_phy_change, dev);
-
- init_timer(&priv->phy_info_timer);
- priv->phy_info_timer.function = &gfar_phy_startup_timer;
- priv->phy_info_timer.data = (unsigned long) priv->mii_info;
- mod_timer(&priv->phy_info_timer, jiffies + HZ);
+ phy_start(priv->phydev);
/* Configure the coalescing support */
if (priv->txcoalescing)
@@ -933,11 +826,6 @@ tx_skb_fail:
priv->tx_bd_base,
gfar_read(&regs->tbase0));
- if (priv->mii_info->phyinfo->close)
- priv->mii_info->phyinfo->close(priv->mii_info);
-
- kfree(priv->mii_info);
-
return err;
}
@@ -1035,7 +923,7 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
txbdp->status &= TXBD_WRAP;
/* Set up checksumming */
- if ((dev->features & NETIF_F_IP_CSUM)
+ if ((dev->features & NETIF_F_IP_CSUM)
&& (CHECKSUM_HW == skb->ip_summed)) {
fcb = gfar_add_fcb(skb, txbdp);
gfar_tx_checksum(skb, fcb);
@@ -1103,11 +991,9 @@ static int gfar_close(struct net_device *dev)
struct gfar_private *priv = netdev_priv(dev);
stop_gfar(dev);
- /* Shutdown the PHY */
- if (priv->mii_info->phyinfo->close)
- priv->mii_info->phyinfo->close(priv->mii_info);
-
- kfree(priv->mii_info);
+ /* Disconnect from the PHY */
+ phy_disconnect(priv->phydev);
+ priv->phydev = NULL;
netif_stop_queue(dev);
@@ -1343,7 +1229,7 @@ struct sk_buff * gfar_new_skb(struct net_device *dev, struct rxbd8 *bdp)
while ((!skb) && timeout--)
skb = dev_alloc_skb(priv->rx_buffer_size + RXBUF_ALIGNMENT);
- if (skb == NULL)
+ if (NULL == skb)
return NULL;
/* We need the data buffer to be aligned properly. We will reserve
@@ -1490,7 +1376,7 @@ static int gfar_process_frame(struct net_device *dev, struct sk_buff *skb,
struct gfar_private *priv = netdev_priv(dev);
struct rxfcb *fcb = NULL;
- if (skb == NULL) {
+ if (NULL == skb) {
if (netif_msg_rx_err(priv))
printk(KERN_WARNING "%s: Missing skb!!.\n", dev->name);
priv->stats.rx_dropped++;
@@ -1718,131 +1604,9 @@ static irqreturn_t gfar_interrupt(int irq, void *dev_id, struct pt_regs *regs)
return IRQ_HANDLED;
}
-static irqreturn_t phy_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-{
- struct net_device *dev = (struct net_device *) dev_id;
- struct gfar_private *priv = netdev_priv(dev);
-
- /* Clear the interrupt */
- mii_clear_phy_interrupt(priv->mii_info);
-
- /* Disable PHY interrupts */
- mii_configure_phy_interrupt(priv->mii_info,
- MII_INTERRUPT_DISABLED);
-
- /* Schedule the phy change */
- schedule_work(&priv->tq);
-
- return IRQ_HANDLED;
-}
-
-/* Scheduled by the phy_interrupt/timer to handle PHY changes */
-static void gfar_phy_change(void *data)
-{
- struct net_device *dev = (struct net_device *) data;
- struct gfar_private *priv = netdev_priv(dev);
- int result = 0;
-
- /* Delay to give the PHY a chance to change the
- * register state */
- msleep(1);
-
- /* Update the link, speed, duplex */
- result = priv->mii_info->phyinfo->read_status(priv->mii_info);
-
- /* Adjust the known status as long as the link
- * isn't still coming up */
- if((0 == result) || (priv->mii_info->link == 0))
- adjust_link(dev);
-
- /* Reenable interrupts, if needed */
- if (priv->einfo->board_flags & FSL_GIANFAR_BRD_HAS_PHY_INTR)
- mii_configure_phy_interrupt(priv->mii_info,
- MII_INTERRUPT_ENABLED);
-}
-
-/* Called every so often on systems that don't interrupt
- * the core for PHY changes */
-static void gfar_phy_timer(unsigned long data)
-{
- struct net_device *dev = (struct net_device *) data;
- struct gfar_private *priv = netdev_priv(dev);
-
- schedule_work(&priv->tq);
-
- mod_timer(&priv->phy_info_timer, jiffies +
- GFAR_PHY_CHANGE_TIME * HZ);
-}
-
-/* Keep trying aneg for some time
- * If, after GFAR_AN_TIMEOUT seconds, it has not
- * finished, we switch to forced.
- * Either way, once the process has completed, we either
- * request the interrupt, or switch the timer over to
- * using gfar_phy_timer to check status */
-static void gfar_phy_startup_timer(unsigned long data)
-{
- int result;
- static int secondary = GFAR_AN_TIMEOUT;
- struct gfar_mii_info *mii_info = (struct gfar_mii_info *)data;
- struct gfar_private *priv = netdev_priv(mii_info->dev);
-
- /* Configure the Auto-negotiation */
- result = mii_info->phyinfo->config_aneg(mii_info);
-
- /* If autonegotiation failed to start, and
- * we haven't timed out, reset the timer, and return */
- if (result && secondary--) {
- mod_timer(&priv->phy_info_timer, jiffies + HZ);
- return;
- } else if (result) {
- /* Couldn't start autonegotiation.
- * Try switching to forced */
- mii_info->autoneg = 0;
- result = mii_info->phyinfo->config_aneg(mii_info);
-
- /* Forcing failed! Give up */
- if(result) {
- if (netif_msg_link(priv))
- printk(KERN_ERR "%s: Forcing failed!\n",
- mii_info->dev->name);
- return;
- }
- }
-
- /* Kill the timer so it can be restarted */
- del_timer_sync(&priv->phy_info_timer);
-
- /* Grab the PHY interrupt, if necessary/possible */
- if (priv->einfo->board_flags & FSL_GIANFAR_BRD_HAS_PHY_INTR) {
- if (request_irq(priv->einfo->interruptPHY,
- phy_interrupt,
- SA_SHIRQ,
- "phy_interrupt",
- mii_info->dev) < 0) {
- if (netif_msg_intr(priv))
- printk(KERN_ERR "%s: Can't get IRQ %d (PHY)\n",
- mii_info->dev->name,
- priv->einfo->interruptPHY);
- } else {
- mii_configure_phy_interrupt(priv->mii_info,
- MII_INTERRUPT_ENABLED);
- return;
- }
- }
-
- /* Start the timer again, this time in order to
- * handle a change in status */
- init_timer(&priv->phy_info_timer);
- priv->phy_info_timer.function = &gfar_phy_timer;
- priv->phy_info_timer.data = (unsigned long) mii_info->dev;
- mod_timer(&priv->phy_info_timer, jiffies +
- GFAR_PHY_CHANGE_TIME * HZ);
-}
-
/* Called every time the controller might need to be made
* aware of new link state. The PHY code conveys this
- * information through variables in the priv structure, and this
+ * information through variables in the phydev structure, and this
* function converts those variables into the appropriate
* register values, and can bring down the device if needed.
*/
@@ -1850,84 +1614,68 @@ static void adjust_link(struct net_device *dev)
{
struct gfar_private *priv = netdev_priv(dev);
struct gfar *regs = priv->regs;
- u32 tempval;
- struct gfar_mii_info *mii_info = priv->mii_info;
+ unsigned long flags;
+ struct phy_device *phydev = priv->phydev;
+ int new_state = 0;
+
+ spin_lock_irqsave(&priv->lock, flags);
+ if (phydev->link) {
+ u32 tempval = gfar_read(&regs->maccfg2);
- if (mii_info->link) {
/* Now we make sure that we can be in full duplex mode.
* If not, we operate in half-duplex mode. */
- if (mii_info->duplex != priv->oldduplex) {
- if (!(mii_info->duplex)) {
- tempval = gfar_read(&regs->maccfg2);
+ if (phydev->duplex != priv->oldduplex) {
+ new_state = 1;
+ if (!(phydev->duplex))
tempval &= ~(MACCFG2_FULL_DUPLEX);
- gfar_write(&regs->maccfg2, tempval);
-
- if (netif_msg_link(priv))
- printk(KERN_INFO "%s: Half Duplex\n",
- dev->name);
- } else {
- tempval = gfar_read(&regs->maccfg2);
+ else
tempval |= MACCFG2_FULL_DUPLEX;
- gfar_write(&regs->maccfg2, tempval);
- if (netif_msg_link(priv))
- printk(KERN_INFO "%s: Full Duplex\n",
- dev->name);
- }
-
- priv->oldduplex = mii_info->duplex;
+ priv->oldduplex = phydev->duplex;
}
- if (mii_info->speed != priv->oldspeed) {
- switch (mii_info->speed) {
+ if (phydev->speed != priv->oldspeed) {
+ new_state = 1;
+ switch (phydev->speed) {
case 1000:
- tempval = gfar_read(&regs->maccfg2);
tempval =
((tempval & ~(MACCFG2_IF)) | MACCFG2_GMII);
- gfar_write(&regs->maccfg2, tempval);
break;
case 100:
case 10:
- tempval = gfar_read(&regs->maccfg2);
tempval =
((tempval & ~(MACCFG2_IF)) | MACCFG2_MII);
- gfar_write(&regs->maccfg2, tempval);
break;
default:
if (netif_msg_link(priv))
printk(KERN_WARNING
- "%s: Ack! Speed (%d) is not 10/100/1000!\n",
- dev->name, mii_info->speed);
+ "%s: Ack! Speed (%d) is not 10/100/1000!\n",
+ dev->name, phydev->speed);
break;
}
- if (netif_msg_link(priv))
- printk(KERN_INFO "%s: Speed %dBT\n", dev->name,
- mii_info->speed);
-
- priv->oldspeed = mii_info->speed;
+ priv->oldspeed = phydev->speed;
}
+ gfar_write(&regs->maccfg2, tempval);
+
if (!priv->oldlink) {
- if (netif_msg_link(priv))
- printk(KERN_INFO "%s: Link is up\n", dev->name);
+ new_state = 1;
priv->oldlink = 1;
- netif_carrier_on(dev);
netif_schedule(dev);
}
- } else {
- if (priv->oldlink) {
- if (netif_msg_link(priv))
- printk(KERN_INFO "%s: Link is down\n",
- dev->name);
- priv->oldlink = 0;
- priv->oldspeed = 0;
- priv->oldduplex = -1;
- netif_carrier_off(dev);
- }
+ } else if (priv->oldlink) {
+ new_state = 1;
+ priv->oldlink = 0;
+ priv->oldspeed = 0;
+ priv->oldduplex = -1;
}
-}
+ if (new_state && netif_msg_link(priv))
+ phy_print_status(phydev);
+
+ spin_unlock_irqrestore(&priv->lock, flags);
+}
/* Update the hash table based on the current list of multicast
* addresses we subscribe to. Also, change the promiscuity of
@@ -2122,12 +1870,23 @@ static struct device_driver gfar_driver = {
static int __init gfar_init(void)
{
- return driver_register(&gfar_driver);
+ int err = gfar_mdio_init();
+
+ if (err)
+ return err;
+
+ err = driver_register(&gfar_driver);
+
+ if (err)
+ gfar_mdio_exit();
+
+ return err;
}
static void __exit gfar_exit(void)
{
driver_unregister(&gfar_driver);
+ gfar_mdio_exit();
}
module_init(gfar_init);
diff --git a/drivers/net/gianfar.h b/drivers/net/gianfar.h
index 28af087d9fbb..220084e53341 100644
--- a/drivers/net/gianfar.h
+++ b/drivers/net/gianfar.h
@@ -17,7 +17,6 @@
*
* Still left to do:
* -Add support for module parameters
- * -Add support for ethtool -s
* -Add patch for ethtool phys id
*/
#ifndef __GIANFAR_H
@@ -37,18 +36,19 @@
#include <linux/skbuff.h>
#include <linux/spinlock.h>
#include <linux/mm.h>
-#include <linux/fsl_devices.h>
+#include <linux/mii.h>
+#include <linux/phy.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/uaccess.h>
#include <linux/module.h>
-#include <linux/version.h>
#include <linux/crc32.h>
#include <linux/workqueue.h>
#include <linux/ethtool.h>
#include <linux/netdevice.h>
-#include "gianfar_phy.h"
+#include <linux/fsl_devices.h>
+#include "gianfar_mii.h"
/* The maximum number of packets to be handled in one call of gfar_poll */
#define GFAR_DEV_WEIGHT 64
@@ -73,7 +73,7 @@
#define PHY_INIT_TIMEOUT 100000
#define GFAR_PHY_CHANGE_TIME 2
-#define DEVICE_NAME "%s: Gianfar Ethernet Controller Version 1.1, "
+#define DEVICE_NAME "%s: Gianfar Ethernet Controller Version 1.2, "
#define DRV_NAME "gfar-enet"
extern const char gfar_driver_name[];
extern const char gfar_driver_version[];
@@ -578,12 +578,7 @@ struct gfar {
u32 hafdup; /* 0x.50c - Half Duplex Register */
u32 maxfrm; /* 0x.510 - Maximum Frame Length Register */
u8 res18[12];
- u32 miimcfg; /* 0x.520 - MII Management Configuration Register */
- u32 miimcom; /* 0x.524 - MII Management Command Register */
- u32 miimadd; /* 0x.528 - MII Management Address Register */
- u32 miimcon; /* 0x.52c - MII Management Control Register */
- u32 miimstat; /* 0x.530 - MII Management Status Register */
- u32 miimind; /* 0x.534 - MII Management Indicator Register */
+ u8 gfar_mii_regs[24]; /* See gianfar_phy.h */
u8 res19[4];
u32 ifstat; /* 0x.53c - Interface Status Register */
u32 macstnaddr1; /* 0x.540 - Station Address Part 1 Register */
@@ -688,9 +683,6 @@ struct gfar_private {
struct gfar *regs; /* Pointer to the GFAR memory mapped Registers */
u32 *hash_regs[16];
int hash_width;
- struct gfar *phyregs;
- struct work_struct tq;
- struct timer_list phy_info_timer;
struct net_device_stats stats; /* linux network statistics */
struct gfar_extra_stats extra_stats;
spinlock_t lock;
@@ -710,7 +702,8 @@ struct gfar_private {
unsigned int interruptError;
struct gianfar_platform_data *einfo;
- struct gfar_mii_info *mii_info;
+ struct phy_device *phydev;
+ struct mii_bus *mii_bus;
int oldspeed;
int oldduplex;
int oldlink;
@@ -732,4 +725,12 @@ extern inline void gfar_write(volatile unsigned *addr, u32 val)
extern struct ethtool_ops *gfar_op_array[];
+extern irqreturn_t gfar_receive(int irq, void *dev_id, struct pt_regs *regs);
+extern int startup_gfar(struct net_device *dev);
+extern void stop_gfar(struct net_device *dev);
+extern void gfar_halt(struct net_device *dev);
+extern void gfar_phy_test(struct mii_bus *bus, struct phy_device *phydev,
+ int enable, u32 regnum, u32 read);
+void gfar_setup_stashing(struct net_device *dev);
+
#endif /* __GIANFAR_H */
diff --git a/drivers/net/gianfar_ethtool.c b/drivers/net/gianfar_ethtool.c
index a451de629197..5a2d810ce575 100644
--- a/drivers/net/gianfar_ethtool.c
+++ b/drivers/net/gianfar_ethtool.c
@@ -34,22 +34,22 @@
#include <asm/irq.h>
#include <asm/uaccess.h>
#include <linux/module.h>
-#include <linux/version.h>
#include <linux/crc32.h>
#include <asm/types.h>
#include <asm/uaccess.h>
#include <linux/ethtool.h>
+#include <linux/mii.h>
+#include <linux/phy.h>
#include "gianfar.h"
#define is_power_of_2(x) ((x) != 0 && (((x) & ((x) - 1)) == 0))
-extern int startup_gfar(struct net_device *dev);
-extern void stop_gfar(struct net_device *dev);
-extern void gfar_halt(struct net_device *dev);
extern void gfar_start(struct net_device *dev);
extern int gfar_clean_rx_ring(struct net_device *dev, int rx_work_limit);
+#define GFAR_MAX_COAL_USECS 0xffff
+#define GFAR_MAX_COAL_FRAMES 0xff
static void gfar_fill_stats(struct net_device *dev, struct ethtool_stats *dummy,
u64 * buf);
static void gfar_gstrings(struct net_device *dev, u32 stringset, u8 * buf);
@@ -182,38 +182,32 @@ static void gfar_gdrvinfo(struct net_device *dev, struct
drvinfo->eedump_len = 0;
}
+
+static int gfar_ssettings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+ struct gfar_private *priv = netdev_priv(dev);
+ struct phy_device *phydev = priv->phydev;
+
+ if (NULL == phydev)
+ return -ENODEV;
+
+ return phy_ethtool_sset(phydev, cmd);
+}
+
+
/* Return the current settings in the ethtool_cmd structure */
static int gfar_gsettings(struct net_device *dev, struct ethtool_cmd *cmd)
{
struct gfar_private *priv = netdev_priv(dev);
- uint gigabit_support =
- priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_GIGABIT ?
- SUPPORTED_1000baseT_Full : 0;
- uint gigabit_advert =
- priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_GIGABIT ?
- ADVERTISED_1000baseT_Full: 0;
-
- cmd->supported = (SUPPORTED_10baseT_Half
- | SUPPORTED_100baseT_Half
- | SUPPORTED_100baseT_Full
- | gigabit_support | SUPPORTED_Autoneg);
-
- /* For now, we always advertise everything */
- cmd->advertising = (ADVERTISED_10baseT_Half
- | ADVERTISED_100baseT_Half
- | ADVERTISED_100baseT_Full
- | gigabit_advert | ADVERTISED_Autoneg);
-
- cmd->speed = priv->mii_info->speed;
- cmd->duplex = priv->mii_info->duplex;
- cmd->port = PORT_MII;
- cmd->phy_address = priv->mii_info->mii_id;
- cmd->transceiver = XCVR_EXTERNAL;
- cmd->autoneg = AUTONEG_ENABLE;
+ struct phy_device *phydev = priv->phydev;
+
+ if (NULL == phydev)
+ return -ENODEV;
+
cmd->maxtxpkt = priv->txcount;
cmd->maxrxpkt = priv->rxcount;
- return 0;
+ return phy_ethtool_gset(phydev, cmd);
}
/* Return the length of the register structure */
@@ -241,14 +235,14 @@ static unsigned int gfar_usecs2ticks(struct gfar_private *priv, unsigned int use
unsigned int count;
/* The timer is different, depending on the interface speed */
- switch (priv->mii_info->speed) {
- case 1000:
+ switch (priv->phydev->speed) {
+ case SPEED_1000:
count = GFAR_GBIT_TIME;
break;
- case 100:
+ case SPEED_100:
count = GFAR_100_TIME;
break;
- case 10:
+ case SPEED_10:
default:
count = GFAR_10_TIME;
break;
@@ -265,14 +259,14 @@ static unsigned int gfar_ticks2usecs(struct gfar_private *priv, unsigned int tic
unsigned int count;
/* The timer is different, depending on the interface speed */
- switch (priv->mii_info->speed) {
- case 1000:
+ switch (priv->phydev->speed) {
+ case SPEED_1000:
count = GFAR_GBIT_TIME;
break;
- case 100:
+ case SPEED_100:
count = GFAR_100_TIME;
break;
- case 10:
+ case SPEED_10:
default:
count = GFAR_10_TIME;
break;
@@ -292,6 +286,9 @@ static int gfar_gcoalesce(struct net_device *dev, struct ethtool_coalesce *cvals
if (!(priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_COALESCE))
return -EOPNOTSUPP;
+ if (NULL == priv->phydev)
+ return -ENODEV;
+
cvals->rx_coalesce_usecs = gfar_ticks2usecs(priv, priv->rxtime);
cvals->rx_max_coalesced_frames = priv->rxcount;
@@ -348,6 +345,22 @@ static int gfar_scoalesce(struct net_device *dev, struct ethtool_coalesce *cvals
else
priv->rxcoalescing = 1;
+ if (NULL == priv->phydev)
+ return -ENODEV;
+
+ /* Check the bounds of the values */
+ if (cvals->rx_coalesce_usecs > GFAR_MAX_COAL_USECS) {
+ pr_info("Coalescing is limited to %d microseconds\n",
+ GFAR_MAX_COAL_USECS);
+ return -EINVAL;
+ }
+
+ if (cvals->rx_max_coalesced_frames > GFAR_MAX_COAL_FRAMES) {
+ pr_info("Coalescing is limited to %d frames\n",
+ GFAR_MAX_COAL_FRAMES);
+ return -EINVAL;
+ }
+
priv->rxtime = gfar_usecs2ticks(priv, cvals->rx_coalesce_usecs);
priv->rxcount = cvals->rx_max_coalesced_frames;
@@ -358,6 +371,19 @@ static int gfar_scoalesce(struct net_device *dev, struct ethtool_coalesce *cvals
else
priv->txcoalescing = 1;
+ /* Check the bounds of the values */
+ if (cvals->tx_coalesce_usecs > GFAR_MAX_COAL_USECS) {
+ pr_info("Coalescing is limited to %d microseconds\n",
+ GFAR_MAX_COAL_USECS);
+ return -EINVAL;
+ }
+
+ if (cvals->tx_max_coalesced_frames > GFAR_MAX_COAL_FRAMES) {
+ pr_info("Coalescing is limited to %d frames\n",
+ GFAR_MAX_COAL_FRAMES);
+ return -EINVAL;
+ }
+
priv->txtime = gfar_usecs2ticks(priv, cvals->tx_coalesce_usecs);
priv->txcount = cvals->tx_max_coalesced_frames;
@@ -536,6 +562,7 @@ static void gfar_set_msglevel(struct net_device *dev, uint32_t data)
struct ethtool_ops gfar_ethtool_ops = {
.get_settings = gfar_gsettings,
+ .set_settings = gfar_ssettings,
.get_drvinfo = gfar_gdrvinfo,
.get_regs_len = gfar_reglen,
.get_regs = gfar_get_regs,
diff --git a/drivers/net/gianfar_mii.c b/drivers/net/gianfar_mii.c
new file mode 100644
index 000000000000..7263395d78bb
--- /dev/null
+++ b/drivers/net/gianfar_mii.c
@@ -0,0 +1,219 @@
+/*
+ * drivers/net/gianfar_mii.c
+ *
+ * Gianfar Ethernet Driver -- MIIM bus implementation
+ * Provides Bus interface for MIIM regs
+ *
+ * Author: Andy Fleming
+ * Maintainer: Kumar Gala (kumar.gala@freescale.com)
+ *
+ * Copyright (c) 2002-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.
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/string.h>
+#include <linux/errno.h>
+#include <linux/unistd.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/spinlock.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <asm/ocp.h>
+#include <linux/crc32.h>
+#include <linux/mii.h>
+#include <linux/phy.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/uaccess.h>
+
+#include "gianfar.h"
+#include "gianfar_mii.h"
+
+/* Write value to the PHY at mii_id at register regnum,
+ * on the bus, waiting until the write is done before returning.
+ * All PHY configuration is done through the TSEC1 MIIM regs */
+int gfar_mdio_write(struct mii_bus *bus, int mii_id, int regnum, u16 value)
+{
+ struct gfar_mii *regs = bus->priv;
+
+ /* Set the PHY address and the register address we want to write */
+ gfar_write(&regs->miimadd, (mii_id << 8) | regnum);
+
+ /* Write out the value we want */
+ gfar_write(&regs->miimcon, value);
+
+ /* Wait for the transaction to finish */
+ while (gfar_read(&regs->miimind) & MIIMIND_BUSY)
+ cpu_relax();
+
+ return 0;
+}
+
+/* Read the bus for PHY at addr mii_id, register regnum, and
+ * return the value. Clears miimcom first. All PHY
+ * configuration has to be done through the TSEC1 MIIM regs */
+int gfar_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
+{
+ struct gfar_mii *regs = bus->priv;
+ u16 value;
+
+ /* Set the PHY address and the register address we want to read */
+ gfar_write(&regs->miimadd, (mii_id << 8) | regnum);
+
+ /* Clear miimcom, and then initiate a read */
+ gfar_write(&regs->miimcom, 0);
+ gfar_write(&regs->miimcom, MII_READ_COMMAND);
+
+ /* Wait for the transaction to finish */
+ while (gfar_read(&regs->miimind) & (MIIMIND_NOTVALID | MIIMIND_BUSY))
+ cpu_relax();
+
+ /* Grab the value of the register from miimstat */
+ value = gfar_read(&regs->miimstat);
+
+ return value;
+}
+
+
+/* Reset the MIIM registers, and wait for the bus to free */
+int gfar_mdio_reset(struct mii_bus *bus)
+{
+ struct gfar_mii *regs = bus->priv;
+ unsigned int timeout = PHY_INIT_TIMEOUT;
+
+ spin_lock_bh(&bus->mdio_lock);
+
+ /* Reset the management interface */
+ gfar_write(&regs->miimcfg, MIIMCFG_RESET);
+
+ /* Setup the MII Mgmt clock speed */
+ gfar_write(&regs->miimcfg, MIIMCFG_INIT_VALUE);
+
+ /* Wait until the bus is free */
+ while ((gfar_read(&regs->miimind) & MIIMIND_BUSY) &&
+ timeout--)
+ cpu_relax();
+
+ spin_unlock_bh(&bus->mdio_lock);
+
+ if(timeout <= 0) {
+ printk(KERN_ERR "%s: The MII Bus is stuck!\n",
+ bus->name);
+ return -EBUSY;
+ }
+
+ return 0;
+}
+
+
+int gfar_mdio_probe(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct gianfar_mdio_data *pdata;
+ struct gfar_mii *regs;
+ struct mii_bus *new_bus;
+ int err = 0;
+
+ if (NULL == dev)
+ return -EINVAL;
+
+ new_bus = kmalloc(sizeof(struct mii_bus), GFP_KERNEL);
+
+ if (NULL == new_bus)
+ return -ENOMEM;
+
+ new_bus->name = "Gianfar MII Bus",
+ new_bus->read = &gfar_mdio_read,
+ new_bus->write = &gfar_mdio_write,
+ new_bus->reset = &gfar_mdio_reset,
+ new_bus->id = pdev->id;
+
+ pdata = (struct gianfar_mdio_data *)pdev->dev.platform_data;
+
+ if (NULL == pdata) {
+ printk(KERN_ERR "gfar mdio %d: Missing platform data!\n", pdev->id);
+ return -ENODEV;
+ }
+
+ /* Set the PHY base address */
+ regs = (struct gfar_mii *) ioremap(pdata->paddr,
+ sizeof (struct gfar_mii));
+
+ if (NULL == regs) {
+ err = -ENOMEM;
+ goto reg_map_fail;
+ }
+
+ new_bus->priv = regs;
+
+ new_bus->irq = pdata->irq;
+
+ new_bus->dev = dev;
+ dev_set_drvdata(dev, new_bus);
+
+ err = mdiobus_register(new_bus);
+
+ if (0 != err) {
+ printk (KERN_ERR "%s: Cannot register as MDIO bus\n",
+ new_bus->name);
+ goto bus_register_fail;
+ }
+
+ return 0;
+
+bus_register_fail:
+ iounmap((void *) regs);
+reg_map_fail:
+ kfree(new_bus);
+
+ return err;
+}
+
+
+int gfar_mdio_remove(struct device *dev)
+{
+ struct mii_bus *bus = dev_get_drvdata(dev);
+
+ mdiobus_unregister(bus);
+
+ dev_set_drvdata(dev, NULL);
+
+ iounmap((void *) (&bus->priv));
+ bus->priv = NULL;
+ kfree(bus);
+
+ return 0;
+}
+
+static struct device_driver gianfar_mdio_driver = {
+ .name = "fsl-gianfar_mdio",
+ .bus = &platform_bus_type,
+ .probe = gfar_mdio_probe,
+ .remove = gfar_mdio_remove,
+};
+
+int __init gfar_mdio_init(void)
+{
+ return driver_register(&gianfar_mdio_driver);
+}
+
+void __exit gfar_mdio_exit(void)
+{
+ driver_unregister(&gianfar_mdio_driver);
+}
diff --git a/drivers/net/gianfar_mii.h b/drivers/net/gianfar_mii.h
new file mode 100644
index 000000000000..56e5665d5c9b
--- /dev/null
+++ b/drivers/net/gianfar_mii.h
@@ -0,0 +1,45 @@
+/*
+ * drivers/net/gianfar_mii.h
+ *
+ * Gianfar Ethernet Driver -- MII Management Bus Implementation
+ * Driver for the MDIO bus controller in the Gianfar register space
+ *
+ * Author: Andy Fleming
+ * Maintainer: Kumar Gala (kumar.gala@freescale.com)
+ *
+ * Copyright (c) 2002-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.
+ *
+ */
+#ifndef __GIANFAR_MII_H
+#define __GIANFAR_MII_H
+
+#define MIIMIND_BUSY 0x00000001
+#define MIIMIND_NOTVALID 0x00000004
+
+#define MII_READ_COMMAND 0x00000001
+
+#define GFAR_SUPPORTED (SUPPORTED_10baseT_Half \
+ | SUPPORTED_100baseT_Half \
+ | SUPPORTED_100baseT_Full \
+ | SUPPORTED_Autoneg \
+ | SUPPORTED_MII)
+
+struct gfar_mii {
+ u32 miimcfg; /* 0x.520 - MII Management Config Register */
+ u32 miimcom; /* 0x.524 - MII Management Command Register */
+ u32 miimadd; /* 0x.528 - MII Management Address Register */
+ u32 miimcon; /* 0x.52c - MII Management Control Register */
+ u32 miimstat; /* 0x.530 - MII Management Status Register */
+ u32 miimind; /* 0x.534 - MII Management Indicator Register */
+};
+
+int gfar_mdio_read(struct mii_bus *bus, int mii_id, int regnum);
+int gfar_mdio_write(struct mii_bus *bus, int mii_id, int regnum, u16 value);
+int __init gfar_mdio_init(void);
+void __exit gfar_mdio_exit(void);
+#endif /* GIANFAR_PHY_H */
diff --git a/drivers/net/gianfar_phy.c b/drivers/net/gianfar_phy.c
deleted file mode 100644
index 7c965f268a82..000000000000
--- a/drivers/net/gianfar_phy.c
+++ /dev/null
@@ -1,661 +0,0 @@
-/*
- * drivers/net/gianfar_phy.c
- *
- * Gianfar Ethernet Driver -- PHY handling
- * Driver for FEC on MPC8540 and TSEC on MPC8540/MPC8560
- * Based on 8260_io/fcc_enet.c
- *
- * Author: Andy Fleming
- * Maintainer: Kumar Gala (kumar.gala@freescale.com)
- *
- * Copyright (c) 2002-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.
- *
- */
-
-#include <linux/config.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/string.h>
-#include <linux/errno.h>
-#include <linux/slab.h>
-#include <linux/interrupt.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-#include <linux/spinlock.h>
-#include <linux/mm.h>
-
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/uaccess.h>
-#include <linux/module.h>
-#include <linux/version.h>
-#include <linux/crc32.h>
-#include <linux/mii.h>
-
-#include "gianfar.h"
-#include "gianfar_phy.h"
-
-static void config_genmii_advert(struct gfar_mii_info *mii_info);
-static void genmii_setup_forced(struct gfar_mii_info *mii_info);
-static void genmii_restart_aneg(struct gfar_mii_info *mii_info);
-static int gbit_config_aneg(struct gfar_mii_info *mii_info);
-static int genmii_config_aneg(struct gfar_mii_info *mii_info);
-static int genmii_update_link(struct gfar_mii_info *mii_info);
-static int genmii_read_status(struct gfar_mii_info *mii_info);
-u16 phy_read(struct gfar_mii_info *mii_info, u16 regnum);
-void phy_write(struct gfar_mii_info *mii_info, u16 regnum, u16 val);
-
-/* Write value to the PHY for this device to the register at regnum, */
-/* waiting until the write is done before it returns. All PHY */
-/* configuration has to be done through the TSEC1 MIIM regs */
-void write_phy_reg(struct net_device *dev, int mii_id, int regnum, int value)
-{
- struct gfar_private *priv = netdev_priv(dev);
- struct gfar *regbase = priv->phyregs;
-
- /* Set the PHY address and the register address we want to write */
- gfar_write(&regbase->miimadd, (mii_id << 8) | regnum);
-
- /* Write out the value we want */
- gfar_write(&regbase->miimcon, value);
-
- /* Wait for the transaction to finish */
- while (gfar_read(&regbase->miimind) & MIIMIND_BUSY)
- cpu_relax();
-}
-
-/* Reads from register regnum in the PHY for device dev, */
-/* returning the value. Clears miimcom first. All PHY */
-/* configuration has to be done through the TSEC1 MIIM regs */
-int read_phy_reg(struct net_device *dev, int mii_id, int regnum)
-{
- struct gfar_private *priv = netdev_priv(dev);
- struct gfar *regbase = priv->phyregs;
- u16 value;
-
- /* Set the PHY address and the register address we want to read */
- gfar_write(&regbase->miimadd, (mii_id << 8) | regnum);
-
- /* Clear miimcom, and then initiate a read */
- gfar_write(&regbase->miimcom, 0);
- gfar_write(&regbase->miimcom, MII_READ_COMMAND);
-
- /* Wait for the transaction to finish */
- while (gfar_read(&regbase->miimind) & (MIIMIND_NOTVALID | MIIMIND_BUSY))
- cpu_relax();
-
- /* Grab the value of the register from miimstat */
- value = gfar_read(&regbase->miimstat);
-
- return value;
-}
-
-void mii_clear_phy_interrupt(struct gfar_mii_info *mii_info)
-{
- if(mii_info->phyinfo->ack_interrupt)
- mii_info->phyinfo->ack_interrupt(mii_info);
-}
-
-
-void mii_configure_phy_interrupt(struct gfar_mii_info *mii_info, u32 interrupts)
-{
- mii_info->interrupts = interrupts;
- if(mii_info->phyinfo->config_intr)
- mii_info->phyinfo->config_intr(mii_info);
-}
-
-
-/* Writes MII_ADVERTISE with the appropriate values, after
- * sanitizing advertise to make sure only supported features
- * are advertised
- */
-static void config_genmii_advert(struct gfar_mii_info *mii_info)
-{
- u32 advertise;
- u16 adv;
-
- /* Only allow advertising what this PHY supports */
- mii_info->advertising &= mii_info->phyinfo->features;
- advertise = mii_info->advertising;
-
- /* Setup standard advertisement */
- adv = phy_read(mii_info, MII_ADVERTISE);
- adv &= ~(ADVERTISE_ALL | ADVERTISE_100BASE4);
- if (advertise & ADVERTISED_10baseT_Half)
- adv |= ADVERTISE_10HALF;
- if (advertise & ADVERTISED_10baseT_Full)
- adv |= ADVERTISE_10FULL;
- if (advertise & ADVERTISED_100baseT_Half)
- adv |= ADVERTISE_100HALF;
- if (advertise & ADVERTISED_100baseT_Full)
- adv |= ADVERTISE_100FULL;
- phy_write(mii_info, MII_ADVERTISE, adv);
-}
-
-static void genmii_setup_forced(struct gfar_mii_info *mii_info)
-{
- u16 ctrl;
- u32 features = mii_info->phyinfo->features;
-
- ctrl = phy_read(mii_info, MII_BMCR);
-
- ctrl &= ~(BMCR_FULLDPLX|BMCR_SPEED100|BMCR_SPEED1000|BMCR_ANENABLE);
- ctrl |= BMCR_RESET;
-
- switch(mii_info->speed) {
- case SPEED_1000:
- if(features & (SUPPORTED_1000baseT_Half
- | SUPPORTED_1000baseT_Full)) {
- ctrl |= BMCR_SPEED1000;
- break;
- }
- mii_info->speed = SPEED_100;
- case SPEED_100:
- if (features & (SUPPORTED_100baseT_Half
- | SUPPORTED_100baseT_Full)) {
- ctrl |= BMCR_SPEED100;
- break;
- }
- mii_info->speed = SPEED_10;
- case SPEED_10:
- if (features & (SUPPORTED_10baseT_Half
- | SUPPORTED_10baseT_Full))
- break;
- default: /* Unsupported speed! */
- printk(KERN_ERR "%s: Bad speed!\n",
- mii_info->dev->name);
- break;
- }
-
- phy_write(mii_info, MII_BMCR, ctrl);
-}
-
-
-/* Enable and Restart Autonegotiation */
-static void genmii_restart_aneg(struct gfar_mii_info *mii_info)
-{
- u16 ctl;
-
- ctl = phy_read(mii_info, MII_BMCR);
- ctl |= (BMCR_ANENABLE | BMCR_ANRESTART);
- phy_write(mii_info, MII_BMCR, ctl);
-}
-
-
-static int gbit_config_aneg(struct gfar_mii_info *mii_info)
-{
- u16 adv;
- u32 advertise;
-
- if(mii_info->autoneg) {
- /* Configure the ADVERTISE register */
- config_genmii_advert(mii_info);
- advertise = mii_info->advertising;
-
- adv = phy_read(mii_info, MII_1000BASETCONTROL);
- adv &= ~(MII_1000BASETCONTROL_FULLDUPLEXCAP |
- MII_1000BASETCONTROL_HALFDUPLEXCAP);
- if (advertise & SUPPORTED_1000baseT_Half)
- adv |= MII_1000BASETCONTROL_HALFDUPLEXCAP;
- if (advertise & SUPPORTED_1000baseT_Full)
- adv |= MII_1000BASETCONTROL_FULLDUPLEXCAP;
- phy_write(mii_info, MII_1000BASETCONTROL, adv);
-
- /* Start/Restart aneg */
- genmii_restart_aneg(mii_info);
- } else
- genmii_setup_forced(mii_info);
-
- return 0;
-}
-
-static int marvell_config_aneg(struct gfar_mii_info *mii_info)
-{
- /* The Marvell PHY has an errata which requires
- * that certain registers get written in order
- * to restart autonegotiation */
- phy_write(mii_info, MII_BMCR, BMCR_RESET);
-
- phy_write(mii_info, 0x1d, 0x1f);
- phy_write(mii_info, 0x1e, 0x200c);
- phy_write(mii_info, 0x1d, 0x5);
- phy_write(mii_info, 0x1e, 0);
- phy_write(mii_info, 0x1e, 0x100);
-
- gbit_config_aneg(mii_info);
-
- return 0;
-}
-static int genmii_config_aneg(struct gfar_mii_info *mii_info)
-{
- if (mii_info->autoneg) {
- config_genmii_advert(mii_info);
- genmii_restart_aneg(mii_info);
- } else
- genmii_setup_forced(mii_info);
-
- return 0;
-}
-
-
-static int genmii_update_link(struct gfar_mii_info *mii_info)
-{
- u16 status;
-
- /* Do a fake read */
- phy_read(mii_info, MII_BMSR);
-
- /* Read link and autonegotiation status */
- status = phy_read(mii_info, MII_BMSR);
- if ((status & BMSR_LSTATUS) == 0)
- mii_info->link = 0;
- else
- mii_info->link = 1;
-
- /* If we are autonegotiating, and not done,
- * return an error */
- if (mii_info->autoneg && !(status & BMSR_ANEGCOMPLETE))
- return -EAGAIN;
-
- return 0;
-}
-
-static int genmii_read_status(struct gfar_mii_info *mii_info)
-{
- u16 status;
- int err;
-
- /* Update the link, but return if there
- * was an error */
- err = genmii_update_link(mii_info);
- if (err)
- return err;
-
- if (mii_info->autoneg) {
- status = phy_read(mii_info, MII_LPA);
-
- if (status & (LPA_10FULL | LPA_100FULL))
- mii_info->duplex = DUPLEX_FULL;
- else
- mii_info->duplex = DUPLEX_HALF;
- if (status & (LPA_100FULL | LPA_100HALF))
- mii_info->speed = SPEED_100;
- else
- mii_info->speed = SPEED_10;
- mii_info->pause = 0;
- }
- /* On non-aneg, we assume what we put in BMCR is the speed,
- * though magic-aneg shouldn't prevent this case from occurring
- */
-
- return 0;
-}
-static int marvell_read_status(struct gfar_mii_info *mii_info)
-{
- u16 status;
- int err;
-
- /* Update the link, but return if there
- * was an error */
- err = genmii_update_link(mii_info);
- if (err)
- return err;
-
- /* If the link is up, read the speed and duplex */
- /* If we aren't autonegotiating, assume speeds
- * are as set */
- if (mii_info->autoneg && mii_info->link) {
- int speed;
- status = phy_read(mii_info, MII_M1011_PHY_SPEC_STATUS);
-
-#if 0
- /* If speed and duplex aren't resolved,
- * return an error. Isn't this handled
- * by checking aneg?
- */
- if ((status & MII_M1011_PHY_SPEC_STATUS_RESOLVED) == 0)
- return -EAGAIN;
-#endif
-
- /* Get the duplexity */
- if (status & MII_M1011_PHY_SPEC_STATUS_FULLDUPLEX)
- mii_info->duplex = DUPLEX_FULL;
- else
- mii_info->duplex = DUPLEX_HALF;
-
- /* Get the speed */
- speed = status & MII_M1011_PHY_SPEC_STATUS_SPD_MASK;
- switch(speed) {
- case MII_M1011_PHY_SPEC_STATUS_1000:
- mii_info->speed = SPEED_1000;
- break;
- case MII_M1011_PHY_SPEC_STATUS_100:
- mii_info->speed = SPEED_100;
- break;
- default:
- mii_info->speed = SPEED_10;
- break;
- }
- mii_info->pause = 0;
- }
-
- return 0;
-}
-
-
-static int cis820x_read_status(struct gfar_mii_info *mii_info)
-{
- u16 status;
- int err;
-
- /* Update the link, but return if there
- * was an error */
- err = genmii_update_link(mii_info);
- if (err)
- return err;
-
- /* If the link is up, read the speed and duplex */
- /* If we aren't autonegotiating, assume speeds
- * are as set */
- if (mii_info->autoneg && mii_info->link) {
- int speed;
-
- status = phy_read(mii_info, MII_CIS8201_AUX_CONSTAT);
- if (status & MII_CIS8201_AUXCONSTAT_DUPLEX)
- mii_info->duplex = DUPLEX_FULL;
- else
- mii_info->duplex = DUPLEX_HALF;
-
- speed = status & MII_CIS8201_AUXCONSTAT_SPEED;
-
- switch (speed) {
- case MII_CIS8201_AUXCONSTAT_GBIT:
- mii_info->speed = SPEED_1000;
- break;
- case MII_CIS8201_AUXCONSTAT_100:
- mii_info->speed = SPEED_100;
- break;
- default:
- mii_info->speed = SPEED_10;
- break;
- }
- }
-
- return 0;
-}
-
-static int marvell_ack_interrupt(struct gfar_mii_info *mii_info)
-{
- /* Clear the interrupts by reading the reg */
- phy_read(mii_info, MII_M1011_IEVENT);
-
- return 0;
-}
-
-static int marvell_config_intr(struct gfar_mii_info *mii_info)
-{
- if(mii_info->interrupts == MII_INTERRUPT_ENABLED)
- phy_write(mii_info, MII_M1011_IMASK, MII_M1011_IMASK_INIT);
- else
- phy_write(mii_info, MII_M1011_IMASK, MII_M1011_IMASK_CLEAR);
-
- return 0;
-}
-
-static int cis820x_init(struct gfar_mii_info *mii_info)
-{
- phy_write(mii_info, MII_CIS8201_AUX_CONSTAT,
- MII_CIS8201_AUXCONSTAT_INIT);
- phy_write(mii_info, MII_CIS8201_EXT_CON1,
- MII_CIS8201_EXTCON1_INIT);
-
- return 0;
-}
-
-static int cis820x_ack_interrupt(struct gfar_mii_info *mii_info)
-{
- phy_read(mii_info, MII_CIS8201_ISTAT);
-
- return 0;
-}
-
-static int cis820x_config_intr(struct gfar_mii_info *mii_info)
-{
- if(mii_info->interrupts == MII_INTERRUPT_ENABLED)
- phy_write(mii_info, MII_CIS8201_IMASK, MII_CIS8201_IMASK_MASK);
- else
- phy_write(mii_info, MII_CIS8201_IMASK, 0);
-
- return 0;
-}
-
-#define DM9161_DELAY 10
-
-static int dm9161_read_status(struct gfar_mii_info *mii_info)
-{
- u16 status;
- int err;
-
- /* Update the link, but return if there
- * was an error */
- err = genmii_update_link(mii_info);
- if (err)
- return err;
-
- /* If the link is up, read the speed and duplex */
- /* If we aren't autonegotiating, assume speeds
- * are as set */
- if (mii_info->autoneg && mii_info->link) {
- status = phy_read(mii_info, MII_DM9161_SCSR);
- if (status & (MII_DM9161_SCSR_100F | MII_DM9161_SCSR_100H))
- mii_info->speed = SPEED_100;
- else
- mii_info->speed = SPEED_10;
-
- if (status & (MII_DM9161_SCSR_100F | MII_DM9161_SCSR_10F))
- mii_info->duplex = DUPLEX_FULL;
- else
- mii_info->duplex = DUPLEX_HALF;
- }
-
- return 0;
-}
-
-
-static int dm9161_config_aneg(struct gfar_mii_info *mii_info)
-{
- struct dm9161_private *priv = mii_info->priv;
-
- if(0 == priv->resetdone)
- return -EAGAIN;
-
- return 0;
-}
-
-static void dm9161_timer(unsigned long data)
-{
- struct gfar_mii_info *mii_info = (struct gfar_mii_info *)data;
- struct dm9161_private *priv = mii_info->priv;
- u16 status = phy_read(mii_info, MII_BMSR);
-
- if (status & BMSR_ANEGCOMPLETE) {
- priv->resetdone = 1;
- } else
- mod_timer(&priv->timer, jiffies + DM9161_DELAY * HZ);
-}
-
-static int dm9161_init(struct gfar_mii_info *mii_info)
-{
- struct dm9161_private *priv;
-
- /* Allocate the private data structure */
- priv = kmalloc(sizeof(struct dm9161_private), GFP_KERNEL);
-
- if (NULL == priv)
- return -ENOMEM;
-
- mii_info->priv = priv;
-
- /* Reset is not done yet */
- priv->resetdone = 0;
-
- /* Isolate the PHY */
- phy_write(mii_info, MII_BMCR, BMCR_ISOLATE);
-
- /* Do not bypass the scrambler/descrambler */
- phy_write(mii_info, MII_DM9161_SCR, MII_DM9161_SCR_INIT);
-
- /* Clear 10BTCSR to default */
- phy_write(mii_info, MII_DM9161_10BTCSR, MII_DM9161_10BTCSR_INIT);
-
- /* Reconnect the PHY, and enable Autonegotiation */
- phy_write(mii_info, MII_BMCR, BMCR_ANENABLE);
-
- /* Start a timer for DM9161_DELAY seconds to wait
- * for the PHY to be ready */
- init_timer(&priv->timer);
- priv->timer.function = &dm9161_timer;
- priv->timer.data = (unsigned long) mii_info;
- mod_timer(&priv->timer, jiffies + DM9161_DELAY * HZ);
-
- return 0;
-}
-
-static void dm9161_close(struct gfar_mii_info *mii_info)
-{
- struct dm9161_private *priv = mii_info->priv;
-
- del_timer_sync(&priv->timer);
- kfree(priv);
-}
-
-#if 0
-static int dm9161_ack_interrupt(struct gfar_mii_info *mii_info)
-{
- phy_read(mii_info, MII_DM9161_INTR);
-
- return 0;
-}
-#endif
-
-/* Cicada 820x */
-static struct phy_info phy_info_cis820x = {
- 0x000fc440,
- "Cicada Cis8204",
- 0x000fffc0,
- .features = MII_GBIT_FEATURES,
- .init = &cis820x_init,
- .config_aneg = &gbit_config_aneg,
- .read_status = &cis820x_read_status,
- .ack_interrupt = &cis820x_ack_interrupt,
- .config_intr = &cis820x_config_intr,
-};
-
-static struct phy_info phy_info_dm9161 = {
- .phy_id = 0x0181b880,
- .name = "Davicom DM9161E",
- .phy_id_mask = 0x0ffffff0,
- .init = dm9161_init,
- .config_aneg = dm9161_config_aneg,
- .read_status = dm9161_read_status,
- .close = dm9161_close,
-};
-
-static struct phy_info phy_info_marvell = {
- .phy_id = 0x01410c00,
- .phy_id_mask = 0xffffff00,
- .name = "Marvell 88E1101/88E1111",
- .features = MII_GBIT_FEATURES,
- .config_aneg = &marvell_config_aneg,
- .read_status = &marvell_read_status,
- .ack_interrupt = &marvell_ack_interrupt,
- .config_intr = &marvell_config_intr,
-};
-
-static struct phy_info phy_info_genmii= {
- .phy_id = 0x00000000,
- .phy_id_mask = 0x00000000,
- .name = "Generic MII",
- .features = MII_BASIC_FEATURES,
- .config_aneg = genmii_config_aneg,
- .read_status = genmii_read_status,
-};
-
-static struct phy_info *phy_info[] = {
- &phy_info_cis820x,
- &phy_info_marvell,
- &phy_info_dm9161,
- &phy_info_genmii,
- NULL
-};
-
-u16 phy_read(struct gfar_mii_info *mii_info, u16 regnum)
-{
- u16 retval;
- unsigned long flags;
-
- spin_lock_irqsave(&mii_info->mdio_lock, flags);
- retval = mii_info->mdio_read(mii_info->dev, mii_info->mii_id, regnum);
- spin_unlock_irqrestore(&mii_info->mdio_lock, flags);
-
- return retval;
-}
-
-void phy_write(struct gfar_mii_info *mii_info, u16 regnum, u16 val)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&mii_info->mdio_lock, flags);
- mii_info->mdio_write(mii_info->dev,
- mii_info->mii_id,
- regnum, val);
- spin_unlock_irqrestore(&mii_info->mdio_lock, flags);
-}
-
-/* Use the PHY ID registers to determine what type of PHY is attached
- * to device dev. return a struct phy_info structure describing that PHY
- */
-struct phy_info * get_phy_info(struct gfar_mii_info *mii_info)
-{
- u16 phy_reg;
- u32 phy_ID;
- int i;
- struct phy_info *theInfo = NULL;
- struct net_device *dev = mii_info->dev;
-
- /* Grab the bits from PHYIR1, and put them in the upper half */
- phy_reg = phy_read(mii_info, MII_PHYSID1);
- phy_ID = (phy_reg & 0xffff) << 16;
-
- /* Grab the bits from PHYIR2, and put them in the lower half */
- phy_reg = phy_read(mii_info, MII_PHYSID2);
- phy_ID |= (phy_reg & 0xffff);
-
- /* loop through all the known PHY types, and find one that */
- /* matches the ID we read from the PHY. */
- for (i = 0; phy_info[i]; i++)
- if (phy_info[i]->phy_id ==
- (phy_ID & phy_info[i]->phy_id_mask)) {
- theInfo = phy_info[i];
- break;
- }
-
- /* This shouldn't happen, as we have generic PHY support */
- if (theInfo == NULL) {
- printk("%s: PHY id %x is not supported!\n", dev->name, phy_ID);
- return NULL;
- } else {
- printk("%s: PHY is %s (%x)\n", dev->name, theInfo->name,
- phy_ID);
- }
-
- return theInfo;
-}
diff --git a/drivers/net/gianfar_phy.h b/drivers/net/gianfar_phy.h
deleted file mode 100644
index 1e9b3abf1e6d..000000000000
--- a/drivers/net/gianfar_phy.h
+++ /dev/null
@@ -1,213 +0,0 @@
-/*
- * drivers/net/gianfar_phy.h
- *
- * Gianfar Ethernet Driver -- PHY handling
- * Driver for FEC on MPC8540 and TSEC on MPC8540/MPC8560
- * Based on 8260_io/fcc_enet.c
- *
- * Author: Andy Fleming
- * Maintainer: Kumar Gala (kumar.gala@freescale.com)
- *
- * Copyright (c) 2002-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.
- *
- */
-#ifndef __GIANFAR_PHY_H
-#define __GIANFAR_PHY_H
-
-#define MII_end ((u32)-2)
-#define MII_read ((u32)-1)
-
-#define MIIMIND_BUSY 0x00000001
-#define MIIMIND_NOTVALID 0x00000004
-
-#define GFAR_AN_TIMEOUT 2000
-
-/* 1000BT control (Marvell & BCM54xx at least) */
-#define MII_1000BASETCONTROL 0x09
-#define MII_1000BASETCONTROL_FULLDUPLEXCAP 0x0200
-#define MII_1000BASETCONTROL_HALFDUPLEXCAP 0x0100
-
-/* Cicada Extended Control Register 1 */
-#define MII_CIS8201_EXT_CON1 0x17
-#define MII_CIS8201_EXTCON1_INIT 0x0000
-
-/* Cicada Interrupt Mask Register */
-#define MII_CIS8201_IMASK 0x19
-#define MII_CIS8201_IMASK_IEN 0x8000
-#define MII_CIS8201_IMASK_SPEED 0x4000
-#define MII_CIS8201_IMASK_LINK 0x2000
-#define MII_CIS8201_IMASK_DUPLEX 0x1000
-#define MII_CIS8201_IMASK_MASK 0xf000
-
-/* Cicada Interrupt Status Register */
-#define MII_CIS8201_ISTAT 0x1a
-#define MII_CIS8201_ISTAT_STATUS 0x8000
-#define MII_CIS8201_ISTAT_SPEED 0x4000
-#define MII_CIS8201_ISTAT_LINK 0x2000
-#define MII_CIS8201_ISTAT_DUPLEX 0x1000
-
-/* Cicada Auxiliary Control/Status Register */
-#define MII_CIS8201_AUX_CONSTAT 0x1c
-#define MII_CIS8201_AUXCONSTAT_INIT 0x0004
-#define MII_CIS8201_AUXCONSTAT_DUPLEX 0x0020
-#define MII_CIS8201_AUXCONSTAT_SPEED 0x0018
-#define MII_CIS8201_AUXCONSTAT_GBIT 0x0010
-#define MII_CIS8201_AUXCONSTAT_100 0x0008
-
-/* 88E1011 PHY Status Register */
-#define MII_M1011_PHY_SPEC_STATUS 0x11
-#define MII_M1011_PHY_SPEC_STATUS_1000 0x8000
-#define MII_M1011_PHY_SPEC_STATUS_100 0x4000
-#define MII_M1011_PHY_SPEC_STATUS_SPD_MASK 0xc000
-#define MII_M1011_PHY_SPEC_STATUS_FULLDUPLEX 0x2000
-#define MII_M1011_PHY_SPEC_STATUS_RESOLVED 0x0800
-#define MII_M1011_PHY_SPEC_STATUS_LINK 0x0400
-
-#define MII_M1011_IEVENT 0x13
-#define MII_M1011_IEVENT_CLEAR 0x0000
-
-#define MII_M1011_IMASK 0x12
-#define MII_M1011_IMASK_INIT 0x6400
-#define MII_M1011_IMASK_CLEAR 0x0000
-
-#define MII_DM9161_SCR 0x10
-#define MII_DM9161_SCR_INIT 0x0610
-
-/* DM9161 Specified Configuration and Status Register */
-#define MII_DM9161_SCSR 0x11
-#define MII_DM9161_SCSR_100F 0x8000
-#define MII_DM9161_SCSR_100H 0x4000
-#define MII_DM9161_SCSR_10F 0x2000
-#define MII_DM9161_SCSR_10H 0x1000
-
-/* DM9161 Interrupt Register */
-#define MII_DM9161_INTR 0x15
-#define MII_DM9161_INTR_PEND 0x8000
-#define MII_DM9161_INTR_DPLX_MASK 0x0800
-#define MII_DM9161_INTR_SPD_MASK 0x0400
-#define MII_DM9161_INTR_LINK_MASK 0x0200
-#define MII_DM9161_INTR_MASK 0x0100
-#define MII_DM9161_INTR_DPLX_CHANGE 0x0010
-#define MII_DM9161_INTR_SPD_CHANGE 0x0008
-#define MII_DM9161_INTR_LINK_CHANGE 0x0004
-#define MII_DM9161_INTR_INIT 0x0000
-#define MII_DM9161_INTR_STOP \
-(MII_DM9161_INTR_DPLX_MASK | MII_DM9161_INTR_SPD_MASK \
- | MII_DM9161_INTR_LINK_MASK | MII_DM9161_INTR_MASK)
-
-/* DM9161 10BT Configuration/Status */
-#define MII_DM9161_10BTCSR 0x12
-#define MII_DM9161_10BTCSR_INIT 0x7800
-
-#define MII_BASIC_FEATURES (SUPPORTED_10baseT_Half | \
- SUPPORTED_10baseT_Full | \
- SUPPORTED_100baseT_Half | \
- SUPPORTED_100baseT_Full | \
- SUPPORTED_Autoneg | \
- SUPPORTED_TP | \
- SUPPORTED_MII)
-
-#define MII_GBIT_FEATURES (MII_BASIC_FEATURES | \
- SUPPORTED_1000baseT_Half | \
- SUPPORTED_1000baseT_Full)
-
-#define MII_READ_COMMAND 0x00000001
-
-#define MII_INTERRUPT_DISABLED 0x0
-#define MII_INTERRUPT_ENABLED 0x1
-/* Taken from mii_if_info and sungem_phy.h */
-struct gfar_mii_info {
- /* Information about the PHY type */
- /* And management functions */
- struct phy_info *phyinfo;
-
- /* forced speed & duplex (no autoneg)
- * partner speed & duplex & pause (autoneg)
- */
- int speed;
- int duplex;
- int pause;
-
- /* The most recently read link state */
- int link;
-
- /* Enabled Interrupts */
- u32 interrupts;
-
- u32 advertising;
- int autoneg;
- int mii_id;
-
- /* private data pointer */
- /* For use by PHYs to maintain extra state */
- void *priv;
-
- /* Provided by host chip */
- struct net_device *dev;
-
- /* A lock to ensure that only one thing can read/write
- * the MDIO bus at a time */
- spinlock_t mdio_lock;
-
- /* Provided by ethernet driver */
- int (*mdio_read) (struct net_device *dev, int mii_id, int reg);
- void (*mdio_write) (struct net_device *dev, int mii_id, int reg, int val);
-};
-
-/* struct phy_info: a structure which defines attributes for a PHY
- *
- * id will contain a number which represents the PHY. During
- * startup, the driver will poll the PHY to find out what its
- * UID--as defined by registers 2 and 3--is. The 32-bit result
- * gotten from the PHY will be ANDed with phy_id_mask to
- * discard any bits which may change based on revision numbers
- * unimportant to functionality
- *
- * There are 6 commands which take a gfar_mii_info structure.
- * Each PHY must declare config_aneg, and read_status.
- */
-struct phy_info {
- u32 phy_id;
- char *name;
- unsigned int phy_id_mask;
- u32 features;
-
- /* Called to initialize the PHY */
- int (*init)(struct gfar_mii_info *mii_info);
-
- /* Called to suspend the PHY for power */
- int (*suspend)(struct gfar_mii_info *mii_info);
-
- /* Reconfigures autonegotiation (or disables it) */
- int (*config_aneg)(struct gfar_mii_info *mii_info);
-
- /* Determines the negotiated speed and duplex */
- int (*read_status)(struct gfar_mii_info *mii_info);
-
- /* Clears any pending interrupts */
- int (*ack_interrupt)(struct gfar_mii_info *mii_info);
-
- /* Enables or disables interrupts */
- int (*config_intr)(struct gfar_mii_info *mii_info);
-
- /* Clears up any memory if needed */
- void (*close)(struct gfar_mii_info *mii_info);
-};
-
-struct phy_info *get_phy_info(struct gfar_mii_info *mii_info);
-int read_phy_reg(struct net_device *dev, int mii_id, int regnum);
-void write_phy_reg(struct net_device *dev, int mii_id, int regnum, int value);
-void mii_clear_phy_interrupt(struct gfar_mii_info *mii_info);
-void mii_configure_phy_interrupt(struct gfar_mii_info *mii_info, u32 interrupts);
-
-struct dm9161_private {
- struct timer_list timer;
- int resetdone;
-};
-
-#endif /* GIANFAR_PHY_H */
diff --git a/drivers/net/hamradio/Kconfig b/drivers/net/hamradio/Kconfig
index de087cd609d9..896aa02000d7 100644
--- a/drivers/net/hamradio/Kconfig
+++ b/drivers/net/hamradio/Kconfig
@@ -1,6 +1,7 @@
config MKISS
tristate "Serial port KISS driver"
depends on AX25
+ select CRC16
---help---
KISS is a protocol used for the exchange of data between a computer
and a Terminal Node Controller (a small embedded system commonly
diff --git a/drivers/net/hamradio/bpqether.c b/drivers/net/hamradio/bpqether.c
index 1756f0ed54cc..cb43a9d28774 100644
--- a/drivers/net/hamradio/bpqether.c
+++ b/drivers/net/hamradio/bpqether.c
@@ -144,7 +144,7 @@ static inline struct net_device *bpq_get_ax25_dev(struct net_device *dev)
{
struct bpqdev *bpq;
- list_for_each_entry(bpq, &bpq_devices, bpq_list) {
+ list_for_each_entry_rcu(bpq, &bpq_devices, bpq_list) {
if (bpq->ethdev == dev)
return bpq->axdev;
}
@@ -399,7 +399,7 @@ static void *bpq_seq_start(struct seq_file *seq, loff_t *pos)
if (*pos == 0)
return SEQ_START_TOKEN;
- list_for_each_entry(bpqdev, &bpq_devices, bpq_list) {
+ list_for_each_entry_rcu(bpqdev, &bpq_devices, bpq_list) {
if (i == *pos)
return bpqdev;
}
@@ -418,7 +418,7 @@ static void *bpq_seq_next(struct seq_file *seq, void *v, loff_t *pos)
p = ((struct bpqdev *)v)->bpq_list.next;
return (p == &bpq_devices) ? NULL
- : list_entry(p, struct bpqdev, bpq_list);
+ : rcu_dereference(list_entry(p, struct bpqdev, bpq_list));
}
static void bpq_seq_stop(struct seq_file *seq, void *v)
@@ -561,8 +561,6 @@ static int bpq_device_event(struct notifier_block *this,unsigned long event, voi
if (!dev_is_ethdev(dev))
return NOTIFY_DONE;
- rcu_read_lock();
-
switch (event) {
case NETDEV_UP: /* new ethernet device -> new BPQ interface */
if (bpq_get_ax25_dev(dev) == NULL)
@@ -581,7 +579,6 @@ static int bpq_device_event(struct notifier_block *this,unsigned long event, voi
default:
break;
}
- rcu_read_unlock();
return NOTIFY_DONE;
}
diff --git a/drivers/net/hamradio/dmascc.c b/drivers/net/hamradio/dmascc.c
index 3be3f916643a..c8dc40214a08 100644
--- a/drivers/net/hamradio/dmascc.c
+++ b/drivers/net/hamradio/dmascc.c
@@ -311,16 +311,6 @@ static void __exit dmascc_exit(void)
}
}
-#ifndef MODULE
-void __init dmascc_setup(char *str, int *ints)
-{
- int i;
-
- for (i = 0; i < MAX_NUM_DEVS && i < ints[0]; i++)
- io[i] = ints[i + 1];
-}
-#endif
-
static int __init dmascc_init(void)
{
int h, i, j, n;
diff --git a/drivers/net/hamradio/mkiss.c b/drivers/net/hamradio/mkiss.c
index d9fe64b46f4b..3e9accf137e7 100644
--- a/drivers/net/hamradio/mkiss.c
+++ b/drivers/net/hamradio/mkiss.c
@@ -14,13 +14,14 @@
*
* Copyright (C) Hans Alblas PE1AYX <hans@esrac.ele.tue.nl>
* Copyright (C) 2004, 05 Ralf Baechle DL5RB <ralf@linux-mips.org>
+ * Copyright (C) 2004, 05 Thomas Osterried DL9SAU <thomas@x-berg.in-berlin.de>
*/
-
#include <linux/config.h>
#include <linux/module.h>
#include <asm/system.h>
#include <linux/bitops.h>
#include <asm/uaccess.h>
+#include <linux/crc16.h>
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/interrupt.h>
@@ -39,11 +40,6 @@
#include <net/ax25.h>
-#ifdef CONFIG_INET
-#include <linux/ip.h>
-#include <linux/tcp.h>
-#endif
-
#define AX_MTU 236
/* SLIP/KISS protocol characters. */
@@ -80,9 +76,13 @@ struct mkiss {
int mode;
int crcmode; /* MW: for FlexNet, SMACK etc. */
-#define CRC_MODE_NONE 0
-#define CRC_MODE_FLEX 1
-#define CRC_MODE_SMACK 2
+ int crcauto; /* CRC auto mode */
+
+#define CRC_MODE_NONE 0
+#define CRC_MODE_FLEX 1
+#define CRC_MODE_SMACK 2
+#define CRC_MODE_FLEX_TEST 3
+#define CRC_MODE_SMACK_TEST 4
atomic_t refcnt;
struct semaphore dead_sem;
@@ -151,6 +151,21 @@ static int check_crc_flex(unsigned char *cp, int size)
return 0;
}
+static int check_crc_16(unsigned char *cp, int size)
+{
+ unsigned short crc = 0x0000;
+
+ if (size < 3)
+ return -1;
+
+ crc = crc16(0, cp, size);
+
+ if (crc != 0x0000)
+ return -1;
+
+ return 0;
+}
+
/*
* Standard encapsulation
*/
@@ -237,19 +252,42 @@ static void ax_bump(struct mkiss *ax)
spin_lock_bh(&ax->buflock);
if (ax->rbuff[0] > 0x0f) {
- if (ax->rbuff[0] & 0x20) {
- ax->crcmode = CRC_MODE_FLEX;
+ if (ax->rbuff[0] & 0x80) {
+ if (check_crc_16(ax->rbuff, ax->rcount) < 0) {
+ ax->stats.rx_errors++;
+ spin_unlock_bh(&ax->buflock);
+
+ return;
+ }
+ if (ax->crcmode != CRC_MODE_SMACK && ax->crcauto) {
+ printk(KERN_INFO
+ "mkiss: %s: Switchting to crc-smack\n",
+ ax->dev->name);
+ ax->crcmode = CRC_MODE_SMACK;
+ }
+ ax->rcount -= 2;
+ *ax->rbuff &= ~0x80;
+ } else if (ax->rbuff[0] & 0x20) {
if (check_crc_flex(ax->rbuff, ax->rcount) < 0) {
- ax->stats.rx_errors++;
+ ax->stats.rx_errors++;
+ spin_unlock_bh(&ax->buflock);
return;
}
+ if (ax->crcmode != CRC_MODE_FLEX && ax->crcauto) {
+ printk(KERN_INFO
+ "mkiss: %s: Switchting to crc-flexnet\n",
+ ax->dev->name);
+ ax->crcmode = CRC_MODE_FLEX;
+ }
ax->rcount -= 2;
- /* dl9sau bugfix: the trailling two bytes flexnet crc
- * will not be passed to the kernel. thus we have
- * to correct the kissparm signature, because it
- * indicates a crc but there's none
+
+ /*
+ * dl9sau bugfix: the trailling two bytes flexnet crc
+ * will not be passed to the kernel. thus we have to
+ * correct the kissparm signature, because it indicates
+ * a crc but there's none
*/
- *ax->rbuff &= ~0x20;
+ *ax->rbuff &= ~0x20;
}
}
spin_unlock_bh(&ax->buflock);
@@ -352,10 +390,8 @@ static void ax_changedmtu(struct mkiss *ax)
"MTU change cancelled.\n",
ax->dev->name);
dev->mtu = ax->mtu;
- if (xbuff != NULL)
- kfree(xbuff);
- if (rbuff != NULL)
- kfree(rbuff);
+ kfree(xbuff);
+ kfree(rbuff);
return;
}
@@ -417,20 +453,69 @@ static void ax_encaps(struct net_device *dev, unsigned char *icp, int len)
p = icp;
spin_lock_bh(&ax->buflock);
- switch (ax->crcmode) {
- unsigned short crc;
+ if ((*p & 0x0f) != 0) {
+ /* Configuration Command (kissparms(1).
+ * Protocol spec says: never append CRC.
+ * This fixes a very old bug in the linux
+ * kiss driver. -- dl9sau */
+ switch (*p & 0xff) {
+ case 0x85:
+ /* command from userspace especially for us,
+ * not for delivery to the tnc */
+ if (len > 1) {
+ int cmd = (p[1] & 0xff);
+ switch(cmd) {
+ case 3:
+ ax->crcmode = CRC_MODE_SMACK;
+ break;
+ case 2:
+ ax->crcmode = CRC_MODE_FLEX;
+ break;
+ case 1:
+ ax->crcmode = CRC_MODE_NONE;
+ break;
+ case 0:
+ default:
+ ax->crcmode = CRC_MODE_SMACK_TEST;
+ cmd = 0;
+ }
+ ax->crcauto = (cmd ? 0 : 1);
+ printk(KERN_INFO "mkiss: %s: crc mode %s %d\n", ax->dev->name, (len) ? "set to" : "is", cmd);
+ }
+ spin_unlock_bh(&ax->buflock);
+ netif_start_queue(dev);
- case CRC_MODE_FLEX:
- *p |= 0x20;
- crc = calc_crc_flex(p, len);
- count = kiss_esc_crc(p, (unsigned char *)ax->xbuff, crc, len+2);
- break;
+ return;
+ default:
+ count = kiss_esc(p, (unsigned char *)ax->xbuff, len);
+ }
+ } else {
+ unsigned short crc;
+ switch (ax->crcmode) {
+ case CRC_MODE_SMACK_TEST:
+ ax->crcmode = CRC_MODE_FLEX_TEST;
+ printk(KERN_INFO "mkiss: %s: Trying crc-smack\n", ax->dev->name);
+ // fall through
+ case CRC_MODE_SMACK:
+ *p |= 0x80;
+ crc = swab16(crc16(0, p, len));
+ count = kiss_esc_crc(p, (unsigned char *)ax->xbuff, crc, len+2);
+ break;
+ case CRC_MODE_FLEX_TEST:
+ ax->crcmode = CRC_MODE_NONE;
+ printk(KERN_INFO "mkiss: %s: Trying crc-flexnet\n", ax->dev->name);
+ // fall through
+ case CRC_MODE_FLEX:
+ *p |= 0x20;
+ crc = calc_crc_flex(p, len);
+ count = kiss_esc_crc(p, (unsigned char *)ax->xbuff, crc, len+2);
+ break;
+
+ default:
+ count = kiss_esc(p, (unsigned char *)ax->xbuff, len);
+ }
+ }
- default:
- count = kiss_esc(p, (unsigned char *)ax->xbuff, len);
- break;
- }
-
set_bit(TTY_DO_WRITE_WAKEUP, &ax->tty->flags);
actual = ax->tty->driver->write(ax->tty, ax->xbuff, count);
ax->stats.tx_packets++;
@@ -439,8 +524,6 @@ static void ax_encaps(struct net_device *dev, unsigned char *icp, int len)
ax->dev->trans_start = jiffies;
ax->xleft = count - actual;
ax->xhead = ax->xbuff + actual;
-
- spin_unlock_bh(&ax->buflock);
}
/* Encapsulate an AX.25 packet and kick it into a TTY queue. */
@@ -622,7 +705,7 @@ static void ax_setup(struct net_device *dev)
* best way to fix this is to use a rwlock in the tty struct, but for now we
* use a single global rwlock for all ttys in ppp line discipline.
*/
-static rwlock_t disc_data_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(disc_data_lock);
static struct mkiss *mkiss_get(struct tty_struct *tty)
{
@@ -643,6 +726,8 @@ static void mkiss_put(struct mkiss *ax)
up(&ax->dead_sem);
}
+static int crc_force = 0; /* Can be overridden with insmod */
+
static int mkiss_open(struct tty_struct *tty)
{
struct net_device *dev;
@@ -682,6 +767,33 @@ static int mkiss_open(struct tty_struct *tty)
if (register_netdev(dev))
goto out_free_buffers;
+ /* after register_netdev() - because else printk smashes the kernel */
+ switch (crc_force) {
+ case 3:
+ ax->crcmode = CRC_MODE_SMACK;
+ printk(KERN_INFO "mkiss: %s: crc mode smack forced.\n",
+ ax->dev->name);
+ break;
+ case 2:
+ ax->crcmode = CRC_MODE_FLEX;
+ printk(KERN_INFO "mkiss: %s: crc mode flexnet forced.\n",
+ ax->dev->name);
+ break;
+ case 1:
+ ax->crcmode = CRC_MODE_NONE;
+ printk(KERN_INFO "mkiss: %s: crc mode disabled.\n",
+ ax->dev->name);
+ break;
+ case 0:
+ /* fall through */
+ default:
+ crc_force = 0;
+ printk(KERN_INFO "mkiss: %s: crc mode is auto.\n",
+ ax->dev->name);
+ ax->crcmode = CRC_MODE_SMACK_TEST;
+ }
+ ax->crcauto = (crc_force ? 0 : 1);
+
netif_start_queue(dev);
/* Done. We have linked the TTY line to a channel. */
@@ -765,7 +877,6 @@ static int mkiss_ioctl(struct tty_struct *tty, struct file *file,
case SIOCSIFHWADDR: {
char addr[AX25_ADDR_LEN];
-printk(KERN_INFO "In SIOCSIFHWADDR");
if (copy_from_user(&addr,
(void __user *) arg, AX25_ADDR_LEN)) {
@@ -864,6 +975,7 @@ out:
}
static struct tty_ldisc ax_ldisc = {
+ .owner = THIS_MODULE,
.magic = TTY_LDISC_MAGIC,
.name = "mkiss",
.open = mkiss_open,
@@ -904,6 +1016,8 @@ static void __exit mkiss_exit_driver(void)
MODULE_AUTHOR("Ralf Baechle DL5RB <ralf@linux-mips.org>");
MODULE_DESCRIPTION("KISS driver for AX.25 over TTYs");
+MODULE_PARM(crc_force, "i");
+MODULE_PARM_DESC(crc_force, "crc [0 = auto | 1 = none | 2 = flexnet | 3 = smack]");
MODULE_LICENSE("GPL");
MODULE_ALIAS_LDISC(N_AX25);
diff --git a/drivers/net/hamradio/mkiss.h b/drivers/net/hamradio/mkiss.h
deleted file mode 100644
index 4ab700478598..000000000000
--- a/drivers/net/hamradio/mkiss.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/****************************************************************************
- * Defines for the Multi-KISS driver.
- ****************************************************************************/
-
-#define AX25_MAXDEV 16 /* MAX number of AX25 channels;
- This can be overridden with
- insmod -oax25_maxdev=nnn */
-#define AX_MTU 236
-
-/* SLIP/KISS protocol characters. */
-#define END 0300 /* indicates end of frame */
-#define ESC 0333 /* indicates byte stuffing */
-#define ESC_END 0334 /* ESC ESC_END means END 'data' */
-#define ESC_ESC 0335 /* ESC ESC_ESC means ESC 'data' */
-
-struct ax_disp {
- int magic;
-
- /* Various fields. */
- struct tty_struct *tty; /* ptr to TTY structure */
- struct net_device *dev; /* easy for intr handling */
-
- /* These are pointers to the malloc()ed frame buffers. */
- unsigned char *rbuff; /* receiver buffer */
- int rcount; /* received chars counter */
- unsigned char *xbuff; /* transmitter buffer */
- unsigned char *xhead; /* pointer to next byte to XMIT */
- int xleft; /* bytes left in XMIT queue */
-
- /* SLIP interface statistics. */
- unsigned long rx_packets; /* inbound frames counter */
- unsigned long tx_packets; /* outbound frames counter */
- unsigned long rx_bytes; /* inbound bytes counter */
- unsigned long tx_bytes; /* outbound bytes counter */
- unsigned long rx_errors; /* Parity, etc. errors */
- unsigned long tx_errors; /* Planned stuff */
- unsigned long rx_dropped; /* No memory for skb */
- unsigned long tx_dropped; /* When MTU change */
- unsigned long rx_over_errors; /* Frame bigger then SLIP buf. */
-
- /* Detailed SLIP statistics. */
- int mtu; /* Our mtu (to spot changes!) */
- int buffsize; /* Max buffers sizes */
-
-
- unsigned long flags; /* Flag values/ mode etc */
- /* long req'd: used by set_bit --RR */
-#define AXF_INUSE 0 /* Channel in use */
-#define AXF_ESCAPE 1 /* ESC received */
-#define AXF_ERROR 2 /* Parity, etc. error */
-#define AXF_KEEPTEST 3 /* Keepalive test flag */
-#define AXF_OUTWAIT 4 /* is outpacket was flag */
-
- int mode;
- int crcmode; /* MW: for FlexNet, SMACK etc. */
-#define CRC_MODE_NONE 0
-#define CRC_MODE_FLEX 1
-#define CRC_MODE_SMACK 2
- spinlock_t buflock; /* lock for rbuf and xbuf */
-};
-
-#define AX25_MAGIC 0x5316
diff --git a/drivers/net/hp100.c b/drivers/net/hp100.c
index cf0ac6fda1a1..e92c17f6931c 100644
--- a/drivers/net/hp100.c
+++ b/drivers/net/hp100.c
@@ -96,7 +96,6 @@
#undef HP100_MULTICAST_FILTER /* Need to be debugged... */
-#include <linux/version.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/string.h>
@@ -2517,10 +2516,8 @@ static int hp100_down_vg_link(struct net_device *dev)
do {
if (hp100_inb(VG_LAN_CFG_1) & HP100_LINK_CABLE_ST)
break;
- if (!in_interrupt()) {
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(1);
- }
+ if (!in_interrupt())
+ schedule_timeout_interruptible(1);
} while (time_after(time, jiffies));
if (time_after_eq(jiffies, time)) /* no signal->no logout */
@@ -2536,10 +2533,8 @@ static int hp100_down_vg_link(struct net_device *dev)
do {
if (!(hp100_inb(VG_LAN_CFG_1) & HP100_LINK_UP_ST))
break;
- if (!in_interrupt()) {
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(1);
- }
+ if (!in_interrupt())
+ schedule_timeout_interruptible(1);
} while (time_after(time, jiffies));
#ifdef HP100_DEBUG
@@ -2577,10 +2572,8 @@ static int hp100_down_vg_link(struct net_device *dev)
do {
if (!(hp100_inb(MAC_CFG_4) & HP100_MAC_SEL_ST))
break;
- if (!in_interrupt()) {
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(1);
- }
+ if (!in_interrupt())
+ schedule_timeout_interruptible(1);
} while (time_after(time, jiffies));
hp100_orb(HP100_AUTO_MODE, MAC_CFG_3); /* Autosel back on */
@@ -2591,10 +2584,8 @@ static int hp100_down_vg_link(struct net_device *dev)
do {
if ((hp100_inb(VG_LAN_CFG_1) & HP100_LINK_CABLE_ST) == 0)
break;
- if (!in_interrupt()) {
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(1);
- }
+ if (!in_interrupt())
+ schedule_timeout_interruptible(1);
} while (time_after(time, jiffies));
if (time_before_eq(time, jiffies)) {
@@ -2606,10 +2597,8 @@ static int hp100_down_vg_link(struct net_device *dev)
time = jiffies + (2 * HZ); /* This seems to take a while.... */
do {
- if (!in_interrupt()) {
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(1);
- }
+ if (!in_interrupt())
+ schedule_timeout_interruptible(1);
} while (time_after(time, jiffies));
return 0;
@@ -2659,10 +2648,8 @@ static int hp100_login_to_vg_hub(struct net_device *dev, u_short force_relogin)
do {
if (~(hp100_inb(VG_LAN_CFG_1) & HP100_LINK_UP_ST))
break;
- if (!in_interrupt()) {
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(1);
- }
+ if (!in_interrupt())
+ schedule_timeout_interruptible(1);
} while (time_after(time, jiffies));
/* Start an addressed training and optionally request promiscuous port */
@@ -2697,10 +2684,8 @@ static int hp100_login_to_vg_hub(struct net_device *dev, u_short force_relogin)
do {
if (hp100_inb(VG_LAN_CFG_1) & HP100_LINK_CABLE_ST)
break;
- if (!in_interrupt()) {
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(1);
- }
+ if (!in_interrupt())
+ schedule_timeout_interruptible(1);
} while (time_before(jiffies, time));
if (time_after_eq(jiffies, time)) {
@@ -2723,10 +2708,8 @@ static int hp100_login_to_vg_hub(struct net_device *dev, u_short force_relogin)
#endif
break;
}
- if (!in_interrupt()) {
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(1);
- }
+ if (!in_interrupt())
+ schedule_timeout_interruptible(1);
} while (time_after(time, jiffies));
}
diff --git a/drivers/net/ibm_emac/Makefile b/drivers/net/ibm_emac/Makefile
index 7f583a333c24..f98ddf0e807a 100644
--- a/drivers/net/ibm_emac/Makefile
+++ b/drivers/net/ibm_emac/Makefile
@@ -1,12 +1,11 @@
#
-# Makefile for the IBM PPC4xx EMAC controllers
+# Makefile for the PowerPC 4xx on-chip ethernet driver
#
obj-$(CONFIG_IBM_EMAC) += ibm_emac.o
-ibm_emac-objs := ibm_emac_mal.o ibm_emac_core.o ibm_emac_phy.o
-
-# Only need this if you want to see additional debug messages
-ifeq ($(CONFIG_IBM_EMAC_ERRMSG), y)
-ibm_emac-objs += ibm_emac_debug.o
-endif
+ibm_emac-objs := ibm_emac_mal.o ibm_emac_core.o ibm_emac_phy.o
+ibm_emac-$(CONFIG_IBM_EMAC_ZMII) += ibm_emac_zmii.o
+ibm_emac-$(CONFIG_IBM_EMAC_RGMII) += ibm_emac_rgmii.o
+ibm_emac-$(CONFIG_IBM_EMAC_TAH) += ibm_emac_tah.o
+ibm_emac-$(CONFIG_IBM_EMAC_DEBUG) += ibm_emac_debug.o
diff --git a/drivers/net/ibm_emac/ibm_emac.h b/drivers/net/ibm_emac/ibm_emac.h
index 15d5a0e82862..644edbff4f94 100644
--- a/drivers/net/ibm_emac/ibm_emac.h
+++ b/drivers/net/ibm_emac/ibm_emac.h
@@ -1,110 +1,143 @@
/*
- * ibm_emac.h
+ * drivers/net/ibm_emac/ibm_emac.h
*
+ * Register definitions for PowerPC 4xx on-chip ethernet contoller
*
- * Armin Kuster akuster@mvista.com
- * June, 2002
+ * Copyright (c) 2004, 2005 Zultys Technologies.
+ * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
*
- * Copyright 2002 MontaVista Softare Inc.
+ * Based on original work by
+ * Matt Porter <mporter@kernel.crashing.org>
+ * Armin Kuster <akuster@mvista.com>
+ * Copyright 2002-2004 MontaVista Software 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.
+ *
*/
+#ifndef __IBM_EMAC_H_
+#define __IBM_EMAC_H_
+
+#include <linux/config.h>
+#include <linux/types.h>
+
+/* This is a simple check to prevent use of this driver on non-tested SoCs */
+#if !defined(CONFIG_405GP) && !defined(CONFIG_405GPR) && !defined(CONFIG_405EP) && \
+ !defined(CONFIG_440GP) && !defined(CONFIG_440GX) && !defined(CONFIG_440SP) && \
+ !defined(CONFIG_440EP) && !defined(CONFIG_NP405H) && !defined(CONFIG_440SPE) && \
+ !defined(CONFIG_440GR)
+#error "Unknown SoC. Please, check chip user manual and make sure EMAC defines are OK"
+#endif
-#ifndef _IBM_EMAC_H_
-#define _IBM_EMAC_H_
-/* General defines needed for the driver */
+/* EMAC registers Write Access rules */
+struct emac_regs {
+ u32 mr0; /* special */
+ u32 mr1; /* Reset */
+ u32 tmr0; /* special */
+ u32 tmr1; /* special */
+ u32 rmr; /* Reset */
+ u32 isr; /* Always */
+ u32 iser; /* Reset */
+ u32 iahr; /* Reset, R, T */
+ u32 ialr; /* Reset, R, T */
+ u32 vtpid; /* Reset, R, T */
+ u32 vtci; /* Reset, R, T */
+ u32 ptr; /* Reset, T */
+ u32 iaht1; /* Reset, R */
+ u32 iaht2; /* Reset, R */
+ u32 iaht3; /* Reset, R */
+ u32 iaht4; /* Reset, R */
+ u32 gaht1; /* Reset, R */
+ u32 gaht2; /* Reset, R */
+ u32 gaht3; /* Reset, R */
+ u32 gaht4; /* Reset, R */
+ u32 lsah;
+ u32 lsal;
+ u32 ipgvr; /* Reset, T */
+ u32 stacr; /* special */
+ u32 trtr; /* special */
+ u32 rwmr; /* Reset */
+ u32 octx;
+ u32 ocrx;
+ u32 ipcr;
+};
+
+#if !defined(CONFIG_IBM_EMAC4)
+#define EMAC_ETHTOOL_REGS_VER 0
+#define EMAC_ETHTOOL_REGS_SIZE (sizeof(struct emac_regs) - sizeof(u32))
+#else
+#define EMAC_ETHTOOL_REGS_VER 1
+#define EMAC_ETHTOOL_REGS_SIZE sizeof(struct emac_regs)
+#endif
-/* Emac */
-typedef struct emac_regs {
- u32 em0mr0;
- u32 em0mr1;
- u32 em0tmr0;
- u32 em0tmr1;
- u32 em0rmr;
- u32 em0isr;
- u32 em0iser;
- u32 em0iahr;
- u32 em0ialr;
- u32 em0vtpid;
- u32 em0vtci;
- u32 em0ptr;
- u32 em0iaht1;
- u32 em0iaht2;
- u32 em0iaht3;
- u32 em0iaht4;
- u32 em0gaht1;
- u32 em0gaht2;
- u32 em0gaht3;
- u32 em0gaht4;
- u32 em0lsah;
- u32 em0lsal;
- u32 em0ipgvr;
- u32 em0stacr;
- u32 em0trtr;
- u32 em0rwmr;
-} emac_t;
+/* EMACx_MR0 */
+#define EMAC_MR0_RXI 0x80000000
+#define EMAC_MR0_TXI 0x40000000
+#define EMAC_MR0_SRST 0x20000000
+#define EMAC_MR0_TXE 0x10000000
+#define EMAC_MR0_RXE 0x08000000
+#define EMAC_MR0_WKE 0x04000000
-/* MODE REG 0 */
-#define EMAC_M0_RXI 0x80000000
-#define EMAC_M0_TXI 0x40000000
-#define EMAC_M0_SRST 0x20000000
-#define EMAC_M0_TXE 0x10000000
-#define EMAC_M0_RXE 0x08000000
-#define EMAC_M0_WKE 0x04000000
+/* EMACx_MR1 */
+#define EMAC_MR1_FDE 0x80000000
+#define EMAC_MR1_ILE 0x40000000
+#define EMAC_MR1_VLE 0x20000000
+#define EMAC_MR1_EIFC 0x10000000
+#define EMAC_MR1_APP 0x08000000
+#define EMAC_MR1_IST 0x01000000
-/* MODE Reg 1 */
-#define EMAC_M1_FDE 0x80000000
-#define EMAC_M1_ILE 0x40000000
-#define EMAC_M1_VLE 0x20000000
-#define EMAC_M1_EIFC 0x10000000
-#define EMAC_M1_APP 0x08000000
-#define EMAC_M1_AEMI 0x02000000
-#define EMAC_M1_IST 0x01000000
-#define EMAC_M1_MF_1000GPCS 0x00c00000 /* Internal GPCS */
-#define EMAC_M1_MF_1000MBPS 0x00800000 /* External GPCS */
-#define EMAC_M1_MF_100MBPS 0x00400000
-#define EMAC_M1_RFS_16K 0x00280000 /* 000 for 512 byte */
-#define EMAC_M1_TR 0x00008000
-#ifdef CONFIG_IBM_EMAC4
-#define EMAC_M1_RFS_8K 0x00200000
-#define EMAC_M1_RFS_4K 0x00180000
-#define EMAC_M1_RFS_2K 0x00100000
-#define EMAC_M1_RFS_1K 0x00080000
-#define EMAC_M1_TX_FIFO_16K 0x00050000 /* 0's for 512 byte */
-#define EMAC_M1_TX_FIFO_8K 0x00040000
-#define EMAC_M1_TX_FIFO_4K 0x00030000
-#define EMAC_M1_TX_FIFO_2K 0x00020000
-#define EMAC_M1_TX_FIFO_1K 0x00010000
-#define EMAC_M1_TX_TR 0x00008000
-#define EMAC_M1_TX_MWSW 0x00001000 /* 0 wait for status */
-#define EMAC_M1_JUMBO_ENABLE 0x00000800 /* Upt to 9Kr status */
-#define EMAC_M1_OPB_CLK_66 0x00000008 /* 66Mhz */
-#define EMAC_M1_OPB_CLK_83 0x00000010 /* 83Mhz */
-#define EMAC_M1_OPB_CLK_100 0x00000018 /* 100Mhz */
-#define EMAC_M1_OPB_CLK_100P 0x00000020 /* 100Mhz+ */
-#else /* CONFIG_IBM_EMAC4 */
-#define EMAC_M1_RFS_4K 0x00300000 /* ~4k for 512 byte */
-#define EMAC_M1_RFS_2K 0x00200000
-#define EMAC_M1_RFS_1K 0x00100000
-#define EMAC_M1_TX_FIFO_2K 0x00080000 /* 0's for 512 byte */
-#define EMAC_M1_TX_FIFO_1K 0x00040000
-#define EMAC_M1_TR0_DEPEND 0x00010000 /* 0'x for single packet */
-#define EMAC_M1_TR1_DEPEND 0x00004000
-#define EMAC_M1_TR1_MULTI 0x00002000
-#define EMAC_M1_JUMBO_ENABLE 0x00001000
-#endif /* CONFIG_IBM_EMAC4 */
-#define EMAC_M1_BASE (EMAC_M1_TX_FIFO_2K | \
- EMAC_M1_APP | \
- EMAC_M1_TR | EMAC_M1_VLE)
+#define EMAC_MR1_MF_MASK 0x00c00000
+#define EMAC_MR1_MF_10 0x00000000
+#define EMAC_MR1_MF_100 0x00400000
+#if !defined(CONFIG_IBM_EMAC4)
+#define EMAC_MR1_MF_1000 0x00000000
+#define EMAC_MR1_MF_1000GPCS 0x00000000
+#define EMAC_MR1_MF_IPPA(id) 0x00000000
+#else
+#define EMAC_MR1_MF_1000 0x00800000
+#define EMAC_MR1_MF_1000GPCS 0x00c00000
+#define EMAC_MR1_MF_IPPA(id) (((id) & 0x1f) << 6)
+#endif
+
+#define EMAC_TX_FIFO_SIZE 2048
+
+#if !defined(CONFIG_IBM_EMAC4)
+#define EMAC_MR1_RFS_4K 0x00300000
+#define EMAC_MR1_RFS_16K 0x00000000
+#define EMAC_RX_FIFO_SIZE(gige) 4096
+#define EMAC_MR1_TFS_2K 0x00080000
+#define EMAC_MR1_TR0_MULT 0x00008000
+#define EMAC_MR1_JPSM 0x00000000
+#define EMAC_MR1_BASE(opb) (EMAC_MR1_TFS_2K | EMAC_MR1_TR0_MULT)
+#else
+#define EMAC_MR1_RFS_4K 0x00180000
+#define EMAC_MR1_RFS_16K 0x00280000
+#define EMAC_RX_FIFO_SIZE(gige) ((gige) ? 16384 : 4096)
+#define EMAC_MR1_TFS_2K 0x00020000
+#define EMAC_MR1_TR 0x00008000
+#define EMAC_MR1_MWSW_001 0x00001000
+#define EMAC_MR1_JPSM 0x00000800
+#define EMAC_MR1_OBCI_MASK 0x00000038
+#define EMAC_MR1_OBCI_50 0x00000000
+#define EMAC_MR1_OBCI_66 0x00000008
+#define EMAC_MR1_OBCI_83 0x00000010
+#define EMAC_MR1_OBCI_100 0x00000018
+#define EMAC_MR1_OBCI_100P 0x00000020
+#define EMAC_MR1_OBCI(freq) ((freq) <= 50 ? EMAC_MR1_OBCI_50 : \
+ (freq) <= 66 ? EMAC_MR1_OBCI_66 : \
+ (freq) <= 83 ? EMAC_MR1_OBCI_83 : \
+ (freq) <= 100 ? EMAC_MR1_OBCI_100 : EMAC_MR1_OBCI_100P)
+#define EMAC_MR1_BASE(opb) (EMAC_MR1_TFS_2K | EMAC_MR1_TR | \
+ EMAC_MR1_MWSW_001 | EMAC_MR1_OBCI(opb))
+#endif
-/* Transmit Mode Register 0 */
-#define EMAC_TMR0_GNP0 0x80000000
-#define EMAC_TMR0_GNP1 0x40000000
-#define EMAC_TMR0_GNPD 0x20000000
-#define EMAC_TMR0_FC 0x10000000
+/* EMACx_TMR0 */
+#define EMAC_TMR0_GNP 0x80000000
+#if !defined(CONFIG_IBM_EMAC4)
+#define EMAC_TMR0_DEFAULT 0x00000000
+#else
#define EMAC_TMR0_TFAE_2_32 0x00000001
#define EMAC_TMR0_TFAE_4_64 0x00000002
#define EMAC_TMR0_TFAE_8_128 0x00000003
@@ -112,14 +145,36 @@ typedef struct emac_regs {
#define EMAC_TMR0_TFAE_32_512 0x00000005
#define EMAC_TMR0_TFAE_64_1024 0x00000006
#define EMAC_TMR0_TFAE_128_2048 0x00000007
+#define EMAC_TMR0_DEFAULT EMAC_TMR0_TFAE_2_32
+#endif
+#define EMAC_TMR0_XMIT (EMAC_TMR0_GNP | EMAC_TMR0_DEFAULT)
+
+/* EMACx_TMR1 */
+
+/* IBM manuals are not very clear here.
+ * This is my interpretation of how things are. --ebs
+ */
+#if defined(CONFIG_40x)
+#define EMAC_FIFO_ENTRY_SIZE 8
+#define EMAC_MAL_BURST_SIZE (16 * 4)
+#else
+#define EMAC_FIFO_ENTRY_SIZE 16
+#define EMAC_MAL_BURST_SIZE (64 * 4)
+#endif
+
+#if !defined(CONFIG_IBM_EMAC4)
+#define EMAC_TMR1(l,h) (((l) << 27) | (((h) & 0xff) << 16))
+#else
+#define EMAC_TMR1(l,h) (((l) << 27) | (((h) & 0x3ff) << 14))
+#endif
-/* Receive Mode Register */
+/* EMACx_RMR */
#define EMAC_RMR_SP 0x80000000
#define EMAC_RMR_SFCS 0x40000000
-#define EMAC_RMR_ARRP 0x20000000
-#define EMAC_RMR_ARP 0x10000000
-#define EMAC_RMR_AROP 0x08000000
-#define EMAC_RMR_ARPI 0x04000000
+#define EMAC_RMR_RRP 0x20000000
+#define EMAC_RMR_RFP 0x10000000
+#define EMAC_RMR_ROP 0x08000000
+#define EMAC_RMR_RPIR 0x04000000
#define EMAC_RMR_PPP 0x02000000
#define EMAC_RMR_PME 0x01000000
#define EMAC_RMR_PMME 0x00800000
@@ -127,6 +182,9 @@ typedef struct emac_regs {
#define EMAC_RMR_MIAE 0x00200000
#define EMAC_RMR_BAE 0x00100000
#define EMAC_RMR_MAE 0x00080000
+#if !defined(CONFIG_IBM_EMAC4)
+#define EMAC_RMR_BASE 0x00000000
+#else
#define EMAC_RMR_RFAF_2_32 0x00000001
#define EMAC_RMR_RFAF_4_64 0x00000002
#define EMAC_RMR_RFAF_8_128 0x00000003
@@ -134,9 +192,21 @@ typedef struct emac_regs {
#define EMAC_RMR_RFAF_32_512 0x00000005
#define EMAC_RMR_RFAF_64_1024 0x00000006
#define EMAC_RMR_RFAF_128_2048 0x00000007
-#define EMAC_RMR_BASE (EMAC_RMR_IAE | EMAC_RMR_BAE)
+#define EMAC_RMR_BASE EMAC_RMR_RFAF_128_2048
+#endif
-/* Interrupt Status & enable Regs */
+/* EMACx_ISR & EMACx_ISER */
+#if !defined(CONFIG_IBM_EMAC4)
+#define EMAC_ISR_TXPE 0x00000000
+#define EMAC_ISR_RXPE 0x00000000
+#define EMAC_ISR_TXUE 0x00000000
+#define EMAC_ISR_RXOE 0x00000000
+#else
+#define EMAC_ISR_TXPE 0x20000000
+#define EMAC_ISR_RXPE 0x10000000
+#define EMAC_ISR_TXUE 0x08000000
+#define EMAC_ISR_RXOE 0x04000000
+#endif
#define EMAC_ISR_OVR 0x02000000
#define EMAC_ISR_PP 0x01000000
#define EMAC_ISR_BP 0x00800000
@@ -147,53 +217,81 @@ typedef struct emac_regs {
#define EMAC_ISR_PTLE 0x00040000
#define EMAC_ISR_ORE 0x00020000
#define EMAC_ISR_IRE 0x00010000
-#define EMAC_ISR_DBDM 0x00000200
-#define EMAC_ISR_DB0 0x00000100
-#define EMAC_ISR_SE0 0x00000080
-#define EMAC_ISR_TE0 0x00000040
-#define EMAC_ISR_DB1 0x00000020
-#define EMAC_ISR_SE1 0x00000010
-#define EMAC_ISR_TE1 0x00000008
+#define EMAC_ISR_SQE 0x00000080
+#define EMAC_ISR_TE 0x00000040
#define EMAC_ISR_MOS 0x00000002
#define EMAC_ISR_MOF 0x00000001
-/* STA CONTROL REG */
+/* EMACx_STACR */
+#define EMAC_STACR_PHYD_MASK 0xffff
+#define EMAC_STACR_PHYD_SHIFT 16
#define EMAC_STACR_OC 0x00008000
#define EMAC_STACR_PHYE 0x00004000
-#define EMAC_STACR_WRITE 0x00002000
-#define EMAC_STACR_READ 0x00001000
-#define EMAC_STACR_CLK_83MHZ 0x00000800 /* 0's for 50Mhz */
-#define EMAC_STACR_CLK_66MHZ 0x00000400
-#define EMAC_STACR_CLK_100MHZ 0x00000C00
+#define EMAC_STACR_STAC_MASK 0x00003000
+#define EMAC_STACR_STAC_READ 0x00001000
+#define EMAC_STACR_STAC_WRITE 0x00002000
+#if !defined(CONFIG_IBM_EMAC4)
+#define EMAC_STACR_OPBC_MASK 0x00000C00
+#define EMAC_STACR_OPBC_50 0x00000000
+#define EMAC_STACR_OPBC_66 0x00000400
+#define EMAC_STACR_OPBC_83 0x00000800
+#define EMAC_STACR_OPBC_100 0x00000C00
+#define EMAC_STACR_OPBC(freq) ((freq) <= 50 ? EMAC_STACR_OPBC_50 : \
+ (freq) <= 66 ? EMAC_STACR_OPBC_66 : \
+ (freq) <= 83 ? EMAC_STACR_OPBC_83 : EMAC_STACR_OPBC_100)
+#define EMAC_STACR_BASE(opb) EMAC_STACR_OPBC(opb)
+#else
+#define EMAC_STACR_BASE(opb) 0x00000000
+#endif
+#define EMAC_STACR_PCDA_MASK 0x1f
+#define EMAC_STACR_PCDA_SHIFT 5
+#define EMAC_STACR_PRA_MASK 0x1f
-/* Transmit Request Threshold Register */
-#define EMAC_TRTR_1600 0x18000000 /* 0's for 64 Bytes */
-#define EMAC_TRTR_1024 0x0f000000
-#define EMAC_TRTR_512 0x07000000
-#define EMAC_TRTR_256 0x03000000
-#define EMAC_TRTR_192 0x10000000
-#define EMAC_TRTR_128 0x01000000
+/*
+ * For the 440SPe, AMCC inexplicably changed the polarity of
+ * the "operation complete" bit in the MII control register.
+ */
+#if defined(CONFIG_440SPE)
+static inline int emac_phy_done(u32 stacr)
+{
+ return !(stacr & EMAC_STACR_OC);
+};
+#define EMAC_STACR_START EMAC_STACR_OC
+#else /* CONFIG_440SPE */
+static inline int emac_phy_done(u32 stacr)
+{
+ return stacr & EMAC_STACR_OC;
+};
+#define EMAC_STACR_START 0
+#endif /* !CONFIG_440SPE */
+
+/* EMACx_TRTR */
+#if !defined(CONFIG_IBM_EMAC4)
+#define EMAC_TRTR_SHIFT 27
+#else
+#define EMAC_TRTR_SHIFT 24
+#endif
+#define EMAC_TRTR(size) ((((size) >> 6) - 1) << EMAC_TRTR_SHIFT)
+
+/* EMACx_RWMR */
+#if !defined(CONFIG_IBM_EMAC4)
+#define EMAC_RWMR(l,h) (((l) << 23) | ( ((h) & 0x1ff) << 7))
+#else
+#define EMAC_RWMR(l,h) (((l) << 22) | ( ((h) & 0x3ff) << 6))
+#endif
+
+/* EMAC specific TX descriptor control fields (write access) */
#define EMAC_TX_CTRL_GFCS 0x0200
#define EMAC_TX_CTRL_GP 0x0100
#define EMAC_TX_CTRL_ISA 0x0080
#define EMAC_TX_CTRL_RSA 0x0040
#define EMAC_TX_CTRL_IVT 0x0020
#define EMAC_TX_CTRL_RVT 0x0010
-#define EMAC_TX_CTRL_TAH_CSUM 0x000e /* TAH only */
-#define EMAC_TX_CTRL_TAH_SEG4 0x000a /* TAH only */
-#define EMAC_TX_CTRL_TAH_SEG3 0x0008 /* TAH only */
-#define EMAC_TX_CTRL_TAH_SEG2 0x0006 /* TAH only */
-#define EMAC_TX_CTRL_TAH_SEG1 0x0004 /* TAH only */
-#define EMAC_TX_CTRL_TAH_SEG0 0x0002 /* TAH only */
-#define EMAC_TX_CTRL_TAH_DIS 0x0000 /* TAH only */
-
-#define EMAC_TX_CTRL_DFLT ( \
- MAL_TX_CTRL_INTR | EMAC_TX_CTRL_GFCS | EMAC_TX_CTRL_GP )
+#define EMAC_TX_CTRL_TAH_CSUM 0x000e
-/* madmal transmit status / Control bits */
+/* EMAC specific TX descriptor status fields (read access) */
#define EMAC_TX_ST_BFCS 0x0200
-#define EMAC_TX_ST_BPP 0x0100
#define EMAC_TX_ST_LCS 0x0080
#define EMAC_TX_ST_ED 0x0040
#define EMAC_TX_ST_EC 0x0020
@@ -202,8 +300,16 @@ typedef struct emac_regs {
#define EMAC_TX_ST_SC 0x0004
#define EMAC_TX_ST_UR 0x0002
#define EMAC_TX_ST_SQE 0x0001
+#if !defined(CONFIG_IBM_EMAC_TAH)
+#define EMAC_IS_BAD_TX(v) ((v) & (EMAC_TX_ST_LCS | EMAC_TX_ST_ED | \
+ EMAC_TX_ST_EC | EMAC_TX_ST_LC | \
+ EMAC_TX_ST_MC | EMAC_TX_ST_UR))
+#else
+#define EMAC_IS_BAD_TX(v) ((v) & (EMAC_TX_ST_LCS | EMAC_TX_ST_ED | \
+ EMAC_TX_ST_EC | EMAC_TX_ST_LC))
+#endif
-/* madmal receive status / Control bits */
+/* EMAC specific RX descriptor status fields (read access) */
#define EMAC_RX_ST_OE 0x0200
#define EMAC_RX_ST_PP 0x0100
#define EMAC_RX_ST_BP 0x0080
@@ -214,54 +320,10 @@ typedef struct emac_regs {
#define EMAC_RX_ST_PTL 0x0004
#define EMAC_RX_ST_ORE 0x0002
#define EMAC_RX_ST_IRE 0x0001
-#define EMAC_BAD_RX_PACKET 0x02ff
-#define EMAC_CSUM_VER_ERROR 0x0003
-
-/* identify a bad rx packet dependent on emac features */
-#ifdef CONFIG_IBM_EMAC4
-#define EMAC_IS_BAD_RX_PACKET(desc) \
- (((desc & (EMAC_BAD_RX_PACKET & ~EMAC_CSUM_VER_ERROR)) || \
- ((desc & EMAC_CSUM_VER_ERROR) == EMAC_RX_ST_ORE) || \
- ((desc & EMAC_CSUM_VER_ERROR) == EMAC_RX_ST_IRE)))
-#else
-#define EMAC_IS_BAD_RX_PACKET(desc) \
- (desc & EMAC_BAD_RX_PACKET)
-#endif
-
-/* SoC implementation specific EMAC register defaults */
-#if defined(CONFIG_440GP)
-#define EMAC_RWMR_DEFAULT 0x80009000
-#define EMAC_TMR0_DEFAULT 0x00000000
-#define EMAC_TMR1_DEFAULT 0xf8640000
-#elif defined(CONFIG_440GX)
-#define EMAC_RWMR_DEFAULT 0x1000a200
-#define EMAC_TMR0_DEFAULT EMAC_TMR0_TFAE_2_32
-#define EMAC_TMR1_DEFAULT 0xa00f0000
-#elif defined(CONFIG_440SP)
-#define EMAC_RWMR_DEFAULT 0x08002000
-#define EMAC_TMR0_DEFAULT EMAC_TMR0_TFAE_128_2048
-#define EMAC_TMR1_DEFAULT 0xf8200000
-#else
-#define EMAC_RWMR_DEFAULT 0x0f002000
-#define EMAC_TMR0_DEFAULT 0x00000000
-#define EMAC_TMR1_DEFAULT 0x380f0000
-#endif /* CONFIG_440GP */
-
-/* Revision specific EMAC register defaults */
-#ifdef CONFIG_IBM_EMAC4
-#define EMAC_M1_DEFAULT (EMAC_M1_BASE | \
- EMAC_M1_OPB_CLK_83 | \
- EMAC_M1_TX_MWSW)
-#define EMAC_RMR_DEFAULT (EMAC_RMR_BASE | \
- EMAC_RMR_RFAF_128_2048)
-#define EMAC_TMR0_XMIT (EMAC_TMR0_GNP0 | \
- EMAC_TMR0_DEFAULT)
-#define EMAC_TRTR_DEFAULT EMAC_TRTR_1024
-#else /* !CONFIG_IBM_EMAC4 */
-#define EMAC_M1_DEFAULT EMAC_M1_BASE
-#define EMAC_RMR_DEFAULT EMAC_RMR_BASE
-#define EMAC_TMR0_XMIT EMAC_TMR0_GNP0
-#define EMAC_TRTR_DEFAULT EMAC_TRTR_1600
-#endif /* CONFIG_IBM_EMAC4 */
-
-#endif
+#define EMAC_RX_TAH_BAD_CSUM 0x0003
+#define EMAC_BAD_RX_MASK (EMAC_RX_ST_OE | EMAC_RX_ST_BP | \
+ EMAC_RX_ST_RP | EMAC_RX_ST_SE | \
+ EMAC_RX_ST_AE | EMAC_RX_ST_BFCS | \
+ EMAC_RX_ST_PTL | EMAC_RX_ST_ORE | \
+ EMAC_RX_ST_IRE )
+#endif /* __IBM_EMAC_H_ */
diff --git a/drivers/net/ibm_emac/ibm_emac_core.c b/drivers/net/ibm_emac/ibm_emac_core.c
index 14e9b6315f20..eb7d69478715 100644
--- a/drivers/net/ibm_emac/ibm_emac_core.c
+++ b/drivers/net/ibm_emac/ibm_emac_core.c
@@ -1,13 +1,14 @@
/*
- * ibm_emac_core.c
+ * drivers/net/ibm_emac/ibm_emac_core.c
*
- * Ethernet driver for the built in ethernet on the IBM 4xx PowerPC
- * processors.
- *
- * (c) 2003 Benjamin Herrenschmidt <benh@kernel.crashing.org>
+ * Driver for PowerPC 4xx on-chip ethernet controller.
*
- * Based on original work by
+ * Copyright (c) 2004, 2005 Zultys Technologies.
+ * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
*
+ * Based on original work by
+ * Matt Porter <mporter@kernel.crashing.org>
+ * (c) 2003 Benjamin Herrenschmidt <benh@kernel.crashing.org>
* Armin Kuster <akuster@mvista.com>
* Johnnie Peters <jpeters@mvista.com>
*
@@ -15,29 +16,24 @@
* 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.
- * TODO
- * - Check for races in the "remove" code path
- * - Add some Power Management to the MAC and the PHY
- * - Audit remaining of non-rewritten code (--BenH)
- * - Cleanup message display using msglevel mecanism
- * - Address all errata
- * - Audit all register update paths to ensure they
- * are being written post soft reset if required.
+ *
*/
+
+#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/string.h>
-#include <linux/timer.h>
-#include <linux/ptrace.h>
#include <linux/errno.h>
-#include <linux/ioport.h>
-#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/types.h>
-#include <linux/dma-mapping.h>
+#include <linux/pci.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/crc32.h>
#include <linux/ethtool.h>
#include <linux/mii.h>
#include <linux/bitops.h>
@@ -45,1691 +41,1895 @@
#include <asm/processor.h>
#include <asm/io.h>
#include <asm/dma.h>
-#include <asm/irq.h>
#include <asm/uaccess.h>
#include <asm/ocp.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-#include <linux/crc32.h>
-
#include "ibm_emac_core.h"
-
-//#define MDIO_DEBUG(fmt) printk fmt
-#define MDIO_DEBUG(fmt)
-
-//#define LINK_DEBUG(fmt) printk fmt
-#define LINK_DEBUG(fmt)
-
-//#define PKT_DEBUG(fmt) printk fmt
-#define PKT_DEBUG(fmt)
-
-#define DRV_NAME "emac"
-#define DRV_VERSION "2.0"
-#define DRV_AUTHOR "Benjamin Herrenschmidt <benh@kernel.crashing.org>"
-#define DRV_DESC "IBM EMAC Ethernet driver"
+#include "ibm_emac_debug.h"
/*
- * When mdio_idx >= 0, contains a list of emac ocp_devs
- * that have had their initialization deferred until the
- * common MDIO controller has been initialized.
+ * Lack of dma_unmap_???? calls is intentional.
+ *
+ * API-correct usage requires additional support state information to be
+ * maintained for every RX and TX buffer descriptor (BD). Unfortunately, due to
+ * EMAC design (e.g. TX buffer passed from network stack can be split into
+ * several BDs, dma_map_single/dma_map_page can be used to map particular BD),
+ * maintaining such information will add additional overhead.
+ * Current DMA API implementation for 4xx processors only ensures cache coherency
+ * and dma_unmap_???? routines are empty and are likely to stay this way.
+ * I decided to omit dma_unmap_??? calls because I don't want to add additional
+ * complexity just for the sake of following some abstract API, when it doesn't
+ * add any real benefit to the driver. I understand that this decision maybe
+ * controversial, but I really tried to make code API-correct and efficient
+ * at the same time and didn't come up with code I liked :(. --ebs
*/
-LIST_HEAD(emac_init_list);
-MODULE_AUTHOR(DRV_AUTHOR);
+#define DRV_NAME "emac"
+#define DRV_VERSION "3.53"
+#define DRV_DESC "PPC 4xx OCP EMAC driver"
+
MODULE_DESCRIPTION(DRV_DESC);
+MODULE_AUTHOR
+ ("Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>");
MODULE_LICENSE("GPL");
-static int skb_res = SKB_RES;
-module_param(skb_res, int, 0444);
-MODULE_PARM_DESC(skb_res, "Amount of data to reserve on skb buffs\n"
- "The 405 handles a misaligned IP header fine but\n"
- "this can help if you are routing to a tunnel or a\n"
- "device that needs aligned data. 0..2");
-
-#define RGMII_PRIV(ocpdev) ((struct ibm_ocp_rgmii*)ocp_get_drvdata(ocpdev))
+/* minimum number of free TX descriptors required to wake up TX process */
+#define EMAC_TX_WAKEUP_THRESH (NUM_TX_BUFF / 4)
-static unsigned int rgmii_enable[] = {
- RGMII_RTBI,
- RGMII_RGMII,
- RGMII_TBI,
- RGMII_GMII
-};
-
-static unsigned int rgmii_speed_mask[] = {
- RGMII_MII2_SPDMASK,
- RGMII_MII3_SPDMASK
-};
+/* If packet size is less than this number, we allocate small skb and copy packet
+ * contents into it instead of just sending original big skb up
+ */
+#define EMAC_RX_COPY_THRESH CONFIG_IBM_EMAC_RX_COPY_THRESHOLD
-static unsigned int rgmii_speed100[] = {
- RGMII_MII2_100MB,
- RGMII_MII3_100MB
-};
+/* Since multiple EMACs share MDIO lines in various ways, we need
+ * to avoid re-using the same PHY ID in cases where the arch didn't
+ * setup precise phy_map entries
+ */
+static u32 busy_phy_map;
+
+#if defined(CONFIG_IBM_EMAC_PHY_RX_CLK_FIX) && \
+ (defined(CONFIG_405EP) || defined(CONFIG_440EP) || defined(CONFIG_440GR))
+/* 405EP has "EMAC to PHY Control Register" (CPC0_EPCTL) which can help us
+ * with PHY RX clock problem.
+ * 440EP/440GR has more sane SDR0_MFR register implementation than 440GX, which
+ * also allows controlling each EMAC clock
+ */
+static inline void EMAC_RX_CLK_TX(int idx)
+{
+ unsigned long flags;
+ local_irq_save(flags);
-static unsigned int rgmii_speed1000[] = {
- RGMII_MII2_1000MB,
- RGMII_MII3_1000MB
-};
+#if defined(CONFIG_405EP)
+ mtdcr(0xf3, mfdcr(0xf3) | (1 << idx));
+#else /* CONFIG_440EP || CONFIG_440GR */
+ SDR_WRITE(DCRN_SDR_MFR, SDR_READ(DCRN_SDR_MFR) | (0x08000000 >> idx));
+#endif
-#define ZMII_PRIV(ocpdev) ((struct ibm_ocp_zmii*)ocp_get_drvdata(ocpdev))
+ local_irq_restore(flags);
+}
-static unsigned int zmii_enable[][4] = {
- {ZMII_SMII0, ZMII_RMII0, ZMII_MII0,
- ~(ZMII_MDI1 | ZMII_MDI2 | ZMII_MDI3)},
- {ZMII_SMII1, ZMII_RMII1, ZMII_MII1,
- ~(ZMII_MDI0 | ZMII_MDI2 | ZMII_MDI3)},
- {ZMII_SMII2, ZMII_RMII2, ZMII_MII2,
- ~(ZMII_MDI0 | ZMII_MDI1 | ZMII_MDI3)},
- {ZMII_SMII3, ZMII_RMII3, ZMII_MII3, ~(ZMII_MDI0 | ZMII_MDI1 | ZMII_MDI2)}
-};
+static inline void EMAC_RX_CLK_DEFAULT(int idx)
+{
+ unsigned long flags;
+ local_irq_save(flags);
-static unsigned int mdi_enable[] = {
- ZMII_MDI0,
- ZMII_MDI1,
- ZMII_MDI2,
- ZMII_MDI3
-};
+#if defined(CONFIG_405EP)
+ mtdcr(0xf3, mfdcr(0xf3) & ~(1 << idx));
+#else /* CONFIG_440EP */
+ SDR_WRITE(DCRN_SDR_MFR, SDR_READ(DCRN_SDR_MFR) & ~(0x08000000 >> idx));
+#endif
-static unsigned int zmii_speed = 0x0;
-static unsigned int zmii_speed100[] = {
- ZMII_MII0_100MB,
- ZMII_MII1_100MB,
- ZMII_MII2_100MB,
- ZMII_MII3_100MB
-};
+ local_irq_restore(flags);
+}
+#else
+#define EMAC_RX_CLK_TX(idx) ((void)0)
+#define EMAC_RX_CLK_DEFAULT(idx) ((void)0)
+#endif
-/* Since multiple EMACs share MDIO lines in various ways, we need
- * to avoid re-using the same PHY ID in cases where the arch didn't
- * setup precise phy_map entries
+#if defined(CONFIG_IBM_EMAC_PHY_RX_CLK_FIX) && defined(CONFIG_440GX)
+/* We can switch Ethernet clock to the internal source through SDR0_MFR[ECS],
+ * unfortunately this is less flexible than 440EP case, because it's a global
+ * setting for all EMACs, therefore we do this clock trick only during probe.
*/
-static u32 busy_phy_map = 0;
+#define EMAC_CLK_INTERNAL SDR_WRITE(DCRN_SDR_MFR, \
+ SDR_READ(DCRN_SDR_MFR) | 0x08000000)
+#define EMAC_CLK_EXTERNAL SDR_WRITE(DCRN_SDR_MFR, \
+ SDR_READ(DCRN_SDR_MFR) & ~0x08000000)
+#else
+#define EMAC_CLK_INTERNAL ((void)0)
+#define EMAC_CLK_EXTERNAL ((void)0)
+#endif
-/* If EMACs share a common MDIO device, this points to it */
-static struct net_device *mdio_ndev = NULL;
+/* I don't want to litter system log with timeout errors
+ * when we have brain-damaged PHY.
+ */
+static inline void emac_report_timeout_error(struct ocp_enet_private *dev,
+ const char *error)
+{
+#if defined(CONFIG_IBM_EMAC_PHY_RX_CLK_FIX)
+ DBG("%d: %s" NL, dev->def->index, error);
+#else
+ if (net_ratelimit())
+ printk(KERN_ERR "emac%d: %s\n", dev->def->index, error);
+#endif
+}
-struct emac_def_dev {
- struct list_head link;
- struct ocp_device *ocpdev;
- struct ibm_ocp_mal *mal;
+/* PHY polling intervals */
+#define PHY_POLL_LINK_ON HZ
+#define PHY_POLL_LINK_OFF (HZ / 5)
+
+/* Please, keep in sync with struct ibm_emac_stats/ibm_emac_error_stats */
+static const char emac_stats_keys[EMAC_ETHTOOL_STATS_COUNT][ETH_GSTRING_LEN] = {
+ "rx_packets", "rx_bytes", "tx_packets", "tx_bytes", "rx_packets_csum",
+ "tx_packets_csum", "tx_undo", "rx_dropped_stack", "rx_dropped_oom",
+ "rx_dropped_error", "rx_dropped_resize", "rx_dropped_mtu",
+ "rx_stopped", "rx_bd_errors", "rx_bd_overrun", "rx_bd_bad_packet",
+ "rx_bd_runt_packet", "rx_bd_short_event", "rx_bd_alignment_error",
+ "rx_bd_bad_fcs", "rx_bd_packet_too_long", "rx_bd_out_of_range",
+ "rx_bd_in_range", "rx_parity", "rx_fifo_overrun", "rx_overrun",
+ "rx_bad_packet", "rx_runt_packet", "rx_short_event",
+ "rx_alignment_error", "rx_bad_fcs", "rx_packet_too_long",
+ "rx_out_of_range", "rx_in_range", "tx_dropped", "tx_bd_errors",
+ "tx_bd_bad_fcs", "tx_bd_carrier_loss", "tx_bd_excessive_deferral",
+ "tx_bd_excessive_collisions", "tx_bd_late_collision",
+ "tx_bd_multple_collisions", "tx_bd_single_collision",
+ "tx_bd_underrun", "tx_bd_sqe", "tx_parity", "tx_underrun", "tx_sqe",
+ "tx_errors"
};
-static struct net_device_stats *emac_stats(struct net_device *dev)
+static irqreturn_t emac_irq(int irq, void *dev_instance, struct pt_regs *regs);
+static void emac_clean_tx_ring(struct ocp_enet_private *dev);
+
+static inline int emac_phy_supports_gige(int phy_mode)
{
- struct ocp_enet_private *fep = dev->priv;
- return &fep->stats;
-};
+ return phy_mode == PHY_MODE_GMII ||
+ phy_mode == PHY_MODE_RGMII ||
+ phy_mode == PHY_MODE_TBI ||
+ phy_mode == PHY_MODE_RTBI;
+}
-static int
-emac_init_rgmii(struct ocp_device *rgmii_dev, int input, int phy_mode)
+static inline int emac_phy_gpcs(int phy_mode)
{
- struct ibm_ocp_rgmii *rgmii = RGMII_PRIV(rgmii_dev);
- const char *mode_name[] = { "RTBI", "RGMII", "TBI", "GMII" };
- int mode = -1;
+ return phy_mode == PHY_MODE_TBI ||
+ phy_mode == PHY_MODE_RTBI;
+}
- if (!rgmii) {
- rgmii = kmalloc(sizeof(struct ibm_ocp_rgmii), GFP_KERNEL);
+static inline void emac_tx_enable(struct ocp_enet_private *dev)
+{
+ struct emac_regs *p = dev->emacp;
+ unsigned long flags;
+ u32 r;
- if (rgmii == NULL) {
- printk(KERN_ERR
- "rgmii%d: Out of memory allocating RGMII structure!\n",
- rgmii_dev->def->index);
- return -ENOMEM;
- }
+ local_irq_save(flags);
- memset(rgmii, 0, sizeof(*rgmii));
+ DBG("%d: tx_enable" NL, dev->def->index);
- rgmii->base =
- (struct rgmii_regs *)ioremap(rgmii_dev->def->paddr,
- sizeof(*rgmii->base));
- if (rgmii->base == NULL) {
- printk(KERN_ERR
- "rgmii%d: Cannot ioremap bridge registers!\n",
- rgmii_dev->def->index);
+ r = in_be32(&p->mr0);
+ if (!(r & EMAC_MR0_TXE))
+ out_be32(&p->mr0, r | EMAC_MR0_TXE);
+ local_irq_restore(flags);
+}
- kfree(rgmii);
- return -ENOMEM;
- }
- ocp_set_drvdata(rgmii_dev, rgmii);
- }
+static void emac_tx_disable(struct ocp_enet_private *dev)
+{
+ struct emac_regs *p = dev->emacp;
+ unsigned long flags;
+ u32 r;
- if (phy_mode) {
- switch (phy_mode) {
- case PHY_MODE_GMII:
- mode = GMII;
- break;
- case PHY_MODE_TBI:
- mode = TBI;
- break;
- case PHY_MODE_RTBI:
- mode = RTBI;
- break;
- case PHY_MODE_RGMII:
- default:
- mode = RGMII;
- }
- rgmii->base->fer &= ~RGMII_FER_MASK(input);
- rgmii->base->fer |= rgmii_enable[mode] << (4 * input);
- } else {
- switch ((rgmii->base->fer & RGMII_FER_MASK(input)) >> (4 *
- input)) {
- case RGMII_RTBI:
- mode = RTBI;
- break;
- case RGMII_RGMII:
- mode = RGMII;
- break;
- case RGMII_TBI:
- mode = TBI;
- break;
- case RGMII_GMII:
- mode = GMII;
- }
- }
+ local_irq_save(flags);
- /* Set mode to RGMII if nothing valid is detected */
- if (mode < 0)
- mode = RGMII;
+ DBG("%d: tx_disable" NL, dev->def->index);
- printk(KERN_NOTICE "rgmii%d: input %d in %s mode\n",
- rgmii_dev->def->index, input, mode_name[mode]);
+ r = in_be32(&p->mr0);
+ if (r & EMAC_MR0_TXE) {
+ int n = 300;
+ out_be32(&p->mr0, r & ~EMAC_MR0_TXE);
+ while (!(in_be32(&p->mr0) & EMAC_MR0_TXI) && n)
+ --n;
+ if (unlikely(!n))
+ emac_report_timeout_error(dev, "TX disable timeout");
+ }
+ local_irq_restore(flags);
+}
- rgmii->mode[input] = mode;
- rgmii->users++;
+static void emac_rx_enable(struct ocp_enet_private *dev)
+{
+ struct emac_regs *p = dev->emacp;
+ unsigned long flags;
+ u32 r;
- return 0;
+ local_irq_save(flags);
+ if (unlikely(dev->commac.rx_stopped))
+ goto out;
+
+ DBG("%d: rx_enable" NL, dev->def->index);
+
+ r = in_be32(&p->mr0);
+ if (!(r & EMAC_MR0_RXE)) {
+ if (unlikely(!(r & EMAC_MR0_RXI))) {
+ /* Wait if previous async disable is still in progress */
+ int n = 100;
+ while (!(r = in_be32(&p->mr0) & EMAC_MR0_RXI) && n)
+ --n;
+ if (unlikely(!n))
+ emac_report_timeout_error(dev,
+ "RX disable timeout");
+ }
+ out_be32(&p->mr0, r | EMAC_MR0_RXE);
+ }
+ out:
+ local_irq_restore(flags);
}
-static void
-emac_rgmii_port_speed(struct ocp_device *ocpdev, int input, int speed)
+static void emac_rx_disable(struct ocp_enet_private *dev)
{
- struct ibm_ocp_rgmii *rgmii = RGMII_PRIV(ocpdev);
- unsigned int rgmii_speed;
-
- rgmii_speed = in_be32(&rgmii->base->ssr);
+ struct emac_regs *p = dev->emacp;
+ unsigned long flags;
+ u32 r;
- rgmii_speed &= ~rgmii_speed_mask[input];
+ local_irq_save(flags);
- if (speed == 1000)
- rgmii_speed |= rgmii_speed1000[input];
- else if (speed == 100)
- rgmii_speed |= rgmii_speed100[input];
+ DBG("%d: rx_disable" NL, dev->def->index);
- out_be32(&rgmii->base->ssr, rgmii_speed);
+ r = in_be32(&p->mr0);
+ if (r & EMAC_MR0_RXE) {
+ int n = 300;
+ out_be32(&p->mr0, r & ~EMAC_MR0_RXE);
+ while (!(in_be32(&p->mr0) & EMAC_MR0_RXI) && n)
+ --n;
+ if (unlikely(!n))
+ emac_report_timeout_error(dev, "RX disable timeout");
+ }
+ local_irq_restore(flags);
}
-static void emac_close_rgmii(struct ocp_device *ocpdev)
+static inline void emac_rx_disable_async(struct ocp_enet_private *dev)
{
- struct ibm_ocp_rgmii *rgmii = RGMII_PRIV(ocpdev);
- BUG_ON(!rgmii || rgmii->users == 0);
+ struct emac_regs *p = dev->emacp;
+ unsigned long flags;
+ u32 r;
- if (!--rgmii->users) {
- ocp_set_drvdata(ocpdev, NULL);
- iounmap((void *)rgmii->base);
- kfree(rgmii);
- }
+ local_irq_save(flags);
+
+ DBG("%d: rx_disable_async" NL, dev->def->index);
+
+ r = in_be32(&p->mr0);
+ if (r & EMAC_MR0_RXE)
+ out_be32(&p->mr0, r & ~EMAC_MR0_RXE);
+ local_irq_restore(flags);
}
-static int emac_init_zmii(struct ocp_device *zmii_dev, int input, int phy_mode)
+static int emac_reset(struct ocp_enet_private *dev)
{
- struct ibm_ocp_zmii *zmii = ZMII_PRIV(zmii_dev);
- const char *mode_name[] = { "SMII", "RMII", "MII" };
- int mode = -1;
+ struct emac_regs *p = dev->emacp;
+ unsigned long flags;
+ int n = 20;
- if (!zmii) {
- zmii = kmalloc(sizeof(struct ibm_ocp_zmii), GFP_KERNEL);
- if (zmii == NULL) {
- printk(KERN_ERR
- "zmii%d: Out of memory allocating ZMII structure!\n",
- zmii_dev->def->index);
- return -ENOMEM;
- }
- memset(zmii, 0, sizeof(*zmii));
+ DBG("%d: reset" NL, dev->def->index);
- zmii->base =
- (struct zmii_regs *)ioremap(zmii_dev->def->paddr,
- sizeof(*zmii->base));
- if (zmii->base == NULL) {
- printk(KERN_ERR
- "zmii%d: Cannot ioremap bridge registers!\n",
- zmii_dev->def->index);
+ local_irq_save(flags);
- kfree(zmii);
- return -ENOMEM;
- }
- ocp_set_drvdata(zmii_dev, zmii);
+ if (!dev->reset_failed) {
+ /* 40x erratum suggests stopping RX channel before reset,
+ * we stop TX as well
+ */
+ emac_rx_disable(dev);
+ emac_tx_disable(dev);
}
- if (phy_mode) {
- switch (phy_mode) {
- case PHY_MODE_MII:
- mode = MII;
- break;
- case PHY_MODE_RMII:
- mode = RMII;
- break;
- case PHY_MODE_SMII:
- default:
- mode = SMII;
- }
- zmii->base->fer &= ~ZMII_FER_MASK(input);
- zmii->base->fer |= zmii_enable[input][mode];
+ out_be32(&p->mr0, EMAC_MR0_SRST);
+ while ((in_be32(&p->mr0) & EMAC_MR0_SRST) && n)
+ --n;
+ local_irq_restore(flags);
+
+ if (n) {
+ dev->reset_failed = 0;
+ return 0;
} else {
- switch ((zmii->base->fer & ZMII_FER_MASK(input)) << (4 * input)) {
- case ZMII_MII0:
- mode = MII;
- break;
- case ZMII_RMII0:
- mode = RMII;
- break;
- case ZMII_SMII0:
- mode = SMII;
- }
+ emac_report_timeout_error(dev, "reset timeout");
+ dev->reset_failed = 1;
+ return -ETIMEDOUT;
}
+}
- /* Set mode to SMII if nothing valid is detected */
- if (mode < 0)
- mode = SMII;
+static void emac_hash_mc(struct ocp_enet_private *dev)
+{
+ struct emac_regs *p = dev->emacp;
+ u16 gaht[4] = { 0 };
+ struct dev_mc_list *dmi;
- printk(KERN_NOTICE "zmii%d: input %d in %s mode\n",
- zmii_dev->def->index, input, mode_name[mode]);
+ DBG("%d: hash_mc %d" NL, dev->def->index, dev->ndev->mc_count);
- zmii->mode[input] = mode;
- zmii->users++;
+ for (dmi = dev->ndev->mc_list; dmi; dmi = dmi->next) {
+ int bit;
+ DBG2("%d: mc %02x:%02x:%02x:%02x:%02x:%02x" NL,
+ dev->def->index,
+ dmi->dmi_addr[0], dmi->dmi_addr[1], dmi->dmi_addr[2],
+ dmi->dmi_addr[3], dmi->dmi_addr[4], dmi->dmi_addr[5]);
- return 0;
+ bit = 63 - (ether_crc(ETH_ALEN, dmi->dmi_addr) >> 26);
+ gaht[bit >> 4] |= 0x8000 >> (bit & 0x0f);
+ }
+ out_be32(&p->gaht1, gaht[0]);
+ out_be32(&p->gaht2, gaht[1]);
+ out_be32(&p->gaht3, gaht[2]);
+ out_be32(&p->gaht4, gaht[3]);
}
-static void emac_enable_zmii_port(struct ocp_device *ocpdev, int input)
+static inline u32 emac_iff2rmr(struct net_device *ndev)
{
- u32 mask;
- struct ibm_ocp_zmii *zmii = ZMII_PRIV(ocpdev);
+ u32 r = EMAC_RMR_SP | EMAC_RMR_SFCS | EMAC_RMR_IAE | EMAC_RMR_BAE |
+ EMAC_RMR_BASE;
+
+ if (ndev->flags & IFF_PROMISC)
+ r |= EMAC_RMR_PME;
+ else if (ndev->flags & IFF_ALLMULTI || ndev->mc_count > 32)
+ r |= EMAC_RMR_PMME;
+ else if (ndev->mc_count > 0)
+ r |= EMAC_RMR_MAE;
- mask = in_be32(&zmii->base->fer);
- mask &= zmii_enable[input][MDI]; /* turn all non enabled MDI's off */
- mask |= zmii_enable[input][zmii->mode[input]] | mdi_enable[input];
- out_be32(&zmii->base->fer, mask);
+ return r;
}
-static void
-emac_zmii_port_speed(struct ocp_device *ocpdev, int input, int speed)
+static inline int emac_opb_mhz(void)
{
- struct ibm_ocp_zmii *zmii = ZMII_PRIV(ocpdev);
-
- if (speed == 100)
- zmii_speed |= zmii_speed100[input];
- else
- zmii_speed &= ~zmii_speed100[input];
-
- out_be32(&zmii->base->ssr, zmii_speed);
+ return (ocp_sys_info.opb_bus_freq + 500000) / 1000000;
}
-static void emac_close_zmii(struct ocp_device *ocpdev)
+/* BHs disabled */
+static int emac_configure(struct ocp_enet_private *dev)
{
- struct ibm_ocp_zmii *zmii = ZMII_PRIV(ocpdev);
- BUG_ON(!zmii || zmii->users == 0);
+ struct emac_regs *p = dev->emacp;
+ struct net_device *ndev = dev->ndev;
+ int gige;
+ u32 r;
- if (!--zmii->users) {
- ocp_set_drvdata(ocpdev, NULL);
- iounmap((void *)zmii->base);
- kfree(zmii);
- }
-}
+ DBG("%d: configure" NL, dev->def->index);
-int emac_phy_read(struct net_device *dev, int mii_id, int reg)
-{
- int count;
- uint32_t stacr;
- struct ocp_enet_private *fep = dev->priv;
- emac_t *emacp = fep->emacp;
+ if (emac_reset(dev) < 0)
+ return -ETIMEDOUT;
- MDIO_DEBUG(("%s: phy_read, id: 0x%x, reg: 0x%x\n", dev->name, mii_id,
- reg));
+ tah_reset(dev->tah_dev);
- /* Enable proper ZMII port */
- if (fep->zmii_dev)
- emac_enable_zmii_port(fep->zmii_dev, fep->zmii_input);
+ /* Mode register */
+ r = EMAC_MR1_BASE(emac_opb_mhz()) | EMAC_MR1_VLE | EMAC_MR1_IST;
+ if (dev->phy.duplex == DUPLEX_FULL)
+ r |= EMAC_MR1_FDE;
+ switch (dev->phy.speed) {
+ case SPEED_1000:
+ if (emac_phy_gpcs(dev->phy.mode)) {
+ r |= EMAC_MR1_MF_1000GPCS |
+ EMAC_MR1_MF_IPPA(dev->phy.address);
- /* Use the EMAC that has the MDIO port */
- if (fep->mdio_dev) {
- dev = fep->mdio_dev;
- fep = dev->priv;
- emacp = fep->emacp;
+ /* Put some arbitrary OUI, Manuf & Rev IDs so we can
+ * identify this GPCS PHY later.
+ */
+ out_be32(&p->ipcr, 0xdeadbeef);
+ } else
+ r |= EMAC_MR1_MF_1000;
+ r |= EMAC_MR1_RFS_16K;
+ gige = 1;
+
+ if (dev->ndev->mtu > ETH_DATA_LEN)
+ r |= EMAC_MR1_JPSM;
+ break;
+ case SPEED_100:
+ r |= EMAC_MR1_MF_100;
+ /* Fall through */
+ default:
+ r |= EMAC_MR1_RFS_4K;
+ gige = 0;
+ break;
}
- count = 0;
- while ((((stacr = in_be32(&emacp->em0stacr)) & EMAC_STACR_OC) == 0)
- && (count++ < MDIO_DELAY))
- udelay(1);
- MDIO_DEBUG((" (count was %d)\n", count));
+ if (dev->rgmii_dev)
+ rgmii_set_speed(dev->rgmii_dev, dev->rgmii_input,
+ dev->phy.speed);
+ else
+ zmii_set_speed(dev->zmii_dev, dev->zmii_input, dev->phy.speed);
- if ((stacr & EMAC_STACR_OC) == 0) {
- printk(KERN_WARNING "%s: PHY read timeout #1!\n", dev->name);
- return -1;
+#if !defined(CONFIG_40x)
+ /* on 40x erratum forces us to NOT use integrated flow control,
+ * let's hope it works on 44x ;)
+ */
+ if (dev->phy.duplex == DUPLEX_FULL) {
+ if (dev->phy.pause)
+ r |= EMAC_MR1_EIFC | EMAC_MR1_APP;
+ else if (dev->phy.asym_pause)
+ r |= EMAC_MR1_APP;
}
+#endif
+ out_be32(&p->mr1, r);
+
+ /* Set individual MAC address */
+ out_be32(&p->iahr, (ndev->dev_addr[0] << 8) | ndev->dev_addr[1]);
+ out_be32(&p->ialr, (ndev->dev_addr[2] << 24) |
+ (ndev->dev_addr[3] << 16) | (ndev->dev_addr[4] << 8) |
+ ndev->dev_addr[5]);
+
+ /* VLAN Tag Protocol ID */
+ out_be32(&p->vtpid, 0x8100);
+
+ /* Receive mode register */
+ r = emac_iff2rmr(ndev);
+ if (r & EMAC_RMR_MAE)
+ emac_hash_mc(dev);
+ out_be32(&p->rmr, r);
+
+ /* FIFOs thresholds */
+ r = EMAC_TMR1((EMAC_MAL_BURST_SIZE / EMAC_FIFO_ENTRY_SIZE) + 1,
+ EMAC_TX_FIFO_SIZE / 2 / EMAC_FIFO_ENTRY_SIZE);
+ out_be32(&p->tmr1, r);
+ out_be32(&p->trtr, EMAC_TRTR(EMAC_TX_FIFO_SIZE / 2));
+
+ /* PAUSE frame is sent when RX FIFO reaches its high-water mark,
+ there should be still enough space in FIFO to allow the our link
+ partner time to process this frame and also time to send PAUSE
+ frame itself.
+
+ Here is the worst case scenario for the RX FIFO "headroom"
+ (from "The Switch Book") (100Mbps, without preamble, inter-frame gap):
+
+ 1) One maximum-length frame on TX 1522 bytes
+ 2) One PAUSE frame time 64 bytes
+ 3) PAUSE frame decode time allowance 64 bytes
+ 4) One maximum-length frame on RX 1522 bytes
+ 5) Round-trip propagation delay of the link (100Mb) 15 bytes
+ ----------
+ 3187 bytes
+
+ I chose to set high-water mark to RX_FIFO_SIZE / 4 (1024 bytes)
+ low-water mark to RX_FIFO_SIZE / 8 (512 bytes)
+ */
+ r = EMAC_RWMR(EMAC_RX_FIFO_SIZE(gige) / 8 / EMAC_FIFO_ENTRY_SIZE,
+ EMAC_RX_FIFO_SIZE(gige) / 4 / EMAC_FIFO_ENTRY_SIZE);
+ out_be32(&p->rwmr, r);
+
+ /* Set PAUSE timer to the maximum */
+ out_be32(&p->ptr, 0xffff);
+
+ /* IRQ sources */
+ out_be32(&p->iser, EMAC_ISR_TXPE | EMAC_ISR_RXPE | /* EMAC_ISR_TXUE |
+ EMAC_ISR_RXOE | */ EMAC_ISR_OVR | EMAC_ISR_BP | EMAC_ISR_SE |
+ EMAC_ISR_ALE | EMAC_ISR_BFCS | EMAC_ISR_PTLE | EMAC_ISR_ORE |
+ EMAC_ISR_IRE | EMAC_ISR_TE);
+
+ /* We need to take GPCS PHY out of isolate mode after EMAC reset */
+ if (emac_phy_gpcs(dev->phy.mode))
+ mii_reset_phy(&dev->phy);
+
+ return 0;
+}
- /* Clear the speed bits and make a read request to the PHY */
- stacr = ((EMAC_STACR_READ | (reg & 0x1f)) & ~EMAC_STACR_CLK_100MHZ);
- stacr |= ((mii_id & 0x1F) << 5);
+/* BHs disabled */
+static void emac_reinitialize(struct ocp_enet_private *dev)
+{
+ DBG("%d: reinitialize" NL, dev->def->index);
- out_be32(&emacp->em0stacr, stacr);
+ if (!emac_configure(dev)) {
+ emac_tx_enable(dev);
+ emac_rx_enable(dev);
+ }
+}
- count = 0;
- while ((((stacr = in_be32(&emacp->em0stacr)) & EMAC_STACR_OC) == 0)
- && (count++ < MDIO_DELAY))
- udelay(1);
- MDIO_DEBUG((" (count was %d)\n", count));
+/* BHs disabled */
+static void emac_full_tx_reset(struct net_device *ndev)
+{
+ struct ocp_enet_private *dev = ndev->priv;
+ struct ocp_func_emac_data *emacdata = dev->def->additions;
- if ((stacr & EMAC_STACR_OC) == 0) {
- printk(KERN_WARNING "%s: PHY read timeout #2!\n", dev->name);
- return -1;
- }
+ DBG("%d: full_tx_reset" NL, dev->def->index);
- /* Check for a read error */
- if (stacr & EMAC_STACR_PHYE) {
- MDIO_DEBUG(("EMAC MDIO PHY error !\n"));
- return -1;
- }
+ emac_tx_disable(dev);
+ mal_disable_tx_channel(dev->mal, emacdata->mal_tx_chan);
+ emac_clean_tx_ring(dev);
+ dev->tx_cnt = dev->tx_slot = dev->ack_slot = 0;
+
+ emac_configure(dev);
- MDIO_DEBUG((" -> 0x%x\n", stacr >> 16));
+ mal_enable_tx_channel(dev->mal, emacdata->mal_tx_chan);
+ emac_tx_enable(dev);
+ emac_rx_enable(dev);
- return (stacr >> 16);
+ netif_wake_queue(ndev);
}
-void emac_phy_write(struct net_device *dev, int mii_id, int reg, int data)
+static int __emac_mdio_read(struct ocp_enet_private *dev, u8 id, u8 reg)
{
- int count;
- uint32_t stacr;
- struct ocp_enet_private *fep = dev->priv;
- emac_t *emacp = fep->emacp;
+ struct emac_regs *p = dev->emacp;
+ u32 r;
+ int n;
- MDIO_DEBUG(("%s phy_write, id: 0x%x, reg: 0x%x, data: 0x%x\n",
- dev->name, mii_id, reg, data));
+ DBG2("%d: mdio_read(%02x,%02x)" NL, dev->def->index, id, reg);
- /* Enable proper ZMII port */
- if (fep->zmii_dev)
- emac_enable_zmii_port(fep->zmii_dev, fep->zmii_input);
+ /* Enable proper MDIO port */
+ zmii_enable_mdio(dev->zmii_dev, dev->zmii_input);
- /* Use the EMAC that has the MDIO port */
- if (fep->mdio_dev) {
- dev = fep->mdio_dev;
- fep = dev->priv;
- emacp = fep->emacp;
+ /* Wait for management interface to become idle */
+ n = 10;
+ while (!emac_phy_done(in_be32(&p->stacr))) {
+ udelay(1);
+ if (!--n)
+ goto to;
}
- count = 0;
- while ((((stacr = in_be32(&emacp->em0stacr)) & EMAC_STACR_OC) == 0)
- && (count++ < MDIO_DELAY))
+ /* Issue read command */
+ out_be32(&p->stacr,
+ EMAC_STACR_BASE(emac_opb_mhz()) | EMAC_STACR_STAC_READ |
+ (reg & EMAC_STACR_PRA_MASK)
+ | ((id & EMAC_STACR_PCDA_MASK) << EMAC_STACR_PCDA_SHIFT)
+ | EMAC_STACR_START);
+
+ /* Wait for read to complete */
+ n = 100;
+ while (!emac_phy_done(r = in_be32(&p->stacr))) {
udelay(1);
- MDIO_DEBUG((" (count was %d)\n", count));
+ if (!--n)
+ goto to;
+ }
- if ((stacr & EMAC_STACR_OC) == 0) {
- printk(KERN_WARNING "%s: PHY write timeout #2!\n", dev->name);
- return;
+ if (unlikely(r & EMAC_STACR_PHYE)) {
+ DBG("%d: mdio_read(%02x, %02x) failed" NL, dev->def->index,
+ id, reg);
+ return -EREMOTEIO;
}
- /* Clear the speed bits and make a read request to the PHY */
+ r = ((r >> EMAC_STACR_PHYD_SHIFT) & EMAC_STACR_PHYD_MASK);
+ DBG2("%d: mdio_read -> %04x" NL, dev->def->index, r);
+ return r;
+ to:
+ DBG("%d: MII management interface timeout (read)" NL, dev->def->index);
+ return -ETIMEDOUT;
+}
- stacr = ((EMAC_STACR_WRITE | (reg & 0x1f)) & ~EMAC_STACR_CLK_100MHZ);
- stacr |= ((mii_id & 0x1f) << 5) | ((data & 0xffff) << 16);
+static void __emac_mdio_write(struct ocp_enet_private *dev, u8 id, u8 reg,
+ u16 val)
+{
+ struct emac_regs *p = dev->emacp;
+ int n;
+
+ DBG2("%d: mdio_write(%02x,%02x,%04x)" NL, dev->def->index, id, reg,
+ val);
- out_be32(&emacp->em0stacr, stacr);
+ /* Enable proper MDIO port */
+ zmii_enable_mdio(dev->zmii_dev, dev->zmii_input);
- count = 0;
- while ((((stacr = in_be32(&emacp->em0stacr)) & EMAC_STACR_OC) == 0)
- && (count++ < MDIO_DELAY))
+ /* Wait for management interface to be idle */
+ n = 10;
+ while (!emac_phy_done(in_be32(&p->stacr))) {
udelay(1);
- MDIO_DEBUG((" (count was %d)\n", count));
+ if (!--n)
+ goto to;
+ }
- if ((stacr & EMAC_STACR_OC) == 0)
- printk(KERN_WARNING "%s: PHY write timeout #2!\n", dev->name);
+ /* Issue write command */
+ out_be32(&p->stacr,
+ EMAC_STACR_BASE(emac_opb_mhz()) | EMAC_STACR_STAC_WRITE |
+ (reg & EMAC_STACR_PRA_MASK) |
+ ((id & EMAC_STACR_PCDA_MASK) << EMAC_STACR_PCDA_SHIFT) |
+ (val << EMAC_STACR_PHYD_SHIFT) | EMAC_STACR_START);
- /* Check for a write error */
- if ((stacr & EMAC_STACR_PHYE) != 0) {
- MDIO_DEBUG(("EMAC MDIO PHY error !\n"));
+ /* Wait for write to complete */
+ n = 100;
+ while (!emac_phy_done(in_be32(&p->stacr))) {
+ udelay(1);
+ if (!--n)
+ goto to;
}
+ return;
+ to:
+ DBG("%d: MII management interface timeout (write)" NL, dev->def->index);
}
-static void emac_txeob_dev(void *param, u32 chanmask)
+static int emac_mdio_read(struct net_device *ndev, int id, int reg)
{
- struct net_device *dev = param;
- struct ocp_enet_private *fep = dev->priv;
- unsigned long flags;
-
- spin_lock_irqsave(&fep->lock, flags);
-
- PKT_DEBUG(("emac_txeob_dev() entry, tx_cnt: %d\n", fep->tx_cnt));
-
- while (fep->tx_cnt &&
- !(fep->tx_desc[fep->ack_slot].ctrl & MAL_TX_CTRL_READY)) {
+ struct ocp_enet_private *dev = ndev->priv;
+ int res;
+
+ local_bh_disable();
+ res = __emac_mdio_read(dev->mdio_dev ? dev->mdio_dev : dev, (u8) id,
+ (u8) reg);
+ local_bh_enable();
+ return res;
+}
- if (fep->tx_desc[fep->ack_slot].ctrl & MAL_TX_CTRL_LAST) {
- /* Tell the system the transmit completed. */
- dma_unmap_single(&fep->ocpdev->dev,
- fep->tx_desc[fep->ack_slot].data_ptr,
- fep->tx_desc[fep->ack_slot].data_len,
- DMA_TO_DEVICE);
- dev_kfree_skb_irq(fep->tx_skb[fep->ack_slot]);
+static void emac_mdio_write(struct net_device *ndev, int id, int reg, int val)
+{
+ struct ocp_enet_private *dev = ndev->priv;
- if (fep->tx_desc[fep->ack_slot].ctrl &
- (EMAC_TX_ST_EC | EMAC_TX_ST_MC | EMAC_TX_ST_SC))
- fep->stats.collisions++;
- }
+ local_bh_disable();
+ __emac_mdio_write(dev->mdio_dev ? dev->mdio_dev : dev, (u8) id,
+ (u8) reg, (u16) val);
+ local_bh_enable();
+}
- fep->tx_skb[fep->ack_slot] = (struct sk_buff *)NULL;
- if (++fep->ack_slot == NUM_TX_BUFF)
- fep->ack_slot = 0;
+/* BHs disabled */
+static void emac_set_multicast_list(struct net_device *ndev)
+{
+ struct ocp_enet_private *dev = ndev->priv;
+ struct emac_regs *p = dev->emacp;
+ u32 rmr = emac_iff2rmr(ndev);
+
+ DBG("%d: multicast %08x" NL, dev->def->index, rmr);
+ BUG_ON(!netif_running(dev->ndev));
+
+ /* I decided to relax register access rules here to avoid
+ * full EMAC reset.
+ *
+ * There is a real problem with EMAC4 core if we use MWSW_001 bit
+ * in MR1 register and do a full EMAC reset.
+ * One TX BD status update is delayed and, after EMAC reset, it
+ * never happens, resulting in TX hung (it'll be recovered by TX
+ * timeout handler eventually, but this is just gross).
+ * So we either have to do full TX reset or try to cheat here :)
+ *
+ * The only required change is to RX mode register, so I *think* all
+ * we need is just to stop RX channel. This seems to work on all
+ * tested SoCs. --ebs
+ */
+ emac_rx_disable(dev);
+ if (rmr & EMAC_RMR_MAE)
+ emac_hash_mc(dev);
+ out_be32(&p->rmr, rmr);
+ emac_rx_enable(dev);
+}
- fep->tx_cnt--;
+/* BHs disabled */
+static int emac_resize_rx_ring(struct ocp_enet_private *dev, int new_mtu)
+{
+ struct ocp_func_emac_data *emacdata = dev->def->additions;
+ int rx_sync_size = emac_rx_sync_size(new_mtu);
+ int rx_skb_size = emac_rx_skb_size(new_mtu);
+ int i, ret = 0;
+
+ emac_rx_disable(dev);
+ mal_disable_rx_channel(dev->mal, emacdata->mal_rx_chan);
+
+ if (dev->rx_sg_skb) {
+ ++dev->estats.rx_dropped_resize;
+ dev_kfree_skb(dev->rx_sg_skb);
+ dev->rx_sg_skb = NULL;
}
- if (fep->tx_cnt < NUM_TX_BUFF)
- netif_wake_queue(dev);
- PKT_DEBUG(("emac_txeob_dev() exit, tx_cnt: %d\n", fep->tx_cnt));
+ /* Make a first pass over RX ring and mark BDs ready, dropping
+ * non-processed packets on the way. We need this as a separate pass
+ * to simplify error recovery in the case of allocation failure later.
+ */
+ for (i = 0; i < NUM_RX_BUFF; ++i) {
+ if (dev->rx_desc[i].ctrl & MAL_RX_CTRL_FIRST)
+ ++dev->estats.rx_dropped_resize;
- spin_unlock_irqrestore(&fep->lock, flags);
-}
+ dev->rx_desc[i].data_len = 0;
+ dev->rx_desc[i].ctrl = MAL_RX_CTRL_EMPTY |
+ (i == (NUM_RX_BUFF - 1) ? MAL_RX_CTRL_WRAP : 0);
+ }
-/*
- Fill/Re-fill the rx chain with valid ctrl/ptrs.
- This function will fill from rx_slot up to the parm end.
- So to completely fill the chain pre-set rx_slot to 0 and
- pass in an end of 0.
- */
-static void emac_rx_fill(struct net_device *dev, int end)
-{
- int i;
- struct ocp_enet_private *fep = dev->priv;
-
- i = fep->rx_slot;
- do {
- /* We don't want the 16 bytes skb_reserve done by dev_alloc_skb,
- * it breaks our cache line alignement. However, we still allocate
- * +16 so that we end up allocating the exact same size as
- * dev_alloc_skb() would do.
- * Also, because of the skb_res, the max DMA size we give to EMAC
- * is slighly wrong, causing it to potentially DMA 2 more bytes
- * from a broken/oversized packet. These 16 bytes will take care
- * that we don't walk on somebody else toes with that.
- */
- fep->rx_skb[i] =
- alloc_skb(fep->rx_buffer_size + 16, GFP_ATOMIC);
-
- if (fep->rx_skb[i] == NULL) {
- /* Keep rx_slot here, the next time clean/fill is called
- * we will try again before the MAL wraps back here
- * If the MAL tries to use this descriptor with
- * the EMPTY bit off it will cause the
- * rxde interrupt. That is where we will
- * try again to allocate an sk_buff.
- */
- break;
+ /* Reallocate RX ring only if bigger skb buffers are required */
+ if (rx_skb_size <= dev->rx_skb_size)
+ goto skip;
+ /* Second pass, allocate new skbs */
+ for (i = 0; i < NUM_RX_BUFF; ++i) {
+ struct sk_buff *skb = alloc_skb(rx_skb_size, GFP_ATOMIC);
+ if (!skb) {
+ ret = -ENOMEM;
+ goto oom;
}
- if (skb_res)
- skb_reserve(fep->rx_skb[i], skb_res);
+ BUG_ON(!dev->rx_skb[i]);
+ dev_kfree_skb(dev->rx_skb[i]);
- /* We must NOT dma_map_single the cache line right after the
- * buffer, so we must crop our sync size to account for the
- * reserved space
- */
- fep->rx_desc[i].data_ptr =
- (unsigned char *)dma_map_single(&fep->ocpdev->dev,
- (void *)fep->rx_skb[i]->
- data,
- fep->rx_buffer_size -
- skb_res, DMA_FROM_DEVICE);
-
- /*
- * Some 4xx implementations use the previously
- * reserved bits in data_len to encode the MS
- * 4-bits of a 36-bit physical address (ERPN)
- * This must be initialized.
- */
- fep->rx_desc[i].data_len = 0;
- fep->rx_desc[i].ctrl = MAL_RX_CTRL_EMPTY | MAL_RX_CTRL_INTR |
- (i == (NUM_RX_BUFF - 1) ? MAL_RX_CTRL_WRAP : 0);
+ skb_reserve(skb, EMAC_RX_SKB_HEADROOM + 2);
+ dev->rx_desc[i].data_ptr =
+ dma_map_single(dev->ldev, skb->data - 2, rx_sync_size,
+ DMA_FROM_DEVICE) + 2;
+ dev->rx_skb[i] = skb;
+ }
+ skip:
+ /* Check if we need to change "Jumbo" bit in MR1 */
+ if ((new_mtu > ETH_DATA_LEN) ^ (dev->ndev->mtu > ETH_DATA_LEN)) {
+ /* This is to prevent starting RX channel in emac_rx_enable() */
+ dev->commac.rx_stopped = 1;
+
+ dev->ndev->mtu = new_mtu;
+ emac_full_tx_reset(dev->ndev);
+ }
- } while ((i = (i + 1) % NUM_RX_BUFF) != end);
+ mal_set_rcbs(dev->mal, emacdata->mal_rx_chan, emac_rx_size(new_mtu));
+ oom:
+ /* Restart RX */
+ dev->commac.rx_stopped = dev->rx_slot = 0;
+ mal_enable_rx_channel(dev->mal, emacdata->mal_rx_chan);
+ emac_rx_enable(dev);
- fep->rx_slot = i;
+ return ret;
}
-static void
-emac_rx_csum(struct net_device *dev, unsigned short ctrl, struct sk_buff *skb)
+/* Process ctx, rtnl_lock semaphore */
+static int emac_change_mtu(struct net_device *ndev, int new_mtu)
{
- struct ocp_enet_private *fep = dev->priv;
+ struct ocp_enet_private *dev = ndev->priv;
+ int ret = 0;
- /* Exit if interface has no TAH engine */
- if (!fep->tah_dev) {
- skb->ip_summed = CHECKSUM_NONE;
- return;
- }
+ if (new_mtu < EMAC_MIN_MTU || new_mtu > EMAC_MAX_MTU)
+ return -EINVAL;
- /* Check for TCP/UDP/IP csum error */
- if (ctrl & EMAC_CSUM_VER_ERROR) {
- /* Let the stack verify checksum errors */
- skb->ip_summed = CHECKSUM_NONE;
-/* adapter->hw_csum_err++; */
- } else {
- /* Csum is good */
- skb->ip_summed = CHECKSUM_UNNECESSARY;
-/* adapter->hw_csum_good++; */
- }
-}
+ DBG("%d: change_mtu(%d)" NL, dev->def->index, new_mtu);
-static int emac_rx_clean(struct net_device *dev)
-{
- int i, b, bnum = 0, buf[6];
- int error, frame_length;
- struct ocp_enet_private *fep = dev->priv;
- unsigned short ctrl;
+ local_bh_disable();
+ if (netif_running(ndev)) {
+ /* Check if we really need to reinitalize RX ring */
+ if (emac_rx_skb_size(ndev->mtu) != emac_rx_skb_size(new_mtu))
+ ret = emac_resize_rx_ring(dev, new_mtu);
+ }
- i = fep->rx_slot;
+ if (!ret) {
+ ndev->mtu = new_mtu;
+ dev->rx_skb_size = emac_rx_skb_size(new_mtu);
+ dev->rx_sync_size = emac_rx_sync_size(new_mtu);
+ }
+ local_bh_enable();
- PKT_DEBUG(("emac_rx_clean() entry, rx_slot: %d\n", fep->rx_slot));
+ return ret;
+}
- do {
- if (fep->rx_skb[i] == NULL)
- continue; /*we have already handled the packet but haved failed to alloc */
- /*
- since rx_desc is in uncached mem we don't keep reading it directly
- we pull out a local copy of ctrl and do the checks on the copy.
- */
- ctrl = fep->rx_desc[i].ctrl;
- if (ctrl & MAL_RX_CTRL_EMPTY)
- break; /*we don't have any more ready packets */
-
- if (EMAC_IS_BAD_RX_PACKET(ctrl)) {
- fep->stats.rx_errors++;
- fep->stats.rx_dropped++;
-
- if (ctrl & EMAC_RX_ST_OE)
- fep->stats.rx_fifo_errors++;
- if (ctrl & EMAC_RX_ST_AE)
- fep->stats.rx_frame_errors++;
- if (ctrl & EMAC_RX_ST_BFCS)
- fep->stats.rx_crc_errors++;
- if (ctrl & (EMAC_RX_ST_RP | EMAC_RX_ST_PTL |
- EMAC_RX_ST_ORE | EMAC_RX_ST_IRE))
- fep->stats.rx_length_errors++;
- } else {
- if ((ctrl & (MAL_RX_CTRL_FIRST | MAL_RX_CTRL_LAST)) ==
- (MAL_RX_CTRL_FIRST | MAL_RX_CTRL_LAST)) {
- /* Single descriptor packet */
- emac_rx_csum(dev, ctrl, fep->rx_skb[i]);
- /* Send the skb up the chain. */
- frame_length = fep->rx_desc[i].data_len - 4;
- skb_put(fep->rx_skb[i], frame_length);
- fep->rx_skb[i]->dev = dev;
- fep->rx_skb[i]->protocol =
- eth_type_trans(fep->rx_skb[i], dev);
- error = netif_rx(fep->rx_skb[i]);
-
- if ((error == NET_RX_DROP) ||
- (error == NET_RX_BAD)) {
- fep->stats.rx_dropped++;
- } else {
- fep->stats.rx_packets++;
- fep->stats.rx_bytes += frame_length;
- }
- fep->rx_skb[i] = NULL;
- } else {
- /* Multiple descriptor packet */
- if (ctrl & MAL_RX_CTRL_FIRST) {
- if (fep->rx_desc[(i + 1) % NUM_RX_BUFF].
- ctrl & MAL_RX_CTRL_EMPTY)
- break;
- bnum = 0;
- buf[bnum] = i;
- ++bnum;
- continue;
- }
- if (((ctrl & MAL_RX_CTRL_FIRST) !=
- MAL_RX_CTRL_FIRST) &&
- ((ctrl & MAL_RX_CTRL_LAST) !=
- MAL_RX_CTRL_LAST)) {
- if (fep->rx_desc[(i + 1) %
- NUM_RX_BUFF].ctrl &
- MAL_RX_CTRL_EMPTY) {
- i = buf[0];
- break;
- }
- buf[bnum] = i;
- ++bnum;
- continue;
- }
- if (ctrl & MAL_RX_CTRL_LAST) {
- buf[bnum] = i;
- ++bnum;
- skb_put(fep->rx_skb[buf[0]],
- fep->rx_desc[buf[0]].data_len);
- for (b = 1; b < bnum; b++) {
- /*
- * MAL is braindead, we need
- * to copy the remainder
- * of the packet from the
- * latter descriptor buffers
- * to the first skb. Then
- * dispose of the source
- * skbs.
- *
- * Once the stack is fixed
- * to handle frags on most
- * protocols we can generate
- * a fragmented skb with
- * no copies.
- */
- memcpy(fep->rx_skb[buf[0]]->
- data +
- fep->rx_skb[buf[0]]->len,
- fep->rx_skb[buf[b]]->
- data,
- fep->rx_desc[buf[b]].
- data_len);
- skb_put(fep->rx_skb[buf[0]],
- fep->rx_desc[buf[b]].
- data_len);
- dma_unmap_single(&fep->ocpdev->
- dev,
- fep->
- rx_desc[buf
- [b]].
- data_ptr,
- fep->
- rx_desc[buf
- [b]].
- data_len,
- DMA_FROM_DEVICE);
- dev_kfree_skb(fep->
- rx_skb[buf[b]]);
- }
- emac_rx_csum(dev, ctrl,
- fep->rx_skb[buf[0]]);
-
- fep->rx_skb[buf[0]]->dev = dev;
- fep->rx_skb[buf[0]]->protocol =
- eth_type_trans(fep->rx_skb[buf[0]],
- dev);
- error = netif_rx(fep->rx_skb[buf[0]]);
-
- if ((error == NET_RX_DROP)
- || (error == NET_RX_BAD)) {
- fep->stats.rx_dropped++;
- } else {
- fep->stats.rx_packets++;
- fep->stats.rx_bytes +=
- fep->rx_skb[buf[0]]->len;
- }
- for (b = 0; b < bnum; b++)
- fep->rx_skb[buf[b]] = NULL;
- }
- }
+static void emac_clean_tx_ring(struct ocp_enet_private *dev)
+{
+ int i;
+ for (i = 0; i < NUM_TX_BUFF; ++i) {
+ if (dev->tx_skb[i]) {
+ dev_kfree_skb(dev->tx_skb[i]);
+ dev->tx_skb[i] = NULL;
+ if (dev->tx_desc[i].ctrl & MAL_TX_CTRL_READY)
+ ++dev->estats.tx_dropped;
}
- } while ((i = (i + 1) % NUM_RX_BUFF) != fep->rx_slot);
-
- PKT_DEBUG(("emac_rx_clean() exit, rx_slot: %d\n", fep->rx_slot));
-
- return i;
+ dev->tx_desc[i].ctrl = 0;
+ dev->tx_desc[i].data_ptr = 0;
+ }
}
-static void emac_rxeob_dev(void *param, u32 chanmask)
+static void emac_clean_rx_ring(struct ocp_enet_private *dev)
{
- struct net_device *dev = param;
- struct ocp_enet_private *fep = dev->priv;
- unsigned long flags;
- int n;
+ int i;
+ for (i = 0; i < NUM_RX_BUFF; ++i)
+ if (dev->rx_skb[i]) {
+ dev->rx_desc[i].ctrl = 0;
+ dev_kfree_skb(dev->rx_skb[i]);
+ dev->rx_skb[i] = NULL;
+ dev->rx_desc[i].data_ptr = 0;
+ }
- spin_lock_irqsave(&fep->lock, flags);
- if ((n = emac_rx_clean(dev)) != fep->rx_slot)
- emac_rx_fill(dev, n);
- spin_unlock_irqrestore(&fep->lock, flags);
+ if (dev->rx_sg_skb) {
+ dev_kfree_skb(dev->rx_sg_skb);
+ dev->rx_sg_skb = NULL;
+ }
}
-/*
- * This interrupt should never occurr, we don't program
- * the MAL for contiunous mode.
- */
-static void emac_txde_dev(void *param, u32 chanmask)
+static inline int emac_alloc_rx_skb(struct ocp_enet_private *dev, int slot,
+ int flags)
{
- struct net_device *dev = param;
- struct ocp_enet_private *fep = dev->priv;
+ struct sk_buff *skb = alloc_skb(dev->rx_skb_size, flags);
+ if (unlikely(!skb))
+ return -ENOMEM;
- printk(KERN_WARNING "%s: transmit descriptor error\n", dev->name);
+ dev->rx_skb[slot] = skb;
+ dev->rx_desc[slot].data_len = 0;
- emac_mac_dump(dev);
- emac_mal_dump(dev);
+ skb_reserve(skb, EMAC_RX_SKB_HEADROOM + 2);
+ dev->rx_desc[slot].data_ptr =
+ dma_map_single(dev->ldev, skb->data - 2, dev->rx_sync_size,
+ DMA_FROM_DEVICE) + 2;
+ barrier();
+ dev->rx_desc[slot].ctrl = MAL_RX_CTRL_EMPTY |
+ (slot == (NUM_RX_BUFF - 1) ? MAL_RX_CTRL_WRAP : 0);
- /* Reenable the transmit channel */
- mal_enable_tx_channels(fep->mal, fep->commac.tx_chan_mask);
+ return 0;
}
-/*
- * This interrupt should be very rare at best. This occurs when
- * the hardware has a problem with the receive descriptors. The manual
- * states that it occurs when the hardware cannot the receive descriptor
- * empty bit is not set. The recovery mechanism will be to
- * traverse through the descriptors, handle any that are marked to be
- * handled and reinitialize each along the way. At that point the driver
- * will be restarted.
- */
-static void emac_rxde_dev(void *param, u32 chanmask)
+static void emac_print_link_status(struct ocp_enet_private *dev)
{
- struct net_device *dev = param;
- struct ocp_enet_private *fep = dev->priv;
- unsigned long flags;
-
- if (net_ratelimit()) {
- printk(KERN_WARNING "%s: receive descriptor error\n",
- fep->ndev->name);
+ if (netif_carrier_ok(dev->ndev))
+ printk(KERN_INFO "%s: link is up, %d %s%s\n",
+ dev->ndev->name, dev->phy.speed,
+ dev->phy.duplex == DUPLEX_FULL ? "FDX" : "HDX",
+ dev->phy.pause ? ", pause enabled" :
+ dev->phy.asym_pause ? ", assymetric pause enabled" : "");
+ else
+ printk(KERN_INFO "%s: link is down\n", dev->ndev->name);
+}
- emac_mac_dump(dev);
- emac_mal_dump(dev);
- emac_desc_dump(dev);
+/* Process ctx, rtnl_lock semaphore */
+static int emac_open(struct net_device *ndev)
+{
+ struct ocp_enet_private *dev = ndev->priv;
+ struct ocp_func_emac_data *emacdata = dev->def->additions;
+ int err, i;
+
+ DBG("%d: open" NL, dev->def->index);
+
+ /* Setup error IRQ handler */
+ err = request_irq(dev->def->irq, emac_irq, 0, "EMAC", dev);
+ if (err) {
+ printk(KERN_ERR "%s: failed to request IRQ %d\n",
+ ndev->name, dev->def->irq);
+ return err;
}
- /* Disable RX channel */
- spin_lock_irqsave(&fep->lock, flags);
- mal_disable_rx_channels(fep->mal, fep->commac.rx_chan_mask);
-
- /* For now, charge the error against all emacs */
- fep->stats.rx_errors++;
-
- /* so do we have any good packets still? */
- emac_rx_clean(dev);
-
- /* When the interface is restarted it resets processing to the
- * first descriptor in the table.
- */
-
- fep->rx_slot = 0;
- emac_rx_fill(dev, 0);
+ /* Allocate RX ring */
+ for (i = 0; i < NUM_RX_BUFF; ++i)
+ if (emac_alloc_rx_skb(dev, i, GFP_KERNEL)) {
+ printk(KERN_ERR "%s: failed to allocate RX ring\n",
+ ndev->name);
+ goto oom;
+ }
- set_mal_dcrn(fep->mal, DCRN_MALRXEOBISR, fep->commac.rx_chan_mask);
- set_mal_dcrn(fep->mal, DCRN_MALRXDEIR, fep->commac.rx_chan_mask);
+ local_bh_disable();
+ dev->tx_cnt = dev->tx_slot = dev->ack_slot = dev->rx_slot =
+ dev->commac.rx_stopped = 0;
+ dev->rx_sg_skb = NULL;
+
+ if (dev->phy.address >= 0) {
+ int link_poll_interval;
+ if (dev->phy.def->ops->poll_link(&dev->phy)) {
+ dev->phy.def->ops->read_link(&dev->phy);
+ EMAC_RX_CLK_DEFAULT(dev->def->index);
+ netif_carrier_on(dev->ndev);
+ link_poll_interval = PHY_POLL_LINK_ON;
+ } else {
+ EMAC_RX_CLK_TX(dev->def->index);
+ netif_carrier_off(dev->ndev);
+ link_poll_interval = PHY_POLL_LINK_OFF;
+ }
+ mod_timer(&dev->link_timer, jiffies + link_poll_interval);
+ emac_print_link_status(dev);
+ } else
+ netif_carrier_on(dev->ndev);
+
+ emac_configure(dev);
+ mal_poll_add(dev->mal, &dev->commac);
+ mal_enable_tx_channel(dev->mal, emacdata->mal_tx_chan);
+ mal_set_rcbs(dev->mal, emacdata->mal_rx_chan, emac_rx_size(ndev->mtu));
+ mal_enable_rx_channel(dev->mal, emacdata->mal_rx_chan);
+ emac_tx_enable(dev);
+ emac_rx_enable(dev);
+ netif_start_queue(ndev);
+ local_bh_enable();
- /* Reenable the receive channels */
- mal_enable_rx_channels(fep->mal, fep->commac.rx_chan_mask);
- spin_unlock_irqrestore(&fep->lock, flags);
+ return 0;
+ oom:
+ emac_clean_rx_ring(dev);
+ free_irq(dev->def->irq, dev);
+ return -ENOMEM;
}
-static irqreturn_t
-emac_mac_irq(int irq, void *dev_instance, struct pt_regs *regs)
+/* BHs disabled */
+static int emac_link_differs(struct ocp_enet_private *dev)
{
- struct net_device *dev = dev_instance;
- struct ocp_enet_private *fep = dev->priv;
- emac_t *emacp = fep->emacp;
- unsigned long tmp_em0isr;
+ u32 r = in_be32(&dev->emacp->mr1);
- /* EMAC interrupt */
- tmp_em0isr = in_be32(&emacp->em0isr);
- if (tmp_em0isr & (EMAC_ISR_TE0 | EMAC_ISR_TE1)) {
- /* This error is a hard transmit error - could retransmit */
- fep->stats.tx_errors++;
+ int duplex = r & EMAC_MR1_FDE ? DUPLEX_FULL : DUPLEX_HALF;
+ int speed, pause, asym_pause;
- /* Reenable the transmit channel */
- mal_enable_tx_channels(fep->mal, fep->commac.tx_chan_mask);
+ if (r & (EMAC_MR1_MF_1000 | EMAC_MR1_MF_1000GPCS))
+ speed = SPEED_1000;
+ else if (r & EMAC_MR1_MF_100)
+ speed = SPEED_100;
+ else
+ speed = SPEED_10;
- } else {
- fep->stats.rx_errors++;
+ switch (r & (EMAC_MR1_EIFC | EMAC_MR1_APP)) {
+ case (EMAC_MR1_EIFC | EMAC_MR1_APP):
+ pause = 1;
+ asym_pause = 0;
+ break;
+ case EMAC_MR1_APP:
+ pause = 0;
+ asym_pause = 1;
+ break;
+ default:
+ pause = asym_pause = 0;
}
-
- if (tmp_em0isr & EMAC_ISR_RP)
- fep->stats.rx_length_errors++;
- if (tmp_em0isr & EMAC_ISR_ALE)
- fep->stats.rx_frame_errors++;
- if (tmp_em0isr & EMAC_ISR_BFCS)
- fep->stats.rx_crc_errors++;
- if (tmp_em0isr & EMAC_ISR_PTLE)
- fep->stats.rx_length_errors++;
- if (tmp_em0isr & EMAC_ISR_ORE)
- fep->stats.rx_length_errors++;
- if (tmp_em0isr & EMAC_ISR_TE0)
- fep->stats.tx_aborted_errors++;
-
- emac_err_dump(dev, tmp_em0isr);
-
- out_be32(&emacp->em0isr, tmp_em0isr);
-
- return IRQ_HANDLED;
+ return speed != dev->phy.speed || duplex != dev->phy.duplex ||
+ pause != dev->phy.pause || asym_pause != dev->phy.asym_pause;
}
-static int emac_start_xmit(struct sk_buff *skb, struct net_device *dev)
+/* BHs disabled */
+static void emac_link_timer(unsigned long data)
{
- unsigned short ctrl;
- unsigned long flags;
- struct ocp_enet_private *fep = dev->priv;
- emac_t *emacp = fep->emacp;
- int len = skb->len;
- unsigned int offset = 0, size, f, tx_slot_first;
- unsigned int nr_frags = skb_shinfo(skb)->nr_frags;
+ struct ocp_enet_private *dev = (struct ocp_enet_private *)data;
+ int link_poll_interval;
- spin_lock_irqsave(&fep->lock, flags);
+ DBG2("%d: link timer" NL, dev->def->index);
- len -= skb->data_len;
+ if (dev->phy.def->ops->poll_link(&dev->phy)) {
+ if (!netif_carrier_ok(dev->ndev)) {
+ EMAC_RX_CLK_DEFAULT(dev->def->index);
- if ((fep->tx_cnt + nr_frags + len / DESC_BUF_SIZE + 1) > NUM_TX_BUFF) {
- PKT_DEBUG(("emac_start_xmit() stopping queue\n"));
- netif_stop_queue(dev);
- spin_unlock_irqrestore(&fep->lock, flags);
- return -EBUSY;
- }
-
- tx_slot_first = fep->tx_slot;
+ /* Get new link parameters */
+ dev->phy.def->ops->read_link(&dev->phy);
- while (len) {
- size = min(len, DESC_BUF_SIZE);
+ if (dev->tah_dev || emac_link_differs(dev))
+ emac_full_tx_reset(dev->ndev);
- fep->tx_desc[fep->tx_slot].data_len = (short)size;
- fep->tx_desc[fep->tx_slot].data_ptr =
- (unsigned char *)dma_map_single(&fep->ocpdev->dev,
- (void *)((unsigned int)skb->
- data + offset),
- size, DMA_TO_DEVICE);
-
- ctrl = EMAC_TX_CTRL_DFLT;
- if (fep->tx_slot != tx_slot_first)
- ctrl |= MAL_TX_CTRL_READY;
- if ((NUM_TX_BUFF - 1) == fep->tx_slot)
- ctrl |= MAL_TX_CTRL_WRAP;
- if (!nr_frags && (len == size)) {
- ctrl |= MAL_TX_CTRL_LAST;
- fep->tx_skb[fep->tx_slot] = skb;
+ netif_carrier_on(dev->ndev);
+ emac_print_link_status(dev);
+ }
+ link_poll_interval = PHY_POLL_LINK_ON;
+ } else {
+ if (netif_carrier_ok(dev->ndev)) {
+ EMAC_RX_CLK_TX(dev->def->index);
+#if defined(CONFIG_IBM_EMAC_PHY_RX_CLK_FIX)
+ emac_reinitialize(dev);
+#endif
+ netif_carrier_off(dev->ndev);
+ emac_print_link_status(dev);
}
- if (skb->ip_summed == CHECKSUM_HW)
- ctrl |= EMAC_TX_CTRL_TAH_CSUM;
- fep->tx_desc[fep->tx_slot].ctrl = ctrl;
+ /* Retry reset if the previous attempt failed.
+ * This is needed mostly for CONFIG_IBM_EMAC_PHY_RX_CLK_FIX
+ * case, but I left it here because it shouldn't trigger for
+ * sane PHYs anyway.
+ */
+ if (unlikely(dev->reset_failed))
+ emac_reinitialize(dev);
- len -= size;
- offset += size;
+ link_poll_interval = PHY_POLL_LINK_OFF;
+ }
+ mod_timer(&dev->link_timer, jiffies + link_poll_interval);
+}
- /* Bump tx count */
- if (++fep->tx_cnt == NUM_TX_BUFF)
- netif_stop_queue(dev);
+/* BHs disabled */
+static void emac_force_link_update(struct ocp_enet_private *dev)
+{
+ netif_carrier_off(dev->ndev);
+ if (timer_pending(&dev->link_timer))
+ mod_timer(&dev->link_timer, jiffies + PHY_POLL_LINK_OFF);
+}
- /* Next descriptor */
- if (++fep->tx_slot == NUM_TX_BUFF)
- fep->tx_slot = 0;
- }
+/* Process ctx, rtnl_lock semaphore */
+static int emac_close(struct net_device *ndev)
+{
+ struct ocp_enet_private *dev = ndev->priv;
+ struct ocp_func_emac_data *emacdata = dev->def->additions;
- for (f = 0; f < nr_frags; f++) {
- struct skb_frag_struct *frag;
+ DBG("%d: close" NL, dev->def->index);
- frag = &skb_shinfo(skb)->frags[f];
- len = frag->size;
- offset = 0;
-
- while (len) {
- size = min(len, DESC_BUF_SIZE);
-
- dma_map_page(&fep->ocpdev->dev,
- frag->page,
- frag->page_offset + offset,
- size, DMA_TO_DEVICE);
-
- ctrl = EMAC_TX_CTRL_DFLT | MAL_TX_CTRL_READY;
- if ((NUM_TX_BUFF - 1) == fep->tx_slot)
- ctrl |= MAL_TX_CTRL_WRAP;
- if ((f == (nr_frags - 1)) && (len == size)) {
- ctrl |= MAL_TX_CTRL_LAST;
- fep->tx_skb[fep->tx_slot] = skb;
- }
+ local_bh_disable();
- if (skb->ip_summed == CHECKSUM_HW)
- ctrl |= EMAC_TX_CTRL_TAH_CSUM;
+ if (dev->phy.address >= 0)
+ del_timer_sync(&dev->link_timer);
- fep->tx_desc[fep->tx_slot].data_len = (short)size;
- fep->tx_desc[fep->tx_slot].data_ptr =
- (char *)((page_to_pfn(frag->page) << PAGE_SHIFT) +
- frag->page_offset + offset);
- fep->tx_desc[fep->tx_slot].ctrl = ctrl;
+ netif_stop_queue(ndev);
+ emac_rx_disable(dev);
+ emac_tx_disable(dev);
+ mal_disable_rx_channel(dev->mal, emacdata->mal_rx_chan);
+ mal_disable_tx_channel(dev->mal, emacdata->mal_tx_chan);
+ mal_poll_del(dev->mal, &dev->commac);
+ local_bh_enable();
- len -= size;
- offset += size;
+ emac_clean_tx_ring(dev);
+ emac_clean_rx_ring(dev);
+ free_irq(dev->def->irq, dev);
- /* Bump tx count */
- if (++fep->tx_cnt == NUM_TX_BUFF)
- netif_stop_queue(dev);
+ return 0;
+}
- /* Next descriptor */
- if (++fep->tx_slot == NUM_TX_BUFF)
- fep->tx_slot = 0;
- }
+static inline u16 emac_tx_csum(struct ocp_enet_private *dev,
+ struct sk_buff *skb)
+{
+#if defined(CONFIG_IBM_EMAC_TAH)
+ if (skb->ip_summed == CHECKSUM_HW) {
+ ++dev->stats.tx_packets_csum;
+ return EMAC_TX_CTRL_TAH_CSUM;
}
+#endif
+ return 0;
+}
- /*
- * Deferred set READY on first descriptor of packet to
- * avoid TX MAL race.
- */
- fep->tx_desc[tx_slot_first].ctrl |= MAL_TX_CTRL_READY;
-
- /* Send the packet out. */
- out_be32(&emacp->em0tmr0, EMAC_TMR0_XMIT);
+static inline int emac_xmit_finish(struct ocp_enet_private *dev, int len)
+{
+ struct emac_regs *p = dev->emacp;
+ struct net_device *ndev = dev->ndev;
- fep->stats.tx_packets++;
- fep->stats.tx_bytes += skb->len;
+ /* Send the packet out */
+ out_be32(&p->tmr0, EMAC_TMR0_XMIT);
- PKT_DEBUG(("emac_start_xmit() exitn"));
+ if (unlikely(++dev->tx_cnt == NUM_TX_BUFF)) {
+ netif_stop_queue(ndev);
+ DBG2("%d: stopped TX queue" NL, dev->def->index);
+ }
- spin_unlock_irqrestore(&fep->lock, flags);
+ ndev->trans_start = jiffies;
+ ++dev->stats.tx_packets;
+ dev->stats.tx_bytes += len;
return 0;
}
-static int emac_adjust_to_link(struct ocp_enet_private *fep)
+/* BHs disabled */
+static int emac_start_xmit(struct sk_buff *skb, struct net_device *ndev)
{
- emac_t *emacp = fep->emacp;
- unsigned long mode_reg;
- int full_duplex, speed;
-
- full_duplex = 0;
- speed = SPEED_10;
+ struct ocp_enet_private *dev = ndev->priv;
+ unsigned int len = skb->len;
+ int slot;
- /* set mode register 1 defaults */
- mode_reg = EMAC_M1_DEFAULT;
+ u16 ctrl = EMAC_TX_CTRL_GFCS | EMAC_TX_CTRL_GP | MAL_TX_CTRL_READY |
+ MAL_TX_CTRL_LAST | emac_tx_csum(dev, skb);
- /* Read link mode on PHY */
- if (fep->phy_mii.def->ops->read_link(&fep->phy_mii) == 0) {
- /* If an error occurred, we don't deal with it yet */
- full_duplex = (fep->phy_mii.duplex == DUPLEX_FULL);
- speed = fep->phy_mii.speed;
+ slot = dev->tx_slot++;
+ if (dev->tx_slot == NUM_TX_BUFF) {
+ dev->tx_slot = 0;
+ ctrl |= MAL_TX_CTRL_WRAP;
}
+ DBG2("%d: xmit(%u) %d" NL, dev->def->index, len, slot);
- /* set speed (default is 10Mb) */
- switch (speed) {
- case SPEED_1000:
- mode_reg |= EMAC_M1_RFS_16K;
- if (fep->rgmii_dev) {
- struct ibm_ocp_rgmii *rgmii = RGMII_PRIV(fep->rgmii_dev);
-
- if ((rgmii->mode[fep->rgmii_input] == RTBI)
- || (rgmii->mode[fep->rgmii_input] == TBI))
- mode_reg |= EMAC_M1_MF_1000GPCS;
- else
- mode_reg |= EMAC_M1_MF_1000MBPS;
-
- emac_rgmii_port_speed(fep->rgmii_dev, fep->rgmii_input,
- 1000);
- }
- break;
- case SPEED_100:
- mode_reg |= EMAC_M1_MF_100MBPS | EMAC_M1_RFS_4K;
- if (fep->rgmii_dev)
- emac_rgmii_port_speed(fep->rgmii_dev, fep->rgmii_input,
- 100);
- if (fep->zmii_dev)
- emac_zmii_port_speed(fep->zmii_dev, fep->zmii_input,
- 100);
- break;
- case SPEED_10:
- default:
- mode_reg = (mode_reg & ~EMAC_M1_MF_100MBPS) | EMAC_M1_RFS_4K;
- if (fep->rgmii_dev)
- emac_rgmii_port_speed(fep->rgmii_dev, fep->rgmii_input,
- 10);
- if (fep->zmii_dev)
- emac_zmii_port_speed(fep->zmii_dev, fep->zmii_input,
- 10);
- }
-
- if (full_duplex)
- mode_reg |= EMAC_M1_FDE | EMAC_M1_EIFC | EMAC_M1_IST;
- else
- mode_reg &= ~(EMAC_M1_FDE | EMAC_M1_EIFC | EMAC_M1_ILE);
-
- LINK_DEBUG(("%s: adjust to link, speed: %d, duplex: %d, opened: %d\n",
- fep->ndev->name, speed, full_duplex, fep->opened));
+ dev->tx_skb[slot] = skb;
+ dev->tx_desc[slot].data_ptr = dma_map_single(dev->ldev, skb->data, len,
+ DMA_TO_DEVICE);
+ dev->tx_desc[slot].data_len = (u16) len;
+ barrier();
+ dev->tx_desc[slot].ctrl = ctrl;
- printk(KERN_INFO "%s: Speed: %d, %s duplex.\n",
- fep->ndev->name, speed, full_duplex ? "Full" : "Half");
- if (fep->opened)
- out_be32(&emacp->em0mr1, mode_reg);
-
- return 0;
+ return emac_xmit_finish(dev, len);
}
-static int emac_set_mac_address(struct net_device *ndev, void *p)
+#if defined(CONFIG_IBM_EMAC_TAH)
+static inline int emac_xmit_split(struct ocp_enet_private *dev, int slot,
+ u32 pd, int len, int last, u16 base_ctrl)
{
- struct ocp_enet_private *fep = ndev->priv;
- emac_t *emacp = fep->emacp;
- struct sockaddr *addr = p;
+ while (1) {
+ u16 ctrl = base_ctrl;
+ int chunk = min(len, MAL_MAX_TX_SIZE);
+ len -= chunk;
- if (!is_valid_ether_addr(addr->sa_data))
- return -EADDRNOTAVAIL;
+ slot = (slot + 1) % NUM_TX_BUFF;
- memcpy(ndev->dev_addr, addr->sa_data, ndev->addr_len);
+ if (last && !len)
+ ctrl |= MAL_TX_CTRL_LAST;
+ if (slot == NUM_TX_BUFF - 1)
+ ctrl |= MAL_TX_CTRL_WRAP;
- /* set the high address */
- out_be32(&emacp->em0iahr,
- (fep->ndev->dev_addr[0] << 8) | fep->ndev->dev_addr[1]);
+ dev->tx_skb[slot] = NULL;
+ dev->tx_desc[slot].data_ptr = pd;
+ dev->tx_desc[slot].data_len = (u16) chunk;
+ dev->tx_desc[slot].ctrl = ctrl;
+ ++dev->tx_cnt;
- /* set the low address */
- out_be32(&emacp->em0ialr,
- (fep->ndev->dev_addr[2] << 24) | (fep->ndev->dev_addr[3] << 16)
- | (fep->ndev->dev_addr[4] << 8) | fep->ndev->dev_addr[5]);
+ if (!len)
+ break;
- return 0;
+ pd += chunk;
+ }
+ return slot;
}
-static int emac_change_mtu(struct net_device *dev, int new_mtu)
+/* BHs disabled (SG version for TAH equipped EMACs) */
+static int emac_start_xmit_sg(struct sk_buff *skb, struct net_device *ndev)
{
- struct ocp_enet_private *fep = dev->priv;
- int old_mtu = dev->mtu;
- unsigned long mode_reg;
- emac_t *emacp = fep->emacp;
- u32 em0mr0;
- int i, full;
- unsigned long flags;
+ struct ocp_enet_private *dev = ndev->priv;
+ int nr_frags = skb_shinfo(skb)->nr_frags;
+ int len = skb->len, chunk;
+ int slot, i;
+ u16 ctrl;
+ u32 pd;
- if ((new_mtu < EMAC_MIN_MTU) || (new_mtu > EMAC_MAX_MTU)) {
- printk(KERN_ERR
- "emac: Invalid MTU setting, MTU must be between %d and %d\n",
- EMAC_MIN_MTU, EMAC_MAX_MTU);
- return -EINVAL;
- }
+ /* This is common "fast" path */
+ if (likely(!nr_frags && len <= MAL_MAX_TX_SIZE))
+ return emac_start_xmit(skb, ndev);
- if (old_mtu != new_mtu && netif_running(dev)) {
- /* Stop rx engine */
- em0mr0 = in_be32(&emacp->em0mr0);
- out_be32(&emacp->em0mr0, em0mr0 & ~EMAC_M0_RXE);
-
- /* Wait for descriptors to be empty */
- do {
- full = 0;
- for (i = 0; i < NUM_RX_BUFF; i++)
- if (!(fep->rx_desc[i].ctrl & MAL_RX_CTRL_EMPTY)) {
- printk(KERN_NOTICE
- "emac: RX ring is still full\n");
- full = 1;
- }
- } while (full);
-
- spin_lock_irqsave(&fep->lock, flags);
-
- mal_disable_rx_channels(fep->mal, fep->commac.rx_chan_mask);
-
- /* Destroy all old rx skbs */
- for (i = 0; i < NUM_RX_BUFF; i++) {
- dma_unmap_single(&fep->ocpdev->dev,
- fep->rx_desc[i].data_ptr,
- fep->rx_desc[i].data_len,
- DMA_FROM_DEVICE);
- dev_kfree_skb(fep->rx_skb[i]);
- fep->rx_skb[i] = NULL;
- }
+ len -= skb->data_len;
- /* Set new rx_buffer_size, jumbo cap, and advertise new mtu */
- mode_reg = in_be32(&emacp->em0mr1);
- if (new_mtu > ENET_DEF_MTU_SIZE) {
- mode_reg |= EMAC_M1_JUMBO_ENABLE;
- fep->rx_buffer_size = EMAC_MAX_FRAME;
- } else {
- mode_reg &= ~EMAC_M1_JUMBO_ENABLE;
- fep->rx_buffer_size = ENET_DEF_BUF_SIZE;
- }
- dev->mtu = new_mtu;
- out_be32(&emacp->em0mr1, mode_reg);
+ /* Note, this is only an *estimation*, we can still run out of empty
+ * slots because of the additional fragmentation into
+ * MAL_MAX_TX_SIZE-sized chunks
+ */
+ if (unlikely(dev->tx_cnt + nr_frags + mal_tx_chunks(len) > NUM_TX_BUFF))
+ goto stop_queue;
+
+ ctrl = EMAC_TX_CTRL_GFCS | EMAC_TX_CTRL_GP | MAL_TX_CTRL_READY |
+ emac_tx_csum(dev, skb);
+ slot = dev->tx_slot;
+
+ /* skb data */
+ dev->tx_skb[slot] = NULL;
+ chunk = min(len, MAL_MAX_TX_SIZE);
+ dev->tx_desc[slot].data_ptr = pd =
+ dma_map_single(dev->ldev, skb->data, len, DMA_TO_DEVICE);
+ dev->tx_desc[slot].data_len = (u16) chunk;
+ len -= chunk;
+ if (unlikely(len))
+ slot = emac_xmit_split(dev, slot, pd + chunk, len, !nr_frags,
+ ctrl);
+ /* skb fragments */
+ for (i = 0; i < nr_frags; ++i) {
+ struct skb_frag_struct *frag = &skb_shinfo(skb)->frags[i];
+ len = frag->size;
- /* Re-init rx skbs */
- fep->rx_slot = 0;
- emac_rx_fill(dev, 0);
+ if (unlikely(dev->tx_cnt + mal_tx_chunks(len) >= NUM_TX_BUFF))
+ goto undo_frame;
- /* Restart the rx engine */
- mal_enable_rx_channels(fep->mal, fep->commac.rx_chan_mask);
- out_be32(&emacp->em0mr0, em0mr0 | EMAC_M0_RXE);
+ pd = dma_map_page(dev->ldev, frag->page, frag->page_offset, len,
+ DMA_TO_DEVICE);
- spin_unlock_irqrestore(&fep->lock, flags);
+ slot = emac_xmit_split(dev, slot, pd, len, i == nr_frags - 1,
+ ctrl);
}
- return 0;
-}
+ DBG2("%d: xmit_sg(%u) %d - %d" NL, dev->def->index, skb->len,
+ dev->tx_slot, slot);
-static void __emac_set_multicast_list(struct net_device *dev)
-{
- struct ocp_enet_private *fep = dev->priv;
- emac_t *emacp = fep->emacp;
- u32 rmr = in_be32(&emacp->em0rmr);
+ /* Attach skb to the last slot so we don't release it too early */
+ dev->tx_skb[slot] = skb;
- /* First clear all special bits, they can be set later */
- rmr &= ~(EMAC_RMR_PME | EMAC_RMR_PMME | EMAC_RMR_MAE);
+ /* Send the packet out */
+ if (dev->tx_slot == NUM_TX_BUFF - 1)
+ ctrl |= MAL_TX_CTRL_WRAP;
+ barrier();
+ dev->tx_desc[dev->tx_slot].ctrl = ctrl;
+ dev->tx_slot = (slot + 1) % NUM_TX_BUFF;
- if (dev->flags & IFF_PROMISC) {
- rmr |= EMAC_RMR_PME;
- } else if (dev->flags & IFF_ALLMULTI || 32 < dev->mc_count) {
- /*
- * Must be setting up to use multicast
- * Now check for promiscuous multicast
- */
- rmr |= EMAC_RMR_PMME;
- } else if (dev->flags & IFF_MULTICAST && 0 < dev->mc_count) {
- unsigned short em0gaht[4] = { 0, 0, 0, 0 };
- struct dev_mc_list *dmi;
-
- /* Need to hash on the multicast address. */
- for (dmi = dev->mc_list; dmi; dmi = dmi->next) {
- unsigned long mc_crc;
- unsigned int bit_number;
-
- mc_crc = ether_crc(6, (char *)dmi->dmi_addr);
- bit_number = 63 - (mc_crc >> 26); /* MSB: 0 LSB: 63 */
- em0gaht[bit_number >> 4] |=
- 0x8000 >> (bit_number & 0x0f);
- }
- emacp->em0gaht1 = em0gaht[0];
- emacp->em0gaht2 = em0gaht[1];
- emacp->em0gaht3 = em0gaht[2];
- emacp->em0gaht4 = em0gaht[3];
+ return emac_xmit_finish(dev, skb->len);
- /* Turn on multicast addressing */
- rmr |= EMAC_RMR_MAE;
+ undo_frame:
+ /* Well, too bad. Our previous estimation was overly optimistic.
+ * Undo everything.
+ */
+ while (slot != dev->tx_slot) {
+ dev->tx_desc[slot].ctrl = 0;
+ --dev->tx_cnt;
+ if (--slot < 0)
+ slot = NUM_TX_BUFF - 1;
}
- out_be32(&emacp->em0rmr, rmr);
+ ++dev->estats.tx_undo;
+
+ stop_queue:
+ netif_stop_queue(ndev);
+ DBG2("%d: stopped TX queue" NL, dev->def->index);
+ return 1;
}
+#else
+# define emac_start_xmit_sg emac_start_xmit
+#endif /* !defined(CONFIG_IBM_EMAC_TAH) */
-static int emac_init_tah(struct ocp_enet_private *fep)
+/* BHs disabled */
+static void emac_parse_tx_error(struct ocp_enet_private *dev, u16 ctrl)
{
- tah_t *tahp;
+ struct ibm_emac_error_stats *st = &dev->estats;
+ DBG("%d: BD TX error %04x" NL, dev->def->index, ctrl);
+
+ ++st->tx_bd_errors;
+ if (ctrl & EMAC_TX_ST_BFCS)
+ ++st->tx_bd_bad_fcs;
+ if (ctrl & EMAC_TX_ST_LCS)
+ ++st->tx_bd_carrier_loss;
+ if (ctrl & EMAC_TX_ST_ED)
+ ++st->tx_bd_excessive_deferral;
+ if (ctrl & EMAC_TX_ST_EC)
+ ++st->tx_bd_excessive_collisions;
+ if (ctrl & EMAC_TX_ST_LC)
+ ++st->tx_bd_late_collision;
+ if (ctrl & EMAC_TX_ST_MC)
+ ++st->tx_bd_multple_collisions;
+ if (ctrl & EMAC_TX_ST_SC)
+ ++st->tx_bd_single_collision;
+ if (ctrl & EMAC_TX_ST_UR)
+ ++st->tx_bd_underrun;
+ if (ctrl & EMAC_TX_ST_SQE)
+ ++st->tx_bd_sqe;
+}
- /* Initialize TAH and enable checksum verification */
- tahp = (tah_t *) ioremap(fep->tah_dev->def->paddr, sizeof(*tahp));
+static void emac_poll_tx(void *param)
+{
+ struct ocp_enet_private *dev = param;
+ DBG2("%d: poll_tx, %d %d" NL, dev->def->index, dev->tx_cnt,
+ dev->ack_slot);
+
+ if (dev->tx_cnt) {
+ u16 ctrl;
+ int slot = dev->ack_slot, n = 0;
+ again:
+ ctrl = dev->tx_desc[slot].ctrl;
+ if (!(ctrl & MAL_TX_CTRL_READY)) {
+ struct sk_buff *skb = dev->tx_skb[slot];
+ ++n;
+
+ if (skb) {
+ dev_kfree_skb(skb);
+ dev->tx_skb[slot] = NULL;
+ }
+ slot = (slot + 1) % NUM_TX_BUFF;
- if (tahp == NULL) {
- printk(KERN_ERR "tah%d: Cannot ioremap TAH registers!\n",
- fep->tah_dev->def->index);
+ if (unlikely(EMAC_IS_BAD_TX(ctrl)))
+ emac_parse_tx_error(dev, ctrl);
- return -ENOMEM;
- }
-
- out_be32(&tahp->tah_mr, TAH_MR_SR);
+ if (--dev->tx_cnt)
+ goto again;
+ }
+ if (n) {
+ dev->ack_slot = slot;
+ if (netif_queue_stopped(dev->ndev) &&
+ dev->tx_cnt < EMAC_TX_WAKEUP_THRESH)
+ netif_wake_queue(dev->ndev);
- /* wait for reset to complete */
- while (in_be32(&tahp->tah_mr) & TAH_MR_SR) ;
+ DBG2("%d: tx %d pkts" NL, dev->def->index, n);
+ }
+ }
+}
- /* 10KB TAH TX FIFO accomodates the max MTU of 9000 */
- out_be32(&tahp->tah_mr,
- TAH_MR_CVR | TAH_MR_ST_768 | TAH_MR_TFS_10KB | TAH_MR_DTFP |
- TAH_MR_DIG);
+static inline void emac_recycle_rx_skb(struct ocp_enet_private *dev, int slot,
+ int len)
+{
+ struct sk_buff *skb = dev->rx_skb[slot];
+ DBG2("%d: recycle %d %d" NL, dev->def->index, slot, len);
- iounmap(tahp);
+ if (len)
+ dma_map_single(dev->ldev, skb->data - 2,
+ EMAC_DMA_ALIGN(len + 2), DMA_FROM_DEVICE);
- return 0;
+ dev->rx_desc[slot].data_len = 0;
+ barrier();
+ dev->rx_desc[slot].ctrl = MAL_RX_CTRL_EMPTY |
+ (slot == (NUM_RX_BUFF - 1) ? MAL_RX_CTRL_WRAP : 0);
}
-static void emac_init_rings(struct net_device *dev)
+static void emac_parse_rx_error(struct ocp_enet_private *dev, u16 ctrl)
{
- struct ocp_enet_private *ep = dev->priv;
- int loop;
+ struct ibm_emac_error_stats *st = &dev->estats;
+ DBG("%d: BD RX error %04x" NL, dev->def->index, ctrl);
+
+ ++st->rx_bd_errors;
+ if (ctrl & EMAC_RX_ST_OE)
+ ++st->rx_bd_overrun;
+ if (ctrl & EMAC_RX_ST_BP)
+ ++st->rx_bd_bad_packet;
+ if (ctrl & EMAC_RX_ST_RP)
+ ++st->rx_bd_runt_packet;
+ if (ctrl & EMAC_RX_ST_SE)
+ ++st->rx_bd_short_event;
+ if (ctrl & EMAC_RX_ST_AE)
+ ++st->rx_bd_alignment_error;
+ if (ctrl & EMAC_RX_ST_BFCS)
+ ++st->rx_bd_bad_fcs;
+ if (ctrl & EMAC_RX_ST_PTL)
+ ++st->rx_bd_packet_too_long;
+ if (ctrl & EMAC_RX_ST_ORE)
+ ++st->rx_bd_out_of_range;
+ if (ctrl & EMAC_RX_ST_IRE)
+ ++st->rx_bd_in_range;
+}
- ep->tx_desc = (struct mal_descriptor *)((char *)ep->mal->tx_virt_addr +
- (ep->mal_tx_chan *
- MAL_DT_ALIGN));
- ep->rx_desc =
- (struct mal_descriptor *)((char *)ep->mal->rx_virt_addr +
- (ep->mal_rx_chan * MAL_DT_ALIGN));
+static inline void emac_rx_csum(struct ocp_enet_private *dev,
+ struct sk_buff *skb, u16 ctrl)
+{
+#if defined(CONFIG_IBM_EMAC_TAH)
+ if (!ctrl && dev->tah_dev) {
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
+ ++dev->stats.rx_packets_csum;
+ }
+#endif
+}
- /* Fill in the transmit descriptor ring. */
- for (loop = 0; loop < NUM_TX_BUFF; loop++) {
- if (ep->tx_skb[loop]) {
- dma_unmap_single(&ep->ocpdev->dev,
- ep->tx_desc[loop].data_ptr,
- ep->tx_desc[loop].data_len,
- DMA_TO_DEVICE);
- dev_kfree_skb_irq(ep->tx_skb[loop]);
+static inline int emac_rx_sg_append(struct ocp_enet_private *dev, int slot)
+{
+ if (likely(dev->rx_sg_skb != NULL)) {
+ int len = dev->rx_desc[slot].data_len;
+ int tot_len = dev->rx_sg_skb->len + len;
+
+ if (unlikely(tot_len + 2 > dev->rx_skb_size)) {
+ ++dev->estats.rx_dropped_mtu;
+ dev_kfree_skb(dev->rx_sg_skb);
+ dev->rx_sg_skb = NULL;
+ } else {
+ cacheable_memcpy(dev->rx_sg_skb->tail,
+ dev->rx_skb[slot]->data, len);
+ skb_put(dev->rx_sg_skb, len);
+ emac_recycle_rx_skb(dev, slot, len);
+ return 0;
}
- ep->tx_skb[loop] = NULL;
- ep->tx_desc[loop].ctrl = 0;
- ep->tx_desc[loop].data_len = 0;
- ep->tx_desc[loop].data_ptr = NULL;
- }
- ep->tx_desc[loop - 1].ctrl |= MAL_TX_CTRL_WRAP;
-
- /* Format the receive descriptor ring. */
- ep->rx_slot = 0;
- /* Default is MTU=1500 + Ethernet overhead */
- ep->rx_buffer_size = dev->mtu + ENET_HEADER_SIZE + ENET_FCS_SIZE;
- emac_rx_fill(dev, 0);
- if (ep->rx_slot != 0) {
- printk(KERN_ERR
- "%s: Not enough mem for RxChain durning Open?\n",
- dev->name);
- /*We couldn't fill the ring at startup?
- *We could clean up and fail to open but right now we will try to
- *carry on. It may be a sign of a bad NUM_RX_BUFF value
- */
}
-
- ep->tx_cnt = 0;
- ep->tx_slot = 0;
- ep->ack_slot = 0;
+ emac_recycle_rx_skb(dev, slot, 0);
+ return -1;
}
-static void emac_reset_configure(struct ocp_enet_private *fep)
+/* BHs disabled */
+static int emac_poll_rx(void *param, int budget)
{
- emac_t *emacp = fep->emacp;
- int i;
-
- mal_disable_tx_channels(fep->mal, fep->commac.tx_chan_mask);
- mal_disable_rx_channels(fep->mal, fep->commac.rx_chan_mask);
+ struct ocp_enet_private *dev = param;
+ int slot = dev->rx_slot, received = 0;
- /*
- * Check for a link, some PHYs don't provide a clock if
- * no link is present. Some EMACs will not come out of
- * soft reset without a PHY clock present.
- */
- if (fep->phy_mii.def->ops->poll_link(&fep->phy_mii)) {
- /* Reset the EMAC */
- out_be32(&emacp->em0mr0, EMAC_M0_SRST);
- udelay(20);
- for (i = 0; i < 100; i++) {
- if ((in_be32(&emacp->em0mr0) & EMAC_M0_SRST) == 0)
- break;
- udelay(10);
- }
+ DBG2("%d: poll_rx(%d)" NL, dev->def->index, budget);
- if (i >= 100) {
- printk(KERN_ERR "%s: Cannot reset EMAC\n",
- fep->ndev->name);
- return;
- }
- }
+ again:
+ while (budget > 0) {
+ int len;
+ struct sk_buff *skb;
+ u16 ctrl = dev->rx_desc[slot].ctrl;
- /* Switch IRQs off for now */
- out_be32(&emacp->em0iser, 0);
-
- /* Configure MAL rx channel */
- mal_set_rcbs(fep->mal, fep->mal_rx_chan, DESC_BUF_SIZE_REG);
+ if (ctrl & MAL_RX_CTRL_EMPTY)
+ break;
- /* set the high address */
- out_be32(&emacp->em0iahr,
- (fep->ndev->dev_addr[0] << 8) | fep->ndev->dev_addr[1]);
+ skb = dev->rx_skb[slot];
+ barrier();
+ len = dev->rx_desc[slot].data_len;
- /* set the low address */
- out_be32(&emacp->em0ialr,
- (fep->ndev->dev_addr[2] << 24) | (fep->ndev->dev_addr[3] << 16)
- | (fep->ndev->dev_addr[4] << 8) | fep->ndev->dev_addr[5]);
+ if (unlikely(!MAL_IS_SINGLE_RX(ctrl)))
+ goto sg;
- /* Adjust to link */
- if (netif_carrier_ok(fep->ndev))
- emac_adjust_to_link(fep);
+ ctrl &= EMAC_BAD_RX_MASK;
+ if (unlikely(ctrl && ctrl != EMAC_RX_TAH_BAD_CSUM)) {
+ emac_parse_rx_error(dev, ctrl);
+ ++dev->estats.rx_dropped_error;
+ emac_recycle_rx_skb(dev, slot, 0);
+ len = 0;
+ goto next;
+ }
- /* enable broadcast/individual address and RX FIFO defaults */
- out_be32(&emacp->em0rmr, EMAC_RMR_DEFAULT);
+ if (len && len < EMAC_RX_COPY_THRESH) {
+ struct sk_buff *copy_skb =
+ alloc_skb(len + EMAC_RX_SKB_HEADROOM + 2, GFP_ATOMIC);
+ if (unlikely(!copy_skb))
+ goto oom;
+
+ skb_reserve(copy_skb, EMAC_RX_SKB_HEADROOM + 2);
+ cacheable_memcpy(copy_skb->data - 2, skb->data - 2,
+ len + 2);
+ emac_recycle_rx_skb(dev, slot, len);
+ skb = copy_skb;
+ } else if (unlikely(emac_alloc_rx_skb(dev, slot, GFP_ATOMIC)))
+ goto oom;
+
+ skb_put(skb, len);
+ push_packet:
+ skb->dev = dev->ndev;
+ skb->protocol = eth_type_trans(skb, dev->ndev);
+ emac_rx_csum(dev, skb, ctrl);
+
+ if (unlikely(netif_receive_skb(skb) == NET_RX_DROP))
+ ++dev->estats.rx_dropped_stack;
+ next:
+ ++dev->stats.rx_packets;
+ skip:
+ dev->stats.rx_bytes += len;
+ slot = (slot + 1) % NUM_RX_BUFF;
+ --budget;
+ ++received;
+ continue;
+ sg:
+ if (ctrl & MAL_RX_CTRL_FIRST) {
+ BUG_ON(dev->rx_sg_skb);
+ if (unlikely(emac_alloc_rx_skb(dev, slot, GFP_ATOMIC))) {
+ DBG("%d: rx OOM %d" NL, dev->def->index, slot);
+ ++dev->estats.rx_dropped_oom;
+ emac_recycle_rx_skb(dev, slot, 0);
+ } else {
+ dev->rx_sg_skb = skb;
+ skb_put(skb, len);
+ }
+ } else if (!emac_rx_sg_append(dev, slot) &&
+ (ctrl & MAL_RX_CTRL_LAST)) {
+
+ skb = dev->rx_sg_skb;
+ dev->rx_sg_skb = NULL;
+
+ ctrl &= EMAC_BAD_RX_MASK;
+ if (unlikely(ctrl && ctrl != EMAC_RX_TAH_BAD_CSUM)) {
+ emac_parse_rx_error(dev, ctrl);
+ ++dev->estats.rx_dropped_error;
+ dev_kfree_skb(skb);
+ len = 0;
+ } else
+ goto push_packet;
+ }
+ goto skip;
+ oom:
+ DBG("%d: rx OOM %d" NL, dev->def->index, slot);
+ /* Drop the packet and recycle skb */
+ ++dev->estats.rx_dropped_oom;
+ emac_recycle_rx_skb(dev, slot, 0);
+ goto next;
+ }
- /* set transmit request threshold register */
- out_be32(&emacp->em0trtr, EMAC_TRTR_DEFAULT);
+ if (received) {
+ DBG2("%d: rx %d BDs" NL, dev->def->index, received);
+ dev->rx_slot = slot;
+ }
- /* Reconfigure multicast */
- __emac_set_multicast_list(fep->ndev);
+ if (unlikely(budget && dev->commac.rx_stopped)) {
+ struct ocp_func_emac_data *emacdata = dev->def->additions;
- /* Set receiver/transmitter defaults */
- out_be32(&emacp->em0rwmr, EMAC_RWMR_DEFAULT);
- out_be32(&emacp->em0tmr0, EMAC_TMR0_DEFAULT);
- out_be32(&emacp->em0tmr1, EMAC_TMR1_DEFAULT);
+ barrier();
+ if (!(dev->rx_desc[slot].ctrl & MAL_RX_CTRL_EMPTY)) {
+ DBG2("%d: rx restart" NL, dev->def->index);
+ received = 0;
+ goto again;
+ }
- /* set frame gap */
- out_be32(&emacp->em0ipgvr, CONFIG_IBM_EMAC_FGAP);
-
- /* set VLAN Tag Protocol Identifier */
- out_be32(&emacp->em0vtpid, 0x8100);
+ if (dev->rx_sg_skb) {
+ DBG2("%d: dropping partial rx packet" NL,
+ dev->def->index);
+ ++dev->estats.rx_dropped_error;
+ dev_kfree_skb(dev->rx_sg_skb);
+ dev->rx_sg_skb = NULL;
+ }
- /* Init ring buffers */
- emac_init_rings(fep->ndev);
+ dev->commac.rx_stopped = 0;
+ mal_enable_rx_channel(dev->mal, emacdata->mal_rx_chan);
+ emac_rx_enable(dev);
+ dev->rx_slot = 0;
+ }
+ return received;
}
-static void emac_kick(struct ocp_enet_private *fep)
+/* BHs disabled */
+static int emac_peek_rx(void *param)
{
- emac_t *emacp = fep->emacp;
- unsigned long emac_ier;
-
- emac_ier = EMAC_ISR_PP | EMAC_ISR_BP | EMAC_ISR_RP |
- EMAC_ISR_SE | EMAC_ISR_PTLE | EMAC_ISR_ALE |
- EMAC_ISR_BFCS | EMAC_ISR_ORE | EMAC_ISR_IRE;
+ struct ocp_enet_private *dev = param;
+ return !(dev->rx_desc[dev->rx_slot].ctrl & MAL_RX_CTRL_EMPTY);
+}
- out_be32(&emacp->em0iser, emac_ier);
+/* BHs disabled */
+static int emac_peek_rx_sg(void *param)
+{
+ struct ocp_enet_private *dev = param;
+ int slot = dev->rx_slot;
+ while (1) {
+ u16 ctrl = dev->rx_desc[slot].ctrl;
+ if (ctrl & MAL_RX_CTRL_EMPTY)
+ return 0;
+ else if (ctrl & MAL_RX_CTRL_LAST)
+ return 1;
- /* enable all MAL transmit and receive channels */
- mal_enable_tx_channels(fep->mal, fep->commac.tx_chan_mask);
- mal_enable_rx_channels(fep->mal, fep->commac.rx_chan_mask);
+ slot = (slot + 1) % NUM_RX_BUFF;
- /* set transmit and receive enable */
- out_be32(&emacp->em0mr0, EMAC_M0_TXE | EMAC_M0_RXE);
+ /* I'm just being paranoid here :) */
+ if (unlikely(slot == dev->rx_slot))
+ return 0;
+ }
}
-static void
-emac_start_link(struct ocp_enet_private *fep, struct ethtool_cmd *ep)
+/* Hard IRQ */
+static void emac_rxde(void *param)
{
- u32 advertise;
- int autoneg;
- int forced_speed;
- int forced_duplex;
+ struct ocp_enet_private *dev = param;
+ ++dev->estats.rx_stopped;
+ emac_rx_disable_async(dev);
+}
- /* Default advertise */
- advertise = ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full |
- ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full |
- ADVERTISED_1000baseT_Half | ADVERTISED_1000baseT_Full;
- autoneg = fep->want_autoneg;
- forced_speed = fep->phy_mii.speed;
- forced_duplex = fep->phy_mii.duplex;
+/* Hard IRQ */
+static irqreturn_t emac_irq(int irq, void *dev_instance, struct pt_regs *regs)
+{
+ struct ocp_enet_private *dev = dev_instance;
+ struct emac_regs *p = dev->emacp;
+ struct ibm_emac_error_stats *st = &dev->estats;
+
+ u32 isr = in_be32(&p->isr);
+ out_be32(&p->isr, isr);
+
+ DBG("%d: isr = %08x" NL, dev->def->index, isr);
+
+ if (isr & EMAC_ISR_TXPE)
+ ++st->tx_parity;
+ if (isr & EMAC_ISR_RXPE)
+ ++st->rx_parity;
+ if (isr & EMAC_ISR_TXUE)
+ ++st->tx_underrun;
+ if (isr & EMAC_ISR_RXOE)
+ ++st->rx_fifo_overrun;
+ if (isr & EMAC_ISR_OVR)
+ ++st->rx_overrun;
+ if (isr & EMAC_ISR_BP)
+ ++st->rx_bad_packet;
+ if (isr & EMAC_ISR_RP)
+ ++st->rx_runt_packet;
+ if (isr & EMAC_ISR_SE)
+ ++st->rx_short_event;
+ if (isr & EMAC_ISR_ALE)
+ ++st->rx_alignment_error;
+ if (isr & EMAC_ISR_BFCS)
+ ++st->rx_bad_fcs;
+ if (isr & EMAC_ISR_PTLE)
+ ++st->rx_packet_too_long;
+ if (isr & EMAC_ISR_ORE)
+ ++st->rx_out_of_range;
+ if (isr & EMAC_ISR_IRE)
+ ++st->rx_in_range;
+ if (isr & EMAC_ISR_SQE)
+ ++st->tx_sqe;
+ if (isr & EMAC_ISR_TE)
+ ++st->tx_errors;
- /* Setup link parameters */
- if (ep) {
- if (ep->autoneg == AUTONEG_ENABLE) {
- advertise = ep->advertising;
- autoneg = 1;
- } else {
- autoneg = 0;
- forced_speed = ep->speed;
- forced_duplex = ep->duplex;
- }
- }
+ return IRQ_HANDLED;
+}
- /* Configure PHY & start aneg */
- fep->want_autoneg = autoneg;
- if (autoneg) {
- LINK_DEBUG(("%s: start link aneg, advertise: 0x%x\n",
- fep->ndev->name, advertise));
- fep->phy_mii.def->ops->setup_aneg(&fep->phy_mii, advertise);
- } else {
- LINK_DEBUG(("%s: start link forced, speed: %d, duplex: %d\n",
- fep->ndev->name, forced_speed, forced_duplex));
- fep->phy_mii.def->ops->setup_forced(&fep->phy_mii, forced_speed,
- forced_duplex);
- }
- fep->timer_ticks = 0;
- mod_timer(&fep->link_timer, jiffies + HZ);
+static struct net_device_stats *emac_stats(struct net_device *ndev)
+{
+ struct ocp_enet_private *dev = ndev->priv;
+ struct ibm_emac_stats *st = &dev->stats;
+ struct ibm_emac_error_stats *est = &dev->estats;
+ struct net_device_stats *nst = &dev->nstats;
+
+ DBG2("%d: stats" NL, dev->def->index);
+
+ /* Compute "legacy" statistics */
+ local_irq_disable();
+ nst->rx_packets = (unsigned long)st->rx_packets;
+ nst->rx_bytes = (unsigned long)st->rx_bytes;
+ nst->tx_packets = (unsigned long)st->tx_packets;
+ nst->tx_bytes = (unsigned long)st->tx_bytes;
+ nst->rx_dropped = (unsigned long)(est->rx_dropped_oom +
+ est->rx_dropped_error +
+ est->rx_dropped_resize +
+ est->rx_dropped_mtu);
+ nst->tx_dropped = (unsigned long)est->tx_dropped;
+
+ nst->rx_errors = (unsigned long)est->rx_bd_errors;
+ nst->rx_fifo_errors = (unsigned long)(est->rx_bd_overrun +
+ est->rx_fifo_overrun +
+ est->rx_overrun);
+ nst->rx_frame_errors = (unsigned long)(est->rx_bd_alignment_error +
+ est->rx_alignment_error);
+ nst->rx_crc_errors = (unsigned long)(est->rx_bd_bad_fcs +
+ est->rx_bad_fcs);
+ nst->rx_length_errors = (unsigned long)(est->rx_bd_runt_packet +
+ est->rx_bd_short_event +
+ est->rx_bd_packet_too_long +
+ est->rx_bd_out_of_range +
+ est->rx_bd_in_range +
+ est->rx_runt_packet +
+ est->rx_short_event +
+ est->rx_packet_too_long +
+ est->rx_out_of_range +
+ est->rx_in_range);
+
+ nst->tx_errors = (unsigned long)(est->tx_bd_errors + est->tx_errors);
+ nst->tx_fifo_errors = (unsigned long)(est->tx_bd_underrun +
+ est->tx_underrun);
+ nst->tx_carrier_errors = (unsigned long)est->tx_bd_carrier_loss;
+ nst->collisions = (unsigned long)(est->tx_bd_excessive_deferral +
+ est->tx_bd_excessive_collisions +
+ est->tx_bd_late_collision +
+ est->tx_bd_multple_collisions);
+ local_irq_enable();
+ return nst;
}
-static void emac_link_timer(unsigned long data)
+static void emac_remove(struct ocp_device *ocpdev)
{
- struct ocp_enet_private *fep = (struct ocp_enet_private *)data;
- int link;
+ struct ocp_enet_private *dev = ocp_get_drvdata(ocpdev);
- if (fep->going_away)
- return;
+ DBG("%d: remove" NL, dev->def->index);
- spin_lock_irq(&fep->lock);
+ ocp_set_drvdata(ocpdev, 0);
+ unregister_netdev(dev->ndev);
- link = fep->phy_mii.def->ops->poll_link(&fep->phy_mii);
- LINK_DEBUG(("%s: poll_link: %d\n", fep->ndev->name, link));
+ tah_fini(dev->tah_dev);
+ rgmii_fini(dev->rgmii_dev, dev->rgmii_input);
+ zmii_fini(dev->zmii_dev, dev->zmii_input);
- if (link == netif_carrier_ok(fep->ndev)) {
- if (!link && fep->want_autoneg && (++fep->timer_ticks) > 10)
- emac_start_link(fep, NULL);
- goto out;
- }
- printk(KERN_INFO "%s: Link is %s\n", fep->ndev->name,
- link ? "Up" : "Down");
- if (link) {
- netif_carrier_on(fep->ndev);
- /* Chip needs a full reset on config change. That sucks, so I
- * should ultimately move that to some tasklet to limit
- * latency peaks caused by this code
- */
- emac_reset_configure(fep);
- if (fep->opened)
- emac_kick(fep);
- } else {
- fep->timer_ticks = 0;
- netif_carrier_off(fep->ndev);
- }
- out:
- mod_timer(&fep->link_timer, jiffies + HZ);
- spin_unlock_irq(&fep->lock);
+ emac_dbg_register(dev->def->index, 0);
+
+ mal_unregister_commac(dev->mal, &dev->commac);
+ iounmap((void *)dev->emacp);
+ kfree(dev->ndev);
}
-static void emac_set_multicast_list(struct net_device *dev)
-{
- struct ocp_enet_private *fep = dev->priv;
+static struct mal_commac_ops emac_commac_ops = {
+ .poll_tx = &emac_poll_tx,
+ .poll_rx = &emac_poll_rx,
+ .peek_rx = &emac_peek_rx,
+ .rxde = &emac_rxde,
+};
- spin_lock_irq(&fep->lock);
- __emac_set_multicast_list(dev);
- spin_unlock_irq(&fep->lock);
-}
+static struct mal_commac_ops emac_commac_sg_ops = {
+ .poll_tx = &emac_poll_tx,
+ .poll_rx = &emac_poll_rx,
+ .peek_rx = &emac_peek_rx_sg,
+ .rxde = &emac_rxde,
+};
-static int emac_get_settings(struct net_device *ndev, struct ethtool_cmd *cmd)
+/* Ethtool support */
+static int emac_ethtool_get_settings(struct net_device *ndev,
+ struct ethtool_cmd *cmd)
{
- struct ocp_enet_private *fep = ndev->priv;
+ struct ocp_enet_private *dev = ndev->priv;
- cmd->supported = fep->phy_mii.def->features;
+ cmd->supported = dev->phy.features;
cmd->port = PORT_MII;
- cmd->transceiver = XCVR_EXTERNAL;
- cmd->phy_address = fep->mii_phy_addr;
- spin_lock_irq(&fep->lock);
- cmd->autoneg = fep->want_autoneg;
- cmd->speed = fep->phy_mii.speed;
- cmd->duplex = fep->phy_mii.duplex;
- spin_unlock_irq(&fep->lock);
+ cmd->phy_address = dev->phy.address;
+ cmd->transceiver =
+ dev->phy.address >= 0 ? XCVR_EXTERNAL : XCVR_INTERNAL;
+
+ local_bh_disable();
+ cmd->advertising = dev->phy.advertising;
+ cmd->autoneg = dev->phy.autoneg;
+ cmd->speed = dev->phy.speed;
+ cmd->duplex = dev->phy.duplex;
+ local_bh_enable();
+
return 0;
}
-static int emac_set_settings(struct net_device *ndev, struct ethtool_cmd *cmd)
+static int emac_ethtool_set_settings(struct net_device *ndev,
+ struct ethtool_cmd *cmd)
{
- struct ocp_enet_private *fep = ndev->priv;
- unsigned long features = fep->phy_mii.def->features;
+ struct ocp_enet_private *dev = ndev->priv;
+ u32 f = dev->phy.features;
- if (!capable(CAP_NET_ADMIN))
- return -EPERM;
+ DBG("%d: set_settings(%d, %d, %d, 0x%08x)" NL, dev->def->index,
+ cmd->autoneg, cmd->speed, cmd->duplex, cmd->advertising);
+ /* Basic sanity checks */
+ if (dev->phy.address < 0)
+ return -EOPNOTSUPP;
if (cmd->autoneg != AUTONEG_ENABLE && cmd->autoneg != AUTONEG_DISABLE)
return -EINVAL;
if (cmd->autoneg == AUTONEG_ENABLE && cmd->advertising == 0)
return -EINVAL;
if (cmd->duplex != DUPLEX_HALF && cmd->duplex != DUPLEX_FULL)
return -EINVAL;
- if (cmd->autoneg == AUTONEG_DISABLE)
+
+ if (cmd->autoneg == AUTONEG_DISABLE) {
switch (cmd->speed) {
case SPEED_10:
- if (cmd->duplex == DUPLEX_HALF &&
- (features & SUPPORTED_10baseT_Half) == 0)
+ if (cmd->duplex == DUPLEX_HALF
+ && !(f & SUPPORTED_10baseT_Half))
return -EINVAL;
- if (cmd->duplex == DUPLEX_FULL &&
- (features & SUPPORTED_10baseT_Full) == 0)
+ if (cmd->duplex == DUPLEX_FULL
+ && !(f & SUPPORTED_10baseT_Full))
return -EINVAL;
break;
case SPEED_100:
- if (cmd->duplex == DUPLEX_HALF &&
- (features & SUPPORTED_100baseT_Half) == 0)
+ if (cmd->duplex == DUPLEX_HALF
+ && !(f & SUPPORTED_100baseT_Half))
return -EINVAL;
- if (cmd->duplex == DUPLEX_FULL &&
- (features & SUPPORTED_100baseT_Full) == 0)
+ if (cmd->duplex == DUPLEX_FULL
+ && !(f & SUPPORTED_100baseT_Full))
return -EINVAL;
break;
case SPEED_1000:
- if (cmd->duplex == DUPLEX_HALF &&
- (features & SUPPORTED_1000baseT_Half) == 0)
+ if (cmd->duplex == DUPLEX_HALF
+ && !(f & SUPPORTED_1000baseT_Half))
return -EINVAL;
- if (cmd->duplex == DUPLEX_FULL &&
- (features & SUPPORTED_1000baseT_Full) == 0)
+ if (cmd->duplex == DUPLEX_FULL
+ && !(f & SUPPORTED_1000baseT_Full))
return -EINVAL;
break;
default:
return -EINVAL;
- } else if ((features & SUPPORTED_Autoneg) == 0)
- return -EINVAL;
- spin_lock_irq(&fep->lock);
- emac_start_link(fep, cmd);
- spin_unlock_irq(&fep->lock);
+ }
+
+ local_bh_disable();
+ dev->phy.def->ops->setup_forced(&dev->phy, cmd->speed,
+ cmd->duplex);
+
+ } else {
+ if (!(f & SUPPORTED_Autoneg))
+ return -EINVAL;
+
+ local_bh_disable();
+ dev->phy.def->ops->setup_aneg(&dev->phy,
+ (cmd->advertising & f) |
+ (dev->phy.advertising &
+ (ADVERTISED_Pause |
+ ADVERTISED_Asym_Pause)));
+ }
+ emac_force_link_update(dev);
+ local_bh_enable();
+
return 0;
}
-static void
-emac_get_drvinfo(struct net_device *ndev, struct ethtool_drvinfo *info)
+static void emac_ethtool_get_ringparam(struct net_device *ndev,
+ struct ethtool_ringparam *rp)
{
- struct ocp_enet_private *fep = ndev->priv;
-
- strcpy(info->driver, DRV_NAME);
- strcpy(info->version, DRV_VERSION);
- info->fw_version[0] = '\0';
- sprintf(info->bus_info, "IBM EMAC %d", fep->ocpdev->def->index);
- info->regdump_len = 0;
+ rp->rx_max_pending = rp->rx_pending = NUM_RX_BUFF;
+ rp->tx_max_pending = rp->tx_pending = NUM_TX_BUFF;
}
-static int emac_nway_reset(struct net_device *ndev)
+static void emac_ethtool_get_pauseparam(struct net_device *ndev,
+ struct ethtool_pauseparam *pp)
{
- struct ocp_enet_private *fep = ndev->priv;
+ struct ocp_enet_private *dev = ndev->priv;
+
+ local_bh_disable();
+ if ((dev->phy.features & SUPPORTED_Autoneg) &&
+ (dev->phy.advertising & (ADVERTISED_Pause | ADVERTISED_Asym_Pause)))
+ pp->autoneg = 1;
+
+ if (dev->phy.duplex == DUPLEX_FULL) {
+ if (dev->phy.pause)
+ pp->rx_pause = pp->tx_pause = 1;
+ else if (dev->phy.asym_pause)
+ pp->tx_pause = 1;
+ }
+ local_bh_enable();
+}
- if (!fep->want_autoneg)
- return -EINVAL;
- spin_lock_irq(&fep->lock);
- emac_start_link(fep, NULL);
- spin_unlock_irq(&fep->lock);
- return 0;
+static u32 emac_ethtool_get_rx_csum(struct net_device *ndev)
+{
+ struct ocp_enet_private *dev = ndev->priv;
+ return dev->tah_dev != 0;
}
-static u32 emac_get_link(struct net_device *ndev)
+static int emac_get_regs_len(struct ocp_enet_private *dev)
{
- return netif_carrier_ok(ndev);
+ return sizeof(struct emac_ethtool_regs_subhdr) + EMAC_ETHTOOL_REGS_SIZE;
}
-static struct ethtool_ops emac_ethtool_ops = {
- .get_settings = emac_get_settings,
- .set_settings = emac_set_settings,
- .get_drvinfo = emac_get_drvinfo,
- .nway_reset = emac_nway_reset,
- .get_link = emac_get_link
-};
+static int emac_ethtool_get_regs_len(struct net_device *ndev)
+{
+ struct ocp_enet_private *dev = ndev->priv;
+ return sizeof(struct emac_ethtool_regs_hdr) +
+ emac_get_regs_len(dev) + mal_get_regs_len(dev->mal) +
+ zmii_get_regs_len(dev->zmii_dev) +
+ rgmii_get_regs_len(dev->rgmii_dev) +
+ tah_get_regs_len(dev->tah_dev);
+}
-static int emac_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+static void *emac_dump_regs(struct ocp_enet_private *dev, void *buf)
{
- struct ocp_enet_private *fep = dev->priv;
- uint16_t *data = (uint16_t *) & rq->ifr_ifru;
+ struct emac_ethtool_regs_subhdr *hdr = buf;
- switch (cmd) {
- case SIOCGMIIPHY:
- data[0] = fep->mii_phy_addr;
- /* Fall through */
- case SIOCGMIIREG:
- data[3] = emac_phy_read(dev, fep->mii_phy_addr, data[1]);
- return 0;
- case SIOCSMIIREG:
- if (!capable(CAP_NET_ADMIN))
- return -EPERM;
+ hdr->version = EMAC_ETHTOOL_REGS_VER;
+ hdr->index = dev->def->index;
+ memcpy_fromio(hdr + 1, dev->emacp, EMAC_ETHTOOL_REGS_SIZE);
+ return ((void *)(hdr + 1) + EMAC_ETHTOOL_REGS_SIZE);
+}
- emac_phy_write(dev, fep->mii_phy_addr, data[1], data[2]);
- return 0;
- default:
- return -EOPNOTSUPP;
+static void emac_ethtool_get_regs(struct net_device *ndev,
+ struct ethtool_regs *regs, void *buf)
+{
+ struct ocp_enet_private *dev = ndev->priv;
+ struct emac_ethtool_regs_hdr *hdr = buf;
+
+ hdr->components = 0;
+ buf = hdr + 1;
+
+ local_irq_disable();
+ buf = mal_dump_regs(dev->mal, buf);
+ buf = emac_dump_regs(dev, buf);
+ if (dev->zmii_dev) {
+ hdr->components |= EMAC_ETHTOOL_REGS_ZMII;
+ buf = zmii_dump_regs(dev->zmii_dev, buf);
}
+ if (dev->rgmii_dev) {
+ hdr->components |= EMAC_ETHTOOL_REGS_RGMII;
+ buf = rgmii_dump_regs(dev->rgmii_dev, buf);
+ }
+ if (dev->tah_dev) {
+ hdr->components |= EMAC_ETHTOOL_REGS_TAH;
+ buf = tah_dump_regs(dev->tah_dev, buf);
+ }
+ local_irq_enable();
}
-static int emac_open(struct net_device *dev)
+static int emac_ethtool_nway_reset(struct net_device *ndev)
{
- struct ocp_enet_private *fep = dev->priv;
- int rc;
+ struct ocp_enet_private *dev = ndev->priv;
+ int res = 0;
- spin_lock_irq(&fep->lock);
+ DBG("%d: nway_reset" NL, dev->def->index);
- fep->opened = 1;
- netif_carrier_off(dev);
+ if (dev->phy.address < 0)
+ return -EOPNOTSUPP;
- /* Reset & configure the chip */
- emac_reset_configure(fep);
+ local_bh_disable();
+ if (!dev->phy.autoneg) {
+ res = -EINVAL;
+ goto out;
+ }
- spin_unlock_irq(&fep->lock);
+ dev->phy.def->ops->setup_aneg(&dev->phy, dev->phy.advertising);
+ emac_force_link_update(dev);
- /* Request our interrupt lines */
- rc = request_irq(dev->irq, emac_mac_irq, 0, "IBM EMAC MAC", dev);
- if (rc != 0) {
- printk("dev->irq %d failed\n", dev->irq);
- goto bail;
- }
- /* Kick the chip rx & tx channels into life */
- spin_lock_irq(&fep->lock);
- emac_kick(fep);
- spin_unlock_irq(&fep->lock);
+ out:
+ local_bh_enable();
+ return res;
+}
- netif_start_queue(dev);
- bail:
- return rc;
+static int emac_ethtool_get_stats_count(struct net_device *ndev)
+{
+ return EMAC_ETHTOOL_STATS_COUNT;
}
-static int emac_close(struct net_device *dev)
+static void emac_ethtool_get_strings(struct net_device *ndev, u32 stringset,
+ u8 * buf)
{
- struct ocp_enet_private *fep = dev->priv;
- emac_t *emacp = fep->emacp;
+ if (stringset == ETH_SS_STATS)
+ memcpy(buf, &emac_stats_keys, sizeof(emac_stats_keys));
+}
- /* XXX Stop IRQ emitting here */
- spin_lock_irq(&fep->lock);
- fep->opened = 0;
- mal_disable_tx_channels(fep->mal, fep->commac.tx_chan_mask);
- mal_disable_rx_channels(fep->mal, fep->commac.rx_chan_mask);
- netif_carrier_off(dev);
- netif_stop_queue(dev);
+static void emac_ethtool_get_ethtool_stats(struct net_device *ndev,
+ struct ethtool_stats *estats,
+ u64 * tmp_stats)
+{
+ struct ocp_enet_private *dev = ndev->priv;
+ local_irq_disable();
+ memcpy(tmp_stats, &dev->stats, sizeof(dev->stats));
+ tmp_stats += sizeof(dev->stats) / sizeof(u64);
+ memcpy(tmp_stats, &dev->estats, sizeof(dev->estats));
+ local_irq_enable();
+}
- /*
- * Check for a link, some PHYs don't provide a clock if
- * no link is present. Some EMACs will not come out of
- * soft reset without a PHY clock present.
- */
- if (fep->phy_mii.def->ops->poll_link(&fep->phy_mii)) {
- out_be32(&emacp->em0mr0, EMAC_M0_SRST);
- udelay(10);
+static void emac_ethtool_get_drvinfo(struct net_device *ndev,
+ struct ethtool_drvinfo *info)
+{
+ struct ocp_enet_private *dev = ndev->priv;
- if (emacp->em0mr0 & EMAC_M0_SRST) {
- /*not sure what to do here hopefully it clears before another open */
- printk(KERN_ERR
- "%s: Phy SoftReset didn't clear, no link?\n",
- dev->name);
- }
- }
+ strcpy(info->driver, "ibm_emac");
+ strcpy(info->version, DRV_VERSION);
+ info->fw_version[0] = '\0';
+ sprintf(info->bus_info, "PPC 4xx EMAC %d", dev->def->index);
+ info->n_stats = emac_ethtool_get_stats_count(ndev);
+ info->regdump_len = emac_ethtool_get_regs_len(ndev);
+}
- /* Free the irq's */
- free_irq(dev->irq, dev);
+static struct ethtool_ops emac_ethtool_ops = {
+ .get_settings = emac_ethtool_get_settings,
+ .set_settings = emac_ethtool_set_settings,
+ .get_drvinfo = emac_ethtool_get_drvinfo,
- spin_unlock_irq(&fep->lock);
+ .get_regs_len = emac_ethtool_get_regs_len,
+ .get_regs = emac_ethtool_get_regs,
- return 0;
-}
+ .nway_reset = emac_ethtool_nway_reset,
-static void emac_remove(struct ocp_device *ocpdev)
-{
- struct net_device *dev = ocp_get_drvdata(ocpdev);
- struct ocp_enet_private *ep = dev->priv;
-
- /* FIXME: locking, races, ... */
- ep->going_away = 1;
- ocp_set_drvdata(ocpdev, NULL);
- if (ep->rgmii_dev)
- emac_close_rgmii(ep->rgmii_dev);
- if (ep->zmii_dev)
- emac_close_zmii(ep->zmii_dev);
-
- unregister_netdev(dev);
- del_timer_sync(&ep->link_timer);
- mal_unregister_commac(ep->mal, &ep->commac);
- iounmap((void *)ep->emacp);
- kfree(dev);
-}
-
-struct mal_commac_ops emac_commac_ops = {
- .txeob = &emac_txeob_dev,
- .txde = &emac_txde_dev,
- .rxeob = &emac_rxeob_dev,
- .rxde = &emac_rxde_dev,
+ .get_ringparam = emac_ethtool_get_ringparam,
+ .get_pauseparam = emac_ethtool_get_pauseparam,
+
+ .get_rx_csum = emac_ethtool_get_rx_csum,
+
+ .get_strings = emac_ethtool_get_strings,
+ .get_stats_count = emac_ethtool_get_stats_count,
+ .get_ethtool_stats = emac_ethtool_get_ethtool_stats,
+
+ .get_link = ethtool_op_get_link,
+ .get_tx_csum = ethtool_op_get_tx_csum,
+ .get_sg = ethtool_op_get_sg,
};
-#ifdef CONFIG_NET_POLL_CONTROLLER
-static void emac_netpoll(struct net_device *ndev)
+static int emac_ioctl(struct net_device *ndev, struct ifreq *rq, int cmd)
{
- emac_rxeob_dev((void *)ndev, 0);
- emac_txeob_dev((void *)ndev, 0);
+ struct ocp_enet_private *dev = ndev->priv;
+ uint16_t *data = (uint16_t *) & rq->ifr_ifru;
+
+ DBG("%d: ioctl %08x" NL, dev->def->index, cmd);
+
+ if (dev->phy.address < 0)
+ return -EOPNOTSUPP;
+
+ switch (cmd) {
+ case SIOCGMIIPHY:
+ case SIOCDEVPRIVATE:
+ data[0] = dev->phy.address;
+ /* Fall through */
+ case SIOCGMIIREG:
+ case SIOCDEVPRIVATE + 1:
+ data[3] = emac_mdio_read(ndev, dev->phy.address, data[1]);
+ return 0;
+
+ case SIOCSMIIREG:
+ case SIOCDEVPRIVATE + 2:
+ if (!capable(CAP_NET_ADMIN))
+ return -EPERM;
+ emac_mdio_write(ndev, dev->phy.address, data[1], data[2]);
+ return 0;
+ default:
+ return -EOPNOTSUPP;
+ }
}
-#endif
-static int emac_init_device(struct ocp_device *ocpdev, struct ibm_ocp_mal *mal)
+static int __init emac_probe(struct ocp_device *ocpdev)
{
- int deferred_init = 0;
- int rc = 0, i;
+ struct ocp_func_emac_data *emacdata = ocpdev->def->additions;
struct net_device *ndev;
- struct ocp_enet_private *ep;
- struct ocp_func_emac_data *emacdata;
- int commac_reg = 0;
- u32 phy_map;
+ struct ocp_device *maldev;
+ struct ocp_enet_private *dev;
+ int err, i;
+
+ DBG("%d: probe" NL, ocpdev->def->index);
- emacdata = (struct ocp_func_emac_data *)ocpdev->def->additions;
if (!emacdata) {
printk(KERN_ERR "emac%d: Missing additional data!\n",
ocpdev->def->index);
@@ -1738,304 +1938,312 @@ static int emac_init_device(struct ocp_device *ocpdev, struct ibm_ocp_mal *mal)
/* Allocate our net_device structure */
ndev = alloc_etherdev(sizeof(struct ocp_enet_private));
- if (ndev == NULL) {
- printk(KERN_ERR
- "emac%d: Could not allocate ethernet device.\n",
+ if (!ndev) {
+ printk(KERN_ERR "emac%d: could not allocate ethernet device!\n",
ocpdev->def->index);
return -ENOMEM;
}
- ep = ndev->priv;
- ep->ndev = ndev;
- ep->ocpdev = ocpdev;
- ndev->irq = ocpdev->def->irq;
- ep->wol_irq = emacdata->wol_irq;
- if (emacdata->mdio_idx >= 0) {
- if (emacdata->mdio_idx == ocpdev->def->index) {
- /* Set the common MDIO net_device */
- mdio_ndev = ndev;
- deferred_init = 1;
- }
- ep->mdio_dev = mdio_ndev;
- } else {
- ep->mdio_dev = ndev;
- }
+ dev = ndev->priv;
+ dev->ndev = ndev;
+ dev->ldev = &ocpdev->dev;
+ dev->def = ocpdev->def;
+ SET_MODULE_OWNER(ndev);
- ocp_set_drvdata(ocpdev, ndev);
-
- spin_lock_init(&ep->lock);
-
- /* Fill out MAL informations and register commac */
- ep->mal = mal;
- ep->mal_tx_chan = emacdata->mal_tx_chan;
- ep->mal_rx_chan = emacdata->mal_rx_chan;
- ep->commac.ops = &emac_commac_ops;
- ep->commac.dev = ndev;
- ep->commac.tx_chan_mask = MAL_CHAN_MASK(ep->mal_tx_chan);
- ep->commac.rx_chan_mask = MAL_CHAN_MASK(ep->mal_rx_chan);
- rc = mal_register_commac(ep->mal, &ep->commac);
- if (rc != 0)
- goto bail;
- commac_reg = 1;
-
- /* Map our MMIOs */
- ep->emacp = (emac_t *) ioremap(ocpdev->def->paddr, sizeof(emac_t));
-
- /* Check if we need to attach to a ZMII */
- if (emacdata->zmii_idx >= 0) {
- ep->zmii_input = emacdata->zmii_mux;
- ep->zmii_dev =
- ocp_find_device(OCP_ANY_ID, OCP_FUNC_ZMII,
- emacdata->zmii_idx);
- if (ep->zmii_dev == NULL)
- printk(KERN_WARNING
- "emac%d: ZMII %d requested but not found !\n",
- ocpdev->def->index, emacdata->zmii_idx);
- else if ((rc =
- emac_init_zmii(ep->zmii_dev, ep->zmii_input,
- emacdata->phy_mode)) != 0)
- goto bail;
+ /* Find MAL device we are connected to */
+ maldev =
+ ocp_find_device(OCP_VENDOR_IBM, OCP_FUNC_MAL, emacdata->mal_idx);
+ if (!maldev) {
+ printk(KERN_ERR "emac%d: unknown mal%d device!\n",
+ dev->def->index, emacdata->mal_idx);
+ err = -ENODEV;
+ goto out;
+ }
+ dev->mal = ocp_get_drvdata(maldev);
+ if (!dev->mal) {
+ printk(KERN_ERR "emac%d: mal%d hasn't been initialized yet!\n",
+ dev->def->index, emacdata->mal_idx);
+ err = -ENODEV;
+ goto out;
}
- /* Check if we need to attach to a RGMII */
- if (emacdata->rgmii_idx >= 0) {
- ep->rgmii_input = emacdata->rgmii_mux;
- ep->rgmii_dev =
- ocp_find_device(OCP_ANY_ID, OCP_FUNC_RGMII,
- emacdata->rgmii_idx);
- if (ep->rgmii_dev == NULL)
- printk(KERN_WARNING
- "emac%d: RGMII %d requested but not found !\n",
- ocpdev->def->index, emacdata->rgmii_idx);
- else if ((rc =
- emac_init_rgmii(ep->rgmii_dev, ep->rgmii_input,
- emacdata->phy_mode)) != 0)
- goto bail;
+ /* Register with MAL */
+ dev->commac.ops = &emac_commac_ops;
+ dev->commac.dev = dev;
+ dev->commac.tx_chan_mask = MAL_CHAN_MASK(emacdata->mal_tx_chan);
+ dev->commac.rx_chan_mask = MAL_CHAN_MASK(emacdata->mal_rx_chan);
+ err = mal_register_commac(dev->mal, &dev->commac);
+ if (err) {
+ printk(KERN_ERR "emac%d: failed to register with mal%d!\n",
+ dev->def->index, emacdata->mal_idx);
+ goto out;
+ }
+ dev->rx_skb_size = emac_rx_skb_size(ndev->mtu);
+ dev->rx_sync_size = emac_rx_sync_size(ndev->mtu);
+
+ /* Get pointers to BD rings */
+ dev->tx_desc =
+ dev->mal->bd_virt + mal_tx_bd_offset(dev->mal,
+ emacdata->mal_tx_chan);
+ dev->rx_desc =
+ dev->mal->bd_virt + mal_rx_bd_offset(dev->mal,
+ emacdata->mal_rx_chan);
+
+ DBG("%d: tx_desc %p" NL, ocpdev->def->index, dev->tx_desc);
+ DBG("%d: rx_desc %p" NL, ocpdev->def->index, dev->rx_desc);
+
+ /* Clean rings */
+ memset(dev->tx_desc, 0, NUM_TX_BUFF * sizeof(struct mal_descriptor));
+ memset(dev->rx_desc, 0, NUM_RX_BUFF * sizeof(struct mal_descriptor));
+
+ /* If we depend on another EMAC for MDIO, check whether it was probed already */
+ if (emacdata->mdio_idx >= 0 && emacdata->mdio_idx != ocpdev->def->index) {
+ struct ocp_device *mdiodev =
+ ocp_find_device(OCP_VENDOR_IBM, OCP_FUNC_EMAC,
+ emacdata->mdio_idx);
+ if (!mdiodev) {
+ printk(KERN_ERR "emac%d: unknown emac%d device!\n",
+ dev->def->index, emacdata->mdio_idx);
+ err = -ENODEV;
+ goto out2;
+ }
+ dev->mdio_dev = ocp_get_drvdata(mdiodev);
+ if (!dev->mdio_dev) {
+ printk(KERN_ERR
+ "emac%d: emac%d hasn't been initialized yet!\n",
+ dev->def->index, emacdata->mdio_idx);
+ err = -ENODEV;
+ goto out2;
+ }
}
- /* Check if we need to attach to a TAH */
- if (emacdata->tah_idx >= 0) {
- ep->tah_dev =
- ocp_find_device(OCP_ANY_ID, OCP_FUNC_TAH,
- emacdata->tah_idx);
- if (ep->tah_dev == NULL)
- printk(KERN_WARNING
- "emac%d: TAH %d requested but not found !\n",
- ocpdev->def->index, emacdata->tah_idx);
- else if ((rc = emac_init_tah(ep)) != 0)
- goto bail;
+ /* Attach to ZMII, if needed */
+ if ((err = zmii_attach(dev)) != 0)
+ goto out2;
+
+ /* Attach to RGMII, if needed */
+ if ((err = rgmii_attach(dev)) != 0)
+ goto out3;
+
+ /* Attach to TAH, if needed */
+ if ((err = tah_attach(dev)) != 0)
+ goto out4;
+
+ /* Map EMAC regs */
+ dev->emacp =
+ (struct emac_regs *)ioremap(dev->def->paddr,
+ sizeof(struct emac_regs));
+ if (!dev->emacp) {
+ printk(KERN_ERR "emac%d: could not ioremap device registers!\n",
+ dev->def->index);
+ err = -ENOMEM;
+ goto out5;
}
- if (deferred_init) {
- if (!list_empty(&emac_init_list)) {
- struct list_head *entry;
- struct emac_def_dev *ddev;
+ /* Fill in MAC address */
+ for (i = 0; i < 6; ++i)
+ ndev->dev_addr[i] = emacdata->mac_addr[i];
- list_for_each(entry, &emac_init_list) {
- ddev =
- list_entry(entry, struct emac_def_dev,
- link);
- emac_init_device(ddev->ocpdev, ddev->mal);
- }
+ /* Set some link defaults before we can find out real parameters */
+ dev->phy.speed = SPEED_100;
+ dev->phy.duplex = DUPLEX_FULL;
+ dev->phy.autoneg = AUTONEG_DISABLE;
+ dev->phy.pause = dev->phy.asym_pause = 0;
+ init_timer(&dev->link_timer);
+ dev->link_timer.function = emac_link_timer;
+ dev->link_timer.data = (unsigned long)dev;
+
+ /* Find PHY if any */
+ dev->phy.dev = ndev;
+ dev->phy.mode = emacdata->phy_mode;
+ if (emacdata->phy_map != 0xffffffff) {
+ u32 phy_map = emacdata->phy_map | busy_phy_map;
+ u32 adv;
+
+ DBG("%d: PHY maps %08x %08x" NL, dev->def->index,
+ emacdata->phy_map, busy_phy_map);
+
+ EMAC_RX_CLK_TX(dev->def->index);
+
+ dev->phy.mdio_read = emac_mdio_read;
+ dev->phy.mdio_write = emac_mdio_write;
+
+ /* Configure EMAC with defaults so we can at least use MDIO
+ * This is needed mostly for 440GX
+ */
+ if (emac_phy_gpcs(dev->phy.mode)) {
+ /* XXX
+ * Make GPCS PHY address equal to EMAC index.
+ * We probably should take into account busy_phy_map
+ * and/or phy_map here.
+ */
+ dev->phy.address = dev->def->index;
}
- }
+
+ emac_configure(dev);
- /* Init link monitoring timer */
- init_timer(&ep->link_timer);
- ep->link_timer.function = emac_link_timer;
- ep->link_timer.data = (unsigned long)ep;
- ep->timer_ticks = 0;
-
- /* Fill up the mii_phy structure */
- ep->phy_mii.dev = ndev;
- ep->phy_mii.mdio_read = emac_phy_read;
- ep->phy_mii.mdio_write = emac_phy_write;
- ep->phy_mii.mode = emacdata->phy_mode;
-
- /* Find PHY */
- phy_map = emacdata->phy_map | busy_phy_map;
- for (i = 0; i <= 0x1f; i++, phy_map >>= 1) {
- if ((phy_map & 0x1) == 0) {
- int val = emac_phy_read(ndev, i, MII_BMCR);
- if (val != 0xffff && val != -1)
- break;
+ for (i = 0; i < 0x20; phy_map >>= 1, ++i)
+ if (!(phy_map & 1)) {
+ int r;
+ busy_phy_map |= 1 << i;
+
+ /* Quick check if there is a PHY at the address */
+ r = emac_mdio_read(dev->ndev, i, MII_BMCR);
+ if (r == 0xffff || r < 0)
+ continue;
+ if (!mii_phy_probe(&dev->phy, i))
+ break;
+ }
+ if (i == 0x20) {
+ printk(KERN_WARNING "emac%d: can't find PHY!\n",
+ dev->def->index);
+ goto out6;
}
- }
- if (i == 0x20) {
- printk(KERN_WARNING "emac%d: Can't find PHY.\n",
- ocpdev->def->index);
- rc = -ENODEV;
- goto bail;
- }
- busy_phy_map |= 1 << i;
- ep->mii_phy_addr = i;
- rc = mii_phy_probe(&ep->phy_mii, i);
- if (rc) {
- printk(KERN_WARNING "emac%d: Failed to probe PHY type.\n",
- ocpdev->def->index);
- rc = -ENODEV;
- goto bail;
- }
-
- /* Disable any PHY features not supported by the platform */
- ep->phy_mii.def->features &= ~emacdata->phy_feat_exc;
- /* Setup initial PHY config & startup aneg */
- if (ep->phy_mii.def->ops->init)
- ep->phy_mii.def->ops->init(&ep->phy_mii);
- netif_carrier_off(ndev);
- if (ep->phy_mii.def->features & SUPPORTED_Autoneg)
- ep->want_autoneg = 1;
- else {
- ep->want_autoneg = 0;
+ /* Init PHY */
+ if (dev->phy.def->ops->init)
+ dev->phy.def->ops->init(&dev->phy);
- /* Select highest supported speed/duplex */
- if (ep->phy_mii.def->features & SUPPORTED_1000baseT_Full) {
- ep->phy_mii.speed = SPEED_1000;
- ep->phy_mii.duplex = DUPLEX_FULL;
- } else if (ep->phy_mii.def->features &
- SUPPORTED_1000baseT_Half) {
- ep->phy_mii.speed = SPEED_1000;
- ep->phy_mii.duplex = DUPLEX_HALF;
- } else if (ep->phy_mii.def->features &
- SUPPORTED_100baseT_Full) {
- ep->phy_mii.speed = SPEED_100;
- ep->phy_mii.duplex = DUPLEX_FULL;
- } else if (ep->phy_mii.def->features &
- SUPPORTED_100baseT_Half) {
- ep->phy_mii.speed = SPEED_100;
- ep->phy_mii.duplex = DUPLEX_HALF;
- } else if (ep->phy_mii.def->features &
- SUPPORTED_10baseT_Full) {
- ep->phy_mii.speed = SPEED_10;
- ep->phy_mii.duplex = DUPLEX_FULL;
+ /* Disable any PHY features not supported by the platform */
+ dev->phy.def->features &= ~emacdata->phy_feat_exc;
+
+ /* Setup initial link parameters */
+ if (dev->phy.features & SUPPORTED_Autoneg) {
+ adv = dev->phy.features;
+#if !defined(CONFIG_40x)
+ adv |= ADVERTISED_Pause | ADVERTISED_Asym_Pause;
+#endif
+ /* Restart autonegotiation */
+ dev->phy.def->ops->setup_aneg(&dev->phy, adv);
} else {
- ep->phy_mii.speed = SPEED_10;
- ep->phy_mii.duplex = DUPLEX_HALF;
+ u32 f = dev->phy.def->features;
+ int speed = SPEED_10, fd = DUPLEX_HALF;
+
+ /* Select highest supported speed/duplex */
+ if (f & SUPPORTED_1000baseT_Full) {
+ speed = SPEED_1000;
+ fd = DUPLEX_FULL;
+ } else if (f & SUPPORTED_1000baseT_Half)
+ speed = SPEED_1000;
+ else if (f & SUPPORTED_100baseT_Full) {
+ speed = SPEED_100;
+ fd = DUPLEX_FULL;
+ } else if (f & SUPPORTED_100baseT_Half)
+ speed = SPEED_100;
+ else if (f & SUPPORTED_10baseT_Full)
+ fd = DUPLEX_FULL;
+
+ /* Force link parameters */
+ dev->phy.def->ops->setup_forced(&dev->phy, speed, fd);
}
- }
- emac_start_link(ep, NULL);
+ } else {
+ emac_reset(dev);
- /* read the MAC Address */
- for (i = 0; i < 6; i++)
- ndev->dev_addr[i] = emacdata->mac_addr[i];
+ /* PHY-less configuration.
+ * XXX I probably should move these settings to emacdata
+ */
+ dev->phy.address = -1;
+ dev->phy.features = SUPPORTED_100baseT_Full | SUPPORTED_MII;
+ dev->phy.pause = 1;
+ }
/* Fill in the driver function table */
ndev->open = &emac_open;
- ndev->hard_start_xmit = &emac_start_xmit;
+ if (dev->tah_dev) {
+ ndev->hard_start_xmit = &emac_start_xmit_sg;
+ ndev->features |= NETIF_F_IP_CSUM | NETIF_F_SG;
+ } else
+ ndev->hard_start_xmit = &emac_start_xmit;
+ ndev->tx_timeout = &emac_full_tx_reset;
+ ndev->watchdog_timeo = 5 * HZ;
ndev->stop = &emac_close;
ndev->get_stats = &emac_stats;
- if (emacdata->jumbo)
- ndev->change_mtu = &emac_change_mtu;
- ndev->set_mac_address = &emac_set_mac_address;
ndev->set_multicast_list = &emac_set_multicast_list;
ndev->do_ioctl = &emac_ioctl;
+ if (emac_phy_supports_gige(emacdata->phy_mode)) {
+ ndev->change_mtu = &emac_change_mtu;
+ dev->commac.ops = &emac_commac_sg_ops;
+ }
SET_ETHTOOL_OPS(ndev, &emac_ethtool_ops);
- if (emacdata->tah_idx >= 0)
- ndev->features = NETIF_F_IP_CSUM | NETIF_F_SG;
-#ifdef CONFIG_NET_POLL_CONTROLLER
- ndev->poll_controller = emac_netpoll;
-#endif
- SET_MODULE_OWNER(ndev);
+ netif_carrier_off(ndev);
+ netif_stop_queue(ndev);
+
+ err = register_netdev(ndev);
+ if (err) {
+ printk(KERN_ERR "emac%d: failed to register net device (%d)!\n",
+ dev->def->index, err);
+ goto out6;
+ }
- rc = register_netdev(ndev);
- if (rc != 0)
- goto bail;
+ ocp_set_drvdata(ocpdev, dev);
- printk("%s: IBM emac, MAC %02x:%02x:%02x:%02x:%02x:%02x\n",
- ndev->name,
+ printk("%s: emac%d, MAC %02x:%02x:%02x:%02x:%02x:%02x\n",
+ ndev->name, dev->def->index,
ndev->dev_addr[0], ndev->dev_addr[1], ndev->dev_addr[2],
ndev->dev_addr[3], ndev->dev_addr[4], ndev->dev_addr[5]);
- printk(KERN_INFO "%s: Found %s PHY (0x%02x)\n",
- ndev->name, ep->phy_mii.def->name, ep->mii_phy_addr);
- bail:
- if (rc && commac_reg)
- mal_unregister_commac(ep->mal, &ep->commac);
- if (rc && ndev)
- kfree(ndev);
+ if (dev->phy.address >= 0)
+ printk("%s: found %s PHY (0x%02x)\n", ndev->name,
+ dev->phy.def->name, dev->phy.address);
- return rc;
-}
-
-static int emac_probe(struct ocp_device *ocpdev)
-{
- struct ocp_device *maldev;
- struct ibm_ocp_mal *mal;
- struct ocp_func_emac_data *emacdata;
-
- emacdata = (struct ocp_func_emac_data *)ocpdev->def->additions;
- if (emacdata == NULL) {
- printk(KERN_ERR "emac%d: Missing additional datas !\n",
- ocpdev->def->index);
- return -ENODEV;
- }
-
- /* Get the MAL device */
- maldev = ocp_find_device(OCP_ANY_ID, OCP_FUNC_MAL, emacdata->mal_idx);
- if (maldev == NULL) {
- printk("No maldev\n");
- return -ENODEV;
- }
- /*
- * Get MAL driver data, it must be here due to link order.
- * When the driver is modularized, symbol dependencies will
- * ensure the MAL driver is already present if built as a
- * module.
- */
- mal = (struct ibm_ocp_mal *)ocp_get_drvdata(maldev);
- if (mal == NULL) {
- printk("No maldrv\n");
- return -ENODEV;
- }
-
- /* If we depend on another EMAC for MDIO, wait for it to show up */
- if (emacdata->mdio_idx >= 0 &&
- (emacdata->mdio_idx != ocpdev->def->index) && !mdio_ndev) {
- struct emac_def_dev *ddev;
- /* Add this index to the deferred init table */
- ddev = kmalloc(sizeof(struct emac_def_dev), GFP_KERNEL);
- ddev->ocpdev = ocpdev;
- ddev->mal = mal;
- list_add_tail(&ddev->link, &emac_init_list);
- } else {
- emac_init_device(ocpdev, mal);
- }
+ emac_dbg_register(dev->def->index, dev);
return 0;
+ out6:
+ iounmap((void *)dev->emacp);
+ out5:
+ tah_fini(dev->tah_dev);
+ out4:
+ rgmii_fini(dev->rgmii_dev, dev->rgmii_input);
+ out3:
+ zmii_fini(dev->zmii_dev, dev->zmii_input);
+ out2:
+ mal_unregister_commac(dev->mal, &dev->commac);
+ out:
+ kfree(ndev);
+ return err;
}
-/* Structure for a device driver */
static struct ocp_device_id emac_ids[] = {
- {.vendor = OCP_ANY_ID,.function = OCP_FUNC_EMAC},
- {.vendor = OCP_VENDOR_INVALID}
+ { .vendor = OCP_VENDOR_IBM, .function = OCP_FUNC_EMAC },
+ { .vendor = OCP_VENDOR_INVALID}
};
static struct ocp_driver emac_driver = {
.name = "emac",
.id_table = emac_ids,
-
.probe = emac_probe,
.remove = emac_remove,
};
static int __init emac_init(void)
{
- printk(KERN_INFO DRV_NAME ": " DRV_DESC ", version " DRV_VERSION "\n");
- printk(KERN_INFO "Maintained by " DRV_AUTHOR "\n");
+ printk(KERN_INFO DRV_DESC ", version " DRV_VERSION "\n");
+
+ DBG(": init" NL);
- if (skb_res > 2) {
- printk(KERN_WARNING "Invalid skb_res: %d, cropping to 2\n",
- skb_res);
- skb_res = 2;
+ if (mal_init())
+ return -ENODEV;
+
+ EMAC_CLK_INTERNAL;
+ if (ocp_register_driver(&emac_driver)) {
+ EMAC_CLK_EXTERNAL;
+ ocp_unregister_driver(&emac_driver);
+ mal_exit();
+ return -ENODEV;
}
+ EMAC_CLK_EXTERNAL;
- return ocp_register_driver(&emac_driver);
+ emac_init_debug();
+ return 0;
}
static void __exit emac_exit(void)
{
+ DBG(": exit" NL);
ocp_unregister_driver(&emac_driver);
+ mal_exit();
+ emac_fini_debug();
}
module_init(emac_init);
diff --git a/drivers/net/ibm_emac/ibm_emac_core.h b/drivers/net/ibm_emac/ibm_emac_core.h
index 97e6e1ea8c89..e9b44d030ac3 100644
--- a/drivers/net/ibm_emac/ibm_emac_core.h
+++ b/drivers/net/ibm_emac/ibm_emac_core.h
@@ -1,146 +1,221 @@
/*
- * ibm_emac_core.h
+ * drivers/net/ibm_emac/ibm_emac_core.h
*
- * Ethernet driver for the built in ethernet on the IBM 405 PowerPC
- * processor.
+ * Driver for PowerPC 4xx on-chip ethernet controller.
*
- * Armin Kuster akuster@mvista.com
- * Sept, 2001
+ * Copyright (c) 2004, 2005 Zultys Technologies.
+ * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
*
- * Orignial driver
- * Johnnie Peters
- * jpeters@mvista.com
- *
- * Copyright 2000 MontaVista Softare Inc.
+ * Based on original work by
+ * Armin Kuster <akuster@mvista.com>
+ * Johnnie Peters <jpeters@mvista.com>
+ * Copyright 2000, 2001 MontaVista Softare 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.
+ *
*/
+#ifndef __IBM_EMAC_CORE_H_
+#define __IBM_EMAC_CORE_H_
-#ifndef _IBM_EMAC_CORE_H_
-#define _IBM_EMAC_CORE_H_
-
+#include <linux/config.h>
#include <linux/netdevice.h>
+#include <linux/dma-mapping.h>
#include <asm/ocp.h>
-#include <asm/mmu.h> /* For phys_addr_t */
#include "ibm_emac.h"
#include "ibm_emac_phy.h"
-#include "ibm_emac_rgmii.h"
#include "ibm_emac_zmii.h"
+#include "ibm_emac_rgmii.h"
#include "ibm_emac_mal.h"
#include "ibm_emac_tah.h"
-#ifndef CONFIG_IBM_EMAC_TXB
-#define NUM_TX_BUFF 64
-#define NUM_RX_BUFF 64
-#else
-#define NUM_TX_BUFF CONFIG_IBM_EMAC_TXB
-#define NUM_RX_BUFF CONFIG_IBM_EMAC_RXB
-#endif
+#define NUM_TX_BUFF CONFIG_IBM_EMAC_TXB
+#define NUM_RX_BUFF CONFIG_IBM_EMAC_RXB
-/* 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.
- */
-#ifndef CONFIG_IBM_EMAC_SKBRES
-#define SKB_RES 2
-#else
-#define SKB_RES CONFIG_IBM_EMAC_SKBRES
+/* Simple sanity check */
+#if NUM_TX_BUFF > 256 || NUM_RX_BUFF > 256
+#error Invalid number of buffer descriptors (greater than 256)
#endif
-/* Note about alignement. alloc_skb() returns a cache line
- * aligned buffer. However, dev_alloc_skb() will add 16 more
- * bytes and "reserve" them, so our buffer will actually end
- * on a half cache line. What we do is to use directly
- * alloc_skb, allocate 16 more bytes to match the total amount
- * allocated by dev_alloc_skb(), but we don't reserve.
+// XXX
+#define EMAC_MIN_MTU 46
+#define EMAC_MAX_MTU 9000
+
+/* Maximum L2 header length (VLAN tagged, no FCS) */
+#define EMAC_MTU_OVERHEAD (6 * 2 + 2 + 4)
+
+/* RX BD size for the given MTU */
+static inline int emac_rx_size(int mtu)
+{
+ if (mtu > ETH_DATA_LEN)
+ return MAL_MAX_RX_SIZE;
+ else
+ return mal_rx_size(ETH_DATA_LEN + EMAC_MTU_OVERHEAD);
+}
+
+#define EMAC_DMA_ALIGN(x) ALIGN((x), dma_get_cache_alignment())
+
+#define EMAC_RX_SKB_HEADROOM \
+ EMAC_DMA_ALIGN(CONFIG_IBM_EMAC_RX_SKB_HEADROOM)
+
+/* Size of RX skb for the given MTU */
+static inline int emac_rx_skb_size(int mtu)
+{
+ int size = max(mtu + EMAC_MTU_OVERHEAD, emac_rx_size(mtu));
+ return EMAC_DMA_ALIGN(size + 2) + EMAC_RX_SKB_HEADROOM;
+}
+
+/* RX DMA sync size */
+static inline int emac_rx_sync_size(int mtu)
+{
+ return EMAC_DMA_ALIGN(emac_rx_size(mtu) + 2);
+}
+
+/* Driver statistcs is split into two parts to make it more cache friendly:
+ * - normal statistics (packet count, etc)
+ * - error statistics
+ *
+ * When statistics is requested by ethtool, these parts are concatenated,
+ * normal one goes first.
+ *
+ * Please, keep these structures in sync with emac_stats_keys.
*/
-#define MAX_NUM_BUF_DESC 255
-#define DESC_BUF_SIZE 4080 /* max 4096-16 */
-#define DESC_BUF_SIZE_REG (DESC_BUF_SIZE / 16)
-
-/* Transmitter timeout. */
-#define TX_TIMEOUT (2*HZ)
-
-/* MDIO latency delay */
-#define MDIO_DELAY 250
-
-/* Power managment shift registers */
-#define IBM_CPM_EMMII 0 /* Shift value for MII */
-#define IBM_CPM_EMRX 1 /* Shift value for recv */
-#define IBM_CPM_EMTX 2 /* Shift value for MAC */
-#define IBM_CPM_EMAC(x) (((x)>>IBM_CPM_EMMII) | ((x)>>IBM_CPM_EMRX) | ((x)>>IBM_CPM_EMTX))
-
-#define ENET_HEADER_SIZE 14
-#define ENET_FCS_SIZE 4
-#define ENET_DEF_MTU_SIZE 1500
-#define ENET_DEF_BUF_SIZE (ENET_DEF_MTU_SIZE + ENET_HEADER_SIZE + ENET_FCS_SIZE)
-#define EMAC_MIN_FRAME 64
-#define EMAC_MAX_FRAME 9018
-#define EMAC_MIN_MTU (EMAC_MIN_FRAME - ENET_HEADER_SIZE - ENET_FCS_SIZE)
-#define EMAC_MAX_MTU (EMAC_MAX_FRAME - ENET_HEADER_SIZE - ENET_FCS_SIZE)
-
-#ifdef CONFIG_IBM_EMAC_ERRMSG
-void emac_serr_dump_0(struct net_device *dev);
-void emac_serr_dump_1(struct net_device *dev);
-void emac_err_dump(struct net_device *dev, int em0isr);
-void emac_phy_dump(struct net_device *);
-void emac_desc_dump(struct net_device *);
-void emac_mac_dump(struct net_device *);
-void emac_mal_dump(struct net_device *);
-#else
-#define emac_serr_dump_0(dev) do { } while (0)
-#define emac_serr_dump_1(dev) do { } while (0)
-#define emac_err_dump(dev,x) do { } while (0)
-#define emac_phy_dump(dev) do { } while (0)
-#define emac_desc_dump(dev) do { } while (0)
-#define emac_mac_dump(dev) do { } while (0)
-#define emac_mal_dump(dev) do { } while (0)
-#endif
+
+/* Normal TX/RX Statistics */
+struct ibm_emac_stats {
+ u64 rx_packets;
+ u64 rx_bytes;
+ u64 tx_packets;
+ u64 tx_bytes;
+ u64 rx_packets_csum;
+ u64 tx_packets_csum;
+};
+
+/* Error statistics */
+struct ibm_emac_error_stats {
+ u64 tx_undo;
+
+ /* Software RX Errors */
+ u64 rx_dropped_stack;
+ u64 rx_dropped_oom;
+ u64 rx_dropped_error;
+ u64 rx_dropped_resize;
+ u64 rx_dropped_mtu;
+ u64 rx_stopped;
+ /* BD reported RX errors */
+ u64 rx_bd_errors;
+ u64 rx_bd_overrun;
+ u64 rx_bd_bad_packet;
+ u64 rx_bd_runt_packet;
+ u64 rx_bd_short_event;
+ u64 rx_bd_alignment_error;
+ u64 rx_bd_bad_fcs;
+ u64 rx_bd_packet_too_long;
+ u64 rx_bd_out_of_range;
+ u64 rx_bd_in_range;
+ /* EMAC IRQ reported RX errors */
+ u64 rx_parity;
+ u64 rx_fifo_overrun;
+ u64 rx_overrun;
+ u64 rx_bad_packet;
+ u64 rx_runt_packet;
+ u64 rx_short_event;
+ u64 rx_alignment_error;
+ u64 rx_bad_fcs;
+ u64 rx_packet_too_long;
+ u64 rx_out_of_range;
+ u64 rx_in_range;
+
+ /* Software TX Errors */
+ u64 tx_dropped;
+ /* BD reported TX errors */
+ u64 tx_bd_errors;
+ u64 tx_bd_bad_fcs;
+ u64 tx_bd_carrier_loss;
+ u64 tx_bd_excessive_deferral;
+ u64 tx_bd_excessive_collisions;
+ u64 tx_bd_late_collision;
+ u64 tx_bd_multple_collisions;
+ u64 tx_bd_single_collision;
+ u64 tx_bd_underrun;
+ u64 tx_bd_sqe;
+ /* EMAC IRQ reported TX errors */
+ u64 tx_parity;
+ u64 tx_underrun;
+ u64 tx_sqe;
+ u64 tx_errors;
+};
+
+#define EMAC_ETHTOOL_STATS_COUNT ((sizeof(struct ibm_emac_stats) + \
+ sizeof(struct ibm_emac_error_stats)) \
+ / sizeof(u64))
struct ocp_enet_private {
- struct sk_buff *tx_skb[NUM_TX_BUFF];
- struct sk_buff *rx_skb[NUM_RX_BUFF];
- struct mal_descriptor *tx_desc;
- struct mal_descriptor *rx_desc;
- struct mal_descriptor *rx_dirty;
- struct net_device_stats stats;
- int tx_cnt;
- int rx_slot;
- int dirty_rx;
- int tx_slot;
- int ack_slot;
- int rx_buffer_size;
-
- struct mii_phy phy_mii;
- int mii_phy_addr;
- int want_autoneg;
- int timer_ticks;
- struct timer_list link_timer;
- struct net_device *mdio_dev;
-
- struct ocp_device *rgmii_dev;
- int rgmii_input;
-
- struct ocp_device *zmii_dev;
- int zmii_input;
-
- struct ibm_ocp_mal *mal;
- int mal_tx_chan, mal_rx_chan;
- struct mal_commac commac;
-
- struct ocp_device *tah_dev;
-
- int opened;
- int going_away;
- int wol_irq;
- emac_t *emacp;
- struct ocp_device *ocpdev;
- struct net_device *ndev;
- spinlock_t lock;
+ struct net_device *ndev; /* 0 */
+ struct emac_regs *emacp;
+
+ struct mal_descriptor *tx_desc;
+ int tx_cnt;
+ int tx_slot;
+ int ack_slot;
+
+ struct mal_descriptor *rx_desc;
+ int rx_slot;
+ struct sk_buff *rx_sg_skb; /* 1 */
+ int rx_skb_size;
+ int rx_sync_size;
+
+ struct ibm_emac_stats stats;
+ struct ocp_device *tah_dev;
+
+ struct ibm_ocp_mal *mal;
+ struct mal_commac commac;
+
+ struct sk_buff *tx_skb[NUM_TX_BUFF];
+ struct sk_buff *rx_skb[NUM_RX_BUFF];
+
+ struct ocp_device *zmii_dev;
+ int zmii_input;
+ struct ocp_enet_private *mdio_dev;
+ struct ocp_device *rgmii_dev;
+ int rgmii_input;
+
+ struct ocp_def *def;
+
+ struct mii_phy phy;
+ struct timer_list link_timer;
+ int reset_failed;
+
+ struct ibm_emac_error_stats estats;
+ struct net_device_stats nstats;
+
+ struct device* ldev;
};
-#endif /* _IBM_EMAC_CORE_H_ */
+
+/* Ethtool get_regs complex data.
+ * We want to get not just EMAC registers, but also MAL, ZMII, RGMII, TAH
+ * when available.
+ *
+ * Returned BLOB consists of the ibm_emac_ethtool_regs_hdr,
+ * MAL registers, EMAC registers and optional ZMII, RGMII, TAH registers.
+ * Each register component is preceded with emac_ethtool_regs_subhdr.
+ * Order of the optional headers follows their relative bit posititions
+ * in emac_ethtool_regs_hdr.components
+ */
+#define EMAC_ETHTOOL_REGS_ZMII 0x00000001
+#define EMAC_ETHTOOL_REGS_RGMII 0x00000002
+#define EMAC_ETHTOOL_REGS_TAH 0x00000004
+
+struct emac_ethtool_regs_hdr {
+ u32 components;
+};
+
+struct emac_ethtool_regs_subhdr {
+ u32 version;
+ u32 index;
+};
+
+#endif /* __IBM_EMAC_CORE_H_ */
diff --git a/drivers/net/ibm_emac/ibm_emac_debug.c b/drivers/net/ibm_emac/ibm_emac_debug.c
index c8512046cf84..75d3b8639041 100644
--- a/drivers/net/ibm_emac/ibm_emac_debug.c
+++ b/drivers/net/ibm_emac/ibm_emac_debug.c
@@ -1,224 +1,213 @@
/*
- * ibm_ocp_debug.c
+ * drivers/net/ibm_emac/ibm_emac_debug.c
*
- * This has all the debug routines that where in *_enet.c
+ * Driver for PowerPC 4xx on-chip ethernet controller, debug print routines.
*
- * Armin Kuster akuster@mvista.com
- * April , 2002
- *
- * Copyright 2002 MontaVista Softare Inc.
+ * Copyright (c) 2004, 2005 Zultys Technologies
+ * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.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/config.h>
+#include <linux/init.h>
+#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/netdevice.h>
+#include <linux/sysrq.h>
#include <asm/io.h>
-#include "ibm_ocp_mal.h"
-#include "ibm_ocp_zmii.h"
-#include "ibm_ocp_enet.h"
-extern int emac_phy_read(struct net_device *dev, int mii_id, int reg);
+#include "ibm_emac_core.h"
+
+static void emac_desc_dump(int idx, struct ocp_enet_private *p)
+{
+ int i;
+ printk("** EMAC%d TX BDs **\n"
+ " tx_cnt = %d tx_slot = %d ack_slot = %d\n",
+ idx, p->tx_cnt, p->tx_slot, p->ack_slot);
+ for (i = 0; i < NUM_TX_BUFF / 2; ++i)
+ printk
+ ("bd[%2d] 0x%08x %c 0x%04x %4u - bd[%2d] 0x%08x %c 0x%04x %4u\n",
+ i, p->tx_desc[i].data_ptr, p->tx_skb[i] ? 'V' : ' ',
+ p->tx_desc[i].ctrl, p->tx_desc[i].data_len,
+ NUM_TX_BUFF / 2 + i,
+ p->tx_desc[NUM_TX_BUFF / 2 + i].data_ptr,
+ p->tx_skb[NUM_TX_BUFF / 2 + i] ? 'V' : ' ',
+ p->tx_desc[NUM_TX_BUFF / 2 + i].ctrl,
+ p->tx_desc[NUM_TX_BUFF / 2 + i].data_len);
+
+ printk("** EMAC%d RX BDs **\n"
+ " rx_slot = %d rx_stopped = %d rx_skb_size = %d rx_sync_size = %d\n"
+ " rx_sg_skb = 0x%p\n",
+ idx, p->rx_slot, p->commac.rx_stopped, p->rx_skb_size,
+ p->rx_sync_size, p->rx_sg_skb);
+ for (i = 0; i < NUM_RX_BUFF / 2; ++i)
+ printk
+ ("bd[%2d] 0x%08x %c 0x%04x %4u - bd[%2d] 0x%08x %c 0x%04x %4u\n",
+ i, p->rx_desc[i].data_ptr, p->rx_skb[i] ? 'V' : ' ',
+ p->rx_desc[i].ctrl, p->rx_desc[i].data_len,
+ NUM_RX_BUFF / 2 + i,
+ p->rx_desc[NUM_RX_BUFF / 2 + i].data_ptr,
+ p->rx_skb[NUM_RX_BUFF / 2 + i] ? 'V' : ' ',
+ p->rx_desc[NUM_RX_BUFF / 2 + i].ctrl,
+ p->rx_desc[NUM_RX_BUFF / 2 + i].data_len);
+}
+
+static void emac_mac_dump(int idx, struct ocp_enet_private *dev)
+{
+ struct emac_regs *p = dev->emacp;
+
+ printk("** EMAC%d registers **\n"
+ "MR0 = 0x%08x MR1 = 0x%08x TMR0 = 0x%08x TMR1 = 0x%08x\n"
+ "RMR = 0x%08x ISR = 0x%08x ISER = 0x%08x\n"
+ "IAR = %04x%08x VTPID = 0x%04x VTCI = 0x%04x\n"
+ "IAHT: 0x%04x 0x%04x 0x%04x 0x%04x "
+ "GAHT: 0x%04x 0x%04x 0x%04x 0x%04x\n"
+ "LSA = %04x%08x IPGVR = 0x%04x\n"
+ "STACR = 0x%08x TRTR = 0x%08x RWMR = 0x%08x\n"
+ "OCTX = 0x%08x OCRX = 0x%08x IPCR = 0x%08x\n",
+ idx, in_be32(&p->mr0), in_be32(&p->mr1),
+ in_be32(&p->tmr0), in_be32(&p->tmr1),
+ in_be32(&p->rmr), in_be32(&p->isr), in_be32(&p->iser),
+ in_be32(&p->iahr), in_be32(&p->ialr), in_be32(&p->vtpid),
+ in_be32(&p->vtci),
+ in_be32(&p->iaht1), in_be32(&p->iaht2), in_be32(&p->iaht3),
+ in_be32(&p->iaht4),
+ in_be32(&p->gaht1), in_be32(&p->gaht2), in_be32(&p->gaht3),
+ in_be32(&p->gaht4),
+ in_be32(&p->lsah), in_be32(&p->lsal), in_be32(&p->ipgvr),
+ in_be32(&p->stacr), in_be32(&p->trtr), in_be32(&p->rwmr),
+ in_be32(&p->octx), in_be32(&p->ocrx), in_be32(&p->ipcr)
+ );
+
+ emac_desc_dump(idx, dev);
+}
+
+static void emac_mal_dump(struct ibm_ocp_mal *mal)
+{
+ struct ocp_func_mal_data *maldata = mal->def->additions;
+ int i;
+
+ printk("** MAL%d Registers **\n"
+ "CFG = 0x%08x ESR = 0x%08x IER = 0x%08x\n"
+ "TX|CASR = 0x%08x CARR = 0x%08x EOBISR = 0x%08x DEIR = 0x%08x\n"
+ "RX|CASR = 0x%08x CARR = 0x%08x EOBISR = 0x%08x DEIR = 0x%08x\n",
+ mal->def->index,
+ get_mal_dcrn(mal, MAL_CFG), get_mal_dcrn(mal, MAL_ESR),
+ get_mal_dcrn(mal, MAL_IER),
+ get_mal_dcrn(mal, MAL_TXCASR), get_mal_dcrn(mal, MAL_TXCARR),
+ get_mal_dcrn(mal, MAL_TXEOBISR), get_mal_dcrn(mal, MAL_TXDEIR),
+ get_mal_dcrn(mal, MAL_RXCASR), get_mal_dcrn(mal, MAL_RXCARR),
+ get_mal_dcrn(mal, MAL_RXEOBISR), get_mal_dcrn(mal, MAL_RXDEIR)
+ );
+
+ printk("TX|");
+ for (i = 0; i < maldata->num_tx_chans; ++i) {
+ if (i && !(i % 4))
+ printk("\n ");
+ printk("CTP%d = 0x%08x ", i, get_mal_dcrn(mal, MAL_TXCTPR(i)));
+ }
+ printk("\nRX|");
+ for (i = 0; i < maldata->num_rx_chans; ++i) {
+ if (i && !(i % 4))
+ printk("\n ");
+ printk("CTP%d = 0x%08x ", i, get_mal_dcrn(mal, MAL_RXCTPR(i)));
+ }
+ printk("\n ");
+ for (i = 0; i < maldata->num_rx_chans; ++i) {
+ u32 r = get_mal_dcrn(mal, MAL_RCBS(i));
+ if (i && !(i % 3))
+ printk("\n ");
+ printk("RCBS%d = 0x%08x (%d) ", i, r, r * 16);
+ }
+ printk("\n");
+}
+
+static struct ocp_enet_private *__emacs[4];
+static struct ibm_ocp_mal *__mals[1];
-void emac_phy_dump(struct net_device *dev)
+void emac_dbg_register(int idx, struct ocp_enet_private *dev)
{
- struct ocp_enet_private *fep = dev->priv;
- unsigned long i;
- uint data;
-
- printk(KERN_DEBUG " Prepare for Phy dump....\n");
- for (i = 0; i < 0x1A; i++) {
- data = emac_phy_read(dev, fep->mii_phy_addr, i);
- printk(KERN_DEBUG "Phy reg 0x%lx ==> %4x\n", i, data);
- if (i == 0x07)
- i = 0x0f;
+ unsigned long flags;
+
+ if (idx >= sizeof(__emacs) / sizeof(__emacs[0])) {
+ printk(KERN_WARNING
+ "invalid index %d when registering EMAC for debugging\n",
+ idx);
+ return;
}
+
+ local_irq_save(flags);
+ __emacs[idx] = dev;
+ local_irq_restore(flags);
}
-void emac_desc_dump(struct net_device *dev)
+void mal_dbg_register(int idx, struct ibm_ocp_mal *mal)
{
- struct ocp_enet_private *fep = dev->priv;
- int curr_slot;
-
- printk(KERN_DEBUG
- "dumping the receive descriptors: current slot is %d\n",
- fep->rx_slot);
- for (curr_slot = 0; curr_slot < NUM_RX_BUFF; curr_slot++) {
- printk(KERN_DEBUG
- "Desc %02d: status 0x%04x, length %3d, addr 0x%x\n",
- curr_slot, fep->rx_desc[curr_slot].ctrl,
- fep->rx_desc[curr_slot].data_len,
- (unsigned int)fep->rx_desc[curr_slot].data_ptr);
+ unsigned long flags;
+
+ if (idx >= sizeof(__mals) / sizeof(__mals[0])) {
+ printk(KERN_WARNING
+ "invalid index %d when registering MAL for debugging\n",
+ idx);
+ return;
}
+
+ local_irq_save(flags);
+ __mals[idx] = mal;
+ local_irq_restore(flags);
}
-void emac_mac_dump(struct net_device *dev)
+void emac_dbg_dump_all(void)
{
- struct ocp_enet_private *fep = dev->priv;
- volatile emac_t *emacp = fep->emacp;
-
- printk(KERN_DEBUG "EMAC DEBUG ********** \n");
- printk(KERN_DEBUG "EMAC_M0 ==> 0x%x\n", in_be32(&emacp->em0mr0));
- printk(KERN_DEBUG "EMAC_M1 ==> 0x%x\n", in_be32(&emacp->em0mr1));
- printk(KERN_DEBUG "EMAC_TXM0==> 0x%x\n", in_be32(&emacp->em0tmr0));
- printk(KERN_DEBUG "EMAC_TXM1==> 0x%x\n", in_be32(&emacp->em0tmr1));
- printk(KERN_DEBUG "EMAC_RXM ==> 0x%x\n", in_be32(&emacp->em0rmr));
- printk(KERN_DEBUG "EMAC_ISR ==> 0x%x\n", in_be32(&emacp->em0isr));
- printk(KERN_DEBUG "EMAC_IER ==> 0x%x\n", in_be32(&emacp->em0iser));
- printk(KERN_DEBUG "EMAC_IAH ==> 0x%x\n", in_be32(&emacp->em0iahr));
- printk(KERN_DEBUG "EMAC_IAL ==> 0x%x\n", in_be32(&emacp->em0ialr));
- printk(KERN_DEBUG "EMAC_VLAN_TPID_REG ==> 0x%x\n",
- in_be32(&emacp->em0vtpid));
+ unsigned int i;
+ unsigned long flags;
+
+ local_irq_save(flags);
+
+ for (i = 0; i < sizeof(__mals) / sizeof(__mals[0]); ++i)
+ if (__mals[i])
+ emac_mal_dump(__mals[i]);
+
+ for (i = 0; i < sizeof(__emacs) / sizeof(__emacs[0]); ++i)
+ if (__emacs[i])
+ emac_mac_dump(i, __emacs[i]);
+
+ local_irq_restore(flags);
}
-void emac_mal_dump(struct net_device *dev)
+#if defined(CONFIG_MAGIC_SYSRQ)
+static void emac_sysrq_handler(int key, struct pt_regs *pt_regs,
+ struct tty_struct *tty)
{
- struct ibm_ocp_mal *mal = ((struct ocp_enet_private *)dev->priv)->mal;
-
- printk(KERN_DEBUG " MAL DEBUG ********** \n");
- printk(KERN_DEBUG " MCR ==> 0x%x\n",
- (unsigned int)get_mal_dcrn(mal, DCRN_MALCR));
- printk(KERN_DEBUG " ESR ==> 0x%x\n",
- (unsigned int)get_mal_dcrn(mal, DCRN_MALESR));
- printk(KERN_DEBUG " IER ==> 0x%x\n",
- (unsigned int)get_mal_dcrn(mal, DCRN_MALIER));
-#ifdef CONFIG_40x
- printk(KERN_DEBUG " DBR ==> 0x%x\n",
- (unsigned int)get_mal_dcrn(mal, DCRN_MALDBR));
-#endif /* CONFIG_40x */
- printk(KERN_DEBUG " TXCASR ==> 0x%x\n",
- (unsigned int)get_mal_dcrn(mal, DCRN_MALTXCASR));
- printk(KERN_DEBUG " TXCARR ==> 0x%x\n",
- (unsigned int)get_mal_dcrn(mal, DCRN_MALTXCARR));
- printk(KERN_DEBUG " TXEOBISR ==> 0x%x\n",
- (unsigned int)get_mal_dcrn(mal, DCRN_MALTXEOBISR));
- printk(KERN_DEBUG " TXDEIR ==> 0x%x\n",
- (unsigned int)get_mal_dcrn(mal, DCRN_MALTXDEIR));
- printk(KERN_DEBUG " RXCASR ==> 0x%x\n",
- (unsigned int)get_mal_dcrn(mal, DCRN_MALRXCASR));
- printk(KERN_DEBUG " RXCARR ==> 0x%x\n",
- (unsigned int)get_mal_dcrn(mal, DCRN_MALRXCARR));
- printk(KERN_DEBUG " RXEOBISR ==> 0x%x\n",
- (unsigned int)get_mal_dcrn(mal, DCRN_MALRXEOBISR));
- printk(KERN_DEBUG " RXDEIR ==> 0x%x\n",
- (unsigned int)get_mal_dcrn(mal, DCRN_MALRXDEIR));
- printk(KERN_DEBUG " TXCTP0R ==> 0x%x\n",
- (unsigned int)get_mal_dcrn(mal, DCRN_MALTXCTP0R));
- printk(KERN_DEBUG " TXCTP1R ==> 0x%x\n",
- (unsigned int)get_mal_dcrn(mal, DCRN_MALTXCTP1R));
- printk(KERN_DEBUG " TXCTP2R ==> 0x%x\n",
- (unsigned int)get_mal_dcrn(mal, DCRN_MALTXCTP2R));
- printk(KERN_DEBUG " TXCTP3R ==> 0x%x\n",
- (unsigned int)get_mal_dcrn(mal, DCRN_MALTXCTP3R));
- printk(KERN_DEBUG " RXCTP0R ==> 0x%x\n",
- (unsigned int)get_mal_dcrn(mal, DCRN_MALRXCTP0R));
- printk(KERN_DEBUG " RXCTP1R ==> 0x%x\n",
- (unsigned int)get_mal_dcrn(mal, DCRN_MALRXCTP1R));
- printk(KERN_DEBUG " RCBS0 ==> 0x%x\n",
- (unsigned int)get_mal_dcrn(mal, DCRN_MALRCBS0));
- printk(KERN_DEBUG " RCBS1 ==> 0x%x\n",
- (unsigned int)get_mal_dcrn(mal, DCRN_MALRCBS1));
+ emac_dbg_dump_all();
}
-void emac_serr_dump_0(struct net_device *dev)
+static struct sysrq_key_op emac_sysrq_op = {
+ .handler = emac_sysrq_handler,
+ .help_msg = "emaC",
+ .action_msg = "Show EMAC(s) status",
+};
+
+int __init emac_init_debug(void)
{
- struct ibm_ocp_mal *mal = ((struct ocp_enet_private *)dev->priv)->mal;
- unsigned long int mal_error, plb_error, plb_addr;
-
- mal_error = get_mal_dcrn(mal, DCRN_MALESR);
- printk(KERN_DEBUG "ppc405_eth_serr: %s channel %ld \n",
- (mal_error & 0x40000000) ? "Receive" :
- "Transmit", (mal_error & 0x3e000000) >> 25);
- printk(KERN_DEBUG " ----- latched error -----\n");
- if (mal_error & MALESR_DE)
- printk(KERN_DEBUG " DE: descriptor error\n");
- if (mal_error & MALESR_OEN)
- printk(KERN_DEBUG " ONE: OPB non-fullword error\n");
- if (mal_error & MALESR_OTE)
- printk(KERN_DEBUG " OTE: OPB timeout error\n");
- if (mal_error & MALESR_OSE)
- printk(KERN_DEBUG " OSE: OPB slave error\n");
-
- if (mal_error & MALESR_PEIN) {
- plb_error = mfdcr(DCRN_PLB0_BESR);
- printk(KERN_DEBUG
- " PEIN: PLB error, PLB0_BESR is 0x%x\n",
- (unsigned int)plb_error);
- plb_addr = mfdcr(DCRN_PLB0_BEAR);
- printk(KERN_DEBUG
- " PEIN: PLB error, PLB0_BEAR is 0x%x\n",
- (unsigned int)plb_addr);
- }
+ return register_sysrq_key('c', &emac_sysrq_op);
}
-void emac_serr_dump_1(struct net_device *dev)
+void __exit emac_fini_debug(void)
{
- struct ibm_ocp_mal *mal = ((struct ocp_enet_private *)dev->priv)->mal;
- int mal_error = get_mal_dcrn(mal, DCRN_MALESR);
-
- printk(KERN_DEBUG " ----- cumulative errors -----\n");
- if (mal_error & MALESR_DEI)
- printk(KERN_DEBUG " DEI: descriptor error interrupt\n");
- if (mal_error & MALESR_ONEI)
- printk(KERN_DEBUG " OPB non-fullword error interrupt\n");
- if (mal_error & MALESR_OTEI)
- printk(KERN_DEBUG " OTEI: timeout error interrupt\n");
- if (mal_error & MALESR_OSEI)
- printk(KERN_DEBUG " OSEI: slave error interrupt\n");
- if (mal_error & MALESR_PBEI)
- printk(KERN_DEBUG " PBEI: PLB bus error interrupt\n");
+ unregister_sysrq_key('c', &emac_sysrq_op);
}
-void emac_err_dump(struct net_device *dev, int em0isr)
+#else
+int __init emac_init_debug(void)
+{
+ return 0;
+}
+void __exit emac_fini_debug(void)
{
- printk(KERN_DEBUG "%s: on-chip ethernet error:\n", dev->name);
-
- if (em0isr & EMAC_ISR_OVR)
- printk(KERN_DEBUG " OVR: overrun\n");
- if (em0isr & EMAC_ISR_PP)
- printk(KERN_DEBUG " PP: control pause packet\n");
- if (em0isr & EMAC_ISR_BP)
- printk(KERN_DEBUG " BP: packet error\n");
- if (em0isr & EMAC_ISR_RP)
- printk(KERN_DEBUG " RP: runt packet\n");
- if (em0isr & EMAC_ISR_SE)
- printk(KERN_DEBUG " SE: short event\n");
- if (em0isr & EMAC_ISR_ALE)
- printk(KERN_DEBUG " ALE: odd number of nibbles in packet\n");
- if (em0isr & EMAC_ISR_BFCS)
- printk(KERN_DEBUG " BFCS: bad FCS\n");
- if (em0isr & EMAC_ISR_PTLE)
- printk(KERN_DEBUG " PTLE: oversized packet\n");
- if (em0isr & EMAC_ISR_ORE)
- printk(KERN_DEBUG
- " ORE: packet length field > max allowed LLC\n");
- if (em0isr & EMAC_ISR_IRE)
- printk(KERN_DEBUG " IRE: In Range error\n");
- if (em0isr & EMAC_ISR_DBDM)
- printk(KERN_DEBUG " DBDM: xmit error or SQE\n");
- if (em0isr & EMAC_ISR_DB0)
- printk(KERN_DEBUG " DB0: xmit error or SQE on TX channel 0\n");
- if (em0isr & EMAC_ISR_SE0)
- printk(KERN_DEBUG
- " SE0: Signal Quality Error test failure from TX channel 0\n");
- if (em0isr & EMAC_ISR_TE0)
- printk(KERN_DEBUG " TE0: xmit channel 0 aborted\n");
- if (em0isr & EMAC_ISR_DB1)
- printk(KERN_DEBUG " DB1: xmit error or SQE on TX channel \n");
- if (em0isr & EMAC_ISR_SE1)
- printk(KERN_DEBUG
- " SE1: Signal Quality Error test failure from TX channel 1\n");
- if (em0isr & EMAC_ISR_TE1)
- printk(KERN_DEBUG " TE1: xmit channel 1 aborted\n");
- if (em0isr & EMAC_ISR_MOS)
- printk(KERN_DEBUG " MOS\n");
- if (em0isr & EMAC_ISR_MOF)
- printk(KERN_DEBUG " MOF\n");
-
- emac_mac_dump(dev);
- emac_mal_dump(dev);
}
+#endif /* CONFIG_MAGIC_SYSRQ */
diff --git a/drivers/net/ibm_emac/ibm_emac_debug.h b/drivers/net/ibm_emac/ibm_emac_debug.h
new file mode 100644
index 000000000000..e85fbe0a8da9
--- /dev/null
+++ b/drivers/net/ibm_emac/ibm_emac_debug.h
@@ -0,0 +1,63 @@
+/*
+ * drivers/net/ibm_emac/ibm_ocp_debug.h
+ *
+ * Driver for PowerPC 4xx on-chip ethernet controller, debug print routines.
+ *
+ * Copyright (c) 2004, 2005 Zultys Technologies
+ * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.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.
+ *
+ */
+#ifndef __IBM_EMAC_DEBUG_H_
+#define __IBM_EMAC_DEBUG_H_
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include "ibm_emac_core.h"
+#include "ibm_emac_mal.h"
+
+#if defined(CONFIG_IBM_EMAC_DEBUG)
+void emac_dbg_register(int idx, struct ocp_enet_private *dev);
+void mal_dbg_register(int idx, struct ibm_ocp_mal *mal);
+int emac_init_debug(void) __init;
+void emac_fini_debug(void) __exit;
+void emac_dbg_dump_all(void);
+# define DBG_LEVEL 1
+#else
+# define emac_dbg_register(x,y) ((void)0)
+# define mal_dbg_register(x,y) ((void)0)
+# define emac_init_debug() ((void)0)
+# define emac_fini_debug() ((void)0)
+# define emac_dbg_dump_all() ((void)0)
+# define DBG_LEVEL 0
+#endif
+
+#if DBG_LEVEL > 0
+# define DBG(f,x...) printk("emac" f, ##x)
+# define MAL_DBG(f,x...) printk("mal" f, ##x)
+# define ZMII_DBG(f,x...) printk("zmii" f, ##x)
+# define RGMII_DBG(f,x...) printk("rgmii" f, ##x)
+# define NL "\n"
+#else
+# define DBG(f,x...) ((void)0)
+# define MAL_DBG(f,x...) ((void)0)
+# define ZMII_DBG(f,x...) ((void)0)
+# define RGMII_DBG(f,x...) ((void)0)
+#endif
+#if DBG_LEVEL > 1
+# define DBG2(f,x...) DBG(f, ##x)
+# define MAL_DBG2(f,x...) MAL_DBG(f, ##x)
+# define ZMII_DBG2(f,x...) ZMII_DBG(f, ##x)
+# define RGMII_DBG2(f,x...) RGMII_DBG(f, ##x)
+#else
+# define DBG2(f,x...) ((void)0)
+# define MAL_DBG2(f,x...) ((void)0)
+# define ZMII_DBG2(f,x...) ((void)0)
+# define RGMII_DBG2(f,x...) ((void)0)
+#endif
+
+#endif /* __IBM_EMAC_DEBUG_H_ */
diff --git a/drivers/net/ibm_emac/ibm_emac_mal.c b/drivers/net/ibm_emac/ibm_emac_mal.c
index e59f57f363ca..da88d43081cc 100644
--- a/drivers/net/ibm_emac/ibm_emac_mal.c
+++ b/drivers/net/ibm_emac/ibm_emac_mal.c
@@ -1,436 +1,565 @@
/*
- * ibm_ocp_mal.c
+ * drivers/net/ibm_emac/ibm_emac_mal.c
*
- * Armin Kuster akuster@mvista.com
- * Juen, 2002
+ * Memory Access Layer (MAL) support
+ *
+ * Copyright (c) 2004, 2005 Zultys Technologies.
+ * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
*
- * Copyright 2002 MontaVista Softare Inc.
+ * Based on original work by
+ * Benjamin Herrenschmidt <benh@kernel.crashing.org>,
+ * David Gibson <hermes@gibson.dropbear.id.au>,
+ *
+ * Armin Kuster <akuster@mvista.com>
+ * Copyright 2002 MontaVista Softare Inc.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
+ *
*/
-
#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/netdevice.h>
#include <linux/init.h>
+#include <linux/interrupt.h>
#include <linux/dma-mapping.h>
-#include <asm/io.h>
-#include <asm/irq.h>
#include <asm/ocp.h>
+#include "ibm_emac_core.h"
#include "ibm_emac_mal.h"
+#include "ibm_emac_debug.h"
-// Locking: Should we share a lock with the client ? The client could provide
-// a lock pointer (optionally) in the commac structure... I don't think this is
-// really necessary though
-
-/* This lock protects the commac list. On today UP implementations, it's
- * really only used as IRQ protection in mal_{register,unregister}_commac()
- */
-static DEFINE_RWLOCK(mal_list_lock);
-
-int mal_register_commac(struct ibm_ocp_mal *mal, struct mal_commac *commac)
+int __init mal_register_commac(struct ibm_ocp_mal *mal,
+ struct mal_commac *commac)
{
unsigned long flags;
+ local_irq_save(flags);
- write_lock_irqsave(&mal_list_lock, flags);
+ MAL_DBG("%d: reg(%08x, %08x)" NL, mal->def->index,
+ commac->tx_chan_mask, commac->rx_chan_mask);
- /* Don't let multiple commacs claim the same channel */
+ /* Don't let multiple commacs claim the same channel(s) */
if ((mal->tx_chan_mask & commac->tx_chan_mask) ||
(mal->rx_chan_mask & commac->rx_chan_mask)) {
- write_unlock_irqrestore(&mal_list_lock, flags);
+ local_irq_restore(flags);
+ printk(KERN_WARNING "mal%d: COMMAC channels conflict!\n",
+ mal->def->index);
return -EBUSY;
}
mal->tx_chan_mask |= commac->tx_chan_mask;
mal->rx_chan_mask |= commac->rx_chan_mask;
+ list_add(&commac->list, &mal->list);
- list_add(&commac->list, &mal->commac);
-
- write_unlock_irqrestore(&mal_list_lock, flags);
-
+ local_irq_restore(flags);
return 0;
}
-int mal_unregister_commac(struct ibm_ocp_mal *mal, struct mal_commac *commac)
+void __exit mal_unregister_commac(struct ibm_ocp_mal *mal,
+ struct mal_commac *commac)
{
unsigned long flags;
+ local_irq_save(flags);
- write_lock_irqsave(&mal_list_lock, flags);
+ MAL_DBG("%d: unreg(%08x, %08x)" NL, mal->def->index,
+ commac->tx_chan_mask, commac->rx_chan_mask);
mal->tx_chan_mask &= ~commac->tx_chan_mask;
mal->rx_chan_mask &= ~commac->rx_chan_mask;
-
list_del_init(&commac->list);
- write_unlock_irqrestore(&mal_list_lock, flags);
-
- return 0;
+ local_irq_restore(flags);
}
int mal_set_rcbs(struct ibm_ocp_mal *mal, int channel, unsigned long size)
{
- switch (channel) {
- case 0:
- set_mal_dcrn(mal, DCRN_MALRCBS0, size);
- break;
-#ifdef DCRN_MALRCBS1
- case 1:
- set_mal_dcrn(mal, DCRN_MALRCBS1, size);
- break;
-#endif
-#ifdef DCRN_MALRCBS2
- case 2:
- set_mal_dcrn(mal, DCRN_MALRCBS2, size);
- break;
-#endif
-#ifdef DCRN_MALRCBS3
- case 3:
- set_mal_dcrn(mal, DCRN_MALRCBS3, size);
- break;
-#endif
- default:
+ struct ocp_func_mal_data *maldata = mal->def->additions;
+ BUG_ON(channel < 0 || channel >= maldata->num_rx_chans ||
+ size > MAL_MAX_RX_SIZE);
+
+ MAL_DBG("%d: set_rbcs(%d, %lu)" NL, mal->def->index, channel, size);
+
+ if (size & 0xf) {
+ printk(KERN_WARNING
+ "mal%d: incorrect RX size %lu for the channel %d\n",
+ mal->def->index, size, channel);
return -EINVAL;
}
+ set_mal_dcrn(mal, MAL_RCBS(channel), size >> 4);
return 0;
}
-static irqreturn_t mal_serr(int irq, void *dev_instance, struct pt_regs *regs)
+int mal_tx_bd_offset(struct ibm_ocp_mal *mal, int channel)
{
- struct ibm_ocp_mal *mal = dev_instance;
- unsigned long mal_error;
+ struct ocp_func_mal_data *maldata = mal->def->additions;
+ BUG_ON(channel < 0 || channel >= maldata->num_tx_chans);
+ return channel * NUM_TX_BUFF;
+}
- /*
- * This SERR applies to one of the devices on the MAL, here we charge
- * it against the first EMAC registered for the MAL.
- */
+int mal_rx_bd_offset(struct ibm_ocp_mal *mal, int channel)
+{
+ struct ocp_func_mal_data *maldata = mal->def->additions;
+ BUG_ON(channel < 0 || channel >= maldata->num_rx_chans);
+ return maldata->num_tx_chans * NUM_TX_BUFF + channel * NUM_RX_BUFF;
+}
- mal_error = get_mal_dcrn(mal, DCRN_MALESR);
+void mal_enable_tx_channel(struct ibm_ocp_mal *mal, int channel)
+{
+ local_bh_disable();
+ MAL_DBG("%d: enable_tx(%d)" NL, mal->def->index, channel);
+ set_mal_dcrn(mal, MAL_TXCASR,
+ get_mal_dcrn(mal, MAL_TXCASR) | MAL_CHAN_MASK(channel));
+ local_bh_enable();
+}
- printk(KERN_ERR "%s: System Error (MALESR=%lx)\n",
- "MAL" /* FIXME: get the name right */ , mal_error);
+void mal_disable_tx_channel(struct ibm_ocp_mal *mal, int channel)
+{
+ set_mal_dcrn(mal, MAL_TXCARR, MAL_CHAN_MASK(channel));
+ MAL_DBG("%d: disable_tx(%d)" NL, mal->def->index, channel);
+}
- /* FIXME: decipher error */
- /* DIXME: distribute to commacs, if possible */
+void mal_enable_rx_channel(struct ibm_ocp_mal *mal, int channel)
+{
+ local_bh_disable();
+ MAL_DBG("%d: enable_rx(%d)" NL, mal->def->index, channel);
+ set_mal_dcrn(mal, MAL_RXCASR,
+ get_mal_dcrn(mal, MAL_RXCASR) | MAL_CHAN_MASK(channel));
+ local_bh_enable();
+}
- /* Clear the error status register */
- set_mal_dcrn(mal, DCRN_MALESR, mal_error);
+void mal_disable_rx_channel(struct ibm_ocp_mal *mal, int channel)
+{
+ set_mal_dcrn(mal, MAL_RXCARR, MAL_CHAN_MASK(channel));
+ MAL_DBG("%d: disable_rx(%d)" NL, mal->def->index, channel);
+}
- return IRQ_HANDLED;
+void mal_poll_add(struct ibm_ocp_mal *mal, struct mal_commac *commac)
+{
+ local_bh_disable();
+ MAL_DBG("%d: poll_add(%p)" NL, mal->def->index, commac);
+ list_add_tail(&commac->poll_list, &mal->poll_list);
+ local_bh_enable();
}
-static irqreturn_t mal_txeob(int irq, void *dev_instance, struct pt_regs *regs)
+void mal_poll_del(struct ibm_ocp_mal *mal, struct mal_commac *commac)
+{
+ local_bh_disable();
+ MAL_DBG("%d: poll_del(%p)" NL, mal->def->index, commac);
+ list_del(&commac->poll_list);
+ local_bh_enable();
+}
+
+/* synchronized by mal_poll() */
+static inline void mal_enable_eob_irq(struct ibm_ocp_mal *mal)
+{
+ MAL_DBG2("%d: enable_irq" NL, mal->def->index);
+ set_mal_dcrn(mal, MAL_CFG, get_mal_dcrn(mal, MAL_CFG) | MAL_CFG_EOPIE);
+}
+
+/* synchronized by __LINK_STATE_RX_SCHED bit in ndev->state */
+static inline void mal_disable_eob_irq(struct ibm_ocp_mal *mal)
+{
+ set_mal_dcrn(mal, MAL_CFG, get_mal_dcrn(mal, MAL_CFG) & ~MAL_CFG_EOPIE);
+ MAL_DBG2("%d: disable_irq" NL, mal->def->index);
+}
+
+static irqreturn_t mal_serr(int irq, void *dev_instance, struct pt_regs *regs)
{
struct ibm_ocp_mal *mal = dev_instance;
- struct list_head *l;
- unsigned long isr;
+ u32 esr = get_mal_dcrn(mal, MAL_ESR);
- isr = get_mal_dcrn(mal, DCRN_MALTXEOBISR);
- set_mal_dcrn(mal, DCRN_MALTXEOBISR, isr);
+ /* Clear the error status register */
+ set_mal_dcrn(mal, MAL_ESR, esr);
- read_lock(&mal_list_lock);
- list_for_each(l, &mal->commac) {
- struct mal_commac *mc = list_entry(l, struct mal_commac, list);
+ MAL_DBG("%d: SERR %08x" NL, mal->def->index, esr);
- if (isr & mc->tx_chan_mask) {
- mc->ops->txeob(mc->dev, isr & mc->tx_chan_mask);
+ if (esr & MAL_ESR_EVB) {
+ if (esr & MAL_ESR_DE) {
+ /* We ignore Descriptor error,
+ * TXDE or RXDE interrupt will be generated anyway.
+ */
+ return IRQ_HANDLED;
}
+
+ if (esr & MAL_ESR_PEIN) {
+ /* PLB error, it's probably buggy hardware or
+ * incorrect physical address in BD (i.e. bug)
+ */
+ if (net_ratelimit())
+ printk(KERN_ERR
+ "mal%d: system error, PLB (ESR = 0x%08x)\n",
+ mal->def->index, esr);
+ return IRQ_HANDLED;
+ }
+
+ /* OPB error, it's probably buggy hardware or incorrect EBC setup */
+ if (net_ratelimit())
+ printk(KERN_ERR
+ "mal%d: system error, OPB (ESR = 0x%08x)\n",
+ mal->def->index, esr);
}
- read_unlock(&mal_list_lock);
+ return IRQ_HANDLED;
+}
+
+static inline void mal_schedule_poll(struct ibm_ocp_mal *mal)
+{
+ if (likely(netif_rx_schedule_prep(&mal->poll_dev))) {
+ MAL_DBG2("%d: schedule_poll" NL, mal->def->index);
+ mal_disable_eob_irq(mal);
+ __netif_rx_schedule(&mal->poll_dev);
+ } else
+ MAL_DBG2("%d: already in poll" NL, mal->def->index);
+}
+static irqreturn_t mal_txeob(int irq, void *dev_instance, struct pt_regs *regs)
+{
+ struct ibm_ocp_mal *mal = dev_instance;
+ u32 r = get_mal_dcrn(mal, MAL_TXEOBISR);
+ MAL_DBG2("%d: txeob %08x" NL, mal->def->index, r);
+ mal_schedule_poll(mal);
+ set_mal_dcrn(mal, MAL_TXEOBISR, r);
return IRQ_HANDLED;
}
static irqreturn_t mal_rxeob(int irq, void *dev_instance, struct pt_regs *regs)
{
struct ibm_ocp_mal *mal = dev_instance;
- struct list_head *l;
- unsigned long isr;
+ u32 r = get_mal_dcrn(mal, MAL_RXEOBISR);
+ MAL_DBG2("%d: rxeob %08x" NL, mal->def->index, r);
+ mal_schedule_poll(mal);
+ set_mal_dcrn(mal, MAL_RXEOBISR, r);
+ return IRQ_HANDLED;
+}
- isr = get_mal_dcrn(mal, DCRN_MALRXEOBISR);
- set_mal_dcrn(mal, DCRN_MALRXEOBISR, isr);
+static irqreturn_t mal_txde(int irq, void *dev_instance, struct pt_regs *regs)
+{
+ struct ibm_ocp_mal *mal = dev_instance;
+ u32 deir = get_mal_dcrn(mal, MAL_TXDEIR);
+ set_mal_dcrn(mal, MAL_TXDEIR, deir);
- read_lock(&mal_list_lock);
- list_for_each(l, &mal->commac) {
- struct mal_commac *mc = list_entry(l, struct mal_commac, list);
+ MAL_DBG("%d: txde %08x" NL, mal->def->index, deir);
- if (isr & mc->rx_chan_mask) {
- mc->ops->rxeob(mc->dev, isr & mc->rx_chan_mask);
- }
- }
- read_unlock(&mal_list_lock);
+ if (net_ratelimit())
+ printk(KERN_ERR
+ "mal%d: TX descriptor error (TXDEIR = 0x%08x)\n",
+ mal->def->index, deir);
return IRQ_HANDLED;
}
-static irqreturn_t mal_txde(int irq, void *dev_instance, struct pt_regs *regs)
+static irqreturn_t mal_rxde(int irq, void *dev_instance, struct pt_regs *regs)
{
struct ibm_ocp_mal *mal = dev_instance;
struct list_head *l;
- unsigned long deir;
+ u32 deir = get_mal_dcrn(mal, MAL_RXDEIR);
- deir = get_mal_dcrn(mal, DCRN_MALTXDEIR);
+ MAL_DBG("%d: rxde %08x" NL, mal->def->index, deir);
- /* FIXME: print which MAL correctly */
- printk(KERN_WARNING "%s: Tx descriptor error (MALTXDEIR=%lx)\n",
- "MAL", deir);
-
- read_lock(&mal_list_lock);
- list_for_each(l, &mal->commac) {
+ list_for_each(l, &mal->list) {
struct mal_commac *mc = list_entry(l, struct mal_commac, list);
-
- if (deir & mc->tx_chan_mask) {
- mc->ops->txde(mc->dev, deir & mc->tx_chan_mask);
+ if (deir & mc->rx_chan_mask) {
+ mc->rx_stopped = 1;
+ mc->ops->rxde(mc->dev);
}
}
- read_unlock(&mal_list_lock);
+
+ mal_schedule_poll(mal);
+ set_mal_dcrn(mal, MAL_RXDEIR, deir);
return IRQ_HANDLED;
}
-/*
- * This interrupt should be very rare at best. This occurs when
- * the hardware has a problem with the receive descriptors. The manual
- * states that it occurs when the hardware cannot the receive descriptor
- * empty bit is not set. The recovery mechanism will be to
- * traverse through the descriptors, handle any that are marked to be
- * handled and reinitialize each along the way. At that point the driver
- * will be restarted.
- */
-static irqreturn_t mal_rxde(int irq, void *dev_instance, struct pt_regs *regs)
+static int mal_poll(struct net_device *ndev, int *budget)
{
- struct ibm_ocp_mal *mal = dev_instance;
+ struct ibm_ocp_mal *mal = ndev->priv;
struct list_head *l;
- unsigned long deir;
-
- deir = get_mal_dcrn(mal, DCRN_MALRXDEIR);
+ int rx_work_limit = min(ndev->quota, *budget), received = 0, done;
+
+ MAL_DBG2("%d: poll(%d) %d ->" NL, mal->def->index, *budget,
+ rx_work_limit);
+ again:
+ /* Process TX skbs */
+ list_for_each(l, &mal->poll_list) {
+ struct mal_commac *mc =
+ list_entry(l, struct mal_commac, poll_list);
+ mc->ops->poll_tx(mc->dev);
+ }
- /*
- * This really is needed. This case encountered in stress testing.
+ /* Process RX skbs.
+ * We _might_ need something more smart here to enforce polling fairness.
*/
- if (deir == 0)
- return IRQ_HANDLED;
-
- /* FIXME: print which MAL correctly */
- printk(KERN_WARNING "%s: Rx descriptor error (MALRXDEIR=%lx)\n",
- "MAL", deir);
-
- read_lock(&mal_list_lock);
- list_for_each(l, &mal->commac) {
- struct mal_commac *mc = list_entry(l, struct mal_commac, list);
+ list_for_each(l, &mal->poll_list) {
+ struct mal_commac *mc =
+ list_entry(l, struct mal_commac, poll_list);
+ int n = mc->ops->poll_rx(mc->dev, rx_work_limit);
+ if (n) {
+ received += n;
+ rx_work_limit -= n;
+ if (rx_work_limit <= 0) {
+ done = 0;
+ goto more_work; // XXX What if this is the last one ?
+ }
+ }
+ }
- if (deir & mc->rx_chan_mask) {
- mc->ops->rxde(mc->dev, deir & mc->rx_chan_mask);
+ /* We need to disable IRQs to protect from RXDE IRQ here */
+ local_irq_disable();
+ __netif_rx_complete(ndev);
+ mal_enable_eob_irq(mal);
+ local_irq_enable();
+
+ done = 1;
+
+ /* Check for "rotting" packet(s) */
+ list_for_each(l, &mal->poll_list) {
+ struct mal_commac *mc =
+ list_entry(l, struct mal_commac, poll_list);
+ if (unlikely(mc->ops->peek_rx(mc->dev) || mc->rx_stopped)) {
+ MAL_DBG2("%d: rotting packet" NL, mal->def->index);
+ if (netif_rx_reschedule(ndev, received))
+ mal_disable_eob_irq(mal);
+ else
+ MAL_DBG2("%d: already in poll list" NL,
+ mal->def->index);
+
+ if (rx_work_limit > 0)
+ goto again;
+ else
+ goto more_work;
}
+ mc->ops->poll_tx(mc->dev);
}
- read_unlock(&mal_list_lock);
- return IRQ_HANDLED;
+ more_work:
+ ndev->quota -= received;
+ *budget -= received;
+
+ MAL_DBG2("%d: poll() %d <- %d" NL, mal->def->index, *budget,
+ done ? 0 : 1);
+ return done ? 0 : 1;
+}
+
+static void mal_reset(struct ibm_ocp_mal *mal)
+{
+ int n = 10;
+ MAL_DBG("%d: reset" NL, mal->def->index);
+
+ set_mal_dcrn(mal, MAL_CFG, MAL_CFG_SR);
+
+ /* Wait for reset to complete (1 system clock) */
+ while ((get_mal_dcrn(mal, MAL_CFG) & MAL_CFG_SR) && n)
+ --n;
+
+ if (unlikely(!n))
+ printk(KERN_ERR "mal%d: reset timeout\n", mal->def->index);
+}
+
+int mal_get_regs_len(struct ibm_ocp_mal *mal)
+{
+ return sizeof(struct emac_ethtool_regs_subhdr) +
+ sizeof(struct ibm_mal_regs);
+}
+
+void *mal_dump_regs(struct ibm_ocp_mal *mal, void *buf)
+{
+ struct emac_ethtool_regs_subhdr *hdr = buf;
+ struct ibm_mal_regs *regs = (struct ibm_mal_regs *)(hdr + 1);
+ struct ocp_func_mal_data *maldata = mal->def->additions;
+ int i;
+
+ hdr->version = MAL_VERSION;
+ hdr->index = mal->def->index;
+
+ regs->tx_count = maldata->num_tx_chans;
+ regs->rx_count = maldata->num_rx_chans;
+
+ regs->cfg = get_mal_dcrn(mal, MAL_CFG);
+ regs->esr = get_mal_dcrn(mal, MAL_ESR);
+ regs->ier = get_mal_dcrn(mal, MAL_IER);
+ regs->tx_casr = get_mal_dcrn(mal, MAL_TXCASR);
+ regs->tx_carr = get_mal_dcrn(mal, MAL_TXCARR);
+ regs->tx_eobisr = get_mal_dcrn(mal, MAL_TXEOBISR);
+ regs->tx_deir = get_mal_dcrn(mal, MAL_TXDEIR);
+ regs->rx_casr = get_mal_dcrn(mal, MAL_RXCASR);
+ regs->rx_carr = get_mal_dcrn(mal, MAL_RXCARR);
+ regs->rx_eobisr = get_mal_dcrn(mal, MAL_RXEOBISR);
+ regs->rx_deir = get_mal_dcrn(mal, MAL_RXDEIR);
+
+ for (i = 0; i < regs->tx_count; ++i)
+ regs->tx_ctpr[i] = get_mal_dcrn(mal, MAL_TXCTPR(i));
+
+ for (i = 0; i < regs->rx_count; ++i) {
+ regs->rx_ctpr[i] = get_mal_dcrn(mal, MAL_RXCTPR(i));
+ regs->rcbs[i] = get_mal_dcrn(mal, MAL_RCBS(i));
+ }
+ return regs + 1;
}
static int __init mal_probe(struct ocp_device *ocpdev)
{
- struct ibm_ocp_mal *mal = NULL;
+ struct ibm_ocp_mal *mal;
struct ocp_func_mal_data *maldata;
- int err = 0;
+ int err = 0, i, bd_size;
+
+ MAL_DBG("%d: probe" NL, ocpdev->def->index);
- maldata = (struct ocp_func_mal_data *)ocpdev->def->additions;
+ maldata = ocpdev->def->additions;
if (maldata == NULL) {
- printk(KERN_ERR "mal%d: Missing additional datas !\n",
+ printk(KERN_ERR "mal%d: missing additional data!\n",
ocpdev->def->index);
return -ENODEV;
}
- mal = kmalloc(sizeof(struct ibm_ocp_mal), GFP_KERNEL);
- if (mal == NULL) {
+ mal = kzalloc(sizeof(struct ibm_ocp_mal), GFP_KERNEL);
+ if (!mal) {
printk(KERN_ERR
- "mal%d: Out of memory allocating MAL structure !\n",
+ "mal%d: out of memory allocating MAL structure!\n",
ocpdev->def->index);
return -ENOMEM;
}
- memset(mal, 0, sizeof(*mal));
-
- switch (ocpdev->def->index) {
- case 0:
- mal->dcrbase = DCRN_MAL_BASE;
- break;
-#ifdef DCRN_MAL1_BASE
- case 1:
- mal->dcrbase = DCRN_MAL1_BASE;
- break;
-#endif
- default:
- BUG();
- }
-
- /**************************/
+ mal->dcrbase = maldata->dcr_base;
+ mal->def = ocpdev->def;
- INIT_LIST_HEAD(&mal->commac);
+ INIT_LIST_HEAD(&mal->poll_list);
+ set_bit(__LINK_STATE_START, &mal->poll_dev.state);
+ mal->poll_dev.weight = CONFIG_IBM_EMAC_POLL_WEIGHT;
+ mal->poll_dev.poll = mal_poll;
+ mal->poll_dev.priv = mal;
+ atomic_set(&mal->poll_dev.refcnt, 1);
- set_mal_dcrn(mal, DCRN_MALRXCARR, 0xFFFFFFFF);
- set_mal_dcrn(mal, DCRN_MALTXCARR, 0xFFFFFFFF);
+ INIT_LIST_HEAD(&mal->list);
- set_mal_dcrn(mal, DCRN_MALCR, MALCR_MMSR); /* 384 */
- /* FIXME: Add delay */
+ /* Load power-on reset defaults */
+ mal_reset(mal);
/* Set the MAL configuration register */
- set_mal_dcrn(mal, DCRN_MALCR,
- MALCR_PLBB | MALCR_OPBBL | MALCR_LEA |
- MALCR_PLBLT_DEFAULT);
-
- /* It would be nice to allocate buffers separately for each
- * channel, but we can't because the channels share the upper
- * 13 bits of address lines. Each channels buffer must also
- * be 4k aligned, so we allocate 4k for each channel. This is
- * inefficient FIXME: do better, if possible */
- mal->tx_virt_addr = dma_alloc_coherent(&ocpdev->dev,
- MAL_DT_ALIGN *
- maldata->num_tx_chans,
- &mal->tx_phys_addr, GFP_KERNEL);
- if (mal->tx_virt_addr == NULL) {
+ set_mal_dcrn(mal, MAL_CFG, MAL_CFG_DEFAULT | MAL_CFG_PLBB |
+ MAL_CFG_OPBBL | MAL_CFG_LEA);
+
+ mal_enable_eob_irq(mal);
+
+ /* Allocate space for BD rings */
+ BUG_ON(maldata->num_tx_chans <= 0 || maldata->num_tx_chans > 32);
+ BUG_ON(maldata->num_rx_chans <= 0 || maldata->num_rx_chans > 32);
+ bd_size = sizeof(struct mal_descriptor) *
+ (NUM_TX_BUFF * maldata->num_tx_chans +
+ NUM_RX_BUFF * maldata->num_rx_chans);
+ mal->bd_virt =
+ dma_alloc_coherent(&ocpdev->dev, bd_size, &mal->bd_dma, GFP_KERNEL);
+
+ if (!mal->bd_virt) {
printk(KERN_ERR
- "mal%d: Out of memory allocating MAL descriptors !\n",
- ocpdev->def->index);
+ "mal%d: out of memory allocating RX/TX descriptors!\n",
+ mal->def->index);
err = -ENOMEM;
goto fail;
}
+ memset(mal->bd_virt, 0, bd_size);
- /* God, oh, god, I hate DCRs */
- set_mal_dcrn(mal, DCRN_MALTXCTP0R, mal->tx_phys_addr);
-#ifdef DCRN_MALTXCTP1R
- if (maldata->num_tx_chans > 1)
- set_mal_dcrn(mal, DCRN_MALTXCTP1R,
- mal->tx_phys_addr + MAL_DT_ALIGN);
-#endif /* DCRN_MALTXCTP1R */
-#ifdef DCRN_MALTXCTP2R
- if (maldata->num_tx_chans > 2)
- set_mal_dcrn(mal, DCRN_MALTXCTP2R,
- mal->tx_phys_addr + 2 * MAL_DT_ALIGN);
-#endif /* DCRN_MALTXCTP2R */
-#ifdef DCRN_MALTXCTP3R
- if (maldata->num_tx_chans > 3)
- set_mal_dcrn(mal, DCRN_MALTXCTP3R,
- mal->tx_phys_addr + 3 * MAL_DT_ALIGN);
-#endif /* DCRN_MALTXCTP3R */
-#ifdef DCRN_MALTXCTP4R
- if (maldata->num_tx_chans > 4)
- set_mal_dcrn(mal, DCRN_MALTXCTP4R,
- mal->tx_phys_addr + 4 * MAL_DT_ALIGN);
-#endif /* DCRN_MALTXCTP4R */
-#ifdef DCRN_MALTXCTP5R
- if (maldata->num_tx_chans > 5)
- set_mal_dcrn(mal, DCRN_MALTXCTP5R,
- mal->tx_phys_addr + 5 * MAL_DT_ALIGN);
-#endif /* DCRN_MALTXCTP5R */
-#ifdef DCRN_MALTXCTP6R
- if (maldata->num_tx_chans > 6)
- set_mal_dcrn(mal, DCRN_MALTXCTP6R,
- mal->tx_phys_addr + 6 * MAL_DT_ALIGN);
-#endif /* DCRN_MALTXCTP6R */
-#ifdef DCRN_MALTXCTP7R
- if (maldata->num_tx_chans > 7)
- set_mal_dcrn(mal, DCRN_MALTXCTP7R,
- mal->tx_phys_addr + 7 * MAL_DT_ALIGN);
-#endif /* DCRN_MALTXCTP7R */
-
- mal->rx_virt_addr = dma_alloc_coherent(&ocpdev->dev,
- MAL_DT_ALIGN *
- maldata->num_rx_chans,
- &mal->rx_phys_addr, GFP_KERNEL);
-
- set_mal_dcrn(mal, DCRN_MALRXCTP0R, mal->rx_phys_addr);
-#ifdef DCRN_MALRXCTP1R
- if (maldata->num_rx_chans > 1)
- set_mal_dcrn(mal, DCRN_MALRXCTP1R,
- mal->rx_phys_addr + MAL_DT_ALIGN);
-#endif /* DCRN_MALRXCTP1R */
-#ifdef DCRN_MALRXCTP2R
- if (maldata->num_rx_chans > 2)
- set_mal_dcrn(mal, DCRN_MALRXCTP2R,
- mal->rx_phys_addr + 2 * MAL_DT_ALIGN);
-#endif /* DCRN_MALRXCTP2R */
-#ifdef DCRN_MALRXCTP3R
- if (maldata->num_rx_chans > 3)
- set_mal_dcrn(mal, DCRN_MALRXCTP3R,
- mal->rx_phys_addr + 3 * MAL_DT_ALIGN);
-#endif /* DCRN_MALRXCTP3R */
+ for (i = 0; i < maldata->num_tx_chans; ++i)
+ set_mal_dcrn(mal, MAL_TXCTPR(i), mal->bd_dma +
+ sizeof(struct mal_descriptor) *
+ mal_tx_bd_offset(mal, i));
+
+ for (i = 0; i < maldata->num_rx_chans; ++i)
+ set_mal_dcrn(mal, MAL_RXCTPR(i), mal->bd_dma +
+ sizeof(struct mal_descriptor) *
+ mal_rx_bd_offset(mal, i));
err = request_irq(maldata->serr_irq, mal_serr, 0, "MAL SERR", mal);
if (err)
- goto fail;
- err = request_irq(maldata->txde_irq, mal_txde, 0, "MAL TX DE ", mal);
+ goto fail2;
+ err = request_irq(maldata->txde_irq, mal_txde, 0, "MAL TX DE", mal);
if (err)
- goto fail;
+ goto fail3;
err = request_irq(maldata->txeob_irq, mal_txeob, 0, "MAL TX EOB", mal);
if (err)
- goto fail;
+ goto fail4;
err = request_irq(maldata->rxde_irq, mal_rxde, 0, "MAL RX DE", mal);
if (err)
- goto fail;
+ goto fail5;
err = request_irq(maldata->rxeob_irq, mal_rxeob, 0, "MAL RX EOB", mal);
if (err)
- goto fail;
+ goto fail6;
- set_mal_dcrn(mal, DCRN_MALIER,
- MALIER_DE | MALIER_NE | MALIER_TE |
- MALIER_OPBE | MALIER_PLBE);
+ /* Enable all MAL SERR interrupt sources */
+ set_mal_dcrn(mal, MAL_IER, MAL_IER_EVENTS);
- /* Advertise me to the rest of the world */
+ /* Advertise this instance to the rest of the world */
ocp_set_drvdata(ocpdev, mal);
- printk(KERN_INFO "mal%d: Initialized, %d tx channels, %d rx channels\n",
- ocpdev->def->index, maldata->num_tx_chans,
- maldata->num_rx_chans);
+ mal_dbg_register(mal->def->index, mal);
+ printk(KERN_INFO "mal%d: initialized, %d TX channels, %d RX channels\n",
+ mal->def->index, maldata->num_tx_chans, maldata->num_rx_chans);
return 0;
+ fail6:
+ free_irq(maldata->rxde_irq, mal);
+ fail5:
+ free_irq(maldata->txeob_irq, mal);
+ fail4:
+ free_irq(maldata->txde_irq, mal);
+ fail3:
+ free_irq(maldata->serr_irq, mal);
+ fail2:
+ dma_free_coherent(&ocpdev->dev, bd_size, mal->bd_virt, mal->bd_dma);
fail:
- /* FIXME: dispose requested IRQs ! */
- if (err && mal)
- kfree(mal);
+ kfree(mal);
return err;
}
static void __exit mal_remove(struct ocp_device *ocpdev)
{
struct ibm_ocp_mal *mal = ocp_get_drvdata(ocpdev);
- struct ocp_func_mal_data *maldata = ocpdev->def->additions;
+ struct ocp_func_mal_data *maldata = mal->def->additions;
+
+ MAL_DBG("%d: remove" NL, mal->def->index);
- BUG_ON(!maldata);
+ /* Syncronize with scheduled polling,
+ stolen from net/core/dev.c:dev_close()
+ */
+ clear_bit(__LINK_STATE_START, &mal->poll_dev.state);
+ netif_poll_disable(&mal->poll_dev);
+
+ if (!list_empty(&mal->list)) {
+ /* This is *very* bad */
+ printk(KERN_EMERG
+ "mal%d: commac list is not empty on remove!\n",
+ mal->def->index);
+ }
ocp_set_drvdata(ocpdev, NULL);
- /* FIXME: shut down the MAL, deal with dependency with emac */
free_irq(maldata->serr_irq, mal);
free_irq(maldata->txde_irq, mal);
free_irq(maldata->txeob_irq, mal);
free_irq(maldata->rxde_irq, mal);
free_irq(maldata->rxeob_irq, mal);
- if (mal->tx_virt_addr)
- dma_free_coherent(&ocpdev->dev,
- MAL_DT_ALIGN * maldata->num_tx_chans,
- mal->tx_virt_addr, mal->tx_phys_addr);
+ mal_reset(mal);
- if (mal->rx_virt_addr)
- dma_free_coherent(&ocpdev->dev,
- MAL_DT_ALIGN * maldata->num_rx_chans,
- mal->rx_virt_addr, mal->rx_phys_addr);
+ mal_dbg_register(mal->def->index, NULL);
+
+ dma_free_coherent(&ocpdev->dev,
+ sizeof(struct mal_descriptor) *
+ (NUM_TX_BUFF * maldata->num_tx_chans +
+ NUM_RX_BUFF * maldata->num_rx_chans), mal->bd_virt,
+ mal->bd_dma);
kfree(mal);
}
/* Structure for a device driver */
static struct ocp_device_id mal_ids[] = {
- {.vendor = OCP_ANY_ID,.function = OCP_FUNC_MAL},
- {.vendor = OCP_VENDOR_INVALID}
+ { .vendor = OCP_VENDOR_IBM, .function = OCP_FUNC_MAL },
+ { .vendor = OCP_VENDOR_INVALID}
};
static struct ocp_driver mal_driver = {
@@ -441,23 +570,14 @@ static struct ocp_driver mal_driver = {
.remove = mal_remove,
};
-static int __init init_mals(void)
+int __init mal_init(void)
{
- int rc;
-
- rc = ocp_register_driver(&mal_driver);
- if (rc < 0) {
- ocp_unregister_driver(&mal_driver);
- return -ENODEV;
- }
-
- return 0;
+ MAL_DBG(": init" NL);
+ return ocp_register_driver(&mal_driver);
}
-static void __exit exit_mals(void)
+void __exit mal_exit(void)
{
+ MAL_DBG(": exit" NL);
ocp_unregister_driver(&mal_driver);
}
-
-module_init(init_mals);
-module_exit(exit_mals);
diff --git a/drivers/net/ibm_emac/ibm_emac_mal.h b/drivers/net/ibm_emac/ibm_emac_mal.h
index dd9f0dabc6e0..2a2d3b24b037 100644
--- a/drivers/net/ibm_emac/ibm_emac_mal.h
+++ b/drivers/net/ibm_emac/ibm_emac_mal.h
@@ -1,131 +1,268 @@
-#ifndef _IBM_EMAC_MAL_H
-#define _IBM_EMAC_MAL_H
+/*
+ * drivers/net/ibm_emac/ibm_emac_mal.h
+ *
+ * Memory Access Layer (MAL) support
+ *
+ * Copyright (c) 2004, 2005 Zultys Technologies.
+ * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
+ *
+ * Based on original work by
+ * Armin Kuster <akuster@mvista.com>
+ * Copyright 2002 MontaVista Softare 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.
+ *
+ */
+#ifndef __IBM_EMAC_MAL_H_
+#define __IBM_EMAC_MAL_H_
+#include <linux/config.h>
+#include <linux/init.h>
#include <linux/list.h>
+#include <linux/netdevice.h>
-#define MAL_DT_ALIGN (4096) /* Alignment for each channel's descriptor table */
+#include <asm/io.h>
-#define MAL_CHAN_MASK(chan) (0x80000000 >> (chan))
+/*
+ * These MAL "versions" probably aren't the real versions IBM uses for these
+ * MAL cores, I assigned them just to make #ifdefs in this file nicer and
+ * reflect the fact that 40x and 44x have slightly different MALs. --ebs
+ */
+#if defined(CONFIG_405GP) || defined(CONFIG_405GPR) || defined(CONFIG_405EP) || \
+ defined(CONFIG_440EP) || defined(CONFIG_440GR) || defined(CONFIG_NP405H)
+#define MAL_VERSION 1
+#elif defined(CONFIG_440GP) || defined(CONFIG_440GX) || defined(CONFIG_440SP) || \
+ defined(CONFIG_440SPE)
+#define MAL_VERSION 2
+#else
+#error "Unknown SoC, please check chip manual and choose MAL 'version'"
+#endif
+
+/* MALx DCR registers */
+#define MAL_CFG 0x00
+#define MAL_CFG_SR 0x80000000
+#define MAL_CFG_PLBB 0x00004000
+#define MAL_CFG_OPBBL 0x00000080
+#define MAL_CFG_EOPIE 0x00000004
+#define MAL_CFG_LEA 0x00000002
+#define MAL_CFG_SD 0x00000001
+#if MAL_VERSION == 1
+#define MAL_CFG_PLBP_MASK 0x00c00000
+#define MAL_CFG_PLBP_10 0x00800000
+#define MAL_CFG_GA 0x00200000
+#define MAL_CFG_OA 0x00100000
+#define MAL_CFG_PLBLE 0x00080000
+#define MAL_CFG_PLBT_MASK 0x00078000
+#define MAL_CFG_DEFAULT (MAL_CFG_PLBP_10 | MAL_CFG_PLBT_MASK)
+#elif MAL_VERSION == 2
+#define MAL_CFG_RPP_MASK 0x00c00000
+#define MAL_CFG_RPP_10 0x00800000
+#define MAL_CFG_RMBS_MASK 0x00300000
+#define MAL_CFG_WPP_MASK 0x000c0000
+#define MAL_CFG_WPP_10 0x00080000
+#define MAL_CFG_WMBS_MASK 0x00030000
+#define MAL_CFG_PLBLE 0x00008000
+#define MAL_CFG_DEFAULT (MAL_CFG_RMBS_MASK | MAL_CFG_WMBS_MASK | \
+ MAL_CFG_RPP_10 | MAL_CFG_WPP_10)
+#else
+#error "Unknown MAL version"
+#endif
+
+#define MAL_ESR 0x01
+#define MAL_ESR_EVB 0x80000000
+#define MAL_ESR_CIDT 0x40000000
+#define MAL_ESR_CID_MASK 0x3e000000
+#define MAL_ESR_CID_SHIFT 25
+#define MAL_ESR_DE 0x00100000
+#define MAL_ESR_OTE 0x00040000
+#define MAL_ESR_OSE 0x00020000
+#define MAL_ESR_PEIN 0x00010000
+#define MAL_ESR_DEI 0x00000010
+#define MAL_ESR_OTEI 0x00000004
+#define MAL_ESR_OSEI 0x00000002
+#define MAL_ESR_PBEI 0x00000001
+#if MAL_VERSION == 1
+#define MAL_ESR_ONE 0x00080000
+#define MAL_ESR_ONEI 0x00000008
+#elif MAL_VERSION == 2
+#define MAL_ESR_PTE 0x00800000
+#define MAL_ESR_PRE 0x00400000
+#define MAL_ESR_PWE 0x00200000
+#define MAL_ESR_PTEI 0x00000080
+#define MAL_ESR_PREI 0x00000040
+#define MAL_ESR_PWEI 0x00000020
+#else
+#error "Unknown MAL version"
+#endif
+
+#define MAL_IER 0x02
+#define MAL_IER_DE 0x00000010
+#define MAL_IER_OTE 0x00000004
+#define MAL_IER_OE 0x00000002
+#define MAL_IER_PE 0x00000001
+#if MAL_VERSION == 1
+#define MAL_IER_NWE 0x00000008
+#define MAL_IER_SOC_EVENTS MAL_IER_NWE
+#elif MAL_VERSION == 2
+#define MAL_IER_PT 0x00000080
+#define MAL_IER_PRE 0x00000040
+#define MAL_IER_PWE 0x00000020
+#define MAL_IER_SOC_EVENTS (MAL_IER_PT | MAL_IER_PRE | MAL_IER_PWE)
+#else
+#error "Unknown MAL version"
+#endif
+#define MAL_IER_EVENTS (MAL_IER_SOC_EVENTS | MAL_IER_OTE | \
+ MAL_IER_OTE | MAL_IER_OE | MAL_IER_PE)
+
+#define MAL_TXCASR 0x04
+#define MAL_TXCARR 0x05
+#define MAL_TXEOBISR 0x06
+#define MAL_TXDEIR 0x07
+#define MAL_RXCASR 0x10
+#define MAL_RXCARR 0x11
+#define MAL_RXEOBISR 0x12
+#define MAL_RXDEIR 0x13
+#define MAL_TXCTPR(n) ((n) + 0x20)
+#define MAL_RXCTPR(n) ((n) + 0x40)
+#define MAL_RCBS(n) ((n) + 0x60)
+
+/* In reality MAL can handle TX buffers up to 4095 bytes long,
+ * but this isn't a good round number :) --ebs
+ */
+#define MAL_MAX_TX_SIZE 4080
+#define MAL_MAX_RX_SIZE 4080
+
+static inline int mal_rx_size(int len)
+{
+ len = (len + 0xf) & ~0xf;
+ return len > MAL_MAX_RX_SIZE ? MAL_MAX_RX_SIZE : len;
+}
+
+static inline int mal_tx_chunks(int len)
+{
+ return (len + MAL_MAX_TX_SIZE - 1) / MAL_MAX_TX_SIZE;
+}
+
+#define MAL_CHAN_MASK(n) (0x80000000 >> (n))
/* MAL Buffer Descriptor structure */
struct mal_descriptor {
- unsigned short ctrl; /* MAL / Commac status control bits */
- short data_len; /* Max length is 4K-1 (12 bits) */
- unsigned char *data_ptr; /* pointer to actual data buffer */
-} __attribute__ ((packed));
+ u16 ctrl; /* MAL / Commac status control bits */
+ u16 data_len; /* Max length is 4K-1 (12 bits) */
+ u32 data_ptr; /* pointer to actual data buffer */
+};
/* the following defines are for the MadMAL status and control registers. */
/* MADMAL transmit and receive status/control bits */
-#define MAL_RX_CTRL_EMPTY 0x8000
-#define MAL_RX_CTRL_WRAP 0x4000
-#define MAL_RX_CTRL_CM 0x2000
-#define MAL_RX_CTRL_LAST 0x1000
-#define MAL_RX_CTRL_FIRST 0x0800
-#define MAL_RX_CTRL_INTR 0x0400
-
-#define MAL_TX_CTRL_READY 0x8000
-#define MAL_TX_CTRL_WRAP 0x4000
-#define MAL_TX_CTRL_CM 0x2000
-#define MAL_TX_CTRL_LAST 0x1000
-#define MAL_TX_CTRL_INTR 0x0400
+#define MAL_RX_CTRL_EMPTY 0x8000
+#define MAL_RX_CTRL_WRAP 0x4000
+#define MAL_RX_CTRL_CM 0x2000
+#define MAL_RX_CTRL_LAST 0x1000
+#define MAL_RX_CTRL_FIRST 0x0800
+#define MAL_RX_CTRL_INTR 0x0400
+#define MAL_RX_CTRL_SINGLE (MAL_RX_CTRL_LAST | MAL_RX_CTRL_FIRST)
+#define MAL_IS_SINGLE_RX(ctrl) (((ctrl) & MAL_RX_CTRL_SINGLE) == MAL_RX_CTRL_SINGLE)
+
+#define MAL_TX_CTRL_READY 0x8000
+#define MAL_TX_CTRL_WRAP 0x4000
+#define MAL_TX_CTRL_CM 0x2000
+#define MAL_TX_CTRL_LAST 0x1000
+#define MAL_TX_CTRL_INTR 0x0400
struct mal_commac_ops {
- void (*txeob) (void *dev, u32 chanmask);
- void (*txde) (void *dev, u32 chanmask);
- void (*rxeob) (void *dev, u32 chanmask);
- void (*rxde) (void *dev, u32 chanmask);
+ void (*poll_tx) (void *dev);
+ int (*poll_rx) (void *dev, int budget);
+ int (*peek_rx) (void *dev);
+ void (*rxde) (void *dev);
};
struct mal_commac {
- struct mal_commac_ops *ops;
- void *dev;
- u32 tx_chan_mask, rx_chan_mask;
- struct list_head list;
+ struct mal_commac_ops *ops;
+ void *dev;
+ struct list_head poll_list;
+ int rx_stopped;
+
+ u32 tx_chan_mask;
+ u32 rx_chan_mask;
+ struct list_head list;
};
struct ibm_ocp_mal {
- int dcrbase;
+ int dcrbase;
- struct list_head commac;
- u32 tx_chan_mask, rx_chan_mask;
+ struct list_head poll_list;
+ struct net_device poll_dev;
- dma_addr_t tx_phys_addr;
- struct mal_descriptor *tx_virt_addr;
+ struct list_head list;
+ u32 tx_chan_mask;
+ u32 rx_chan_mask;
- dma_addr_t rx_phys_addr;
- struct mal_descriptor *rx_virt_addr;
-};
+ dma_addr_t bd_dma;
+ struct mal_descriptor *bd_virt;
-#define GET_MAL_STANZA(base,dcrn) \
- case base: \
- x = mfdcr(dcrn(base)); \
- break;
-
-#define SET_MAL_STANZA(base,dcrn, val) \
- case base: \
- mtdcr(dcrn(base), (val)); \
- break;
-
-#define GET_MAL0_STANZA(dcrn) GET_MAL_STANZA(DCRN_MAL_BASE,dcrn)
-#define SET_MAL0_STANZA(dcrn,val) SET_MAL_STANZA(DCRN_MAL_BASE,dcrn,val)
-
-#ifdef DCRN_MAL1_BASE
-#define GET_MAL1_STANZA(dcrn) GET_MAL_STANZA(DCRN_MAL1_BASE,dcrn)
-#define SET_MAL1_STANZA(dcrn,val) SET_MAL_STANZA(DCRN_MAL1_BASE,dcrn,val)
-#else /* ! DCRN_MAL1_BASE */
-#define GET_MAL1_STANZA(dcrn)
-#define SET_MAL1_STANZA(dcrn,val)
-#endif
+ struct ocp_def *def;
+};
-#define get_mal_dcrn(mal, dcrn) ({ \
- u32 x; \
- switch ((mal)->dcrbase) { \
- GET_MAL0_STANZA(dcrn) \
- GET_MAL1_STANZA(dcrn) \
- default: \
- x = 0; \
- BUG(); \
- } \
-x; })
-
-#define set_mal_dcrn(mal, dcrn, val) do { \
- switch ((mal)->dcrbase) { \
- SET_MAL0_STANZA(dcrn,val) \
- SET_MAL1_STANZA(dcrn,val) \
- default: \
- BUG(); \
- } } while (0)
-
-static inline void mal_enable_tx_channels(struct ibm_ocp_mal *mal, u32 chanmask)
+static inline u32 get_mal_dcrn(struct ibm_ocp_mal *mal, int reg)
{
- set_mal_dcrn(mal, DCRN_MALTXCASR,
- get_mal_dcrn(mal, DCRN_MALTXCASR) | chanmask);
+ return mfdcr(mal->dcrbase + reg);
}
-static inline void mal_disable_tx_channels(struct ibm_ocp_mal *mal,
- u32 chanmask)
+static inline void set_mal_dcrn(struct ibm_ocp_mal *mal, int reg, u32 val)
{
- set_mal_dcrn(mal, DCRN_MALTXCARR, chanmask);
+ mtdcr(mal->dcrbase + reg, val);
}
-static inline void mal_enable_rx_channels(struct ibm_ocp_mal *mal, u32 chanmask)
-{
- set_mal_dcrn(mal, DCRN_MALRXCASR,
- get_mal_dcrn(mal, DCRN_MALRXCASR) | chanmask);
-}
+/* Register MAL devices */
+int mal_init(void) __init;
+void mal_exit(void) __exit;
-static inline void mal_disable_rx_channels(struct ibm_ocp_mal *mal,
- u32 chanmask)
-{
- set_mal_dcrn(mal, DCRN_MALRXCARR, chanmask);
-}
+int mal_register_commac(struct ibm_ocp_mal *mal,
+ struct mal_commac *commac) __init;
+void mal_unregister_commac(struct ibm_ocp_mal *mal,
+ struct mal_commac *commac) __exit;
+int mal_set_rcbs(struct ibm_ocp_mal *mal, int channel, unsigned long size);
+
+/* Returns BD ring offset for a particular channel
+ (in 'struct mal_descriptor' elements)
+*/
+int mal_tx_bd_offset(struct ibm_ocp_mal *mal, int channel);
+int mal_rx_bd_offset(struct ibm_ocp_mal *mal, int channel);
+
+void mal_enable_tx_channel(struct ibm_ocp_mal *mal, int channel);
+void mal_disable_tx_channel(struct ibm_ocp_mal *mal, int channel);
+void mal_enable_rx_channel(struct ibm_ocp_mal *mal, int channel);
+void mal_disable_rx_channel(struct ibm_ocp_mal *mal, int channel);
-extern int mal_register_commac(struct ibm_ocp_mal *mal,
- struct mal_commac *commac);
-extern int mal_unregister_commac(struct ibm_ocp_mal *mal,
- struct mal_commac *commac);
+/* Add/remove EMAC to/from MAL polling list */
+void mal_poll_add(struct ibm_ocp_mal *mal, struct mal_commac *commac);
+void mal_poll_del(struct ibm_ocp_mal *mal, struct mal_commac *commac);
+
+/* Ethtool MAL registers */
+struct ibm_mal_regs {
+ u32 tx_count;
+ u32 rx_count;
+
+ u32 cfg;
+ u32 esr;
+ u32 ier;
+ u32 tx_casr;
+ u32 tx_carr;
+ u32 tx_eobisr;
+ u32 tx_deir;
+ u32 rx_casr;
+ u32 rx_carr;
+ u32 rx_eobisr;
+ u32 rx_deir;
+ u32 tx_ctpr[32];
+ u32 rx_ctpr[32];
+ u32 rcbs[32];
+};
-extern int mal_set_rcbs(struct ibm_ocp_mal *mal, int channel,
- unsigned long size);
+int mal_get_regs_len(struct ibm_ocp_mal *mal);
+void *mal_dump_regs(struct ibm_ocp_mal *mal, void *buf);
-#endif /* _IBM_EMAC_MAL_H */
+#endif /* __IBM_EMAC_MAL_H_ */
diff --git a/drivers/net/ibm_emac/ibm_emac_phy.c b/drivers/net/ibm_emac/ibm_emac_phy.c
index 14213f090e91..67935dd33a65 100644
--- a/drivers/net/ibm_emac/ibm_emac_phy.c
+++ b/drivers/net/ibm_emac/ibm_emac_phy.c
@@ -1,96 +1,80 @@
/*
- * ibm_ocp_phy.c
+ * drivers/net/ibm_emac/ibm_emac_phy.c
*
- * PHY drivers for the ibm ocp ethernet driver. Borrowed
- * from sungem_phy.c, though I only kept the generic MII
+ * Driver for PowerPC 4xx on-chip ethernet controller, PHY support.
+ * Borrowed from sungem_phy.c, though I only kept the generic MII
* driver for now.
*
* This file should be shared with other drivers or eventually
* merged as the "low level" part of miilib
*
* (c) 2003, Benjamin Herrenscmidt (benh@kernel.crashing.org)
+ * (c) 2004-2005, Eugene Surovegin <ebs@ebshome.net>
*
*/
-
#include <linux/config.h>
-
#include <linux/module.h>
-
#include <linux/kernel.h>
-#include <linux/sched.h>
#include <linux/types.h>
#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
#include <linux/mii.h>
#include <linux/ethtool.h>
#include <linux/delay.h>
+#include <asm/ocp.h>
+
#include "ibm_emac_phy.h"
-static int reset_one_mii_phy(struct mii_phy *phy, int phy_id)
+static inline int phy_read(struct mii_phy *phy, int reg)
+{
+ return phy->mdio_read(phy->dev, phy->address, reg);
+}
+
+static inline void phy_write(struct mii_phy *phy, int reg, int val)
{
- u16 val;
+ phy->mdio_write(phy->dev, phy->address, reg, val);
+}
+
+int mii_reset_phy(struct mii_phy *phy)
+{
+ int val;
int limit = 10000;
- val = __phy_read(phy, phy_id, MII_BMCR);
+ val = phy_read(phy, MII_BMCR);
val &= ~BMCR_ISOLATE;
val |= BMCR_RESET;
- __phy_write(phy, phy_id, MII_BMCR, val);
+ phy_write(phy, MII_BMCR, val);
- udelay(100);
+ udelay(300);
while (limit--) {
- val = __phy_read(phy, phy_id, MII_BMCR);
- if ((val & BMCR_RESET) == 0)
+ val = phy_read(phy, MII_BMCR);
+ if (val >= 0 && (val & BMCR_RESET) == 0)
break;
udelay(10);
}
if ((val & BMCR_ISOLATE) && limit > 0)
- __phy_write(phy, phy_id, MII_BMCR, val & ~BMCR_ISOLATE);
+ phy_write(phy, MII_BMCR, val & ~BMCR_ISOLATE);
- return (limit <= 0);
-}
-
-static int cis8201_init(struct mii_phy *phy)
-{
- u16 epcr;
-
- epcr = phy_read(phy, MII_CIS8201_EPCR);
- epcr &= ~EPCR_MODE_MASK;
-
- switch (phy->mode) {
- case PHY_MODE_TBI:
- epcr |= EPCR_TBI_MODE;
- break;
- case PHY_MODE_RTBI:
- epcr |= EPCR_RTBI_MODE;
- break;
- case PHY_MODE_GMII:
- epcr |= EPCR_GMII_MODE;
- break;
- case PHY_MODE_RGMII:
- default:
- epcr |= EPCR_RGMII_MODE;
- }
-
- phy_write(phy, MII_CIS8201_EPCR, epcr);
-
- return 0;
+ return limit <= 0;
}
static int genmii_setup_aneg(struct mii_phy *phy, u32 advertise)
{
- u16 ctl, adv;
+ int ctl, adv;
- phy->autoneg = 1;
+ phy->autoneg = AUTONEG_ENABLE;
phy->speed = SPEED_10;
phy->duplex = DUPLEX_HALF;
- phy->pause = 0;
+ phy->pause = phy->asym_pause = 0;
phy->advertising = advertise;
/* Setup standard advertise */
adv = phy_read(phy, MII_ADVERTISE);
- adv &= ~(ADVERTISE_ALL | ADVERTISE_100BASE4);
+ if (adv < 0)
+ return adv;
+ adv &= ~(ADVERTISE_ALL | ADVERTISE_100BASE4 | ADVERTISE_PAUSE_CAP |
+ ADVERTISE_PAUSE_ASYM);
if (advertise & ADVERTISED_10baseT_Half)
adv |= ADVERTISE_10HALF;
if (advertise & ADVERTISED_10baseT_Full)
@@ -99,8 +83,25 @@ static int genmii_setup_aneg(struct mii_phy *phy, u32 advertise)
adv |= ADVERTISE_100HALF;
if (advertise & ADVERTISED_100baseT_Full)
adv |= ADVERTISE_100FULL;
+ if (advertise & ADVERTISED_Pause)
+ adv |= ADVERTISE_PAUSE_CAP;
+ if (advertise & ADVERTISED_Asym_Pause)
+ adv |= ADVERTISE_PAUSE_ASYM;
phy_write(phy, MII_ADVERTISE, adv);
+ if (phy->features &
+ (SUPPORTED_1000baseT_Full | SUPPORTED_1000baseT_Half)) {
+ adv = phy_read(phy, MII_CTRL1000);
+ if (adv < 0)
+ return adv;
+ adv &= ~(ADVERTISE_1000FULL | ADVERTISE_1000HALF);
+ if (advertise & ADVERTISED_1000baseT_Full)
+ adv |= ADVERTISE_1000FULL;
+ if (advertise & ADVERTISED_1000baseT_Half)
+ adv |= ADVERTISE_1000HALF;
+ phy_write(phy, MII_CTRL1000, adv);
+ }
+
/* Start/Restart aneg */
ctl = phy_read(phy, MII_BMCR);
ctl |= (BMCR_ANENABLE | BMCR_ANRESTART);
@@ -111,14 +112,16 @@ static int genmii_setup_aneg(struct mii_phy *phy, u32 advertise)
static int genmii_setup_forced(struct mii_phy *phy, int speed, int fd)
{
- u16 ctl;
+ int ctl;
- phy->autoneg = 0;
+ phy->autoneg = AUTONEG_DISABLE;
phy->speed = speed;
phy->duplex = fd;
- phy->pause = 0;
+ phy->pause = phy->asym_pause = 0;
ctl = phy_read(phy, MII_BMCR);
+ if (ctl < 0)
+ return ctl;
ctl &= ~(BMCR_FULLDPLX | BMCR_SPEED100 | BMCR_ANENABLE);
/* First reset the PHY */
@@ -132,6 +135,8 @@ static int genmii_setup_forced(struct mii_phy *phy, int speed, int fd)
ctl |= BMCR_SPEED100;
break;
case SPEED_1000:
+ ctl |= BMCR_SPEED1000;
+ break;
default:
return -EINVAL;
}
@@ -144,112 +149,155 @@ static int genmii_setup_forced(struct mii_phy *phy, int speed, int fd)
static int genmii_poll_link(struct mii_phy *phy)
{
- u16 status;
+ int status;
- (void)phy_read(phy, MII_BMSR);
+ /* Clear latched value with dummy read */
+ phy_read(phy, MII_BMSR);
status = phy_read(phy, MII_BMSR);
- if ((status & BMSR_LSTATUS) == 0)
+ if (status < 0 || (status & BMSR_LSTATUS) == 0)
return 0;
- if (phy->autoneg && !(status & BMSR_ANEGCOMPLETE))
+ if (phy->autoneg == AUTONEG_ENABLE && !(status & BMSR_ANEGCOMPLETE))
return 0;
return 1;
}
-#define MII_CIS8201_ACSR 0x1c
-#define ACSR_DUPLEX_STATUS 0x0020
-#define ACSR_SPEED_1000BASET 0x0010
-#define ACSR_SPEED_100BASET 0x0008
-
-static int cis8201_read_link(struct mii_phy *phy)
+static int genmii_read_link(struct mii_phy *phy)
{
- u16 acsr;
+ if (phy->autoneg == AUTONEG_ENABLE) {
+ int glpa = 0;
+ int lpa = phy_read(phy, MII_LPA) & phy_read(phy, MII_ADVERTISE);
+ if (lpa < 0)
+ return lpa;
+
+ if (phy->features &
+ (SUPPORTED_1000baseT_Full | SUPPORTED_1000baseT_Half)) {
+ int adv = phy_read(phy, MII_CTRL1000);
+ glpa = phy_read(phy, MII_STAT1000);
- if (phy->autoneg) {
- acsr = phy_read(phy, MII_CIS8201_ACSR);
+ if (glpa < 0 || adv < 0)
+ return adv;
- if (acsr & ACSR_DUPLEX_STATUS)
+ glpa &= adv << 2;
+ }
+
+ phy->speed = SPEED_10;
+ phy->duplex = DUPLEX_HALF;
+ phy->pause = phy->asym_pause = 0;
+
+ if (glpa & (LPA_1000FULL | LPA_1000HALF)) {
+ phy->speed = SPEED_1000;
+ if (glpa & LPA_1000FULL)
+ phy->duplex = DUPLEX_FULL;
+ } else if (lpa & (LPA_100FULL | LPA_100HALF)) {
+ phy->speed = SPEED_100;
+ if (lpa & LPA_100FULL)
+ phy->duplex = DUPLEX_FULL;
+ } else if (lpa & LPA_10FULL)
+ phy->duplex = DUPLEX_FULL;
+
+ if (phy->duplex == DUPLEX_FULL) {
+ phy->pause = lpa & LPA_PAUSE_CAP ? 1 : 0;
+ phy->asym_pause = lpa & LPA_PAUSE_ASYM ? 1 : 0;
+ }
+ } else {
+ int bmcr = phy_read(phy, MII_BMCR);
+ if (bmcr < 0)
+ return bmcr;
+
+ if (bmcr & BMCR_FULLDPLX)
phy->duplex = DUPLEX_FULL;
else
phy->duplex = DUPLEX_HALF;
- if (acsr & ACSR_SPEED_1000BASET) {
+ if (bmcr & BMCR_SPEED1000)
phy->speed = SPEED_1000;
- } else if (acsr & ACSR_SPEED_100BASET)
+ else if (bmcr & BMCR_SPEED100)
phy->speed = SPEED_100;
else
phy->speed = SPEED_10;
- phy->pause = 0;
- }
- /* On non-aneg, we assume what we put in BMCR is the speed,
- * though magic-aneg shouldn't prevent this case from occurring
- */
+ phy->pause = phy->asym_pause = 0;
+ }
return 0;
}
-static int genmii_read_link(struct mii_phy *phy)
+/* Generic implementation for most 10/100/1000 PHYs */
+static struct mii_phy_ops generic_phy_ops = {
+ .setup_aneg = genmii_setup_aneg,
+ .setup_forced = genmii_setup_forced,
+ .poll_link = genmii_poll_link,
+ .read_link = genmii_read_link
+};
+
+static struct mii_phy_def genmii_phy_def = {
+ .phy_id = 0x00000000,
+ .phy_id_mask = 0x00000000,
+ .name = "Generic MII",
+ .ops = &generic_phy_ops
+};
+
+/* CIS8201 */
+#define MII_CIS8201_10BTCSR 0x16
+#define TENBTCSR_ECHO_DISABLE 0x2000
+#define MII_CIS8201_EPCR 0x17
+#define EPCR_MODE_MASK 0x3000
+#define EPCR_GMII_MODE 0x0000
+#define EPCR_RGMII_MODE 0x1000
+#define EPCR_TBI_MODE 0x2000
+#define EPCR_RTBI_MODE 0x3000
+#define MII_CIS8201_ACSR 0x1c
+#define ACSR_PIN_PRIO_SELECT 0x0004
+
+static int cis8201_init(struct mii_phy *phy)
{
- u16 lpa;
+ int epcr;
- if (phy->autoneg) {
- lpa = phy_read(phy, MII_LPA) & phy_read(phy, MII_ADVERTISE);
+ epcr = phy_read(phy, MII_CIS8201_EPCR);
+ if (epcr < 0)
+ return epcr;
- phy->speed = SPEED_10;
- phy->duplex = DUPLEX_HALF;
- phy->pause = 0;
+ epcr &= ~EPCR_MODE_MASK;
- if (lpa & (LPA_100FULL | LPA_100HALF)) {
- phy->speed = SPEED_100;
- if (lpa & LPA_100FULL)
- phy->duplex = DUPLEX_FULL;
- } else if (lpa & LPA_10FULL)
- phy->duplex = DUPLEX_FULL;
+ switch (phy->mode) {
+ case PHY_MODE_TBI:
+ epcr |= EPCR_TBI_MODE;
+ break;
+ case PHY_MODE_RTBI:
+ epcr |= EPCR_RTBI_MODE;
+ break;
+ case PHY_MODE_GMII:
+ epcr |= EPCR_GMII_MODE;
+ break;
+ case PHY_MODE_RGMII:
+ default:
+ epcr |= EPCR_RGMII_MODE;
}
- /* On non-aneg, we assume what we put in BMCR is the speed,
- * though magic-aneg shouldn't prevent this case from occurring
- */
+
+ phy_write(phy, MII_CIS8201_EPCR, epcr);
+
+ /* MII regs override strap pins */
+ phy_write(phy, MII_CIS8201_ACSR,
+ phy_read(phy, MII_CIS8201_ACSR) | ACSR_PIN_PRIO_SELECT);
+
+ /* Disable TX_EN -> CRS echo mode, otherwise 10/HDX doesn't work */
+ phy_write(phy, MII_CIS8201_10BTCSR,
+ phy_read(phy, MII_CIS8201_10BTCSR) | TENBTCSR_ECHO_DISABLE);
return 0;
}
-#define MII_BASIC_FEATURES (SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full | \
- SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full | \
- SUPPORTED_Autoneg | SUPPORTED_TP | SUPPORTED_MII)
-#define MII_GBIT_FEATURES (MII_BASIC_FEATURES | \
- SUPPORTED_1000baseT_Half | SUPPORTED_1000baseT_Full)
-
-/* CIS8201 phy ops */
static struct mii_phy_ops cis8201_phy_ops = {
- init:cis8201_init,
- setup_aneg:genmii_setup_aneg,
- setup_forced:genmii_setup_forced,
- poll_link:genmii_poll_link,
- read_link:cis8201_read_link
-};
-
-/* Generic implementation for most 10/100 PHYs */
-static struct mii_phy_ops generic_phy_ops = {
- setup_aneg:genmii_setup_aneg,
- setup_forced:genmii_setup_forced,
- poll_link:genmii_poll_link,
- read_link:genmii_read_link
+ .init = cis8201_init,
+ .setup_aneg = genmii_setup_aneg,
+ .setup_forced = genmii_setup_forced,
+ .poll_link = genmii_poll_link,
+ .read_link = genmii_read_link
};
static struct mii_phy_def cis8201_phy_def = {
- phy_id:0x000fc410,
- phy_id_mask:0x000ffff0,
- name:"CIS8201 Gigabit Ethernet",
- features:MII_GBIT_FEATURES,
- magic_aneg:0,
- ops:&cis8201_phy_ops
-};
-
-static struct mii_phy_def genmii_phy_def = {
- phy_id:0x00000000,
- phy_id_mask:0x00000000,
- name:"Generic MII",
- features:MII_BASIC_FEATURES,
- magic_aneg:0,
- ops:&generic_phy_ops
+ .phy_id = 0x000fc410,
+ .phy_id_mask = 0x000ffff0,
+ .name = "CIS8201 Gigabit Ethernet",
+ .ops = &cis8201_phy_ops
};
static struct mii_phy_def *mii_phy_table[] = {
@@ -258,39 +306,60 @@ static struct mii_phy_def *mii_phy_table[] = {
NULL
};
-int mii_phy_probe(struct mii_phy *phy, int mii_id)
+int mii_phy_probe(struct mii_phy *phy, int address)
{
- int rc;
- u32 id;
struct mii_phy_def *def;
int i;
+ u32 id;
- phy->autoneg = 0;
+ phy->autoneg = AUTONEG_DISABLE;
phy->advertising = 0;
- phy->mii_id = mii_id;
- phy->speed = 0;
- phy->duplex = 0;
- phy->pause = 0;
-
- /* Take PHY out of isloate mode and reset it. */
- rc = reset_one_mii_phy(phy, mii_id);
- if (rc)
+ phy->address = address;
+ phy->speed = SPEED_10;
+ phy->duplex = DUPLEX_HALF;
+ phy->pause = phy->asym_pause = 0;
+
+ /* Take PHY out of isolate mode and reset it. */
+ if (mii_reset_phy(phy))
return -ENODEV;
/* Read ID and find matching entry */
- id = (phy_read(phy, MII_PHYSID1) << 16 | phy_read(phy, MII_PHYSID2))
- & 0xfffffff0;
+ id = (phy_read(phy, MII_PHYSID1) << 16) | phy_read(phy, MII_PHYSID2);
for (i = 0; (def = mii_phy_table[i]) != NULL; i++)
if ((id & def->phy_id_mask) == def->phy_id)
break;
/* Should never be NULL (we have a generic entry), but... */
- if (def == NULL)
+ if (!def)
return -ENODEV;
phy->def = def;
+ /* Determine PHY features if needed */
+ phy->features = def->features;
+ if (!phy->features) {
+ u16 bmsr = phy_read(phy, MII_BMSR);
+ if (bmsr & BMSR_ANEGCAPABLE)
+ phy->features |= SUPPORTED_Autoneg;
+ if (bmsr & BMSR_10HALF)
+ phy->features |= SUPPORTED_10baseT_Half;
+ if (bmsr & BMSR_10FULL)
+ phy->features |= SUPPORTED_10baseT_Full;
+ if (bmsr & BMSR_100HALF)
+ phy->features |= SUPPORTED_100baseT_Half;
+ if (bmsr & BMSR_100FULL)
+ phy->features |= SUPPORTED_100baseT_Full;
+ if (bmsr & BMSR_ESTATEN) {
+ u16 esr = phy_read(phy, MII_ESTATUS);
+ if (esr & ESTATUS_1000_TFULL)
+ phy->features |= SUPPORTED_1000baseT_Full;
+ if (esr & ESTATUS_1000_THALF)
+ phy->features |= SUPPORTED_1000baseT_Half;
+ }
+ phy->features |= SUPPORTED_MII;
+ }
+
/* Setup default advertising */
- phy->advertising = def->features;
+ phy->advertising = phy->features;
return 0;
}
diff --git a/drivers/net/ibm_emac/ibm_emac_phy.h b/drivers/net/ibm_emac/ibm_emac_phy.h
index 61afbea96563..a70e0fea54c4 100644
--- a/drivers/net/ibm_emac/ibm_emac_phy.h
+++ b/drivers/net/ibm_emac/ibm_emac_phy.h
@@ -1,65 +1,25 @@
-
/*
- * ibm_emac_phy.h
- *
+ * drivers/net/ibm_emac/ibm_emac_phy.h
*
- * Benjamin Herrenschmidt <benh@kernel.crashing.org>
- * February 2003
+ * Driver for PowerPC 4xx on-chip ethernet controller, PHY support
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
+ * Benjamin Herrenschmidt <benh@kernel.crashing.org>
+ * February 2003
*
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
- * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 675 Mass Ave, Cambridge, MA 02139, USA.
+ * Minor additions by Eugene Surovegin <ebs@ebshome.net>, 2004
*
+ * 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 file basically duplicates sungem_phy.{c,h} with different PHYs
* supported. I'm looking into merging that in a single mii layer more
* flexible than mii.c
*/
-#ifndef _IBM_EMAC_PHY_H_
-#define _IBM_EMAC_PHY_H_
-
-/*
- * PHY mode settings
- * Used for multi-mode capable PHYs
- */
-#define PHY_MODE_NA 0
-#define PHY_MODE_MII 1
-#define PHY_MODE_RMII 2
-#define PHY_MODE_SMII 3
-#define PHY_MODE_RGMII 4
-#define PHY_MODE_TBI 5
-#define PHY_MODE_GMII 6
-#define PHY_MODE_RTBI 7
-#define PHY_MODE_SGMII 8
-
-/*
- * PHY specific registers/values
- */
-
-/* CIS8201 */
-#define MII_CIS8201_EPCR 0x17
-#define EPCR_MODE_MASK 0x3000
-#define EPCR_GMII_MODE 0x0000
-#define EPCR_RGMII_MODE 0x1000
-#define EPCR_TBI_MODE 0x2000
-#define EPCR_RTBI_MODE 0x3000
+#ifndef _IBM_OCP_PHY_H_
+#define _IBM_OCP_PHY_H_
struct mii_phy;
@@ -77,7 +37,8 @@ struct mii_phy_ops {
struct mii_phy_def {
u32 phy_id; /* Concatenated ID1 << 16 | ID2 */
u32 phy_id_mask; /* Significant bits */
- u32 features; /* Ethtool SUPPORTED_* defines */
+ u32 features; /* Ethtool SUPPORTED_* defines or
+ 0 for autodetect */
int magic_aneg; /* Autoneg does all speed test for us */
const char *name;
const struct mii_phy_ops *ops;
@@ -86,8 +47,11 @@ struct mii_phy_def {
/* An instance of a PHY, partially borrowed from mii_if_info */
struct mii_phy {
struct mii_phy_def *def;
- int advertising;
- int mii_id;
+ u32 advertising; /* Ethtool ADVERTISED_* defines */
+ u32 features; /* Copied from mii_phy_def.features
+ or determined automaticaly */
+ int address; /* PHY address */
+ int mode; /* PHY mode */
/* 1: autoneg enabled, 0: disabled */
int autoneg;
@@ -98,40 +62,19 @@ struct mii_phy {
int speed;
int duplex;
int pause;
-
- /* PHY mode - if needed */
- int mode;
+ int asym_pause;
/* Provided by host chip */
struct net_device *dev;
- int (*mdio_read) (struct net_device * dev, int mii_id, int reg);
- void (*mdio_write) (struct net_device * dev, int mii_id, int reg,
+ int (*mdio_read) (struct net_device * dev, int addr, int reg);
+ void (*mdio_write) (struct net_device * dev, int addr, int reg,
int val);
};
/* Pass in a struct mii_phy with dev, mdio_read and mdio_write
* filled, the remaining fields will be filled on return
*/
-extern int mii_phy_probe(struct mii_phy *phy, int mii_id);
-
-static inline int __phy_read(struct mii_phy *phy, int id, int reg)
-{
- return phy->mdio_read(phy->dev, id, reg);
-}
-
-static inline void __phy_write(struct mii_phy *phy, int id, int reg, int val)
-{
- phy->mdio_write(phy->dev, id, reg, val);
-}
-
-static inline int phy_read(struct mii_phy *phy, int reg)
-{
- return phy->mdio_read(phy->dev, phy->mii_id, reg);
-}
-
-static inline void phy_write(struct mii_phy *phy, int reg, int val)
-{
- phy->mdio_write(phy->dev, phy->mii_id, reg, val);
-}
+int mii_phy_probe(struct mii_phy *phy, int address);
+int mii_reset_phy(struct mii_phy *phy);
-#endif /* _IBM_EMAC_PHY_H_ */
+#endif /* _IBM_OCP_PHY_H_ */
diff --git a/drivers/net/ibm_emac/ibm_emac_rgmii.c b/drivers/net/ibm_emac/ibm_emac_rgmii.c
new file mode 100644
index 000000000000..f0b1ffb2dbbf
--- /dev/null
+++ b/drivers/net/ibm_emac/ibm_emac_rgmii.c
@@ -0,0 +1,201 @@
+/*
+ * drivers/net/ibm_emac/ibm_emac_rgmii.c
+ *
+ * Driver for PowerPC 4xx on-chip ethernet controller, RGMII bridge support.
+ *
+ * Copyright (c) 2004, 2005 Zultys Technologies.
+ * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
+ *
+ * Based on original work by
+ * Matt Porter <mporter@kernel.crashing.org>
+ * Copyright 2004 MontaVista Software, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ */
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/ethtool.h>
+#include <asm/io.h>
+
+#include "ibm_emac_core.h"
+#include "ibm_emac_debug.h"
+
+/* RGMIIx_FER */
+#define RGMII_FER_MASK(idx) (0x7 << ((idx) * 4))
+#define RGMII_FER_RTBI(idx) (0x4 << ((idx) * 4))
+#define RGMII_FER_RGMII(idx) (0x5 << ((idx) * 4))
+#define RGMII_FER_TBI(idx) (0x6 << ((idx) * 4))
+#define RGMII_FER_GMII(idx) (0x7 << ((idx) * 4))
+
+/* RGMIIx_SSR */
+#define RGMII_SSR_MASK(idx) (0x7 << ((idx) * 8))
+#define RGMII_SSR_100(idx) (0x2 << ((idx) * 8))
+#define RGMII_SSR_1000(idx) (0x4 << ((idx) * 8))
+
+/* RGMII bridge supports only GMII/TBI and RGMII/RTBI PHYs */
+static inline int rgmii_valid_mode(int phy_mode)
+{
+ return phy_mode == PHY_MODE_GMII ||
+ phy_mode == PHY_MODE_RGMII ||
+ phy_mode == PHY_MODE_TBI ||
+ phy_mode == PHY_MODE_RTBI;
+}
+
+static inline const char *rgmii_mode_name(int mode)
+{
+ switch (mode) {
+ case PHY_MODE_RGMII:
+ return "RGMII";
+ case PHY_MODE_TBI:
+ return "TBI";
+ case PHY_MODE_GMII:
+ return "GMII";
+ case PHY_MODE_RTBI:
+ return "RTBI";
+ default:
+ BUG();
+ }
+}
+
+static inline u32 rgmii_mode_mask(int mode, int input)
+{
+ switch (mode) {
+ case PHY_MODE_RGMII:
+ return RGMII_FER_RGMII(input);
+ case PHY_MODE_TBI:
+ return RGMII_FER_TBI(input);
+ case PHY_MODE_GMII:
+ return RGMII_FER_GMII(input);
+ case PHY_MODE_RTBI:
+ return RGMII_FER_RTBI(input);
+ default:
+ BUG();
+ }
+}
+
+static int __init rgmii_init(struct ocp_device *ocpdev, int input, int mode)
+{
+ struct ibm_ocp_rgmii *dev = ocp_get_drvdata(ocpdev);
+ struct rgmii_regs *p;
+
+ RGMII_DBG("%d: init(%d, %d)" NL, ocpdev->def->index, input, mode);
+
+ if (!dev) {
+ dev = kzalloc(sizeof(struct ibm_ocp_rgmii), GFP_KERNEL);
+ if (!dev) {
+ printk(KERN_ERR
+ "rgmii%d: couldn't allocate device structure!\n",
+ ocpdev->def->index);
+ return -ENOMEM;
+ }
+
+ p = (struct rgmii_regs *)ioremap(ocpdev->def->paddr,
+ sizeof(struct rgmii_regs));
+ if (!p) {
+ printk(KERN_ERR
+ "rgmii%d: could not ioremap device registers!\n",
+ ocpdev->def->index);
+ kfree(dev);
+ return -ENOMEM;
+ }
+
+ dev->base = p;
+ ocp_set_drvdata(ocpdev, dev);
+
+ /* Disable all inputs by default */
+ out_be32(&p->fer, 0);
+ } else
+ p = dev->base;
+
+ /* Enable this input */
+ out_be32(&p->fer, in_be32(&p->fer) | rgmii_mode_mask(mode, input));
+
+ printk(KERN_NOTICE "rgmii%d: input %d in %s mode\n",
+ ocpdev->def->index, input, rgmii_mode_name(mode));
+
+ ++dev->users;
+ return 0;
+}
+
+int __init rgmii_attach(void *emac)
+{
+ struct ocp_enet_private *dev = emac;
+ struct ocp_func_emac_data *emacdata = dev->def->additions;
+
+ /* Check if we need to attach to a RGMII */
+ if (emacdata->rgmii_idx >= 0 && rgmii_valid_mode(emacdata->phy_mode)) {
+ dev->rgmii_input = emacdata->rgmii_mux;
+ dev->rgmii_dev =
+ ocp_find_device(OCP_VENDOR_IBM, OCP_FUNC_RGMII,
+ emacdata->rgmii_idx);
+ if (!dev->rgmii_dev) {
+ printk(KERN_ERR "emac%d: unknown rgmii%d!\n",
+ dev->def->index, emacdata->rgmii_idx);
+ return -ENODEV;
+ }
+ if (rgmii_init
+ (dev->rgmii_dev, dev->rgmii_input, emacdata->phy_mode)) {
+ printk(KERN_ERR
+ "emac%d: rgmii%d initialization failed!\n",
+ dev->def->index, emacdata->rgmii_idx);
+ return -ENODEV;
+ }
+ }
+ return 0;
+}
+
+void rgmii_set_speed(struct ocp_device *ocpdev, int input, int speed)
+{
+ struct ibm_ocp_rgmii *dev = ocp_get_drvdata(ocpdev);
+ u32 ssr = in_be32(&dev->base->ssr) & ~RGMII_SSR_MASK(input);
+
+ RGMII_DBG("%d: speed(%d, %d)" NL, ocpdev->def->index, input, speed);
+
+ if (speed == SPEED_1000)
+ ssr |= RGMII_SSR_1000(input);
+ else if (speed == SPEED_100)
+ ssr |= RGMII_SSR_100(input);
+
+ out_be32(&dev->base->ssr, ssr);
+}
+
+void __exit __rgmii_fini(struct ocp_device *ocpdev, int input)
+{
+ struct ibm_ocp_rgmii *dev = ocp_get_drvdata(ocpdev);
+ BUG_ON(!dev || dev->users == 0);
+
+ RGMII_DBG("%d: fini(%d)" NL, ocpdev->def->index, input);
+
+ /* Disable this input */
+ out_be32(&dev->base->fer,
+ in_be32(&dev->base->fer) & ~RGMII_FER_MASK(input));
+
+ if (!--dev->users) {
+ /* Free everything if this is the last user */
+ ocp_set_drvdata(ocpdev, NULL);
+ iounmap((void *)dev->base);
+ kfree(dev);
+ }
+}
+
+int __rgmii_get_regs_len(struct ocp_device *ocpdev)
+{
+ return sizeof(struct emac_ethtool_regs_subhdr) +
+ sizeof(struct rgmii_regs);
+}
+
+void *rgmii_dump_regs(struct ocp_device *ocpdev, void *buf)
+{
+ struct ibm_ocp_rgmii *dev = ocp_get_drvdata(ocpdev);
+ struct emac_ethtool_regs_subhdr *hdr = buf;
+ struct rgmii_regs *regs = (struct rgmii_regs *)(hdr + 1);
+
+ hdr->version = 0;
+ hdr->index = ocpdev->def->index;
+ memcpy_fromio(regs, dev->base, sizeof(struct rgmii_regs));
+ return regs + 1;
+}
diff --git a/drivers/net/ibm_emac/ibm_emac_rgmii.h b/drivers/net/ibm_emac/ibm_emac_rgmii.h
index 49f188f4ea6e..a1ffb8a44fff 100644
--- a/drivers/net/ibm_emac/ibm_emac_rgmii.h
+++ b/drivers/net/ibm_emac/ibm_emac_rgmii.h
@@ -1,5 +1,7 @@
/*
- * Defines for the IBM RGMII bridge
+ * drivers/net/ibm_emac/ibm_emac_rgmii.c
+ *
+ * Driver for PowerPC 4xx on-chip ethernet controller, RGMII bridge support.
*
* Based on ocp_zmii.h/ibm_emac_zmii.h
* Armin Kuster akuster@mvista.com
@@ -7,6 +9,9 @@
* Copyright 2004 MontaVista Software, Inc.
* Matt Porter <mporter@kernel.crashing.org>
*
+ * Copyright (c) 2004, 2005 Zultys Technologies.
+ * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.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
@@ -19,47 +24,42 @@
#include <linux/config.h>
/* RGMII bridge */
-typedef struct rgmii_regs {
+struct rgmii_regs {
u32 fer; /* Function enable register */
u32 ssr; /* Speed select register */
-} rgmii_t;
-
-#define RGMII_INPUTS 4
+};
/* RGMII device */
struct ibm_ocp_rgmii {
struct rgmii_regs *base;
- int mode[RGMII_INPUTS];
int users; /* number of EMACs using this RGMII bridge */
};
-/* Fuctional Enable Reg */
-#define RGMII_FER_MASK(x) (0x00000007 << (4*x))
-#define RGMII_RTBI 0x00000004
-#define RGMII_RGMII 0x00000005
-#define RGMII_TBI 0x00000006
-#define RGMII_GMII 0x00000007
-
-/* Speed Selection reg */
+#ifdef CONFIG_IBM_EMAC_RGMII
+int rgmii_attach(void *emac) __init;
-#define RGMII_SP2_100 0x00000002
-#define RGMII_SP2_1000 0x00000004
-#define RGMII_SP3_100 0x00000200
-#define RGMII_SP3_1000 0x00000400
+void __rgmii_fini(struct ocp_device *ocpdev, int input) __exit;
+static inline void rgmii_fini(struct ocp_device *ocpdev, int input)
+{
+ if (ocpdev)
+ __rgmii_fini(ocpdev, input);
+}
-#define RGMII_MII2_SPDMASK 0x00000007
-#define RGMII_MII3_SPDMASK 0x00000700
+void rgmii_set_speed(struct ocp_device *ocpdev, int input, int speed);
-#define RGMII_MII2_100MB RGMII_SP2_100 & ~RGMII_SP2_1000
-#define RGMII_MII2_1000MB RGMII_SP2_1000 & ~RGMII_SP2_100
-#define RGMII_MII2_10MB ~(RGMII_SP2_100 | RGMII_SP2_1000)
-#define RGMII_MII3_100MB RGMII_SP3_100 & ~RGMII_SP3_1000
-#define RGMII_MII3_1000MB RGMII_SP3_1000 & ~RGMII_SP3_100
-#define RGMII_MII3_10MB ~(RGMII_SP3_100 | RGMII_SP3_1000)
+int __rgmii_get_regs_len(struct ocp_device *ocpdev);
+static inline int rgmii_get_regs_len(struct ocp_device *ocpdev)
+{
+ return ocpdev ? __rgmii_get_regs_len(ocpdev) : 0;
+}
-#define RTBI 0
-#define RGMII 1
-#define TBI 2
-#define GMII 3
+void *rgmii_dump_regs(struct ocp_device *ocpdev, void *buf);
+#else
+# define rgmii_attach(x) 0
+# define rgmii_fini(x,y) ((void)0)
+# define rgmii_set_speed(x,y,z) ((void)0)
+# define rgmii_get_regs_len(x) 0
+# define rgmii_dump_regs(x,buf) (buf)
+#endif /* !CONFIG_IBM_EMAC_RGMII */
#endif /* _IBM_EMAC_RGMII_H_ */
diff --git a/drivers/net/ibm_emac/ibm_emac_tah.c b/drivers/net/ibm_emac/ibm_emac_tah.c
new file mode 100644
index 000000000000..af08afc22f9f
--- /dev/null
+++ b/drivers/net/ibm_emac/ibm_emac_tah.c
@@ -0,0 +1,111 @@
+/*
+ * drivers/net/ibm_emac/ibm_emac_tah.c
+ *
+ * Driver for PowerPC 4xx on-chip ethernet controller, TAH support.
+ *
+ * Copyright 2004 MontaVista Software, Inc.
+ * Matt Porter <mporter@kernel.crashing.org>
+ *
+ * Copyright (c) 2005 Eugene Surovegin <ebs@ebshome.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/config.h>
+#include <asm/io.h>
+
+#include "ibm_emac_core.h"
+
+static int __init tah_init(struct ocp_device *ocpdev)
+{
+ struct tah_regs *p;
+
+ if (ocp_get_drvdata(ocpdev)) {
+ printk(KERN_ERR "tah%d: already in use!\n", ocpdev->def->index);
+ return -EBUSY;
+ }
+
+ /* Initialize TAH and enable IPv4 checksum verification, no TSO yet */
+ p = (struct tah_regs *)ioremap(ocpdev->def->paddr, sizeof(*p));
+ if (!p) {
+ printk(KERN_ERR "tah%d: could not ioremap device registers!\n",
+ ocpdev->def->index);
+ return -ENOMEM;
+ }
+ ocp_set_drvdata(ocpdev, p);
+ __tah_reset(ocpdev);
+
+ return 0;
+}
+
+int __init tah_attach(void *emac)
+{
+ struct ocp_enet_private *dev = emac;
+ struct ocp_func_emac_data *emacdata = dev->def->additions;
+
+ /* Check if we need to attach to a TAH */
+ if (emacdata->tah_idx >= 0) {
+ dev->tah_dev = ocp_find_device(OCP_ANY_ID, OCP_FUNC_TAH,
+ emacdata->tah_idx);
+ if (!dev->tah_dev) {
+ printk(KERN_ERR "emac%d: unknown tah%d!\n",
+ dev->def->index, emacdata->tah_idx);
+ return -ENODEV;
+ }
+ if (tah_init(dev->tah_dev)) {
+ printk(KERN_ERR
+ "emac%d: tah%d initialization failed!\n",
+ dev->def->index, emacdata->tah_idx);
+ return -ENODEV;
+ }
+ }
+ return 0;
+}
+
+void __exit __tah_fini(struct ocp_device *ocpdev)
+{
+ struct tah_regs *p = ocp_get_drvdata(ocpdev);
+ BUG_ON(!p);
+ ocp_set_drvdata(ocpdev, NULL);
+ iounmap((void *)p);
+}
+
+void __tah_reset(struct ocp_device *ocpdev)
+{
+ struct tah_regs *p = ocp_get_drvdata(ocpdev);
+ int n;
+
+ /* Reset TAH */
+ out_be32(&p->mr, TAH_MR_SR);
+ n = 100;
+ while ((in_be32(&p->mr) & TAH_MR_SR) && n)
+ --n;
+
+ if (unlikely(!n))
+ printk(KERN_ERR "tah%d: reset timeout\n", ocpdev->def->index);
+
+ /* 10KB TAH TX FIFO accomodates the max MTU of 9000 */
+ out_be32(&p->mr,
+ TAH_MR_CVR | TAH_MR_ST_768 | TAH_MR_TFS_10KB | TAH_MR_DTFP |
+ TAH_MR_DIG);
+}
+
+int __tah_get_regs_len(struct ocp_device *ocpdev)
+{
+ return sizeof(struct emac_ethtool_regs_subhdr) +
+ sizeof(struct tah_regs);
+}
+
+void *tah_dump_regs(struct ocp_device *ocpdev, void *buf)
+{
+ struct tah_regs *dev = ocp_get_drvdata(ocpdev);
+ struct emac_ethtool_regs_subhdr *hdr = buf;
+ struct tah_regs *regs = (struct tah_regs *)(hdr + 1);
+
+ hdr->version = 0;
+ hdr->index = ocpdev->def->index;
+ memcpy_fromio(regs, dev, sizeof(struct tah_regs));
+ return regs + 1;
+}
diff --git a/drivers/net/ibm_emac/ibm_emac_tah.h b/drivers/net/ibm_emac/ibm_emac_tah.h
index ecfc69805521..9299b5dd7eb1 100644
--- a/drivers/net/ibm_emac/ibm_emac_tah.h
+++ b/drivers/net/ibm_emac/ibm_emac_tah.h
@@ -1,9 +1,13 @@
/*
- * Defines for the IBM TAH
+ * drivers/net/ibm_emac/ibm_emac_tah.h
+ *
+ * Driver for PowerPC 4xx on-chip ethernet controller, TAH support.
*
* Copyright 2004 MontaVista Software, Inc.
* Matt Porter <mporter@kernel.crashing.org>
*
+ * Copyright (c) 2005 Eugene Surovegin <ebs@ebshome.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
@@ -13,36 +17,72 @@
#ifndef _IBM_EMAC_TAH_H
#define _IBM_EMAC_TAH_H
+#include <linux/config.h>
+#include <linux/init.h>
+#include <asm/ocp.h>
+
/* TAH */
-typedef struct tah_regs {
- u32 tah_revid;
+struct tah_regs {
+ u32 revid;
u32 pad[3];
- u32 tah_mr;
- u32 tah_ssr0;
- u32 tah_ssr1;
- u32 tah_ssr2;
- u32 tah_ssr3;
- u32 tah_ssr4;
- u32 tah_ssr5;
- u32 tah_tsr;
-} tah_t;
+ u32 mr;
+ u32 ssr0;
+ u32 ssr1;
+ u32 ssr2;
+ u32 ssr3;
+ u32 ssr4;
+ u32 ssr5;
+ u32 tsr;
+};
/* TAH engine */
-#define TAH_MR_CVR 0x80000000
-#define TAH_MR_SR 0x40000000
-#define TAH_MR_ST_256 0x01000000
-#define TAH_MR_ST_512 0x02000000
-#define TAH_MR_ST_768 0x03000000
-#define TAH_MR_ST_1024 0x04000000
-#define TAH_MR_ST_1280 0x05000000
-#define TAH_MR_ST_1536 0x06000000
-#define TAH_MR_TFS_16KB 0x00000000
-#define TAH_MR_TFS_2KB 0x00200000
-#define TAH_MR_TFS_4KB 0x00400000
-#define TAH_MR_TFS_6KB 0x00600000
-#define TAH_MR_TFS_8KB 0x00800000
-#define TAH_MR_TFS_10KB 0x00a00000
-#define TAH_MR_DTFP 0x00100000
-#define TAH_MR_DIG 0x00080000
+#define TAH_MR_CVR 0x80000000
+#define TAH_MR_SR 0x40000000
+#define TAH_MR_ST_256 0x01000000
+#define TAH_MR_ST_512 0x02000000
+#define TAH_MR_ST_768 0x03000000
+#define TAH_MR_ST_1024 0x04000000
+#define TAH_MR_ST_1280 0x05000000
+#define TAH_MR_ST_1536 0x06000000
+#define TAH_MR_TFS_16KB 0x00000000
+#define TAH_MR_TFS_2KB 0x00200000
+#define TAH_MR_TFS_4KB 0x00400000
+#define TAH_MR_TFS_6KB 0x00600000
+#define TAH_MR_TFS_8KB 0x00800000
+#define TAH_MR_TFS_10KB 0x00a00000
+#define TAH_MR_DTFP 0x00100000
+#define TAH_MR_DIG 0x00080000
+
+#ifdef CONFIG_IBM_EMAC_TAH
+int tah_attach(void *emac) __init;
+
+void __tah_fini(struct ocp_device *ocpdev) __exit;
+static inline void tah_fini(struct ocp_device *ocpdev)
+{
+ if (ocpdev)
+ __tah_fini(ocpdev);
+}
+
+void __tah_reset(struct ocp_device *ocpdev);
+static inline void tah_reset(struct ocp_device *ocpdev)
+{
+ if (ocpdev)
+ __tah_reset(ocpdev);
+}
+
+int __tah_get_regs_len(struct ocp_device *ocpdev);
+static inline int tah_get_regs_len(struct ocp_device *ocpdev)
+{
+ return ocpdev ? __tah_get_regs_len(ocpdev) : 0;
+}
+
+void *tah_dump_regs(struct ocp_device *ocpdev, void *buf);
+#else
+# define tah_attach(x) 0
+# define tah_fini(x) ((void)0)
+# define tah_reset(x) ((void)0)
+# define tah_get_regs_len(x) 0
+# define tah_dump_regs(x,buf) (buf)
+#endif /* !CONFIG_IBM_EMAC_TAH */
#endif /* _IBM_EMAC_TAH_H */
diff --git a/drivers/net/ibm_emac/ibm_emac_zmii.c b/drivers/net/ibm_emac/ibm_emac_zmii.c
new file mode 100644
index 000000000000..35c1185079ed
--- /dev/null
+++ b/drivers/net/ibm_emac/ibm_emac_zmii.c
@@ -0,0 +1,255 @@
+/*
+ * drivers/net/ibm_emac/ibm_emac_zmii.c
+ *
+ * Driver for PowerPC 4xx on-chip ethernet controller, ZMII bridge support.
+ *
+ * Copyright (c) 2004, 2005 Zultys Technologies.
+ * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
+ *
+ * Based on original work by
+ * Armin Kuster <akuster@mvista.com>
+ * Copyright 2001 MontaVista Softare Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ */
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/ethtool.h>
+#include <asm/io.h>
+
+#include "ibm_emac_core.h"
+#include "ibm_emac_debug.h"
+
+/* ZMIIx_FER */
+#define ZMII_FER_MDI(idx) (0x80000000 >> ((idx) * 4))
+#define ZMII_FER_MDI_ALL (ZMII_FER_MDI(0) | ZMII_FER_MDI(1) | \
+ ZMII_FER_MDI(2) | ZMII_FER_MDI(3))
+
+#define ZMII_FER_SMII(idx) (0x40000000 >> ((idx) * 4))
+#define ZMII_FER_RMII(idx) (0x20000000 >> ((idx) * 4))
+#define ZMII_FER_MII(idx) (0x10000000 >> ((idx) * 4))
+
+/* ZMIIx_SSR */
+#define ZMII_SSR_SCI(idx) (0x40000000 >> ((idx) * 4))
+#define ZMII_SSR_FSS(idx) (0x20000000 >> ((idx) * 4))
+#define ZMII_SSR_SP(idx) (0x10000000 >> ((idx) * 4))
+
+/* ZMII only supports MII, RMII and SMII
+ * we also support autodetection for backward compatibility
+ */
+static inline int zmii_valid_mode(int mode)
+{
+ return mode == PHY_MODE_MII ||
+ mode == PHY_MODE_RMII ||
+ mode == PHY_MODE_SMII ||
+ mode == PHY_MODE_NA;
+}
+
+static inline const char *zmii_mode_name(int mode)
+{
+ switch (mode) {
+ case PHY_MODE_MII:
+ return "MII";
+ case PHY_MODE_RMII:
+ return "RMII";
+ case PHY_MODE_SMII:
+ return "SMII";
+ default:
+ BUG();
+ }
+}
+
+static inline u32 zmii_mode_mask(int mode, int input)
+{
+ switch (mode) {
+ case PHY_MODE_MII:
+ return ZMII_FER_MII(input);
+ case PHY_MODE_RMII:
+ return ZMII_FER_RMII(input);
+ case PHY_MODE_SMII:
+ return ZMII_FER_SMII(input);
+ default:
+ return 0;
+ }
+}
+
+static int __init zmii_init(struct ocp_device *ocpdev, int input, int *mode)
+{
+ struct ibm_ocp_zmii *dev = ocp_get_drvdata(ocpdev);
+ struct zmii_regs *p;
+
+ ZMII_DBG("%d: init(%d, %d)" NL, ocpdev->def->index, input, *mode);
+
+ if (!dev) {
+ dev = kzalloc(sizeof(struct ibm_ocp_zmii), GFP_KERNEL);
+ if (!dev) {
+ printk(KERN_ERR
+ "zmii%d: couldn't allocate device structure!\n",
+ ocpdev->def->index);
+ return -ENOMEM;
+ }
+ dev->mode = PHY_MODE_NA;
+
+ p = (struct zmii_regs *)ioremap(ocpdev->def->paddr,
+ sizeof(struct zmii_regs));
+ if (!p) {
+ printk(KERN_ERR
+ "zmii%d: could not ioremap device registers!\n",
+ ocpdev->def->index);
+ kfree(dev);
+ return -ENOMEM;
+ }
+ dev->base = p;
+ ocp_set_drvdata(ocpdev, dev);
+
+ /* We may need FER value for autodetection later */
+ dev->fer_save = in_be32(&p->fer);
+
+ /* Disable all inputs by default */
+ out_be32(&p->fer, 0);
+ } else
+ p = dev->base;
+
+ if (!zmii_valid_mode(*mode)) {
+ /* Probably an EMAC connected to RGMII,
+ * but it still may need ZMII for MDIO
+ */
+ goto out;
+ }
+
+ /* Autodetect ZMII mode if not specified.
+ * This is only for backward compatibility with the old driver.
+ * Please, always specify PHY mode in your board port to avoid
+ * any surprises.
+ */
+ if (dev->mode == PHY_MODE_NA) {
+ if (*mode == PHY_MODE_NA) {
+ u32 r = dev->fer_save;
+
+ ZMII_DBG("%d: autodetecting mode, FER = 0x%08x" NL,
+ ocpdev->def->index, r);
+
+ if (r & (ZMII_FER_MII(0) | ZMII_FER_MII(1)))
+ dev->mode = PHY_MODE_MII;
+ else if (r & (ZMII_FER_RMII(0) | ZMII_FER_RMII(1)))
+ dev->mode = PHY_MODE_RMII;
+ else
+ dev->mode = PHY_MODE_SMII;
+ } else
+ dev->mode = *mode;
+
+ printk(KERN_NOTICE "zmii%d: bridge in %s mode\n",
+ ocpdev->def->index, zmii_mode_name(dev->mode));
+ } else {
+ /* All inputs must use the same mode */
+ if (*mode != PHY_MODE_NA && *mode != dev->mode) {
+ printk(KERN_ERR
+ "zmii%d: invalid mode %d specified for input %d\n",
+ ocpdev->def->index, *mode, input);
+ return -EINVAL;
+ }
+ }
+
+ /* Report back correct PHY mode,
+ * it may be used during PHY initialization.
+ */
+ *mode = dev->mode;
+
+ /* Enable this input */
+ out_be32(&p->fer, in_be32(&p->fer) | zmii_mode_mask(dev->mode, input));
+ out:
+ ++dev->users;
+ return 0;
+}
+
+int __init zmii_attach(void *emac)
+{
+ struct ocp_enet_private *dev = emac;
+ struct ocp_func_emac_data *emacdata = dev->def->additions;
+
+ if (emacdata->zmii_idx >= 0) {
+ dev->zmii_input = emacdata->zmii_mux;
+ dev->zmii_dev =
+ ocp_find_device(OCP_VENDOR_IBM, OCP_FUNC_ZMII,
+ emacdata->zmii_idx);
+ if (!dev->zmii_dev) {
+ printk(KERN_ERR "emac%d: unknown zmii%d!\n",
+ dev->def->index, emacdata->zmii_idx);
+ return -ENODEV;
+ }
+ if (zmii_init
+ (dev->zmii_dev, dev->zmii_input, &emacdata->phy_mode)) {
+ printk(KERN_ERR
+ "emac%d: zmii%d initialization failed!\n",
+ dev->def->index, emacdata->zmii_idx);
+ return -ENODEV;
+ }
+ }
+ return 0;
+}
+
+void __zmii_enable_mdio(struct ocp_device *ocpdev, int input)
+{
+ struct ibm_ocp_zmii *dev = ocp_get_drvdata(ocpdev);
+ u32 fer = in_be32(&dev->base->fer) & ~ZMII_FER_MDI_ALL;
+
+ ZMII_DBG2("%d: mdio(%d)" NL, ocpdev->def->index, input);
+
+ out_be32(&dev->base->fer, fer | ZMII_FER_MDI(input));
+}
+
+void __zmii_set_speed(struct ocp_device *ocpdev, int input, int speed)
+{
+ struct ibm_ocp_zmii *dev = ocp_get_drvdata(ocpdev);
+ u32 ssr = in_be32(&dev->base->ssr);
+
+ ZMII_DBG("%d: speed(%d, %d)" NL, ocpdev->def->index, input, speed);
+
+ if (speed == SPEED_100)
+ ssr |= ZMII_SSR_SP(input);
+ else
+ ssr &= ~ZMII_SSR_SP(input);
+
+ out_be32(&dev->base->ssr, ssr);
+}
+
+void __exit __zmii_fini(struct ocp_device *ocpdev, int input)
+{
+ struct ibm_ocp_zmii *dev = ocp_get_drvdata(ocpdev);
+ BUG_ON(!dev || dev->users == 0);
+
+ ZMII_DBG("%d: fini(%d)" NL, ocpdev->def->index, input);
+
+ /* Disable this input */
+ out_be32(&dev->base->fer,
+ in_be32(&dev->base->fer) & ~zmii_mode_mask(dev->mode, input));
+
+ if (!--dev->users) {
+ /* Free everything if this is the last user */
+ ocp_set_drvdata(ocpdev, NULL);
+ iounmap((void *)dev->base);
+ kfree(dev);
+ }
+}
+
+int __zmii_get_regs_len(struct ocp_device *ocpdev)
+{
+ return sizeof(struct emac_ethtool_regs_subhdr) +
+ sizeof(struct zmii_regs);
+}
+
+void *zmii_dump_regs(struct ocp_device *ocpdev, void *buf)
+{
+ struct ibm_ocp_zmii *dev = ocp_get_drvdata(ocpdev);
+ struct emac_ethtool_regs_subhdr *hdr = buf;
+ struct zmii_regs *regs = (struct zmii_regs *)(hdr + 1);
+
+ hdr->version = 0;
+ hdr->index = ocpdev->def->index;
+ memcpy_fromio(regs, dev->base, sizeof(struct zmii_regs));
+ return regs + 1;
+}
diff --git a/drivers/net/ibm_emac/ibm_emac_zmii.h b/drivers/net/ibm_emac/ibm_emac_zmii.h
index 6f6cd2a39e38..0bb26062c0ad 100644
--- a/drivers/net/ibm_emac/ibm_emac_zmii.h
+++ b/drivers/net/ibm_emac/ibm_emac_zmii.h
@@ -1,23 +1,27 @@
/*
- * ocp_zmii.h
+ * drivers/net/ibm_emac/ibm_emac_zmii.h
*
- * Defines for the IBM ZMII bridge
+ * Driver for PowerPC 4xx on-chip ethernet controller, ZMII bridge support.
*
- * Armin Kuster akuster@mvista.com
- * Dec, 2001
+ * Copyright (c) 2004, 2005 Zultys Technologies.
+ * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
*
- * Copyright 2001 MontaVista Softare Inc.
+ * Based on original work by
+ * Armin Kuster <akuster@mvista.com>
+ * Copyright 2001 MontaVista Softare 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.
+ *
*/
-
#ifndef _IBM_EMAC_ZMII_H_
#define _IBM_EMAC_ZMII_H_
#include <linux/config.h>
+#include <linux/init.h>
+#include <asm/ocp.h>
/* ZMII bridge registers */
struct zmii_regs {
@@ -26,68 +30,54 @@ struct zmii_regs {
u32 smiirs; /* SMII status reg */
};
-#define ZMII_INPUTS 4
-
/* ZMII device */
struct ibm_ocp_zmii {
struct zmii_regs *base;
- int mode[ZMII_INPUTS];
+ int mode; /* subset of PHY_MODE_XXXX */
int users; /* number of EMACs using this ZMII bridge */
+ u32 fer_save; /* FER value left by firmware */
};
-/* Fuctional Enable Reg */
-
-#define ZMII_FER_MASK(x) (0xf0000000 >> (4*x))
-
-#define ZMII_MDI0 0x80000000
-#define ZMII_SMII0 0x40000000
-#define ZMII_RMII0 0x20000000
-#define ZMII_MII0 0x10000000
-#define ZMII_MDI1 0x08000000
-#define ZMII_SMII1 0x04000000
-#define ZMII_RMII1 0x02000000
-#define ZMII_MII1 0x01000000
-#define ZMII_MDI2 0x00800000
-#define ZMII_SMII2 0x00400000
-#define ZMII_RMII2 0x00200000
-#define ZMII_MII2 0x00100000
-#define ZMII_MDI3 0x00080000
-#define ZMII_SMII3 0x00040000
-#define ZMII_RMII3 0x00020000
-#define ZMII_MII3 0x00010000
+#ifdef CONFIG_IBM_EMAC_ZMII
+int zmii_attach(void *emac) __init;
-/* Speed Selection reg */
+void __zmii_fini(struct ocp_device *ocpdev, int input) __exit;
+static inline void zmii_fini(struct ocp_device *ocpdev, int input)
+{
+ if (ocpdev)
+ __zmii_fini(ocpdev, input);
+}
-#define ZMII_SCI0 0x40000000
-#define ZMII_FSS0 0x20000000
-#define ZMII_SP0 0x10000000
-#define ZMII_SCI1 0x04000000
-#define ZMII_FSS1 0x02000000
-#define ZMII_SP1 0x01000000
-#define ZMII_SCI2 0x00400000
-#define ZMII_FSS2 0x00200000
-#define ZMII_SP2 0x00100000
-#define ZMII_SCI3 0x00040000
-#define ZMII_FSS3 0x00020000
-#define ZMII_SP3 0x00010000
+void __zmii_enable_mdio(struct ocp_device *ocpdev, int input);
+static inline void zmii_enable_mdio(struct ocp_device *ocpdev, int input)
+{
+ if (ocpdev)
+ __zmii_enable_mdio(ocpdev, input);
+}
-#define ZMII_MII0_100MB ZMII_SP0
-#define ZMII_MII0_10MB ~ZMII_SP0
-#define ZMII_MII1_100MB ZMII_SP1
-#define ZMII_MII1_10MB ~ZMII_SP1
-#define ZMII_MII2_100MB ZMII_SP2
-#define ZMII_MII2_10MB ~ZMII_SP2
-#define ZMII_MII3_100MB ZMII_SP3
-#define ZMII_MII3_10MB ~ZMII_SP3
+void __zmii_set_speed(struct ocp_device *ocpdev, int input, int speed);
+static inline void zmii_set_speed(struct ocp_device *ocpdev, int input,
+ int speed)
+{
+ if (ocpdev)
+ __zmii_set_speed(ocpdev, input, speed);
+}
-/* SMII Status reg */
+int __zmii_get_regs_len(struct ocp_device *ocpdev);
+static inline int zmii_get_regs_len(struct ocp_device *ocpdev)
+{
+ return ocpdev ? __zmii_get_regs_len(ocpdev) : 0;
+}
-#define ZMII_STS0 0xFF000000 /* EMAC0 smii status mask */
-#define ZMII_STS1 0x00FF0000 /* EMAC1 smii status mask */
+void *zmii_dump_regs(struct ocp_device *ocpdev, void *buf);
-#define SMII 0
-#define RMII 1
-#define MII 2
-#define MDI 3
+#else
+# define zmii_attach(x) 0
+# define zmii_fini(x,y) ((void)0)
+# define zmii_enable_mdio(x,y) ((void)0)
+# define zmii_set_speed(x,y,z) ((void)0)
+# define zmii_get_regs_len(x) 0
+# define zmii_dump_regs(x,buf) (buf)
+#endif /* !CONFIG_IBM_EMAC_ZMII */
#endif /* _IBM_EMAC_ZMII_H_ */
diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c
index a2c4dd4fb221..ceb98fd398af 100644
--- a/drivers/net/ibmveth.c
+++ b/drivers/net/ibmveth.c
@@ -35,7 +35,6 @@
#include <linux/config.h>
#include <linux/module.h>
-#include <linux/version.h>
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/ioport.h>
@@ -59,7 +58,7 @@
#include "ibmveth.h"
-#define DEBUG 1
+#undef DEBUG
#define ibmveth_printk(fmt, args...) \
printk(KERN_INFO "%s: " fmt, __FILE__, ## args)
@@ -96,7 +95,7 @@ static void ibmveth_proc_unregister_driver(void);
static void ibmveth_proc_register_adapter(struct ibmveth_adapter *adapter);
static void ibmveth_proc_unregister_adapter(struct ibmveth_adapter *adapter);
static irqreturn_t ibmveth_interrupt(int irq, void *dev_instance, struct pt_regs *regs);
-static inline void ibmveth_schedule_replenishing(struct ibmveth_adapter*);
+static inline void ibmveth_rxq_harvest_buffer(struct ibmveth_adapter *adapter);
#ifdef CONFIG_PROC_FS
#define IBMVETH_PROC_DIR "net/ibmveth"
@@ -181,6 +180,7 @@ static int ibmveth_alloc_buffer_pool(struct ibmveth_buff_pool *pool)
atomic_set(&pool->available, 0);
pool->producer_index = 0;
pool->consumer_index = 0;
+ pool->active = 0;
return 0;
}
@@ -236,7 +236,7 @@ static void ibmveth_replenish_buffer_pool(struct ibmveth_adapter *adapter, struc
lpar_rc = h_add_logical_lan_buffer(adapter->vdev->unit_address, desc.desc);
if(lpar_rc != H_Success) {
- pool->free_map[free_index] = IBM_VETH_INVALID_MAP;
+ pool->free_map[free_index] = index;
pool->skbuff[index] = NULL;
pool->consumer_index--;
dma_unmap_single(&adapter->vdev->dev,
@@ -255,37 +255,19 @@ static void ibmveth_replenish_buffer_pool(struct ibmveth_adapter *adapter, struc
atomic_add(buffers_added, &(pool->available));
}
-/* check if replenishing is needed. */
-static inline int ibmveth_is_replenishing_needed(struct ibmveth_adapter *adapter)
-{
- return ((atomic_read(&adapter->rx_buff_pool[0].available) < adapter->rx_buff_pool[0].threshold) ||
- (atomic_read(&adapter->rx_buff_pool[1].available) < adapter->rx_buff_pool[1].threshold) ||
- (atomic_read(&adapter->rx_buff_pool[2].available) < adapter->rx_buff_pool[2].threshold));
-}
-
-/* kick the replenish tasklet if we need replenishing and it isn't already running */
-static inline void ibmveth_schedule_replenishing(struct ibmveth_adapter *adapter)
-{
- if(ibmveth_is_replenishing_needed(adapter) &&
- (atomic_dec_if_positive(&adapter->not_replenishing) == 0)) {
- schedule_work(&adapter->replenish_task);
- }
-}
-
-/* replenish tasklet routine */
+/* replenish routine */
static void ibmveth_replenish_task(struct ibmveth_adapter *adapter)
{
+ int i;
+
adapter->replenish_task_cycles++;
- ibmveth_replenish_buffer_pool(adapter, &adapter->rx_buff_pool[0]);
- ibmveth_replenish_buffer_pool(adapter, &adapter->rx_buff_pool[1]);
- ibmveth_replenish_buffer_pool(adapter, &adapter->rx_buff_pool[2]);
+ for(i = 0; i < IbmVethNumBufferPools; i++)
+ if(adapter->rx_buff_pool[i].active)
+ ibmveth_replenish_buffer_pool(adapter,
+ &adapter->rx_buff_pool[i]);
adapter->rx_no_buffer = *(u64*)(((char*)adapter->buffer_list_addr) + 4096 - 8);
-
- atomic_inc(&adapter->not_replenishing);
-
- ibmveth_schedule_replenishing(adapter);
}
/* empty and free ana buffer pool - also used to do cleanup in error paths */
@@ -293,10 +275,8 @@ static void ibmveth_free_buffer_pool(struct ibmveth_adapter *adapter, struct ibm
{
int i;
- if(pool->free_map) {
- kfree(pool->free_map);
- pool->free_map = NULL;
- }
+ kfree(pool->free_map);
+ pool->free_map = NULL;
if(pool->skbuff && pool->dma_addr) {
for(i = 0; i < pool->size; ++i) {
@@ -321,6 +301,7 @@ static void ibmveth_free_buffer_pool(struct ibmveth_adapter *adapter, struct ibm
kfree(pool->skbuff);
pool->skbuff = NULL;
}
+ pool->active = 0;
}
/* remove a buffer from a pool */
@@ -379,6 +360,12 @@ static void ibmveth_rxq_recycle_buffer(struct ibmveth_adapter *adapter)
ibmveth_assert(pool < IbmVethNumBufferPools);
ibmveth_assert(index < adapter->rx_buff_pool[pool].size);
+ if(!adapter->rx_buff_pool[pool].active) {
+ ibmveth_rxq_harvest_buffer(adapter);
+ ibmveth_free_buffer_pool(adapter, &adapter->rx_buff_pool[pool]);
+ return;
+ }
+
desc.desc = 0;
desc.fields.valid = 1;
desc.fields.length = adapter->rx_buff_pool[pool].buff_size;
@@ -409,6 +396,8 @@ static inline void ibmveth_rxq_harvest_buffer(struct ibmveth_adapter *adapter)
static void ibmveth_cleanup(struct ibmveth_adapter *adapter)
{
+ int i;
+
if(adapter->buffer_list_addr != NULL) {
if(!dma_mapping_error(adapter->buffer_list_dma)) {
dma_unmap_single(&adapter->vdev->dev,
@@ -443,26 +432,24 @@ static void ibmveth_cleanup(struct ibmveth_adapter *adapter)
adapter->rx_queue.queue_addr = NULL;
}
- ibmveth_free_buffer_pool(adapter, &adapter->rx_buff_pool[0]);
- ibmveth_free_buffer_pool(adapter, &adapter->rx_buff_pool[1]);
- ibmveth_free_buffer_pool(adapter, &adapter->rx_buff_pool[2]);
+ for(i = 0; i<IbmVethNumBufferPools; i++)
+ ibmveth_free_buffer_pool(adapter, &adapter->rx_buff_pool[i]);
}
static int ibmveth_open(struct net_device *netdev)
{
struct ibmveth_adapter *adapter = netdev->priv;
u64 mac_address = 0;
- int rxq_entries;
+ int rxq_entries = 1;
unsigned long lpar_rc;
int rc;
union ibmveth_buf_desc rxq_desc;
+ int i;
ibmveth_debug_printk("open starting\n");
- rxq_entries =
- adapter->rx_buff_pool[0].size +
- adapter->rx_buff_pool[1].size +
- adapter->rx_buff_pool[2].size + 1;
+ for(i = 0; i<IbmVethNumBufferPools; i++)
+ rxq_entries += adapter->rx_buff_pool[i].size;
adapter->buffer_list_addr = (void*) get_zeroed_page(GFP_KERNEL);
adapter->filter_list_addr = (void*) get_zeroed_page(GFP_KERNEL);
@@ -502,14 +489,8 @@ static int ibmveth_open(struct net_device *netdev)
adapter->rx_queue.num_slots = rxq_entries;
adapter->rx_queue.toggle = 1;
- if(ibmveth_alloc_buffer_pool(&adapter->rx_buff_pool[0]) ||
- ibmveth_alloc_buffer_pool(&adapter->rx_buff_pool[1]) ||
- ibmveth_alloc_buffer_pool(&adapter->rx_buff_pool[2]))
- {
- ibmveth_error_printk("unable to allocate buffer pools\n");
- ibmveth_cleanup(adapter);
- return -ENOMEM;
- }
+ /* call change_mtu to init the buffer pools based in initial mtu */
+ ibmveth_change_mtu(netdev, netdev->mtu);
memcpy(&mac_address, netdev->dev_addr, netdev->addr_len);
mac_address = mac_address >> 16;
@@ -532,7 +513,7 @@ static int ibmveth_open(struct net_device *netdev)
if(lpar_rc != H_Success) {
ibmveth_error_printk("h_register_logical_lan failed with %ld\n", lpar_rc);
- ibmveth_error_printk("buffer TCE:0x%x filter TCE:0x%x rxq desc:0x%lx MAC:0x%lx\n",
+ ibmveth_error_printk("buffer TCE:0x%lx filter TCE:0x%lx rxq desc:0x%lx MAC:0x%lx\n",
adapter->buffer_list_dma,
adapter->filter_list_dma,
rxq_desc.desc,
@@ -552,10 +533,10 @@ static int ibmveth_open(struct net_device *netdev)
return rc;
}
- netif_start_queue(netdev);
+ ibmveth_debug_printk("initial replenish cycle\n");
+ ibmveth_interrupt(netdev->irq, netdev, NULL);
- ibmveth_debug_printk("scheduling initial replenish cycle\n");
- ibmveth_schedule_replenishing(adapter);
+ netif_start_queue(netdev);
ibmveth_debug_printk("open complete\n");
@@ -573,9 +554,6 @@ static int ibmveth_close(struct net_device *netdev)
free_irq(netdev->irq, netdev);
- cancel_delayed_work(&adapter->replenish_task);
- flush_scheduled_work();
-
do {
lpar_rc = h_free_logical_lan(adapter->vdev->unit_address);
} while (H_isLongBusy(lpar_rc) || (lpar_rc == H_Busy));
@@ -640,12 +618,18 @@ static int ibmveth_start_xmit(struct sk_buff *skb, struct net_device *netdev)
unsigned long lpar_rc;
int nfrags = 0, curfrag;
unsigned long correlator;
+ unsigned long flags;
unsigned int retry_count;
+ unsigned int tx_dropped = 0;
+ unsigned int tx_bytes = 0;
+ unsigned int tx_packets = 0;
+ unsigned int tx_send_failed = 0;
+ unsigned int tx_map_failed = 0;
+
if ((skb_shinfo(skb)->nr_frags + 1) > IbmVethMaxSendFrags) {
- adapter->stats.tx_dropped++;
- dev_kfree_skb(skb);
- return 0;
+ tx_dropped++;
+ goto out;
}
memset(&desc, 0, sizeof(desc));
@@ -664,10 +648,9 @@ static int ibmveth_start_xmit(struct sk_buff *skb, struct net_device *netdev)
if(dma_mapping_error(desc[0].fields.address)) {
ibmveth_error_printk("tx: unable to map initial fragment\n");
- adapter->tx_map_failed++;
- adapter->stats.tx_dropped++;
- dev_kfree_skb(skb);
- return 0;
+ tx_map_failed++;
+ tx_dropped++;
+ goto out;
}
curfrag = nfrags;
@@ -684,8 +667,8 @@ static int ibmveth_start_xmit(struct sk_buff *skb, struct net_device *netdev)
if(dma_mapping_error(desc[curfrag+1].fields.address)) {
ibmveth_error_printk("tx: unable to map fragment %d\n", curfrag);
- adapter->tx_map_failed++;
- adapter->stats.tx_dropped++;
+ tx_map_failed++;
+ tx_dropped++;
/* Free all the mappings we just created */
while(curfrag < nfrags) {
dma_unmap_single(&adapter->vdev->dev,
@@ -694,8 +677,7 @@ static int ibmveth_start_xmit(struct sk_buff *skb, struct net_device *netdev)
DMA_TO_DEVICE);
curfrag++;
}
- dev_kfree_skb(skb);
- return 0;
+ goto out;
}
}
@@ -720,11 +702,12 @@ static int ibmveth_start_xmit(struct sk_buff *skb, struct net_device *netdev)
ibmveth_error_printk("tx: desc[%i] valid=%d, len=%d, address=0x%d\n", i,
desc[i].fields.valid, desc[i].fields.length, desc[i].fields.address);
}
- adapter->tx_send_failed++;
- adapter->stats.tx_dropped++;
+ tx_send_failed++;
+ tx_dropped++;
} else {
- adapter->stats.tx_packets++;
- adapter->stats.tx_bytes += skb->len;
+ tx_packets++;
+ tx_bytes += skb->len;
+ netdev->trans_start = jiffies;
}
do {
@@ -733,6 +716,14 @@ static int ibmveth_start_xmit(struct sk_buff *skb, struct net_device *netdev)
desc[nfrags].fields.length, DMA_TO_DEVICE);
} while(--nfrags >= 0);
+out: spin_lock_irqsave(&adapter->stats_lock, flags);
+ adapter->stats.tx_dropped += tx_dropped;
+ adapter->stats.tx_bytes += tx_bytes;
+ adapter->stats.tx_packets += tx_packets;
+ adapter->tx_send_failed += tx_send_failed;
+ adapter->tx_map_failed += tx_map_failed;
+ spin_unlock_irqrestore(&adapter->stats_lock, flags);
+
dev_kfree_skb(skb);
return 0;
}
@@ -776,13 +767,14 @@ static int ibmveth_poll(struct net_device *netdev, int *budget)
adapter->stats.rx_packets++;
adapter->stats.rx_bytes += length;
frames_processed++;
+ netdev->last_rx = jiffies;
}
} else {
more_work = 0;
}
} while(more_work && (frames_processed < max_frames_to_process));
- ibmveth_schedule_replenishing(adapter);
+ ibmveth_replenish_task(adapter);
if(more_work) {
/* more work to do - return that we are not done yet */
@@ -883,17 +875,54 @@ static void ibmveth_set_multicast_list(struct net_device *netdev)
static int ibmveth_change_mtu(struct net_device *dev, int new_mtu)
{
- if ((new_mtu < 68) || (new_mtu > (1<<20)))
+ struct ibmveth_adapter *adapter = dev->priv;
+ int i;
+ int prev_smaller = 1;
+
+ if ((new_mtu < 68) ||
+ (new_mtu > (pool_size[IbmVethNumBufferPools-1]) - IBMVETH_BUFF_OH))
return -EINVAL;
+
+ for(i = 0; i<IbmVethNumBufferPools; i++) {
+ int activate = 0;
+ if (new_mtu > (pool_size[i] - IBMVETH_BUFF_OH)) {
+ activate = 1;
+ prev_smaller= 1;
+ } else {
+ if (prev_smaller)
+ activate = 1;
+ prev_smaller= 0;
+ }
+
+ if (activate && !adapter->rx_buff_pool[i].active) {
+ struct ibmveth_buff_pool *pool =
+ &adapter->rx_buff_pool[i];
+ if(ibmveth_alloc_buffer_pool(pool)) {
+ ibmveth_error_printk("unable to alloc pool\n");
+ return -ENOMEM;
+ }
+ adapter->rx_buff_pool[i].active = 1;
+ } else if (!activate && adapter->rx_buff_pool[i].active) {
+ adapter->rx_buff_pool[i].active = 0;
+ h_free_logical_lan_buffer(adapter->vdev->unit_address,
+ (u64)pool_size[i]);
+ }
+
+ }
+
+ /* kick the interrupt handler so that the new buffer pools get
+ replenished or deallocated */
+ ibmveth_interrupt(dev->irq, dev, NULL);
+
dev->mtu = new_mtu;
return 0;
}
static int __devinit ibmveth_probe(struct vio_dev *dev, const struct vio_device_id *id)
{
- int rc;
+ int rc, i;
struct net_device *netdev;
- struct ibmveth_adapter *adapter;
+ struct ibmveth_adapter *adapter = NULL;
unsigned char *mac_addr_p;
unsigned int *mcastFilterSize_p;
@@ -960,23 +989,21 @@ static int __devinit ibmveth_probe(struct vio_dev *dev, const struct vio_device_
netdev->ethtool_ops = &netdev_ethtool_ops;
netdev->change_mtu = ibmveth_change_mtu;
SET_NETDEV_DEV(netdev, &dev->dev);
+ netdev->features |= NETIF_F_LLTX;
+ spin_lock_init(&adapter->stats_lock);
memcpy(&netdev->dev_addr, &adapter->mac_addr, netdev->addr_len);
- ibmveth_init_buffer_pool(&adapter->rx_buff_pool[0], 0, IbmVethPool0DftCnt, IbmVethPool0DftSize);
- ibmveth_init_buffer_pool(&adapter->rx_buff_pool[1], 1, IbmVethPool1DftCnt, IbmVethPool1DftSize);
- ibmveth_init_buffer_pool(&adapter->rx_buff_pool[2], 2, IbmVethPool2DftCnt, IbmVethPool2DftSize);
+ for(i = 0; i<IbmVethNumBufferPools; i++)
+ ibmveth_init_buffer_pool(&adapter->rx_buff_pool[i], i,
+ pool_count[i], pool_size[i]);
ibmveth_debug_printk("adapter @ 0x%p\n", adapter);
- INIT_WORK(&adapter->replenish_task, (void*)ibmveth_replenish_task, (void*)adapter);
-
adapter->buffer_list_dma = DMA_ERROR_CODE;
adapter->filter_list_dma = DMA_ERROR_CODE;
adapter->rx_queue.queue_dma = DMA_ERROR_CODE;
- atomic_set(&adapter->not_replenishing, 1);
-
ibmveth_debug_printk("registering netdev...\n");
rc = register_netdev(netdev);
@@ -1146,14 +1173,16 @@ static struct vio_device_id ibmveth_device_table[] __devinitdata= {
{ "network", "IBM,l-lan"},
{ "", "" }
};
-
MODULE_DEVICE_TABLE(vio, ibmveth_device_table);
static struct vio_driver ibmveth_driver = {
- .name = (char *)ibmveth_driver_name,
- .id_table = ibmveth_device_table,
- .probe = ibmveth_probe,
- .remove = ibmveth_remove
+ .id_table = ibmveth_device_table,
+ .probe = ibmveth_probe,
+ .remove = ibmveth_remove,
+ .driver = {
+ .name = ibmveth_driver_name,
+ .owner = THIS_MODULE,
+ }
};
static int __init ibmveth_module_init(void)
diff --git a/drivers/net/ibmveth.h b/drivers/net/ibmveth.h
index 51a470da9686..46919a814fca 100644
--- a/drivers/net/ibmveth.h
+++ b/drivers/net/ibmveth.h
@@ -49,6 +49,7 @@
#define H_SEND_LOGICAL_LAN 0x120
#define H_MULTICAST_CTRL 0x130
#define H_CHANGE_LOGICAL_LAN_MAC 0x14C
+#define H_FREE_LOGICAL_LAN_BUFFER 0x1D4
/* hcall macros */
#define h_register_logical_lan(ua, buflst, rxq, fltlst, mac) \
@@ -69,13 +70,15 @@
#define h_change_logical_lan_mac(ua, mac) \
plpar_hcall_norets(H_CHANGE_LOGICAL_LAN_MAC, ua, mac)
-#define IbmVethNumBufferPools 3
-#define IbmVethPool0DftSize (1024 * 2)
-#define IbmVethPool1DftSize (1024 * 4)
-#define IbmVethPool2DftSize (1024 * 10)
-#define IbmVethPool0DftCnt 256
-#define IbmVethPool1DftCnt 256
-#define IbmVethPool2DftCnt 256
+#define h_free_logical_lan_buffer(ua, bufsize) \
+ plpar_hcall_norets(H_FREE_LOGICAL_LAN_BUFFER, ua, bufsize)
+
+#define IbmVethNumBufferPools 5
+#define IBMVETH_BUFF_OH 22 /* Overhead: 14 ethernet header + 8 opaque handle */
+
+/* pool_size should be sorted */
+static int pool_size[] = { 512, 1024 * 2, 1024 * 16, 1024 * 32, 1024 * 64 };
+static int pool_count[] = { 256, 768, 256, 256, 256 };
#define IBM_VETH_INVALID_MAP ((u16)0xffff)
@@ -90,6 +93,7 @@ struct ibmveth_buff_pool {
u16 *free_map;
dma_addr_t *dma_addr;
struct sk_buff **skbuff;
+ int active;
};
struct ibmveth_rx_q {
@@ -114,10 +118,6 @@ struct ibmveth_adapter {
dma_addr_t filter_list_dma;
struct ibmveth_buff_pool rx_buff_pool[IbmVethNumBufferPools];
struct ibmveth_rx_q rx_queue;
- atomic_t not_replenishing;
-
- /* helper tasks */
- struct work_struct replenish_task;
/* adapter specific stats */
u64 replenish_task_cycles;
@@ -131,6 +131,7 @@ struct ibmveth_adapter {
u64 tx_linearize_failed;
u64 tx_map_failed;
u64 tx_send_failed;
+ spinlock_t stats_lock;
};
struct ibmveth_buf_desc_fields {
diff --git a/drivers/net/ioc3-eth.c b/drivers/net/ioc3-eth.c
index 49e5467bdd73..6a3129bc15a6 100644
--- a/drivers/net/ioc3-eth.c
+++ b/drivers/net/ioc3-eth.c
@@ -46,10 +46,8 @@
#include <linux/udp.h>
#ifdef CONFIG_SERIAL_8250
-#include <linux/serial.h>
-#include <asm/serial.h>
-#define IOC3_BAUD (22000000 / (3*16))
-#define IOC3_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST)
+#include <linux/serial_core.h>
+#include <linux/serial_8250.h>
#endif
#include <linux/netdevice.h>
@@ -1146,12 +1144,11 @@ static inline int ioc3_is_menet(struct pci_dev *pdev)
* around ioc3 oddities in this respect.
*
* The IOC3 serials use a 22MHz clock rate with an additional divider by 3.
- * (IOC3_BAUD = (22000000 / (3*16)))
*/
static void __devinit ioc3_serial_probe(struct pci_dev *pdev, struct ioc3 *ioc3)
{
- struct serial_struct req;
+ struct uart_port port;
/*
* We need to recognice and treat the fourth MENET serial as it
@@ -1165,20 +1162,25 @@ static void __devinit ioc3_serial_probe(struct pci_dev *pdev, struct ioc3 *ioc3)
if (ioc3_is_menet(pdev) && PCI_SLOT(pdev->devfn) == 3)
return;
- /* Register to interrupt zero because we share the interrupt with
- the serial driver which we don't properly support yet. */
- memset(&req, 0, sizeof(req));
- req.irq = 0;
- req.flags = IOC3_COM_FLAGS;
- req.io_type = SERIAL_IO_MEM;
- req.iomem_reg_shift = 0;
- req.baud_base = IOC3_BAUD;
-
- req.iomem_base = (unsigned char *) &ioc3->sregs.uarta;
- register_serial(&req);
-
- req.iomem_base = (unsigned char *) &ioc3->sregs.uartb;
- register_serial(&req);
+ /*
+ * Register to interrupt zero because we share the interrupt with
+ * the serial driver which we don't properly support yet.
+ *
+ * Can't use UPF_IOREMAP as the whole of IOC3 resources have already
+ * been registered.
+ */
+ memset(&port, 0, sizeof(port));
+ port.irq = 0;
+ port.flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF;
+ port.iotype = UPIO_MEM;
+ port.regshift = 0;
+ port.uartclk = 22000000 / 3;
+
+ port.membase = (unsigned char *) &ioc3->sregs.uarta;
+ serial8250_register_port(&port);
+
+ port.membase = (unsigned char *) &ioc3->sregs.uartb;
+ serial8250_register_port(&port);
}
#endif
diff --git a/drivers/net/irda/Kconfig b/drivers/net/irda/Kconfig
index ca5914091d3a..d54156f11e61 100644
--- a/drivers/net/irda/Kconfig
+++ b/drivers/net/irda/Kconfig
@@ -400,5 +400,15 @@ config VIA_FIR
To compile it as a module, choose M here: the module will be called
via-ircc.
+config PXA_FICP
+ tristate "Intel PXA2xx Internal FICP"
+ depends on ARCH_PXA && IRDA
+ help
+ Say Y or M here if you want to build support for the PXA2xx
+ built-in IRDA interface which can support both SIR and FIR.
+ This driver relies on platform specific helper routines so
+ available capabilities may vary from one PXA2xx target to
+ another.
+
endmenu
diff --git a/drivers/net/irda/Makefile b/drivers/net/irda/Makefile
index 29a8bd812b21..e7a8b7f7f5dd 100644
--- a/drivers/net/irda/Makefile
+++ b/drivers/net/irda/Makefile
@@ -18,6 +18,7 @@ obj-$(CONFIG_SMC_IRCC_FIR) += smsc-ircc2.o
obj-$(CONFIG_ALI_FIR) += ali-ircc.o
obj-$(CONFIG_VLSI_FIR) += vlsi_ir.o
obj-$(CONFIG_VIA_FIR) += via-ircc.o
+obj-$(CONFIG_PXA_FICP) += pxaficp_ir.o
# Old dongle drivers for old SIR drivers
obj-$(CONFIG_ESI_DONGLE_OLD) += esi.o
obj-$(CONFIG_TEKRAM_DONGLE_OLD) += tekram.o
diff --git a/drivers/net/irda/donauboe.c b/drivers/net/irda/donauboe.c
index 0a08c539c051..3137592d60c0 100644
--- a/drivers/net/irda/donauboe.c
+++ b/drivers/net/irda/donauboe.c
@@ -1459,8 +1459,10 @@ toshoboe_net_ioctl (struct net_device *dev, struct ifreq *rq, int cmd)
*/
IRDA_DEBUG (1, "%s(BANDWIDTH), %s, (%X/%ld\n", __FUNCTION__
,dev->name, INB (OBOE_STATUS), irq->ifr_baudrate );
- if (!in_interrupt () && !capable (CAP_NET_ADMIN))
- return -EPERM;
+ if (!in_interrupt () && !capable (CAP_NET_ADMIN)) {
+ ret = -EPERM;
+ goto out;
+ }
/* self->speed=irq->ifr_baudrate; */
/* toshoboe_setbaud(self); */
@@ -1470,8 +1472,10 @@ toshoboe_net_ioctl (struct net_device *dev, struct ifreq *rq, int cmd)
case SIOCSMEDIABUSY: /* Set media busy */
IRDA_DEBUG (1, "%s(MEDIABUSY), %s, (%X/%x)\n", __FUNCTION__
,dev->name, INB (OBOE_STATUS), capable (CAP_NET_ADMIN) );
- if (!capable (CAP_NET_ADMIN))
- return -EPERM;
+ if (!capable (CAP_NET_ADMIN)) {
+ ret = -EPERM;
+ goto out;
+ }
irda_device_set_media_busy (self->netdev, TRUE);
break;
case SIOCGRECEIVING: /* Check if we are receiving right now */
@@ -1483,7 +1487,7 @@ toshoboe_net_ioctl (struct net_device *dev, struct ifreq *rq, int cmd)
IRDA_DEBUG (1, "%s(?), %s, (cmd=0x%X)\n", __FUNCTION__, dev->name, cmd);
ret = -EOPNOTSUPP;
}
-
+out:
spin_unlock_irqrestore(&self->spinlock, flags);
return ret;
@@ -1695,11 +1699,9 @@ toshoboe_open (struct pci_dev *pci_dev, const struct pci_device_id *pdid)
freebufs:
for (i = 0; i < TX_SLOTS; ++i)
- if (self->tx_bufs[i])
- kfree (self->tx_bufs[i]);
+ kfree (self->tx_bufs[i]);
for (i = 0; i < RX_SLOTS; ++i)
- if (self->rx_bufs[i])
- kfree (self->rx_bufs[i]);
+ kfree (self->rx_bufs[i]);
kfree(self->ringbuf);
freeregion:
diff --git a/drivers/net/irda/irda-usb.c b/drivers/net/irda/irda-usb.c
index 6c766fdc51a6..c22c0517883c 100644
--- a/drivers/net/irda/irda-usb.c
+++ b/drivers/net/irda/irda-usb.c
@@ -1168,10 +1168,8 @@ static inline void irda_usb_close(struct irda_usb_cb *self)
unregister_netdev(self->netdev);
/* Remove the speed buffer */
- if (self->speed_buff != NULL) {
- kfree(self->speed_buff);
- self->speed_buff = NULL;
- }
+ kfree(self->speed_buff);
+ self->speed_buff = NULL;
}
/********************** USB CONFIG SUBROUTINES **********************/
diff --git a/drivers/net/irda/irport.c b/drivers/net/irda/irport.c
index 5971315f3fa0..3d016a498e1d 100644
--- a/drivers/net/irda/irport.c
+++ b/drivers/net/irda/irport.c
@@ -235,8 +235,7 @@ static int irport_close(struct irport_cb *self)
__FUNCTION__, self->io.sir_base);
release_region(self->io.sir_base, self->io.sir_ext);
- if (self->tx_buff.head)
- kfree(self->tx_buff.head);
+ kfree(self->tx_buff.head);
if (self->rx_buff.skb)
kfree_skb(self->rx_buff.skb);
diff --git a/drivers/net/irda/pxaficp_ir.c b/drivers/net/irda/pxaficp_ir.c
new file mode 100644
index 000000000000..e1aa9910503b
--- /dev/null
+++ b/drivers/net/irda/pxaficp_ir.c
@@ -0,0 +1,866 @@
+/*
+ * linux/drivers/net/irda/pxaficp_ir.c
+ *
+ * Based on sa1100_ir.c by Russell King
+ *
+ * Changes copyright (C) 2003-2005 MontaVista Software, 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.
+ *
+ * Infra-red driver (SIR/FIR) for the PXA2xx embedded microprocessor
+ *
+ */
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/netdevice.h>
+#include <linux/slab.h>
+#include <linux/rtnetlink.h>
+#include <linux/interrupt.h>
+#include <linux/dma-mapping.h>
+#include <linux/platform_device.h>
+#include <linux/pm.h>
+
+#include <net/irda/irda.h>
+#include <net/irda/irmod.h>
+#include <net/irda/wrapper.h>
+#include <net/irda/irda_device.h>
+
+#include <asm/irq.h>
+#include <asm/dma.h>
+#include <asm/delay.h>
+#include <asm/hardware.h>
+#include <asm/arch/irda.h>
+#include <asm/arch/pxa-regs.h>
+
+#ifdef CONFIG_MACH_MAINSTONE
+#include <asm/arch/mainstone.h>
+#endif
+
+#define IrSR_RXPL_NEG_IS_ZERO (1<<4)
+#define IrSR_RXPL_POS_IS_ZERO 0x0
+#define IrSR_TXPL_NEG_IS_ZERO (1<<3)
+#define IrSR_TXPL_POS_IS_ZERO 0x0
+#define IrSR_XMODE_PULSE_1_6 (1<<2)
+#define IrSR_XMODE_PULSE_3_16 0x0
+#define IrSR_RCVEIR_IR_MODE (1<<1)
+#define IrSR_RCVEIR_UART_MODE 0x0
+#define IrSR_XMITIR_IR_MODE (1<<0)
+#define IrSR_XMITIR_UART_MODE 0x0
+
+#define IrSR_IR_RECEIVE_ON (\
+ IrSR_RXPL_NEG_IS_ZERO | \
+ IrSR_TXPL_POS_IS_ZERO | \
+ IrSR_XMODE_PULSE_3_16 | \
+ IrSR_RCVEIR_IR_MODE | \
+ IrSR_XMITIR_UART_MODE)
+
+#define IrSR_IR_TRANSMIT_ON (\
+ IrSR_RXPL_NEG_IS_ZERO | \
+ IrSR_TXPL_POS_IS_ZERO | \
+ IrSR_XMODE_PULSE_3_16 | \
+ IrSR_RCVEIR_UART_MODE | \
+ IrSR_XMITIR_IR_MODE)
+
+struct pxa_irda {
+ int speed;
+ int newspeed;
+ unsigned long last_oscr;
+
+ unsigned char *dma_rx_buff;
+ unsigned char *dma_tx_buff;
+ dma_addr_t dma_rx_buff_phy;
+ dma_addr_t dma_tx_buff_phy;
+ unsigned int dma_tx_buff_len;
+ int txdma;
+ int rxdma;
+
+ struct net_device_stats stats;
+ struct irlap_cb *irlap;
+ struct qos_info qos;
+
+ iobuff_t tx_buff;
+ iobuff_t rx_buff;
+
+ struct device *dev;
+ struct pxaficp_platform_data *pdata;
+};
+
+
+#define IS_FIR(si) ((si)->speed >= 4000000)
+#define IRDA_FRAME_SIZE_LIMIT 2047
+
+inline static void pxa_irda_fir_dma_rx_start(struct pxa_irda *si)
+{
+ DCSR(si->rxdma) = DCSR_NODESC;
+ DSADR(si->rxdma) = __PREG(ICDR);
+ DTADR(si->rxdma) = si->dma_rx_buff_phy;
+ DCMD(si->rxdma) = DCMD_INCTRGADDR | DCMD_FLOWSRC | DCMD_WIDTH1 | DCMD_BURST32 | IRDA_FRAME_SIZE_LIMIT;
+ DCSR(si->rxdma) |= DCSR_RUN;
+}
+
+inline static void pxa_irda_fir_dma_tx_start(struct pxa_irda *si)
+{
+ DCSR(si->txdma) = DCSR_NODESC;
+ DSADR(si->txdma) = si->dma_tx_buff_phy;
+ DTADR(si->txdma) = __PREG(ICDR);
+ DCMD(si->txdma) = DCMD_INCSRCADDR | DCMD_FLOWTRG | DCMD_ENDIRQEN | DCMD_WIDTH1 | DCMD_BURST32 | si->dma_tx_buff_len;
+ DCSR(si->txdma) |= DCSR_RUN;
+}
+
+/*
+ * Set the IrDA communications speed.
+ */
+static int pxa_irda_set_speed(struct pxa_irda *si, int speed)
+{
+ unsigned long flags;
+ unsigned int divisor;
+
+ switch (speed) {
+ case 9600: case 19200: case 38400:
+ case 57600: case 115200:
+
+ /* refer to PXA250/210 Developer's Manual 10-7 */
+ /* BaudRate = 14.7456 MHz / (16*Divisor) */
+ divisor = 14745600 / (16 * speed);
+
+ local_irq_save(flags);
+
+ if (IS_FIR(si)) {
+ /* stop RX DMA */
+ DCSR(si->rxdma) &= ~DCSR_RUN;
+ /* disable FICP */
+ ICCR0 = 0;
+ pxa_set_cken(CKEN13_FICP, 0);
+
+ /* set board transceiver to SIR mode */
+ si->pdata->transceiver_mode(si->dev, IR_SIRMODE);
+
+ /* configure GPIO46/47 */
+ pxa_gpio_mode(GPIO46_STRXD_MD);
+ pxa_gpio_mode(GPIO47_STTXD_MD);
+
+ /* enable the STUART clock */
+ pxa_set_cken(CKEN5_STUART, 1);
+ }
+
+ /* disable STUART first */
+ STIER = 0;
+
+ /* access DLL & DLH */
+ STLCR |= LCR_DLAB;
+ STDLL = divisor & 0xff;
+ STDLH = divisor >> 8;
+ STLCR &= ~LCR_DLAB;
+
+ si->speed = speed;
+ STISR = IrSR_IR_RECEIVE_ON | IrSR_XMODE_PULSE_1_6;
+ STIER = IER_UUE | IER_RLSE | IER_RAVIE | IER_RTIOE;
+
+ local_irq_restore(flags);
+ break;
+
+ case 4000000:
+ local_irq_save(flags);
+
+ /* disable STUART */
+ STIER = 0;
+ STISR = 0;
+ pxa_set_cken(CKEN5_STUART, 0);
+
+ /* disable FICP first */
+ ICCR0 = 0;
+
+ /* set board transceiver to FIR mode */
+ si->pdata->transceiver_mode(si->dev, IR_FIRMODE);
+
+ /* configure GPIO46/47 */
+ pxa_gpio_mode(GPIO46_ICPRXD_MD);
+ pxa_gpio_mode(GPIO47_ICPTXD_MD);
+
+ /* enable the FICP clock */
+ pxa_set_cken(CKEN13_FICP, 1);
+
+ si->speed = speed;
+ pxa_irda_fir_dma_rx_start(si);
+ ICCR0 = ICCR0_ITR | ICCR0_RXE;
+
+ local_irq_restore(flags);
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+/* SIR interrupt service routine. */
+static irqreturn_t pxa_irda_sir_irq(int irq, void *dev_id, struct pt_regs *regs)
+{
+ struct net_device *dev = dev_id;
+ struct pxa_irda *si = netdev_priv(dev);
+ int iir, lsr, data;
+
+ iir = STIIR;
+
+ switch (iir & 0x0F) {
+ case 0x06: /* Receiver Line Status */
+ lsr = STLSR;
+ while (lsr & LSR_FIFOE) {
+ data = STRBR;
+ if (lsr & (LSR_OE | LSR_PE | LSR_FE | LSR_BI)) {
+ printk(KERN_DEBUG "pxa_ir: sir receiving error\n");
+ si->stats.rx_errors++;
+ if (lsr & LSR_FE)
+ si->stats.rx_frame_errors++;
+ if (lsr & LSR_OE)
+ si->stats.rx_fifo_errors++;
+ } else {
+ si->stats.rx_bytes++;
+ async_unwrap_char(dev, &si->stats, &si->rx_buff, data);
+ }
+ lsr = STLSR;
+ }
+ dev->last_rx = jiffies;
+ si->last_oscr = OSCR;
+ break;
+
+ case 0x04: /* Received Data Available */
+ /* forth through */
+
+ case 0x0C: /* Character Timeout Indication */
+ do {
+ si->stats.rx_bytes++;
+ async_unwrap_char(dev, &si->stats, &si->rx_buff, STRBR);
+ } while (STLSR & LSR_DR);
+ dev->last_rx = jiffies;
+ si->last_oscr = OSCR;
+ break;
+
+ case 0x02: /* Transmit FIFO Data Request */
+ while ((si->tx_buff.len) && (STLSR & LSR_TDRQ)) {
+ STTHR = *si->tx_buff.data++;
+ si->tx_buff.len -= 1;
+ }
+
+ if (si->tx_buff.len == 0) {
+ si->stats.tx_packets++;
+ si->stats.tx_bytes += si->tx_buff.data -
+ si->tx_buff.head;
+
+ /* We need to ensure that the transmitter has finished. */
+ while ((STLSR & LSR_TEMT) == 0)
+ cpu_relax();
+ si->last_oscr = OSCR;
+
+ /*
+ * Ok, we've finished transmitting. Now enable
+ * the receiver. Sometimes we get a receive IRQ
+ * immediately after a transmit...
+ */
+ if (si->newspeed) {
+ pxa_irda_set_speed(si, si->newspeed);
+ si->newspeed = 0;
+ } else {
+ /* enable IR Receiver, disable IR Transmitter */
+ STISR = IrSR_IR_RECEIVE_ON | IrSR_XMODE_PULSE_1_6;
+ /* enable STUART and receive interrupts */
+ STIER = IER_UUE | IER_RLSE | IER_RAVIE | IER_RTIOE;
+ }
+ /* I'm hungry! */
+ netif_wake_queue(dev);
+ }
+ break;
+ }
+
+ return IRQ_HANDLED;
+}
+
+/* FIR Receive DMA interrupt handler */
+static void pxa_irda_fir_dma_rx_irq(int channel, void *data, struct pt_regs *regs)
+{
+ int dcsr = DCSR(channel);
+
+ DCSR(channel) = dcsr & ~DCSR_RUN;
+
+ printk(KERN_DEBUG "pxa_ir: fir rx dma bus error %#x\n", dcsr);
+}
+
+/* FIR Transmit DMA interrupt handler */
+static void pxa_irda_fir_dma_tx_irq(int channel, void *data, struct pt_regs *regs)
+{
+ struct net_device *dev = data;
+ struct pxa_irda *si = netdev_priv(dev);
+ int dcsr;
+
+ dcsr = DCSR(channel);
+ DCSR(channel) = dcsr & ~DCSR_RUN;
+
+ if (dcsr & DCSR_ENDINTR) {
+ si->stats.tx_packets++;
+ si->stats.tx_bytes += si->dma_tx_buff_len;
+ } else {
+ si->stats.tx_errors++;
+ }
+
+ while (ICSR1 & ICSR1_TBY)
+ cpu_relax();
+ si->last_oscr = OSCR;
+
+ /*
+ * HACK: It looks like the TBY bit is dropped too soon.
+ * Without this delay things break.
+ */
+ udelay(120);
+
+ if (si->newspeed) {
+ pxa_irda_set_speed(si, si->newspeed);
+ si->newspeed = 0;
+ } else {
+ ICCR0 = 0;
+ pxa_irda_fir_dma_rx_start(si);
+ ICCR0 = ICCR0_ITR | ICCR0_RXE;
+ }
+ netif_wake_queue(dev);
+}
+
+/* EIF(Error in FIFO/End in Frame) handler for FIR */
+static void pxa_irda_fir_irq_eif(struct pxa_irda *si, struct net_device *dev)
+{
+ unsigned int len, stat, data;
+
+ /* Get the current data position. */
+ len = DTADR(si->rxdma) - si->dma_rx_buff_phy;
+
+ do {
+ /* Read Status, and then Data. */
+ stat = ICSR1;
+ rmb();
+ data = ICDR;
+
+ if (stat & (ICSR1_CRE | ICSR1_ROR)) {
+ si->stats.rx_errors++;
+ if (stat & ICSR1_CRE) {
+ printk(KERN_DEBUG "pxa_ir: fir receive CRC error\n");
+ si->stats.rx_crc_errors++;
+ }
+ if (stat & ICSR1_ROR) {
+ printk(KERN_DEBUG "pxa_ir: fir receive overrun\n");
+ si->stats.rx_frame_errors++;
+ }
+ } else {
+ si->dma_rx_buff[len++] = data;
+ }
+ /* If we hit the end of frame, there's no point in continuing. */
+ if (stat & ICSR1_EOF)
+ break;
+ } while (ICSR0 & ICSR0_EIF);
+
+ if (stat & ICSR1_EOF) {
+ /* end of frame. */
+ struct sk_buff *skb = alloc_skb(len+1,GFP_ATOMIC);
+ if (!skb) {
+ printk(KERN_ERR "pxa_ir: fir out of memory for receive skb\n");
+ si->stats.rx_dropped++;
+ return;
+ }
+
+ /* Align IP header to 20 bytes */
+ skb_reserve(skb, 1);
+ memcpy(skb->data, si->dma_rx_buff, len);
+ skb_put(skb, len);
+
+ /* Feed it to IrLAP */
+ skb->dev = dev;
+ skb->mac.raw = skb->data;
+ skb->protocol = htons(ETH_P_IRDA);
+ netif_rx(skb);
+
+ si->stats.rx_packets++;
+ si->stats.rx_bytes += len;
+
+ dev->last_rx = jiffies;
+ }
+}
+
+/* FIR interrupt handler */
+static irqreturn_t pxa_irda_fir_irq(int irq, void *dev_id, struct pt_regs *regs)
+{
+ struct net_device *dev = dev_id;
+ struct pxa_irda *si = netdev_priv(dev);
+ int icsr0;
+
+ /* stop RX DMA */
+ DCSR(si->rxdma) &= ~DCSR_RUN;
+ si->last_oscr = OSCR;
+ icsr0 = ICSR0;
+
+ if (icsr0 & (ICSR0_FRE | ICSR0_RAB)) {
+ if (icsr0 & ICSR0_FRE) {
+ printk(KERN_DEBUG "pxa_ir: fir receive frame error\n");
+ si->stats.rx_frame_errors++;
+ } else {
+ printk(KERN_DEBUG "pxa_ir: fir receive abort\n");
+ si->stats.rx_errors++;
+ }
+ ICSR0 = icsr0 & (ICSR0_FRE | ICSR0_RAB);
+ }
+
+ if (icsr0 & ICSR0_EIF) {
+ /* An error in FIFO occured, or there is a end of frame */
+ pxa_irda_fir_irq_eif(si, dev);
+ }
+
+ ICCR0 = 0;
+ pxa_irda_fir_dma_rx_start(si);
+ ICCR0 = ICCR0_ITR | ICCR0_RXE;
+
+ return IRQ_HANDLED;
+}
+
+/* hard_xmit interface of irda device */
+static int pxa_irda_hard_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+ struct pxa_irda *si = netdev_priv(dev);
+ int speed = irda_get_next_speed(skb);
+
+ /*
+ * Does this packet contain a request to change the interface
+ * speed? If so, remember it until we complete the transmission
+ * of this frame.
+ */
+ if (speed != si->speed && speed != -1)
+ si->newspeed = speed;
+
+ /*
+ * If this is an empty frame, we can bypass a lot.
+ */
+ if (skb->len == 0) {
+ if (si->newspeed) {
+ si->newspeed = 0;
+ pxa_irda_set_speed(si, speed);
+ }
+ dev_kfree_skb(skb);
+ return 0;
+ }
+
+ netif_stop_queue(dev);
+
+ if (!IS_FIR(si)) {
+ si->tx_buff.data = si->tx_buff.head;
+ si->tx_buff.len = async_wrap_skb(skb, si->tx_buff.data, si->tx_buff.truesize);
+
+ /* Disable STUART interrupts and switch to transmit mode. */
+ STIER = 0;
+ STISR = IrSR_IR_TRANSMIT_ON | IrSR_XMODE_PULSE_1_6;
+
+ /* enable STUART and transmit interrupts */
+ STIER = IER_UUE | IER_TIE;
+ } else {
+ unsigned long mtt = irda_get_mtt(skb);
+
+ si->dma_tx_buff_len = skb->len;
+ memcpy(si->dma_tx_buff, skb->data, skb->len);
+
+ if (mtt)
+ while ((unsigned)(OSCR - si->last_oscr)/4 < mtt)
+ cpu_relax();
+
+ /* stop RX DMA, disable FICP */
+ DCSR(si->rxdma) &= ~DCSR_RUN;
+ ICCR0 = 0;
+
+ pxa_irda_fir_dma_tx_start(si);
+ ICCR0 = ICCR0_ITR | ICCR0_TXE;
+ }
+
+ dev_kfree_skb(skb);
+ dev->trans_start = jiffies;
+ return 0;
+}
+
+static int pxa_irda_ioctl(struct net_device *dev, struct ifreq *ifreq, int cmd)
+{
+ struct if_irda_req *rq = (struct if_irda_req *)ifreq;
+ struct pxa_irda *si = netdev_priv(dev);
+ int ret;
+
+ switch (cmd) {
+ case SIOCSBANDWIDTH:
+ ret = -EPERM;
+ if (capable(CAP_NET_ADMIN)) {
+ /*
+ * We are unable to set the speed if the
+ * device is not running.
+ */
+ if (netif_running(dev)) {
+ ret = pxa_irda_set_speed(si,
+ rq->ifr_baudrate);
+ } else {
+ printk(KERN_INFO "pxa_ir: SIOCSBANDWIDTH: !netif_running\n");
+ ret = 0;
+ }
+ }
+ break;
+
+ case SIOCSMEDIABUSY:
+ ret = -EPERM;
+ if (capable(CAP_NET_ADMIN)) {
+ irda_device_set_media_busy(dev, TRUE);
+ ret = 0;
+ }
+ break;
+
+ case SIOCGRECEIVING:
+ ret = 0;
+ rq->ifr_receiving = IS_FIR(si) ? 0
+ : si->rx_buff.state != OUTSIDE_FRAME;
+ break;
+
+ default:
+ ret = -EOPNOTSUPP;
+ break;
+ }
+
+ return ret;
+}
+
+static struct net_device_stats *pxa_irda_stats(struct net_device *dev)
+{
+ struct pxa_irda *si = netdev_priv(dev);
+ return &si->stats;
+}
+
+static void pxa_irda_startup(struct pxa_irda *si)
+{
+ /* Disable STUART interrupts */
+ STIER = 0;
+ /* enable STUART interrupt to the processor */
+ STMCR = MCR_OUT2;
+ /* configure SIR frame format: StartBit - Data 7 ... Data 0 - Stop Bit */
+ STLCR = LCR_WLS0 | LCR_WLS1;
+ /* enable FIFO, we use FIFO to improve performance */
+ STFCR = FCR_TRFIFOE | FCR_ITL_32;
+
+ /* disable FICP */
+ ICCR0 = 0;
+ /* configure FICP ICCR2 */
+ ICCR2 = ICCR2_TXP | ICCR2_TRIG_32;
+
+ /* configure DMAC */
+ DRCMR17 = si->rxdma | DRCMR_MAPVLD;
+ DRCMR18 = si->txdma | DRCMR_MAPVLD;
+
+ /* force SIR reinitialization */
+ si->speed = 4000000;
+ pxa_irda_set_speed(si, 9600);
+
+ printk(KERN_DEBUG "pxa_ir: irda startup\n");
+}
+
+static void pxa_irda_shutdown(struct pxa_irda *si)
+{
+ unsigned long flags;
+
+ local_irq_save(flags);
+
+ /* disable STUART and interrupt */
+ STIER = 0;
+ /* disable STUART SIR mode */
+ STISR = 0;
+ /* disable the STUART clock */
+ pxa_set_cken(CKEN5_STUART, 0);
+
+ /* disable DMA */
+ DCSR(si->txdma) &= ~DCSR_RUN;
+ DCSR(si->rxdma) &= ~DCSR_RUN;
+ /* disable FICP */
+ ICCR0 = 0;
+ /* disable the FICP clock */
+ pxa_set_cken(CKEN13_FICP, 0);
+
+ DRCMR17 = 0;
+ DRCMR18 = 0;
+
+ local_irq_restore(flags);
+
+ /* power off board transceiver */
+ si->pdata->transceiver_mode(si->dev, IR_OFF);
+
+ printk(KERN_DEBUG "pxa_ir: irda shutdown\n");
+}
+
+static int pxa_irda_start(struct net_device *dev)
+{
+ struct pxa_irda *si = netdev_priv(dev);
+ int err;
+
+ si->speed = 9600;
+
+ err = request_irq(IRQ_STUART, pxa_irda_sir_irq, 0, dev->name, dev);
+ if (err)
+ goto err_irq1;
+
+ err = request_irq(IRQ_ICP, pxa_irda_fir_irq, 0, dev->name, dev);
+ if (err)
+ goto err_irq2;
+
+ /*
+ * The interrupt must remain disabled for now.
+ */
+ disable_irq(IRQ_STUART);
+ disable_irq(IRQ_ICP);
+
+ err = -EBUSY;
+ si->rxdma = pxa_request_dma("FICP_RX",DMA_PRIO_LOW, pxa_irda_fir_dma_rx_irq, dev);
+ if (si->rxdma < 0)
+ goto err_rx_dma;
+
+ si->txdma = pxa_request_dma("FICP_TX",DMA_PRIO_LOW, pxa_irda_fir_dma_tx_irq, dev);
+ if (si->txdma < 0)
+ goto err_tx_dma;
+
+ err = -ENOMEM;
+ si->dma_rx_buff = dma_alloc_coherent(si->dev, IRDA_FRAME_SIZE_LIMIT,
+ &si->dma_rx_buff_phy, GFP_KERNEL );
+ if (!si->dma_rx_buff)
+ goto err_dma_rx_buff;
+
+ si->dma_tx_buff = dma_alloc_coherent(si->dev, IRDA_FRAME_SIZE_LIMIT,
+ &si->dma_tx_buff_phy, GFP_KERNEL );
+ if (!si->dma_tx_buff)
+ goto err_dma_tx_buff;
+
+ /* Setup the serial port for the initial speed. */
+ pxa_irda_startup(si);
+
+ /*
+ * Open a new IrLAP layer instance.
+ */
+ si->irlap = irlap_open(dev, &si->qos, "pxa");
+ err = -ENOMEM;
+ if (!si->irlap)
+ goto err_irlap;
+
+ /*
+ * Now enable the interrupt and start the queue
+ */
+ enable_irq(IRQ_STUART);
+ enable_irq(IRQ_ICP);
+ netif_start_queue(dev);
+
+ printk(KERN_DEBUG "pxa_ir: irda driver opened\n");
+
+ return 0;
+
+err_irlap:
+ pxa_irda_shutdown(si);
+ dma_free_coherent(si->dev, IRDA_FRAME_SIZE_LIMIT, si->dma_tx_buff, si->dma_tx_buff_phy);
+err_dma_tx_buff:
+ dma_free_coherent(si->dev, IRDA_FRAME_SIZE_LIMIT, si->dma_rx_buff, si->dma_rx_buff_phy);
+err_dma_rx_buff:
+ pxa_free_dma(si->txdma);
+err_tx_dma:
+ pxa_free_dma(si->rxdma);
+err_rx_dma:
+ free_irq(IRQ_ICP, dev);
+err_irq2:
+ free_irq(IRQ_STUART, dev);
+err_irq1:
+
+ return err;
+}
+
+static int pxa_irda_stop(struct net_device *dev)
+{
+ struct pxa_irda *si = netdev_priv(dev);
+
+ netif_stop_queue(dev);
+
+ pxa_irda_shutdown(si);
+
+ /* Stop IrLAP */
+ if (si->irlap) {
+ irlap_close(si->irlap);
+ si->irlap = NULL;
+ }
+
+ free_irq(IRQ_STUART, dev);
+ free_irq(IRQ_ICP, dev);
+
+ pxa_free_dma(si->rxdma);
+ pxa_free_dma(si->txdma);
+
+ if (si->dma_rx_buff)
+ dma_free_coherent(si->dev, IRDA_FRAME_SIZE_LIMIT, si->dma_tx_buff, si->dma_tx_buff_phy);
+ if (si->dma_tx_buff)
+ dma_free_coherent(si->dev, IRDA_FRAME_SIZE_LIMIT, si->dma_rx_buff, si->dma_rx_buff_phy);
+
+ printk(KERN_DEBUG "pxa_ir: irda driver closed\n");
+ return 0;
+}
+
+static int pxa_irda_suspend(struct device *_dev, pm_message_t state)
+{
+ struct net_device *dev = dev_get_drvdata(_dev);
+ struct pxa_irda *si;
+
+ if (dev && netif_running(dev)) {
+ si = netdev_priv(dev);
+ netif_device_detach(dev);
+ pxa_irda_shutdown(si);
+ }
+
+ return 0;
+}
+
+static int pxa_irda_resume(struct device *_dev)
+{
+ struct net_device *dev = dev_get_drvdata(_dev);
+ struct pxa_irda *si;
+
+ if (dev && netif_running(dev)) {
+ si = netdev_priv(dev);
+ pxa_irda_startup(si);
+ netif_device_attach(dev);
+ netif_wake_queue(dev);
+ }
+
+ return 0;
+}
+
+
+static int pxa_irda_init_iobuf(iobuff_t *io, int size)
+{
+ io->head = kmalloc(size, GFP_KERNEL | GFP_DMA);
+ if (io->head != NULL) {
+ io->truesize = size;
+ io->in_frame = FALSE;
+ io->state = OUTSIDE_FRAME;
+ io->data = io->head;
+ }
+ return io->head ? 0 : -ENOMEM;
+}
+
+static int pxa_irda_probe(struct device *_dev)
+{
+ struct platform_device *pdev = to_platform_device(_dev);
+ struct net_device *dev;
+ struct pxa_irda *si;
+ unsigned int baudrate_mask;
+ int err;
+
+ if (!pdev->dev.platform_data)
+ return -ENODEV;
+
+ err = request_mem_region(__PREG(STUART), 0x24, "IrDA") ? 0 : -EBUSY;
+ if (err)
+ goto err_mem_1;
+
+ err = request_mem_region(__PREG(FICP), 0x1c, "IrDA") ? 0 : -EBUSY;
+ if (err)
+ goto err_mem_2;
+
+ dev = alloc_irdadev(sizeof(struct pxa_irda));
+ if (!dev)
+ goto err_mem_3;
+
+ si = netdev_priv(dev);
+ si->dev = &pdev->dev;
+ si->pdata = pdev->dev.platform_data;
+
+ /*
+ * Initialise the SIR buffers
+ */
+ err = pxa_irda_init_iobuf(&si->rx_buff, 14384);
+ if (err)
+ goto err_mem_4;
+ err = pxa_irda_init_iobuf(&si->tx_buff, 4000);
+ if (err)
+ goto err_mem_5;
+
+ 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->get_stats = pxa_irda_stats;
+
+ irda_init_max_qos_capabilies(&si->qos);
+
+ baudrate_mask = 0;
+ if (si->pdata->transceiver_cap & IR_SIRMODE)
+ baudrate_mask |= IR_9600|IR_19200|IR_38400|IR_57600|IR_115200;
+ if (si->pdata->transceiver_cap & IR_FIRMODE)
+ baudrate_mask |= IR_4000000 << 8;
+
+ si->qos.baud_rate.bits &= baudrate_mask;
+ si->qos.min_turn_time.bits = 7; /* 1ms or more */
+
+ irda_qos_bits_to_value(&si->qos);
+
+ err = register_netdev(dev);
+
+ if (err == 0)
+ dev_set_drvdata(&pdev->dev, dev);
+
+ if (err) {
+ kfree(si->tx_buff.head);
+err_mem_5:
+ kfree(si->rx_buff.head);
+err_mem_4:
+ free_netdev(dev);
+err_mem_3:
+ release_mem_region(__PREG(FICP), 0x1c);
+err_mem_2:
+ release_mem_region(__PREG(STUART), 0x24);
+ }
+err_mem_1:
+ return err;
+}
+
+static int pxa_irda_remove(struct device *_dev)
+{
+ struct net_device *dev = dev_get_drvdata(_dev);
+
+ if (dev) {
+ struct pxa_irda *si = netdev_priv(dev);
+ unregister_netdev(dev);
+ kfree(si->tx_buff.head);
+ kfree(si->rx_buff.head);
+ free_netdev(dev);
+ }
+
+ release_mem_region(__PREG(STUART), 0x24);
+ release_mem_region(__PREG(FICP), 0x1c);
+
+ return 0;
+}
+
+static struct device_driver pxa_ir_driver = {
+ .name = "pxa2xx-ir",
+ .bus = &platform_bus_type,
+ .probe = pxa_irda_probe,
+ .remove = pxa_irda_remove,
+ .suspend = pxa_irda_suspend,
+ .resume = pxa_irda_resume,
+};
+
+static int __init pxa_irda_init(void)
+{
+ return driver_register(&pxa_ir_driver);
+}
+
+static void __exit pxa_irda_exit(void)
+{
+ driver_unregister(&pxa_ir_driver);
+}
+
+module_init(pxa_irda_init);
+module_exit(pxa_irda_exit);
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/irda/sa1100_ir.c b/drivers/net/irda/sa1100_ir.c
index 8d34ac60d906..76e0b9fb5e96 100644
--- a/drivers/net/irda/sa1100_ir.c
+++ b/drivers/net/irda/sa1100_ir.c
@@ -29,7 +29,7 @@
#include <linux/rtnetlink.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
#include <net/irda/irda.h>
@@ -291,12 +291,12 @@ static void sa1100_irda_shutdown(struct sa1100_irda *si)
/*
* Suspend the IrDA interface.
*/
-static int sa1100_irda_suspend(struct device *_dev, pm_message_t state, u32 level)
+static int sa1100_irda_suspend(struct device *_dev, pm_message_t state)
{
struct net_device *dev = dev_get_drvdata(_dev);
struct sa1100_irda *si;
- if (!dev || level != SUSPEND_DISABLE)
+ if (!dev)
return 0;
si = dev->priv;
@@ -316,12 +316,12 @@ static int sa1100_irda_suspend(struct device *_dev, pm_message_t state, u32 leve
/*
* Resume the IrDA interface.
*/
-static int sa1100_irda_resume(struct device *_dev, u32 level)
+static int sa1100_irda_resume(struct device *_dev)
{
struct net_device *dev = dev_get_drvdata(_dev);
struct sa1100_irda *si;
- if (!dev || level != RESUME_ENABLE)
+ if (!dev)
return 0;
si = dev->priv;
diff --git a/drivers/net/irda/sir_dev.c b/drivers/net/irda/sir_dev.c
index efc5a8870565..df22b8b532e7 100644
--- a/drivers/net/irda/sir_dev.c
+++ b/drivers/net/irda/sir_dev.c
@@ -490,8 +490,7 @@ static void sirdev_free_buffers(struct sir_dev *dev)
{
if (dev->rx_buff.skb)
kfree_skb(dev->rx_buff.skb);
- if (dev->tx_buff.head)
- kfree(dev->tx_buff.head);
+ kfree(dev->tx_buff.head);
dev->rx_buff.head = dev->tx_buff.head = NULL;
dev->rx_buff.skb = NULL;
}
diff --git a/drivers/net/irda/smsc-ircc2.c b/drivers/net/irda/smsc-ircc2.c
index dd89bda1f131..a1d207f2fa68 100644
--- a/drivers/net/irda/smsc-ircc2.c
+++ b/drivers/net/irda/smsc-ircc2.c
@@ -53,6 +53,7 @@
#include <linux/rtnetlink.h>
#include <linux/serial_reg.h>
#include <linux/dma-mapping.h>
+#include <linux/platform_device.h>
#include <asm/io.h>
#include <asm/dma.h>
@@ -213,8 +214,8 @@ static int smsc_ircc_probe_transceiver_smsc_ircc_atc(int fir_base);
/* Power Management */
-static int smsc_ircc_suspend(struct device *dev, pm_message_t state, u32 level);
-static int smsc_ircc_resume(struct device *dev, u32 level);
+static int smsc_ircc_suspend(struct device *dev, pm_message_t state);
+static int smsc_ircc_resume(struct device *dev);
static struct device_driver smsc_ircc_driver = {
.name = SMSC_IRCC2_DRIVER_NAME,
@@ -638,21 +639,14 @@ static void smsc_ircc_setup_qos(struct smsc_ircc_cb *self)
*/
static void smsc_ircc_init_chip(struct smsc_ircc_cb *self)
{
- int iobase, ir_mode, ctrl, fast;
-
- IRDA_ASSERT(self != NULL, return;);
-
- iobase = self->io.fir_base;
- ir_mode = IRCC_CFGA_IRDA_SIR_A;
- ctrl = 0;
- fast = 0;
+ int iobase = self->io.fir_base;
register_bank(iobase, 0);
outb(IRCC_MASTER_RESET, iobase + IRCC_MASTER);
outb(0x00, iobase + IRCC_MASTER);
register_bank(iobase, 1);
- outb(((inb(iobase + IRCC_SCE_CFGA) & 0x87) | ir_mode),
+ outb(((inb(iobase + IRCC_SCE_CFGA) & 0x87) | IRCC_CFGA_IRDA_SIR_A),
iobase + IRCC_SCE_CFGA);
#ifdef smsc_669 /* Uses pin 88/89 for Rx/Tx */
@@ -666,10 +660,10 @@ static void smsc_ircc_init_chip(struct smsc_ircc_cb *self)
outb(SMSC_IRCC2_FIFO_THRESHOLD, iobase + IRCC_FIFO_THRESHOLD);
register_bank(iobase, 4);
- outb((inb(iobase + IRCC_CONTROL) & 0x30) | ctrl, iobase + IRCC_CONTROL);
+ outb((inb(iobase + IRCC_CONTROL) & 0x30), iobase + IRCC_CONTROL);
register_bank(iobase, 0);
- outb(fast, iobase + IRCC_LCR_A);
+ outb(0, iobase + IRCC_LCR_A);
smsc_ircc_set_sir_speed(self, SMSC_IRCC2_C_IRDA_FALLBACK_SPEED);
@@ -1556,6 +1550,46 @@ static int ircc_is_receiving(struct smsc_ircc_cb *self)
}
#endif /* unused */
+static int smsc_ircc_request_irq(struct smsc_ircc_cb *self)
+{
+ int error;
+
+ error = request_irq(self->io.irq, smsc_ircc_interrupt, 0,
+ self->netdev->name, self->netdev);
+ if (error)
+ IRDA_DEBUG(0, "%s(), unable to allocate irq=%d, err=%d\n",
+ __FUNCTION__, self->io.irq, error);
+
+ return error;
+}
+
+static void smsc_ircc_start_interrupts(struct smsc_ircc_cb *self)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&self->lock, flags);
+
+ self->io.speed = 0;
+ smsc_ircc_change_speed(self, SMSC_IRCC2_C_IRDA_FALLBACK_SPEED);
+
+ spin_unlock_irqrestore(&self->lock, flags);
+}
+
+static void smsc_ircc_stop_interrupts(struct smsc_ircc_cb *self)
+{
+ int iobase = self->io.fir_base;
+ unsigned long flags;
+
+ spin_lock_irqsave(&self->lock, flags);
+
+ register_bank(iobase, 0);
+ outb(0, iobase + IRCC_IER);
+ outb(IRCC_MASTER_RESET, iobase + IRCC_MASTER);
+ outb(0x00, iobase + IRCC_MASTER);
+
+ spin_unlock_irqrestore(&self->lock, flags);
+}
+
/*
* Function smsc_ircc_net_open (dev)
@@ -1567,7 +1601,6 @@ static int smsc_ircc_net_open(struct net_device *dev)
{
struct smsc_ircc_cb *self;
char hwname[16];
- unsigned long flags;
IRDA_DEBUG(1, "%s\n", __FUNCTION__);
@@ -1575,6 +1608,11 @@ static int smsc_ircc_net_open(struct net_device *dev)
self = netdev_priv(dev);
IRDA_ASSERT(self != NULL, return 0;);
+ if (self->io.suspended) {
+ IRDA_DEBUG(0, "%s(), device is suspended\n", __FUNCTION__);
+ return -EAGAIN;
+ }
+
if (request_irq(self->io.irq, smsc_ircc_interrupt, 0, dev->name,
(void *) dev)) {
IRDA_DEBUG(0, "%s(), unable to allocate irq=%d\n",
@@ -1582,11 +1620,7 @@ static int smsc_ircc_net_open(struct net_device *dev)
return -EAGAIN;
}
- spin_lock_irqsave(&self->lock, flags);
- /*smsc_ircc_sir_start(self);*/
- self->io.speed = 0;
- smsc_ircc_change_speed(self, SMSC_IRCC2_C_IRDA_FALLBACK_SPEED);
- spin_unlock_irqrestore(&self->lock, flags);
+ smsc_ircc_start_interrupts(self);
/* Give self a hardware name */
/* It would be cool to offer the chip revision here - Jean II */
@@ -1639,37 +1673,63 @@ static int smsc_ircc_net_close(struct net_device *dev)
irlap_close(self->irlap);
self->irlap = NULL;
- free_irq(self->io.irq, dev);
+ smsc_ircc_stop_interrupts(self);
+
+ /* if we are called from smsc_ircc_resume we don't have IRQ reserved */
+ if (!self->io.suspended)
+ free_irq(self->io.irq, dev);
+
disable_dma(self->io.dma);
free_dma(self->io.dma);
return 0;
}
-static int smsc_ircc_suspend(struct device *dev, pm_message_t state, u32 level)
+static int smsc_ircc_suspend(struct device *dev, pm_message_t state)
{
struct smsc_ircc_cb *self = dev_get_drvdata(dev);
- IRDA_MESSAGE("%s, Suspending\n", driver_name);
+ if (!self->io.suspended) {
+ IRDA_DEBUG(1, "%s, Suspending\n", driver_name);
- if (level == SUSPEND_DISABLE && !self->io.suspended) {
- smsc_ircc_net_close(self->netdev);
+ rtnl_lock();
+ if (netif_running(self->netdev)) {
+ netif_device_detach(self->netdev);
+ smsc_ircc_stop_interrupts(self);
+ free_irq(self->io.irq, self->netdev);
+ disable_dma(self->io.dma);
+ }
self->io.suspended = 1;
+ rtnl_unlock();
}
return 0;
}
-static int smsc_ircc_resume(struct device *dev, u32 level)
+static int smsc_ircc_resume(struct device *dev)
{
struct smsc_ircc_cb *self = dev_get_drvdata(dev);
- if (level == RESUME_ENABLE && self->io.suspended) {
-
- smsc_ircc_net_open(self->netdev);
+ if (self->io.suspended) {
+ IRDA_DEBUG(1, "%s, Waking up\n", driver_name);
+
+ rtnl_lock();
+ smsc_ircc_init_chip(self);
+ if (netif_running(self->netdev)) {
+ if (smsc_ircc_request_irq(self)) {
+ /*
+ * Don't fail resume process, just kill this
+ * network interface
+ */
+ unregister_netdevice(self->netdev);
+ } else {
+ enable_dma(self->io.dma);
+ smsc_ircc_start_interrupts(self);
+ netif_device_attach(self->netdev);
+ }
+ }
self->io.suspended = 0;
-
- IRDA_MESSAGE("%s, Waking up\n", driver_name);
+ rtnl_unlock();
}
return 0;
}
@@ -1682,9 +1742,6 @@ static int smsc_ircc_resume(struct device *dev, u32 level)
*/
static int __exit smsc_ircc_close(struct smsc_ircc_cb *self)
{
- int iobase;
- unsigned long flags;
-
IRDA_DEBUG(1, "%s\n", __FUNCTION__);
IRDA_ASSERT(self != NULL, return -1;);
@@ -1694,22 +1751,7 @@ static int __exit smsc_ircc_close(struct smsc_ircc_cb *self)
/* Remove netdevice */
unregister_netdev(self->netdev);
- /* Make sure the irq handler is not exectuting */
- spin_lock_irqsave(&self->lock, flags);
-
- /* Stop interrupts */
- iobase = self->io.fir_base;
- register_bank(iobase, 0);
- outb(0, iobase + IRCC_IER);
- outb(IRCC_MASTER_RESET, iobase + IRCC_MASTER);
- outb(0x00, iobase + IRCC_MASTER);
-#if 0
- /* Reset to SIR mode */
- register_bank(iobase, 1);
- outb(IRCC_CFGA_IRDA_SIR_A|IRCC_CFGA_TX_POLARITY, iobase + IRCC_SCE_CFGA);
- outb(IRCC_CFGB_IR, iobase + IRCC_SCE_CFGB);
-#endif
- spin_unlock_irqrestore(&self->lock, flags);
+ smsc_ircc_stop_interrupts(self);
/* Release the PORTS that this driver is using */
IRDA_DEBUG(0, "%s(), releasing 0x%03x\n", __FUNCTION__,
diff --git a/drivers/net/irda/stir4200.c b/drivers/net/irda/stir4200.c
index 15f207323d97..3961a754e920 100644
--- a/drivers/net/irda/stir4200.c
+++ b/drivers/net/irda/stir4200.c
@@ -678,10 +678,9 @@ static void turnaround_delay(const struct stir_cb *stir, long us)
return;
ticks = us / (1000000 / HZ);
- if (ticks > 0) {
- current->state = TASK_INTERRUPTIBLE;
- schedule_timeout(1 + ticks);
- } else
+ if (ticks > 0)
+ schedule_timeout_interruptible(1 + ticks);
+ else
udelay(us);
}
diff --git a/drivers/net/irda/vlsi_ir.c b/drivers/net/irda/vlsi_ir.c
index 651c5a6578fd..a9f49f058cfb 100644
--- a/drivers/net/irda/vlsi_ir.c
+++ b/drivers/net/irda/vlsi_ir.c
@@ -473,8 +473,7 @@ static int vlsi_free_ring(struct vlsi_ring *r)
rd_set_addr_status(rd, 0, 0);
if (busaddr)
pci_unmap_single(r->pdev, busaddr, r->len, r->dir);
- if (rd->buf)
- kfree(rd->buf);
+ kfree(rd->buf);
}
kfree(r);
return 0;
diff --git a/drivers/net/iseries_veth.c b/drivers/net/iseries_veth.c
index 3d56cf5a4e23..77eadf84cb2c 100644
--- a/drivers/net/iseries_veth.c
+++ b/drivers/net/iseries_veth.c
@@ -58,7 +58,6 @@
#include <linux/config.h>
#include <linux/module.h>
-#include <linux/version.h>
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/ioport.h>
@@ -70,13 +69,14 @@
#include <linux/delay.h>
#include <linux/mm.h>
#include <linux/ethtool.h>
-#include <asm/iSeries/mf.h>
-#include <asm/iSeries/iSeries_pci.h>
+
+#include <asm/abs_addr.h>
+#include <asm/iseries/mf.h>
#include <asm/uaccess.h>
-#include <asm/iSeries/HvLpConfig.h>
-#include <asm/iSeries/HvTypes.h>
-#include <asm/iSeries/HvLpEvent.h>
+#include <asm/iseries/hv_lp_config.h>
+#include <asm/iseries/hv_types.h>
+#include <asm/iseries/hv_lp_event.h>
#include <asm/iommu.h>
#include <asm/vio.h>
@@ -1397,13 +1397,13 @@ static inline void veth_build_dma_list(struct dma_chunk *list,
* it just at the granularity of iSeries real->absolute
* mapping? Indeed, given the way the allocator works, can we
* count on them being absolutely contiguous? */
- list[0].addr = ISERIES_HV_ADDR(p);
+ list[0].addr = iseries_hv_addr(p);
list[0].size = min(length,
PAGE_SIZE - ((unsigned long)p & ~PAGE_MASK));
done = list[0].size;
while (done < length) {
- list[i].addr = ISERIES_HV_ADDR(p + done);
+ list[i].addr = iseries_hv_addr(p + done);
list[i].size = min(length-done, PAGE_SIZE);
done += list[i].size;
i++;
@@ -1496,8 +1496,8 @@ static void veth_receive(struct veth_lpar_connection *cnx,
cnx->dst_inst,
HvLpDma_AddressType_RealAddress,
HvLpDma_AddressType_TceIndex,
- ISERIES_HV_ADDR(&local_list),
- ISERIES_HV_ADDR(&remote_list),
+ iseries_hv_addr(&local_list),
+ iseries_hv_addr(&remote_list),
length);
if (rc != HvLpDma_Rc_Good) {
dev_kfree_skb_irq(skb);
@@ -1647,10 +1647,13 @@ static struct vio_device_id veth_device_table[] __devinitdata = {
MODULE_DEVICE_TABLE(vio, veth_device_table);
static struct vio_driver veth_driver = {
- .name = DRV_NAME,
.id_table = veth_device_table,
.probe = veth_probe,
- .remove = veth_remove
+ .remove = veth_remove,
+ .driver = {
+ .name = DRV_NAME,
+ .owner = THIS_MODULE,
+ }
};
/*
diff --git a/drivers/net/ixgb/ixgb_ethtool.c b/drivers/net/ixgb/ixgb_ethtool.c
index 9d026ed77ddd..d38ade5f2f4e 100644
--- a/drivers/net/ixgb/ixgb_ethtool.c
+++ b/drivers/net/ixgb/ixgb_ethtool.c
@@ -645,11 +645,10 @@ ixgb_phys_id(struct net_device *netdev, uint32_t data)
mod_timer(&adapter->blink_timer, jiffies);
- set_current_state(TASK_INTERRUPTIBLE);
- if(data)
- schedule_timeout(data * HZ);
+ if (data)
+ schedule_timeout_interruptible(data * HZ);
else
- schedule_timeout(MAX_SCHEDULE_TIMEOUT);
+ schedule_timeout_interruptible(MAX_SCHEDULE_TIMEOUT);
del_timer_sync(&adapter->blink_timer);
ixgb_led_off(&adapter->hw);
@@ -695,7 +694,7 @@ ixgb_get_strings(struct net_device *netdev, uint32_t stringset, uint8_t *data)
}
}
-struct ethtool_ops ixgb_ethtool_ops = {
+static struct ethtool_ops ixgb_ethtool_ops = {
.get_settings = ixgb_get_settings,
.set_settings = ixgb_set_settings,
.get_drvinfo = ixgb_get_drvinfo,
@@ -723,6 +722,7 @@ struct ethtool_ops ixgb_ethtool_ops = {
.phys_id = ixgb_phys_id,
.get_stats_count = ixgb_get_stats_count,
.get_ethtool_stats = ixgb_get_ethtool_stats,
+ .get_perm_addr = ethtool_op_get_perm_addr,
};
void ixgb_set_ethtool_ops(struct net_device *netdev)
diff --git a/drivers/net/ixgb/ixgb_hw.c b/drivers/net/ixgb/ixgb_hw.c
index 69329c73095a..620cad48bdea 100644
--- a/drivers/net/ixgb/ixgb_hw.c
+++ b/drivers/net/ixgb/ixgb_hw.c
@@ -47,9 +47,22 @@ static void ixgb_optics_reset(struct ixgb_hw *hw);
static ixgb_phy_type ixgb_identify_phy(struct ixgb_hw *hw);
-uint32_t ixgb_mac_reset(struct ixgb_hw *hw);
+static void ixgb_clear_hw_cntrs(struct ixgb_hw *hw);
-uint32_t ixgb_mac_reset(struct ixgb_hw *hw)
+static void ixgb_clear_vfta(struct ixgb_hw *hw);
+
+static void ixgb_init_rx_addrs(struct ixgb_hw *hw);
+
+static uint16_t ixgb_read_phy_reg(struct ixgb_hw *hw,
+ uint32_t reg_address,
+ uint32_t phy_address,
+ uint32_t device_type);
+
+static boolean_t ixgb_setup_fc(struct ixgb_hw *hw);
+
+static boolean_t mac_addr_valid(uint8_t *mac_addr);
+
+static uint32_t ixgb_mac_reset(struct ixgb_hw *hw)
{
uint32_t ctrl_reg;
@@ -335,7 +348,7 @@ ixgb_init_hw(struct ixgb_hw *hw)
* of the receive addresss registers. Clears the multicast table. Assumes
* the receiver is in reset when the routine is called.
*****************************************************************************/
-void
+static void
ixgb_init_rx_addrs(struct ixgb_hw *hw)
{
uint32_t i;
@@ -604,7 +617,7 @@ ixgb_write_vfta(struct ixgb_hw *hw,
*
* hw - Struct containing variables accessed by shared code
*****************************************************************************/
-void
+static void
ixgb_clear_vfta(struct ixgb_hw *hw)
{
uint32_t offset;
@@ -620,7 +633,7 @@ ixgb_clear_vfta(struct ixgb_hw *hw)
* hw - Struct containing variables accessed by shared code
*****************************************************************************/
-boolean_t
+static boolean_t
ixgb_setup_fc(struct ixgb_hw *hw)
{
uint32_t ctrl_reg;
@@ -722,7 +735,7 @@ ixgb_setup_fc(struct ixgb_hw *hw)
* This requires that first an address cycle command is sent, followed by a
* read command.
*****************************************************************************/
-uint16_t
+static uint16_t
ixgb_read_phy_reg(struct ixgb_hw *hw,
uint32_t reg_address,
uint32_t phy_address,
@@ -815,7 +828,7 @@ ixgb_read_phy_reg(struct ixgb_hw *hw,
* This requires that first an address cycle command is sent, followed by a
* write command.
*****************************************************************************/
-void
+static void
ixgb_write_phy_reg(struct ixgb_hw *hw,
uint32_t reg_address,
uint32_t phy_address,
@@ -959,7 +972,7 @@ boolean_t ixgb_check_for_bad_link(struct ixgb_hw *hw)
*
* hw - Struct containing variables accessed by shared code
*****************************************************************************/
-void
+static void
ixgb_clear_hw_cntrs(struct ixgb_hw *hw)
{
volatile uint32_t temp_reg;
@@ -1114,7 +1127,7 @@ ixgb_get_bus_info(struct ixgb_hw *hw)
* mac_addr - pointer to MAC address.
*
*****************************************************************************/
-boolean_t
+static boolean_t
mac_addr_valid(uint8_t *mac_addr)
{
boolean_t is_valid = TRUE;
diff --git a/drivers/net/ixgb/ixgb_hw.h b/drivers/net/ixgb/ixgb_hw.h
index 8bcf31ed10c2..382c6300ccc2 100644
--- a/drivers/net/ixgb/ixgb_hw.h
+++ b/drivers/net/ixgb/ixgb_hw.h
@@ -784,23 +784,8 @@ struct ixgb_hw_stats {
extern boolean_t ixgb_adapter_stop(struct ixgb_hw *hw);
extern boolean_t ixgb_init_hw(struct ixgb_hw *hw);
extern boolean_t ixgb_adapter_start(struct ixgb_hw *hw);
-extern void ixgb_init_rx_addrs(struct ixgb_hw *hw);
extern void ixgb_check_for_link(struct ixgb_hw *hw);
extern boolean_t ixgb_check_for_bad_link(struct ixgb_hw *hw);
-extern boolean_t ixgb_setup_fc(struct ixgb_hw *hw);
-extern void ixgb_clear_hw_cntrs(struct ixgb_hw *hw);
-extern boolean_t mac_addr_valid(uint8_t *mac_addr);
-
-extern uint16_t ixgb_read_phy_reg(struct ixgb_hw *hw,
- uint32_t reg_addr,
- uint32_t phy_addr,
- uint32_t device_type);
-
-extern void ixgb_write_phy_reg(struct ixgb_hw *hw,
- uint32_t reg_addr,
- uint32_t phy_addr,
- uint32_t device_type,
- uint16_t data);
extern void ixgb_rar_set(struct ixgb_hw *hw,
uint8_t *addr,
@@ -818,8 +803,6 @@ extern void ixgb_write_vfta(struct ixgb_hw *hw,
uint32_t offset,
uint32_t value);
-extern void ixgb_clear_vfta(struct ixgb_hw *hw);
-
/* Access functions to eeprom data */
void ixgb_get_ee_mac_addr(struct ixgb_hw *hw, uint8_t *mac_addr);
uint32_t ixgb_get_ee_pba_number(struct ixgb_hw *hw);
diff --git a/drivers/net/ixgb/ixgb_main.c b/drivers/net/ixgb/ixgb_main.c
index 89d6d69be382..f9f77e4f5965 100644
--- a/drivers/net/ixgb/ixgb_main.c
+++ b/drivers/net/ixgb/ixgb_main.c
@@ -45,7 +45,7 @@
*/
char ixgb_driver_name[] = "ixgb";
-char ixgb_driver_string[] = "Intel(R) PRO/10GbE Network Driver";
+static char ixgb_driver_string[] = "Intel(R) PRO/10GbE Network Driver";
#ifndef CONFIG_IXGB_NAPI
#define DRIVERNAPI
@@ -460,8 +460,9 @@ ixgb_probe(struct pci_dev *pdev,
}
ixgb_get_ee_mac_addr(&adapter->hw, netdev->dev_addr);
+ memcpy(netdev->perm_addr, netdev->dev_addr, netdev->addr_len);
- if(!is_valid_ether_addr(netdev->dev_addr)) {
+ if(!is_valid_ether_addr(netdev->perm_addr)) {
err = -EIO;
goto err_eeprom;
}
diff --git a/drivers/net/jazzsonic.c b/drivers/net/jazzsonic.c
index 8423cb6875f0..2fb3101cb33e 100644
--- a/drivers/net/jazzsonic.c
+++ b/drivers/net/jazzsonic.c
@@ -33,7 +33,7 @@
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
#include <asm/bootinfo.h>
@@ -285,18 +285,8 @@ static struct device_driver jazz_sonic_driver = {
.remove = __devexit_p(jazz_sonic_device_remove),
};
-static void jazz_sonic_platform_release (struct device *device)
-{
- struct platform_device *pldev;
-
- /* free device */
- pldev = to_platform_device (device);
- kfree (pldev);
-}
-
static int __init jazz_sonic_init_module(void)
{
- struct platform_device *pldev;
int err;
if ((err = driver_register(&jazz_sonic_driver))) {
@@ -304,27 +294,19 @@ static int __init jazz_sonic_init_module(void)
return err;
}
- jazz_sonic_device = NULL;
-
- if (!(pldev = kmalloc (sizeof (*pldev), GFP_KERNEL))) {
+ jazz_sonic_device = platform_device_alloc(jazz_sonic_string, 0);
+ if (!jazz_sonnic_device)
goto out_unregister;
- }
- memset(pldev, 0, sizeof (*pldev));
- pldev->name = jazz_sonic_string;
- pldev->id = 0;
- pldev->dev.release = jazz_sonic_platform_release;
- jazz_sonic_device = pldev;
-
- if (platform_device_register (pldev)) {
- kfree(pldev);
+ if (platform_device_add(jazz_sonic_device)) {
+ platform_device_put(jazz_sonic_device);
jazz_sonic_device = NULL;
}
return 0;
out_unregister:
- platform_device_unregister(pldev);
+ driver_unregister(&jazz_sonic_driver);
return -ENOMEM;
}
diff --git a/drivers/net/lance.c b/drivers/net/lance.c
index b4929beb33b2..1d75ca0bb939 100644
--- a/drivers/net/lance.c
+++ b/drivers/net/lance.c
@@ -298,7 +298,7 @@ enum {OLD_LANCE = 0, PCNET_ISA=1, PCNET_ISAP=2, PCNET_PCI=3, PCNET_VLB=4, PCNET_
static unsigned char lance_need_isa_bounce_buffers = 1;
static int lance_open(struct net_device *dev);
-static void lance_init_ring(struct net_device *dev, int mode);
+static void lance_init_ring(struct net_device *dev, gfp_t mode);
static int lance_start_xmit(struct sk_buff *skb, struct net_device *dev);
static int lance_rx(struct net_device *dev);
static irqreturn_t lance_interrupt(int irq, void *dev_id, struct pt_regs *regs);
@@ -846,7 +846,7 @@ lance_purge_ring(struct net_device *dev)
/* Initialize the LANCE Rx and Tx rings. */
static void
-lance_init_ring(struct net_device *dev, int gfp)
+lance_init_ring(struct net_device *dev, gfp_t gfp)
{
struct lance_private *lp = dev->priv;
int i;
diff --git a/drivers/net/lasi_82596.c b/drivers/net/lasi_82596.c
index 41bad07ac1ac..f7b7238d8352 100644
--- a/drivers/net/lasi_82596.c
+++ b/drivers/net/lasi_82596.c
@@ -415,6 +415,10 @@ static int rx_ring_size = RX_RING_SIZE;
static int ticks_limit = 100;
static int max_cmd_backlog = TX_RING_SIZE-1;
+#ifdef CONFIG_NET_POLL_CONTROLLER
+static void i596_poll_controller(struct net_device *dev);
+#endif
+
static inline void CA(struct net_device *dev)
{
@@ -636,11 +640,11 @@ static int init_i596_mem(struct net_device *dev)
disable_irq(dev->irq); /* disable IRQs from LAN */
DEB(DEB_INIT,
- printk("RESET 82596 port: %p (with IRQ %d disabled)\n",
- (void*)(dev->base_addr + PA_I82596_RESET),
+ printk("RESET 82596 port: %lx (with IRQ %d disabled)\n",
+ (dev->base_addr + PA_I82596_RESET),
dev->irq));
- gsc_writel(0, (void*)(dev->base_addr + PA_I82596_RESET)); /* Hard Reset */
+ gsc_writel(0, (dev->base_addr + PA_I82596_RESET)); /* Hard Reset */
udelay(100); /* Wait 100us - seems to help */
/* change the scp address */
@@ -1209,6 +1213,9 @@ static int __devinit i82596_probe(struct net_device *dev,
dev->set_multicast_list = set_multicast_list;
dev->tx_timeout = i596_tx_timeout;
dev->watchdog_timeo = TX_TIMEOUT;
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ dev->poll_controller = i596_poll_controller;
+#endif
dev->priv = (void *)(dev->mem_start);
@@ -1242,6 +1249,14 @@ static int __devinit i82596_probe(struct net_device *dev,
return 0;
}
+#ifdef CONFIG_NET_POLL_CONTROLLER
+static void i596_poll_controller(struct net_device *dev)
+{
+ disable_irq(dev->irq);
+ i596_interrupt(dev->irq, dev, NULL);
+ enable_irq(dev->irq);
+}
+#endif
static irqreturn_t i596_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
@@ -1528,17 +1543,18 @@ 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);
+ __FILE__, dev->hpa.start);
return -ENODEV;
}
- printk(KERN_INFO "Found i82596 at 0x%lx, IRQ %d\n", dev->hpa, dev->irq);
+ printk(KERN_INFO "Found i82596 at 0x%lx, IRQ %d\n", dev->hpa.start,
+ dev->irq);
netdevice = alloc_etherdev(0);
if (!netdevice)
return -ENOMEM;
- netdevice->base_addr = dev->hpa;
+ netdevice->base_addr = dev->hpa.start;
netdevice->irq = dev->irq;
retval = i82596_probe(netdevice, &dev->dev);
@@ -1566,7 +1582,7 @@ static struct parisc_device_id lan_tbl[] = {
MODULE_DEVICE_TABLE(parisc, lan_tbl);
static struct parisc_driver lan_driver = {
- .name = "Apricot",
+ .name = "lasi_82596",
.id_table = lan_tbl,
.probe = lan_init_chip,
};
diff --git a/drivers/net/lne390.c b/drivers/net/lne390.c
index 27f0d8ac4c40..309d254842cf 100644
--- a/drivers/net/lne390.c
+++ b/drivers/net/lne390.c
@@ -298,7 +298,7 @@ static int __init lne390_probe1(struct net_device *dev, int ioaddr)
return 0;
unmap:
if (ei_status.reg0)
- iounmap((void *)dev->mem_start);
+ iounmap(ei_status.mem);
cleanup:
free_irq(dev->irq, dev);
return ret;
diff --git a/drivers/net/mac8390.c b/drivers/net/mac8390.c
index ce5761816a64..d8c99f038fa0 100644
--- a/drivers/net/mac8390.c
+++ b/drivers/net/mac8390.c
@@ -15,7 +15,6 @@
* and fixed access to Sonic Sys card which masquerades as a Farallon
* by rayk@knightsmanor.org */
-#include <linux/version.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/types.h>
diff --git a/drivers/net/mace.c b/drivers/net/mace.c
index 81d0a26e4f41..2a5add257b8f 100644
--- a/drivers/net/mace.c
+++ b/drivers/net/mace.c
@@ -1016,6 +1016,7 @@ static struct of_device_id mace_match[] =
},
{},
};
+MODULE_DEVICE_TABLE (of, mace_match);
static struct macio_driver mace_driver =
{
@@ -1035,10 +1036,8 @@ static void __exit mace_cleanup(void)
{
macio_unregister_driver(&mace_driver);
- if (dummy_buf) {
- kfree(dummy_buf);
- dummy_buf = NULL;
- }
+ kfree(dummy_buf);
+ dummy_buf = NULL;
}
MODULE_AUTHOR("Paul Mackerras");
diff --git a/drivers/net/macsonic.c b/drivers/net/macsonic.c
index 405e18365ede..9ef4592aca03 100644
--- a/drivers/net/macsonic.c
+++ b/drivers/net/macsonic.c
@@ -47,7 +47,7 @@
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
#include <asm/bootinfo.h>
@@ -599,18 +599,8 @@ static struct device_driver mac_sonic_driver = {
.remove = __devexit_p(mac_sonic_device_remove),
};
-static void mac_sonic_platform_release(struct device *device)
-{
- struct platform_device *pldev;
-
- /* free device */
- pldev = to_platform_device (device);
- kfree (pldev);
-}
-
static int __init mac_sonic_init_module(void)
{
- struct platform_device *pldev;
int err;
if ((err = driver_register(&mac_sonic_driver))) {
@@ -618,27 +608,20 @@ static int __init mac_sonic_init_module(void)
return err;
}
- mac_sonic_device = NULL;
-
- if (!(pldev = kmalloc (sizeof (*pldev), GFP_KERNEL))) {
+ mac_sonic_device = platform_device_alloc(mac_sonic_string, 0);
+ if (!mac_sonic_device) {
goto out_unregister;
}
- memset(pldev, 0, sizeof (*pldev));
- pldev->name = mac_sonic_string;
- pldev->id = 0;
- pldev->dev.release = mac_sonic_platform_release;
- mac_sonic_device = pldev;
-
- if (platform_device_register (pldev)) {
- kfree(pldev);
+ if (platform_device_add(mac_sonic_device)) {
+ platform_device_put(mac_sonic_device);
mac_sonic_device = NULL;
}
return 0;
out_unregister:
- platform_device_unregister(pldev);
+ driver_unregister(&mac_sonic_driver);
return -ENOMEM;
}
diff --git a/drivers/net/mii.c b/drivers/net/mii.c
index c33cb3dc942b..e42aa797f08b 100644
--- a/drivers/net/mii.c
+++ b/drivers/net/mii.c
@@ -207,6 +207,20 @@ int mii_ethtool_sset(struct mii_if_info *mii, struct ethtool_cmd *ecmd)
return 0;
}
+int mii_check_gmii_support(struct mii_if_info *mii)
+{
+ int reg;
+
+ reg = mii->mdio_read(mii->dev, mii->phy_id, MII_BMSR);
+ if (reg & BMSR_ESTATEN) {
+ reg = mii->mdio_read(mii->dev, mii->phy_id, MII_ESTATUS);
+ if (reg & (ESTATUS_1000_TFULL | ESTATUS_1000_THALF))
+ return 1;
+ }
+
+ return 0;
+}
+
int mii_link_ok (struct mii_if_info *mii)
{
/* first, a dummy read, needed to latch some MII phys */
@@ -394,5 +408,6 @@ EXPORT_SYMBOL(mii_ethtool_gset);
EXPORT_SYMBOL(mii_ethtool_sset);
EXPORT_SYMBOL(mii_check_link);
EXPORT_SYMBOL(mii_check_media);
+EXPORT_SYMBOL(mii_check_gmii_support);
EXPORT_SYMBOL(generic_mii_ioctl);
diff --git a/drivers/net/mipsnet.c b/drivers/net/mipsnet.c
new file mode 100644
index 000000000000..bbffb585b3b3
--- /dev/null
+++ b/drivers/net/mipsnet.c
@@ -0,0 +1,372 @@
+/*
+ * 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.
+ */
+
+#define DEBUG
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/netdevice.h>
+#include <linux/sched.h>
+#include <linux/etherdevice.h>
+#include <linux/netdevice.h>
+#include <linux/platform_device.h>
+#include <asm/io.h>
+#include <asm/mips-boards/simint.h>
+
+#include "mipsnet.h" /* actual device IO mapping */
+
+#define MIPSNET_VERSION "2005-06-20"
+
+#define mipsnet_reg_address(dev, field) (dev->base_addr + field_offset(field))
+
+struct mipsnet_priv {
+ struct net_device_stats stats;
+};
+
+static struct platform_device *mips_plat_dev;
+
+static char mipsnet_string[] = "mipsnet";
+
+/*
+ * Copy data from the MIPSNET rx data port
+ */
+static int ioiocpy_frommipsnet(struct net_device *dev, unsigned char *kdata,
+ int len)
+{
+ uint32_t available_len = inl(mipsnet_reg_address(dev, rxDataCount));
+ if (available_len < len)
+ return -EFAULT;
+
+ for (; len > 0; len--, kdata++) {
+ *kdata = inb(mipsnet_reg_address(dev, rxDataBuffer));
+ }
+
+ return inl(mipsnet_reg_address(dev, rxDataCount));
+}
+
+static inline ssize_t mipsnet_put_todevice(struct net_device *dev,
+ struct sk_buff *skb)
+{
+ int count_to_go = skb->len;
+ char *buf_ptr = skb->data;
+ struct mipsnet_priv *mp = netdev_priv(dev);
+
+ pr_debug("%s: %s(): telling MIPSNET txDataCount(%d)\n",
+ dev->name, __FUNCTION__, skb->len);
+
+ outl(skb->len, mipsnet_reg_address(dev, txDataCount));
+
+ pr_debug("%s: %s(): sending data to MIPSNET txDataBuffer(%d)\n",
+ dev->name, __FUNCTION__, skb->len);
+
+ for (; count_to_go; buf_ptr++, count_to_go--) {
+ outb(*buf_ptr, mipsnet_reg_address(dev, txDataBuffer));
+ }
+
+ mp->stats.tx_packets++;
+ mp->stats.tx_bytes += skb->len;
+
+ return skb->len;
+}
+
+static int mipsnet_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+ pr_debug("%s:%s(): transmitting %d bytes\n",
+ dev->name, __FUNCTION__, skb->len);
+
+ /* Only one packet at a time. Once TXDONE interrupt is serviced, the
+ * queue will be restarted.
+ */
+ netif_stop_queue(dev);
+ mipsnet_put_todevice(dev, skb);
+
+ return 0;
+}
+
+static inline ssize_t mipsnet_get_fromdev(struct net_device *dev, size_t count)
+{
+ struct sk_buff *skb;
+ size_t len = count;
+ struct mipsnet_priv *mp = netdev_priv(dev);
+
+ if (!(skb = alloc_skb(len + 2, GFP_KERNEL))) {
+ mp->stats.rx_dropped++;
+ return -ENOMEM;
+ }
+
+ skb_reserve(skb, 2);
+ if (ioiocpy_frommipsnet(dev, skb_put(skb, len), len))
+ return -EFAULT;
+
+ skb->dev = dev;
+ skb->protocol = eth_type_trans(skb, dev);
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
+
+ pr_debug("%s:%s(): pushing RXed data to kernel\n",
+ dev->name, __FUNCTION__);
+ netif_rx(skb);
+
+ mp->stats.rx_packets++;
+ mp->stats.rx_bytes += len;
+
+ return count;
+}
+
+static irqreturn_t
+mipsnet_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+ struct net_device *dev = dev_id;
+
+ irqreturn_t retval = IRQ_NONE;
+ uint64_t interruptFlags;
+
+ if (irq == dev->irq) {
+ pr_debug("%s:%s(): irq %d for device\n",
+ dev->name, __FUNCTION__, irq);
+
+ retval = IRQ_HANDLED;
+
+ interruptFlags =
+ inl(mipsnet_reg_address(dev, interruptControl));
+ pr_debug("%s:%s(): intCtl=0x%016llx\n", dev->name,
+ __FUNCTION__, interruptFlags);
+
+ if (interruptFlags & MIPSNET_INTCTL_TXDONE) {
+ pr_debug("%s:%s(): got TXDone\n",
+ dev->name, __FUNCTION__);
+ outl(MIPSNET_INTCTL_TXDONE,
+ mipsnet_reg_address(dev, interruptControl));
+ // only one packet at a time, we are done.
+ netif_wake_queue(dev);
+ } else if (interruptFlags & MIPSNET_INTCTL_RXDONE) {
+ pr_debug("%s:%s(): got RX data\n",
+ dev->name, __FUNCTION__);
+ mipsnet_get_fromdev(dev,
+ inl(mipsnet_reg_address(dev, rxDataCount)));
+ pr_debug("%s:%s(): clearing RX int\n",
+ dev->name, __FUNCTION__);
+ outl(MIPSNET_INTCTL_RXDONE,
+ mipsnet_reg_address(dev, interruptControl));
+
+ } else if (interruptFlags & MIPSNET_INTCTL_TESTBIT) {
+ pr_debug("%s:%s(): got test interrupt\n",
+ dev->name, __FUNCTION__);
+ // TESTBIT is cleared on read.
+ // And takes effect after a write with 0
+ outl(0, mipsnet_reg_address(dev, interruptControl));
+ } else {
+ pr_debug("%s:%s(): no valid fags 0x%016llx\n",
+ dev->name, __FUNCTION__, interruptFlags);
+ // Maybe shared IRQ, just ignore, no clearing.
+ retval = IRQ_NONE;
+ }
+
+ } else {
+ printk(KERN_INFO "%s: %s(): irq %d for unknown device\n",
+ dev->name, __FUNCTION__, irq);
+ retval = IRQ_NONE;
+ }
+ return retval;
+} //mipsnet_interrupt()
+
+static int mipsnet_open(struct net_device *dev)
+{
+ int err;
+ pr_debug("%s: mipsnet_open\n", dev->name);
+
+ err = request_irq(dev->irq, &mipsnet_interrupt,
+ SA_SHIRQ, dev->name, (void *) dev);
+
+ if (err) {
+ pr_debug("%s: %s(): can't get irq %d\n",
+ dev->name, __FUNCTION__, dev->irq);
+ release_region(dev->base_addr, MIPSNET_IO_EXTENT);
+ return err;
+ }
+
+ pr_debug("%s: %s(): got IO region at 0x%04lx and irq %d for dev.\n",
+ dev->name, __FUNCTION__, dev->base_addr, dev->irq);
+
+
+ netif_start_queue(dev);
+
+ // test interrupt handler
+ outl(MIPSNET_INTCTL_TESTBIT,
+ mipsnet_reg_address(dev, interruptControl));
+
+
+ return 0;
+}
+
+static int mipsnet_close(struct net_device *dev)
+{
+ pr_debug("%s: %s()\n", dev->name, __FUNCTION__);
+ netif_stop_queue(dev);
+ return 0;
+}
+
+static struct net_device_stats *mipsnet_get_stats(struct net_device *dev)
+{
+ struct mipsnet_priv *mp = netdev_priv(dev);
+
+ return &mp->stats;
+}
+
+static void mipsnet_set_mclist(struct net_device *dev)
+{
+ // we don't do anything
+ return;
+}
+
+static int __init mipsnet_probe(struct device *dev)
+{
+ struct net_device *netdev;
+ int err;
+
+ netdev = alloc_etherdev(sizeof(struct mipsnet_priv));
+ if (!netdev) {
+ err = -ENOMEM;
+ goto out;
+ }
+
+ dev_set_drvdata(dev, netdev);
+
+ netdev->open = mipsnet_open;
+ netdev->stop = mipsnet_close;
+ netdev->hard_start_xmit = mipsnet_xmit;
+ netdev->get_stats = mipsnet_get_stats;
+ netdev->set_multicast_list = mipsnet_set_mclist;
+
+ /*
+ * TODO: probe for these or load them from PARAM
+ */
+ netdev->base_addr = 0x4200;
+ netdev->irq = MIPSCPU_INT_BASE + MIPSCPU_INT_MB0 +
+ inl(mipsnet_reg_address(netdev, interruptInfo));
+
+ // Get the io region now, get irq on open()
+ if (!request_region(netdev->base_addr, MIPSNET_IO_EXTENT, "mipsnet")) {
+ pr_debug("%s: %s(): IO region {start: 0x%04lux, len: %d} "
+ "for dev is not availble.\n", netdev->name,
+ __FUNCTION__, netdev->base_addr, MIPSNET_IO_EXTENT);
+ err = -EBUSY;
+ goto out_free_netdev;
+ }
+
+ /*
+ * Lacking any better mechanism to allocate a MAC address we use a
+ * random one ...
+ */
+ random_ether_addr(netdev->dev_addr);
+
+ err = register_netdev(netdev);
+ if (err) {
+ printk(KERN_ERR "MIPSNet: failed to register netdev.\n");
+ goto out_free_region;
+ }
+
+ return 0;
+
+out_free_region:
+ release_region(netdev->base_addr, MIPSNET_IO_EXTENT);
+
+out_free_netdev:
+ free_netdev(netdev);
+
+out:
+ return err;
+}
+
+static int __devexit mipsnet_device_remove(struct device *device)
+{
+ struct net_device *dev = dev_get_drvdata(device);
+
+ unregister_netdev(dev);
+ release_region(dev->base_addr, MIPSNET_IO_EXTENT);
+ free_netdev(dev);
+ dev_set_drvdata(device, NULL);
+
+ return 0;
+}
+
+static struct device_driver mipsnet_driver = {
+ .name = mipsnet_string,
+ .bus = &platform_bus_type,
+ .probe = mipsnet_probe,
+ .remove = __devexit_p(mipsnet_device_remove),
+};
+
+static void mipsnet_platform_release(struct device *device)
+{
+ struct platform_device *pldev;
+
+ /* free device */
+ pldev = to_platform_device(device);
+ kfree(pldev);
+}
+
+static int __init mipsnet_init_module(void)
+{
+ struct platform_device *pldev;
+ int err;
+
+ printk(KERN_INFO "MIPSNet Ethernet driver. Version: %s. "
+ "(c)2005 MIPS Technologies, Inc.\n", MIPSNET_VERSION);
+
+ if (driver_register(&mipsnet_driver)) {
+ printk(KERN_ERR "Driver registration failed\n");
+ err = -ENODEV;
+ goto out;
+ }
+
+ if (!(pldev = kmalloc (sizeof (*pldev), GFP_KERNEL))) {
+ err = -ENOMEM;
+ goto out_unregister_driver;
+ }
+
+ memset (pldev, 0, sizeof (*pldev));
+ pldev->name = mipsnet_string;
+ pldev->id = 0;
+ pldev->dev.release = mipsnet_platform_release;
+
+ if (platform_device_register(pldev)) {
+ err = -ENODEV;
+ goto out_free_pldev;
+ }
+
+ if (!pldev->dev.driver) {
+ /*
+ * The driver was not bound to this device, there was
+ * no hardware at this address. Unregister it, as the
+ * release fuction will take care of freeing the
+ * allocated structure
+ */
+ platform_device_unregister (pldev);
+ }
+
+ mips_plat_dev = pldev;
+
+ return 0;
+
+out_free_pldev:
+ kfree(pldev);
+
+out_unregister_driver:
+ driver_unregister(&mipsnet_driver);
+out:
+ return err;
+}
+
+static void __exit mipsnet_exit_module(void)
+{
+ pr_debug("MIPSNet Ethernet driver exiting\n");
+
+ driver_unregister(&mipsnet_driver);
+}
+
+module_init(mipsnet_init_module);
+module_exit(mipsnet_exit_module);
diff --git a/drivers/net/mipsnet.h b/drivers/net/mipsnet.h
new file mode 100644
index 000000000000..878535953cb1
--- /dev/null
+++ b/drivers/net/mipsnet.h
@@ -0,0 +1,127 @@
+//
+// <COPYRIGHT CLASS="1B" YEAR="2005">
+// Unpublished work (c) MIPS Technologies, Inc. All rights reserved.
+// Unpublished rights reserved under the copyright laws of the U.S.A. and
+// other countries.
+//
+// PROPRIETARY / SECRET CONFIDENTIAL INFORMATION OF MIPS TECHNOLOGIES, INC.
+// FOR INTERNAL USE ONLY.
+//
+// Under no circumstances (contract or otherwise) may this information be
+// disclosed to, or copied, modified or used by anyone other than employees
+// or contractors of MIPS Technologies having a need to know.
+// </COPYRIGHT>
+//
+//++
+// File: MIPS_Net.h
+//
+// Description:
+// The definition of the emulated MIPSNET device's interface.
+//
+// Notes: This include file needs to work from a Linux device drivers.
+//
+//--
+//
+
+#ifndef __MIPSNET_H
+#define __MIPSNET_H
+
+/*
+ * Id of this Net device, as seen by the core.
+ */
+#define MIPS_NET_DEV_ID ((uint64_t) \
+ ((uint64_t)'M'<< 0)| \
+ ((uint64_t)'I'<< 8)| \
+ ((uint64_t)'P'<<16)| \
+ ((uint64_t)'S'<<24)| \
+ ((uint64_t)'N'<<32)| \
+ ((uint64_t)'E'<<40)| \
+ ((uint64_t)'T'<<48)| \
+ ((uint64_t)'0'<<56))
+
+/*
+ * Net status/control block as seen by sw in the core.
+ * (Why not use bit fields? can't be bothered with cross-platform struct
+ * packing.)
+ */
+typedef struct _net_control_block {
+ /// dev info for probing
+ /// reads as MIPSNET%d where %d is some form of version
+ uint64_t devId; /*0x00 */
+
+ /*
+ * read only busy flag.
+ * Set and cleared by the Net Device to indicate that an rx or a tx
+ * is in progress.
+ */
+ uint32_t busy; /*0x08 */
+
+ /*
+ * Set by the Net Device.
+ * The device will set it once data has been received.
+ * The value is the number of bytes that should be read from
+ * rxDataBuffer. The value will decrease till 0 until all the data
+ * from rxDataBuffer has been read.
+ */
+ uint32_t rxDataCount; /*0x0c */
+#define MIPSNET_MAX_RXTX_DATACOUNT (1<<16)
+
+ /*
+ * Settable from the MIPS core, cleared by the Net Device.
+ * The core should set the number of bytes it wants to send,
+ * then it should write those bytes of data to txDataBuffer.
+ * The device will clear txDataCount has been processed (not necessarily sent).
+ */
+ uint32_t txDataCount; /*0x10 */
+
+ /*
+ * Interrupt control
+ *
+ * Used to clear the interrupted generated by this dev.
+ * Write a 1 to clear the interrupt. (except bit31).
+ *
+ * Bit0 is set if it was a tx-done interrupt.
+ * Bit1 is set when new rx-data is available.
+ * Until this bit is cleared there will be no other RXs.
+ *
+ * Bit31 is used for testing, it clears after a read.
+ * Writing 1 to this bit will cause an interrupt to be generated.
+ * To clear the test interrupt, write 0 to this register.
+ */
+ uint32_t interruptControl; /*0x14 */
+#define MIPSNET_INTCTL_TXDONE ((uint32_t)(1<< 0))
+#define MIPSNET_INTCTL_RXDONE ((uint32_t)(1<< 1))
+#define MIPSNET_INTCTL_TESTBIT ((uint32_t)(1<<31))
+#define MIPSNET_INTCTL_ALLSOURCES (MIPSNET_INTCTL_TXDONE|MIPSNET_INTCTL_RXDONE|MIPSNET_INTCTL_TESTBIT)
+
+ /*
+ * Readonly core-specific interrupt info for the device to signal the core.
+ * The meaning of the contents of this field might change.
+ */
+ /*###\todo: the whole memIntf interrupt scheme is messy: the device should have
+ * no control what so ever of what VPE/register set is being used.
+ * The MemIntf should only expose interrupt lines, and something in the
+ * config should be responsible for the line<->core/vpe bindings.
+ */
+ uint32_t interruptInfo; /*0x18 */
+
+ /*
+ * This is where the received data is read out.
+ * There is more data to read until rxDataReady is 0.
+ * Only 1 byte at this regs offset is used.
+ */
+ uint32_t rxDataBuffer; /*0x1c */
+
+ /*
+ * This is where the data to transmit is written.
+ * Data should be written for the amount specified in the txDataCount register.
+ * Only 1 byte at this regs offset is used.
+ */
+ uint32_t txDataBuffer; /*0x20 */
+} MIPS_T_NetControl;
+
+#define MIPSNET_IO_EXTENT 0x40 /* being generous */
+
+#define field_offset(field) ((int)&((MIPS_T_NetControl*)(0))->field)
+
+#endif /* __MIPSNET_H */
diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c
index 25c9a99c377b..71f2c6705bc3 100644
--- a/drivers/net/mv643xx_eth.c
+++ b/drivers/net/mv643xx_eth.c
@@ -39,6 +39,8 @@
#include <linux/bitops.h>
#include <linux/delay.h>
#include <linux/ethtool.h>
+#include <linux/platform_device.h>
+
#include <asm/io.h>
#include <asm/types.h>
#include <asm/pgtable.h>
@@ -1533,6 +1535,9 @@ static int mv643xx_eth_probe(struct device *ddev)
printk(KERN_NOTICE "%s: RX NAPI Enabled \n", dev->name);
#endif
+ if (mp->tx_sram_size > 0)
+ printk(KERN_NOTICE "%s: Using SRAM\n", dev->name);
+
return 0;
out:
diff --git a/drivers/net/mv643xx_eth.h b/drivers/net/mv643xx_eth.h
index bcfda5192da0..f769f9b626ea 100644
--- a/drivers/net/mv643xx_eth.h
+++ b/drivers/net/mv643xx_eth.h
@@ -1,7 +1,6 @@
#ifndef __MV643XX_ETH_H__
#define __MV643XX_ETH_H__
-#include <linux/version.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/spinlock.h>
diff --git a/drivers/net/myri_sbus.c b/drivers/net/myri_sbus.c
index f0996ce5c268..6c86dca62e2a 100644
--- a/drivers/net/myri_sbus.c
+++ b/drivers/net/myri_sbus.c
@@ -277,7 +277,7 @@ static void myri_init_rings(struct myri_eth *mp, int from_irq)
struct recvq __iomem *rq = mp->rq;
struct myri_rxd __iomem *rxd = &rq->myri_rxd[0];
struct net_device *dev = mp->dev;
- int gfp_flags = GFP_KERNEL;
+ gfp_t gfp_flags = GFP_KERNEL;
int i;
if (from_irq || in_interrupt())
diff --git a/drivers/net/myri_sbus.h b/drivers/net/myri_sbus.h
index 9391e55a5e92..47722f708a41 100644
--- a/drivers/net/myri_sbus.h
+++ b/drivers/net/myri_sbus.h
@@ -296,7 +296,7 @@ struct myri_eth {
/* We use this to acquire receive skb's that we can DMA directly into. */
#define ALIGNED_RX_SKB_ADDR(addr) \
((((unsigned long)(addr) + (64 - 1)) & ~(64 - 1)) - (unsigned long)(addr))
-static inline struct sk_buff *myri_alloc_skb(unsigned int length, int gfp_flags)
+static inline struct sk_buff *myri_alloc_skb(unsigned int length, gfp_t gfp_flags)
{
struct sk_buff *skb;
diff --git a/drivers/net/ne.c b/drivers/net/ne.c
index d209a1556b2e..0de8fdd2aa86 100644
--- a/drivers/net/ne.c
+++ b/drivers/net/ne.c
@@ -54,6 +54,10 @@ static const char version2[] =
#include <asm/system.h>
#include <asm/io.h>
+#if defined(CONFIG_TOSHIBA_RBTX4927) || defined(CONFIG_TOSHIBA_RBTX4938)
+#include <asm/tx4938/rbtx4938.h>
+#endif
+
#include "8390.h"
#define DRV_NAME "ne"
@@ -111,6 +115,9 @@ bad_clone_list[] __initdata = {
{"E-LAN100", "E-LAN200", {0x00, 0x00, 0x5d}}, /* Broken ne1000 clones */
{"PCM-4823", "PCM-4823", {0x00, 0xc0, 0x6c}}, /* Broken Advantech MoBo */
{"REALTEK", "RTL8019", {0x00, 0x00, 0xe8}}, /* no-name with Realtek chip */
+#if defined(CONFIG_TOSHIBA_RBTX4927) || defined(CONFIG_TOSHIBA_RBTX4938)
+ {"RBHMA4X00-RTL8019", "RBHMA4X00/RTL8019", {0x00, 0x60, 0x0a}}, /* Toshiba built-in */
+#endif
{"LCS-8834", "LCS-8836", {0x04, 0x04, 0x37}}, /* ShinyNet (SET) */
{NULL,}
};
@@ -226,6 +233,10 @@ struct net_device * __init ne_probe(int unit)
sprintf(dev->name, "eth%d", unit);
netdev_boot_setup_check(dev);
+#ifdef CONFIG_TOSHIBA_RBTX4938
+ dev->base_addr = 0x07f20280;
+ dev->irq = RBTX4938_RTL_8019_IRQ;
+#endif
err = do_ne_probe(dev);
if (err)
goto out;
@@ -506,6 +517,10 @@ static int __init ne_probe1(struct net_device *dev, int ioaddr)
ei_status.name = name;
ei_status.tx_start_page = start_page;
ei_status.stop_page = stop_page;
+#if defined(CONFIG_TOSHIBA_RBTX4927) || defined(CONFIG_TOSHIBA_RBTX4938)
+ wordlength = 1;
+#endif
+
#ifdef CONFIG_PLAT_OAKS32R
ei_status.word16 = 0;
#else
diff --git a/drivers/net/ne2k-pci.c b/drivers/net/ne2k-pci.c
index f1c01ac29102..d11821dd86ed 100644
--- a/drivers/net/ne2k-pci.c
+++ b/drivers/net/ne2k-pci.c
@@ -372,6 +372,7 @@ static int __devinit ne2k_pci_init_one (struct pci_dev *pdev,
printk("%2.2X%s", SA_prom[i], i == 5 ? ".\n": ":");
dev->dev_addr[i] = SA_prom[i];
}
+ memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
return 0;
@@ -637,6 +638,7 @@ static struct ethtool_ops ne2k_pci_ethtool_ops = {
.get_drvinfo = ne2k_pci_get_drvinfo,
.get_tx_csum = ethtool_op_get_tx_csum,
.get_sg = ethtool_op_get_sg,
+ .get_perm_addr = ethtool_op_get_perm_addr,
};
static void __devexit ne2k_pci_remove_one (struct pci_dev *pdev)
@@ -673,7 +675,6 @@ static int ne2k_pci_resume (struct pci_dev *pdev)
pci_set_power_state(pdev, 0);
pci_restore_state(pdev);
pci_enable_device(pdev);
- pci_set_master(pdev);
NS8390_init(dev, 1);
netif_device_attach(dev);
diff --git a/drivers/net/ni65.c b/drivers/net/ni65.c
index 925d1dfcc4dc..bb42ff218484 100644
--- a/drivers/net/ni65.c
+++ b/drivers/net/ni65.c
@@ -696,8 +696,7 @@ static void ni65_free_buffer(struct priv *p)
return;
for(i=0;i<TMDNUM;i++) {
- if(p->tmdbounce[i])
- kfree(p->tmdbounce[i]);
+ kfree(p->tmdbounce[i]);
#ifdef XMT_VIA_SKB
if(p->tmd_skb[i])
dev_kfree_skb(p->tmd_skb[i]);
@@ -710,12 +709,10 @@ static void ni65_free_buffer(struct priv *p)
if(p->recv_skb[i])
dev_kfree_skb(p->recv_skb[i]);
#else
- if(p->recvbounce[i])
- kfree(p->recvbounce[i]);
+ kfree(p->recvbounce[i]);
#endif
}
- if(p->self)
- kfree(p->self);
+ kfree(p->self);
}
diff --git a/drivers/net/ns83820.c b/drivers/net/ns83820.c
index e4811b42a6b7..f857ae94d261 100644
--- a/drivers/net/ns83820.c
+++ b/drivers/net/ns83820.c
@@ -110,7 +110,6 @@
#include <linux/init.h>
#include <linux/ip.h> /* for iph */
#include <linux/in.h> /* for IPPROTO_... */
-#include <linux/eeprom.h>
#include <linux/compiler.h>
#include <linux/prefetch.h>
#include <linux/ethtool.h>
@@ -445,7 +444,6 @@ struct ns83820 {
u32 MEAR_cache;
u32 IMR_cache;
- struct eeprom ee;
unsigned linkstate;
@@ -1558,15 +1556,13 @@ static void ns83820_getmac(struct ns83820 *dev, u8 *mac)
unsigned i;
for (i=0; i<3; i++) {
u32 data;
-#if 0 /* I've left this in as an example of how to use eeprom.h */
- data = eeprom_readw(&dev->ee, 0xa + 2 - i);
-#else
+
/* Read from the perfect match memory: this is loaded by
* the chip from the EEPROM via the EELOAD self test.
*/
writel(i*2, dev->base + RFCR);
data = readl(dev->base + RFDR);
-#endif
+
*mac++ = data;
*mac++ = data >> 8;
}
@@ -1632,8 +1628,7 @@ static void ns83820_run_bist(struct net_device *ndev, const char *name, u32 enab
timed_out = 1;
break;
}
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(1);
+ schedule_timeout_uninterruptible(1);
}
if (status & fail)
@@ -1852,8 +1847,6 @@ static int __devinit ns83820_init_one(struct pci_dev *pci_dev, const struct pci_
spin_lock_init(&dev->misc_lock);
dev->pci_dev = pci_dev;
- dev->ee.cache = &dev->MEAR_cache;
- dev->ee.lock = &dev->misc_lock;
SET_MODULE_OWNER(ndev);
SET_NETDEV_DEV(ndev, &pci_dev->dev);
@@ -1888,9 +1881,6 @@ static int __devinit ns83820_init_one(struct pci_dev *pci_dev, const struct pci_
dev->IMR_cache = 0;
- setup_ee_mem_bitbanger(&dev->ee, dev->base + MEAR, 3, 2, 1, 0,
- 0);
-
err = request_irq(pci_dev->irq, ns83820_irq, SA_SHIRQ,
DRV_NAME, ndev);
if (err) {
diff --git a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c
index 9f22d138e3ad..818c185d6438 100644
--- a/drivers/net/pcmcia/pcnet_cs.c
+++ b/drivers/net/pcmcia/pcnet_cs.c
@@ -1020,6 +1020,12 @@ static void set_misc_reg(struct net_device *dev)
} else {
outb(full_duplex ? 4 : 0, nic_base + DLINK_DIAG);
}
+ } else if (info->flags & IS_DL10019) {
+ /* Advertise 100F, 100H, 10F, 10H */
+ mdio_write(nic_base + DLINK_GPIO, info->eth_phy, 4, 0x01e1);
+ /* Restart MII autonegotiation */
+ mdio_write(nic_base + DLINK_GPIO, info->eth_phy, 0, 0x0000);
+ mdio_write(nic_base + DLINK_GPIO, info->eth_phy, 0, 0x1200);
}
}
diff --git a/drivers/net/pcnet32.c b/drivers/net/pcnet32.c
index 113b68099216..be319229f543 100644
--- a/drivers/net/pcnet32.c
+++ b/drivers/net/pcnet32.c
@@ -22,8 +22,8 @@
*************************************************************************/
#define DRV_NAME "pcnet32"
-#define DRV_VERSION "1.30j"
-#define DRV_RELDATE "29.04.2005"
+#define DRV_VERSION "1.31c"
+#define DRV_RELDATE "01.Nov.2005"
#define PFX DRV_NAME ": "
static const char *version =
@@ -257,6 +257,14 @@ static int homepna[MAX_UNITS];
* v1.30h 24 Jun 2004 Don Fry correctly select auto, speed, duplex in bcr32.
* v1.30i 28 Jun 2004 Don Fry change to use module_param.
* v1.30j 29 Apr 2005 Don Fry fix skb/map leak with loopback test.
+ * v1.31 02 Sep 2005 Hubert WS Lin <wslin@tw.ibm.c0m> added set_ringparam().
+ * v1.31a 12 Sep 2005 Hubert WS Lin <wslin@tw.ibm.c0m> set min ring size to 4
+ * to allow loopback test to work unchanged.
+ * v1.31b 06 Oct 2005 Don Fry changed alloc_ring to show name of device
+ * if allocation fails
+ * v1.31c 01 Nov 2005 Don Fry Allied Telesyn 2700/2701 FX are 100Mbit only.
+ * Force 100Mbit FD if Auto (ASEL) is selected.
+ * See Bugzilla 2669 and 4551.
*/
@@ -266,17 +274,17 @@ static int homepna[MAX_UNITS];
* That translates to 2 (4 == 2^^2) and 4 (16 == 2^^4).
*/
#ifndef PCNET32_LOG_TX_BUFFERS
-#define PCNET32_LOG_TX_BUFFERS 4
-#define PCNET32_LOG_RX_BUFFERS 5
+#define PCNET32_LOG_TX_BUFFERS 4
+#define PCNET32_LOG_RX_BUFFERS 5
+#define PCNET32_LOG_MAX_TX_BUFFERS 9 /* 2^9 == 512 */
+#define PCNET32_LOG_MAX_RX_BUFFERS 9
#endif
#define TX_RING_SIZE (1 << (PCNET32_LOG_TX_BUFFERS))
-#define TX_RING_MOD_MASK (TX_RING_SIZE - 1)
-#define TX_RING_LEN_BITS ((PCNET32_LOG_TX_BUFFERS) << 12)
+#define TX_MAX_RING_SIZE (1 << (PCNET32_LOG_MAX_TX_BUFFERS))
#define RX_RING_SIZE (1 << (PCNET32_LOG_RX_BUFFERS))
-#define RX_RING_MOD_MASK (RX_RING_SIZE - 1)
-#define RX_RING_LEN_BITS ((PCNET32_LOG_RX_BUFFERS) << 4)
+#define RX_MAX_RING_SIZE (1 << (PCNET32_LOG_MAX_RX_BUFFERS))
#define PKT_BUF_SZ 1544
@@ -334,14 +342,14 @@ struct pcnet32_access {
};
/*
- * The first three fields of pcnet32_private are read by the ethernet device
- * so we allocate the structure should be allocated by pci_alloc_consistent().
+ * The first field of pcnet32_private is read by the ethernet device
+ * so the structure should be allocated using pci_alloc_consistent().
*/
struct pcnet32_private {
- /* The Tx and Rx ring entries must be aligned on 16-byte boundaries in 32bit mode. */
- struct pcnet32_rx_head rx_ring[RX_RING_SIZE];
- struct pcnet32_tx_head tx_ring[TX_RING_SIZE];
struct pcnet32_init_block init_block;
+ /* The Tx and Rx ring entries must be aligned on 16-byte boundaries in 32bit mode. */
+ struct pcnet32_rx_head *rx_ring;
+ struct pcnet32_tx_head *tx_ring;
dma_addr_t dma_addr; /* DMA address of beginning of this
object, returned by
pci_alloc_consistent */
@@ -349,13 +357,21 @@ struct pcnet32_private {
structure */
const char *name;
/* The saved address of a sent-in-place packet/buffer, for skfree(). */
- struct sk_buff *tx_skbuff[TX_RING_SIZE];
- struct sk_buff *rx_skbuff[RX_RING_SIZE];
- dma_addr_t tx_dma_addr[TX_RING_SIZE];
- dma_addr_t rx_dma_addr[RX_RING_SIZE];
+ struct sk_buff **tx_skbuff;
+ struct sk_buff **rx_skbuff;
+ dma_addr_t *tx_dma_addr;
+ dma_addr_t *rx_dma_addr;
struct pcnet32_access a;
spinlock_t lock; /* Guard lock */
unsigned int cur_rx, cur_tx; /* The next free ring entry */
+ unsigned int rx_ring_size; /* current rx ring size */
+ unsigned int tx_ring_size; /* current tx ring size */
+ unsigned int rx_mod_mask; /* rx ring modular mask */
+ unsigned int tx_mod_mask; /* tx ring modular mask */
+ unsigned short rx_len_bits;
+ unsigned short tx_len_bits;
+ dma_addr_t rx_ring_dma_addr;
+ dma_addr_t tx_ring_dma_addr;
unsigned int dirty_rx, dirty_tx; /* The ring entries to be free()ed. */
struct net_device_stats stats;
char tx_full;
@@ -397,6 +413,9 @@ static int pcnet32_get_regs_len(struct net_device *dev);
static void pcnet32_get_regs(struct net_device *dev, struct ethtool_regs *regs,
void *ptr);
static void pcnet32_purge_tx_ring(struct net_device *dev);
+static int pcnet32_alloc_ring(struct net_device *dev, char *name);
+static void pcnet32_free_ring(struct net_device *dev);
+
enum pci_flags_bit {
PCI_USES_IO=1, PCI_USES_MEM=2, PCI_USES_MASTER=4,
@@ -613,10 +632,64 @@ static void pcnet32_get_ringparam(struct net_device *dev, struct ethtool_ringpar
{
struct pcnet32_private *lp = dev->priv;
- ering->tx_max_pending = TX_RING_SIZE - 1;
- ering->tx_pending = lp->cur_tx - lp->dirty_tx;
- ering->rx_max_pending = RX_RING_SIZE - 1;
- ering->rx_pending = lp->cur_rx & RX_RING_MOD_MASK;
+ ering->tx_max_pending = TX_MAX_RING_SIZE - 1;
+ ering->tx_pending = lp->tx_ring_size - 1;
+ ering->rx_max_pending = RX_MAX_RING_SIZE - 1;
+ ering->rx_pending = lp->rx_ring_size - 1;
+}
+
+static int pcnet32_set_ringparam(struct net_device *dev, struct ethtool_ringparam *ering)
+{
+ struct pcnet32_private *lp = dev->priv;
+ unsigned long flags;
+ int i;
+
+ if (ering->rx_mini_pending || ering->rx_jumbo_pending)
+ return -EINVAL;
+
+ if (netif_running(dev))
+ pcnet32_close(dev);
+
+ spin_lock_irqsave(&lp->lock, flags);
+ pcnet32_free_ring(dev);
+ lp->tx_ring_size = min(ering->tx_pending, (unsigned int) TX_MAX_RING_SIZE);
+ lp->rx_ring_size = min(ering->rx_pending, (unsigned int) RX_MAX_RING_SIZE);
+
+ /* set the minimum ring size to 4, to allow the loopback test to work
+ * unchanged.
+ */
+ for (i = 2; i <= PCNET32_LOG_MAX_TX_BUFFERS; i++) {
+ if (lp->tx_ring_size <= (1 << i))
+ break;
+ }
+ lp->tx_ring_size = (1 << i);
+ lp->tx_mod_mask = lp->tx_ring_size - 1;
+ lp->tx_len_bits = (i << 12);
+
+ for (i = 2; i <= PCNET32_LOG_MAX_RX_BUFFERS; i++) {
+ if (lp->rx_ring_size <= (1 << i))
+ break;
+ }
+ lp->rx_ring_size = (1 << i);
+ lp->rx_mod_mask = lp->rx_ring_size - 1;
+ lp->rx_len_bits = (i << 4);
+
+ if (pcnet32_alloc_ring(dev, dev->name)) {
+ pcnet32_free_ring(dev);
+ spin_unlock_irqrestore(&lp->lock, flags);
+ return -ENOMEM;
+ }
+
+ spin_unlock_irqrestore(&lp->lock, flags);
+
+ if (pcnet32_debug & NETIF_MSG_DRV)
+ printk(KERN_INFO PFX "%s: Ring Param Settings: RX: %d, TX: %d\n",
+ dev->name, lp->rx_ring_size, lp->tx_ring_size);
+
+ if (netif_running(dev))
+ pcnet32_open(dev);
+
+ return 0;
}
static void pcnet32_get_strings(struct net_device *dev, u32 stringset, u8 *data)
@@ -915,7 +988,11 @@ static void pcnet32_get_regs(struct net_device *dev, struct ethtool_regs *regs,
*buff++ = a->read_csr(ioaddr, 114);
/* read bus configuration registers */
- for (i=0; i<36; i++) {
+ for (i=0; i<30; i++) {
+ *buff++ = a->read_bcr(ioaddr, i);
+ }
+ *buff++ = 0; /* skip bcr30 so as not to hang 79C976 */
+ for (i=31; i<36; i++) {
*buff++ = a->read_bcr(ioaddr, i);
}
@@ -948,6 +1025,7 @@ static struct ethtool_ops pcnet32_ethtool_ops = {
.nway_reset = pcnet32_nway_reset,
.get_link = pcnet32_get_link,
.get_ringparam = pcnet32_get_ringparam,
+ .set_ringparam = pcnet32_set_ringparam,
.get_tx_csum = ethtool_op_get_tx_csum,
.get_sg = ethtool_op_get_sg,
.get_tso = ethtool_op_get_tso,
@@ -957,6 +1035,7 @@ static struct ethtool_ops pcnet32_ethtool_ops = {
.phys_id = pcnet32_phys_id,
.get_regs_len = pcnet32_get_regs_len,
.get_regs = pcnet32_get_regs,
+ .get_perm_addr = ethtool_op_get_perm_addr,
};
/* only probes for non-PCI devices, the rest are handled by
@@ -1185,9 +1264,10 @@ pcnet32_probe1(unsigned long ioaddr, int shared, struct pci_dev *pdev)
memcpy(dev->dev_addr, promaddr, 6);
}
}
+ memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
/* if the ethernet address is not valid, force to 00:00:00:00:00:00 */
- if (!is_valid_ether_addr(dev->dev_addr))
+ if (!is_valid_ether_addr(dev->perm_addr))
memset(dev->dev_addr, 0, sizeof(dev->dev_addr));
if (pcnet32_debug & NETIF_MSG_PROBE) {
@@ -1239,6 +1319,12 @@ pcnet32_probe1(unsigned long ioaddr, int shared, struct pci_dev *pdev)
dev->priv = lp;
lp->name = chipname;
lp->shared_irq = shared;
+ lp->tx_ring_size = TX_RING_SIZE; /* default tx ring size */
+ lp->rx_ring_size = RX_RING_SIZE; /* default rx ring size */
+ lp->tx_mod_mask = lp->tx_ring_size - 1;
+ lp->rx_mod_mask = lp->rx_ring_size - 1;
+ lp->tx_len_bits = (PCNET32_LOG_TX_BUFFERS << 12);
+ lp->rx_len_bits = (PCNET32_LOG_RX_BUFFERS << 4);
lp->mii_if.full_duplex = fdx;
lp->mii_if.phy_id_mask = 0x1f;
lp->mii_if.reg_num_mask = 0x1f;
@@ -1265,21 +1351,24 @@ pcnet32_probe1(unsigned long ioaddr, int shared, struct pci_dev *pdev)
}
lp->a = *a;
+ /* prior to register_netdev, dev->name is not yet correct */
+ if (pcnet32_alloc_ring(dev, pci_name(lp->pci_dev))) {
+ ret = -ENOMEM;
+ goto err_free_ring;
+ }
/* detect special T1/E1 WAN card by checking for MAC address */
if (dev->dev_addr[0] == 0x00 && dev->dev_addr[1] == 0xe0
&& dev->dev_addr[2] == 0x75)
lp->options = PCNET32_PORT_FD | PCNET32_PORT_GPSI;
lp->init_block.mode = le16_to_cpu(0x0003); /* Disable Rx and Tx. */
- lp->init_block.tlen_rlen = le16_to_cpu(TX_RING_LEN_BITS | RX_RING_LEN_BITS);
+ lp->init_block.tlen_rlen = le16_to_cpu(lp->tx_len_bits | lp->rx_len_bits);
for (i = 0; i < 6; i++)
lp->init_block.phys_addr[i] = dev->dev_addr[i];
lp->init_block.filter[0] = 0x00000000;
lp->init_block.filter[1] = 0x00000000;
- lp->init_block.rx_ring = (u32)le32_to_cpu(lp->dma_addr +
- offsetof(struct pcnet32_private, rx_ring));
- lp->init_block.tx_ring = (u32)le32_to_cpu(lp->dma_addr +
- offsetof(struct pcnet32_private, tx_ring));
+ lp->init_block.rx_ring = (u32)le32_to_cpu(lp->rx_ring_dma_addr);
+ lp->init_block.tx_ring = (u32)le32_to_cpu(lp->tx_ring_dma_addr);
/* switch pcnet32 to 32bit mode */
a->write_bcr(ioaddr, 20, 2);
@@ -1310,7 +1399,7 @@ pcnet32_probe1(unsigned long ioaddr, int shared, struct pci_dev *pdev)
if (pcnet32_debug & NETIF_MSG_PROBE)
printk(", failed to detect IRQ line.\n");
ret = -ENODEV;
- goto err_free_consistent;
+ goto err_free_ring;
}
if (pcnet32_debug & NETIF_MSG_PROBE)
printk(", probed IRQ %d.\n", dev->irq);
@@ -1341,7 +1430,7 @@ pcnet32_probe1(unsigned long ioaddr, int shared, struct pci_dev *pdev)
/* Fill in the generic fields of the device structure. */
if (register_netdev(dev))
- goto err_free_consistent;
+ goto err_free_ring;
if (pdev) {
pci_set_drvdata(pdev, dev);
@@ -1359,6 +1448,8 @@ pcnet32_probe1(unsigned long ioaddr, int shared, struct pci_dev *pdev)
return 0;
+err_free_ring:
+ pcnet32_free_ring(dev);
err_free_consistent:
pci_free_consistent(lp->pci_dev, sizeof(*lp), lp, lp->dma_addr);
err_free_netdev:
@@ -1369,6 +1460,101 @@ err_release_region:
}
+/* if any allocation fails, caller must also call pcnet32_free_ring */
+static int pcnet32_alloc_ring(struct net_device *dev, char *name)
+{
+ struct pcnet32_private *lp = dev->priv;
+
+ lp->tx_ring = pci_alloc_consistent(lp->pci_dev,
+ sizeof(struct pcnet32_tx_head) * lp->tx_ring_size,
+ &lp->tx_ring_dma_addr);
+ if (lp->tx_ring == NULL) {
+ if (pcnet32_debug & NETIF_MSG_DRV)
+ printk("\n" KERN_ERR PFX "%s: Consistent memory allocation failed.\n",
+ name);
+ return -ENOMEM;
+ }
+
+ lp->rx_ring = pci_alloc_consistent(lp->pci_dev,
+ sizeof(struct pcnet32_rx_head) * lp->rx_ring_size,
+ &lp->rx_ring_dma_addr);
+ if (lp->rx_ring == NULL) {
+ if (pcnet32_debug & NETIF_MSG_DRV)
+ printk("\n" KERN_ERR PFX "%s: Consistent memory allocation failed.\n",
+ name);
+ return -ENOMEM;
+ }
+
+ lp->tx_dma_addr = kmalloc(sizeof(dma_addr_t) * lp->tx_ring_size,
+ GFP_ATOMIC);
+ if (!lp->tx_dma_addr) {
+ if (pcnet32_debug & NETIF_MSG_DRV)
+ printk("\n" KERN_ERR PFX "%s: Memory allocation failed.\n", name);
+ return -ENOMEM;
+ }
+ memset(lp->tx_dma_addr, 0, sizeof(dma_addr_t) * lp->tx_ring_size);
+
+ lp->rx_dma_addr = kmalloc(sizeof(dma_addr_t) * lp->rx_ring_size,
+ GFP_ATOMIC);
+ if (!lp->rx_dma_addr) {
+ if (pcnet32_debug & NETIF_MSG_DRV)
+ printk("\n" KERN_ERR PFX "%s: Memory allocation failed.\n", name);
+ return -ENOMEM;
+ }
+ memset(lp->rx_dma_addr, 0, sizeof(dma_addr_t) * lp->rx_ring_size);
+
+ lp->tx_skbuff = kmalloc(sizeof(struct sk_buff *) * lp->tx_ring_size,
+ GFP_ATOMIC);
+ if (!lp->tx_skbuff) {
+ if (pcnet32_debug & NETIF_MSG_DRV)
+ printk("\n" KERN_ERR PFX "%s: Memory allocation failed.\n", name);
+ return -ENOMEM;
+ }
+ memset(lp->tx_skbuff, 0, sizeof(struct sk_buff *) * lp->tx_ring_size);
+
+ lp->rx_skbuff = kmalloc(sizeof(struct sk_buff *) * lp->rx_ring_size,
+ GFP_ATOMIC);
+ if (!lp->rx_skbuff) {
+ if (pcnet32_debug & NETIF_MSG_DRV)
+ printk("\n" KERN_ERR PFX "%s: Memory allocation failed.\n", name);
+ return -ENOMEM;
+ }
+ memset(lp->rx_skbuff, 0, sizeof(struct sk_buff *) * lp->rx_ring_size);
+
+ return 0;
+}
+
+
+static void pcnet32_free_ring(struct net_device *dev)
+{
+ struct pcnet32_private *lp = dev->priv;
+
+ kfree(lp->tx_skbuff);
+ lp->tx_skbuff = NULL;
+
+ kfree(lp->rx_skbuff);
+ lp->rx_skbuff = NULL;
+
+ kfree(lp->tx_dma_addr);
+ lp->tx_dma_addr = NULL;
+
+ kfree(lp->rx_dma_addr);
+ lp->rx_dma_addr = NULL;
+
+ if (lp->tx_ring) {
+ pci_free_consistent(lp->pci_dev, sizeof(struct pcnet32_tx_head) * lp->tx_ring_size,
+ lp->tx_ring, lp->tx_ring_dma_addr);
+ lp->tx_ring = NULL;
+ }
+
+ if (lp->rx_ring) {
+ pci_free_consistent(lp->pci_dev, sizeof(struct pcnet32_rx_head) * lp->rx_ring_size,
+ lp->rx_ring, lp->rx_ring_dma_addr);
+ lp->rx_ring = NULL;
+ }
+}
+
+
static int
pcnet32_open(struct net_device *dev)
{
@@ -1400,8 +1586,8 @@ pcnet32_open(struct net_device *dev)
if (netif_msg_ifup(lp))
printk(KERN_DEBUG "%s: pcnet32_open() irq %d tx/rx rings %#x/%#x init %#x.\n",
dev->name, dev->irq,
- (u32) (lp->dma_addr + offsetof(struct pcnet32_private, tx_ring)),
- (u32) (lp->dma_addr + offsetof(struct pcnet32_private, rx_ring)),
+ (u32) (lp->tx_ring_dma_addr),
+ (u32) (lp->rx_ring_dma_addr),
(u32) (lp->dma_addr + offsetof(struct pcnet32_private, init_block)));
/* set/reset autoselect bit */
@@ -1433,12 +1619,18 @@ pcnet32_open(struct net_device *dev)
val |= 0x10;
lp->a.write_csr (ioaddr, 124, val);
- /* Allied Telesyn AT 2700/2701 FX looses the link, so skip that */
+ /* Allied Telesyn AT 2700/2701 FX are 100Mbit only and do not negotiate */
if (lp->pci_dev->subsystem_vendor == PCI_VENDOR_ID_AT &&
- (lp->pci_dev->subsystem_device == PCI_SUBDEVICE_ID_AT_2700FX ||
- lp->pci_dev->subsystem_device == PCI_SUBDEVICE_ID_AT_2701FX)) {
- printk(KERN_DEBUG "%s: Skipping PHY selection.\n", dev->name);
- } else {
+ (lp->pci_dev->subsystem_device == PCI_SUBDEVICE_ID_AT_2700FX ||
+ lp->pci_dev->subsystem_device == PCI_SUBDEVICE_ID_AT_2701FX)) {
+ if (lp->options & PCNET32_PORT_ASEL) {
+ lp->options = PCNET32_PORT_FD | PCNET32_PORT_100;
+ if (netif_msg_link(lp))
+ printk(KERN_DEBUG "%s: Setting 100Mb-Full Duplex.\n",
+ dev->name);
+ }
+ }
+ {
/*
* 24 Jun 2004 according AMD, in order to change the PHY,
* DANAS (or DISPM for 79C976) must be set; then select the speed,
@@ -1521,7 +1713,7 @@ pcnet32_open(struct net_device *dev)
err_free_ring:
/* free any allocated skbuffs */
- for (i = 0; i < RX_RING_SIZE; i++) {
+ for (i = 0; i < lp->rx_ring_size; i++) {
lp->rx_ring[i].status = 0;
if (lp->rx_skbuff[i]) {
pci_unmap_single(lp->pci_dev, lp->rx_dma_addr[i], PKT_BUF_SZ-2,
@@ -1531,6 +1723,9 @@ err_free_ring:
lp->rx_skbuff[i] = NULL;
lp->rx_dma_addr[i] = 0;
}
+
+ pcnet32_free_ring(dev);
+
/*
* Switch back to 16bit mode to avoid problems with dumb
* DOS packet driver after a warm reboot
@@ -1562,7 +1757,7 @@ pcnet32_purge_tx_ring(struct net_device *dev)
struct pcnet32_private *lp = dev->priv;
int i;
- for (i = 0; i < TX_RING_SIZE; i++) {
+ for (i = 0; i < lp->tx_ring_size; i++) {
lp->tx_ring[i].status = 0; /* CPU owns buffer */
wmb(); /* Make sure adapter sees owner change */
if (lp->tx_skbuff[i]) {
@@ -1587,7 +1782,7 @@ pcnet32_init_ring(struct net_device *dev)
lp->cur_rx = lp->cur_tx = 0;
lp->dirty_rx = lp->dirty_tx = 0;
- for (i = 0; i < RX_RING_SIZE; i++) {
+ for (i = 0; i < lp->rx_ring_size; i++) {
struct sk_buff *rx_skbuff = lp->rx_skbuff[i];
if (rx_skbuff == NULL) {
if (!(rx_skbuff = lp->rx_skbuff[i] = dev_alloc_skb (PKT_BUF_SZ))) {
@@ -1611,20 +1806,18 @@ pcnet32_init_ring(struct net_device *dev)
}
/* The Tx buffer address is filled in as needed, but we do need to clear
* the upper ownership bit. */
- for (i = 0; i < TX_RING_SIZE; i++) {
+ for (i = 0; i < lp->tx_ring_size; i++) {
lp->tx_ring[i].status = 0; /* CPU owns buffer */
wmb(); /* Make sure adapter sees owner change */
lp->tx_ring[i].base = 0;
lp->tx_dma_addr[i] = 0;
}
- lp->init_block.tlen_rlen = le16_to_cpu(TX_RING_LEN_BITS | RX_RING_LEN_BITS);
+ lp->init_block.tlen_rlen = le16_to_cpu(lp->tx_len_bits | lp->rx_len_bits);
for (i = 0; i < 6; i++)
lp->init_block.phys_addr[i] = dev->dev_addr[i];
- lp->init_block.rx_ring = (u32)le32_to_cpu(lp->dma_addr +
- offsetof(struct pcnet32_private, rx_ring));
- lp->init_block.tx_ring = (u32)le32_to_cpu(lp->dma_addr +
- offsetof(struct pcnet32_private, tx_ring));
+ lp->init_block.rx_ring = (u32)le32_to_cpu(lp->rx_ring_dma_addr);
+ lp->init_block.tx_ring = (u32)le32_to_cpu(lp->tx_ring_dma_addr);
wmb(); /* Make sure all changes are visible */
return 0;
}
@@ -1682,13 +1875,13 @@ pcnet32_tx_timeout (struct net_device *dev)
printk(KERN_DEBUG " Ring data dump: dirty_tx %d cur_tx %d%s cur_rx %d.",
lp->dirty_tx, lp->cur_tx, lp->tx_full ? " (full)" : "",
lp->cur_rx);
- for (i = 0 ; i < RX_RING_SIZE; i++)
+ for (i = 0 ; i < lp->rx_ring_size; i++)
printk("%s %08x %04x %08x %04x", i & 1 ? "" : "\n ",
le32_to_cpu(lp->rx_ring[i].base),
(-le16_to_cpu(lp->rx_ring[i].buf_length)) & 0xffff,
le32_to_cpu(lp->rx_ring[i].msg_length),
le16_to_cpu(lp->rx_ring[i].status));
- for (i = 0 ; i < TX_RING_SIZE; i++)
+ for (i = 0 ; i < lp->tx_ring_size; i++)
printk("%s %08x %04x %08x %04x", i & 1 ? "" : "\n ",
le32_to_cpu(lp->tx_ring[i].base),
(-le16_to_cpu(lp->tx_ring[i].length)) & 0xffff,
@@ -1729,7 +1922,7 @@ pcnet32_start_xmit(struct sk_buff *skb, struct net_device *dev)
/* Fill in a Tx ring entry */
/* Mask to ring buffer boundary. */
- entry = lp->cur_tx & TX_RING_MOD_MASK;
+ entry = lp->cur_tx & lp->tx_mod_mask;
/* Caution: the write order is important here, set the status
* with the "ownership" bits last. */
@@ -1753,7 +1946,7 @@ pcnet32_start_xmit(struct sk_buff *skb, struct net_device *dev)
dev->trans_start = jiffies;
- if (lp->tx_ring[(entry+1) & TX_RING_MOD_MASK].base != 0) {
+ if (lp->tx_ring[(entry+1) & lp->tx_mod_mask].base != 0) {
lp->tx_full = 1;
netif_stop_queue(dev);
}
@@ -1806,7 +1999,7 @@ pcnet32_interrupt(int irq, void *dev_id, struct pt_regs * regs)
int delta;
while (dirty_tx != lp->cur_tx) {
- int entry = dirty_tx & TX_RING_MOD_MASK;
+ int entry = dirty_tx & lp->tx_mod_mask;
int status = (short)le16_to_cpu(lp->tx_ring[entry].status);
if (status < 0)
@@ -1864,18 +2057,18 @@ pcnet32_interrupt(int irq, void *dev_id, struct pt_regs * regs)
dirty_tx++;
}
- delta = (lp->cur_tx - dirty_tx) & (TX_RING_MOD_MASK + TX_RING_SIZE);
- if (delta > TX_RING_SIZE) {
+ delta = (lp->cur_tx - dirty_tx) & (lp->tx_mod_mask + lp->tx_ring_size);
+ if (delta > lp->tx_ring_size) {
if (netif_msg_drv(lp))
printk(KERN_ERR "%s: out-of-sync dirty pointer, %d vs. %d, full=%d.\n",
dev->name, dirty_tx, lp->cur_tx, lp->tx_full);
- dirty_tx += TX_RING_SIZE;
- delta -= TX_RING_SIZE;
+ dirty_tx += lp->tx_ring_size;
+ delta -= lp->tx_ring_size;
}
if (lp->tx_full &&
netif_queue_stopped(dev) &&
- delta < TX_RING_SIZE - 2) {
+ delta < lp->tx_ring_size - 2) {
/* The ring is no longer full, clear tbusy. */
lp->tx_full = 0;
netif_wake_queue (dev);
@@ -1932,8 +2125,8 @@ static int
pcnet32_rx(struct net_device *dev)
{
struct pcnet32_private *lp = dev->priv;
- int entry = lp->cur_rx & RX_RING_MOD_MASK;
- int boguscnt = RX_RING_SIZE / 2;
+ int entry = lp->cur_rx & lp->rx_mod_mask;
+ int boguscnt = lp->rx_ring_size / 2;
/* If we own the next entry, it's a new packet. Send it up. */
while ((short)le16_to_cpu(lp->rx_ring[entry].status) >= 0) {
@@ -1998,12 +2191,12 @@ pcnet32_rx(struct net_device *dev)
if (netif_msg_drv(lp))
printk(KERN_ERR "%s: Memory squeeze, deferring packet.\n",
dev->name);
- for (i = 0; i < RX_RING_SIZE; i++)
+ for (i = 0; i < lp->rx_ring_size; i++)
if ((short)le16_to_cpu(lp->rx_ring[(entry+i)
- & RX_RING_MOD_MASK].status) < 0)
+ & lp->rx_mod_mask].status) < 0)
break;
- if (i > RX_RING_SIZE -2) {
+ if (i > lp->rx_ring_size -2) {
lp->stats.rx_dropped++;
lp->rx_ring[entry].status |= le16_to_cpu(0x8000);
wmb(); /* Make sure adapter sees owner change */
@@ -2041,7 +2234,7 @@ pcnet32_rx(struct net_device *dev)
lp->rx_ring[entry].buf_length = le16_to_cpu(2-PKT_BUF_SZ);
wmb(); /* Make sure owner changes after all others are visible */
lp->rx_ring[entry].status |= le16_to_cpu(0x8000);
- entry = (++lp->cur_rx) & RX_RING_MOD_MASK;
+ entry = (++lp->cur_rx) & lp->rx_mod_mask;
if (--boguscnt <= 0) break; /* don't stay in loop forever */
}
@@ -2084,7 +2277,7 @@ pcnet32_close(struct net_device *dev)
spin_lock_irqsave(&lp->lock, flags);
/* free all allocated skbuffs */
- for (i = 0; i < RX_RING_SIZE; i++) {
+ for (i = 0; i < lp->rx_ring_size; i++) {
lp->rx_ring[i].status = 0;
wmb(); /* Make sure adapter sees owner change */
if (lp->rx_skbuff[i]) {
@@ -2096,7 +2289,7 @@ pcnet32_close(struct net_device *dev)
lp->rx_dma_addr[i] = 0;
}
- for (i = 0; i < TX_RING_SIZE; i++) {
+ for (i = 0; i < lp->tx_ring_size; i++) {
lp->tx_ring[i].status = 0; /* CPU owns buffer */
wmb(); /* Make sure adapter sees owner change */
if (lp->tx_skbuff[i]) {
@@ -2265,6 +2458,7 @@ static void __devexit pcnet32_remove_one(struct pci_dev *pdev)
struct pcnet32_private *lp = dev->priv;
unregister_netdev(dev);
+ pcnet32_free_ring(dev);
release_region(dev->base_addr, PCNET32_TOTAL_SIZE);
pci_free_consistent(lp->pci_dev, sizeof(*lp), lp, lp->dma_addr);
free_netdev(dev);
@@ -2340,6 +2534,7 @@ static void __exit pcnet32_cleanup_module(void)
struct pcnet32_private *lp = pcnet32_dev->priv;
next_dev = lp->next;
unregister_netdev(pcnet32_dev);
+ pcnet32_free_ring(pcnet32_dev);
release_region(pcnet32_dev->base_addr, PCNET32_TOTAL_SIZE);
pci_free_consistent(lp->pci_dev, sizeof(*lp), lp, lp->dma_addr);
free_netdev(pcnet32_dev);
diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
index 14f4de1a8180..c782a6329805 100644
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -12,14 +12,6 @@ config PHYLIB
devices. This option provides infrastructure for
managing PHY devices.
-config PHYCONTROL
- bool " Support for automatically handling PHY state changes"
- depends on PHYLIB
- help
- Adds code to perform all the work for keeping PHY link
- state (speed/duplex/etc) up-to-date. Also handles
- interrupts.
-
comment "MII PHY device drivers"
depends on PHYLIB
diff --git a/drivers/net/phy/cicada.c b/drivers/net/phy/cicada.c
index c47fb2ecd147..7d8d534255c0 100644
--- a/drivers/net/phy/cicada.c
+++ b/drivers/net/phy/cicada.c
@@ -29,7 +29,6 @@
#include <linux/spinlock.h>
#include <linux/mm.h>
#include <linux/module.h>
-#include <linux/version.h>
#include <linux/mii.h>
#include <linux/ethtool.h>
#include <linux/phy.h>
diff --git a/drivers/net/phy/davicom.c b/drivers/net/phy/davicom.c
index 6caf499fae32..5e9002e444c5 100644
--- a/drivers/net/phy/davicom.c
+++ b/drivers/net/phy/davicom.c
@@ -29,7 +29,6 @@
#include <linux/spinlock.h>
#include <linux/mm.h>
#include <linux/module.h>
-#include <linux/version.h>
#include <linux/mii.h>
#include <linux/ethtool.h>
#include <linux/phy.h>
diff --git a/drivers/net/phy/lxt.c b/drivers/net/phy/lxt.c
index 4c840448ec86..bef79e454c33 100644
--- a/drivers/net/phy/lxt.c
+++ b/drivers/net/phy/lxt.c
@@ -29,7 +29,6 @@
#include <linux/spinlock.h>
#include <linux/mm.h>
#include <linux/module.h>
-#include <linux/version.h>
#include <linux/mii.h>
#include <linux/ethtool.h>
#include <linux/phy.h>
diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c
index 4a72b025006b..a2d6386d13bc 100644
--- a/drivers/net/phy/marvell.c
+++ b/drivers/net/phy/marvell.c
@@ -29,7 +29,6 @@
#include <linux/spinlock.h>
#include <linux/mm.h>
#include <linux/module.h>
-#include <linux/version.h>
#include <linux/mii.h>
#include <linux/ethtool.h>
#include <linux/phy.h>
diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c
index 90630672703d..02940c0fef68 100644
--- a/drivers/net/phy/mdio_bus.c
+++ b/drivers/net/phy/mdio_bus.c
@@ -29,7 +29,6 @@
#include <linux/spinlock.h>
#include <linux/mm.h>
#include <linux/module.h>
-#include <linux/version.h>
#include <linux/mii.h>
#include <linux/ethtool.h>
#include <linux/phy.h>
@@ -61,6 +60,9 @@ int mdiobus_register(struct mii_bus *bus)
for (i = 0; i < PHY_MAX_ADDR; i++) {
struct phy_device *phydev;
+ if (bus->phy_mask & (1 << i))
+ continue;
+
phydev = get_phy_device(bus, i);
if (IS_ERR(phydev))
@@ -133,13 +135,9 @@ static int mdio_bus_suspend(struct device * dev, pm_message_t state)
int ret = 0;
struct device_driver *drv = dev->driver;
- if (drv && drv->suspend) {
- ret = drv->suspend(dev, state, SUSPEND_DISABLE);
- if (ret == 0)
- ret = drv->suspend(dev, state, SUSPEND_SAVE_STATE);
- if (ret == 0)
- ret = drv->suspend(dev, state, SUSPEND_POWER_DOWN);
- }
+ if (drv && drv->suspend)
+ ret = drv->suspend(dev, state);
+
return ret;
}
@@ -148,13 +146,9 @@ static int mdio_bus_resume(struct device * dev)
int ret = 0;
struct device_driver *drv = dev->driver;
- if (drv && drv->resume) {
- ret = drv->resume(dev, RESUME_POWER_ON);
- if (ret == 0)
- ret = drv->resume(dev, RESUME_RESTORE_STATE);
- if (ret == 0)
- ret = drv->resume(dev, RESUME_ENABLE);
- }
+ if (drv && drv->resume)
+ ret = drv->resume(dev);
+
return ret;
}
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index d9e11f93bf3a..b8686e47f899 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -30,7 +30,6 @@
#include <linux/spinlock.h>
#include <linux/mm.h>
#include <linux/module.h>
-#include <linux/version.h>
#include <linux/mii.h>
#include <linux/ethtool.h>
#include <linux/phy.h>
@@ -242,10 +241,6 @@ EXPORT_SYMBOL(phy_sanitize_settings);
* choose the next best ones from the ones selected, so we don't
* care if ethtool tries to give us bad values
*
- * A note about the PHYCONTROL Layer. If you turn off
- * CONFIG_PHYCONTROL, you will need to read the PHY status
- * registers after this function completes, and update your
- * controller manually.
*/
int phy_ethtool_sset(struct phy_device *phydev, struct ethtool_cmd *cmd)
{
@@ -380,7 +375,6 @@ int phy_start_aneg(struct phy_device *phydev)
err = phydev->drv->config_aneg(phydev);
-#ifdef CONFIG_PHYCONTROL
if (err < 0)
goto out_unlock;
@@ -395,14 +389,12 @@ int phy_start_aneg(struct phy_device *phydev)
}
out_unlock:
-#endif
spin_unlock(&phydev->lock);
return err;
}
EXPORT_SYMBOL(phy_start_aneg);
-#ifdef CONFIG_PHYCONTROL
static void phy_change(void *data);
static void phy_timer(unsigned long data);
@@ -868,4 +860,3 @@ static void phy_timer(unsigned long data)
mod_timer(&phydev->phy_timer, jiffies + PHY_STATE_TIME * HZ);
}
-#endif /* CONFIG_PHYCONTROL */
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index 33f7bdb5857c..16bebe7a7ce1 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -30,7 +30,6 @@
#include <linux/spinlock.h>
#include <linux/mm.h>
#include <linux/module.h>
-#include <linux/version.h>
#include <linux/mii.h>
#include <linux/ethtool.h>
#include <linux/phy.h>
@@ -101,7 +100,6 @@ struct phy_device * get_phy_device(struct mii_bus *bus, int addr)
return dev;
}
-#ifdef CONFIG_PHYCONTROL
/* phy_prepare_link:
*
* description: Tells the PHY infrastructure to handle the
@@ -160,8 +158,6 @@ void phy_disconnect(struct phy_device *phydev)
}
EXPORT_SYMBOL(phy_disconnect);
-#endif /* CONFIG_PHYCONTROL */
-
/* phy_attach:
*
* description: Called by drivers to attach to a particular PHY
diff --git a/drivers/net/phy/qsemi.c b/drivers/net/phy/qsemi.c
index d461ba457631..65d995b02b25 100644
--- a/drivers/net/phy/qsemi.c
+++ b/drivers/net/phy/qsemi.c
@@ -29,7 +29,6 @@
#include <linux/spinlock.h>
#include <linux/mm.h>
#include <linux/module.h>
-#include <linux/version.h>
#include <linux/mii.h>
#include <linux/ethtool.h>
#include <linux/phy.h>
diff --git a/drivers/net/ppp_async.c b/drivers/net/ppp_async.c
index 59e8183c639e..400f652282d7 100644
--- a/drivers/net/ppp_async.c
+++ b/drivers/net/ppp_async.c
@@ -31,6 +31,7 @@
#include <linux/spinlock.h>
#include <linux/init.h>
#include <asm/uaccess.h>
+#include <asm/string.h>
#define PPP_VERSION "2.4.2"
@@ -835,8 +836,11 @@ process_input_packet(struct asyncppp *ap)
err:
/* frame had an error, remember that, reset SC_TOSS & SC_ESCAPE */
ap->state = SC_PREV_ERROR;
- if (skb)
+ if (skb) {
+ /* make skb appear as freshly allocated */
skb_trim(skb, 0);
+ skb_reserve(skb, - skb_headroom(skb));
+ }
}
/* Called when the tty driver has data for us. Runs parallel with the
@@ -889,10 +893,17 @@ ppp_async_input(struct asyncppp *ap, const unsigned char *buf,
skb = dev_alloc_skb(ap->mru + PPP_HDRLEN + 2);
if (skb == 0)
goto nomem;
- /* Try to get the payload 4-byte aligned */
+ ap->rpkt = skb;
+ }
+ if (skb->len == 0) {
+ /* Try to get the payload 4-byte aligned.
+ * This should match the
+ * PPP_ALLSTATIONS/PPP_UI/compressed tests in
+ * process_input_packet, but we do not have
+ * enough chars here to test buf[1] and buf[2].
+ */
if (buf[0] != PPP_ALLSTATIONS)
skb_reserve(skb, 2 + (buf[0] & 1));
- ap->rpkt = skb;
}
if (n > skb_tailroom(skb)) {
/* packet overflowed MRU */
diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c
index 0df7e92b0bf8..50430f79f8cf 100644
--- a/drivers/net/ppp_generic.c
+++ b/drivers/net/ppp_generic.c
@@ -137,13 +137,14 @@ struct ppp {
/*
* Bits in flags: SC_NO_TCP_CCID, SC_CCP_OPEN, SC_CCP_UP, SC_LOOP_TRAFFIC,
- * SC_MULTILINK, SC_MP_SHORTSEQ, SC_MP_XSHORTSEQ, SC_COMP_TCP, SC_REJ_COMP_TCP.
+ * SC_MULTILINK, SC_MP_SHORTSEQ, SC_MP_XSHORTSEQ, SC_COMP_TCP, SC_REJ_COMP_TCP,
+ * SC_MUST_COMP
* Bits in rstate: SC_DECOMP_RUN, SC_DC_ERROR, SC_DC_FERROR.
* Bits in xstate: SC_COMP_RUN
*/
#define SC_FLAG_BITS (SC_NO_TCP_CCID|SC_CCP_OPEN|SC_CCP_UP|SC_LOOP_TRAFFIC \
|SC_MULTILINK|SC_MP_SHORTSEQ|SC_MP_XSHORTSEQ \
- |SC_COMP_TCP|SC_REJ_COMP_TCP)
+ |SC_COMP_TCP|SC_REJ_COMP_TCP|SC_MUST_COMP)
/*
* Private data structure for each channel.
@@ -863,7 +864,7 @@ static int __init ppp_init(void)
err = PTR_ERR(ppp_class);
goto out_chrdev;
}
- class_device_create(ppp_class, MKDEV(PPP_MAJOR, 0), NULL, "ppp");
+ class_device_create(ppp_class, NULL, MKDEV(PPP_MAJOR, 0), NULL, "ppp");
err = devfs_mk_cdev(MKDEV(PPP_MAJOR, 0),
S_IFCHR|S_IRUSR|S_IWUSR, "ppp");
if (err)
@@ -1027,6 +1028,56 @@ ppp_xmit_process(struct ppp *ppp)
ppp_xmit_unlock(ppp);
}
+static inline struct sk_buff *
+pad_compress_skb(struct ppp *ppp, struct sk_buff *skb)
+{
+ struct sk_buff *new_skb;
+ int len;
+ int new_skb_size = ppp->dev->mtu +
+ ppp->xcomp->comp_extra + ppp->dev->hard_header_len;
+ int compressor_skb_size = ppp->dev->mtu +
+ ppp->xcomp->comp_extra + PPP_HDRLEN;
+ new_skb = alloc_skb(new_skb_size, GFP_ATOMIC);
+ if (!new_skb) {
+ if (net_ratelimit())
+ printk(KERN_ERR "PPP: no memory (comp pkt)\n");
+ return NULL;
+ }
+ if (ppp->dev->hard_header_len > PPP_HDRLEN)
+ skb_reserve(new_skb,
+ ppp->dev->hard_header_len - PPP_HDRLEN);
+
+ /* compressor still expects A/C bytes in hdr */
+ len = ppp->xcomp->compress(ppp->xc_state, skb->data - 2,
+ new_skb->data, skb->len + 2,
+ compressor_skb_size);
+ if (len > 0 && (ppp->flags & SC_CCP_UP)) {
+ kfree_skb(skb);
+ skb = new_skb;
+ skb_put(skb, len);
+ skb_pull(skb, 2); /* pull off A/C bytes */
+ } else if (len == 0) {
+ /* didn't compress, or CCP not up yet */
+ kfree_skb(new_skb);
+ new_skb = skb;
+ } else {
+ /*
+ * (len < 0)
+ * MPPE requires that we do not send unencrypted
+ * frames. The compressor will return -1 if we
+ * should drop the frame. We cannot simply test
+ * the compress_proto because MPPE and MPPC share
+ * the same number.
+ */
+ if (net_ratelimit())
+ printk(KERN_ERR "ppp: compressor dropped pkt\n");
+ kfree_skb(skb);
+ kfree_skb(new_skb);
+ new_skb = NULL;
+ }
+ return new_skb;
+}
+
/*
* Compress and send a frame.
* The caller should have locked the xmit path,
@@ -1113,29 +1164,14 @@ ppp_send_frame(struct ppp *ppp, struct sk_buff *skb)
/* try to do packet compression */
if ((ppp->xstate & SC_COMP_RUN) && ppp->xc_state != 0
&& proto != PPP_LCP && proto != PPP_CCP) {
- new_skb = alloc_skb(ppp->dev->mtu + ppp->dev->hard_header_len,
- GFP_ATOMIC);
- if (new_skb == 0) {
- printk(KERN_ERR "PPP: no memory (comp pkt)\n");
+ if (!(ppp->flags & SC_CCP_UP) && (ppp->flags & SC_MUST_COMP)) {
+ if (net_ratelimit())
+ printk(KERN_ERR "ppp: compression required but down - pkt dropped.\n");
goto drop;
}
- if (ppp->dev->hard_header_len > PPP_HDRLEN)
- skb_reserve(new_skb,
- ppp->dev->hard_header_len - PPP_HDRLEN);
-
- /* compressor still expects A/C bytes in hdr */
- len = ppp->xcomp->compress(ppp->xc_state, skb->data - 2,
- new_skb->data, skb->len + 2,
- ppp->dev->mtu + PPP_HDRLEN);
- if (len > 0 && (ppp->flags & SC_CCP_UP)) {
- kfree_skb(skb);
- skb = new_skb;
- skb_put(skb, len);
- skb_pull(skb, 2); /* pull off A/C bytes */
- } else {
- /* didn't compress, or CCP not up yet */
- kfree_skb(new_skb);
- }
+ skb = pad_compress_skb(ppp, skb);
+ if (!skb)
+ goto drop;
}
/*
@@ -1155,7 +1191,8 @@ ppp_send_frame(struct ppp *ppp, struct sk_buff *skb)
return;
drop:
- kfree_skb(skb);
+ if (skb)
+ kfree_skb(skb);
++ppp->stats.tx_errors;
}
@@ -1552,6 +1589,9 @@ ppp_receive_nonmp_frame(struct ppp *ppp, struct sk_buff *skb)
&& (ppp->rstate & (SC_DC_FERROR | SC_DC_ERROR)) == 0)
skb = ppp_decompress_frame(ppp, skb);
+ if (ppp->flags & SC_MUST_COMP && ppp->rstate & SC_DC_FERROR)
+ goto err;
+
proto = PPP_PROTO(skb);
switch (proto) {
case PPP_VJC_COMP:
diff --git a/drivers/net/ppp_mppe.c b/drivers/net/ppp_mppe.c
new file mode 100644
index 000000000000..1985d1b57c45
--- /dev/null
+++ b/drivers/net/ppp_mppe.c
@@ -0,0 +1,724 @@
+/*
+ * ppp_mppe.c - interface MPPE to the PPP code.
+ * This version is for use with Linux kernel 2.6.14+
+ *
+ * By Frank Cusack <fcusack@fcusack.com>.
+ * Copyright (c) 2002,2003,2004 Google, Inc.
+ * All rights reserved.
+ *
+ * License:
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation is hereby granted, provided that the above copyright
+ * notice appears in all copies. This software is provided without any
+ * warranty, express or implied.
+ *
+ * ALTERNATIVELY, provided that this notice is retained in full, this product
+ * may be distributed under the terms of the GNU General Public License (GPL),
+ * in which case the provisions of the GPL apply INSTEAD OF those given above.
+ *
+ * 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
+ *
+ *
+ * Changelog:
+ * 08/12/05 - Matt Domsch <Matt_Domsch@dell.com>
+ * Only need extra skb padding on transmit, not receive.
+ * 06/18/04 - Matt Domsch <Matt_Domsch@dell.com>, Oleg Makarenko <mole@quadra.ru>
+ * Use Linux kernel 2.6 arc4 and sha1 routines rather than
+ * providing our own.
+ * 2/15/04 - TS: added #include <version.h> and testing for Kernel
+ * version before using
+ * MOD_DEC_USAGE_COUNT/MOD_INC_USAGE_COUNT which are
+ * deprecated in 2.6
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/version.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/crypto.h>
+#include <linux/mm.h>
+#include <linux/ppp_defs.h>
+#include <linux/ppp-comp.h>
+#include <asm/scatterlist.h>
+
+#include "ppp_mppe.h"
+
+MODULE_AUTHOR("Frank Cusack <fcusack@fcusack.com>");
+MODULE_DESCRIPTION("Point-to-Point Protocol Microsoft Point-to-Point Encryption support");
+MODULE_LICENSE("Dual BSD/GPL");
+MODULE_ALIAS("ppp-compress-" __stringify(CI_MPPE));
+MODULE_VERSION("1.0.2");
+
+static void
+setup_sg(struct scatterlist *sg, const void *address, unsigned int length)
+{
+ sg[0].page = virt_to_page(address);
+ sg[0].offset = offset_in_page(address);
+ sg[0].length = length;
+}
+
+#define SHA1_PAD_SIZE 40
+
+/*
+ * kernel crypto API needs its arguments to be in kmalloc'd memory, not in the module
+ * static data area. That means sha_pad needs to be kmalloc'd.
+ */
+
+struct sha_pad {
+ unsigned char sha_pad1[SHA1_PAD_SIZE];
+ unsigned char sha_pad2[SHA1_PAD_SIZE];
+};
+static struct sha_pad *sha_pad;
+
+static inline void sha_pad_init(struct sha_pad *shapad)
+{
+ memset(shapad->sha_pad1, 0x00, sizeof(shapad->sha_pad1));
+ memset(shapad->sha_pad2, 0xF2, sizeof(shapad->sha_pad2));
+}
+
+/*
+ * State for an MPPE (de)compressor.
+ */
+struct ppp_mppe_state {
+ struct crypto_tfm *arc4;
+ struct crypto_tfm *sha1;
+ unsigned char *sha1_digest;
+ unsigned char master_key[MPPE_MAX_KEY_LEN];
+ unsigned char session_key[MPPE_MAX_KEY_LEN];
+ unsigned keylen; /* key length in bytes */
+ /* NB: 128-bit == 16, 40-bit == 8! */
+ /* If we want to support 56-bit, */
+ /* the unit has to change to bits */
+ unsigned char bits; /* MPPE control bits */
+ unsigned ccount; /* 12-bit coherency count (seqno) */
+ unsigned stateful; /* stateful mode flag */
+ int discard; /* stateful mode packet loss flag */
+ int sanity_errors; /* take down LCP if too many */
+ int unit;
+ int debug;
+ struct compstat stats;
+};
+
+/* struct ppp_mppe_state.bits definitions */
+#define MPPE_BIT_A 0x80 /* Encryption table were (re)inititalized */
+#define MPPE_BIT_B 0x40 /* MPPC only (not implemented) */
+#define MPPE_BIT_C 0x20 /* MPPC only (not implemented) */
+#define MPPE_BIT_D 0x10 /* This is an encrypted frame */
+
+#define MPPE_BIT_FLUSHED MPPE_BIT_A
+#define MPPE_BIT_ENCRYPTED MPPE_BIT_D
+
+#define MPPE_BITS(p) ((p)[4] & 0xf0)
+#define MPPE_CCOUNT(p) ((((p)[4] & 0x0f) << 8) + (p)[5])
+#define MPPE_CCOUNT_SPACE 0x1000 /* The size of the ccount space */
+
+#define MPPE_OVHD 2 /* MPPE overhead/packet */
+#define SANITY_MAX 1600 /* Max bogon factor we will tolerate */
+
+/*
+ * Key Derivation, from RFC 3078, RFC 3079.
+ * Equivalent to Get_Key() for MS-CHAP as described in RFC 3079.
+ */
+static void get_new_key_from_sha(struct ppp_mppe_state * state, unsigned char *InterimKey)
+{
+ struct scatterlist sg[4];
+
+ setup_sg(&sg[0], state->master_key, state->keylen);
+ setup_sg(&sg[1], sha_pad->sha_pad1, sizeof(sha_pad->sha_pad1));
+ setup_sg(&sg[2], state->session_key, state->keylen);
+ setup_sg(&sg[3], sha_pad->sha_pad2, sizeof(sha_pad->sha_pad2));
+
+ crypto_digest_digest (state->sha1, sg, 4, state->sha1_digest);
+
+ memcpy(InterimKey, state->sha1_digest, state->keylen);
+}
+
+/*
+ * Perform the MPPE rekey algorithm, from RFC 3078, sec. 7.3.
+ * Well, not what's written there, but rather what they meant.
+ */
+static void mppe_rekey(struct ppp_mppe_state * state, int initial_key)
+{
+ unsigned char InterimKey[MPPE_MAX_KEY_LEN];
+ struct scatterlist sg_in[1], sg_out[1];
+
+ get_new_key_from_sha(state, InterimKey);
+ if (!initial_key) {
+ crypto_cipher_setkey(state->arc4, InterimKey, state->keylen);
+ setup_sg(sg_in, InterimKey, state->keylen);
+ setup_sg(sg_out, state->session_key, state->keylen);
+ if (crypto_cipher_encrypt(state->arc4, sg_out, sg_in,
+ state->keylen) != 0) {
+ printk(KERN_WARNING "mppe_rekey: cipher_encrypt failed\n");
+ }
+ } else {
+ memcpy(state->session_key, InterimKey, state->keylen);
+ }
+ if (state->keylen == 8) {
+ /* See RFC 3078 */
+ state->session_key[0] = 0xd1;
+ state->session_key[1] = 0x26;
+ state->session_key[2] = 0x9e;
+ }
+ crypto_cipher_setkey(state->arc4, state->session_key, state->keylen);
+}
+
+/*
+ * Allocate space for a (de)compressor.
+ */
+static void *mppe_alloc(unsigned char *options, int optlen)
+{
+ struct ppp_mppe_state *state;
+ unsigned int digestsize;
+
+ if (optlen != CILEN_MPPE + sizeof(state->master_key)
+ || options[0] != CI_MPPE || options[1] != CILEN_MPPE)
+ goto out;
+
+ state = (struct ppp_mppe_state *) kmalloc(sizeof(*state), GFP_KERNEL);
+ if (state == NULL)
+ goto out;
+
+ memset(state, 0, sizeof(*state));
+
+ state->arc4 = crypto_alloc_tfm("arc4", 0);
+ if (!state->arc4)
+ goto out_free;
+
+ state->sha1 = crypto_alloc_tfm("sha1", 0);
+ if (!state->sha1)
+ goto out_free;
+
+ digestsize = crypto_tfm_alg_digestsize(state->sha1);
+ if (digestsize < MPPE_MAX_KEY_LEN)
+ goto out_free;
+
+ state->sha1_digest = kmalloc(digestsize, GFP_KERNEL);
+ if (!state->sha1_digest)
+ goto out_free;
+
+ /* Save keys. */
+ memcpy(state->master_key, &options[CILEN_MPPE],
+ sizeof(state->master_key));
+ memcpy(state->session_key, state->master_key,
+ sizeof(state->master_key));
+
+ /*
+ * We defer initial key generation until mppe_init(), as mppe_alloc()
+ * is called frequently during negotiation.
+ */
+
+ return (void *)state;
+
+ out_free:
+ if (state->sha1_digest)
+ kfree(state->sha1_digest);
+ if (state->sha1)
+ crypto_free_tfm(state->sha1);
+ if (state->arc4)
+ crypto_free_tfm(state->arc4);
+ kfree(state);
+ out:
+ return NULL;
+}
+
+/*
+ * Deallocate space for a (de)compressor.
+ */
+static void mppe_free(void *arg)
+{
+ struct ppp_mppe_state *state = (struct ppp_mppe_state *) arg;
+ if (state) {
+ if (state->sha1_digest)
+ kfree(state->sha1_digest);
+ if (state->sha1)
+ crypto_free_tfm(state->sha1);
+ if (state->arc4)
+ crypto_free_tfm(state->arc4);
+ kfree(state);
+ }
+}
+
+/*
+ * Initialize (de)compressor state.
+ */
+static int
+mppe_init(void *arg, unsigned char *options, int optlen, int unit, int debug,
+ const char *debugstr)
+{
+ struct ppp_mppe_state *state = (struct ppp_mppe_state *) arg;
+ unsigned char mppe_opts;
+
+ if (optlen != CILEN_MPPE
+ || options[0] != CI_MPPE || options[1] != CILEN_MPPE)
+ return 0;
+
+ MPPE_CI_TO_OPTS(&options[2], mppe_opts);
+ if (mppe_opts & MPPE_OPT_128)
+ state->keylen = 16;
+ else if (mppe_opts & MPPE_OPT_40)
+ state->keylen = 8;
+ else {
+ printk(KERN_WARNING "%s[%d]: unknown key length\n", debugstr,
+ unit);
+ return 0;
+ }
+ if (mppe_opts & MPPE_OPT_STATEFUL)
+ state->stateful = 1;
+
+ /* Generate the initial session key. */
+ mppe_rekey(state, 1);
+
+ if (debug) {
+ int i;
+ char mkey[sizeof(state->master_key) * 2 + 1];
+ char skey[sizeof(state->session_key) * 2 + 1];
+
+ printk(KERN_DEBUG "%s[%d]: initialized with %d-bit %s mode\n",
+ debugstr, unit, (state->keylen == 16) ? 128 : 40,
+ (state->stateful) ? "stateful" : "stateless");
+
+ for (i = 0; i < sizeof(state->master_key); i++)
+ sprintf(mkey + i * 2, "%02x", state->master_key[i]);
+ for (i = 0; i < sizeof(state->session_key); i++)
+ sprintf(skey + i * 2, "%02x", state->session_key[i]);
+ printk(KERN_DEBUG
+ "%s[%d]: keys: master: %s initial session: %s\n",
+ debugstr, unit, mkey, skey);
+ }
+
+ /*
+ * Initialize the coherency count. The initial value is not specified
+ * in RFC 3078, but we can make a reasonable assumption that it will
+ * start at 0. Setting it to the max here makes the comp/decomp code
+ * do the right thing (determined through experiment).
+ */
+ state->ccount = MPPE_CCOUNT_SPACE - 1;
+
+ /*
+ * Note that even though we have initialized the key table, we don't
+ * set the FLUSHED bit. This is contrary to RFC 3078, sec. 3.1.
+ */
+ state->bits = MPPE_BIT_ENCRYPTED;
+
+ state->unit = unit;
+ state->debug = debug;
+
+ return 1;
+}
+
+static int
+mppe_comp_init(void *arg, unsigned char *options, int optlen, int unit,
+ int hdrlen, int debug)
+{
+ /* ARGSUSED */
+ return mppe_init(arg, options, optlen, unit, debug, "mppe_comp_init");
+}
+
+/*
+ * We received a CCP Reset-Request (actually, we are sending a Reset-Ack),
+ * tell the compressor to rekey. Note that we MUST NOT rekey for
+ * every CCP Reset-Request; we only rekey on the next xmit packet.
+ * We might get multiple CCP Reset-Requests if our CCP Reset-Ack is lost.
+ * So, rekeying for every CCP Reset-Request is broken as the peer will not
+ * know how many times we've rekeyed. (If we rekey and THEN get another
+ * CCP Reset-Request, we must rekey again.)
+ */
+static void mppe_comp_reset(void *arg)
+{
+ struct ppp_mppe_state *state = (struct ppp_mppe_state *) arg;
+
+ state->bits |= MPPE_BIT_FLUSHED;
+}
+
+/*
+ * Compress (encrypt) a packet.
+ * It's strange to call this a compressor, since the output is always
+ * MPPE_OVHD + 2 bytes larger than the input.
+ */
+static int
+mppe_compress(void *arg, unsigned char *ibuf, unsigned char *obuf,
+ int isize, int osize)
+{
+ struct ppp_mppe_state *state = (struct ppp_mppe_state *) arg;
+ int proto;
+ struct scatterlist sg_in[1], sg_out[1];
+
+ /*
+ * Check that the protocol is in the range we handle.
+ */
+ proto = PPP_PROTOCOL(ibuf);
+ if (proto < 0x0021 || proto > 0x00fa)
+ return 0;
+
+ /* Make sure we have enough room to generate an encrypted packet. */
+ if (osize < isize + MPPE_OVHD + 2) {
+ /* Drop the packet if we should encrypt it, but can't. */
+ printk(KERN_DEBUG "mppe_compress[%d]: osize too small! "
+ "(have: %d need: %d)\n", state->unit,
+ osize, osize + MPPE_OVHD + 2);
+ return -1;
+ }
+
+ osize = isize + MPPE_OVHD + 2;
+
+ /*
+ * Copy over the PPP header and set control bits.
+ */
+ obuf[0] = PPP_ADDRESS(ibuf);
+ obuf[1] = PPP_CONTROL(ibuf);
+ obuf[2] = PPP_COMP >> 8; /* isize + MPPE_OVHD + 1 */
+ obuf[3] = PPP_COMP; /* isize + MPPE_OVHD + 2 */
+ obuf += PPP_HDRLEN;
+
+ state->ccount = (state->ccount + 1) % MPPE_CCOUNT_SPACE;
+ if (state->debug >= 7)
+ printk(KERN_DEBUG "mppe_compress[%d]: ccount %d\n", state->unit,
+ state->ccount);
+ obuf[0] = state->ccount >> 8;
+ obuf[1] = state->ccount & 0xff;
+
+ if (!state->stateful || /* stateless mode */
+ ((state->ccount & 0xff) == 0xff) || /* "flag" packet */
+ (state->bits & MPPE_BIT_FLUSHED)) { /* CCP Reset-Request */
+ /* We must rekey */
+ if (state->debug && state->stateful)
+ printk(KERN_DEBUG "mppe_compress[%d]: rekeying\n",
+ state->unit);
+ mppe_rekey(state, 0);
+ state->bits |= MPPE_BIT_FLUSHED;
+ }
+ obuf[0] |= state->bits;
+ state->bits &= ~MPPE_BIT_FLUSHED; /* reset for next xmit */
+
+ obuf += MPPE_OVHD;
+ ibuf += 2; /* skip to proto field */
+ isize -= 2;
+
+ /* Encrypt packet */
+ setup_sg(sg_in, ibuf, isize);
+ setup_sg(sg_out, obuf, osize);
+ if (crypto_cipher_encrypt(state->arc4, sg_out, sg_in, isize) != 0) {
+ printk(KERN_DEBUG "crypto_cypher_encrypt failed\n");
+ return -1;
+ }
+
+ state->stats.unc_bytes += isize;
+ state->stats.unc_packets++;
+ state->stats.comp_bytes += osize;
+ state->stats.comp_packets++;
+
+ return osize;
+}
+
+/*
+ * Since every frame grows by MPPE_OVHD + 2 bytes, this is always going
+ * to look bad ... and the longer the link is up the worse it will get.
+ */
+static void mppe_comp_stats(void *arg, struct compstat *stats)
+{
+ struct ppp_mppe_state *state = (struct ppp_mppe_state *) arg;
+
+ *stats = state->stats;
+}
+
+static int
+mppe_decomp_init(void *arg, unsigned char *options, int optlen, int unit,
+ int hdrlen, int mru, int debug)
+{
+ /* ARGSUSED */
+ return mppe_init(arg, options, optlen, unit, debug, "mppe_decomp_init");
+}
+
+/*
+ * We received a CCP Reset-Ack. Just ignore it.
+ */
+static void mppe_decomp_reset(void *arg)
+{
+ /* ARGSUSED */
+ return;
+}
+
+/*
+ * Decompress (decrypt) an MPPE packet.
+ */
+static int
+mppe_decompress(void *arg, unsigned char *ibuf, int isize, unsigned char *obuf,
+ int osize)
+{
+ struct ppp_mppe_state *state = (struct ppp_mppe_state *) arg;
+ unsigned ccount;
+ int flushed = MPPE_BITS(ibuf) & MPPE_BIT_FLUSHED;
+ int sanity = 0;
+ struct scatterlist sg_in[1], sg_out[1];
+
+ if (isize <= PPP_HDRLEN + MPPE_OVHD) {
+ if (state->debug)
+ printk(KERN_DEBUG
+ "mppe_decompress[%d]: short pkt (%d)\n",
+ state->unit, isize);
+ return DECOMP_ERROR;
+ }
+
+ /*
+ * Make sure we have enough room to decrypt the packet.
+ * Note that for our test we only subtract 1 byte whereas in
+ * mppe_compress() we added 2 bytes (+MPPE_OVHD);
+ * this is to account for possible PFC.
+ */
+ if (osize < isize - MPPE_OVHD - 1) {
+ printk(KERN_DEBUG "mppe_decompress[%d]: osize too small! "
+ "(have: %d need: %d)\n", state->unit,
+ osize, isize - MPPE_OVHD - 1);
+ return DECOMP_ERROR;
+ }
+ osize = isize - MPPE_OVHD - 2; /* assume no PFC */
+
+ ccount = MPPE_CCOUNT(ibuf);
+ if (state->debug >= 7)
+ printk(KERN_DEBUG "mppe_decompress[%d]: ccount %d\n",
+ state->unit, ccount);
+
+ /* sanity checks -- terminate with extreme prejudice */
+ if (!(MPPE_BITS(ibuf) & MPPE_BIT_ENCRYPTED)) {
+ printk(KERN_DEBUG
+ "mppe_decompress[%d]: ENCRYPTED bit not set!\n",
+ state->unit);
+ state->sanity_errors += 100;
+ sanity = 1;
+ }
+ if (!state->stateful && !flushed) {
+ printk(KERN_DEBUG "mppe_decompress[%d]: FLUSHED bit not set in "
+ "stateless mode!\n", state->unit);
+ state->sanity_errors += 100;
+ sanity = 1;
+ }
+ if (state->stateful && ((ccount & 0xff) == 0xff) && !flushed) {
+ printk(KERN_DEBUG "mppe_decompress[%d]: FLUSHED bit not set on "
+ "flag packet!\n", state->unit);
+ state->sanity_errors += 100;
+ sanity = 1;
+ }
+
+ if (sanity) {
+ if (state->sanity_errors < SANITY_MAX)
+ return DECOMP_ERROR;
+ else
+ /*
+ * Take LCP down if the peer is sending too many bogons.
+ * We don't want to do this for a single or just a few
+ * instances since it could just be due to packet corruption.
+ */
+ return DECOMP_FATALERROR;
+ }
+
+ /*
+ * Check the coherency count.
+ */
+
+ if (!state->stateful) {
+ /* RFC 3078, sec 8.1. Rekey for every packet. */
+ while (state->ccount != ccount) {
+ mppe_rekey(state, 0);
+ state->ccount = (state->ccount + 1) % MPPE_CCOUNT_SPACE;
+ }
+ } else {
+ /* RFC 3078, sec 8.2. */
+ if (!state->discard) {
+ /* normal state */
+ state->ccount = (state->ccount + 1) % MPPE_CCOUNT_SPACE;
+ if (ccount != state->ccount) {
+ /*
+ * (ccount > state->ccount)
+ * Packet loss detected, enter the discard state.
+ * Signal the peer to rekey (by sending a CCP Reset-Request).
+ */
+ state->discard = 1;
+ return DECOMP_ERROR;
+ }
+ } else {
+ /* discard state */
+ if (!flushed) {
+ /* ccp.c will be silent (no additional CCP Reset-Requests). */
+ return DECOMP_ERROR;
+ } else {
+ /* Rekey for every missed "flag" packet. */
+ while ((ccount & ~0xff) !=
+ (state->ccount & ~0xff)) {
+ mppe_rekey(state, 0);
+ state->ccount =
+ (state->ccount +
+ 256) % MPPE_CCOUNT_SPACE;
+ }
+
+ /* reset */
+ state->discard = 0;
+ state->ccount = ccount;
+ /*
+ * Another problem with RFC 3078 here. It implies that the
+ * peer need not send a Reset-Ack packet. But RFC 1962
+ * requires it. Hopefully, M$ does send a Reset-Ack; even
+ * though it isn't required for MPPE synchronization, it is
+ * required to reset CCP state.
+ */
+ }
+ }
+ if (flushed)
+ mppe_rekey(state, 0);
+ }
+
+ /*
+ * Fill in the first part of the PPP header. The protocol field
+ * comes from the decrypted data.
+ */
+ obuf[0] = PPP_ADDRESS(ibuf); /* +1 */
+ obuf[1] = PPP_CONTROL(ibuf); /* +1 */
+ obuf += 2;
+ ibuf += PPP_HDRLEN + MPPE_OVHD;
+ isize -= PPP_HDRLEN + MPPE_OVHD; /* -6 */
+ /* net osize: isize-4 */
+
+ /*
+ * Decrypt the first byte in order to check if it is
+ * a compressed or uncompressed protocol field.
+ */
+ setup_sg(sg_in, ibuf, 1);
+ setup_sg(sg_out, obuf, 1);
+ if (crypto_cipher_decrypt(state->arc4, sg_out, sg_in, 1) != 0) {
+ printk(KERN_DEBUG "crypto_cypher_decrypt failed\n");
+ return DECOMP_ERROR;
+ }
+
+ /*
+ * Do PFC decompression.
+ * This would be nicer if we were given the actual sk_buff
+ * instead of a char *.
+ */
+ if ((obuf[0] & 0x01) != 0) {
+ obuf[1] = obuf[0];
+ obuf[0] = 0;
+ obuf++;
+ osize++;
+ }
+
+ /* And finally, decrypt the rest of the packet. */
+ setup_sg(sg_in, ibuf + 1, isize - 1);
+ setup_sg(sg_out, obuf + 1, osize - 1);
+ if (crypto_cipher_decrypt(state->arc4, sg_out, sg_in, isize - 1) != 0) {
+ printk(KERN_DEBUG "crypto_cypher_decrypt failed\n");
+ return DECOMP_ERROR;
+ }
+
+ state->stats.unc_bytes += osize;
+ state->stats.unc_packets++;
+ state->stats.comp_bytes += isize;
+ state->stats.comp_packets++;
+
+ /* good packet credit */
+ state->sanity_errors >>= 1;
+
+ return osize;
+}
+
+/*
+ * Incompressible data has arrived (this should never happen!).
+ * We should probably drop the link if the protocol is in the range
+ * of what should be encrypted. At the least, we should drop this
+ * packet. (How to do this?)
+ */
+static void mppe_incomp(void *arg, unsigned char *ibuf, int icnt)
+{
+ struct ppp_mppe_state *state = (struct ppp_mppe_state *) arg;
+
+ if (state->debug &&
+ (PPP_PROTOCOL(ibuf) >= 0x0021 && PPP_PROTOCOL(ibuf) <= 0x00fa))
+ printk(KERN_DEBUG
+ "mppe_incomp[%d]: incompressible (unencrypted) data! "
+ "(proto %04x)\n", state->unit, PPP_PROTOCOL(ibuf));
+
+ state->stats.inc_bytes += icnt;
+ state->stats.inc_packets++;
+ state->stats.unc_bytes += icnt;
+ state->stats.unc_packets++;
+}
+
+/*************************************************************
+ * Module interface table
+ *************************************************************/
+
+/*
+ * Procedures exported to if_ppp.c.
+ */
+static struct compressor ppp_mppe = {
+ .compress_proto = CI_MPPE,
+ .comp_alloc = mppe_alloc,
+ .comp_free = mppe_free,
+ .comp_init = mppe_comp_init,
+ .comp_reset = mppe_comp_reset,
+ .compress = mppe_compress,
+ .comp_stat = mppe_comp_stats,
+ .decomp_alloc = mppe_alloc,
+ .decomp_free = mppe_free,
+ .decomp_init = mppe_decomp_init,
+ .decomp_reset = mppe_decomp_reset,
+ .decompress = mppe_decompress,
+ .incomp = mppe_incomp,
+ .decomp_stat = mppe_comp_stats,
+ .owner = THIS_MODULE,
+ .comp_extra = MPPE_PAD,
+};
+
+/*
+ * ppp_mppe_init()
+ *
+ * Prior to allowing load, try to load the arc4 and sha1 crypto
+ * libraries. The actual use will be allocated later, but
+ * this way the module will fail to insmod if they aren't available.
+ */
+
+static int __init ppp_mppe_init(void)
+{
+ int answer;
+ if (!(crypto_alg_available("arc4", 0) &&
+ crypto_alg_available("sha1", 0)))
+ return -ENODEV;
+
+ sha_pad = kmalloc(sizeof(struct sha_pad), GFP_KERNEL);
+ if (!sha_pad)
+ return -ENOMEM;
+ sha_pad_init(sha_pad);
+
+ answer = ppp_register_compressor(&ppp_mppe);
+
+ if (answer == 0)
+ printk(KERN_INFO "PPP MPPE Compression module registered\n");
+ else
+ kfree(sha_pad);
+
+ return answer;
+}
+
+static void __exit ppp_mppe_cleanup(void)
+{
+ ppp_unregister_compressor(&ppp_mppe);
+ kfree(sha_pad);
+}
+
+module_init(ppp_mppe_init);
+module_exit(ppp_mppe_cleanup);
diff --git a/drivers/net/ppp_mppe.h b/drivers/net/ppp_mppe.h
new file mode 100644
index 000000000000..7a14e058c668
--- /dev/null
+++ b/drivers/net/ppp_mppe.h
@@ -0,0 +1,86 @@
+#define MPPE_PAD 4 /* MPPE growth per frame */
+#define MPPE_MAX_KEY_LEN 16 /* largest key length (128-bit) */
+
+/* option bits for ccp_options.mppe */
+#define MPPE_OPT_40 0x01 /* 40 bit */
+#define MPPE_OPT_128 0x02 /* 128 bit */
+#define MPPE_OPT_STATEFUL 0x04 /* stateful mode */
+/* unsupported opts */
+#define MPPE_OPT_56 0x08 /* 56 bit */
+#define MPPE_OPT_MPPC 0x10 /* MPPC compression */
+#define MPPE_OPT_D 0x20 /* Unknown */
+#define MPPE_OPT_UNSUPPORTED (MPPE_OPT_56|MPPE_OPT_MPPC|MPPE_OPT_D)
+#define MPPE_OPT_UNKNOWN 0x40 /* Bits !defined in RFC 3078 were set */
+
+/*
+ * This is not nice ... the alternative is a bitfield struct though.
+ * And unfortunately, we cannot share the same bits for the option
+ * names above since C and H are the same bit. We could do a u_int32
+ * but then we have to do a htonl() all the time and/or we still need
+ * to know which octet is which.
+ */
+#define MPPE_C_BIT 0x01 /* MPPC */
+#define MPPE_D_BIT 0x10 /* Obsolete, usage unknown */
+#define MPPE_L_BIT 0x20 /* 40-bit */
+#define MPPE_S_BIT 0x40 /* 128-bit */
+#define MPPE_M_BIT 0x80 /* 56-bit, not supported */
+#define MPPE_H_BIT 0x01 /* Stateless (in a different byte) */
+
+/* Does not include H bit; used for least significant octet only. */
+#define MPPE_ALL_BITS (MPPE_D_BIT|MPPE_L_BIT|MPPE_S_BIT|MPPE_M_BIT|MPPE_H_BIT)
+
+/* Build a CI from mppe opts (see RFC 3078) */
+#define MPPE_OPTS_TO_CI(opts, ci) \
+ do { \
+ u_char *ptr = ci; /* u_char[4] */ \
+ \
+ /* H bit */ \
+ if (opts & MPPE_OPT_STATEFUL) \
+ *ptr++ = 0x0; \
+ else \
+ *ptr++ = MPPE_H_BIT; \
+ *ptr++ = 0; \
+ *ptr++ = 0; \
+ \
+ /* S,L bits */ \
+ *ptr = 0; \
+ if (opts & MPPE_OPT_128) \
+ *ptr |= MPPE_S_BIT; \
+ if (opts & MPPE_OPT_40) \
+ *ptr |= MPPE_L_BIT; \
+ /* M,D,C bits not supported */ \
+ } while (/* CONSTCOND */ 0)
+
+/* The reverse of the above */
+#define MPPE_CI_TO_OPTS(ci, opts) \
+ do { \
+ u_char *ptr = ci; /* u_char[4] */ \
+ \
+ opts = 0; \
+ \
+ /* H bit */ \
+ if (!(ptr[0] & MPPE_H_BIT)) \
+ opts |= MPPE_OPT_STATEFUL; \
+ \
+ /* S,L bits */ \
+ if (ptr[3] & MPPE_S_BIT) \
+ opts |= MPPE_OPT_128; \
+ if (ptr[3] & MPPE_L_BIT) \
+ opts |= MPPE_OPT_40; \
+ \
+ /* M,D,C bits */ \
+ if (ptr[3] & MPPE_M_BIT) \
+ opts |= MPPE_OPT_56; \
+ if (ptr[3] & MPPE_D_BIT) \
+ opts |= MPPE_OPT_D; \
+ if (ptr[3] & MPPE_C_BIT) \
+ opts |= MPPE_OPT_MPPC; \
+ \
+ /* Other bits */ \
+ if (ptr[0] & ~MPPE_H_BIT) \
+ opts |= MPPE_OPT_UNKNOWN; \
+ if (ptr[1] || ptr[2]) \
+ opts |= MPPE_OPT_UNKNOWN; \
+ if (ptr[3] & ~MPPE_ALL_BITS) \
+ opts |= MPPE_OPT_UNKNOWN; \
+ } while (/* CONSTCOND */ 0)
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index afb3f186b884..159b56a56ef4 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -1027,6 +1027,7 @@ static struct ethtool_ops rtl8169_ethtool_ops = {
.get_strings = rtl8169_get_strings,
.get_stats_count = rtl8169_get_stats_count,
.get_ethtool_stats = rtl8169_get_ethtool_stats,
+ .get_perm_addr = ethtool_op_get_perm_addr,
};
static void rtl8169_write_gmii_reg_bit(void __iomem *ioaddr, int reg, int bitnum,
@@ -1511,6 +1512,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
/* Get MAC address. FIXME: read EEPROM */
for (i = 0; i < MAC_ADDR_LEN; i++)
dev->dev_addr[i] = RTL_R8(MAC0 + i);
+ memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
dev->open = rtl8169_open;
dev->hard_start_xmit = rtl8169_start_xmit;
diff --git a/drivers/net/rionet.c b/drivers/net/rionet.c
new file mode 100644
index 000000000000..12cde0604580
--- /dev/null
+++ b/drivers/net/rionet.c
@@ -0,0 +1,574 @@
+/*
+ * rionet - Ethernet driver over RapidIO messaging services
+ *
+ * Copyright 2005 MontaVista Software, Inc.
+ * Matt Porter <mporter@kernel.crashing.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/module.h>
+#include <linux/kernel.h>
+#include <linux/dma-mapping.h>
+#include <linux/delay.h>
+#include <linux/rio.h>
+#include <linux/rio_drv.h>
+#include <linux/rio_ids.h>
+
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/crc32.h>
+#include <linux/ethtool.h>
+
+#define DRV_NAME "rionet"
+#define DRV_VERSION "0.2"
+#define DRV_AUTHOR "Matt Porter <mporter@kernel.crashing.org>"
+#define DRV_DESC "Ethernet over RapidIO"
+
+MODULE_AUTHOR(DRV_AUTHOR);
+MODULE_DESCRIPTION(DRV_DESC);
+MODULE_LICENSE("GPL");
+
+#define RIONET_DEFAULT_MSGLEVEL \
+ (NETIF_MSG_DRV | \
+ NETIF_MSG_LINK | \
+ NETIF_MSG_RX_ERR | \
+ NETIF_MSG_TX_ERR)
+
+#define RIONET_DOORBELL_JOIN 0x1000
+#define RIONET_DOORBELL_LEAVE 0x1001
+
+#define RIONET_MAILBOX 0
+
+#define RIONET_TX_RING_SIZE CONFIG_RIONET_TX_SIZE
+#define RIONET_RX_RING_SIZE CONFIG_RIONET_RX_SIZE
+
+static LIST_HEAD(rionet_peers);
+
+struct rionet_private {
+ struct rio_mport *mport;
+ struct sk_buff *rx_skb[RIONET_RX_RING_SIZE];
+ struct sk_buff *tx_skb[RIONET_TX_RING_SIZE];
+ struct net_device_stats stats;
+ int rx_slot;
+ int tx_slot;
+ int tx_cnt;
+ int ack_slot;
+ spinlock_t lock;
+ spinlock_t tx_lock;
+ u32 msg_enable;
+};
+
+struct rionet_peer {
+ struct list_head node;
+ struct rio_dev *rdev;
+ struct resource *res;
+};
+
+static int rionet_check = 0;
+static int rionet_capable = 1;
+
+/*
+ * This is a fast lookup table for for translating TX
+ * Ethernet packets into a destination RIO device. It
+ * could be made into a hash table to save memory depending
+ * on system trade-offs.
+ */
+static struct rio_dev *rionet_active[RIO_MAX_ROUTE_ENTRIES];
+
+#define is_rionet_capable(pef, src_ops, dst_ops) \
+ ((pef & RIO_PEF_INB_MBOX) && \
+ (pef & RIO_PEF_INB_DOORBELL) && \
+ (src_ops & RIO_SRC_OPS_DOORBELL) && \
+ (dst_ops & RIO_DST_OPS_DOORBELL))
+#define dev_rionet_capable(dev) \
+ is_rionet_capable(dev->pef, dev->src_ops, dev->dst_ops)
+
+#define RIONET_MAC_MATCH(x) (*(u32 *)x == 0x00010001)
+#define RIONET_GET_DESTID(x) (*(u16 *)(x + 4))
+
+static struct net_device_stats *rionet_stats(struct net_device *ndev)
+{
+ struct rionet_private *rnet = ndev->priv;
+ return &rnet->stats;
+}
+
+static int rionet_rx_clean(struct net_device *ndev)
+{
+ int i;
+ int error = 0;
+ struct rionet_private *rnet = ndev->priv;
+ void *data;
+
+ i = rnet->rx_slot;
+
+ do {
+ if (!rnet->rx_skb[i])
+ continue;
+
+ if (!(data = rio_get_inb_message(rnet->mport, RIONET_MAILBOX)))
+ break;
+
+ rnet->rx_skb[i]->data = data;
+ skb_put(rnet->rx_skb[i], RIO_MAX_MSG_SIZE);
+ rnet->rx_skb[i]->dev = ndev;
+ rnet->rx_skb[i]->protocol =
+ eth_type_trans(rnet->rx_skb[i], ndev);
+ error = netif_rx(rnet->rx_skb[i]);
+
+ if (error == NET_RX_DROP) {
+ rnet->stats.rx_dropped++;
+ } else if (error == NET_RX_BAD) {
+ if (netif_msg_rx_err(rnet))
+ printk(KERN_WARNING "%s: bad rx packet\n",
+ DRV_NAME);
+ rnet->stats.rx_errors++;
+ } else {
+ rnet->stats.rx_packets++;
+ rnet->stats.rx_bytes += RIO_MAX_MSG_SIZE;
+ }
+
+ } while ((i = (i + 1) % RIONET_RX_RING_SIZE) != rnet->rx_slot);
+
+ return i;
+}
+
+static void rionet_rx_fill(struct net_device *ndev, int end)
+{
+ int i;
+ struct rionet_private *rnet = ndev->priv;
+
+ i = rnet->rx_slot;
+ do {
+ rnet->rx_skb[i] = dev_alloc_skb(RIO_MAX_MSG_SIZE);
+
+ if (!rnet->rx_skb[i])
+ break;
+
+ rio_add_inb_buffer(rnet->mport, RIONET_MAILBOX,
+ rnet->rx_skb[i]->data);
+ } while ((i = (i + 1) % RIONET_RX_RING_SIZE) != end);
+
+ rnet->rx_slot = i;
+}
+
+static int rionet_queue_tx_msg(struct sk_buff *skb, struct net_device *ndev,
+ struct rio_dev *rdev)
+{
+ struct rionet_private *rnet = ndev->priv;
+
+ rio_add_outb_message(rnet->mport, rdev, 0, skb->data, skb->len);
+ rnet->tx_skb[rnet->tx_slot] = skb;
+
+ rnet->stats.tx_packets++;
+ rnet->stats.tx_bytes += skb->len;
+
+ if (++rnet->tx_cnt == RIONET_TX_RING_SIZE)
+ netif_stop_queue(ndev);
+
+ ++rnet->tx_slot;
+ rnet->tx_slot &= (RIONET_TX_RING_SIZE - 1);
+
+ if (netif_msg_tx_queued(rnet))
+ printk(KERN_INFO "%s: queued skb %8.8x len %8.8x\n", DRV_NAME,
+ (u32) skb, skb->len);
+
+ return 0;
+}
+
+static int rionet_start_xmit(struct sk_buff *skb, struct net_device *ndev)
+{
+ int i;
+ struct rionet_private *rnet = ndev->priv;
+ struct ethhdr *eth = (struct ethhdr *)skb->data;
+ u16 destid;
+ unsigned long flags;
+
+ local_irq_save(flags);
+ if (!spin_trylock(&rnet->tx_lock)) {
+ local_irq_restore(flags);
+ return NETDEV_TX_LOCKED;
+ }
+
+ if ((rnet->tx_cnt + 1) > RIONET_TX_RING_SIZE) {
+ netif_stop_queue(ndev);
+ spin_unlock_irqrestore(&rnet->tx_lock, flags);
+ printk(KERN_ERR "%s: BUG! Tx Ring full when queue awake!\n",
+ ndev->name);
+ return NETDEV_TX_BUSY;
+ }
+
+ if (eth->h_dest[0] & 0x01) {
+ for (i = 0; i < RIO_MAX_ROUTE_ENTRIES; i++)
+ if (rionet_active[i])
+ rionet_queue_tx_msg(skb, ndev,
+ rionet_active[i]);
+ } else if (RIONET_MAC_MATCH(eth->h_dest)) {
+ destid = RIONET_GET_DESTID(eth->h_dest);
+ if (rionet_active[destid])
+ rionet_queue_tx_msg(skb, ndev, rionet_active[destid]);
+ }
+
+ spin_unlock_irqrestore(&rnet->tx_lock, flags);
+
+ return 0;
+}
+
+static void rionet_dbell_event(struct rio_mport *mport, void *dev_id, u16 sid, u16 tid,
+ u16 info)
+{
+ struct net_device *ndev = dev_id;
+ struct rionet_private *rnet = ndev->priv;
+ struct rionet_peer *peer;
+
+ if (netif_msg_intr(rnet))
+ printk(KERN_INFO "%s: doorbell sid %4.4x tid %4.4x info %4.4x",
+ DRV_NAME, sid, tid, info);
+ if (info == RIONET_DOORBELL_JOIN) {
+ if (!rionet_active[sid]) {
+ list_for_each_entry(peer, &rionet_peers, node) {
+ if (peer->rdev->destid == sid)
+ rionet_active[sid] = peer->rdev;
+ }
+ rio_mport_send_doorbell(mport, sid,
+ RIONET_DOORBELL_JOIN);
+ }
+ } else if (info == RIONET_DOORBELL_LEAVE) {
+ rionet_active[sid] = NULL;
+ } else {
+ if (netif_msg_intr(rnet))
+ printk(KERN_WARNING "%s: unhandled doorbell\n",
+ DRV_NAME);
+ }
+}
+
+static void rionet_inb_msg_event(struct rio_mport *mport, void *dev_id, int mbox, int slot)
+{
+ int n;
+ struct net_device *ndev = dev_id;
+ struct rionet_private *rnet = (struct rionet_private *)ndev->priv;
+
+ if (netif_msg_intr(rnet))
+ printk(KERN_INFO "%s: inbound message event, mbox %d slot %d\n",
+ DRV_NAME, mbox, slot);
+
+ spin_lock(&rnet->lock);
+ if ((n = rionet_rx_clean(ndev)) != rnet->rx_slot)
+ rionet_rx_fill(ndev, n);
+ spin_unlock(&rnet->lock);
+}
+
+static void rionet_outb_msg_event(struct rio_mport *mport, void *dev_id, int mbox, int slot)
+{
+ struct net_device *ndev = dev_id;
+ struct rionet_private *rnet = ndev->priv;
+
+ spin_lock(&rnet->lock);
+
+ if (netif_msg_intr(rnet))
+ printk(KERN_INFO
+ "%s: outbound message event, mbox %d slot %d\n",
+ DRV_NAME, mbox, slot);
+
+ while (rnet->tx_cnt && (rnet->ack_slot != slot)) {
+ /* dma unmap single */
+ dev_kfree_skb_irq(rnet->tx_skb[rnet->ack_slot]);
+ rnet->tx_skb[rnet->ack_slot] = NULL;
+ ++rnet->ack_slot;
+ rnet->ack_slot &= (RIONET_TX_RING_SIZE - 1);
+ rnet->tx_cnt--;
+ }
+
+ if (rnet->tx_cnt < RIONET_TX_RING_SIZE)
+ netif_wake_queue(ndev);
+
+ spin_unlock(&rnet->lock);
+}
+
+static int rionet_open(struct net_device *ndev)
+{
+ int i, rc = 0;
+ struct rionet_peer *peer, *tmp;
+ u32 pwdcsr;
+ struct rionet_private *rnet = ndev->priv;
+
+ if (netif_msg_ifup(rnet))
+ printk(KERN_INFO "%s: open\n", DRV_NAME);
+
+ if ((rc = rio_request_inb_dbell(rnet->mport,
+ (void *)ndev,
+ RIONET_DOORBELL_JOIN,
+ RIONET_DOORBELL_LEAVE,
+ rionet_dbell_event)) < 0)
+ goto out;
+
+ if ((rc = rio_request_inb_mbox(rnet->mport,
+ (void *)ndev,
+ RIONET_MAILBOX,
+ RIONET_RX_RING_SIZE,
+ rionet_inb_msg_event)) < 0)
+ goto out;
+
+ if ((rc = rio_request_outb_mbox(rnet->mport,
+ (void *)ndev,
+ RIONET_MAILBOX,
+ RIONET_TX_RING_SIZE,
+ rionet_outb_msg_event)) < 0)
+ goto out;
+
+ /* Initialize inbound message ring */
+ for (i = 0; i < RIONET_RX_RING_SIZE; i++)
+ rnet->rx_skb[i] = NULL;
+ rnet->rx_slot = 0;
+ rionet_rx_fill(ndev, 0);
+
+ rnet->tx_slot = 0;
+ rnet->tx_cnt = 0;
+ rnet->ack_slot = 0;
+
+ netif_carrier_on(ndev);
+ netif_start_queue(ndev);
+
+ list_for_each_entry_safe(peer, tmp, &rionet_peers, node) {
+ if (!(peer->res = rio_request_outb_dbell(peer->rdev,
+ RIONET_DOORBELL_JOIN,
+ RIONET_DOORBELL_LEAVE)))
+ {
+ printk(KERN_ERR "%s: error requesting doorbells\n",
+ DRV_NAME);
+ continue;
+ }
+
+ /*
+ * If device has initialized inbound doorbells,
+ * send a join message
+ */
+ rio_read_config_32(peer->rdev, RIO_WRITE_PORT_CSR, &pwdcsr);
+ if (pwdcsr & RIO_DOORBELL_AVAIL)
+ rio_send_doorbell(peer->rdev, RIONET_DOORBELL_JOIN);
+ }
+
+ out:
+ return rc;
+}
+
+static int rionet_close(struct net_device *ndev)
+{
+ struct rionet_private *rnet = (struct rionet_private *)ndev->priv;
+ struct rionet_peer *peer, *tmp;
+ int i;
+
+ if (netif_msg_ifup(rnet))
+ printk(KERN_INFO "%s: close\n", DRV_NAME);
+
+ netif_stop_queue(ndev);
+ netif_carrier_off(ndev);
+
+ for (i = 0; i < RIONET_RX_RING_SIZE; i++)
+ if (rnet->rx_skb[i])
+ kfree_skb(rnet->rx_skb[i]);
+
+ list_for_each_entry_safe(peer, tmp, &rionet_peers, node) {
+ if (rionet_active[peer->rdev->destid]) {
+ rio_send_doorbell(peer->rdev, RIONET_DOORBELL_LEAVE);
+ rionet_active[peer->rdev->destid] = NULL;
+ }
+ rio_release_outb_dbell(peer->rdev, peer->res);
+ }
+
+ rio_release_inb_dbell(rnet->mport, RIONET_DOORBELL_JOIN,
+ RIONET_DOORBELL_LEAVE);
+ rio_release_inb_mbox(rnet->mport, RIONET_MAILBOX);
+ rio_release_outb_mbox(rnet->mport, RIONET_MAILBOX);
+
+ return 0;
+}
+
+static void rionet_remove(struct rio_dev *rdev)
+{
+ struct net_device *ndev = NULL;
+ struct rionet_peer *peer, *tmp;
+
+ unregister_netdev(ndev);
+ kfree(ndev);
+
+ list_for_each_entry_safe(peer, tmp, &rionet_peers, node) {
+ list_del(&peer->node);
+ kfree(peer);
+ }
+}
+
+static void rionet_get_drvinfo(struct net_device *ndev,
+ struct ethtool_drvinfo *info)
+{
+ struct rionet_private *rnet = ndev->priv;
+
+ strcpy(info->driver, DRV_NAME);
+ strcpy(info->version, DRV_VERSION);
+ strcpy(info->fw_version, "n/a");
+ strcpy(info->bus_info, rnet->mport->name);
+}
+
+static u32 rionet_get_msglevel(struct net_device *ndev)
+{
+ struct rionet_private *rnet = ndev->priv;
+
+ return rnet->msg_enable;
+}
+
+static void rionet_set_msglevel(struct net_device *ndev, u32 value)
+{
+ struct rionet_private *rnet = ndev->priv;
+
+ rnet->msg_enable = value;
+}
+
+static struct ethtool_ops rionet_ethtool_ops = {
+ .get_drvinfo = rionet_get_drvinfo,
+ .get_msglevel = rionet_get_msglevel,
+ .set_msglevel = rionet_set_msglevel,
+ .get_link = ethtool_op_get_link,
+};
+
+static int rionet_setup_netdev(struct rio_mport *mport)
+{
+ int rc = 0;
+ struct net_device *ndev = NULL;
+ struct rionet_private *rnet;
+ u16 device_id;
+
+ /* Allocate our net_device structure */
+ ndev = alloc_etherdev(sizeof(struct rionet_private));
+ if (ndev == NULL) {
+ printk(KERN_INFO "%s: could not allocate ethernet device.\n",
+ DRV_NAME);
+ rc = -ENOMEM;
+ goto out;
+ }
+
+ /* Set up private area */
+ rnet = (struct rionet_private *)ndev->priv;
+ rnet->mport = mport;
+
+ /* Set the default MAC address */
+ device_id = rio_local_get_device_id(mport);
+ ndev->dev_addr[0] = 0x00;
+ ndev->dev_addr[1] = 0x01;
+ ndev->dev_addr[2] = 0x00;
+ ndev->dev_addr[3] = 0x01;
+ 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->get_stats = &rionet_stats;
+ ndev->mtu = RIO_MAX_MSG_SIZE - 14;
+ ndev->features = NETIF_F_LLTX;
+ SET_ETHTOOL_OPS(ndev, &rionet_ethtool_ops);
+
+ SET_MODULE_OWNER(ndev);
+
+ spin_lock_init(&rnet->lock);
+ spin_lock_init(&rnet->tx_lock);
+
+ rnet->msg_enable = RIONET_DEFAULT_MSGLEVEL;
+
+ rc = register_netdev(ndev);
+ if (rc != 0)
+ goto out;
+
+ printk("%s: %s %s Version %s, MAC %02x:%02x:%02x:%02x:%02x:%02x\n",
+ ndev->name,
+ DRV_NAME,
+ DRV_DESC,
+ DRV_VERSION,
+ ndev->dev_addr[0], ndev->dev_addr[1], ndev->dev_addr[2],
+ ndev->dev_addr[3], ndev->dev_addr[4], ndev->dev_addr[5]);
+
+ out:
+ return rc;
+}
+
+/*
+ * XXX Make multi-net safe
+ */
+static int rionet_probe(struct rio_dev *rdev, const struct rio_device_id *id)
+{
+ int rc = -ENODEV;
+ u32 lpef, lsrc_ops, ldst_ops;
+ struct rionet_peer *peer;
+
+ /* If local device is not rionet capable, give up quickly */
+ if (!rionet_capable)
+ goto out;
+
+ /*
+ * First time through, make sure local device is rionet
+ * capable, setup netdev, and set flags so this is skipped
+ * on later probes
+ */
+ if (!rionet_check) {
+ rio_local_read_config_32(rdev->net->hport, RIO_PEF_CAR, &lpef);
+ rio_local_read_config_32(rdev->net->hport, RIO_SRC_OPS_CAR,
+ &lsrc_ops);
+ rio_local_read_config_32(rdev->net->hport, RIO_DST_OPS_CAR,
+ &ldst_ops);
+ if (!is_rionet_capable(lpef, lsrc_ops, ldst_ops)) {
+ printk(KERN_ERR
+ "%s: local device is not network capable\n",
+ DRV_NAME);
+ rionet_check = 1;
+ rionet_capable = 0;
+ goto out;
+ }
+
+ rc = rionet_setup_netdev(rdev->net->hport);
+ rionet_check = 1;
+ }
+
+ /*
+ * If the remote device has mailbox/doorbell capabilities,
+ * add it to the peer list.
+ */
+ if (dev_rionet_capable(rdev)) {
+ if (!(peer = kmalloc(sizeof(struct rionet_peer), GFP_KERNEL))) {
+ rc = -ENOMEM;
+ goto out;
+ }
+ peer->rdev = rdev;
+ list_add_tail(&peer->node, &rionet_peers);
+ }
+
+ out:
+ return rc;
+}
+
+static struct rio_device_id rionet_id_table[] = {
+ {RIO_DEVICE(RIO_ANY_ID, RIO_ANY_ID)}
+};
+
+static struct rio_driver rionet_driver = {
+ .name = "rionet",
+ .id_table = rionet_id_table,
+ .probe = rionet_probe,
+ .remove = rionet_remove,
+};
+
+static int __init rionet_init(void)
+{
+ return rio_register_driver(&rionet_driver);
+}
+
+static void __exit rionet_exit(void)
+{
+ rio_unregister_driver(&rionet_driver);
+}
+
+module_init(rionet_init);
+module_exit(rionet_exit);
diff --git a/drivers/net/rrunner.c b/drivers/net/rrunner.c
index ec1a18d189a1..19c2df9c86fe 100644
--- a/drivers/net/rrunner.c
+++ b/drivers/net/rrunner.c
@@ -1710,10 +1710,8 @@ static int rr_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
error = -EFAULT;
}
wf_out:
- if (oldimage)
- kfree(oldimage);
- if (image)
- kfree(image);
+ kfree(oldimage);
+ kfree(image);
return error;
case SIOCRRID:
diff --git a/drivers/net/s2io-regs.h b/drivers/net/s2io-regs.h
index 7cefe5507b9e..00179bc3437f 100644
--- a/drivers/net/s2io-regs.h
+++ b/drivers/net/s2io-regs.h
@@ -814,6 +814,17 @@ typedef struct _XENA_dev_config {
u64 rxgxs_ber_0; /* CHANGED */
u64 rxgxs_ber_1; /* CHANGED */
+ u64 spi_control;
+#define SPI_CONTROL_KEY(key) vBIT(key,0,4)
+#define SPI_CONTROL_BYTECNT(cnt) vBIT(cnt,29,3)
+#define SPI_CONTROL_CMD(cmd) vBIT(cmd,32,8)
+#define SPI_CONTROL_ADDR(addr) vBIT(addr,40,24)
+#define SPI_CONTROL_SEL1 BIT(4)
+#define SPI_CONTROL_REQ BIT(7)
+#define SPI_CONTROL_NACK BIT(5)
+#define SPI_CONTROL_DONE BIT(6)
+ u64 spi_data;
+#define SPI_DATA_WRITE(data,len) vBIT(data,0,len)
} XENA_dev_config_t;
#define XENA_REG_SPACE sizeof(XENA_dev_config_t)
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c
index dd451e099a4c..e57df8dfe6b4 100644
--- a/drivers/net/s2io.c
+++ b/drivers/net/s2io.c
@@ -30,6 +30,8 @@
* in the driver.
* rx_ring_sz: This defines the number of descriptors each ring can have. This
* is also an array of size 8.
+ * rx_ring_mode: This defines the operation mode of all 8 rings. The valid
+ * values are 1, 2 and 3.
* tx_fifo_num: This defines the number of Tx FIFOs thats used int the driver.
* tx_fifo_len: This too is an array of 8. Each element defines the number of
* Tx descriptors that can be associated with each corresponding FIFO.
@@ -53,7 +55,6 @@
#include <linux/timex.h>
#include <linux/sched.h>
#include <linux/ethtool.h>
-#include <linux/version.h>
#include <linux/workqueue.h>
#include <linux/if_vlan.h>
@@ -65,9 +66,14 @@
#include "s2io.h"
#include "s2io-regs.h"
+#define DRV_VERSION "Version 2.0.9.3"
+
/* S2io Driver name & version. */
static char s2io_driver_name[] = "Neterion";
-static char s2io_driver_version[] = "Version 2.0.8.1";
+static char s2io_driver_version[] = DRV_VERSION;
+
+int rxd_size[4] = {32,48,48,64};
+int rxd_count[4] = {127,85,85,63};
static inline int RXD_IS_UP2DT(RxD_t *rxdp)
{
@@ -102,7 +108,7 @@ static inline int rx_buffer_level(nic_t * sp, int rxb_size, int ring)
mac_control = &sp->mac_control;
if ((mac_control->rings[ring].pkt_cnt - rxb_size) > 16) {
level = LOW;
- if (rxb_size <= MAX_RXDS_PER_BLOCK) {
+ if (rxb_size <= rxd_count[sp->rxd_mode]) {
level = PANIC;
}
}
@@ -294,6 +300,7 @@ static unsigned int rx_ring_sz[MAX_RX_RINGS] =
{[0 ...(MAX_RX_RINGS - 1)] = 0 };
static unsigned int rts_frm_len[MAX_RX_RINGS] =
{[0 ...(MAX_RX_RINGS - 1)] = 0 };
+static unsigned int rx_ring_mode = 1;
static unsigned int use_continuous_tx_intrs = 1;
static unsigned int rmac_pause_time = 65535;
static unsigned int mc_pause_threshold_q0q3 = 187;
@@ -302,11 +309,14 @@ static unsigned int shared_splits;
static unsigned int tmac_util_period = 5;
static unsigned int rmac_util_period = 5;
static unsigned int bimodal = 0;
+static unsigned int l3l4hdr_size = 128;
#ifndef CONFIG_S2IO_NAPI
static unsigned int indicate_max_pkts;
#endif
/* Frequency of Rx desc syncs expressed as power of 2 */
static unsigned int rxsync_frequency = 3;
+/* Interrupt type. Values can be 0(INTA), 1(MSI), 2(MSI_X) */
+static unsigned int intr_type = 0;
/*
* S2IO device table.
@@ -353,10 +363,8 @@ static int init_shared_mem(struct s2io_nic *nic)
int i, j, blk_cnt, rx_sz, tx_sz;
int lst_size, lst_per_page;
struct net_device *dev = nic->dev;
-#ifdef CONFIG_2BUFF_MODE
unsigned long tmp;
buffAdd_t *ba;
-#endif
mac_info_t *mac_control;
struct config_param *config;
@@ -454,7 +462,8 @@ static int init_shared_mem(struct s2io_nic *nic)
/* Allocation and initialization of RXDs in Rings */
size = 0;
for (i = 0; i < config->rx_ring_num; i++) {
- if (config->rx_cfg[i].num_rxd % (MAX_RXDS_PER_BLOCK + 1)) {
+ if (config->rx_cfg[i].num_rxd %
+ (rxd_count[nic->rxd_mode] + 1)) {
DBG_PRINT(ERR_DBG, "%s: RxD count of ", dev->name);
DBG_PRINT(ERR_DBG, "Ring%d is not a multiple of ",
i);
@@ -463,11 +472,15 @@ static int init_shared_mem(struct s2io_nic *nic)
}
size += config->rx_cfg[i].num_rxd;
mac_control->rings[i].block_count =
- config->rx_cfg[i].num_rxd / (MAX_RXDS_PER_BLOCK + 1);
- mac_control->rings[i].pkt_cnt =
- config->rx_cfg[i].num_rxd - mac_control->rings[i].block_count;
+ config->rx_cfg[i].num_rxd /
+ (rxd_count[nic->rxd_mode] + 1 );
+ mac_control->rings[i].pkt_cnt = config->rx_cfg[i].num_rxd -
+ mac_control->rings[i].block_count;
}
- size = (size * (sizeof(RxD_t)));
+ if (nic->rxd_mode == RXD_MODE_1)
+ size = (size * (sizeof(RxD1_t)));
+ else
+ size = (size * (sizeof(RxD3_t)));
rx_sz = size;
for (i = 0; i < config->rx_ring_num; i++) {
@@ -482,15 +495,15 @@ static int init_shared_mem(struct s2io_nic *nic)
mac_control->rings[i].nic = nic;
mac_control->rings[i].ring_no = i;
- blk_cnt =
- config->rx_cfg[i].num_rxd / (MAX_RXDS_PER_BLOCK + 1);
+ blk_cnt = config->rx_cfg[i].num_rxd /
+ (rxd_count[nic->rxd_mode] + 1);
/* Allocating all the Rx blocks */
for (j = 0; j < blk_cnt; j++) {
-#ifndef CONFIG_2BUFF_MODE
- size = (MAX_RXDS_PER_BLOCK + 1) * (sizeof(RxD_t));
-#else
- size = SIZE_OF_BLOCK;
-#endif
+ rx_block_info_t *rx_blocks;
+ int l;
+
+ rx_blocks = &mac_control->rings[i].rx_blocks[j];
+ size = SIZE_OF_BLOCK; //size is always page size
tmp_v_addr = pci_alloc_consistent(nic->pdev, size,
&tmp_p_addr);
if (tmp_v_addr == NULL) {
@@ -500,11 +513,24 @@ static int init_shared_mem(struct s2io_nic *nic)
* memory that was alloced till the
* failure happened.
*/
- mac_control->rings[i].rx_blocks[j].block_virt_addr =
- tmp_v_addr;
+ rx_blocks->block_virt_addr = tmp_v_addr;
return -ENOMEM;
}
memset(tmp_v_addr, 0, size);
+ rx_blocks->block_virt_addr = tmp_v_addr;
+ rx_blocks->block_dma_addr = tmp_p_addr;
+ rx_blocks->rxds = kmalloc(sizeof(rxd_info_t)*
+ rxd_count[nic->rxd_mode],
+ GFP_KERNEL);
+ for (l=0; l<rxd_count[nic->rxd_mode];l++) {
+ rx_blocks->rxds[l].virt_addr =
+ rx_blocks->block_virt_addr +
+ (rxd_size[nic->rxd_mode] * l);
+ rx_blocks->rxds[l].dma_addr =
+ rx_blocks->block_dma_addr +
+ (rxd_size[nic->rxd_mode] * l);
+ }
+
mac_control->rings[i].rx_blocks[j].block_virt_addr =
tmp_v_addr;
mac_control->rings[i].rx_blocks[j].block_dma_addr =
@@ -524,62 +550,58 @@ static int init_shared_mem(struct s2io_nic *nic)
blk_cnt].block_dma_addr;
pre_rxd_blk = (RxD_block_t *) tmp_v_addr;
- pre_rxd_blk->reserved_1 = END_OF_BLOCK; /* last RxD
- * marker.
- */
-#ifndef CONFIG_2BUFF_MODE
pre_rxd_blk->reserved_2_pNext_RxD_block =
(unsigned long) tmp_v_addr_next;
-#endif
pre_rxd_blk->pNext_RxD_Blk_physical =
(u64) tmp_p_addr_next;
}
}
-
-#ifdef CONFIG_2BUFF_MODE
- /*
- * Allocation of Storages for buffer addresses in 2BUFF mode
- * and the buffers as well.
- */
- for (i = 0; i < config->rx_ring_num; i++) {
- blk_cnt =
- config->rx_cfg[i].num_rxd / (MAX_RXDS_PER_BLOCK + 1);
- mac_control->rings[i].ba = kmalloc((sizeof(buffAdd_t *) * blk_cnt),
+ if (nic->rxd_mode >= RXD_MODE_3A) {
+ /*
+ * Allocation of Storages for buffer addresses in 2BUFF mode
+ * and the buffers as well.
+ */
+ for (i = 0; i < config->rx_ring_num; i++) {
+ blk_cnt = config->rx_cfg[i].num_rxd /
+ (rxd_count[nic->rxd_mode]+ 1);
+ mac_control->rings[i].ba =
+ kmalloc((sizeof(buffAdd_t *) * blk_cnt),
GFP_KERNEL);
- if (!mac_control->rings[i].ba)
- return -ENOMEM;
- for (j = 0; j < blk_cnt; j++) {
- int k = 0;
- mac_control->rings[i].ba[j] = kmalloc((sizeof(buffAdd_t) *
- (MAX_RXDS_PER_BLOCK + 1)),
- GFP_KERNEL);
- if (!mac_control->rings[i].ba[j])
+ if (!mac_control->rings[i].ba)
return -ENOMEM;
- while (k != MAX_RXDS_PER_BLOCK) {
- ba = &mac_control->rings[i].ba[j][k];
-
- ba->ba_0_org = (void *) kmalloc
- (BUF0_LEN + ALIGN_SIZE, GFP_KERNEL);
- if (!ba->ba_0_org)
- return -ENOMEM;
- tmp = (unsigned long) ba->ba_0_org;
- tmp += ALIGN_SIZE;
- tmp &= ~((unsigned long) ALIGN_SIZE);
- ba->ba_0 = (void *) tmp;
-
- ba->ba_1_org = (void *) kmalloc
- (BUF1_LEN + ALIGN_SIZE, GFP_KERNEL);
- if (!ba->ba_1_org)
+ for (j = 0; j < blk_cnt; j++) {
+ int k = 0;
+ mac_control->rings[i].ba[j] =
+ kmalloc((sizeof(buffAdd_t) *
+ (rxd_count[nic->rxd_mode] + 1)),
+ GFP_KERNEL);
+ if (!mac_control->rings[i].ba[j])
return -ENOMEM;
- tmp = (unsigned long) ba->ba_1_org;
- tmp += ALIGN_SIZE;
- tmp &= ~((unsigned long) ALIGN_SIZE);
- ba->ba_1 = (void *) tmp;
- k++;
+ while (k != rxd_count[nic->rxd_mode]) {
+ ba = &mac_control->rings[i].ba[j][k];
+
+ ba->ba_0_org = (void *) kmalloc
+ (BUF0_LEN + ALIGN_SIZE, GFP_KERNEL);
+ if (!ba->ba_0_org)
+ return -ENOMEM;
+ tmp = (unsigned long)ba->ba_0_org;
+ tmp += ALIGN_SIZE;
+ tmp &= ~((unsigned long) ALIGN_SIZE);
+ ba->ba_0 = (void *) tmp;
+
+ ba->ba_1_org = (void *) kmalloc
+ (BUF1_LEN + ALIGN_SIZE, GFP_KERNEL);
+ if (!ba->ba_1_org)
+ return -ENOMEM;
+ tmp = (unsigned long) ba->ba_1_org;
+ tmp += ALIGN_SIZE;
+ tmp &= ~((unsigned long) ALIGN_SIZE);
+ ba->ba_1 = (void *) tmp;
+ k++;
+ }
}
}
}
-#endif
/* Allocation and initialization of Statistics block */
size = sizeof(StatInfo_t);
@@ -665,11 +687,7 @@ static void free_shared_mem(struct s2io_nic *nic)
kfree(mac_control->fifos[i].list_info);
}
-#ifndef CONFIG_2BUFF_MODE
- size = (MAX_RXDS_PER_BLOCK + 1) * (sizeof(RxD_t));
-#else
size = SIZE_OF_BLOCK;
-#endif
for (i = 0; i < config->rx_ring_num; i++) {
blk_cnt = mac_control->rings[i].block_count;
for (j = 0; j < blk_cnt; j++) {
@@ -681,30 +699,31 @@ static void free_shared_mem(struct s2io_nic *nic)
break;
pci_free_consistent(nic->pdev, size,
tmp_v_addr, tmp_p_addr);
+ kfree(mac_control->rings[i].rx_blocks[j].rxds);
}
}
-#ifdef CONFIG_2BUFF_MODE
- /* Freeing buffer storage addresses in 2BUFF mode. */
- for (i = 0; i < config->rx_ring_num; i++) {
- blk_cnt =
- config->rx_cfg[i].num_rxd / (MAX_RXDS_PER_BLOCK + 1);
- for (j = 0; j < blk_cnt; j++) {
- int k = 0;
- if (!mac_control->rings[i].ba[j])
- continue;
- while (k != MAX_RXDS_PER_BLOCK) {
- buffAdd_t *ba = &mac_control->rings[i].ba[j][k];
- kfree(ba->ba_0_org);
- kfree(ba->ba_1_org);
- k++;
+ if (nic->rxd_mode >= RXD_MODE_3A) {
+ /* Freeing buffer storage addresses in 2BUFF mode. */
+ for (i = 0; i < config->rx_ring_num; i++) {
+ blk_cnt = config->rx_cfg[i].num_rxd /
+ (rxd_count[nic->rxd_mode] + 1);
+ for (j = 0; j < blk_cnt; j++) {
+ int k = 0;
+ if (!mac_control->rings[i].ba[j])
+ continue;
+ while (k != rxd_count[nic->rxd_mode]) {
+ buffAdd_t *ba =
+ &mac_control->rings[i].ba[j][k];
+ kfree(ba->ba_0_org);
+ kfree(ba->ba_1_org);
+ k++;
+ }
+ kfree(mac_control->rings[i].ba[j]);
}
- kfree(mac_control->rings[i].ba[j]);
- }
- if (mac_control->rings[i].ba)
kfree(mac_control->rings[i].ba);
+ }
}
-#endif
if (mac_control->stats_mem) {
pci_free_consistent(nic->pdev,
@@ -1396,8 +1415,13 @@ static int init_nic(struct s2io_nic *nic)
writeq(val64, &bar0->rti_data1_mem);
val64 = RTI_DATA2_MEM_RX_UFC_A(0x1) |
- RTI_DATA2_MEM_RX_UFC_B(0x2) |
- RTI_DATA2_MEM_RX_UFC_C(0x40) | RTI_DATA2_MEM_RX_UFC_D(0x80);
+ RTI_DATA2_MEM_RX_UFC_B(0x2) ;
+ if (nic->intr_type == MSI_X)
+ val64 |= (RTI_DATA2_MEM_RX_UFC_C(0x20) | \
+ RTI_DATA2_MEM_RX_UFC_D(0x40));
+ else
+ val64 |= (RTI_DATA2_MEM_RX_UFC_C(0x40) | \
+ RTI_DATA2_MEM_RX_UFC_D(0x80));
writeq(val64, &bar0->rti_data2_mem);
for (i = 0; i < config->rx_ring_num; i++) {
@@ -1507,17 +1531,15 @@ static int init_nic(struct s2io_nic *nic)
#define LINK_UP_DOWN_INTERRUPT 1
#define MAC_RMAC_ERR_TIMER 2
-#if defined(CONFIG_MSI_MODE) || defined(CONFIG_MSIX_MODE)
-#define s2io_link_fault_indication(x) MAC_RMAC_ERR_TIMER
-#else
-int s2io_link_fault_indication(nic_t *nic)
+static int s2io_link_fault_indication(nic_t *nic)
{
+ if (nic->intr_type != INTA)
+ return MAC_RMAC_ERR_TIMER;
if (nic->device_type == XFRAME_II_DEVICE)
return LINK_UP_DOWN_INTERRUPT;
else
return MAC_RMAC_ERR_TIMER;
}
-#endif
/**
* en_dis_able_nic_intrs - Enable or Disable the interrupts
@@ -1841,7 +1863,7 @@ static int verify_xena_quiescence(nic_t *sp, u64 val64, int flag)
*
*/
-void fix_mac_address(nic_t * sp)
+static void fix_mac_address(nic_t * sp)
{
XENA_dev_config_t __iomem *bar0 = sp->bar0;
u64 val64;
@@ -1888,20 +1910,19 @@ static int start_nic(struct s2io_nic *nic)
val64 = readq(&bar0->prc_ctrl_n[i]);
if (nic->config.bimodal)
val64 |= PRC_CTRL_BIMODAL_INTERRUPT;
-#ifndef CONFIG_2BUFF_MODE
- val64 |= PRC_CTRL_RC_ENABLED;
-#else
- val64 |= PRC_CTRL_RC_ENABLED | PRC_CTRL_RING_MODE_3;
-#endif
+ if (nic->rxd_mode == RXD_MODE_1)
+ val64 |= PRC_CTRL_RC_ENABLED;
+ else
+ val64 |= PRC_CTRL_RC_ENABLED | PRC_CTRL_RING_MODE_3;
writeq(val64, &bar0->prc_ctrl_n[i]);
}
-#ifdef CONFIG_2BUFF_MODE
- /* Enabling 2 buffer mode by writing into Rx_pa_cfg reg. */
- val64 = readq(&bar0->rx_pa_cfg);
- val64 |= RX_PA_CFG_IGNORE_L2_ERR;
- writeq(val64, &bar0->rx_pa_cfg);
-#endif
+ if (nic->rxd_mode == RXD_MODE_3B) {
+ /* Enabling 2 buffer mode by writing into Rx_pa_cfg reg. */
+ val64 = readq(&bar0->rx_pa_cfg);
+ val64 |= RX_PA_CFG_IGNORE_L2_ERR;
+ writeq(val64, &bar0->rx_pa_cfg);
+ }
/*
* Enabling MC-RLDRAM. After enabling the device, we timeout
@@ -1941,11 +1962,14 @@ static int start_nic(struct s2io_nic *nic)
}
/* Enable select interrupts */
- interruptible = TX_TRAFFIC_INTR | RX_TRAFFIC_INTR;
- interruptible |= TX_PIC_INTR | RX_PIC_INTR;
- interruptible |= TX_MAC_INTR | RX_MAC_INTR;
-
- en_dis_able_nic_intrs(nic, interruptible, ENABLE_INTRS);
+ if (nic->intr_type != INTA)
+ en_dis_able_nic_intrs(nic, ENA_ALL_INTRS, DISABLE_INTRS);
+ else {
+ interruptible = TX_TRAFFIC_INTR | RX_TRAFFIC_INTR;
+ interruptible |= TX_PIC_INTR | RX_PIC_INTR;
+ interruptible |= TX_MAC_INTR | RX_MAC_INTR;
+ en_dis_able_nic_intrs(nic, interruptible, ENABLE_INTRS);
+ }
/*
* With some switches, link might be already up at this point.
@@ -2081,6 +2105,39 @@ static void stop_nic(struct s2io_nic *nic)
}
}
+int fill_rxd_3buf(nic_t *nic, RxD_t *rxdp, struct sk_buff *skb)
+{
+ struct net_device *dev = nic->dev;
+ struct sk_buff *frag_list;
+ void *tmp;
+
+ /* Buffer-1 receives L3/L4 headers */
+ ((RxD3_t*)rxdp)->Buffer1_ptr = pci_map_single
+ (nic->pdev, skb->data, l3l4hdr_size + 4,
+ PCI_DMA_FROMDEVICE);
+
+ /* skb_shinfo(skb)->frag_list will have L4 data payload */
+ skb_shinfo(skb)->frag_list = dev_alloc_skb(dev->mtu + ALIGN_SIZE);
+ if (skb_shinfo(skb)->frag_list == NULL) {
+ DBG_PRINT(ERR_DBG, "%s: dev_alloc_skb failed\n ", dev->name);
+ return -ENOMEM ;
+ }
+ frag_list = skb_shinfo(skb)->frag_list;
+ frag_list->next = NULL;
+ tmp = (void *)ALIGN((long)frag_list->data, ALIGN_SIZE + 1);
+ frag_list->data = tmp;
+ frag_list->tail = tmp;
+
+ /* Buffer-2 receives L4 data payload */
+ ((RxD3_t*)rxdp)->Buffer2_ptr = pci_map_single(nic->pdev,
+ frag_list->data, dev->mtu,
+ PCI_DMA_FROMDEVICE);
+ rxdp->Control_2 |= SET_BUFFER1_SIZE_3(l3l4hdr_size + 4);
+ rxdp->Control_2 |= SET_BUFFER2_SIZE_3(dev->mtu);
+
+ return SUCCESS;
+}
+
/**
* fill_rx_buffers - Allocates the Rx side skbs
* @nic: device private variable
@@ -2102,24 +2159,18 @@ static void stop_nic(struct s2io_nic *nic)
* SUCCESS on success or an appropriate -ve value on failure.
*/
-int fill_rx_buffers(struct s2io_nic *nic, int ring_no)
+static int fill_rx_buffers(struct s2io_nic *nic, int ring_no)
{
struct net_device *dev = nic->dev;
struct sk_buff *skb;
RxD_t *rxdp;
int off, off1, size, block_no, block_no1;
- int offset, offset1;
u32 alloc_tab = 0;
u32 alloc_cnt;
mac_info_t *mac_control;
struct config_param *config;
-#ifdef CONFIG_2BUFF_MODE
- RxD_t *rxdpnext;
- int nextblk;
u64 tmp;
buffAdd_t *ba;
- dma_addr_t rxdpphys;
-#endif
#ifndef CONFIG_S2IO_NAPI
unsigned long flags;
#endif
@@ -2129,8 +2180,6 @@ int fill_rx_buffers(struct s2io_nic *nic, int ring_no)
config = &nic->config;
alloc_cnt = mac_control->rings[ring_no].pkt_cnt -
atomic_read(&nic->rx_bufs_left[ring_no]);
- size = dev->mtu + HEADER_ETHERNET_II_802_3_SIZE +
- HEADER_802_2_SIZE + HEADER_SNAP_SIZE;
while (alloc_tab < alloc_cnt) {
block_no = mac_control->rings[ring_no].rx_curr_put_info.
@@ -2139,159 +2188,145 @@ int fill_rx_buffers(struct s2io_nic *nic, int ring_no)
block_index;
off = mac_control->rings[ring_no].rx_curr_put_info.offset;
off1 = mac_control->rings[ring_no].rx_curr_get_info.offset;
-#ifndef CONFIG_2BUFF_MODE
- offset = block_no * (MAX_RXDS_PER_BLOCK + 1) + off;
- offset1 = block_no1 * (MAX_RXDS_PER_BLOCK + 1) + off1;
-#else
- offset = block_no * (MAX_RXDS_PER_BLOCK) + off;
- offset1 = block_no1 * (MAX_RXDS_PER_BLOCK) + off1;
-#endif
- rxdp = mac_control->rings[ring_no].rx_blocks[block_no].
- block_virt_addr + off;
- if ((offset == offset1) && (rxdp->Host_Control)) {
- DBG_PRINT(INTR_DBG, "%s: Get and Put", dev->name);
+ rxdp = mac_control->rings[ring_no].
+ rx_blocks[block_no].rxds[off].virt_addr;
+
+ if ((block_no == block_no1) && (off == off1) &&
+ (rxdp->Host_Control)) {
+ DBG_PRINT(INTR_DBG, "%s: Get and Put",
+ dev->name);
DBG_PRINT(INTR_DBG, " info equated\n");
goto end;
}
-#ifndef CONFIG_2BUFF_MODE
- if (rxdp->Control_1 == END_OF_BLOCK) {
+ if (off && (off == rxd_count[nic->rxd_mode])) {
mac_control->rings[ring_no].rx_curr_put_info.
block_index++;
+ if (mac_control->rings[ring_no].rx_curr_put_info.
+ block_index == mac_control->rings[ring_no].
+ block_count)
+ mac_control->rings[ring_no].rx_curr_put_info.
+ block_index = 0;
+ block_no = mac_control->rings[ring_no].
+ rx_curr_put_info.block_index;
+ if (off == rxd_count[nic->rxd_mode])
+ off = 0;
mac_control->rings[ring_no].rx_curr_put_info.
- block_index %= mac_control->rings[ring_no].block_count;
- block_no = mac_control->rings[ring_no].rx_curr_put_info.
- block_index;
- off++;
- off %= (MAX_RXDS_PER_BLOCK + 1);
- mac_control->rings[ring_no].rx_curr_put_info.offset =
- off;
- rxdp = (RxD_t *) ((unsigned long) rxdp->Control_2);
+ offset = off;
+ rxdp = mac_control->rings[ring_no].
+ rx_blocks[block_no].block_virt_addr;
DBG_PRINT(INTR_DBG, "%s: Next block at: %p\n",
dev->name, rxdp);
}
#ifndef CONFIG_S2IO_NAPI
spin_lock_irqsave(&nic->put_lock, flags);
mac_control->rings[ring_no].put_pos =
- (block_no * (MAX_RXDS_PER_BLOCK + 1)) + off;
- spin_unlock_irqrestore(&nic->put_lock, flags);
-#endif
-#else
- if (rxdp->Host_Control == END_OF_BLOCK) {
- mac_control->rings[ring_no].rx_curr_put_info.
- block_index++;
- mac_control->rings[ring_no].rx_curr_put_info.block_index
- %= mac_control->rings[ring_no].block_count;
- block_no = mac_control->rings[ring_no].rx_curr_put_info
- .block_index;
- off = 0;
- DBG_PRINT(INTR_DBG, "%s: block%d at: 0x%llx\n",
- dev->name, block_no,
- (unsigned long long) rxdp->Control_1);
- mac_control->rings[ring_no].rx_curr_put_info.offset =
- off;
- rxdp = mac_control->rings[ring_no].rx_blocks[block_no].
- block_virt_addr;
- }
-#ifndef CONFIG_S2IO_NAPI
- spin_lock_irqsave(&nic->put_lock, flags);
- mac_control->rings[ring_no].put_pos = (block_no *
- (MAX_RXDS_PER_BLOCK + 1)) + off;
+ (block_no * (rxd_count[nic->rxd_mode] + 1)) + off;
spin_unlock_irqrestore(&nic->put_lock, flags);
#endif
-#endif
-
-#ifndef CONFIG_2BUFF_MODE
- if (rxdp->Control_1 & RXD_OWN_XENA)
-#else
- if (rxdp->Control_2 & BIT(0))
-#endif
- {
+ if ((rxdp->Control_1 & RXD_OWN_XENA) &&
+ ((nic->rxd_mode >= RXD_MODE_3A) &&
+ (rxdp->Control_2 & BIT(0)))) {
mac_control->rings[ring_no].rx_curr_put_info.
- offset = off;
+ offset = off;
goto end;
}
-#ifdef CONFIG_2BUFF_MODE
- /*
- * RxDs Spanning cache lines will be replenished only
- * if the succeeding RxD is also owned by Host. It
- * will always be the ((8*i)+3) and ((8*i)+6)
- * descriptors for the 48 byte descriptor. The offending
- * decsriptor is of-course the 3rd descriptor.
- */
- rxdpphys = mac_control->rings[ring_no].rx_blocks[block_no].
- block_dma_addr + (off * sizeof(RxD_t));
- if (((u64) (rxdpphys)) % 128 > 80) {
- rxdpnext = mac_control->rings[ring_no].rx_blocks[block_no].
- block_virt_addr + (off + 1);
- if (rxdpnext->Host_Control == END_OF_BLOCK) {
- nextblk = (block_no + 1) %
- (mac_control->rings[ring_no].block_count);
- rxdpnext = mac_control->rings[ring_no].rx_blocks
- [nextblk].block_virt_addr;
- }
- if (rxdpnext->Control_2 & BIT(0))
- goto end;
- }
-#endif
-
-#ifndef CONFIG_2BUFF_MODE
- skb = dev_alloc_skb(size + NET_IP_ALIGN);
-#else
- skb = dev_alloc_skb(dev->mtu + ALIGN_SIZE + BUF0_LEN + 4);
-#endif
- if (!skb) {
+ /* calculate size of skb based on ring mode */
+ size = dev->mtu + HEADER_ETHERNET_II_802_3_SIZE +
+ HEADER_802_2_SIZE + HEADER_SNAP_SIZE;
+ if (nic->rxd_mode == RXD_MODE_1)
+ size += NET_IP_ALIGN;
+ else if (nic->rxd_mode == RXD_MODE_3B)
+ size = dev->mtu + ALIGN_SIZE + BUF0_LEN + 4;
+ else
+ size = l3l4hdr_size + ALIGN_SIZE + BUF0_LEN + 4;
+
+ /* allocate skb */
+ skb = dev_alloc_skb(size);
+ if(!skb) {
DBG_PRINT(ERR_DBG, "%s: Out of ", dev->name);
DBG_PRINT(ERR_DBG, "memory to allocate SKBs\n");
if (first_rxdp) {
wmb();
first_rxdp->Control_1 |= RXD_OWN_XENA;
}
- return -ENOMEM;
+ return -ENOMEM ;
+ }
+ if (nic->rxd_mode == RXD_MODE_1) {
+ /* 1 buffer mode - normal operation mode */
+ memset(rxdp, 0, sizeof(RxD1_t));
+ skb_reserve(skb, NET_IP_ALIGN);
+ ((RxD1_t*)rxdp)->Buffer0_ptr = pci_map_single
+ (nic->pdev, skb->data, size, PCI_DMA_FROMDEVICE);
+ rxdp->Control_2 &= (~MASK_BUFFER0_SIZE_1);
+ rxdp->Control_2 |= SET_BUFFER0_SIZE_1(size);
+
+ } else if (nic->rxd_mode >= RXD_MODE_3A) {
+ /*
+ * 2 or 3 buffer mode -
+ * Both 2 buffer mode and 3 buffer mode provides 128
+ * byte aligned receive buffers.
+ *
+ * 3 buffer mode provides header separation where in
+ * skb->data will have L3/L4 headers where as
+ * skb_shinfo(skb)->frag_list will have the L4 data
+ * payload
+ */
+
+ memset(rxdp, 0, sizeof(RxD3_t));
+ ba = &mac_control->rings[ring_no].ba[block_no][off];
+ skb_reserve(skb, BUF0_LEN);
+ tmp = (u64)(unsigned long) skb->data;
+ tmp += ALIGN_SIZE;
+ tmp &= ~ALIGN_SIZE;
+ skb->data = (void *) (unsigned long)tmp;
+ skb->tail = (void *) (unsigned long)tmp;
+
+ ((RxD3_t*)rxdp)->Buffer0_ptr =
+ pci_map_single(nic->pdev, ba->ba_0, BUF0_LEN,
+ PCI_DMA_FROMDEVICE);
+ rxdp->Control_2 = SET_BUFFER0_SIZE_3(BUF0_LEN);
+ if (nic->rxd_mode == RXD_MODE_3B) {
+ /* Two buffer mode */
+
+ /*
+ * Buffer2 will have L3/L4 header plus
+ * L4 payload
+ */
+ ((RxD3_t*)rxdp)->Buffer2_ptr = pci_map_single
+ (nic->pdev, skb->data, dev->mtu + 4,
+ PCI_DMA_FROMDEVICE);
+
+ /* Buffer-1 will be dummy buffer not used */
+ ((RxD3_t*)rxdp)->Buffer1_ptr =
+ pci_map_single(nic->pdev, ba->ba_1, BUF1_LEN,
+ PCI_DMA_FROMDEVICE);
+ rxdp->Control_2 |= SET_BUFFER1_SIZE_3(1);
+ rxdp->Control_2 |= SET_BUFFER2_SIZE_3
+ (dev->mtu + 4);
+ } else {
+ /* 3 buffer mode */
+ if (fill_rxd_3buf(nic, rxdp, skb) == -ENOMEM) {
+ dev_kfree_skb_irq(skb);
+ if (first_rxdp) {
+ wmb();
+ first_rxdp->Control_1 |=
+ RXD_OWN_XENA;
+ }
+ return -ENOMEM ;
+ }
+ }
+ rxdp->Control_2 |= BIT(0);
}
-#ifndef CONFIG_2BUFF_MODE
- skb_reserve(skb, NET_IP_ALIGN);
- memset(rxdp, 0, sizeof(RxD_t));
- rxdp->Buffer0_ptr = pci_map_single
- (nic->pdev, skb->data, size, PCI_DMA_FROMDEVICE);
- rxdp->Control_2 &= (~MASK_BUFFER0_SIZE);
- rxdp->Control_2 |= SET_BUFFER0_SIZE(size);
rxdp->Host_Control = (unsigned long) (skb);
if (alloc_tab & ((1 << rxsync_frequency) - 1))
rxdp->Control_1 |= RXD_OWN_XENA;
off++;
- off %= (MAX_RXDS_PER_BLOCK + 1);
- mac_control->rings[ring_no].rx_curr_put_info.offset = off;
-#else
- ba = &mac_control->rings[ring_no].ba[block_no][off];
- skb_reserve(skb, BUF0_LEN);
- tmp = ((unsigned long) skb->data & ALIGN_SIZE);
- if (tmp)
- skb_reserve(skb, (ALIGN_SIZE + 1) - tmp);
-
- memset(rxdp, 0, sizeof(RxD_t));
- rxdp->Buffer2_ptr = pci_map_single
- (nic->pdev, skb->data, dev->mtu + BUF0_LEN + 4,
- PCI_DMA_FROMDEVICE);
- rxdp->Buffer0_ptr =
- pci_map_single(nic->pdev, ba->ba_0, BUF0_LEN,
- PCI_DMA_FROMDEVICE);
- rxdp->Buffer1_ptr =
- pci_map_single(nic->pdev, ba->ba_1, BUF1_LEN,
- PCI_DMA_FROMDEVICE);
-
- rxdp->Control_2 = SET_BUFFER2_SIZE(dev->mtu + 4);
- rxdp->Control_2 |= SET_BUFFER0_SIZE(BUF0_LEN);
- rxdp->Control_2 |= SET_BUFFER1_SIZE(1); /* dummy. */
- rxdp->Control_2 |= BIT(0); /* Set Buffer_Empty bit. */
- rxdp->Host_Control = (u64) ((unsigned long) (skb));
- if (alloc_tab & ((1 << rxsync_frequency) - 1))
- rxdp->Control_1 |= RXD_OWN_XENA;
- off++;
+ if (off == (rxd_count[nic->rxd_mode] + 1))
+ off = 0;
mac_control->rings[ring_no].rx_curr_put_info.offset = off;
-#endif
- rxdp->Control_2 |= SET_RXD_MARKER;
+ rxdp->Control_2 |= SET_RXD_MARKER;
if (!(alloc_tab & ((1 << rxsync_frequency) - 1))) {
if (first_rxdp) {
wmb();
@@ -2316,6 +2351,67 @@ int fill_rx_buffers(struct s2io_nic *nic, int ring_no)
return SUCCESS;
}
+static void free_rxd_blk(struct s2io_nic *sp, int ring_no, int blk)
+{
+ struct net_device *dev = sp->dev;
+ int j;
+ struct sk_buff *skb;
+ RxD_t *rxdp;
+ mac_info_t *mac_control;
+ buffAdd_t *ba;
+
+ mac_control = &sp->mac_control;
+ for (j = 0 ; j < rxd_count[sp->rxd_mode]; j++) {
+ rxdp = mac_control->rings[ring_no].
+ rx_blocks[blk].rxds[j].virt_addr;
+ skb = (struct sk_buff *)
+ ((unsigned long) rxdp->Host_Control);
+ if (!skb) {
+ continue;
+ }
+ if (sp->rxd_mode == RXD_MODE_1) {
+ pci_unmap_single(sp->pdev, (dma_addr_t)
+ ((RxD1_t*)rxdp)->Buffer0_ptr,
+ dev->mtu +
+ HEADER_ETHERNET_II_802_3_SIZE
+ + HEADER_802_2_SIZE +
+ HEADER_SNAP_SIZE,
+ PCI_DMA_FROMDEVICE);
+ memset(rxdp, 0, sizeof(RxD1_t));
+ } else if(sp->rxd_mode == RXD_MODE_3B) {
+ ba = &mac_control->rings[ring_no].
+ ba[blk][j];
+ pci_unmap_single(sp->pdev, (dma_addr_t)
+ ((RxD3_t*)rxdp)->Buffer0_ptr,
+ BUF0_LEN,
+ PCI_DMA_FROMDEVICE);
+ pci_unmap_single(sp->pdev, (dma_addr_t)
+ ((RxD3_t*)rxdp)->Buffer1_ptr,
+ BUF1_LEN,
+ PCI_DMA_FROMDEVICE);
+ pci_unmap_single(sp->pdev, (dma_addr_t)
+ ((RxD3_t*)rxdp)->Buffer2_ptr,
+ dev->mtu + 4,
+ PCI_DMA_FROMDEVICE);
+ memset(rxdp, 0, sizeof(RxD3_t));
+ } else {
+ pci_unmap_single(sp->pdev, (dma_addr_t)
+ ((RxD3_t*)rxdp)->Buffer0_ptr, BUF0_LEN,
+ PCI_DMA_FROMDEVICE);
+ pci_unmap_single(sp->pdev, (dma_addr_t)
+ ((RxD3_t*)rxdp)->Buffer1_ptr,
+ l3l4hdr_size + 4,
+ PCI_DMA_FROMDEVICE);
+ pci_unmap_single(sp->pdev, (dma_addr_t)
+ ((RxD3_t*)rxdp)->Buffer2_ptr, dev->mtu,
+ PCI_DMA_FROMDEVICE);
+ memset(rxdp, 0, sizeof(RxD3_t));
+ }
+ dev_kfree_skb(skb);
+ atomic_dec(&sp->rx_bufs_left[ring_no]);
+ }
+}
+
/**
* free_rx_buffers - Frees all Rx buffers
* @sp: device private variable.
@@ -2328,77 +2424,17 @@ int fill_rx_buffers(struct s2io_nic *nic, int ring_no)
static void free_rx_buffers(struct s2io_nic *sp)
{
struct net_device *dev = sp->dev;
- int i, j, blk = 0, off, buf_cnt = 0;
- RxD_t *rxdp;
- struct sk_buff *skb;
+ int i, blk = 0, buf_cnt = 0;
mac_info_t *mac_control;
struct config_param *config;
-#ifdef CONFIG_2BUFF_MODE
- buffAdd_t *ba;
-#endif
mac_control = &sp->mac_control;
config = &sp->config;
for (i = 0; i < config->rx_ring_num; i++) {
- for (j = 0, blk = 0; j < config->rx_cfg[i].num_rxd; j++) {
- off = j % (MAX_RXDS_PER_BLOCK + 1);
- rxdp = mac_control->rings[i].rx_blocks[blk].
- block_virt_addr + off;
-
-#ifndef CONFIG_2BUFF_MODE
- if (rxdp->Control_1 == END_OF_BLOCK) {
- rxdp =
- (RxD_t *) ((unsigned long) rxdp->
- Control_2);
- j++;
- blk++;
- }
-#else
- if (rxdp->Host_Control == END_OF_BLOCK) {
- blk++;
- continue;
- }
-#endif
+ for (blk = 0; blk < rx_ring_sz[i]; blk++)
+ free_rxd_blk(sp,i,blk);
- if (!(rxdp->Control_1 & RXD_OWN_XENA)) {
- memset(rxdp, 0, sizeof(RxD_t));
- continue;
- }
-
- skb =
- (struct sk_buff *) ((unsigned long) rxdp->
- Host_Control);
- if (skb) {
-#ifndef CONFIG_2BUFF_MODE
- pci_unmap_single(sp->pdev, (dma_addr_t)
- rxdp->Buffer0_ptr,
- dev->mtu +
- HEADER_ETHERNET_II_802_3_SIZE
- + HEADER_802_2_SIZE +
- HEADER_SNAP_SIZE,
- PCI_DMA_FROMDEVICE);
-#else
- ba = &mac_control->rings[i].ba[blk][off];
- pci_unmap_single(sp->pdev, (dma_addr_t)
- rxdp->Buffer0_ptr,
- BUF0_LEN,
- PCI_DMA_FROMDEVICE);
- pci_unmap_single(sp->pdev, (dma_addr_t)
- rxdp->Buffer1_ptr,
- BUF1_LEN,
- PCI_DMA_FROMDEVICE);
- pci_unmap_single(sp->pdev, (dma_addr_t)
- rxdp->Buffer2_ptr,
- dev->mtu + BUF0_LEN + 4,
- PCI_DMA_FROMDEVICE);
-#endif
- dev_kfree_skb(skb);
- atomic_dec(&sp->rx_bufs_left[i]);
- buf_cnt++;
- }
- memset(rxdp, 0, sizeof(RxD_t));
- }
mac_control->rings[i].rx_curr_put_info.block_index = 0;
mac_control->rings[i].rx_curr_get_info.block_index = 0;
mac_control->rings[i].rx_curr_put_info.offset = 0;
@@ -2504,7 +2540,7 @@ static void rx_intr_handler(ring_info_t *ring_data)
{
nic_t *nic = ring_data->nic;
struct net_device *dev = (struct net_device *) nic->dev;
- int get_block, get_offset, put_block, put_offset, ring_bufs;
+ int get_block, put_block, put_offset;
rx_curr_get_info_t get_info, put_info;
RxD_t *rxdp;
struct sk_buff *skb;
@@ -2523,21 +2559,22 @@ static void rx_intr_handler(ring_info_t *ring_data)
get_block = get_info.block_index;
put_info = ring_data->rx_curr_put_info;
put_block = put_info.block_index;
- ring_bufs = get_info.ring_len+1;
- rxdp = ring_data->rx_blocks[get_block].block_virt_addr +
- get_info.offset;
- get_offset = (get_block * (MAX_RXDS_PER_BLOCK + 1)) +
- get_info.offset;
+ rxdp = ring_data->rx_blocks[get_block].rxds[get_info.offset].virt_addr;
#ifndef CONFIG_S2IO_NAPI
spin_lock(&nic->put_lock);
put_offset = ring_data->put_pos;
spin_unlock(&nic->put_lock);
#else
- put_offset = (put_block * (MAX_RXDS_PER_BLOCK + 1)) +
+ put_offset = (put_block * (rxd_count[nic->rxd_mode] + 1)) +
put_info.offset;
#endif
- while (RXD_IS_UP2DT(rxdp) &&
- (((get_offset + 1) % ring_bufs) != put_offset)) {
+ while (RXD_IS_UP2DT(rxdp)) {
+ /* If your are next to put index then it's FIFO full condition */
+ if ((get_block == put_block) &&
+ (get_info.offset + 1) == put_info.offset) {
+ DBG_PRINT(ERR_DBG, "%s: Ring Full\n",dev->name);
+ break;
+ }
skb = (struct sk_buff *) ((unsigned long)rxdp->Host_Control);
if (skb == NULL) {
DBG_PRINT(ERR_DBG, "%s: The skb is ",
@@ -2546,46 +2583,52 @@ static void rx_intr_handler(ring_info_t *ring_data)
spin_unlock(&nic->rx_lock);
return;
}
-#ifndef CONFIG_2BUFF_MODE
- pci_unmap_single(nic->pdev, (dma_addr_t)
- rxdp->Buffer0_ptr,
+ if (nic->rxd_mode == RXD_MODE_1) {
+ pci_unmap_single(nic->pdev, (dma_addr_t)
+ ((RxD1_t*)rxdp)->Buffer0_ptr,
dev->mtu +
HEADER_ETHERNET_II_802_3_SIZE +
HEADER_802_2_SIZE +
HEADER_SNAP_SIZE,
PCI_DMA_FROMDEVICE);
-#else
- pci_unmap_single(nic->pdev, (dma_addr_t)
- rxdp->Buffer0_ptr,
+ } else if (nic->rxd_mode == RXD_MODE_3B) {
+ pci_unmap_single(nic->pdev, (dma_addr_t)
+ ((RxD3_t*)rxdp)->Buffer0_ptr,
BUF0_LEN, PCI_DMA_FROMDEVICE);
- pci_unmap_single(nic->pdev, (dma_addr_t)
- rxdp->Buffer1_ptr,
+ pci_unmap_single(nic->pdev, (dma_addr_t)
+ ((RxD3_t*)rxdp)->Buffer1_ptr,
BUF1_LEN, PCI_DMA_FROMDEVICE);
- pci_unmap_single(nic->pdev, (dma_addr_t)
- rxdp->Buffer2_ptr,
- dev->mtu + BUF0_LEN + 4,
+ pci_unmap_single(nic->pdev, (dma_addr_t)
+ ((RxD3_t*)rxdp)->Buffer2_ptr,
+ dev->mtu + 4,
PCI_DMA_FROMDEVICE);
-#endif
+ } else {
+ pci_unmap_single(nic->pdev, (dma_addr_t)
+ ((RxD3_t*)rxdp)->Buffer0_ptr, BUF0_LEN,
+ PCI_DMA_FROMDEVICE);
+ pci_unmap_single(nic->pdev, (dma_addr_t)
+ ((RxD3_t*)rxdp)->Buffer1_ptr,
+ l3l4hdr_size + 4,
+ PCI_DMA_FROMDEVICE);
+ pci_unmap_single(nic->pdev, (dma_addr_t)
+ ((RxD3_t*)rxdp)->Buffer2_ptr,
+ dev->mtu, PCI_DMA_FROMDEVICE);
+ }
rx_osm_handler(ring_data, rxdp);
get_info.offset++;
- ring_data->rx_curr_get_info.offset =
- get_info.offset;
- rxdp = ring_data->rx_blocks[get_block].block_virt_addr +
- get_info.offset;
- if (get_info.offset &&
- (!(get_info.offset % MAX_RXDS_PER_BLOCK))) {
+ ring_data->rx_curr_get_info.offset = get_info.offset;
+ rxdp = ring_data->rx_blocks[get_block].
+ rxds[get_info.offset].virt_addr;
+ if (get_info.offset == rxd_count[nic->rxd_mode]) {
get_info.offset = 0;
- ring_data->rx_curr_get_info.offset
- = get_info.offset;
+ ring_data->rx_curr_get_info.offset = get_info.offset;
get_block++;
- get_block %= ring_data->block_count;
- ring_data->rx_curr_get_info.block_index
- = get_block;
+ if (get_block == ring_data->block_count)
+ get_block = 0;
+ ring_data->rx_curr_get_info.block_index = get_block;
rxdp = ring_data->rx_blocks[get_block].block_virt_addr;
}
- get_offset = (get_block * (MAX_RXDS_PER_BLOCK + 1)) +
- get_info.offset;
#ifdef CONFIG_S2IO_NAPI
nic->pkts_to_process -= 1;
if (!nic->pkts_to_process)
@@ -2633,11 +2676,11 @@ static void tx_intr_handler(fifo_info_t *fifo_data)
err = txdlp->Control_1 & TXD_T_CODE;
if ((err >> 48) == 0xA) {
DBG_PRINT(TX_DBG, "TxD returned due \
- to loss of link\n");
+to loss of link\n");
}
else {
DBG_PRINT(ERR_DBG, "***TxD error \
- %llx\n", err);
+%llx\n", err);
}
}
@@ -2787,7 +2830,7 @@ static void alarm_intr_handler(struct s2io_nic *nic)
* SUCCESS on success and FAILURE on failure.
*/
-int wait_for_cmd_complete(nic_t * sp)
+static int wait_for_cmd_complete(nic_t * sp)
{
XENA_dev_config_t __iomem *bar0 = sp->bar0;
int ret = FAILURE, cnt = 0;
@@ -2854,6 +2897,9 @@ void s2io_reset(nic_t * sp)
/* Set swapper to enable I/O register access */
s2io_set_swapper(sp);
+ /* Restore the MSIX table entries from local variables */
+ restore_xmsi_data(sp);
+
/* Clear certain PCI/PCI-X fields after reset */
if (sp->device_type == XFRAME_II_DEVICE) {
/* Clear parity err detect bit */
@@ -2983,8 +3029,9 @@ int s2io_set_swapper(nic_t * sp)
SWAPPER_CTRL_RXD_W_FE |
SWAPPER_CTRL_RXF_W_FE |
SWAPPER_CTRL_XMSI_FE |
- SWAPPER_CTRL_XMSI_SE |
SWAPPER_CTRL_STATS_FE | SWAPPER_CTRL_STATS_SE);
+ if (sp->intr_type == INTA)
+ val64 |= SWAPPER_CTRL_XMSI_SE;
writeq(val64, &bar0->swapper_ctrl);
#else
/*
@@ -3005,8 +3052,9 @@ int s2io_set_swapper(nic_t * sp)
SWAPPER_CTRL_RXD_W_SE |
SWAPPER_CTRL_RXF_W_FE |
SWAPPER_CTRL_XMSI_FE |
- SWAPPER_CTRL_XMSI_SE |
SWAPPER_CTRL_STATS_FE | SWAPPER_CTRL_STATS_SE);
+ if (sp->intr_type == INTA)
+ val64 |= SWAPPER_CTRL_XMSI_SE;
writeq(val64, &bar0->swapper_ctrl);
#endif
val64 = readq(&bar0->swapper_ctrl);
@@ -3028,6 +3076,201 @@ int s2io_set_swapper(nic_t * sp)
return SUCCESS;
}
+static int wait_for_msix_trans(nic_t *nic, int i)
+{
+ XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0;
+ u64 val64;
+ int ret = 0, cnt = 0;
+
+ do {
+ val64 = readq(&bar0->xmsi_access);
+ if (!(val64 & BIT(15)))
+ break;
+ mdelay(1);
+ cnt++;
+ } while(cnt < 5);
+ if (cnt == 5) {
+ DBG_PRINT(ERR_DBG, "XMSI # %d Access failed\n", i);
+ ret = 1;
+ }
+
+ return ret;
+}
+
+void restore_xmsi_data(nic_t *nic)
+{
+ XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0;
+ u64 val64;
+ int i;
+
+ for (i=0; i< MAX_REQUESTED_MSI_X; i++) {
+ writeq(nic->msix_info[i].addr, &bar0->xmsi_address);
+ writeq(nic->msix_info[i].data, &bar0->xmsi_data);
+ val64 = (BIT(7) | BIT(15) | vBIT(i, 26, 6));
+ writeq(val64, &bar0->xmsi_access);
+ if (wait_for_msix_trans(nic, i)) {
+ DBG_PRINT(ERR_DBG, "failed in %s\n", __FUNCTION__);
+ continue;
+ }
+ }
+}
+
+static void store_xmsi_data(nic_t *nic)
+{
+ XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0;
+ u64 val64, addr, data;
+ int i;
+
+ /* Store and display */
+ for (i=0; i< MAX_REQUESTED_MSI_X; i++) {
+ val64 = (BIT(15) | vBIT(i, 26, 6));
+ writeq(val64, &bar0->xmsi_access);
+ if (wait_for_msix_trans(nic, i)) {
+ DBG_PRINT(ERR_DBG, "failed in %s\n", __FUNCTION__);
+ continue;
+ }
+ addr = readq(&bar0->xmsi_address);
+ data = readq(&bar0->xmsi_data);
+ if (addr && data) {
+ nic->msix_info[i].addr = addr;
+ nic->msix_info[i].data = data;
+ }
+ }
+}
+
+int s2io_enable_msi(nic_t *nic)
+{
+ XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0;
+ u16 msi_ctrl, msg_val;
+ struct config_param *config = &nic->config;
+ struct net_device *dev = nic->dev;
+ u64 val64, tx_mat, rx_mat;
+ int i, err;
+
+ val64 = readq(&bar0->pic_control);
+ val64 &= ~BIT(1);
+ writeq(val64, &bar0->pic_control);
+
+ err = pci_enable_msi(nic->pdev);
+ if (err) {
+ DBG_PRINT(ERR_DBG, "%s: enabling MSI failed\n",
+ nic->dev->name);
+ return err;
+ }
+
+ /*
+ * Enable MSI and use MSI-1 in stead of the standard MSI-0
+ * for interrupt handling.
+ */
+ pci_read_config_word(nic->pdev, 0x4c, &msg_val);
+ msg_val ^= 0x1;
+ pci_write_config_word(nic->pdev, 0x4c, msg_val);
+ pci_read_config_word(nic->pdev, 0x4c, &msg_val);
+
+ pci_read_config_word(nic->pdev, 0x42, &msi_ctrl);
+ msi_ctrl |= 0x10;
+ pci_write_config_word(nic->pdev, 0x42, msi_ctrl);
+
+ /* program MSI-1 into all usable Tx_Mat and Rx_Mat fields */
+ tx_mat = readq(&bar0->tx_mat0_n[0]);
+ for (i=0; i<config->tx_fifo_num; i++) {
+ tx_mat |= TX_MAT_SET(i, 1);
+ }
+ writeq(tx_mat, &bar0->tx_mat0_n[0]);
+
+ rx_mat = readq(&bar0->rx_mat);
+ for (i=0; i<config->rx_ring_num; i++) {
+ rx_mat |= RX_MAT_SET(i, 1);
+ }
+ writeq(rx_mat, &bar0->rx_mat);
+
+ dev->irq = nic->pdev->irq;
+ return 0;
+}
+
+int s2io_enable_msi_x(nic_t *nic)
+{
+ XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0;
+ u64 tx_mat, rx_mat;
+ u16 msi_control; /* Temp variable */
+ int ret, i, j, msix_indx = 1;
+
+ nic->entries = kmalloc(MAX_REQUESTED_MSI_X * sizeof(struct msix_entry),
+ GFP_KERNEL);
+ if (nic->entries == NULL) {
+ DBG_PRINT(ERR_DBG, "%s: Memory allocation failed\n", __FUNCTION__);
+ return -ENOMEM;
+ }
+ memset(nic->entries, 0, MAX_REQUESTED_MSI_X * sizeof(struct msix_entry));
+
+ nic->s2io_entries =
+ kmalloc(MAX_REQUESTED_MSI_X * sizeof(struct s2io_msix_entry),
+ GFP_KERNEL);
+ if (nic->s2io_entries == NULL) {
+ DBG_PRINT(ERR_DBG, "%s: Memory allocation failed\n", __FUNCTION__);
+ kfree(nic->entries);
+ return -ENOMEM;
+ }
+ memset(nic->s2io_entries, 0,
+ MAX_REQUESTED_MSI_X * sizeof(struct s2io_msix_entry));
+
+ for (i=0; i< MAX_REQUESTED_MSI_X; i++) {
+ nic->entries[i].entry = i;
+ nic->s2io_entries[i].entry = i;
+ nic->s2io_entries[i].arg = NULL;
+ nic->s2io_entries[i].in_use = 0;
+ }
+
+ tx_mat = readq(&bar0->tx_mat0_n[0]);
+ for (i=0; i<nic->config.tx_fifo_num; i++, msix_indx++) {
+ tx_mat |= TX_MAT_SET(i, msix_indx);
+ nic->s2io_entries[msix_indx].arg = &nic->mac_control.fifos[i];
+ nic->s2io_entries[msix_indx].type = MSIX_FIFO_TYPE;
+ nic->s2io_entries[msix_indx].in_use = MSIX_FLG;
+ }
+ writeq(tx_mat, &bar0->tx_mat0_n[0]);
+
+ if (!nic->config.bimodal) {
+ rx_mat = readq(&bar0->rx_mat);
+ for (j=0; j<nic->config.rx_ring_num; j++, msix_indx++) {
+ rx_mat |= RX_MAT_SET(j, msix_indx);
+ nic->s2io_entries[msix_indx].arg = &nic->mac_control.rings[j];
+ nic->s2io_entries[msix_indx].type = MSIX_RING_TYPE;
+ nic->s2io_entries[msix_indx].in_use = MSIX_FLG;
+ }
+ writeq(rx_mat, &bar0->rx_mat);
+ } else {
+ tx_mat = readq(&bar0->tx_mat0_n[7]);
+ for (j=0; j<nic->config.rx_ring_num; j++, msix_indx++) {
+ tx_mat |= TX_MAT_SET(i, msix_indx);
+ nic->s2io_entries[msix_indx].arg = &nic->mac_control.rings[j];
+ nic->s2io_entries[msix_indx].type = MSIX_RING_TYPE;
+ nic->s2io_entries[msix_indx].in_use = MSIX_FLG;
+ }
+ writeq(tx_mat, &bar0->tx_mat0_n[7]);
+ }
+
+ ret = pci_enable_msix(nic->pdev, nic->entries, MAX_REQUESTED_MSI_X);
+ if (ret) {
+ DBG_PRINT(ERR_DBG, "%s: Enabling MSIX failed\n", nic->dev->name);
+ kfree(nic->entries);
+ kfree(nic->s2io_entries);
+ nic->entries = NULL;
+ nic->s2io_entries = NULL;
+ return -ENOMEM;
+ }
+
+ /*
+ * To enable MSI-X, MSI also needs to be enabled, due to a bug
+ * in the herc NIC. (Temp change, needs to be removed later)
+ */
+ pci_read_config_word(nic->pdev, 0x42, &msi_control);
+ msi_control |= 0x1; /* Enable MSI */
+ pci_write_config_word(nic->pdev, 0x42, msi_control);
+
+ return 0;
+}
+
/* ********************************************************* *
* Functions defined below concern the OS part of the driver *
* ********************************************************* */
@@ -3044,10 +3287,12 @@ int s2io_set_swapper(nic_t * sp)
* file on failure.
*/
-int s2io_open(struct net_device *dev)
+static int s2io_open(struct net_device *dev)
{
nic_t *sp = dev->priv;
int err = 0;
+ int i;
+ u16 msi_control; /* Temp variable */
/*
* Make sure you have link off by default every time
@@ -3064,13 +3309,55 @@ int s2io_open(struct net_device *dev)
goto hw_init_failed;
}
+ /* Store the values of the MSIX table in the nic_t structure */
+ store_xmsi_data(sp);
+
/* After proper initialization of H/W, register ISR */
- err = request_irq((int) sp->pdev->irq, s2io_isr, SA_SHIRQ,
- sp->name, dev);
- if (err) {
- DBG_PRINT(ERR_DBG, "%s: ISR registration failed\n",
- dev->name);
- goto isr_registration_failed;
+ if (sp->intr_type == MSI) {
+ err = request_irq((int) sp->pdev->irq, s2io_msi_handle,
+ SA_SHIRQ, sp->name, dev);
+ if (err) {
+ DBG_PRINT(ERR_DBG, "%s: MSI registration \
+failed\n", dev->name);
+ goto isr_registration_failed;
+ }
+ }
+ if (sp->intr_type == MSI_X) {
+ for (i=1; (sp->s2io_entries[i].in_use == MSIX_FLG); i++) {
+ if (sp->s2io_entries[i].type == MSIX_FIFO_TYPE) {
+ sprintf(sp->desc1, "%s:MSI-X-%d-TX",
+ dev->name, i);
+ err = request_irq(sp->entries[i].vector,
+ s2io_msix_fifo_handle, 0, sp->desc1,
+ sp->s2io_entries[i].arg);
+ DBG_PRINT(ERR_DBG, "%s @ 0x%llx\n", sp->desc1,
+ sp->msix_info[i].addr);
+ } else {
+ sprintf(sp->desc2, "%s:MSI-X-%d-RX",
+ dev->name, i);
+ err = request_irq(sp->entries[i].vector,
+ s2io_msix_ring_handle, 0, sp->desc2,
+ sp->s2io_entries[i].arg);
+ DBG_PRINT(ERR_DBG, "%s @ 0x%llx\n", sp->desc2,
+ sp->msix_info[i].addr);
+ }
+ if (err) {
+ DBG_PRINT(ERR_DBG, "%s: MSI-X-%d registration \
+failed\n", dev->name, i);
+ DBG_PRINT(ERR_DBG, "Returned: %d\n", err);
+ goto isr_registration_failed;
+ }
+ sp->s2io_entries[i].in_use = MSIX_REGISTERED_SUCCESS;
+ }
+ }
+ if (sp->intr_type == INTA) {
+ err = request_irq((int) sp->pdev->irq, s2io_isr, SA_SHIRQ,
+ sp->name, dev);
+ if (err) {
+ DBG_PRINT(ERR_DBG, "%s: ISR registration failed\n",
+ dev->name);
+ goto isr_registration_failed;
+ }
}
if (s2io_set_mac_addr(dev, dev->dev_addr) == FAILURE) {
@@ -3083,11 +3370,37 @@ int s2io_open(struct net_device *dev)
return 0;
setting_mac_address_failed:
- free_irq(sp->pdev->irq, dev);
+ if (sp->intr_type != MSI_X)
+ free_irq(sp->pdev->irq, dev);
isr_registration_failed:
del_timer_sync(&sp->alarm_timer);
+ if (sp->intr_type == MSI_X) {
+ if (sp->device_type == XFRAME_II_DEVICE) {
+ for (i=1; (sp->s2io_entries[i].in_use ==
+ MSIX_REGISTERED_SUCCESS); i++) {
+ int vector = sp->entries[i].vector;
+ void *arg = sp->s2io_entries[i].arg;
+
+ free_irq(vector, arg);
+ }
+ pci_disable_msix(sp->pdev);
+
+ /* Temp */
+ pci_read_config_word(sp->pdev, 0x42, &msi_control);
+ msi_control &= 0xFFFE; /* Disable MSI */
+ pci_write_config_word(sp->pdev, 0x42, msi_control);
+ }
+ }
+ else if (sp->intr_type == MSI)
+ pci_disable_msi(sp->pdev);
s2io_reset(sp);
hw_init_failed:
+ if (sp->intr_type == MSI_X) {
+ if (sp->entries)
+ kfree(sp->entries);
+ if (sp->s2io_entries)
+ kfree(sp->s2io_entries);
+ }
return err;
}
@@ -3104,15 +3417,38 @@ hw_init_failed:
* file on failure.
*/
-int s2io_close(struct net_device *dev)
+static int s2io_close(struct net_device *dev)
{
nic_t *sp = dev->priv;
+ int i;
+ u16 msi_control;
+
flush_scheduled_work();
netif_stop_queue(dev);
/* Reset card, kill tasklet and free Tx and Rx buffers. */
s2io_card_down(sp);
- free_irq(sp->pdev->irq, dev);
+ if (sp->intr_type == MSI_X) {
+ if (sp->device_type == XFRAME_II_DEVICE) {
+ for (i=1; (sp->s2io_entries[i].in_use ==
+ MSIX_REGISTERED_SUCCESS); i++) {
+ int vector = sp->entries[i].vector;
+ void *arg = sp->s2io_entries[i].arg;
+
+ free_irq(vector, arg);
+ }
+ pci_read_config_word(sp->pdev, 0x42, &msi_control);
+ msi_control &= 0xFFFE; /* Disable MSI */
+ pci_write_config_word(sp->pdev, 0x42, msi_control);
+
+ pci_disable_msix(sp->pdev);
+ }
+ }
+ else {
+ free_irq(sp->pdev->irq, dev);
+ if (sp->intr_type == MSI)
+ pci_disable_msi(sp->pdev);
+ }
sp->device_close_flag = TRUE; /* Device is shut down. */
return 0;
}
@@ -3130,7 +3466,7 @@ int s2io_close(struct net_device *dev)
* 0 on success & 1 on failure.
*/
-int s2io_xmit(struct sk_buff *skb, struct net_device *dev)
+static int s2io_xmit(struct sk_buff *skb, struct net_device *dev)
{
nic_t *sp = dev->priv;
u16 frg_cnt, frg_len, i, queue, queue_len, put_off, get_off;
@@ -3278,6 +3614,104 @@ s2io_alarm_handle(unsigned long data)
mod_timer(&sp->alarm_timer, jiffies + HZ / 2);
}
+static irqreturn_t
+s2io_msi_handle(int irq, void *dev_id, struct pt_regs *regs)
+{
+ struct net_device *dev = (struct net_device *) dev_id;
+ nic_t *sp = dev->priv;
+ int i;
+ int ret;
+ mac_info_t *mac_control;
+ struct config_param *config;
+
+ atomic_inc(&sp->isr_cnt);
+ mac_control = &sp->mac_control;
+ config = &sp->config;
+ DBG_PRINT(INTR_DBG, "%s: MSI handler\n", __FUNCTION__);
+
+ /* If Intr is because of Rx Traffic */
+ for (i = 0; i < config->rx_ring_num; i++)
+ rx_intr_handler(&mac_control->rings[i]);
+
+ /* If Intr is because of Tx Traffic */
+ for (i = 0; i < config->tx_fifo_num; i++)
+ tx_intr_handler(&mac_control->fifos[i]);
+
+ /*
+ * If the Rx buffer count is below the panic threshold then
+ * reallocate the buffers from the interrupt handler itself,
+ * else schedule a tasklet to reallocate the buffers.
+ */
+ for (i = 0; i < config->rx_ring_num; i++) {
+ int rxb_size = atomic_read(&sp->rx_bufs_left[i]);
+ int level = rx_buffer_level(sp, rxb_size, i);
+
+ if ((level == PANIC) && (!TASKLET_IN_USE)) {
+ DBG_PRINT(INTR_DBG, "%s: Rx BD hit ", dev->name);
+ DBG_PRINT(INTR_DBG, "PANIC levels\n");
+ if ((ret = fill_rx_buffers(sp, i)) == -ENOMEM) {
+ DBG_PRINT(ERR_DBG, "%s:Out of memory",
+ dev->name);
+ DBG_PRINT(ERR_DBG, " in ISR!!\n");
+ clear_bit(0, (&sp->tasklet_status));
+ atomic_dec(&sp->isr_cnt);
+ return IRQ_HANDLED;
+ }
+ clear_bit(0, (&sp->tasklet_status));
+ } else if (level == LOW) {
+ tasklet_schedule(&sp->task);
+ }
+ }
+
+ atomic_dec(&sp->isr_cnt);
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t
+s2io_msix_ring_handle(int irq, void *dev_id, struct pt_regs *regs)
+{
+ ring_info_t *ring = (ring_info_t *)dev_id;
+ nic_t *sp = ring->nic;
+ int rxb_size, level, rng_n;
+
+ atomic_inc(&sp->isr_cnt);
+ rx_intr_handler(ring);
+
+ rng_n = ring->ring_no;
+ rxb_size = atomic_read(&sp->rx_bufs_left[rng_n]);
+ level = rx_buffer_level(sp, rxb_size, rng_n);
+
+ if ((level == PANIC) && (!TASKLET_IN_USE)) {
+ int ret;
+ DBG_PRINT(INTR_DBG, "%s: Rx BD hit ", __FUNCTION__);
+ DBG_PRINT(INTR_DBG, "PANIC levels\n");
+ if ((ret = fill_rx_buffers(sp, rng_n)) == -ENOMEM) {
+ DBG_PRINT(ERR_DBG, "Out of memory in %s",
+ __FUNCTION__);
+ clear_bit(0, (&sp->tasklet_status));
+ return IRQ_HANDLED;
+ }
+ clear_bit(0, (&sp->tasklet_status));
+ } else if (level == LOW) {
+ tasklet_schedule(&sp->task);
+ }
+ atomic_dec(&sp->isr_cnt);
+
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t
+s2io_msix_fifo_handle(int irq, void *dev_id, struct pt_regs *regs)
+{
+ fifo_info_t *fifo = (fifo_info_t *)dev_id;
+ nic_t *sp = fifo->nic;
+
+ atomic_inc(&sp->isr_cnt);
+ tx_intr_handler(fifo);
+ atomic_dec(&sp->isr_cnt);
+ return IRQ_HANDLED;
+}
+
static void s2io_txpic_intr_handle(nic_t *sp)
{
XENA_dev_config_t __iomem *bar0 = sp->bar0;
@@ -3478,7 +3912,7 @@ static void s2io_updt_stats(nic_t *sp)
* pointer to the updated net_device_stats structure.
*/
-struct net_device_stats *s2io_get_stats(struct net_device *dev)
+static struct net_device_stats *s2io_get_stats(struct net_device *dev)
{
nic_t *sp = dev->priv;
mac_info_t *mac_control;
@@ -3778,11 +4212,10 @@ static void s2io_ethtool_gdrvinfo(struct net_device *dev,
{
nic_t *sp = dev->priv;
- strncpy(info->driver, s2io_driver_name, sizeof(s2io_driver_name));
- strncpy(info->version, s2io_driver_version,
- sizeof(s2io_driver_version));
- strncpy(info->fw_version, "", 32);
- strncpy(info->bus_info, pci_name(sp->pdev), 32);
+ strncpy(info->driver, s2io_driver_name, sizeof(info->driver));
+ strncpy(info->version, s2io_driver_version, sizeof(info->version));
+ strncpy(info->fw_version, "", sizeof(info->fw_version));
+ strncpy(info->bus_info, pci_name(sp->pdev), sizeof(info->bus_info));
info->regdump_len = XENA_REG_SPACE;
info->eedump_len = XENA_EEPROM_SPACE;
info->testinfo_len = S2IO_TEST_LEN;
@@ -3978,29 +4411,53 @@ static int s2io_ethtool_setpause_data(struct net_device *dev,
*/
#define S2IO_DEV_ID 5
-static int read_eeprom(nic_t * sp, int off, u32 * data)
+static int read_eeprom(nic_t * sp, int off, u64 * data)
{
int ret = -1;
u32 exit_cnt = 0;
u64 val64;
XENA_dev_config_t __iomem *bar0 = sp->bar0;
- val64 = I2C_CONTROL_DEV_ID(S2IO_DEV_ID) | I2C_CONTROL_ADDR(off) |
- I2C_CONTROL_BYTE_CNT(0x3) | I2C_CONTROL_READ |
- I2C_CONTROL_CNTL_START;
- SPECIAL_REG_WRITE(val64, &bar0->i2c_control, LF);
+ if (sp->device_type == XFRAME_I_DEVICE) {
+ val64 = I2C_CONTROL_DEV_ID(S2IO_DEV_ID) | I2C_CONTROL_ADDR(off) |
+ I2C_CONTROL_BYTE_CNT(0x3) | I2C_CONTROL_READ |
+ I2C_CONTROL_CNTL_START;
+ SPECIAL_REG_WRITE(val64, &bar0->i2c_control, LF);
- while (exit_cnt < 5) {
- val64 = readq(&bar0->i2c_control);
- if (I2C_CONTROL_CNTL_END(val64)) {
- *data = I2C_CONTROL_GET_DATA(val64);
- ret = 0;
- break;
+ while (exit_cnt < 5) {
+ val64 = readq(&bar0->i2c_control);
+ if (I2C_CONTROL_CNTL_END(val64)) {
+ *data = I2C_CONTROL_GET_DATA(val64);
+ ret = 0;
+ break;
+ }
+ msleep(50);
+ exit_cnt++;
}
- msleep(50);
- exit_cnt++;
}
+ if (sp->device_type == XFRAME_II_DEVICE) {
+ val64 = SPI_CONTROL_KEY(0x9) | SPI_CONTROL_SEL1 |
+ SPI_CONTROL_BYTECNT(0x3) |
+ SPI_CONTROL_CMD(0x3) | SPI_CONTROL_ADDR(off);
+ SPECIAL_REG_WRITE(val64, &bar0->spi_control, LF);
+ val64 |= SPI_CONTROL_REQ;
+ SPECIAL_REG_WRITE(val64, &bar0->spi_control, LF);
+ while (exit_cnt < 5) {
+ val64 = readq(&bar0->spi_control);
+ if (val64 & SPI_CONTROL_NACK) {
+ ret = 1;
+ break;
+ } else if (val64 & SPI_CONTROL_DONE) {
+ *data = readq(&bar0->spi_data);
+ *data &= 0xffffff;
+ ret = 0;
+ break;
+ }
+ msleep(50);
+ exit_cnt++;
+ }
+ }
return ret;
}
@@ -4019,28 +4476,53 @@ static int read_eeprom(nic_t * sp, int off, u32 * data)
* 0 on success, -1 on failure.
*/
-static int write_eeprom(nic_t * sp, int off, u32 data, int cnt)
+static int write_eeprom(nic_t * sp, int off, u64 data, int cnt)
{
int exit_cnt = 0, ret = -1;
u64 val64;
XENA_dev_config_t __iomem *bar0 = sp->bar0;
- val64 = I2C_CONTROL_DEV_ID(S2IO_DEV_ID) | I2C_CONTROL_ADDR(off) |
- I2C_CONTROL_BYTE_CNT(cnt) | I2C_CONTROL_SET_DATA(data) |
- I2C_CONTROL_CNTL_START;
- SPECIAL_REG_WRITE(val64, &bar0->i2c_control, LF);
+ if (sp->device_type == XFRAME_I_DEVICE) {
+ val64 = I2C_CONTROL_DEV_ID(S2IO_DEV_ID) | I2C_CONTROL_ADDR(off) |
+ I2C_CONTROL_BYTE_CNT(cnt) | I2C_CONTROL_SET_DATA((u32)data) |
+ I2C_CONTROL_CNTL_START;
+ SPECIAL_REG_WRITE(val64, &bar0->i2c_control, LF);
+
+ while (exit_cnt < 5) {
+ val64 = readq(&bar0->i2c_control);
+ if (I2C_CONTROL_CNTL_END(val64)) {
+ if (!(val64 & I2C_CONTROL_NACK))
+ ret = 0;
+ break;
+ }
+ msleep(50);
+ exit_cnt++;
+ }
+ }
- while (exit_cnt < 5) {
- val64 = readq(&bar0->i2c_control);
- if (I2C_CONTROL_CNTL_END(val64)) {
- if (!(val64 & I2C_CONTROL_NACK))
+ if (sp->device_type == XFRAME_II_DEVICE) {
+ int write_cnt = (cnt == 8) ? 0 : cnt;
+ writeq(SPI_DATA_WRITE(data,(cnt<<3)), &bar0->spi_data);
+
+ val64 = SPI_CONTROL_KEY(0x9) | SPI_CONTROL_SEL1 |
+ SPI_CONTROL_BYTECNT(write_cnt) |
+ SPI_CONTROL_CMD(0x2) | SPI_CONTROL_ADDR(off);
+ SPECIAL_REG_WRITE(val64, &bar0->spi_control, LF);
+ val64 |= SPI_CONTROL_REQ;
+ SPECIAL_REG_WRITE(val64, &bar0->spi_control, LF);
+ while (exit_cnt < 5) {
+ val64 = readq(&bar0->spi_control);
+ if (val64 & SPI_CONTROL_NACK) {
+ ret = 1;
+ break;
+ } else if (val64 & SPI_CONTROL_DONE) {
ret = 0;
- break;
+ break;
+ }
+ msleep(50);
+ exit_cnt++;
}
- msleep(50);
- exit_cnt++;
}
-
return ret;
}
@@ -4060,7 +4542,8 @@ static int write_eeprom(nic_t * sp, int off, u32 data, int cnt)
static int s2io_ethtool_geeprom(struct net_device *dev,
struct ethtool_eeprom *eeprom, u8 * data_buf)
{
- u32 data, i, valid;
+ u32 i, valid;
+ u64 data;
nic_t *sp = dev->priv;
eeprom->magic = sp->pdev->vendor | (sp->pdev->device << 16);
@@ -4098,7 +4581,7 @@ static int s2io_ethtool_seeprom(struct net_device *dev,
u8 * data_buf)
{
int len = eeprom->len, cnt = 0;
- u32 valid = 0, data;
+ u64 valid = 0, data;
nic_t *sp = dev->priv;
if (eeprom->magic != (sp->pdev->vendor | (sp->pdev->device << 16))) {
@@ -4146,7 +4629,7 @@ static int s2io_ethtool_seeprom(struct net_device *dev,
static int s2io_register_test(nic_t * sp, uint64_t * data)
{
XENA_dev_config_t __iomem *bar0 = sp->bar0;
- u64 val64 = 0;
+ u64 val64 = 0, exp_val;
int fail = 0;
val64 = readq(&bar0->pif_rd_swapper_fb);
@@ -4162,7 +4645,11 @@ static int s2io_register_test(nic_t * sp, uint64_t * data)
}
val64 = readq(&bar0->rx_queue_cfg);
- if (val64 != 0x0808080808080808ULL) {
+ if (sp->device_type == XFRAME_II_DEVICE)
+ exp_val = 0x0404040404040404ULL;
+ else
+ exp_val = 0x0808080808080808ULL;
+ if (val64 != exp_val) {
fail = 1;
DBG_PRINT(INFO_DBG, "Read Test level 3 fails\n");
}
@@ -4190,7 +4677,7 @@ static int s2io_register_test(nic_t * sp, uint64_t * data)
}
*data = fail;
- return 0;
+ return fail;
}
/**
@@ -4209,58 +4696,83 @@ static int s2io_register_test(nic_t * sp, uint64_t * data)
static int s2io_eeprom_test(nic_t * sp, uint64_t * data)
{
int fail = 0;
- u32 ret_data;
+ u64 ret_data, org_4F0, org_7F0;
+ u8 saved_4F0 = 0, saved_7F0 = 0;
+ struct net_device *dev = sp->dev;
/* Test Write Error at offset 0 */
- if (!write_eeprom(sp, 0, 0, 3))
- fail = 1;
+ /* Note that SPI interface allows write access to all areas
+ * of EEPROM. Hence doing all negative testing only for Xframe I.
+ */
+ if (sp->device_type == XFRAME_I_DEVICE)
+ if (!write_eeprom(sp, 0, 0, 3))
+ fail = 1;
+
+ /* Save current values at offsets 0x4F0 and 0x7F0 */
+ if (!read_eeprom(sp, 0x4F0, &org_4F0))
+ saved_4F0 = 1;
+ if (!read_eeprom(sp, 0x7F0, &org_7F0))
+ saved_7F0 = 1;
/* Test Write at offset 4f0 */
- if (write_eeprom(sp, 0x4F0, 0x01234567, 3))
+ if (write_eeprom(sp, 0x4F0, 0x012345, 3))
fail = 1;
if (read_eeprom(sp, 0x4F0, &ret_data))
fail = 1;
- if (ret_data != 0x01234567)
+ if (ret_data != 0x012345) {
+ DBG_PRINT(ERR_DBG, "%s: eeprom test error at offset 0x4F0. Data written %llx Data read %llx\n", dev->name, (u64)0x12345, ret_data);
fail = 1;
+ }
/* Reset the EEPROM data go FFFF */
- write_eeprom(sp, 0x4F0, 0xFFFFFFFF, 3);
+ write_eeprom(sp, 0x4F0, 0xFFFFFF, 3);
/* Test Write Request Error at offset 0x7c */
- if (!write_eeprom(sp, 0x07C, 0, 3))
- fail = 1;
+ if (sp->device_type == XFRAME_I_DEVICE)
+ if (!write_eeprom(sp, 0x07C, 0, 3))
+ fail = 1;
- /* Test Write Request at offset 0x7fc */
- if (write_eeprom(sp, 0x7FC, 0x01234567, 3))
+ /* Test Write Request at offset 0x7f0 */
+ if (write_eeprom(sp, 0x7F0, 0x012345, 3))
fail = 1;
- if (read_eeprom(sp, 0x7FC, &ret_data))
+ if (read_eeprom(sp, 0x7F0, &ret_data))
fail = 1;
- if (ret_data != 0x01234567)
+ if (ret_data != 0x012345) {
+ DBG_PRINT(ERR_DBG, "%s: eeprom test error at offset 0x7F0. Data written %llx Data read %llx\n", dev->name, (u64)0x12345, ret_data);
fail = 1;
+ }
/* Reset the EEPROM data go FFFF */
- write_eeprom(sp, 0x7FC, 0xFFFFFFFF, 3);
+ write_eeprom(sp, 0x7F0, 0xFFFFFF, 3);
- /* Test Write Error at offset 0x80 */
- if (!write_eeprom(sp, 0x080, 0, 3))
- fail = 1;
+ if (sp->device_type == XFRAME_I_DEVICE) {
+ /* Test Write Error at offset 0x80 */
+ if (!write_eeprom(sp, 0x080, 0, 3))
+ fail = 1;
- /* Test Write Error at offset 0xfc */
- if (!write_eeprom(sp, 0x0FC, 0, 3))
- fail = 1;
+ /* Test Write Error at offset 0xfc */
+ if (!write_eeprom(sp, 0x0FC, 0, 3))
+ fail = 1;
- /* Test Write Error at offset 0x100 */
- if (!write_eeprom(sp, 0x100, 0, 3))
- fail = 1;
+ /* Test Write Error at offset 0x100 */
+ if (!write_eeprom(sp, 0x100, 0, 3))
+ fail = 1;
- /* Test Write Error at offset 4ec */
- if (!write_eeprom(sp, 0x4EC, 0, 3))
- fail = 1;
+ /* Test Write Error at offset 4ec */
+ if (!write_eeprom(sp, 0x4EC, 0, 3))
+ fail = 1;
+ }
+
+ /* Restore values at offsets 0x4F0 and 0x7F0 */
+ if (saved_4F0)
+ write_eeprom(sp, 0x4F0, org_4F0, 3);
+ if (saved_7F0)
+ write_eeprom(sp, 0x7F0, org_7F0, 3);
*data = fail;
- return 0;
+ return fail;
}
/**
@@ -4342,7 +4854,7 @@ static int s2io_rldram_test(nic_t * sp, uint64_t * data)
{
XENA_dev_config_t __iomem *bar0 = sp->bar0;
u64 val64;
- int cnt, iteration = 0, test_pass = 0;
+ int cnt, iteration = 0, test_fail = 0;
val64 = readq(&bar0->adapter_control);
val64 &= ~ADAPTER_ECC_EN;
@@ -4350,7 +4862,7 @@ static int s2io_rldram_test(nic_t * sp, uint64_t * data)
val64 = readq(&bar0->mc_rldram_test_ctrl);
val64 |= MC_RLDRAM_TEST_MODE;
- writeq(val64, &bar0->mc_rldram_test_ctrl);
+ SPECIAL_REG_WRITE(val64, &bar0->mc_rldram_test_ctrl, LF);
val64 = readq(&bar0->mc_rldram_mrs);
val64 |= MC_RLDRAM_QUEUE_SIZE_ENABLE;
@@ -4378,17 +4890,12 @@ static int s2io_rldram_test(nic_t * sp, uint64_t * data)
}
writeq(val64, &bar0->mc_rldram_test_d2);
- val64 = (u64) (0x0000003fffff0000ULL);
+ val64 = (u64) (0x0000003ffffe0100ULL);
writeq(val64, &bar0->mc_rldram_test_add);
-
- val64 = MC_RLDRAM_TEST_MODE;
- writeq(val64, &bar0->mc_rldram_test_ctrl);
-
- val64 |=
- MC_RLDRAM_TEST_MODE | MC_RLDRAM_TEST_WRITE |
- MC_RLDRAM_TEST_GO;
- writeq(val64, &bar0->mc_rldram_test_ctrl);
+ val64 = MC_RLDRAM_TEST_MODE | MC_RLDRAM_TEST_WRITE |
+ MC_RLDRAM_TEST_GO;
+ SPECIAL_REG_WRITE(val64, &bar0->mc_rldram_test_ctrl, LF);
for (cnt = 0; cnt < 5; cnt++) {
val64 = readq(&bar0->mc_rldram_test_ctrl);
@@ -4400,11 +4907,8 @@ static int s2io_rldram_test(nic_t * sp, uint64_t * data)
if (cnt == 5)
break;
- val64 = MC_RLDRAM_TEST_MODE;
- writeq(val64, &bar0->mc_rldram_test_ctrl);
-
- val64 |= MC_RLDRAM_TEST_MODE | MC_RLDRAM_TEST_GO;
- writeq(val64, &bar0->mc_rldram_test_ctrl);
+ val64 = MC_RLDRAM_TEST_MODE | MC_RLDRAM_TEST_GO;
+ SPECIAL_REG_WRITE(val64, &bar0->mc_rldram_test_ctrl, LF);
for (cnt = 0; cnt < 5; cnt++) {
val64 = readq(&bar0->mc_rldram_test_ctrl);
@@ -4417,18 +4921,18 @@ static int s2io_rldram_test(nic_t * sp, uint64_t * data)
break;
val64 = readq(&bar0->mc_rldram_test_ctrl);
- if (val64 & MC_RLDRAM_TEST_PASS)
- test_pass = 1;
+ if (!(val64 & MC_RLDRAM_TEST_PASS))
+ test_fail = 1;
iteration++;
}
- if (!test_pass)
- *data = 1;
- else
- *data = 0;
+ *data = test_fail;
- return 0;
+ /* Bring the adapter out of test mode */
+ SPECIAL_REG_WRITE(0, &bar0->mc_rldram_test_ctrl, LF);
+
+ return test_fail;
}
/**
@@ -4601,19 +5105,20 @@ static void s2io_get_ethtool_stats(struct net_device *dev,
tmp_stats[i++] = stat_info->sw_stat.double_ecc_errs;
}
-int s2io_ethtool_get_regs_len(struct net_device *dev)
+static int s2io_ethtool_get_regs_len(struct net_device *dev)
{
return (XENA_REG_SPACE);
}
-u32 s2io_ethtool_get_rx_csum(struct net_device * dev)
+static u32 s2io_ethtool_get_rx_csum(struct net_device * dev)
{
nic_t *sp = dev->priv;
return (sp->rx_csum);
}
-int s2io_ethtool_set_rx_csum(struct net_device *dev, u32 data)
+
+static int s2io_ethtool_set_rx_csum(struct net_device *dev, u32 data)
{
nic_t *sp = dev->priv;
@@ -4624,17 +5129,19 @@ int s2io_ethtool_set_rx_csum(struct net_device *dev, u32 data)
return 0;
}
-int s2io_get_eeprom_len(struct net_device *dev)
+
+static int s2io_get_eeprom_len(struct net_device *dev)
{
return (XENA_EEPROM_SPACE);
}
-int s2io_ethtool_self_test_count(struct net_device *dev)
+static int s2io_ethtool_self_test_count(struct net_device *dev)
{
return (S2IO_TEST_LEN);
}
-void s2io_ethtool_get_strings(struct net_device *dev,
- u32 stringset, u8 * data)
+
+static void s2io_ethtool_get_strings(struct net_device *dev,
+ u32 stringset, u8 * data)
{
switch (stringset) {
case ETH_SS_TEST:
@@ -4650,7 +5157,7 @@ static int s2io_ethtool_get_stats_count(struct net_device *dev)
return (S2IO_STAT_LEN);
}
-int s2io_ethtool_op_set_tx_csum(struct net_device *dev, u32 data)
+static int s2io_ethtool_op_set_tx_csum(struct net_device *dev, u32 data)
{
if (data)
dev->features |= NETIF_F_IP_CSUM;
@@ -4703,7 +5210,7 @@ static struct ethtool_ops netdev_ethtool_ops = {
* function always return EOPNOTSUPPORTED
*/
-int s2io_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+static int s2io_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
{
return -EOPNOTSUPP;
}
@@ -4719,7 +5226,7 @@ int s2io_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
* file on failure.
*/
-int s2io_change_mtu(struct net_device *dev, int new_mtu)
+static int s2io_change_mtu(struct net_device *dev, int new_mtu)
{
nic_t *sp = dev->priv;
@@ -4932,7 +5439,7 @@ static void s2io_card_down(nic_t * sp)
static int s2io_card_up(nic_t * sp)
{
- int i, ret;
+ int i, ret = 0;
mac_info_t *mac_control;
struct config_param *config;
struct net_device *dev = (struct net_device *) sp->dev;
@@ -4944,6 +5451,15 @@ static int s2io_card_up(nic_t * sp)
return -ENODEV;
}
+ if (sp->intr_type == MSI)
+ ret = s2io_enable_msi(sp);
+ else if (sp->intr_type == MSI_X)
+ ret = s2io_enable_msi_x(sp);
+ if (ret) {
+ DBG_PRINT(ERR_DBG, "%s: Defaulting to INTA\n", dev->name);
+ sp->intr_type = INTA;
+ }
+
/*
* Initializing the Rx buffers. For now we are considering only 1
* Rx ring and initializing buffers into 30 Rx blocks
@@ -5058,16 +5574,7 @@ static int rx_osm_handler(ring_info_t *ring_data, RxD_t * rxdp)
((unsigned long) rxdp->Host_Control);
int ring_no = ring_data->ring_no;
u16 l3_csum, l4_csum;
-#ifdef CONFIG_2BUFF_MODE
- int buf0_len = RXD_GET_BUFFER0_SIZE(rxdp->Control_2);
- int buf2_len = RXD_GET_BUFFER2_SIZE(rxdp->Control_2);
- int get_block = ring_data->rx_curr_get_info.block_index;
- int get_off = ring_data->rx_curr_get_info.offset;
- buffAdd_t *ba = &ring_data->ba[get_block][get_off];
- unsigned char *buff;
-#else
- u16 len = (u16) ((RXD_GET_BUFFER0_SIZE(rxdp->Control_2)) >> 48);;
-#endif
+
skb->dev = dev;
if (rxdp->Control_1 & RXD_T_CODE) {
unsigned long long err = rxdp->Control_1 & RXD_T_CODE;
@@ -5084,19 +5591,36 @@ static int rx_osm_handler(ring_info_t *ring_data, RxD_t * rxdp)
rxdp->Host_Control = 0;
sp->rx_pkt_count++;
sp->stats.rx_packets++;
-#ifndef CONFIG_2BUFF_MODE
- sp->stats.rx_bytes += len;
-#else
- sp->stats.rx_bytes += buf0_len + buf2_len;
-#endif
+ if (sp->rxd_mode == RXD_MODE_1) {
+ int len = RXD_GET_BUFFER0_SIZE_1(rxdp->Control_2);
-#ifndef CONFIG_2BUFF_MODE
- skb_put(skb, len);
-#else
- buff = skb_push(skb, buf0_len);
- memcpy(buff, ba->ba_0, buf0_len);
- skb_put(skb, buf2_len);
-#endif
+ sp->stats.rx_bytes += len;
+ skb_put(skb, len);
+
+ } else if (sp->rxd_mode >= RXD_MODE_3A) {
+ int get_block = ring_data->rx_curr_get_info.block_index;
+ int get_off = ring_data->rx_curr_get_info.offset;
+ int buf0_len = RXD_GET_BUFFER0_SIZE_3(rxdp->Control_2);
+ int buf2_len = RXD_GET_BUFFER2_SIZE_3(rxdp->Control_2);
+ unsigned char *buff = skb_push(skb, buf0_len);
+
+ buffAdd_t *ba = &ring_data->ba[get_block][get_off];
+ sp->stats.rx_bytes += buf0_len + buf2_len;
+ memcpy(buff, ba->ba_0, buf0_len);
+
+ if (sp->rxd_mode == RXD_MODE_3A) {
+ int buf1_len = RXD_GET_BUFFER1_SIZE_3(rxdp->Control_2);
+
+ skb_put(skb, buf1_len);
+ skb->len += buf2_len;
+ skb->data_len += buf2_len;
+ skb->truesize += buf2_len;
+ skb_put(skb_shinfo(skb)->frag_list, buf2_len);
+ sp->stats.rx_bytes += buf1_len;
+
+ } else
+ skb_put(skb, buf2_len);
+ }
if ((rxdp->Control_1 & TCP_OR_UDP_FRAME) &&
(sp->rx_csum)) {
@@ -5228,8 +5752,11 @@ static void s2io_init_pci(nic_t * sp)
MODULE_AUTHOR("Raghavendra Koushik <raghavendra.koushik@neterion.com>");
MODULE_LICENSE("GPL");
+MODULE_VERSION(DRV_VERSION);
+
module_param(tx_fifo_num, int, 0);
module_param(rx_ring_num, int, 0);
+module_param(rx_ring_mode, int, 0);
module_param_array(tx_fifo_len, uint, NULL, 0);
module_param_array(rx_ring_sz, uint, NULL, 0);
module_param_array(rts_frm_len, uint, NULL, 0);
@@ -5241,10 +5768,12 @@ module_param(shared_splits, int, 0);
module_param(tmac_util_period, int, 0);
module_param(rmac_util_period, int, 0);
module_param(bimodal, bool, 0);
+module_param(l3l4hdr_size, int , 0);
#ifndef CONFIG_S2IO_NAPI
module_param(indicate_max_pkts, int, 0);
#endif
module_param(rxsync_frequency, int, 0);
+module_param(intr_type, int, 0);
/**
* s2io_init_nic - Initialization of the adapter .
@@ -5274,9 +5803,16 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
mac_info_t *mac_control;
struct config_param *config;
int mode;
+ u8 dev_intr_type = intr_type;
#ifdef CONFIG_S2IO_NAPI
- DBG_PRINT(ERR_DBG, "NAPI support has been enabled\n");
+ if (dev_intr_type != INTA) {
+ DBG_PRINT(ERR_DBG, "NAPI cannot be enabled when MSI/MSI-X \
+is enabled. Defaulting to INTA\n");
+ dev_intr_type = INTA;
+ }
+ else
+ DBG_PRINT(ERR_DBG, "NAPI support has been enabled\n");
#endif
if ((ret = pci_enable_device(pdev))) {
@@ -5303,10 +5839,35 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
return -ENOMEM;
}
- if (pci_request_regions(pdev, s2io_driver_name)) {
- DBG_PRINT(ERR_DBG, "Request Regions failed\n"),
- pci_disable_device(pdev);
- return -ENODEV;
+ if ((dev_intr_type == MSI_X) &&
+ ((pdev->device != PCI_DEVICE_ID_HERC_WIN) &&
+ (pdev->device != PCI_DEVICE_ID_HERC_UNI))) {
+ DBG_PRINT(ERR_DBG, "Xframe I does not support MSI_X. \
+Defaulting to INTA\n");
+ dev_intr_type = INTA;
+ }
+ if (dev_intr_type != MSI_X) {
+ if (pci_request_regions(pdev, s2io_driver_name)) {
+ DBG_PRINT(ERR_DBG, "Request Regions failed\n"),
+ pci_disable_device(pdev);
+ return -ENODEV;
+ }
+ }
+ else {
+ if (!(request_mem_region(pci_resource_start(pdev, 0),
+ pci_resource_len(pdev, 0), s2io_driver_name))) {
+ DBG_PRINT(ERR_DBG, "bar0 Request Regions failed\n");
+ pci_disable_device(pdev);
+ return -ENODEV;
+ }
+ if (!(request_mem_region(pci_resource_start(pdev, 2),
+ pci_resource_len(pdev, 2), s2io_driver_name))) {
+ DBG_PRINT(ERR_DBG, "bar1 Request Regions failed\n");
+ release_mem_region(pci_resource_start(pdev, 0),
+ pci_resource_len(pdev, 0));
+ pci_disable_device(pdev);
+ return -ENODEV;
+ }
}
dev = alloc_etherdev(sizeof(nic_t));
@@ -5329,6 +5890,14 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
sp->pdev = pdev;
sp->high_dma_flag = dma_flag;
sp->device_enabled_once = FALSE;
+ if (rx_ring_mode == 1)
+ sp->rxd_mode = RXD_MODE_1;
+ if (rx_ring_mode == 2)
+ sp->rxd_mode = RXD_MODE_3B;
+ if (rx_ring_mode == 3)
+ sp->rxd_mode = RXD_MODE_3A;
+
+ sp->intr_type = dev_intr_type;
if ((pdev->device == PCI_DEVICE_ID_HERC_WIN) ||
(pdev->device == PCI_DEVICE_ID_HERC_UNI))
@@ -5336,6 +5905,7 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
else
sp->device_type = XFRAME_I_DEVICE;
+
/* Initialize some PCI/PCI-X fields of the NIC. */
s2io_init_pci(sp);
@@ -5379,7 +5949,7 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
config->rx_ring_num = rx_ring_num;
for (i = 0; i < MAX_RX_RINGS; i++) {
config->rx_cfg[i].num_rxd = rx_ring_sz[i] *
- (MAX_RXDS_PER_BLOCK + 1);
+ (rxd_count[sp->rxd_mode] + 1);
config->rx_cfg[i].ring_priority = i;
}
@@ -5571,12 +6141,20 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
if (sp->device_type & XFRAME_II_DEVICE) {
DBG_PRINT(ERR_DBG, "%s: Neterion Xframe II 10GbE adapter ",
dev->name);
- DBG_PRINT(ERR_DBG, "(rev %d), %s",
+ DBG_PRINT(ERR_DBG, "(rev %d), Version %s",
get_xena_rev_id(sp->pdev),
s2io_driver_version);
-#ifdef CONFIG_2BUFF_MODE
- DBG_PRINT(ERR_DBG, ", Buffer mode %d",2);
-#endif
+ switch(sp->intr_type) {
+ case INTA:
+ DBG_PRINT(ERR_DBG, ", Intr type INTA");
+ break;
+ case MSI:
+ DBG_PRINT(ERR_DBG, ", Intr type MSI");
+ break;
+ case MSI_X:
+ DBG_PRINT(ERR_DBG, ", Intr type MSI-X");
+ break;
+ }
DBG_PRINT(ERR_DBG, "\nCopyright(c) 2002-2005 Neterion Inc.\n");
DBG_PRINT(ERR_DBG, "MAC ADDR: %02x:%02x:%02x:%02x:%02x:%02x\n",
@@ -5595,12 +6173,20 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
} else {
DBG_PRINT(ERR_DBG, "%s: Neterion Xframe I 10GbE adapter ",
dev->name);
- DBG_PRINT(ERR_DBG, "(rev %d), %s",
+ DBG_PRINT(ERR_DBG, "(rev %d), Version %s",
get_xena_rev_id(sp->pdev),
s2io_driver_version);
-#ifdef CONFIG_2BUFF_MODE
- DBG_PRINT(ERR_DBG, ", Buffer mode %d",2);
-#endif
+ switch(sp->intr_type) {
+ case INTA:
+ DBG_PRINT(ERR_DBG, ", Intr type INTA");
+ break;
+ case MSI:
+ DBG_PRINT(ERR_DBG, ", Intr type MSI");
+ break;
+ case MSI_X:
+ DBG_PRINT(ERR_DBG, ", Intr type MSI-X");
+ break;
+ }
DBG_PRINT(ERR_DBG, "\nCopyright(c) 2002-2005 Neterion Inc.\n");
DBG_PRINT(ERR_DBG, "MAC ADDR: %02x:%02x:%02x:%02x:%02x:%02x\n",
sp->def_mac_addr[0].mac_addr[0],
@@ -5610,6 +6196,12 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
sp->def_mac_addr[0].mac_addr[4],
sp->def_mac_addr[0].mac_addr[5]);
}
+ if (sp->rxd_mode == RXD_MODE_3B)
+ DBG_PRINT(ERR_DBG, "%s: 2-Buffer mode support has been "
+ "enabled\n",dev->name);
+ if (sp->rxd_mode == RXD_MODE_3A)
+ DBG_PRINT(ERR_DBG, "%s: 3-Buffer mode support has been "
+ "enabled\n",dev->name);
/* Initialize device name */
strcpy(sp->name, dev->name);
@@ -5644,7 +6236,14 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
mem_alloc_failed:
free_shared_mem(sp);
pci_disable_device(pdev);
- pci_release_regions(pdev);
+ if (dev_intr_type != MSI_X)
+ pci_release_regions(pdev);
+ else {
+ release_mem_region(pci_resource_start(pdev, 0),
+ pci_resource_len(pdev, 0));
+ release_mem_region(pci_resource_start(pdev, 2),
+ pci_resource_len(pdev, 2));
+ }
pci_set_drvdata(pdev, NULL);
free_netdev(dev);
@@ -5678,7 +6277,14 @@ static void __devexit s2io_rem_nic(struct pci_dev *pdev)
iounmap(sp->bar0);
iounmap(sp->bar1);
pci_disable_device(pdev);
- pci_release_regions(pdev);
+ if (sp->intr_type != MSI_X)
+ pci_release_regions(pdev);
+ else {
+ release_mem_region(pci_resource_start(pdev, 0),
+ pci_resource_len(pdev, 0));
+ release_mem_region(pci_resource_start(pdev, 2),
+ pci_resource_len(pdev, 2));
+ }
pci_set_drvdata(pdev, NULL);
free_netdev(dev);
}
diff --git a/drivers/net/s2io.h b/drivers/net/s2io.h
index 89151cb52181..419aad7f10e7 100644
--- a/drivers/net/s2io.h
+++ b/drivers/net/s2io.h
@@ -418,7 +418,7 @@ typedef struct list_info_hold {
void *list_virt_addr;
} list_info_hold_t;
-/* Rx descriptor structure */
+/* Rx descriptor structure for 1 buffer mode */
typedef struct _RxD_t {
u64 Host_Control; /* reserved for host */
u64 Control_1;
@@ -439,49 +439,54 @@ typedef struct _RxD_t {
#define SET_RXD_MARKER vBIT(THE_RXD_MARK, 0, 2)
#define GET_RXD_MARKER(ctrl) ((ctrl & SET_RXD_MARKER) >> 62)
-#ifndef CONFIG_2BUFF_MODE
-#define MASK_BUFFER0_SIZE vBIT(0x3FFF,2,14)
-#define SET_BUFFER0_SIZE(val) vBIT(val,2,14)
-#else
-#define MASK_BUFFER0_SIZE vBIT(0xFF,2,14)
-#define MASK_BUFFER1_SIZE vBIT(0xFFFF,16,16)
-#define MASK_BUFFER2_SIZE vBIT(0xFFFF,32,16)
-#define SET_BUFFER0_SIZE(val) vBIT(val,8,8)
-#define SET_BUFFER1_SIZE(val) vBIT(val,16,16)
-#define SET_BUFFER2_SIZE(val) vBIT(val,32,16)
-#endif
-
#define MASK_VLAN_TAG vBIT(0xFFFF,48,16)
#define SET_VLAN_TAG(val) vBIT(val,48,16)
#define SET_NUM_TAG(val) vBIT(val,16,32)
-#ifndef CONFIG_2BUFF_MODE
-#define RXD_GET_BUFFER0_SIZE(Control_2) (u64)((Control_2 & vBIT(0x3FFF,2,14)))
-#else
-#define RXD_GET_BUFFER0_SIZE(Control_2) (u8)((Control_2 & MASK_BUFFER0_SIZE) \
- >> 48)
-#define RXD_GET_BUFFER1_SIZE(Control_2) (u16)((Control_2 & MASK_BUFFER1_SIZE) \
- >> 32)
-#define RXD_GET_BUFFER2_SIZE(Control_2) (u16)((Control_2 & MASK_BUFFER2_SIZE) \
- >> 16)
+
+} RxD_t;
+/* Rx descriptor structure for 1 buffer mode */
+typedef struct _RxD1_t {
+ struct _RxD_t h;
+
+#define MASK_BUFFER0_SIZE_1 vBIT(0x3FFF,2,14)
+#define SET_BUFFER0_SIZE_1(val) vBIT(val,2,14)
+#define RXD_GET_BUFFER0_SIZE_1(_Control_2) \
+ (u16)((_Control_2 & MASK_BUFFER0_SIZE_1) >> 48)
+ u64 Buffer0_ptr;
+} RxD1_t;
+/* Rx descriptor structure for 3 or 2 buffer mode */
+
+typedef struct _RxD3_t {
+ struct _RxD_t h;
+
+#define MASK_BUFFER0_SIZE_3 vBIT(0xFF,2,14)
+#define MASK_BUFFER1_SIZE_3 vBIT(0xFFFF,16,16)
+#define MASK_BUFFER2_SIZE_3 vBIT(0xFFFF,32,16)
+#define SET_BUFFER0_SIZE_3(val) vBIT(val,8,8)
+#define SET_BUFFER1_SIZE_3(val) vBIT(val,16,16)
+#define SET_BUFFER2_SIZE_3(val) vBIT(val,32,16)
+#define RXD_GET_BUFFER0_SIZE_3(Control_2) \
+ (u8)((Control_2 & MASK_BUFFER0_SIZE_3) >> 48)
+#define RXD_GET_BUFFER1_SIZE_3(Control_2) \
+ (u16)((Control_2 & MASK_BUFFER1_SIZE_3) >> 32)
+#define RXD_GET_BUFFER2_SIZE_3(Control_2) \
+ (u16)((Control_2 & MASK_BUFFER2_SIZE_3) >> 16)
#define BUF0_LEN 40
#define BUF1_LEN 1
-#endif
u64 Buffer0_ptr;
-#ifdef CONFIG_2BUFF_MODE
u64 Buffer1_ptr;
u64 Buffer2_ptr;
-#endif
-} RxD_t;
+} RxD3_t;
+
/* Structure that represents the Rx descriptor block which contains
* 128 Rx descriptors.
*/
-#ifndef CONFIG_2BUFF_MODE
typedef struct _RxD_block {
-#define MAX_RXDS_PER_BLOCK 127
- RxD_t rxd[MAX_RXDS_PER_BLOCK];
+#define MAX_RXDS_PER_BLOCK_1 127
+ RxD1_t rxd[MAX_RXDS_PER_BLOCK_1];
u64 reserved_0;
#define END_OF_BLOCK 0xFEFFFFFFFFFFFFFFULL
@@ -492,18 +497,13 @@ typedef struct _RxD_block {
* the upper 32 bits should
* be 0 */
} RxD_block_t;
-#else
-typedef struct _RxD_block {
-#define MAX_RXDS_PER_BLOCK 85
- RxD_t rxd[MAX_RXDS_PER_BLOCK];
-#define END_OF_BLOCK 0xFEFFFFFFFFFFFFFFULL
- u64 reserved_1; /* 0xFEFFFFFFFFFFFFFF to mark last Rxd
- * in this blk */
- u64 pNext_RxD_Blk_physical; /* Phy ponter to next blk. */
-} RxD_block_t;
#define SIZE_OF_BLOCK 4096
+#define RXD_MODE_1 0
+#define RXD_MODE_3A 1
+#define RXD_MODE_3B 2
+
/* Structure to hold virtual addresses of Buf0 and Buf1 in
* 2buf mode. */
typedef struct bufAdd {
@@ -512,7 +512,6 @@ typedef struct bufAdd {
void *ba_0;
void *ba_1;
} buffAdd_t;
-#endif
/* Structure which stores all the MAC control parameters */
@@ -539,10 +538,17 @@ typedef struct {
typedef tx_curr_get_info_t tx_curr_put_info_t;
+
+typedef struct rxd_info {
+ void *virt_addr;
+ dma_addr_t dma_addr;
+}rxd_info_t;
+
/* Structure that holds the Phy and virt addresses of the Blocks */
typedef struct rx_block_info {
- RxD_t *block_virt_addr;
+ void *block_virt_addr;
dma_addr_t block_dma_addr;
+ rxd_info_t *rxds;
} rx_block_info_t;
/* pre declaration of the nic structure */
@@ -578,10 +584,8 @@ typedef struct ring_info {
int put_pos;
#endif
-#ifdef CONFIG_2BUFF_MODE
/* Buffer Address store. */
buffAdd_t **ba;
-#endif
nic_t *nic;
} ring_info_t;
@@ -647,13 +651,36 @@ typedef struct {
/* Default Tunable parameters of the NIC. */
#define DEFAULT_FIFO_LEN 4096
-#define SMALL_RXD_CNT 30 * (MAX_RXDS_PER_BLOCK+1)
-#define LARGE_RXD_CNT 100 * (MAX_RXDS_PER_BLOCK+1)
#define SMALL_BLK_CNT 30
#define LARGE_BLK_CNT 100
+/*
+ * Structure to keep track of the MSI-X vectors and the corresponding
+ * argument registered against each vector
+ */
+#define MAX_REQUESTED_MSI_X 17
+struct s2io_msix_entry
+{
+ u16 vector;
+ u16 entry;
+ void *arg;
+
+ u8 type;
+#define MSIX_FIFO_TYPE 1
+#define MSIX_RING_TYPE 2
+
+ u8 in_use;
+#define MSIX_REGISTERED_SUCCESS 0xAA
+};
+
+struct msix_info_st {
+ u64 addr;
+ u64 data;
+};
+
/* Structure representing one instance of the NIC */
struct s2io_nic {
+ int rxd_mode;
#ifdef CONFIG_S2IO_NAPI
/*
* Count of packets to be processed in a given iteration, it will be indicated
@@ -719,13 +746,8 @@ struct s2io_nic {
* a schedule task that will set the correct Link state once the
* NIC's PHY has stabilized after a state change.
*/
-#ifdef INIT_TQUEUE
- struct tq_struct rst_timer_task;
- struct tq_struct set_link_task;
-#else
struct work_struct rst_timer_task;
struct work_struct set_link_task;
-#endif
/* Flag that can be used to turn on or turn off the Rx checksum
* offload feature.
@@ -748,10 +770,23 @@ struct s2io_nic {
atomic_t card_state;
volatile unsigned long link_state;
struct vlan_group *vlgrp;
+#define MSIX_FLG 0xA5
+ struct msix_entry *entries;
+ struct s2io_msix_entry *s2io_entries;
+ char desc1[35];
+ char desc2[35];
+
+ struct msix_info_st msix_info[0x3f];
+
#define XFRAME_I_DEVICE 1
#define XFRAME_II_DEVICE 2
u8 device_type;
+#define INTA 0
+#define MSI 1
+#define MSI_X 2
+ u8 intr_type;
+
spinlock_t rx_lock;
atomic_t isr_cnt;
};
@@ -886,6 +921,13 @@ static int s2io_poll(struct net_device *dev, int *budget);
static void s2io_init_pci(nic_t * sp);
int s2io_set_mac_addr(struct net_device *dev, u8 * addr);
static void s2io_alarm_handle(unsigned long data);
+static int s2io_enable_msi(nic_t *nic);
+static irqreturn_t s2io_msi_handle(int irq, void *dev_id, struct pt_regs *regs);
+static irqreturn_t
+s2io_msix_ring_handle(int irq, void *dev_id, struct pt_regs *regs);
+static irqreturn_t
+s2io_msix_fifo_handle(int irq, void *dev_id, struct pt_regs *regs);
+int s2io_enable_msi_x(nic_t *nic);
static irqreturn_t s2io_isr(int irq, void *dev_id, struct pt_regs *regs);
static int verify_xena_quiescence(nic_t *sp, u64 val64, int flag);
static struct ethtool_ops netdev_ethtool_ops;
@@ -894,4 +936,5 @@ int s2io_set_swapper(nic_t * sp);
static void s2io_card_down(nic_t *nic);
static int s2io_card_up(nic_t *nic);
int get_xena_rev_id(struct pci_dev *pdev);
+void restore_xmsi_data(nic_t *nic);
#endif /* _S2IO_H */
diff --git a/drivers/net/saa9730.c b/drivers/net/saa9730.c
index fd0167077fbe..110e777f206e 100644
--- a/drivers/net/saa9730.c
+++ b/drivers/net/saa9730.c
@@ -997,10 +997,7 @@ static void __devexit saa9730_remove_one(struct pci_dev *pdev)
if (dev) {
unregister_netdev(dev);
-
- if (dev->priv)
- kfree(dev->priv);
-
+ kfree(dev->priv);
free_netdev(dev);
pci_release_regions(pdev);
pci_disable_device(pdev);
@@ -1096,8 +1093,7 @@ static int lan_saa9730_init(struct net_device *dev, int ioaddr, int irq)
return 0;
out:
- if (dev->priv)
- kfree(dev->priv);
+ kfree(dev->priv);
return ret;
}
diff --git a/drivers/net/sb1250-mac.c b/drivers/net/sb1250-mac.c
index 7abd55a4fb21..aa4ca1821759 100644
--- a/drivers/net/sb1250-mac.c
+++ b/drivers/net/sb1250-mac.c
@@ -10,7 +10,7 @@
* 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.
@@ -118,8 +118,6 @@ MODULE_PARM_DESC(int_timeout, "Timeout value");
********************************************************************* */
-typedef unsigned long sbmac_port_t;
-
typedef enum { sbmac_speed_auto, sbmac_speed_10,
sbmac_speed_100, sbmac_speed_1000 } sbmac_speed_t;
@@ -129,7 +127,7 @@ typedef enum { sbmac_duplex_auto, sbmac_duplex_half,
typedef enum { sbmac_fc_auto, sbmac_fc_disabled, sbmac_fc_frame,
sbmac_fc_collision, sbmac_fc_carrier } sbmac_fc_t;
-typedef enum { sbmac_state_uninit, sbmac_state_off, sbmac_state_on,
+typedef enum { sbmac_state_uninit, sbmac_state_off, sbmac_state_on,
sbmac_state_broken } sbmac_state_t;
@@ -144,17 +142,13 @@ typedef enum { sbmac_state_uninit, sbmac_state_off, sbmac_state_on,
#define NUMCACHEBLKS(x) (((x)+SMP_CACHE_BYTES-1)/SMP_CACHE_BYTES)
-#define SBMAC_READCSR(t) __raw_readq((unsigned long)t)
-#define SBMAC_WRITECSR(t,v) __raw_writeq(v, (unsigned long)t)
-
-
#define SBMAC_MAX_TXDESCR 32
#define SBMAC_MAX_RXDESCR 32
#define ETHER_ALIGN 2
#define ETHER_ADDR_LEN 6
-#define ENET_PACKET_SIZE 1518
-/*#define ENET_PACKET_SIZE 9216 */
+#define ENET_PACKET_SIZE 1518
+/*#define ENET_PACKET_SIZE 9216 */
/**********************************************************************
* DMA Descriptor structure
@@ -172,12 +166,12 @@ typedef unsigned long paddr_t;
********************************************************************* */
typedef struct sbmacdma_s {
-
- /*
+
+ /*
* This stuff is used to identify the channel and the registers
* associated with it.
*/
-
+
struct sbmac_softc *sbdma_eth; /* back pointer to associated MAC */
int sbdma_channel; /* channel number */
int sbdma_txdir; /* direction (1=transmit) */
@@ -187,21 +181,21 @@ typedef struct sbmacdma_s {
int sbdma_int_timeout; /* # usec rx/tx interrupt */
#endif
- sbmac_port_t sbdma_config0; /* DMA config register 0 */
- sbmac_port_t sbdma_config1; /* DMA config register 1 */
- sbmac_port_t sbdma_dscrbase; /* Descriptor base address */
- sbmac_port_t sbdma_dscrcnt; /* Descriptor count register */
- sbmac_port_t sbdma_curdscr; /* current descriptor address */
-
+ volatile void __iomem *sbdma_config0; /* DMA config register 0 */
+ volatile void __iomem *sbdma_config1; /* DMA config register 1 */
+ volatile void __iomem *sbdma_dscrbase; /* Descriptor base address */
+ volatile void __iomem *sbdma_dscrcnt; /* Descriptor count register */
+ volatile void __iomem *sbdma_curdscr; /* current descriptor address */
+
/*
* This stuff is for maintenance of the ring
*/
-
+
sbdmadscr_t *sbdma_dscrtable; /* base of descriptor table */
sbdmadscr_t *sbdma_dscrtable_end; /* end of descriptor table */
-
+
struct sk_buff **sbdma_ctxtable; /* context table, one per descr */
-
+
paddr_t sbdma_dscrtable_phys; /* and also the phys addr */
sbdmadscr_t *sbdma_addptr; /* next dscr for sw to add */
sbdmadscr_t *sbdma_remptr; /* next dscr for sw to remove */
@@ -213,15 +207,15 @@ typedef struct sbmacdma_s {
********************************************************************* */
struct sbmac_softc {
-
+
/*
* Linux-specific things
*/
-
+
struct net_device *sbm_dev; /* pointer to linux device */
spinlock_t sbm_lock; /* spin lock */
struct timer_list sbm_timer; /* for monitoring MII */
- struct net_device_stats sbm_stats;
+ struct net_device_stats sbm_stats;
int sbm_devflags; /* current device flags */
int sbm_phy_oldbmsr;
@@ -229,31 +223,31 @@ struct sbmac_softc {
int sbm_phy_oldk1stsr;
int sbm_phy_oldlinkstat;
int sbm_buffersize;
-
+
unsigned char sbm_phys[2];
-
+
/*
* Controller-specific things
*/
-
- unsigned long sbm_base; /* MAC's base address */
+
+ volatile void __iomem *sbm_base; /* MAC's base address */
sbmac_state_t sbm_state; /* current state */
-
- sbmac_port_t sbm_macenable; /* MAC Enable Register */
- sbmac_port_t sbm_maccfg; /* MAC Configuration Register */
- sbmac_port_t sbm_fifocfg; /* FIFO configuration register */
- sbmac_port_t sbm_framecfg; /* Frame configuration register */
- sbmac_port_t sbm_rxfilter; /* receive filter register */
- sbmac_port_t sbm_isr; /* Interrupt status register */
- sbmac_port_t sbm_imr; /* Interrupt mask register */
- sbmac_port_t sbm_mdio; /* MDIO register */
-
+
+ volatile void __iomem *sbm_macenable; /* MAC Enable Register */
+ volatile void __iomem *sbm_maccfg; /* MAC Configuration Register */
+ volatile void __iomem *sbm_fifocfg; /* FIFO configuration register */
+ volatile void __iomem *sbm_framecfg; /* Frame configuration register */
+ volatile void __iomem *sbm_rxfilter; /* receive filter register */
+ volatile void __iomem *sbm_isr; /* Interrupt status register */
+ volatile void __iomem *sbm_imr; /* Interrupt mask register */
+ volatile void __iomem *sbm_mdio; /* MDIO register */
+
sbmac_speed_t sbm_speed; /* current speed */
sbmac_duplex_t sbm_duplex; /* current duplex */
sbmac_fc_t sbm_fc; /* current flow control setting */
-
+
unsigned char sbm_hwaddr[ETHER_ADDR_LEN];
-
+
sbmacdma_t sbm_txdma; /* for now, only use channel 0 */
sbmacdma_t sbm_rxdma;
int rx_hw_checksum;
@@ -302,6 +296,7 @@ static void sbmac_set_rx_mode(struct net_device *dev);
static int sbmac_mii_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
static int sbmac_close(struct net_device *dev);
static int sbmac_mii_poll(struct sbmac_softc *s,int noisy);
+static int sbmac_mii_probe(struct net_device *dev);
static void sbmac_mii_sync(struct sbmac_softc *s);
static void sbmac_mii_senddata(struct sbmac_softc *s,unsigned int data, int bitcnt);
@@ -439,6 +434,9 @@ static uint64_t sbmac_orig_hwaddr[MAX_UNITS];
#define MII_BMCR 0x00 /* Basic mode control register (rw) */
#define MII_BMSR 0x01 /* Basic mode status register (ro) */
+#define MII_PHYIDR1 0x02
+#define MII_PHYIDR2 0x03
+
#define MII_K1STSR 0x0A /* 1K Status Register (ro) */
#define MII_ANLPAR 0x05 /* Autonegotiation lnk partner abilities (rw) */
@@ -450,13 +448,13 @@ static uint64_t sbmac_orig_hwaddr[MAX_UNITS];
/**********************************************************************
* SBMAC_MII_SYNC(s)
- *
+ *
* Synchronize with the MII - send a pattern of bits to the MII
* that will guarantee that it is ready to accept a command.
- *
- * Input parameters:
+ *
+ * Input parameters:
* s - sbmac structure
- *
+ *
* Return value:
* nothing
********************************************************************* */
@@ -467,25 +465,25 @@ static void sbmac_mii_sync(struct sbmac_softc *s)
uint64_t bits;
int mac_mdio_genc;
- mac_mdio_genc = SBMAC_READCSR(s->sbm_mdio) & M_MAC_GENC;
-
+ mac_mdio_genc = __raw_readq(s->sbm_mdio) & M_MAC_GENC;
+
bits = M_MAC_MDIO_DIR_OUTPUT | M_MAC_MDIO_OUT;
-
- SBMAC_WRITECSR(s->sbm_mdio,bits | mac_mdio_genc);
-
+
+ __raw_writeq(bits | mac_mdio_genc, s->sbm_mdio);
+
for (cnt = 0; cnt < 32; cnt++) {
- SBMAC_WRITECSR(s->sbm_mdio,bits | M_MAC_MDC | mac_mdio_genc);
- SBMAC_WRITECSR(s->sbm_mdio,bits | mac_mdio_genc);
+ __raw_writeq(bits | M_MAC_MDC | mac_mdio_genc, s->sbm_mdio);
+ __raw_writeq(bits | mac_mdio_genc, s->sbm_mdio);
}
}
/**********************************************************************
* SBMAC_MII_SENDDATA(s,data,bitcnt)
- *
+ *
* Send some bits to the MII. The bits to be sent are right-
* justified in the 'data' parameter.
- *
- * Input parameters:
+ *
+ * Input parameters:
* s - sbmac structure
* data - data to send
* bitcnt - number of bits to send
@@ -498,20 +496,20 @@ static void sbmac_mii_senddata(struct sbmac_softc *s,unsigned int data, int bitc
unsigned int curmask;
int mac_mdio_genc;
- mac_mdio_genc = SBMAC_READCSR(s->sbm_mdio) & M_MAC_GENC;
-
+ mac_mdio_genc = __raw_readq(s->sbm_mdio) & M_MAC_GENC;
+
bits = M_MAC_MDIO_DIR_OUTPUT;
- SBMAC_WRITECSR(s->sbm_mdio,bits | mac_mdio_genc);
-
+ __raw_writeq(bits | mac_mdio_genc, s->sbm_mdio);
+
curmask = 1 << (bitcnt - 1);
-
+
for (i = 0; i < bitcnt; i++) {
if (data & curmask)
bits |= M_MAC_MDIO_OUT;
else bits &= ~M_MAC_MDIO_OUT;
- SBMAC_WRITECSR(s->sbm_mdio,bits | mac_mdio_genc);
- SBMAC_WRITECSR(s->sbm_mdio,bits | M_MAC_MDC | mac_mdio_genc);
- SBMAC_WRITECSR(s->sbm_mdio,bits | mac_mdio_genc);
+ __raw_writeq(bits | mac_mdio_genc, s->sbm_mdio);
+ __raw_writeq(bits | M_MAC_MDC | mac_mdio_genc, s->sbm_mdio);
+ __raw_writeq(bits | mac_mdio_genc, s->sbm_mdio);
curmask >>= 1;
}
}
@@ -520,14 +518,14 @@ static void sbmac_mii_senddata(struct sbmac_softc *s,unsigned int data, int bitc
/**********************************************************************
* SBMAC_MII_READ(s,phyaddr,regidx)
- *
+ *
* Read a PHY register.
- *
- * Input parameters:
+ *
+ * Input parameters:
* s - sbmac structure
* phyaddr - PHY's address
* regidx = index of register to read
- *
+ *
* Return value:
* value read, or 0 if an error occurred.
********************************************************************* */
@@ -543,9 +541,9 @@ static unsigned int sbmac_mii_read(struct sbmac_softc *s,int phyaddr,int regidx)
* Synchronize ourselves so that the PHY knows the next
* thing coming down is a command
*/
-
+
sbmac_mii_sync(s);
-
+
/*
* Send the data to the PHY. The sequence is
* a "start" command (2 bits)
@@ -553,59 +551,55 @@ static unsigned int sbmac_mii_read(struct sbmac_softc *s,int phyaddr,int regidx)
* the PHY addr (5 bits)
* the register index (5 bits)
*/
-
+
sbmac_mii_senddata(s,MII_COMMAND_START, 2);
sbmac_mii_senddata(s,MII_COMMAND_READ, 2);
sbmac_mii_senddata(s,phyaddr, 5);
sbmac_mii_senddata(s,regidx, 5);
-
- mac_mdio_genc = SBMAC_READCSR(s->sbm_mdio) & M_MAC_GENC;
-
- /*
+
+ mac_mdio_genc = __raw_readq(s->sbm_mdio) & M_MAC_GENC;
+
+ /*
* Switch the port around without a clock transition.
*/
- SBMAC_WRITECSR(s->sbm_mdio,M_MAC_MDIO_DIR_INPUT | mac_mdio_genc);
-
+ __raw_writeq(M_MAC_MDIO_DIR_INPUT | mac_mdio_genc, s->sbm_mdio);
+
/*
* Send out a clock pulse to signal we want the status
*/
-
- SBMAC_WRITECSR(s->sbm_mdio,
- M_MAC_MDIO_DIR_INPUT | M_MAC_MDC | mac_mdio_genc);
- SBMAC_WRITECSR(s->sbm_mdio,M_MAC_MDIO_DIR_INPUT | mac_mdio_genc);
-
- /*
+
+ __raw_writeq(M_MAC_MDIO_DIR_INPUT | M_MAC_MDC | mac_mdio_genc, s->sbm_mdio);
+ __raw_writeq(M_MAC_MDIO_DIR_INPUT | mac_mdio_genc, s->sbm_mdio);
+
+ /*
* If an error occurred, the PHY will signal '1' back
*/
- error = SBMAC_READCSR(s->sbm_mdio) & M_MAC_MDIO_IN;
-
- /*
+ error = __raw_readq(s->sbm_mdio) & M_MAC_MDIO_IN;
+
+ /*
* Issue an 'idle' clock pulse, but keep the direction
* the same.
*/
- SBMAC_WRITECSR(s->sbm_mdio,
- M_MAC_MDIO_DIR_INPUT | M_MAC_MDC | mac_mdio_genc);
- SBMAC_WRITECSR(s->sbm_mdio,M_MAC_MDIO_DIR_INPUT | mac_mdio_genc);
-
+ __raw_writeq(M_MAC_MDIO_DIR_INPUT | M_MAC_MDC | mac_mdio_genc, s->sbm_mdio);
+ __raw_writeq(M_MAC_MDIO_DIR_INPUT | mac_mdio_genc, s->sbm_mdio);
+
regval = 0;
-
+
for (idx = 0; idx < 16; idx++) {
regval <<= 1;
-
+
if (error == 0) {
- if (SBMAC_READCSR(s->sbm_mdio) & M_MAC_MDIO_IN)
+ if (__raw_readq(s->sbm_mdio) & M_MAC_MDIO_IN)
regval |= 1;
}
-
- SBMAC_WRITECSR(s->sbm_mdio,
- M_MAC_MDIO_DIR_INPUT|M_MAC_MDC | mac_mdio_genc);
- SBMAC_WRITECSR(s->sbm_mdio,
- M_MAC_MDIO_DIR_INPUT | mac_mdio_genc);
+
+ __raw_writeq(M_MAC_MDIO_DIR_INPUT|M_MAC_MDC | mac_mdio_genc, s->sbm_mdio);
+ __raw_writeq(M_MAC_MDIO_DIR_INPUT | mac_mdio_genc, s->sbm_mdio);
}
-
+
/* Switch back to output */
- SBMAC_WRITECSR(s->sbm_mdio,M_MAC_MDIO_DIR_OUTPUT | mac_mdio_genc);
-
+ __raw_writeq(M_MAC_MDIO_DIR_OUTPUT | mac_mdio_genc, s->sbm_mdio);
+
if (error == 0)
return regval;
return 0;
@@ -614,15 +608,15 @@ static unsigned int sbmac_mii_read(struct sbmac_softc *s,int phyaddr,int regidx)
/**********************************************************************
* SBMAC_MII_WRITE(s,phyaddr,regidx,regval)
- *
+ *
* Write a value to a PHY register.
- *
- * Input parameters:
+ *
+ * Input parameters:
* s - sbmac structure
* phyaddr - PHY to use
* regidx - register within the PHY
* regval - data to write to register
- *
+ *
* Return value:
* nothing
********************************************************************* */
@@ -633,7 +627,7 @@ static void sbmac_mii_write(struct sbmac_softc *s,int phyaddr,int regidx,
int mac_mdio_genc;
sbmac_mii_sync(s);
-
+
sbmac_mii_senddata(s,MII_COMMAND_START,2);
sbmac_mii_senddata(s,MII_COMMAND_WRITE,2);
sbmac_mii_senddata(s,phyaddr, 5);
@@ -641,27 +635,27 @@ static void sbmac_mii_write(struct sbmac_softc *s,int phyaddr,int regidx,
sbmac_mii_senddata(s,MII_COMMAND_ACK,2);
sbmac_mii_senddata(s,regval,16);
- mac_mdio_genc = SBMAC_READCSR(s->sbm_mdio) & M_MAC_GENC;
+ mac_mdio_genc = __raw_readq(s->sbm_mdio) & M_MAC_GENC;
- SBMAC_WRITECSR(s->sbm_mdio,M_MAC_MDIO_DIR_OUTPUT | mac_mdio_genc);
+ __raw_writeq(M_MAC_MDIO_DIR_OUTPUT | mac_mdio_genc, s->sbm_mdio);
}
/**********************************************************************
* SBDMA_INITCTX(d,s,chan,txrx,maxdescr)
- *
+ *
* Initialize a DMA channel context. Since there are potentially
* eight DMA channels per MAC, it's nice to do this in a standard
- * way.
- *
- * Input parameters:
+ * way.
+ *
+ * Input parameters:
* d - sbmacdma_t structure (DMA channel context)
* s - sbmac_softc structure (pointer to a MAC)
* chan - channel number (0..1 right now)
* txrx - Identifies DMA_TX or DMA_RX for channel direction
* maxdescr - number of descriptors
- *
+ *
* Return value:
* nothing
********************************************************************* */
@@ -672,101 +666,87 @@ static void sbdma_initctx(sbmacdma_t *d,
int txrx,
int maxdescr)
{
- /*
- * Save away interesting stuff in the structure
+ /*
+ * Save away interesting stuff in the structure
*/
-
+
d->sbdma_eth = s;
d->sbdma_channel = chan;
d->sbdma_txdir = txrx;
-
+
#if 0
/* RMON clearing */
s->sbe_idx =(s->sbm_base - A_MAC_BASE_0)/MAC_SPACING;
#endif
- SBMAC_WRITECSR(IOADDR(
- A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_TX_BYTES)), 0);
- SBMAC_WRITECSR(IOADDR(
- A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_COLLISIONS)), 0);
- SBMAC_WRITECSR(IOADDR(
- A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_LATE_COL)), 0);
- SBMAC_WRITECSR(IOADDR(
- A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_EX_COL)), 0);
- SBMAC_WRITECSR(IOADDR(
- A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_FCS_ERROR)), 0);
- SBMAC_WRITECSR(IOADDR(
- A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_TX_ABORT)), 0);
- SBMAC_WRITECSR(IOADDR(
- A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_TX_BAD)), 0);
- SBMAC_WRITECSR(IOADDR(
- A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_TX_GOOD)), 0);
- SBMAC_WRITECSR(IOADDR(
- A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_TX_RUNT)), 0);
- SBMAC_WRITECSR(IOADDR(
- A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_TX_OVERSIZE)), 0);
- SBMAC_WRITECSR(IOADDR(
- A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_BYTES)), 0);
- SBMAC_WRITECSR(IOADDR(
- A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_MCAST)), 0);
- SBMAC_WRITECSR(IOADDR(
- A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_BCAST)), 0);
- SBMAC_WRITECSR(IOADDR(
- A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_BAD)), 0);
- SBMAC_WRITECSR(IOADDR(
- A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_GOOD)), 0);
- SBMAC_WRITECSR(IOADDR(
- A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_RUNT)), 0);
- SBMAC_WRITECSR(IOADDR(
- A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_OVERSIZE)), 0);
- SBMAC_WRITECSR(IOADDR(
- A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_FCS_ERROR)), 0);
- SBMAC_WRITECSR(IOADDR(
- A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_LENGTH_ERROR)), 0);
- SBMAC_WRITECSR(IOADDR(
- A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_CODE_ERROR)), 0);
- SBMAC_WRITECSR(IOADDR(
- A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_ALIGN_ERROR)), 0);
-
- /*
- * initialize register pointers
- */
-
- d->sbdma_config0 =
+ __raw_writeq(0, IOADDR(A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_TX_BYTES)));
+ __raw_writeq(0, IOADDR(A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_COLLISIONS)));
+ __raw_writeq(0, IOADDR(A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_LATE_COL)));
+ __raw_writeq(0, IOADDR(A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_EX_COL)));
+ __raw_writeq(0, IOADDR(A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_FCS_ERROR)));
+ __raw_writeq(0, IOADDR(A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_TX_ABORT)));
+ __raw_writeq(0, IOADDR(A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_TX_BAD)));
+ __raw_writeq(0, IOADDR(A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_TX_GOOD)));
+ __raw_writeq(0, IOADDR(A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_TX_RUNT)));
+ __raw_writeq(0, IOADDR(A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_TX_OVERSIZE)));
+ __raw_writeq(0, IOADDR(A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_BYTES)));
+ __raw_writeq(0, IOADDR(A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_MCAST)));
+ __raw_writeq(0, IOADDR(A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_BCAST)));
+ __raw_writeq(0, IOADDR(A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_BAD)));
+ __raw_writeq(0, IOADDR(A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_GOOD)));
+ __raw_writeq(0, IOADDR(A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_RUNT)));
+ __raw_writeq(0, IOADDR(A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_OVERSIZE)));
+ __raw_writeq(0, IOADDR(A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_FCS_ERROR)));
+ __raw_writeq(0, IOADDR(A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_LENGTH_ERROR)));
+ __raw_writeq(0, IOADDR(A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_CODE_ERROR)));
+ __raw_writeq(0, IOADDR(A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_ALIGN_ERROR)));
+
+ /*
+ * initialize register pointers
+ */
+
+ d->sbdma_config0 =
s->sbm_base + R_MAC_DMA_REGISTER(txrx,chan,R_MAC_DMA_CONFIG0);
- d->sbdma_config1 =
+ d->sbdma_config1 =
s->sbm_base + R_MAC_DMA_REGISTER(txrx,chan,R_MAC_DMA_CONFIG1);
- d->sbdma_dscrbase =
+ d->sbdma_dscrbase =
s->sbm_base + R_MAC_DMA_REGISTER(txrx,chan,R_MAC_DMA_DSCR_BASE);
- d->sbdma_dscrcnt =
+ d->sbdma_dscrcnt =
s->sbm_base + R_MAC_DMA_REGISTER(txrx,chan,R_MAC_DMA_DSCR_CNT);
- d->sbdma_curdscr =
+ d->sbdma_curdscr =
s->sbm_base + R_MAC_DMA_REGISTER(txrx,chan,R_MAC_DMA_CUR_DSCRADDR);
-
+
/*
* Allocate memory for the ring
*/
-
+
d->sbdma_maxdescr = maxdescr;
-
- d->sbdma_dscrtable = (sbdmadscr_t *)
- kmalloc(d->sbdma_maxdescr*sizeof(sbdmadscr_t), GFP_KERNEL);
-
+
+ d->sbdma_dscrtable = (sbdmadscr_t *)
+ kmalloc((d->sbdma_maxdescr+1)*sizeof(sbdmadscr_t), GFP_KERNEL);
+
+ /*
+ * The descriptor table must be aligned to at least 16 bytes or the
+ * MAC will corrupt it.
+ */
+ d->sbdma_dscrtable = (sbdmadscr_t *)
+ ALIGN((unsigned long)d->sbdma_dscrtable, sizeof(sbdmadscr_t));
+
memset(d->sbdma_dscrtable,0,d->sbdma_maxdescr*sizeof(sbdmadscr_t));
-
+
d->sbdma_dscrtable_end = d->sbdma_dscrtable + d->sbdma_maxdescr;
-
+
d->sbdma_dscrtable_phys = virt_to_phys(d->sbdma_dscrtable);
-
+
/*
* And context table
*/
-
- d->sbdma_ctxtable = (struct sk_buff **)
+
+ d->sbdma_ctxtable = (struct sk_buff **)
kmalloc(d->sbdma_maxdescr*sizeof(struct sk_buff *), GFP_KERNEL);
-
+
memset(d->sbdma_ctxtable,0,d->sbdma_maxdescr*sizeof(struct sk_buff *));
-
+
#ifdef CONFIG_SBMAC_COALESCE
/*
* Setup Rx/Tx DMA coalescing defaults
@@ -777,7 +757,7 @@ static void sbdma_initctx(sbmacdma_t *d,
} else {
d->sbdma_int_pktcnt = 1;
}
-
+
if ( int_timeout ) {
d->sbdma_int_timeout = int_timeout;
} else {
@@ -789,13 +769,13 @@ static void sbdma_initctx(sbmacdma_t *d,
/**********************************************************************
* SBDMA_CHANNEL_START(d)
- *
+ *
* Initialize the hardware registers for a DMA channel.
- *
- * Input parameters:
+ *
+ * Input parameters:
* d - DMA channel to init (context must be previously init'd
* rxtx - DMA_RX or DMA_TX depending on what type of channel
- *
+ *
* Return value:
* nothing
********************************************************************* */
@@ -805,24 +785,21 @@ static void sbdma_channel_start(sbmacdma_t *d, int rxtx )
/*
* Turn on the DMA channel
*/
-
+
#ifdef CONFIG_SBMAC_COALESCE
- SBMAC_WRITECSR(d->sbdma_config1,
- V_DMA_INT_TIMEOUT(d->sbdma_int_timeout) |
- 0);
- SBMAC_WRITECSR(d->sbdma_config0,
- M_DMA_EOP_INT_EN |
+ __raw_writeq(V_DMA_INT_TIMEOUT(d->sbdma_int_timeout) |
+ 0, d->sbdma_config1);
+ __raw_writeq(M_DMA_EOP_INT_EN |
V_DMA_RINGSZ(d->sbdma_maxdescr) |
V_DMA_INT_PKTCNT(d->sbdma_int_pktcnt) |
- 0);
+ 0, d->sbdma_config0);
#else
- SBMAC_WRITECSR(d->sbdma_config1,0);
- SBMAC_WRITECSR(d->sbdma_config0,
- V_DMA_RINGSZ(d->sbdma_maxdescr) |
- 0);
+ __raw_writeq(0, d->sbdma_config1);
+ __raw_writeq(V_DMA_RINGSZ(d->sbdma_maxdescr) |
+ 0, d->sbdma_config0);
#endif
- SBMAC_WRITECSR(d->sbdma_dscrbase,d->sbdma_dscrtable_phys);
+ __raw_writeq(d->sbdma_dscrtable_phys, d->sbdma_dscrbase);
/*
* Initialize ring pointers
@@ -834,12 +811,12 @@ static void sbdma_channel_start(sbmacdma_t *d, int rxtx )
/**********************************************************************
* SBDMA_CHANNEL_STOP(d)
- *
+ *
* Initialize the hardware registers for a DMA channel.
- *
- * Input parameters:
+ *
+ * Input parameters:
* d - DMA channel to init (context must be previously init'd
- *
+ *
* Return value:
* nothing
********************************************************************* */
@@ -849,44 +826,44 @@ static void sbdma_channel_stop(sbmacdma_t *d)
/*
* Turn off the DMA channel
*/
-
- SBMAC_WRITECSR(d->sbdma_config1,0);
-
- SBMAC_WRITECSR(d->sbdma_dscrbase,0);
-
- SBMAC_WRITECSR(d->sbdma_config0,0);
-
+
+ __raw_writeq(0, d->sbdma_config1);
+
+ __raw_writeq(0, d->sbdma_dscrbase);
+
+ __raw_writeq(0, d->sbdma_config0);
+
/*
* Zero ring pointers
*/
-
- d->sbdma_addptr = 0;
- d->sbdma_remptr = 0;
+
+ d->sbdma_addptr = NULL;
+ d->sbdma_remptr = NULL;
}
static void sbdma_align_skb(struct sk_buff *skb,int power2,int offset)
{
unsigned long addr;
unsigned long newaddr;
-
+
addr = (unsigned long) skb->data;
-
+
newaddr = (addr + power2 - 1) & ~(power2 - 1);
-
+
skb_reserve(skb,newaddr-addr+offset);
}
/**********************************************************************
* SBDMA_ADD_RCVBUFFER(d,sb)
- *
+ *
* Add a buffer to the specified DMA channel. For receive channels,
* this queues a buffer for inbound packets.
- *
- * Input parameters:
+ *
+ * Input parameters:
* d - DMA channel descriptor
* sb - sk_buff to add, or NULL if we should allocate one
- *
+ *
* Return value:
* 0 if buffer could not be added (ring is full)
* 1 if buffer added successfully
@@ -899,24 +876,24 @@ static int sbdma_add_rcvbuffer(sbmacdma_t *d,struct sk_buff *sb)
sbdmadscr_t *nextdsc;
struct sk_buff *sb_new = NULL;
int pktsize = ENET_PACKET_SIZE;
-
+
/* get pointer to our current place in the ring */
-
+
dsc = d->sbdma_addptr;
nextdsc = SBDMA_NEXTBUF(d,sbdma_addptr);
-
+
/*
* figure out if the ring is full - if the next descriptor
* is the same as the one that we're going to remove from
* the ring, the ring is full
*/
-
+
if (nextdsc == d->sbdma_remptr) {
return -ENOSPC;
}
- /*
- * Allocate a sk_buff if we don't already have one.
+ /*
+ * Allocate a sk_buff if we don't already have one.
* If we do have an sk_buff, reset it so that it's empty.
*
* Note: sk_buffs don't seem to be guaranteed to have any sort
@@ -925,7 +902,7 @@ static int sbdma_add_rcvbuffer(sbmacdma_t *d,struct sk_buff *sb)
*
* 1. the data does not start in the middle of a cache line.
* 2. The data does not end in the middle of a cache line
- * 3. The buffer can be aligned such that the IP addresses are
+ * 3. The buffer can be aligned such that the IP addresses are
* naturally aligned.
*
* Remember, the SOCs MAC writes whole cache lines at a time,
@@ -933,7 +910,7 @@ static int sbdma_add_rcvbuffer(sbmacdma_t *d,struct sk_buff *sb)
* data portion starts in the middle of a cache line, the SOC
* DMA will trash the beginning (and ending) portions.
*/
-
+
if (sb == NULL) {
sb_new = dev_alloc_skb(ENET_PACKET_SIZE + SMP_CACHE_BYTES * 2 + ETHER_ALIGN);
if (sb_new == NULL) {
@@ -949,23 +926,22 @@ static int sbdma_add_rcvbuffer(sbmacdma_t *d,struct sk_buff *sb)
}
else {
sb_new = sb;
- /*
+ /*
* nothing special to reinit buffer, it's already aligned
* and sb->data already points to a good place.
*/
}
-
+
/*
- * fill in the descriptor
+ * fill in the descriptor
*/
-
+
#ifdef CONFIG_SBMAC_COALESCE
/*
* Do not interrupt per DMA transfer.
*/
dsc->dscr_a = virt_to_phys(sb_new->data) |
- V_DMA_DSCRA_A_SIZE(NUMCACHEBLKS(pktsize+ETHER_ALIGN)) |
- 0;
+ V_DMA_DSCRA_A_SIZE(NUMCACHEBLKS(pktsize+ETHER_ALIGN)) | 0;
#else
dsc->dscr_a = virt_to_phys(sb_new->data) |
V_DMA_DSCRA_A_SIZE(NUMCACHEBLKS(pktsize+ETHER_ALIGN)) |
@@ -974,38 +950,38 @@ static int sbdma_add_rcvbuffer(sbmacdma_t *d,struct sk_buff *sb)
/* receiving: no options */
dsc->dscr_b = 0;
-
+
/*
- * fill in the context
+ * fill in the context
*/
-
+
d->sbdma_ctxtable[dsc-d->sbdma_dscrtable] = sb_new;
-
- /*
- * point at next packet
+
+ /*
+ * point at next packet
*/
-
+
d->sbdma_addptr = nextdsc;
-
- /*
+
+ /*
* Give the buffer to the DMA engine.
*/
-
- SBMAC_WRITECSR(d->sbdma_dscrcnt,1);
-
+
+ __raw_writeq(1, d->sbdma_dscrcnt);
+
return 0; /* we did it */
}
/**********************************************************************
* SBDMA_ADD_TXBUFFER(d,sb)
- *
+ *
* Add a transmit buffer to the specified DMA channel, causing a
* transmit to start.
- *
- * Input parameters:
+ *
+ * Input parameters:
* d - DMA channel descriptor
* sb - sk_buff to add
- *
+ *
* Return value:
* 0 transmit queued successfully
* otherwise error code
@@ -1019,70 +995,70 @@ static int sbdma_add_txbuffer(sbmacdma_t *d,struct sk_buff *sb)
uint64_t phys;
uint64_t ncb;
int length;
-
+
/* get pointer to our current place in the ring */
-
+
dsc = d->sbdma_addptr;
nextdsc = SBDMA_NEXTBUF(d,sbdma_addptr);
-
+
/*
* figure out if the ring is full - if the next descriptor
* is the same as the one that we're going to remove from
* the ring, the ring is full
*/
-
+
if (nextdsc == d->sbdma_remptr) {
return -ENOSPC;
}
-
+
/*
* Under Linux, it's not necessary to copy/coalesce buffers
* like it is on NetBSD. We think they're all contiguous,
* but that may not be true for GBE.
*/
-
+
length = sb->len;
-
+
/*
* fill in the descriptor. Note that the number of cache
* blocks in the descriptor is the number of blocks
* *spanned*, so we need to add in the offset (if any)
* while doing the calculation.
*/
-
+
phys = virt_to_phys(sb->data);
ncb = NUMCACHEBLKS(length+(phys & (SMP_CACHE_BYTES - 1)));
- dsc->dscr_a = phys |
+ dsc->dscr_a = phys |
V_DMA_DSCRA_A_SIZE(ncb) |
#ifndef CONFIG_SBMAC_COALESCE
M_DMA_DSCRA_INTERRUPT |
#endif
M_DMA_ETHTX_SOP;
-
+
/* transmitting: set outbound options and length */
dsc->dscr_b = V_DMA_DSCRB_OPTIONS(K_DMA_ETHTX_APPENDCRC_APPENDPAD) |
V_DMA_DSCRB_PKT_SIZE(length);
-
+
/*
- * fill in the context
+ * fill in the context
*/
-
+
d->sbdma_ctxtable[dsc-d->sbdma_dscrtable] = sb;
-
- /*
- * point at next packet
+
+ /*
+ * point at next packet
*/
-
+
d->sbdma_addptr = nextdsc;
-
- /*
+
+ /*
* Give the buffer to the DMA engine.
*/
-
- SBMAC_WRITECSR(d->sbdma_dscrcnt,1);
-
+
+ __raw_writeq(1, d->sbdma_dscrcnt);
+
return 0; /* we did it */
}
@@ -1091,12 +1067,12 @@ static int sbdma_add_txbuffer(sbmacdma_t *d,struct sk_buff *sb)
/**********************************************************************
* SBDMA_EMPTYRING(d)
- *
+ *
* Free all allocated sk_buffs on the specified DMA channel;
- *
- * Input parameters:
+ *
+ * Input parameters:
* d - DMA channel
- *
+ *
* Return value:
* nothing
********************************************************************* */
@@ -1105,7 +1081,7 @@ static void sbdma_emptyring(sbmacdma_t *d)
{
int idx;
struct sk_buff *sb;
-
+
for (idx = 0; idx < d->sbdma_maxdescr; idx++) {
sb = d->sbdma_ctxtable[idx];
if (sb) {
@@ -1118,13 +1094,13 @@ static void sbdma_emptyring(sbmacdma_t *d)
/**********************************************************************
* SBDMA_FILLRING(d)
- *
+ *
* Fill the specified DMA channel (must be receive channel)
* with sk_buffs
- *
- * Input parameters:
+ *
+ * Input parameters:
* d - DMA channel
- *
+ *
* Return value:
* nothing
********************************************************************* */
@@ -1132,7 +1108,7 @@ static void sbdma_emptyring(sbmacdma_t *d)
static void sbdma_fillring(sbmacdma_t *d)
{
int idx;
-
+
for (idx = 0; idx < SBMAC_MAX_RXDESCR-1; idx++) {
if (sbdma_add_rcvbuffer(d,NULL) != 0)
break;
@@ -1142,16 +1118,16 @@ static void sbdma_fillring(sbmacdma_t *d)
/**********************************************************************
* SBDMA_RX_PROCESS(sc,d)
- *
- * Process "completed" receive buffers on the specified DMA channel.
+ *
+ * Process "completed" receive buffers on the specified DMA channel.
* Note that this isn't really ideal for priority channels, since
- * it processes all of the packets on a given channel before
- * returning.
+ * it processes all of the packets on a given channel before
+ * returning.
*
- * Input parameters:
+ * Input parameters:
* sc - softc structure
* d - DMA channel context
- *
+ *
* Return value:
* nothing
********************************************************************* */
@@ -1163,56 +1139,56 @@ static void sbdma_rx_process(struct sbmac_softc *sc,sbmacdma_t *d)
sbdmadscr_t *dsc;
struct sk_buff *sb;
int len;
-
+
for (;;) {
- /*
+ /*
* figure out where we are (as an index) and where
* the hardware is (also as an index)
*
- * This could be done faster if (for example) the
+ * This could be done faster if (for example) the
* descriptor table was page-aligned and contiguous in
* both virtual and physical memory -- you could then
* just compare the low-order bits of the virtual address
* (sbdma_remptr) and the physical address (sbdma_curdscr CSR)
*/
-
+
curidx = d->sbdma_remptr - d->sbdma_dscrtable;
- hwidx = (int) (((SBMAC_READCSR(d->sbdma_curdscr) & M_DMA_CURDSCR_ADDR) -
+ hwidx = (int) (((__raw_readq(d->sbdma_curdscr) & M_DMA_CURDSCR_ADDR) -
d->sbdma_dscrtable_phys) / sizeof(sbdmadscr_t));
-
+
/*
* If they're the same, that means we've processed all
* of the descriptors up to (but not including) the one that
* the hardware is working on right now.
*/
-
+
if (curidx == hwidx)
break;
-
+
/*
* Otherwise, get the packet's sk_buff ptr back
*/
-
+
dsc = &(d->sbdma_dscrtable[curidx]);
sb = d->sbdma_ctxtable[curidx];
d->sbdma_ctxtable[curidx] = NULL;
-
+
len = (int)G_DMA_DSCRB_PKT_SIZE(dsc->dscr_b) - 4;
-
+
/*
* Check packet status. If good, process it.
* If not, silently drop it and put it back on the
* receive ring.
*/
-
+
if (!(dsc->dscr_a & M_DMA_ETHRX_BAD)) {
-
+
/*
* Add a new buffer to replace the old one. If we fail
* to allocate a buffer, we're going to drop this
* packet and put it right back on the receive ring.
*/
-
+
if (sbdma_add_rcvbuffer(d,NULL) == -ENOBUFS) {
sc->sbm_stats.rx_dropped++;
sbdma_add_rcvbuffer(d,sb); /* re-add old buffer */
@@ -1221,7 +1197,7 @@ static void sbdma_rx_process(struct sbmac_softc *sc,sbmacdma_t *d)
* Set length into the packet
*/
skb_put(sb,len);
-
+
/*
* Buffer has been replaced on the
* receive ring. Pass the buffer to
@@ -1240,7 +1216,7 @@ static void sbdma_rx_process(struct sbmac_softc *sc,sbmacdma_t *d)
sb->ip_summed = CHECKSUM_NONE;
}
}
-
+
netif_rx(sb);
}
} else {
@@ -1251,14 +1227,14 @@ static void sbdma_rx_process(struct sbmac_softc *sc,sbmacdma_t *d)
sc->sbm_stats.rx_errors++;
sbdma_add_rcvbuffer(d,sb);
}
-
-
- /*
+
+
+ /*
* .. and advance to the next buffer.
*/
-
+
d->sbdma_remptr = SBDMA_NEXTBUF(d,sbdma_remptr);
-
+
}
}
@@ -1266,17 +1242,17 @@ static void sbdma_rx_process(struct sbmac_softc *sc,sbmacdma_t *d)
/**********************************************************************
* SBDMA_TX_PROCESS(sc,d)
- *
- * Process "completed" transmit buffers on the specified DMA channel.
+ *
+ * Process "completed" transmit buffers on the specified DMA channel.
* This is normally called within the interrupt service routine.
* Note that this isn't really ideal for priority channels, since
- * it processes all of the packets on a given channel before
- * returning.
+ * it processes all of the packets on a given channel before
+ * returning.
*
- * Input parameters:
+ * Input parameters:
* sc - softc structure
* d - DMA channel context
- *
+ *
* Return value:
* nothing
********************************************************************* */
@@ -1290,21 +1266,21 @@ static void sbdma_tx_process(struct sbmac_softc *sc,sbmacdma_t *d)
unsigned long flags;
spin_lock_irqsave(&(sc->sbm_lock), flags);
-
+
for (;;) {
- /*
+ /*
* figure out where we are (as an index) and where
* the hardware is (also as an index)
*
- * This could be done faster if (for example) the
+ * This could be done faster if (for example) the
* descriptor table was page-aligned and contiguous in
* both virtual and physical memory -- you could then
* just compare the low-order bits of the virtual address
* (sbdma_remptr) and the physical address (sbdma_curdscr CSR)
*/
-
+
curidx = d->sbdma_remptr - d->sbdma_dscrtable;
- hwidx = (int) (((SBMAC_READCSR(d->sbdma_curdscr) & M_DMA_CURDSCR_ADDR) -
+ hwidx = (int) (((__raw_readq(d->sbdma_curdscr) & M_DMA_CURDSCR_ADDR) -
d->sbdma_dscrtable_phys) / sizeof(sbdmadscr_t));
/*
@@ -1312,75 +1288,75 @@ static void sbdma_tx_process(struct sbmac_softc *sc,sbmacdma_t *d)
* of the descriptors up to (but not including) the one that
* the hardware is working on right now.
*/
-
+
if (curidx == hwidx)
break;
-
+
/*
* Otherwise, get the packet's sk_buff ptr back
*/
-
+
dsc = &(d->sbdma_dscrtable[curidx]);
sb = d->sbdma_ctxtable[curidx];
d->sbdma_ctxtable[curidx] = NULL;
-
+
/*
* Stats
*/
-
+
sc->sbm_stats.tx_bytes += sb->len;
sc->sbm_stats.tx_packets++;
-
+
/*
* for transmits, we just free buffers.
*/
-
+
dev_kfree_skb_irq(sb);
-
- /*
+
+ /*
* .. and advance to the next buffer.
*/
d->sbdma_remptr = SBDMA_NEXTBUF(d,sbdma_remptr);
-
+
}
-
+
/*
* Decide if we should wake up the protocol or not.
* Other drivers seem to do this when we reach a low
* watermark on the transmit queue.
*/
-
+
netif_wake_queue(d->sbdma_eth->sbm_dev);
-
+
spin_unlock_irqrestore(&(sc->sbm_lock), flags);
-
+
}
/**********************************************************************
* SBMAC_INITCTX(s)
- *
+ *
* Initialize an Ethernet context structure - this is called
* once per MAC on the 1250. Memory is allocated here, so don't
* call it again from inside the ioctl routines that bring the
* interface up/down
- *
- * Input parameters:
+ *
+ * Input parameters:
* s - sbmac context structure
- *
+ *
* Return value:
* 0
********************************************************************* */
static int sbmac_initctx(struct sbmac_softc *s)
{
-
- /*
- * figure out the addresses of some ports
+
+ /*
+ * figure out the addresses of some ports
*/
-
+
s->sbm_macenable = s->sbm_base + R_MAC_ENABLE;
s->sbm_maccfg = s->sbm_base + R_MAC_CFG;
s->sbm_fifocfg = s->sbm_base + R_MAC_THRSH_CFG;
@@ -1397,29 +1373,29 @@ static int sbmac_initctx(struct sbmac_softc *s)
s->sbm_phy_oldanlpar = 0;
s->sbm_phy_oldk1stsr = 0;
s->sbm_phy_oldlinkstat = 0;
-
+
/*
* Initialize the DMA channels. Right now, only one per MAC is used
* Note: Only do this _once_, as it allocates memory from the kernel!
*/
-
+
sbdma_initctx(&(s->sbm_txdma),s,0,DMA_TX,SBMAC_MAX_TXDESCR);
sbdma_initctx(&(s->sbm_rxdma),s,0,DMA_RX,SBMAC_MAX_RXDESCR);
-
+
/*
* initial state is OFF
*/
-
+
s->sbm_state = sbmac_state_off;
-
+
/*
* Initial speed is (XXX TEMP) 10MBit/s HDX no FC
*/
-
+
s->sbm_speed = sbmac_speed_10;
s->sbm_duplex = sbmac_duplex_half;
s->sbm_fc = sbmac_fc_disabled;
-
+
return 0;
}
@@ -1430,7 +1406,7 @@ static void sbdma_uninitctx(struct sbmacdma_s *d)
kfree(d->sbdma_dscrtable);
d->sbdma_dscrtable = NULL;
}
-
+
if (d->sbdma_ctxtable) {
kfree(d->sbdma_ctxtable);
d->sbdma_ctxtable = NULL;
@@ -1447,12 +1423,12 @@ static void sbmac_uninitctx(struct sbmac_softc *sc)
/**********************************************************************
* SBMAC_CHANNEL_START(s)
- *
+ *
* Start packet processing on this MAC.
- *
- * Input parameters:
+ *
+ * Input parameters:
* s - sbmac structure
- *
+ *
* Return value:
* nothing
********************************************************************* */
@@ -1460,49 +1436,49 @@ static void sbmac_uninitctx(struct sbmac_softc *sc)
static void sbmac_channel_start(struct sbmac_softc *s)
{
uint64_t reg;
- sbmac_port_t port;
+ volatile void __iomem *port;
uint64_t cfg,fifo,framecfg;
int idx, th_value;
-
+
/*
* Don't do this if running
*/
if (s->sbm_state == sbmac_state_on)
return;
-
+
/*
* Bring the controller out of reset, but leave it off.
*/
-
- SBMAC_WRITECSR(s->sbm_macenable,0);
-
+
+ __raw_writeq(0, s->sbm_macenable);
+
/*
* Ignore all received packets
*/
-
- SBMAC_WRITECSR(s->sbm_rxfilter,0);
-
- /*
+
+ __raw_writeq(0, s->sbm_rxfilter);
+
+ /*
* Calculate values for various control registers.
*/
-
+
cfg = M_MAC_RETRY_EN |
- M_MAC_TX_HOLD_SOP_EN |
+ M_MAC_TX_HOLD_SOP_EN |
V_MAC_TX_PAUSE_CNT_16K |
M_MAC_AP_STAT_EN |
M_MAC_FAST_SYNC |
M_MAC_SS_EN |
0;
-
- /*
+
+ /*
* Be sure that RD_THRSH+WR_THRSH <= 32 for pass1 pars
* and make sure that RD_THRSH + WR_THRSH <=128 for pass2 and above
* Use a larger RD_THRSH for gigabit
*/
- if (periph_rev >= 2)
+ if (periph_rev >= 2)
th_value = 64;
- else
+ else
th_value = 28;
fifo = V_MAC_TX_WR_THRSH(4) | /* Must be '4' or '8' */
@@ -1520,51 +1496,51 @@ static void sbmac_channel_start(struct sbmac_softc *s)
V_MAC_BACKOFF_SEL(1);
/*
- * Clear out the hash address map
+ * Clear out the hash address map
*/
-
+
port = s->sbm_base + R_MAC_HASH_BASE;
for (idx = 0; idx < MAC_HASH_COUNT; idx++) {
- SBMAC_WRITECSR(port,0);
+ __raw_writeq(0, port);
port += sizeof(uint64_t);
}
-
+
/*
* Clear out the exact-match table
*/
-
+
port = s->sbm_base + R_MAC_ADDR_BASE;
for (idx = 0; idx < MAC_ADDR_COUNT; idx++) {
- SBMAC_WRITECSR(port,0);
+ __raw_writeq(0, port);
port += sizeof(uint64_t);
}
-
+
/*
* Clear out the DMA Channel mapping table registers
*/
-
+
port = s->sbm_base + R_MAC_CHUP0_BASE;
for (idx = 0; idx < MAC_CHMAP_COUNT; idx++) {
- SBMAC_WRITECSR(port,0);
+ __raw_writeq(0, port);
port += sizeof(uint64_t);
}
port = s->sbm_base + R_MAC_CHLO0_BASE;
for (idx = 0; idx < MAC_CHMAP_COUNT; idx++) {
- SBMAC_WRITECSR(port,0);
+ __raw_writeq(0, port);
port += sizeof(uint64_t);
}
-
+
/*
* Program the hardware address. It goes into the hardware-address
* register as well as the first filter register.
*/
-
+
reg = sbmac_addr2reg(s->sbm_hwaddr);
-
+
port = s->sbm_base + R_MAC_ADDR_BASE;
- SBMAC_WRITECSR(port,reg);
+ __raw_writeq(reg, port);
port = s->sbm_base + R_MAC_ETHERNET_ADDR;
#ifdef CONFIG_SB1_PASS_1_WORKAROUNDS
@@ -1573,108 +1549,105 @@ static void sbmac_channel_start(struct sbmac_softc *s)
* destination address in the R_MAC_ETHERNET_ADDR register.
* Set the value to zero.
*/
- SBMAC_WRITECSR(port,0);
+ __raw_writeq(0, port);
#else
- SBMAC_WRITECSR(port,reg);
+ __raw_writeq(reg, port);
#endif
-
+
/*
* Set the receive filter for no packets, and write values
* to the various config registers
*/
-
- SBMAC_WRITECSR(s->sbm_rxfilter,0);
- SBMAC_WRITECSR(s->sbm_imr,0);
- SBMAC_WRITECSR(s->sbm_framecfg,framecfg);
- SBMAC_WRITECSR(s->sbm_fifocfg,fifo);
- SBMAC_WRITECSR(s->sbm_maccfg,cfg);
-
+
+ __raw_writeq(0, s->sbm_rxfilter);
+ __raw_writeq(0, s->sbm_imr);
+ __raw_writeq(framecfg, s->sbm_framecfg);
+ __raw_writeq(fifo, s->sbm_fifocfg);
+ __raw_writeq(cfg, s->sbm_maccfg);
+
/*
* Initialize DMA channels (rings should be ok now)
*/
-
+
sbdma_channel_start(&(s->sbm_rxdma), DMA_RX);
sbdma_channel_start(&(s->sbm_txdma), DMA_TX);
-
+
/*
* Configure the speed, duplex, and flow control
*/
sbmac_set_speed(s,s->sbm_speed);
sbmac_set_duplex(s,s->sbm_duplex,s->sbm_fc);
-
+
/*
* Fill the receive ring
*/
-
+
sbdma_fillring(&(s->sbm_rxdma));
-
- /*
+
+ /*
* Turn on the rest of the bits in the enable register
- */
-
- SBMAC_WRITECSR(s->sbm_macenable,
- M_MAC_RXDMA_EN0 |
+ */
+
+ __raw_writeq(M_MAC_RXDMA_EN0 |
M_MAC_TXDMA_EN0 |
M_MAC_RX_ENABLE |
- M_MAC_TX_ENABLE);
-
-
+ M_MAC_TX_ENABLE, s->sbm_macenable);
+
+
#ifdef CONFIG_SBMAC_COALESCE
/*
* Accept any TX interrupt and EOP count/timer RX interrupts on ch 0
*/
- SBMAC_WRITECSR(s->sbm_imr,
- ((M_MAC_INT_EOP_COUNT | M_MAC_INT_EOP_TIMER) << S_MAC_TX_CH0) |
- ((M_MAC_INT_EOP_COUNT | M_MAC_INT_EOP_TIMER) << S_MAC_RX_CH0));
+ __raw_writeq(((M_MAC_INT_EOP_COUNT | M_MAC_INT_EOP_TIMER) << S_MAC_TX_CH0) |
+ ((M_MAC_INT_EOP_COUNT | M_MAC_INT_EOP_TIMER) << S_MAC_RX_CH0), s->sbm_imr);
#else
/*
* Accept any kind of interrupt on TX and RX DMA channel 0
*/
- SBMAC_WRITECSR(s->sbm_imr,
- (M_MAC_INT_CHANNEL << S_MAC_TX_CH0) |
- (M_MAC_INT_CHANNEL << S_MAC_RX_CH0));
+ __raw_writeq((M_MAC_INT_CHANNEL << S_MAC_TX_CH0) |
+ (M_MAC_INT_CHANNEL << S_MAC_RX_CH0), s->sbm_imr);
#endif
-
- /*
- * Enable receiving unicasts and broadcasts
+
+ /*
+ * Enable receiving unicasts and broadcasts
*/
-
- SBMAC_WRITECSR(s->sbm_rxfilter,M_MAC_UCAST_EN | M_MAC_BCAST_EN);
-
+
+ __raw_writeq(M_MAC_UCAST_EN | M_MAC_BCAST_EN, s->sbm_rxfilter);
+
/*
- * we're running now.
+ * we're running now.
*/
-
+
s->sbm_state = sbmac_state_on;
-
- /*
- * Program multicast addresses
+
+ /*
+ * Program multicast addresses
*/
-
+
sbmac_setmulti(s);
-
- /*
- * If channel was in promiscuous mode before, turn that on
+
+ /*
+ * If channel was in promiscuous mode before, turn that on
*/
-
+
if (s->sbm_devflags & IFF_PROMISC) {
sbmac_promiscuous_mode(s,1);
}
-
+
}
/**********************************************************************
* SBMAC_CHANNEL_STOP(s)
- *
+ *
* Stop packet processing on this MAC.
- *
- * Input parameters:
+ *
+ * Input parameters:
* s - sbmac structure
- *
+ *
* Return value:
* nothing
********************************************************************* */
@@ -1682,49 +1655,49 @@ static void sbmac_channel_start(struct sbmac_softc *s)
static void sbmac_channel_stop(struct sbmac_softc *s)
{
/* don't do this if already stopped */
-
+
if (s->sbm_state == sbmac_state_off)
return;
-
+
/* don't accept any packets, disable all interrupts */
-
- SBMAC_WRITECSR(s->sbm_rxfilter,0);
- SBMAC_WRITECSR(s->sbm_imr,0);
-
+
+ __raw_writeq(0, s->sbm_rxfilter);
+ __raw_writeq(0, s->sbm_imr);
+
/* Turn off ticker */
-
+
/* XXX */
-
+
/* turn off receiver and transmitter */
-
- SBMAC_WRITECSR(s->sbm_macenable,0);
-
+
+ __raw_writeq(0, s->sbm_macenable);
+
/* We're stopped now. */
-
+
s->sbm_state = sbmac_state_off;
-
+
/*
* Stop DMA channels (rings should be ok now)
*/
-
+
sbdma_channel_stop(&(s->sbm_rxdma));
sbdma_channel_stop(&(s->sbm_txdma));
-
+
/* Empty the receive and transmit rings */
-
+
sbdma_emptyring(&(s->sbm_rxdma));
sbdma_emptyring(&(s->sbm_txdma));
-
+
}
/**********************************************************************
* SBMAC_SET_CHANNEL_STATE(state)
- *
+ *
* Set the channel's state ON or OFF
- *
- * Input parameters:
+ *
+ * Input parameters:
* state - new state
- *
+ *
* Return value:
* old state
********************************************************************* */
@@ -1732,43 +1705,43 @@ static sbmac_state_t sbmac_set_channel_state(struct sbmac_softc *sc,
sbmac_state_t state)
{
sbmac_state_t oldstate = sc->sbm_state;
-
+
/*
* If same as previous state, return
*/
-
+
if (state == oldstate) {
return oldstate;
}
-
+
/*
- * If new state is ON, turn channel on
+ * If new state is ON, turn channel on
*/
-
+
if (state == sbmac_state_on) {
sbmac_channel_start(sc);
}
else {
sbmac_channel_stop(sc);
}
-
+
/*
* Return previous state
*/
-
+
return oldstate;
}
/**********************************************************************
* SBMAC_PROMISCUOUS_MODE(sc,onoff)
- *
+ *
* Turn on or off promiscuous mode
- *
- * Input parameters:
+ *
+ * Input parameters:
* sc - softc
* onoff - 1 to turn on, 0 to turn off
- *
+ *
* Return value:
* nothing
********************************************************************* */
@@ -1776,30 +1749,30 @@ static sbmac_state_t sbmac_set_channel_state(struct sbmac_softc *sc,
static void sbmac_promiscuous_mode(struct sbmac_softc *sc,int onoff)
{
uint64_t reg;
-
+
if (sc->sbm_state != sbmac_state_on)
return;
-
+
if (onoff) {
- reg = SBMAC_READCSR(sc->sbm_rxfilter);
+ reg = __raw_readq(sc->sbm_rxfilter);
reg |= M_MAC_ALLPKT_EN;
- SBMAC_WRITECSR(sc->sbm_rxfilter,reg);
- }
+ __raw_writeq(reg, sc->sbm_rxfilter);
+ }
else {
- reg = SBMAC_READCSR(sc->sbm_rxfilter);
+ reg = __raw_readq(sc->sbm_rxfilter);
reg &= ~M_MAC_ALLPKT_EN;
- SBMAC_WRITECSR(sc->sbm_rxfilter,reg);
+ __raw_writeq(reg, sc->sbm_rxfilter);
}
}
/**********************************************************************
* SBMAC_SETIPHDR_OFFSET(sc,onoff)
- *
+ *
* Set the iphdr offset as 15 assuming ethernet encapsulation
- *
- * Input parameters:
+ *
+ * Input parameters:
* sc - softc
- *
+ *
* Return value:
* nothing
********************************************************************* */
@@ -1807,12 +1780,12 @@ static void sbmac_promiscuous_mode(struct sbmac_softc *sc,int onoff)
static void sbmac_set_iphdr_offset(struct sbmac_softc *sc)
{
uint64_t reg;
-
+
/* Hard code the off set to 15 for now */
- reg = SBMAC_READCSR(sc->sbm_rxfilter);
+ reg = __raw_readq(sc->sbm_rxfilter);
reg &= ~M_MAC_IPHDR_OFFSET | V_MAC_IPHDR_OFFSET(15);
- SBMAC_WRITECSR(sc->sbm_rxfilter,reg);
-
+ __raw_writeq(reg, sc->sbm_rxfilter);
+
/* read system identification to determine revision */
if (periph_rev >= 2) {
sc->rx_hw_checksum = ENABLE;
@@ -1824,13 +1797,13 @@ static void sbmac_set_iphdr_offset(struct sbmac_softc *sc)
/**********************************************************************
* SBMAC_ADDR2REG(ptr)
- *
+ *
* Convert six bytes into the 64-bit register value that
* we typically write into the SBMAC's address/mcast registers
- *
- * Input parameters:
+ *
+ * Input parameters:
* ptr - pointer to 6 bytes
- *
+ *
* Return value:
* register value
********************************************************************* */
@@ -1838,35 +1811,35 @@ static void sbmac_set_iphdr_offset(struct sbmac_softc *sc)
static uint64_t sbmac_addr2reg(unsigned char *ptr)
{
uint64_t reg = 0;
-
+
ptr += 6;
-
- reg |= (uint64_t) *(--ptr);
+
+ reg |= (uint64_t) *(--ptr);
reg <<= 8;
- reg |= (uint64_t) *(--ptr);
+ reg |= (uint64_t) *(--ptr);
reg <<= 8;
- reg |= (uint64_t) *(--ptr);
+ reg |= (uint64_t) *(--ptr);
reg <<= 8;
- reg |= (uint64_t) *(--ptr);
+ reg |= (uint64_t) *(--ptr);
reg <<= 8;
- reg |= (uint64_t) *(--ptr);
+ reg |= (uint64_t) *(--ptr);
reg <<= 8;
- reg |= (uint64_t) *(--ptr);
-
+ reg |= (uint64_t) *(--ptr);
+
return reg;
}
/**********************************************************************
* SBMAC_SET_SPEED(s,speed)
- *
+ *
* Configure LAN speed for the specified MAC.
* Warning: must be called when MAC is off!
- *
- * Input parameters:
+ *
+ * Input parameters:
* s - sbmac structure
* speed - speed to set MAC to (see sbmac_speed_t enum)
- *
+ *
* Return value:
* 1 if successful
* 0 indicates invalid parameters
@@ -1880,31 +1853,31 @@ static int sbmac_set_speed(struct sbmac_softc *s,sbmac_speed_t speed)
/*
* Save new current values
*/
-
+
s->sbm_speed = speed;
-
+
if (s->sbm_state == sbmac_state_on)
return 0; /* save for next restart */
/*
- * Read current register values
+ * Read current register values
*/
-
- cfg = SBMAC_READCSR(s->sbm_maccfg);
- framecfg = SBMAC_READCSR(s->sbm_framecfg);
-
+
+ cfg = __raw_readq(s->sbm_maccfg);
+ framecfg = __raw_readq(s->sbm_framecfg);
+
/*
* Mask out the stuff we want to change
*/
-
+
cfg &= ~(M_MAC_BURST_EN | M_MAC_SPEED_SEL);
framecfg &= ~(M_MAC_IFG_RX | M_MAC_IFG_TX | M_MAC_IFG_THRSH |
M_MAC_SLOT_SIZE);
-
+
/*
* Now add in the new bits
*/
-
+
switch (speed) {
case sbmac_speed_10:
framecfg |= V_MAC_IFG_RX_10 |
@@ -1913,7 +1886,7 @@ static int sbmac_set_speed(struct sbmac_softc *s,sbmac_speed_t speed)
V_MAC_SLOT_SIZE_10;
cfg |= V_MAC_SPEED_SEL_10MBPS;
break;
-
+
case sbmac_speed_100:
framecfg |= V_MAC_IFG_RX_100 |
V_MAC_IFG_TX_100 |
@@ -1921,7 +1894,7 @@ static int sbmac_set_speed(struct sbmac_softc *s,sbmac_speed_t speed)
V_MAC_SLOT_SIZE_100;
cfg |= V_MAC_SPEED_SEL_100MBPS ;
break;
-
+
case sbmac_speed_1000:
framecfg |= V_MAC_IFG_RX_1000 |
V_MAC_IFG_TX_1000 |
@@ -1929,34 +1902,34 @@ static int sbmac_set_speed(struct sbmac_softc *s,sbmac_speed_t speed)
V_MAC_SLOT_SIZE_1000;
cfg |= V_MAC_SPEED_SEL_1000MBPS | M_MAC_BURST_EN;
break;
-
+
case sbmac_speed_auto: /* XXX not implemented */
/* fall through */
default:
return 0;
}
-
+
/*
- * Send the bits back to the hardware
+ * Send the bits back to the hardware
*/
-
- SBMAC_WRITECSR(s->sbm_framecfg,framecfg);
- SBMAC_WRITECSR(s->sbm_maccfg,cfg);
-
+
+ __raw_writeq(framecfg, s->sbm_framecfg);
+ __raw_writeq(cfg, s->sbm_maccfg);
+
return 1;
}
/**********************************************************************
* SBMAC_SET_DUPLEX(s,duplex,fc)
- *
+ *
* Set Ethernet duplex and flow control options for this MAC
* Warning: must be called when MAC is off!
- *
- * Input parameters:
+ *
+ * Input parameters:
* s - sbmac structure
* duplex - duplex setting (see sbmac_duplex_t)
* fc - flow control setting (see sbmac_fc_t)
- *
+ *
* Return value:
* 1 if ok
* 0 if an invalid parameter combination was specified
@@ -1965,67 +1938,67 @@ static int sbmac_set_speed(struct sbmac_softc *s,sbmac_speed_t speed)
static int sbmac_set_duplex(struct sbmac_softc *s,sbmac_duplex_t duplex,sbmac_fc_t fc)
{
uint64_t cfg;
-
+
/*
* Save new current values
*/
-
+
s->sbm_duplex = duplex;
s->sbm_fc = fc;
-
+
if (s->sbm_state == sbmac_state_on)
return 0; /* save for next restart */
-
+
/*
- * Read current register values
+ * Read current register values
*/
-
- cfg = SBMAC_READCSR(s->sbm_maccfg);
-
+
+ cfg = __raw_readq(s->sbm_maccfg);
+
/*
* Mask off the stuff we're about to change
*/
-
+
cfg &= ~(M_MAC_FC_SEL | M_MAC_FC_CMD | M_MAC_HDX_EN);
-
-
+
+
switch (duplex) {
case sbmac_duplex_half:
switch (fc) {
case sbmac_fc_disabled:
cfg |= M_MAC_HDX_EN | V_MAC_FC_CMD_DISABLED;
break;
-
+
case sbmac_fc_collision:
cfg |= M_MAC_HDX_EN | V_MAC_FC_CMD_ENABLED;
break;
-
+
case sbmac_fc_carrier:
cfg |= M_MAC_HDX_EN | V_MAC_FC_CMD_ENAB_FALSECARR;
break;
-
+
case sbmac_fc_auto: /* XXX not implemented */
- /* fall through */
+ /* fall through */
case sbmac_fc_frame: /* not valid in half duplex */
default: /* invalid selection */
return 0;
}
break;
-
+
case sbmac_duplex_full:
switch (fc) {
case sbmac_fc_disabled:
cfg |= V_MAC_FC_CMD_DISABLED;
break;
-
+
case sbmac_fc_frame:
cfg |= V_MAC_FC_CMD_ENABLED;
break;
-
+
case sbmac_fc_collision: /* not valid in full duplex */
case sbmac_fc_carrier: /* not valid in full duplex */
case sbmac_fc_auto: /* XXX not implemented */
- /* fall through */
+ /* fall through */
default:
return 0;
}
@@ -2034,13 +2007,13 @@ static int sbmac_set_duplex(struct sbmac_softc *s,sbmac_duplex_t duplex,sbmac_fc
/* XXX not implemented */
break;
}
-
+
/*
- * Send the bits back to the hardware
+ * Send the bits back to the hardware
*/
-
- SBMAC_WRITECSR(s->sbm_maccfg,cfg);
-
+
+ __raw_writeq(cfg, s->sbm_maccfg);
+
return 1;
}
@@ -2049,12 +2022,12 @@ static int sbmac_set_duplex(struct sbmac_softc *s,sbmac_duplex_t duplex,sbmac_fc
/**********************************************************************
* SBMAC_INTR()
- *
+ *
* Interrupt handler for MAC interrupts
- *
- * Input parameters:
+ *
+ * Input parameters:
* MAC structure
- *
+ *
* Return value:
* nothing
********************************************************************* */
@@ -2066,27 +2039,27 @@ static irqreturn_t sbmac_intr(int irq,void *dev_instance,struct pt_regs *rgs)
int handled = 0;
for (;;) {
-
+
/*
* Read the ISR (this clears the bits in the real
* register, except for counter addr)
*/
-
- isr = SBMAC_READCSR(sc->sbm_isr) & ~M_MAC_COUNTER_ADDR;
-
+
+ isr = __raw_readq(sc->sbm_isr) & ~M_MAC_COUNTER_ADDR;
+
if (isr == 0)
break;
handled = 1;
-
+
/*
* Transmits on channel 0
*/
-
+
if (isr & (M_MAC_INT_CHANNEL << S_MAC_TX_CH0)) {
sbdma_tx_process(sc,&(sc->sbm_txdma));
}
-
+
/*
* Receives on channel 0
*/
@@ -2106,8 +2079,8 @@ static irqreturn_t sbmac_intr(int irq,void *dev_instance,struct pt_regs *rgs)
* EOP_SEEN here takes care of this case.
* (EOP_SEEN is part of M_MAC_INT_CHANNEL << S_MAC_RX_CH0)
*/
-
-
+
+
if (isr & (M_MAC_INT_CHANNEL << S_MAC_RX_CH0)) {
sbdma_rx_process(sc,&(sc->sbm_rxdma));
}
@@ -2118,29 +2091,29 @@ static irqreturn_t sbmac_intr(int irq,void *dev_instance,struct pt_regs *rgs)
/**********************************************************************
* SBMAC_START_TX(skb,dev)
- *
- * Start output on the specified interface. Basically, we
+ *
+ * Start output on the specified interface. Basically, we
* queue as many buffers as we can until the ring fills up, or
* we run off the end of the queue, whichever comes first.
- *
- * Input parameters:
- *
- *
+ *
+ * Input parameters:
+ *
+ *
* Return value:
* nothing
********************************************************************* */
static int sbmac_start_tx(struct sk_buff *skb, struct net_device *dev)
{
struct sbmac_softc *sc = netdev_priv(dev);
-
+
/* lock eth irq */
spin_lock_irq (&sc->sbm_lock);
-
+
/*
- * Put the buffer on the transmit ring. If we
+ * Put the buffer on the transmit ring. If we
* don't have room, stop the queue.
*/
-
+
if (sbdma_add_txbuffer(&(sc->sbm_txdma),skb)) {
/* XXX save skb that we could not send */
netif_stop_queue(dev);
@@ -2148,24 +2121,24 @@ static int sbmac_start_tx(struct sk_buff *skb, struct net_device *dev)
return 1;
}
-
+
dev->trans_start = jiffies;
-
+
spin_unlock_irq (&sc->sbm_lock);
-
+
return 0;
}
/**********************************************************************
* SBMAC_SETMULTI(sc)
- *
+ *
* Reprogram the multicast table into the hardware, given
* the list of multicasts associated with the interface
* structure.
- *
- * Input parameters:
+ *
+ * Input parameters:
* sc - softc
- *
+ *
* Return value:
* nothing
********************************************************************* */
@@ -2173,75 +2146,75 @@ static int sbmac_start_tx(struct sk_buff *skb, struct net_device *dev)
static void sbmac_setmulti(struct sbmac_softc *sc)
{
uint64_t reg;
- sbmac_port_t port;
+ volatile void __iomem *port;
int idx;
struct dev_mc_list *mclist;
struct net_device *dev = sc->sbm_dev;
-
- /*
+
+ /*
* Clear out entire multicast table. We do this by nuking
* the entire hash table and all the direct matches except
- * the first one, which is used for our station address
+ * the first one, which is used for our station address
*/
-
+
for (idx = 1; idx < MAC_ADDR_COUNT; idx++) {
port = sc->sbm_base + R_MAC_ADDR_BASE+(idx*sizeof(uint64_t));
- SBMAC_WRITECSR(port,0);
+ __raw_writeq(0, port);
}
-
+
for (idx = 0; idx < MAC_HASH_COUNT; idx++) {
port = sc->sbm_base + R_MAC_HASH_BASE+(idx*sizeof(uint64_t));
- SBMAC_WRITECSR(port,0);
+ __raw_writeq(0, port);
}
-
+
/*
* Clear the filter to say we don't want any multicasts.
*/
-
- reg = SBMAC_READCSR(sc->sbm_rxfilter);
+
+ reg = __raw_readq(sc->sbm_rxfilter);
reg &= ~(M_MAC_MCAST_INV | M_MAC_MCAST_EN);
- SBMAC_WRITECSR(sc->sbm_rxfilter,reg);
-
+ __raw_writeq(reg, sc->sbm_rxfilter);
+
if (dev->flags & IFF_ALLMULTI) {
- /*
- * Enable ALL multicasts. Do this by inverting the
- * multicast enable bit.
+ /*
+ * Enable ALL multicasts. Do this by inverting the
+ * multicast enable bit.
*/
- reg = SBMAC_READCSR(sc->sbm_rxfilter);
+ reg = __raw_readq(sc->sbm_rxfilter);
reg |= (M_MAC_MCAST_INV | M_MAC_MCAST_EN);
- SBMAC_WRITECSR(sc->sbm_rxfilter,reg);
+ __raw_writeq(reg, sc->sbm_rxfilter);
return;
}
-
- /*
+
+ /*
* Progam new multicast entries. For now, only use the
* perfect filter. In the future we'll need to use the
* hash filter if the perfect filter overflows
*/
-
+
/* XXX only using perfect filter for now, need to use hash
* XXX if the table overflows */
-
+
idx = 1; /* skip station address */
mclist = dev->mc_list;
while (mclist && (idx < MAC_ADDR_COUNT)) {
reg = sbmac_addr2reg(mclist->dmi_addr);
port = sc->sbm_base + R_MAC_ADDR_BASE+(idx * sizeof(uint64_t));
- SBMAC_WRITECSR(port,reg);
+ __raw_writeq(reg, port);
idx++;
mclist = mclist->next;
}
-
- /*
+
+ /*
* Enable the "accept multicast bits" if we programmed at least one
- * multicast.
+ * multicast.
*/
-
+
if (idx > 1) {
- reg = SBMAC_READCSR(sc->sbm_rxfilter);
+ reg = __raw_readq(sc->sbm_rxfilter);
reg |= M_MAC_MCAST_EN;
- SBMAC_WRITECSR(sc->sbm_rxfilter,reg);
+ __raw_writeq(reg, sc->sbm_rxfilter);
}
}
@@ -2250,12 +2223,12 @@ static void sbmac_setmulti(struct sbmac_softc *sc)
#if defined(SBMAC_ETH0_HWADDR) || defined(SBMAC_ETH1_HWADDR) || defined(SBMAC_ETH2_HWADDR)
/**********************************************************************
* SBMAC_PARSE_XDIGIT(str)
- *
+ *
* Parse a hex digit, returning its value
- *
- * Input parameters:
+ *
+ * Input parameters:
* str - character
- *
+ *
* Return value:
* hex value, or -1 if invalid
********************************************************************* */
@@ -2263,7 +2236,7 @@ static void sbmac_setmulti(struct sbmac_softc *sc)
static int sbmac_parse_xdigit(char str)
{
int digit;
-
+
if ((str >= '0') && (str <= '9'))
digit = str - '0';
else if ((str >= 'a') && (str <= 'f'))
@@ -2272,20 +2245,20 @@ static int sbmac_parse_xdigit(char str)
digit = str - 'A' + 10;
else
return -1;
-
+
return digit;
}
/**********************************************************************
* SBMAC_PARSE_HWADDR(str,hwaddr)
- *
+ *
* Convert a string in the form xx:xx:xx:xx:xx:xx into a 6-byte
* Ethernet address.
- *
- * Input parameters:
+ *
+ * Input parameters:
* str - string
* hwaddr - pointer to hardware address
- *
+ *
* Return value:
* 0 if ok, else -1
********************************************************************* */
@@ -2294,7 +2267,7 @@ static int sbmac_parse_hwaddr(char *str, unsigned char *hwaddr)
{
int digit1,digit2;
int idx = 6;
-
+
while (*str && (idx > 0)) {
digit1 = sbmac_parse_xdigit(*str);
if (digit1 < 0)
@@ -2302,7 +2275,7 @@ static int sbmac_parse_hwaddr(char *str, unsigned char *hwaddr)
str++;
if (!*str)
return -1;
-
+
if ((*str == ':') || (*str == '-')) {
digit2 = digit1;
digit1 = 0;
@@ -2313,10 +2286,10 @@ static int sbmac_parse_hwaddr(char *str, unsigned char *hwaddr)
return -1;
str++;
}
-
+
*hwaddr++ = (digit1 << 4) | digit2;
idx--;
-
+
if (*str == '-')
str++;
if (*str == ':')
@@ -2337,12 +2310,12 @@ static int sb1250_change_mtu(struct net_device *_dev, int new_mtu)
/**********************************************************************
* SBMAC_INIT(dev)
- *
+ *
* Attach routine - init hardware and hook ourselves into linux
- *
- * Input parameters:
+ *
+ * Input parameters:
* dev - net_device structure
- *
+ *
* Return value:
* status
********************************************************************* */
@@ -2354,53 +2327,53 @@ static int sbmac_init(struct net_device *dev, int idx)
uint64_t ea_reg;
int i;
int err;
-
+
sc = netdev_priv(dev);
-
+
/* Determine controller base address */
-
+
sc->sbm_base = IOADDR(dev->base_addr);
sc->sbm_dev = dev;
sc->sbe_idx = idx;
-
+
eaddr = sc->sbm_hwaddr;
-
- /*
+
+ /*
* Read the ethernet address. The firwmare left this programmed
* for us in the ethernet address register for each mac.
*/
-
- ea_reg = SBMAC_READCSR(sc->sbm_base + R_MAC_ETHERNET_ADDR);
- SBMAC_WRITECSR(sc->sbm_base + R_MAC_ETHERNET_ADDR, 0);
+
+ ea_reg = __raw_readq(sc->sbm_base + R_MAC_ETHERNET_ADDR);
+ __raw_writeq(0, sc->sbm_base + R_MAC_ETHERNET_ADDR);
for (i = 0; i < 6; i++) {
eaddr[i] = (uint8_t) (ea_reg & 0xFF);
ea_reg >>= 8;
}
-
+
for (i = 0; i < 6; i++) {
dev->dev_addr[i] = eaddr[i];
}
-
-
+
+
/*
- * Init packet size
+ * Init packet size
*/
-
+
sc->sbm_buffersize = ENET_PACKET_SIZE + SMP_CACHE_BYTES * 2 + ETHER_ALIGN;
- /*
+ /*
* Initialize context (get pointers to registers and stuff), then
* allocate the memory for the descriptor tables.
*/
-
+
sbmac_initctx(sc);
-
+
/*
* Set up Linux device callins
*/
-
+
spin_lock_init(&(sc->sbm_lock));
-
+
dev->open = sbmac_open;
dev->hard_start_xmit = sbmac_start_tx;
dev->stop = sbmac_close;
@@ -2419,7 +2392,7 @@ static int sbmac_init(struct net_device *dev, int idx)
if (err)
goto out_uninit;
- if (periph_rev >= 2) {
+ if (sc->rx_hw_checksum == ENABLE) {
printk(KERN_INFO "%s: enabling TCP rcv checksum\n",
sc->sbm_dev->name);
}
@@ -2430,10 +2403,10 @@ static int sbmac_init(struct net_device *dev, int idx)
* was being displayed)
*/
printk(KERN_INFO
- "%s: SiByte Ethernet at 0x%08lX, address: %02X:%02X:%02X:%02X:%02X:%02X\n",
+ "%s: SiByte Ethernet at 0x%08lX, address: %02X:%02X:%02X:%02X:%02X:%02X\n",
dev->name, dev->base_addr,
eaddr[0],eaddr[1],eaddr[2],eaddr[3],eaddr[4],eaddr[5]);
-
+
return 0;
@@ -2447,54 +2420,86 @@ out_uninit:
static int sbmac_open(struct net_device *dev)
{
struct sbmac_softc *sc = netdev_priv(dev);
-
+
if (debug > 1) {
printk(KERN_DEBUG "%s: sbmac_open() irq %d.\n", dev->name, dev->irq);
}
-
- /*
+
+ /*
* map/route interrupt (clear status first, in case something
* weird is pending; we haven't initialized the mac registers
* yet)
*/
- SBMAC_READCSR(sc->sbm_isr);
+ __raw_readq(sc->sbm_isr);
if (request_irq(dev->irq, &sbmac_intr, SA_SHIRQ, dev->name, dev))
return -EBUSY;
/*
- * Configure default speed
+ * Probe phy address
+ */
+
+ if(sbmac_mii_probe(dev) == -1) {
+ printk("%s: failed to probe PHY.\n", dev->name);
+ return -EINVAL;
+ }
+
+ /*
+ * Configure default speed
*/
sbmac_mii_poll(sc,noisy_mii);
-
+
/*
* Turn on the channel
*/
sbmac_set_channel_state(sc,sbmac_state_on);
-
+
/*
* XXX Station address is in dev->dev_addr
*/
-
+
if (dev->if_port == 0)
- dev->if_port = 0;
-
+ dev->if_port = 0;
+
netif_start_queue(dev);
-
+
sbmac_set_rx_mode(dev);
-
+
/* Set the timer to check for link beat. */
init_timer(&sc->sbm_timer);
sc->sbm_timer.expires = jiffies + 2 * HZ/100;
sc->sbm_timer.data = (unsigned long)dev;
sc->sbm_timer.function = &sbmac_timer;
add_timer(&sc->sbm_timer);
-
+
return 0;
}
+static int sbmac_mii_probe(struct net_device *dev)
+{
+ int i;
+ struct sbmac_softc *s = netdev_priv(dev);
+ u16 bmsr, id1, id2;
+ u32 vendor, device;
+
+ for (i=1; i<31; i++) {
+ bmsr = sbmac_mii_read(s, i, MII_BMSR);
+ if (bmsr != 0) {
+ s->sbm_phys[0] = i;
+ id1 = sbmac_mii_read(s, i, MII_PHYIDR1);
+ id2 = sbmac_mii_read(s, i, MII_PHYIDR2);
+ vendor = ((u32)id1 << 6) | ((id2 >> 10) & 0x3f);
+ device = (id2 >> 4) & 0x3f;
+
+ printk(KERN_INFO "%s: found phy %d, vendor %06x part %02x\n",
+ dev->name, i, vendor, device);
+ return i;
+ }
+ }
+ return -1;
+}
static int sbmac_mii_poll(struct sbmac_softc *s,int noisy)
@@ -2609,20 +2614,20 @@ static void sbmac_timer(unsigned long data)
int mii_status;
spin_lock_irq (&sc->sbm_lock);
-
+
/* make IFF_RUNNING follow the MII status bit "Link established" */
mii_status = sbmac_mii_read(sc, sc->sbm_phys[0], MII_BMSR);
-
+
if ( (mii_status & BMSR_LINKSTAT) != (sc->sbm_phy_oldlinkstat) ) {
sc->sbm_phy_oldlinkstat = mii_status & BMSR_LINKSTAT;
if (mii_status & BMSR_LINKSTAT) {
netif_carrier_on(dev);
}
else {
- netif_carrier_off(dev);
+ netif_carrier_off(dev);
}
}
-
+
/*
* Poll the PHY to see what speed we should be running at
*/
@@ -2640,9 +2645,9 @@ static void sbmac_timer(unsigned long data)
sbmac_channel_start(sc);
}
}
-
+
spin_unlock_irq (&sc->sbm_lock);
-
+
sc->sbm_timer.expires = jiffies + next_tick;
add_timer(&sc->sbm_timer);
}
@@ -2651,13 +2656,13 @@ static void sbmac_timer(unsigned long data)
static void sbmac_tx_timeout (struct net_device *dev)
{
struct sbmac_softc *sc = netdev_priv(dev);
-
+
spin_lock_irq (&sc->sbm_lock);
-
-
+
+
dev->trans_start = jiffies;
sc->sbm_stats.tx_errors++;
-
+
spin_unlock_irq (&sc->sbm_lock);
printk (KERN_WARNING "%s: Transmit timed out\n",dev->name);
@@ -2670,13 +2675,13 @@ static struct net_device_stats *sbmac_get_stats(struct net_device *dev)
{
struct sbmac_softc *sc = netdev_priv(dev);
unsigned long flags;
-
+
spin_lock_irqsave(&sc->sbm_lock, flags);
-
+
/* XXX update other stats here */
-
+
spin_unlock_irqrestore(&sc->sbm_lock, flags);
-
+
return &sc->sbm_stats;
}
@@ -2693,8 +2698,8 @@ static void sbmac_set_rx_mode(struct net_device *dev)
/*
* Promiscuous changed.
*/
-
- if (dev->flags & IFF_PROMISC) {
+
+ if (dev->flags & IFF_PROMISC) {
/* Unconditionally log net taps. */
msg_flag = 1;
sbmac_promiscuous_mode(sc,1);
@@ -2705,18 +2710,18 @@ static void sbmac_set_rx_mode(struct net_device *dev)
}
}
spin_unlock_irqrestore(&sc->sbm_lock, flags);
-
+
if (msg_flag) {
printk(KERN_NOTICE "%s: Promiscuous mode %sabled.\n",
dev->name,(msg_flag==1)?"en":"dis");
}
-
+
/*
* Program the multicasts. Do this every time.
*/
-
+
sbmac_setmulti(sc);
-
+
}
static int sbmac_mii_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
@@ -2725,10 +2730,10 @@ static int sbmac_mii_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
u16 *data = (u16 *)&rq->ifr_ifru;
unsigned long flags;
int retval;
-
+
spin_lock_irqsave(&sc->sbm_lock, flags);
retval = 0;
-
+
switch(cmd) {
case SIOCDEVPRIVATE: /* Get the address of the PHY in use. */
data[0] = sc->sbm_phys[0] & 0x1f;
@@ -2750,7 +2755,7 @@ static int sbmac_mii_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
default:
retval = -EOPNOTSUPP;
}
-
+
spin_unlock_irqrestore(&sc->sbm_lock, flags);
return retval;
}
@@ -2781,7 +2786,7 @@ static int sbmac_close(struct net_device *dev)
sbdma_emptyring(&(sc->sbm_txdma));
sbdma_emptyring(&(sc->sbm_rxdma));
-
+
return 0;
}
@@ -2793,13 +2798,13 @@ sbmac_setup_hwaddr(int chan,char *addr)
{
uint8_t eaddr[6];
uint64_t val;
- sbmac_port_t port;
+ unsigned long port;
port = A_MAC_CHANNEL_BASE(chan);
sbmac_parse_hwaddr(addr,eaddr);
val = sbmac_addr2reg(eaddr);
- SBMAC_WRITECSR(IOADDR(port+R_MAC_ETHERNET_ADDR),val);
- val = SBMAC_READCSR(IOADDR(port+R_MAC_ETHERNET_ADDR));
+ __raw_writeq(val, IOADDR(port+R_MAC_ETHERNET_ADDR));
+ val = __raw_readq(IOADDR(port+R_MAC_ETHERNET_ADDR));
}
#endif
@@ -2810,9 +2815,9 @@ sbmac_init_module(void)
{
int idx;
struct net_device *dev;
- sbmac_port_t port;
+ unsigned long port;
int chip_max_units;
-
+
/*
* For bringup when not using the firmware, we can pre-fill
* the MAC addresses using the environment variables
@@ -2858,13 +2863,13 @@ sbmac_init_module(void)
port = A_MAC_CHANNEL_BASE(idx);
- /*
+ /*
* The R_MAC_ETHERNET_ADDR register will be set to some nonzero
* value for us by the firmware if we're going to use this MAC.
* If we find a zero, skip this MAC.
*/
- sbmac_orig_hwaddr[idx] = SBMAC_READCSR(IOADDR(port+R_MAC_ETHERNET_ADDR));
+ sbmac_orig_hwaddr[idx] = __raw_readq(IOADDR(port+R_MAC_ETHERNET_ADDR));
if (sbmac_orig_hwaddr[idx] == 0) {
printk(KERN_DEBUG "sbmac: not configuring MAC at "
"%lx\n", port);
@@ -2876,7 +2881,7 @@ sbmac_init_module(void)
*/
dev = alloc_etherdev(sizeof(struct sbmac_softc));
- if (!dev)
+ if (!dev)
return -ENOMEM; /* return ENOMEM */
printk(KERN_DEBUG "sbmac: configuring MAC at %lx\n", port);
@@ -2886,8 +2891,7 @@ sbmac_init_module(void)
dev->mem_end = 0;
if (sbmac_init(dev, idx)) {
port = A_MAC_CHANNEL_BASE(idx);
- SBMAC_WRITECSR(IOADDR(port+R_MAC_ETHERNET_ADDR),
- sbmac_orig_hwaddr[idx]);
+ __raw_writeq(sbmac_orig_hwaddr[idx], IOADDR(port+R_MAC_ETHERNET_ADDR));
free_netdev(dev);
continue;
}
diff --git a/drivers/net/sgiseeq.c b/drivers/net/sgiseeq.c
index 9bc3b1c0dd6a..a4614df38a90 100644
--- a/drivers/net/sgiseeq.c
+++ b/drivers/net/sgiseeq.c
@@ -32,8 +32,6 @@
#include "sgiseeq.h"
-static char *version = "sgiseeq.c: David S. Miller (dm@engr.sgi.com)\n";
-
static char *sgiseeqstr = "SGI Seeq8003";
/*
@@ -113,9 +111,9 @@ static struct net_device *root_sgiseeq_dev;
static inline void hpc3_eth_reset(struct hpc3_ethregs *hregs)
{
- hregs->rx_reset = HPC3_ERXRST_CRESET | HPC3_ERXRST_CLRIRQ;
+ hregs->reset = HPC3_ERST_CRESET | HPC3_ERST_CLRIRQ;
udelay(20);
- hregs->rx_reset = 0;
+ hregs->reset = 0;
}
static inline void reset_hpc3_and_seeq(struct hpc3_ethregs *hregs,
@@ -252,7 +250,6 @@ void sgiseeq_dump_rings(void)
#define TSTAT_INIT_SEEQ (SEEQ_TCMD_IPT|SEEQ_TCMD_I16|SEEQ_TCMD_IC|SEEQ_TCMD_IUF)
#define TSTAT_INIT_EDLC ((TSTAT_INIT_SEEQ) | SEEQ_TCMD_RB2)
-#define RDMACFG_INIT (HPC3_ERXDCFG_FRXDC | HPC3_ERXDCFG_FEOP | HPC3_ERXDCFG_FIRQ)
static int init_seeq(struct net_device *dev, struct sgiseeq_private *sp,
struct sgiseeq_regs *sregs)
@@ -274,8 +271,6 @@ static int init_seeq(struct net_device *dev, struct sgiseeq_private *sp,
sregs->tstat = TSTAT_INIT_SEEQ;
}
- hregs->rx_dconfig |= RDMACFG_INIT;
-
hregs->rx_ndptr = CPHYSADDR(sp->rx_desc);
hregs->tx_ndptr = CPHYSADDR(sp->tx_desc);
@@ -446,7 +441,7 @@ static irqreturn_t sgiseeq_interrupt(int irq, void *dev_id, struct pt_regs *regs
spin_lock(&sp->tx_lock);
/* Ack the IRQ and set software state. */
- hregs->rx_reset = HPC3_ERXRST_CLRIRQ;
+ hregs->reset = HPC3_ERST_CLRIRQ;
/* Always check for received packets. */
sgiseeq_rx(dev, sp, hregs, sregs);
@@ -493,11 +488,13 @@ static int sgiseeq_close(struct net_device *dev)
{
struct sgiseeq_private *sp = netdev_priv(dev);
struct sgiseeq_regs *sregs = sp->sregs;
+ unsigned int irq = dev->irq;
netif_stop_queue(dev);
/* Shutdown the Seeq. */
reset_hpc3_and_seeq(sp->hregs, sregs);
+ free_irq(irq, dev);
return 0;
}
@@ -644,7 +641,7 @@ static inline void setup_rx_ring(struct sgiseeq_rx_desc *buf, int nbufs)
#define ALIGNED(x) ((((unsigned long)(x)) + 0xf) & ~(0xf))
-static int sgiseeq_init(struct hpc3_regs* regs, int irq)
+static int sgiseeq_init(struct hpc3_regs* hpcregs, int irq)
{
struct sgiseeq_init_block *sr;
struct sgiseeq_private *sp;
@@ -680,8 +677,8 @@ static int sgiseeq_init(struct hpc3_regs* regs, int irq)
gpriv = sp;
gdev = dev;
#endif
- sp->sregs = (struct sgiseeq_regs *) &hpc3c0->eth_ext[0];
- sp->hregs = &hpc3c0->ethregs;
+ sp->sregs = (struct sgiseeq_regs *) &hpcregs->eth_ext[0];
+ sp->hregs = &hpcregs->ethregs;
sp->name = sgiseeqstr;
sp->mode = SEEQ_RCMD_RBCAST;
@@ -698,6 +695,11 @@ static int sgiseeq_init(struct hpc3_regs* regs, int irq)
setup_rx_ring(sp->rx_desc, SEEQ_RX_BUFFERS);
setup_tx_ring(sp->tx_desc, SEEQ_TX_BUFFERS);
+ /* Setup PIO and DMA transfer timing */
+ sp->hregs->pconfig = 0x161;
+ sp->hregs->dconfig = HPC3_EDCFG_FIRQ | HPC3_EDCFG_FEOP |
+ HPC3_EDCFG_FRXDC | HPC3_EDCFG_PTO | 0x026;
+
/* Reset the chip. */
hpc3_eth_reset(sp->hregs);
@@ -724,7 +726,7 @@ static int sgiseeq_init(struct hpc3_regs* regs, int irq)
goto err_out_free_page;
}
- printk(KERN_INFO "%s: SGI Seeq8003 ", dev->name);
+ printk(KERN_INFO "%s: %s ", dev->name, sgiseeqstr);
for (i = 0; i < 6; i++)
printk("%2.2x%c", dev->dev_addr[i], i == 5 ? '\n' : ':');
@@ -734,7 +736,7 @@ static int sgiseeq_init(struct hpc3_regs* regs, int irq)
return 0;
err_out_free_page:
- free_page((unsigned long) sp);
+ free_page((unsigned long) sp->srings);
err_out_free_dev:
kfree(dev);
@@ -744,8 +746,6 @@ err_out:
static int __init sgiseeq_probe(void)
{
- printk(version);
-
/* On board adapter on 1st HPC is always present */
return sgiseeq_init(hpc3c0, SGI_ENET_IRQ);
}
@@ -754,15 +754,12 @@ static void __exit sgiseeq_exit(void)
{
struct net_device *next, *dev;
struct sgiseeq_private *sp;
- int irq;
for (dev = root_sgiseeq_dev; dev; dev = next) {
sp = (struct sgiseeq_private *) netdev_priv(dev);
next = sp->next_module;
- irq = dev->irq;
unregister_netdev(dev);
- free_irq(irq, dev);
- free_page((unsigned long) sp);
+ free_page((unsigned long) sp->srings);
free_netdev(dev);
}
}
@@ -770,4 +767,6 @@ static void __exit sgiseeq_exit(void)
module_init(sgiseeq_probe);
module_exit(sgiseeq_exit);
+MODULE_DESCRIPTION("SGI Seeq 8003 driver");
+MODULE_AUTHOR("Linux/MIPS Mailing List <linux-mips@linux-mips.org>");
MODULE_LICENSE("GPL");
diff --git a/drivers/net/sis190.c b/drivers/net/sis190.c
index 92f75529eff8..478791e09bf7 100644
--- a/drivers/net/sis190.c
+++ b/drivers/net/sis190.c
@@ -842,7 +842,7 @@ static void sis190_set_rx_mode(struct net_device *dev)
for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count;
i++, mclist = mclist->next) {
int bit_nr =
- ether_crc(ETH_ALEN, mclist->dmi_addr) >> 26;
+ ether_crc(ETH_ALEN, mclist->dmi_addr) & 0x3f;
mc_filter[bit_nr >> 5] |= 1 << (bit_nr & 31);
rx_mode |= AcceptMulticast;
}
diff --git a/drivers/net/sis900.c b/drivers/net/sis900.c
index 23b713c700b3..1d4d88680db1 100644
--- a/drivers/net/sis900.c
+++ b/drivers/net/sis900.c
@@ -1696,15 +1696,20 @@ static int sis900_rx(struct net_device *net_dev)
long ioaddr = net_dev->base_addr;
unsigned int entry = sis_priv->cur_rx % NUM_RX_DESC;
u32 rx_status = sis_priv->rx_ring[entry].cmdsts;
+ int rx_work_limit;
if (netif_msg_rx_status(sis_priv))
printk(KERN_DEBUG "sis900_rx, cur_rx:%4.4d, dirty_rx:%4.4d "
"status:0x%8.8x\n",
sis_priv->cur_rx, sis_priv->dirty_rx, rx_status);
+ rx_work_limit = sis_priv->dirty_rx + NUM_RX_DESC - sis_priv->cur_rx;
while (rx_status & OWN) {
unsigned int rx_size;
+ if (--rx_work_limit < 0)
+ break;
+
rx_size = (rx_status & DSIZE) - CRC_SIZE;
if (rx_status & (ABORT|OVERRUN|TOOLONG|RUNT|RXISERR|CRCERR|FAERR)) {
@@ -1732,9 +1737,11 @@ static int sis900_rx(struct net_device *net_dev)
we are working on NULL sk_buff :-( */
if (sis_priv->rx_skbuff[entry] == NULL) {
if (netif_msg_rx_err(sis_priv))
- printk(KERN_INFO "%s: NULL pointer "
- "encountered in Rx ring, skipping\n",
- net_dev->name);
+ printk(KERN_WARNING "%s: NULL pointer "
+ "encountered in Rx ring\n"
+ "cur_rx:%4.4d, dirty_rx:%4.4d\n",
+ net_dev->name, sis_priv->cur_rx,
+ sis_priv->dirty_rx);
break;
}
@@ -1770,6 +1777,7 @@ static int sis900_rx(struct net_device *net_dev)
sis_priv->rx_ring[entry].cmdsts = 0;
sis_priv->rx_ring[entry].bufptr = 0;
sis_priv->stats.rx_dropped++;
+ sis_priv->cur_rx++;
break;
}
skb->dev = net_dev;
@@ -1787,7 +1795,7 @@ static int sis900_rx(struct net_device *net_dev)
/* refill the Rx buffer, what if the rate of refilling is slower
* than consuming ?? */
- for (;sis_priv->cur_rx - sis_priv->dirty_rx > 0; sis_priv->dirty_rx++) {
+ for (; sis_priv->cur_rx != sis_priv->dirty_rx; sis_priv->dirty_rx++) {
struct sk_buff *skb;
entry = sis_priv->dirty_rx % NUM_RX_DESC;
diff --git a/drivers/net/sk98lin/h/skdrv1st.h b/drivers/net/sk98lin/h/skdrv1st.h
index 308440bd0e12..91b8d4f45904 100644
--- a/drivers/net/sk98lin/h/skdrv1st.h
+++ b/drivers/net/sk98lin/h/skdrv1st.h
@@ -39,9 +39,6 @@
#ifndef __INC_SKDRV1ST_H
#define __INC_SKDRV1ST_H
-/* Check kernel version */
-#include <linux/version.h>
-
typedef struct s_AC SK_AC;
/* Set card versions */
diff --git a/drivers/net/sk_mca.c b/drivers/net/sk_mca.c
index 4c56b8d8221b..e5d6d95960c7 100644
--- a/drivers/net/sk_mca.c
+++ b/drivers/net/sk_mca.c
@@ -93,7 +93,6 @@ History:
#include <linux/mca-legacy.h>
#include <linux/init.h>
#include <linux/module.h>
-#include <linux/version.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
diff --git a/drivers/net/sk_mca.h b/drivers/net/sk_mca.h
index 7e7c99582746..d6fa1823dfa6 100644
--- a/drivers/net/sk_mca.h
+++ b/drivers/net/sk_mca.h
@@ -1,5 +1,3 @@
-#include <linux/version.h>
-
#ifndef _SK_MCA_INCLUDE_
#define _SK_MCA_INCLUDE_
diff --git a/drivers/net/skfp/smt.c b/drivers/net/skfp/smt.c
index f17c05cbe44b..99a776a51fb5 100644
--- a/drivers/net/skfp/smt.c
+++ b/drivers/net/skfp/smt.c
@@ -1896,7 +1896,7 @@ void smt_swap_para(struct smt_header *sm, int len, int direction)
static void smt_string_swap(char *data, const char *format, int len)
{
- const char *open_paren = 0 ;
+ const char *open_paren = NULL ;
int x ;
while (len > 0 && *format) {
diff --git a/drivers/net/skge.c b/drivers/net/skge.c
index c2e6484ef138..596c93b12daa 100644
--- a/drivers/net/skge.c
+++ b/drivers/net/skge.c
@@ -37,12 +37,13 @@
#include <linux/delay.h>
#include <linux/crc32.h>
#include <linux/dma-mapping.h>
+#include <linux/mii.h>
#include <asm/irq.h>
#include "skge.h"
#define DRV_NAME "skge"
-#define DRV_VERSION "1.1"
+#define DRV_VERSION "1.2"
#define PFX DRV_NAME " "
#define DEFAULT_TX_RING_SIZE 128
@@ -88,8 +89,8 @@ MODULE_DEVICE_TABLE(pci, skge_id_table);
static int skge_up(struct net_device *dev);
static int skge_down(struct net_device *dev);
static void skge_tx_clean(struct skge_port *skge);
-static void xm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val);
-static void gm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val);
+static int xm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val);
+static int gm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val);
static void genesis_get_stats(struct skge_port *skge, u64 *data);
static void yukon_get_stats(struct skge_port *skge, u64 *data);
static void yukon_init(struct skge_hw *hw, int port);
@@ -129,7 +130,7 @@ static void skge_get_regs(struct net_device *dev, struct ethtool_regs *regs,
regs->len - B3_RI_WTO_R1);
}
-/* Wake on Lan only supported on Yukon chps with rev 1 or above */
+/* Wake on Lan only supported on Yukon chips with rev 1 or above */
static int wol_supported(const struct skge_hw *hw)
{
return !((hw->chip_id == CHIP_ID_GENESIS ||
@@ -169,8 +170,8 @@ static int skge_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
return 0;
}
-/* Determine supported/adverised modes based on hardware.
- * Note: ethtoool ADVERTISED_xxx == SUPPORTED_xxx
+/* Determine supported/advertised modes based on hardware.
+ * Note: ethtool ADVERTISED_xxx == SUPPORTED_xxx
*/
static u32 skge_supported_modes(const struct skge_hw *hw)
{
@@ -531,13 +532,13 @@ static inline u32 hwkhz(const struct skge_hw *hw)
return 78215; /* or: 78.125 MHz */
}
-/* Chip hz to microseconds */
+/* Chip HZ to microseconds */
static inline u32 skge_clk2usec(const struct skge_hw *hw, u32 ticks)
{
return (ticks * 1000) / hwkhz(hw);
}
-/* Microseconds to chip hz */
+/* Microseconds to chip HZ */
static inline u32 skge_usecs2clk(const struct skge_hw *hw, u32 usec)
{
return hwkhz(hw) * usec / 1000;
@@ -730,6 +731,7 @@ static struct ethtool_ops skge_ethtool_ops = {
.phys_id = skge_phys_id,
.get_stats_count = skge_get_stats_count,
.get_ethtool_stats = skge_get_ethtool_stats,
+ .get_perm_addr = ethtool_op_get_perm_addr,
};
/*
@@ -882,32 +884,37 @@ static void skge_link_down(struct skge_port *skge)
printk(KERN_INFO PFX "%s: Link is down.\n", skge->netdev->name);
}
-static u16 xm_phy_read(struct skge_hw *hw, int port, u16 reg)
+static int __xm_phy_read(struct skge_hw *hw, int port, u16 reg, u16 *val)
{
int i;
- u16 v;
xm_write16(hw, port, XM_PHY_ADDR, reg | hw->phy_addr);
- v = xm_read16(hw, port, XM_PHY_DATA);
+ xm_read16(hw, port, XM_PHY_DATA);
/* Need to wait for external PHY */
for (i = 0; i < PHY_RETRIES; i++) {
udelay(1);
- if (xm_read16(hw, port, XM_MMU_CMD)
- & XM_MMU_PHY_RDY)
+ if (xm_read16(hw, port, XM_MMU_CMD) & XM_MMU_PHY_RDY)
goto ready;
}
- printk(KERN_WARNING PFX "%s: phy read timed out\n",
- hw->dev[port]->name);
- return 0;
+ return -ETIMEDOUT;
ready:
- v = xm_read16(hw, port, XM_PHY_DATA);
+ *val = xm_read16(hw, port, XM_PHY_DATA);
+ return 0;
+}
+
+static u16 xm_phy_read(struct skge_hw *hw, int port, u16 reg)
+{
+ u16 v = 0;
+ if (__xm_phy_read(hw, port, reg, &v))
+ printk(KERN_WARNING PFX "%s: phy read timed out\n",
+ hw->dev[port]->name);
return v;
}
-static void xm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val)
+static int xm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val)
{
int i;
@@ -917,19 +924,11 @@ static void xm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val)
goto ready;
udelay(1);
}
- printk(KERN_WARNING PFX "%s: phy write failed to come ready\n",
- hw->dev[port]->name);
-
+ return -EIO;
ready:
xm_write16(hw, port, XM_PHY_DATA, val);
- for (i = 0; i < PHY_RETRIES; i++) {
- udelay(1);
- if (!(xm_read16(hw, port, XM_MMU_CMD) & XM_MMU_PHY_BUSY))
- return;
- }
- printk(KERN_WARNING PFX "%s: phy write timed out\n",
- hw->dev[port]->name);
+ return 0;
}
static void genesis_init(struct skge_hw *hw)
@@ -1164,7 +1163,7 @@ static void bcom_phy_init(struct skge_port *skge, int jumbo)
xm_phy_write(hw, port, PHY_BCOM_P_EXT_CTRL, ext);
xm_phy_write(hw, port, PHY_BCOM_CTRL, ctl);
- /* Use link status change interrrupt */
+ /* Use link status change interrupt */
xm_phy_write(hw, port, PHY_BCOM_INT_MASK, PHY_B_DEF_MSK);
bcom_check_link(hw, port);
@@ -1204,7 +1203,7 @@ static void genesis_mac_init(struct skge_hw *hw, int port)
skge_write32(hw, B2_GP_IO, r);
skge_read32(hw, B2_GP_IO);
- /* Enable GMII interfac */
+ /* Enable GMII interface */
xm_write16(hw, port, XM_HW_CFG, XM_HW_GMII_MD);
bcom_phy_init(skge, jumbo);
@@ -1255,7 +1254,7 @@ static void genesis_mac_init(struct skge_hw *hw, int port)
* that jumbo frames larger than 8192 bytes will be
* truncated. Disabling all bad frame filtering causes
* the RX FIFO to operate in streaming mode, in which
- * case the XMAC will start transfering frames out of the
+ * case the XMAC will start transferring frames out of the
* RX FIFO as soon as the FIFO threshold is reached.
*/
xm_write32(hw, port, XM_MODE, XM_DEF_MODE);
@@ -1322,7 +1321,7 @@ static void genesis_stop(struct skge_port *skge)
port == 0 ? PA_CLR_TO_TX1 : PA_CLR_TO_TX2);
/*
- * If the transfer stucks at the MAC the STOP command will not
+ * If the transfer sticks at the MAC the STOP command will not
* terminate if we don't flush the XMAC's transmit FIFO !
*/
xm_write32(hw, port, XM_MODE,
@@ -1399,42 +1398,6 @@ static void genesis_mac_intr(struct skge_hw *hw, int port)
}
}
-static void gm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val)
-{
- int i;
-
- gma_write16(hw, port, GM_SMI_DATA, val);
- gma_write16(hw, port, GM_SMI_CTRL,
- GM_SMI_CT_PHY_AD(hw->phy_addr) | GM_SMI_CT_REG_AD(reg));
- for (i = 0; i < PHY_RETRIES; i++) {
- udelay(1);
-
- if (!(gma_read16(hw, port, GM_SMI_CTRL) & GM_SMI_CT_BUSY))
- break;
- }
-}
-
-static u16 gm_phy_read(struct skge_hw *hw, int port, u16 reg)
-{
- int i;
-
- gma_write16(hw, port, GM_SMI_CTRL,
- GM_SMI_CT_PHY_AD(hw->phy_addr)
- | GM_SMI_CT_REG_AD(reg) | GM_SMI_CT_OP_RD);
-
- for (i = 0; i < PHY_RETRIES; i++) {
- udelay(1);
- if (gma_read16(hw, port, GM_SMI_CTRL) & GM_SMI_CT_RD_VAL)
- goto ready;
- }
-
- printk(KERN_WARNING PFX "%s: phy read timeout\n",
- hw->dev[port]->name);
- return 0;
- ready:
- return gma_read16(hw, port, GM_SMI_DATA);
-}
-
static void genesis_link_up(struct skge_port *skge)
{
struct skge_hw *hw = skge->hw;
@@ -1548,7 +1511,55 @@ static inline void bcom_phy_intr(struct skge_port *skge)
}
-/* Marvell Phy Initailization */
+static int gm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val)
+{
+ int i;
+
+ gma_write16(hw, port, GM_SMI_DATA, val);
+ gma_write16(hw, port, GM_SMI_CTRL,
+ GM_SMI_CT_PHY_AD(hw->phy_addr) | GM_SMI_CT_REG_AD(reg));
+ for (i = 0; i < PHY_RETRIES; i++) {
+ udelay(1);
+
+ if (!(gma_read16(hw, port, GM_SMI_CTRL) & GM_SMI_CT_BUSY))
+ return 0;
+ }
+
+ printk(KERN_WARNING PFX "%s: phy write timeout\n",
+ hw->dev[port]->name);
+ return -EIO;
+}
+
+static int __gm_phy_read(struct skge_hw *hw, int port, u16 reg, u16 *val)
+{
+ int i;
+
+ gma_write16(hw, port, GM_SMI_CTRL,
+ GM_SMI_CT_PHY_AD(hw->phy_addr)
+ | GM_SMI_CT_REG_AD(reg) | GM_SMI_CT_OP_RD);
+
+ for (i = 0; i < PHY_RETRIES; i++) {
+ udelay(1);
+ if (gma_read16(hw, port, GM_SMI_CTRL) & GM_SMI_CT_RD_VAL)
+ goto ready;
+ }
+
+ return -ETIMEDOUT;
+ ready:
+ *val = gma_read16(hw, port, GM_SMI_DATA);
+ return 0;
+}
+
+static u16 gm_phy_read(struct skge_hw *hw, int port, u16 reg)
+{
+ u16 v = 0;
+ if (__gm_phy_read(hw, port, reg, &v))
+ printk(KERN_WARNING PFX "%s: phy read timeout\n",
+ hw->dev[port]->name);
+ return v;
+}
+
+/* Marvell Phy Initialization */
static void yukon_init(struct skge_hw *hw, int port)
{
struct skge_port *skge = netdev_priv(hw->dev[port]);
@@ -1793,6 +1804,25 @@ static void yukon_mac_init(struct skge_hw *hw, int port)
skge_write16(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_OPER_ON);
}
+/* Go into power down mode */
+static void yukon_suspend(struct skge_hw *hw, int port)
+{
+ u16 ctrl;
+
+ ctrl = gm_phy_read(hw, port, PHY_MARV_PHY_CTRL);
+ ctrl |= PHY_M_PC_POL_R_DIS;
+ gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, ctrl);
+
+ ctrl = gm_phy_read(hw, port, PHY_MARV_CTRL);
+ ctrl |= PHY_CT_RESET;
+ gm_phy_write(hw, port, PHY_MARV_CTRL, ctrl);
+
+ /* switch IEEE compatible power down mode on */
+ ctrl = gm_phy_read(hw, port, PHY_MARV_CTRL);
+ ctrl |= PHY_CT_PDOWN;
+ gm_phy_write(hw, port, PHY_MARV_CTRL, ctrl);
+}
+
static void yukon_stop(struct skge_port *skge)
{
struct skge_hw *hw = skge->hw;
@@ -1806,14 +1836,7 @@ static void yukon_stop(struct skge_port *skge)
& ~(GM_GPCR_TX_ENA|GM_GPCR_RX_ENA));
gma_read16(hw, port, GM_GP_CTRL);
- if (hw->chip_id == CHIP_ID_YUKON_LITE &&
- hw->chip_rev >= CHIP_REV_YU_LITE_A3) {
- u32 io = skge_read32(hw, B2_GP_IO);
-
- io |= GP_DIR_9 | GP_IO_9;
- skge_write32(hw, B2_GP_IO, io);
- skge_read32(hw, B2_GP_IO);
- }
+ yukon_suspend(hw, port);
/* set GPHY Control reset */
skge_write8(hw, SK_REG(port, GPHY_CTRL), GPC_RST_SET);
@@ -1996,6 +2019,51 @@ static void yukon_phy_intr(struct skge_port *skge)
/* XXX restart autonegotiation? */
}
+/* Basic MII support */
+static int skge_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
+{
+ struct mii_ioctl_data *data = if_mii(ifr);
+ struct skge_port *skge = netdev_priv(dev);
+ struct skge_hw *hw = skge->hw;
+ int err = -EOPNOTSUPP;
+
+ if (!netif_running(dev))
+ return -ENODEV; /* Phy still in reset */
+
+ switch(cmd) {
+ case SIOCGMIIPHY:
+ data->phy_id = hw->phy_addr;
+
+ /* fallthru */
+ case SIOCGMIIREG: {
+ u16 val = 0;
+ spin_lock_bh(&hw->phy_lock);
+ if (hw->chip_id == CHIP_ID_GENESIS)
+ err = __xm_phy_read(hw, skge->port, data->reg_num & 0x1f, &val);
+ else
+ err = __gm_phy_read(hw, skge->port, data->reg_num & 0x1f, &val);
+ spin_unlock_bh(&hw->phy_lock);
+ data->val_out = val;
+ break;
+ }
+
+ case SIOCSMIIREG:
+ if (!capable(CAP_NET_ADMIN))
+ return -EPERM;
+
+ spin_lock_bh(&hw->phy_lock);
+ if (hw->chip_id == CHIP_ID_GENESIS)
+ err = xm_phy_write(hw, skge->port, data->reg_num & 0x1f,
+ data->val_in);
+ else
+ err = gm_phy_write(hw, skge->port, data->reg_num & 0x1f,
+ data->val_in);
+ spin_unlock_bh(&hw->phy_lock);
+ break;
+ }
+ return err;
+}
+
static void skge_ramset(struct skge_hw *hw, u16 q, u32 start, size_t len)
{
u32 end;
@@ -2088,7 +2156,7 @@ static int skge_up(struct net_device *dev)
hw->intr_mask |= portirqmask[port];
skge_write32(hw, B0_IMSK, hw->intr_mask);
- /* Initialze MAC */
+ /* Initialize MAC */
spin_lock_bh(&hw->phy_lock);
if (hw->chip_id == CHIP_ID_GENESIS)
genesis_mac_init(hw, port);
@@ -2408,7 +2476,7 @@ static void yukon_set_multicast(struct net_device *dev)
reg = gma_read16(hw, port, GM_RX_CTRL);
reg |= GM_RXCR_UCF_ENA;
- if (dev->flags & IFF_PROMISC) /* promiscious */
+ if (dev->flags & IFF_PROMISC) /* promiscuous */
reg &= ~(GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA);
else if (dev->flags & IFF_ALLMULTI) /* all multicast */
memset(filter, 0xff, sizeof(filter));
@@ -2559,7 +2627,7 @@ static int skge_poll(struct net_device *dev, int *budget)
unsigned int to_do = min(dev->quota, *budget);
unsigned int work_done = 0;
- for (e = ring->to_clean; work_done < to_do; e = e->next) {
+ for (e = ring->to_clean; prefetch(e->next), work_done < to_do; e = e->next) {
struct skge_rx_desc *rd = e->desc;
struct sk_buff *skb;
u32 control;
@@ -2592,11 +2660,11 @@ static int skge_poll(struct net_device *dev, int *budget)
if (work_done >= to_do)
return 1; /* not done */
- local_irq_disable();
- __netif_rx_complete(dev);
+ netif_rx_complete(dev);
hw->intr_mask |= portirqmask[skge->port];
skge_write32(hw, B0_IMSK, hw->intr_mask);
- local_irq_enable();
+ skge_read32(hw, B0_IMSK);
+
return 0;
}
@@ -2608,7 +2676,7 @@ static inline void skge_tx_intr(struct net_device *dev)
struct skge_element *e;
spin_lock(&skge->tx_lock);
- for (e = ring->to_clean; e != ring->to_use; e = e->next) {
+ for (e = ring->to_clean; prefetch(e->next), e != ring->to_use; e = e->next) {
struct skge_tx_desc *td = e->desc;
u32 control;
@@ -2731,7 +2799,7 @@ static void skge_error_irq(struct skge_hw *hw)
}
/*
- * Interrrupt from PHY are handled in tasklet (soft irq)
+ * Interrupt from PHY are handled in tasklet (soft irq)
* because accessing phy registers requires spin wait which might
* cause excess interrupt latency.
*/
@@ -2761,6 +2829,14 @@ static void skge_extirq(unsigned long data)
local_irq_enable();
}
+static inline void skge_wakeup(struct net_device *dev)
+{
+ struct skge_port *skge = netdev_priv(dev);
+
+ prefetch(skge->rx_ring.to_clean);
+ netif_rx_schedule(dev);
+}
+
static irqreturn_t skge_intr(int irq, void *dev_id, struct pt_regs *regs)
{
struct skge_hw *hw = dev_id;
@@ -2772,12 +2848,12 @@ static irqreturn_t skge_intr(int irq, void *dev_id, struct pt_regs *regs)
status &= hw->intr_mask;
if (status & IS_R1_F) {
hw->intr_mask &= ~IS_R1_F;
- netif_rx_schedule(hw->dev[0]);
+ skge_wakeup(hw->dev[0]);
}
if (status & IS_R2_F) {
hw->intr_mask &= ~IS_R2_F;
- netif_rx_schedule(hw->dev[1]);
+ skge_wakeup(hw->dev[1]);
}
if (status & IS_XA1_F)
@@ -2892,6 +2968,7 @@ static const char *skge_board_name(const struct skge_hw *hw)
*/
static int skge_reset(struct skge_hw *hw)
{
+ u32 reg;
u16 ctst;
u8 t8, mac_cfg, pmd_type, phy_type;
int i;
@@ -2970,6 +3047,7 @@ static int skge_reset(struct skge_hw *hw)
/* switch power to VCC (WA for VAUX problem) */
skge_write8(hw, B0_POWER_CTRL,
PC_VAUX_ENA | PC_VCC_ENA | PC_VAUX_OFF | PC_VCC_ON);
+
/* avoid boards with stuck Hardware error bits */
if ((skge_read32(hw, B0_ISRC) & IS_HW_ERR) &&
(skge_read32(hw, B0_HWE_ISRC) & IS_IRQ_SENSOR)) {
@@ -2977,6 +3055,14 @@ static int skge_reset(struct skge_hw *hw)
hw->intr_mask &= ~IS_HW_ERR;
}
+ /* Clear PHY COMA */
+ skge_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
+ pci_read_config_dword(hw->pdev, PCI_DEV_REG1, &reg);
+ reg &= ~PCI_PHY_COMA;
+ pci_write_config_dword(hw->pdev, PCI_DEV_REG1, reg);
+ skge_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
+
+
for (i = 0; i < hw->ports; i++) {
skge_write16(hw, SK_REG(i, GMAC_LINK_CTRL), GMLC_RST_SET);
skge_write16(hw, SK_REG(i, GMAC_LINK_CTRL), GMLC_RST_CLR);
@@ -3047,6 +3133,7 @@ static struct net_device *skge_devinit(struct skge_hw *hw, int port,
SET_NETDEV_DEV(dev, &hw->pdev->dev);
dev->open = skge_up;
dev->stop = skge_down;
+ dev->do_ioctl = skge_ioctl;
dev->hard_start_xmit = skge_xmit_frame;
dev->get_stats = skge_get_stats;
if (hw->chip_id == CHIP_ID_GENESIS)
@@ -3096,6 +3183,7 @@ static struct net_device *skge_devinit(struct skge_hw *hw, int port,
/* read the mac address */
memcpy_fromio(dev->dev_addr, hw->regs + B2_MAC_1 + port*8, ETH_ALEN);
+ memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
/* device is off until link detection */
netif_carrier_off(dev);
@@ -3145,7 +3233,7 @@ static int __devinit skge_probe(struct pci_dev *pdev,
}
#ifdef __BIG_ENDIAN
- /* byte swap decriptors in hardware */
+ /* byte swap descriptors in hardware */
{
u32 reg;
@@ -3156,14 +3244,13 @@ static int __devinit skge_probe(struct pci_dev *pdev,
#endif
err = -ENOMEM;
- hw = kmalloc(sizeof(*hw), GFP_KERNEL);
+ hw = kzalloc(sizeof(*hw), GFP_KERNEL);
if (!hw) {
printk(KERN_ERR PFX "%s: cannot allocate hardware struct\n",
pci_name(pdev));
goto err_out_free_regions;
}
- memset(hw, 0, sizeof(*hw));
hw->pdev = pdev;
spin_lock_init(&hw->phy_lock);
tasklet_init(&hw->ext_tasklet, skge_extirq, (unsigned long) hw);
@@ -3186,7 +3273,7 @@ static int __devinit skge_probe(struct pci_dev *pdev,
if (err)
goto err_out_free_irq;
- printk(KERN_INFO PFX "addr 0x%lx irq %d chip %s rev %d\n",
+ printk(KERN_INFO PFX DRV_VERSION " addr 0x%lx irq %d chip %s rev %d\n",
pci_resource_start(pdev, 0), pdev->irq,
skge_board_name(hw), hw->chip_rev);
diff --git a/drivers/net/skge.h b/drivers/net/skge.h
index 72c175b87a5a..ee123c15f545 100644
--- a/drivers/net/skge.h
+++ b/drivers/net/skge.h
@@ -6,6 +6,8 @@
/* PCI config registers */
#define PCI_DEV_REG1 0x40
+#define PCI_PHY_COMA 0x8000000
+#define PCI_VIO 0x2000000
#define PCI_DEV_REG2 0x44
#define PCI_REV_DESC 0x4
diff --git a/drivers/net/smc91x.c b/drivers/net/smc91x.c
index 1438fdd20826..74d5f1a6fdea 100644
--- a/drivers/net/smc91x.c
+++ b/drivers/net/smc91x.c
@@ -77,7 +77,7 @@ static const char version[] =
#include <linux/errno.h>
#include <linux/ioport.h>
#include <linux/crc32.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <linux/spinlock.h>
#include <linux/ethtool.h>
#include <linux/mii.h>
@@ -1983,6 +1983,10 @@ static int __init smc_probe(struct net_device *dev, void __iomem *ioaddr)
if (lp->version >= (CHIP_91100 << 4))
smc_phy_detect(dev);
+ /* then shut everything down to save power */
+ smc_shutdown(dev);
+ smc_phy_powerdown(dev);
+
/* Set default parameters */
lp->msg_enable = NETIF_MSG_LINK;
lp->ctl_rfduplx = 0;
@@ -2291,11 +2295,11 @@ static int smc_drv_remove(struct device *dev)
return 0;
}
-static int smc_drv_suspend(struct device *dev, pm_message_t state, u32 level)
+static int smc_drv_suspend(struct device *dev, pm_message_t state)
{
struct net_device *ndev = dev_get_drvdata(dev);
- if (ndev && level == SUSPEND_DISABLE) {
+ if (ndev) {
if (netif_running(ndev)) {
netif_device_detach(ndev);
smc_shutdown(ndev);
@@ -2305,12 +2309,12 @@ static int smc_drv_suspend(struct device *dev, pm_message_t state, u32 level)
return 0;
}
-static int smc_drv_resume(struct device *dev, u32 level)
+static int smc_drv_resume(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct net_device *ndev = dev_get_drvdata(dev);
- if (ndev && level == RESUME_ENABLE) {
+ if (ndev) {
struct smc_local *lp = netdev_priv(ndev);
smc_enable_device(pdev);
if (netif_running(ndev)) {
diff --git a/drivers/net/smc91x.h b/drivers/net/smc91x.h
index ac9ce6509eee..817f200742c3 100644
--- a/drivers/net/smc91x.h
+++ b/drivers/net/smc91x.h
@@ -230,12 +230,12 @@ SMC_outw(u16 val, void __iomem *ioaddr, int reg)
#define SMC_CAN_USE_16BIT 1
#define SMC_CAN_USE_32BIT 0
-#define SMC_inb(a, r) inb((a) + (r) - 0xa0000000)
-#define SMC_inw(a, r) inw((a) + (r) - 0xa0000000)
-#define SMC_outb(v, a, r) outb(v, (a) + (r) - 0xa0000000)
-#define SMC_outw(v, a, r) outw(v, (a) + (r) - 0xa0000000)
-#define SMC_insw(a, r, p, l) insw((a) + (r) - 0xa0000000, p, l)
-#define SMC_outsw(a, r, p, l) outsw((a) + (r) - 0xa0000000, p, l)
+#define SMC_inb(a, r) inb((u32)a) + (r))
+#define SMC_inw(a, r) inw(((u32)a) + (r))
+#define SMC_outb(v, a, r) outb(v, ((u32)a) + (r))
+#define SMC_outw(v, a, r) outw(v, ((u32)a) + (r))
+#define SMC_insw(a, r, p, l) insw(((u32)a) + (r), p, l)
+#define SMC_outsw(a, r, p, l) outsw(((u32)a) + (r), p, l)
#define set_irq_type(irq, type) do {} while(0)
diff --git a/drivers/net/spider_net.c b/drivers/net/spider_net.c
index c796f41b4a52..0d765f1733b5 100644
--- a/drivers/net/spider_net.c
+++ b/drivers/net/spider_net.c
@@ -2290,7 +2290,6 @@ spider_net_remove(struct pci_dev *pdev)
}
static struct pci_driver spider_net_driver = {
- .owner = THIS_MODULE,
.name = spider_net_driver_name,
.id_table = spider_net_pci_tbl,
.probe = spider_net_probe,
diff --git a/drivers/net/starfire.c b/drivers/net/starfire.c
index efdb179ecc8c..d167deda9a53 100644
--- a/drivers/net/starfire.c
+++ b/drivers/net/starfire.c
@@ -147,7 +147,6 @@ TODO: - fix forced speed/duplexing code (broken a long time ago, when
#define DRV_RELDATE "October 3, 2005"
#include <linux/config.h>
-#include <linux/version.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/pci.h>
@@ -1091,8 +1090,10 @@ static int netdev_open(struct net_device *dev)
rx_ring_size = sizeof(struct starfire_rx_desc) * RX_RING_SIZE;
np->queue_mem_size = tx_done_q_size + rx_done_q_size + tx_ring_size + rx_ring_size;
np->queue_mem = pci_alloc_consistent(np->pci_dev, np->queue_mem_size, &np->queue_mem_dma);
- if (np->queue_mem == 0)
+ if (np->queue_mem == NULL) {
+ free_irq(dev->irq, dev);
return -ENOMEM;
+ }
np->tx_done_q = np->queue_mem;
np->tx_done_q_dma = np->queue_mem_dma;
diff --git a/drivers/net/sunbmac.c b/drivers/net/sunbmac.c
index f88f5e32b714..cfaf47c63c58 100644
--- a/drivers/net/sunbmac.c
+++ b/drivers/net/sunbmac.c
@@ -214,7 +214,8 @@ static void bigmac_init_rings(struct bigmac *bp, int from_irq)
{
struct bmac_init_block *bb = bp->bmac_block;
struct net_device *dev = bp->dev;
- int i, gfp_flags = GFP_KERNEL;
+ int i;
+ gfp_t gfp_flags = GFP_KERNEL;
if (from_irq || in_interrupt())
gfp_flags = GFP_ATOMIC;
diff --git a/drivers/net/sunbmac.h b/drivers/net/sunbmac.h
index 5674003fc38a..b0dbc5187143 100644
--- a/drivers/net/sunbmac.h
+++ b/drivers/net/sunbmac.h
@@ -339,7 +339,7 @@ struct bigmac {
#define ALIGNED_RX_SKB_ADDR(addr) \
((((unsigned long)(addr) + (64 - 1)) & ~(64 - 1)) - (unsigned long)(addr))
-static inline struct sk_buff *big_mac_alloc_skb(unsigned int length, int gfp_flags)
+static inline struct sk_buff *big_mac_alloc_skb(unsigned int length, gfp_t gfp_flags)
{
struct sk_buff *skb;
diff --git a/drivers/net/sundance.c b/drivers/net/sundance.c
index d500a5771dbc..0ab9c38b4a34 100644
--- a/drivers/net/sundance.c
+++ b/drivers/net/sundance.c
@@ -80,7 +80,7 @@
I/O access could affect performance in ARM-based system
- Add Linux software VLAN support
- Version LK1.08 (D-Link):
+ Version LK1.08 (Philippe De Muyter phdm@macqel.be):
- Fix bug of custom mac address
(StationAddr register only accept word write)
@@ -91,11 +91,14 @@
Version LK1.09a (ICPlus):
- Add the delay time in reading the contents of EEPROM
+ Version LK1.10 (Philippe De Muyter phdm@macqel.be):
+ - Make 'unblock interface after Tx underrun' work
+
*/
#define DRV_NAME "sundance"
-#define DRV_VERSION "1.01+LK1.09a"
-#define DRV_RELDATE "10-Jul-2003"
+#define DRV_VERSION "1.01+LK1.10"
+#define DRV_RELDATE "28-Oct-2005"
/* The user-configurable values.
@@ -263,8 +266,10 @@ IV. Notes
IVb. References
The Sundance ST201 datasheet, preliminary version.
-http://cesdis.gsfc.nasa.gov/linux/misc/100mbps.html
-http://cesdis.gsfc.nasa.gov/linux/misc/NWay.html
+The Kendin KS8723 datasheet, preliminary version.
+The ICplus IP100 datasheet, preliminary version.
+http://www.scyld.com/expert/100mbps.html
+http://www.scyld.com/expert/NWay.html
IVc. Errata
@@ -500,6 +505,25 @@ static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
static int netdev_close(struct net_device *dev);
static struct ethtool_ops ethtool_ops;
+static void sundance_reset(struct net_device *dev, unsigned long reset_cmd)
+{
+ struct netdev_private *np = netdev_priv(dev);
+ void __iomem *ioaddr = np->base + ASICCtrl;
+ int countdown;
+
+ /* ST201 documentation states ASICCtrl is a 32bit register */
+ iowrite32 (reset_cmd | ioread32 (ioaddr), ioaddr);
+ /* ST201 documentation states reset can take up to 1 ms */
+ countdown = 10 + 1;
+ while (ioread32 (ioaddr) & (ResetBusy << 16)) {
+ if (--countdown == 0) {
+ printk(KERN_WARNING "%s : reset not completed !!\n", dev->name);
+ break;
+ }
+ udelay(100);
+ }
+}
+
static int __devinit sundance_probe1 (struct pci_dev *pdev,
const struct pci_device_id *ent)
{
@@ -518,6 +542,7 @@ static int __devinit sundance_probe1 (struct pci_dev *pdev,
#else
int bar = 1;
#endif
+ int phy, phy_idx = 0;
/* when built into the kernel, we only print version if device is found */
@@ -549,6 +574,7 @@ static int __devinit sundance_probe1 (struct pci_dev *pdev,
for (i = 0; i < 3; i++)
((u16 *)dev->dev_addr)[i] =
le16_to_cpu(eeprom_read(ioaddr, i + EEPROM_SA_OFFSET));
+ memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
dev->base_addr = (unsigned long)ioaddr;
dev->irq = irq;
@@ -605,33 +631,31 @@ static int __devinit sundance_probe1 (struct pci_dev *pdev,
printk("%2.2x:", dev->dev_addr[i]);
printk("%2.2x, IRQ %d.\n", dev->dev_addr[i], irq);
- if (1) {
- int phy, phy_idx = 0;
- np->phys[0] = 1; /* Default setting */
- np->mii_preamble_required++;
- for (phy = 1; phy < 32 && phy_idx < MII_CNT; phy++) {
- int mii_status = mdio_read(dev, phy, MII_BMSR);
- if (mii_status != 0xffff && mii_status != 0x0000) {
- np->phys[phy_idx++] = phy;
- np->mii_if.advertising = mdio_read(dev, phy, MII_ADVERTISE);
- if ((mii_status & 0x0040) == 0)
- np->mii_preamble_required++;
- printk(KERN_INFO "%s: MII PHY found at address %d, status "
- "0x%4.4x advertising %4.4x.\n",
- dev->name, phy, mii_status, np->mii_if.advertising);
- }
- }
- np->mii_preamble_required--;
-
- if (phy_idx == 0) {
- printk(KERN_INFO "%s: No MII transceiver found, aborting. ASIC status %x\n",
- dev->name, ioread32(ioaddr + ASICCtrl));
- goto err_out_unregister;
+ np->phys[0] = 1; /* Default setting */
+ np->mii_preamble_required++;
+ for (phy = 1; phy <= 32 && phy_idx < MII_CNT; phy++) {
+ int mii_status = mdio_read(dev, phy, MII_BMSR);
+ int phyx = phy & 0x1f;
+ if (mii_status != 0xffff && mii_status != 0x0000) {
+ np->phys[phy_idx++] = phyx;
+ np->mii_if.advertising = mdio_read(dev, phyx, MII_ADVERTISE);
+ if ((mii_status & 0x0040) == 0)
+ np->mii_preamble_required++;
+ printk(KERN_INFO "%s: MII PHY found at address %d, status "
+ "0x%4.4x advertising %4.4x.\n",
+ dev->name, phyx, mii_status, np->mii_if.advertising);
}
+ }
+ np->mii_preamble_required--;
- np->mii_if.phy_id = np->phys[0];
+ if (phy_idx == 0) {
+ printk(KERN_INFO "%s: No MII transceiver found, aborting. ASIC status %x\n",
+ dev->name, ioread32(ioaddr + ASICCtrl));
+ goto err_out_unregister;
}
+ np->mii_if.phy_id = np->phys[0];
+
/* Parse override configuration */
np->an_enable = 1;
if (card_idx < MAX_UNITS) {
@@ -692,7 +716,7 @@ static int __devinit sundance_probe1 (struct pci_dev *pdev,
/* Reset the chip to erase previous misconfiguration. */
if (netif_msg_hw(np))
printk("ASIC Control is %x.\n", ioread32(ioaddr + ASICCtrl));
- iowrite16(0x007f, ioaddr + ASICCtrl + 2);
+ iowrite16(0x00ff, ioaddr + ASICCtrl + 2);
if (netif_msg_hw(np))
printk("ASIC Control is now %x.\n", ioread32(ioaddr + ASICCtrl));
@@ -1190,23 +1214,33 @@ static irqreturn_t intr_handler(int irq, void *dev_instance, struct pt_regs *rgs
("%s: Transmit status is %2.2x.\n",
dev->name, tx_status);
if (tx_status & 0x1e) {
+ if (netif_msg_tx_err(np))
+ printk("%s: Transmit error status %4.4x.\n",
+ dev->name, tx_status);
np->stats.tx_errors++;
if (tx_status & 0x10)
np->stats.tx_fifo_errors++;
if (tx_status & 0x08)
np->stats.collisions++;
+ if (tx_status & 0x04)
+ np->stats.tx_fifo_errors++;
if (tx_status & 0x02)
np->stats.tx_window_errors++;
- /* This reset has not been verified!. */
- if (tx_status & 0x10) { /* Reset the Tx. */
- np->stats.tx_fifo_errors++;
- spin_lock(&np->lock);
- reset_tx(dev);
- spin_unlock(&np->lock);
+ /*
+ ** This reset has been verified on
+ ** DFE-580TX boards ! phdm@macqel.be.
+ */
+ if (tx_status & 0x10) { /* TxUnderrun */
+ unsigned short txthreshold;
+
+ txthreshold = ioread16 (ioaddr + TxStartThresh);
+ /* Restart Tx FIFO and transmitter */
+ sundance_reset(dev, (NetworkReset|FIFOReset|TxReset) << 16);
+ iowrite16 (txthreshold, ioaddr + TxStartThresh);
+ /* No need to reset the Tx pointer here */
}
- if (tx_status & 0x1e) /* Restart the Tx. */
- iowrite16 (TxEnable,
- ioaddr + MACCtrl1);
+ /* Restart the Tx. */
+ iowrite16 (TxEnable, ioaddr + MACCtrl1);
}
/* Yup, this is a documentation bug. It cost me *hours*. */
iowrite16 (0, ioaddr + TxStatus);
@@ -1619,6 +1653,7 @@ static struct ethtool_ops ethtool_ops = {
.get_link = get_link,
.get_msglevel = get_msglevel,
.set_msglevel = set_msglevel,
+ .get_perm_addr = ethtool_op_get_perm_addr,
};
static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 1802c3b48799..1828a6bf8458 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -37,6 +37,7 @@
#include <linux/tcp.h>
#include <linux/workqueue.h>
#include <linux/prefetch.h>
+#include <linux/dma-mapping.h>
#include <net/checksum.h>
@@ -67,8 +68,8 @@
#define DRV_MODULE_NAME "tg3"
#define PFX DRV_MODULE_NAME ": "
-#define DRV_MODULE_VERSION "3.42"
-#define DRV_MODULE_RELDATE "Oct 3, 2005"
+#define DRV_MODULE_VERSION "3.43"
+#define DRV_MODULE_RELDATE "Oct 24, 2005"
#define TG3_DEF_MAC_MODE 0
#define TG3_DEF_RX_MODE 0
@@ -219,6 +220,10 @@ static struct pci_device_id tg3_pci_tbl[] = {
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
{ PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5753F,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
+ { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5714,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
+ { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5715,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
{ PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5780,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
{ PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5780S,
@@ -466,6 +471,15 @@ static void tg3_write_mem(struct tg3 *tp, u32 off, u32 val)
spin_unlock_irqrestore(&tp->indirect_lock, flags);
}
+static void tg3_write_mem_fast(struct tg3 *tp, u32 off, u32 val)
+{
+ /* If no workaround is needed, write to mem space directly */
+ if (tp->write32 != tg3_write_indirect_reg32)
+ tw32(NIC_SRAM_WIN_BASE + off, val);
+ else
+ tg3_write_mem(tp, off, val);
+}
+
static void tg3_read_mem(struct tg3 *tp, u32 off, u32 *val)
{
unsigned long flags;
@@ -570,7 +584,7 @@ static void tg3_switch_clocks(struct tg3 *tp)
u32 clock_ctrl = tr32(TG3PCI_CLOCK_CTRL);
u32 orig_clock_ctrl;
- if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780)
+ if (tp->tg3_flags2 & TG3_FLG2_5780_CLASS)
return;
orig_clock_ctrl = clock_ctrl;
@@ -1210,7 +1224,7 @@ static int tg3_set_power_state(struct tg3 *tp, int state)
CLOCK_CTRL_ALTCLK |
CLOCK_CTRL_PWRDOWN_PLL133);
udelay(40);
- } else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780) {
+ } else if (tp->tg3_flags2 & TG3_FLG2_5780_CLASS) {
/* do nothing */
} else if (!((tp->tg3_flags2 & TG3_FLG2_5750_PLUS) &&
(tp->tg3_flags & TG3_FLAG_ENABLE_ASF))) {
@@ -3712,14 +3726,14 @@ static inline void tg3_set_mtu(struct net_device *dev, struct tg3 *tp,
dev->mtu = new_mtu;
if (new_mtu > ETH_DATA_LEN) {
- if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780) {
+ if (tp->tg3_flags2 & TG3_FLG2_5780_CLASS) {
tp->tg3_flags2 &= ~TG3_FLG2_TSO_CAPABLE;
ethtool_op_set_tso(dev, 0);
}
else
tp->tg3_flags |= TG3_FLAG_JUMBO_RING_ENABLE;
} else {
- if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780)
+ if (tp->tg3_flags2 & TG3_FLG2_5780_CLASS)
tp->tg3_flags2 |= TG3_FLG2_TSO_CAPABLE;
tp->tg3_flags &= ~TG3_FLAG_JUMBO_RING_ENABLE;
}
@@ -3850,7 +3864,7 @@ static void tg3_init_rings(struct tg3 *tp)
memset(tp->tx_ring, 0, TG3_TX_RING_BYTES);
tp->rx_pkt_buf_sz = RX_PKT_BUF_SZ;
- if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780) &&
+ if ((tp->tg3_flags2 & TG3_FLG2_5780_CLASS) &&
(tp->dev->mtu > ETH_DATA_LEN))
tp->rx_pkt_buf_sz = RX_JUMBO_PKT_BUF_SZ;
@@ -3905,10 +3919,8 @@ static void tg3_init_rings(struct tg3 *tp)
*/
static void tg3_free_consistent(struct tg3 *tp)
{
- if (tp->rx_std_buffers) {
- kfree(tp->rx_std_buffers);
- tp->rx_std_buffers = NULL;
- }
+ kfree(tp->rx_std_buffers);
+ tp->rx_std_buffers = NULL;
if (tp->rx_std) {
pci_free_consistent(tp->pdev, TG3_RX_RING_BYTES,
tp->rx_std, tp->rx_std_mapping);
@@ -4347,7 +4359,7 @@ static int tg3_chip_reset(struct tg3 *tp)
val &= ~PCIX_CAPS_RELAXED_ORDERING;
pci_write_config_dword(tp->pdev, TG3PCI_X_CAPS, val);
- if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780) {
+ if (tp->tg3_flags2 & TG3_FLG2_5780_CLASS) {
u32 val;
/* Chip reset on 5780 will reset MSI enable bit,
@@ -6003,7 +6015,7 @@ static int tg3_reset_hw(struct tg3 *tp)
tw32(MAC_RCV_VALUE_1, 0xffffffff & RCV_RULE_DISABLE_MASK);
if ((tp->tg3_flags2 & TG3_FLG2_5705_PLUS) &&
- (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5780))
+ !(tp->tg3_flags2 & TG3_FLG2_5780_CLASS))
limit = 8;
else
limit = 16;
@@ -6191,14 +6203,16 @@ static void tg3_timer(unsigned long __opaque)
tp->timer_counter = tp->timer_multiplier;
}
- /* Heartbeat is only sent once every 120 seconds. */
+ /* Heartbeat is only sent once every 2 seconds. */
if (!--tp->asf_counter) {
if (tp->tg3_flags & TG3_FLAG_ENABLE_ASF) {
u32 val;
- tg3_write_mem(tp, NIC_SRAM_FW_CMD_MBOX, FWCMD_NICDRV_ALIVE);
- tg3_write_mem(tp, NIC_SRAM_FW_CMD_LEN_MBOX, 4);
- tg3_write_mem(tp, NIC_SRAM_FW_CMD_DATA_MBOX, 3);
+ tg3_write_mem_fast(tp, NIC_SRAM_FW_CMD_MBOX,
+ FWCMD_NICDRV_ALIVE2);
+ tg3_write_mem_fast(tp, NIC_SRAM_FW_CMD_LEN_MBOX, 4);
+ /* 5 seconds timeout */
+ tg3_write_mem_fast(tp, NIC_SRAM_FW_CMD_DATA_MBOX, 5);
val = tr32(GRC_RX_CPU_EVENT);
val |= (1 << 14);
tw32(GRC_RX_CPU_EVENT, val);
@@ -6409,7 +6423,7 @@ static int tg3_open(struct net_device *dev)
tp->timer_counter = tp->timer_multiplier =
(HZ / tp->timer_offset);
tp->asf_counter = tp->asf_multiplier =
- ((HZ / tp->timer_offset) * 120);
+ ((HZ / tp->timer_offset) * 2);
init_timer(&tp->timer);
tp->timer.expires = jiffies + tp->timer_offset;
@@ -7237,7 +7251,7 @@ static int tg3_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
cmd->supported |= (SUPPORTED_1000baseT_Half |
SUPPORTED_1000baseT_Full);
- if (!(tp->tg3_flags2 & TG3_FLG2_PHY_SERDES))
+ if (!(tp->tg3_flags2 & TG3_FLG2_ANY_SERDES))
cmd->supported |= (SUPPORTED_100baseT_Half |
SUPPORTED_100baseT_Full |
SUPPORTED_10baseT_Half |
@@ -7264,7 +7278,7 @@ static int tg3_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
{
struct tg3 *tp = netdev_priv(dev);
- if (tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) {
+ if (tp->tg3_flags2 & TG3_FLG2_ANY_SERDES) {
/* These are the only valid advertisement bits allowed. */
if (cmd->autoneg == AUTONEG_ENABLE &&
(cmd->advertising & ~(ADVERTISED_1000baseT_Half |
@@ -7272,7 +7286,17 @@ static int tg3_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
ADVERTISED_Autoneg |
ADVERTISED_FIBRE)))
return -EINVAL;
- }
+ /* Fiber can only do SPEED_1000. */
+ else if ((cmd->autoneg != AUTONEG_ENABLE) &&
+ (cmd->speed != SPEED_1000))
+ return -EINVAL;
+ /* Copper cannot force SPEED_1000. */
+ } else if ((cmd->autoneg != AUTONEG_ENABLE) &&
+ (cmd->speed == SPEED_1000))
+ return -EINVAL;
+ else if ((cmd->speed == SPEED_1000) &&
+ (tp->tg3_flags2 & TG3_FLAG_10_100_ONLY))
+ return -EINVAL;
tg3_full_lock(tp, 0);
@@ -8380,7 +8404,7 @@ static void __devinit tg3_get_nvram_info(struct tg3 *tp)
}
if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750) ||
- (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780)) {
+ (tp->tg3_flags2 & TG3_FLG2_5780_CLASS)) {
switch (nvcfg1 & NVRAM_CFG1_VENDOR_MASK) {
case FLASH_VENDOR_ATMEL_FLASH_BUFFERED:
tp->nvram_jedecnum = JEDEC_ATMEL;
@@ -8980,7 +9004,7 @@ static void __devinit tg3_get_eeprom_hw_cfg(struct tg3 *tp)
tp->phy_id = eeprom_phy_id;
if (eeprom_phy_serdes) {
- if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780)
+ if (tp->tg3_flags2 & TG3_FLG2_5780_CLASS)
tp->tg3_flags2 |= TG3_FLG2_MII_SERDES;
else
tp->tg3_flags2 |= TG3_FLG2_PHY_SERDES;
@@ -9393,8 +9417,11 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
}
/* Find msi capability. */
- if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780)
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780 ||
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5714) {
+ tp->tg3_flags2 |= TG3_FLG2_5780_CLASS;
tp->msi_cap = pci_find_capability(tp->pdev, PCI_CAP_ID_MSI);
+ }
/* Initialize misc host control in PCI block. */
tp->misc_host_ctrl |= (misc_ctrl_reg &
@@ -9412,7 +9439,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5752 ||
- GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780)
+ (tp->tg3_flags2 & TG3_FLG2_5780_CLASS))
tp->tg3_flags2 |= TG3_FLG2_5750_PLUS;
if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) ||
@@ -9607,7 +9634,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
* ether_setup() via the alloc_etherdev() call
*/
if (tp->dev->mtu > ETH_DATA_LEN &&
- GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5780)
+ !(tp->tg3_flags2 & TG3_FLG2_5780_CLASS))
tp->tg3_flags |= TG3_FLAG_JUMBO_RING_ENABLE;
/* Determine WakeOnLan speed to use. */
@@ -9830,7 +9857,7 @@ static int __devinit tg3_get_device_address(struct tg3 *tp)
mac_offset = 0x7c;
if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704 &&
!(tp->tg3_flags & TG3_FLG2_SUN_570X)) ||
- GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780) {
+ (tp->tg3_flags2 & TG3_FLG2_5780_CLASS)) {
if (tr32(TG3PCI_DUAL_MAC_CTRL) & DUAL_MAC_CTRL_ID)
mac_offset = 0xcc;
if (tg3_nvram_lock(tp))
@@ -10148,6 +10175,9 @@ static int __devinit tg3_test_dma(struct tg3 *tp)
} else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780) {
/* 5780 always in PCIX mode */
tp->dma_rwctrl |= 0x00144000;
+ } else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5714) {
+ /* 5714 always in PCIX mode */
+ tp->dma_rwctrl |= 0x00148000;
} else {
tp->dma_rwctrl |= 0x001b000f;
}
@@ -10347,6 +10377,7 @@ static char * __devinit tg3_phy_string(struct tg3 *tp)
case PHY_ID_BCM5705: return "5705";
case PHY_ID_BCM5750: return "5750";
case PHY_ID_BCM5752: return "5752";
+ case PHY_ID_BCM5714: return "5714";
case PHY_ID_BCM5780: return "5780";
case PHY_ID_BCM8002: return "8002/serdes";
case 0: return "serdes";
@@ -10492,17 +10523,17 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
}
/* Configure DMA attributes. */
- err = pci_set_dma_mask(pdev, 0xffffffffffffffffULL);
+ err = pci_set_dma_mask(pdev, DMA_64BIT_MASK);
if (!err) {
pci_using_dac = 1;
- err = pci_set_consistent_dma_mask(pdev, 0xffffffffffffffffULL);
+ err = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK);
if (err < 0) {
printk(KERN_ERR PFX "Unable to obtain 64 bit DMA "
"for consistent allocations\n");
goto err_out_free_res;
}
} else {
- err = pci_set_dma_mask(pdev, 0xffffffffULL);
+ err = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
if (err) {
printk(KERN_ERR PFX "No usable DMA configuration, "
"aborting.\n");
diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h
index 2e733c60bfa4..fb7e2a5f4a08 100644
--- a/drivers/net/tg3.h
+++ b/drivers/net/tg3.h
@@ -137,6 +137,7 @@
#define ASIC_REV_5750 0x04
#define ASIC_REV_5752 0x06
#define ASIC_REV_5780 0x08
+#define ASIC_REV_5714 0x09
#define GET_CHIP_REV(CHIP_REV_ID) ((CHIP_REV_ID) >> 8)
#define CHIPREV_5700_AX 0x70
#define CHIPREV_5700_BX 0x71
@@ -531,6 +532,8 @@
#define MAC_SERDES_CFG_EDGE_SELECT 0x00001000
#define MAC_SERDES_STAT 0x00000594
/* 0x598 --> 0x5b0 unused */
+#define SERDES_RX_CTRL 0x000005b0 /* 5780/5714 only */
+#define SERDES_RX_SIG_DETECT 0x00000400
#define SG_DIG_CTRL 0x000005b0
#define SG_DIG_USING_HW_AUTONEG 0x80000000
#define SG_DIG_SOFT_RESET 0x40000000
@@ -1329,6 +1332,8 @@
#define GRC_LCLCTRL_CLEARINT 0x00000002
#define GRC_LCLCTRL_SETINT 0x00000004
#define GRC_LCLCTRL_INT_ON_ATTN 0x00000008
+#define GRC_LCLCTRL_USE_SIG_DETECT 0x00000010 /* 5714/5780 only */
+#define GRC_LCLCTRL_USE_EXT_SIG_DETECT 0x00000020 /* 5714/5780 only */
#define GRC_LCLCTRL_GPIO_INPUT3 0x00000020
#define GRC_LCLCTRL_GPIO_OE3 0x00000040
#define GRC_LCLCTRL_GPIO_OUTPUT3 0x00000080
@@ -1507,6 +1512,7 @@
#define FWCMD_NICDRV_IPV6ADDR_CHG 0x00000004
#define FWCMD_NICDRV_FIX_DMAR 0x00000005
#define FWCMD_NICDRV_FIX_DMAW 0x00000006
+#define FWCMD_NICDRV_ALIVE2 0x0000000d
#define NIC_SRAM_FW_CMD_LEN_MBOX 0x00000b7c
#define NIC_SRAM_FW_CMD_DATA_MBOX 0x00000b80
#define NIC_SRAM_FW_ASF_STATUS_MBOX 0x00000c00
@@ -2175,6 +2181,7 @@ struct tg3 {
TG3_FLG2_MII_SERDES)
#define TG3_FLG2_PARALLEL_DETECT 0x01000000
#define TG3_FLG2_ICH_WORKAROUND 0x02000000
+#define TG3_FLG2_5780_CLASS 0x04000000
u32 split_mode_max_reqs;
#define SPLIT_MODE_5704_MAX_REQ 3
@@ -2222,6 +2229,7 @@ struct tg3 {
#define PHY_ID_BCM5705 0x600081a0
#define PHY_ID_BCM5750 0x60008180
#define PHY_ID_BCM5752 0x60008100
+#define PHY_ID_BCM5714 0x60008340
#define PHY_ID_BCM5780 0x60008350
#define PHY_ID_BCM8002 0x60010140
#define PHY_ID_INVALID 0xffffffff
@@ -2246,8 +2254,8 @@ struct tg3 {
(X) == PHY_ID_BCM5411 || (X) == PHY_ID_BCM5701 || \
(X) == PHY_ID_BCM5703 || (X) == PHY_ID_BCM5704 || \
(X) == PHY_ID_BCM5705 || (X) == PHY_ID_BCM5750 || \
- (X) == PHY_ID_BCM5752 || (X) == PHY_ID_BCM5780 || \
- (X) == PHY_ID_BCM8002)
+ (X) == PHY_ID_BCM5752 || (X) == PHY_ID_BCM5714 || \
+ (X) == PHY_ID_BCM5780 || (X) == PHY_ID_BCM8002)
struct tg3_hw_stats *hw_stats;
dma_addr_t stats_mapping;
diff --git a/drivers/net/tokenring/ibmtr.c b/drivers/net/tokenring/ibmtr.c
index 32057e65808b..9f491563944e 100644
--- a/drivers/net/tokenring/ibmtr.c
+++ b/drivers/net/tokenring/ibmtr.c
@@ -318,7 +318,7 @@ static void ibmtr_cleanup_card(struct net_device *dev)
if (dev->base_addr) {
outb(0,dev->base_addr+ADAPTRESET);
- schedule_timeout(TR_RST_TIME); /* wait 50ms */
+ schedule_timeout_uninterruptible(TR_RST_TIME); /* wait 50ms */
outb(0,dev->base_addr+ADAPTRESETREL);
}
@@ -854,8 +854,7 @@ static int tok_init_card(struct net_device *dev)
writeb(~INT_ENABLE, ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_EVEN);
outb(0, PIOaddr + ADAPTRESET);
- current->state=TASK_UNINTERRUPTIBLE;
- schedule_timeout(TR_RST_TIME); /* wait 50ms */
+ schedule_timeout_uninterruptible(TR_RST_TIME); /* wait 50ms */
outb(0, PIOaddr + ADAPTRESETREL);
#ifdef ENABLE_PAGING
@@ -903,8 +902,8 @@ static int tok_open(struct net_device *dev)
DPRINTK("Adapter is up and running\n");
return 0;
}
- current->state=TASK_INTERRUPTIBLE;
- i=schedule_timeout(TR_RETRY_INTERVAL); /* wait 30 seconds */
+ i=schedule_timeout_interruptible(TR_RETRY_INTERVAL);
+ /* wait 30 seconds */
if(i!=0) break; /*prob. a signal, like the i>24*HZ case above */
}
outb(0, dev->base_addr + ADAPTRESET);/* kill pending interrupts*/
diff --git a/drivers/net/tokenring/olympic.c b/drivers/net/tokenring/olympic.c
index 9e7923192a49..05477d24fd49 100644
--- a/drivers/net/tokenring/olympic.c
+++ b/drivers/net/tokenring/olympic.c
@@ -1101,7 +1101,7 @@ static int olympic_close(struct net_device *dev)
while(olympic_priv->srb_queued) {
- t = schedule_timeout(60*HZ);
+ t = schedule_timeout_interruptible(60*HZ);
if(signal_pending(current)) {
printk(KERN_WARNING "%s: SRB timed out.\n",dev->name);
diff --git a/drivers/net/tokenring/proteon.c b/drivers/net/tokenring/proteon.c
index eb1423ede75c..d04c918ebef8 100644
--- a/drivers/net/tokenring/proteon.c
+++ b/drivers/net/tokenring/proteon.c
@@ -29,6 +29,7 @@ static const char version[] = "proteon.c: v1.00 02/01/2003 by Jochen Friedrich\n
#include <linux/init.h>
#include <linux/netdevice.h>
#include <linux/trdevice.h>
+#include <linux/platform_device.h>
#include <asm/system.h>
#include <asm/io.h>
diff --git a/drivers/net/tokenring/skisa.c b/drivers/net/tokenring/skisa.c
index 3c7c66204f74..72cf708396be 100644
--- a/drivers/net/tokenring/skisa.c
+++ b/drivers/net/tokenring/skisa.c
@@ -36,6 +36,7 @@ static const char version[] = "skisa.c: v1.03 09/12/2002 by Jochen Friedrich\n";
#include <linux/init.h>
#include <linux/netdevice.h>
#include <linux/trdevice.h>
+#include <linux/platform_device.h>
#include <asm/system.h>
#include <asm/io.h>
diff --git a/drivers/net/tokenring/tms380tr.c b/drivers/net/tokenring/tms380tr.c
index 2e39bf1f7462..c1925590a0e1 100644
--- a/drivers/net/tokenring/tms380tr.c
+++ b/drivers/net/tokenring/tms380tr.c
@@ -1243,8 +1243,7 @@ void tms380tr_wait(unsigned long time)
tmp = jiffies + time/(1000000/HZ);
do {
- current->state = TASK_INTERRUPTIBLE;
- tmp = schedule_timeout(tmp);
+ tmp = schedule_timeout_interruptible(tmp);
} while(time_after(tmp, jiffies));
#else
udelay(time);
diff --git a/drivers/net/tulip/de2104x.c b/drivers/net/tulip/de2104x.c
index a22d00198e4d..d7fb3ffe06ac 100644
--- a/drivers/net/tulip/de2104x.c
+++ b/drivers/net/tulip/de2104x.c
@@ -1787,10 +1787,15 @@ static void __init de21041_get_srom_info (struct de_private *de)
/* DEC now has a specification but early board makers
just put the address in the first EEPROM locations. */
/* This does memcmp(eedata, eedata+16, 8) */
+
+#ifndef CONFIG_MIPS_COBALT
+
for (i = 0; i < 8; i ++)
if (ee_data[i] != ee_data[16+i])
sa_offset = 20;
+#endif
+
/* store MAC address */
for (i = 0; i < 6; i ++)
de->dev->dev_addr[i] = ee_data[i + sa_offset];
@@ -2071,8 +2076,7 @@ static int __init de_init_one (struct pci_dev *pdev,
return 0;
err_out_iomap:
- if (de->ee_data)
- kfree(de->ee_data);
+ kfree(de->ee_data);
iounmap(regs);
err_out_res:
pci_release_regions(pdev);
@@ -2091,8 +2095,7 @@ static void __exit de_remove_one (struct pci_dev *pdev)
if (!dev)
BUG();
unregister_netdev(dev);
- if (de->ee_data)
- kfree(de->ee_data);
+ kfree(de->ee_data);
iounmap(de->regs);
pci_release_regions(pdev);
pci_disable_device(pdev);
diff --git a/drivers/net/tulip/tulip_core.c b/drivers/net/tulip/tulip_core.c
index 6266a9a7e6e3..125ed00e95a5 100644
--- a/drivers/net/tulip/tulip_core.c
+++ b/drivers/net/tulip/tulip_core.c
@@ -1727,8 +1727,7 @@ err_out_free_ring:
tp->rx_ring, tp->rx_ring_dma);
err_out_mtable:
- if (tp->mtable)
- kfree (tp->mtable);
+ kfree (tp->mtable);
pci_iounmap(pdev, ioaddr);
err_out_free_res:
@@ -1806,8 +1805,7 @@ static void __devexit tulip_remove_one (struct pci_dev *pdev)
sizeof (struct tulip_rx_desc) * RX_RING_SIZE +
sizeof (struct tulip_tx_desc) * TX_RING_SIZE,
tp->rx_ring, tp->rx_ring_dma);
- if (tp->mtable)
- kfree (tp->mtable);
+ kfree (tp->mtable);
pci_iounmap(pdev, tp->base_addr);
free_netdev (dev);
pci_release_regions (pdev);
diff --git a/drivers/net/typhoon.c b/drivers/net/typhoon.c
index ecfa6f8805ce..4c76cb794bfb 100644
--- a/drivers/net/typhoon.c
+++ b/drivers/net/typhoon.c
@@ -419,10 +419,9 @@ typhoon_reset(void __iomem *ioaddr, int wait_type)
TYPHOON_STATUS_WAITING_FOR_HOST)
goto out;
- if(wait_type == WaitSleep) {
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(1);
- } else
+ if(wait_type == WaitSleep)
+ schedule_timeout_uninterruptible(1);
+ else
udelay(TYPHOON_UDELAY);
}
diff --git a/drivers/net/via-rhine.c b/drivers/net/via-rhine.c
index fc7738ffbfff..241871589283 100644
--- a/drivers/net/via-rhine.c
+++ b/drivers/net/via-rhine.c
@@ -490,6 +490,8 @@ struct rhine_private {
u8 tx_thresh, rx_thresh;
struct mii_if_info mii_if;
+ struct work_struct tx_timeout_task;
+ struct work_struct check_media_task;
void __iomem *base;
};
@@ -497,6 +499,8 @@ static int mdio_read(struct net_device *dev, int phy_id, int location);
static void mdio_write(struct net_device *dev, int phy_id, int location, int value);
static int rhine_open(struct net_device *dev);
static void rhine_tx_timeout(struct net_device *dev);
+static void rhine_tx_timeout_task(struct net_device *dev);
+static void rhine_check_media_task(struct net_device *dev);
static int rhine_start_tx(struct sk_buff *skb, struct net_device *dev);
static irqreturn_t rhine_interrupt(int irq, void *dev_instance, struct pt_regs *regs);
static void rhine_tx(struct net_device *dev);
@@ -814,8 +818,9 @@ static int __devinit rhine_init_one(struct pci_dev *pdev,
for (i = 0; i < 6; i++)
dev->dev_addr[i] = ioread8(ioaddr + StationAddr + i);
+ memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
- if (!is_valid_ether_addr(dev->dev_addr)) {
+ if (!is_valid_ether_addr(dev->perm_addr)) {
rc = -EIO;
printk(KERN_ERR "Invalid MAC address\n");
goto err_out_unmap;
@@ -850,6 +855,12 @@ static int __devinit rhine_init_one(struct pci_dev *pdev,
if (rp->quirks & rqRhineI)
dev->features |= NETIF_F_SG|NETIF_F_HW_CSUM;
+ INIT_WORK(&rp->tx_timeout_task,
+ (void (*)(void *))rhine_tx_timeout_task, dev);
+
+ INIT_WORK(&rp->check_media_task,
+ (void (*)(void *))rhine_check_media_task, dev);
+
/* dev->name not defined before register_netdev()! */
rc = register_netdev(dev);
if (rc)
@@ -1076,6 +1087,11 @@ static void rhine_check_media(struct net_device *dev, unsigned int init_media)
ioaddr + ChipCmd1);
}
+static void rhine_check_media_task(struct net_device *dev)
+{
+ rhine_check_media(dev, 0);
+}
+
static void init_registers(struct net_device *dev)
{
struct rhine_private *rp = netdev_priv(dev);
@@ -1129,8 +1145,8 @@ static void rhine_disable_linkmon(void __iomem *ioaddr, u32 quirks)
if (quirks & rqRhineI) {
iowrite8(0x01, ioaddr + MIIRegAddr); // MII_BMSR
- /* Can be called from ISR. Evil. */
- mdelay(1);
+ /* Do not call from ISR! */
+ msleep(1);
/* 0x80 must be set immediately before turning it off */
iowrite8(0x80, ioaddr + MIICmd);
@@ -1220,6 +1236,16 @@ static int rhine_open(struct net_device *dev)
static void rhine_tx_timeout(struct net_device *dev)
{
struct rhine_private *rp = netdev_priv(dev);
+
+ /*
+ * Move bulk of work outside of interrupt context
+ */
+ schedule_work(&rp->tx_timeout_task);
+}
+
+static void rhine_tx_timeout_task(struct net_device *dev)
+{
+ struct rhine_private *rp = netdev_priv(dev);
void __iomem *ioaddr = rp->base;
printk(KERN_WARNING "%s: Transmit timed out, status %4.4x, PHY status "
@@ -1625,7 +1651,7 @@ static void rhine_error(struct net_device *dev, int intr_status)
spin_lock(&rp->lock);
if (intr_status & IntrLinkChange)
- rhine_check_media(dev, 0);
+ schedule_work(&rp->check_media_task);
if (intr_status & IntrStatsMax) {
rp->stats.rx_crc_errors += ioread16(ioaddr + RxCRCErrs);
rp->stats.rx_missed_errors += ioread16(ioaddr + RxMissed);
@@ -1829,6 +1855,7 @@ static struct ethtool_ops netdev_ethtool_ops = {
.set_wol = rhine_set_wol,
.get_sg = ethtool_op_get_sg,
.get_tx_csum = ethtool_op_get_tx_csum,
+ .get_perm_addr = ethtool_op_get_perm_addr,
};
static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
@@ -1872,6 +1899,9 @@ static int rhine_close(struct net_device *dev)
spin_unlock_irq(&rp->lock);
free_irq(rp->pdev->irq, dev);
+
+ flush_scheduled_work();
+
free_rbufs(dev);
free_tbufs(dev);
free_ring(dev);
diff --git a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c
index abc5cee6eedc..82c6b757d306 100644
--- a/drivers/net/via-velocity.c
+++ b/drivers/net/via-velocity.c
@@ -61,7 +61,6 @@
#include <linux/timer.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
-#include <linux/version.h>
#include <linux/string.h>
#include <linux/wait.h>
#include <asm/io.h>
@@ -1212,10 +1211,8 @@ static void velocity_free_td_ring(struct velocity_info *vptr)
velocity_free_td_ring_entry(vptr, j, i);
}
- if (vptr->td_infos[j]) {
- kfree(vptr->td_infos[j]);
- vptr->td_infos[j] = NULL;
- }
+ kfree(vptr->td_infos[j]);
+ vptr->td_infos[j] = NULL;
}
}
diff --git a/drivers/net/wan/cosa.c b/drivers/net/wan/cosa.c
index 7ff814fd65d0..e392ee8b37a1 100644
--- a/drivers/net/wan/cosa.c
+++ b/drivers/net/wan/cosa.c
@@ -400,7 +400,7 @@ static int __init cosa_init(void)
goto out_chrdev;
}
for (i=0; i<nr_cards; i++) {
- class_device_create(cosa_class, MKDEV(cosa_major, i),
+ class_device_create(cosa_class, NULL, MKDEV(cosa_major, i),
NULL, "cosa%d", i);
err = devfs_mk_cdev(MKDEV(cosa_major, i),
S_IFCHR|S_IRUSR|S_IWUSR,
@@ -1617,8 +1617,7 @@ static int get_wait_data(struct cosa_data *cosa)
return r;
}
/* sleep if not ready to read */
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(1);
+ schedule_timeout_interruptible(1);
}
printk(KERN_INFO "cosa: timeout in get_wait_data (status 0x%x)\n",
cosa_getstatus(cosa));
@@ -1644,8 +1643,7 @@ static int put_wait_data(struct cosa_data *cosa, int data)
}
#if 0
/* sleep if not ready to read */
- current->state = TASK_INTERRUPTIBLE;
- schedule_timeout(1);
+ schedule_timeout_interruptible(1);
#endif
}
printk(KERN_INFO "cosa%d: timeout in put_wait_data (status 0x%x)\n",
diff --git a/drivers/net/wan/cycx_drv.c b/drivers/net/wan/cycx_drv.c
index 9e56fc346ba4..e6d005726aad 100644
--- a/drivers/net/wan/cycx_drv.c
+++ b/drivers/net/wan/cycx_drv.c
@@ -109,7 +109,7 @@ static long cycx_2x_irq_options[] = { 7, 3, 5, 9, 10, 11, 12, 15 };
* < 0 error.
* Context: process */
-int __init cycx_drv_init(void)
+static int __init cycx_drv_init(void)
{
printk(KERN_INFO "%s v%u.%u %s\n", fullname, MOD_VERSION, MOD_RELEASE,
copyright);
@@ -119,7 +119,7 @@ int __init cycx_drv_init(void)
/* Module 'remove' entry point.
* o release all remaining system resources */
-void cycx_drv_cleanup(void)
+static void cycx_drv_cleanup(void)
{
}
@@ -184,8 +184,7 @@ int cycx_down(struct cycx_hw *hw)
}
/* Enable interrupt generation. */
-EXPORT_SYMBOL(cycx_inten);
-void cycx_inten(struct cycx_hw *hw)
+static void cycx_inten(struct cycx_hw *hw)
{
writeb(0, hw->dpmbase);
}
diff --git a/drivers/net/wan/cycx_main.c b/drivers/net/wan/cycx_main.c
index 7b48064364dc..430b1f630fb4 100644
--- a/drivers/net/wan/cycx_main.c
+++ b/drivers/net/wan/cycx_main.c
@@ -103,7 +103,7 @@ static struct cycx_device *cycx_card_array; /* adapter data space */
* < 0 error.
* Context: process
*/
-int __init cycx_init(void)
+static int __init cycx_init(void)
{
int cnt, err = -ENOMEM;
diff --git a/drivers/net/wan/cycx_x25.c b/drivers/net/wan/cycx_x25.c
index 02d57c0b4243..a631d1c2fa14 100644
--- a/drivers/net/wan/cycx_x25.c
+++ b/drivers/net/wan/cycx_x25.c
@@ -78,6 +78,7 @@
#define CYCLOMX_X25_DEBUG 1
+#include <linux/ctype.h> /* isdigit() */
#include <linux/errno.h> /* return codes */
#include <linux/if_arp.h> /* ARPHRD_HWX25 */
#include <linux/kernel.h> /* printk(), and other useful stuff */
@@ -418,7 +419,7 @@ static int cycx_wan_new_if(struct wan_device *wandev, struct net_device *dev,
/* Set channel timeouts (default if not specified) */
chan->idle_tmout = conf->idle_timeout ? conf->idle_timeout : 90;
- } else if (is_digit(conf->addr[0])) { /* PVC */
+ } else if (isdigit(conf->addr[0])) { /* PVC */
s16 lcn = dec_to_uint(conf->addr, 0);
if (lcn >= card->u.x.lo_pvc && lcn <= card->u.x.hi_pvc)
@@ -1531,7 +1532,7 @@ static unsigned dec_to_uint(u8 *str, int len)
if (!len)
len = strlen(str);
- for (; len && is_digit(*str); ++str, --len)
+ for (; len && isdigit(*str); ++str, --len)
val = (val * 10) + (*str - (unsigned) '0');
return val;
diff --git a/drivers/net/wan/dscc4.c b/drivers/net/wan/dscc4.c
index 520a77a798e2..2f61a47b4716 100644
--- a/drivers/net/wan/dscc4.c
+++ b/drivers/net/wan/dscc4.c
@@ -446,8 +446,8 @@ static inline unsigned int dscc4_tx_quiescent(struct dscc4_dev_priv *dpriv,
return readl(dpriv->base_addr + CH0FTDA + dpriv->dev_id*4) == dpriv->ltda;
}
-int state_check(u32 state, struct dscc4_dev_priv *dpriv, struct net_device *dev,
- const char *msg)
+static int state_check(u32 state, struct dscc4_dev_priv *dpriv,
+ struct net_device *dev, const char *msg)
{
int ret = 0;
@@ -466,8 +466,9 @@ int state_check(u32 state, struct dscc4_dev_priv *dpriv, struct net_device *dev,
return ret;
}
-void dscc4_tx_print(struct net_device *dev, struct dscc4_dev_priv *dpriv,
- char *msg)
+static void dscc4_tx_print(struct net_device *dev,
+ struct dscc4_dev_priv *dpriv,
+ char *msg)
{
printk(KERN_DEBUG "%s: tx_current=%02d tx_dirty=%02d (%s)\n",
dev->name, dpriv->tx_current, dpriv->tx_dirty, msg);
@@ -507,7 +508,8 @@ static void dscc4_release_ring(struct dscc4_dev_priv *dpriv)
}
}
-inline int try_get_rx_skb(struct dscc4_dev_priv *dpriv, struct net_device *dev)
+static inline int try_get_rx_skb(struct dscc4_dev_priv *dpriv,
+ struct net_device *dev)
{
unsigned int dirty = dpriv->rx_dirty%RX_RING_SIZE;
struct RxFD *rx_fd = dpriv->rx_fd + dirty;
@@ -542,8 +544,7 @@ static int dscc4_wait_ack_cec(struct dscc4_dev_priv *dpriv,
msg, i);
goto done;
}
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(10);
+ schedule_timeout_uninterruptible(10);
rmb();
} while (++i > 0);
printk(KERN_ERR "%s: %s timeout\n", dev->name, msg);
@@ -588,8 +589,7 @@ static inline int dscc4_xpr_ack(struct dscc4_dev_priv *dpriv)
(dpriv->iqtx[cur] & Xpr))
break;
smp_rmb();
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(10);
+ schedule_timeout_uninterruptible(10);
} while (++i > 0);
return (i >= 0 ) ? i : -EAGAIN;
@@ -1035,8 +1035,7 @@ static void dscc4_pci_reset(struct pci_dev *pdev, void __iomem *ioaddr)
/* Flush posted writes */
readl(ioaddr + GSTAR);
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(10);
+ schedule_timeout_uninterruptible(10);
for (i = 0; i < 16; i++)
pci_write_config_dword(pdev, i << 2, dscc4_pci_config_store[i]);
@@ -1894,7 +1893,7 @@ try:
* It failed and locked solid. Thus the introduction of a dummy skb.
* Problem is acknowledged in errata sheet DS5. Joy :o/
*/
-struct sk_buff *dscc4_init_dummy_skb(struct dscc4_dev_priv *dpriv)
+static struct sk_buff *dscc4_init_dummy_skb(struct dscc4_dev_priv *dpriv)
{
struct sk_buff *skb;
diff --git a/drivers/net/wan/farsync.c b/drivers/net/wan/farsync.c
index 2c83cca34b86..7981a2c7906e 100644
--- a/drivers/net/wan/farsync.c
+++ b/drivers/net/wan/farsync.c
@@ -74,11 +74,11 @@ MODULE_LICENSE("GPL");
/*
* Modules parameters and associated varaibles
*/
-int fst_txq_low = FST_LOW_WATER_MARK;
-int fst_txq_high = FST_HIGH_WATER_MARK;
-int fst_max_reads = 7;
-int fst_excluded_cards = 0;
-int fst_excluded_list[FST_MAX_CARDS];
+static int fst_txq_low = FST_LOW_WATER_MARK;
+static int fst_txq_high = FST_HIGH_WATER_MARK;
+static int fst_max_reads = 7;
+static int fst_excluded_cards = 0;
+static int fst_excluded_list[FST_MAX_CARDS];
module_param(fst_txq_low, int, 0);
module_param(fst_txq_high, int, 0);
@@ -572,13 +572,13 @@ static void do_bottom_half_rx(struct fst_card_info *card);
static void fst_process_tx_work_q(unsigned long work_q);
static void fst_process_int_work_q(unsigned long work_q);
-DECLARE_TASKLET(fst_tx_task, fst_process_tx_work_q, 0);
-DECLARE_TASKLET(fst_int_task, fst_process_int_work_q, 0);
+static DECLARE_TASKLET(fst_tx_task, fst_process_tx_work_q, 0);
+static DECLARE_TASKLET(fst_int_task, fst_process_int_work_q, 0);
-struct fst_card_info *fst_card_array[FST_MAX_CARDS];
-spinlock_t fst_work_q_lock;
-u64 fst_work_txq;
-u64 fst_work_intq;
+static struct fst_card_info *fst_card_array[FST_MAX_CARDS];
+static spinlock_t fst_work_q_lock;
+static u64 fst_work_txq;
+static u64 fst_work_intq;
static void
fst_q_work_item(u64 * queue, int card_index)
@@ -980,8 +980,7 @@ fst_issue_cmd(struct fst_port_info *port, unsigned short cmd)
/* Wait for any previous command to complete */
while (mbval > NAK) {
spin_unlock_irqrestore(&card->card_lock, flags);
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(1);
+ schedule_timeout_uninterruptible(1);
spin_lock_irqsave(&card->card_lock, flags);
if (++safety > 2000) {
@@ -1498,7 +1497,7 @@ do_bottom_half_rx(struct fst_card_info *card)
* The interrupt service routine
* Dev_id is our fst_card_info pointer
*/
-irqreturn_t
+static irqreturn_t
fst_intr(int irq, void *dev_id, struct pt_regs *regs)
{
struct fst_card_info *card;
diff --git a/drivers/net/wan/hdlc_fr.c b/drivers/net/wan/hdlc_fr.c
index a5d6891c9d4c..e1601d35dced 100644
--- a/drivers/net/wan/hdlc_fr.c
+++ b/drivers/net/wan/hdlc_fr.c
@@ -330,7 +330,7 @@ static int pvc_close(struct net_device *dev)
-int pvc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
+static int pvc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
{
pvc_device *pvc = dev_to_pvc(dev);
fr_proto_pvc_info info;
diff --git a/drivers/net/wan/lmc/lmc_debug.c b/drivers/net/wan/lmc/lmc_debug.c
index 9dccd9546a17..3b94352b0d03 100644
--- a/drivers/net/wan/lmc/lmc_debug.c
+++ b/drivers/net/wan/lmc/lmc_debug.c
@@ -8,10 +8,10 @@
/*
* Prints out len, max to 80 octets using printk, 20 per line
*/
-void lmcConsoleLog(char *type, unsigned char *ucData, int iLen)
-{
#ifdef DEBUG
#ifdef LMC_PACKET_LOG
+void lmcConsoleLog(char *type, unsigned char *ucData, int iLen)
+{
int iNewLine = 1;
char str[80], *pstr;
@@ -43,26 +43,24 @@ void lmcConsoleLog(char *type, unsigned char *ucData, int iLen)
}
sprintf(pstr, "\n");
printk(str);
+}
#endif
#endif
-}
#ifdef DEBUG
u_int32_t lmcEventLogIndex = 0;
u_int32_t lmcEventLogBuf[LMC_EVENTLOGSIZE * LMC_EVENTLOGARGS];
-#endif
void lmcEventLog (u_int32_t EventNum, u_int32_t arg2, u_int32_t arg3)
{
-#ifdef DEBUG
lmcEventLogBuf[lmcEventLogIndex++] = EventNum;
lmcEventLogBuf[lmcEventLogIndex++] = arg2;
lmcEventLogBuf[lmcEventLogIndex++] = arg3;
lmcEventLogBuf[lmcEventLogIndex++] = jiffies;
lmcEventLogIndex &= (LMC_EVENTLOGSIZE * LMC_EVENTLOGARGS) - 1;
-#endif
}
+#endif /* DEBUG */
void lmc_trace(struct net_device *dev, char *msg){
#ifdef LMC_TRACE
diff --git a/drivers/net/wan/lmc/lmc_media.c b/drivers/net/wan/lmc/lmc_media.c
index f55ce76b00ed..af8b55fdd9d9 100644
--- a/drivers/net/wan/lmc/lmc_media.c
+++ b/drivers/net/wan/lmc/lmc_media.c
@@ -48,14 +48,6 @@
*/
/*
- * For lack of a better place, put the SSI cable stuff here.
- */
-char *lmc_t1_cables[] = {
- "V.10/RS423", "EIA530A", "reserved", "X.21", "V.35",
- "EIA449/EIA530/V.36", "V.28/EIA232", "none", NULL
-};
-
-/*
* protocol independent method.
*/
static void lmc_set_protocol (lmc_softc_t * const, lmc_ctl_t *);
diff --git a/drivers/net/wan/pc300.h b/drivers/net/wan/pc300.h
index 73401b0f0151..2024b26b99e6 100644
--- a/drivers/net/wan/pc300.h
+++ b/drivers/net/wan/pc300.h
@@ -472,24 +472,8 @@ enum pc300_loopback_cmds {
#ifdef __KERNEL__
/* Function Prototypes */
-int dma_buf_write(pc300_t *, int, ucchar *, int);
-int dma_buf_read(pc300_t *, int, struct sk_buff *);
void tx_dma_start(pc300_t *, int);
-void rx_dma_start(pc300_t *, int);
-void tx_dma_stop(pc300_t *, int);
-void rx_dma_stop(pc300_t *, int);
-int cpc_queue_xmit(struct sk_buff *, struct net_device *);
-void cpc_net_rx(struct net_device *);
-void cpc_sca_status(pc300_t *, int);
-int cpc_change_mtu(struct net_device *, int);
-int cpc_ioctl(struct net_device *, struct ifreq *, int);
-int ch_config(pc300dev_t *);
-int rx_config(pc300dev_t *);
-int tx_config(pc300dev_t *);
-void cpc_opench(pc300dev_t *);
-void cpc_closech(pc300dev_t *);
int cpc_open(struct net_device *dev);
-int cpc_close(struct net_device *dev);
int cpc_set_media(hdlc_device *, int);
#endif /* __KERNEL__ */
diff --git a/drivers/net/wan/pc300_drv.c b/drivers/net/wan/pc300_drv.c
index 3e7753b10717..a3e65d1bc19b 100644
--- a/drivers/net/wan/pc300_drv.c
+++ b/drivers/net/wan/pc300_drv.c
@@ -291,6 +291,7 @@ static uclong detect_ram(pc300_t *);
static void plx_init(pc300_t *);
static void cpc_trace(struct net_device *, struct sk_buff *, char);
static int cpc_attach(struct net_device *, unsigned short, unsigned short);
+static int cpc_close(struct net_device *dev);
#ifdef CONFIG_PC300_MLPPP
void cpc_tty_init(pc300dev_t * dev);
@@ -437,7 +438,7 @@ static void rx_dma_buf_check(pc300_t * card, int ch)
printk("\n");
}
-int dma_get_rx_frame_size(pc300_t * card, int ch)
+static int dma_get_rx_frame_size(pc300_t * card, int ch)
{
volatile pcsca_bd_t __iomem *ptdescr;
ucshort first_bd = card->chan[ch].rx_first_bd;
@@ -462,7 +463,7 @@ int dma_get_rx_frame_size(pc300_t * card, int ch)
* dma_buf_write: writes a frame to the Tx DMA buffers
* NOTE: this function writes one frame at a time.
*/
-int dma_buf_write(pc300_t * card, int ch, ucchar * ptdata, int len)
+static int dma_buf_write(pc300_t * card, int ch, ucchar * ptdata, int len)
{
int i, nchar;
volatile pcsca_bd_t __iomem *ptdescr;
@@ -503,7 +504,7 @@ int dma_buf_write(pc300_t * card, int ch, ucchar * ptdata, int len)
* dma_buf_read: reads a frame from the Rx DMA buffers
* NOTE: this function reads one frame at a time.
*/
-int dma_buf_read(pc300_t * card, int ch, struct sk_buff *skb)
+static int dma_buf_read(pc300_t * card, int ch, struct sk_buff *skb)
{
int nchar;
pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
@@ -560,7 +561,7 @@ int dma_buf_read(pc300_t * card, int ch, struct sk_buff *skb)
return (rcvd);
}
-void tx_dma_stop(pc300_t * card, int ch)
+static void tx_dma_stop(pc300_t * card, int ch)
{
void __iomem *scabase = card->hw.scabase;
ucchar drr_ena_bit = 1 << (5 + 2 * ch);
@@ -571,7 +572,7 @@ void tx_dma_stop(pc300_t * card, int ch)
cpc_writeb(scabase + DRR, drr_rst_bit & ~drr_ena_bit);
}
-void rx_dma_stop(pc300_t * card, int ch)
+static void rx_dma_stop(pc300_t * card, int ch)
{
void __iomem *scabase = card->hw.scabase;
ucchar drr_ena_bit = 1 << (4 + 2 * ch);
@@ -582,7 +583,7 @@ void rx_dma_stop(pc300_t * card, int ch)
cpc_writeb(scabase + DRR, drr_rst_bit & ~drr_ena_bit);
}
-void rx_dma_start(pc300_t * card, int ch)
+static void rx_dma_start(pc300_t * card, int ch)
{
void __iomem *scabase = card->hw.scabase;
pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
@@ -607,7 +608,7 @@ void rx_dma_start(pc300_t * card, int ch)
/*************************/
/*** FALC Routines ***/
/*************************/
-void falc_issue_cmd(pc300_t * card, int ch, ucchar cmd)
+static void falc_issue_cmd(pc300_t * card, int ch, ucchar cmd)
{
void __iomem *falcbase = card->hw.falcbase;
unsigned long i = 0;
@@ -622,7 +623,7 @@ void falc_issue_cmd(pc300_t * card, int ch, ucchar cmd)
cpc_writeb(falcbase + F_REG(CMDR, ch), cmd);
}
-void falc_intr_enable(pc300_t * card, int ch)
+static void falc_intr_enable(pc300_t * card, int ch)
{
pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
@@ -672,7 +673,7 @@ void falc_intr_enable(pc300_t * card, int ch)
}
}
-void falc_open_timeslot(pc300_t * card, int ch, int timeslot)
+static void falc_open_timeslot(pc300_t * card, int ch, int timeslot)
{
void __iomem *falcbase = card->hw.falcbase;
ucchar tshf = card->chan[ch].falc.offset;
@@ -688,7 +689,7 @@ void falc_open_timeslot(pc300_t * card, int ch, int timeslot)
(0x80 >> (timeslot & 0x07)));
}
-void falc_close_timeslot(pc300_t * card, int ch, int timeslot)
+static void falc_close_timeslot(pc300_t * card, int ch, int timeslot)
{
void __iomem *falcbase = card->hw.falcbase;
ucchar tshf = card->chan[ch].falc.offset;
@@ -704,7 +705,7 @@ void falc_close_timeslot(pc300_t * card, int ch, int timeslot)
~(0x80 >> (timeslot & 0x07)));
}
-void falc_close_all_timeslots(pc300_t * card, int ch)
+static void falc_close_all_timeslots(pc300_t * card, int ch)
{
pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
@@ -726,7 +727,7 @@ void falc_close_all_timeslots(pc300_t * card, int ch)
}
}
-void falc_open_all_timeslots(pc300_t * card, int ch)
+static void falc_open_all_timeslots(pc300_t * card, int ch)
{
pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
@@ -758,7 +759,7 @@ void falc_open_all_timeslots(pc300_t * card, int ch)
}
}
-void falc_init_timeslot(pc300_t * card, int ch)
+static void falc_init_timeslot(pc300_t * card, int ch)
{
pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
@@ -776,7 +777,7 @@ void falc_init_timeslot(pc300_t * card, int ch)
}
}
-void falc_enable_comm(pc300_t * card, int ch)
+static void falc_enable_comm(pc300_t * card, int ch)
{
pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
falc_t *pfalc = (falc_t *) & chan->falc;
@@ -792,7 +793,7 @@ void falc_enable_comm(pc300_t * card, int ch)
~((CPLD_REG1_FALC_DCD | CPLD_REG1_FALC_CTS) << (2 * ch)));
}
-void falc_disable_comm(pc300_t * card, int ch)
+static void falc_disable_comm(pc300_t * card, int ch)
{
pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
falc_t *pfalc = (falc_t *) & chan->falc;
@@ -806,7 +807,7 @@ void falc_disable_comm(pc300_t * card, int ch)
((CPLD_REG1_FALC_DCD | CPLD_REG1_FALC_CTS) << (2 * ch)));
}
-void falc_init_t1(pc300_t * card, int ch)
+static void falc_init_t1(pc300_t * card, int ch)
{
pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
@@ -975,7 +976,7 @@ void falc_init_t1(pc300_t * card, int ch)
falc_close_all_timeslots(card, ch);
}
-void falc_init_e1(pc300_t * card, int ch)
+static void falc_init_e1(pc300_t * card, int ch)
{
pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
@@ -1155,7 +1156,7 @@ void falc_init_e1(pc300_t * card, int ch)
falc_close_all_timeslots(card, ch);
}
-void falc_init_hdlc(pc300_t * card, int ch)
+static void falc_init_hdlc(pc300_t * card, int ch)
{
void __iomem *falcbase = card->hw.falcbase;
pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
@@ -1181,7 +1182,7 @@ void falc_init_hdlc(pc300_t * card, int ch)
falc_intr_enable(card, ch);
}
-void te_config(pc300_t * card, int ch)
+static void te_config(pc300_t * card, int ch)
{
pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
@@ -1241,7 +1242,7 @@ void te_config(pc300_t * card, int ch)
CPC_UNLOCK(card, flags);
}
-void falc_check_status(pc300_t * card, int ch, unsigned char frs0)
+static void falc_check_status(pc300_t * card, int ch, unsigned char frs0)
{
pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
@@ -1397,7 +1398,7 @@ void falc_check_status(pc300_t * card, int ch, unsigned char frs0)
}
}
-void falc_update_stats(pc300_t * card, int ch)
+static void falc_update_stats(pc300_t * card, int ch)
{
pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
@@ -1450,7 +1451,7 @@ void falc_update_stats(pc300_t * card, int ch)
* the synchronizer and then sent to the system interface.
*----------------------------------------------------------------------------
*/
-void falc_remote_loop(pc300_t * card, int ch, int loop_on)
+static void falc_remote_loop(pc300_t * card, int ch, int loop_on)
{
pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
@@ -1495,7 +1496,7 @@ void falc_remote_loop(pc300_t * card, int ch, int loop_on)
* coding must be identical.
*----------------------------------------------------------------------------
*/
-void falc_local_loop(pc300_t * card, int ch, int loop_on)
+static void falc_local_loop(pc300_t * card, int ch, int loop_on)
{
pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
falc_t *pfalc = (falc_t *) & chan->falc;
@@ -1522,7 +1523,7 @@ void falc_local_loop(pc300_t * card, int ch, int loop_on)
* looped. They are originated by the FALC-LH transmitter.
*----------------------------------------------------------------------------
*/
-void falc_payload_loop(pc300_t * card, int ch, int loop_on)
+static void falc_payload_loop(pc300_t * card, int ch, int loop_on)
{
pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
@@ -1576,7 +1577,7 @@ void falc_payload_loop(pc300_t * card, int ch, int loop_on)
* Description: Turns XLU bit off in the proper register
*----------------------------------------------------------------------------
*/
-void turn_off_xlu(pc300_t * card, int ch)
+static void turn_off_xlu(pc300_t * card, int ch)
{
pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
@@ -1597,7 +1598,7 @@ void turn_off_xlu(pc300_t * card, int ch)
* Description: Turns XLD bit off in the proper register
*----------------------------------------------------------------------------
*/
-void turn_off_xld(pc300_t * card, int ch)
+static void turn_off_xld(pc300_t * card, int ch)
{
pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
@@ -1619,7 +1620,7 @@ void turn_off_xld(pc300_t * card, int ch)
* to generate a LOOP activation code over a T1/E1 line.
*----------------------------------------------------------------------------
*/
-void falc_generate_loop_up_code(pc300_t * card, int ch)
+static void falc_generate_loop_up_code(pc300_t * card, int ch)
{
pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
@@ -1652,7 +1653,7 @@ void falc_generate_loop_up_code(pc300_t * card, int ch)
* to generate a LOOP deactivation code over a T1/E1 line.
*----------------------------------------------------------------------------
*/
-void falc_generate_loop_down_code(pc300_t * card, int ch)
+static void falc_generate_loop_down_code(pc300_t * card, int ch)
{
pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
@@ -1682,7 +1683,7 @@ void falc_generate_loop_down_code(pc300_t * card, int ch)
* it on the reception side.
*----------------------------------------------------------------------------
*/
-void falc_pattern_test(pc300_t * card, int ch, unsigned int activate)
+static void falc_pattern_test(pc300_t * card, int ch, unsigned int activate)
{
pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
@@ -1729,7 +1730,7 @@ void falc_pattern_test(pc300_t * card, int ch, unsigned int activate)
* Description: This routine returns the bit error counter value
*----------------------------------------------------------------------------
*/
-ucshort falc_pattern_test_error(pc300_t * card, int ch)
+static ucshort falc_pattern_test_error(pc300_t * card, int ch)
{
pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
falc_t *pfalc = (falc_t *) & chan->falc;
@@ -1769,7 +1770,7 @@ cpc_trace(struct net_device *dev, struct sk_buff *skb_main, char rx_tx)
netif_rx(skb);
}
-void cpc_tx_timeout(struct net_device *dev)
+static void cpc_tx_timeout(struct net_device *dev)
{
pc300dev_t *d = (pc300dev_t *) dev->priv;
pc300ch_t *chan = (pc300ch_t *) d->chan;
@@ -1797,7 +1798,7 @@ void cpc_tx_timeout(struct net_device *dev)
netif_wake_queue(dev);
}
-int cpc_queue_xmit(struct sk_buff *skb, struct net_device *dev)
+static int cpc_queue_xmit(struct sk_buff *skb, struct net_device *dev)
{
pc300dev_t *d = (pc300dev_t *) dev->priv;
pc300ch_t *chan = (pc300ch_t *) d->chan;
@@ -1880,7 +1881,7 @@ int cpc_queue_xmit(struct sk_buff *skb, struct net_device *dev)
return 0;
}
-void cpc_net_rx(struct net_device *dev)
+static void cpc_net_rx(struct net_device *dev)
{
pc300dev_t *d = (pc300dev_t *) dev->priv;
pc300ch_t *chan = (pc300ch_t *) d->chan;
@@ -2403,7 +2404,7 @@ static irqreturn_t cpc_intr(int irq, void *dev_id, struct pt_regs *regs)
return IRQ_HANDLED;
}
-void cpc_sca_status(pc300_t * card, int ch)
+static void cpc_sca_status(pc300_t * card, int ch)
{
ucchar ilar;
void __iomem *scabase = card->hw.scabase;
@@ -2495,7 +2496,7 @@ void cpc_sca_status(pc300_t * card, int ch)
}
}
-void cpc_falc_status(pc300_t * card, int ch)
+static void cpc_falc_status(pc300_t * card, int ch)
{
pc300ch_t *chan = &card->chan[ch];
falc_t *pfalc = (falc_t *) & chan->falc;
@@ -2523,7 +2524,7 @@ void cpc_falc_status(pc300_t * card, int ch)
CPC_UNLOCK(card, flags);
}
-int cpc_change_mtu(struct net_device *dev, int new_mtu)
+static int cpc_change_mtu(struct net_device *dev, int new_mtu)
{
if ((new_mtu < 128) || (new_mtu > PC300_DEF_MTU))
return -EINVAL;
@@ -2531,7 +2532,7 @@ int cpc_change_mtu(struct net_device *dev, int new_mtu)
return 0;
}
-int cpc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
+static int cpc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
{
hdlc_device *hdlc = dev_to_hdlc(dev);
pc300dev_t *d = (pc300dev_t *) dev->priv;
@@ -2856,7 +2857,7 @@ static int clock_rate_calc(uclong rate, uclong clock, int *br_io)
}
}
-int ch_config(pc300dev_t * d)
+static int ch_config(pc300dev_t * d)
{
pc300ch_t *chan = (pc300ch_t *) d->chan;
pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
@@ -3004,7 +3005,7 @@ int ch_config(pc300dev_t * d)
return 0;
}
-int rx_config(pc300dev_t * d)
+static int rx_config(pc300dev_t * d)
{
pc300ch_t *chan = (pc300ch_t *) d->chan;
pc300_t *card = (pc300_t *) chan->card;
@@ -3035,7 +3036,7 @@ int rx_config(pc300dev_t * d)
return 0;
}
-int tx_config(pc300dev_t * d)
+static int tx_config(pc300dev_t * d)
{
pc300ch_t *chan = (pc300ch_t *) d->chan;
pc300_t *card = (pc300_t *) chan->card;
@@ -3098,7 +3099,7 @@ static int cpc_attach(struct net_device *dev, unsigned short encoding,
return 0;
}
-void cpc_opench(pc300dev_t * d)
+static void cpc_opench(pc300dev_t * d)
{
pc300ch_t *chan = (pc300ch_t *) d->chan;
pc300_t *card = (pc300_t *) chan->card;
@@ -3116,7 +3117,7 @@ void cpc_opench(pc300dev_t * d)
cpc_readb(scabase + M_REG(CTL, ch)) & ~(CTL_RTS | CTL_DTR));
}
-void cpc_closech(pc300dev_t * d)
+static void cpc_closech(pc300dev_t * d)
{
pc300ch_t *chan = (pc300ch_t *) d->chan;
pc300_t *card = (pc300_t *) chan->card;
@@ -3173,7 +3174,7 @@ int cpc_open(struct net_device *dev)
return 0;
}
-int cpc_close(struct net_device *dev)
+static int cpc_close(struct net_device *dev)
{
hdlc_device *hdlc = dev_to_hdlc(dev);
pc300dev_t *d = (pc300dev_t *) dev->priv;
diff --git a/drivers/net/wan/pc300_tty.c b/drivers/net/wan/pc300_tty.c
index 8454bf6caaa7..52f26b9c69d2 100644
--- a/drivers/net/wan/pc300_tty.c
+++ b/drivers/net/wan/pc300_tty.c
@@ -112,10 +112,10 @@ typedef struct _st_cpc_tty_area {
static struct tty_driver serial_drv;
/* local variables */
-st_cpc_tty_area cpc_tty_area[CPC_TTY_NPORTS];
+static st_cpc_tty_area cpc_tty_area[CPC_TTY_NPORTS];
-int cpc_tty_cnt=0; /* number of intrfaces configured with MLPPP */
-int cpc_tty_unreg_flag = 0;
+static int cpc_tty_cnt = 0; /* number of intrfaces configured with MLPPP */
+static int cpc_tty_unreg_flag = 0;
/* TTY functions prototype */
static int cpc_tty_open(struct tty_struct *tty, struct file *flip);
@@ -132,9 +132,9 @@ static void cpc_tty_trace(pc300dev_t *dev, char* buf, int len, char rxtx);
static void cpc_tty_signal_off(pc300dev_t *pc300dev, unsigned char);
static void cpc_tty_signal_on(pc300dev_t *pc300dev, unsigned char);
-int pc300_tiocmset(struct tty_struct *, struct file *,
- unsigned int, unsigned int);
-int pc300_tiocmget(struct tty_struct *, struct file *);
+static int pc300_tiocmset(struct tty_struct *, struct file *,
+ unsigned int, unsigned int);
+static int pc300_tiocmget(struct tty_struct *, struct file *);
/* functions called by PC300 driver */
void cpc_tty_init(pc300dev_t *dev);
@@ -538,8 +538,8 @@ static int cpc_tty_chars_in_buffer(struct tty_struct *tty)
return(0);
}
-int pc300_tiocmset(struct tty_struct *tty, struct file *file,
- unsigned int set, unsigned int clear)
+static int pc300_tiocmset(struct tty_struct *tty, struct file *file,
+ unsigned int set, unsigned int clear)
{
st_cpc_tty_area *cpc_tty;
@@ -565,7 +565,7 @@ int pc300_tiocmset(struct tty_struct *tty, struct file *file,
return 0;
}
-int pc300_tiocmget(struct tty_struct *tty, struct file *file)
+static int pc300_tiocmget(struct tty_struct *tty, struct file *file)
{
unsigned int result;
unsigned char status;
diff --git a/drivers/net/wan/sdla.c b/drivers/net/wan/sdla.c
index 3ac9a45b20fa..036adc4f8ba7 100644
--- a/drivers/net/wan/sdla.c
+++ b/drivers/net/wan/sdla.c
@@ -182,7 +182,7 @@ static char sdla_byte(struct net_device *dev, int addr)
return(byte);
}
-void sdla_stop(struct net_device *dev)
+static void sdla_stop(struct net_device *dev)
{
struct frad_local *flp;
@@ -209,7 +209,7 @@ void sdla_stop(struct net_device *dev)
}
}
-void sdla_start(struct net_device *dev)
+static void sdla_start(struct net_device *dev)
{
struct frad_local *flp;
@@ -247,7 +247,7 @@ void sdla_start(struct net_device *dev)
*
***************************************************/
-int sdla_z80_poll(struct net_device *dev, int z80_addr, int jiffs, char resp1, char resp2)
+static int sdla_z80_poll(struct net_device *dev, int z80_addr, int jiffs, char resp1, char resp2)
{
unsigned long start, done, now;
char resp, *temp;
@@ -505,7 +505,7 @@ static int sdla_cmd(struct net_device *dev, int cmd, short dlci, short flags,
static int sdla_reconfig(struct net_device *dev);
-int sdla_activate(struct net_device *slave, struct net_device *master)
+static int sdla_activate(struct net_device *slave, struct net_device *master)
{
struct frad_local *flp;
int i;
@@ -527,7 +527,7 @@ int sdla_activate(struct net_device *slave, struct net_device *master)
return(0);
}
-int sdla_deactivate(struct net_device *slave, struct net_device *master)
+static int sdla_deactivate(struct net_device *slave, struct net_device *master)
{
struct frad_local *flp;
int i;
@@ -549,7 +549,7 @@ int sdla_deactivate(struct net_device *slave, struct net_device *master)
return(0);
}
-int sdla_assoc(struct net_device *slave, struct net_device *master)
+static int sdla_assoc(struct net_device *slave, struct net_device *master)
{
struct frad_local *flp;
int i;
@@ -585,7 +585,7 @@ int sdla_assoc(struct net_device *slave, struct net_device *master)
return(0);
}
-int sdla_deassoc(struct net_device *slave, struct net_device *master)
+static int sdla_deassoc(struct net_device *slave, struct net_device *master)
{
struct frad_local *flp;
int i;
@@ -613,7 +613,7 @@ int sdla_deassoc(struct net_device *slave, struct net_device *master)
return(0);
}
-int sdla_dlci_conf(struct net_device *slave, struct net_device *master, int get)
+static int sdla_dlci_conf(struct net_device *slave, struct net_device *master, int get)
{
struct frad_local *flp;
struct dlci_local *dlp;
@@ -1324,7 +1324,7 @@ NOTE: This is rather a useless action right now, as the
return(0);
}
-int sdla_change_mtu(struct net_device *dev, int new_mtu)
+static int sdla_change_mtu(struct net_device *dev, int new_mtu)
{
struct frad_local *flp;
@@ -1337,7 +1337,7 @@ int sdla_change_mtu(struct net_device *dev, int new_mtu)
return(-EOPNOTSUPP);
}
-int sdla_set_config(struct net_device *dev, struct ifmap *map)
+static int sdla_set_config(struct net_device *dev, struct ifmap *map)
{
struct frad_local *flp;
int i;
diff --git a/drivers/net/wan/sdla_fr.c b/drivers/net/wan/sdla_fr.c
index 0497dbdb8631..7f1ce9d4333e 100644
--- a/drivers/net/wan/sdla_fr.c
+++ b/drivers/net/wan/sdla_fr.c
@@ -822,7 +822,7 @@ static int new_if(struct wan_device* wandev, struct net_device* dev,
chan->card = card;
/* verify media address */
- if (is_digit(conf->addr[0])) {
+ if (isdigit(conf->addr[0])) {
dlci = dec_to_uint(conf->addr, 0);
@@ -3456,7 +3456,7 @@ static unsigned int dec_to_uint (unsigned char* str, int len)
if (!len)
len = strlen(str);
- for (val = 0; len && is_digit(*str); ++str, --len)
+ for (val = 0; len && isdigit(*str); ++str, --len)
val = (val * 10) + (*str - (unsigned)'0');
return val;
diff --git a/drivers/net/wan/sdla_x25.c b/drivers/net/wan/sdla_x25.c
index 8a95d61a2f8f..63f846d6f3a6 100644
--- a/drivers/net/wan/sdla_x25.c
+++ b/drivers/net/wan/sdla_x25.c
@@ -957,7 +957,7 @@ static int new_if(struct wan_device* wandev, struct net_device* dev,
chan->hold_timeout = (conf->hold_timeout) ?
conf->hold_timeout : 10;
- }else if (is_digit(conf->addr[0])){ /* PVC */
+ }else if (isdigit(conf->addr[0])){ /* PVC */
int lcn = dec_to_uint(conf->addr, 0);
if ((lcn >= card->u.x.lo_pvc) && (lcn <= card->u.x.hi_pvc)){
@@ -3875,7 +3875,7 @@ static unsigned int dec_to_uint (unsigned char* str, int len)
if (!len)
len = strlen(str);
- for (val = 0; len && is_digit(*str); ++str, --len)
+ for (val = 0; len && isdigit(*str); ++str, --len)
val = (val * 10) + (*str - (unsigned)'0');
return val;
@@ -3896,9 +3896,9 @@ static unsigned int hex_to_uint (unsigned char* str, int len)
for (val = 0; len; ++str, --len)
{
ch = *str;
- if (is_digit(ch))
+ if (isdigit(ch))
val = (val << 4) + (ch - (unsigned)'0');
- else if (is_hex_digit(ch))
+ else if (isxdigit(ch))
val = (val << 4) + ((ch & 0xDF) - (unsigned)'A' + 10);
else break;
}
diff --git a/drivers/net/wan/sdladrv.c b/drivers/net/wan/sdladrv.c
index c8bc6da57a41..7c2cf2e76300 100644
--- a/drivers/net/wan/sdladrv.c
+++ b/drivers/net/wan/sdladrv.c
@@ -642,9 +642,7 @@ int sdla_mapmem (sdlahw_t* hw, unsigned long addr)
* Enable interrupt generation.
*/
-EXPORT_SYMBOL(sdla_inten);
-
-int sdla_inten (sdlahw_t* hw)
+static int sdla_inten (sdlahw_t* hw)
{
unsigned port = hw->port;
int tmp, i;
@@ -698,8 +696,7 @@ int sdla_inten (sdlahw_t* hw)
* Disable interrupt generation.
*/
-EXPORT_SYMBOL(sdla_intde);
-
+#if 0
int sdla_intde (sdlahw_t* hw)
{
unsigned port = hw->port;
@@ -748,14 +745,13 @@ int sdla_intde (sdlahw_t* hw)
}
return 0;
}
+#endif /* 0 */
/*============================================================================
* Acknowledge SDLA hardware interrupt.
*/
-EXPORT_SYMBOL(sdla_intack);
-
-int sdla_intack (sdlahw_t* hw)
+static int sdla_intack (sdlahw_t* hw)
{
unsigned port = hw->port;
int tmp;
@@ -827,8 +823,7 @@ void read_S514_int_stat (sdlahw_t* hw, u32* int_status)
* Generate an interrupt to adapter's CPU.
*/
-EXPORT_SYMBOL(sdla_intr);
-
+#if 0
int sdla_intr (sdlahw_t* hw)
{
unsigned port = hw->port;
@@ -863,6 +858,7 @@ int sdla_intr (sdlahw_t* hw)
}
return 0;
}
+#endif /* 0 */
/*============================================================================
* Execute Adapter Command.
diff --git a/drivers/net/wan/syncppp.c b/drivers/net/wan/syncppp.c
index a6d3b55013a5..2d1bba06a085 100644
--- a/drivers/net/wan/syncppp.c
+++ b/drivers/net/wan/syncppp.c
@@ -221,7 +221,7 @@ static void sppp_clear_timeout(struct sppp *p)
* here.
*/
-void sppp_input (struct net_device *dev, struct sk_buff *skb)
+static void sppp_input (struct net_device *dev, struct sk_buff *skb)
{
struct ppp_header *h;
struct sppp *sp = (struct sppp *)sppp_of(dev);
@@ -355,8 +355,6 @@ done:
return;
}
-EXPORT_SYMBOL(sppp_input);
-
/*
* Handle transmit packets.
*/
@@ -990,7 +988,7 @@ EXPORT_SYMBOL(sppp_reopen);
* the mtu is out of range.
*/
-int sppp_change_mtu(struct net_device *dev, int new_mtu)
+static int sppp_change_mtu(struct net_device *dev, int new_mtu)
{
if(new_mtu<128||new_mtu>PPP_MTU||(dev->flags&IFF_UP))
return -EINVAL;
@@ -998,8 +996,6 @@ int sppp_change_mtu(struct net_device *dev, int new_mtu)
return 0;
}
-EXPORT_SYMBOL(sppp_change_mtu);
-
/**
* sppp_do_ioctl - Ioctl handler for ppp/hdlc
* @dev: Device subject to ioctl
@@ -1456,7 +1452,7 @@ static int sppp_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_t
return 0;
}
-struct packet_type sppp_packet_type = {
+static struct packet_type sppp_packet_type = {
.type = __constant_htons(ETH_P_WAN_PPP),
.func = sppp_rcv,
};
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c
index 06998c2240d9..340ab4ee4b67 100644
--- a/drivers/net/wireless/airo.c
+++ b/drivers/net/wireless/airo.c
@@ -35,6 +35,7 @@
#include <linux/interrupt.h>
#include <linux/in.h>
#include <linux/bitops.h>
+#include <linux/scatterlist.h>
#include <asm/io.h>
#include <asm/system.h>
@@ -46,6 +47,8 @@
#include <linux/pci.h>
#include <asm/uaccess.h>
+#include "airo.h"
+
#ifdef CONFIG_PCI
static struct pci_device_id card_ids[] = {
{ 0x14b9, 1, PCI_ANY_ID, PCI_ANY_ID, },
@@ -1046,7 +1049,6 @@ static WifiCtlHdr wifictlhdr8023 = {
}
};
-#ifdef WIRELESS_EXT
// Frequency list (map channels to frequencies)
static const long frequency_list[] = { 2412, 2417, 2422, 2427, 2432, 2437, 2442,
2447, 2452, 2457, 2462, 2467, 2472, 2484 };
@@ -1067,7 +1069,6 @@ typedef struct wep_key_t {
/* List of Wireless Handlers (new API) */
static const struct iw_handler_def airo_handler_def;
-#endif /* WIRELESS_EXT */
static const char version[] = "airo.c 0.6 (Ben Reed & Javier Achirica)";
@@ -1110,10 +1111,8 @@ static irqreturn_t airo_interrupt( int irq, void* dev_id, struct pt_regs
static int airo_thread(void *data);
static void timer_func( struct net_device *dev );
static int airo_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
-#ifdef WIRELESS_EXT
static struct iw_statistics *airo_get_wireless_stats (struct net_device *dev);
static void airo_read_wireless_stats (struct airo_info *local);
-#endif /* WIRELESS_EXT */
#ifdef CISCO_EXT
static int readrids(struct net_device *dev, aironet_ioctl *comp);
static int writerids(struct net_device *dev, aironet_ioctl *comp);
@@ -1187,12 +1186,10 @@ struct airo_info {
int fid;
} xmit, xmit11;
struct net_device *wifidev;
-#ifdef WIRELESS_EXT
struct iw_statistics wstats; // wireless stats
unsigned long scan_timestamp; /* Time started to scan */
struct iw_spy_data spy_data;
struct iw_public_data wireless_data;
-#endif /* WIRELESS_EXT */
#ifdef MICSUPPORT
/* MIC stuff */
struct crypto_tfm *tfm;
@@ -1596,11 +1593,9 @@ static void emmh32_setseed(emmh32_context *context, u8 *pkey, int keylen, struct
aes_counter[12] = (u8)(counter >> 24);
counter++;
memcpy (plain, aes_counter, 16);
- sg[0].page = virt_to_page(plain);
- sg[0].offset = ((long) plain & ~PAGE_MASK);
- sg[0].length = 16;
+ sg_set_buf(sg, plain, 16);
crypto_cipher_encrypt(tfm, sg, sg, 16);
- cipher = kmap(sg[0].page) + sg[0].offset;
+ cipher = kmap(sg->page) + sg->offset;
for (j=0; (j<16) && (i< (sizeof(context->coeff)/sizeof(context->coeff[0]))); ) {
context->coeff[i++] = ntohl(*(u32 *)&cipher[j]);
j += 4;
@@ -2047,7 +2042,7 @@ static int mpi_send_packet (struct net_device *dev)
return 1;
}
-static void get_tx_error(struct airo_info *ai, u32 fid)
+static void get_tx_error(struct airo_info *ai, s32 fid)
{
u16 status;
@@ -2387,14 +2382,10 @@ void stop_airo_card( struct net_device *dev, int freeres )
dev_kfree_skb(skb);
}
- if (ai->flash)
- kfree(ai->flash);
- if (ai->rssi)
- kfree(ai->rssi);
- if (ai->APList)
- kfree(ai->APList);
- if (ai->SSID)
- kfree(ai->SSID);
+ kfree(ai->flash);
+ kfree(ai->rssi);
+ kfree(ai->APList);
+ kfree(ai->SSID);
if (freeres) {
/* PCMCIA frees this stuff, so only for PCI and ISA */
release_region( dev->base_addr, 64 );
@@ -2527,7 +2518,8 @@ static int mpi_map_card(struct airo_info *ai, struct pci_dev *pci,
unsigned long mem_start, mem_len, aux_start, aux_len;
int rc = -1;
int i;
- unsigned char *busaddroff,*vpackoff;
+ dma_addr_t busaddroff;
+ unsigned char *vpackoff;
unsigned char __iomem *pciaddroff;
mem_start = pci_resource_start(pci, 1);
@@ -2570,7 +2562,7 @@ static int mpi_map_card(struct airo_info *ai, struct pci_dev *pci,
/*
* Setup descriptor RX, TX, CONFIG
*/
- busaddroff = (unsigned char *)ai->shared_dma;
+ busaddroff = ai->shared_dma;
pciaddroff = ai->pciaux + AUX_OFFSET;
vpackoff = ai->shared;
@@ -2579,7 +2571,7 @@ static int mpi_map_card(struct airo_info *ai, struct pci_dev *pci,
ai->rxfids[i].pending = 0;
ai->rxfids[i].card_ram_off = pciaddroff;
ai->rxfids[i].virtual_host_addr = vpackoff;
- ai->rxfids[i].rx_desc.host_addr = (dma_addr_t) busaddroff;
+ ai->rxfids[i].rx_desc.host_addr = busaddroff;
ai->rxfids[i].rx_desc.valid = 1;
ai->rxfids[i].rx_desc.len = PKTSIZE;
ai->rxfids[i].rx_desc.rdy = 0;
@@ -2594,7 +2586,7 @@ static int mpi_map_card(struct airo_info *ai, struct pci_dev *pci,
ai->txfids[i].card_ram_off = pciaddroff;
ai->txfids[i].virtual_host_addr = vpackoff;
ai->txfids[i].tx_desc.valid = 1;
- ai->txfids[i].tx_desc.host_addr = (dma_addr_t) busaddroff;
+ ai->txfids[i].tx_desc.host_addr = busaddroff;
memcpy(ai->txfids[i].virtual_host_addr,
&wifictlhdr8023, sizeof(wifictlhdr8023));
@@ -2607,8 +2599,8 @@ static int mpi_map_card(struct airo_info *ai, struct pci_dev *pci,
/* Rid descriptor setup */
ai->config_desc.card_ram_off = pciaddroff;
ai->config_desc.virtual_host_addr = vpackoff;
- ai->config_desc.rid_desc.host_addr = (dma_addr_t) busaddroff;
- ai->ridbus = (dma_addr_t)busaddroff;
+ ai->config_desc.rid_desc.host_addr = busaddroff;
+ ai->ridbus = busaddroff;
ai->config_desc.rid_desc.rid = 0;
ai->config_desc.rid_desc.len = RIDSIZE;
ai->config_desc.rid_desc.valid = 1;
@@ -2647,9 +2639,7 @@ static void wifi_setup(struct net_device *dev)
dev->get_stats = &airo_get_stats;
dev->set_mac_address = &airo_set_mac_address;
dev->do_ioctl = &airo_ioctl;
-#ifdef WIRELESS_EXT
dev->wireless_handlers = &airo_handler_def;
-#endif /* WIRELESS_EXT */
dev->change_mtu = &airo_change_mtu;
dev->open = &airo_open;
dev->stop = &airo_close;
@@ -2675,9 +2665,7 @@ static struct net_device *init_wifidev(struct airo_info *ai,
dev->priv = ethdev->priv;
dev->irq = ethdev->irq;
dev->base_addr = ethdev->base_addr;
-#ifdef WIRELESS_EXT
dev->wireless_data = ethdev->wireless_data;
-#endif /* WIRELESS_EXT */
memcpy(dev->dev_addr, ethdev->dev_addr, dev->addr_len);
err = register_netdev(dev);
if (err<0) {
@@ -2755,11 +2743,9 @@ static struct net_device *_init_airo_card( unsigned short irq, int port,
dev->set_multicast_list = &airo_set_multicast_list;
dev->set_mac_address = &airo_set_mac_address;
dev->do_ioctl = &airo_ioctl;
-#ifdef WIRELESS_EXT
dev->wireless_handlers = &airo_handler_def;
ai->wireless_data.spy_data = &ai->spy_data;
dev->wireless_data = &ai->wireless_data;
-#endif /* WIRELESS_EXT */
dev->change_mtu = &airo_change_mtu;
dev->open = &airo_open;
dev->stop = &airo_close;
@@ -3637,10 +3623,8 @@ static u16 setup_card(struct airo_info *ai, u8 *mac, int lock)
int rc;
memset( &mySsid, 0, sizeof( mySsid ) );
- if (ai->flash) {
- kfree (ai->flash);
- ai->flash = NULL;
- }
+ kfree (ai->flash);
+ ai->flash = NULL;
/* The NOP is the first step in getting the card going */
cmd.cmd = NOP;
@@ -3677,14 +3661,10 @@ static u16 setup_card(struct airo_info *ai, u8 *mac, int lock)
tdsRssiRid rssi_rid;
CapabilityRid cap_rid;
- if (ai->APList) {
- kfree(ai->APList);
- ai->APList = NULL;
- }
- if (ai->SSID) {
- kfree(ai->SSID);
- ai->SSID = NULL;
- }
+ kfree(ai->APList);
+ ai->APList = NULL;
+ kfree(ai->SSID);
+ ai->SSID = NULL;
// general configuration (read/modify/write)
status = readConfigRid(ai, lock);
if ( status != SUCCESS ) return ERROR;
@@ -3698,10 +3678,8 @@ static u16 setup_card(struct airo_info *ai, u8 *mac, int lock)
memcpy(ai->rssi, (u8*)&rssi_rid + 2, 512); /* Skip RID length member */
}
else {
- if (ai->rssi) {
- kfree(ai->rssi);
- ai->rssi = NULL;
- }
+ kfree(ai->rssi);
+ ai->rssi = NULL;
if (cap_rid.softCap & 8)
ai->config.rmode |= RXMODE_NORMALIZED_RSSI;
else
@@ -4557,9 +4535,8 @@ static int proc_status_open( struct inode *inode, struct file *file ) {
StatusRid status_rid;
int i;
- if ((file->private_data = kmalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
+ if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
return -ENOMEM;
- memset(file->private_data, 0, sizeof(struct proc_data));
data = (struct proc_data *)file->private_data;
if ((data->rbuffer = kmalloc( 2048, GFP_KERNEL )) == NULL) {
kfree (file->private_data);
@@ -4637,9 +4614,8 @@ static int proc_stats_rid_open( struct inode *inode,
int i, j;
u32 *vals = stats.vals;
- if ((file->private_data = kmalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
+ if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
return -ENOMEM;
- memset(file->private_data, 0, sizeof(struct proc_data));
data = (struct proc_data *)file->private_data;
if ((data->rbuffer = kmalloc( 4096, GFP_KERNEL )) == NULL) {
kfree (file->private_data);
@@ -4903,20 +4879,18 @@ static int proc_config_open( struct inode *inode, struct file *file ) {
struct airo_info *ai = dev->priv;
int i;
- if ((file->private_data = kmalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
+ if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
return -ENOMEM;
- memset(file->private_data, 0, sizeof(struct proc_data));
data = (struct proc_data *)file->private_data;
if ((data->rbuffer = kmalloc( 2048, GFP_KERNEL )) == NULL) {
kfree (file->private_data);
return -ENOMEM;
}
- if ((data->wbuffer = kmalloc( 2048, GFP_KERNEL )) == NULL) {
+ if ((data->wbuffer = kzalloc( 2048, GFP_KERNEL )) == NULL) {
kfree (data->rbuffer);
kfree (file->private_data);
return -ENOMEM;
}
- memset( data->wbuffer, 0, 2048 );
data->maxwritelen = 2048;
data->on_close = proc_config_on_close;
@@ -5177,24 +5151,21 @@ static int proc_wepkey_open( struct inode *inode, struct file *file ) {
int j=0;
int rc;
- if ((file->private_data = kmalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
+ if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
return -ENOMEM;
- memset(file->private_data, 0, sizeof(struct proc_data));
memset(&wkr, 0, sizeof(wkr));
data = (struct proc_data *)file->private_data;
- if ((data->rbuffer = kmalloc( 180, GFP_KERNEL )) == NULL) {
+ if ((data->rbuffer = kzalloc( 180, GFP_KERNEL )) == NULL) {
kfree (file->private_data);
return -ENOMEM;
}
- memset(data->rbuffer, 0, 180);
data->writelen = 0;
data->maxwritelen = 80;
- if ((data->wbuffer = kmalloc( 80, GFP_KERNEL )) == NULL) {
+ if ((data->wbuffer = kzalloc( 80, GFP_KERNEL )) == NULL) {
kfree (data->rbuffer);
kfree (file->private_data);
return -ENOMEM;
}
- memset( data->wbuffer, 0, 80 );
data->on_close = proc_wepkey_on_close;
ptr = data->rbuffer;
@@ -5225,9 +5196,8 @@ static int proc_SSID_open( struct inode *inode, struct file *file ) {
char *ptr;
SsidRid SSID_rid;
- if ((file->private_data = kmalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
+ if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
return -ENOMEM;
- memset(file->private_data, 0, sizeof(struct proc_data));
data = (struct proc_data *)file->private_data;
if ((data->rbuffer = kmalloc( 104, GFP_KERNEL )) == NULL) {
kfree (file->private_data);
@@ -5235,12 +5205,11 @@ static int proc_SSID_open( struct inode *inode, struct file *file ) {
}
data->writelen = 0;
data->maxwritelen = 33*3;
- if ((data->wbuffer = kmalloc( 33*3, GFP_KERNEL )) == NULL) {
+ if ((data->wbuffer = kzalloc( 33*3, GFP_KERNEL )) == NULL) {
kfree (data->rbuffer);
kfree (file->private_data);
return -ENOMEM;
}
- memset( data->wbuffer, 0, 33*3 );
data->on_close = proc_SSID_on_close;
readSsidRid(ai, &SSID_rid);
@@ -5269,9 +5238,8 @@ static int proc_APList_open( struct inode *inode, struct file *file ) {
char *ptr;
APListRid APList_rid;
- if ((file->private_data = kmalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
+ if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
return -ENOMEM;
- memset(file->private_data, 0, sizeof(struct proc_data));
data = (struct proc_data *)file->private_data;
if ((data->rbuffer = kmalloc( 104, GFP_KERNEL )) == NULL) {
kfree (file->private_data);
@@ -5279,12 +5247,11 @@ static int proc_APList_open( struct inode *inode, struct file *file ) {
}
data->writelen = 0;
data->maxwritelen = 4*6*3;
- if ((data->wbuffer = kmalloc( data->maxwritelen, GFP_KERNEL )) == NULL) {
+ if ((data->wbuffer = kzalloc( data->maxwritelen, GFP_KERNEL )) == NULL) {
kfree (data->rbuffer);
kfree (file->private_data);
return -ENOMEM;
}
- memset( data->wbuffer, 0, data->maxwritelen );
data->on_close = proc_APList_on_close;
readAPListRid(ai, &APList_rid);
@@ -5319,9 +5286,8 @@ static int proc_BSSList_open( struct inode *inode, struct file *file ) {
/* If doLoseSync is not 1, we won't do a Lose Sync */
int doLoseSync = -1;
- if ((file->private_data = kmalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
+ if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
return -ENOMEM;
- memset(file->private_data, 0, sizeof(struct proc_data));
data = (struct proc_data *)file->private_data;
if ((data->rbuffer = kmalloc( 1024, GFP_KERNEL )) == NULL) {
kfree (file->private_data);
@@ -5380,11 +5346,13 @@ static int proc_BSSList_open( struct inode *inode, struct file *file ) {
static int proc_close( struct inode *inode, struct file *file )
{
- struct proc_data *data = (struct proc_data *)file->private_data;
- if ( data->on_close != NULL ) data->on_close( inode, file );
- if ( data->rbuffer ) kfree( data->rbuffer );
- if ( data->wbuffer ) kfree( data->wbuffer );
- kfree( data );
+ struct proc_data *data = file->private_data;
+
+ if (data->on_close != NULL)
+ data->on_close(inode, file);
+ kfree(data->rbuffer);
+ kfree(data->wbuffer);
+ kfree(data);
return 0;
}
@@ -5515,12 +5483,13 @@ static int airo_pci_resume(struct pci_dev *pdev)
struct net_device *dev = pci_get_drvdata(pdev);
struct airo_info *ai = dev->priv;
Resp rsp;
+ pci_power_t prev_state = pdev->current_state;
- pci_set_power_state(pdev, 0);
+ pci_set_power_state(pdev, PCI_D0);
pci_restore_state(pdev);
- pci_enable_wake(pdev, pci_choose_state(pdev, ai->power), 0);
+ pci_enable_wake(pdev, PCI_D0, 0);
- if (ai->power.event > 1) {
+ if (prev_state != PCI_D1) {
reset_card(dev, 0);
mpi_init_descriptors(ai);
setup_card(ai, dev->dev_addr, 0);
@@ -5598,7 +5567,6 @@ static void __exit airo_cleanup_module( void )
remove_proc_entry("aironet", proc_root_driver);
}
-#ifdef WIRELESS_EXT
/*
* Initial Wireless Extension code for Aironet driver by :
* Jean Tourrilhes <jt@hpl.hp.com> - HPL - 17 November 00
@@ -7107,8 +7075,6 @@ static const struct iw_handler_def airo_handler_def =
.get_wireless_stats = airo_get_wireless_stats,
};
-#endif /* WIRELESS_EXT */
-
/*
* This defines the configuration part of the Wireless Extensions
* Note : irq and spinlock protection will occur in the subroutines
@@ -7187,7 +7153,6 @@ static int airo_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
return rc;
}
-#ifdef WIRELESS_EXT
/*
* Get the Wireless stats out of the driver
* Note : irq and spinlock protection will occur in the subroutines
@@ -7260,7 +7225,6 @@ static struct iw_statistics *airo_get_wireless_stats(struct net_device *dev)
return &local->wstats;
}
-#endif /* WIRELESS_EXT */
#ifdef CISCO_EXT
/*
diff --git a/drivers/net/wireless/airo.h b/drivers/net/wireless/airo.h
new file mode 100644
index 000000000000..e480adf86be6
--- /dev/null
+++ b/drivers/net/wireless/airo.h
@@ -0,0 +1,9 @@
+#ifndef _AIRO_H_
+#define _AIRO_H_
+
+struct net_device *init_airo_card(unsigned short irq, int port, int is_pcmcia,
+ struct device *dmdev);
+int reset_airo_card(struct net_device *dev);
+void stop_airo_card(struct net_device *dev, int freeres);
+
+#endif /* _AIRO_H_ */
diff --git a/drivers/net/wireless/airo_cs.c b/drivers/net/wireless/airo_cs.c
index bf25584d68d3..e328547599dc 100644
--- a/drivers/net/wireless/airo_cs.c
+++ b/drivers/net/wireless/airo_cs.c
@@ -42,6 +42,8 @@
#include <asm/io.h>
#include <asm/system.h>
+#include "airo.h"
+
/*
All the PCMCIA modules use PCMCIA_DEBUG to control debugging. If
you do not define PCMCIA_DEBUG at all, all the debug code will be
@@ -78,10 +80,6 @@ MODULE_SUPPORTED_DEVICE("Aironet 4500, 4800 and Cisco 340 PCMCIA cards");
event handler.
*/
-struct net_device *init_airo_card( int, int, int, struct device * );
-void stop_airo_card( struct net_device *, int );
-int reset_airo_card( struct net_device * );
-
static void airo_config(dev_link_t *link);
static void airo_release(dev_link_t *link);
static int airo_event(event_t event, int priority,
@@ -172,12 +170,11 @@ static dev_link_t *airo_attach(void)
DEBUG(0, "airo_attach()\n");
/* Initialize the dev_link_t structure */
- link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL);
+ link = kzalloc(sizeof(struct dev_link_t), GFP_KERNEL);
if (!link) {
printk(KERN_ERR "airo_cs: no memory for new device\n");
return NULL;
}
- memset(link, 0, sizeof(struct dev_link_t));
/* Interrupt setup */
link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
@@ -196,13 +193,12 @@ static dev_link_t *airo_attach(void)
link->conf.IntType = INT_MEMORY_AND_IO;
/* Allocate space for private device-specific data */
- local = kmalloc(sizeof(local_info_t), GFP_KERNEL);
+ local = kzalloc(sizeof(local_info_t), GFP_KERNEL);
if (!local) {
printk(KERN_ERR "airo_cs: no memory for new device\n");
kfree (link);
return NULL;
}
- memset(local, 0, sizeof(local_info_t));
link->priv = local;
/* Register with Card Services */
@@ -258,9 +254,7 @@ static void airo_detach(dev_link_t *link)
/* Unlink device structure, free pieces */
*linkp = link->next;
- if (link->priv) {
- kfree(link->priv);
- }
+ kfree(link->priv);
kfree(link);
} /* airo_detach */
diff --git a/drivers/net/wireless/airport.c b/drivers/net/wireless/airport.c
index 9d496703c465..7b321f7cf358 100644
--- a/drivers/net/wireless/airport.c
+++ b/drivers/net/wireless/airport.c
@@ -15,28 +15,11 @@
#define PFX DRIVER_NAME ": "
#include <linux/config.h>
-
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
-#include <linux/ptrace.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <linux/timer.h>
-#include <linux/ioport.h>
-#include <linux/netdevice.h>
-#include <linux/if_arp.h>
-#include <linux/etherdevice.h>
-#include <linux/wireless.h>
-
-#include <asm/io.h>
-#include <asm/system.h>
-#include <asm/current.h>
-#include <asm/prom.h>
-#include <asm/machdep.h>
+#include <linux/delay.h>
#include <asm/pmac_feature.h>
-#include <asm/irq.h>
-#include <asm/uaccess.h>
#include "orinoco.h"
diff --git a/drivers/net/wireless/atmel.c b/drivers/net/wireless/atmel.c
index dbc991a5afc9..5e53c5258a33 100644
--- a/drivers/net/wireless/atmel.c
+++ b/drivers/net/wireless/atmel.c
@@ -618,12 +618,12 @@ static int atmel_lock_mac(struct atmel_private *priv);
static void atmel_wmem32(struct atmel_private *priv, u16 pos, u32 data);
static void atmel_command_irq(struct atmel_private *priv);
static int atmel_validate_channel(struct atmel_private *priv, int channel);
-static void atmel_management_frame(struct atmel_private *priv, struct ieee80211_hdr *header,
+static void atmel_management_frame(struct atmel_private *priv, struct ieee80211_hdr_4addr *header,
u16 frame_len, u8 rssi);
static void atmel_management_timer(u_long a);
static void atmel_send_command(struct atmel_private *priv, int command, void *cmd, int cmd_size);
static int atmel_send_command_wait(struct atmel_private *priv, int command, void *cmd, int cmd_size);
-static void atmel_transmit_management_frame(struct atmel_private *priv, struct ieee80211_hdr *header,
+static void atmel_transmit_management_frame(struct atmel_private *priv, struct ieee80211_hdr_4addr *header,
u8 *body, int body_len);
static u8 atmel_get_mib8(struct atmel_private *priv, u8 type, u8 index);
@@ -827,7 +827,7 @@ static void tx_update_descriptor(struct atmel_private *priv, int is_bcast, u16 l
static int start_tx (struct sk_buff *skb, struct net_device *dev)
{
struct atmel_private *priv = netdev_priv(dev);
- struct ieee80211_hdr header;
+ struct ieee80211_hdr_4addr header;
unsigned long flags;
u16 buff, frame_ctl, len = (ETH_ZLEN < skb->len) ? skb->len : ETH_ZLEN;
u8 SNAP_RFC1024[6] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00};
@@ -902,7 +902,7 @@ static int start_tx (struct sk_buff *skb, struct net_device *dev)
}
static void atmel_transmit_management_frame(struct atmel_private *priv,
- struct ieee80211_hdr *header,
+ struct ieee80211_hdr_4addr *header,
u8 *body, int body_len)
{
u16 buff;
@@ -917,7 +917,7 @@ static void atmel_transmit_management_frame(struct atmel_private *priv,
tx_update_descriptor(priv, header->addr1[0] & 0x01, len, buff, TX_PACKET_TYPE_MGMT);
}
-static void fast_rx_path(struct atmel_private *priv, struct ieee80211_hdr *header,
+static void fast_rx_path(struct atmel_private *priv, struct ieee80211_hdr_4addr *header,
u16 msdu_size, u16 rx_packet_loc, u32 crc)
{
/* fast path: unfragmented packet copy directly into skbuf */
@@ -990,7 +990,7 @@ static int probe_crc(struct atmel_private *priv, u16 packet_loc, u16 msdu_size)
return (crc ^ 0xffffffff) == netcrc;
}
-static void frag_rx_path(struct atmel_private *priv, struct ieee80211_hdr *header,
+static void frag_rx_path(struct atmel_private *priv, struct ieee80211_hdr_4addr *header,
u16 msdu_size, u16 rx_packet_loc, u32 crc, u16 seq_no, u8 frag_no, int more_frags)
{
u8 mac4[6];
@@ -1082,7 +1082,7 @@ static void frag_rx_path(struct atmel_private *priv, struct ieee80211_hdr *heade
static void rx_done_irq(struct atmel_private *priv)
{
int i;
- struct ieee80211_hdr header;
+ struct ieee80211_hdr_4addr header;
for (i = 0;
atmel_rmem8(priv, atmel_rx(priv, RX_DESC_FLAGS_OFFSET, priv->rx_desc_head)) == RX_DESC_FLAG_VALID &&
@@ -1654,8 +1654,7 @@ void stop_atmel_card(struct net_device *dev)
unregister_netdev(dev);
remove_proc_entry("driver/atmel", NULL);
free_irq(dev->irq, dev);
- if (priv->firmware)
- kfree(priv->firmware);
+ kfree(priv->firmware);
release_region(dev->base_addr, 32);
free_netdev(dev);
}
@@ -2217,7 +2216,7 @@ static int atmel_get_range(struct net_device *dev,
int k,i,j;
dwrq->length = sizeof(struct iw_range);
- memset(range, 0, sizeof(range));
+ memset(range, 0, sizeof(struct iw_range));
range->min_nwid = 0x0000;
range->max_nwid = 0x0000;
range->num_channels = 0;
@@ -2449,8 +2448,7 @@ static int atmel_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
break;
}
- if (priv->firmware)
- kfree(priv->firmware);
+ kfree(priv->firmware);
priv->firmware = new_firmware;
priv->firmware_length = com.len;
@@ -2649,7 +2647,7 @@ static void handle_beacon_probe(struct atmel_private *priv, u16 capability, u8 c
static void send_authentication_request(struct atmel_private *priv, u16 system, u8 *challenge, int challenge_len)
{
- struct ieee80211_hdr header;
+ struct ieee80211_hdr_4addr header;
struct auth_body auth;
header.frame_ctl = cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_AUTH);
@@ -2684,7 +2682,7 @@ static void send_association_request(struct atmel_private *priv, int is_reassoc)
{
u8 *ssid_el_p;
int bodysize;
- struct ieee80211_hdr header;
+ struct ieee80211_hdr_4addr header;
struct ass_req_format {
u16 capability;
u16 listen_interval;
@@ -2734,7 +2732,7 @@ static void send_association_request(struct atmel_private *priv, int is_reassoc)
atmel_transmit_management_frame(priv, &header, (void *)&body, bodysize);
}
-static int is_frame_from_current_bss(struct atmel_private *priv, struct ieee80211_hdr *header)
+static int is_frame_from_current_bss(struct atmel_private *priv, struct ieee80211_hdr_4addr *header)
{
if (le16_to_cpu(header->frame_ctl) & IEEE80211_FCTL_FROMDS)
return memcmp(header->addr3, priv->CurrentBSSID, 6) == 0;
@@ -2784,7 +2782,7 @@ static int retrieve_bss(struct atmel_private *priv)
}
-static void store_bss_info(struct atmel_private *priv, struct ieee80211_hdr *header,
+static void store_bss_info(struct atmel_private *priv, struct ieee80211_hdr_4addr *header,
u16 capability, u16 beacon_period, u8 channel, u8 rssi,
u8 ssid_len, u8 *ssid, int is_beacon)
{
@@ -3075,7 +3073,7 @@ static void atmel_smooth_qual(struct atmel_private *priv)
}
/* deals with incoming managment frames. */
-static void atmel_management_frame(struct atmel_private *priv, struct ieee80211_hdr *header,
+static void atmel_management_frame(struct atmel_private *priv, struct ieee80211_hdr_4addr *header,
u16 frame_len, u8 rssi)
{
u16 subtype;
diff --git a/drivers/net/wireless/atmel_cs.c b/drivers/net/wireless/atmel_cs.c
index 0c3301ef70cc..17d1fd90f832 100644
--- a/drivers/net/wireless/atmel_cs.c
+++ b/drivers/net/wireless/atmel_cs.c
@@ -181,12 +181,11 @@ static dev_link_t *atmel_attach(void)
DEBUG(0, "atmel_attach()\n");
/* Initialize the dev_link_t structure */
- link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL);
+ link = kzalloc(sizeof(struct dev_link_t), GFP_KERNEL);
if (!link) {
printk(KERN_ERR "atmel_cs: no memory for new device\n");
return NULL;
}
- memset(link, 0, sizeof(struct dev_link_t));
/* Interrupt setup */
link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
@@ -205,13 +204,12 @@ static dev_link_t *atmel_attach(void)
link->conf.IntType = INT_MEMORY_AND_IO;
/* Allocate space for private device-specific data */
- local = kmalloc(sizeof(local_info_t), GFP_KERNEL);
+ local = kzalloc(sizeof(local_info_t), GFP_KERNEL);
if (!local) {
printk(KERN_ERR "atmel_cs: no memory for new device\n");
kfree (link);
return NULL;
}
- memset(local, 0, sizeof(local_info_t));
link->priv = local;
/* Register with Card Services */
@@ -260,8 +258,7 @@ static void atmel_detach(dev_link_t *link)
/* Unlink device structure, free pieces */
*linkp = link->next;
- if (link->priv)
- kfree(link->priv);
+ kfree(link->priv);
kfree(link);
}
diff --git a/drivers/net/wireless/hermes.c b/drivers/net/wireless/hermes.c
index 21c3d0d227e6..579480dad374 100644
--- a/drivers/net/wireless/hermes.c
+++ b/drivers/net/wireless/hermes.c
@@ -39,17 +39,10 @@
*/
#include <linux/config.h>
-
#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/threads.h>
-#include <linux/smp.h>
-#include <asm/io.h>
-#include <linux/delay.h>
-#include <linux/init.h>
#include <linux/kernel.h>
-#include <linux/net.h>
-#include <asm/errno.h>
+#include <linux/init.h>
+#include <linux/delay.h>
#include "hermes.h"
@@ -451,6 +444,43 @@ int hermes_bap_pwrite(hermes_t *hw, int bap, const void *buf, unsigned len,
return err;
}
+/* Write a block of data to the chip's buffer with padding if
+ * neccessary, via the BAP. Synchronization/serialization is the
+ * caller's problem. len must be even.
+ *
+ * Returns: < 0 on internal failure (errno), 0 on success, > 0 on error from firmware
+ */
+int hermes_bap_pwrite_pad(hermes_t *hw, int bap, const void *buf, unsigned data_len, unsigned len,
+ u16 id, u16 offset)
+{
+ int dreg = bap ? HERMES_DATA1 : HERMES_DATA0;
+ int err = 0;
+
+ if (len < 0 || len % 2 || data_len > len)
+ return -EINVAL;
+
+ err = hermes_bap_seek(hw, bap, id, offset);
+ if (err)
+ goto out;
+
+ /* Transfer all the complete words of data */
+ hermes_write_words(hw, dreg, buf, data_len/2);
+ /* If there is an odd byte left over pad and transfer it */
+ if (data_len & 1) {
+ u8 end[2];
+ end[1] = 0;
+ end[0] = ((unsigned char *)buf)[data_len - 1];
+ hermes_write_words(hw, dreg, end, 1);
+ data_len ++;
+ }
+ /* Now send zeros for the padding */
+ if (data_len < len)
+ hermes_clear_words(hw, dreg, (len - data_len) / 2);
+ /* Complete */
+ out:
+ return err;
+}
+
/* Read a Length-Type-Value record from the card.
*
* If length is NULL, we ignore the length read from the card, and
@@ -538,6 +568,7 @@ EXPORT_SYMBOL(hermes_allocate);
EXPORT_SYMBOL(hermes_bap_pread);
EXPORT_SYMBOL(hermes_bap_pwrite);
+EXPORT_SYMBOL(hermes_bap_pwrite_pad);
EXPORT_SYMBOL(hermes_read_ltv);
EXPORT_SYMBOL(hermes_write_ltv);
diff --git a/drivers/net/wireless/hermes.h b/drivers/net/wireless/hermes.h
index 8c9e874c9118..a6bd472d75d4 100644
--- a/drivers/net/wireless/hermes.h
+++ b/drivers/net/wireless/hermes.h
@@ -30,9 +30,8 @@
* access to the hermes_t structure, and to the hardware
*/
-#include <linux/delay.h>
#include <linux/if_ether.h>
-#include <asm/byteorder.h>
+#include <asm/io.h>
/*
* Limits and constants
@@ -192,13 +191,13 @@
#define HERMES_RXSTAT_WMP (0x6000) /* Wavelan-II Management Protocol frame */
struct hermes_tx_descriptor {
- u16 status;
- u16 reserved1;
- u16 reserved2;
- u32 sw_support;
+ __le16 status;
+ __le16 reserved1;
+ __le16 reserved2;
+ __le32 sw_support;
u8 retry_count;
u8 tx_rate;
- u16 tx_control;
+ __le16 tx_control;
} __attribute__ ((packed));
#define HERMES_TXSTAT_RETRYERR (0x0001)
@@ -222,60 +221,60 @@ struct hermes_tx_descriptor {
#define HERMES_INQ_SEC_STAT_AGERE (0xF202)
struct hermes_tallies_frame {
- u16 TxUnicastFrames;
- u16 TxMulticastFrames;
- u16 TxFragments;
- u16 TxUnicastOctets;
- u16 TxMulticastOctets;
- u16 TxDeferredTransmissions;
- u16 TxSingleRetryFrames;
- u16 TxMultipleRetryFrames;
- u16 TxRetryLimitExceeded;
- u16 TxDiscards;
- u16 RxUnicastFrames;
- u16 RxMulticastFrames;
- u16 RxFragments;
- u16 RxUnicastOctets;
- u16 RxMulticastOctets;
- u16 RxFCSErrors;
- u16 RxDiscards_NoBuffer;
- u16 TxDiscardsWrongSA;
- u16 RxWEPUndecryptable;
- u16 RxMsgInMsgFragments;
- u16 RxMsgInBadMsgFragments;
+ __le16 TxUnicastFrames;
+ __le16 TxMulticastFrames;
+ __le16 TxFragments;
+ __le16 TxUnicastOctets;
+ __le16 TxMulticastOctets;
+ __le16 TxDeferredTransmissions;
+ __le16 TxSingleRetryFrames;
+ __le16 TxMultipleRetryFrames;
+ __le16 TxRetryLimitExceeded;
+ __le16 TxDiscards;
+ __le16 RxUnicastFrames;
+ __le16 RxMulticastFrames;
+ __le16 RxFragments;
+ __le16 RxUnicastOctets;
+ __le16 RxMulticastOctets;
+ __le16 RxFCSErrors;
+ __le16 RxDiscards_NoBuffer;
+ __le16 TxDiscardsWrongSA;
+ __le16 RxWEPUndecryptable;
+ __le16 RxMsgInMsgFragments;
+ __le16 RxMsgInBadMsgFragments;
/* Those last are probably not available in very old firmwares */
- u16 RxDiscards_WEPICVError;
- u16 RxDiscards_WEPExcluded;
+ __le16 RxDiscards_WEPICVError;
+ __le16 RxDiscards_WEPExcluded;
} __attribute__ ((packed));
/* Grabbed from wlan-ng - Thanks Mark... - Jean II
* This is the result of a scan inquiry command */
/* Structure describing info about an Access Point */
struct prism2_scan_apinfo {
- u16 channel; /* Channel where the AP sits */
- u16 noise; /* Noise level */
- u16 level; /* Signal level */
+ __le16 channel; /* Channel where the AP sits */
+ __le16 noise; /* Noise level */
+ __le16 level; /* Signal level */
u8 bssid[ETH_ALEN]; /* MAC address of the Access Point */
- u16 beacon_interv; /* Beacon interval */
- u16 capabilities; /* Capabilities */
- u16 essid_len; /* ESSID length */
+ __le16 beacon_interv; /* Beacon interval */
+ __le16 capabilities; /* Capabilities */
+ __le16 essid_len; /* ESSID length */
u8 essid[32]; /* ESSID of the network */
u8 rates[10]; /* Bit rate supported */
- u16 proberesp_rate; /* Data rate of the response frame */
- u16 atim; /* ATIM window time, Kus (hostscan only) */
+ __le16 proberesp_rate; /* Data rate of the response frame */
+ __le16 atim; /* ATIM window time, Kus (hostscan only) */
} __attribute__ ((packed));
/* Same stuff for the Lucent/Agere card.
* Thanks to h1kari <h1kari AT dachb0den.com> - Jean II */
struct agere_scan_apinfo {
- u16 channel; /* Channel where the AP sits */
- u16 noise; /* Noise level */
- u16 level; /* Signal level */
+ __le16 channel; /* Channel where the AP sits */
+ __le16 noise; /* Noise level */
+ __le16 level; /* Signal level */
u8 bssid[ETH_ALEN]; /* MAC address of the Access Point */
- u16 beacon_interv; /* Beacon interval */
- u16 capabilities; /* Capabilities */
+ __le16 beacon_interv; /* Beacon interval */
+ __le16 capabilities; /* Capabilities */
/* bits: 0-ess, 1-ibss, 4-privacy [wep] */
- u16 essid_len; /* ESSID length */
+ __le16 essid_len; /* ESSID length */
u8 essid[32]; /* ESSID of the network */
} __attribute__ ((packed));
@@ -283,16 +282,16 @@ struct agere_scan_apinfo {
struct symbol_scan_apinfo {
u8 channel; /* Channel where the AP sits */
u8 unknown1; /* 8 in 2.9x and 3.9x f/w, 0 otherwise */
- u16 noise; /* Noise level */
- u16 level; /* Signal level */
+ __le16 noise; /* Noise level */
+ __le16 level; /* Signal level */
u8 bssid[ETH_ALEN]; /* MAC address of the Access Point */
- u16 beacon_interv; /* Beacon interval */
- u16 capabilities; /* Capabilities */
+ __le16 beacon_interv; /* Beacon interval */
+ __le16 capabilities; /* Capabilities */
/* bits: 0-ess, 1-ibss, 4-privacy [wep] */
- u16 essid_len; /* ESSID length */
+ __le16 essid_len; /* ESSID length */
u8 essid[32]; /* ESSID of the network */
- u16 rates[5]; /* Bit rate supported */
- u16 basic_rates; /* Basic rates bitmask */
+ __le16 rates[5]; /* Bit rate supported */
+ __le16 basic_rates; /* Basic rates bitmask */
u8 unknown2[6]; /* Always FF:FF:FF:FF:00:00 */
u8 unknown3[8]; /* Always 0, appeared in f/w 3.91-68 */
} __attribute__ ((packed));
@@ -312,7 +311,7 @@ union hermes_scan_info {
#define HERMES_LINKSTATUS_ASSOC_FAILED (0x0006)
struct hermes_linkstatus {
- u16 linkstatus; /* Link status */
+ __le16 linkstatus; /* Link status */
} __attribute__ ((packed));
struct hermes_response {
@@ -321,8 +320,8 @@ struct hermes_response {
/* "ID" structure - used for ESSID and station nickname */
struct hermes_idstring {
- u16 len;
- u16 val[16];
+ __le16 len;
+ __le16 val[16];
} __attribute__ ((packed));
struct hermes_multicast {
@@ -377,6 +376,8 @@ int hermes_bap_pread(hermes_t *hw, int bap, void *buf, unsigned len,
u16 id, u16 offset);
int hermes_bap_pwrite(hermes_t *hw, int bap, const void *buf, unsigned len,
u16 id, u16 offset);
+int hermes_bap_pwrite_pad(hermes_t *hw, int bap, const void *buf,
+ unsigned data_len, unsigned len, u16 id, u16 offset);
int hermes_read_ltv(hermes_t *hw, int bap, u16 rid, unsigned buflen,
u16 *length, void *buf);
int hermes_write_ltv(hermes_t *hw, int bap, u16 rid,
@@ -447,7 +448,7 @@ static inline void hermes_clear_words(struct hermes *hw, int off, unsigned count
static inline int hermes_read_wordrec(hermes_t *hw, int bap, u16 rid, u16 *word)
{
- u16 rec;
+ __le16 rec;
int err;
err = HERMES_READ_RECORD(hw, bap, rid, &rec);
@@ -457,7 +458,7 @@ static inline int hermes_read_wordrec(hermes_t *hw, int bap, u16 rid, u16 *word)
static inline int hermes_write_wordrec(hermes_t *hw, int bap, u16 rid, u16 word)
{
- u16 rec = cpu_to_le16(word);
+ __le16 rec = cpu_to_le16(word);
return HERMES_WRITE_RECORD(hw, bap, rid, &rec);
}
diff --git a/drivers/net/wireless/hostap/hostap.c b/drivers/net/wireless/hostap/hostap.c
index e7f5821b4942..3d2ea61033be 100644
--- a/drivers/net/wireless/hostap/hostap.c
+++ b/drivers/net/wireless/hostap/hostap.c
@@ -13,7 +13,6 @@
*/
#include <linux/config.h>
-#include <linux/version.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
@@ -716,9 +715,6 @@ static int prism2_close(struct net_device *dev)
hostap_deauth_all_stas(dev, local->ap, 1);
#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
- if (local->func->dev_close && local->func->dev_close(local))
- return 0;
-
if (dev == local->dev) {
local->func->hw_shutdown(dev, HOSTAP_HW_ENABLE_CMDCOMPL);
}
@@ -766,9 +762,6 @@ static int prism2_open(struct net_device *dev)
local->hw_downloading)
return -ENODEV;
- if (local->func->dev_open && local->func->dev_open(local))
- return 1;
-
if (!try_module_get(local->hw_module))
return -ENODEV;
local->num_dev_open++;
diff --git a/drivers/net/wireless/hostap/hostap_80211_rx.c b/drivers/net/wireless/hostap/hostap_80211_rx.c
index b0501243b175..ffac50899454 100644
--- a/drivers/net/wireless/hostap/hostap_80211_rx.c
+++ b/drivers/net/wireless/hostap/hostap_80211_rx.c
@@ -6,10 +6,10 @@
void hostap_dump_rx_80211(const char *name, struct sk_buff *skb,
struct hostap_80211_rx_status *rx_stats)
{
- struct ieee80211_hdr *hdr;
+ struct ieee80211_hdr_4addr *hdr;
u16 fc;
- hdr = (struct ieee80211_hdr *) skb->data;
+ hdr = (struct ieee80211_hdr_4addr *) skb->data;
printk(KERN_DEBUG "%s: RX signal=%d noise=%d rate=%d len=%d "
"jiffies=%ld\n",
@@ -51,7 +51,7 @@ int prism2_rx_80211(struct net_device *dev, struct sk_buff *skb,
int hdrlen, phdrlen, head_need, tail_need;
u16 fc;
int prism_header, ret;
- struct ieee80211_hdr *hdr;
+ struct ieee80211_hdr_4addr *hdr;
iface = netdev_priv(dev);
local = iface->local;
@@ -70,7 +70,7 @@ int prism2_rx_80211(struct net_device *dev, struct sk_buff *skb,
phdrlen = 0;
}
- hdr = (struct ieee80211_hdr *) skb->data;
+ hdr = (struct ieee80211_hdr_4addr *) skb->data;
fc = le16_to_cpu(hdr->frame_ctl);
if (type == PRISM2_RX_MGMT && (fc & IEEE80211_FCTL_VERS)) {
@@ -215,7 +215,7 @@ prism2_frag_cache_find(local_info_t *local, unsigned int seq,
/* Called only as a tasklet (software IRQ) */
static struct sk_buff *
-prism2_frag_cache_get(local_info_t *local, struct ieee80211_hdr *hdr)
+prism2_frag_cache_get(local_info_t *local, struct ieee80211_hdr_4addr *hdr)
{
struct sk_buff *skb = NULL;
u16 sc;
@@ -229,7 +229,7 @@ prism2_frag_cache_get(local_info_t *local, struct ieee80211_hdr *hdr)
if (frag == 0) {
/* Reserve enough space to fit maximum frame length */
skb = dev_alloc_skb(local->dev->mtu +
- sizeof(struct ieee80211_hdr) +
+ sizeof(struct ieee80211_hdr_4addr) +
8 /* LLC */ +
2 /* alignment */ +
8 /* WEP */ + ETH_ALEN /* WDS */);
@@ -267,7 +267,7 @@ prism2_frag_cache_get(local_info_t *local, struct ieee80211_hdr *hdr)
/* Called only as a tasklet (software IRQ) */
static int prism2_frag_cache_invalidate(local_info_t *local,
- struct ieee80211_hdr *hdr)
+ struct ieee80211_hdr_4addr *hdr)
{
u16 sc;
unsigned int seq;
@@ -441,7 +441,7 @@ hostap_rx_frame_mgmt(local_info_t *local, struct sk_buff *skb,
u16 stype)
{
if (local->iw_mode == IW_MODE_MASTER) {
- hostap_update_sta_ps(local, (struct ieee80211_hdr *)
+ hostap_update_sta_ps(local, (struct ieee80211_hdr_4addr *)
skb->data);
}
@@ -520,7 +520,7 @@ static inline struct net_device *prism2_rx_get_wds(local_info_t *local,
static inline int
-hostap_rx_frame_wds(local_info_t *local, struct ieee80211_hdr *hdr,
+hostap_rx_frame_wds(local_info_t *local, struct ieee80211_hdr_4addr *hdr,
u16 fc, struct net_device **wds)
{
/* FIX: is this really supposed to accept WDS frames only in Master
@@ -579,13 +579,13 @@ static int hostap_is_eapol_frame(local_info_t *local, struct sk_buff *skb)
{
struct net_device *dev = local->dev;
u16 fc, ethertype;
- struct ieee80211_hdr *hdr;
+ struct ieee80211_hdr_4addr *hdr;
u8 *pos;
if (skb->len < 24)
return 0;
- hdr = (struct ieee80211_hdr *) skb->data;
+ hdr = (struct ieee80211_hdr_4addr *) skb->data;
fc = le16_to_cpu(hdr->frame_ctl);
/* check that the frame is unicast frame to us */
@@ -619,13 +619,13 @@ static inline int
hostap_rx_frame_decrypt(local_info_t *local, struct sk_buff *skb,
struct ieee80211_crypt_data *crypt)
{
- struct ieee80211_hdr *hdr;
+ struct ieee80211_hdr_4addr *hdr;
int res, hdrlen;
if (crypt == NULL || crypt->ops->decrypt_mpdu == NULL)
return 0;
- hdr = (struct ieee80211_hdr *) skb->data;
+ hdr = (struct ieee80211_hdr_4addr *) skb->data;
hdrlen = hostap_80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl));
if (local->tkip_countermeasures &&
@@ -658,13 +658,13 @@ static inline int
hostap_rx_frame_decrypt_msdu(local_info_t *local, struct sk_buff *skb,
int keyidx, struct ieee80211_crypt_data *crypt)
{
- struct ieee80211_hdr *hdr;
+ struct ieee80211_hdr_4addr *hdr;
int res, hdrlen;
if (crypt == NULL || crypt->ops->decrypt_msdu == NULL)
return 0;
- hdr = (struct ieee80211_hdr *) skb->data;
+ hdr = (struct ieee80211_hdr_4addr *) skb->data;
hdrlen = hostap_80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl));
atomic_inc(&crypt->refcnt);
@@ -689,7 +689,7 @@ void hostap_80211_rx(struct net_device *dev, struct sk_buff *skb,
{
struct hostap_interface *iface;
local_info_t *local;
- struct ieee80211_hdr *hdr;
+ struct ieee80211_hdr_4addr *hdr;
size_t hdrlen;
u16 fc, type, stype, sc;
struct net_device *wds = NULL;
@@ -716,7 +716,7 @@ void hostap_80211_rx(struct net_device *dev, struct sk_buff *skb,
dev = local->ddev;
iface = netdev_priv(dev);
- hdr = (struct ieee80211_hdr *) skb->data;
+ hdr = (struct ieee80211_hdr_4addr *) skb->data;
stats = hostap_get_stats(dev);
if (skb->len < 10)
@@ -737,7 +737,8 @@ void hostap_80211_rx(struct net_device *dev, struct sk_buff *skb,
struct iw_quality wstats;
wstats.level = rx_stats->signal;
wstats.noise = rx_stats->noise;
- wstats.updated = 6; /* No qual value */
+ wstats.updated = IW_QUAL_LEVEL_UPDATED | IW_QUAL_NOISE_UPDATED
+ | IW_QUAL_QUAL_INVALID | IW_QUAL_DBM;
/* Update spy records */
wireless_spy_update(dev, hdr->addr2, &wstats);
}
@@ -889,7 +890,7 @@ void hostap_80211_rx(struct net_device *dev, struct sk_buff *skb,
if (local->host_decrypt && (fc & IEEE80211_FCTL_PROTECTED) &&
(keyidx = hostap_rx_frame_decrypt(local, skb, crypt)) < 0)
goto rx_dropped;
- hdr = (struct ieee80211_hdr *) skb->data;
+ hdr = (struct ieee80211_hdr_4addr *) skb->data;
/* skb: hdr + (possibly fragmented) plaintext payload */
@@ -941,7 +942,7 @@ void hostap_80211_rx(struct net_device *dev, struct sk_buff *skb,
/* this was the last fragment and the frame will be
* delivered, so remove skb from fragment cache */
skb = frag_skb;
- hdr = (struct ieee80211_hdr *) skb->data;
+ hdr = (struct ieee80211_hdr_4addr *) skb->data;
prism2_frag_cache_invalidate(local, hdr);
}
@@ -952,7 +953,7 @@ void hostap_80211_rx(struct net_device *dev, struct sk_buff *skb,
hostap_rx_frame_decrypt_msdu(local, skb, keyidx, crypt))
goto rx_dropped;
- hdr = (struct ieee80211_hdr *) skb->data;
+ hdr = (struct ieee80211_hdr_4addr *) skb->data;
if (crypt && !(fc & IEEE80211_FCTL_PROTECTED) && !local->open_wep) {
if (local->ieee_802_1x &&
hostap_is_eapol_frame(local, skb)) {
diff --git a/drivers/net/wireless/hostap/hostap_80211_tx.c b/drivers/net/wireless/hostap/hostap_80211_tx.c
index 6358015f6526..9d24f8a38ac5 100644
--- a/drivers/net/wireless/hostap/hostap_80211_tx.c
+++ b/drivers/net/wireless/hostap/hostap_80211_tx.c
@@ -1,9 +1,9 @@
void hostap_dump_tx_80211(const char *name, struct sk_buff *skb)
{
- struct ieee80211_hdr *hdr;
+ struct ieee80211_hdr_4addr *hdr;
u16 fc;
- hdr = (struct ieee80211_hdr *) skb->data;
+ hdr = (struct ieee80211_hdr_4addr *) skb->data;
printk(KERN_DEBUG "%s: TX len=%d jiffies=%ld\n",
name, skb->len, jiffies);
@@ -41,7 +41,7 @@ int hostap_data_start_xmit(struct sk_buff *skb, struct net_device *dev)
struct hostap_interface *iface;
local_info_t *local;
int need_headroom, need_tailroom = 0;
- struct ieee80211_hdr hdr;
+ struct ieee80211_hdr_4addr hdr;
u16 fc, ethertype = 0;
enum {
WDS_NO = 0, WDS_OWN_FRAME, WDS_COMPLIANT_FRAME
@@ -244,7 +244,7 @@ int hostap_mgmt_start_xmit(struct sk_buff *skb, struct net_device *dev)
struct hostap_interface *iface;
local_info_t *local;
struct hostap_skb_tx_data *meta;
- struct ieee80211_hdr *hdr;
+ struct ieee80211_hdr_4addr *hdr;
u16 fc;
iface = netdev_priv(dev);
@@ -266,7 +266,7 @@ int hostap_mgmt_start_xmit(struct sk_buff *skb, struct net_device *dev)
meta->iface = iface;
if (skb->len >= IEEE80211_DATA_HDR3_LEN + sizeof(rfc1042_header) + 2) {
- hdr = (struct ieee80211_hdr *) skb->data;
+ hdr = (struct ieee80211_hdr_4addr *) skb->data;
fc = le16_to_cpu(hdr->frame_ctl);
if (WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_DATA &&
WLAN_FC_GET_STYPE(fc) == IEEE80211_STYPE_DATA) {
@@ -289,7 +289,7 @@ struct sk_buff * hostap_tx_encrypt(struct sk_buff *skb,
{
struct hostap_interface *iface;
local_info_t *local;
- struct ieee80211_hdr *hdr;
+ struct ieee80211_hdr_4addr *hdr;
u16 fc;
int hdr_len, res;
@@ -303,7 +303,7 @@ struct sk_buff * hostap_tx_encrypt(struct sk_buff *skb,
if (local->tkip_countermeasures &&
crypt && crypt->ops && strcmp(crypt->ops->name, "TKIP") == 0) {
- hdr = (struct ieee80211_hdr *) skb->data;
+ hdr = (struct ieee80211_hdr_4addr *) skb->data;
if (net_ratelimit()) {
printk(KERN_DEBUG "%s: TKIP countermeasures: dropped "
"TX packet to " MACSTR "\n",
@@ -317,15 +317,15 @@ struct sk_buff * hostap_tx_encrypt(struct sk_buff *skb,
if (skb == NULL)
return NULL;
- if ((skb_headroom(skb) < crypt->ops->extra_prefix_len ||
- skb_tailroom(skb) < crypt->ops->extra_postfix_len) &&
- pskb_expand_head(skb, crypt->ops->extra_prefix_len,
- crypt->ops->extra_postfix_len, GFP_ATOMIC)) {
+ if ((skb_headroom(skb) < crypt->ops->extra_mpdu_prefix_len ||
+ skb_tailroom(skb) < crypt->ops->extra_mpdu_postfix_len) &&
+ pskb_expand_head(skb, crypt->ops->extra_mpdu_prefix_len,
+ crypt->ops->extra_mpdu_postfix_len, GFP_ATOMIC)) {
kfree_skb(skb);
return NULL;
}
- hdr = (struct ieee80211_hdr *) skb->data;
+ hdr = (struct ieee80211_hdr_4addr *) skb->data;
fc = le16_to_cpu(hdr->frame_ctl);
hdr_len = hostap_80211_get_hdrlen(fc);
@@ -360,7 +360,7 @@ int hostap_master_start_xmit(struct sk_buff *skb, struct net_device *dev)
ap_tx_ret tx_ret;
struct hostap_skb_tx_data *meta;
int no_encrypt = 0;
- struct ieee80211_hdr *hdr;
+ struct ieee80211_hdr_4addr *hdr;
iface = netdev_priv(dev);
local = iface->local;
@@ -403,7 +403,7 @@ int hostap_master_start_xmit(struct sk_buff *skb, struct net_device *dev)
tx_ret = hostap_handle_sta_tx(local, &tx);
skb = tx.skb;
meta = (struct hostap_skb_tx_data *) skb->cb;
- hdr = (struct ieee80211_hdr *) skb->data;
+ hdr = (struct ieee80211_hdr_4addr *) skb->data;
fc = le16_to_cpu(hdr->frame_ctl);
switch (tx_ret) {
case AP_TX_CONTINUE:
diff --git a/drivers/net/wireless/hostap/hostap_ap.c b/drivers/net/wireless/hostap/hostap_ap.c
index 930cef8367f2..9da94ab7f05f 100644
--- a/drivers/net/wireless/hostap/hostap_ap.c
+++ b/drivers/net/wireless/hostap/hostap_ap.c
@@ -591,14 +591,14 @@ static void hostap_ap_tx_cb(struct sk_buff *skb, int ok, void *data)
{
struct ap_data *ap = data;
u16 fc;
- struct ieee80211_hdr *hdr;
+ struct ieee80211_hdr_4addr *hdr;
if (!ap->local->hostapd || !ap->local->apdev) {
dev_kfree_skb(skb);
return;
}
- hdr = (struct ieee80211_hdr *) skb->data;
+ hdr = (struct ieee80211_hdr_4addr *) skb->data;
fc = le16_to_cpu(hdr->frame_ctl);
/* Pass the TX callback frame to the hostapd; use 802.11 header version
@@ -623,7 +623,7 @@ static void hostap_ap_tx_cb_auth(struct sk_buff *skb, int ok, void *data)
{
struct ap_data *ap = data;
struct net_device *dev = ap->local->dev;
- struct ieee80211_hdr *hdr;
+ struct ieee80211_hdr_4addr *hdr;
u16 fc, *pos, auth_alg, auth_transaction, status;
struct sta_info *sta = NULL;
char *txt = NULL;
@@ -633,7 +633,7 @@ static void hostap_ap_tx_cb_auth(struct sk_buff *skb, int ok, void *data)
return;
}
- hdr = (struct ieee80211_hdr *) skb->data;
+ hdr = (struct ieee80211_hdr_4addr *) skb->data;
fc = le16_to_cpu(hdr->frame_ctl);
if (WLAN_FC_GET_TYPE(fc) != IEEE80211_FTYPE_MGMT ||
WLAN_FC_GET_STYPE(fc) != IEEE80211_STYPE_AUTH ||
@@ -692,7 +692,7 @@ static void hostap_ap_tx_cb_assoc(struct sk_buff *skb, int ok, void *data)
{
struct ap_data *ap = data;
struct net_device *dev = ap->local->dev;
- struct ieee80211_hdr *hdr;
+ struct ieee80211_hdr_4addr *hdr;
u16 fc, *pos, status;
struct sta_info *sta = NULL;
char *txt = NULL;
@@ -702,7 +702,7 @@ static void hostap_ap_tx_cb_assoc(struct sk_buff *skb, int ok, void *data)
return;
}
- hdr = (struct ieee80211_hdr *) skb->data;
+ hdr = (struct ieee80211_hdr_4addr *) skb->data;
fc = le16_to_cpu(hdr->frame_ctl);
if (WLAN_FC_GET_TYPE(fc) != IEEE80211_FTYPE_MGMT ||
(WLAN_FC_GET_STYPE(fc) != IEEE80211_STYPE_ASSOC_RESP &&
@@ -757,12 +757,12 @@ static void hostap_ap_tx_cb_assoc(struct sk_buff *skb, int ok, void *data)
static void hostap_ap_tx_cb_poll(struct sk_buff *skb, int ok, void *data)
{
struct ap_data *ap = data;
- struct ieee80211_hdr *hdr;
+ struct ieee80211_hdr_4addr *hdr;
struct sta_info *sta;
if (skb->len < 24)
goto fail;
- hdr = (struct ieee80211_hdr *) skb->data;
+ hdr = (struct ieee80211_hdr_4addr *) skb->data;
if (ok) {
spin_lock(&ap->sta_table_lock);
sta = ap_get_sta(ap, hdr->addr1);
@@ -918,7 +918,7 @@ static void prism2_send_mgmt(struct net_device *dev,
{
struct hostap_interface *iface;
local_info_t *local;
- struct ieee80211_hdr *hdr;
+ struct ieee80211_hdr_4addr *hdr;
u16 fc;
struct sk_buff *skb;
struct hostap_skb_tx_data *meta;
@@ -944,7 +944,7 @@ static void prism2_send_mgmt(struct net_device *dev,
fc = type_subtype;
hdrlen = hostap_80211_get_hdrlen(fc);
- hdr = (struct ieee80211_hdr *) skb_put(skb, hdrlen);
+ hdr = (struct ieee80211_hdr_4addr *) skb_put(skb, hdrlen);
if (body)
memcpy(skb_put(skb, body_len), body, body_len);
@@ -1256,14 +1256,14 @@ static char * ap_auth_make_challenge(struct ap_data *ap)
}
skb = dev_alloc_skb(WLAN_AUTH_CHALLENGE_LEN +
- ap->crypt->extra_prefix_len +
- ap->crypt->extra_postfix_len);
+ ap->crypt->extra_mpdu_prefix_len +
+ ap->crypt->extra_mpdu_postfix_len);
if (skb == NULL) {
kfree(tmpbuf);
return NULL;
}
- skb_reserve(skb, ap->crypt->extra_prefix_len);
+ skb_reserve(skb, ap->crypt->extra_mpdu_prefix_len);
memset(skb_put(skb, WLAN_AUTH_CHALLENGE_LEN), 0,
WLAN_AUTH_CHALLENGE_LEN);
if (ap->crypt->encrypt_mpdu(skb, 0, ap->crypt_priv)) {
@@ -1272,7 +1272,7 @@ static char * ap_auth_make_challenge(struct ap_data *ap)
return NULL;
}
- memcpy(tmpbuf, skb->data + ap->crypt->extra_prefix_len,
+ memcpy(tmpbuf, skb->data + ap->crypt->extra_mpdu_prefix_len,
WLAN_AUTH_CHALLENGE_LEN);
dev_kfree_skb(skb);
@@ -1285,7 +1285,7 @@ static void handle_authen(local_info_t *local, struct sk_buff *skb,
struct hostap_80211_rx_status *rx_stats)
{
struct net_device *dev = local->dev;
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
+ struct ieee80211_hdr_4addr *hdr = (struct ieee80211_hdr_4addr *) skb->data;
size_t hdrlen;
struct ap_data *ap = local->ap;
char body[8 + WLAN_AUTH_CHALLENGE_LEN], *challenge = NULL;
@@ -1498,7 +1498,7 @@ static void handle_assoc(local_info_t *local, struct sk_buff *skb,
struct hostap_80211_rx_status *rx_stats, int reassoc)
{
struct net_device *dev = local->dev;
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
+ struct ieee80211_hdr_4addr *hdr = (struct ieee80211_hdr_4addr *) skb->data;
char body[12], *p, *lpos;
int len, left;
u16 *pos;
@@ -1705,7 +1705,7 @@ static void handle_deauth(local_info_t *local, struct sk_buff *skb,
struct hostap_80211_rx_status *rx_stats)
{
struct net_device *dev = local->dev;
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
+ struct ieee80211_hdr_4addr *hdr = (struct ieee80211_hdr_4addr *) skb->data;
char *body = (char *) (skb->data + IEEE80211_MGMT_HDR_LEN);
int len;
u16 reason_code, *pos;
@@ -1746,7 +1746,7 @@ static void handle_disassoc(local_info_t *local, struct sk_buff *skb,
struct hostap_80211_rx_status *rx_stats)
{
struct net_device *dev = local->dev;
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
+ struct ieee80211_hdr_4addr *hdr = (struct ieee80211_hdr_4addr *) skb->data;
char *body = skb->data + IEEE80211_MGMT_HDR_LEN;
int len;
u16 reason_code, *pos;
@@ -1784,7 +1784,7 @@ static void handle_disassoc(local_info_t *local, struct sk_buff *skb,
/* Called only as a scheduled task for pending AP frames. */
static void ap_handle_data_nullfunc(local_info_t *local,
- struct ieee80211_hdr *hdr)
+ struct ieee80211_hdr_4addr *hdr)
{
struct net_device *dev = local->dev;
@@ -1801,7 +1801,7 @@ static void ap_handle_data_nullfunc(local_info_t *local,
/* Called only as a scheduled task for pending AP frames. */
static void ap_handle_dropped_data(local_info_t *local,
- struct ieee80211_hdr *hdr)
+ struct ieee80211_hdr_4addr *hdr)
{
struct net_device *dev = local->dev;
struct sta_info *sta;
@@ -1860,7 +1860,7 @@ static void pspoll_send_buffered(local_info_t *local, struct sta_info *sta,
/* Called only as a scheduled task for pending AP frames. */
static void handle_pspoll(local_info_t *local,
- struct ieee80211_hdr *hdr,
+ struct ieee80211_hdr_4addr *hdr,
struct hostap_80211_rx_status *rx_stats)
{
struct net_device *dev = local->dev;
@@ -1979,7 +1979,7 @@ static void handle_wds_oper_queue(void *data)
static void handle_beacon(local_info_t *local, struct sk_buff *skb,
struct hostap_80211_rx_status *rx_stats)
{
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
+ struct ieee80211_hdr_4addr *hdr = (struct ieee80211_hdr_4addr *) skb->data;
char *body = skb->data + IEEE80211_MGMT_HDR_LEN;
int len, left;
u16 *pos, beacon_int, capability;
@@ -2137,11 +2137,11 @@ static void handle_ap_item(local_info_t *local, struct sk_buff *skb,
struct net_device *dev = local->dev;
#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
u16 fc, type, stype;
- struct ieee80211_hdr *hdr;
+ struct ieee80211_hdr_4addr *hdr;
/* FIX: should give skb->len to handler functions and check that the
* buffer is long enough */
- hdr = (struct ieee80211_hdr *) skb->data;
+ hdr = (struct ieee80211_hdr_4addr *) skb->data;
fc = le16_to_cpu(hdr->frame_ctl);
type = WLAN_FC_GET_TYPE(fc);
stype = WLAN_FC_GET_STYPE(fc);
@@ -2258,7 +2258,7 @@ void hostap_rx(struct net_device *dev, struct sk_buff *skb,
struct hostap_interface *iface;
local_info_t *local;
u16 fc;
- struct ieee80211_hdr *hdr;
+ struct ieee80211_hdr_4addr *hdr;
iface = netdev_priv(dev);
local = iface->local;
@@ -2268,7 +2268,7 @@ void hostap_rx(struct net_device *dev, struct sk_buff *skb,
local->stats.rx_packets++;
- hdr = (struct ieee80211_hdr *) skb->data;
+ hdr = (struct ieee80211_hdr_4addr *) skb->data;
fc = le16_to_cpu(hdr->frame_ctl);
if (local->ap->ap_policy == AP_OTHER_AP_SKIP_ALL &&
@@ -2289,7 +2289,7 @@ void hostap_rx(struct net_device *dev, struct sk_buff *skb,
static void schedule_packet_send(local_info_t *local, struct sta_info *sta)
{
struct sk_buff *skb;
- struct ieee80211_hdr *hdr;
+ struct ieee80211_hdr_4addr *hdr;
struct hostap_80211_rx_status rx_stats;
if (skb_queue_empty(&sta->tx_buf))
@@ -2302,7 +2302,7 @@ static void schedule_packet_send(local_info_t *local, struct sta_info *sta)
return;
}
- hdr = (struct ieee80211_hdr *) skb_put(skb, 16);
+ hdr = (struct ieee80211_hdr_4addr *) skb_put(skb, 16);
/* Generate a fake pspoll frame to start packet delivery */
hdr->frame_ctl = __constant_cpu_to_le16(
@@ -2349,7 +2349,7 @@ static int prism2_ap_get_sta_qual(local_info_t *local, struct sockaddr addr[],
qual[count].noise = HFA384X_LEVEL_TO_dBm(sta->last_rx_silence);
qual[count].updated = sta->last_rx_updated;
- sta->last_rx_updated = 0;
+ sta->last_rx_updated = IW_QUAL_DBM;
count++;
if (count >= buf_size)
@@ -2467,7 +2467,7 @@ static int prism2_ap_translate_scan(struct net_device *dev, char *buffer)
}
#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
- sta->last_rx_updated = 0;
+ sta->last_rx_updated = IW_QUAL_DBM;
/* To be continued, we should make good use of IWEVCUSTOM */
}
@@ -2685,7 +2685,7 @@ ap_tx_ret hostap_handle_sta_tx(local_info_t *local, struct hostap_tx_data *tx)
struct sta_info *sta = NULL;
struct sk_buff *skb = tx->skb;
int set_tim, ret;
- struct ieee80211_hdr *hdr;
+ struct ieee80211_hdr_4addr *hdr;
struct hostap_skb_tx_data *meta;
meta = (struct hostap_skb_tx_data *) skb->cb;
@@ -2694,7 +2694,7 @@ ap_tx_ret hostap_handle_sta_tx(local_info_t *local, struct hostap_tx_data *tx)
meta->iface->type == HOSTAP_INTERFACE_STA)
goto out;
- hdr = (struct ieee80211_hdr *) skb->data;
+ hdr = (struct ieee80211_hdr_4addr *) skb->data;
if (hdr->addr1[0] & 0x01) {
/* broadcast/multicast frame - no AP related processing */
@@ -2821,10 +2821,10 @@ void hostap_handle_sta_release(void *ptr)
void hostap_handle_sta_tx_exc(local_info_t *local, struct sk_buff *skb)
{
struct sta_info *sta;
- struct ieee80211_hdr *hdr;
+ struct ieee80211_hdr_4addr *hdr;
struct hostap_skb_tx_data *meta;
- hdr = (struct ieee80211_hdr *) skb->data;
+ hdr = (struct ieee80211_hdr_4addr *) skb->data;
meta = (struct hostap_skb_tx_data *) skb->cb;
spin_lock(&local->ap->sta_table_lock);
@@ -2892,7 +2892,7 @@ static void hostap_update_sta_ps2(local_info_t *local, struct sta_info *sta,
/* Called only as a tasklet (software IRQ). Called for each RX frame to update
* STA power saving state. pwrmgt is a flag from 802.11 frame_ctl field. */
-int hostap_update_sta_ps(local_info_t *local, struct ieee80211_hdr *hdr)
+int hostap_update_sta_ps(local_info_t *local, struct ieee80211_hdr_4addr *hdr)
{
struct sta_info *sta;
u16 fc;
@@ -2925,12 +2925,12 @@ ap_rx_ret hostap_handle_sta_rx(local_info_t *local, struct net_device *dev,
int ret;
struct sta_info *sta;
u16 fc, type, stype;
- struct ieee80211_hdr *hdr;
+ struct ieee80211_hdr_4addr *hdr;
if (local->ap == NULL)
return AP_RX_CONTINUE;
- hdr = (struct ieee80211_hdr *) skb->data;
+ hdr = (struct ieee80211_hdr_4addr *) skb->data;
fc = le16_to_cpu(hdr->frame_ctl);
type = WLAN_FC_GET_TYPE(fc);
@@ -3058,7 +3058,7 @@ ap_rx_ret hostap_handle_sta_rx(local_info_t *local, struct net_device *dev,
/* Called only as a tasklet (software IRQ) */
int hostap_handle_sta_crypto(local_info_t *local,
- struct ieee80211_hdr *hdr,
+ struct ieee80211_hdr_4addr *hdr,
struct ieee80211_crypt_data **crypt,
void **sta_ptr)
{
@@ -3160,7 +3160,7 @@ int hostap_add_sta(struct ap_data *ap, u8 *sta_addr)
/* Called only as a tasklet (software IRQ) */
int hostap_update_rx_stats(struct ap_data *ap,
- struct ieee80211_hdr *hdr,
+ struct ieee80211_hdr_4addr *hdr,
struct hostap_80211_rx_status *rx_stats)
{
struct sta_info *sta;
@@ -3174,7 +3174,7 @@ int hostap_update_rx_stats(struct ap_data *ap,
sta->last_rx_silence = rx_stats->noise;
sta->last_rx_signal = rx_stats->signal;
sta->last_rx_rate = rx_stats->rate;
- sta->last_rx_updated = 7;
+ sta->last_rx_updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
if (rx_stats->rate == 10)
sta->rx_count[0]++;
else if (rx_stats->rate == 20)
diff --git a/drivers/net/wireless/hostap/hostap_ap.h b/drivers/net/wireless/hostap/hostap_ap.h
index 816a52bcea8f..6d00df69c2e3 100644
--- a/drivers/net/wireless/hostap/hostap_ap.h
+++ b/drivers/net/wireless/hostap/hostap_ap.h
@@ -233,7 +233,7 @@ struct hostap_tx_data {
ap_tx_ret hostap_handle_sta_tx(local_info_t *local, struct hostap_tx_data *tx);
void hostap_handle_sta_release(void *ptr);
void hostap_handle_sta_tx_exc(local_info_t *local, struct sk_buff *skb);
-int hostap_update_sta_ps(local_info_t *local, struct ieee80211_hdr *hdr);
+int hostap_update_sta_ps(local_info_t *local, struct ieee80211_hdr_4addr *hdr);
typedef enum {
AP_RX_CONTINUE, AP_RX_DROP, AP_RX_EXIT, AP_RX_CONTINUE_NOT_AUTHORIZED
} ap_rx_ret;
@@ -241,13 +241,13 @@ ap_rx_ret hostap_handle_sta_rx(local_info_t *local, struct net_device *dev,
struct sk_buff *skb,
struct hostap_80211_rx_status *rx_stats,
int wds);
-int hostap_handle_sta_crypto(local_info_t *local, struct ieee80211_hdr *hdr,
+int hostap_handle_sta_crypto(local_info_t *local, struct ieee80211_hdr_4addr *hdr,
struct ieee80211_crypt_data **crypt,
void **sta_ptr);
int hostap_is_sta_assoc(struct ap_data *ap, u8 *sta_addr);
int hostap_is_sta_authorized(struct ap_data *ap, u8 *sta_addr);
int hostap_add_sta(struct ap_data *ap, u8 *sta_addr);
-int hostap_update_rx_stats(struct ap_data *ap, struct ieee80211_hdr *hdr,
+int hostap_update_rx_stats(struct ap_data *ap, struct ieee80211_hdr_4addr *hdr,
struct hostap_80211_rx_status *rx_stats);
void hostap_update_rates(local_info_t *local);
void hostap_add_wds_links(local_info_t *local);
diff --git a/drivers/net/wireless/hostap/hostap_cs.c b/drivers/net/wireless/hostap/hostap_cs.c
index faa83badf0a1..2643976a6677 100644
--- a/drivers/net/wireless/hostap/hostap_cs.c
+++ b/drivers/net/wireless/hostap/hostap_cs.c
@@ -492,42 +492,10 @@ static void prism2_pccard_genesis_reset(local_info_t *local, int hcr)
}
-static int prism2_pccard_dev_open(local_info_t *local)
-{
- struct hostap_cs_priv *hw_priv = local->hw_priv;
- hw_priv->link->open++;
- return 0;
-}
-
-
-static int prism2_pccard_dev_close(local_info_t *local)
-{
- struct hostap_cs_priv *hw_priv;
-
- if (local == NULL || local->hw_priv == NULL)
- return 1;
- hw_priv = local->hw_priv;
- if (hw_priv->link == NULL)
- return 1;
-
- if (!hw_priv->link->open) {
- printk(KERN_WARNING "%s: prism2_pccard_dev_close(): "
- "link not open?!\n", local->dev->name);
- return 1;
- }
-
- hw_priv->link->open--;
-
- return 0;
-}
-
-
static struct prism2_helper_functions prism2_pccard_funcs =
{
.card_present = prism2_pccard_card_present,
.cor_sreset = prism2_pccard_cor_sreset,
- .dev_open = prism2_pccard_dev_open,
- .dev_close = prism2_pccard_dev_close,
.genesis_reset = prism2_pccard_genesis_reset,
.hw_type = HOSTAP_HW_PCCARD,
};
@@ -597,13 +565,14 @@ static void prism2_detach(dev_link_t *link)
*linkp = link->next;
/* release net devices */
if (link->priv) {
+ struct hostap_cs_priv *hw_priv;
struct net_device *dev;
struct hostap_interface *iface;
dev = link->priv;
iface = netdev_priv(dev);
- kfree(iface->local->hw_priv);
- iface->local->hw_priv = NULL;
+ hw_priv = iface->local->hw_priv;
prism2_free_local_data(dev);
+ kfree(hw_priv);
}
kfree(link);
}
@@ -883,6 +852,13 @@ static int prism2_event(event_t event, int priority,
{
dev_link_t *link = args->client_data;
struct net_device *dev = (struct net_device *) link->priv;
+ int dev_open = 0;
+
+ if (link->state & DEV_CONFIG) {
+ struct hostap_interface *iface = netdev_priv(dev);
+ if (iface && iface->local)
+ dev_open = iface->local->num_dev_open > 0;
+ }
switch (event) {
case CS_EVENT_CARD_INSERTION:
@@ -911,7 +887,7 @@ static int prism2_event(event_t event, int priority,
case CS_EVENT_RESET_PHYSICAL:
PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_RESET_PHYSICAL\n", dev_info);
if (link->state & DEV_CONFIG) {
- if (link->open) {
+ if (dev_open) {
netif_stop_queue(dev);
netif_device_detach(dev);
}
@@ -931,8 +907,8 @@ static int prism2_event(event_t event, int priority,
pcmcia_request_configuration(link->handle,
&link->conf);
prism2_hw_shutdown(dev, 1);
- prism2_hw_config(dev, link->open ? 0 : 1);
- if (link->open) {
+ prism2_hw_config(dev, dev_open ? 0 : 1);
+ if (dev_open) {
netif_device_attach(dev);
netif_start_queue(dev);
}
diff --git a/drivers/net/wireless/hostap/hostap_hw.c b/drivers/net/wireless/hostap/hostap_hw.c
index e533a663deda..abfae7fedebc 100644
--- a/drivers/net/wireless/hostap/hostap_hw.c
+++ b/drivers/net/wireless/hostap/hostap_hw.c
@@ -31,7 +31,6 @@
#include <linux/config.h>
-#include <linux/version.h>
#include <asm/delay.h>
#include <asm/uaccess.h>
@@ -3322,6 +3321,18 @@ static void prism2_free_local_data(struct net_device *dev)
iface = netdev_priv(dev);
local = iface->local;
+ /* Unregister all netdevs before freeing local data. */
+ list_for_each_safe(ptr, n, &local->hostap_interfaces) {
+ iface = list_entry(ptr, struct hostap_interface, list);
+ if (iface->type == HOSTAP_INTERFACE_MASTER) {
+ /* special handling for this interface below */
+ continue;
+ }
+ hostap_remove_interface(iface->dev, 0, 1);
+ }
+
+ unregister_netdev(local->dev);
+
flush_scheduled_work();
if (timer_pending(&local->crypt_deinit_timer))
@@ -3382,15 +3393,6 @@ static void prism2_free_local_data(struct net_device *dev)
prism2_download_free_data(local->dl_sec);
#endif /* PRISM2_DOWNLOAD_SUPPORT */
- list_for_each_safe(ptr, n, &local->hostap_interfaces) {
- iface = list_entry(ptr, struct hostap_interface, list);
- if (iface->type == HOSTAP_INTERFACE_MASTER) {
- /* special handling for this interface below */
- continue;
- }
- hostap_remove_interface(iface->dev, 0, 1);
- }
-
prism2_clear_set_tim_queue(local);
list_for_each_safe(ptr, n, &local->bss_list) {
@@ -3403,7 +3405,6 @@ static void prism2_free_local_data(struct net_device *dev)
kfree(local->last_scan_results);
kfree(local->generic_elem);
- unregister_netdev(local->dev);
free_netdev(local->dev);
}
diff --git a/drivers/net/wireless/hostap/hostap_ioctl.c b/drivers/net/wireless/hostap/hostap_ioctl.c
index e720369a3515..2617d70bcda9 100644
--- a/drivers/net/wireless/hostap/hostap_ioctl.c
+++ b/drivers/net/wireless/hostap/hostap_ioctl.c
@@ -50,7 +50,8 @@ static struct iw_statistics *hostap_get_wireless_stats(struct net_device *dev)
#endif /* in_atomic */
if (update && prism2_update_comms_qual(dev) == 0)
- wstats->qual.updated = 7;
+ wstats->qual.updated = IW_QUAL_ALL_UPDATED |
+ IW_QUAL_DBM;
wstats->qual.qual = local->comms_qual;
wstats->qual.level = local->avg_signal;
@@ -59,7 +60,7 @@ static struct iw_statistics *hostap_get_wireless_stats(struct net_device *dev)
wstats->qual.qual = 0;
wstats->qual.level = 0;
wstats->qual.noise = 0;
- wstats->qual.updated = 0;
+ wstats->qual.updated = IW_QUAL_ALL_INVALID;
}
return wstats;
@@ -551,7 +552,6 @@ static int prism2_ioctl_giwaplist(struct net_device *dev,
kfree(addr);
kfree(qual);
-
return 0;
}
@@ -1827,13 +1827,6 @@ static char * __prism2_translate_scan(local_info_t *local,
iwe.cmd = SIOCGIWAP;
iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
memcpy(iwe.u.ap_addr.sa_data, bssid, ETH_ALEN);
- /* FIX:
- * I do not know how this is possible, but iwe_stream_add_event
- * seems to re-order memcpy execution so that len is set only
- * after copying.. Pre-setting len here "fixes" this, but real
- * problems should be solved (after which these iwe.len
- * settings could be removed from this function). */
- iwe.len = IW_EV_ADDR_LEN;
current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
IW_EV_ADDR_LEN);
@@ -1843,7 +1836,6 @@ static char * __prism2_translate_scan(local_info_t *local,
iwe.cmd = SIOCGIWESSID;
iwe.u.data.length = ssid_len;
iwe.u.data.flags = 1;
- iwe.len = IW_EV_POINT_LEN + iwe.u.data.length;
current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, ssid);
memset(&iwe, 0, sizeof(iwe));
@@ -1859,7 +1851,6 @@ static char * __prism2_translate_scan(local_info_t *local,
iwe.u.mode = IW_MODE_MASTER;
else
iwe.u.mode = IW_MODE_ADHOC;
- iwe.len = IW_EV_UINT_LEN;
current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
IW_EV_UINT_LEN);
}
@@ -1877,7 +1868,6 @@ static char * __prism2_translate_scan(local_info_t *local,
if (chan > 0) {
iwe.u.freq.m = freq_list[le16_to_cpu(chan - 1)] * 100000;
iwe.u.freq.e = 1;
- iwe.len = IW_EV_FREQ_LEN;
current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
IW_EV_FREQ_LEN);
}
@@ -1894,7 +1884,10 @@ static char * __prism2_translate_scan(local_info_t *local,
iwe.u.qual.noise =
HFA384X_LEVEL_TO_dBm(le16_to_cpu(scan->anl));
}
- iwe.len = IW_EV_QUAL_LEN;
+ iwe.u.qual.updated = IW_QUAL_LEVEL_UPDATED
+ | IW_QUAL_NOISE_UPDATED
+ | IW_QUAL_QUAL_INVALID
+ | IW_QUAL_DBM;
current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
IW_EV_QUAL_LEN);
}
@@ -1906,7 +1899,6 @@ static char * __prism2_translate_scan(local_info_t *local,
else
iwe.u.data.flags = IW_ENCODE_DISABLED;
iwe.u.data.length = 0;
- iwe.len = IW_EV_POINT_LEN + iwe.u.data.length;
current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, "");
/* TODO: add SuppRates into BSS table */
@@ -1930,7 +1922,7 @@ static char * __prism2_translate_scan(local_info_t *local,
}
/* TODO: add BeaconInt,resp_rate,atim into BSS table */
- buf = kmalloc(MAX_WPA_IE_LEN * 2 + 30, GFP_KERNEL);
+ buf = kmalloc(MAX_WPA_IE_LEN * 2 + 30, GFP_ATOMIC);
if (buf && scan) {
memset(&iwe, 0, sizeof(iwe));
iwe.cmd = IWEVCUSTOM;
@@ -3088,9 +3080,7 @@ static int prism2_ioctl_priv_download(local_info_t *local, struct iw_point *p)
ret = local->func->download(local, param);
out:
- if (param != NULL)
- kfree(param);
-
+ kfree(param);
return ret;
}
#endif /* PRISM2_DOWNLOAD_SUPPORT */
@@ -3897,9 +3887,7 @@ static int prism2_ioctl_priv_hostapd(local_info_t *local, struct iw_point *p)
}
out:
- if (param != NULL)
- kfree(param);
-
+ kfree(param);
return ret;
}
diff --git a/drivers/net/wireless/hostap/hostap_pci.c b/drivers/net/wireless/hostap/hostap_pci.c
index 025f8cdb5566..2e85bdced2dd 100644
--- a/drivers/net/wireless/hostap/hostap_pci.c
+++ b/drivers/net/wireless/hostap/hostap_pci.c
@@ -5,7 +5,6 @@
* Andy Warner <andyw@pobox.com> */
#include <linux/config.h>
-#include <linux/version.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/if.h>
@@ -59,11 +58,13 @@ static struct pci_device_id prism2_pci_id_table[] __devinitdata = {
static inline void hfa384x_outb_debug(struct net_device *dev, int a, u8 v)
{
struct hostap_interface *iface;
+ struct hostap_pci_priv *hw_priv;
local_info_t *local;
unsigned long flags;
iface = netdev_priv(dev);
local = iface->local;
+ hw_priv = local->hw_priv;
spin_lock_irqsave(&local->lock, flags);
prism2_io_debug_add(dev, PRISM2_IO_DEBUG_CMD_OUTB, a, v);
@@ -74,12 +75,14 @@ static inline void hfa384x_outb_debug(struct net_device *dev, int a, u8 v)
static inline u8 hfa384x_inb_debug(struct net_device *dev, int a)
{
struct hostap_interface *iface;
+ struct hostap_pci_priv *hw_priv;
local_info_t *local;
unsigned long flags;
u8 v;
iface = netdev_priv(dev);
local = iface->local;
+ hw_priv = local->hw_priv;
spin_lock_irqsave(&local->lock, flags);
v = readb(hw_priv->mem_start + a);
@@ -91,11 +94,13 @@ static inline u8 hfa384x_inb_debug(struct net_device *dev, int a)
static inline void hfa384x_outw_debug(struct net_device *dev, int a, u16 v)
{
struct hostap_interface *iface;
+ struct hostap_pci_priv *hw_priv;
local_info_t *local;
unsigned long flags;
iface = netdev_priv(dev);
local = iface->local;
+ hw_priv = local->hw_priv;
spin_lock_irqsave(&local->lock, flags);
prism2_io_debug_add(dev, PRISM2_IO_DEBUG_CMD_OUTW, a, v);
@@ -106,12 +111,14 @@ static inline void hfa384x_outw_debug(struct net_device *dev, int a, u16 v)
static inline u16 hfa384x_inw_debug(struct net_device *dev, int a)
{
struct hostap_interface *iface;
+ struct hostap_pci_priv *hw_priv;
local_info_t *local;
unsigned long flags;
u16 v;
iface = netdev_priv(dev);
local = iface->local;
+ hw_priv = local->hw_priv;
spin_lock_irqsave(&local->lock, flags);
v = readw(hw_priv->mem_start + a);
@@ -277,8 +284,6 @@ static struct prism2_helper_functions prism2_pci_funcs =
{
.card_present = NULL,
.cor_sreset = prism2_pci_cor_sreset,
- .dev_open = NULL,
- .dev_close = NULL,
.genesis_reset = prism2_pci_genesis_reset,
.hw_type = HOSTAP_HW_PCI,
};
@@ -352,8 +357,6 @@ static int prism2_pci_probe(struct pci_dev *pdev,
return hostap_hw_ready(dev);
fail:
- kfree(hw_priv);
-
if (irq_registered && dev)
free_irq(dev->irq, dev);
@@ -364,10 +367,8 @@ static int prism2_pci_probe(struct pci_dev *pdev,
err_out_disable:
pci_disable_device(pdev);
- kfree(hw_priv);
- if (local)
- local->hw_priv = NULL;
prism2_free_local_data(dev);
+ kfree(hw_priv);
return -ENODEV;
}
@@ -392,9 +393,8 @@ static void prism2_pci_remove(struct pci_dev *pdev)
free_irq(dev->irq, dev);
mem_start = hw_priv->mem_start;
- kfree(hw_priv);
- iface->local->hw_priv = NULL;
prism2_free_local_data(dev);
+ kfree(hw_priv);
iounmap(mem_start);
@@ -441,7 +441,7 @@ static int prism2_pci_resume(struct pci_dev *pdev)
MODULE_DEVICE_TABLE(pci, prism2_pci_id_table);
static struct pci_driver prism2_pci_drv_id = {
- .name = "prism2_pci",
+ .name = "hostap_pci",
.id_table = prism2_pci_id_table,
.probe = prism2_pci_probe,
.remove = prism2_pci_remove,
diff --git a/drivers/net/wireless/hostap/hostap_plx.c b/drivers/net/wireless/hostap/hostap_plx.c
index 474ef83d813e..94fe2449f099 100644
--- a/drivers/net/wireless/hostap/hostap_plx.c
+++ b/drivers/net/wireless/hostap/hostap_plx.c
@@ -8,7 +8,6 @@
#include <linux/config.h>
-#include <linux/version.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/if.h>
@@ -328,8 +327,6 @@ static struct prism2_helper_functions prism2_plx_funcs =
{
.card_present = NULL,
.cor_sreset = prism2_plx_cor_sreset,
- .dev_open = NULL,
- .dev_close = NULL,
.genesis_reset = prism2_plx_genesis_reset,
.hw_type = HOSTAP_HW_PLX,
};
@@ -570,10 +567,8 @@ static int prism2_plx_probe(struct pci_dev *pdev,
return hostap_hw_ready(dev);
fail:
- kfree(hw_priv);
- if (local)
- local->hw_priv = NULL;
prism2_free_local_data(dev);
+ kfree(hw_priv);
if (irq_registered && dev)
free_irq(dev->irq, dev);
@@ -606,9 +601,8 @@ static void prism2_plx_remove(struct pci_dev *pdev)
if (dev->irq)
free_irq(dev->irq, dev);
- kfree(iface->local->hw_priv);
- iface->local->hw_priv = NULL;
prism2_free_local_data(dev);
+ kfree(hw_priv);
pci_disable_device(pdev);
}
@@ -616,7 +610,7 @@ static void prism2_plx_remove(struct pci_dev *pdev)
MODULE_DEVICE_TABLE(pci, prism2_plx_id_table);
static struct pci_driver prism2_plx_drv_id = {
- .name = "prism2_plx",
+ .name = "hostap_plx",
.id_table = prism2_plx_id_table,
.probe = prism2_plx_probe,
.remove = prism2_plx_remove,
diff --git a/drivers/net/wireless/hostap/hostap_wlan.h b/drivers/net/wireless/hostap/hostap_wlan.h
index cc061e1560d3..cfd801559492 100644
--- a/drivers/net/wireless/hostap/hostap_wlan.h
+++ b/drivers/net/wireless/hostap/hostap_wlan.h
@@ -552,8 +552,6 @@ struct prism2_helper_functions {
* (hostap_{cs,plx,pci}.c */
int (*card_present)(local_info_t *local);
void (*cor_sreset)(local_info_t *local);
- int (*dev_open)(local_info_t *local);
- int (*dev_close)(local_info_t *local);
void (*genesis_reset)(local_info_t *local, int hcr);
/* the following functions are from hostap_hw.c, but they may have some
diff --git a/drivers/net/wireless/ipw2100.c b/drivers/net/wireless/ipw2100.c
index 2414e6493aa5..a2e6214169e9 100644
--- a/drivers/net/wireless/ipw2100.c
+++ b/drivers/net/wireless/ipw2100.c
@@ -167,17 +167,16 @@ that only one external action is invoked at a time.
#include "ipw2100.h"
-#define IPW2100_VERSION "1.1.0"
+#define IPW2100_VERSION "1.1.3"
#define DRV_NAME "ipw2100"
#define DRV_VERSION IPW2100_VERSION
#define DRV_DESCRIPTION "Intel(R) PRO/Wireless 2100 Network Driver"
-#define DRV_COPYRIGHT "Copyright(c) 2003-2004 Intel Corporation"
-
+#define DRV_COPYRIGHT "Copyright(c) 2003-2005 Intel Corporation"
/* Debugging stuff */
#ifdef CONFIG_IPW_DEBUG
-#define CONFIG_IPW2100_RX_DEBUG /* Reception debugging */
+#define CONFIG_IPW2100_RX_DEBUG /* Reception debugging */
#endif
MODULE_DESCRIPTION(DRV_DESCRIPTION);
@@ -220,18 +219,18 @@ do { \
} while (0)
#else
#define IPW_DEBUG(level, message...) do {} while (0)
-#endif /* CONFIG_IPW_DEBUG */
+#endif /* CONFIG_IPW_DEBUG */
#ifdef CONFIG_IPW_DEBUG
static const char *command_types[] = {
"undefined",
- "unused", /* HOST_ATTENTION */
+ "unused", /* HOST_ATTENTION */
"HOST_COMPLETE",
- "unused", /* SLEEP */
- "unused", /* HOST_POWER_DOWN */
+ "unused", /* SLEEP */
+ "unused", /* HOST_POWER_DOWN */
"unused",
"SYSTEM_CONFIG",
- "unused", /* SET_IMR */
+ "unused", /* SET_IMR */
"SSID",
"MANDATORY_BSSID",
"AUTHENTICATION_TYPE",
@@ -277,17 +276,16 @@ static const char *command_types[] = {
"GROUP_ORDINALS",
"SHORT_RETRY_LIMIT",
"LONG_RETRY_LIMIT",
- "unused", /* SAVE_CALIBRATION */
- "unused", /* RESTORE_CALIBRATION */
+ "unused", /* SAVE_CALIBRATION */
+ "unused", /* RESTORE_CALIBRATION */
"undefined",
"undefined",
"undefined",
"HOST_PRE_POWER_DOWN",
- "unused", /* HOST_INTERRUPT_COALESCING */
+ "unused", /* HOST_INTERRUPT_COALESCING */
"undefined",
"CARD_DISABLE_PHY_OFF",
- "MSDU_TX_RATES"
- "undefined",
+ "MSDU_TX_RATES" "undefined",
"undefined",
"SET_STATION_STAT_BITS",
"CLEAR_STATIONS_STAT_BITS",
@@ -298,7 +296,6 @@ static const char *command_types[] = {
};
#endif
-
/* Pre-decl until we get the code solid and then we can clean it up */
static void ipw2100_tx_send_commands(struct ipw2100_priv *priv);
static void ipw2100_tx_send_data(struct ipw2100_priv *priv);
@@ -321,11 +318,10 @@ static void ipw2100_release_firmware(struct ipw2100_priv *priv,
static int ipw2100_ucode_download(struct ipw2100_priv *priv,
struct ipw2100_fw *fw);
static void ipw2100_wx_event_work(struct ipw2100_priv *priv);
-static struct iw_statistics *ipw2100_wx_wireless_stats(struct net_device * dev);
+static struct iw_statistics *ipw2100_wx_wireless_stats(struct net_device *dev);
static struct iw_handler_def ipw2100_wx_handler_def;
-
-static inline void read_register(struct net_device *dev, u32 reg, u32 *val)
+static inline void read_register(struct net_device *dev, u32 reg, u32 * val)
{
*val = readl((void __iomem *)(dev->base_addr + reg));
IPW_DEBUG_IO("r: 0x%08X => 0x%08X\n", reg, *val);
@@ -337,13 +333,14 @@ static inline void write_register(struct net_device *dev, u32 reg, u32 val)
IPW_DEBUG_IO("w: 0x%08X <= 0x%08X\n", reg, val);
}
-static inline void read_register_word(struct net_device *dev, u32 reg, u16 *val)
+static inline void read_register_word(struct net_device *dev, u32 reg,
+ u16 * val)
{
*val = readw((void __iomem *)(dev->base_addr + reg));
IPW_DEBUG_IO("r: 0x%08X => %04X\n", reg, *val);
}
-static inline void read_register_byte(struct net_device *dev, u32 reg, u8 *val)
+static inline void read_register_byte(struct net_device *dev, u32 reg, u8 * val)
{
*val = readb((void __iomem *)(dev->base_addr + reg));
IPW_DEBUG_IO("r: 0x%08X => %02X\n", reg, *val);
@@ -355,14 +352,13 @@ static inline void write_register_word(struct net_device *dev, u32 reg, u16 val)
IPW_DEBUG_IO("w: 0x%08X <= %04X\n", reg, val);
}
-
static inline void write_register_byte(struct net_device *dev, u32 reg, u8 val)
{
writeb(val, (void __iomem *)(dev->base_addr + reg));
IPW_DEBUG_IO("w: 0x%08X =< %02X\n", reg, val);
}
-static inline void read_nic_dword(struct net_device *dev, u32 addr, u32 *val)
+static inline void read_nic_dword(struct net_device *dev, u32 addr, u32 * val)
{
write_register(dev, IPW_REG_INDIRECT_ACCESS_ADDRESS,
addr & IPW_REG_INDIRECT_ADDR_MASK);
@@ -376,7 +372,7 @@ static inline void write_nic_dword(struct net_device *dev, u32 addr, u32 val)
write_register(dev, IPW_REG_INDIRECT_ACCESS_DATA, val);
}
-static inline void read_nic_word(struct net_device *dev, u32 addr, u16 *val)
+static inline void read_nic_word(struct net_device *dev, u32 addr, u16 * val)
{
write_register(dev, IPW_REG_INDIRECT_ACCESS_ADDRESS,
addr & IPW_REG_INDIRECT_ADDR_MASK);
@@ -390,7 +386,7 @@ static inline void write_nic_word(struct net_device *dev, u32 addr, u16 val)
write_register_word(dev, IPW_REG_INDIRECT_ACCESS_DATA, val);
}
-static inline void read_nic_byte(struct net_device *dev, u32 addr, u8 *val)
+static inline void read_nic_byte(struct net_device *dev, u32 addr, u8 * val)
{
write_register(dev, IPW_REG_INDIRECT_ACCESS_ADDRESS,
addr & IPW_REG_INDIRECT_ADDR_MASK);
@@ -416,7 +412,7 @@ static inline void write_nic_dword_auto_inc(struct net_device *dev, u32 val)
}
static inline void write_nic_memory(struct net_device *dev, u32 addr, u32 len,
- const u8 *buf)
+ const u8 * buf)
{
u32 aligned_addr;
u32 aligned_len;
@@ -431,32 +427,30 @@ static inline void write_nic_memory(struct net_device *dev, u32 addr, u32 len,
write_register(dev, IPW_REG_INDIRECT_ACCESS_ADDRESS,
aligned_addr);
for (i = dif_len; i < 4; i++, buf++)
- write_register_byte(
- dev, IPW_REG_INDIRECT_ACCESS_DATA + i,
- *buf);
+ write_register_byte(dev,
+ IPW_REG_INDIRECT_ACCESS_DATA + i,
+ *buf);
len -= dif_len;
aligned_addr += 4;
}
/* read DWs through autoincrement registers */
- write_register(dev, IPW_REG_AUTOINCREMENT_ADDRESS,
- aligned_addr);
+ write_register(dev, IPW_REG_AUTOINCREMENT_ADDRESS, aligned_addr);
aligned_len = len & (~0x3);
for (i = 0; i < aligned_len; i += 4, buf += 4, aligned_addr += 4)
- write_register(
- dev, IPW_REG_AUTOINCREMENT_DATA, *(u32 *)buf);
+ write_register(dev, IPW_REG_AUTOINCREMENT_DATA, *(u32 *) buf);
/* copy the last nibble */
dif_len = len - aligned_len;
write_register(dev, IPW_REG_INDIRECT_ACCESS_ADDRESS, aligned_addr);
for (i = 0; i < dif_len; i++, buf++)
- write_register_byte(
- dev, IPW_REG_INDIRECT_ACCESS_DATA + i, *buf);
+ write_register_byte(dev, IPW_REG_INDIRECT_ACCESS_DATA + i,
+ *buf);
}
static inline void read_nic_memory(struct net_device *dev, u32 addr, u32 len,
- u8 *buf)
+ u8 * buf)
{
u32 aligned_addr;
u32 aligned_len;
@@ -471,39 +465,38 @@ static inline void read_nic_memory(struct net_device *dev, u32 addr, u32 len,
write_register(dev, IPW_REG_INDIRECT_ACCESS_ADDRESS,
aligned_addr);
for (i = dif_len; i < 4; i++, buf++)
- read_register_byte(
- dev, IPW_REG_INDIRECT_ACCESS_DATA + i, buf);
+ read_register_byte(dev,
+ IPW_REG_INDIRECT_ACCESS_DATA + i,
+ buf);
len -= dif_len;
aligned_addr += 4;
}
/* read DWs through autoincrement registers */
- write_register(dev, IPW_REG_AUTOINCREMENT_ADDRESS,
- aligned_addr);
+ write_register(dev, IPW_REG_AUTOINCREMENT_ADDRESS, aligned_addr);
aligned_len = len & (~0x3);
for (i = 0; i < aligned_len; i += 4, buf += 4, aligned_addr += 4)
- read_register(dev, IPW_REG_AUTOINCREMENT_DATA,
- (u32 *)buf);
+ read_register(dev, IPW_REG_AUTOINCREMENT_DATA, (u32 *) buf);
/* copy the last nibble */
dif_len = len - aligned_len;
- write_register(dev, IPW_REG_INDIRECT_ACCESS_ADDRESS,
- aligned_addr);
+ write_register(dev, IPW_REG_INDIRECT_ACCESS_ADDRESS, aligned_addr);
for (i = 0; i < dif_len; i++, buf++)
- read_register_byte(dev, IPW_REG_INDIRECT_ACCESS_DATA +
- i, buf);
+ read_register_byte(dev, IPW_REG_INDIRECT_ACCESS_DATA + i, buf);
}
static inline int ipw2100_hw_is_adapter_in_system(struct net_device *dev)
{
return (dev->base_addr &&
- (readl((void __iomem *)(dev->base_addr + IPW_REG_DOA_DEBUG_AREA_START))
+ (readl
+ ((void __iomem *)(dev->base_addr +
+ IPW_REG_DOA_DEBUG_AREA_START))
== IPW_DATA_DOA_DEBUG_VALUE));
}
static int ipw2100_get_ordinal(struct ipw2100_priv *priv, u32 ord,
- void *val, u32 *len)
+ void *val, u32 * len)
{
struct ipw2100_ordinals *ordinals = &priv->ordinals;
u32 addr;
@@ -529,8 +522,8 @@ static int ipw2100_get_ordinal(struct ipw2100_priv *priv, u32 ord,
return -EINVAL;
}
- read_nic_dword(priv->net_dev, ordinals->table1_addr + (ord << 2),
- &addr);
+ read_nic_dword(priv->net_dev,
+ ordinals->table1_addr + (ord << 2), &addr);
read_nic_dword(priv->net_dev, addr, val);
*len = IPW_ORD_TAB_1_ENTRY_SIZE;
@@ -543,8 +536,8 @@ static int ipw2100_get_ordinal(struct ipw2100_priv *priv, u32 ord,
ord -= IPW_START_ORD_TAB_2;
/* get the address of statistic */
- read_nic_dword(priv->net_dev, ordinals->table2_addr + (ord << 3),
- &addr);
+ read_nic_dword(priv->net_dev,
+ ordinals->table2_addr + (ord << 3), &addr);
/* get the second DW of statistics ;
* two 16-bit words - first is length, second is count */
@@ -553,10 +546,10 @@ static int ipw2100_get_ordinal(struct ipw2100_priv *priv, u32 ord,
&field_info);
/* get each entry length */
- field_len = *((u16 *)&field_info);
+ field_len = *((u16 *) & field_info);
/* get number of entries */
- field_count = *(((u16 *)&field_info) + 1);
+ field_count = *(((u16 *) & field_info) + 1);
/* abort if no enought memory */
total_length = field_len * field_count;
@@ -581,8 +574,8 @@ static int ipw2100_get_ordinal(struct ipw2100_priv *priv, u32 ord,
return -EINVAL;
}
-static int ipw2100_set_ordinal(struct ipw2100_priv *priv, u32 ord, u32 *val,
- u32 *len)
+static int ipw2100_set_ordinal(struct ipw2100_priv *priv, u32 ord, u32 * val,
+ u32 * len)
{
struct ipw2100_ordinals *ordinals = &priv->ordinals;
u32 addr;
@@ -594,8 +587,8 @@ static int ipw2100_set_ordinal(struct ipw2100_priv *priv, u32 ord, u32 *val,
return -EINVAL;
}
- read_nic_dword(priv->net_dev, ordinals->table1_addr + (ord << 2),
- &addr);
+ read_nic_dword(priv->net_dev,
+ ordinals->table1_addr + (ord << 2), &addr);
write_nic_dword(priv->net_dev, addr, *val);
@@ -612,7 +605,7 @@ static int ipw2100_set_ordinal(struct ipw2100_priv *priv, u32 ord, u32 *val,
}
static char *snprint_line(char *buf, size_t count,
- const u8 *data, u32 len, u32 ofs)
+ const u8 * data, u32 len, u32 ofs)
{
int out, i, j, l;
char c;
@@ -646,7 +639,7 @@ static char *snprint_line(char *buf, size_t count,
return buf;
}
-static void printk_buf(int level, const u8 *data, u32 len)
+static void printk_buf(int level, const u8 * data, u32 len)
{
char line[81];
u32 ofs = 0;
@@ -662,8 +655,6 @@ static void printk_buf(int level, const u8 *data, u32 len)
}
}
-
-
#define MAX_RESET_BACKOFF 10
static inline void schedule_reset(struct ipw2100_priv *priv)
@@ -703,7 +694,7 @@ static inline void schedule_reset(struct ipw2100_priv *priv)
#define HOST_COMPLETE_TIMEOUT (2 * HZ)
static int ipw2100_hw_send_command(struct ipw2100_priv *priv,
- struct host_command * cmd)
+ struct host_command *cmd)
{
struct list_head *element;
struct ipw2100_tx_packet *packet;
@@ -713,25 +704,28 @@ static int ipw2100_hw_send_command(struct ipw2100_priv *priv,
IPW_DEBUG_HC("Sending %s command (#%d), %d bytes\n",
command_types[cmd->host_command], cmd->host_command,
cmd->host_command_length);
- printk_buf(IPW_DL_HC, (u8*)cmd->host_command_parameters,
+ printk_buf(IPW_DL_HC, (u8 *) cmd->host_command_parameters,
cmd->host_command_length);
spin_lock_irqsave(&priv->low_lock, flags);
if (priv->fatal_error) {
- IPW_DEBUG_INFO("Attempt to send command while hardware in fatal error condition.\n");
+ IPW_DEBUG_INFO
+ ("Attempt to send command while hardware in fatal error condition.\n");
err = -EIO;
goto fail_unlock;
}
if (!(priv->status & STATUS_RUNNING)) {
- IPW_DEBUG_INFO("Attempt to send command while hardware is not running.\n");
+ IPW_DEBUG_INFO
+ ("Attempt to send command while hardware is not running.\n");
err = -EIO;
goto fail_unlock;
}
if (priv->status & STATUS_CMD_ACTIVE) {
- IPW_DEBUG_INFO("Attempt to send command while another command is pending.\n");
+ IPW_DEBUG_INFO
+ ("Attempt to send command while another command is pending.\n");
err = -EBUSY;
goto fail_unlock;
}
@@ -752,7 +746,8 @@ static int ipw2100_hw_send_command(struct ipw2100_priv *priv,
/* initialize the firmware command packet */
packet->info.c_struct.cmd->host_command_reg = cmd->host_command;
packet->info.c_struct.cmd->host_command_reg1 = cmd->host_command1;
- packet->info.c_struct.cmd->host_command_len_reg = cmd->host_command_length;
+ packet->info.c_struct.cmd->host_command_len_reg =
+ cmd->host_command_length;
packet->info.c_struct.cmd->sequence = cmd->host_command_sequence;
memcpy(packet->info.c_struct.cmd->host_command_params_reg,
@@ -776,13 +771,15 @@ static int ipw2100_hw_send_command(struct ipw2100_priv *priv,
* then there is a problem.
*/
- err = wait_event_interruptible_timeout(
- priv->wait_command_queue, !(priv->status & STATUS_CMD_ACTIVE),
- HOST_COMPLETE_TIMEOUT);
+ err =
+ wait_event_interruptible_timeout(priv->wait_command_queue,
+ !(priv->
+ status & STATUS_CMD_ACTIVE),
+ HOST_COMPLETE_TIMEOUT);
if (err == 0) {
IPW_DEBUG_INFO("Command completion failed out after %dms.\n",
- HOST_COMPLETE_TIMEOUT / (HZ / 100));
+ 1000 * (HOST_COMPLETE_TIMEOUT / HZ));
priv->fatal_error = IPW2100_ERR_MSG_TIMEOUT;
priv->status &= ~STATUS_CMD_ACTIVE;
schedule_reset(priv);
@@ -800,18 +797,16 @@ static int ipw2100_hw_send_command(struct ipw2100_priv *priv,
* doesn't seem to have as many firmware restart cycles...
*
* As a test, we're sticking in a 1/100s delay here */
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(HZ / 100);
+ schedule_timeout_uninterruptible(msecs_to_jiffies(10));
return 0;
- fail_unlock:
+ fail_unlock:
spin_unlock_irqrestore(&priv->low_lock, flags);
return err;
}
-
/*
* Verify the values and data access of the hardware
* No locks needed or used. No functions called.
@@ -826,8 +821,7 @@ static int ipw2100_verify(struct ipw2100_priv *priv)
/* Domain 0 check - all values should be DOA_DEBUG */
for (address = IPW_REG_DOA_DEBUG_AREA_START;
- address < IPW_REG_DOA_DEBUG_AREA_END;
- address += sizeof(u32)) {
+ address < IPW_REG_DOA_DEBUG_AREA_END; address += sizeof(u32)) {
read_register(priv->net_dev, address, &data1);
if (data1 != IPW_DATA_DOA_DEBUG_VALUE)
return -EIO;
@@ -899,7 +893,6 @@ static int ipw2100_wait_for_card_state(struct ipw2100_priv *priv, int state)
return -EIO;
}
-
/*********************************************************************
Procedure : sw_reset_and_clock
Purpose : Asserts s/w reset, asserts clock initialization
@@ -976,17 +969,16 @@ static int ipw2100_download_firmware(struct ipw2100_priv *priv)
if (priv->fatal_error) {
IPW_DEBUG_ERROR("%s: ipw2100_download_firmware called after "
- "fatal error %d. Interface must be brought down.\n",
- priv->net_dev->name, priv->fatal_error);
+ "fatal error %d. Interface must be brought down.\n",
+ priv->net_dev->name, priv->fatal_error);
return -EINVAL;
}
-
#ifdef CONFIG_PM
if (!ipw2100_firmware.version) {
err = ipw2100_get_firmware(priv, &ipw2100_firmware);
if (err) {
IPW_DEBUG_ERROR("%s: ipw2100_get_firmware failed: %d\n",
- priv->net_dev->name, err);
+ priv->net_dev->name, err);
priv->fatal_error = IPW2100_ERR_FW_LOAD;
goto fail;
}
@@ -995,7 +987,7 @@ static int ipw2100_download_firmware(struct ipw2100_priv *priv)
err = ipw2100_get_firmware(priv, &ipw2100_firmware);
if (err) {
IPW_DEBUG_ERROR("%s: ipw2100_get_firmware failed: %d\n",
- priv->net_dev->name, err);
+ priv->net_dev->name, err);
priv->fatal_error = IPW2100_ERR_FW_LOAD;
goto fail;
}
@@ -1006,21 +998,20 @@ static int ipw2100_download_firmware(struct ipw2100_priv *priv)
err = sw_reset_and_clock(priv);
if (err) {
IPW_DEBUG_ERROR("%s: sw_reset_and_clock failed: %d\n",
- priv->net_dev->name, err);
+ priv->net_dev->name, err);
goto fail;
}
err = ipw2100_verify(priv);
if (err) {
IPW_DEBUG_ERROR("%s: ipw2100_verify failed: %d\n",
- priv->net_dev->name, err);
+ priv->net_dev->name, err);
goto fail;
}
/* Hold ARC */
write_nic_dword(priv->net_dev,
- IPW_INTERNAL_REGISTER_HALT_AND_RESET,
- 0x80000000);
+ IPW_INTERNAL_REGISTER_HALT_AND_RESET, 0x80000000);
/* allow ARC to run */
write_register(priv->net_dev, IPW_REG_RESET_REG, 0);
@@ -1035,13 +1026,13 @@ static int ipw2100_download_firmware(struct ipw2100_priv *priv)
/* release ARC */
write_nic_dword(priv->net_dev,
- IPW_INTERNAL_REGISTER_HALT_AND_RESET,
- 0x00000000);
+ IPW_INTERNAL_REGISTER_HALT_AND_RESET, 0x00000000);
/* s/w reset and clock stabilization (again!!!) */
err = sw_reset_and_clock(priv);
if (err) {
- printk(KERN_ERR DRV_NAME ": %s: sw_reset_and_clock failed: %d\n",
+ printk(KERN_ERR DRV_NAME
+ ": %s: sw_reset_and_clock failed: %d\n",
priv->net_dev->name, err);
goto fail;
}
@@ -1050,10 +1041,9 @@ static int ipw2100_download_firmware(struct ipw2100_priv *priv)
err = ipw2100_fw_download(priv, &ipw2100_firmware);
if (err) {
IPW_DEBUG_ERROR("%s: Error loading firmware: %d\n",
- priv->net_dev->name, err);
+ priv->net_dev->name, err);
goto fail;
}
-
#ifndef CONFIG_PM
/*
* When the .resume method of the driver is called, the other
@@ -1085,7 +1075,7 @@ static int ipw2100_download_firmware(struct ipw2100_priv *priv)
return 0;
- fail:
+ fail:
ipw2100_release_firmware(priv, &ipw2100_firmware);
return err;
}
@@ -1106,7 +1096,6 @@ static inline void ipw2100_disable_interrupts(struct ipw2100_priv *priv)
write_register(priv->net_dev, IPW_REG_INTA_MASK, 0x0);
}
-
static void ipw2100_initialize_ordinals(struct ipw2100_priv *priv)
{
struct ipw2100_ordinals *ord = &priv->ordinals;
@@ -1178,11 +1167,10 @@ static int ipw2100_get_hw_features(struct ipw2100_priv *priv)
* EEPROM_SRAM_DB_START_ADDRESS using ordinal in ordinal table 1
*/
len = sizeof(addr);
- if (ipw2100_get_ordinal(
- priv, IPW_ORD_EEPROM_SRAM_DB_BLOCK_START_ADDRESS,
- &addr, &len)) {
+ if (ipw2100_get_ordinal
+ (priv, IPW_ORD_EEPROM_SRAM_DB_BLOCK_START_ADDRESS, &addr, &len)) {
IPW_DEBUG_INFO("failed querying ordinals at line %d\n",
- __LINE__);
+ __LINE__);
return -EIO;
}
@@ -1195,7 +1183,7 @@ static int ipw2100_get_hw_features(struct ipw2100_priv *priv)
priv->eeprom_version = (val >> 24) & 0xFF;
IPW_DEBUG_INFO("EEPROM version: %d\n", priv->eeprom_version);
- /*
+ /*
* HW RF Kill enable is bit 0 in byte at offset 0x21 in firmware
*
* notice that the EEPROM bit is reverse polarity, i.e.
@@ -1207,8 +1195,7 @@ static int ipw2100_get_hw_features(struct ipw2100_priv *priv)
priv->hw_features |= HW_FEATURE_RFKILL;
IPW_DEBUG_INFO("HW RF Kill: %ssupported.\n",
- (priv->hw_features & HW_FEATURE_RFKILL) ?
- "" : "not ");
+ (priv->hw_features & HW_FEATURE_RFKILL) ? "" : "not ");
return 0;
}
@@ -1235,7 +1222,8 @@ static int ipw2100_start_adapter(struct ipw2100_priv *priv)
* fw & dino ucode
*/
if (ipw2100_download_firmware(priv)) {
- printk(KERN_ERR DRV_NAME ": %s: Failed to power on the adapter.\n",
+ printk(KERN_ERR DRV_NAME
+ ": %s: Failed to power on the adapter.\n",
priv->net_dev->name);
return -EIO;
}
@@ -1256,8 +1244,7 @@ static int ipw2100_start_adapter(struct ipw2100_priv *priv)
IPW_DEBUG_FW("Waiting for f/w initialization to complete...\n");
i = 5000;
do {
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(40 * HZ / 1000);
+ schedule_timeout_uninterruptible(msecs_to_jiffies(40));
/* Todo... wait for sync command ... */
read_register(priv->net_dev, IPW_REG_INTA, &inta);
@@ -1295,7 +1282,8 @@ static int ipw2100_start_adapter(struct ipw2100_priv *priv)
i ? "SUCCESS" : "FAILED");
if (!i) {
- printk(KERN_WARNING DRV_NAME ": %s: Firmware did not initialize.\n",
+ printk(KERN_WARNING DRV_NAME
+ ": %s: Firmware did not initialize.\n",
priv->net_dev->name);
return -EIO;
}
@@ -1328,7 +1316,6 @@ static inline void ipw2100_reset_fatalerror(struct ipw2100_priv *priv)
priv->fatal_error = 0;
}
-
/* NOTE: Our interrupt is disabled when this method is called */
static int ipw2100_power_cycle_adapter(struct ipw2100_priv *priv)
{
@@ -1352,19 +1339,19 @@ static int ipw2100_power_cycle_adapter(struct ipw2100_priv *priv)
if (reg & IPW_AUX_HOST_RESET_REG_MASTER_DISABLED)
break;
- } while(i--);
+ } while (i--);
priv->status &= ~STATUS_RESET_PENDING;
if (!i) {
- IPW_DEBUG_INFO("exit - waited too long for master assert stop\n");
+ IPW_DEBUG_INFO
+ ("exit - waited too long for master assert stop\n");
return -EIO;
}
write_register(priv->net_dev, IPW_REG_RESET_REG,
IPW_AUX_HOST_RESET_REG_SW_RESET);
-
/* Reset any fatal_error conditions */
ipw2100_reset_fatalerror(priv);
@@ -1411,14 +1398,12 @@ static int ipw2100_hw_phy_off(struct ipw2100_priv *priv)
(val2 & IPW2100_COMMAND_PHY_OFF))
return 0;
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(HW_PHY_OFF_LOOP_DELAY);
+ schedule_timeout_uninterruptible(HW_PHY_OFF_LOOP_DELAY);
}
return -EIO;
}
-
static int ipw2100_enable_adapter(struct ipw2100_priv *priv)
{
struct host_command cmd = {
@@ -1448,9 +1433,8 @@ static int ipw2100_enable_adapter(struct ipw2100_priv *priv)
err = ipw2100_wait_for_card_state(priv, IPW_HW_STATE_ENABLED);
if (err) {
- IPW_DEBUG_INFO(
- "%s: card not responding to init command.\n",
- priv->net_dev->name);
+ IPW_DEBUG_INFO("%s: card not responding to init command.\n",
+ priv->net_dev->name);
goto fail_up;
}
@@ -1459,14 +1443,14 @@ static int ipw2100_enable_adapter(struct ipw2100_priv *priv)
queue_delayed_work(priv->workqueue, &priv->hang_check, HZ / 2);
}
-fail_up:
+ fail_up:
up(&priv->adapter_sem);
return err;
}
static int ipw2100_hw_stop_adapter(struct ipw2100_priv *priv)
{
-#define HW_POWER_DOWN_DELAY (HZ / 10)
+#define HW_POWER_DOWN_DELAY (msecs_to_jiffies(100))
struct host_command cmd = {
.host_command = HOST_PRE_POWER_DOWN,
@@ -1491,7 +1475,8 @@ static int ipw2100_hw_stop_adapter(struct ipw2100_priv *priv)
err = ipw2100_hw_phy_off(priv);
if (err)
- printk(KERN_WARNING DRV_NAME ": Error disabling radio %d\n", err);
+ printk(KERN_WARNING DRV_NAME
+ ": Error disabling radio %d\n", err);
/*
* If in D0-standby mode going directly to D3 may cause a
@@ -1520,10 +1505,8 @@ static int ipw2100_hw_stop_adapter(struct ipw2100_priv *priv)
printk(KERN_WARNING DRV_NAME ": "
"%s: Power down command failed: Error %d\n",
priv->net_dev->name, err);
- else {
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(HW_POWER_DOWN_DELAY);
- }
+ else
+ schedule_timeout_uninterruptible(HW_POWER_DOWN_DELAY);
}
priv->status &= ~STATUS_ENABLED;
@@ -1571,7 +1554,6 @@ static int ipw2100_hw_stop_adapter(struct ipw2100_priv *priv)
return 0;
}
-
static int ipw2100_disable_adapter(struct ipw2100_priv *priv)
{
struct host_command cmd = {
@@ -1598,19 +1580,21 @@ static int ipw2100_disable_adapter(struct ipw2100_priv *priv)
err = ipw2100_hw_send_command(priv, &cmd);
if (err) {
- printk(KERN_WARNING DRV_NAME ": exit - failed to send CARD_DISABLE command\n");
+ printk(KERN_WARNING DRV_NAME
+ ": exit - failed to send CARD_DISABLE command\n");
goto fail_up;
}
err = ipw2100_wait_for_card_state(priv, IPW_HW_STATE_DISABLED);
if (err) {
- printk(KERN_WARNING DRV_NAME ": exit - card failed to change to DISABLED\n");
+ printk(KERN_WARNING DRV_NAME
+ ": exit - card failed to change to DISABLED\n");
goto fail_up;
}
IPW_DEBUG_INFO("TODO: implement scan state machine\n");
-fail_up:
+ fail_up:
up(&priv->adapter_sem);
return err;
}
@@ -1632,7 +1616,7 @@ static int ipw2100_set_scan_options(struct ipw2100_priv *priv)
if (!(priv->config & CFG_ASSOCIATE))
cmd.host_command_parameters[0] |= IPW_SCAN_NOASSOCIATE;
- if ((priv->sec.flags & SEC_ENABLED) && priv->sec.enabled)
+ if ((priv->ieee->sec.flags & SEC_ENABLED) && priv->ieee->sec.enabled)
cmd.host_command_parameters[0] |= IPW_SCAN_MIXED_CELL;
if (priv->config & CFG_PASSIVE_SCAN)
cmd.host_command_parameters[0] |= IPW_SCAN_PASSIVE;
@@ -1714,8 +1698,9 @@ static int ipw2100_up(struct ipw2100_priv *priv, int deferred)
(priv->status & STATUS_RESET_PENDING)) {
/* Power cycle the card ... */
if (ipw2100_power_cycle_adapter(priv)) {
- printk(KERN_WARNING DRV_NAME ": %s: Could not cycle adapter.\n",
- priv->net_dev->name);
+ printk(KERN_WARNING DRV_NAME
+ ": %s: Could not cycle adapter.\n",
+ priv->net_dev->name);
rc = 1;
goto exit;
}
@@ -1724,8 +1709,9 @@ static int ipw2100_up(struct ipw2100_priv *priv, int deferred)
/* Load the firmware, start the clocks, etc. */
if (ipw2100_start_adapter(priv)) {
- printk(KERN_ERR DRV_NAME ": %s: Failed to start the firmware.\n",
- priv->net_dev->name);
+ printk(KERN_ERR DRV_NAME
+ ": %s: Failed to start the firmware.\n",
+ priv->net_dev->name);
rc = 1;
goto exit;
}
@@ -1734,16 +1720,18 @@ static int ipw2100_up(struct ipw2100_priv *priv, int deferred)
/* Determine capabilities of this particular HW configuration */
if (ipw2100_get_hw_features(priv)) {
- printk(KERN_ERR DRV_NAME ": %s: Failed to determine HW features.\n",
- priv->net_dev->name);
+ printk(KERN_ERR DRV_NAME
+ ": %s: Failed to determine HW features.\n",
+ priv->net_dev->name);
rc = 1;
goto exit;
}
lock = LOCK_NONE;
if (ipw2100_set_ordinal(priv, IPW_ORD_PERS_DB_LOCK, &lock, &ord_len)) {
- printk(KERN_ERR DRV_NAME ": %s: Failed to clear ordinal lock.\n",
- priv->net_dev->name);
+ printk(KERN_ERR DRV_NAME
+ ": %s: Failed to clear ordinal lock.\n",
+ priv->net_dev->name);
rc = 1;
goto exit;
}
@@ -1769,7 +1757,7 @@ static int ipw2100_up(struct ipw2100_priv *priv, int deferred)
* HOST_COMPLETE */
if (ipw2100_adapter_setup(priv)) {
printk(KERN_ERR DRV_NAME ": %s: Failed to start the card.\n",
- priv->net_dev->name);
+ priv->net_dev->name);
rc = 1;
goto exit;
}
@@ -1778,20 +1766,19 @@ static int ipw2100_up(struct ipw2100_priv *priv, int deferred)
/* Enable the adapter - sends HOST_COMPLETE */
if (ipw2100_enable_adapter(priv)) {
printk(KERN_ERR DRV_NAME ": "
- "%s: failed in call to enable adapter.\n",
- priv->net_dev->name);
+ "%s: failed in call to enable adapter.\n",
+ priv->net_dev->name);
ipw2100_hw_stop_adapter(priv);
rc = 1;
goto exit;
}
-
/* Start a scan . . . */
ipw2100_set_scan_options(priv);
ipw2100_start_scan(priv);
}
- exit:
+ exit:
return rc;
}
@@ -1807,8 +1794,7 @@ static void ipw2100_down(struct ipw2100_priv *priv)
unsigned long flags;
union iwreq_data wrqu = {
.ap_addr = {
- .sa_family = ARPHRD_ETHER
- }
+ .sa_family = ARPHRD_ETHER}
};
int associated = priv->status & STATUS_ASSOCIATED;
@@ -1847,7 +1833,7 @@ static void ipw2100_down(struct ipw2100_priv *priv)
#ifdef ACPI_CSTATE_LIMIT_DEFINED
if (priv->config & CFG_C3_DISABLED) {
- IPW_DEBUG_INFO(DRV_NAME ": Resetting C3 transitions.\n");
+ IPW_DEBUG_INFO(": Resetting C3 transitions.\n");
acpi_set_cstate_limit(priv->cstate_limit);
priv->config &= ~CFG_C3_DISABLED;
}
@@ -1867,14 +1853,12 @@ static void ipw2100_reset_adapter(struct ipw2100_priv *priv)
unsigned long flags;
union iwreq_data wrqu = {
.ap_addr = {
- .sa_family = ARPHRD_ETHER
- }
+ .sa_family = ARPHRD_ETHER}
};
int associated = priv->status & STATUS_ASSOCIATED;
spin_lock_irqsave(&priv->low_lock, flags);
- IPW_DEBUG_INFO(DRV_NAME ": %s: Restarting adapter.\n",
- priv->net_dev->name);
+ IPW_DEBUG_INFO(": %s: Restarting adapter.\n", priv->net_dev->name);
priv->resets++;
priv->status &= ~(STATUS_ASSOCIATED | STATUS_ASSOCIATING);
priv->status |= STATUS_SECURITY_UPDATED;
@@ -1899,7 +1883,6 @@ static void ipw2100_reset_adapter(struct ipw2100_priv *priv)
}
-
static void isr_indicate_associated(struct ipw2100_priv *priv, u32 status)
{
@@ -1909,7 +1892,7 @@ static void isr_indicate_associated(struct ipw2100_priv *priv, u32 status)
u32 txrate;
u32 chan;
char *txratename;
- u8 bssid[ETH_ALEN];
+ u8 bssid[ETH_ALEN];
/*
* TBD: BSSID is usually 00:00:00:00:00:00 here and not
@@ -1923,16 +1906,15 @@ static void isr_indicate_associated(struct ipw2100_priv *priv, u32 status)
essid, &essid_len);
if (ret) {
IPW_DEBUG_INFO("failed querying ordinals at line %d\n",
- __LINE__);
+ __LINE__);
return;
}
len = sizeof(u32);
- ret = ipw2100_get_ordinal(priv, IPW_ORD_CURRENT_TX_RATE,
- &txrate, &len);
+ ret = ipw2100_get_ordinal(priv, IPW_ORD_CURRENT_TX_RATE, &txrate, &len);
if (ret) {
IPW_DEBUG_INFO("failed querying ordinals at line %d\n",
- __LINE__);
+ __LINE__);
return;
}
@@ -1940,19 +1922,18 @@ static void isr_indicate_associated(struct ipw2100_priv *priv, u32 status)
ret = ipw2100_get_ordinal(priv, IPW_ORD_OUR_FREQ, &chan, &len);
if (ret) {
IPW_DEBUG_INFO("failed querying ordinals at line %d\n",
- __LINE__);
+ __LINE__);
return;
}
len = ETH_ALEN;
- ipw2100_get_ordinal(priv, IPW_ORD_STAT_ASSN_AP_BSSID, &bssid, &len);
+ ipw2100_get_ordinal(priv, IPW_ORD_STAT_ASSN_AP_BSSID, &bssid, &len);
if (ret) {
IPW_DEBUG_INFO("failed querying ordinals at line %d\n",
- __LINE__);
+ __LINE__);
return;
}
memcpy(priv->ieee->bssid, bssid, ETH_ALEN);
-
switch (txrate) {
case TX_RATE_1_MBIT:
txratename = "1Mbps";
@@ -1979,7 +1960,7 @@ static void isr_indicate_associated(struct ipw2100_priv *priv, u32 status)
/* now we copy read ssid into dev */
if (!(priv->config & CFG_STATIC_ESSID)) {
- priv->essid_len = min((u8)essid_len, (u8)IW_ESSID_MAX_SIZE);
+ priv->essid_len = min((u8) essid_len, (u8) IW_ESSID_MAX_SIZE);
memcpy(priv->essid, essid, priv->essid_len);
}
priv->channel = chan;
@@ -1991,7 +1972,6 @@ static void isr_indicate_associated(struct ipw2100_priv *priv, u32 status)
queue_delayed_work(priv->workqueue, &priv->wx_event_work, HZ / 10);
}
-
static int ipw2100_set_essid(struct ipw2100_priv *priv, char *essid,
int length, int batch_mode)
{
@@ -2006,8 +1986,7 @@ static int ipw2100_set_essid(struct ipw2100_priv *priv, char *essid,
IPW_DEBUG_HC("SSID: '%s'\n", escape_essid(essid, ssid_len));
if (ssid_len)
- memcpy((char*)cmd.host_command_parameters,
- essid, ssid_len);
+ memcpy(cmd.host_command_parameters, essid, ssid_len);
if (!batch_mode) {
err = ipw2100_disable_adapter(priv);
@@ -2019,7 +1998,7 @@ static int ipw2100_set_essid(struct ipw2100_priv *priv, char *essid,
* disable auto association -- so we cheat by setting a bogus SSID */
if (!ssid_len && !(priv->config & CFG_ASSOCIATE)) {
int i;
- u8 *bogus = (u8*)cmd.host_command_parameters;
+ u8 *bogus = (u8 *) cmd.host_command_parameters;
for (i = 0; i < IW_ESSID_MAX_SIZE; i++)
bogus[i] = 0x18 + i;
cmd.host_command_length = IW_ESSID_MAX_SIZE;
@@ -2030,8 +2009,7 @@ static int ipw2100_set_essid(struct ipw2100_priv *priv, char *essid,
err = ipw2100_hw_send_command(priv, &cmd);
if (!err) {
- memset(priv->essid + ssid_len, 0,
- IW_ESSID_MAX_SIZE - ssid_len);
+ memset(priv->essid + ssid_len, 0, IW_ESSID_MAX_SIZE - ssid_len);
memcpy(priv->essid, essid, ssid_len);
priv->essid_len = ssid_len;
}
@@ -2076,14 +2054,14 @@ static void isr_indicate_association_lost(struct ipw2100_priv *priv, u32 status)
static void isr_indicate_rf_kill(struct ipw2100_priv *priv, u32 status)
{
IPW_DEBUG_INFO("%s: RF Kill state changed to radio OFF.\n",
- priv->net_dev->name);
+ priv->net_dev->name);
/* RF_KILL is now enabled (else we wouldn't be here) */
priv->status |= STATUS_RF_KILL_HW;
#ifdef ACPI_CSTATE_LIMIT_DEFINED
if (priv->config & CFG_C3_DISABLED) {
- IPW_DEBUG_INFO(DRV_NAME ": Resetting C3 transitions.\n");
+ IPW_DEBUG_INFO(": Resetting C3 transitions.\n");
acpi_set_cstate_limit(priv->cstate_limit);
priv->config &= ~CFG_C3_DISABLED;
}
@@ -2107,16 +2085,16 @@ static void isr_scan_complete(struct ipw2100_priv *priv, u32 status)
#define IPW2100_HANDLER(v, f) { v, f, # v }
struct ipw2100_status_indicator {
int status;
- void (*cb)(struct ipw2100_priv *priv, u32 status);
+ void (*cb) (struct ipw2100_priv * priv, u32 status);
char *name;
};
#else
#define IPW2100_HANDLER(v, f) { v, f }
struct ipw2100_status_indicator {
int status;
- void (*cb)(struct ipw2100_priv *priv, u32 status);
+ void (*cb) (struct ipw2100_priv * priv, u32 status);
};
-#endif /* CONFIG_IPW_DEBUG */
+#endif /* CONFIG_IPW_DEBUG */
static void isr_indicate_scanning(struct ipw2100_priv *priv, u32 status)
{
@@ -2140,7 +2118,6 @@ static const struct ipw2100_status_indicator status_handlers[] = {
IPW2100_HANDLER(-1, NULL)
};
-
static void isr_status_change(struct ipw2100_priv *priv, int status)
{
int i;
@@ -2158,7 +2135,7 @@ static void isr_status_change(struct ipw2100_priv *priv, int status)
for (i = 0; status_handlers[i].status != -1; i++) {
if (status == status_handlers[i].status) {
IPW_DEBUG_NOTIF("Status change: %s\n",
- status_handlers[i].name);
+ status_handlers[i].name);
if (status_handlers[i].cb)
status_handlers[i].cb(priv, status);
priv->wstats.status = status;
@@ -2169,9 +2146,8 @@ static void isr_status_change(struct ipw2100_priv *priv, int status)
IPW_DEBUG_NOTIF("unknown status received: %04x\n", status);
}
-static void isr_rx_complete_command(
- struct ipw2100_priv *priv,
- struct ipw2100_cmd_header *cmd)
+static void isr_rx_complete_command(struct ipw2100_priv *priv,
+ struct ipw2100_cmd_header *cmd)
{
#ifdef CONFIG_IPW_DEBUG
if (cmd->host_command_reg < ARRAY_SIZE(command_types)) {
@@ -2201,10 +2177,8 @@ static const char *frame_types[] = {
};
#endif
-
-static inline int ipw2100_alloc_skb(
- struct ipw2100_priv *priv,
- struct ipw2100_rx_packet *packet)
+static inline int ipw2100_alloc_skb(struct ipw2100_priv *priv,
+ struct ipw2100_rx_packet *packet)
{
packet->skb = dev_alloc_skb(sizeof(struct ipw2100_rx));
if (!packet->skb)
@@ -2220,7 +2194,6 @@ static inline int ipw2100_alloc_skb(
return 0;
}
-
#define SEARCH_ERROR 0xffffffff
#define SEARCH_FAIL 0xfffffffe
#define SEARCH_SUCCESS 0xfffffff0
@@ -2234,10 +2207,10 @@ static inline int ipw2100_snapshot_alloc(struct ipw2100_priv *priv)
if (priv->snapshot[0])
return 1;
for (i = 0; i < 0x30; i++) {
- priv->snapshot[i] = (u8*)kmalloc(0x1000, GFP_ATOMIC);
+ priv->snapshot[i] = (u8 *) kmalloc(0x1000, GFP_ATOMIC);
if (!priv->snapshot[i]) {
IPW_DEBUG_INFO("%s: Error allocating snapshot "
- "buffer %d\n", priv->net_dev->name, i);
+ "buffer %d\n", priv->net_dev->name, i);
while (i > 0)
kfree(priv->snapshot[--i]);
priv->snapshot[0] = NULL;
@@ -2258,7 +2231,7 @@ static inline void ipw2100_snapshot_free(struct ipw2100_priv *priv)
priv->snapshot[0] = NULL;
}
-static inline u32 ipw2100_match_buf(struct ipw2100_priv *priv, u8 *in_buf,
+static inline u32 ipw2100_match_buf(struct ipw2100_priv *priv, u8 * in_buf,
size_t len, int mode)
{
u32 i, j;
@@ -2275,9 +2248,9 @@ static inline u32 ipw2100_match_buf(struct ipw2100_priv *priv, u8 *in_buf,
for (ret = SEARCH_FAIL, i = 0; i < 0x30000; i += 4) {
read_nic_dword(priv->net_dev, i, &tmp);
if (mode == SEARCH_SNAPSHOT)
- *(u32 *)SNAPSHOT_ADDR(i) = tmp;
+ *(u32 *) SNAPSHOT_ADDR(i) = tmp;
if (ret == SEARCH_FAIL) {
- d = (u8*)&tmp;
+ d = (u8 *) & tmp;
for (j = 0; j < 4; j++) {
if (*s != *d) {
s = in_buf;
@@ -2315,8 +2288,7 @@ static inline u32 ipw2100_match_buf(struct ipw2100_priv *priv, u8 *in_buf,
static u8 packet_data[IPW_RX_NIC_BUFFER_LENGTH];
#endif
-static inline void ipw2100_corruption_detected(struct ipw2100_priv *priv,
- int i)
+static inline void ipw2100_corruption_detected(struct ipw2100_priv *priv, int i)
{
#ifdef CONFIG_IPW_DEBUG_C3
struct ipw2100_status *status = &priv->status_queue.drv[i];
@@ -2327,11 +2299,11 @@ static inline void ipw2100_corruption_detected(struct ipw2100_priv *priv,
int limit;
#endif
- IPW_DEBUG_INFO(DRV_NAME ": PCI latency error detected at "
- "0x%04zX.\n", i * sizeof(struct ipw2100_status));
+ IPW_DEBUG_INFO(": PCI latency error detected at 0x%04zX.\n",
+ i * sizeof(struct ipw2100_status));
#ifdef ACPI_CSTATE_LIMIT_DEFINED
- IPW_DEBUG_INFO(DRV_NAME ": Disabling C3 transitions.\n");
+ IPW_DEBUG_INFO(": Disabling C3 transitions.\n");
limit = acpi_get_cstate_limit();
if (limit > 2) {
priv->cstate_limit = limit;
@@ -2351,9 +2323,9 @@ static inline void ipw2100_corruption_detected(struct ipw2100_priv *priv,
if (reg & IPW_AUX_HOST_RESET_REG_MASTER_DISABLED)
break;
- } while (j--);
+ } while (j--);
- match = ipw2100_match_buf(priv, (u8*)status,
+ match = ipw2100_match_buf(priv, (u8 *) status,
sizeof(struct ipw2100_status),
SEARCH_SNAPSHOT);
if (match < SEARCH_SUCCESS)
@@ -2365,7 +2337,7 @@ static inline void ipw2100_corruption_detected(struct ipw2100_priv *priv,
IPW_DEBUG_INFO("%s: No DMA status match in "
"Firmware.\n", priv->net_dev->name);
- printk_buf((u8*)priv->status_queue.drv,
+ printk_buf((u8 *) priv->status_queue.drv,
sizeof(struct ipw2100_status) * RX_QUEUE_LENGTH);
#endif
@@ -2397,26 +2369,26 @@ static inline void isr_rx(struct ipw2100_priv *priv, int i,
IPW_DEBUG_DROP("Dropping packet while interface is not up.\n");
return;
}
-
+#ifdef CONFIG_IPW2100_MONITOR
if (unlikely(priv->ieee->iw_mode == IW_MODE_MONITOR &&
+ priv->config & CFG_CRC_CHECK &&
status->flags & IPW_STATUS_FLAG_CRC_ERROR)) {
IPW_DEBUG_RX("CRC error in packet. Dropping.\n");
priv->ieee->stats.rx_errors++;
return;
}
+#endif
if (unlikely(priv->ieee->iw_mode != IW_MODE_MONITOR &&
- !(priv->status & STATUS_ASSOCIATED))) {
+ !(priv->status & STATUS_ASSOCIATED))) {
IPW_DEBUG_DROP("Dropping packet while not associated.\n");
priv->wstats.discard.misc++;
return;
}
-
pci_unmap_single(priv->pci_dev,
packet->dma_addr,
- sizeof(struct ipw2100_rx),
- PCI_DMA_FROMDEVICE);
+ sizeof(struct ipw2100_rx), PCI_DMA_FROMDEVICE);
skb_put(packet->skb, status->frame_size);
@@ -2443,8 +2415,8 @@ static inline void isr_rx(struct ipw2100_priv *priv, int i,
/* We need to allocate a new SKB and attach it to the RDB. */
if (unlikely(ipw2100_alloc_skb(priv, packet))) {
printk(KERN_WARNING DRV_NAME ": "
- "%s: Unable to allocate SKB onto RBD ring - disabling "
- "adapter.\n", priv->net_dev->name);
+ "%s: Unable to allocate SKB onto RBD ring - disabling "
+ "adapter.\n", priv->net_dev->name);
/* TODO: schedule adapter shutdown */
IPW_DEBUG_INFO("TODO: Shutdown adapter...\n");
}
@@ -2539,11 +2511,11 @@ static inline void __ipw2100_rx_process(struct ipw2100_priv *priv)
/* Sync the DMA for the STATUS buffer so CPU is sure to get
* the correct values */
- pci_dma_sync_single_for_cpu(
- priv->pci_dev,
- sq->nic + sizeof(struct ipw2100_status) * i,
- sizeof(struct ipw2100_status),
- PCI_DMA_FROMDEVICE);
+ pci_dma_sync_single_for_cpu(priv->pci_dev,
+ sq->nic +
+ sizeof(struct ipw2100_status) * i,
+ sizeof(struct ipw2100_status),
+ PCI_DMA_FROMDEVICE);
/* Sync the DMA for the RX buffer so CPU is sure to get
* the correct values */
@@ -2557,8 +2529,7 @@ static inline void __ipw2100_rx_process(struct ipw2100_priv *priv)
}
u = packet->rxp;
- frame_type = sq->drv[i].status_fields &
- STATUS_TYPE_MASK;
+ frame_type = sq->drv[i].status_fields & STATUS_TYPE_MASK;
stats.rssi = sq->drv[i].rssi + IPW2100_RSSI_TO_DBM;
stats.len = sq->drv[i].frame_size;
@@ -2567,16 +2538,14 @@ static inline void __ipw2100_rx_process(struct ipw2100_priv *priv)
stats.mask |= IEEE80211_STATMASK_RSSI;
stats.freq = IEEE80211_24GHZ_BAND;
- IPW_DEBUG_RX(
- "%s: '%s' frame type received (%d).\n",
- priv->net_dev->name, frame_types[frame_type],
- stats.len);
+ IPW_DEBUG_RX("%s: '%s' frame type received (%d).\n",
+ priv->net_dev->name, frame_types[frame_type],
+ stats.len);
switch (frame_type) {
case COMMAND_STATUS_VAL:
/* Reset Rx watchdog */
- isr_rx_complete_command(
- priv, &u->rx_data.command);
+ isr_rx_complete_command(priv, &u->rx_data.command);
break;
case STATUS_CHANGE_VAL:
@@ -2593,12 +2562,10 @@ static inline void __ipw2100_rx_process(struct ipw2100_priv *priv)
#endif
if (stats.len < sizeof(u->rx_data.header))
break;
- switch (WLAN_FC_GET_TYPE(u->rx_data.header.
- frame_ctl)) {
+ switch (WLAN_FC_GET_TYPE(u->rx_data.header.frame_ctl)) {
case IEEE80211_FTYPE_MGMT:
ieee80211_rx_mgt(priv->ieee,
- &u->rx_data.header,
- &stats);
+ &u->rx_data.header, &stats);
break;
case IEEE80211_FTYPE_CTL:
@@ -2612,7 +2579,7 @@ static inline void __ipw2100_rx_process(struct ipw2100_priv *priv)
break;
}
- increment:
+ increment:
/* clear status field associated with this RBD */
rxq->drv[i].status.info.field = 0;
@@ -2624,12 +2591,10 @@ static inline void __ipw2100_rx_process(struct ipw2100_priv *priv)
rxq->next = (i ? i : rxq->entries) - 1;
write_register(priv->net_dev,
- IPW_MEM_HOST_SHARED_RX_WRITE_INDEX,
- rxq->next);
+ IPW_MEM_HOST_SHARED_RX_WRITE_INDEX, rxq->next);
}
}
-
/*
* __ipw2100_tx_process
*
@@ -2672,7 +2637,7 @@ static inline void __ipw2100_rx_process(struct ipw2100_priv *priv)
static inline int __ipw2100_tx_process(struct ipw2100_priv *priv)
{
struct ipw2100_bd_queue *txq = &priv->tx_queue;
- struct ipw2100_bd *tbd;
+ struct ipw2100_bd *tbd;
struct list_head *element;
struct ipw2100_tx_packet *packet;
int descriptors_used;
@@ -2685,7 +2650,7 @@ static inline int __ipw2100_tx_process(struct ipw2100_priv *priv)
element = priv->fw_pend_list.next;
packet = list_entry(element, struct ipw2100_tx_packet, list);
- tbd = &txq->drv[packet->index];
+ tbd = &txq->drv[packet->index];
/* Determine how many TBD entries must be finished... */
switch (packet->type) {
@@ -2698,14 +2663,14 @@ static inline int __ipw2100_tx_process(struct ipw2100_priv *priv)
case DATA:
/* DATA uses two slots; advance and loop position. */
descriptors_used = tbd->num_fragments;
- frag_num = tbd->num_fragments - 1;
+ frag_num = tbd->num_fragments - 1;
e = txq->oldest + frag_num;
e %= txq->entries;
break;
default:
printk(KERN_WARNING DRV_NAME ": %s: Bad fw_pend_list entry!\n",
- priv->net_dev->name);
+ priv->net_dev->name);
return 0;
}
@@ -2721,13 +2686,12 @@ static inline int __ipw2100_tx_process(struct ipw2100_priv *priv)
printk(KERN_WARNING DRV_NAME ": %s: write index mismatch\n",
priv->net_dev->name);
- /*
+ /*
* txq->next is the index of the last packet written txq->oldest is
* the index of the r is the index of the next packet to be read by
* firmware
*/
-
/*
* Quick graphic to help you visualize the following
* if / else statement
@@ -2755,23 +2719,20 @@ static inline int __ipw2100_tx_process(struct ipw2100_priv *priv)
#ifdef CONFIG_IPW_DEBUG
{
int i = txq->oldest;
- IPW_DEBUG_TX(
- "TX%d V=%p P=%04X T=%04X L=%d\n", i,
- &txq->drv[i],
- (u32)(txq->nic + i * sizeof(struct ipw2100_bd)),
- txq->drv[i].host_addr,
- txq->drv[i].buf_length);
+ IPW_DEBUG_TX("TX%d V=%p P=%04X T=%04X L=%d\n", i,
+ &txq->drv[i],
+ (u32) (txq->nic + i * sizeof(struct ipw2100_bd)),
+ txq->drv[i].host_addr, txq->drv[i].buf_length);
if (packet->type == DATA) {
i = (i + 1) % txq->entries;
- IPW_DEBUG_TX(
- "TX%d V=%p P=%04X T=%04X L=%d\n", i,
- &txq->drv[i],
- (u32)(txq->nic + i *
- sizeof(struct ipw2100_bd)),
- (u32)txq->drv[i].host_addr,
- txq->drv[i].buf_length);
+ IPW_DEBUG_TX("TX%d V=%p P=%04X T=%04X L=%d\n", i,
+ &txq->drv[i],
+ (u32) (txq->nic + i *
+ sizeof(struct ipw2100_bd)),
+ (u32) txq->drv[i].host_addr,
+ txq->drv[i].buf_length);
}
}
#endif
@@ -2785,23 +2746,18 @@ static inline int __ipw2100_tx_process(struct ipw2100_priv *priv)
priv->net_dev->name, txq->oldest, packet->index);
/* DATA packet; we have to unmap and free the SKB */
- priv->ieee->stats.tx_packets++;
for (i = 0; i < frag_num; i++) {
- tbd = &txq->drv[(packet->index + 1 + i) %
- txq->entries];
+ tbd = &txq->drv[(packet->index + 1 + i) % txq->entries];
- IPW_DEBUG_TX(
- "TX%d P=%08x L=%d\n",
- (packet->index + 1 + i) % txq->entries,
- tbd->host_addr, tbd->buf_length);
+ IPW_DEBUG_TX("TX%d P=%08x L=%d\n",
+ (packet->index + 1 + i) % txq->entries,
+ tbd->host_addr, tbd->buf_length);
pci_unmap_single(priv->pci_dev,
tbd->host_addr,
- tbd->buf_length,
- PCI_DMA_TODEVICE);
+ tbd->buf_length, PCI_DMA_TODEVICE);
}
- priv->ieee->stats.tx_bytes += packet->info.d_struct.txb->payload_size;
ieee80211_txb_free(packet->info.d_struct.txb);
packet->info.d_struct.txb = NULL;
@@ -2810,13 +2766,8 @@ static inline int __ipw2100_tx_process(struct ipw2100_priv *priv)
/* We have a free slot in the Tx queue, so wake up the
* transmit layer if it is stopped. */
- if (priv->status & STATUS_ASSOCIATED &&
- netif_queue_stopped(priv->net_dev)) {
- IPW_DEBUG_INFO(KERN_INFO
- "%s: Waking net queue.\n",
- priv->net_dev->name);
+ if (priv->status & STATUS_ASSOCIATED)
netif_wake_queue(priv->net_dev);
- }
/* A packet was processed by the hardware, so update the
* watchdog */
@@ -2834,11 +2785,12 @@ static inline int __ipw2100_tx_process(struct ipw2100_priv *priv)
#ifdef CONFIG_IPW_DEBUG
if (packet->info.c_struct.cmd->host_command_reg <
sizeof(command_types) / sizeof(*command_types))
- IPW_DEBUG_TX(
- "Command '%s (%d)' processed: %d.\n",
- command_types[packet->info.c_struct.cmd->host_command_reg],
- packet->info.c_struct.cmd->host_command_reg,
- packet->info.c_struct.cmd->cmd_status_reg);
+ IPW_DEBUG_TX("Command '%s (%d)' processed: %d.\n",
+ command_types[packet->info.c_struct.cmd->
+ host_command_reg],
+ packet->info.c_struct.cmd->
+ host_command_reg,
+ packet->info.c_struct.cmd->cmd_status_reg);
#endif
list_add_tail(element, &priv->msg_free_list);
@@ -2853,17 +2805,17 @@ static inline int __ipw2100_tx_process(struct ipw2100_priv *priv)
SET_STAT(&priv->txq_stat, txq->available);
IPW_DEBUG_TX("packet latency (send to process) %ld jiffies\n",
- jiffies - packet->jiffy_start);
+ jiffies - packet->jiffy_start);
return (!list_empty(&priv->fw_pend_list));
}
-
static inline void __ipw2100_tx_complete(struct ipw2100_priv *priv)
{
int i = 0;
- while (__ipw2100_tx_process(priv) && i < 200) i++;
+ while (__ipw2100_tx_process(priv) && i < 200)
+ i++;
if (i == 200) {
printk(KERN_WARNING DRV_NAME ": "
@@ -2872,7 +2824,6 @@ static inline void __ipw2100_tx_complete(struct ipw2100_priv *priv)
}
}
-
static void ipw2100_tx_send_commands(struct ipw2100_priv *priv)
{
struct list_head *element;
@@ -2897,13 +2848,12 @@ static void ipw2100_tx_send_commands(struct ipw2100_priv *priv)
list_del(element);
DEC_STAT(&priv->msg_pend_stat);
- packet = list_entry(element,
- struct ipw2100_tx_packet, list);
+ packet = list_entry(element, struct ipw2100_tx_packet, list);
IPW_DEBUG_TX("using TBD at virt=%p, phys=%p\n",
- &txq->drv[txq->next],
- (void*)(txq->nic + txq->next *
- sizeof(struct ipw2100_bd)));
+ &txq->drv[txq->next],
+ (void *)(txq->nic + txq->next *
+ sizeof(struct ipw2100_bd)));
packet->index = txq->next;
@@ -2916,8 +2866,8 @@ static void ipw2100_tx_send_commands(struct ipw2100_priv *priv)
* with f/w debug version */
tbd->num_fragments = 1;
tbd->status.info.field =
- IPW_BD_STATUS_TX_FRAME_COMMAND |
- IPW_BD_STATUS_TX_INTERRUPT_ENABLE;
+ IPW_BD_STATUS_TX_FRAME_COMMAND |
+ IPW_BD_STATUS_TX_INTERRUPT_ENABLE;
/* update TBD queue counters */
txq->next++;
@@ -2939,7 +2889,6 @@ static void ipw2100_tx_send_commands(struct ipw2100_priv *priv)
}
}
-
/*
* ipw2100_tx_send_data
*
@@ -2951,9 +2900,9 @@ static void ipw2100_tx_send_data(struct ipw2100_priv *priv)
struct ipw2100_bd_queue *txq = &priv->tx_queue;
struct ipw2100_bd *tbd;
int next = txq->next;
- int i = 0;
+ int i = 0;
struct ipw2100_data_header *ipw_hdr;
- struct ieee80211_hdr *hdr;
+ struct ieee80211_hdr_3addr *hdr;
while (!list_empty(&priv->tx_pend_list)) {
/* if there isn't enough space in TBD queue, then
@@ -2963,20 +2912,18 @@ static void ipw2100_tx_send_data(struct ipw2100_priv *priv)
* maintained between the r and w indexes
*/
element = priv->tx_pend_list.next;
- packet = list_entry(element, struct ipw2100_tx_packet, list);
+ packet = list_entry(element, struct ipw2100_tx_packet, list);
if (unlikely(1 + packet->info.d_struct.txb->nr_frags >
IPW_MAX_BDS)) {
/* TODO: Support merging buffers if more than
* IPW_MAX_BDS are used */
- IPW_DEBUG_INFO(
- "%s: Maximum BD theshold exceeded. "
- "Increase fragmentation level.\n",
- priv->net_dev->name);
+ IPW_DEBUG_INFO("%s: Maximum BD theshold exceeded. "
+ "Increase fragmentation level.\n",
+ priv->net_dev->name);
}
- if (txq->available <= 3 +
- packet->info.d_struct.txb->nr_frags) {
+ if (txq->available <= 3 + packet->info.d_struct.txb->nr_frags) {
IPW_DEBUG_TX("no room in tx_queue\n");
break;
}
@@ -2989,8 +2936,8 @@ static void ipw2100_tx_send_data(struct ipw2100_priv *priv)
packet->index = txq->next;
ipw_hdr = packet->info.d_struct.data;
- hdr = (struct ieee80211_hdr *)packet->info.d_struct.txb->
- fragments[0]->data;
+ hdr = (struct ieee80211_hdr_3addr *)packet->info.d_struct.txb->
+ fragments[0]->data;
if (priv->ieee->iw_mode == IW_MODE_INFRA) {
/* To DS: Addr1 = BSSID, Addr2 = SA,
@@ -3012,7 +2959,8 @@ static void ipw2100_tx_send_data(struct ipw2100_priv *priv)
ipw_hdr->encrypted = packet->info.d_struct.txb->encrypted;
if (packet->info.d_struct.txb->nr_frags > 1)
ipw_hdr->fragment_size =
- packet->info.d_struct.txb->frag_size - IEEE80211_3ADDR_LEN;
+ packet->info.d_struct.txb->frag_size -
+ IEEE80211_3ADDR_LEN;
else
ipw_hdr->fragment_size = 0;
@@ -3020,54 +2968,53 @@ static void ipw2100_tx_send_data(struct ipw2100_priv *priv)
tbd->buf_length = sizeof(struct ipw2100_data_header);
tbd->num_fragments = 1 + packet->info.d_struct.txb->nr_frags;
tbd->status.info.field =
- IPW_BD_STATUS_TX_FRAME_802_3 |
- IPW_BD_STATUS_TX_FRAME_NOT_LAST_FRAGMENT;
+ IPW_BD_STATUS_TX_FRAME_802_3 |
+ IPW_BD_STATUS_TX_FRAME_NOT_LAST_FRAGMENT;
txq->next++;
txq->next %= txq->entries;
- IPW_DEBUG_TX(
- "data header tbd TX%d P=%08x L=%d\n",
- packet->index, tbd->host_addr,
- tbd->buf_length);
+ IPW_DEBUG_TX("data header tbd TX%d P=%08x L=%d\n",
+ packet->index, tbd->host_addr, tbd->buf_length);
#ifdef CONFIG_IPW_DEBUG
if (packet->info.d_struct.txb->nr_frags > 1)
IPW_DEBUG_FRAG("fragment Tx: %d frames\n",
packet->info.d_struct.txb->nr_frags);
#endif
- for (i = 0; i < packet->info.d_struct.txb->nr_frags; i++) {
- tbd = &txq->drv[txq->next];
+ for (i = 0; i < packet->info.d_struct.txb->nr_frags; i++) {
+ tbd = &txq->drv[txq->next];
if (i == packet->info.d_struct.txb->nr_frags - 1)
tbd->status.info.field =
- IPW_BD_STATUS_TX_FRAME_802_3 |
- IPW_BD_STATUS_TX_INTERRUPT_ENABLE;
+ IPW_BD_STATUS_TX_FRAME_802_3 |
+ IPW_BD_STATUS_TX_INTERRUPT_ENABLE;
else
tbd->status.info.field =
- IPW_BD_STATUS_TX_FRAME_802_3 |
- IPW_BD_STATUS_TX_FRAME_NOT_LAST_FRAGMENT;
+ IPW_BD_STATUS_TX_FRAME_802_3 |
+ IPW_BD_STATUS_TX_FRAME_NOT_LAST_FRAGMENT;
tbd->buf_length = packet->info.d_struct.txb->
- fragments[i]->len - IEEE80211_3ADDR_LEN;
+ fragments[i]->len - IEEE80211_3ADDR_LEN;
- tbd->host_addr = pci_map_single(
- priv->pci_dev,
- packet->info.d_struct.txb->fragments[i]->data +
- IEEE80211_3ADDR_LEN,
- tbd->buf_length,
- PCI_DMA_TODEVICE);
+ tbd->host_addr = pci_map_single(priv->pci_dev,
+ packet->info.d_struct.
+ txb->fragments[i]->
+ data +
+ IEEE80211_3ADDR_LEN,
+ tbd->buf_length,
+ PCI_DMA_TODEVICE);
- IPW_DEBUG_TX(
- "data frag tbd TX%d P=%08x L=%d\n",
- txq->next, tbd->host_addr, tbd->buf_length);
+ IPW_DEBUG_TX("data frag tbd TX%d P=%08x L=%d\n",
+ txq->next, tbd->host_addr,
+ tbd->buf_length);
- pci_dma_sync_single_for_device(
- priv->pci_dev, tbd->host_addr,
- tbd->buf_length,
- PCI_DMA_TODEVICE);
+ pci_dma_sync_single_for_device(priv->pci_dev,
+ tbd->host_addr,
+ tbd->buf_length,
+ PCI_DMA_TODEVICE);
txq->next++;
txq->next %= txq->entries;
- }
+ }
txq->available -= 1 + packet->info.d_struct.txb->nr_frags;
SET_STAT(&priv->txq_stat, txq->available);
@@ -3083,7 +3030,7 @@ static void ipw2100_tx_send_data(struct ipw2100_priv *priv)
IPW_MEM_HOST_SHARED_TX_QUEUE_WRITE_INDEX,
txq->next);
}
- return;
+ return;
}
static void ipw2100_irq_tasklet(struct ipw2100_priv *priv)
@@ -3111,11 +3058,9 @@ static void ipw2100_irq_tasklet(struct ipw2100_priv *priv)
if (inta & IPW2100_INTA_FATAL_ERROR) {
printk(KERN_WARNING DRV_NAME
- ": Fatal interrupt. Scheduling firmware restart.\n");
+ ": Fatal interrupt. Scheduling firmware restart.\n");
priv->inta_other++;
- write_register(
- dev, IPW_REG_INTA,
- IPW2100_INTA_FATAL_ERROR);
+ write_register(dev, IPW_REG_INTA, IPW2100_INTA_FATAL_ERROR);
read_nic_dword(dev, IPW_NIC_FATAL_ERROR, &priv->fatal_error);
IPW_DEBUG_INFO("%s: Fatal error value: 0x%08X\n",
@@ -3130,11 +3075,10 @@ static void ipw2100_irq_tasklet(struct ipw2100_priv *priv)
}
if (inta & IPW2100_INTA_PARITY_ERROR) {
- printk(KERN_ERR DRV_NAME ": ***** PARITY ERROR INTERRUPT !!!! \n");
+ printk(KERN_ERR DRV_NAME
+ ": ***** PARITY ERROR INTERRUPT !!!! \n");
priv->inta_other++;
- write_register(
- dev, IPW_REG_INTA,
- IPW2100_INTA_PARITY_ERROR);
+ write_register(dev, IPW_REG_INTA, IPW2100_INTA_PARITY_ERROR);
}
if (inta & IPW2100_INTA_RX_TRANSFER) {
@@ -3142,9 +3086,7 @@ static void ipw2100_irq_tasklet(struct ipw2100_priv *priv)
priv->rx_interrupts++;
- write_register(
- dev, IPW_REG_INTA,
- IPW2100_INTA_RX_TRANSFER);
+ write_register(dev, IPW_REG_INTA, IPW2100_INTA_RX_TRANSFER);
__ipw2100_rx_process(priv);
__ipw2100_tx_complete(priv);
@@ -3155,8 +3097,7 @@ static void ipw2100_irq_tasklet(struct ipw2100_priv *priv)
priv->tx_interrupts++;
- write_register(dev, IPW_REG_INTA,
- IPW2100_INTA_TX_TRANSFER);
+ write_register(dev, IPW_REG_INTA, IPW2100_INTA_TX_TRANSFER);
__ipw2100_tx_complete(priv);
ipw2100_tx_send_commands(priv);
@@ -3166,9 +3107,7 @@ static void ipw2100_irq_tasklet(struct ipw2100_priv *priv)
if (inta & IPW2100_INTA_TX_COMPLETE) {
IPW_DEBUG_ISR("TX complete\n");
priv->inta_other++;
- write_register(
- dev, IPW_REG_INTA,
- IPW2100_INTA_TX_COMPLETE);
+ write_register(dev, IPW_REG_INTA, IPW2100_INTA_TX_COMPLETE);
__ipw2100_tx_complete(priv);
}
@@ -3176,9 +3115,7 @@ static void ipw2100_irq_tasklet(struct ipw2100_priv *priv)
if (inta & IPW2100_INTA_EVENT_INTERRUPT) {
/* ipw2100_handle_event(dev); */
priv->inta_other++;
- write_register(
- dev, IPW_REG_INTA,
- IPW2100_INTA_EVENT_INTERRUPT);
+ write_register(dev, IPW_REG_INTA, IPW2100_INTA_EVENT_INTERRUPT);
}
if (inta & IPW2100_INTA_FW_INIT_DONE) {
@@ -3188,30 +3125,25 @@ static void ipw2100_irq_tasklet(struct ipw2100_priv *priv)
read_register(dev, IPW_REG_INTA, &tmp);
if (tmp & (IPW2100_INTA_FATAL_ERROR |
IPW2100_INTA_PARITY_ERROR)) {
- write_register(
- dev, IPW_REG_INTA,
- IPW2100_INTA_FATAL_ERROR |
- IPW2100_INTA_PARITY_ERROR);
+ write_register(dev, IPW_REG_INTA,
+ IPW2100_INTA_FATAL_ERROR |
+ IPW2100_INTA_PARITY_ERROR);
}
- write_register(dev, IPW_REG_INTA,
- IPW2100_INTA_FW_INIT_DONE);
+ write_register(dev, IPW_REG_INTA, IPW2100_INTA_FW_INIT_DONE);
}
if (inta & IPW2100_INTA_STATUS_CHANGE) {
IPW_DEBUG_ISR("Status change interrupt\n");
priv->inta_other++;
- write_register(
- dev, IPW_REG_INTA,
- IPW2100_INTA_STATUS_CHANGE);
+ write_register(dev, IPW_REG_INTA, IPW2100_INTA_STATUS_CHANGE);
}
if (inta & IPW2100_INTA_SLAVE_MODE_HOST_COMMAND_DONE) {
IPW_DEBUG_ISR("slave host mode interrupt\n");
priv->inta_other++;
- write_register(
- dev, IPW_REG_INTA,
- IPW2100_INTA_SLAVE_MODE_HOST_COMMAND_DONE);
+ write_register(dev, IPW_REG_INTA,
+ IPW2100_INTA_SLAVE_MODE_HOST_COMMAND_DONE);
}
priv->in_isr--;
@@ -3222,9 +3154,7 @@ static void ipw2100_irq_tasklet(struct ipw2100_priv *priv)
IPW_DEBUG_ISR("exit\n");
}
-
-static irqreturn_t ipw2100_interrupt(int irq, void *data,
- struct pt_regs *regs)
+static irqreturn_t ipw2100_interrupt(int irq, void *data, struct pt_regs *regs)
{
struct ipw2100_priv *priv = data;
u32 inta, inta_mask;
@@ -3232,7 +3162,7 @@ static irqreturn_t ipw2100_interrupt(int irq, void *data,
if (!data)
return IRQ_NONE;
- spin_lock(&priv->low_lock);
+ spin_lock(&priv->low_lock);
/* We check to see if we should be ignoring interrupts before
* we touch the hardware. During ucode load if we try and handle
@@ -3266,15 +3196,16 @@ static irqreturn_t ipw2100_interrupt(int irq, void *data,
ipw2100_disable_interrupts(priv);
tasklet_schedule(&priv->irq_tasklet);
- spin_unlock(&priv->low_lock);
+ spin_unlock(&priv->low_lock);
return IRQ_HANDLED;
- none:
+ none:
spin_unlock(&priv->low_lock);
return IRQ_NONE;
}
-static int ipw2100_tx(struct ieee80211_txb *txb, struct net_device *dev)
+static int ipw2100_tx(struct ieee80211_txb *txb, struct net_device *dev,
+ int pri)
{
struct ipw2100_priv *priv = ieee80211_priv(dev);
struct list_head *element;
@@ -3298,10 +3229,8 @@ static int ipw2100_tx(struct ieee80211_txb *txb, struct net_device *dev)
packet->info.d_struct.txb = txb;
- IPW_DEBUG_TX("Sending fragment (%d bytes):\n",
- txb->fragments[0]->len);
- printk_buf(IPW_DL_TX, txb->fragments[0]->data,
- txb->fragments[0]->len);
+ IPW_DEBUG_TX("Sending fragment (%d bytes):\n", txb->fragments[0]->len);
+ printk_buf(IPW_DL_TX, txb->fragments[0]->data, txb->fragments[0]->len);
packet->jiffy_start = jiffies;
@@ -3316,22 +3245,23 @@ static int ipw2100_tx(struct ieee80211_txb *txb, struct net_device *dev)
spin_unlock_irqrestore(&priv->low_lock, flags);
return 0;
- fail_unlock:
+ fail_unlock:
netif_stop_queue(dev);
spin_unlock_irqrestore(&priv->low_lock, flags);
return 1;
}
-
static int ipw2100_msg_allocate(struct ipw2100_priv *priv)
{
int i, j, err = -EINVAL;
void *v;
dma_addr_t p;
- priv->msg_buffers = (struct ipw2100_tx_packet *)kmalloc(
- IPW_COMMAND_POOL_SIZE * sizeof(struct ipw2100_tx_packet),
- GFP_KERNEL);
+ priv->msg_buffers =
+ (struct ipw2100_tx_packet *)kmalloc(IPW_COMMAND_POOL_SIZE *
+ sizeof(struct
+ ipw2100_tx_packet),
+ GFP_KERNEL);
if (!priv->msg_buffers) {
printk(KERN_ERR DRV_NAME ": %s: PCI alloc failed for msg "
"buffers.\n", priv->net_dev->name);
@@ -3339,15 +3269,12 @@ static int ipw2100_msg_allocate(struct ipw2100_priv *priv)
}
for (i = 0; i < IPW_COMMAND_POOL_SIZE; i++) {
- v = pci_alloc_consistent(
- priv->pci_dev,
- sizeof(struct ipw2100_cmd_header),
- &p);
+ v = pci_alloc_consistent(priv->pci_dev,
+ sizeof(struct ipw2100_cmd_header), &p);
if (!v) {
printk(KERN_ERR DRV_NAME ": "
"%s: PCI alloc failed for msg "
- "buffers.\n",
- priv->net_dev->name);
+ "buffers.\n", priv->net_dev->name);
err = -ENOMEM;
break;
}
@@ -3356,7 +3283,7 @@ static int ipw2100_msg_allocate(struct ipw2100_priv *priv)
priv->msg_buffers[i].type = COMMAND;
priv->msg_buffers[i].info.c_struct.cmd =
- (struct ipw2100_cmd_header*)v;
+ (struct ipw2100_cmd_header *)v;
priv->msg_buffers[i].info.c_struct.cmd_phys = p;
}
@@ -3364,11 +3291,11 @@ static int ipw2100_msg_allocate(struct ipw2100_priv *priv)
return 0;
for (j = 0; j < i; j++) {
- pci_free_consistent(
- priv->pci_dev,
- sizeof(struct ipw2100_cmd_header),
- priv->msg_buffers[j].info.c_struct.cmd,
- priv->msg_buffers[j].info.c_struct.cmd_phys);
+ pci_free_consistent(priv->pci_dev,
+ sizeof(struct ipw2100_cmd_header),
+ priv->msg_buffers[j].info.c_struct.cmd,
+ priv->msg_buffers[j].info.c_struct.
+ cmd_phys);
}
kfree(priv->msg_buffers);
@@ -3402,7 +3329,8 @@ static void ipw2100_msg_free(struct ipw2100_priv *priv)
pci_free_consistent(priv->pci_dev,
sizeof(struct ipw2100_cmd_header),
priv->msg_buffers[i].info.c_struct.cmd,
- priv->msg_buffers[i].info.c_struct.cmd_phys);
+ priv->msg_buffers[i].info.c_struct.
+ cmd_phys);
}
kfree(priv->msg_buffers);
@@ -3428,6 +3356,7 @@ static ssize_t show_pci(struct device *d, struct device_attribute *attr,
return out - buf;
}
+
static DEVICE_ATTR(pci, S_IRUGO, show_pci, NULL);
static ssize_t show_cfg(struct device *d, struct device_attribute *attr,
@@ -3436,209 +3365,269 @@ static ssize_t show_cfg(struct device *d, struct device_attribute *attr,
struct ipw2100_priv *p = d->driver_data;
return sprintf(buf, "0x%08x\n", (int)p->config);
}
+
static DEVICE_ATTR(cfg, S_IRUGO, show_cfg, NULL);
static ssize_t show_status(struct device *d, struct device_attribute *attr,
- char *buf)
+ char *buf)
{
struct ipw2100_priv *p = d->driver_data;
return sprintf(buf, "0x%08x\n", (int)p->status);
}
+
static DEVICE_ATTR(status, S_IRUGO, show_status, NULL);
static ssize_t show_capability(struct device *d, struct device_attribute *attr,
- char *buf)
+ char *buf)
{
struct ipw2100_priv *p = d->driver_data;
return sprintf(buf, "0x%08x\n", (int)p->capability);
}
-static DEVICE_ATTR(capability, S_IRUGO, show_capability, NULL);
+static DEVICE_ATTR(capability, S_IRUGO, show_capability, NULL);
#define IPW2100_REG(x) { IPW_ ##x, #x }
static const struct {
u32 addr;
const char *name;
} hw_data[] = {
- IPW2100_REG(REG_GP_CNTRL),
- IPW2100_REG(REG_GPIO),
- IPW2100_REG(REG_INTA),
- IPW2100_REG(REG_INTA_MASK),
- IPW2100_REG(REG_RESET_REG),
-};
+IPW2100_REG(REG_GP_CNTRL),
+ IPW2100_REG(REG_GPIO),
+ IPW2100_REG(REG_INTA),
+ IPW2100_REG(REG_INTA_MASK), IPW2100_REG(REG_RESET_REG),};
#define IPW2100_NIC(x, s) { x, #x, s }
static const struct {
u32 addr;
const char *name;
size_t size;
} nic_data[] = {
- IPW2100_NIC(IPW2100_CONTROL_REG, 2),
- IPW2100_NIC(0x210014, 1),
- IPW2100_NIC(0x210000, 1),
-};
+IPW2100_NIC(IPW2100_CONTROL_REG, 2),
+ IPW2100_NIC(0x210014, 1), IPW2100_NIC(0x210000, 1),};
#define IPW2100_ORD(x, d) { IPW_ORD_ ##x, #x, d }
static const struct {
u8 index;
const char *name;
const char *desc;
} ord_data[] = {
- IPW2100_ORD(STAT_TX_HOST_REQUESTS, "requested Host Tx's (MSDU)"),
- IPW2100_ORD(STAT_TX_HOST_COMPLETE, "successful Host Tx's (MSDU)"),
- IPW2100_ORD(STAT_TX_DIR_DATA, "successful Directed Tx's (MSDU)"),
- IPW2100_ORD(STAT_TX_DIR_DATA1, "successful Directed Tx's (MSDU) @ 1MB"),
- IPW2100_ORD(STAT_TX_DIR_DATA2, "successful Directed Tx's (MSDU) @ 2MB"),
- IPW2100_ORD(STAT_TX_DIR_DATA5_5, "successful Directed Tx's (MSDU) @ 5_5MB"),
- IPW2100_ORD(STAT_TX_DIR_DATA11, "successful Directed Tx's (MSDU) @ 11MB"),
- IPW2100_ORD(STAT_TX_NODIR_DATA1, "successful Non_Directed Tx's (MSDU) @ 1MB"),
- IPW2100_ORD(STAT_TX_NODIR_DATA2, "successful Non_Directed Tx's (MSDU) @ 2MB"),
- IPW2100_ORD(STAT_TX_NODIR_DATA5_5, "successful Non_Directed Tx's (MSDU) @ 5.5MB"),
- IPW2100_ORD(STAT_TX_NODIR_DATA11, "successful Non_Directed Tx's (MSDU) @ 11MB"),
- IPW2100_ORD(STAT_NULL_DATA, "successful NULL data Tx's"),
- IPW2100_ORD(STAT_TX_RTS, "successful Tx RTS"),
- IPW2100_ORD(STAT_TX_CTS, "successful Tx CTS"),
- IPW2100_ORD(STAT_TX_ACK, "successful Tx ACK"),
- IPW2100_ORD(STAT_TX_ASSN, "successful Association Tx's"),
- IPW2100_ORD(STAT_TX_ASSN_RESP, "successful Association response Tx's"),
- IPW2100_ORD(STAT_TX_REASSN, "successful Reassociation Tx's"),
- IPW2100_ORD(STAT_TX_REASSN_RESP, "successful Reassociation response Tx's"),
- IPW2100_ORD(STAT_TX_PROBE, "probes successfully transmitted"),
- IPW2100_ORD(STAT_TX_PROBE_RESP, "probe responses successfully transmitted"),
- IPW2100_ORD(STAT_TX_BEACON, "tx beacon"),
- IPW2100_ORD(STAT_TX_ATIM, "Tx ATIM"),
- IPW2100_ORD(STAT_TX_DISASSN, "successful Disassociation TX"),
- IPW2100_ORD(STAT_TX_AUTH, "successful Authentication Tx"),
- IPW2100_ORD(STAT_TX_DEAUTH, "successful Deauthentication TX"),
- IPW2100_ORD(STAT_TX_TOTAL_BYTES, "Total successful Tx data bytes"),
- IPW2100_ORD(STAT_TX_RETRIES, "Tx retries"),
- IPW2100_ORD(STAT_TX_RETRY1, "Tx retries at 1MBPS"),
- IPW2100_ORD(STAT_TX_RETRY2, "Tx retries at 2MBPS"),
- IPW2100_ORD(STAT_TX_RETRY5_5, "Tx retries at 5.5MBPS"),
- IPW2100_ORD(STAT_TX_RETRY11, "Tx retries at 11MBPS"),
- IPW2100_ORD(STAT_TX_FAILURES, "Tx Failures"),
- IPW2100_ORD(STAT_TX_MAX_TRIES_IN_HOP,"times max tries in a hop failed"),
- IPW2100_ORD(STAT_TX_DISASSN_FAIL, "times disassociation failed"),
- IPW2100_ORD(STAT_TX_ERR_CTS, "missed/bad CTS frames"),
- IPW2100_ORD(STAT_TX_ERR_ACK, "tx err due to acks"),
- IPW2100_ORD(STAT_RX_HOST, "packets passed to host"),
- IPW2100_ORD(STAT_RX_DIR_DATA, "directed packets"),
- IPW2100_ORD(STAT_RX_DIR_DATA1, "directed packets at 1MB"),
- IPW2100_ORD(STAT_RX_DIR_DATA2, "directed packets at 2MB"),
- IPW2100_ORD(STAT_RX_DIR_DATA5_5, "directed packets at 5.5MB"),
- IPW2100_ORD(STAT_RX_DIR_DATA11, "directed packets at 11MB"),
- IPW2100_ORD(STAT_RX_NODIR_DATA,"nondirected packets"),
- IPW2100_ORD(STAT_RX_NODIR_DATA1, "nondirected packets at 1MB"),
- IPW2100_ORD(STAT_RX_NODIR_DATA2, "nondirected packets at 2MB"),
- IPW2100_ORD(STAT_RX_NODIR_DATA5_5, "nondirected packets at 5.5MB"),
- IPW2100_ORD(STAT_RX_NODIR_DATA11, "nondirected packets at 11MB"),
- IPW2100_ORD(STAT_RX_NULL_DATA, "null data rx's"),
- IPW2100_ORD(STAT_RX_RTS, "Rx RTS"),
- IPW2100_ORD(STAT_RX_CTS, "Rx CTS"),
- IPW2100_ORD(STAT_RX_ACK, "Rx ACK"),
- IPW2100_ORD(STAT_RX_CFEND, "Rx CF End"),
- IPW2100_ORD(STAT_RX_CFEND_ACK, "Rx CF End + CF Ack"),
- IPW2100_ORD(STAT_RX_ASSN, "Association Rx's"),
- IPW2100_ORD(STAT_RX_ASSN_RESP, "Association response Rx's"),
- IPW2100_ORD(STAT_RX_REASSN, "Reassociation Rx's"),
- IPW2100_ORD(STAT_RX_REASSN_RESP, "Reassociation response Rx's"),
- IPW2100_ORD(STAT_RX_PROBE, "probe Rx's"),
- IPW2100_ORD(STAT_RX_PROBE_RESP, "probe response Rx's"),
- IPW2100_ORD(STAT_RX_BEACON, "Rx beacon"),
- IPW2100_ORD(STAT_RX_ATIM, "Rx ATIM"),
- IPW2100_ORD(STAT_RX_DISASSN, "disassociation Rx"),
- IPW2100_ORD(STAT_RX_AUTH, "authentication Rx"),
- IPW2100_ORD(STAT_RX_DEAUTH, "deauthentication Rx"),
- IPW2100_ORD(STAT_RX_TOTAL_BYTES,"Total rx data bytes received"),
- IPW2100_ORD(STAT_RX_ERR_CRC, "packets with Rx CRC error"),
- IPW2100_ORD(STAT_RX_ERR_CRC1, "Rx CRC errors at 1MB"),
- IPW2100_ORD(STAT_RX_ERR_CRC2, "Rx CRC errors at 2MB"),
- IPW2100_ORD(STAT_RX_ERR_CRC5_5, "Rx CRC errors at 5.5MB"),
- IPW2100_ORD(STAT_RX_ERR_CRC11, "Rx CRC errors at 11MB"),
- IPW2100_ORD(STAT_RX_DUPLICATE1, "duplicate rx packets at 1MB"),
- IPW2100_ORD(STAT_RX_DUPLICATE2, "duplicate rx packets at 2MB"),
- IPW2100_ORD(STAT_RX_DUPLICATE5_5, "duplicate rx packets at 5.5MB"),
- IPW2100_ORD(STAT_RX_DUPLICATE11, "duplicate rx packets at 11MB"),
- IPW2100_ORD(STAT_RX_DUPLICATE, "duplicate rx packets"),
- IPW2100_ORD(PERS_DB_LOCK, "locking fw permanent db"),
- IPW2100_ORD(PERS_DB_SIZE, "size of fw permanent db"),
- IPW2100_ORD(PERS_DB_ADDR, "address of fw permanent db"),
- IPW2100_ORD(STAT_RX_INVALID_PROTOCOL, "rx frames with invalid protocol"),
- IPW2100_ORD(SYS_BOOT_TIME, "Boot time"),
- IPW2100_ORD(STAT_RX_NO_BUFFER, "rx frames rejected due to no buffer"),
- IPW2100_ORD(STAT_RX_MISSING_FRAG, "rx frames dropped due to missing fragment"),
- IPW2100_ORD(STAT_RX_ORPHAN_FRAG, "rx frames dropped due to non-sequential fragment"),
- IPW2100_ORD(STAT_RX_ORPHAN_FRAME, "rx frames dropped due to unmatched 1st frame"),
- IPW2100_ORD(STAT_RX_FRAG_AGEOUT, "rx frames dropped due to uncompleted frame"),
- IPW2100_ORD(STAT_RX_ICV_ERRORS, "ICV errors during decryption"),
- IPW2100_ORD(STAT_PSP_SUSPENSION,"times adapter suspended"),
- IPW2100_ORD(STAT_PSP_BCN_TIMEOUT, "beacon timeout"),
- IPW2100_ORD(STAT_PSP_POLL_TIMEOUT, "poll response timeouts"),
- IPW2100_ORD(STAT_PSP_NONDIR_TIMEOUT, "timeouts waiting for last {broad,multi}cast pkt"),
- IPW2100_ORD(STAT_PSP_RX_DTIMS, "PSP DTIMs received"),
- IPW2100_ORD(STAT_PSP_RX_TIMS, "PSP TIMs received"),
- IPW2100_ORD(STAT_PSP_STATION_ID,"PSP Station ID"),
- IPW2100_ORD(LAST_ASSN_TIME, "RTC time of last association"),
- IPW2100_ORD(STAT_PERCENT_MISSED_BCNS,"current calculation of % missed beacons"),
- IPW2100_ORD(STAT_PERCENT_RETRIES,"current calculation of % missed tx retries"),
- IPW2100_ORD(ASSOCIATED_AP_PTR, "0 if not associated, else pointer to AP table entry"),
- IPW2100_ORD(AVAILABLE_AP_CNT, "AP's decsribed in the AP table"),
- IPW2100_ORD(AP_LIST_PTR, "Ptr to list of available APs"),
- IPW2100_ORD(STAT_AP_ASSNS, "associations"),
- IPW2100_ORD(STAT_ASSN_FAIL, "association failures"),
- IPW2100_ORD(STAT_ASSN_RESP_FAIL,"failures due to response fail"),
- IPW2100_ORD(STAT_FULL_SCANS, "full scans"),
- IPW2100_ORD(CARD_DISABLED, "Card Disabled"),
- IPW2100_ORD(STAT_ROAM_INHIBIT, "times roaming was inhibited due to activity"),
- IPW2100_ORD(RSSI_AT_ASSN, "RSSI of associated AP at time of association"),
- IPW2100_ORD(STAT_ASSN_CAUSE1, "reassociation: no probe response or TX on hop"),
- IPW2100_ORD(STAT_ASSN_CAUSE2, "reassociation: poor tx/rx quality"),
- IPW2100_ORD(STAT_ASSN_CAUSE3, "reassociation: tx/rx quality (excessive AP load"),
- IPW2100_ORD(STAT_ASSN_CAUSE4, "reassociation: AP RSSI level"),
- IPW2100_ORD(STAT_ASSN_CAUSE5, "reassociations due to load leveling"),
- IPW2100_ORD(STAT_AUTH_FAIL, "times authentication failed"),
- IPW2100_ORD(STAT_AUTH_RESP_FAIL,"times authentication response failed"),
- IPW2100_ORD(STATION_TABLE_CNT, "entries in association table"),
- IPW2100_ORD(RSSI_AVG_CURR, "Current avg RSSI"),
- IPW2100_ORD(POWER_MGMT_MODE, "Power mode - 0=CAM, 1=PSP"),
- IPW2100_ORD(COUNTRY_CODE, "IEEE country code as recv'd from beacon"),
- IPW2100_ORD(COUNTRY_CHANNELS, "channels suported by country"),
- IPW2100_ORD(RESET_CNT, "adapter resets (warm)"),
- IPW2100_ORD(BEACON_INTERVAL, "Beacon interval"),
- IPW2100_ORD(ANTENNA_DIVERSITY, "TRUE if antenna diversity is disabled"),
- IPW2100_ORD(DTIM_PERIOD, "beacon intervals between DTIMs"),
- IPW2100_ORD(OUR_FREQ, "current radio freq lower digits - channel ID"),
- IPW2100_ORD(RTC_TIME, "current RTC time"),
- IPW2100_ORD(PORT_TYPE, "operating mode"),
- IPW2100_ORD(CURRENT_TX_RATE, "current tx rate"),
- IPW2100_ORD(SUPPORTED_RATES, "supported tx rates"),
- IPW2100_ORD(ATIM_WINDOW, "current ATIM Window"),
- IPW2100_ORD(BASIC_RATES, "basic tx rates"),
- IPW2100_ORD(NIC_HIGHEST_RATE, "NIC highest tx rate"),
- IPW2100_ORD(AP_HIGHEST_RATE, "AP highest tx rate"),
- IPW2100_ORD(CAPABILITIES, "Management frame capability field"),
- IPW2100_ORD(AUTH_TYPE, "Type of authentication"),
- IPW2100_ORD(RADIO_TYPE, "Adapter card platform type"),
- IPW2100_ORD(RTS_THRESHOLD, "Min packet length for RTS handshaking"),
- IPW2100_ORD(INT_MODE, "International mode"),
- IPW2100_ORD(FRAGMENTATION_THRESHOLD, "protocol frag threshold"),
- IPW2100_ORD(EEPROM_SRAM_DB_BLOCK_START_ADDRESS, "EEPROM offset in SRAM"),
- IPW2100_ORD(EEPROM_SRAM_DB_BLOCK_SIZE, "EEPROM size in SRAM"),
- IPW2100_ORD(EEPROM_SKU_CAPABILITY, "EEPROM SKU Capability"),
- IPW2100_ORD(EEPROM_IBSS_11B_CHANNELS, "EEPROM IBSS 11b channel set"),
- IPW2100_ORD(MAC_VERSION, "MAC Version"),
- IPW2100_ORD(MAC_REVISION, "MAC Revision"),
- IPW2100_ORD(RADIO_VERSION, "Radio Version"),
- IPW2100_ORD(NIC_MANF_DATE_TIME, "MANF Date/Time STAMP"),
- IPW2100_ORD(UCODE_VERSION, "Ucode Version"),
-};
-
+IPW2100_ORD(STAT_TX_HOST_REQUESTS, "requested Host Tx's (MSDU)"),
+ IPW2100_ORD(STAT_TX_HOST_COMPLETE,
+ "successful Host Tx's (MSDU)"),
+ IPW2100_ORD(STAT_TX_DIR_DATA,
+ "successful Directed Tx's (MSDU)"),
+ IPW2100_ORD(STAT_TX_DIR_DATA1,
+ "successful Directed Tx's (MSDU) @ 1MB"),
+ IPW2100_ORD(STAT_TX_DIR_DATA2,
+ "successful Directed Tx's (MSDU) @ 2MB"),
+ IPW2100_ORD(STAT_TX_DIR_DATA5_5,
+ "successful Directed Tx's (MSDU) @ 5_5MB"),
+ IPW2100_ORD(STAT_TX_DIR_DATA11,
+ "successful Directed Tx's (MSDU) @ 11MB"),
+ IPW2100_ORD(STAT_TX_NODIR_DATA1,
+ "successful Non_Directed Tx's (MSDU) @ 1MB"),
+ IPW2100_ORD(STAT_TX_NODIR_DATA2,
+ "successful Non_Directed Tx's (MSDU) @ 2MB"),
+ IPW2100_ORD(STAT_TX_NODIR_DATA5_5,
+ "successful Non_Directed Tx's (MSDU) @ 5.5MB"),
+ IPW2100_ORD(STAT_TX_NODIR_DATA11,
+ "successful Non_Directed Tx's (MSDU) @ 11MB"),
+ IPW2100_ORD(STAT_NULL_DATA, "successful NULL data Tx's"),
+ IPW2100_ORD(STAT_TX_RTS, "successful Tx RTS"),
+ IPW2100_ORD(STAT_TX_CTS, "successful Tx CTS"),
+ IPW2100_ORD(STAT_TX_ACK, "successful Tx ACK"),
+ IPW2100_ORD(STAT_TX_ASSN, "successful Association Tx's"),
+ IPW2100_ORD(STAT_TX_ASSN_RESP,
+ "successful Association response Tx's"),
+ IPW2100_ORD(STAT_TX_REASSN,
+ "successful Reassociation Tx's"),
+ IPW2100_ORD(STAT_TX_REASSN_RESP,
+ "successful Reassociation response Tx's"),
+ IPW2100_ORD(STAT_TX_PROBE,
+ "probes successfully transmitted"),
+ IPW2100_ORD(STAT_TX_PROBE_RESP,
+ "probe responses successfully transmitted"),
+ IPW2100_ORD(STAT_TX_BEACON, "tx beacon"),
+ IPW2100_ORD(STAT_TX_ATIM, "Tx ATIM"),
+ IPW2100_ORD(STAT_TX_DISASSN,
+ "successful Disassociation TX"),
+ IPW2100_ORD(STAT_TX_AUTH, "successful Authentication Tx"),
+ IPW2100_ORD(STAT_TX_DEAUTH,
+ "successful Deauthentication TX"),
+ IPW2100_ORD(STAT_TX_TOTAL_BYTES,
+ "Total successful Tx data bytes"),
+ IPW2100_ORD(STAT_TX_RETRIES, "Tx retries"),
+ IPW2100_ORD(STAT_TX_RETRY1, "Tx retries at 1MBPS"),
+ IPW2100_ORD(STAT_TX_RETRY2, "Tx retries at 2MBPS"),
+ IPW2100_ORD(STAT_TX_RETRY5_5, "Tx retries at 5.5MBPS"),
+ IPW2100_ORD(STAT_TX_RETRY11, "Tx retries at 11MBPS"),
+ IPW2100_ORD(STAT_TX_FAILURES, "Tx Failures"),
+ IPW2100_ORD(STAT_TX_MAX_TRIES_IN_HOP,
+ "times max tries in a hop failed"),
+ IPW2100_ORD(STAT_TX_DISASSN_FAIL,
+ "times disassociation failed"),
+ IPW2100_ORD(STAT_TX_ERR_CTS, "missed/bad CTS frames"),
+ IPW2100_ORD(STAT_TX_ERR_ACK, "tx err due to acks"),
+ IPW2100_ORD(STAT_RX_HOST, "packets passed to host"),
+ IPW2100_ORD(STAT_RX_DIR_DATA, "directed packets"),
+ IPW2100_ORD(STAT_RX_DIR_DATA1, "directed packets at 1MB"),
+ IPW2100_ORD(STAT_RX_DIR_DATA2, "directed packets at 2MB"),
+ IPW2100_ORD(STAT_RX_DIR_DATA5_5,
+ "directed packets at 5.5MB"),
+ IPW2100_ORD(STAT_RX_DIR_DATA11, "directed packets at 11MB"),
+ IPW2100_ORD(STAT_RX_NODIR_DATA, "nondirected packets"),
+ IPW2100_ORD(STAT_RX_NODIR_DATA1,
+ "nondirected packets at 1MB"),
+ IPW2100_ORD(STAT_RX_NODIR_DATA2,
+ "nondirected packets at 2MB"),
+ IPW2100_ORD(STAT_RX_NODIR_DATA5_5,
+ "nondirected packets at 5.5MB"),
+ IPW2100_ORD(STAT_RX_NODIR_DATA11,
+ "nondirected packets at 11MB"),
+ IPW2100_ORD(STAT_RX_NULL_DATA, "null data rx's"),
+ IPW2100_ORD(STAT_RX_RTS, "Rx RTS"), IPW2100_ORD(STAT_RX_CTS,
+ "Rx CTS"),
+ IPW2100_ORD(STAT_RX_ACK, "Rx ACK"),
+ IPW2100_ORD(STAT_RX_CFEND, "Rx CF End"),
+ IPW2100_ORD(STAT_RX_CFEND_ACK, "Rx CF End + CF Ack"),
+ IPW2100_ORD(STAT_RX_ASSN, "Association Rx's"),
+ IPW2100_ORD(STAT_RX_ASSN_RESP, "Association response Rx's"),
+ IPW2100_ORD(STAT_RX_REASSN, "Reassociation Rx's"),
+ IPW2100_ORD(STAT_RX_REASSN_RESP,
+ "Reassociation response Rx's"),
+ IPW2100_ORD(STAT_RX_PROBE, "probe Rx's"),
+ IPW2100_ORD(STAT_RX_PROBE_RESP, "probe response Rx's"),
+ IPW2100_ORD(STAT_RX_BEACON, "Rx beacon"),
+ IPW2100_ORD(STAT_RX_ATIM, "Rx ATIM"),
+ IPW2100_ORD(STAT_RX_DISASSN, "disassociation Rx"),
+ IPW2100_ORD(STAT_RX_AUTH, "authentication Rx"),
+ IPW2100_ORD(STAT_RX_DEAUTH, "deauthentication Rx"),
+ IPW2100_ORD(STAT_RX_TOTAL_BYTES,
+ "Total rx data bytes received"),
+ IPW2100_ORD(STAT_RX_ERR_CRC, "packets with Rx CRC error"),
+ IPW2100_ORD(STAT_RX_ERR_CRC1, "Rx CRC errors at 1MB"),
+ IPW2100_ORD(STAT_RX_ERR_CRC2, "Rx CRC errors at 2MB"),
+ IPW2100_ORD(STAT_RX_ERR_CRC5_5, "Rx CRC errors at 5.5MB"),
+ IPW2100_ORD(STAT_RX_ERR_CRC11, "Rx CRC errors at 11MB"),
+ IPW2100_ORD(STAT_RX_DUPLICATE1,
+ "duplicate rx packets at 1MB"),
+ IPW2100_ORD(STAT_RX_DUPLICATE2,
+ "duplicate rx packets at 2MB"),
+ IPW2100_ORD(STAT_RX_DUPLICATE5_5,
+ "duplicate rx packets at 5.5MB"),
+ IPW2100_ORD(STAT_RX_DUPLICATE11,
+ "duplicate rx packets at 11MB"),
+ IPW2100_ORD(STAT_RX_DUPLICATE, "duplicate rx packets"),
+ IPW2100_ORD(PERS_DB_LOCK, "locking fw permanent db"),
+ IPW2100_ORD(PERS_DB_SIZE, "size of fw permanent db"),
+ IPW2100_ORD(PERS_DB_ADDR, "address of fw permanent db"),
+ IPW2100_ORD(STAT_RX_INVALID_PROTOCOL,
+ "rx frames with invalid protocol"),
+ IPW2100_ORD(SYS_BOOT_TIME, "Boot time"),
+ IPW2100_ORD(STAT_RX_NO_BUFFER,
+ "rx frames rejected due to no buffer"),
+ IPW2100_ORD(STAT_RX_MISSING_FRAG,
+ "rx frames dropped due to missing fragment"),
+ IPW2100_ORD(STAT_RX_ORPHAN_FRAG,
+ "rx frames dropped due to non-sequential fragment"),
+ IPW2100_ORD(STAT_RX_ORPHAN_FRAME,
+ "rx frames dropped due to unmatched 1st frame"),
+ IPW2100_ORD(STAT_RX_FRAG_AGEOUT,
+ "rx frames dropped due to uncompleted frame"),
+ IPW2100_ORD(STAT_RX_ICV_ERRORS,
+ "ICV errors during decryption"),
+ IPW2100_ORD(STAT_PSP_SUSPENSION, "times adapter suspended"),
+ IPW2100_ORD(STAT_PSP_BCN_TIMEOUT, "beacon timeout"),
+ IPW2100_ORD(STAT_PSP_POLL_TIMEOUT,
+ "poll response timeouts"),
+ IPW2100_ORD(STAT_PSP_NONDIR_TIMEOUT,
+ "timeouts waiting for last {broad,multi}cast pkt"),
+ IPW2100_ORD(STAT_PSP_RX_DTIMS, "PSP DTIMs received"),
+ IPW2100_ORD(STAT_PSP_RX_TIMS, "PSP TIMs received"),
+ IPW2100_ORD(STAT_PSP_STATION_ID, "PSP Station ID"),
+ IPW2100_ORD(LAST_ASSN_TIME, "RTC time of last association"),
+ IPW2100_ORD(STAT_PERCENT_MISSED_BCNS,
+ "current calculation of % missed beacons"),
+ IPW2100_ORD(STAT_PERCENT_RETRIES,
+ "current calculation of % missed tx retries"),
+ IPW2100_ORD(ASSOCIATED_AP_PTR,
+ "0 if not associated, else pointer to AP table entry"),
+ IPW2100_ORD(AVAILABLE_AP_CNT,
+ "AP's decsribed in the AP table"),
+ IPW2100_ORD(AP_LIST_PTR, "Ptr to list of available APs"),
+ IPW2100_ORD(STAT_AP_ASSNS, "associations"),
+ IPW2100_ORD(STAT_ASSN_FAIL, "association failures"),
+ IPW2100_ORD(STAT_ASSN_RESP_FAIL,
+ "failures due to response fail"),
+ IPW2100_ORD(STAT_FULL_SCANS, "full scans"),
+ IPW2100_ORD(CARD_DISABLED, "Card Disabled"),
+ IPW2100_ORD(STAT_ROAM_INHIBIT,
+ "times roaming was inhibited due to activity"),
+ IPW2100_ORD(RSSI_AT_ASSN,
+ "RSSI of associated AP at time of association"),
+ IPW2100_ORD(STAT_ASSN_CAUSE1,
+ "reassociation: no probe response or TX on hop"),
+ IPW2100_ORD(STAT_ASSN_CAUSE2,
+ "reassociation: poor tx/rx quality"),
+ IPW2100_ORD(STAT_ASSN_CAUSE3,
+ "reassociation: tx/rx quality (excessive AP load"),
+ IPW2100_ORD(STAT_ASSN_CAUSE4,
+ "reassociation: AP RSSI level"),
+ IPW2100_ORD(STAT_ASSN_CAUSE5,
+ "reassociations due to load leveling"),
+ IPW2100_ORD(STAT_AUTH_FAIL, "times authentication failed"),
+ IPW2100_ORD(STAT_AUTH_RESP_FAIL,
+ "times authentication response failed"),
+ IPW2100_ORD(STATION_TABLE_CNT,
+ "entries in association table"),
+ IPW2100_ORD(RSSI_AVG_CURR, "Current avg RSSI"),
+ IPW2100_ORD(POWER_MGMT_MODE, "Power mode - 0=CAM, 1=PSP"),
+ IPW2100_ORD(COUNTRY_CODE,
+ "IEEE country code as recv'd from beacon"),
+ IPW2100_ORD(COUNTRY_CHANNELS,
+ "channels suported by country"),
+ IPW2100_ORD(RESET_CNT, "adapter resets (warm)"),
+ IPW2100_ORD(BEACON_INTERVAL, "Beacon interval"),
+ IPW2100_ORD(ANTENNA_DIVERSITY,
+ "TRUE if antenna diversity is disabled"),
+ IPW2100_ORD(DTIM_PERIOD, "beacon intervals between DTIMs"),
+ IPW2100_ORD(OUR_FREQ,
+ "current radio freq lower digits - channel ID"),
+ IPW2100_ORD(RTC_TIME, "current RTC time"),
+ IPW2100_ORD(PORT_TYPE, "operating mode"),
+ IPW2100_ORD(CURRENT_TX_RATE, "current tx rate"),
+ IPW2100_ORD(SUPPORTED_RATES, "supported tx rates"),
+ IPW2100_ORD(ATIM_WINDOW, "current ATIM Window"),
+ IPW2100_ORD(BASIC_RATES, "basic tx rates"),
+ IPW2100_ORD(NIC_HIGHEST_RATE, "NIC highest tx rate"),
+ IPW2100_ORD(AP_HIGHEST_RATE, "AP highest tx rate"),
+ IPW2100_ORD(CAPABILITIES,
+ "Management frame capability field"),
+ IPW2100_ORD(AUTH_TYPE, "Type of authentication"),
+ IPW2100_ORD(RADIO_TYPE, "Adapter card platform type"),
+ IPW2100_ORD(RTS_THRESHOLD,
+ "Min packet length for RTS handshaking"),
+ IPW2100_ORD(INT_MODE, "International mode"),
+ IPW2100_ORD(FRAGMENTATION_THRESHOLD,
+ "protocol frag threshold"),
+ IPW2100_ORD(EEPROM_SRAM_DB_BLOCK_START_ADDRESS,
+ "EEPROM offset in SRAM"),
+ IPW2100_ORD(EEPROM_SRAM_DB_BLOCK_SIZE,
+ "EEPROM size in SRAM"),
+ IPW2100_ORD(EEPROM_SKU_CAPABILITY, "EEPROM SKU Capability"),
+ IPW2100_ORD(EEPROM_IBSS_11B_CHANNELS,
+ "EEPROM IBSS 11b channel set"),
+ IPW2100_ORD(MAC_VERSION, "MAC Version"),
+ IPW2100_ORD(MAC_REVISION, "MAC Revision"),
+ IPW2100_ORD(RADIO_VERSION, "Radio Version"),
+ IPW2100_ORD(NIC_MANF_DATE_TIME, "MANF Date/Time STAMP"),
+ IPW2100_ORD(UCODE_VERSION, "Ucode Version"),};
static ssize_t show_registers(struct device *d, struct device_attribute *attr,
- char *buf)
+ char *buf)
{
int i;
struct ipw2100_priv *priv = dev_get_drvdata(d);
struct net_device *dev = priv->net_dev;
- char * out = buf;
+ char *out = buf;
u32 val = 0;
out += sprintf(out, "%30s [Address ] : Hex\n", "Register");
@@ -3651,15 +3640,15 @@ static ssize_t show_registers(struct device *d, struct device_attribute *attr,
return out - buf;
}
-static DEVICE_ATTR(registers, S_IRUGO, show_registers, NULL);
+static DEVICE_ATTR(registers, S_IRUGO, show_registers, NULL);
static ssize_t show_hardware(struct device *d, struct device_attribute *attr,
- char *buf)
+ char *buf)
{
struct ipw2100_priv *priv = dev_get_drvdata(d);
struct net_device *dev = priv->net_dev;
- char * out = buf;
+ char *out = buf;
int i;
out += sprintf(out, "%30s [Address ] : Hex\n", "NIC entry");
@@ -3692,11 +3681,11 @@ static ssize_t show_hardware(struct device *d, struct device_attribute *attr,
}
return out - buf;
}
-static DEVICE_ATTR(hardware, S_IRUGO, show_hardware, NULL);
+static DEVICE_ATTR(hardware, S_IRUGO, show_hardware, NULL);
static ssize_t show_memory(struct device *d, struct device_attribute *attr,
- char *buf)
+ char *buf)
{
struct ipw2100_priv *priv = dev_get_drvdata(d);
struct net_device *dev = priv->net_dev;
@@ -3712,10 +3701,13 @@ static ssize_t show_memory(struct device *d, struct device_attribute *attr,
/* sysfs provides us PAGE_SIZE buffer */
while (len < PAGE_SIZE - 128 && loop < 0x30000) {
- if (priv->snapshot[0]) for (i = 0; i < 4; i++)
- buffer[i] = *(u32 *)SNAPSHOT_ADDR(loop + i * 4);
- else for (i = 0; i < 4; i++)
- read_nic_dword(dev, loop + i * 4, &buffer[i]);
+ if (priv->snapshot[0])
+ for (i = 0; i < 4; i++)
+ buffer[i] =
+ *(u32 *) SNAPSHOT_ADDR(loop + i * 4);
+ else
+ for (i = 0; i < 4; i++)
+ read_nic_dword(dev, loop + i * 4, &buffer[i]);
if (priv->dump_raw)
len += sprintf(buf + len,
@@ -3723,26 +3715,26 @@ static ssize_t show_memory(struct device *d, struct device_attribute *attr,
"%c%c%c%c"
"%c%c%c%c"
"%c%c%c%c",
- ((u8*)buffer)[0x0],
- ((u8*)buffer)[0x1],
- ((u8*)buffer)[0x2],
- ((u8*)buffer)[0x3],
- ((u8*)buffer)[0x4],
- ((u8*)buffer)[0x5],
- ((u8*)buffer)[0x6],
- ((u8*)buffer)[0x7],
- ((u8*)buffer)[0x8],
- ((u8*)buffer)[0x9],
- ((u8*)buffer)[0xa],
- ((u8*)buffer)[0xb],
- ((u8*)buffer)[0xc],
- ((u8*)buffer)[0xd],
- ((u8*)buffer)[0xe],
- ((u8*)buffer)[0xf]);
+ ((u8 *) buffer)[0x0],
+ ((u8 *) buffer)[0x1],
+ ((u8 *) buffer)[0x2],
+ ((u8 *) buffer)[0x3],
+ ((u8 *) buffer)[0x4],
+ ((u8 *) buffer)[0x5],
+ ((u8 *) buffer)[0x6],
+ ((u8 *) buffer)[0x7],
+ ((u8 *) buffer)[0x8],
+ ((u8 *) buffer)[0x9],
+ ((u8 *) buffer)[0xa],
+ ((u8 *) buffer)[0xb],
+ ((u8 *) buffer)[0xc],
+ ((u8 *) buffer)[0xd],
+ ((u8 *) buffer)[0xe],
+ ((u8 *) buffer)[0xf]);
else
len += sprintf(buf + len, "%s\n",
snprint_line(line, sizeof(line),
- (u8*)buffer, 16, loop));
+ (u8 *) buffer, 16, loop));
loop += 16;
}
@@ -3750,44 +3742,44 @@ static ssize_t show_memory(struct device *d, struct device_attribute *attr,
}
static ssize_t store_memory(struct device *d, struct device_attribute *attr,
- const char *buf, size_t count)
+ const char *buf, size_t count)
{
struct ipw2100_priv *priv = dev_get_drvdata(d);
struct net_device *dev = priv->net_dev;
const char *p = buf;
+ (void) dev; /* kill unused-var warning for debug-only code */
+
if (count < 1)
return count;
if (p[0] == '1' ||
(count >= 2 && tolower(p[0]) == 'o' && tolower(p[1]) == 'n')) {
IPW_DEBUG_INFO("%s: Setting memory dump to RAW mode.\n",
- dev->name);
+ dev->name);
priv->dump_raw = 1;
} else if (p[0] == '0' || (count >= 2 && tolower(p[0]) == 'o' &&
- tolower(p[1]) == 'f')) {
+ tolower(p[1]) == 'f')) {
IPW_DEBUG_INFO("%s: Setting memory dump to HEX mode.\n",
- dev->name);
+ dev->name);
priv->dump_raw = 0;
} else if (tolower(p[0]) == 'r') {
- IPW_DEBUG_INFO("%s: Resetting firmware snapshot.\n",
- dev->name);
+ IPW_DEBUG_INFO("%s: Resetting firmware snapshot.\n", dev->name);
ipw2100_snapshot_free(priv);
} else
IPW_DEBUG_INFO("%s: Usage: 0|on = HEX, 1|off = RAW, "
- "reset = clear memory snapshot\n",
- dev->name);
+ "reset = clear memory snapshot\n", dev->name);
return count;
}
-static DEVICE_ATTR(memory, S_IWUSR|S_IRUGO, show_memory, store_memory);
+static DEVICE_ATTR(memory, S_IWUSR | S_IRUGO, show_memory, store_memory);
static ssize_t show_ordinals(struct device *d, struct device_attribute *attr,
- char *buf)
+ char *buf)
{
struct ipw2100_priv *priv = dev_get_drvdata(d);
u32 val = 0;
@@ -3795,6 +3787,9 @@ static ssize_t show_ordinals(struct device *d, struct device_attribute *attr,
u32 val_len;
static int loop = 0;
+ if (priv->status & STATUS_RF_KILL_MASK)
+ return 0;
+
if (loop >= sizeof(ord_data) / sizeof(*ord_data))
loop = 0;
@@ -3818,14 +3813,14 @@ static ssize_t show_ordinals(struct device *d, struct device_attribute *attr,
return len;
}
-static DEVICE_ATTR(ordinals, S_IRUGO, show_ordinals, NULL);
+static DEVICE_ATTR(ordinals, S_IRUGO, show_ordinals, NULL);
static ssize_t show_stats(struct device *d, struct device_attribute *attr,
- char *buf)
+ char *buf)
{
struct ipw2100_priv *priv = dev_get_drvdata(d);
- char * out = buf;
+ char *out = buf;
out += sprintf(out, "interrupts: %d {tx: %d, rx: %d, other: %d}\n",
priv->interrupts, priv->tx_interrupts,
@@ -3839,8 +3834,8 @@ static ssize_t show_stats(struct device *d, struct device_attribute *attr,
return out - buf;
}
-static DEVICE_ATTR(stats, S_IRUGO, show_stats, NULL);
+static DEVICE_ATTR(stats, S_IRUGO, show_stats, NULL);
static int ipw2100_switch_mode(struct ipw2100_priv *priv, u32 mode)
{
@@ -3868,19 +3863,18 @@ static int ipw2100_switch_mode(struct ipw2100_priv *priv, u32 mode)
priv->last_mode = priv->ieee->iw_mode;
priv->net_dev->type = ARPHRD_IEEE80211;
break;
-#endif /* CONFIG_IPW2100_MONITOR */
+#endif /* CONFIG_IPW2100_MONITOR */
}
priv->ieee->iw_mode = mode;
#ifdef CONFIG_PM
- /* Indicate ipw2100_download_firmware download firmware
+ /* Indicate ipw2100_download_firmware download firmware
* from disk instead of memory. */
ipw2100_firmware.version = 0;
#endif
- printk(KERN_INFO "%s: Reseting on mode change.\n",
- priv->net_dev->name);
+ printk(KERN_INFO "%s: Reseting on mode change.\n", priv->net_dev->name);
priv->reset_backoff = 0;
schedule_reset(priv);
@@ -3888,12 +3882,12 @@ static int ipw2100_switch_mode(struct ipw2100_priv *priv, u32 mode)
}
static ssize_t show_internals(struct device *d, struct device_attribute *attr,
- char *buf)
+ char *buf)
{
struct ipw2100_priv *priv = dev_get_drvdata(d);
int len = 0;
-#define DUMP_VAR(x,y) len += sprintf(buf + len, # x ": %" # y "\n", priv-> x)
+#define DUMP_VAR(x,y) len += sprintf(buf + len, # x ": %" y "\n", priv-> x)
if (priv->status & STATUS_ASSOCIATED)
len += sprintf(buf + len, "connected: %lu\n",
@@ -3901,55 +3895,60 @@ static ssize_t show_internals(struct device *d, struct device_attribute *attr,
else
len += sprintf(buf + len, "not connected\n");
- DUMP_VAR(ieee->crypt[priv->ieee->tx_keyidx], p);
- DUMP_VAR(status, 08lx);
- DUMP_VAR(config, 08lx);
- DUMP_VAR(capability, 08lx);
+ DUMP_VAR(ieee->crypt[priv->ieee->tx_keyidx], "p");
+ DUMP_VAR(status, "08lx");
+ DUMP_VAR(config, "08lx");
+ DUMP_VAR(capability, "08lx");
- len += sprintf(buf + len, "last_rtc: %lu\n", (unsigned long)priv->last_rtc);
+ len +=
+ sprintf(buf + len, "last_rtc: %lu\n",
+ (unsigned long)priv->last_rtc);
- DUMP_VAR(fatal_error, d);
- DUMP_VAR(stop_hang_check, d);
- DUMP_VAR(stop_rf_kill, d);
- DUMP_VAR(messages_sent, d);
+ DUMP_VAR(fatal_error, "d");
+ DUMP_VAR(stop_hang_check, "d");
+ DUMP_VAR(stop_rf_kill, "d");
+ DUMP_VAR(messages_sent, "d");
- DUMP_VAR(tx_pend_stat.value, d);
- DUMP_VAR(tx_pend_stat.hi, d);
+ DUMP_VAR(tx_pend_stat.value, "d");
+ DUMP_VAR(tx_pend_stat.hi, "d");
- DUMP_VAR(tx_free_stat.value, d);
- DUMP_VAR(tx_free_stat.lo, d);
+ DUMP_VAR(tx_free_stat.value, "d");
+ DUMP_VAR(tx_free_stat.lo, "d");
- DUMP_VAR(msg_free_stat.value, d);
- DUMP_VAR(msg_free_stat.lo, d);
+ DUMP_VAR(msg_free_stat.value, "d");
+ DUMP_VAR(msg_free_stat.lo, "d");
- DUMP_VAR(msg_pend_stat.value, d);
- DUMP_VAR(msg_pend_stat.hi, d);
+ DUMP_VAR(msg_pend_stat.value, "d");
+ DUMP_VAR(msg_pend_stat.hi, "d");
- DUMP_VAR(fw_pend_stat.value, d);
- DUMP_VAR(fw_pend_stat.hi, d);
+ DUMP_VAR(fw_pend_stat.value, "d");
+ DUMP_VAR(fw_pend_stat.hi, "d");
- DUMP_VAR(txq_stat.value, d);
- DUMP_VAR(txq_stat.lo, d);
+ DUMP_VAR(txq_stat.value, "d");
+ DUMP_VAR(txq_stat.lo, "d");
- DUMP_VAR(ieee->scans, d);
- DUMP_VAR(reset_backoff, d);
+ DUMP_VAR(ieee->scans, "d");
+ DUMP_VAR(reset_backoff, "d");
return len;
}
-static DEVICE_ATTR(internals, S_IRUGO, show_internals, NULL);
+static DEVICE_ATTR(internals, S_IRUGO, show_internals, NULL);
static ssize_t show_bssinfo(struct device *d, struct device_attribute *attr,
- char *buf)
+ char *buf)
{
struct ipw2100_priv *priv = dev_get_drvdata(d);
char essid[IW_ESSID_MAX_SIZE + 1];
u8 bssid[ETH_ALEN];
u32 chan = 0;
- char * out = buf;
+ char *out = buf;
int length;
int ret;
+ if (priv->status & STATUS_RF_KILL_MASK)
+ return 0;
+
memset(essid, 0, sizeof(essid));
memset(bssid, 0, sizeof(bssid));
@@ -3980,8 +3979,8 @@ static ssize_t show_bssinfo(struct device *d, struct device_attribute *attr,
return out - buf;
}
-static DEVICE_ATTR(bssinfo, S_IRUGO, show_bssinfo, NULL);
+static DEVICE_ATTR(bssinfo, S_IRUGO, show_bssinfo, NULL);
#ifdef CONFIG_IPW_DEBUG
static ssize_t show_debug_level(struct device_driver *d, char *buf)
@@ -3989,8 +3988,8 @@ static ssize_t show_debug_level(struct device_driver *d, char *buf)
return sprintf(buf, "0x%08X\n", ipw2100_debug_level);
}
-static ssize_t store_debug_level(struct device_driver *d, const char *buf,
- size_t count)
+static ssize_t store_debug_level(struct device_driver *d,
+ const char *buf, size_t count)
{
char *p = (char *)buf;
u32 val;
@@ -4003,28 +4002,26 @@ static ssize_t store_debug_level(struct device_driver *d, const char *buf,
} else
val = simple_strtoul(p, &p, 10);
if (p == buf)
- IPW_DEBUG_INFO(DRV_NAME
- ": %s is not in hex or decimal form.\n", buf);
+ IPW_DEBUG_INFO(": %s is not in hex or decimal form.\n", buf);
else
ipw2100_debug_level = val;
return strnlen(buf, count);
}
+
static DRIVER_ATTR(debug_level, S_IWUSR | S_IRUGO, show_debug_level,
store_debug_level);
-#endif /* CONFIG_IPW_DEBUG */
-
+#endif /* CONFIG_IPW_DEBUG */
static ssize_t show_fatal_error(struct device *d,
- struct device_attribute *attr, char *buf)
+ struct device_attribute *attr, char *buf)
{
struct ipw2100_priv *priv = dev_get_drvdata(d);
char *out = buf;
int i;
if (priv->fatal_error)
- out += sprintf(out, "0x%08X\n",
- priv->fatal_error);
+ out += sprintf(out, "0x%08X\n", priv->fatal_error);
else
out += sprintf(out, "0\n");
@@ -4042,24 +4039,26 @@ static ssize_t show_fatal_error(struct device *d,
}
static ssize_t store_fatal_error(struct device *d,
- struct device_attribute *attr, const char *buf, size_t count)
+ struct device_attribute *attr, const char *buf,
+ size_t count)
{
struct ipw2100_priv *priv = dev_get_drvdata(d);
schedule_reset(priv);
return count;
}
-static DEVICE_ATTR(fatal_error, S_IWUSR|S_IRUGO, show_fatal_error, store_fatal_error);
+static DEVICE_ATTR(fatal_error, S_IWUSR | S_IRUGO, show_fatal_error,
+ store_fatal_error);
static ssize_t show_scan_age(struct device *d, struct device_attribute *attr,
- char *buf)
+ char *buf)
{
struct ipw2100_priv *priv = dev_get_drvdata(d);
return sprintf(buf, "%d\n", priv->ieee->scan_age);
}
static ssize_t store_scan_age(struct device *d, struct device_attribute *attr,
- const char *buf, size_t count)
+ const char *buf, size_t count)
{
struct ipw2100_priv *priv = dev_get_drvdata(d);
struct net_device *dev = priv->net_dev;
@@ -4069,6 +4068,8 @@ static ssize_t store_scan_age(struct device *d, struct device_attribute *attr,
unsigned long val;
char *p = buffer;
+ (void) dev; /* kill unused-var warning for debug-only code */
+
IPW_DEBUG_INFO("enter\n");
strncpy(buffer, buf, len);
@@ -4082,8 +4083,7 @@ static ssize_t store_scan_age(struct device *d, struct device_attribute *attr,
} else
val = simple_strtoul(p, &p, 10);
if (p == buffer) {
- IPW_DEBUG_INFO("%s: user supplied invalid value.\n",
- dev->name);
+ IPW_DEBUG_INFO("%s: user supplied invalid value.\n", dev->name);
} else {
priv->ieee->scan_age = val;
IPW_DEBUG_INFO("set scan_age = %u\n", priv->ieee->scan_age);
@@ -4092,11 +4092,11 @@ static ssize_t store_scan_age(struct device *d, struct device_attribute *attr,
IPW_DEBUG_INFO("exit\n");
return len;
}
-static DEVICE_ATTR(scan_age, S_IWUSR | S_IRUGO, show_scan_age, store_scan_age);
+static DEVICE_ATTR(scan_age, S_IWUSR | S_IRUGO, show_scan_age, store_scan_age);
static ssize_t show_rf_kill(struct device *d, struct device_attribute *attr,
- char *buf)
+ char *buf)
{
/* 0 - RF kill not enabled
1 - SW based RF kill active (sysfs)
@@ -4104,7 +4104,7 @@ static ssize_t show_rf_kill(struct device *d, struct device_attribute *attr,
3 - Both HW and SW baed RF kill active */
struct ipw2100_priv *priv = (struct ipw2100_priv *)d->driver_data;
int val = ((priv->status & STATUS_RF_KILL_SW) ? 0x1 : 0x0) |
- (rf_kill_active(priv) ? 0x2 : 0x0);
+ (rf_kill_active(priv) ? 0x2 : 0x0);
return sprintf(buf, "%i\n", val);
}
@@ -4112,7 +4112,7 @@ static int ipw_radio_kill_sw(struct ipw2100_priv *priv, int disable_radio)
{
if ((disable_radio ? 1 : 0) ==
(priv->status & STATUS_RF_KILL_SW ? 1 : 0))
- return 0 ;
+ return 0;
IPW_DEBUG_RF_KILL("Manual SW RF Kill set to: RADIO %s\n",
disable_radio ? "OFF" : "ON");
@@ -4130,8 +4130,7 @@ static int ipw_radio_kill_sw(struct ipw2100_priv *priv, int disable_radio)
/* Make sure the RF_KILL check timer is running */
priv->stop_rf_kill = 0;
cancel_delayed_work(&priv->rf_kill);
- queue_delayed_work(priv->workqueue, &priv->rf_kill,
- HZ);
+ queue_delayed_work(priv->workqueue, &priv->rf_kill, HZ);
} else
schedule_reset(priv);
}
@@ -4141,14 +4140,14 @@ static int ipw_radio_kill_sw(struct ipw2100_priv *priv, int disable_radio)
}
static ssize_t store_rf_kill(struct device *d, struct device_attribute *attr,
- const char *buf, size_t count)
+ const char *buf, size_t count)
{
struct ipw2100_priv *priv = dev_get_drvdata(d);
ipw_radio_kill_sw(priv, buf[0] == '1');
return count;
}
-static DEVICE_ATTR(rf_kill, S_IWUSR|S_IRUGO, show_rf_kill, store_rf_kill);
+static DEVICE_ATTR(rf_kill, S_IWUSR | S_IRUGO, show_rf_kill, store_rf_kill);
static struct attribute *ipw2100_sysfs_entries[] = {
&dev_attr_hardware.attr,
@@ -4172,7 +4171,6 @@ static struct attribute_group ipw2100_attribute_group = {
.attrs = ipw2100_sysfs_entries,
};
-
static int status_queue_allocate(struct ipw2100_priv *priv, int entries)
{
struct ipw2100_status_queue *q = &priv->status_queue;
@@ -4180,11 +4178,11 @@ static int status_queue_allocate(struct ipw2100_priv *priv, int entries)
IPW_DEBUG_INFO("enter\n");
q->size = entries * sizeof(struct ipw2100_status);
- q->drv = (struct ipw2100_status *)pci_alloc_consistent(
- priv->pci_dev, q->size, &q->nic);
+ q->drv =
+ (struct ipw2100_status *)pci_alloc_consistent(priv->pci_dev,
+ q->size, &q->nic);
if (!q->drv) {
- IPW_DEBUG_WARNING(
- "Can not allocate status queue.\n");
+ IPW_DEBUG_WARNING("Can not allocate status queue.\n");
return -ENOMEM;
}
@@ -4200,9 +4198,9 @@ static void status_queue_free(struct ipw2100_priv *priv)
IPW_DEBUG_INFO("enter\n");
if (priv->status_queue.drv) {
- pci_free_consistent(
- priv->pci_dev, priv->status_queue.size,
- priv->status_queue.drv, priv->status_queue.nic);
+ pci_free_consistent(priv->pci_dev, priv->status_queue.size,
+ priv->status_queue.drv,
+ priv->status_queue.nic);
priv->status_queue.drv = NULL;
}
@@ -4220,7 +4218,8 @@ static int bd_queue_allocate(struct ipw2100_priv *priv,
q->size = entries * sizeof(struct ipw2100_bd);
q->drv = pci_alloc_consistent(priv->pci_dev, q->size, &q->nic);
if (!q->drv) {
- IPW_DEBUG_INFO("can't allocate shared memory for buffer descriptors\n");
+ IPW_DEBUG_INFO
+ ("can't allocate shared memory for buffer descriptors\n");
return -ENOMEM;
}
memset(q->drv, 0, q->size);
@@ -4230,8 +4229,7 @@ static int bd_queue_allocate(struct ipw2100_priv *priv,
return 0;
}
-static void bd_queue_free(struct ipw2100_priv *priv,
- struct ipw2100_bd_queue *q)
+static void bd_queue_free(struct ipw2100_priv *priv, struct ipw2100_bd_queue *q)
{
IPW_DEBUG_INFO("enter\n");
@@ -4239,21 +4237,21 @@ static void bd_queue_free(struct ipw2100_priv *priv,
return;
if (q->drv) {
- pci_free_consistent(priv->pci_dev,
- q->size, q->drv, q->nic);
+ pci_free_consistent(priv->pci_dev, q->size, q->drv, q->nic);
q->drv = NULL;
}
IPW_DEBUG_INFO("exit\n");
}
-static void bd_queue_initialize(
- struct ipw2100_priv *priv, struct ipw2100_bd_queue * q,
- u32 base, u32 size, u32 r, u32 w)
+static void bd_queue_initialize(struct ipw2100_priv *priv,
+ struct ipw2100_bd_queue *q, u32 base, u32 size,
+ u32 r, u32 w)
{
IPW_DEBUG_INFO("enter\n");
- IPW_DEBUG_INFO("initializing bd queue at virt=%p, phys=%08x\n", q->drv, (u32)q->nic);
+ IPW_DEBUG_INFO("initializing bd queue at virt=%p, phys=%08x\n", q->drv,
+ (u32) q->nic);
write_register(priv->net_dev, base, q->nic);
write_register(priv->net_dev, size, q->entries);
@@ -4289,32 +4287,38 @@ static int ipw2100_tx_allocate(struct ipw2100_priv *priv)
err = bd_queue_allocate(priv, &priv->tx_queue, TX_QUEUE_LENGTH);
if (err) {
IPW_DEBUG_ERROR("%s: failed bd_queue_allocate\n",
- priv->net_dev->name);
+ priv->net_dev->name);
return err;
}
- priv->tx_buffers = (struct ipw2100_tx_packet *)kmalloc(
- TX_PENDED_QUEUE_LENGTH * sizeof(struct ipw2100_tx_packet),
- GFP_ATOMIC);
+ priv->tx_buffers =
+ (struct ipw2100_tx_packet *)kmalloc(TX_PENDED_QUEUE_LENGTH *
+ sizeof(struct
+ ipw2100_tx_packet),
+ GFP_ATOMIC);
if (!priv->tx_buffers) {
- printk(KERN_ERR DRV_NAME ": %s: alloc failed form tx buffers.\n",
+ printk(KERN_ERR DRV_NAME
+ ": %s: alloc failed form tx buffers.\n",
priv->net_dev->name);
bd_queue_free(priv, &priv->tx_queue);
return -ENOMEM;
}
for (i = 0; i < TX_PENDED_QUEUE_LENGTH; i++) {
- v = pci_alloc_consistent(
- priv->pci_dev, sizeof(struct ipw2100_data_header), &p);
+ v = pci_alloc_consistent(priv->pci_dev,
+ sizeof(struct ipw2100_data_header),
+ &p);
if (!v) {
- printk(KERN_ERR DRV_NAME ": %s: PCI alloc failed for tx "
- "buffers.\n", priv->net_dev->name);
+ printk(KERN_ERR DRV_NAME
+ ": %s: PCI alloc failed for tx " "buffers.\n",
+ priv->net_dev->name);
err = -ENOMEM;
break;
}
priv->tx_buffers[i].type = DATA;
- priv->tx_buffers[i].info.d_struct.data = (struct ipw2100_data_header*)v;
+ priv->tx_buffers[i].info.d_struct.data =
+ (struct ipw2100_data_header *)v;
priv->tx_buffers[i].info.d_struct.data_phys = p;
priv->tx_buffers[i].info.d_struct.txb = NULL;
}
@@ -4323,11 +4327,11 @@ static int ipw2100_tx_allocate(struct ipw2100_priv *priv)
return 0;
for (j = 0; j < i; j++) {
- pci_free_consistent(
- priv->pci_dev,
- sizeof(struct ipw2100_data_header),
- priv->tx_buffers[j].info.d_struct.data,
- priv->tx_buffers[j].info.d_struct.data_phys);
+ pci_free_consistent(priv->pci_dev,
+ sizeof(struct ipw2100_data_header),
+ priv->tx_buffers[j].info.d_struct.data,
+ priv->tx_buffers[j].info.d_struct.
+ data_phys);
}
kfree(priv->tx_buffers);
@@ -4360,7 +4364,8 @@ static void ipw2100_tx_initialize(struct ipw2100_priv *priv)
/* We simply drop any SKBs that have been queued for
* transmit */
if (priv->tx_buffers[i].info.d_struct.txb) {
- ieee80211_txb_free(priv->tx_buffers[i].info.d_struct.txb);
+ ieee80211_txb_free(priv->tx_buffers[i].info.d_struct.
+ txb);
priv->tx_buffers[i].info.d_struct.txb = NULL;
}
@@ -4398,15 +4403,17 @@ static void ipw2100_tx_free(struct ipw2100_priv *priv)
for (i = 0; i < TX_PENDED_QUEUE_LENGTH; i++) {
if (priv->tx_buffers[i].info.d_struct.txb) {
- ieee80211_txb_free(priv->tx_buffers[i].info.d_struct.txb);
+ ieee80211_txb_free(priv->tx_buffers[i].info.d_struct.
+ txb);
priv->tx_buffers[i].info.d_struct.txb = NULL;
}
if (priv->tx_buffers[i].info.d_struct.data)
- pci_free_consistent(
- priv->pci_dev,
- sizeof(struct ipw2100_data_header),
- priv->tx_buffers[i].info.d_struct.data,
- priv->tx_buffers[i].info.d_struct.data_phys);
+ pci_free_consistent(priv->pci_dev,
+ sizeof(struct ipw2100_data_header),
+ priv->tx_buffers[i].info.d_struct.
+ data,
+ priv->tx_buffers[i].info.d_struct.
+ data_phys);
}
kfree(priv->tx_buffers);
@@ -4415,8 +4422,6 @@ static void ipw2100_tx_free(struct ipw2100_priv *priv)
IPW_DEBUG_INFO("exit\n");
}
-
-
static int ipw2100_rx_allocate(struct ipw2100_priv *priv)
{
int i, j, err = -EINVAL;
@@ -4546,14 +4551,13 @@ static int ipw2100_read_mac_address(struct ipw2100_priv *priv)
int err;
- err = ipw2100_get_ordinal(priv, IPW_ORD_STAT_ADAPTER_MAC,
- mac, &length);
+ err = ipw2100_get_ordinal(priv, IPW_ORD_STAT_ADAPTER_MAC, mac, &length);
if (err) {
IPW_DEBUG_INFO("MAC address read failed\n");
return -EIO;
}
IPW_DEBUG_INFO("card MAC is %02X:%02X:%02X:%02X:%02X:%02X\n",
- mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
+ mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
memcpy(priv->net_dev->dev_addr, mac, ETH_ALEN);
@@ -4580,8 +4584,7 @@ static int ipw2100_set_mac_address(struct ipw2100_priv *priv, int batch_mode)
IPW_DEBUG_INFO("enter\n");
if (priv->config & CFG_CUSTOM_MAC) {
- memcpy(cmd.host_command_parameters, priv->mac_addr,
- ETH_ALEN);
+ memcpy(cmd.host_command_parameters, priv->mac_addr, ETH_ALEN);
memcpy(priv->net_dev->dev_addr, priv->mac_addr, ETH_ALEN);
} else
memcpy(cmd.host_command_parameters, priv->net_dev->dev_addr,
@@ -4618,7 +4621,8 @@ static int ipw2100_set_port_type(struct ipw2100_priv *priv, u32 port_type,
if (!batch_mode) {
err = ipw2100_disable_adapter(priv);
if (err) {
- printk(KERN_ERR DRV_NAME ": %s: Could not disable adapter %d\n",
+ printk(KERN_ERR DRV_NAME
+ ": %s: Could not disable adapter %d\n",
priv->net_dev->name, err);
return err;
}
@@ -4633,7 +4637,6 @@ static int ipw2100_set_port_type(struct ipw2100_priv *priv, u32 port_type,
return err;
}
-
static int ipw2100_set_channel(struct ipw2100_priv *priv, u32 channel,
int batch_mode)
{
@@ -4664,8 +4667,7 @@ static int ipw2100_set_channel(struct ipw2100_priv *priv, u32 channel,
err = ipw2100_hw_send_command(priv, &cmd);
if (err) {
- IPW_DEBUG_INFO("Failed to set channel to %d",
- channel);
+ IPW_DEBUG_INFO("Failed to set channel to %d", channel);
return err;
}
@@ -4707,15 +4709,14 @@ static int ipw2100_system_config(struct ipw2100_priv *priv, int batch_mode)
cmd.host_command_parameters[0] |= IPW_CFG_IBSS_AUTO_START;
cmd.host_command_parameters[0] |= IPW_CFG_IBSS_MASK |
- IPW_CFG_BSS_MASK |
- IPW_CFG_802_1x_ENABLE;
+ IPW_CFG_BSS_MASK | IPW_CFG_802_1x_ENABLE;
if (!(priv->config & CFG_LONG_PREAMBLE))
cmd.host_command_parameters[0] |= IPW_CFG_PREAMBLE_AUTO;
err = ipw2100_get_ordinal(priv,
IPW_ORD_EEPROM_IBSS_11B_CHANNELS,
- &ibss_mask, &len);
+ &ibss_mask, &len);
if (err)
ibss_mask = IPW_IBSS_11B_DEFAULT_MASK;
@@ -4723,7 +4724,7 @@ static int ipw2100_system_config(struct ipw2100_priv *priv, int batch_mode)
cmd.host_command_parameters[2] = REG_CHANNEL_MASK & ibss_mask;
/* 11b only */
- /*cmd.host_command_parameters[0] |= DIVERSITY_ANTENNA_A;*/
+ /*cmd.host_command_parameters[0] |= DIVERSITY_ANTENNA_A; */
err = ipw2100_hw_send_command(priv, &cmd);
if (err)
@@ -4787,8 +4788,7 @@ static int ipw2100_set_tx_rates(struct ipw2100_priv *priv, u32 rate,
return 0;
}
-static int ipw2100_set_power_mode(struct ipw2100_priv *priv,
- int power_level)
+static int ipw2100_set_power_mode(struct ipw2100_priv *priv, int power_level)
{
struct host_command cmd = {
.host_command = POWER_MODE,
@@ -4809,11 +4809,10 @@ static int ipw2100_set_power_mode(struct ipw2100_priv *priv,
priv->power_mode = IPW_POWER_ENABLED | power_level;
#ifdef CONFIG_IPW2100_TX_POWER
- if (priv->port_type == IBSS &&
- priv->adhoc_power != DFTL_IBSS_TX_POWER) {
+ if (priv->port_type == IBSS && priv->adhoc_power != DFTL_IBSS_TX_POWER) {
/* Set beacon interval */
cmd.host_command = TX_POWER_INDEX;
- cmd.host_command_parameters[0] = (u32)priv->adhoc_power;
+ cmd.host_command_parameters[0] = (u32) priv->adhoc_power;
err = ipw2100_hw_send_command(priv, &cmd);
if (err)
@@ -4824,7 +4823,6 @@ static int ipw2100_set_power_mode(struct ipw2100_priv *priv,
return 0;
}
-
static int ipw2100_set_rts_threshold(struct ipw2100_priv *priv, u32 threshold)
{
struct host_command cmd = {
@@ -4929,8 +4927,7 @@ static int ipw2100_set_long_retry(struct ipw2100_priv *priv, u32 retry)
return 0;
}
-
-static int ipw2100_set_mandatory_bssid(struct ipw2100_priv *priv, u8 *bssid,
+static int ipw2100_set_mandatory_bssid(struct ipw2100_priv *priv, u8 * bssid,
int batch_mode)
{
struct host_command cmd = {
@@ -4942,16 +4939,15 @@ static int ipw2100_set_mandatory_bssid(struct ipw2100_priv *priv, u8 *bssid,
#ifdef CONFIG_IPW_DEBUG
if (bssid != NULL)
- IPW_DEBUG_HC(
- "MANDATORY_BSSID: %02X:%02X:%02X:%02X:%02X:%02X\n",
- bssid[0], bssid[1], bssid[2], bssid[3], bssid[4],
- bssid[5]);
+ IPW_DEBUG_HC("MANDATORY_BSSID: %02X:%02X:%02X:%02X:%02X:%02X\n",
+ bssid[0], bssid[1], bssid[2], bssid[3], bssid[4],
+ bssid[5]);
else
IPW_DEBUG_HC("MANDATORY_BSSID: <clear>\n");
#endif
/* if BSSID is empty then we disable mandatory bssid mode */
if (bssid != NULL)
- memcpy((u8 *)cmd.host_command_parameters, bssid, ETH_ALEN);
+ memcpy(cmd.host_command_parameters, bssid, ETH_ALEN);
if (!batch_mode) {
err = ipw2100_disable_adapter(priv);
@@ -4967,7 +4963,6 @@ static int ipw2100_set_mandatory_bssid(struct ipw2100_priv *priv, u8 *bssid,
return err;
}
-#ifdef CONFIG_IEEE80211_WPA
static int ipw2100_disassociate_bssid(struct ipw2100_priv *priv)
{
struct host_command cmd = {
@@ -4991,42 +4986,10 @@ static int ipw2100_disassociate_bssid(struct ipw2100_priv *priv)
return err;
}
-#endif
-
-/*
- * Pseudo code for setting up wpa_frame:
- */
-#if 0
-void x(struct ieee80211_assoc_frame *wpa_assoc)
-{
- struct ipw2100_wpa_assoc_frame frame;
- frame->fixed_ie_mask = IPW_WPA_CAPABILTIES |
- IPW_WPA_LISTENINTERVAL |
- IPW_WPA_AP_ADDRESS;
- frame->capab_info = wpa_assoc->capab_info;
- frame->lisen_interval = wpa_assoc->listent_interval;
- memcpy(frame->current_ap, wpa_assoc->current_ap, ETH_ALEN);
-
- /* UNKNOWN -- I'm not postivive about this part; don't have any WPA
- * setup here to test it with.
- *
- * Walk the IEs in the wpa_assoc and figure out the total size of all
- * that data. Stick that into frame->var_ie_len. Then memcpy() all of
- * the IEs from wpa_frame into frame.
- */
- frame->var_ie_len = calculate_ie_len(wpa_assoc);
- memcpy(frame->var_ie, wpa_assoc->variable, frame->var_ie_len);
-
- ipw2100_set_wpa_ie(priv, &frame, 0);
-}
-#endif
-
-
-
static int ipw2100_set_wpa_ie(struct ipw2100_priv *,
struct ipw2100_wpa_assoc_frame *, int)
-__attribute__ ((unused));
+ __attribute__ ((unused));
static int ipw2100_set_wpa_ie(struct ipw2100_priv *priv,
struct ipw2100_wpa_assoc_frame *wpa_frame,
@@ -5080,7 +5043,7 @@ static int ipw2100_set_security_information(struct ipw2100_priv *priv,
.host_command_length = sizeof(struct security_info_params)
};
struct security_info_params *security =
- (struct security_info_params *)&cmd.host_command_parameters;
+ (struct security_info_params *)&cmd.host_command_parameters;
int err;
memset(security, 0, sizeof(*security));
@@ -5098,25 +5061,25 @@ static int ipw2100_set_security_information(struct ipw2100_priv *priv,
break;
case SEC_LEVEL_1:
security->allowed_ciphers = IPW_WEP40_CIPHER |
- IPW_WEP104_CIPHER;
+ IPW_WEP104_CIPHER;
break;
case SEC_LEVEL_2:
security->allowed_ciphers = IPW_WEP40_CIPHER |
- IPW_WEP104_CIPHER | IPW_TKIP_CIPHER;
+ IPW_WEP104_CIPHER | IPW_TKIP_CIPHER;
break;
case SEC_LEVEL_2_CKIP:
security->allowed_ciphers = IPW_WEP40_CIPHER |
- IPW_WEP104_CIPHER | IPW_CKIP_CIPHER;
+ IPW_WEP104_CIPHER | IPW_CKIP_CIPHER;
break;
case SEC_LEVEL_3:
security->allowed_ciphers = IPW_WEP40_CIPHER |
- IPW_WEP104_CIPHER | IPW_TKIP_CIPHER | IPW_CCMP_CIPHER;
+ IPW_WEP104_CIPHER | IPW_TKIP_CIPHER | IPW_CCMP_CIPHER;
break;
}
- IPW_DEBUG_HC(
- "SET_SECURITY_INFORMATION: auth:%d cipher:0x%02X (level %d)\n",
- security->auth_mode, security->allowed_ciphers, security_level);
+ IPW_DEBUG_HC
+ ("SET_SECURITY_INFORMATION: auth:%d cipher:0x%02X (level %d)\n",
+ security->auth_mode, security->allowed_ciphers, security_level);
security->replay_counters_number = 0;
@@ -5134,8 +5097,7 @@ static int ipw2100_set_security_information(struct ipw2100_priv *priv,
return err;
}
-static int ipw2100_set_tx_power(struct ipw2100_priv *priv,
- u32 tx_power)
+static int ipw2100_set_tx_power(struct ipw2100_priv *priv, u32 tx_power)
{
struct host_command cmd = {
.host_command = TX_POWER_INDEX,
@@ -5144,6 +5106,10 @@ static int ipw2100_set_tx_power(struct ipw2100_priv *priv,
};
int err = 0;
+ if (tx_power != IPW_TX_POWER_DEFAULT)
+ tx_power = (tx_power - IPW_TX_POWER_MIN_DBM) * 16 /
+ (IPW_TX_POWER_MAX_DBM - IPW_TX_POWER_MIN_DBM);
+
cmd.host_command_parameters[0] = tx_power;
if (priv->ieee->iw_mode == IW_MODE_ADHOC)
@@ -5189,7 +5155,6 @@ static int ipw2100_set_ibss_beacon_interval(struct ipw2100_priv *priv,
return 0;
}
-
void ipw2100_queues_initialize(struct ipw2100_priv *priv)
{
ipw2100_tx_initialize(priv);
@@ -5207,13 +5172,12 @@ void ipw2100_queues_free(struct ipw2100_priv *priv)
int ipw2100_queues_allocate(struct ipw2100_priv *priv)
{
if (ipw2100_tx_allocate(priv) ||
- ipw2100_rx_allocate(priv) ||
- ipw2100_msg_allocate(priv))
+ ipw2100_rx_allocate(priv) || ipw2100_msg_allocate(priv))
goto fail;
return 0;
- fail:
+ fail:
ipw2100_tx_free(priv);
ipw2100_rx_free(priv);
ipw2100_msg_free(priv);
@@ -5239,7 +5203,8 @@ static int ipw2100_set_wep_flags(struct ipw2100_priv *priv, u32 flags,
if (!batch_mode) {
err = ipw2100_disable_adapter(priv);
if (err) {
- printk(KERN_ERR DRV_NAME ": %s: Could not disable adapter %d\n",
+ printk(KERN_ERR DRV_NAME
+ ": %s: Could not disable adapter %d\n",
priv->net_dev->name, err);
return err;
}
@@ -5266,7 +5231,6 @@ struct ipw2100_wep_key {
#define WEP_STR_64(x) x[0],x[1],x[2],x[3],x[4]
#define WEP_STR_128(x) x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7],x[8],x[9],x[10]
-
/**
* Set a the wep key
*
@@ -5291,11 +5255,11 @@ static int ipw2100_set_key(struct ipw2100_priv *priv,
.host_command_sequence = 0,
.host_command_length = sizeof(struct ipw2100_wep_key),
};
- struct ipw2100_wep_key *wep_key = (void*)cmd.host_command_parameters;
+ struct ipw2100_wep_key *wep_key = (void *)cmd.host_command_parameters;
int err;
IPW_DEBUG_HC("WEP_KEY_INFO: index = %d, len = %d/%d\n",
- idx, keylen, len);
+ idx, keylen, len);
/* NOTE: We don't check cached values in case the firmware was reset
* or some other problem is occuring. If the user is setting the key,
@@ -5312,22 +5276,23 @@ static int ipw2100_set_key(struct ipw2100_priv *priv,
/* Will be optimized out on debug not being configured in */
if (keylen == 0)
IPW_DEBUG_WEP("%s: Clearing key %d\n",
- priv->net_dev->name, wep_key->idx);
+ priv->net_dev->name, wep_key->idx);
else if (keylen == 5)
IPW_DEBUG_WEP("%s: idx: %d, len: %d key: " WEP_FMT_64 "\n",
- priv->net_dev->name, wep_key->idx, wep_key->len,
- WEP_STR_64(wep_key->key));
+ priv->net_dev->name, wep_key->idx, wep_key->len,
+ WEP_STR_64(wep_key->key));
else
IPW_DEBUG_WEP("%s: idx: %d, len: %d key: " WEP_FMT_128
- "\n",
- priv->net_dev->name, wep_key->idx, wep_key->len,
- WEP_STR_128(wep_key->key));
+ "\n",
+ priv->net_dev->name, wep_key->idx, wep_key->len,
+ WEP_STR_128(wep_key->key));
if (!batch_mode) {
err = ipw2100_disable_adapter(priv);
/* FIXME: IPG: shouldn't this prink be in _disable_adapter()? */
if (err) {
- printk(KERN_ERR DRV_NAME ": %s: Could not disable adapter %d\n",
+ printk(KERN_ERR DRV_NAME
+ ": %s: Could not disable adapter %d\n",
priv->net_dev->name, err);
return err;
}
@@ -5351,7 +5316,7 @@ static int ipw2100_set_key_index(struct ipw2100_priv *priv,
.host_command = WEP_KEY_INDEX,
.host_command_sequence = 0,
.host_command_length = 4,
- .host_command_parameters = { idx },
+ .host_command_parameters = {idx},
};
int err;
@@ -5363,7 +5328,8 @@ static int ipw2100_set_key_index(struct ipw2100_priv *priv,
if (!batch_mode) {
err = ipw2100_disable_adapter(priv);
if (err) {
- printk(KERN_ERR DRV_NAME ": %s: Could not disable adapter %d\n",
+ printk(KERN_ERR DRV_NAME
+ ": %s: Could not disable adapter %d\n",
priv->net_dev->name, err);
return err;
}
@@ -5378,9 +5344,7 @@ static int ipw2100_set_key_index(struct ipw2100_priv *priv,
return err;
}
-
-static int ipw2100_configure_security(struct ipw2100_priv *priv,
- int batch_mode)
+static int ipw2100_configure_security(struct ipw2100_priv *priv, int batch_mode)
{
int i, err, auth_mode, sec_level, use_group;
@@ -5393,40 +5357,42 @@ static int ipw2100_configure_security(struct ipw2100_priv *priv,
return err;
}
- if (!priv->sec.enabled) {
- err = ipw2100_set_security_information(
- priv, IPW_AUTH_OPEN, SEC_LEVEL_0, 0, 1);
+ if (!priv->ieee->sec.enabled) {
+ err =
+ ipw2100_set_security_information(priv, IPW_AUTH_OPEN,
+ SEC_LEVEL_0, 0, 1);
} else {
auth_mode = IPW_AUTH_OPEN;
- if ((priv->sec.flags & SEC_AUTH_MODE) &&
- (priv->sec.auth_mode == WLAN_AUTH_SHARED_KEY))
+ if ((priv->ieee->sec.flags & SEC_AUTH_MODE) &&
+ (priv->ieee->sec.auth_mode == WLAN_AUTH_SHARED_KEY))
auth_mode = IPW_AUTH_SHARED;
sec_level = SEC_LEVEL_0;
- if (priv->sec.flags & SEC_LEVEL)
- sec_level = priv->sec.level;
+ if (priv->ieee->sec.flags & SEC_LEVEL)
+ sec_level = priv->ieee->sec.level;
use_group = 0;
- if (priv->sec.flags & SEC_UNICAST_GROUP)
- use_group = priv->sec.unicast_uses_group;
+ if (priv->ieee->sec.flags & SEC_UNICAST_GROUP)
+ use_group = priv->ieee->sec.unicast_uses_group;
- err = ipw2100_set_security_information(
- priv, auth_mode, sec_level, use_group, 1);
+ err =
+ ipw2100_set_security_information(priv, auth_mode, sec_level,
+ use_group, 1);
}
if (err)
goto exit;
- if (priv->sec.enabled) {
+ if (priv->ieee->sec.enabled) {
for (i = 0; i < 4; i++) {
- if (!(priv->sec.flags & (1 << i))) {
- memset(priv->sec.keys[i], 0, WEP_KEY_LEN);
- priv->sec.key_sizes[i] = 0;
+ if (!(priv->ieee->sec.flags & (1 << i))) {
+ memset(priv->ieee->sec.keys[i], 0, WEP_KEY_LEN);
+ priv->ieee->sec.key_sizes[i] = 0;
} else {
err = ipw2100_set_key(priv, i,
- priv->sec.keys[i],
- priv->sec.key_sizes[i],
- 1);
+ priv->ieee->sec.keys[i],
+ priv->ieee->sec.
+ key_sizes[i], 1);
if (err)
goto exit;
}
@@ -5437,14 +5403,16 @@ static int ipw2100_configure_security(struct ipw2100_priv *priv,
/* Always enable privacy so the Host can filter WEP packets if
* encrypted data is sent up */
- err = ipw2100_set_wep_flags(
- priv, priv->sec.enabled ? IPW_PRIVACY_CAPABLE : 0, 1);
+ err =
+ ipw2100_set_wep_flags(priv,
+ priv->ieee->sec.
+ enabled ? IPW_PRIVACY_CAPABLE : 0, 1);
if (err)
goto exit;
priv->status &= ~STATUS_SECURITY_UPDATED;
- exit:
+ exit:
if (!batch_mode)
ipw2100_enable_adapter(priv);
@@ -5473,60 +5441,64 @@ static void shim__set_security(struct net_device *dev,
for (i = 0; i < 4; i++) {
if (sec->flags & (1 << i)) {
- priv->sec.key_sizes[i] = sec->key_sizes[i];
+ priv->ieee->sec.key_sizes[i] = sec->key_sizes[i];
if (sec->key_sizes[i] == 0)
- priv->sec.flags &= ~(1 << i);
+ priv->ieee->sec.flags &= ~(1 << i);
else
- memcpy(priv->sec.keys[i], sec->keys[i],
+ memcpy(priv->ieee->sec.keys[i], sec->keys[i],
sec->key_sizes[i]);
- priv->sec.flags |= (1 << i);
- priv->status |= STATUS_SECURITY_UPDATED;
+ if (sec->level == SEC_LEVEL_1) {
+ priv->ieee->sec.flags |= (1 << i);
+ priv->status |= STATUS_SECURITY_UPDATED;
+ } else
+ priv->ieee->sec.flags &= ~(1 << i);
}
}
if ((sec->flags & SEC_ACTIVE_KEY) &&
- priv->sec.active_key != sec->active_key) {
+ priv->ieee->sec.active_key != sec->active_key) {
if (sec->active_key <= 3) {
- priv->sec.active_key = sec->active_key;
- priv->sec.flags |= SEC_ACTIVE_KEY;
+ priv->ieee->sec.active_key = sec->active_key;
+ priv->ieee->sec.flags |= SEC_ACTIVE_KEY;
} else
- priv->sec.flags &= ~SEC_ACTIVE_KEY;
+ priv->ieee->sec.flags &= ~SEC_ACTIVE_KEY;
priv->status |= STATUS_SECURITY_UPDATED;
}
if ((sec->flags & SEC_AUTH_MODE) &&
- (priv->sec.auth_mode != sec->auth_mode)) {
- priv->sec.auth_mode = sec->auth_mode;
- priv->sec.flags |= SEC_AUTH_MODE;
+ (priv->ieee->sec.auth_mode != sec->auth_mode)) {
+ priv->ieee->sec.auth_mode = sec->auth_mode;
+ priv->ieee->sec.flags |= SEC_AUTH_MODE;
priv->status |= STATUS_SECURITY_UPDATED;
}
- if (sec->flags & SEC_ENABLED &&
- priv->sec.enabled != sec->enabled) {
- priv->sec.flags |= SEC_ENABLED;
- priv->sec.enabled = sec->enabled;
+ if (sec->flags & SEC_ENABLED && priv->ieee->sec.enabled != sec->enabled) {
+ priv->ieee->sec.flags |= SEC_ENABLED;
+ priv->ieee->sec.enabled = sec->enabled;
priv->status |= STATUS_SECURITY_UPDATED;
force_update = 1;
}
- if (sec->flags & SEC_LEVEL &&
- priv->sec.level != sec->level) {
- priv->sec.level = sec->level;
- priv->sec.flags |= SEC_LEVEL;
+ if (sec->flags & SEC_ENCRYPT)
+ priv->ieee->sec.encrypt = sec->encrypt;
+
+ if (sec->flags & SEC_LEVEL && priv->ieee->sec.level != sec->level) {
+ priv->ieee->sec.level = sec->level;
+ priv->ieee->sec.flags |= SEC_LEVEL;
priv->status |= STATUS_SECURITY_UPDATED;
}
IPW_DEBUG_WEP("Security flags: %c %c%c%c%c %c%c%c%c\n",
- priv->sec.flags & (1<<8) ? '1' : '0',
- priv->sec.flags & (1<<7) ? '1' : '0',
- priv->sec.flags & (1<<6) ? '1' : '0',
- priv->sec.flags & (1<<5) ? '1' : '0',
- priv->sec.flags & (1<<4) ? '1' : '0',
- priv->sec.flags & (1<<3) ? '1' : '0',
- priv->sec.flags & (1<<2) ? '1' : '0',
- priv->sec.flags & (1<<1) ? '1' : '0',
- priv->sec.flags & (1<<0) ? '1' : '0');
+ priv->ieee->sec.flags & (1 << 8) ? '1' : '0',
+ priv->ieee->sec.flags & (1 << 7) ? '1' : '0',
+ priv->ieee->sec.flags & (1 << 6) ? '1' : '0',
+ priv->ieee->sec.flags & (1 << 5) ? '1' : '0',
+ priv->ieee->sec.flags & (1 << 4) ? '1' : '0',
+ priv->ieee->sec.flags & (1 << 3) ? '1' : '0',
+ priv->ieee->sec.flags & (1 << 2) ? '1' : '0',
+ priv->ieee->sec.flags & (1 << 1) ? '1' : '0',
+ priv->ieee->sec.flags & (1 << 0) ? '1' : '0');
/* As a temporary work around to enable WPA until we figure out why
* wpa_supplicant toggles the security capability of the driver, which
@@ -5535,7 +5507,7 @@ static void shim__set_security(struct net_device *dev,
* if (force_update || !(priv->status & STATUS_ASSOCIATED))*/
if (!(priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)))
ipw2100_configure_security(priv, 0);
-done:
+ done:
up(&priv->action_sem);
}
@@ -5560,7 +5532,7 @@ static int ipw2100_adapter_setup(struct ipw2100_priv *priv)
return 0;
}
-#endif /* CONFIG_IPW2100_MONITOR */
+#endif /* CONFIG_IPW2100_MONITOR */
err = ipw2100_read_mac_address(priv);
if (err)
@@ -5580,7 +5552,7 @@ static int ipw2100_adapter_setup(struct ipw2100_priv *priv)
return err;
}
- err = ipw2100_system_config(priv, batch_mode);
+ err = ipw2100_system_config(priv, batch_mode);
if (err)
return err;
@@ -5618,8 +5590,10 @@ static int ipw2100_adapter_setup(struct ipw2100_priv *priv)
return err;
if (priv->ieee->iw_mode == IW_MODE_ADHOC) {
- err = ipw2100_set_ibss_beacon_interval(
- priv, priv->beacon_interval, batch_mode);
+ err =
+ ipw2100_set_ibss_beacon_interval(priv,
+ priv->beacon_interval,
+ batch_mode);
if (err)
return err;
@@ -5629,18 +5603,17 @@ static int ipw2100_adapter_setup(struct ipw2100_priv *priv)
}
/*
- err = ipw2100_set_fragmentation_threshold(
- priv, priv->frag_threshold, batch_mode);
- if (err)
- return err;
- */
+ err = ipw2100_set_fragmentation_threshold(
+ priv, priv->frag_threshold, batch_mode);
+ if (err)
+ return err;
+ */
IPW_DEBUG_INFO("exit\n");
return 0;
}
-
/*************************************************************************
*
* EXTERNALLY CALLED METHODS
@@ -5673,7 +5646,7 @@ static int ipw2100_set_address(struct net_device *dev, void *p)
ipw2100_reset_adapter(priv);
return 0;
- done:
+ done:
up(&priv->action_sem);
return err;
}
@@ -5712,7 +5685,7 @@ static int ipw2100_close(struct net_device *dev)
/* Flush the TX queue ... */
while (!list_empty(&priv->tx_pend_list)) {
element = priv->tx_pend_list.next;
- packet = list_entry(element, struct ipw2100_tx_packet, list);
+ packet = list_entry(element, struct ipw2100_tx_packet, list);
list_del(element);
DEC_STAT(&priv->tx_pend_stat);
@@ -5730,8 +5703,6 @@ static int ipw2100_close(struct net_device *dev)
return 0;
}
-
-
/*
* TODO: Fix this function... its just wrong
*/
@@ -5751,7 +5722,6 @@ static void ipw2100_tx_timeout(struct net_device *dev)
schedule_reset(priv);
}
-
/*
* TODO: reimplement it so that it reads statistics
* from the adapter using ordinal tables
@@ -5765,11 +5735,10 @@ static struct net_device_stats *ipw2100_stats(struct net_device *dev)
return &priv->ieee->stats;
}
-/* Support for wpa_supplicant. Will be replaced with WEXT once
- * they get WPA support. */
-#ifdef CONFIG_IEEE80211_WPA
+#if WIRELESS_EXT < 18
+/* Support for wpa_supplicant before WE-18, deprecated. */
-/* following definitions must match definitions in driver_ipw2100.c */
+/* following definitions must match definitions in driver_ipw.c */
#define IPW2100_IOCTL_WPA_SUPPLICANT SIOCIWFIRSTPRIV+30
@@ -5800,25 +5769,26 @@ static struct net_device_stats *ipw2100_stats(struct net_device *dev)
struct ipw2100_param {
u32 cmd;
u8 sta_addr[ETH_ALEN];
- union {
+ union {
struct {
u8 name;
u32 value;
} wpa_param;
struct {
u32 len;
- u8 *data;
+ u8 reserved[32];
+ u8 data[0];
} wpa_ie;
- struct{
- int command;
- int reason_code;
+ struct {
+ u32 command;
+ u32 reason_code;
} mlme;
struct {
u8 alg[IPW2100_CRYPT_ALG_NAME_LEN];
u8 set_tx;
u32 err;
u8 idx;
- u8 seq[8]; /* sequence counter (set: RX, get: TX) */
+ u8 seq[8]; /* sequence counter (set: RX, get: TX) */
u16 key_len;
u8 key[0];
} crypt;
@@ -5826,38 +5796,24 @@ struct ipw2100_param {
} u;
};
-/* end of driver_ipw2100.c code */
+/* end of driver_ipw.c code */
+#endif /* WIRELESS_EXT < 18 */
-static int ipw2100_wpa_enable(struct ipw2100_priv *priv, int value){
-
- struct ieee80211_device *ieee = priv->ieee;
- struct ieee80211_security sec = {
- .flags = SEC_LEVEL | SEC_ENABLED,
- };
- int ret = 0;
-
- ieee->wpa_enabled = value;
-
- if (value){
- sec.level = SEC_LEVEL_3;
- sec.enabled = 1;
- } else {
- sec.level = SEC_LEVEL_0;
- sec.enabled = 0;
- }
-
- if (ieee->set_security)
- ieee->set_security(ieee->dev, &sec);
- else
- ret = -EOPNOTSUPP;
-
- return ret;
+static int ipw2100_wpa_enable(struct ipw2100_priv *priv, int value)
+{
+ /* This is called when wpa_supplicant loads and closes the driver
+ * interface. */
+ priv->ieee->wpa_enabled = value;
+ return 0;
}
-#define AUTH_ALG_OPEN_SYSTEM 0x1
-#define AUTH_ALG_SHARED_KEY 0x2
+#if WIRELESS_EXT < 18
+#define IW_AUTH_ALG_OPEN_SYSTEM 0x1
+#define IW_AUTH_ALG_SHARED_KEY 0x2
+#endif
-static int ipw2100_wpa_set_auth_algs(struct ipw2100_priv *priv, int value){
+static int ipw2100_wpa_set_auth_algs(struct ipw2100_priv *priv, int value)
+{
struct ieee80211_device *ieee = priv->ieee;
struct ieee80211_security sec = {
@@ -5865,13 +5821,14 @@ static int ipw2100_wpa_set_auth_algs(struct ipw2100_priv *priv, int value){
};
int ret = 0;
- if (value & AUTH_ALG_SHARED_KEY){
+ if (value & IW_AUTH_ALG_SHARED_KEY) {
sec.auth_mode = WLAN_AUTH_SHARED_KEY;
ieee->open_wep = 0;
- } else {
+ } else if (value & IW_AUTH_ALG_OPEN_SYSTEM) {
sec.auth_mode = WLAN_AUTH_OPEN;
ieee->open_wep = 1;
- }
+ } else
+ return -EINVAL;
if (ieee->set_security)
ieee->set_security(ieee->dev, &sec);
@@ -5881,103 +5838,135 @@ static int ipw2100_wpa_set_auth_algs(struct ipw2100_priv *priv, int value){
return ret;
}
+void ipw2100_wpa_assoc_frame(struct ipw2100_priv *priv,
+ char *wpa_ie, int wpa_ie_len)
+{
-static int ipw2100_wpa_set_param(struct net_device *dev, u8 name, u32 value){
-
- struct ipw2100_priv *priv = ieee80211_priv(dev);
- int ret=0;
+ struct ipw2100_wpa_assoc_frame frame;
- switch(name){
- case IPW2100_PARAM_WPA_ENABLED:
- ret = ipw2100_wpa_enable(priv, value);
- break;
+ frame.fixed_ie_mask = 0;
- case IPW2100_PARAM_TKIP_COUNTERMEASURES:
- priv->ieee->tkip_countermeasures=value;
- break;
+ /* copy WPA IE */
+ memcpy(frame.var_ie, wpa_ie, wpa_ie_len);
+ frame.var_ie_len = wpa_ie_len;
- case IPW2100_PARAM_DROP_UNENCRYPTED:
- priv->ieee->drop_unencrypted=value;
- break;
+ /* make sure WPA is enabled */
+ ipw2100_wpa_enable(priv, 1);
+ ipw2100_set_wpa_ie(priv, &frame, 0);
+}
- case IPW2100_PARAM_PRIVACY_INVOKED:
- priv->ieee->privacy_invoked=value;
- break;
+#if WIRELESS_EXT < 18
+static int ipw2100_wpa_set_param(struct net_device *dev, u8 name, u32 value)
+{
+ struct ipw2100_priv *priv = ieee80211_priv(dev);
+ struct ieee80211_crypt_data *crypt;
+ unsigned long flags;
+ int ret = 0;
- case IPW2100_PARAM_AUTH_ALGS:
- ret = ipw2100_wpa_set_auth_algs(priv, value);
- break;
+ switch (name) {
+ case IPW2100_PARAM_WPA_ENABLED:
+ ret = ipw2100_wpa_enable(priv, value);
+ break;
- case IPW2100_PARAM_IEEE_802_1X:
- priv->ieee->ieee802_1x=value;
+ case IPW2100_PARAM_TKIP_COUNTERMEASURES:
+ crypt = priv->ieee->crypt[priv->ieee->tx_keyidx];
+ if (!crypt || !crypt->ops->set_flags || !crypt->ops->get_flags)
break;
- default:
- printk(KERN_ERR DRV_NAME ": %s: Unknown WPA param: %d\n",
- dev->name, name);
- ret = -EOPNOTSUPP;
- }
+ flags = crypt->ops->get_flags(crypt->priv);
- return ret;
-}
+ if (value)
+ flags |= IEEE80211_CRYPTO_TKIP_COUNTERMEASURES;
+ else
+ flags &= ~IEEE80211_CRYPTO_TKIP_COUNTERMEASURES;
-static int ipw2100_wpa_mlme(struct net_device *dev, int command, int reason){
+ crypt->ops->set_flags(flags, crypt->priv);
- struct ipw2100_priv *priv = ieee80211_priv(dev);
- int ret=0;
+ break;
- switch(command){
- case IPW2100_MLME_STA_DEAUTH:
- // silently ignore
+ case IPW2100_PARAM_DROP_UNENCRYPTED:{
+ /* See IW_AUTH_DROP_UNENCRYPTED handling for details */
+ struct ieee80211_security sec = {
+ .flags = SEC_ENABLED,
+ .enabled = value,
+ };
+ priv->ieee->drop_unencrypted = value;
+ /* We only change SEC_LEVEL for open mode. Others
+ * are set by ipw_wpa_set_encryption.
+ */
+ if (!value) {
+ sec.flags |= SEC_LEVEL;
+ sec.level = SEC_LEVEL_0;
+ } else {
+ sec.flags |= SEC_LEVEL;
+ sec.level = SEC_LEVEL_1;
+ }
+ if (priv->ieee->set_security)
+ priv->ieee->set_security(priv->ieee->dev, &sec);
break;
+ }
- case IPW2100_MLME_STA_DISASSOC:
- ipw2100_disassociate_bssid(priv);
- break;
+ case IPW2100_PARAM_PRIVACY_INVOKED:
+ priv->ieee->privacy_invoked = value;
+ break;
- default:
- printk(KERN_ERR DRV_NAME ": %s: Unknown MLME request: %d\n",
- dev->name, command);
- ret = -EOPNOTSUPP;
+ case IPW2100_PARAM_AUTH_ALGS:
+ ret = ipw2100_wpa_set_auth_algs(priv, value);
+ break;
+
+ case IPW2100_PARAM_IEEE_802_1X:
+ priv->ieee->ieee802_1x = value;
+ break;
+
+ default:
+ printk(KERN_ERR DRV_NAME ": %s: Unknown WPA param: %d\n",
+ dev->name, name);
+ ret = -EOPNOTSUPP;
}
return ret;
}
+static int ipw2100_wpa_mlme(struct net_device *dev, int command, int reason)
+{
-void ipw2100_wpa_assoc_frame(struct ipw2100_priv *priv,
- char *wpa_ie, int wpa_ie_len){
+ struct ipw2100_priv *priv = ieee80211_priv(dev);
+ int ret = 0;
- struct ipw2100_wpa_assoc_frame frame;
+ switch (command) {
+ case IPW2100_MLME_STA_DEAUTH:
+ // silently ignore
+ break;
- frame.fixed_ie_mask = 0;
+ case IPW2100_MLME_STA_DISASSOC:
+ ipw2100_disassociate_bssid(priv);
+ break;
- /* copy WPA IE */
- memcpy(frame.var_ie, wpa_ie, wpa_ie_len);
- frame.var_ie_len = wpa_ie_len;
+ default:
+ printk(KERN_ERR DRV_NAME ": %s: Unknown MLME request: %d\n",
+ dev->name, command);
+ ret = -EOPNOTSUPP;
+ }
- /* make sure WPA is enabled */
- ipw2100_wpa_enable(priv, 1);
- ipw2100_set_wpa_ie(priv, &frame, 0);
+ return ret;
}
-
static int ipw2100_wpa_set_wpa_ie(struct net_device *dev,
- struct ipw2100_param *param, int plen){
+ struct ipw2100_param *param, int plen)
+{
struct ipw2100_priv *priv = ieee80211_priv(dev);
struct ieee80211_device *ieee = priv->ieee;
u8 *buf;
- if (! ieee->wpa_enabled)
- return -EOPNOTSUPP;
+ if (!ieee->wpa_enabled)
+ return -EOPNOTSUPP;
if (param->u.wpa_ie.len > MAX_WPA_IE_LEN ||
- (param->u.wpa_ie.len &&
- param->u.wpa_ie.data==NULL))
+ (param->u.wpa_ie.len && param->u.wpa_ie.data == NULL))
return -EINVAL;
- if (param->u.wpa_ie.len){
+ if (param->u.wpa_ie.len) {
buf = kmalloc(param->u.wpa_ie.len, GFP_KERNEL);
if (buf == NULL)
return -ENOMEM;
@@ -6002,8 +5991,9 @@ static int ipw2100_wpa_set_wpa_ie(struct net_device *dev,
/* implementation borrowed from hostap driver */
static int ipw2100_wpa_set_encryption(struct net_device *dev,
- struct ipw2100_param *param, int param_len){
-
+ struct ipw2100_param *param,
+ int param_len)
+{
int ret = 0;
struct ipw2100_priv *priv = ieee80211_priv(dev);
struct ieee80211_device *ieee = priv->ieee;
@@ -6018,9 +6008,10 @@ static int ipw2100_wpa_set_encryption(struct net_device *dev,
param->u.crypt.alg[IPW2100_CRYPT_ALG_NAME_LEN - 1] = '\0';
if (param_len !=
- (int) ((char *) param->u.crypt.key - (char *) param) +
- param->u.crypt.key_len){
- IPW_DEBUG_INFO("Len mismatch %d, %d\n", param_len, param->u.crypt.key_len);
+ (int)((char *)param->u.crypt.key - (char *)param) +
+ param->u.crypt.key_len) {
+ IPW_DEBUG_INFO("Len mismatch %d, %d\n", param_len,
+ param->u.crypt.key_len);
return -EINVAL;
}
if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
@@ -6033,17 +6024,19 @@ static int ipw2100_wpa_set_encryption(struct net_device *dev,
return -EINVAL;
}
+ sec.flags |= SEC_ENABLED | SEC_ENCRYPT;
if (strcmp(param->u.crypt.alg, "none") == 0) {
- if (crypt){
+ if (crypt) {
sec.enabled = 0;
+ sec.encrypt = 0;
sec.level = SEC_LEVEL_0;
- sec.flags |= SEC_ENABLED | SEC_LEVEL;
+ sec.flags |= SEC_LEVEL;
ieee80211_crypt_delayed_deinit(ieee, crypt);
}
goto done;
}
sec.enabled = 1;
- sec.flags |= SEC_ENABLED;
+ sec.encrypt = 1;
ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
if (ops == NULL && strcmp(param->u.crypt.alg, "WEP") == 0) {
@@ -6058,7 +6051,7 @@ static int ipw2100_wpa_set_encryption(struct net_device *dev,
}
if (ops == NULL) {
IPW_DEBUG_INFO("%s: unknown crypto alg '%s'\n",
- dev->name, param->u.crypt.alg);
+ dev->name, param->u.crypt.alg);
param->u.crypt.err = IPW2100_CRYPT_ERR_UNKNOWN_ALG;
ret = -EINVAL;
goto done;
@@ -6069,21 +6062,20 @@ static int ipw2100_wpa_set_encryption(struct net_device *dev,
ieee80211_crypt_delayed_deinit(ieee, crypt);
- new_crypt = (struct ieee80211_crypt_data *)
- kmalloc(sizeof(struct ieee80211_crypt_data), GFP_KERNEL);
+ new_crypt = kzalloc(sizeof(struct ieee80211_crypt_data), GFP_KERNEL);
if (new_crypt == NULL) {
ret = -ENOMEM;
goto done;
}
- memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data));
new_crypt->ops = ops;
if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
- new_crypt->priv = new_crypt->ops->init(param->u.crypt.idx);
+ new_crypt->priv =
+ new_crypt->ops->init(param->u.crypt.idx);
if (new_crypt->priv == NULL) {
kfree(new_crypt);
param->u.crypt.err =
- IPW2100_CRYPT_ERR_CRYPT_INIT_FAILED;
+ IPW2100_CRYPT_ERR_CRYPT_INIT_FAILED;
ret = -EINVAL;
goto done;
}
@@ -6095,24 +6087,25 @@ static int ipw2100_wpa_set_encryption(struct net_device *dev,
(*crypt)->ops->set_key(param->u.crypt.key,
param->u.crypt.key_len, param->u.crypt.seq,
(*crypt)->priv) < 0) {
- IPW_DEBUG_INFO("%s: key setting failed\n",
- dev->name);
+ IPW_DEBUG_INFO("%s: key setting failed\n", dev->name);
param->u.crypt.err = IPW2100_CRYPT_ERR_KEY_SET_FAILED;
ret = -EINVAL;
goto done;
}
- if (param->u.crypt.set_tx){
+ if (param->u.crypt.set_tx) {
ieee->tx_keyidx = param->u.crypt.idx;
sec.active_key = param->u.crypt.idx;
sec.flags |= SEC_ACTIVE_KEY;
}
- if (ops->name != NULL){
+ if (ops->name != NULL) {
if (strcmp(ops->name, "WEP") == 0) {
- memcpy(sec.keys[param->u.crypt.idx], param->u.crypt.key, param->u.crypt.key_len);
- sec.key_sizes[param->u.crypt.idx] = param->u.crypt.key_len;
+ memcpy(sec.keys[param->u.crypt.idx],
+ param->u.crypt.key, param->u.crypt.key_len);
+ sec.key_sizes[param->u.crypt.idx] =
+ param->u.crypt.key_len;
sec.flags |= (1 << param->u.crypt.idx);
sec.flags |= SEC_LEVEL;
sec.level = SEC_LEVEL_1;
@@ -6124,7 +6117,7 @@ static int ipw2100_wpa_set_encryption(struct net_device *dev,
sec.level = SEC_LEVEL_3;
}
}
- done:
+ done:
if (ieee->set_security)
ieee->set_security(ieee->dev, &sec);
@@ -6135,8 +6128,7 @@ static int ipw2100_wpa_set_encryption(struct net_device *dev,
* the callbacks structures used to initialize the 802.11 stack. */
if (ieee->reset_on_keychange &&
ieee->iw_mode != IW_MODE_INFRA &&
- ieee->reset_port &&
- ieee->reset_port(dev)) {
+ ieee->reset_port && ieee->reset_port(dev)) {
IPW_DEBUG_INFO("%s: reset_port failed\n", dev->name);
param->u.crypt.err = IPW2100_CRYPT_ERR_CARD_CONF_FAILED;
return -EINVAL;
@@ -6145,11 +6137,11 @@ static int ipw2100_wpa_set_encryption(struct net_device *dev,
return ret;
}
-
-static int ipw2100_wpa_supplicant(struct net_device *dev, struct iw_point *p){
+static int ipw2100_wpa_supplicant(struct net_device *dev, struct iw_point *p)
+{
struct ipw2100_param *param;
- int ret=0;
+ int ret = 0;
IPW_DEBUG_IOCTL("wpa_supplicant: len=%d\n", p->length);
@@ -6160,12 +6152,12 @@ static int ipw2100_wpa_supplicant(struct net_device *dev, struct iw_point *p){
if (param == NULL)
return -ENOMEM;
- if (copy_from_user(param, p->pointer, p->length)){
+ if (copy_from_user(param, p->pointer, p->length)) {
kfree(param);
return -EFAULT;
}
- switch (param->cmd){
+ switch (param->cmd) {
case IPW2100_CMD_SET_WPA_PARAM:
ret = ipw2100_wpa_set_param(dev, param->u.wpa_param.name,
@@ -6186,8 +6178,9 @@ static int ipw2100_wpa_supplicant(struct net_device *dev, struct iw_point *p){
break;
default:
- printk(KERN_ERR DRV_NAME ": %s: Unknown WPA supplicant request: %d\n",
- dev->name, param->cmd);
+ printk(KERN_ERR DRV_NAME
+ ": %s: Unknown WPA supplicant request: %d\n", dev->name,
+ param->cmd);
ret = -EOPNOTSUPP;
}
@@ -6198,27 +6191,23 @@ static int ipw2100_wpa_supplicant(struct net_device *dev, struct iw_point *p){
kfree(param);
return ret;
}
-#endif /* CONFIG_IEEE80211_WPA */
static int ipw2100_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
{
-#ifdef CONFIG_IEEE80211_WPA
- struct iwreq *wrq = (struct iwreq *) rq;
- int ret=-1;
- switch (cmd){
- case IPW2100_IOCTL_WPA_SUPPLICANT:
+ struct iwreq *wrq = (struct iwreq *)rq;
+ int ret = -1;
+ switch (cmd) {
+ case IPW2100_IOCTL_WPA_SUPPLICANT:
ret = ipw2100_wpa_supplicant(dev, &wrq->u.data);
return ret;
- default:
+ default:
return -EOPNOTSUPP;
}
-#endif /* CONFIG_IEEE80211_WPA */
-
return -EOPNOTSUPP;
}
-
+#endif /* WIRELESS_EXT < 18 */
static void ipw_ethtool_get_drvinfo(struct net_device *dev,
struct ethtool_drvinfo *info)
@@ -6240,14 +6229,13 @@ static void ipw_ethtool_get_drvinfo(struct net_device *dev,
static u32 ipw2100_ethtool_get_link(struct net_device *dev)
{
- struct ipw2100_priv *priv = ieee80211_priv(dev);
- return (priv->status & STATUS_ASSOCIATED) ? 1 : 0;
+ struct ipw2100_priv *priv = ieee80211_priv(dev);
+ return (priv->status & STATUS_ASSOCIATED) ? 1 : 0;
}
-
static struct ethtool_ops ipw2100_ethtool_ops = {
- .get_link = ipw2100_ethtool_get_link,
- .get_drvinfo = ipw_ethtool_get_drvinfo,
+ .get_link = ipw2100_ethtool_get_link,
+ .get_drvinfo = ipw_ethtool_get_drvinfo,
};
static void ipw2100_hang_check(void *adapter)
@@ -6292,7 +6280,6 @@ static void ipw2100_hang_check(void *adapter)
spin_unlock_irqrestore(&priv->low_lock, flags);
}
-
static void ipw2100_rf_kill(void *adapter)
{
struct ipw2100_priv *priv = adapter;
@@ -6317,7 +6304,7 @@ static void ipw2100_rf_kill(void *adapter)
IPW_DEBUG_RF_KILL("HW RF Kill deactivated. SW RF Kill still "
"enabled\n");
- exit_unlock:
+ exit_unlock:
spin_unlock_irqrestore(&priv->low_lock, flags);
}
@@ -6325,11 +6312,10 @@ static void ipw2100_irq_tasklet(struct ipw2100_priv *priv);
/* Look into using netdev destructor to shutdown ieee80211? */
-static struct net_device *ipw2100_alloc_device(
- struct pci_dev *pci_dev,
- void __iomem *base_addr,
- unsigned long mem_start,
- unsigned long mem_len)
+static struct net_device *ipw2100_alloc_device(struct pci_dev *pci_dev,
+ void __iomem * base_addr,
+ unsigned long mem_start,
+ unsigned long mem_len)
{
struct ipw2100_priv *priv;
struct net_device *dev;
@@ -6345,17 +6331,22 @@ static struct net_device *ipw2100_alloc_device(
priv->ieee->hard_start_xmit = ipw2100_tx;
priv->ieee->set_security = shim__set_security;
+ priv->ieee->perfect_rssi = -20;
+ priv->ieee->worst_rssi = -85;
+
dev->open = ipw2100_open;
dev->stop = ipw2100_close;
dev->init = ipw2100_net_init;
+#if WIRELESS_EXT < 18
dev->do_ioctl = ipw2100_ioctl;
+#endif
dev->get_stats = ipw2100_stats;
dev->ethtool_ops = &ipw2100_ethtool_ops;
dev->tx_timeout = ipw2100_tx_timeout;
dev->wireless_handlers = &ipw2100_wx_handler_def;
dev->get_wireless_stats = ipw2100_wx_wireless_stats;
dev->set_mac_address = ipw2100_set_address;
- dev->watchdog_timeo = 3*HZ;
+ dev->watchdog_timeo = 3 * HZ;
dev->irq = 0;
dev->base_addr = (unsigned long)base_addr;
@@ -6368,22 +6359,19 @@ static struct net_device *ipw2100_alloc_device(
* ends up causing problems. So, we just handle
* the WX extensions through the ipw2100_ioctl interface */
-
/* memset() puts everything to 0, so we only have explicitely set
* those values that need to be something else */
/* If power management is turned on, default to AUTO mode */
priv->power_mode = IPW_POWER_AUTO;
-
-
-#ifdef CONFIG_IEEE80211_WPA
+#ifdef CONFIG_IPW2100_MONITOR
+ priv->config |= CFG_CRC_CHECK;
+#endif
priv->ieee->wpa_enabled = 0;
- priv->ieee->tkip_countermeasures = 0;
priv->ieee->drop_unencrypted = 0;
priv->ieee->privacy_invoked = 0;
priv->ieee->ieee802_1x = 1;
-#endif /* CONFIG_IEEE80211_WPA */
/* Set module parameters */
switch (mode) {
@@ -6405,8 +6393,7 @@ static struct net_device *ipw2100_alloc_device(
priv->status |= STATUS_RF_KILL_SW;
if (channel != 0 &&
- ((channel >= REG_MIN_CHANNEL) &&
- (channel <= REG_MAX_CHANNEL))) {
+ ((channel >= REG_MIN_CHANNEL) && (channel <= REG_MAX_CHANNEL))) {
priv->config |= CFG_STATIC_CHANNEL;
priv->channel = channel;
}
@@ -6445,12 +6432,8 @@ static struct net_device *ipw2100_alloc_device(
INIT_LIST_HEAD(&priv->fw_pend_list);
INIT_STAT(&priv->fw_pend_stat);
-
-#ifdef CONFIG_SOFTWARE_SUSPEND2
- priv->workqueue = create_workqueue(DRV_NAME, 0);
-#else
priv->workqueue = create_workqueue(DRV_NAME);
-#endif
+
INIT_WORK(&priv->reset_work,
(void (*)(void *))ipw2100_reset_adapter, priv);
INIT_WORK(&priv->security_work,
@@ -6539,7 +6522,7 @@ static int ipw2100_pci_init_one(struct pci_dev *pci_dev,
return err;
}
- /* We disable the RETRY_TIMEOUT register (0x41) to keep
+ /* We disable the RETRY_TIMEOUT register (0x41) to keep
* PCI Tx retries from interfering with C3 CPU state */
pci_read_config_dword(pci_dev, 0x40, &val);
if ((val & 0x0000ff00) != 0)
@@ -6570,12 +6553,10 @@ static int ipw2100_pci_init_one(struct pci_dev *pci_dev,
ipw2100_queues_initialize(priv);
err = request_irq(pci_dev->irq,
- ipw2100_interrupt, SA_SHIRQ,
- dev->name, priv);
+ ipw2100_interrupt, SA_SHIRQ, dev->name, priv);
if (err) {
printk(KERN_WARNING DRV_NAME
- "Error calling request_irq: %d.\n",
- pci_dev->irq);
+ "Error calling request_irq: %d.\n", pci_dev->irq);
goto fail;
}
dev->irq = pci_dev->irq;
@@ -6610,7 +6591,6 @@ static int ipw2100_pci_init_one(struct pci_dev *pci_dev,
/* perform this after register_netdev so that dev->name is set */
sysfs_create_group(&pci_dev->dev.kobj, &ipw2100_attribute_group);
- netif_carrier_off(dev);
/* If the RF Kill switch is disabled, go ahead and complete the
* startup sequence */
@@ -6638,10 +6618,10 @@ static int ipw2100_pci_init_one(struct pci_dev *pci_dev,
return 0;
- fail_unlock:
+ fail_unlock:
up(&priv->action_sem);
- fail:
+ fail:
if (dev) {
if (registered)
unregister_netdev(dev);
@@ -6657,7 +6637,8 @@ static int ipw2100_pci_init_one(struct pci_dev *pci_dev,
/* These are safe to call even if they weren't allocated */
ipw2100_queues_free(priv);
- sysfs_remove_group(&pci_dev->dev.kobj, &ipw2100_attribute_group);
+ sysfs_remove_group(&pci_dev->dev.kobj,
+ &ipw2100_attribute_group);
free_ieee80211(dev);
pci_set_drvdata(pci_dev, NULL);
@@ -6683,7 +6664,8 @@ static void __devexit ipw2100_pci_remove_one(struct pci_dev *pci_dev)
priv->status &= ~STATUS_INITIALIZED;
dev = priv->net_dev;
- sysfs_remove_group(&pci_dev->dev.kobj, &ipw2100_attribute_group);
+ sysfs_remove_group(&pci_dev->dev.kobj,
+ &ipw2100_attribute_group);
#ifdef CONFIG_PM
if (ipw2100_firmware.version)
@@ -6725,19 +6707,13 @@ static void __devexit ipw2100_pci_remove_one(struct pci_dev *pci_dev)
IPW_DEBUG_INFO("exit\n");
}
-
#ifdef CONFIG_PM
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11)
-static int ipw2100_suspend(struct pci_dev *pci_dev, u32 state)
-#else
static int ipw2100_suspend(struct pci_dev *pci_dev, pm_message_t state)
-#endif
{
struct ipw2100_priv *priv = pci_get_drvdata(pci_dev);
struct net_device *dev = priv->net_dev;
- IPW_DEBUG_INFO("%s: Going into suspend...\n",
- dev->name);
+ IPW_DEBUG_INFO("%s: Going into suspend...\n", dev->name);
down(&priv->action_sem);
if (priv->status & STATUS_INITIALIZED) {
@@ -6749,7 +6725,7 @@ static int ipw2100_suspend(struct pci_dev *pci_dev, pm_message_t state)
netif_device_detach(dev);
pci_save_state(pci_dev);
- pci_disable_device (pci_dev);
+ pci_disable_device(pci_dev);
pci_set_power_state(pci_dev, PCI_D3hot);
up(&priv->action_sem);
@@ -6768,8 +6744,7 @@ static int ipw2100_resume(struct pci_dev *pci_dev)
down(&priv->action_sem);
- IPW_DEBUG_INFO("%s: Coming out of suspend...\n",
- dev->name);
+ IPW_DEBUG_INFO("%s: Coming out of suspend...\n", dev->name);
pci_set_power_state(pci_dev, PCI_D0);
pci_enable_device(pci_dev);
@@ -6789,9 +6764,9 @@ static int ipw2100_resume(struct pci_dev *pci_dev)
* the queue of needed */
netif_device_attach(dev);
- /* Bring the device back up */
- if (!(priv->status & STATUS_RF_KILL_SW))
- ipw2100_up(priv, 0);
+ /* Bring the device back up */
+ if (!(priv->status & STATUS_RF_KILL_SW))
+ ipw2100_up(priv, 0);
up(&priv->action_sem);
@@ -6799,56 +6774,55 @@ static int ipw2100_resume(struct pci_dev *pci_dev)
}
#endif
-
#define IPW2100_DEV_ID(x) { PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, x }
static struct pci_device_id ipw2100_pci_id_table[] __devinitdata = {
- IPW2100_DEV_ID(0x2520), /* IN 2100A mPCI 3A */
- IPW2100_DEV_ID(0x2521), /* IN 2100A mPCI 3B */
- IPW2100_DEV_ID(0x2524), /* IN 2100A mPCI 3B */
- IPW2100_DEV_ID(0x2525), /* IN 2100A mPCI 3B */
- IPW2100_DEV_ID(0x2526), /* IN 2100A mPCI Gen A3 */
- IPW2100_DEV_ID(0x2522), /* IN 2100 mPCI 3B */
- IPW2100_DEV_ID(0x2523), /* IN 2100 mPCI 3A */
- IPW2100_DEV_ID(0x2527), /* IN 2100 mPCI 3B */
- IPW2100_DEV_ID(0x2528), /* IN 2100 mPCI 3B */
- IPW2100_DEV_ID(0x2529), /* IN 2100 mPCI 3B */
- IPW2100_DEV_ID(0x252B), /* IN 2100 mPCI 3A */
- IPW2100_DEV_ID(0x252C), /* IN 2100 mPCI 3A */
- IPW2100_DEV_ID(0x252D), /* IN 2100 mPCI 3A */
-
- IPW2100_DEV_ID(0x2550), /* IB 2100A mPCI 3B */
- IPW2100_DEV_ID(0x2551), /* IB 2100 mPCI 3B */
- IPW2100_DEV_ID(0x2553), /* IB 2100 mPCI 3B */
- IPW2100_DEV_ID(0x2554), /* IB 2100 mPCI 3B */
- IPW2100_DEV_ID(0x2555), /* IB 2100 mPCI 3B */
-
- IPW2100_DEV_ID(0x2560), /* DE 2100A mPCI 3A */
- IPW2100_DEV_ID(0x2562), /* DE 2100A mPCI 3A */
- IPW2100_DEV_ID(0x2563), /* DE 2100A mPCI 3A */
- IPW2100_DEV_ID(0x2561), /* DE 2100 mPCI 3A */
- IPW2100_DEV_ID(0x2565), /* DE 2100 mPCI 3A */
- IPW2100_DEV_ID(0x2566), /* DE 2100 mPCI 3A */
- IPW2100_DEV_ID(0x2567), /* DE 2100 mPCI 3A */
-
- IPW2100_DEV_ID(0x2570), /* GA 2100 mPCI 3B */
-
- IPW2100_DEV_ID(0x2580), /* TO 2100A mPCI 3B */
- IPW2100_DEV_ID(0x2582), /* TO 2100A mPCI 3B */
- IPW2100_DEV_ID(0x2583), /* TO 2100A mPCI 3B */
- IPW2100_DEV_ID(0x2581), /* TO 2100 mPCI 3B */
- IPW2100_DEV_ID(0x2585), /* TO 2100 mPCI 3B */
- IPW2100_DEV_ID(0x2586), /* TO 2100 mPCI 3B */
- IPW2100_DEV_ID(0x2587), /* TO 2100 mPCI 3B */
-
- IPW2100_DEV_ID(0x2590), /* SO 2100A mPCI 3B */
- IPW2100_DEV_ID(0x2592), /* SO 2100A mPCI 3B */
- IPW2100_DEV_ID(0x2591), /* SO 2100 mPCI 3B */
- IPW2100_DEV_ID(0x2593), /* SO 2100 mPCI 3B */
- IPW2100_DEV_ID(0x2596), /* SO 2100 mPCI 3B */
- IPW2100_DEV_ID(0x2598), /* SO 2100 mPCI 3B */
-
- IPW2100_DEV_ID(0x25A0), /* HP 2100 mPCI 3B */
+ IPW2100_DEV_ID(0x2520), /* IN 2100A mPCI 3A */
+ IPW2100_DEV_ID(0x2521), /* IN 2100A mPCI 3B */
+ IPW2100_DEV_ID(0x2524), /* IN 2100A mPCI 3B */
+ IPW2100_DEV_ID(0x2525), /* IN 2100A mPCI 3B */
+ IPW2100_DEV_ID(0x2526), /* IN 2100A mPCI Gen A3 */
+ IPW2100_DEV_ID(0x2522), /* IN 2100 mPCI 3B */
+ IPW2100_DEV_ID(0x2523), /* IN 2100 mPCI 3A */
+ IPW2100_DEV_ID(0x2527), /* IN 2100 mPCI 3B */
+ IPW2100_DEV_ID(0x2528), /* IN 2100 mPCI 3B */
+ IPW2100_DEV_ID(0x2529), /* IN 2100 mPCI 3B */
+ IPW2100_DEV_ID(0x252B), /* IN 2100 mPCI 3A */
+ IPW2100_DEV_ID(0x252C), /* IN 2100 mPCI 3A */
+ IPW2100_DEV_ID(0x252D), /* IN 2100 mPCI 3A */
+
+ IPW2100_DEV_ID(0x2550), /* IB 2100A mPCI 3B */
+ IPW2100_DEV_ID(0x2551), /* IB 2100 mPCI 3B */
+ IPW2100_DEV_ID(0x2553), /* IB 2100 mPCI 3B */
+ IPW2100_DEV_ID(0x2554), /* IB 2100 mPCI 3B */
+ IPW2100_DEV_ID(0x2555), /* IB 2100 mPCI 3B */
+
+ IPW2100_DEV_ID(0x2560), /* DE 2100A mPCI 3A */
+ IPW2100_DEV_ID(0x2562), /* DE 2100A mPCI 3A */
+ IPW2100_DEV_ID(0x2563), /* DE 2100A mPCI 3A */
+ IPW2100_DEV_ID(0x2561), /* DE 2100 mPCI 3A */
+ IPW2100_DEV_ID(0x2565), /* DE 2100 mPCI 3A */
+ IPW2100_DEV_ID(0x2566), /* DE 2100 mPCI 3A */
+ IPW2100_DEV_ID(0x2567), /* DE 2100 mPCI 3A */
+
+ IPW2100_DEV_ID(0x2570), /* GA 2100 mPCI 3B */
+
+ IPW2100_DEV_ID(0x2580), /* TO 2100A mPCI 3B */
+ IPW2100_DEV_ID(0x2582), /* TO 2100A mPCI 3B */
+ IPW2100_DEV_ID(0x2583), /* TO 2100A mPCI 3B */
+ IPW2100_DEV_ID(0x2581), /* TO 2100 mPCI 3B */
+ IPW2100_DEV_ID(0x2585), /* TO 2100 mPCI 3B */
+ IPW2100_DEV_ID(0x2586), /* TO 2100 mPCI 3B */
+ IPW2100_DEV_ID(0x2587), /* TO 2100 mPCI 3B */
+
+ IPW2100_DEV_ID(0x2590), /* SO 2100A mPCI 3B */
+ IPW2100_DEV_ID(0x2592), /* SO 2100A mPCI 3B */
+ IPW2100_DEV_ID(0x2591), /* SO 2100 mPCI 3B */
+ IPW2100_DEV_ID(0x2593), /* SO 2100 mPCI 3B */
+ IPW2100_DEV_ID(0x2596), /* SO 2100 mPCI 3B */
+ IPW2100_DEV_ID(0x2598), /* SO 2100 mPCI 3B */
+
+ IPW2100_DEV_ID(0x25A0), /* HP 2100 mPCI 3B */
{0,},
};
@@ -6865,7 +6839,6 @@ static struct pci_driver ipw2100_pci_driver = {
#endif
};
-
/**
* Initialize the ipw2100 driver/module
*
@@ -6882,10 +6855,6 @@ static int __init ipw2100_init(void)
printk(KERN_INFO DRV_NAME ": %s, %s\n", DRV_DESCRIPTION, DRV_VERSION);
printk(KERN_INFO DRV_NAME ": %s\n", DRV_COPYRIGHT);
-#ifdef CONFIG_IEEE80211_NOWEP
- IPW_DEBUG_INFO(DRV_NAME ": Compiled with WEP disabled.\n");
-#endif
-
ret = pci_module_init(&ipw2100_pci_driver);
#ifdef CONFIG_IPW_DEBUG
@@ -6897,7 +6866,6 @@ static int __init ipw2100_init(void)
return ret;
}
-
/**
* Cleanup ipw2100 driver registration
*/
@@ -6953,7 +6921,6 @@ static int ipw2100_wx_get_name(struct net_device *dev,
return 0;
}
-
static int ipw2100_wx_set_freq(struct net_device *dev,
struct iw_request_info *info,
union iwreq_data *wrqu, char *extra)
@@ -6973,8 +6940,7 @@ static int ipw2100_wx_set_freq(struct net_device *dev,
/* if setting by freq convert to channel */
if (fwrq->e == 1) {
- if ((fwrq->m >= (int) 2.412e8 &&
- fwrq->m <= (int) 2.487e8)) {
+ if ((fwrq->m >= (int)2.412e8 && fwrq->m <= (int)2.487e8)) {
int f = fwrq->m / 100000;
int c = 0;
@@ -6988,19 +6954,19 @@ static int ipw2100_wx_set_freq(struct net_device *dev,
}
}
- if (fwrq->e > 0 || fwrq->m > 1000)
- return -EOPNOTSUPP;
- else { /* Set the channel */
+ if (fwrq->e > 0 || fwrq->m > 1000) {
+ err = -EOPNOTSUPP;
+ goto done;
+ } else { /* Set the channel */
IPW_DEBUG_WX("SET Freq/Channel -> %d \n", fwrq->m);
err = ipw2100_set_channel(priv, fwrq->m, 0);
}
- done:
+ done:
up(&priv->action_sem);
return err;
}
-
static int ipw2100_wx_get_freq(struct net_device *dev,
struct iw_request_info *info,
union iwreq_data *wrqu, char *extra)
@@ -7049,7 +7015,7 @@ static int ipw2100_wx_set_mode(struct net_device *dev,
case IW_MODE_MONITOR:
err = ipw2100_switch_mode(priv, IW_MODE_MONITOR);
break;
-#endif /* CONFIG_IPW2100_MONITOR */
+#endif /* CONFIG_IPW2100_MONITOR */
case IW_MODE_ADHOC:
err = ipw2100_switch_mode(priv, IW_MODE_ADHOC);
break;
@@ -7060,9 +7026,9 @@ static int ipw2100_wx_set_mode(struct net_device *dev,
break;
}
-done:
+ done:
up(&priv->action_sem);
- return err;
+ return err;
}
static int ipw2100_wx_get_mode(struct net_device *dev,
@@ -7081,7 +7047,6 @@ static int ipw2100_wx_get_mode(struct net_device *dev,
return 0;
}
-
#define POWER_MODES 5
/* Values are in microsecond */
@@ -7128,19 +7093,19 @@ static int ipw2100_wx_get_range(struct net_device *dev,
/* ~5 Mb/s real (802.11b) */
range->throughput = 5 * 1000 * 1000;
-// range->sensitivity; /* signal level threshold range */
+// range->sensitivity; /* signal level threshold range */
range->max_qual.qual = 100;
/* TODO: Find real max RSSI and stick here */
range->max_qual.level = 0;
range->max_qual.noise = 0;
- range->max_qual.updated = 7; /* Updated all three */
+ range->max_qual.updated = 7; /* Updated all three */
- range->avg_qual.qual = 70; /* > 8% missed beacons is 'bad' */
+ range->avg_qual.qual = 70; /* > 8% missed beacons is 'bad' */
/* TODO: Find real 'good' to 'bad' threshol value for RSSI */
range->avg_qual.level = 20 + IPW2100_RSSI_TO_DBM;
range->avg_qual.noise = 0;
- range->avg_qual.updated = 7; /* Updated all three */
+ range->avg_qual.updated = 7; /* Updated all three */
range->num_bitrates = RATE_COUNT;
@@ -7154,61 +7119,62 @@ static int ipw2100_wx_get_range(struct net_device *dev,
range->max_frag = MAX_FRAG_THRESHOLD;
range->min_pmp = period_duration[0]; /* Minimal PM period */
- range->max_pmp = period_duration[POWER_MODES-1];/* Maximal PM period */
- range->min_pmt = timeout_duration[POWER_MODES-1]; /* Minimal PM timeout */
- range->max_pmt = timeout_duration[0];/* Maximal PM timeout */
+ range->max_pmp = period_duration[POWER_MODES - 1]; /* Maximal PM period */
+ range->min_pmt = timeout_duration[POWER_MODES - 1]; /* Minimal PM timeout */
+ range->max_pmt = timeout_duration[0]; /* Maximal PM timeout */
- /* How to decode max/min PM period */
+ /* How to decode max/min PM period */
range->pmp_flags = IW_POWER_PERIOD;
- /* How to decode max/min PM period */
+ /* How to decode max/min PM period */
range->pmt_flags = IW_POWER_TIMEOUT;
/* What PM options are supported */
range->pm_capa = IW_POWER_TIMEOUT | IW_POWER_PERIOD;
range->encoding_size[0] = 5;
- range->encoding_size[1] = 13; /* Different token sizes */
- range->num_encoding_sizes = 2; /* Number of entry in the list */
- range->max_encoding_tokens = WEP_KEYS; /* Max number of tokens */
-// range->encoding_login_index; /* token index for login token */
+ range->encoding_size[1] = 13; /* Different token sizes */
+ range->num_encoding_sizes = 2; /* Number of entry in the list */
+ range->max_encoding_tokens = WEP_KEYS; /* Max number of tokens */
+// range->encoding_login_index; /* token index for login token */
if (priv->ieee->iw_mode == IW_MODE_ADHOC) {
range->txpower_capa = IW_TXPOW_DBM;
range->num_txpower = IW_MAX_TXPOWER;
- for (i = 0, level = (IPW_TX_POWER_MAX_DBM * 16); i < IW_MAX_TXPOWER;
- i++, level -= ((IPW_TX_POWER_MAX_DBM - IPW_TX_POWER_MIN_DBM) * 16) /
- (IW_MAX_TXPOWER - 1))
+ for (i = 0, level = (IPW_TX_POWER_MAX_DBM * 16);
+ i < IW_MAX_TXPOWER;
+ i++, level -=
+ ((IPW_TX_POWER_MAX_DBM -
+ IPW_TX_POWER_MIN_DBM) * 16) / (IW_MAX_TXPOWER - 1))
range->txpower[i] = level / 16;
} else {
range->txpower_capa = 0;
range->num_txpower = 0;
}
-
/* Set the Wireless Extension versions */
range->we_version_compiled = WIRELESS_EXT;
range->we_version_source = 16;
-// range->retry_capa; /* What retry options are supported */
-// range->retry_flags; /* How to decode max/min retry limit */
-// range->r_time_flags; /* How to decode max/min retry life */
-// range->min_retry; /* Minimal number of retries */
-// range->max_retry; /* Maximal number of retries */
-// range->min_r_time; /* Minimal retry lifetime */
-// range->max_r_time; /* Maximal retry lifetime */
+// range->retry_capa; /* What retry options are supported */
+// range->retry_flags; /* How to decode max/min retry limit */
+// range->r_time_flags; /* How to decode max/min retry life */
+// range->min_retry; /* Minimal number of retries */
+// range->max_retry; /* Maximal number of retries */
+// range->min_r_time; /* Minimal retry lifetime */
+// range->max_r_time; /* Maximal retry lifetime */
- range->num_channels = FREQ_COUNT;
+ range->num_channels = FREQ_COUNT;
val = 0;
for (i = 0; i < FREQ_COUNT; i++) {
// TODO: Include only legal frequencies for some countries
-// if (local->channel_mask & (1 << i)) {
- range->freq[val].i = i + 1;
- range->freq[val].m = ipw2100_frequencies[i] * 100000;
- range->freq[val].e = 1;
- val++;
-// }
+// if (local->channel_mask & (1 << i)) {
+ range->freq[val].i = i + 1;
+ range->freq[val].m = ipw2100_frequencies[i] * 100000;
+ range->freq[val].e = 1;
+ val++;
+// }
if (val == IW_MAX_FREQUENCIES)
- break;
+ break;
}
range->num_frequency = val;
@@ -7263,7 +7229,7 @@ static int ipw2100_wx_set_wap(struct net_device *dev,
wrqu->ap_addr.sa_data[4] & 0xff,
wrqu->ap_addr.sa_data[5] & 0xff);
- done:
+ done:
up(&priv->action_sem);
return err;
}
@@ -7280,10 +7246,9 @@ static int ipw2100_wx_get_wap(struct net_device *dev,
/* If we are associated, trying to associate, or have a statically
* configured BSSID then return that; otherwise return ANY */
- if (priv->config & CFG_STATIC_BSSID ||
- priv->status & STATUS_ASSOCIATED) {
+ if (priv->config & CFG_STATIC_BSSID || priv->status & STATUS_ASSOCIATED) {
wrqu->ap_addr.sa_family = ARPHRD_ETHER;
- memcpy(wrqu->ap_addr.sa_data, &priv->bssid, ETH_ALEN);
+ memcpy(wrqu->ap_addr.sa_data, priv->bssid, ETH_ALEN);
} else
memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN);
@@ -7297,7 +7262,7 @@ static int ipw2100_wx_set_essid(struct net_device *dev,
union iwreq_data *wrqu, char *extra)
{
struct ipw2100_priv *priv = ieee80211_priv(dev);
- char *essid = ""; /* ANY */
+ char *essid = ""; /* ANY */
int length = 0;
int err = 0;
@@ -7337,7 +7302,7 @@ static int ipw2100_wx_set_essid(struct net_device *dev,
err = ipw2100_set_essid(priv, essid, length, 0);
- done:
+ done:
up(&priv->action_sem);
return err;
}
@@ -7354,17 +7319,16 @@ static int ipw2100_wx_get_essid(struct net_device *dev,
/* If we are associated, trying to associate, or have a statically
* configured ESSID then return that; otherwise return ANY */
- if (priv->config & CFG_STATIC_ESSID ||
- priv->status & STATUS_ASSOCIATED) {
+ if (priv->config & CFG_STATIC_ESSID || priv->status & STATUS_ASSOCIATED) {
IPW_DEBUG_WX("Getting essid: '%s'\n",
escape_essid(priv->essid, priv->essid_len));
memcpy(extra, priv->essid, priv->essid_len);
wrqu->essid.length = priv->essid_len;
- wrqu->essid.flags = 1; /* active */
+ wrqu->essid.flags = 1; /* active */
} else {
IPW_DEBUG_WX("Getting essid: ANY\n");
wrqu->essid.length = 0;
- wrqu->essid.flags = 0; /* active */
+ wrqu->essid.flags = 0; /* active */
}
return 0;
@@ -7383,9 +7347,9 @@ static int ipw2100_wx_set_nick(struct net_device *dev,
if (wrqu->data.length > IW_ESSID_MAX_SIZE)
return -E2BIG;
- wrqu->data.length = min((size_t)wrqu->data.length, sizeof(priv->nick));
+ wrqu->data.length = min((size_t) wrqu->data.length, sizeof(priv->nick));
memset(priv->nick, 0, sizeof(priv->nick));
- memcpy(priv->nick, extra, wrqu->data.length);
+ memcpy(priv->nick, extra, wrqu->data.length);
IPW_DEBUG_WX("SET Nickname -> %s \n", priv->nick);
@@ -7404,7 +7368,7 @@ static int ipw2100_wx_get_nick(struct net_device *dev,
wrqu->data.length = strlen(priv->nick) + 1;
memcpy(extra, priv->nick, wrqu->data.length);
- wrqu->data.flags = 1; /* active */
+ wrqu->data.flags = 1; /* active */
IPW_DEBUG_WX("GET Nickname -> %s \n", extra);
@@ -7446,12 +7410,11 @@ static int ipw2100_wx_set_rate(struct net_device *dev,
err = ipw2100_set_tx_rates(priv, rate, 0);
IPW_DEBUG_WX("SET Rate -> %04X \n", rate);
- done:
+ done:
up(&priv->action_sem);
return err;
}
-
static int ipw2100_wx_get_rate(struct net_device *dev,
struct iw_request_info *info,
union iwreq_data *wrqu, char *extra)
@@ -7499,7 +7462,7 @@ static int ipw2100_wx_get_rate(struct net_device *dev,
IPW_DEBUG_WX("GET Rate -> %d \n", wrqu->bitrate.value);
- done:
+ done:
up(&priv->action_sem);
return err;
}
@@ -7524,8 +7487,7 @@ static int ipw2100_wx_set_rts(struct net_device *dev,
if (wrqu->rts.disabled)
value = priv->rts_threshold | RTS_DISABLED;
else {
- if (wrqu->rts.value < 1 ||
- wrqu->rts.value > 2304) {
+ if (wrqu->rts.value < 1 || wrqu->rts.value > 2304) {
err = -EINVAL;
goto done;
}
@@ -7535,7 +7497,7 @@ static int ipw2100_wx_set_rts(struct net_device *dev,
err = ipw2100_set_rts_threshold(priv, value);
IPW_DEBUG_WX("SET RTS Threshold -> 0x%08X \n", value);
- done:
+ done:
up(&priv->action_sem);
return err;
}
@@ -7551,7 +7513,7 @@ static int ipw2100_wx_get_rts(struct net_device *dev,
struct ipw2100_priv *priv = ieee80211_priv(dev);
wrqu->rts.value = priv->rts_threshold & ~RTS_DISABLED;
- wrqu->rts.fixed = 1; /* no auto select */
+ wrqu->rts.fixed = 1; /* no auto select */
/* If RTS is set to the default value, then it is disabled */
wrqu->rts.disabled = (priv->rts_threshold & RTS_DISABLED) ? 1 : 0;
@@ -7578,8 +7540,7 @@ static int ipw2100_wx_set_txpow(struct net_device *dev,
wrqu->txpower.value > IPW_TX_POWER_MAX_DBM)
return -EINVAL;
- value = (wrqu->txpower.value - IPW_TX_POWER_MIN_DBM) * 16 /
- (IPW_TX_POWER_MAX_DBM - IPW_TX_POWER_MIN_DBM);
+ value = wrqu->txpower.value;
}
down(&priv->action_sem);
@@ -7592,7 +7553,7 @@ static int ipw2100_wx_set_txpow(struct net_device *dev,
IPW_DEBUG_WX("SET TX Power -> %d \n", value);
- done:
+ done:
up(&priv->action_sem);
return err;
}
@@ -7619,11 +7580,7 @@ static int ipw2100_wx_get_txpow(struct net_device *dev,
} else {
wrqu->power.disabled = 0;
wrqu->power.fixed = 1;
- wrqu->power.value =
- (priv->tx_power *
- (IPW_TX_POWER_MAX_DBM - IPW_TX_POWER_MIN_DBM)) /
- (IPW_TX_POWER_MAX - IPW_TX_POWER_MIN) +
- IPW_TX_POWER_MIN_DBM;
+ wrqu->power.value = priv->tx_power;
}
wrqu->power.flags = IW_TXPOW_DBM;
@@ -7688,8 +7645,7 @@ static int ipw2100_wx_set_retry(struct net_device *dev,
struct ipw2100_priv *priv = ieee80211_priv(dev);
int err = 0;
- if (wrqu->retry.flags & IW_RETRY_LIFETIME ||
- wrqu->retry.disabled)
+ if (wrqu->retry.flags & IW_RETRY_LIFETIME || wrqu->retry.disabled)
return -EINVAL;
if (!(wrqu->retry.flags & IW_RETRY_LIMIT))
@@ -7704,14 +7660,14 @@ static int ipw2100_wx_set_retry(struct net_device *dev,
if (wrqu->retry.flags & IW_RETRY_MIN) {
err = ipw2100_set_short_retry(priv, wrqu->retry.value);
IPW_DEBUG_WX("SET Short Retry Limit -> %d \n",
- wrqu->retry.value);
+ wrqu->retry.value);
goto done;
}
if (wrqu->retry.flags & IW_RETRY_MAX) {
err = ipw2100_set_long_retry(priv, wrqu->retry.value);
IPW_DEBUG_WX("SET Long Retry Limit -> %d \n",
- wrqu->retry.value);
+ wrqu->retry.value);
goto done;
}
@@ -7721,7 +7677,7 @@ static int ipw2100_wx_set_retry(struct net_device *dev,
IPW_DEBUG_WX("SET Both Retry Limits -> %d \n", wrqu->retry.value);
- done:
+ done:
up(&priv->action_sem);
return err;
}
@@ -7736,20 +7692,19 @@ static int ipw2100_wx_get_retry(struct net_device *dev,
struct ipw2100_priv *priv = ieee80211_priv(dev);
- wrqu->retry.disabled = 0; /* can't be disabled */
+ wrqu->retry.disabled = 0; /* can't be disabled */
- if ((wrqu->retry.flags & IW_RETRY_TYPE) ==
- IW_RETRY_LIFETIME)
+ if ((wrqu->retry.flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME)
return -EINVAL;
if (wrqu->retry.flags & IW_RETRY_MAX) {
- wrqu->retry.flags = IW_RETRY_LIMIT & IW_RETRY_MAX;
+ wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MAX;
wrqu->retry.value = priv->long_retry_limit;
} else {
wrqu->retry.flags =
(priv->short_retry_limit !=
priv->long_retry_limit) ?
- IW_RETRY_LIMIT & IW_RETRY_MIN : IW_RETRY_LIMIT;
+ IW_RETRY_LIMIT | IW_RETRY_MIN : IW_RETRY_LIMIT;
wrqu->retry.value = priv->short_retry_limit;
}
@@ -7773,15 +7728,14 @@ static int ipw2100_wx_set_scan(struct net_device *dev,
}
IPW_DEBUG_WX("Initiating scan...\n");
- if (ipw2100_set_scan_options(priv) ||
- ipw2100_start_scan(priv)) {
+ if (ipw2100_set_scan_options(priv) || ipw2100_start_scan(priv)) {
IPW_DEBUG_WX("Start scan failed.\n");
/* TODO: Mark a scan as pending so when hardware initialized
* a scan starts */
}
- done:
+ done:
up(&priv->action_sem);
return err;
}
@@ -7798,7 +7752,6 @@ static int ipw2100_wx_get_scan(struct net_device *dev,
return ieee80211_wx_get_scan(priv->ieee, info, wrqu, extra);
}
-
/*
* Implementation based on code in hostap-driver v0.1.3 hostap_ioctl.c
*/
@@ -7827,8 +7780,8 @@ static int ipw2100_wx_get_encode(struct net_device *dev,
}
static int ipw2100_wx_set_power(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
{
struct ipw2100_priv *priv = ieee80211_priv(dev);
int err = 0;
@@ -7847,11 +7800,11 @@ static int ipw2100_wx_set_power(struct net_device *dev,
}
switch (wrqu->power.flags & IW_POWER_MODE) {
- case IW_POWER_ON: /* If not specified */
- case IW_POWER_MODE: /* If set all mask */
- case IW_POWER_ALL_R: /* If explicitely state all */
+ case IW_POWER_ON: /* If not specified */
+ case IW_POWER_MODE: /* If set all mask */
+ case IW_POWER_ALL_R: /* If explicitely state all */
break;
- default: /* Otherwise we don't support it */
+ default: /* Otherwise we don't support it */
IPW_DEBUG_WX("SET PM Mode: %X not supported.\n",
wrqu->power.flags);
err = -EOPNOTSUPP;
@@ -7863,18 +7816,17 @@ static int ipw2100_wx_set_power(struct net_device *dev,
priv->power_mode = IPW_POWER_ENABLED | priv->power_mode;
err = ipw2100_set_power_mode(priv, IPW_POWER_LEVEL(priv->power_mode));
- IPW_DEBUG_WX("SET Power Management Mode -> 0x%02X\n",
- priv->power_mode);
+ IPW_DEBUG_WX("SET Power Management Mode -> 0x%02X\n", priv->power_mode);
- done:
+ done:
up(&priv->action_sem);
return err;
}
static int ipw2100_wx_get_power(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
{
/*
* This can be called at any time. No action lock required
@@ -7882,9 +7834,9 @@ static int ipw2100_wx_get_power(struct net_device *dev,
struct ipw2100_priv *priv = ieee80211_priv(dev);
- if (!(priv->power_mode & IPW_POWER_ENABLED)) {
+ if (!(priv->power_mode & IPW_POWER_ENABLED))
wrqu->power.disabled = 1;
- } else {
+ else {
wrqu->power.disabled = 0;
wrqu->power.flags = 0;
}
@@ -7894,6 +7846,269 @@ static int ipw2100_wx_get_power(struct net_device *dev,
return 0;
}
+#if WIRELESS_EXT > 17
+/*
+ * WE-18 WPA support
+ */
+
+/* SIOCSIWGENIE */
+static int ipw2100_wx_set_genie(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+
+ struct ipw2100_priv *priv = ieee80211_priv(dev);
+ struct ieee80211_device *ieee = priv->ieee;
+ u8 *buf;
+
+ if (!ieee->wpa_enabled)
+ return -EOPNOTSUPP;
+
+ if (wrqu->data.length > MAX_WPA_IE_LEN ||
+ (wrqu->data.length && extra == NULL))
+ return -EINVAL;
+
+ if (wrqu->data.length) {
+ buf = kmalloc(wrqu->data.length, GFP_KERNEL);
+ if (buf == NULL)
+ return -ENOMEM;
+
+ memcpy(buf, extra, wrqu->data.length);
+ kfree(ieee->wpa_ie);
+ ieee->wpa_ie = buf;
+ ieee->wpa_ie_len = wrqu->data.length;
+ } else {
+ kfree(ieee->wpa_ie);
+ ieee->wpa_ie = NULL;
+ ieee->wpa_ie_len = 0;
+ }
+
+ ipw2100_wpa_assoc_frame(priv, ieee->wpa_ie, ieee->wpa_ie_len);
+
+ return 0;
+}
+
+/* SIOCGIWGENIE */
+static int ipw2100_wx_get_genie(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct ipw2100_priv *priv = ieee80211_priv(dev);
+ struct ieee80211_device *ieee = priv->ieee;
+
+ if (ieee->wpa_ie_len == 0 || ieee->wpa_ie == NULL) {
+ wrqu->data.length = 0;
+ return 0;
+ }
+
+ if (wrqu->data.length < ieee->wpa_ie_len)
+ return -E2BIG;
+
+ wrqu->data.length = ieee->wpa_ie_len;
+ memcpy(extra, ieee->wpa_ie, ieee->wpa_ie_len);
+
+ return 0;
+}
+
+/* SIOCSIWAUTH */
+static int ipw2100_wx_set_auth(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct ipw2100_priv *priv = ieee80211_priv(dev);
+ struct ieee80211_device *ieee = priv->ieee;
+ struct iw_param *param = &wrqu->param;
+ struct ieee80211_crypt_data *crypt;
+ unsigned long flags;
+ int ret = 0;
+
+ switch (param->flags & IW_AUTH_INDEX) {
+ case IW_AUTH_WPA_VERSION:
+ case IW_AUTH_CIPHER_PAIRWISE:
+ case IW_AUTH_CIPHER_GROUP:
+ case IW_AUTH_KEY_MGMT:
+ /*
+ * ipw2200 does not use these parameters
+ */
+ break;
+
+ case IW_AUTH_TKIP_COUNTERMEASURES:
+ crypt = priv->ieee->crypt[priv->ieee->tx_keyidx];
+ if (!crypt || !crypt->ops->set_flags || !crypt->ops->get_flags)
+ break;
+
+ flags = crypt->ops->get_flags(crypt->priv);
+
+ if (param->value)
+ flags |= IEEE80211_CRYPTO_TKIP_COUNTERMEASURES;
+ else
+ flags &= ~IEEE80211_CRYPTO_TKIP_COUNTERMEASURES;
+
+ crypt->ops->set_flags(flags, crypt->priv);
+
+ break;
+
+ case IW_AUTH_DROP_UNENCRYPTED:{
+ /* HACK:
+ *
+ * wpa_supplicant calls set_wpa_enabled when the driver
+ * is loaded and unloaded, regardless of if WPA is being
+ * used. No other calls are made which can be used to
+ * determine if encryption will be used or not prior to
+ * association being expected. If encryption is not being
+ * used, drop_unencrypted is set to false, else true -- we
+ * can use this to determine if the CAP_PRIVACY_ON bit should
+ * be set.
+ */
+ struct ieee80211_security sec = {
+ .flags = SEC_ENABLED,
+ .enabled = param->value,
+ };
+ priv->ieee->drop_unencrypted = param->value;
+ /* We only change SEC_LEVEL for open mode. Others
+ * are set by ipw_wpa_set_encryption.
+ */
+ if (!param->value) {
+ sec.flags |= SEC_LEVEL;
+ sec.level = SEC_LEVEL_0;
+ } else {
+ sec.flags |= SEC_LEVEL;
+ sec.level = SEC_LEVEL_1;
+ }
+ if (priv->ieee->set_security)
+ priv->ieee->set_security(priv->ieee->dev, &sec);
+ break;
+ }
+
+ case IW_AUTH_80211_AUTH_ALG:
+ ret = ipw2100_wpa_set_auth_algs(priv, param->value);
+ break;
+
+ case IW_AUTH_WPA_ENABLED:
+ ret = ipw2100_wpa_enable(priv, param->value);
+ break;
+
+ case IW_AUTH_RX_UNENCRYPTED_EAPOL:
+ ieee->ieee802_1x = param->value;
+ break;
+
+ //case IW_AUTH_ROAMING_CONTROL:
+ case IW_AUTH_PRIVACY_INVOKED:
+ ieee->privacy_invoked = param->value;
+ break;
+
+ default:
+ return -EOPNOTSUPP;
+ }
+ return ret;
+}
+
+/* SIOCGIWAUTH */
+static int ipw2100_wx_get_auth(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct ipw2100_priv *priv = ieee80211_priv(dev);
+ struct ieee80211_device *ieee = priv->ieee;
+ struct ieee80211_crypt_data *crypt;
+ struct iw_param *param = &wrqu->param;
+ int ret = 0;
+
+ switch (param->flags & IW_AUTH_INDEX) {
+ case IW_AUTH_WPA_VERSION:
+ case IW_AUTH_CIPHER_PAIRWISE:
+ case IW_AUTH_CIPHER_GROUP:
+ case IW_AUTH_KEY_MGMT:
+ /*
+ * wpa_supplicant will control these internally
+ */
+ ret = -EOPNOTSUPP;
+ break;
+
+ case IW_AUTH_TKIP_COUNTERMEASURES:
+ crypt = priv->ieee->crypt[priv->ieee->tx_keyidx];
+ if (!crypt || !crypt->ops->get_flags) {
+ IPW_DEBUG_WARNING("Can't get TKIP countermeasures: "
+ "crypt not set!\n");
+ break;
+ }
+
+ param->value = (crypt->ops->get_flags(crypt->priv) &
+ IEEE80211_CRYPTO_TKIP_COUNTERMEASURES) ? 1 : 0;
+
+ break;
+
+ case IW_AUTH_DROP_UNENCRYPTED:
+ param->value = ieee->drop_unencrypted;
+ break;
+
+ case IW_AUTH_80211_AUTH_ALG:
+ param->value = priv->ieee->sec.auth_mode;
+ break;
+
+ case IW_AUTH_WPA_ENABLED:
+ param->value = ieee->wpa_enabled;
+ break;
+
+ case IW_AUTH_RX_UNENCRYPTED_EAPOL:
+ param->value = ieee->ieee802_1x;
+ break;
+
+ case IW_AUTH_ROAMING_CONTROL:
+ case IW_AUTH_PRIVACY_INVOKED:
+ param->value = ieee->privacy_invoked;
+ break;
+
+ default:
+ return -EOPNOTSUPP;
+ }
+ return 0;
+}
+
+/* SIOCSIWENCODEEXT */
+static int ipw2100_wx_set_encodeext(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct ipw2100_priv *priv = ieee80211_priv(dev);
+ return ieee80211_wx_set_encodeext(priv->ieee, info, wrqu, extra);
+}
+
+/* SIOCGIWENCODEEXT */
+static int ipw2100_wx_get_encodeext(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct ipw2100_priv *priv = ieee80211_priv(dev);
+ return ieee80211_wx_get_encodeext(priv->ieee, info, wrqu, extra);
+}
+
+/* SIOCSIWMLME */
+static int ipw2100_wx_set_mlme(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct ipw2100_priv *priv = ieee80211_priv(dev);
+ struct iw_mlme *mlme = (struct iw_mlme *)extra;
+ u16 reason;
+
+ reason = cpu_to_le16(mlme->reason_code);
+
+ switch (mlme->cmd) {
+ case IW_MLME_DEAUTH:
+ // silently ignore
+ break;
+
+ case IW_MLME_DISASSOC:
+ ipw2100_disassociate_bssid(priv);
+ break;
+
+ default:
+ return -EOPNOTSUPP;
+ }
+ return 0;
+}
+#endif /* WIRELESS_EXT > 17 */
/*
*
@@ -7927,7 +8142,7 @@ static int ipw2100_wx_set_promisc(struct net_device *dev,
if (priv->ieee->iw_mode == IW_MODE_MONITOR)
err = ipw2100_switch_mode(priv, priv->last_mode);
}
- done:
+ done:
up(&priv->action_sem);
return err;
}
@@ -7962,7 +8177,7 @@ static int ipw2100_wx_set_powermode(struct net_device *dev,
if (priv->power_mode != mode)
err = ipw2100_set_power_mode(priv, mode);
- done:
+ done:
up(&priv->action_sem);
return err;
}
@@ -7990,8 +8205,8 @@ static int ipw2100_wx_get_powermode(struct net_device *dev,
"Power save level: %d (None)", level);
break;
case IPW_POWER_AUTO:
- snprintf(extra, MAX_POWER_STRING,
- "Power save level: %d (Auto)", 0);
+ snprintf(extra, MAX_POWER_STRING,
+ "Power save level: %d (Auto)", 0);
break;
default:
timeout = timeout_duration[level - 1] / 1000;
@@ -8008,7 +8223,6 @@ static int ipw2100_wx_get_powermode(struct net_device *dev,
return 0;
}
-
static int ipw2100_wx_set_preamble(struct net_device *dev,
struct iw_request_info *info,
union iwreq_data *wrqu, char *extra)
@@ -8033,14 +8247,14 @@ static int ipw2100_wx_set_preamble(struct net_device *dev,
err = ipw2100_system_config(priv, 0);
-done:
+ done:
up(&priv->action_sem);
return err;
}
static int ipw2100_wx_get_preamble(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
{
/*
* This can be called at any time. No action lock required
@@ -8056,54 +8270,116 @@ static int ipw2100_wx_get_preamble(struct net_device *dev,
return 0;
}
-static iw_handler ipw2100_wx_handlers[] =
-{
- NULL, /* SIOCSIWCOMMIT */
- ipw2100_wx_get_name, /* SIOCGIWNAME */
- NULL, /* SIOCSIWNWID */
- NULL, /* SIOCGIWNWID */
- ipw2100_wx_set_freq, /* SIOCSIWFREQ */
- ipw2100_wx_get_freq, /* SIOCGIWFREQ */
- ipw2100_wx_set_mode, /* SIOCSIWMODE */
- ipw2100_wx_get_mode, /* SIOCGIWMODE */
- NULL, /* SIOCSIWSENS */
- NULL, /* SIOCGIWSENS */
- NULL, /* SIOCSIWRANGE */
- ipw2100_wx_get_range, /* SIOCGIWRANGE */
- NULL, /* SIOCSIWPRIV */
- NULL, /* SIOCGIWPRIV */
- NULL, /* SIOCSIWSTATS */
- NULL, /* SIOCGIWSTATS */
- NULL, /* SIOCSIWSPY */
- NULL, /* SIOCGIWSPY */
- NULL, /* SIOCGIWTHRSPY */
- NULL, /* SIOCWIWTHRSPY */
- ipw2100_wx_set_wap, /* SIOCSIWAP */
- ipw2100_wx_get_wap, /* SIOCGIWAP */
- NULL, /* -- hole -- */
- NULL, /* SIOCGIWAPLIST -- deprecated */
- ipw2100_wx_set_scan, /* SIOCSIWSCAN */
- ipw2100_wx_get_scan, /* SIOCGIWSCAN */
- ipw2100_wx_set_essid, /* SIOCSIWESSID */
- ipw2100_wx_get_essid, /* SIOCGIWESSID */
- ipw2100_wx_set_nick, /* SIOCSIWNICKN */
- ipw2100_wx_get_nick, /* SIOCGIWNICKN */
- NULL, /* -- hole -- */
- NULL, /* -- hole -- */
- ipw2100_wx_set_rate, /* SIOCSIWRATE */
- ipw2100_wx_get_rate, /* SIOCGIWRATE */
- ipw2100_wx_set_rts, /* SIOCSIWRTS */
- ipw2100_wx_get_rts, /* SIOCGIWRTS */
- ipw2100_wx_set_frag, /* SIOCSIWFRAG */
- ipw2100_wx_get_frag, /* SIOCGIWFRAG */
- ipw2100_wx_set_txpow, /* SIOCSIWTXPOW */
- ipw2100_wx_get_txpow, /* SIOCGIWTXPOW */
- ipw2100_wx_set_retry, /* SIOCSIWRETRY */
- ipw2100_wx_get_retry, /* SIOCGIWRETRY */
- ipw2100_wx_set_encode, /* SIOCSIWENCODE */
- ipw2100_wx_get_encode, /* SIOCGIWENCODE */
- ipw2100_wx_set_power, /* SIOCSIWPOWER */
- ipw2100_wx_get_power, /* SIOCGIWPOWER */
+#ifdef CONFIG_IPW2100_MONITOR
+static int ipw2100_wx_set_crc_check(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct ipw2100_priv *priv = ieee80211_priv(dev);
+ int err, mode = *(int *)extra;
+
+ down(&priv->action_sem);
+ if (!(priv->status & STATUS_INITIALIZED)) {
+ err = -EIO;
+ goto done;
+ }
+
+ if (mode == 1)
+ priv->config |= CFG_CRC_CHECK;
+ else if (mode == 0)
+ priv->config &= ~CFG_CRC_CHECK;
+ else {
+ err = -EINVAL;
+ goto done;
+ }
+ err = 0;
+
+ done:
+ up(&priv->action_sem);
+ return err;
+}
+
+static int ipw2100_wx_get_crc_check(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ /*
+ * This can be called at any time. No action lock required
+ */
+
+ struct ipw2100_priv *priv = ieee80211_priv(dev);
+
+ if (priv->config & CFG_CRC_CHECK)
+ snprintf(wrqu->name, IFNAMSIZ, "CRC checked (1)");
+ else
+ snprintf(wrqu->name, IFNAMSIZ, "CRC ignored (0)");
+
+ return 0;
+}
+#endif /* CONFIG_IPW2100_MONITOR */
+
+static iw_handler ipw2100_wx_handlers[] = {
+ NULL, /* SIOCSIWCOMMIT */
+ ipw2100_wx_get_name, /* SIOCGIWNAME */
+ NULL, /* SIOCSIWNWID */
+ NULL, /* SIOCGIWNWID */
+ ipw2100_wx_set_freq, /* SIOCSIWFREQ */
+ ipw2100_wx_get_freq, /* SIOCGIWFREQ */
+ ipw2100_wx_set_mode, /* SIOCSIWMODE */
+ ipw2100_wx_get_mode, /* SIOCGIWMODE */
+ NULL, /* SIOCSIWSENS */
+ NULL, /* SIOCGIWSENS */
+ NULL, /* SIOCSIWRANGE */
+ ipw2100_wx_get_range, /* SIOCGIWRANGE */
+ NULL, /* SIOCSIWPRIV */
+ NULL, /* SIOCGIWPRIV */
+ NULL, /* SIOCSIWSTATS */
+ NULL, /* SIOCGIWSTATS */
+ NULL, /* SIOCSIWSPY */
+ NULL, /* SIOCGIWSPY */
+ NULL, /* SIOCGIWTHRSPY */
+ NULL, /* SIOCWIWTHRSPY */
+ ipw2100_wx_set_wap, /* SIOCSIWAP */
+ ipw2100_wx_get_wap, /* SIOCGIWAP */
+#if WIRELESS_EXT > 17
+ ipw2100_wx_set_mlme, /* SIOCSIWMLME */
+#else
+ NULL, /* -- hole -- */
+#endif
+ NULL, /* SIOCGIWAPLIST -- deprecated */
+ ipw2100_wx_set_scan, /* SIOCSIWSCAN */
+ ipw2100_wx_get_scan, /* SIOCGIWSCAN */
+ ipw2100_wx_set_essid, /* SIOCSIWESSID */
+ ipw2100_wx_get_essid, /* SIOCGIWESSID */
+ ipw2100_wx_set_nick, /* SIOCSIWNICKN */
+ ipw2100_wx_get_nick, /* SIOCGIWNICKN */
+ NULL, /* -- hole -- */
+ NULL, /* -- hole -- */
+ ipw2100_wx_set_rate, /* SIOCSIWRATE */
+ ipw2100_wx_get_rate, /* SIOCGIWRATE */
+ ipw2100_wx_set_rts, /* SIOCSIWRTS */
+ ipw2100_wx_get_rts, /* SIOCGIWRTS */
+ ipw2100_wx_set_frag, /* SIOCSIWFRAG */
+ ipw2100_wx_get_frag, /* SIOCGIWFRAG */
+ ipw2100_wx_set_txpow, /* SIOCSIWTXPOW */
+ ipw2100_wx_get_txpow, /* SIOCGIWTXPOW */
+ ipw2100_wx_set_retry, /* SIOCSIWRETRY */
+ ipw2100_wx_get_retry, /* SIOCGIWRETRY */
+ ipw2100_wx_set_encode, /* SIOCSIWENCODE */
+ ipw2100_wx_get_encode, /* SIOCGIWENCODE */
+ ipw2100_wx_set_power, /* SIOCSIWPOWER */
+ ipw2100_wx_get_power, /* SIOCGIWPOWER */
+#if WIRELESS_EXT > 17
+ NULL, /* -- hole -- */
+ NULL, /* -- hole -- */
+ ipw2100_wx_set_genie, /* SIOCSIWGENIE */
+ ipw2100_wx_get_genie, /* SIOCGIWGENIE */
+ ipw2100_wx_set_auth, /* SIOCSIWAUTH */
+ ipw2100_wx_get_auth, /* SIOCGIWAUTH */
+ ipw2100_wx_set_encodeext, /* SIOCSIWENCODEEXT */
+ ipw2100_wx_get_encodeext, /* SIOCGIWENCODEEXT */
+ NULL, /* SIOCSIWPMKSA */
+#endif
};
#define IPW2100_PRIV_SET_MONITOR SIOCIWFIRSTPRIV
@@ -8112,60 +8388,71 @@ static iw_handler ipw2100_wx_handlers[] =
#define IPW2100_PRIV_GET_POWER SIOCIWFIRSTPRIV+3
#define IPW2100_PRIV_SET_LONGPREAMBLE SIOCIWFIRSTPRIV+4
#define IPW2100_PRIV_GET_LONGPREAMBLE SIOCIWFIRSTPRIV+5
+#define IPW2100_PRIV_SET_CRC_CHECK SIOCIWFIRSTPRIV+6
+#define IPW2100_PRIV_GET_CRC_CHECK SIOCIWFIRSTPRIV+7
static const struct iw_priv_args ipw2100_private_args[] = {
#ifdef CONFIG_IPW2100_MONITOR
{
- IPW2100_PRIV_SET_MONITOR,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "monitor"
- },
+ IPW2100_PRIV_SET_MONITOR,
+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "monitor"},
{
- IPW2100_PRIV_RESET,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 0, 0, "reset"
- },
-#endif /* CONFIG_IPW2100_MONITOR */
+ IPW2100_PRIV_RESET,
+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 0, 0, "reset"},
+#endif /* CONFIG_IPW2100_MONITOR */
{
- IPW2100_PRIV_SET_POWER,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_power"
- },
+ IPW2100_PRIV_SET_POWER,
+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_power"},
{
- IPW2100_PRIV_GET_POWER,
- 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | MAX_POWER_STRING, "get_power"
- },
+ IPW2100_PRIV_GET_POWER,
+ 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | MAX_POWER_STRING,
+ "get_power"},
{
- IPW2100_PRIV_SET_LONGPREAMBLE,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_preamble"
- },
+ IPW2100_PRIV_SET_LONGPREAMBLE,
+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_preamble"},
{
- IPW2100_PRIV_GET_LONGPREAMBLE,
- 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | IFNAMSIZ, "get_preamble"
- },
+ IPW2100_PRIV_GET_LONGPREAMBLE,
+ 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | IFNAMSIZ, "get_preamble"},
+#ifdef CONFIG_IPW2100_MONITOR
+ {
+ IPW2100_PRIV_SET_CRC_CHECK,
+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_crc_check"},
+ {
+ IPW2100_PRIV_GET_CRC_CHECK,
+ 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | IFNAMSIZ, "get_crc_check"},
+#endif /* CONFIG_IPW2100_MONITOR */
};
static iw_handler ipw2100_private_handler[] = {
#ifdef CONFIG_IPW2100_MONITOR
ipw2100_wx_set_promisc,
ipw2100_wx_reset,
-#else /* CONFIG_IPW2100_MONITOR */
+#else /* CONFIG_IPW2100_MONITOR */
NULL,
NULL,
-#endif /* CONFIG_IPW2100_MONITOR */
+#endif /* CONFIG_IPW2100_MONITOR */
ipw2100_wx_set_powermode,
ipw2100_wx_get_powermode,
ipw2100_wx_set_preamble,
ipw2100_wx_get_preamble,
+#ifdef CONFIG_IPW2100_MONITOR
+ ipw2100_wx_set_crc_check,
+ ipw2100_wx_get_crc_check,
+#else /* CONFIG_IPW2100_MONITOR */
+ NULL,
+ NULL,
+#endif /* CONFIG_IPW2100_MONITOR */
};
-static struct iw_handler_def ipw2100_wx_handler_def =
-{
+static struct iw_handler_def ipw2100_wx_handler_def = {
.standard = ipw2100_wx_handlers,
.num_standard = sizeof(ipw2100_wx_handlers) / sizeof(iw_handler),
.num_private = sizeof(ipw2100_private_handler) / sizeof(iw_handler),
- .num_private_args = sizeof(ipw2100_private_args) /
- sizeof(struct iw_priv_args),
- .private = (iw_handler *)ipw2100_private_handler,
+ .num_private_args = sizeof(ipw2100_private_args) /
+ sizeof(struct iw_priv_args),
+ .private = (iw_handler *) ipw2100_private_handler,
.private_args = (struct iw_priv_args *)ipw2100_private_args,
};
@@ -8174,7 +8461,7 @@ static struct iw_handler_def ipw2100_wx_handler_def =
* Called by /proc/net/wireless
* Also called by SIOCGIWSTATS
*/
-static struct iw_statistics *ipw2100_wx_wireless_stats(struct net_device * dev)
+static struct iw_statistics *ipw2100_wx_wireless_stats(struct net_device *dev)
{
enum {
POOR = 30,
@@ -8194,7 +8481,7 @@ static struct iw_statistics *ipw2100_wx_wireless_stats(struct net_device * dev)
u32 ord_len = sizeof(u32);
if (!priv)
- return (struct iw_statistics *) NULL;
+ return (struct iw_statistics *)NULL;
wstats = &priv->wstats;
@@ -8211,7 +8498,7 @@ static struct iw_statistics *ipw2100_wx_wireless_stats(struct net_device * dev)
wstats->qual.noise = 0;
wstats->qual.updated = 7;
wstats->qual.updated |= IW_QUAL_NOISE_INVALID |
- IW_QUAL_QUAL_INVALID | IW_QUAL_LEVEL_INVALID;
+ IW_QUAL_QUAL_INVALID | IW_QUAL_LEVEL_INVALID;
return wstats;
}
@@ -8219,7 +8506,7 @@ static struct iw_statistics *ipw2100_wx_wireless_stats(struct net_device * dev)
&missed_beacons, &ord_len))
goto fail_get_ordinal;
- /* If we don't have a connection the quality and level is 0*/
+ /* If we don't have a connection the quality and level is 0 */
if (!(priv->status & STATUS_ASSOCIATED)) {
wstats->qual.qual = 0;
wstats->qual.level = 0;
@@ -8236,10 +8523,10 @@ static struct iw_statistics *ipw2100_wx_wireless_stats(struct net_device * dev)
rssi_qual = (rssi - 15) * (GOOD - FAIR) / 5 + FAIR;
else if (rssi < 30)
rssi_qual = (rssi - 20) * (VERY_GOOD - GOOD) /
- 10 + GOOD;
+ 10 + GOOD;
else
rssi_qual = (rssi - 30) * (PERFECT - VERY_GOOD) /
- 10 + VERY_GOOD;
+ 10 + VERY_GOOD;
if (ipw2100_get_ordinal(priv, IPW_ORD_STAT_PERCENT_RETRIES,
&tx_retries, &ord_len))
@@ -8253,25 +8540,25 @@ static struct iw_statistics *ipw2100_wx_wireless_stats(struct net_device * dev)
tx_qual = (70 - tx_retries) * (GOOD - FAIR) / 5 + FAIR;
else if (tx_retries > 50)
tx_qual = (65 - tx_retries) * (VERY_GOOD - GOOD) /
- 15 + GOOD;
+ 15 + GOOD;
else
tx_qual = (50 - tx_retries) *
- (PERFECT - VERY_GOOD) / 50 + VERY_GOOD;
+ (PERFECT - VERY_GOOD) / 50 + VERY_GOOD;
if (missed_beacons > 50)
beacon_qual = (60 - missed_beacons) * POOR / 10;
else if (missed_beacons > 40)
beacon_qual = (50 - missed_beacons) * (FAIR - POOR) /
- 10 + POOR;
+ 10 + POOR;
else if (missed_beacons > 32)
beacon_qual = (40 - missed_beacons) * (GOOD - FAIR) /
- 18 + FAIR;
+ 18 + FAIR;
else if (missed_beacons > 20)
beacon_qual = (32 - missed_beacons) *
- (VERY_GOOD - GOOD) / 20 + GOOD;
+ (VERY_GOOD - GOOD) / 20 + GOOD;
else
beacon_qual = (20 - missed_beacons) *
- (PERFECT - VERY_GOOD) / 20 + VERY_GOOD;
+ (PERFECT - VERY_GOOD) / 20 + VERY_GOOD;
quality = min(beacon_qual, min(tx_qual, rssi_qual));
@@ -8294,7 +8581,7 @@ static struct iw_statistics *ipw2100_wx_wireless_stats(struct net_device * dev)
wstats->qual.updated = 7;
wstats->qual.updated |= IW_QUAL_NOISE_INVALID;
- /* FIXME: this is percent and not a # */
+ /* FIXME: this is percent and not a # */
wstats->miss.beacon = missed_beacons;
if (ipw2100_get_ordinal(priv, IPW_ORD_STAT_TX_FAILURES,
@@ -8304,10 +8591,10 @@ static struct iw_statistics *ipw2100_wx_wireless_stats(struct net_device * dev)
return wstats;
- fail_get_ordinal:
+ fail_get_ordinal:
IPW_DEBUG_WX("failed querying ordinals.\n");
- return (struct iw_statistics *) NULL;
+ return (struct iw_statistics *)NULL;
}
static void ipw2100_wx_event_work(struct ipw2100_priv *priv)
@@ -8330,23 +8617,17 @@ static void ipw2100_wx_event_work(struct ipw2100_priv *priv)
if (!(priv->status & (STATUS_ASSOCIATING | STATUS_ASSOCIATED)) ||
priv->status & STATUS_RF_KILL_MASK ||
ipw2100_get_ordinal(priv, IPW_ORD_STAT_ASSN_AP_BSSID,
- &priv->bssid, &len)) {
+ &priv->bssid, &len)) {
memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN);
} else {
/* We now have the BSSID, so can finish setting to the full
* associated state */
memcpy(wrqu.ap_addr.sa_data, priv->bssid, ETH_ALEN);
- memcpy(&priv->ieee->bssid, priv->bssid, ETH_ALEN);
+ memcpy(priv->ieee->bssid, priv->bssid, ETH_ALEN);
priv->status &= ~STATUS_ASSOCIATING;
priv->status |= STATUS_ASSOCIATED;
netif_carrier_on(priv->net_dev);
- if (netif_queue_stopped(priv->net_dev)) {
- IPW_DEBUG_INFO("Waking net queue.\n");
- netif_wake_queue(priv->net_dev);
- } else {
- IPW_DEBUG_INFO("Starting net queue.\n");
- netif_start_queue(priv->net_dev);
- }
+ netif_wake_queue(priv->net_dev);
}
if (!(priv->status & STATUS_ASSOCIATED)) {
@@ -8355,7 +8636,8 @@ static void ipw2100_wx_event_work(struct ipw2100_priv *priv)
/* This is a disassociation event, so kick the firmware to
* look for another AP */
if (priv->config & CFG_STATIC_ESSID)
- ipw2100_set_essid(priv, priv->essid, priv->essid_len, 0);
+ ipw2100_set_essid(priv, priv->essid, priv->essid_len,
+ 0);
else
ipw2100_set_essid(priv, NULL, 0, 0);
up(&priv->action_sem);
@@ -8378,7 +8660,6 @@ static void ipw2100_wx_event_work(struct ipw2100_priv *priv)
#define IPW2100_FW_NAME(x) IPW2100_FW_PREFIX "" x ".fw"
-
/*
BINARY FIRMWARE HEADER FORMAT
@@ -8400,12 +8681,10 @@ struct ipw2100_fw_header {
unsigned int uc_size;
} __attribute__ ((packed));
-
-
static int ipw2100_mod_firmware_load(struct ipw2100_fw *fw)
{
struct ipw2100_fw_header *h =
- (struct ipw2100_fw_header *)fw->fw_entry->data;
+ (struct ipw2100_fw_header *)fw->fw_entry->data;
if (IPW2100_FW_MAJOR(h->version) != IPW2100_FW_MAJOR_VERSION) {
printk(KERN_WARNING DRV_NAME ": Firmware image not compatible "
@@ -8424,7 +8703,6 @@ static int ipw2100_mod_firmware_load(struct ipw2100_fw *fw)
return 0;
}
-
static int ipw2100_get_firmware(struct ipw2100_priv *priv,
struct ipw2100_fw *fw)
{
@@ -8432,7 +8710,7 @@ static int ipw2100_get_firmware(struct ipw2100_priv *priv,
int rc;
IPW_DEBUG_INFO("%s: Using hotplug firmware load.\n",
- priv->net_dev->name);
+ priv->net_dev->name);
switch (priv->ieee->iw_mode) {
case IW_MODE_ADHOC:
@@ -8458,7 +8736,7 @@ static int ipw2100_get_firmware(struct ipw2100_priv *priv,
return rc;
}
IPW_DEBUG_INFO("firmware data %p size %zd\n", fw->fw_entry->data,
- fw->fw_entry->size);
+ fw->fw_entry->size);
ipw2100_mod_firmware_load(fw);
@@ -8474,7 +8752,6 @@ static void ipw2100_release_firmware(struct ipw2100_priv *priv,
fw->fw_entry = NULL;
}
-
static int ipw2100_get_fwversion(struct ipw2100_priv *priv, char *buf,
size_t max)
{
@@ -8483,8 +8760,7 @@ static int ipw2100_get_fwversion(struct ipw2100_priv *priv, char *buf,
u32 tmp;
int i;
/* firmware version is an ascii string (max len of 14) */
- if (ipw2100_get_ordinal(priv, IPW_ORD_STAT_FW_VER_NUM,
- ver, &len))
+ if (ipw2100_get_ordinal(priv, IPW_ORD_STAT_FW_VER_NUM, ver, &len))
return -EIO;
tmp = max;
if (len >= max)
@@ -8501,8 +8777,7 @@ static int ipw2100_get_ucodeversion(struct ipw2100_priv *priv, char *buf,
u32 ver;
u32 len = sizeof(ver);
/* microcode version is a 32 bit integer */
- if (ipw2100_get_ordinal(priv, IPW_ORD_UCODE_VERSION,
- &ver, &len))
+ if (ipw2100_get_ordinal(priv, IPW_ORD_UCODE_VERSION, &ver, &len))
return -EIO;
return snprintf(buf, max, "%08X", ver);
}
@@ -8510,8 +8785,7 @@ static int ipw2100_get_ucodeversion(struct ipw2100_priv *priv, char *buf,
/*
* On exit, the firmware will have been freed from the fw list
*/
-static int ipw2100_fw_download(struct ipw2100_priv *priv,
- struct ipw2100_fw *fw)
+static int ipw2100_fw_download(struct ipw2100_priv *priv, struct ipw2100_fw *fw)
{
/* firmware is constructed of N contiguous entries, each entry is
* structured as:
@@ -8519,7 +8793,7 @@ static int ipw2100_fw_download(struct ipw2100_priv *priv,
* offset sie desc
* 0 4 address to write to
* 4 2 length of data run
- * 6 length data
+ * 6 length data
*/
unsigned int addr;
unsigned short len;
@@ -8528,12 +8802,12 @@ static int ipw2100_fw_download(struct ipw2100_priv *priv,
unsigned int firmware_data_left = fw->fw.size;
while (firmware_data_left > 0) {
- addr = *(u32 *)(firmware_data);
- firmware_data += 4;
+ addr = *(u32 *) (firmware_data);
+ firmware_data += 4;
firmware_data_left -= 4;
- len = *(u16 *)(firmware_data);
- firmware_data += 2;
+ len = *(u16 *) (firmware_data);
+ firmware_data += 2;
firmware_data_left -= 2;
if (len > 32) {
@@ -8544,7 +8818,7 @@ static int ipw2100_fw_download(struct ipw2100_priv *priv,
}
write_nic_memory(priv->net_dev, addr, len, firmware_data);
- firmware_data += len;
+ firmware_data += len;
firmware_data_left -= len;
}
@@ -8658,21 +8932,19 @@ static int ipw2100_ucode_download(struct ipw2100_priv *priv,
for (i = 0; i < 30; i++) {
/* Read alive response structure */
for (j = 0;
- j < (sizeof(struct symbol_alive_response) >> 1);
- j++)
- read_nic_word(dev, 0x210004,
- ((u16 *)&response) + j);
+ j < (sizeof(struct symbol_alive_response) >> 1); j++)
+ read_nic_word(dev, 0x210004, ((u16 *) & response) + j);
- if ((response.cmd_id == 1) &&
- (response.ucode_valid == 0x1))
+ if ((response.cmd_id == 1) && (response.ucode_valid == 0x1))
break;
udelay(10);
}
if (i == 30) {
- printk(KERN_ERR DRV_NAME ": %s: No response from Symbol - hw not alive\n",
+ printk(KERN_ERR DRV_NAME
+ ": %s: No response from Symbol - hw not alive\n",
dev->name);
- printk_buf(IPW_DL_ERROR, (u8*)&response, sizeof(response));
+ printk_buf(IPW_DL_ERROR, (u8 *) & response, sizeof(response));
return -EIO;
}
diff --git a/drivers/net/wireless/ipw2100.h b/drivers/net/wireless/ipw2100.h
index 2a3cdbd50168..140fdf2a0a09 100644
--- a/drivers/net/wireless/ipw2100.h
+++ b/drivers/net/wireless/ipw2100.h
@@ -1,6 +1,6 @@
/******************************************************************************
- Copyright(c) 2003 - 2005 Intel Corporation. All rights reserved.
+ Copyright(c) 2003 - 2004 Intel Corporation. All rights reserved.
This program is free software; you can redistribute it and/or modify it
under the terms of version 2 of the GNU General Public License as
@@ -37,7 +37,6 @@
#include <linux/socket.h>
#include <linux/if_arp.h>
#include <linux/wireless.h>
-#include <linux/version.h>
#include <net/iw_handler.h> // new driver API
#include <net/ieee80211.h>
@@ -93,7 +92,6 @@ struct ipw2100_rx_packet;
#define IPW_DL_IOCTL (1<<14)
#define IPW_DL_RF_KILL (1<<17)
-
#define IPW_DL_MANAGE (1<<15)
#define IPW_DL_FW (1<<16)
@@ -156,7 +154,9 @@ extern const char *band_str[];
struct bd_status {
union {
- struct { u8 nlf:1, txType:2, intEnabled:1, reserved:4;} fields;
+ struct {
+ u8 nlf:1, txType:2, intEnabled:1, reserved:4;
+ } fields;
u8 field;
} info;
} __attribute__ ((packed));
@@ -165,7 +165,7 @@ struct ipw2100_bd {
u32 host_addr;
u32 buf_length;
struct bd_status status;
- /* number of fragments for frame (should be set only for
+ /* number of fragments for frame (should be set only for
* 1st TBD) */
u8 num_fragments;
u8 reserved[6];
@@ -293,10 +293,10 @@ struct ipw2100_cmd_header {
struct ipw2100_data_header {
u32 host_command_reg;
u32 host_command_reg1;
- u8 encrypted; // BOOLEAN in win! TRUE if frame is enc by driver
+ u8 encrypted; // BOOLEAN in win! TRUE if frame is enc by driver
u8 needs_encryption; // BOOLEAN in win! TRUE if frma need to be enc in NIC
u8 wep_index; // 0 no key, 1-4 key index, 0xff immediate key
- u8 key_size; // 0 no imm key, 0x5 64bit encr, 0xd 128bit encr, 0x10 128bit encr and 128bit IV
+ u8 key_size; // 0 no imm key, 0x5 64bit encr, 0xd 128bit encr, 0x10 128bit encr and 128bit IV
u8 key[16];
u8 reserved[10]; // f/w reserved
u8 src_addr[ETH_ALEN];
@@ -306,14 +306,13 @@ struct ipw2100_data_header {
/* Host command data structure */
struct host_command {
- u32 host_command; // COMMAND ID
- u32 host_command1; // COMMAND ID
+ u32 host_command; // COMMAND ID
+ u32 host_command1; // COMMAND ID
u32 host_command_sequence; // UNIQUE COMMAND NUMBER (ID)
u32 host_command_length; // LENGTH
u32 host_command_parameters[HOST_COMMAND_PARAMS_REG_LEN]; // COMMAND PARAMETERS
} __attribute__ ((packed));
-
typedef enum {
POWER_ON_RESET,
EXIT_POWER_DOWN_RESET,
@@ -328,17 +327,16 @@ enum {
RX
};
-
struct ipw2100_tx_packet {
int type;
int index;
union {
- struct { /* COMMAND */
- struct ipw2100_cmd_header* cmd;
+ struct { /* COMMAND */
+ struct ipw2100_cmd_header *cmd;
dma_addr_t cmd_phys;
} c_struct;
- struct { /* DATA */
- struct ipw2100_data_header* data;
+ struct { /* DATA */
+ struct ipw2100_data_header *data;
dma_addr_t data_phys;
struct ieee80211_txb *txb;
} d_struct;
@@ -348,7 +346,6 @@ struct ipw2100_tx_packet {
struct list_head list;
};
-
struct ipw2100_rx_packet {
struct ipw2100_rx *rxp;
dma_addr_t dma_addr;
@@ -432,13 +429,13 @@ enum {
};
#define STATUS_POWERED (1<<0)
-#define STATUS_CMD_ACTIVE (1<<1) /**< host command in progress */
-#define STATUS_RUNNING (1<<2) /* Card initialized, but not enabled */
-#define STATUS_ENABLED (1<<3) /* Card enabled -- can scan,Tx,Rx */
-#define STATUS_STOPPING (1<<4) /* Card is in shutdown phase */
-#define STATUS_INITIALIZED (1<<5) /* Card is ready for external calls */
-#define STATUS_ASSOCIATING (1<<9) /* Associated, but no BSSID yet */
-#define STATUS_ASSOCIATED (1<<10) /* Associated and BSSID valid */
+#define STATUS_CMD_ACTIVE (1<<1) /**< host command in progress */
+#define STATUS_RUNNING (1<<2) /* Card initialized, but not enabled */
+#define STATUS_ENABLED (1<<3) /* Card enabled -- can scan,Tx,Rx */
+#define STATUS_STOPPING (1<<4) /* Card is in shutdown phase */
+#define STATUS_INITIALIZED (1<<5) /* Card is ready for external calls */
+#define STATUS_ASSOCIATING (1<<9) /* Associated, but no BSSID yet */
+#define STATUS_ASSOCIATED (1<<10) /* Associated and BSSID valid */
#define STATUS_INT_ENABLED (1<<11)
#define STATUS_RF_KILL_HW (1<<12)
#define STATUS_RF_KILL_SW (1<<13)
@@ -451,9 +448,7 @@ enum {
#define STATUS_SCAN_COMPLETE (1<<26)
#define STATUS_WX_EVENT_PENDING (1<<27)
#define STATUS_RESET_PENDING (1<<29)
-#define STATUS_SECURITY_UPDATED (1<<30) /* Security sync needed */
-
-
+#define STATUS_SECURITY_UPDATED (1<<30) /* Security sync needed */
/* Internal NIC states */
#define IPW_STATE_INITIALIZED (1<<0)
@@ -469,11 +464,9 @@ enum {
#define IPW_STATE_POWER_DOWN (1<<10)
#define IPW_STATE_SCANNING (1<<11)
-
-
-#define CFG_STATIC_CHANNEL (1<<0) /* Restrict assoc. to single channel */
-#define CFG_STATIC_ESSID (1<<1) /* Restrict assoc. to single SSID */
-#define CFG_STATIC_BSSID (1<<2) /* Restrict assoc. to single BSSID */
+#define CFG_STATIC_CHANNEL (1<<0) /* Restrict assoc. to single channel */
+#define CFG_STATIC_ESSID (1<<1) /* Restrict assoc. to single SSID */
+#define CFG_STATIC_BSSID (1<<2) /* Restrict assoc. to single BSSID */
#define CFG_CUSTOM_MAC (1<<3)
#define CFG_LONG_PREAMBLE (1<<4)
#define CFG_ASSOCIATE (1<<6)
@@ -481,14 +474,17 @@ enum {
#define CFG_ADHOC_CREATE (1<<8)
#define CFG_C3_DISABLED (1<<9)
#define CFG_PASSIVE_SCAN (1<<10)
+#ifdef CONFIG_IPW2100_MONITOR
+#define CFG_CRC_CHECK (1<<11)
+#endif
-#define CAP_SHARED_KEY (1<<0) /* Off = OPEN */
-#define CAP_PRIVACY_ON (1<<1) /* Off = No privacy */
+#define CAP_SHARED_KEY (1<<0) /* Off = OPEN */
+#define CAP_PRIVACY_ON (1<<1) /* Off = No privacy */
struct ipw2100_priv {
- int stop_hang_check; /* Set 1 when shutting down to kill hang_check */
- int stop_rf_kill; /* Set 1 when shutting down to kill rf_kill */
+ int stop_hang_check; /* Set 1 when shutting down to kill hang_check */
+ int stop_rf_kill; /* Set 1 when shutting down to kill rf_kill */
struct ieee80211_device *ieee;
unsigned long status;
@@ -519,19 +515,16 @@ struct ipw2100_priv {
unsigned long hw_features;
int hangs;
u32 last_rtc;
- int dump_raw; /* 1 to dump raw bytes in /sys/.../memory */
- u8* snapshot[0x30];
+ int dump_raw; /* 1 to dump raw bytes in /sys/.../memory */
+ u8 *snapshot[0x30];
u8 mandatory_bssid_mac[ETH_ALEN];
u8 mac_addr[ETH_ALEN];
int power_mode;
- /* WEP data */
- struct ieee80211_security sec;
int messages_sent;
-
int short_retry_limit;
int long_retry_limit;
@@ -599,7 +592,6 @@ struct ipw2100_priv {
wait_queue_head_t wait_command_queue;
};
-
/*********************************************************
* Host Command -> From Driver to FW
*********************************************************/
@@ -646,7 +638,6 @@ struct ipw2100_priv {
#define CARD_DISABLE_PHY_OFF 61
#define MSDU_TX_RATES 62
-
/* Rogue AP Detection */
#define SET_STATION_STAT_BITS 64
#define CLEAR_STATIONS_STAT_BITS 65
@@ -655,8 +646,6 @@ struct ipw2100_priv {
#define DISASSOCIATION_BSSID 68
#define SET_WPA_IE 69
-
-
/* system configuration bit mask: */
#define IPW_CFG_MONITOR 0x00004
#define IPW_CFG_PREAMBLE_AUTO 0x00010
@@ -704,7 +693,7 @@ struct ipw2100_priv {
#define IPW2100_INTA_TX_TRANSFER (0x00000001) // Bit 0 (LSB)
#define IPW2100_INTA_RX_TRANSFER (0x00000002) // Bit 1
#define IPW2100_INTA_TX_COMPLETE (0x00000004) // Bit 2
-#define IPW2100_INTA_EVENT_INTERRUPT (0x00000008) // Bit 3
+#define IPW2100_INTA_EVENT_INTERRUPT (0x00000008) // Bit 3
#define IPW2100_INTA_STATUS_CHANGE (0x00000010) // Bit 4
#define IPW2100_INTA_BEACON_PERIOD_EXPIRED (0x00000020) // Bit 5
#define IPW2100_INTA_SLAVE_MODE_HOST_COMMAND_DONE (0x00010000) // Bit 16
@@ -784,9 +773,6 @@ struct ipw2100_priv {
#define IPW_CARD_DISABLE_PHY_OFF_COMPLETE_WAIT 100 // 100 milli
#define IPW_PREPARE_POWER_DOWN_COMPLETE_WAIT 100 // 100 milli
-
-
-
#define IPW_HEADER_802_11_SIZE sizeof(struct ieee80211_hdr_3addr)
#define IPW_MAX_80211_PAYLOAD_SIZE 2304U
#define IPW_MAX_802_11_PAYLOAD_LENGTH 2312
@@ -808,7 +794,7 @@ struct ipw2100_priv {
struct ipw2100_rx {
union {
unsigned char payload[IPW_RX_NIC_BUFFER_LENGTH];
- struct ieee80211_hdr header;
+ struct ieee80211_hdr_4addr header;
u32 status;
struct ipw2100_notification notification;
struct ipw2100_cmd_header command;
@@ -843,8 +829,8 @@ struct ipw2100_rx {
#define IPW_TX_POWER_MIN_DBM (-12)
#define IPW_TX_POWER_MAX_DBM 16
-#define FW_SCAN_DONOT_ASSOCIATE 0x0001 // Dont Attempt to Associate after Scan
-#define FW_SCAN_PASSIVE 0x0008 // Force PASSSIVE Scan
+#define FW_SCAN_DONOT_ASSOCIATE 0x0001 // Dont Attempt to Associate after Scan
+#define FW_SCAN_PASSIVE 0x0008 // Force PASSSIVE Scan
#define REG_MIN_CHANNEL 0
#define REG_MAX_CHANNEL 14
@@ -856,7 +842,6 @@ struct ipw2100_rx {
#define DIVERSITY_ANTENNA_A 1 // Use antenna A
#define DIVERSITY_ANTENNA_B 2 // Use antenna B
-
#define HOST_COMMAND_WAIT 0
#define HOST_COMMAND_NO_WAIT 1
@@ -873,10 +858,9 @@ struct ipw2100_rx {
#define TYPE_ASSOCIATION_REQUEST 0x0013
#define TYPE_REASSOCIATION_REQUEST 0x0014
-
-#define HW_FEATURE_RFKILL (0x0001)
-#define RF_KILLSWITCH_OFF (1)
-#define RF_KILLSWITCH_ON (0)
+#define HW_FEATURE_RFKILL 0x0001
+#define RF_KILLSWITCH_OFF 1
+#define RF_KILLSWITCH_ON 0
#define IPW_COMMAND_POOL_SIZE 40
@@ -895,7 +879,7 @@ struct ipw2100_rx {
// Fixed size data: Ordinal Table 1
typedef enum _ORDINAL_TABLE_1 { // NS - means Not Supported by FW
// Transmit statistics
- IPW_ORD_STAT_TX_HOST_REQUESTS = 1,// # of requested Host Tx's (MSDU)
+ IPW_ORD_STAT_TX_HOST_REQUESTS = 1, // # of requested Host Tx's (MSDU)
IPW_ORD_STAT_TX_HOST_COMPLETE, // # of successful Host Tx's (MSDU)
IPW_ORD_STAT_TX_DIR_DATA, // # of successful Directed Tx's (MSDU)
@@ -905,42 +889,42 @@ typedef enum _ORDINAL_TABLE_1 { // NS - means Not Supported by FW
IPW_ORD_STAT_TX_DIR_DATA11, // # of successful Directed Tx's (MSDU) @ 11MB
IPW_ORD_STAT_TX_DIR_DATA22, // # of successful Directed Tx's (MSDU) @ 22MB
- IPW_ORD_STAT_TX_NODIR_DATA1 = 13,// # of successful Non_Directed Tx's (MSDU) @ 1MB
+ IPW_ORD_STAT_TX_NODIR_DATA1 = 13, // # of successful Non_Directed Tx's (MSDU) @ 1MB
IPW_ORD_STAT_TX_NODIR_DATA2, // # of successful Non_Directed Tx's (MSDU) @ 2MB
IPW_ORD_STAT_TX_NODIR_DATA5_5, // # of successful Non_Directed Tx's (MSDU) @ 5.5MB
IPW_ORD_STAT_TX_NODIR_DATA11, // # of successful Non_Directed Tx's (MSDU) @ 11MB
IPW_ORD_STAT_NULL_DATA = 21, // # of successful NULL data Tx's
- IPW_ORD_STAT_TX_RTS, // # of successful Tx RTS
- IPW_ORD_STAT_TX_CTS, // # of successful Tx CTS
- IPW_ORD_STAT_TX_ACK, // # of successful Tx ACK
- IPW_ORD_STAT_TX_ASSN, // # of successful Association Tx's
+ IPW_ORD_STAT_TX_RTS, // # of successful Tx RTS
+ IPW_ORD_STAT_TX_CTS, // # of successful Tx CTS
+ IPW_ORD_STAT_TX_ACK, // # of successful Tx ACK
+ IPW_ORD_STAT_TX_ASSN, // # of successful Association Tx's
IPW_ORD_STAT_TX_ASSN_RESP, // # of successful Association response Tx's
- IPW_ORD_STAT_TX_REASSN, // # of successful Reassociation Tx's
+ IPW_ORD_STAT_TX_REASSN, // # of successful Reassociation Tx's
IPW_ORD_STAT_TX_REASSN_RESP, // # of successful Reassociation response Tx's
- IPW_ORD_STAT_TX_PROBE, // # of probes successfully transmitted
+ IPW_ORD_STAT_TX_PROBE, // # of probes successfully transmitted
IPW_ORD_STAT_TX_PROBE_RESP, // # of probe responses successfully transmitted
- IPW_ORD_STAT_TX_BEACON, // # of tx beacon
- IPW_ORD_STAT_TX_ATIM, // # of Tx ATIM
+ IPW_ORD_STAT_TX_BEACON, // # of tx beacon
+ IPW_ORD_STAT_TX_ATIM, // # of Tx ATIM
IPW_ORD_STAT_TX_DISASSN, // # of successful Disassociation TX
- IPW_ORD_STAT_TX_AUTH, // # of successful Authentication Tx
- IPW_ORD_STAT_TX_DEAUTH, // # of successful Deauthentication TX
+ IPW_ORD_STAT_TX_AUTH, // # of successful Authentication Tx
+ IPW_ORD_STAT_TX_DEAUTH, // # of successful Deauthentication TX
- IPW_ORD_STAT_TX_TOTAL_BYTES = 41,// Total successful Tx data bytes
- IPW_ORD_STAT_TX_RETRIES, // # of Tx retries
- IPW_ORD_STAT_TX_RETRY1, // # of Tx retries at 1MBPS
- IPW_ORD_STAT_TX_RETRY2, // # of Tx retries at 2MBPS
- IPW_ORD_STAT_TX_RETRY5_5, // # of Tx retries at 5.5MBPS
- IPW_ORD_STAT_TX_RETRY11, // # of Tx retries at 11MBPS
+ IPW_ORD_STAT_TX_TOTAL_BYTES = 41, // Total successful Tx data bytes
+ IPW_ORD_STAT_TX_RETRIES, // # of Tx retries
+ IPW_ORD_STAT_TX_RETRY1, // # of Tx retries at 1MBPS
+ IPW_ORD_STAT_TX_RETRY2, // # of Tx retries at 2MBPS
+ IPW_ORD_STAT_TX_RETRY5_5, // # of Tx retries at 5.5MBPS
+ IPW_ORD_STAT_TX_RETRY11, // # of Tx retries at 11MBPS
IPW_ORD_STAT_TX_FAILURES = 51, // # of Tx Failures
IPW_ORD_STAT_TX_ABORT_AT_HOP, //NS // # of Tx's aborted at hop time
- IPW_ORD_STAT_TX_MAX_TRIES_IN_HOP,// # of times max tries in a hop failed
+ IPW_ORD_STAT_TX_MAX_TRIES_IN_HOP, // # of times max tries in a hop failed
IPW_ORD_STAT_TX_ABORT_LATE_DMA, //NS // # of times tx aborted due to late dma setup
IPW_ORD_STAT_TX_ABORT_STX, //NS // # of times backoff aborted
IPW_ORD_STAT_TX_DISASSN_FAIL, // # of times disassociation failed
- IPW_ORD_STAT_TX_ERR_CTS, // # of missed/bad CTS frames
- IPW_ORD_STAT_TX_BPDU, //NS // # of spanning tree BPDUs sent
+ IPW_ORD_STAT_TX_ERR_CTS, // # of missed/bad CTS frames
+ IPW_ORD_STAT_TX_BPDU, //NS // # of spanning tree BPDUs sent
IPW_ORD_STAT_TX_ERR_ACK, // # of tx err due to acks
// Receive statistics
@@ -952,7 +936,7 @@ typedef enum _ORDINAL_TABLE_1 { // NS - means Not Supported by FW
IPW_ORD_STAT_RX_DIR_DATA11, // # of directed packets at 11MB
IPW_ORD_STAT_RX_DIR_DATA22, // # of directed packets at 22MB
- IPW_ORD_STAT_RX_NODIR_DATA = 71,// # of nondirected packets
+ IPW_ORD_STAT_RX_NODIR_DATA = 71, // # of nondirected packets
IPW_ORD_STAT_RX_NODIR_DATA1, // # of nondirected packets at 1MB
IPW_ORD_STAT_RX_NODIR_DATA2, // # of nondirected packets at 2MB
IPW_ORD_STAT_RX_NODIR_DATA5_5, // # of nondirected packets at 5.5MB
@@ -977,18 +961,18 @@ typedef enum _ORDINAL_TABLE_1 { // NS - means Not Supported by FW
IPW_ORD_STAT_RX_AUTH, // # of authentication Rx
IPW_ORD_STAT_RX_DEAUTH, // # of deauthentication Rx
- IPW_ORD_STAT_RX_TOTAL_BYTES = 101,// Total rx data bytes received
- IPW_ORD_STAT_RX_ERR_CRC, // # of packets with Rx CRC error
- IPW_ORD_STAT_RX_ERR_CRC1, // # of Rx CRC errors at 1MB
- IPW_ORD_STAT_RX_ERR_CRC2, // # of Rx CRC errors at 2MB
- IPW_ORD_STAT_RX_ERR_CRC5_5, // # of Rx CRC errors at 5.5MB
- IPW_ORD_STAT_RX_ERR_CRC11, // # of Rx CRC errors at 11MB
+ IPW_ORD_STAT_RX_TOTAL_BYTES = 101, // Total rx data bytes received
+ IPW_ORD_STAT_RX_ERR_CRC, // # of packets with Rx CRC error
+ IPW_ORD_STAT_RX_ERR_CRC1, // # of Rx CRC errors at 1MB
+ IPW_ORD_STAT_RX_ERR_CRC2, // # of Rx CRC errors at 2MB
+ IPW_ORD_STAT_RX_ERR_CRC5_5, // # of Rx CRC errors at 5.5MB
+ IPW_ORD_STAT_RX_ERR_CRC11, // # of Rx CRC errors at 11MB
- IPW_ORD_STAT_RX_DUPLICATE1 = 112, // # of duplicate rx packets at 1MB
- IPW_ORD_STAT_RX_DUPLICATE2, // # of duplicate rx packets at 2MB
- IPW_ORD_STAT_RX_DUPLICATE5_5, // # of duplicate rx packets at 5.5MB
- IPW_ORD_STAT_RX_DUPLICATE11, // # of duplicate rx packets at 11MB
- IPW_ORD_STAT_RX_DUPLICATE = 119, // # of duplicate rx packets
+ IPW_ORD_STAT_RX_DUPLICATE1 = 112, // # of duplicate rx packets at 1MB
+ IPW_ORD_STAT_RX_DUPLICATE2, // # of duplicate rx packets at 2MB
+ IPW_ORD_STAT_RX_DUPLICATE5_5, // # of duplicate rx packets at 5.5MB
+ IPW_ORD_STAT_RX_DUPLICATE11, // # of duplicate rx packets at 11MB
+ IPW_ORD_STAT_RX_DUPLICATE = 119, // # of duplicate rx packets
IPW_ORD_PERS_DB_LOCK = 120, // # locking fw permanent db
IPW_ORD_PERS_DB_SIZE, // # size of fw permanent db
@@ -1006,17 +990,17 @@ typedef enum _ORDINAL_TABLE_1 { // NS - means Not Supported by FW
IPW_ORD_STAT_RX_ICV_ERRORS, // # of ICV errors during decryption
// PSP Statistics
- IPW_ORD_STAT_PSP_SUSPENSION = 137,// # of times adapter suspended
+ IPW_ORD_STAT_PSP_SUSPENSION = 137, // # of times adapter suspended
IPW_ORD_STAT_PSP_BCN_TIMEOUT, // # of beacon timeout
IPW_ORD_STAT_PSP_POLL_TIMEOUT, // # of poll response timeouts
- IPW_ORD_STAT_PSP_NONDIR_TIMEOUT,// # of timeouts waiting for last broadcast/muticast pkt
+ IPW_ORD_STAT_PSP_NONDIR_TIMEOUT, // # of timeouts waiting for last broadcast/muticast pkt
IPW_ORD_STAT_PSP_RX_DTIMS, // # of PSP DTIMs received
IPW_ORD_STAT_PSP_RX_TIMS, // # of PSP TIMs received
IPW_ORD_STAT_PSP_STATION_ID, // PSP Station ID
// Association and roaming
IPW_ORD_LAST_ASSN_TIME = 147, // RTC time of last association
- IPW_ORD_STAT_PERCENT_MISSED_BCNS,// current calculation of % missed beacons
+ IPW_ORD_STAT_PERCENT_MISSED_BCNS, // current calculation of % missed beacons
IPW_ORD_STAT_PERCENT_RETRIES, // current calculation of % missed tx retries
IPW_ORD_ASSOCIATED_AP_PTR, // If associated, this is ptr to the associated
// AP table entry. set to 0 if not associated
@@ -1151,7 +1135,7 @@ struct ipw2100_fw_chunk {
};
struct ipw2100_fw_chunk_set {
- const void *data;
+ const void *data;
unsigned long size;
};
@@ -1164,4 +1148,4 @@ struct ipw2100_fw {
#define MAX_FW_VERSION_LEN 14
-#endif /* _IPW2100_H */
+#endif /* _IPW2100_H */
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c
index b7f275c00de3..b0d195d1721a 100644
--- a/drivers/net/wireless/ipw2200.c
+++ b/drivers/net/wireless/ipw2200.c
@@ -1,6 +1,6 @@
/******************************************************************************
- Copyright(c) 2003 - 2004 Intel Corporation. All rights reserved.
+ Copyright(c) 2003 - 2005 Intel Corporation. All rights reserved.
802.11 status code portion of this file from ethereal-0.10.6:
Copyright 2000, Axis Communications AB
@@ -31,30 +31,103 @@
******************************************************************************/
#include "ipw2200.h"
+#include <linux/version.h>
-#define IPW2200_VERSION "1.0.0"
+#define IPW2200_VERSION "git-1.0.8"
#define DRV_DESCRIPTION "Intel(R) PRO/Wireless 2200/2915 Network Driver"
-#define DRV_COPYRIGHT "Copyright(c) 2003-2004 Intel Corporation"
+#define DRV_COPYRIGHT "Copyright(c) 2003-2005 Intel Corporation"
#define DRV_VERSION IPW2200_VERSION
+#define ETH_P_80211_STATS (ETH_P_80211_RAW + 1)
+
MODULE_DESCRIPTION(DRV_DESCRIPTION);
MODULE_VERSION(DRV_VERSION);
MODULE_AUTHOR(DRV_COPYRIGHT);
MODULE_LICENSE("GPL");
+static int cmdlog = 0;
static int debug = 0;
static int channel = 0;
-static char *ifname;
static int mode = 0;
static u32 ipw_debug_level;
static int associate = 1;
static int auto_create = 1;
+static int led = 0;
static int disable = 0;
+static int hwcrypto = 1;
static const char ipw_modes[] = {
'a', 'b', 'g', '?'
};
+#ifdef CONFIG_IPW_QOS
+static int qos_enable = 0;
+static int qos_burst_enable = 0;
+static int qos_no_ack_mask = 0;
+static int burst_duration_CCK = 0;
+static int burst_duration_OFDM = 0;
+
+static struct ieee80211_qos_parameters def_qos_parameters_OFDM = {
+ {QOS_TX0_CW_MIN_OFDM, QOS_TX1_CW_MIN_OFDM, QOS_TX2_CW_MIN_OFDM,
+ QOS_TX3_CW_MIN_OFDM},
+ {QOS_TX0_CW_MAX_OFDM, QOS_TX1_CW_MAX_OFDM, QOS_TX2_CW_MAX_OFDM,
+ QOS_TX3_CW_MAX_OFDM},
+ {QOS_TX0_AIFS, QOS_TX1_AIFS, QOS_TX2_AIFS, QOS_TX3_AIFS},
+ {QOS_TX0_ACM, QOS_TX1_ACM, QOS_TX2_ACM, QOS_TX3_ACM},
+ {QOS_TX0_TXOP_LIMIT_OFDM, QOS_TX1_TXOP_LIMIT_OFDM,
+ QOS_TX2_TXOP_LIMIT_OFDM, QOS_TX3_TXOP_LIMIT_OFDM}
+};
+
+static struct ieee80211_qos_parameters def_qos_parameters_CCK = {
+ {QOS_TX0_CW_MIN_CCK, QOS_TX1_CW_MIN_CCK, QOS_TX2_CW_MIN_CCK,
+ QOS_TX3_CW_MIN_CCK},
+ {QOS_TX0_CW_MAX_CCK, QOS_TX1_CW_MAX_CCK, QOS_TX2_CW_MAX_CCK,
+ QOS_TX3_CW_MAX_CCK},
+ {QOS_TX0_AIFS, QOS_TX1_AIFS, QOS_TX2_AIFS, QOS_TX3_AIFS},
+ {QOS_TX0_ACM, QOS_TX1_ACM, QOS_TX2_ACM, QOS_TX3_ACM},
+ {QOS_TX0_TXOP_LIMIT_CCK, QOS_TX1_TXOP_LIMIT_CCK, QOS_TX2_TXOP_LIMIT_CCK,
+ QOS_TX3_TXOP_LIMIT_CCK}
+};
+
+static struct ieee80211_qos_parameters def_parameters_OFDM = {
+ {DEF_TX0_CW_MIN_OFDM, DEF_TX1_CW_MIN_OFDM, DEF_TX2_CW_MIN_OFDM,
+ DEF_TX3_CW_MIN_OFDM},
+ {DEF_TX0_CW_MAX_OFDM, DEF_TX1_CW_MAX_OFDM, DEF_TX2_CW_MAX_OFDM,
+ DEF_TX3_CW_MAX_OFDM},
+ {DEF_TX0_AIFS, DEF_TX1_AIFS, DEF_TX2_AIFS, DEF_TX3_AIFS},
+ {DEF_TX0_ACM, DEF_TX1_ACM, DEF_TX2_ACM, DEF_TX3_ACM},
+ {DEF_TX0_TXOP_LIMIT_OFDM, DEF_TX1_TXOP_LIMIT_OFDM,
+ DEF_TX2_TXOP_LIMIT_OFDM, DEF_TX3_TXOP_LIMIT_OFDM}
+};
+
+static struct ieee80211_qos_parameters def_parameters_CCK = {
+ {DEF_TX0_CW_MIN_CCK, DEF_TX1_CW_MIN_CCK, DEF_TX2_CW_MIN_CCK,
+ DEF_TX3_CW_MIN_CCK},
+ {DEF_TX0_CW_MAX_CCK, DEF_TX1_CW_MAX_CCK, DEF_TX2_CW_MAX_CCK,
+ DEF_TX3_CW_MAX_CCK},
+ {DEF_TX0_AIFS, DEF_TX1_AIFS, DEF_TX2_AIFS, DEF_TX3_AIFS},
+ {DEF_TX0_ACM, DEF_TX1_ACM, DEF_TX2_ACM, DEF_TX3_ACM},
+ {DEF_TX0_TXOP_LIMIT_CCK, DEF_TX1_TXOP_LIMIT_CCK, DEF_TX2_TXOP_LIMIT_CCK,
+ DEF_TX3_TXOP_LIMIT_CCK}
+};
+
+static u8 qos_oui[QOS_OUI_LEN] = { 0x00, 0x50, 0xF2 };
+
+static int from_priority_to_tx_queue[] = {
+ IPW_TX_QUEUE_1, IPW_TX_QUEUE_2, IPW_TX_QUEUE_2, IPW_TX_QUEUE_1,
+ IPW_TX_QUEUE_3, IPW_TX_QUEUE_3, IPW_TX_QUEUE_4, IPW_TX_QUEUE_4
+};
+
+static u32 ipw_qos_get_burst_duration(struct ipw_priv *priv);
+
+static int ipw_send_qos_params_command(struct ipw_priv *priv, struct ieee80211_qos_parameters
+ *qos_param);
+static int ipw_send_qos_info_command(struct ipw_priv *priv, struct ieee80211_qos_information_element
+ *qos_param);
+#endif /* CONFIG_IPW_QOS */
+
+static struct iw_statistics *ipw_get_wireless_stats(struct net_device *dev);
+static void ipw_remove_current_network(struct ipw_priv *priv);
static void ipw_rx(struct ipw_priv *priv);
static int ipw_queue_tx_reclaim(struct ipw_priv *priv,
struct clx2_tx_queue *txq, int qindex);
@@ -68,42 +141,24 @@ static void ipw_tx_queue_free(struct ipw_priv *);
static struct ipw_rx_queue *ipw_rx_queue_alloc(struct ipw_priv *);
static void ipw_rx_queue_free(struct ipw_priv *, struct ipw_rx_queue *);
static void ipw_rx_queue_replenish(void *);
-
static int ipw_up(struct ipw_priv *);
+static void ipw_bg_up(void *);
static void ipw_down(struct ipw_priv *);
+static void ipw_bg_down(void *);
static int ipw_config(struct ipw_priv *);
static int init_supported_rates(struct ipw_priv *priv,
struct ipw_supported_rates *prates);
+static void ipw_set_hwcrypto_keys(struct ipw_priv *);
+static void ipw_send_wep_keys(struct ipw_priv *, int);
-static u8 band_b_active_channel[MAX_B_CHANNELS] = {
- 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0
-};
-static u8 band_a_active_channel[MAX_A_CHANNELS] = {
- 36, 40, 44, 48, 149, 153, 157, 161, 165, 52, 56, 60, 64, 0
-};
+static int ipw_is_valid_channel(struct ieee80211_device *, u8);
+static int ipw_channel_to_index(struct ieee80211_device *, u8);
+static u8 ipw_freq_to_channel(struct ieee80211_device *, u32);
+static int ipw_set_geo(struct ieee80211_device *, const struct ieee80211_geo *);
+static const struct ieee80211_geo *ipw_get_geo(struct ieee80211_device *);
-static int is_valid_channel(int mode_mask, int channel)
-{
- int i;
-
- if (!channel)
- return 0;
-
- if (mode_mask & IEEE_A)
- for (i = 0; i < MAX_A_CHANNELS; i++)
- if (band_a_active_channel[i] == channel)
- return IEEE_A;
-
- if (mode_mask & (IEEE_B | IEEE_G))
- for (i = 0; i < MAX_B_CHANNELS; i++)
- if (band_b_active_channel[i] == channel)
- return mode_mask & (IEEE_B | IEEE_G);
-
- return 0;
-}
-
-static char *snprint_line(char *buf, size_t count,
- const u8 * data, u32 len, u32 ofs)
+static int snprint_line(char *buf, size_t count,
+ const u8 * data, u32 len, u32 ofs)
{
int out, i, j, l;
char c;
@@ -134,7 +189,7 @@ static char *snprint_line(char *buf, size_t count,
out += snprintf(buf + out, count - out, " ");
}
- return buf;
+ return out;
}
static void printk_buf(int level, const u8 * data, u32 len)
@@ -145,14 +200,33 @@ static void printk_buf(int level, const u8 * data, u32 len)
return;
while (len) {
- printk(KERN_DEBUG "%s\n",
- snprint_line(line, sizeof(line), &data[ofs],
- min(len, 16U), ofs));
+ snprint_line(line, sizeof(line), &data[ofs],
+ min(len, 16U), ofs);
+ printk(KERN_DEBUG "%s\n", line);
ofs += 16;
len -= min(len, 16U);
}
}
+static int snprintk_buf(u8 * output, size_t size, const u8 * data, size_t len)
+{
+ size_t out = size;
+ u32 ofs = 0;
+ int total = 0;
+
+ while (size && len) {
+ out = snprint_line(output, size, &data[ofs],
+ min_t(size_t, len, 16U), ofs);
+
+ ofs += 16;
+ output += out;
+ size -= out;
+ len -= min_t(size_t, len, 16U);
+ total += out;
+ }
+ return total;
+}
+
static u32 _ipw_read_reg32(struct ipw_priv *priv, u32 reg);
#define ipw_read_reg32(a, b) _ipw_read_reg32(a, b)
@@ -226,38 +300,42 @@ static inline u32 __ipw_read32(char *f, u32 l, struct ipw_priv *ipw, u32 ofs)
#define ipw_read32(ipw, ofs) __ipw_read32(__FILE__, __LINE__, ipw, ofs)
static void _ipw_read_indirect(struct ipw_priv *, u32, u8 *, int);
-#define ipw_read_indirect(a, b, c, d) \
- IPW_DEBUG_IO("%s %d: read_inddirect(0x%08X) %d bytes\n", __FILE__, __LINE__, (u32)(b), d); \
- _ipw_read_indirect(a, b, c, d)
+static inline void __ipw_read_indirect(const char *f, int l,
+ struct ipw_priv *a, u32 b, u8 * c, int d)
+{
+ IPW_DEBUG_IO("%s %d: read_indirect(0x%08X) %d bytes\n", f, l, (u32) (b),
+ d);
+ _ipw_read_indirect(a, b, c, d);
+}
+
+#define ipw_read_indirect(a, b, c, d) __ipw_read_indirect(__FILE__, __LINE__, a, b, c, d)
static void _ipw_write_indirect(struct ipw_priv *priv, u32 addr, u8 * data,
int num);
#define ipw_write_indirect(a, b, c, d) \
IPW_DEBUG_IO("%s %d: write_indirect(0x%08X) %d bytes\n", __FILE__, __LINE__, (u32)(b), d); \
- _ipw_write_indirect(a, b, c, d)
+ _ipw_write_indirect(a, b, c, d)
/* indirect write s */
static void _ipw_write_reg32(struct ipw_priv *priv, u32 reg, u32 value)
{
IPW_DEBUG_IO(" %p : reg = 0x%8X : value = 0x%8X\n", priv, reg, value);
- _ipw_write32(priv, CX2_INDIRECT_ADDR, reg);
- _ipw_write32(priv, CX2_INDIRECT_DATA, value);
+ _ipw_write32(priv, IPW_INDIRECT_ADDR, reg);
+ _ipw_write32(priv, IPW_INDIRECT_DATA, value);
}
static void _ipw_write_reg8(struct ipw_priv *priv, u32 reg, u8 value)
{
IPW_DEBUG_IO(" reg = 0x%8X : value = 0x%8X\n", reg, value);
- _ipw_write32(priv, CX2_INDIRECT_ADDR, reg & CX2_INDIRECT_ADDR_MASK);
- _ipw_write8(priv, CX2_INDIRECT_DATA, value);
- IPW_DEBUG_IO(" reg = 0x%8lX : value = 0x%8X\n",
- (unsigned long)(priv->hw_base + CX2_INDIRECT_DATA), value);
+ _ipw_write32(priv, IPW_INDIRECT_ADDR, reg & IPW_INDIRECT_ADDR_MASK);
+ _ipw_write8(priv, IPW_INDIRECT_DATA, value);
}
static void _ipw_write_reg16(struct ipw_priv *priv, u32 reg, u16 value)
{
IPW_DEBUG_IO(" reg = 0x%8X : value = 0x%8X\n", reg, value);
- _ipw_write32(priv, CX2_INDIRECT_ADDR, reg & CX2_INDIRECT_ADDR_MASK);
- _ipw_write16(priv, CX2_INDIRECT_DATA, value);
+ _ipw_write32(priv, IPW_INDIRECT_ADDR, reg & IPW_INDIRECT_ADDR_MASK);
+ _ipw_write16(priv, IPW_INDIRECT_DATA, value);
}
/* indirect read s */
@@ -265,9 +343,9 @@ static void _ipw_write_reg16(struct ipw_priv *priv, u32 reg, u16 value)
static u8 _ipw_read_reg8(struct ipw_priv *priv, u32 reg)
{
u32 word;
- _ipw_write32(priv, CX2_INDIRECT_ADDR, reg & CX2_INDIRECT_ADDR_MASK);
+ _ipw_write32(priv, IPW_INDIRECT_ADDR, reg & IPW_INDIRECT_ADDR_MASK);
IPW_DEBUG_IO(" reg = 0x%8X : \n", reg);
- word = _ipw_read32(priv, CX2_INDIRECT_DATA);
+ word = _ipw_read32(priv, IPW_INDIRECT_DATA);
return (word >> ((reg & 0x3) * 8)) & 0xff;
}
@@ -277,8 +355,8 @@ static u32 _ipw_read_reg32(struct ipw_priv *priv, u32 reg)
IPW_DEBUG_IO("%p : reg = 0x%08x\n", priv, reg);
- _ipw_write32(priv, CX2_INDIRECT_ADDR, reg);
- value = _ipw_read32(priv, CX2_INDIRECT_DATA);
+ _ipw_write32(priv, IPW_INDIRECT_ADDR, reg);
+ value = _ipw_read32(priv, IPW_INDIRECT_DATA);
IPW_DEBUG_IO(" reg = 0x%4X : value = 0x%4x \n", reg, value);
return value;
}
@@ -287,67 +365,69 @@ static u32 _ipw_read_reg32(struct ipw_priv *priv, u32 reg)
static void _ipw_read_indirect(struct ipw_priv *priv, u32 addr, u8 * buf,
int num)
{
- u32 aligned_addr = addr & CX2_INDIRECT_ADDR_MASK;
+ u32 aligned_addr = addr & IPW_INDIRECT_ADDR_MASK;
u32 dif_len = addr - aligned_addr;
- u32 aligned_len;
u32 i;
IPW_DEBUG_IO("addr = %i, buf = %p, num = %i\n", addr, buf, num);
+ if (num <= 0) {
+ return;
+ }
+
/* Read the first nibble byte by byte */
if (unlikely(dif_len)) {
+ _ipw_write32(priv, IPW_INDIRECT_ADDR, aligned_addr);
/* Start reading at aligned_addr + dif_len */
- _ipw_write32(priv, CX2_INDIRECT_ADDR, aligned_addr);
- for (i = dif_len; i < 4; i++, buf++)
- *buf = _ipw_read8(priv, CX2_INDIRECT_DATA + i);
- num -= dif_len;
+ for (i = dif_len; ((i < 4) && (num > 0)); i++, num--)
+ *buf++ = _ipw_read8(priv, IPW_INDIRECT_DATA + i);
aligned_addr += 4;
}
- /* Read DWs through autoinc register */
- _ipw_write32(priv, CX2_AUTOINC_ADDR, aligned_addr);
- aligned_len = num & CX2_INDIRECT_ADDR_MASK;
- for (i = 0; i < aligned_len; i += 4, buf += 4, aligned_addr += 4)
- *(u32 *) buf = ipw_read32(priv, CX2_AUTOINC_DATA);
+ _ipw_write32(priv, IPW_AUTOINC_ADDR, aligned_addr);
+ for (; num >= 4; buf += 4, aligned_addr += 4, num -= 4)
+ *(u32 *) buf = _ipw_read32(priv, IPW_AUTOINC_DATA);
/* Copy the last nibble */
- dif_len = num - aligned_len;
- _ipw_write32(priv, CX2_INDIRECT_ADDR, aligned_addr);
- for (i = 0; i < dif_len; i++, buf++)
- *buf = ipw_read8(priv, CX2_INDIRECT_DATA + i);
+ if (unlikely(num)) {
+ _ipw_write32(priv, IPW_INDIRECT_ADDR, aligned_addr);
+ for (i = 0; num > 0; i++, num--)
+ *buf++ = ipw_read8(priv, IPW_INDIRECT_DATA + i);
+ }
}
static void _ipw_write_indirect(struct ipw_priv *priv, u32 addr, u8 * buf,
int num)
{
- u32 aligned_addr = addr & CX2_INDIRECT_ADDR_MASK;
+ u32 aligned_addr = addr & IPW_INDIRECT_ADDR_MASK;
u32 dif_len = addr - aligned_addr;
- u32 aligned_len;
u32 i;
IPW_DEBUG_IO("addr = %i, buf = %p, num = %i\n", addr, buf, num);
+ if (num <= 0) {
+ return;
+ }
+
/* Write the first nibble byte by byte */
if (unlikely(dif_len)) {
- /* Start writing at aligned_addr + dif_len */
- _ipw_write32(priv, CX2_INDIRECT_ADDR, aligned_addr);
- for (i = dif_len; i < 4; i++, buf++)
- _ipw_write8(priv, CX2_INDIRECT_DATA + i, *buf);
- num -= dif_len;
+ _ipw_write32(priv, IPW_INDIRECT_ADDR, aligned_addr);
+ /* Start reading at aligned_addr + dif_len */
+ for (i = dif_len; ((i < 4) && (num > 0)); i++, num--, buf++)
+ _ipw_write8(priv, IPW_INDIRECT_DATA + i, *buf);
aligned_addr += 4;
}
- /* Write DWs through autoinc register */
- _ipw_write32(priv, CX2_AUTOINC_ADDR, aligned_addr);
- aligned_len = num & CX2_INDIRECT_ADDR_MASK;
- for (i = 0; i < aligned_len; i += 4, buf += 4, aligned_addr += 4)
- _ipw_write32(priv, CX2_AUTOINC_DATA, *(u32 *) buf);
+ _ipw_write32(priv, IPW_AUTOINC_ADDR, aligned_addr);
+ for (; num >= 4; buf += 4, aligned_addr += 4, num -= 4)
+ _ipw_write32(priv, IPW_AUTOINC_DATA, *(u32 *) buf);
/* Copy the last nibble */
- dif_len = num - aligned_len;
- _ipw_write32(priv, CX2_INDIRECT_ADDR, aligned_addr);
- for (i = 0; i < dif_len; i++, buf++)
- _ipw_write8(priv, CX2_INDIRECT_DATA + i, *buf);
+ if (unlikely(num)) {
+ _ipw_write32(priv, IPW_INDIRECT_ADDR, aligned_addr);
+ for (i = 0; num > 0; i++, num--, buf++)
+ _ipw_write8(priv, IPW_INDIRECT_DATA + i, *buf);
+ }
}
static void ipw_write_direct(struct ipw_priv *priv, u32 addr, void *buf,
@@ -371,7 +451,7 @@ static inline void ipw_enable_interrupts(struct ipw_priv *priv)
if (priv->status & STATUS_INT_ENABLED)
return;
priv->status |= STATUS_INT_ENABLED;
- ipw_write32(priv, CX2_INTA_MASK_R, CX2_INTA_MASK_ALL);
+ ipw_write32(priv, IPW_INTA_MASK_R, IPW_INTA_MASK_ALL);
}
static inline void ipw_disable_interrupts(struct ipw_priv *priv)
@@ -379,9 +459,10 @@ static inline void ipw_disable_interrupts(struct ipw_priv *priv)
if (!(priv->status & STATUS_INT_ENABLED))
return;
priv->status &= ~STATUS_INT_ENABLED;
- ipw_write32(priv, CX2_INTA_MASK_R, ~CX2_INTA_MASK_ALL);
+ ipw_write32(priv, IPW_INTA_MASK_R, ~IPW_INTA_MASK_ALL);
}
+#ifdef CONFIG_IPW_DEBUG
static char *ipw_error_desc(u32 val)
{
switch (val) {
@@ -394,81 +475,65 @@ static char *ipw_error_desc(u32 val)
case IPW_FW_ERROR_MEMORY_OVERFLOW:
return "MEMORY_OVERFLOW";
case IPW_FW_ERROR_BAD_PARAM:
- return "ERROR_BAD_PARAM";
+ return "BAD_PARAM";
case IPW_FW_ERROR_BAD_CHECKSUM:
- return "ERROR_BAD_CHECKSUM";
+ return "BAD_CHECKSUM";
case IPW_FW_ERROR_NMI_INTERRUPT:
- return "ERROR_NMI_INTERRUPT";
+ return "NMI_INTERRUPT";
case IPW_FW_ERROR_BAD_DATABASE:
- return "ERROR_BAD_DATABASE";
+ return "BAD_DATABASE";
case IPW_FW_ERROR_ALLOC_FAIL:
- return "ERROR_ALLOC_FAIL";
+ return "ALLOC_FAIL";
case IPW_FW_ERROR_DMA_UNDERRUN:
- return "ERROR_DMA_UNDERRUN";
+ return "DMA_UNDERRUN";
case IPW_FW_ERROR_DMA_STATUS:
- return "ERROR_DMA_STATUS";
- case IPW_FW_ERROR_DINOSTATUS_ERROR:
- return "ERROR_DINOSTATUS_ERROR";
- case IPW_FW_ERROR_EEPROMSTATUS_ERROR:
- return "ERROR_EEPROMSTATUS_ERROR";
+ return "DMA_STATUS";
+ case IPW_FW_ERROR_DINO_ERROR:
+ return "DINO_ERROR";
+ case IPW_FW_ERROR_EEPROM_ERROR:
+ return "EEPROM_ERROR";
case IPW_FW_ERROR_SYSASSERT:
- return "ERROR_SYSASSERT";
+ return "SYSASSERT";
case IPW_FW_ERROR_FATAL_ERROR:
- return "ERROR_FATALSTATUS_ERROR";
+ return "FATAL_ERROR";
default:
- return "UNKNOWNSTATUS_ERROR";
+ return "UNKNOWN_ERROR";
}
}
-static void ipw_dump_nic_error_log(struct ipw_priv *priv)
+static void ipw_dump_error_log(struct ipw_priv *priv,
+ struct ipw_fw_error *error)
{
- u32 desc, time, blink1, blink2, ilink1, ilink2, idata, i, count, base;
-
- base = ipw_read32(priv, IPWSTATUS_ERROR_LOG);
- count = ipw_read_reg32(priv, base);
+ u32 i;
- if (ERROR_START_OFFSET <= count * ERROR_ELEM_SIZE) {
- IPW_ERROR("Start IPW Error Log Dump:\n");
- IPW_ERROR("Status: 0x%08X, Config: %08X\n",
- priv->status, priv->config);
+ if (!error) {
+ IPW_ERROR("Error allocating and capturing error log. "
+ "Nothing to dump.\n");
+ return;
}
- for (i = ERROR_START_OFFSET;
- i <= count * ERROR_ELEM_SIZE; i += ERROR_ELEM_SIZE) {
- desc = ipw_read_reg32(priv, base + i);
- time = ipw_read_reg32(priv, base + i + 1 * sizeof(u32));
- blink1 = ipw_read_reg32(priv, base + i + 2 * sizeof(u32));
- blink2 = ipw_read_reg32(priv, base + i + 3 * sizeof(u32));
- ilink1 = ipw_read_reg32(priv, base + i + 4 * sizeof(u32));
- ilink2 = ipw_read_reg32(priv, base + i + 5 * sizeof(u32));
- idata = ipw_read_reg32(priv, base + i + 6 * sizeof(u32));
+ IPW_ERROR("Start IPW Error Log Dump:\n");
+ IPW_ERROR("Status: 0x%08X, Config: %08X\n",
+ error->status, error->config);
+ for (i = 0; i < error->elem_len; i++)
IPW_ERROR("%s %i 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n",
- ipw_error_desc(desc), time, blink1, blink2,
- ilink1, ilink2, idata);
- }
+ ipw_error_desc(error->elem[i].desc),
+ error->elem[i].time,
+ error->elem[i].blink1,
+ error->elem[i].blink2,
+ error->elem[i].link1,
+ error->elem[i].link2, error->elem[i].data);
+ for (i = 0; i < error->log_len; i++)
+ IPW_ERROR("%i\t0x%08x\t%i\n",
+ error->log[i].time,
+ error->log[i].data, error->log[i].event);
}
+#endif
-static void ipw_dump_nic_event_log(struct ipw_priv *priv)
+static inline int ipw_is_init(struct ipw_priv *priv)
{
- u32 ev, time, data, i, count, base;
-
- base = ipw_read32(priv, IPW_EVENT_LOG);
- count = ipw_read_reg32(priv, base);
-
- if (EVENT_START_OFFSET <= count * EVENT_ELEM_SIZE)
- IPW_ERROR("Start IPW Event Log Dump:\n");
-
- for (i = EVENT_START_OFFSET;
- i <= count * EVENT_ELEM_SIZE; i += EVENT_ELEM_SIZE) {
- ev = ipw_read_reg32(priv, base + i);
- time = ipw_read_reg32(priv, base + i + 1 * sizeof(u32));
- data = ipw_read_reg32(priv, base + i + 2 * sizeof(u32));
-
-#ifdef CONFIG_IPW_DEBUG
- IPW_ERROR("%i\t0x%08x\t%i\n", time, data, ev);
-#endif
- }
+ return (priv->status & STATUS_INIT) ? 1 : 0;
}
static int ipw_get_ordinal(struct ipw_priv *priv, u32 ord, void *val, u32 * len)
@@ -636,6 +701,340 @@ static void ipw_init_ordinals(struct ipw_priv *priv)
}
+u32 ipw_register_toggle(u32 reg)
+{
+ reg &= ~IPW_START_STANDBY;
+ if (reg & IPW_GATE_ODMA)
+ reg &= ~IPW_GATE_ODMA;
+ if (reg & IPW_GATE_IDMA)
+ reg &= ~IPW_GATE_IDMA;
+ if (reg & IPW_GATE_ADMA)
+ reg &= ~IPW_GATE_ADMA;
+ return reg;
+}
+
+/*
+ * LED behavior:
+ * - On radio ON, turn on any LEDs that require to be on during start
+ * - On initialization, start unassociated blink
+ * - On association, disable unassociated blink
+ * - On disassociation, start unassociated blink
+ * - On radio OFF, turn off any LEDs started during radio on
+ *
+ */
+#define LD_TIME_LINK_ON 300
+#define LD_TIME_LINK_OFF 2700
+#define LD_TIME_ACT_ON 250
+
+void ipw_led_link_on(struct ipw_priv *priv)
+{
+ unsigned long flags;
+ u32 led;
+
+ /* If configured to not use LEDs, or nic_type is 1,
+ * then we don't toggle a LINK led */
+ if (priv->config & CFG_NO_LED || priv->nic_type == EEPROM_NIC_TYPE_1)
+ return;
+
+ spin_lock_irqsave(&priv->lock, flags);
+
+ if (!(priv->status & STATUS_RF_KILL_MASK) &&
+ !(priv->status & STATUS_LED_LINK_ON)) {
+ IPW_DEBUG_LED("Link LED On\n");
+ led = ipw_read_reg32(priv, IPW_EVENT_REG);
+ led |= priv->led_association_on;
+
+ led = ipw_register_toggle(led);
+
+ IPW_DEBUG_LED("Reg: 0x%08X\n", led);
+ ipw_write_reg32(priv, IPW_EVENT_REG, led);
+
+ priv->status |= STATUS_LED_LINK_ON;
+
+ /* If we aren't associated, schedule turning the LED off */
+ if (!(priv->status & STATUS_ASSOCIATED))
+ queue_delayed_work(priv->workqueue,
+ &priv->led_link_off,
+ LD_TIME_LINK_ON);
+ }
+
+ spin_unlock_irqrestore(&priv->lock, flags);
+}
+
+static void ipw_bg_led_link_on(void *data)
+{
+ struct ipw_priv *priv = data;
+ down(&priv->sem);
+ ipw_led_link_on(data);
+ up(&priv->sem);
+}
+
+void ipw_led_link_off(struct ipw_priv *priv)
+{
+ unsigned long flags;
+ u32 led;
+
+ /* If configured not to use LEDs, or nic type is 1,
+ * then we don't goggle the LINK led. */
+ if (priv->config & CFG_NO_LED || priv->nic_type == EEPROM_NIC_TYPE_1)
+ return;
+
+ spin_lock_irqsave(&priv->lock, flags);
+
+ if (priv->status & STATUS_LED_LINK_ON) {
+ led = ipw_read_reg32(priv, IPW_EVENT_REG);
+ led &= priv->led_association_off;
+ led = ipw_register_toggle(led);
+
+ IPW_DEBUG_LED("Reg: 0x%08X\n", led);
+ ipw_write_reg32(priv, IPW_EVENT_REG, led);
+
+ IPW_DEBUG_LED("Link LED Off\n");
+
+ priv->status &= ~STATUS_LED_LINK_ON;
+
+ /* If we aren't associated and the radio is on, schedule
+ * turning the LED on (blink while unassociated) */
+ if (!(priv->status & STATUS_RF_KILL_MASK) &&
+ !(priv->status & STATUS_ASSOCIATED))
+ queue_delayed_work(priv->workqueue, &priv->led_link_on,
+ LD_TIME_LINK_OFF);
+
+ }
+
+ spin_unlock_irqrestore(&priv->lock, flags);
+}
+
+static void ipw_bg_led_link_off(void *data)
+{
+ struct ipw_priv *priv = data;
+ down(&priv->sem);
+ ipw_led_link_off(data);
+ up(&priv->sem);
+}
+
+static inline void __ipw_led_activity_on(struct ipw_priv *priv)
+{
+ u32 led;
+
+ if (priv->config & CFG_NO_LED)
+ return;
+
+ if (priv->status & STATUS_RF_KILL_MASK)
+ return;
+
+ if (!(priv->status & STATUS_LED_ACT_ON)) {
+ led = ipw_read_reg32(priv, IPW_EVENT_REG);
+ led |= priv->led_activity_on;
+
+ led = ipw_register_toggle(led);
+
+ IPW_DEBUG_LED("Reg: 0x%08X\n", led);
+ ipw_write_reg32(priv, IPW_EVENT_REG, led);
+
+ IPW_DEBUG_LED("Activity LED On\n");
+
+ priv->status |= STATUS_LED_ACT_ON;
+
+ cancel_delayed_work(&priv->led_act_off);
+ queue_delayed_work(priv->workqueue, &priv->led_act_off,
+ LD_TIME_ACT_ON);
+ } else {
+ /* Reschedule LED off for full time period */
+ cancel_delayed_work(&priv->led_act_off);
+ queue_delayed_work(priv->workqueue, &priv->led_act_off,
+ LD_TIME_ACT_ON);
+ }
+}
+
+void ipw_led_activity_on(struct ipw_priv *priv)
+{
+ unsigned long flags;
+ spin_lock_irqsave(&priv->lock, flags);
+ __ipw_led_activity_on(priv);
+ spin_unlock_irqrestore(&priv->lock, flags);
+}
+
+void ipw_led_activity_off(struct ipw_priv *priv)
+{
+ unsigned long flags;
+ u32 led;
+
+ if (priv->config & CFG_NO_LED)
+ return;
+
+ spin_lock_irqsave(&priv->lock, flags);
+
+ if (priv->status & STATUS_LED_ACT_ON) {
+ led = ipw_read_reg32(priv, IPW_EVENT_REG);
+ led &= priv->led_activity_off;
+
+ led = ipw_register_toggle(led);
+
+ IPW_DEBUG_LED("Reg: 0x%08X\n", led);
+ ipw_write_reg32(priv, IPW_EVENT_REG, led);
+
+ IPW_DEBUG_LED("Activity LED Off\n");
+
+ priv->status &= ~STATUS_LED_ACT_ON;
+ }
+
+ spin_unlock_irqrestore(&priv->lock, flags);
+}
+
+static void ipw_bg_led_activity_off(void *data)
+{
+ struct ipw_priv *priv = data;
+ down(&priv->sem);
+ ipw_led_activity_off(data);
+ up(&priv->sem);
+}
+
+void ipw_led_band_on(struct ipw_priv *priv)
+{
+ unsigned long flags;
+ u32 led;
+
+ /* Only nic type 1 supports mode LEDs */
+ if (priv->config & CFG_NO_LED ||
+ priv->nic_type != EEPROM_NIC_TYPE_1 || !priv->assoc_network)
+ return;
+
+ spin_lock_irqsave(&priv->lock, flags);
+
+ led = ipw_read_reg32(priv, IPW_EVENT_REG);
+ if (priv->assoc_network->mode == IEEE_A) {
+ led |= priv->led_ofdm_on;
+ led &= priv->led_association_off;
+ IPW_DEBUG_LED("Mode LED On: 802.11a\n");
+ } else if (priv->assoc_network->mode == IEEE_G) {
+ led |= priv->led_ofdm_on;
+ led |= priv->led_association_on;
+ IPW_DEBUG_LED("Mode LED On: 802.11g\n");
+ } else {
+ led &= priv->led_ofdm_off;
+ led |= priv->led_association_on;
+ IPW_DEBUG_LED("Mode LED On: 802.11b\n");
+ }
+
+ led = ipw_register_toggle(led);
+
+ IPW_DEBUG_LED("Reg: 0x%08X\n", led);
+ ipw_write_reg32(priv, IPW_EVENT_REG, led);
+
+ spin_unlock_irqrestore(&priv->lock, flags);
+}
+
+void ipw_led_band_off(struct ipw_priv *priv)
+{
+ unsigned long flags;
+ u32 led;
+
+ /* Only nic type 1 supports mode LEDs */
+ if (priv->config & CFG_NO_LED || priv->nic_type != EEPROM_NIC_TYPE_1)
+ return;
+
+ spin_lock_irqsave(&priv->lock, flags);
+
+ led = ipw_read_reg32(priv, IPW_EVENT_REG);
+ led &= priv->led_ofdm_off;
+ led &= priv->led_association_off;
+
+ led = ipw_register_toggle(led);
+
+ IPW_DEBUG_LED("Reg: 0x%08X\n", led);
+ ipw_write_reg32(priv, IPW_EVENT_REG, led);
+
+ spin_unlock_irqrestore(&priv->lock, flags);
+}
+
+void ipw_led_radio_on(struct ipw_priv *priv)
+{
+ ipw_led_link_on(priv);
+}
+
+void ipw_led_radio_off(struct ipw_priv *priv)
+{
+ ipw_led_activity_off(priv);
+ ipw_led_link_off(priv);
+}
+
+void ipw_led_link_up(struct ipw_priv *priv)
+{
+ /* Set the Link Led on for all nic types */
+ ipw_led_link_on(priv);
+}
+
+void ipw_led_link_down(struct ipw_priv *priv)
+{
+ ipw_led_activity_off(priv);
+ ipw_led_link_off(priv);
+
+ if (priv->status & STATUS_RF_KILL_MASK)
+ ipw_led_radio_off(priv);
+}
+
+void ipw_led_init(struct ipw_priv *priv)
+{
+ priv->nic_type = priv->eeprom[EEPROM_NIC_TYPE];
+
+ /* Set the default PINs for the link and activity leds */
+ priv->led_activity_on = IPW_ACTIVITY_LED;
+ priv->led_activity_off = ~(IPW_ACTIVITY_LED);
+
+ priv->led_association_on = IPW_ASSOCIATED_LED;
+ priv->led_association_off = ~(IPW_ASSOCIATED_LED);
+
+ /* Set the default PINs for the OFDM leds */
+ priv->led_ofdm_on = IPW_OFDM_LED;
+ priv->led_ofdm_off = ~(IPW_OFDM_LED);
+
+ switch (priv->nic_type) {
+ case EEPROM_NIC_TYPE_1:
+ /* In this NIC type, the LEDs are reversed.... */
+ priv->led_activity_on = IPW_ASSOCIATED_LED;
+ priv->led_activity_off = ~(IPW_ASSOCIATED_LED);
+ priv->led_association_on = IPW_ACTIVITY_LED;
+ priv->led_association_off = ~(IPW_ACTIVITY_LED);
+
+ if (!(priv->config & CFG_NO_LED))
+ ipw_led_band_on(priv);
+
+ /* And we don't blink link LEDs for this nic, so
+ * just return here */
+ return;
+
+ case EEPROM_NIC_TYPE_3:
+ case EEPROM_NIC_TYPE_2:
+ case EEPROM_NIC_TYPE_4:
+ case EEPROM_NIC_TYPE_0:
+ break;
+
+ default:
+ IPW_DEBUG_INFO("Unknown NIC type from EEPROM: %d\n",
+ priv->nic_type);
+ priv->nic_type = EEPROM_NIC_TYPE_0;
+ break;
+ }
+
+ if (!(priv->config & CFG_NO_LED)) {
+ if (priv->status & STATUS_ASSOCIATED)
+ ipw_led_link_on(priv);
+ else
+ ipw_led_link_off(priv);
+ }
+}
+
+void ipw_led_shutdown(struct ipw_priv *priv)
+{
+ ipw_led_activity_off(priv);
+ ipw_led_link_off(priv);
+ ipw_led_band_off(priv);
+ cancel_delayed_work(&priv->led_link_on);
+ cancel_delayed_work(&priv->led_link_off);
+ cancel_delayed_work(&priv->led_act_off);
+}
+
/*
* The following adds a new attribute to the sysfs representation
* of this device driver (i.e. a new file in /sys/bus/pci/drivers/ipw/)
@@ -647,8 +1046,9 @@ static ssize_t show_debug_level(struct device_driver *d, char *buf)
{
return sprintf(buf, "0x%08X\n", ipw_debug_level);
}
-static ssize_t store_debug_level(struct device_driver *d,
- const char *buf, size_t count)
+
+static ssize_t store_debug_level(struct device_driver *d, const char *buf,
+ size_t count)
{
char *p = (char *)buf;
u32 val;
@@ -672,75 +1072,263 @@ static ssize_t store_debug_level(struct device_driver *d,
static DRIVER_ATTR(debug_level, S_IWUSR | S_IRUGO,
show_debug_level, store_debug_level);
-static ssize_t show_status(struct device *d,
- struct device_attribute *attr, char *buf)
+static inline u32 ipw_get_event_log_len(struct ipw_priv *priv)
{
- struct ipw_priv *p = d->driver_data;
- return sprintf(buf, "0x%08x\n", (int)p->status);
+ return ipw_read_reg32(priv, ipw_read32(priv, IPW_EVENT_LOG));
}
-static DEVICE_ATTR(status, S_IRUGO, show_status, NULL);
+static void ipw_capture_event_log(struct ipw_priv *priv,
+ u32 log_len, struct ipw_event *log)
+{
+ u32 base;
-static ssize_t show_cfg(struct device *d, struct device_attribute *attr,
- char *buf)
+ if (log_len) {
+ base = ipw_read32(priv, IPW_EVENT_LOG);
+ ipw_read_indirect(priv, base + sizeof(base) + sizeof(u32),
+ (u8 *) log, sizeof(*log) * log_len);
+ }
+}
+
+static struct ipw_fw_error *ipw_alloc_error_log(struct ipw_priv *priv)
{
- struct ipw_priv *p = d->driver_data;
- return sprintf(buf, "0x%08x\n", (int)p->config);
+ struct ipw_fw_error *error;
+ u32 log_len = ipw_get_event_log_len(priv);
+ u32 base = ipw_read32(priv, IPW_ERROR_LOG);
+ u32 elem_len = ipw_read_reg32(priv, base);
+
+ error = kmalloc(sizeof(*error) +
+ sizeof(*error->elem) * elem_len +
+ sizeof(*error->log) * log_len, GFP_ATOMIC);
+ if (!error) {
+ IPW_ERROR("Memory allocation for firmware error log "
+ "failed.\n");
+ return NULL;
+ }
+ error->jiffies = jiffies;
+ error->status = priv->status;
+ error->config = priv->config;
+ error->elem_len = elem_len;
+ error->log_len = log_len;
+ error->elem = (struct ipw_error_elem *)error->payload;
+ error->log = (struct ipw_event *)(error->elem +
+ (sizeof(*error->elem) * elem_len));
+
+ ipw_capture_event_log(priv, log_len, error->log);
+
+ if (elem_len)
+ ipw_read_indirect(priv, base + sizeof(base), (u8 *) error->elem,
+ sizeof(*error->elem) * elem_len);
+
+ return error;
}
-static DEVICE_ATTR(cfg, S_IRUGO, show_cfg, NULL);
+static void ipw_free_error_log(struct ipw_fw_error *error)
+{
+ if (error)
+ kfree(error);
+}
-static ssize_t show_nic_type(struct device *d,
- struct device_attribute *attr, char *buf)
+static ssize_t show_event_log(struct device *d,
+ struct device_attribute *attr, char *buf)
{
- struct ipw_priv *p = d->driver_data;
- u8 type = p->eeprom[EEPROM_NIC_TYPE];
+ struct ipw_priv *priv = dev_get_drvdata(d);
+ u32 log_len = ipw_get_event_log_len(priv);
+ struct ipw_event log[log_len];
+ u32 len = 0, i;
+
+ ipw_capture_event_log(priv, log_len, log);
+
+ len += snprintf(buf + len, PAGE_SIZE - len, "%08X", log_len);
+ for (i = 0; i < log_len; i++)
+ len += snprintf(buf + len, PAGE_SIZE - len,
+ "\n%08X%08X%08X",
+ log[i].time, log[i].event, log[i].data);
+ len += snprintf(buf + len, PAGE_SIZE - len, "\n");
+ return len;
+}
+
+static DEVICE_ATTR(event_log, S_IRUGO, show_event_log, NULL);
- switch (type) {
- case EEPROM_NIC_TYPE_STANDARD:
- return sprintf(buf, "STANDARD\n");
- case EEPROM_NIC_TYPE_DELL:
- return sprintf(buf, "DELL\n");
- case EEPROM_NIC_TYPE_FUJITSU:
- return sprintf(buf, "FUJITSU\n");
- case EEPROM_NIC_TYPE_IBM:
- return sprintf(buf, "IBM\n");
- case EEPROM_NIC_TYPE_HP:
- return sprintf(buf, "HP\n");
+static ssize_t show_error(struct device *d,
+ struct device_attribute *attr, char *buf)
+{
+ struct ipw_priv *priv = dev_get_drvdata(d);
+ u32 len = 0, i;
+ if (!priv->error)
+ return 0;
+ len += snprintf(buf + len, PAGE_SIZE - len,
+ "%08lX%08X%08X%08X",
+ priv->error->jiffies,
+ priv->error->status,
+ priv->error->config, priv->error->elem_len);
+ for (i = 0; i < priv->error->elem_len; i++)
+ len += snprintf(buf + len, PAGE_SIZE - len,
+ "\n%08X%08X%08X%08X%08X%08X%08X",
+ priv->error->elem[i].time,
+ priv->error->elem[i].desc,
+ priv->error->elem[i].blink1,
+ priv->error->elem[i].blink2,
+ priv->error->elem[i].link1,
+ priv->error->elem[i].link2,
+ priv->error->elem[i].data);
+
+ len += snprintf(buf + len, PAGE_SIZE - len,
+ "\n%08X", priv->error->log_len);
+ for (i = 0; i < priv->error->log_len; i++)
+ len += snprintf(buf + len, PAGE_SIZE - len,
+ "\n%08X%08X%08X",
+ priv->error->log[i].time,
+ priv->error->log[i].event,
+ priv->error->log[i].data);
+ len += snprintf(buf + len, PAGE_SIZE - len, "\n");
+ return len;
+}
+
+static ssize_t clear_error(struct device *d,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct ipw_priv *priv = dev_get_drvdata(d);
+ if (priv->error) {
+ ipw_free_error_log(priv->error);
+ priv->error = NULL;
}
+ return count;
+}
- return sprintf(buf, "UNKNOWN\n");
+static DEVICE_ATTR(error, S_IRUGO | S_IWUSR, show_error, clear_error);
+
+static ssize_t show_cmd_log(struct device *d,
+ struct device_attribute *attr, char *buf)
+{
+ struct ipw_priv *priv = dev_get_drvdata(d);
+ u32 len = 0, i;
+ if (!priv->cmdlog)
+ return 0;
+ for (i = (priv->cmdlog_pos + 1) % priv->cmdlog_len;
+ (i != priv->cmdlog_pos) && (PAGE_SIZE - len);
+ i = (i + 1) % priv->cmdlog_len) {
+ len +=
+ snprintf(buf + len, PAGE_SIZE - len,
+ "\n%08lX%08X%08X%08X\n", priv->cmdlog[i].jiffies,
+ priv->cmdlog[i].retcode, priv->cmdlog[i].cmd.cmd,
+ priv->cmdlog[i].cmd.len);
+ len +=
+ snprintk_buf(buf + len, PAGE_SIZE - len,
+ (u8 *) priv->cmdlog[i].cmd.param,
+ priv->cmdlog[i].cmd.len);
+ len += snprintf(buf + len, PAGE_SIZE - len, "\n");
+ }
+ len += snprintf(buf + len, PAGE_SIZE - len, "\n");
+ return len;
}
-static DEVICE_ATTR(nic_type, S_IRUGO, show_nic_type, NULL);
+static DEVICE_ATTR(cmd_log, S_IRUGO, show_cmd_log, NULL);
-static ssize_t dump_error_log(struct device *d,
- struct device_attribute *attr, const char *buf,
- size_t count)
+static ssize_t show_scan_age(struct device *d, struct device_attribute *attr,
+ char *buf)
{
- char *p = (char *)buf;
+ struct ipw_priv *priv = dev_get_drvdata(d);
+ return sprintf(buf, "%d\n", priv->ieee->scan_age);
+}
- if (p[0] == '1')
- ipw_dump_nic_error_log((struct ipw_priv *)d->driver_data);
+static ssize_t store_scan_age(struct device *d, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct ipw_priv *priv = dev_get_drvdata(d);
+#ifdef CONFIG_IPW_DEBUG
+ struct net_device *dev = priv->net_dev;
+#endif
+ char buffer[] = "00000000";
+ unsigned long len =
+ (sizeof(buffer) - 1) > count ? count : sizeof(buffer) - 1;
+ unsigned long val;
+ char *p = buffer;
- return strnlen(buf, count);
+ IPW_DEBUG_INFO("enter\n");
+
+ strncpy(buffer, buf, len);
+ buffer[len] = 0;
+
+ if (p[1] == 'x' || p[1] == 'X' || p[0] == 'x' || p[0] == 'X') {
+ p++;
+ if (p[0] == 'x' || p[0] == 'X')
+ p++;
+ val = simple_strtoul(p, &p, 16);
+ } else
+ val = simple_strtoul(p, &p, 10);
+ if (p == buffer) {
+ IPW_DEBUG_INFO("%s: user supplied invalid value.\n", dev->name);
+ } else {
+ priv->ieee->scan_age = val;
+ IPW_DEBUG_INFO("set scan_age = %u\n", priv->ieee->scan_age);
+ }
+
+ IPW_DEBUG_INFO("exit\n");
+ return len;
}
-static DEVICE_ATTR(dump_errors, S_IWUSR, NULL, dump_error_log);
+static DEVICE_ATTR(scan_age, S_IWUSR | S_IRUGO, show_scan_age, store_scan_age);
-static ssize_t dump_event_log(struct device *d,
- struct device_attribute *attr, const char *buf,
- size_t count)
+static ssize_t show_led(struct device *d, struct device_attribute *attr,
+ char *buf)
{
- char *p = (char *)buf;
+ struct ipw_priv *priv = dev_get_drvdata(d);
+ return sprintf(buf, "%d\n", (priv->config & CFG_NO_LED) ? 0 : 1);
+}
- if (p[0] == '1')
- ipw_dump_nic_event_log((struct ipw_priv *)d->driver_data);
+static ssize_t store_led(struct device *d, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct ipw_priv *priv = dev_get_drvdata(d);
- return strnlen(buf, count);
+ IPW_DEBUG_INFO("enter\n");
+
+ if (count == 0)
+ return 0;
+
+ if (*buf == 0) {
+ IPW_DEBUG_LED("Disabling LED control.\n");
+ priv->config |= CFG_NO_LED;
+ ipw_led_shutdown(priv);
+ } else {
+ IPW_DEBUG_LED("Enabling LED control.\n");
+ priv->config &= ~CFG_NO_LED;
+ ipw_led_init(priv);
+ }
+
+ IPW_DEBUG_INFO("exit\n");
+ return count;
}
-static DEVICE_ATTR(dump_events, S_IWUSR, NULL, dump_event_log);
+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;
+ return sprintf(buf, "0x%08x\n", (int)p->status);
+}
+
+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;
+ return sprintf(buf, "0x%08x\n", (int)p->config);
+}
+
+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;
+ return sprintf(buf, "TYPE: %d\n", priv->nic_type);
+}
+
+static DEVICE_ATTR(nic_type, S_IRUGO, show_nic_type, NULL);
static ssize_t show_ucode_version(struct device *d,
struct device_attribute *attr, char *buf)
@@ -798,7 +1386,7 @@ static ssize_t show_command_event_reg(struct device *d,
u32 reg = 0;
struct ipw_priv *p = d->driver_data;
- reg = ipw_read_reg32(p, CX2_INTERNAL_CMD_EVENT);
+ reg = ipw_read_reg32(p, IPW_INTERNAL_CMD_EVENT);
return sprintf(buf, "0x%08x\n", reg);
}
static ssize_t store_command_event_reg(struct device *d,
@@ -809,7 +1397,7 @@ static ssize_t store_command_event_reg(struct device *d,
struct ipw_priv *p = d->driver_data;
sscanf(buf, "%x", &reg);
- ipw_write_reg32(p, CX2_INTERNAL_CMD_EVENT, reg);
+ ipw_write_reg32(p, IPW_INTERNAL_CMD_EVENT, reg);
return strnlen(buf, count);
}
@@ -845,6 +1433,7 @@ static ssize_t show_indirect_dword(struct device *d,
{
u32 reg = 0;
struct ipw_priv *priv = d->driver_data;
+
if (priv->status & STATUS_INDIRECT_DWORD)
reg = ipw_read_reg32(priv, priv->indirect_dword);
else
@@ -871,6 +1460,7 @@ static ssize_t show_indirect_byte(struct device *d,
{
u8 reg = 0;
struct ipw_priv *priv = d->driver_data;
+
if (priv->status & STATUS_INDIRECT_BYTE)
reg = ipw_read_reg8(priv, priv->indirect_byte);
else
@@ -945,7 +1535,7 @@ static ssize_t show_rf_kill(struct device *d, struct device_attribute *attr,
static int ipw_radio_kill_sw(struct ipw_priv *priv, int disable_radio)
{
if ((disable_radio ? 1 : 0) ==
- (priv->status & STATUS_RF_KILL_SW ? 1 : 0))
+ ((priv->status & STATUS_RF_KILL_SW) ? 1 : 0))
return 0;
IPW_DEBUG_RF_KILL("Manual SW RF Kill set to: RADIO %s\n",
@@ -954,10 +1544,8 @@ static int ipw_radio_kill_sw(struct ipw_priv *priv, int disable_radio)
if (disable_radio) {
priv->status |= STATUS_RF_KILL_SW;
- if (priv->workqueue) {
+ if (priv->workqueue)
cancel_delayed_work(&priv->request_scan);
- }
- wake_up_interruptible(&priv->wait_command_queue);
queue_work(priv->workqueue, &priv->down);
} else {
priv->status &= ~STATUS_RF_KILL_SW;
@@ -987,6 +1575,93 @@ static ssize_t store_rf_kill(struct device *d, struct device_attribute *attr,
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;
+ int pos = 0, len = 0;
+ if (priv->config & CFG_SPEED_SCAN) {
+ while (priv->speed_scan[pos] != 0)
+ len += sprintf(&buf[len], "%d ",
+ priv->speed_scan[pos++]);
+ return len + sprintf(&buf[len], "\n");
+ }
+
+ return sprintf(buf, "0\n");
+}
+
+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;
+ int channel, pos = 0;
+ const char *p = buf;
+
+ /* list of space separated channels to scan, optionally ending with 0 */
+ while ((channel = simple_strtol(p, NULL, 0))) {
+ if (pos == MAX_SPEED_SCAN - 1) {
+ priv->speed_scan[pos] = 0;
+ break;
+ }
+
+ if (ipw_is_valid_channel(priv->ieee, channel))
+ priv->speed_scan[pos++] = channel;
+ else
+ IPW_WARNING("Skipping invalid channel request: %d\n",
+ channel);
+ p = strchr(p, ' ');
+ if (!p)
+ break;
+ while (*p == ' ' || *p == '\t')
+ p++;
+ }
+
+ if (pos == 0)
+ priv->config &= ~CFG_SPEED_SCAN;
+ else {
+ priv->speed_scan_pos = 0;
+ priv->config |= CFG_SPEED_SCAN;
+ }
+
+ return count;
+}
+
+static DEVICE_ATTR(speed_scan, S_IWUSR | S_IRUGO, show_speed_scan,
+ store_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;
+ 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;
+ if (buf[0] == '1')
+ priv->config |= CFG_NET_STATS;
+ else
+ priv->config &= ~CFG_NET_STATS;
+
+ return count;
+}
+
+static DEVICE_ATTR(net_stats, S_IWUSR | S_IRUGO,
+ show_net_stats, store_net_stats);
+
+static void notify_wx_assoc_event(struct ipw_priv *priv)
+{
+ union iwreq_data wrqu;
+ wrqu.ap_addr.sa_family = ARPHRD_ETHER;
+ if (priv->status & STATUS_ASSOCIATED)
+ memcpy(wrqu.ap_addr.sa_data, priv->bssid, ETH_ALEN);
+ else
+ memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN);
+ wireless_send_event(priv->net_dev, SIOCGIWAP, &wrqu, NULL);
+}
+
static void ipw_irq_tasklet(struct ipw_priv *priv)
{
u32 inta, inta_mask, handled = 0;
@@ -995,102 +1670,135 @@ static void ipw_irq_tasklet(struct ipw_priv *priv)
spin_lock_irqsave(&priv->lock, flags);
- inta = ipw_read32(priv, CX2_INTA_RW);
- inta_mask = ipw_read32(priv, CX2_INTA_MASK_R);
- inta &= (CX2_INTA_MASK_ALL & inta_mask);
+ inta = ipw_read32(priv, IPW_INTA_RW);
+ inta_mask = ipw_read32(priv, IPW_INTA_MASK_R);
+ inta &= (IPW_INTA_MASK_ALL & inta_mask);
/* Add any cached INTA values that need to be handled */
inta |= priv->isr_inta;
/* handle all the justifications for the interrupt */
- if (inta & CX2_INTA_BIT_RX_TRANSFER) {
+ if (inta & IPW_INTA_BIT_RX_TRANSFER) {
ipw_rx(priv);
- handled |= CX2_INTA_BIT_RX_TRANSFER;
+ handled |= IPW_INTA_BIT_RX_TRANSFER;
}
- if (inta & CX2_INTA_BIT_TX_CMD_QUEUE) {
+ if (inta & IPW_INTA_BIT_TX_CMD_QUEUE) {
IPW_DEBUG_HC("Command completed.\n");
rc = ipw_queue_tx_reclaim(priv, &priv->txq_cmd, -1);
priv->status &= ~STATUS_HCMD_ACTIVE;
wake_up_interruptible(&priv->wait_command_queue);
- handled |= CX2_INTA_BIT_TX_CMD_QUEUE;
+ handled |= IPW_INTA_BIT_TX_CMD_QUEUE;
}
- if (inta & CX2_INTA_BIT_TX_QUEUE_1) {
+ if (inta & IPW_INTA_BIT_TX_QUEUE_1) {
IPW_DEBUG_TX("TX_QUEUE_1\n");
rc = ipw_queue_tx_reclaim(priv, &priv->txq[0], 0);
- handled |= CX2_INTA_BIT_TX_QUEUE_1;
+ handled |= IPW_INTA_BIT_TX_QUEUE_1;
}
- if (inta & CX2_INTA_BIT_TX_QUEUE_2) {
+ if (inta & IPW_INTA_BIT_TX_QUEUE_2) {
IPW_DEBUG_TX("TX_QUEUE_2\n");
rc = ipw_queue_tx_reclaim(priv, &priv->txq[1], 1);
- handled |= CX2_INTA_BIT_TX_QUEUE_2;
+ handled |= IPW_INTA_BIT_TX_QUEUE_2;
}
- if (inta & CX2_INTA_BIT_TX_QUEUE_3) {
+ if (inta & IPW_INTA_BIT_TX_QUEUE_3) {
IPW_DEBUG_TX("TX_QUEUE_3\n");
rc = ipw_queue_tx_reclaim(priv, &priv->txq[2], 2);
- handled |= CX2_INTA_BIT_TX_QUEUE_3;
+ handled |= IPW_INTA_BIT_TX_QUEUE_3;
}
- if (inta & CX2_INTA_BIT_TX_QUEUE_4) {
+ if (inta & IPW_INTA_BIT_TX_QUEUE_4) {
IPW_DEBUG_TX("TX_QUEUE_4\n");
rc = ipw_queue_tx_reclaim(priv, &priv->txq[3], 3);
- handled |= CX2_INTA_BIT_TX_QUEUE_4;
+ handled |= IPW_INTA_BIT_TX_QUEUE_4;
}
- if (inta & CX2_INTA_BIT_STATUS_CHANGE) {
+ if (inta & IPW_INTA_BIT_STATUS_CHANGE) {
IPW_WARNING("STATUS_CHANGE\n");
- handled |= CX2_INTA_BIT_STATUS_CHANGE;
+ handled |= IPW_INTA_BIT_STATUS_CHANGE;
}
- if (inta & CX2_INTA_BIT_BEACON_PERIOD_EXPIRED) {
+ if (inta & IPW_INTA_BIT_BEACON_PERIOD_EXPIRED) {
IPW_WARNING("TX_PERIOD_EXPIRED\n");
- handled |= CX2_INTA_BIT_BEACON_PERIOD_EXPIRED;
+ handled |= IPW_INTA_BIT_BEACON_PERIOD_EXPIRED;
}
- if (inta & CX2_INTA_BIT_SLAVE_MODE_HOST_CMD_DONE) {
+ if (inta & IPW_INTA_BIT_SLAVE_MODE_HOST_CMD_DONE) {
IPW_WARNING("HOST_CMD_DONE\n");
- handled |= CX2_INTA_BIT_SLAVE_MODE_HOST_CMD_DONE;
+ handled |= IPW_INTA_BIT_SLAVE_MODE_HOST_CMD_DONE;
}
- if (inta & CX2_INTA_BIT_FW_INITIALIZATION_DONE) {
+ if (inta & IPW_INTA_BIT_FW_INITIALIZATION_DONE) {
IPW_WARNING("FW_INITIALIZATION_DONE\n");
- handled |= CX2_INTA_BIT_FW_INITIALIZATION_DONE;
+ handled |= IPW_INTA_BIT_FW_INITIALIZATION_DONE;
}
- if (inta & CX2_INTA_BIT_FW_CARD_DISABLE_PHY_OFF_DONE) {
+ if (inta & IPW_INTA_BIT_FW_CARD_DISABLE_PHY_OFF_DONE) {
IPW_WARNING("PHY_OFF_DONE\n");
- handled |= CX2_INTA_BIT_FW_CARD_DISABLE_PHY_OFF_DONE;
+ handled |= IPW_INTA_BIT_FW_CARD_DISABLE_PHY_OFF_DONE;
}
- if (inta & CX2_INTA_BIT_RF_KILL_DONE) {
+ if (inta & IPW_INTA_BIT_RF_KILL_DONE) {
IPW_DEBUG_RF_KILL("RF_KILL_DONE\n");
priv->status |= STATUS_RF_KILL_HW;
wake_up_interruptible(&priv->wait_command_queue);
- netif_carrier_off(priv->net_dev);
- netif_stop_queue(priv->net_dev);
+ priv->status &= ~(STATUS_ASSOCIATED | STATUS_ASSOCIATING);
cancel_delayed_work(&priv->request_scan);
+ schedule_work(&priv->link_down);
queue_delayed_work(priv->workqueue, &priv->rf_kill, 2 * HZ);
- handled |= CX2_INTA_BIT_RF_KILL_DONE;
+ handled |= IPW_INTA_BIT_RF_KILL_DONE;
}
- if (inta & CX2_INTA_BIT_FATAL_ERROR) {
+ if (inta & IPW_INTA_BIT_FATAL_ERROR) {
IPW_ERROR("Firmware error detected. Restarting.\n");
+ if (priv->error) {
+ IPW_ERROR("Sysfs 'error' log already exists.\n");
#ifdef CONFIG_IPW_DEBUG
- if (ipw_debug_level & IPW_DL_FW_ERRORS) {
- ipw_dump_nic_error_log(priv);
- ipw_dump_nic_event_log(priv);
- }
+ if (ipw_debug_level & IPW_DL_FW_ERRORS) {
+ struct ipw_fw_error *error =
+ ipw_alloc_error_log(priv);
+ ipw_dump_error_log(priv, error);
+ if (error)
+ ipw_free_error_log(error);
+ }
#endif
+ } else {
+ priv->error = ipw_alloc_error_log(priv);
+ if (priv->error)
+ IPW_ERROR("Sysfs 'error' log captured.\n");
+ else
+ IPW_ERROR("Error allocating sysfs 'error' "
+ "log.\n");
+#ifdef CONFIG_IPW_DEBUG
+ if (ipw_debug_level & IPW_DL_FW_ERRORS)
+ ipw_dump_error_log(priv, priv->error);
+#endif
+ }
+
+ /* XXX: If hardware encryption is for WPA/WPA2,
+ * we have to notify the supplicant. */
+ if (priv->ieee->sec.encrypt) {
+ priv->status &= ~STATUS_ASSOCIATED;
+ notify_wx_assoc_event(priv);
+ }
+
+ /* Keep the restart process from trying to send host
+ * commands by clearing the INIT status bit */
+ priv->status &= ~STATUS_INIT;
+
+ /* Cancel currently queued command. */
+ priv->status &= ~STATUS_HCMD_ACTIVE;
+ wake_up_interruptible(&priv->wait_command_queue);
+
queue_work(priv->workqueue, &priv->adapter_restart);
- handled |= CX2_INTA_BIT_FATAL_ERROR;
+ handled |= IPW_INTA_BIT_FATAL_ERROR;
}
- if (inta & CX2_INTA_BIT_PARITY_ERROR) {
+ if (inta & IPW_INTA_BIT_PARITY_ERROR) {
IPW_ERROR("Parity error\n");
- handled |= CX2_INTA_BIT_PARITY_ERROR;
+ handled |= IPW_INTA_BIT_PARITY_ERROR;
}
if (handled != inta) {
@@ -1103,7 +1811,6 @@ static void ipw_irq_tasklet(struct ipw_priv *priv)
spin_unlock_irqrestore(&priv->lock, flags);
}
-#ifdef CONFIG_IPW_DEBUG
#define IPW_CMD(x) case IPW_CMD_ ## x : return #x
static char *get_cmd_string(u8 cmd)
{
@@ -1162,44 +1869,78 @@ static char *get_cmd_string(u8 cmd)
return "UNKNOWN";
}
}
-#endif /* CONFIG_IPW_DEBUG */
#define HOST_COMPLETE_TIMEOUT HZ
static int ipw_send_cmd(struct ipw_priv *priv, struct host_cmd *cmd)
{
int rc = 0;
+ unsigned long flags;
+ spin_lock_irqsave(&priv->lock, flags);
if (priv->status & STATUS_HCMD_ACTIVE) {
- IPW_ERROR("Already sending a command\n");
- return -1;
+ IPW_ERROR("Failed to send %s: Already sending a command.\n",
+ get_cmd_string(cmd->cmd));
+ spin_unlock_irqrestore(&priv->lock, flags);
+ return -EAGAIN;
}
priv->status |= STATUS_HCMD_ACTIVE;
- IPW_DEBUG_HC("Sending %s command (#%d), %d bytes\n",
- get_cmd_string(cmd->cmd), cmd->cmd, cmd->len);
+ if (priv->cmdlog) {
+ priv->cmdlog[priv->cmdlog_pos].jiffies = jiffies;
+ priv->cmdlog[priv->cmdlog_pos].cmd.cmd = cmd->cmd;
+ priv->cmdlog[priv->cmdlog_pos].cmd.len = cmd->len;
+ memcpy(priv->cmdlog[priv->cmdlog_pos].cmd.param, cmd->param,
+ cmd->len);
+ priv->cmdlog[priv->cmdlog_pos].retcode = -1;
+ }
+
+ IPW_DEBUG_HC("%s command (#%d) %d bytes: 0x%08X\n",
+ get_cmd_string(cmd->cmd), cmd->cmd, cmd->len,
+ priv->status);
printk_buf(IPW_DL_HOST_COMMAND, (u8 *) cmd->param, cmd->len);
rc = ipw_queue_tx_hcmd(priv, cmd->cmd, &cmd->param, cmd->len, 0);
- if (rc)
- return rc;
+ if (rc) {
+ priv->status &= ~STATUS_HCMD_ACTIVE;
+ IPW_ERROR("Failed to send %s: Reason %d\n",
+ get_cmd_string(cmd->cmd), rc);
+ spin_unlock_irqrestore(&priv->lock, flags);
+ goto exit;
+ }
+ spin_unlock_irqrestore(&priv->lock, flags);
rc = wait_event_interruptible_timeout(priv->wait_command_queue,
!(priv->
status & STATUS_HCMD_ACTIVE),
HOST_COMPLETE_TIMEOUT);
if (rc == 0) {
- IPW_DEBUG_INFO("Command completion failed out after %dms.\n",
- jiffies_to_msecs(HOST_COMPLETE_TIMEOUT));
- priv->status &= ~STATUS_HCMD_ACTIVE;
- return -EIO;
- }
- if (priv->status & STATUS_RF_KILL_MASK) {
- IPW_DEBUG_INFO("Command aborted due to RF Kill Switch\n");
- return -EIO;
+ spin_lock_irqsave(&priv->lock, flags);
+ if (priv->status & STATUS_HCMD_ACTIVE) {
+ IPW_ERROR("Failed to send %s: Command timed out.\n",
+ get_cmd_string(cmd->cmd));
+ priv->status &= ~STATUS_HCMD_ACTIVE;
+ spin_unlock_irqrestore(&priv->lock, flags);
+ rc = -EIO;
+ goto exit;
+ }
+ spin_unlock_irqrestore(&priv->lock, flags);
+ } else
+ rc = 0;
+
+ if (priv->status & STATUS_RF_KILL_HW) {
+ IPW_ERROR("Failed to send %s: Aborted due to RF kill switch.\n",
+ get_cmd_string(cmd->cmd));
+ rc = -EIO;
+ goto exit;
}
- return 0;
+ exit:
+ if (priv->cmdlog) {
+ priv->cmdlog[priv->cmdlog_pos++].retcode = rc;
+ priv->cmdlog_pos %= priv->cmdlog_len;
+ }
+ return rc;
}
static int ipw_send_host_complete(struct ipw_priv *priv)
@@ -1214,12 +1955,7 @@ static int ipw_send_host_complete(struct ipw_priv *priv)
return -1;
}
- if (ipw_send_cmd(priv, &cmd)) {
- IPW_ERROR("failed to send HOST_COMPLETE command\n");
- return -1;
- }
-
- return 0;
+ return ipw_send_cmd(priv, &cmd);
}
static int ipw_send_system_config(struct ipw_priv *priv,
@@ -1235,13 +1971,8 @@ static int ipw_send_system_config(struct ipw_priv *priv,
return -1;
}
- memcpy(&cmd.param, config, sizeof(*config));
- if (ipw_send_cmd(priv, &cmd)) {
- IPW_ERROR("failed to send SYSTEM_CONFIG command\n");
- return -1;
- }
-
- return 0;
+ memcpy(cmd.param, config, sizeof(*config));
+ return ipw_send_cmd(priv, &cmd);
}
static int ipw_send_ssid(struct ipw_priv *priv, u8 * ssid, int len)
@@ -1256,13 +1987,8 @@ static int ipw_send_ssid(struct ipw_priv *priv, u8 * ssid, int len)
return -1;
}
- memcpy(&cmd.param, ssid, cmd.len);
- if (ipw_send_cmd(priv, &cmd)) {
- IPW_ERROR("failed to send SSID command\n");
- return -1;
- }
-
- return 0;
+ memcpy(cmd.param, ssid, cmd.len);
+ return ipw_send_cmd(priv, &cmd);
}
static int ipw_send_adapter_address(struct ipw_priv *priv, u8 * mac)
@@ -1280,16 +2006,15 @@ static int ipw_send_adapter_address(struct ipw_priv *priv, u8 * mac)
IPW_DEBUG_INFO("%s: Setting MAC to " MAC_FMT "\n",
priv->net_dev->name, MAC_ARG(mac));
- memcpy(&cmd.param, mac, ETH_ALEN);
-
- if (ipw_send_cmd(priv, &cmd)) {
- IPW_ERROR("failed to send ADAPTER_ADDRESS command\n");
- return -1;
- }
-
- return 0;
+ memcpy(cmd.param, mac, ETH_ALEN);
+ return ipw_send_cmd(priv, &cmd);
}
+/*
+ * NOTE: This must be executed from our workqueue as it results in udelay
+ * being called which may corrupt the keyboard if executed on default
+ * workqueue
+ */
static void ipw_adapter_restart(void *adapter)
{
struct ipw_priv *priv = adapter;
@@ -1298,12 +2023,25 @@ static void ipw_adapter_restart(void *adapter)
return;
ipw_down(priv);
+
+ if (priv->assoc_network &&
+ (priv->assoc_network->capability & WLAN_CAPABILITY_IBSS))
+ ipw_remove_current_network(priv);
+
if (ipw_up(priv)) {
IPW_ERROR("Failed to up device\n");
return;
}
}
+static void ipw_bg_adapter_restart(void *data)
+{
+ struct ipw_priv *priv = data;
+ down(&priv->sem);
+ ipw_adapter_restart(data);
+ up(&priv->sem);
+}
+
#define IPW_SCAN_CHECK_WATCHDOG (5 * HZ)
static void ipw_scan_check(void *data)
@@ -1313,10 +2051,18 @@ static void ipw_scan_check(void *data)
IPW_DEBUG_SCAN("Scan completion watchdog resetting "
"adapter (%dms).\n",
IPW_SCAN_CHECK_WATCHDOG / 100);
- ipw_adapter_restart(priv);
+ queue_work(priv->workqueue, &priv->adapter_restart);
}
}
+static void ipw_bg_scan_check(void *data)
+{
+ struct ipw_priv *priv = data;
+ down(&priv->sem);
+ ipw_scan_check(data);
+ up(&priv->sem);
+}
+
static int ipw_send_scan_request_ext(struct ipw_priv *priv,
struct ipw_scan_request_ext *request)
{
@@ -1325,20 +2071,8 @@ static int ipw_send_scan_request_ext(struct ipw_priv *priv,
.len = sizeof(*request)
};
- if (!priv || !request) {
- IPW_ERROR("Invalid args\n");
- return -1;
- }
-
- memcpy(&cmd.param, request, sizeof(*request));
- if (ipw_send_cmd(priv, &cmd)) {
- IPW_ERROR("failed to send SCAN_REQUEST_EXT command\n");
- return -1;
- }
-
- queue_delayed_work(priv->workqueue, &priv->scan_check,
- IPW_SCAN_CHECK_WATCHDOG);
- return 0;
+ memcpy(cmd.param, request, sizeof(*request));
+ return ipw_send_cmd(priv, &cmd);
}
static int ipw_send_scan_abort(struct ipw_priv *priv)
@@ -1353,12 +2087,7 @@ static int ipw_send_scan_abort(struct ipw_priv *priv)
return -1;
}
- if (ipw_send_cmd(priv, &cmd)) {
- IPW_ERROR("failed to send SCAN_ABORT command\n");
- return -1;
- }
-
- return 0;
+ return ipw_send_cmd(priv, &cmd);
}
static int ipw_set_sensitivity(struct ipw_priv *priv, u16 sens)
@@ -1370,12 +2099,7 @@ static int ipw_set_sensitivity(struct ipw_priv *priv, u16 sens)
struct ipw_sensitivity_calib *calib = (struct ipw_sensitivity_calib *)
&cmd.param;
calib->beacon_rssi_raw = sens;
- if (ipw_send_cmd(priv, &cmd)) {
- IPW_ERROR("failed to send SENSITIVITY CALIB command\n");
- return -1;
- }
-
- return 0;
+ return ipw_send_cmd(priv, &cmd);
}
static int ipw_send_associate(struct ipw_priv *priv,
@@ -1386,18 +2110,26 @@ static int ipw_send_associate(struct ipw_priv *priv,
.len = sizeof(*associate)
};
+ struct ipw_associate tmp_associate;
+ memcpy(&tmp_associate, associate, sizeof(*associate));
+ tmp_associate.policy_support =
+ cpu_to_le16(tmp_associate.policy_support);
+ tmp_associate.assoc_tsf_msw = cpu_to_le32(tmp_associate.assoc_tsf_msw);
+ tmp_associate.assoc_tsf_lsw = cpu_to_le32(tmp_associate.assoc_tsf_lsw);
+ tmp_associate.capability = cpu_to_le16(tmp_associate.capability);
+ tmp_associate.listen_interval =
+ cpu_to_le16(tmp_associate.listen_interval);
+ tmp_associate.beacon_interval =
+ cpu_to_le16(tmp_associate.beacon_interval);
+ tmp_associate.atim_window = cpu_to_le16(tmp_associate.atim_window);
+
if (!priv || !associate) {
IPW_ERROR("Invalid args\n");
return -1;
}
- memcpy(&cmd.param, associate, sizeof(*associate));
- if (ipw_send_cmd(priv, &cmd)) {
- IPW_ERROR("failed to send ASSOCIATE command\n");
- return -1;
- }
-
- return 0;
+ memcpy(cmd.param, &tmp_associate, sizeof(*associate));
+ return ipw_send_cmd(priv, &cmd);
}
static int ipw_send_supported_rates(struct ipw_priv *priv,
@@ -1413,13 +2145,8 @@ static int ipw_send_supported_rates(struct ipw_priv *priv,
return -1;
}
- memcpy(&cmd.param, rates, sizeof(*rates));
- if (ipw_send_cmd(priv, &cmd)) {
- IPW_ERROR("failed to send SUPPORTED_RATES command\n");
- return -1;
- }
-
- return 0;
+ memcpy(cmd.param, rates, sizeof(*rates));
+ return ipw_send_cmd(priv, &cmd);
}
static int ipw_set_random_seed(struct ipw_priv *priv)
@@ -1436,15 +2163,9 @@ static int ipw_set_random_seed(struct ipw_priv *priv)
get_random_bytes(&cmd.param, sizeof(u32));
- if (ipw_send_cmd(priv, &cmd)) {
- IPW_ERROR("failed to send SEED_NUMBER command\n");
- return -1;
- }
-
- return 0;
+ return ipw_send_cmd(priv, &cmd);
}
-#if 0
static int ipw_send_card_disable(struct ipw_priv *priv, u32 phy_off)
{
struct host_cmd cmd = {
@@ -1459,14 +2180,8 @@ static int ipw_send_card_disable(struct ipw_priv *priv, u32 phy_off)
*((u32 *) & cmd.param) = phy_off;
- if (ipw_send_cmd(priv, &cmd)) {
- IPW_ERROR("failed to send CARD_DISABLE command\n");
- return -1;
- }
-
- return 0;
+ return ipw_send_cmd(priv, &cmd);
}
-#endif
static int ipw_send_tx_power(struct ipw_priv *priv, struct ipw_tx_power *power)
{
@@ -1480,12 +2195,51 @@ static int ipw_send_tx_power(struct ipw_priv *priv, struct ipw_tx_power *power)
return -1;
}
- memcpy(&cmd.param, power, sizeof(*power));
- if (ipw_send_cmd(priv, &cmd)) {
- IPW_ERROR("failed to send TX_POWER command\n");
- return -1;
+ memcpy(cmd.param, power, sizeof(*power));
+ return ipw_send_cmd(priv, &cmd);
+}
+
+static int ipw_set_tx_power(struct ipw_priv *priv)
+{
+ const struct ieee80211_geo *geo = ipw_get_geo(priv->ieee);
+ struct ipw_tx_power tx_power;
+ s8 max_power;
+ int i;
+
+ memset(&tx_power, 0, sizeof(tx_power));
+
+ /* configure device for 'G' band */
+ tx_power.ieee_mode = IPW_G_MODE;
+ tx_power.num_channels = geo->bg_channels;
+ for (i = 0; i < geo->bg_channels; i++) {
+ max_power = geo->bg[i].max_power;
+ tx_power.channels_tx_power[i].channel_number =
+ geo->bg[i].channel;
+ tx_power.channels_tx_power[i].tx_power = max_power ?
+ min(max_power, priv->tx_power) : priv->tx_power;
}
+ if (ipw_send_tx_power(priv, &tx_power))
+ return -EIO;
+ /* configure device to also handle 'B' band */
+ tx_power.ieee_mode = IPW_B_MODE;
+ if (ipw_send_tx_power(priv, &tx_power))
+ return -EIO;
+
+ /* configure device to also handle 'A' band */
+ if (priv->ieee->abg_true) {
+ tx_power.ieee_mode = IPW_A_MODE;
+ tx_power.num_channels = geo->a_channels;
+ for (i = 0; i < tx_power.num_channels; i++) {
+ max_power = geo->a[i].max_power;
+ tx_power.channels_tx_power[i].channel_number =
+ geo->a[i].channel;
+ tx_power.channels_tx_power[i].tx_power = max_power ?
+ min(max_power, priv->tx_power) : priv->tx_power;
+ }
+ if (ipw_send_tx_power(priv, &tx_power))
+ return -EIO;
+ }
return 0;
}
@@ -1504,13 +2258,8 @@ static int ipw_send_rts_threshold(struct ipw_priv *priv, u16 rts)
return -1;
}
- memcpy(&cmd.param, &rts_threshold, sizeof(rts_threshold));
- if (ipw_send_cmd(priv, &cmd)) {
- IPW_ERROR("failed to send RTS_THRESHOLD command\n");
- return -1;
- }
-
- return 0;
+ memcpy(cmd.param, &rts_threshold, sizeof(rts_threshold));
+ return ipw_send_cmd(priv, &cmd);
}
static int ipw_send_frag_threshold(struct ipw_priv *priv, u16 frag)
@@ -1528,13 +2277,8 @@ static int ipw_send_frag_threshold(struct ipw_priv *priv, u16 frag)
return -1;
}
- memcpy(&cmd.param, &frag_threshold, sizeof(frag_threshold));
- if (ipw_send_cmd(priv, &cmd)) {
- IPW_ERROR("failed to send FRAG_THRESHOLD command\n");
- return -1;
- }
-
- return 0;
+ memcpy(cmd.param, &frag_threshold, sizeof(frag_threshold));
+ return ipw_send_cmd(priv, &cmd);
}
static int ipw_send_power_mode(struct ipw_priv *priv, u32 mode)
@@ -1564,12 +2308,27 @@ static int ipw_send_power_mode(struct ipw_priv *priv, u32 mode)
break;
}
- if (ipw_send_cmd(priv, &cmd)) {
- IPW_ERROR("failed to send POWER_MODE command\n");
+ return ipw_send_cmd(priv, &cmd);
+}
+
+static int ipw_send_retry_limit(struct ipw_priv *priv, u8 slimit, u8 llimit)
+{
+ struct ipw_retry_limit retry_limit = {
+ .short_retry_limit = slimit,
+ .long_retry_limit = llimit
+ };
+ struct host_cmd cmd = {
+ .cmd = IPW_CMD_RETRY_LIMIT,
+ .len = sizeof(retry_limit)
+ };
+
+ if (!priv) {
+ IPW_ERROR("Invalid args\n");
return -1;
}
- return 0;
+ memcpy(cmd.param, &retry_limit, sizeof(retry_limit));
+ return ipw_send_cmd(priv, &cmd);
}
/*
@@ -1671,8 +2430,7 @@ static u16 eeprom_read_u16(struct ipw_priv *priv, u8 addr)
/* data's copy of the eeprom data */
static void eeprom_parse_mac(struct ipw_priv *priv, u8 * mac)
{
- u8 *ee = (u8 *) priv->eeprom;
- memcpy(mac, &ee[EEPROM_MAC_ADDRESS], 6);
+ memcpy(mac, &priv->eeprom[EEPROM_MAC_ADDRESS], 6);
}
/*
@@ -1692,7 +2450,7 @@ static void ipw_eeprom_init_sram(struct ipw_priv *priv)
/* read entire contents of eeprom into private buffer */
for (i = 0; i < 128; i++)
- eeprom[i] = eeprom_read_u16(priv, (u8) i);
+ eeprom[i] = le16_to_cpu(eeprom_read_u16(priv, (u8) i));
/*
If the data looks correct, then copy it to our private
@@ -1703,7 +2461,7 @@ static void ipw_eeprom_init_sram(struct ipw_priv *priv)
IPW_DEBUG_INFO("Writing EEPROM data into SRAM\n");
/* write the eeprom data to sram */
- for (i = 0; i < CX2_EEPROM_IMAGE_SIZE; i++)
+ for (i = 0; i < IPW_EEPROM_IMAGE_SIZE; i++)
ipw_write8(priv, IPW_EEPROM_DATA + i, priv->eeprom[i]);
/* Do not load eeprom data on fatal error or suspend */
@@ -1723,14 +2481,14 @@ static inline void ipw_zero_memory(struct ipw_priv *priv, u32 start, u32 count)
count >>= 2;
if (!count)
return;
- _ipw_write32(priv, CX2_AUTOINC_ADDR, start);
+ _ipw_write32(priv, IPW_AUTOINC_ADDR, start);
while (count--)
- _ipw_write32(priv, CX2_AUTOINC_DATA, 0);
+ _ipw_write32(priv, IPW_AUTOINC_DATA, 0);
}
static inline void ipw_fw_dma_reset_command_blocks(struct ipw_priv *priv)
{
- ipw_zero_memory(priv, CX2_SHARED_SRAM_DMA_CONTROL,
+ ipw_zero_memory(priv, IPW_SHARED_SRAM_DMA_CONTROL,
CB_NUMBER_OF_ELEMENTS_SMALL *
sizeof(struct command_block));
}
@@ -1744,7 +2502,7 @@ static int ipw_fw_dma_enable(struct ipw_priv *priv)
ipw_fw_dma_reset_command_blocks(priv);
/* Write CB base address */
- ipw_write_reg32(priv, CX2_DMA_I_CB_BASE, CX2_SHARED_SRAM_DMA_CONTROL);
+ ipw_write_reg32(priv, IPW_DMA_I_CB_BASE, IPW_SHARED_SRAM_DMA_CONTROL);
IPW_DEBUG_FW("<< : \n");
return 0;
@@ -1758,7 +2516,7 @@ static void ipw_fw_dma_abort(struct ipw_priv *priv)
//set the Stop and Abort bit
control = DMA_CONTROL_SMALL_CB_CONST_VALUE | DMA_CB_STOP_AND_ABORT;
- ipw_write_reg32(priv, CX2_DMA_I_DMA_CONTROL, control);
+ ipw_write_reg32(priv, IPW_DMA_I_DMA_CONTROL, control);
priv->sram_desc.last_cb_index = 0;
IPW_DEBUG_FW("<< \n");
@@ -1768,7 +2526,7 @@ static int ipw_fw_dma_write_command_block(struct ipw_priv *priv, int index,
struct command_block *cb)
{
u32 address =
- CX2_SHARED_SRAM_DMA_CONTROL +
+ IPW_SHARED_SRAM_DMA_CONTROL +
(sizeof(struct command_block) * index);
IPW_DEBUG_FW(">> :\n");
@@ -1792,13 +2550,13 @@ static int ipw_fw_dma_kick(struct ipw_priv *priv)
&priv->sram_desc.cb_list[index]);
/* Enable the DMA in the CSR register */
- ipw_clear_bit(priv, CX2_RESET_REG,
- CX2_RESET_REG_MASTER_DISABLED |
- CX2_RESET_REG_STOP_MASTER);
+ ipw_clear_bit(priv, IPW_RESET_REG,
+ IPW_RESET_REG_MASTER_DISABLED |
+ IPW_RESET_REG_STOP_MASTER);
/* Set the Start bit. */
control = DMA_CONTROL_SMALL_CB_CONST_VALUE | DMA_CB_START;
- ipw_write_reg32(priv, CX2_DMA_I_DMA_CONTROL, control);
+ ipw_write_reg32(priv, IPW_DMA_I_DMA_CONTROL, control);
IPW_DEBUG_FW("<< :\n");
return 0;
@@ -1811,12 +2569,12 @@ static void ipw_fw_dma_dump_command_block(struct ipw_priv *priv)
u32 cb_fields_address = 0;
IPW_DEBUG_FW(">> :\n");
- address = ipw_read_reg32(priv, CX2_DMA_I_CURRENT_CB);
+ address = ipw_read_reg32(priv, IPW_DMA_I_CURRENT_CB);
IPW_DEBUG_FW_INFO("Current CB is 0x%x \n", address);
/* Read the DMA Controlor register */
- register_value = ipw_read_reg32(priv, CX2_DMA_I_DMA_CONTROL);
- IPW_DEBUG_FW_INFO("CX2_DMA_I_DMA_CONTROL is 0x%x \n", register_value);
+ register_value = ipw_read_reg32(priv, IPW_DMA_I_DMA_CONTROL);
+ IPW_DEBUG_FW_INFO("IPW_DMA_I_DMA_CONTROL is 0x%x \n", register_value);
/* Print the CB values */
cb_fields_address = address;
@@ -1845,9 +2603,9 @@ static int ipw_fw_dma_command_block_index(struct ipw_priv *priv)
u32 current_cb_index = 0;
IPW_DEBUG_FW("<< :\n");
- current_cb_address = ipw_read_reg32(priv, CX2_DMA_I_CURRENT_CB);
+ current_cb_address = ipw_read_reg32(priv, IPW_DMA_I_CURRENT_CB);
- current_cb_index = (current_cb_address - CX2_SHARED_SRAM_DMA_CONTROL) /
+ current_cb_index = (current_cb_address - IPW_SHARED_SRAM_DMA_CONTROL) /
sizeof(struct command_block);
IPW_DEBUG_FW_INFO("Current CB index 0x%x address = 0x%X \n",
@@ -1976,8 +2734,8 @@ static int ipw_fw_dma_wait(struct ipw_priv *priv)
ipw_fw_dma_abort(priv);
/*Disable the DMA in the CSR register */
- ipw_set_bit(priv, CX2_RESET_REG,
- CX2_RESET_REG_MASTER_DISABLED | CX2_RESET_REG_STOP_MASTER);
+ ipw_set_bit(priv, IPW_RESET_REG,
+ IPW_RESET_REG_MASTER_DISABLED | IPW_RESET_REG_STOP_MASTER);
IPW_DEBUG_FW("<< dmaWaitSync \n");
return 0;
@@ -1987,6 +2745,9 @@ static void ipw_remove_current_network(struct ipw_priv *priv)
{
struct list_head *element, *safe;
struct ieee80211_network *network = NULL;
+ unsigned long flags;
+
+ spin_lock_irqsave(&priv->ieee->lock, flags);
list_for_each_safe(element, safe, &priv->ieee->network_list) {
network = list_entry(element, struct ieee80211_network, list);
if (!memcmp(network->bssid, priv->bssid, ETH_ALEN)) {
@@ -1995,6 +2756,7 @@ static void ipw_remove_current_network(struct ipw_priv *priv)
&priv->ieee->network_free_list);
}
}
+ spin_unlock_irqrestore(&priv->ieee->lock, flags);
}
/**
@@ -2037,10 +2799,10 @@ static int ipw_stop_master(struct ipw_priv *priv)
IPW_DEBUG_TRACE(">> \n");
/* stop master. typical delay - 0 */
- ipw_set_bit(priv, CX2_RESET_REG, CX2_RESET_REG_STOP_MASTER);
+ ipw_set_bit(priv, IPW_RESET_REG, IPW_RESET_REG_STOP_MASTER);
- rc = ipw_poll_bit(priv, CX2_RESET_REG,
- CX2_RESET_REG_MASTER_DISABLED, 100);
+ rc = ipw_poll_bit(priv, IPW_RESET_REG,
+ IPW_RESET_REG_MASTER_DISABLED, 100);
if (rc < 0) {
IPW_ERROR("stop master failed in 10ms\n");
return -1;
@@ -2056,7 +2818,7 @@ static void ipw_arc_release(struct ipw_priv *priv)
IPW_DEBUG_TRACE(">> \n");
mdelay(5);
- ipw_clear_bit(priv, CX2_RESET_REG, CBD_RESET_REG_PRINCETON_RESET);
+ ipw_clear_bit(priv, IPW_RESET_REG, CBD_RESET_REG_PRINCETON_RESET);
/* no one knows timing, for safety add some delay */
mdelay(5);
@@ -2073,13 +2835,12 @@ struct fw_chunk {
};
#define IPW_FW_MAJOR_VERSION 2
-#define IPW_FW_MINOR_VERSION 2
+#define IPW_FW_MINOR_VERSION 4
#define IPW_FW_MINOR(x) ((x & 0xff) >> 8)
#define IPW_FW_MAJOR(x) (x & 0xff)
-#define IPW_FW_VERSION ((IPW_FW_MINOR_VERSION << 8) | \
- IPW_FW_MAJOR_VERSION)
+#define IPW_FW_VERSION ((IPW_FW_MINOR_VERSION << 8) | IPW_FW_MAJOR_VERSION)
#define IPW_FW_PREFIX "ipw-" __stringify(IPW_FW_MAJOR_VERSION) \
"." __stringify(IPW_FW_MINOR_VERSION) "-"
@@ -2107,8 +2868,8 @@ static int ipw_load_ucode(struct ipw_priv *priv, u8 * data, size_t len)
// spin_lock_irqsave(&priv->lock, flags);
- for (addr = CX2_SHARED_LOWER_BOUND;
- addr < CX2_REGISTER_DOMAIN1_END; addr += 4) {
+ for (addr = IPW_SHARED_LOWER_BOUND;
+ addr < IPW_REGISTER_DOMAIN1_END; addr += 4) {
ipw_write32(priv, addr, 0);
}
@@ -2117,16 +2878,16 @@ static int ipw_load_ucode(struct ipw_priv *priv, u8 * data, size_t len)
/* destroy DMA queues */
/* reset sequence */
- ipw_write_reg32(priv, CX2_MEM_HALT_AND_RESET, CX2_BIT_HALT_RESET_ON);
+ ipw_write_reg32(priv, IPW_MEM_HALT_AND_RESET, IPW_BIT_HALT_RESET_ON);
ipw_arc_release(priv);
- ipw_write_reg32(priv, CX2_MEM_HALT_AND_RESET, CX2_BIT_HALT_RESET_OFF);
+ ipw_write_reg32(priv, IPW_MEM_HALT_AND_RESET, IPW_BIT_HALT_RESET_OFF);
mdelay(1);
/* reset PHY */
- ipw_write_reg32(priv, CX2_INTERNAL_CMD_EVENT, CX2_BASEBAND_POWER_DOWN);
+ ipw_write_reg32(priv, IPW_INTERNAL_CMD_EVENT, IPW_BASEBAND_POWER_DOWN);
mdelay(1);
- ipw_write_reg32(priv, CX2_INTERNAL_CMD_EVENT, 0);
+ ipw_write_reg32(priv, IPW_INTERNAL_CMD_EVENT, 0);
mdelay(1);
/* enable ucode store */
@@ -2144,18 +2905,19 @@ static int ipw_load_ucode(struct ipw_priv *priv, u8 * data, size_t len)
*/
/* load new ipw uCode */
for (i = 0; i < len / 2; i++)
- ipw_write_reg16(priv, CX2_BASEBAND_CONTROL_STORE, image[i]);
+ ipw_write_reg16(priv, IPW_BASEBAND_CONTROL_STORE,
+ cpu_to_le16(image[i]));
/* enable DINO */
- ipw_write_reg8(priv, CX2_BASEBAND_CONTROL_STATUS, 0);
- ipw_write_reg8(priv, CX2_BASEBAND_CONTROL_STATUS, DINO_ENABLE_SYSTEM);
+ ipw_write_reg8(priv, IPW_BASEBAND_CONTROL_STATUS, 0);
+ ipw_write_reg8(priv, IPW_BASEBAND_CONTROL_STATUS, DINO_ENABLE_SYSTEM);
/* this is where the igx / win driver deveates from the VAP driver. */
/* wait for alive response */
for (i = 0; i < 100; i++) {
/* poll for incoming data */
- cr = ipw_read_reg8(priv, CX2_BASEBAND_CONTROL_STATUS);
+ cr = ipw_read_reg8(priv, IPW_BASEBAND_CONTROL_STATUS);
if (cr & DINO_RXFIFO_DATA)
break;
mdelay(1);
@@ -2167,7 +2929,8 @@ static int ipw_load_ucode(struct ipw_priv *priv, u8 * data, size_t len)
for (i = 0; i < ARRAY_SIZE(response_buffer); i++)
response_buffer[i] =
- ipw_read_reg32(priv, CX2_BASEBAND_RX_FIFO_READ);
+ le32_to_cpu(ipw_read_reg32(priv,
+ IPW_BASEBAND_RX_FIFO_READ));
memcpy(&priv->dino_alive, response_buffer,
sizeof(priv->dino_alive));
if (priv->dino_alive.alive_command == 1
@@ -2196,7 +2959,7 @@ static int ipw_load_ucode(struct ipw_priv *priv, u8 * data, size_t len)
/* disable DINO, otherwise for some reason
firmware have problem getting alive resp. */
- ipw_write_reg8(priv, CX2_BASEBAND_CONTROL_STATUS, 0);
+ ipw_write_reg8(priv, IPW_BASEBAND_CONTROL_STATUS, 0);
// spin_unlock_irqrestore(&priv->lock, flags);
@@ -2236,13 +2999,14 @@ static int ipw_load_firmware(struct ipw_priv *priv, u8 * data, size_t len)
* offeset*/
/* Dma loading */
rc = ipw_fw_dma_add_buffer(priv, shared_phys + offset,
- chunk->address, chunk->length);
+ le32_to_cpu(chunk->address),
+ le32_to_cpu(chunk->length));
if (rc) {
IPW_DEBUG_INFO("dmaAddBuffer Failed\n");
goto out;
}
- offset += chunk->length;
+ offset += le32_to_cpu(chunk->length);
} while (offset < len);
/* Run the DMA and wait for the answer */
@@ -2268,16 +3032,16 @@ static int ipw_stop_nic(struct ipw_priv *priv)
int rc = 0;
/* stop */
- ipw_write32(priv, CX2_RESET_REG, CX2_RESET_REG_STOP_MASTER);
+ ipw_write32(priv, IPW_RESET_REG, IPW_RESET_REG_STOP_MASTER);
- rc = ipw_poll_bit(priv, CX2_RESET_REG,
- CX2_RESET_REG_MASTER_DISABLED, 500);
+ rc = ipw_poll_bit(priv, IPW_RESET_REG,
+ IPW_RESET_REG_MASTER_DISABLED, 500);
if (rc < 0) {
IPW_ERROR("wait for reg master disabled failed\n");
return rc;
}
- ipw_set_bit(priv, CX2_RESET_REG, CBD_RESET_REG_PRINCETON_RESET);
+ ipw_set_bit(priv, IPW_RESET_REG, CBD_RESET_REG_PRINCETON_RESET);
return rc;
}
@@ -2287,14 +3051,14 @@ static void ipw_start_nic(struct ipw_priv *priv)
IPW_DEBUG_TRACE(">>\n");
/* prvHwStartNic release ARC */
- ipw_clear_bit(priv, CX2_RESET_REG,
- CX2_RESET_REG_MASTER_DISABLED |
- CX2_RESET_REG_STOP_MASTER |
+ ipw_clear_bit(priv, IPW_RESET_REG,
+ IPW_RESET_REG_MASTER_DISABLED |
+ IPW_RESET_REG_STOP_MASTER |
CBD_RESET_REG_PRINCETON_RESET);
/* enable power management */
- ipw_set_bit(priv, CX2_GP_CNTRL_RW,
- CX2_GP_CNTRL_BIT_HOST_ALLOWS_STANDBY);
+ ipw_set_bit(priv, IPW_GP_CNTRL_RW,
+ IPW_GP_CNTRL_BIT_HOST_ALLOWS_STANDBY);
IPW_DEBUG_TRACE("<<\n");
}
@@ -2307,25 +3071,25 @@ static int ipw_init_nic(struct ipw_priv *priv)
/* reset */
/*prvHwInitNic */
/* set "initialization complete" bit to move adapter to D0 state */
- ipw_set_bit(priv, CX2_GP_CNTRL_RW, CX2_GP_CNTRL_BIT_INIT_DONE);
+ ipw_set_bit(priv, IPW_GP_CNTRL_RW, IPW_GP_CNTRL_BIT_INIT_DONE);
/* low-level PLL activation */
- ipw_write32(priv, CX2_READ_INT_REGISTER,
- CX2_BIT_INT_HOST_SRAM_READ_INT_REGISTER);
+ ipw_write32(priv, IPW_READ_INT_REGISTER,
+ IPW_BIT_INT_HOST_SRAM_READ_INT_REGISTER);
/* wait for clock stabilization */
- rc = ipw_poll_bit(priv, CX2_GP_CNTRL_RW,
- CX2_GP_CNTRL_BIT_CLOCK_READY, 250);
+ rc = ipw_poll_bit(priv, IPW_GP_CNTRL_RW,
+ IPW_GP_CNTRL_BIT_CLOCK_READY, 250);
if (rc < 0)
IPW_DEBUG_INFO("FAILED wait for clock stablization\n");
/* assert SW reset */
- ipw_set_bit(priv, CX2_RESET_REG, CX2_RESET_REG_SW_RESET);
+ ipw_set_bit(priv, IPW_RESET_REG, IPW_RESET_REG_SW_RESET);
udelay(10);
/* set "initialization complete" bit to move adapter to D0 state */
- ipw_set_bit(priv, CX2_GP_CNTRL_RW, CX2_GP_CNTRL_BIT_INIT_DONE);
+ ipw_set_bit(priv, IPW_GP_CNTRL_RW, IPW_GP_CNTRL_BIT_INIT_DONE);
IPW_DEBUG_TRACE(">>\n");
return 0;
@@ -2337,14 +3101,19 @@ static int ipw_init_nic(struct ipw_priv *priv)
static int ipw_reset_nic(struct ipw_priv *priv)
{
int rc = 0;
+ unsigned long flags;
IPW_DEBUG_TRACE(">>\n");
rc = ipw_init_nic(priv);
+ spin_lock_irqsave(&priv->lock, flags);
/* Clear the 'host command active' bit... */
priv->status &= ~STATUS_HCMD_ACTIVE;
wake_up_interruptible(&priv->wait_command_queue);
+ priv->status &= ~(STATUS_SCANNING | STATUS_SCAN_ABORTING);
+ wake_up_interruptible(&priv->wait_state);
+ spin_unlock_irqrestore(&priv->lock, flags);
IPW_DEBUG_TRACE("<<\n");
return rc;
@@ -2364,22 +3133,23 @@ static int ipw_get_fw(struct ipw_priv *priv,
}
header = (struct fw_header *)(*fw)->data;
- if (IPW_FW_MAJOR(header->version) != IPW_FW_MAJOR_VERSION) {
+ if (IPW_FW_MAJOR(le32_to_cpu(header->version)) != IPW_FW_MAJOR_VERSION) {
IPW_ERROR("'%s' firmware version not compatible (%d != %d)\n",
name,
- IPW_FW_MAJOR(header->version), IPW_FW_MAJOR_VERSION);
+ IPW_FW_MAJOR(le32_to_cpu(header->version)),
+ IPW_FW_MAJOR_VERSION);
return -EINVAL;
}
IPW_DEBUG_INFO("Loading firmware '%s' file v%d.%d (%zd bytes)\n",
name,
- IPW_FW_MAJOR(header->version),
- IPW_FW_MINOR(header->version),
+ IPW_FW_MAJOR(le32_to_cpu(header->version)),
+ IPW_FW_MINOR(le32_to_cpu(header->version)),
(*fw)->size - sizeof(struct fw_header));
return 0;
}
-#define CX2_RX_BUF_SIZE (3000)
+#define IPW_RX_BUF_SIZE (3000)
static inline void ipw_rx_queue_reset(struct ipw_priv *priv,
struct ipw_rx_queue *rxq)
@@ -2398,8 +3168,9 @@ static inline void ipw_rx_queue_reset(struct ipw_priv *priv,
* to an SKB, so we need to unmap and free potential storage */
if (rxq->pool[i].skb != NULL) {
pci_unmap_single(priv->pci_dev, rxq->pool[i].dma_addr,
- CX2_RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
+ IPW_RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
dev_kfree_skb(rxq->pool[i].skb);
+ rxq->pool[i].skb = NULL;
}
list_add_tail(&rxq->pool[i].list, &rxq->rx_used);
}
@@ -2417,6 +3188,19 @@ static int fw_loaded = 0;
static const struct firmware *bootfw = NULL;
static const struct firmware *firmware = NULL;
static const struct firmware *ucode = NULL;
+
+static void free_firmware(void)
+{
+ if (fw_loaded) {
+ release_firmware(bootfw);
+ release_firmware(ucode);
+ release_firmware(firmware);
+ bootfw = ucode = firmware = NULL;
+ fw_loaded = 0;
+ }
+}
+#else
+#define free_firmware() do {} while (0)
#endif
static int ipw_load(struct ipw_priv *priv)
@@ -2445,10 +3229,10 @@ static int ipw_load(struct ipw_priv *priv)
rc = ipw_get_fw(priv, &firmware, IPW_FW_NAME("ibss"));
break;
-#ifdef CONFIG_IPW_PROMISC
+#ifdef CONFIG_IPW2200_MONITOR
case IW_MODE_MONITOR:
rc = ipw_get_fw(priv, &ucode,
- IPW_FW_NAME("ibss_ucode"));
+ IPW_FW_NAME("sniffer_ucode"));
if (rc)
goto error;
@@ -2487,11 +3271,11 @@ static int ipw_load(struct ipw_priv *priv)
retry:
/* Ensure interrupts are disabled */
- ipw_write32(priv, CX2_INTA_MASK_R, ~CX2_INTA_MASK_ALL);
+ ipw_write32(priv, IPW_INTA_MASK_R, ~IPW_INTA_MASK_ALL);
priv->status &= ~STATUS_INT_ENABLED;
/* ack pending interrupts */
- ipw_write32(priv, CX2_INTA_RW, CX2_INTA_MASK_ALL);
+ ipw_write32(priv, IPW_INTA_RW, IPW_INTA_MASK_ALL);
ipw_stop_nic(priv);
@@ -2501,14 +3285,14 @@ static int ipw_load(struct ipw_priv *priv)
goto error;
}
- ipw_zero_memory(priv, CX2_NIC_SRAM_LOWER_BOUND,
- CX2_NIC_SRAM_UPPER_BOUND - CX2_NIC_SRAM_LOWER_BOUND);
+ ipw_zero_memory(priv, IPW_NIC_SRAM_LOWER_BOUND,
+ IPW_NIC_SRAM_UPPER_BOUND - IPW_NIC_SRAM_LOWER_BOUND);
/* DMA the initial boot firmware into the device */
rc = ipw_load_firmware(priv, bootfw->data + sizeof(struct fw_header),
bootfw->size - sizeof(struct fw_header));
if (rc < 0) {
- IPW_ERROR("Unable to load boot firmware\n");
+ IPW_ERROR("Unable to load boot firmware: %d\n", rc);
goto error;
}
@@ -2516,8 +3300,8 @@ static int ipw_load(struct ipw_priv *priv)
ipw_start_nic(priv);
/* wait for the device to finish it's initial startup sequence */
- rc = ipw_poll_bit(priv, CX2_INTA_RW,
- CX2_INTA_BIT_FW_INITIALIZATION_DONE, 500);
+ rc = ipw_poll_bit(priv, IPW_INTA_RW,
+ IPW_INTA_BIT_FW_INITIALIZATION_DONE, 500);
if (rc < 0) {
IPW_ERROR("device failed to boot initial fw image\n");
goto error;
@@ -2525,13 +3309,13 @@ static int ipw_load(struct ipw_priv *priv)
IPW_DEBUG_INFO("initial device response after %dms\n", rc);
/* ack fw init done interrupt */
- ipw_write32(priv, CX2_INTA_RW, CX2_INTA_BIT_FW_INITIALIZATION_DONE);
+ ipw_write32(priv, IPW_INTA_RW, IPW_INTA_BIT_FW_INITIALIZATION_DONE);
/* DMA the ucode into the device */
rc = ipw_load_ucode(priv, ucode->data + sizeof(struct fw_header),
ucode->size - sizeof(struct fw_header));
if (rc < 0) {
- IPW_ERROR("Unable to load ucode\n");
+ IPW_ERROR("Unable to load ucode: %d\n", rc);
goto error;
}
@@ -2543,7 +3327,7 @@ static int ipw_load(struct ipw_priv *priv)
sizeof(struct fw_header),
firmware->size - sizeof(struct fw_header));
if (rc < 0) {
- IPW_ERROR("Unable to load firmware\n");
+ IPW_ERROR("Unable to load firmware: %d\n", rc);
goto error;
}
@@ -2556,12 +3340,14 @@ static int ipw_load(struct ipw_priv *priv)
}
/* Ensure interrupts are disabled */
- ipw_write32(priv, CX2_INTA_MASK_R, ~CX2_INTA_MASK_ALL);
+ ipw_write32(priv, IPW_INTA_MASK_R, ~IPW_INTA_MASK_ALL);
+ /* ack pending interrupts */
+ ipw_write32(priv, IPW_INTA_RW, IPW_INTA_MASK_ALL);
/* kick start the device */
ipw_start_nic(priv);
- if (ipw_read32(priv, CX2_INTA_RW) & CX2_INTA_BIT_PARITY_ERROR) {
+ if (ipw_read32(priv, IPW_INTA_RW) & IPW_INTA_BIT_PARITY_ERROR) {
if (retries > 0) {
IPW_WARNING("Parity error. Retrying init.\n");
retries--;
@@ -2574,8 +3360,8 @@ static int ipw_load(struct ipw_priv *priv)
}
/* wait for the device */
- rc = ipw_poll_bit(priv, CX2_INTA_RW,
- CX2_INTA_BIT_FW_INITIALIZATION_DONE, 500);
+ rc = ipw_poll_bit(priv, IPW_INTA_RW,
+ IPW_INTA_BIT_FW_INITIALIZATION_DONE, 500);
if (rc < 0) {
IPW_ERROR("device failed to start after 500ms\n");
goto error;
@@ -2583,7 +3369,7 @@ static int ipw_load(struct ipw_priv *priv)
IPW_DEBUG_INFO("device response after %dms\n", rc);
/* ack fw init done interrupt */
- ipw_write32(priv, CX2_INTA_RW, CX2_INTA_BIT_FW_INITIALIZATION_DONE);
+ ipw_write32(priv, IPW_INTA_RW, IPW_INTA_BIT_FW_INITIALIZATION_DONE);
/* read eeprom data and initialize the eeprom region of sram */
priv->eeprom_delay = 1;
@@ -2595,10 +3381,10 @@ static int ipw_load(struct ipw_priv *priv)
/* Ensure our queue has valid packets */
ipw_rx_queue_replenish(priv);
- ipw_write32(priv, CX2_RX_READ_INDEX, priv->rxq->read);
+ ipw_write32(priv, IPW_RX_READ_INDEX, priv->rxq->read);
/* ack pending interrupts */
- ipw_write32(priv, CX2_INTA_RW, CX2_INTA_MASK_ALL);
+ ipw_write32(priv, IPW_INTA_RW, IPW_INTA_MASK_ALL);
#ifndef CONFIG_PM
release_firmware(bootfw);
@@ -2755,16 +3541,18 @@ static void ipw_queue_tx_free_tfd(struct ipw_priv *priv,
return;
/* sanity check */
- if (bd->u.data.num_chunks > NUM_TFD_CHUNKS) {
- IPW_ERROR("Too many chunks: %i\n", bd->u.data.num_chunks);
+ if (le32_to_cpu(bd->u.data.num_chunks) > NUM_TFD_CHUNKS) {
+ IPW_ERROR("Too many chunks: %i\n",
+ le32_to_cpu(bd->u.data.num_chunks));
/** @todo issue fatal error, it is quite serious situation */
return;
}
/* unmap chunks if any */
- for (i = 0; i < bd->u.data.num_chunks; i++) {
- pci_unmap_single(dev, bd->u.data.chunk_ptr[i],
- bd->u.data.chunk_len[i], PCI_DMA_TODEVICE);
+ for (i = 0; i < le32_to_cpu(bd->u.data.num_chunks); i++) {
+ pci_unmap_single(dev, le32_to_cpu(bd->u.data.chunk_ptr[i]),
+ le16_to_cpu(bd->u.data.chunk_len[i]),
+ PCI_DMA_TODEVICE);
if (txq->txb[txq->q.last_used]) {
ieee80211_txb_free(txq->txb[txq->q.last_used]);
txq->txb[txq->q.last_used] = NULL;
@@ -2821,21 +3609,6 @@ static void ipw_tx_queue_free(struct ipw_priv *priv)
ipw_queue_tx_free(priv, &priv->txq[3]);
}
-static void inline __maybe_wake_tx(struct ipw_priv *priv)
-{
- if (netif_running(priv->net_dev)) {
- switch (priv->port_type) {
- case DCR_TYPE_MU_BSS:
- case DCR_TYPE_MU_IBSS:
- if (!(priv->status & STATUS_ASSOCIATED)) {
- return;
- }
- }
- netif_wake_queue(priv->net_dev);
- }
-
-}
-
static inline void ipw_create_bssid(struct ipw_priv *priv, u8 * bssid)
{
/* First 3 bytes are manufacturer */
@@ -2898,7 +3671,13 @@ static void ipw_send_disassociate(struct ipw_priv *priv, int quiet)
{
int err;
- if (!(priv->status & (STATUS_ASSOCIATING | STATUS_ASSOCIATED))) {
+ if (priv->status & STATUS_ASSOCIATING) {
+ IPW_DEBUG_ASSOC("Disassociating while associating.\n");
+ queue_work(priv->workqueue, &priv->disassociate);
+ return;
+ }
+
+ if (!(priv->status & STATUS_ASSOCIATED)) {
IPW_DEBUG_ASSOC("Disassociating while not associated.\n");
return;
}
@@ -2915,6 +3694,7 @@ static void ipw_send_disassociate(struct ipw_priv *priv, int quiet)
priv->assoc_request.assoc_type = HC_DISASSOC_QUIET;
else
priv->assoc_request.assoc_type = HC_DISASSOCIATE;
+
err = ipw_send_associate(priv, &priv->assoc_request);
if (err) {
IPW_DEBUG_HC("Attempt to send [dis]associate command "
@@ -2924,20 +3704,27 @@ static void ipw_send_disassociate(struct ipw_priv *priv, int quiet)
}
-static void ipw_disassociate(void *data)
+static int ipw_disassociate(void *data)
{
+ struct ipw_priv *priv = data;
+ if (!(priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)))
+ return 0;
ipw_send_disassociate(data, 0);
+ return 1;
}
-static void notify_wx_assoc_event(struct ipw_priv *priv)
+static void ipw_bg_disassociate(void *data)
{
- union iwreq_data wrqu;
- wrqu.ap_addr.sa_family = ARPHRD_ETHER;
- if (priv->status & STATUS_ASSOCIATED)
- memcpy(wrqu.ap_addr.sa_data, priv->bssid, ETH_ALEN);
- else
- memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN);
- wireless_send_event(priv->net_dev, SIOCGIWAP, &wrqu, NULL);
+ struct ipw_priv *priv = data;
+ down(&priv->sem);
+ ipw_disassociate(data);
+ up(&priv->sem);
+}
+
+static void ipw_system_config(void *data)
+{
+ struct ipw_priv *priv = data;
+ ipw_send_system_config(priv, &priv->sys_config);
}
struct ipw_status_code {
@@ -2997,7 +3784,7 @@ static const char *ipw_get_status_code(u16 status)
{
int i;
for (i = 0; i < ARRAY_SIZE(ipw_status_codes); i++)
- if (ipw_status_codes[i].status == status)
+ if (ipw_status_codes[i].status == (status & 0xff))
return ipw_status_codes[i].reason;
return "Unknown status value.";
}
@@ -3076,18 +3863,30 @@ static inline u32 ipw_get_max_rate(struct ipw_priv *priv)
while (i && !(mask & i))
i >>= 1;
switch (i) {
- case IEEE80211_CCK_RATE_1MB_MASK: return 1000000;
- case IEEE80211_CCK_RATE_2MB_MASK: return 2000000;
- case IEEE80211_CCK_RATE_5MB_MASK: return 5500000;
- case IEEE80211_OFDM_RATE_6MB_MASK: return 6000000;
- case IEEE80211_OFDM_RATE_9MB_MASK: return 9000000;
- case IEEE80211_CCK_RATE_11MB_MASK: return 11000000;
- case IEEE80211_OFDM_RATE_12MB_MASK: return 12000000;
- case IEEE80211_OFDM_RATE_18MB_MASK: return 18000000;
- case IEEE80211_OFDM_RATE_24MB_MASK: return 24000000;
- case IEEE80211_OFDM_RATE_36MB_MASK: return 36000000;
- case IEEE80211_OFDM_RATE_48MB_MASK: return 48000000;
- case IEEE80211_OFDM_RATE_54MB_MASK: return 54000000;
+ case IEEE80211_CCK_RATE_1MB_MASK:
+ return 1000000;
+ case IEEE80211_CCK_RATE_2MB_MASK:
+ return 2000000;
+ case IEEE80211_CCK_RATE_5MB_MASK:
+ return 5500000;
+ case IEEE80211_OFDM_RATE_6MB_MASK:
+ return 6000000;
+ case IEEE80211_OFDM_RATE_9MB_MASK:
+ return 9000000;
+ case IEEE80211_CCK_RATE_11MB_MASK:
+ return 11000000;
+ case IEEE80211_OFDM_RATE_12MB_MASK:
+ return 12000000;
+ case IEEE80211_OFDM_RATE_18MB_MASK:
+ return 18000000;
+ case IEEE80211_OFDM_RATE_24MB_MASK:
+ return 24000000;
+ case IEEE80211_OFDM_RATE_36MB_MASK:
+ return 36000000;
+ case IEEE80211_OFDM_RATE_48MB_MASK:
+ return 48000000;
+ case IEEE80211_OFDM_RATE_54MB_MASK:
+ return 54000000;
}
if (priv->ieee->mode == IEEE_B)
@@ -3115,25 +3914,35 @@ static u32 ipw_get_current_rate(struct ipw_priv *priv)
return ipw_get_max_rate(priv);
switch (rate) {
- case IPW_TX_RATE_1MB: return 1000000;
- case IPW_TX_RATE_2MB: return 2000000;
- case IPW_TX_RATE_5MB: return 5500000;
- case IPW_TX_RATE_6MB: return 6000000;
- case IPW_TX_RATE_9MB: return 9000000;
- case IPW_TX_RATE_11MB: return 11000000;
- case IPW_TX_RATE_12MB: return 12000000;
- case IPW_TX_RATE_18MB: return 18000000;
- case IPW_TX_RATE_24MB: return 24000000;
- case IPW_TX_RATE_36MB: return 36000000;
- case IPW_TX_RATE_48MB: return 48000000;
- case IPW_TX_RATE_54MB: return 54000000;
+ case IPW_TX_RATE_1MB:
+ return 1000000;
+ case IPW_TX_RATE_2MB:
+ return 2000000;
+ case IPW_TX_RATE_5MB:
+ return 5500000;
+ case IPW_TX_RATE_6MB:
+ return 6000000;
+ case IPW_TX_RATE_9MB:
+ return 9000000;
+ case IPW_TX_RATE_11MB:
+ return 11000000;
+ case IPW_TX_RATE_12MB:
+ return 12000000;
+ case IPW_TX_RATE_18MB:
+ return 18000000;
+ case IPW_TX_RATE_24MB:
+ return 24000000;
+ case IPW_TX_RATE_36MB:
+ return 36000000;
+ case IPW_TX_RATE_48MB:
+ return 48000000;
+ case IPW_TX_RATE_54MB:
+ return 54000000;
}
return 0;
}
-#define PERFECT_RSSI (-50)
-#define WORST_RSSI (-85)
#define IPW_STATS_INTERVAL (2 * HZ)
static void ipw_gather_stats(struct ipw_priv *priv)
{
@@ -3145,6 +3954,7 @@ static void ipw_gather_stats(struct ipw_priv *priv)
s16 rssi;
u32 beacon_quality, signal_quality, tx_quality, rx_quality,
rate_quality;
+ u32 max_rate;
if (!(priv->status & STATUS_ASSOCIATED)) {
priv->quality = 0;
@@ -3201,7 +4011,8 @@ static void ipw_gather_stats(struct ipw_priv *priv)
beacon_quality, missed_beacons_percent);
priv->last_rate = ipw_get_current_rate(priv);
- rate_quality = priv->last_rate * 40 / priv->last_rate + 60;
+ max_rate = ipw_get_max_rate(priv);
+ rate_quality = priv->last_rate * 40 / max_rate + 60;
IPW_DEBUG_STATS("Rate quality : %3d%% (%dMbs)\n",
rate_quality, priv->last_rate / 1000000);
@@ -3222,13 +4033,20 @@ static void ipw_gather_stats(struct ipw_priv *priv)
tx_quality, tx_failures_delta, tx_packets_delta);
rssi = average_value(&priv->average_rssi);
- if (rssi > PERFECT_RSSI)
+ signal_quality =
+ (100 *
+ (priv->ieee->perfect_rssi - priv->ieee->worst_rssi) *
+ (priv->ieee->perfect_rssi - priv->ieee->worst_rssi) -
+ (priv->ieee->perfect_rssi - rssi) *
+ (15 * (priv->ieee->perfect_rssi - priv->ieee->worst_rssi) +
+ 62 * (priv->ieee->perfect_rssi - rssi))) /
+ ((priv->ieee->perfect_rssi - priv->ieee->worst_rssi) *
+ (priv->ieee->perfect_rssi - priv->ieee->worst_rssi));
+ if (signal_quality > 100)
signal_quality = 100;
- else if (rssi < WORST_RSSI)
+ else if (signal_quality < 1)
signal_quality = 0;
- else
- signal_quality = (rssi - WORST_RSSI) * 100 /
- (PERFECT_RSSI - WORST_RSSI);
+
IPW_DEBUG_STATS("Signal level : %3d%% (%d dBm)\n",
signal_quality, rssi);
@@ -3257,6 +4075,85 @@ static void ipw_gather_stats(struct ipw_priv *priv)
IPW_STATS_INTERVAL);
}
+static void ipw_bg_gather_stats(void *data)
+{
+ struct ipw_priv *priv = data;
+ down(&priv->sem);
+ ipw_gather_stats(data);
+ up(&priv->sem);
+}
+
+/* Missed beacon behavior:
+ * 1st missed -> roaming_threshold, just wait, don't do any scan/roam.
+ * roaming_threshold -> disassociate_threshold, scan and roam for better signal.
+ * Above disassociate threshold, give up and stop scanning.
+ * Roaming is disabled if disassociate_threshold <= roaming_threshold */
+static inline void ipw_handle_missed_beacon(struct ipw_priv *priv,
+ int missed_count)
+{
+ priv->notif_missed_beacons = missed_count;
+
+ if (missed_count > priv->disassociate_threshold &&
+ priv->status & STATUS_ASSOCIATED) {
+ /* If associated and we've hit the missed
+ * beacon threshold, disassociate, turn
+ * off roaming, and abort any active scans */
+ IPW_DEBUG(IPW_DL_INFO | IPW_DL_NOTIF |
+ IPW_DL_STATE | IPW_DL_ASSOC,
+ "Missed beacon: %d - disassociate\n", missed_count);
+ priv->status &= ~STATUS_ROAMING;
+ if (priv->status & STATUS_SCANNING) {
+ IPW_DEBUG(IPW_DL_INFO | IPW_DL_NOTIF |
+ IPW_DL_STATE,
+ "Aborting scan with missed beacon.\n");
+ queue_work(priv->workqueue, &priv->abort_scan);
+ }
+
+ queue_work(priv->workqueue, &priv->disassociate);
+ return;
+ }
+
+ if (priv->status & STATUS_ROAMING) {
+ /* If we are currently roaming, then just
+ * print a debug statement... */
+ IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE,
+ "Missed beacon: %d - roam in progress\n",
+ missed_count);
+ return;
+ }
+
+ if (missed_count > priv->roaming_threshold &&
+ missed_count <= priv->disassociate_threshold) {
+ /* If we are not already roaming, set the ROAM
+ * bit in the status and kick off a scan.
+ * This can happen several times before we reach
+ * disassociate_threshold. */
+ IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE,
+ "Missed beacon: %d - initiate "
+ "roaming\n", missed_count);
+ if (!(priv->status & STATUS_ROAMING)) {
+ priv->status |= STATUS_ROAMING;
+ if (!(priv->status & STATUS_SCANNING))
+ queue_work(priv->workqueue,
+ &priv->request_scan);
+ }
+ return;
+ }
+
+ if (priv->status & STATUS_SCANNING) {
+ /* Stop scan to keep fw from getting
+ * stuck (only if we aren't roaming --
+ * otherwise we'll never scan more than 2 or 3
+ * channels..) */
+ IPW_DEBUG(IPW_DL_INFO | IPW_DL_NOTIF | IPW_DL_STATE,
+ "Aborting scan with missed beacon.\n");
+ queue_work(priv->workqueue, &priv->abort_scan);
+ }
+
+ IPW_DEBUG_NOTIF("Missed beacon: %d\n", missed_count);
+
+}
+
/**
* Handle host notification packet.
* Called from interrupt routine
@@ -3264,6 +4161,8 @@ static void ipw_gather_stats(struct ipw_priv *priv)
static inline void ipw_rx_notification(struct ipw_priv *priv,
struct ipw_rx_notification *notif)
{
+ notif->size = le16_to_cpu(notif->size);
+
IPW_DEBUG_NOTIF("type = %i (%d bytes)\n", notif->subtype, notif->size);
switch (notif->subtype) {
@@ -3307,30 +4206,44 @@ static inline void ipw_rx_notification(struct ipw_priv *priv,
priv->status &= ~STATUS_ASSOCIATING;
priv->status |= STATUS_ASSOCIATED;
-
- netif_carrier_on(priv->net_dev);
- if (netif_queue_stopped(priv->net_dev)) {
- IPW_DEBUG_NOTIF
- ("waking queue\n");
- netif_wake_queue(priv->net_dev);
- } else {
- IPW_DEBUG_NOTIF
- ("starting queue\n");
- netif_start_queue(priv->
- net_dev);
+ queue_work(priv->workqueue,
+ &priv->system_config);
+
+#ifdef CONFIG_IPW_QOS
+#define IPW_GET_PACKET_STYPE(x) WLAN_FC_GET_STYPE( \
+ le16_to_cpu(((struct ieee80211_hdr *)(x))->frame_ctl))
+ if ((priv->status & STATUS_AUTH) &&
+ (IPW_GET_PACKET_STYPE(&notif->u.raw)
+ == IEEE80211_STYPE_ASSOC_RESP)) {
+ if ((sizeof
+ (struct
+ ieee80211_assoc_response)
+ <= notif->size)
+ && (notif->size <= 2314)) {
+ struct
+ ieee80211_rx_stats
+ stats = {
+ .len =
+ notif->
+ size - 1,
+ };
+
+ IPW_DEBUG_QOS
+ ("QoS Associate "
+ "size %d\n",
+ notif->size);
+ ieee80211_rx_mgt(priv->
+ ieee,
+ (struct
+ ieee80211_hdr_4addr
+ *)
+ &notif->u.raw, &stats);
+ }
}
+#endif
- ipw_reset_stats(priv);
- /* Ensure the rate is updated immediately */
- priv->last_rate =
- ipw_get_current_rate(priv);
- schedule_work(&priv->gather_stats);
- notify_wx_assoc_event(priv);
+ schedule_work(&priv->link_up);
-/* queue_delayed_work(priv->workqueue,
- &priv->request_scan,
- SCAN_ASSOCIATED_INTERVAL);
-*/
break;
}
@@ -3363,12 +4276,7 @@ static inline void ipw_rx_notification(struct ipw_priv *priv,
STATUS_AUTH |
STATUS_ASSOCIATED);
- netif_carrier_off(priv->
- net_dev);
- netif_stop_queue(priv->net_dev);
- queue_work(priv->workqueue,
- &priv->request_scan);
- notify_wx_assoc_event(priv);
+ schedule_work(&priv->link_down);
break;
}
@@ -3383,6 +4291,24 @@ static inline void ipw_rx_notification(struct ipw_priv *priv,
}
case CMAS_INIT:{
+ if (priv->status & STATUS_AUTH) {
+ struct
+ ieee80211_assoc_response
+ *resp;
+ resp =
+ (struct
+ ieee80211_assoc_response
+ *)&notif->u.raw;
+ IPW_DEBUG(IPW_DL_NOTIF |
+ IPW_DL_STATE |
+ IPW_DL_ASSOC,
+ "association failed (0x%04X): %s\n",
+ ntohs(resp->status),
+ ipw_get_status_code
+ (ntohs
+ (resp->status)));
+ }
+
IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
IPW_DL_ASSOC,
"disassociated: '%s' " MAC_FMT
@@ -3395,35 +4321,21 @@ static inline void ipw_rx_notification(struct ipw_priv *priv,
~(STATUS_DISASSOCIATING |
STATUS_ASSOCIATING |
STATUS_ASSOCIATED | STATUS_AUTH);
+ if (priv->assoc_network
+ && (priv->assoc_network->
+ capability &
+ WLAN_CAPABILITY_IBSS))
+ ipw_remove_current_network
+ (priv);
- netif_stop_queue(priv->net_dev);
- if (!(priv->status & STATUS_ROAMING)) {
- netif_carrier_off(priv->
- net_dev);
- notify_wx_assoc_event(priv);
-
- /* Cancel any queued work ... */
- cancel_delayed_work(&priv->
- request_scan);
- cancel_delayed_work(&priv->
- adhoc_check);
-
- /* Queue up another scan... */
- queue_work(priv->workqueue,
- &priv->request_scan);
-
- cancel_delayed_work(&priv->
- gather_stats);
- } else {
- priv->status |= STATUS_ROAMING;
- queue_work(priv->workqueue,
- &priv->request_scan);
- }
+ schedule_work(&priv->link_down);
- ipw_reset_stats(priv);
break;
}
+ case CMAS_RX_ASSOC_RESP:
+ break;
+
default:
IPW_ERROR("assoc: unknown (%d)\n",
assoc->state);
@@ -3466,11 +4378,7 @@ static inline void ipw_rx_notification(struct ipw_priv *priv,
STATUS_AUTH |
STATUS_ASSOCIATED);
- netif_carrier_off(priv->net_dev);
- netif_stop_queue(priv->net_dev);
- queue_work(priv->workqueue,
- &priv->request_scan);
- notify_wx_assoc_event(priv);
+ schedule_work(&priv->link_down);
break;
case CMAS_TX_AUTH_SEQ_1:
@@ -3512,6 +4420,7 @@ static inline void ipw_rx_notification(struct ipw_priv *priv,
case CMAS_RX_ASSOC_RESP:
IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
IPW_DL_ASSOC, "RX_ASSOC_RESP\n");
+
break;
case CMAS_ASSOCIATED:
IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
@@ -3556,43 +4465,67 @@ static inline void ipw_rx_notification(struct ipw_priv *priv,
priv->status &=
~(STATUS_SCANNING | STATUS_SCAN_ABORTING);
+ wake_up_interruptible(&priv->wait_state);
cancel_delayed_work(&priv->scan_check);
+ if (priv->status & STATUS_EXIT_PENDING)
+ break;
+
+ priv->ieee->scans++;
+
+#ifdef CONFIG_IPW2200_MONITOR
+ if (priv->ieee->iw_mode == IW_MODE_MONITOR) {
+ priv->status |= STATUS_SCAN_FORCED;
+ queue_work(priv->workqueue,
+ &priv->request_scan);
+ break;
+ }
+ priv->status &= ~STATUS_SCAN_FORCED;
+#endif /* CONFIG_IPW2200_MONITOR */
+
if (!(priv->status & (STATUS_ASSOCIATED |
STATUS_ASSOCIATING |
STATUS_ROAMING |
STATUS_DISASSOCIATING)))
queue_work(priv->workqueue, &priv->associate);
else if (priv->status & STATUS_ROAMING) {
- /* If a scan completed and we are in roam mode, then
- * the scan that completed was the one requested as a
- * result of entering roam... so, schedule the
- * roam work */
- queue_work(priv->workqueue, &priv->roam);
+ if (x->status == SCAN_COMPLETED_STATUS_COMPLETE)
+ /* If a scan completed and we are in roam mode, then
+ * the scan that completed was the one requested as a
+ * result of entering roam... so, schedule the
+ * roam work */
+ queue_work(priv->workqueue,
+ &priv->roam);
+ else
+ /* Don't schedule if we aborted the scan */
+ priv->status &= ~STATUS_ROAMING;
} else if (priv->status & STATUS_SCAN_PENDING)
queue_work(priv->workqueue,
&priv->request_scan);
-
- priv->ieee->scans++;
+ else if (priv->config & CFG_BACKGROUND_SCAN
+ && priv->status & STATUS_ASSOCIATED)
+ queue_delayed_work(priv->workqueue,
+ &priv->request_scan, HZ);
break;
}
case HOST_NOTIFICATION_STATUS_FRAG_LENGTH:{
struct notif_frag_length *x = &notif->u.frag_len;
- if (notif->size == sizeof(*x)) {
- IPW_ERROR("Frag length: %d\n", x->frag_length);
- } else {
+ if (notif->size == sizeof(*x))
+ IPW_ERROR("Frag length: %d\n",
+ le16_to_cpu(x->frag_length));
+ else
IPW_ERROR("Frag length of wrong size %d "
"(should be %zd)\n",
notif->size, sizeof(*x));
- }
break;
}
case HOST_NOTIFICATION_STATUS_LINK_DETERIORATION:{
struct notif_link_deterioration *x =
&notif->u.link_deterioration;
+
if (notif->size == sizeof(*x)) {
IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE,
"link deterioration: '%s' " MAC_FMT
@@ -3612,11 +4545,9 @@ static inline void ipw_rx_notification(struct ipw_priv *priv,
case HOST_NOTIFICATION_DINO_CONFIG_RESPONSE:{
IPW_ERROR("Dino config\n");
if (priv->hcmd
- && priv->hcmd->cmd == HOST_CMD_DINO_CONFIG) {
- /* TODO: Do anything special? */
- } else {
+ && priv->hcmd->cmd != HOST_CMD_DINO_CONFIG)
IPW_ERROR("Unexpected DINO_CONFIG_RESPONSE\n");
- }
+
break;
}
@@ -3629,36 +4560,11 @@ static inline void ipw_rx_notification(struct ipw_priv *priv,
break;
}
- if (x->state == HOST_NOTIFICATION_STATUS_BEACON_MISSING) {
- if (priv->status & STATUS_SCANNING) {
- /* Stop scan to keep fw from getting
- * stuck... */
- queue_work(priv->workqueue,
- &priv->abort_scan);
- }
-
- if (x->number > priv->missed_beacon_threshold &&
- priv->status & STATUS_ASSOCIATED) {
- IPW_DEBUG(IPW_DL_INFO | IPW_DL_NOTIF |
- IPW_DL_STATE,
- "Missed beacon: %d - disassociate\n",
- x->number);
- queue_work(priv->workqueue,
- &priv->disassociate);
- } else if (x->number > priv->roaming_threshold) {
- IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE,
- "Missed beacon: %d - initiate "
- "roaming\n", x->number);
- queue_work(priv->workqueue,
- &priv->roam);
- } else {
- IPW_DEBUG_NOTIF("Missed beacon: %d\n",
- x->number);
- }
-
- priv->notif_missed_beacons = x->number;
-
- }
+ if (le32_to_cpu(x->state) ==
+ HOST_NOTIFICATION_STATUS_BEACON_MISSING)
+ ipw_handle_missed_beacon(priv,
+ le32_to_cpu(x->
+ number));
break;
}
@@ -3697,7 +4603,8 @@ static inline void ipw_rx_notification(struct ipw_priv *priv,
case HOST_NOTIFICATION_NOISE_STATS:{
if (notif->size == sizeof(u32)) {
priv->last_noise =
- (u8) (notif->u.noise.value & 0xff);
+ (u8) (le32_to_cpu(notif->u.noise.value) &
+ 0xff);
average_add(&priv->average_noise,
priv->last_noise);
break;
@@ -3730,43 +4637,43 @@ static int ipw_queue_reset(struct ipw_priv *priv)
ipw_tx_queue_free(priv);
/* Tx CMD queue */
rc = ipw_queue_tx_init(priv, &priv->txq_cmd, nTxCmd,
- CX2_TX_CMD_QUEUE_READ_INDEX,
- CX2_TX_CMD_QUEUE_WRITE_INDEX,
- CX2_TX_CMD_QUEUE_BD_BASE,
- CX2_TX_CMD_QUEUE_BD_SIZE);
+ IPW_TX_CMD_QUEUE_READ_INDEX,
+ IPW_TX_CMD_QUEUE_WRITE_INDEX,
+ IPW_TX_CMD_QUEUE_BD_BASE,
+ IPW_TX_CMD_QUEUE_BD_SIZE);
if (rc) {
IPW_ERROR("Tx Cmd queue init failed\n");
goto error;
}
/* Tx queue(s) */
rc = ipw_queue_tx_init(priv, &priv->txq[0], nTx,
- CX2_TX_QUEUE_0_READ_INDEX,
- CX2_TX_QUEUE_0_WRITE_INDEX,
- CX2_TX_QUEUE_0_BD_BASE, CX2_TX_QUEUE_0_BD_SIZE);
+ IPW_TX_QUEUE_0_READ_INDEX,
+ IPW_TX_QUEUE_0_WRITE_INDEX,
+ IPW_TX_QUEUE_0_BD_BASE, IPW_TX_QUEUE_0_BD_SIZE);
if (rc) {
IPW_ERROR("Tx 0 queue init failed\n");
goto error;
}
rc = ipw_queue_tx_init(priv, &priv->txq[1], nTx,
- CX2_TX_QUEUE_1_READ_INDEX,
- CX2_TX_QUEUE_1_WRITE_INDEX,
- CX2_TX_QUEUE_1_BD_BASE, CX2_TX_QUEUE_1_BD_SIZE);
+ IPW_TX_QUEUE_1_READ_INDEX,
+ IPW_TX_QUEUE_1_WRITE_INDEX,
+ IPW_TX_QUEUE_1_BD_BASE, IPW_TX_QUEUE_1_BD_SIZE);
if (rc) {
IPW_ERROR("Tx 1 queue init failed\n");
goto error;
}
rc = ipw_queue_tx_init(priv, &priv->txq[2], nTx,
- CX2_TX_QUEUE_2_READ_INDEX,
- CX2_TX_QUEUE_2_WRITE_INDEX,
- CX2_TX_QUEUE_2_BD_BASE, CX2_TX_QUEUE_2_BD_SIZE);
+ IPW_TX_QUEUE_2_READ_INDEX,
+ IPW_TX_QUEUE_2_WRITE_INDEX,
+ IPW_TX_QUEUE_2_BD_BASE, IPW_TX_QUEUE_2_BD_SIZE);
if (rc) {
IPW_ERROR("Tx 2 queue init failed\n");
goto error;
}
rc = ipw_queue_tx_init(priv, &priv->txq[3], nTx,
- CX2_TX_QUEUE_3_READ_INDEX,
- CX2_TX_QUEUE_3_WRITE_INDEX,
- CX2_TX_QUEUE_3_BD_BASE, CX2_TX_QUEUE_3_BD_SIZE);
+ IPW_TX_QUEUE_3_READ_INDEX,
+ IPW_TX_QUEUE_3_WRITE_INDEX,
+ IPW_TX_QUEUE_3_BD_BASE, IPW_TX_QUEUE_3_BD_SIZE);
if (rc) {
IPW_ERROR("Tx 3 queue init failed\n");
goto error;
@@ -3814,9 +4721,10 @@ static int ipw_queue_tx_reclaim(struct ipw_priv *priv,
priv->tx_packets++;
}
done:
- if (ipw_queue_space(q) > q->low_mark && qindex >= 0) {
- __maybe_wake_tx(priv);
- }
+ if ((ipw_queue_space(q) > q->low_mark) &&
+ (qindex >= 0) &&
+ (priv->status & STATUS_ASSOCIATED) && netif_running(priv->net_dev))
+ netif_wake_queue(priv->net_dev);
used = q->first_empty - q->last_used;
if (used < 0)
used += q->n_bd;
@@ -3857,7 +4765,7 @@ static int ipw_queue_tx_hcmd(struct ipw_priv *priv, int hcmd, void *buf,
* Rx theory of operation
*
* The host allocates 32 DMA target addresses and passes the host address
- * to the firmware at register CX2_RFDS_TABLE_LOWER + N * RFD_SIZE where N is
+ * to the firmware at register IPW_RFDS_TABLE_LOWER + N * RFD_SIZE where N is
* 0 to 31
*
* Rx Queue Indexes
@@ -3941,7 +4849,7 @@ static void ipw_rx_queue_restock(struct ipw_priv *priv)
rxb = list_entry(element, struct ipw_rx_mem_buffer, list);
list_del(element);
- ipw_write32(priv, CX2_RFDS_TABLE_LOWER + rxq->write * RFD_SIZE,
+ ipw_write32(priv, IPW_RFDS_TABLE_LOWER + rxq->write * RFD_SIZE,
rxb->dma_addr);
rxq->queue[rxq->write] = rxb;
rxq->write = (rxq->write + 1) % RX_QUEUE_SIZE;
@@ -3956,7 +4864,7 @@ static void ipw_rx_queue_restock(struct ipw_priv *priv)
/* If we've added more space for the firmware to place data, tell it */
if (write != rxq->write)
- ipw_write32(priv, CX2_RX_WRITE_INDEX, rxq->write);
+ ipw_write32(priv, IPW_RX_WRITE_INDEX, rxq->write);
}
/*
@@ -3977,7 +4885,7 @@ static void ipw_rx_queue_replenish(void *data)
while (!list_empty(&rxq->rx_used)) {
element = rxq->rx_used.next;
rxb = list_entry(element, struct ipw_rx_mem_buffer, list);
- rxb->skb = alloc_skb(CX2_RX_BUF_SIZE, GFP_ATOMIC);
+ rxb->skb = alloc_skb(IPW_RX_BUF_SIZE, GFP_ATOMIC);
if (!rxb->skb) {
printk(KERN_CRIT "%s: Can not allocate SKB buffers.\n",
priv->net_dev->name);
@@ -3991,7 +4899,7 @@ static void ipw_rx_queue_replenish(void *data)
rxb->rxb = (struct ipw_rx_buffer *)rxb->skb->data;
rxb->dma_addr =
pci_map_single(priv->pci_dev, rxb->skb->data,
- CX2_RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
+ IPW_RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
list_add_tail(&rxb->list, &rxq->rx_free);
rxq->free_count++;
@@ -4001,6 +4909,14 @@ static void ipw_rx_queue_replenish(void *data)
ipw_rx_queue_restock(priv);
}
+static void ipw_bg_rx_queue_replenish(void *data)
+{
+ struct ipw_priv *priv = data;
+ down(&priv->sem);
+ ipw_rx_queue_replenish(data);
+ up(&priv->sem);
+}
+
/* Assumes that the skb field of the buffers in 'pool' is kept accurate.
* If an SKB has been detached, the POOL needs to have it's SKB set to NULL
* This free routine walks the list of POOL entries and if SKB is set to
@@ -4016,7 +4932,7 @@ static void ipw_rx_queue_free(struct ipw_priv *priv, struct ipw_rx_queue *rxq)
for (i = 0; i < RX_QUEUE_SIZE + RX_FREE_BUFFERS; i++) {
if (rxq->pool[i].skb != NULL) {
pci_unmap_single(priv->pci_dev, rxq->pool[i].dma_addr,
- CX2_RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
+ IPW_RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
dev_kfree_skb(rxq->pool[i].skb);
}
}
@@ -4030,6 +4946,10 @@ static struct ipw_rx_queue *ipw_rx_queue_alloc(struct ipw_priv *priv)
int i;
rxq = (struct ipw_rx_queue *)kmalloc(sizeof(*rxq), GFP_KERNEL);
+ if (unlikely(!rxq)) {
+ IPW_ERROR("memory allocation failed\n");
+ return NULL;
+ }
memset(rxq, 0, sizeof(*rxq));
spin_lock_init(&rxq->lock);
INIT_LIST_HEAD(&rxq->rx_free);
@@ -4131,8 +5051,18 @@ static int ipw_compatible_rates(struct ipw_priv *priv,
num_rates = min(network->rates_len, (u8) IPW_MAX_RATES);
rates->num_rates = 0;
for (i = 0; i < num_rates; i++) {
- if (!ipw_is_rate_in_mask
- (priv, network->mode, network->rates[i])) {
+ if (!ipw_is_rate_in_mask(priv, network->mode,
+ network->rates[i])) {
+
+ if (network->rates[i] & IEEE80211_BASIC_RATE_MASK) {
+ IPW_DEBUG_SCAN("Adding masked mandatory "
+ "rate %02X\n",
+ network->rates[i]);
+ rates->supported_rates[rates->num_rates++] =
+ network->rates[i];
+ continue;
+ }
+
IPW_DEBUG_SCAN("Rate %02X masked : 0x%08X\n",
network->rates[i], priv->rates_mask);
continue;
@@ -4141,11 +5071,20 @@ static int ipw_compatible_rates(struct ipw_priv *priv,
rates->supported_rates[rates->num_rates++] = network->rates[i];
}
- num_rates =
- min(network->rates_ex_len, (u8) (IPW_MAX_RATES - num_rates));
+ num_rates = min(network->rates_ex_len,
+ (u8) (IPW_MAX_RATES - num_rates));
for (i = 0; i < num_rates; i++) {
- if (!ipw_is_rate_in_mask
- (priv, network->mode, network->rates_ex[i])) {
+ if (!ipw_is_rate_in_mask(priv, network->mode,
+ network->rates_ex[i])) {
+ if (network->rates_ex[i] & IEEE80211_BASIC_RATE_MASK) {
+ IPW_DEBUG_SCAN("Adding masked mandatory "
+ "rate %02X\n",
+ network->rates_ex[i]);
+ rates->supported_rates[rates->num_rates++] =
+ network->rates[i];
+ continue;
+ }
+
IPW_DEBUG_SCAN("Rate %02X masked : 0x%08X\n",
network->rates_ex[i], priv->rates_mask);
continue;
@@ -4155,7 +5094,7 @@ static int ipw_compatible_rates(struct ipw_priv *priv,
network->rates_ex[i];
}
- return rates->num_rates;
+ return 1;
}
static inline void ipw_copy_rates(struct ipw_supported_rates *dest,
@@ -4237,6 +5176,216 @@ struct ipw_network_match {
struct ipw_supported_rates rates;
};
+static int ipw_find_adhoc_network(struct ipw_priv *priv,
+ struct ipw_network_match *match,
+ struct ieee80211_network *network,
+ int roaming)
+{
+ struct ipw_supported_rates rates;
+
+ /* Verify that this network's capability is compatible with the
+ * current mode (AdHoc or Infrastructure) */
+ if ((priv->ieee->iw_mode == IW_MODE_ADHOC &&
+ !(network->capability & WLAN_CAPABILITY_IBSS))) {
+ IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' excluded due to "
+ "capability mismatch.\n",
+ escape_essid(network->ssid, network->ssid_len),
+ MAC_ARG(network->bssid));
+ return 0;
+ }
+
+ /* If we do not have an ESSID for this AP, we can not associate with
+ * it */
+ if (network->flags & NETWORK_EMPTY_ESSID) {
+ IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' excluded "
+ "because of hidden ESSID.\n",
+ escape_essid(network->ssid, network->ssid_len),
+ MAC_ARG(network->bssid));
+ return 0;
+ }
+
+ if (unlikely(roaming)) {
+ /* If we are roaming, then ensure check if this is a valid
+ * network to try and roam to */
+ if ((network->ssid_len != match->network->ssid_len) ||
+ memcmp(network->ssid, match->network->ssid,
+ network->ssid_len)) {
+ IPW_DEBUG_MERGE("Netowrk '%s (" MAC_FMT ")' excluded "
+ "because of non-network ESSID.\n",
+ escape_essid(network->ssid,
+ network->ssid_len),
+ MAC_ARG(network->bssid));
+ return 0;
+ }
+ } else {
+ /* If an ESSID has been configured then compare the broadcast
+ * ESSID to ours */
+ if ((priv->config & CFG_STATIC_ESSID) &&
+ ((network->ssid_len != priv->essid_len) ||
+ memcmp(network->ssid, priv->essid,
+ min(network->ssid_len, priv->essid_len)))) {
+ char escaped[IW_ESSID_MAX_SIZE * 2 + 1];
+
+ strncpy(escaped,
+ escape_essid(network->ssid, network->ssid_len),
+ sizeof(escaped));
+ IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' excluded "
+ "because of ESSID mismatch: '%s'.\n",
+ escaped, MAC_ARG(network->bssid),
+ escape_essid(priv->essid,
+ priv->essid_len));
+ return 0;
+ }
+ }
+
+ /* If the old network rate is better than this one, don't bother
+ * testing everything else. */
+
+ if (network->time_stamp[0] < match->network->time_stamp[0]) {
+ IPW_DEBUG_MERGE("Network '%s excluded because newer than "
+ "current network.\n",
+ escape_essid(match->network->ssid,
+ match->network->ssid_len));
+ return 0;
+ } else if (network->time_stamp[1] < match->network->time_stamp[1]) {
+ IPW_DEBUG_MERGE("Network '%s excluded because newer than "
+ "current network.\n",
+ escape_essid(match->network->ssid,
+ match->network->ssid_len));
+ return 0;
+ }
+
+ /* Now go through and see if the requested network is valid... */
+ if (priv->ieee->scan_age != 0 &&
+ time_after(jiffies, network->last_scanned + priv->ieee->scan_age)) {
+ IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' excluded "
+ "because of age: %lums.\n",
+ escape_essid(network->ssid, network->ssid_len),
+ MAC_ARG(network->bssid),
+ 1000 * (jiffies - network->last_scanned) / HZ);
+ return 0;
+ }
+
+ if ((priv->config & CFG_STATIC_CHANNEL) &&
+ (network->channel != priv->channel)) {
+ IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' excluded "
+ "because of channel mismatch: %d != %d.\n",
+ escape_essid(network->ssid, network->ssid_len),
+ MAC_ARG(network->bssid),
+ network->channel, priv->channel);
+ return 0;
+ }
+
+ /* Verify privacy compatability */
+ if (((priv->capability & CAP_PRIVACY_ON) ? 1 : 0) !=
+ ((network->capability & WLAN_CAPABILITY_PRIVACY) ? 1 : 0)) {
+ IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' excluded "
+ "because of privacy mismatch: %s != %s.\n",
+ escape_essid(network->ssid, network->ssid_len),
+ MAC_ARG(network->bssid),
+ priv->
+ capability & CAP_PRIVACY_ON ? "on" : "off",
+ network->
+ capability & WLAN_CAPABILITY_PRIVACY ? "on" :
+ "off");
+ return 0;
+ }
+
+ if (!memcmp(network->bssid, priv->bssid, ETH_ALEN)) {
+ IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' excluded "
+ "because of the same BSSID match: " MAC_FMT
+ ".\n", escape_essid(network->ssid,
+ network->ssid_len),
+ MAC_ARG(network->bssid), MAC_ARG(priv->bssid));
+ return 0;
+ }
+
+ /* Filter out any incompatible freq / mode combinations */
+ if (!ieee80211_is_valid_mode(priv->ieee, network->mode)) {
+ IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' excluded "
+ "because of invalid frequency/mode "
+ "combination.\n",
+ escape_essid(network->ssid, network->ssid_len),
+ MAC_ARG(network->bssid));
+ return 0;
+ }
+
+ /* Ensure that the rates supported by the driver are compatible with
+ * this AP, including verification of basic rates (mandatory) */
+ if (!ipw_compatible_rates(priv, network, &rates)) {
+ IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' excluded "
+ "because configured rate mask excludes "
+ "AP mandatory rate.\n",
+ escape_essid(network->ssid, network->ssid_len),
+ MAC_ARG(network->bssid));
+ return 0;
+ }
+
+ if (rates.num_rates == 0) {
+ IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' excluded "
+ "because of no compatible rates.\n",
+ escape_essid(network->ssid, network->ssid_len),
+ MAC_ARG(network->bssid));
+ return 0;
+ }
+
+ /* TODO: Perform any further minimal comparititive tests. We do not
+ * want to put too much policy logic here; intelligent scan selection
+ * should occur within a generic IEEE 802.11 user space tool. */
+
+ /* Set up 'new' AP to this network */
+ ipw_copy_rates(&match->rates, &rates);
+ match->network = network;
+ IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' is a viable match.\n",
+ escape_essid(network->ssid, network->ssid_len),
+ MAC_ARG(network->bssid));
+
+ return 1;
+}
+
+static void ipw_merge_adhoc_network(void *data)
+{
+ struct ipw_priv *priv = data;
+ struct ieee80211_network *network = NULL;
+ struct ipw_network_match match = {
+ .network = priv->assoc_network
+ };
+
+ if ((priv->status & STATUS_ASSOCIATED) &&
+ (priv->ieee->iw_mode == IW_MODE_ADHOC)) {
+ /* First pass through ROAM process -- look for a better
+ * network */
+ unsigned long flags;
+
+ spin_lock_irqsave(&priv->ieee->lock, flags);
+ list_for_each_entry(network, &priv->ieee->network_list, list) {
+ if (network != priv->assoc_network)
+ ipw_find_adhoc_network(priv, &match, network,
+ 1);
+ }
+ spin_unlock_irqrestore(&priv->ieee->lock, flags);
+
+ if (match.network == priv->assoc_network) {
+ IPW_DEBUG_MERGE("No better ADHOC in this network to "
+ "merge to.\n");
+ return;
+ }
+
+ down(&priv->sem);
+ if ((priv->ieee->iw_mode == IW_MODE_ADHOC)) {
+ IPW_DEBUG_MERGE("remove network %s\n",
+ escape_essid(priv->essid,
+ priv->essid_len));
+ ipw_remove_current_network(priv);
+ }
+
+ ipw_disassociate(priv);
+ priv->assoc_network = match.network;
+ up(&priv->sem);
+ return;
+ }
+}
+
static int ipw_best_network(struct ipw_priv *priv,
struct ipw_network_match *match,
struct ieee80211_network *network, int roaming)
@@ -4318,9 +5467,9 @@ static int ipw_best_network(struct ipw_priv *priv,
/* If this network has already had an association attempt within the
* last 3 seconds, do not try and associate again... */
if (network->last_associate &&
- time_after(network->last_associate + (HZ * 5UL), jiffies)) {
+ time_after(network->last_associate + (HZ * 3UL), jiffies)) {
IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded "
- "because of storming (%lu since last "
+ "because of storming (%lus since last "
"assoc attempt).\n",
escape_essid(network->ssid, network->ssid_len),
MAC_ARG(network->bssid),
@@ -4330,12 +5479,12 @@ static int ipw_best_network(struct ipw_priv *priv,
/* Now go through and see if the requested network is valid... */
if (priv->ieee->scan_age != 0 &&
- jiffies - network->last_scanned > priv->ieee->scan_age) {
+ time_after(jiffies, network->last_scanned + priv->ieee->scan_age)) {
IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded "
"because of age: %lums.\n",
escape_essid(network->ssid, network->ssid_len),
MAC_ARG(network->bssid),
- (jiffies - network->last_scanned) / (HZ / 100));
+ 1000 * (jiffies - network->last_scanned) / HZ);
return 0;
}
@@ -4363,6 +5512,15 @@ static int ipw_best_network(struct ipw_priv *priv,
return 0;
}
+ if (!priv->ieee->wpa_enabled && (network->wpa_ie_len > 0 ||
+ network->rsn_ie_len > 0)) {
+ IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded "
+ "because of WPA capability mismatch.\n",
+ escape_essid(network->ssid, network->ssid_len),
+ MAC_ARG(network->bssid));
+ return 0;
+ }
+
if ((priv->config & CFG_STATIC_BSSID) &&
memcmp(network->bssid, priv->bssid, ETH_ALEN)) {
IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded "
@@ -4382,7 +5540,26 @@ static int ipw_best_network(struct ipw_priv *priv,
return 0;
}
- ipw_compatible_rates(priv, network, &rates);
+ /* Filter out invalid channel in current GEO */
+ if (!ipw_is_valid_channel(priv->ieee, network->channel)) {
+ IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded "
+ "because of invalid channel in current GEO\n",
+ escape_essid(network->ssid, network->ssid_len),
+ MAC_ARG(network->bssid));
+ return 0;
+ }
+
+ /* Ensure that the rates supported by the driver are compatible with
+ * this AP, including verification of basic rates (mandatory) */
+ if (!ipw_compatible_rates(priv, network, &rates)) {
+ IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded "
+ "because configured rate mask excludes "
+ "AP mandatory rate.\n",
+ escape_essid(network->ssid, network->ssid_len),
+ MAC_ARG(network->bssid));
+ return 0;
+ }
+
if (rates.num_rates == 0) {
IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded "
"because of no compatible rates.\n",
@@ -4409,6 +5586,9 @@ static int ipw_best_network(struct ipw_priv *priv,
static void ipw_adhoc_create(struct ipw_priv *priv,
struct ieee80211_network *network)
{
+ const struct ieee80211_geo *geo = ipw_get_geo(priv->ieee);
+ int i;
+
/*
* For the purposes of scanning, we can set our wireless mode
* to trigger scans across combinations of bands, but when it
@@ -4419,22 +5599,47 @@ static void ipw_adhoc_create(struct ipw_priv *priv,
* chossen band. Attempting to create a new ad-hoc network
* with an invalid channel for wireless mode will trigger a
* FW fatal error.
+ *
*/
- network->mode = is_valid_channel(priv->ieee->mode, priv->channel);
- if (network->mode) {
- network->channel = priv->channel;
- } else {
+ switch (ipw_is_valid_channel(priv->ieee, priv->channel)) {
+ case IEEE80211_52GHZ_BAND:
+ network->mode = IEEE_A;
+ i = ipw_channel_to_index(priv->ieee, priv->channel);
+ if (i == -1)
+ BUG();
+ if (geo->a[i].flags & IEEE80211_CH_PASSIVE_ONLY) {
+ IPW_WARNING("Overriding invalid channel\n");
+ priv->channel = geo->a[0].channel;
+ }
+ break;
+
+ case IEEE80211_24GHZ_BAND:
+ if (priv->ieee->mode & IEEE_G)
+ network->mode = IEEE_G;
+ else
+ network->mode = IEEE_B;
+ i = ipw_channel_to_index(priv->ieee, priv->channel);
+ if (i == -1)
+ BUG();
+ if (geo->bg[i].flags & IEEE80211_CH_PASSIVE_ONLY) {
+ IPW_WARNING("Overriding invalid channel\n");
+ priv->channel = geo->bg[0].channel;
+ }
+ break;
+
+ default:
IPW_WARNING("Overriding invalid channel\n");
if (priv->ieee->mode & IEEE_A) {
network->mode = IEEE_A;
- priv->channel = band_a_active_channel[0];
+ priv->channel = geo->a[0].channel;
} else if (priv->ieee->mode & IEEE_G) {
network->mode = IEEE_G;
- priv->channel = band_b_active_channel[0];
+ priv->channel = geo->bg[0].channel;
} else {
network->mode = IEEE_B;
- priv->channel = band_b_active_channel[0];
+ priv->channel = geo->bg[0].channel;
}
+ break;
}
network->channel = priv->channel;
@@ -4444,6 +5649,8 @@ static void ipw_adhoc_create(struct ipw_priv *priv,
memcpy(network->ssid, priv->essid, priv->essid_len);
memset(&network->stats, 0, sizeof(network->stats));
network->capability = WLAN_CAPABILITY_IBSS;
+ if (!(priv->config & CFG_PREAMBLE_LONG))
+ network->capability |= WLAN_CAPABILITY_SHORT_PREAMBLE;
if (priv->capability & CAP_PRIVACY_ON)
network->capability |= WLAN_CAPABILITY_PRIVACY;
network->rates_len = min(priv->rates.num_rates, MAX_RATES_LENGTH);
@@ -4460,13 +5667,35 @@ static void ipw_adhoc_create(struct ipw_priv *priv,
network->beacon_interval = 100; /* Default */
network->listen_interval = 10; /* Default */
network->atim_window = 0; /* Default */
-#ifdef CONFIG_IEEE80211_WPA
network->wpa_ie_len = 0;
network->rsn_ie_len = 0;
-#endif /* CONFIG_IEEE80211_WPA */
}
-static void ipw_send_wep_keys(struct ipw_priv *priv)
+static void ipw_send_tgi_tx_key(struct ipw_priv *priv, int type, int index)
+{
+ struct ipw_tgi_tx_key *key;
+ struct host_cmd cmd = {
+ .cmd = IPW_CMD_TGI_TX_KEY,
+ .len = sizeof(*key)
+ };
+
+ if (!(priv->ieee->sec.flags & (1 << index)))
+ return;
+
+ key = (struct ipw_tgi_tx_key *)&cmd.param;
+ key->key_id = index;
+ memcpy(key->key, priv->ieee->sec.keys[index], SCM_TEMPORAL_KEY_LENGTH);
+ key->security_type = type;
+ key->station_index = 0; /* always 0 for BSS */
+ key->flags = 0;
+ /* 0 for new key; previous value of counter (after fatal error) */
+ key->tx_counter[0] = 0;
+ key->tx_counter[1] = 0;
+
+ ipw_send_cmd(priv, &cmd);
+}
+
+static void ipw_send_wep_keys(struct ipw_priv *priv, int type)
{
struct ipw_wep_key *key;
int i;
@@ -4479,19 +5708,97 @@ static void ipw_send_wep_keys(struct ipw_priv *priv)
key->cmd_id = DINO_CMD_WEP_KEY;
key->seq_num = 0;
+ /* Note: AES keys cannot be set for multiple times.
+ * Only set it at the first time. */
for (i = 0; i < 4; i++) {
- key->key_index = i;
- if (!(priv->sec.flags & (1 << i))) {
+ key->key_index = i | type;
+ if (!(priv->ieee->sec.flags & (1 << i))) {
key->key_size = 0;
- } else {
- key->key_size = priv->sec.key_sizes[i];
- memcpy(key->key, priv->sec.keys[i], key->key_size);
+ continue;
}
- if (ipw_send_cmd(priv, &cmd)) {
- IPW_ERROR("failed to send WEP_KEY command\n");
- return;
- }
+ key->key_size = priv->ieee->sec.key_sizes[i];
+ memcpy(key->key, priv->ieee->sec.keys[i], key->key_size);
+
+ ipw_send_cmd(priv, &cmd);
+ }
+}
+
+static void ipw_set_hw_decrypt_unicast(struct ipw_priv *priv, int level)
+{
+ if (priv->ieee->host_encrypt)
+ return;
+
+ switch (level) {
+ case SEC_LEVEL_3:
+ priv->sys_config.disable_unicast_decryption = 0;
+ priv->ieee->host_decrypt = 0;
+ break;
+ case SEC_LEVEL_2:
+ priv->sys_config.disable_unicast_decryption = 1;
+ priv->ieee->host_decrypt = 1;
+ break;
+ case SEC_LEVEL_1:
+ priv->sys_config.disable_unicast_decryption = 0;
+ priv->ieee->host_decrypt = 0;
+ break;
+ case SEC_LEVEL_0:
+ priv->sys_config.disable_unicast_decryption = 1;
+ break;
+ default:
+ break;
+ }
+}
+
+static void ipw_set_hw_decrypt_multicast(struct ipw_priv *priv, int level)
+{
+ if (priv->ieee->host_encrypt)
+ return;
+
+ switch (level) {
+ case SEC_LEVEL_3:
+ priv->sys_config.disable_multicast_decryption = 0;
+ break;
+ case SEC_LEVEL_2:
+ priv->sys_config.disable_multicast_decryption = 1;
+ break;
+ case SEC_LEVEL_1:
+ priv->sys_config.disable_multicast_decryption = 0;
+ break;
+ case SEC_LEVEL_0:
+ priv->sys_config.disable_multicast_decryption = 1;
+ break;
+ default:
+ break;
+ }
+}
+
+static void ipw_set_hwcrypto_keys(struct ipw_priv *priv)
+{
+ switch (priv->ieee->sec.level) {
+ case SEC_LEVEL_3:
+ if (priv->ieee->sec.flags & SEC_ACTIVE_KEY)
+ ipw_send_tgi_tx_key(priv,
+ DCT_FLAG_EXT_SECURITY_CCM,
+ priv->ieee->sec.active_key);
+
+ if (!priv->ieee->host_mc_decrypt)
+ ipw_send_wep_keys(priv, DCW_WEP_KEY_SEC_TYPE_CCM);
+ break;
+ case SEC_LEVEL_2:
+ if (priv->ieee->sec.flags & SEC_ACTIVE_KEY)
+ ipw_send_tgi_tx_key(priv,
+ DCT_FLAG_EXT_SECURITY_TKIP,
+ priv->ieee->sec.active_key);
+ break;
+ case SEC_LEVEL_1:
+ ipw_send_wep_keys(priv, DCW_WEP_KEY_SEC_TYPE_WEP);
+ ipw_set_hw_decrypt_unicast(priv, priv->ieee->sec.level);
+ ipw_set_hw_decrypt_multicast(priv, priv->ieee->sec.level);
+ break;
+ case SEC_LEVEL_0:
+ default:
+ break;
}
}
@@ -4499,9 +5806,12 @@ static void ipw_adhoc_check(void *data)
{
struct ipw_priv *priv = data;
- if (priv->missed_adhoc_beacons++ > priv->missed_beacon_threshold &&
+ if (priv->missed_adhoc_beacons++ > priv->disassociate_threshold &&
!(priv->config & CFG_ADHOC_PERSIST)) {
- IPW_DEBUG_SCAN("Disassociating due to missed beacons\n");
+ IPW_DEBUG(IPW_DL_INFO | IPW_DL_NOTIF |
+ IPW_DL_STATE | IPW_DL_ASSOC,
+ "Missed beacon: %d - disassociate\n",
+ priv->missed_adhoc_beacons);
ipw_remove_current_network(priv);
ipw_disassociate(priv);
return;
@@ -4511,6 +5821,14 @@ static void ipw_adhoc_check(void *data)
priv->assoc_request.beacon_interval);
}
+static void ipw_bg_adhoc_check(void *data)
+{
+ struct ipw_priv *priv = data;
+ down(&priv->sem);
+ ipw_adhoc_check(data);
+ up(&priv->sem);
+}
+
#ifdef CONFIG_IPW_DEBUG
static void ipw_debug_config(struct ipw_priv *priv)
{
@@ -4526,7 +5844,8 @@ static void ipw_debug_config(struct ipw_priv *priv)
else
IPW_DEBUG_INFO("ESSID unlocked.\n");
if (priv->config & CFG_STATIC_BSSID)
- IPW_DEBUG_INFO("BSSID locked to %d\n", priv->channel);
+ IPW_DEBUG_INFO("BSSID locked to " MAC_FMT "\n",
+ MAC_ARG(priv->bssid));
else
IPW_DEBUG_INFO("BSSID unlocked.\n");
if (priv->capability & CAP_PRIVACY_ON)
@@ -4539,8 +5858,7 @@ static void ipw_debug_config(struct ipw_priv *priv)
#define ipw_debug_config(x) do {} while (0)
#endif
-static inline void ipw_set_fixed_rate(struct ipw_priv *priv,
- struct ieee80211_network *network)
+static inline void ipw_set_fixed_rate(struct ipw_priv *priv, int mode)
{
/* TODO: Verify that this works... */
struct ipw_fixed_rate fr = {
@@ -4557,6 +5875,8 @@ static inline void ipw_set_fixed_rate(struct ipw_priv *priv,
/* IEEE_A */
if (priv->rates_mask & ~IEEE80211_OFDM_RATES_MASK) {
/* Invalid fixed rate mask */
+ IPW_DEBUG_WX
+ ("invalid fixed rate mask in ipw_set_fixed_rate\n");
fr.tx_rates = 0;
break;
}
@@ -4566,9 +5886,11 @@ static inline void ipw_set_fixed_rate(struct ipw_priv *priv,
default: /* 2.4Ghz or Mixed */
/* IEEE_B */
- if (network->mode == IEEE_B) {
+ if (mode == IEEE_B) {
if (fr.tx_rates & ~IEEE80211_CCK_RATES_MASK) {
/* Invalid fixed rate mask */
+ IPW_DEBUG_WX
+ ("invalid fixed rate mask in ipw_set_fixed_rate\n");
fr.tx_rates = 0;
}
break;
@@ -4578,6 +5900,8 @@ static inline void ipw_set_fixed_rate(struct ipw_priv *priv,
if (fr.tx_rates & ~(IEEE80211_CCK_RATES_MASK |
IEEE80211_OFDM_RATES_MASK)) {
/* Invalid fixed rate mask */
+ IPW_DEBUG_WX
+ ("invalid fixed rate mask in ipw_set_fixed_rate\n");
fr.tx_rates = 0;
break;
}
@@ -4605,6 +5929,1112 @@ static inline void ipw_set_fixed_rate(struct ipw_priv *priv,
ipw_write_reg32(priv, reg, *(u32 *) & fr);
}
+static void ipw_abort_scan(struct ipw_priv *priv)
+{
+ int err;
+
+ if (priv->status & STATUS_SCAN_ABORTING) {
+ IPW_DEBUG_HC("Ignoring concurrent scan abort request.\n");
+ return;
+ }
+ priv->status |= STATUS_SCAN_ABORTING;
+
+ err = ipw_send_scan_abort(priv);
+ if (err)
+ IPW_DEBUG_HC("Request to abort scan failed.\n");
+}
+
+static void ipw_add_scan_channels(struct ipw_priv *priv,
+ struct ipw_scan_request_ext *scan,
+ int scan_type)
+{
+ int channel_index = 0;
+ const struct ieee80211_geo *geo;
+ int i;
+
+ geo = ipw_get_geo(priv->ieee);
+
+ if (priv->ieee->freq_band & IEEE80211_52GHZ_BAND) {
+ int start = channel_index;
+ for (i = 0; i < geo->a_channels; i++) {
+ if ((priv->status & STATUS_ASSOCIATED) &&
+ geo->a[i].channel == priv->channel)
+ continue;
+ channel_index++;
+ scan->channels_list[channel_index] = geo->a[i].channel;
+ ipw_set_scan_type(scan, channel_index,
+ geo->a[i].
+ flags & IEEE80211_CH_PASSIVE_ONLY ?
+ IPW_SCAN_PASSIVE_FULL_DWELL_SCAN :
+ scan_type);
+ }
+
+ if (start != channel_index) {
+ scan->channels_list[start] = (u8) (IPW_A_MODE << 6) |
+ (channel_index - start);
+ channel_index++;
+ }
+ }
+
+ if (priv->ieee->freq_band & IEEE80211_24GHZ_BAND) {
+ int start = channel_index;
+ if (priv->config & CFG_SPEED_SCAN) {
+ int index;
+ u8 channels[IEEE80211_24GHZ_CHANNELS] = {
+ /* nop out the list */
+ [0] = 0
+ };
+
+ u8 channel;
+ while (channel_index < IPW_SCAN_CHANNELS) {
+ channel =
+ priv->speed_scan[priv->speed_scan_pos];
+ if (channel == 0) {
+ priv->speed_scan_pos = 0;
+ channel = priv->speed_scan[0];
+ }
+ if ((priv->status & STATUS_ASSOCIATED) &&
+ channel == priv->channel) {
+ priv->speed_scan_pos++;
+ continue;
+ }
+
+ /* If this channel has already been
+ * added in scan, break from loop
+ * and this will be the first channel
+ * in the next scan.
+ */
+ if (channels[channel - 1] != 0)
+ break;
+
+ channels[channel - 1] = 1;
+ priv->speed_scan_pos++;
+ channel_index++;
+ scan->channels_list[channel_index] = channel;
+ index =
+ ipw_channel_to_index(priv->ieee, channel);
+ ipw_set_scan_type(scan, channel_index,
+ geo->bg[index].
+ flags &
+ IEEE80211_CH_PASSIVE_ONLY ?
+ IPW_SCAN_PASSIVE_FULL_DWELL_SCAN
+ : scan_type);
+ }
+ } else {
+ for (i = 0; i < geo->bg_channels; i++) {
+ if ((priv->status & STATUS_ASSOCIATED) &&
+ geo->bg[i].channel == priv->channel)
+ continue;
+ channel_index++;
+ scan->channels_list[channel_index] =
+ geo->bg[i].channel;
+ ipw_set_scan_type(scan, channel_index,
+ geo->bg[i].
+ flags &
+ IEEE80211_CH_PASSIVE_ONLY ?
+ IPW_SCAN_PASSIVE_FULL_DWELL_SCAN
+ : scan_type);
+ }
+ }
+
+ if (start != channel_index) {
+ scan->channels_list[start] = (u8) (IPW_B_MODE << 6) |
+ (channel_index - start);
+ }
+ }
+}
+
+static int ipw_request_scan(struct ipw_priv *priv)
+{
+ struct ipw_scan_request_ext scan;
+ int err = 0, scan_type;
+
+ if (!(priv->status & STATUS_INIT) ||
+ (priv->status & STATUS_EXIT_PENDING))
+ return 0;
+
+ down(&priv->sem);
+
+ if (priv->status & STATUS_SCANNING) {
+ IPW_DEBUG_HC("Concurrent scan requested. Ignoring.\n");
+ priv->status |= STATUS_SCAN_PENDING;
+ goto done;
+ }
+
+ if (!(priv->status & STATUS_SCAN_FORCED) &&
+ priv->status & STATUS_SCAN_ABORTING) {
+ IPW_DEBUG_HC("Scan request while abort pending. Queuing.\n");
+ priv->status |= STATUS_SCAN_PENDING;
+ goto done;
+ }
+
+ if (priv->status & STATUS_RF_KILL_MASK) {
+ IPW_DEBUG_HC("Aborting scan due to RF Kill activation\n");
+ priv->status |= STATUS_SCAN_PENDING;
+ goto done;
+ }
+
+ memset(&scan, 0, sizeof(scan));
+
+ if (priv->config & CFG_SPEED_SCAN)
+ scan.dwell_time[IPW_SCAN_ACTIVE_BROADCAST_SCAN] =
+ cpu_to_le16(30);
+ else
+ scan.dwell_time[IPW_SCAN_ACTIVE_BROADCAST_SCAN] =
+ cpu_to_le16(20);
+
+ scan.dwell_time[IPW_SCAN_ACTIVE_BROADCAST_AND_DIRECT_SCAN] =
+ cpu_to_le16(20);
+ scan.dwell_time[IPW_SCAN_PASSIVE_FULL_DWELL_SCAN] = cpu_to_le16(120);
+
+ scan.full_scan_index = cpu_to_le32(ieee80211_get_scans(priv->ieee));
+
+#ifdef CONFIG_IPW2200_MONITOR
+ if (priv->ieee->iw_mode == IW_MODE_MONITOR) {
+ u8 channel;
+ u8 band = 0;
+
+ switch (ipw_is_valid_channel(priv->ieee, priv->channel)) {
+ case IEEE80211_52GHZ_BAND:
+ band = (u8) (IPW_A_MODE << 6) | 1;
+ channel = priv->channel;
+ break;
+
+ case IEEE80211_24GHZ_BAND:
+ band = (u8) (IPW_B_MODE << 6) | 1;
+ channel = priv->channel;
+ break;
+
+ default:
+ band = (u8) (IPW_B_MODE << 6) | 1;
+ channel = 9;
+ break;
+ }
+
+ scan.channels_list[0] = band;
+ scan.channels_list[1] = channel;
+ ipw_set_scan_type(&scan, 1, IPW_SCAN_PASSIVE_FULL_DWELL_SCAN);
+
+ /* NOTE: The card will sit on this channel for this time
+ * period. Scan aborts are timing sensitive and frequently
+ * result in firmware restarts. As such, it is best to
+ * set a small dwell_time here and just keep re-issuing
+ * scans. Otherwise fast channel hopping will not actually
+ * hop channels.
+ *
+ * TODO: Move SPEED SCAN support to all modes and bands */
+ scan.dwell_time[IPW_SCAN_PASSIVE_FULL_DWELL_SCAN] =
+ cpu_to_le16(2000);
+ } else {
+#endif /* CONFIG_IPW2200_MONITOR */
+ /* If we are roaming, then make this a directed scan for the
+ * current network. Otherwise, ensure that every other scan
+ * is a fast channel hop scan */
+ if ((priv->status & STATUS_ROAMING)
+ || (!(priv->status & STATUS_ASSOCIATED)
+ && (priv->config & CFG_STATIC_ESSID)
+ && (le32_to_cpu(scan.full_scan_index) % 2))) {
+ err = ipw_send_ssid(priv, priv->essid, priv->essid_len);
+ if (err) {
+ IPW_DEBUG_HC("Attempt to send SSID command "
+ "failed.\n");
+ goto done;
+ }
+
+ scan_type = IPW_SCAN_ACTIVE_BROADCAST_AND_DIRECT_SCAN;
+ } else
+ scan_type = IPW_SCAN_ACTIVE_BROADCAST_SCAN;
+
+ ipw_add_scan_channels(priv, &scan, scan_type);
+#ifdef CONFIG_IPW2200_MONITOR
+ }
+#endif
+
+ err = ipw_send_scan_request_ext(priv, &scan);
+ if (err) {
+ IPW_DEBUG_HC("Sending scan command failed: %08X\n", err);
+ goto done;
+ }
+
+ priv->status |= STATUS_SCANNING;
+ priv->status &= ~STATUS_SCAN_PENDING;
+ queue_delayed_work(priv->workqueue, &priv->scan_check,
+ IPW_SCAN_CHECK_WATCHDOG);
+ done:
+ up(&priv->sem);
+ return err;
+}
+
+static void ipw_bg_abort_scan(void *data)
+{
+ struct ipw_priv *priv = data;
+ down(&priv->sem);
+ ipw_abort_scan(data);
+ up(&priv->sem);
+}
+
+static int ipw_wpa_enable(struct ipw_priv *priv, int value)
+{
+ /* This is called when wpa_supplicant loads and closes the driver
+ * interface. */
+ priv->ieee->wpa_enabled = value;
+ return 0;
+}
+
+static int ipw_wpa_set_auth_algs(struct ipw_priv *priv, int value)
+{
+ struct ieee80211_device *ieee = priv->ieee;
+ struct ieee80211_security sec = {
+ .flags = SEC_AUTH_MODE,
+ };
+ int ret = 0;
+
+ if (value & IW_AUTH_ALG_SHARED_KEY) {
+ sec.auth_mode = WLAN_AUTH_SHARED_KEY;
+ ieee->open_wep = 0;
+ } else if (value & IW_AUTH_ALG_OPEN_SYSTEM) {
+ sec.auth_mode = WLAN_AUTH_OPEN;
+ ieee->open_wep = 1;
+ } else
+ return -EINVAL;
+
+ if (ieee->set_security)
+ ieee->set_security(ieee->dev, &sec);
+ else
+ ret = -EOPNOTSUPP;
+
+ return ret;
+}
+
+void ipw_wpa_assoc_frame(struct ipw_priv *priv, char *wpa_ie, int wpa_ie_len)
+{
+ /* make sure WPA is enabled */
+ ipw_wpa_enable(priv, 1);
+
+ ipw_disassociate(priv);
+}
+
+static int ipw_set_rsn_capa(struct ipw_priv *priv,
+ char *capabilities, int length)
+{
+ struct host_cmd cmd = {
+ .cmd = IPW_CMD_RSN_CAPABILITIES,
+ .len = length,
+ };
+
+ IPW_DEBUG_HC("HOST_CMD_RSN_CAPABILITIES\n");
+
+ memcpy(cmd.param, capabilities, length);
+ return ipw_send_cmd(priv, &cmd);
+}
+
+/*
+ * WE-18 support
+ */
+
+/* SIOCSIWGENIE */
+static int ipw_wx_set_genie(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct ipw_priv *priv = ieee80211_priv(dev);
+ struct ieee80211_device *ieee = priv->ieee;
+ u8 *buf;
+ int err = 0;
+
+ if (wrqu->data.length > MAX_WPA_IE_LEN ||
+ (wrqu->data.length && extra == NULL))
+ return -EINVAL;
+
+ //down(&priv->sem);
+
+ //if (!ieee->wpa_enabled) {
+ // err = -EOPNOTSUPP;
+ // goto out;
+ //}
+
+ if (wrqu->data.length) {
+ buf = kmalloc(wrqu->data.length, GFP_KERNEL);
+ if (buf == NULL) {
+ err = -ENOMEM;
+ goto out;
+ }
+
+ memcpy(buf, extra, wrqu->data.length);
+ kfree(ieee->wpa_ie);
+ ieee->wpa_ie = buf;
+ ieee->wpa_ie_len = wrqu->data.length;
+ } else {
+ kfree(ieee->wpa_ie);
+ ieee->wpa_ie = NULL;
+ ieee->wpa_ie_len = 0;
+ }
+
+ ipw_wpa_assoc_frame(priv, ieee->wpa_ie, ieee->wpa_ie_len);
+ out:
+ //up(&priv->sem);
+ return err;
+}
+
+/* SIOCGIWGENIE */
+static int ipw_wx_get_genie(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct ipw_priv *priv = ieee80211_priv(dev);
+ struct ieee80211_device *ieee = priv->ieee;
+ int err = 0;
+
+ //down(&priv->sem);
+
+ //if (!ieee->wpa_enabled) {
+ // err = -EOPNOTSUPP;
+ // goto out;
+ //}
+
+ if (ieee->wpa_ie_len == 0 || ieee->wpa_ie == NULL) {
+ wrqu->data.length = 0;
+ goto out;
+ }
+
+ if (wrqu->data.length < ieee->wpa_ie_len) {
+ err = -E2BIG;
+ goto out;
+ }
+
+ wrqu->data.length = ieee->wpa_ie_len;
+ memcpy(extra, ieee->wpa_ie, ieee->wpa_ie_len);
+
+ out:
+ //up(&priv->sem);
+ return err;
+}
+
+static int wext_cipher2level(int cipher)
+{
+ switch (cipher) {
+ case IW_AUTH_CIPHER_NONE:
+ return SEC_LEVEL_0;
+ case IW_AUTH_CIPHER_WEP40:
+ case IW_AUTH_CIPHER_WEP104:
+ return SEC_LEVEL_1;
+ case IW_AUTH_CIPHER_TKIP:
+ return SEC_LEVEL_2;
+ case IW_AUTH_CIPHER_CCMP:
+ return SEC_LEVEL_3;
+ default:
+ return -1;
+ }
+}
+
+/* SIOCSIWAUTH */
+static int ipw_wx_set_auth(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct ipw_priv *priv = ieee80211_priv(dev);
+ struct ieee80211_device *ieee = priv->ieee;
+ struct iw_param *param = &wrqu->param;
+ struct ieee80211_crypt_data *crypt;
+ unsigned long flags;
+ int ret = 0;
+
+ switch (param->flags & IW_AUTH_INDEX) {
+ case IW_AUTH_WPA_VERSION:
+ break;
+ case IW_AUTH_CIPHER_PAIRWISE:
+ ipw_set_hw_decrypt_unicast(priv,
+ wext_cipher2level(param->value));
+ break;
+ case IW_AUTH_CIPHER_GROUP:
+ ipw_set_hw_decrypt_multicast(priv,
+ wext_cipher2level(param->value));
+ break;
+ case IW_AUTH_KEY_MGMT:
+ /*
+ * ipw2200 does not use these parameters
+ */
+ break;
+
+ case IW_AUTH_TKIP_COUNTERMEASURES:
+ crypt = priv->ieee->crypt[priv->ieee->tx_keyidx];
+ if (!crypt || !crypt->ops->set_flags || !crypt->ops->get_flags)
+ break;
+
+ flags = crypt->ops->get_flags(crypt->priv);
+
+ if (param->value)
+ flags |= IEEE80211_CRYPTO_TKIP_COUNTERMEASURES;
+ else
+ flags &= ~IEEE80211_CRYPTO_TKIP_COUNTERMEASURES;
+
+ crypt->ops->set_flags(flags, crypt->priv);
+
+ break;
+
+ case IW_AUTH_DROP_UNENCRYPTED:{
+ /* HACK:
+ *
+ * wpa_supplicant calls set_wpa_enabled when the driver
+ * is loaded and unloaded, regardless of if WPA is being
+ * used. No other calls are made which can be used to
+ * determine if encryption will be used or not prior to
+ * association being expected. If encryption is not being
+ * used, drop_unencrypted is set to false, else true -- we
+ * can use this to determine if the CAP_PRIVACY_ON bit should
+ * be set.
+ */
+ struct ieee80211_security sec = {
+ .flags = SEC_ENABLED,
+ .enabled = param->value,
+ };
+ priv->ieee->drop_unencrypted = param->value;
+ /* We only change SEC_LEVEL for open mode. Others
+ * are set by ipw_wpa_set_encryption.
+ */
+ if (!param->value) {
+ sec.flags |= SEC_LEVEL;
+ sec.level = SEC_LEVEL_0;
+ } else {
+ sec.flags |= SEC_LEVEL;
+ sec.level = SEC_LEVEL_1;
+ }
+ if (priv->ieee->set_security)
+ priv->ieee->set_security(priv->ieee->dev, &sec);
+ break;
+ }
+
+ case IW_AUTH_80211_AUTH_ALG:
+ ret = ipw_wpa_set_auth_algs(priv, param->value);
+ break;
+
+ case IW_AUTH_WPA_ENABLED:
+ ret = ipw_wpa_enable(priv, param->value);
+ break;
+
+ case IW_AUTH_RX_UNENCRYPTED_EAPOL:
+ ieee->ieee802_1x = param->value;
+ break;
+
+ //case IW_AUTH_ROAMING_CONTROL:
+ case IW_AUTH_PRIVACY_INVOKED:
+ ieee->privacy_invoked = param->value;
+ break;
+
+ default:
+ return -EOPNOTSUPP;
+ }
+ return ret;
+}
+
+/* SIOCGIWAUTH */
+static int ipw_wx_get_auth(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct ipw_priv *priv = ieee80211_priv(dev);
+ struct ieee80211_device *ieee = priv->ieee;
+ struct ieee80211_crypt_data *crypt;
+ struct iw_param *param = &wrqu->param;
+ int ret = 0;
+
+ switch (param->flags & IW_AUTH_INDEX) {
+ case IW_AUTH_WPA_VERSION:
+ case IW_AUTH_CIPHER_PAIRWISE:
+ case IW_AUTH_CIPHER_GROUP:
+ case IW_AUTH_KEY_MGMT:
+ /*
+ * wpa_supplicant will control these internally
+ */
+ ret = -EOPNOTSUPP;
+ break;
+
+ case IW_AUTH_TKIP_COUNTERMEASURES:
+ crypt = priv->ieee->crypt[priv->ieee->tx_keyidx];
+ if (!crypt || !crypt->ops->get_flags)
+ break;
+
+ param->value = (crypt->ops->get_flags(crypt->priv) &
+ IEEE80211_CRYPTO_TKIP_COUNTERMEASURES) ? 1 : 0;
+
+ break;
+
+ case IW_AUTH_DROP_UNENCRYPTED:
+ param->value = ieee->drop_unencrypted;
+ break;
+
+ case IW_AUTH_80211_AUTH_ALG:
+ param->value = ieee->sec.auth_mode;
+ break;
+
+ case IW_AUTH_WPA_ENABLED:
+ param->value = ieee->wpa_enabled;
+ break;
+
+ case IW_AUTH_RX_UNENCRYPTED_EAPOL:
+ param->value = ieee->ieee802_1x;
+ break;
+
+ case IW_AUTH_ROAMING_CONTROL:
+ case IW_AUTH_PRIVACY_INVOKED:
+ param->value = ieee->privacy_invoked;
+ break;
+
+ default:
+ return -EOPNOTSUPP;
+ }
+ return 0;
+}
+
+/* SIOCSIWENCODEEXT */
+static int ipw_wx_set_encodeext(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct ipw_priv *priv = ieee80211_priv(dev);
+ struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
+
+ if (hwcrypto) {
+ if (ext->alg == IW_ENCODE_ALG_TKIP) {
+ /* IPW HW can't build TKIP MIC,
+ host decryption still needed */
+ if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY)
+ priv->ieee->host_mc_decrypt = 1;
+ else {
+ priv->ieee->host_encrypt = 0;
+ priv->ieee->host_encrypt_msdu = 1;
+ priv->ieee->host_decrypt = 1;
+ }
+ } else {
+ priv->ieee->host_encrypt = 0;
+ priv->ieee->host_encrypt_msdu = 0;
+ priv->ieee->host_decrypt = 0;
+ priv->ieee->host_mc_decrypt = 0;
+ }
+ }
+
+ return ieee80211_wx_set_encodeext(priv->ieee, info, wrqu, extra);
+}
+
+/* SIOCGIWENCODEEXT */
+static int ipw_wx_get_encodeext(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct ipw_priv *priv = ieee80211_priv(dev);
+ return ieee80211_wx_get_encodeext(priv->ieee, info, wrqu, extra);
+}
+
+/* SIOCSIWMLME */
+static int ipw_wx_set_mlme(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct ipw_priv *priv = ieee80211_priv(dev);
+ struct iw_mlme *mlme = (struct iw_mlme *)extra;
+ u16 reason;
+
+ reason = cpu_to_le16(mlme->reason_code);
+
+ switch (mlme->cmd) {
+ case IW_MLME_DEAUTH:
+ // silently ignore
+ break;
+
+ case IW_MLME_DISASSOC:
+ ipw_disassociate(priv);
+ break;
+
+ default:
+ return -EOPNOTSUPP;
+ }
+ return 0;
+}
+
+#ifdef CONFIG_IPW_QOS
+
+/* QoS */
+/*
+* get the modulation type of the current network or
+* the card current mode
+*/
+u8 ipw_qos_current_mode(struct ipw_priv * priv)
+{
+ u8 mode = 0;
+
+ if (priv->status & STATUS_ASSOCIATED) {
+ unsigned long flags;
+
+ spin_lock_irqsave(&priv->ieee->lock, flags);
+ mode = priv->assoc_network->mode;
+ spin_unlock_irqrestore(&priv->ieee->lock, flags);
+ } else {
+ mode = priv->ieee->mode;
+ }
+ IPW_DEBUG_QOS("QoS network/card mode %d \n", mode);
+ return mode;
+}
+
+/*
+* Handle management frame beacon and probe response
+*/
+static int ipw_qos_handle_probe_response(struct ipw_priv *priv,
+ int active_network,
+ struct ieee80211_network *network)
+{
+ u32 size = sizeof(struct ieee80211_qos_parameters);
+
+ if (network->capability & WLAN_CAPABILITY_IBSS)
+ network->qos_data.active = network->qos_data.supported;
+
+ if (network->flags & NETWORK_HAS_QOS_MASK) {
+ if (active_network &&
+ (network->flags & NETWORK_HAS_QOS_PARAMETERS))
+ network->qos_data.active = network->qos_data.supported;
+
+ if ((network->qos_data.active == 1) && (active_network == 1) &&
+ (network->flags & NETWORK_HAS_QOS_PARAMETERS) &&
+ (network->qos_data.old_param_count !=
+ network->qos_data.param_count)) {
+ network->qos_data.old_param_count =
+ network->qos_data.param_count;
+ schedule_work(&priv->qos_activate);
+ IPW_DEBUG_QOS("QoS parameters change call "
+ "qos_activate\n");
+ }
+ } else {
+ if ((priv->ieee->mode == IEEE_B) || (network->mode == IEEE_B))
+ memcpy(&network->qos_data.parameters,
+ &def_parameters_CCK, size);
+ else
+ memcpy(&network->qos_data.parameters,
+ &def_parameters_OFDM, size);
+
+ if ((network->qos_data.active == 1) && (active_network == 1)) {
+ IPW_DEBUG_QOS("QoS was disabled call qos_activate \n");
+ schedule_work(&priv->qos_activate);
+ }
+
+ network->qos_data.active = 0;
+ network->qos_data.supported = 0;
+ }
+ if ((priv->status & STATUS_ASSOCIATED) &&
+ (priv->ieee->iw_mode == IW_MODE_ADHOC) && (active_network == 0)) {
+ if (memcmp(network->bssid, priv->bssid, ETH_ALEN))
+ if ((network->capability & WLAN_CAPABILITY_IBSS) &&
+ !(network->flags & NETWORK_EMPTY_ESSID))
+ if ((network->ssid_len ==
+ priv->assoc_network->ssid_len) &&
+ !memcmp(network->ssid,
+ priv->assoc_network->ssid,
+ network->ssid_len)) {
+ queue_work(priv->workqueue,
+ &priv->merge_networks);
+ }
+ }
+
+ return 0;
+}
+
+/*
+* This function set up the firmware to support QoS. It sends
+* IPW_CMD_QOS_PARAMETERS and IPW_CMD_WME_INFO
+*/
+static int ipw_qos_activate(struct ipw_priv *priv,
+ struct ieee80211_qos_data *qos_network_data)
+{
+ int err;
+ struct ieee80211_qos_parameters qos_parameters[QOS_QOS_SETS];
+ struct ieee80211_qos_parameters *active_one = NULL;
+ u32 size = sizeof(struct ieee80211_qos_parameters);
+ u32 burst_duration;
+ int i;
+ u8 type;
+
+ type = ipw_qos_current_mode(priv);
+
+ active_one = &(qos_parameters[QOS_PARAM_SET_DEF_CCK]);
+ memcpy(active_one, priv->qos_data.def_qos_parm_CCK, size);
+ active_one = &(qos_parameters[QOS_PARAM_SET_DEF_OFDM]);
+ memcpy(active_one, priv->qos_data.def_qos_parm_OFDM, size);
+
+ if (qos_network_data == NULL) {
+ if (type == IEEE_B) {
+ IPW_DEBUG_QOS("QoS activate network mode %d\n", type);
+ active_one = &def_parameters_CCK;
+ } else
+ active_one = &def_parameters_OFDM;
+
+ memcpy(&qos_parameters[QOS_PARAM_SET_ACTIVE], active_one, size);
+ burst_duration = ipw_qos_get_burst_duration(priv);
+ for (i = 0; i < QOS_QUEUE_NUM; i++)
+ qos_parameters[QOS_PARAM_SET_ACTIVE].tx_op_limit[i] =
+ (u16) burst_duration;
+ } else if (priv->ieee->iw_mode == IW_MODE_ADHOC) {
+ if (type == IEEE_B) {
+ IPW_DEBUG_QOS("QoS activate IBSS nework mode %d\n",
+ type);
+ if (priv->qos_data.qos_enable == 0)
+ active_one = &def_parameters_CCK;
+ else
+ active_one = priv->qos_data.def_qos_parm_CCK;
+ } else {
+ if (priv->qos_data.qos_enable == 0)
+ active_one = &def_parameters_OFDM;
+ else
+ active_one = priv->qos_data.def_qos_parm_OFDM;
+ }
+ memcpy(&qos_parameters[QOS_PARAM_SET_ACTIVE], active_one, size);
+ } else {
+ unsigned long flags;
+ int active;
+
+ spin_lock_irqsave(&priv->ieee->lock, flags);
+ active_one = &(qos_network_data->parameters);
+ qos_network_data->old_param_count =
+ qos_network_data->param_count;
+ memcpy(&qos_parameters[QOS_PARAM_SET_ACTIVE], active_one, size);
+ active = qos_network_data->supported;
+ spin_unlock_irqrestore(&priv->ieee->lock, flags);
+
+ if (active == 0) {
+ burst_duration = ipw_qos_get_burst_duration(priv);
+ for (i = 0; i < QOS_QUEUE_NUM; i++)
+ qos_parameters[QOS_PARAM_SET_ACTIVE].
+ tx_op_limit[i] = (u16) burst_duration;
+ }
+ }
+
+ IPW_DEBUG_QOS("QoS sending IPW_CMD_QOS_PARAMETERS\n");
+ err = ipw_send_qos_params_command(priv,
+ (struct ieee80211_qos_parameters *)
+ &(qos_parameters[0]));
+ if (err)
+ IPW_DEBUG_QOS("QoS IPW_CMD_QOS_PARAMETERS failed\n");
+
+ return err;
+}
+
+/*
+* send IPW_CMD_WME_INFO to the firmware
+*/
+static int ipw_qos_set_info_element(struct ipw_priv *priv)
+{
+ int ret = 0;
+ struct ieee80211_qos_information_element qos_info;
+
+ if (priv == NULL)
+ return -1;
+
+ qos_info.elementID = QOS_ELEMENT_ID;
+ qos_info.length = sizeof(struct ieee80211_qos_information_element) - 2;
+
+ qos_info.version = QOS_VERSION_1;
+ qos_info.ac_info = 0;
+
+ memcpy(qos_info.qui, qos_oui, QOS_OUI_LEN);
+ qos_info.qui_type = QOS_OUI_TYPE;
+ qos_info.qui_subtype = QOS_OUI_INFO_SUB_TYPE;
+
+ ret = ipw_send_qos_info_command(priv, &qos_info);
+ if (ret != 0) {
+ IPW_DEBUG_QOS("QoS error calling ipw_send_qos_info_command\n");
+ }
+ return ret;
+}
+
+/*
+* Set the QoS parameter with the association request structure
+*/
+static int ipw_qos_association(struct ipw_priv *priv,
+ struct ieee80211_network *network)
+{
+ int err = 0;
+ struct ieee80211_qos_data *qos_data = NULL;
+ struct ieee80211_qos_data ibss_data = {
+ .supported = 1,
+ .active = 1,
+ };
+
+ switch (priv->ieee->iw_mode) {
+ case IW_MODE_ADHOC:
+ if (!(network->capability & WLAN_CAPABILITY_IBSS))
+ BUG();
+
+ qos_data = &ibss_data;
+ break;
+
+ case IW_MODE_INFRA:
+ qos_data = &network->qos_data;
+ break;
+
+ default:
+ BUG();
+ break;
+ }
+
+ err = ipw_qos_activate(priv, qos_data);
+ if (err) {
+ priv->assoc_request.policy_support &= ~HC_QOS_SUPPORT_ASSOC;
+ return err;
+ }
+
+ if (priv->qos_data.qos_enable && qos_data->supported) {
+ IPW_DEBUG_QOS("QoS will be enabled for this association\n");
+ priv->assoc_request.policy_support |= HC_QOS_SUPPORT_ASSOC;
+ return ipw_qos_set_info_element(priv);
+ }
+
+ return 0;
+}
+
+/*
+* handling the beaconing responces. if we get different QoS setting
+* of the network from the the associated setting adjust the QoS
+* setting
+*/
+static int ipw_qos_association_resp(struct ipw_priv *priv,
+ struct ieee80211_network *network)
+{
+ int ret = 0;
+ unsigned long flags;
+ u32 size = sizeof(struct ieee80211_qos_parameters);
+ int set_qos_param = 0;
+
+ if ((priv == NULL) || (network == NULL) ||
+ (priv->assoc_network == NULL))
+ return ret;
+
+ if (!(priv->status & STATUS_ASSOCIATED))
+ return ret;
+
+ if ((priv->ieee->iw_mode != IW_MODE_INFRA))
+ return ret;
+
+ spin_lock_irqsave(&priv->ieee->lock, flags);
+ if (network->flags & NETWORK_HAS_QOS_PARAMETERS) {
+ memcpy(&priv->assoc_network->qos_data, &network->qos_data,
+ sizeof(struct ieee80211_qos_data));
+ priv->assoc_network->qos_data.active = 1;
+ if ((network->qos_data.old_param_count !=
+ network->qos_data.param_count)) {
+ set_qos_param = 1;
+ network->qos_data.old_param_count =
+ network->qos_data.param_count;
+ }
+
+ } else {
+ if ((network->mode == IEEE_B) || (priv->ieee->mode == IEEE_B))
+ memcpy(&priv->assoc_network->qos_data.parameters,
+ &def_parameters_CCK, size);
+ else
+ memcpy(&priv->assoc_network->qos_data.parameters,
+ &def_parameters_OFDM, size);
+ priv->assoc_network->qos_data.active = 0;
+ priv->assoc_network->qos_data.supported = 0;
+ set_qos_param = 1;
+ }
+
+ spin_unlock_irqrestore(&priv->ieee->lock, flags);
+
+ if (set_qos_param == 1)
+ schedule_work(&priv->qos_activate);
+
+ return ret;
+}
+
+static u32 ipw_qos_get_burst_duration(struct ipw_priv *priv)
+{
+ u32 ret = 0;
+
+ if ((priv == NULL))
+ return 0;
+
+ if (!(priv->ieee->modulation & IEEE80211_OFDM_MODULATION))
+ ret = priv->qos_data.burst_duration_CCK;
+ else
+ ret = priv->qos_data.burst_duration_OFDM;
+
+ return ret;
+}
+
+/*
+* Initialize the setting of QoS global
+*/
+static void ipw_qos_init(struct ipw_priv *priv, int enable,
+ int burst_enable, u32 burst_duration_CCK,
+ u32 burst_duration_OFDM)
+{
+ priv->qos_data.qos_enable = enable;
+
+ if (priv->qos_data.qos_enable) {
+ priv->qos_data.def_qos_parm_CCK = &def_qos_parameters_CCK;
+ priv->qos_data.def_qos_parm_OFDM = &def_qos_parameters_OFDM;
+ IPW_DEBUG_QOS("QoS is enabled\n");
+ } else {
+ priv->qos_data.def_qos_parm_CCK = &def_parameters_CCK;
+ priv->qos_data.def_qos_parm_OFDM = &def_parameters_OFDM;
+ IPW_DEBUG_QOS("QoS is not enabled\n");
+ }
+
+ priv->qos_data.burst_enable = burst_enable;
+
+ if (burst_enable) {
+ priv->qos_data.burst_duration_CCK = burst_duration_CCK;
+ priv->qos_data.burst_duration_OFDM = burst_duration_OFDM;
+ } else {
+ priv->qos_data.burst_duration_CCK = 0;
+ priv->qos_data.burst_duration_OFDM = 0;
+ }
+}
+
+/*
+* map the packet priority to the right TX Queue
+*/
+static int ipw_get_tx_queue_number(struct ipw_priv *priv, u16 priority)
+{
+ if (priority > 7 || !priv->qos_data.qos_enable)
+ priority = 0;
+
+ return from_priority_to_tx_queue[priority] - 1;
+}
+
+/*
+* add QoS parameter to the TX command
+*/
+static int ipw_qos_set_tx_queue_command(struct ipw_priv *priv,
+ u16 priority,
+ struct tfd_data *tfd, u8 unicast)
+{
+ int ret = 0;
+ int tx_queue_id = 0;
+ struct ieee80211_qos_data *qos_data = NULL;
+ int active, supported;
+ unsigned long flags;
+
+ if (!(priv->status & STATUS_ASSOCIATED))
+ return 0;
+
+ qos_data = &priv->assoc_network->qos_data;
+
+ spin_lock_irqsave(&priv->ieee->lock, flags);
+
+ if (priv->ieee->iw_mode == IW_MODE_ADHOC) {
+ if (unicast == 0)
+ qos_data->active = 0;
+ else
+ qos_data->active = qos_data->supported;
+ }
+
+ active = qos_data->active;
+ supported = qos_data->supported;
+
+ spin_unlock_irqrestore(&priv->ieee->lock, flags);
+
+ IPW_DEBUG_QOS("QoS %d network is QoS active %d supported %d "
+ "unicast %d\n",
+ priv->qos_data.qos_enable, active, supported, unicast);
+ if (active && priv->qos_data.qos_enable) {
+ ret = from_priority_to_tx_queue[priority];
+ tx_queue_id = ret - 1;
+ IPW_DEBUG_QOS("QoS packet priority is %d \n", priority);
+ if (priority <= 7) {
+ tfd->tx_flags_ext |= DCT_FLAG_EXT_QOS_ENABLED;
+ tfd->tfd.tfd_26.mchdr.qos_ctrl = priority;
+ tfd->tfd.tfd_26.mchdr.frame_ctl |=
+ IEEE80211_STYPE_QOS_DATA;
+
+ if (priv->qos_data.qos_no_ack_mask &
+ (1UL << tx_queue_id)) {
+ tfd->tx_flags &= ~DCT_FLAG_ACK_REQD;
+ tfd->tfd.tfd_26.mchdr.qos_ctrl |=
+ CTRL_QOS_NO_ACK;
+ }
+ }
+ }
+
+ return ret;
+}
+
+/*
+* background support to run QoS activate functionality
+*/
+static void ipw_bg_qos_activate(void *data)
+{
+ struct ipw_priv *priv = data;
+
+ if (priv == NULL)
+ return;
+
+ down(&priv->sem);
+
+ if (priv->status & STATUS_ASSOCIATED)
+ ipw_qos_activate(priv, &(priv->assoc_network->qos_data));
+
+ up(&priv->sem);
+}
+
+static int ipw_handle_probe_response(struct net_device *dev,
+ struct ieee80211_probe_response *resp,
+ struct ieee80211_network *network)
+{
+ struct ipw_priv *priv = ieee80211_priv(dev);
+ int active_network = ((priv->status & STATUS_ASSOCIATED) &&
+ (network == priv->assoc_network));
+
+ ipw_qos_handle_probe_response(priv, active_network, network);
+
+ return 0;
+}
+
+static int ipw_handle_beacon(struct net_device *dev,
+ struct ieee80211_beacon *resp,
+ struct ieee80211_network *network)
+{
+ struct ipw_priv *priv = ieee80211_priv(dev);
+ int active_network = ((priv->status & STATUS_ASSOCIATED) &&
+ (network == priv->assoc_network));
+
+ ipw_qos_handle_probe_response(priv, active_network, network);
+
+ return 0;
+}
+
+static int ipw_handle_assoc_response(struct net_device *dev,
+ struct ieee80211_assoc_response *resp,
+ struct ieee80211_network *network)
+{
+ struct ipw_priv *priv = ieee80211_priv(dev);
+ ipw_qos_association_resp(priv, network);
+ return 0;
+}
+
+static int ipw_send_qos_params_command(struct ipw_priv *priv, struct ieee80211_qos_parameters
+ *qos_param)
+{
+ struct host_cmd cmd = {
+ .cmd = IPW_CMD_QOS_PARAMETERS,
+ .len = (sizeof(struct ieee80211_qos_parameters) * 3)
+ };
+
+ memcpy(cmd.param, qos_param, sizeof(*qos_param) * 3);
+ return ipw_send_cmd(priv, &cmd);
+}
+
+static int ipw_send_qos_info_command(struct ipw_priv *priv, struct ieee80211_qos_information_element
+ *qos_param)
+{
+ struct host_cmd cmd = {
+ .cmd = IPW_CMD_WME_INFO,
+ .len = sizeof(*qos_param)
+ };
+
+ memcpy(cmd.param, qos_param, sizeof(*qos_param));
+ return ipw_send_cmd(priv, &cmd);
+}
+
+#endif /* CONFIG_IPW_QOS */
+
static int ipw_associate_network(struct ipw_priv *priv,
struct ieee80211_network *network,
struct ipw_supported_rates *rates, int roaming)
@@ -4612,7 +7042,7 @@ static int ipw_associate_network(struct ipw_priv *priv,
int err;
if (priv->config & CFG_FIXED_RATE)
- ipw_set_fixed_rate(priv, network);
+ ipw_set_fixed_rate(priv, network->mode);
if (!(priv->config & CFG_STATIC_ESSID)) {
priv->essid_len = min(network->ssid_len,
@@ -4627,14 +7057,22 @@ static int ipw_associate_network(struct ipw_priv *priv,
if ((priv->capability & CAP_PRIVACY_ON) &&
(priv->capability & CAP_SHARED_KEY)) {
priv->assoc_request.auth_type = AUTH_SHARED_KEY;
- priv->assoc_request.auth_key = priv->sec.active_key;
+ priv->assoc_request.auth_key = priv->ieee->sec.active_key;
+
+ if ((priv->capability & CAP_PRIVACY_ON) &&
+ (priv->ieee->sec.level == SEC_LEVEL_1) &&
+ !(priv->ieee->host_encrypt || priv->ieee->host_decrypt))
+ ipw_send_wep_keys(priv, DCW_WEP_KEY_SEC_TYPE_WEP);
} else {
priv->assoc_request.auth_type = AUTH_OPEN;
priv->assoc_request.auth_key = 0;
}
- if (priv->capability & CAP_PRIVACY_ON)
- ipw_send_wep_keys(priv);
+ if (priv->ieee->wpa_ie_len) {
+ priv->assoc_request.policy_support = 0x02; /* RSN active */
+ ipw_set_rsn_capa(priv, priv->ieee->wpa_ie,
+ priv->ieee->wpa_ie_len);
+ }
/*
* It is valid for our ieee device to support multiple modes, but
@@ -4648,20 +7086,41 @@ static int ipw_associate_network(struct ipw_priv *priv,
else if (network->mode & priv->ieee->mode & IEEE_B)
priv->assoc_request.ieee_mode = IPW_B_MODE;
+ priv->assoc_request.capability = network->capability;
+ if ((network->capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
+ && !(priv->config & CFG_PREAMBLE_LONG)) {
+ priv->assoc_request.preamble_length = DCT_FLAG_SHORT_PREAMBLE;
+ } else {
+ priv->assoc_request.preamble_length = DCT_FLAG_LONG_PREAMBLE;
+
+ /* Clear the short preamble if we won't be supporting it */
+ priv->assoc_request.capability &=
+ ~WLAN_CAPABILITY_SHORT_PREAMBLE;
+ }
+
+ /* Clear capability bits that aren't used in Ad Hoc */
+ if (priv->ieee->iw_mode == IW_MODE_ADHOC)
+ priv->assoc_request.capability &=
+ ~WLAN_CAPABILITY_SHORT_SLOT_TIME;
+
IPW_DEBUG_ASSOC("%sssocation attempt: '%s', channel %d, "
- "802.11%c [%d], enc=%s%s%s%c%c\n",
+ "802.11%c [%d], %s[:%s], enc=%s%s%s%c%c\n",
roaming ? "Rea" : "A",
escape_essid(priv->essid, priv->essid_len),
network->channel,
ipw_modes[priv->assoc_request.ieee_mode],
rates->num_rates,
+ (priv->assoc_request.preamble_length ==
+ DCT_FLAG_LONG_PREAMBLE) ? "long" : "short",
+ network->capability &
+ WLAN_CAPABILITY_SHORT_PREAMBLE ? "short" : "long",
priv->capability & CAP_PRIVACY_ON ? "on " : "off",
priv->capability & CAP_PRIVACY_ON ?
(priv->capability & CAP_SHARED_KEY ? "(shared)" :
"(open)") : "",
priv->capability & CAP_PRIVACY_ON ? " key=" : "",
priv->capability & CAP_PRIVACY_ON ?
- '1' + priv->sec.active_key : '.',
+ '1' + priv->ieee->sec.active_key : '.',
priv->capability & CAP_PRIVACY_ON ? '.' : ' ');
priv->assoc_request.beacon_interval = network->beacon_interval;
@@ -4679,17 +7138,16 @@ static int ipw_associate_network(struct ipw_priv *priv,
priv->assoc_request.assoc_tsf_lsw = network->time_stamp[0];
}
- memcpy(&priv->assoc_request.bssid, network->bssid, ETH_ALEN);
+ memcpy(priv->assoc_request.bssid, network->bssid, ETH_ALEN);
if (priv->ieee->iw_mode == IW_MODE_ADHOC) {
memset(&priv->assoc_request.dest, 0xFF, ETH_ALEN);
priv->assoc_request.atim_window = network->atim_window;
} else {
- memcpy(&priv->assoc_request.dest, network->bssid, ETH_ALEN);
+ memcpy(priv->assoc_request.dest, network->bssid, ETH_ALEN);
priv->assoc_request.atim_window = 0;
}
- priv->assoc_request.capability = network->capability;
priv->assoc_request.listen_interval = network->listen_interval;
err = ipw_send_ssid(priv, priv->essid, priv->essid_len);
@@ -4706,6 +7164,12 @@ static int ipw_associate_network(struct ipw_priv *priv,
priv->sys_config.dot11g_auto_detection = 1;
else
priv->sys_config.dot11g_auto_detection = 0;
+
+ if (priv->ieee->iw_mode == IW_MODE_ADHOC)
+ priv->sys_config.answer_broadcast_ssid_probe = 1;
+ else
+ priv->sys_config.answer_broadcast_ssid_probe = 0;
+
err = ipw_send_system_config(priv, &priv->sys_config);
if (err) {
IPW_DEBUG_HC("Attempt to send sys config command failed.\n");
@@ -4713,7 +7177,7 @@ static int ipw_associate_network(struct ipw_priv *priv,
}
IPW_DEBUG_ASSOC("Association sensitivity: %d\n", network->stats.rssi);
- err = ipw_set_sensitivity(priv, network->stats.rssi);
+ err = ipw_set_sensitivity(priv, network->stats.rssi + IPW_RSSI_TO_DBM);
if (err) {
IPW_DEBUG_HC("Attempt to send associate command failed.\n");
return err;
@@ -4731,6 +7195,10 @@ static int ipw_associate_network(struct ipw_priv *priv,
priv->assoc_network = network;
+#ifdef CONFIG_IPW_QOS
+ ipw_qos_association(priv, network);
+#endif
+
err = ipw_send_associate(priv, &priv->assoc_request);
if (err) {
IPW_DEBUG_HC("Attempt to send associate command failed.\n");
@@ -4778,12 +7246,15 @@ static void ipw_roam(void *data)
if (priv->status & STATUS_ASSOCIATED) {
/* First pass through ROAM process -- look for a better
* network */
+ unsigned long flags;
u8 rssi = priv->assoc_network->stats.rssi;
priv->assoc_network->stats.rssi = -128;
+ spin_lock_irqsave(&priv->ieee->lock, flags);
list_for_each_entry(network, &priv->ieee->network_list, list) {
if (network != priv->assoc_network)
ipw_best_network(priv, &match, network, 1);
}
+ spin_unlock_irqrestore(&priv->ieee->lock, flags);
priv->assoc_network->stats.rssi = rssi;
if (match.network == priv->assoc_network) {
@@ -4806,7 +7277,15 @@ static void ipw_roam(void *data)
priv->status &= ~STATUS_ROAMING;
}
-static void ipw_associate(void *data)
+static void ipw_bg_roam(void *data)
+{
+ struct ipw_priv *priv = data;
+ down(&priv->sem);
+ ipw_roam(data);
+ up(&priv->sem);
+}
+
+static int ipw_associate(void *data)
{
struct ipw_priv *priv = data;
@@ -4816,14 +7295,41 @@ static void ipw_associate(void *data)
};
struct ipw_supported_rates *rates;
struct list_head *element;
+ unsigned long flags;
+
+ if (priv->ieee->iw_mode == IW_MODE_MONITOR) {
+ IPW_DEBUG_ASSOC("Not attempting association (monitor mode)\n");
+ return 0;
+ }
+
+ if (priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) {
+ IPW_DEBUG_ASSOC("Not attempting association (already in "
+ "progress)\n");
+ return 0;
+ }
+
+ if (priv->status & STATUS_DISASSOCIATING) {
+ IPW_DEBUG_ASSOC("Not attempting association (in "
+ "disassociating)\n ");
+ queue_work(priv->workqueue, &priv->associate);
+ return 0;
+ }
+
+ if (!ipw_is_init(priv) || (priv->status & STATUS_SCANNING)) {
+ IPW_DEBUG_ASSOC("Not attempting association (scanning or not "
+ "initialized)\n");
+ return 0;
+ }
if (!(priv->config & CFG_ASSOCIATE) &&
!(priv->config & (CFG_STATIC_ESSID |
CFG_STATIC_CHANNEL | CFG_STATIC_BSSID))) {
IPW_DEBUG_ASSOC("Not attempting association (associate=0)\n");
- return;
+ return 0;
}
+ /* Protect our use of the network_list */
+ spin_lock_irqsave(&priv->ieee->lock, flags);
list_for_each_entry(network, &priv->ieee->network_list, list)
ipw_best_network(priv, &match, network, 0);
@@ -4834,6 +7340,7 @@ static void ipw_associate(void *data)
priv->ieee->iw_mode == IW_MODE_ADHOC &&
priv->config & CFG_ADHOC_CREATE &&
priv->config & CFG_STATIC_ESSID &&
+ priv->config & CFG_STATIC_CHANNEL &&
!list_empty(&priv->ieee->network_free_list)) {
element = priv->ieee->network_free_list.next;
network = list_entry(element, struct ieee80211_network, list);
@@ -4842,25 +7349,83 @@ static void ipw_associate(void *data)
list_del(element);
list_add_tail(&network->list, &priv->ieee->network_list);
}
+ spin_unlock_irqrestore(&priv->ieee->lock, flags);
/* If we reached the end of the list, then we don't have any valid
* matching APs */
if (!network) {
ipw_debug_config(priv);
- queue_delayed_work(priv->workqueue, &priv->request_scan,
- SCAN_INTERVAL);
+ if (!(priv->status & STATUS_SCANNING)) {
+ if (!(priv->config & CFG_SPEED_SCAN))
+ queue_delayed_work(priv->workqueue,
+ &priv->request_scan,
+ SCAN_INTERVAL);
+ else
+ queue_work(priv->workqueue,
+ &priv->request_scan);
+ }
- return;
+ return 0;
}
ipw_associate_network(priv, network, rates, 0);
+
+ return 1;
}
-static inline void ipw_handle_data_packet(struct ipw_priv *priv,
- struct ipw_rx_mem_buffer *rxb,
- struct ieee80211_rx_stats *stats)
+static void ipw_bg_associate(void *data)
{
+ struct ipw_priv *priv = data;
+ down(&priv->sem);
+ ipw_associate(data);
+ up(&priv->sem);
+}
+
+static void ipw_rebuild_decrypted_skb(struct ipw_priv *priv,
+ struct sk_buff *skb)
+{
+ struct ieee80211_hdr *hdr;
+ u16 fc;
+
+ hdr = (struct ieee80211_hdr *)skb->data;
+ fc = le16_to_cpu(hdr->frame_ctl);
+ if (!(fc & IEEE80211_FCTL_PROTECTED))
+ return;
+
+ fc &= ~IEEE80211_FCTL_PROTECTED;
+ hdr->frame_ctl = cpu_to_le16(fc);
+ switch (priv->ieee->sec.level) {
+ case SEC_LEVEL_3:
+ /* Remove CCMP HDR */
+ memmove(skb->data + IEEE80211_3ADDR_LEN,
+ skb->data + IEEE80211_3ADDR_LEN + 8,
+ skb->len - IEEE80211_3ADDR_LEN - 8);
+ skb_trim(skb, skb->len - 16); /* CCMP_HDR_LEN + CCMP_MIC_LEN */
+ break;
+ case SEC_LEVEL_2:
+ break;
+ case SEC_LEVEL_1:
+ /* Remove IV */
+ memmove(skb->data + IEEE80211_3ADDR_LEN,
+ skb->data + IEEE80211_3ADDR_LEN + 4,
+ skb->len - IEEE80211_3ADDR_LEN - 4);
+ skb_trim(skb, skb->len - 8); /* IV + ICV */
+ break;
+ case SEC_LEVEL_0:
+ break;
+ default:
+ printk(KERN_ERR "Unknow security level %d\n",
+ priv->ieee->sec.level);
+ break;
+ }
+}
+
+static void ipw_handle_data_packet(struct ipw_priv *priv,
+ struct ipw_rx_mem_buffer *rxb,
+ struct ieee80211_rx_stats *stats)
+{
+ struct ieee80211_hdr_4addr *hdr;
struct ipw_rx_packet *pkt = (struct ipw_rx_packet *)rxb->skb->data;
/* We received data from the HW, so stop the watchdog */
@@ -4868,7 +7433,7 @@ static inline void ipw_handle_data_packet(struct ipw_priv *priv,
/* We only process data packets if the
* interface is open */
- if (unlikely((pkt->u.frame.length + IPW_RX_FRAME_SIZE) >
+ if (unlikely((le16_to_cpu(pkt->u.frame.length) + IPW_RX_FRAME_SIZE) >
skb_tailroom(rxb->skb))) {
priv->ieee->stats.rx_errors++;
priv->wstats.discard.misc++;
@@ -4885,14 +7450,351 @@ static inline void ipw_handle_data_packet(struct ipw_priv *priv,
skb_reserve(rxb->skb, offsetof(struct ipw_rx_packet, u.frame.data));
/* Set the size of the skb to the size of the frame */
- skb_put(rxb->skb, pkt->u.frame.length);
+ skb_put(rxb->skb, le16_to_cpu(pkt->u.frame.length));
IPW_DEBUG_RX("Rx packet of %d bytes.\n", rxb->skb->len);
+ /* HW decrypt will not clear the WEP bit, MIC, PN, etc. */
+ hdr = (struct ieee80211_hdr_4addr *)rxb->skb->data;
+ if (priv->ieee->iw_mode != IW_MODE_MONITOR &&
+ ((is_multicast_ether_addr(hdr->addr1) ||
+ is_broadcast_ether_addr(hdr->addr1)) ?
+ !priv->ieee->host_mc_decrypt : !priv->ieee->host_decrypt))
+ ipw_rebuild_decrypted_skb(priv, rxb->skb);
+
if (!ieee80211_rx(priv->ieee, rxb->skb, stats))
priv->ieee->stats.rx_errors++;
- else /* ieee80211_rx succeeded, so it now owns the SKB */
+ else { /* ieee80211_rx succeeded, so it now owns the SKB */
rxb->skb = NULL;
+ __ipw_led_activity_on(priv);
+ }
+}
+
+#ifdef CONFIG_IEEE80211_RADIOTAP
+static void ipw_handle_data_packet_monitor(struct ipw_priv *priv,
+ struct ipw_rx_mem_buffer *rxb,
+ struct ieee80211_rx_stats *stats)
+{
+ struct ipw_rx_packet *pkt = (struct ipw_rx_packet *)rxb->skb->data;
+ struct ipw_rx_frame *frame = &pkt->u.frame;
+
+ /* initial pull of some data */
+ u16 received_channel = frame->received_channel;
+ u8 antennaAndPhy = frame->antennaAndPhy;
+ s8 antsignal = frame->rssi_dbm - IPW_RSSI_TO_DBM; /* call it signed anyhow */
+ u16 pktrate = frame->rate;
+
+ /* Magic struct that slots into the radiotap header -- no reason
+ * to build this manually element by element, we can write it much
+ * more efficiently than we can parse it. ORDER MATTERS HERE */
+ struct ipw_rt_hdr {
+ struct ieee80211_radiotap_header rt_hdr;
+ u8 rt_flags; /* radiotap packet flags */
+ u8 rt_rate; /* rate in 500kb/s */
+ u16 rt_channel; /* channel in mhz */
+ u16 rt_chbitmask; /* channel bitfield */
+ s8 rt_dbmsignal; /* signal in dbM, kluged to signed */
+ u8 rt_antenna; /* antenna number */
+ } *ipw_rt;
+
+ short len = le16_to_cpu(pkt->u.frame.length);
+
+ /* We received data from the HW, so stop the watchdog */
+ priv->net_dev->trans_start = jiffies;
+
+ /* We only process data packets if the
+ * interface is open */
+ if (unlikely((le16_to_cpu(pkt->u.frame.length) + IPW_RX_FRAME_SIZE) >
+ skb_tailroom(rxb->skb))) {
+ priv->ieee->stats.rx_errors++;
+ priv->wstats.discard.misc++;
+ IPW_DEBUG_DROP("Corruption detected! Oh no!\n");
+ return;
+ } else if (unlikely(!netif_running(priv->net_dev))) {
+ priv->ieee->stats.rx_dropped++;
+ priv->wstats.discard.misc++;
+ IPW_DEBUG_DROP("Dropping packet while interface is not up.\n");
+ return;
+ }
+
+ /* Libpcap 0.9.3+ can handle variable length radiotap, so we'll use
+ * that now */
+ if (len > IPW_RX_BUF_SIZE - sizeof(struct ipw_rt_hdr)) {
+ /* FIXME: Should alloc bigger skb instead */
+ priv->ieee->stats.rx_dropped++;
+ priv->wstats.discard.misc++;
+ IPW_DEBUG_DROP("Dropping too large packet in monitor\n");
+ return;
+ }
+
+ /* copy the frame itself */
+ memmove(rxb->skb->data + sizeof(struct ipw_rt_hdr),
+ rxb->skb->data + IPW_RX_FRAME_SIZE, len);
+
+ /* Zero the radiotap static buffer ... We only need to zero the bytes NOT
+ * part of our real header, saves a little time.
+ *
+ * No longer necessary since we fill in all our data. Purge before merging
+ * patch officially.
+ * memset(rxb->skb->data + sizeof(struct ipw_rt_hdr), 0,
+ * IEEE80211_RADIOTAP_HDRLEN - sizeof(struct ipw_rt_hdr));
+ */
+
+ ipw_rt = (struct ipw_rt_hdr *)rxb->skb->data;
+
+ ipw_rt->rt_hdr.it_version = PKTHDR_RADIOTAP_VERSION;
+ ipw_rt->rt_hdr.it_pad = 0; /* always good to zero */
+ ipw_rt->rt_hdr.it_len = sizeof(struct ipw_rt_hdr); /* total header+data */
+
+ /* Big bitfield of all the fields we provide in radiotap */
+ ipw_rt->rt_hdr.it_present =
+ ((1 << IEEE80211_RADIOTAP_FLAGS) |
+ (1 << IEEE80211_RADIOTAP_RATE) |
+ (1 << IEEE80211_RADIOTAP_CHANNEL) |
+ (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) |
+ (1 << IEEE80211_RADIOTAP_ANTENNA));
+
+ /* Zero the flags, we'll add to them as we go */
+ ipw_rt->rt_flags = 0;
+
+ /* Convert signal to DBM */
+ ipw_rt->rt_dbmsignal = antsignal;
+
+ /* Convert the channel data and set the flags */
+ ipw_rt->rt_channel = cpu_to_le16(ieee80211chan2mhz(received_channel));
+ if (received_channel > 14) { /* 802.11a */
+ ipw_rt->rt_chbitmask =
+ cpu_to_le16((IEEE80211_CHAN_OFDM | IEEE80211_CHAN_5GHZ));
+ } else if (antennaAndPhy & 32) { /* 802.11b */
+ ipw_rt->rt_chbitmask =
+ cpu_to_le16((IEEE80211_CHAN_CCK | IEEE80211_CHAN_2GHZ));
+ } else { /* 802.11g */
+ ipw_rt->rt_chbitmask =
+ (IEEE80211_CHAN_OFDM | IEEE80211_CHAN_2GHZ);
+ }
+
+ /* set the rate in multiples of 500k/s */
+ switch (pktrate) {
+ case IPW_TX_RATE_1MB:
+ ipw_rt->rt_rate = 2;
+ break;
+ case IPW_TX_RATE_2MB:
+ ipw_rt->rt_rate = 4;
+ break;
+ case IPW_TX_RATE_5MB:
+ ipw_rt->rt_rate = 10;
+ break;
+ case IPW_TX_RATE_6MB:
+ ipw_rt->rt_rate = 12;
+ break;
+ case IPW_TX_RATE_9MB:
+ ipw_rt->rt_rate = 18;
+ break;
+ case IPW_TX_RATE_11MB:
+ ipw_rt->rt_rate = 22;
+ break;
+ case IPW_TX_RATE_12MB:
+ ipw_rt->rt_rate = 24;
+ break;
+ case IPW_TX_RATE_18MB:
+ ipw_rt->rt_rate = 36;
+ break;
+ case IPW_TX_RATE_24MB:
+ ipw_rt->rt_rate = 48;
+ break;
+ case IPW_TX_RATE_36MB:
+ ipw_rt->rt_rate = 72;
+ break;
+ case IPW_TX_RATE_48MB:
+ ipw_rt->rt_rate = 96;
+ break;
+ case IPW_TX_RATE_54MB:
+ ipw_rt->rt_rate = 108;
+ break;
+ default:
+ ipw_rt->rt_rate = 0;
+ break;
+ }
+
+ /* antenna number */
+ ipw_rt->rt_antenna = (antennaAndPhy & 3); /* Is this right? */
+
+ /* set the preamble flag if we have it */
+ if ((antennaAndPhy & 64))
+ ipw_rt->rt_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
+
+ /* Set the size of the skb to the size of the frame */
+ skb_put(rxb->skb, len + sizeof(struct ipw_rt_hdr));
+
+ IPW_DEBUG_RX("Rx packet of %d bytes.\n", rxb->skb->len);
+
+ if (!ieee80211_rx(priv->ieee, rxb->skb, stats))
+ priv->ieee->stats.rx_errors++;
+ else { /* ieee80211_rx succeeded, so it now owns the SKB */
+ rxb->skb = NULL;
+ /* no LED during capture */
+ }
+}
+#endif
+
+static inline int is_network_packet(struct ipw_priv *priv,
+ struct ieee80211_hdr_4addr *header)
+{
+ /* Filter incoming packets to determine if they are targetted toward
+ * this network, discarding packets coming from ourselves */
+ switch (priv->ieee->iw_mode) {
+ case IW_MODE_ADHOC: /* Header: Dest. | Source | BSSID */
+ /* packets from our adapter are dropped (echo) */
+ if (!memcmp(header->addr2, priv->net_dev->dev_addr, ETH_ALEN))
+ return 0;
+
+ /* {broad,multi}cast packets to our BSSID go through */
+ if (is_multicast_ether_addr(header->addr1) ||
+ is_broadcast_ether_addr(header->addr1))
+ return !memcmp(header->addr3, priv->bssid, ETH_ALEN);
+
+ /* packets to our adapter go through */
+ return !memcmp(header->addr1, priv->net_dev->dev_addr,
+ ETH_ALEN);
+
+ case IW_MODE_INFRA: /* Header: Dest. | BSSID | Source */
+ /* packets from our adapter are dropped (echo) */
+ if (!memcmp(header->addr3, priv->net_dev->dev_addr, ETH_ALEN))
+ return 0;
+
+ /* {broad,multi}cast packets to our BSS go through */
+ if (is_multicast_ether_addr(header->addr1) ||
+ is_broadcast_ether_addr(header->addr1))
+ return !memcmp(header->addr2, priv->bssid, ETH_ALEN);
+
+ /* packets to our adapter go through */
+ return !memcmp(header->addr1, priv->net_dev->dev_addr,
+ ETH_ALEN);
+ }
+
+ return 1;
+}
+
+#define IPW_PACKET_RETRY_TIME HZ
+
+static inline int is_duplicate_packet(struct ipw_priv *priv,
+ struct ieee80211_hdr_4addr *header)
+{
+ u16 sc = le16_to_cpu(header->seq_ctl);
+ u16 seq = WLAN_GET_SEQ_SEQ(sc);
+ u16 frag = WLAN_GET_SEQ_FRAG(sc);
+ u16 *last_seq, *last_frag;
+ unsigned long *last_time;
+
+ switch (priv->ieee->iw_mode) {
+ case IW_MODE_ADHOC:
+ {
+ struct list_head *p;
+ struct ipw_ibss_seq *entry = NULL;
+ u8 *mac = header->addr2;
+ int index = mac[5] % IPW_IBSS_MAC_HASH_SIZE;
+
+ __list_for_each(p, &priv->ibss_mac_hash[index]) {
+ entry =
+ list_entry(p, struct ipw_ibss_seq, list);
+ if (!memcmp(entry->mac, mac, ETH_ALEN))
+ break;
+ }
+ if (p == &priv->ibss_mac_hash[index]) {
+ entry = kmalloc(sizeof(*entry), GFP_ATOMIC);
+ if (!entry) {
+ IPW_ERROR
+ ("Cannot malloc new mac entry\n");
+ return 0;
+ }
+ memcpy(entry->mac, mac, ETH_ALEN);
+ entry->seq_num = seq;
+ entry->frag_num = frag;
+ entry->packet_time = jiffies;
+ list_add(&entry->list,
+ &priv->ibss_mac_hash[index]);
+ return 0;
+ }
+ last_seq = &entry->seq_num;
+ last_frag = &entry->frag_num;
+ last_time = &entry->packet_time;
+ break;
+ }
+ case IW_MODE_INFRA:
+ last_seq = &priv->last_seq_num;
+ last_frag = &priv->last_frag_num;
+ last_time = &priv->last_packet_time;
+ break;
+ default:
+ return 0;
+ }
+ if ((*last_seq == seq) &&
+ time_after(*last_time + IPW_PACKET_RETRY_TIME, jiffies)) {
+ if (*last_frag == frag)
+ goto drop;
+ if (*last_frag + 1 != frag)
+ /* out-of-order fragment */
+ goto drop;
+ } else
+ *last_seq = seq;
+
+ *last_frag = frag;
+ *last_time = jiffies;
+ return 0;
+
+ drop:
+ /* Comment this line now since we observed the card receives
+ * duplicate packets but the FCTL_RETRY bit is not set in the
+ * IBSS mode with fragmentation enabled.
+ BUG_ON(!(le16_to_cpu(header->frame_ctl) & IEEE80211_FCTL_RETRY)); */
+ return 1;
+}
+
+static void ipw_handle_mgmt_packet(struct ipw_priv *priv,
+ struct ipw_rx_mem_buffer *rxb,
+ struct ieee80211_rx_stats *stats)
+{
+ struct sk_buff *skb = rxb->skb;
+ struct ipw_rx_packet *pkt = (struct ipw_rx_packet *)skb->data;
+ struct ieee80211_hdr_4addr *header = (struct ieee80211_hdr_4addr *)
+ (skb->data + IPW_RX_FRAME_SIZE);
+
+ ieee80211_rx_mgt(priv->ieee, header, stats);
+
+ if (priv->ieee->iw_mode == IW_MODE_ADHOC &&
+ ((WLAN_FC_GET_STYPE(le16_to_cpu(header->frame_ctl)) ==
+ IEEE80211_STYPE_PROBE_RESP) ||
+ (WLAN_FC_GET_STYPE(le16_to_cpu(header->frame_ctl)) ==
+ IEEE80211_STYPE_BEACON))) {
+ if (!memcmp(header->addr3, priv->bssid, ETH_ALEN))
+ ipw_add_station(priv, header->addr2);
+ }
+
+ if (priv->config & CFG_NET_STATS) {
+ IPW_DEBUG_HC("sending stat packet\n");
+
+ /* Set the size of the skb to the size of the full
+ * ipw header and 802.11 frame */
+ skb_put(skb, le16_to_cpu(pkt->u.frame.length) +
+ IPW_RX_FRAME_SIZE);
+
+ /* Advance past the ipw packet header to the 802.11 frame */
+ skb_pull(skb, IPW_RX_FRAME_SIZE);
+
+ /* Push the ieee80211_rx_stats before the 802.11 frame */
+ memcpy(skb_push(skb, sizeof(*stats)), stats, sizeof(*stats));
+
+ skb->dev = priv->ieee->dev;
+
+ /* Point raw at the ieee80211_stats */
+ skb->mac.raw = skb->data;
+
+ skb->pkt_type = PACKET_OTHERHOST;
+ skb->protocol = __constant_htons(ETH_P_80211_STATS);
+ memset(skb->cb, 0, sizeof(rxb->skb->cb));
+ netif_rx(skb);
+ rxb->skb = NULL;
+ }
}
/*
@@ -4904,12 +7806,12 @@ static void ipw_rx(struct ipw_priv *priv)
{
struct ipw_rx_mem_buffer *rxb;
struct ipw_rx_packet *pkt;
- struct ieee80211_hdr *header;
+ struct ieee80211_hdr_4addr *header;
u32 r, w, i;
u8 network_packet;
- r = ipw_read32(priv, CX2_RX_READ_INDEX);
- w = ipw_read32(priv, CX2_RX_WRITE_INDEX);
+ r = ipw_read32(priv, IPW_RX_READ_INDEX);
+ w = ipw_read32(priv, IPW_RX_WRITE_INDEX);
i = (priv->rxq->processed + 1) % RX_QUEUE_SIZE;
while (i != r) {
@@ -4923,7 +7825,7 @@ static void ipw_rx(struct ipw_priv *priv)
priv->rxq->queue[i] = NULL;
pci_dma_sync_single_for_cpu(priv->pci_dev, rxb->dma_addr,
- CX2_RX_BUF_SIZE,
+ IPW_RX_BUF_SIZE,
PCI_DMA_FROMDEVICE);
pkt = (struct ipw_rx_packet *)rxb->skb->data;
@@ -4934,9 +7836,13 @@ static void ipw_rx(struct ipw_priv *priv)
switch (pkt->header.message_type) {
case RX_FRAME_TYPE: /* 802.11 frame */ {
struct ieee80211_rx_stats stats = {
- .rssi = pkt->u.frame.rssi_dbm -
+ .rssi =
+ le16_to_cpu(pkt->u.frame.rssi_dbm) -
IPW_RSSI_TO_DBM,
- .signal = pkt->u.frame.signal,
+ .signal =
+ le16_to_cpu(pkt->u.frame.signal),
+ .noise =
+ le16_to_cpu(pkt->u.frame.noise),
.rate = pkt->u.frame.rate,
.mac_time = jiffies,
.received_channel =
@@ -4946,63 +7852,46 @@ static void ipw_rx(struct ipw_priv *priv)
control & (1 << 0)) ?
IEEE80211_24GHZ_BAND :
IEEE80211_52GHZ_BAND,
- .len = pkt->u.frame.length,
+ .len = le16_to_cpu(pkt->u.frame.length),
};
if (stats.rssi != 0)
stats.mask |= IEEE80211_STATMASK_RSSI;
if (stats.signal != 0)
stats.mask |= IEEE80211_STATMASK_SIGNAL;
+ if (stats.noise != 0)
+ stats.mask |= IEEE80211_STATMASK_NOISE;
if (stats.rate != 0)
stats.mask |= IEEE80211_STATMASK_RATE;
priv->rx_packets++;
-#ifdef CONFIG_IPW_PROMISC
+#ifdef CONFIG_IPW2200_MONITOR
if (priv->ieee->iw_mode == IW_MODE_MONITOR) {
+#ifdef CONFIG_IEEE80211_RADIOTAP
+ ipw_handle_data_packet_monitor(priv,
+ rxb,
+ &stats);
+#else
ipw_handle_data_packet(priv, rxb,
&stats);
+#endif
break;
}
#endif
header =
- (struct ieee80211_hdr *)(rxb->skb->data +
- IPW_RX_FRAME_SIZE);
+ (struct ieee80211_hdr_4addr *)(rxb->skb->
+ data +
+ IPW_RX_FRAME_SIZE);
/* TODO: Check Ad-Hoc dest/source and make sure
* that we are actually parsing these packets
* correctly -- we should probably use the
* frame control of the packet and disregard
* the current iw_mode */
- switch (priv->ieee->iw_mode) {
- case IW_MODE_ADHOC:
- network_packet =
- !memcmp(header->addr1,
- priv->net_dev->dev_addr,
- ETH_ALEN) ||
- !memcmp(header->addr3,
- priv->bssid, ETH_ALEN) ||
- is_broadcast_ether_addr(header->
- addr1)
- || is_multicast_ether_addr(header->
- addr1);
- break;
-
- case IW_MODE_INFRA:
- default:
- network_packet =
- !memcmp(header->addr3,
- priv->bssid, ETH_ALEN) ||
- !memcmp(header->addr1,
- priv->net_dev->dev_addr,
- ETH_ALEN) ||
- is_broadcast_ether_addr(header->
- addr1)
- || is_multicast_ether_addr(header->
- addr1);
- break;
- }
+ network_packet =
+ is_network_packet(priv, header);
if (network_packet && priv->assoc_network) {
priv->assoc_network->stats.rssi =
stats.rssi;
@@ -5012,9 +7901,10 @@ static void ipw_rx(struct ipw_priv *priv)
}
IPW_DEBUG_RX("Frame: len=%u\n",
- pkt->u.frame.length);
+ le16_to_cpu(pkt->u.frame.length));
- if (pkt->u.frame.length < frame_hdr_len(header)) {
+ if (le16_to_cpu(pkt->u.frame.length) <
+ frame_hdr_len(header)) {
IPW_DEBUG_DROP
("Received packet is too small. "
"Dropping.\n");
@@ -5023,34 +7913,22 @@ static void ipw_rx(struct ipw_priv *priv)
break;
}
- switch (WLAN_FC_GET_TYPE(header->frame_ctl)) {
+ switch (WLAN_FC_GET_TYPE
+ (le16_to_cpu(header->frame_ctl))) {
+
case IEEE80211_FTYPE_MGMT:
- ieee80211_rx_mgt(priv->ieee, header,
- &stats);
- if (priv->ieee->iw_mode == IW_MODE_ADHOC
- &&
- ((WLAN_FC_GET_STYPE
- (header->frame_ctl) ==
- IEEE80211_STYPE_PROBE_RESP)
- ||
- (WLAN_FC_GET_STYPE
- (header->frame_ctl) ==
- IEEE80211_STYPE_BEACON))
- && !memcmp(header->addr3,
- priv->bssid, ETH_ALEN))
- ipw_add_station(priv,
- header->addr2);
+ ipw_handle_mgmt_packet(priv, rxb,
+ &stats);
break;
case IEEE80211_FTYPE_CTL:
break;
case IEEE80211_FTYPE_DATA:
- if (network_packet)
- ipw_handle_data_packet(priv,
- rxb,
- &stats);
- else
+ if (unlikely(!network_packet ||
+ is_duplicate_packet(priv,
+ header)))
+ {
IPW_DEBUG_DROP("Dropping: "
MAC_FMT ", "
MAC_FMT ", "
@@ -5061,6 +7939,12 @@ static void ipw_rx(struct ipw_priv *priv)
addr2),
MAC_ARG(header->
addr3));
+ break;
+ }
+
+ ipw_handle_data_packet(priv, rxb,
+ &stats);
+
break;
}
break;
@@ -5091,7 +7975,7 @@ static void ipw_rx(struct ipw_priv *priv)
}
pci_unmap_single(priv->pci_dev, rxb->dma_addr,
- CX2_RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
+ IPW_RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
list_add_tail(&rxb->list, &priv->rxq->rx_used);
i = (i + 1) % RX_QUEUE_SIZE;
@@ -5103,128 +7987,129 @@ static void ipw_rx(struct ipw_priv *priv)
ipw_rx_queue_restock(priv);
}
-static void ipw_abort_scan(struct ipw_priv *priv)
+#define DEFAULT_RTS_THRESHOLD 2304U
+#define MIN_RTS_THRESHOLD 1U
+#define MAX_RTS_THRESHOLD 2304U
+#define DEFAULT_BEACON_INTERVAL 100U
+#define DEFAULT_SHORT_RETRY_LIMIT 7U
+#define DEFAULT_LONG_RETRY_LIMIT 4U
+
+static int ipw_sw_reset(struct ipw_priv *priv, int init)
{
- int err;
+ int band, modulation;
+ int old_mode = priv->ieee->iw_mode;
- if (priv->status & STATUS_SCAN_ABORTING) {
- IPW_DEBUG_HC("Ignoring concurrent scan abort request.\n");
- return;
- }
- priv->status |= STATUS_SCAN_ABORTING;
+ /* Initialize module parameter values here */
+ priv->config = 0;
- err = ipw_send_scan_abort(priv);
- if (err)
- IPW_DEBUG_HC("Request to abort scan failed.\n");
-}
+ /* We default to disabling the LED code as right now it causes
+ * too many systems to lock up... */
+ if (!led)
+ priv->config |= CFG_NO_LED;
-static int ipw_request_scan(struct ipw_priv *priv)
-{
- struct ipw_scan_request_ext scan;
- int channel_index = 0;
- int i, err, scan_type;
+ if (associate)
+ priv->config |= CFG_ASSOCIATE;
+ else
+ IPW_DEBUG_INFO("Auto associate disabled.\n");
- if (priv->status & STATUS_EXIT_PENDING) {
- IPW_DEBUG_SCAN("Aborting scan due to device shutdown\n");
- priv->status |= STATUS_SCAN_PENDING;
- return 0;
- }
+ if (auto_create)
+ priv->config |= CFG_ADHOC_CREATE;
+ else
+ IPW_DEBUG_INFO("Auto adhoc creation disabled.\n");
- if (priv->status & STATUS_SCANNING) {
- IPW_DEBUG_HC("Concurrent scan requested. Aborting first.\n");
- priv->status |= STATUS_SCAN_PENDING;
- ipw_abort_scan(priv);
- return 0;
+ if (disable) {
+ priv->status |= STATUS_RF_KILL_SW;
+ IPW_DEBUG_INFO("Radio disabled.\n");
}
- if (priv->status & STATUS_SCAN_ABORTING) {
- IPW_DEBUG_HC("Scan request while abort pending. Queuing.\n");
- priv->status |= STATUS_SCAN_PENDING;
- return 0;
+ if (channel != 0) {
+ priv->config |= CFG_STATIC_CHANNEL;
+ priv->channel = channel;
+ IPW_DEBUG_INFO("Bind to static channel %d\n", channel);
+ /* TODO: Validate that provided channel is in range */
}
+#ifdef CONFIG_IPW_QOS
+ ipw_qos_init(priv, qos_enable, qos_burst_enable,
+ burst_duration_CCK, burst_duration_OFDM);
+#endif /* CONFIG_IPW_QOS */
- if (priv->status & STATUS_RF_KILL_MASK) {
- IPW_DEBUG_HC("Aborting scan due to RF Kill activation\n");
- priv->status |= STATUS_SCAN_PENDING;
- return 0;
+ switch (mode) {
+ case 1:
+ priv->ieee->iw_mode = IW_MODE_ADHOC;
+ priv->net_dev->type = ARPHRD_ETHER;
+
+ break;
+#ifdef CONFIG_IPW2200_MONITOR
+ case 2:
+ priv->ieee->iw_mode = IW_MODE_MONITOR;
+#ifdef CONFIG_IEEE80211_RADIOTAP
+ priv->net_dev->type = ARPHRD_IEEE80211_RADIOTAP;
+#else
+ priv->net_dev->type = ARPHRD_IEEE80211;
+#endif
+ break;
+#endif
+ default:
+ case 0:
+ priv->net_dev->type = ARPHRD_ETHER;
+ priv->ieee->iw_mode = IW_MODE_INFRA;
+ break;
}
- memset(&scan, 0, sizeof(scan));
+ if (hwcrypto) {
+ priv->ieee->host_encrypt = 0;
+ priv->ieee->host_encrypt_msdu = 0;
+ priv->ieee->host_decrypt = 0;
+ priv->ieee->host_mc_decrypt = 0;
+ }
+ IPW_DEBUG_INFO("Hardware crypto [%s]\n", hwcrypto ? "on" : "off");
- scan.dwell_time[IPW_SCAN_ACTIVE_BROADCAST_SCAN] = 20;
- scan.dwell_time[IPW_SCAN_ACTIVE_BROADCAST_AND_DIRECT_SCAN] = 20;
- scan.dwell_time[IPW_SCAN_PASSIVE_FULL_DWELL_SCAN] = 20;
-
- scan.full_scan_index = ieee80211_get_scans(priv->ieee);
- /* If we are roaming, then make this a directed scan for the current
- * network. Otherwise, ensure that every other scan is a fast
- * channel hop scan */
- if ((priv->status & STATUS_ROAMING)
- || (!(priv->status & STATUS_ASSOCIATED)
- && (priv->config & CFG_STATIC_ESSID)
- && (scan.full_scan_index % 2))) {
- err = ipw_send_ssid(priv, priv->essid, priv->essid_len);
- if (err) {
- IPW_DEBUG_HC("Attempt to send SSID command failed.\n");
- return err;
- }
+ /* IPW2200/2915 is abled to do hardware fragmentation. */
+ priv->ieee->host_open_frag = 0;
- scan_type = IPW_SCAN_ACTIVE_BROADCAST_AND_DIRECT_SCAN;
+ if ((priv->pci_dev->device == 0x4223) ||
+ (priv->pci_dev->device == 0x4224)) {
+ if (init)
+ printk(KERN_INFO DRV_NAME
+ ": Detected Intel PRO/Wireless 2915ABG Network "
+ "Connection\n");
+ priv->ieee->abg_true = 1;
+ band = IEEE80211_52GHZ_BAND | IEEE80211_24GHZ_BAND;
+ modulation = IEEE80211_OFDM_MODULATION |
+ IEEE80211_CCK_MODULATION;
+ priv->adapter = IPW_2915ABG;
+ priv->ieee->mode = IEEE_A | IEEE_G | IEEE_B;
} else {
- scan_type = IPW_SCAN_ACTIVE_BROADCAST_SCAN;
- }
-
- if (priv->ieee->freq_band & IEEE80211_52GHZ_BAND) {
- int start = channel_index;
- for (i = 0; i < MAX_A_CHANNELS; i++) {
- if (band_a_active_channel[i] == 0)
- break;
- if ((priv->status & STATUS_ASSOCIATED) &&
- band_a_active_channel[i] == priv->channel)
- continue;
- channel_index++;
- scan.channels_list[channel_index] =
- band_a_active_channel[i];
- ipw_set_scan_type(&scan, channel_index, scan_type);
- }
+ if (init)
+ printk(KERN_INFO DRV_NAME
+ ": Detected Intel PRO/Wireless 2200BG Network "
+ "Connection\n");
- if (start != channel_index) {
- scan.channels_list[start] = (u8) (IPW_A_MODE << 6) |
- (channel_index - start);
- channel_index++;
- }
+ priv->ieee->abg_true = 0;
+ band = IEEE80211_24GHZ_BAND;
+ modulation = IEEE80211_OFDM_MODULATION |
+ IEEE80211_CCK_MODULATION;
+ priv->adapter = IPW_2200BG;
+ priv->ieee->mode = IEEE_G | IEEE_B;
}
- if (priv->ieee->freq_band & IEEE80211_24GHZ_BAND) {
- int start = channel_index;
- for (i = 0; i < MAX_B_CHANNELS; i++) {
- if (band_b_active_channel[i] == 0)
- break;
- if ((priv->status & STATUS_ASSOCIATED) &&
- band_b_active_channel[i] == priv->channel)
- continue;
- channel_index++;
- scan.channels_list[channel_index] =
- band_b_active_channel[i];
- ipw_set_scan_type(&scan, channel_index, scan_type);
- }
+ priv->ieee->freq_band = band;
+ priv->ieee->modulation = modulation;
- if (start != channel_index) {
- scan.channels_list[start] = (u8) (IPW_B_MODE << 6) |
- (channel_index - start);
- }
- }
+ priv->rates_mask = IEEE80211_DEFAULT_RATES_MASK;
- err = ipw_send_scan_request_ext(priv, &scan);
- if (err) {
- IPW_DEBUG_HC("Sending scan command failed: %08X\n", err);
- return -EIO;
- }
+ priv->disassociate_threshold = IPW_MB_DISASSOCIATE_THRESHOLD_DEFAULT;
+ priv->roaming_threshold = IPW_MB_ROAMING_THRESHOLD_DEFAULT;
- priv->status |= STATUS_SCANNING;
- priv->status &= ~STATUS_SCAN_PENDING;
+ priv->rts_threshold = DEFAULT_RTS_THRESHOLD;
+ priv->short_retry_limit = DEFAULT_SHORT_RETRY_LIMIT;
+ priv->long_retry_limit = DEFAULT_LONG_RETRY_LIMIT;
- return 0;
+ /* If power management is turned on, default to AC mode */
+ priv->power_mode = IPW_POWER_AC;
+ priv->tx_power = IPW_TX_POWER_DEFAULT;
+
+ return old_mode == priv->ieee->iw_mode;
}
/*
@@ -5242,12 +8127,16 @@ static int ipw_wx_get_name(struct net_device *dev,
union iwreq_data *wrqu, char *extra)
{
struct ipw_priv *priv = ieee80211_priv(dev);
- if (!(priv->status & STATUS_ASSOCIATED))
+ down(&priv->sem);
+ if (priv->status & STATUS_RF_KILL_MASK)
+ strcpy(wrqu->name, "radio off");
+ else if (!(priv->status & STATUS_ASSOCIATED))
strcpy(wrqu->name, "unassociated");
else
snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11%c",
ipw_modes[priv->assoc_request.ieee_mode]);
IPW_DEBUG_WX("Name: %s\n", wrqu->name);
+ up(&priv->sem);
return 0;
}
@@ -5256,13 +8145,9 @@ static int ipw_set_channel(struct ipw_priv *priv, u8 channel)
if (channel == 0) {
IPW_DEBUG_INFO("Setting channel to ANY (0)\n");
priv->config &= ~CFG_STATIC_CHANNEL;
- if (!(priv->status & (STATUS_SCANNING | STATUS_ASSOCIATED |
- STATUS_ASSOCIATING))) {
- IPW_DEBUG_ASSOC("Attempting to associate with new "
- "parameters.\n");
- ipw_associate(priv);
- }
-
+ IPW_DEBUG_ASSOC("Attempting to associate with new "
+ "parameters.\n");
+ ipw_associate(priv);
return 0;
}
@@ -5277,14 +8162,32 @@ static int ipw_set_channel(struct ipw_priv *priv, u8 channel)
IPW_DEBUG_INFO("Setting channel to %i\n", (int)channel);
priv->channel = channel;
- /* If we are currently associated, or trying to associate
- * then see if this is a new channel (causing us to disassociate) */
- if (priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) {
- IPW_DEBUG_ASSOC("Disassociating due to channel change.\n");
- ipw_disassociate(priv);
- } else {
- ipw_associate(priv);
+#ifdef CONFIG_IPW2200_MONITOR
+ if (priv->ieee->iw_mode == IW_MODE_MONITOR) {
+ int i;
+ if (priv->status & STATUS_SCANNING) {
+ IPW_DEBUG_SCAN("Scan abort triggered due to "
+ "channel change.\n");
+ ipw_abort_scan(priv);
+ }
+
+ for (i = 1000; i && (priv->status & STATUS_SCANNING); i--)
+ udelay(10);
+
+ if (priv->status & STATUS_SCANNING)
+ IPW_DEBUG_SCAN("Still scanning...\n");
+ else
+ IPW_DEBUG_SCAN("Took %dms to abort current scan\n",
+ 1000 - i);
+
+ return 0;
}
+#endif /* CONFIG_IPW2200_MONITOR */
+
+ /* Network configuration changed -- force [re]association */
+ IPW_DEBUG_ASSOC("[re]association triggered due to channel change.\n");
+ if (!ipw_disassociate(priv))
+ ipw_associate(priv);
return 0;
}
@@ -5294,31 +8197,48 @@ static int ipw_wx_set_freq(struct net_device *dev,
union iwreq_data *wrqu, char *extra)
{
struct ipw_priv *priv = ieee80211_priv(dev);
+ const struct ieee80211_geo *geo = ipw_get_geo(priv->ieee);
struct iw_freq *fwrq = &wrqu->freq;
-
+ int ret = 0, i;
+ u8 channel, flags;
+ int band;
+
+ if (fwrq->m == 0) {
+ IPW_DEBUG_WX("SET Freq/Channel -> any\n");
+ down(&priv->sem);
+ ret = ipw_set_channel(priv, 0);
+ up(&priv->sem);
+ return ret;
+ }
/* if setting by freq convert to channel */
if (fwrq->e == 1) {
- if ((fwrq->m >= (int)2.412e8 && fwrq->m <= (int)2.487e8)) {
- int f = fwrq->m / 100000;
- int c = 0;
+ channel = ipw_freq_to_channel(priv->ieee, fwrq->m);
+ if (channel == 0)
+ return -EINVAL;
+ } else
+ channel = fwrq->m;
+
+ if (!(band = ipw_is_valid_channel(priv->ieee, channel)))
+ return -EINVAL;
- while ((c < REG_MAX_CHANNEL) &&
- (f != ipw_frequencies[c]))
- c++;
+ if (priv->ieee->iw_mode == IW_MODE_ADHOC) {
+ i = ipw_channel_to_index(priv->ieee, channel);
+ if (i == -1)
+ return -EINVAL;
- /* hack to fall through */
- fwrq->e = 0;
- fwrq->m = c + 1;
+ flags = (band == IEEE80211_24GHZ_BAND) ?
+ geo->bg[i].flags : geo->a[i].flags;
+ if (flags & IEEE80211_CH_PASSIVE_ONLY) {
+ IPW_DEBUG_WX("Invalid Ad-Hoc channel for 802.11a\n");
+ return -EINVAL;
}
}
- if (fwrq->e > 0 || fwrq->m > 1000)
- return -EOPNOTSUPP;
-
IPW_DEBUG_WX("SET Freq/Channel -> %d \n", fwrq->m);
- return ipw_set_channel(priv, (u8) fwrq->m);
-
- return 0;
+ down(&priv->sem);
+ ret = ipw_set_channel(priv, channel);
+ up(&priv->sem);
+ return ret;
}
static int ipw_wx_get_freq(struct net_device *dev,
@@ -5331,12 +8251,14 @@ static int ipw_wx_get_freq(struct net_device *dev,
/* If we are associated, trying to associate, or have a statically
* configured CHANNEL then return that; otherwise return ANY */
+ down(&priv->sem);
if (priv->config & CFG_STATIC_CHANNEL ||
priv->status & (STATUS_ASSOCIATING | STATUS_ASSOCIATED))
wrqu->freq.m = priv->channel;
else
wrqu->freq.m = 0;
+ up(&priv->sem);
IPW_DEBUG_WX("GET Freq/Channel -> %d \n", priv->channel);
return 0;
}
@@ -5350,11 +8272,8 @@ static int ipw_wx_set_mode(struct net_device *dev,
IPW_DEBUG_WX("Set MODE: %d\n", wrqu->mode);
- if (wrqu->mode == priv->ieee->iw_mode)
- return 0;
-
switch (wrqu->mode) {
-#ifdef CONFIG_IPW_PROMISC
+#ifdef CONFIG_IPW2200_MONITOR
case IW_MODE_MONITOR:
#endif
case IW_MODE_ADHOC:
@@ -5366,31 +8285,33 @@ static int ipw_wx_set_mode(struct net_device *dev,
default:
return -EINVAL;
}
+ if (wrqu->mode == priv->ieee->iw_mode)
+ return 0;
+
+ down(&priv->sem);
-#ifdef CONFIG_IPW_PROMISC
+ ipw_sw_reset(priv, 0);
+
+#ifdef CONFIG_IPW2200_MONITOR
if (priv->ieee->iw_mode == IW_MODE_MONITOR)
priv->net_dev->type = ARPHRD_ETHER;
if (wrqu->mode == IW_MODE_MONITOR)
+#ifdef CONFIG_IEEE80211_RADIOTAP
+ priv->net_dev->type = ARPHRD_IEEE80211_RADIOTAP;
+#else
priv->net_dev->type = ARPHRD_IEEE80211;
-#endif /* CONFIG_IPW_PROMISC */
+#endif
+#endif /* CONFIG_IPW2200_MONITOR */
-#ifdef CONFIG_PM
/* Free the existing firmware and reset the fw_loaded
* flag so ipw_load() will bring in the new firmawre */
- if (fw_loaded) {
- fw_loaded = 0;
- }
-
- release_firmware(bootfw);
- release_firmware(ucode);
- release_firmware(firmware);
- bootfw = ucode = firmware = NULL;
-#endif
+ free_firmware();
priv->ieee->iw_mode = wrqu->mode;
- ipw_adapter_restart(priv);
+ queue_work(priv->workqueue, &priv->adapter_restart);
+ up(&priv->sem);
return err;
}
@@ -5399,20 +8320,13 @@ static int ipw_wx_get_mode(struct net_device *dev,
union iwreq_data *wrqu, char *extra)
{
struct ipw_priv *priv = ieee80211_priv(dev);
-
+ down(&priv->sem);
wrqu->mode = priv->ieee->iw_mode;
IPW_DEBUG_WX("Get MODE -> %d\n", wrqu->mode);
-
+ up(&priv->sem);
return 0;
}
-#define DEFAULT_RTS_THRESHOLD 2304U
-#define MIN_RTS_THRESHOLD 1U
-#define MAX_RTS_THRESHOLD 2304U
-#define DEFAULT_BEACON_INTERVAL 100U
-#define DEFAULT_SHORT_RETRY_LIMIT 7U
-#define DEFAULT_LONG_RETRY_LIMIT 4U
-
/* Values are in microsecond */
static const s32 timeout_duration[] = {
350000,
@@ -5436,8 +8350,8 @@ static int ipw_wx_get_range(struct net_device *dev,
{
struct ipw_priv *priv = ieee80211_priv(dev);
struct iw_range *range = (struct iw_range *)extra;
- u16 val;
- int i;
+ const struct ieee80211_geo *geo = ipw_get_geo(priv->ieee);
+ int i = 0, j;
wrqu->data.length = sizeof(*range);
memset(range, 0, sizeof(*range));
@@ -5448,7 +8362,7 @@ static int ipw_wx_get_range(struct net_device *dev,
range->max_qual.qual = 100;
/* TODO: Find real max RSSI and stick here */
range->max_qual.level = 0;
- range->max_qual.noise = 0;
+ range->max_qual.noise = priv->ieee->worst_rssi + 0x100;
range->max_qual.updated = 7; /* Updated all three */
range->avg_qual.qual = 70;
@@ -5456,7 +8370,7 @@ static int ipw_wx_get_range(struct net_device *dev,
range->avg_qual.level = 0; /* FIXME to real average level */
range->avg_qual.noise = 0;
range->avg_qual.updated = 7; /* Updated all three */
-
+ down(&priv->sem);
range->num_bitrates = min(priv->rates.num_rates, (u8) IW_MAX_BITRATES);
for (i = 0; i < range->num_bitrates; i++)
@@ -5476,19 +8390,35 @@ static int ipw_wx_get_range(struct net_device *dev,
range->we_version_compiled = WIRELESS_EXT;
range->we_version_source = 16;
- range->num_channels = FREQ_COUNT;
-
- val = 0;
- for (i = 0; i < FREQ_COUNT; i++) {
- range->freq[val].i = i + 1;
- range->freq[val].m = ipw_frequencies[i] * 100000;
- range->freq[val].e = 1;
- val++;
+ i = 0;
+ if (priv->ieee->mode & (IEEE_B | IEEE_G)) {
+ for (j = 0; j < geo->bg_channels && i < IW_MAX_FREQUENCIES;
+ i++, j++) {
+ range->freq[i].i = geo->bg[j].channel;
+ range->freq[i].m = geo->bg[j].freq * 100000;
+ range->freq[i].e = 1;
+ }
+ }
- if (val == IW_MAX_FREQUENCIES)
- break;
+ if (priv->ieee->mode & IEEE_A) {
+ for (j = 0; j < geo->a_channels && i < IW_MAX_FREQUENCIES;
+ i++, j++) {
+ range->freq[i].i = geo->a[j].channel;
+ range->freq[i].m = geo->a[j].freq * 100000;
+ range->freq[i].e = 1;
+ }
}
- range->num_frequency = val;
+
+ range->num_channels = i;
+ range->num_frequency = i;
+
+ up(&priv->sem);
+
+ /* Event capability (kernel + driver) */
+ range->event_capa[0] = (IW_EVENT_CAPA_K_0 |
+ IW_EVENT_CAPA_MASK(SIOCGIWTHRSPY) |
+ IW_EVENT_CAPA_MASK(SIOCGIWAP));
+ range->event_capa[1] = IW_EVENT_CAPA_K_1;
IPW_DEBUG_WX("GET Range\n");
return 0;
@@ -5509,25 +8439,23 @@ static int ipw_wx_set_wap(struct net_device *dev,
if (wrqu->ap_addr.sa_family != ARPHRD_ETHER)
return -EINVAL;
-
+ down(&priv->sem);
if (!memcmp(any, wrqu->ap_addr.sa_data, ETH_ALEN) ||
!memcmp(off, wrqu->ap_addr.sa_data, ETH_ALEN)) {
/* we disable mandatory BSSID association */
IPW_DEBUG_WX("Setting AP BSSID to ANY\n");
priv->config &= ~CFG_STATIC_BSSID;
- if (!(priv->status & (STATUS_SCANNING | STATUS_ASSOCIATED |
- STATUS_ASSOCIATING))) {
- IPW_DEBUG_ASSOC("Attempting to associate with new "
- "parameters.\n");
- ipw_associate(priv);
- }
-
+ IPW_DEBUG_ASSOC("Attempting to associate with new "
+ "parameters.\n");
+ ipw_associate(priv);
+ up(&priv->sem);
return 0;
}
priv->config |= CFG_STATIC_BSSID;
if (!memcmp(priv->bssid, wrqu->ap_addr.sa_data, ETH_ALEN)) {
IPW_DEBUG_WX("BSSID set to current BSSID.\n");
+ up(&priv->sem);
return 0;
}
@@ -5536,15 +8464,12 @@ static int ipw_wx_set_wap(struct net_device *dev,
memcpy(priv->bssid, wrqu->ap_addr.sa_data, ETH_ALEN);
- /* If we are currently associated, or trying to associate
- * then see if this is a new BSSID (causing us to disassociate) */
- if (priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) {
- IPW_DEBUG_ASSOC("Disassociating due to BSSID change.\n");
- ipw_disassociate(priv);
- } else {
+ /* Network configuration changed -- force [re]association */
+ IPW_DEBUG_ASSOC("[re]association triggered due to BSSID change.\n");
+ if (!ipw_disassociate(priv))
ipw_associate(priv);
- }
+ up(&priv->sem);
return 0;
}
@@ -5555,15 +8480,17 @@ static int ipw_wx_get_wap(struct net_device *dev,
struct ipw_priv *priv = ieee80211_priv(dev);
/* If we are associated, trying to associate, or have a statically
* configured BSSID then return that; otherwise return ANY */
+ down(&priv->sem);
if (priv->config & CFG_STATIC_BSSID ||
priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) {
wrqu->ap_addr.sa_family = ARPHRD_ETHER;
- memcpy(wrqu->ap_addr.sa_data, &priv->bssid, ETH_ALEN);
+ memcpy(wrqu->ap_addr.sa_data, priv->bssid, ETH_ALEN);
} else
memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN);
IPW_DEBUG_WX("Getting WAP BSSID: " MAC_FMT "\n",
MAC_ARG(wrqu->ap_addr.sa_data));
+ up(&priv->sem);
return 0;
}
@@ -5574,21 +8501,22 @@ static int ipw_wx_set_essid(struct net_device *dev,
struct ipw_priv *priv = ieee80211_priv(dev);
char *essid = ""; /* ANY */
int length = 0;
-
+ down(&priv->sem);
if (wrqu->essid.flags && wrqu->essid.length) {
length = wrqu->essid.length - 1;
essid = extra;
}
if (length == 0) {
IPW_DEBUG_WX("Setting ESSID to ANY\n");
- priv->config &= ~CFG_STATIC_ESSID;
- if (!(priv->status & (STATUS_SCANNING | STATUS_ASSOCIATED |
+ if ((priv->config & CFG_STATIC_ESSID) &&
+ !(priv->status & (STATUS_ASSOCIATED |
STATUS_ASSOCIATING))) {
IPW_DEBUG_ASSOC("Attempting to associate with new "
"parameters.\n");
+ priv->config &= ~CFG_STATIC_ESSID;
ipw_associate(priv);
}
-
+ up(&priv->sem);
return 0;
}
@@ -5598,6 +8526,7 @@ static int ipw_wx_set_essid(struct net_device *dev,
if (priv->essid_len == length && !memcmp(priv->essid, extra, length)) {
IPW_DEBUG_WX("ESSID set to current ESSID.\n");
+ up(&priv->sem);
return 0;
}
@@ -5607,15 +8536,12 @@ static int ipw_wx_set_essid(struct net_device *dev,
priv->essid_len = length;
memcpy(priv->essid, essid, priv->essid_len);
- /* If we are currently associated, or trying to associate
- * then see if this is a new ESSID (causing us to disassociate) */
- if (priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) {
- IPW_DEBUG_ASSOC("Disassociating due to ESSID change.\n");
- ipw_disassociate(priv);
- } else {
+ /* Network configuration changed -- force [re]association */
+ IPW_DEBUG_ASSOC("[re]association triggered due to ESSID change.\n");
+ if (!ipw_disassociate(priv))
ipw_associate(priv);
- }
+ up(&priv->sem);
return 0;
}
@@ -5627,6 +8553,7 @@ static int ipw_wx_get_essid(struct net_device *dev,
/* If we are associated, trying to associate, or have a statically
* configured ESSID then return that; otherwise return ANY */
+ down(&priv->sem);
if (priv->config & CFG_STATIC_ESSID ||
priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) {
IPW_DEBUG_WX("Getting essid: '%s'\n",
@@ -5639,7 +8566,7 @@ static int ipw_wx_get_essid(struct net_device *dev,
wrqu->essid.length = 0;
wrqu->essid.flags = 0; /* active */
}
-
+ up(&priv->sem);
return 0;
}
@@ -5652,11 +8579,12 @@ static int ipw_wx_set_nick(struct net_device *dev,
IPW_DEBUG_WX("Setting nick to '%s'\n", extra);
if (wrqu->data.length > IW_ESSID_MAX_SIZE)
return -E2BIG;
-
+ down(&priv->sem);
wrqu->data.length = min((size_t) wrqu->data.length, sizeof(priv->nick));
memset(priv->nick, 0, sizeof(priv->nick));
memcpy(priv->nick, extra, wrqu->data.length);
IPW_DEBUG_TRACE("<<\n");
+ up(&priv->sem);
return 0;
}
@@ -5667,9 +8595,11 @@ static int ipw_wx_get_nick(struct net_device *dev,
{
struct ipw_priv *priv = ieee80211_priv(dev);
IPW_DEBUG_WX("Getting nick\n");
+ down(&priv->sem);
wrqu->data.length = strlen(priv->nick) + 1;
memcpy(extra, priv->nick, wrqu->data.length);
wrqu->data.flags = 1; /* active */
+ up(&priv->sem);
return 0;
}
@@ -5677,8 +8607,113 @@ static int ipw_wx_set_rate(struct net_device *dev,
struct iw_request_info *info,
union iwreq_data *wrqu, char *extra)
{
- IPW_DEBUG_WX("0x%p, 0x%p, 0x%p\n", dev, info, wrqu);
- return -EOPNOTSUPP;
+ /* TODO: We should use semaphores or locks for access to priv */
+ struct ipw_priv *priv = ieee80211_priv(dev);
+ u32 target_rate = wrqu->bitrate.value;
+ u32 fixed, mask;
+
+ /* value = -1, fixed = 0 means auto only, so we should use all rates offered by AP */
+ /* value = X, fixed = 1 means only rate X */
+ /* value = X, fixed = 0 means all rates lower equal X */
+
+ if (target_rate == -1) {
+ fixed = 0;
+ mask = IEEE80211_DEFAULT_RATES_MASK;
+ /* Now we should reassociate */
+ goto apply;
+ }
+
+ mask = 0;
+ fixed = wrqu->bitrate.fixed;
+
+ if (target_rate == 1000000 || !fixed)
+ mask |= IEEE80211_CCK_RATE_1MB_MASK;
+ if (target_rate == 1000000)
+ goto apply;
+
+ if (target_rate == 2000000 || !fixed)
+ mask |= IEEE80211_CCK_RATE_2MB_MASK;
+ if (target_rate == 2000000)
+ goto apply;
+
+ if (target_rate == 5500000 || !fixed)
+ mask |= IEEE80211_CCK_RATE_5MB_MASK;
+ if (target_rate == 5500000)
+ goto apply;
+
+ if (target_rate == 6000000 || !fixed)
+ mask |= IEEE80211_OFDM_RATE_6MB_MASK;
+ if (target_rate == 6000000)
+ goto apply;
+
+ if (target_rate == 9000000 || !fixed)
+ mask |= IEEE80211_OFDM_RATE_9MB_MASK;
+ if (target_rate == 9000000)
+ goto apply;
+
+ if (target_rate == 11000000 || !fixed)
+ mask |= IEEE80211_CCK_RATE_11MB_MASK;
+ if (target_rate == 11000000)
+ goto apply;
+
+ if (target_rate == 12000000 || !fixed)
+ mask |= IEEE80211_OFDM_RATE_12MB_MASK;
+ if (target_rate == 12000000)
+ goto apply;
+
+ if (target_rate == 18000000 || !fixed)
+ mask |= IEEE80211_OFDM_RATE_18MB_MASK;
+ if (target_rate == 18000000)
+ goto apply;
+
+ if (target_rate == 24000000 || !fixed)
+ mask |= IEEE80211_OFDM_RATE_24MB_MASK;
+ if (target_rate == 24000000)
+ goto apply;
+
+ if (target_rate == 36000000 || !fixed)
+ mask |= IEEE80211_OFDM_RATE_36MB_MASK;
+ if (target_rate == 36000000)
+ goto apply;
+
+ if (target_rate == 48000000 || !fixed)
+ mask |= IEEE80211_OFDM_RATE_48MB_MASK;
+ if (target_rate == 48000000)
+ goto apply;
+
+ if (target_rate == 54000000 || !fixed)
+ mask |= IEEE80211_OFDM_RATE_54MB_MASK;
+ if (target_rate == 54000000)
+ goto apply;
+
+ IPW_DEBUG_WX("invalid rate specified, returning error\n");
+ return -EINVAL;
+
+ apply:
+ IPW_DEBUG_WX("Setting rate mask to 0x%08X [%s]\n",
+ mask, fixed ? "fixed" : "sub-rates");
+ down(&priv->sem);
+ if (mask == IEEE80211_DEFAULT_RATES_MASK) {
+ priv->config &= ~CFG_FIXED_RATE;
+ ipw_set_fixed_rate(priv, priv->ieee->mode);
+ } else
+ priv->config |= CFG_FIXED_RATE;
+
+ if (priv->rates_mask == mask) {
+ IPW_DEBUG_WX("Mask set to current mask.\n");
+ up(&priv->sem);
+ return 0;
+ }
+
+ priv->rates_mask = mask;
+
+ /* Network configuration changed -- force [re]association */
+ IPW_DEBUG_ASSOC("[re]association triggered due to rates change.\n");
+ if (!ipw_disassociate(priv))
+ ipw_associate(priv);
+
+ up(&priv->sem);
+ return 0;
}
static int ipw_wx_get_rate(struct net_device *dev,
@@ -5686,8 +8721,9 @@ static int ipw_wx_get_rate(struct net_device *dev,
union iwreq_data *wrqu, char *extra)
{
struct ipw_priv *priv = ieee80211_priv(dev);
+ down(&priv->sem);
wrqu->bitrate.value = priv->last_rate;
-
+ up(&priv->sem);
IPW_DEBUG_WX("GET Rate -> %d \n", wrqu->bitrate.value);
return 0;
}
@@ -5697,18 +8733,20 @@ static int ipw_wx_set_rts(struct net_device *dev,
union iwreq_data *wrqu, char *extra)
{
struct ipw_priv *priv = ieee80211_priv(dev);
-
+ down(&priv->sem);
if (wrqu->rts.disabled)
priv->rts_threshold = DEFAULT_RTS_THRESHOLD;
else {
if (wrqu->rts.value < MIN_RTS_THRESHOLD ||
- wrqu->rts.value > MAX_RTS_THRESHOLD)
+ wrqu->rts.value > MAX_RTS_THRESHOLD) {
+ up(&priv->sem);
return -EINVAL;
-
+ }
priv->rts_threshold = wrqu->rts.value;
}
ipw_send_rts_threshold(priv, priv->rts_threshold);
+ up(&priv->sem);
IPW_DEBUG_WX("SET RTS Threshold -> %d \n", priv->rts_threshold);
return 0;
}
@@ -5718,10 +8756,11 @@ static int ipw_wx_get_rts(struct net_device *dev,
union iwreq_data *wrqu, char *extra)
{
struct ipw_priv *priv = ieee80211_priv(dev);
+ down(&priv->sem);
wrqu->rts.value = priv->rts_threshold;
wrqu->rts.fixed = 0; /* no auto select */
wrqu->rts.disabled = (wrqu->rts.value == DEFAULT_RTS_THRESHOLD);
-
+ up(&priv->sem);
IPW_DEBUG_WX("GET RTS Threshold -> %d \n", wrqu->rts.value);
return 0;
}
@@ -5731,41 +8770,33 @@ static int ipw_wx_set_txpow(struct net_device *dev,
union iwreq_data *wrqu, char *extra)
{
struct ipw_priv *priv = ieee80211_priv(dev);
- struct ipw_tx_power tx_power;
- int i;
-
- if (ipw_radio_kill_sw(priv, wrqu->power.disabled))
- return -EINPROGRESS;
-
- if (wrqu->power.flags != IW_TXPOW_DBM)
- return -EINVAL;
-
- if ((wrqu->power.value > 20) || (wrqu->power.value < -12))
- return -EINVAL;
+ int err = 0;
- priv->tx_power = wrqu->power.value;
+ down(&priv->sem);
+ if (ipw_radio_kill_sw(priv, wrqu->power.disabled)) {
+ err = -EINPROGRESS;
+ goto out;
+ }
- memset(&tx_power, 0, sizeof(tx_power));
+ if (!wrqu->power.fixed)
+ wrqu->power.value = IPW_TX_POWER_DEFAULT;
- /* configure device for 'G' band */
- tx_power.ieee_mode = IPW_G_MODE;
- tx_power.num_channels = 11;
- for (i = 0; i < 11; i++) {
- tx_power.channels_tx_power[i].channel_number = i + 1;
- tx_power.channels_tx_power[i].tx_power = priv->tx_power;
+ if (wrqu->power.flags != IW_TXPOW_DBM) {
+ err = -EINVAL;
+ goto out;
}
- if (ipw_send_tx_power(priv, &tx_power))
- goto error;
- /* configure device to also handle 'B' band */
- tx_power.ieee_mode = IPW_B_MODE;
- if (ipw_send_tx_power(priv, &tx_power))
- goto error;
-
- return 0;
+ if ((wrqu->power.value > IPW_TX_POWER_MAX) ||
+ (wrqu->power.value < IPW_TX_POWER_MIN)) {
+ err = -EINVAL;
+ goto out;
+ }
- error:
- return -EIO;
+ priv->tx_power = wrqu->power.value;
+ err = ipw_set_tx_power(priv);
+ out:
+ up(&priv->sem);
+ return err;
}
static int ipw_wx_get_txpow(struct net_device *dev,
@@ -5773,14 +8804,15 @@ static int ipw_wx_get_txpow(struct net_device *dev,
union iwreq_data *wrqu, char *extra)
{
struct ipw_priv *priv = ieee80211_priv(dev);
-
+ down(&priv->sem);
wrqu->power.value = priv->tx_power;
wrqu->power.fixed = 1;
wrqu->power.flags = IW_TXPOW_DBM;
wrqu->power.disabled = (priv->status & STATUS_RF_KILL_MASK) ? 1 : 0;
+ up(&priv->sem);
IPW_DEBUG_WX("GET TX Power -> %s %d \n",
- wrqu->power.disabled ? "ON" : "OFF", wrqu->power.value);
+ wrqu->power.disabled ? "OFF" : "ON", wrqu->power.value);
return 0;
}
@@ -5790,18 +8822,21 @@ static int ipw_wx_set_frag(struct net_device *dev,
union iwreq_data *wrqu, char *extra)
{
struct ipw_priv *priv = ieee80211_priv(dev);
-
+ down(&priv->sem);
if (wrqu->frag.disabled)
priv->ieee->fts = DEFAULT_FTS;
else {
if (wrqu->frag.value < MIN_FRAG_THRESHOLD ||
- wrqu->frag.value > MAX_FRAG_THRESHOLD)
+ wrqu->frag.value > MAX_FRAG_THRESHOLD) {
+ up(&priv->sem);
return -EINVAL;
+ }
priv->ieee->fts = wrqu->frag.value & ~0x1;
}
ipw_send_frag_threshold(priv, wrqu->frag.value);
+ up(&priv->sem);
IPW_DEBUG_WX("SET Frag Threshold -> %d \n", wrqu->frag.value);
return 0;
}
@@ -5811,10 +8846,11 @@ static int ipw_wx_get_frag(struct net_device *dev,
union iwreq_data *wrqu, char *extra)
{
struct ipw_priv *priv = ieee80211_priv(dev);
+ down(&priv->sem);
wrqu->frag.value = priv->ieee->fts;
wrqu->frag.fixed = 0; /* no auto select */
wrqu->frag.disabled = (wrqu->frag.value == DEFAULT_FTS);
-
+ up(&priv->sem);
IPW_DEBUG_WX("GET Frag Threshold -> %d \n", wrqu->frag.value);
return 0;
@@ -5824,16 +8860,128 @@ static int ipw_wx_set_retry(struct net_device *dev,
struct iw_request_info *info,
union iwreq_data *wrqu, char *extra)
{
- IPW_DEBUG_WX("0x%p, 0x%p, 0x%p\n", dev, info, wrqu);
- return -EOPNOTSUPP;
+ struct ipw_priv *priv = ieee80211_priv(dev);
+
+ if (wrqu->retry.flags & IW_RETRY_LIFETIME || wrqu->retry.disabled)
+ return -EINVAL;
+
+ if (!(wrqu->retry.flags & IW_RETRY_LIMIT))
+ return 0;
+
+ if (wrqu->retry.value < 0 || wrqu->retry.value > 255)
+ return -EINVAL;
+
+ down(&priv->sem);
+ if (wrqu->retry.flags & IW_RETRY_MIN)
+ priv->short_retry_limit = (u8) wrqu->retry.value;
+ else if (wrqu->retry.flags & IW_RETRY_MAX)
+ priv->long_retry_limit = (u8) wrqu->retry.value;
+ else {
+ priv->short_retry_limit = (u8) wrqu->retry.value;
+ priv->long_retry_limit = (u8) wrqu->retry.value;
+ }
+
+ ipw_send_retry_limit(priv, priv->short_retry_limit,
+ priv->long_retry_limit);
+ up(&priv->sem);
+ IPW_DEBUG_WX("SET retry limit -> short:%d long:%d\n",
+ priv->short_retry_limit, priv->long_retry_limit);
+ return 0;
}
static int ipw_wx_get_retry(struct net_device *dev,
struct iw_request_info *info,
union iwreq_data *wrqu, char *extra)
{
- IPW_DEBUG_WX("0x%p, 0x%p, 0x%p\n", dev, info, wrqu);
- return -EOPNOTSUPP;
+ struct ipw_priv *priv = ieee80211_priv(dev);
+
+ down(&priv->sem);
+ wrqu->retry.disabled = 0;
+
+ if ((wrqu->retry.flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) {
+ up(&priv->sem);
+ return -EINVAL;
+ }
+
+ if (wrqu->retry.flags & IW_RETRY_MAX) {
+ wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MAX;
+ wrqu->retry.value = priv->long_retry_limit;
+ } else if (wrqu->retry.flags & IW_RETRY_MIN) {
+ wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MIN;
+ wrqu->retry.value = priv->short_retry_limit;
+ } else {
+ wrqu->retry.flags = IW_RETRY_LIMIT;
+ wrqu->retry.value = priv->short_retry_limit;
+ }
+ up(&priv->sem);
+
+ IPW_DEBUG_WX("GET retry -> %d \n", wrqu->retry.value);
+
+ return 0;
+}
+
+static int ipw_request_direct_scan(struct ipw_priv *priv, char *essid,
+ int essid_len)
+{
+ struct ipw_scan_request_ext scan;
+ int err = 0, scan_type;
+
+ down(&priv->sem);
+
+ if (priv->status & STATUS_RF_KILL_MASK) {
+ IPW_DEBUG_HC("Aborting scan due to RF kill activation\n");
+ priv->status |= STATUS_SCAN_PENDING;
+ goto done;
+ }
+
+ IPW_DEBUG_HC("starting request direct scan!\n");
+
+ if (priv->status & (STATUS_SCANNING | STATUS_SCAN_ABORTING)) {
+ err = wait_event_interruptible(priv->wait_state,
+ !(priv->
+ status & (STATUS_SCANNING |
+ STATUS_SCAN_ABORTING)));
+ if (err) {
+ IPW_DEBUG_HC("aborting direct scan");
+ goto done;
+ }
+ }
+ memset(&scan, 0, sizeof(scan));
+
+ if (priv->config & CFG_SPEED_SCAN)
+ scan.dwell_time[IPW_SCAN_ACTIVE_BROADCAST_SCAN] =
+ cpu_to_le16(30);
+ else
+ scan.dwell_time[IPW_SCAN_ACTIVE_BROADCAST_SCAN] =
+ cpu_to_le16(20);
+
+ scan.dwell_time[IPW_SCAN_ACTIVE_BROADCAST_AND_DIRECT_SCAN] =
+ cpu_to_le16(20);
+ scan.dwell_time[IPW_SCAN_PASSIVE_FULL_DWELL_SCAN] = cpu_to_le16(120);
+ scan.dwell_time[IPW_SCAN_ACTIVE_DIRECT_SCAN] = cpu_to_le16(20);
+
+ scan.full_scan_index = cpu_to_le32(ieee80211_get_scans(priv->ieee));
+
+ err = ipw_send_ssid(priv, essid, essid_len);
+ if (err) {
+ IPW_DEBUG_HC("Attempt to send SSID command failed\n");
+ goto done;
+ }
+ scan_type = IPW_SCAN_ACTIVE_BROADCAST_AND_DIRECT_SCAN;
+
+ ipw_add_scan_channels(priv, &scan, scan_type);
+
+ err = ipw_send_scan_request_ext(priv, &scan);
+ if (err) {
+ IPW_DEBUG_HC("Sending scan command failed: %08X\n", err);
+ goto done;
+ }
+
+ priv->status |= STATUS_SCANNING;
+
+ done:
+ up(&priv->sem);
+ return err;
}
static int ipw_wx_set_scan(struct net_device *dev,
@@ -5841,9 +8989,21 @@ static int ipw_wx_set_scan(struct net_device *dev,
union iwreq_data *wrqu, char *extra)
{
struct ipw_priv *priv = ieee80211_priv(dev);
+ struct iw_scan_req *req = NULL;
+ if (wrqu->data.length
+ && wrqu->data.length == sizeof(struct iw_scan_req)) {
+ req = (struct iw_scan_req *)extra;
+ if (wrqu->data.flags & IW_SCAN_THIS_ESSID) {
+ ipw_request_direct_scan(priv, req->essid,
+ req->essid_len);
+ return 0;
+ }
+ }
+
IPW_DEBUG_WX("Start scan\n");
- if (ipw_request_scan(priv))
- return -EIO;
+
+ queue_work(priv->workqueue, &priv->request_scan);
+
return 0;
}
@@ -5860,7 +9020,21 @@ static int ipw_wx_set_encode(struct net_device *dev,
union iwreq_data *wrqu, char *key)
{
struct ipw_priv *priv = ieee80211_priv(dev);
- return ieee80211_wx_set_encode(priv->ieee, info, wrqu, key);
+ int ret;
+ u32 cap = priv->capability;
+
+ down(&priv->sem);
+ ret = ieee80211_wx_set_encode(priv->ieee, info, wrqu, key);
+
+ /* In IBSS mode, we need to notify the firmware to update
+ * the beacon info after we changed the capability. */
+ if (cap != priv->capability &&
+ priv->ieee->iw_mode == IW_MODE_ADHOC &&
+ priv->status & STATUS_ASSOCIATED)
+ ipw_disassociate(priv);
+
+ up(&priv->sem);
+ return ret;
}
static int ipw_wx_get_encode(struct net_device *dev,
@@ -5877,17 +9051,17 @@ static int ipw_wx_set_power(struct net_device *dev,
{
struct ipw_priv *priv = ieee80211_priv(dev);
int err;
-
+ down(&priv->sem);
if (wrqu->power.disabled) {
priv->power_mode = IPW_POWER_LEVEL(priv->power_mode);
err = ipw_send_power_mode(priv, IPW_POWER_MODE_CAM);
if (err) {
IPW_DEBUG_WX("failed setting power mode.\n");
+ up(&priv->sem);
return err;
}
-
IPW_DEBUG_WX("SET Power Management Mode -> off\n");
-
+ up(&priv->sem);
return 0;
}
@@ -5899,6 +9073,7 @@ static int ipw_wx_set_power(struct net_device *dev,
default: /* Otherwise we don't support it */
IPW_DEBUG_WX("SET PM Mode: %X not supported.\n",
wrqu->power.flags);
+ up(&priv->sem);
return -EOPNOTSUPP;
}
@@ -5911,11 +9086,12 @@ static int ipw_wx_set_power(struct net_device *dev,
err = ipw_send_power_mode(priv, IPW_POWER_LEVEL(priv->power_mode));
if (err) {
IPW_DEBUG_WX("failed setting power mode.\n");
+ up(&priv->sem);
return err;
}
IPW_DEBUG_WX("SET Power Management Mode -> 0x%02X\n", priv->power_mode);
-
+ up(&priv->sem);
return 0;
}
@@ -5924,13 +9100,13 @@ static int ipw_wx_get_power(struct net_device *dev,
union iwreq_data *wrqu, char *extra)
{
struct ipw_priv *priv = ieee80211_priv(dev);
-
- if (!(priv->power_mode & IPW_POWER_ENABLED)) {
+ down(&priv->sem);
+ if (!(priv->power_mode & IPW_POWER_ENABLED))
wrqu->power.disabled = 1;
- } else {
+ else
wrqu->power.disabled = 0;
- }
+ up(&priv->sem);
IPW_DEBUG_WX("GET Power Management Mode -> %02X\n", priv->power_mode);
return 0;
@@ -5943,7 +9119,7 @@ static int ipw_wx_set_powermode(struct net_device *dev,
struct ipw_priv *priv = ieee80211_priv(dev);
int mode = *(int *)extra;
int err;
-
+ down(&priv->sem);
if ((mode < 1) || (mode > IPW_POWER_LIMIT)) {
mode = IPW_POWER_AC;
priv->power_mode = mode;
@@ -5956,10 +9132,11 @@ static int ipw_wx_set_powermode(struct net_device *dev,
if (err) {
IPW_DEBUG_WX("failed setting power mode.\n");
+ up(&priv->sem);
return err;
}
}
-
+ up(&priv->sem);
return 0;
}
@@ -6008,55 +9185,56 @@ static int ipw_wx_set_wireless_mode(struct net_device *dev,
IPW_WARNING("Attempt to set invalid wireless mode: %d\n", mode);
return -EINVAL;
}
-
+ down(&priv->sem);
if (priv->adapter == IPW_2915ABG) {
- priv->ieee->abg_ture = 1;
+ priv->ieee->abg_true = 1;
if (mode & IEEE_A) {
band |= IEEE80211_52GHZ_BAND;
modulation |= IEEE80211_OFDM_MODULATION;
} else
- priv->ieee->abg_ture = 0;
+ priv->ieee->abg_true = 0;
} else {
if (mode & IEEE_A) {
IPW_WARNING("Attempt to set 2200BG into "
"802.11a mode\n");
+ up(&priv->sem);
return -EINVAL;
}
- priv->ieee->abg_ture = 0;
+ priv->ieee->abg_true = 0;
}
if (mode & IEEE_B) {
band |= IEEE80211_24GHZ_BAND;
modulation |= IEEE80211_CCK_MODULATION;
} else
- priv->ieee->abg_ture = 0;
+ priv->ieee->abg_true = 0;
if (mode & IEEE_G) {
band |= IEEE80211_24GHZ_BAND;
modulation |= IEEE80211_OFDM_MODULATION;
} else
- priv->ieee->abg_ture = 0;
+ priv->ieee->abg_true = 0;
priv->ieee->mode = mode;
priv->ieee->freq_band = band;
priv->ieee->modulation = modulation;
init_supported_rates(priv, &priv->rates);
- /* If we are currently associated, or trying to associate
- * then see if this is a new configuration (causing us to
- * disassociate) */
- if (priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) {
- /* The resulting association will trigger
- * the new rates to be sent to the device */
- IPW_DEBUG_ASSOC("Disassociating due to mode change.\n");
- ipw_disassociate(priv);
- } else
+ /* Network configuration changed -- force [re]association */
+ IPW_DEBUG_ASSOC("[re]association triggered due to mode change.\n");
+ if (!ipw_disassociate(priv)) {
ipw_send_supported_rates(priv, &priv->rates);
+ ipw_associate(priv);
+ }
+
+ /* Update the band LEDs */
+ ipw_led_band_on(priv);
IPW_DEBUG_WX("PRIV SET MODE: %c%c%c\n",
mode & IEEE_A ? 'a' : '.',
mode & IEEE_B ? 'b' : '.', mode & IEEE_G ? 'g' : '.');
+ up(&priv->sem);
return 0;
}
@@ -6065,124 +9243,234 @@ static int ipw_wx_get_wireless_mode(struct net_device *dev,
union iwreq_data *wrqu, char *extra)
{
struct ipw_priv *priv = ieee80211_priv(dev);
-
- switch (priv->ieee->freq_band) {
- case IEEE80211_24GHZ_BAND:
- switch (priv->ieee->modulation) {
- case IEEE80211_CCK_MODULATION:
- strncpy(extra, "802.11b (2)", MAX_WX_STRING);
- break;
- case IEEE80211_OFDM_MODULATION:
- strncpy(extra, "802.11g (4)", MAX_WX_STRING);
- break;
- default:
- strncpy(extra, "802.11bg (6)", MAX_WX_STRING);
- break;
- }
- break;
-
- case IEEE80211_52GHZ_BAND:
+ down(&priv->sem);
+ switch (priv->ieee->mode) {
+ case IEEE_A:
strncpy(extra, "802.11a (1)", MAX_WX_STRING);
break;
-
- default: /* Mixed Band */
- switch (priv->ieee->modulation) {
- case IEEE80211_CCK_MODULATION:
- strncpy(extra, "802.11ab (3)", MAX_WX_STRING);
- break;
- case IEEE80211_OFDM_MODULATION:
- strncpy(extra, "802.11ag (5)", MAX_WX_STRING);
- break;
- default:
- strncpy(extra, "802.11abg (7)", MAX_WX_STRING);
- break;
- }
+ case IEEE_B:
+ strncpy(extra, "802.11b (2)", MAX_WX_STRING);
+ break;
+ case IEEE_A | IEEE_B:
+ strncpy(extra, "802.11ab (3)", MAX_WX_STRING);
+ break;
+ case IEEE_G:
+ strncpy(extra, "802.11g (4)", MAX_WX_STRING);
+ break;
+ case IEEE_A | IEEE_G:
+ strncpy(extra, "802.11ag (5)", MAX_WX_STRING);
+ break;
+ case IEEE_B | IEEE_G:
+ strncpy(extra, "802.11bg (6)", MAX_WX_STRING);
+ break;
+ case IEEE_A | IEEE_B | IEEE_G:
+ strncpy(extra, "802.11abg (7)", MAX_WX_STRING);
+ break;
+ default:
+ strncpy(extra, "unknown", MAX_WX_STRING);
break;
}
IPW_DEBUG_WX("PRIV GET MODE: %s\n", extra);
wrqu->data.length = strlen(extra) + 1;
+ up(&priv->sem);
+
+ return 0;
+}
+
+static int ipw_wx_set_preamble(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct ipw_priv *priv = ieee80211_priv(dev);
+ int mode = *(int *)extra;
+ down(&priv->sem);
+ /* Switching from SHORT -> LONG requires a disassociation */
+ if (mode == 1) {
+ if (!(priv->config & CFG_PREAMBLE_LONG)) {
+ priv->config |= CFG_PREAMBLE_LONG;
+
+ /* Network configuration changed -- force [re]association */
+ IPW_DEBUG_ASSOC
+ ("[re]association triggered due to preamble change.\n");
+ if (!ipw_disassociate(priv))
+ ipw_associate(priv);
+ }
+ goto done;
+ }
+
+ if (mode == 0) {
+ priv->config &= ~CFG_PREAMBLE_LONG;
+ goto done;
+ }
+ up(&priv->sem);
+ return -EINVAL;
+ done:
+ up(&priv->sem);
return 0;
}
-#ifdef CONFIG_IPW_PROMISC
-static int ipw_wx_set_promisc(struct net_device *dev,
+static int ipw_wx_get_preamble(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct ipw_priv *priv = ieee80211_priv(dev);
+ down(&priv->sem);
+ if (priv->config & CFG_PREAMBLE_LONG)
+ snprintf(wrqu->name, IFNAMSIZ, "long (1)");
+ else
+ snprintf(wrqu->name, IFNAMSIZ, "auto (0)");
+ up(&priv->sem);
+ return 0;
+}
+
+#ifdef CONFIG_IPW2200_MONITOR
+static int ipw_wx_set_monitor(struct net_device *dev,
struct iw_request_info *info,
union iwreq_data *wrqu, char *extra)
{
struct ipw_priv *priv = ieee80211_priv(dev);
int *parms = (int *)extra;
int enable = (parms[0] > 0);
-
- IPW_DEBUG_WX("SET PROMISC: %d %d\n", enable, parms[1]);
+ down(&priv->sem);
+ IPW_DEBUG_WX("SET MONITOR: %d %d\n", enable, parms[1]);
if (enable) {
if (priv->ieee->iw_mode != IW_MODE_MONITOR) {
+#ifdef CONFIG_IEEE80211_RADIOTAP
+ priv->net_dev->type = ARPHRD_IEEE80211_RADIOTAP;
+#else
priv->net_dev->type = ARPHRD_IEEE80211;
- ipw_adapter_restart(priv);
+#endif
+ queue_work(priv->workqueue, &priv->adapter_restart);
}
ipw_set_channel(priv, parms[1]);
} else {
- if (priv->ieee->iw_mode != IW_MODE_MONITOR)
+ if (priv->ieee->iw_mode != IW_MODE_MONITOR) {
+ up(&priv->sem);
return 0;
+ }
priv->net_dev->type = ARPHRD_ETHER;
- ipw_adapter_restart(priv);
+ queue_work(priv->workqueue, &priv->adapter_restart);
}
+ up(&priv->sem);
return 0;
}
+#endif // CONFIG_IPW2200_MONITOR
+
static int ipw_wx_reset(struct net_device *dev,
struct iw_request_info *info,
union iwreq_data *wrqu, char *extra)
{
struct ipw_priv *priv = ieee80211_priv(dev);
IPW_DEBUG_WX("RESET\n");
- ipw_adapter_restart(priv);
+ queue_work(priv->workqueue, &priv->adapter_restart);
+ return 0;
+}
+
+static int ipw_wx_sw_reset(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct ipw_priv *priv = ieee80211_priv(dev);
+ union iwreq_data wrqu_sec = {
+ .encoding = {
+ .flags = IW_ENCODE_DISABLED,
+ },
+ };
+ int ret;
+
+ IPW_DEBUG_WX("SW_RESET\n");
+
+ down(&priv->sem);
+
+ ret = ipw_sw_reset(priv, 0);
+ if (!ret) {
+ free_firmware();
+ ipw_adapter_restart(priv);
+ }
+
+ /* The SW reset bit might have been toggled on by the 'disable'
+ * module parameter, so take appropriate action */
+ ipw_radio_kill_sw(priv, priv->status & STATUS_RF_KILL_SW);
+
+ up(&priv->sem);
+ ieee80211_wx_set_encode(priv->ieee, info, &wrqu_sec, NULL);
+ down(&priv->sem);
+
+ if (!(priv->status & STATUS_RF_KILL_MASK)) {
+ /* Configuration likely changed -- force [re]association */
+ IPW_DEBUG_ASSOC("[re]association triggered due to sw "
+ "reset.\n");
+ if (!ipw_disassociate(priv))
+ ipw_associate(priv);
+ }
+
+ up(&priv->sem);
+
return 0;
}
-#endif // CONFIG_IPW_PROMISC
/* Rebase the WE IOCTLs to zero for the handler array */
#define IW_IOCTL(x) [(x)-SIOCSIWCOMMIT]
static iw_handler ipw_wx_handlers[] = {
- IW_IOCTL(SIOCGIWNAME) = ipw_wx_get_name,
- IW_IOCTL(SIOCSIWFREQ) = ipw_wx_set_freq,
- IW_IOCTL(SIOCGIWFREQ) = ipw_wx_get_freq,
- IW_IOCTL(SIOCSIWMODE) = ipw_wx_set_mode,
- IW_IOCTL(SIOCGIWMODE) = ipw_wx_get_mode,
- IW_IOCTL(SIOCGIWRANGE) = ipw_wx_get_range,
- IW_IOCTL(SIOCSIWAP) = ipw_wx_set_wap,
- IW_IOCTL(SIOCGIWAP) = ipw_wx_get_wap,
- IW_IOCTL(SIOCSIWSCAN) = ipw_wx_set_scan,
- IW_IOCTL(SIOCGIWSCAN) = ipw_wx_get_scan,
- IW_IOCTL(SIOCSIWESSID) = ipw_wx_set_essid,
- IW_IOCTL(SIOCGIWESSID) = ipw_wx_get_essid,
- IW_IOCTL(SIOCSIWNICKN) = ipw_wx_set_nick,
- IW_IOCTL(SIOCGIWNICKN) = ipw_wx_get_nick,
- IW_IOCTL(SIOCSIWRATE) = ipw_wx_set_rate,
- IW_IOCTL(SIOCGIWRATE) = ipw_wx_get_rate,
- IW_IOCTL(SIOCSIWRTS) = ipw_wx_set_rts,
- IW_IOCTL(SIOCGIWRTS) = ipw_wx_get_rts,
- IW_IOCTL(SIOCSIWFRAG) = ipw_wx_set_frag,
- IW_IOCTL(SIOCGIWFRAG) = ipw_wx_get_frag,
- IW_IOCTL(SIOCSIWTXPOW) = ipw_wx_set_txpow,
- IW_IOCTL(SIOCGIWTXPOW) = ipw_wx_get_txpow,
- IW_IOCTL(SIOCSIWRETRY) = ipw_wx_set_retry,
- IW_IOCTL(SIOCGIWRETRY) = ipw_wx_get_retry,
- IW_IOCTL(SIOCSIWENCODE) = ipw_wx_set_encode,
- IW_IOCTL(SIOCGIWENCODE) = ipw_wx_get_encode,
- IW_IOCTL(SIOCSIWPOWER) = ipw_wx_set_power,
- IW_IOCTL(SIOCGIWPOWER) = ipw_wx_get_power,
+ IW_IOCTL(SIOCGIWNAME) = ipw_wx_get_name,
+ IW_IOCTL(SIOCSIWFREQ) = ipw_wx_set_freq,
+ IW_IOCTL(SIOCGIWFREQ) = ipw_wx_get_freq,
+ IW_IOCTL(SIOCSIWMODE) = ipw_wx_set_mode,
+ IW_IOCTL(SIOCGIWMODE) = ipw_wx_get_mode,
+ IW_IOCTL(SIOCGIWRANGE) = ipw_wx_get_range,
+ IW_IOCTL(SIOCSIWAP) = ipw_wx_set_wap,
+ IW_IOCTL(SIOCGIWAP) = ipw_wx_get_wap,
+ IW_IOCTL(SIOCSIWSCAN) = ipw_wx_set_scan,
+ IW_IOCTL(SIOCGIWSCAN) = ipw_wx_get_scan,
+ IW_IOCTL(SIOCSIWESSID) = ipw_wx_set_essid,
+ IW_IOCTL(SIOCGIWESSID) = ipw_wx_get_essid,
+ IW_IOCTL(SIOCSIWNICKN) = ipw_wx_set_nick,
+ IW_IOCTL(SIOCGIWNICKN) = ipw_wx_get_nick,
+ IW_IOCTL(SIOCSIWRATE) = ipw_wx_set_rate,
+ IW_IOCTL(SIOCGIWRATE) = ipw_wx_get_rate,
+ IW_IOCTL(SIOCSIWRTS) = ipw_wx_set_rts,
+ IW_IOCTL(SIOCGIWRTS) = ipw_wx_get_rts,
+ IW_IOCTL(SIOCSIWFRAG) = ipw_wx_set_frag,
+ IW_IOCTL(SIOCGIWFRAG) = ipw_wx_get_frag,
+ IW_IOCTL(SIOCSIWTXPOW) = ipw_wx_set_txpow,
+ IW_IOCTL(SIOCGIWTXPOW) = ipw_wx_get_txpow,
+ IW_IOCTL(SIOCSIWRETRY) = ipw_wx_set_retry,
+ IW_IOCTL(SIOCGIWRETRY) = ipw_wx_get_retry,
+ IW_IOCTL(SIOCSIWENCODE) = ipw_wx_set_encode,
+ IW_IOCTL(SIOCGIWENCODE) = ipw_wx_get_encode,
+ IW_IOCTL(SIOCSIWPOWER) = ipw_wx_set_power,
+ IW_IOCTL(SIOCGIWPOWER) = ipw_wx_get_power,
+ IW_IOCTL(SIOCSIWSPY) = iw_handler_set_spy,
+ IW_IOCTL(SIOCGIWSPY) = iw_handler_get_spy,
+ IW_IOCTL(SIOCSIWTHRSPY) = iw_handler_set_thrspy,
+ IW_IOCTL(SIOCGIWTHRSPY) = iw_handler_get_thrspy,
+ IW_IOCTL(SIOCSIWGENIE) = ipw_wx_set_genie,
+ IW_IOCTL(SIOCGIWGENIE) = ipw_wx_get_genie,
+ IW_IOCTL(SIOCSIWMLME) = ipw_wx_set_mlme,
+ IW_IOCTL(SIOCSIWAUTH) = ipw_wx_set_auth,
+ IW_IOCTL(SIOCGIWAUTH) = ipw_wx_get_auth,
+ IW_IOCTL(SIOCSIWENCODEEXT) = ipw_wx_set_encodeext,
+ IW_IOCTL(SIOCGIWENCODEEXT) = ipw_wx_get_encodeext,
};
-#define IPW_PRIV_SET_POWER SIOCIWFIRSTPRIV
-#define IPW_PRIV_GET_POWER SIOCIWFIRSTPRIV+1
-#define IPW_PRIV_SET_MODE SIOCIWFIRSTPRIV+2
-#define IPW_PRIV_GET_MODE SIOCIWFIRSTPRIV+3
-#define IPW_PRIV_SET_PROMISC SIOCIWFIRSTPRIV+4
-#define IPW_PRIV_RESET SIOCIWFIRSTPRIV+5
+enum {
+ IPW_PRIV_SET_POWER = SIOCIWFIRSTPRIV,
+ IPW_PRIV_GET_POWER,
+ IPW_PRIV_SET_MODE,
+ IPW_PRIV_GET_MODE,
+ IPW_PRIV_SET_PREAMBLE,
+ IPW_PRIV_GET_PREAMBLE,
+ IPW_PRIV_RESET,
+ IPW_PRIV_SW_RESET,
+#ifdef CONFIG_IPW2200_MONITOR
+ IPW_PRIV_SET_MONITOR,
+#endif
+};
static struct iw_priv_args ipw_priv_args[] = {
{
@@ -6201,14 +9489,25 @@ static struct iw_priv_args ipw_priv_args[] = {
.cmd = IPW_PRIV_GET_MODE,
.get_args = IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | MAX_WX_STRING,
.name = "get_mode"},
-#ifdef CONFIG_IPW_PROMISC
{
- IPW_PRIV_SET_PROMISC,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "monitor"},
+ .cmd = IPW_PRIV_SET_PREAMBLE,
+ .set_args = IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+ .name = "set_preamble"},
+ {
+ .cmd = IPW_PRIV_GET_PREAMBLE,
+ .get_args = IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | IFNAMSIZ,
+ .name = "get_preamble"},
{
IPW_PRIV_RESET,
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 0, 0, "reset"},
-#endif /* CONFIG_IPW_PROMISC */
+ {
+ IPW_PRIV_SW_RESET,
+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 0, 0, "sw_reset"},
+#ifdef CONFIG_IPW2200_MONITOR
+ {
+ IPW_PRIV_SET_MONITOR,
+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "monitor"},
+#endif /* CONFIG_IPW2200_MONITOR */
};
static iw_handler ipw_priv_handler[] = {
@@ -6216,19 +9515,23 @@ static iw_handler ipw_priv_handler[] = {
ipw_wx_get_powermode,
ipw_wx_set_wireless_mode,
ipw_wx_get_wireless_mode,
-#ifdef CONFIG_IPW_PROMISC
- ipw_wx_set_promisc,
+ ipw_wx_set_preamble,
+ ipw_wx_get_preamble,
ipw_wx_reset,
+ ipw_wx_sw_reset,
+#ifdef CONFIG_IPW2200_MONITOR
+ ipw_wx_set_monitor,
#endif
};
static struct iw_handler_def ipw_wx_handler_def = {
- .standard = ipw_wx_handlers,
- .num_standard = ARRAY_SIZE(ipw_wx_handlers),
- .num_private = ARRAY_SIZE(ipw_priv_handler),
- .num_private_args = ARRAY_SIZE(ipw_priv_args),
- .private = ipw_priv_handler,
- .private_args = ipw_priv_args,
+ .standard = ipw_wx_handlers,
+ .num_standard = ARRAY_SIZE(ipw_wx_handlers),
+ .num_private = ARRAY_SIZE(ipw_priv_handler),
+ .num_private_args = ARRAY_SIZE(ipw_priv_args),
+ .private = ipw_priv_handler,
+ .private_args = ipw_priv_args,
+ .get_wireless_stats = ipw_get_wireless_stats,
};
/*
@@ -6243,8 +9546,8 @@ static struct iw_statistics *ipw_get_wireless_stats(struct net_device *dev)
wstats = &priv->wstats;
- /* if hw is disabled, then ipw2100_get_ordinal() can't be called.
- * ipw2100_wx_wireless_stats seems to be called before fw is
+ /* if hw is disabled, then ipw_get_ordinal() can't be called.
+ * netdev->get_wireless_stats seems to be called before fw is
* initialized. STATUS_ASSOCIATED will only be set if the hw is up
* and associated; if not associcated, the values are all meaningless
* anyway, so set them all to NULL and INVALID */
@@ -6295,7 +9598,7 @@ static inline void init_sys_config(struct ipw_sys_config *sys_config)
sys_config->dot11g_auto_detection = 0;
sys_config->enable_cts_to_self = 0;
sys_config->bt_coexist_collision_thr = 0;
- sys_config->pass_noise_stats_to_host = 1;
+ sys_config->pass_noise_stats_to_host = 1; //1 -- fix for 256
}
static int ipw_net_open(struct net_device *dev)
@@ -6303,9 +9606,11 @@ static int ipw_net_open(struct net_device *dev)
struct ipw_priv *priv = ieee80211_priv(dev);
IPW_DEBUG_INFO("dev->open\n");
/* we should be verifying the device is ready to be opened */
+ down(&priv->sem);
if (!(priv->status & STATUS_RF_KILL_MASK) &&
(priv->status & STATUS_ASSOCIATED))
netif_start_queue(dev);
+ up(&priv->sem);
return 0;
}
@@ -6323,22 +9628,34 @@ modify to send one tfd per fragment instead of using chunking. otherwise
we need to heavily modify the ieee80211_skb_to_txb.
*/
-static inline void ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb)
+static inline int ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb,
+ int pri)
{
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)
+ struct ieee80211_hdr_3addr *hdr = (struct ieee80211_hdr_3addr *)
txb->fragments[0]->data;
int i = 0;
struct tfd_frame *tfd;
+#ifdef CONFIG_IPW_QOS
+ int tx_id = ipw_get_tx_queue_number(priv, pri);
+ struct clx2_tx_queue *txq = &priv->txq[tx_id];
+#else
struct clx2_tx_queue *txq = &priv->txq[0];
+#endif
struct clx2_queue *q = &txq->q;
u8 id, hdr_len, unicast;
u16 remaining_bytes;
+ int fc;
+
+ /* If there isn't room in the queue, we return busy and let the
+ * network stack requeue the packet for us */
+ if (ipw_queue_space(q) < q->high_mark)
+ return NETDEV_TX_BUSY;
switch (priv->ieee->iw_mode) {
case IW_MODE_ADHOC:
hdr_len = IEEE80211_3ADDR_LEN;
- unicast = !is_broadcast_ether_addr(hdr->addr1) &&
- !is_multicast_ether_addr(hdr->addr1);
+ unicast = !(is_multicast_ether_addr(hdr->addr1) ||
+ is_broadcast_ether_addr(hdr->addr1));
id = ipw_find_station(priv, hdr->addr1);
if (id == IPW_INVALID_STATION) {
id = ipw_add_station(priv, hdr->addr1);
@@ -6353,8 +9670,8 @@ static inline void ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb)
case IW_MODE_INFRA:
default:
- unicast = !is_broadcast_ether_addr(hdr->addr3) &&
- !is_multicast_ether_addr(hdr->addr3);
+ unicast = !(is_multicast_ether_addr(hdr->addr3) ||
+ is_broadcast_ether_addr(hdr->addr3));
hdr_len = IEEE80211_3ADDR_LEN;
id = 0;
break;
@@ -6369,26 +9686,83 @@ static inline void ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb)
tfd->control_flags.control_bits = TFD_NEED_IRQ_MASK;
tfd->u.data.cmd_id = DINO_CMD_TX;
- tfd->u.data.len = txb->payload_size;
+ tfd->u.data.len = cpu_to_le16(txb->payload_size);
remaining_bytes = txb->payload_size;
- if (unlikely(!unicast))
- tfd->u.data.tx_flags = DCT_FLAG_NO_WEP;
- else
- tfd->u.data.tx_flags = DCT_FLAG_NO_WEP | DCT_FLAG_ACK_REQD;
if (priv->assoc_request.ieee_mode == IPW_B_MODE)
- tfd->u.data.tx_flags_ext = DCT_FLAG_EXT_MODE_CCK;
+ tfd->u.data.tx_flags_ext |= DCT_FLAG_EXT_MODE_CCK;
else
- tfd->u.data.tx_flags_ext = DCT_FLAG_EXT_MODE_OFDM;
+ tfd->u.data.tx_flags_ext |= DCT_FLAG_EXT_MODE_OFDM;
+
+ if (priv->assoc_request.preamble_length == DCT_FLAG_SHORT_PREAMBLE)
+ tfd->u.data.tx_flags |= DCT_FLAG_SHORT_PREAMBLE;
- if (priv->config & CFG_PREAMBLE)
- tfd->u.data.tx_flags |= DCT_FLAG_SHORT_PREMBL;
+ fc = le16_to_cpu(hdr->frame_ctl);
+ hdr->frame_ctl = cpu_to_le16(fc & ~IEEE80211_FCTL_MOREFRAGS);
memcpy(&tfd->u.data.tfd.tfd_24.mchdr, hdr, hdr_len);
+ if (likely(unicast))
+ tfd->u.data.tx_flags |= DCT_FLAG_ACK_REQD;
+
+ if (txb->encrypted && !priv->ieee->host_encrypt) {
+ switch (priv->ieee->sec.level) {
+ case SEC_LEVEL_3:
+ tfd->u.data.tfd.tfd_24.mchdr.frame_ctl |=
+ IEEE80211_FCTL_PROTECTED;
+ /* XXX: ACK flag must be set for CCMP even if it
+ * is a multicast/broadcast packet, because CCMP
+ * group communication encrypted by GTK is
+ * actually done by the AP. */
+ if (!unicast)
+ tfd->u.data.tx_flags |= DCT_FLAG_ACK_REQD;
+
+ tfd->u.data.tx_flags &= ~DCT_FLAG_NO_WEP;
+ tfd->u.data.tx_flags_ext |= DCT_FLAG_EXT_SECURITY_CCM;
+ tfd->u.data.key_index = 0;
+ tfd->u.data.key_index |= DCT_WEP_INDEX_USE_IMMEDIATE;
+ break;
+ case SEC_LEVEL_2:
+ tfd->u.data.tfd.tfd_24.mchdr.frame_ctl |=
+ IEEE80211_FCTL_PROTECTED;
+ tfd->u.data.tx_flags &= ~DCT_FLAG_NO_WEP;
+ tfd->u.data.tx_flags_ext |= DCT_FLAG_EXT_SECURITY_TKIP;
+ tfd->u.data.key_index = DCT_WEP_INDEX_USE_IMMEDIATE;
+ break;
+ case SEC_LEVEL_1:
+ tfd->u.data.tfd.tfd_24.mchdr.frame_ctl |=
+ IEEE80211_FCTL_PROTECTED;
+ tfd->u.data.key_index = priv->ieee->tx_keyidx;
+ if (priv->ieee->sec.key_sizes[priv->ieee->tx_keyidx] <=
+ 40)
+ tfd->u.data.key_index |= DCT_WEP_KEY_64Bit;
+ else
+ tfd->u.data.key_index |= DCT_WEP_KEY_128Bit;
+ break;
+ case SEC_LEVEL_0:
+ break;
+ default:
+ printk(KERN_ERR "Unknow security level %d\n",
+ priv->ieee->sec.level);
+ break;
+ }
+ } else
+ /* No hardware encryption */
+ tfd->u.data.tx_flags |= DCT_FLAG_NO_WEP;
+
+#ifdef CONFIG_IPW_QOS
+ ipw_qos_set_tx_queue_command(priv, pri, &(tfd->u.data), unicast);
+#endif /* CONFIG_IPW_QOS */
+
/* payload */
- tfd->u.data.num_chunks = min((u8) (NUM_TFD_CHUNKS - 2), txb->nr_frags);
- for (i = 0; i < tfd->u.data.num_chunks; i++) {
+ tfd->u.data.num_chunks = cpu_to_le32(min((u8) (NUM_TFD_CHUNKS - 2),
+ txb->nr_frags));
+ IPW_DEBUG_FRAG("%i fragments being sent as %i chunks.\n",
+ txb->nr_frags, le32_to_cpu(tfd->u.data.num_chunks));
+ for (i = 0; i < le32_to_cpu(tfd->u.data.num_chunks); i++) {
+ IPW_DEBUG_FRAG("Adding fragment %i of %i (%d bytes).\n",
+ i, le32_to_cpu(tfd->u.data.num_chunks),
+ txb->fragments[i]->len - hdr_len);
IPW_DEBUG_TX("Dumping TX packet frag %i of %i (%d bytes):\n",
i, tfd->u.data.num_chunks,
txb->fragments[i]->len - hdr_len);
@@ -6396,11 +9770,13 @@ static inline void ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb)
txb->fragments[i]->len - hdr_len);
tfd->u.data.chunk_ptr[i] =
- pci_map_single(priv->pci_dev,
- txb->fragments[i]->data + hdr_len,
- txb->fragments[i]->len - hdr_len,
- PCI_DMA_TODEVICE);
- tfd->u.data.chunk_len[i] = txb->fragments[i]->len - hdr_len;
+ cpu_to_le32(pci_map_single
+ (priv->pci_dev,
+ txb->fragments[i]->data + hdr_len,
+ txb->fragments[i]->len - hdr_len,
+ PCI_DMA_TODEVICE));
+ tfd->u.data.chunk_len[i] =
+ cpu_to_le16(txb->fragments[i]->len - hdr_len);
}
if (i != txb->nr_frags) {
@@ -6415,9 +9791,10 @@ static inline void ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb)
remaining_bytes);
skb = alloc_skb(remaining_bytes, GFP_ATOMIC);
if (skb != NULL) {
- tfd->u.data.chunk_len[i] = remaining_bytes;
+ tfd->u.data.chunk_len[i] = cpu_to_le16(remaining_bytes);
for (j = i; j < txb->nr_frags; j++) {
int size = txb->fragments[j]->len - hdr_len;
+
printk(KERN_INFO "Adding frag %d %d...\n",
j, size);
memcpy(skb_put(skb, size),
@@ -6426,10 +9803,14 @@ static inline void ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb)
dev_kfree_skb_any(txb->fragments[i]);
txb->fragments[i] = skb;
tfd->u.data.chunk_ptr[i] =
- pci_map_single(priv->pci_dev, skb->data,
- tfd->u.data.chunk_len[i],
- PCI_DMA_TODEVICE);
- tfd->u.data.num_chunks++;
+ cpu_to_le32(pci_map_single
+ (priv->pci_dev, skb->data,
+ tfd->u.data.chunk_len[i],
+ PCI_DMA_TODEVICE));
+
+ tfd->u.data.num_chunks =
+ cpu_to_le32(le32_to_cpu(tfd->u.data.num_chunks) +
+ 1);
}
}
@@ -6437,24 +9818,38 @@ static inline void ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb)
q->first_empty = ipw_queue_inc_wrap(q->first_empty, q->n_bd);
ipw_write32(priv, q->reg_w, q->first_empty);
- if (ipw_queue_space(q) < q->high_mark)
- netif_stop_queue(priv->net_dev);
-
- return;
+ return NETDEV_TX_OK;
drop:
IPW_DEBUG_DROP("Silently dropping Tx packet.\n");
ieee80211_txb_free(txb);
+ return NETDEV_TX_OK;
+}
+
+static int ipw_net_is_queue_full(struct net_device *dev, int pri)
+{
+ struct ipw_priv *priv = ieee80211_priv(dev);
+#ifdef CONFIG_IPW_QOS
+ int tx_id = ipw_get_tx_queue_number(priv, pri);
+ struct clx2_tx_queue *txq = &priv->txq[tx_id];
+#else
+ struct clx2_tx_queue *txq = &priv->txq[0];
+#endif /* CONFIG_IPW_QOS */
+
+ if (ipw_queue_space(&txq->q) < txq->q.high_mark)
+ return 1;
+
+ return 0;
}
static int ipw_net_hard_start_xmit(struct ieee80211_txb *txb,
- struct net_device *dev)
+ struct net_device *dev, int pri)
{
struct ipw_priv *priv = ieee80211_priv(dev);
unsigned long flags;
+ int ret;
IPW_DEBUG_TX("dev->xmit(%d bytes)\n", txb->payload_size);
-
spin_lock_irqsave(&priv->lock, flags);
if (!(priv->status & STATUS_ASSOCIATED)) {
@@ -6464,10 +9859,12 @@ static int ipw_net_hard_start_xmit(struct ieee80211_txb *txb,
goto fail_unlock;
}
- ipw_tx_skb(priv, txb);
-
+ ret = ipw_tx_skb(priv, txb, pri);
+ if (ret == NETDEV_TX_OK)
+ __ipw_led_activity_on(priv);
spin_unlock_irqrestore(&priv->lock, flags);
- return 0;
+
+ return ret;
fail_unlock:
spin_unlock_irqrestore(&priv->lock, flags);
@@ -6494,11 +9891,13 @@ static int ipw_net_set_mac_address(struct net_device *dev, void *p)
struct sockaddr *addr = p;
if (!is_valid_ether_addr(addr->sa_data))
return -EADDRNOTAVAIL;
+ down(&priv->sem);
priv->config |= CFG_CUSTOM_MAC;
memcpy(priv->mac_addr, addr->sa_data, ETH_ALEN);
printk(KERN_INFO "%s: Setting MAC to " MAC_FMT "\n",
priv->net_dev->name, MAC_ARG(priv->mac_addr));
- ipw_adapter_restart(priv);
+ queue_work(priv->workqueue, &priv->adapter_restart);
+ up(&priv->sem);
return 0;
}
@@ -6521,7 +9920,7 @@ static void ipw_ethtool_get_drvinfo(struct net_device *dev,
snprintf(info->fw_version, sizeof(info->fw_version), "%s (%s)",
vers, date);
strcpy(info->bus_info, pci_name(p->pci_dev));
- info->eedump_len = CX2_EEPROM_IMAGE_SIZE;
+ info->eedump_len = IPW_EEPROM_IMAGE_SIZE;
}
static u32 ipw_ethtool_get_link(struct net_device *dev)
@@ -6532,7 +9931,7 @@ static u32 ipw_ethtool_get_link(struct net_device *dev)
static int ipw_ethtool_get_eeprom_len(struct net_device *dev)
{
- return CX2_EEPROM_IMAGE_SIZE;
+ return IPW_EEPROM_IMAGE_SIZE;
}
static int ipw_ethtool_get_eeprom(struct net_device *dev,
@@ -6540,10 +9939,11 @@ static int ipw_ethtool_get_eeprom(struct net_device *dev,
{
struct ipw_priv *p = ieee80211_priv(dev);
- if (eeprom->offset + eeprom->len > CX2_EEPROM_IMAGE_SIZE)
+ if (eeprom->offset + eeprom->len > IPW_EEPROM_IMAGE_SIZE)
return -EINVAL;
-
- memcpy(bytes, &((u8 *) p->eeprom)[eeprom->offset], eeprom->len);
+ down(&p->sem);
+ memcpy(bytes, &p->eeprom[eeprom->offset], eeprom->len);
+ up(&p->sem);
return 0;
}
@@ -6553,23 +9953,23 @@ static int ipw_ethtool_set_eeprom(struct net_device *dev,
struct ipw_priv *p = ieee80211_priv(dev);
int i;
- if (eeprom->offset + eeprom->len > CX2_EEPROM_IMAGE_SIZE)
+ if (eeprom->offset + eeprom->len > IPW_EEPROM_IMAGE_SIZE)
return -EINVAL;
-
- memcpy(&((u8 *) p->eeprom)[eeprom->offset], bytes, eeprom->len);
+ down(&p->sem);
+ memcpy(&p->eeprom[eeprom->offset], bytes, eeprom->len);
for (i = IPW_EEPROM_DATA;
- i < IPW_EEPROM_DATA + CX2_EEPROM_IMAGE_SIZE; i++)
+ i < IPW_EEPROM_DATA + IPW_EEPROM_IMAGE_SIZE; i++)
ipw_write8(p, i, p->eeprom[i]);
-
+ up(&p->sem);
return 0;
}
static struct ethtool_ops ipw_ethtool_ops = {
- .get_link = ipw_ethtool_get_link,
- .get_drvinfo = ipw_ethtool_get_drvinfo,
- .get_eeprom_len = ipw_ethtool_get_eeprom_len,
- .get_eeprom = ipw_ethtool_get_eeprom,
- .set_eeprom = ipw_ethtool_set_eeprom,
+ .get_link = ipw_ethtool_get_link,
+ .get_drvinfo = ipw_ethtool_get_drvinfo,
+ .get_eeprom_len = ipw_ethtool_get_eeprom_len,
+ .get_eeprom = ipw_ethtool_get_eeprom,
+ .set_eeprom = ipw_ethtool_set_eeprom,
};
static irqreturn_t ipw_isr(int irq, void *data, struct pt_regs *regs)
@@ -6587,8 +9987,8 @@ static irqreturn_t ipw_isr(int irq, void *data, struct pt_regs *regs)
goto none;
}
- inta = ipw_read32(priv, CX2_INTA_RW);
- inta_mask = ipw_read32(priv, CX2_INTA_MASK_R);
+ inta = ipw_read32(priv, IPW_INTA_RW);
+ inta_mask = ipw_read32(priv, IPW_INTA_MASK_R);
if (inta == 0xFFFFFFFF) {
/* Hardware disappeared */
@@ -6596,7 +9996,7 @@ static irqreturn_t ipw_isr(int irq, void *data, struct pt_regs *regs)
goto none;
}
- if (!(inta & (CX2_INTA_MASK_ALL & inta_mask))) {
+ if (!(inta & (IPW_INTA_MASK_ALL & inta_mask))) {
/* Shared interrupt */
goto none;
}
@@ -6605,8 +10005,8 @@ static irqreturn_t ipw_isr(int irq, void *data, struct pt_regs *regs)
ipw_disable_interrupts(priv);
/* ack current interrupts */
- inta &= (CX2_INTA_MASK_ALL & inta_mask);
- ipw_write32(priv, CX2_INTA_RW, inta);
+ inta &= (IPW_INTA_MASK_ALL & inta_mask);
+ ipw_write32(priv, IPW_INTA_RW, inta);
/* Cache INTA value for our tasklet */
priv->isr_inta = inta;
@@ -6652,28 +10052,116 @@ static void ipw_rf_kill(void *adapter)
spin_unlock_irqrestore(&priv->lock, flags);
}
+static void ipw_bg_rf_kill(void *data)
+{
+ struct ipw_priv *priv = data;
+ down(&priv->sem);
+ ipw_rf_kill(data);
+ up(&priv->sem);
+}
+
+void ipw_link_up(struct ipw_priv *priv)
+{
+ priv->last_seq_num = -1;
+ priv->last_frag_num = -1;
+ priv->last_packet_time = 0;
+
+ netif_carrier_on(priv->net_dev);
+ if (netif_queue_stopped(priv->net_dev)) {
+ IPW_DEBUG_NOTIF("waking queue\n");
+ netif_wake_queue(priv->net_dev);
+ } else {
+ IPW_DEBUG_NOTIF("starting queue\n");
+ netif_start_queue(priv->net_dev);
+ }
+
+ cancel_delayed_work(&priv->request_scan);
+ ipw_reset_stats(priv);
+ /* Ensure the rate is updated immediately */
+ priv->last_rate = ipw_get_current_rate(priv);
+ ipw_gather_stats(priv);
+ ipw_led_link_up(priv);
+ notify_wx_assoc_event(priv);
+
+ if (priv->config & CFG_BACKGROUND_SCAN)
+ queue_delayed_work(priv->workqueue, &priv->request_scan, HZ);
+}
+
+static void ipw_bg_link_up(void *data)
+{
+ struct ipw_priv *priv = data;
+ down(&priv->sem);
+ ipw_link_up(data);
+ up(&priv->sem);
+}
+
+void ipw_link_down(struct ipw_priv *priv)
+{
+ ipw_led_link_down(priv);
+ netif_carrier_off(priv->net_dev);
+ netif_stop_queue(priv->net_dev);
+ notify_wx_assoc_event(priv);
+
+ /* Cancel any queued work ... */
+ cancel_delayed_work(&priv->request_scan);
+ cancel_delayed_work(&priv->adhoc_check);
+ cancel_delayed_work(&priv->gather_stats);
+
+ ipw_reset_stats(priv);
+
+ if (!(priv->status & STATUS_EXIT_PENDING)) {
+ /* Queue up another scan... */
+ queue_work(priv->workqueue, &priv->request_scan);
+ }
+}
+
+static void ipw_bg_link_down(void *data)
+{
+ struct ipw_priv *priv = data;
+ down(&priv->sem);
+ ipw_link_down(data);
+ up(&priv->sem);
+}
+
static int ipw_setup_deferred_work(struct ipw_priv *priv)
{
int ret = 0;
priv->workqueue = create_workqueue(DRV_NAME);
init_waitqueue_head(&priv->wait_command_queue);
-
- INIT_WORK(&priv->adhoc_check, ipw_adhoc_check, priv);
- INIT_WORK(&priv->associate, ipw_associate, priv);
- INIT_WORK(&priv->disassociate, ipw_disassociate, priv);
- INIT_WORK(&priv->rx_replenish, ipw_rx_queue_replenish, priv);
- INIT_WORK(&priv->adapter_restart, ipw_adapter_restart, priv);
- INIT_WORK(&priv->rf_kill, ipw_rf_kill, priv);
- INIT_WORK(&priv->up, (void (*)(void *))ipw_up, priv);
- INIT_WORK(&priv->down, (void (*)(void *))ipw_down, priv);
+ init_waitqueue_head(&priv->wait_state);
+
+ INIT_WORK(&priv->adhoc_check, ipw_bg_adhoc_check, priv);
+ INIT_WORK(&priv->associate, ipw_bg_associate, priv);
+ INIT_WORK(&priv->disassociate, ipw_bg_disassociate, priv);
+ INIT_WORK(&priv->system_config, ipw_system_config, priv);
+ INIT_WORK(&priv->rx_replenish, ipw_bg_rx_queue_replenish, priv);
+ INIT_WORK(&priv->adapter_restart, ipw_bg_adapter_restart, priv);
+ INIT_WORK(&priv->rf_kill, ipw_bg_rf_kill, priv);
+ INIT_WORK(&priv->up, (void (*)(void *))ipw_bg_up, priv);
+ INIT_WORK(&priv->down, (void (*)(void *))ipw_bg_down, priv);
INIT_WORK(&priv->request_scan,
(void (*)(void *))ipw_request_scan, priv);
INIT_WORK(&priv->gather_stats,
- (void (*)(void *))ipw_gather_stats, priv);
- INIT_WORK(&priv->abort_scan, (void (*)(void *))ipw_abort_scan, priv);
- INIT_WORK(&priv->roam, ipw_roam, priv);
- INIT_WORK(&priv->scan_check, ipw_scan_check, priv);
+ (void (*)(void *))ipw_bg_gather_stats, priv);
+ INIT_WORK(&priv->abort_scan, (void (*)(void *))ipw_bg_abort_scan, priv);
+ INIT_WORK(&priv->roam, ipw_bg_roam, priv);
+ INIT_WORK(&priv->scan_check, ipw_bg_scan_check, priv);
+ INIT_WORK(&priv->link_up, (void (*)(void *))ipw_bg_link_up, priv);
+ INIT_WORK(&priv->link_down, (void (*)(void *))ipw_bg_link_down, priv);
+ INIT_WORK(&priv->led_link_on, (void (*)(void *))ipw_bg_led_link_on,
+ priv);
+ INIT_WORK(&priv->led_link_off, (void (*)(void *))ipw_bg_led_link_off,
+ priv);
+ INIT_WORK(&priv->led_act_off, (void (*)(void *))ipw_bg_led_activity_off,
+ priv);
+ INIT_WORK(&priv->merge_networks,
+ (void (*)(void *))ipw_merge_adhoc_network, priv);
+
+#ifdef CONFIG_IPW_QOS
+ INIT_WORK(&priv->qos_activate, (void (*)(void *))ipw_bg_qos_activate,
+ priv);
+#endif /* CONFIG_IPW_QOS */
tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long))
ipw_irq_tasklet, (unsigned long)priv);
@@ -6686,34 +10174,36 @@ static void shim__set_security(struct net_device *dev,
{
struct ipw_priv *priv = ieee80211_priv(dev);
int i;
-
for (i = 0; i < 4; i++) {
if (sec->flags & (1 << i)) {
- priv->sec.key_sizes[i] = sec->key_sizes[i];
+ priv->ieee->sec.encode_alg[i] = sec->encode_alg[i];
+ priv->ieee->sec.key_sizes[i] = sec->key_sizes[i];
if (sec->key_sizes[i] == 0)
- priv->sec.flags &= ~(1 << i);
- else
- memcpy(priv->sec.keys[i], sec->keys[i],
+ priv->ieee->sec.flags &= ~(1 << i);
+ else {
+ memcpy(priv->ieee->sec.keys[i], sec->keys[i],
sec->key_sizes[i]);
- priv->sec.flags |= (1 << i);
+ priv->ieee->sec.flags |= (1 << i);
+ }
priv->status |= STATUS_SECURITY_UPDATED;
- }
+ } else if (sec->level != SEC_LEVEL_1)
+ priv->ieee->sec.flags &= ~(1 << i);
}
- if ((sec->flags & SEC_ACTIVE_KEY) &&
- priv->sec.active_key != sec->active_key) {
+ if (sec->flags & SEC_ACTIVE_KEY) {
if (sec->active_key <= 3) {
- priv->sec.active_key = sec->active_key;
- priv->sec.flags |= SEC_ACTIVE_KEY;
+ priv->ieee->sec.active_key = sec->active_key;
+ priv->ieee->sec.flags |= SEC_ACTIVE_KEY;
} else
- priv->sec.flags &= ~SEC_ACTIVE_KEY;
+ priv->ieee->sec.flags &= ~SEC_ACTIVE_KEY;
priv->status |= STATUS_SECURITY_UPDATED;
- }
+ } else
+ priv->ieee->sec.flags &= ~SEC_ACTIVE_KEY;
if ((sec->flags & SEC_AUTH_MODE) &&
- (priv->sec.auth_mode != sec->auth_mode)) {
- priv->sec.auth_mode = sec->auth_mode;
- priv->sec.flags |= SEC_AUTH_MODE;
+ (priv->ieee->sec.auth_mode != sec->auth_mode)) {
+ priv->ieee->sec.auth_mode = sec->auth_mode;
+ priv->ieee->sec.flags |= SEC_AUTH_MODE;
if (sec->auth_mode == WLAN_AUTH_SHARED_KEY)
priv->capability |= CAP_SHARED_KEY;
else
@@ -6721,9 +10211,9 @@ static void shim__set_security(struct net_device *dev,
priv->status |= STATUS_SECURITY_UPDATED;
}
- if (sec->flags & SEC_ENABLED && priv->sec.enabled != sec->enabled) {
- priv->sec.flags |= SEC_ENABLED;
- priv->sec.enabled = sec->enabled;
+ if (sec->flags & SEC_ENABLED && priv->ieee->sec.enabled != sec->enabled) {
+ priv->ieee->sec.flags |= SEC_ENABLED;
+ priv->ieee->sec.enabled = sec->enabled;
priv->status |= STATUS_SECURITY_UPDATED;
if (sec->enabled)
priv->capability |= CAP_PRIVACY_ON;
@@ -6731,12 +10221,18 @@ static void shim__set_security(struct net_device *dev,
priv->capability &= ~CAP_PRIVACY_ON;
}
- if (sec->flags & SEC_LEVEL && priv->sec.level != sec->level) {
- priv->sec.level = sec->level;
- priv->sec.flags |= SEC_LEVEL;
+ if (sec->flags & SEC_ENCRYPT)
+ priv->ieee->sec.encrypt = sec->encrypt;
+
+ if (sec->flags & SEC_LEVEL && priv->ieee->sec.level != sec->level) {
+ priv->ieee->sec.level = sec->level;
+ priv->ieee->sec.flags |= SEC_LEVEL;
priv->status |= STATUS_SECURITY_UPDATED;
}
+ if (!priv->ieee->host_encrypt && (sec->flags & SEC_ENCRYPT))
+ ipw_set_hwcrypto_keys(priv);
+
/* To match current functionality of ipw2100 (which works well w/
* various supplicants, we don't force a disassociate if the
* privacy capability changes ... */
@@ -6785,29 +10281,10 @@ static int init_supported_rates(struct ipw_priv *priv,
static int ipw_config(struct ipw_priv *priv)
{
- int i;
- struct ipw_tx_power tx_power;
-
- memset(&priv->sys_config, 0, sizeof(priv->sys_config));
- memset(&tx_power, 0, sizeof(tx_power));
-
/* This is only called from ipw_up, which resets/reloads the firmware
so, we don't need to first disable the card before we configure
it */
-
- /* configure device for 'G' band */
- tx_power.ieee_mode = IPW_G_MODE;
- tx_power.num_channels = 11;
- for (i = 0; i < 11; i++) {
- tx_power.channels_tx_power[i].channel_number = i + 1;
- tx_power.channels_tx_power[i].tx_power = priv->tx_power;
- }
- if (ipw_send_tx_power(priv, &tx_power))
- goto error;
-
- /* configure device to also handle 'B' band */
- tx_power.ieee_mode = IPW_B_MODE;
- if (ipw_send_tx_power(priv, &tx_power))
+ if (ipw_set_tx_power(priv))
goto error;
/* initialize adapter address */
@@ -6816,6 +10293,11 @@ static int ipw_config(struct ipw_priv *priv)
/* set basic system config settings */
init_sys_config(&priv->sys_config);
+ if (priv->ieee->iw_mode == IW_MODE_ADHOC)
+ priv->sys_config.answer_broadcast_ssid_probe = 1;
+ else
+ priv->sys_config.answer_broadcast_ssid_probe = 0;
+
if (ipw_send_system_config(priv, &priv->sys_config))
goto error;
@@ -6828,6 +10310,10 @@ static int ipw_config(struct ipw_priv *priv)
if (ipw_send_rts_threshold(priv, priv->rts_threshold))
goto error;
}
+#ifdef CONFIG_IPW_QOS
+ IPW_DEBUG_QOS("QoS: call ipw_qos_activate\n");
+ ipw_qos_activate(priv, NULL);
+#endif /* CONFIG_IPW_QOS */
if (ipw_set_random_seed(priv))
goto error;
@@ -6836,9 +10322,17 @@ static int ipw_config(struct ipw_priv *priv)
if (ipw_send_host_complete(priv))
goto error;
- /* If configured to try and auto-associate, kick off a scan */
- if ((priv->config & CFG_ASSOCIATE) && ipw_request_scan(priv))
- goto error;
+ priv->status |= STATUS_INIT;
+
+ ipw_led_init(priv);
+ ipw_led_radio_on(priv);
+ priv->notif_missed_beacons = 0;
+
+ /* Set hardware WEP key if it is configured. */
+ if ((priv->capability & CAP_PRIVACY_ON) &&
+ (priv->ieee->sec.level == SEC_LEVEL_1) &&
+ !(priv->ieee->host_encrypt || priv->ieee->host_decrypt))
+ ipw_set_hwcrypto_keys(priv);
return 0;
@@ -6846,20 +10340,379 @@ static int ipw_config(struct ipw_priv *priv)
return -EIO;
}
+/*
+ * NOTE:
+ *
+ * These tables have been tested in conjunction with the
+ * Intel PRO/Wireless 2200BG and 2915ABG Network Connection Adapters.
+ *
+ * Altering this values, using it on other hardware, or in geographies
+ * not intended for resale of the above mentioned Intel adapters has
+ * not been tested.
+ *
+ */
+static const struct ieee80211_geo ipw_geos[] = {
+ { /* Restricted */
+ "---",
+ .bg_channels = 11,
+ .bg = {{2412, 1}, {2417, 2}, {2422, 3},
+ {2427, 4}, {2432, 5}, {2437, 6},
+ {2442, 7}, {2447, 8}, {2452, 9},
+ {2457, 10}, {2462, 11}},
+ },
+
+ { /* Custom US/Canada */
+ "ZZF",
+ .bg_channels = 11,
+ .bg = {{2412, 1}, {2417, 2}, {2422, 3},
+ {2427, 4}, {2432, 5}, {2437, 6},
+ {2442, 7}, {2447, 8}, {2452, 9},
+ {2457, 10}, {2462, 11}},
+ .a_channels = 8,
+ .a = {{5180, 36},
+ {5200, 40},
+ {5220, 44},
+ {5240, 48},
+ {5260, 52, IEEE80211_CH_PASSIVE_ONLY},
+ {5280, 56, IEEE80211_CH_PASSIVE_ONLY},
+ {5300, 60, IEEE80211_CH_PASSIVE_ONLY},
+ {5320, 64, IEEE80211_CH_PASSIVE_ONLY}},
+ },
+
+ { /* Rest of World */
+ "ZZD",
+ .bg_channels = 13,
+ .bg = {{2412, 1}, {2417, 2}, {2422, 3},
+ {2427, 4}, {2432, 5}, {2437, 6},
+ {2442, 7}, {2447, 8}, {2452, 9},
+ {2457, 10}, {2462, 11}, {2467, 12},
+ {2472, 13}},
+ },
+
+ { /* Custom USA & Europe & High */
+ "ZZA",
+ .bg_channels = 11,
+ .bg = {{2412, 1}, {2417, 2}, {2422, 3},
+ {2427, 4}, {2432, 5}, {2437, 6},
+ {2442, 7}, {2447, 8}, {2452, 9},
+ {2457, 10}, {2462, 11}},
+ .a_channels = 13,
+ .a = {{5180, 36},
+ {5200, 40},
+ {5220, 44},
+ {5240, 48},
+ {5260, 52, IEEE80211_CH_PASSIVE_ONLY},
+ {5280, 56, IEEE80211_CH_PASSIVE_ONLY},
+ {5300, 60, IEEE80211_CH_PASSIVE_ONLY},
+ {5320, 64, IEEE80211_CH_PASSIVE_ONLY},
+ {5745, 149},
+ {5765, 153},
+ {5785, 157},
+ {5805, 161},
+ {5825, 165}},
+ },
+
+ { /* Custom NA & Europe */
+ "ZZB",
+ .bg_channels = 11,
+ .bg = {{2412, 1}, {2417, 2}, {2422, 3},
+ {2427, 4}, {2432, 5}, {2437, 6},
+ {2442, 7}, {2447, 8}, {2452, 9},
+ {2457, 10}, {2462, 11}},
+ .a_channels = 13,
+ .a = {{5180, 36},
+ {5200, 40},
+ {5220, 44},
+ {5240, 48},
+ {5260, 52, IEEE80211_CH_PASSIVE_ONLY},
+ {5280, 56, IEEE80211_CH_PASSIVE_ONLY},
+ {5300, 60, IEEE80211_CH_PASSIVE_ONLY},
+ {5320, 64, IEEE80211_CH_PASSIVE_ONLY},
+ {5745, 149, IEEE80211_CH_PASSIVE_ONLY},
+ {5765, 153, IEEE80211_CH_PASSIVE_ONLY},
+ {5785, 157, IEEE80211_CH_PASSIVE_ONLY},
+ {5805, 161, IEEE80211_CH_PASSIVE_ONLY},
+ {5825, 165, IEEE80211_CH_PASSIVE_ONLY}},
+ },
+
+ { /* Custom Japan */
+ "ZZC",
+ .bg_channels = 11,
+ .bg = {{2412, 1}, {2417, 2}, {2422, 3},
+ {2427, 4}, {2432, 5}, {2437, 6},
+ {2442, 7}, {2447, 8}, {2452, 9},
+ {2457, 10}, {2462, 11}},
+ .a_channels = 4,
+ .a = {{5170, 34}, {5190, 38},
+ {5210, 42}, {5230, 46}},
+ },
+
+ { /* Custom */
+ "ZZM",
+ .bg_channels = 11,
+ .bg = {{2412, 1}, {2417, 2}, {2422, 3},
+ {2427, 4}, {2432, 5}, {2437, 6},
+ {2442, 7}, {2447, 8}, {2452, 9},
+ {2457, 10}, {2462, 11}},
+ },
+
+ { /* Europe */
+ "ZZE",
+ .bg_channels = 13,
+ .bg = {{2412, 1}, {2417, 2}, {2422, 3},
+ {2427, 4}, {2432, 5}, {2437, 6},
+ {2442, 7}, {2447, 8}, {2452, 9},
+ {2457, 10}, {2462, 11}, {2467, 12},
+ {2472, 13}},
+ .a_channels = 19,
+ .a = {{5180, 36},
+ {5200, 40},
+ {5220, 44},
+ {5240, 48},
+ {5260, 52, IEEE80211_CH_PASSIVE_ONLY},
+ {5280, 56, IEEE80211_CH_PASSIVE_ONLY},
+ {5300, 60, IEEE80211_CH_PASSIVE_ONLY},
+ {5320, 64, IEEE80211_CH_PASSIVE_ONLY},
+ {5500, 100, IEEE80211_CH_PASSIVE_ONLY},
+ {5520, 104, IEEE80211_CH_PASSIVE_ONLY},
+ {5540, 108, IEEE80211_CH_PASSIVE_ONLY},
+ {5560, 112, IEEE80211_CH_PASSIVE_ONLY},
+ {5580, 116, IEEE80211_CH_PASSIVE_ONLY},
+ {5600, 120, IEEE80211_CH_PASSIVE_ONLY},
+ {5620, 124, IEEE80211_CH_PASSIVE_ONLY},
+ {5640, 128, IEEE80211_CH_PASSIVE_ONLY},
+ {5660, 132, IEEE80211_CH_PASSIVE_ONLY},
+ {5680, 136, IEEE80211_CH_PASSIVE_ONLY},
+ {5700, 140, IEEE80211_CH_PASSIVE_ONLY}},
+ },
+
+ { /* Custom Japan */
+ "ZZJ",
+ .bg_channels = 14,
+ .bg = {{2412, 1}, {2417, 2}, {2422, 3},
+ {2427, 4}, {2432, 5}, {2437, 6},
+ {2442, 7}, {2447, 8}, {2452, 9},
+ {2457, 10}, {2462, 11}, {2467, 12},
+ {2472, 13}, {2484, 14, IEEE80211_CH_B_ONLY}},
+ .a_channels = 4,
+ .a = {{5170, 34}, {5190, 38},
+ {5210, 42}, {5230, 46}},
+ },
+
+ { /* Rest of World */
+ "ZZR",
+ .bg_channels = 14,
+ .bg = {{2412, 1}, {2417, 2}, {2422, 3},
+ {2427, 4}, {2432, 5}, {2437, 6},
+ {2442, 7}, {2447, 8}, {2452, 9},
+ {2457, 10}, {2462, 11}, {2467, 12},
+ {2472, 13}, {2484, 14, IEEE80211_CH_B_ONLY |
+ IEEE80211_CH_PASSIVE_ONLY}},
+ },
+
+ { /* High Band */
+ "ZZH",
+ .bg_channels = 13,
+ .bg = {{2412, 1}, {2417, 2}, {2422, 3},
+ {2427, 4}, {2432, 5}, {2437, 6},
+ {2442, 7}, {2447, 8}, {2452, 9},
+ {2457, 10}, {2462, 11},
+ {2467, 12, IEEE80211_CH_PASSIVE_ONLY},
+ {2472, 13, IEEE80211_CH_PASSIVE_ONLY}},
+ .a_channels = 4,
+ .a = {{5745, 149}, {5765, 153},
+ {5785, 157}, {5805, 161}},
+ },
+
+ { /* Custom Europe */
+ "ZZG",
+ .bg_channels = 13,
+ .bg = {{2412, 1}, {2417, 2}, {2422, 3},
+ {2427, 4}, {2432, 5}, {2437, 6},
+ {2442, 7}, {2447, 8}, {2452, 9},
+ {2457, 10}, {2462, 11},
+ {2467, 12}, {2472, 13}},
+ .a_channels = 4,
+ .a = {{5180, 36}, {5200, 40},
+ {5220, 44}, {5240, 48}},
+ },
+
+ { /* Europe */
+ "ZZK",
+ .bg_channels = 13,
+ .bg = {{2412, 1}, {2417, 2}, {2422, 3},
+ {2427, 4}, {2432, 5}, {2437, 6},
+ {2442, 7}, {2447, 8}, {2452, 9},
+ {2457, 10}, {2462, 11},
+ {2467, 12, IEEE80211_CH_PASSIVE_ONLY},
+ {2472, 13, IEEE80211_CH_PASSIVE_ONLY}},
+ .a_channels = 24,
+ .a = {{5180, 36, IEEE80211_CH_PASSIVE_ONLY},
+ {5200, 40, IEEE80211_CH_PASSIVE_ONLY},
+ {5220, 44, IEEE80211_CH_PASSIVE_ONLY},
+ {5240, 48, IEEE80211_CH_PASSIVE_ONLY},
+ {5260, 52, IEEE80211_CH_PASSIVE_ONLY},
+ {5280, 56, IEEE80211_CH_PASSIVE_ONLY},
+ {5300, 60, IEEE80211_CH_PASSIVE_ONLY},
+ {5320, 64, IEEE80211_CH_PASSIVE_ONLY},
+ {5500, 100, IEEE80211_CH_PASSIVE_ONLY},
+ {5520, 104, IEEE80211_CH_PASSIVE_ONLY},
+ {5540, 108, IEEE80211_CH_PASSIVE_ONLY},
+ {5560, 112, IEEE80211_CH_PASSIVE_ONLY},
+ {5580, 116, IEEE80211_CH_PASSIVE_ONLY},
+ {5600, 120, IEEE80211_CH_PASSIVE_ONLY},
+ {5620, 124, IEEE80211_CH_PASSIVE_ONLY},
+ {5640, 128, IEEE80211_CH_PASSIVE_ONLY},
+ {5660, 132, IEEE80211_CH_PASSIVE_ONLY},
+ {5680, 136, IEEE80211_CH_PASSIVE_ONLY},
+ {5700, 140, IEEE80211_CH_PASSIVE_ONLY},
+ {5745, 149, IEEE80211_CH_PASSIVE_ONLY},
+ {5765, 153, IEEE80211_CH_PASSIVE_ONLY},
+ {5785, 157, IEEE80211_CH_PASSIVE_ONLY},
+ {5805, 161, IEEE80211_CH_PASSIVE_ONLY},
+ {5825, 165, IEEE80211_CH_PASSIVE_ONLY}},
+ },
+
+ { /* Europe */
+ "ZZL",
+ .bg_channels = 11,
+ .bg = {{2412, 1}, {2417, 2}, {2422, 3},
+ {2427, 4}, {2432, 5}, {2437, 6},
+ {2442, 7}, {2447, 8}, {2452, 9},
+ {2457, 10}, {2462, 11}},
+ .a_channels = 13,
+ .a = {{5180, 36, IEEE80211_CH_PASSIVE_ONLY},
+ {5200, 40, IEEE80211_CH_PASSIVE_ONLY},
+ {5220, 44, IEEE80211_CH_PASSIVE_ONLY},
+ {5240, 48, IEEE80211_CH_PASSIVE_ONLY},
+ {5260, 52, IEEE80211_CH_PASSIVE_ONLY},
+ {5280, 56, IEEE80211_CH_PASSIVE_ONLY},
+ {5300, 60, IEEE80211_CH_PASSIVE_ONLY},
+ {5320, 64, IEEE80211_CH_PASSIVE_ONLY},
+ {5745, 149, IEEE80211_CH_PASSIVE_ONLY},
+ {5765, 153, IEEE80211_CH_PASSIVE_ONLY},
+ {5785, 157, IEEE80211_CH_PASSIVE_ONLY},
+ {5805, 161, IEEE80211_CH_PASSIVE_ONLY},
+ {5825, 165, IEEE80211_CH_PASSIVE_ONLY}},
+ }
+};
+
+/* GEO code borrowed from ieee80211_geo.c */
+static int ipw_is_valid_channel(struct ieee80211_device *ieee, u8 channel)
+{
+ int i;
+
+ /* Driver needs to initialize the geography map before using
+ * these helper functions */
+ BUG_ON(ieee->geo.bg_channels == 0 && ieee->geo.a_channels == 0);
+
+ if (ieee->freq_band & IEEE80211_24GHZ_BAND)
+ for (i = 0; i < ieee->geo.bg_channels; i++)
+ /* NOTE: If G mode is currently supported but
+ * this is a B only channel, we don't see it
+ * as valid. */
+ if ((ieee->geo.bg[i].channel == channel) &&
+ (!(ieee->mode & IEEE_G) ||
+ !(ieee->geo.bg[i].flags & IEEE80211_CH_B_ONLY)))
+ return IEEE80211_24GHZ_BAND;
+
+ if (ieee->freq_band & IEEE80211_52GHZ_BAND)
+ for (i = 0; i < ieee->geo.a_channels; i++)
+ if (ieee->geo.a[i].channel == channel)
+ return IEEE80211_52GHZ_BAND;
+
+ return 0;
+}
+
+static int ipw_channel_to_index(struct ieee80211_device *ieee, u8 channel)
+{
+ int i;
+
+ /* Driver needs to initialize the geography map before using
+ * these helper functions */
+ BUG_ON(ieee->geo.bg_channels == 0 && ieee->geo.a_channels == 0);
+
+ if (ieee->freq_band & IEEE80211_24GHZ_BAND)
+ for (i = 0; i < ieee->geo.bg_channels; i++)
+ if (ieee->geo.bg[i].channel == channel)
+ return i;
+
+ if (ieee->freq_band & IEEE80211_52GHZ_BAND)
+ for (i = 0; i < ieee->geo.a_channels; i++)
+ if (ieee->geo.a[i].channel == channel)
+ return i;
+
+ return -1;
+}
+
+static u8 ipw_freq_to_channel(struct ieee80211_device *ieee, u32 freq)
+{
+ int i;
+
+ /* Driver needs to initialize the geography map before using
+ * these helper functions */
+ BUG_ON(ieee->geo.bg_channels == 0 && ieee->geo.a_channels == 0);
+
+ freq /= 100000;
+
+ if (ieee->freq_band & IEEE80211_24GHZ_BAND)
+ for (i = 0; i < ieee->geo.bg_channels; i++)
+ if (ieee->geo.bg[i].freq == freq)
+ return ieee->geo.bg[i].channel;
+
+ if (ieee->freq_band & IEEE80211_52GHZ_BAND)
+ for (i = 0; i < ieee->geo.a_channels; i++)
+ if (ieee->geo.a[i].freq == freq)
+ return ieee->geo.a[i].channel;
+
+ return 0;
+}
+
+static int ipw_set_geo(struct ieee80211_device *ieee,
+ const struct ieee80211_geo *geo)
+{
+ memcpy(ieee->geo.name, geo->name, 3);
+ ieee->geo.name[3] = '\0';
+ ieee->geo.bg_channels = geo->bg_channels;
+ ieee->geo.a_channels = geo->a_channels;
+ memcpy(ieee->geo.bg, geo->bg, geo->bg_channels *
+ sizeof(struct ieee80211_channel));
+ memcpy(ieee->geo.a, geo->a, ieee->geo.a_channels *
+ sizeof(struct ieee80211_channel));
+ return 0;
+}
+
+static const struct ieee80211_geo *ipw_get_geo(struct ieee80211_device *ieee)
+{
+ return &ieee->geo;
+}
+
#define MAX_HW_RESTARTS 5
static int ipw_up(struct ipw_priv *priv)
{
- int rc, i;
+ int rc, i, j;
if (priv->status & STATUS_EXIT_PENDING)
return -EIO;
+ if (cmdlog && !priv->cmdlog) {
+ priv->cmdlog = kmalloc(sizeof(*priv->cmdlog) * cmdlog,
+ GFP_KERNEL);
+ if (priv->cmdlog == NULL) {
+ IPW_ERROR("Error allocating %d command log entries.\n",
+ cmdlog);
+ } else {
+ memset(priv->cmdlog, 0, sizeof(*priv->cmdlog) * cmdlog);
+ priv->cmdlog_len = cmdlog;
+ }
+ }
+
for (i = 0; i < MAX_HW_RESTARTS; i++) {
/* Load the microcode, firmware, and eeprom.
* Also start the clocks. */
rc = ipw_load(priv);
if (rc) {
- IPW_ERROR("Unable to load firmware: 0x%08X\n", rc);
+ IPW_ERROR("Unable to load firmware: %d\n", rc);
return rc;
}
@@ -6868,20 +10721,50 @@ static int ipw_up(struct ipw_priv *priv)
eeprom_parse_mac(priv, priv->mac_addr);
memcpy(priv->net_dev->dev_addr, priv->mac_addr, ETH_ALEN);
- if (priv->status & STATUS_RF_KILL_MASK)
+ for (j = 0; j < ARRAY_SIZE(ipw_geos); j++) {
+ if (!memcmp(&priv->eeprom[EEPROM_COUNTRY_CODE],
+ ipw_geos[j].name, 3))
+ break;
+ }
+ if (j == ARRAY_SIZE(ipw_geos)) {
+ IPW_WARNING("SKU [%c%c%c] not recognized.\n",
+ priv->eeprom[EEPROM_COUNTRY_CODE + 0],
+ priv->eeprom[EEPROM_COUNTRY_CODE + 1],
+ priv->eeprom[EEPROM_COUNTRY_CODE + 2]);
+ j = 0;
+ }
+ if (ipw_set_geo(priv->ieee, &ipw_geos[j])) {
+ IPW_WARNING("Could not set geography.");
+ return 0;
+ }
+
+ IPW_DEBUG_INFO("Geography %03d [%s] detected.\n",
+ j, priv->ieee->geo.name);
+
+ if (priv->status & STATUS_RF_KILL_SW) {
+ IPW_WARNING("Radio disabled by module parameter.\n");
return 0;
+ } else if (rf_kill_active(priv)) {
+ IPW_WARNING("Radio Frequency Kill Switch is On:\n"
+ "Kill switch must be turned off for "
+ "wireless networking to work.\n");
+ queue_delayed_work(priv->workqueue, &priv->rf_kill,
+ 2 * HZ);
+ return 0;
+ }
rc = ipw_config(priv);
if (!rc) {
IPW_DEBUG_INFO("Configured device on count %i\n", i);
- priv->notif_missed_beacons = 0;
- netif_start_queue(priv->net_dev);
+
+ /* If configure to try and auto-associate, kick
+ * off a scan. */
+ queue_work(priv->workqueue, &priv->request_scan);
+
return 0;
- } else {
- IPW_DEBUG_INFO("Device configuration failed: 0x%08X\n",
- rc);
}
+ IPW_DEBUG_INFO("Device configuration failed: 0x%08X\n", rc);
IPW_DEBUG_INFO("Failed to config device on retry %d of %d\n",
i, MAX_HW_RESTARTS);
@@ -6893,47 +10776,101 @@ static int ipw_up(struct ipw_priv *priv)
/* tried to restart and config the device for as long as our
* patience could withstand */
IPW_ERROR("Unable to initialize device after %d attempts.\n", i);
+
return -EIO;
}
-static void ipw_down(struct ipw_priv *priv)
+static void ipw_bg_up(void *data)
{
+ struct ipw_priv *priv = data;
+ down(&priv->sem);
+ ipw_up(data);
+ up(&priv->sem);
+}
+
+static void ipw_deinit(struct ipw_priv *priv)
+{
+ int i;
+
+ if (priv->status & STATUS_SCANNING) {
+ IPW_DEBUG_INFO("Aborting scan during shutdown.\n");
+ ipw_abort_scan(priv);
+ }
+
+ if (priv->status & STATUS_ASSOCIATED) {
+ IPW_DEBUG_INFO("Disassociating during shutdown.\n");
+ ipw_disassociate(priv);
+ }
+
+ ipw_led_shutdown(priv);
+
+ /* Wait up to 1s for status to change to not scanning and not
+ * associated (disassociation can take a while for a ful 802.11
+ * exchange */
+ for (i = 1000; i && (priv->status &
+ (STATUS_DISASSOCIATING |
+ STATUS_ASSOCIATED | STATUS_SCANNING)); i--)
+ udelay(10);
+
+ if (priv->status & (STATUS_DISASSOCIATING |
+ STATUS_ASSOCIATED | STATUS_SCANNING))
+ IPW_DEBUG_INFO("Still associated or scanning...\n");
+ else
+ IPW_DEBUG_INFO("Took %dms to de-init\n", 1000 - i);
+
/* Attempt to disable the card */
-#if 0
ipw_send_card_disable(priv, 0);
-#endif
+
+ priv->status &= ~STATUS_INIT;
+}
+
+static void ipw_down(struct ipw_priv *priv)
+{
+ int exit_pending = priv->status & STATUS_EXIT_PENDING;
+
+ priv->status |= STATUS_EXIT_PENDING;
+
+ if (ipw_is_init(priv))
+ ipw_deinit(priv);
+
+ /* Wipe out the EXIT_PENDING status bit if we are not actually
+ * exiting the module */
+ if (!exit_pending)
+ priv->status &= ~STATUS_EXIT_PENDING;
/* tell the device to stop sending interrupts */
ipw_disable_interrupts(priv);
/* Clear all bits but the RF Kill */
- priv->status &= STATUS_RF_KILL_MASK;
-
+ priv->status &= STATUS_RF_KILL_MASK | STATUS_EXIT_PENDING;
netif_carrier_off(priv->net_dev);
netif_stop_queue(priv->net_dev);
ipw_stop_nic(priv);
+
+ ipw_led_radio_off(priv);
+}
+
+static void ipw_bg_down(void *data)
+{
+ struct ipw_priv *priv = data;
+ down(&priv->sem);
+ ipw_down(data);
+ up(&priv->sem);
}
/* Called by register_netdev() */
static int ipw_net_init(struct net_device *dev)
{
struct ipw_priv *priv = ieee80211_priv(dev);
+ down(&priv->sem);
- if (priv->status & STATUS_RF_KILL_SW) {
- IPW_WARNING("Radio disabled by module parameter.\n");
- return 0;
- } else if (rf_kill_active(priv)) {
- IPW_WARNING("Radio Frequency Kill Switch is On:\n"
- "Kill switch must be turned off for "
- "wireless networking to work.\n");
- queue_delayed_work(priv->workqueue, &priv->rf_kill, 2 * HZ);
- return 0;
- }
-
- if (ipw_up(priv))
+ if (ipw_up(priv)) {
+ up(&priv->sem);
return -EIO;
+ }
+ up(&priv->sem);
return 0;
}
@@ -6958,7 +10895,7 @@ static struct pci_device_id card_ids[] = {
{PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2762, 0, 0, 0},
{PCI_VENDOR_ID_INTEL, 0x104f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
{PCI_VENDOR_ID_INTEL, 0x4220, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, /* BG */
- {PCI_VENDOR_ID_INTEL, 0x4221, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, /* 2225BG */
+ {PCI_VENDOR_ID_INTEL, 0x4221, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, /* BG */
{PCI_VENDOR_ID_INTEL, 0x4223, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, /* ABG */
{PCI_VENDOR_ID_INTEL, 0x4224, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, /* ABG */
@@ -6978,11 +10915,16 @@ static struct attribute *ipw_sysfs_entries[] = {
&dev_attr_nic_type.attr,
&dev_attr_status.attr,
&dev_attr_cfg.attr,
- &dev_attr_dump_errors.attr,
- &dev_attr_dump_events.attr,
+ &dev_attr_error.attr,
+ &dev_attr_event_log.attr,
+ &dev_attr_cmd_log.attr,
&dev_attr_eeprom_delay.attr,
&dev_attr_ucode_version.attr,
&dev_attr_rtc.attr,
+ &dev_attr_scan_age.attr,
+ &dev_attr_led.attr,
+ &dev_attr_speed_scan.attr,
+ &dev_attr_net_stats.attr,
NULL
};
@@ -6998,7 +10940,7 @@ static int ipw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
void __iomem *base;
u32 length, val;
struct ipw_priv *priv;
- int band, modulation;
+ int i;
net_dev = alloc_ieee80211(sizeof(struct ipw_priv));
if (net_dev == NULL) {
@@ -7008,13 +10950,17 @@ static int ipw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
priv = ieee80211_priv(net_dev);
priv->ieee = netdev_priv(net_dev);
+
priv->net_dev = net_dev;
priv->pci_dev = pdev;
#ifdef CONFIG_IPW_DEBUG
ipw_debug_level = debug;
#endif
spin_lock_init(&priv->lock);
+ for (i = 0; i < IPW_IBSS_MAC_HASH_SIZE; i++)
+ INIT_LIST_HEAD(&priv->ibss_mac_hash[i]);
+ init_MUTEX(&priv->sem);
if (pci_enable_device(pdev)) {
err = -ENODEV;
goto out_free_ieee80211;
@@ -7061,90 +11007,7 @@ static int ipw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
goto out_iounmap;
}
- /* Initialize module parameter values here */
- if (ifname)
- strncpy(net_dev->name, ifname, IFNAMSIZ);
-
- if (associate)
- priv->config |= CFG_ASSOCIATE;
- else
- IPW_DEBUG_INFO("Auto associate disabled.\n");
-
- if (auto_create)
- priv->config |= CFG_ADHOC_CREATE;
- else
- IPW_DEBUG_INFO("Auto adhoc creation disabled.\n");
-
- if (disable) {
- priv->status |= STATUS_RF_KILL_SW;
- IPW_DEBUG_INFO("Radio disabled.\n");
- }
-
- if (channel != 0) {
- priv->config |= CFG_STATIC_CHANNEL;
- priv->channel = channel;
- IPW_DEBUG_INFO("Bind to static channel %d\n", channel);
- IPW_DEBUG_INFO("Bind to static channel %d\n", channel);
- /* TODO: Validate that provided channel is in range */
- }
-
- switch (mode) {
- case 1:
- priv->ieee->iw_mode = IW_MODE_ADHOC;
- break;
-#ifdef CONFIG_IPW_PROMISC
- case 2:
- priv->ieee->iw_mode = IW_MODE_MONITOR;
- break;
-#endif
- default:
- case 0:
- priv->ieee->iw_mode = IW_MODE_INFRA;
- break;
- }
-
- if ((priv->pci_dev->device == 0x4223) ||
- (priv->pci_dev->device == 0x4224)) {
- printk(KERN_INFO DRV_NAME
- ": Detected Intel PRO/Wireless 2915ABG Network "
- "Connection\n");
- priv->ieee->abg_ture = 1;
- band = IEEE80211_52GHZ_BAND | IEEE80211_24GHZ_BAND;
- modulation = IEEE80211_OFDM_MODULATION |
- IEEE80211_CCK_MODULATION;
- priv->adapter = IPW_2915ABG;
- priv->ieee->mode = IEEE_A | IEEE_G | IEEE_B;
- } else {
- if (priv->pci_dev->device == 0x4221)
- printk(KERN_INFO DRV_NAME
- ": Detected Intel PRO/Wireless 2225BG Network "
- "Connection\n");
- else
- printk(KERN_INFO DRV_NAME
- ": Detected Intel PRO/Wireless 2200BG Network "
- "Connection\n");
-
- priv->ieee->abg_ture = 0;
- band = IEEE80211_24GHZ_BAND;
- modulation = IEEE80211_OFDM_MODULATION |
- IEEE80211_CCK_MODULATION;
- priv->adapter = IPW_2200BG;
- priv->ieee->mode = IEEE_G | IEEE_B;
- }
-
- priv->ieee->freq_band = band;
- priv->ieee->modulation = modulation;
-
- priv->rates_mask = IEEE80211_DEFAULT_RATES_MASK;
-
- priv->missed_beacon_threshold = IPW_MB_DISASSOCIATE_THRESHOLD_DEFAULT;
- priv->roaming_threshold = IPW_MB_ROAMING_THRESHOLD_DEFAULT;
-
- priv->rts_threshold = DEFAULT_RTS_THRESHOLD;
-
- /* If power management is turned on, default to AC mode */
- priv->power_mode = IPW_POWER_AC;
- priv->tx_power = IPW_DEFAULT_TX_POWER;
+ ipw_sw_reset(priv, 1);
err = request_irq(pdev->irq, ipw_isr, SA_SHIRQ, DRV_NAME, priv);
if (err) {
@@ -7155,8 +11018,20 @@ static int ipw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
SET_MODULE_OWNER(net_dev);
SET_NETDEV_DEV(net_dev, &pdev->dev);
+ down(&priv->sem);
+
priv->ieee->hard_start_xmit = ipw_net_hard_start_xmit;
priv->ieee->set_security = shim__set_security;
+ priv->ieee->is_queue_full = ipw_net_is_queue_full;
+
+#ifdef CONFIG_IPW_QOS
+ priv->ieee->handle_probe_response = ipw_handle_beacon;
+ priv->ieee->handle_beacon = ipw_handle_probe_response;
+ priv->ieee->handle_assoc_response = ipw_handle_assoc_response;
+#endif /* CONFIG_IPW_QOS */
+
+ priv->ieee->perfect_rssi = -20;
+ priv->ieee->worst_rssi = -85;
net_dev->open = ipw_net_open;
net_dev->stop = ipw_net_stop;
@@ -7164,7 +11039,9 @@ static int ipw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
net_dev->get_stats = ipw_net_get_stats;
net_dev->set_multicast_list = ipw_net_set_multicast_list;
net_dev->set_mac_address = ipw_net_set_mac_address;
- net_dev->get_wireless_stats = ipw_get_wireless_stats;
+ priv->wireless_data.spy_data = &priv->ieee->spy_data;
+ priv->wireless_data.ieee80211 = priv->ieee;
+ net_dev->wireless_data = &priv->wireless_data;
net_dev->wireless_handlers = &ipw_wx_handler_def;
net_dev->ethtool_ops = &ipw_ethtool_ops;
net_dev->irq = pdev->irq;
@@ -7175,18 +11052,19 @@ static int ipw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
err = sysfs_create_group(&pdev->dev.kobj, &ipw_attribute_group);
if (err) {
IPW_ERROR("failed to create sysfs device attributes\n");
+ up(&priv->sem);
goto out_release_irq;
}
+ up(&priv->sem);
err = register_netdev(net_dev);
if (err) {
IPW_ERROR("failed to register network device\n");
- goto out_remove_group;
+ goto out_remove_sysfs;
}
-
return 0;
- out_remove_group:
+ out_remove_sysfs:
sysfs_remove_group(&pdev->dev.kobj, &ipw_attribute_group);
out_release_irq:
free_irq(pdev->irq, priv);
@@ -7209,14 +11087,19 @@ static int ipw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
static void ipw_pci_remove(struct pci_dev *pdev)
{
struct ipw_priv *priv = pci_get_drvdata(pdev);
+ struct list_head *p, *q;
+ int i;
+
if (!priv)
return;
- priv->status |= STATUS_EXIT_PENDING;
+ down(&priv->sem);
+ priv->status |= STATUS_EXIT_PENDING;
+ ipw_down(priv);
sysfs_remove_group(&pdev->dev.kobj, &ipw_attribute_group);
- ipw_down(priv);
+ up(&priv->sem);
unregister_netdev(priv->net_dev);
@@ -7226,16 +11109,31 @@ static void ipw_pci_remove(struct pci_dev *pdev)
}
ipw_tx_queue_free(priv);
+ if (priv->cmdlog) {
+ kfree(priv->cmdlog);
+ priv->cmdlog = NULL;
+ }
/* ipw_down will ensure that there is no more pending work
* in the workqueue's, so we can safely remove them now. */
- if (priv->workqueue) {
- cancel_delayed_work(&priv->adhoc_check);
- cancel_delayed_work(&priv->gather_stats);
- cancel_delayed_work(&priv->request_scan);
- cancel_delayed_work(&priv->rf_kill);
- cancel_delayed_work(&priv->scan_check);
- destroy_workqueue(priv->workqueue);
- priv->workqueue = NULL;
+ cancel_delayed_work(&priv->adhoc_check);
+ cancel_delayed_work(&priv->gather_stats);
+ cancel_delayed_work(&priv->request_scan);
+ cancel_delayed_work(&priv->rf_kill);
+ cancel_delayed_work(&priv->scan_check);
+ destroy_workqueue(priv->workqueue);
+ priv->workqueue = NULL;
+
+ /* Free MAC hash list for ADHOC */
+ for (i = 0; i < IPW_IBSS_MAC_HASH_SIZE; i++) {
+ list_for_each_safe(p, q, &priv->ibss_mac_hash[i]) {
+ kfree(list_entry(p, struct ipw_ibss_seq, list));
+ list_del(p);
+ }
+ }
+
+ if (priv->error) {
+ ipw_free_error_log(priv->error);
+ priv->error = NULL;
}
free_irq(pdev->irq, priv);
@@ -7244,15 +11142,7 @@ static void ipw_pci_remove(struct pci_dev *pdev)
pci_disable_device(pdev);
pci_set_drvdata(pdev, NULL);
free_ieee80211(priv->net_dev);
-
-#ifdef CONFIG_PM
- if (fw_loaded) {
- release_firmware(bootfw);
- release_firmware(ucode);
- release_firmware(firmware);
- fw_loaded = 0;
- }
-#endif
+ free_firmware();
}
#ifdef CONFIG_PM
@@ -7284,13 +11174,10 @@ static int ipw_pci_resume(struct pci_dev *pdev)
printk(KERN_INFO "%s: Coming out of suspend...\n", dev->name);
- pci_set_power_state(pdev, 0);
+ pci_set_power_state(pdev, PCI_D0);
pci_enable_device(pdev);
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10)
- pci_restore_state(pdev, priv->pm_state);
-#else
pci_restore_state(pdev);
-#endif
+
/*
* Suspend/Resume resets the PCI configuration space, so we have to
* re-disable the RETRY_TIMEOUT register (0x41) to keep PCI Tx retries
@@ -7362,16 +11249,33 @@ MODULE_PARM_DESC(associate, "auto associate when scanning (default on)");
module_param(auto_create, int, 0444);
MODULE_PARM_DESC(auto_create, "auto create adhoc network (default on)");
+module_param(led, int, 0444);
+MODULE_PARM_DESC(led, "enable led control on some systems (default 0 off)\n");
+
module_param(debug, int, 0444);
MODULE_PARM_DESC(debug, "debug output mask");
module_param(channel, int, 0444);
MODULE_PARM_DESC(channel, "channel to limit associate to (default 0 [ANY])");
-module_param(ifname, charp, 0444);
-MODULE_PARM_DESC(ifname, "network device name (default eth%d)");
+#ifdef CONFIG_IPW_QOS
+module_param(qos_enable, int, 0444);
+MODULE_PARM_DESC(qos_enable, "enable all QoS functionalitis");
+
+module_param(qos_burst_enable, int, 0444);
+MODULE_PARM_DESC(qos_burst_enable, "enable QoS burst mode");
+
+module_param(qos_no_ack_mask, int, 0444);
+MODULE_PARM_DESC(qos_no_ack_mask, "mask Tx_Queue to no ack");
-#ifdef CONFIG_IPW_PROMISC
+module_param(burst_duration_CCK, int, 0444);
+MODULE_PARM_DESC(burst_duration_CCK, "set CCK burst value");
+
+module_param(burst_duration_OFDM, int, 0444);
+MODULE_PARM_DESC(burst_duration_OFDM, "set OFDM burst value");
+#endif /* CONFIG_IPW_QOS */
+
+#ifdef CONFIG_IPW2200_MONITOR
module_param(mode, int, 0444);
MODULE_PARM_DESC(mode, "network mode (0=BSS,1=IBSS,2=Monitor)");
#else
@@ -7379,5 +11283,12 @@ module_param(mode, int, 0444);
MODULE_PARM_DESC(mode, "network mode (0=BSS,1=IBSS)");
#endif
+module_param(hwcrypto, int, 0444);
+MODULE_PARM_DESC(hwcrypto, "enable hardware crypto (default on)");
+
+module_param(cmdlog, int, 0444);
+MODULE_PARM_DESC(cmdlog,
+ "allocate a ring buffer for logging firmware commands");
+
module_exit(ipw_exit);
module_init(ipw_init);
diff --git a/drivers/net/wireless/ipw2200.h b/drivers/net/wireless/ipw2200.h
index 5b00882133f9..1c98db0652c9 100644
--- a/drivers/net/wireless/ipw2200.h
+++ b/drivers/net/wireless/ipw2200.h
@@ -1,6 +1,6 @@
/******************************************************************************
- Copyright(c) 2003 - 2004 Intel Corporation. All rights reserved.
+ Copyright(c) 2003 - 2005 Intel Corporation. All rights reserved.
This program is free software; you can redistribute it and/or modify it
under the terms of version 2 of the GNU General Public License as
@@ -34,7 +34,6 @@
#include <linux/config.h>
#include <linux/init.h>
-#include <linux/version.h>
#include <linux/pci.h>
#include <linux/netdevice.h>
#include <linux/ethtool.h>
@@ -50,6 +49,7 @@
#include <asm/io.h>
#include <net/ieee80211.h>
+#include <net/ieee80211_radiotap.h>
#define DRV_NAME "ipw2200"
@@ -161,6 +161,16 @@ enum connection_manager_assoc_states {
* TX Queue Flag Definitions
*/
+/* tx wep key definition */
+#define DCT_WEP_KEY_NOT_IMMIDIATE 0x00
+#define DCT_WEP_KEY_64Bit 0x40
+#define DCT_WEP_KEY_128Bit 0x80
+#define DCT_WEP_KEY_128bitIV 0xC0
+#define DCT_WEP_KEY_SIZE_MASK 0xC0
+
+#define DCT_WEP_KEY_INDEX_MASK 0x0F
+#define DCT_WEP_INDEX_USE_IMMEDIATE 0x20
+
/* abort attempt if mgmt frame is rx'd */
#define DCT_FLAG_ABORT_MGMT 0x01
@@ -168,7 +178,8 @@ enum connection_manager_assoc_states {
#define DCT_FLAG_CTS_REQUIRED 0x02
/* use short preamble */
-#define DCT_FLAG_SHORT_PREMBL 0x04
+#define DCT_FLAG_LONG_PREAMBLE 0x00
+#define DCT_FLAG_SHORT_PREAMBLE 0x04
/* RTS/CTS first */
#define DCT_FLAG_RTS_REQD 0x08
@@ -185,9 +196,23 @@ enum connection_manager_assoc_states {
/* ACK rx is expected to follow */
#define DCT_FLAG_ACK_REQD 0x80
+/* TX flags extension */
#define DCT_FLAG_EXT_MODE_CCK 0x01
#define DCT_FLAG_EXT_MODE_OFDM 0x00
+#define DCT_FLAG_EXT_SECURITY_WEP 0x00
+#define DCT_FLAG_EXT_SECURITY_NO DCT_FLAG_EXT_SECURITY_WEP
+#define DCT_FLAG_EXT_SECURITY_CKIP 0x04
+#define DCT_FLAG_EXT_SECURITY_CCM 0x08
+#define DCT_FLAG_EXT_SECURITY_TKIP 0x0C
+#define DCT_FLAG_EXT_SECURITY_MASK 0x0C
+
+#define DCT_FLAG_EXT_QOS_ENABLED 0x10
+
+#define DCT_FLAG_EXT_HC_NO_SIFS_PIFS 0x00
+#define DCT_FLAG_EXT_HC_SIFS 0x20
+#define DCT_FLAG_EXT_HC_PIFS 0x40
+
#define TX_RX_TYPE_MASK 0xFF
#define TX_FRAME_TYPE 0x00
#define TX_HOST_COMMAND_TYPE 0x01
@@ -233,6 +258,117 @@ enum connection_manager_assoc_states {
#define DCR_TYPE_SNIFFER 0x06
#define DCR_TYPE_MU_BSS DCR_TYPE_MU_ESS
+/* QoS definitions */
+
+#define CW_MIN_OFDM 15
+#define CW_MAX_OFDM 1023
+#define CW_MIN_CCK 31
+#define CW_MAX_CCK 1023
+
+#define QOS_TX0_CW_MIN_OFDM CW_MIN_OFDM
+#define QOS_TX1_CW_MIN_OFDM CW_MIN_OFDM
+#define QOS_TX2_CW_MIN_OFDM ( (CW_MIN_OFDM + 1) / 2 - 1 )
+#define QOS_TX3_CW_MIN_OFDM ( (CW_MIN_OFDM + 1) / 4 - 1 )
+
+#define QOS_TX0_CW_MIN_CCK CW_MIN_CCK
+#define QOS_TX1_CW_MIN_CCK CW_MIN_CCK
+#define QOS_TX2_CW_MIN_CCK ( (CW_MIN_CCK + 1) / 2 - 1 )
+#define QOS_TX3_CW_MIN_CCK ( (CW_MIN_CCK + 1) / 4 - 1 )
+
+#define QOS_TX0_CW_MAX_OFDM CW_MAX_OFDM
+#define QOS_TX1_CW_MAX_OFDM CW_MAX_OFDM
+#define QOS_TX2_CW_MAX_OFDM CW_MIN_OFDM
+#define QOS_TX3_CW_MAX_OFDM ( (CW_MIN_OFDM + 1) / 2 - 1 )
+
+#define QOS_TX0_CW_MAX_CCK CW_MAX_CCK
+#define QOS_TX1_CW_MAX_CCK CW_MAX_CCK
+#define QOS_TX2_CW_MAX_CCK CW_MIN_CCK
+#define QOS_TX3_CW_MAX_CCK ( (CW_MIN_CCK + 1) / 2 - 1 )
+
+#define QOS_TX0_AIFS (3 - QOS_AIFSN_MIN_VALUE)
+#define QOS_TX1_AIFS (7 - QOS_AIFSN_MIN_VALUE)
+#define QOS_TX2_AIFS (2 - QOS_AIFSN_MIN_VALUE)
+#define QOS_TX3_AIFS (2 - QOS_AIFSN_MIN_VALUE)
+
+#define QOS_TX0_ACM 0
+#define QOS_TX1_ACM 0
+#define QOS_TX2_ACM 0
+#define QOS_TX3_ACM 0
+
+#define QOS_TX0_TXOP_LIMIT_CCK 0
+#define QOS_TX1_TXOP_LIMIT_CCK 0
+#define QOS_TX2_TXOP_LIMIT_CCK 6016
+#define QOS_TX3_TXOP_LIMIT_CCK 3264
+
+#define QOS_TX0_TXOP_LIMIT_OFDM 0
+#define QOS_TX1_TXOP_LIMIT_OFDM 0
+#define QOS_TX2_TXOP_LIMIT_OFDM 3008
+#define QOS_TX3_TXOP_LIMIT_OFDM 1504
+
+#define DEF_TX0_CW_MIN_OFDM CW_MIN_OFDM
+#define DEF_TX1_CW_MIN_OFDM CW_MIN_OFDM
+#define DEF_TX2_CW_MIN_OFDM CW_MIN_OFDM
+#define DEF_TX3_CW_MIN_OFDM CW_MIN_OFDM
+
+#define DEF_TX0_CW_MIN_CCK CW_MIN_CCK
+#define DEF_TX1_CW_MIN_CCK CW_MIN_CCK
+#define DEF_TX2_CW_MIN_CCK CW_MIN_CCK
+#define DEF_TX3_CW_MIN_CCK CW_MIN_CCK
+
+#define DEF_TX0_CW_MAX_OFDM CW_MAX_OFDM
+#define DEF_TX1_CW_MAX_OFDM CW_MAX_OFDM
+#define DEF_TX2_CW_MAX_OFDM CW_MAX_OFDM
+#define DEF_TX3_CW_MAX_OFDM CW_MAX_OFDM
+
+#define DEF_TX0_CW_MAX_CCK CW_MAX_CCK
+#define DEF_TX1_CW_MAX_CCK CW_MAX_CCK
+#define DEF_TX2_CW_MAX_CCK CW_MAX_CCK
+#define DEF_TX3_CW_MAX_CCK CW_MAX_CCK
+
+#define DEF_TX0_AIFS 0
+#define DEF_TX1_AIFS 0
+#define DEF_TX2_AIFS 0
+#define DEF_TX3_AIFS 0
+
+#define DEF_TX0_ACM 0
+#define DEF_TX1_ACM 0
+#define DEF_TX2_ACM 0
+#define DEF_TX3_ACM 0
+
+#define DEF_TX0_TXOP_LIMIT_CCK 0
+#define DEF_TX1_TXOP_LIMIT_CCK 0
+#define DEF_TX2_TXOP_LIMIT_CCK 0
+#define DEF_TX3_TXOP_LIMIT_CCK 0
+
+#define DEF_TX0_TXOP_LIMIT_OFDM 0
+#define DEF_TX1_TXOP_LIMIT_OFDM 0
+#define DEF_TX2_TXOP_LIMIT_OFDM 0
+#define DEF_TX3_TXOP_LIMIT_OFDM 0
+
+#define QOS_QOS_SETS 3
+#define QOS_PARAM_SET_ACTIVE 0
+#define QOS_PARAM_SET_DEF_CCK 1
+#define QOS_PARAM_SET_DEF_OFDM 2
+
+#define CTRL_QOS_NO_ACK (0x0020)
+
+#define IPW_TX_QUEUE_1 1
+#define IPW_TX_QUEUE_2 2
+#define IPW_TX_QUEUE_3 3
+#define IPW_TX_QUEUE_4 4
+
+/* QoS sturctures */
+struct ipw_qos_info {
+ int qos_enable;
+ struct ieee80211_qos_parameters *def_qos_parm_OFDM;
+ struct ieee80211_qos_parameters *def_qos_parm_CCK;
+ u32 burst_duration_CCK;
+ u32 burst_duration_OFDM;
+ u16 qos_no_ack_mask;
+ int burst_enable;
+};
+
+/**************************************************************/
/**
* Generic queue structure
*
@@ -402,9 +538,9 @@ struct clx2_tx_queue {
#define RX_FREE_BUFFERS 32
#define RX_LOW_WATERMARK 8
-#define SUP_RATE_11A_MAX_NUM_CHANNELS (8)
-#define SUP_RATE_11B_MAX_NUM_CHANNELS (4)
-#define SUP_RATE_11G_MAX_NUM_CHANNELS (12)
+#define SUP_RATE_11A_MAX_NUM_CHANNELS 8
+#define SUP_RATE_11B_MAX_NUM_CHANNELS 4
+#define SUP_RATE_11G_MAX_NUM_CHANNELS 12
// Used for passing to driver number of successes and failures per rate
struct rate_histogram {
@@ -453,6 +589,9 @@ struct notif_channel_result {
u8 uReserved;
} __attribute__ ((packed));
+#define SCAN_COMPLETED_STATUS_COMPLETE 1
+#define SCAN_COMPLETED_STATUS_ABORTED 2
+
struct notif_scan_complete {
u8 scan_type;
u8 num_channels;
@@ -563,8 +702,8 @@ struct ipw_rx_packet {
} __attribute__ ((packed));
#define IPW_RX_NOTIFICATION_SIZE sizeof(struct ipw_rx_header) + 12
-#define IPW_RX_FRAME_SIZE sizeof(struct ipw_rx_header) + \
- sizeof(struct ipw_rx_frame)
+#define IPW_RX_FRAME_SIZE (unsigned int)(sizeof(struct ipw_rx_header) + \
+ sizeof(struct ipw_rx_frame))
struct ipw_rx_mem_buffer {
dma_addr_t dma_addr;
@@ -657,6 +796,19 @@ struct ipw_multicast_addr {
u8 mac4[6];
} __attribute__ ((packed));
+#define DCW_WEP_KEY_INDEX_MASK 0x03 /* bits [0:1] */
+#define DCW_WEP_KEY_SEC_TYPE_MASK 0x30 /* bits [4:5] */
+
+#define DCW_WEP_KEY_SEC_TYPE_WEP 0x00
+#define DCW_WEP_KEY_SEC_TYPE_CCM 0x20
+#define DCW_WEP_KEY_SEC_TYPE_TKIP 0x30
+
+#define DCW_WEP_KEY_INVALID_SIZE 0x00 /* 0 = Invalid key */
+#define DCW_WEP_KEY64Bit_SIZE 0x05 /* 64-bit encryption */
+#define DCW_WEP_KEY128Bit_SIZE 0x0D /* 128-bit encryption */
+#define DCW_CCM_KEY128Bit_SIZE 0x10 /* 128-bit key */
+//#define DCW_WEP_KEY128BitIV_SIZE 0x10 /* 128-bit key and 128-bit IV */
+
struct ipw_wep_key {
u8 cmd_id;
u8 seq_num;
@@ -818,14 +970,6 @@ struct ipw_tx_power {
struct ipw_channel_tx_power channels_tx_power[MAX_A_CHANNELS];
} __attribute__ ((packed));
-struct ipw_qos_parameters {
- u16 cw_min[4];
- u16 cw_max[4];
- u8 aifs[4];
- u8 flag[4];
- u16 tx_op_limit[4];
-} __attribute__ ((packed));
-
struct ipw_rsn_capabilities {
u8 id;
u8 length;
@@ -888,6 +1032,10 @@ struct ipw_cmd {
#define STATUS_SCAN_PENDING (1<<20)
#define STATUS_SCANNING (1<<21)
#define STATUS_SCAN_ABORTING (1<<22)
+#define STATUS_SCAN_FORCED (1<<23)
+
+#define STATUS_LED_LINK_ON (1<<24)
+#define STATUS_LED_ACT_ON (1<<25)
#define STATUS_INDIRECT_BYTE (1<<28) /* sysfs entry configured for access */
#define STATUS_INDIRECT_DWORD (1<<29) /* sysfs entry configured for access */
@@ -899,11 +1047,15 @@ struct ipw_cmd {
#define CFG_STATIC_ESSID (1<<1) /* Restrict assoc. to single SSID */
#define CFG_STATIC_BSSID (1<<2) /* Restrict assoc. to single BSSID */
#define CFG_CUSTOM_MAC (1<<3)
-#define CFG_PREAMBLE (1<<4)
+#define CFG_PREAMBLE_LONG (1<<4)
#define CFG_ADHOC_PERSIST (1<<5)
#define CFG_ASSOCIATE (1<<6)
#define CFG_FIXED_RATE (1<<7)
#define CFG_ADHOC_CREATE (1<<8)
+#define CFG_NO_LED (1<<9)
+#define CFG_BACKGROUND_SCAN (1<<10)
+#define CFG_SPEED_SCAN (1<<11)
+#define CFG_NET_STATS (1<<12)
#define CAP_SHARED_KEY (1<<0) /* Off = OPEN */
#define CAP_PRIVACY_ON (1<<1) /* Off = No privacy */
@@ -925,13 +1077,50 @@ struct average {
s32 sum;
};
+#define MAX_SPEED_SCAN 100
+#define IPW_IBSS_MAC_HASH_SIZE 31
+
+struct ipw_ibss_seq {
+ u8 mac[ETH_ALEN];
+ u16 seq_num;
+ u16 frag_num;
+ unsigned long packet_time;
+ struct list_head list;
+};
+
+struct ipw_error_elem {
+ u32 desc;
+ u32 time;
+ u32 blink1;
+ u32 blink2;
+ u32 link1;
+ u32 link2;
+ u32 data;
+};
+
+struct ipw_event {
+ u32 event;
+ u32 time;
+ u32 data;
+} __attribute__ ((packed));
+
+struct ipw_fw_error {
+ unsigned long jiffies;
+ u32 status;
+ u32 config;
+ u32 elem_len;
+ u32 log_len;
+ struct ipw_error_elem *elem;
+ struct ipw_event *log;
+ u8 payload[0];
+} __attribute__ ((packed));
+
struct ipw_priv {
/* ieee device used by generic ieee processing code */
struct ieee80211_device *ieee;
- struct ieee80211_security sec;
- /* spinlock */
spinlock_t lock;
+ struct semaphore sem;
/* basic pci-network driver stuff */
struct pci_dev *pci_dev;
@@ -966,7 +1155,7 @@ struct ipw_priv {
int rx_bufs_min; /**< minimum number of bufs in Rx queue */
int rx_pend_max; /**< maximum pending buffers for one IRQ */
u32 hcmd_seq; /**< sequence number for hcmd */
- u32 missed_beacon_threshold;
+ u32 disassociate_threshold;
u32 roaming_threshold;
struct ipw_associate assoc_request;
@@ -1007,6 +1196,8 @@ struct ipw_priv {
u8 mac_addr[ETH_ALEN];
u8 num_stations;
u8 stations[MAX_STATIONS][ETH_ALEN];
+ u8 short_retry_limit;
+ u8 long_retry_limit;
u32 notif_missed_beacons;
@@ -1024,17 +1215,29 @@ struct ipw_priv {
u32 tx_packets;
u32 quality;
+ u8 speed_scan[MAX_SPEED_SCAN];
+ u8 speed_scan_pos;
+
+ u16 last_seq_num;
+ u16 last_frag_num;
+ unsigned long last_packet_time;
+ struct list_head ibss_mac_hash[IPW_IBSS_MAC_HASH_SIZE];
+
/* eeprom */
u8 eeprom[0x100]; /* 256 bytes of eeprom */
+ u8 country[4];
int eeprom_delay;
struct iw_statistics wstats;
+ struct iw_public_data wireless_data;
+
struct workqueue_struct *workqueue;
struct work_struct adhoc_check;
struct work_struct associate;
struct work_struct disassociate;
+ struct work_struct system_config;
struct work_struct rx_replenish;
struct work_struct request_scan;
struct work_struct adapter_restart;
@@ -1045,25 +1248,51 @@ struct ipw_priv {
struct work_struct abort_scan;
struct work_struct roam;
struct work_struct scan_check;
+ struct work_struct link_up;
+ struct work_struct link_down;
struct tasklet_struct irq_tasklet;
+ /* LED related variables and work_struct */
+ u8 nic_type;
+ u32 led_activity_on;
+ u32 led_activity_off;
+ u32 led_association_on;
+ u32 led_association_off;
+ u32 led_ofdm_on;
+ u32 led_ofdm_off;
+
+ struct work_struct led_link_on;
+ struct work_struct led_link_off;
+ struct work_struct led_act_off;
+ struct work_struct merge_networks;
+
+ struct ipw_cmd_log *cmdlog;
+ int cmdlog_len;
+ int cmdlog_pos;
+
#define IPW_2200BG 1
#define IPW_2915ABG 2
u8 adapter;
-#define IPW_DEFAULT_TX_POWER 0x14
- u8 tx_power;
+ s8 tx_power;
#ifdef CONFIG_PM
u32 pm_state[16];
#endif
+ struct ipw_fw_error *error;
+
/* network state */
/* Used to pass the current INTA value from ISR to Tasklet */
u32 isr_inta;
+ /* QoS */
+ struct ipw_qos_info qos_data;
+ struct work_struct qos_activate;
+ /*********************************/
+
/* debugging info */
u32 indirect_dword;
u32 direct_dword;
@@ -1125,6 +1354,8 @@ do { if (ipw_debug_level & (level)) \
#define IPW_DL_RF_KILL (1<<17)
#define IPW_DL_FW_ERRORS (1<<18)
+#define IPW_DL_LED (1<<19)
+
#define IPW_DL_ORD (1<<20)
#define IPW_DL_FRAG (1<<21)
@@ -1137,6 +1368,8 @@ do { if (ipw_debug_level & (level)) \
#define IPW_DL_TRACE (1<<28)
#define IPW_DL_STATS (1<<29)
+#define IPW_DL_MERGE (1<<30)
+#define IPW_DL_QOS (1<<31)
#define IPW_ERROR(f, a...) printk(KERN_ERR DRV_NAME ": " f, ## a)
#define IPW_WARNING(f, a...) printk(KERN_WARNING DRV_NAME ": " f, ## a)
@@ -1150,6 +1383,7 @@ do { if (ipw_debug_level & (level)) \
#define IPW_DEBUG_TX(f, a...) IPW_DEBUG(IPW_DL_TX, f, ## a)
#define IPW_DEBUG_ISR(f, a...) IPW_DEBUG(IPW_DL_ISR, f, ## a)
#define IPW_DEBUG_MANAGEMENT(f, a...) IPW_DEBUG(IPW_DL_MANAGE, f, ## a)
+#define IPW_DEBUG_LED(f, a...) IPW_DEBUG(IPW_DL_LED, f, ## a)
#define IPW_DEBUG_WEP(f, a...) IPW_DEBUG(IPW_DL_WEP, f, ## a)
#define IPW_DEBUG_HC(f, a...) IPW_DEBUG(IPW_DL_HOST_COMMAND, f, ## a)
#define IPW_DEBUG_FRAG(f, a...) IPW_DEBUG(IPW_DL_FRAG, f, ## a)
@@ -1163,6 +1397,8 @@ do { if (ipw_debug_level & (level)) \
#define IPW_DEBUG_STATE(f, a...) IPW_DEBUG(IPW_DL_STATE | IPW_DL_ASSOC | IPW_DL_INFO, f, ## a)
#define IPW_DEBUG_ASSOC(f, a...) IPW_DEBUG(IPW_DL_ASSOC | IPW_DL_INFO, f, ## a)
#define IPW_DEBUG_STATS(f, a...) IPW_DEBUG(IPW_DL_STATS, f, ## a)
+#define IPW_DEBUG_MERGE(f, a...) IPW_DEBUG(IPW_DL_MERGE, f, ## a)
+#define IPW_DEBUG_QOS(f, a...) IPW_DEBUG(IPW_DL_QOS, f, ## a)
#include <linux/ctype.h>
@@ -1177,59 +1413,65 @@ do { if (ipw_debug_level & (level)) \
#define DINO_RXFIFO_DATA 0x01
#define DINO_CONTROL_REG 0x00200000
-#define CX2_INTA_RW 0x00000008
-#define CX2_INTA_MASK_R 0x0000000C
-#define CX2_INDIRECT_ADDR 0x00000010
-#define CX2_INDIRECT_DATA 0x00000014
-#define CX2_AUTOINC_ADDR 0x00000018
-#define CX2_AUTOINC_DATA 0x0000001C
-#define CX2_RESET_REG 0x00000020
-#define CX2_GP_CNTRL_RW 0x00000024
+#define IPW_INTA_RW 0x00000008
+#define IPW_INTA_MASK_R 0x0000000C
+#define IPW_INDIRECT_ADDR 0x00000010
+#define IPW_INDIRECT_DATA 0x00000014
+#define IPW_AUTOINC_ADDR 0x00000018
+#define IPW_AUTOINC_DATA 0x0000001C
+#define IPW_RESET_REG 0x00000020
+#define IPW_GP_CNTRL_RW 0x00000024
-#define CX2_READ_INT_REGISTER 0xFF4
+#define IPW_READ_INT_REGISTER 0xFF4
-#define CX2_GP_CNTRL_BIT_INIT_DONE 0x00000004
+#define IPW_GP_CNTRL_BIT_INIT_DONE 0x00000004
-#define CX2_REGISTER_DOMAIN1_END 0x00001000
-#define CX2_SRAM_READ_INT_REGISTER 0x00000ff4
+#define IPW_REGISTER_DOMAIN1_END 0x00001000
+#define IPW_SRAM_READ_INT_REGISTER 0x00000ff4
-#define CX2_SHARED_LOWER_BOUND 0x00000200
-#define CX2_INTERRUPT_AREA_LOWER_BOUND 0x00000f80
+#define IPW_SHARED_LOWER_BOUND 0x00000200
+#define IPW_INTERRUPT_AREA_LOWER_BOUND 0x00000f80
-#define CX2_NIC_SRAM_LOWER_BOUND 0x00000000
-#define CX2_NIC_SRAM_UPPER_BOUND 0x00030000
+#define IPW_NIC_SRAM_LOWER_BOUND 0x00000000
+#define IPW_NIC_SRAM_UPPER_BOUND 0x00030000
-#define CX2_BIT_INT_HOST_SRAM_READ_INT_REGISTER (1 << 29)
-#define CX2_GP_CNTRL_BIT_CLOCK_READY 0x00000001
-#define CX2_GP_CNTRL_BIT_HOST_ALLOWS_STANDBY 0x00000002
+#define IPW_BIT_INT_HOST_SRAM_READ_INT_REGISTER (1 << 29)
+#define IPW_GP_CNTRL_BIT_CLOCK_READY 0x00000001
+#define IPW_GP_CNTRL_BIT_HOST_ALLOWS_STANDBY 0x00000002
/*
* RESET Register Bit Indexes
*/
-#define CBD_RESET_REG_PRINCETON_RESET 0x00000001 /* Bit 0 (LSB) */
-#define CX2_RESET_REG_SW_RESET 0x00000080 /* Bit 7 */
-#define CX2_RESET_REG_MASTER_DISABLED 0x00000100 /* Bit 8 */
-#define CX2_RESET_REG_STOP_MASTER 0x00000200 /* Bit 9 */
-#define CX2_ARC_KESHET_CONFIG 0x08000000 /* Bit 27 */
-#define CX2_START_STANDBY 0x00000004 /* Bit 2 */
-
-#define CX2_CSR_CIS_UPPER_BOUND 0x00000200
-#define CX2_DOMAIN_0_END 0x1000
+#define CBD_RESET_REG_PRINCETON_RESET (1<<0)
+#define IPW_START_STANDBY (1<<2)
+#define IPW_ACTIVITY_LED (1<<4)
+#define IPW_ASSOCIATED_LED (1<<5)
+#define IPW_OFDM_LED (1<<6)
+#define IPW_RESET_REG_SW_RESET (1<<7)
+#define IPW_RESET_REG_MASTER_DISABLED (1<<8)
+#define IPW_RESET_REG_STOP_MASTER (1<<9)
+#define IPW_GATE_ODMA (1<<25)
+#define IPW_GATE_IDMA (1<<26)
+#define IPW_ARC_KESHET_CONFIG (1<<27)
+#define IPW_GATE_ADMA (1<<29)
+
+#define IPW_CSR_CIS_UPPER_BOUND 0x00000200
+#define IPW_DOMAIN_0_END 0x1000
#define CLX_MEM_BAR_SIZE 0x1000
-#define CX2_BASEBAND_CONTROL_STATUS 0X00200000
-#define CX2_BASEBAND_TX_FIFO_WRITE 0X00200004
-#define CX2_BASEBAND_RX_FIFO_READ 0X00200004
-#define CX2_BASEBAND_CONTROL_STORE 0X00200010
+#define IPW_BASEBAND_CONTROL_STATUS 0X00200000
+#define IPW_BASEBAND_TX_FIFO_WRITE 0X00200004
+#define IPW_BASEBAND_RX_FIFO_READ 0X00200004
+#define IPW_BASEBAND_CONTROL_STORE 0X00200010
-#define CX2_INTERNAL_CMD_EVENT 0X00300004
-#define CX2_BASEBAND_POWER_DOWN 0x00000001
+#define IPW_INTERNAL_CMD_EVENT 0X00300004
+#define IPW_BASEBAND_POWER_DOWN 0x00000001
-#define CX2_MEM_HALT_AND_RESET 0x003000e0
+#define IPW_MEM_HALT_AND_RESET 0x003000e0
/* defgroup bits_halt_reset MEM_HALT_AND_RESET register bits */
-#define CX2_BIT_HALT_RESET_ON 0x80000000
-#define CX2_BIT_HALT_RESET_OFF 0x00000000
+#define IPW_BIT_HALT_RESET_ON 0x80000000
+#define IPW_BIT_HALT_RESET_OFF 0x00000000
#define CB_LAST_VALID 0x20000000
#define CB_INT_ENABLED 0x40000000
@@ -1248,63 +1490,63 @@ do { if (ipw_debug_level & (level)) \
#define DMA_CB_STOP_AND_ABORT 0x00000C00
#define DMA_CB_START 0x00000100
-#define CX2_SHARED_SRAM_SIZE 0x00030000
-#define CX2_SHARED_SRAM_DMA_CONTROL 0x00027000
+#define IPW_SHARED_SRAM_SIZE 0x00030000
+#define IPW_SHARED_SRAM_DMA_CONTROL 0x00027000
#define CB_MAX_LENGTH 0x1FFF
-#define CX2_HOST_EEPROM_DATA_SRAM_SIZE 0xA18
-#define CX2_EEPROM_IMAGE_SIZE 0x100
+#define IPW_HOST_EEPROM_DATA_SRAM_SIZE 0xA18
+#define IPW_EEPROM_IMAGE_SIZE 0x100
/* DMA defs */
-#define CX2_DMA_I_CURRENT_CB 0x003000D0
-#define CX2_DMA_O_CURRENT_CB 0x003000D4
-#define CX2_DMA_I_DMA_CONTROL 0x003000A4
-#define CX2_DMA_I_CB_BASE 0x003000A0
-
-#define CX2_TX_CMD_QUEUE_BD_BASE (0x00000200)
-#define CX2_TX_CMD_QUEUE_BD_SIZE (0x00000204)
-#define CX2_TX_QUEUE_0_BD_BASE (0x00000208)
-#define CX2_TX_QUEUE_0_BD_SIZE (0x0000020C)
-#define CX2_TX_QUEUE_1_BD_BASE (0x00000210)
-#define CX2_TX_QUEUE_1_BD_SIZE (0x00000214)
-#define CX2_TX_QUEUE_2_BD_BASE (0x00000218)
-#define CX2_TX_QUEUE_2_BD_SIZE (0x0000021C)
-#define CX2_TX_QUEUE_3_BD_BASE (0x00000220)
-#define CX2_TX_QUEUE_3_BD_SIZE (0x00000224)
-#define CX2_RX_BD_BASE (0x00000240)
-#define CX2_RX_BD_SIZE (0x00000244)
-#define CX2_RFDS_TABLE_LOWER (0x00000500)
-
-#define CX2_TX_CMD_QUEUE_READ_INDEX (0x00000280)
-#define CX2_TX_QUEUE_0_READ_INDEX (0x00000284)
-#define CX2_TX_QUEUE_1_READ_INDEX (0x00000288)
-#define CX2_TX_QUEUE_2_READ_INDEX (0x0000028C)
-#define CX2_TX_QUEUE_3_READ_INDEX (0x00000290)
-#define CX2_RX_READ_INDEX (0x000002A0)
-
-#define CX2_TX_CMD_QUEUE_WRITE_INDEX (0x00000F80)
-#define CX2_TX_QUEUE_0_WRITE_INDEX (0x00000F84)
-#define CX2_TX_QUEUE_1_WRITE_INDEX (0x00000F88)
-#define CX2_TX_QUEUE_2_WRITE_INDEX (0x00000F8C)
-#define CX2_TX_QUEUE_3_WRITE_INDEX (0x00000F90)
-#define CX2_RX_WRITE_INDEX (0x00000FA0)
+#define IPW_DMA_I_CURRENT_CB 0x003000D0
+#define IPW_DMA_O_CURRENT_CB 0x003000D4
+#define IPW_DMA_I_DMA_CONTROL 0x003000A4
+#define IPW_DMA_I_CB_BASE 0x003000A0
+
+#define IPW_TX_CMD_QUEUE_BD_BASE 0x00000200
+#define IPW_TX_CMD_QUEUE_BD_SIZE 0x00000204
+#define IPW_TX_QUEUE_0_BD_BASE 0x00000208
+#define IPW_TX_QUEUE_0_BD_SIZE (0x0000020C)
+#define IPW_TX_QUEUE_1_BD_BASE 0x00000210
+#define IPW_TX_QUEUE_1_BD_SIZE 0x00000214
+#define IPW_TX_QUEUE_2_BD_BASE 0x00000218
+#define IPW_TX_QUEUE_2_BD_SIZE (0x0000021C)
+#define IPW_TX_QUEUE_3_BD_BASE 0x00000220
+#define IPW_TX_QUEUE_3_BD_SIZE 0x00000224
+#define IPW_RX_BD_BASE 0x00000240
+#define IPW_RX_BD_SIZE 0x00000244
+#define IPW_RFDS_TABLE_LOWER 0x00000500
+
+#define IPW_TX_CMD_QUEUE_READ_INDEX 0x00000280
+#define IPW_TX_QUEUE_0_READ_INDEX 0x00000284
+#define IPW_TX_QUEUE_1_READ_INDEX 0x00000288
+#define IPW_TX_QUEUE_2_READ_INDEX (0x0000028C)
+#define IPW_TX_QUEUE_3_READ_INDEX 0x00000290
+#define IPW_RX_READ_INDEX (0x000002A0)
+
+#define IPW_TX_CMD_QUEUE_WRITE_INDEX (0x00000F80)
+#define IPW_TX_QUEUE_0_WRITE_INDEX (0x00000F84)
+#define IPW_TX_QUEUE_1_WRITE_INDEX (0x00000F88)
+#define IPW_TX_QUEUE_2_WRITE_INDEX (0x00000F8C)
+#define IPW_TX_QUEUE_3_WRITE_INDEX (0x00000F90)
+#define IPW_RX_WRITE_INDEX (0x00000FA0)
/*
* EEPROM Related Definitions
*/
-#define IPW_EEPROM_DATA_SRAM_ADDRESS (CX2_SHARED_LOWER_BOUND + 0x814)
-#define IPW_EEPROM_DATA_SRAM_SIZE (CX2_SHARED_LOWER_BOUND + 0x818)
-#define IPW_EEPROM_LOAD_DISABLE (CX2_SHARED_LOWER_BOUND + 0x81C)
-#define IPW_EEPROM_DATA (CX2_SHARED_LOWER_BOUND + 0x820)
-#define IPW_EEPROM_UPPER_ADDRESS (CX2_SHARED_LOWER_BOUND + 0x9E0)
+#define IPW_EEPROM_DATA_SRAM_ADDRESS (IPW_SHARED_LOWER_BOUND + 0x814)
+#define IPW_EEPROM_DATA_SRAM_SIZE (IPW_SHARED_LOWER_BOUND + 0x818)
+#define IPW_EEPROM_LOAD_DISABLE (IPW_SHARED_LOWER_BOUND + 0x81C)
+#define IPW_EEPROM_DATA (IPW_SHARED_LOWER_BOUND + 0x820)
+#define IPW_EEPROM_UPPER_ADDRESS (IPW_SHARED_LOWER_BOUND + 0x9E0)
-#define IPW_STATION_TABLE_LOWER (CX2_SHARED_LOWER_BOUND + 0xA0C)
-#define IPW_STATION_TABLE_UPPER (CX2_SHARED_LOWER_BOUND + 0xB0C)
-#define IPW_REQUEST_ATIM (CX2_SHARED_LOWER_BOUND + 0xB0C)
-#define IPW_ATIM_SENT (CX2_SHARED_LOWER_BOUND + 0xB10)
-#define IPW_WHO_IS_AWAKE (CX2_SHARED_LOWER_BOUND + 0xB14)
-#define IPW_DURING_ATIM_WINDOW (CX2_SHARED_LOWER_BOUND + 0xB18)
+#define IPW_STATION_TABLE_LOWER (IPW_SHARED_LOWER_BOUND + 0xA0C)
+#define IPW_STATION_TABLE_UPPER (IPW_SHARED_LOWER_BOUND + 0xB0C)
+#define IPW_REQUEST_ATIM (IPW_SHARED_LOWER_BOUND + 0xB0C)
+#define IPW_ATIM_SENT (IPW_SHARED_LOWER_BOUND + 0xB10)
+#define IPW_WHO_IS_AWAKE (IPW_SHARED_LOWER_BOUND + 0xB14)
+#define IPW_DURING_ATIM_WINDOW (IPW_SHARED_LOWER_BOUND + 0xB18)
#define MSB 1
#define LSB 0
@@ -1326,15 +1568,15 @@ do { if (ipw_debug_level & (level)) \
#define EEPROM_HW_VERSION (GET_EEPROM_ADDR(0x72,LSB)) /* 2 bytes */
/* NIC type as found in the one byte EEPROM_NIC_TYPE offset*/
-#define EEPROM_NIC_TYPE_STANDARD 0
-#define EEPROM_NIC_TYPE_DELL 1
-#define EEPROM_NIC_TYPE_FUJITSU 2
-#define EEPROM_NIC_TYPE_IBM 3
-#define EEPROM_NIC_TYPE_HP 4
+#define EEPROM_NIC_TYPE_0 0
+#define EEPROM_NIC_TYPE_1 1
+#define EEPROM_NIC_TYPE_2 2
+#define EEPROM_NIC_TYPE_3 3
+#define EEPROM_NIC_TYPE_4 4
#define FW_MEM_REG_LOWER_BOUND 0x00300000
#define FW_MEM_REG_EEPROM_ACCESS (FW_MEM_REG_LOWER_BOUND + 0x40)
-
+#define IPW_EVENT_REG (FW_MEM_REG_LOWER_BOUND + 0x04)
#define EEPROM_BIT_SK (1<<0)
#define EEPROM_BIT_CS (1<<1)
#define EEPROM_BIT_DI (1<<2)
@@ -1343,50 +1585,47 @@ do { if (ipw_debug_level & (level)) \
#define EEPROM_CMD_READ 0x2
/* Interrupts masks */
-#define CX2_INTA_NONE 0x00000000
+#define IPW_INTA_NONE 0x00000000
-#define CX2_INTA_BIT_RX_TRANSFER 0x00000002
-#define CX2_INTA_BIT_STATUS_CHANGE 0x00000010
-#define CX2_INTA_BIT_BEACON_PERIOD_EXPIRED 0x00000020
+#define IPW_INTA_BIT_RX_TRANSFER 0x00000002
+#define IPW_INTA_BIT_STATUS_CHANGE 0x00000010
+#define IPW_INTA_BIT_BEACON_PERIOD_EXPIRED 0x00000020
//Inta Bits for CF
-#define CX2_INTA_BIT_TX_CMD_QUEUE 0x00000800
-#define CX2_INTA_BIT_TX_QUEUE_1 0x00001000
-#define CX2_INTA_BIT_TX_QUEUE_2 0x00002000
-#define CX2_INTA_BIT_TX_QUEUE_3 0x00004000
-#define CX2_INTA_BIT_TX_QUEUE_4 0x00008000
+#define IPW_INTA_BIT_TX_CMD_QUEUE 0x00000800
+#define IPW_INTA_BIT_TX_QUEUE_1 0x00001000
+#define IPW_INTA_BIT_TX_QUEUE_2 0x00002000
+#define IPW_INTA_BIT_TX_QUEUE_3 0x00004000
+#define IPW_INTA_BIT_TX_QUEUE_4 0x00008000
-#define CX2_INTA_BIT_SLAVE_MODE_HOST_CMD_DONE 0x00010000
+#define IPW_INTA_BIT_SLAVE_MODE_HOST_CMD_DONE 0x00010000
-#define CX2_INTA_BIT_PREPARE_FOR_POWER_DOWN 0x00100000
-#define CX2_INTA_BIT_POWER_DOWN 0x00200000
+#define IPW_INTA_BIT_PREPARE_FOR_POWER_DOWN 0x00100000
+#define IPW_INTA_BIT_POWER_DOWN 0x00200000
-#define CX2_INTA_BIT_FW_INITIALIZATION_DONE 0x01000000
-#define CX2_INTA_BIT_FW_CARD_DISABLE_PHY_OFF_DONE 0x02000000
-#define CX2_INTA_BIT_RF_KILL_DONE 0x04000000
-#define CX2_INTA_BIT_FATAL_ERROR 0x40000000
-#define CX2_INTA_BIT_PARITY_ERROR 0x80000000
+#define IPW_INTA_BIT_FW_INITIALIZATION_DONE 0x01000000
+#define IPW_INTA_BIT_FW_CARD_DISABLE_PHY_OFF_DONE 0x02000000
+#define IPW_INTA_BIT_RF_KILL_DONE 0x04000000
+#define IPW_INTA_BIT_FATAL_ERROR 0x40000000
+#define IPW_INTA_BIT_PARITY_ERROR 0x80000000
/* Interrupts enabled at init time. */
-#define CX2_INTA_MASK_ALL \
- (CX2_INTA_BIT_TX_QUEUE_1 | \
- CX2_INTA_BIT_TX_QUEUE_2 | \
- CX2_INTA_BIT_TX_QUEUE_3 | \
- CX2_INTA_BIT_TX_QUEUE_4 | \
- CX2_INTA_BIT_TX_CMD_QUEUE | \
- CX2_INTA_BIT_RX_TRANSFER | \
- CX2_INTA_BIT_FATAL_ERROR | \
- CX2_INTA_BIT_PARITY_ERROR | \
- CX2_INTA_BIT_STATUS_CHANGE | \
- CX2_INTA_BIT_FW_INITIALIZATION_DONE | \
- CX2_INTA_BIT_BEACON_PERIOD_EXPIRED | \
- CX2_INTA_BIT_SLAVE_MODE_HOST_CMD_DONE | \
- CX2_INTA_BIT_PREPARE_FOR_POWER_DOWN | \
- CX2_INTA_BIT_POWER_DOWN | \
- CX2_INTA_BIT_RF_KILL_DONE )
-
-#define IPWSTATUS_ERROR_LOG (CX2_SHARED_LOWER_BOUND + 0x410)
-#define IPW_EVENT_LOG (CX2_SHARED_LOWER_BOUND + 0x414)
+#define IPW_INTA_MASK_ALL \
+ (IPW_INTA_BIT_TX_QUEUE_1 | \
+ IPW_INTA_BIT_TX_QUEUE_2 | \
+ IPW_INTA_BIT_TX_QUEUE_3 | \
+ IPW_INTA_BIT_TX_QUEUE_4 | \
+ IPW_INTA_BIT_TX_CMD_QUEUE | \
+ IPW_INTA_BIT_RX_TRANSFER | \
+ IPW_INTA_BIT_FATAL_ERROR | \
+ IPW_INTA_BIT_PARITY_ERROR | \
+ IPW_INTA_BIT_STATUS_CHANGE | \
+ IPW_INTA_BIT_FW_INITIALIZATION_DONE | \
+ IPW_INTA_BIT_BEACON_PERIOD_EXPIRED | \
+ IPW_INTA_BIT_SLAVE_MODE_HOST_CMD_DONE | \
+ IPW_INTA_BIT_PREPARE_FOR_POWER_DOWN | \
+ IPW_INTA_BIT_POWER_DOWN | \
+ IPW_INTA_BIT_RF_KILL_DONE )
/* FW event log definitions */
#define EVENT_ELEM_SIZE (3 * sizeof(u32))
@@ -1396,6 +1635,11 @@ do { if (ipw_debug_level & (level)) \
#define ERROR_ELEM_SIZE (7 * sizeof(u32))
#define ERROR_START_OFFSET (1 * sizeof(u32))
+/* TX power level (dbm) */
+#define IPW_TX_POWER_MIN -12
+#define IPW_TX_POWER_MAX 20
+#define IPW_TX_POWER_DEFAULT IPW_TX_POWER_MAX
+
enum {
IPW_FW_ERROR_OK = 0,
IPW_FW_ERROR_FAIL,
@@ -1408,8 +1652,8 @@ enum {
IPW_FW_ERROR_ALLOC_FAIL,
IPW_FW_ERROR_DMA_UNDERRUN,
IPW_FW_ERROR_DMA_STATUS,
- IPW_FW_ERROR_DINOSTATUS_ERROR,
- IPW_FW_ERROR_EEPROMSTATUS_ERROR,
+ IPW_FW_ERROR_DINO_ERROR,
+ IPW_FW_ERROR_EEPROM_ERROR,
IPW_FW_ERROR_SYSASSERT,
IPW_FW_ERROR_FATAL_ERROR
};
@@ -1425,6 +1669,8 @@ enum {
#define HC_IBSS_RECONF 4
#define HC_DISASSOC_QUIET 5
+#define HC_QOS_SUPPORT_ASSOC 0x01
+
#define IPW_RATE_CAPABILITIES 1
#define IPW_RATE_CONNECT 0
@@ -1595,18 +1841,20 @@ enum {
IPW_ORD_TABLE_7_LAST
};
-#define IPW_ORDINALS_TABLE_LOWER (CX2_SHARED_LOWER_BOUND + 0x500)
-#define IPW_ORDINALS_TABLE_0 (CX2_SHARED_LOWER_BOUND + 0x180)
-#define IPW_ORDINALS_TABLE_1 (CX2_SHARED_LOWER_BOUND + 0x184)
-#define IPW_ORDINALS_TABLE_2 (CX2_SHARED_LOWER_BOUND + 0x188)
-#define IPW_MEM_FIXED_OVERRIDE (CX2_SHARED_LOWER_BOUND + 0x41C)
+#define IPW_ERROR_LOG (IPW_SHARED_LOWER_BOUND + 0x410)
+#define IPW_EVENT_LOG (IPW_SHARED_LOWER_BOUND + 0x414)
+#define IPW_ORDINALS_TABLE_LOWER (IPW_SHARED_LOWER_BOUND + 0x500)
+#define IPW_ORDINALS_TABLE_0 (IPW_SHARED_LOWER_BOUND + 0x180)
+#define IPW_ORDINALS_TABLE_1 (IPW_SHARED_LOWER_BOUND + 0x184)
+#define IPW_ORDINALS_TABLE_2 (IPW_SHARED_LOWER_BOUND + 0x188)
+#define IPW_MEM_FIXED_OVERRIDE (IPW_SHARED_LOWER_BOUND + 0x41C)
struct ipw_fixed_rate {
u16 tx_rates;
u16 reserved;
} __attribute__ ((packed));
-#define CX2_INDIRECT_ADDR_MASK (~0x3ul)
+#define IPW_INDIRECT_ADDR_MASK (~0x3ul)
struct host_cmd {
u8 cmd;
@@ -1615,6 +1863,12 @@ struct host_cmd {
u32 param[TFD_CMD_IMMEDIATE_PAYLOAD_LENGTH];
} __attribute__ ((packed));
+struct ipw_cmd_log {
+ unsigned long jiffies;
+ int retcode;
+ struct host_cmd cmd;
+};
+
#define CFG_BT_COEXISTENCE_MIN 0x00
#define CFG_BT_COEXISTENCE_DEFER 0x02
#define CFG_BT_COEXISTENCE_KILL 0x04
@@ -1643,23 +1897,14 @@ struct host_cmd {
#define REG_CHANNEL_MASK 0x00003FFF
#define IPW_IBSS_11B_DEFAULT_MASK 0x87ff
-static const long ipw_frequencies[] = {
- 2412, 2417, 2422, 2427,
- 2432, 2437, 2442, 2447,
- 2452, 2457, 2462, 2467,
- 2472, 2484
-};
-
-#define FREQ_COUNT ARRAY_SIZE(ipw_frequencies)
-
#define IPW_MAX_CONFIG_RETRIES 10
-static inline u32 frame_hdr_len(struct ieee80211_hdr *hdr)
+static inline u32 frame_hdr_len(struct ieee80211_hdr_4addr *hdr)
{
u32 retval;
u16 fc;
- retval = sizeof(struct ieee80211_hdr);
+ retval = sizeof(struct ieee80211_hdr_3addr);
fc = le16_to_cpu(hdr->frame_ctl);
/*
diff --git a/drivers/net/wireless/netwave_cs.c b/drivers/net/wireless/netwave_cs.c
index ca6c03c89926..92793b958e32 100644
--- a/drivers/net/wireless/netwave_cs.c
+++ b/drivers/net/wireless/netwave_cs.c
@@ -57,9 +57,7 @@
#include <linux/bitops.h>
#ifdef CONFIG_NET_RADIO
#include <linux/wireless.h>
-#if WIRELESS_EXT > 12
#include <net/iw_handler.h>
-#endif /* WIRELESS_EXT > 12 */
#endif
#include <pcmcia/cs_types.h>
@@ -225,10 +223,7 @@ static void update_stats(struct net_device *dev);
static struct net_device_stats *netwave_get_stats(struct net_device *dev);
/* Wireless extensions */
-#ifdef WIRELESS_EXT
static struct iw_statistics* netwave_get_wireless_stats(struct net_device *dev);
-#endif
-static int netwave_ioctl(struct net_device *, struct ifreq *, int);
static void set_multicast_list(struct net_device *dev);
@@ -260,26 +255,7 @@ static dev_link_t *dev_list;
because they generally can't be allocated dynamically.
*/
-#if WIRELESS_EXT <= 12
-/* Wireless extensions backward compatibility */
-
-/* Part of iw_handler prototype we need */
-struct iw_request_info
-{
- __u16 cmd; /* Wireless Extension command */
- __u16 flags; /* More to come ;-) */
-};
-
-/* Wireless Extension Backward compatibility - Jean II
- * If the new wireless device private ioctl range is not defined,
- * default to standard device private ioctl range */
-#ifndef SIOCIWFIRSTPRIV
-#define SIOCIWFIRSTPRIV SIOCDEVPRIVATE
-#endif /* SIOCIWFIRSTPRIV */
-
-#else /* WIRELESS_EXT <= 12 */
static const struct iw_handler_def netwave_handler_def;
-#endif /* WIRELESS_EXT <= 12 */
#define SIOCGIPSNAP SIOCIWFIRSTPRIV + 1 /* Site Survey Snapshot */
@@ -319,9 +295,7 @@ typedef struct netwave_private {
struct timer_list watchdog; /* To avoid blocking state */
struct site_survey nss;
struct net_device_stats stats;
-#ifdef WIRELESS_EXT
struct iw_statistics iw_stats; /* Wireless stats */
-#endif
} netwave_private;
#ifdef NETWAVE_STATS
@@ -353,7 +327,6 @@ static inline void wait_WOC(unsigned int iobase)
while ((inb(iobase + NETWAVE_REG_ASR) & 0x8) != 0x8) ;
}
-#ifdef WIRELESS_EXT
static void netwave_snapshot(netwave_private *priv, u_char __iomem *ramBase,
kio_addr_t iobase) {
u_short resultBuffer;
@@ -376,9 +349,7 @@ static void netwave_snapshot(netwave_private *priv, u_char __iomem *ramBase,
sizeof(struct site_survey));
}
}
-#endif
-#ifdef WIRELESS_EXT
/*
* Function netwave_get_wireless_stats (dev)
*
@@ -411,7 +382,6 @@ static struct iw_statistics *netwave_get_wireless_stats(struct net_device *dev)
return &priv->iw_stats;
}
-#endif
/*
* Function netwave_attach (void)
@@ -471,13 +441,7 @@ static dev_link_t *netwave_attach(void)
dev->get_stats = &netwave_get_stats;
dev->set_multicast_list = &set_multicast_list;
/* wireless extensions */
-#if WIRELESS_EXT <= 16
- dev->get_wireless_stats = &netwave_get_wireless_stats;
-#endif /* WIRELESS_EXT <= 16 */
-#if WIRELESS_EXT > 12
dev->wireless_handlers = (struct iw_handler_def *)&netwave_handler_def;
-#endif /* WIRELESS_EXT > 12 */
- dev->do_ioctl = &netwave_ioctl;
dev->tx_timeout = &netwave_watchdog;
dev->watchdog_timeo = TX_TIMEOUT;
@@ -576,13 +540,8 @@ static int netwave_set_nwid(struct net_device *dev,
/* Disable interrupts & save flags */
spin_lock_irqsave(&priv->spinlock, flags);
-#if WIRELESS_EXT > 8
if(!wrqu->nwid.disabled) {
domain = wrqu->nwid.value;
-#else /* WIRELESS_EXT > 8 */
- if(wrqu->nwid.on) {
- domain = wrqu->nwid.nwid;
-#endif /* WIRELESS_EXT > 8 */
printk( KERN_DEBUG "Setting domain to 0x%x%02x\n",
(domain >> 8) & 0x01, domain & 0xff);
wait_WOC(iobase);
@@ -606,15 +565,9 @@ static int netwave_get_nwid(struct net_device *dev,
union iwreq_data *wrqu,
char *extra)
{
-#if WIRELESS_EXT > 8
wrqu->nwid.value = domain;
wrqu->nwid.disabled = 0;
wrqu->nwid.fixed = 1;
-#else /* WIRELESS_EXT > 8 */
- wrqu->nwid.nwid = domain;
- wrqu->nwid.on = 1;
-#endif /* WIRELESS_EXT > 8 */
-
return 0;
}
@@ -657,17 +610,11 @@ static int netwave_get_scramble(struct net_device *dev,
{
key[1] = scramble_key & 0xff;
key[0] = (scramble_key>>8) & 0xff;
-#if WIRELESS_EXT > 8
wrqu->encoding.flags = IW_ENCODE_ENABLED;
wrqu->encoding.length = 2;
-#else /* WIRELESS_EXT > 8 */
- wrqu->encoding.method = 1;
-#endif /* WIRELESS_EXT > 8 */
-
return 0;
}
-#if WIRELESS_EXT > 8
/*
* Wireless Handler : get mode
*/
@@ -683,7 +630,6 @@ static int netwave_get_mode(struct net_device *dev,
return 0;
}
-#endif /* WIRELESS_EXT > 8 */
/*
* Wireless Handler : get range info
@@ -702,11 +648,9 @@ static int netwave_get_range(struct net_device *dev,
/* Set all the info we don't care or don't know about to zero */
memset(range, 0, sizeof(struct iw_range));
-#if WIRELESS_EXT > 10
/* Set the Wireless Extension versions */
range->we_version_compiled = WIRELESS_EXT;
range->we_version_source = 9; /* Nothing for us in v10 and v11 */
-#endif /* WIRELESS_EXT > 10 */
/* Set information in the range struct */
range->throughput = 450 * 1000; /* don't argue on this ! */
@@ -720,16 +664,12 @@ static int netwave_get_range(struct net_device *dev,
range->max_qual.level = 255;
range->max_qual.noise = 0;
-#if WIRELESS_EXT > 7
range->num_bitrates = 1;
range->bitrate[0] = 1000000; /* 1 Mb/s */
-#endif /* WIRELESS_EXT > 7 */
-#if WIRELESS_EXT > 8
range->encoding_size[0] = 2; /* 16 bits scrambling */
range->num_encoding_sizes = 1;
range->max_encoding_tokens = 1; /* Only one key possible */
-#endif /* WIRELESS_EXT > 8 */
return ret;
}
@@ -775,8 +715,6 @@ static const struct iw_priv_args netwave_private_args[] = {
"getsitesurvey" },
};
-#if WIRELESS_EXT > 12
-
static const iw_handler netwave_handler[] =
{
NULL, /* SIOCSIWNAME */
@@ -839,131 +777,8 @@ static const struct iw_handler_def netwave_handler_def =
.standard = (iw_handler *) netwave_handler,
.private = (iw_handler *) netwave_private_handler,
.private_args = (struct iw_priv_args *) netwave_private_args,
-#if WIRELESS_EXT > 16
.get_wireless_stats = netwave_get_wireless_stats,
-#endif /* WIRELESS_EXT > 16 */
};
-#endif /* WIRELESS_EXT > 12 */
-
-/*
- * Function netwave_ioctl (dev, rq, cmd)
- *
- * Perform ioctl : config & info stuff
- * This is the stuff that are treated the wireless extensions (iwconfig)
- *
- */
-static int netwave_ioctl(struct net_device *dev, /* ioctl device */
- struct ifreq *rq, /* Data passed */
- int cmd) /* Ioctl number */
-{
- int ret = 0;
-#ifdef WIRELESS_EXT
-#if WIRELESS_EXT <= 12
- struct iwreq *wrq = (struct iwreq *) rq;
-#endif
-#endif
-
- DEBUG(0, "%s: ->netwave_ioctl(cmd=0x%X)\n", dev->name, cmd);
-
- /* Look what is the request */
- switch(cmd) {
- /* --------------- WIRELESS EXTENSIONS --------------- */
-#ifdef WIRELESS_EXT
-#if WIRELESS_EXT <= 12
- case SIOCGIWNAME:
- netwave_get_name(dev, NULL, &(wrq->u), NULL);
- break;
- case SIOCSIWNWID:
- ret = netwave_set_nwid(dev, NULL, &(wrq->u), NULL);
- break;
- case SIOCGIWNWID:
- ret = netwave_get_nwid(dev, NULL, &(wrq->u), NULL);
- break;
-#if WIRELESS_EXT > 8 /* Note : The API did change... */
- case SIOCGIWENCODE:
- /* Get scramble key */
- if(wrq->u.encoding.pointer != (caddr_t) 0)
- {
- char key[2];
- ret = netwave_get_scramble(dev, NULL, &(wrq->u), key);
- if(copy_to_user(wrq->u.encoding.pointer, key, 2))
- ret = -EFAULT;
- }
- break;
- case SIOCSIWENCODE:
- /* Set scramble key */
- if(wrq->u.encoding.pointer != (caddr_t) 0)
- {
- char key[2];
- if(copy_from_user(key, wrq->u.encoding.pointer, 2))
- {
- ret = -EFAULT;
- break;
- }
- ret = netwave_set_scramble(dev, NULL, &(wrq->u), key);
- }
- break;
- case SIOCGIWMODE:
- /* Mode of operation */
- ret = netwave_get_mode(dev, NULL, &(wrq->u), NULL);
- break;
-#else /* WIRELESS_EXT > 8 */
- case SIOCGIWENCODE:
- /* Get scramble key */
- ret = netwave_get_scramble(dev, NULL, &(wrq->u),
- (char *) &wrq->u.encoding.code);
- break;
- case SIOCSIWENCODE:
- /* Set scramble key */
- ret = netwave_set_scramble(dev, NULL, &(wrq->u),
- (char *) &wrq->u.encoding.code);
- break;
-#endif /* WIRELESS_EXT > 8 */
- case SIOCGIWRANGE:
- /* Basic checking... */
- if(wrq->u.data.pointer != (caddr_t) 0) {
- struct iw_range range;
- ret = netwave_get_range(dev, NULL, &(wrq->u), (char *) &range);
- if (copy_to_user(wrq->u.data.pointer, &range,
- sizeof(struct iw_range)))
- ret = -EFAULT;
- }
- break;
- case SIOCGIWPRIV:
- /* Basic checking... */
- if(wrq->u.data.pointer != (caddr_t) 0) {
- /* Set the number of ioctl available */
- wrq->u.data.length = sizeof(netwave_private_args) / sizeof(netwave_private_args[0]);
-
- /* Copy structure to the user buffer */
- if(copy_to_user(wrq->u.data.pointer,
- (u_char *) netwave_private_args,
- sizeof(netwave_private_args)))
- ret = -EFAULT;
- }
- break;
- case SIOCGIPSNAP:
- if(wrq->u.data.pointer != (caddr_t) 0) {
- char buffer[sizeof( struct site_survey)];
- ret = netwave_get_snap(dev, NULL, &(wrq->u), buffer);
- /* Copy structure to the user buffer */
- if(copy_to_user(wrq->u.data.pointer,
- buffer,
- sizeof( struct site_survey)))
- {
- printk(KERN_DEBUG "Bad buffer!\n");
- break;
- }
- }
- break;
-#endif /* WIRELESS_EXT <= 12 */
-#endif /* WIRELESS_EXT */
- default:
- ret = -EOPNOTSUPP;
- }
-
- return ret;
-}
/*
* Function netwave_pcmcia_config (link)
diff --git a/drivers/net/wireless/orinoco.c b/drivers/net/wireless/orinoco.c
index 15ceaf615756..488ab06fb79f 100644
--- a/drivers/net/wireless/orinoco.c
+++ b/drivers/net/wireless/orinoco.c
@@ -77,30 +77,16 @@
#define DRIVER_NAME "orinoco"
#include <linux/config.h>
-
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
-#include <linux/ptrace.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <linux/timer.h>
-#include <linux/ioport.h>
#include <linux/netdevice.h>
-#include <linux/if_arp.h>
#include <linux/etherdevice.h>
#include <linux/ethtool.h>
#include <linux/wireless.h>
#include <net/iw_handler.h>
#include <net/ieee80211.h>
-#include <net/ieee80211.h>
-
-#include <asm/uaccess.h>
-#include <asm/io.h>
-#include <asm/system.h>
-
-#include "hermes.h"
#include "hermes_rid.h"
#include "orinoco.h"
@@ -137,7 +123,7 @@ MODULE_PARM_DESC(force_monitor, "Allow monitor mode for all firmware versions");
/* We do this this way to avoid ifdefs in the actual code */
#ifdef WIRELESS_SPY
-#define SPY_NUMBER(priv) (priv->spy_number)
+#define SPY_NUMBER(priv) (priv->spy_data.spy_number)
#else
#define SPY_NUMBER(priv) 0
#endif /* WIRELESS_SPY */
@@ -216,31 +202,32 @@ static struct {
/********************************************************************/
/* Used in Event handling.
- * We avoid nested structres as they break on ARM -- Moustafa */
+ * We avoid nested structures as they break on ARM -- Moustafa */
struct hermes_tx_descriptor_802_11 {
/* hermes_tx_descriptor */
- u16 status;
- u16 reserved1;
- u16 reserved2;
- u32 sw_support;
+ __le16 status;
+ __le16 reserved1;
+ __le16 reserved2;
+ __le32 sw_support;
u8 retry_count;
u8 tx_rate;
- u16 tx_control;
+ __le16 tx_control;
- /* ieee802_11_hdr */
- u16 frame_ctl;
- u16 duration_id;
+ /* ieee80211_hdr */
+ __le16 frame_ctl;
+ __le16 duration_id;
u8 addr1[ETH_ALEN];
u8 addr2[ETH_ALEN];
u8 addr3[ETH_ALEN];
- u16 seq_ctl;
+ __le16 seq_ctl;
u8 addr4[ETH_ALEN];
- u16 data_len;
+
+ __le16 data_len;
/* ethhdr */
- unsigned char h_dest[ETH_ALEN]; /* destination eth addr */
- unsigned char h_source[ETH_ALEN]; /* source ether addr */
- unsigned short h_proto; /* packet type ID field */
+ u8 h_dest[ETH_ALEN]; /* destination eth addr */
+ u8 h_source[ETH_ALEN]; /* source ether addr */
+ __be16 h_proto; /* packet type ID field */
/* p8022_hdr */
u8 dsap;
@@ -248,31 +235,31 @@ struct hermes_tx_descriptor_802_11 {
u8 ctrl;
u8 oui[3];
- u16 ethertype;
+ __be16 ethertype;
} __attribute__ ((packed));
/* Rx frame header except compatibility 802.3 header */
struct hermes_rx_descriptor {
/* Control */
- u16 status;
- u32 time;
+ __le16 status;
+ __le32 time;
u8 silence;
u8 signal;
u8 rate;
u8 rxflow;
- u32 reserved;
+ __le32 reserved;
/* 802.11 header */
- u16 frame_ctl;
- u16 duration_id;
+ __le16 frame_ctl;
+ __le16 duration_id;
u8 addr1[ETH_ALEN];
u8 addr2[ETH_ALEN];
u8 addr3[ETH_ALEN];
- u16 seq_ctl;
+ __le16 seq_ctl;
u8 addr4[ETH_ALEN];
/* Data length */
- u16 data_len;
+ __le16 data_len;
} __attribute__ ((packed));
/********************************************************************/
@@ -396,14 +383,14 @@ static struct iw_statistics *orinoco_get_wireless_stats(struct net_device *dev)
/* If a spy address is defined, we report stats of the
* first spy address - Jean II */
if (SPY_NUMBER(priv)) {
- wstats->qual.qual = priv->spy_stat[0].qual;
- wstats->qual.level = priv->spy_stat[0].level;
- wstats->qual.noise = priv->spy_stat[0].noise;
- wstats->qual.updated = priv->spy_stat[0].updated;
+ wstats->qual.qual = priv->spy_data.spy_stat[0].qual;
+ wstats->qual.level = priv->spy_data.spy_stat[0].level;
+ wstats->qual.noise = priv->spy_data.spy_stat[0].noise;
+ wstats->qual.updated = priv->spy_data.spy_stat[0].updated;
}
} else {
struct {
- u16 qual, signal, noise;
+ __le16 qual, signal, noise;
} __attribute__ ((packed)) cq;
err = HERMES_READ_RECORD(hw, USER_BAP,
@@ -503,13 +490,12 @@ static int orinoco_xmit(struct sk_buff *skb, struct net_device *dev)
return 0;
}
- /* Check packet length, pad short packets, round up odd length */
+ /* Length of the packet body */
+ /* FIXME: what if the skb is smaller than this? */
len = max_t(int, ALIGN(skb->len, 2), ETH_ZLEN);
- if (skb->len < len) {
- skb = skb_padto(skb, len);
- if (skb == NULL)
- goto fail;
- }
+ skb = skb_padto(skb, len);
+ if (skb == NULL)
+ goto fail;
len -= ETH_HLEN;
eh = (struct ethhdr *)skb->data;
@@ -556,13 +542,21 @@ static int orinoco_xmit(struct sk_buff *skb, struct net_device *dev)
stats->tx_errors++;
goto fail;
}
+ /* Actual xfer length - allow for padding */
+ len = ALIGN(data_len, 2);
+ if (len < ETH_ZLEN - ETH_HLEN)
+ len = ETH_ZLEN - ETH_HLEN;
} else { /* IEEE 802.3 frame */
data_len = len + ETH_HLEN;
data_off = HERMES_802_3_OFFSET;
p = skb->data;
+ /* Actual xfer length - round up for odd length packets */
+ len = ALIGN(data_len, 2);
+ if (len < ETH_ZLEN)
+ len = ETH_ZLEN;
}
- err = hermes_bap_pwrite(hw, USER_BAP, p, data_len,
+ err = hermes_bap_pwrite_pad(hw, USER_BAP, p, data_len, len,
txfid, data_off);
if (err) {
printk(KERN_ERR "%s: Error %d writing packet to BAP\n",
@@ -634,16 +628,17 @@ static void __orinoco_ev_txexc(struct net_device *dev, hermes_t *hw)
struct orinoco_private *priv = netdev_priv(dev);
struct net_device_stats *stats = &priv->stats;
u16 fid = hermes_read_regn(hw, TXCOMPLFID);
+ u16 status;
struct hermes_tx_descriptor_802_11 hdr;
int err = 0;
if (fid == DUMMY_FID)
return; /* Nothing's really happened */
- /* Read the frame header */
+ /* Read part of the frame header - we need status and addr1 */
err = hermes_bap_pread(hw, IRQ_BAP, &hdr,
- sizeof(struct hermes_tx_descriptor) +
- sizeof(struct ieee80211_hdr),
+ offsetof(struct hermes_tx_descriptor_802_11,
+ addr2),
fid, 0);
hermes_write_regn(hw, TXCOMPLFID, DUMMY_FID);
@@ -663,8 +658,8 @@ static void __orinoco_ev_txexc(struct net_device *dev, hermes_t *hw)
* exceeded, because that's the only status that really mean
* that this particular node went away.
* Other errors means that *we* screwed up. - Jean II */
- hdr.status = le16_to_cpu(hdr.status);
- if (hdr.status & (HERMES_TXSTAT_RETRYERR | HERMES_TXSTAT_AGEDERR)) {
+ status = le16_to_cpu(hdr.status);
+ if (status & (HERMES_TXSTAT_RETRYERR | HERMES_TXSTAT_AGEDERR)) {
union iwreq_data wrqu;
/* Copy 802.11 dest address.
@@ -723,18 +718,13 @@ static inline int is_ethersnap(void *_hdr)
static inline void orinoco_spy_gather(struct net_device *dev, u_char *mac,
int level, int noise)
{
- struct orinoco_private *priv = netdev_priv(dev);
- int i;
-
- /* Gather wireless spy statistics: for each packet, compare the
- * source address with out list, and if match, get the stats... */
- for (i = 0; i < priv->spy_number; i++)
- if (!memcmp(mac, priv->spy_address[i], ETH_ALEN)) {
- priv->spy_stat[i].level = level - 0x95;
- priv->spy_stat[i].noise = noise - 0x95;
- priv->spy_stat[i].qual = (level > noise) ? (level - noise) : 0;
- priv->spy_stat[i].updated = 7;
- }
+ struct iw_quality wstats;
+ wstats.level = level - 0x95;
+ wstats.noise = noise - 0x95;
+ wstats.qual = (level > noise) ? (level - noise) : 0;
+ wstats.updated = 7;
+ /* Update spy records */
+ wireless_spy_update(dev, mac, &wstats);
}
static void orinoco_stat_gather(struct net_device *dev,
@@ -1055,7 +1045,7 @@ static void orinoco_join_ap(struct net_device *dev)
unsigned long flags;
struct join_req {
u8 bssid[ETH_ALEN];
- u16 channel;
+ __le16 channel;
} __attribute__ ((packed)) req;
const int atom_len = offsetof(struct prism2_scan_apinfo, atim);
struct prism2_scan_apinfo *atom = NULL;
@@ -1070,7 +1060,7 @@ static void orinoco_join_ap(struct net_device *dev)
return;
if (orinoco_lock(priv, &flags) != 0)
- goto out;
+ goto fail_lock;
/* Sanity checks in case user changed something in the meantime */
if (! priv->bssid_fixed)
@@ -1115,8 +1105,10 @@ static void orinoco_join_ap(struct net_device *dev)
printk(KERN_ERR "%s: Error issuing join request\n", dev->name);
out:
- kfree(buf);
orinoco_unlock(priv, &flags);
+
+ fail_lock:
+ kfree(buf);
}
/* Send new BSSID to userspace */
@@ -1134,12 +1126,14 @@ static void orinoco_send_wevents(struct net_device *dev)
err = hermes_read_ltv(hw, IRQ_BAP, HERMES_RID_CURRENTBSSID,
ETH_ALEN, NULL, wrqu.ap_addr.sa_data);
if (err != 0)
- return;
+ goto out;
wrqu.ap_addr.sa_family = ARPHRD_ETHER;
/* Send event to user space */
wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL);
+
+ out:
orinoco_unlock(priv, &flags);
}
@@ -1148,8 +1142,8 @@ static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw)
struct orinoco_private *priv = netdev_priv(dev);
u16 infofid;
struct {
- u16 len;
- u16 type;
+ __le16 len;
+ __le16 type;
} __attribute__ ((packed)) info;
int len, type;
int err;
@@ -2464,6 +2458,10 @@ struct net_device *alloc_orinocodev(int sizeof_card,
dev->get_stats = orinoco_get_stats;
dev->ethtool_ops = &orinoco_ethtool_ops;
dev->wireless_handlers = (struct iw_handler_def *)&orinoco_handler_def;
+#ifdef WIRELESS_SPY
+ priv->wireless_data.spy_data = &priv->spy_data;
+ dev->wireless_data = &priv->wireless_data;
+#endif
dev->change_mtu = orinoco_change_mtu;
dev->set_multicast_list = orinoco_set_multicast_list;
/* we use the default eth_mac_addr for setting the MAC addr */
@@ -2835,7 +2833,7 @@ static int orinoco_ioctl_getiwrange(struct net_device *dev,
}
}
- if ((priv->iw_mode == IW_MODE_ADHOC) && (priv->spy_number == 0)){
+ if ((priv->iw_mode == IW_MODE_ADHOC) && (!SPY_NUMBER(priv))){
/* Quality stats meaningless in ad-hoc mode */
} else {
range->max_qual.qual = 0x8b - 0x2f;
@@ -2882,6 +2880,14 @@ static int orinoco_ioctl_getiwrange(struct net_device *dev,
range->min_r_time = 0;
range->max_r_time = 65535 * 1000; /* ??? */
+ /* Event capability (kernel) */
+ IW_EVENT_CAPA_SET_KERNEL(range->event_capa);
+ /* Event capability (driver) */
+ IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWTHRSPY);
+ IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWAP);
+ IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWSCAN);
+ IW_EVENT_CAPA_SET(range->event_capa, IWEVTXDROP);
+
TRACE_EXIT(dev->name);
return 0;
@@ -3841,92 +3847,6 @@ static int orinoco_ioctl_getrid(struct net_device *dev,
return err;
}
-/* Spy is used for link quality/strength measurements in Ad-Hoc mode
- * Jean II */
-static int orinoco_ioctl_setspy(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_point *srq,
- char *extra)
-
-{
- struct orinoco_private *priv = netdev_priv(dev);
- struct sockaddr *address = (struct sockaddr *) extra;
- int number = srq->length;
- int i;
- unsigned long flags;
-
- /* Make sure nobody mess with the structure while we do */
- if (orinoco_lock(priv, &flags) != 0)
- return -EBUSY;
-
- /* orinoco_lock() doesn't disable interrupts, so make sure the
- * interrupt rx path don't get confused while we copy */
- priv->spy_number = 0;
-
- if (number > 0) {
- /* Extract the addresses */
- for (i = 0; i < number; i++)
- memcpy(priv->spy_address[i], address[i].sa_data,
- ETH_ALEN);
- /* Reset stats */
- memset(priv->spy_stat, 0,
- sizeof(struct iw_quality) * IW_MAX_SPY);
- /* Set number of addresses */
- priv->spy_number = number;
- }
-
- /* Now, let the others play */
- orinoco_unlock(priv, &flags);
-
- /* Do NOT call commit handler */
- return 0;
-}
-
-static int orinoco_ioctl_getspy(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_point *srq,
- char *extra)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- struct sockaddr *address = (struct sockaddr *) extra;
- int number;
- int i;
- unsigned long flags;
-
- if (orinoco_lock(priv, &flags) != 0)
- return -EBUSY;
-
- number = priv->spy_number;
- /* Create address struct */
- for (i = 0; i < number; i++) {
- memcpy(address[i].sa_data, priv->spy_address[i], ETH_ALEN);
- address[i].sa_family = AF_UNIX;
- }
- if (number > 0) {
- /* Create address struct */
- for (i = 0; i < number; i++) {
- memcpy(address[i].sa_data, priv->spy_address[i],
- ETH_ALEN);
- address[i].sa_family = AF_UNIX;
- }
- /* Copy stats */
- /* In theory, we should disable irqs while copying the stats
- * because the rx path might update it in the middle...
- * Bah, who care ? - Jean II */
- memcpy(extra + (sizeof(struct sockaddr) * number),
- priv->spy_stat, sizeof(struct iw_quality) * number);
- }
- /* Reset updated flags. */
- for (i = 0; i < number; i++)
- priv->spy_stat[i].updated = 0;
-
- orinoco_unlock(priv, &flags);
-
- srq->length = number;
-
- return 0;
-}
-
/* Trigger a scan (look for other cells in the vicinity */
static int orinoco_ioctl_setscan(struct net_device *dev,
struct iw_request_info *info,
@@ -3999,7 +3919,7 @@ static int orinoco_ioctl_setscan(struct net_device *dev,
HERMES_HOSTSCAN_SYMBOL_BCAST);
break;
case FIRMWARE_TYPE_INTERSIL: {
- u16 req[3];
+ __le16 req[3];
req[0] = cpu_to_le16(0x3fff); /* All channels */
req[1] = cpu_to_le16(0x0001); /* rate 1 Mbps */
@@ -4073,7 +3993,7 @@ static inline int orinoco_translate_scan(struct net_device *dev,
case FIRMWARE_TYPE_INTERSIL:
offset = 4;
if (priv->has_hostscan) {
- atom_len = le16_to_cpup((u16 *)scan);
+ atom_len = le16_to_cpup((__le16 *)scan);
/* Sanity check for atom_len */
if (atom_len < sizeof(struct prism2_scan_apinfo)) {
printk(KERN_ERR "%s: Invalid atom_len in scan data: %d\n",
@@ -4357,8 +4277,10 @@ static const iw_handler orinoco_handler[] = {
[SIOCSIWSENS -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setsens,
[SIOCGIWSENS -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getsens,
[SIOCGIWRANGE -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getiwrange,
- [SIOCSIWSPY -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setspy,
- [SIOCGIWSPY -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getspy,
+ [SIOCSIWSPY -SIOCIWFIRST] = (iw_handler) iw_handler_set_spy,
+ [SIOCGIWSPY -SIOCIWFIRST] = (iw_handler) iw_handler_get_spy,
+ [SIOCSIWTHRSPY-SIOCIWFIRST] = (iw_handler) iw_handler_set_thrspy,
+ [SIOCGIWTHRSPY-SIOCIWFIRST] = (iw_handler) iw_handler_get_thrspy,
[SIOCSIWAP -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setwap,
[SIOCGIWAP -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getwap,
[SIOCSIWSCAN -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setscan,
diff --git a/drivers/net/wireless/orinoco.h b/drivers/net/wireless/orinoco.h
index 2f213a7103fe..f5d856db92a1 100644
--- a/drivers/net/wireless/orinoco.h
+++ b/drivers/net/wireless/orinoco.h
@@ -7,13 +7,11 @@
#ifndef _ORINOCO_H
#define _ORINOCO_H
-#define DRIVER_VERSION "0.15rc2"
+#define DRIVER_VERSION "0.15rc3"
-#include <linux/types.h>
-#include <linux/spinlock.h>
#include <linux/netdevice.h>
#include <linux/wireless.h>
-#include <linux/version.h>
+#include <net/iw_handler.h>
#include "hermes.h"
@@ -28,7 +26,7 @@
#define ORINOCO_MAX_KEYS 4
struct orinoco_key {
- u16 len; /* always stored as little-endian */
+ __le16 len; /* always stored as little-endian */
char data[ORINOCO_MAX_KEY_SIZE];
} __attribute__ ((packed));
@@ -36,14 +34,14 @@ struct header_struct {
/* 802.3 */
u8 dest[ETH_ALEN];
u8 src[ETH_ALEN];
- u16 len;
+ __be16 len;
/* 802.2 */
u8 dsap;
u8 ssap;
u8 ctrl;
/* SNAP */
u8 oui[3];
- u16 ethertype;
+ unsigned short ethertype;
} __attribute__ ((packed));
typedef enum {
@@ -112,9 +110,8 @@ struct orinoco_private {
u16 pm_on, pm_mcast, pm_period, pm_timeout;
u16 preamble;
#ifdef WIRELESS_SPY
- int spy_number;
- u_char spy_address[IW_MAX_SPY][ETH_ALEN];
- struct iw_quality spy_stat[IW_MAX_SPY];
+ struct iw_spy_data spy_data; /* iwspy support */
+ struct iw_public_data wireless_data;
#endif
/* Configuration dependent variables */
diff --git a/drivers/net/wireless/orinoco_cs.c b/drivers/net/wireless/orinoco_cs.c
index bedd7f9f23e4..dc1128a00971 100644
--- a/drivers/net/wireless/orinoco_cs.c
+++ b/drivers/net/wireless/orinoco_cs.c
@@ -14,33 +14,16 @@
#define PFX DRIVER_NAME ": "
#include <linux/config.h>
-#ifdef __IN_PCMCIA_PACKAGE__
-#include <pcmcia/k_compat.h>
-#endif /* __IN_PCMCIA_PACKAGE__ */
-
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
-#include <linux/sched.h>
-#include <linux/ptrace.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <linux/ioport.h>
-#include <linux/netdevice.h>
-#include <linux/if_arp.h>
-#include <linux/etherdevice.h>
-#include <linux/wireless.h>
-
+#include <linux/delay.h>
#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h>
#include <pcmcia/cisreg.h>
#include <pcmcia/ds.h>
-#include <asm/uaccess.h>
-#include <asm/io.h>
-#include <asm/system.h>
-
#include "orinoco.h"
/********************************************************************/
@@ -97,17 +80,8 @@ static dev_link_t *dev_list; /* = NULL */
/* Function prototypes */
/********************************************************************/
-/* device methods */
-static int orinoco_cs_hard_reset(struct orinoco_private *priv);
-
-/* PCMCIA gumpf */
-static void orinoco_cs_config(dev_link_t * link);
-static void orinoco_cs_release(dev_link_t * link);
-static int orinoco_cs_event(event_t event, int priority,
- event_callback_args_t * args);
-
-static dev_link_t *orinoco_cs_attach(void);
-static void orinoco_cs_detach(dev_link_t *);
+static void orinoco_cs_release(dev_link_t *link);
+static void orinoco_cs_detach(dev_link_t *link);
/********************************************************************/
/* Device methods */
@@ -603,49 +577,85 @@ static char version[] __initdata = DRIVER_NAME " " DRIVER_VERSION
"Pavel Roskin <proski@gnu.org>, et al)";
static struct pcmcia_device_id orinoco_cs_ids[] = {
- PCMCIA_DEVICE_MANF_CARD(0x000b, 0x7300),
- PCMCIA_DEVICE_MANF_CARD(0x0138, 0x0002),
- PCMCIA_DEVICE_MANF_CARD(0x0156, 0x0002),
- PCMCIA_DEVICE_MANF_CARD(0x01eb, 0x080a),
- PCMCIA_DEVICE_MANF_CARD(0x0261, 0x0002),
- PCMCIA_DEVICE_MANF_CARD(0x0268, 0x0001),
- PCMCIA_DEVICE_MANF_CARD(0x026f, 0x0305),
- PCMCIA_DEVICE_MANF_CARD(0x0274, 0x1613),
- PCMCIA_DEVICE_MANF_CARD(0x028a, 0x0002),
- PCMCIA_DEVICE_MANF_CARD(0x028a, 0x0673),
- PCMCIA_DEVICE_MANF_CARD(0x02aa, 0x0002),
- PCMCIA_DEVICE_MANF_CARD(0x02ac, 0x0002),
- PCMCIA_DEVICE_MANF_CARD(0x14ea, 0xb001),
- PCMCIA_DEVICE_MANF_CARD(0x50c2, 0x7300),
- PCMCIA_DEVICE_MANF_CARD(0x9005, 0x0021),
- PCMCIA_DEVICE_MANF_CARD(0xc250, 0x0002),
- PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0002),
- PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0005),
+ PCMCIA_DEVICE_MANF_CARD(0x000b, 0x7100), /* SonicWALL Long Range Wireless Card */
+ PCMCIA_DEVICE_MANF_CARD(0x000b, 0x7300), /* Sohoware NCP110, Philips 802.11b */
+ PCMCIA_DEVICE_MANF_CARD(0x0089, 0x0002), /* AnyPoint(TM) Wireless II PC Card */
+ PCMCIA_DEVICE_MANF_CARD(0x0101, 0x0777), /* 3Com AirConnect PCI 777A */
+ PCMCIA_DEVICE_MANF_CARD(0x0126, 0x8000), /* PROXIM RangeLAN-DS/LAN PC CARD */
+ PCMCIA_DEVICE_MANF_CARD(0x0138, 0x0002), /* Compaq WL100 11 Mbps Wireless Adapter */
+ PCMCIA_DEVICE_MANF_CARD(0x0156, 0x0002), /* Lucent Orinoco and old Intersil */
+ PCMCIA_DEVICE_MANF_CARD(0x016b, 0x0001), /* Ericsson WLAN Card C11 */
+ PCMCIA_DEVICE_MANF_CARD(0x01eb, 0x080a), /* Nortel Networks eMobility 802.11 Wireless Adapter */
+ PCMCIA_DEVICE_MANF_CARD(0x01ff, 0x0008), /* Intermec MobileLAN 11Mbps 802.11b WLAN Card */
+ PCMCIA_DEVICE_MANF_CARD(0x0250, 0x0002), /* Samsung SWL2000-N 11Mb/s WLAN Card */
+ PCMCIA_DEVICE_MANF_CARD(0x0261, 0x0002), /* AirWay 802.11 Adapter (PCMCIA) */
+ PCMCIA_DEVICE_MANF_CARD(0x0268, 0x0001), /* ARtem Onair */
+ PCMCIA_DEVICE_MANF_CARD(0x026f, 0x0305), /* Buffalo WLI-PCM-S11 */
+ PCMCIA_DEVICE_MANF_CARD(0x0274, 0x1612), /* Linksys WPC11 Version 2.5 */
+ PCMCIA_DEVICE_MANF_CARD(0x0274, 0x1613), /* Linksys WPC11 Version 3 */
+ PCMCIA_DEVICE_MANF_CARD(0x028a, 0x0002), /* Compaq HNW-100 11 Mbps Wireless Adapter */
+ PCMCIA_DEVICE_MANF_CARD(0x028a, 0x0673), /* Linksys WCF12 Wireless CompactFlash Card */
+ PCMCIA_DEVICE_MANF_CARD(0x02aa, 0x0002), /* ASUS SpaceLink WL-100 */
+ PCMCIA_DEVICE_MANF_CARD(0x02ac, 0x0002), /* SpeedStream SS1021 Wireless Adapter */
+ PCMCIA_DEVICE_MANF_CARD(0x14ea, 0xb001), /* PLANEX RoadLannerWave GW-NS11H */
+ PCMCIA_DEVICE_MANF_CARD(0x50c2, 0x7300), /* Airvast WN-100 */
+ PCMCIA_DEVICE_MANF_CARD(0x9005, 0x0021), /* Adaptec Ultra Wireless ANW-8030 */
+ PCMCIA_DEVICE_MANF_CARD(0xc001, 0x0008), /* CONTEC FLEXSCAN/FX-DDS110-PCC */
+ PCMCIA_DEVICE_MANF_CARD(0xc250, 0x0002), /* Conceptronic CON11Cpro, EMTAC A2424i */
+ PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0002), /* Safeway 802.11b, ZCOMAX AirRunner/XI-300 */
+ PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0005), /* D-Link DCF660, Sandisk Connect SDWCFB-000 */
+ PCMCIA_DEVICE_PROD_ID12(" ", "IEEE 802.11 Wireless LAN/PC Card", 0x3b6e20c8, 0xefccafe9),
PCMCIA_DEVICE_PROD_ID12("3Com", "3CRWE737A AirConnect Wireless LAN PC Card", 0x41240e5b, 0x56010af3),
- PCMCIA_DEVICE_PROD_ID123("Instant Wireless ", " Network PC CARD", "Version 01.02", 0x11d901af, 0x6e9bd926, 0x4b74baa0),
PCMCIA_DEVICE_PROD_ID12("ACTIONTEC", "PRISM Wireless LAN PC Card", 0x393089da, 0xa71e69d5),
+ PCMCIA_DEVICE_PROD_ID12("Addtron", "AWP-100 Wireless PCMCIA", 0xe6ec52ce, 0x08649af2),
+ PCMCIA_DEVICE_PROD_ID123("AIRVAST", "IEEE 802.11b Wireless PCMCIA Card", "HFA3863", 0xea569531, 0x4bcb9645, 0x355cb092),
+ PCMCIA_DEVICE_PROD_ID12("Allied Telesyn", "AT-WCL452 Wireless PCMCIA Radio", 0x5cd01705, 0x4271660f),
+ PCMCIA_DEVICE_PROD_ID12("ASUS", "802_11b_PC_CARD_25", 0x78fc06ee, 0xdb9aa842),
+ PCMCIA_DEVICE_PROD_ID12("ASUS", "802_11B_CF_CARD_25", 0x78fc06ee, 0x45a50c1e),
PCMCIA_DEVICE_PROD_ID12("Avaya Communication", "Avaya Wireless PC Card", 0xd8a43b78, 0x0d341169),
+ PCMCIA_DEVICE_PROD_ID12("BENQ", "AWL100 PCMCIA ADAPTER", 0x35dadc74, 0x01f7fedb),
PCMCIA_DEVICE_PROD_ID12("BUFFALO", "WLI-PCM-L11G", 0x2decece3, 0xf57ca4b3),
+ PCMCIA_DEVICE_PROD_ID12("BUFFALO", "WLI-CF-S11G", 0x2decece3, 0x82067c18),
PCMCIA_DEVICE_PROD_ID12("Cabletron", "RoamAbout 802.11 DS", 0x32d445f5, 0xedeffd90),
+ PCMCIA_DEVICE_PROD_ID12("Compaq", "WL200_11Mbps_Wireless_PCI_Card", 0x54f7c49c, 0x15a75e5b),
+ PCMCIA_DEVICE_PROD_ID123("corega", "WL PCCL-11", "ISL37300P", 0x0a21501a, 0x59868926, 0xc9049a39),
PCMCIA_DEVICE_PROD_ID12("corega K.K.", "Wireless LAN PCC-11", 0x5261440f, 0xa6405584),
PCMCIA_DEVICE_PROD_ID12("corega K.K.", "Wireless LAN PCCA-11", 0x5261440f, 0xdf6115f9),
PCMCIA_DEVICE_PROD_ID12("corega_K.K.", "Wireless_LAN_PCCB-11", 0x29e33311, 0xee7a27ae),
PCMCIA_DEVICE_PROD_ID12("D", "Link DRC-650 11Mbps WLAN Card", 0x71b18589, 0xf144e3ac),
PCMCIA_DEVICE_PROD_ID12("D", "Link DWL-650 11Mbps WLAN Card", 0x71b18589, 0xb6f1b0ab),
+ PCMCIA_DEVICE_PROD_ID12("D-Link Corporation", "D-Link DWL-650H 11Mbps WLAN Adapter", 0xef544d24, 0xcd8ea916),
+ PCMCIA_DEVICE_PROD_ID12("Digital Data Communications", "WPC-0100", 0xfdd73470, 0xe0b6f146),
PCMCIA_DEVICE_PROD_ID12("ELSA", "AirLancer MC-11", 0x4507a33a, 0xef54f0e3),
PCMCIA_DEVICE_PROD_ID12("HyperLink", "Wireless PC Card 11Mbps", 0x56cc3f1a, 0x0bcf220c),
+ PCMCIA_DEVICE_PROD_ID123("Instant Wireless ", " Network PC CARD", "Version 01.02", 0x11d901af, 0x6e9bd926, 0x4b74baa0),
+ PCMCIA_DEVICE_PROD_ID12("Intel", "PRO/Wireless 2011 LAN PC Card", 0x816cc815, 0x07f58077),
PCMCIA_DEVICE_PROD_ID12("INTERSIL", "HFA384x/IEEE", 0x74c5e40d, 0xdb472a18),
+ PCMCIA_DEVICE_PROD_ID12("INTERSIL", "I-GATE 11M PC Card / PC Card plus", 0x74c5e40d, 0x8304ff77),
+ PCMCIA_DEVICE_PROD_ID12("Intersil", "PRISM 2_5 PCMCIA ADAPTER", 0x4b801a17, 0x6345a0bf),
+ PCMCIA_DEVICE_PROD_ID123("Intersil", "PRISM Freedom PCMCIA Adapter", "ISL37100P", 0x4b801a17, 0xf222ec2d, 0x630d52b2),
+ PCMCIA_DEVICE_PROD_ID12("LeArtery", "SYNCBYAIR 11Mbps Wireless LAN PC Card", 0x7e3b326a, 0x49893e92),
+ PCMCIA_DEVICE_PROD_ID12("Linksys", "Wireless CompactFlash Card", 0x0733cc81, 0x0c52f395),
PCMCIA_DEVICE_PROD_ID12("Lucent Technologies", "WaveLAN/IEEE", 0x23eb9949, 0xc562e72a),
PCMCIA_DEVICE_PROD_ID12("MELCO", "WLI-PCM-L11", 0x481e0094, 0x7360e410),
PCMCIA_DEVICE_PROD_ID12("MELCO", "WLI-PCM-L11G", 0x481e0094, 0xf57ca4b3),
PCMCIA_DEVICE_PROD_ID12("Microsoft", "Wireless Notebook Adapter MN-520", 0x5961bf85, 0x6eec8c01),
PCMCIA_DEVICE_PROD_ID12("NCR", "WaveLAN/IEEE", 0x24358cd4, 0xc562e72a),
+ PCMCIA_DEVICE_PROD_ID12("NETGEAR MA401 Wireless PC", "Card", 0xa37434e9, 0x9762e8f1),
PCMCIA_DEVICE_PROD_ID12("NETGEAR MA401RA Wireless PC", "Card", 0x0306467f, 0x9762e8f1),
+ PCMCIA_DEVICE_PROD_ID12("Nortel Networks", "emobility 802.11 Wireless LAN PC Card", 0x2d617ea0, 0x88cd5767),
+ PCMCIA_DEVICE_PROD_ID12("OEM", "PRISM2 IEEE 802.11 PC-Card", 0xfea54c90, 0x48f2bdd6),
+ PCMCIA_DEVICE_PROD_ID12("OTC", "Wireless AirEZY 2411-PCC WLAN Card", 0x4ac44287, 0x235a6bed),
+ PCMCIA_DEVICE_PROD_ID123("PCMCIA", "11M WLAN Card v2.5", "ISL37300P", 0x281f1c5d, 0x6e440487, 0xc9049a39),
PCMCIA_DEVICE_PROD_ID12("PLANEX", "GeoWave/GW-CF110", 0x209f40ab, 0xd9715264),
+ PCMCIA_DEVICE_PROD_ID12("PLANEX", "GeoWave/GW-NS110", 0x209f40ab, 0x46263178),
PCMCIA_DEVICE_PROD_ID12("PROXIM", "LAN PC CARD HARMONY 80211B", 0xc6536a5e, 0x090c3cd9),
PCMCIA_DEVICE_PROD_ID12("PROXIM", "LAN PCI CARD HARMONY 80211B", 0xc6536a5e, 0x9f494e26),
PCMCIA_DEVICE_PROD_ID12("SAMSUNG", "11Mbps WLAN Card", 0x43d74cb4, 0x579bd91b),
- PCMCIA_DEVICE_PROD_ID1("Symbol Technologies", 0x3f02b4d6),
+ PCMCIA_DEVICE_PROD_ID12("SMC", "SMC2632W", 0xc4f8b18b, 0x474a1f2a),
+ PCMCIA_DEVICE_PROD_ID12("Symbol Technologies", "LA4111 Spectrum24 Wireless LAN PC Card", 0x3f02b4d6, 0x3663cb0e),
+ PCMCIA_DEVICE_PROD_ID123("The Linksys Group, Inc.", "Instant Wireless Network PC Card", "ISL37300P", 0xa5f472c2, 0x590eb502, 0xc9049a39),
+ PCMCIA_DEVICE_PROD_ID12("ZoomAir 11Mbps High", "Rate wireless Networking", 0x273fe3db, 0x32a1eaee),
PCMCIA_DEVICE_NULL,
};
MODULE_DEVICE_TABLE(pcmcia, orinoco_cs_ids);
@@ -656,8 +666,8 @@ static struct pcmcia_driver orinoco_driver = {
.name = DRIVER_NAME,
},
.attach = orinoco_cs_attach,
- .event = orinoco_cs_event,
.detach = orinoco_cs_detach,
+ .event = orinoco_cs_event,
.id_table = orinoco_cs_ids,
};
diff --git a/drivers/net/wireless/orinoco_nortel.c b/drivers/net/wireless/orinoco_nortel.c
index 86fa58e5cfac..d8afd51ff8a5 100644
--- a/drivers/net/wireless/orinoco_nortel.c
+++ b/drivers/net/wireless/orinoco_nortel.c
@@ -40,29 +40,13 @@
#define PFX DRIVER_NAME ": "
#include <linux/config.h>
-
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
-#include <linux/sched.h>
-#include <linux/ptrace.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <linux/timer.h>
-#include <linux/ioport.h>
-#include <asm/uaccess.h>
-#include <asm/io.h>
-#include <asm/system.h>
-#include <linux/netdevice.h>
-#include <linux/if_arp.h>
-#include <linux/etherdevice.h>
-#include <linux/list.h>
+#include <linux/delay.h>
#include <linux/pci.h>
-#include <linux/fcntl.h>
-
#include <pcmcia/cisreg.h>
-#include "hermes.h"
#include "orinoco.h"
#define COR_OFFSET (0xe0) /* COR attribute offset of Prism2 PC card */
@@ -108,7 +92,7 @@ static int nortel_pci_cor_reset(struct orinoco_private *priv)
return 0;
}
-int nortel_pci_hw_init(struct nortel_pci_card *card)
+static int nortel_pci_hw_init(struct nortel_pci_card *card)
{
int i;
u32 reg;
diff --git a/drivers/net/wireless/orinoco_pci.c b/drivers/net/wireless/orinoco_pci.c
index 42e03438291b..5362c214fc8e 100644
--- a/drivers/net/wireless/orinoco_pci.c
+++ b/drivers/net/wireless/orinoco_pci.c
@@ -93,28 +93,12 @@
#define PFX DRIVER_NAME ": "
#include <linux/config.h>
-
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
-#include <linux/sched.h>
-#include <linux/ptrace.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <linux/timer.h>
-#include <linux/ioport.h>
-#include <linux/netdevice.h>
-#include <linux/if_arp.h>
-#include <linux/etherdevice.h>
-#include <linux/list.h>
+#include <linux/delay.h>
#include <linux/pci.h>
-#include <linux/fcntl.h>
-
-#include <asm/uaccess.h>
-#include <asm/io.h>
-#include <asm/system.h>
-#include "hermes.h"
#include "orinoco.h"
/* All the magic there is from wlan-ng */
diff --git a/drivers/net/wireless/orinoco_plx.c b/drivers/net/wireless/orinoco_plx.c
index 7ab05b89fb3f..210e73776545 100644
--- a/drivers/net/wireless/orinoco_plx.c
+++ b/drivers/net/wireless/orinoco_plx.c
@@ -117,29 +117,13 @@
#define PFX DRIVER_NAME ": "
#include <linux/config.h>
-
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
-#include <linux/sched.h>
-#include <linux/ptrace.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <linux/timer.h>
-#include <linux/ioport.h>
-#include <asm/uaccess.h>
-#include <asm/io.h>
-#include <asm/system.h>
-#include <linux/netdevice.h>
-#include <linux/if_arp.h>
-#include <linux/etherdevice.h>
-#include <linux/list.h>
+#include <linux/delay.h>
#include <linux/pci.h>
-#include <linux/fcntl.h>
-
#include <pcmcia/cisreg.h>
-#include "hermes.h"
#include "orinoco.h"
#define COR_OFFSET (0x3e0) /* COR attribute offset of Prism2 PC card */
diff --git a/drivers/net/wireless/orinoco_tmd.c b/drivers/net/wireless/orinoco_tmd.c
index 85893f42445b..5e68b7026186 100644
--- a/drivers/net/wireless/orinoco_tmd.c
+++ b/drivers/net/wireless/orinoco_tmd.c
@@ -53,29 +53,13 @@
#define PFX DRIVER_NAME ": "
#include <linux/config.h>
-
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
-#include <linux/sched.h>
-#include <linux/ptrace.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <linux/timer.h>
-#include <linux/ioport.h>
-#include <asm/uaccess.h>
-#include <asm/io.h>
-#include <asm/system.h>
-#include <linux/netdevice.h>
-#include <linux/if_arp.h>
-#include <linux/etherdevice.h>
-#include <linux/list.h>
+#include <linux/delay.h>
#include <linux/pci.h>
-#include <linux/fcntl.h>
-
#include <pcmcia/cisreg.h>
-#include "hermes.h"
#include "orinoco.h"
#define COR_VALUE (COR_LEVEL_REQ | COR_FUNC_ENA) /* Enable PC card with interrupt in level trigger */
diff --git a/drivers/net/wireless/prism54/isl_38xx.c b/drivers/net/wireless/prism54/isl_38xx.c
index adc7499136dc..109a96d90007 100644
--- a/drivers/net/wireless/prism54/isl_38xx.c
+++ b/drivers/net/wireless/prism54/isl_38xx.c
@@ -18,7 +18,6 @@
*
*/
-#include <linux/version.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/delay.h>
@@ -112,9 +111,10 @@ isl38xx_handle_wakeup(isl38xx_control_block *control_block,
void
isl38xx_trigger_device(int asleep, void __iomem *device_base)
{
- u32 reg, counter = 0;
+ u32 reg;
#if VERBOSE > SHOW_ERROR_MESSAGES
+ u32 counter = 0;
struct timeval current_time;
DEBUG(SHOW_FUNCTION_CALLS, "isl38xx trigger device\n");
#endif
@@ -131,7 +131,6 @@ isl38xx_trigger_device(int asleep, void __iomem *device_base)
current_time.tv_sec, (long)current_time.tv_usec,
readl(device_base + ISL38XX_CTRL_STAT_REG));
#endif
- udelay(ISL38XX_WRITEIO_DELAY);
reg = readl(device_base + ISL38XX_INT_IDENT_REG);
if (reg == 0xabadface) {
@@ -145,7 +144,9 @@ isl38xx_trigger_device(int asleep, void __iomem *device_base)
while (reg = readl(device_base + ISL38XX_CTRL_STAT_REG),
(reg & ISL38XX_CTRL_STAT_SLEEPMODE) == 0) {
udelay(ISL38XX_WRITEIO_DELAY);
+#if VERBOSE > SHOW_ERROR_MESSAGES
counter++;
+#endif
}
#if VERBOSE > SHOW_ERROR_MESSAGES
@@ -153,10 +154,6 @@ isl38xx_trigger_device(int asleep, void __iomem *device_base)
"%08li.%08li Device register read %08x\n",
current_time.tv_sec, (long)current_time.tv_usec,
readl(device_base + ISL38XX_CTRL_STAT_REG));
-#endif
- udelay(ISL38XX_WRITEIO_DELAY);
-
-#if VERBOSE > SHOW_ERROR_MESSAGES
do_gettimeofday(&current_time);
DEBUG(SHOW_TRACING,
"%08li.%08li Device asleep counter %i\n",
@@ -171,7 +168,6 @@ isl38xx_trigger_device(int asleep, void __iomem *device_base)
/* perform another read on the Device Status Register */
reg = readl(device_base + ISL38XX_CTRL_STAT_REG);
- udelay(ISL38XX_WRITEIO_DELAY);
#if VERBOSE > SHOW_ERROR_MESSAGES
do_gettimeofday(&current_time);
@@ -187,7 +183,6 @@ isl38xx_trigger_device(int asleep, void __iomem *device_base)
isl38xx_w32_flush(device_base, ISL38XX_DEV_INT_UPDATE,
ISL38XX_DEV_INT_REG);
- udelay(ISL38XX_WRITEIO_DELAY);
}
}
diff --git a/drivers/net/wireless/prism54/isl_38xx.h b/drivers/net/wireless/prism54/isl_38xx.h
index e83e4912ab66..8af20980af8d 100644
--- a/drivers/net/wireless/prism54/isl_38xx.h
+++ b/drivers/net/wireless/prism54/isl_38xx.h
@@ -20,7 +20,6 @@
#ifndef _ISL_38XX_H
#define _ISL_38XX_H
-#include <linux/version.h>
#include <asm/io.h>
#include <asm/byteorder.h>
diff --git a/drivers/net/wireless/prism54/isl_ioctl.c b/drivers/net/wireless/prism54/isl_ioctl.c
index 9a8790e3580c..135a156db25d 100644
--- a/drivers/net/wireless/prism54/isl_ioctl.c
+++ b/drivers/net/wireless/prism54/isl_ioctl.c
@@ -20,7 +20,6 @@
*
*/
-#include <linux/version.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/if_arp.h>
@@ -462,14 +461,12 @@ prism54_get_range(struct net_device *ndev, struct iw_request_info *info,
/* txpower is supported in dBm's */
range->txpower_capa = IW_TXPOW_DBM;
-#if WIRELESS_EXT > 16
/* Event capability (kernel + driver) */
range->event_capa[0] = (IW_EVENT_CAPA_K_0 |
IW_EVENT_CAPA_MASK(SIOCGIWTHRSPY) |
IW_EVENT_CAPA_MASK(SIOCGIWAP));
range->event_capa[1] = IW_EVENT_CAPA_K_1;
range->event_capa[4] = IW_EVENT_CAPA_MASK(IWEVCUSTOM);
-#endif /* WIRELESS_EXT > 16 */
if (islpci_get_state(priv) < PRV_STATE_INIT)
return 0;
@@ -693,14 +690,13 @@ prism54_get_scan(struct net_device *ndev, struct iw_request_info *info,
extra + dwrq->length,
&(bsslist->bsslist[i]),
noise);
-#if WIRELESS_EXT > 16
+
/* Check if there is space for one more entry */
if((extra + dwrq->length - current_ev) <= IW_EV_ADDR_LEN) {
/* Ask user space to try again with a bigger buffer */
rvalue = -E2BIG;
break;
}
-#endif /* WIRELESS_EXT > 16 */
}
kfree(bsslist);
@@ -2727,12 +2723,7 @@ const struct iw_handler_def prism54_handler_def = {
.standard = (iw_handler *) prism54_handler,
.private = (iw_handler *) prism54_private_handler,
.private_args = (struct iw_priv_args *) prism54_private_args,
-#if WIRELESS_EXT > 16
.get_wireless_stats = prism54_get_wireless_stats,
-#endif /* WIRELESS_EXT > 16 */
-#if WIRELESS_EXT == 16
- .spy_offset = offsetof(islpci_private, spy_data),
-#endif /* WIRELESS_EXT == 16 */
};
/* For wpa_supplicant */
diff --git a/drivers/net/wireless/prism54/islpci_dev.c b/drivers/net/wireless/prism54/islpci_dev.c
index 6f13d4a8e2d3..5ddf29599032 100644
--- a/drivers/net/wireless/prism54/islpci_dev.c
+++ b/drivers/net/wireless/prism54/islpci_dev.c
@@ -19,7 +19,6 @@
*
*/
-#include <linux/version.h>
#include <linux/module.h>
#include <linux/netdevice.h>
@@ -439,8 +438,7 @@ prism54_bring_down(islpci_private *priv)
wmb();
/* wait a while for the device to reset */
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(50*HZ/1000);
+ schedule_timeout_uninterruptible(msecs_to_jiffies(50));
return 0;
}
@@ -491,8 +489,7 @@ islpci_reset_if(islpci_private *priv)
/* The software reset acknowledge needs about 220 msec here.
* Be conservative and wait for up to one second. */
- set_current_state(TASK_UNINTERRUPTIBLE);
- remaining = schedule_timeout(HZ);
+ remaining = schedule_timeout_uninterruptible(HZ);
if(remaining > 0) {
result = 0;
@@ -756,8 +753,7 @@ islpci_free_memory(islpci_private *priv)
pci_unmap_single(priv->pdev, buf->pci_addr,
buf->size, PCI_DMA_FROMDEVICE);
buf->pci_addr = 0;
- if (buf->mem)
- kfree(buf->mem);
+ kfree(buf->mem);
buf->size = 0;
buf->mem = NULL;
}
@@ -839,13 +835,9 @@ islpci_setup(struct pci_dev *pdev)
priv->ndev->type = (priv->iw_mode == IW_MODE_MONITOR) ?
priv->monitor_type : ARPHRD_ETHER;
-#if WIRELESS_EXT > 16
/* Add pointers to enable iwspy support. */
priv->wireless_data.spy_data = &priv->spy_data;
ndev->wireless_data = &priv->wireless_data;
-#else /* WIRELESS_EXT > 16 */
- ndev->get_wireless_stats = &prism54_get_wireless_stats;
-#endif /* WIRELESS_EXT > 16 */
/* save the start and end address of the PCI memory area */
ndev->mem_start = (unsigned long) priv->device_base;
diff --git a/drivers/net/wireless/prism54/islpci_dev.h b/drivers/net/wireless/prism54/islpci_dev.h
index 32a1019f1b36..07053165e4c5 100644
--- a/drivers/net/wireless/prism54/islpci_dev.h
+++ b/drivers/net/wireless/prism54/islpci_dev.h
@@ -23,7 +23,6 @@
#ifndef _ISLPCI_DEV_H
#define _ISLPCI_DEV_H
-#include <linux/version.h>
#include <linux/netdevice.h>
#include <linux/wireless.h>
#include <net/iw_handler.h>
@@ -100,9 +99,7 @@ typedef struct {
struct iw_spy_data spy_data; /* iwspy support */
-#if WIRELESS_EXT > 16
struct iw_public_data wireless_data;
-#endif /* WIRELESS_EXT > 16 */
int monitor_type; /* ARPHRD_IEEE80211 or ARPHRD_IEEE80211_PRISM */
diff --git a/drivers/net/wireless/prism54/islpci_eth.c b/drivers/net/wireless/prism54/islpci_eth.c
index 5952e9960499..33d64d2ee53f 100644
--- a/drivers/net/wireless/prism54/islpci_eth.c
+++ b/drivers/net/wireless/prism54/islpci_eth.c
@@ -17,7 +17,6 @@
*
*/
-#include <linux/version.h>
#include <linux/module.h>
#include <linux/pci.h>
@@ -97,12 +96,6 @@ islpci_eth_transmit(struct sk_buff *skb, struct net_device *ndev)
/* lock the driver code */
spin_lock_irqsave(&priv->slock, flags);
- /* determine the amount of fragments needed to store the frame */
-
- frame_size = skb->len < ETH_ZLEN ? ETH_ZLEN : skb->len;
- if (init_wds)
- frame_size += 6;
-
/* check whether the destination queue has enough fragments for the frame */
curr_frag = le32_to_cpu(cb->driver_curr_frag[ISL38XX_CB_TX_DATA_LQ]);
if (unlikely(curr_frag - priv->free_data_tx >= ISL38XX_CB_TX_QSIZE)) {
@@ -213,6 +206,7 @@ islpci_eth_transmit(struct sk_buff *skb, struct net_device *ndev)
/* store the skb address for future freeing */
priv->data_low_tx[index] = skb;
/* set the proper fragment start address and size information */
+ frame_size = skb->len;
fragment->size = cpu_to_le16(frame_size);
fragment->flags = cpu_to_le16(0); /* set to 1 if more fragments */
fragment->address = cpu_to_le32(pci_map_address);
@@ -232,26 +226,23 @@ islpci_eth_transmit(struct sk_buff *skb, struct net_device *ndev)
priv->data_low_tx_full = 1;
}
+ /* set the transmission time */
+ ndev->trans_start = jiffies;
+ priv->statistics.tx_packets++;
+ priv->statistics.tx_bytes += skb->len;
+
/* trigger the device */
islpci_trigger(priv);
/* unlock the driver code */
spin_unlock_irqrestore(&priv->slock, flags);
- /* set the transmission time */
- ndev->trans_start = jiffies;
- priv->statistics.tx_packets++;
- priv->statistics.tx_bytes += skb->len;
-
return 0;
drop_free:
- /* free the skbuf structure before aborting */
- dev_kfree_skb(skb);
- skb = NULL;
-
priv->statistics.tx_dropped++;
spin_unlock_irqrestore(&priv->slock, flags);
+ dev_kfree_skb(skb);
return err;
}
diff --git a/drivers/net/wireless/prism54/islpci_hotplug.c b/drivers/net/wireless/prism54/islpci_hotplug.c
index dc040caab7d7..b41d666fea3c 100644
--- a/drivers/net/wireless/prism54/islpci_hotplug.c
+++ b/drivers/net/wireless/prism54/islpci_hotplug.c
@@ -18,7 +18,6 @@
*
*/
-#include <linux/version.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/delay.h>
diff --git a/drivers/net/wireless/prism54/islpci_mgt.c b/drivers/net/wireless/prism54/islpci_mgt.c
index b6f2e5a223be..6a60c5970cb5 100644
--- a/drivers/net/wireless/prism54/islpci_mgt.c
+++ b/drivers/net/wireless/prism54/islpci_mgt.c
@@ -137,7 +137,7 @@ islpci_mgmt_rx_fill(struct net_device *ndev)
PCI_DMA_FROMDEVICE);
if (!buf->pci_addr) {
printk(KERN_WARNING
- "Failed to make memory DMA'able\n.");
+ "Failed to make memory DMA'able.\n");
return -ENOMEM;
}
}
@@ -455,7 +455,7 @@ islpci_mgt_transaction(struct net_device *ndev,
struct islpci_mgmtframe **recvframe)
{
islpci_private *priv = netdev_priv(ndev);
- const long wait_cycle_jiffies = (ISL38XX_WAIT_CYCLE * 10 * HZ) / 1000;
+ const long wait_cycle_jiffies = msecs_to_jiffies(ISL38XX_WAIT_CYCLE * 10);
long timeout_left = ISL38XX_MAX_WAIT_CYCLES * wait_cycle_jiffies;
int err;
DEFINE_WAIT(wait);
@@ -475,8 +475,7 @@ islpci_mgt_transaction(struct net_device *ndev,
int timeleft;
struct islpci_mgmtframe *frame;
- set_current_state(TASK_UNINTERRUPTIBLE);
- timeleft = schedule_timeout(wait_cycle_jiffies);
+ timeleft = schedule_timeout_uninterruptible(wait_cycle_jiffies);
frame = xchg(&priv->mgmt_received, NULL);
if (frame) {
if (frame->header->oid == oid) {
diff --git a/drivers/net/wireless/prism54/oid_mgt.c b/drivers/net/wireless/prism54/oid_mgt.c
index 12123e24b113..eea2f04c8c6d 100644
--- a/drivers/net/wireless/prism54/oid_mgt.c
+++ b/drivers/net/wireless/prism54/oid_mgt.c
@@ -268,11 +268,10 @@ mgt_clean(islpci_private *priv)
if (!priv->mib)
return;
- for (i = 0; i < OID_NUM_LAST; i++)
- if (priv->mib[i]) {
- kfree(priv->mib[i]);
- priv->mib[i] = NULL;
- }
+ for (i = 0; i < OID_NUM_LAST; i++) {
+ kfree(priv->mib[i]);
+ priv->mib[i] = NULL;
+ }
kfree(priv->mib);
priv->mib = NULL;
}
diff --git a/drivers/net/wireless/ray_cs.c b/drivers/net/wireless/ray_cs.c
index e9c5ea0f5535..70fd6fd8feb9 100644
--- a/drivers/net/wireless/ray_cs.c
+++ b/drivers/net/wireless/ray_cs.c
@@ -1649,28 +1649,28 @@ static iw_stats * ray_get_wireless_stats(struct net_device * dev)
*/
static const iw_handler ray_handler[] = {
- [SIOCSIWCOMMIT-SIOCIWFIRST] (iw_handler) ray_commit,
- [SIOCGIWNAME -SIOCIWFIRST] (iw_handler) ray_get_name,
- [SIOCSIWFREQ -SIOCIWFIRST] (iw_handler) ray_set_freq,
- [SIOCGIWFREQ -SIOCIWFIRST] (iw_handler) ray_get_freq,
- [SIOCSIWMODE -SIOCIWFIRST] (iw_handler) ray_set_mode,
- [SIOCGIWMODE -SIOCIWFIRST] (iw_handler) ray_get_mode,
- [SIOCGIWRANGE -SIOCIWFIRST] (iw_handler) ray_get_range,
+ [SIOCSIWCOMMIT-SIOCIWFIRST] = (iw_handler) ray_commit,
+ [SIOCGIWNAME -SIOCIWFIRST] = (iw_handler) ray_get_name,
+ [SIOCSIWFREQ -SIOCIWFIRST] = (iw_handler) ray_set_freq,
+ [SIOCGIWFREQ -SIOCIWFIRST] = (iw_handler) ray_get_freq,
+ [SIOCSIWMODE -SIOCIWFIRST] = (iw_handler) ray_set_mode,
+ [SIOCGIWMODE -SIOCIWFIRST] = (iw_handler) ray_get_mode,
+ [SIOCGIWRANGE -SIOCIWFIRST] = (iw_handler) ray_get_range,
#ifdef WIRELESS_SPY
- [SIOCSIWSPY -SIOCIWFIRST] (iw_handler) iw_handler_set_spy,
- [SIOCGIWSPY -SIOCIWFIRST] (iw_handler) iw_handler_get_spy,
- [SIOCSIWTHRSPY-SIOCIWFIRST] (iw_handler) iw_handler_set_thrspy,
- [SIOCGIWTHRSPY-SIOCIWFIRST] (iw_handler) iw_handler_get_thrspy,
+ [SIOCSIWSPY -SIOCIWFIRST] = (iw_handler) iw_handler_set_spy,
+ [SIOCGIWSPY -SIOCIWFIRST] = (iw_handler) iw_handler_get_spy,
+ [SIOCSIWTHRSPY-SIOCIWFIRST] = (iw_handler) iw_handler_set_thrspy,
+ [SIOCGIWTHRSPY-SIOCIWFIRST] = (iw_handler) iw_handler_get_thrspy,
#endif /* WIRELESS_SPY */
- [SIOCGIWAP -SIOCIWFIRST] (iw_handler) ray_get_wap,
- [SIOCSIWESSID -SIOCIWFIRST] (iw_handler) ray_set_essid,
- [SIOCGIWESSID -SIOCIWFIRST] (iw_handler) ray_get_essid,
- [SIOCSIWRATE -SIOCIWFIRST] (iw_handler) ray_set_rate,
- [SIOCGIWRATE -SIOCIWFIRST] (iw_handler) ray_get_rate,
- [SIOCSIWRTS -SIOCIWFIRST] (iw_handler) ray_set_rts,
- [SIOCGIWRTS -SIOCIWFIRST] (iw_handler) ray_get_rts,
- [SIOCSIWFRAG -SIOCIWFIRST] (iw_handler) ray_set_frag,
- [SIOCGIWFRAG -SIOCIWFIRST] (iw_handler) ray_get_frag,
+ [SIOCGIWAP -SIOCIWFIRST] = (iw_handler) ray_get_wap,
+ [SIOCSIWESSID -SIOCIWFIRST] = (iw_handler) ray_set_essid,
+ [SIOCGIWESSID -SIOCIWFIRST] = (iw_handler) ray_get_essid,
+ [SIOCSIWRATE -SIOCIWFIRST] = (iw_handler) ray_set_rate,
+ [SIOCGIWRATE -SIOCIWFIRST] = (iw_handler) ray_get_rate,
+ [SIOCSIWRTS -SIOCIWFIRST] = (iw_handler) ray_set_rts,
+ [SIOCGIWRTS -SIOCIWFIRST] = (iw_handler) ray_get_rts,
+ [SIOCSIWFRAG -SIOCIWFIRST] = (iw_handler) ray_set_frag,
+ [SIOCGIWFRAG -SIOCIWFIRST] = (iw_handler) ray_get_frag,
};
#define SIOCSIPFRAMING SIOCIWFIRSTPRIV /* Set framing mode */
@@ -1678,9 +1678,9 @@ static const iw_handler ray_handler[] = {
#define SIOCGIPCOUNTRY SIOCIWFIRSTPRIV + 3 /* Get country code */
static const iw_handler ray_private_handler[] = {
- [0] (iw_handler) ray_set_framing,
- [1] (iw_handler) ray_get_framing,
- [3] (iw_handler) ray_get_country,
+ [0] = (iw_handler) ray_set_framing,
+ [1] = (iw_handler) ray_get_framing,
+ [3] = (iw_handler) ray_get_country,
};
static const struct iw_priv_args ray_private_args[] = {
diff --git a/drivers/net/wireless/spectrum_cs.c b/drivers/net/wireless/spectrum_cs.c
index 39c6cdf7f3f7..b1bbc8e8e91f 100644
--- a/drivers/net/wireless/spectrum_cs.c
+++ b/drivers/net/wireless/spectrum_cs.c
@@ -22,58 +22,23 @@
#define PFX DRIVER_NAME ": "
#include <linux/config.h>
-#ifdef __IN_PCMCIA_PACKAGE__
-#include <pcmcia/k_compat.h>
-#endif /* __IN_PCMCIA_PACKAGE__ */
-
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
-#include <linux/sched.h>
-#include <linux/ptrace.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <linux/ioport.h>
-#include <linux/netdevice.h>
-#include <linux/if_arp.h>
-#include <linux/etherdevice.h>
-#include <linux/wireless.h>
-
+#include <linux/delay.h>
+#include <linux/firmware.h>
#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h>
#include <pcmcia/cisreg.h>
#include <pcmcia/ds.h>
-#include <asm/uaccess.h>
-#include <asm/io.h>
-#include <asm/system.h>
-
#include "orinoco.h"
-/*
- * If SPECTRUM_FW_INCLUDED is defined, the firmware is hardcoded into
- * the driver. Use get_symbol_fw script to generate spectrum_fw.h and
- * copy it to the same directory as spectrum_cs.c.
- *
- * If SPECTRUM_FW_INCLUDED is not defined, the firmware is loaded at the
- * runtime using hotplug. Use the same get_symbol_fw script to generate
- * files symbol_sp24t_prim_fw symbol_sp24t_sec_fw, copy them to the
- * hotplug firmware directory (typically /usr/lib/hotplug/firmware) and
- * make sure that you have hotplug installed and enabled in the kernel.
- */
-/* #define SPECTRUM_FW_INCLUDED 1 */
-
-#ifdef SPECTRUM_FW_INCLUDED
-/* Header with the firmware */
-#include "spectrum_fw.h"
-#else /* !SPECTRUM_FW_INCLUDED */
-#include <linux/firmware.h>
static unsigned char *primsym;
static unsigned char *secsym;
static const char primary_fw_name[] = "symbol_sp24t_prim_fw";
static const char secondary_fw_name[] = "symbol_sp24t_sec_fw";
-#endif /* !SPECTRUM_FW_INCLUDED */
/********************************************************************/
/* Module stuff */
@@ -124,17 +89,8 @@ static dev_link_t *dev_list; /* = NULL */
/* Function prototypes */
/********************************************************************/
-/* device methods */
-static int spectrum_cs_hard_reset(struct orinoco_private *priv);
-
-/* PCMCIA gumpf */
-static void spectrum_cs_config(dev_link_t * link);
-static void spectrum_cs_release(dev_link_t * link);
-static int spectrum_cs_event(event_t event, int priority,
- event_callback_args_t * args);
-
-static dev_link_t *spectrum_cs_attach(void);
-static void spectrum_cs_detach(dev_link_t *);
+static void spectrum_cs_release(dev_link_t *link);
+static void spectrum_cs_detach(dev_link_t *link);
/********************************************************************/
/* Firmware downloader */
@@ -182,8 +138,8 @@ static void spectrum_cs_detach(dev_link_t *);
* Each block has the following structure.
*/
struct dblock {
- u32 _addr; /* adapter address where to write the block */
- u16 _len; /* length of the data only, in bytes */
+ __le32 _addr; /* adapter address where to write the block */
+ __le16 _len; /* length of the data only, in bytes */
char data[0]; /* data to be written */
} __attribute__ ((packed));
@@ -193,9 +149,9 @@ struct dblock {
* items with matching ID should be written.
*/
struct pdr {
- u32 _id; /* record ID */
- u32 _addr; /* adapter address where to write the data */
- u32 _len; /* expected length of the data, in bytes */
+ __le32 _id; /* record ID */
+ __le32 _addr; /* adapter address where to write the data */
+ __le32 _len; /* expected length of the data, in bytes */
char next[0]; /* next PDR starts here */
} __attribute__ ((packed));
@@ -206,8 +162,8 @@ struct pdr {
* be plugged into the secondary firmware.
*/
struct pdi {
- u16 _len; /* length of ID and data, in words */
- u16 _id; /* record ID */
+ __le16 _len; /* length of ID and data, in words */
+ __le16 _id; /* record ID */
char data[0]; /* plug data */
} __attribute__ ((packed));;
@@ -414,7 +370,7 @@ spectrum_plug_pdi(hermes_t *hw, struct pdr *first_pdr, struct pdi *pdi)
/* Read PDA from the adapter */
static int
-spectrum_read_pda(hermes_t *hw, u16 *pda, int pda_len)
+spectrum_read_pda(hermes_t *hw, __le16 *pda, int pda_len)
{
int ret;
int pda_size;
@@ -445,7 +401,7 @@ spectrum_read_pda(hermes_t *hw, u16 *pda, int pda_len)
/* Parse PDA and write the records into the adapter */
static int
spectrum_apply_pda(hermes_t *hw, const struct dblock *first_block,
- u16 *pda)
+ __le16 *pda)
{
int ret;
struct pdi *pdi;
@@ -511,7 +467,7 @@ spectrum_dl_image(hermes_t *hw, dev_link_t *link,
const struct dblock *first_block;
/* Plug Data Area (PDA) */
- u16 pda[PDA_WORDS];
+ __le16 pda[PDA_WORDS];
/* Binary block begins after the 0x1A marker */
ptr = image;
@@ -571,8 +527,6 @@ spectrum_dl_firmware(hermes_t *hw, dev_link_t *link)
{
int ret;
client_handle_t handle = link->handle;
-
-#ifndef SPECTRUM_FW_INCLUDED
const struct firmware *fw_entry;
if (request_firmware(&fw_entry, primary_fw_name,
@@ -592,7 +546,6 @@ spectrum_dl_firmware(hermes_t *hw, dev_link_t *link)
secondary_fw_name);
return -ENOENT;
}
-#endif
/* Load primary firmware */
ret = spectrum_dl_image(hw, link, primsym);
@@ -1085,7 +1038,7 @@ static char version[] __initdata = DRIVER_NAME " " DRIVER_VERSION
static struct pcmcia_device_id spectrum_cs_ids[] = {
PCMCIA_DEVICE_MANF_CARD(0x026c, 0x0001), /* Symbol Spectrum24 LA4100 */
PCMCIA_DEVICE_MANF_CARD(0x0104, 0x0001), /* Socket Communications CF */
- PCMCIA_DEVICE_MANF_CARD(0x0089, 0x0001), /* Intel PRO/Wireless 2011B */
+ PCMCIA_DEVICE_PROD_ID12("Intel", "PRO/Wireless LAN PC Card", 0x816cc815, 0x6fbf459a), /* 2011B, not 2011 */
PCMCIA_DEVICE_NULL,
};
MODULE_DEVICE_TABLE(pcmcia, spectrum_cs_ids);
@@ -1096,8 +1049,8 @@ static struct pcmcia_driver orinoco_driver = {
.name = DRIVER_NAME,
},
.attach = spectrum_cs_attach,
- .event = spectrum_cs_event,
.detach = spectrum_cs_detach,
+ .event = spectrum_cs_event,
.id_table = spectrum_cs_ids,
};
diff --git a/drivers/net/wireless/strip.c b/drivers/net/wireless/strip.c
index 7bc7fc823128..d25264ba0c0e 100644
--- a/drivers/net/wireless/strip.c
+++ b/drivers/net/wireless/strip.c
@@ -860,12 +860,9 @@ static int allocate_buffers(struct strip *strip_info, int mtu)
strip_info->mtu = dev->mtu = mtu;
return (1);
}
- if (r)
- kfree(r);
- if (s)
- kfree(s);
- if (t)
- kfree(t);
+ kfree(r);
+ kfree(s);
+ kfree(t);
return (0);
}
@@ -922,13 +919,9 @@ static int strip_change_mtu(struct net_device *dev, int new_mtu)
printk(KERN_NOTICE "%s: strip MTU changed fom %d to %d.\n",
strip_info->dev->name, old_mtu, strip_info->mtu);
- if (orbuff)
- kfree(orbuff);
- if (osbuff)
- kfree(osbuff);
- if (otbuff)
- kfree(otbuff);
-
+ kfree(orbuff);
+ kfree(osbuff);
+ kfree(otbuff);
return 0;
}
@@ -2498,18 +2491,13 @@ static int strip_close_low(struct net_device *dev)
/*
* Free all STRIP frame buffers.
*/
- if (strip_info->rx_buff) {
- kfree(strip_info->rx_buff);
- strip_info->rx_buff = NULL;
- }
- if (strip_info->sx_buff) {
- kfree(strip_info->sx_buff);
- strip_info->sx_buff = NULL;
- }
- if (strip_info->tx_buff) {
- kfree(strip_info->tx_buff);
- strip_info->tx_buff = NULL;
- }
+ kfree(strip_info->rx_buff);
+ strip_info->rx_buff = NULL;
+ kfree(strip_info->sx_buff);
+ strip_info->sx_buff = NULL;
+ kfree(strip_info->tx_buff);
+ strip_info->tx_buff = NULL;
+
del_timer(&strip_info->idle_timer);
return 0;
}
diff --git a/drivers/net/wireless/wavelan.c b/drivers/net/wireless/wavelan.c
index 7a5e20a17890..b0d8b5b03152 100644
--- a/drivers/net/wireless/wavelan.c
+++ b/drivers/net/wireless/wavelan.c
@@ -430,7 +430,6 @@ static void fee_read(unsigned long ioaddr, /* I/O port of the card */
}
}
-#ifdef WIRELESS_EXT /* if the wireless extension exists in the kernel */
/*------------------------------------------------------------------*/
/*
@@ -514,7 +513,6 @@ static void fee_write(unsigned long ioaddr, /* I/O port of the card */
fee_wait(ioaddr, 10, 100);
#endif /* EEPROM_IS_PROTECTED */
}
-#endif /* WIRELESS_EXT */
/************************ I82586 SUBROUTINES *************************/
/*
@@ -973,11 +971,9 @@ static void wv_mmc_show(struct net_device * dev)
mmc_read(ioaddr, 0, (u8 *) & m, sizeof(m));
mmc_out(ioaddr, mmwoff(0, mmw_freeze), 0);
-#ifdef WIRELESS_EXT /* if wireless extension exists in the kernel */
/* Don't forget to update statistics */
lp->wstats.discard.nwid +=
(m.mmr_wrong_nwid_h << 8) | m.mmr_wrong_nwid_l;
-#endif /* WIRELESS_EXT */
printk(KERN_DEBUG "##### WaveLAN modem status registers: #####\n");
#ifdef DEBUG_SHOW_UNUSED
@@ -1499,7 +1495,6 @@ static int wavelan_set_mac_address(struct net_device * dev, void *addr)
}
#endif /* SET_MAC_ADDRESS */
-#ifdef WIRELESS_EXT /* if wireless extensions exist in the kernel */
/*------------------------------------------------------------------*/
/*
@@ -2473,7 +2468,6 @@ static iw_stats *wavelan_get_wireless_stats(struct net_device * dev)
#endif
return &lp->wstats;
}
-#endif /* WIRELESS_EXT */
/************************* PACKET RECEPTION *************************/
/*
@@ -4194,11 +4188,9 @@ static int __init wavelan_config(struct net_device *dev, unsigned short ioaddr)
dev->set_mac_address = &wavelan_set_mac_address;
#endif /* SET_MAC_ADDRESS */
-#ifdef WIRELESS_EXT /* if wireless extension exists in the kernel */
dev->wireless_handlers = &wavelan_handler_def;
lp->wireless_data.spy_data = &lp->spy_data;
dev->wireless_data = &lp->wireless_data;
-#endif
dev->mtu = WAVELAN_MTU;
diff --git a/drivers/net/wireless/wavelan.p.h b/drivers/net/wireless/wavelan.p.h
index 509ff22a6caa..166e28b9a4f7 100644
--- a/drivers/net/wireless/wavelan.p.h
+++ b/drivers/net/wireless/wavelan.p.h
@@ -409,11 +409,9 @@
#define MULTICAST_AVOID /* Avoid extra multicast (I'm sceptical). */
#undef SET_MAC_ADDRESS /* Experimental */
-#ifdef WIRELESS_EXT /* If wireless extensions exist in the kernel */
/* Warning: this stuff will slow down the driver. */
#define WIRELESS_SPY /* Enable spying addresses. */
#undef HISTOGRAM /* Enable histogram of signal level. */
-#endif
/****************************** DEBUG ******************************/
@@ -506,12 +504,10 @@ struct net_local
u_short tx_first_free;
u_short tx_first_in_use;
-#ifdef WIRELESS_EXT
iw_stats wstats; /* Wireless-specific statistics */
struct iw_spy_data spy_data;
struct iw_public_data wireless_data;
-#endif
#ifdef HISTOGRAM
int his_number; /* number of intervals */
diff --git a/drivers/net/wireless/wavelan_cs.c b/drivers/net/wireless/wavelan_cs.c
index 183c4732ef65..c822cad3333f 100644
--- a/drivers/net/wireless/wavelan_cs.c
+++ b/drivers/net/wireless/wavelan_cs.c
@@ -415,7 +415,6 @@ fee_read(u_long base, /* i/o port of the card */
}
}
-#ifdef WIRELESS_EXT /* If wireless extension exist in the kernel */
/*------------------------------------------------------------------*/
/*
@@ -500,7 +499,6 @@ fee_write(u_long base, /* i/o port of the card */
fee_wait(base, 10, 100);
#endif /* EEPROM_IS_PROTECTED */
}
-#endif /* WIRELESS_EXT */
/******************* WaveLAN Roaming routines... ********************/
@@ -1161,10 +1159,8 @@ wv_mmc_show(struct net_device * dev)
mmc_read(base, 0, (u_char *)&m, sizeof(m));
mmc_out(base, mmwoff(0, mmw_freeze), 0);
-#ifdef WIRELESS_EXT /* If wireless extension exist in the kernel */
/* Don't forget to update statistics */
lp->wstats.discard.nwid += (m.mmr_wrong_nwid_h << 8) | m.mmr_wrong_nwid_l;
-#endif /* WIRELESS_EXT */
spin_unlock_irqrestore(&lp->spinlock, flags);
@@ -1550,7 +1546,6 @@ wavelan_set_mac_address(struct net_device * dev,
}
#endif /* SET_MAC_ADDRESS */
-#ifdef WIRELESS_EXT /* If wireless extension exist in the kernel */
/*------------------------------------------------------------------*/
/*
@@ -2793,7 +2788,6 @@ wavelan_get_wireless_stats(struct net_device * dev)
#endif
return &lp->wstats;
}
-#endif /* WIRELESS_EXT */
/************************* PACKET RECEPTION *************************/
/*
@@ -4614,9 +4608,8 @@ wavelan_attach(void)
#endif
/* Initialize the dev_link_t structure */
- link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL);
+ link = kzalloc(sizeof(struct dev_link_t), GFP_KERNEL);
if (!link) return NULL;
- memset(link, 0, sizeof(struct dev_link_t));
/* The io structure describes IO port mapping */
link->io.NumPorts1 = 8;
@@ -4679,11 +4672,9 @@ wavelan_attach(void)
dev->watchdog_timeo = WATCHDOG_JIFFIES;
SET_ETHTOOL_OPS(dev, &ops);
-#ifdef WIRELESS_EXT /* If wireless extension exist in the kernel */
dev->wireless_handlers = &wavelan_handler_def;
lp->wireless_data.spy_data = &lp->spy_data;
dev->wireless_data = &lp->wireless_data;
-#endif
/* Other specific data */
dev->mtu = WAVELAN_MTU;
diff --git a/drivers/net/wireless/wavelan_cs.p.h b/drivers/net/wireless/wavelan_cs.p.h
index 01d882be8790..724a715089c9 100644
--- a/drivers/net/wireless/wavelan_cs.p.h
+++ b/drivers/net/wireless/wavelan_cs.p.h
@@ -472,11 +472,9 @@
#define MULTICAST_AVOID /* Avoid extra multicast (I'm sceptical) */
#undef SET_MAC_ADDRESS /* Experimental */
-#ifdef WIRELESS_EXT /* If wireless extension exist in the kernel */
/* Warning : these stuff will slow down the driver... */
#define WIRELESS_SPY /* Enable spying addresses */
#undef HISTOGRAM /* Enable histogram of sig level... */
-#endif
/****************************** DEBUG ******************************/
@@ -624,12 +622,10 @@ struct net_local
int rfp; /* Last DMA machine receive pointer */
int overrunning; /* Receiver overrun flag */
-#ifdef WIRELESS_EXT
iw_stats wstats; /* Wireless specific stats */
struct iw_spy_data spy_data;
struct iw_public_data wireless_data;
-#endif
#ifdef HISTOGRAM
int his_number; /* Number of intervals */
diff --git a/drivers/net/wireless/wl3501.h b/drivers/net/wireless/wl3501.h
index 7fcbe589c3f2..4303c50c2ab6 100644
--- a/drivers/net/wireless/wl3501.h
+++ b/drivers/net/wireless/wl3501.h
@@ -548,7 +548,7 @@ struct wl3501_80211_tx_plcp_hdr {
struct wl3501_80211_tx_hdr {
struct wl3501_80211_tx_plcp_hdr pclp_hdr;
- struct ieee80211_hdr mac_hdr;
+ struct ieee80211_hdr_4addr mac_hdr;
} __attribute__ ((packed));
/*
diff --git a/drivers/net/wireless/wl3501_cs.c b/drivers/net/wireless/wl3501_cs.c
index 3f8c27f0871b..978fdc606781 100644
--- a/drivers/net/wireless/wl3501_cs.c
+++ b/drivers/net/wireless/wl3501_cs.c
@@ -1965,10 +1965,9 @@ static dev_link_t *wl3501_attach(void)
int ret;
/* Initialize the dev_link_t structure */
- link = kmalloc(sizeof(*link), GFP_KERNEL);
+ link = kzalloc(sizeof(*link), GFP_KERNEL);
if (!link)
goto out;
- memset(link, 0, sizeof(struct dev_link_t));
/* The io structure describes IO port mapping */
link->io.NumPorts1 = 16;
diff --git a/drivers/parisc/asp.c b/drivers/parisc/asp.c
index 388609967133..558420bc9f88 100644
--- a/drivers/parisc/asp.c
+++ b/drivers/parisc/asp.c
@@ -77,12 +77,12 @@ asp_init_chip(struct parisc_device *dev)
struct gsc_irq gsc_irq;
int ret;
- asp.version = gsc_readb(dev->hpa + ASP_VER_OFFSET) & 0xf;
+ asp.version = gsc_readb(dev->hpa.start + ASP_VER_OFFSET) & 0xf;
asp.name = (asp.version == 1) ? "Asp" : "Cutoff";
asp.hpa = ASP_INTERRUPT_ADDR;
printk(KERN_INFO "%s version %d at 0x%lx found.\n",
- asp.name, asp.version, dev->hpa);
+ asp.name, asp.version, dev->hpa.start);
/* the IRQ ASP should use */
ret = -EBUSY;
@@ -126,7 +126,7 @@ static struct parisc_device_id asp_tbl[] = {
};
struct parisc_driver asp_driver = {
- .name = "Asp",
+ .name = "asp",
.id_table = asp_tbl,
.probe = asp_init_chip,
};
diff --git a/drivers/parisc/ccio-dma.c b/drivers/parisc/ccio-dma.c
index 0e98a9d9834c..9e0229f7e25f 100644
--- a/drivers/parisc/ccio-dma.c
+++ b/drivers/parisc/ccio-dma.c
@@ -100,9 +100,9 @@
#define DBG_RUN_SG(x...)
#endif
-#define CCIO_INLINE /* inline */
-#define WRITE_U32(value, addr) gsc_writel(value, (u32 *)(addr))
-#define READ_U32(addr) gsc_readl((u32 *)(addr))
+#define CCIO_INLINE inline
+#define WRITE_U32(value, addr) __raw_writel(value, addr)
+#define READ_U32(addr) __raw_readl(addr)
#define U2_IOA_RUNWAY 0x580
#define U2_BC_GSC 0x501
@@ -115,28 +115,28 @@
struct ioa_registers {
/* Runway Supervisory Set */
- volatile int32_t unused1[12];
- volatile uint32_t io_command; /* Offset 12 */
- volatile uint32_t io_status; /* Offset 13 */
- volatile uint32_t io_control; /* Offset 14 */
- volatile int32_t unused2[1];
+ int32_t unused1[12];
+ uint32_t io_command; /* Offset 12 */
+ uint32_t io_status; /* Offset 13 */
+ uint32_t io_control; /* Offset 14 */
+ int32_t unused2[1];
/* Runway Auxiliary Register Set */
- volatile uint32_t io_err_resp; /* Offset 0 */
- volatile uint32_t io_err_info; /* Offset 1 */
- volatile uint32_t io_err_req; /* Offset 2 */
- volatile uint32_t io_err_resp_hi; /* Offset 3 */
- volatile uint32_t io_tlb_entry_m; /* Offset 4 */
- volatile uint32_t io_tlb_entry_l; /* Offset 5 */
- volatile uint32_t unused3[1];
- volatile uint32_t io_pdir_base; /* Offset 7 */
- volatile uint32_t io_io_low_hv; /* Offset 8 */
- volatile uint32_t io_io_high_hv; /* Offset 9 */
- volatile uint32_t unused4[1];
- volatile uint32_t io_chain_id_mask; /* Offset 11 */
- volatile uint32_t unused5[2];
- volatile uint32_t io_io_low; /* Offset 14 */
- volatile uint32_t io_io_high; /* Offset 15 */
+ uint32_t io_err_resp; /* Offset 0 */
+ uint32_t io_err_info; /* Offset 1 */
+ uint32_t io_err_req; /* Offset 2 */
+ uint32_t io_err_resp_hi; /* Offset 3 */
+ uint32_t io_tlb_entry_m; /* Offset 4 */
+ uint32_t io_tlb_entry_l; /* Offset 5 */
+ uint32_t unused3[1];
+ uint32_t io_pdir_base; /* Offset 7 */
+ uint32_t io_io_low_hv; /* Offset 8 */
+ uint32_t io_io_high_hv; /* Offset 9 */
+ uint32_t unused4[1];
+ uint32_t io_chain_id_mask; /* Offset 11 */
+ uint32_t unused5[2];
+ uint32_t io_io_low; /* Offset 14 */
+ uint32_t io_io_high; /* Offset 15 */
};
/*
@@ -226,7 +226,7 @@ struct ioa_registers {
*/
struct ioc {
- struct ioa_registers *ioc_hpa; /* I/O MMU base address */
+ struct ioa_registers __iomem *ioc_regs; /* I/O MMU base address */
u8 *res_map; /* resource map, bit == pdir entry */
u64 *pdir_base; /* physical base address */
u32 pdir_size; /* bytes, function of IOV Space size */
@@ -595,7 +595,7 @@ ccio_io_pdir_entry(u64 *pdir_ptr, space_t sid, unsigned long vba,
** Grab virtual index [0:11]
** Deposit virt_idx bits into I/O PDIR word
*/
- asm volatile ("lci 0(%%sr1, %1), %0" : "=r" (ci) : "r" (vba));
+ asm volatile ("lci %%r0(%%sr1, %1), %0" : "=r" (ci) : "r" (vba));
asm volatile ("extru %1,19,12,%0" : "+r" (ci) : "r" (ci));
asm volatile ("depw %1,15,12,%0" : "+r" (pa) : "r" (ci));
@@ -613,7 +613,7 @@ ccio_io_pdir_entry(u64 *pdir_ptr, space_t sid, unsigned long vba,
** the real mode coherence index generation of U2, the PDIR entry
** must be flushed to memory to retain coherence."
*/
- asm volatile("fdc 0(%0)" : : "r" (pdir_ptr));
+ asm volatile("fdc %%r0(%0)" : : "r" (pdir_ptr));
asm volatile("sync");
}
@@ -636,7 +636,7 @@ ccio_clear_io_tlb(struct ioc *ioc, dma_addr_t iovp, size_t byte_cnt)
byte_cnt += chain_size;
while(byte_cnt > chain_size) {
- WRITE_U32(CMD_TLB_PURGE | iovp, &ioc->ioc_hpa->io_command);
+ WRITE_U32(CMD_TLB_PURGE | iovp, &ioc->ioc_regs->io_command);
iovp += chain_size;
byte_cnt -= chain_size;
}
@@ -684,7 +684,7 @@ ccio_mark_invalid(struct ioc *ioc, dma_addr_t iova, size_t byte_cnt)
** Hopefully someone figures out how to patch (NOP) the
** FDC/SYNC out at boot time.
*/
- asm volatile("fdc 0(%0)" : : "r" (pdir_ptr[7]));
+ asm volatile("fdc %%r0(%0)" : : "r" (pdir_ptr[7]));
iovp += IOVP_SIZE;
byte_cnt -= IOVP_SIZE;
@@ -836,7 +836,7 @@ ccio_unmap_single(struct device *dev, dma_addr_t iova, size_t size,
* This function implements the pci_alloc_consistent function.
*/
static void *
-ccio_alloc_consistent(struct device *dev, size_t size, dma_addr_t *dma_handle, int flag)
+ccio_alloc_consistent(struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t flag)
{
void *ret;
#if 0
@@ -1251,7 +1251,7 @@ static struct parisc_device_id ccio_tbl[] = {
static int ccio_probe(struct parisc_device *dev);
static struct parisc_driver ccio_driver = {
- .name = "U2:Uturn",
+ .name = "ccio",
.id_table = ccio_tbl,
.probe = ccio_probe,
};
@@ -1314,14 +1314,13 @@ ccio_ioc_init(struct ioc *ioc)
ioc->pdir_size = (iova_space_size / IOVP_SIZE) * sizeof(u64);
- BUG_ON(ioc->pdir_size >= 4 * 1024 * 1024); /* max pdir size < 4MB */
+ BUG_ON(ioc->pdir_size > 8 * 1024 * 1024); /* max pdir size <= 8MB */
/* Verify it's a power of two */
BUG_ON((1 << get_order(ioc->pdir_size)) != (ioc->pdir_size >> PAGE_SHIFT));
- DBG_INIT("%s() hpa 0x%lx mem %luMB IOV %dMB (%d bits)\n",
- __FUNCTION__,
- ioc->ioc_hpa,
+ DBG_INIT("%s() hpa 0x%p mem %luMB IOV %dMB (%d bits)\n",
+ __FUNCTION__, ioc->ioc_regs,
(unsigned long) num_physpages >> (20 - PAGE_SHIFT),
iova_space_size>>20,
iov_order + PAGE_SHIFT);
@@ -1329,13 +1328,12 @@ ccio_ioc_init(struct ioc *ioc)
ioc->pdir_base = (u64 *)__get_free_pages(GFP_KERNEL,
get_order(ioc->pdir_size));
if(NULL == ioc->pdir_base) {
- panic("%s:%s() could not allocate I/O Page Table\n", __FILE__,
- __FUNCTION__);
+ panic("%s() could not allocate I/O Page Table\n", __FUNCTION__);
}
memset(ioc->pdir_base, 0, ioc->pdir_size);
BUG_ON((((unsigned long)ioc->pdir_base) & PAGE_MASK) != (unsigned long)ioc->pdir_base);
- DBG_INIT(" base %p", ioc->pdir_base);
+ DBG_INIT(" base %p\n", ioc->pdir_base);
/* resource map size dictated by pdir_size */
ioc->res_size = (ioc->pdir_size / sizeof(u64)) >> 3;
@@ -1344,8 +1342,7 @@ ccio_ioc_init(struct ioc *ioc)
ioc->res_map = (u8 *)__get_free_pages(GFP_KERNEL,
get_order(ioc->res_size));
if(NULL == ioc->res_map) {
- panic("%s:%s() could not allocate resource map\n", __FILE__,
- __FUNCTION__);
+ panic("%s() could not allocate resource map\n", __FUNCTION__);
}
memset(ioc->res_map, 0, ioc->res_size);
@@ -1366,44 +1363,58 @@ ccio_ioc_init(struct ioc *ioc)
** Initialize IOA hardware
*/
WRITE_U32(CCIO_CHAINID_MASK << ioc->chainid_shift,
- &ioc->ioc_hpa->io_chain_id_mask);
+ &ioc->ioc_regs->io_chain_id_mask);
WRITE_U32(virt_to_phys(ioc->pdir_base),
- &ioc->ioc_hpa->io_pdir_base);
+ &ioc->ioc_regs->io_pdir_base);
/*
** Go to "Virtual Mode"
*/
- WRITE_U32(IOA_NORMAL_MODE, &ioc->ioc_hpa->io_control);
+ WRITE_U32(IOA_NORMAL_MODE, &ioc->ioc_regs->io_control);
/*
** Initialize all I/O TLB entries to 0 (Valid bit off).
*/
- WRITE_U32(0, &ioc->ioc_hpa->io_tlb_entry_m);
- WRITE_U32(0, &ioc->ioc_hpa->io_tlb_entry_l);
+ WRITE_U32(0, &ioc->ioc_regs->io_tlb_entry_m);
+ WRITE_U32(0, &ioc->ioc_regs->io_tlb_entry_l);
for(i = 1 << CCIO_CHAINID_SHIFT; i ; i--) {
WRITE_U32((CMD_TLB_DIRECT_WRITE | (i << ioc->chainid_shift)),
- &ioc->ioc_hpa->io_command);
+ &ioc->ioc_regs->io_command);
}
}
static void
-ccio_init_resource(struct resource *res, char *name, unsigned long ioaddr)
+ccio_init_resource(struct resource *res, char *name, void __iomem *ioaddr)
{
int result;
res->parent = NULL;
res->flags = IORESOURCE_MEM;
- res->start = (unsigned long)(signed) __raw_readl(ioaddr) << 16;
- res->end = (unsigned long)(signed) (__raw_readl(ioaddr + 4) << 16) - 1;
+ /*
+ * bracing ((signed) ...) are required for 64bit kernel because
+ * we only want to sign extend the lower 16 bits of the register.
+ * The upper 16-bits of range registers are hardcoded to 0xffff.
+ */
+ res->start = (unsigned long)((signed) READ_U32(ioaddr) << 16);
+ res->end = (unsigned long)((signed) (READ_U32(ioaddr + 4) << 16) - 1);
res->name = name;
+ /*
+ * Check if this MMIO range is disable
+ */
if (res->end + 1 == res->start)
return;
- result = request_resource(&iomem_resource, res);
+
+ /* On some platforms (e.g. K-Class), we have already registered
+ * resources for devices reported by firmware. Some are children
+ * of ccio.
+ * "insert" ccio ranges in the mmio hierarchy (/proc/iomem).
+ */
+ result = insert_resource(&iomem_resource, res);
if (result < 0) {
- printk(KERN_ERR "%s: failed to claim CCIO bus address space (%08lx,%08lx)\n",
- __FILE__, res->start, res->end);
+ printk(KERN_ERR "%s() failed to claim CCIO bus address space (%08lx,%08lx)\n",
+ __FUNCTION__, res->start, res->end);
}
}
@@ -1414,9 +1425,8 @@ static void __init ccio_init_resources(struct ioc *ioc)
sprintf(name, "GSC Bus [%d/]", ioc->hw_path);
- ccio_init_resource(res, name, (unsigned long)&ioc->ioc_hpa->io_io_low);
- ccio_init_resource(res + 1, name,
- (unsigned long)&ioc->ioc_hpa->io_io_low_hv);
+ ccio_init_resource(res, name, &ioc->ioc_regs->io_io_low);
+ ccio_init_resource(res + 1, name, &ioc->ioc_regs->io_io_low_hv);
}
static int new_ioc_area(struct resource *res, unsigned long size,
@@ -1427,7 +1437,12 @@ static int new_ioc_area(struct resource *res, unsigned long size,
res->start = (max - size + 1) &~ (align - 1);
res->end = res->start + size;
- if (!request_resource(&iomem_resource, res))
+
+ /* We might be trying to expand the MMIO range to include
+ * a child device that has already registered it's MMIO space.
+ * Use "insert" instead of request_resource().
+ */
+ if (!insert_resource(&iomem_resource, res))
return 0;
return new_ioc_area(res, size, min, max - size, align);
@@ -1486,15 +1501,15 @@ int ccio_allocate_resource(const struct parisc_device *dev,
if (!expand_ioc_area(parent, size, min, max, align)) {
__raw_writel(((parent->start)>>16) | 0xffff0000,
- (unsigned long)&(ioc->ioc_hpa->io_io_low));
+ &ioc->ioc_regs->io_io_low);
__raw_writel(((parent->end)>>16) | 0xffff0000,
- (unsigned long)&(ioc->ioc_hpa->io_io_high));
+ &ioc->ioc_regs->io_io_high);
} else if (!expand_ioc_area(parent + 1, size, min, max, align)) {
parent++;
__raw_writel(((parent->start)>>16) | 0xffff0000,
- (unsigned long)&(ioc->ioc_hpa->io_io_low_hv));
+ &ioc->ioc_regs->io_io_low_hv);
__raw_writel(((parent->end)>>16) | 0xffff0000,
- (unsigned long)&(ioc->ioc_hpa->io_io_high_hv));
+ &ioc->ioc_regs->io_io_high_hv);
} else {
return -EBUSY;
}
@@ -1521,7 +1536,12 @@ int ccio_request_resource(const struct parisc_device *dev,
return -EBUSY;
}
- return request_resource(parent, res);
+ /* "transparent" bus bridges need to register MMIO resources
+ * firmware assigned them. e.g. children of hppb.c (e.g. K-class)
+ * registered their resources in the PDC "bus walk" (See
+ * arch/parisc/kernel/inventory.c).
+ */
+ return insert_resource(parent, res);
}
/**
@@ -1546,7 +1566,7 @@ static int ccio_probe(struct parisc_device *dev)
ioc->name = dev->id.hversion == U2_IOA_RUNWAY ? "U2" : "UTurn";
- printk(KERN_INFO "Found %s at 0x%lx\n", ioc->name, dev->hpa);
+ printk(KERN_INFO "Found %s at 0x%lx\n", ioc->name, dev->hpa.start);
for (i = 0; i < ioc_count; i++) {
ioc_p = &(*ioc_p)->next;
@@ -1554,7 +1574,7 @@ static int ccio_probe(struct parisc_device *dev)
*ioc_p = ioc;
ioc->hw_path = dev->hw_path;
- ioc->ioc_hpa = (struct ioa_registers *)dev->hpa;
+ ioc->ioc_regs = ioremap(dev->hpa.start, 4096);
ccio_ioc_init(ioc);
ccio_init_resources(ioc);
hppa_dma_ops = &ccio_ops;
diff --git a/drivers/parisc/ccio-rm-dma.c b/drivers/parisc/ccio-rm-dma.c
index 57e6385976e2..356b8357bccc 100644
--- a/drivers/parisc/ccio-rm-dma.c
+++ b/drivers/parisc/ccio-rm-dma.c
@@ -167,7 +167,7 @@ ccio_probe(struct parisc_device *dev)
{
printk(KERN_INFO "%s found %s at 0x%lx\n", MODULE_NAME,
dev->id.hversion == U2_BC_GSC ? "U2" : "UTurn",
- dev->hpa);
+ dev->hpa.start);
/*
** FIXME - should check U2 registers to verify it's really running
diff --git a/drivers/parisc/dino.c b/drivers/parisc/dino.c
index 2f2dbef2c3b7..5ab75334c579 100644
--- a/drivers/parisc/dino.c
+++ b/drivers/parisc/dino.c
@@ -178,6 +178,8 @@ static int dino_cfg_read(struct pci_bus *bus, unsigned int devfn, int where,
void __iomem *base_addr = d->hba.base_addr;
unsigned long flags;
+ DBG("%s: %p, %d, %d, %d\n", __FUNCTION__, base_addr, devfn, where,
+ size);
spin_lock_irqsave(&d->dinosaur_pen, flags);
/* tell HW which CFG address */
@@ -211,6 +213,8 @@ static int dino_cfg_write(struct pci_bus *bus, unsigned int devfn, int where,
void __iomem *base_addr = d->hba.base_addr;
unsigned long flags;
+ DBG("%s: %p, %d, %d, %d\n", __FUNCTION__, base_addr, devfn, where,
+ size);
spin_lock_irqsave(&d->dinosaur_pen, flags);
/* avoid address stepping feature */
@@ -295,7 +299,7 @@ static void dino_disable_irq(unsigned int irq)
struct dino_device *dino_dev = irq_desc[irq].handler_data;
int local_irq = gsc_find_local_irq(irq, dino_dev->global_irq, irq);
- DBG(KERN_WARNING "%s(0x%p, %d)\n", __FUNCTION__, irq_dev, irq);
+ DBG(KERN_WARNING "%s(0x%p, %d)\n", __FUNCTION__, dino_dev, irq);
/* Clear the matching bit in the IMR register */
dino_dev->imr &= ~(DINO_MASK_IRQ(local_irq));
@@ -308,7 +312,7 @@ static void dino_enable_irq(unsigned int irq)
int local_irq = gsc_find_local_irq(irq, dino_dev->global_irq, irq);
u32 tmp;
- DBG(KERN_WARNING "%s(0x%p, %d)\n", __FUNCTION__, irq_dev, irq);
+ DBG(KERN_WARNING "%s(0x%p, %d)\n", __FUNCTION__, dino_dev, irq);
/*
** clear pending IRQ bits
@@ -490,7 +494,7 @@ dino_card_setup(struct pci_bus *bus, void __iomem *base_addr)
if (res->start == F_EXTEND(0xf0000000UL | (i * _8MB)))
break;
}
- DBG("DINO GSC WRITE i=%d, start=%lx, dino addr = %lx\n",
+ DBG("DINO GSC WRITE i=%d, start=%lx, dino addr = %p\n",
i, res->start, base_addr + DINO_IO_ADDR_EN);
__raw_writel(1 << i, base_addr + DINO_IO_ADDR_EN);
}
@@ -683,6 +687,14 @@ static void __init
dino_card_init(struct dino_device *dino_dev)
{
u32 brdg_feat = 0x00784e05;
+ unsigned long status;
+
+ status = __raw_readl(dino_dev->hba.base_addr+DINO_IO_STATUS);
+ if (status & 0x0000ff80) {
+ __raw_writel(0x00000005,
+ dino_dev->hba.base_addr+DINO_IO_COMMAND);
+ udelay(1);
+ }
__raw_writel(0x00000000, dino_dev->hba.base_addr+DINO_GMASK);
__raw_writel(0x00000001, dino_dev->hba.base_addr+DINO_IO_FBB_EN);
@@ -902,15 +914,15 @@ void ccio_cujo20_fixup(struct parisc_device *dev, u32 iovp);
** If so, initialize the chip appropriately (card-mode vs bridge mode).
** Much of the initialization is common though.
*/
-static int __init
-dino_driver_callback(struct parisc_device *dev)
+static int __init dino_probe(struct parisc_device *dev)
{
struct dino_device *dino_dev; // Dino specific control struct
const char *version = "unknown";
char *name;
int is_cujo = 0;
struct pci_bus *bus;
-
+ unsigned long hpa = dev->hpa.start;
+
name = "Dino";
if (is_card_dino(&dev->id)) {
version = "3.x (card mode)";
@@ -928,11 +940,11 @@ dino_driver_callback(struct parisc_device *dev)
}
}
- printk("%s version %s found at 0x%lx\n", name, version, dev->hpa);
+ printk("%s version %s found at 0x%lx\n", name, version, hpa);
- if (!request_mem_region(dev->hpa, PAGE_SIZE, name)) {
+ if (!request_mem_region(hpa, PAGE_SIZE, name)) {
printk(KERN_ERR "DINO: Hey! Someone took my MMIO space (0x%ld)!\n",
- dev->hpa);
+ hpa);
return 1;
}
@@ -940,12 +952,12 @@ dino_driver_callback(struct parisc_device *dev)
if (is_cujo && dev->id.hversion_rev == 1) {
#ifdef CONFIG_IOMMU_CCIO
printk(KERN_WARNING "Enabling Cujo 2.0 bug workaround\n");
- if (dev->hpa == (unsigned long)CUJO_RAVEN_ADDR) {
+ if (hpa == (unsigned long)CUJO_RAVEN_ADDR) {
ccio_cujo20_fixup(dev, CUJO_RAVEN_BADPAGE);
- } else if (dev->hpa == (unsigned long)CUJO_FIREHAWK_ADDR) {
+ } else if (hpa == (unsigned long)CUJO_FIREHAWK_ADDR) {
ccio_cujo20_fixup(dev, CUJO_FIREHAWK_BADPAGE);
} else {
- printk("Don't recognise Cujo at address 0x%lx, not enabling workaround\n", dev->hpa);
+ printk("Don't recognise Cujo at address 0x%lx, not enabling workaround\n", hpa);
}
#endif
} else if (!is_cujo && !is_card_dino(&dev->id) &&
@@ -970,7 +982,7 @@ dino_driver_callback(struct parisc_device *dev)
memset(dino_dev, 0, sizeof(struct dino_device));
dino_dev->hba.dev = dev;
- dino_dev->hba.base_addr = ioremap(dev->hpa, 4096); /* faster access */
+ dino_dev->hba.base_addr = ioremap(hpa, 4096);
dino_dev->hba.lmmio_space_offset = 0; /* CPU addrs == bus addrs */
spin_lock_init(&dino_dev->dinosaur_pen);
dino_dev->hba.iommu = ccio_get_iommu(dev);
@@ -1027,9 +1039,9 @@ static struct parisc_device_id dino_tbl[] = {
};
static struct parisc_driver dino_driver = {
- .name = "Dino",
+ .name = "dino",
.id_table = dino_tbl,
- .probe = dino_driver_callback,
+ .probe = dino_probe,
};
/*
diff --git a/drivers/parisc/eisa.c b/drivers/parisc/eisa.c
index 043d47aea75b..6362bf99eff6 100644
--- a/drivers/parisc/eisa.c
+++ b/drivers/parisc/eisa.c
@@ -315,7 +315,7 @@ static int __devinit eisa_probe(struct parisc_device *dev)
char *name = is_mongoose(dev) ? "Mongoose" : "Wax";
printk(KERN_INFO "%s EISA Adapter found at 0x%08lx\n",
- name, dev->hpa);
+ name, dev->hpa.start);
eisa_dev.hba.dev = dev;
eisa_dev.hba.iommu = ccio_get_iommu(dev);
@@ -397,7 +397,7 @@ static struct parisc_device_id eisa_tbl[] = {
MODULE_DEVICE_TABLE(parisc, eisa_tbl);
static struct parisc_driver eisa_driver = {
- .name = "EISA Bus Adapter",
+ .name = "eisa_ba",
.id_table = eisa_tbl,
.probe = eisa_probe,
};
diff --git a/drivers/parisc/gsc.c b/drivers/parisc/gsc.c
index af5e02526a18..16d40f95978d 100644
--- a/drivers/parisc/gsc.c
+++ b/drivers/parisc/gsc.c
@@ -183,12 +183,20 @@ void gsc_asic_assign_irq(struct gsc_asic *asic, int local_irq, int *irqp)
*irqp = irq;
}
+static struct device *next_device(struct klist_iter *i)
+{
+ struct klist_node * n = klist_next(i);
+ return n ? container_of(n, struct device, knode_parent) : NULL;
+}
+
void gsc_fixup_irqs(struct parisc_device *parent, void *ctrl,
void (*choose_irq)(struct parisc_device *, void *))
{
struct device *dev;
+ struct klist_iter i;
- list_for_each_entry(dev, &parent->dev.children, node) {
+ klist_iter_init(&parent->dev.klist_children, &i);
+ while ((dev = next_device(&i))) {
struct parisc_device *padev = to_parisc_device(dev);
/* work-around for 715/64 and others which have parent
@@ -197,6 +205,7 @@ void gsc_fixup_irqs(struct parisc_device *parent, void *ctrl,
return gsc_fixup_irqs(padev, ctrl, choose_irq);
choose_irq(padev, ctrl);
}
+ klist_iter_exit(&i);
}
int gsc_common_setup(struct parisc_device *parent, struct gsc_asic *gsc_asic)
diff --git a/drivers/parisc/hppb.c b/drivers/parisc/hppb.c
index e869c6020370..5edf93f80757 100644
--- a/drivers/parisc/hppb.c
+++ b/drivers/parisc/hppb.c
@@ -68,14 +68,14 @@ static int hppb_probe(struct parisc_device *dev)
memset(card->next, '\0', sizeof(struct hppb_card));
card = card->next;
}
- printk(KERN_INFO "Found GeckoBoa at 0x%lx\n", dev->hpa);
+ printk(KERN_INFO "Found GeckoBoa at 0x%lx\n", dev->hpa.start);
- card->hpa = dev->hpa;
+ card->hpa = dev->hpa.start;
card->mmio_region.name = "HP-PB Bus";
card->mmio_region.flags = IORESOURCE_MEM;
- card->mmio_region.start = __raw_readl(dev->hpa + IO_IO_LOW);
- card->mmio_region.end = __raw_readl(dev->hpa + IO_IO_HIGH) - 1;
+ card->mmio_region.start = gsc_readl(dev->hpa.start + IO_IO_LOW);
+ card->mmio_region.end = gsc_readl(dev->hpa.start + IO_IO_HIGH) - 1;
status = ccio_request_resource(dev, &card->mmio_region);
if(status < 0) {
@@ -93,7 +93,7 @@ static struct parisc_device_id hppb_tbl[] = {
};
static struct parisc_driver hppb_driver = {
- .name = "Gecko Boa",
+ .name = "gecko_boa",
.id_table = hppb_tbl,
.probe = hppb_probe,
};
diff --git a/drivers/parisc/iosapic.c b/drivers/parisc/iosapic.c
index 7a57c1b8373f..a39fbfef789a 100644
--- a/drivers/parisc/iosapic.c
+++ b/drivers/parisc/iosapic.c
@@ -244,7 +244,7 @@ static struct irt_entry *iosapic_alloc_irt(int num_entries)
* 4-byte alignment on 32-bit kernels
*/
a = (unsigned long)kmalloc(sizeof(struct irt_entry) * num_entries + 8, GFP_KERNEL);
- a = (a + 7) & ~7;
+ a = (a + 7UL) & ~7UL;
return (struct irt_entry *)a;
}
diff --git a/drivers/parisc/lasi.c b/drivers/parisc/lasi.c
index cb84a4e84a2f..a8c20396ffbe 100644
--- a/drivers/parisc/lasi.c
+++ b/drivers/parisc/lasi.c
@@ -175,7 +175,7 @@ lasi_init_chip(struct parisc_device *dev)
return -ENOMEM;
lasi->name = "Lasi";
- lasi->hpa = dev->hpa;
+ lasi->hpa = dev->hpa.start;
/* Check the 4-bit (yes, only 4) version register */
lasi->version = gsc_readl(lasi->hpa + LASI_VER) & 0xf;
@@ -233,7 +233,7 @@ static struct parisc_device_id lasi_tbl[] = {
};
struct parisc_driver lasi_driver = {
- .name = "Lasi",
+ .name = "lasi",
.id_table = lasi_tbl,
.probe = lasi_init_chip,
};
diff --git a/drivers/parisc/lba_pci.c b/drivers/parisc/lba_pci.c
index 7fdd80b7eb47..5e495dcbc58a 100644
--- a/drivers/parisc/lba_pci.c
+++ b/drivers/parisc/lba_pci.c
@@ -1288,7 +1288,7 @@ lba_legacy_resources(struct parisc_device *pa_dev, struct lba_device *lba_dev)
** Adjust "window" for this rope.
*/
rsize /= ROPES_PER_IOC;
- r->start += (rsize + 1) * LBA_NUM(pa_dev->hpa);
+ r->start += (rsize + 1) * LBA_NUM(pa_dev->hpa.start);
r->end = r->start + rsize;
} else {
r->end = r->start = 0; /* Not enabled. */
@@ -1458,7 +1458,7 @@ lba_driver_probe(struct parisc_device *dev)
u32 func_class;
void *tmp_obj;
char *version;
- void __iomem *addr = ioremap(dev->hpa, 4096);
+ void __iomem *addr = ioremap(dev->hpa.start, 4096);
/* Read HW Rev First */
func_class = READ_REG32(addr + LBA_FCLASS);
@@ -1476,7 +1476,7 @@ lba_driver_probe(struct parisc_device *dev)
}
printk(KERN_INFO "%s version %s (0x%x) found at 0x%lx\n",
- MODULE_NAME, version, func_class & 0xf, dev->hpa);
+ MODULE_NAME, version, func_class & 0xf, dev->hpa.start);
if (func_class < 2) {
printk(KERN_WARNING "Can't support LBA older than "
@@ -1503,17 +1503,17 @@ lba_driver_probe(struct parisc_device *dev)
* but for the mask for func_class.
*/
printk(KERN_INFO "%s version %s (0x%x) found at 0x%lx\n",
- MODULE_NAME, version, func_class & 0xff, dev->hpa);
+ MODULE_NAME, version, func_class & 0xff, dev->hpa.start);
cfg_ops = &mercury_cfg_ops;
} else {
- printk(KERN_ERR "Unknown LBA found at 0x%lx\n", dev->hpa);
+ printk(KERN_ERR "Unknown LBA found at 0x%lx\n", dev->hpa.start);
return -ENODEV;
}
/*
** Tell I/O SAPIC driver we have a IRQ handler/region.
*/
- tmp_obj = iosapic_register(dev->hpa + LBA_IOSAPIC_BASE);
+ tmp_obj = iosapic_register(dev->hpa.start + LBA_IOSAPIC_BASE);
/* NOTE: PCI devices (e.g. 103c:1005 graphics card) which don't
** have an IRT entry will get NULL back from iosapic code.
@@ -1635,7 +1635,7 @@ void __init lba_init(void)
*/
void lba_set_iregs(struct parisc_device *lba, u32 ibase, u32 imask)
{
- void __iomem * base_addr = ioremap(lba->hpa, 4096);
+ void __iomem * base_addr = ioremap(lba->hpa.start, 4096);
imask <<= 2; /* adjust for hints - 2 more bits */
diff --git a/drivers/parisc/led.c b/drivers/parisc/led.c
index 286902298e33..95bd07b8b61b 100644
--- a/drivers/parisc/led.c
+++ b/drivers/parisc/led.c
@@ -18,6 +18,9 @@
* Changes:
* - Audit copy_from_user in led_proc_write.
* Daniele Bellucci <bellucda@tiscali.it>
+ * - Switch from using a tasklet to a work queue, so the led_LCD_driver
+ * can sleep.
+ * David Pye <dmp@davidmpye.dyndns.org>
*/
#include <linux/config.h>
@@ -37,6 +40,7 @@
#include <linux/proc_fs.h>
#include <linux/ctype.h>
#include <linux/blkdev.h>
+#include <linux/workqueue.h>
#include <linux/rcupdate.h>
#include <asm/io.h>
#include <asm/processor.h>
@@ -47,25 +51,30 @@
#include <asm/uaccess.h>
/* The control of the LEDs and LCDs on PARISC-machines have to be done
- completely in software. The necessary calculations are done in a tasklet
- which is scheduled at every timer interrupt and since the calculations
- may consume relatively much CPU-time some of the calculations can be
+ completely in software. The necessary calculations are done in a work queue
+ task which is scheduled regularly, and since the calculations may consume a
+ relatively large amount of CPU time, some of the calculations can be
turned off with the following variables (controlled via procfs) */
static int led_type = -1;
-static int led_heartbeat = 1;
-static int led_diskio = 1;
-static int led_lanrxtx = 1;
+static unsigned char lastleds; /* LED state from most recent update */
+static unsigned int led_heartbeat = 1;
+static unsigned int led_diskio = 1;
+static unsigned int led_lanrxtx = 1;
static char lcd_text[32];
static char lcd_text_default[32];
+
+static struct workqueue_struct *led_wq;
+static void led_work_func(void *);
+static DECLARE_WORK(led_task, led_work_func, NULL);
+
#if 0
#define DPRINTK(x) printk x
#else
#define DPRINTK(x)
#endif
-
struct lcd_block {
unsigned char command; /* stores the command byte */
unsigned char on; /* value for turning LED on */
@@ -116,12 +125,27 @@ lcd_info __attribute__((aligned(8))) =
#define LCD_DATA_REG lcd_info.lcd_data_reg_addr
#define LED_DATA_REG lcd_info.lcd_cmd_reg_addr /* LASI & ASP only */
+#define LED_HASLCD 1
+#define LED_NOLCD 0
+
+/* The workqueue must be created at init-time */
+static int start_task(void)
+{
+ /* Display the default text now */
+ if (led_type == LED_HASLCD) lcd_print( lcd_text_default );
+
+ /* Create the work queue and queue the LED task */
+ led_wq = create_singlethread_workqueue("led_wq");
+ queue_work(led_wq, &led_task);
+
+ return 0;
+}
+
+device_initcall(start_task);
/* ptr to LCD/LED-specific function */
static void (*led_func_ptr) (unsigned char);
-#define LED_HASLCD 1
-#define LED_NOLCD 0
#ifdef CONFIG_PROC_FS
static int led_proc_read(char *page, char **start, off_t off, int count,
int *eof, void *data)
@@ -286,52 +310,35 @@ static void led_LASI_driver(unsigned char leds)
/*
**
** led_LCD_driver()
- **
- ** The logic of the LCD driver is, that we write at every scheduled call
- ** only to one of LCD_CMD_REG _or_ LCD_DATA_REG - registers.
- ** That way we don't need to let this tasklet busywait for min_cmd_delay
- ** milliseconds.
- **
- ** TODO: check the value of "min_cmd_delay" against the value of HZ.
**
*/
static void led_LCD_driver(unsigned char leds)
{
- static int last_index; /* 0:heartbeat, 1:disk, 2:lan_in, 3:lan_out */
- static int last_was_cmd;/* 0: CMD was written last, 1: DATA was last */
- struct lcd_block *block_ptr;
- int value;
-
- switch (last_index) {
- case 0: block_ptr = &lcd_info.heartbeat;
- value = leds & LED_HEARTBEAT;
- break;
- case 1: block_ptr = &lcd_info.disk_io;
- value = leds & LED_DISK_IO;
- break;
- case 2: block_ptr = &lcd_info.lan_rcv;
- value = leds & LED_LAN_RCV;
- break;
- case 3: block_ptr = &lcd_info.lan_tx;
- value = leds & LED_LAN_TX;
- break;
- default: /* should never happen: */
- return;
- }
-
- if (last_was_cmd) {
- /* write the value to the LCD data port */
- gsc_writeb( value ? block_ptr->on : block_ptr->off, LCD_DATA_REG );
- } else {
- /* write the command-byte to the LCD command register */
- gsc_writeb( block_ptr->command, LCD_CMD_REG );
- }
+ static int i;
+ static unsigned char mask[4] = { LED_HEARTBEAT, LED_DISK_IO,
+ LED_LAN_RCV, LED_LAN_TX };
- /* now update the vars for the next interrupt iteration */
- if (++last_was_cmd == 2) { /* switch between cmd & data */
- last_was_cmd = 0;
- if (++last_index == 4)
- last_index = 0; /* switch back to heartbeat index */
+ static struct lcd_block * blockp[4] = {
+ &lcd_info.heartbeat,
+ &lcd_info.disk_io,
+ &lcd_info.lan_rcv,
+ &lcd_info.lan_tx
+ };
+
+ /* Convert min_cmd_delay to milliseconds */
+ unsigned int msec_cmd_delay = 1 + (lcd_info.min_cmd_delay / 1000);
+
+ for (i=0; i<4; ++i)
+ {
+ if ((leds & mask[i]) != (lastleds & mask[i]))
+ {
+ gsc_writeb( blockp[i]->command, LCD_CMD_REG );
+ msleep(msec_cmd_delay);
+
+ gsc_writeb( leds & mask[i] ? blockp[i]->on :
+ blockp[i]->off, LCD_DATA_REG );
+ msleep(msec_cmd_delay);
+ }
}
}
@@ -356,7 +363,7 @@ static __inline__ int led_get_net_activity(void)
rx_total = tx_total = 0;
- /* we are running as tasklet, so locking dev_base
+ /* we are running as a workqueue task, so locking dev_base
* for reading should be OK */
read_lock(&dev_base_lock);
rcu_read_lock();
@@ -405,7 +412,7 @@ static __inline__ int led_get_diskio_activity(void)
static unsigned long last_pgpgin, last_pgpgout;
struct page_state pgstat;
int changed;
-
+
get_full_page_state(&pgstat); /* get no of sectors in & out */
/* Just use a very simple calculation here. Do not care about overflow,
@@ -413,86 +420,70 @@ static __inline__ int led_get_diskio_activity(void)
changed = (pgstat.pgpgin != last_pgpgin) || (pgstat.pgpgout != last_pgpgout);
last_pgpgin = pgstat.pgpgin;
last_pgpgout = pgstat.pgpgout;
-
+
return (changed ? LED_DISK_IO : 0);
}
/*
- ** led_tasklet_func()
+ ** led_work_func()
**
- ** is scheduled at every timer interrupt from time.c and
- ** updates the chassis LCD/LED
+ ** manages when and which chassis LCD/LED gets updated
TODO:
- display load average (older machines like 715/64 have 4 "free" LED's for that)
- optimizations
*/
-#define HEARTBEAT_LEN (HZ*6/100)
-#define HEARTBEAT_2ND_RANGE_START (HZ*22/100)
+#define HEARTBEAT_LEN (HZ*10/100)
+#define HEARTBEAT_2ND_RANGE_START (HZ*28/100)
#define HEARTBEAT_2ND_RANGE_END (HEARTBEAT_2ND_RANGE_START + HEARTBEAT_LEN)
-#define NORMALIZED_COUNT(count) (count/(HZ/100))
+#define LED_UPDATE_INTERVAL (1 + (HZ*19/1000))
-static void led_tasklet_func(unsigned long unused)
+static void led_work_func (void *unused)
{
- static unsigned char lastleds;
- unsigned char currentleds; /* stores current value of the LEDs */
- static unsigned long count; /* static incremented value, not wrapped */
+ static unsigned long last_jiffies;
static unsigned long count_HZ; /* counter in range 0..HZ */
+ unsigned char currentleds = 0; /* stores current value of the LEDs */
/* exit if not initialized */
if (!led_func_ptr)
return;
- /* increment the local counters */
- ++count;
- if (++count_HZ == HZ)
+ /* increment the heartbeat timekeeper */
+ count_HZ += jiffies - last_jiffies;
+ last_jiffies = jiffies;
+ if (count_HZ >= HZ)
count_HZ = 0;
- currentleds = lastleds;
-
- if (led_heartbeat)
- {
- /* flash heartbeat-LED like a real heart (2 x short then a long delay) */
- if (count_HZ<HEARTBEAT_LEN ||
- (count_HZ>=HEARTBEAT_2ND_RANGE_START && count_HZ<HEARTBEAT_2ND_RANGE_END))
- currentleds |= LED_HEARTBEAT;
- else
- currentleds &= ~LED_HEARTBEAT;
- }
-
- /* look for network activity and flash LEDs respectively */
- if (led_lanrxtx && ((NORMALIZED_COUNT(count)+(8/2)) & 7) == 0)
+ if (likely(led_heartbeat))
{
- currentleds &= ~(LED_LAN_RCV | LED_LAN_TX);
- currentleds |= led_get_net_activity();
+ /* flash heartbeat-LED like a real heart
+ * (2 x short then a long delay)
+ */
+ if (count_HZ < HEARTBEAT_LEN ||
+ (count_HZ >= HEARTBEAT_2ND_RANGE_START &&
+ count_HZ < HEARTBEAT_2ND_RANGE_END))
+ currentleds |= LED_HEARTBEAT;
}
- /* avoid to calculate diskio-stats at same irq as netio-stats */
- if (led_diskio && (NORMALIZED_COUNT(count) & 7) == 0)
- {
- currentleds &= ~LED_DISK_IO;
- currentleds |= led_get_diskio_activity();
- }
+ if (likely(led_lanrxtx)) currentleds |= led_get_net_activity();
+ if (likely(led_diskio)) currentleds |= led_get_diskio_activity();
/* blink all LEDs twice a second if we got an Oops (HPMC) */
- if (oops_in_progress) {
+ if (unlikely(oops_in_progress))
currentleds = (count_HZ<=(HZ/2)) ? 0 : 0xff;
- }
-
- /* update the LCD/LEDs */
- if (currentleds != lastleds) {
- led_func_ptr(currentleds);
- lastleds = currentleds;
- }
-}
-/* main led tasklet struct (scheduled from time.c) */
-DECLARE_TASKLET_DISABLED(led_tasklet, led_tasklet_func, 0);
+ if (currentleds != lastleds)
+ {
+ led_func_ptr(currentleds); /* Update the LCD/LEDs */
+ lastleds = currentleds;
+ }
+ queue_delayed_work(led_wq, &led_task, LED_UPDATE_INTERVAL);
+}
/*
** led_halt()
@@ -522,9 +513,13 @@ static int led_halt(struct notifier_block *nb, unsigned long event, void *buf)
default: return NOTIFY_DONE;
}
- /* completely stop the LED/LCD tasklet */
- tasklet_disable(&led_tasklet);
-
+ /* Cancel the work item and delete the queue */
+ if (led_wq) {
+ cancel_rearming_delayed_workqueue(led_wq, &led_task);
+ destroy_workqueue(led_wq);
+ led_wq = NULL;
+ }
+
if (lcd_info.model == DISPLAY_MODEL_LCD)
lcd_print(txt);
else
@@ -559,7 +554,6 @@ int __init register_led_driver(int model, unsigned long cmd_reg, unsigned long d
printk(KERN_INFO "LCD display at %lx,%lx registered\n",
LCD_CMD_REG , LCD_DATA_REG);
led_func_ptr = led_LCD_driver;
- lcd_print( lcd_text_default );
led_type = LED_HASLCD;
break;
@@ -589,9 +583,11 @@ int __init register_led_driver(int model, unsigned long cmd_reg, unsigned long d
initialized++;
register_reboot_notifier(&led_notifier);
- /* start the led tasklet for the first time */
- tasklet_enable(&led_tasklet);
-
+ /* Ensure the work is queued */
+ if (led_wq) {
+ queue_work(led_wq, &led_task);
+ }
+
return 0;
}
@@ -626,8 +622,8 @@ void __init register_led_regions(void)
** lcd_print()
**
** Displays the given string on the LCD-Display of newer machines.
- ** lcd_print() disables the timer-based led tasklet during its
- ** execution and enables it afterwards again.
+ ** lcd_print() disables/enables the timer-based led work queue to
+ ** avoid a race condition while writing the CMD/DATA register pair.
**
*/
int lcd_print( char *str )
@@ -637,12 +633,13 @@ int lcd_print( char *str )
if (!led_func_ptr || lcd_info.model != DISPLAY_MODEL_LCD)
return 0;
- /* temporarily disable the led tasklet */
- tasklet_disable(&led_tasklet);
+ /* temporarily disable the led work task */
+ if (led_wq)
+ cancel_rearming_delayed_workqueue(led_wq, &led_task);
/* copy display string to buffer for procfs */
strlcpy(lcd_text, str, sizeof(lcd_text));
-
+
/* Set LCD Cursor to 1st character */
gsc_writeb(lcd_info.reset_cmd1, LCD_CMD_REG);
udelay(lcd_info.min_cmd_delay);
@@ -656,8 +653,10 @@ int lcd_print( char *str )
udelay(lcd_info.min_cmd_delay);
}
- /* re-enable the led tasklet */
- tasklet_enable(&led_tasklet);
+ /* re-queue the work */
+ if (led_wq) {
+ queue_work(led_wq, &led_task);
+ }
return lcd_info.lcd_width;
}
diff --git a/drivers/parisc/pdc_stable.c b/drivers/parisc/pdc_stable.c
index 67c8f3b44848..273a74179720 100644
--- a/drivers/parisc/pdc_stable.c
+++ b/drivers/parisc/pdc_stable.c
@@ -536,7 +536,7 @@ pdcs_info_read(struct subsystem *entry, char *buf)
out += sprintf(out, "Memory tested: ");
if ((result & 0x0F) < 0x0E)
- out += sprintf(out, "%.3f MB", 0.256*(1<<(result & 0x0F)));
+ out += sprintf(out, "%d kB", (1<<(result & 0x0F))*256);
else
out += sprintf(out, "All");
out += sprintf(out, "\n");
diff --git a/drivers/parisc/sba_iommu.c b/drivers/parisc/sba_iommu.c
index 82ea68b55df4..c85653f315aa 100644
--- a/drivers/parisc/sba_iommu.c
+++ b/drivers/parisc/sba_iommu.c
@@ -91,8 +91,8 @@ extern struct proc_dir_entry * proc_mckinley_root;
#define DBG_RES(x...)
#endif
-#if defined(__LP64__) && !defined(CONFIG_PDC_NARROW)
-/* "low end" PA8800 machines use ZX1 chipset */
+#if defined(CONFIG_64BIT)
+/* "low end" PA8800 machines use ZX1 chipset: PAT PDC and only run 64-bit */
#define ZX1_SUPPORT
#endif
@@ -231,7 +231,7 @@ struct ioc {
spinlock_t res_lock;
unsigned int res_bitshift; /* from the LEFT! */
unsigned int res_size; /* size of resource map in bytes */
-#if SBA_HINT_SUPPORT
+#ifdef SBA_HINT_SUPPORT
/* FIXME : DMA HINTs not used */
unsigned long hint_mask_pdir; /* bits used for DMA hints */
unsigned int hint_shift_pdir;
@@ -294,7 +294,7 @@ static unsigned long piranha_bad_128k = 0;
/* Looks nice and keeps the compiler happy */
#define SBA_DEV(d) ((struct sba_device *) (d))
-#if SBA_AGP_SUPPORT
+#ifdef SBA_AGP_SUPPORT
static int reserve_sba_gart = 1;
#endif
@@ -314,7 +314,7 @@ static int reserve_sba_gart = 1;
#define WRITE_REG32(val, addr) __raw_writel(cpu_to_le32(val), addr)
#define WRITE_REG64(val, addr) __raw_writeq(cpu_to_le64(val), addr)
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
#define READ_REG(addr) READ_REG64(addr)
#define WRITE_REG(value, addr) WRITE_REG64(value, addr)
#else
@@ -324,7 +324,7 @@ static int reserve_sba_gart = 1;
#ifdef DEBUG_SBA_INIT
-/* NOTE: When __LP64__ isn't defined, READ_REG64() is two 32-bit reads */
+/* NOTE: When CONFIG_64BIT isn't defined, READ_REG64() is two 32-bit reads */
/**
* sba_dump_ranges - debugging only - print ranges assigned to this IOA
@@ -364,7 +364,7 @@ static void sba_dump_tlb(void __iomem *hpa)
#else
#define sba_dump_ranges(x)
#define sba_dump_tlb(x)
-#endif
+#endif /* DEBUG_SBA_INIT */
#ifdef ASSERT_PDIR_SANITY
@@ -674,7 +674,7 @@ sba_free_range(struct ioc *ioc, dma_addr_t iova, size_t size)
*
***************************************************************/
-#if SBA_HINT_SUPPORT
+#ifdef SBA_HINT_SUPPORT
#define SBA_DMA_HINT(ioc, val) ((val) << (ioc)->hint_shift_pdir)
#endif
@@ -743,9 +743,8 @@ sba_io_pdir_entry(u64 *pdir_ptr, space_t sid, unsigned long vba,
* (bit #61, big endian), we have to flush and sync every time
* IO-PDIR is changed in Ike/Astro.
*/
- if (ioc_needs_fdc) {
- asm volatile("fdc 0(%%sr1,%0)\n\tsync" : : "r" (pdir_ptr));
- }
+ if (ioc_needs_fdc)
+ asm volatile("fdc %%r0(%0)" : : "r" (pdir_ptr));
}
@@ -769,42 +768,57 @@ static SBA_INLINE void
sba_mark_invalid(struct ioc *ioc, dma_addr_t iova, size_t byte_cnt)
{
u32 iovp = (u32) SBA_IOVP(ioc,iova);
-
- /* Even though this is a big-endian machine, the entries
- ** in the iopdir are little endian. That's why we clear the byte
- ** at +7 instead of at +0.
- */
- int off = PDIR_INDEX(iovp)*sizeof(u64)+7;
+ u64 *pdir_ptr = &ioc->pdir_base[PDIR_INDEX(iovp)];
#ifdef ASSERT_PDIR_SANITY
- /* Assert first pdir entry is set */
- if (0x80 != (((u8 *) ioc->pdir_base)[off])) {
+ /* Assert first pdir entry is set.
+ **
+ ** Even though this is a big-endian machine, the entries
+ ** in the iopdir are little endian. That's why we look at
+ ** the byte at +7 instead of at +0.
+ */
+ if (0x80 != (((u8 *) pdir_ptr)[7])) {
sba_dump_pdir_entry(ioc,"sba_mark_invalid()", PDIR_INDEX(iovp));
}
#endif
- if (byte_cnt <= IOVP_SIZE)
+ if (byte_cnt > IOVP_SIZE)
{
- iovp |= IOVP_SHIFT; /* set "size" field for PCOM */
+#if 0
+ unsigned long entries_per_cacheline = ioc_needs_fdc ?
+ L1_CACHE_ALIGN(((unsigned long) pdir_ptr))
+ - (unsigned long) pdir_ptr;
+ : 262144;
+#endif
- /*
- ** clear I/O PDIR entry "valid" bit
- ** Do NOT clear the rest - save it for debugging.
- ** We should only clear bits that have previously
- ** been enabled.
- */
- ((u8 *)(ioc->pdir_base))[off] = 0;
- } else {
- u32 t = get_order(byte_cnt) + PAGE_SHIFT;
+ /* set "size" field for PCOM */
+ iovp |= get_order(byte_cnt) + PAGE_SHIFT;
- iovp |= t;
do {
/* clear I/O Pdir entry "valid" bit first */
- ((u8 *)(ioc->pdir_base))[off] = 0;
- off += sizeof(u64);
+ ((u8 *) pdir_ptr)[7] = 0;
+ if (ioc_needs_fdc) {
+ asm volatile("fdc %%r0(%0)" : : "r" (pdir_ptr));
+#if 0
+ entries_per_cacheline = L1_CACHE_SHIFT - 3;
+#endif
+ }
+ pdir_ptr++;
byte_cnt -= IOVP_SIZE;
- } while (byte_cnt > 0);
- }
+ } while (byte_cnt > IOVP_SIZE);
+ } else
+ iovp |= IOVP_SHIFT; /* set "size" field for PCOM */
+
+ /*
+ ** clear I/O PDIR entry "valid" bit.
+ ** We have to R/M/W the cacheline regardless how much of the
+ ** pdir entry that we clobber.
+ ** The rest of the entry would be useful for debugging if we
+ ** could dump core on HPMC.
+ */
+ ((u8 *) pdir_ptr)[7] = 0;
+ if (ioc_needs_fdc)
+ asm volatile("fdc %%r0(%0)" : : "r" (pdir_ptr));
WRITE_REG( SBA_IOVA(ioc, iovp, 0, 0), ioc->ioc_hpa+IOC_PCOM);
}
@@ -819,18 +833,29 @@ sba_mark_invalid(struct ioc *ioc, dma_addr_t iova, size_t byte_cnt)
static int sba_dma_supported( struct device *dev, u64 mask)
{
struct ioc *ioc;
+
if (dev == NULL) {
printk(KERN_ERR MODULE_NAME ": EISA/ISA/et al not supported\n");
BUG();
return(0);
}
- ioc = GET_IOC(dev);
+ /* Documentation/DMA-mapping.txt tells drivers to try 64-bit first,
+ * then fall back to 32-bit if that fails.
+ * We are just "encouraging" 32-bit DMA masks here since we can
+ * never allow IOMMU bypass unless we add special support for ZX1.
+ */
+ if (mask > ~0U)
+ return 0;
- /* check if mask is > than the largest IO Virt Address */
+ ioc = GET_IOC(dev);
- return((int) (mask >= (ioc->ibase +
- (ioc->pdir_size / sizeof(u64) * IOVP_SIZE) )));
+ /*
+ * check if mask is >= than the current max IO Virt Address
+ * The max IO Virt address will *always* < 30 bits.
+ */
+ return((int)(mask >= (ioc->ibase - 1 +
+ (ioc->pdir_size / sizeof(u64) * IOVP_SIZE) )));
}
@@ -898,11 +923,17 @@ sba_map_single(struct device *dev, void *addr, size_t size,
size -= IOVP_SIZE;
pdir_start++;
}
- /* form complete address */
+
+ /* force FDC ops in io_pdir_entry() to be visible to IOMMU */
+ if (ioc_needs_fdc)
+ asm volatile("sync" : : );
+
#ifdef ASSERT_PDIR_SANITY
sba_check_pdir(ioc,"Check after sba_map_single()");
#endif
spin_unlock_irqrestore(&ioc->res_lock, flags);
+
+ /* form complete address */
return SBA_IOVA(ioc, iovp, offset, DEFAULT_DMA_HINT_REG);
}
@@ -958,12 +989,19 @@ sba_unmap_single(struct device *dev, dma_addr_t iova, size_t size,
d--;
}
ioc->saved_cnt = 0;
+
READ_REG(ioc->ioc_hpa+IOC_PCOM); /* flush purges */
}
#else /* DELAYED_RESOURCE_CNT == 0 */
sba_free_range(ioc, iova, size);
+
+ /* If fdc's were issued, force fdc's to be visible now */
+ if (ioc_needs_fdc)
+ asm volatile("sync" : : );
+
READ_REG(ioc->ioc_hpa+IOC_PCOM); /* flush purges */
#endif /* DELAYED_RESOURCE_CNT == 0 */
+
spin_unlock_irqrestore(&ioc->res_lock, flags);
/* XXX REVISIT for 2.5 Linux - need syncdma for zero-copy support.
@@ -986,7 +1024,7 @@ sba_unmap_single(struct device *dev, dma_addr_t iova, size_t size,
* See Documentation/DMA-mapping.txt
*/
static void *sba_alloc_consistent(struct device *hwdev, size_t size,
- dma_addr_t *dma_handle, int gfp)
+ dma_addr_t *dma_handle, gfp_t gfp)
{
void *ret;
@@ -1106,6 +1144,10 @@ sba_map_sg(struct device *dev, struct scatterlist *sglist, int nents,
*/
filled = iommu_fill_pdir(ioc, sglist, nents, 0, sba_io_pdir_entry);
+ /* force FDC ops in io_pdir_entry() to be visible to IOMMU */
+ if (ioc_needs_fdc)
+ asm volatile("sync" : : );
+
#ifdef ASSERT_PDIR_SANITY
if (sba_check_pdir(ioc,"Check after sba_map_sg()"))
{
@@ -1234,8 +1276,10 @@ sba_alloc_pdir(unsigned int pdir_size)
unsigned long pdir_order = get_order(pdir_size);
pdir_base = __get_free_pages(GFP_KERNEL, pdir_order);
- if (NULL == (void *) pdir_base)
- panic("sba_ioc_init() could not allocate I/O Page Table\n");
+ if (NULL == (void *) pdir_base) {
+ panic("%s() could not allocate I/O Page Table\n",
+ __FUNCTION__);
+ }
/* If this is not PA8700 (PCX-W2)
** OR newer than ver 2.2
@@ -1322,19 +1366,29 @@ sba_alloc_pdir(unsigned int pdir_size)
return (void *) pdir_base;
}
+static struct device *next_device(struct klist_iter *i)
+{
+ struct klist_node * n = klist_next(i);
+ return n ? container_of(n, struct device, knode_parent) : NULL;
+}
+
/* setup Mercury or Elroy IBASE/IMASK registers. */
-static void setup_ibase_imask(struct parisc_device *sba, struct ioc *ioc, int ioc_num)
+static void
+setup_ibase_imask(struct parisc_device *sba, struct ioc *ioc, int ioc_num)
{
- /* lba_set_iregs() is in drivers/parisc/lba_pci.c */
+ /* lba_set_iregs() is in drivers/parisc/lba_pci.c */
extern void lba_set_iregs(struct parisc_device *, u32, u32);
struct device *dev;
+ struct klist_iter i;
- list_for_each_entry(dev, &sba->dev.children, node) {
+ klist_iter_init(&sba->dev.klist_children, &i);
+ while ((dev = next_device(&i))) {
struct parisc_device *lba = to_parisc_device(dev);
- int rope_num = (lba->hpa >> 13) & 0xf;
+ int rope_num = (lba->hpa.start >> 13) & 0xf;
if (rope_num >> 3 == ioc_num)
lba_set_iregs(lba, ioc->ibase, ioc->imask);
}
+ klist_iter_exit(&i);
}
static void
@@ -1343,7 +1397,7 @@ sba_ioc_init_pluto(struct parisc_device *sba, struct ioc *ioc, int ioc_num)
u32 iova_space_mask;
u32 iova_space_size;
int iov_order, tcnfg;
-#if SBA_AGP_SUPPORT
+#ifdef SBA_AGP_SUPPORT
int agp_found = 0;
#endif
/*
@@ -1380,7 +1434,7 @@ sba_ioc_init_pluto(struct parisc_device *sba, struct ioc *ioc, int ioc_num)
DBG_INIT("%s() pdir %p size %x\n",
__FUNCTION__, ioc->pdir_base, ioc->pdir_size);
-#if SBA_HINT_SUPPORT
+#ifdef SBA_HINT_SUPPORT
ioc->hint_shift_pdir = iov_order + PAGE_SHIFT;
ioc->hint_mask_pdir = ~(0x3 << (iov_order + PAGE_SHIFT));
@@ -1404,7 +1458,7 @@ sba_ioc_init_pluto(struct parisc_device *sba, struct ioc *ioc, int ioc_num)
WRITE_REG(ioc->imask, ioc->ioc_hpa + IOC_IMASK);
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
/*
** Setting the upper bits makes checking for bypass addresses
** a little faster later on.
@@ -1437,7 +1491,7 @@ sba_ioc_init_pluto(struct parisc_device *sba, struct ioc *ioc, int ioc_num)
*/
WRITE_REG(ioc->ibase | 31, ioc->ioc_hpa + IOC_PCOM);
-#if SBA_AGP_SUPPORT
+#ifdef SBA_AGP_SUPPORT
/*
** If an AGP device is present, only use half of the IOV space
** for PCI DMA. Unfortunately we can't know ahead of time
@@ -1489,11 +1543,9 @@ sba_ioc_init(struct parisc_device *sba, struct ioc *ioc, int ioc_num)
if (iova_space_size < (1 << (20 - PAGE_SHIFT))) {
iova_space_size = 1 << (20 - PAGE_SHIFT);
}
-#ifdef __LP64__
else if (iova_space_size > (1 << (30 - PAGE_SHIFT))) {
iova_space_size = 1 << (30 - PAGE_SHIFT);
}
-#endif
/*
** iova space must be log2() in size.
@@ -1519,7 +1571,7 @@ sba_ioc_init(struct parisc_device *sba, struct ioc *ioc, int ioc_num)
DBG_INIT("%s() pdir %p size %x\n",
__FUNCTION__, ioc->pdir_base, pdir_size);
-#if SBA_HINT_SUPPORT
+#ifdef SBA_HINT_SUPPORT
/* FIXME : DMA HINTs not used */
ioc->hint_shift_pdir = iov_order + PAGE_SHIFT;
ioc->hint_mask_pdir = ~(0x3 << (iov_order + PAGE_SHIFT));
@@ -1590,7 +1642,7 @@ sba_ioc_init(struct parisc_device *sba, struct ioc *ioc, int ioc_num)
static void __iomem *ioc_remap(struct sba_device *sba_dev, int offset)
{
- return ioremap(sba_dev->dev->hpa + offset, SBA_FUNC_SIZE);
+ return ioremap(sba_dev->dev->hpa.start + offset, SBA_FUNC_SIZE);
}
static void sba_hw_init(struct sba_device *sba_dev)
@@ -1968,7 +2020,7 @@ sba_driver_callback(struct parisc_device *dev)
u32 func_class;
int i;
char *version;
- void __iomem *sba_addr = ioremap(dev->hpa, SBA_FUNC_SIZE);
+ void __iomem *sba_addr = ioremap(dev->hpa.start, SBA_FUNC_SIZE);
sba_dump_ranges(sba_addr);
@@ -2010,7 +2062,7 @@ sba_driver_callback(struct parisc_device *dev)
}
printk(KERN_INFO "%s found %s at 0x%lx\n",
- MODULE_NAME, version, dev->hpa);
+ MODULE_NAME, version, dev->hpa.start);
sba_dev = kmalloc(sizeof(struct sba_device), GFP_KERNEL);
if (!sba_dev) {
diff --git a/drivers/parisc/superio.c b/drivers/parisc/superio.c
index e0efed796b92..bab3bcabcb6e 100644
--- a/drivers/parisc/superio.c
+++ b/drivers/parisc/superio.c
@@ -11,6 +11,7 @@
* (C) Copyright 2000 Alex deVries <alex@onefishtwo.ca>
* (C) Copyright 2001 John Marvin <jsm fc hp com>
* (C) Copyright 2003 Grant Grundler <grundler parisc-linux org>
+ * (C) Copyright 2005 Kyle McMartin <kyle@parisc-linux.org>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -405,6 +406,7 @@ static void __devinit superio_serial_init(void)
serial[0].iobase = sio_dev.sp1_base;
serial[0].irq = SP1_IRQ;
+ spin_lock_init(&serial[0].lock);
retval = early_serial_setup(&serial[0]);
if (retval < 0) {
@@ -414,6 +416,7 @@ static void __devinit superio_serial_init(void)
serial[1].iobase = sio_dev.sp2_base;
serial[1].irq = SP2_IRQ;
+ spin_lock_init(&serial[1].lock);
retval = early_serial_setup(&serial[1]);
if (retval < 0)
diff --git a/drivers/parisc/wax.c b/drivers/parisc/wax.c
index e547d7d024d8..17dce2adf7fe 100644
--- a/drivers/parisc/wax.c
+++ b/drivers/parisc/wax.c
@@ -81,7 +81,7 @@ wax_init_chip(struct parisc_device *dev)
return -ENOMEM;
wax->name = "wax";
- wax->hpa = dev->hpa;
+ wax->hpa = dev->hpa.start;
wax->version = 0; /* gsc_readb(wax->hpa+WAX_VER); */
printk(KERN_INFO "%s at 0x%lx found.\n", wax->name, wax->hpa);
diff --git a/drivers/parport/parport_gsc.c b/drivers/parport/parport_gsc.c
index 02d72acd1c89..fde29a75f888 100644
--- a/drivers/parport/parport_gsc.c
+++ b/drivers/parport/parport_gsc.c
@@ -359,11 +359,12 @@ static int __devinit parport_init_chip(struct parisc_device *dev)
unsigned long port;
if (!dev->irq) {
- printk("IRQ not found for parallel device at 0x%lx\n", dev->hpa);
+ printk(KERN_WARNING "IRQ not found for parallel device at 0x%lx\n",
+ dev->hpa.start);
return -ENODEV;
}
- port = dev->hpa + PARPORT_GSC_OFFSET;
+ port = dev->hpa.start + PARPORT_GSC_OFFSET;
/* some older machines with ASP-chip don't support
* the enhanced parport modes.
diff --git a/drivers/parport/probe.c b/drivers/parport/probe.c
index 6e6f42d01e64..4b48b31ec235 100644
--- a/drivers/parport/probe.c
+++ b/drivers/parport/probe.c
@@ -78,17 +78,15 @@ static void parse_data(struct parport *port, int device, char *str)
u++;
}
if (!strcmp(p, "MFG") || !strcmp(p, "MANUFACTURER")) {
- if (info->mfr)
- kfree (info->mfr);
+ kfree(info->mfr);
info->mfr = kstrdup(sep, GFP_KERNEL);
} else if (!strcmp(p, "MDL") || !strcmp(p, "MODEL")) {
- if (info->model)
- kfree (info->model);
+ kfree(info->model);
info->model = kstrdup(sep, GFP_KERNEL);
} else if (!strcmp(p, "CLS") || !strcmp(p, "CLASS")) {
int i;
- if (info->class_name)
- kfree (info->class_name);
+
+ kfree(info->class_name);
info->class_name = kstrdup(sep, GFP_KERNEL);
for (u = sep; *u; u++)
*u = toupper(*u);
@@ -102,21 +100,22 @@ static void parse_data(struct parport *port, int device, char *str)
info->class = PARPORT_CLASS_OTHER;
} else if (!strcmp(p, "CMD") ||
!strcmp(p, "COMMAND SET")) {
- if (info->cmdset)
- kfree (info->cmdset);
+ kfree(info->cmdset);
info->cmdset = kstrdup(sep, GFP_KERNEL);
/* if it speaks printer language, it's
probably a printer */
if (strstr(sep, "PJL") || strstr(sep, "PCL"))
guessed_class = PARPORT_CLASS_PRINTER;
} else if (!strcmp(p, "DES") || !strcmp(p, "DESCRIPTION")) {
- if (info->description)
- kfree (info->description);
+ kfree(info->description);
info->description = kstrdup(sep, GFP_KERNEL);
}
}
rock_on:
- if (q) p = q+1; else p=NULL;
+ if (q)
+ p = q + 1;
+ else
+ p = NULL;
}
/* If the device didn't tell us its class, maybe we have managed to
diff --git a/drivers/parport/share.c b/drivers/parport/share.c
index ae7becf7efa5..9cb3ab156b09 100644
--- a/drivers/parport/share.c
+++ b/drivers/parport/share.c
@@ -202,16 +202,11 @@ static void free_port (struct parport *port)
list_del(&port->full_list);
spin_unlock(&full_list_lock);
for (d = 0; d < 5; d++) {
- if (port->probe_info[d].class_name)
- kfree (port->probe_info[d].class_name);
- if (port->probe_info[d].mfr)
- kfree (port->probe_info[d].mfr);
- if (port->probe_info[d].model)
- kfree (port->probe_info[d].model);
- if (port->probe_info[d].cmdset)
- kfree (port->probe_info[d].cmdset);
- if (port->probe_info[d].description)
- kfree (port->probe_info[d].description);
+ kfree(port->probe_info[d].class_name);
+ kfree(port->probe_info[d].mfr);
+ kfree(port->probe_info[d].model);
+ kfree(port->probe_info[d].cmdset);
+ kfree(port->probe_info[d].description);
}
kfree(port->name);
@@ -618,9 +613,9 @@ parport_register_device(struct parport *port, const char *name,
return tmp;
out_free_all:
- kfree (tmp->state);
+ kfree(tmp->state);
out_free_pardevice:
- kfree (tmp);
+ kfree(tmp);
out:
parport_put_port (port);
module_put(port->ops->owner);
diff --git a/drivers/pci/access.c b/drivers/pci/access.c
index 24a76de49f41..ea16805a153c 100644
--- a/drivers/pci/access.c
+++ b/drivers/pci/access.c
@@ -2,6 +2,8 @@
#include <linux/module.h>
#include <linux/ioport.h>
+#include "pci.h"
+
/*
* This interrupt-safe spinlock protects all accesses to PCI
* configuration space.
@@ -60,3 +62,92 @@ EXPORT_SYMBOL(pci_bus_read_config_dword);
EXPORT_SYMBOL(pci_bus_write_config_byte);
EXPORT_SYMBOL(pci_bus_write_config_word);
EXPORT_SYMBOL(pci_bus_write_config_dword);
+
+static u32 pci_user_cached_config(struct pci_dev *dev, int pos)
+{
+ u32 data;
+
+ data = dev->saved_config_space[pos/sizeof(dev->saved_config_space[0])];
+ data >>= (pos % sizeof(dev->saved_config_space[0])) * 8;
+ return data;
+}
+
+#define PCI_USER_READ_CONFIG(size,type) \
+int pci_user_read_config_##size \
+ (struct pci_dev *dev, int pos, type *val) \
+{ \
+ unsigned long flags; \
+ int ret = 0; \
+ u32 data = -1; \
+ if (PCI_##size##_BAD) return PCIBIOS_BAD_REGISTER_NUMBER; \
+ spin_lock_irqsave(&pci_lock, flags); \
+ if (likely(!dev->block_ucfg_access)) \
+ ret = dev->bus->ops->read(dev->bus, dev->devfn, \
+ pos, sizeof(type), &data); \
+ else if (pos < sizeof(dev->saved_config_space)) \
+ data = pci_user_cached_config(dev, pos); \
+ spin_unlock_irqrestore(&pci_lock, flags); \
+ *val = (type)data; \
+ return ret; \
+}
+
+#define PCI_USER_WRITE_CONFIG(size,type) \
+int pci_user_write_config_##size \
+ (struct pci_dev *dev, int pos, type val) \
+{ \
+ unsigned long flags; \
+ int ret = -EIO; \
+ if (PCI_##size##_BAD) return PCIBIOS_BAD_REGISTER_NUMBER; \
+ spin_lock_irqsave(&pci_lock, flags); \
+ if (likely(!dev->block_ucfg_access)) \
+ ret = dev->bus->ops->write(dev->bus, dev->devfn, \
+ pos, sizeof(type), val); \
+ spin_unlock_irqrestore(&pci_lock, flags); \
+ return ret; \
+}
+
+PCI_USER_READ_CONFIG(byte, u8)
+PCI_USER_READ_CONFIG(word, u16)
+PCI_USER_READ_CONFIG(dword, u32)
+PCI_USER_WRITE_CONFIG(byte, u8)
+PCI_USER_WRITE_CONFIG(word, u16)
+PCI_USER_WRITE_CONFIG(dword, u32)
+
+/**
+ * pci_block_user_cfg_access - Block userspace PCI config reads/writes
+ * @dev: pci device struct
+ *
+ * This function blocks any userspace PCI config accesses from occurring.
+ * When blocked, any writes will be bit bucketed and reads will return the
+ * data saved using pci_save_state for the first 64 bytes of config
+ * space and return 0xff for all other config reads.
+ **/
+void pci_block_user_cfg_access(struct pci_dev *dev)
+{
+ unsigned long flags;
+
+ pci_save_state(dev);
+
+ /* spinlock to synchronize with anyone reading config space now */
+ spin_lock_irqsave(&pci_lock, flags);
+ dev->block_ucfg_access = 1;
+ spin_unlock_irqrestore(&pci_lock, flags);
+}
+EXPORT_SYMBOL_GPL(pci_block_user_cfg_access);
+
+/**
+ * pci_unblock_user_cfg_access - Unblock userspace PCI config reads/writes
+ * @dev: pci device struct
+ *
+ * This function allows userspace PCI config accesses to resume.
+ **/
+void pci_unblock_user_cfg_access(struct pci_dev *dev)
+{
+ unsigned long flags;
+
+ /* spinlock to synchronize with anyone reading saved config space */
+ spin_lock_irqsave(&pci_lock, flags);
+ dev->block_ucfg_access = 0;
+ spin_unlock_irqrestore(&pci_lock, flags);
+}
+EXPORT_SYMBOL_GPL(pci_unblock_user_cfg_access);
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c
index 424e7de181ae..8e21f6ab89a1 100644
--- a/drivers/pci/hotplug/acpiphp_glue.c
+++ b/drivers/pci/hotplug/acpiphp_glue.c
@@ -58,6 +58,9 @@ static LIST_HEAD(bridge_list);
static void handle_hotplug_event_bridge (acpi_handle, u32, void *);
static void handle_hotplug_event_func (acpi_handle, u32, void *);
+static void acpiphp_sanitize_bus(struct pci_bus *bus);
+static void acpiphp_set_hpp_values(acpi_handle handle, struct pci_bus *bus);
+
/*
* initialization & terminatation routines
@@ -796,8 +799,13 @@ static int enable_device(struct acpiphp_slot *slot)
}
}
+ pci_bus_size_bridges(bus);
pci_bus_assign_resources(bus);
+ acpiphp_sanitize_bus(bus);
+ pci_enable_bridges(bus);
pci_bus_add_devices(bus);
+ acpiphp_set_hpp_values(DEVICE_ACPI_HANDLE(&bus->self->dev), bus);
+ acpiphp_configure_ioapics(DEVICE_ACPI_HANDLE(&bus->self->dev));
/* associate pci_dev to our representation */
list_for_each (l, &slot->funcs) {
diff --git a/drivers/pci/hotplug/cpcihp_generic.c b/drivers/pci/hotplug/cpcihp_generic.c
index a62a4345b466..2d4639d6841f 100644
--- a/drivers/pci/hotplug/cpcihp_generic.c
+++ b/drivers/pci/hotplug/cpcihp_generic.c
@@ -39,6 +39,7 @@
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/pci.h>
+#include <linux/string.h>
#include "cpci_hotplug.h"
#define DRIVER_VERSION "0.1"
diff --git a/drivers/pci/hotplug/cpcihp_zt5550.c b/drivers/pci/hotplug/cpcihp_zt5550.c
index e9928024be78..f7cb00da38df 100644
--- a/drivers/pci/hotplug/cpcihp_zt5550.c
+++ b/drivers/pci/hotplug/cpcihp_zt5550.c
@@ -36,6 +36,7 @@
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/pci.h>
+#include <linux/signal.h> /* SA_SHIRQ */
#include "cpci_hotplug.h"
#include "cpcihp_zt5550.h"
@@ -78,11 +79,20 @@ static void __iomem *csr_int_mask;
static int zt5550_hc_config(struct pci_dev *pdev)
{
+ int ret;
+
/* Since we know that no boards exist with two HC chips, treat it as an error */
if(hc_dev) {
err("too many host controller devices?");
return -EBUSY;
}
+
+ ret = pci_enable_device(pdev);
+ if(ret) {
+ err("cannot enable %s\n", pci_name(pdev));
+ return ret;
+ }
+
hc_dev = pdev;
dbg("hc_dev = %p", hc_dev);
dbg("pci resource start %lx", pci_resource_start(hc_dev, 1));
@@ -91,7 +101,8 @@ static int zt5550_hc_config(struct pci_dev *pdev)
if(!request_mem_region(pci_resource_start(hc_dev, 1),
pci_resource_len(hc_dev, 1), MY_NAME)) {
err("cannot reserve MMIO region");
- return -ENOMEM;
+ ret = -ENOMEM;
+ goto exit_disable_device;
}
hc_registers =
@@ -99,9 +110,8 @@ static int zt5550_hc_config(struct pci_dev *pdev)
if(!hc_registers) {
err("cannot remap MMIO region %lx @ %lx",
pci_resource_len(hc_dev, 1), pci_resource_start(hc_dev, 1));
- release_mem_region(pci_resource_start(hc_dev, 1),
- pci_resource_len(hc_dev, 1));
- return -ENODEV;
+ ret = -ENODEV;
+ goto exit_release_region;
}
csr_hc_index = hc_registers + CSR_HCINDEX;
@@ -124,6 +134,13 @@ static int zt5550_hc_config(struct pci_dev *pdev)
writeb((u8) ALL_DIRECT_INTS_MASK, csr_int_mask);
dbg("disabled timer0, timer1 and ENUM interrupts");
return 0;
+
+exit_release_region:
+ release_mem_region(pci_resource_start(hc_dev, 1),
+ pci_resource_len(hc_dev, 1));
+exit_disable_device:
+ pci_disable_device(hc_dev);
+ return ret;
}
static int zt5550_hc_cleanup(void)
@@ -134,6 +151,7 @@ static int zt5550_hc_cleanup(void)
iounmap(hc_registers);
release_mem_region(pci_resource_start(hc_dev, 1),
pci_resource_len(hc_dev, 1));
+ pci_disable_device(hc_dev);
return 0;
}
diff --git a/drivers/pci/hotplug/cpqphp_core.c b/drivers/pci/hotplug/cpqphp_core.c
index 8c6d3987d461..9aed8efe6a11 100644
--- a/drivers/pci/hotplug/cpqphp_core.c
+++ b/drivers/pci/hotplug/cpqphp_core.c
@@ -794,12 +794,21 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
u32 rc;
struct controller *ctrl;
struct pci_func *func;
+ int err;
+
+ err = pci_enable_device(pdev);
+ if (err) {
+ printk(KERN_ERR MY_NAME ": cannot enable PCI device %s (%d)\n",
+ pci_name(pdev), err);
+ return err;
+ }
// 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);
- return -ENODEV;
+ rc = -ENODEV;
+ goto err_disable_device;
}
dbg("Vendor ID: %x\n", vendor_id);
@@ -807,7 +816,8 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
dbg("revision: %d\n", rev);
if (rc || ((vendor_id == PCI_VENDOR_ID_COMPAQ) && (!rev))) {
err(msg_HPC_rev_error);
- return -ENODEV;
+ rc = -ENODEV;
+ goto err_disable_device;
}
/* Check for the proper subsytem ID's
@@ -820,18 +830,20 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
rc = pci_read_config_word(pdev, PCI_SUBSYSTEM_VENDOR_ID, &subsystem_vid);
if (rc) {
err("%s : pci_read_config_word failed\n", __FUNCTION__);
- return rc;
+ 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);
- return -ENODEV;
+ rc = -ENODEV;
+ goto err_disable_device;
}
ctrl = (struct controller *) kmalloc(sizeof(struct controller), GFP_KERNEL);
if (!ctrl) {
err("%s : out of memory\n", __FUNCTION__);
- return -ENOMEM;
+ rc = -ENOMEM;
+ goto err_disable_device;
}
memset(ctrl, 0, sizeof(struct controller));
@@ -1264,6 +1276,8 @@ err_free_bus:
kfree(ctrl->pci_bus);
err_free_ctrl:
kfree(ctrl);
+err_disable_device:
+ pci_disable_device(pdev);
return rc;
}
diff --git a/drivers/pci/hotplug/cpqphp_pci.c b/drivers/pci/hotplug/cpqphp_pci.c
index 93e39c4096a9..00b81a7bdd26 100644
--- a/drivers/pci/hotplug/cpqphp_pci.c
+++ b/drivers/pci/hotplug/cpqphp_pci.c
@@ -259,8 +259,7 @@ static int PCI_GetBusDevHelper(struct controller *ctrl, u8 *bus_num, u8 *dev_num
sizeof(struct irq_routing_table)) / sizeof(struct irq_info);
// Make sure I got at least one entry
if (len == 0) {
- if (PCIIRQRoutingInfoLength != NULL)
- kfree(PCIIRQRoutingInfoLength );
+ kfree(PCIIRQRoutingInfoLength );
return -1;
}
@@ -275,8 +274,7 @@ static int PCI_GetBusDevHelper(struct controller *ctrl, u8 *bus_num, u8 *dev_num
ctrl->pci_bus->number = tbus;
pci_bus_read_config_dword (ctrl->pci_bus, *dev_num, PCI_VENDOR_ID, &work);
if (!nobridge || (work == 0xffffffff)) {
- if (PCIIRQRoutingInfoLength != NULL)
- kfree(PCIIRQRoutingInfoLength );
+ kfree(PCIIRQRoutingInfoLength );
return 0;
}
@@ -289,20 +287,17 @@ 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;
- if (PCIIRQRoutingInfoLength != NULL)
- kfree(PCIIRQRoutingInfoLength );
+ kfree(PCIIRQRoutingInfoLength );
return 0;
}
} else {
- if (PCIIRQRoutingInfoLength != NULL)
- kfree(PCIIRQRoutingInfoLength );
+ kfree(PCIIRQRoutingInfoLength );
return 0;
}
}
}
- if (PCIIRQRoutingInfoLength != NULL)
- kfree(PCIIRQRoutingInfoLength );
+ kfree(PCIIRQRoutingInfoLength );
return -1;
}
diff --git a/drivers/pci/hotplug/fakephp.c b/drivers/pci/hotplug/fakephp.c
index 8e47fa66e25e..060d74775d7b 100644
--- a/drivers/pci/hotplug/fakephp.c
+++ b/drivers/pci/hotplug/fakephp.c
@@ -37,6 +37,8 @@
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/init.h>
+#include <linux/string.h>
+#include <linux/slab.h>
#include "pci_hotplug.h"
#include "../pci.h"
diff --git a/drivers/pci/hotplug/ibmphp_core.c b/drivers/pci/hotplug/ibmphp_core.c
index 0392e004258f..aabf1e70b528 100644
--- a/drivers/pci/hotplug/ibmphp_core.c
+++ b/drivers/pci/hotplug/ibmphp_core.c
@@ -1077,7 +1077,7 @@ static int enable_slot(struct hotplug_slot *hs)
if (rc) {
err("Adding this card exceeds the limitations of this bus.\n");
err("(i.e., >1 133MHz cards running on same bus, or "
- ">2 66 PCI cards running on same bus\n.");
+ ">2 66 PCI cards running on same bus.\n");
err("Try hot-adding into another bus\n");
rc = -EINVAL;
goto error_nopower;
diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h
index 061ead21ef14..c42b68d3aa24 100644
--- a/drivers/pci/hotplug/pciehp.h
+++ b/drivers/pci/hotplug/pciehp.h
@@ -32,8 +32,6 @@
#include <linux/types.h>
#include <linux/pci.h>
#include <linux/delay.h>
-#include <asm/semaphore.h>
-#include <asm/io.h>
#include <linux/pcieport_if.h>
#include "pci_hotplug.h"
@@ -42,6 +40,7 @@
extern int pciehp_poll_mode;
extern int pciehp_poll_time;
extern int pciehp_debug;
+extern int pciehp_force;
/*#define dbg(format, arg...) do { if (pciehp_debug) printk(KERN_DEBUG "%s: " format, MY_NAME , ## arg); } while (0)*/
#define dbg(format, arg...) do { if (pciehp_debug) printk("%s: " format, MY_NAME , ## arg); } while (0)
@@ -49,39 +48,20 @@ extern int pciehp_debug;
#define info(format, arg...) printk(KERN_INFO "%s: " format, MY_NAME , ## arg)
#define warn(format, arg...) printk(KERN_WARNING "%s: " format, MY_NAME , ## arg)
-struct pci_func {
- struct pci_func *next;
- u8 bus;
- u8 device;
- u8 function;
- u8 is_a_board;
- u16 status;
- u8 configured;
- u8 switch_save;
- u8 presence_save;
- u32 base_length[0x06];
- u8 base_type[0x06];
- u16 reserved2;
- u32 config_space[0x20];
- struct pci_resource *mem_head;
- struct pci_resource *p_mem_head;
- struct pci_resource *io_head;
- struct pci_resource *bus_head;
- struct pci_dev* pci_dev;
+struct hotplug_params {
+ u8 cache_line_size;
+ u8 latency_timer;
+ u8 enable_serr;
+ u8 enable_perr;
};
struct slot {
struct slot *next;
u8 bus;
u8 device;
+ u16 status;
u32 number;
- u8 is_a_board;
- u8 configured;
u8 state;
- u8 switch_save;
- u8 presence_save;
- u32 capabilities;
- u16 reserved2;
struct timer_list task_event;
u8 hp_slot;
struct controller *ctrl;
@@ -90,42 +70,47 @@ struct slot {
struct list_head slot_list;
};
-struct pci_resource {
- struct pci_resource * next;
- u32 base;
- u32 length;
-};
-
struct event_info {
u32 event_type;
u8 hp_slot;
};
+typedef u8(*php_intr_callback_t) (u8 hp_slot, void *instance_id);
+
+struct php_ctlr_state_s {
+ struct php_ctlr_state_s *pnext;
+ struct pci_dev *pci_dev;
+ unsigned int irq;
+ unsigned long flags; /* spinlock's */
+ u32 slot_device_offset;
+ u32 num_slots;
+ struct timer_list int_poll_timer; /* Added for poll event */
+ php_intr_callback_t attention_button_callback;
+ php_intr_callback_t switch_change_callback;
+ php_intr_callback_t presence_change_callback;
+ php_intr_callback_t power_fault_callback;
+ void *callback_instance_id;
+ struct ctrl_reg *creg; /* Ptr to controller register space */
+};
+
+#define MAX_EVENTS 10
struct controller {
struct controller *next;
struct semaphore crit_sect; /* critical section semaphore */
- void *hpc_ctlr_handle; /* HPC controller handle */
+ struct php_ctlr_state_s *hpc_ctlr_handle; /* HPC controller handle */
int num_slots; /* Number of slots on ctlr */
int slot_num_inc; /* 1 or -1 */
- struct pci_resource *mem_head;
- struct pci_resource *p_mem_head;
- struct pci_resource *io_head;
- struct pci_resource *bus_head;
struct pci_dev *pci_dev;
struct pci_bus *pci_bus;
- struct event_info event_queue[10];
+ struct event_info event_queue[MAX_EVENTS];
struct slot *slot;
struct hpc_ops *hpc_ops;
wait_queue_head_t queue; /* sleep & wake process */
u8 next_event;
- u8 seg;
u8 bus;
u8 device;
u8 function;
- u8 rev;
u8 slot_device_offset;
- u8 add_support;
- enum pci_bus_speed speed;
u32 first_slot; /* First physical slot number */ /* PCIE only has 1 slot */
u8 slot_bus; /* Bus where the slots handled by this controller sit */
u8 ctrlcap;
@@ -133,20 +118,6 @@ struct controller {
u8 cap_base;
};
-struct irq_mapping {
- u8 barber_pole;
- u8 valid_INT;
- u8 interrupt[4];
-};
-
-struct resource_lists {
- struct pci_resource *mem_head;
- struct pci_resource *p_mem_head;
- struct pci_resource *io_head;
- struct pci_resource *bus_head;
- struct irq_mapping *irqs;
-};
-
#define INT_BUTTON_IGNORE 0
#define INT_PRESENCE_ON 1
#define INT_PRESENCE_OFF 2
@@ -200,21 +171,14 @@ struct resource_lists {
* error Messages
*/
#define msg_initialization_err "Initialization failure, error=%d\n"
-#define msg_HPC_rev_error "Unsupported revision of the PCI hot plug controller found.\n"
-#define msg_HPC_non_pcie "The PCI hot plug controller is not supported by this driver.\n"
-#define msg_HPC_not_supported "This system is not supported by this version of pciephd module. Upgrade to a newer version of pciehpd\n"
-#define msg_unable_to_save "Unable to store PCI hot plug add resource information. This system must be rebooted before adding any PCI devices.\n"
#define msg_button_on "PCI slot #%d - powering on due to button press.\n"
#define msg_button_off "PCI slot #%d - powering off due to button press.\n"
#define msg_button_cancel "PCI slot #%d - action canceled due to button press.\n"
#define msg_button_ignore "PCI slot #%d - button press ignored. (action in progress...)\n"
/* controller functions */
-extern int pciehprm_find_available_resources (struct controller *ctrl);
extern int pciehp_event_start_thread (void);
extern void pciehp_event_stop_thread (void);
-extern struct pci_func *pciehp_slot_create (unsigned char busnumber);
-extern struct pci_func *pciehp_slot_find (unsigned char bus, unsigned char device, unsigned char index);
extern int pciehp_enable_slot (struct slot *slot);
extern int pciehp_disable_slot (struct slot *slot);
@@ -224,25 +188,17 @@ extern u8 pciehp_handle_presence_change (u8 hp_slot, void *inst_id);
extern u8 pciehp_handle_power_fault (u8 hp_slot, void *inst_id);
/* extern void long_delay (int delay); */
-/* resource functions */
-extern int pciehp_resource_sort_and_combine (struct pci_resource **head);
-
/* pci functions */
-extern int pciehp_set_irq (u8 bus_num, u8 dev_num, u8 int_pin, u8 irq_num);
-/*extern int pciehp_get_bus_dev (struct controller *ctrl, u8 *bus_num, u8 *dev_num, struct slot *slot);*/
-extern int pciehp_save_config (struct controller *ctrl, int busnumber, int num_ctlr_slots, int first_device_num);
-extern int pciehp_save_used_resources (struct controller *ctrl, struct pci_func * func, int flag);
-extern int pciehp_save_slot_config (struct controller *ctrl, struct pci_func * new_slot);
-extern void pciehp_destroy_board_resources (struct pci_func * func);
-extern int pciehp_return_board_resources (struct pci_func * func, struct resource_lists * resources);
-extern void pciehp_destroy_resource_list (struct resource_lists * resources);
-extern int pciehp_configure_device (struct controller* ctrl, struct pci_func* func);
-extern int pciehp_unconfigure_device (struct pci_func* func);
+extern int pciehp_configure_device (struct slot *p_slot);
+extern int pciehp_unconfigure_device (struct slot *p_slot);
+extern int pciehp_get_hp_hw_control_from_firmware(struct pci_dev *dev);
+extern void pciehp_get_hp_params_from_firmware(struct pci_dev *dev,
+ struct hotplug_params *hpp);
+
/* Global variables */
extern struct controller *pciehp_ctrl_list;
-extern struct pci_func *pciehp_slot_list[256];
/* Inline functions */
@@ -252,12 +208,9 @@ static inline struct slot *pciehp_find_slot(struct controller *ctrl, u8 device)
p_slot = ctrl->slot;
- dbg("p_slot = %p\n", p_slot);
-
while (p_slot && (p_slot->device != device)) {
tmp_slot = p_slot;
p_slot = p_slot->next;
- dbg("In while loop, p_slot = %p\n", p_slot);
}
if (p_slot == NULL) {
err("ERROR: pciehp_find_slot device=0x%x\n", device);
@@ -273,7 +226,6 @@ static inline int wait_for_ctrl_irq(struct controller *ctrl)
DECLARE_WAITQUEUE(wait, current);
- dbg("%s : start\n", __FUNCTION__);
add_wait_queue(&ctrl->queue, &wait);
if (!pciehp_poll_mode)
/* Sleep for up to 1 second */
@@ -285,19 +237,9 @@ static inline int wait_for_ctrl_irq(struct controller *ctrl)
if (signal_pending(current))
retval = -EINTR;
- dbg("%s : end\n", __FUNCTION__);
return retval;
}
-/* Puts node back in the resource list pointed to by head */
-static inline void return_resource(struct pci_resource **head, struct pci_resource *node)
-{
- if (!node || !head)
- return;
- node->next = *head;
- *head = node;
-}
-
#define SLOT_NAME_SIZE 10
static inline void make_slot_name(char *buffer, int buffer_size, struct slot *slot)
@@ -311,14 +253,7 @@ enum php_ctlr_type {
ACPI
};
-typedef u8(*php_intr_callback_t) (unsigned int change_id, void *instance_id);
-
-int pcie_init(struct controller *ctrl, struct pcie_device *dev,
- php_intr_callback_t attention_button_callback,
- php_intr_callback_t switch_change_callback,
- php_intr_callback_t presence_change_callback,
- php_intr_callback_t power_fault_callback);
-
+int pcie_init(struct controller *ctrl, struct pcie_device *dev);
/* This has no meaning for PCI Express, as there is only 1 slot per port */
int pcie_get_ctlr_slot_config(struct controller *ctrl,
diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c
index cafc7eadcf80..8df704860348 100644
--- a/drivers/pci/hotplug/pciehp_core.c
+++ b/drivers/pci/hotplug/pciehp_core.c
@@ -27,27 +27,20 @@
*
*/
-#include <linux/config.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/kernel.h>
#include <linux/types.h>
-#include <linux/proc_fs.h>
-#include <linux/slab.h>
-#include <linux/workqueue.h>
#include <linux/pci.h>
-#include <linux/init.h>
-#include <asm/uaccess.h>
#include "pciehp.h"
-#include "pciehprm.h"
#include <linux/interrupt.h>
/* Global variables */
int pciehp_debug;
int pciehp_poll_mode;
int pciehp_poll_time;
+int pciehp_force;
struct controller *pciehp_ctrl_list;
-struct pci_func *pciehp_slot_list[256];
#define DRIVER_VERSION "0.4"
#define DRIVER_AUTHOR "Dan Zink <dan.zink@compaq.com>, Greg Kroah-Hartman <greg@kroah.com>, Dely Sy <dely.l.sy@intel.com>"
@@ -60,9 +53,11 @@ MODULE_LICENSE("GPL");
module_param(pciehp_debug, bool, 0644);
module_param(pciehp_poll_mode, bool, 0644);
module_param(pciehp_poll_time, int, 0644);
+module_param(pciehp_force, bool, 0644);
MODULE_PARM_DESC(pciehp_debug, "Debugging mode enabled or not");
MODULE_PARM_DESC(pciehp_poll_mode, "Using polling mechanism for hot-plug events or not");
MODULE_PARM_DESC(pciehp_poll_time, "Polling mechanism frequency, in seconds");
+MODULE_PARM_DESC(pciehp_force, "Force pciehp, even if _OSC and OSHP are missing");
#define PCIE_MODULE_NAME "pciehp"
@@ -114,8 +109,6 @@ static int init_slots(struct controller *ctrl)
u32 slot_number;
int result = -ENOMEM;
- dbg("%s\n",__FUNCTION__);
-
number_of_slots = ctrl->num_slots;
slot_device = ctrl->slot_device_offset;
slot_number = ctrl->first_slot;
@@ -370,7 +363,6 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_
u8 value;
struct pci_dev *pdev;
- dbg("%s: Called by hp_drv\n", __FUNCTION__);
ctrl = kmalloc(sizeof(*ctrl), GFP_KERNEL);
if (!ctrl) {
err("%s : out of memory\n", __FUNCTION__);
@@ -378,22 +370,15 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_
}
memset(ctrl, 0, sizeof(struct controller));
- dbg("%s: DRV_thread pid = %d\n", __FUNCTION__, current->pid);
-
pdev = dev->port;
+ ctrl->pci_dev = pdev;
- rc = pcie_init(ctrl, dev,
- (php_intr_callback_t) pciehp_handle_attention_button,
- (php_intr_callback_t) pciehp_handle_switch_change,
- (php_intr_callback_t) pciehp_handle_presence_change,
- (php_intr_callback_t) pciehp_handle_power_fault);
+ rc = pcie_init(ctrl, dev);
if (rc) {
dbg("%s: controller initialization failed\n", PCIE_MODULE_NAME);
goto err_out_free_ctrl;
}
- ctrl->pci_dev = pdev;
-
pci_set_drvdata(pdev, ctrl);
ctrl->pci_bus = kmalloc(sizeof(*ctrl->pci_bus), GFP_KERNEL);
@@ -402,7 +387,6 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_
rc = -ENOMEM;
goto err_out_unmap_mmio_region;
}
- dbg("%s: ctrl->pci_bus %p\n", __FUNCTION__, ctrl->pci_bus);
memcpy (ctrl->pci_bus, pdev->bus, sizeof (*ctrl->pci_bus));
ctrl->bus = pdev->bus->number; /* ctrl bus */
ctrl->slot_bus = pdev->subordinate->number; /* bus controlled by this HPC */
@@ -424,25 +408,6 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_
first_device_num = ctrl->slot_device_offset;
num_ctlr_slots = ctrl->num_slots;
- /* Store PCI Config Space for all devices on this bus */
- dbg("%s: Before calling pciehp_save_config, ctrl->bus %x,ctrl->slot_bus %x\n",
- __FUNCTION__,ctrl->bus, ctrl->slot_bus);
- rc = pciehp_save_config(ctrl, ctrl->slot_bus, num_ctlr_slots, first_device_num);
- if (rc) {
- err("%s: unable to save PCI configuration data, error %d\n", __FUNCTION__, rc);
- goto err_out_free_ctrl_bus;
- }
-
- /* Get IO, memory, and IRQ resources for new devices */
- rc = pciehprm_find_available_resources(ctrl);
- ctrl->add_support = !rc;
-
- if (rc) {
- dbg("pciehprm_find_available_resources = %#x\n", rc);
- err("unable to locate PCI configuration resources for hot plug add.\n");
- goto err_out_free_ctrl_bus;
- }
-
/* Setup the slot information structures */
rc = init_slots(ctrl);
if (rc) {
@@ -451,7 +416,6 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_
}
t_slot = pciehp_find_slot(ctrl, first_device_num);
- dbg("%s: t_slot %p\n", __FUNCTION__, t_slot);
/* Finish setting up the hot plug ctrl device */
ctrl->next_event = 0;
@@ -468,7 +432,6 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_
down(&ctrl->crit_sect);
t_slot->hpc_ops->get_adapter_status(t_slot, &value); /* Check if slot is occupied */
- dbg("%s: adpater value %x\n", __FUNCTION__, value);
if ((POWER_CTRL(ctrl->ctrlcap)) && !value) {
rc = t_slot->hpc_ops->power_off_slot(t_slot); /* Power off slot if not occupied*/
@@ -501,7 +464,6 @@ err_out_none:
static int pcie_start_thread(void)
{
- int loop;
int retval = 0;
dbg("Initialize + Start the notification/polling mechanism \n");
@@ -512,32 +474,11 @@ static int pcie_start_thread(void)
return retval;
}
- dbg("Initialize slot lists\n");
- /* One slot list for each bus in the system */
- for (loop = 0; loop < 256; loop++) {
- pciehp_slot_list[loop] = NULL;
- }
-
return retval;
}
-static inline void __exit
-free_pciehp_res(struct pci_resource *res)
-{
- struct pci_resource *tres;
-
- while (res) {
- tres = res;
- res = res->next;
- kfree(tres);
- }
-}
-
static void __exit unload_pciehpd(void)
{
- struct pci_func *next;
- struct pci_func *TempSlot;
- int loop;
struct controller *ctrl;
struct controller *tctrl;
@@ -546,11 +487,6 @@ static void __exit unload_pciehpd(void)
while (ctrl) {
cleanup_slots(ctrl);
- free_pciehp_res(ctrl->io_head);
- free_pciehp_res(ctrl->mem_head);
- free_pciehp_res(ctrl->p_mem_head);
- free_pciehp_res(ctrl->bus_head);
-
kfree (ctrl->pci_bus);
ctrl->hpc_ops->release_ctlr(ctrl);
@@ -561,20 +497,6 @@ static void __exit unload_pciehpd(void)
kfree(tctrl);
}
- for (loop = 0; loop < 256; loop++) {
- next = pciehp_slot_list[loop];
- while (next != NULL) {
- free_pciehp_res(next->io_head);
- free_pciehp_res(next->mem_head);
- free_pciehp_res(next->p_mem_head);
- free_pciehp_res(next->bus_head);
-
- TempSlot = next;
- next = next->next;
- kfree(TempSlot);
- }
- }
-
/* Stop the notification mechanism */
pciehp_event_stop_thread();
@@ -639,21 +561,16 @@ static int __init pcied_init(void)
if (retval)
goto error_hpc_init;
- retval = pciehprm_init(PCI);
- if (!retval) {
- retval = pcie_port_service_register(&hpdriver_portdrv);
- dbg("pcie_port_service_register = %d\n", retval);
- info(DRIVER_DESC " version: " DRIVER_VERSION "\n");
- if (retval)
- dbg("%s: Failure to register service\n", __FUNCTION__);
- }
+ retval = pcie_port_service_register(&hpdriver_portdrv);
+ dbg("pcie_port_service_register = %d\n", retval);
+ info(DRIVER_DESC " version: " DRIVER_VERSION "\n");
+ if (retval)
+ dbg("%s: Failure to register service\n", __FUNCTION__);
error_hpc_init:
if (retval) {
- pciehprm_cleanup();
pciehp_event_stop_thread();
- } else
- pciehprm_print_pirt();
+ };
return retval;
}
@@ -663,9 +580,6 @@ static void __exit pcied_cleanup(void)
dbg("unload_pciehpd()\n");
unload_pciehpd();
- pciehprm_cleanup();
-
- dbg("pcie_port_service_unregister\n");
pcie_port_service_unregister(&hpdriver_portdrv);
info(DRIVER_DESC " version: " DRIVER_VERSION " unloaded\n");
diff --git a/drivers/pci/hotplug/pciehp_ctrl.c b/drivers/pci/hotplug/pciehp_ctrl.c
index 898f6da6f0de..5e582eca21d8 100644
--- a/drivers/pci/hotplug/pciehp_ctrl.c
+++ b/drivers/pci/hotplug/pciehp_ctrl.c
@@ -27,25 +27,14 @@
*
*/
-#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/types.h>
-#include <linux/slab.h>
-#include <linux/workqueue.h>
-#include <linux/interrupt.h>
-#include <linux/delay.h>
-#include <linux/wait.h>
#include <linux/smp_lock.h>
#include <linux/pci.h>
#include "../pci.h"
#include "pciehp.h"
-#include "pciehprm.h"
-static u32 configure_new_device(struct controller *ctrl, struct pci_func *func,
- u8 behind_bridge, struct resource_lists *resources, u8 bridge_bus, u8 bridge_dev);
-static int configure_new_function( struct controller *ctrl, struct pci_func *func,
- u8 behind_bridge, struct resource_lists *resources, u8 bridge_bus, u8 bridge_dev);
static void interrupt_event_handler(struct controller *ctrl);
static struct semaphore event_semaphore; /* mutex for process loop (up if something to process) */
@@ -60,22 +49,18 @@ u8 pciehp_handle_attention_button(u8 hp_slot, void *inst_id)
struct slot *p_slot;
u8 rc = 0;
u8 getstatus;
- struct pci_func *func;
struct event_info *taskInfo;
/* Attention Button Change */
dbg("pciehp: Attention button interrupt received.\n");
- func = pciehp_slot_find(ctrl->slot_bus, (hp_slot + ctrl->slot_device_offset), 0);
-
/* This is the structure that tells the worker thread what to do */
taskInfo = &(ctrl->event_queue[ctrl->next_event]);
p_slot = pciehp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset);
- p_slot->hpc_ops->get_adapter_status(p_slot, &(func->presence_save));
p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
- ctrl->next_event = (ctrl->next_event + 1) % 10;
+ ctrl->next_event = (ctrl->next_event + 1) % MAX_EVENTS;
taskInfo->hp_slot = hp_slot;
rc++;
@@ -117,24 +102,20 @@ u8 pciehp_handle_switch_change(u8 hp_slot, void *inst_id)
struct slot *p_slot;
u8 rc = 0;
u8 getstatus;
- struct pci_func *func;
struct event_info *taskInfo;
/* Switch Change */
dbg("pciehp: Switch interrupt received.\n");
- func = pciehp_slot_find(ctrl->slot_bus, (hp_slot + ctrl->slot_device_offset), 0);
-
/* This is the structure that tells the worker thread
* what to do
*/
taskInfo = &(ctrl->event_queue[ctrl->next_event]);
- ctrl->next_event = (ctrl->next_event + 1) % 10;
+ ctrl->next_event = (ctrl->next_event + 1) % MAX_EVENTS;
taskInfo->hp_slot = hp_slot;
rc++;
p_slot = pciehp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset);
- p_slot->hpc_ops->get_adapter_status(p_slot, &(func->presence_save));
p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
if (getstatus) {
@@ -142,14 +123,12 @@ u8 pciehp_handle_switch_change(u8 hp_slot, void *inst_id)
* Switch opened
*/
info("Latch open on Slot(%d)\n", ctrl->first_slot + hp_slot);
- func->switch_save = 0;
taskInfo->event_type = INT_SWITCH_OPEN;
} else {
/*
* Switch closed
*/
info("Latch close on Slot(%d)\n", ctrl->first_slot + hp_slot);
- func->switch_save = 0x10;
taskInfo->event_type = INT_SWITCH_CLOSE;
}
@@ -163,20 +142,17 @@ u8 pciehp_handle_presence_change(u8 hp_slot, void *inst_id)
{
struct controller *ctrl = (struct controller *) inst_id;
struct slot *p_slot;
- u8 rc = 0;
- struct pci_func *func;
+ u8 presence_save, rc = 0;
struct event_info *taskInfo;
/* Presence Change */
dbg("pciehp: Presence/Notify input change.\n");
- func = pciehp_slot_find(ctrl->slot_bus, (hp_slot + ctrl->slot_device_offset), 0);
-
/* This is the structure that tells the worker thread
* what to do
*/
taskInfo = &(ctrl->event_queue[ctrl->next_event]);
- ctrl->next_event = (ctrl->next_event + 1) % 10;
+ ctrl->next_event = (ctrl->next_event + 1) % MAX_EVENTS;
taskInfo->hp_slot = hp_slot;
rc++;
@@ -185,8 +161,8 @@ u8 pciehp_handle_presence_change(u8 hp_slot, void *inst_id)
/* Switch is open, assume a presence change
* Save the presence state
*/
- p_slot->hpc_ops->get_adapter_status(p_slot, &(func->presence_save));
- if (func->presence_save) {
+ p_slot->hpc_ops->get_adapter_status(p_slot, &presence_save);
+ if (presence_save) {
/*
* Card Present
*/
@@ -211,19 +187,16 @@ u8 pciehp_handle_power_fault(u8 hp_slot, void *inst_id)
struct controller *ctrl = (struct controller *) inst_id;
struct slot *p_slot;
u8 rc = 0;
- struct pci_func *func;
struct event_info *taskInfo;
/* power fault */
dbg("pciehp: Power fault interrupt received.\n");
- func = pciehp_slot_find(ctrl->slot_bus, (hp_slot + ctrl->slot_device_offset), 0);
-
/* this is the structure that tells the worker thread
* what to do
*/
taskInfo = &(ctrl->event_queue[ctrl->next_event]);
- ctrl->next_event = (ctrl->next_event + 1) % 10;
+ ctrl->next_event = (ctrl->next_event + 1) % MAX_EVENTS;
taskInfo->hp_slot = hp_slot;
rc++;
@@ -234,7 +207,7 @@ u8 pciehp_handle_power_fault(u8 hp_slot, void *inst_id)
* power fault Cleared
*/
info("Power fault cleared on Slot(%d)\n", ctrl->first_slot + hp_slot);
- func->status = 0x00;
+ p_slot->status = 0x00;
taskInfo->event_type = INT_POWER_FAULT_CLEAR;
} else {
/*
@@ -243,7 +216,7 @@ u8 pciehp_handle_power_fault(u8 hp_slot, void *inst_id)
info("Power fault on Slot(%d)\n", ctrl->first_slot + hp_slot);
taskInfo->event_type = INT_POWER_FAULT;
/* set power fault status for this board */
- func->status = 0xFF;
+ p_slot->status = 0xFF;
info("power fault bit %x set\n", hp_slot);
}
if (rc)
@@ -252,810 +225,6 @@ u8 pciehp_handle_power_fault(u8 hp_slot, void *inst_id)
return rc;
}
-
-/**
- * sort_by_size: sort nodes by their length, smallest first.
- *
- * @head: list to sort
- */
-static int sort_by_size(struct pci_resource **head)
-{
- struct pci_resource *current_res;
- struct pci_resource *next_res;
- int out_of_order = 1;
-
- if (!(*head))
- return 1;
-
- if (!((*head)->next))
- return 0;
-
- while (out_of_order) {
- out_of_order = 0;
-
- /* Special case for swapping list head */
- if (((*head)->next) &&
- ((*head)->length > (*head)->next->length)) {
- out_of_order++;
- current_res = *head;
- *head = (*head)->next;
- current_res->next = (*head)->next;
- (*head)->next = current_res;
- }
-
- current_res = *head;
-
- while (current_res->next && current_res->next->next) {
- if (current_res->next->length > current_res->next->next->length) {
- out_of_order++;
- next_res = current_res->next;
- current_res->next = current_res->next->next;
- current_res = current_res->next;
- next_res->next = current_res->next;
- current_res->next = next_res;
- } else
- current_res = current_res->next;
- }
- } /* End of out_of_order loop */
-
- return 0;
-}
-
-
-/*
- * sort_by_max_size
- *
- * Sorts nodes on the list by their length.
- * Largest first.
- *
- */
-static int sort_by_max_size(struct pci_resource **head)
-{
- struct pci_resource *current_res;
- struct pci_resource *next_res;
- int out_of_order = 1;
-
- if (!(*head))
- return 1;
-
- if (!((*head)->next))
- return 0;
-
- while (out_of_order) {
- out_of_order = 0;
-
- /* Special case for swapping list head */
- if (((*head)->next) &&
- ((*head)->length < (*head)->next->length)) {
- out_of_order++;
- current_res = *head;
- *head = (*head)->next;
- current_res->next = (*head)->next;
- (*head)->next = current_res;
- }
-
- current_res = *head;
-
- while (current_res->next && current_res->next->next) {
- if (current_res->next->length < current_res->next->next->length) {
- out_of_order++;
- next_res = current_res->next;
- current_res->next = current_res->next->next;
- current_res = current_res->next;
- next_res->next = current_res->next;
- current_res->next = next_res;
- } else
- current_res = current_res->next;
- }
- } /* End of out_of_order loop */
-
- return 0;
-}
-
-
-/**
- * do_pre_bridge_resource_split: return one unused resource node
- * @head: list to scan
- *
- */
-static struct pci_resource *
-do_pre_bridge_resource_split(struct pci_resource **head,
- struct pci_resource **orig_head, u32 alignment)
-{
- struct pci_resource *prevnode = NULL;
- struct pci_resource *node;
- struct pci_resource *split_node;
- u32 rc;
- u32 temp_dword;
- dbg("do_pre_bridge_resource_split\n");
-
- if (!(*head) || !(*orig_head))
- return NULL;
-
- rc = pciehp_resource_sort_and_combine(head);
-
- if (rc)
- return NULL;
-
- if ((*head)->base != (*orig_head)->base)
- return NULL;
-
- if ((*head)->length == (*orig_head)->length)
- return NULL;
-
-
- /* If we got here, there the bridge requires some of the resource, but
- * 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.
- */
- split_node = kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
-
- if (!split_node)
- return NULL;
-
- temp_dword = (node->length | (alignment-1)) + 1 - alignment;
-
- split_node->base = node->base;
- split_node->length = temp_dword;
-
- node->length -= temp_dword;
- node->base += split_node->length;
-
- /* Put it in the list */
- *head = split_node;
- split_node->next = node;
- }
-
- if (node->length < alignment)
- return NULL;
-
- /* Now unlink it */
- if (*head == node) {
- *head = node->next;
- } else {
- prevnode = *head;
- while (prevnode->next != node)
- prevnode = prevnode->next;
-
- prevnode->next = node->next;
- }
- node->next = NULL;
-
- return node;
-}
-
-
-/**
- * do_bridge_resource_split: return one unused resource node
- * @head: list to scan
- *
- */
-static struct pci_resource *
-do_bridge_resource_split(struct pci_resource **head, u32 alignment)
-{
- struct pci_resource *prevnode = NULL;
- struct pci_resource *node;
- u32 rc;
- u32 temp_dword;
-
- if (!(*head))
- return NULL;
-
- rc = pciehp_resource_sort_and_combine(head);
-
- if (rc)
- return NULL;
-
- node = *head;
-
- while (node->next) {
- prevnode = node;
- node = node->next;
- kfree(prevnode);
- }
-
- if (node->length < alignment) {
- kfree(node);
- return NULL;
- }
-
- if (node->base & (alignment - 1)) {
- /* Short circuit if adjusted size is too small */
- temp_dword = (node->base | (alignment-1)) + 1;
- if ((node->length - (temp_dword - node->base)) < alignment) {
- kfree(node);
- return NULL;
- }
-
- node->length -= (temp_dword - node->base);
- node->base = temp_dword;
- }
-
- if (node->length & (alignment - 1)) {
- /* There's stuff in use after this node */
- kfree(node);
- return NULL;
- }
-
- return node;
-}
-
-
-/*
- * get_io_resource
- *
- * this function sorts the resource list by size and then
- * returns the first node of "size" length that is not in the
- * ISA aliasing window. If it finds a node larger than "size"
- * it will split it up.
- *
- * size must be a power of two.
- */
-static struct pci_resource *get_io_resource(struct pci_resource **head, u32 size)
-{
- struct pci_resource *prevnode;
- struct pci_resource *node;
- struct pci_resource *split_node = NULL;
- u32 temp_dword;
-
- if (!(*head))
- return NULL;
-
- if ( pciehp_resource_sort_and_combine(head) )
- return NULL;
-
- if ( sort_by_size(head) )
- return NULL;
-
- for (node = *head; node; node = node->next) {
- if (node->length < size)
- continue;
-
- if (node->base & (size - 1)) {
- /* this one isn't base aligned properly
- 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 */
- if ((node->length - (temp_dword - node->base)) < size)
- continue;
-
- split_node = kmalloc(sizeof(struct pci_resource),
- GFP_KERNEL);
-
- if (!split_node)
- return NULL;
-
- split_node->base = node->base;
- split_node->length = temp_dword - node->base;
- node->base = temp_dword;
- node->length -= split_node->length;
-
- /* Put it in the list */
- split_node->next = node->next;
- node->next = split_node;
- } /* End of non-aligned base */
-
- /* 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 */
- split_node = kmalloc(sizeof(struct pci_resource),
- GFP_KERNEL);
-
- if (!split_node)
- return NULL;
-
- split_node->base = node->base + size;
- split_node->length = node->length - size;
- node->length = size;
-
- /* Put it in the list */
- split_node->next = node->next;
- node->next = split_node;
- } /* End of too big on top end */
-
- /* For IO make sure it's not in the ISA aliasing space */
- if (node->base & 0x300L)
- continue;
-
- /* If we got here, then it is the right size
- Now take it out of the list */
- if (*head == node) {
- *head = node->next;
- } else {
- prevnode = *head;
- while (prevnode->next != node)
- prevnode = prevnode->next;
-
- prevnode->next = node->next;
- }
- node->next = NULL;
- /* Stop looping */
- break;
- }
-
- return node;
-}
-
-
-/*
- * get_max_resource
- *
- * Gets the largest node that is at least "size" big from the
- * list pointed to by head. It aligns the node on top and bottom
- * to "size" alignment before returning it.
- * J.I. modified to put max size limits of; 64M->32M->16M->8M->4M->1M
- * This is needed to avoid allocating entire ACPI _CRS res to one child bridge/slot.
- */
-static struct pci_resource *get_max_resource(struct pci_resource **head, u32 size)
-{
- struct pci_resource *max;
- struct pci_resource *temp;
- struct pci_resource *split_node;
- u32 temp_dword;
- u32 max_size[] = { 0x4000000, 0x2000000, 0x1000000, 0x0800000, 0x0400000, 0x0200000, 0x0100000, 0x00 };
- int i;
-
- if (!(*head))
- return NULL;
-
- if (pciehp_resource_sort_and_combine(head))
- return NULL;
-
- if (sort_by_max_size(head))
- 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 (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 */
- temp_dword = (max->base | (size-1)) + 1;
-
- /* Short circuit if adjusted size is too small */
- if ((max->length - (temp_dword - max->base)) < size)
- continue;
-
- split_node = kmalloc(sizeof(struct pci_resource),
- GFP_KERNEL);
-
- if (!split_node)
- return NULL;
-
- split_node->base = max->base;
- split_node->length = temp_dword - max->base;
- max->base = temp_dword;
- max->length -= split_node->length;
-
- /* Put it next in the list */
- split_node->next = max->next;
- max->next = split_node;
- }
-
- 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 */
- split_node = kmalloc(sizeof(struct pci_resource),
- GFP_KERNEL);
-
- if (!split_node)
- return NULL;
- temp_dword = ((max->base + max->length) & ~(size - 1));
- split_node->base = temp_dword;
- split_node->length = max->length + max->base
- - split_node->base;
- max->length -= split_node->length;
-
- /* Put it in the list */
- split_node->next = max->next;
- max->next = split_node;
- }
-
- /* Make sure it didn't shrink too much when we aligned it */
- if (max->length < size)
- continue;
-
- for ( i = 0; max_size[i] > size; i++) {
- if (max->length > max_size[i]) {
- split_node = kmalloc(sizeof(struct pci_resource),
- GFP_KERNEL);
- if (!split_node)
- break; /* return NULL; */
- split_node->base = max->base + max_size[i];
- split_node->length = max->length - max_size[i];
- max->length = max_size[i];
- /* Put it next in the list */
- split_node->next = max->next;
- max->next = split_node;
- break;
- }
- }
-
- /* Now take it out of the list */
- temp = (struct pci_resource*) *head;
- if (temp == max) {
- *head = max->next;
- } else {
- while (temp && temp->next != max) {
- temp = temp->next;
- }
-
- temp->next = max->next;
- }
-
- max->next = NULL;
- return max;
- }
-
- /* If we get here, we couldn't find one */
- return NULL;
-}
-
-
-/*
- * get_resource
- *
- * this function sorts the resource list by size and then
- * returns the first node of "size" length. If it finds a node
- * larger than "size" it will split it up.
- *
- * size must be a power of two.
- */
-static struct pci_resource *get_resource(struct pci_resource **head, u32 size)
-{
- struct pci_resource *prevnode;
- struct pci_resource *node;
- struct pci_resource *split_node;
- u32 temp_dword;
-
- if (!(*head))
- return NULL;
-
- if ( pciehp_resource_sort_and_combine(head) )
- return NULL;
-
- if ( sort_by_size(head) )
- return NULL;
-
- for (node = *head; node; node = node->next) {
- dbg("%s: req_size =0x%x node=%p, base=0x%x, length=0x%x\n",
- __FUNCTION__, size, node, node->base, node->length);
- if (node->length < size)
- continue;
-
- if (node->base & (size - 1)) {
- dbg("%s: not aligned\n", __FUNCTION__);
- /* this one isn't base aligned properly
- 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 */
- if ((node->length - (temp_dword - node->base)) < size)
- continue;
-
- split_node = kmalloc(sizeof(struct pci_resource),
- GFP_KERNEL);
-
- if (!split_node)
- return NULL;
-
- split_node->base = node->base;
- split_node->length = temp_dword - node->base;
- node->base = temp_dword;
- node->length -= split_node->length;
-
- /* Put it in the list */
- split_node->next = node->next;
- node->next = split_node;
- } /* End of non-aligned base */
-
- /* Don't need to check if too small since we already did */
- if (node->length > size) {
- dbg("%s: too big\n", __FUNCTION__);
- /* this one is longer than we need
- so we'll make a new entry and split it up */
- split_node = kmalloc(sizeof(struct pci_resource),
- GFP_KERNEL);
-
- if (!split_node)
- return NULL;
-
- split_node->base = node->base + size;
- split_node->length = node->length - size;
- node->length = size;
-
- /* Put it in the list */
- split_node->next = node->next;
- node->next = split_node;
- } /* End of too big on top end */
-
- dbg("%s: got one!!!\n", __FUNCTION__);
- /* If we got here, then it is the right size
- Now take it out of the list */
- if (*head == node) {
- *head = node->next;
- } else {
- prevnode = *head;
- while (prevnode->next != node)
- prevnode = prevnode->next;
-
- prevnode->next = node->next;
- }
- node->next = NULL;
- /* Stop looping */
- break;
- }
- return node;
-}
-
-
-/*
- * pciehp_resource_sort_and_combine
- *
- * Sorts all of the nodes in the list in ascending order by
- * their base addresses. Also does garbage collection by
- * combining adjacent nodes.
- *
- * returns 0 if success
- */
-int pciehp_resource_sort_and_combine(struct pci_resource **head)
-{
- struct pci_resource *node1;
- struct pci_resource *node2;
- int out_of_order = 1;
-
- dbg("%s: head = %p, *head = %p\n", __FUNCTION__, head, *head);
-
- if (!(*head))
- return 1;
-
- dbg("*head->next = %p\n",(*head)->next);
-
- if (!(*head)->next)
- return 0; /* only one item on the list, already sorted! */
-
- dbg("*head->base = 0x%x\n",(*head)->base);
- dbg("*head->next->base = 0x%x\n",(*head)->next->base);
- while (out_of_order) {
- out_of_order = 0;
-
- /* Special case for swapping list head */
- if (((*head)->next) &&
- ((*head)->base > (*head)->next->base)) {
- node1 = *head;
- (*head) = (*head)->next;
- node1->next = (*head)->next;
- (*head)->next = node1;
- out_of_order++;
- }
-
- node1 = (*head);
-
- while (node1->next && node1->next->next) {
- if (node1->next->base > node1->next->next->base) {
- out_of_order++;
- node2 = node1->next;
- node1->next = node1->next->next;
- node1 = node1->next;
- node2->next = node1->next;
- node1->next = node2;
- } else
- node1 = node1->next;
- }
- } /* End of out_of_order loop */
-
- node1 = *head;
-
- while (node1 && node1->next) {
- if ((node1->base + node1->length) == node1->next->base) {
- /* Combine */
- dbg("8..\n");
- node1->length += node1->next->length;
- node2 = node1->next;
- node1->next = node1->next->next;
- kfree(node2);
- } else
- node1 = node1->next;
- }
-
- return 0;
-}
-
-
-/**
- * pciehp_slot_create - Creates a node and adds it to the proper bus.
- * @busnumber - bus where new node is to be located
- *
- * Returns pointer to the new node or NULL if unsuccessful
- */
-struct pci_func *pciehp_slot_create(u8 busnumber)
-{
- struct pci_func *new_slot;
- struct pci_func *next;
- dbg("%s: busnumber %x\n", __FUNCTION__, busnumber);
- new_slot = kmalloc(sizeof(struct pci_func), GFP_KERNEL);
-
- if (new_slot == NULL)
- return new_slot;
-
- memset(new_slot, 0, sizeof(struct pci_func));
-
- new_slot->next = NULL;
- new_slot->configured = 1;
-
- if (pciehp_slot_list[busnumber] == NULL) {
- pciehp_slot_list[busnumber] = new_slot;
- } else {
- next = pciehp_slot_list[busnumber];
- while (next->next != NULL)
- next = next->next;
- next->next = new_slot;
- }
- return new_slot;
-}
-
-
-/**
- * slot_remove - Removes a node from the linked list of slots.
- * @old_slot: slot to remove
- *
- * Returns 0 if successful, !0 otherwise.
- */
-static int slot_remove(struct pci_func * old_slot)
-{
- struct pci_func *next;
-
- if (old_slot == NULL)
- return 1;
-
- next = pciehp_slot_list[old_slot->bus];
-
- if (next == NULL)
- return 1;
-
- if (next == old_slot) {
- pciehp_slot_list[old_slot->bus] = old_slot->next;
- pciehp_destroy_board_resources(old_slot);
- kfree(old_slot);
- return 0;
- }
-
- while ((next->next != old_slot) && (next->next != NULL)) {
- next = next->next;
- }
-
- if (next->next == old_slot) {
- next->next = old_slot->next;
- pciehp_destroy_board_resources(old_slot);
- kfree(old_slot);
- return 0;
- } else
- return 2;
-}
-
-
-/**
- * bridge_slot_remove - Removes a node from the linked list of slots.
- * @bridge: bridge to remove
- *
- * Returns 0 if successful, !0 otherwise.
- */
-static int bridge_slot_remove(struct pci_func *bridge)
-{
- u8 subordinateBus, secondaryBus;
- u8 tempBus;
- struct pci_func *next;
-
- if (bridge == NULL)
- return 1;
-
- secondaryBus = (bridge->config_space[0x06] >> 8) & 0xFF;
- subordinateBus = (bridge->config_space[0x06] >> 16) & 0xFF;
-
- for (tempBus = secondaryBus; tempBus <= subordinateBus; tempBus++) {
- next = pciehp_slot_list[tempBus];
-
- while (!slot_remove(next)) {
- next = pciehp_slot_list[tempBus];
- }
- }
-
- next = pciehp_slot_list[bridge->bus];
-
- if (next == NULL) {
- return 1;
- }
-
- if (next == bridge) {
- pciehp_slot_list[bridge->bus] = bridge->next;
- kfree(bridge);
- return 0;
- }
-
- while ((next->next != bridge) && (next->next != NULL)) {
- next = next->next;
- }
-
- if (next->next == bridge) {
- next->next = bridge->next;
- kfree(bridge);
- return 0;
- } else
- return 2;
-}
-
-
-/**
- * pciehp_slot_find - Looks for a node by bus, and device, multiple functions accessed
- * @bus: bus to find
- * @device: device to find
- * @index: is 0 for first function found, 1 for the second...
- *
- * Returns pointer to the node if successful, %NULL otherwise.
- */
-struct pci_func *pciehp_slot_find(u8 bus, u8 device, u8 index)
-{
- int found = -1;
- struct pci_func *func;
-
- func = pciehp_slot_list[bus];
- dbg("%s: bus %x device %x index %x\n",
- __FUNCTION__, bus, device, index);
- if (func != NULL) {
- dbg("%s: func-> bus %x device %x function %x pci_dev %p\n",
- __FUNCTION__, func->bus, func->device, func->function,
- func->pci_dev);
- } else
- dbg("%s: func == NULL\n", __FUNCTION__);
-
- if ((func == NULL) || ((func->device == device) && (index == 0)))
- return func;
-
- if (func->device == device)
- found++;
-
- while (func->next != NULL) {
- func = func->next;
-
- dbg("%s: In while loop, func-> bus %x device %x function %x pci_dev %p\n",
- __FUNCTION__, func->bus, func->device, func->function,
- func->pci_dev);
- if (func->device == device)
- found++;
- dbg("%s: while loop, found %d, index %d\n", __FUNCTION__,
- found, index);
-
- if ((found == index) || (func->function == index)) {
- dbg("%s: Found bus %x dev %x func %x\n", __FUNCTION__,
- func->bus, func->device, func->function);
- return func;
- }
- }
-
- return NULL;
-}
-
-static int is_bridge(struct pci_func * func)
-{
- /* Check the header type */
- if (((func->config_space[0x03] >> 16) & 0xFF) == 0x01)
- return 1;
- else
- return 0;
-}
-
-
/* The following routines constitute the bulk of the
hotplug controller logic
*/
@@ -1100,20 +269,17 @@ static void set_slot_off(struct controller *ctrl, struct slot * pslot)
* Configures board
*
*/
-static u32 board_added(struct pci_func * func, struct controller * ctrl)
+static int board_added(struct slot *p_slot)
{
u8 hp_slot;
- int index;
- u32 temp_register = 0xFFFFFFFF;
- u32 rc = 0;
- struct pci_func *new_func = NULL;
- struct slot *p_slot;
- struct resource_lists res_lists;
+ int rc = 0;
+ struct controller *ctrl = p_slot->ctrl;
- p_slot = pciehp_find_slot(ctrl, func->device);
- hp_slot = func->device - ctrl->slot_device_offset;
+ hp_slot = p_slot->device - ctrl->slot_device_offset;
- dbg("%s: func->device, slot_offset, hp_slot = %d, %d ,%d\n", __FUNCTION__, func->device, ctrl->slot_device_offset, hp_slot);
+ dbg("%s: slot device, slot offset, hp slot = %d, %d ,%d\n",
+ __FUNCTION__, p_slot->device,
+ ctrl->slot_device_offset, hp_slot);
/* Wait for exclusive access to hardware */
down(&ctrl->crit_sect);
@@ -1141,9 +307,7 @@ static u32 board_added(struct pci_func * func, struct controller * ctrl)
up(&ctrl->crit_sect);
/* Wait for ~1 second */
- dbg("%s: before long_delay\n", __FUNCTION__);
wait_for_ctrl_irq (ctrl);
- dbg("%s: afterlong_delay\n", __FUNCTION__);
/* Check link training status */
rc = p_slot->hpc_ops->check_lnk_status(ctrl);
@@ -1153,98 +317,47 @@ static u32 board_added(struct pci_func * func, struct controller * ctrl)
return rc;
}
- dbg("%s: func status = %x\n", __FUNCTION__, func->status);
+ dbg("%s: slot status = %x\n", __FUNCTION__, p_slot->status);
/* Check for a power fault */
- if (func->status == 0xFF) {
+ if (p_slot->status == 0xFF) {
/* power fault occurred, but it was benign */
- temp_register = 0xFFFFFFFF;
- dbg("%s: temp register set to %x by power fault\n", __FUNCTION__, temp_register);
rc = POWER_FAILURE;
- func->status = 0;
- } else {
- /* Get vendor/device ID u32 */
- rc = pci_bus_read_config_dword (ctrl->pci_dev->subordinate, PCI_DEVFN(func->device, func->function),
- PCI_VENDOR_ID, &temp_register);
- dbg("%s: pci_bus_read_config_dword returns %d\n", __FUNCTION__, rc);
- dbg("%s: temp_register is %x\n", __FUNCTION__, temp_register);
-
- if (rc != 0) {
- /* Something's wrong here */
- temp_register = 0xFFFFFFFF;
- dbg("%s: temp register set to %x by error\n", __FUNCTION__, temp_register);
- }
- /* Preset return code. It will be changed later if things go okay. */
- rc = NO_ADAPTER_PRESENT;
+ p_slot->status = 0;
+ goto err_exit;
}
- /* All F's is an empty slot or an invalid board */
- if (temp_register != 0xFFFFFFFF) { /* Check for a board in the slot */
- res_lists.io_head = ctrl->io_head;
- res_lists.mem_head = ctrl->mem_head;
- res_lists.p_mem_head = ctrl->p_mem_head;
- res_lists.bus_head = ctrl->bus_head;
- res_lists.irqs = NULL;
-
- rc = configure_new_device(ctrl, func, 0, &res_lists, 0, 0);
- dbg("%s: back from configure_new_device\n", __FUNCTION__);
-
- ctrl->io_head = res_lists.io_head;
- ctrl->mem_head = res_lists.mem_head;
- ctrl->p_mem_head = res_lists.p_mem_head;
- ctrl->bus_head = res_lists.bus_head;
+ rc = pciehp_configure_device(p_slot);
+ if (rc) {
+ err("Cannot add device 0x%x:%x\n", p_slot->bus,
+ p_slot->device);
+ goto err_exit;
+ }
- pciehp_resource_sort_and_combine(&(ctrl->mem_head));
- pciehp_resource_sort_and_combine(&(ctrl->p_mem_head));
- pciehp_resource_sort_and_combine(&(ctrl->io_head));
- pciehp_resource_sort_and_combine(&(ctrl->bus_head));
+ p_slot->status = 0;
- if (rc) {
- set_slot_off(ctrl, p_slot);
- return rc;
- }
- pciehp_save_slot_config(ctrl, func);
-
- func->status = 0;
- func->switch_save = 0x10;
- func->is_a_board = 0x01;
+ /*
+ * Some PCI Express root ports require fixup after hot-plug operation.
+ */
+ if (pcie_mch_quirk)
+ pci_fixup_device(pci_fixup_final, ctrl->pci_dev);
+ if (PWR_LED(ctrl->ctrlcap)) {
+ /* Wait for exclusive access to hardware */
+ down(&ctrl->crit_sect);
- /* next, we will instantiate the linux pci_dev structures
- * (with appropriate driver notification, if already present)
- */
- index = 0;
- do {
- new_func = pciehp_slot_find(ctrl->slot_bus, func->device, index++);
- if (new_func && !new_func->pci_dev) {
- dbg("%s:call pci_hp_configure_dev, func %x\n",
- __FUNCTION__, index);
- pciehp_configure_device(ctrl, new_func);
- }
- } while (new_func);
-
- /*
- * Some PCI Express root ports require fixup after hot-plug operation.
- */
- if (pcie_mch_quirk)
- pci_fixup_device(pci_fixup_final, ctrl->pci_dev);
-
- if (PWR_LED(ctrl->ctrlcap)) {
- /* Wait for exclusive access to hardware */
- down(&ctrl->crit_sect);
-
- p_slot->hpc_ops->green_led_on(p_slot);
+ p_slot->hpc_ops->green_led_on(p_slot);
- /* Wait for the command to complete */
- wait_for_ctrl_irq (ctrl);
+ /* Wait for the command to complete */
+ wait_for_ctrl_irq (ctrl);
- /* Done with exclusive hardware access */
- up(&ctrl->crit_sect);
- }
- } else {
- set_slot_off(ctrl, p_slot);
- return -1;
- }
+ /* Done with exclusive hardware access */
+ up(&ctrl->crit_sect);
+ }
return 0;
+
+err_exit:
+ set_slot_off(ctrl, p_slot);
+ return -1;
}
@@ -1252,55 +365,25 @@ static u32 board_added(struct pci_func * func, struct controller * ctrl)
* remove_board - Turns off slot and LED's
*
*/
-static u32 remove_board(struct pci_func *func, struct controller *ctrl)
+static int remove_board(struct slot *p_slot)
{
- int index;
- u8 skip = 0;
u8 device;
u8 hp_slot;
- u32 rc;
- struct resource_lists res_lists;
- struct pci_func *temp_func;
- struct slot *p_slot;
-
- if (func == NULL)
- return 1;
+ int rc;
+ struct controller *ctrl = p_slot->ctrl;
- if (pciehp_unconfigure_device(func))
+ if (pciehp_unconfigure_device(p_slot))
return 1;
- device = func->device;
+ device = p_slot->device;
- hp_slot = func->device - ctrl->slot_device_offset;
+ hp_slot = p_slot->device - ctrl->slot_device_offset;
p_slot = pciehp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset);
dbg("In %s, hp_slot = %d\n", __FUNCTION__, hp_slot);
- if ((ctrl->add_support) &&
- !(func->bus_head || func->mem_head || func->p_mem_head || func->io_head)) {
- /* Here we check to see if we've saved any of the board's
- * resources already. If so, we'll skip the attempt to
- * determine what's being used.
- */
- index = 0;
-
- temp_func = func;
-
- while ((temp_func = pciehp_slot_find(temp_func->bus, temp_func->device, index++))) {
- if (temp_func->bus_head || temp_func->mem_head
- || temp_func->p_mem_head || temp_func->io_head) {
- skip = 1;
- break;
- }
- }
-
- if (!skip)
- rc = pciehp_save_used_resources(ctrl, func, DISABLE_CARD);
- }
/* Change status to shutdown */
- if (func->is_a_board)
- func->status = 0x01;
- func->configured = 0;
+ p_slot->status = 0x01;
/* Wait for exclusive access to hardware */
down(&ctrl->crit_sect);
@@ -1328,56 +411,6 @@ static u32 remove_board(struct pci_func *func, struct controller *ctrl)
/* Done with exclusive hardware access */
up(&ctrl->crit_sect);
- if (ctrl->add_support) {
- while (func) {
- res_lists.io_head = ctrl->io_head;
- res_lists.mem_head = ctrl->mem_head;
- res_lists.p_mem_head = ctrl->p_mem_head;
- res_lists.bus_head = ctrl->bus_head;
-
- dbg("Returning resources to ctlr lists for (B/D/F) = (%#x/%#x/%#x)\n",
- func->bus, func->device, func->function);
-
- pciehp_return_board_resources(func, &res_lists);
-
- ctrl->io_head = res_lists.io_head;
- ctrl->mem_head = res_lists.mem_head;
- ctrl->p_mem_head = res_lists.p_mem_head;
- ctrl->bus_head = res_lists.bus_head;
-
- pciehp_resource_sort_and_combine(&(ctrl->mem_head));
- pciehp_resource_sort_and_combine(&(ctrl->p_mem_head));
- pciehp_resource_sort_and_combine(&(ctrl->io_head));
- pciehp_resource_sort_and_combine(&(ctrl->bus_head));
-
- if (is_bridge(func)) {
- dbg("PCI Bridge Hot-Remove s:b:d:f(%02x:%02x:%02x:%02x)\n",
- ctrl->seg, func->bus, func->device, func->function);
- bridge_slot_remove(func);
- } else {
- dbg("PCI Function Hot-Remove s:b:d:f(%02x:%02x:%02x:%02x)\n",
- ctrl->seg, func->bus, func->device, func->function);
- slot_remove(func);
- }
-
- func = pciehp_slot_find(ctrl->slot_bus, device, 0);
- }
-
- /* Setup slot structure with entry for empty slot */
- func = pciehp_slot_create(ctrl->slot_bus);
-
- if (func == NULL) {
- return 1;
- }
-
- func->bus = ctrl->slot_bus;
- func->device = device;
- func->function = 0;
- func->configured = 0;
- func->switch_save = 0x10;
- func->is_a_board = 0;
- }
-
return 0;
}
@@ -1411,13 +444,15 @@ static void pciehp_pushbutton_thread(unsigned long slot)
p_slot->hpc_ops->get_power_status(p_slot, &getstatus);
if (getstatus) {
p_slot->state = POWEROFF_STATE;
- dbg("In power_down_board, b:d(%x:%x)\n", p_slot->bus, p_slot->device);
+ dbg("%s: disabling bus:device(%x:%x)\n", __FUNCTION__,
+ p_slot->bus, p_slot->device);
pciehp_disable_slot(p_slot);
p_slot->state = STATIC_STATE;
} else {
p_slot->state = POWERON_STATE;
- dbg("In add_board, b:d(%x:%x)\n", p_slot->bus, p_slot->device);
+ dbg("%s: adding bus:device(%x:%x)\n", __FUNCTION__,
+ p_slot->bus, p_slot->device);
if (pciehp_enable_slot(p_slot) && PWR_LED(p_slot->ctrl->ctrlcap)) {
/* Wait for exclusive access to hardware */
@@ -1459,13 +494,15 @@ static void pciehp_surprise_rm_thread(unsigned long slot)
p_slot->hpc_ops->get_adapter_status(p_slot, &getstatus);
if (!getstatus) {
p_slot->state = POWEROFF_STATE;
- dbg("In removing board, b:d(%x:%x)\n", p_slot->bus, p_slot->device);
+ dbg("%s: removing bus:device(%x:%x)\n",
+ __FUNCTION__, p_slot->bus, p_slot->device);
pciehp_disable_slot(p_slot);
p_slot->state = STATIC_STATE;
} else {
p_slot->state = POWERON_STATE;
- dbg("In add_board, b:d(%x:%x)\n", p_slot->bus, p_slot->device);
+ dbg("%s: adding bus:device(%x:%x)\n",
+ __FUNCTION__, p_slot->bus, p_slot->device);
if (pciehp_enable_slot(p_slot) && PWR_LED(p_slot->ctrl->ctrlcap)) {
/* Wait for exclusive access to hardware */
@@ -1531,7 +568,6 @@ int pciehp_event_start_thread(void)
err ("Can't start up our event thread\n");
return -1;
}
- dbg("Our event thread pid = %d\n", pid);
return 0;
}
@@ -1539,9 +575,7 @@ int pciehp_event_start_thread(void)
void pciehp_event_stop_thread(void)
{
event_finished = 1;
- dbg("event_thread finish command given\n");
up(&event_semaphore);
- dbg("wait for event_thread to exit\n");
down(&event_exit);
}
@@ -1573,7 +607,6 @@ static void interrupt_event_handler(struct controller *ctrl)
{
int loop = 0;
int change = 1;
- struct pci_func *func;
u8 hp_slot;
u8 getstatus;
struct slot *p_slot;
@@ -1581,16 +614,12 @@ static void interrupt_event_handler(struct controller *ctrl)
while (change) {
change = 0;
- for (loop = 0; loop < 10; loop++) {
+ for (loop = 0; loop < MAX_EVENTS; loop++) {
if (ctrl->event_queue[loop].event_type != 0) {
hp_slot = ctrl->event_queue[loop].hp_slot;
- func = pciehp_slot_find(ctrl->slot_bus, (hp_slot + ctrl->slot_device_offset), 0);
-
p_slot = pciehp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset);
- dbg("hp_slot %d, func %p, p_slot %p\n", hp_slot, func, p_slot);
-
if (ctrl->event_queue[loop].event_type == INT_BUTTON_CANCEL) {
dbg("button cancel\n");
del_timer(&p_slot->task_event);
@@ -1682,7 +711,6 @@ static void interrupt_event_handler(struct controller *ctrl)
p_slot->task_event.function = (void (*)(unsigned long)) pushbutton_helper_thread;
p_slot->task_event.data = (unsigned long) p_slot;
- dbg("add_timer p_slot = %p\n", (void *) p_slot);
add_timer(&p_slot->task_event);
}
}
@@ -1737,13 +765,6 @@ int pciehp_enable_slot(struct slot *p_slot)
{
u8 getstatus = 0;
int rc;
- struct pci_func *func;
-
- func = pciehp_slot_find(p_slot->bus, p_slot->device, 0);
- if (!func) {
- dbg("%s: Error! slot NULL\n", __FUNCTION__);
- return 1;
- }
/* Check to see if (latch closed, card present, power off) */
down(&p_slot->ctrl->crit_sect);
@@ -1773,45 +794,11 @@ int pciehp_enable_slot(struct slot *p_slot)
}
up(&p_slot->ctrl->crit_sect);
- slot_remove(func);
-
- func = pciehp_slot_create(p_slot->bus);
- if (func == NULL)
- return 1;
-
- func->bus = p_slot->bus;
- func->device = p_slot->device;
- func->function = 0;
- func->configured = 0;
- func->is_a_board = 1;
-
- /* We have to save the presence info for these slots */
- p_slot->hpc_ops->get_adapter_status(p_slot, &(func->presence_save));
p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
- func->switch_save = !getstatus? 0x10:0;
- rc = board_added(func, p_slot->ctrl);
+ rc = board_added(p_slot);
if (rc) {
- if (is_bridge(func))
- bridge_slot_remove(func);
- else
- slot_remove(func);
-
- /* Setup slot structure with entry for empty slot */
- func = pciehp_slot_create(p_slot->bus);
- if (func == NULL)
- return 1; /* Out of memory */
-
- func->bus = p_slot->bus;
- func->device = p_slot->device;
- func->function = 0;
- func->configured = 0;
- func->is_a_board = 1;
-
- /* We have to save the presence info for these slots */
- p_slot->hpc_ops->get_adapter_status(p_slot, &(func->presence_save));
p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
- func->switch_save = !getstatus? 0x10:0;
}
if (p_slot)
@@ -1823,14 +810,8 @@ int pciehp_enable_slot(struct slot *p_slot)
int pciehp_disable_slot(struct slot *p_slot)
{
- u8 class_code, header_type, BCR;
- u8 index = 0;
u8 getstatus = 0;
- u32 rc = 0;
int ret = 0;
- unsigned int devfn;
- struct pci_bus *pci_bus = p_slot->ctrl->pci_dev->subordinate;
- struct pci_func *func;
if (!p_slot->ctrl)
return 1;
@@ -1867,838 +848,8 @@ int pciehp_disable_slot(struct slot *p_slot)
up(&p_slot->ctrl->crit_sect);
- func = pciehp_slot_find(p_slot->bus, p_slot->device, index++);
-
- /* Make sure there are no video controllers here
- * for all func of p_slot
- */
- while (func && !rc) {
- pci_bus->number = func->bus;
- devfn = PCI_DEVFN(func->device, func->function);
-
- /* Check the Class Code */
- rc = pci_bus_read_config_byte (pci_bus, devfn, 0x0B, &class_code);
- if (rc)
- return rc;
-
- if (class_code == PCI_BASE_CLASS_DISPLAY) {
- /* Display/Video adapter (not supported) */
- rc = REMOVE_NOT_SUPPORTED;
- } else {
- /* See if it's a bridge */
- rc = pci_bus_read_config_byte (pci_bus, devfn, PCI_HEADER_TYPE, &header_type);
- if (rc)
- return rc;
-
- /* If it's a bridge, check the VGA Enable bit */
- if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) {
- rc = pci_bus_read_config_byte (pci_bus, devfn, PCI_BRIDGE_CONTROL, &BCR);
- if (rc)
- return rc;
-
- /* If the VGA Enable bit is set, remove isn't supported */
- if (BCR & PCI_BRIDGE_CTL_VGA) {
- rc = REMOVE_NOT_SUPPORTED;
- }
- }
- }
-
- func = pciehp_slot_find(p_slot->bus, p_slot->device, index++);
- }
-
- func = pciehp_slot_find(p_slot->bus, p_slot->device, 0);
- if ((func != NULL) && !rc) {
- rc = remove_board(func, p_slot->ctrl);
- } else if (!rc)
- rc = 1;
-
- if (p_slot)
- update_slot_info(p_slot);
-
- return rc;
-}
-
-
-/**
- * configure_new_device - Configures the PCI header information of one board.
- *
- * @ctrl: pointer to controller structure
- * @func: pointer to function structure
- * @behind_bridge: 1 if this is a recursive call, 0 if not
- * @resources: pointer to set of resource lists
- *
- * Returns 0 if success
- *
- */
-static u32 configure_new_device(struct controller * ctrl, struct pci_func * func,
- u8 behind_bridge, struct resource_lists * resources, u8 bridge_bus, u8 bridge_dev)
-{
- u8 temp_byte, function, max_functions, stop_it;
- int rc;
- u32 ID;
- struct pci_func *new_slot;
- struct pci_bus lpci_bus, *pci_bus;
- int index;
-
- new_slot = func;
-
- dbg("%s\n", __FUNCTION__);
- memcpy(&lpci_bus, ctrl->pci_dev->subordinate, sizeof(lpci_bus));
- pci_bus = &lpci_bus;
- pci_bus->number = func->bus;
-
- /* Check for Multi-function device */
- rc = pci_bus_read_config_byte(pci_bus, PCI_DEVFN(func->device, func->function), 0x0E, &temp_byte);
- if (rc) {
- dbg("%s: rc = %d\n", __FUNCTION__, rc);
- return rc;
- }
-
- if (temp_byte & 0x80) /* Multi-function device */
- max_functions = 8;
- else
- max_functions = 1;
-
- function = 0;
-
- do {
- rc = configure_new_function(ctrl, new_slot, behind_bridge,
- resources, bridge_bus, bridge_dev);
-
- if (rc) {
- dbg("configure_new_function failed: %d\n", rc);
- index = 0;
-
- while (new_slot) {
- new_slot = pciehp_slot_find(new_slot->bus,
- new_slot->device, index++);
-
- if (new_slot)
- pciehp_return_board_resources(new_slot,
- resources);
- }
-
- return rc;
- }
-
- function++;
-
- stop_it = 0;
-
- /* The following loop skips to the next present function
- * and creates a board structure
- */
-
- while ((function < max_functions) && (!stop_it)) {
- pci_bus_read_config_dword(pci_bus, PCI_DEVFN(func->device, function), 0x00, &ID);
-
- if (ID == 0xFFFFFFFF) { /* There's nothing there. */
- function++;
- } else { /* There's something there */
- /* Setup slot structure. */
- new_slot = pciehp_slot_create(func->bus);
-
- if (new_slot == NULL) {
- /* Out of memory */
- return 1;
- }
-
- new_slot->bus = func->bus;
- new_slot->device = func->device;
- new_slot->function = function;
- new_slot->is_a_board = 1;
- new_slot->status = 0;
-
- stop_it++;
- }
- }
-
- } while (function < max_functions);
- dbg("returning from %s\n", __FUNCTION__);
-
- return 0;
-}
-
-/*
- * Configuration logic that involves the hotplug data structures and
- * their bookkeeping
- */
-
-/**
- * configure_bridge: fill bridge's registers, either configure or disable it.
- */
-static int
-configure_bridge(struct pci_bus *pci_bus, unsigned int devfn,
- struct pci_resource *mem_node,
- struct pci_resource **hold_mem_node,
- int base_addr, int limit_addr)
-{
- u16 temp_word;
- u32 rc;
-
- if (mem_node) {
- memcpy(*hold_mem_node, mem_node, sizeof(struct pci_resource));
- mem_node->next = NULL;
-
- /* set Mem base and Limit registers */
- RES_CHECK(mem_node->base, 16);
- temp_word = (u16)(mem_node->base >> 16);
- rc = pci_bus_write_config_word(pci_bus, devfn, base_addr, temp_word);
-
- RES_CHECK(mem_node->base + mem_node->length - 1, 16);
- temp_word = (u16)((mem_node->base + mem_node->length - 1) >> 16);
- rc = pci_bus_write_config_word(pci_bus, devfn, limit_addr, temp_word);
- } else {
- temp_word = 0xFFFF;
- rc = pci_bus_write_config_word(pci_bus, devfn, base_addr, temp_word);
-
- temp_word = 0x0000;
- rc = pci_bus_write_config_word(pci_bus, devfn, limit_addr, temp_word);
-
- kfree(*hold_mem_node);
- *hold_mem_node = NULL;
- }
- return rc;
-}
-
-static int
-configure_new_bridge(struct controller *ctrl, struct pci_func *func,
- u8 behind_bridge, struct resource_lists *resources,
- struct pci_bus *pci_bus)
-{
- int cloop;
- u8 temp_byte;
- u8 device;
- u16 temp_word;
- u32 rc;
- u32 ID;
- unsigned int devfn;
- struct pci_resource *mem_node;
- struct pci_resource *p_mem_node;
- struct pci_resource *io_node;
- struct pci_resource *bus_node;
- struct pci_resource *hold_mem_node;
- struct pci_resource *hold_p_mem_node;
- struct pci_resource *hold_IO_node;
- struct pci_resource *hold_bus_node;
- struct irq_mapping irqs;
- struct pci_func *new_slot;
- struct resource_lists temp_resources;
-
- devfn = PCI_DEVFN(func->device, func->function);
-
- /* set Primary bus */
- dbg("set Primary bus = 0x%x\n", func->bus);
- rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_PRIMARY_BUS, func->bus);
- if (rc)
- return rc;
-
- /* find range of busses to use */
- bus_node = get_max_resource(&resources->bus_head, 1L);
-
- /* If we don't have any busses to allocate, we can't continue */
- if (!bus_node) {
- err("Got NO bus resource to use\n");
- return -ENOMEM;
- }
- dbg("Got ranges of buses to use: base:len=0x%x:%x\n", bus_node->base, bus_node->length);
-
- /* set Secondary bus */
- temp_byte = (u8)bus_node->base;
- dbg("set Secondary bus = 0x%x\n", temp_byte);
- rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_SECONDARY_BUS, temp_byte);
- if (rc)
- return rc;
-
- /* set subordinate bus */
- temp_byte = (u8)(bus_node->base + bus_node->length - 1);
- dbg("set subordinate bus = 0x%x\n", temp_byte);
- rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_SUBORDINATE_BUS, temp_byte);
- if (rc)
- return rc;
-
- /* Set HP parameters (Cache Line Size, Latency Timer) */
- rc = pciehprm_set_hpp(ctrl, func, PCI_HEADER_TYPE_BRIDGE);
- if (rc)
- return rc;
-
- /* Setup the IO, memory, and prefetchable windows */
-
- io_node = get_max_resource(&(resources->io_head), 0x1000L);
- if (io_node) {
- dbg("io_node(base, len, next) (%x, %x, %p)\n", io_node->base,
- io_node->length, io_node->next);
- }
-
- mem_node = get_max_resource(&(resources->mem_head), 0x100000L);
- if (mem_node) {
- dbg("mem_node(base, len, next) (%x, %x, %p)\n", mem_node->base,
- mem_node->length, mem_node->next);
- }
-
- if (resources->p_mem_head)
- p_mem_node = get_max_resource(&(resources->p_mem_head), 0x100000L);
- else {
- /*
- * In some platform implementation, MEM and PMEM are not
- * distinguished, and hence ACPI _CRS has only MEM entries
- * for both MEM and PMEM.
- */
- dbg("using MEM for PMEM\n");
- p_mem_node = get_max_resource(&(resources->mem_head), 0x100000L);
- }
- if (p_mem_node) {
- dbg("p_mem_node(base, len, next) (%x, %x, %p)\n", p_mem_node->base,
- p_mem_node->length, p_mem_node->next);
- }
-
- /* set up the IRQ info */
- if (!resources->irqs) {
- irqs.barber_pole = 0;
- irqs.interrupt[0] = 0;
- irqs.interrupt[1] = 0;
- irqs.interrupt[2] = 0;
- irqs.interrupt[3] = 0;
- irqs.valid_INT = 0;
- } else {
- irqs.barber_pole = resources->irqs->barber_pole;
- irqs.interrupt[0] = resources->irqs->interrupt[0];
- irqs.interrupt[1] = resources->irqs->interrupt[1];
- irqs.interrupt[2] = resources->irqs->interrupt[2];
- irqs.interrupt[3] = resources->irqs->interrupt[3];
- irqs.valid_INT = resources->irqs->valid_INT;
- }
-
- /* set up resource lists that are now aligned on top and bottom
- * for anything behind the bridge.
- */
- temp_resources.bus_head = bus_node;
- temp_resources.io_head = io_node;
- temp_resources.mem_head = mem_node;
- temp_resources.p_mem_head = p_mem_node;
- 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
- */
- hold_bus_node = kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
- hold_IO_node = kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
- hold_mem_node = kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
- hold_p_mem_node = kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
-
- if (!hold_bus_node || !hold_IO_node || !hold_mem_node || !hold_p_mem_node) {
- kfree(hold_bus_node);
- kfree(hold_IO_node);
- kfree(hold_mem_node);
- kfree(hold_p_mem_node);
-
- return 1;
- }
-
- memcpy(hold_bus_node, bus_node, sizeof(struct pci_resource));
-
- bus_node->base += 1;
- bus_node->length -= 1;
- bus_node->next = NULL;
-
- /* If we have IO resources copy them and fill in the bridge's
- * IO range registers
- */
- if (io_node) {
- memcpy(hold_IO_node, io_node, sizeof(struct pci_resource));
- io_node->next = NULL;
-
- /* set IO base and Limit registers */
- RES_CHECK(io_node->base, 8);
- temp_byte = (u8)(io_node->base >> 8);
- rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_IO_BASE, temp_byte);
-
- RES_CHECK(io_node->base + io_node->length - 1, 8);
- temp_byte = (u8)((io_node->base + io_node->length - 1) >> 8);
- rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_IO_LIMIT, temp_byte);
- } else {
- kfree(hold_IO_node);
- hold_IO_node = NULL;
- }
-
- /* If we have memory resources copy them and fill in the bridge's
- * memory range registers. Otherwise, fill in the range
- * registers with values that disable them.
- */
- rc = configure_bridge(pci_bus, devfn, mem_node, &hold_mem_node,
- PCI_MEMORY_BASE, PCI_MEMORY_LIMIT);
-
- /* If we have prefetchable memory resources copy them and
- * fill in the bridge's memory range registers. Otherwise,
- * fill in the range registers with values that disable them.
- */
- rc = configure_bridge(pci_bus, devfn, p_mem_node, &hold_p_mem_node,
- PCI_PREF_MEMORY_BASE, PCI_PREF_MEMORY_LIMIT);
-
- /* Adjust this to compensate for extra adjustment in first loop */
- irqs.barber_pole--;
-
- rc = 0;
-
- /* Here we actually find the devices and configure them */
- for (device = 0; (device <= 0x1F) && !rc; device++) {
- irqs.barber_pole = (irqs.barber_pole + 1) & 0x03;
-
- ID = 0xFFFFFFFF;
- pci_bus->number = hold_bus_node->base;
- pci_bus_read_config_dword (pci_bus, PCI_DEVFN(device, 0), PCI_VENDOR_ID, &ID);
- pci_bus->number = func->bus;
-
- if (ID != 0xFFFFFFFF) { /* device Present */
- /* Setup slot structure. */
- new_slot = pciehp_slot_create(hold_bus_node->base);
-
- if (new_slot == NULL) {
- /* Out of memory */
- rc = -ENOMEM;
- continue;
- }
-
- new_slot->bus = hold_bus_node->base;
- new_slot->device = device;
- new_slot->function = 0;
- new_slot->is_a_board = 1;
- new_slot->status = 0;
-
- rc = configure_new_device(ctrl, new_slot, 1,
- &temp_resources, func->bus,
- func->device);
- dbg("configure_new_device rc=0x%x\n",rc);
- } /* End of IF (device in slot?) */
- } /* End of FOR loop */
-
- if (rc) {
- pciehp_destroy_resource_list(&temp_resources);
-
- return_resource(&(resources->bus_head), hold_bus_node);
- return_resource(&(resources->io_head), hold_IO_node);
- return_resource(&(resources->mem_head), hold_mem_node);
- return_resource(&(resources->p_mem_head), hold_p_mem_node);
- return(rc);
- }
-
- /* save the interrupt routing information */
- if (resources->irqs) {
- resources->irqs->interrupt[0] = irqs.interrupt[0];
- resources->irqs->interrupt[1] = irqs.interrupt[1];
- resources->irqs->interrupt[2] = irqs.interrupt[2];
- resources->irqs->interrupt[3] = irqs.interrupt[3];
- resources->irqs->valid_INT = irqs.valid_INT;
- } else if (!behind_bridge) {
- /* We need to hook up the interrupts here */
- for (cloop = 0; cloop < 4; cloop++) {
- if (irqs.valid_INT & (0x01 << cloop)) {
- rc = pciehp_set_irq(func->bus, func->device,
- 0x0A + cloop, irqs.interrupt[cloop]);
- if (rc) {
- pciehp_destroy_resource_list (&temp_resources);
- return_resource(&(resources->bus_head), hold_bus_node);
- return_resource(&(resources->io_head), hold_IO_node);
- return_resource(&(resources->mem_head), hold_mem_node);
- return_resource(&(resources->p_mem_head), hold_p_mem_node);
- return rc;
- }
- }
- } /* end of for loop */
- }
-
- /* Return unused bus resources
- * First use the temporary node to store information for the board
- */
- if (hold_bus_node && bus_node && temp_resources.bus_head) {
- hold_bus_node->length = bus_node->base - hold_bus_node->base;
-
- hold_bus_node->next = func->bus_head;
- func->bus_head = hold_bus_node;
-
- temp_byte = (u8)(temp_resources.bus_head->base - 1);
-
- /* set subordinate bus */
- dbg("re-set subordinate bus = 0x%x\n", temp_byte);
- rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_SUBORDINATE_BUS, temp_byte);
-
- if (temp_resources.bus_head->length == 0) {
- kfree(temp_resources.bus_head);
- temp_resources.bus_head = NULL;
- } else {
- dbg("return bus res of b:d(0x%x:%x) base:len(0x%x:%x)\n",
- func->bus, func->device, temp_resources.bus_head->base, temp_resources.bus_head->length);
- return_resource(&(resources->bus_head), temp_resources.bus_head);
- }
- }
-
- /* If we have IO space available and there is some left,
- * return the unused portion
- */
- if (hold_IO_node && temp_resources.io_head) {
- io_node = do_pre_bridge_resource_split(&(temp_resources.io_head),
- &hold_IO_node, 0x1000);
-
- /* Check if we were able to split something off */
- if (io_node) {
- hold_IO_node->base = io_node->base + io_node->length;
-
- RES_CHECK(hold_IO_node->base, 8);
- temp_byte = (u8)((hold_IO_node->base) >> 8);
- rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_IO_BASE, temp_byte);
-
- return_resource(&(resources->io_head), io_node);
- }
-
- io_node = do_bridge_resource_split(&(temp_resources.io_head), 0x1000);
-
- /* Check if we were able to split something off */
- if (io_node) {
- /* First use the temporary node to store information for the board */
- hold_IO_node->length = io_node->base - hold_IO_node->base;
-
- /* If we used any, add it to the board's list */
- if (hold_IO_node->length) {
- hold_IO_node->next = func->io_head;
- func->io_head = hold_IO_node;
-
- RES_CHECK(io_node->base - 1, 8);
- temp_byte = (u8)((io_node->base - 1) >> 8);
- rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_IO_LIMIT, temp_byte);
-
- return_resource(&(resources->io_head), io_node);
- } else {
- /* it doesn't need any IO */
- temp_byte = 0x00;
- rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_IO_LIMIT, temp_byte);
-
- return_resource(&(resources->io_head), io_node);
- kfree(hold_IO_node);
- }
- } else {
- /* it used most of the range */
- hold_IO_node->next = func->io_head;
- func->io_head = hold_IO_node;
- }
- } else if (hold_IO_node) {
- /* it used the whole range */
- hold_IO_node->next = func->io_head;
- func->io_head = hold_IO_node;
- }
-
- /* If we have memory space available and there is some left,
- * return the unused portion
- */
- if (hold_mem_node && temp_resources.mem_head) {
- mem_node = do_pre_bridge_resource_split(&(temp_resources.mem_head), &hold_mem_node, 0x100000L);
-
- /* Check if we were able to split something off */
- if (mem_node) {
- hold_mem_node->base = mem_node->base + mem_node->length;
-
- RES_CHECK(hold_mem_node->base, 16);
- temp_word = (u16)((hold_mem_node->base) >> 16);
- rc = pci_bus_write_config_word (pci_bus, devfn, PCI_MEMORY_BASE, temp_word);
-
- return_resource(&(resources->mem_head), mem_node);
- }
-
- mem_node = do_bridge_resource_split(&(temp_resources.mem_head), 0x100000L);
-
- /* Check if we were able to split something off */
- if (mem_node) {
- /* First use the temporary node to store information for the board */
- hold_mem_node->length = mem_node->base - hold_mem_node->base;
-
- if (hold_mem_node->length) {
- hold_mem_node->next = func->mem_head;
- func->mem_head = hold_mem_node;
-
- /* configure end address */
- RES_CHECK(mem_node->base - 1, 16);
- temp_word = (u16)((mem_node->base - 1) >> 16);
- rc = pci_bus_write_config_word (pci_bus, devfn, PCI_MEMORY_LIMIT, temp_word);
-
- /* Return unused resources to the pool */
- return_resource(&(resources->mem_head), mem_node);
- } else {
- /* it doesn't need any Mem */
- temp_word = 0x0000;
- rc = pci_bus_write_config_word (pci_bus, devfn, PCI_MEMORY_LIMIT, temp_word);
-
- return_resource(&(resources->mem_head), mem_node);
- kfree(hold_mem_node);
- }
- } else {
- /* it used most of the range */
- hold_mem_node->next = func->mem_head;
- func->mem_head = hold_mem_node;
- }
- } else if (hold_mem_node) {
- /* it used the whole range */
- hold_mem_node->next = func->mem_head;
- func->mem_head = hold_mem_node;
- }
-
- /* If we have prefetchable memory space available and there is some
- * left at the end, return the unused portion
- */
- if (hold_p_mem_node && temp_resources.p_mem_head) {
- p_mem_node = do_pre_bridge_resource_split(&(temp_resources.p_mem_head),
- &hold_p_mem_node, 0x100000L);
-
- /* Check if we were able to split something off */
- if (p_mem_node) {
- hold_p_mem_node->base = p_mem_node->base + p_mem_node->length;
-
- RES_CHECK(hold_p_mem_node->base, 16);
- temp_word = (u16)((hold_p_mem_node->base) >> 16);
- rc = pci_bus_write_config_word (pci_bus, devfn, PCI_PREF_MEMORY_BASE, temp_word);
-
- return_resource(&(resources->p_mem_head), p_mem_node);
- }
-
- p_mem_node = do_bridge_resource_split(&(temp_resources.p_mem_head), 0x100000L);
-
- /* Check if we were able to split something off */
- if (p_mem_node) {
- /* First use the temporary node to store information for the board */
- hold_p_mem_node->length = p_mem_node->base - hold_p_mem_node->base;
-
- /* If we used any, add it to the board's list */
- if (hold_p_mem_node->length) {
- hold_p_mem_node->next = func->p_mem_head;
- func->p_mem_head = hold_p_mem_node;
-
- RES_CHECK(p_mem_node->base - 1, 16);
- temp_word = (u16)((p_mem_node->base - 1) >> 16);
- rc = pci_bus_write_config_word (pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, temp_word);
-
- return_resource(&(resources->p_mem_head), p_mem_node);
- } else {
- /* it doesn't need any PMem */
- temp_word = 0x0000;
- rc = pci_bus_write_config_word (pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, temp_word);
-
- return_resource(&(resources->p_mem_head), p_mem_node);
- kfree(hold_p_mem_node);
- }
- } else {
- /* it used the most of the range */
- hold_p_mem_node->next = func->p_mem_head;
- func->p_mem_head = hold_p_mem_node;
- }
- } else if (hold_p_mem_node) {
- /* it used the whole range */
- hold_p_mem_node->next = func->p_mem_head;
- func->p_mem_head = hold_p_mem_node;
- }
-
- /* We should be configuring an IRQ and the bridge's base address
- * registers if it needs them. Although we have never seen such
- * a device
- */
-
- pciehprm_enable_card(ctrl, func, PCI_HEADER_TYPE_BRIDGE);
-
- dbg("PCI Bridge Hot-Added s:b:d:f(%02x:%02x:%02x:%02x)\n", ctrl->seg, func->bus, func->device, func->function);
-
- return rc;
+ ret = remove_board(p_slot);
+ update_slot_info(p_slot);
+ return ret;
}
-/**
- * configure_new_function - Configures the PCI header information of one device
- *
- * @ctrl: pointer to controller structure
- * @func: pointer to function structure
- * @behind_bridge: 1 if this is a recursive call, 0 if not
- * @resources: pointer to set of resource lists
- *
- * Calls itself recursively for bridged devices.
- * Returns 0 if success
- *
- */
-static int
-configure_new_function(struct controller *ctrl, struct pci_func *func,
- u8 behind_bridge, struct resource_lists *resources,
- u8 bridge_bus, u8 bridge_dev)
-{
- int cloop;
- u8 temp_byte;
- u8 class_code;
- u32 rc;
- u32 temp_register;
- u32 base;
- unsigned int devfn;
- struct pci_resource *mem_node;
- struct pci_resource *io_node;
- struct pci_bus lpci_bus, *pci_bus;
-
- memcpy(&lpci_bus, ctrl->pci_dev->subordinate, sizeof(lpci_bus));
- pci_bus = &lpci_bus;
- pci_bus->number = func->bus;
- devfn = PCI_DEVFN(func->device, func->function);
-
- /* Check for Bridge */
- rc = pci_bus_read_config_byte(pci_bus, devfn, PCI_HEADER_TYPE, &temp_byte);
- if (rc)
- return rc;
- dbg("%s: bus %x dev %x func %x temp_byte = %x\n", __FUNCTION__,
- func->bus, func->device, func->function, temp_byte);
-
- if ((temp_byte & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { /* PCI-PCI Bridge */
- rc = configure_new_bridge(ctrl, func, behind_bridge, resources,
- pci_bus);
-
- if (rc)
- return rc;
- } else if ((temp_byte & 0x7F) == PCI_HEADER_TYPE_NORMAL) {
- /* Standard device */
- u64 base64;
- rc = pci_bus_read_config_byte(pci_bus, devfn, 0x0B, &class_code);
-
- if (class_code == PCI_BASE_CLASS_DISPLAY)
- return DEVICE_TYPE_NOT_SUPPORTED;
-
- /* Figure out IO and memory needs */
- for (cloop = PCI_BASE_ADDRESS_0; cloop <= PCI_BASE_ADDRESS_5; cloop += 4) {
- temp_register = 0xFFFFFFFF;
-
- rc = pci_bus_write_config_dword (pci_bus, devfn, cloop, temp_register);
- rc = pci_bus_read_config_dword(pci_bus, devfn, cloop, &temp_register);
- dbg("Bar[%x]=0x%x on bus:dev:func(0x%x:%x:%x)\n", cloop, temp_register,
- func->bus, func->device, func->function);
-
- if (!temp_register)
- continue;
-
- base64 = 0L;
- if (temp_register & PCI_BASE_ADDRESS_SPACE_IO) {
- /* Map IO */
-
- /* set base = amount of IO space */
- base = temp_register & 0xFFFFFFFC;
- base = ~base + 1;
-
- dbg("NEED IO length(0x%x)\n", base);
- io_node = get_io_resource(&(resources->io_head),(ulong)base);
-
- /* allocate the resource to the board */
- if (io_node) {
- dbg("Got IO base=0x%x(length=0x%x)\n", io_node->base, io_node->length);
- base = (u32)io_node->base;
- io_node->next = func->io_head;
- func->io_head = io_node;
- } else {
- err("Got NO IO resource(length=0x%x)\n", base);
- return -ENOMEM;
- }
- } else { /* map MEM */
- int prefetchable = 1;
- struct pci_resource **res_node = &func->p_mem_head;
- char *res_type_str = "PMEM";
- u32 temp_register2;
-
- if (!(temp_register & PCI_BASE_ADDRESS_MEM_PREFETCH)) {
- prefetchable = 0;
- res_node = &func->mem_head;
- res_type_str++;
- }
-
- base = temp_register & 0xFFFFFFF0;
- base = ~base + 1;
-
- switch (temp_register & PCI_BASE_ADDRESS_MEM_TYPE_MASK) {
- case PCI_BASE_ADDRESS_MEM_TYPE_32:
- dbg("NEED 32 %s bar=0x%x(length=0x%x)\n", res_type_str, temp_register, base);
-
- if (prefetchable && resources->p_mem_head)
- mem_node=get_resource(&(resources->p_mem_head), (ulong)base);
- else {
- if (prefetchable)
- dbg("using MEM for PMEM\n");
- mem_node = get_resource(&(resources->mem_head), (ulong)base);
- }
-
- /* allocate the resource to the board */
- if (mem_node) {
- base = (u32)mem_node->base;
- mem_node->next = *res_node;
- *res_node = mem_node;
- dbg("Got 32 %s base=0x%x(length=0x%x)\n", res_type_str, mem_node->base,
- mem_node->length);
- } else {
- err("Got NO 32 %s resource(length=0x%x)\n", res_type_str, base);
- return -ENOMEM;
- }
- break;
- case PCI_BASE_ADDRESS_MEM_TYPE_64:
- rc = pci_bus_read_config_dword(pci_bus, devfn, cloop+4, &temp_register2);
- dbg("NEED 64 %s bar=0x%x:%x(length=0x%x)\n", res_type_str, temp_register2,
- temp_register, base);
-
- if (prefetchable && resources->p_mem_head)
- mem_node = get_resource(&(resources->p_mem_head), (ulong)base);
- else {
- if (prefetchable)
- dbg("using MEM for PMEM\n");
- mem_node = get_resource(&(resources->mem_head), (ulong)base);
- }
-
- /* allocate the resource to the board */
- if (mem_node) {
- base64 = mem_node->base;
- mem_node->next = *res_node;
- *res_node = mem_node;
- dbg("Got 64 %s base=0x%x:%x(length=%x)\n", res_type_str, (u32)(base64 >> 32),
- (u32)base64, mem_node->length);
- } else {
- err("Got NO 64 %s resource(length=0x%x)\n", res_type_str, base);
- return -ENOMEM;
- }
- break;
- default:
- dbg("reserved BAR type=0x%x\n", temp_register);
- break;
- }
-
- }
-
- if (base64) {
- rc = pci_bus_write_config_dword(pci_bus, devfn, cloop, (u32)base64);
- cloop += 4;
- base64 >>= 32;
-
- if (base64) {
- dbg("%s: high dword of base64(0x%x) set to 0\n", __FUNCTION__, (u32)base64);
- base64 = 0x0L;
- }
-
- rc = pci_bus_write_config_dword(pci_bus, devfn, cloop, (u32)base64);
- } else {
- rc = pci_bus_write_config_dword(pci_bus, devfn, cloop, base);
- }
- } /* End of base register loop */
-
- /* disable ROM base Address */
- rc = pci_bus_write_config_dword (pci_bus, devfn, PCI_ROM_ADDRESS, 0x00);
-
- /* Set HP parameters (Cache Line Size, Latency Timer) */
- rc = pciehprm_set_hpp(ctrl, func, PCI_HEADER_TYPE_NORMAL);
- if (rc)
- return rc;
-
- pciehprm_enable_card(ctrl, func, PCI_HEADER_TYPE_NORMAL);
-
- dbg("PCI function Hot-Added s:b:d:f(%02x:%02x:%02x:%02x)\n", ctrl->seg, func->bus, func->device,
- func->function);
- } /* End of Not-A-Bridge else */
- else {
- /* It's some strange type of PCI adapter (Cardbus?) */
- return DEVICE_TYPE_NOT_SUPPORTED;
- }
-
- func->configured = 1;
-
- return 0;
-}
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c
index 7a0e27f0e063..4a3cecca012c 100644
--- a/drivers/pci/hotplug/pciehp_hpc.c
+++ b/drivers/pci/hotplug/pciehp_hpc.c
@@ -27,16 +27,10 @@
*
*/
-#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/types.h>
-#include <linux/slab.h>
-#include <linux/vmalloc.h>
-#include <linux/interrupt.h>
-#include <linux/spinlock.h>
#include <linux/pci.h>
-#include <asm/system.h>
#include "../pci.h"
#include "pciehp.h"
@@ -217,23 +211,6 @@ static int pcie_cap_base = 0; /* Base of the PCI Express capability item struct
#define MRL_STATE 0x0020
#define PRSN_STATE 0x0040
-struct php_ctlr_state_s {
- struct php_ctlr_state_s *pnext;
- struct pci_dev *pci_dev;
- unsigned int irq;
- unsigned long flags; /* spinlock's */
- u32 slot_device_offset;
- u32 num_slots;
- struct timer_list int_poll_timer; /* Added for poll event */
- php_intr_callback_t attention_button_callback;
- php_intr_callback_t switch_change_callback;
- php_intr_callback_t presence_change_callback;
- php_intr_callback_t power_fault_callback;
- void *callback_instance_id;
- struct ctrl_reg *creg; /* Ptr to controller register space */
-};
-
-
static spinlock_t hpc_event_lock;
DEFINE_DBG_BUFFER /* Debug string buffer for entire HPC defined here */
@@ -297,7 +274,6 @@ static int pcie_write_cmd(struct slot *slot, u16 cmd)
DBG_ENTER_ROUTINE
- dbg("%s : Enter\n", __FUNCTION__);
if (!php_ctlr) {
err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
return -1;
@@ -308,7 +284,6 @@ static int pcie_write_cmd(struct slot *slot, u16 cmd)
err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
return retval;
}
- dbg("%s : hp_register_read_word SLOT_STATUS %x\n", __FUNCTION__, slot_status);
if ((slot_status & CMD_COMPLETED) == CMD_COMPLETED ) {
/* After 1 sec and CMD_COMPLETED still not set, just proceed forward to issue
@@ -316,14 +291,11 @@ static int pcie_write_cmd(struct slot *slot, u16 cmd)
dbg("%s : CMD_COMPLETED not clear after 1 sec.\n", __FUNCTION__);
}
- dbg("%s: Before hp_register_write_word SLOT_CTRL %x\n", __FUNCTION__, cmd);
retval = hp_register_write_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), cmd | CMD_CMPL_INTR_ENABLE);
if (retval) {
err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__);
return retval;
}
- dbg("%s : hp_register_write_word SLOT_CTRL %x\n", __FUNCTION__, cmd | CMD_CMPL_INTR_ENABLE);
- dbg("%s : Exit\n", __FUNCTION__);
DBG_LEAVE_ROUTINE
return retval;
@@ -509,7 +481,6 @@ static int hpc_query_power_fault(struct slot * slot)
u16 slot_status;
u8 pwr_fault;
int retval = 0;
- u8 status;
DBG_ENTER_ROUTINE
@@ -521,15 +492,13 @@ static int hpc_query_power_fault(struct slot * slot)
retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(slot->ctrl->cap_base), slot_status);
if (retval) {
- err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
+ err("%s : Cannot check for power fault\n", __FUNCTION__);
return retval;
}
pwr_fault = (u8)((slot_status & PWR_FAULT_DETECTED) >> 1);
- status = (pwr_fault != 1) ? 1 : 0;
DBG_LEAVE_ROUTINE
- /* Note: Logic 0 => fault */
- return status;
+ return pwr_fault;
}
static int hpc_set_attention_status(struct slot *slot, u8 value)
@@ -539,7 +508,8 @@ static int hpc_set_attention_status(struct slot *slot, u8 value)
u16 slot_ctrl;
int rc = 0;
- dbg("%s: \n", __FUNCTION__);
+ DBG_ENTER_ROUTINE
+
if (!php_ctlr) {
err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
return -1;
@@ -555,7 +525,6 @@ static int hpc_set_attention_status(struct slot *slot, u8 value)
err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
return rc;
}
- dbg("%s : hp_register_read_word SLOT_CTRL %x\n", __FUNCTION__, slot_ctrl);
switch (value) {
case 0 : /* turn off */
@@ -576,6 +545,7 @@ static int hpc_set_attention_status(struct slot *slot, u8 value)
pcie_write_cmd(slot, slot_cmd);
dbg("%s: SLOT_CTRL %x write cmd %x\n", __FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), slot_cmd);
+ DBG_LEAVE_ROUTINE
return rc;
}
@@ -587,7 +557,8 @@ static void hpc_set_green_led_on(struct slot *slot)
u16 slot_ctrl;
int rc = 0;
- dbg("%s: \n", __FUNCTION__);
+ DBG_ENTER_ROUTINE
+
if (!php_ctlr) {
err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
return ;
@@ -604,7 +575,6 @@ static void hpc_set_green_led_on(struct slot *slot)
err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
return;
}
- dbg("%s : hp_register_read_word SLOT_CTRL %x\n", __FUNCTION__, slot_ctrl);
slot_cmd = (slot_ctrl & ~PWR_LED_CTRL) | 0x0100;
if (!pciehp_poll_mode)
slot_cmd = slot_cmd | HP_INTR_ENABLE;
@@ -612,6 +582,7 @@ static void hpc_set_green_led_on(struct slot *slot)
pcie_write_cmd(slot, slot_cmd);
dbg("%s: SLOT_CTRL %x write cmd %x\n",__FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), slot_cmd);
+ DBG_LEAVE_ROUTINE
return;
}
@@ -622,7 +593,8 @@ static void hpc_set_green_led_off(struct slot *slot)
u16 slot_ctrl;
int rc = 0;
- dbg("%s: \n", __FUNCTION__);
+ DBG_ENTER_ROUTINE
+
if (!php_ctlr) {
err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
return ;
@@ -639,7 +611,6 @@ static void hpc_set_green_led_off(struct slot *slot)
err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
return;
}
- dbg("%s : hp_register_read_word SLOT_CTRL %x\n", __FUNCTION__, slot_ctrl);
slot_cmd = (slot_ctrl & ~PWR_LED_CTRL) | 0x0300;
@@ -648,6 +619,7 @@ static void hpc_set_green_led_off(struct slot *slot)
pcie_write_cmd(slot, slot_cmd);
dbg("%s: SLOT_CTRL %x write cmd %x\n", __FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), slot_cmd);
+ DBG_LEAVE_ROUTINE
return;
}
@@ -658,7 +630,8 @@ static void hpc_set_green_led_blink(struct slot *slot)
u16 slot_ctrl;
int rc = 0;
- dbg("%s: \n", __FUNCTION__);
+ DBG_ENTER_ROUTINE
+
if (!php_ctlr) {
err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
return ;
@@ -675,7 +648,6 @@ static void hpc_set_green_led_blink(struct slot *slot)
err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
return;
}
- dbg("%s : hp_register_read_word SLOT_CTRL %x\n", __FUNCTION__, slot_ctrl);
slot_cmd = (slot_ctrl & ~PWR_LED_CTRL) | 0x0200;
@@ -684,6 +656,7 @@ static void hpc_set_green_led_blink(struct slot *slot)
pcie_write_cmd(slot, slot_cmd);
dbg("%s: SLOT_CTRL %x write cmd %x\n",__FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), slot_cmd);
+ DBG_LEAVE_ROUTINE
return;
}
@@ -780,7 +753,6 @@ static int hpc_power_on_slot(struct slot * slot)
int retval = 0;
DBG_ENTER_ROUTINE
- dbg("%s: \n", __FUNCTION__);
if (!php_ctlr) {
err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
@@ -799,8 +771,6 @@ static int hpc_power_on_slot(struct slot * slot)
err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
return retval;
}
- dbg("%s: SLOT_CTRL %x, value read %xn", __FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base),
- slot_ctrl);
slot_cmd = (slot_ctrl & ~PWR_CTRL) | POWER_ON;
@@ -829,7 +799,6 @@ static int hpc_power_off_slot(struct slot * slot)
int retval = 0;
DBG_ENTER_ROUTINE
- dbg("%s: \n", __FUNCTION__);
if (!php_ctlr) {
err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
@@ -848,8 +817,6 @@ static int hpc_power_off_slot(struct slot * slot)
err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
return retval;
}
- dbg("%s: SLOT_CTRL %x, value read %x\n", __FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base),
- slot_ctrl);
slot_cmd = (slot_ctrl & ~PWR_CTRL) | POWER_OFF;
@@ -924,7 +891,6 @@ static irqreturn_t pcie_isr(int IRQ, void *dev_id, struct pt_regs *regs)
return IRQ_NONE;
}
- dbg("%s: Set Mask Hot-plug Interrupt Enable\n", __FUNCTION__);
dbg("%s: hp_register_read_word SLOT_CTRL with value %x\n", __FUNCTION__, temp_word);
temp_word = (temp_word & ~HP_INTR_ENABLE & ~CMD_CMPL_INTR_ENABLE) | 0x00;
@@ -933,7 +899,6 @@ static irqreturn_t pcie_isr(int IRQ, void *dev_id, struct pt_regs *regs)
err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__);
return IRQ_NONE;
}
- dbg("%s: hp_register_write_word SLOT_CTRL with value %x\n", __FUNCTION__, temp_word);
rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status);
if (rc) {
@@ -949,14 +914,12 @@ static irqreturn_t pcie_isr(int IRQ, void *dev_id, struct pt_regs *regs)
err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__);
return IRQ_NONE;
}
- dbg("%s: hp_register_write_word SLOT_STATUS with value %x\n", __FUNCTION__, temp_word);
}
if (intr_loc & CMD_COMPLETED) {
/*
* Command Complete Interrupt Pending
*/
- dbg("%s: In Command Complete Interrupt Pending\n", __FUNCTION__);
wake_up_interruptible(&ctrl->queue);
}
@@ -989,7 +952,6 @@ static irqreturn_t pcie_isr(int IRQ, void *dev_id, struct pt_regs *regs)
}
dbg("%s: Unmask Hot-plug Interrupt Enable\n", __FUNCTION__);
- dbg("%s: hp_register_read_word SLOT_CTRL with value %x\n", __FUNCTION__, temp_word);
temp_word = (temp_word & ~HP_INTR_ENABLE) | HP_INTR_ENABLE;
rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_CTRL(ctrl->cap_base), temp_word);
@@ -997,14 +959,12 @@ static irqreturn_t pcie_isr(int IRQ, void *dev_id, struct pt_regs *regs)
err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__);
return IRQ_NONE;
}
- dbg("%s: hp_register_write_word SLOT_CTRL with value %x\n", __FUNCTION__, temp_word);
rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status);
if (rc) {
err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
return IRQ_NONE;
}
- dbg("%s: hp_register_read_word SLOT_STATUS with value %x\n", __FUNCTION__, slot_status);
/* Clear command complete interrupt caused by this write */
temp_word = 0x1F;
@@ -1248,12 +1208,7 @@ static struct hpc_ops pciehp_hpc_ops = {
.check_lnk_status = hpc_check_lnk_status,
};
-int pcie_init(struct controller * ctrl,
- struct pcie_device *dev,
- php_intr_callback_t attention_button_callback,
- php_intr_callback_t switch_change_callback,
- php_intr_callback_t presence_change_callback,
- php_intr_callback_t power_fault_callback)
+int pcie_init(struct controller * ctrl, struct pcie_device *dev)
{
struct php_ctlr_state_s *php_ctlr, *p;
void *instance_id = ctrl;
@@ -1282,8 +1237,8 @@ int pcie_init(struct controller * ctrl,
pdev = dev->port;
php_ctlr->pci_dev = pdev; /* save pci_dev in context */
- dbg("%s: pdev->vendor %x pdev->device %x\n", __FUNCTION__,
- pdev->vendor, pdev->device);
+ dbg("%s: hotplug controller vendor id 0x%x device id 0x%x\n",
+ __FUNCTION__, pdev->vendor, pdev->device);
saved_cap_base = pcie_cap_base;
@@ -1340,8 +1295,6 @@ int pcie_init(struct controller * ctrl,
first = 0;
}
- dbg("pdev = %p: b:d:f:irq=0x%x:%x:%x:%x\n", pdev, pdev->bus->number,
- PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn), dev->irq);
for ( rc = 0; rc < DEVICE_COUNT_RESOURCE; rc++)
if (pci_resource_len(pdev, rc) > 0)
dbg("pci resource[%d] start=0x%lx(len=0x%lx)\n", rc,
@@ -1359,13 +1312,12 @@ int pcie_init(struct controller * ctrl,
/* find the IRQ */
php_ctlr->irq = dev->irq;
- dbg("HPC interrupt = %d\n", php_ctlr->irq);
/* Save interrupt callback info */
- php_ctlr->attention_button_callback = attention_button_callback;
- php_ctlr->switch_change_callback = switch_change_callback;
- php_ctlr->presence_change_callback = presence_change_callback;
- php_ctlr->power_fault_callback = power_fault_callback;
+ php_ctlr->attention_button_callback = pciehp_handle_attention_button;
+ php_ctlr->switch_change_callback = pciehp_handle_switch_change;
+ php_ctlr->presence_change_callback = pciehp_handle_presence_change;
+ php_ctlr->power_fault_callback = pciehp_handle_power_fault;
php_ctlr->callback_instance_id = instance_id;
/* return PCI Controller Info */
@@ -1387,15 +1339,12 @@ int pcie_init(struct controller * ctrl,
err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__);
goto abort_free_ctlr;
}
- dbg("%s : Mask HPIE hp_register_write_word SLOT_CTRL %x\n", __FUNCTION__, temp_word);
rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status);
if (rc) {
err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
goto abort_free_ctlr;
}
- dbg("%s: Mask HPIE SLOT_STATUS offset %x reads slot_status %x\n", __FUNCTION__, SLOT_STATUS(ctrl->cap_base)
- , slot_status);
temp_word = 0x1F; /* Clear all events */
rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), temp_word);
@@ -1403,7 +1352,6 @@ int pcie_init(struct controller * ctrl,
err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__);
goto abort_free_ctlr;
}
- dbg("%s: SLOT_STATUS offset %x writes slot_status %x\n", __FUNCTION__, SLOT_STATUS(ctrl->cap_base), temp_word);
if (pciehp_poll_mode) {/* Install interrupt polling code */
/* Install and start the interrupt polling timer */
@@ -1419,13 +1367,14 @@ int pcie_init(struct controller * ctrl,
}
}
+ dbg("pciehp ctrl b:d:f:irq=0x%x:%x:%x:%x\n", pdev->bus->number,
+ PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn), dev->irq);
+
rc = hp_register_read_word(pdev, SLOT_CTRL(ctrl->cap_base), temp_word);
if (rc) {
err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
goto abort_free_ctlr;
}
- dbg("%s: SLOT_CTRL %x value read %x\n", __FUNCTION__, SLOT_CTRL(ctrl->cap_base), temp_word);
- dbg("%s: slot_cap %x\n", __FUNCTION__, slot_cap);
intr_enable = intr_enable | PRSN_DETECT_ENABLE;
@@ -1445,7 +1394,6 @@ int pcie_init(struct controller * ctrl,
} else {
temp_word = (temp_word & ~HP_INTR_ENABLE) | HP_INTR_ENABLE;
}
- dbg("%s: temp_word %x\n", __FUNCTION__, temp_word);
/* Unmask Hot-plug Interrupt Enable for the interrupt notification mechanism case */
rc = hp_register_write_word(pdev, SLOT_CTRL(ctrl->cap_base), temp_word);
@@ -1453,14 +1401,11 @@ int pcie_init(struct controller * ctrl,
err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__);
goto abort_free_ctlr;
}
- dbg("%s : Unmask HPIE hp_register_write_word SLOT_CTRL with %x\n", __FUNCTION__, temp_word);
rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status);
if (rc) {
err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
goto abort_free_ctlr;
}
- dbg("%s: Unmask HPIE SLOT_STATUS offset %x reads slot_status %x\n", __FUNCTION__,
- SLOT_STATUS(ctrl->cap_base), slot_status);
temp_word = 0x1F; /* Clear all events */
rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), temp_word);
@@ -1468,8 +1413,16 @@ int pcie_init(struct controller * ctrl,
err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__);
goto abort_free_ctlr;
}
- dbg("%s: SLOT_STATUS offset %x writes slot_status %x\n", __FUNCTION__, SLOT_STATUS(ctrl->cap_base), temp_word);
+ if (pciehp_force) {
+ dbg("Bypassing BIOS check for pciehp use on %s\n",
+ pci_name(ctrl->pci_dev));
+ } else {
+ rc = pciehp_get_hp_hw_control_from_firmware(ctrl->pci_dev);
+ if (rc)
+ goto abort_free_ctlr;
+ }
+
/* Add this HPC instance into the HPC list */
spin_lock(&list_lock);
if (php_ctlr_list_head == 0) {
diff --git a/drivers/pci/hotplug/pciehp_pci.c b/drivers/pci/hotplug/pciehp_pci.c
index 33b539b34f7e..647673a7d224 100644
--- a/drivers/pci/hotplug/pciehp_pci.c
+++ b/drivers/pci/hotplug/pciehp_pci.c
@@ -27,801 +27,111 @@
*
*/
-#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/types.h>
-#include <linux/slab.h>
-#include <linux/workqueue.h>
-#include <linux/proc_fs.h>
#include <linux/pci.h>
#include "../pci.h"
#include "pciehp.h"
-#ifndef CONFIG_IA64
-#include "../../../arch/i386/pci/pci.h" /* horrible hack showing how processor dependant we are... */
-#endif
-int pciehp_configure_device (struct controller* ctrl, struct pci_func* func)
+int pciehp_configure_device(struct slot *p_slot)
{
- 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));
-
- /* Still NULL ? Well then scan for it ! */
- if (func->pci_dev == NULL) {
- dbg("%s: pci_dev still null. do pci_scan_slot\n", __FUNCTION__);
-
- num = pci_scan_slot(ctrl->pci_dev->subordinate, PCI_DEVFN(func->device, func->function));
-
- if (num)
- pci_bus_add_devices(ctrl->pci_dev->subordinate);
-
- func->pci_dev = pci_find_slot(func->bus, PCI_DEVFN(func->device, func->function));
- if (func->pci_dev == NULL) {
- dbg("ERROR: pci_dev still null\n");
- return 0;
- }
+ struct pci_dev *dev;
+ struct pci_bus *parent = p_slot->ctrl->pci_dev->subordinate;
+ int num, fn;
+
+ dev = pci_find_slot(p_slot->bus, PCI_DEVFN(p_slot->device, 0));
+ if (dev) {
+ err("Device %s already exists at %x:%x, cannot hot-add\n",
+ pci_name(dev), p_slot->bus, p_slot->device);
+ return -EINVAL;
}
- if (func->pci_dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
- pci_read_config_byte(func->pci_dev, PCI_SECONDARY_BUS, &bus);
- child = pci_add_new_bus(func->pci_dev->bus, (func->pci_dev), bus);
- pci_do_scan_bus(child);
+ num = pci_scan_slot(parent, PCI_DEVFN(p_slot->device, 0));
+ if (num == 0) {
+ err("No new device found\n");
+ return -ENODEV;
+ }
+ for (fn = 0; fn < 8; fn++) {
+ if (!(dev = pci_find_slot(p_slot->bus,
+ PCI_DEVFN(p_slot->device, fn))))
+ continue;
+ if ((dev->class >> 16) == PCI_BASE_CLASS_DISPLAY) {
+ err("Cannot hot-add display device %s\n",
+ pci_name(dev));
+ continue;
+ }
+ if ((dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) ||
+ (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)) {
+ /* Find an unused bus number for the new bridge */
+ struct pci_bus *child;
+ unsigned char busnr, start = parent->secondary;
+ unsigned char end = parent->subordinate;
+ for (busnr = start; busnr <= end; busnr++) {
+ if (!pci_find_bus(pci_domain_nr(parent),
+ busnr))
+ break;
+ }
+ if (busnr >= end) {
+ err("No free bus for hot-added bridge\n");
+ continue;
+ }
+ child = pci_add_new_bus(parent, dev, busnr);
+ if (!child) {
+ err("Cannot add new bus for %s\n",
+ pci_name(dev));
+ continue;
+ }
+ child->subordinate = pci_do_scan_bus(child);
+ pci_bus_size_bridges(child);
+ }
+ /* TBD: program firmware provided _HPP values */
+ /* program_fw_provided_values(dev); */
}
+ pci_bus_assign_resources(parent);
+ pci_bus_add_devices(parent);
+ pci_enable_bridges(parent);
return 0;
}
-
-int pciehp_unconfigure_device(struct pci_func* func)
+int pciehp_unconfigure_device(struct slot *p_slot)
{
int rc = 0;
int j;
- struct pci_bus *pbus;
+ u8 bctl = 0;
- dbg("%s: bus/dev/func = %x/%x/%x\n", __FUNCTION__, func->bus,
- func->device, func->function);
- pbus = func->pci_dev->bus;
+ dbg("%s: bus/dev = %x/%x\n", __FUNCTION__, p_slot->bus,
+ p_slot->device);
for (j=0; j<8 ; j++) {
- struct pci_dev* temp = pci_find_slot(func->bus,
- (func->device << 3) | j);
- if (temp) {
- pci_remove_bus_device(temp);
+ struct pci_dev* temp = pci_find_slot(p_slot->bus,
+ (p_slot->device << 3) | j);
+ if (!temp)
+ continue;
+ if ((temp->class >> 16) == PCI_BASE_CLASS_DISPLAY) {
+ err("Cannot remove display device %s\n",
+ pci_name(temp));
+ continue;
}
+ if (temp->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
+ pci_read_config_byte(temp, PCI_BRIDGE_CONTROL, &bctl);
+ if (bctl & PCI_BRIDGE_CTL_VGA) {
+ err("Cannot remove display device %s\n",
+ pci_name(temp));
+ continue;
+ }
+ }
+ pci_remove_bus_device(temp);
}
/*
* Some PCI Express root ports require fixup after hot-plug operation.
*/
if (pcie_mch_quirk)
- pci_fixup_device(pci_fixup_final, pbus->self);
+ pci_fixup_device(pci_fixup_final, p_slot->ctrl->pci_dev);
return rc;
}
-/*
- * pciehp_set_irq
- *
- * @bus_num: bus number of PCI device
- * @dev_num: device number of PCI device
- * @slot: pointer to u8 where slot number will be returned
- */
-int pciehp_set_irq (u8 bus_num, u8 dev_num, u8 int_pin, u8 irq_num)
-{
-#if defined(CONFIG_X86) && !defined(CONFIG_X86_IO_APIC) && !defined(CONFIG_X86_64)
- int rc;
- u16 temp_word;
- struct pci_dev fakedev;
- struct pci_bus fakebus;
-
- fakedev.devfn = dev_num << 3;
- fakedev.bus = &fakebus;
- fakebus.number = bus_num;
- dbg("%s: dev %d, bus %d, pin %d, num %d\n",
- __FUNCTION__, dev_num, bus_num, int_pin, irq_num);
- rc = pcibios_set_irq_routing(&fakedev, int_pin - 0x0a, irq_num);
- dbg("%s: rc %d\n", __FUNCTION__, rc);
- if (!rc)
- return !rc;
-
- /* 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);
-#endif
- return 0;
-}
-
-/* More PCI configuration routines; this time centered around hotplug controller */
-
-
-/*
- * pciehp_save_config
- *
- * Reads configuration for all slots in a PCI bus and saves info.
- *
- * Note: For non-hot plug busses, the slot # saved is the device #
- *
- * returns 0 if success
- */
-int pciehp_save_config(struct controller *ctrl, int busnumber, int num_ctlr_slots, int first_device_num)
-{
- int rc;
- u8 class_code;
- u8 header_type;
- u32 ID;
- u8 secondary_bus;
- struct pci_func *new_slot;
- int sub_bus;
- int max_functions;
- int function;
- u8 DevError;
- int device = 0;
- int cloop = 0;
- int stop_it;
- int index;
- int is_hot_plug = num_ctlr_slots || first_device_num;
- struct pci_bus lpci_bus, *pci_bus;
- int FirstSupported, LastSupported;
-
- dbg("%s: Enter\n", __FUNCTION__);
-
- memcpy(&lpci_bus, ctrl->pci_dev->subordinate, sizeof(lpci_bus));
- pci_bus = &lpci_bus;
-
- dbg("%s: num_ctlr_slots = %d, first_device_num = %d\n", __FUNCTION__,
- num_ctlr_slots, first_device_num);
-
- /* Decide which slots are supported */
- if (is_hot_plug) {
- /*********************************
- * is_hot_plug is the slot mask
- *********************************/
- FirstSupported = first_device_num;
- LastSupported = FirstSupported + num_ctlr_slots - 1;
- } else {
- FirstSupported = 0;
- LastSupported = 0x1F;
- }
-
- dbg("FirstSupported = %d, LastSupported = %d\n", FirstSupported,
- LastSupported);
-
- /* Save PCI configuration space for all devices in supported slots */
- dbg("%s: pci_bus->number = %x\n", __FUNCTION__, pci_bus->number);
- pci_bus->number = busnumber;
- dbg("%s: bus = %x, dev = %x\n", __FUNCTION__, busnumber, device);
- for (device = FirstSupported; device <= LastSupported; device++) {
- ID = 0xFFFFFFFF;
- rc = pci_bus_read_config_dword(pci_bus, PCI_DEVFN(device, 0),
- PCI_VENDOR_ID, &ID);
-
- if (ID != 0xFFFFFFFF) { /* device in slot */
- dbg("%s: ID = %x\n", __FUNCTION__, ID);
- rc = pci_bus_read_config_byte(pci_bus, PCI_DEVFN(device, 0),
- 0x0B, &class_code);
- if (rc)
- return rc;
-
- rc = pci_bus_read_config_byte(pci_bus, PCI_DEVFN(device, 0),
- PCI_HEADER_TYPE, &header_type);
- if (rc)
- return rc;
-
- dbg("class_code = %x, header_type = %x\n", class_code, header_type);
-
- /* If multi-function device, set max_functions to 8 */
- if (header_type & 0x80)
- max_functions = 8;
- else
- max_functions = 1;
-
- function = 0;
-
- do {
- DevError = 0;
- dbg("%s: In do loop\n", __FUNCTION__);
-
- 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(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 = pciehp_save_config(ctrl, sub_bus, 0, 0);
- if (rc)
- return rc;
- }
- }
-
- index = 0;
- new_slot = pciehp_slot_find(busnumber, device, index++);
-
- dbg("%s: new_slot = %p bus %x dev %x fun %x\n",
- __FUNCTION__, new_slot, busnumber, device, index-1);
-
- while (new_slot && (new_slot->function != (u8) function)) {
- new_slot = pciehp_slot_find(busnumber, device, index++);
- dbg("%s: while loop, new_slot = %p bus %x dev %x fun %x\n",
- __FUNCTION__, new_slot, busnumber, device, index-1);
- }
- if (!new_slot) {
- /* Setup slot structure. */
- new_slot = pciehp_slot_create(busnumber);
- dbg("%s: if, new_slot = %p bus %x dev %x fun %x\n",
- __FUNCTION__, new_slot, busnumber, device, function);
-
- 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);
- dbg("new_slot->pci_dev = %p\n", new_slot->pci_dev);
-
- for (cloop = 0; cloop < 0x20; cloop++) {
- rc = pci_bus_read_config_dword(pci_bus,
- PCI_DEVFN(device, function),
- cloop << 2,
- (u32 *) &(new_slot->config_space [cloop]));
- /* dbg("new_slot->config_space[%x] = %x\n",
- cloop, new_slot->config_space[cloop]); */
- if (rc)
- return rc;
- }
-
- function++;
-
- stop_it = 0;
-
- /* this loop skips to the next present function
- * reading in Class Code and Header type.
- */
-
- while ((function < max_functions)&&(!stop_it)) {
- dbg("%s: In while loop \n", __FUNCTION__);
- rc = pci_bus_read_config_dword(pci_bus,
- PCI_DEVFN(device, function),
- PCI_VENDOR_ID, &ID);
-
- if (ID == 0xFFFFFFFF) { /* nothing there. */
- function++;
- dbg("Nothing there\n");
- } else { /* Something there */
- rc = pci_bus_read_config_byte(pci_bus,
- PCI_DEVFN(device, function),
- 0x0B, &class_code);
- if (rc)
- return rc;
-
- rc = pci_bus_read_config_byte(pci_bus,
- PCI_DEVFN(device, function),
- PCI_HEADER_TYPE, &header_type);
- if (rc)
- return rc;
-
- dbg("class_code = %x, header_type = %x\n", class_code, header_type);
- stop_it++;
- }
- }
-
- } 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 = pciehp_slot_create(busnumber);
-
- if (new_slot == NULL) {
- return(1);
- }
- dbg("new_slot = %p, bus = %x, dev = %x, fun = %x\n", new_slot,
- new_slot->bus, new_slot->device, new_slot->function);
-
- 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 */
-
- dbg("%s: Exit\n", __FUNCTION__);
- return(0);
-}
-
-
-/*
- * pciehp_save_slot_config
- *
- * Saves configuration info for all PCI devices in a given slot
- * including subordinate busses.
- *
- * returns 0 if success
- */
-int pciehp_save_slot_config(struct controller *ctrl, struct pci_func * new_slot)
-{
- int rc;
- u8 class_code;
- u8 header_type;
- u32 ID;
- u8 secondary_bus;
- int sub_bus;
- int max_functions;
- int function;
- int cloop = 0;
- int stop_it;
- struct pci_bus lpci_bus, *pci_bus;
- memcpy(&lpci_bus, ctrl->pci_dev->subordinate, sizeof(lpci_bus));
- pci_bus = &lpci_bus;
- pci_bus->number = new_slot->bus;
-
- ID = 0xFFFFFFFF;
-
- pci_bus_read_config_dword(pci_bus, PCI_DEVFN(new_slot->device, 0),
- PCI_VENDOR_ID, &ID);
-
- if (ID != 0xFFFFFFFF) { /* device in slot */
- pci_bus_read_config_byte(pci_bus, PCI_DEVFN(new_slot->device, 0),
- 0x0B, &class_code);
-
- pci_bus_read_config_byte(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(pci_bus,
- PCI_DEVFN(new_slot->device, function),
- PCI_SECONDARY_BUS, &secondary_bus);
-
- sub_bus = (int) secondary_bus;
-
- /* Save the config headers for the secondary bus. */
- rc = pciehp_save_config(ctrl, sub_bus, 0, 0);
-
- if (rc)
- return rc;
-
- } /* End of IF */
-
- new_slot->status = 0;
-
- for (cloop = 0; cloop < 0x20; cloop++) {
- pci_bus_read_config_dword(pci_bus,
- PCI_DEVFN(new_slot->device, function),
- cloop << 2,
- (u32 *) &(new_slot->config_space [cloop]));
- }
-
- function++;
-
- stop_it = 0;
-
- /* 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(pci_bus,
- PCI_DEVFN(new_slot->device, function),
- PCI_VENDOR_ID, &ID);
-
- if (ID == 0xFFFFFFFF) { /* nothing there. */
- function++;
- } else { /* Something there */
- pci_bus_read_config_byte(pci_bus,
- PCI_DEVFN(new_slot->device, function),
- 0x0B, &class_code);
-
- pci_bus_read_config_byte(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;
-}
-
-
-/*
- * pciehp_save_used_resources
- *
- * Stores used resource information for existing boards. this is
- * for boards that were in the system when this driver was loaded.
- * this function is for hot plug ADD
- *
- * returns 0 if success
- * if disable == 1(DISABLE_CARD),
- * it loops for all functions of the slot and disables them.
- * else, it just get resources of the function and return.
- */
-int pciehp_save_used_resources(struct controller *ctrl, struct pci_func *func, int disable)
-{
- u8 cloop;
- u8 header_type;
- u8 secondary_bus;
- u8 temp_byte;
- u16 command;
- u16 save_command;
- u16 w_base, w_length;
- u32 temp_register;
- u32 save_base;
- u32 base, length;
- u64 base64 = 0;
- int index = 0;
- unsigned int devfn;
- struct pci_resource *mem_node = NULL;
- struct pci_resource *p_mem_node = NULL;
- struct pci_resource *t_mem_node;
- struct pci_resource *io_node;
- struct pci_resource *bus_node;
- struct pci_bus lpci_bus, *pci_bus;
- memcpy(&lpci_bus, ctrl->pci_dev->subordinate, sizeof(lpci_bus));
- pci_bus = &lpci_bus;
-
- if (disable)
- func = pciehp_slot_find(func->bus, func->device, index++);
-
- while ((func != NULL) && func->is_a_board) {
- pci_bus->number = func->bus;
- devfn = PCI_DEVFN(func->device, func->function);
-
- /* Save the command register */
- pci_bus_read_config_word(pci_bus, devfn, PCI_COMMAND, &save_command);
-
- if (disable) {
- /* disable card */
- command = 0x00;
- pci_bus_write_config_word(pci_bus, devfn, PCI_COMMAND, command);
- }
-
- /* 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 */
- dbg("Save_used_res of PCI bridge b:d=0x%x:%x, sc=0x%x\n",
- func->bus, func->device, save_command);
- if (disable) {
- /* 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);
- pci_bus_read_config_byte(pci_bus, devfn, PCI_SUBORDINATE_BUS, &temp_byte);
-
- bus_node = kmalloc(sizeof(struct pci_resource),
- GFP_KERNEL);
- if (!bus_node)
- return -ENOMEM;
-
- bus_node->base = (ulong)secondary_bus;
- bus_node->length = (ulong)(temp_byte - secondary_bus + 1);
-
- bus_node->next = func->bus_head;
- func->bus_head = bus_node;
-
- /* Save IO base and Limit registers */
- pci_bus_read_config_byte(pci_bus, devfn, PCI_IO_BASE, &temp_byte);
- base = temp_byte;
- pci_bus_read_config_byte(pci_bus, devfn, PCI_IO_LIMIT, &temp_byte);
- length = temp_byte;
-
- if ((base <= length) && (!disable || (save_command & PCI_COMMAND_IO))) {
- io_node = kmalloc(sizeof(struct pci_resource),
- GFP_KERNEL);
- if (!io_node)
- return -ENOMEM;
-
- io_node->base = (ulong)(base & PCI_IO_RANGE_MASK) << 8;
- io_node->length = (ulong)(length - base + 0x10) << 8;
-
- io_node->next = func->io_head;
- func->io_head = io_node;
- }
-
- /* 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);
-
- if ((w_base <= w_length) && (!disable || (save_command & PCI_COMMAND_MEMORY))) {
- mem_node = kmalloc(sizeof(struct pci_resource),
- GFP_KERNEL);
- if (!mem_node)
- return -ENOMEM;
-
- mem_node->base = (ulong)w_base << 16;
- mem_node->length = (ulong)(w_length - w_base + 0x10) << 16;
-
- mem_node->next = func->mem_head;
- func->mem_head = mem_node;
- }
- /* 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);
-
- if ((w_base <= w_length) && (!disable || (save_command & PCI_COMMAND_MEMORY))) {
- p_mem_node = kmalloc(sizeof(struct pci_resource),
- GFP_KERNEL);
- if (!p_mem_node)
- return -ENOMEM;
-
- p_mem_node->base = (ulong)w_base << 16;
- p_mem_node->length = (ulong)(w_length - w_base + 0x10) << 16;
-
- p_mem_node->next = func->p_mem_head;
- func->p_mem_head = p_mem_node;
- }
- } else if ((header_type & 0x7F) == PCI_HEADER_TYPE_NORMAL) {
- dbg("Save_used_res of PCI adapter b:d=0x%x:%x, sc=0x%x\n",
- func->bus, func->device, save_command);
-
- /* Figure out IO and memory base lengths */
- for (cloop = PCI_BASE_ADDRESS_0; cloop <= PCI_BASE_ADDRESS_5; cloop += 4) {
- pci_bus_read_config_dword(pci_bus, devfn, cloop, &save_base);
-
- temp_register = 0xFFFFFFFF;
- pci_bus_write_config_dword(pci_bus, devfn, cloop, temp_register);
- pci_bus_read_config_dword(pci_bus, devfn, cloop, &temp_register);
-
- if (!disable)
- pci_bus_write_config_dword(pci_bus, devfn, cloop, save_base);
-
- if (!temp_register)
- continue;
-
- base = temp_register;
-
- if ((base & PCI_BASE_ADDRESS_SPACE_IO) &&
- (!disable || (save_command & PCI_COMMAND_IO))) {
- /* IO base */
- /* set temp_register = amount of IO space requested */
- base = base & 0xFFFFFFFCL;
- base = (~base) + 1;
-
- io_node = kmalloc(sizeof (struct pci_resource),
- GFP_KERNEL);
- if (!io_node)
- return -ENOMEM;
-
- io_node->base = (ulong)save_base & PCI_BASE_ADDRESS_IO_MASK;
- io_node->length = (ulong)base;
- dbg("sur adapter: IO bar=0x%x(length=0x%x)\n",
- io_node->base, io_node->length);
-
- io_node->next = func->io_head;
- func->io_head = io_node;
- } else { /* map Memory */
- int prefetchable = 1;
- /* struct pci_resources **res_node; */
- char *res_type_str = "PMEM";
- u32 temp_register2;
-
- t_mem_node = kmalloc(sizeof (struct pci_resource),
- GFP_KERNEL);
- if (!t_mem_node)
- return -ENOMEM;
-
- if (!(base & PCI_BASE_ADDRESS_MEM_PREFETCH) &&
- (!disable || (save_command & PCI_COMMAND_MEMORY))) {
- prefetchable = 0;
- mem_node = t_mem_node;
- res_type_str++;
- } else
- p_mem_node = t_mem_node;
-
- base = base & 0xFFFFFFF0L;
- base = (~base) + 1;
-
- switch (temp_register & PCI_BASE_ADDRESS_MEM_TYPE_MASK) {
- case PCI_BASE_ADDRESS_MEM_TYPE_32:
- if (prefetchable) {
- p_mem_node->base = (ulong)save_base & PCI_BASE_ADDRESS_MEM_MASK;
- p_mem_node->length = (ulong)base;
- dbg("sur adapter: 32 %s bar=0x%x(length=0x%x)\n",
- res_type_str,
- p_mem_node->base,
- p_mem_node->length);
-
- p_mem_node->next = func->p_mem_head;
- func->p_mem_head = p_mem_node;
- } else {
- mem_node->base = (ulong)save_base & PCI_BASE_ADDRESS_MEM_MASK;
- mem_node->length = (ulong)base;
- dbg("sur adapter: 32 %s bar=0x%x(length=0x%x)\n",
- res_type_str,
- mem_node->base,
- mem_node->length);
-
- mem_node->next = func->mem_head;
- func->mem_head = mem_node;
- }
- break;
- case PCI_BASE_ADDRESS_MEM_TYPE_64:
- pci_bus_read_config_dword(pci_bus, devfn, cloop+4, &temp_register2);
- base64 = temp_register2;
- base64 = (base64 << 32) | save_base;
-
- if (temp_register2) {
- dbg("sur adapter: 64 %s high dword of base64(0x%x:%x) masked to 0\n",
- res_type_str, temp_register2, (u32)base64);
- base64 &= 0x00000000FFFFFFFFL;
- }
-
- if (prefetchable) {
- p_mem_node->base = base64 & PCI_BASE_ADDRESS_MEM_MASK;
- p_mem_node->length = base;
- dbg("sur adapter: 64 %s base=0x%x(len=0x%x)\n",
- res_type_str,
- p_mem_node->base,
- p_mem_node->length);
-
- p_mem_node->next = func->p_mem_head;
- func->p_mem_head = p_mem_node;
- } else {
- mem_node->base = base64 & PCI_BASE_ADDRESS_MEM_MASK;
- mem_node->length = base;
- dbg("sur adapter: 64 %s base=0x%x(len=0x%x)\n",
- res_type_str,
- mem_node->base,
- mem_node->length);
-
- mem_node->next = func->mem_head;
- func->mem_head = mem_node;
- }
- cloop += 4;
- break;
- default:
- dbg("asur: reserved BAR type=0x%x\n",
- temp_register);
- break;
- }
- }
- } /* End of base register loop */
- } else { /* Some other unknown header type */
- dbg("Save_used_res of PCI unknown type b:d=0x%x:%x. skip.\n",
- func->bus, func->device);
- }
-
- /* find the next device in this slot */
- if (!disable)
- break;
- func = pciehp_slot_find(func->bus, func->device, index++);
- }
-
- return 0;
-}
-
-
-/**
- * kfree_resource_list: release memory of all list members
- * @res: resource list to free
- */
-static inline void
-return_resource_list(struct pci_resource **func, struct pci_resource **res)
-{
- struct pci_resource *node;
- struct pci_resource *t_node;
-
- node = *func;
- *func = NULL;
- while (node) {
- t_node = node->next;
- return_resource(res, node);
- node = t_node;
- }
-}
-
-/*
- * pciehp_return_board_resources
- *
- * this routine returns all resources allocated to a board to
- * the available pool.
- *
- * returns 0 if success
- */
-int pciehp_return_board_resources(struct pci_func * func,
- struct resource_lists * resources)
-{
- int rc;
-
- dbg("%s\n", __FUNCTION__);
-
- if (!func)
- return 1;
-
- return_resource_list(&(func->io_head),&(resources->io_head));
- return_resource_list(&(func->mem_head),&(resources->mem_head));
- return_resource_list(&(func->p_mem_head),&(resources->p_mem_head));
- return_resource_list(&(func->bus_head),&(resources->bus_head));
-
- rc = pciehp_resource_sort_and_combine(&(resources->mem_head));
- rc |= pciehp_resource_sort_and_combine(&(resources->p_mem_head));
- rc |= pciehp_resource_sort_and_combine(&(resources->io_head));
- rc |= pciehp_resource_sort_and_combine(&(resources->bus_head));
-
- return rc;
-}
-
-/**
- * kfree_resource_list: release memory of all list members
- * @res: resource list to free
- */
-static inline void
-kfree_resource_list(struct pci_resource **r)
-{
- struct pci_resource *res, *tres;
-
- res = *r;
- *r = NULL;
-
- while (res) {
- tres = res;
- res = res->next;
- kfree(tres);
- }
-}
-
-/**
- * pciehp_destroy_resource_list: put node back in the resource list
- * @resources: list to put nodes back
- */
-void pciehp_destroy_resource_list(struct resource_lists * resources)
-{
- kfree_resource_list(&(resources->io_head));
- kfree_resource_list(&(resources->mem_head));
- kfree_resource_list(&(resources->p_mem_head));
- kfree_resource_list(&(resources->bus_head));
-}
-
-/**
- * pciehp_destroy_board_resources: put node back in the resource list
- * @resources: list to put nodes back
- */
-void pciehp_destroy_board_resources(struct pci_func * func)
-{
- kfree_resource_list(&(func->io_head));
- kfree_resource_list(&(func->mem_head));
- kfree_resource_list(&(func->p_mem_head));
- kfree_resource_list(&(func->bus_head));
-}
diff --git a/drivers/pci/hotplug/pciehprm.h b/drivers/pci/hotplug/pciehprm.h
deleted file mode 100644
index 05f20fbc5f50..000000000000
--- a/drivers/pci/hotplug/pciehprm.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * PCIEHPRM : PCIEHP Resource Manager for ACPI/non-ACPI platform
- *
- * Copyright (C) 1995,2001 Compaq Computer Corporation
- * Copyright (C) 2001,2003 Greg Kroah-Hartman (greg@kroah.com)
- * Copyright (C) 2001 IBM Corp.
- * Copyright (C) 2003-2004 Intel Corporation
- *
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
- * NON INFRINGEMENT. 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.
- *
- * Send feedback to <greg@kroah.com>, <kristen.c.accardi@intel.com>
- *
- */
-
-#ifndef _PCIEHPRM_H_
-#define _PCIEHPRM_H_
-
-#ifdef CONFIG_HOTPLUG_PCI_PCIE_PHPRM_NONACPI
-#include "pciehprm_nonacpi.h"
-#endif
-
-int pciehprm_init(enum php_ctlr_type ct);
-void pciehprm_cleanup(void);
-int pciehprm_print_pirt(void);
-int pciehprm_find_available_resources(struct controller *ctrl);
-int pciehprm_set_hpp(struct controller *ctrl, struct pci_func *func, u8 card_type);
-void pciehprm_enable_card(struct controller *ctrl, struct pci_func *func, u8 card_type);
-
-#ifdef DEBUG
-#define RES_CHECK(this, bits) \
- { if (((this) & (bits - 1))) \
- printk("%s:%d ERR: potential res loss!\n", __FUNCTION__, __LINE__); }
-#else
-#define RES_CHECK(this, bits)
-#endif
-
-#endif /* _PCIEHPRM_H_ */
diff --git a/drivers/pci/hotplug/pciehprm_acpi.c b/drivers/pci/hotplug/pciehprm_acpi.c
index 1406db35b089..ae244e218620 100644
--- a/drivers/pci/hotplug/pciehprm_acpi.c
+++ b/drivers/pci/hotplug/pciehprm_acpi.c
@@ -24,100 +24,20 @@
*
*/
-#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/pci.h>
-#include <linux/init.h>
#include <linux/acpi.h>
-#include <linux/efi.h>
#include <linux/pci-acpi.h>
-#include <asm/uaccess.h>
-#include <asm/system.h>
-#ifdef CONFIG_IA64
-#include <asm/iosapic.h>
-#endif
-#include <acpi/acpi.h>
#include <acpi/acpi_bus.h>
#include <acpi/actypes.h>
#include "pciehp.h"
-#include "pciehprm.h"
-
-#define PCI_MAX_BUS 0x100
-#define ACPI_STA_DEVICE_PRESENT 0x01
#define METHOD_NAME__SUN "_SUN"
#define METHOD_NAME__HPP "_HPP"
#define METHOD_NAME_OSHP "OSHP"
-/* Status code for running acpi method to gain native control */
-#define NC_NOT_RUN 0
-#define OSC_NOT_EXIST 1
-#define OSC_RUN_FAILED 2
-#define OSHP_NOT_EXIST 3
-#define OSHP_RUN_FAILED 4
-#define NC_RUN_SUCCESS 5
-
-#define PHP_RES_BUS 0xA0
-#define PHP_RES_IO 0xA1
-#define PHP_RES_MEM 0xA2
-#define PHP_RES_PMEM 0xA3
-
-#define BRIDGE_TYPE_P2P 0x00
-#define BRIDGE_TYPE_HOST 0x01
-
-/* this should go to drivers/acpi/include/ */
-struct acpi__hpp {
- u8 cache_line_size;
- u8 latency_timer;
- u8 enable_serr;
- u8 enable_perr;
-};
-
-struct acpi_php_slot {
- struct acpi_php_slot *next;
- struct acpi_bridge *bridge;
- acpi_handle handle;
- int seg;
- int bus;
- int dev;
- int fun;
- u32 sun;
- struct pci_resource *mem_head;
- struct pci_resource *p_mem_head;
- struct pci_resource *io_head;
- struct pci_resource *bus_head;
- void *slot_ops; /* _STA, _EJx, etc */
- struct slot *slot;
-}; /* per func */
-
-struct acpi_bridge {
- struct acpi_bridge *parent;
- struct acpi_bridge *next;
- struct acpi_bridge *child;
- acpi_handle handle;
- int seg;
- int pbus; /* pdev->bus->number */
- int pdevice; /* PCI_SLOT(pdev->devfn) */
- int pfunction; /* PCI_DEVFN(pdev->devfn) */
- int bus; /* pdev->subordinate->number */
- struct acpi__hpp *_hpp;
- struct acpi_php_slot *slots;
- struct pci_resource *tmem_head; /* total from crs */
- struct pci_resource *tp_mem_head; /* total from crs */
- struct pci_resource *tio_head; /* total from crs */
- struct pci_resource *tbus_head; /* total from crs */
- struct pci_resource *mem_head; /* available */
- struct pci_resource *p_mem_head; /* available */
- struct pci_resource *io_head; /* available */
- struct pci_resource *bus_head; /* available */
- int scanned;
- int type;
-};
-
-static struct acpi_bridge *acpi_bridges_head;
-
static u8 * acpi_path_name( acpi_handle handle)
{
acpi_status status;
@@ -133,85 +53,43 @@ static u8 * acpi_path_name( acpi_handle handle)
return path_name;
}
-static void acpi_get__hpp ( struct acpi_bridge *ab);
-static int acpi_run_oshp ( struct acpi_bridge *ab);
-static int osc_run_status = NC_NOT_RUN;
-static int oshp_run_status = NC_NOT_RUN;
-
-static int acpi_add_slot_to_php_slots(
- struct acpi_bridge *ab,
- int bus_num,
- acpi_handle handle,
- u32 adr,
- u32 sun
- )
-{
- struct acpi_php_slot *aps;
- static long samesun = -1;
-
- aps = (struct acpi_php_slot *) kmalloc (sizeof(struct acpi_php_slot), GFP_KERNEL);
- if (!aps) {
- err ("acpi_pciehprm: alloc for aps fail\n");
- return -1;
- }
- memset(aps, 0, sizeof(struct acpi_php_slot));
-
- aps->handle = handle;
- aps->bus = bus_num;
- aps->dev = (adr >> 16) & 0xffff;
- aps->fun = adr & 0xffff;
- aps->sun = sun;
-
- aps->next = ab->slots; /* cling to the bridge */
- aps->bridge = ab;
- ab->slots = aps;
-
- ab->scanned += 1;
- if (!ab->_hpp)
- acpi_get__hpp(ab);
-
- if (osc_run_status == OSC_NOT_EXIST)
- oshp_run_status = acpi_run_oshp(ab);
-
- if (sun != samesun) {
- info("acpi_pciehprm: Slot sun(%x) at s:b:d:f=0x%02x:%02x:%02x:%02x\n",
- aps->sun, ab->seg, aps->bus, aps->dev, aps->fun);
- samesun = sun;
- }
- return 0;
-}
-
-static void acpi_get__hpp ( struct acpi_bridge *ab)
+static acpi_status
+acpi_run_hpp(acpi_handle handle, struct hotplug_params *hpp)
{
acpi_status status;
u8 nui[4];
struct acpi_buffer ret_buf = { 0, NULL};
union acpi_object *ext_obj, *package;
- u8 *path_name = acpi_path_name(ab->handle);
+ u8 *path_name = acpi_path_name(handle);
int i, len = 0;
/* get _hpp */
- status = acpi_evaluate_object(ab->handle, METHOD_NAME__HPP, NULL, &ret_buf);
+ status = acpi_evaluate_object(handle, METHOD_NAME__HPP, NULL, &ret_buf);
switch (status) {
case AE_BUFFER_OVERFLOW:
ret_buf.pointer = kmalloc (ret_buf.length, GFP_KERNEL);
if (!ret_buf.pointer) {
- err ("acpi_pciehprm:%s alloc for _HPP fail\n", path_name);
- return;
+ err ("%s:%s alloc for _HPP fail\n", __FUNCTION__,
+ path_name);
+ return AE_NO_MEMORY;
}
- status = acpi_evaluate_object(ab->handle, METHOD_NAME__HPP, NULL, &ret_buf);
+ status = acpi_evaluate_object(handle, METHOD_NAME__HPP,
+ NULL, &ret_buf);
if (ACPI_SUCCESS(status))
break;
default:
if (ACPI_FAILURE(status)) {
- err("acpi_pciehprm:%s _HPP fail=0x%x\n", path_name, status);
- return;
+ dbg("%s:%s _HPP fail=0x%x\n", __FUNCTION__,
+ path_name, status);
+ return status;
}
}
ext_obj = (union acpi_object *) ret_buf.pointer;
if (ext_obj->type != ACPI_TYPE_PACKAGE) {
- err ("acpi_pciehprm:%s _HPP obj not a package\n", path_name);
+ err ("%s:%s _HPP obj not a package\n", __FUNCTION__,
+ path_name);
+ status = AE_ERROR;
goto free_and_return;
}
@@ -224,1514 +102,153 @@ static void acpi_get__hpp ( struct acpi_bridge *ab)
nui[i] = (u8)ext_obj->integer.value;
break;
default:
- err ("acpi_pciehprm:%s _HPP obj type incorrect\n", path_name);
+ err ("%s:%s _HPP obj type incorrect\n", __FUNCTION__,
+ path_name);
+ status = AE_ERROR;
goto free_and_return;
}
}
- ab->_hpp = kmalloc (sizeof (struct acpi__hpp), GFP_KERNEL);
- if (!ab->_hpp) {
- err ("acpi_pciehprm:%s alloc for _HPP failed\n", path_name);
- goto free_and_return;
- }
- memset(ab->_hpp, 0, sizeof(struct acpi__hpp));
+ hpp->cache_line_size = nui[0];
+ hpp->latency_timer = nui[1];
+ hpp->enable_serr = nui[2];
+ hpp->enable_perr = nui[3];
- ab->_hpp->cache_line_size = nui[0];
- ab->_hpp->latency_timer = nui[1];
- ab->_hpp->enable_serr = nui[2];
- ab->_hpp->enable_perr = nui[3];
-
- dbg(" _HPP: cache_line_size=0x%x\n", ab->_hpp->cache_line_size);
- dbg(" _HPP: latency timer =0x%x\n", ab->_hpp->latency_timer);
- dbg(" _HPP: enable SERR =0x%x\n", ab->_hpp->enable_serr);
- dbg(" _HPP: enable PERR =0x%x\n", ab->_hpp->enable_perr);
+ dbg(" _HPP: cache_line_size=0x%x\n", hpp->cache_line_size);
+ dbg(" _HPP: latency timer =0x%x\n", hpp->latency_timer);
+ dbg(" _HPP: enable SERR =0x%x\n", hpp->enable_serr);
+ dbg(" _HPP: enable PERR =0x%x\n", hpp->enable_perr);
free_and_return:
kfree(ret_buf.pointer);
+ return status;
}
-static int acpi_run_oshp ( struct acpi_bridge *ab)
+static acpi_status acpi_run_oshp(acpi_handle handle)
{
acpi_status status;
- u8 *path_name = acpi_path_name(ab->handle);
+ u8 *path_name = acpi_path_name(handle);
/* run OSHP */
- status = acpi_evaluate_object(ab->handle, METHOD_NAME_OSHP, NULL, NULL);
+ status = acpi_evaluate_object(handle, METHOD_NAME_OSHP, NULL, NULL);
if (ACPI_FAILURE(status)) {
- err("acpi_pciehprm:%s OSHP fails=0x%x\n", path_name, status);
- oshp_run_status = (status == AE_NOT_FOUND) ? OSHP_NOT_EXIST : OSHP_RUN_FAILED;
+ dbg("%s:%s OSHP fails=0x%x\n", __FUNCTION__, path_name,
+ status);
} else {
- oshp_run_status = NC_RUN_SUCCESS;
- dbg("acpi_pciehprm:%s OSHP passes =0x%x\n", path_name, status);
- dbg("acpi_pciehprm:%s oshp_run_status =0x%x\n", path_name, oshp_run_status);
- }
- return oshp_run_status;
-}
-
-static acpi_status acpi_evaluate_crs(
- acpi_handle handle,
- struct acpi_resource **retbuf
- )
-{
- acpi_status status;
- struct acpi_buffer crsbuf;
- u8 *path_name = acpi_path_name(handle);
-
- crsbuf.length = 0;
- crsbuf.pointer = NULL;
-
- status = acpi_get_current_resources (handle, &crsbuf);
-
- switch (status) {
- case AE_BUFFER_OVERFLOW:
- break; /* found */
- case AE_NOT_FOUND:
- dbg("acpi_pciehprm:%s _CRS not found\n", path_name);
- return status;
- default:
- err ("acpi_pciehprm:%s _CRS fail=0x%x\n", path_name, status);
- return status;
+ dbg("%s:%s OSHP passes\n", __FUNCTION__, path_name);
}
-
- crsbuf.pointer = kmalloc (crsbuf.length, GFP_KERNEL);
- if (!crsbuf.pointer) {
- err ("acpi_pciehprm: alloc %ld bytes for %s _CRS fail\n", (ulong)crsbuf.length, path_name);
- return AE_NO_MEMORY;
- }
-
- status = acpi_get_current_resources (handle, &crsbuf);
- if (ACPI_FAILURE(status)) {
- err("acpi_pciehprm: %s _CRS fail=0x%x.\n", path_name, status);
- kfree(crsbuf.pointer);
- return status;
- }
-
- *retbuf = crsbuf.pointer;
-
return status;
}
-static void free_pci_resource ( struct pci_resource *aprh)
+static int is_root_bridge(acpi_handle handle)
{
- struct pci_resource *res, *next;
+ acpi_status status;
+ struct acpi_device_info *info;
+ struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
+ int i;
- for (res = aprh; res; res = next) {
- next = res->next;
- kfree(res);
- }
-}
-
-static void print_pci_resource ( struct pci_resource *aprh)
-{
- struct pci_resource *res;
-
- for (res = aprh; res; res = res->next)
- dbg(" base= 0x%x length= 0x%x\n", res->base, res->length);
-}
-
-static void print_slot_resources( struct acpi_php_slot *aps)
-{
- if (aps->bus_head) {
- dbg(" BUS Resources:\n");
- print_pci_resource (aps->bus_head);
- }
-
- if (aps->io_head) {
- dbg(" IO Resources:\n");
- print_pci_resource (aps->io_head);
- }
-
- if (aps->mem_head) {
- dbg(" MEM Resources:\n");
- print_pci_resource (aps->mem_head);
- }
-
- if (aps->p_mem_head) {
- dbg(" PMEM Resources:\n");
- print_pci_resource (aps->p_mem_head);
- }
-}
-
-static void print_pci_resources( struct acpi_bridge *ab)
-{
- if (ab->tbus_head) {
- dbg(" Total BUS Resources:\n");
- print_pci_resource (ab->tbus_head);
- }
- if (ab->bus_head) {
- dbg(" BUS Resources:\n");
- print_pci_resource (ab->bus_head);
- }
-
- if (ab->tio_head) {
- dbg(" Total IO Resources:\n");
- print_pci_resource (ab->tio_head);
- }
- if (ab->io_head) {
- dbg(" IO Resources:\n");
- print_pci_resource (ab->io_head);
- }
-
- if (ab->tmem_head) {
- dbg(" Total MEM Resources:\n");
- print_pci_resource (ab->tmem_head);
- }
- if (ab->mem_head) {
- dbg(" MEM Resources:\n");
- print_pci_resource (ab->mem_head);
- }
-
- if (ab->tp_mem_head) {
- dbg(" Total PMEM Resources:\n");
- print_pci_resource (ab->tp_mem_head);
- }
- if (ab->p_mem_head) {
- dbg(" PMEM Resources:\n");
- print_pci_resource (ab->p_mem_head);
- }
- if (ab->_hpp) {
- dbg(" _HPP: cache_line_size=0x%x\n", ab->_hpp->cache_line_size);
- dbg(" _HPP: latency timer =0x%x\n", ab->_hpp->latency_timer);
- dbg(" _HPP: enable SERR =0x%x\n", ab->_hpp->enable_serr);
- dbg(" _HPP: enable PERR =0x%x\n", ab->_hpp->enable_perr);
- }
-}
-
-static int pciehprm_delete_resource(
- struct pci_resource **aprh,
- ulong base,
- ulong size)
-{
- struct pci_resource *res;
- struct pci_resource *prevnode;
- struct pci_resource *split_node;
- ulong tbase;
-
- pciehp_resource_sort_and_combine(aprh);
-
- for (res = *aprh; res; res = res->next) {
- if (res->base > base)
- continue;
-
- if ((res->base + res->length) < (base + size))
- continue;
-
- if (res->base < base) {
- tbase = base;
-
- if ((res->length - (tbase - res->base)) < size)
- continue;
-
- split_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
- if (!split_node)
- return -ENOMEM;
-
- split_node->base = res->base;
- split_node->length = tbase - res->base;
- res->base = tbase;
- res->length -= split_node->length;
-
- split_node->next = res->next;
- res->next = split_node;
- }
-
- if (res->length >= size) {
- split_node = (struct pci_resource*) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
- if (!split_node)
- return -ENOMEM;
-
- split_node->base = res->base + size;
- split_node->length = res->length - size;
- res->length = size;
-
- split_node->next = res->next;
- res->next = split_node;
- }
-
- if (*aprh == res) {
- *aprh = res->next;
- } else {
- prevnode = *aprh;
- while (prevnode->next != res)
- prevnode = prevnode->next;
-
- prevnode->next = res->next;
- }
- res->next = NULL;
- kfree(res);
- break;
- }
-
- return 0;
-}
-
-static int pciehprm_delete_resources(
- struct pci_resource **aprh,
- struct pci_resource *this
- )
-{
- struct pci_resource *res;
-
- for (res = this; res; res = res->next)
- pciehprm_delete_resource(aprh, res->base, res->length);
-
- return 0;
-}
-
-static int pciehprm_add_resource(
- struct pci_resource **aprh,
- ulong base,
- ulong size)
-{
- struct pci_resource *res;
-
- for (res = *aprh; res; res = res->next) {
- if ((res->base + res->length) == base) {
- res->length += size;
- size = 0L;
- break;
+ status = acpi_get_object_info(handle, &buffer);
+ if (ACPI_SUCCESS(status)) {
+ info = buffer.pointer;
+ if ((info->valid & ACPI_VALID_HID) &&
+ !strcmp(PCI_ROOT_HID_STRING,
+ info->hardware_id.value)) {
+ acpi_os_free(buffer.pointer);
+ return 1;
+ }
+ if (info->valid & ACPI_VALID_CID) {
+ for (i=0; i < info->compatibility_id.count; i++) {
+ if (!strcmp(PCI_ROOT_HID_STRING,
+ info->compatibility_id.id[i].value)) {
+ acpi_os_free(buffer.pointer);
+ return 1;
+ }
+ }
}
- if (res->next == *aprh)
- break;
}
-
- if (size) {
- res = kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
- if (!res) {
- err ("acpi_pciehprm: alloc for res fail\n");
- return -ENOMEM;
- }
- memset(res, 0, sizeof (struct pci_resource));
-
- res->base = base;
- res->length = size;
- res->next = *aprh;
- *aprh = res;
- }
-
return 0;
}
-static int pciehprm_add_resources(
- struct pci_resource **aprh,
- struct pci_resource *this
- )
-{
- struct pci_resource *res;
- int rc = 0;
-
- for (res = this; res && !rc; res = res->next)
- rc = pciehprm_add_resource(aprh, res->base, res->length);
-
- return rc;
-}
-
-static void acpi_parse_io (
- struct acpi_bridge *ab,
- union acpi_resource_data *data
- )
+int pciehp_get_hp_hw_control_from_firmware(struct pci_dev *dev)
{
- struct acpi_resource_io *dataio;
- dataio = (struct acpi_resource_io *) data;
-
- dbg("Io Resource\n");
- dbg(" %d bit decode\n", ACPI_DECODE_16 == dataio->io_decode ? 16:10);
- dbg(" Range minimum base: %08X\n", dataio->min_base_address);
- dbg(" Range maximum base: %08X\n", dataio->max_base_address);
- dbg(" Alignment: %08X\n", dataio->alignment);
- dbg(" Range Length: %08X\n", dataio->range_length);
-}
-
-static void acpi_parse_fixed_io (
- struct acpi_bridge *ab,
- union acpi_resource_data *data
- )
-{
- struct acpi_resource_fixed_io *datafio;
- datafio = (struct acpi_resource_fixed_io *) data;
-
- dbg("Fixed Io Resource\n");
- dbg(" Range base address: %08X", datafio->base_address);
- dbg(" Range length: %08X", datafio->range_length);
-}
-
-static void acpi_parse_address16_32 (
- struct acpi_bridge *ab,
- union acpi_resource_data *data,
- acpi_resource_type id
- )
-{
- /*
- * acpi_resource_address16 == acpi_resource_address32
- * acpi_resource_address16 *data16 = (acpi_resource_address16 *) data;
+ acpi_status status;
+ acpi_handle chandle, handle = DEVICE_ACPI_HANDLE(&(dev->dev));
+ struct pci_dev *pdev = dev;
+ u8 *path_name;
+ /*
+ * Per PCI firmware specification, we should run the ACPI _OSC
+ * method to get control of hotplug hardware before using it.
+ * If an _OSC is missing, we look for an OSHP to do the same thing.
+ * To handle different BIOS behavior, we look for _OSC and OSHP
+ * within the scope of the hotplug controller and its parents, upto
+ * the host bridge under which this controller exists.
*/
- struct acpi_resource_address32 *data32 = (struct acpi_resource_address32 *) data;
- struct pci_resource **aprh, **tprh;
-
- if (id == ACPI_RSTYPE_ADDRESS16)
- dbg("acpi_pciehprm:16-Bit Address Space Resource\n");
- else
- dbg("acpi_pciehprm:32-Bit Address Space Resource\n");
-
- switch (data32->resource_type) {
- case ACPI_MEMORY_RANGE:
- dbg(" Resource Type: Memory Range\n");
- aprh = &ab->mem_head;
- tprh = &ab->tmem_head;
-
- switch (data32->attribute.memory.cache_attribute) {
- case ACPI_NON_CACHEABLE_MEMORY:
- dbg(" Type Specific: Noncacheable memory\n");
- break;
- case ACPI_CACHABLE_MEMORY:
- dbg(" Type Specific: Cacheable memory\n");
- break;
- case ACPI_WRITE_COMBINING_MEMORY:
- dbg(" Type Specific: Write-combining memory\n");
- break;
- case ACPI_PREFETCHABLE_MEMORY:
- aprh = &ab->p_mem_head;
- dbg(" Type Specific: Prefetchable memory\n");
- break;
- default:
- dbg(" Type Specific: Invalid cache attribute\n");
+ while (!handle) {
+ /*
+ * This hotplug controller was not listed in the ACPI name
+ * space at all. Try to get acpi handle of parent pci bus.
+ */
+ if (!pdev || !pdev->bus->parent)
break;
- }
-
- dbg(" Type Specific: Read%s\n", ACPI_READ_WRITE_MEMORY == data32->attribute.memory.read_write_attribute ? "/Write":" Only");
- break;
-
- case ACPI_IO_RANGE:
- dbg(" Resource Type: I/O Range\n");
- aprh = &ab->io_head;
- tprh = &ab->tio_head;
-
- switch (data32->attribute.io.range_attribute) {
- case ACPI_NON_ISA_ONLY_RANGES:
- dbg(" Type Specific: Non-ISA Io Addresses\n");
- break;
- case ACPI_ISA_ONLY_RANGES:
- dbg(" Type Specific: ISA Io Addresses\n");
- break;
- case ACPI_ENTIRE_RANGE:
- dbg(" Type Specific: ISA and non-ISA Io Addresses\n");
- break;
- default:
- dbg(" Type Specific: Invalid range attribute\n");
+ dbg("Could not find %s in acpi namespace, trying parent\n",
+ pci_name(pdev));
+ if (!pdev->bus->parent->self)
+ /* Parent must be a host bridge */
+ handle = acpi_get_pci_rootbridge_handle(
+ pci_domain_nr(pdev->bus->parent),
+ pdev->bus->parent->number);
+ else
+ handle = DEVICE_ACPI_HANDLE(
+ &(pdev->bus->parent->self->dev));
+ pdev = pdev->bus->parent->self;
+ }
+
+ while (handle) {
+ path_name = acpi_path_name(handle);
+ dbg("Trying to get hotplug control for %s \n", path_name);
+ status = pci_osc_control_set(handle,
+ OSC_PCI_EXPRESS_NATIVE_HP_CONTROL);
+ if (status == AE_NOT_FOUND)
+ status = acpi_run_oshp(handle);
+ if (ACPI_SUCCESS(status)) {
+ dbg("Gained control for hotplug HW for pci %s (%s)\n",
+ pci_name(dev), path_name);
+ return 0;
+ }
+ if (is_root_bridge(handle))
break;
- }
- break;
-
- case ACPI_BUS_NUMBER_RANGE:
- dbg(" Resource Type: Bus Number Range(fixed)\n");
- /* fixup to be compatible with the rest of php driver */
- data32->min_address_range++;
- data32->address_length--;
- aprh = &ab->bus_head;
- tprh = &ab->tbus_head;
- break;
- default:
- dbg(" Resource Type: Invalid resource type. Exiting.\n");
- return;
- }
-
- dbg(" Resource %s\n", ACPI_CONSUMER == data32->producer_consumer ? "Consumer":"Producer");
- dbg(" %s decode\n", ACPI_SUB_DECODE == data32->decode ? "Subtractive":"Positive");
- dbg(" Min address is %s fixed\n", ACPI_ADDRESS_FIXED == data32->min_address_fixed ? "":"not");
- dbg(" Max address is %s fixed\n", ACPI_ADDRESS_FIXED == data32->max_address_fixed ? "":"not");
- dbg(" Granularity: %08X\n", data32->granularity);
- dbg(" Address range min: %08X\n", data32->min_address_range);
- dbg(" Address range max: %08X\n", data32->max_address_range);
- dbg(" Address translation offset: %08X\n", data32->address_translation_offset);
- dbg(" Address Length: %08X\n", data32->address_length);
-
- if (0xFF != data32->resource_source.index) {
- dbg(" Resource Source Index: %X\n", data32->resource_source.index);
- /* dbg(" Resource Source: %s\n", data32->resource_source.string_ptr); */
- }
-
- pciehprm_add_resource(aprh, data32->min_address_range, data32->address_length);
-}
-
-static acpi_status acpi_parse_crs(
- struct acpi_bridge *ab,
- struct acpi_resource *crsbuf
- )
-{
- acpi_status status = AE_OK;
- struct acpi_resource *resource = crsbuf;
- u8 count = 0;
- u8 done = 0;
-
- while (!done) {
- dbg("acpi_pciehprm: PCI bus 0x%x Resource structure %x.\n", ab->bus, count++);
- switch (resource->id) {
- case ACPI_RSTYPE_IRQ:
- dbg("Irq -------- Resource\n");
- break;
- case ACPI_RSTYPE_DMA:
- dbg("DMA -------- Resource\n");
- break;
- case ACPI_RSTYPE_START_DPF:
- dbg("Start DPF -------- Resource\n");
- break;
- case ACPI_RSTYPE_END_DPF:
- dbg("End DPF -------- Resource\n");
- break;
- case ACPI_RSTYPE_IO:
- acpi_parse_io (ab, &resource->data);
- break;
- case ACPI_RSTYPE_FIXED_IO:
- acpi_parse_fixed_io (ab, &resource->data);
- break;
- case ACPI_RSTYPE_VENDOR:
- dbg("Vendor -------- Resource\n");
- break;
- case ACPI_RSTYPE_END_TAG:
- dbg("End_tag -------- Resource\n");
- done = 1;
- break;
- case ACPI_RSTYPE_MEM24:
- dbg("Mem24 -------- Resource\n");
- break;
- case ACPI_RSTYPE_MEM32:
- dbg("Mem32 -------- Resource\n");
- break;
- case ACPI_RSTYPE_FIXED_MEM32:
- dbg("Fixed Mem32 -------- Resource\n");
- break;
- case ACPI_RSTYPE_ADDRESS16:
- acpi_parse_address16_32(ab, &resource->data, ACPI_RSTYPE_ADDRESS16);
- break;
- case ACPI_RSTYPE_ADDRESS32:
- acpi_parse_address16_32(ab, &resource->data, ACPI_RSTYPE_ADDRESS32);
- break;
- case ACPI_RSTYPE_ADDRESS64:
- info("Address64 -------- Resource unparsed\n");
- break;
- case ACPI_RSTYPE_EXT_IRQ:
- dbg("Ext Irq -------- Resource\n");
- break;
- default:
- dbg("Invalid -------- resource type 0x%x\n", resource->id);
- break;
- }
-
- resource = (struct acpi_resource *) ((char *)resource + resource->length);
- }
-
- return status;
-}
-
-static acpi_status acpi_get_crs( struct acpi_bridge *ab)
-{
- acpi_status status;
- struct acpi_resource *crsbuf;
-
- status = acpi_evaluate_crs(ab->handle, &crsbuf);
- if (ACPI_SUCCESS(status)) {
- status = acpi_parse_crs(ab, crsbuf);
- kfree(crsbuf);
-
- pciehp_resource_sort_and_combine(&ab->bus_head);
- pciehp_resource_sort_and_combine(&ab->io_head);
- pciehp_resource_sort_and_combine(&ab->mem_head);
- pciehp_resource_sort_and_combine(&ab->p_mem_head);
-
- pciehprm_add_resources (&ab->tbus_head, ab->bus_head);
- pciehprm_add_resources (&ab->tio_head, ab->io_head);
- pciehprm_add_resources (&ab->tmem_head, ab->mem_head);
- pciehprm_add_resources (&ab->tp_mem_head, ab->p_mem_head);
- }
-
- return status;
-}
-
-/* find acpi_bridge downword from ab. */
-static struct acpi_bridge *
-find_acpi_bridge_by_bus(
- struct acpi_bridge *ab,
- int seg,
- int bus /* pdev->subordinate->number */
- )
-{
- struct acpi_bridge *lab = NULL;
-
- if (!ab)
- return NULL;
-
- if ((ab->bus == bus) && (ab->seg == seg))
- return ab;
-
- if (ab->child)
- lab = find_acpi_bridge_by_bus(ab->child, seg, bus);
-
- if (!lab)
- if (ab->next)
- lab = find_acpi_bridge_by_bus(ab->next, seg, bus);
-
- return lab;
-}
-
-/*
- * Build a device tree of ACPI PCI Bridges
- */
-static void pciehprm_acpi_register_a_bridge (
- struct acpi_bridge **head,
- struct acpi_bridge *pab, /* parent bridge to which child bridge is added */
- struct acpi_bridge *cab /* child bridge to add */
- )
-{
- struct acpi_bridge *lpab;
- struct acpi_bridge *lcab;
-
- lpab = find_acpi_bridge_by_bus(*head, pab->seg, pab->bus);
- if (!lpab) {
- if (!(pab->type & BRIDGE_TYPE_HOST))
- warn("PCI parent bridge s:b(%x:%x) not in list.\n", pab->seg, pab->bus);
- pab->next = *head;
- *head = pab;
- lpab = pab;
- }
-
- if ((cab->type & BRIDGE_TYPE_HOST) && (pab == cab))
- return;
-
- lcab = find_acpi_bridge_by_bus(*head, cab->seg, cab->bus);
- if (lcab) {
- if ((pab->bus != lcab->parent->bus) || (lcab->bus != cab->bus))
- err("PCI child bridge s:b(%x:%x) in list with diff parent.\n", cab->seg, cab->bus);
- return;
- } else
- lcab = cab;
-
- lcab->parent = lpab;
- lcab->next = lpab->child;
- lpab->child = lcab;
-}
-
-static acpi_status pciehprm_acpi_build_php_slots_callback(
- acpi_handle handle,
- u32 Level,
- void *context,
- void **retval
- )
-{
- ulong bus_num;
- ulong seg_num;
- ulong sun, adr;
- ulong padr = 0;
- acpi_handle phandle = NULL;
- struct acpi_bridge *pab = (struct acpi_bridge *)context;
- struct acpi_bridge *lab;
- acpi_status status;
- u8 *path_name = acpi_path_name(handle);
-
- /* get _SUN */
- status = acpi_evaluate_integer(handle, METHOD_NAME__SUN, NULL, &sun);
- switch(status) {
- case AE_NOT_FOUND:
- return AE_OK;
- default:
- if (ACPI_FAILURE(status)) {
- err("acpi_pciehprm:%s _SUN fail=0x%x\n", path_name, status);
- return status;
- }
- }
-
- /* get _ADR. _ADR must exist if _SUN exists */
- status = acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL, &adr);
- if (ACPI_FAILURE(status)) {
- err("acpi_pciehprm:%s _ADR fail=0x%x\n", path_name, status);
- return status;
- }
-
- dbg("acpi_pciehprm:%s sun=0x%08x adr=0x%08x\n", path_name, (u32)sun, (u32)adr);
-
- status = acpi_get_parent(handle, &phandle);
- if (ACPI_FAILURE(status)) {
- err("acpi_pciehprm:%s get_parent fail=0x%x\n", path_name, status);
- return (status);
- }
-
- bus_num = pab->bus;
- seg_num = pab->seg;
-
- if (pab->bus == bus_num) {
- lab = pab;
- } else {
- dbg("WARN: pab is not parent\n");
- lab = find_acpi_bridge_by_bus(pab, seg_num, bus_num);
- if (!lab) {
- dbg("acpi_pciehprm: alloc new P2P bridge(%x) for sun(%08x)\n", (u32)bus_num, (u32)sun);
- lab = (struct acpi_bridge *)kmalloc(sizeof(struct acpi_bridge), GFP_KERNEL);
- if (!lab) {
- err("acpi_pciehprm: alloc for ab fail\n");
- return AE_NO_MEMORY;
- }
- memset(lab, 0, sizeof(struct acpi_bridge));
-
- lab->handle = phandle;
- lab->pbus = pab->bus;
- lab->pdevice = (int)(padr >> 16) & 0xffff;
- lab->pfunction = (int)(padr & 0xffff);
- lab->bus = (int)bus_num;
- lab->scanned = 0;
- lab->type = BRIDGE_TYPE_P2P;
-
- pciehprm_acpi_register_a_bridge (&acpi_bridges_head, pab, lab);
- } else
- dbg("acpi_pciehprm: found P2P bridge(%x) for sun(%08x)\n", (u32)bus_num, (u32)sun);
- }
-
- acpi_add_slot_to_php_slots(lab, (int)bus_num, handle, (u32)adr, (u32)sun);
-
- return (status);
-}
-
-static int pciehprm_acpi_build_php_slots(
- struct acpi_bridge *ab,
- u32 depth
- )
-{
- acpi_status status;
- u8 *path_name = acpi_path_name(ab->handle);
-
- /* Walk down this pci bridge to get _SUNs if any behind P2P */
- status = acpi_walk_namespace ( ACPI_TYPE_DEVICE,
- ab->handle,
- depth,
- pciehprm_acpi_build_php_slots_callback,
- ab,
- NULL );
- if (ACPI_FAILURE(status)) {
- dbg("acpi_pciehprm:%s walk for _SUN on pci bridge seg:bus(%x:%x) fail=0x%x\n", path_name, ab->seg, ab->bus, status);
- return -1;
- }
-
- return 0;
-}
-
-static void build_a_bridge(
- struct acpi_bridge *pab,
- struct acpi_bridge *ab
- )
-{
- u8 *path_name = acpi_path_name(ab->handle);
-
- pciehprm_acpi_register_a_bridge (&acpi_bridges_head, pab, ab);
-
- switch (ab->type) {
- case BRIDGE_TYPE_HOST:
- dbg("acpi_pciehprm: Registered PCI HOST Bridge(%02x) on s:b:d:f(%02x:%02x:%02x:%02x) [%s]\n",
- ab->bus, ab->seg, ab->pbus, ab->pdevice, ab->pfunction, path_name);
- break;
- case BRIDGE_TYPE_P2P:
- dbg("acpi_pciehprm: Registered PCI P2P Bridge(%02x-%02x) on s:b:d:f(%02x:%02x:%02x:%02x) [%s]\n",
- ab->pbus, ab->bus, ab->seg, ab->pbus, ab->pdevice, ab->pfunction, path_name);
- break;
- };
-
- /* build any immediate PHP slots under this pci bridge */
- pciehprm_acpi_build_php_slots(ab, 1);
-}
-
-static struct acpi_bridge * add_p2p_bridge(
- acpi_handle handle,
- struct acpi_bridge *pab, /* parent */
- ulong adr
- )
-{
- struct acpi_bridge *ab;
- struct pci_dev *pdev;
- ulong devnum, funcnum;
- u8 *path_name = acpi_path_name(handle);
-
- ab = (struct acpi_bridge *) kmalloc (sizeof(struct acpi_bridge), GFP_KERNEL);
- if (!ab) {
- err("acpi_pciehprm: alloc for ab fail\n");
- return NULL;
- }
- memset(ab, 0, sizeof(struct acpi_bridge));
-
- devnum = (adr >> 16) & 0xffff;
- funcnum = adr & 0xffff;
-
- pdev = pci_find_slot(pab->bus, PCI_DEVFN(devnum, funcnum));
- if (!pdev || !pdev->subordinate) {
- err("acpi_pciehprm:%s is not a P2P Bridge\n", path_name);
- kfree(ab);
- return NULL;
- }
-
- ab->handle = handle;
- ab->seg = pab->seg;
- ab->pbus = pab->bus; /* or pdev->bus->number */
- ab->pdevice = devnum; /* or PCI_SLOT(pdev->devfn) */
- ab->pfunction = funcnum; /* or PCI_FUNC(pdev->devfn) */
- ab->bus = pdev->subordinate->number;
- ab->scanned = 0;
- ab->type = BRIDGE_TYPE_P2P;
-
- dbg("acpi_pciehprm: P2P(%x-%x) on pci=b:d:f(%x:%x:%x) acpi=b:d:f(%x:%x:%x) [%s]\n",
- pab->bus, ab->bus, pdev->bus->number, PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn),
- pab->bus, (u32)devnum, (u32)funcnum, path_name);
-
- build_a_bridge(pab, ab);
-
- return ab;
-}
-
-static acpi_status scan_p2p_bridge(
- acpi_handle handle,
- u32 Level,
- void *context,
- void **retval
- )
-{
- struct acpi_bridge *pab = (struct acpi_bridge *)context;
- struct acpi_bridge *ab;
- acpi_status status;
- ulong adr = 0;
- u8 *path_name = acpi_path_name(handle);
- ulong devnum, funcnum;
- struct pci_dev *pdev;
-
- /* get device, function */
- status = acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL, &adr);
- if (ACPI_FAILURE(status)) {
- if (status != AE_NOT_FOUND)
- err("acpi_pciehprm:%s _ADR fail=0x%x\n", path_name, status);
- return AE_OK;
- }
-
- devnum = (adr >> 16) & 0xffff;
- funcnum = adr & 0xffff;
-
- pdev = pci_find_slot(pab->bus, PCI_DEVFN(devnum, funcnum));
- if (!pdev)
- return AE_OK;
- if (!pdev->subordinate)
- return AE_OK;
-
- ab = add_p2p_bridge(handle, pab, adr);
- if (ab) {
- status = acpi_walk_namespace ( ACPI_TYPE_DEVICE,
- handle,
- (u32)1,
- scan_p2p_bridge,
- ab,
- NULL);
+ chandle = handle;
+ status = acpi_get_parent(chandle, &handle);
if (ACPI_FAILURE(status))
- dbg("acpi_pciehprm:%s find_p2p fail=0x%x\n", path_name, status);
- }
-
- return AE_OK;
-}
-
-static struct acpi_bridge * add_host_bridge(
- acpi_handle handle,
- ulong segnum,
- ulong busnum
- )
-{
- ulong adr = 0;
- acpi_status status;
- struct acpi_bridge *ab;
- u8 *path_name = acpi_path_name(handle);
-
- /* get device, function: host br adr is always 0000 though. */
- status = acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL, &adr);
- if (ACPI_FAILURE(status)) {
- err("acpi_pciehprm:%s _ADR fail=0x%x\n", path_name, status);
- return NULL;
- }
- dbg("acpi_pciehprm: ROOT PCI seg(0x%x)bus(0x%x)dev(0x%x)func(0x%x) [%s]\n", (u32)segnum,
- (u32)busnum, (u32)(adr >> 16) & 0xffff, (u32)adr & 0xffff, path_name);
-
- ab = (struct acpi_bridge *) kmalloc (sizeof(struct acpi_bridge), GFP_KERNEL);
- if (!ab) {
- err("acpi_pciehprm: alloc for ab fail\n");
- return NULL;
- }
- memset(ab, 0, sizeof(struct acpi_bridge));
-
- ab->handle = handle;
- ab->seg = (int)segnum;
- ab->bus = ab->pbus = (int)busnum;
- ab->pdevice = (int)(adr >> 16) & 0xffff;
- ab->pfunction = (int)(adr & 0xffff);
- ab->scanned = 0;
- ab->type = BRIDGE_TYPE_HOST;
-
- /* get root pci bridge's current resources */
- status = acpi_get_crs(ab);
- if (ACPI_FAILURE(status)) {
- err("acpi_pciehprm:%s evaluate _CRS fail=0x%x\n", path_name, status);
- kfree(ab);
- return NULL;
- }
-
- status = pci_osc_control_set (OSC_PCI_EXPRESS_NATIVE_HP_CONTROL);
- if (ACPI_FAILURE(status)) {
- err("%s: status %x\n", __FUNCTION__, status);
- osc_run_status = (status == AE_NOT_FOUND) ? OSC_NOT_EXIST : OSC_RUN_FAILED;
- } else {
- osc_run_status = NC_RUN_SUCCESS;
- }
- dbg("%s: osc_run_status %x\n", __FUNCTION__, osc_run_status);
-
- build_a_bridge(ab, ab);
-
- return ab;
-}
-
-static acpi_status acpi_scan_from_root_pci_callback (
- acpi_handle handle,
- u32 Level,
- void *context,
- void **retval
- )
-{
- ulong segnum = 0;
- ulong busnum = 0;
- acpi_status status;
- struct acpi_bridge *ab;
- u8 *path_name = acpi_path_name(handle);
-
- /* get bus number of this pci root bridge */
- status = acpi_evaluate_integer(handle, METHOD_NAME__SEG, NULL, &segnum);
- if (ACPI_FAILURE(status)) {
- if (status != AE_NOT_FOUND) {
- err("acpi_pciehprm:%s evaluate _SEG fail=0x%x\n", path_name, status);
- return status;
- }
- segnum = 0;
- }
-
- /* get bus number of this pci root bridge */
- status = acpi_evaluate_integer(handle, METHOD_NAME__BBN, NULL, &busnum);
- if (ACPI_FAILURE(status)) {
- err("acpi_pciehprm:%s evaluate _BBN fail=0x%x\n", path_name, status);
- return (status);
- }
-
- ab = add_host_bridge(handle, segnum, busnum);
- if (ab) {
- status = acpi_walk_namespace ( ACPI_TYPE_DEVICE,
- handle,
- 1,
- scan_p2p_bridge,
- ab,
- NULL);
- if (ACPI_FAILURE(status))
- dbg("acpi_pciehprm:%s find_p2p fail=0x%x\n", path_name, status);
+ break;
}
- return AE_OK;
+ err("Cannot get control of hotplug hardware for pci %s\n",
+ pci_name(dev));
+ return -1;
}
-static int pciehprm_acpi_scan_pci (void)
+void pciehp_get_hp_params_from_firmware(struct pci_dev *dev,
+ struct hotplug_params *hpp)
{
- acpi_status status;
+ acpi_status status = AE_NOT_FOUND;
+ struct pci_dev *pdev = dev;
/*
- * TBD: traverse LDM device tree with the help of
- * unified ACPI augmented for php device population.
+ * _HPP settings apply to all child buses, until another _HPP is
+ * encountered. If we don't find an _HPP for the input pci dev,
+ * look for it in the parent device scope since that would apply to
+ * this pci dev. If we don't find any _HPP, use hardcoded defaults
*/
- status = acpi_get_devices ( PCI_ROOT_HID_STRING,
- acpi_scan_from_root_pci_callback,
- NULL,
- NULL );
- if (ACPI_FAILURE(status)) {
- err("acpi_pciehprm:get_device PCI ROOT HID fail=0x%x\n", status);
- return -1;
- }
-
- return 0;
-}
-
-int pciehprm_init(enum php_ctlr_type ctlr_type)
-{
- int rc;
-
- if (ctlr_type != PCI)
- return -ENODEV;
-
- dbg("pciehprm ACPI init <enter>\n");
- acpi_bridges_head = NULL;
-
- /* construct PCI bus:device tree of acpi_handles */
- rc = pciehprm_acpi_scan_pci();
- if (rc)
- return rc;
-
- if ((oshp_run_status != NC_RUN_SUCCESS) && (osc_run_status != NC_RUN_SUCCESS)) {
- err("Fails to gain control of native hot-plug\n");
- rc = -ENODEV;
- }
-
- dbg("pciehprm ACPI init %s\n", (rc)?"fail":"success");
- return rc;
-}
-
-static void free_a_slot(struct acpi_php_slot *aps)
-{
- dbg(" free a php func of slot(0x%02x) on PCI b:d:f=0x%02x:%02x:%02x\n", aps->sun, aps->bus, aps->dev, aps->fun);
-
- free_pci_resource (aps->io_head);
- free_pci_resource (aps->bus_head);
- free_pci_resource (aps->mem_head);
- free_pci_resource (aps->p_mem_head);
-
- kfree(aps);
-}
-
-static void free_a_bridge( struct acpi_bridge *ab)
-{
- struct acpi_php_slot *aps, *next;
-
- switch (ab->type) {
- case BRIDGE_TYPE_HOST:
- dbg("Free ACPI PCI HOST Bridge(%x) [%s] on s:b:d:f(%x:%x:%x:%x)\n",
- ab->bus, acpi_path_name(ab->handle), ab->seg, ab->pbus, ab->pdevice, ab->pfunction);
- break;
- case BRIDGE_TYPE_P2P:
- dbg("Free ACPI PCI P2P Bridge(%x-%x) [%s] on s:b:d:f(%x:%x:%x:%x)\n",
- ab->pbus, ab->bus, acpi_path_name(ab->handle), ab->seg, ab->pbus, ab->pdevice, ab->pfunction);
- break;
- };
-
- /* free slots first */
- for (aps = ab->slots; aps; aps = next) {
- next = aps->next;
- free_a_slot(aps);
- }
-
- free_pci_resource (ab->io_head);
- free_pci_resource (ab->tio_head);
- free_pci_resource (ab->bus_head);
- free_pci_resource (ab->tbus_head);
- free_pci_resource (ab->mem_head);
- free_pci_resource (ab->tmem_head);
- free_pci_resource (ab->p_mem_head);
- free_pci_resource (ab->tp_mem_head);
-
- kfree(ab);
-}
-
-static void pciehprm_free_bridges ( struct acpi_bridge *ab)
-{
- if (!ab)
- return;
-
- if (ab->child)
- pciehprm_free_bridges (ab->child);
-
- if (ab->next)
- pciehprm_free_bridges (ab->next);
-
- free_a_bridge(ab);
-}
-
-void pciehprm_cleanup(void)
-{
- pciehprm_free_bridges (acpi_bridges_head);
-}
-
-static int get_number_of_slots (
- struct acpi_bridge *ab,
- int selfonly
- )
-{
- struct acpi_php_slot *aps;
- int prev_slot = -1;
- int slot_num = 0;
-
- for ( aps = ab->slots; aps; aps = aps->next)
- if (aps->dev != prev_slot) {
- prev_slot = aps->dev;
- slot_num++;
- }
-
- if (ab->child)
- slot_num += get_number_of_slots (ab->child, 0);
-
- if (selfonly)
- return slot_num;
-
- if (ab->next)
- slot_num += get_number_of_slots (ab->next, 0);
-
- return slot_num;
-}
-
-static int print_acpi_resources (struct acpi_bridge *ab)
-{
- struct acpi_php_slot *aps;
- int i;
-
- switch (ab->type) {
- case BRIDGE_TYPE_HOST:
- dbg("PCI HOST Bridge (%x) [%s]\n", ab->bus, acpi_path_name(ab->handle));
- break;
- case BRIDGE_TYPE_P2P:
- dbg("PCI P2P Bridge (%x-%x) [%s]\n", ab->pbus, ab->bus, acpi_path_name(ab->handle));
- break;
- };
-
- print_pci_resources (ab);
-
- for ( i = -1, aps = ab->slots; aps; aps = aps->next) {
- if (aps->dev == i)
- continue;
- dbg(" Slot sun(%x) s:b:d:f(%02x:%02x:%02x:%02x)\n", aps->sun, aps->seg, aps->bus, aps->dev, aps->fun);
- print_slot_resources(aps);
- i = aps->dev;
- }
-
- if (ab->child)
- print_acpi_resources (ab->child);
-
- if (ab->next)
- print_acpi_resources (ab->next);
-
- return 0;
-}
-
-int pciehprm_print_pirt(void)
-{
- dbg("PCIEHPRM ACPI Slots\n");
- if (acpi_bridges_head)
- print_acpi_resources (acpi_bridges_head);
-
- return 0;
-}
-
-static struct acpi_php_slot * get_acpi_slot (
- struct acpi_bridge *ab,
- u32 sun
- )
-{
- struct acpi_php_slot *aps = NULL;
-
- for ( aps = ab->slots; aps; aps = aps->next)
- if (aps->sun == sun)
- return aps;
-
- if (!aps && ab->child) {
- aps = (struct acpi_php_slot *)get_acpi_slot (ab->child, sun);
- if (aps)
- return aps;
- }
-
- if (!aps && ab->next) {
- aps = (struct acpi_php_slot *)get_acpi_slot (ab->next, sun);
- if (aps)
- return aps;
- }
-
- return aps;
-
-}
-
-#if 0
-void * pciehprm_get_slot(struct slot *slot)
-{
- struct acpi_bridge *ab = acpi_bridges_head;
- struct acpi_php_slot *aps = get_acpi_slot (ab, slot->number);
-
- aps->slot = slot;
-
- dbg("Got acpi slot sun(%x): s:b:d:f(%x:%x:%x:%x)\n", aps->sun, aps->seg, aps->bus, aps->dev, aps->fun);
-
- return (void *)aps;
-}
-#endif
-
-static void pciehprm_dump_func_res( struct pci_func *fun)
-{
- struct pci_func *func = fun;
-
- if (func->bus_head) {
- dbg(": BUS Resources:\n");
- print_pci_resource (func->bus_head);
- }
- if (func->io_head) {
- dbg(": IO Resources:\n");
- print_pci_resource (func->io_head);
- }
- if (func->mem_head) {
- dbg(": MEM Resources:\n");
- print_pci_resource (func->mem_head);
- }
- if (func->p_mem_head) {
- dbg(": PMEM Resources:\n");
- print_pci_resource (func->p_mem_head);
- }
-}
-
-static void pciehprm_dump_ctrl_res( struct controller *ctlr)
-{
- struct controller *ctrl = ctlr;
-
- if (ctrl->bus_head) {
- dbg(": BUS Resources:\n");
- print_pci_resource (ctrl->bus_head);
- }
- if (ctrl->io_head) {
- dbg(": IO Resources:\n");
- print_pci_resource (ctrl->io_head);
- }
- if (ctrl->mem_head) {
- dbg(": MEM Resources:\n");
- print_pci_resource (ctrl->mem_head);
- }
- if (ctrl->p_mem_head) {
- dbg(": PMEM Resources:\n");
- print_pci_resource (ctrl->p_mem_head);
- }
-}
-
-static int pciehprm_get_used_resources (
- struct controller *ctrl,
- struct pci_func *func
- )
-{
- return pciehp_save_used_resources (ctrl, func, !DISABLE_CARD);
-}
-
-static int configure_existing_function(
- struct controller *ctrl,
- struct pci_func *func
- )
-{
- int rc;
-
- /* see how much resources the func has used. */
- rc = pciehprm_get_used_resources (ctrl, func);
-
- if (!rc) {
- /* subtract the resources used by the func from ctrl resources */
- rc = pciehprm_delete_resources (&ctrl->bus_head, func->bus_head);
- rc |= pciehprm_delete_resources (&ctrl->io_head, func->io_head);
- rc |= pciehprm_delete_resources (&ctrl->mem_head, func->mem_head);
- rc |= pciehprm_delete_resources (&ctrl->p_mem_head, func->p_mem_head);
- if (rc)
- warn("aCEF: cannot del used resources\n");
- } else
- err("aCEF: cannot get used resources\n");
-
- return rc;
-}
-
-static int bind_pci_resources_to_slots ( struct controller *ctrl)
-{
- struct pci_func *func, new_func;
- int busn = ctrl->slot_bus;
- int devn, funn;
- u32 vid;
-
- for (devn = 0; devn < 32; devn++) {
- for (funn = 0; funn < 8; funn++) {
- /*
- if (devn == ctrl->device && funn == ctrl->function)
- continue;
- */
- /* find out if this entry is for an occupied slot */
- vid = 0xFFFFFFFF;
- pci_bus_read_config_dword(ctrl->pci_dev->subordinate, PCI_DEVFN(devn, funn), PCI_VENDOR_ID, &vid);
-
- if (vid != 0xFFFFFFFF) {
- dbg("%s: vid = %x\n", __FUNCTION__, vid);
- func = pciehp_slot_find(busn, devn, funn);
- if (!func) {
- memset(&new_func, 0, sizeof(struct pci_func));
- new_func.bus = busn;
- new_func.device = devn;
- new_func.function = funn;
- new_func.is_a_board = 1;
- configure_existing_function(ctrl, &new_func);
- pciehprm_dump_func_res(&new_func);
- } else {
- configure_existing_function(ctrl, func);
- pciehprm_dump_func_res(func);
- }
- dbg("aCCF:existing PCI 0x%x Func ResourceDump\n", ctrl->bus);
- }
- }
- }
-
- return 0;
-}
-
-static int bind_pci_resources(
- struct controller *ctrl,
- struct acpi_bridge *ab
- )
-{
- int status = 0;
-
- if (ab->bus_head) {
- dbg("bapr: BUS Resources add on PCI 0x%x\n", ab->bus);
- status = pciehprm_add_resources (&ctrl->bus_head, ab->bus_head);
- if (pciehprm_delete_resources (&ab->bus_head, ctrl->bus_head))
- warn("bapr: cannot sub BUS Resource on PCI 0x%x\n", ab->bus);
- if (status) {
- err("bapr: BUS Resource add on PCI 0x%x: fail=0x%x\n", ab->bus, status);
- return status;
- }
- } else
- info("bapr: No BUS Resource on PCI 0x%x.\n", ab->bus);
-
- if (ab->io_head) {
- dbg("bapr: IO Resources add on PCI 0x%x\n", ab->bus);
- status = pciehprm_add_resources (&ctrl->io_head, ab->io_head);
- if (pciehprm_delete_resources (&ab->io_head, ctrl->io_head))
- warn("bapr: cannot sub IO Resource on PCI 0x%x\n", ab->bus);
- if (status) {
- err("bapr: IO Resource add on PCI 0x%x: fail=0x%x\n", ab->bus, status);
- return status;
- }
- } else
- info("bapr: No IO Resource on PCI 0x%x.\n", ab->bus);
-
- if (ab->mem_head) {
- dbg("bapr: MEM Resources add on PCI 0x%x\n", ab->bus);
- status = pciehprm_add_resources (&ctrl->mem_head, ab->mem_head);
- if (pciehprm_delete_resources (&ab->mem_head, ctrl->mem_head))
- warn("bapr: cannot sub MEM Resource on PCI 0x%x\n", ab->bus);
- if (status) {
- err("bapr: MEM Resource add on PCI 0x%x: fail=0x%x\n", ab->bus, status);
- return status;
- }
- } else
- info("bapr: No MEM Resource on PCI 0x%x.\n", ab->bus);
-
- if (ab->p_mem_head) {
- dbg("bapr: PMEM Resources add on PCI 0x%x\n", ab->bus);
- status = pciehprm_add_resources (&ctrl->p_mem_head, ab->p_mem_head);
- if (pciehprm_delete_resources (&ab->p_mem_head, ctrl->p_mem_head))
- warn("bapr: cannot sub PMEM Resource on PCI 0x%x\n", ab->bus);
- if (status) {
- err("bapr: PMEM Resource add on PCI 0x%x: fail=0x%x\n", ab->bus, status);
- return status;
- }
- } else
- info("bapr: No PMEM Resource on PCI 0x%x.\n", ab->bus);
-
- return status;
-}
-
-static int no_pci_resources( struct acpi_bridge *ab)
-{
- return !(ab->p_mem_head || ab->mem_head || ab->io_head || ab->bus_head);
-}
-
-static int find_pci_bridge_resources (
- struct controller *ctrl,
- struct acpi_bridge *ab
- )
-{
- int rc = 0;
- struct pci_func func;
-
- memset(&func, 0, sizeof(struct pci_func));
-
- func.bus = ab->pbus;
- func.device = ab->pdevice;
- func.function = ab->pfunction;
- func.is_a_board = 1;
-
- /* Get used resources for this PCI bridge */
- rc = pciehp_save_used_resources (ctrl, &func, !DISABLE_CARD);
-
- ab->io_head = func.io_head;
- ab->mem_head = func.mem_head;
- ab->p_mem_head = func.p_mem_head;
- ab->bus_head = func.bus_head;
- if (ab->bus_head)
- pciehprm_delete_resource(&ab->bus_head, ctrl->pci_dev->subordinate->number, 1);
-
- return rc;
-}
-
-static int get_pci_resources_from_bridge(
- struct controller *ctrl,
- struct acpi_bridge *ab
- )
-{
- int rc = 0;
-
- dbg("grfb: Get Resources for PCI 0x%x from actual PCI bridge 0x%x.\n", ctrl->bus, ab->bus);
-
- rc = find_pci_bridge_resources (ctrl, ab);
-
- pciehp_resource_sort_and_combine(&ab->bus_head);
- pciehp_resource_sort_and_combine(&ab->io_head);
- pciehp_resource_sort_and_combine(&ab->mem_head);
- pciehp_resource_sort_and_combine(&ab->p_mem_head);
-
- pciehprm_add_resources (&ab->tbus_head, ab->bus_head);
- pciehprm_add_resources (&ab->tio_head, ab->io_head);
- pciehprm_add_resources (&ab->tmem_head, ab->mem_head);
- pciehprm_add_resources (&ab->tp_mem_head, ab->p_mem_head);
-
- return rc;
-}
-
-static int get_pci_resources(
- struct controller *ctrl,
- struct acpi_bridge *ab
- )
-{
- int rc = 0;
-
- if (no_pci_resources(ab)) {
- dbg("spbr:PCI 0x%x has no resources. Get parent resources.\n", ab->bus);
- rc = get_pci_resources_from_bridge(ctrl, ab);
- }
-
- return rc;
-}
-
-/*
- * Get resources for this ctrl.
- * 1. get total resources from ACPI _CRS or bridge (this ctrl)
- * 2. find used resources of existing adapters
- * 3. subtract used resources from total resources
- */
-int pciehprm_find_available_resources( struct controller *ctrl)
-{
- int rc = 0;
- struct acpi_bridge *ab;
-
- ab = find_acpi_bridge_by_bus(acpi_bridges_head, ctrl->seg, ctrl->pci_dev->subordinate->number);
- if (!ab) {
- err("pfar:cannot locate acpi bridge of PCI 0x%x.\n", ctrl->pci_dev->subordinate->number);
- return -1;
- }
- if (no_pci_resources(ab)) {
- rc = get_pci_resources(ctrl, ab);
- if (rc) {
- err("pfar:cannot get pci resources of PCI 0x%x.\n", ctrl->pci_dev->subordinate->number);
- return -1;
- }
- }
-
- rc = bind_pci_resources(ctrl, ab);
- dbg("pfar:pre-Bind PCI 0x%x Ctrl Resource Dump\n", ctrl->pci_dev->subordinate->number);
- pciehprm_dump_ctrl_res(ctrl);
-
- bind_pci_resources_to_slots (ctrl);
-
- dbg("pfar:post-Bind PCI 0x%x Ctrl Resource Dump\n", ctrl->pci_dev->subordinate->number);
- pciehprm_dump_ctrl_res(ctrl);
-
- return rc;
-}
-
-int pciehprm_set_hpp(
- struct controller *ctrl,
- struct pci_func *func,
- u8 card_type
- )
-{
- struct acpi_bridge *ab;
- struct pci_bus lpci_bus, *pci_bus;
- int rc = 0;
- unsigned int devfn;
- u8 cls= 0x08; /* default cache line size */
- u8 lt = 0x40; /* default latency timer */
- u8 ep = 0;
- u8 es = 0;
-
- memcpy(&lpci_bus, ctrl->pci_bus, sizeof(lpci_bus));
- pci_bus = &lpci_bus;
- pci_bus->number = func->bus;
- devfn = PCI_DEVFN(func->device, func->function);
-
- ab = find_acpi_bridge_by_bus(acpi_bridges_head, ctrl->seg, ctrl->bus);
-
- if (ab) {
- if (ab->_hpp) {
- lt = (u8)ab->_hpp->latency_timer;
- cls = (u8)ab->_hpp->cache_line_size;
- ep = (u8)ab->_hpp->enable_perr;
- es = (u8)ab->_hpp->enable_serr;
- } else
- dbg("_hpp: no _hpp for B/D/F=%#x/%#x/%#x. use default value\n", func->bus, func->device, func->function);
- } else
- dbg("_hpp: no acpi bridge for B/D/F = %#x/%#x/%#x. use default value\n", func->bus, func->device, func->function);
-
-
- if (card_type == PCI_HEADER_TYPE_BRIDGE) {
- /* set subordinate Latency Timer */
- rc |= pci_bus_write_config_byte(pci_bus, devfn, PCI_SEC_LATENCY_TIMER, lt);
+ while (pdev && (ACPI_FAILURE(status))) {
+ acpi_handle handle = DEVICE_ACPI_HANDLE(&(pdev->dev));
+ if (!handle)
+ break;
+ status = acpi_run_hpp(handle, hpp);
+ if (!(pdev->bus->parent))
+ break;
+ /* Check if a parent object supports _HPP */
+ pdev = pdev->bus->parent->self;
}
-
- /* set base Latency Timer */
- rc |= pci_bus_write_config_byte(pci_bus, devfn, PCI_LATENCY_TIMER, lt);
- dbg(" set latency timer =0x%02x: %x\n", lt, rc);
-
- rc |= pci_bus_write_config_byte(pci_bus, devfn, PCI_CACHE_LINE_SIZE, cls);
- dbg(" set cache_line_size=0x%02x: %x\n", cls, rc);
-
- return rc;
}
-void pciehprm_enable_card(
- struct controller *ctrl,
- struct pci_func *func,
- u8 card_type)
-{
- u16 command, cmd, bcommand, bcmd;
- struct pci_bus lpci_bus, *pci_bus;
- struct acpi_bridge *ab;
- unsigned int devfn;
- int rc;
-
- memcpy(&lpci_bus, ctrl->pci_bus, sizeof(lpci_bus));
- pci_bus = &lpci_bus;
- pci_bus->number = func->bus;
- devfn = PCI_DEVFN(func->device, func->function);
-
- rc = pci_bus_read_config_word(pci_bus, devfn, PCI_COMMAND, &cmd);
-
- if (card_type == PCI_HEADER_TYPE_BRIDGE) {
- rc = pci_bus_read_config_word(pci_bus, devfn, PCI_BRIDGE_CONTROL, &bcmd);
- }
-
- command = cmd | PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE
- | PCI_COMMAND_IO | PCI_COMMAND_MEMORY;
- bcommand = bcmd | PCI_BRIDGE_CTL_NO_ISA;
-
- ab = find_acpi_bridge_by_bus(acpi_bridges_head, ctrl->seg, ctrl->bus);
- if (ab) {
- if (ab->_hpp) {
- if (ab->_hpp->enable_perr) {
- command |= PCI_COMMAND_PARITY;
- bcommand |= PCI_BRIDGE_CTL_PARITY;
- } else {
- command &= ~PCI_COMMAND_PARITY;
- bcommand &= ~PCI_BRIDGE_CTL_PARITY;
- }
- if (ab->_hpp->enable_serr) {
- command |= PCI_COMMAND_SERR;
- bcommand |= PCI_BRIDGE_CTL_SERR;
- } else {
- command &= ~PCI_COMMAND_SERR;
- bcommand &= ~PCI_BRIDGE_CTL_SERR;
- }
- } else
- dbg("no _hpp for B/D/F = %#x/%#x/%#x.\n", func->bus, func->device, func->function);
- } else
- dbg("no acpi bridge for B/D/F = %#x/%#x/%#x.\n", func->bus, func->device, func->function);
-
- if (command != cmd) {
- rc = pci_bus_write_config_word(pci_bus, devfn, PCI_COMMAND, command);
- }
- if ((card_type == PCI_HEADER_TYPE_BRIDGE) && (bcommand != bcmd)) {
- rc = pci_bus_write_config_word(pci_bus, devfn, PCI_BRIDGE_CONTROL, bcommand);
- }
-}
diff --git a/drivers/pci/hotplug/pciehprm_nonacpi.c b/drivers/pci/hotplug/pciehprm_nonacpi.c
index 3622965f8961..29180dfe8493 100644
--- a/drivers/pci/hotplug/pciehprm_nonacpi.c
+++ b/drivers/pci/hotplug/pciehprm_nonacpi.c
@@ -27,475 +27,21 @@
*
*/
-#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/types.h>
+#include <linux/sched.h>
#include <linux/pci.h>
-#include <linux/init.h>
-#include <asm/uaccess.h>
-#ifdef CONFIG_IA64
-#include <asm/iosapic.h>
-#endif
+#include <linux/slab.h>
#include "pciehp.h"
-#include "pciehprm.h"
-#include "pciehprm_nonacpi.h"
-
-void pciehprm_cleanup(void)
+void pciehp_get_hp_params_from_firmware(struct pci_dev *dev,
+ struct hotplug_params *hpp)
{
return;
}
-int pciehprm_print_pirt(void)
-{
- return 0;
-}
-
-int pciehprm_get_physical_slot_number(struct controller *ctrl, u32 *sun, u8 busnum, u8 devnum)
-{
-
- *sun = (u8) (ctrl->first_slot);
- return 0;
-}
-
-
-static void print_pci_resource ( struct pci_resource *aprh)
-{
- struct pci_resource *res;
-
- for (res = aprh; res; res = res->next)
- dbg(" base= 0x%x length= 0x%x\n", res->base, res->length);
-}
-
-
-static void phprm_dump_func_res( struct pci_func *fun)
-{
- struct pci_func *func = fun;
-
- if (func->bus_head) {
- dbg(": BUS Resources:\n");
- print_pci_resource (func->bus_head);
- }
- if (func->io_head) {
- dbg(": IO Resources:\n");
- print_pci_resource (func->io_head);
- }
- if (func->mem_head) {
- dbg(": MEM Resources:\n");
- print_pci_resource (func->mem_head);
- }
- if (func->p_mem_head) {
- dbg(": PMEM Resources:\n");
- print_pci_resource (func->p_mem_head);
- }
-}
-
-static int phprm_get_used_resources (
- struct controller *ctrl,
- struct pci_func *func
- )
-{
- return pciehp_save_used_resources (ctrl, func, !DISABLE_CARD);
-}
-
-static int phprm_delete_resource(
- struct pci_resource **aprh,
- ulong base,
- ulong size)
-{
- struct pci_resource *res;
- struct pci_resource *prevnode;
- struct pci_resource *split_node;
- ulong tbase;
-
- pciehp_resource_sort_and_combine(aprh);
-
- for (res = *aprh; res; res = res->next) {
- if (res->base > base)
- continue;
-
- if ((res->base + res->length) < (base + size))
- continue;
-
- if (res->base < base) {
- tbase = base;
-
- if ((res->length - (tbase - res->base)) < size)
- continue;
-
- split_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
- if (!split_node)
- return -ENOMEM;
-
- split_node->base = res->base;
- split_node->length = tbase - res->base;
- res->base = tbase;
- res->length -= split_node->length;
-
- split_node->next = res->next;
- res->next = split_node;
- }
-
- if (res->length >= size) {
- split_node = (struct pci_resource*) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
- if (!split_node)
- return -ENOMEM;
-
- split_node->base = res->base + size;
- split_node->length = res->length - size;
- res->length = size;
-
- split_node->next = res->next;
- res->next = split_node;
- }
-
- if (*aprh == res) {
- *aprh = res->next;
- } else {
- prevnode = *aprh;
- while (prevnode->next != res)
- prevnode = prevnode->next;
-
- prevnode->next = res->next;
- }
- res->next = NULL;
- kfree(res);
- break;
- }
-
- return 0;
-}
-
-
-static int phprm_delete_resources(
- struct pci_resource **aprh,
- struct pci_resource *this
- )
-{
- struct pci_resource *res;
-
- for (res = this; res; res = res->next)
- phprm_delete_resource(aprh, res->base, res->length);
-
- return 0;
-}
-
-
-static int configure_existing_function(
- struct controller *ctrl,
- struct pci_func *func
- )
-{
- int rc;
-
- /* see how much resources the func has used. */
- rc = phprm_get_used_resources (ctrl, func);
-
- if (!rc) {
- /* subtract the resources used by the func from ctrl resources */
- rc = phprm_delete_resources (&ctrl->bus_head, func->bus_head);
- rc |= phprm_delete_resources (&ctrl->io_head, func->io_head);
- rc |= phprm_delete_resources (&ctrl->mem_head, func->mem_head);
- rc |= phprm_delete_resources (&ctrl->p_mem_head, func->p_mem_head);
- if (rc)
- warn("aCEF: cannot del used resources\n");
- } else
- err("aCEF: cannot get used resources\n");
-
- return rc;
-}
-
-static int pciehprm_delete_resource(
- struct pci_resource **aprh,
- ulong base,
- ulong size)
-{
- struct pci_resource *res;
- struct pci_resource *prevnode;
- struct pci_resource *split_node;
- ulong tbase;
-
- pciehp_resource_sort_and_combine(aprh);
-
- for (res = *aprh; res; res = res->next) {
- if (res->base > base)
- continue;
-
- if ((res->base + res->length) < (base + size))
- continue;
-
- if (res->base < base) {
- tbase = base;
-
- if ((res->length - (tbase - res->base)) < size)
- continue;
-
- split_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
- if (!split_node)
- return -ENOMEM;
-
- split_node->base = res->base;
- split_node->length = tbase - res->base;
- res->base = tbase;
- res->length -= split_node->length;
-
- split_node->next = res->next;
- res->next = split_node;
- }
-
- if (res->length >= size) {
- split_node = (struct pci_resource*) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
- if (!split_node)
- return -ENOMEM;
-
- split_node->base = res->base + size;
- split_node->length = res->length - size;
- res->length = size;
-
- split_node->next = res->next;
- res->next = split_node;
- }
-
- if (*aprh == res) {
- *aprh = res->next;
- } else {
- prevnode = *aprh;
- while (prevnode->next != res)
- prevnode = prevnode->next;
-
- prevnode->next = res->next;
- }
- res->next = NULL;
- kfree(res);
- break;
- }
-
- return 0;
-}
-
-static int bind_pci_resources_to_slots ( struct controller *ctrl)
-{
- struct pci_func *func, new_func;
- int busn = ctrl->slot_bus;
- int devn, funn;
- u32 vid;
-
- for (devn = 0; devn < 32; devn++) {
- for (funn = 0; funn < 8; funn++) {
- /*
- if (devn == ctrl->device && funn == ctrl->function)
- continue;
- */
- /* find out if this entry is for an occupied slot */
- vid = 0xFFFFFFFF;
-
- pci_bus_read_config_dword(ctrl->pci_dev->subordinate, PCI_DEVFN(devn, funn), PCI_VENDOR_ID, &vid);
-
- if (vid != 0xFFFFFFFF) {
- dbg("%s: vid = %x bus %x dev %x fun %x\n", __FUNCTION__,
- vid, busn, devn, funn);
- func = pciehp_slot_find(busn, devn, funn);
- dbg("%s: func = %p\n", __FUNCTION__,func);
- if (!func) {
- memset(&new_func, 0, sizeof(struct pci_func));
- new_func.bus = busn;
- new_func.device = devn;
- new_func.function = funn;
- new_func.is_a_board = 1;
- configure_existing_function(ctrl, &new_func);
- phprm_dump_func_res(&new_func);
- } else {
- configure_existing_function(ctrl, func);
- phprm_dump_func_res(func);
- }
- dbg("aCCF:existing PCI 0x%x Func ResourceDump\n", ctrl->bus);
- }
- }
- }
-
- return 0;
-}
-
-static void phprm_dump_ctrl_res( struct controller *ctlr)
-{
- struct controller *ctrl = ctlr;
-
- if (ctrl->bus_head) {
- dbg(": BUS Resources:\n");
- print_pci_resource (ctrl->bus_head);
- }
- if (ctrl->io_head) {
- dbg(": IO Resources:\n");
- print_pci_resource (ctrl->io_head);
- }
- if (ctrl->mem_head) {
- dbg(": MEM Resources:\n");
- print_pci_resource (ctrl->mem_head);
- }
- if (ctrl->p_mem_head) {
- dbg(": PMEM Resources:\n");
- print_pci_resource (ctrl->p_mem_head);
- }
-}
-
-/*
- * phprm_find_available_resources
- *
- * Finds available memory, IO, and IRQ resources for programming
- * devices which may be added to the system
- * this function is for hot plug ADD!
- *
- * returns 0 if success
- */
-int pciehprm_find_available_resources(struct controller *ctrl)
-{
- struct pci_func func;
- u32 rc;
-
- memset(&func, 0, sizeof(struct pci_func));
-
- func.bus = ctrl->bus;
- func.device = ctrl->device;
- func.function = ctrl->function;
- func.is_a_board = 1;
-
- /* Get resources for this PCI bridge */
- rc = pciehp_save_used_resources (ctrl, &func, !DISABLE_CARD);
- dbg("%s: pciehp_save_used_resources rc = %d\n", __FUNCTION__, rc);
-
- if (func.mem_head)
- func.mem_head->next = ctrl->mem_head;
- ctrl->mem_head = func.mem_head;
-
- if (func.p_mem_head)
- func.p_mem_head->next = ctrl->p_mem_head;
- ctrl->p_mem_head = func.p_mem_head;
-
- if (func.io_head)
- func.io_head->next = ctrl->io_head;
- ctrl->io_head = func.io_head;
-
- if(func.bus_head)
- func.bus_head->next = ctrl->bus_head;
- ctrl->bus_head = func.bus_head;
-
- if (ctrl->bus_head)
- pciehprm_delete_resource(&ctrl->bus_head, ctrl->pci_dev->subordinate->number, 1);
-
- dbg("%s:pre-Bind PCI 0x%x Ctrl Resource Dump\n", __FUNCTION__, ctrl->bus);
- phprm_dump_ctrl_res(ctrl);
-
- dbg("%s: before bind_pci_resources_to slots\n", __FUNCTION__);
-
- bind_pci_resources_to_slots (ctrl);
-
- dbg("%s:post-Bind PCI 0x%x Ctrl Resource Dump\n", __FUNCTION__, ctrl->bus);
- phprm_dump_ctrl_res(ctrl);
-
- return (rc);
-}
-
-int pciehprm_set_hpp(
- struct controller *ctrl,
- struct pci_func *func,
- u8 card_type)
-{
- u32 rc;
- u8 temp_byte;
- struct pci_bus lpci_bus, *pci_bus;
- unsigned int devfn;
- memcpy(&lpci_bus, ctrl->pci_bus, sizeof(lpci_bus));
- pci_bus = &lpci_bus;
- pci_bus->number = func->bus;
- devfn = PCI_DEVFN(func->device, func->function);
-
- temp_byte = 0x40; /* hard coded value for LT */
- if (card_type == PCI_HEADER_TYPE_BRIDGE) {
- /* set subordinate Latency Timer */
- rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_SEC_LATENCY_TIMER, temp_byte);
-
- if (rc) {
- dbg("%s: set secondary LT error. b:d:f(%02x:%02x:%02x)\n", __FUNCTION__,
- func->bus, func->device, func->function);
- return rc;
- }
- }
-
- /* set base Latency Timer */
- rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_LATENCY_TIMER, temp_byte);
-
- if (rc) {
- dbg("%s: set LT error. b:d:f(%02x:%02x:%02x)\n", __FUNCTION__, func->bus, func->device, func->function);
- return rc;
- }
-
- /* set Cache Line size */
- temp_byte = 0x08; /* hard coded value for CLS */
-
- rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_CACHE_LINE_SIZE, temp_byte);
-
- if (rc) {
- dbg("%s: set CLS error. b:d:f(%02x:%02x:%02x)\n", __FUNCTION__, func->bus, func->device, func->function);
- }
-
- /* set enable_perr */
- /* set enable_serr */
-
- return rc;
-}
-
-void pciehprm_enable_card(
- struct controller *ctrl,
- struct pci_func *func,
- u8 card_type)
-{
- u16 command, bcommand;
- struct pci_bus lpci_bus, *pci_bus;
- unsigned int devfn;
- int rc;
-
- memcpy(&lpci_bus, ctrl->pci_bus, sizeof(lpci_bus));
- pci_bus = &lpci_bus;
- pci_bus->number = func->bus;
- devfn = PCI_DEVFN(func->device, func->function);
-
- rc = pci_bus_read_config_word(pci_bus, devfn, PCI_COMMAND, &command);
-
- command |= PCI_COMMAND_PARITY | PCI_COMMAND_SERR
- | PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE
- | PCI_COMMAND_IO | PCI_COMMAND_MEMORY;
-
- rc = pci_bus_write_config_word(pci_bus, devfn, PCI_COMMAND, command);
-
- if (card_type == PCI_HEADER_TYPE_BRIDGE) {
-
- rc = pci_bus_read_config_word(pci_bus, devfn, PCI_BRIDGE_CONTROL, &bcommand);
-
- bcommand |= PCI_BRIDGE_CTL_PARITY | PCI_BRIDGE_CTL_SERR
- | PCI_BRIDGE_CTL_NO_ISA;
-
- rc = pci_bus_write_config_word(pci_bus, devfn, PCI_BRIDGE_CONTROL, bcommand);
- }
-}
-
-static int legacy_pciehprm_init_pci(void)
+int pciehp_get_hp_hw_control_from_firmware(struct pci_dev *dev)
{
return 0;
}
-
-int pciehprm_init(enum php_ctlr_type ctrl_type)
-{
- int retval;
-
- switch (ctrl_type) {
- case PCI:
- retval = legacy_pciehprm_init_pci();
- break;
- default:
- retval = -ENODEV;
- break;
- }
-
- return retval;
-}
diff --git a/drivers/pci/hotplug/pciehprm_nonacpi.h b/drivers/pci/hotplug/pciehprm_nonacpi.h
deleted file mode 100644
index b10603b0e958..000000000000
--- a/drivers/pci/hotplug/pciehprm_nonacpi.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * PCIEHPRM NONACPI: PHP Resource Manager for Non-ACPI/Legacy platform
- *
- * Copyright (C) 1995,2001 Compaq Computer Corporation
- * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
- * Copyright (C) 2001 IBM Corp.
- * Copyright (C) 2003-2004 Intel Corporation
- *
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
- * NON INFRINGEMENT. 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.
- *
- * Send feedback to <greg@kroah.com>, <kristen.c.accardi@intel.com>
- *
- */
-
-#ifndef _PCIEHPRM_NONACPI_H_
-#define _PCIEHPRM_NONACPI_H_
-
-struct irq_info {
- u8 bus, devfn; /* bus, device and function */
- struct {
- u8 link; /* IRQ line ID, chipset dependent, 0=not routed */
- u16 bitmap; /* Available IRQs */
- } __attribute__ ((packed)) irq[4];
- u8 slot; /* slot number, 0=onboard */
- u8 rfu;
-} __attribute__ ((packed));
-
-struct irq_routing_table {
- u32 signature; /* PIRQ_SIGNATURE should be here */
- u16 version; /* PIRQ_VERSION */
- u16 size; /* Table size in bytes */
- u8 rtr_bus, rtr_devfn; /* Where the interrupt router lies */
- u16 exclusive_irqs; /* IRQs devoted exclusively to PCI usage */
- u16 rtr_vendor, rtr_device; /* Vendor and device ID of interrupt router */
- u32 miniport_data; /* Crap */
- u8 rfu[11];
- u8 checksum; /* Modulo 256 checksum must give zero */
- struct irq_info slots[0];
-} __attribute__ ((packed));
-
-#endif /* _PCIEHPRM_NONACPI_H_ */
diff --git a/drivers/pci/hotplug/rpadlpar_core.c b/drivers/pci/hotplug/rpadlpar_core.c
index ad1017da8656..cc03609f45d0 100644
--- a/drivers/pci/hotplug/rpadlpar_core.c
+++ b/drivers/pci/hotplug/rpadlpar_core.c
@@ -16,10 +16,13 @@
*/
#include <linux/init.h>
#include <linux/pci.h>
+#include <linux/string.h>
+
#include <asm/pci-bridge.h>
#include <asm/semaphore.h>
#include <asm/rtas.h>
#include <asm/vio.h>
+
#include "../pci.h"
#include "rpaphp.h"
#include "rpadlpar.h"
@@ -131,43 +134,6 @@ static void rpadlpar_claim_one_bus(struct pci_bus *b)
rpadlpar_claim_one_bus(child_bus);
}
-static int pci_add_secondary_bus(struct device_node *dn,
- struct pci_dev *bridge_dev)
-{
- struct pci_dn *pdn = dn->data;
- struct pci_controller *hose = pdn->phb;
- struct pci_bus *child;
- u8 sec_busno;
-
- /* Get busno of downstream bus */
- pci_read_config_byte(bridge_dev, PCI_SECONDARY_BUS, &sec_busno);
-
- /* Allocate and add to children of bridge_dev->bus */
- child = pci_add_new_bus(bridge_dev->bus, bridge_dev, sec_busno);
- if (!child) {
- printk(KERN_ERR "%s: could not add secondary bus\n", __FUNCTION__);
- return -ENOMEM;
- }
-
- sprintf(child->name, "PCI Bus #%02x", child->number);
-
- /* Fixup subordinate bridge bases and resources */
- pcibios_fixup_bus(child);
-
- /* Claim new bus resources */
- rpadlpar_claim_one_bus(bridge_dev->bus);
-
- if (hose->last_busno < child->number)
- hose->last_busno = child->number;
-
- pdn->bussubno = child->number;
-
- /* ioremap() for child bus, which may or may not succeed */
- remap_bus_range(child);
-
- return 0;
-}
-
static struct pci_dev *dlpar_find_new_dev(struct pci_bus *parent,
struct device_node *dev_dn)
{
@@ -185,29 +151,41 @@ static struct pci_dev *dlpar_find_new_dev(struct pci_bus *parent,
static struct pci_dev *dlpar_pci_add_bus(struct device_node *dn)
{
struct pci_dn *pdn = dn->data;
- struct pci_controller *hose = pdn->phb;
+ struct pci_controller *phb = pdn->phb;
struct pci_dev *dev = NULL;
- /* Scan phb bus for EADS device, adding new one to bus->devices */
- if (!pci_scan_single_device(hose->bus, pdn->devfn)) {
- printk(KERN_ERR "%s: found no device on bus\n", __FUNCTION__);
+ rpaphp_eeh_init_nodes(dn);
+ /* Add EADS device to PHB bus, adding new entry to bus->devices */
+ dev = of_create_pci_dev(dn, phb->bus, pdn->devfn);
+ if (!dev) {
+ printk(KERN_ERR "%s: failed to create pci dev for %s\n",
+ __FUNCTION__, dn->full_name);
return NULL;
}
+ if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE ||
+ dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)
+ of_scan_pci_bridge(dn, dev);
+
+ rpaphp_init_new_devs(dev->subordinate);
+
+ /* Claim new bus resources */
+ rpadlpar_claim_one_bus(dev->bus);
+
+ /* ioremap() for child bus, which may or may not succeed */
+ (void) remap_bus_range(dev->bus);
+
/* Add new devices to global lists. Register in proc, sysfs. */
- pci_bus_add_devices(hose->bus);
+ pci_bus_add_devices(phb->bus);
/* Confirm new bridge dev was created */
- dev = dlpar_find_new_dev(hose->bus, dn);
+ dev = dlpar_find_new_dev(phb->bus, dn);
if (dev) {
if (dev->hdr_type != PCI_HEADER_TYPE_BRIDGE) {
printk(KERN_ERR "%s: unexpected header type %d\n",
__FUNCTION__, dev->hdr_type);
return NULL;
}
-
- if (pci_add_secondary_bus(dn, dev))
- return NULL;
}
return dev;
@@ -216,7 +194,6 @@ static struct pci_dev *dlpar_pci_add_bus(struct device_node *dn)
static int dlpar_add_pci_slot(char *drc_name, struct device_node *dn)
{
struct pci_dev *dev;
- int rc;
if (rpaphp_find_pci_bus(dn))
return -EINVAL;
@@ -229,15 +206,6 @@ static int dlpar_add_pci_slot(char *drc_name, struct device_node *dn)
return -EIO;
}
- if (dn->child) {
- rc = rpaphp_config_pci_adapter(dev->subordinate);
- if (rc < 0) {
- printk(KERN_ERR "%s: unable to enable slot %s\n",
- __FUNCTION__, drc_name);
- return -EIO;
- }
- }
-
/* Add hotplug slot */
if (rpaphp_add_slot(dn)) {
printk(KERN_ERR "%s: unable to add hotplug slot %s\n",
@@ -303,7 +271,7 @@ static int dlpar_add_phb(char *drc_name, struct device_node *dn)
{
struct pci_controller *phb;
- if (PCI_DN(dn)->phb) {
+ if (PCI_DN(dn) && PCI_DN(dn)->phb) {
/* PHB already exists */
return -EINVAL;
}
@@ -432,6 +400,8 @@ int dlpar_remove_pci_slot(char *drc_name, struct device_node *dn)
__FUNCTION__, drc_name);
return -EIO;
}
+ } else {
+ rpaphp_unconfig_pci_adapter(bus);
}
if (unmap_bus_range(bus)) {
diff --git a/drivers/pci/hotplug/rpaphp.h b/drivers/pci/hotplug/rpaphp.h
index 61d94d1e29cb..57ea71a7bda5 100644
--- a/drivers/pci/hotplug/rpaphp.h
+++ b/drivers/pci/hotplug/rpaphp.h
@@ -92,9 +92,12 @@ extern struct pci_bus *rpaphp_find_pci_bus(struct device_node *dn);
extern int rpaphp_claim_resource(struct pci_dev *dev, int resource);
extern int rpaphp_enable_pci_slot(struct slot *slot);
extern int register_pci_slot(struct slot *slot);
-extern int rpaphp_unconfig_pci_adapter(struct slot *slot);
extern int rpaphp_get_pci_adapter_status(struct slot *slot, int is_init, u8 * value);
+extern void rpaphp_init_new_devs(struct pci_bus *bus);
+extern void rpaphp_eeh_init_nodes(struct device_node *dn);
+
extern int rpaphp_config_pci_adapter(struct pci_bus *bus);
+extern int rpaphp_unconfig_pci_adapter(struct pci_bus *bus);
/* rpaphp_core.c */
extern int rpaphp_add_slot(struct device_node *dn);
diff --git a/drivers/pci/hotplug/rpaphp_core.c b/drivers/pci/hotplug/rpaphp_core.c
index c830ff0acdc3..cf075c34b578 100644
--- a/drivers/pci/hotplug/rpaphp_core.c
+++ b/drivers/pci/hotplug/rpaphp_core.c
@@ -426,8 +426,11 @@ static int disable_slot(struct hotplug_slot *hotplug_slot)
dbg("DISABLING SLOT %s\n", slot->name);
down(&rpaphp_sem);
- retval = rpaphp_unconfig_pci_adapter(slot);
+ retval = rpaphp_unconfig_pci_adapter(slot->bus);
up(&rpaphp_sem);
+ slot->state = NOT_CONFIGURED;
+ info("%s: devices in slot[%s] unconfigured.\n", __FUNCTION__,
+ slot->name);
exit:
dbg("%s - Exit: rc[%d]\n", __FUNCTION__, retval);
return retval;
diff --git a/drivers/pci/hotplug/rpaphp_pci.c b/drivers/pci/hotplug/rpaphp_pci.c
index 49e4d10a6488..a7859a84d1ae 100644
--- a/drivers/pci/hotplug/rpaphp_pci.c
+++ b/drivers/pci/hotplug/rpaphp_pci.c
@@ -23,11 +23,13 @@
*
*/
#include <linux/pci.h>
+#include <linux/string.h>
+
#include <asm/pci-bridge.h>
#include <asm/rtas.h>
#include <asm/machdep.h>
-#include "../pci.h" /* for pci_add_new_bus */
+#include "../pci.h" /* for pci_add_new_bus */
#include "rpaphp.h"
static struct pci_bus *find_bus_among_children(struct pci_bus *bus,
@@ -152,8 +154,7 @@ exit:
}
/* Must be called before pci_bus_add_devices */
-static void
-rpaphp_fixup_new_pci_devices(struct pci_bus *bus, int fix_bus)
+void rpaphp_fixup_new_pci_devices(struct pci_bus *bus, int fix_bus)
{
struct pci_dev *dev;
@@ -182,6 +183,20 @@ rpaphp_fixup_new_pci_devices(struct pci_bus *bus, int fix_bus)
}
}
+static void rpaphp_eeh_add_bus_device(struct pci_bus *bus)
+{
+ struct pci_dev *dev;
+
+ list_for_each_entry(dev, &bus->devices, bus_list) {
+ eeh_add_device_late(dev);
+ if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
+ struct pci_bus *subbus = dev->subordinate;
+ if (subbus)
+ rpaphp_eeh_add_bus_device (subbus);
+ }
+ }
+}
+
static int rpaphp_pci_config_bridge(struct pci_dev *dev)
{
u8 sec_busno;
@@ -215,6 +230,13 @@ static int rpaphp_pci_config_bridge(struct pci_dev *dev)
return 0;
}
+void rpaphp_init_new_devs(struct pci_bus *bus)
+{
+ rpaphp_fixup_new_pci_devices(bus, 0);
+ rpaphp_eeh_add_bus_device(bus);
+}
+EXPORT_SYMBOL_GPL(rpaphp_init_new_devs);
+
/*****************************************************************************
rpaphp_pci_config_slot() will configure all devices under the
given slot->dn and return the the first pci_dev.
@@ -231,36 +253,51 @@ rpaphp_pci_config_slot(struct pci_bus *bus)
if (!dn || !dn->child)
return NULL;
- slotno = PCI_SLOT(PCI_DN(dn->child)->devfn);
+ if (systemcfg->platform == PLATFORM_PSERIES_LPAR) {
+ of_scan_bus(dn, bus);
+ if (list_empty(&bus->devices)) {
+ err("%s: No new device found\n", __FUNCTION__);
+ return NULL;
+ }
- /* pci_scan_slot should find all children */
- num = pci_scan_slot(bus, PCI_DEVFN(slotno, 0));
- if (num) {
- rpaphp_fixup_new_pci_devices(bus, 1);
+ rpaphp_init_new_devs(bus);
pci_bus_add_devices(bus);
- }
- if (list_empty(&bus->devices)) {
- err("%s: No new device found\n", __FUNCTION__);
- return NULL;
- }
- list_for_each_entry(dev, &bus->devices, bus_list) {
- if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE)
- rpaphp_pci_config_bridge(dev);
+ dev = list_entry(&bus->devices, struct pci_dev, bus_list);
+ } else {
+ slotno = PCI_SLOT(PCI_DN(dn->child)->devfn);
+
+ /* pci_scan_slot should find all children */
+ num = pci_scan_slot(bus, PCI_DEVFN(slotno, 0));
+ if (num) {
+ rpaphp_fixup_new_pci_devices(bus, 1);
+ pci_bus_add_devices(bus);
+ }
+ if (list_empty(&bus->devices)) {
+ err("%s: No new device found\n", __FUNCTION__);
+ return NULL;
+ }
+ list_for_each_entry(dev, &bus->devices, bus_list) {
+ if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE)
+ rpaphp_pci_config_bridge(dev);
+
+ rpaphp_eeh_add_bus_device(bus);
+ }
}
return dev;
}
-static void enable_eeh(struct device_node *dn)
+void rpaphp_eeh_init_nodes(struct device_node *dn)
{
struct device_node *sib;
for (sib = dn->child; sib; sib = sib->sibling)
- enable_eeh(sib);
+ rpaphp_eeh_init_nodes(sib);
eeh_add_device_early(dn);
return;
}
+EXPORT_SYMBOL_GPL(rpaphp_eeh_init_nodes);
static void print_slot_pci_funcs(struct pci_bus *bus)
{
@@ -287,7 +324,7 @@ int rpaphp_config_pci_adapter(struct pci_bus *bus)
if (!dn)
goto exit;
- enable_eeh(dn);
+ rpaphp_eeh_init_nodes(dn);
dev = rpaphp_pci_config_slot(bus);
if (!dev) {
err("%s: can't find any devices.\n", __FUNCTION__);
@@ -319,21 +356,17 @@ static void rpaphp_eeh_remove_bus_device(struct pci_dev *dev)
return;
}
-int rpaphp_unconfig_pci_adapter(struct slot *slot)
+int rpaphp_unconfig_pci_adapter(struct pci_bus *bus)
{
struct pci_dev *dev, *tmp;
- int retval = 0;
- list_for_each_entry_safe(dev, tmp, slot->pci_devs, bus_list) {
+ list_for_each_entry_safe(dev, tmp, &bus->devices, bus_list) {
rpaphp_eeh_remove_bus_device(dev);
pci_remove_bus_device(dev);
}
-
- slot->state = NOT_CONFIGURED;
- info("%s: devices in slot[%s] unconfigured.\n", __FUNCTION__,
- slot->name);
- return retval;
+ return 0;
}
+EXPORT_SYMBOL_GPL(rpaphp_unconfig_pci_adapter);
static int setup_pci_hotplug_slot_info(struct slot *slot)
{
@@ -447,8 +480,8 @@ int rpaphp_enable_pci_slot(struct slot *slot)
retval = rpaphp_config_pci_adapter(slot->bus);
if (!retval) {
slot->state = CONFIGURED;
- dbg("%s: PCI devices in slot[%s] has been configured\n",
- __FUNCTION__, slot->name);
+ info("%s: devices in slot[%s] configured\n",
+ __FUNCTION__, slot->name);
} else {
slot->state = NOT_CONFIGURED;
dbg("%s: no pci_dev struct for adapter in slot[%s]\n",
diff --git a/drivers/pci/hotplug/rpaphp_slot.c b/drivers/pci/hotplug/rpaphp_slot.c
index 0e8815495083..daa89ae57123 100644
--- a/drivers/pci/hotplug/rpaphp_slot.c
+++ b/drivers/pci/hotplug/rpaphp_slot.c
@@ -27,6 +27,9 @@
#include <linux/kobject.h>
#include <linux/sysfs.h>
#include <linux/pci.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+
#include <asm/rtas.h>
#include "rpaphp.h"
diff --git a/drivers/pci/hotplug/shpchp.h b/drivers/pci/hotplug/shpchp.h
index b7d1c61d6bbb..08ad26a0cae7 100644
--- a/drivers/pci/hotplug/shpchp.h
+++ b/drivers/pci/hotplug/shpchp.h
@@ -32,8 +32,8 @@
#include <linux/types.h>
#include <linux/pci.h>
#include <linux/delay.h>
-#include <asm/semaphore.h>
-#include <asm/io.h>
+#include <linux/sched.h> /* signal_pending(), struct timer_list */
+
#include "pci_hotplug.h"
#if !defined(MODULE)
@@ -52,42 +52,18 @@ extern int shpchp_debug;
#define info(format, arg...) printk(KERN_INFO "%s: " format, MY_NAME , ## arg)
#define warn(format, arg...) printk(KERN_WARNING "%s: " format, MY_NAME , ## arg)
-struct pci_func {
- struct pci_func *next;
- u8 bus;
- u8 device;
- u8 function;
- u8 is_a_board;
- u16 status;
- u8 configured;
- u8 switch_save;
- u8 presence_save;
- u8 pwr_save;
- u32 base_length[0x06];
- u8 base_type[0x06];
- u16 reserved2;
- u32 config_space[0x20];
- struct pci_resource *mem_head;
- struct pci_resource *p_mem_head;
- struct pci_resource *io_head;
- struct pci_resource *bus_head;
- struct pci_dev* pci_dev;
-};
-
#define SLOT_MAGIC 0x67267321
struct slot {
u32 magic;
struct slot *next;
u8 bus;
u8 device;
+ u16 status;
u32 number;
u8 is_a_board;
- u8 configured;
u8 state;
- u8 switch_save;
u8 presence_save;
- u32 capabilities;
- u16 reserved2;
+ u8 pwr_save;
struct timer_list task_event;
u8 hp_slot;
struct controller *ctrl;
@@ -96,12 +72,6 @@ struct slot {
struct list_head slot_list;
};
-struct pci_resource {
- struct pci_resource * next;
- u32 base;
- u32 length;
-};
-
struct event_info {
u32 event_type;
u8 hp_slot;
@@ -110,13 +80,9 @@ struct event_info {
struct controller {
struct controller *next;
struct semaphore crit_sect; /* critical section semaphore */
- void * hpc_ctlr_handle; /* HPC controller handle */
+ struct php_ctlr_state_s *hpc_ctlr_handle; /* HPC controller handle */
int num_slots; /* Number of slots on ctlr */
int slot_num_inc; /* 1 or -1 */
- struct pci_resource *mem_head;
- struct pci_resource *p_mem_head;
- struct pci_resource *io_head;
- struct pci_resource *bus_head;
struct pci_dev *pci_dev;
struct pci_bus *pci_bus;
struct event_info event_queue[10];
@@ -124,33 +90,21 @@ struct controller {
struct hpc_ops *hpc_ops;
wait_queue_head_t queue; /* sleep & wake process */
u8 next_event;
- u8 seg;
u8 bus;
u8 device;
u8 function;
- u8 rev;
u8 slot_device_offset;
u8 add_support;
enum pci_bus_speed speed;
u32 first_slot; /* First physical slot number */
u8 slot_bus; /* Bus where the slots handled by this controller sit */
- u8 push_flag;
- u16 ctlrcap;
- u16 vendor_id;
-};
-
-struct irq_mapping {
- u8 barber_pole;
- u8 valid_INT;
- u8 interrupt[4];
};
-struct resource_lists {
- struct pci_resource *mem_head;
- struct pci_resource *p_mem_head;
- struct pci_resource *io_head;
- struct pci_resource *bus_head;
- struct irq_mapping *irqs;
+struct hotplug_params {
+ u8 cache_line_size;
+ u8 latency_timer;
+ u8 enable_serr;
+ u8 enable_perr;
};
/* Define AMD SHPC ID */
@@ -194,24 +148,16 @@ struct resource_lists {
* error Messages
*/
#define msg_initialization_err "Initialization failure, error=%d\n"
-#define msg_HPC_rev_error "Unsupported revision of the PCI hot plug controller found.\n"
-#define msg_HPC_non_shpc "The PCI hot plug controller is not supported by this driver.\n"
-#define msg_HPC_not_supported "This system is not supported by this version of shpcphd mdoule. Upgrade to a newer version of shpchpd\n"
-#define msg_unable_to_save "Unable to store PCI hot plug add resource information. This system must be rebooted before adding any PCI devices.\n"
#define msg_button_on "PCI slot #%d - powering on due to button press.\n"
#define msg_button_off "PCI slot #%d - powering off due to button press.\n"
#define msg_button_cancel "PCI slot #%d - action canceled due to button press.\n"
-#define msg_button_ignore "PCI slot #%d - button press ignored. (action in progress...)\n"
/* sysfs functions for the hotplug controller info */
extern void shpchp_create_ctrl_files (struct controller *ctrl);
/* controller functions */
-extern int shpchprm_find_available_resources(struct controller *ctrl);
extern int shpchp_event_start_thread(void);
extern void shpchp_event_stop_thread(void);
-extern struct pci_func *shpchp_slot_create(unsigned char busnumber);
-extern struct pci_func *shpchp_slot_find(unsigned char bus, unsigned char device, unsigned char index);
extern int shpchp_enable_slot(struct slot *slot);
extern int shpchp_disable_slot(struct slot *slot);
@@ -220,29 +166,20 @@ extern u8 shpchp_handle_switch_change(u8 hp_slot, void *inst_id);
extern u8 shpchp_handle_presence_change(u8 hp_slot, void *inst_id);
extern u8 shpchp_handle_power_fault(u8 hp_slot, void *inst_id);
-/* resource functions */
-extern int shpchp_resource_sort_and_combine(struct pci_resource **head);
-
/* pci functions */
-extern int shpchp_set_irq(u8 bus_num, u8 dev_num, u8 int_pin, u8 irq_num);
-/*extern int shpchp_get_bus_dev(struct controller *ctrl, u8 *bus_num, u8 *dev_num, struct slot *slot);*/
extern int shpchp_save_config(struct controller *ctrl, int busnumber, int num_ctlr_slots, int first_device_num);
-extern int shpchp_save_used_resources(struct controller *ctrl, struct pci_func * func, int flag);
-extern int shpchp_save_slot_config(struct controller *ctrl, struct pci_func * new_slot);
-extern void shpchp_destroy_board_resources(struct pci_func * func);
-extern int shpchp_return_board_resources(struct pci_func * func, struct resource_lists * resources);
-extern void shpchp_destroy_resource_list(struct resource_lists * resources);
-extern int shpchp_configure_device(struct controller* ctrl, struct pci_func* func);
-extern int shpchp_unconfigure_device(struct pci_func* func);
+extern int shpchp_configure_device(struct slot *p_slot);
+extern int shpchp_unconfigure_device(struct slot *p_slot);
+extern void get_hp_hw_control_from_firmware(struct pci_dev *dev);
+extern void get_hp_params_from_firmware(struct pci_dev *dev,
+ struct hotplug_params *hpp);
+extern int shpchprm_get_physical_slot_number(struct controller *ctrl,
+ u32 *sun, u8 busnum, u8 devnum);
+extern void shpchp_remove_ctrl_files(struct controller *ctrl);
/* Global variables */
extern struct controller *shpchp_ctrl_list;
-extern struct pci_func *shpchp_slot_list[256];
-
-/* These are added to support AMD shpc */
-extern u8 shpchp_nic_irq;
-extern u8 shpchp_disk_irq;
struct ctrl_reg {
volatile u32 base_offset;
@@ -298,7 +235,7 @@ enum ctrl_offsets {
SLOT11 = offsetof(struct ctrl_reg, slot11),
SLOT12 = offsetof(struct ctrl_reg, slot12),
};
-typedef u8(*php_intr_callback_t) (unsigned int change_id, void *instance_id);
+typedef u8(*php_intr_callback_t) (u8 hp_slot, void *instance_id);
struct php_ctlr_state_s {
struct php_ctlr_state_s *pnext;
struct pci_dev *pci_dev;
@@ -359,12 +296,9 @@ static inline struct slot *shpchp_find_slot (struct controller *ctrl, u8 device)
p_slot = ctrl->slot;
- dbg("p_slot = %p\n", p_slot);
-
while (p_slot && (p_slot->device != device)) {
tmp_slot = p_slot;
p_slot = p_slot->next;
- dbg("In while loop, p_slot = %p\n", p_slot);
}
if (p_slot == NULL) {
err("ERROR: shpchp_find_slot device=0x%x\n", device);
@@ -379,8 +313,6 @@ static inline int wait_for_ctrl_irq (struct controller *ctrl)
DECLARE_WAITQUEUE(wait, current);
int retval = 0;
- dbg("%s : start\n",__FUNCTION__);
-
add_wait_queue(&ctrl->queue, &wait);
if (!shpchp_poll_mode) {
@@ -394,19 +326,9 @@ static inline int wait_for_ctrl_irq (struct controller *ctrl)
if (signal_pending(current))
retval = -EINTR;
- dbg("%s : end\n", __FUNCTION__);
return retval;
}
-/* Puts node back in the resource list pointed to by head */
-static inline void return_resource(struct pci_resource **head, struct pci_resource *node)
-{
- if (!node || !head)
- return;
- node->next = *head;
- *head = node;
-}
-
#define SLOT_NAME_SIZE 10
static inline void make_slot_name(char *buffer, int buffer_size, struct slot *slot)
@@ -420,11 +342,7 @@ enum php_ctlr_type {
ACPI
};
-int shpc_init( struct controller *ctrl, struct pci_dev *pdev,
- php_intr_callback_t attention_button_callback,
- php_intr_callback_t switch_change_callback,
- php_intr_callback_t presence_change_callback,
- php_intr_callback_t power_fault_callback);
+int shpc_init( struct controller *ctrl, struct pci_dev *pdev);
int shpc_get_ctlr_slot_config( struct controller *ctrl,
int *num_ctlr_slots,
@@ -437,8 +355,6 @@ struct hpc_ops {
int (*power_on_slot ) (struct slot *slot);
int (*slot_enable ) (struct slot *slot);
int (*slot_disable ) (struct slot *slot);
- int (*enable_all_slots) (struct slot *slot);
- int (*pwr_on_all_slots) (struct slot *slot);
int (*set_bus_speed_mode) (struct slot *slot, enum pci_bus_speed speed);
int (*get_power_status) (struct slot *slot, u8 *status);
int (*get_attention_status) (struct slot *slot, u8 *status);
diff --git a/drivers/pci/hotplug/shpchp_core.c b/drivers/pci/hotplug/shpchp_core.c
index 6f7d8a29957a..63628e01dd43 100644
--- a/drivers/pci/hotplug/shpchp_core.c
+++ b/drivers/pci/hotplug/shpchp_core.c
@@ -27,26 +27,18 @@
*
*/
-#include <linux/config.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/kernel.h>
#include <linux/types.h>
-#include <linux/proc_fs.h>
-#include <linux/slab.h>
-#include <linux/workqueue.h>
#include <linux/pci.h>
-#include <linux/init.h>
-#include <asm/uaccess.h>
#include "shpchp.h"
-#include "shpchprm.h"
/* Global variables */
int shpchp_debug;
int shpchp_poll_mode;
int shpchp_poll_time;
struct controller *shpchp_ctrl_list; /* = NULL */
-struct pci_func *shpchp_slot_list[256];
#define DRIVER_VERSION "0.4"
#define DRIVER_AUTHOR "Dan Zink <dan.zink@compaq.com>, Greg Kroah-Hartman <greg@kroah.com>, Dely Sy <dely.l.sy@intel.com>"
@@ -113,8 +105,6 @@ static int init_slots(struct controller *ctrl)
u32 slot_number, sun;
int result = -ENOMEM;
- dbg("%s\n",__FUNCTION__);
-
number_of_slots = ctrl->num_slots;
slot_device = ctrl->slot_device_offset;
slot_number = ctrl->first_slot;
@@ -352,6 +342,17 @@ static int get_cur_bus_speed (struct hotplug_slot *hotplug_slot, enum pci_bus_sp
return 0;
}
+static int is_shpc_capable(struct pci_dev *dev)
+{
+ if ((dev->vendor == PCI_VENDOR_ID_AMD) || (dev->device ==
+ PCI_DEVICE_ID_AMD_GOLAM_7450))
+ return 1;
+ if (pci_find_capability(dev, PCI_CAP_ID_SHPC))
+ return 1;
+
+ return 0;
+}
+
static int shpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
{
int rc;
@@ -360,6 +361,9 @@ static int shpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
int first_device_num; /* first PCI device number supported by this SHPC */
int num_ctlr_slots; /* number of slots supported by this SHPC */
+ if (!is_shpc_capable(pdev))
+ return -ENODEV;
+
ctrl = (struct controller *) kmalloc(sizeof(struct controller), GFP_KERNEL);
if (!ctrl) {
err("%s : out of memory\n", __FUNCTION__);
@@ -367,19 +371,12 @@ static int shpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
}
memset(ctrl, 0, sizeof(struct controller));
- dbg("DRV_thread pid = %d\n", current->pid);
-
- rc = shpc_init(ctrl, pdev,
- (php_intr_callback_t) shpchp_handle_attention_button,
- (php_intr_callback_t) shpchp_handle_switch_change,
- (php_intr_callback_t) shpchp_handle_presence_change,
- (php_intr_callback_t) shpchp_handle_power_fault);
+ rc = shpc_init(ctrl, pdev);
if (rc) {
dbg("%s: controller initialization failed\n", SHPC_MODULE_NAME);
goto err_out_free_ctrl;
}
- dbg("%s: controller initialization success\n", __FUNCTION__);
ctrl->pci_dev = pdev; /* pci_dev of the P2P bridge */
pci_set_drvdata(pdev, ctrl);
@@ -411,23 +408,8 @@ static int shpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
first_device_num = ctrl->slot_device_offset;
num_ctlr_slots = ctrl->num_slots;
- /* Store PCI Config Space for all devices on this bus */
- rc = shpchp_save_config(ctrl, ctrl->slot_bus, num_ctlr_slots, first_device_num);
- if (rc) {
- err("%s: unable to save PCI configuration data, error %d\n", __FUNCTION__, rc);
- goto err_out_free_ctrl_bus;
- }
-
- /* Get IO, memory, and IRQ resources for new devices */
- rc = shpchprm_find_available_resources(ctrl);
- ctrl->add_support = !rc;
+ ctrl->add_support = 1;
- if (rc) {
- dbg("shpchprm_find_available_resources = %#x\n", rc);
- err("unable to locate PCI configuration resources for hot plug add.\n");
- goto err_out_free_ctrl_bus;
- }
-
/* Setup the slot information structures */
rc = init_slots(ctrl);
if (rc) {
@@ -477,7 +459,6 @@ err_out_none:
static int shpc_start_thread(void)
{
- int loop;
int retval = 0;
dbg("Initialize + Start the notification/polling mechanism \n");
@@ -488,48 +469,21 @@ static int shpc_start_thread(void)
return retval;
}
- dbg("Initialize slot lists\n");
- /* One slot list for each bus in the system */
- for (loop = 0; loop < 256; loop++) {
- shpchp_slot_list[loop] = NULL;
- }
-
return retval;
}
-static inline void __exit
-free_shpchp_res(struct pci_resource *res)
-{
- struct pci_resource *tres;
-
- while (res) {
- tres = res;
- res = res->next;
- kfree(tres);
- }
-}
-
static void __exit unload_shpchpd(void)
{
- struct pci_func *next;
- struct pci_func *TempSlot;
- int loop;
struct controller *ctrl;
struct controller *tctrl;
ctrl = shpchp_ctrl_list;
while (ctrl) {
+ shpchp_remove_ctrl_files(ctrl);
cleanup_slots(ctrl);
- free_shpchp_res(ctrl->io_head);
- free_shpchp_res(ctrl->mem_head);
- free_shpchp_res(ctrl->p_mem_head);
- free_shpchp_res(ctrl->bus_head);
-
kfree (ctrl->pci_bus);
-
- dbg("%s: calling release_ctlr\n", __FUNCTION__);
ctrl->hpc_ops->release_ctlr(ctrl);
tctrl = ctrl;
@@ -538,20 +492,6 @@ static void __exit unload_shpchpd(void)
kfree(tctrl);
}
- for (loop = 0; loop < 256; loop++) {
- next = shpchp_slot_list[loop];
- while (next != NULL) {
- free_shpchp_res(next->io_head);
- free_shpchp_res(next->mem_head);
- free_shpchp_res(next->p_mem_head);
- free_shpchp_res(next->bus_head);
-
- TempSlot = next;
- next = next->next;
- kfree(TempSlot);
- }
- }
-
/* Stop the notification mechanism */
shpchp_event_stop_thread();
@@ -596,20 +536,14 @@ static int __init shpcd_init(void)
if (retval)
goto error_hpc_init;
- retval = shpchprm_init(PCI);
- if (!retval) {
- retval = pci_register_driver(&shpc_driver);
- dbg("%s: pci_register_driver = %d\n", __FUNCTION__, retval);
- info(DRIVER_DESC " version: " DRIVER_VERSION "\n");
- }
+ retval = pci_register_driver(&shpc_driver);
+ dbg("%s: pci_register_driver = %d\n", __FUNCTION__, retval);
+ info(DRIVER_DESC " version: " DRIVER_VERSION "\n");
error_hpc_init:
if (retval) {
- shpchprm_cleanup();
shpchp_event_stop_thread();
- } else
- shpchprm_print_pirt();
-
+ }
return retval;
}
@@ -618,9 +552,6 @@ static void __exit shpcd_cleanup(void)
dbg("unload_shpchpd()\n");
unload_shpchpd();
- shpchprm_cleanup();
-
- dbg("pci_unregister_driver\n");
pci_unregister_driver(&shpc_driver);
info(DRIVER_DESC " version: " DRIVER_VERSION " unloaded\n");
diff --git a/drivers/pci/hotplug/shpchp_ctrl.c b/drivers/pci/hotplug/shpchp_ctrl.c
index 91c9903e621f..58619359ad08 100644
--- a/drivers/pci/hotplug/shpchp_ctrl.c
+++ b/drivers/pci/hotplug/shpchp_ctrl.c
@@ -27,24 +27,14 @@
*
*/
-#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/types.h>
-#include <linux/slab.h>
-#include <linux/workqueue.h>
-#include <linux/interrupt.h>
-#include <linux/delay.h>
-#include <linux/wait.h>
#include <linux/smp_lock.h>
#include <linux/pci.h>
+#include "../pci.h"
#include "shpchp.h"
-#include "shpchprm.h"
-static u32 configure_new_device(struct controller *ctrl, struct pci_func *func,
- u8 behind_bridge, struct resource_lists *resources, u8 bridge_bus, u8 bridge_dev);
-static int configure_new_function( struct controller *ctrl, struct pci_func *func,
- u8 behind_bridge, struct resource_lists *resources, u8 bridge_bus, u8 bridge_dev);
static void interrupt_event_handler(struct controller *ctrl);
static struct semaphore event_semaphore; /* mutex for process loop (up if something to process) */
@@ -52,28 +42,22 @@ static struct semaphore event_exit; /* guard ensure thread has exited before ca
static int event_finished;
static unsigned long pushbutton_pending; /* = 0 */
-u8 shpchp_disk_irq;
-u8 shpchp_nic_irq;
-
u8 shpchp_handle_attention_button(u8 hp_slot, void *inst_id)
{
struct controller *ctrl = (struct controller *) inst_id;
struct slot *p_slot;
u8 rc = 0;
u8 getstatus;
- struct pci_func *func;
struct event_info *taskInfo;
/* Attention Button Change */
dbg("shpchp: Attention button interrupt received.\n");
- func = shpchp_slot_find(ctrl->slot_bus, (hp_slot + ctrl->slot_device_offset), 0);
-
/* This is the structure that tells the worker thread what to do */
taskInfo = &(ctrl->event_queue[ctrl->next_event]);
p_slot = shpchp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset);
- p_slot->hpc_ops->get_adapter_status(p_slot, &(func->presence_save));
+ p_slot->hpc_ops->get_adapter_status(p_slot, &(p_slot->presence_save));
p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
ctrl->next_event = (ctrl->next_event + 1) % 10;
@@ -118,14 +102,11 @@ u8 shpchp_handle_switch_change(u8 hp_slot, void *inst_id)
struct slot *p_slot;
u8 rc = 0;
u8 getstatus;
- struct pci_func *func;
struct event_info *taskInfo;
/* Switch Change */
dbg("shpchp: Switch interrupt received.\n");
- func = shpchp_slot_find(ctrl->slot_bus, (hp_slot + ctrl->slot_device_offset), 0);
-
/* This is the structure that tells the worker thread
* what to do
*/
@@ -135,19 +116,18 @@ u8 shpchp_handle_switch_change(u8 hp_slot, void *inst_id)
rc++;
p_slot = shpchp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset);
- p_slot->hpc_ops->get_adapter_status(p_slot, &(func->presence_save));
+ p_slot->hpc_ops->get_adapter_status(p_slot, &(p_slot->presence_save));
p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
dbg("%s: Card present %x Power status %x\n", __FUNCTION__,
- func->presence_save, func->pwr_save);
+ p_slot->presence_save, p_slot->pwr_save);
if (getstatus) {
/*
* Switch opened
*/
info("Latch open on Slot(%d)\n", ctrl->first_slot + hp_slot);
- func->switch_save = 0;
taskInfo->event_type = INT_SWITCH_OPEN;
- if (func->pwr_save && func->presence_save) {
+ if (p_slot->pwr_save && p_slot->presence_save) {
taskInfo->event_type = INT_POWER_FAULT;
err("Surprise Removal of card\n");
}
@@ -156,7 +136,6 @@ u8 shpchp_handle_switch_change(u8 hp_slot, void *inst_id)
* Switch closed
*/
info("Latch close on Slot(%d)\n", ctrl->first_slot + hp_slot);
- func->switch_save = 0x10;
taskInfo->event_type = INT_SWITCH_CLOSE;
}
@@ -172,14 +151,11 @@ u8 shpchp_handle_presence_change(u8 hp_slot, void *inst_id)
struct slot *p_slot;
u8 rc = 0;
/*u8 temp_byte;*/
- struct pci_func *func;
struct event_info *taskInfo;
/* Presence Change */
dbg("shpchp: Presence/Notify input change.\n");
- func = shpchp_slot_find(ctrl->slot_bus, (hp_slot + ctrl->slot_device_offset), 0);
-
/* This is the structure that tells the worker thread
* what to do
*/
@@ -193,8 +169,8 @@ u8 shpchp_handle_presence_change(u8 hp_slot, void *inst_id)
/*
* Save the presence state
*/
- p_slot->hpc_ops->get_adapter_status(p_slot, &(func->presence_save));
- if (func->presence_save) {
+ p_slot->hpc_ops->get_adapter_status(p_slot, &(p_slot->presence_save));
+ if (p_slot->presence_save) {
/*
* Card Present
*/
@@ -219,14 +195,11 @@ u8 shpchp_handle_power_fault(u8 hp_slot, void *inst_id)
struct controller *ctrl = (struct controller *) inst_id;
struct slot *p_slot;
u8 rc = 0;
- struct pci_func *func;
struct event_info *taskInfo;
/* Power fault */
dbg("shpchp: Power fault interrupt received.\n");
- func = shpchp_slot_find(ctrl->slot_bus, (hp_slot + ctrl->slot_device_offset), 0);
-
/* This is the structure that tells the worker thread
* what to do
*/
@@ -242,7 +215,7 @@ u8 shpchp_handle_power_fault(u8 hp_slot, void *inst_id)
* Power fault Cleared
*/
info("Power fault cleared on Slot(%d)\n", ctrl->first_slot + hp_slot);
- func->status = 0x00;
+ p_slot->status = 0x00;
taskInfo->event_type = INT_POWER_FAULT_CLEAR;
} else {
/*
@@ -251,7 +224,7 @@ u8 shpchp_handle_power_fault(u8 hp_slot, void *inst_id)
info("Power fault on Slot(%d)\n", ctrl->first_slot + hp_slot);
taskInfo->event_type = INT_POWER_FAULT;
/* set power fault status for this board */
- func->status = 0xFF;
+ p_slot->status = 0xFF;
info("power fault bit %x set\n", hp_slot);
}
if (rc)
@@ -260,799 +233,13 @@ u8 shpchp_handle_power_fault(u8 hp_slot, void *inst_id)
return rc;
}
-
-/*
- * sort_by_size
- *
- * Sorts nodes on the list by their length.
- * Smallest first.
- *
- */
-static int sort_by_size(struct pci_resource **head)
-{
- struct pci_resource *current_res;
- struct pci_resource *next_res;
- int out_of_order = 1;
-
- if (!(*head))
- return(1);
-
- if (!((*head)->next))
- return(0);
-
- while (out_of_order) {
- out_of_order = 0;
-
- /* Special case for swapping list head */
- if (((*head)->next) &&
- ((*head)->length > (*head)->next->length)) {
- out_of_order++;
- current_res = *head;
- *head = (*head)->next;
- current_res->next = (*head)->next;
- (*head)->next = current_res;
- }
-
- current_res = *head;
-
- while (current_res->next && current_res->next->next) {
- if (current_res->next->length > current_res->next->next->length) {
- out_of_order++;
- next_res = current_res->next;
- current_res->next = current_res->next->next;
- current_res = current_res->next;
- next_res->next = current_res->next;
- current_res->next = next_res;
- } else
- current_res = current_res->next;
- }
- } /* End of out_of_order loop */
-
- return(0);
-}
-
-
-/*
- * sort_by_max_size
- *
- * Sorts nodes on the list by their length.
- * Largest first.
- *
- */
-static int sort_by_max_size(struct pci_resource **head)
-{
- struct pci_resource *current_res;
- struct pci_resource *next_res;
- int out_of_order = 1;
-
- if (!(*head))
- return(1);
-
- if (!((*head)->next))
- return(0);
-
- while (out_of_order) {
- out_of_order = 0;
-
- /* Special case for swapping list head */
- if (((*head)->next) &&
- ((*head)->length < (*head)->next->length)) {
- out_of_order++;
- current_res = *head;
- *head = (*head)->next;
- current_res->next = (*head)->next;
- (*head)->next = current_res;
- }
-
- current_res = *head;
-
- while (current_res->next && current_res->next->next) {
- if (current_res->next->length < current_res->next->next->length) {
- out_of_order++;
- next_res = current_res->next;
- current_res->next = current_res->next->next;
- current_res = current_res->next;
- next_res->next = current_res->next;
- current_res->next = next_res;
- } else
- current_res = current_res->next;
- }
- } /* End of out_of_order loop */
-
- return(0);
-}
-
-
-/*
- * do_pre_bridge_resource_split
- *
- * Returns zero or one node of resources that aren't in use
- *
- */
-static struct pci_resource *do_pre_bridge_resource_split (struct pci_resource **head, struct pci_resource **orig_head, u32 alignment)
-{
- struct pci_resource *prevnode = NULL;
- struct pci_resource *node;
- struct pci_resource *split_node;
- u32 rc;
- u32 temp_dword;
- dbg("do_pre_bridge_resource_split\n");
-
- if (!(*head) || !(*orig_head))
- return(NULL);
-
- rc = shpchp_resource_sort_and_combine(head);
-
- if (rc)
- return(NULL);
-
- if ((*head)->base != (*orig_head)->base)
- return(NULL);
-
- if ((*head)->length == (*orig_head)->length)
- return(NULL);
-
-
- /* If we got here, there the bridge requires some of the resource, but
- * 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.
- */
- split_node = kmalloc(sizeof(*split_node), GFP_KERNEL);
-
- if (!split_node)
- return(NULL);
-
- temp_dword = (node->length | (alignment-1)) + 1 - alignment;
-
- split_node->base = node->base;
- split_node->length = temp_dword;
-
- node->length -= temp_dword;
- node->base += split_node->length;
-
- /* Put it in the list */
- *head = split_node;
- split_node->next = node;
- }
-
- if (node->length < alignment) {
- return(NULL);
- }
-
- /* Now unlink it */
- if (*head == node) {
- *head = node->next;
- node->next = NULL;
- } else {
- prevnode = *head;
- while (prevnode->next != node)
- prevnode = prevnode->next;
-
- prevnode->next = node->next;
- node->next = NULL;
- }
-
- return(node);
-}
-
-
-/*
- * do_bridge_resource_split
- *
- * Returns zero or one node of resources that aren't in use
- *
- */
-static struct pci_resource *do_bridge_resource_split (struct pci_resource **head, u32 alignment)
-{
- struct pci_resource *prevnode = NULL;
- struct pci_resource *node;
- u32 rc;
- u32 temp_dword;
-
- if (!(*head))
- return(NULL);
-
- rc = shpchp_resource_sort_and_combine(head);
-
- if (rc)
- return(NULL);
-
- node = *head;
-
- while (node->next) {
- prevnode = node;
- node = node->next;
- kfree(prevnode);
- }
-
- if (node->length < alignment) {
- kfree(node);
- return(NULL);
- }
-
- if (node->base & (alignment - 1)) {
- /* Short circuit if adjusted size is too small */
- temp_dword = (node->base | (alignment-1)) + 1;
- if ((node->length - (temp_dword - node->base)) < alignment) {
- kfree(node);
- return(NULL);
- }
-
- node->length -= (temp_dword - node->base);
- node->base = temp_dword;
- }
-
- if (node->length & (alignment - 1)) {
- /* There's stuff in use after this node */
- kfree(node);
- return(NULL);
- }
-
- return(node);
-}
-
-
-/*
- * get_io_resource
- *
- * this function sorts the resource list by size and then
- * returns the first node of "size" length that is not in the
- * ISA aliasing window. If it finds a node larger than "size"
- * it will split it up.
- *
- * size must be a power of two.
- */
-static struct pci_resource *get_io_resource (struct pci_resource **head, u32 size)
-{
- struct pci_resource *prevnode;
- struct pci_resource *node;
- struct pci_resource *split_node = NULL;
- u32 temp_dword;
-
- if (!(*head))
- return(NULL);
-
- if ( shpchp_resource_sort_and_combine(head) )
- return(NULL);
-
- if ( sort_by_size(head) )
- return(NULL);
-
- for (node = *head; node; node = node->next) {
- if (node->length < size)
- continue;
-
- if (node->base & (size - 1)) {
- /* This one isn't base aligned properly
- 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 */
- if ((node->length - (temp_dword - node->base)) < size)
- continue;
-
- split_node = kmalloc(sizeof(*split_node), GFP_KERNEL);
-
- if (!split_node)
- return(NULL);
-
- split_node->base = node->base;
- split_node->length = temp_dword - node->base;
- node->base = temp_dword;
- node->length -= split_node->length;
-
- /* Put it in the list */
- split_node->next = node->next;
- node->next = split_node;
- } /* End of non-aligned base */
-
- /* 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 */
- split_node = kmalloc(sizeof(*split_node), GFP_KERNEL);
-
- if (!split_node)
- return(NULL);
-
- split_node->base = node->base + size;
- split_node->length = node->length - size;
- node->length = size;
-
- /* Put it in the list */
- split_node->next = node->next;
- node->next = split_node;
- } /* End of too big on top end */
-
- /* For IO make sure it's not in the ISA aliasing space */
- if (node->base & 0x300L)
- continue;
-
- /* If we got here, then it is the right size
- Now take it out of the list */
- if (*head == node) {
- *head = node->next;
- } else {
- prevnode = *head;
- while (prevnode->next != node)
- prevnode = prevnode->next;
-
- prevnode->next = node->next;
- }
- node->next = NULL;
- /* Stop looping */
- break;
- }
-
- return(node);
-}
-
-
-/*
- * get_max_resource
- *
- * Gets the largest node that is at least "size" big from the
- * list pointed to by head. It aligns the node on top and bottom
- * to "size" alignment before returning it.
- * J.I. modified to put max size limits of; 64M->32M->16M->8M->4M->1M
- * This is needed to avoid allocating entire ACPI _CRS res to one child bridge/slot.
- */
-static struct pci_resource *get_max_resource (struct pci_resource **head, u32 size)
-{
- struct pci_resource *max;
- struct pci_resource *temp;
- struct pci_resource *split_node;
- u32 temp_dword;
- u32 max_size[] = { 0x4000000, 0x2000000, 0x1000000, 0x0800000, 0x0400000, 0x0200000, 0x0100000, 0x00 };
- int i;
-
- if (!(*head))
- return(NULL);
-
- if (shpchp_resource_sort_and_combine(head))
- return(NULL);
-
- if (sort_by_max_size(head))
- 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 (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 */
- temp_dword = (max->base | (size-1)) + 1;
-
- /* Short circuit if adjusted size is too small */
- if ((max->length - (temp_dword - max->base)) < size)
- continue;
-
- split_node = kmalloc(sizeof(*split_node), GFP_KERNEL);
-
- if (!split_node)
- return(NULL);
-
- split_node->base = max->base;
- split_node->length = temp_dword - max->base;
- max->base = temp_dword;
- max->length -= split_node->length;
-
- /* Put it next in the list */
- split_node->next = max->next;
- max->next = split_node;
- }
-
- 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 */
- split_node = kmalloc(sizeof(*split_node), GFP_KERNEL);
-
- if (!split_node)
- return(NULL);
- temp_dword = ((max->base + max->length) & ~(size - 1));
- split_node->base = temp_dword;
- split_node->length = max->length + max->base
- - split_node->base;
- max->length -= split_node->length;
-
- /* Put it in the list */
- split_node->next = max->next;
- max->next = split_node;
- }
-
- /* Make sure it didn't shrink too much when we aligned it */
- if (max->length < size)
- continue;
-
- for ( i = 0; max_size[i] > size; i++) {
- if (max->length > max_size[i]) {
- split_node = kmalloc(sizeof(*split_node),
- GFP_KERNEL);
- if (!split_node)
- break; /* return (NULL); */
- split_node->base = max->base + max_size[i];
- split_node->length = max->length - max_size[i];
- max->length = max_size[i];
- /* Put it next in the list */
- split_node->next = max->next;
- max->next = split_node;
- break;
- }
- }
-
- /* Now take it out of the list */
- temp = (struct pci_resource*) *head;
- if (temp == max) {
- *head = max->next;
- } else {
- while (temp && temp->next != max) {
- temp = temp->next;
- }
-
- temp->next = max->next;
- }
-
- max->next = NULL;
- return(max);
- }
-
- /* If we get here, we couldn't find one */
- return(NULL);
-}
-
-
-/*
- * get_resource
- *
- * this function sorts the resource list by size and then
- * returns the first node of "size" length. If it finds a node
- * larger than "size" it will split it up.
- *
- * size must be a power of two.
- */
-static struct pci_resource *get_resource (struct pci_resource **head, u32 size)
-{
- struct pci_resource *prevnode;
- struct pci_resource *node;
- struct pci_resource *split_node;
- u32 temp_dword;
-
- if (!(*head))
- return(NULL);
-
- if ( shpchp_resource_sort_and_combine(head) )
- return(NULL);
-
- if ( sort_by_size(head) )
- return(NULL);
-
- for (node = *head; node; node = node->next) {
- dbg("%s: req_size =0x%x node=%p, base=0x%x, length=0x%x\n",
- __FUNCTION__, size, node, node->base, node->length);
- if (node->length < size)
- continue;
-
- if (node->base & (size - 1)) {
- dbg("%s: not aligned\n", __FUNCTION__);
- /* this one isn't base aligned properly
- 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 */
- if ((node->length - (temp_dword - node->base)) < size)
- continue;
-
- split_node = kmalloc(sizeof(*split_node), GFP_KERNEL);
-
- if (!split_node)
- return(NULL);
-
- split_node->base = node->base;
- split_node->length = temp_dword - node->base;
- node->base = temp_dword;
- node->length -= split_node->length;
-
- /* Put it in the list */
- split_node->next = node->next;
- node->next = split_node;
- } /* End of non-aligned base */
-
- /* Don't need to check if too small since we already did */
- if (node->length > size) {
- dbg("%s: too big\n", __FUNCTION__);
- /* this one is longer than we need
- so we'll make a new entry and split it up */
- split_node = kmalloc(sizeof(*split_node), GFP_KERNEL);
-
- if (!split_node)
- return(NULL);
-
- split_node->base = node->base + size;
- split_node->length = node->length - size;
- node->length = size;
-
- /* Put it in the list */
- split_node->next = node->next;
- node->next = split_node;
- } /* End of too big on top end */
-
- dbg("%s: got one!!!\n", __FUNCTION__);
- /* If we got here, then it is the right size
- Now take it out of the list */
- if (*head == node) {
- *head = node->next;
- } else {
- prevnode = *head;
- while (prevnode->next != node)
- prevnode = prevnode->next;
-
- prevnode->next = node->next;
- }
- node->next = NULL;
- /* Stop looping */
- break;
- }
- return(node);
-}
-
-
-/*
- * shpchp_resource_sort_and_combine
- *
- * Sorts all of the nodes in the list in ascending order by
- * their base addresses. Also does garbage collection by
- * combining adjacent nodes.
- *
- * returns 0 if success
- */
-int shpchp_resource_sort_and_combine(struct pci_resource **head)
-{
- struct pci_resource *node1;
- struct pci_resource *node2;
- int out_of_order = 1;
-
- dbg("%s: head = %p, *head = %p\n", __FUNCTION__, head, *head);
-
- if (!(*head))
- return(1);
-
- dbg("*head->next = %p\n",(*head)->next);
-
- if (!(*head)->next)
- return(0); /* only one item on the list, already sorted! */
-
- dbg("*head->base = 0x%x\n",(*head)->base);
- dbg("*head->next->base = 0x%x\n",(*head)->next->base);
- while (out_of_order) {
- out_of_order = 0;
-
- /* Special case for swapping list head */
- if (((*head)->next) &&
- ((*head)->base > (*head)->next->base)) {
- node1 = *head;
- (*head) = (*head)->next;
- node1->next = (*head)->next;
- (*head)->next = node1;
- out_of_order++;
- }
-
- node1 = (*head);
-
- while (node1->next && node1->next->next) {
- if (node1->next->base > node1->next->next->base) {
- out_of_order++;
- node2 = node1->next;
- node1->next = node1->next->next;
- node1 = node1->next;
- node2->next = node1->next;
- node1->next = node2;
- } else
- node1 = node1->next;
- }
- } /* End of out_of_order loop */
-
- node1 = *head;
-
- while (node1 && node1->next) {
- if ((node1->base + node1->length) == node1->next->base) {
- /* Combine */
- dbg("8..\n");
- node1->length += node1->next->length;
- node2 = node1->next;
- node1->next = node1->next->next;
- kfree(node2);
- } else
- node1 = node1->next;
- }
-
- return(0);
-}
-
-
-/**
- * shpchp_slot_create - Creates a node and adds it to the proper bus.
- * @busnumber - bus where new node is to be located
- *
- * Returns pointer to the new node or NULL if unsuccessful
- */
-struct pci_func *shpchp_slot_create(u8 busnumber)
-{
- struct pci_func *new_slot;
- struct pci_func *next;
-
- new_slot = kmalloc(sizeof(*new_slot), GFP_KERNEL);
-
- if (new_slot == NULL) {
- return(new_slot);
- }
-
- memset(new_slot, 0, sizeof(struct pci_func));
-
- new_slot->next = NULL;
- new_slot->configured = 1;
-
- if (shpchp_slot_list[busnumber] == NULL) {
- shpchp_slot_list[busnumber] = new_slot;
- } else {
- next = shpchp_slot_list[busnumber];
- while (next->next != NULL)
- next = next->next;
- next->next = new_slot;
- }
- return(new_slot);
-}
-
-
-/*
- * slot_remove - Removes a node from the linked list of slots.
- * @old_slot: slot to remove
- *
- * Returns 0 if successful, !0 otherwise.
- */
-static int slot_remove(struct pci_func * old_slot)
-{
- struct pci_func *next;
-
- if (old_slot == NULL)
- return(1);
-
- next = shpchp_slot_list[old_slot->bus];
-
- if (next == NULL) {
- return(1);
- }
-
- if (next == old_slot) {
- shpchp_slot_list[old_slot->bus] = old_slot->next;
- shpchp_destroy_board_resources(old_slot);
- kfree(old_slot);
- return(0);
- }
-
- while ((next->next != old_slot) && (next->next != NULL)) {
- next = next->next;
- }
-
- if (next->next == old_slot) {
- next->next = old_slot->next;
- shpchp_destroy_board_resources(old_slot);
- kfree(old_slot);
- return(0);
- } else
- return(2);
-}
-
-
-/**
- * bridge_slot_remove - Removes a node from the linked list of slots.
- * @bridge: bridge to remove
- *
- * Returns 0 if successful, !0 otherwise.
- */
-static int bridge_slot_remove(struct pci_func *bridge)
-{
- u8 subordinateBus, secondaryBus;
- u8 tempBus;
- struct pci_func *next;
-
- if (bridge == NULL)
- return(1);
-
- secondaryBus = (bridge->config_space[0x06] >> 8) & 0xFF;
- subordinateBus = (bridge->config_space[0x06] >> 16) & 0xFF;
-
- for (tempBus = secondaryBus; tempBus <= subordinateBus; tempBus++) {
- next = shpchp_slot_list[tempBus];
-
- while (!slot_remove(next)) {
- next = shpchp_slot_list[tempBus];
- }
- }
-
- next = shpchp_slot_list[bridge->bus];
-
- if (next == NULL) {
- return(1);
- }
-
- if (next == bridge) {
- shpchp_slot_list[bridge->bus] = bridge->next;
- kfree(bridge);
- return(0);
- }
-
- while ((next->next != bridge) && (next->next != NULL)) {
- next = next->next;
- }
-
- if (next->next == bridge) {
- next->next = bridge->next;
- kfree(bridge);
- return(0);
- } else
- return(2);
-}
-
-
-/**
- * shpchp_slot_find - Looks for a node by bus, and device, multiple functions accessed
- * @bus: bus to find
- * @device: device to find
- * @index: is 0 for first function found, 1 for the second...
- *
- * Returns pointer to the node if successful, %NULL otherwise.
- */
-struct pci_func *shpchp_slot_find(u8 bus, u8 device, u8 index)
-{
- int found = -1;
- struct pci_func *func;
-
- func = shpchp_slot_list[bus];
-
- if ((func == NULL) || ((func->device == device) && (index == 0)))
- return(func);
-
- if (func->device == device)
- found++;
-
- while (func->next != NULL) {
- func = func->next;
-
- if (func->device == device)
- found++;
-
- if (found == index)
- return(func);
- }
-
- return(NULL);
-}
-
-static int is_bridge(struct pci_func * func)
-{
- /* Check the header type */
- if (((func->config_space[0x03] >> 16) & 0xFF) == 0x01)
- return 1;
- else
- return 0;
-}
-
-
/* The following routines constitute the bulk of the
hotplug controller logic
*/
-static u32 change_bus_speed(struct controller *ctrl, struct slot *p_slot, enum pci_bus_speed speed)
+static int change_bus_speed(struct controller *ctrl, struct slot *p_slot,
+ enum pci_bus_speed speed)
{
- u32 rc = 0;
+ int rc = 0;
dbg("%s: change to speed %d\n", __FUNCTION__, speed);
down(&ctrl->crit_sect);
@@ -1074,10 +261,11 @@ static u32 change_bus_speed(struct controller *ctrl, struct slot *p_slot, enum p
return rc;
}
-static u32 fix_bus_speed(struct controller *ctrl, struct slot *pslot, u8 flag,
-enum pci_bus_speed asp, enum pci_bus_speed bsp, enum pci_bus_speed msp)
+static int fix_bus_speed(struct controller *ctrl, struct slot *pslot,
+ u8 flag, enum pci_bus_speed asp, enum pci_bus_speed bsp,
+ enum pci_bus_speed msp)
{
- u32 rc = 0;
+ int rc = 0;
if (flag != 0) { /* Other slots on the same bus are occupied */
if ( asp < bsp ) {
@@ -1116,23 +304,20 @@ enum pci_bus_speed asp, enum pci_bus_speed bsp, enum pci_bus_speed msp)
* Configures board
*
*/
-static u32 board_added(struct pci_func * func, struct controller * ctrl)
+static int board_added(struct slot *p_slot)
{
u8 hp_slot;
u8 slots_not_empty = 0;
- int index;
- u32 temp_register = 0xFFFFFFFF;
- u32 retval, rc = 0;
- struct pci_func *new_func = NULL;
- struct slot *p_slot;
- struct resource_lists res_lists;
+ int rc = 0;
enum pci_bus_speed adapter_speed, bus_speed, max_bus_speed;
u8 pi, mode;
+ struct controller *ctrl = p_slot->ctrl;
- p_slot = shpchp_find_slot(ctrl, func->device);
- hp_slot = func->device - ctrl->slot_device_offset;
+ hp_slot = p_slot->device - ctrl->slot_device_offset;
- dbg("%s: func->device, slot_offset, hp_slot = %d, %d ,%d\n", __FUNCTION__, func->device, ctrl->slot_device_offset, hp_slot);
+ dbg("%s: p_slot->device, slot_offset, hp_slot = %d, %d ,%d\n",
+ __FUNCTION__, p_slot->device,
+ ctrl->slot_device_offset, hp_slot);
/* Wait for exclusive access to hardware */
down(&ctrl->crit_sect);
@@ -1320,143 +505,68 @@ static u32 board_added(struct pci_func * func, struct controller * ctrl)
up(&ctrl->crit_sect);
/* Wait for ~1 second */
- dbg("%s: before long_delay\n", __FUNCTION__);
wait_for_ctrl_irq (ctrl);
- dbg("%s: after long_delay\n", __FUNCTION__);
- dbg("%s: func status = %x\n", __FUNCTION__, func->status);
+ dbg("%s: slot status = %x\n", __FUNCTION__, p_slot->status);
/* Check for a power fault */
- if (func->status == 0xFF) {
+ if (p_slot->status == 0xFF) {
/* power fault occurred, but it was benign */
- temp_register = 0xFFFFFFFF;
- dbg("%s: temp register set to %x by power fault\n", __FUNCTION__, temp_register);
+ dbg("%s: power fault\n", __FUNCTION__);
rc = POWER_FAILURE;
- func->status = 0;
- } else {
- /* Get vendor/device ID u32 */
- rc = pci_bus_read_config_dword (ctrl->pci_dev->subordinate, PCI_DEVFN(func->device, func->function),
- PCI_VENDOR_ID, &temp_register);
- dbg("%s: pci_bus_read_config_dword returns %d\n", __FUNCTION__, rc);
- dbg("%s: temp_register is %x\n", __FUNCTION__, temp_register);
-
- if (rc != 0) {
- /* Something's wrong here */
- temp_register = 0xFFFFFFFF;
- dbg("%s: temp register set to %x by error\n", __FUNCTION__, temp_register);
- }
- /* Preset return code. It will be changed later if things go okay. */
- rc = NO_ADAPTER_PRESENT;
+ p_slot->status = 0;
+ goto err_exit;
}
- /* All F's is an empty slot or an invalid board */
- if (temp_register != 0xFFFFFFFF) { /* Check for a board in the slot */
- res_lists.io_head = ctrl->io_head;
- res_lists.mem_head = ctrl->mem_head;
- res_lists.p_mem_head = ctrl->p_mem_head;
- res_lists.bus_head = ctrl->bus_head;
- res_lists.irqs = NULL;
-
- rc = configure_new_device(ctrl, func, 0, &res_lists, 0, 0);
- dbg("%s: back from configure_new_device\n", __FUNCTION__);
-
- ctrl->io_head = res_lists.io_head;
- ctrl->mem_head = res_lists.mem_head;
- ctrl->p_mem_head = res_lists.p_mem_head;
- ctrl->bus_head = res_lists.bus_head;
-
- shpchp_resource_sort_and_combine(&(ctrl->mem_head));
- shpchp_resource_sort_and_combine(&(ctrl->p_mem_head));
- shpchp_resource_sort_and_combine(&(ctrl->io_head));
- shpchp_resource_sort_and_combine(&(ctrl->bus_head));
-
- if (rc) {
- /* Wait for exclusive access to hardware */
- down(&ctrl->crit_sect);
-
- /* turn off slot, turn on Amber LED, turn off Green LED */
- retval = p_slot->hpc_ops->slot_disable(p_slot);
- if (retval) {
- err("%s: Issue of Slot Enable command failed\n", __FUNCTION__);
- /* Done with exclusive hardware access */
- up(&ctrl->crit_sect);
- return retval;
- }
- /* Wait for the command to complete */
- wait_for_ctrl_irq (ctrl);
-
- retval = p_slot->hpc_ops->check_cmd_status(ctrl);
- if (retval) {
- err("%s: Failed to disable slot, error code(%d)\n", __FUNCTION__, retval);
- /* Done with exclusive hardware access */
- up(&ctrl->crit_sect);
- return retval;
- }
-
- /* Done with exclusive hardware access */
- up(&ctrl->crit_sect);
+ if (shpchp_configure_device(p_slot)) {
+ err("Cannot add device at 0x%x:0x%x\n", p_slot->bus,
+ p_slot->device);
+ goto err_exit;
+ }
- return(rc);
- }
- shpchp_save_slot_config(ctrl, func);
+ p_slot->status = 0;
+ p_slot->is_a_board = 0x01;
+ p_slot->pwr_save = 1;
- func->status = 0;
- func->switch_save = 0x10;
- func->is_a_board = 0x01;
- func->pwr_save = 1;
+ /* Wait for exclusive access to hardware */
+ down(&ctrl->crit_sect);
- /* Next, we will instantiate the linux pci_dev structures
- * (with appropriate driver notification, if already present)
- */
- index = 0;
- do {
- new_func = shpchp_slot_find(ctrl->slot_bus, func->device, index++);
- if (new_func && !new_func->pci_dev) {
- dbg("%s:call pci_hp_configure_dev\n", __FUNCTION__);
- shpchp_configure_device(ctrl, new_func);
- }
- } while (new_func);
+ p_slot->hpc_ops->green_led_on(p_slot);
- /* Wait for exclusive access to hardware */
- down(&ctrl->crit_sect);
+ /* Wait for the command to complete */
+ wait_for_ctrl_irq (ctrl);
- p_slot->hpc_ops->green_led_on(p_slot);
+ /* Done with exclusive hardware access */
+ up(&ctrl->crit_sect);
- /* Wait for the command to complete */
- wait_for_ctrl_irq (ctrl);
+ return 0;
+err_exit:
+ /* Wait for exclusive access to hardware */
+ down(&ctrl->crit_sect);
+ /* turn off slot, turn on Amber LED, turn off Green LED */
+ rc = p_slot->hpc_ops->slot_disable(p_slot);
+ if (rc) {
+ err("%s: Issue of Slot Disable command failed\n", __FUNCTION__);
/* Done with exclusive hardware access */
up(&ctrl->crit_sect);
+ return rc;
+ }
+ /* Wait for the command to complete */
+ wait_for_ctrl_irq (ctrl);
- } else {
- /* Wait for exclusive access to hardware */
- down(&ctrl->crit_sect);
-
- /* turn off slot, turn on Amber LED, turn off Green LED */
- rc = p_slot->hpc_ops->slot_disable(p_slot);
- if (rc) {
- err("%s: Issue of Slot Disable command failed\n", __FUNCTION__);
- /* Done with exclusive hardware access */
- up(&ctrl->crit_sect);
- return rc;
- }
- /* Wait for the command to complete */
- wait_for_ctrl_irq (ctrl);
-
- rc = p_slot->hpc_ops->check_cmd_status(ctrl);
- if (rc) {
- err("%s: Failed to disable slot, error code(%d)\n", __FUNCTION__, rc);
- /* Done with exclusive hardware access */
- up(&ctrl->crit_sect);
- return rc;
- }
-
+ rc = p_slot->hpc_ops->check_cmd_status(ctrl);
+ if (rc) {
+ err("%s: Failed to disable slot, error code(%d)\n", __FUNCTION__, rc);
/* Done with exclusive hardware access */
up(&ctrl->crit_sect);
-
- return(rc);
+ return rc;
}
- return 0;
+
+ /* Done with exclusive hardware access */
+ up(&ctrl->crit_sect);
+
+ return(rc);
}
@@ -1464,55 +574,23 @@ static u32 board_added(struct pci_func * func, struct controller * ctrl)
* remove_board - Turns off slot and LED's
*
*/
-static u32 remove_board(struct pci_func *func, struct controller *ctrl)
+static int remove_board(struct slot *p_slot)
{
- int index;
- u8 skip = 0;
- u8 device;
+ struct controller *ctrl = p_slot->ctrl;
u8 hp_slot;
- u32 rc;
- struct resource_lists res_lists;
- struct pci_func *temp_func;
- struct slot *p_slot;
-
- if (func == NULL)
- return(1);
+ int rc;
- if (shpchp_unconfigure_device(func))
+ if (shpchp_unconfigure_device(p_slot))
return(1);
- device = func->device;
-
- hp_slot = func->device - ctrl->slot_device_offset;
+ hp_slot = p_slot->device - ctrl->slot_device_offset;
p_slot = shpchp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset);
dbg("In %s, hp_slot = %d\n", __FUNCTION__, hp_slot);
- if ((ctrl->add_support) &&
- !(func->bus_head || func->mem_head || func->p_mem_head || func->io_head)) {
- /* Here we check to see if we've saved any of the board's
- * resources already. If so, we'll skip the attempt to
- * determine what's being used.
- */
- index = 0;
-
- temp_func = func;
-
- while ((temp_func = shpchp_slot_find(temp_func->bus, temp_func->device, index++))) {
- if (temp_func->bus_head || temp_func->mem_head
- || temp_func->p_mem_head || temp_func->io_head) {
- skip = 1;
- break;
- }
- }
-
- if (!skip)
- rc = shpchp_save_used_resources(ctrl, func, DISABLE_CARD);
- }
/* Change status to shutdown */
- if (func->is_a_board)
- func->status = 0x01;
- func->configured = 0;
+ if (p_slot->is_a_board)
+ p_slot->status = 0x01;
/* Wait for exclusive access to hardware */
down(&ctrl->crit_sect);
@@ -1549,55 +627,8 @@ static u32 remove_board(struct pci_func *func, struct controller *ctrl)
/* Done with exclusive hardware access */
up(&ctrl->crit_sect);
- if (ctrl->add_support) {
- while (func) {
- res_lists.io_head = ctrl->io_head;
- res_lists.mem_head = ctrl->mem_head;
- res_lists.p_mem_head = ctrl->p_mem_head;
- res_lists.bus_head = ctrl->bus_head;
-
- dbg("Returning resources to ctlr lists for (B/D/F) = (%#x/%#x/%#x)\n", func->bus,
- func->device, func->function);
-
- shpchp_return_board_resources(func, &res_lists);
-
- ctrl->io_head = res_lists.io_head;
- ctrl->mem_head = res_lists.mem_head;
- ctrl->p_mem_head = res_lists.p_mem_head;
- ctrl->bus_head = res_lists.bus_head;
-
- shpchp_resource_sort_and_combine(&(ctrl->mem_head));
- shpchp_resource_sort_and_combine(&(ctrl->p_mem_head));
- shpchp_resource_sort_and_combine(&(ctrl->io_head));
- shpchp_resource_sort_and_combine(&(ctrl->bus_head));
-
- if (is_bridge(func)) {
- dbg("PCI Bridge Hot-Remove s:b:d:f(%02x:%02x:%02x:%02x)\n", ctrl->seg, func->bus,
- func->device, func->function);
- bridge_slot_remove(func);
- } else
- dbg("PCI Function Hot-Remove s:b:d:f(%02x:%02x:%02x:%02x)\n", ctrl->seg, func->bus,
- func->device, func->function);
- slot_remove(func);
-
- func = shpchp_slot_find(ctrl->slot_bus, device, 0);
- }
-
- /* Setup slot structure with entry for empty slot */
- func = shpchp_slot_create(ctrl->slot_bus);
-
- if (func == NULL) {
- return(1);
- }
-
- func->bus = ctrl->slot_bus;
- func->device = device;
- func->function = 0;
- func->configured = 0;
- func->switch_save = 0x10;
- func->pwr_save = 0;
- func->is_a_board = 0;
- }
+ p_slot->pwr_save = 0;
+ p_slot->is_a_board = 0;
return 0;
}
@@ -1633,13 +664,11 @@ static void shpchp_pushbutton_thread (unsigned long slot)
p_slot->hpc_ops->get_power_status(p_slot, &getstatus);
if (getstatus) {
p_slot->state = POWEROFF_STATE;
- dbg("In power_down_board, b:d(%x:%x)\n", p_slot->bus, p_slot->device);
shpchp_disable_slot(p_slot);
p_slot->state = STATIC_STATE;
} else {
p_slot->state = POWERON_STATE;
- dbg("In add_board, b:d(%x:%x)\n", p_slot->bus, p_slot->device);
if (shpchp_enable_slot(p_slot)) {
/* Wait for exclusive access to hardware */
@@ -1701,7 +730,6 @@ int shpchp_event_start_thread (void)
err ("Can't start up our event thread\n");
return -1;
}
- dbg("Our event thread pid = %d\n", pid);
return 0;
}
@@ -1709,9 +737,7 @@ int shpchp_event_start_thread (void)
void shpchp_event_stop_thread (void)
{
event_finished = 1;
- dbg("event_thread finish command given\n");
up(&event_semaphore);
- dbg("wait for event_thread to exit\n");
down(&event_exit);
}
@@ -1739,12 +765,10 @@ static void interrupt_event_handler(struct controller *ctrl)
{
int loop = 0;
int change = 1;
- struct pci_func *func;
u8 hp_slot;
u8 getstatus;
struct slot *p_slot;
- dbg("%s:\n", __FUNCTION__);
while (change) {
change = 0;
@@ -1754,12 +778,8 @@ static void interrupt_event_handler(struct controller *ctrl)
ctrl->event_queue[loop].event_type);
hp_slot = ctrl->event_queue[loop].hp_slot;
- func = shpchp_slot_find(ctrl->slot_bus, (hp_slot + ctrl->slot_device_offset), 0);
-
p_slot = shpchp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset);
- dbg("%s: hp_slot %d, func %p, p_slot %p\n", __FUNCTION__, hp_slot, func, p_slot);
-
if (ctrl->event_queue[loop].event_type == INT_BUTTON_CANCEL) {
dbg("%s: button cancel\n", __FUNCTION__);
del_timer(&p_slot->task_event);
@@ -1880,13 +900,6 @@ int shpchp_enable_slot (struct slot *p_slot)
{
u8 getstatus = 0;
int rc;
- struct pci_func *func;
-
- func = shpchp_slot_find(p_slot->bus, p_slot->device, 0);
- if (!func) {
- dbg("%s: Error! slot NULL\n", __FUNCTION__);
- return -ENODEV;
- }
/* Check to see if (latch closed, card present, power off) */
down(&p_slot->ctrl->crit_sect);
@@ -1910,72 +923,34 @@ int shpchp_enable_slot (struct slot *p_slot)
}
up(&p_slot->ctrl->crit_sect);
- slot_remove(func);
-
- func = shpchp_slot_create(p_slot->bus);
- if (func == NULL)
- return -ENOMEM;
-
- func->bus = p_slot->bus;
- func->device = p_slot->device;
- func->function = 0;
- func->configured = 0;
- func->is_a_board = 1;
+ p_slot->is_a_board = 1;
/* We have to save the presence info for these slots */
- p_slot->hpc_ops->get_adapter_status(p_slot, &(func->presence_save));
- p_slot->hpc_ops->get_power_status(p_slot, &(func->pwr_save));
- dbg("%s: func->pwr_save %x\n", __FUNCTION__, func->pwr_save);
+ p_slot->hpc_ops->get_adapter_status(p_slot, &(p_slot->presence_save));
+ p_slot->hpc_ops->get_power_status(p_slot, &(p_slot->pwr_save));
+ dbg("%s: p_slot->pwr_save %x\n", __FUNCTION__, p_slot->pwr_save);
p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
- func->switch_save = !getstatus? 0x10:0;
- rc = board_added(func, p_slot->ctrl);
+ rc = board_added(p_slot);
if (rc) {
- if (is_bridge(func))
- bridge_slot_remove(func);
- else
- slot_remove(func);
-
- /* Setup slot structure with entry for empty slot */
- func = shpchp_slot_create(p_slot->bus);
- if (func == NULL)
- return -ENOMEM; /* Out of memory */
-
- func->bus = p_slot->bus;
- func->device = p_slot->device;
- func->function = 0;
- func->configured = 0;
- func->is_a_board = 1;
-
- /* We have to save the presence info for these slots */
- p_slot->hpc_ops->get_adapter_status(p_slot, &(func->presence_save));
+ p_slot->hpc_ops->get_adapter_status(p_slot,
+ &(p_slot->presence_save));
p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
- func->switch_save = !getstatus? 0x10:0;
}
- if (p_slot)
- update_slot_info(p_slot);
-
+ update_slot_info(p_slot);
return rc;
}
int shpchp_disable_slot (struct slot *p_slot)
{
- u8 class_code, header_type, BCR;
- u8 index = 0;
u8 getstatus = 0;
- u32 rc = 0;
int ret = 0;
- unsigned int devfn;
- struct pci_bus *pci_bus;
- struct pci_func *func;
if (!p_slot->ctrl)
return -ENODEV;
- pci_bus = p_slot->ctrl->pci_dev->subordinate;
-
/* Check to see if (latch closed, card present, power on) */
down(&p_slot->ctrl->crit_sect);
@@ -1999,849 +974,8 @@ int shpchp_disable_slot (struct slot *p_slot)
}
up(&p_slot->ctrl->crit_sect);
- func = shpchp_slot_find(p_slot->bus, p_slot->device, index++);
-
- /* Make sure there are no video controllers here
- * for all func of p_slot
- */
- while (func && !rc) {
- pci_bus->number = func->bus;
- devfn = PCI_DEVFN(func->device, func->function);
-
- /* Check the Class Code */
- rc = pci_bus_read_config_byte (pci_bus, devfn, 0x0B, &class_code);
- if (rc)
- return -ENODEV;
-
- if (class_code == PCI_BASE_CLASS_DISPLAY) {
- /* Display/Video adapter (not supported) */
- rc = REMOVE_NOT_SUPPORTED;
- } else {
- /* See if it's a bridge */
- rc = pci_bus_read_config_byte (pci_bus, devfn, PCI_HEADER_TYPE, &header_type);
- if (rc)
- return -ENODEV;
-
- /* If it's a bridge, check the VGA Enable bit */
- if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) {
- rc = pci_bus_read_config_byte (pci_bus, devfn, PCI_BRIDGE_CONTROL, &BCR);
- if (rc)
- return -ENODEV;
-
- /* If the VGA Enable bit is set, remove isn't supported */
- if (BCR & PCI_BRIDGE_CTL_VGA) {
- rc = REMOVE_NOT_SUPPORTED;
- }
- }
- }
-
- func = shpchp_slot_find(p_slot->bus, p_slot->device, index++);
- }
-
- func = shpchp_slot_find(p_slot->bus, p_slot->device, 0);
- if ((func != NULL) && !rc) {
- rc = remove_board(func, p_slot->ctrl);
- } else if (!rc)
- rc = -ENODEV;
-
- if (p_slot)
- update_slot_info(p_slot);
-
- return rc;
-}
-
-
-/**
- * configure_new_device - Configures the PCI header information of one board.
- *
- * @ctrl: pointer to controller structure
- * @func: pointer to function structure
- * @behind_bridge: 1 if this is a recursive call, 0 if not
- * @resources: pointer to set of resource lists
- *
- * Returns 0 if success
- *
- */
-static u32 configure_new_device (struct controller * ctrl, struct pci_func * func,
- u8 behind_bridge, struct resource_lists * resources, u8 bridge_bus, u8 bridge_dev)
-{
- u8 temp_byte, function, max_functions, stop_it;
- int rc;
- u32 ID;
- struct pci_func *new_slot;
- struct pci_bus lpci_bus, *pci_bus;
- int index;
-
- new_slot = func;
-
- dbg("%s\n", __FUNCTION__);
- memcpy(&lpci_bus, ctrl->pci_dev->subordinate, sizeof(lpci_bus));
- pci_bus = &lpci_bus;
- pci_bus->number = func->bus;
-
- /* Check for Multi-function device */
- rc = pci_bus_read_config_byte(pci_bus, PCI_DEVFN(func->device, func->function), 0x0E, &temp_byte);
- if (rc) {
- dbg("%s: rc = %d\n", __FUNCTION__, rc);
- return rc;
- }
-
- if (temp_byte & 0x80) /* Multi-function device */
- max_functions = 8;
- else
- max_functions = 1;
-
- function = 0;
-
- do {
- rc = configure_new_function(ctrl, new_slot, behind_bridge, resources, bridge_bus, bridge_dev);
-
- if (rc) {
- dbg("configure_new_function failed %d\n",rc);
- index = 0;
-
- while (new_slot) {
- new_slot = shpchp_slot_find(new_slot->bus, new_slot->device, index++);
-
- if (new_slot)
- shpchp_return_board_resources(new_slot, resources);
- }
-
- return(rc);
- }
-
- function++;
-
- stop_it = 0;
-
- /* The following loop skips to the next present function
- * and creates a board structure
- */
-
- while ((function < max_functions) && (!stop_it)) {
- pci_bus_read_config_dword(pci_bus, PCI_DEVFN(func->device, function), 0x00, &ID);
-
- if (ID == 0xFFFFFFFF) { /* There's nothing there. */
- function++;
- } else { /* There's something there */
- /* Setup slot structure. */
- new_slot = shpchp_slot_create(func->bus);
-
- if (new_slot == NULL) {
- /* Out of memory */
- return(1);
- }
-
- new_slot->bus = func->bus;
- new_slot->device = func->device;
- new_slot->function = function;
- new_slot->is_a_board = 1;
- new_slot->status = 0;
-
- stop_it++;
- }
- }
-
- } while (function < max_functions);
- dbg("returning from configure_new_device\n");
-
- return 0;
-}
-
-
-/*
- * Configuration logic that involves the hotplug data structures and
- * their bookkeeping
- */
-
-
-/**
- * configure_new_function - Configures the PCI header information of one device
- *
- * @ctrl: pointer to controller structure
- * @func: pointer to function structure
- * @behind_bridge: 1 if this is a recursive call, 0 if not
- * @resources: pointer to set of resource lists
- *
- * Calls itself recursively for bridged devices.
- * Returns 0 if success
- *
- */
-static int configure_new_function (struct controller * ctrl, struct pci_func * func,
- u8 behind_bridge, struct resource_lists *resources, u8 bridge_bus, u8 bridge_dev)
-{
- int cloop;
- u8 temp_byte;
- u8 device;
- u8 class_code;
- u16 temp_word;
- u32 rc;
- u32 temp_register;
- u32 base;
- u32 ID;
- unsigned int devfn;
- struct pci_resource *mem_node;
- struct pci_resource *p_mem_node;
- struct pci_resource *io_node;
- struct pci_resource *bus_node;
- struct pci_resource *hold_mem_node;
- struct pci_resource *hold_p_mem_node;
- struct pci_resource *hold_IO_node;
- struct pci_resource *hold_bus_node;
- struct irq_mapping irqs;
- struct pci_func *new_slot;
- struct pci_bus lpci_bus, *pci_bus;
- struct resource_lists temp_resources;
-#if defined(CONFIG_X86_64)
- u8 IRQ=0;
-#endif
-
- memcpy(&lpci_bus, ctrl->pci_dev->subordinate, sizeof(lpci_bus));
- pci_bus = &lpci_bus;
- pci_bus->number = func->bus;
- devfn = PCI_DEVFN(func->device, func->function);
-
- /* Check for Bridge */
- rc = pci_bus_read_config_byte (pci_bus, devfn, PCI_HEADER_TYPE, &temp_byte);
- if (rc)
- return rc;
-
- if ((temp_byte & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { /* PCI-PCI Bridge */
- /* set Primary bus */
- dbg("set Primary bus = 0x%x\n", func->bus);
- rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_PRIMARY_BUS, func->bus);
- if (rc)
- return rc;
-
- /* find range of busses to use */
- bus_node = get_max_resource(&resources->bus_head, 1L);
-
- /* If we don't have any busses to allocate, we can't continue */
- if (!bus_node) {
- err("Got NO bus resource to use\n");
- return -ENOMEM;
- }
- dbg("Got ranges of buses to use: base:len=0x%x:%x\n", bus_node->base, bus_node->length);
-
- /* set Secondary bus */
- temp_byte = (u8)bus_node->base;
- dbg("set Secondary bus = 0x%x\n", temp_byte);
- rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_SECONDARY_BUS, temp_byte);
- if (rc)
- return rc;
-
- /* set subordinate bus */
- temp_byte = (u8)(bus_node->base + bus_node->length - 1);
- dbg("set subordinate bus = 0x%x\n", temp_byte);
- rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_SUBORDINATE_BUS, temp_byte);
- if (rc)
- return rc;
-
- /* Set HP parameters (Cache Line Size, Latency Timer) */
- rc = shpchprm_set_hpp(ctrl, func, PCI_HEADER_TYPE_BRIDGE);
- if (rc)
- return rc;
-
- /* Setup the IO, memory, and prefetchable windows */
-
- io_node = get_max_resource(&(resources->io_head), 0x1000L);
- if (io_node) {
- dbg("io_node(base, len, next) (%x, %x, %p)\n", io_node->base, io_node->length, io_node->next);
- }
-
- mem_node = get_max_resource(&(resources->mem_head), 0x100000L);
- if (mem_node) {
- dbg("mem_node(base, len, next) (%x, %x, %p)\n", mem_node->base, mem_node->length, mem_node->next);
- }
-
- if (resources->p_mem_head)
- p_mem_node = get_max_resource(&(resources->p_mem_head), 0x100000L);
- else {
- /*
- * In some platform implementation, MEM and PMEM are not
- * distinguished, and hence ACPI _CRS has only MEM entries
- * for both MEM and PMEM.
- */
- dbg("using MEM for PMEM\n");
- p_mem_node = get_max_resource(&(resources->mem_head), 0x100000L);
- }
- if (p_mem_node) {
- dbg("p_mem_node(base, len, next) (%x, %x, %p)\n", p_mem_node->base, p_mem_node->length, p_mem_node->next);
- }
-
- /* set up the IRQ info */
- if (!resources->irqs) {
- irqs.barber_pole = 0;
- irqs.interrupt[0] = 0;
- irqs.interrupt[1] = 0;
- irqs.interrupt[2] = 0;
- irqs.interrupt[3] = 0;
- irqs.valid_INT = 0;
- } else {
- irqs.barber_pole = resources->irqs->barber_pole;
- irqs.interrupt[0] = resources->irqs->interrupt[0];
- irqs.interrupt[1] = resources->irqs->interrupt[1];
- irqs.interrupt[2] = resources->irqs->interrupt[2];
- irqs.interrupt[3] = resources->irqs->interrupt[3];
- irqs.valid_INT = resources->irqs->valid_INT;
- }
-
- /* set up resource lists that are now aligned on top and bottom
- * for anything behind the bridge.
- */
- temp_resources.bus_head = bus_node;
- temp_resources.io_head = io_node;
- temp_resources.mem_head = mem_node;
- temp_resources.p_mem_head = p_mem_node;
- 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
- */
- 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);
- hold_p_mem_node = kmalloc(sizeof(*hold_p_mem_node), GFP_KERNEL);
-
- if (!hold_bus_node || !hold_IO_node || !hold_mem_node || !hold_p_mem_node) {
- kfree(hold_bus_node);
- kfree(hold_IO_node);
- kfree(hold_mem_node);
- kfree(hold_p_mem_node);
-
- return 1;
- }
-
- memcpy(hold_bus_node, bus_node, sizeof(struct pci_resource));
-
- bus_node->base += 1;
- bus_node->length -= 1;
- bus_node->next = NULL;
-
- /* If we have IO resources copy them and fill in the bridge's
- * IO range registers
- */
- if (io_node) {
- memcpy(hold_IO_node, io_node, sizeof(struct pci_resource));
- io_node->next = NULL;
-
- /* set IO base and Limit registers */
- RES_CHECK(io_node->base, 8);
- temp_byte = (u8)(io_node->base >> 8);
- rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_IO_BASE, temp_byte);
-
- RES_CHECK(io_node->base + io_node->length - 1, 8);
- temp_byte = (u8)((io_node->base + io_node->length - 1) >> 8);
- rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_IO_LIMIT, temp_byte);
- } else {
- kfree(hold_IO_node);
- hold_IO_node = NULL;
- }
-
- /* If we have memory resources copy them and fill in the bridge's
- * memory range registers. Otherwise, fill in the range
- * registers with values that disable them.
- */
- if (mem_node) {
- memcpy(hold_mem_node, mem_node, sizeof(struct pci_resource));
- mem_node->next = NULL;
-
- /* set Mem base and Limit registers */
- RES_CHECK(mem_node->base, 16);
- temp_word = (u32)(mem_node->base >> 16);
- rc = pci_bus_write_config_word(pci_bus, devfn, PCI_MEMORY_BASE, temp_word);
-
- RES_CHECK(mem_node->base + mem_node->length - 1, 16);
- temp_word = (u32)((mem_node->base + mem_node->length - 1) >> 16);
- rc = pci_bus_write_config_word(pci_bus, devfn, PCI_MEMORY_LIMIT, temp_word);
- } else {
- temp_word = 0xFFFF;
- rc = pci_bus_write_config_word(pci_bus, devfn, PCI_MEMORY_BASE, temp_word);
-
- temp_word = 0x0000;
- rc = pci_bus_write_config_word(pci_bus, devfn, PCI_MEMORY_LIMIT, temp_word);
-
- kfree(hold_mem_node);
- hold_mem_node = NULL;
- }
-
- /* If we have prefetchable memory resources copy them and
- * fill in the bridge's memory range registers. Otherwise,
- * fill in the range registers with values that disable them.
- */
- if (p_mem_node) {
- memcpy(hold_p_mem_node, p_mem_node, sizeof(struct pci_resource));
- p_mem_node->next = NULL;
-
- /* set Pre Mem base and Limit registers */
- RES_CHECK(p_mem_node->base, 16);
- temp_word = (u32)(p_mem_node->base >> 16);
- rc = pci_bus_write_config_word(pci_bus, devfn, PCI_PREF_MEMORY_BASE, temp_word);
-
- RES_CHECK(p_mem_node->base + p_mem_node->length - 1, 16);
- temp_word = (u32)((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);
- } else {
- temp_word = 0xFFFF;
- rc = pci_bus_write_config_word(pci_bus, devfn, PCI_PREF_MEMORY_BASE, temp_word);
-
- temp_word = 0x0000;
- rc = pci_bus_write_config_word(pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, temp_word);
-
- kfree(hold_p_mem_node);
- hold_p_mem_node = NULL;
- }
-
- /* Adjust this to compensate for extra adjustment in first loop */
- irqs.barber_pole--;
-
- rc = 0;
-
- /* Here we actually find the devices and configure them */
- for (device = 0; (device <= 0x1F) && !rc; device++) {
- irqs.barber_pole = (irqs.barber_pole + 1) & 0x03;
-
- ID = 0xFFFFFFFF;
- pci_bus->number = hold_bus_node->base;
- pci_bus_read_config_dword(pci_bus, PCI_DEVFN(device, 0),
- PCI_VENDOR_ID, &ID);
- pci_bus->number = func->bus;
-
- if (ID != 0xFFFFFFFF) { /* device Present */
- /* Setup slot structure. */
- new_slot = shpchp_slot_create(hold_bus_node->base);
-
- if (new_slot == NULL) {
- /* Out of memory */
- rc = -ENOMEM;
- continue;
- }
-
- new_slot->bus = hold_bus_node->base;
- new_slot->device = device;
- new_slot->function = 0;
- new_slot->is_a_board = 1;
- new_slot->status = 0;
-
- rc = configure_new_device(ctrl, new_slot, 1, &temp_resources, func->bus, func->device);
- dbg("configure_new_device rc=0x%x\n",rc);
- } /* End of IF (device in slot?) */
- } /* End of FOR loop */
-
- if (rc) {
- shpchp_destroy_resource_list(&temp_resources);
-
- return_resource(&(resources->bus_head), hold_bus_node);
- return_resource(&(resources->io_head), hold_IO_node);
- return_resource(&(resources->mem_head), hold_mem_node);
- return_resource(&(resources->p_mem_head), hold_p_mem_node);
- return(rc);
- }
-
- /* save the interrupt routing information */
- if (resources->irqs) {
- resources->irqs->interrupt[0] = irqs.interrupt[0];
- resources->irqs->interrupt[1] = irqs.interrupt[1];
- resources->irqs->interrupt[2] = irqs.interrupt[2];
- resources->irqs->interrupt[3] = irqs.interrupt[3];
- resources->irqs->valid_INT = irqs.valid_INT;
- } else if (!behind_bridge) {
- /* We need to hook up the interrupts here */
- for (cloop = 0; cloop < 4; cloop++) {
- if (irqs.valid_INT & (0x01 << cloop)) {
- rc = shpchp_set_irq(func->bus, func->device,
- 0x0A + cloop, irqs.interrupt[cloop]);
- if (rc) {
- shpchp_destroy_resource_list (&temp_resources);
- return_resource(&(resources->bus_head), hold_bus_node);
- return_resource(&(resources->io_head), hold_IO_node);
- return_resource(&(resources->mem_head), hold_mem_node);
- return_resource(&(resources->p_mem_head), hold_p_mem_node);
- return rc;
- }
- }
- } /* end of for loop */
- }
-
- /* Return unused bus resources
- * First use the temporary node to store information for the board
- */
- if (hold_bus_node && bus_node && temp_resources.bus_head) {
- hold_bus_node->length = bus_node->base - hold_bus_node->base;
-
- hold_bus_node->next = func->bus_head;
- func->bus_head = hold_bus_node;
-
- temp_byte = (u8)(temp_resources.bus_head->base - 1);
-
- /* set subordinate bus */
- dbg("re-set subordinate bus = 0x%x\n", temp_byte);
- rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_SUBORDINATE_BUS, temp_byte);
-
- if (temp_resources.bus_head->length == 0) {
- kfree(temp_resources.bus_head);
- temp_resources.bus_head = NULL;
- } else {
- dbg("return bus res of b:d(0x%x:%x) base:len(0x%x:%x)\n",
- func->bus, func->device, temp_resources.bus_head->base, temp_resources.bus_head->length);
- return_resource(&(resources->bus_head), temp_resources.bus_head);
- }
- }
-
- /* If we have IO space available and there is some left,
- * return the unused portion
- */
- if (hold_IO_node && temp_resources.io_head) {
- io_node = do_pre_bridge_resource_split(&(temp_resources.io_head),
- &hold_IO_node, 0x1000);
-
- /* Check if we were able to split something off */
- if (io_node) {
- hold_IO_node->base = io_node->base + io_node->length;
-
- RES_CHECK(hold_IO_node->base, 8);
- temp_byte = (u8)((hold_IO_node->base) >> 8);
- rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_IO_BASE, temp_byte);
-
- return_resource(&(resources->io_head), io_node);
- }
-
- io_node = do_bridge_resource_split(&(temp_resources.io_head), 0x1000);
-
- /* Check if we were able to split something off */
- if (io_node) {
- /* First use the temporary node to store information for the board */
- hold_IO_node->length = io_node->base - hold_IO_node->base;
-
- /* If we used any, add it to the board's list */
- if (hold_IO_node->length) {
- hold_IO_node->next = func->io_head;
- func->io_head = hold_IO_node;
-
- RES_CHECK(io_node->base - 1, 8);
- temp_byte = (u8)((io_node->base - 1) >> 8);
- rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_IO_LIMIT, temp_byte);
-
- return_resource(&(resources->io_head), io_node);
- } else {
- /* it doesn't need any IO */
- temp_byte = 0x00;
- rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_IO_LIMIT, temp_byte);
-
- return_resource(&(resources->io_head), io_node);
- kfree(hold_IO_node);
- }
- } else {
- /* it used most of the range */
- hold_IO_node->next = func->io_head;
- func->io_head = hold_IO_node;
- }
- } else if (hold_IO_node) {
- /* it used the whole range */
- hold_IO_node->next = func->io_head;
- func->io_head = hold_IO_node;
- }
-
- /* If we have memory space available and there is some left,
- * return the unused portion
- */
- if (hold_mem_node && temp_resources.mem_head) {
- mem_node = do_pre_bridge_resource_split(&(temp_resources.mem_head), &hold_mem_node, 0x100000L);
-
- /* Check if we were able to split something off */
- if (mem_node) {
- hold_mem_node->base = mem_node->base + mem_node->length;
-
- RES_CHECK(hold_mem_node->base, 16);
- temp_word = (u32)((hold_mem_node->base) >> 16);
- rc = pci_bus_write_config_word (pci_bus, devfn, PCI_MEMORY_BASE, temp_word);
-
- return_resource(&(resources->mem_head), mem_node);
- }
-
- mem_node = do_bridge_resource_split(&(temp_resources.mem_head), 0x100000L);
-
- /* Check if we were able to split something off */
- if (mem_node) {
- /* First use the temporary node to store information for the board */
- hold_mem_node->length = mem_node->base - hold_mem_node->base;
-
- if (hold_mem_node->length) {
- hold_mem_node->next = func->mem_head;
- func->mem_head = hold_mem_node;
-
- /* configure end address */
- RES_CHECK(mem_node->base - 1, 16);
- temp_word = (u32)((mem_node->base - 1) >> 16);
- rc = pci_bus_write_config_word (pci_bus, devfn, PCI_MEMORY_LIMIT, temp_word);
-
- /* Return unused resources to the pool */
- return_resource(&(resources->mem_head), mem_node);
- } else {
- /* it doesn't need any Mem */
- temp_word = 0x0000;
- rc = pci_bus_write_config_word (pci_bus, devfn, PCI_MEMORY_LIMIT, temp_word);
-
- return_resource(&(resources->mem_head), mem_node);
- kfree(hold_mem_node);
- }
- } else {
- /* it used most of the range */
- hold_mem_node->next = func->mem_head;
- func->mem_head = hold_mem_node;
- }
- } else if (hold_mem_node) {
- /* it used the whole range */
- hold_mem_node->next = func->mem_head;
- func->mem_head = hold_mem_node;
- }
-
- /* If we have prefetchable memory space available and there is some
- * left at the end, return the unused portion
- */
- if (hold_p_mem_node && temp_resources.p_mem_head) {
- p_mem_node = do_pre_bridge_resource_split(&(temp_resources.p_mem_head),
- &hold_p_mem_node, 0x100000L);
-
- /* Check if we were able to split something off */
- if (p_mem_node) {
- hold_p_mem_node->base = p_mem_node->base + p_mem_node->length;
-
- RES_CHECK(hold_p_mem_node->base, 16);
- temp_word = (u32)((hold_p_mem_node->base) >> 16);
- rc = pci_bus_write_config_word (pci_bus, devfn, PCI_PREF_MEMORY_BASE, temp_word);
-
- return_resource(&(resources->p_mem_head), p_mem_node);
- }
-
- p_mem_node = do_bridge_resource_split(&(temp_resources.p_mem_head), 0x100000L);
-
- /* Check if we were able to split something off */
- if (p_mem_node) {
- /* First use the temporary node to store information for the board */
- hold_p_mem_node->length = p_mem_node->base - hold_p_mem_node->base;
-
- /* If we used any, add it to the board's list */
- if (hold_p_mem_node->length) {
- hold_p_mem_node->next = func->p_mem_head;
- func->p_mem_head = hold_p_mem_node;
-
- RES_CHECK(p_mem_node->base - 1, 16);
- temp_word = (u32)((p_mem_node->base - 1) >> 16);
- rc = pci_bus_write_config_word (pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, temp_word);
-
- return_resource(&(resources->p_mem_head), p_mem_node);
- } else {
- /* it doesn't need any PMem */
- temp_word = 0x0000;
- rc = pci_bus_write_config_word (pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, temp_word);
-
- return_resource(&(resources->p_mem_head), p_mem_node);
- kfree(hold_p_mem_node);
- }
- } else {
- /* it used the most of the range */
- hold_p_mem_node->next = func->p_mem_head;
- func->p_mem_head = hold_p_mem_node;
- }
- } else if (hold_p_mem_node) {
- /* it used the whole range */
- hold_p_mem_node->next = func->p_mem_head;
- func->p_mem_head = hold_p_mem_node;
- }
-
- /* We should be configuring an IRQ and the bridge's base address
- * registers if it needs them. Although we have never seen such
- * a device
- */
-
- shpchprm_enable_card(ctrl, func, PCI_HEADER_TYPE_BRIDGE);
-
- dbg("PCI Bridge Hot-Added s:b:d:f(%02x:%02x:%02x:%02x)\n", ctrl->seg, func->bus, func->device, func->function);
- } else if ((temp_byte & 0x7F) == PCI_HEADER_TYPE_NORMAL) {
- /* Standard device */
- u64 base64;
- rc = pci_bus_read_config_byte (pci_bus, devfn, 0x0B, &class_code);
-
- if (class_code == PCI_BASE_CLASS_DISPLAY)
- return (DEVICE_TYPE_NOT_SUPPORTED);
-
- /* Figure out IO and memory needs */
- for (cloop = PCI_BASE_ADDRESS_0; cloop <= PCI_BASE_ADDRESS_5; cloop += 4) {
- temp_register = 0xFFFFFFFF;
-
- rc = pci_bus_write_config_dword (pci_bus, devfn, cloop, temp_register);
- rc = pci_bus_read_config_dword(pci_bus, devfn, cloop, &temp_register);
- dbg("Bar[%x]=0x%x on bus:dev:func(0x%x:%x:%x)\n", cloop, temp_register, func->bus, func->device,
- func->function);
-
- if (!temp_register)
- continue;
-
- base64 = 0L;
- if (temp_register & PCI_BASE_ADDRESS_SPACE_IO) {
- /* Map IO */
-
- /* set base = amount of IO space */
- base = temp_register & 0xFFFFFFFC;
- base = ~base + 1;
-
- dbg("NEED IO length(0x%x)\n", base);
- io_node = get_io_resource(&(resources->io_head),(ulong)base);
-
- /* allocate the resource to the board */
- if (io_node) {
- dbg("Got IO base=0x%x(length=0x%x)\n", io_node->base, io_node->length);
- base = (u32)io_node->base;
- io_node->next = func->io_head;
- func->io_head = io_node;
- } else {
- err("Got NO IO resource(length=0x%x)\n", base);
- return -ENOMEM;
- }
- } else { /* map MEM */
- int prefetchable = 1;
- struct pci_resource **res_node = &func->p_mem_head;
- char *res_type_str = "PMEM";
- u32 temp_register2;
-
- if (!(temp_register & PCI_BASE_ADDRESS_MEM_PREFETCH)) {
- prefetchable = 0;
- res_node = &func->mem_head;
- res_type_str++;
- }
-
- base = temp_register & 0xFFFFFFF0;
- base = ~base + 1;
-
- switch (temp_register & PCI_BASE_ADDRESS_MEM_TYPE_MASK) {
- case PCI_BASE_ADDRESS_MEM_TYPE_32:
- dbg("NEED 32 %s bar=0x%x(length=0x%x)\n", res_type_str, temp_register, base);
-
- if (prefetchable && resources->p_mem_head)
- mem_node=get_resource(&(resources->p_mem_head), (ulong)base);
- else {
- if (prefetchable)
- dbg("using MEM for PMEM\n");
- mem_node=get_resource(&(resources->mem_head), (ulong)base);
- }
-
- /* allocate the resource to the board */
- if (mem_node) {
- base = (u32)mem_node->base;
- mem_node->next = *res_node;
- *res_node = mem_node;
- dbg("Got 32 %s base=0x%x(length=0x%x)\n", res_type_str, mem_node->base,
- mem_node->length);
- } else {
- err("Got NO 32 %s resource(length=0x%x)\n", res_type_str, base);
- return -ENOMEM;
- }
- break;
- case PCI_BASE_ADDRESS_MEM_TYPE_64:
- rc = pci_bus_read_config_dword(pci_bus, devfn, cloop+4, &temp_register2);
- dbg("NEED 64 %s bar=0x%x:%x(length=0x%x)\n", res_type_str, temp_register2,
- temp_register, base);
-
- if (prefetchable && resources->p_mem_head)
- mem_node = get_resource(&(resources->p_mem_head), (ulong)base);
- else {
- if (prefetchable)
- dbg("using MEM for PMEM\n");
- mem_node = get_resource(&(resources->mem_head), (ulong)base);
- }
-
- /* allocate the resource to the board */
- if (mem_node) {
- base64 = mem_node->base;
- mem_node->next = *res_node;
- *res_node = mem_node;
- dbg("Got 64 %s base=0x%x:%x(length=%x)\n", res_type_str, (u32)(base64 >> 32),
- (u32)base64, mem_node->length);
- } else {
- err("Got NO 64 %s resource(length=0x%x)\n", res_type_str, base);
- return -ENOMEM;
- }
- break;
- default:
- dbg("reserved BAR type=0x%x\n", temp_register);
- break;
- }
-
- }
-
- if (base64) {
- rc = pci_bus_write_config_dword(pci_bus, devfn, cloop, (u32)base64);
- cloop += 4;
- base64 >>= 32;
-
- if (base64) {
- dbg("%s: high dword of base64(0x%x) set to 0\n", __FUNCTION__, (u32)base64);
- base64 = 0x0L;
- }
-
- rc = pci_bus_write_config_dword(pci_bus, devfn, cloop, (u32)base64);
- } else {
- rc = pci_bus_write_config_dword(pci_bus, devfn, cloop, base);
- }
- } /* End of base register loop */
-
-#if defined(CONFIG_X86_64)
- /* Figure out which interrupt pin this function uses */
- 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 &
- (0x01 << ((temp_byte + resources->irqs->barber_pole - 1) & 0x03)))) {
- /* We have to share with something already set up */
- 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) {
- IRQ = shpchp_disk_irq;
- } else {
- IRQ = shpchp_nic_irq;
- }
- }
-
- /* IRQ Line */
- rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_INTERRUPT_LINE, IRQ);
-
- if (!behind_bridge) {
- rc = shpchp_set_irq(func->bus, func->device, temp_byte + 0x09, IRQ);
- if (rc)
- return(1);
- } else {
- /* TBD - this code may also belong in the other clause of this If statement */
- resources->irqs->interrupt[(temp_byte + resources->irqs->barber_pole - 1) & 0x03] = IRQ;
- resources->irqs->valid_INT |= 0x01 << (temp_byte + resources->irqs->barber_pole - 1) & 0x03;
- }
-#endif
- /* Disable ROM base Address */
- rc = pci_bus_write_config_dword (pci_bus, devfn, PCI_ROM_ADDRESS, 0x00);
-
- /* Set HP parameters (Cache Line Size, Latency Timer) */
- rc = shpchprm_set_hpp(ctrl, func, PCI_HEADER_TYPE_NORMAL);
- if (rc)
- return rc;
-
- shpchprm_enable_card(ctrl, func, PCI_HEADER_TYPE_NORMAL);
-
- dbg("PCI function Hot-Added s:b:d:f(%02x:%02x:%02x:%02x)\n", ctrl->seg, func->bus, func->device, func->function);
- } /* End of Not-A-Bridge else */
- else {
- /* It's some strange type of PCI adapter (Cardbus?) */
- return(DEVICE_TYPE_NOT_SUPPORTED);
- }
-
- func->configured = 1;
-
- return 0;
+ ret = remove_board(p_slot);
+ update_slot_info(p_slot);
+ return ret;
}
diff --git a/drivers/pci/hotplug/shpchp_hpc.c b/drivers/pci/hotplug/shpchp_hpc.c
index 8d98410bf1c0..40905a6c8094 100644
--- a/drivers/pci/hotplug/shpchp_hpc.c
+++ b/drivers/pci/hotplug/shpchp_hpc.c
@@ -27,17 +27,10 @@
*
*/
-#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/types.h>
-#include <linux/slab.h>
-#include <linux/vmalloc.h>
-#include <linux/interrupt.h>
-#include <linux/spinlock.h>
-#include <linux/delay.h>
#include <linux/pci.h>
-#include <asm/system.h>
#include "shpchp.h"
#ifdef DEBUG
@@ -282,7 +275,7 @@ static void start_int_poll_timer(struct php_ctlr_state_s *php_ctlr, int seconds)
static int shpc_write_cmd(struct slot *slot, u8 t_slot, u8 cmd)
{
- struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle;
+ struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
u16 cmd_status;
int retval = 0;
u16 temp_word;
@@ -320,7 +313,6 @@ static int shpc_write_cmd(struct slot *slot, u8 t_slot, u8 cmd)
* command.
*/
writew(temp_word, php_ctlr->creg + CMD);
- dbg("%s: temp_word written %x\n", __FUNCTION__, temp_word);
DBG_LEAVE_ROUTINE
return retval;
@@ -328,7 +320,7 @@ static int shpc_write_cmd(struct slot *slot, u8 t_slot, u8 cmd)
static int hpc_check_cmd_status(struct controller *ctrl)
{
- struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) ctrl->hpc_ctlr_handle;
+ struct php_ctlr_state_s *php_ctlr = ctrl->hpc_ctlr_handle;
u16 cmd_status;
int retval = 0;
@@ -368,7 +360,7 @@ static int hpc_check_cmd_status(struct controller *ctrl)
static int hpc_get_attention_status(struct slot *slot, u8 *status)
{
- struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle;
+ struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
u32 slot_reg;
u16 slot_status;
u8 atten_led_state;
@@ -408,7 +400,7 @@ static int hpc_get_attention_status(struct slot *slot, u8 *status)
static int hpc_get_power_status(struct slot * slot, u8 *status)
{
- struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle;
+ struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
u32 slot_reg;
u16 slot_status;
u8 slot_state;
@@ -450,7 +442,7 @@ static int hpc_get_power_status(struct slot * slot, u8 *status)
static int hpc_get_latch_status(struct slot *slot, u8 *status)
{
- struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle;
+ struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
u32 slot_reg;
u16 slot_status;
@@ -473,7 +465,7 @@ static int hpc_get_latch_status(struct slot *slot, u8 *status)
static int hpc_get_adapter_status(struct slot *slot, u8 *status)
{
- struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle;
+ struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
u32 slot_reg;
u16 slot_status;
u8 card_state;
@@ -496,7 +488,7 @@ static int hpc_get_adapter_status(struct slot *slot, u8 *status)
static int hpc_get_prog_int(struct slot *slot, u8 *prog_int)
{
- struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle;
+ struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
DBG_ENTER_ROUTINE
@@ -513,7 +505,7 @@ static int hpc_get_prog_int(struct slot *slot, u8 *prog_int)
static int hpc_get_adapter_speed(struct slot *slot, enum pci_bus_speed *value)
{
- struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle;
+ struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
u32 slot_reg;
u16 slot_status, sec_bus_status;
u8 m66_cap, pcix_cap, pi;
@@ -594,7 +586,7 @@ static int hpc_get_adapter_speed(struct slot *slot, enum pci_bus_speed *value)
static int hpc_get_mode1_ECC_cap(struct slot *slot, u8 *mode)
{
- struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle;
+ struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
u16 sec_bus_status;
u8 pi;
int retval = 0;
@@ -623,7 +615,7 @@ static int hpc_get_mode1_ECC_cap(struct slot *slot, u8 *mode)
static int hpc_query_power_fault(struct slot * slot)
{
- struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle;
+ struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
u32 slot_reg;
u16 slot_status;
u8 pwr_fault_state, status;
@@ -647,7 +639,7 @@ static int hpc_query_power_fault(struct slot * slot)
static int hpc_set_attention_status(struct slot *slot, u8 value)
{
- struct php_ctlr_state_s *php_ctlr =(struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle;
+ struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
u8 slot_cmd = 0;
int rc = 0;
@@ -683,7 +675,7 @@ static int hpc_set_attention_status(struct slot *slot, u8 value)
static void hpc_set_green_led_on(struct slot *slot)
{
- struct php_ctlr_state_s *php_ctlr =(struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle;
+ struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
u8 slot_cmd;
if (!slot->ctrl->hpc_ctlr_handle) {
@@ -705,7 +697,7 @@ static void hpc_set_green_led_on(struct slot *slot)
static void hpc_set_green_led_off(struct slot *slot)
{
- struct php_ctlr_state_s *php_ctlr =(struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle;
+ struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
u8 slot_cmd;
if (!slot->ctrl->hpc_ctlr_handle) {
@@ -727,7 +719,7 @@ static void hpc_set_green_led_off(struct slot *slot)
static void hpc_set_green_led_blink(struct slot *slot)
{
- struct php_ctlr_state_s *php_ctlr =(struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle;
+ struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
u8 slot_cmd;
if (!slot->ctrl->hpc_ctlr_handle) {
@@ -754,7 +746,7 @@ int shpc_get_ctlr_slot_config(struct controller *ctrl,
int *updown, /* physical_slot_num increament: 1 or -1 */
int *flags)
{
- struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) ctrl->hpc_ctlr_handle;
+ struct php_ctlr_state_s *php_ctlr = ctrl->hpc_ctlr_handle;
DBG_ENTER_ROUTINE
@@ -776,7 +768,7 @@ int shpc_get_ctlr_slot_config(struct controller *ctrl,
static void hpc_release_ctlr(struct controller *ctrl)
{
- struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) ctrl->hpc_ctlr_handle;
+ struct php_ctlr_state_s *php_ctlr = ctrl->hpc_ctlr_handle;
struct php_ctlr_state_s *p, *p_prev;
DBG_ENTER_ROUTINE
@@ -796,10 +788,8 @@ static void hpc_release_ctlr(struct controller *ctrl)
}
}
if (php_ctlr->pci_dev) {
- dbg("%s: before calling iounmap & release_mem_region\n", __FUNCTION__);
iounmap(php_ctlr->creg);
release_mem_region(pci_resource_start(php_ctlr->pci_dev, 0), pci_resource_len(php_ctlr->pci_dev, 0));
- dbg("%s: before calling iounmap & release_mem_region\n", __FUNCTION__);
php_ctlr->pci_dev = NULL;
}
@@ -828,7 +818,7 @@ DBG_LEAVE_ROUTINE
static int hpc_power_on_slot(struct slot * slot)
{
- struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle;
+ struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
u8 slot_cmd;
int retval = 0;
@@ -859,7 +849,7 @@ static int hpc_power_on_slot(struct slot * slot)
static int hpc_slot_enable(struct slot * slot)
{
- struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle;
+ struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
u8 slot_cmd;
int retval = 0;
@@ -890,7 +880,7 @@ static int hpc_slot_enable(struct slot * slot)
static int hpc_slot_disable(struct slot * slot)
{
- struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle;
+ struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
u8 slot_cmd;
int retval = 0;
@@ -920,51 +910,12 @@ static int hpc_slot_disable(struct slot * slot)
return retval;
}
-static int hpc_enable_all_slots( struct slot *slot )
-{
- int retval = 0;
-
- DBG_ENTER_ROUTINE
-
- if (!slot->ctrl->hpc_ctlr_handle) {
- err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
- return -1;
- }
-
- retval = shpc_write_cmd(slot, 0, SET_ENABLE_ALL);
- if (retval) {
- err("%s: Write command failed!\n", __FUNCTION__);
- return -1;
- }
-
- DBG_LEAVE_ROUTINE
-
- return retval;
-}
-
-static int hpc_pwr_on_all_slots(struct slot *slot)
-{
- int retval = 0;
-
- DBG_ENTER_ROUTINE
-
- retval = shpc_write_cmd(slot, 0, SET_PWR_ON_ALL);
-
- if (retval) {
- err("%s: Write command failed!\n", __FUNCTION__);
- return -1;
- }
-
- DBG_LEAVE_ROUTINE
- return retval;
-}
-
static int hpc_set_bus_speed_mode(struct slot * slot, enum pci_bus_speed value)
{
u8 slot_cmd;
u8 pi;
int retval = 0;
- struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle;
+ struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
DBG_ENTER_ROUTINE
@@ -1089,18 +1040,13 @@ static irqreturn_t shpc_isr(int IRQ, void *dev_id, struct pt_regs *regs)
if (!intr_loc)
return IRQ_NONE;
- dbg("%s: shpc_isr proceeds\n", __FUNCTION__);
dbg("%s: intr_loc = %x\n",__FUNCTION__, intr_loc);
if(!shpchp_poll_mode) {
/* Mask Global Interrupt Mask - see implementation note on p. 139 */
/* of SHPC spec rev 1.0*/
temp_dword = readl(php_ctlr->creg + SERR_INTR_ENABLE);
- dbg("%s: Before masking global interrupt, temp_dword = %x\n",
- __FUNCTION__, temp_dword);
temp_dword |= 0x00000001;
- dbg("%s: After masking global interrupt, temp_dword = %x\n",
- __FUNCTION__, temp_dword);
writel(temp_dword, php_ctlr->creg + SERR_INTR_ENABLE);
intr_loc2 = readl(php_ctlr->creg + INTR_LOC);
@@ -1114,11 +1060,7 @@ static irqreturn_t shpc_isr(int IRQ, void *dev_id, struct pt_regs *regs)
* Detect bit in Controller SERR-INT register
*/
temp_dword = readl(php_ctlr->creg + SERR_INTR_ENABLE);
- dbg("%s: Before clearing CCIP, temp_dword = %x\n",
- __FUNCTION__, temp_dword);
temp_dword &= 0xfffeffff;
- dbg("%s: After clearing CCIP, temp_dword = %x\n",
- __FUNCTION__, temp_dword);
writel(temp_dword, php_ctlr->creg + SERR_INTR_ENABLE);
wake_up_interruptible(&ctrl->queue);
}
@@ -1126,11 +1068,7 @@ static irqreturn_t shpc_isr(int IRQ, void *dev_id, struct pt_regs *regs)
if ((intr_loc = (intr_loc >> 1)) == 0) {
/* Unmask Global Interrupt Mask */
temp_dword = readl(php_ctlr->creg + SERR_INTR_ENABLE);
- dbg("%s: 1-Before unmasking global interrupt, temp_dword = %x\n",
- __FUNCTION__, temp_dword);
temp_dword &= 0xfffffffe;
- dbg("%s: 1-After unmasking global interrupt, temp_dword = %x\n",
- __FUNCTION__, temp_dword);
writel(temp_dword, php_ctlr->creg + SERR_INTR_ENABLE);
return IRQ_NONE;
@@ -1140,11 +1078,9 @@ static irqreturn_t shpc_isr(int IRQ, void *dev_id, struct pt_regs *regs)
/* To find out which slot has interrupt pending */
if ((intr_loc >> hp_slot) & 0x01) {
temp_dword = readl(php_ctlr->creg + SLOT1 + (4*hp_slot));
- dbg("%s: Slot %x with intr, temp_dword = %x\n",
- __FUNCTION__, hp_slot, temp_dword);
+ dbg("%s: Slot %x with intr, slot register = %x\n",
+ __FUNCTION__, hp_slot, temp_dword);
temp_byte = (temp_dword >> 16) & 0xFF;
- dbg("%s: Slot with intr, temp_byte = %x\n",
- __FUNCTION__, temp_byte);
if ((php_ctlr->switch_change_callback) && (temp_byte & 0x08))
schedule_flag += php_ctlr->switch_change_callback(
hp_slot, php_ctlr->callback_instance_id);
@@ -1160,8 +1096,6 @@ static irqreturn_t shpc_isr(int IRQ, void *dev_id, struct pt_regs *regs)
/* Clear all slot events */
temp_dword = 0xe01f3fff;
- dbg("%s: Clearing slot events, temp_dword = %x\n",
- __FUNCTION__, temp_dword);
writel(temp_dword, php_ctlr->creg + SLOT1 + (4*hp_slot));
intr_loc2 = readl(php_ctlr->creg + INTR_LOC);
@@ -1171,11 +1105,7 @@ static irqreturn_t shpc_isr(int IRQ, void *dev_id, struct pt_regs *regs)
if (!shpchp_poll_mode) {
/* Unmask Global Interrupt Mask */
temp_dword = readl(php_ctlr->creg + SERR_INTR_ENABLE);
- dbg("%s: 2-Before unmasking global interrupt, temp_dword = %x\n",
- __FUNCTION__, temp_dword);
temp_dword &= 0xfffffffe;
- dbg("%s: 2-After unmasking global interrupt, temp_dword = %x\n",
- __FUNCTION__, temp_dword);
writel(temp_dword, php_ctlr->creg + SERR_INTR_ENABLE);
}
@@ -1184,7 +1114,7 @@ static irqreturn_t shpc_isr(int IRQ, void *dev_id, struct pt_regs *regs)
static int hpc_get_max_bus_speed (struct slot *slot, enum pci_bus_speed *value)
{
- struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle;
+ struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
enum pci_bus_speed bus_speed = PCI_SPEED_UNKNOWN;
int retval = 0;
u8 pi;
@@ -1253,7 +1183,7 @@ static int hpc_get_max_bus_speed (struct slot *slot, enum pci_bus_speed *value)
static int hpc_get_cur_bus_speed (struct slot *slot, enum pci_bus_speed *value)
{
- struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle;
+ struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
enum pci_bus_speed bus_speed = PCI_SPEED_UNKNOWN;
u16 sec_bus_status;
int retval = 0;
@@ -1367,8 +1297,6 @@ static struct hpc_ops shpchp_hpc_ops = {
.power_on_slot = hpc_power_on_slot,
.slot_enable = hpc_slot_enable,
.slot_disable = hpc_slot_disable,
- .enable_all_slots = hpc_enable_all_slots,
- .pwr_on_all_slots = hpc_pwr_on_all_slots,
.set_bus_speed_mode = hpc_set_bus_speed_mode,
.set_attention_status = hpc_set_attention_status,
.get_power_status = hpc_get_power_status,
@@ -1391,12 +1319,7 @@ static struct hpc_ops shpchp_hpc_ops = {
.check_cmd_status = hpc_check_cmd_status,
};
-int shpc_init(struct controller * ctrl,
- struct pci_dev * pdev,
- php_intr_callback_t attention_button_callback,
- php_intr_callback_t switch_change_callback,
- php_intr_callback_t presence_change_callback,
- php_intr_callback_t power_fault_callback)
+int shpc_init(struct controller * ctrl, struct pci_dev * pdev)
{
struct php_ctlr_state_s *php_ctlr, *p;
void *instance_id = ctrl;
@@ -1405,7 +1328,6 @@ int shpc_init(struct controller * ctrl,
static int first = 1;
u32 shpc_cap_offset, shpc_base_offset;
u32 tempdword, slot_reg;
- u16 vendor_id, device_id;
u8 i;
DBG_ENTER_ROUTINE
@@ -1422,21 +1344,8 @@ int shpc_init(struct controller * ctrl,
php_ctlr->pci_dev = pdev; /* save pci_dev in context */
- rc = pci_read_config_word(pdev, PCI_VENDOR_ID, &vendor_id);
- dbg("%s: Vendor ID: %x\n",__FUNCTION__, vendor_id);
- if (rc) {
- err("%s: unable to read PCI configuration data\n", __FUNCTION__);
- goto abort_free_ctlr;
- }
-
- rc = pci_read_config_word(pdev, PCI_DEVICE_ID, &device_id);
- dbg("%s: Device ID: %x\n",__FUNCTION__, device_id);
- if (rc) {
- err("%s: unable to read PCI configuration data\n", __FUNCTION__);
- goto abort_free_ctlr;
- }
-
- if ((vendor_id == PCI_VENDOR_ID_AMD) || (device_id == PCI_DEVICE_ID_AMD_GOLAM_7450)) {
+ if ((pdev->vendor == PCI_VENDOR_ID_AMD) || (pdev->device ==
+ PCI_DEVICE_ID_AMD_GOLAM_7450)) {
shpc_base_offset = 0; /* amd shpc driver doesn't use this; assume 0 */
} else {
if ((shpc_cap_offset = pci_find_capability(pdev, PCI_CAP_ID_SHPC)) == 0) {
@@ -1469,7 +1378,8 @@ int shpc_init(struct controller * ctrl,
err("%s : pci_read_config_dword failed\n", __FUNCTION__);
goto abort_free_ctlr;
}
- dbg("%s: offset %d: tempdword %x\n", __FUNCTION__,i, tempdword);
+ dbg("%s: offset %d: value %x\n", __FUNCTION__,i,
+ tempdword);
}
}
@@ -1478,13 +1388,6 @@ int shpc_init(struct controller * ctrl,
first = 0;
}
- dbg("pdev = %p: b:d:f:irq=0x%x:%x:%x:%x\n", pdev, pdev->bus->number, PCI_SLOT(pdev->devfn),
- PCI_FUNC(pdev->devfn), pdev->irq);
- for ( rc = 0; rc < DEVICE_COUNT_RESOURCE; rc++)
- if (pci_resource_len(pdev, rc) > 0)
- dbg("pci resource[%d] start=0x%lx(len=0x%lx), shpc_base_offset %x\n", rc,
- pci_resource_start(pdev, rc), pci_resource_len(pdev, rc), shpc_base_offset);
-
info("HPC vendor_id %x device_id %x ss_vid %x ss_did %x\n", pdev->vendor, pdev->device, pdev->subsystem_vendor,
pdev->subsystem_device);
@@ -1504,7 +1407,6 @@ int shpc_init(struct controller * ctrl,
goto abort_free_ctlr;
}
dbg("%s: php_ctlr->creg %p\n", __FUNCTION__, php_ctlr->creg);
- dbg("%s: physical addr %p\n", __FUNCTION__, (void*)pci_resource_start(pdev, 0));
init_MUTEX(&ctrl->crit_sect);
/* Setup wait queue */
@@ -1512,13 +1414,10 @@ int shpc_init(struct controller * ctrl,
/* Find the IRQ */
php_ctlr->irq = pdev->irq;
- dbg("HPC interrupt = %d\n", php_ctlr->irq);
-
- /* Save interrupt callback info */
- php_ctlr->attention_button_callback = attention_button_callback;
- php_ctlr->switch_change_callback = switch_change_callback;
- php_ctlr->presence_change_callback = presence_change_callback;
- php_ctlr->power_fault_callback = power_fault_callback;
+ php_ctlr->attention_button_callback = shpchp_handle_attention_button,
+ php_ctlr->switch_change_callback = shpchp_handle_switch_change;
+ php_ctlr->presence_change_callback = shpchp_handle_presence_change;
+ php_ctlr->power_fault_callback = shpchp_handle_power_fault;
php_ctlr->callback_instance_id = instance_id;
/* Return PCI Controller Info */
@@ -1556,7 +1455,6 @@ int shpc_init(struct controller * ctrl,
if (rc) {
info("Can't get msi for the hotplug controller\n");
info("Use INTx for the hotplug controller\n");
- dbg("%s: rc = %x\n", __FUNCTION__, rc);
} else
php_ctlr->irq = pdev->irq;
@@ -1566,9 +1464,11 @@ int shpc_init(struct controller * ctrl,
err("Can't get irq %d for the hotplug controller\n", php_ctlr->irq);
goto abort_free_ctlr;
}
- /* Execute OSHP method here */
}
- dbg("%s: Before adding HPC to HPC list\n", __FUNCTION__);
+ dbg("%s: HPC at b:d:f:irq=0x%x:%x:%x:%x\n", __FUNCTION__,
+ pdev->bus->number, PCI_SLOT(pdev->devfn),
+ PCI_FUNC(pdev->devfn), pdev->irq);
+ get_hp_hw_control_from_firmware(pdev);
/* Add this HPC instance into the HPC list */
spin_lock(&list_lock);
@@ -1607,7 +1507,6 @@ int shpc_init(struct controller * ctrl,
dbg("%s: SERR_INTR_ENABLE = %x\n", __FUNCTION__, tempdword);
}
- dbg("%s: Leaving shpc_init\n", __FUNCTION__);
DBG_LEAVE_ROUTINE
return 0;
diff --git a/drivers/pci/hotplug/shpchp_pci.c b/drivers/pci/hotplug/shpchp_pci.c
index d867099114ec..38009bc0fd5d 100644
--- a/drivers/pci/hotplug/shpchp_pci.c
+++ b/drivers/pci/hotplug/shpchp_pci.c
@@ -27,784 +27,151 @@
*
*/
-#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/types.h>
-#include <linux/slab.h>
-#include <linux/workqueue.h>
-#include <linux/proc_fs.h>
#include <linux/pci.h>
#include "../pci.h"
#include "shpchp.h"
-#ifndef CONFIG_IA64
-#include "../../../arch/i386/pci/pci.h" /* horrible hack showing how processor dependant we are... */
-#endif
-int shpchp_configure_device (struct controller* ctrl, struct pci_func* func)
+static void program_fw_provided_values(struct pci_dev *dev)
{
- 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));
-
- /* Still NULL ? Well then scan for it ! */
- if (func->pci_dev == NULL) {
- num = pci_scan_slot(ctrl->pci_dev->subordinate, PCI_DEVFN(func->device, func->function));
- if (num) {
- dbg("%s: subordiante %p number %x\n", __FUNCTION__, ctrl->pci_dev->subordinate,
- ctrl->pci_dev->subordinate->number);
- pci_bus_add_devices(ctrl->pci_dev->subordinate);
- }
-
- func->pci_dev = pci_find_slot(func->bus, PCI_DEVFN(func->device, func->function));
- if (func->pci_dev == NULL) {
- dbg("ERROR: pci_dev still null\n");
- return 0;
+ u16 pci_cmd, pci_bctl;
+ struct pci_dev *cdev;
+ struct hotplug_params hpp = {0x8, 0x40, 0, 0}; /* defaults */
+
+ /* Program hpp values for this device */
+ if (!(dev->hdr_type == PCI_HEADER_TYPE_NORMAL ||
+ (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE &&
+ (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI)))
+ return;
+
+ get_hp_params_from_firmware(dev, &hpp);
+
+ pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, hpp.cache_line_size);
+ pci_write_config_byte(dev, PCI_LATENCY_TIMER, hpp.latency_timer);
+ pci_read_config_word(dev, PCI_COMMAND, &pci_cmd);
+ if (hpp.enable_serr)
+ pci_cmd |= PCI_COMMAND_SERR;
+ else
+ pci_cmd &= ~PCI_COMMAND_SERR;
+ if (hpp.enable_perr)
+ pci_cmd |= PCI_COMMAND_PARITY;
+ else
+ pci_cmd &= ~PCI_COMMAND_PARITY;
+ pci_write_config_word(dev, PCI_COMMAND, pci_cmd);
+
+ /* Program bridge control value and child devices */
+ if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) {
+ pci_write_config_byte(dev, PCI_SEC_LATENCY_TIMER,
+ hpp.latency_timer);
+ pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &pci_bctl);
+ if (hpp.enable_serr)
+ pci_bctl |= PCI_BRIDGE_CTL_SERR;
+ else
+ pci_bctl &= ~PCI_BRIDGE_CTL_SERR;
+ if (hpp.enable_perr)
+ pci_bctl |= PCI_BRIDGE_CTL_PARITY;
+ else
+ pci_bctl &= ~PCI_BRIDGE_CTL_PARITY;
+ pci_write_config_word(dev, PCI_BRIDGE_CONTROL, pci_bctl);
+ if (dev->subordinate) {
+ list_for_each_entry(cdev, &dev->subordinate->devices,
+ bus_list)
+ program_fw_provided_values(cdev);
}
}
-
- if (func->pci_dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
- pci_read_config_byte(func->pci_dev, PCI_SECONDARY_BUS, &bus);
- child = pci_add_new_bus(func->pci_dev->bus, (func->pci_dev), bus);
- pci_do_scan_bus(child);
-
- }
-
- return 0;
}
-
-int shpchp_unconfigure_device(struct pci_func* func)
+int shpchp_configure_device(struct slot *p_slot)
{
- int rc = 0;
- int j;
-
- dbg("%s: bus/dev/func = %x/%x/%x\n", __FUNCTION__, func->bus,
- func->device, func->function);
-
- for (j=0; j<8 ; j++) {
- struct pci_dev* temp = pci_find_slot(func->bus,
- (func->device << 3) | j);
- if (temp) {
- pci_remove_bus_device(temp);
- }
+ struct pci_dev *dev;
+ struct pci_bus *parent = p_slot->ctrl->pci_dev->subordinate;
+ int num, fn;
+
+ dev = pci_find_slot(p_slot->bus, PCI_DEVFN(p_slot->device, 0));
+ if (dev) {
+ err("Device %s already exists at %x:%x, cannot hot-add\n",
+ pci_name(dev), p_slot->bus, p_slot->device);
+ return -EINVAL;
}
- return rc;
-}
-
-/*
- * shpchp_set_irq
- *
- * @bus_num: bus number of PCI device
- * @dev_num: device number of PCI device
- * @slot: pointer to u8 where slot number will be returned
- */
-int shpchp_set_irq (u8 bus_num, u8 dev_num, u8 int_pin, u8 irq_num)
-{
-#if defined(CONFIG_X86) && !defined(CONFIG_X86_IO_APIC) && !defined(CONFIG_X86_64)
- int rc;
- u16 temp_word;
- struct pci_dev fakedev;
- struct pci_bus fakebus;
- fakedev.devfn = dev_num << 3;
- fakedev.bus = &fakebus;
- fakebus.number = bus_num;
- dbg("%s: dev %d, bus %d, pin %d, num %d\n",
- __FUNCTION__, dev_num, bus_num, int_pin, irq_num);
- rc = pcibios_set_irq_routing(&fakedev, int_pin - 0x0a, irq_num);
- dbg("%s: rc %d\n", __FUNCTION__, rc);
- if (!rc)
- return !rc;
-
- /* 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);
-#endif
- return 0;
-}
-
-/* More PCI configuration routines; this time centered around hotplug controller */
-
-
-/*
- * shpchp_save_config
- *
- * Reads configuration for all slots in a PCI bus and saves info.
- *
- * Note: For non-hot plug busses, the slot # saved is the device #
- *
- * returns 0 if success
- */
-int shpchp_save_config(struct controller *ctrl, int busnumber, int num_ctlr_slots, int first_device_num)
-{
- int rc;
- u8 class_code;
- u8 header_type;
- u32 ID;
- u8 secondary_bus;
- struct pci_func *new_slot;
- int sub_bus;
- int FirstSupported;
- int LastSupported;
- int max_functions;
- int function;
- u8 DevError;
- int device = 0;
- int cloop = 0;
- int stop_it;
- int index;
- int is_hot_plug = num_ctlr_slots || first_device_num;
- struct pci_bus lpci_bus, *pci_bus;
-
- dbg("%s: num_ctlr_slots = %d, first_device_num = %d\n", __FUNCTION__,
- num_ctlr_slots, first_device_num);
-
- memcpy(&lpci_bus, ctrl->pci_dev->subordinate, sizeof(lpci_bus));
- pci_bus = &lpci_bus;
-
- dbg("%s: num_ctlr_slots = %d, first_device_num = %d\n", __FUNCTION__,
- num_ctlr_slots, first_device_num);
-
- /* Decide which slots are supported */
- if (is_hot_plug) {
- /*********************************
- * is_hot_plug is the slot mask
- *********************************/
- FirstSupported = first_device_num;
- LastSupported = FirstSupported + num_ctlr_slots - 1;
- } else {
- FirstSupported = 0;
- LastSupported = 0x1F;
+ num = pci_scan_slot(parent, PCI_DEVFN(p_slot->device, 0));
+ if (num == 0) {
+ err("No new device found\n");
+ return -ENODEV;
}
- dbg("FirstSupported = %d, LastSupported = %d\n", FirstSupported,
- LastSupported);
-
- /* Save PCI configuration space for all devices in supported slots */
- pci_bus->number = busnumber;
- for (device = FirstSupported; device <= LastSupported; device++) {
- ID = 0xFFFFFFFF;
- rc = pci_bus_read_config_dword(pci_bus, PCI_DEVFN(device, 0),
- PCI_VENDOR_ID, &ID);
-
- if (ID != 0xFFFFFFFF) { /* device in slot */
- rc = pci_bus_read_config_byte(pci_bus, PCI_DEVFN(device, 0),
- 0x0B, &class_code);
- if (rc)
- return rc;
-
- rc = pci_bus_read_config_byte(pci_bus, PCI_DEVFN(device, 0),
- PCI_HEADER_TYPE, &header_type);
- if (rc)
- return rc;
-
- dbg("class_code = %x, header_type = %x\n", class_code, header_type);
-
- /* If multi-function device, set max_functions to 8 */
- if (header_type & 0x80)
- max_functions = 8;
- else
- max_functions = 1;
-
- function = 0;
-
- do {
- DevError = 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(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 = shpchp_save_config(ctrl, sub_bus, 0, 0);
- if (rc)
- return rc;
- }
- }
-
- index = 0;
- new_slot = shpchp_slot_find(busnumber, device, index++);
-
- dbg("new_slot = %p\n", new_slot);
-
- while (new_slot && (new_slot->function != (u8) function)) {
- new_slot = shpchp_slot_find(busnumber, device, index++);
- dbg("new_slot = %p\n", new_slot);
- }
- if (!new_slot) {
- /* Setup slot structure. */
- new_slot = shpchp_slot_create(busnumber);
- dbg("new_slot = %p\n", new_slot);
-
- 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;
- new_slot->pwr_save = 1;
- /* 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);
- dbg("new_slot->pci_dev = %p\n", new_slot->pci_dev);
-
- for (cloop = 0; cloop < 0x20; cloop++) {
- rc = pci_bus_read_config_dword(pci_bus,
- PCI_DEVFN(device, function),
- cloop << 2,
- (u32 *) &(new_slot->config_space [cloop]));
- /* dbg("new_slot->config_space[%x] = %x\n",
- cloop, new_slot->config_space[cloop]); */
- if (rc)
- return rc;
- }
-
- function++;
-
- stop_it = 0;
-
- /* 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(pci_bus,
- PCI_DEVFN(device, function),
- PCI_VENDOR_ID, &ID);
-
- if (ID == 0xFFFFFFFF) { /* nothing there. */
- function++;
- dbg("Nothing there\n");
- } else { /* Something there */
- rc = pci_bus_read_config_byte(pci_bus,
- PCI_DEVFN(device, function),
- 0x0B, &class_code);
- if (rc)
- return rc;
-
- rc = pci_bus_read_config_byte(pci_bus,
- PCI_DEVFN(device, function),
- PCI_HEADER_TYPE, &header_type);
- if (rc)
- return rc;
-
- dbg("class_code = %x, header_type = %x\n",
- class_code, header_type);
- stop_it++;
- }
- }
-
- } 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 = shpchp_slot_create(busnumber);
-
- if (new_slot == NULL) {
- return(1);
- }
- dbg("new_slot = %p\n", new_slot);
-
- 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;
+ for (fn = 0; fn < 8; fn++) {
+ if (!(dev = pci_find_slot(p_slot->bus,
+ PCI_DEVFN(p_slot->device, fn))))
+ continue;
+ if ((dev->class >> 16) == PCI_BASE_CLASS_DISPLAY) {
+ err("Cannot hot-add display device %s\n",
+ pci_name(dev));
+ continue;
}
- } /* End of FOR loop */
-
- return(0);
-}
-
-
-/*
- * shpchp_save_slot_config
- *
- * Saves configuration info for all PCI devices in a given slot
- * including subordinate busses.
- *
- * returns 0 if success
- */
-int shpchp_save_slot_config(struct controller *ctrl, struct pci_func * new_slot)
-{
- int rc;
- u8 class_code;
- u8 header_type;
- u32 ID;
- u8 secondary_bus;
- int sub_bus;
- int max_functions;
- int function;
- int cloop = 0;
- int stop_it;
- struct pci_bus lpci_bus, *pci_bus;
- memcpy(&lpci_bus, ctrl->pci_dev->subordinate, sizeof(lpci_bus));
- pci_bus = &lpci_bus;
- pci_bus->number = new_slot->bus;
-
- ID = 0xFFFFFFFF;
-
- pci_bus_read_config_dword(pci_bus, PCI_DEVFN(new_slot->device, 0),
- PCI_VENDOR_ID, &ID);
-
- if (ID != 0xFFFFFFFF) { /* device in slot */
- pci_bus_read_config_byte(pci_bus, PCI_DEVFN(new_slot->device, 0),
- 0x0B, &class_code);
-
- pci_bus_read_config_byte(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(pci_bus,
- PCI_DEVFN(new_slot->device, function),
- PCI_SECONDARY_BUS, &secondary_bus);
-
- sub_bus = (int) secondary_bus;
-
- /* Save the config headers for the secondary bus. */
- rc = shpchp_save_config(ctrl, sub_bus, 0, 0);
-
- if (rc)
- return rc;
-
- } /* End of IF */
-
- new_slot->status = 0;
-
- for (cloop = 0; cloop < 0x20; cloop++) {
- pci_bus_read_config_dword(pci_bus,
- PCI_DEVFN(new_slot->device, function),
- cloop << 2,
- (u32 *) &(new_slot->config_space [cloop]));
+ if ((dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) ||
+ (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)) {
+ /* Find an unused bus number for the new bridge */
+ struct pci_bus *child;
+ unsigned char busnr, start = parent->secondary;
+ unsigned char end = parent->subordinate;
+ for (busnr = start; busnr <= end; busnr++) {
+ if (!pci_find_bus(pci_domain_nr(parent),
+ busnr))
+ break;
}
-
- function++;
-
- stop_it = 0;
-
- /* 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(pci_bus,
- PCI_DEVFN(new_slot->device, function),
- PCI_VENDOR_ID, &ID);
-
- if (ID == 0xFFFFFFFF) { /* nothing there. */
- function++;
- } else { /* Something there */
- pci_bus_read_config_byte(pci_bus,
- PCI_DEVFN(new_slot->device, function),
- 0x0B, &class_code);
-
- pci_bus_read_config_byte(pci_bus,
- PCI_DEVFN(new_slot->device, function),
- PCI_HEADER_TYPE, &header_type);
-
- stop_it++;
- }
+ if (busnr >= end) {
+ err("No free bus for hot-added bridge\n");
+ continue;
}
-
- } while (function < max_functions);
- } /* End of IF (device in slot?) */
- else {
- return 2;
+ child = pci_add_new_bus(parent, dev, busnr);
+ if (!child) {
+ err("Cannot add new bus for %s\n",
+ pci_name(dev));
+ continue;
+ }
+ child->subordinate = pci_do_scan_bus(child);
+ pci_bus_size_bridges(child);
+ }
+ program_fw_provided_values(dev);
}
+ pci_bus_assign_resources(parent);
+ pci_bus_add_devices(parent);
+ pci_enable_bridges(parent);
return 0;
}
-
-/*
- * shpchp_save_used_resources
- *
- * Stores used resource information for existing boards. this is
- * for boards that were in the system when this driver was loaded.
- * this function is for hot plug ADD
- *
- * returns 0 if success
- * if disable == 1(DISABLE_CARD),
- * it loops for all functions of the slot and disables them.
- * else, it just get resources of the function and return.
- */
-int shpchp_save_used_resources(struct controller *ctrl, struct pci_func *func, int disable)
+int shpchp_unconfigure_device(struct slot *p_slot)
{
- u8 cloop;
- u8 header_type;
- u8 secondary_bus;
- u8 temp_byte;
- u16 command;
- u16 save_command;
- u16 w_base, w_length;
- u32 temp_register;
- u32 save_base;
- u32 base, length;
- u64 base64 = 0;
- int index = 0;
- unsigned int devfn;
- struct pci_resource *mem_node = NULL;
- struct pci_resource *p_mem_node = NULL;
- struct pci_resource *t_mem_node;
- struct pci_resource *io_node;
- struct pci_resource *bus_node;
- struct pci_bus lpci_bus, *pci_bus;
- memcpy(&lpci_bus, ctrl->pci_dev->subordinate, sizeof(lpci_bus));
- pci_bus = &lpci_bus;
-
- if (disable)
- func = shpchp_slot_find(func->bus, func->device, index++);
-
- while ((func != NULL) && func->is_a_board) {
- pci_bus->number = func->bus;
- devfn = PCI_DEVFN(func->device, func->function);
-
- /* Save the command register */
- pci_bus_read_config_word(pci_bus, devfn, PCI_COMMAND, &save_command);
+ int rc = 0;
+ int j;
+ u8 bctl = 0;
+
+ dbg("%s: bus/dev = %x/%x\n", __FUNCTION__, p_slot->bus, p_slot->device);
- if (disable) {
- /* disable card */
- command = 0x00;
- pci_bus_write_config_word(pci_bus, devfn, PCI_COMMAND, command);
+ for (j=0; j<8 ; j++) {
+ struct pci_dev* temp = pci_find_slot(p_slot->bus,
+ (p_slot->device << 3) | j);
+ if (!temp)
+ continue;
+ if ((temp->class >> 16) == PCI_BASE_CLASS_DISPLAY) {
+ err("Cannot remove display device %s\n",
+ pci_name(temp));
+ continue;
}
-
- /* 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 */
- dbg("Save_used_res of PCI bridge b:d=0x%x:%x, sc=0x%x\n",
- func->bus, func->device, save_command);
- if (disable) {
- /* Clear Bridge Control Register */
- command = 0x00;
- pci_bus_write_config_word(pci_bus, devfn, PCI_BRIDGE_CONTROL, command);
+ if (temp->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
+ pci_read_config_byte(temp, PCI_BRIDGE_CONTROL, &bctl);
+ if (bctl & PCI_BRIDGE_CTL_VGA) {
+ err("Cannot remove display device %s\n",
+ pci_name(temp));
+ continue;
}
-
- pci_bus_read_config_byte(pci_bus, devfn, PCI_SECONDARY_BUS, &secondary_bus);
- pci_bus_read_config_byte(pci_bus, devfn, PCI_SUBORDINATE_BUS, &temp_byte);
-
- bus_node = kmalloc(sizeof(struct pci_resource),
- GFP_KERNEL);
- if (!bus_node)
- return -ENOMEM;
-
- bus_node->base = (ulong)secondary_bus;
- bus_node->length = (ulong)(temp_byte - secondary_bus + 1);
-
- bus_node->next = func->bus_head;
- func->bus_head = bus_node;
-
- /* Save IO base and Limit registers */
- pci_bus_read_config_byte(pci_bus, devfn, PCI_IO_BASE, &temp_byte);
- base = temp_byte;
- pci_bus_read_config_byte(pci_bus, devfn, PCI_IO_LIMIT, &temp_byte);
- length = temp_byte;
-
- if ((base <= length) && (!disable || (save_command & PCI_COMMAND_IO))) {
- io_node = kmalloc(sizeof(struct pci_resource),
- GFP_KERNEL);
- if (!io_node)
- return -ENOMEM;
-
- io_node->base = (ulong)(base & PCI_IO_RANGE_MASK) << 8;
- io_node->length = (ulong)(length - base + 0x10) << 8;
-
- io_node->next = func->io_head;
- func->io_head = io_node;
- }
-
- /* 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);
-
- if ((w_base <= w_length) && (!disable || (save_command & PCI_COMMAND_MEMORY))) {
- mem_node = kmalloc(sizeof(struct pci_resource),
- GFP_KERNEL);
- if (!mem_node)
- return -ENOMEM;
-
- mem_node->base = (ulong)w_base << 16;
- mem_node->length = (ulong)(w_length - w_base + 0x10) << 16;
-
- mem_node->next = func->mem_head;
- func->mem_head = mem_node;
- }
- /* 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);
-
- if ((w_base <= w_length) && (!disable || (save_command & PCI_COMMAND_MEMORY))) {
- p_mem_node = kmalloc(sizeof(struct pci_resource),
- GFP_KERNEL);
- if (!p_mem_node)
- return -ENOMEM;
-
- p_mem_node->base = (ulong)w_base << 16;
- p_mem_node->length = (ulong)(w_length - w_base + 0x10) << 16;
-
- p_mem_node->next = func->p_mem_head;
- func->p_mem_head = p_mem_node;
- }
- } else if ((header_type & 0x7F) == PCI_HEADER_TYPE_NORMAL) {
- dbg("Save_used_res of PCI adapter b:d=0x%x:%x, sc=0x%x\n",
- func->bus, func->device, save_command);
-
- /* Figure out IO and memory base lengths */
- for (cloop = PCI_BASE_ADDRESS_0; cloop <= PCI_BASE_ADDRESS_5; cloop += 4) {
- pci_bus_read_config_dword(pci_bus, devfn, cloop, &save_base);
-
- temp_register = 0xFFFFFFFF;
- pci_bus_write_config_dword(pci_bus, devfn, cloop, temp_register);
- pci_bus_read_config_dword(pci_bus, devfn, cloop, &temp_register);
-
- if (!disable)
- pci_bus_write_config_dword(pci_bus, devfn, cloop, save_base);
-
- if (!temp_register)
- continue;
-
- base = temp_register;
-
- if ((base & PCI_BASE_ADDRESS_SPACE_IO) &&
- (!disable || (save_command & PCI_COMMAND_IO))) {
- /* IO base */
- /* set temp_register = amount of IO space requested */
- base = base & 0xFFFFFFFCL;
- base = (~base) + 1;
-
- io_node = kmalloc(sizeof (struct pci_resource),
- GFP_KERNEL);
- if (!io_node)
- return -ENOMEM;
-
- io_node->base = (ulong)save_base & PCI_BASE_ADDRESS_IO_MASK;
- io_node->length = (ulong)base;
- dbg("sur adapter: IO bar=0x%x(length=0x%x)\n",
- io_node->base, io_node->length);
-
- io_node->next = func->io_head;
- func->io_head = io_node;
- } else { /* map Memory */
- int prefetchable = 1;
- /* struct pci_resources **res_node; */
- char *res_type_str = "PMEM";
- u32 temp_register2;
-
- t_mem_node = kmalloc(sizeof (struct pci_resource),
- GFP_KERNEL);
- if (!t_mem_node)
- return -ENOMEM;
-
- if (!(base & PCI_BASE_ADDRESS_MEM_PREFETCH) &&
- (!disable || (save_command & PCI_COMMAND_MEMORY))) {
- prefetchable = 0;
- mem_node = t_mem_node;
- res_type_str++;
- } else
- p_mem_node = t_mem_node;
-
- base = base & 0xFFFFFFF0L;
- base = (~base) + 1;
-
- switch (temp_register & PCI_BASE_ADDRESS_MEM_TYPE_MASK) {
- case PCI_BASE_ADDRESS_MEM_TYPE_32:
- if (prefetchable) {
- p_mem_node->base = (ulong)save_base & PCI_BASE_ADDRESS_MEM_MASK;
- p_mem_node->length = (ulong)base;
- dbg("sur adapter: 32 %s bar=0x%x(length=0x%x)\n",
- res_type_str,
- p_mem_node->base,
- p_mem_node->length);
-
- p_mem_node->next = func->p_mem_head;
- func->p_mem_head = p_mem_node;
- } else {
- mem_node->base = (ulong)save_base & PCI_BASE_ADDRESS_MEM_MASK;
- mem_node->length = (ulong)base;
- dbg("sur adapter: 32 %s bar=0x%x(length=0x%x)\n",
- res_type_str,
- mem_node->base,
- mem_node->length);
-
- mem_node->next = func->mem_head;
- func->mem_head = mem_node;
- }
- break;
- case PCI_BASE_ADDRESS_MEM_TYPE_64:
- pci_bus_read_config_dword(pci_bus, devfn, cloop+4, &temp_register2);
- base64 = temp_register2;
- base64 = (base64 << 32) | save_base;
-
- if (temp_register2) {
- dbg("sur adapter: 64 %s high dword of base64(0x%x:%x) masked to 0\n",
- res_type_str, temp_register2, (u32)base64);
- base64 &= 0x00000000FFFFFFFFL;
- }
-
- if (prefetchable) {
- p_mem_node->base = base64 & PCI_BASE_ADDRESS_MEM_MASK;
- p_mem_node->length = base;
- dbg("sur adapter: 64 %s base=0x%x(len=0x%x)\n",
- res_type_str,
- p_mem_node->base,
- p_mem_node->length);
-
- p_mem_node->next = func->p_mem_head;
- func->p_mem_head = p_mem_node;
- } else {
- mem_node->base = base64 & PCI_BASE_ADDRESS_MEM_MASK;
- mem_node->length = base;
- dbg("sur adapter: 64 %s base=0x%x(len=0x%x)\n",
- res_type_str,
- mem_node->base,
- mem_node->length);
-
- mem_node->next = func->mem_head;
- func->mem_head = mem_node;
- }
- cloop += 4;
- break;
- default:
- dbg("asur: reserved BAR type=0x%x\n",
- temp_register);
- break;
- }
- }
- } /* End of base register loop */
- } else { /* Some other unknown header type */
- dbg("Save_used_res of PCI unknown type b:d=0x%x:%x. skip.\n",
- func->bus, func->device);
}
-
- /* find the next device in this slot */
- if (!disable)
- break;
- func = shpchp_slot_find(func->bus, func->device, index++);
+ pci_remove_bus_device(temp);
}
-
- return 0;
-}
-
-/**
- * kfree_resource_list: release memory of all list members
- * @res: resource list to free
- */
-static inline void
-return_resource_list(struct pci_resource **func, struct pci_resource **res)
-{
- struct pci_resource *node;
- struct pci_resource *t_node;
-
- node = *func;
- *func = NULL;
- while (node) {
- t_node = node->next;
- return_resource(res, node);
- node = t_node;
- }
-}
-
-/*
- * shpchp_return_board_resources
- *
- * this routine returns all resources allocated to a board to
- * the available pool.
- *
- * returns 0 if success
- */
-int shpchp_return_board_resources(struct pci_func * func,
- struct resource_lists * resources)
-{
- int rc;
- dbg("%s\n", __FUNCTION__);
-
- if (!func)
- return 1;
-
- return_resource_list(&(func->io_head),&(resources->io_head));
- return_resource_list(&(func->mem_head),&(resources->mem_head));
- return_resource_list(&(func->p_mem_head),&(resources->p_mem_head));
- return_resource_list(&(func->bus_head),&(resources->bus_head));
-
- rc = shpchp_resource_sort_and_combine(&(resources->mem_head));
- rc |= shpchp_resource_sort_and_combine(&(resources->p_mem_head));
- rc |= shpchp_resource_sort_and_combine(&(resources->io_head));
- rc |= shpchp_resource_sort_and_combine(&(resources->bus_head));
-
return rc;
}
-/**
- * kfree_resource_list: release memory of all list members
- * @res: resource list to free
- */
-static inline void
-kfree_resource_list(struct pci_resource **r)
-{
- struct pci_resource *res, *tres;
-
- res = *r;
- *r = NULL;
-
- while (res) {
- tres = res;
- res = res->next;
- kfree(tres);
- }
-}
-
-/**
- * shpchp_destroy_resource_list: put node back in the resource list
- * @resources: list to put nodes back
- */
-void shpchp_destroy_resource_list(struct resource_lists *resources)
-{
- kfree_resource_list(&(resources->io_head));
- kfree_resource_list(&(resources->mem_head));
- kfree_resource_list(&(resources->p_mem_head));
- kfree_resource_list(&(resources->bus_head));
-}
-
-/**
- * shpchp_destroy_board_resources: put node back in the resource list
- * @resources: list to put nodes back
- */
-void shpchp_destroy_board_resources(struct pci_func * func)
-{
- kfree_resource_list(&(func->io_head));
- kfree_resource_list(&(func->mem_head));
- kfree_resource_list(&(func->p_mem_head));
- kfree_resource_list(&(func->bus_head));
-}
diff --git a/drivers/pci/hotplug/shpchp_sysfs.c b/drivers/pci/hotplug/shpchp_sysfs.c
index c9445ebda5c7..f5cfbf2c047c 100644
--- a/drivers/pci/hotplug/shpchp_sysfs.c
+++ b/drivers/pci/hotplug/shpchp_sysfs.c
@@ -26,12 +26,9 @@
*
*/
-#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/types.h>
-#include <linux/proc_fs.h>
-#include <linux/workqueue.h>
#include <linux/pci.h>
#include "shpchp.h"
@@ -40,104 +37,60 @@
static ssize_t show_ctrl (struct device *dev, struct device_attribute *attr, char *buf)
{
- struct pci_dev *pci_dev;
- struct controller *ctrl;
+ struct pci_dev *pdev;
char * out = buf;
- int index;
- struct pci_resource *res;
+ int index, busnr;
+ struct resource *res;
+ struct pci_bus *bus;
- pci_dev = container_of (dev, struct pci_dev, dev);
- ctrl = pci_get_drvdata(pci_dev);
+ pdev = container_of (dev, struct pci_dev, dev);
+ bus = pdev->subordinate;
out += sprintf(buf, "Free resources: memory\n");
- index = 11;
- res = ctrl->mem_head;
- while (res && index--) {
- out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length);
- res = res->next;
+ for (index = 0; index < PCI_BUS_NUM_RESOURCES; index++) {
+ res = bus->resource[index];
+ if (res && (res->flags & IORESOURCE_MEM) &&
+ !(res->flags & IORESOURCE_PREFETCH)) {
+ out += sprintf(out, "start = %8.8lx, length = %8.8lx\n",
+ res->start, (res->end - res->start));
+ }
}
out += sprintf(out, "Free resources: prefetchable memory\n");
- index = 11;
- res = ctrl->p_mem_head;
- while (res && index--) {
- out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length);
- res = res->next;
+ for (index = 0; index < PCI_BUS_NUM_RESOURCES; index++) {
+ res = bus->resource[index];
+ if (res && (res->flags & IORESOURCE_MEM) &&
+ (res->flags & IORESOURCE_PREFETCH)) {
+ out += sprintf(out, "start = %8.8lx, length = %8.8lx\n",
+ res->start, (res->end - res->start));
+ }
}
out += sprintf(out, "Free resources: IO\n");
- index = 11;
- res = ctrl->io_head;
- while (res && index--) {
- out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length);
- res = res->next;
+ for (index = 0; index < PCI_BUS_NUM_RESOURCES; index++) {
+ res = bus->resource[index];
+ if (res && (res->flags & IORESOURCE_IO)) {
+ out += sprintf(out, "start = %8.8lx, length = %8.8lx\n",
+ res->start, (res->end - res->start));
+ }
}
out += sprintf(out, "Free resources: bus numbers\n");
- index = 11;
- res = ctrl->bus_head;
- while (res && index--) {
- out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length);
- res = res->next;
+ for (busnr = bus->secondary; busnr <= bus->subordinate; busnr++) {
+ if (!pci_find_bus(pci_domain_nr(bus), busnr))
+ break;
}
+ if (busnr < bus->subordinate)
+ out += sprintf(out, "start = %8.8x, length = %8.8x\n",
+ busnr, (bus->subordinate - busnr));
return out - buf;
}
static DEVICE_ATTR (ctrl, S_IRUGO, show_ctrl, NULL);
-static ssize_t show_dev (struct device *dev, struct device_attribute *attr, char *buf)
+void shpchp_create_ctrl_files (struct controller *ctrl)
{
- struct pci_dev *pci_dev;
- struct controller *ctrl;
- char * out = buf;
- int index;
- struct pci_resource *res;
- struct pci_func *new_slot;
- struct slot *slot;
-
- pci_dev = container_of (dev, struct pci_dev, dev);
- ctrl = pci_get_drvdata(pci_dev);
-
- slot=ctrl->slot;
-
- while (slot) {
- new_slot = shpchp_slot_find(slot->bus, slot->device, 0);
- if (!new_slot)
- break;
- out += sprintf(out, "assigned resources: memory\n");
- index = 11;
- res = new_slot->mem_head;
- while (res && index--) {
- out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length);
- res = res->next;
- }
- out += sprintf(out, "assigned resources: prefetchable memory\n");
- index = 11;
- res = new_slot->p_mem_head;
- while (res && index--) {
- out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length);
- res = res->next;
- }
- out += sprintf(out, "assigned resources: IO\n");
- index = 11;
- res = new_slot->io_head;
- while (res && index--) {
- out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length);
- res = res->next;
- }
- out += sprintf(out, "assigned resources: bus numbers\n");
- index = 11;
- res = new_slot->bus_head;
- while (res && index--) {
- out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length);
- res = res->next;
- }
- slot=slot->next;
- }
-
- return out - buf;
+ device_create_file (&ctrl->pci_dev->dev, &dev_attr_ctrl);
}
-static DEVICE_ATTR (dev, S_IRUGO, show_dev, NULL);
-void shpchp_create_ctrl_files (struct controller *ctrl)
+void shpchp_remove_ctrl_files(struct controller *ctrl)
{
- device_create_file (&ctrl->pci_dev->dev, &dev_attr_ctrl);
- device_create_file (&ctrl->pci_dev->dev, &dev_attr_dev);
+ device_remove_file(&ctrl->pci_dev->dev, &dev_attr_ctrl);
}
diff --git a/drivers/pci/hotplug/shpchprm.h b/drivers/pci/hotplug/shpchprm.h
deleted file mode 100644
index 057b192ce589..000000000000
--- a/drivers/pci/hotplug/shpchprm.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * SHPCHPRM : SHPCHP Resource Manager for ACPI/non-ACPI platform
- *
- * Copyright (C) 1995,2001 Compaq Computer Corporation
- * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
- * Copyright (C) 2001 IBM Corp.
- * Copyright (C) 2003-2004 Intel Corporation
- *
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
- * NON INFRINGEMENT. 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.
- *
- * Send feedback to <greg@kroah.com>, <kristen.c.accardi@intel.com>
- *
- */
-
-#ifndef _SHPCHPRM_H_
-#define _SHPCHPRM_H_
-
-#ifdef CONFIG_HOTPLUG_PCI_SHPC_PHPRM_LEGACY
-#include "shpchprm_legacy.h"
-#else
-#include "shpchprm_nonacpi.h"
-#endif
-
-int shpchprm_init(enum php_ctlr_type ct);
-void shpchprm_cleanup(void);
-int shpchprm_print_pirt(void);
-int shpchprm_find_available_resources(struct controller *ctrl);
-int shpchprm_set_hpp(struct controller *ctrl, struct pci_func *func, u8 card_type);
-void shpchprm_enable_card(struct controller *ctrl, struct pci_func *func, u8 card_type);
-int shpchprm_get_physical_slot_number(struct controller *ctrl, u32 *sun, u8 busnum, u8 devnum);
-
-#ifdef DEBUG
-#define RES_CHECK(this, bits) \
- { if (((this) & (bits - 1))) \
- printk("%s:%d ERR: potential res loss!\n", __FUNCTION__, __LINE__); }
-#else
-#define RES_CHECK(this, bits)
-#endif
-
-#endif /* _SHPCHPRM_H_ */
diff --git a/drivers/pci/hotplug/shpchprm_acpi.c b/drivers/pci/hotplug/shpchprm_acpi.c
index d37b31658edf..17145e52223a 100644
--- a/drivers/pci/hotplug/shpchprm_acpi.c
+++ b/drivers/pci/hotplug/shpchprm_acpi.c
@@ -24,91 +24,19 @@
*
*/
-#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/pci.h>
-#include <linux/init.h>
-#include <linux/acpi.h>
-#include <linux/efi.h>
-#include <asm/uaccess.h>
-#include <asm/system.h>
-#ifdef CONFIG_IA64
-#include <asm/iosapic.h>
-#endif
#include <acpi/acpi.h>
#include <acpi/acpi_bus.h>
#include <acpi/actypes.h>
#include "shpchp.h"
-#include "shpchprm.h"
-
-#define PCI_MAX_BUS 0x100
-#define ACPI_STA_DEVICE_PRESENT 0x01
#define METHOD_NAME__SUN "_SUN"
#define METHOD_NAME__HPP "_HPP"
#define METHOD_NAME_OSHP "OSHP"
-#define PHP_RES_BUS 0xA0
-#define PHP_RES_IO 0xA1
-#define PHP_RES_MEM 0xA2
-#define PHP_RES_PMEM 0xA3
-
-#define BRIDGE_TYPE_P2P 0x00
-#define BRIDGE_TYPE_HOST 0x01
-
-/* this should go to drivers/acpi/include/ */
-struct acpi__hpp {
- u8 cache_line_size;
- u8 latency_timer;
- u8 enable_serr;
- u8 enable_perr;
-};
-
-struct acpi_php_slot {
- struct acpi_php_slot *next;
- struct acpi_bridge *bridge;
- acpi_handle handle;
- int seg;
- int bus;
- int dev;
- int fun;
- u32 sun;
- struct pci_resource *mem_head;
- struct pci_resource *p_mem_head;
- struct pci_resource *io_head;
- struct pci_resource *bus_head;
- void *slot_ops; /* _STA, _EJx, etc */
- struct slot *slot;
-}; /* per func */
-
-struct acpi_bridge {
- struct acpi_bridge *parent;
- struct acpi_bridge *next;
- struct acpi_bridge *child;
- acpi_handle handle;
- int seg;
- int pbus; /* pdev->bus->number */
- int pdevice; /* PCI_SLOT(pdev->devfn) */
- int pfunction; /* PCI_DEVFN(pdev->devfn) */
- int bus; /* pdev->subordinate->number */
- struct acpi__hpp *_hpp;
- struct acpi_php_slot *slots;
- struct pci_resource *tmem_head; /* total from crs */
- struct pci_resource *tp_mem_head; /* total from crs */
- struct pci_resource *tio_head; /* total from crs */
- struct pci_resource *tbus_head; /* total from crs */
- struct pci_resource *mem_head; /* available */
- struct pci_resource *p_mem_head; /* available */
- struct pci_resource *io_head; /* available */
- struct pci_resource *bus_head; /* available */
- int scanned;
- int type;
-};
-
-static struct acpi_bridge *acpi_bridges_head;
-
static u8 * acpi_path_name( acpi_handle handle)
{
acpi_status status;
@@ -124,82 +52,43 @@ static u8 * acpi_path_name( acpi_handle handle)
return path_name;
}
-static void acpi_get__hpp ( struct acpi_bridge *ab);
-static void acpi_run_oshp ( struct acpi_bridge *ab);
-
-static int acpi_add_slot_to_php_slots(
- struct acpi_bridge *ab,
- int bus_num,
- acpi_handle handle,
- u32 adr,
- u32 sun
- )
-{
- struct acpi_php_slot *aps;
- static long samesun = -1;
-
- aps = (struct acpi_php_slot *) kmalloc (sizeof(struct acpi_php_slot), GFP_KERNEL);
- if (!aps) {
- err ("acpi_shpchprm: alloc for aps fail\n");
- return -1;
- }
- memset(aps, 0, sizeof(struct acpi_php_slot));
-
- aps->handle = handle;
- aps->bus = bus_num;
- aps->dev = (adr >> 16) & 0xffff;
- aps->fun = adr & 0xffff;
- aps->sun = sun;
-
- aps->next = ab->slots; /* cling to the bridge */
- aps->bridge = ab;
- ab->slots = aps;
-
- ab->scanned += 1;
- if (!ab->_hpp)
- acpi_get__hpp(ab);
-
- acpi_run_oshp(ab);
-
- if (sun != samesun) {
- info("acpi_shpchprm: Slot sun(%x) at s:b:d:f=0x%02x:%02x:%02x:%02x\n", aps->sun, ab->seg,
- aps->bus, aps->dev, aps->fun);
- samesun = sun;
- }
- return 0;
-}
-
-static void acpi_get__hpp ( struct acpi_bridge *ab)
+static acpi_status
+acpi_run_hpp(acpi_handle handle, struct hotplug_params *hpp)
{
acpi_status status;
u8 nui[4];
struct acpi_buffer ret_buf = { 0, NULL};
union acpi_object *ext_obj, *package;
- u8 *path_name = acpi_path_name(ab->handle);
+ u8 *path_name = acpi_path_name(handle);
int i, len = 0;
/* get _hpp */
- status = acpi_evaluate_object(ab->handle, METHOD_NAME__HPP, NULL, &ret_buf);
+ status = acpi_evaluate_object(handle, METHOD_NAME__HPP, NULL, &ret_buf);
switch (status) {
case AE_BUFFER_OVERFLOW:
ret_buf.pointer = kmalloc (ret_buf.length, GFP_KERNEL);
if (!ret_buf.pointer) {
- err ("acpi_shpchprm:%s alloc for _HPP fail\n", path_name);
- return;
+ err ("%s:%s alloc for _HPP fail\n", __FUNCTION__,
+ path_name);
+ return AE_NO_MEMORY;
}
- status = acpi_evaluate_object(ab->handle, METHOD_NAME__HPP, NULL, &ret_buf);
+ status = acpi_evaluate_object(handle, METHOD_NAME__HPP,
+ NULL, &ret_buf);
if (ACPI_SUCCESS(status))
break;
default:
if (ACPI_FAILURE(status)) {
- err("acpi_shpchprm:%s _HPP fail=0x%x\n", path_name, status);
- return;
+ dbg("%s:%s _HPP fail=0x%x\n", __FUNCTION__,
+ path_name, status);
+ return status;
}
}
ext_obj = (union acpi_object *) ret_buf.pointer;
if (ext_obj->type != ACPI_TYPE_PACKAGE) {
- err ("acpi_shpchprm:%s _HPP obj not a package\n", path_name);
+ err ("%s:%s _HPP obj not a package\n", __FUNCTION__,
+ path_name);
+ status = AE_ERROR;
goto free_and_return;
}
@@ -212,1353 +101,41 @@ static void acpi_get__hpp ( struct acpi_bridge *ab)
nui[i] = (u8)ext_obj->integer.value;
break;
default:
- err ("acpi_shpchprm:%s _HPP obj type incorrect\n", path_name);
+ err ("%s:%s _HPP obj type incorrect\n", __FUNCTION__,
+ path_name);
+ status = AE_ERROR;
goto free_and_return;
}
}
- ab->_hpp = kmalloc (sizeof (struct acpi__hpp), GFP_KERNEL);
- if (!ab->_hpp) {
- err ("acpi_shpchprm:%s alloc for _HPP failed\n", path_name);
- goto free_and_return;
- }
- memset(ab->_hpp, 0, sizeof(struct acpi__hpp));
+ hpp->cache_line_size = nui[0];
+ hpp->latency_timer = nui[1];
+ hpp->enable_serr = nui[2];
+ hpp->enable_perr = nui[3];
- ab->_hpp->cache_line_size = nui[0];
- ab->_hpp->latency_timer = nui[1];
- ab->_hpp->enable_serr = nui[2];
- ab->_hpp->enable_perr = nui[3];
-
- dbg(" _HPP: cache_line_size=0x%x\n", ab->_hpp->cache_line_size);
- dbg(" _HPP: latency timer =0x%x\n", ab->_hpp->latency_timer);
- dbg(" _HPP: enable SERR =0x%x\n", ab->_hpp->enable_serr);
- dbg(" _HPP: enable PERR =0x%x\n", ab->_hpp->enable_perr);
+ dbg(" _HPP: cache_line_size=0x%x\n", hpp->cache_line_size);
+ dbg(" _HPP: latency timer =0x%x\n", hpp->latency_timer);
+ dbg(" _HPP: enable SERR =0x%x\n", hpp->enable_serr);
+ dbg(" _HPP: enable PERR =0x%x\n", hpp->enable_perr);
free_and_return:
kfree(ret_buf.pointer);
-}
-
-static void acpi_run_oshp ( struct acpi_bridge *ab)
-{
- acpi_status status;
- u8 *path_name = acpi_path_name(ab->handle);
-
- /* run OSHP */
- status = acpi_evaluate_object(ab->handle, METHOD_NAME_OSHP, NULL, NULL);
- if (ACPI_FAILURE(status)) {
- err("acpi_pciehprm:%s OSHP fails=0x%x\n", path_name, status);
- } else
- dbg("acpi_pciehprm:%s OSHP passes =0x%x\n", path_name, status);
- return;
-}
-
-static acpi_status acpi_evaluate_crs(
- acpi_handle handle,
- struct acpi_resource **retbuf
- )
-{
- acpi_status status;
- struct acpi_buffer crsbuf;
- u8 *path_name = acpi_path_name(handle);
-
- crsbuf.length = 0;
- crsbuf.pointer = NULL;
-
- status = acpi_get_current_resources (handle, &crsbuf);
-
- switch (status) {
- case AE_BUFFER_OVERFLOW:
- break; /* found */
- case AE_NOT_FOUND:
- dbg("acpi_shpchprm:%s _CRS not found\n", path_name);
- return status;
- default:
- err ("acpi_shpchprm:%s _CRS fail=0x%x\n", path_name, status);
- return status;
- }
-
- crsbuf.pointer = kmalloc (crsbuf.length, GFP_KERNEL);
- if (!crsbuf.pointer) {
- err ("acpi_shpchprm: alloc %ld bytes for %s _CRS fail\n", (ulong)crsbuf.length, path_name);
- return AE_NO_MEMORY;
- }
-
- status = acpi_get_current_resources (handle, &crsbuf);
- if (ACPI_FAILURE(status)) {
- err("acpi_shpchprm: %s _CRS fail=0x%x.\n", path_name, status);
- kfree(crsbuf.pointer);
- return status;
- }
-
- *retbuf = crsbuf.pointer;
-
- return status;
-}
-
-static void free_pci_resource ( struct pci_resource *aprh)
-{
- struct pci_resource *res, *next;
-
- for (res = aprh; res; res = next) {
- next = res->next;
- kfree(res);
- }
-}
-
-static void print_pci_resource ( struct pci_resource *aprh)
-{
- struct pci_resource *res;
-
- for (res = aprh; res; res = res->next)
- dbg(" base= 0x%x length= 0x%x\n", res->base, res->length);
-}
-
-static void print_slot_resources( struct acpi_php_slot *aps)
-{
- if (aps->bus_head) {
- dbg(" BUS Resources:\n");
- print_pci_resource (aps->bus_head);
- }
-
- if (aps->io_head) {
- dbg(" IO Resources:\n");
- print_pci_resource (aps->io_head);
- }
-
- if (aps->mem_head) {
- dbg(" MEM Resources:\n");
- print_pci_resource (aps->mem_head);
- }
-
- if (aps->p_mem_head) {
- dbg(" PMEM Resources:\n");
- print_pci_resource (aps->p_mem_head);
- }
-}
-
-static void print_pci_resources( struct acpi_bridge *ab)
-{
- if (ab->tbus_head) {
- dbg(" Total BUS Resources:\n");
- print_pci_resource (ab->tbus_head);
- }
- if (ab->bus_head) {
- dbg(" BUS Resources:\n");
- print_pci_resource (ab->bus_head);
- }
-
- if (ab->tio_head) {
- dbg(" Total IO Resources:\n");
- print_pci_resource (ab->tio_head);
- }
- if (ab->io_head) {
- dbg(" IO Resources:\n");
- print_pci_resource (ab->io_head);
- }
-
- if (ab->tmem_head) {
- dbg(" Total MEM Resources:\n");
- print_pci_resource (ab->tmem_head);
- }
- if (ab->mem_head) {
- dbg(" MEM Resources:\n");
- print_pci_resource (ab->mem_head);
- }
-
- if (ab->tp_mem_head) {
- dbg(" Total PMEM Resources:\n");
- print_pci_resource (ab->tp_mem_head);
- }
- if (ab->p_mem_head) {
- dbg(" PMEM Resources:\n");
- print_pci_resource (ab->p_mem_head);
- }
- if (ab->_hpp) {
- dbg(" _HPP: cache_line_size=0x%x\n", ab->_hpp->cache_line_size);
- dbg(" _HPP: latency timer =0x%x\n", ab->_hpp->latency_timer);
- dbg(" _HPP: enable SERR =0x%x\n", ab->_hpp->enable_serr);
- dbg(" _HPP: enable PERR =0x%x\n", ab->_hpp->enable_perr);
- }
-}
-
-static int shpchprm_delete_resource(
- struct pci_resource **aprh,
- ulong base,
- ulong size)
-{
- struct pci_resource *res;
- struct pci_resource *prevnode;
- struct pci_resource *split_node;
- ulong tbase;
-
- shpchp_resource_sort_and_combine(aprh);
-
- for (res = *aprh; res; res = res->next) {
- if (res->base > base)
- continue;
-
- if ((res->base + res->length) < (base + size))
- continue;
-
- if (res->base < base) {
- tbase = base;
-
- if ((res->length - (tbase - res->base)) < size)
- continue;
-
- split_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
- if (!split_node)
- return -ENOMEM;
-
- split_node->base = res->base;
- split_node->length = tbase - res->base;
- res->base = tbase;
- res->length -= split_node->length;
-
- split_node->next = res->next;
- res->next = split_node;
- }
-
- if (res->length >= size) {
- split_node = (struct pci_resource*) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
- if (!split_node)
- return -ENOMEM;
-
- split_node->base = res->base + size;
- split_node->length = res->length - size;
- res->length = size;
-
- split_node->next = res->next;
- res->next = split_node;
- }
-
- if (*aprh == res) {
- *aprh = res->next;
- } else {
- prevnode = *aprh;
- while (prevnode->next != res)
- prevnode = prevnode->next;
-
- prevnode->next = res->next;
- }
- res->next = NULL;
- kfree(res);
- break;
- }
-
- return 0;
-}
-
-static int shpchprm_delete_resources(
- struct pci_resource **aprh,
- struct pci_resource *this
- )
-{
- struct pci_resource *res;
-
- for (res = this; res; res = res->next)
- shpchprm_delete_resource(aprh, res->base, res->length);
-
- return 0;
-}
-
-static int shpchprm_add_resource(
- struct pci_resource **aprh,
- ulong base,
- ulong size)
-{
- struct pci_resource *res;
-
- for (res = *aprh; res; res = res->next) {
- if ((res->base + res->length) == base) {
- res->length += size;
- size = 0L;
- break;
- }
- if (res->next == *aprh)
- break;
- }
-
- if (size) {
- res = kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
- if (!res) {
- err ("acpi_shpchprm: alloc for res fail\n");
- return -ENOMEM;
- }
- memset(res, 0, sizeof (struct pci_resource));
-
- res->base = base;
- res->length = size;
- res->next = *aprh;
- *aprh = res;
- }
-
- return 0;
-}
-
-static int shpchprm_add_resources(
- struct pci_resource **aprh,
- struct pci_resource *this
- )
-{
- struct pci_resource *res;
- int rc = 0;
-
- for (res = this; res && !rc; res = res->next)
- rc = shpchprm_add_resource(aprh, res->base, res->length);
-
- return rc;
-}
-
-static void acpi_parse_io (
- struct acpi_bridge *ab,
- union acpi_resource_data *data
- )
-{
- struct acpi_resource_io *dataio;
- dataio = (struct acpi_resource_io *) data;
-
- dbg("Io Resource\n");
- dbg(" %d bit decode\n", ACPI_DECODE_16 == dataio->io_decode ? 16:10);
- dbg(" Range minimum base: %08X\n", dataio->min_base_address);
- dbg(" Range maximum base: %08X\n", dataio->max_base_address);
- dbg(" Alignment: %08X\n", dataio->alignment);
- dbg(" Range Length: %08X\n", dataio->range_length);
-}
-
-static void acpi_parse_fixed_io (
- struct acpi_bridge *ab,
- union acpi_resource_data *data
- )
-{
- struct acpi_resource_fixed_io *datafio;
- datafio = (struct acpi_resource_fixed_io *) data;
-
- dbg("Fixed Io Resource\n");
- dbg(" Range base address: %08X", datafio->base_address);
- dbg(" Range length: %08X", datafio->range_length);
-}
-
-static void acpi_parse_address16_32 (
- struct acpi_bridge *ab,
- union acpi_resource_data *data,
- acpi_resource_type id
- )
-{
- /*
- * acpi_resource_address16 == acpi_resource_address32
- * acpi_resource_address16 *data16 = (acpi_resource_address16 *) data;
- */
- struct acpi_resource_address32 *data32 = (struct acpi_resource_address32 *) data;
- struct pci_resource **aprh, **tprh;
-
- if (id == ACPI_RSTYPE_ADDRESS16)
- dbg("acpi_shpchprm:16-Bit Address Space Resource\n");
- else
- dbg("acpi_shpchprm:32-Bit Address Space Resource\n");
-
- switch (data32->resource_type) {
- case ACPI_MEMORY_RANGE:
- dbg(" Resource Type: Memory Range\n");
- aprh = &ab->mem_head;
- tprh = &ab->tmem_head;
-
- switch (data32->attribute.memory.cache_attribute) {
- case ACPI_NON_CACHEABLE_MEMORY:
- dbg(" Type Specific: Noncacheable memory\n");
- break;
- case ACPI_CACHABLE_MEMORY:
- dbg(" Type Specific: Cacheable memory\n");
- break;
- case ACPI_WRITE_COMBINING_MEMORY:
- dbg(" Type Specific: Write-combining memory\n");
- break;
- case ACPI_PREFETCHABLE_MEMORY:
- aprh = &ab->p_mem_head;
- dbg(" Type Specific: Prefetchable memory\n");
- break;
- default:
- dbg(" Type Specific: Invalid cache attribute\n");
- break;
- }
-
- dbg(" Type Specific: Read%s\n", ACPI_READ_WRITE_MEMORY == data32->attribute.memory.read_write_attribute ? "/Write":" Only");
- break;
-
- case ACPI_IO_RANGE:
- dbg(" Resource Type: I/O Range\n");
- aprh = &ab->io_head;
- tprh = &ab->tio_head;
-
- switch (data32->attribute.io.range_attribute) {
- case ACPI_NON_ISA_ONLY_RANGES:
- dbg(" Type Specific: Non-ISA Io Addresses\n");
- break;
- case ACPI_ISA_ONLY_RANGES:
- dbg(" Type Specific: ISA Io Addresses\n");
- break;
- case ACPI_ENTIRE_RANGE:
- dbg(" Type Specific: ISA and non-ISA Io Addresses\n");
- break;
- default:
- dbg(" Type Specific: Invalid range attribute\n");
- break;
- }
- break;
-
- case ACPI_BUS_NUMBER_RANGE:
- dbg(" Resource Type: Bus Number Range(fixed)\n");
- /* fixup to be compatible with the rest of php driver */
- data32->min_address_range++;
- data32->address_length--;
- aprh = &ab->bus_head;
- tprh = &ab->tbus_head;
- break;
- default:
- dbg(" Resource Type: Invalid resource type. Exiting.\n");
- return;
- }
-
- dbg(" Resource %s\n", ACPI_CONSUMER == data32->producer_consumer ? "Consumer":"Producer");
- dbg(" %s decode\n", ACPI_SUB_DECODE == data32->decode ? "Subtractive":"Positive");
- dbg(" Min address is %s fixed\n", ACPI_ADDRESS_FIXED == data32->min_address_fixed ? "":"not");
- dbg(" Max address is %s fixed\n", ACPI_ADDRESS_FIXED == data32->max_address_fixed ? "":"not");
- dbg(" Granularity: %08X\n", data32->granularity);
- dbg(" Address range min: %08X\n", data32->min_address_range);
- dbg(" Address range max: %08X\n", data32->max_address_range);
- dbg(" Address translation offset: %08X\n", data32->address_translation_offset);
- dbg(" Address Length: %08X\n", data32->address_length);
-
- if (0xFF != data32->resource_source.index) {
- dbg(" Resource Source Index: %X\n", data32->resource_source.index);
- /* dbg(" Resource Source: %s\n", data32->resource_source.string_ptr); */
- }
-
- shpchprm_add_resource(aprh, data32->min_address_range, data32->address_length);
-}
-
-static acpi_status acpi_parse_crs(
- struct acpi_bridge *ab,
- struct acpi_resource *crsbuf
- )
-{
- acpi_status status = AE_OK;
- struct acpi_resource *resource = crsbuf;
- u8 count = 0;
- u8 done = 0;
-
- while (!done) {
- dbg("acpi_shpchprm: PCI bus 0x%x Resource structure %x.\n", ab->bus, count++);
- switch (resource->id) {
- case ACPI_RSTYPE_IRQ:
- dbg("Irq -------- Resource\n");
- break;
- case ACPI_RSTYPE_DMA:
- dbg("DMA -------- Resource\n");
- break;
- case ACPI_RSTYPE_START_DPF:
- dbg("Start DPF -------- Resource\n");
- break;
- case ACPI_RSTYPE_END_DPF:
- dbg("End DPF -------- Resource\n");
- break;
- case ACPI_RSTYPE_IO:
- acpi_parse_io (ab, &resource->data);
- break;
- case ACPI_RSTYPE_FIXED_IO:
- acpi_parse_fixed_io (ab, &resource->data);
- break;
- case ACPI_RSTYPE_VENDOR:
- dbg("Vendor -------- Resource\n");
- break;
- case ACPI_RSTYPE_END_TAG:
- dbg("End_tag -------- Resource\n");
- done = 1;
- break;
- case ACPI_RSTYPE_MEM24:
- dbg("Mem24 -------- Resource\n");
- break;
- case ACPI_RSTYPE_MEM32:
- dbg("Mem32 -------- Resource\n");
- break;
- case ACPI_RSTYPE_FIXED_MEM32:
- dbg("Fixed Mem32 -------- Resource\n");
- break;
- case ACPI_RSTYPE_ADDRESS16:
- acpi_parse_address16_32(ab, &resource->data, ACPI_RSTYPE_ADDRESS16);
- break;
- case ACPI_RSTYPE_ADDRESS32:
- acpi_parse_address16_32(ab, &resource->data, ACPI_RSTYPE_ADDRESS32);
- break;
- case ACPI_RSTYPE_ADDRESS64:
- info("Address64 -------- Resource unparsed\n");
- break;
- case ACPI_RSTYPE_EXT_IRQ:
- dbg("Ext Irq -------- Resource\n");
- break;
- default:
- dbg("Invalid -------- resource type 0x%x\n", resource->id);
- break;
- }
-
- resource = (struct acpi_resource *) ((char *)resource + resource->length);
- }
-
return status;
}
-static acpi_status acpi_get_crs( struct acpi_bridge *ab)
+static void acpi_run_oshp(acpi_handle handle)
{
acpi_status status;
- struct acpi_resource *crsbuf;
-
- status = acpi_evaluate_crs(ab->handle, &crsbuf);
- if (ACPI_SUCCESS(status)) {
- status = acpi_parse_crs(ab, crsbuf);
- kfree(crsbuf);
-
- shpchp_resource_sort_and_combine(&ab->bus_head);
- shpchp_resource_sort_and_combine(&ab->io_head);
- shpchp_resource_sort_and_combine(&ab->mem_head);
- shpchp_resource_sort_and_combine(&ab->p_mem_head);
-
- shpchprm_add_resources (&ab->tbus_head, ab->bus_head);
- shpchprm_add_resources (&ab->tio_head, ab->io_head);
- shpchprm_add_resources (&ab->tmem_head, ab->mem_head);
- shpchprm_add_resources (&ab->tp_mem_head, ab->p_mem_head);
- }
-
- return status;
-}
-
-/* find acpi_bridge downword from ab. */
-static struct acpi_bridge *
-find_acpi_bridge_by_bus(
- struct acpi_bridge *ab,
- int seg,
- int bus /* pdev->subordinate->number */
- )
-{
- struct acpi_bridge *lab = NULL;
-
- if (!ab)
- return NULL;
-
- if ((ab->bus == bus) && (ab->seg == seg))
- return ab;
-
- if (ab->child)
- lab = find_acpi_bridge_by_bus(ab->child, seg, bus);
-
- if (!lab)
- if (ab->next)
- lab = find_acpi_bridge_by_bus(ab->next, seg, bus);
-
- return lab;
-}
-
-/*
- * Build a device tree of ACPI PCI Bridges
- */
-static void shpchprm_acpi_register_a_bridge (
- struct acpi_bridge **head,
- struct acpi_bridge *pab, /* parent bridge to which child bridge is added */
- struct acpi_bridge *cab /* child bridge to add */
- )
-{
- struct acpi_bridge *lpab;
- struct acpi_bridge *lcab;
-
- lpab = find_acpi_bridge_by_bus(*head, pab->seg, pab->bus);
- if (!lpab) {
- if (!(pab->type & BRIDGE_TYPE_HOST))
- warn("PCI parent bridge s:b(%x:%x) not in list.\n", pab->seg, pab->bus);
- pab->next = *head;
- *head = pab;
- lpab = pab;
- }
-
- if ((cab->type & BRIDGE_TYPE_HOST) && (pab == cab))
- return;
-
- lcab = find_acpi_bridge_by_bus(*head, cab->seg, cab->bus);
- if (lcab) {
- if ((pab->bus != lcab->parent->bus) || (lcab->bus != cab->bus))
- err("PCI child bridge s:b(%x:%x) in list with diff parent.\n", cab->seg, cab->bus);
- return;
- } else
- lcab = cab;
-
- lcab->parent = lpab;
- lcab->next = lpab->child;
- lpab->child = lcab;
-}
-
-static acpi_status shpchprm_acpi_build_php_slots_callback(
- acpi_handle handle,
- u32 Level,
- void *context,
- void **retval
- )
-{
- ulong bus_num;
- ulong seg_num;
- ulong sun, adr;
- ulong padr = 0;
- acpi_handle phandle = NULL;
- struct acpi_bridge *pab = (struct acpi_bridge *)context;
- struct acpi_bridge *lab;
- acpi_status status;
u8 *path_name = acpi_path_name(handle);
- /* get _SUN */
- status = acpi_evaluate_integer(handle, METHOD_NAME__SUN, NULL, &sun);
- switch(status) {
- case AE_NOT_FOUND:
- return AE_OK;
- default:
- if (ACPI_FAILURE(status)) {
- err("acpi_shpchprm:%s _SUN fail=0x%x\n", path_name, status);
- return status;
- }
- }
-
- /* get _ADR. _ADR must exist if _SUN exists */
- status = acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL, &adr);
- if (ACPI_FAILURE(status)) {
- err("acpi_shpchprm:%s _ADR fail=0x%x\n", path_name, status);
- return status;
- }
-
- dbg("acpi_shpchprm:%s sun=0x%08x adr=0x%08x\n", path_name, (u32)sun, (u32)adr);
-
- status = acpi_get_parent(handle, &phandle);
+ /* run OSHP */
+ status = acpi_evaluate_object(handle, METHOD_NAME_OSHP, NULL, NULL);
if (ACPI_FAILURE(status)) {
- err("acpi_shpchprm:%s get_parent fail=0x%x\n", path_name, status);
- return (status);
- }
-
- bus_num = pab->bus;
- seg_num = pab->seg;
-
- if (pab->bus == bus_num) {
- lab = pab;
+ err("%s:%s OSHP fails=0x%x\n", __FUNCTION__, path_name,
+ status);
} else {
- dbg("WARN: pab is not parent\n");
- lab = find_acpi_bridge_by_bus(pab, seg_num, bus_num);
- if (!lab) {
- dbg("acpi_shpchprm: alloc new P2P bridge(%x) for sun(%08x)\n", (u32)bus_num, (u32)sun);
- lab = (struct acpi_bridge *)kmalloc(sizeof(struct acpi_bridge), GFP_KERNEL);
- if (!lab) {
- err("acpi_shpchprm: alloc for ab fail\n");
- return AE_NO_MEMORY;
- }
- memset(lab, 0, sizeof(struct acpi_bridge));
-
- lab->handle = phandle;
- lab->pbus = pab->bus;
- lab->pdevice = (int)(padr >> 16) & 0xffff;
- lab->pfunction = (int)(padr & 0xffff);
- lab->bus = (int)bus_num;
- lab->scanned = 0;
- lab->type = BRIDGE_TYPE_P2P;
-
- shpchprm_acpi_register_a_bridge (&acpi_bridges_head, pab, lab);
- } else
- dbg("acpi_shpchprm: found P2P bridge(%x) for sun(%08x)\n", (u32)bus_num, (u32)sun);
+ dbg("%s:%s OSHP passes\n", __FUNCTION__, path_name);
}
-
- acpi_add_slot_to_php_slots(lab, (int)bus_num, handle, (u32)adr, (u32)sun);
- return (status);
-}
-
-static int shpchprm_acpi_build_php_slots(
- struct acpi_bridge *ab,
- u32 depth
- )
-{
- acpi_status status;
- u8 *path_name = acpi_path_name(ab->handle);
-
- /* Walk down this pci bridge to get _SUNs if any behind P2P */
- status = acpi_walk_namespace ( ACPI_TYPE_DEVICE,
- ab->handle,
- depth,
- shpchprm_acpi_build_php_slots_callback,
- ab,
- NULL );
- if (ACPI_FAILURE(status)) {
- dbg("acpi_shpchprm:%s walk for _SUN on pci bridge seg:bus(%x:%x) fail=0x%x\n", path_name, ab->seg, ab->bus, status);
- return -1;
- }
-
- return 0;
-}
-
-static void build_a_bridge(
- struct acpi_bridge *pab,
- struct acpi_bridge *ab
- )
-{
- u8 *path_name = acpi_path_name(ab->handle);
-
- shpchprm_acpi_register_a_bridge (&acpi_bridges_head, pab, ab);
-
- switch (ab->type) {
- case BRIDGE_TYPE_HOST:
- dbg("acpi_shpchprm: Registered PCI HOST Bridge(%02x) on s:b:d:f(%02x:%02x:%02x:%02x) [%s]\n",
- ab->bus, ab->seg, ab->pbus, ab->pdevice, ab->pfunction, path_name);
- break;
- case BRIDGE_TYPE_P2P:
- dbg("acpi_shpchprm: Registered PCI P2P Bridge(%02x-%02x) on s:b:d:f(%02x:%02x:%02x:%02x) [%s]\n",
- ab->pbus, ab->bus, ab->seg, ab->pbus, ab->pdevice, ab->pfunction, path_name);
- break;
- };
-
- /* build any immediate PHP slots under this pci bridge */
- shpchprm_acpi_build_php_slots(ab, 1);
-}
-
-static struct acpi_bridge * add_p2p_bridge(
- acpi_handle handle,
- struct acpi_bridge *pab, /* parent */
- ulong adr
- )
-{
- struct acpi_bridge *ab;
- struct pci_dev *pdev;
- ulong devnum, funcnum;
- u8 *path_name = acpi_path_name(handle);
-
- ab = (struct acpi_bridge *) kmalloc (sizeof(struct acpi_bridge), GFP_KERNEL);
- if (!ab) {
- err("acpi_shpchprm: alloc for ab fail\n");
- return NULL;
- }
- memset(ab, 0, sizeof(struct acpi_bridge));
-
- devnum = (adr >> 16) & 0xffff;
- funcnum = adr & 0xffff;
-
- pdev = pci_find_slot(pab->bus, PCI_DEVFN(devnum, funcnum));
- if (!pdev || !pdev->subordinate) {
- err("acpi_shpchprm:%s is not a P2P Bridge\n", path_name);
- kfree(ab);
- return NULL;
- }
-
- ab->handle = handle;
- ab->seg = pab->seg;
- ab->pbus = pab->bus; /* or pdev->bus->number */
- ab->pdevice = devnum; /* or PCI_SLOT(pdev->devfn) */
- ab->pfunction = funcnum; /* or PCI_FUNC(pdev->devfn) */
- ab->bus = pdev->subordinate->number;
- ab->scanned = 0;
- ab->type = BRIDGE_TYPE_P2P;
-
- dbg("acpi_shpchprm: P2P(%x-%x) on pci=b:d:f(%x:%x:%x) acpi=b:d:f(%x:%x:%x) [%s]\n",
- pab->bus, ab->bus, pdev->bus->number, PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn),
- pab->bus, (u32)devnum, (u32)funcnum, path_name);
-
- build_a_bridge(pab, ab);
-
- return ab;
-}
-
-static acpi_status scan_p2p_bridge(
- acpi_handle handle,
- u32 Level,
- void *context,
- void **retval
- )
-{
- struct acpi_bridge *pab = (struct acpi_bridge *)context;
- struct acpi_bridge *ab;
- acpi_status status;
- ulong adr = 0;
- u8 *path_name = acpi_path_name(handle);
- ulong devnum, funcnum;
- struct pci_dev *pdev;
-
- /* get device, function */
- status = acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL, &adr);
- if (ACPI_FAILURE(status)) {
- if (status != AE_NOT_FOUND)
- err("acpi_shpchprm:%s _ADR fail=0x%x\n", path_name, status);
- return AE_OK;
- }
-
- devnum = (adr >> 16) & 0xffff;
- funcnum = adr & 0xffff;
-
- pdev = pci_find_slot(pab->bus, PCI_DEVFN(devnum, funcnum));
- if (!pdev)
- return AE_OK;
- if (!pdev->subordinate)
- return AE_OK;
-
- ab = add_p2p_bridge(handle, pab, adr);
- if (ab) {
- status = acpi_walk_namespace ( ACPI_TYPE_DEVICE,
- handle,
- (u32)1,
- scan_p2p_bridge,
- ab,
- NULL);
- if (ACPI_FAILURE(status))
- dbg("acpi_shpchprm:%s find_p2p fail=0x%x\n", path_name, status);
- }
-
- return AE_OK;
-}
-
-static struct acpi_bridge * add_host_bridge(
- acpi_handle handle,
- ulong segnum,
- ulong busnum
- )
-{
- ulong adr = 0;
- acpi_status status;
- struct acpi_bridge *ab;
- u8 *path_name = acpi_path_name(handle);
-
- /* get device, function: host br adr is always 0000 though. */
- status = acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL, &adr);
- if (ACPI_FAILURE(status)) {
- err("acpi_shpchprm:%s _ADR fail=0x%x\n", path_name, status);
- return NULL;
- }
- dbg("acpi_shpchprm: ROOT PCI seg(0x%x)bus(0x%x)dev(0x%x)func(0x%x) [%s]\n", (u32)segnum, (u32)busnum,
- (u32)(adr >> 16) & 0xffff, (u32)adr & 0xffff, path_name);
-
- ab = (struct acpi_bridge *) kmalloc (sizeof(struct acpi_bridge), GFP_KERNEL);
- if (!ab) {
- err("acpi_shpchprm: alloc for ab fail\n");
- return NULL;
- }
- memset(ab, 0, sizeof(struct acpi_bridge));
-
- ab->handle = handle;
- ab->seg = (int)segnum;
- ab->bus = ab->pbus = (int)busnum;
- ab->pdevice = (int)(adr >> 16) & 0xffff;
- ab->pfunction = (int)(adr & 0xffff);
- ab->scanned = 0;
- ab->type = BRIDGE_TYPE_HOST;
-
- /* get root pci bridge's current resources */
- status = acpi_get_crs(ab);
- if (ACPI_FAILURE(status)) {
- err("acpi_shpchprm:%s evaluate _CRS fail=0x%x\n", path_name, status);
- kfree(ab);
- return NULL;
- }
- build_a_bridge(ab, ab);
-
- return ab;
-}
-
-static acpi_status acpi_scan_from_root_pci_callback (
- acpi_handle handle,
- u32 Level,
- void *context,
- void **retval
- )
-{
- ulong segnum = 0;
- ulong busnum = 0;
- acpi_status status;
- struct acpi_bridge *ab;
- u8 *path_name = acpi_path_name(handle);
-
- /* get bus number of this pci root bridge */
- status = acpi_evaluate_integer(handle, METHOD_NAME__SEG, NULL, &segnum);
- if (ACPI_FAILURE(status)) {
- if (status != AE_NOT_FOUND) {
- err("acpi_shpchprm:%s evaluate _SEG fail=0x%x\n", path_name, status);
- return status;
- }
- segnum = 0;
- }
-
- /* get bus number of this pci root bridge */
- status = acpi_evaluate_integer(handle, METHOD_NAME__BBN, NULL, &busnum);
- if (ACPI_FAILURE(status)) {
- err("acpi_shpchprm:%s evaluate _BBN fail=0x%x\n", path_name, status);
- return (status);
- }
-
- ab = add_host_bridge(handle, segnum, busnum);
- if (ab) {
- status = acpi_walk_namespace ( ACPI_TYPE_DEVICE,
- handle,
- 1,
- scan_p2p_bridge,
- ab,
- NULL);
- if (ACPI_FAILURE(status))
- dbg("acpi_shpchprm:%s find_p2p fail=0x%x\n", path_name, status);
- }
-
- return AE_OK;
-}
-
-static int shpchprm_acpi_scan_pci (void)
-{
- acpi_status status;
-
- /*
- * TBD: traverse LDM device tree with the help of
- * unified ACPI augmented for php device population.
- */
- status = acpi_get_devices ( PCI_ROOT_HID_STRING,
- acpi_scan_from_root_pci_callback,
- NULL,
- NULL );
- if (ACPI_FAILURE(status)) {
- err("acpi_shpchprm:get_device PCI ROOT HID fail=0x%x\n", status);
- return -1;
- }
-
- return 0;
-}
-
-int shpchprm_init(enum php_ctlr_type ctlr_type)
-{
- int rc;
-
- if (ctlr_type != PCI)
- return -ENODEV;
-
- dbg("shpchprm ACPI init <enter>\n");
- acpi_bridges_head = NULL;
-
- /* construct PCI bus:device tree of acpi_handles */
- rc = shpchprm_acpi_scan_pci();
- if (rc)
- return rc;
-
- dbg("shpchprm ACPI init %s\n", (rc)?"fail":"success");
- return rc;
-}
-
-static void free_a_slot(struct acpi_php_slot *aps)
-{
- dbg(" free a php func of slot(0x%02x) on PCI b:d:f=0x%02x:%02x:%02x\n", aps->sun, aps->bus, aps->dev, aps->fun);
-
- free_pci_resource (aps->io_head);
- free_pci_resource (aps->bus_head);
- free_pci_resource (aps->mem_head);
- free_pci_resource (aps->p_mem_head);
-
- kfree(aps);
-}
-
-static void free_a_bridge( struct acpi_bridge *ab)
-{
- struct acpi_php_slot *aps, *next;
-
- switch (ab->type) {
- case BRIDGE_TYPE_HOST:
- dbg("Free ACPI PCI HOST Bridge(%x) [%s] on s:b:d:f(%x:%x:%x:%x)\n",
- ab->bus, acpi_path_name(ab->handle), ab->seg, ab->pbus, ab->pdevice, ab->pfunction);
- break;
- case BRIDGE_TYPE_P2P:
- dbg("Free ACPI PCI P2P Bridge(%x-%x) [%s] on s:b:d:f(%x:%x:%x:%x)\n",
- ab->pbus, ab->bus, acpi_path_name(ab->handle), ab->seg, ab->pbus, ab->pdevice, ab->pfunction);
- break;
- };
-
- /* free slots first */
- for (aps = ab->slots; aps; aps = next) {
- next = aps->next;
- free_a_slot(aps);
- }
-
- free_pci_resource (ab->io_head);
- free_pci_resource (ab->tio_head);
- free_pci_resource (ab->bus_head);
- free_pci_resource (ab->tbus_head);
- free_pci_resource (ab->mem_head);
- free_pci_resource (ab->tmem_head);
- free_pci_resource (ab->p_mem_head);
- free_pci_resource (ab->tp_mem_head);
-
- kfree(ab);
-}
-
-static void shpchprm_free_bridges ( struct acpi_bridge *ab)
-{
- if (!ab)
- return;
-
- if (ab->child)
- shpchprm_free_bridges (ab->child);
-
- if (ab->next)
- shpchprm_free_bridges (ab->next);
-
- free_a_bridge(ab);
-}
-
-void shpchprm_cleanup(void)
-{
- shpchprm_free_bridges (acpi_bridges_head);
-}
-
-static int get_number_of_slots (
- struct acpi_bridge *ab,
- int selfonly
- )
-{
- struct acpi_php_slot *aps;
- int prev_slot = -1;
- int slot_num = 0;
-
- for ( aps = ab->slots; aps; aps = aps->next)
- if (aps->dev != prev_slot) {
- prev_slot = aps->dev;
- slot_num++;
- }
-
- if (ab->child)
- slot_num += get_number_of_slots (ab->child, 0);
-
- if (selfonly)
- return slot_num;
-
- if (ab->next)
- slot_num += get_number_of_slots (ab->next, 0);
-
- return slot_num;
-}
-
-static int print_acpi_resources (struct acpi_bridge *ab)
-{
- struct acpi_php_slot *aps;
- int i;
-
- switch (ab->type) {
- case BRIDGE_TYPE_HOST:
- dbg("PCI HOST Bridge (%x) [%s]\n", ab->bus, acpi_path_name(ab->handle));
- break;
- case BRIDGE_TYPE_P2P:
- dbg("PCI P2P Bridge (%x-%x) [%s]\n", ab->pbus, ab->bus, acpi_path_name(ab->handle));
- break;
- };
-
- print_pci_resources (ab);
-
- for ( i = -1, aps = ab->slots; aps; aps = aps->next) {
- if (aps->dev == i)
- continue;
- dbg(" Slot sun(%x) s:b:d:f(%02x:%02x:%02x:%02x)\n", aps->sun, aps->seg, aps->bus, aps->dev, aps->fun);
- print_slot_resources(aps);
- i = aps->dev;
- }
-
- if (ab->child)
- print_acpi_resources (ab->child);
-
- if (ab->next)
- print_acpi_resources (ab->next);
-
- return 0;
-}
-
-int shpchprm_print_pirt(void)
-{
- dbg("SHPCHPRM ACPI Slots\n");
- if (acpi_bridges_head)
- print_acpi_resources (acpi_bridges_head);
- return 0;
-}
-
-static struct acpi_php_slot * get_acpi_slot (
- struct acpi_bridge *ab,
- u32 sun
- )
-{
- struct acpi_php_slot *aps = NULL;
-
- for ( aps = ab->slots; aps; aps = aps->next)
- if (aps->sun == sun)
- return aps;
-
- if (!aps && ab->child) {
- aps = (struct acpi_php_slot *)get_acpi_slot (ab->child, sun);
- if (aps)
- return aps;
- }
-
- if (!aps && ab->next) {
- aps = (struct acpi_php_slot *)get_acpi_slot (ab->next, sun);
- if (aps)
- return aps;
- }
-
- return aps;
-
-}
-
-#if 0
-static void * shpchprm_get_slot(struct slot *slot)
-{
- struct acpi_bridge *ab = acpi_bridges_head;
- struct acpi_php_slot *aps = get_acpi_slot (ab, slot->number);
-
- aps->slot = slot;
-
- dbg("Got acpi slot sun(%x): s:b:d:f(%x:%x:%x:%x)\n", aps->sun, aps->seg, aps->bus, aps->dev, aps->fun);
-
- return (void *)aps;
-}
-#endif
-
-static void shpchprm_dump_func_res( struct pci_func *fun)
-{
- struct pci_func *func = fun;
-
- if (func->bus_head) {
- dbg(": BUS Resources:\n");
- print_pci_resource (func->bus_head);
- }
- if (func->io_head) {
- dbg(": IO Resources:\n");
- print_pci_resource (func->io_head);
- }
- if (func->mem_head) {
- dbg(": MEM Resources:\n");
- print_pci_resource (func->mem_head);
- }
- if (func->p_mem_head) {
- dbg(": PMEM Resources:\n");
- print_pci_resource (func->p_mem_head);
- }
-}
-
-static void shpchprm_dump_ctrl_res( struct controller *ctlr)
-{
- struct controller *ctrl = ctlr;
-
- if (ctrl->bus_head) {
- dbg(": BUS Resources:\n");
- print_pci_resource (ctrl->bus_head);
- }
- if (ctrl->io_head) {
- dbg(": IO Resources:\n");
- print_pci_resource (ctrl->io_head);
- }
- if (ctrl->mem_head) {
- dbg(": MEM Resources:\n");
- print_pci_resource (ctrl->mem_head);
- }
- if (ctrl->p_mem_head) {
- dbg(": PMEM Resources:\n");
- print_pci_resource (ctrl->p_mem_head);
- }
-}
-
-static int shpchprm_get_used_resources (
- struct controller *ctrl,
- struct pci_func *func
- )
-{
- return shpchp_save_used_resources (ctrl, func, !DISABLE_CARD);
-}
-
-static int configure_existing_function(
- struct controller *ctrl,
- struct pci_func *func
- )
-{
- int rc;
-
- /* see how much resources the func has used. */
- rc = shpchprm_get_used_resources (ctrl, func);
-
- if (!rc) {
- /* subtract the resources used by the func from ctrl resources */
- rc = shpchprm_delete_resources (&ctrl->bus_head, func->bus_head);
- rc |= shpchprm_delete_resources (&ctrl->io_head, func->io_head);
- rc |= shpchprm_delete_resources (&ctrl->mem_head, func->mem_head);
- rc |= shpchprm_delete_resources (&ctrl->p_mem_head, func->p_mem_head);
- if (rc)
- warn("aCEF: cannot del used resources\n");
- } else
- err("aCEF: cannot get used resources\n");
-
- return rc;
-}
-
-static int bind_pci_resources_to_slots ( struct controller *ctrl)
-{
- struct pci_func *func, new_func;
- int busn = ctrl->slot_bus;
- int devn, funn;
- u32 vid;
-
- for (devn = 0; devn < 32; devn++) {
- for (funn = 0; funn < 8; funn++) {
- /*
- if (devn == ctrl->device && funn == ctrl->function)
- continue;
- */
- /* find out if this entry is for an occupied slot */
- vid = 0xFFFFFFFF;
- pci_bus_read_config_dword(ctrl->pci_dev->subordinate, PCI_DEVFN(devn, funn), PCI_VENDOR_ID, &vid);
-
- if (vid != 0xFFFFFFFF) {
- func = shpchp_slot_find(busn, devn, funn);
- if (!func) {
- memset(&new_func, 0, sizeof(struct pci_func));
- new_func.bus = busn;
- new_func.device = devn;
- new_func.function = funn;
- new_func.is_a_board = 1;
- configure_existing_function(ctrl, &new_func);
- shpchprm_dump_func_res(&new_func);
- } else {
- configure_existing_function(ctrl, func);
- shpchprm_dump_func_res(func);
- }
- dbg("aCCF:existing PCI 0x%x Func ResourceDump\n", ctrl->bus);
- }
- }
- }
-
- return 0;
-}
-
-static int bind_pci_resources(
- struct controller *ctrl,
- struct acpi_bridge *ab
- )
-{
- int status = 0;
-
- if (ab->bus_head) {
- dbg("bapr: BUS Resources add on PCI 0x%x\n", ab->bus);
- status = shpchprm_add_resources (&ctrl->bus_head, ab->bus_head);
- if (shpchprm_delete_resources (&ab->bus_head, ctrl->bus_head))
- warn("bapr: cannot sub BUS Resource on PCI 0x%x\n", ab->bus);
- if (status) {
- err("bapr: BUS Resource add on PCI 0x%x: fail=0x%x\n", ab->bus, status);
- return status;
- }
- } else
- info("bapr: No BUS Resource on PCI 0x%x.\n", ab->bus);
-
- if (ab->io_head) {
- dbg("bapr: IO Resources add on PCI 0x%x\n", ab->bus);
- status = shpchprm_add_resources (&ctrl->io_head, ab->io_head);
- if (shpchprm_delete_resources (&ab->io_head, ctrl->io_head))
- warn("bapr: cannot sub IO Resource on PCI 0x%x\n", ab->bus);
- if (status) {
- err("bapr: IO Resource add on PCI 0x%x: fail=0x%x\n", ab->bus, status);
- return status;
- }
- } else
- info("bapr: No IO Resource on PCI 0x%x.\n", ab->bus);
-
- if (ab->mem_head) {
- dbg("bapr: MEM Resources add on PCI 0x%x\n", ab->bus);
- status = shpchprm_add_resources (&ctrl->mem_head, ab->mem_head);
- if (shpchprm_delete_resources (&ab->mem_head, ctrl->mem_head))
- warn("bapr: cannot sub MEM Resource on PCI 0x%x\n", ab->bus);
- if (status) {
- err("bapr: MEM Resource add on PCI 0x%x: fail=0x%x\n", ab->bus, status);
- return status;
- }
- } else
- info("bapr: No MEM Resource on PCI 0x%x.\n", ab->bus);
-
- if (ab->p_mem_head) {
- dbg("bapr: PMEM Resources add on PCI 0x%x\n", ab->bus);
- status = shpchprm_add_resources (&ctrl->p_mem_head, ab->p_mem_head);
- if (shpchprm_delete_resources (&ab->p_mem_head, ctrl->p_mem_head))
- warn("bapr: cannot sub PMEM Resource on PCI 0x%x\n", ab->bus);
- if (status) {
- err("bapr: PMEM Resource add on PCI 0x%x: fail=0x%x\n", ab->bus, status);
- return status;
- }
- } else
- info("bapr: No PMEM Resource on PCI 0x%x.\n", ab->bus);
-
- return status;
-}
-
-static int no_pci_resources( struct acpi_bridge *ab)
-{
- return !(ab->p_mem_head || ab->mem_head || ab->io_head || ab->bus_head);
-}
-
-static int find_pci_bridge_resources (
- struct controller *ctrl,
- struct acpi_bridge *ab
- )
-{
- int rc = 0;
- struct pci_func func;
-
- memset(&func, 0, sizeof(struct pci_func));
-
- func.bus = ab->pbus;
- func.device = ab->pdevice;
- func.function = ab->pfunction;
- func.is_a_board = 1;
-
- /* Get used resources for this PCI bridge */
- rc = shpchp_save_used_resources (ctrl, &func, !DISABLE_CARD);
-
- ab->io_head = func.io_head;
- ab->mem_head = func.mem_head;
- ab->p_mem_head = func.p_mem_head;
- ab->bus_head = func.bus_head;
- if (ab->bus_head)
- shpchprm_delete_resource(&ab->bus_head, ctrl->bus, 1);
-
- return rc;
-}
-
-static int get_pci_resources_from_bridge(
- struct controller *ctrl,
- struct acpi_bridge *ab
- )
-{
- int rc = 0;
-
- dbg("grfb: Get Resources for PCI 0x%x from actual PCI bridge 0x%x.\n", ctrl->bus, ab->bus);
-
- rc = find_pci_bridge_resources (ctrl, ab);
-
- shpchp_resource_sort_and_combine(&ab->bus_head);
- shpchp_resource_sort_and_combine(&ab->io_head);
- shpchp_resource_sort_and_combine(&ab->mem_head);
- shpchp_resource_sort_and_combine(&ab->p_mem_head);
-
- shpchprm_add_resources (&ab->tbus_head, ab->bus_head);
- shpchprm_add_resources (&ab->tio_head, ab->io_head);
- shpchprm_add_resources (&ab->tmem_head, ab->mem_head);
- shpchprm_add_resources (&ab->tp_mem_head, ab->p_mem_head);
-
- return rc;
-}
-
-static int get_pci_resources(
- struct controller *ctrl,
- struct acpi_bridge *ab
- )
-{
- int rc = 0;
-
- if (no_pci_resources(ab)) {
- dbg("spbr:PCI 0x%x has no resources. Get parent resources.\n", ab->bus);
- rc = get_pci_resources_from_bridge(ctrl, ab);
- }
-
- return rc;
}
int shpchprm_get_physical_slot_number(struct controller *ctrl, u32 *sun, u8 busnum, u8 devnum)
@@ -1570,144 +147,40 @@ int shpchprm_get_physical_slot_number(struct controller *ctrl, u32 *sun, u8 busn
return 0;
}
-/*
- * Get resources for this ctrl.
- * 1. get total resources from ACPI _CRS or bridge (this ctrl)
- * 2. find used resources of existing adapters
- * 3. subtract used resources from total resources
- */
-int shpchprm_find_available_resources( struct controller *ctrl)
+void get_hp_hw_control_from_firmware(struct pci_dev *dev)
{
- int rc = 0;
- struct acpi_bridge *ab;
-
- ab = find_acpi_bridge_by_bus(acpi_bridges_head, ctrl->seg, ctrl->pci_dev->subordinate->number);
- if (!ab) {
- err("pfar:cannot locate acpi bridge of PCI 0x%x.\n", ctrl->pci_dev->subordinate->number);
- return -1;
- }
- if (no_pci_resources(ab)) {
- rc = get_pci_resources(ctrl, ab);
- if (rc) {
- err("pfar:cannot get pci resources of PCI 0x%x.\n",ctrl->pci_dev->subordinate->number);
- return -1;
- }
- }
-
- rc = bind_pci_resources(ctrl, ab);
- dbg("pfar:pre-Bind PCI 0x%x Ctrl Resource Dump\n", ctrl->pci_dev->subordinate->number);
- shpchprm_dump_ctrl_res(ctrl);
-
- bind_pci_resources_to_slots (ctrl);
-
- dbg("pfar:post-Bind PCI 0x%x Ctrl Resource Dump\n", ctrl->pci_dev->subordinate->number);
- shpchprm_dump_ctrl_res(ctrl);
-
- return rc;
-}
-
-int shpchprm_set_hpp(
- struct controller *ctrl,
- struct pci_func *func,
- u8 card_type
- )
-{
- struct acpi_bridge *ab;
- struct pci_bus lpci_bus, *pci_bus;
- int rc = 0;
- unsigned int devfn;
- u8 cls= 0x08; /* default cache line size */
- u8 lt = 0x40; /* default latency timer */
- u8 ep = 0;
- u8 es = 0;
-
- memcpy(&lpci_bus, ctrl->pci_bus, sizeof(lpci_bus));
- pci_bus = &lpci_bus;
- pci_bus->number = func->bus;
- devfn = PCI_DEVFN(func->device, func->function);
-
- ab = find_acpi_bridge_by_bus(acpi_bridges_head, ctrl->seg, ctrl->slot_bus);
-
- if (ab) {
- if (ab->_hpp) {
- lt = (u8)ab->_hpp->latency_timer;
- cls = (u8)ab->_hpp->cache_line_size;
- ep = (u8)ab->_hpp->enable_perr;
- es = (u8)ab->_hpp->enable_serr;
- } else
- dbg("_hpp: no _hpp for B/D/F=%#x/%#x/%#x. use default value\n", func->bus, func->device, func->function);
- } else
- dbg("_hpp: no acpi bridge for B/D/F = %#x/%#x/%#x. use default value\n", func->bus, func->device, func->function);
-
-
- if (card_type == PCI_HEADER_TYPE_BRIDGE) {
- /* set subordinate Latency Timer */
- rc |= pci_bus_write_config_byte(pci_bus, devfn, PCI_SEC_LATENCY_TIMER, lt);
- }
-
- /* set base Latency Timer */
- rc |= pci_bus_write_config_byte(pci_bus, devfn, PCI_LATENCY_TIMER, lt);
- dbg(" set latency timer =0x%02x: %x\n", lt, rc);
-
- rc |= pci_bus_write_config_byte(pci_bus, devfn, PCI_CACHE_LINE_SIZE, cls);
- dbg(" set cache_line_size=0x%02x: %x\n", cls, rc);
-
- return rc;
+ /*
+ * OSHP is an optional ACPI firmware control method. If present,
+ * we need to run it to inform BIOS that we will control SHPC
+ * hardware from now on.
+ */
+ acpi_handle handle = DEVICE_ACPI_HANDLE(&(dev->dev));
+ if (!handle)
+ return;
+ acpi_run_oshp(handle);
}
-void shpchprm_enable_card(
- struct controller *ctrl,
- struct pci_func *func,
- u8 card_type)
+void get_hp_params_from_firmware(struct pci_dev *dev,
+ struct hotplug_params *hpp)
{
- u16 command, cmd, bcommand, bcmd;
- struct pci_bus lpci_bus, *pci_bus;
- struct acpi_bridge *ab;
- unsigned int devfn;
- int rc;
-
- memcpy(&lpci_bus, ctrl->pci_bus, sizeof(lpci_bus));
- pci_bus = &lpci_bus;
- pci_bus->number = func->bus;
- devfn = PCI_DEVFN(func->device, func->function);
-
- rc = pci_bus_read_config_word(pci_bus, devfn, PCI_COMMAND, &command);
-
- if (card_type == PCI_HEADER_TYPE_BRIDGE) {
- rc = pci_bus_read_config_word(pci_bus, devfn, PCI_BRIDGE_CONTROL, &bcommand);
- }
+ acpi_status status = AE_NOT_FOUND;
+ struct pci_dev *pdev = dev;
- cmd = command = command | PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE
- | PCI_COMMAND_IO | PCI_COMMAND_MEMORY;
- bcmd = bcommand = bcommand | PCI_BRIDGE_CTL_NO_ISA;
-
- ab = find_acpi_bridge_by_bus(acpi_bridges_head, ctrl->seg, ctrl->slot_bus);
- if (ab) {
- if (ab->_hpp) {
- if (ab->_hpp->enable_perr) {
- command |= PCI_COMMAND_PARITY;
- bcommand |= PCI_BRIDGE_CTL_PARITY;
- } else {
- command &= ~PCI_COMMAND_PARITY;
- bcommand &= ~PCI_BRIDGE_CTL_PARITY;
- }
- if (ab->_hpp->enable_serr) {
- command |= PCI_COMMAND_SERR;
- bcommand |= PCI_BRIDGE_CTL_SERR;
- } else {
- command &= ~PCI_COMMAND_SERR;
- bcommand &= ~PCI_BRIDGE_CTL_SERR;
- }
- } else
- dbg("no _hpp for B/D/F = %#x/%#x/%#x.\n", func->bus, func->device, func->function);
- } else
- dbg("no acpi bridge for B/D/F = %#x/%#x/%#x.\n", func->bus, func->device, func->function);
-
- if (command != cmd) {
- rc = pci_bus_write_config_word(pci_bus, devfn, PCI_COMMAND, command);
- }
- if ((card_type == PCI_HEADER_TYPE_BRIDGE) && (bcommand != bcmd)) {
- rc = pci_bus_write_config_word(pci_bus, devfn, PCI_BRIDGE_CONTROL, bcommand);
+ /*
+ * _HPP settings apply to all child buses, until another _HPP is
+ * encountered. If we don't find an _HPP for the input pci dev,
+ * look for it in the parent device scope since that would apply to
+ * this pci dev. If we don't find any _HPP, use hardcoded defaults
+ */
+ while (pdev && (ACPI_FAILURE(status))) {
+ acpi_handle handle = DEVICE_ACPI_HANDLE(&(pdev->dev));
+ if (!handle)
+ break;
+ status = acpi_run_hpp(handle, hpp);
+ if (!(pdev->bus->parent))
+ break;
+ /* Check if a parent object supports _HPP */
+ pdev = pdev->bus->parent->self;
}
}
diff --git a/drivers/pci/hotplug/shpchprm_legacy.c b/drivers/pci/hotplug/shpchprm_legacy.c
index ba6c549c9b9d..ed6c1254bf6f 100644
--- a/drivers/pci/hotplug/shpchprm_legacy.c
+++ b/drivers/pci/hotplug/shpchprm_legacy.c
@@ -27,33 +27,11 @@
*
*/
-#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/pci.h>
-#include <linux/init.h>
-#include <asm/uaccess.h>
-#ifdef CONFIG_IA64
-#include <asm/iosapic.h>
-#endif
#include "shpchp.h"
-#include "shpchprm.h"
-#include "shpchprm_legacy.h"
-
-static void __iomem *shpchp_rom_start;
-static u16 unused_IRQ;
-
-void shpchprm_cleanup(void)
-{
- if (shpchp_rom_start)
- iounmap(shpchp_rom_start);
-}
-
-int shpchprm_print_pirt(void)
-{
- return 0;
-}
int shpchprm_get_physical_slot_number(struct controller *ctrl, u32 *sun, u8 busnum, u8 devnum)
{
@@ -63,377 +41,14 @@ int shpchprm_get_physical_slot_number(struct controller *ctrl, u32 *sun, u8 busn
return 0;
}
-/* Find the Hot Plug Resource Table in the specified region of memory */
-static void __iomem *detect_HRT_floating_pointer(void __iomem *begin, void __iomem *end)
+void get_hp_params_from_firmware(struct pci_dev *dev,
+ struct hotplug_params *hpp)
{
- void __iomem *fp;
- void __iomem *endp;
- u8 temp1, temp2, temp3, temp4;
- int status = 0;
-
- endp = (end - sizeof(struct hrt) + 1);
-
- for (fp = begin; fp <= endp; fp += 16) {
- temp1 = readb(fp + SIG0);
- temp2 = readb(fp + SIG1);
- temp3 = readb(fp + SIG2);
- temp4 = readb(fp + SIG3);
- if (temp1 == '$' && temp2 == 'H' && temp3 == 'R' && temp4 == 'T') {
- status = 1;
- break;
- }
- }
-
- if (!status)
- fp = NULL;
-
- dbg("Discovered Hotplug Resource Table at %p\n", fp);
- return fp;
+ return;
}
-/*
- * shpchprm_find_available_resources
- *
- * Finds available memory, IO, and IRQ resources for programming
- * devices which may be added to the system
- * this function is for hot plug ADD!
- *
- * returns 0 if success
- */
-int shpchprm_find_available_resources(struct controller *ctrl)
+void get_hp_hw_control_from_firmware(struct pci_dev *dev)
{
- u8 populated_slot;
- u8 bridged_slot;
- void __iomem *one_slot;
- struct pci_func *func = NULL;
- int i = 10, index = 0;
- u32 temp_dword, rc;
- ulong temp_ulong;
- struct pci_resource *mem_node;
- struct pci_resource *p_mem_node;
- struct pci_resource *io_node;
- struct pci_resource *bus_node;
- void __iomem *rom_resource_table;
- struct pci_bus lpci_bus, *pci_bus;
- u8 cfgspc_irq, temp;
-
- memcpy(&lpci_bus, ctrl->pci_bus, sizeof(lpci_bus));
- pci_bus = &lpci_bus;
- rom_resource_table = detect_HRT_floating_pointer(shpchp_rom_start, shpchp_rom_start + 0xffff);
- dbg("rom_resource_table = %p\n", rom_resource_table);
- if (rom_resource_table == NULL)
- return -ENODEV;
-
- /* Sum all resources and setup resource maps */
- unused_IRQ = readl(rom_resource_table + UNUSED_IRQ);
- dbg("unused_IRQ = %x\n", unused_IRQ);
-
- temp = 0;
- while (unused_IRQ) {
- if (unused_IRQ & 1) {
- shpchp_disk_irq = temp;
- break;
- }
- unused_IRQ = unused_IRQ >> 1;
- temp++;
- }
-
- dbg("shpchp_disk_irq= %d\n", shpchp_disk_irq);
- unused_IRQ = unused_IRQ >> 1;
- temp++;
-
- while (unused_IRQ) {
- if (unused_IRQ & 1) {
- shpchp_nic_irq = temp;
- break;
- }
- unused_IRQ = unused_IRQ >> 1;
- temp++;
- }
-
- dbg("shpchp_nic_irq= %d\n", shpchp_nic_irq);
- unused_IRQ = readl(rom_resource_table + PCIIRQ);
-
- temp = 0;
-
- pci_read_config_byte(ctrl->pci_dev, PCI_INTERRUPT_LINE, &cfgspc_irq);
-
- if (!shpchp_nic_irq) {
- shpchp_nic_irq = cfgspc_irq;
- }
-
- if (!shpchp_disk_irq) {
- shpchp_disk_irq = cfgspc_irq;
- }
-
- dbg("shpchp_disk_irq, shpchp_nic_irq= %d, %d\n", shpchp_disk_irq, shpchp_nic_irq);
-
- one_slot = rom_resource_table + sizeof(struct hrt);
-
- i = readb(rom_resource_table + NUMBER_OF_ENTRIES);
- dbg("number_of_entries = %d\n", i);
-
- if (!readb(one_slot + SECONDARY_BUS))
- return (1);
-
- dbg("dev|IO base|length|MEMbase|length|PM base|length|PB SB MB\n");
-
- while (i && readb(one_slot + SECONDARY_BUS)) {
- u8 dev_func = readb(one_slot + DEV_FUNC);
- u8 primary_bus = readb(one_slot + PRIMARY_BUS);
- u8 secondary_bus = readb(one_slot + SECONDARY_BUS);
- u8 max_bus = readb(one_slot + MAX_BUS);
- u16 io_base = readw(one_slot + IO_BASE);
- u16 io_length = readw(one_slot + IO_LENGTH);
- u16 mem_base = readw(one_slot + MEM_BASE);
- u16 mem_length = readw(one_slot + MEM_LENGTH);
- u16 pre_mem_base = readw(one_slot + PRE_MEM_BASE);
- u16 pre_mem_length = readw(one_slot + PRE_MEM_LENGTH);
-
- dbg("%2.2x | %4.4x | %4.4x | %4.4x | %4.4x | %4.4x | %4.4x |%2.2x %2.2x %2.2x\n",
- 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 (primary_bus != ctrl->slot_bus) {
- i--;
- one_slot += sizeof(struct slot_rt);
- continue;
- }
- /* find out if this entry is for an occupied slot */
- temp_dword = 0xFFFFFFFF;
- pci_bus->number = primary_bus;
- pci_bus_read_config_dword(pci_bus, dev_func, PCI_VENDOR_ID, &temp_dword);
-
- dbg("temp_D_word = %x\n", temp_dword);
-
- if (temp_dword != 0xFFFFFFFF) {
- index = 0;
- func = shpchp_slot_find(primary_bus, dev_func >> 3, 0);
-
- while (func && (func->function != (dev_func & 0x07))) {
- dbg("func = %p b:d:f(%x:%x:%x)\n", func, primary_bus, dev_func >> 3, index);
- func = shpchp_slot_find(primary_bus, dev_func >> 3, index++);
- }
-
- /* 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 */
- if (secondary_bus != primary_bus)
- bridged_slot = 1;
- else
- bridged_slot = 0;
-
- populated_slot = 1;
- } else {
- populated_slot = 0;
- bridged_slot = 0;
- }
- dbg("slot populated =%s \n", populated_slot?"yes":"no");
-
- /* If we've got a valid IO base, use it */
-
- temp_ulong = io_base + io_length;
-
- if ((io_base) && (temp_ulong <= 0x10000)) {
- io_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
- if (!io_node)
- return -ENOMEM;
-
- io_node->base = (ulong)io_base;
- io_node->length = (ulong)io_length;
- dbg("found io_node(base, length) = %x, %x\n", io_node->base, io_node->length);
-
- if (!populated_slot) {
- io_node->next = ctrl->io_head;
- ctrl->io_head = io_node;
- } else {
- io_node->next = func->io_head;
- func->io_head = io_node;
- }
- }
-
- /* If we've got a valid memory base, use it */
- temp_ulong = mem_base + mem_length;
- if ((mem_base) && (temp_ulong <= 0x10000)) {
- mem_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
- if (!mem_node)
- return -ENOMEM;
-
- mem_node->base = (ulong)mem_base << 16;
- mem_node->length = (ulong)(mem_length << 16);
- dbg("found mem_node(base, length) = %x, %x\n", mem_node->base, mem_node->length);
-
- if (!populated_slot) {
- mem_node->next = ctrl->mem_head;
- ctrl->mem_head = mem_node;
- } else {
- mem_node->next = func->mem_head;
- func->mem_head = mem_node;
- }
- }
-
- /*
- * If we've got a valid prefetchable memory base, and
- * the base + length isn't greater than 0xFFFF
- */
- temp_ulong = pre_mem_base + pre_mem_length;
- if ((pre_mem_base) && (temp_ulong <= 0x10000)) {
- p_mem_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
- if (!p_mem_node)
- return -ENOMEM;
-
- p_mem_node->base = (ulong)pre_mem_base << 16;
- p_mem_node->length = (ulong)pre_mem_length << 16;
- dbg("found p_mem_node(base, length) = %x, %x\n", p_mem_node->base, p_mem_node->length);
-
- if (!populated_slot) {
- p_mem_node->next = ctrl->p_mem_head;
- ctrl->p_mem_head = p_mem_node;
- } else {
- p_mem_node->next = func->p_mem_head;
- func->p_mem_head = p_mem_node;
- }
- }
-
- /*
- * 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 = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
- if (!bus_node)
- return -ENOMEM;
-
- bus_node->base = (ulong)secondary_bus;
- bus_node->length = (ulong)(max_bus - secondary_bus + 1);
- dbg("found bus_node(base, length) = %x, %x\n", bus_node->base, bus_node->length);
-
- if (!populated_slot) {
- bus_node->next = ctrl->bus_head;
- ctrl->bus_head = bus_node;
- } else {
- bus_node->next = func->bus_head;
- func->bus_head = bus_node;
- }
- }
-
- i--;
- one_slot += sizeof(struct slot_rt);
- }
-
- /* If all of the following fail, we don't have any resources for hot plug add */
- rc = 1;
- rc &= shpchp_resource_sort_and_combine(&(ctrl->mem_head));
- rc &= shpchp_resource_sort_and_combine(&(ctrl->p_mem_head));
- rc &= shpchp_resource_sort_and_combine(&(ctrl->io_head));
- rc &= shpchp_resource_sort_and_combine(&(ctrl->bus_head));
-
- return (rc);
+ return;
}
-int shpchprm_set_hpp(
- struct controller *ctrl,
- struct pci_func *func,
- u8 card_type)
-{
- u32 rc;
- u8 temp_byte;
- struct pci_bus lpci_bus, *pci_bus;
- unsigned int devfn;
- memcpy(&lpci_bus, ctrl->pci_bus, sizeof(lpci_bus));
- pci_bus = &lpci_bus;
- pci_bus->number = func->bus;
- devfn = PCI_DEVFN(func->device, func->function);
-
- temp_byte = 0x40; /* hard coded value for LT */
- if (card_type == PCI_HEADER_TYPE_BRIDGE) {
- /* set subordinate Latency Timer */
- rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_SEC_LATENCY_TIMER, temp_byte);
- if (rc) {
- dbg("%s: set secondary LT error. b:d:f(%02x:%02x:%02x)\n", __FUNCTION__, func->bus,
- func->device, func->function);
- return rc;
- }
- }
-
- /* set base Latency Timer */
- rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_LATENCY_TIMER, temp_byte);
- if (rc) {
- dbg("%s: set LT error. b:d:f(%02x:%02x:%02x)\n", __FUNCTION__, func->bus, func->device, func->function);
- return rc;
- }
-
- /* set Cache Line size */
- temp_byte = 0x08; /* hard coded value for CLS */
- rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_CACHE_LINE_SIZE, temp_byte);
- if (rc) {
- dbg("%s: set CLS error. b:d:f(%02x:%02x:%02x)\n", __FUNCTION__, func->bus, func->device, func->function);
- }
-
- /* set enable_perr */
- /* set enable_serr */
-
- return rc;
-}
-
-void shpchprm_enable_card(
- struct controller *ctrl,
- struct pci_func *func,
- u8 card_type)
-{
- u16 command, bcommand;
- struct pci_bus lpci_bus, *pci_bus;
- unsigned int devfn;
- int rc;
-
- memcpy(&lpci_bus, ctrl->pci_bus, sizeof(lpci_bus));
- pci_bus = &lpci_bus;
- pci_bus->number = func->bus;
- devfn = PCI_DEVFN(func->device, func->function);
-
- rc = pci_bus_read_config_word(pci_bus, devfn, PCI_COMMAND, &command);
- command |= PCI_COMMAND_PARITY | PCI_COMMAND_SERR
- | PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE
- | PCI_COMMAND_IO | PCI_COMMAND_MEMORY;
- rc = pci_bus_write_config_word(pci_bus, devfn, PCI_COMMAND, command);
-
- if (card_type == PCI_HEADER_TYPE_BRIDGE) {
- rc = pci_bus_read_config_word(pci_bus, devfn, PCI_BRIDGE_CONTROL, &bcommand);
- bcommand |= PCI_BRIDGE_CTL_PARITY | PCI_BRIDGE_CTL_SERR
- | PCI_BRIDGE_CTL_NO_ISA;
- rc = pci_bus_write_config_word(pci_bus, devfn, PCI_BRIDGE_CONTROL, bcommand);
- }
-}
-
-static int legacy_shpchprm_init_pci(void)
-{
- shpchp_rom_start = ioremap(ROM_PHY_ADDR, ROM_PHY_LEN);
- if (!shpchp_rom_start) {
- err("Could not ioremap memory region for ROM\n");
- return -EIO;
- }
-
- return 0;
-}
-
-int shpchprm_init(enum php_ctlr_type ctrl_type)
-{
- int retval;
-
- switch (ctrl_type) {
- case PCI:
- retval = legacy_shpchprm_init_pci();
- break;
- default:
- retval = -ENODEV;
- break;
- }
-
- return retval;
-}
diff --git a/drivers/pci/hotplug/shpchprm_legacy.h b/drivers/pci/hotplug/shpchprm_legacy.h
deleted file mode 100644
index 21bda74ddfa5..000000000000
--- a/drivers/pci/hotplug/shpchprm_legacy.h
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * SHPCHPRM Legacy: PHP Resource Manager for Non-ACPI/Legacy platform using HRT
- *
- * Copyright (C) 1995,2001 Compaq Computer Corporation
- * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
- * Copyright (C) 2001 IBM Corp.
- * Copyright (C) 2003-2004 Intel Corporation
- *
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
- * NON INFRINGEMENT. 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.
- *
- * Send feedback to <greg@kroah.com>, <kristen.c.accardi@intel.com>
- *
- */
-
-#ifndef _SHPCHPRM_LEGACY_H_
-#define _SHPCHPRM_LEGACY_H_
-
-#define ROM_PHY_ADDR 0x0F0000
-#define ROM_PHY_LEN 0x00FFFF
-
-struct slot_rt {
- u8 dev_func;
- u8 primary_bus;
- u8 secondary_bus;
- u8 max_bus;
- u16 io_base;
- u16 io_length;
- u16 mem_base;
- u16 mem_length;
- u16 pre_mem_base;
- u16 pre_mem_length;
-} __attribute__ ((packed));
-
-/* 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),
-};
-
-struct hrt {
- char sig0;
- char sig1;
- char sig2;
- char sig3;
- u16 unused_IRQ;
- u16 PCIIRQ;
- u8 number_of_entries;
- u8 revision;
- u16 reserved1;
- u32 reserved2;
-} __attribute__ ((packed));
-
-/* 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),
- SIG2 = offsetof(struct hrt, sig2),
- SIG3 = offsetof(struct hrt, sig3),
- UNUSED_IRQ = offsetof(struct hrt, unused_IRQ),
- PCIIRQ = offsetof(struct hrt, PCIIRQ),
- NUMBER_OF_ENTRIES = offsetof(struct hrt, number_of_entries),
- REVISION = offsetof(struct hrt, revision),
- HRT_RESERVED1 = offsetof(struct hrt, reserved1),
- HRT_RESERVED2 = offsetof(struct hrt, reserved2),
-};
-
-struct irq_info {
- u8 bus, devfn; /* bus, device and function */
- struct {
- u8 link; /* IRQ line ID, chipset dependent, 0=not routed */
- u16 bitmap; /* Available IRQs */
- } __attribute__ ((packed)) irq[4];
- u8 slot; /* slot number, 0=onboard */
- u8 rfu;
-} __attribute__ ((packed));
-
-struct irq_routing_table {
- u32 signature; /* PIRQ_SIGNATURE should be here */
- u16 version; /* PIRQ_VERSION */
- u16 size; /* Table size in bytes */
- u8 rtr_bus, rtr_devfn; /* Where the interrupt router lies */
- u16 exclusive_irqs; /* IRQs devoted exclusively to PCI usage */
- u16 rtr_vendor, rtr_device; /* Vendor and device ID of interrupt router */
- u32 miniport_data; /* Crap */
- u8 rfu[11];
- u8 checksum; /* Modulo 256 checksum must give zero */
- struct irq_info slots[0];
-} __attribute__ ((packed));
-
-#endif /* _SHPCHPRM_LEGACY_H_ */
diff --git a/drivers/pci/hotplug/shpchprm_nonacpi.c b/drivers/pci/hotplug/shpchprm_nonacpi.c
index 5f75ef7f3df2..c6b40998eeb3 100644
--- a/drivers/pci/hotplug/shpchprm_nonacpi.c
+++ b/drivers/pci/hotplug/shpchprm_nonacpi.c
@@ -32,24 +32,9 @@
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/pci.h>
-#include <linux/init.h>
-#include <asm/uaccess.h>
-#ifdef CONFIG_IA64
-#include <asm/iosapic.h>
-#endif
-#include "shpchp.h"
-#include "shpchprm.h"
-#include "shpchprm_nonacpi.h"
+#include <linux/slab.h>
-void shpchprm_cleanup(void)
-{
- return;
-}
-
-int shpchprm_print_pirt(void)
-{
- return 0;
-}
+#include "shpchp.h"
int shpchprm_get_physical_slot_number(struct controller *ctrl, u32 *sun, u8 busnum, u8 devnum)
{
@@ -60,375 +45,13 @@ int shpchprm_get_physical_slot_number(struct controller *ctrl, u32 *sun, u8 busn
return 0;
}
-static void print_pci_resource ( struct pci_resource *aprh)
-{
- struct pci_resource *res;
-
- for (res = aprh; res; res = res->next)
- dbg(" base= 0x%x length= 0x%x\n", res->base, res->length);
-}
-
-
-static void phprm_dump_func_res( struct pci_func *fun)
-{
- struct pci_func *func = fun;
-
- if (func->bus_head) {
- dbg(": BUS Resources:\n");
- print_pci_resource (func->bus_head);
- }
- if (func->io_head) {
- dbg(": IO Resources:\n");
- print_pci_resource (func->io_head);
- }
- if (func->mem_head) {
- dbg(": MEM Resources:\n");
- print_pci_resource (func->mem_head);
- }
- if (func->p_mem_head) {
- dbg(": PMEM Resources:\n");
- print_pci_resource (func->p_mem_head);
- }
-}
-
-static int phprm_get_used_resources (
- struct controller *ctrl,
- struct pci_func *func
- )
-{
- return shpchp_save_used_resources (ctrl, func, !DISABLE_CARD);
-}
-
-static int phprm_delete_resource(
- struct pci_resource **aprh,
- ulong base,
- ulong size)
-{
- struct pci_resource *res;
- struct pci_resource *prevnode;
- struct pci_resource *split_node;
- ulong tbase;
-
- shpchp_resource_sort_and_combine(aprh);
-
- for (res = *aprh; res; res = res->next) {
- if (res->base > base)
- continue;
-
- if ((res->base + res->length) < (base + size))
- continue;
-
- if (res->base < base) {
- tbase = base;
-
- if ((res->length - (tbase - res->base)) < size)
- continue;
-
- split_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
- if (!split_node)
- return -ENOMEM;
-
- split_node->base = res->base;
- split_node->length = tbase - res->base;
- res->base = tbase;
- res->length -= split_node->length;
-
- split_node->next = res->next;
- res->next = split_node;
- }
-
- if (res->length >= size) {
- split_node = (struct pci_resource*) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
- if (!split_node)
- return -ENOMEM;
-
- split_node->base = res->base + size;
- split_node->length = res->length - size;
- res->length = size;
-
- split_node->next = res->next;
- res->next = split_node;
- }
-
- if (*aprh == res) {
- *aprh = res->next;
- } else {
- prevnode = *aprh;
- while (prevnode->next != res)
- prevnode = prevnode->next;
-
- prevnode->next = res->next;
- }
- res->next = NULL;
- kfree(res);
- break;
- }
-
- return 0;
-}
-
-
-static int phprm_delete_resources(
- struct pci_resource **aprh,
- struct pci_resource *this
- )
-{
- struct pci_resource *res;
-
- for (res = this; res; res = res->next)
- phprm_delete_resource(aprh, res->base, res->length);
-
- return 0;
-}
-
-
-static int configure_existing_function(
- struct controller *ctrl,
- struct pci_func *func
- )
-{
- int rc;
-
- /* see how much resources the func has used. */
- rc = phprm_get_used_resources (ctrl, func);
-
- if (!rc) {
- /* subtract the resources used by the func from ctrl resources */
- rc = phprm_delete_resources (&ctrl->bus_head, func->bus_head);
- rc |= phprm_delete_resources (&ctrl->io_head, func->io_head);
- rc |= phprm_delete_resources (&ctrl->mem_head, func->mem_head);
- rc |= phprm_delete_resources (&ctrl->p_mem_head, func->p_mem_head);
- if (rc)
- warn("aCEF: cannot del used resources\n");
- } else
- err("aCEF: cannot get used resources\n");
-
- return rc;
-}
-
-static int bind_pci_resources_to_slots ( struct controller *ctrl)
-{
- struct pci_func *func, new_func;
- int busn = ctrl->slot_bus;
- int devn, funn;
- u32 vid;
-
- for (devn = 0; devn < 32; devn++) {
- for (funn = 0; funn < 8; funn++) {
- /*
- if (devn == ctrl->device && funn == ctrl->function)
- continue;
- */
- /* find out if this entry is for an occupied slot */
- vid = 0xFFFFFFFF;
-
- pci_bus_read_config_dword(ctrl->pci_dev->subordinate, PCI_DEVFN(devn, funn), PCI_VENDOR_ID, &vid);
-
- if (vid != 0xFFFFFFFF) {
- func = shpchp_slot_find(busn, devn, funn);
- if (!func) {
- memset(&new_func, 0, sizeof(struct pci_func));
- new_func.bus = busn;
- new_func.device = devn;
- new_func.function = funn;
- new_func.is_a_board = 1;
- configure_existing_function(ctrl, &new_func);
- phprm_dump_func_res(&new_func);
- } else {
- configure_existing_function(ctrl, func);
- phprm_dump_func_res(func);
- }
- dbg("aCCF:existing PCI 0x%x Func ResourceDump\n", ctrl->bus);
- }
- }
- }
-
- return 0;
-}
-
-static void phprm_dump_ctrl_res( struct controller *ctlr)
-{
- struct controller *ctrl = ctlr;
-
- if (ctrl->bus_head) {
- dbg(": BUS Resources:\n");
- print_pci_resource (ctrl->bus_head);
- }
- if (ctrl->io_head) {
- dbg(": IO Resources:\n");
- print_pci_resource (ctrl->io_head);
- }
- if (ctrl->mem_head) {
- dbg(": MEM Resources:\n");
- print_pci_resource (ctrl->mem_head);
- }
- if (ctrl->p_mem_head) {
- dbg(": PMEM Resources:\n");
- print_pci_resource (ctrl->p_mem_head);
- }
-}
-
-/*
- * phprm_find_available_resources
- *
- * Finds available memory, IO, and IRQ resources for programming
- * devices which may be added to the system
- * this function is for hot plug ADD!
- *
- * returns 0 if success
- */
-int shpchprm_find_available_resources(struct controller *ctrl)
-{
- struct pci_func func;
- u32 rc;
-
- memset(&func, 0, sizeof(struct pci_func));
-
- func.bus = ctrl->bus;
- func.device = ctrl->device;
- func.function = ctrl->function;
- func.is_a_board = 1;
-
- /* Get resources for this PCI bridge */
- rc = shpchp_save_used_resources (ctrl, &func, !DISABLE_CARD);
- dbg("%s: shpchp_save_used_resources rc = %d\n", __FUNCTION__, rc);
-
- if (func.mem_head)
- func.mem_head->next = ctrl->mem_head;
- ctrl->mem_head = func.mem_head;
-
- if (func.p_mem_head)
- func.p_mem_head->next = ctrl->p_mem_head;
- ctrl->p_mem_head = func.p_mem_head;
-
- if (func.io_head)
- func.io_head->next = ctrl->io_head;
- ctrl->io_head = func.io_head;
-
- if(func.bus_head)
- func.bus_head->next = ctrl->bus_head;
- ctrl->bus_head = func.bus_head;
- if (ctrl->bus_head)
- phprm_delete_resource(&ctrl->bus_head, ctrl->pci_dev->subordinate->number, 1);
-
- dbg("%s:pre-Bind PCI 0x%x Ctrl Resource Dump\n", __FUNCTION__, ctrl->bus);
- phprm_dump_ctrl_res(ctrl);
- bind_pci_resources_to_slots (ctrl);
-
- dbg("%s:post-Bind PCI 0x%x Ctrl Resource Dump\n", __FUNCTION__, ctrl->bus);
- phprm_dump_ctrl_res(ctrl);
-
-
- /* If all of the following fail, we don't have any resources for hot plug add */
- rc = 1;
- rc &= shpchp_resource_sort_and_combine(&(ctrl->mem_head));
- rc &= shpchp_resource_sort_and_combine(&(ctrl->p_mem_head));
- rc &= shpchp_resource_sort_and_combine(&(ctrl->io_head));
- rc &= shpchp_resource_sort_and_combine(&(ctrl->bus_head));
-
- return (rc);
-}
-
-int shpchprm_set_hpp(
- struct controller *ctrl,
- struct pci_func *func,
- u8 card_type)
+void get_hp_params_from_firmware(struct pci_dev *dev,
+ struct hotplug_params *hpp)
{
- u32 rc;
- u8 temp_byte;
- struct pci_bus lpci_bus, *pci_bus;
- unsigned int devfn;
- memcpy(&lpci_bus, ctrl->pci_bus, sizeof(lpci_bus));
- pci_bus = &lpci_bus;
- pci_bus->number = func->bus;
- devfn = PCI_DEVFN(func->device, func->function);
-
- temp_byte = 0x40; /* hard coded value for LT */
- if (card_type == PCI_HEADER_TYPE_BRIDGE) {
- /* set subordinate Latency Timer */
- rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_SEC_LATENCY_TIMER, temp_byte);
-
- if (rc) {
- dbg("%s: set secondary LT error. b:d:f(%02x:%02x:%02x)\n", __FUNCTION__, func->bus,
- func->device, func->function);
- return rc;
- }
- }
-
- /* set base Latency Timer */
- rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_LATENCY_TIMER, temp_byte);
-
- if (rc) {
- dbg("%s: set LT error. b:d:f(%02x:%02x:%02x)\n", __FUNCTION__, func->bus, func->device, func->function);
- return rc;
- }
-
- /* set Cache Line size */
- temp_byte = 0x08; /* hard coded value for CLS */
-
- rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_CACHE_LINE_SIZE, temp_byte);
-
- if (rc) {
- dbg("%s: set CLS error. b:d:f(%02x:%02x:%02x)\n", __FUNCTION__, func->bus, func->device, func->function);
- }
-
- /* set enable_perr */
- /* set enable_serr */
-
- return rc;
-}
-
-void shpchprm_enable_card(
- struct controller *ctrl,
- struct pci_func *func,
- u8 card_type)
-{
- u16 command, bcommand;
- struct pci_bus lpci_bus, *pci_bus;
- unsigned int devfn;
- int rc;
-
- memcpy(&lpci_bus, ctrl->pci_bus, sizeof(lpci_bus));
- pci_bus = &lpci_bus;
- pci_bus->number = func->bus;
- devfn = PCI_DEVFN(func->device, func->function);
-
- rc = pci_bus_read_config_word(pci_bus, devfn, PCI_COMMAND, &command);
-
- command |= PCI_COMMAND_PARITY | PCI_COMMAND_SERR
- | PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE
- | PCI_COMMAND_IO | PCI_COMMAND_MEMORY;
-
- rc = pci_bus_write_config_word(pci_bus, devfn, PCI_COMMAND, command);
-
- if (card_type == PCI_HEADER_TYPE_BRIDGE) {
-
- rc = pci_bus_read_config_word(pci_bus, devfn, PCI_BRIDGE_CONTROL, &bcommand);
-
- bcommand |= PCI_BRIDGE_CTL_PARITY | PCI_BRIDGE_CTL_SERR
- | PCI_BRIDGE_CTL_NO_ISA;
-
- rc = pci_bus_write_config_word(pci_bus, devfn, PCI_BRIDGE_CONTROL, bcommand);
- }
-}
-
-static int legacy_shpchprm_init_pci(void)
-{
- return 0;
+ return;
}
-int shpchprm_init(enum php_ctlr_type ctrl_type)
+void get_hp_hw_control_from_firmware(struct pci_dev *dev)
{
- int retval;
-
- switch (ctrl_type) {
- case PCI:
- retval = legacy_shpchprm_init_pci();
- break;
- default:
- retval = -ENODEV;
- break;
- }
-
- return retval;
+ return;
}
diff --git a/drivers/pci/hotplug/shpchprm_nonacpi.h b/drivers/pci/hotplug/shpchprm_nonacpi.h
deleted file mode 100644
index cddaaa5ee1b3..000000000000
--- a/drivers/pci/hotplug/shpchprm_nonacpi.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * SHPCHPRM NONACPI: PHP Resource Manager for Non-ACPI/Legacy platform
- *
- * Copyright (C) 1995,2001 Compaq Computer Corporation
- * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
- * Copyright (C) 2001 IBM Corp.
- * Copyright (C) 2003-2004 Intel Corporation
- *
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
- * NON INFRINGEMENT. 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.
- *
- * Send feedback to <greg@kroah.com>, <kristen.c.accardi@intel.com>
- *
- */
-
-#ifndef _SHPCHPRM_NONACPI_H_
-#define _SHPCHPRM_NONACPI_H_
-
-struct irq_info {
- u8 bus, devfn; /* bus, device and function */
- struct {
- u8 link; /* IRQ line ID, chipset dependent, 0=not routed */
- u16 bitmap; /* Available IRQs */
- } __attribute__ ((packed)) irq[4];
- u8 slot; /* slot number, 0=onboard */
- u8 rfu;
-} __attribute__ ((packed));
-
-struct irq_routing_table {
- u32 signature; /* PIRQ_SIGNATURE should be here */
- u16 version; /* PIRQ_VERSION */
- u16 size; /* Table size in bytes */
- u8 rtr_bus, rtr_devfn; /* Where the interrupt router lies */
- u16 exclusive_irqs; /* IRQs devoted exclusively to PCI usage */
- u16 rtr_vendor, rtr_device; /* Vendor and device ID of interrupt router */
- u32 miniport_data; /* Crap */
- u8 rfu[11];
- u8 checksum; /* Modulo 256 checksum must give zero */
- struct irq_info slots[0];
-} __attribute__ ((packed));
-
-#endif /* _SHPCHPRM_NONACPI_H_ */
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index ee8677bda950..202b7507a357 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -23,6 +23,8 @@
#include "pci.h"
#include "msi.h"
+#define MSI_TARGET_CPU first_cpu(cpu_online_map)
+
static DEFINE_SPINLOCK(msi_lock);
static struct msi_desc* msi_desc[NR_IRQS] = { [0 ... NR_IRQS-1] = NULL };
static kmem_cache_t* msi_cachep;
@@ -92,6 +94,7 @@ static void set_msi_affinity(unsigned int vector, cpumask_t cpu_mask)
struct msi_desc *entry;
struct msg_address address;
unsigned int irq = vector;
+ unsigned int dest_cpu = first_cpu(cpu_mask);
entry = (struct msi_desc *)msi_desc[vector];
if (!entry || !entry->dev)
@@ -108,9 +111,9 @@ static void set_msi_affinity(unsigned int vector, cpumask_t cpu_mask)
pci_read_config_dword(entry->dev, msi_lower_address_reg(pos),
&address.lo_address.value);
address.lo_address.value &= MSI_ADDRESS_DEST_ID_MASK;
- address.lo_address.value |= (cpu_mask_to_apicid(cpu_mask) <<
- MSI_TARGET_CPU_SHIFT);
- entry->msi_attrib.current_cpu = cpu_mask_to_apicid(cpu_mask);
+ address.lo_address.value |= (cpu_physical_id(dest_cpu) <<
+ MSI_TARGET_CPU_SHIFT);
+ entry->msi_attrib.current_cpu = cpu_physical_id(dest_cpu);
pci_write_config_dword(entry->dev, msi_lower_address_reg(pos),
address.lo_address.value);
set_native_irq_info(irq, cpu_mask);
@@ -123,9 +126,9 @@ static void set_msi_affinity(unsigned int vector, cpumask_t cpu_mask)
address.lo_address.value = readl(entry->mask_base + offset);
address.lo_address.value &= MSI_ADDRESS_DEST_ID_MASK;
- address.lo_address.value |= (cpu_mask_to_apicid(cpu_mask) <<
- MSI_TARGET_CPU_SHIFT);
- entry->msi_attrib.current_cpu = cpu_mask_to_apicid(cpu_mask);
+ address.lo_address.value |= (cpu_physical_id(dest_cpu) <<
+ MSI_TARGET_CPU_SHIFT);
+ entry->msi_attrib.current_cpu = cpu_physical_id(dest_cpu);
writel(address.lo_address.value, entry->mask_base + offset);
set_native_irq_info(irq, cpu_mask);
break;
@@ -259,14 +262,15 @@ static void msi_data_init(struct msg_data *msi_data,
static void msi_address_init(struct msg_address *msi_address)
{
unsigned int dest_id;
+ unsigned long dest_phys_id = cpu_physical_id(MSI_TARGET_CPU);
memset(msi_address, 0, sizeof(struct msg_address));
msi_address->hi_address = (u32)0;
dest_id = (MSI_ADDRESS_HEADER << MSI_ADDRESS_HEADER_SHIFT);
- msi_address->lo_address.u.dest_mode = MSI_DEST_MODE;
+ msi_address->lo_address.u.dest_mode = MSI_PHYSICAL_MODE;
msi_address->lo_address.u.redirection_hint = MSI_REDIRECTION_HINT_MODE;
msi_address->lo_address.u.dest_id = dest_id;
- msi_address->lo_address.value |= (MSI_TARGET_CPU << MSI_TARGET_CPU_SHIFT);
+ msi_address->lo_address.value |= (dest_phys_id << MSI_TARGET_CPU_SHIFT);
}
static int msi_free_vector(struct pci_dev* dev, int vector, int reassign);
@@ -575,6 +579,8 @@ static int msi_capability_init(struct pci_dev *dev)
/**
* msix_capability_init - configure device's MSI-X capability
* @dev: pointer to the pci_dev data structure of MSI-X device function
+ * @entries: pointer to an array of struct msix_entry entries
+ * @nvec: number of @entries
*
* Setup the MSI-X capability structure of device function with a
* single MSI-X vector. A return of zero indicates the successful setup of
diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c
index e9e37abe1f76..a9b00cc2d885 100644
--- a/drivers/pci/pci-acpi.c
+++ b/drivers/pci/pci-acpi.c
@@ -91,9 +91,7 @@ acpi_query_osc (
static acpi_status
acpi_run_osc (
acpi_handle handle,
- u32 level,
- void *context,
- void **retval )
+ void *context)
{
acpi_status status;
struct acpi_object_list input;
@@ -184,7 +182,7 @@ EXPORT_SYMBOL(pci_osc_support_set);
*
* Attempt to take control from Firmware on requested control bits.
**/
-acpi_status pci_osc_control_set(u32 flags)
+acpi_status pci_osc_control_set(acpi_handle handle, u32 flags)
{
acpi_status status;
u32 ctrlset;
@@ -198,10 +196,7 @@ acpi_status pci_osc_control_set(u32 flags)
return AE_SUPPORT;
}
ctrlset_buf[OSC_CONTROL_TYPE] |= ctrlset;
- status = acpi_get_devices ( PCI_ROOT_HID_STRING,
- acpi_run_osc,
- ctrlset_buf,
- NULL );
+ status = acpi_run_osc(handle, ctrlset_buf);
if (ACPI_FAILURE (status)) {
ctrlset_buf[OSC_CONTROL_TYPE] &= ~ctrlset;
}
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index 0d0d533894e0..a9046d4b8af3 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -8,6 +8,9 @@
#include <linux/init.h>
#include <linux/device.h>
#include <linux/mempolicy.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/sched.h>
#include "pci.h"
/*
@@ -26,12 +29,15 @@ struct pci_dynid {
#ifdef CONFIG_HOTPLUG
/**
- * store_new_id
+ * store_new_id - add a new PCI device ID to this driver and re-probe devices
+ * @driver: target device driver
+ * @buf: buffer for scanning device ID data
+ * @count: input size
*
* Adds a new dynamic pci device ID to this driver,
* and causes the driver to probe for all devices again.
*/
-static inline ssize_t
+static ssize_t
store_new_id(struct device_driver *driver, const char *buf, size_t count)
{
struct pci_dynid *dynid;
@@ -194,8 +200,10 @@ static int pci_call_probe(struct pci_driver *drv, struct pci_dev *dev,
/**
* __pci_device_probe()
+ * @drv: driver to call to check if it wants the PCI device
+ * @pci_dev: PCI device being probed
*
- * returns 0 on success, else error.
+ * returns 0 on success, else error.
* side-effect: pci_dev->driver is set to drv when drv claims pci_dev.
*/
static int
@@ -356,15 +364,16 @@ static struct kobj_type pci_driver_kobj_type = {
};
/**
- * pci_register_driver - register a new pci driver
+ * __pci_register_driver - register a new pci driver
* @drv: the driver structure to register
+ * @owner: owner module of drv
*
* Adds the driver structure to the list of registered drivers.
* Returns a negative value on error, otherwise 0.
* If no error occurred, the driver remains registered even if
* no device was claimed during registration.
*/
-int pci_register_driver(struct pci_driver *drv)
+int __pci_register_driver(struct pci_driver *drv, struct module *owner)
{
int error;
@@ -377,7 +386,11 @@ int pci_register_driver(struct pci_driver *drv)
* the pci shutdown function, this test can go away. */
if (!drv->driver.shutdown)
drv->driver.shutdown = pci_device_shutdown;
- drv->driver.owner = drv->owner;
+ else
+ printk(KERN_WARNING "Warning: PCI driver %s has a struct "
+ "device_driver shutdown method, please update!\n",
+ drv->name);
+ drv->driver.owner = owner;
drv->driver.kobj.ktype = &pci_driver_kobj_type;
spin_lock_init(&drv->dynids.lock);
@@ -436,11 +449,11 @@ pci_dev_driver(const struct pci_dev *dev)
/**
* pci_bus_match - Tell if a PCI device structure has a matching PCI device id structure
- * @ids: array of PCI device id structures to search in
* @dev: the PCI device structure to match against
+ * @drv: the device driver to search for matching PCI device id structures
*
* Used by a driver to check whether a PCI device present in the
- * system is in its list of supported devices.Returns the matching
+ * system is in its list of supported devices. Returns the matching
* pci_device_id structure or %NULL if there is no match.
*/
static int pci_bus_match(struct device *dev, struct device_driver *drv)
@@ -514,7 +527,7 @@ postcore_initcall(pci_driver_init);
EXPORT_SYMBOL(pci_match_id);
EXPORT_SYMBOL(pci_match_device);
-EXPORT_SYMBOL(pci_register_driver);
+EXPORT_SYMBOL(__pci_register_driver);
EXPORT_SYMBOL(pci_unregister_driver);
EXPORT_SYMBOL(pci_dev_driver);
EXPORT_SYMBOL(pci_bus_type);
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index 2898830c496f..965a5934623a 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -130,7 +130,7 @@ pci_read_config(struct kobject *kobj, char *buf, loff_t off, size_t count)
if ((off & 1) && size) {
u8 val;
- pci_read_config_byte(dev, off, &val);
+ pci_user_read_config_byte(dev, off, &val);
data[off - init_off] = val;
off++;
size--;
@@ -138,7 +138,7 @@ pci_read_config(struct kobject *kobj, char *buf, loff_t off, size_t count)
if ((off & 3) && size > 2) {
u16 val;
- pci_read_config_word(dev, off, &val);
+ pci_user_read_config_word(dev, off, &val);
data[off - init_off] = val & 0xff;
data[off - init_off + 1] = (val >> 8) & 0xff;
off += 2;
@@ -147,7 +147,7 @@ pci_read_config(struct kobject *kobj, char *buf, loff_t off, size_t count)
while (size > 3) {
u32 val;
- pci_read_config_dword(dev, off, &val);
+ pci_user_read_config_dword(dev, off, &val);
data[off - init_off] = val & 0xff;
data[off - init_off + 1] = (val >> 8) & 0xff;
data[off - init_off + 2] = (val >> 16) & 0xff;
@@ -158,7 +158,7 @@ pci_read_config(struct kobject *kobj, char *buf, loff_t off, size_t count)
if (size >= 2) {
u16 val;
- pci_read_config_word(dev, off, &val);
+ pci_user_read_config_word(dev, off, &val);
data[off - init_off] = val & 0xff;
data[off - init_off + 1] = (val >> 8) & 0xff;
off += 2;
@@ -167,7 +167,7 @@ pci_read_config(struct kobject *kobj, char *buf, loff_t off, size_t count)
if (size > 0) {
u8 val;
- pci_read_config_byte(dev, off, &val);
+ pci_user_read_config_byte(dev, off, &val);
data[off - init_off] = val;
off++;
--size;
@@ -192,7 +192,7 @@ pci_write_config(struct kobject *kobj, char *buf, loff_t off, size_t count)
}
if ((off & 1) && size) {
- pci_write_config_byte(dev, off, data[off - init_off]);
+ pci_user_write_config_byte(dev, off, data[off - init_off]);
off++;
size--;
}
@@ -200,7 +200,7 @@ pci_write_config(struct kobject *kobj, char *buf, loff_t off, size_t count)
if ((off & 3) && size > 2) {
u16 val = data[off - init_off];
val |= (u16) data[off - init_off + 1] << 8;
- pci_write_config_word(dev, off, val);
+ pci_user_write_config_word(dev, off, val);
off += 2;
size -= 2;
}
@@ -210,7 +210,7 @@ pci_write_config(struct kobject *kobj, char *buf, loff_t off, size_t count)
val |= (u32) data[off - init_off + 1] << 8;
val |= (u32) data[off - init_off + 2] << 16;
val |= (u32) data[off - init_off + 3] << 24;
- pci_write_config_dword(dev, off, val);
+ pci_user_write_config_dword(dev, off, val);
off += 4;
size -= 4;
}
@@ -218,13 +218,13 @@ pci_write_config(struct kobject *kobj, char *buf, loff_t off, size_t count)
if (size >= 2) {
u16 val = data[off - init_off];
val |= (u16) data[off - init_off + 1] << 8;
- pci_write_config_word(dev, off, val);
+ pci_user_write_config_word(dev, off, val);
off += 2;
size -= 2;
}
if (size) {
- pci_write_config_byte(dev, off, data[off - init_off]);
+ pci_user_write_config_byte(dev, off, data[off - init_off]);
off++;
--size;
}
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 259d247b7551..8e287a828d5d 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -15,6 +15,7 @@
#include <linux/pci.h>
#include <linux/module.h>
#include <linux/spinlock.h>
+#include <linux/string.h>
#include <asm/dma.h> /* isa_dma_bridge_buggy */
#include "pci.h"
@@ -62,11 +63,38 @@ pci_max_busnr(void)
return max;
}
+static int __pci_find_next_cap(struct pci_bus *bus, unsigned int devfn, u8 pos, int cap)
+{
+ u8 id;
+ int ttl = 48;
+
+ while (ttl--) {
+ pci_bus_read_config_byte(bus, devfn, pos, &pos);
+ if (pos < 0x40)
+ break;
+ pos &= ~3;
+ pci_bus_read_config_byte(bus, devfn, pos + PCI_CAP_LIST_ID,
+ &id);
+ if (id == 0xff)
+ break;
+ if (id == cap)
+ return pos;
+ pos += PCI_CAP_LIST_NEXT;
+ }
+ return 0;
+}
+
+int pci_find_next_capability(struct pci_dev *dev, u8 pos, int cap)
+{
+ return __pci_find_next_cap(dev->bus, dev->devfn,
+ pos + PCI_CAP_LIST_NEXT, cap);
+}
+EXPORT_SYMBOL_GPL(pci_find_next_capability);
+
static int __pci_bus_find_cap(struct pci_bus *bus, unsigned int devfn, u8 hdr_type, int cap)
{
u16 status;
- u8 pos, id;
- int ttl = 48;
+ u8 pos;
pci_bus_read_config_word(bus, devfn, PCI_STATUS, &status);
if (!(status & PCI_STATUS_CAP_LIST))
@@ -75,24 +103,15 @@ static int __pci_bus_find_cap(struct pci_bus *bus, unsigned int devfn, u8 hdr_ty
switch (hdr_type) {
case PCI_HEADER_TYPE_NORMAL:
case PCI_HEADER_TYPE_BRIDGE:
- pci_bus_read_config_byte(bus, devfn, PCI_CAPABILITY_LIST, &pos);
+ pos = PCI_CAPABILITY_LIST;
break;
case PCI_HEADER_TYPE_CARDBUS:
- pci_bus_read_config_byte(bus, devfn, PCI_CB_CAPABILITY_LIST, &pos);
+ pos = PCI_CB_CAPABILITY_LIST;
break;
default:
return 0;
}
- while (ttl-- && pos >= 0x40) {
- pos &= ~3;
- pci_bus_read_config_byte(bus, devfn, pos + PCI_CAP_LIST_ID, &id);
- if (id == 0xff)
- break;
- if (id == cap)
- return pos;
- pci_bus_read_config_byte(bus, devfn, pos + PCI_CAP_LIST_NEXT, &pos);
- }
- return 0;
+ return __pci_find_next_cap(bus, devfn, pos, cap);
}
/**
@@ -252,6 +271,8 @@ pci_restore_bars(struct pci_dev *dev)
pci_update_resource(dev, &dev->resource[i], i);
}
+int (*platform_pci_set_power_state)(struct pci_dev *dev, pci_power_t t);
+
/**
* pci_set_power_state - Set the power state of a PCI device
* @dev: PCI device to be suspended
@@ -266,7 +287,6 @@ pci_restore_bars(struct pci_dev *dev)
* -EIO if device does not support PCI PM.
* 0 if we can successfully change the power state.
*/
-int (*platform_pci_set_power_state)(struct pci_dev *dev, pci_power_t t);
int
pci_set_power_state(struct pci_dev *dev, pci_power_t state)
{
@@ -314,19 +334,19 @@ pci_set_power_state(struct pci_dev *dev, pci_power_t state)
* sets PowerState to 0.
*/
switch (dev->current_state) {
+ case PCI_D0:
+ case PCI_D1:
+ case PCI_D2:
+ pmcsr &= ~PCI_PM_CTRL_STATE_MASK;
+ pmcsr |= state;
+ break;
case PCI_UNKNOWN: /* Boot-up */
if ((pmcsr & PCI_PM_CTRL_STATE_MASK) == PCI_D3hot
&& !(pmcsr & PCI_PM_CTRL_NO_SOFT_RESET))
need_restore = 1;
/* Fall-through: force to D0 */
- case PCI_D3hot:
- case PCI_D3cold:
- case PCI_POWER_ERROR:
- pmcsr = 0;
- break;
default:
- pmcsr &= ~PCI_PM_CTRL_STATE_MASK;
- pmcsr |= state;
+ pmcsr = 0;
break;
}
@@ -808,8 +828,8 @@ pci_clear_mwi(struct pci_dev *dev)
/**
* pci_intx - enables/disables PCI INTx for device dev
- * @dev: the PCI device to operate on
- * @enable: boolean
+ * @pdev: the PCI device to operate on
+ * @enable: boolean: whether to enable or disable PCI INTx
*
* Enables/disables PCI INTx for device dev
*/
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index d3f3dd42240d..6527b36c9a61 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -15,6 +15,13 @@ extern int pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res,
extern int (*platform_pci_choose_state)(struct pci_dev *dev, pm_message_t state);
extern int (*platform_pci_set_power_state)(struct pci_dev *dev, pci_power_t state);
+extern int pci_user_read_config_byte(struct pci_dev *dev, int where, u8 *val);
+extern int pci_user_read_config_word(struct pci_dev *dev, int where, u16 *val);
+extern int pci_user_read_config_dword(struct pci_dev *dev, int where, u32 *val);
+extern int pci_user_write_config_byte(struct pci_dev *dev, int where, u8 val);
+extern int pci_user_write_config_word(struct pci_dev *dev, int where, u16 val);
+extern int pci_user_write_config_dword(struct pci_dev *dev, int where, u32 val);
+
/* PCI /proc functions */
#ifdef CONFIG_PROC_FS
extern int pci_proc_attach_device(struct pci_dev *dev);
diff --git a/drivers/pci/pcie/portdrv_core.c b/drivers/pci/pcie/portdrv_core.c
index 393e0cee91a9..467a4ceccf10 100644
--- a/drivers/pci/pcie/portdrv_core.c
+++ b/drivers/pci/pcie/portdrv_core.c
@@ -11,6 +11,8 @@
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/pm.h>
+#include <linux/string.h>
+#include <linux/slab.h>
#include <linux/pcieport_if.h>
#include "portdrv.h"
@@ -61,7 +63,7 @@ static int pcie_port_remove_service(struct device *dev)
static void pcie_port_shutdown_service(struct device *dev) {}
-static int pcie_port_suspend_service(struct device *dev, pm_message_t state, u32 level)
+static int pcie_port_suspend_service(struct device *dev, pm_message_t state)
{
struct pcie_device *pciedev;
struct pcie_port_service_driver *driver;
@@ -76,7 +78,7 @@ static int pcie_port_suspend_service(struct device *dev, pm_message_t state, u32
return 0;
}
-static int pcie_port_resume_service(struct device *dev, u32 level)
+static int pcie_port_resume_service(struct device *dev)
{
struct pcie_device *pciedev;
struct pcie_port_service_driver *driver;
diff --git a/drivers/pci/pcie/portdrv_pci.c b/drivers/pci/pcie/portdrv_pci.c
index 3c565ce7f77b..02260141dc81 100644
--- a/drivers/pci/pcie/portdrv_pci.c
+++ b/drivers/pci/pcie/portdrv_pci.c
@@ -12,6 +12,7 @@
#include <linux/errno.h>
#include <linux/pm.h>
#include <linux/init.h>
+#include <linux/slab.h>
#include <linux/pcieport_if.h>
#include "portdrv.h"
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 005786416bb5..fce2cb2112d8 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -669,6 +669,7 @@ static void pci_release_dev(struct device *dev)
/**
* pci_cfg_space_size - get the configuration space size of the PCI device.
+ * @dev: PCI device
*
* Regular PCI devices have 256 bytes, but PCI-X 2 and PCI Express devices
* have 4096 bytes. Even if the device is capable, that doesn't mean we can
diff --git a/drivers/pci/proc.c b/drivers/pci/proc.c
index 9613f666c110..9eb465727fce 100644
--- a/drivers/pci/proc.c
+++ b/drivers/pci/proc.c
@@ -80,7 +80,7 @@ proc_bus_pci_read(struct file *file, char __user *buf, size_t nbytes, loff_t *pp
if ((pos & 1) && cnt) {
unsigned char val;
- pci_read_config_byte(dev, pos, &val);
+ pci_user_read_config_byte(dev, pos, &val);
__put_user(val, buf);
buf++;
pos++;
@@ -89,7 +89,7 @@ proc_bus_pci_read(struct file *file, char __user *buf, size_t nbytes, loff_t *pp
if ((pos & 3) && cnt > 2) {
unsigned short val;
- pci_read_config_word(dev, pos, &val);
+ pci_user_read_config_word(dev, pos, &val);
__put_user(cpu_to_le16(val), (unsigned short __user *) buf);
buf += 2;
pos += 2;
@@ -98,7 +98,7 @@ proc_bus_pci_read(struct file *file, char __user *buf, size_t nbytes, loff_t *pp
while (cnt >= 4) {
unsigned int val;
- pci_read_config_dword(dev, pos, &val);
+ pci_user_read_config_dword(dev, pos, &val);
__put_user(cpu_to_le32(val), (unsigned int __user *) buf);
buf += 4;
pos += 4;
@@ -107,7 +107,7 @@ proc_bus_pci_read(struct file *file, char __user *buf, size_t nbytes, loff_t *pp
if (cnt >= 2) {
unsigned short val;
- pci_read_config_word(dev, pos, &val);
+ pci_user_read_config_word(dev, pos, &val);
__put_user(cpu_to_le16(val), (unsigned short __user *) buf);
buf += 2;
pos += 2;
@@ -116,7 +116,7 @@ proc_bus_pci_read(struct file *file, char __user *buf, size_t nbytes, loff_t *pp
if (cnt) {
unsigned char val;
- pci_read_config_byte(dev, pos, &val);
+ pci_user_read_config_byte(dev, pos, &val);
__put_user(val, buf);
buf++;
pos++;
@@ -151,7 +151,7 @@ proc_bus_pci_write(struct file *file, const char __user *buf, size_t nbytes, lof
if ((pos & 1) && cnt) {
unsigned char val;
__get_user(val, buf);
- pci_write_config_byte(dev, pos, val);
+ pci_user_write_config_byte(dev, pos, val);
buf++;
pos++;
cnt--;
@@ -160,7 +160,7 @@ proc_bus_pci_write(struct file *file, const char __user *buf, size_t nbytes, lof
if ((pos & 3) && cnt > 2) {
unsigned short val;
__get_user(val, (unsigned short __user *) buf);
- pci_write_config_word(dev, pos, le16_to_cpu(val));
+ pci_user_write_config_word(dev, pos, le16_to_cpu(val));
buf += 2;
pos += 2;
cnt -= 2;
@@ -169,7 +169,7 @@ proc_bus_pci_write(struct file *file, const char __user *buf, size_t nbytes, lof
while (cnt >= 4) {
unsigned int val;
__get_user(val, (unsigned int __user *) buf);
- pci_write_config_dword(dev, pos, le32_to_cpu(val));
+ pci_user_write_config_dword(dev, pos, le32_to_cpu(val));
buf += 4;
pos += 4;
cnt -= 4;
@@ -178,7 +178,7 @@ proc_bus_pci_write(struct file *file, const char __user *buf, size_t nbytes, lof
if (cnt >= 2) {
unsigned short val;
__get_user(val, (unsigned short __user *) buf);
- pci_write_config_word(dev, pos, le16_to_cpu(val));
+ pci_user_write_config_word(dev, pos, le16_to_cpu(val));
buf += 2;
pos += 2;
cnt -= 2;
@@ -187,7 +187,7 @@ proc_bus_pci_write(struct file *file, const char __user *buf, size_t nbytes, lof
if (cnt) {
unsigned char val;
__get_user(val, buf);
- pci_write_config_byte(dev, pos, val);
+ pci_user_write_config_byte(dev, pos, val);
buf++;
pos++;
cnt--;
@@ -484,10 +484,10 @@ static int show_dev_config(struct seq_file *m, void *v)
drv = pci_dev_driver(dev);
- pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev);
- pci_read_config_byte (dev, PCI_LATENCY_TIMER, &latency);
- pci_read_config_byte (dev, PCI_MIN_GNT, &min_gnt);
- pci_read_config_byte (dev, PCI_MAX_LAT, &max_lat);
+ pci_user_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev);
+ pci_user_read_config_byte (dev, PCI_LATENCY_TIMER, &latency);
+ pci_user_read_config_byte (dev, PCI_MIN_GNT, &min_gnt);
+ pci_user_read_config_byte (dev, PCI_MAX_LAT, &max_lat);
seq_printf(m, " Bus %2d, device %3d, function %2d:\n",
dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
seq_printf(m, " Class %04x", class_rev >> 16);
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 7992bc8cc6a4..3a4f49f4effb 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -7,6 +7,9 @@
*
* Copyright (c) 1999 Martin Mares <mj@ucw.cz>
*
+ * Init/reset quirks for USB host controllers should be in the
+ * USB quirks file, where their drivers can access reuse it.
+ *
* The bridge optimization stuff has been removed. If you really
* have a silly BIOS which is unable to set your host bridge right,
* use the PowerTweak utility (see http://powertweak.sourceforge.net).
@@ -353,7 +356,7 @@ static void piix4_mem_quirk(struct pci_dev *dev, const char *name, unsigned int
/*
* PIIX4 ACPI: Two IO regions pointed to by longwords at
* 0x40 (64 bytes of ACPI registers)
- * 0x90 (32 bytes of SMB registers)
+ * 0x90 (16 bytes of SMB registers)
* and a few strange programmable PIIX4 device resources.
*/
static void __devinit quirk_piix4_acpi(struct pci_dev *dev)
@@ -363,7 +366,7 @@ static void __devinit quirk_piix4_acpi(struct pci_dev *dev)
pci_read_config_dword(dev, 0x40, &region);
quirk_io_region(dev, region, 64, PCI_BRIDGE_RESOURCES, "PIIX4 ACPI");
pci_read_config_dword(dev, 0x90, &region);
- quirk_io_region(dev, region, 32, PCI_BRIDGE_RESOURCES+1, "PIIX4 SMB");
+ quirk_io_region(dev, region, 16, PCI_BRIDGE_RESOURCES+1, "PIIX4 SMB");
/* Device resource A has enables for some of the other ones */
pci_read_config_dword(dev, 0x5c, &res_a);
@@ -414,6 +417,18 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12,
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0, quirk_ich4_lpc_acpi );
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB_1, quirk_ich4_lpc_acpi );
+static void __devinit quirk_ich6_lpc_acpi(struct pci_dev *dev)
+{
+ u32 region;
+
+ pci_read_config_dword(dev, 0x40, &region);
+ quirk_io_region(dev, region, 128, PCI_BRIDGE_RESOURCES, "ICH6 ACPI/GPIO/TCO");
+
+ pci_read_config_dword(dev, 0x48, &region);
+ quirk_io_region(dev, region, 64, PCI_BRIDGE_RESOURCES+1, "ICH6 GPIO");
+}
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1, quirk_ich6_lpc_acpi );
+
/*
* VIA ACPI: One IO region pointed to by longword at
* 0x48 or 0x20 (256 bytes of ACPI registers)
@@ -447,11 +462,11 @@ static void __devinit quirk_vt82c686_acpi(struct pci_dev *dev)
pci_read_config_word(dev, 0x70, &hm);
hm &= PCI_BASE_ADDRESS_IO_MASK;
- quirk_io_region(dev, hm, 128, PCI_BRIDGE_RESOURCES + 1, "vt82c868 HW-mon");
+ quirk_io_region(dev, hm, 128, PCI_BRIDGE_RESOURCES + 1, "vt82c686 HW-mon");
pci_read_config_dword(dev, 0x90, &smb);
smb &= PCI_BASE_ADDRESS_IO_MASK;
- quirk_io_region(dev, smb, 16, PCI_BRIDGE_RESOURCES + 2, "vt82c868 SMB");
+ quirk_io_region(dev, smb, 16, PCI_BRIDGE_RESOURCES + 2, "vt82c686 SMB");
}
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4, quirk_vt82c686_acpi );
@@ -633,28 +648,6 @@ static void quirk_via_irq(struct pci_dev *dev)
DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_ANY_ID, quirk_via_irq);
/*
- * PIIX3 USB: We have to disable USB interrupts that are
- * hardwired to PIRQD# and may be shared with an
- * external device.
- *
- * Legacy Support Register (LEGSUP):
- * bit13: USB PIRQ Enable (USBPIRQDEN),
- * bit4: Trap/SMI On IRQ Enable (USBSMIEN).
- *
- * We mask out all r/wc bits, too.
- */
-static void __devinit quirk_piix3_usb(struct pci_dev *dev)
-{
- u16 legsup;
-
- pci_read_config_word(dev, 0xc0, &legsup);
- legsup &= 0x50ef;
- pci_write_config_word(dev, 0xc0, legsup);
-}
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371SB_2, quirk_piix3_usb );
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_2, quirk_piix3_usb );
-
-/*
* VIA VT82C598 has its device ID settable and many BIOSes
* set it to the ID of VT82C597 for backward compatibility.
* We need to switch it off to be able to recognize the real
@@ -922,6 +915,12 @@ static void __init asus_hides_smbus_hostbridge(struct pci_dev *dev)
case 0x186a: /* M6Ne notebook */
asus_hides_smbus = 1;
}
+ if (dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB) {
+ switch (dev->subsystem_device) {
+ case 0x1882: /* M6V notebook */
+ asus_hides_smbus = 1;
+ }
+ }
} else if (unlikely(dev->subsystem_vendor == PCI_VENDOR_ID_HP)) {
if (dev->device == PCI_DEVICE_ID_INTEL_82855PM_HB)
switch(dev->subsystem_device) {
@@ -932,6 +931,7 @@ static void __init asus_hides_smbus_hostbridge(struct pci_dev *dev)
if (dev->device == PCI_DEVICE_ID_INTEL_82865_HB)
switch (dev->subsystem_device) {
case 0x12bc: /* HP D330L */
+ case 0x12bd: /* HP D530 */
asus_hides_smbus = 1;
}
} else if (unlikely(dev->subsystem_vendor == PCI_VENDOR_ID_TOSHIBA)) {
@@ -966,6 +966,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82865_HB, asus
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_7205_0, asus_hides_smbus_hostbridge );
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82855PM_HB, asus_hides_smbus_hostbridge );
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82855GM_HB, asus_hides_smbus_hostbridge );
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82915GM_HB, asus_hides_smbus_hostbridge );
static void __init asus_hides_smbus_lpc(struct pci_dev *dev)
{
@@ -990,6 +991,23 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12, as
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12, asus_hides_smbus_lpc );
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0, asus_hides_smbus_lpc );
+static void __init asus_hides_smbus_lpc_ich6(struct pci_dev *dev)
+{
+ u32 val, rcba;
+ void __iomem *base;
+
+ if (likely(!asus_hides_smbus))
+ return;
+ pci_read_config_dword(dev, 0xF0, &rcba);
+ base = ioremap_nocache(rcba & 0xFFFFC000, 0x4000); /* use bits 31:14, 16 kB aligned */
+ if (base == NULL) return;
+ val=readl(base + 0x3418); /* read the Function Disable register, dword mode only */
+ writel(val & 0xFFFFFFF7, base + 0x3418); /* enable the SMBus device */
+ iounmap(base);
+ printk(KERN_INFO "PCI: Enabled ICH6/i801 SMBus device\n");
+}
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1, asus_hides_smbus_lpc_ich6 );
+
/*
* SiS 96x south bridge: BIOS typically hides SMBus device...
*/
@@ -1002,234 +1020,6 @@ static void __init quirk_sis_96x_smbus(struct pci_dev *dev)
pci_read_config_byte(dev, 0x77, &val);
}
-
-#define UHCI_USBLEGSUP 0xc0 /* legacy support */
-#define UHCI_USBCMD 0 /* command register */
-#define UHCI_USBSTS 2 /* status register */
-#define UHCI_USBINTR 4 /* interrupt register */
-#define UHCI_USBLEGSUP_DEFAULT 0x2000 /* only PIRQ enable set */
-#define UHCI_USBCMD_RUN (1 << 0) /* RUN/STOP bit */
-#define UHCI_USBCMD_GRESET (1 << 2) /* Global reset */
-#define UHCI_USBCMD_CONFIGURE (1 << 6) /* config semaphore */
-#define UHCI_USBSTS_HALTED (1 << 5) /* HCHalted bit */
-
-#define OHCI_CONTROL 0x04
-#define OHCI_CMDSTATUS 0x08
-#define OHCI_INTRSTATUS 0x0c
-#define OHCI_INTRENABLE 0x10
-#define OHCI_INTRDISABLE 0x14
-#define OHCI_OCR (1 << 3) /* ownership change request */
-#define OHCI_CTRL_IR (1 << 8) /* interrupt routing */
-#define OHCI_INTR_OC (1 << 30) /* ownership change */
-
-#define EHCI_HCC_PARAMS 0x08 /* extended capabilities */
-#define EHCI_USBCMD 0 /* command register */
-#define EHCI_USBCMD_RUN (1 << 0) /* RUN/STOP bit */
-#define EHCI_USBSTS 4 /* status register */
-#define EHCI_USBSTS_HALTED (1 << 12) /* HCHalted bit */
-#define EHCI_USBINTR 8 /* interrupt register */
-#define EHCI_USBLEGSUP 0 /* legacy support register */
-#define EHCI_USBLEGSUP_BIOS (1 << 16) /* BIOS semaphore */
-#define EHCI_USBLEGSUP_OS (1 << 24) /* OS semaphore */
-#define EHCI_USBLEGCTLSTS 4 /* legacy control/status */
-#define EHCI_USBLEGCTLSTS_SOOE (1 << 13) /* SMI on ownership change */
-
-int usb_early_handoff __devinitdata = 0;
-static int __init usb_handoff_early(char *str)
-{
- usb_early_handoff = 1;
- return 0;
-}
-__setup("usb-handoff", usb_handoff_early);
-
-static void __devinit quirk_usb_handoff_uhci(struct pci_dev *pdev)
-{
- unsigned long base = 0;
- int wait_time, delta;
- u16 val, sts;
- int i;
-
- for (i = 0; i < PCI_ROM_RESOURCE; i++)
- if ((pci_resource_flags(pdev, i) & IORESOURCE_IO)) {
- base = pci_resource_start(pdev, i);
- break;
- }
-
- if (!base)
- return;
-
- /*
- * stop controller
- */
- sts = inw(base + UHCI_USBSTS);
- val = inw(base + UHCI_USBCMD);
- val &= ~(u16)(UHCI_USBCMD_RUN | UHCI_USBCMD_CONFIGURE);
- outw(val, base + UHCI_USBCMD);
-
- /*
- * wait while it stops if it was running
- */
- if ((sts & UHCI_USBSTS_HALTED) == 0)
- {
- wait_time = 1000;
- delta = 100;
-
- do {
- outw(0x1f, base + UHCI_USBSTS);
- udelay(delta);
- wait_time -= delta;
- val = inw(base + UHCI_USBSTS);
- if (val & UHCI_USBSTS_HALTED)
- break;
- } while (wait_time > 0);
- }
-
- /*
- * disable interrupts & legacy support
- */
- outw(0, base + UHCI_USBINTR);
- outw(0x1f, base + UHCI_USBSTS);
- pci_read_config_word(pdev, UHCI_USBLEGSUP, &val);
- if (val & 0xbf)
- pci_write_config_word(pdev, UHCI_USBLEGSUP, UHCI_USBLEGSUP_DEFAULT);
-
-}
-
-static void __devinit quirk_usb_handoff_ohci(struct pci_dev *pdev)
-{
- void __iomem *base;
- int wait_time;
-
- base = ioremap_nocache(pci_resource_start(pdev, 0),
- pci_resource_len(pdev, 0));
- if (base == NULL) return;
-
- if (readl(base + OHCI_CONTROL) & OHCI_CTRL_IR) {
- wait_time = 500; /* 0.5 seconds */
- writel(OHCI_INTR_OC, base + OHCI_INTRENABLE);
- writel(OHCI_OCR, base + OHCI_CMDSTATUS);
- while (wait_time > 0 &&
- readl(base + OHCI_CONTROL) & OHCI_CTRL_IR) {
- wait_time -= 10;
- msleep(10);
- }
- }
-
- /*
- * disable interrupts
- */
- writel(~(u32)0, base + OHCI_INTRDISABLE);
- writel(~(u32)0, base + OHCI_INTRSTATUS);
-
- iounmap(base);
-}
-
-static void __devinit quirk_usb_disable_ehci(struct pci_dev *pdev)
-{
- int wait_time, delta;
- void __iomem *base, *op_reg_base;
- u32 hcc_params, val, temp;
- u8 cap_length;
-
- base = ioremap_nocache(pci_resource_start(pdev, 0),
- pci_resource_len(pdev, 0));
- if (base == NULL) return;
-
- cap_length = readb(base);
- op_reg_base = base + cap_length;
- hcc_params = readl(base + EHCI_HCC_PARAMS);
- hcc_params = (hcc_params >> 8) & 0xff;
- if (hcc_params) {
- pci_read_config_dword(pdev,
- hcc_params + EHCI_USBLEGSUP,
- &val);
- if (((val & 0xff) == 1) && (val & EHCI_USBLEGSUP_BIOS)) {
- /*
- * Ok, BIOS is in smm mode, try to hand off...
- */
- pci_read_config_dword(pdev,
- hcc_params + EHCI_USBLEGCTLSTS,
- &temp);
- pci_write_config_dword(pdev,
- hcc_params + EHCI_USBLEGCTLSTS,
- temp | EHCI_USBLEGCTLSTS_SOOE);
- val |= EHCI_USBLEGSUP_OS;
- pci_write_config_dword(pdev,
- hcc_params + EHCI_USBLEGSUP,
- val);
-
- wait_time = 500;
- do {
- msleep(10);
- wait_time -= 10;
- pci_read_config_dword(pdev,
- hcc_params + EHCI_USBLEGSUP,
- &val);
- } while (wait_time && (val & EHCI_USBLEGSUP_BIOS));
- if (!wait_time) {
- /*
- * well, possibly buggy BIOS...
- */
- printk(KERN_WARNING "EHCI early BIOS handoff "
- "failed (BIOS bug ?)\n");
- pci_write_config_dword(pdev,
- hcc_params + EHCI_USBLEGSUP,
- EHCI_USBLEGSUP_OS);
- pci_write_config_dword(pdev,
- hcc_params + EHCI_USBLEGCTLSTS,
- 0);
- }
- }
- }
-
- /*
- * halt EHCI & disable its interrupts in any case
- */
- val = readl(op_reg_base + EHCI_USBSTS);
- if ((val & EHCI_USBSTS_HALTED) == 0) {
- val = readl(op_reg_base + EHCI_USBCMD);
- val &= ~EHCI_USBCMD_RUN;
- writel(val, op_reg_base + EHCI_USBCMD);
-
- wait_time = 2000;
- delta = 100;
- do {
- writel(0x3f, op_reg_base + EHCI_USBSTS);
- udelay(delta);
- wait_time -= delta;
- val = readl(op_reg_base + EHCI_USBSTS);
- if ((val == ~(u32)0) || (val & EHCI_USBSTS_HALTED)) {
- break;
- }
- } while (wait_time > 0);
- }
- writel(0, op_reg_base + EHCI_USBINTR);
- writel(0x3f, op_reg_base + EHCI_USBSTS);
-
- iounmap(base);
-
- return;
-}
-
-
-
-static void __devinit quirk_usb_early_handoff(struct pci_dev *pdev)
-{
- if (!usb_early_handoff)
- return;
-
- if (pdev->class == ((PCI_CLASS_SERIAL_USB << 8) | 0x00)) { /* UHCI */
- quirk_usb_handoff_uhci(pdev);
- } else if (pdev->class == ((PCI_CLASS_SERIAL_USB << 8) | 0x10)) { /* OHCI */
- quirk_usb_handoff_ohci(pdev);
- } else if (pdev->class == ((PCI_CLASS_SERIAL_USB << 8) | 0x20)) { /* EHCI */
- quirk_usb_disable_ehci(pdev);
- }
-
- return;
-}
-DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, quirk_usb_early_handoff);
-
/*
* ... This is further complicated by the fact that some SiS96x south
* bridges pretend to be 85C503/5513 instead. In that case see if we
@@ -1453,6 +1243,21 @@ static void __devinit quirk_netmos(struct pci_dev *dev)
}
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NETMOS, PCI_ANY_ID, quirk_netmos);
+
+static void __devinit fixup_rev1_53c810(struct pci_dev* dev)
+{
+ /* rev 1 ncr53c810 chips don't set the class at all which means
+ * they don't get their resources remapped. Fix that here.
+ */
+
+ if (dev->class == PCI_CLASS_NOT_DEFINED) {
+ printk(KERN_INFO "NCR 53c810 rev 1 detected, setting PCI class.\n");
+ dev->class = PCI_CLASS_STORAGE_SCSI;
+ }
+}
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NCR, PCI_DEVICE_ID_NCR_53C810, fixup_rev1_53c810);
+
+
static void pci_do_fixups(struct pci_dev *dev, struct pci_fixup *f, struct pci_fixup *end)
{
while (f < end) {
diff --git a/drivers/pci/rom.c b/drivers/pci/rom.c
index 49bd21702314..598a115cd00e 100644
--- a/drivers/pci/rom.c
+++ b/drivers/pci/rom.c
@@ -9,6 +9,7 @@
#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/pci.h>
+#include <linux/slab.h>
#include "pci.h"
diff --git a/drivers/pci/syscall.c b/drivers/pci/syscall.c
index c071790cc983..87fafc08cb9d 100644
--- a/drivers/pci/syscall.c
+++ b/drivers/pci/syscall.c
@@ -13,7 +13,7 @@
#include <linux/smp_lock.h>
#include <linux/syscalls.h>
#include <asm/uaccess.h>
-
+#include "pci.h"
asmlinkage long
sys_pciconfig_read(unsigned long bus, unsigned long dfn,
@@ -38,13 +38,13 @@ sys_pciconfig_read(unsigned long bus, unsigned long dfn,
lock_kernel();
switch (len) {
case 1:
- cfg_ret = pci_read_config_byte(dev, off, &byte);
+ cfg_ret = pci_user_read_config_byte(dev, off, &byte);
break;
case 2:
- cfg_ret = pci_read_config_word(dev, off, &word);
+ cfg_ret = pci_user_read_config_word(dev, off, &word);
break;
case 4:
- cfg_ret = pci_read_config_dword(dev, off, &dword);
+ cfg_ret = pci_user_read_config_dword(dev, off, &dword);
break;
default:
err = -EINVAL;
@@ -112,7 +112,7 @@ sys_pciconfig_write(unsigned long bus, unsigned long dfn,
err = get_user(byte, (u8 __user *)buf);
if (err)
break;
- err = pci_write_config_byte(dev, off, byte);
+ err = pci_user_write_config_byte(dev, off, byte);
if (err != PCIBIOS_SUCCESSFUL)
err = -EIO;
break;
@@ -121,7 +121,7 @@ sys_pciconfig_write(unsigned long bus, unsigned long dfn,
err = get_user(word, (u16 __user *)buf);
if (err)
break;
- err = pci_write_config_word(dev, off, word);
+ err = pci_user_write_config_word(dev, off, word);
if (err != PCIBIOS_SUCCESSFUL)
err = -EIO;
break;
@@ -130,7 +130,7 @@ sys_pciconfig_write(unsigned long bus, unsigned long dfn,
err = get_user(dword, (u32 __user *)buf);
if (err)
break;
- err = pci_write_config_dword(dev, off, dword);
+ err = pci_user_write_config_dword(dev, off, dword);
if (err != PCIBIOS_SUCCESSFUL)
err = -EIO;
break;
diff --git a/drivers/pcmcia/Kconfig b/drivers/pcmcia/Kconfig
index 36cc9a96a338..309eb557f9a3 100644
--- a/drivers/pcmcia/Kconfig
+++ b/drivers/pcmcia/Kconfig
@@ -154,6 +154,16 @@ config TCIC
"Bridge" is the name used for the hardware inside your computer that
PCMCIA cards are plugged into. If unsure, say N.
+config PCMCIA_M8XX
+ tristate "MPC8xx PCMCIA support"
+ depends on PCMCIA && PPC && 8xx
+ select PCCARD_NONSTATIC
+ help
+ Say Y here to include support for PowerPC 8xx series PCMCIA
+ controller.
+
+ This driver is also available as a module called m8xx_pcmcia.
+
config HD64465_PCMCIA
tristate "HD64465 host bridge support"
depends on HD64465 && PCMCIA
diff --git a/drivers/pcmcia/Makefile b/drivers/pcmcia/Makefile
index a41fbb38fdcb..bcecf5133b7e 100644
--- a/drivers/pcmcia/Makefile
+++ b/drivers/pcmcia/Makefile
@@ -25,6 +25,7 @@ obj-$(CONFIG_PD6729) += pd6729.o
obj-$(CONFIG_I82365) += i82365.o
obj-$(CONFIG_I82092) += i82092.o
obj-$(CONFIG_TCIC) += tcic.o
+obj-$(CONFIG_PCMCIA_M8XX) += m8xx_pcmcia.o
obj-$(CONFIG_HD64465_PCMCIA) += hd64465_ss.o
obj-$(CONFIG_PCMCIA_SA1100) += sa11xx_core.o sa1100_cs.o
obj-$(CONFIG_PCMCIA_SA1111) += sa11xx_core.o sa1111_cs.o
@@ -42,12 +43,14 @@ pxa2xx_core-y += soc_common.o pxa2xx_base.o
au1x00_ss-y += au1000_generic.o
au1x00_ss-$(CONFIG_MIPS_PB1000) += au1000_pb1x00.o
au1x00_ss-$(CONFIG_MIPS_PB1100) += au1000_pb1x00.o
+au1x00_ss-$(CONFIG_MIPS_PB1200) += au1000_db1x00.o
au1x00_ss-$(CONFIG_MIPS_PB1500) += au1000_pb1x00.o
au1x00_ss-$(CONFIG_MIPS_DB1000) += au1000_db1x00.o
au1x00_ss-$(CONFIG_MIPS_DB1100) += au1000_db1x00.o
+au1x00_ss-$(CONFIG_MIPS_DB1200) += au1000_db1x00.o
au1x00_ss-$(CONFIG_MIPS_DB1500) += au1000_db1x00.o
au1x00_ss-$(CONFIG_MIPS_DB1550) += au1000_db1x00.o
-au1x00_ss-$(CONFIG_MIPS_XXS1500) += au1000_xxs1500.o
+au1x00_ss-$(CONFIG_MIPS_XXS1500) += au1000_xxs1500.o
sa1111_cs-y += sa1111_generic.o
sa1111_cs-$(CONFIG_ASSABET_NEPONSET) += sa1100_neponset.o
@@ -57,6 +60,7 @@ sa1111_cs-$(CONFIG_SA1100_JORNADA720) += sa1100_jornada720.o
sa1100_cs-y += sa1100_generic.o
sa1100_cs-$(CONFIG_SA1100_ASSABET) += sa1100_assabet.o
sa1100_cs-$(CONFIG_SA1100_CERF) += sa1100_cerf.o
+sa1100_cs-$(CONFIG_SA1100_COLLIE) += pxa2xx_sharpsl.o
sa1100_cs-$(CONFIG_SA1100_H3600) += sa1100_h3600.o
sa1100_cs-$(CONFIG_SA1100_SHANNON) += sa1100_shannon.o
sa1100_cs-$(CONFIG_SA1100_SIMPAD) += sa1100_simpad.o
diff --git a/drivers/pcmcia/au1000_db1x00.c b/drivers/pcmcia/au1000_db1x00.c
index 42cf8bfbcc98..abc13f28ba3f 100644
--- a/drivers/pcmcia/au1000_db1x00.c
+++ b/drivers/pcmcia/au1000_db1x00.c
@@ -30,6 +30,7 @@
*
*/
+#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/errno.h>
@@ -40,7 +41,15 @@
#include <asm/irq.h>
#include <asm/signal.h>
#include <asm/mach-au1x00/au1000.h>
-#include <asm/mach-db1x00/db1x00.h>
+
+#if defined(CONFIG_MIPS_DB1200)
+ #include <db1200.h>
+#elif defined(CONFIG_MIPS_PB1200)
+ #include <pb1200.h>
+#else
+ #include <asm/mach-db1x00/db1x00.h>
+ static BCSR * const bcsr = (BCSR *)BCSR_KSEG1_ADDR;
+#endif
#include "au1000_generic.h"
@@ -50,7 +59,6 @@
#define debug(x,args...)
#endif
-static BCSR * const bcsr = (BCSR *)BCSR_KSEG1_ADDR;
struct au1000_pcmcia_socket au1000_pcmcia_socket[PCMCIA_NUM_SOCKS];
extern int au1x00_pcmcia_socket_probe(struct device *, struct pcmcia_low_level *, int, int);
@@ -59,6 +67,8 @@ static int db1x00_pcmcia_hw_init(struct au1000_pcmcia_socket *skt)
{
#ifdef CONFIG_MIPS_DB1550
skt->irq = skt->nr ? AU1000_GPIO_5 : AU1000_GPIO_3;
+#elif defined(CONFIG_MIPS_DB1200) || defined(CONFIG_MIPS_PB1200)
+ skt->irq = skt->nr ? BOARD_PC1_INT : BOARD_PC0_INT;
#else
skt->irq = skt->nr ? AU1000_GPIO_5 : AU1000_GPIO_2;
#endif
@@ -85,11 +95,19 @@ db1x00_pcmcia_socket_state(struct au1000_pcmcia_socket *skt, struct pcmcia_state
switch (skt->nr) {
case 0:
vs = bcsr->status & 0x3;
+#if defined(CONFIG_MIPS_DB1200) || defined(CONFIG_MIPS_PB1200)
+ inserted = BOARD_CARD_INSERTED(0);
+#else
inserted = !(bcsr->status & (1<<4));
+#endif
break;
case 1:
vs = (bcsr->status & 0xC)>>2;
+#if defined(CONFIG_MIPS_DB1200) || defined(CONFIG_MIPS_PB1200)
+ inserted = BOARD_CARD_INSERTED(1);
+#else
inserted = !(bcsr->status & (1<<5));
+#endif
break;
default:/* should never happen */
return;
diff --git a/drivers/pcmcia/au1000_generic.c b/drivers/pcmcia/au1000_generic.c
index 470ef756252e..87302c548c24 100644
--- a/drivers/pcmcia/au1000_generic.c
+++ b/drivers/pcmcia/au1000_generic.c
@@ -42,7 +42,7 @@
#include <linux/notifier.h>
#include <linux/interrupt.h>
#include <linux/spinlock.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <asm/io.h>
#include <asm/irq.h>
@@ -490,7 +490,7 @@ int au1x00_drv_pcmcia_remove(struct device *dev)
flush_scheduled_work();
skt->ops->hw_shutdown(skt);
au1x00_pcmcia_config_skt(skt, &dead_socket);
- iounmap(skt->virt_io);
+ iounmap(skt->virt_io + (u32)mips_io_port_base);
skt->virt_io = NULL;
}
@@ -519,36 +519,15 @@ static int au1x00_drv_pcmcia_probe(struct device *dev)
}
-static int au1x00_drv_pcmcia_suspend(struct device *dev, pm_message_t state, u32 level)
-{
- int ret = 0;
- if (level == SUSPEND_SAVE_STATE)
- ret = pcmcia_socket_dev_suspend(dev, state);
- return ret;
-}
-
-static int au1x00_drv_pcmcia_resume(struct device *dev, u32 level)
-{
- int ret = 0;
- if (level == RESUME_RESTORE_STATE)
- ret = pcmcia_socket_dev_resume(dev);
- return ret;
-}
-
-
static struct device_driver au1x00_pcmcia_driver = {
.probe = au1x00_drv_pcmcia_probe,
.remove = au1x00_drv_pcmcia_remove,
.name = "au1x00-pcmcia",
.bus = &platform_bus_type,
- .suspend = au1x00_drv_pcmcia_suspend,
- .resume = au1x00_drv_pcmcia_resume
+ .suspend = pcmcia_socket_dev_suspend,
+ .resume = pcmcia_socket_dev_resume,
};
-static struct platform_device au1x00_device = {
- .name = "au1x00-pcmcia",
- .id = 0,
-};
/* au1x00_pcmcia_init()
*
@@ -562,7 +541,6 @@ static int __init au1x00_pcmcia_init(void)
int error = 0;
if ((error = driver_register(&au1x00_pcmcia_driver)))
return error;
- platform_device_register(&au1x00_device);
return error;
}
@@ -573,7 +551,6 @@ static int __init au1x00_pcmcia_init(void)
static void __exit au1x00_pcmcia_exit(void)
{
driver_unregister(&au1x00_pcmcia_driver);
- platform_device_unregister(&au1x00_device);
}
module_init(au1x00_pcmcia_init);
diff --git a/drivers/pcmcia/au1000_generic.h b/drivers/pcmcia/au1000_generic.h
index d5122b1ea94b..f2c970b5f4ff 100644
--- a/drivers/pcmcia/au1000_generic.h
+++ b/drivers/pcmcia/au1000_generic.h
@@ -22,6 +22,8 @@
#define __ASM_AU1000_PCMCIA_H
/* include the world */
+#include <linux/config.h>
+
#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
#include <pcmcia/ss.h>
@@ -44,13 +46,13 @@
/* pcmcia socket 1 needs external glue logic so the memory map
* differs from board to board.
*/
-#if defined(CONFIG_MIPS_PB1000) || defined(CONFIG_MIPS_PB1100) || defined(CONFIG_MIPS_PB1500) || defined(CONFIG_MIPS_PB1550)
+#if defined(CONFIG_MIPS_PB1000) || defined(CONFIG_MIPS_PB1100) || defined(CONFIG_MIPS_PB1500) || defined(CONFIG_MIPS_PB1550) || defined(CONFIG_MIPS_PB1200)
#define AU1X_SOCK1_IO 0xF08000000
#define AU1X_SOCK1_PHYS_ATTR 0xF48000000
#define AU1X_SOCK1_PHYS_MEM 0xF88000000
#define AU1X_SOCK1_PSEUDO_PHYS_ATTR 0xF4800000
#define AU1X_SOCK1_PSEUDO_PHYS_MEM 0xF8800000
-#elif defined(CONFIG_MIPS_DB1000) || defined(CONFIG_MIPS_DB1100) || defined(CONFIG_MIPS_DB1500) || defined(CONFIG_MIPS_DB1550)
+#elif defined(CONFIG_MIPS_DB1000) || defined(CONFIG_MIPS_DB1100) || defined(CONFIG_MIPS_DB1500) || defined(CONFIG_MIPS_DB1550) || defined(CONFIG_MIPS_DB1200)
#define AU1X_SOCK1_IO 0xF04000000
#define AU1X_SOCK1_PHYS_ATTR 0xF44000000
#define AU1X_SOCK1_PHYS_MEM 0xF84000000
diff --git a/drivers/pcmcia/au1000_pb1x00.c b/drivers/pcmcia/au1000_pb1x00.c
index d414a3bb50b9..fd5522ede867 100644
--- a/drivers/pcmcia/au1000_pb1x00.c
+++ b/drivers/pcmcia/au1000_pb1x00.c
@@ -21,6 +21,7 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
*/
+#include <linux/config.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/delay.h>
@@ -30,7 +31,6 @@
#include <linux/timer.h>
#include <linux/mm.h>
#include <linux/proc_fs.h>
-#include <linux/version.h>
#include <linux/types.h>
#include <pcmcia/cs_types.h>
diff --git a/drivers/pcmcia/au1000_xxs1500.c b/drivers/pcmcia/au1000_xxs1500.c
index f113b69d699b..01874b0bb03b 100644
--- a/drivers/pcmcia/au1000_xxs1500.c
+++ b/drivers/pcmcia/au1000_xxs1500.c
@@ -27,7 +27,6 @@
*/
#include <linux/module.h>
#include <linux/init.h>
-#include <linux/config.h>
#include <linux/delay.h>
#include <linux/ioport.h>
#include <linux/kernel.h>
@@ -35,7 +34,6 @@
#include <linux/timer.h>
#include <linux/mm.h>
#include <linux/proc_fs.h>
-#include <linux/version.h>
#include <linux/types.h>
#include <pcmcia/cs_types.h>
diff --git a/drivers/pcmcia/cistpl.c b/drivers/pcmcia/cistpl.c
index 3afb682255a0..2dc3e611a9a3 100644
--- a/drivers/pcmcia/cistpl.c
+++ b/drivers/pcmcia/cistpl.c
@@ -334,10 +334,8 @@ void destroy_cis_cache(struct pcmcia_socket *s)
/*
* If there was a fake CIS, destroy that as well.
*/
- if (s->fake_cis) {
- kfree(s->fake_cis);
- s->fake_cis = NULL;
- }
+ kfree(s->fake_cis);
+ s->fake_cis = NULL;
}
EXPORT_SYMBOL(destroy_cis_cache);
@@ -386,10 +384,8 @@ int verify_cis_cache(struct pcmcia_socket *s)
int pcmcia_replace_cis(struct pcmcia_socket *s, cisdump_t *cis)
{
- if (s->fake_cis != NULL) {
- kfree(s->fake_cis);
- s->fake_cis = NULL;
- }
+ kfree(s->fake_cis);
+ s->fake_cis = NULL;
if (cis->Length > CISTPL_MAX_CIS_SIZE)
return CS_BAD_SIZE;
s->fake_cis = kmalloc(cis->Length, GFP_KERNEL);
diff --git a/drivers/pcmcia/cs.c b/drivers/pcmcia/cs.c
index d5e76423a0ee..234cdca6fe13 100644
--- a/drivers/pcmcia/cs.c
+++ b/drivers/pcmcia/cs.c
@@ -331,10 +331,8 @@ static void shutdown_socket(struct pcmcia_socket *s)
cb_free(s);
#endif
s->functions = 0;
- if (s->config) {
- kfree(s->config);
- s->config = NULL;
- }
+ kfree(s->config);
+ s->config = NULL;
{
int status;
diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c
index 080608c7381a..39d096b52926 100644
--- a/drivers/pcmcia/ds.c
+++ b/drivers/pcmcia/ds.c
@@ -1157,7 +1157,8 @@ static struct pcmcia_callback pcmcia_bus_callback = {
.requery = pcmcia_bus_rescan,
};
-static int __devinit pcmcia_bus_add_socket(struct class_device *class_dev)
+static int __devinit pcmcia_bus_add_socket(struct class_device *class_dev,
+ struct class_interface *class_intf)
{
struct pcmcia_socket *socket = class_get_devdata(class_dev);
int ret;
@@ -1192,7 +1193,8 @@ static int __devinit pcmcia_bus_add_socket(struct class_device *class_dev)
return 0;
}
-static void pcmcia_bus_remove_socket(struct class_device *class_dev)
+static void pcmcia_bus_remove_socket(struct class_device *class_dev,
+ struct class_interface *class_intf)
{
struct pcmcia_socket *socket = class_get_devdata(class_dev);
diff --git a/drivers/pcmcia/hd64465_ss.c b/drivers/pcmcia/hd64465_ss.c
index 316f8bcc878b..561706ba4499 100644
--- a/drivers/pcmcia/hd64465_ss.c
+++ b/drivers/pcmcia/hd64465_ss.c
@@ -37,7 +37,7 @@
#include <asm/errno.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <asm/io.h>
#include <asm/hd64465/hd64465.h>
@@ -844,27 +844,11 @@ static void hs_exit_socket(hs_socket_t *sp)
local_irq_restore(flags);
}
-static int hd64465_suspend(struct device *dev, pm_message_t state, u32 level)
-{
- int ret = 0;
- if (level == SUSPEND_SAVE_STATE)
- ret = pcmcia_socket_dev_suspend(dev, state);
- return ret;
-}
-
-static int hd64465_resume(struct device *dev, u32 level)
-{
- int ret = 0;
- if (level == RESUME_RESTORE_STATE)
- ret = pcmcia_socket_dev_resume(dev);
- return ret;
-}
-
static struct device_driver hd64465_driver = {
.name = "hd64465-pcmcia",
.bus = &platform_bus_type,
- .suspend = hd64465_suspend,
- .resume = hd64465_resume,
+ .suspend = pcmcia_socket_dev_suspend,
+ .resume = pcmcia_socket_dev_resume,
};
static struct platform_device hd64465_device = {
diff --git a/drivers/pcmcia/i82365.c b/drivers/pcmcia/i82365.c
index a713015e8228..4ddd76239b34 100644
--- a/drivers/pcmcia/i82365.c
+++ b/drivers/pcmcia/i82365.c
@@ -47,7 +47,7 @@
#include <linux/delay.h>
#include <linux/workqueue.h>
#include <linux/interrupt.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <linux/bitops.h>
#include <asm/irq.h>
#include <asm/io.h>
@@ -1332,27 +1332,11 @@ static struct pccard_operations pcic_operations = {
/*====================================================================*/
-static int i82365_suspend(struct device *dev, pm_message_t state, u32 level)
-{
- int ret = 0;
- if (level == SUSPEND_SAVE_STATE)
- ret = pcmcia_socket_dev_suspend(dev, state);
- return ret;
-}
-
-static int i82365_resume(struct device *dev, u32 level)
-{
- int ret = 0;
- if (level == RESUME_RESTORE_STATE)
- ret = pcmcia_socket_dev_resume(dev);
- return ret;
-}
-
static struct device_driver i82365_driver = {
.name = "i82365",
.bus = &platform_bus_type,
- .suspend = i82365_suspend,
- .resume = i82365_resume,
+ .suspend = pcmcia_socket_dev_suspend,
+ .resume = pcmcia_socket_dev_resume,
};
static struct platform_device i82365_device = {
@@ -1382,6 +1366,7 @@ static int __init init_i82365(void)
if (sockets == 0) {
printk("not found.\n");
platform_device_unregister(&i82365_device);
+ release_region(i365_base, 2);
driver_unregister(&i82365_driver);
return -ENODEV;
}
diff --git a/drivers/pcmcia/m32r_cfc.c b/drivers/pcmcia/m32r_cfc.c
index 65f3ee3d4d3c..2c22b4b3619d 100644
--- a/drivers/pcmcia/m32r_cfc.c
+++ b/drivers/pcmcia/m32r_cfc.c
@@ -23,7 +23,7 @@
#include <linux/delay.h>
#include <linux/workqueue.h>
#include <linux/interrupt.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <linux/bitops.h>
#include <asm/irq.h>
#include <asm/io.h>
@@ -731,28 +731,11 @@ static struct pccard_operations pcc_operations = {
/*====================================================================*/
-static int m32r_pcc_suspend(struct device *dev, pm_message_t state, u32 level)
-{
- int ret = 0;
- if (level == SUSPEND_SAVE_STATE)
- ret = pcmcia_socket_dev_suspend(dev, state);
- return ret;
-}
-
-static int m32r_pcc_resume(struct device *dev, u32 level)
-{
- int ret = 0;
- if (level == RESUME_RESTORE_STATE)
- ret = pcmcia_socket_dev_resume(dev);
- return ret;
-}
-
-
static struct device_driver pcc_driver = {
.name = "cfc",
.bus = &platform_bus_type,
- .suspend = m32r_pcc_suspend,
- .resume = m32r_pcc_resume,
+ .suspend = pcmcia_socket_dev_suspend,
+ .resume = pcmcia_socket_dev_resume,
};
static struct platform_device pcc_device = {
diff --git a/drivers/pcmcia/m32r_pcc.c b/drivers/pcmcia/m32r_pcc.c
index 7b14d7efd68c..356a6fb416a1 100644
--- a/drivers/pcmcia/m32r_pcc.c
+++ b/drivers/pcmcia/m32r_pcc.c
@@ -23,7 +23,7 @@
#include <linux/delay.h>
#include <linux/workqueue.h>
#include <linux/interrupt.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <asm/irq.h>
#include <asm/io.h>
#include <asm/bitops.h>
@@ -695,28 +695,11 @@ static struct pccard_operations pcc_operations = {
/*====================================================================*/
-static int m32r_pcc_suspend(struct device *dev, pm_message_t state, u32 level)
-{
- int ret = 0;
- if (level == SUSPEND_SAVE_STATE)
- ret = pcmcia_socket_dev_suspend(dev, state);
- return ret;
-}
-
-static int m32r_pcc_resume(struct device *dev, u32 level)
-{
- int ret = 0;
- if (level == RESUME_RESTORE_STATE)
- ret = pcmcia_socket_dev_resume(dev);
- return ret;
-}
-
-
static struct device_driver pcc_driver = {
.name = "pcc",
.bus = &platform_bus_type,
- .suspend = m32r_pcc_suspend,
- .resume = m32r_pcc_resume,
+ .suspend = pcmcia_socket_dev_suspend,
+ .resume = pcmcia_socket_dev_resume,
};
static struct platform_device pcc_device = {
diff --git a/drivers/pcmcia/m8xx_pcmcia.c b/drivers/pcmcia/m8xx_pcmcia.c
new file mode 100644
index 000000000000..6d9f71cfcb34
--- /dev/null
+++ b/drivers/pcmcia/m8xx_pcmcia.c
@@ -0,0 +1,1272 @@
+/*
+ * m8xx_pcmcia.c - Linux PCMCIA socket driver for the mpc8xx series.
+ *
+ * (C) 1999-2000 Magnus Damm <damm@bitsmart.com>
+ * (C) 2001-2002 Montavista Software, Inc.
+ * <mlocke@mvista.com>
+ *
+ * Support for two slots by Cyclades Corporation
+ * <oliver.kurth@cyclades.de>
+ * Further fixes, v2.6 kernel port
+ * <marcelo.tosatti@cyclades.com>
+ *
+ * "The ExCA standard specifies that socket controllers should provide
+ * two IO and five memory windows per socket, which can be independently
+ * configured and positioned in the host address space and mapped to
+ * arbitrary segments of card address space. " - David A Hinds. 1999
+ *
+ * This controller does _not_ meet the ExCA standard.
+ *
+ * m8xx pcmcia controller brief info:
+ * + 8 windows (attrib, mem, i/o)
+ * + up to two slots (SLOT_A and SLOT_B)
+ * + inputpins, outputpins, event and mask registers.
+ * - no offset register. sigh.
+ *
+ * Because of the lacking offset register we must map the whole card.
+ * We assign each memory window PCMCIA_MEM_WIN_SIZE address space.
+ * Make sure there is (PCMCIA_MEM_WIN_SIZE * PCMCIA_MEM_WIN_NO
+ * * PCMCIA_SOCKETS_NO) bytes at PCMCIA_MEM_WIN_BASE.
+ * The i/o windows are dynamically allocated at PCMCIA_IO_WIN_BASE.
+ * They are maximum 64KByte each...
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/fcntl.h>
+#include <linux/string.h>
+
+#include <asm/io.h>
+#include <asm/bitops.h>
+#include <asm/system.h>
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/timer.h>
+#include <linux/ioport.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+
+#include <asm/mpc8xx.h>
+#include <asm/8xx_immap.h>
+#include <asm/irq.h>
+
+#include <pcmcia/version.h>
+#include <pcmcia/cs_types.h>
+#include <pcmcia/cs.h>
+#include <pcmcia/ss.h>
+
+#ifdef PCMCIA_DEBUG
+static int pc_debug = PCMCIA_DEBUG;
+module_param(pc_debug, int, 0);
+#define dprintk(args...) printk(KERN_DEBUG "m8xx_pcmcia: " args);
+#else
+#define dprintk(args...)
+#endif
+
+#define pcmcia_info(args...) printk(KERN_INFO "m8xx_pcmcia: "args)
+#define pcmcia_error(args...) printk(KERN_ERR "m8xx_pcmcia: "args)
+
+static const char *version = "Version 0.06, Aug 2005";
+MODULE_LICENSE("Dual MPL/GPL");
+
+#if !defined(CONFIG_PCMCIA_SLOT_A) && !defined(CONFIG_PCMCIA_SLOT_B)
+
+/* The RPX series use SLOT_B */
+#if defined(CONFIG_RPXCLASSIC) || defined(CONFIG_RPXLITE)
+#define CONFIG_PCMCIA_SLOT_B
+#define CONFIG_BD_IS_MHZ
+#endif
+
+/* The ADS board use SLOT_A */
+#ifdef CONFIG_ADS
+#define CONFIG_PCMCIA_SLOT_A
+#define CONFIG_BD_IS_MHZ
+#endif
+
+/* The FADS series are a mess */
+#ifdef CONFIG_FADS
+#if defined(CONFIG_MPC860T) || defined(CONFIG_MPC860) || defined(CONFIG_MPC821)
+#define CONFIG_PCMCIA_SLOT_A
+#else
+#define CONFIG_PCMCIA_SLOT_B
+#endif
+#endif
+
+/* Cyclades ACS uses both slots */
+#ifdef CONFIG_PRxK
+#define CONFIG_PCMCIA_SLOT_A
+#define CONFIG_PCMCIA_SLOT_B
+#endif
+
+#endif /* !defined(CONFIG_PCMCIA_SLOT_A) && !defined(CONFIG_PCMCIA_SLOT_B) */
+
+#if defined(CONFIG_PCMCIA_SLOT_A) && defined(CONFIG_PCMCIA_SLOT_B)
+
+#define PCMCIA_SOCKETS_NO 2
+/* We have only 8 windows, dualsocket support will be limited. */
+#define PCMCIA_MEM_WIN_NO 2
+#define PCMCIA_IO_WIN_NO 2
+#define PCMCIA_SLOT_MSG "SLOT_A and SLOT_B"
+
+#elif defined(CONFIG_PCMCIA_SLOT_A) || defined(CONFIG_PCMCIA_SLOT_B)
+
+#define PCMCIA_SOCKETS_NO 1
+/* full support for one slot */
+#define PCMCIA_MEM_WIN_NO 5
+#define PCMCIA_IO_WIN_NO 2
+
+/* define _slot_ to be able to optimize macros */
+
+#ifdef CONFIG_PCMCIA_SLOT_A
+#define _slot_ 0
+#define PCMCIA_SLOT_MSG "SLOT_A"
+#else
+#define _slot_ 1
+#define PCMCIA_SLOT_MSG "SLOT_B"
+#endif
+
+#else
+#error m8xx_pcmcia: Bad configuration!
+#endif
+
+/* ------------------------------------------------------------------------- */
+
+#define PCMCIA_MEM_WIN_BASE 0xe0000000 /* base address for memory window 0 */
+#define PCMCIA_MEM_WIN_SIZE 0x04000000 /* each memory window is 64 MByte */
+#define PCMCIA_IO_WIN_BASE _IO_BASE /* base address for io window 0 */
+
+#define PCMCIA_SCHLVL PCMCIA_INTERRUPT /* Status Change Interrupt Level */
+
+/* ------------------------------------------------------------------------- */
+
+/* 2.4.x and newer has this always in HZ */
+#define M8XX_BUSFREQ ((((bd_t *)&(__res))->bi_busfreq))
+
+static int pcmcia_schlvl = PCMCIA_SCHLVL;
+
+static spinlock_t events_lock = SPIN_LOCK_UNLOCKED;
+
+
+#define PCMCIA_SOCKET_KEY_5V 1
+#define PCMCIA_SOCKET_KEY_LV 2
+
+/* look up table for pgcrx registers */
+static u32 *m8xx_pgcrx[2] = {
+ &((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pgcra,
+ &((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pgcrb
+};
+
+/*
+ * This structure is used to address each window in the PCMCIA controller.
+ *
+ * Keep in mind that we assume that pcmcia_win[n+1] is mapped directly
+ * after pcmcia_win[n]...
+ */
+
+struct pcmcia_win {
+ u32 br;
+ u32 or;
+};
+
+/*
+ * For some reason the hardware guys decided to make both slots share
+ * some registers.
+ *
+ * Could someone invent object oriented hardware ?
+ *
+ * The macros are used to get the right bit from the registers.
+ * SLOT_A : slot = 0
+ * SLOT_B : slot = 1
+ */
+
+#define M8XX_PCMCIA_VS1(slot) (0x80000000 >> (slot << 4))
+#define M8XX_PCMCIA_VS2(slot) (0x40000000 >> (slot << 4))
+#define M8XX_PCMCIA_VS_MASK(slot) (0xc0000000 >> (slot << 4))
+#define M8XX_PCMCIA_VS_SHIFT(slot) (30 - (slot << 4))
+
+#define M8XX_PCMCIA_WP(slot) (0x20000000 >> (slot << 4))
+#define M8XX_PCMCIA_CD2(slot) (0x10000000 >> (slot << 4))
+#define M8XX_PCMCIA_CD1(slot) (0x08000000 >> (slot << 4))
+#define M8XX_PCMCIA_BVD2(slot) (0x04000000 >> (slot << 4))
+#define M8XX_PCMCIA_BVD1(slot) (0x02000000 >> (slot << 4))
+#define M8XX_PCMCIA_RDY(slot) (0x01000000 >> (slot << 4))
+#define M8XX_PCMCIA_RDY_L(slot) (0x00800000 >> (slot << 4))
+#define M8XX_PCMCIA_RDY_H(slot) (0x00400000 >> (slot << 4))
+#define M8XX_PCMCIA_RDY_R(slot) (0x00200000 >> (slot << 4))
+#define M8XX_PCMCIA_RDY_F(slot) (0x00100000 >> (slot << 4))
+#define M8XX_PCMCIA_MASK(slot) (0xFFFF0000 >> (slot << 4))
+
+#define M8XX_PCMCIA_POR_VALID 0x00000001
+#define M8XX_PCMCIA_POR_WRPROT 0x00000002
+#define M8XX_PCMCIA_POR_ATTRMEM 0x00000010
+#define M8XX_PCMCIA_POR_IO 0x00000018
+#define M8XX_PCMCIA_POR_16BIT 0x00000040
+
+#define M8XX_PGCRX(slot) m8xx_pgcrx[slot]
+
+#define M8XX_PGCRX_CXOE 0x00000080
+#define M8XX_PGCRX_CXRESET 0x00000040
+
+/* we keep one lookup table per socket to check flags */
+
+#define PCMCIA_EVENTS_MAX 5 /* 4 max at a time + termination */
+
+struct event_table {
+ u32 regbit;
+ u32 eventbit;
+};
+
+struct socket_info {
+ void (*handler)(void *info, u32 events);
+ void *info;
+
+ u32 slot;
+
+ socket_state_t state;
+ struct pccard_mem_map mem_win[PCMCIA_MEM_WIN_NO];
+ struct pccard_io_map io_win[PCMCIA_IO_WIN_NO];
+ struct event_table events[PCMCIA_EVENTS_MAX];
+ struct pcmcia_socket socket;
+};
+
+static struct socket_info socket[PCMCIA_SOCKETS_NO];
+
+/*
+ * Search this table to see if the windowsize is
+ * supported...
+ */
+
+#define M8XX_SIZES_NO 32
+
+static const u32 m8xx_size_to_gray[M8XX_SIZES_NO] =
+{
+ 0x00000001, 0x00000002, 0x00000008, 0x00000004,
+ 0x00000080, 0x00000040, 0x00000010, 0x00000020,
+ 0x00008000, 0x00004000, 0x00001000, 0x00002000,
+ 0x00000100, 0x00000200, 0x00000800, 0x00000400,
+
+ 0x0fffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0x01000000, 0x02000000, 0xffffffff, 0x04000000,
+ 0x00010000, 0x00020000, 0x00080000, 0x00040000,
+ 0x00800000, 0x00400000, 0x00100000, 0x00200000
+};
+
+/* ------------------------------------------------------------------------- */
+
+static irqreturn_t m8xx_interrupt(int irq, void *dev, struct pt_regs *regs);
+
+#define PCMCIA_BMT_LIMIT (15*4) /* Bus Monitor Timeout value */
+
+/* ------------------------------------------------------------------------- */
+/* board specific stuff: */
+/* voltage_set(), hardware_enable() and hardware_disable() */
+/* ------------------------------------------------------------------------- */
+/* RPX Boards from Embedded Planet */
+
+#if defined(CONFIG_RPXCLASSIC) || defined(CONFIG_RPXLITE)
+
+/* The RPX boards seems to have it's bus monitor timeout set to 6*8 clocks.
+ * SYPCR is write once only, therefore must the slowest memory be faster
+ * than the bus monitor or we will get a machine check due to the bus timeout.
+ */
+
+#define PCMCIA_BOARD_MSG "RPX CLASSIC or RPX LITE"
+
+#undef PCMCIA_BMT_LIMIT
+#define PCMCIA_BMT_LIMIT (6*8)
+
+static int voltage_set(int slot, int vcc, int vpp)
+{
+ u32 reg = 0;
+
+ switch(vcc) {
+ case 0: break;
+ case 33:
+ reg |= BCSR1_PCVCTL4;
+ break;
+ case 50:
+ reg |= BCSR1_PCVCTL5;
+ break;
+ default:
+ return 1;
+ }
+
+ switch(vpp) {
+ case 0: break;
+ case 33:
+ case 50:
+ if(vcc == vpp)
+ reg |= BCSR1_PCVCTL6;
+ else
+ return 1;
+ break;
+ case 120:
+ reg |= BCSR1_PCVCTL7;
+ default:
+ return 1;
+ }
+
+ if(!((vcc == 50) || (vcc == 0)))
+ return 1;
+
+ /* first, turn off all power */
+
+ out_be32(((u32 *)RPX_CSR_ADDR), in_be32(((u32 *)RPX_CSR_ADDR)) & ~(BCSR1_PCVCTL4 | BCSR1_PCVCTL5 | BCSR1_PCVCTL6 | BCSR1_PCVCTL7));
+
+ /* enable new powersettings */
+
+ out_be32(((u32 *)RPX_CSR_ADDR), in_be32(((u32 *)RPX_CSR_ADDR)) | reg);
+
+ return 0;
+}
+
+#define socket_get(_slot_) PCMCIA_SOCKET_KEY_5V
+#define hardware_enable(_slot_) /* No hardware to enable */
+#define hardware_disable(_slot_) /* No hardware to disable */
+
+#endif /* CONFIG_RPXCLASSIC */
+
+/* FADS Boards from Motorola */
+
+#if defined(CONFIG_FADS)
+
+#define PCMCIA_BOARD_MSG "FADS"
+
+static int voltage_set(int slot, int vcc, int vpp)
+{
+ u32 reg = 0;
+
+ switch(vcc) {
+ case 0:
+ break;
+ case 33:
+ reg |= BCSR1_PCCVCC0;
+ break;
+ case 50:
+ reg |= BCSR1_PCCVCC1;
+ break;
+ default:
+ return 1;
+ }
+
+ switch(vpp) {
+ case 0:
+ break;
+ case 33:
+ case 50:
+ if(vcc == vpp)
+ reg |= BCSR1_PCCVPP1;
+ else
+ return 1;
+ break;
+ case 120:
+ if ((vcc == 33) || (vcc == 50))
+ reg |= BCSR1_PCCVPP0;
+ else
+ return 1;
+ default:
+ return 1;
+ }
+
+ /* first, turn off all power */
+ out_be32(&((u32 *)BCSR1), in_be32(&((u32 *)BCSR1)) & ~(BCSR1_PCCVCC_MASK | BCSR1_PCCVPP_MASK));
+
+ /* enable new powersettings */
+ out_be32(&((u32 *)BCSR1), in_be32(&((u32 *)BCSR1)) | reg);
+
+ return 0;
+}
+
+#define socket_get(_slot_) PCMCIA_SOCKET_KEY_5V
+
+static void hardware_enable(int slot)
+{
+ out_be32(&((u32 *)BCSR1), in_be32(&((u32 *)BCSR1)) & ~BCSR1_PCCEN);
+}
+
+static void hardware_disable(int slot)
+{
+ out_be32(&((u32 *)BCSR1), in_be32(&((u32 *)BCSR1)) | BCSR1_PCCEN);
+}
+
+#endif
+
+/* ------------------------------------------------------------------------- */
+/* Motorola MBX860 */
+
+#if defined(CONFIG_MBX)
+
+#define PCMCIA_BOARD_MSG "MBX"
+
+static int voltage_set(int slot, int vcc, int vpp)
+{
+ u8 reg = 0;
+
+ switch(vcc) {
+ case 0:
+ break;
+ case 33:
+ reg |= CSR2_VCC_33;
+ break;
+ case 50:
+ reg |= CSR2_VCC_50;
+ break;
+ default:
+ return 1;
+ }
+
+ switch(vpp) {
+ case 0:
+ break;
+ case 33:
+ case 50:
+ if(vcc == vpp)
+ reg |= CSR2_VPP_VCC;
+ else
+ return 1;
+ break;
+ case 120:
+ if ((vcc == 33) || (vcc == 50))
+ reg |= CSR2_VPP_12;
+ else
+ return 1;
+ default:
+ return 1;
+ }
+
+ /* first, turn off all power */
+ out_8(&((u8 *)MBX_CSR2_ADDR), in_8(&((u8 *)MBX_CSR2_ADDR)) & ~(CSR2_VCC_MASK | CSR2_VPP_MASK));
+
+ /* enable new powersettings */
+ out_8(&((u8 *)MBX_CSR2_ADDR), in_8(&((u8 *)MBX_CSR2_ADDR)) | reg);
+
+ return 0;
+}
+
+#define socket_get(_slot_) PCMCIA_SOCKET_KEY_5V
+#define hardware_enable(_slot_) /* No hardware to enable */
+#define hardware_disable(_slot_) /* No hardware to disable */
+
+#endif /* CONFIG_MBX */
+
+#if defined(CONFIG_PRxK)
+#include <asm/cpld.h>
+extern volatile fpga_pc_regs *fpga_pc;
+
+#define PCMCIA_BOARD_MSG "MPC855T"
+
+static int voltage_set(int slot, int vcc, int vpp)
+{
+ u8 reg = 0;
+ u8 regread;
+ cpld_regs *ccpld = get_cpld();
+
+ switch(vcc) {
+ case 0:
+ break;
+ case 33:
+ reg |= PCMCIA_VCC_33;
+ break;
+ case 50:
+ reg |= PCMCIA_VCC_50;
+ break;
+ default:
+ return 1;
+ }
+
+ switch(vpp) {
+ case 0:
+ break;
+ case 33:
+ case 50:
+ if(vcc == vpp)
+ reg |= PCMCIA_VPP_VCC;
+ else
+ return 1;
+ break;
+ case 120:
+ if ((vcc == 33) || (vcc == 50))
+ reg |= PCMCIA_VPP_12;
+ else
+ return 1;
+ default:
+ return 1;
+ }
+
+ reg = reg >> (slot << 2);
+ regread = in_8(&ccpld->fpga_pc_ctl);
+ if (reg != (regread & ((PCMCIA_VCC_MASK | PCMCIA_VPP_MASK) >> (slot << 2)))) {
+ /* enable new powersettings */
+ regread = regread & ~((PCMCIA_VCC_MASK | PCMCIA_VPP_MASK) >> (slot << 2));
+ out_8(&ccpld->fpga_pc_ctl, reg | regread);
+ msleep(100);
+ }
+
+ return 0;
+}
+
+#define socket_get(_slot_) PCMCIA_SOCKET_KEY_LV
+#define hardware_enable(_slot_) /* No hardware to enable */
+#define hardware_disable(_slot_) /* No hardware to disable */
+
+#endif /* CONFIG_PRxK */
+
+static void m8xx_shutdown(void)
+{
+ u32 m, i;
+ struct pcmcia_win *w;
+
+ for(i = 0; i < PCMCIA_SOCKETS_NO; i++){
+ w = (void *) &((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pbr0;
+
+ out_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pscr, M8XX_PCMCIA_MASK(i));
+ out_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_per, in_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_per) & ~M8XX_PCMCIA_MASK(i));
+
+ /* turn off interrupt and disable CxOE */
+ out_be32(M8XX_PGCRX(i), M8XX_PGCRX_CXOE);
+
+ /* turn off memory windows */
+ for(m = 0; m < PCMCIA_MEM_WIN_NO; m++) {
+ out_be32(&w->or, 0); /* set to not valid */
+ w++;
+ }
+
+ /* turn off voltage */
+ voltage_set(i, 0, 0);
+
+ /* disable external hardware */
+ hardware_disable(i);
+ }
+
+ free_irq(pcmcia_schlvl, NULL);
+}
+
+static struct device_driver m8xx_driver = {
+ .name = "m8xx-pcmcia",
+ .bus = &platform_bus_type,
+ .suspend = pcmcia_socket_dev_suspend,
+ .resume = pcmcia_socket_dev_resume,
+};
+
+static struct platform_device m8xx_device = {
+ .name = "m8xx-pcmcia",
+ .id = 0,
+};
+
+static u32 pending_events[PCMCIA_SOCKETS_NO];
+static spinlock_t pending_event_lock = SPIN_LOCK_UNLOCKED;
+
+static irqreturn_t m8xx_interrupt(int irq, void *dev, struct pt_regs *regs)
+{
+ struct socket_info *s;
+ struct event_table *e;
+ unsigned int i, events, pscr, pipr, per;
+
+ dprintk("Interrupt!\n");
+ /* get interrupt sources */
+
+ pscr = in_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pscr);
+ pipr = in_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pipr);
+ per = in_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_per);
+
+ for(i = 0; i < PCMCIA_SOCKETS_NO; i++) {
+ s = &socket[i];
+ e = &s->events[0];
+ events = 0;
+
+ while(e->regbit) {
+ if(pscr & e->regbit)
+ events |= e->eventbit;
+
+ e++;
+ }
+
+ /*
+ * report only if both card detect signals are the same
+ * not too nice done,
+ * we depend on that CD2 is the bit to the left of CD1...
+ */
+ if(events & SS_DETECT)
+ if(((pipr & M8XX_PCMCIA_CD2(i)) >> 1) ^
+ (pipr & M8XX_PCMCIA_CD1(i)))
+ {
+ events &= ~SS_DETECT;
+ }
+
+#ifdef PCMCIA_GLITCHY_CD
+ /*
+ * I've experienced CD problems with my ADS board.
+ * We make an extra check to see if there was a
+ * real change of Card detection.
+ */
+
+ if((events & SS_DETECT) &&
+ ((pipr &
+ (M8XX_PCMCIA_CD2(i) | M8XX_PCMCIA_CD1(i))) == 0) &&
+ (s->state.Vcc | s->state.Vpp)) {
+ events &= ~SS_DETECT;
+ /*printk( "CD glitch workaround - CD = 0x%08x!\n",
+ (pipr & (M8XX_PCMCIA_CD2(i)
+ | M8XX_PCMCIA_CD1(i))));*/
+ }
+#endif
+
+ /* call the handler */
+
+ dprintk("slot %u: events = 0x%02x, pscr = 0x%08x, "
+ "pipr = 0x%08x\n",
+ i, events, pscr, pipr);
+
+ if(events) {
+ spin_lock(&pending_event_lock);
+ pending_events[i] |= events;
+ spin_unlock(&pending_event_lock);
+ /*
+ * Turn off RDY_L bits in the PER mask on
+ * CD interrupt receival.
+ *
+ * They can generate bad interrupts on the
+ * ACS4,8,16,32. - marcelo
+ */
+ per &= ~M8XX_PCMCIA_RDY_L(0);
+ per &= ~M8XX_PCMCIA_RDY_L(1);
+
+ out_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_per, per);
+
+ if (events)
+ pcmcia_parse_events(&socket[i].socket, events);
+ }
+ }
+
+ /* clear the interrupt sources */
+ out_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pscr, pscr);
+
+ dprintk("Interrupt done.\n");
+
+ return IRQ_HANDLED;
+}
+
+static u32 m8xx_get_graycode(u32 size)
+{
+ u32 k;
+
+ for(k = 0; k < M8XX_SIZES_NO; k++)
+ if(m8xx_size_to_gray[k] == size)
+ break;
+
+ if((k == M8XX_SIZES_NO) || (m8xx_size_to_gray[k] == -1))
+ k = -1;
+
+ return k;
+}
+
+static u32 m8xx_get_speed(u32 ns, u32 is_io)
+{
+ u32 reg, clocks, psst, psl, psht;
+
+ if(!ns) {
+
+ /*
+ * We get called with IO maps setup to 0ns
+ * if not specified by the user.
+ * They should be 255ns.
+ */
+
+ if(is_io)
+ ns = 255;
+ else
+ ns = 100; /* fast memory if 0 */
+ }
+
+ /*
+ * In PSST, PSL, PSHT fields we tell the controller
+ * timing parameters in CLKOUT clock cycles.
+ * CLKOUT is the same as GCLK2_50.
+ */
+
+/* how we want to adjust the timing - in percent */
+
+#define ADJ 180 /* 80 % longer accesstime - to be sure */
+
+ clocks = ((M8XX_BUSFREQ / 1000) * ns) / 1000;
+ clocks = (clocks * ADJ) / (100*1000);
+ if(clocks >= PCMCIA_BMT_LIMIT) {
+ printk( "Max access time limit reached\n");
+ clocks = PCMCIA_BMT_LIMIT-1;
+ }
+
+ psst = clocks / 7; /* setup time */
+ psht = clocks / 7; /* hold time */
+ psl = (clocks * 5) / 7; /* strobe length */
+
+ psst += clocks - (psst + psht + psl);
+
+ reg = psst << 12;
+ reg |= psl << 7;
+ reg |= psht << 16;
+
+ return reg;
+}
+
+static int m8xx_get_status(struct pcmcia_socket *sock, unsigned int *value)
+{
+ int lsock = container_of(sock, struct socket_info, socket)->slot;
+ struct socket_info *s = &socket[lsock];
+ unsigned int pipr, reg;
+
+ pipr = in_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pipr);
+
+ *value = ((pipr & (M8XX_PCMCIA_CD1(lsock)
+ | M8XX_PCMCIA_CD2(lsock))) == 0) ? SS_DETECT : 0;
+ *value |= (pipr & M8XX_PCMCIA_WP(lsock)) ? SS_WRPROT : 0;
+
+ if (s->state.flags & SS_IOCARD)
+ *value |= (pipr & M8XX_PCMCIA_BVD1(lsock)) ? SS_STSCHG : 0;
+ else {
+ *value |= (pipr & M8XX_PCMCIA_RDY(lsock)) ? SS_READY : 0;
+ *value |= (pipr & M8XX_PCMCIA_BVD1(lsock)) ? SS_BATDEAD : 0;
+ *value |= (pipr & M8XX_PCMCIA_BVD2(lsock)) ? SS_BATWARN : 0;
+ }
+
+ if (s->state.Vcc | s->state.Vpp)
+ *value |= SS_POWERON;
+
+ /*
+ * Voltage detection:
+ * This driver only supports 16-Bit pc-cards.
+ * Cardbus is not handled here.
+ *
+ * To determine what voltage to use we must read the VS1 and VS2 pin.
+ * Depending on what socket type is present,
+ * different combinations mean different things.
+ *
+ * Card Key Socket Key VS1 VS2 Card Vcc for CIS parse
+ *
+ * 5V 5V, LV* NC NC 5V only 5V (if available)
+ *
+ * 5V 5V, LV* GND NC 5 or 3.3V as low as possible
+ *
+ * 5V 5V, LV* GND GND 5, 3.3, x.xV as low as possible
+ *
+ * LV* 5V - - shall not fit into socket
+ *
+ * LV* LV* GND NC 3.3V only 3.3V
+ *
+ * LV* LV* NC GND x.xV x.xV (if avail.)
+ *
+ * LV* LV* GND GND 3.3 or x.xV as low as possible
+ *
+ * *LV means Low Voltage
+ *
+ *
+ * That gives us the following table:
+ *
+ * Socket VS1 VS2 Voltage
+ *
+ * 5V NC NC 5V
+ * 5V NC GND none (should not be possible)
+ * 5V GND NC >= 3.3V
+ * 5V GND GND >= x.xV
+ *
+ * LV NC NC 5V (if available)
+ * LV NC GND x.xV (if available)
+ * LV GND NC 3.3V
+ * LV GND GND >= x.xV
+ *
+ * So, how do I determine if I have a 5V or a LV
+ * socket on my board? Look at the socket!
+ *
+ *
+ * Socket with 5V key:
+ * ++--------------------------------------------+
+ * || |
+ * || ||
+ * || ||
+ * | |
+ * +---------------------------------------------+
+ *
+ * Socket with LV key:
+ * ++--------------------------------------------+
+ * || |
+ * | ||
+ * | ||
+ * | |
+ * +---------------------------------------------+
+ *
+ *
+ * With other words - LV only cards does not fit
+ * into the 5V socket!
+ */
+
+ /* read out VS1 and VS2 */
+
+ reg = (pipr & M8XX_PCMCIA_VS_MASK(lsock))
+ >> M8XX_PCMCIA_VS_SHIFT(lsock);
+
+ if(socket_get(lsock) == PCMCIA_SOCKET_KEY_LV) {
+ switch(reg) {
+ case 1:
+ *value |= SS_3VCARD;
+ break; /* GND, NC - 3.3V only */
+ case 2:
+ *value |= SS_XVCARD;
+ break; /* NC. GND - x.xV only */
+ };
+ }
+
+ dprintk("GetStatus(%d) = %#2.2x\n", lsock, *value);
+ return 0;
+}
+
+static int m8xx_get_socket(struct pcmcia_socket *sock, socket_state_t *state)
+{
+ int lsock = container_of(sock, struct socket_info, socket)->slot;
+ *state = socket[lsock].state; /* copy the whole structure */
+
+ dprintk("GetSocket(%d) = flags %#3.3x, Vcc %d, Vpp %d, "
+ "io_irq %d, csc_mask %#2.2x\n", lsock, state->flags,
+ state->Vcc, state->Vpp, state->io_irq, state->csc_mask);
+ return 0;
+}
+
+static int m8xx_set_socket(struct pcmcia_socket *sock, socket_state_t *state)
+{
+ int lsock = container_of(sock, struct socket_info, socket)->slot;
+ struct socket_info *s = &socket[lsock];
+ struct event_table *e;
+ unsigned int reg;
+ unsigned long flags;
+
+ dprintk( "SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, "
+ "io_irq %d, csc_mask %#2.2x)\n", lsock, state->flags,
+ state->Vcc, state->Vpp, state->io_irq, state->csc_mask);
+
+ /* First, set voltage - bail out if invalid */
+ if(voltage_set(lsock, state->Vcc, state->Vpp))
+ return -EINVAL;
+
+ /* Take care of reset... */
+ if(state->flags & SS_RESET)
+ out_be32(M8XX_PGCRX(lsock), in_be32(M8XX_PGCRX(lsock)) | M8XX_PGCRX_CXRESET); /* active high */
+ else
+ out_be32(M8XX_PGCRX(lsock), in_be32(M8XX_PGCRX(lsock)) & ~M8XX_PGCRX_CXRESET);
+
+ /* ... and output enable. */
+
+ /* The CxOE signal is connected to a 74541 on the ADS.
+ I guess most other boards used the ADS as a reference.
+ I tried to control the CxOE signal with SS_OUTPUT_ENA,
+ but the reset signal seems connected via the 541.
+ If the CxOE is left high are some signals tristated and
+ no pullups are present -> the cards act wierd.
+ So right now the buffers are enabled if the power is on. */
+
+ if(state->Vcc || state->Vpp)
+ out_be32(M8XX_PGCRX(lsock), in_be32(M8XX_PGCRX(lsock)) & ~M8XX_PGCRX_CXOE); /* active low */
+ else
+ out_be32(M8XX_PGCRX(lsock), in_be32(M8XX_PGCRX(lsock)) | M8XX_PGCRX_CXOE);
+
+ /*
+ * We'd better turn off interrupts before
+ * we mess with the events-table..
+ */
+
+ spin_lock_irqsave(&events_lock, flags);
+
+ /*
+ * Play around with the interrupt mask to be able to
+ * give the events the generic pcmcia driver wants us to.
+ */
+
+ e = &s->events[0];
+ reg = 0;
+
+ if(state->csc_mask & SS_DETECT) {
+ e->eventbit = SS_DETECT;
+ reg |= e->regbit = (M8XX_PCMCIA_CD2(lsock)
+ | M8XX_PCMCIA_CD1(lsock));
+ e++;
+ }
+ if(state->flags & SS_IOCARD) {
+ /*
+ * I/O card
+ */
+ if(state->csc_mask & SS_STSCHG) {
+ e->eventbit = SS_STSCHG;
+ reg |= e->regbit = M8XX_PCMCIA_BVD1(lsock);
+ e++;
+ }
+ /*
+ * If io_irq is non-zero we should enable irq.
+ */
+ if(state->io_irq) {
+ out_be32(M8XX_PGCRX(lsock), in_be32(M8XX_PGCRX(lsock)) | mk_int_int_mask(state->io_irq) << 24);
+ /*
+ * Strange thing here:
+ * The manual does not tell us which interrupt
+ * the sources generate.
+ * Anyhow, I found out that RDY_L generates IREQLVL.
+ *
+ * We use level triggerd interrupts, and they don't
+ * have to be cleared in PSCR in the interrupt handler.
+ */
+ reg |= M8XX_PCMCIA_RDY_L(lsock);
+ }
+ else
+ out_be32(M8XX_PGCRX(lsock), in_be32(M8XX_PGCRX(lsock)) & 0x00ffffff);
+ }
+ else {
+ /*
+ * Memory card
+ */
+ if(state->csc_mask & SS_BATDEAD) {
+ e->eventbit = SS_BATDEAD;
+ reg |= e->regbit = M8XX_PCMCIA_BVD1(lsock);
+ e++;
+ }
+ if(state->csc_mask & SS_BATWARN) {
+ e->eventbit = SS_BATWARN;
+ reg |= e->regbit = M8XX_PCMCIA_BVD2(lsock);
+ e++;
+ }
+ /* What should I trigger on - low/high,raise,fall? */
+ if(state->csc_mask & SS_READY) {
+ e->eventbit = SS_READY;
+ reg |= e->regbit = 0; //??
+ e++;
+ }
+ }
+
+ e->regbit = 0; /* terminate list */
+
+ /*
+ * Clear the status changed .
+ * Port A and Port B share the same port.
+ * Writing ones will clear the bits.
+ */
+
+ out_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pscr, reg);
+
+ /*
+ * Write the mask.
+ * Port A and Port B share the same port.
+ * Need for read-modify-write.
+ * Ones will enable the interrupt.
+ */
+
+ /*
+ reg |= ((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_per
+ & M8XX_PCMCIA_MASK(lsock);
+ */
+
+ reg |= in_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_per) &
+ (M8XX_PCMCIA_MASK(0) | M8XX_PCMCIA_MASK(1));
+
+ out_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_per, reg);
+
+ spin_unlock_irqrestore(&events_lock, flags);
+
+ /* copy the struct and modify the copy */
+
+ s->state = *state;
+
+ return 0;
+}
+
+static int m8xx_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *io)
+{
+ int lsock = container_of(sock, struct socket_info, socket)->slot;
+
+ struct socket_info *s = &socket[lsock];
+ struct pcmcia_win *w;
+ unsigned int reg, winnr;
+
+#define M8XX_SIZE (io->stop - io->start + 1)
+#define M8XX_BASE (PCMCIA_IO_WIN_BASE + io->start)
+
+ dprintk( "SetIOMap(%d, %d, %#2.2x, %d ns, "
+ "%#4.4x-%#4.4x)\n", lsock, io->map, io->flags,
+ io->speed, io->start, io->stop);
+
+ if ((io->map >= PCMCIA_IO_WIN_NO) || (io->start > 0xffff)
+ || (io->stop > 0xffff) || (io->stop < io->start))
+ return -EINVAL;
+
+ if((reg = m8xx_get_graycode(M8XX_SIZE)) == -1)
+ return -EINVAL;
+
+ if(io->flags & MAP_ACTIVE) {
+
+ dprintk( "io->flags & MAP_ACTIVE\n");
+
+ winnr = (PCMCIA_MEM_WIN_NO * PCMCIA_SOCKETS_NO)
+ + (lsock * PCMCIA_IO_WIN_NO) + io->map;
+
+ /* setup registers */
+
+ w = (void *) &((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pbr0;
+ w += winnr;
+
+ out_be32(&w->or, 0); /* turn off window first */
+ out_be32(&w->br, M8XX_BASE);
+
+ reg <<= 27;
+ reg |= M8XX_PCMCIA_POR_IO |(lsock << 2);
+
+ reg |= m8xx_get_speed(io->speed, 1);
+
+ if(io->flags & MAP_WRPROT)
+ reg |= M8XX_PCMCIA_POR_WRPROT;
+
+ /*if(io->flags & (MAP_16BIT | MAP_AUTOSZ))*/
+ if(io->flags & MAP_16BIT)
+ reg |= M8XX_PCMCIA_POR_16BIT;
+
+ if(io->flags & MAP_ACTIVE)
+ reg |= M8XX_PCMCIA_POR_VALID;
+
+ out_be32(&w->or, reg);
+
+ dprintk("Socket %u: Mapped io window %u at %#8.8x, "
+ "OR = %#8.8x.\n", lsock, io->map, w->br, w->or);
+ } else {
+ /* shutdown IO window */
+ winnr = (PCMCIA_MEM_WIN_NO * PCMCIA_SOCKETS_NO)
+ + (lsock * PCMCIA_IO_WIN_NO) + io->map;
+
+ /* setup registers */
+
+ w = (void *) &((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pbr0;
+ w += winnr;
+
+ out_be32(&w->or, 0); /* turn off window */
+ out_be32(&w->br, 0); /* turn off base address */
+
+ dprintk("Socket %u: Unmapped io window %u at %#8.8x, "
+ "OR = %#8.8x.\n", lsock, io->map, w->br, w->or);
+ }
+
+ /* copy the struct and modify the copy */
+ s->io_win[io->map] = *io;
+ s->io_win[io->map].flags &= (MAP_WRPROT
+ | MAP_16BIT
+ | MAP_ACTIVE);
+ dprintk("SetIOMap exit\n");
+
+ return 0;
+}
+
+static int m8xx_set_mem_map(struct pcmcia_socket *sock, struct pccard_mem_map *mem)
+{
+ int lsock = container_of(sock, struct socket_info, socket)->slot;
+ struct socket_info *s = &socket[lsock];
+ struct pcmcia_win *w;
+ struct pccard_mem_map *old;
+ unsigned int reg, winnr;
+
+ dprintk( "SetMemMap(%d, %d, %#2.2x, %d ns, "
+ "%#5.5lx, %#5.5x)\n", lsock, mem->map, mem->flags,
+ mem->speed, mem->static_start, mem->card_start);
+
+ if ((mem->map >= PCMCIA_MEM_WIN_NO)
+// || ((mem->s) >= PCMCIA_MEM_WIN_SIZE)
+ || (mem->card_start >= 0x04000000)
+ || (mem->static_start & 0xfff) /* 4KByte resolution */
+ || (mem->card_start & 0xfff))
+ return -EINVAL;
+
+ if((reg = m8xx_get_graycode(PCMCIA_MEM_WIN_SIZE)) == -1) {
+ printk( "Cannot set size to 0x%08x.\n", PCMCIA_MEM_WIN_SIZE);
+ return -EINVAL;
+ }
+ reg <<= 27;
+
+ winnr = (lsock * PCMCIA_MEM_WIN_NO) + mem->map;
+
+ /* Setup the window in the pcmcia controller */
+
+ w = (void *) &((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pbr0;
+ w += winnr;
+
+ reg |= lsock << 2;
+
+ reg |= m8xx_get_speed(mem->speed, 0);
+
+ if(mem->flags & MAP_ATTRIB)
+ reg |= M8XX_PCMCIA_POR_ATTRMEM;
+
+ if(mem->flags & MAP_WRPROT)
+ reg |= M8XX_PCMCIA_POR_WRPROT;
+
+ if(mem->flags & MAP_16BIT)
+ reg |= M8XX_PCMCIA_POR_16BIT;
+
+ if(mem->flags & MAP_ACTIVE)
+ reg |= M8XX_PCMCIA_POR_VALID;
+
+ out_be32(&w->or, reg);
+
+ dprintk("Socket %u: Mapped memory window %u at %#8.8x, "
+ "OR = %#8.8x.\n", lsock, mem->map, w->br, w->or);
+
+ if(mem->flags & MAP_ACTIVE) {
+ /* get the new base address */
+ mem->static_start = PCMCIA_MEM_WIN_BASE +
+ (PCMCIA_MEM_WIN_SIZE * winnr)
+ + mem->card_start;
+ }
+
+ dprintk("SetMemMap(%d, %d, %#2.2x, %d ns, "
+ "%#5.5lx, %#5.5x)\n", lsock, mem->map, mem->flags,
+ mem->speed, mem->static_start, mem->card_start);
+
+ /* copy the struct and modify the copy */
+
+ old = &s->mem_win[mem->map];
+
+ *old = *mem;
+ old->flags &= (MAP_ATTRIB
+ | MAP_WRPROT
+ | MAP_16BIT
+ | MAP_ACTIVE);
+
+ return 0;
+}
+
+static int m8xx_sock_init(struct pcmcia_socket *sock)
+{
+ int i;
+ pccard_io_map io = { 0, 0, 0, 0, 1 };
+ pccard_mem_map mem = { 0, 0, 0, 0, 0, 0 };
+
+ dprintk( "sock_init(%d)\n", s);
+
+ m8xx_set_socket(sock, &dead_socket);
+ for (i = 0; i < PCMCIA_IO_WIN_NO; i++) {
+ io.map = i;
+ m8xx_set_io_map(sock, &io);
+ }
+ for (i = 0; i < PCMCIA_MEM_WIN_NO; i++) {
+ mem.map = i;
+ m8xx_set_mem_map(sock, &mem);
+ }
+
+ return 0;
+
+}
+
+static int m8xx_suspend(struct pcmcia_socket *sock)
+{
+ return m8xx_set_socket(sock, &dead_socket);
+}
+
+static struct pccard_operations m8xx_services = {
+ .init = m8xx_sock_init,
+ .suspend = m8xx_suspend,
+ .get_status = m8xx_get_status,
+ .get_socket = m8xx_get_socket,
+ .set_socket = m8xx_set_socket,
+ .set_io_map = m8xx_set_io_map,
+ .set_mem_map = m8xx_set_mem_map,
+};
+
+static int __init m8xx_init(void)
+{
+ struct pcmcia_win *w;
+ unsigned int i,m;
+
+ pcmcia_info("%s\n", version);
+
+ if (driver_register(&m8xx_driver))
+ return -1;
+
+ pcmcia_info(PCMCIA_BOARD_MSG " using " PCMCIA_SLOT_MSG
+ " with IRQ %u.\n", pcmcia_schlvl);
+
+ /* Configure Status change interrupt */
+
+ if(request_irq(pcmcia_schlvl, m8xx_interrupt, 0,
+ "m8xx_pcmcia", NULL)) {
+ pcmcia_error("Cannot allocate IRQ %u for SCHLVL!\n",
+ pcmcia_schlvl);
+ return -1;
+ }
+
+ w = (void *) &((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pbr0;
+
+ out_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pscr,
+ M8XX_PCMCIA_MASK(0)| M8XX_PCMCIA_MASK(1));
+
+ out_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_per,
+ in_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_per) &
+ ~(M8XX_PCMCIA_MASK(0)| M8XX_PCMCIA_MASK(1)));
+
+/* connect interrupt and disable CxOE */
+
+ out_be32(M8XX_PGCRX(0), M8XX_PGCRX_CXOE | (mk_int_int_mask(pcmcia_schlvl) << 16));
+ out_be32(M8XX_PGCRX(1), M8XX_PGCRX_CXOE | (mk_int_int_mask(pcmcia_schlvl) << 16));
+
+/* intialize the fixed memory windows */
+
+ for(i = 0; i < PCMCIA_SOCKETS_NO; i++){
+ for(m = 0; m < PCMCIA_MEM_WIN_NO; m++) {
+ out_be32(&w->br, PCMCIA_MEM_WIN_BASE +
+ (PCMCIA_MEM_WIN_SIZE
+ * (m + i * PCMCIA_MEM_WIN_NO)));
+
+ out_be32(&w->or, 0); /* set to not valid */
+
+ w++;
+ }
+ }
+
+/* turn off voltage */
+ voltage_set(0, 0, 0);
+ voltage_set(1, 0, 0);
+
+/* Enable external hardware */
+ hardware_enable(0);
+ hardware_enable(1);
+
+ platform_device_register(&m8xx_device);
+
+ for (i = 0 ; i < PCMCIA_SOCKETS_NO; i++) {
+ socket[i].slot = i;
+ socket[i].socket.owner = THIS_MODULE;
+ socket[i].socket.features = SS_CAP_PCCARD | SS_CAP_MEM_ALIGN | SS_CAP_STATIC_MAP;
+ socket[i].socket.irq_mask = 0x000;
+ socket[i].socket.map_size = 0x1000;
+ socket[i].socket.io_offset = 0;
+ socket[i].socket.pci_irq = i ? 7 : 9;
+ socket[i].socket.ops = &m8xx_services;
+ socket[i].socket.resource_ops = &pccard_nonstatic_ops;
+ socket[i].socket.cb_dev = NULL;
+ socket[i].socket.dev.dev = &m8xx_device.dev;
+ }
+
+ for (i = 0; i < PCMCIA_SOCKETS_NO; i++)
+ pcmcia_register_socket(&socket[i].socket);
+
+ return 0;
+}
+
+static void __exit m8xx_exit(void)
+{
+ int i;
+
+ for (i = 0; i < PCMCIA_SOCKETS_NO; i++)
+ pcmcia_unregister_socket(&socket[i].socket);
+
+ m8xx_shutdown();
+
+ platform_device_unregister(&m8xx_device);
+ driver_unregister(&m8xx_driver);
+}
+
+module_init(m8xx_init);
+module_exit(m8xx_exit);
diff --git a/drivers/pcmcia/omap_cf.c b/drivers/pcmcia/omap_cf.c
index 94be9e51654e..47b5ade95bde 100644
--- a/drivers/pcmcia/omap_cf.c
+++ b/drivers/pcmcia/omap_cf.c
@@ -12,7 +12,7 @@
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/sched.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/delay.h>
@@ -329,27 +329,13 @@ static int __devexit omap_cf_remove(struct device *dev)
return 0;
}
-static int omap_cf_suspend(struct device *dev, pm_message_t mesg, u32 level)
-{
- if (level != SUSPEND_SAVE_STATE)
- return 0;
- return pcmcia_socket_dev_suspend(dev, mesg);
-}
-
-static int omap_cf_resume(struct device *dev, u32 level)
-{
- if (level != RESUME_RESTORE_STATE)
- return 0;
- return pcmcia_socket_dev_resume(dev);
-}
-
static struct device_driver omap_cf_driver = {
.name = (char *) driver_name,
.bus = &platform_bus_type,
.probe = omap_cf_probe,
.remove = __devexit_p(omap_cf_remove),
- .suspend = omap_cf_suspend,
- .resume = omap_cf_resume,
+ .suspend = pcmcia_socket_dev_suspend,
+ .resume = pcmcia_socket_dev_resume,
};
static int __init omap_cf_init(void)
diff --git a/drivers/pcmcia/pxa2xx_base.c b/drivers/pcmcia/pxa2xx_base.c
index 325c992f7d8f..7fa18fb814bc 100644
--- a/drivers/pcmcia/pxa2xx_base.c
+++ b/drivers/pcmcia/pxa2xx_base.c
@@ -23,6 +23,7 @@
#include <linux/ioport.h>
#include <linux/kernel.h>
#include <linux/spinlock.h>
+#include <linux/platform_device.h>
#include <asm/hardware.h>
#include <asm/io.h>
@@ -205,32 +206,20 @@ int pxa2xx_drv_pcmcia_probe(struct device *dev)
}
EXPORT_SYMBOL(pxa2xx_drv_pcmcia_probe);
-static int pxa2xx_drv_pcmcia_suspend(struct device *dev, pm_message_t state, u32 level)
+static int pxa2xx_drv_pcmcia_resume(struct device *dev)
{
- int ret = 0;
- if (level == SUSPEND_SAVE_STATE)
- ret = pcmcia_socket_dev_suspend(dev, state);
- return ret;
-}
+ struct pcmcia_low_level *ops = dev->platform_data;
+ int nr = ops ? ops->nr : 0;
-static int pxa2xx_drv_pcmcia_resume(struct device *dev, u32 level)
-{
- int ret = 0;
- if (level == RESUME_RESTORE_STATE)
- {
- struct pcmcia_low_level *ops = dev->platform_data;
- int nr = ops ? ops->nr : 0;
-
- MECR = nr > 1 ? MECR_CIT | MECR_NOS : (nr > 0 ? MECR_CIT : 0);
- ret = pcmcia_socket_dev_resume(dev);
- }
- return ret;
+ MECR = nr > 1 ? MECR_CIT | MECR_NOS : (nr > 0 ? MECR_CIT : 0);
+
+ return pcmcia_socket_dev_resume(dev);
}
static struct device_driver pxa2xx_pcmcia_driver = {
.probe = pxa2xx_drv_pcmcia_probe,
.remove = soc_common_drv_pcmcia_remove,
- .suspend = pxa2xx_drv_pcmcia_suspend,
+ .suspend = pcmcia_socket_dev_suspend,
.resume = pxa2xx_drv_pcmcia_resume,
.name = "pxa2xx-pcmcia",
.bus = &platform_bus_type,
diff --git a/drivers/pcmcia/pxa2xx_mainstone.c b/drivers/pcmcia/pxa2xx_mainstone.c
index bbe69b07ce50..5209d8c7764f 100644
--- a/drivers/pcmcia/pxa2xx_mainstone.c
+++ b/drivers/pcmcia/pxa2xx_mainstone.c
@@ -17,7 +17,7 @@
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/interrupt.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <pcmcia/ss.h>
diff --git a/drivers/pcmcia/pxa2xx_sharpsl.c b/drivers/pcmcia/pxa2xx_sharpsl.c
index a1178a600e3c..56c58831e80e 100644
--- a/drivers/pcmcia/pxa2xx_sharpsl.c
+++ b/drivers/pcmcia/pxa2xx_sharpsl.c
@@ -16,17 +16,26 @@
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/interrupt.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <asm/mach-types.h>
#include <asm/hardware.h>
#include <asm/irq.h>
#include <asm/hardware/scoop.h>
-#include <asm/arch/pxa-regs.h>
#include "soc_common.h"
#define NO_KEEP_VS 0x0001
+/* PCMCIA to Scoop linkage
+
+ There is no easy way to link multiple scoop devices into one
+ single entity for the pxa2xx_pcmcia device so this structure
+ is used which is setup by the platform code
+*/
+struct scoop_pcmcia_config *platform_scoop_config;
+#define SCOOP_DEV platform_scoop_config->devs
+
static void sharpsl_pcmcia_init_reset(struct scoop_pcmcia_dev *scoopdev)
{
reset_scoop(scoopdev->dev);
@@ -38,36 +47,16 @@ static int sharpsl_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
{
int ret;
- /*
- * Setup default state of GPIO outputs
- * before we enable them as outputs.
- */
- GPSR(GPIO48_nPOE) =
- GPIO_bit(GPIO48_nPOE) |
- GPIO_bit(GPIO49_nPWE) |
- GPIO_bit(GPIO50_nPIOR) |
- GPIO_bit(GPIO51_nPIOW) |
- GPIO_bit(GPIO52_nPCE_1) |
- GPIO_bit(GPIO53_nPCE_2);
-
- pxa_gpio_mode(GPIO48_nPOE_MD);
- pxa_gpio_mode(GPIO49_nPWE_MD);
- pxa_gpio_mode(GPIO50_nPIOR_MD);
- pxa_gpio_mode(GPIO51_nPIOW_MD);
- pxa_gpio_mode(GPIO52_nPCE_1_MD);
- pxa_gpio_mode(GPIO53_nPCE_2_MD);
- pxa_gpio_mode(GPIO54_pSKTSEL_MD);
- pxa_gpio_mode(GPIO55_nPREG_MD);
- pxa_gpio_mode(GPIO56_nPWAIT_MD);
- pxa_gpio_mode(GPIO57_nIOIS16_MD);
+ if (platform_scoop_config->pcmcia_init)
+ platform_scoop_config->pcmcia_init();
/* Register interrupts */
- if (scoop_devs[skt->nr].cd_irq >= 0) {
+ if (SCOOP_DEV[skt->nr].cd_irq >= 0) {
struct pcmcia_irqs cd_irq;
cd_irq.sock = skt->nr;
- cd_irq.irq = scoop_devs[skt->nr].cd_irq;
- cd_irq.str = scoop_devs[skt->nr].cd_irq_str;
+ cd_irq.irq = SCOOP_DEV[skt->nr].cd_irq;
+ cd_irq.str = SCOOP_DEV[skt->nr].cd_irq_str;
ret = soc_pcmcia_request_irqs(skt, &cd_irq, 1);
if (ret) {
@@ -76,19 +65,19 @@ static int sharpsl_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
}
}
- skt->irq = scoop_devs[skt->nr].irq;
+ skt->irq = SCOOP_DEV[skt->nr].irq;
return 0;
}
static void sharpsl_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
{
- if (scoop_devs[skt->nr].cd_irq >= 0) {
+ if (SCOOP_DEV[skt->nr].cd_irq >= 0) {
struct pcmcia_irqs cd_irq;
cd_irq.sock = skt->nr;
- cd_irq.irq = scoop_devs[skt->nr].cd_irq;
- cd_irq.str = scoop_devs[skt->nr].cd_irq_str;
+ cd_irq.irq = SCOOP_DEV[skt->nr].cd_irq;
+ cd_irq.str = SCOOP_DEV[skt->nr].cd_irq_str;
soc_pcmcia_free_irqs(skt, &cd_irq, 1);
}
}
@@ -98,9 +87,9 @@ static void sharpsl_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
struct pcmcia_state *state)
{
unsigned short cpr, csr;
- struct device *scoop = scoop_devs[skt->nr].dev;
+ struct device *scoop = SCOOP_DEV[skt->nr].dev;
- cpr = read_scoop_reg(scoop_devs[skt->nr].dev, SCOOP_CPR);
+ cpr = read_scoop_reg(SCOOP_DEV[skt->nr].dev, SCOOP_CPR);
write_scoop_reg(scoop, SCOOP_IRM, 0x00FF);
write_scoop_reg(scoop, SCOOP_ISR, 0x0000);
@@ -109,21 +98,25 @@ static void sharpsl_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
if (csr & 0x0004) {
/* card eject */
write_scoop_reg(scoop, SCOOP_CDR, 0x0000);
- scoop_devs[skt->nr].keep_vs = NO_KEEP_VS;
+ SCOOP_DEV[skt->nr].keep_vs = NO_KEEP_VS;
}
- else if (!(scoop_devs[skt->nr].keep_vs & NO_KEEP_VS)) {
+ else if (!(SCOOP_DEV[skt->nr].keep_vs & NO_KEEP_VS)) {
/* keep vs1,vs2 */
write_scoop_reg(scoop, SCOOP_CDR, 0x0000);
- csr |= scoop_devs[skt->nr].keep_vs;
+ csr |= SCOOP_DEV[skt->nr].keep_vs;
}
else if (cpr & 0x0003) {
/* power on */
write_scoop_reg(scoop, SCOOP_CDR, 0x0000);
- scoop_devs[skt->nr].keep_vs = (csr & 0x00C0);
+ SCOOP_DEV[skt->nr].keep_vs = (csr & 0x00C0);
}
else {
/* card detect */
- write_scoop_reg(scoop, SCOOP_CDR, 0x0002);
+ if ((machine_is_spitz() || machine_is_borzoi()) && skt->nr == 1) {
+ write_scoop_reg(scoop, SCOOP_CDR, 0x0000);
+ } else {
+ write_scoop_reg(scoop, SCOOP_CDR, 0x0002);
+ }
}
state->detect = (csr & 0x0004) ? 0 : 1;
@@ -137,7 +130,6 @@ static void sharpsl_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
if ((cpr & 0x0080) && ((cpr & 0x8040) != 0x8040)) {
printk(KERN_ERR "sharpsl_pcmcia_socket_state(): CPR=%04X, Low voltage!\n", cpr);
}
-
}
@@ -145,7 +137,7 @@ static int sharpsl_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
const socket_state_t *state)
{
unsigned long flags;
- struct device *scoop = scoop_devs[skt->nr].dev;
+ struct device *scoop = SCOOP_DEV[skt->nr].dev;
unsigned short cpr, ncpr, ccr, nccr, mcr, nmcr, imr, nimr;
@@ -170,8 +162,13 @@ static int sharpsl_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
nccr = (ccr = read_scoop_reg(scoop, SCOOP_CCR)) & ~0x0080;
nimr = (imr = read_scoop_reg(scoop, SCOOP_IMR)) & ~0x003E;
- ncpr |= (state->Vcc == 33) ? 0x0001 :
- (state->Vcc == 50) ? 0x0002 : 0;
+ if ((machine_is_spitz() || machine_is_borzoi() || machine_is_akita()) && skt->nr == 0) {
+ ncpr |= (state->Vcc == 33) ? 0x0002 :
+ (state->Vcc == 50) ? 0x0002 : 0;
+ } else {
+ ncpr |= (state->Vcc == 33) ? 0x0001 :
+ (state->Vcc == 50) ? 0x0002 : 0;
+ }
nmcr |= (state->flags&SS_IOCARD) ? 0x0010 : 0;
ncpr |= (state->flags&SS_OUTPUT_ENA) ? 0x0080 : 0;
nccr |= (state->flags&SS_RESET)? 0x0080: 0;
@@ -183,18 +180,22 @@ static int sharpsl_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
((skt->status&SS_WRPROT) ? 0x0008 : 0);
if (!(ncpr & 0x0003)) {
- scoop_devs[skt->nr].keep_rd = 0;
- } else if (!scoop_devs[skt->nr].keep_rd) {
+ SCOOP_DEV[skt->nr].keep_rd = 0;
+ } else if (!SCOOP_DEV[skt->nr].keep_rd) {
if (nccr & 0x0080)
- scoop_devs[skt->nr].keep_rd = 1;
+ SCOOP_DEV[skt->nr].keep_rd = 1;
else
nccr |= 0x0080;
}
if (mcr != nmcr)
write_scoop_reg(scoop, SCOOP_MCR, nmcr);
- if (cpr != ncpr)
- write_scoop_reg(scoop, SCOOP_CPR, ncpr);
+ if (cpr != ncpr) {
+ if (platform_scoop_config->power_ctrl)
+ platform_scoop_config->power_ctrl(scoop, ncpr , skt->nr);
+ else
+ write_scoop_reg(scoop, SCOOP_CPR, ncpr);
+ }
if (ccr != nccr)
write_scoop_reg(scoop, SCOOP_CCR, nccr);
if (imr != nimr)
@@ -207,39 +208,62 @@ static int sharpsl_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
static void sharpsl_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
{
- sharpsl_pcmcia_init_reset(&scoop_devs[skt->nr]);
+ sharpsl_pcmcia_init_reset(&SCOOP_DEV[skt->nr]);
/* Enable interrupt */
- write_scoop_reg(scoop_devs[skt->nr].dev, SCOOP_IMR, 0x00C0);
- write_scoop_reg(scoop_devs[skt->nr].dev, SCOOP_MCR, 0x0101);
- scoop_devs[skt->nr].keep_vs = NO_KEEP_VS;
+ write_scoop_reg(SCOOP_DEV[skt->nr].dev, SCOOP_IMR, 0x00C0);
+ write_scoop_reg(SCOOP_DEV[skt->nr].dev, SCOOP_MCR, 0x0101);
+ SCOOP_DEV[skt->nr].keep_vs = NO_KEEP_VS;
+
+ if (machine_is_collie())
+ /* We need to disable SS_OUTPUT_ENA here. */
+ write_scoop_reg(SCOOP_DEV[skt->nr].dev, SCOOP_CPR, read_scoop_reg(SCOOP_DEV[skt->nr].dev, SCOOP_CPR) & ~0x0080);
}
static void sharpsl_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
{
/* CF_BUS_OFF */
- sharpsl_pcmcia_init_reset(&scoop_devs[skt->nr]);
+ sharpsl_pcmcia_init_reset(&SCOOP_DEV[skt->nr]);
+
+ if (machine_is_collie())
+ /* We need to disable SS_OUTPUT_ENA here. */
+ write_scoop_reg(SCOOP_DEV[skt->nr].dev, SCOOP_CPR, read_scoop_reg(SCOOP_DEV[skt->nr].dev, SCOOP_CPR) & ~0x0080);
}
static struct pcmcia_low_level sharpsl_pcmcia_ops = {
- .owner = THIS_MODULE,
- .hw_init = sharpsl_pcmcia_hw_init,
- .hw_shutdown = sharpsl_pcmcia_hw_shutdown,
- .socket_state = sharpsl_pcmcia_socket_state,
- .configure_socket = sharpsl_pcmcia_configure_socket,
- .socket_init = sharpsl_pcmcia_socket_init,
- .socket_suspend = sharpsl_pcmcia_socket_suspend,
- .first = 0,
- .nr = 0,
+ .owner = THIS_MODULE,
+ .hw_init = sharpsl_pcmcia_hw_init,
+ .hw_shutdown = sharpsl_pcmcia_hw_shutdown,
+ .socket_state = sharpsl_pcmcia_socket_state,
+ .configure_socket = sharpsl_pcmcia_configure_socket,
+ .socket_init = sharpsl_pcmcia_socket_init,
+ .socket_suspend = sharpsl_pcmcia_socket_suspend,
+ .first = 0,
+ .nr = 0,
};
+#ifdef CONFIG_SA1100_COLLIE
+#include "sa11xx_base.h"
+
+int __init pcmcia_collie_init(struct device *dev)
+{
+ int ret = -ENODEV;
+
+ if (machine_is_collie())
+ ret = sa11xx_drv_pcmcia_probe(dev, &sharpsl_pcmcia_ops, 0, 1);
+
+ return ret;
+}
+
+#else
+
static struct platform_device *sharpsl_pcmcia_device;
static int __init sharpsl_pcmcia_init(void)
{
int ret;
- sharpsl_pcmcia_ops.nr=scoop_num;
+ sharpsl_pcmcia_ops.nr=platform_scoop_config->num_devs;
sharpsl_pcmcia_device = kmalloc(sizeof(*sharpsl_pcmcia_device), GFP_KERNEL);
if (!sharpsl_pcmcia_device)
return -ENOMEM;
@@ -247,7 +271,7 @@ static int __init sharpsl_pcmcia_init(void)
memset(sharpsl_pcmcia_device, 0, sizeof(*sharpsl_pcmcia_device));
sharpsl_pcmcia_device->name = "pxa2xx-pcmcia";
sharpsl_pcmcia_device->dev.platform_data = &sharpsl_pcmcia_ops;
- sharpsl_pcmcia_device->dev.parent=scoop_devs[0].dev;
+ sharpsl_pcmcia_device->dev.parent=platform_scoop_config->devs[0].dev;
ret = platform_device_register(sharpsl_pcmcia_device);
if (ret)
@@ -269,6 +293,7 @@ static void __exit sharpsl_pcmcia_exit(void)
fs_initcall(sharpsl_pcmcia_init);
module_exit(sharpsl_pcmcia_exit);
+#endif
MODULE_DESCRIPTION("Sharp SL Series PCMCIA Support");
MODULE_LICENSE("GPL");
diff --git a/drivers/pcmcia/rsrc_nonstatic.c b/drivers/pcmcia/rsrc_nonstatic.c
index f9a5c70284b5..00960a379b9c 100644
--- a/drivers/pcmcia/rsrc_nonstatic.c
+++ b/drivers/pcmcia/rsrc_nonstatic.c
@@ -779,7 +779,7 @@ static int nonstatic_autoadd_resources(struct pcmcia_socket *s)
if (!s->cb_dev || !s->cb_dev->bus)
return -ENODEV;
-#if defined(CONFIG_X86) || defined(CONFIG_X86_64)
+#if defined(CONFIG_X86)
/* If this is the root bus, the risk of hitting
* some strange system devices which aren't protected
* by either ACPI resource tables or properly requested
@@ -994,7 +994,8 @@ static struct class_device_attribute *pccard_rsrc_attributes[] = {
NULL,
};
-static int __devinit pccard_sysfs_add_rsrc(struct class_device *class_dev)
+static int __devinit pccard_sysfs_add_rsrc(struct class_device *class_dev,
+ struct class_interface *class_intf)
{
struct pcmcia_socket *s = class_get_devdata(class_dev);
struct class_device_attribute **attr;
@@ -1011,7 +1012,8 @@ static int __devinit pccard_sysfs_add_rsrc(struct class_device *class_dev)
return ret;
}
-static void __devexit pccard_sysfs_remove_rsrc(struct class_device *class_dev)
+static void __devexit pccard_sysfs_remove_rsrc(struct class_device *class_dev,
+ struct class_interface *class_intf)
{
struct pcmcia_socket *s = class_get_devdata(class_dev);
struct class_device_attribute **attr;
diff --git a/drivers/pcmcia/sa1100_generic.c b/drivers/pcmcia/sa1100_generic.c
index d4ed508b38be..6d441ec75c6a 100644
--- a/drivers/pcmcia/sa1100_generic.c
+++ b/drivers/pcmcia/sa1100_generic.c
@@ -33,13 +33,18 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/config.h>
+#include <linux/platform_device.h>
#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
#include <pcmcia/ss.h>
+#include <asm/hardware/scoop.h>
+
#include "sa1100_generic.h"
+int __init pcmcia_collie_init(struct device *dev);
+
static int (*sa11x0_pcmcia_hw_init[])(struct device *dev) = {
#ifdef CONFIG_SA1100_ASSABET
pcmcia_assabet_init,
@@ -56,6 +61,9 @@ static int (*sa11x0_pcmcia_hw_init[])(struct device *dev) = {
#ifdef CONFIG_SA1100_SIMPAD
pcmcia_simpad_init,
#endif
+#ifdef CONFIG_SA1100_COLLIE
+ pcmcia_collie_init,
+#endif
};
static int sa11x0_drv_pcmcia_probe(struct device *dev)
@@ -74,29 +82,13 @@ static int sa11x0_drv_pcmcia_probe(struct device *dev)
return ret;
}
-static int sa11x0_drv_pcmcia_suspend(struct device *dev, pm_message_t state, u32 level)
-{
- int ret = 0;
- if (level == SUSPEND_SAVE_STATE)
- ret = pcmcia_socket_dev_suspend(dev, state);
- return ret;
-}
-
-static int sa11x0_drv_pcmcia_resume(struct device *dev, u32 level)
-{
- int ret = 0;
- if (level == RESUME_RESTORE_STATE)
- ret = pcmcia_socket_dev_resume(dev);
- return ret;
-}
-
static struct device_driver sa11x0_pcmcia_driver = {
.probe = sa11x0_drv_pcmcia_probe,
.remove = soc_common_drv_pcmcia_remove,
.name = "sa11x0-pcmcia",
.bus = &platform_bus_type,
- .suspend = sa11x0_drv_pcmcia_suspend,
- .resume = sa11x0_drv_pcmcia_resume,
+ .suspend = pcmcia_socket_dev_suspend,
+ .resume = pcmcia_socket_dev_resume,
};
/* sa11x0_pcmcia_init()
diff --git a/drivers/pcmcia/sa1111_generic.c b/drivers/pcmcia/sa1111_generic.c
index bb90a1448a53..81ded52c8959 100644
--- a/drivers/pcmcia/sa1111_generic.c
+++ b/drivers/pcmcia/sa1111_generic.c
@@ -122,7 +122,7 @@ void sa1111_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
static int pcmcia_probe(struct sa1111_dev *dev)
{
- char *base;
+ void __iomem *base;
if (!request_mem_region(dev->res.start, 512,
SA1111_DRIVER_NAME(dev)))
diff --git a/drivers/pcmcia/socket_sysfs.c b/drivers/pcmcia/socket_sysfs.c
index 1040a6c1a8a4..4a3150a7854c 100644
--- a/drivers/pcmcia/socket_sysfs.c
+++ b/drivers/pcmcia/socket_sysfs.c
@@ -341,7 +341,8 @@ static struct bin_attribute pccard_cis_attr = {
.write = pccard_store_cis,
};
-static int __devinit pccard_sysfs_add_socket(struct class_device *class_dev)
+static int __devinit pccard_sysfs_add_socket(struct class_device *class_dev,
+ struct class_interface *class_intf)
{
struct class_device_attribute **attr;
int ret = 0;
@@ -357,7 +358,8 @@ static int __devinit pccard_sysfs_add_socket(struct class_device *class_dev)
return ret;
}
-static void __devexit pccard_sysfs_remove_socket(struct class_device *class_dev)
+static void __devexit pccard_sysfs_remove_socket(struct class_device *class_dev,
+ struct class_interface *class_intf)
{
struct class_device_attribute **attr;
diff --git a/drivers/pcmcia/tcic.c b/drivers/pcmcia/tcic.c
index d5a61eae6119..e31263864377 100644
--- a/drivers/pcmcia/tcic.c
+++ b/drivers/pcmcia/tcic.c
@@ -44,7 +44,7 @@
#include <linux/ioport.h>
#include <linux/delay.h>
#include <linux/workqueue.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <linux/bitops.h>
#include <asm/io.h>
@@ -372,27 +372,11 @@ static int __init get_tcic_id(void)
/*====================================================================*/
-static int tcic_drv_suspend(struct device *dev, pm_message_t state, u32 level)
-{
- int ret = 0;
- if (level == SUSPEND_SAVE_STATE)
- ret = pcmcia_socket_dev_suspend(dev, state);
- return ret;
-}
-
-static int tcic_drv_resume(struct device *dev, u32 level)
-{
- int ret = 0;
- if (level == RESUME_RESTORE_STATE)
- ret = pcmcia_socket_dev_resume(dev);
- return ret;
-}
-
static struct device_driver tcic_driver = {
.name = "tcic-pcmcia",
.bus = &platform_bus_type,
- .suspend = tcic_drv_suspend,
- .resume = tcic_drv_resume,
+ .suspend = pcmcia_socket_dev_suspend,
+ .resume = pcmcia_socket_dev_resume,
};
static struct platform_device tcic_device = {
diff --git a/drivers/pcmcia/vrc4171_card.c b/drivers/pcmcia/vrc4171_card.c
index 17bb2da6752b..38a028c725d4 100644
--- a/drivers/pcmcia/vrc4171_card.c
+++ b/drivers/pcmcia/vrc4171_card.c
@@ -24,6 +24,7 @@
#include <linux/spinlock.h>
#include <linux/sched.h>
#include <linux/types.h>
+#include <linux/platform_device.h>
#include <asm/io.h>
@@ -774,31 +775,11 @@ static int __devinit vrc4171_card_setup(char *options)
__setup("vrc4171_card=", vrc4171_card_setup);
-static int vrc4171_card_suspend(struct device *dev, pm_message_t state, u32 level)
-{
- int retval = 0;
-
- if (level == SUSPEND_SAVE_STATE)
- retval = pcmcia_socket_dev_suspend(dev, state);
-
- return retval;
-}
-
-static int vrc4171_card_resume(struct device *dev, u32 level)
-{
- int retval = 0;
-
- if (level == RESUME_RESTORE_STATE)
- retval = pcmcia_socket_dev_resume(dev);
-
- return retval;
-}
-
static struct device_driver vrc4171_card_driver = {
.name = vrc4171_card_name,
.bus = &platform_bus_type,
- .suspend = vrc4171_card_suspend,
- .resume = vrc4171_card_resume,
+ .suspend = pcmcia_socket_dev_suspend,
+ .resume = pcmcia_socket_dev_resume,
};
static int __devinit vrc4171_card_init(void)
diff --git a/drivers/pcmcia/yenta_socket.c b/drivers/pcmcia/yenta_socket.c
index db9f952f9e3c..ec6ab65f0872 100644
--- a/drivers/pcmcia/yenta_socket.c
+++ b/drivers/pcmcia/yenta_socket.c
@@ -151,6 +151,40 @@ static void exca_writew(struct yenta_socket *socket, unsigned reg, u16 val)
readb(socket->base + 0x800 + reg + 1);
}
+static ssize_t show_yenta_registers(struct device *yentadev, struct device_attribute *attr, char *buf)
+{
+ struct pci_dev *dev = to_pci_dev(yentadev);
+ struct yenta_socket *socket = pci_get_drvdata(dev);
+ int offset = 0, i;
+
+ offset = snprintf(buf, PAGE_SIZE, "CB registers:");
+ for (i = 0; i < 0x24; i += 4) {
+ unsigned val;
+ if (!(i & 15))
+ offset += snprintf(buf + offset, PAGE_SIZE - offset, "\n%02x:", i);
+ val = cb_readl(socket, i);
+ offset += snprintf(buf + offset, PAGE_SIZE - offset, " %08x", val);
+ }
+
+ offset += snprintf(buf + offset, PAGE_SIZE - offset, "\n\nExCA registers:");
+ for (i = 0; i < 0x45; i++) {
+ unsigned char val;
+ if (!(i & 7)) {
+ if (i & 8) {
+ memcpy(buf + offset, " -", 2);
+ offset += 2;
+ } else
+ offset += snprintf(buf + offset, PAGE_SIZE - offset, "\n%02x:", i);
+ }
+ val = exca_readb(socket, i);
+ offset += snprintf(buf + offset, PAGE_SIZE - offset, " %02x", val);
+ }
+ buf[offset++] = '\n';
+ return offset;
+}
+
+static DEVICE_ATTR(yenta_registers, S_IRUSR, show_yenta_registers, NULL);
+
/*
* Ugh, mixed-mode cardbus and 16-bit pccard state: things depend
* on what kind of card is inserted..
@@ -765,6 +799,9 @@ static void yenta_close(struct pci_dev *dev)
{
struct yenta_socket *sock = pci_get_drvdata(dev);
+ /* Remove the register attributes */
+ device_remove_file(&dev->dev, &dev_attr_yenta_registers);
+
/* we don't want a dying socket registered */
pcmcia_unregister_socket(&sock->socket);
@@ -1138,8 +1175,11 @@ static int __devinit yenta_probe (struct pci_dev *dev, const struct pci_device_i
/* Register it with the pcmcia layer.. */
ret = pcmcia_register_socket(&socket->socket);
- if (ret == 0)
+ if (ret == 0) {
+ /* Add the yenta register attributes */
+ device_create_file(&dev->dev, &dev_attr_yenta_registers);
goto out;
+ }
unmap:
iounmap(socket->base);
diff --git a/drivers/pnp/card.c b/drivers/pnp/card.c
index e95ed67d4f05..bd7c966ea2d7 100644
--- a/drivers/pnp/card.c
+++ b/drivers/pnp/card.c
@@ -12,7 +12,7 @@
#include "base.h"
LIST_HEAD(pnp_cards);
-LIST_HEAD(pnp_card_drivers);
+static LIST_HEAD(pnp_card_drivers);
static const struct pnp_card_device_id * match_card(struct pnp_card_driver * drv, struct pnp_card * card)
@@ -374,11 +374,13 @@ void pnp_unregister_card_driver(struct pnp_card_driver * drv)
pnp_unregister_driver(&drv->link);
}
+#if 0
EXPORT_SYMBOL(pnp_add_card);
EXPORT_SYMBOL(pnp_remove_card);
EXPORT_SYMBOL(pnp_add_card_device);
EXPORT_SYMBOL(pnp_remove_card_device);
EXPORT_SYMBOL(pnp_add_card_id);
+#endif /* 0 */
EXPORT_SYMBOL(pnp_request_card_device);
EXPORT_SYMBOL(pnp_release_card_device);
EXPORT_SYMBOL(pnp_register_card_driver);
diff --git a/drivers/pnp/core.c b/drivers/pnp/core.c
index deed92459bc5..aec83ec5ea23 100644
--- a/drivers/pnp/core.c
+++ b/drivers/pnp/core.c
@@ -158,13 +158,14 @@ void __pnp_remove_device(struct pnp_dev *dev)
*
* this function will free all mem used by dev
*/
-
+#if 0
void pnp_remove_device(struct pnp_dev *dev)
{
if (!dev || dev->card)
return;
__pnp_remove_device(dev);
}
+#endif /* 0 */
static int __init pnp_init(void)
{
@@ -174,7 +175,9 @@ static int __init pnp_init(void)
subsys_initcall(pnp_init);
+#if 0
EXPORT_SYMBOL(pnp_register_protocol);
EXPORT_SYMBOL(pnp_unregister_protocol);
EXPORT_SYMBOL(pnp_add_device);
EXPORT_SYMBOL(pnp_remove_device);
+#endif /* 0 */
diff --git a/drivers/pnp/driver.c b/drivers/pnp/driver.c
index 33da25f3213f..d3ccce706ab4 100644
--- a/drivers/pnp/driver.c
+++ b/drivers/pnp/driver.c
@@ -214,6 +214,8 @@ int pnp_add_id(struct pnp_id *id, struct pnp_dev *dev)
EXPORT_SYMBOL(pnp_register_driver);
EXPORT_SYMBOL(pnp_unregister_driver);
+#if 0
EXPORT_SYMBOL(pnp_add_id);
+#endif
EXPORT_SYMBOL(pnp_device_attach);
EXPORT_SYMBOL(pnp_device_detach);
diff --git a/drivers/pnp/isapnp/core.c b/drivers/pnp/isapnp/core.c
index beedd86800f4..57fd60314d59 100644
--- a/drivers/pnp/isapnp/core.c
+++ b/drivers/pnp/isapnp/core.c
@@ -941,7 +941,9 @@ EXPORT_SYMBOL(isapnp_protocol);
EXPORT_SYMBOL(isapnp_present);
EXPORT_SYMBOL(isapnp_cfg_begin);
EXPORT_SYMBOL(isapnp_cfg_end);
+#if 0
EXPORT_SYMBOL(isapnp_read_byte);
+#endif
EXPORT_SYMBOL(isapnp_write_byte);
static int isapnp_read_resources(struct pnp_dev *dev, struct pnp_resource_table *res)
diff --git a/drivers/pnp/manager.c b/drivers/pnp/manager.c
index 94442ffd4aed..261668618b2d 100644
--- a/drivers/pnp/manager.c
+++ b/drivers/pnp/manager.c
@@ -12,6 +12,8 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/pnp.h>
+#include <linux/slab.h>
+#include <linux/bitmap.h>
#include "base.h"
DECLARE_MUTEX(pnp_res_mutex);
@@ -553,7 +555,9 @@ void pnp_resource_change(struct resource *resource, unsigned long start, unsigne
EXPORT_SYMBOL(pnp_manual_config_dev);
+#if 0
EXPORT_SYMBOL(pnp_auto_config_dev);
+#endif
EXPORT_SYMBOL(pnp_activate_dev);
EXPORT_SYMBOL(pnp_disable_dev);
EXPORT_SYMBOL(pnp_resource_change);
diff --git a/drivers/pnp/pnpacpi/core.c b/drivers/pnp/pnpacpi/core.c
index 1a8915e74160..816479ad217b 100644
--- a/drivers/pnp/pnpacpi/core.c
+++ b/drivers/pnp/pnpacpi/core.c
@@ -117,7 +117,7 @@ static int pnpacpi_disable_resources(struct pnp_dev *dev)
return ACPI_FAILURE(status) ? -ENODEV : 0;
}
-struct pnp_protocol pnpacpi_protocol = {
+static struct pnp_protocol pnpacpi_protocol = {
.name = "Plug and Play ACPI",
.get = pnpacpi_get_resources,
.set = pnpacpi_set_resources,
@@ -234,7 +234,7 @@ static acpi_status __init pnpacpi_add_device_handler(acpi_handle handle,
}
int pnpacpi_disabled __initdata;
-int __init pnpacpi_init(void)
+static int __init pnpacpi_init(void)
{
if (acpi_disabled || pnpacpi_disabled) {
pnp_info("PnP ACPI: disabled");
@@ -258,4 +258,6 @@ static int __init pnpacpi_setup(char *str)
}
__setup("pnpacpi=", pnpacpi_setup);
+#if 0
EXPORT_SYMBOL(pnpacpi_protocol);
+#endif
diff --git a/drivers/pnp/pnpbios/rsparser.c b/drivers/pnp/pnpbios/rsparser.c
index b0ca65b68645..5e38cd7335f7 100644
--- a/drivers/pnp/pnpbios/rsparser.c
+++ b/drivers/pnp/pnpbios/rsparser.c
@@ -7,6 +7,8 @@
#include <linux/ctype.h>
#include <linux/pnp.h>
#include <linux/pnpbios.h>
+#include <linux/string.h>
+#include <linux/slab.h>
#ifdef CONFIG_PCI
#include <linux/pci.h>
diff --git a/drivers/pnp/resource.c b/drivers/pnp/resource.c
index 887ad8939349..6ded527169f4 100644
--- a/drivers/pnp/resource.c
+++ b/drivers/pnp/resource.c
@@ -477,12 +477,14 @@ int pnp_check_dma(struct pnp_dev * dev, int idx)
}
+#if 0
EXPORT_SYMBOL(pnp_register_dependent_option);
EXPORT_SYMBOL(pnp_register_independent_option);
EXPORT_SYMBOL(pnp_register_irq_resource);
EXPORT_SYMBOL(pnp_register_dma_resource);
EXPORT_SYMBOL(pnp_register_port_resource);
EXPORT_SYMBOL(pnp_register_mem_resource);
+#endif /* 0 */
/* format is: pnp_reserve_irq=irq1[,irq2] .... */
diff --git a/drivers/rapidio/Kconfig b/drivers/rapidio/Kconfig
new file mode 100644
index 000000000000..0b2d2c3579a7
--- /dev/null
+++ b/drivers/rapidio/Kconfig
@@ -0,0 +1,18 @@
+#
+# RapidIO configuration
+#
+config RAPIDIO_8_BIT_TRANSPORT
+ bool "8-bit transport addressing"
+ depends on RAPIDIO
+ ---help---
+ By default, the kernel assumes a 16-bit addressed RapidIO
+ network. By selecting this option, the kernel will support
+ an 8-bit addressed network.
+
+config RAPIDIO_DISC_TIMEOUT
+ int "Discovery timeout duration (seconds)"
+ depends on RAPIDIO
+ default "30"
+ ---help---
+ Amount of time a discovery node waits for a host to complete
+ enumeration beforing giving up.
diff --git a/drivers/rapidio/Makefile b/drivers/rapidio/Makefile
new file mode 100644
index 000000000000..7c0e1818de51
--- /dev/null
+++ b/drivers/rapidio/Makefile
@@ -0,0 +1,6 @@
+#
+# Makefile for RapidIO interconnect services
+#
+obj-y += rio.o rio-access.o rio-driver.o rio-scan.o rio-sysfs.o
+
+obj-$(CONFIG_RAPIDIO) += switches/
diff --git a/drivers/rapidio/rio-access.c b/drivers/rapidio/rio-access.c
new file mode 100644
index 000000000000..b9fab2ae3a36
--- /dev/null
+++ b/drivers/rapidio/rio-access.c
@@ -0,0 +1,175 @@
+/*
+ * RapidIO configuration space access support
+ *
+ * Copyright 2005 MontaVista Software, Inc.
+ * Matt Porter <mporter@kernel.crashing.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/rio.h>
+#include <linux/module.h>
+
+/*
+ * These interrupt-safe spinlocks protect all accesses to RIO
+ * configuration space and doorbell access.
+ */
+static spinlock_t rio_config_lock = SPIN_LOCK_UNLOCKED;
+static spinlock_t rio_doorbell_lock = SPIN_LOCK_UNLOCKED;
+
+/*
+ * Wrappers for all RIO configuration access functions. They just check
+ * alignment, do locking and call the low-level functions pointed to
+ * by rio_mport->ops.
+ */
+
+#define RIO_8_BAD 0
+#define RIO_16_BAD (offset & 1)
+#define RIO_32_BAD (offset & 3)
+
+/**
+ * RIO_LOP_READ - Generate rio_local_read_config_* functions
+ * @size: Size of configuration space read (8, 16, 32 bits)
+ * @type: C type of value argument
+ * @len: Length of configuration space read (1, 2, 4 bytes)
+ *
+ * Generates rio_local_read_config_* functions used to access
+ * configuration space registers on the local device.
+ */
+#define RIO_LOP_READ(size,type,len) \
+int __rio_local_read_config_##size \
+ (struct rio_mport *mport, u32 offset, type *value) \
+{ \
+ int res; \
+ unsigned long flags; \
+ u32 data = 0; \
+ if (RIO_##size##_BAD) return RIO_BAD_SIZE; \
+ spin_lock_irqsave(&rio_config_lock, flags); \
+ res = mport->ops->lcread(mport->id, offset, len, &data); \
+ *value = (type)data; \
+ spin_unlock_irqrestore(&rio_config_lock, flags); \
+ return res; \
+}
+
+/**
+ * RIO_LOP_WRITE - Generate rio_local_write_config_* functions
+ * @size: Size of configuration space write (8, 16, 32 bits)
+ * @type: C type of value argument
+ * @len: Length of configuration space write (1, 2, 4 bytes)
+ *
+ * Generates rio_local_write_config_* functions used to access
+ * configuration space registers on the local device.
+ */
+#define RIO_LOP_WRITE(size,type,len) \
+int __rio_local_write_config_##size \
+ (struct rio_mport *mport, u32 offset, type value) \
+{ \
+ int res; \
+ unsigned long flags; \
+ if (RIO_##size##_BAD) return RIO_BAD_SIZE; \
+ spin_lock_irqsave(&rio_config_lock, flags); \
+ res = mport->ops->lcwrite(mport->id, offset, len, value); \
+ spin_unlock_irqrestore(&rio_config_lock, flags); \
+ return res; \
+}
+
+RIO_LOP_READ(8, u8, 1)
+RIO_LOP_READ(16, u16, 2)
+RIO_LOP_READ(32, u32, 4)
+RIO_LOP_WRITE(8, u8, 1)
+RIO_LOP_WRITE(16, u16, 2)
+RIO_LOP_WRITE(32, u32, 4)
+
+EXPORT_SYMBOL_GPL(__rio_local_read_config_8);
+EXPORT_SYMBOL_GPL(__rio_local_read_config_16);
+EXPORT_SYMBOL_GPL(__rio_local_read_config_32);
+EXPORT_SYMBOL_GPL(__rio_local_write_config_8);
+EXPORT_SYMBOL_GPL(__rio_local_write_config_16);
+EXPORT_SYMBOL_GPL(__rio_local_write_config_32);
+
+/**
+ * RIO_OP_READ - Generate rio_mport_read_config_* functions
+ * @size: Size of configuration space read (8, 16, 32 bits)
+ * @type: C type of value argument
+ * @len: Length of configuration space read (1, 2, 4 bytes)
+ *
+ * Generates rio_mport_read_config_* functions used to access
+ * configuration space registers on the local device.
+ */
+#define RIO_OP_READ(size,type,len) \
+int rio_mport_read_config_##size \
+ (struct rio_mport *mport, u16 destid, u8 hopcount, u32 offset, type *value) \
+{ \
+ int res; \
+ unsigned long flags; \
+ u32 data = 0; \
+ if (RIO_##size##_BAD) return RIO_BAD_SIZE; \
+ spin_lock_irqsave(&rio_config_lock, flags); \
+ res = mport->ops->cread(mport->id, destid, hopcount, offset, len, &data); \
+ *value = (type)data; \
+ spin_unlock_irqrestore(&rio_config_lock, flags); \
+ return res; \
+}
+
+/**
+ * RIO_OP_WRITE - Generate rio_mport_write_config_* functions
+ * @size: Size of configuration space write (8, 16, 32 bits)
+ * @type: C type of value argument
+ * @len: Length of configuration space write (1, 2, 4 bytes)
+ *
+ * Generates rio_mport_write_config_* functions used to access
+ * configuration space registers on the local device.
+ */
+#define RIO_OP_WRITE(size,type,len) \
+int rio_mport_write_config_##size \
+ (struct rio_mport *mport, u16 destid, u8 hopcount, u32 offset, type value) \
+{ \
+ int res; \
+ unsigned long flags; \
+ if (RIO_##size##_BAD) return RIO_BAD_SIZE; \
+ spin_lock_irqsave(&rio_config_lock, flags); \
+ res = mport->ops->cwrite(mport->id, destid, hopcount, offset, len, value); \
+ spin_unlock_irqrestore(&rio_config_lock, flags); \
+ return res; \
+}
+
+RIO_OP_READ(8, u8, 1)
+RIO_OP_READ(16, u16, 2)
+RIO_OP_READ(32, u32, 4)
+RIO_OP_WRITE(8, u8, 1)
+RIO_OP_WRITE(16, u16, 2)
+RIO_OP_WRITE(32, u32, 4)
+
+EXPORT_SYMBOL_GPL(rio_mport_read_config_8);
+EXPORT_SYMBOL_GPL(rio_mport_read_config_16);
+EXPORT_SYMBOL_GPL(rio_mport_read_config_32);
+EXPORT_SYMBOL_GPL(rio_mport_write_config_8);
+EXPORT_SYMBOL_GPL(rio_mport_write_config_16);
+EXPORT_SYMBOL_GPL(rio_mport_write_config_32);
+
+/**
+ * rio_mport_send_doorbell - Send a doorbell message
+ *
+ * @mport: RIO master port
+ * @destid: RIO device destination ID
+ * @data: Doorbell message data
+ *
+ * Send a doorbell message to a RIO device. The doorbell message
+ * has a 16-bit info field provided by the data argument.
+ */
+int rio_mport_send_doorbell(struct rio_mport *mport, u16 destid, u16 data)
+{
+ int res;
+ unsigned long flags;
+
+ spin_lock_irqsave(&rio_doorbell_lock, flags);
+ res = mport->ops->dsend(mport->id, destid, data);
+ spin_unlock_irqrestore(&rio_doorbell_lock, flags);
+
+ return res;
+}
+
+EXPORT_SYMBOL_GPL(rio_mport_send_doorbell);
diff --git a/drivers/rapidio/rio-driver.c b/drivers/rapidio/rio-driver.c
new file mode 100644
index 000000000000..dc749609699a
--- /dev/null
+++ b/drivers/rapidio/rio-driver.c
@@ -0,0 +1,229 @@
+/*
+ * RapidIO driver support
+ *
+ * Copyright 2005 MontaVista Software, Inc.
+ * Matt Porter <mporter@kernel.crashing.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/init.h>
+#include <linux/module.h>
+#include <linux/rio.h>
+#include <linux/rio_ids.h>
+
+#include "rio.h"
+
+/**
+ * rio_match_device - Tell if a RIO device has a matching RIO device id structure
+ * @id: the RIO device id structure to match against
+ * @rdev: the RIO device structure to match against
+ *
+ * Used from driver probe and bus matching to check whether a RIO device
+ * matches a device id structure provided by a RIO driver. Returns the
+ * matching &struct rio_device_id or %NULL if there is no match.
+ */
+static const struct rio_device_id *rio_match_device(const struct rio_device_id
+ *id,
+ const struct rio_dev *rdev)
+{
+ while (id->vid || id->asm_vid) {
+ if (((id->vid == RIO_ANY_ID) || (id->vid == rdev->vid)) &&
+ ((id->did == RIO_ANY_ID) || (id->did == rdev->did)) &&
+ ((id->asm_vid == RIO_ANY_ID)
+ || (id->asm_vid == rdev->asm_vid))
+ && ((id->asm_did == RIO_ANY_ID)
+ || (id->asm_did == rdev->asm_did)))
+ return id;
+ id++;
+ }
+ return NULL;
+}
+
+/**
+ * rio_dev_get - Increments the reference count of the RIO device structure
+ *
+ * @rdev: RIO device being referenced
+ *
+ * Each live reference to a device should be refcounted.
+ *
+ * Drivers for RIO devices should normally record such references in
+ * their probe() methods, when they bind to a device, and release
+ * them by calling rio_dev_put(), in their disconnect() methods.
+ */
+struct rio_dev *rio_dev_get(struct rio_dev *rdev)
+{
+ if (rdev)
+ get_device(&rdev->dev);
+
+ return rdev;
+}
+
+/**
+ * rio_dev_put - Release a use of the RIO device structure
+ *
+ * @rdev: RIO device being disconnected
+ *
+ * Must be called when a user of a device is finished with it.
+ * When the last user of the device calls this function, the
+ * memory of the device is freed.
+ */
+void rio_dev_put(struct rio_dev *rdev)
+{
+ if (rdev)
+ put_device(&rdev->dev);
+}
+
+/**
+ * rio_device_probe - Tell if a RIO device structure has a matching RIO
+ * device id structure
+ * @id: the RIO device id structure to match against
+ * @dev: the RIO device structure to match against
+ *
+ * return 0 and set rio_dev->driver when drv claims rio_dev, else error
+ */
+static int rio_device_probe(struct device *dev)
+{
+ struct rio_driver *rdrv = to_rio_driver(dev->driver);
+ struct rio_dev *rdev = to_rio_dev(dev);
+ int error = -ENODEV;
+ const struct rio_device_id *id;
+
+ if (!rdev->driver && rdrv->probe) {
+ if (!rdrv->id_table)
+ return error;
+ id = rio_match_device(rdrv->id_table, rdev);
+ rio_dev_get(rdev);
+ if (id)
+ error = rdrv->probe(rdev, id);
+ if (error >= 0) {
+ rdev->driver = rdrv;
+ error = 0;
+ rio_dev_put(rdev);
+ }
+ }
+ return error;
+}
+
+/**
+ * rio_device_remove - Remove a RIO device from the system
+ *
+ * @dev: the RIO device structure to match against
+ *
+ * Remove a RIO device from the system. If it has an associated
+ * driver, then run the driver remove() method. Then update
+ * the reference count.
+ */
+static int rio_device_remove(struct device *dev)
+{
+ struct rio_dev *rdev = to_rio_dev(dev);
+ struct rio_driver *rdrv = rdev->driver;
+
+ if (rdrv) {
+ if (rdrv->remove)
+ rdrv->remove(rdev);
+ rdev->driver = NULL;
+ }
+
+ rio_dev_put(rdev);
+
+ return 0;
+}
+
+/**
+ * rio_register_driver - register a new RIO driver
+ * @rdrv: the RIO driver structure to register
+ *
+ * Adds a &struct rio_driver to the list of registered drivers
+ * Returns a negative value on error, otherwise 0. If no error
+ * occurred, the driver remains registered even if no device
+ * was claimed during registration.
+ */
+int rio_register_driver(struct rio_driver *rdrv)
+{
+ /* initialize common driver fields */
+ rdrv->driver.name = rdrv->name;
+ rdrv->driver.bus = &rio_bus_type;
+ rdrv->driver.probe = rio_device_probe;
+ rdrv->driver.remove = rio_device_remove;
+
+ /* register with core */
+ return driver_register(&rdrv->driver);
+}
+
+/**
+ * rio_unregister_driver - unregister a RIO driver
+ * @rdrv: the RIO driver structure to unregister
+ *
+ * Deletes the &struct rio_driver from the list of registered RIO
+ * drivers, gives it a chance to clean up by calling its remove()
+ * function for each device it was responsible for, and marks those
+ * devices as driverless.
+ */
+void rio_unregister_driver(struct rio_driver *rdrv)
+{
+ driver_unregister(&rdrv->driver);
+}
+
+/**
+ * rio_match_bus - Tell if a RIO device structure has a matching RIO
+ * driver device id structure
+ * @dev: the standard device structure to match against
+ * @drv: the standard driver structure containing the ids to match against
+ *
+ * Used by a driver to check whether a RIO device present in the
+ * system is in its list of supported devices. Returns 1 if
+ * there is a matching &struct rio_device_id or 0 if there is
+ * no match.
+ */
+static int rio_match_bus(struct device *dev, struct device_driver *drv)
+{
+ struct rio_dev *rdev = to_rio_dev(dev);
+ struct rio_driver *rdrv = to_rio_driver(drv);
+ const struct rio_device_id *id = rdrv->id_table;
+ const struct rio_device_id *found_id;
+
+ if (!id)
+ goto out;
+
+ found_id = rio_match_device(id, rdev);
+
+ if (found_id)
+ return 1;
+
+ out:return 0;
+}
+
+static struct device rio_bus = {
+ .bus_id = "rapidio",
+};
+
+struct bus_type rio_bus_type = {
+ .name = "rapidio",
+ .match = rio_match_bus,
+ .dev_attrs = rio_dev_attrs
+};
+
+/**
+ * rio_bus_init - Register the RapidIO bus with the device model
+ *
+ * Registers the RIO bus device and RIO bus type with the Linux
+ * device model.
+ */
+static int __init rio_bus_init(void)
+{
+ if (device_register(&rio_bus) < 0)
+ printk("RIO: failed to register RIO bus device\n");
+ return bus_register(&rio_bus_type);
+}
+
+postcore_initcall(rio_bus_init);
+
+EXPORT_SYMBOL_GPL(rio_register_driver);
+EXPORT_SYMBOL_GPL(rio_unregister_driver);
+EXPORT_SYMBOL_GPL(rio_bus_type);
+EXPORT_SYMBOL_GPL(rio_dev_get);
+EXPORT_SYMBOL_GPL(rio_dev_put);
diff --git a/drivers/rapidio/rio-scan.c b/drivers/rapidio/rio-scan.c
new file mode 100644
index 000000000000..4f7ed4bd3be9
--- /dev/null
+++ b/drivers/rapidio/rio-scan.c
@@ -0,0 +1,945 @@
+/*
+ * RapidIO enumeration and discovery support
+ *
+ * Copyright 2005 MontaVista Software, Inc.
+ * Matt Porter <mporter@kernel.crashing.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/config.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+
+#include <linux/delay.h>
+#include <linux/dma-mapping.h>
+#include <linux/init.h>
+#include <linux/rio.h>
+#include <linux/rio_drv.h>
+#include <linux/rio_ids.h>
+#include <linux/rio_regs.h>
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <linux/timer.h>
+
+#include "rio.h"
+
+LIST_HEAD(rio_devices);
+static LIST_HEAD(rio_switches);
+
+#define RIO_ENUM_CMPL_MAGIC 0xdeadbeef
+
+static void rio_enum_timeout(unsigned long);
+
+DEFINE_SPINLOCK(rio_global_list_lock);
+
+static int next_destid = 0;
+static int next_switchid = 0;
+static int next_net = 0;
+
+static struct timer_list rio_enum_timer =
+TIMER_INITIALIZER(rio_enum_timeout, 0, 0);
+
+static int rio_mport_phys_table[] = {
+ RIO_EFB_PAR_EP_ID,
+ RIO_EFB_PAR_EP_REC_ID,
+ RIO_EFB_SER_EP_ID,
+ RIO_EFB_SER_EP_REC_ID,
+ -1,
+};
+
+static int rio_sport_phys_table[] = {
+ RIO_EFB_PAR_EP_FREE_ID,
+ RIO_EFB_SER_EP_FREE_ID,
+ -1,
+};
+
+/**
+ * rio_get_device_id - Get the base/extended device id for a device
+ * @port: RIO master port
+ * @destid: Destination ID of device
+ * @hopcount: Hopcount to device
+ *
+ * Reads the base/extended device id from a device. Returns the
+ * 8/16-bit device ID.
+ */
+static u16 rio_get_device_id(struct rio_mport *port, u16 destid, u8 hopcount)
+{
+ u32 result;
+
+ rio_mport_read_config_32(port, destid, hopcount, RIO_DID_CSR, &result);
+
+ return RIO_GET_DID(result);
+}
+
+/**
+ * rio_set_device_id - Set the base/extended device id for a device
+ * @port: RIO master port
+ * @destid: Destination ID of device
+ * @hopcount: Hopcount to device
+ * @did: Device ID value to be written
+ *
+ * Writes the base/extended device id from a device.
+ */
+static void rio_set_device_id(struct rio_mport *port, u16 destid, u8 hopcount, u16 did)
+{
+ rio_mport_write_config_32(port, destid, hopcount, RIO_DID_CSR,
+ RIO_SET_DID(did));
+}
+
+/**
+ * rio_local_set_device_id - Set the base/extended device id for a port
+ * @port: RIO master port
+ * @did: Device ID value to be written
+ *
+ * Writes the base/extended device id from a device.
+ */
+static void rio_local_set_device_id(struct rio_mport *port, u16 did)
+{
+ rio_local_write_config_32(port, RIO_DID_CSR, RIO_SET_DID(did));
+}
+
+/**
+ * rio_clear_locks- Release all host locks and signal enumeration complete
+ * @port: Master port to issue transaction
+ *
+ * Marks the component tag CSR on each device with the enumeration
+ * complete flag. When complete, it then release the host locks on
+ * each device. Returns 0 on success or %-EINVAL on failure.
+ */
+static int rio_clear_locks(struct rio_mport *port)
+{
+ struct rio_dev *rdev;
+ u32 result;
+ int ret = 0;
+
+ /* Write component tag CSR magic complete value */
+ rio_local_write_config_32(port, RIO_COMPONENT_TAG_CSR,
+ RIO_ENUM_CMPL_MAGIC);
+ list_for_each_entry(rdev, &rio_devices, global_list)
+ rio_write_config_32(rdev, RIO_COMPONENT_TAG_CSR,
+ RIO_ENUM_CMPL_MAGIC);
+
+ /* Release host device id locks */
+ rio_local_write_config_32(port, RIO_HOST_DID_LOCK_CSR,
+ port->host_deviceid);
+ rio_local_read_config_32(port, RIO_HOST_DID_LOCK_CSR, &result);
+ if ((result & 0xffff) != 0xffff) {
+ printk(KERN_INFO
+ "RIO: badness when releasing host lock on master port, result %8.8x\n",
+ result);
+ ret = -EINVAL;
+ }
+ list_for_each_entry(rdev, &rio_devices, global_list) {
+ rio_write_config_32(rdev, RIO_HOST_DID_LOCK_CSR,
+ port->host_deviceid);
+ rio_read_config_32(rdev, RIO_HOST_DID_LOCK_CSR, &result);
+ if ((result & 0xffff) != 0xffff) {
+ printk(KERN_INFO
+ "RIO: badness when releasing host lock on vid %4.4x did %4.4x\n",
+ rdev->vid, rdev->did);
+ ret = -EINVAL;
+ }
+ }
+
+ return ret;
+}
+
+/**
+ * rio_enum_host- Set host lock and initialize host destination ID
+ * @port: Master port to issue transaction
+ *
+ * Sets the local host master port lock and destination ID register
+ * with the host device ID value. The host device ID value is provided
+ * by the platform. Returns %0 on success or %-1 on failure.
+ */
+static int rio_enum_host(struct rio_mport *port)
+{
+ u32 result;
+
+ /* Set master port host device id lock */
+ rio_local_write_config_32(port, RIO_HOST_DID_LOCK_CSR,
+ port->host_deviceid);
+
+ rio_local_read_config_32(port, RIO_HOST_DID_LOCK_CSR, &result);
+ if ((result & 0xffff) != port->host_deviceid)
+ return -1;
+
+ /* Set master port destid and init destid ctr */
+ rio_local_set_device_id(port, port->host_deviceid);
+
+ if (next_destid == port->host_deviceid)
+ next_destid++;
+
+ return 0;
+}
+
+/**
+ * rio_device_has_destid- Test if a device contains a destination ID register
+ * @port: Master port to issue transaction
+ * @src_ops: RIO device source operations
+ * @dst_ops: RIO device destination operations
+ *
+ * Checks the provided @src_ops and @dst_ops for the necessary transaction
+ * capabilities that indicate whether or not a device will implement a
+ * destination ID register. Returns 1 if true or 0 if false.
+ */
+static int rio_device_has_destid(struct rio_mport *port, int src_ops,
+ int dst_ops)
+{
+ u32 mask = RIO_OPS_READ | RIO_OPS_WRITE | RIO_OPS_ATOMIC_TST_SWP | RIO_OPS_ATOMIC_INC | RIO_OPS_ATOMIC_DEC | RIO_OPS_ATOMIC_SET | RIO_OPS_ATOMIC_CLR;
+
+ return !!((src_ops | dst_ops) & mask);
+}
+
+/**
+ * rio_release_dev- Frees a RIO device struct
+ * @dev: LDM device associated with a RIO device struct
+ *
+ * Gets the RIO device struct associated a RIO device struct.
+ * The RIO device struct is freed.
+ */
+static void rio_release_dev(struct device *dev)
+{
+ struct rio_dev *rdev;
+
+ rdev = to_rio_dev(dev);
+ kfree(rdev);
+}
+
+/**
+ * rio_is_switch- Tests if a RIO device has switch capabilities
+ * @rdev: RIO device
+ *
+ * Gets the RIO device Processing Element Features register
+ * contents and tests for switch capabilities. Returns 1 if
+ * the device is a switch or 0 if it is not a switch.
+ * The RIO device struct is freed.
+ */
+static int rio_is_switch(struct rio_dev *rdev)
+{
+ if (rdev->pef & RIO_PEF_SWITCH)
+ return 1;
+ return 0;
+}
+
+/**
+ * rio_route_set_ops- Sets routing operations for a particular vendor switch
+ * @rdev: RIO device
+ *
+ * Searches the RIO route ops table for known switch types. If the vid
+ * and did match a switch table entry, then set the add_entry() and
+ * get_entry() ops to the table entry values.
+ */
+static void rio_route_set_ops(struct rio_dev *rdev)
+{
+ struct rio_route_ops *cur = __start_rio_route_ops;
+ struct rio_route_ops *end = __end_rio_route_ops;
+
+ while (cur < end) {
+ if ((cur->vid == rdev->vid) && (cur->did == rdev->did)) {
+ pr_debug("RIO: adding routing ops for %s\n", rio_name(rdev));
+ rdev->rswitch->add_entry = cur->add_hook;
+ rdev->rswitch->get_entry = cur->get_hook;
+ }
+ cur++;
+ }
+
+ if (!rdev->rswitch->add_entry || !rdev->rswitch->get_entry)
+ printk(KERN_ERR "RIO: missing routing ops for %s\n",
+ rio_name(rdev));
+}
+
+/**
+ * rio_add_device- Adds a RIO device to the device model
+ * @rdev: RIO device
+ *
+ * Adds the RIO device to the global device list and adds the RIO
+ * device to the RIO device list. Creates the generic sysfs nodes
+ * for an RIO device.
+ */
+static void __devinit rio_add_device(struct rio_dev *rdev)
+{
+ device_add(&rdev->dev);
+
+ spin_lock(&rio_global_list_lock);
+ list_add_tail(&rdev->global_list, &rio_devices);
+ spin_unlock(&rio_global_list_lock);
+
+ rio_create_sysfs_dev_files(rdev);
+}
+
+/**
+ * rio_setup_device- Allocates and sets up a RIO device
+ * @net: RIO network
+ * @port: Master port to send transactions
+ * @destid: Current destination ID
+ * @hopcount: Current hopcount
+ * @do_enum: Enumeration/Discovery mode flag
+ *
+ * Allocates a RIO device and configures fields based on configuration
+ * space contents. If device has a destination ID register, a destination
+ * ID is either assigned in enumeration mode or read from configuration
+ * space in discovery mode. If the device has switch capabilities, then
+ * a switch is allocated and configured appropriately. Returns a pointer
+ * to a RIO device on success or NULL on failure.
+ *
+ */
+static struct rio_dev *rio_setup_device(struct rio_net *net,
+ struct rio_mport *port, u16 destid,
+ u8 hopcount, int do_enum)
+{
+ struct rio_dev *rdev;
+ struct rio_switch *rswitch;
+ int result, rdid;
+
+ rdev = kmalloc(sizeof(struct rio_dev), GFP_KERNEL);
+ if (!rdev)
+ goto out;
+
+ memset(rdev, 0, sizeof(struct rio_dev));
+ rdev->net = net;
+ rio_mport_read_config_32(port, destid, hopcount, RIO_DEV_ID_CAR,
+ &result);
+ rdev->did = result >> 16;
+ rdev->vid = result & 0xffff;
+ rio_mport_read_config_32(port, destid, hopcount, RIO_DEV_INFO_CAR,
+ &rdev->device_rev);
+ rio_mport_read_config_32(port, destid, hopcount, RIO_ASM_ID_CAR,
+ &result);
+ rdev->asm_did = result >> 16;
+ rdev->asm_vid = result & 0xffff;
+ rio_mport_read_config_32(port, destid, hopcount, RIO_ASM_INFO_CAR,
+ &result);
+ rdev->asm_rev = result >> 16;
+ rio_mport_read_config_32(port, destid, hopcount, RIO_PEF_CAR,
+ &rdev->pef);
+ if (rdev->pef & RIO_PEF_EXT_FEATURES)
+ rdev->efptr = result & 0xffff;
+
+ rio_mport_read_config_32(port, destid, hopcount, RIO_SRC_OPS_CAR,
+ &rdev->src_ops);
+ rio_mport_read_config_32(port, destid, hopcount, RIO_DST_OPS_CAR,
+ &rdev->dst_ops);
+
+ if (rio_device_has_destid(port, rdev->src_ops, rdev->dst_ops)
+ && do_enum) {
+ rio_set_device_id(port, destid, hopcount, next_destid);
+ rdev->destid = next_destid++;
+ if (next_destid == port->host_deviceid)
+ next_destid++;
+ } else
+ rdev->destid = rio_get_device_id(port, destid, hopcount);
+
+ /* If a PE has both switch and other functions, show it as a switch */
+ if (rio_is_switch(rdev)) {
+ rio_mport_read_config_32(port, destid, hopcount,
+ RIO_SWP_INFO_CAR, &rdev->swpinfo);
+ rswitch = kmalloc(sizeof(struct rio_switch), GFP_KERNEL);
+ if (!rswitch) {
+ kfree(rdev);
+ rdev = NULL;
+ goto out;
+ }
+ rswitch->switchid = next_switchid;
+ rswitch->hopcount = hopcount;
+ rswitch->destid = 0xffff;
+ /* Initialize switch route table */
+ for (rdid = 0; rdid < RIO_MAX_ROUTE_ENTRIES; rdid++)
+ rswitch->route_table[rdid] = RIO_INVALID_ROUTE;
+ rdev->rswitch = rswitch;
+ sprintf(rio_name(rdev), "%02x:s:%04x", rdev->net->id,
+ rdev->rswitch->switchid);
+ rio_route_set_ops(rdev);
+
+ list_add_tail(&rswitch->node, &rio_switches);
+
+ } else
+ sprintf(rio_name(rdev), "%02x:e:%04x", rdev->net->id,
+ rdev->destid);
+
+ rdev->dev.bus = &rio_bus_type;
+
+ device_initialize(&rdev->dev);
+ rdev->dev.release = rio_release_dev;
+ rio_dev_get(rdev);
+
+ rdev->dma_mask = DMA_32BIT_MASK;
+ rdev->dev.dma_mask = &rdev->dma_mask;
+ rdev->dev.coherent_dma_mask = DMA_32BIT_MASK;
+
+ if ((rdev->pef & RIO_PEF_INB_DOORBELL) &&
+ (rdev->dst_ops & RIO_DST_OPS_DOORBELL))
+ rio_init_dbell_res(&rdev->riores[RIO_DOORBELL_RESOURCE],
+ 0, 0xffff);
+
+ rio_add_device(rdev);
+
+ out:
+ return rdev;
+}
+
+/**
+ * rio_sport_is_active- Tests if a switch port has an active connection.
+ * @port: Master port to send transaction
+ * @destid: Associated destination ID for switch
+ * @hopcount: Hopcount to reach switch
+ * @sport: Switch port number
+ *
+ * Reads the port error status CSR for a particular switch port to
+ * determine if the port has an active link. Returns
+ * %PORT_N_ERR_STS_PORT_OK if the port is active or %0 if it is
+ * inactive.
+ */
+static int
+rio_sport_is_active(struct rio_mport *port, u16 destid, u8 hopcount, int sport)
+{
+ u32 result;
+ u32 ext_ftr_ptr;
+
+ int *entry = rio_sport_phys_table;
+
+ do {
+ if ((ext_ftr_ptr =
+ rio_mport_get_feature(port, 0, destid, hopcount, *entry)))
+
+ break;
+ } while (*++entry >= 0);
+
+ if (ext_ftr_ptr)
+ rio_mport_read_config_32(port, destid, hopcount,
+ ext_ftr_ptr +
+ RIO_PORT_N_ERR_STS_CSR(sport),
+ &result);
+
+ return (result & PORT_N_ERR_STS_PORT_OK);
+}
+
+/**
+ * rio_route_add_entry- Add a route entry to a switch routing table
+ * @mport: Master port to send transaction
+ * @rdev: Switch device
+ * @table: Routing table ID
+ * @route_destid: Destination ID to be routed
+ * @route_port: Port number to be routed
+ *
+ * Calls the switch specific add_entry() method to add a route entry
+ * on a switch. The route table can be specified using the @table
+ * argument if a switch has per port routing tables or the normal
+ * use is to specific all tables (or the global table) by passing
+ * %RIO_GLOBAL_TABLE in @table. Returns %0 on success or %-EINVAL
+ * on failure.
+ */
+static int rio_route_add_entry(struct rio_mport *mport, struct rio_dev *rdev,
+ u16 table, u16 route_destid, u8 route_port)
+{
+ return rdev->rswitch->add_entry(mport, rdev->rswitch->destid,
+ rdev->rswitch->hopcount, table,
+ route_destid, route_port);
+}
+
+/**
+ * rio_route_get_entry- Read a route entry in a switch routing table
+ * @mport: Master port to send transaction
+ * @rdev: Switch device
+ * @table: Routing table ID
+ * @route_destid: Destination ID to be routed
+ * @route_port: Pointer to read port number into
+ *
+ * Calls the switch specific get_entry() method to read a route entry
+ * in a switch. The route table can be specified using the @table
+ * argument if a switch has per port routing tables or the normal
+ * use is to specific all tables (or the global table) by passing
+ * %RIO_GLOBAL_TABLE in @table. Returns %0 on success or %-EINVAL
+ * on failure.
+ */
+static int
+rio_route_get_entry(struct rio_mport *mport, struct rio_dev *rdev, u16 table,
+ u16 route_destid, u8 * route_port)
+{
+ return rdev->rswitch->get_entry(mport, rdev->rswitch->destid,
+ rdev->rswitch->hopcount, table,
+ route_destid, route_port);
+}
+
+/**
+ * rio_get_host_deviceid_lock- Reads the Host Device ID Lock CSR on a device
+ * @port: Master port to send transaction
+ * @hopcount: Number of hops to the device
+ *
+ * Used during enumeration to read the Host Device ID Lock CSR on a
+ * RIO device. Returns the value of the lock register.
+ */
+static u16 rio_get_host_deviceid_lock(struct rio_mport *port, u8 hopcount)
+{
+ u32 result;
+
+ rio_mport_read_config_32(port, RIO_ANY_DESTID, hopcount,
+ RIO_HOST_DID_LOCK_CSR, &result);
+
+ return (u16) (result & 0xffff);
+}
+
+/**
+ * rio_get_swpinfo_inport- Gets the ingress port number
+ * @mport: Master port to send transaction
+ * @destid: Destination ID associated with the switch
+ * @hopcount: Number of hops to the device
+ *
+ * Returns port number being used to access the switch device.
+ */
+static u8
+rio_get_swpinfo_inport(struct rio_mport *mport, u16 destid, u8 hopcount)
+{
+ u32 result;
+
+ rio_mport_read_config_32(mport, destid, hopcount, RIO_SWP_INFO_CAR,
+ &result);
+
+ return (u8) (result & 0xff);
+}
+
+/**
+ * rio_get_swpinfo_tports- Gets total number of ports on the switch
+ * @mport: Master port to send transaction
+ * @destid: Destination ID associated with the switch
+ * @hopcount: Number of hops to the device
+ *
+ * Returns total numbers of ports implemented by the switch device.
+ */
+static u8 rio_get_swpinfo_tports(struct rio_mport *mport, u16 destid,
+ u8 hopcount)
+{
+ u32 result;
+
+ rio_mport_read_config_32(mport, destid, hopcount, RIO_SWP_INFO_CAR,
+ &result);
+
+ return RIO_GET_TOTAL_PORTS(result);
+}
+
+/**
+ * rio_net_add_mport- Add a master port to a RIO network
+ * @net: RIO network
+ * @port: Master port to add
+ *
+ * Adds a master port to the network list of associated master
+ * ports..
+ */
+static void rio_net_add_mport(struct rio_net *net, struct rio_mport *port)
+{
+ spin_lock(&rio_global_list_lock);
+ list_add_tail(&port->nnode, &net->mports);
+ spin_unlock(&rio_global_list_lock);
+}
+
+/**
+ * rio_enum_peer- Recursively enumerate a RIO network through a master port
+ * @net: RIO network being enumerated
+ * @port: Master port to send transactions
+ * @hopcount: Number of hops into the network
+ *
+ * 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,
+ u8 hopcount)
+{
+ int port_num;
+ int num_ports;
+ int cur_destid;
+ struct rio_dev *rdev;
+ u16 destid;
+ int tmp;
+
+ if (rio_get_host_deviceid_lock(port, hopcount) == port->host_deviceid) {
+ pr_debug("RIO: PE already discovered by this host\n");
+ /*
+ * Already discovered by this host. Add it as another
+ * master port for the current network.
+ */
+ rio_net_add_mport(net, port);
+ return 0;
+ }
+
+ /* Attempt to acquire device lock */
+ rio_mport_write_config_32(port, RIO_ANY_DESTID, hopcount,
+ RIO_HOST_DID_LOCK_CSR, port->host_deviceid);
+ while ((tmp = rio_get_host_deviceid_lock(port, hopcount))
+ < port->host_deviceid) {
+ /* Delay a bit */
+ mdelay(1);
+ /* Attempt to acquire device lock again */
+ rio_mport_write_config_32(port, RIO_ANY_DESTID, hopcount,
+ RIO_HOST_DID_LOCK_CSR,
+ port->host_deviceid);
+ }
+
+ if (rio_get_host_deviceid_lock(port, hopcount) > port->host_deviceid) {
+ pr_debug(
+ "RIO: PE locked by a higher priority host...retreating\n");
+ return -1;
+ }
+
+ /* Setup new RIO device */
+ if ((rdev = rio_setup_device(net, port, RIO_ANY_DESTID, hopcount, 1))) {
+ /* Add device to the global and bus/net specific list. */
+ list_add_tail(&rdev->net_list, &net->devices);
+ } else
+ return -1;
+
+ if (rio_is_switch(rdev)) {
+ next_switchid++;
+
+ for (destid = 0; destid < next_destid; destid++) {
+ rio_route_add_entry(port, rdev, RIO_GLOBAL_TABLE,
+ destid, rio_get_swpinfo_inport(port,
+ RIO_ANY_DESTID,
+ hopcount));
+ rdev->rswitch->route_table[destid] =
+ rio_get_swpinfo_inport(port, RIO_ANY_DESTID,
+ hopcount);
+ }
+
+ num_ports =
+ rio_get_swpinfo_tports(port, RIO_ANY_DESTID, hopcount);
+ pr_debug(
+ "RIO: found %s (vid %4.4x did %4.4x) with %d ports\n",
+ rio_name(rdev), rdev->vid, rdev->did, num_ports);
+ for (port_num = 0; port_num < num_ports; port_num++) {
+ if (rio_get_swpinfo_inport
+ (port, RIO_ANY_DESTID, hopcount) == port_num)
+ continue;
+
+ cur_destid = next_destid;
+
+ if (rio_sport_is_active
+ (port, RIO_ANY_DESTID, hopcount, port_num)) {
+ pr_debug(
+ "RIO: scanning device on port %d\n",
+ port_num);
+ rio_route_add_entry(port, rdev,
+ RIO_GLOBAL_TABLE,
+ RIO_ANY_DESTID, port_num);
+
+ if (rio_enum_peer(net, port, hopcount + 1) < 0)
+ return -1;
+
+ /* Update routing tables */
+ if (next_destid > cur_destid) {
+ for (destid = cur_destid;
+ destid < next_destid; destid++) {
+ rio_route_add_entry(port, rdev,
+ RIO_GLOBAL_TABLE,
+ destid,
+ port_num);
+ rdev->rswitch->
+ route_table[destid] =
+ port_num;
+ }
+ rdev->rswitch->destid = cur_destid;
+ }
+ }
+ }
+ } else
+ pr_debug("RIO: found %s (vid %4.4x did %4.4x)\n",
+ rio_name(rdev), rdev->vid, rdev->did);
+
+ return 0;
+}
+
+/**
+ * rio_enum_complete- Tests if enumeration of a network is complete
+ * @port: Master port to send transaction
+ *
+ * Tests the Component Tag CSR for presence of the magic enumeration
+ * complete flag. Return %1 if enumeration is complete or %0 if
+ * enumeration is incomplete.
+ */
+static int rio_enum_complete(struct rio_mport *port)
+{
+ u32 tag_csr;
+ int ret = 0;
+
+ rio_local_read_config_32(port, RIO_COMPONENT_TAG_CSR, &tag_csr);
+
+ if (tag_csr == RIO_ENUM_CMPL_MAGIC)
+ ret = 1;
+
+ return ret;
+}
+
+/**
+ * rio_disc_peer- Recursively discovers a RIO network through a master port
+ * @net: RIO network being discovered
+ * @port: Master port to send transactions
+ * @destid: Current destination ID in network
+ * @hopcount: Number of hops into the network
+ *
+ * Recursively discovers a RIO network. Transactions are sent via the
+ * master port passed in @port.
+ */
+static int
+rio_disc_peer(struct rio_net *net, struct rio_mport *port, u16 destid,
+ u8 hopcount)
+{
+ u8 port_num, route_port;
+ int num_ports;
+ struct rio_dev *rdev;
+ u16 ndestid;
+
+ /* Setup new RIO device */
+ if ((rdev = rio_setup_device(net, port, destid, hopcount, 0))) {
+ /* Add device to the global and bus/net specific list. */
+ list_add_tail(&rdev->net_list, &net->devices);
+ } else
+ return -1;
+
+ if (rio_is_switch(rdev)) {
+ next_switchid++;
+
+ /* Associated destid is how we accessed this switch */
+ rdev->rswitch->destid = destid;
+
+ num_ports = rio_get_swpinfo_tports(port, destid, hopcount);
+ pr_debug(
+ "RIO: found %s (vid %4.4x did %4.4x) with %d ports\n",
+ rio_name(rdev), rdev->vid, rdev->did, num_ports);
+ for (port_num = 0; port_num < num_ports; port_num++) {
+ if (rio_get_swpinfo_inport(port, destid, hopcount) ==
+ port_num)
+ continue;
+
+ if (rio_sport_is_active
+ (port, destid, hopcount, port_num)) {
+ pr_debug(
+ "RIO: scanning device on port %d\n",
+ port_num);
+ for (ndestid = 0; ndestid < RIO_ANY_DESTID;
+ ndestid++) {
+ rio_route_get_entry(port, rdev,
+ RIO_GLOBAL_TABLE,
+ ndestid,
+ &route_port);
+ if (route_port == port_num)
+ break;
+ }
+
+ if (rio_disc_peer
+ (net, port, ndestid, hopcount + 1) < 0)
+ return -1;
+ }
+ }
+ } else
+ pr_debug("RIO: found %s (vid %4.4x did %4.4x)\n",
+ rio_name(rdev), rdev->vid, rdev->did);
+
+ return 0;
+}
+
+/**
+ * rio_mport_is_active- Tests if master port link is active
+ * @port: Master port to test
+ *
+ * Reads the port error status CSR for the master port to
+ * determine if the port has an active link. Returns
+ * %PORT_N_ERR_STS_PORT_OK if the master port is active
+ * or %0 if it is inactive.
+ */
+static int rio_mport_is_active(struct rio_mport *port)
+{
+ u32 result = 0;
+ u32 ext_ftr_ptr;
+ int *entry = rio_mport_phys_table;
+
+ do {
+ if ((ext_ftr_ptr =
+ rio_mport_get_feature(port, 1, 0, 0, *entry)))
+ break;
+ } while (*++entry >= 0);
+
+ if (ext_ftr_ptr)
+ rio_local_read_config_32(port,
+ ext_ftr_ptr +
+ RIO_PORT_N_ERR_STS_CSR(port->index),
+ &result);
+
+ return (result & PORT_N_ERR_STS_PORT_OK);
+}
+
+/**
+ * rio_alloc_net- Allocate and configure a new RIO network
+ * @port: Master port associated with the RIO network
+ *
+ * Allocates a RIO network structure, initializes per-network
+ * list heads, and adds the associated master port to the
+ * network list of associated master ports. Returns a
+ * RIO network pointer on success or %NULL on failure.
+ */
+static struct rio_net __devinit *rio_alloc_net(struct rio_mport *port)
+{
+ struct rio_net *net;
+
+ net = kmalloc(sizeof(struct rio_net), GFP_KERNEL);
+ if (net) {
+ memset(net, 0, sizeof(struct rio_net));
+ INIT_LIST_HEAD(&net->node);
+ INIT_LIST_HEAD(&net->devices);
+ INIT_LIST_HEAD(&net->mports);
+ list_add_tail(&port->nnode, &net->mports);
+ net->hport = port;
+ net->id = next_net++;
+ }
+ return net;
+}
+
+/**
+ * rio_enum_mport- Start enumeration through a master port
+ * @mport: Master port to send transactions
+ *
+ * Starts the enumeration process. If somebody has enumerated our
+ * master port device, then give up. If not and we have an active
+ * link, then start recursive peer enumeration. Returns %0 if
+ * enumeration succeeds or %-EBUSY if enumeration fails.
+ */
+int rio_enum_mport(struct rio_mport *mport)
+{
+ struct rio_net *net = NULL;
+ int rc = 0;
+
+ printk(KERN_INFO "RIO: enumerate master port %d, %s\n", mport->id,
+ mport->name);
+ /* If somebody else enumerated our master port device, bail. */
+ if (rio_enum_host(mport) < 0) {
+ printk(KERN_INFO
+ "RIO: master port %d device has been enumerated by a remote host\n",
+ mport->id);
+ rc = -EBUSY;
+ goto out;
+ }
+
+ /* If master port has an active link, allocate net and enum peers */
+ if (rio_mport_is_active(mport)) {
+ if (!(net = rio_alloc_net(mport))) {
+ printk(KERN_ERR "RIO: failed to allocate new net\n");
+ rc = -ENOMEM;
+ goto out;
+ }
+ if (rio_enum_peer(net, mport, 0) < 0) {
+ /* A higher priority host won enumeration, bail. */
+ printk(KERN_INFO
+ "RIO: master port %d device has lost enumeration to a remote host\n",
+ mport->id);
+ rio_clear_locks(mport);
+ rc = -EBUSY;
+ goto out;
+ }
+ rio_clear_locks(mport);
+ } else {
+ printk(KERN_INFO "RIO: master port %d link inactive\n",
+ mport->id);
+ rc = -EINVAL;
+ }
+
+ out:
+ return rc;
+}
+
+/**
+ * rio_build_route_tables- Generate route tables from switch route entries
+ *
+ * For each switch device, generate a route table by copying existing
+ * route entries from the switch.
+ */
+static void rio_build_route_tables(void)
+{
+ struct rio_dev *rdev;
+ int i;
+ u8 sport;
+
+ list_for_each_entry(rdev, &rio_devices, global_list)
+ if (rio_is_switch(rdev))
+ for (i = 0; i < RIO_MAX_ROUTE_ENTRIES; i++) {
+ if (rio_route_get_entry
+ (rdev->net->hport, rdev, RIO_GLOBAL_TABLE, i,
+ &sport) < 0)
+ continue;
+ rdev->rswitch->route_table[i] = sport;
+ }
+}
+
+/**
+ * rio_enum_timeout- Signal that enumeration timed out
+ * @data: Address of timeout flag.
+ *
+ * When the enumeration complete timer expires, set a flag that
+ * signals to the discovery process that enumeration did not
+ * complete in a sane amount of time.
+ */
+static void rio_enum_timeout(unsigned long data)
+{
+ /* Enumeration timed out, set flag */
+ *(int *)data = 1;
+}
+
+/**
+ * rio_disc_mport- Start discovery through a master port
+ * @mport: Master port to send transactions
+ *
+ * Starts the discovery process. If we have an active link,
+ * then wait for the signal that enumeration is complete.
+ * When enumeration completion is signaled, start recursive
+ * peer discovery. Returns %0 if discovery succeeds or %-EBUSY
+ * on failure.
+ */
+int rio_disc_mport(struct rio_mport *mport)
+{
+ struct rio_net *net = NULL;
+ int enum_timeout_flag = 0;
+
+ printk(KERN_INFO "RIO: discover master port %d, %s\n", mport->id,
+ mport->name);
+
+ /* If master port has an active link, allocate net and discover peers */
+ if (rio_mport_is_active(mport)) {
+ if (!(net = rio_alloc_net(mport))) {
+ printk(KERN_ERR "RIO: Failed to allocate new net\n");
+ goto bail;
+ }
+
+ pr_debug("RIO: wait for enumeration complete...");
+
+ rio_enum_timer.expires =
+ jiffies + CONFIG_RAPIDIO_DISC_TIMEOUT * HZ;
+ rio_enum_timer.data = (unsigned long)&enum_timeout_flag;
+ add_timer(&rio_enum_timer);
+ while (!rio_enum_complete(mport)) {
+ mdelay(1);
+ if (enum_timeout_flag) {
+ del_timer_sync(&rio_enum_timer);
+ goto timeout;
+ }
+ }
+ del_timer_sync(&rio_enum_timer);
+
+ pr_debug("done\n");
+ if (rio_disc_peer(net, mport, RIO_ANY_DESTID, 0) < 0) {
+ printk(KERN_INFO
+ "RIO: master port %d device has failed discovery\n",
+ mport->id);
+ goto bail;
+ }
+
+ rio_build_route_tables();
+ }
+
+ return 0;
+
+ timeout:
+ pr_debug("timeout\n");
+ bail:
+ return -EBUSY;
+}
diff --git a/drivers/rapidio/rio-sysfs.c b/drivers/rapidio/rio-sysfs.c
new file mode 100644
index 000000000000..30a11436e241
--- /dev/null
+++ b/drivers/rapidio/rio-sysfs.c
@@ -0,0 +1,230 @@
+/*
+ * RapidIO sysfs attributes and support
+ *
+ * Copyright 2005 MontaVista Software, Inc.
+ * Matt Porter <mporter@kernel.crashing.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/config.h>
+#include <linux/kernel.h>
+#include <linux/rio.h>
+#include <linux/rio_drv.h>
+#include <linux/stat.h>
+
+#include "rio.h"
+
+/* Sysfs support */
+#define rio_config_attr(field, format_string) \
+static ssize_t \
+field##_show(struct device *dev, struct device_attribute *attr, char *buf) \
+{ \
+ struct rio_dev *rdev = to_rio_dev(dev); \
+ \
+ return sprintf(buf, format_string, rdev->field); \
+} \
+
+rio_config_attr(did, "0x%04x\n");
+rio_config_attr(vid, "0x%04x\n");
+rio_config_attr(device_rev, "0x%08x\n");
+rio_config_attr(asm_did, "0x%04x\n");
+rio_config_attr(asm_vid, "0x%04x\n");
+rio_config_attr(asm_rev, "0x%04x\n");
+
+static ssize_t routes_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ struct rio_dev *rdev = to_rio_dev(dev);
+ char *str = buf;
+ int i;
+
+ if (!rdev->rswitch)
+ goto out;
+
+ for (i = 0; i < RIO_MAX_ROUTE_ENTRIES; i++) {
+ if (rdev->rswitch->route_table[i] == RIO_INVALID_ROUTE)
+ continue;
+ str +=
+ sprintf(str, "%04x %02x\n", i,
+ rdev->rswitch->route_table[i]);
+ }
+
+ out:
+ return (str - buf);
+}
+
+struct device_attribute rio_dev_attrs[] = {
+ __ATTR_RO(did),
+ __ATTR_RO(vid),
+ __ATTR_RO(device_rev),
+ __ATTR_RO(asm_did),
+ __ATTR_RO(asm_vid),
+ __ATTR_RO(asm_rev),
+ __ATTR_RO(routes),
+ __ATTR_NULL,
+};
+
+static ssize_t
+rio_read_config(struct kobject *kobj, char *buf, loff_t off, size_t count)
+{
+ struct rio_dev *dev =
+ to_rio_dev(container_of(kobj, struct device, kobj));
+ unsigned int size = 0x100;
+ loff_t init_off = off;
+ u8 *data = (u8 *) buf;
+
+ /* Several chips lock up trying to read undefined config space */
+ if (capable(CAP_SYS_ADMIN))
+ size = 0x200000;
+
+ if (off > size)
+ return 0;
+ if (off + count > size) {
+ size -= off;
+ count = size;
+ } else {
+ size = count;
+ }
+
+ if ((off & 1) && size) {
+ u8 val;
+ rio_read_config_8(dev, off, &val);
+ data[off - init_off] = val;
+ off++;
+ size--;
+ }
+
+ if ((off & 3) && size > 2) {
+ u16 val;
+ rio_read_config_16(dev, off, &val);
+ data[off - init_off] = (val >> 8) & 0xff;
+ data[off - init_off + 1] = val & 0xff;
+ off += 2;
+ size -= 2;
+ }
+
+ while (size > 3) {
+ u32 val;
+ rio_read_config_32(dev, off, &val);
+ data[off - init_off] = (val >> 24) & 0xff;
+ data[off - init_off + 1] = (val >> 16) & 0xff;
+ data[off - init_off + 2] = (val >> 8) & 0xff;
+ data[off - init_off + 3] = val & 0xff;
+ off += 4;
+ size -= 4;
+ }
+
+ if (size >= 2) {
+ u16 val;
+ rio_read_config_16(dev, off, &val);
+ data[off - init_off] = (val >> 8) & 0xff;
+ data[off - init_off + 1] = val & 0xff;
+ off += 2;
+ size -= 2;
+ }
+
+ if (size > 0) {
+ u8 val;
+ rio_read_config_8(dev, off, &val);
+ data[off - init_off] = val;
+ off++;
+ --size;
+ }
+
+ return count;
+}
+
+static ssize_t
+rio_write_config(struct kobject *kobj, char *buf, loff_t off, size_t count)
+{
+ struct rio_dev *dev =
+ to_rio_dev(container_of(kobj, struct device, kobj));
+ unsigned int size = count;
+ loff_t init_off = off;
+ u8 *data = (u8 *) buf;
+
+ if (off > 0x200000)
+ return 0;
+ if (off + count > 0x200000) {
+ size = 0x200000 - off;
+ count = size;
+ }
+
+ if ((off & 1) && size) {
+ rio_write_config_8(dev, off, data[off - init_off]);
+ off++;
+ size--;
+ }
+
+ if ((off & 3) && (size > 2)) {
+ u16 val = data[off - init_off + 1];
+ val |= (u16) data[off - init_off] << 8;
+ rio_write_config_16(dev, off, val);
+ off += 2;
+ size -= 2;
+ }
+
+ while (size > 3) {
+ u32 val = data[off - init_off + 3];
+ val |= (u32) data[off - init_off + 2] << 8;
+ val |= (u32) data[off - init_off + 1] << 16;
+ val |= (u32) data[off - init_off] << 24;
+ rio_write_config_32(dev, off, val);
+ off += 4;
+ size -= 4;
+ }
+
+ if (size >= 2) {
+ u16 val = data[off - init_off + 1];
+ val |= (u16) data[off - init_off] << 8;
+ rio_write_config_16(dev, off, val);
+ off += 2;
+ size -= 2;
+ }
+
+ if (size) {
+ rio_write_config_8(dev, off, data[off - init_off]);
+ off++;
+ --size;
+ }
+
+ return count;
+}
+
+static struct bin_attribute rio_config_attr = {
+ .attr = {
+ .name = "config",
+ .mode = S_IRUGO | S_IWUSR,
+ .owner = THIS_MODULE,
+ },
+ .size = 0x200000,
+ .read = rio_read_config,
+ .write = rio_write_config,
+};
+
+/**
+ * rio_create_sysfs_dev_files - create RIO specific sysfs files
+ * @rdev: device whose entries should be created
+ *
+ * Create files when @rdev is added to sysfs.
+ */
+int rio_create_sysfs_dev_files(struct rio_dev *rdev)
+{
+ sysfs_create_bin_file(&rdev->dev.kobj, &rio_config_attr);
+
+ return 0;
+}
+
+/**
+ * rio_remove_sysfs_dev_files - cleanup RIO specific sysfs files
+ * @rdev: device whose entries we should free
+ *
+ * Cleanup when @rdev is removed from sysfs.
+ */
+void rio_remove_sysfs_dev_files(struct rio_dev *rdev)
+{
+ sysfs_remove_bin_file(&rdev->dev.kobj, &rio_config_attr);
+}
diff --git a/drivers/rapidio/rio.c b/drivers/rapidio/rio.c
new file mode 100644
index 000000000000..3ca1011ceaac
--- /dev/null
+++ b/drivers/rapidio/rio.c
@@ -0,0 +1,510 @@
+/*
+ * RapidIO interconnect services
+ * (RapidIO Interconnect Specification, http://www.rapidio.org)
+ *
+ * Copyright 2005 MontaVista Software, Inc.
+ * Matt Porter <mporter@kernel.crashing.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/config.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/rio.h>
+#include <linux/rio_drv.h>
+#include <linux/rio_ids.h>
+#include <linux/rio_regs.h>
+#include <linux/module.h>
+#include <linux/spinlock.h>
+
+#include "rio.h"
+
+static LIST_HEAD(rio_mports);
+
+/**
+ * rio_local_get_device_id - Get the base/extended device id for a port
+ * @port: RIO master port from which to get the deviceid
+ *
+ * Reads the base/extended device id from the local device
+ * implementing the master port. Returns the 8/16-bit device
+ * id.
+ */
+u16 rio_local_get_device_id(struct rio_mport *port)
+{
+ u32 result;
+
+ rio_local_read_config_32(port, RIO_DID_CSR, &result);
+
+ return (RIO_GET_DID(result));
+}
+
+/**
+ * rio_request_inb_mbox - request inbound mailbox service
+ * @mport: RIO master port from which to allocate the mailbox resource
+ * @dev_id: Device specific pointer to pass on event
+ * @mbox: Mailbox number to claim
+ * @entries: Number of entries in inbound mailbox queue
+ * @minb: Callback to execute when inbound message is received
+ *
+ * Requests ownership of an inbound mailbox resource and binds
+ * a callback function to the resource. Returns %0 on success.
+ */
+int rio_request_inb_mbox(struct rio_mport *mport,
+ void *dev_id,
+ int mbox,
+ int entries,
+ void (*minb) (struct rio_mport * mport, void *dev_id, int mbox,
+ int slot))
+{
+ int rc = 0;
+
+ struct resource *res = kmalloc(sizeof(struct resource), GFP_KERNEL);
+
+ if (res) {
+ rio_init_mbox_res(res, mbox, mbox);
+
+ /* Make sure this mailbox isn't in use */
+ if ((rc =
+ request_resource(&mport->riores[RIO_INB_MBOX_RESOURCE],
+ res)) < 0) {
+ kfree(res);
+ goto out;
+ }
+
+ mport->inb_msg[mbox].res = res;
+
+ /* Hook the inbound message callback */
+ mport->inb_msg[mbox].mcback = minb;
+
+ rc = rio_open_inb_mbox(mport, dev_id, mbox, entries);
+ } else
+ rc = -ENOMEM;
+
+ out:
+ return rc;
+}
+
+/**
+ * rio_release_inb_mbox - release inbound mailbox message service
+ * @mport: RIO master port from which to release the mailbox resource
+ * @mbox: Mailbox number to release
+ *
+ * Releases ownership of an inbound mailbox resource. Returns 0
+ * if the request has been satisfied.
+ */
+int rio_release_inb_mbox(struct rio_mport *mport, int mbox)
+{
+ rio_close_inb_mbox(mport, mbox);
+
+ /* Release the mailbox resource */
+ return release_resource(mport->inb_msg[mbox].res);
+}
+
+/**
+ * rio_request_outb_mbox - request outbound mailbox service
+ * @mport: RIO master port from which to allocate the mailbox resource
+ * @dev_id: Device specific pointer to pass on event
+ * @mbox: Mailbox number to claim
+ * @entries: Number of entries in outbound mailbox queue
+ * @moutb: Callback to execute when outbound message is sent
+ *
+ * Requests ownership of an outbound mailbox resource and binds
+ * a callback function to the resource. Returns 0 on success.
+ */
+int rio_request_outb_mbox(struct rio_mport *mport,
+ void *dev_id,
+ int mbox,
+ int entries,
+ void (*moutb) (struct rio_mport * mport, void *dev_id, int mbox, int slot))
+{
+ int rc = 0;
+
+ struct resource *res = kmalloc(sizeof(struct resource), GFP_KERNEL);
+
+ if (res) {
+ rio_init_mbox_res(res, mbox, mbox);
+
+ /* Make sure this outbound mailbox isn't in use */
+ if ((rc =
+ request_resource(&mport->riores[RIO_OUTB_MBOX_RESOURCE],
+ res)) < 0) {
+ kfree(res);
+ goto out;
+ }
+
+ mport->outb_msg[mbox].res = res;
+
+ /* Hook the inbound message callback */
+ mport->outb_msg[mbox].mcback = moutb;
+
+ rc = rio_open_outb_mbox(mport, dev_id, mbox, entries);
+ } else
+ rc = -ENOMEM;
+
+ out:
+ return rc;
+}
+
+/**
+ * rio_release_outb_mbox - release outbound mailbox message service
+ * @mport: RIO master port from which to release the mailbox resource
+ * @mbox: Mailbox number to release
+ *
+ * Releases ownership of an inbound mailbox resource. Returns 0
+ * if the request has been satisfied.
+ */
+int rio_release_outb_mbox(struct rio_mport *mport, int mbox)
+{
+ rio_close_outb_mbox(mport, mbox);
+
+ /* Release the mailbox resource */
+ return release_resource(mport->outb_msg[mbox].res);
+}
+
+/**
+ * rio_setup_inb_dbell - bind inbound doorbell callback
+ * @mport: RIO master port to bind the doorbell callback
+ * @dev_id: Device specific pointer to pass on event
+ * @res: Doorbell message resource
+ * @dinb: Callback to execute when doorbell is received
+ *
+ * Adds a doorbell resource/callback pair into a port's
+ * doorbell event list. Returns 0 if the request has been
+ * satisfied.
+ */
+static int
+rio_setup_inb_dbell(struct rio_mport *mport, void *dev_id, struct resource *res,
+ void (*dinb) (struct rio_mport * mport, void *dev_id, u16 src, u16 dst,
+ u16 info))
+{
+ int rc = 0;
+ struct rio_dbell *dbell;
+
+ if (!(dbell = kmalloc(sizeof(struct rio_dbell), GFP_KERNEL))) {
+ rc = -ENOMEM;
+ goto out;
+ }
+
+ dbell->res = res;
+ dbell->dinb = dinb;
+ dbell->dev_id = dev_id;
+
+ list_add_tail(&dbell->node, &mport->dbells);
+
+ out:
+ return rc;
+}
+
+/**
+ * rio_request_inb_dbell - request inbound doorbell message service
+ * @mport: RIO master port from which to allocate the doorbell resource
+ * @dev_id: Device specific pointer to pass on event
+ * @start: Doorbell info range start
+ * @end: Doorbell info range end
+ * @dinb: Callback to execute when doorbell is received
+ *
+ * Requests ownership of an inbound doorbell resource and binds
+ * a callback function to the resource. Returns 0 if the request
+ * has been satisfied.
+ */
+int rio_request_inb_dbell(struct rio_mport *mport,
+ void *dev_id,
+ u16 start,
+ u16 end,
+ void (*dinb) (struct rio_mport * mport, void *dev_id, u16 src,
+ u16 dst, u16 info))
+{
+ int rc = 0;
+
+ struct resource *res = kmalloc(sizeof(struct resource), GFP_KERNEL);
+
+ if (res) {
+ rio_init_dbell_res(res, start, end);
+
+ /* Make sure these doorbells aren't in use */
+ if ((rc =
+ request_resource(&mport->riores[RIO_DOORBELL_RESOURCE],
+ res)) < 0) {
+ kfree(res);
+ goto out;
+ }
+
+ /* Hook the doorbell callback */
+ rc = rio_setup_inb_dbell(mport, dev_id, res, dinb);
+ } else
+ rc = -ENOMEM;
+
+ out:
+ return rc;
+}
+
+/**
+ * rio_release_inb_dbell - release inbound doorbell message service
+ * @mport: RIO master port from which to release the doorbell resource
+ * @start: Doorbell info range start
+ * @end: Doorbell info range end
+ *
+ * Releases ownership of an inbound doorbell resource and removes
+ * callback from the doorbell event list. Returns 0 if the request
+ * has been satisfied.
+ */
+int rio_release_inb_dbell(struct rio_mport *mport, u16 start, u16 end)
+{
+ int rc = 0, found = 0;
+ struct rio_dbell *dbell;
+
+ list_for_each_entry(dbell, &mport->dbells, node) {
+ if ((dbell->res->start == start) && (dbell->res->end == end)) {
+ found = 1;
+ break;
+ }
+ }
+
+ /* If we can't find an exact match, fail */
+ if (!found) {
+ rc = -EINVAL;
+ goto out;
+ }
+
+ /* Delete from list */
+ list_del(&dbell->node);
+
+ /* Release the doorbell resource */
+ rc = release_resource(dbell->res);
+
+ /* Free the doorbell event */
+ kfree(dbell);
+
+ out:
+ return rc;
+}
+
+/**
+ * rio_request_outb_dbell - request outbound doorbell message range
+ * @rdev: RIO device from which to allocate the doorbell resource
+ * @start: Doorbell message range start
+ * @end: Doorbell message range end
+ *
+ * Requests ownership of a doorbell message range. Returns a resource
+ * if the request has been satisfied or %NULL on failure.
+ */
+struct resource *rio_request_outb_dbell(struct rio_dev *rdev, u16 start,
+ u16 end)
+{
+ struct resource *res = kmalloc(sizeof(struct resource), GFP_KERNEL);
+
+ if (res) {
+ rio_init_dbell_res(res, start, end);
+
+ /* Make sure these doorbells aren't in use */
+ if (request_resource(&rdev->riores[RIO_DOORBELL_RESOURCE], res)
+ < 0) {
+ kfree(res);
+ res = NULL;
+ }
+ }
+
+ return res;
+}
+
+/**
+ * rio_release_outb_dbell - release outbound doorbell message range
+ * @rdev: RIO device from which to release the doorbell resource
+ * @res: Doorbell resource to be freed
+ *
+ * Releases ownership of a doorbell message range. Returns 0 if the
+ * request has been satisfied.
+ */
+int rio_release_outb_dbell(struct rio_dev *rdev, struct resource *res)
+{
+ int rc = release_resource(res);
+
+ kfree(res);
+
+ return rc;
+}
+
+/**
+ * rio_mport_get_feature - query for devices' extended features
+ * @port: Master port to issue transaction
+ * @local: Indicate a local master port or remote device access
+ * @destid: Destination ID of the device
+ * @hopcount: Number of switch hops to the device
+ * @ftr: Extended feature code
+ *
+ * Tell if a device supports a given RapidIO capability.
+ * Returns the offset of the requested extended feature
+ * block within the device's RIO configuration space or
+ * 0 in case the device does not support it. Possible
+ * values for @ftr:
+ *
+ * %RIO_EFB_PAR_EP_ID LP/LVDS EP Devices
+ *
+ * %RIO_EFB_PAR_EP_REC_ID LP/LVDS EP Recovery Devices
+ *
+ * %RIO_EFB_PAR_EP_FREE_ID LP/LVDS EP Free Devices
+ *
+ * %RIO_EFB_SER_EP_ID LP/Serial EP Devices
+ *
+ * %RIO_EFB_SER_EP_REC_ID LP/Serial EP Recovery Devices
+ *
+ * %RIO_EFB_SER_EP_FREE_ID LP/Serial EP Free Devices
+ */
+u32
+rio_mport_get_feature(struct rio_mport * port, int local, u16 destid,
+ u8 hopcount, int ftr)
+{
+ u32 asm_info, ext_ftr_ptr, ftr_header;
+
+ if (local)
+ rio_local_read_config_32(port, RIO_ASM_INFO_CAR, &asm_info);
+ else
+ rio_mport_read_config_32(port, destid, hopcount,
+ RIO_ASM_INFO_CAR, &asm_info);
+
+ ext_ftr_ptr = asm_info & RIO_EXT_FTR_PTR_MASK;
+
+ while (ext_ftr_ptr) {
+ if (local)
+ rio_local_read_config_32(port, ext_ftr_ptr,
+ &ftr_header);
+ else
+ rio_mport_read_config_32(port, destid, hopcount,
+ ext_ftr_ptr, &ftr_header);
+ if (RIO_GET_BLOCK_ID(ftr_header) == ftr)
+ return ext_ftr_ptr;
+ if (!(ext_ftr_ptr = RIO_GET_BLOCK_PTR(ftr_header)))
+ break;
+ }
+
+ return 0;
+}
+
+/**
+ * rio_get_asm - Begin or continue searching for a RIO device by vid/did/asm_vid/asm_did
+ * @vid: RIO vid to match or %RIO_ANY_ID to match all vids
+ * @did: RIO did to match or %RIO_ANY_ID to match all dids
+ * @asm_vid: RIO asm_vid to match or %RIO_ANY_ID to match all asm_vids
+ * @asm_did: RIO asm_did to match or %RIO_ANY_ID to match all asm_dids
+ * @from: Previous RIO device found in search, or %NULL for new search
+ *
+ * Iterates through the list of known RIO devices. If a RIO device is
+ * found with a matching @vid, @did, @asm_vid, @asm_did, the reference
+ * count to the device is incrememted and a pointer to its device
+ * structure is returned. Otherwise, %NULL is returned. A new search
+ * is initiated by passing %NULL to the @from argument. Otherwise, if
+ * @from is not %NULL, searches continue from next device on the global
+ * list. The reference count for @from is always decremented if it is
+ * not %NULL.
+ */
+struct rio_dev *rio_get_asm(u16 vid, u16 did,
+ u16 asm_vid, u16 asm_did, struct rio_dev *from)
+{
+ struct list_head *n;
+ struct rio_dev *rdev;
+
+ WARN_ON(in_interrupt());
+ spin_lock(&rio_global_list_lock);
+ n = from ? from->global_list.next : rio_devices.next;
+
+ while (n && (n != &rio_devices)) {
+ rdev = rio_dev_g(n);
+ if ((vid == RIO_ANY_ID || rdev->vid == vid) &&
+ (did == RIO_ANY_ID || rdev->did == did) &&
+ (asm_vid == RIO_ANY_ID || rdev->asm_vid == asm_vid) &&
+ (asm_did == RIO_ANY_ID || rdev->asm_did == asm_did))
+ goto exit;
+ n = n->next;
+ }
+ rdev = NULL;
+ exit:
+ rio_dev_put(from);
+ rdev = rio_dev_get(rdev);
+ spin_unlock(&rio_global_list_lock);
+ return rdev;
+}
+
+/**
+ * rio_get_device - Begin or continue searching for a RIO device by vid/did
+ * @vid: RIO vid to match or %RIO_ANY_ID to match all vids
+ * @did: RIO did to match or %RIO_ANY_ID to match all dids
+ * @from: Previous RIO device found in search, or %NULL for new search
+ *
+ * Iterates through the list of known RIO devices. If a RIO device is
+ * found with a matching @vid and @did, the reference count to the
+ * device is incrememted and a pointer to its device structure is returned.
+ * Otherwise, %NULL is returned. A new search is initiated by passing %NULL
+ * to the @from argument. Otherwise, if @from is not %NULL, searches
+ * continue from next device on the global list. The reference count for
+ * @from is always decremented if it is not %NULL.
+ */
+struct rio_dev *rio_get_device(u16 vid, u16 did, struct rio_dev *from)
+{
+ return rio_get_asm(vid, did, RIO_ANY_ID, RIO_ANY_ID, from);
+}
+
+static void rio_fixup_device(struct rio_dev *dev)
+{
+}
+
+static int __devinit rio_init(void)
+{
+ struct rio_dev *dev = NULL;
+
+ while ((dev = rio_get_device(RIO_ANY_ID, RIO_ANY_ID, dev)) != NULL) {
+ rio_fixup_device(dev);
+ }
+ return 0;
+}
+
+device_initcall(rio_init);
+
+int rio_init_mports(void)
+{
+ int rc = 0;
+ struct rio_mport *port;
+
+ list_for_each_entry(port, &rio_mports, node) {
+ if (!request_mem_region(port->iores.start,
+ port->iores.end - port->iores.start,
+ port->name)) {
+ printk(KERN_ERR
+ "RIO: Error requesting master port region %8.8lx-%8.8lx\n",
+ port->iores.start, port->iores.end - 1);
+ rc = -ENOMEM;
+ goto out;
+ }
+
+ if (port->host_deviceid >= 0)
+ rio_enum_mport(port);
+ else
+ rio_disc_mport(port);
+ }
+
+ out:
+ return rc;
+}
+
+void rio_register_mport(struct rio_mport *port)
+{
+ list_add_tail(&port->node, &rio_mports);
+}
+
+EXPORT_SYMBOL_GPL(rio_local_get_device_id);
+EXPORT_SYMBOL_GPL(rio_get_device);
+EXPORT_SYMBOL_GPL(rio_get_asm);
+EXPORT_SYMBOL_GPL(rio_request_inb_dbell);
+EXPORT_SYMBOL_GPL(rio_release_inb_dbell);
+EXPORT_SYMBOL_GPL(rio_request_outb_dbell);
+EXPORT_SYMBOL_GPL(rio_release_outb_dbell);
+EXPORT_SYMBOL_GPL(rio_request_inb_mbox);
+EXPORT_SYMBOL_GPL(rio_release_inb_mbox);
+EXPORT_SYMBOL_GPL(rio_request_outb_mbox);
+EXPORT_SYMBOL_GPL(rio_release_outb_mbox);
diff --git a/drivers/rapidio/rio.h b/drivers/rapidio/rio.h
new file mode 100644
index 000000000000..b242cee656e7
--- /dev/null
+++ b/drivers/rapidio/rio.h
@@ -0,0 +1,60 @@
+/*
+ * RapidIO interconnect services
+ *
+ * Copyright 2005 MontaVista Software, Inc.
+ * Matt Porter <mporter@kernel.crashing.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/device.h>
+#include <linux/list.h>
+#include <linux/rio.h>
+
+/* Functions internal to the RIO core code */
+
+extern u32 rio_mport_get_feature(struct rio_mport *mport, int local, u16 destid,
+ u8 hopcount, int ftr);
+extern int rio_create_sysfs_dev_files(struct rio_dev *rdev);
+extern int rio_enum_mport(struct rio_mport *mport);
+extern int rio_disc_mport(struct rio_mport *mport);
+
+/* Structures internal to the RIO core code */
+extern struct device_attribute rio_dev_attrs[];
+extern spinlock_t rio_global_list_lock;
+
+extern struct rio_route_ops __start_rio_route_ops[];
+extern struct rio_route_ops __end_rio_route_ops[];
+
+/* Helpers internal to the RIO core code */
+#define DECLARE_RIO_ROUTE_SECTION(section, vid, did, add_hook, get_hook) \
+ static struct rio_route_ops __rio_route_ops __attribute_used__ \
+ __attribute__((__section__(#section))) = { vid, did, add_hook, get_hook };
+
+/**
+ * DECLARE_RIO_ROUTE_OPS - Registers switch routing operations
+ * @vid: RIO vendor ID
+ * @did: RIO device ID
+ * @add_hook: Callback that adds a route entry
+ * @get_hook: Callback that gets a route entry
+ *
+ * Manipulating switch route tables in RIO is switch specific. This
+ * registers a switch by vendor and device ID with two callbacks for
+ * modifying and retrieving route entries in a switch. A &struct
+ * rio_route_ops is initialized with the ops and placed into a
+ * RIO-specific kernel section.
+ */
+#define DECLARE_RIO_ROUTE_OPS(vid, did, add_hook, get_hook) \
+ DECLARE_RIO_ROUTE_SECTION(.rio_route_ops, \
+ vid, did, add_hook, get_hook)
+
+#ifdef CONFIG_RAPIDIO_8_BIT_TRANSPORT
+#define RIO_GET_DID(x) ((x & 0x00ff0000) >> 16)
+#define RIO_SET_DID(x) ((x & 0x000000ff) << 16)
+#else
+#define RIO_GET_DID(x) (x & 0xffff)
+#define RIO_SET_DID(x) (x & 0xffff)
+#endif
diff --git a/drivers/rapidio/switches/Makefile b/drivers/rapidio/switches/Makefile
new file mode 100644
index 000000000000..b924f8301761
--- /dev/null
+++ b/drivers/rapidio/switches/Makefile
@@ -0,0 +1,5 @@
+#
+# Makefile for RIO switches
+#
+
+obj-$(CONFIG_RAPIDIO) += tsi500.o
diff --git a/drivers/rapidio/switches/tsi500.c b/drivers/rapidio/switches/tsi500.c
new file mode 100644
index 000000000000..c77c23bd9840
--- /dev/null
+++ b/drivers/rapidio/switches/tsi500.c
@@ -0,0 +1,60 @@
+/*
+ * RapidIO Tsi500 switch support
+ *
+ * Copyright 2005 MontaVista Software, Inc.
+ * Matt Porter <mporter@kernel.crashing.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/rio.h>
+#include <linux/rio_drv.h>
+#include <linux/rio_ids.h>
+#include "../rio.h"
+
+static int
+tsi500_route_add_entry(struct rio_mport *mport, u16 destid, u8 hopcount, u16 table, u16 route_destid, u8 route_port)
+{
+ int i;
+ u32 offset = 0x10000 + 0xa00 + ((route_destid / 2)&~0x3);
+ u32 result;
+
+ if (table == 0xff) {
+ rio_mport_read_config_32(mport, destid, hopcount, offset, &result);
+ result &= ~(0xf << (4*(route_destid & 0x7)));
+ for (i=0;i<4;i++)
+ rio_mport_write_config_32(mport, destid, hopcount, offset + (0x20000*i), result | (route_port << (4*(route_destid & 0x7))));
+ }
+ else {
+ rio_mport_read_config_32(mport, destid, hopcount, offset + (0x20000*table), &result);
+ result &= ~(0xf << (4*(route_destid & 0x7)));
+ rio_mport_write_config_32(mport, destid, hopcount, offset + (0x20000*table), result | (route_port << (4*(route_destid & 0x7))));
+ }
+
+ return 0;
+}
+
+static int
+tsi500_route_get_entry(struct rio_mport *mport, u16 destid, u8 hopcount, u16 table, u16 route_destid, u8 *route_port)
+{
+ int ret = 0;
+ u32 offset = 0x10000 + 0xa00 + ((route_destid / 2)&~0x3);
+ u32 result;
+
+ if (table == 0xff)
+ rio_mport_read_config_32(mport, destid, hopcount, offset, &result);
+ else
+ rio_mport_read_config_32(mport, destid, hopcount, offset + (0x20000*table), &result);
+
+ result &= 0xf << (4*(route_destid & 0x7));
+ *route_port = result >> (4*(route_destid & 0x7));
+ if (*route_port > 3)
+ ret = -1;
+
+ return ret;
+}
+
+DECLARE_RIO_ROUTE_OPS(RIO_VID_TUNDRA, RIO_DID_TSI500, tsi500_route_add_entry, tsi500_route_get_entry);
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c
index 8fc891a9d47f..7008d32433bf 100644
--- a/drivers/s390/block/dasd.c
+++ b/drivers/s390/block/dasd.c
@@ -115,8 +115,7 @@ dasd_alloc_device(void)
void
dasd_free_device(struct dasd_device *device)
{
- if (device->private)
- kfree(device->private);
+ kfree(device->private);
free_page((unsigned long) device->erp_mem);
free_pages((unsigned long) device->ccw_mem, 1);
kfree(device);
@@ -539,8 +538,7 @@ dasd_kmalloc_request(char *magic, int cplength, int datasize,
if (datasize > 0) {
cqr->data = kmalloc(datasize, GFP_ATOMIC | GFP_DMA);
if (cqr->data == NULL) {
- if (cqr->cpaddr != NULL)
- kfree(cqr->cpaddr);
+ kfree(cqr->cpaddr);
kfree(cqr);
return ERR_PTR(-ENOMEM);
}
@@ -615,10 +613,8 @@ dasd_kfree_request(struct dasd_ccw_req * cqr, struct dasd_device * device)
clear_normalized_cda(ccw);
} while (ccw++->flags & (CCW_FLAG_CC | CCW_FLAG_DC));
#endif
- if (cqr->cpaddr != NULL)
- kfree(cqr->cpaddr);
- if (cqr->data != NULL)
- kfree(cqr->data);
+ kfree(cqr->cpaddr);
+ kfree(cqr->data);
kfree(cqr);
dasd_put_device(device);
}
diff --git a/drivers/s390/block/dasd_devmap.c b/drivers/s390/block/dasd_devmap.c
index bda896d9d788..caee16a3dc62 100644
--- a/drivers/s390/block/dasd_devmap.c
+++ b/drivers/s390/block/dasd_devmap.c
@@ -387,8 +387,7 @@ dasd_add_busid(char *bus_id, int features)
new = 0;
}
spin_unlock(&dasd_devmap_lock);
- if (new)
- kfree(new);
+ kfree(new);
return devmap;
}
diff --git a/drivers/s390/block/dasd_diag.c b/drivers/s390/block/dasd_diag.c
index 7478423b53bb..ab8754e566bc 100644
--- a/drivers/s390/block/dasd_diag.c
+++ b/drivers/s390/block/dasd_diag.c
@@ -6,7 +6,7 @@
* Bugreports.to..: <Linux390@de.ibm.com>
* (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000
*
- * $Revision: 1.49 $
+ * $Revision: 1.51 $
*/
#include <linux/config.h>
@@ -67,9 +67,9 @@ static const u8 DASD_DIAG_CMS1[] = { 0xc3, 0xd4, 0xe2, 0xf1 };/* EBCDIC CMS1 */
static __inline__ int
dia250(void *iob, int cmd)
{
- typedef struct {
- char _[max(sizeof (struct dasd_diag_init_io),
- sizeof (struct dasd_diag_rw_io))];
+ typedef union {
+ struct dasd_diag_init_io init_io;
+ struct dasd_diag_rw_io rw_io;
} addr_type;
int rc;
@@ -190,7 +190,7 @@ dasd_start_diag(struct dasd_ccw_req * cqr)
private->iob.flags = DASD_DIAG_RWFLAG_ASYNC;
private->iob.block_count = dreq->block_count;
private->iob.interrupt_params = (addr_t) cqr;
- private->iob.bio_list = __pa(dreq->bio);
+ private->iob.bio_list = dreq->bio;
private->iob.flaga = DASD_DIAG_FLAGA_DEFAULT;
cqr->startclk = get_clock();
@@ -394,47 +394,57 @@ dasd_diag_check_device(struct dasd_device *device)
memset(&bio, 0, sizeof (struct dasd_diag_bio));
bio.type = MDSK_READ_REQ;
bio.block_number = private->pt_block + 1;
- bio.buffer = __pa(label);
+ bio.buffer = label;
memset(&private->iob, 0, sizeof (struct dasd_diag_rw_io));
private->iob.dev_nr = rdc_data->dev_nr;
private->iob.key = 0;
private->iob.flags = 0; /* do synchronous io */
private->iob.block_count = 1;
private->iob.interrupt_params = 0;
- private->iob.bio_list = __pa(&bio);
+ private->iob.bio_list = &bio;
private->iob.flaga = DASD_DIAG_FLAGA_DEFAULT;
rc = dia250(&private->iob, RW_BIO);
- if (rc == 0 || rc == 3)
- break;
+ if (rc == 3) {
+ DEV_MESSAGE(KERN_WARNING, device, "%s",
+ "DIAG call failed");
+ rc = -EOPNOTSUPP;
+ goto out;
+ }
mdsk_term_io(device);
+ if (rc == 0)
+ break;
}
- if (rc == 3) {
- DEV_MESSAGE(KERN_WARNING, device, "%s", "DIAG call failed");
- rc = -EOPNOTSUPP;
- } else if (rc != 0) {
+ if (bsize > PAGE_SIZE) {
DEV_MESSAGE(KERN_WARNING, device, "device access failed "
"(rc=%d)", rc);
rc = -EIO;
+ goto out;
+ }
+ /* check for label block */
+ if (memcmp(label->label_id, DASD_DIAG_CMS1,
+ sizeof(DASD_DIAG_CMS1)) == 0) {
+ /* get formatted blocksize from label block */
+ bsize = (unsigned int) label->block_size;
+ device->blocks = (unsigned long) label->block_count;
+ } else
+ device->blocks = end_block;
+ device->bp_block = bsize;
+ device->s2b_shift = 0; /* bits to shift 512 to get a block */
+ for (sb = 512; sb < bsize; sb = sb << 1)
+ device->s2b_shift++;
+ rc = mdsk_init_io(device, device->bp_block, 0, NULL);
+ if (rc) {
+ DEV_MESSAGE(KERN_WARNING, device, "DIAG initialization "
+ "failed (rc=%d)", rc);
+ rc = -EIO;
} else {
- if (memcmp(label->label_id, DASD_DIAG_CMS1,
- sizeof(DASD_DIAG_CMS1)) == 0) {
- /* get formatted blocksize from label block */
- bsize = (unsigned int) label->block_size;
- device->blocks = (unsigned long) label->block_count;
- } else
- device->blocks = end_block;
- device->bp_block = bsize;
- device->s2b_shift = 0; /* bits to shift 512 to get a block */
- for (sb = 512; sb < bsize; sb = sb << 1)
- device->s2b_shift++;
-
DEV_MESSAGE(KERN_INFO, device,
"(%ld B/blk): %ldkB",
(unsigned long) device->bp_block,
(unsigned long) (device->blocks <<
device->s2b_shift) >> 1);
- rc = 0;
}
+out:
free_page((long) label);
return rc;
}
@@ -529,7 +539,7 @@ dasd_diag_build_cp(struct dasd_device * device, struct request *req)
memset(dbio, 0, sizeof (struct dasd_diag_bio));
dbio->type = rw_cmd;
dbio->block_number = recid + 1;
- dbio->buffer = __pa(dst);
+ dbio->buffer = dst;
dbio++;
dst += blksize;
recid++;
diff --git a/drivers/s390/block/dasd_diag.h b/drivers/s390/block/dasd_diag.h
index b26eb28df4bf..df31484d73a7 100644
--- a/drivers/s390/block/dasd_diag.h
+++ b/drivers/s390/block/dasd_diag.h
@@ -6,7 +6,7 @@
* Bugreports.to..: <Linux390@de.ibm.com>
* (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000
*
- * $Revision: 1.7 $
+ * $Revision: 1.8 $
*/
#define MDSK_WRITE_REQ 0x01
@@ -78,7 +78,7 @@ struct dasd_diag_bio {
u8 spare1[2];
u32 alet;
blocknum_t block_number;
- u64 buffer;
+ void *buffer;
} __attribute__ ((packed, aligned(8)));
struct dasd_diag_init_io {
@@ -104,7 +104,7 @@ struct dasd_diag_rw_io {
u32 alet;
u8 spare3[4];
u64 interrupt_params;
- u64 bio_list;
+ struct dasd_diag_bio *bio_list;
u8 spare4[8];
} __attribute__ ((packed, aligned(8)));
#else /* CONFIG_ARCH_S390X */
@@ -119,7 +119,7 @@ struct dasd_diag_bio {
u16 spare1;
blocknum_t block_number;
u32 alet;
- u32 buffer;
+ void *buffer;
} __attribute__ ((packed, aligned(8)));
struct dasd_diag_init_io {
@@ -142,7 +142,7 @@ struct dasd_diag_rw_io {
u8 spare2[2];
u32 block_count;
u32 alet;
- u32 bio_list;
+ struct dasd_diag_bio *bio_list;
u32 interrupt_params;
u8 spare3[20];
} __attribute__ ((packed, aligned(8)));
diff --git a/drivers/s390/char/con3215.c b/drivers/s390/char/con3215.c
index f11a67fda40e..75419cf9d353 100644
--- a/drivers/s390/char/con3215.c
+++ b/drivers/s390/char/con3215.c
@@ -727,8 +727,7 @@ raw3215_remove (struct ccw_device *cdev)
raw = cdev->dev.driver_data;
if (raw) {
cdev->dev.driver_data = NULL;
- if (raw->buffer)
- kfree(raw->buffer);
+ kfree(raw->buffer);
kfree(raw);
}
}
diff --git a/drivers/s390/char/con3270.c b/drivers/s390/char/con3270.c
index fc7a213e591f..c570a9f6ce9c 100644
--- a/drivers/s390/char/con3270.c
+++ b/drivers/s390/char/con3270.c
@@ -213,6 +213,9 @@ con3270_update(struct con3270 *cp)
struct string *s, *n;
int rc;
+ if (cp->view.dev)
+ raw3270_activate_view(&cp->view);
+
wrq = xchg(&cp->write, 0);
if (!wrq) {
con3270_set_timer(cp, 1);
@@ -489,8 +492,6 @@ con3270_write(struct console *co, const char *str, unsigned int count)
unsigned char c;
cp = condev;
- if (cp->view.dev)
- raw3270_activate_view(&cp->view);
spin_lock_irqsave(&cp->view.lock, flags);
while (count-- > 0) {
c = *str++;
@@ -620,7 +621,7 @@ con3270_init(void)
(void (*)(unsigned long)) con3270_read_tasklet,
(unsigned long) condev->read);
- raw3270_add_view(&condev->view, &con3270_fn, 0);
+ raw3270_add_view(&condev->view, &con3270_fn, 1);
INIT_LIST_HEAD(&condev->freemem);
for (i = 0; i < CON3270_STRING_PAGES; i++) {
diff --git a/drivers/s390/char/fs3270.c b/drivers/s390/char/fs3270.c
index 60afcdcf91c2..735a7fcdeff5 100644
--- a/drivers/s390/char/fs3270.c
+++ b/drivers/s390/char/fs3270.c
@@ -33,8 +33,11 @@ struct fs3270 {
int read_command; /* ccw command to use for reads. */
int write_command; /* ccw command to use for writes. */
int attention; /* Got attention. */
- struct raw3270_request *clear; /* single clear request. */
- wait_queue_head_t attn_wait; /* Attention wait queue. */
+ int active; /* Fullscreen view is active. */
+ struct raw3270_request *init; /* single init request. */
+ wait_queue_head_t wait; /* Init & attention wait queue. */
+ struct idal_buffer *rdbuf; /* full-screen-deactivate buffer */
+ size_t rdbuf_size; /* size of data returned by RDBUF */
};
static void
@@ -43,58 +46,172 @@ fs3270_wake_up(struct raw3270_request *rq, void *data)
wake_up((wait_queue_head_t *) data);
}
+static inline int
+fs3270_working(struct fs3270 *fp)
+{
+ /*
+ * The fullscreen view is in working order if the view
+ * has been activated AND the initial request is finished.
+ */
+ return fp->active && raw3270_request_final(fp->init);
+}
+
static int
fs3270_do_io(struct raw3270_view *view, struct raw3270_request *rq)
{
- wait_queue_head_t wq;
+ struct fs3270 *fp;
int rc;
- init_waitqueue_head(&wq);
+ fp = (struct fs3270 *) view;
rq->callback = fs3270_wake_up;
- rq->callback_data = &wq;
- rc = raw3270_start(view, rq);
- if (rc)
- return rc;
- /* Started sucessfully. Now wait for completion. */
- wait_event(wq, raw3270_request_final(rq));
- return rq->rc;
+ rq->callback_data = &fp->wait;
+
+ do {
+ if (!fs3270_working(fp)) {
+ /* Fullscreen view isn't ready yet. */
+ rc = wait_event_interruptible(fp->wait,
+ fs3270_working(fp));
+ if (rc != 0)
+ break;
+ }
+ rc = raw3270_start(view, rq);
+ if (rc == 0) {
+ /* Started sucessfully. Now wait for completion. */
+ wait_event(fp->wait, raw3270_request_final(rq));
+ }
+ } while (rc == -EACCES);
+ return rc;
}
+/*
+ * Switch to the fullscreen view.
+ */
static void
fs3270_reset_callback(struct raw3270_request *rq, void *data)
{
+ struct fs3270 *fp;
+
+ fp = (struct fs3270 *) rq->view;
raw3270_request_reset(rq);
+ wake_up(&fp->wait);
+}
+
+static void
+fs3270_restore_callback(struct raw3270_request *rq, void *data)
+{
+ struct fs3270 *fp;
+
+ fp = (struct fs3270 *) rq->view;
+ if (rq->rc != 0 || rq->rescnt != 0) {
+ if (fp->fs_pid)
+ kill_proc(fp->fs_pid, SIGHUP, 1);
+ }
+ fp->rdbuf_size = 0;
+ raw3270_request_reset(rq);
+ wake_up(&fp->wait);
}
-/*
- * Switch to the fullscreen view.
- */
static int
fs3270_activate(struct raw3270_view *view)
{
struct fs3270 *fp;
+ char *cp;
+ int rc;
fp = (struct fs3270 *) view;
- raw3270_request_set_cmd(fp->clear, TC_EWRITEA);
- fp->clear->callback = fs3270_reset_callback;
- return raw3270_start(view, fp->clear);
+
+ /* If an old init command is still running just return. */
+ if (!raw3270_request_final(fp->init))
+ return 0;
+
+ if (fp->rdbuf_size == 0) {
+ /* No saved buffer. Just clear the screen. */
+ raw3270_request_set_cmd(fp->init, TC_EWRITEA);
+ fp->init->callback = fs3270_reset_callback;
+ } else {
+ /* Restore fullscreen buffer saved by fs3270_deactivate. */
+ raw3270_request_set_cmd(fp->init, TC_EWRITEA);
+ raw3270_request_set_idal(fp->init, fp->rdbuf);
+ fp->init->ccw.count = fp->rdbuf_size;
+ cp = fp->rdbuf->data[0];
+ cp[0] = TW_KR;
+ cp[1] = TO_SBA;
+ cp[2] = cp[6];
+ cp[3] = cp[7];
+ cp[4] = TO_IC;
+ cp[5] = TO_SBA;
+ cp[6] = 0x40;
+ cp[7] = 0x40;
+ fp->init->rescnt = 0;
+ fp->init->callback = fs3270_restore_callback;
+ }
+ rc = fp->init->rc = raw3270_start_locked(view, fp->init);
+ if (rc)
+ fp->init->callback(fp->init, NULL);
+ else
+ fp->active = 1;
+ return rc;
}
/*
* Shutdown fullscreen view.
*/
static void
+fs3270_save_callback(struct raw3270_request *rq, void *data)
+{
+ struct fs3270 *fp;
+
+ fp = (struct fs3270 *) rq->view;
+
+ /* Correct idal buffer element 0 address. */
+ fp->rdbuf->data[0] -= 5;
+ fp->rdbuf->size += 5;
+
+ /*
+ * If the rdbuf command failed or the idal buffer is
+ * to small for the amount of data returned by the
+ * rdbuf command, then we have no choice but to send
+ * a SIGHUP to the application.
+ */
+ if (rq->rc != 0 || rq->rescnt == 0) {
+ if (fp->fs_pid)
+ kill_proc(fp->fs_pid, SIGHUP, 1);
+ fp->rdbuf_size = 0;
+ } else
+ fp->rdbuf_size = fp->rdbuf->size - rq->rescnt;
+ raw3270_request_reset(rq);
+ wake_up(&fp->wait);
+}
+
+static void
fs3270_deactivate(struct raw3270_view *view)
{
- // FIXME: is this a good idea? The user program using fullscreen 3270
- // will die just because a console message appeared. On the other
- // hand the fullscreen device is unoperational now.
struct fs3270 *fp;
fp = (struct fs3270 *) view;
- if (fp->fs_pid != 0)
- kill_proc(fp->fs_pid, SIGHUP, 1);
- fp->fs_pid = 0;
+ fp->active = 0;
+
+ /* If an old init command is still running just return. */
+ if (!raw3270_request_final(fp->init))
+ return;
+
+ /* Prepare read-buffer request. */
+ raw3270_request_set_cmd(fp->init, TC_RDBUF);
+ /*
+ * Hackish: skip first 5 bytes of the idal buffer to make
+ * room for the TW_KR/TO_SBA/<address>/<address>/TO_IC sequence
+ * in the activation command.
+ */
+ fp->rdbuf->data[0] += 5;
+ fp->rdbuf->size -= 5;
+ raw3270_request_set_idal(fp->init, fp->rdbuf);
+ fp->init->rescnt = 0;
+ fp->init->callback = fs3270_save_callback;
+
+ /* Start I/O to read in the 3270 buffer. */
+ fp->init->rc = raw3270_start_locked(view, fp->init);
+ if (fp->init->rc)
+ fp->init->callback(fp->init, NULL);
}
static int
@@ -103,7 +220,7 @@ fs3270_irq(struct fs3270 *fp, struct raw3270_request *rq, struct irb *irb)
/* Handle ATTN. Set indication and wake waiters for attention. */
if (irb->scsw.dstat & DEV_STAT_ATTENTION) {
fp->attention = 1;
- wake_up(&fp->attn_wait);
+ wake_up(&fp->wait);
}
if (rq) {
@@ -125,7 +242,7 @@ fs3270_read(struct file *filp, char *data, size_t count, loff_t *off)
struct fs3270 *fp;
struct raw3270_request *rq;
struct idal_buffer *ib;
- int rc;
+ ssize_t rc;
if (count == 0 || count > 65535)
return -EINVAL;
@@ -133,7 +250,7 @@ fs3270_read(struct file *filp, char *data, size_t count, loff_t *off)
if (!fp)
return -ENODEV;
ib = idal_buffer_alloc(count, 0);
- if (!ib)
+ if (IS_ERR(ib))
return -ENOMEM;
rq = raw3270_request_alloc(0);
if (!IS_ERR(rq)) {
@@ -141,10 +258,19 @@ fs3270_read(struct file *filp, char *data, size_t count, loff_t *off)
fp->read_command = 6;
raw3270_request_set_cmd(rq, fp->read_command ? : 2);
raw3270_request_set_idal(rq, ib);
- wait_event(fp->attn_wait, fp->attention);
- rc = fs3270_do_io(&fp->view, rq);
- if (rc == 0 && idal_buffer_to_user(ib, data, count))
- rc = -EFAULT;
+ rc = wait_event_interruptible(fp->wait, fp->attention);
+ fp->attention = 0;
+ if (rc == 0) {
+ rc = fs3270_do_io(&fp->view, rq);
+ if (rc == 0) {
+ count -= rq->rescnt;
+ if (idal_buffer_to_user(ib, data, count) != 0)
+ rc = -EFAULT;
+ else
+ rc = count;
+
+ }
+ }
raw3270_request_free(rq);
} else
rc = PTR_ERR(rq);
@@ -162,13 +288,13 @@ fs3270_write(struct file *filp, const char *data, size_t count, loff_t *off)
struct raw3270_request *rq;
struct idal_buffer *ib;
int write_command;
- int rc;
+ ssize_t rc;
fp = filp->private_data;
if (!fp)
return -ENODEV;
ib = idal_buffer_alloc(count, 0);
- if (!ib)
+ if (IS_ERR(ib))
return -ENOMEM;
rq = raw3270_request_alloc(0);
if (!IS_ERR(rq)) {
@@ -179,6 +305,8 @@ fs3270_write(struct file *filp, const char *data, size_t count, loff_t *off)
raw3270_request_set_cmd(rq, write_command);
raw3270_request_set_idal(rq, ib);
rc = fs3270_do_io(&fp->view, rq);
+ if (rc == 0)
+ rc = count - rq->rescnt;
} else
rc = -EFAULT;
raw3270_request_free(rq);
@@ -232,7 +360,7 @@ fs3270_ioctl(struct inode *inode, struct file *filp,
}
/*
- * Allocate tty3270 structure.
+ * Allocate fs3270 structure.
*/
static struct fs3270 *
fs3270_alloc_view(void)
@@ -243,8 +371,8 @@ fs3270_alloc_view(void)
if (!fp)
return ERR_PTR(-ENOMEM);
memset(fp, 0, sizeof(struct fs3270));
- fp->clear = raw3270_request_alloc(0);
- if (!IS_ERR(fp->clear)) {
+ fp->init = raw3270_request_alloc(0);
+ if (IS_ERR(fp->init)) {
kfree(fp);
return ERR_PTR(-ENOMEM);
}
@@ -252,12 +380,17 @@ fs3270_alloc_view(void)
}
/*
- * Free tty3270 structure.
+ * Free fs3270 structure.
*/
static void
fs3270_free_view(struct raw3270_view *view)
{
- raw3270_request_free(((struct fs3270 *) view)->clear);
+ struct fs3270 *fp;
+
+ fp = (struct fs3270 *) view;
+ if (fp->rdbuf)
+ idal_buffer_free(fp->rdbuf);
+ raw3270_request_free(((struct fs3270 *) view)->init);
kfree(view);
}
@@ -285,11 +418,20 @@ static int
fs3270_open(struct inode *inode, struct file *filp)
{
struct fs3270 *fp;
+ struct idal_buffer *ib;
int minor, rc;
if (imajor(filp->f_dentry->d_inode) != IBM_FS3270_MAJOR)
return -ENODEV;
minor = iminor(filp->f_dentry->d_inode);
+ /* Check for minor 0 multiplexer. */
+ if (minor == 0) {
+ if (!current->signal->tty)
+ return -ENODEV;
+ if (current->signal->tty->driver->major != IBM_TTY3270_MAJOR)
+ return -ENODEV;
+ minor = current->signal->tty->index + RAW3270_FIRSTMINOR;
+ }
/* Check if some other program is already using fullscreen mode. */
fp = (struct fs3270 *) raw3270_find_view(&fs3270_fn, minor);
if (!IS_ERR(fp)) {
@@ -301,7 +443,7 @@ fs3270_open(struct inode *inode, struct file *filp)
if (IS_ERR(fp))
return PTR_ERR(fp);
- init_waitqueue_head(&fp->attn_wait);
+ init_waitqueue_head(&fp->wait);
fp->fs_pid = current->pid;
rc = raw3270_add_view(&fp->view, &fs3270_fn, minor);
if (rc) {
@@ -309,8 +451,18 @@ fs3270_open(struct inode *inode, struct file *filp)
return rc;
}
+ /* Allocate idal-buffer. */
+ ib = idal_buffer_alloc(2*fp->view.rows*fp->view.cols + 5, 0);
+ if (IS_ERR(ib)) {
+ raw3270_put_view(&fp->view);
+ raw3270_del_view(&fp->view);
+ return PTR_ERR(fp);
+ }
+ fp->rdbuf = ib;
+
rc = raw3270_activate_view(&fp->view);
if (rc) {
+ raw3270_put_view(&fp->view);
raw3270_del_view(&fp->view);
return rc;
}
@@ -329,8 +481,12 @@ fs3270_close(struct inode *inode, struct file *filp)
fp = filp->private_data;
filp->private_data = 0;
- if (fp)
+ if (fp) {
+ fp->fs_pid = 0;
+ raw3270_reset(&fp->view);
+ raw3270_put_view(&fp->view);
raw3270_del_view(&fp->view);
+ }
return 0;
}
diff --git a/drivers/s390/char/keyboard.c b/drivers/s390/char/keyboard.c
index fd43d99b45a3..5bda2340a39d 100644
--- a/drivers/s390/char/keyboard.c
+++ b/drivers/s390/char/keyboard.c
@@ -99,13 +99,11 @@ out_fn_handler:
kfree(kbd->fn_handler);
out_func:
for (i = 0; i < ARRAY_SIZE(func_table); i++)
- if (kbd->func_table[i])
- kfree(kbd->func_table[i]);
+ kfree(kbd->func_table[i]);
kfree(kbd->func_table);
out_maps:
for (i = 0; i < ARRAY_SIZE(key_maps); i++)
- if (kbd->key_maps[i])
- kfree(kbd->key_maps[i]);
+ kfree(kbd->key_maps[i]);
kfree(kbd->key_maps);
out_kbd:
kfree(kbd);
@@ -121,12 +119,10 @@ kbd_free(struct kbd_data *kbd)
kfree(kbd->accent_table);
kfree(kbd->fn_handler);
for (i = 0; i < ARRAY_SIZE(func_table); i++)
- if (kbd->func_table[i])
- kfree(kbd->func_table[i]);
+ kfree(kbd->func_table[i]);
kfree(kbd->func_table);
for (i = 0; i < ARRAY_SIZE(key_maps); i++)
- if (kbd->key_maps[i])
- kfree(kbd->key_maps[i]);
+ kfree(kbd->key_maps[i]);
kfree(kbd->key_maps);
kfree(kbd);
}
@@ -452,8 +448,7 @@ do_kdgkb_ioctl(struct kbd_data *kbd, struct kbsentry __user *u_kbs,
return -EFAULT;
}
p[len] = 0;
- if (kbd->func_table[kb_func])
- kfree(kbd->func_table[kb_func]);
+ kfree(kbd->func_table[kb_func]);
kbd->func_table[kb_func] = p;
break;
}
diff --git a/drivers/s390/char/keyboard.h b/drivers/s390/char/keyboard.h
index 3b4da5a9cf79..f7bf45c6bf0d 100644
--- a/drivers/s390/char/keyboard.h
+++ b/drivers/s390/char/keyboard.h
@@ -41,14 +41,14 @@ int kbd_ioctl(struct kbd_data *, struct file *, unsigned int, unsigned long);
/*
* Helper Functions.
*/
-extern inline void
+static inline void
kbd_put_queue(struct tty_struct *tty, int ch)
{
tty_insert_flip_char(tty, ch, 0);
tty_schedule_flip(tty);
}
-extern inline void
+static inline void
kbd_puts_queue(struct tty_struct *tty, char *cp)
{
while (*cp)
diff --git a/drivers/s390/char/raw3270.c b/drivers/s390/char/raw3270.c
index 328d9cbc56a3..f5b7d360fc10 100644
--- a/drivers/s390/char/raw3270.c
+++ b/drivers/s390/char/raw3270.c
@@ -25,6 +25,12 @@
#include "raw3270.h"
+#include <linux/major.h>
+#include <linux/kdev_t.h>
+#include <linux/device.h>
+
+struct class *class3270;
+
/* The main 3270 data structure. */
struct raw3270 {
struct list_head list;
@@ -41,6 +47,8 @@ struct raw3270 {
struct timer_list timer; /* Device timer. */
unsigned char *ascebc; /* ascii -> ebcdic table */
+ struct class_device *clttydev; /* 3270-class tty device ptr */
+ struct class_device *cltubdev; /* 3270-class tub device ptr */
};
/* raw3270->flags */
@@ -175,8 +183,7 @@ raw3270_request_alloc_bootmem(size_t size)
void
raw3270_request_free (struct raw3270_request *rq)
{
- if (rq->buffer)
- kfree(rq->buffer);
+ kfree(rq->buffer);
kfree(rq);
}
@@ -317,6 +324,22 @@ raw3270_start(struct raw3270_view *view, struct raw3270_request *rq)
}
int
+raw3270_start_locked(struct raw3270_view *view, struct raw3270_request *rq)
+{
+ struct raw3270 *rp;
+ int rc;
+
+ rp = view->dev;
+ if (!rp || rp->view != view)
+ rc = -EACCES;
+ else if (!test_bit(RAW3270_FLAGS_READY, &rp->flags))
+ rc = -ENODEV;
+ else
+ rc = __raw3270_start(rp, view, rq);
+ return rc;
+}
+
+int
raw3270_start_irq(struct raw3270_view *view, struct raw3270_request *rq)
{
struct raw3270 *rp;
@@ -744,6 +767,22 @@ raw3270_reset_device(struct raw3270 *rp)
return rc;
}
+int
+raw3270_reset(struct raw3270_view *view)
+{
+ struct raw3270 *rp;
+ int rc;
+
+ rp = view->dev;
+ if (!rp || rp->view != view)
+ rc = -EACCES;
+ else if (!test_bit(RAW3270_FLAGS_READY, &rp->flags))
+ rc = -ENODEV;
+ else
+ rc = raw3270_reset_device(view->dev);
+ return rc;
+}
+
/*
* Setup new 3270 device.
*/
@@ -774,11 +813,12 @@ raw3270_setup_device(struct ccw_device *cdev, struct raw3270 *rp, char *ascebc)
/*
* Add device to list and find the smallest unused minor
- * number for it.
+ * number for it. Note: there is no device with minor 0,
+ * see special case for fs3270.c:fs3270_open().
*/
down(&raw3270_sem);
/* Keep the list sorted. */
- minor = 0;
+ minor = RAW3270_FIRSTMINOR;
rp->minor = -1;
list_for_each(l, &raw3270_devices) {
tmp = list_entry(l, struct raw3270, list);
@@ -789,7 +829,7 @@ raw3270_setup_device(struct ccw_device *cdev, struct raw3270 *rp, char *ascebc)
}
minor++;
}
- if (rp->minor == -1 && minor < RAW3270_MAXDEVS) {
+ if (rp->minor == -1 && minor < RAW3270_MAXDEVS + RAW3270_FIRSTMINOR) {
rp->minor = minor;
list_add_tail(&rp->list, &raw3270_devices);
}
@@ -941,11 +981,12 @@ raw3270_deactivate_view(struct raw3270_view *view)
list_add_tail(&view->list, &rp->view_list);
/* Try to activate another view. */
if (test_bit(RAW3270_FLAGS_READY, &rp->flags)) {
- list_for_each_entry(view, &rp->view_list, list)
- if (view->fn->activate(view) == 0) {
- rp->view = view;
+ list_for_each_entry(view, &rp->view_list, list) {
+ rp->view = view;
+ if (view->fn->activate(view) == 0)
break;
- }
+ rp->view = 0;
+ }
}
}
spin_unlock_irqrestore(get_ccwdev_lock(rp->cdev), flags);
@@ -961,6 +1002,8 @@ raw3270_add_view(struct raw3270_view *view, struct raw3270_fn *fn, int minor)
struct raw3270 *rp;
int rc;
+ if (minor <= 0)
+ return -ENODEV;
down(&raw3270_sem);
rc = -ENODEV;
list_for_each_entry(rp, &raw3270_devices, list) {
@@ -976,7 +1019,7 @@ raw3270_add_view(struct raw3270_view *view, struct raw3270_fn *fn, int minor)
view->cols = rp->cols;
view->ascebc = rp->ascebc;
spin_lock_init(&view->lock);
- list_add_tail(&view->list, &rp->view_list);
+ list_add(&view->list, &rp->view_list);
rc = 0;
}
spin_unlock_irqrestore(get_ccwdev_lock(rp->cdev), flags);
@@ -1039,7 +1082,7 @@ raw3270_del_view(struct raw3270_view *view)
if (!rp->view && test_bit(RAW3270_FLAGS_READY, &rp->flags)) {
/* Try to activate another view. */
list_for_each_entry(nv, &rp->view_list, list) {
- if (nv->fn->activate(view) == 0) {
+ if (nv->fn->activate(nv) == 0) {
rp->view = nv;
break;
}
@@ -1063,6 +1106,12 @@ raw3270_delete_device(struct raw3270 *rp)
/* Remove from device chain. */
down(&raw3270_sem);
+ if (rp->clttydev)
+ class_device_destroy(class3270,
+ MKDEV(IBM_TTY3270_MAJOR, rp->minor));
+ if (rp->cltubdev)
+ class_device_destroy(class3270,
+ MKDEV(IBM_FS3270_MAJOR, rp->minor));
list_del_init(&rp->list);
up(&raw3270_sem);
@@ -1129,6 +1178,16 @@ raw3270_create_attributes(struct raw3270 *rp)
{
//FIXME: check return code
sysfs_create_group(&rp->cdev->dev.kobj, &raw3270_attr_group);
+ rp->clttydev =
+ class_device_create(class3270,
+ MKDEV(IBM_TTY3270_MAJOR, rp->minor),
+ &rp->cdev->dev, "tty%s",
+ rp->cdev->dev.bus_id);
+ rp->cltubdev =
+ class_device_create(class3270,
+ MKDEV(IBM_FS3270_MAJOR, rp->minor),
+ &rp->cdev->dev, "tub%s",
+ rp->cdev->dev.bus_id);
}
/*
@@ -1189,13 +1248,13 @@ raw3270_set_online (struct ccw_device *cdev)
return PTR_ERR(rp);
rc = raw3270_reset_device(rp);
if (rc)
- return rc;
+ goto failure;
rc = raw3270_size_device(rp);
if (rc)
- return rc;
+ goto failure;
rc = raw3270_reset_device(rp);
if (rc)
- return rc;
+ goto failure;
raw3270_create_attributes(rp);
set_bit(RAW3270_FLAGS_READY, &rp->flags);
down(&raw3270_sem);
@@ -1203,6 +1262,10 @@ raw3270_set_online (struct ccw_device *cdev)
np->notifier(rp->minor, 1);
up(&raw3270_sem);
return 0;
+
+failure:
+ raw3270_delete_device(rp);
+ return rc;
}
/*
@@ -1217,6 +1280,14 @@ raw3270_remove (struct ccw_device *cdev)
struct raw3270_notifier *np;
rp = cdev->dev.driver_data;
+ /*
+ * _remove is the opposite of _probe; it's probe that
+ * should set up rp. raw3270_remove gets entered for
+ * devices even if they haven't been varied online.
+ * Thus, rp may validly be NULL here.
+ */
+ if (rp == NULL)
+ return;
clear_bit(RAW3270_FLAGS_READY, &rp->flags);
sysfs_remove_group(&cdev->dev.kobj, &raw3270_attr_group);
@@ -1301,6 +1372,7 @@ raw3270_init(void)
if (rc == 0) {
/* Create attributes for early (= console) device. */
down(&raw3270_sem);
+ class3270 = class_create(THIS_MODULE, "3270");
list_for_each_entry(rp, &raw3270_devices, list) {
get_device(&rp->cdev->dev);
raw3270_create_attributes(rp);
@@ -1314,6 +1386,7 @@ static void
raw3270_exit(void)
{
ccw_driver_unregister(&raw3270_ccw_driver);
+ class_destroy(class3270);
}
MODULE_LICENSE("GPL");
@@ -1335,7 +1408,9 @@ EXPORT_SYMBOL(raw3270_find_view);
EXPORT_SYMBOL(raw3270_activate_view);
EXPORT_SYMBOL(raw3270_deactivate_view);
EXPORT_SYMBOL(raw3270_start);
+EXPORT_SYMBOL(raw3270_start_locked);
EXPORT_SYMBOL(raw3270_start_irq);
+EXPORT_SYMBOL(raw3270_reset);
EXPORT_SYMBOL(raw3270_register_notifier);
EXPORT_SYMBOL(raw3270_unregister_notifier);
EXPORT_SYMBOL(raw3270_wait_queue);
diff --git a/drivers/s390/char/raw3270.h b/drivers/s390/char/raw3270.h
index ed5d4eb9f623..b635bf8e7775 100644
--- a/drivers/s390/char/raw3270.h
+++ b/drivers/s390/char/raw3270.h
@@ -21,6 +21,7 @@
/* Local Channel Commands */
#define TC_WRITE 0x01 /* Write */
+#define TC_RDBUF 0x02 /* Read Buffer */
#define TC_EWRITE 0x05 /* Erase write */
#define TC_READMOD 0x06 /* Read modified */
#define TC_EWRITEA 0x0d /* Erase write alternate */
@@ -76,7 +77,8 @@
#define TW_KR 0xc2 /* Keyboard restore */
#define TW_PLUSALARM 0x04 /* Add this bit for alarm */
-#define RAW3270_MAXDEVS 256
+#define RAW3270_FIRSTMINOR 1 /* First minor number */
+#define RAW3270_MAXDEVS 255 /* Max number of 3270 devices */
/* For TUBGETMOD and TUBSETMOD. Should include. */
struct raw3270_iocb {
@@ -166,7 +168,10 @@ void raw3270_del_view(struct raw3270_view *);
void raw3270_deactivate_view(struct raw3270_view *);
struct raw3270_view *raw3270_find_view(struct raw3270_fn *, int);
int raw3270_start(struct raw3270_view *, struct raw3270_request *);
+int raw3270_start_locked(struct raw3270_view *, struct raw3270_request *);
int raw3270_start_irq(struct raw3270_view *, struct raw3270_request *);
+int raw3270_reset(struct raw3270_view *);
+struct raw3270_view *raw3270_view(struct raw3270_view *);
/* Reference count inliner for view structures. */
static inline void
diff --git a/drivers/s390/char/tape_class.c b/drivers/s390/char/tape_class.c
index ed0cb1f15b4c..fcaee447d6fe 100644
--- a/drivers/s390/char/tape_class.c
+++ b/drivers/s390/char/tape_class.c
@@ -72,6 +72,7 @@ struct tape_class_device *register_tape_dev(
tcd->class_device = class_device_create(
tape_class,
+ NULL,
tcd->char_device->dev,
device,
"%s", tcd->device_name
diff --git a/drivers/s390/char/tape_core.c b/drivers/s390/char/tape_core.c
index 6c52e8307dc5..8f486e1a8507 100644
--- a/drivers/s390/char/tape_core.c
+++ b/drivers/s390/char/tape_core.c
@@ -682,8 +682,7 @@ tape_alloc_request(int cplength, int datasize)
request->cpdata = kmalloc(datasize, GFP_KERNEL | GFP_DMA);
if (request->cpdata == NULL) {
DBF_EXCEPTION(1, "cqra nomem\n");
- if (request->cpaddr != NULL)
- kfree(request->cpaddr);
+ kfree(request->cpaddr);
kfree(request);
return ERR_PTR(-ENOMEM);
}
@@ -706,10 +705,8 @@ tape_free_request (struct tape_request * request)
if (request->device != NULL) {
request->device = tape_put_device(request->device);
}
- if (request->cpdata != NULL)
- kfree(request->cpdata);
- if (request->cpaddr != NULL)
- kfree(request->cpaddr);
+ kfree(request->cpdata);
+ kfree(request->cpaddr);
kfree(request);
}
diff --git a/drivers/s390/char/tty3270.c b/drivers/s390/char/tty3270.c
index 7db5ebce7f0f..4b9069370388 100644
--- a/drivers/s390/char/tty3270.c
+++ b/drivers/s390/char/tty3270.c
@@ -653,18 +653,12 @@ tty3270_activate(struct raw3270_view *view)
tp->update_flags = TTY_UPDATE_ALL;
tty3270_set_timer(tp, 1);
spin_unlock_irqrestore(&tp->view.lock, flags);
- start_tty(tp->tty);
return 0;
}
static void
tty3270_deactivate(struct raw3270_view *view)
{
- struct tty3270 *tp;
-
- tp = (struct tty3270 *) view;
- if (tp && tp->tty)
- stop_tty(tp->tty);
}
static int
@@ -716,13 +710,13 @@ tty3270_alloc_view(void)
tp->freemem_pages[pages], PAGE_SIZE);
}
tp->write = raw3270_request_alloc(TTY3270_OUTPUT_BUFFER_SIZE);
- if (!tp->write)
+ if (IS_ERR(tp->write))
goto out_pages;
tp->read = raw3270_request_alloc(0);
- if (!tp->read)
+ if (IS_ERR(tp->read))
goto out_write;
tp->kreset = raw3270_request_alloc(1);
- if (!tp->kreset)
+ if (IS_ERR(tp->kreset))
goto out_read;
tp->kbd = kbd_alloc();
if (!tp->kbd)
@@ -845,7 +839,8 @@ tty3270_del_views(void)
int i;
for (i = 0; i < tty3270_max_index; i++) {
- tp = (struct tty3270 *) raw3270_find_view(&tty3270_fn, i);
+ tp = (struct tty3270 *)
+ raw3270_find_view(&tty3270_fn, i + RAW3270_FIRSTMINOR);
if (!IS_ERR(tp))
raw3270_del_view(&tp->view);
}
@@ -871,7 +866,9 @@ tty3270_open(struct tty_struct *tty, struct file * filp)
if (tty->count > 1)
return 0;
/* Check if the tty3270 is already there. */
- tp = (struct tty3270 *) raw3270_find_view(&tty3270_fn, tty->index);
+ tp = (struct tty3270 *)
+ raw3270_find_view(&tty3270_fn,
+ tty->index + RAW3270_FIRSTMINOR);
if (!IS_ERR(tp)) {
tty->driver_data = tp;
tty->winsize.ws_row = tp->view.rows - 2;
@@ -903,7 +900,8 @@ tty3270_open(struct tty_struct *tty, struct file * filp)
(void (*)(unsigned long)) tty3270_read_tasklet,
(unsigned long) tp->read);
- rc = raw3270_add_view(&tp->view, &tty3270_fn, tty->index);
+ rc = raw3270_add_view(&tp->view, &tty3270_fn,
+ tty->index + RAW3270_FIRSTMINOR);
if (rc) {
tty3270_free_view(tp);
return rc;
@@ -911,8 +909,8 @@ tty3270_open(struct tty_struct *tty, struct file * filp)
rc = tty3270_alloc_screen(tp);
if (rc) {
- raw3270_del_view(&tp->view);
raw3270_put_view(&tp->view);
+ raw3270_del_view(&tp->view);
return rc;
}
@@ -1780,7 +1778,7 @@ tty3270_init(void)
struct tty_driver *driver;
int ret;
- driver = alloc_tty_driver(256);
+ driver = alloc_tty_driver(RAW3270_MAXDEVS);
if (!driver)
return -ENOMEM;
@@ -1794,6 +1792,7 @@ tty3270_init(void)
driver->driver_name = "ttyTUB";
driver->name = "ttyTUB";
driver->major = IBM_TTY3270_MAJOR;
+ driver->minor_start = RAW3270_FIRSTMINOR;
driver->type = TTY_DRIVER_TYPE_SYSTEM;
driver->subtype = SYSTEM_TYPE_TTY;
driver->init_termios = tty_std_termios;
diff --git a/drivers/s390/char/vmcp.c b/drivers/s390/char/vmcp.c
index 8990d8076e7d..19762f3476aa 100644
--- a/drivers/s390/char/vmcp.c
+++ b/drivers/s390/char/vmcp.c
@@ -103,8 +103,10 @@ vmcp_write(struct file *file, const char __user * buff, size_t count,
}
cmd[count] = '\0';
session = (struct vmcp_session *)file->private_data;
- if (down_interruptible(&session->mutex))
+ if (down_interruptible(&session->mutex)) {
+ kfree(cmd);
return -ERESTARTSYS;
+ }
if (!session->response)
session->response = (char *)__get_free_pages(GFP_KERNEL
| __GFP_REPEAT | GFP_DMA,
diff --git a/drivers/s390/char/vmlogrdr.c b/drivers/s390/char/vmlogrdr.c
index 491f00c032e8..b2d75de144c6 100644
--- a/drivers/s390/char/vmlogrdr.c
+++ b/drivers/s390/char/vmlogrdr.c
@@ -788,6 +788,7 @@ vmlogrdr_register_device(struct vmlogrdr_priv_t *priv) {
}
priv->class_device = class_device_create(
vmlogrdr_class,
+ NULL,
MKDEV(vmlogrdr_major, priv->minor_num),
dev,
"%s", dev->bus_id );
diff --git a/drivers/s390/cio/ccwgroup.c b/drivers/s390/cio/ccwgroup.c
index dbb3eb0e330b..e7bd7f37f080 100644
--- a/drivers/s390/cio/ccwgroup.c
+++ b/drivers/s390/cio/ccwgroup.c
@@ -1,7 +1,7 @@
/*
* drivers/s390/cio/ccwgroup.c
* bus driver for ccwgroup
- * $Revision: 1.29 $
+ * $Revision: 1.32 $
*
* Copyright (C) 2002 IBM Deutschland Entwicklung GmbH,
* IBM Corporation
@@ -274,7 +274,7 @@ ccwgroup_set_online(struct ccwgroup_device *gdev)
goto out;
}
gdrv = to_ccwgroupdrv (gdev->dev.driver);
- if ((ret = gdrv->set_online(gdev)))
+ if ((ret = gdrv->set_online ? gdrv->set_online(gdev) : 0))
goto out;
gdev->state = CCWGROUP_ONLINE;
@@ -300,7 +300,7 @@ ccwgroup_set_offline(struct ccwgroup_device *gdev)
goto out;
}
gdrv = to_ccwgroupdrv (gdev->dev.driver);
- if ((ret = gdrv->set_offline(gdev)))
+ if ((ret = gdrv->set_offline ? gdrv->set_offline(gdev) : 0))
goto out;
gdev->state = CCWGROUP_OFFLINE;
diff --git a/drivers/s390/cio/cmf.c b/drivers/s390/cio/cmf.c
index 8cc4f1a940dc..b978f7fe8327 100644
--- a/drivers/s390/cio/cmf.c
+++ b/drivers/s390/cio/cmf.c
@@ -30,10 +30,13 @@
#include <linux/list.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
+#include <linux/slab.h>
+#include <linux/timex.h> /* get_clock() */
#include <asm/ccwdev.h>
#include <asm/cio.h>
#include <asm/cmb.h>
+#include <asm/div64.h>
#include "cio.h"
#include "css.h"
@@ -639,8 +642,7 @@ static void
free_cmbe (struct ccw_device *cdev)
{
spin_lock_irq(cdev->ccwlock);
- if (cdev->private->cmb)
- kfree(cdev->private->cmb);
+ kfree(cdev->private->cmb);
cdev->private->cmb = NULL;
spin_unlock_irq(cdev->ccwlock);
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c
index 9adc11e8b8bc..811c9d150637 100644
--- a/drivers/s390/cio/device.c
+++ b/drivers/s390/cio/device.c
@@ -22,6 +22,7 @@
#include <asm/ccwdev.h>
#include <asm/cio.h>
+#include <asm/param.h> /* HZ */
#include "cio.h"
#include "css.h"
@@ -252,6 +253,23 @@ cutype_show (struct device *dev, struct device_attribute *attr, char *buf)
}
static ssize_t
+modalias_show (struct device *dev, struct device_attribute *attr, char *buf)
+{
+ struct ccw_device *cdev = to_ccwdev(dev);
+ struct ccw_device_id *id = &(cdev->id);
+ int ret;
+
+ ret = sprintf(buf, "ccw:t%04Xm%02x",
+ id->cu_type, id->cu_model);
+ if (id->dev_type != 0)
+ ret += sprintf(buf + ret, "dt%04Xdm%02X\n",
+ id->dev_type, id->dev_model);
+ else
+ ret += sprintf(buf + ret, "dtdm\n");
+ return ret;
+}
+
+static ssize_t
online_show (struct device *dev, struct device_attribute *attr, char *buf)
{
struct ccw_device *cdev = to_ccwdev(dev);
@@ -448,6 +466,7 @@ static DEVICE_ATTR(chpids, 0444, chpids_show, NULL);
static DEVICE_ATTR(pimpampom, 0444, pimpampom_show, NULL);
static DEVICE_ATTR(devtype, 0444, devtype_show, NULL);
static DEVICE_ATTR(cutype, 0444, cutype_show, NULL);
+static DEVICE_ATTR(modalias, 0444, modalias_show, NULL);
static DEVICE_ATTR(online, 0644, online_show, online_store);
extern struct device_attribute dev_attr_cmb_enable;
static DEVICE_ATTR(availability, 0444, available_show, NULL);
@@ -471,6 +490,7 @@ subchannel_add_files (struct device *dev)
static struct attribute * ccwdev_attrs[] = {
&dev_attr_devtype.attr,
&dev_attr_cutype.attr,
+ &dev_attr_modalias.attr,
&dev_attr_online.attr,
&dev_attr_cmb_enable.attr,
&dev_attr_availability.attr,
diff --git a/drivers/s390/cio/device_fsm.c b/drivers/s390/cio/device_fsm.c
index fbe4202a3f6f..c1c89f4fd4e3 100644
--- a/drivers/s390/cio/device_fsm.c
+++ b/drivers/s390/cio/device_fsm.c
@@ -11,6 +11,8 @@
#include <linux/module.h>
#include <linux/config.h>
#include <linux/init.h>
+#include <linux/jiffies.h>
+#include <linux/string.h>
#include <asm/ccwdev.h>
#include <asm/cio.h>
diff --git a/drivers/s390/cio/device_ops.c b/drivers/s390/cio/device_ops.c
index ad3fe5aeb663..85a3026e6900 100644
--- a/drivers/s390/cio/device_ops.c
+++ b/drivers/s390/cio/device_ops.c
@@ -550,10 +550,8 @@ ccw_device_stlck(struct ccw_device *cdev)
/* Clear irb. */
memset(&cdev->private->irb, 0, sizeof(struct irb));
out_unlock:
- if (buf)
- kfree(buf);
- if (buf2)
- kfree(buf2);
+ kfree(buf);
+ kfree(buf2);
spin_unlock_irqrestore(&sch->lock, flags);
return ret;
}
diff --git a/drivers/s390/cio/qdio.c b/drivers/s390/cio/qdio.c
index 381f339e3200..eb39218b925e 100644
--- a/drivers/s390/cio/qdio.c
+++ b/drivers/s390/cio/qdio.c
@@ -56,7 +56,7 @@
#include "ioasm.h"
#include "chsc.h"
-#define VERSION_QDIO_C "$Revision: 1.101 $"
+#define VERSION_QDIO_C "$Revision: 1.108 $"
/****************** MODULE PARAMETER VARIABLES ********************/
MODULE_AUTHOR("Utz Bacher <utz.bacher@de.ibm.com>");
@@ -1338,16 +1338,14 @@ qdio_release_irq_memory(struct qdio_irq *irq_ptr)
if (!irq_ptr->input_qs[i])
goto next;
- if (irq_ptr->input_qs[i]->slib)
- kfree(irq_ptr->input_qs[i]->slib);
+ kfree(irq_ptr->input_qs[i]->slib);
kfree(irq_ptr->input_qs[i]);
next:
if (!irq_ptr->output_qs[i])
continue;
- if (irq_ptr->output_qs[i]->slib)
- kfree(irq_ptr->output_qs[i]->slib);
+ kfree(irq_ptr->output_qs[i]->slib);
kfree(irq_ptr->output_qs[i]);
}
@@ -2873,10 +2871,10 @@ qdio_establish(struct qdio_initialize *init_data)
return result;
}
- wait_event_interruptible_timeout(cdev->private->wait_q,
+ /* Timeout is cared for already by using ccw_device_start_timeout(). */
+ wait_event_interruptible(cdev->private->wait_q,
irq_ptr->state == QDIO_IRQ_STATE_ESTABLISHED ||
- irq_ptr->state == QDIO_IRQ_STATE_ERR,
- QDIO_ESTABLISH_TIMEOUT);
+ irq_ptr->state == QDIO_IRQ_STATE_ERR);
if (irq_ptr->state == QDIO_IRQ_STATE_ESTABLISHED)
result = 0;
@@ -3315,8 +3313,7 @@ qdio_get_qdio_memory(void)
static void
qdio_release_qdio_memory(void)
{
- if (indicators)
- kfree(indicators);
+ kfree(indicators);
}
static void
diff --git a/drivers/s390/cio/qdio.h b/drivers/s390/cio/qdio.h
index 6b8aa6a852be..328e31cc6854 100644
--- a/drivers/s390/cio/qdio.h
+++ b/drivers/s390/cio/qdio.h
@@ -265,7 +265,7 @@ QDIO_PRINT_##importance(header "%02x %02x %02x %02x %02x %02x %02x %02x " \
/*
* Some instructions as assembly
*/
-extern __inline__ int
+static inline int
do_siga_sync(unsigned int irq, unsigned int mask1, unsigned int mask2)
{
int cc;
@@ -300,7 +300,7 @@ do_siga_sync(unsigned int irq, unsigned int mask1, unsigned int mask2)
return cc;
}
-extern __inline__ int
+static inline int
do_siga_input(unsigned int irq, unsigned int mask)
{
int cc;
@@ -334,7 +334,7 @@ do_siga_input(unsigned int irq, unsigned int mask)
return cc;
}
-extern __inline__ int
+static inline int
do_siga_output(unsigned long irq, unsigned long mask, __u32 *bb)
{
int cc;
@@ -401,7 +401,7 @@ do_siga_output(unsigned long irq, unsigned long mask, __u32 *bb)
return cc;
}
-extern __inline__ unsigned long
+static inline unsigned long
do_clear_global_summary(void)
{
diff --git a/drivers/s390/crypto/z90main.c b/drivers/s390/crypto/z90main.c
index 0cb47eca91f3..4010f2bb85af 100644
--- a/drivers/s390/crypto/z90main.c
+++ b/drivers/s390/crypto/z90main.c
@@ -37,7 +37,6 @@
#include <linux/kobject_uevent.h>
#include <linux/proc_fs.h>
#include <linux/syscalls.h>
-#include <linux/version.h>
#include "z90crypt.h"
#include "z90common.h"
@@ -3051,8 +3050,7 @@ destroy_crypto_device(int index)
if (dev_ptr) {
disabledFlag = dev_ptr->disabled;
t = dev_ptr->dev_type;
- if (dev_ptr->dev_resp_p)
- kfree(dev_ptr->dev_resp_p);
+ kfree(dev_ptr->dev_resp_p);
kfree(dev_ptr);
} else {
disabledFlag = 0;
@@ -3080,11 +3078,11 @@ static void
destroy_z90crypt(void)
{
int i;
+
for (i = 0; i < z90crypt.max_count; i++)
if (z90crypt.device_p[i])
destroy_crypto_device(i);
- if (z90crypt.hdware_info)
- kfree((void *)z90crypt.hdware_info);
+ kfree(z90crypt.hdware_info);
memset((void *)&z90crypt, 0, sizeof(z90crypt));
}
diff --git a/drivers/s390/net/claw.c b/drivers/s390/net/claw.c
index 3092473991a7..6b63d21612ec 100644
--- a/drivers/s390/net/claw.c
+++ b/drivers/s390/net/claw.c
@@ -88,7 +88,6 @@
#include <linux/tcp.h>
#include <linux/timer.h>
#include <linux/types.h>
-#include <linux/version.h>
#include "cu3088.h"
#include "claw.h"
@@ -2743,14 +2742,10 @@ probe_error( struct ccwgroup_device *cgdev)
#endif
privptr=(struct claw_privbk *)cgdev->dev.driver_data;
if (privptr!=NULL) {
- if (privptr->p_env != NULL) {
- kfree(privptr->p_env);
- privptr->p_env=NULL;
- }
- if (privptr->p_mtc_envelope!=NULL) {
- kfree(privptr->p_mtc_envelope);
- privptr->p_mtc_envelope=NULL;
- }
+ kfree(privptr->p_env);
+ privptr->p_env=NULL;
+ kfree(privptr->p_mtc_envelope);
+ privptr->p_mtc_envelope=NULL;
kfree(privptr);
privptr=NULL;
}
@@ -4121,22 +4116,14 @@ claw_remove_device(struct ccwgroup_device *cgdev)
if (cgdev->state == CCWGROUP_ONLINE)
claw_shutdown_device(cgdev);
claw_remove_files(&cgdev->dev);
- if (priv->p_mtc_envelope!=NULL) {
- kfree(priv->p_mtc_envelope);
- priv->p_mtc_envelope=NULL;
- }
- if (priv->p_env != NULL) {
- kfree(priv->p_env);
- priv->p_env=NULL;
- }
- if (priv->channel[0].irb != NULL) {
- kfree(priv->channel[0].irb);
- priv->channel[0].irb=NULL;
- }
- if (priv->channel[1].irb != NULL) {
- kfree(priv->channel[1].irb);
- priv->channel[1].irb=NULL;
- }
+ kfree(priv->p_mtc_envelope);
+ priv->p_mtc_envelope=NULL;
+ kfree(priv->p_env);
+ priv->p_env=NULL;
+ kfree(priv->channel[0].irb);
+ priv->channel[0].irb=NULL;
+ kfree(priv->channel[1].irb);
+ priv->channel[1].irb=NULL;
kfree(priv);
cgdev->dev.driver_data=NULL;
cgdev->cdev[READ]->dev.driver_data = NULL;
diff --git a/drivers/s390/net/fsm.c b/drivers/s390/net/fsm.c
index fa09440d82e5..24029bd9c7d0 100644
--- a/drivers/s390/net/fsm.c
+++ b/drivers/s390/net/fsm.c
@@ -16,7 +16,7 @@ MODULE_LICENSE("GPL");
fsm_instance *
init_fsm(char *name, const char **state_names, const char **event_names, int nr_states,
- int nr_events, const fsm_node *tmpl, int tmpl_len, int order)
+ int nr_events, const fsm_node *tmpl, int tmpl_len, gfp_t order)
{
int i;
fsm_instance *this;
@@ -78,8 +78,7 @@ kfree_fsm(fsm_instance *this)
{
if (this) {
if (this->f) {
- if (this->f->jumpmatrix)
- kfree(this->f->jumpmatrix);
+ kfree(this->f->jumpmatrix);
kfree(this->f);
}
kfree(this);
diff --git a/drivers/s390/net/fsm.h b/drivers/s390/net/fsm.h
index f9a011001eb6..5b98253be7aa 100644
--- a/drivers/s390/net/fsm.h
+++ b/drivers/s390/net/fsm.h
@@ -110,7 +110,7 @@ extern fsm_instance *
init_fsm(char *name, const char **state_names,
const char **event_names,
int nr_states, int nr_events, const fsm_node *tmpl,
- int tmpl_len, int order);
+ int tmpl_len, gfp_t order);
/**
* Releases an FSM
@@ -140,7 +140,7 @@ fsm_record_history(fsm_instance *fi, int state, int event);
* 1 if current state or event is out of range
* !0 if state and event in range, but no action defined.
*/
-extern __inline__ int
+static inline int
fsm_event(fsm_instance *fi, int event, void *arg)
{
fsm_function_t r;
@@ -188,7 +188,7 @@ fsm_event(fsm_instance *fi, int event, void *arg)
* @param fi Pointer to FSM
* @param state The new state for this FSM.
*/
-extern __inline__ void
+static inline void
fsm_newstate(fsm_instance *fi, int newstate)
{
atomic_set(&fi->state,newstate);
@@ -208,7 +208,7 @@ fsm_newstate(fsm_instance *fi, int newstate)
*
* @return The current state of the FSM.
*/
-extern __inline__ int
+static inline int
fsm_getstate(fsm_instance *fi)
{
return atomic_read(&fi->state);
diff --git a/drivers/s390/net/iucv.c b/drivers/s390/net/iucv.c
index e08e74e16124..df7647c3c100 100644
--- a/drivers/s390/net/iucv.c
+++ b/drivers/s390/net/iucv.c
@@ -447,14 +447,10 @@ static void
iucv_exit(void)
{
iucv_retrieve_buffer();
- if (iucv_external_int_buffer) {
- kfree(iucv_external_int_buffer);
- iucv_external_int_buffer = NULL;
- }
- if (iucv_param_pool) {
- kfree(iucv_param_pool);
- iucv_param_pool = NULL;
- }
+ kfree(iucv_external_int_buffer);
+ iucv_external_int_buffer = NULL;
+ kfree(iucv_param_pool);
+ iucv_param_pool = NULL;
s390_root_dev_unregister(iucv_root);
bus_unregister(&iucv_bus);
printk(KERN_INFO "IUCV lowlevel driver unloaded\n");
diff --git a/drivers/s390/net/lcs.c b/drivers/s390/net/lcs.c
index 46f34ba93ac5..1c8ad2fcad8a 100644
--- a/drivers/s390/net/lcs.c
+++ b/drivers/s390/net/lcs.c
@@ -145,8 +145,7 @@ lcs_free_channel(struct lcs_channel *channel)
LCS_DBF_TEXT(2, setup, "ichfree");
for (cnt = 0; cnt < LCS_NUM_BUFFS; cnt++) {
- if (channel->iob[cnt].data != NULL)
- kfree(channel->iob[cnt].data);
+ kfree(channel->iob[cnt].data);
channel->iob[cnt].data = NULL;
}
}
diff --git a/drivers/s390/net/qeth.h b/drivers/s390/net/qeth.h
index 9963479ba89f..38a2441564d7 100644
--- a/drivers/s390/net/qeth.h
+++ b/drivers/s390/net/qeth.h
@@ -275,6 +275,10 @@ qeth_is_ipa_enabled(struct qeth_ipa_info *ipa, enum qeth_ipa_funcs func)
QETH_IDX_FUNC_LEVEL_IQD_ENA_IPAT, \
QETH_IDX_FUNC_LEVEL_IQD_DIS_IPAT, \
QETH_MAX_QUEUES,0x103}, \
+ {0x1731,0x06,0x1732,0x06,QETH_CARD_TYPE_OSN,0, \
+ QETH_IDX_FUNC_LEVEL_OSAE_ENA_IPAT, \
+ QETH_IDX_FUNC_LEVEL_OSAE_DIS_IPAT, \
+ QETH_MAX_QUEUES,0}, \
{0,0,0,0,0,0,0,0,0}}
#define QETH_REAL_CARD 1
@@ -363,10 +367,22 @@ struct qeth_hdr_layer2 {
__u8 reserved2[16];
} __attribute__ ((packed));
+struct qeth_hdr_osn {
+ __u8 id;
+ __u8 reserved;
+ __u16 seq_no;
+ __u16 reserved2;
+ __u16 control_flags;
+ __u16 pdu_length;
+ __u8 reserved3[18];
+ __u32 ccid;
+} __attribute__ ((packed));
+
struct qeth_hdr {
union {
struct qeth_hdr_layer2 l2;
struct qeth_hdr_layer3 l3;
+ struct qeth_hdr_osn osn;
} hdr;
} __attribute__ ((packed));
@@ -413,6 +429,7 @@ enum qeth_header_ids {
QETH_HEADER_TYPE_LAYER3 = 0x01,
QETH_HEADER_TYPE_LAYER2 = 0x02,
QETH_HEADER_TYPE_TSO = 0x03,
+ QETH_HEADER_TYPE_OSN = 0x04,
};
/* flags for qeth_hdr.ext_flags */
#define QETH_HDR_EXT_VLAN_FRAME 0x01
@@ -582,7 +599,6 @@ enum qeth_card_states {
* Protocol versions
*/
enum qeth_prot_versions {
- QETH_PROT_SNA = 0x0001,
QETH_PROT_IPV4 = 0x0004,
QETH_PROT_IPV6 = 0x0006,
};
@@ -761,6 +777,11 @@ enum qeth_threads {
QETH_RECOVER_THREAD = 2,
};
+struct qeth_osn_info {
+ int (*assist_cb)(struct net_device *dev, void *data);
+ int (*data_cb)(struct sk_buff *skb);
+};
+
struct qeth_card {
struct list_head list;
enum qeth_card_states state;
@@ -803,6 +824,7 @@ struct qeth_card {
int use_hard_stop;
int (*orig_hard_header)(struct sk_buff *,struct net_device *,
unsigned short,void *,void *,unsigned);
+ struct qeth_osn_info osn_info;
};
struct qeth_card_list_struct {
@@ -916,10 +938,12 @@ qeth_get_hlen(__u8 link_type)
static inline unsigned short
qeth_get_netdev_flags(struct qeth_card *card)
{
- if (card->options.layer2)
+ if (card->options.layer2 &&
+ (card->info.type == QETH_CARD_TYPE_OSAE))
return 0;
switch (card->info.type) {
case QETH_CARD_TYPE_IQD:
+ case QETH_CARD_TYPE_OSN:
return IFF_NOARP;
#ifdef CONFIG_QETH_IPV6
default:
@@ -956,9 +980,10 @@ static inline int
qeth_get_max_mtu_for_card(int cardtype)
{
switch (cardtype) {
+
case QETH_CARD_TYPE_UNKNOWN:
- return 61440;
case QETH_CARD_TYPE_OSAE:
+ case QETH_CARD_TYPE_OSN:
return 61440;
case QETH_CARD_TYPE_IQD:
return 57344;
@@ -1004,6 +1029,7 @@ qeth_mtu_is_valid(struct qeth_card * card, int mtu)
case QETH_CARD_TYPE_IQD:
return ((mtu >= 576) &&
(mtu <= card->info.max_mtu + 4096 - 32));
+ case QETH_CARD_TYPE_OSN:
case QETH_CARD_TYPE_UNKNOWN:
default:
return 1;
@@ -1015,6 +1041,7 @@ qeth_get_arphdr_type(int cardtype, int linktype)
{
switch (cardtype) {
case QETH_CARD_TYPE_OSAE:
+ case QETH_CARD_TYPE_OSN:
switch (linktype) {
case QETH_LINK_TYPE_LANE_TR:
case QETH_LINK_TYPE_HSTR:
@@ -1182,4 +1209,16 @@ qeth_fill_header(struct qeth_card *, struct qeth_hdr *,
extern void
qeth_flush_buffers(struct qeth_qdio_out_q *, int, int, int);
+extern int
+qeth_osn_assist(struct net_device *, void *, int);
+
+extern int
+qeth_osn_register(unsigned char *read_dev_no,
+ struct net_device **,
+ int (*assist_cb)(struct net_device *, void *),
+ int (*data_cb)(struct sk_buff *));
+
+extern void
+qeth_osn_deregister(struct net_device *);
+
#endif /* __QETH_H__ */
diff --git a/drivers/s390/net/qeth_eddp.c b/drivers/s390/net/qeth_eddp.c
index f94f1f25eec6..011915d5e243 100644
--- a/drivers/s390/net/qeth_eddp.c
+++ b/drivers/s390/net/qeth_eddp.c
@@ -62,8 +62,7 @@ qeth_eddp_free_context(struct qeth_eddp_context *ctx)
for (i = 0; i < ctx->num_pages; ++i)
free_page((unsigned long)ctx->pages[i]);
kfree(ctx->pages);
- if (ctx->elements != NULL)
- kfree(ctx->elements);
+ kfree(ctx->elements);
kfree(ctx);
}
diff --git a/drivers/s390/net/qeth_fs.h b/drivers/s390/net/qeth_fs.h
index 5c9a51ce91b6..c0b4c8d82c45 100644
--- a/drivers/s390/net/qeth_fs.h
+++ b/drivers/s390/net/qeth_fs.h
@@ -12,7 +12,7 @@
#ifndef __QETH_FS_H__
#define __QETH_FS_H__
-#define VERSION_QETH_FS_H "$Revision: 1.9 $"
+#define VERSION_QETH_FS_H "$Revision: 1.10 $"
extern const char *VERSION_QETH_PROC_C;
extern const char *VERSION_QETH_SYS_C;
@@ -43,6 +43,12 @@ extern void
qeth_remove_device_attributes(struct device *dev);
extern int
+qeth_create_device_attributes_osn(struct device *dev);
+
+extern void
+qeth_remove_device_attributes_osn(struct device *dev);
+
+extern int
qeth_create_driver_attributes(void);
extern void
@@ -108,6 +114,8 @@ qeth_get_cardname(struct qeth_card *card)
return " OSD Express";
case QETH_CARD_TYPE_IQD:
return " HiperSockets";
+ case QETH_CARD_TYPE_OSN:
+ return " OSN QDIO";
default:
return " unknown";
}
@@ -153,6 +161,8 @@ qeth_get_cardname_short(struct qeth_card *card)
}
case QETH_CARD_TYPE_IQD:
return "HiperSockets";
+ case QETH_CARD_TYPE_OSN:
+ return "OSN";
default:
return "unknown";
}
diff --git a/drivers/s390/net/qeth_main.c b/drivers/s390/net/qeth_main.c
index bd28e2438d7f..692003c9f896 100644
--- a/drivers/s390/net/qeth_main.c
+++ b/drivers/s390/net/qeth_main.c
@@ -196,7 +196,6 @@ qeth_notifier_register(struct task_struct *p, int signum)
{
struct qeth_notify_list_struct *n_entry;
-
/*check first if entry already exists*/
spin_lock(&qeth_notify_lock);
list_for_each_entry(n_entry, &qeth_notify_list, list) {
@@ -1024,7 +1023,10 @@ qeth_set_intial_options(struct qeth_card *card)
card->options.fake_broadcast = 0;
card->options.add_hhlen = DEFAULT_ADD_HHLEN;
card->options.fake_ll = 0;
- card->options.layer2 = 0;
+ if (card->info.type == QETH_CARD_TYPE_OSN)
+ card->options.layer2 = 1;
+ else
+ card->options.layer2 = 0;
}
/**
@@ -1113,19 +1115,20 @@ qeth_determine_card_type(struct qeth_card *card)
QETH_DBF_TEXT(setup, 2, "detcdtyp");
+ card->qdio.do_prio_queueing = QETH_PRIOQ_DEFAULT;
+ card->qdio.default_out_queue = QETH_DEFAULT_QUEUE;
while (known_devices[i][4]) {
if ((CARD_RDEV(card)->id.dev_type == known_devices[i][2]) &&
(CARD_RDEV(card)->id.dev_model == known_devices[i][3])) {
card->info.type = known_devices[i][4];
+ card->qdio.no_out_queues = known_devices[i][8];
+ card->info.is_multicast_different = known_devices[i][9];
if (is_1920_device(card)) {
PRINT_INFO("Priority Queueing not able "
"due to hardware limitations!\n");
card->qdio.no_out_queues = 1;
card->qdio.default_out_queue = 0;
- } else {
- card->qdio.no_out_queues = known_devices[i][8];
- }
- card->info.is_multicast_different = known_devices[i][9];
+ }
return 0;
}
i++;
@@ -1149,6 +1152,8 @@ qeth_probe_device(struct ccwgroup_device *gdev)
if (!get_device(dev))
return -ENODEV;
+ QETH_DBF_TEXT_(setup, 2, "%s", gdev->dev.bus_id);
+
card = qeth_alloc_card();
if (!card) {
put_device(dev);
@@ -1158,28 +1163,27 @@ qeth_probe_device(struct ccwgroup_device *gdev)
card->read.ccwdev = gdev->cdev[0];
card->write.ccwdev = gdev->cdev[1];
card->data.ccwdev = gdev->cdev[2];
-
- if ((rc = qeth_setup_card(card))){
- QETH_DBF_TEXT_(setup, 2, "2err%d", rc);
- put_device(dev);
- qeth_free_card(card);
- return rc;
- }
gdev->dev.driver_data = card;
card->gdev = gdev;
gdev->cdev[0]->handler = qeth_irq;
gdev->cdev[1]->handler = qeth_irq;
gdev->cdev[2]->handler = qeth_irq;
- rc = qeth_create_device_attributes(dev);
- if (rc) {
+ if ((rc = qeth_determine_card_type(card))){
+ PRINT_WARN("%s: not a valid card type\n", __func__);
+ QETH_DBF_TEXT_(setup, 2, "3err%d", rc);
+ put_device(dev);
+ qeth_free_card(card);
+ return rc;
+ }
+ if ((rc = qeth_setup_card(card))){
+ QETH_DBF_TEXT_(setup, 2, "2err%d", rc);
put_device(dev);
qeth_free_card(card);
return rc;
}
- if ((rc = qeth_determine_card_type(card))){
- PRINT_WARN("%s: not a valid card type\n", __func__);
- QETH_DBF_TEXT_(setup, 2, "3err%d", rc);
+ rc = qeth_create_device_attributes(dev);
+ if (rc) {
put_device(dev);
qeth_free_card(card);
return rc;
@@ -1660,6 +1664,8 @@ qeth_check_ipa_data(struct qeth_card *card, struct qeth_cmd_buffer *iob)
netif_carrier_on(card->dev);
qeth_schedule_recovery(card);
return NULL;
+ case IPA_CMD_MODCCID:
+ return cmd;
case IPA_CMD_REGISTER_LOCAL_ADDR:
QETH_DBF_TEXT(trace,3, "irla");
break;
@@ -1721,6 +1727,14 @@ qeth_send_control_data_cb(struct qeth_channel *channel,
cmd = qeth_check_ipa_data(card, iob);
if ((cmd == NULL) && (card->state != CARD_STATE_DOWN))
goto out;
+ /*in case of OSN : check if cmd is set */
+ if (card->info.type == QETH_CARD_TYPE_OSN &&
+ cmd &&
+ cmd->hdr.command != IPA_CMD_STARTLAN &&
+ card->osn_info.assist_cb != NULL) {
+ card->osn_info.assist_cb(card->dev, cmd);
+ goto out;
+ }
spin_lock_irqsave(&card->lock, flags);
list_for_each_entry_safe(reply, r, &card->cmd_waiter_list, list) {
@@ -1737,8 +1751,7 @@ qeth_send_control_data_cb(struct qeth_channel *channel,
keep_reply = reply->callback(card,
reply,
(unsigned long)cmd);
- }
- else
+ } else
keep_reply = reply->callback(card,
reply,
(unsigned long)iob);
@@ -1768,6 +1781,24 @@ out:
qeth_release_buffer(channel,iob);
}
+static inline void
+qeth_prepare_control_data(struct qeth_card *card, int len,
+struct qeth_cmd_buffer *iob)
+{
+ qeth_setup_ccw(&card->write,iob->data,len);
+ iob->callback = qeth_release_buffer;
+
+ memcpy(QETH_TRANSPORT_HEADER_SEQ_NO(iob->data),
+ &card->seqno.trans_hdr, QETH_SEQ_NO_LENGTH);
+ card->seqno.trans_hdr++;
+ memcpy(QETH_PDU_HEADER_SEQ_NO(iob->data),
+ &card->seqno.pdu_hdr, QETH_SEQ_NO_LENGTH);
+ card->seqno.pdu_hdr++;
+ memcpy(QETH_PDU_HEADER_ACK_SEQ_NO(iob->data),
+ &card->seqno.pdu_hdr_ack, QETH_SEQ_NO_LENGTH);
+ QETH_DBF_HEX(control, 2, iob->data, QETH_DBF_CONTROL_LEN);
+}
+
static int
qeth_send_control_data(struct qeth_card *card, int len,
struct qeth_cmd_buffer *iob,
@@ -1778,24 +1809,11 @@ qeth_send_control_data(struct qeth_card *card, int len,
{
int rc;
unsigned long flags;
- struct qeth_reply *reply;
+ struct qeth_reply *reply = NULL;
struct timer_list timer;
QETH_DBF_TEXT(trace, 2, "sendctl");
- qeth_setup_ccw(&card->write,iob->data,len);
-
- memcpy(QETH_TRANSPORT_HEADER_SEQ_NO(iob->data),
- &card->seqno.trans_hdr, QETH_SEQ_NO_LENGTH);
- card->seqno.trans_hdr++;
-
- memcpy(QETH_PDU_HEADER_SEQ_NO(iob->data),
- &card->seqno.pdu_hdr, QETH_SEQ_NO_LENGTH);
- card->seqno.pdu_hdr++;
- memcpy(QETH_PDU_HEADER_ACK_SEQ_NO(iob->data),
- &card->seqno.pdu_hdr_ack, QETH_SEQ_NO_LENGTH);
- iob->callback = qeth_release_buffer;
-
reply = qeth_alloc_reply(card);
if (!reply) {
PRINT_WARN("Could no alloc qeth_reply!\n");
@@ -1810,10 +1828,6 @@ qeth_send_control_data(struct qeth_card *card, int len,
init_timer(&timer);
timer.function = qeth_cmd_timeout;
timer.data = (unsigned long) reply;
- if (IS_IPA(iob->data))
- timer.expires = jiffies + QETH_IPA_TIMEOUT;
- else
- timer.expires = jiffies + QETH_TIMEOUT;
init_waitqueue_head(&reply->wait_q);
spin_lock_irqsave(&card->lock, flags);
list_add_tail(&reply->list, &card->cmd_waiter_list);
@@ -1821,6 +1835,11 @@ qeth_send_control_data(struct qeth_card *card, int len,
QETH_DBF_HEX(control, 2, iob->data, QETH_DBF_CONTROL_LEN);
wait_event(card->wait_q,
atomic_compare_and_swap(0,1,&card->write.irq_pending) == 0);
+ qeth_prepare_control_data(card, len, iob);
+ if (IS_IPA(iob->data))
+ timer.expires = jiffies + QETH_IPA_TIMEOUT;
+ else
+ timer.expires = jiffies + QETH_TIMEOUT;
QETH_DBF_TEXT(trace, 6, "noirqpnd");
spin_lock_irqsave(get_ccwdev_lock(card->write.ccwdev), flags);
rc = ccw_device_start(card->write.ccwdev, &card->write.ccw,
@@ -1848,6 +1867,62 @@ qeth_send_control_data(struct qeth_card *card, int len,
}
static int
+qeth_osn_send_control_data(struct qeth_card *card, int len,
+ struct qeth_cmd_buffer *iob)
+{
+ unsigned long flags;
+ int rc = 0;
+
+ QETH_DBF_TEXT(trace, 5, "osndctrd");
+
+ wait_event(card->wait_q,
+ atomic_compare_and_swap(0,1,&card->write.irq_pending) == 0);
+ qeth_prepare_control_data(card, len, iob);
+ QETH_DBF_TEXT(trace, 6, "osnoirqp");
+ spin_lock_irqsave(get_ccwdev_lock(card->write.ccwdev), flags);
+ rc = ccw_device_start(card->write.ccwdev, &card->write.ccw,
+ (addr_t) iob, 0, 0);
+ spin_unlock_irqrestore(get_ccwdev_lock(card->write.ccwdev), flags);
+ if (rc){
+ PRINT_WARN("qeth_osn_send_control_data: "
+ "ccw_device_start rc = %i\n", rc);
+ QETH_DBF_TEXT_(trace, 2, " err%d", rc);
+ qeth_release_buffer(iob->channel, iob);
+ atomic_set(&card->write.irq_pending, 0);
+ wake_up(&card->wait_q);
+ }
+ return rc;
+}
+
+static inline void
+qeth_prepare_ipa_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob,
+ char prot_type)
+{
+ memcpy(iob->data, IPA_PDU_HEADER, IPA_PDU_HEADER_SIZE);
+ memcpy(QETH_IPA_CMD_PROT_TYPE(iob->data),&prot_type,1);
+ memcpy(QETH_IPA_CMD_DEST_ADDR(iob->data),
+ &card->token.ulp_connection_r, QETH_MPC_TOKEN_LENGTH);
+}
+
+static int
+qeth_osn_send_ipa_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob,
+ int data_len)
+{
+ u16 s1, s2;
+
+QETH_DBF_TEXT(trace,4,"osndipa");
+
+ qeth_prepare_ipa_cmd(card, iob, QETH_PROT_OSN2);
+ s1 = (u16)(IPA_PDU_HEADER_SIZE + data_len);
+ s2 = (u16)data_len;
+ memcpy(QETH_IPA_PDU_LEN_TOTAL(iob->data), &s1, 2);
+ memcpy(QETH_IPA_PDU_LEN_PDU1(iob->data), &s2, 2);
+ memcpy(QETH_IPA_PDU_LEN_PDU2(iob->data), &s2, 2);
+ memcpy(QETH_IPA_PDU_LEN_PDU3(iob->data), &s2, 2);
+ return qeth_osn_send_control_data(card, s1, iob);
+}
+
+static int
qeth_send_ipa_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob,
int (*reply_cb)
(struct qeth_card *,struct qeth_reply*, unsigned long),
@@ -1858,17 +1933,14 @@ qeth_send_ipa_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob,
QETH_DBF_TEXT(trace,4,"sendipa");
- memcpy(iob->data, IPA_PDU_HEADER, IPA_PDU_HEADER_SIZE);
-
if (card->options.layer2)
- prot_type = QETH_PROT_LAYER2;
+ if (card->info.type == QETH_CARD_TYPE_OSN)
+ prot_type = QETH_PROT_OSN2;
+ else
+ prot_type = QETH_PROT_LAYER2;
else
prot_type = QETH_PROT_TCPIP;
-
- memcpy(QETH_IPA_CMD_PROT_TYPE(iob->data),&prot_type,1);
- memcpy(QETH_IPA_CMD_DEST_ADDR(iob->data),
- &card->token.ulp_connection_r, QETH_MPC_TOKEN_LENGTH);
-
+ qeth_prepare_ipa_cmd(card,iob,prot_type);
rc = qeth_send_control_data(card, IPA_CMD_LENGTH, iob,
reply_cb, reply_param);
return rc;
@@ -2010,7 +2082,10 @@ qeth_ulp_enable(struct qeth_card *card)
*(QETH_ULP_ENABLE_LINKNUM(iob->data)) =
(__u8) card->info.portno;
if (card->options.layer2)
- prot_type = QETH_PROT_LAYER2;
+ if (card->info.type == QETH_CARD_TYPE_OSN)
+ prot_type = QETH_PROT_OSN2;
+ else
+ prot_type = QETH_PROT_LAYER2;
else
prot_type = QETH_PROT_TCPIP;
@@ -2100,15 +2175,21 @@ qeth_check_for_inbound_error(struct qeth_qdio_buffer *buf,
}
static inline struct sk_buff *
-qeth_get_skb(unsigned int length)
+qeth_get_skb(unsigned int length, struct qeth_hdr *hdr)
{
struct sk_buff* skb;
+ int add_len;
+
+ add_len = 0;
+ if (hdr->hdr.osn.id == QETH_HEADER_TYPE_OSN)
+ add_len = sizeof(struct qeth_hdr);
#ifdef CONFIG_QETH_VLAN
- if ((skb = dev_alloc_skb(length + VLAN_HLEN)))
- skb_reserve(skb, VLAN_HLEN);
-#else
- skb = dev_alloc_skb(length);
+ else
+ add_len = VLAN_HLEN;
#endif
+ skb = dev_alloc_skb(length + add_len);
+ if (skb && add_len)
+ skb_reserve(skb, add_len);
return skb;
}
@@ -2138,7 +2219,10 @@ qeth_get_next_skb(struct qeth_card *card, struct qdio_buffer *buffer,
offset += sizeof(struct qeth_hdr);
if (card->options.layer2)
- skb_len = (*hdr)->hdr.l2.pkt_length;
+ if (card->info.type == QETH_CARD_TYPE_OSN)
+ skb_len = (*hdr)->hdr.osn.pdu_length;
+ else
+ skb_len = (*hdr)->hdr.l2.pkt_length;
else
skb_len = (*hdr)->hdr.l3.length;
@@ -2146,15 +2230,15 @@ qeth_get_next_skb(struct qeth_card *card, struct qdio_buffer *buffer,
return NULL;
if (card->options.fake_ll){
if(card->dev->type == ARPHRD_IEEE802_TR){
- if (!(skb = qeth_get_skb(skb_len+QETH_FAKE_LL_LEN_TR)))
+ if (!(skb = qeth_get_skb(skb_len+QETH_FAKE_LL_LEN_TR, *hdr)))
goto no_mem;
skb_reserve(skb,QETH_FAKE_LL_LEN_TR);
} else {
- if (!(skb = qeth_get_skb(skb_len+QETH_FAKE_LL_LEN_ETH)))
+ if (!(skb = qeth_get_skb(skb_len+QETH_FAKE_LL_LEN_ETH, *hdr)))
goto no_mem;
skb_reserve(skb,QETH_FAKE_LL_LEN_ETH);
}
- } else if (!(skb = qeth_get_skb(skb_len)))
+ } else if (!(skb = qeth_get_skb(skb_len, *hdr)))
goto no_mem;
data_ptr = element->addr + offset;
while (skb_len) {
@@ -2453,8 +2537,12 @@ qeth_process_inbound_buffer(struct qeth_card *card,
skb->dev = card->dev;
if (hdr->hdr.l2.id == QETH_HEADER_TYPE_LAYER2)
vlan_tag = qeth_layer2_rebuild_skb(card, skb, hdr);
- else
+ else if (hdr->hdr.l3.id == QETH_HEADER_TYPE_LAYER3)
qeth_rebuild_skb(card, skb, hdr);
+ else { /*in case of OSN*/
+ skb_push(skb, sizeof(struct qeth_hdr));
+ memcpy(skb->data, hdr, sizeof(struct qeth_hdr));
+ }
/* is device UP ? */
if (!(card->dev->flags & IFF_UP)){
dev_kfree_skb_any(skb);
@@ -2465,7 +2553,10 @@ qeth_process_inbound_buffer(struct qeth_card *card,
vlan_hwaccel_rx(skb, card->vlangrp, vlan_tag);
else
#endif
- rxrc = netif_rx(skb);
+ if (card->info.type == QETH_CARD_TYPE_OSN)
+ rxrc = card->osn_info.data_cb(skb);
+ else
+ rxrc = netif_rx(skb);
card->dev->last_rx = jiffies;
card->stats.rx_packets++;
card->stats.rx_bytes += skb->len;
@@ -3150,8 +3241,6 @@ qeth_init_qdio_info(struct qeth_card *card)
INIT_LIST_HEAD(&card->qdio.in_buf_pool.entry_list);
INIT_LIST_HEAD(&card->qdio.init_pool.entry_list);
/* outbound */
- card->qdio.do_prio_queueing = QETH_PRIOQ_DEFAULT;
- card->qdio.default_out_queue = QETH_DEFAULT_QUEUE;
}
static int
@@ -3466,7 +3555,7 @@ qeth_mpc_initialize(struct qeth_card *card)
return 0;
out_qdio:
- qeth_qdio_clear_card(card, card->info.type==QETH_CARD_TYPE_OSAE);
+ qeth_qdio_clear_card(card, card->info.type!=QETH_CARD_TYPE_IQD);
return rc;
}
@@ -3491,6 +3580,9 @@ qeth_get_netdevice(enum qeth_card_types type, enum qeth_link_types linktype)
case QETH_CARD_TYPE_IQD:
dev = alloc_netdev(0, "hsi%d", ether_setup);
break;
+ case QETH_CARD_TYPE_OSN:
+ dev = alloc_netdev(0, "osn%d", ether_setup);
+ break;
default:
dev = alloc_etherdev(0);
}
@@ -3655,7 +3747,8 @@ qeth_open(struct net_device *dev)
if (card->state != CARD_STATE_SOFTSETUP)
return -ENODEV;
- if ( (card->options.layer2) &&
+ if ( (card->info.type != QETH_CARD_TYPE_OSN) &&
+ (card->options.layer2) &&
(!card->info.layer2_mac_registered)) {
QETH_DBF_TEXT(trace,4,"nomacadr");
return -EPERM;
@@ -3693,6 +3786,9 @@ qeth_get_cast_type(struct qeth_card *card, struct sk_buff *skb)
{
int cast_type = RTN_UNSPEC;
+ if (card->info.type == QETH_CARD_TYPE_OSN)
+ return cast_type;
+
if (skb->dst && skb->dst->neighbour){
cast_type = skb->dst->neighbour->type;
if ((cast_type == RTN_BROADCAST) ||
@@ -3782,13 +3878,16 @@ static inline int
qeth_prepare_skb(struct qeth_card *card, struct sk_buff **skb,
struct qeth_hdr **hdr, int ipv)
{
- int rc;
+ int rc = 0;
#ifdef CONFIG_QETH_VLAN
u16 *tag;
#endif
QETH_DBF_TEXT(trace, 6, "prepskb");
-
+ if (card->info.type == QETH_CARD_TYPE_OSN) {
+ *hdr = (struct qeth_hdr *)(*skb)->data;
+ return rc;
+ }
rc = qeth_realloc_headroom(card, skb, sizeof(struct qeth_hdr));
if (rc)
return rc;
@@ -4291,8 +4390,14 @@ qeth_send_packet(struct qeth_card *card, struct sk_buff *skb)
}
}
}
+ if ((card->info.type == QETH_CARD_TYPE_OSN) &&
+ (skb->protocol == htons(ETH_P_IPV6))) {
+ dev_kfree_skb_any(skb);
+ return 0;
+ }
cast_type = qeth_get_cast_type(card, skb);
- if ((cast_type == RTN_BROADCAST) && (card->info.broadcast_capable == 0)){
+ if ((cast_type == RTN_BROADCAST) &&
+ (card->info.broadcast_capable == 0)){
card->stats.tx_dropped++;
card->stats.tx_errors++;
dev_kfree_skb_any(skb);
@@ -4320,7 +4425,8 @@ qeth_send_packet(struct qeth_card *card, struct sk_buff *skb)
QETH_DBF_TEXT_(trace, 4, "pskbe%d", rc);
return rc;
}
- qeth_fill_header(card, hdr, skb, ipv, cast_type);
+ if (card->info.type != QETH_CARD_TYPE_OSN)
+ qeth_fill_header(card, hdr, skb, ipv, cast_type);
}
if (large_send == QETH_LARGE_SEND_EDDP) {
@@ -4381,6 +4487,7 @@ qeth_mdio_read(struct net_device *dev, int phy_id, int regnum)
case MII_BMCR: /* Basic mode control register */
rc = BMCR_FULLDPLX;
if ((card->info.link_type != QETH_LINK_TYPE_GBIT_ETH)&&
+ (card->info.link_type != QETH_LINK_TYPE_OSN) &&
(card->info.link_type != QETH_LINK_TYPE_10GBIT_ETH))
rc |= BMCR_SPEED100;
break;
@@ -5004,6 +5111,9 @@ qeth_do_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
(card->state != CARD_STATE_SOFTSETUP))
return -ENODEV;
+ if (card->info.type == QETH_CARD_TYPE_OSN)
+ return -EPERM;
+
switch (cmd){
case SIOC_QETH_ARP_SET_NO_ENTRIES:
if ( !capable(CAP_NET_ADMIN) ||
@@ -5329,6 +5439,9 @@ qeth_set_multicast_list(struct net_device *dev)
{
struct qeth_card *card = (struct qeth_card *) dev->priv;
+ if (card->info.type == QETH_CARD_TYPE_OSN)
+ return ;
+
QETH_DBF_TEXT(trace,3,"setmulti");
qeth_delete_mc_addresses(card);
qeth_add_multicast_ipv4(card);
@@ -5370,6 +5483,94 @@ qeth_get_addr_buffer(enum qeth_prot_versions prot)
return addr;
}
+int
+qeth_osn_assist(struct net_device *dev,
+ void *data,
+ int data_len)
+{
+ struct qeth_cmd_buffer *iob;
+ struct qeth_card *card;
+ int rc;
+
+ QETH_DBF_TEXT(trace, 2, "osnsdmc");
+ if (!dev)
+ return -ENODEV;
+ card = (struct qeth_card *)dev->priv;
+ if (!card)
+ return -ENODEV;
+ if ((card->state != CARD_STATE_UP) &&
+ (card->state != CARD_STATE_SOFTSETUP))
+ return -ENODEV;
+ iob = qeth_wait_for_buffer(&card->write);
+ memcpy(iob->data+IPA_PDU_HEADER_SIZE, data, data_len);
+ rc = qeth_osn_send_ipa_cmd(card, iob, data_len);
+ return rc;
+}
+
+static struct net_device *
+qeth_netdev_by_devno(unsigned char *read_dev_no)
+{
+ struct qeth_card *card;
+ struct net_device *ndev;
+ unsigned char *readno;
+ __u16 temp_dev_no, card_dev_no;
+ char *endp;
+ unsigned long flags;
+
+ ndev = NULL;
+ memcpy(&temp_dev_no, read_dev_no, 2);
+ read_lock_irqsave(&qeth_card_list.rwlock, flags);
+ list_for_each_entry(card, &qeth_card_list.list, list) {
+ readno = CARD_RDEV_ID(card);
+ readno += (strlen(readno) - 4);
+ card_dev_no = simple_strtoul(readno, &endp, 16);
+ if (card_dev_no == temp_dev_no) {
+ ndev = card->dev;
+ break;
+ }
+ }
+ read_unlock_irqrestore(&qeth_card_list.rwlock, flags);
+ return ndev;
+}
+
+int
+qeth_osn_register(unsigned char *read_dev_no,
+ struct net_device **dev,
+ int (*assist_cb)(struct net_device *, void *),
+ int (*data_cb)(struct sk_buff *))
+{
+ struct qeth_card * card;
+
+ QETH_DBF_TEXT(trace, 2, "osnreg");
+ *dev = qeth_netdev_by_devno(read_dev_no);
+ if (*dev == NULL)
+ return -ENODEV;
+ card = (struct qeth_card *)(*dev)->priv;
+ if (!card)
+ return -ENODEV;
+ if ((assist_cb == NULL) || (data_cb == NULL))
+ return -EINVAL;
+ card->osn_info.assist_cb = assist_cb;
+ card->osn_info.data_cb = data_cb;
+ return 0;
+}
+
+void
+qeth_osn_deregister(struct net_device * dev)
+{
+ struct qeth_card *card;
+
+ QETH_DBF_TEXT(trace, 2, "osndereg");
+ if (!dev)
+ return;
+ card = (struct qeth_card *)dev->priv;
+ if (!card)
+ return;
+ card->osn_info.assist_cb = NULL;
+ card->osn_info.data_cb = NULL;
+ return;
+}
+
static void
qeth_delete_mc_addresses(struct qeth_card *card)
{
@@ -5700,6 +5901,12 @@ qeth_layer2_set_mac_address(struct net_device *dev, void *p)
QETH_DBF_TEXT(trace, 3, "setmcLY3");
return -EOPNOTSUPP;
}
+ if (card->info.type == QETH_CARD_TYPE_OSN) {
+ PRINT_WARN("Setting MAC address on %s is not supported.\n",
+ dev->name);
+ QETH_DBF_TEXT(trace, 3, "setmcOSN");
+ return -EOPNOTSUPP;
+ }
QETH_DBF_TEXT_(trace, 3, "%s", CARD_BUS_ID(card));
QETH_DBF_HEX(trace, 3, addr->sa_data, OSA_ADDR_LEN);
rc = qeth_layer2_send_delmac(card, &card->dev->dev_addr[0]);
@@ -6076,9 +6283,8 @@ qeth_netdev_init(struct net_device *dev)
qeth_get_hlen(card->info.link_type) + card->options.add_hhlen;
dev->addr_len = OSA_ADDR_LEN;
dev->mtu = card->info.initial_mtu;
-
- SET_ETHTOOL_OPS(dev, &qeth_ethtool_ops);
-
+ if (card->info.type != QETH_CARD_TYPE_OSN)
+ SET_ETHTOOL_OPS(dev, &qeth_ethtool_ops);
SET_MODULE_OWNER(dev);
return 0;
}
@@ -6095,6 +6301,7 @@ qeth_init_func_level(struct qeth_card *card)
QETH_IDX_FUNC_LEVEL_OSAE_ENA_IPAT;
} else {
if (card->info.type == QETH_CARD_TYPE_IQD)
+ /*FIXME:why do we have same values for dis and ena for osae??? */
card->info.func_level =
QETH_IDX_FUNC_LEVEL_IQD_DIS_IPAT;
else
@@ -6124,7 +6331,7 @@ retry:
ccw_device_set_online(CARD_WDEV(card));
ccw_device_set_online(CARD_DDEV(card));
}
- rc = qeth_qdio_clear_card(card,card->info.type==QETH_CARD_TYPE_OSAE);
+ rc = qeth_qdio_clear_card(card,card->info.type!=QETH_CARD_TYPE_IQD);
if (rc == -ERESTARTSYS) {
QETH_DBF_TEXT(setup, 2, "break1");
return rc;
@@ -6176,8 +6383,8 @@ retry:
card->dev = qeth_get_netdevice(card->info.type,
card->info.link_type);
if (!card->dev){
- qeth_qdio_clear_card(card, card->info.type ==
- QETH_CARD_TYPE_OSAE);
+ qeth_qdio_clear_card(card, card->info.type !=
+ QETH_CARD_TYPE_IQD);
rc = -ENODEV;
QETH_DBF_TEXT_(setup, 2, "6err%d", rc);
goto out;
@@ -7084,6 +7291,8 @@ qeth_softsetup_card(struct qeth_card *card)
return rc;
} else
card->lan_online = 1;
+ if (card->info.type==QETH_CARD_TYPE_OSN)
+ goto out;
if (card->options.layer2) {
card->dev->features |=
NETIF_F_HW_VLAN_FILTER |
@@ -7255,7 +7464,8 @@ qeth_stop_card(struct qeth_card *card, int recovery_mode)
if (card->read.state == CH_STATE_UP &&
card->write.state == CH_STATE_UP &&
(card->state == CARD_STATE_UP)) {
- if(recovery_mode) {
+ if (recovery_mode &&
+ card->info.type != QETH_CARD_TYPE_OSN) {
qeth_stop(card->dev);
} else {
rtnl_lock();
@@ -7437,7 +7647,8 @@ qeth_start_again(struct qeth_card *card, int recovery_mode)
{
QETH_DBF_TEXT(setup ,2, "startag");
- if(recovery_mode) {
+ if (recovery_mode &&
+ card->info.type != QETH_CARD_TYPE_OSN) {
qeth_open(card->dev);
} else {
rtnl_lock();
@@ -7469,33 +7680,36 @@ qeth_start_again(struct qeth_card *card, int recovery_mode)
static void qeth_make_parameters_consistent(struct qeth_card *card)
{
- if (card->options.layer2) {
- if (card->info.type == QETH_CARD_TYPE_IQD) {
- PRINT_ERR("Device %s does not support " \
- "layer 2 functionality. " \
- "Ignoring layer2 option.\n",CARD_BUS_ID(card));
- }
- IGNORE_PARAM_NEQ(route4.type, NO_ROUTER, NO_ROUTER,
- "Routing options are");
+ if (card->options.layer2 == 0)
+ return;
+ if (card->info.type == QETH_CARD_TYPE_OSN)
+ return;
+ if (card->info.type == QETH_CARD_TYPE_IQD) {
+ PRINT_ERR("Device %s does not support layer 2 functionality." \
+ " Ignoring layer2 option.\n",CARD_BUS_ID(card));
+ card->options.layer2 = 0;
+ return;
+ }
+ IGNORE_PARAM_NEQ(route4.type, NO_ROUTER, NO_ROUTER,
+ "Routing options are");
#ifdef CONFIG_QETH_IPV6
- IGNORE_PARAM_NEQ(route6.type, NO_ROUTER, NO_ROUTER,
- "Routing options are");
+ IGNORE_PARAM_NEQ(route6.type, NO_ROUTER, NO_ROUTER,
+ "Routing options are");
#endif
- IGNORE_PARAM_EQ(checksum_type, HW_CHECKSUMMING,
- QETH_CHECKSUM_DEFAULT,
- "Checksumming options are");
- IGNORE_PARAM_NEQ(broadcast_mode, QETH_TR_BROADCAST_ALLRINGS,
- QETH_TR_BROADCAST_ALLRINGS,
- "Broadcast mode options are");
- IGNORE_PARAM_NEQ(macaddr_mode, QETH_TR_MACADDR_NONCANONICAL,
- QETH_TR_MACADDR_NONCANONICAL,
- "Canonical MAC addr options are");
- IGNORE_PARAM_NEQ(fake_broadcast, 0, 0,
- "Broadcast faking options are");
- IGNORE_PARAM_NEQ(add_hhlen, DEFAULT_ADD_HHLEN,
- DEFAULT_ADD_HHLEN,"Option add_hhlen is");
- IGNORE_PARAM_NEQ(fake_ll, 0, 0,"Option fake_ll is");
- }
+ IGNORE_PARAM_EQ(checksum_type, HW_CHECKSUMMING,
+ QETH_CHECKSUM_DEFAULT,
+ "Checksumming options are");
+ IGNORE_PARAM_NEQ(broadcast_mode, QETH_TR_BROADCAST_ALLRINGS,
+ QETH_TR_BROADCAST_ALLRINGS,
+ "Broadcast mode options are");
+ IGNORE_PARAM_NEQ(macaddr_mode, QETH_TR_MACADDR_NONCANONICAL,
+ QETH_TR_MACADDR_NONCANONICAL,
+ "Canonical MAC addr options are");
+ IGNORE_PARAM_NEQ(fake_broadcast, 0, 0,
+ "Broadcast faking options are");
+ IGNORE_PARAM_NEQ(add_hhlen, DEFAULT_ADD_HHLEN,
+ DEFAULT_ADD_HHLEN,"Option add_hhlen is");
+ IGNORE_PARAM_NEQ(fake_ll, 0, 0,"Option fake_ll is");
}
@@ -7525,8 +7739,7 @@ __qeth_set_online(struct ccwgroup_device *gdev, int recovery_mode)
return -EIO;
}
- if (card->options.layer2)
- qeth_make_parameters_consistent(card);
+ qeth_make_parameters_consistent(card);
if ((rc = qeth_hardsetup_card(card))){
QETH_DBF_TEXT_(setup, 2, "2err%d", rc);
@@ -7585,6 +7798,7 @@ qeth_set_online(struct ccwgroup_device *gdev)
static struct ccw_device_id qeth_ids[] = {
{CCW_DEVICE(0x1731, 0x01), driver_info:QETH_CARD_TYPE_OSAE},
{CCW_DEVICE(0x1731, 0x05), driver_info:QETH_CARD_TYPE_IQD},
+ {CCW_DEVICE(0x1731, 0x06), driver_info:QETH_CARD_TYPE_OSN},
{},
};
MODULE_DEVICE_TABLE(ccw, qeth_ids);
@@ -8329,6 +8543,9 @@ again:
printk("qeth: removed\n");
}
+EXPORT_SYMBOL(qeth_osn_register);
+EXPORT_SYMBOL(qeth_osn_deregister);
+EXPORT_SYMBOL(qeth_osn_assist);
module_init(qeth_init);
module_exit(qeth_exit);
MODULE_AUTHOR("Frank Pavlic <pavlic@de.ibm.com>");
diff --git a/drivers/s390/net/qeth_mpc.c b/drivers/s390/net/qeth_mpc.c
index f685ecc7da99..30e053d3cac2 100644
--- a/drivers/s390/net/qeth_mpc.c
+++ b/drivers/s390/net/qeth_mpc.c
@@ -11,7 +11,7 @@
#include <asm/cio.h>
#include "qeth_mpc.h"
-const char *VERSION_QETH_MPC_C = "$Revision: 1.11 $";
+const char *VERSION_QETH_MPC_C = "$Revision: 1.12 $";
unsigned char IDX_ACTIVATE_READ[]={
0x00,0x00,0x80,0x00, 0x00,0x00,0x00,0x00,
@@ -138,7 +138,9 @@ unsigned char IPA_PDU_HEADER[]={
sizeof(struct qeth_ipa_cmd)%256,
0x00,
sizeof(struct qeth_ipa_cmd)/256,
- sizeof(struct qeth_ipa_cmd),0x05, 0x77,0x77,0x77,0x77,
+ sizeof(struct qeth_ipa_cmd)%256,
+ 0x05,
+ 0x77,0x77,0x77,0x77,
0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,
0x01,0x00,
sizeof(struct qeth_ipa_cmd)/256,
diff --git a/drivers/s390/net/qeth_mpc.h b/drivers/s390/net/qeth_mpc.h
index 3d916b5c5d09..7edc5f1fc0d2 100644
--- a/drivers/s390/net/qeth_mpc.h
+++ b/drivers/s390/net/qeth_mpc.h
@@ -46,13 +46,16 @@ extern unsigned char IPA_PDU_HEADER[];
/* IP Assist related definitions */
/*****************************************************************************/
#define IPA_CMD_INITIATOR_HOST 0x00
-#define IPA_CMD_INITIATOR_HYDRA 0x01
+#define IPA_CMD_INITIATOR_OSA 0x01
+#define IPA_CMD_INITIATOR_HOST_REPLY 0x80
+#define IPA_CMD_INITIATOR_OSA_REPLY 0x81
#define IPA_CMD_PRIM_VERSION_NO 0x01
enum qeth_card_types {
QETH_CARD_TYPE_UNKNOWN = 0,
QETH_CARD_TYPE_OSAE = 10,
QETH_CARD_TYPE_IQD = 1234,
+ QETH_CARD_TYPE_OSN = 11,
};
#define QETH_MPC_DIFINFO_LEN_INDICATES_LINK_TYPE 0x18
@@ -61,6 +64,7 @@ enum qeth_link_types {
QETH_LINK_TYPE_FAST_ETH = 0x01,
QETH_LINK_TYPE_HSTR = 0x02,
QETH_LINK_TYPE_GBIT_ETH = 0x03,
+ QETH_LINK_TYPE_OSN = 0x04,
QETH_LINK_TYPE_10GBIT_ETH = 0x10,
QETH_LINK_TYPE_LANE_ETH100 = 0x81,
QETH_LINK_TYPE_LANE_TR = 0x82,
@@ -111,6 +115,9 @@ enum qeth_ipa_cmds {
IPA_CMD_DELGMAC = 0x24,
IPA_CMD_SETVLAN = 0x25,
IPA_CMD_DELVLAN = 0x26,
+ IPA_CMD_SETCCID = 0x41,
+ IPA_CMD_DELCCID = 0x42,
+ IPA_CMD_MODCCID = 0x43,
IPA_CMD_SETIP = 0xb1,
IPA_CMD_DELIP = 0xb7,
IPA_CMD_QIPASSIST = 0xb2,
@@ -437,8 +444,9 @@ enum qeth_ipa_arp_return_codes {
#define QETH_ARP_DATA_SIZE 3968
#define QETH_ARP_CMD_LEN (QETH_ARP_DATA_SIZE + 8)
/* Helper functions */
-#define IS_IPA_REPLY(cmd) (cmd->hdr.initiator == IPA_CMD_INITIATOR_HOST)
-
+#define IS_IPA_REPLY(cmd) ((cmd->hdr.initiator == IPA_CMD_INITIATOR_HOST) || \
+ (cmd->hdr.initiator == IPA_CMD_INITIATOR_OSA_REPLY))
+
/*****************************************************************************/
/* END OF IP Assist related definitions */
/*****************************************************************************/
@@ -483,6 +491,7 @@ extern unsigned char ULP_ENABLE[];
/* Layer 2 defintions */
#define QETH_PROT_LAYER2 0x08
#define QETH_PROT_TCPIP 0x03
+#define QETH_PROT_OSN2 0x0a
#define QETH_ULP_ENABLE_PROT_TYPE(buffer) (buffer+0x50)
#define QETH_IPA_CMD_PROT_TYPE(buffer) (buffer+0x19)
diff --git a/drivers/s390/net/qeth_sys.c b/drivers/s390/net/qeth_sys.c
index dda105b73063..f91a02db5743 100644
--- a/drivers/s390/net/qeth_sys.c
+++ b/drivers/s390/net/qeth_sys.c
@@ -1,6 +1,6 @@
/*
*
- * linux/drivers/s390/net/qeth_sys.c ($Revision: 1.54 $)
+ * linux/drivers/s390/net/qeth_sys.c ($Revision: 1.55 $)
*
* Linux on zSeries OSA Express and HiperSockets support
* This file contains code related to sysfs.
@@ -20,7 +20,7 @@
#include "qeth_mpc.h"
#include "qeth_fs.h"
-const char *VERSION_QETH_SYS_C = "$Revision: 1.54 $";
+const char *VERSION_QETH_SYS_C = "$Revision: 1.55 $";
/*****************************************************************************/
/* */
@@ -937,6 +937,19 @@ static struct attribute_group qeth_device_attr_group = {
.attrs = (struct attribute **)qeth_device_attrs,
};
+static struct device_attribute * qeth_osn_device_attrs[] = {
+ &dev_attr_state,
+ &dev_attr_chpid,
+ &dev_attr_if_name,
+ &dev_attr_card_type,
+ &dev_attr_buffer_count,
+ &dev_attr_recover,
+ NULL,
+};
+
+static struct attribute_group qeth_osn_device_attr_group = {
+ .attrs = (struct attribute **)qeth_osn_device_attrs,
+};
#define QETH_DEVICE_ATTR(_id,_name,_mode,_show,_store) \
struct device_attribute dev_attr_##_id = { \
@@ -1667,7 +1680,12 @@ int
qeth_create_device_attributes(struct device *dev)
{
int ret;
+ struct qeth_card *card = dev->driver_data;
+ if (card->info.type == QETH_CARD_TYPE_OSN)
+ return sysfs_create_group(&dev->kobj,
+ &qeth_osn_device_attr_group);
+
if ((ret = sysfs_create_group(&dev->kobj, &qeth_device_attr_group)))
return ret;
if ((ret = sysfs_create_group(&dev->kobj, &qeth_device_ipato_group))){
@@ -1693,6 +1711,12 @@ qeth_create_device_attributes(struct device *dev)
void
qeth_remove_device_attributes(struct device *dev)
{
+ struct qeth_card *card = dev->driver_data;
+
+ if (card->info.type == QETH_CARD_TYPE_OSN)
+ return sysfs_remove_group(&dev->kobj,
+ &qeth_osn_device_attr_group);
+
sysfs_remove_group(&dev->kobj, &qeth_device_attr_group);
sysfs_remove_group(&dev->kobj, &qeth_device_ipato_group);
sysfs_remove_group(&dev->kobj, &qeth_device_vipa_group);
diff --git a/drivers/s390/s390mach.h b/drivers/s390/s390mach.h
index 4eaa70179182..d9ea7ed2e46e 100644
--- a/drivers/s390/s390mach.h
+++ b/drivers/s390/s390mach.h
@@ -88,7 +88,7 @@ struct crw {
#define CRW_ERC_PERRI 0x07 /* perm. error, facility init */
#define CRW_ERC_PMOD 0x08 /* installed parameters modified */
-extern __inline__ int stcrw(struct crw *pcrw )
+static inline int stcrw(struct crw *pcrw )
{
int ccode;
diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c
index cab098556b44..c218b5c944a6 100644
--- a/drivers/s390/scsi/zfcp_aux.c
+++ b/drivers/s390/scsi/zfcp_aux.c
@@ -450,8 +450,7 @@ zfcp_cfdc_dev_ioctl(struct file *file, unsigned int command,
kfree(sg_list);
}
- if (sense_data != NULL)
- kfree(sense_data);
+ kfree(sense_data);
return retval;
}
diff --git a/drivers/sbus/char/cpwatchdog.c b/drivers/sbus/char/cpwatchdog.c
index c82abeb59d3a..fd2cc7782f76 100644
--- a/drivers/sbus/char/cpwatchdog.c
+++ b/drivers/sbus/char/cpwatchdog.c
@@ -26,6 +26,7 @@
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <linux/timer.h>
+#include <linux/smp_lock.h>
#include <asm/irq.h>
#include <asm/ebus.h>
#include <asm/oplib.h>
@@ -394,6 +395,28 @@ static int wd_ioctl(struct inode *inode, struct file *file,
return(0);
}
+static long wd_compat_ioctl(struct file *file, unsigned int cmd,
+ unsigned long arg)
+{
+ int rval = -ENOIOCTLCMD;
+
+ switch (cmd) {
+ /* solaris ioctls are specific to this driver */
+ case WIOCSTART:
+ case WIOCSTOP:
+ case WIOCGSTAT:
+ lock_kernel();
+ rval = wd_ioctl(file->f_dentry->d_inode, file, cmd, arg);
+ unlock_kernel();
+ break;
+ /* everything else is handled by the generic compat layer */
+ default:
+ break;
+ }
+
+ return rval;
+}
+
static ssize_t wd_write(struct file *file,
const char __user *buf,
size_t count,
@@ -441,6 +464,7 @@ static irqreturn_t wd_interrupt(int irq, void *dev_id, struct pt_regs *regs)
static struct file_operations wd_fops = {
.owner = THIS_MODULE,
.ioctl = wd_ioctl,
+ .compat_ioctl = wd_compat_ioctl,
.open = wd_open,
.write = wd_write,
.read = wd_read,
diff --git a/drivers/sbus/char/display7seg.c b/drivers/sbus/char/display7seg.c
index 24ed5893b4f0..c3a51d1fae5d 100644
--- a/drivers/sbus/char/display7seg.c
+++ b/drivers/sbus/char/display7seg.c
@@ -15,6 +15,7 @@
#include <linux/init.h>
#include <linux/miscdevice.h>
#include <linux/ioport.h> /* request_region */
+#include <linux/smp_lock.h>
#include <asm/atomic.h>
#include <asm/ebus.h> /* EBus device */
#include <asm/oplib.h> /* OpenProm Library */
@@ -114,22 +115,25 @@ static int d7s_release(struct inode *inode, struct file *f)
return 0;
}
-static int d7s_ioctl(struct inode *inode, struct file *f,
- unsigned int cmd, unsigned long arg)
+static long d7s_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
__u8 regs = readb(d7s_regs);
__u8 ireg = 0;
+ int error = 0;
- if (D7S_MINOR != iminor(inode))
+ if (D7S_MINOR != iminor(file->f_dentry->d_inode))
return -ENODEV;
+ lock_kernel();
switch (cmd) {
case D7SIOCWR:
/* assign device register values
* we mask-out D7S_FLIP if in sol_compat mode
*/
- if (get_user(ireg, (int __user *) arg))
- return -EFAULT;
+ if (get_user(ireg, (int __user *) arg)) {
+ error = -EFAULT;
+ break;
+ }
if (0 != sol_compat) {
(regs & D7S_FLIP) ?
(ireg |= D7S_FLIP) : (ireg &= ~D7S_FLIP);
@@ -144,8 +148,10 @@ static int d7s_ioctl(struct inode *inode, struct file *f,
* This driver will not misinform you about the state
* of your hardware while in sol_compat mode
*/
- if (put_user(regs, (int __user *) arg))
- return -EFAULT;
+ if (put_user(regs, (int __user *) arg)) {
+ error = -EFAULT;
+ break;
+ }
break;
case D7SIOCTM:
@@ -155,15 +161,17 @@ static int d7s_ioctl(struct inode *inode, struct file *f,
writeb(regs, d7s_regs);
break;
};
+ unlock_kernel();
- return 0;
+ return error;
}
static struct file_operations d7s_fops = {
- .owner = THIS_MODULE,
- .ioctl = d7s_ioctl,
- .open = d7s_open,
- .release = d7s_release,
+ .owner = THIS_MODULE,
+ .unlocked_ioctl = d7s_ioctl,
+ .compat_ioctl = d7s_ioctl,
+ .open = d7s_open,
+ .release = d7s_release,
};
static struct miscdevice d7s_miscdev = { D7S_MINOR, D7S_DEVNAME, &d7s_fops };
diff --git a/drivers/sbus/char/envctrl.c b/drivers/sbus/char/envctrl.c
index b0cc3c2588fd..19e8eddf887a 100644
--- a/drivers/sbus/char/envctrl.c
+++ b/drivers/sbus/char/envctrl.c
@@ -654,9 +654,8 @@ envctrl_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
/* Function Description: Command what to read. Mapped to user ioctl().
* Return: Gives 0 for implemented commands, -EINVAL otherwise.
*/
-static int
-envctrl_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long arg)
+static long
+envctrl_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
char __user *infobuf;
@@ -715,11 +714,14 @@ envctrl_release(struct inode *inode, struct file *file)
}
static struct file_operations envctrl_fops = {
- .owner = THIS_MODULE,
- .read = envctrl_read,
- .ioctl = envctrl_ioctl,
- .open = envctrl_open,
- .release = envctrl_release,
+ .owner = THIS_MODULE,
+ .read = envctrl_read,
+ .unlocked_ioctl = envctrl_ioctl,
+#ifdef CONFIG_COMPAT
+ .compat_ioctl = envctrl_ioctl,
+#endif
+ .open = envctrl_open,
+ .release = envctrl_release,
};
static struct miscdevice envctrl_dev = {
@@ -1125,10 +1127,9 @@ out_deregister:
misc_deregister(&envctrl_dev);
out_iounmap:
iounmap(i2c);
- for (i = 0; i < ENVCTRL_MAX_CPU * 2; i++) {
- if (i2c_childlist[i].tables)
- kfree(i2c_childlist[i].tables);
- }
+ for (i = 0; i < ENVCTRL_MAX_CPU * 2; i++)
+ kfree(i2c_childlist[i].tables);
+
return err;
}
@@ -1141,10 +1142,8 @@ static void __exit envctrl_cleanup(void)
iounmap(i2c);
misc_deregister(&envctrl_dev);
- for (i = 0; i < ENVCTRL_MAX_CPU * 2; i++) {
- if (i2c_childlist[i].tables)
- kfree(i2c_childlist[i].tables);
- }
+ for (i = 0; i < ENVCTRL_MAX_CPU * 2; i++)
+ kfree(i2c_childlist[i].tables);
}
module_init(envctrl_init);
diff --git a/drivers/sbus/char/openprom.c b/drivers/sbus/char/openprom.c
index 58ed33749571..383a95f34a0d 100644
--- a/drivers/sbus/char/openprom.c
+++ b/drivers/sbus/char/openprom.c
@@ -39,6 +39,7 @@
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/miscdevice.h>
+#include <linux/smp_lock.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <asm/oplib.h>
@@ -565,6 +566,40 @@ static int openprom_ioctl(struct inode * inode, struct file * file,
}
}
+static long openprom_compat_ioctl(struct file *file, unsigned int cmd,
+ unsigned long arg)
+{
+ long rval = -ENOTTY;
+
+ /*
+ * SunOS/Solaris only, the NetBSD one's have embedded pointers in
+ * the arg which we'd need to clean up...
+ */
+ switch (cmd) {
+ case OPROMGETOPT:
+ case OPROMSETOPT:
+ case OPROMNXTOPT:
+ case OPROMSETOPT2:
+ case OPROMNEXT:
+ case OPROMCHILD:
+ case OPROMGETPROP:
+ case OPROMNXTPROP:
+ case OPROMU2P:
+ case OPROMGETCONS:
+ case OPROMGETFBNAME:
+ case OPROMGETBOOTARGS:
+ case OPROMSETCUR:
+ case OPROMPCI2NODE:
+ case OPROMPATH2NODE:
+ lock_kernel();
+ rval = openprom_ioctl(file->f_dentry->d_inode, file, cmd, arg);
+ lock_kernel();
+ break;
+ }
+
+ return rval;
+}
+
static int openprom_open(struct inode * inode, struct file * file)
{
DATA *data;
@@ -590,6 +625,7 @@ static struct file_operations openprom_fops = {
.owner = THIS_MODULE,
.llseek = no_llseek,
.ioctl = openprom_ioctl,
+ .compat_ioctl = openprom_compat_ioctl,
.open = openprom_open,
.release = openprom_release,
};
diff --git a/drivers/sbus/char/rtc.c b/drivers/sbus/char/rtc.c
index 9b988baf0b51..5774bdd0e26f 100644
--- a/drivers/sbus/char/rtc.c
+++ b/drivers/sbus/char/rtc.c
@@ -210,6 +210,27 @@ static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
}
}
+static long rtc_compat_ioctl(struct file *file, unsigned int cmd,
+ unsigned long arg)
+{
+ int rval = -ENOIOCTLCMD;
+
+ switch (cmd) {
+ /*
+ * These two are specific to this driver, the generic rtc ioctls
+ * are hanlded elsewhere.
+ */
+ case RTCGET:
+ case RTCSET:
+ lock_kernel();
+ rval = rtc_ioctl(file->f_dentry->d_inode, file, cmd, arg);
+ unlock_kernel();
+ break;
+ }
+
+ return rval;
+}
+
static int rtc_open(struct inode *inode, struct file *file)
{
int ret;
@@ -237,6 +258,7 @@ static struct file_operations rtc_fops = {
.owner = THIS_MODULE,
.llseek = no_llseek,
.ioctl = rtc_ioctl,
+ .compat_ioctl = rtc_compat_ioctl,
.open = rtc_open,
.release = rtc_release,
};
diff --git a/drivers/scsi/3w-9xxx.c b/drivers/scsi/3w-9xxx.c
index a748fbfb6692..3ff74f472249 100644
--- a/drivers/scsi/3w-9xxx.c
+++ b/drivers/scsi/3w-9xxx.c
@@ -1017,8 +1017,7 @@ static void twa_free_device_extension(TW_Device_Extension *tw_dev)
tw_dev->generic_buffer_virt[0],
tw_dev->generic_buffer_phys[0]);
- if (tw_dev->event_queue[0])
- kfree(tw_dev->event_queue[0]);
+ kfree(tw_dev->event_queue[0]);
} /* End twa_free_device_extension() */
/* This function will free a request id */
@@ -1732,7 +1731,9 @@ static int twa_scsi_eh_reset(struct scsi_cmnd *SCpnt)
tw_dev->num_resets++;
- printk(KERN_WARNING "3w-9xxx: scsi%d: WARNING: (0x%02X:0x%04X): Unit #%d: Command (0x%x) timed out, resetting card.\n", tw_dev->host->host_no, TW_DRIVER, 0x2c, SCpnt->device->id, SCpnt->cmnd[0]);
+ sdev_printk(KERN_WARNING, SCpnt->device,
+ "WARNING: (0x%02X:0x%04X): Command (0x%x) timed out, resetting card.\n",
+ TW_DRIVER, 0x2c, SCpnt->cmnd[0]);
/* Now reset the card and some of the device extension data */
if (twa_reset_device_extension(tw_dev, 0)) {
diff --git a/drivers/scsi/3w-xxxx.c b/drivers/scsi/3w-xxxx.c
index ae9e0203e9de..283f6d25892b 100644
--- a/drivers/scsi/3w-xxxx.c
+++ b/drivers/scsi/3w-xxxx.c
@@ -1432,7 +1432,9 @@ static int tw_scsi_eh_reset(struct scsi_cmnd *SCpnt)
tw_dev->num_resets++;
- printk(KERN_WARNING "3w-xxxx: scsi%d: WARNING: Unit #%d: Command (0x%x) timed out, resetting card.\n", tw_dev->host->host_no, SCpnt->device->id, SCpnt->cmnd[0]);
+ sdev_printk(KERN_WARNING, SCpnt->device,
+ "WARNING: Command (0x%x) timed out, resetting card.\n",
+ SCpnt->cmnd[0]);
/* Now reset the card and some of the device extension data */
if (tw_reset_device_extension(tw_dev, 0)) {
diff --git a/drivers/scsi/3w-xxxx.h b/drivers/scsi/3w-xxxx.h
index 98bad773f240..4f81fc39ec57 100644
--- a/drivers/scsi/3w-xxxx.h
+++ b/drivers/scsi/3w-xxxx.h
@@ -54,7 +54,6 @@
#ifndef _3W_XXXX_H
#define _3W_XXXX_H
-#include <linux/version.h>
#include <linux/types.h>
/* AEN strings */
diff --git a/drivers/scsi/53c700.c b/drivers/scsi/53c700.c
index a7620fc368e7..e7ad269041a4 100644
--- a/drivers/scsi/53c700.c
+++ b/drivers/scsi/53c700.c
@@ -128,6 +128,7 @@
#include <linux/blkdev.h>
#include <linux/module.h>
#include <linux/interrupt.h>
+#include <linux/device.h>
#include <asm/dma.h>
#include <asm/system.h>
#include <asm/io.h>
@@ -831,8 +832,8 @@ process_extended_message(struct Scsi_Host *host,
} else {
/* SDTR message out of the blue, reject it */
- printk(KERN_WARNING "scsi%d Unexpected SDTR msg\n",
- host->host_no);
+ shost_printk(KERN_WARNING, host,
+ "Unexpected SDTR msg\n");
hostdata->msgout[0] = A_REJECT_MSG;
dma_cache_sync(hostdata->msgout, 1, DMA_TO_DEVICE);
script_patch_16(hostdata->script, MessageCount, 1);
@@ -906,15 +907,17 @@ process_message(struct Scsi_Host *host, struct NCR_700_Host_Parameters *hostdata
NCR_700_clear_flag(SCp->device, NCR_700_DEV_BEGIN_SYNC_NEGOTIATION);
} else if(SCp != NULL && NCR_700_get_tag_neg_state(SCp->device) == NCR_700_DURING_TAG_NEGOTIATION) {
/* rejected our first simple tag message */
- printk(KERN_WARNING "scsi%d (%d:%d) Rejected first tag queue attempt, turning off tag queueing\n", host->host_no, pun, lun);
+ scmd_printk(KERN_WARNING, SCp,
+ "Rejected first tag queue attempt, turning off tag queueing\n");
/* we're done negotiating */
NCR_700_set_tag_neg_state(SCp->device, NCR_700_FINISHED_TAG_NEGOTIATION);
- hostdata->tag_negotiated &= ~(1<<SCp->device->id);
+ hostdata->tag_negotiated &= ~(1<<scmd_id(SCp));
SCp->device->tagged_supported = 0;
scsi_deactivate_tcq(SCp->device, host->cmd_per_lun);
} else {
- printk(KERN_WARNING "scsi%d (%d:%d) Unexpected REJECT Message %s\n",
- host->host_no, pun, lun,
+ shost_printk(KERN_WARNING, host,
+ "(%d:%d) Unexpected REJECT Message %s\n",
+ pun, lun,
NCR_700_phase[(dsps & 0xf00) >> 8]);
/* however, just ignore it */
}
@@ -983,7 +986,8 @@ process_script_interrupt(__u32 dsps, __u32 dsp, struct scsi_cmnd *SCp,
if(SCp->cmnd[0] == REQUEST_SENSE) {
/* OOPS: bad device, returning another
* contingent allegiance condition */
- printk(KERN_ERR "scsi%d (%d:%d) broken device is looping in contingent allegiance: ignoring\n", host->host_no, pun, lun);
+ scmd_printk(KERN_ERR, SCp,
+ "broken device is looping in contingent allegiance: ignoring\n");
NCR_700_scsi_done(hostdata, SCp, hostdata->status[0]);
} else {
#ifdef NCR_DEBUG
@@ -1047,12 +1051,13 @@ process_script_interrupt(__u32 dsps, __u32 dsp, struct scsi_cmnd *SCp,
// SCp->request_bufflen,
// DMA_FROM_DEVICE);
// if(((char *)SCp->request_buffer)[7] & 0x02) {
- // printk(KERN_INFO "scsi%d: (%d:%d) Enabling Tag Command Queuing\n", host->host_no, pun, lun);
- // hostdata->tag_negotiated |= (1<<SCp->device->id);
+ // scmd_printk(KERN_INFO, SCp,
+ // "Enabling Tag Command Queuing\n");
+ // hostdata->tag_negotiated |= (1<<scmd_id(SCp));
// NCR_700_set_flag(SCp->device, NCR_700_DEV_BEGIN_TAG_QUEUEING);
// } else {
// NCR_700_clear_flag(SCp->device, NCR_700_DEV_BEGIN_TAG_QUEUEING);
- // hostdata->tag_negotiated &= ~(1<<SCp->device->id);
+ // hostdata->tag_negotiated &= ~(1<<scmd_id(SCp));
// }
//}
NCR_700_scsi_done(hostdata, SCp, hostdata->status[0]);
@@ -1060,11 +1065,11 @@ process_script_interrupt(__u32 dsps, __u32 dsp, struct scsi_cmnd *SCp,
} else if((dsps & 0xfffff0f0) == A_UNEXPECTED_PHASE) {
__u8 i = (dsps & 0xf00) >> 8;
- printk(KERN_ERR "scsi%d: (%d:%d), UNEXPECTED PHASE %s (%s)\n",
- host->host_no, pun, lun,
+ scmd_printk(KERN_ERR, SCp, "UNEXPECTED PHASE %s (%s)\n",
NCR_700_phase[i],
sbcl_to_string(NCR_700_readb(host, SBCL_REG)));
- printk(KERN_ERR " len = %d, cmd =", SCp->cmd_len);
+ scmd_printk(KERN_ERR, SCp, " len = %d, cmd =",
+ SCp->cmd_len);
scsi_print_command(SCp);
NCR_700_internal_bus_reset(host);
@@ -1115,14 +1120,14 @@ process_script_interrupt(__u32 dsps, __u32 dsp, struct scsi_cmnd *SCp,
}
slot = (struct NCR_700_command_slot *)SCp->host_scribble;
- DEBUG(("53c700: %d:%d:%d, reselection is tag %d, slot %p(%d)\n",
- host->host_no, SDp->id, SDp->lun,
- hostdata->msgin[2], slot, slot->tag));
+ DDEBUG(KERN_DEBUG, SDp,
+ "reselection is tag %d, slot %p(%d)\n",
+ hostdata->msgin[2], slot, slot->tag);
} else {
struct scsi_cmnd *SCp = scsi_find_tag(SDp, SCSI_NO_TAG);
if(unlikely(SCp == NULL)) {
- printk(KERN_ERR "scsi%d: (%d:%d) no saved request for untagged cmd\n",
- host->host_no, reselection_id, lun);
+ sdev_printk(KERN_ERR, SDp,
+ "no saved request for untagged cmd\n");
BUG();
}
slot = (struct NCR_700_command_slot *)SCp->host_scribble;
@@ -1422,7 +1427,7 @@ NCR_700_start_command(struct scsi_cmnd *SCp)
* If a contingent allegiance condition exists, the device
* will refuse all tags, so send the request sense as untagged
* */
- if((hostdata->tag_negotiated & (1<<SCp->device->id))
+ if((hostdata->tag_negotiated & (1<<scmd_id(SCp)))
&& (slot->tag != SCSI_NO_TAG && SCp->cmnd[0] != REQUEST_SENSE)) {
count += scsi_populate_tag_msg(SCp, &hostdata->msgout[count]);
}
@@ -1441,7 +1446,7 @@ NCR_700_start_command(struct scsi_cmnd *SCp)
script_patch_ID(hostdata->script,
- Device_ID, 1<<SCp->device->id);
+ Device_ID, 1<<scmd_id(SCp));
script_patch_32_abs(hostdata->script, CommandAddress,
slot->pCmd);
@@ -1764,17 +1769,15 @@ NCR_700_queuecommand(struct scsi_cmnd *SCp, void (*done)(struct scsi_cmnd *))
* - The blk layer sent and untagged command
*/
if(NCR_700_get_depth(SCp->device) != 0
- && (!(hostdata->tag_negotiated & (1<<SCp->device->id))
+ && (!(hostdata->tag_negotiated & (1<<scmd_id(SCp)))
|| !blk_rq_tagged(SCp->request))) {
- DEBUG((KERN_ERR "scsi%d (%d:%d) has non zero depth %d\n",
- SCp->device->host->host_no, SCp->device->id, SCp->device->lun,
- NCR_700_get_depth(SCp->device)));
+ CDEBUG(KERN_ERR, SCp, "has non zero depth %d\n",
+ NCR_700_get_depth(SCp->device));
return SCSI_MLQUEUE_DEVICE_BUSY;
}
if(NCR_700_get_depth(SCp->device) >= SCp->device->queue_depth) {
- DEBUG((KERN_ERR "scsi%d (%d:%d) has max tag depth %d\n",
- SCp->device->host->host_no, SCp->device->id, SCp->device->lun,
- NCR_700_get_depth(SCp->device)));
+ CDEBUG(KERN_ERR, SCp, "has max tag depth %d\n",
+ NCR_700_get_depth(SCp->device));
return SCSI_MLQUEUE_DEVICE_BUSY;
}
NCR_700_set_depth(SCp->device, NCR_700_get_depth(SCp->device) + 1);
@@ -1796,10 +1799,10 @@ NCR_700_queuecommand(struct scsi_cmnd *SCp, void (*done)(struct scsi_cmnd *))
scsi_print_command(SCp);
#endif
if(blk_rq_tagged(SCp->request)
- && (hostdata->tag_negotiated &(1<<SCp->device->id)) == 0
+ && (hostdata->tag_negotiated &(1<<scmd_id(SCp))) == 0
&& NCR_700_get_tag_neg_state(SCp->device) == NCR_700_START_TAG_NEGOTIATION) {
- printk(KERN_ERR "scsi%d: (%d:%d) Enabling Tag Command Queuing\n", SCp->device->host->host_no, SCp->device->id, SCp->device->lun);
- hostdata->tag_negotiated |= (1<<SCp->device->id);
+ scmd_printk(KERN_ERR, SCp, "Enabling Tag Command Queuing\n");
+ hostdata->tag_negotiated |= (1<<scmd_id(SCp));
NCR_700_set_tag_neg_state(SCp->device, NCR_700_DURING_TAG_NEGOTIATION);
}
@@ -1810,17 +1813,16 @@ NCR_700_queuecommand(struct scsi_cmnd *SCp, void (*done)(struct scsi_cmnd *))
* FIXME: This will royally screw up on multiple LUN devices
* */
if(!blk_rq_tagged(SCp->request)
- && (hostdata->tag_negotiated &(1<<SCp->device->id))) {
- printk(KERN_INFO "scsi%d: (%d:%d) Disabling Tag Command Queuing\n", SCp->device->host->host_no, SCp->device->id, SCp->device->lun);
- hostdata->tag_negotiated &= ~(1<<SCp->device->id);
+ && (hostdata->tag_negotiated &(1<<scmd_id(SCp)))) {
+ scmd_printk(KERN_INFO, SCp, "Disabling Tag Command Queuing\n");
+ hostdata->tag_negotiated &= ~(1<<scmd_id(SCp));
}
- if((hostdata->tag_negotiated &(1<<SCp->device->id))
+ if((hostdata->tag_negotiated &(1<<scmd_id(SCp)))
&& scsi_get_tag_type(SCp->device)) {
slot->tag = SCp->request->tag;
- DEBUG(("53c700 %d:%d:%d, sending out tag %d, slot %p\n",
- SCp->device->host->host_no, SCp->device->id, SCp->device->lun, slot->tag,
- slot));
+ CDEBUG(KERN_DEBUG, SCp, "sending out tag %d, slot %p\n",
+ slot->tag, slot);
} else {
slot->tag = SCSI_NO_TAG;
/* must populate current_cmnd for scsi_find_tag to work */
@@ -1920,8 +1922,8 @@ NCR_700_abort(struct scsi_cmnd * SCp)
{
struct NCR_700_command_slot *slot;
- printk(KERN_INFO "scsi%d (%d:%d) New error handler wants to abort command\n\t",
- SCp->device->host->host_no, SCp->device->id, SCp->device->lun);
+ scmd_printk(KERN_INFO, SCp,
+ "New error handler wants to abort command\n\t");
scsi_print_command(SCp);
slot = (struct NCR_700_command_slot *)SCp->host_scribble;
@@ -1954,8 +1956,8 @@ NCR_700_bus_reset(struct scsi_cmnd * SCp)
struct NCR_700_Host_Parameters *hostdata =
(struct NCR_700_Host_Parameters *)SCp->device->host->hostdata[0];
- printk(KERN_INFO "scsi%d (%d:%d) New error handler wants BUS reset, cmd %p\n\t",
- SCp->device->host->host_no, SCp->device->id, SCp->device->lun, SCp);
+ scmd_printk(KERN_INFO, SCp,
+ "New error handler wants BUS reset, cmd %p\n\t", SCp);
scsi_print_command(SCp);
/* In theory, eh_complete should always be null because the
@@ -1987,8 +1989,7 @@ NCR_700_bus_reset(struct scsi_cmnd * SCp)
STATIC int
NCR_700_host_reset(struct scsi_cmnd * SCp)
{
- printk(KERN_INFO "scsi%d (%d:%d) New error handler wants HOST reset\n\t",
- SCp->device->host->host_no, SCp->device->id, SCp->device->lun);
+ scmd_printk(KERN_INFO, SCp, "New error handler wants HOST reset\n\t");
scsi_print_command(SCp);
spin_lock_irq(SCp->device->host->host_lock);
@@ -2110,7 +2111,7 @@ static int NCR_700_change_queue_type(struct scsi_device *SDp, int tag_type)
/* shift back to the default unqueued number of commands
* (the user can still raise this) */
scsi_deactivate_tcq(SDp, SDp->host->cmd_per_lun);
- hostdata->tag_negotiated &= ~(1 << SDp->id);
+ hostdata->tag_negotiated &= ~(1 << sdev_id(SDp));
} else {
/* Here, we cleared the negotiation flag above, so this
* will force the driver to renegotiate */
diff --git a/drivers/scsi/53c700.h b/drivers/scsi/53c700.h
index e86012cf6ab7..362d78483d09 100644
--- a/drivers/scsi/53c700.h
+++ b/drivers/scsi/53c700.h
@@ -22,8 +22,14 @@
#ifdef NCR_700_DEBUG
#define DEBUG(x) printk x
+#define DDEBUG(prefix, sdev, fmt, a...) \
+ sdev_printk(prefix, sdev, fmt, ##a)
+#define CDEBUG(prefix, scmd, fmt, a...) \
+ scmd_printk(prefix, scmd, fmt, ##a)
#else
-#define DEBUG(x)
+#define DEBUG(x) do {} while (0)
+#define DDEBUG(prefix, scmd, fmt, a...) do {} while (0)
+#define CDEBUG(prefix, scmd, fmt, a...) do {} while (0)
#endif
/* The number of available command slots */
diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig
index 3ee9b8b33be0..afeca325b4dc 100644
--- a/drivers/scsi/Kconfig
+++ b/drivers/scsi/Kconfig
@@ -229,7 +229,7 @@ config SCSI_FC_ATTRS
config SCSI_ISCSI_ATTRS
tristate "iSCSI Transport Attributes"
- depends on SCSI
+ depends on SCSI && NET
help
If you wish to export transport-specific information about
each attached iSCSI device to sysfs, say Y.
@@ -247,6 +247,30 @@ endmenu
menu "SCSI low-level drivers"
depends on SCSI!=n
+config ISCSI_TCP
+ tristate "iSCSI Initiator over TCP/IP"
+ depends on SCSI && INET
+ select CRYPTO
+ select CRYPTO_MD5
+ select CRYPTO_CRC32C
+ select SCSI_ISCSI_ATTRS
+ help
+ The iSCSI Driver provides a host with the ability to access storage
+ through an IP network. The driver uses the iSCSI protocol to transport
+ SCSI requests and responses over a TCP/IP network between the host
+ (the "initiator") and "targets". Architecturally, the iSCSI driver
+ combines with the host's TCP/IP stack, network drivers, and Network
+ Interface Card (NIC) to provide the same functions as a SCSI or a
+ Fibre Channel (FC) adapter driver with a Host Bus Adapter (HBA).
+
+ To compile this driver as a module, choose M here: the
+ module will be called iscsi_tcp.
+
+ The userspace component needed to initialize the driver, documentation,
+ and sample configuration files can be found here:
+
+ http://linux-iscsi.sf.net
+
config SGIWD93_SCSI
tristate "SGI WD93C93 SCSI Driver"
depends on SGI_IP22 && SCSI
@@ -489,11 +513,11 @@ config SCSI_SATA_NV
If unsure, say N.
-config SCSI_SATA_PROMISE
- tristate "Promise SATA TX2/TX4 support"
+config SCSI_PDC_ADMA
+ tristate "Pacific Digital ADMA support"
depends on SCSI_SATA && PCI
help
- This option enables support for Promise Serial ATA TX2/TX4.
+ This option enables support for Pacific Digital ADMA controllers
If unsure, say N.
@@ -505,6 +529,14 @@ config SCSI_SATA_QSTOR
If unsure, say N.
+config SCSI_SATA_PROMISE
+ tristate "Promise SATA TX2/TX4 support"
+ depends on SCSI_SATA && PCI
+ help
+ This option enables support for Promise Serial ATA TX2/TX4.
+
+ If unsure, say N.
+
config SCSI_SATA_SX4
tristate "Promise SATA SX4 support"
depends on SCSI_SATA && PCI && EXPERIMENTAL
@@ -521,6 +553,14 @@ config SCSI_SATA_SIL
If unsure, say N.
+config SCSI_SATA_SIL24
+ tristate "Silicon Image 3124/3132 SATA support"
+ depends on SCSI_SATA && PCI && EXPERIMENTAL
+ help
+ This option enables support for Silicon Image 3124/3132 Serial ATA.
+
+ If unsure, say N.
+
config SCSI_SATA_SIS
tristate "SiS 964/180 SATA support"
depends on SCSI_SATA && PCI && EXPERIMENTAL
@@ -580,19 +620,6 @@ config SCSI_OMIT_FLASHPOINT
substantial, so users of MultiMaster Host Adapters may wish to omit
it.
-#
-# This is marked broken because it uses over 4kB of stack in
-# just two routines:
-# 2076 CpqTsProcessIMQEntry
-# 2052 PeekIMQEntry
-#
-config SCSI_CPQFCTS
- tristate "Compaq Fibre Channel 64-bit/66Mhz HBA support"
- depends on PCI && SCSI && BROKEN
- help
- Say Y here to compile in support for the Compaq StorageWorks Fibre
- Channel 64-bit/66Mhz Host Bus Adapter.
-
config SCSI_DMX3191D
tristate "DMX3191D SCSI support"
depends on PCI && SCSI
diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile
index 48529d180ca8..b88b8c455598 100644
--- a/drivers/scsi/Makefile
+++ b/drivers/scsi/Makefile
@@ -33,6 +33,7 @@ obj-$(CONFIG_SCSI_FC_ATTRS) += scsi_transport_fc.o
obj-$(CONFIG_SCSI_ISCSI_ATTRS) += scsi_transport_iscsi.o
obj-$(CONFIG_SCSI_SAS_ATTRS) += scsi_transport_sas.o
+obj-$(CONFIG_ISCSI_TCP) += iscsi_tcp.o
obj-$(CONFIG_SCSI_AMIGA7XX) += amiga7xx.o 53c7xx.o
obj-$(CONFIG_A3000_SCSI) += a3000.o wd33c93.o
obj-$(CONFIG_A2091_SCSI) += a2091.o wd33c93.o
@@ -119,7 +120,6 @@ obj-$(CONFIG_JAZZ_ESP) += NCR53C9x.o jazz_esp.o
obj-$(CONFIG_SUN3X_ESP) += NCR53C9x.o sun3x_esp.o
obj-$(CONFIG_SCSI_DEBUG) += scsi_debug.o
obj-$(CONFIG_SCSI_FCAL) += fcal.o
-obj-$(CONFIG_SCSI_CPQFCTS) += cpqfc.o
obj-$(CONFIG_SCSI_LASI700) += 53c700.o lasi700.o
obj-$(CONFIG_SCSI_NSP32) += nsp32.o
obj-$(CONFIG_SCSI_IPR) += ipr.o
@@ -130,6 +130,7 @@ obj-$(CONFIG_SCSI_ATA_PIIX) += libata.o ata_piix.o
obj-$(CONFIG_SCSI_SATA_PROMISE) += libata.o sata_promise.o
obj-$(CONFIG_SCSI_SATA_QSTOR) += libata.o sata_qstor.o
obj-$(CONFIG_SCSI_SATA_SIL) += libata.o sata_sil.o
+obj-$(CONFIG_SCSI_SATA_SIL24) += libata.o sata_sil24.o
obj-$(CONFIG_SCSI_SATA_VIA) += libata.o sata_via.o
obj-$(CONFIG_SCSI_SATA_VITESSE) += libata.o sata_vsc.o
obj-$(CONFIG_SCSI_SATA_SIS) += libata.o sata_sis.o
@@ -137,6 +138,7 @@ obj-$(CONFIG_SCSI_SATA_SX4) += libata.o sata_sx4.o
obj-$(CONFIG_SCSI_SATA_NV) += libata.o sata_nv.o
obj-$(CONFIG_SCSI_SATA_ULI) += libata.o sata_uli.o
obj-$(CONFIG_SCSI_SATA_MV) += libata.o sata_mv.o
+obj-$(CONFIG_SCSI_PDC_ADMA) += libata.o pdc_adma.o
obj-$(CONFIG_ARM) += arm/
@@ -162,8 +164,6 @@ ncr53c8xx-flags-$(CONFIG_SCSI_ZALON) \
CFLAGS_ncr53c8xx.o := $(ncr53c8xx-flags-y) $(ncr53c8xx-flags-m)
zalon7xx-objs := zalon.o ncr53c8xx.o
NCR_Q720_mod-objs := NCR_Q720.o ncr53c8xx.o
-cpqfc-objs := cpqfcTSinit.o cpqfcTScontrol.o cpqfcTSi2c.o \
- cpqfcTSworker.o cpqfcTStrigger.o
libata-objs := libata-core.o libata-scsi.o
# Files generated that shall be removed upon make clean
diff --git a/drivers/scsi/NCR5380.c b/drivers/scsi/NCR5380.c
index 23392ae7df8b..cba9655d0f14 100644
--- a/drivers/scsi/NCR5380.c
+++ b/drivers/scsi/NCR5380.c
@@ -606,10 +606,7 @@ static int __init NCR5380_probe_irq(struct Scsi_Host *instance, int possible)
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_DATA | ICR_ASSERT_SEL);
while (probe_irq == SCSI_IRQ_NONE && time_before(jiffies, timeout))
- {
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(1);
- }
+ schedule_timeout_uninterruptible(1);
NCR5380_write(SELECT_ENABLE_REG, 0);
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
@@ -1247,13 +1244,13 @@ static void collect_stats(struct NCR5380_hostdata *hostdata, Scsi_Cmnd * cmd)
case WRITE:
case WRITE_6:
case WRITE_10:
- hostdata->time_write[cmd->device->id] += (jiffies - hostdata->timebase);
+ hostdata->time_write[scmd_id(cmd)] += (jiffies - hostdata->timebase);
hostdata->pendingw--;
break;
case READ:
case READ_6:
case READ_10:
- hostdata->time_read[cmd->device->id] += (jiffies - hostdata->timebase);
+ hostdata->time_read[scmd_id(cmd)] += (jiffies - hostdata->timebase);
hostdata->pendingr--;
break;
}
@@ -1385,7 +1382,7 @@ static int NCR5380_select(struct Scsi_Host *instance, Scsi_Cmnd * cmd, int tag)
* the host and target ID's on the SCSI bus.
*/
- NCR5380_write(OUTPUT_DATA_REG, (hostdata->id_mask | (1 << cmd->device->id)));
+ NCR5380_write(OUTPUT_DATA_REG, (hostdata->id_mask | (1 << scmd_id(cmd))));
/*
* Raise ATN while SEL is true before BSY goes false from arbitration,
@@ -1430,7 +1427,7 @@ static int NCR5380_select(struct Scsi_Host *instance, Scsi_Cmnd * cmd, int tag)
udelay(1);
- dprintk(NDEBUG_SELECTION, ("scsi%d : selecting target %d\n", instance->host_no, cmd->device->id));
+ dprintk(NDEBUG_SELECTION, ("scsi%d : selecting target %d\n", instance->host_no, scmd_id(cmd)));
/*
* The SCSI specification calls for a 250 ms timeout for the actual
@@ -1483,7 +1480,7 @@ part2:
if (!(NCR5380_read(STATUS_REG) & SR_BSY)) {
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
- if (hostdata->targets_present & (1 << cmd->device->id)) {
+ if (hostdata->targets_present & (1 << scmd_id(cmd))) {
printk(KERN_DEBUG "scsi%d : weirdness\n", instance->host_no);
if (hostdata->restart_select)
printk(KERN_DEBUG "\trestart select\n");
@@ -1499,7 +1496,7 @@ part2:
NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
return 0;
}
- hostdata->targets_present |= (1 << cmd->device->id);
+ hostdata->targets_present |= (1 << scmd_id(cmd));
/*
* Since we followed the SCSI spec, and raised ATN while SEL
@@ -2190,7 +2187,8 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) {
* If the watchdog timer fires, all future accesses to this
* device will use the polled-IO.
*/
- printk("scsi%d : switching target %d lun %d to slow handshake\n", instance->host_no, cmd->device->id, cmd->device->lun);
+ scmd_printk(KERN_INFO, cmd,
+ "switching to slow handshake\n");
cmd->device->borken = 1;
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN);
sink = 1;
@@ -2429,9 +2427,11 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) {
scsi_print_msg(extended_msg);
printk("\n");
} else if (tmp != EXTENDED_MESSAGE)
- printk("scsi%d: rejecting unknown message %02x from target %d, lun %d\n", instance->host_no, tmp, cmd->device->id, cmd->device->lun);
+ scmd_printk(KERN_INFO, cmd,
+ "rejecting unknown message %02x\n",tmp);
else
- printk("scsi%d: rejecting unknown extended message code %02x, length %d from target %d, lun %d\n", instance->host_no, extended_msg[1], extended_msg[0], cmd->device->id, cmd->device->lun);
+ scmd_printk(KERN_INFO, cmd,
+ "rejecting unknown extended message code %02x, length %d\n", extended_msg[1], extended_msg[0]);
msgout = MESSAGE_REJECT;
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN);
diff --git a/drivers/scsi/NCR53C9x.c b/drivers/scsi/NCR53C9x.c
index 6ceabbd42a3d..26146a4b67b8 100644
--- a/drivers/scsi/NCR53C9x.c
+++ b/drivers/scsi/NCR53C9x.c
@@ -936,7 +936,7 @@ static void esp_release_dmabufs(struct NCR_ESP *esp, Scsi_Cmnd *sp)
static void esp_restore_pointers(struct NCR_ESP *esp, Scsi_Cmnd *sp)
{
- struct esp_pointers *ep = &esp->data_pointers[sp->device->id];
+ struct esp_pointers *ep = &esp->data_pointers[scmd_id(sp)];
sp->SCp.ptr = ep->saved_ptr;
sp->SCp.buffer = ep->saved_buffer;
@@ -946,7 +946,7 @@ static void esp_restore_pointers(struct NCR_ESP *esp, Scsi_Cmnd *sp)
static void esp_save_pointers(struct NCR_ESP *esp, Scsi_Cmnd *sp)
{
- struct esp_pointers *ep = &esp->data_pointers[sp->device->id];
+ struct esp_pointers *ep = &esp->data_pointers[scmd_id(sp)];
ep->saved_ptr = sp->SCp.ptr;
ep->saved_buffer = sp->SCp.buffer;
@@ -1693,13 +1693,13 @@ static inline void esp_connect(struct NCR_ESP *esp, struct ESP_regs *eregs,
if(esp->prev_soff != esp_dev->sync_max_offset ||
esp->prev_stp != esp_dev->sync_min_period ||
(esp->erev > esp100a &&
- esp->prev_cfg3 != esp->config3[sp->device->id])) {
+ esp->prev_cfg3 != esp->config3[scmd_id(sp)])) {
esp->prev_soff = esp_dev->sync_max_offset;
esp_write(eregs->esp_soff, esp->prev_soff);
esp->prev_stp = esp_dev->sync_min_period;
esp_write(eregs->esp_stp, esp->prev_stp);
if(esp->erev > esp100a) {
- esp->prev_cfg3 = esp->config3[sp->device->id];
+ esp->prev_cfg3 = esp->config3[scmd_id(sp)];
esp_write(eregs->esp_cfg3, esp->prev_cfg3);
}
}
@@ -2205,7 +2205,7 @@ static int esp_do_freebus(struct NCR_ESP *esp, struct ESP_regs *eregs)
if(SCptr->SCp.Status != GOOD &&
SCptr->SCp.Status != CONDITION_GOOD &&
- ((1<<SCptr->device->id) & esp->targets_present) &&
+ ((1<<scmd_id(SCptr)) & esp->targets_present) &&
esp_dev->sync && esp_dev->sync_max_offset) {
/* SCSI standard says that the synchronous capabilities
* should be renegotiated at this point. Most likely
@@ -2597,7 +2597,7 @@ static int esp_select_complete(struct NCR_ESP *esp, struct ESP_regs *eregs)
*/
if(esp->ireg == (ESP_INTR_FDONE | ESP_INTR_BSERV)) {
/* target speaks... */
- esp->targets_present |= (1<<SCptr->device->id);
+ esp->targets_present |= (1<<scmd_id(SCptr));
/* What if the target ignores the sdtr? */
if(esp->snip)
@@ -3064,7 +3064,7 @@ static int check_multibyte_msg(struct NCR_ESP *esp,
ESPSDTR(("soff=%2x stp=%2x cfg3=%2x\n",
esp_dev->sync_max_offset,
esp_dev->sync_min_period,
- esp->config3[SCptr->device->id]));
+ esp->config3[scmd_id(SCptr)]));
esp->snip = 0;
} else if(esp_dev->sync_max_offset) {
@@ -3621,7 +3621,7 @@ void esp_slave_destroy(Scsi_Device *SDptr)
{
struct NCR_ESP *esp = (struct NCR_ESP *) SDptr->host->hostdata;
- esp->targets_present &= ~(1 << SDptr->id);
+ esp->targets_present &= ~(1 << sdev_id(SDptr));
kfree(SDptr->hostdata);
SDptr->hostdata = NULL;
}
diff --git a/drivers/scsi/NCR53c406a.c b/drivers/scsi/NCR53c406a.c
index e1f2246ee7cd..135376992a57 100644
--- a/drivers/scsi/NCR53c406a.c
+++ b/drivers/scsi/NCR53c406a.c
@@ -710,7 +710,7 @@ static int NCR53c406a_queue(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *))
/* We are locked here already by the mid layer */
REG0;
- outb(SCpnt->device->id, DEST_ID); /* set destination */
+ outb(scmd_id(SCpnt), DEST_ID); /* set destination */
outb(FLUSH_FIFO, CMD_REG); /* reset the fifos */
for (i = 0; i < SCpnt->cmd_len; i++) {
diff --git a/drivers/scsi/a100u2w.c b/drivers/scsi/a100u2w.c
index c34403c30483..9f45ae1745da 100644
--- a/drivers/scsi/a100u2w.c
+++ b/drivers/scsi/a100u2w.c
@@ -923,7 +923,7 @@ static int inia100_device_reset(struct scsi_cmnd * SCpnt)
{ /* I need Host Control Block Information */
ORC_HCS *pHCB;
pHCB = (ORC_HCS *) SCpnt->device->host->hostdata;
- return orc_device_reset(pHCB, SCpnt, SCpnt->device->id);
+ return orc_device_reset(pHCB, SCpnt, scmd_id(SCpnt));
}
diff --git a/drivers/scsi/a2091.c b/drivers/scsi/a2091.c
index f7a1751e892d..30a14ba77a6a 100644
--- a/drivers/scsi/a2091.c
+++ b/drivers/scsi/a2091.c
@@ -2,7 +2,6 @@
#include <linux/mm.h>
#include <linux/blkdev.h>
#include <linux/sched.h>
-#include <linux/version.h>
#include <linux/init.h>
#include <linux/interrupt.h>
diff --git a/drivers/scsi/aacraid/README b/drivers/scsi/aacraid/README
index 4fa524687bc5..4193865d419c 100644
--- a/drivers/scsi/aacraid/README
+++ b/drivers/scsi/aacraid/README
@@ -57,7 +57,7 @@ Deanna Bonds (non-DASD support, PAE fibs and 64 bit,
(fixed 64bit and 64G memory model, changed confusing naming convention
where fibs that go to the hardware are consistently called hw_fibs and
not just fibs like the name of the driver tracking structure)
-Mark Salyzyn <Mark_Salyzyn@adaptec.com> Fixed panic issues and added some new product ids for upcoming hbas.
+Mark Salyzyn <Mark_Salyzyn@adaptec.com> Fixed panic issues and added some new product ids for upcoming hbas. Performance tuning, card failover and bug mitigations.
Original Driver
-------------------------
diff --git a/drivers/scsi/aacraid/TODO b/drivers/scsi/aacraid/TODO
index 2f148b4617dc..78dc863eff4f 100644
--- a/drivers/scsi/aacraid/TODO
+++ b/drivers/scsi/aacraid/TODO
@@ -1,4 +1,3 @@
o Testing
o More testing
-o Drop irq_mask, basically unused
o I/O size increase
diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c
index 93416f760e5a..2a128a156aa1 100644
--- a/drivers/scsi/aacraid/aachba.c
+++ b/drivers/scsi/aacraid/aachba.c
@@ -359,15 +359,6 @@ int aac_get_containers(struct aac_dev *dev)
return status;
}
-static void aac_io_done(struct scsi_cmnd * scsicmd)
-{
- unsigned long cpu_flags;
- struct Scsi_Host *host = scsicmd->device->host;
- spin_lock_irqsave(host->host_lock, cpu_flags);
- scsicmd->scsi_done(scsicmd);
- spin_unlock_irqrestore(host->host_lock, cpu_flags);
-}
-
static void aac_internal_transfer(struct scsi_cmnd *scsicmd, void *data, unsigned int offset, unsigned int len)
{
void *buf;
@@ -424,7 +415,7 @@ static void get_container_name_callback(void *context, struct fib * fibptr)
fib_complete(fibptr);
fib_free(fibptr);
- aac_io_done(scsicmd);
+ scsicmd->scsi_done(scsicmd);
}
/**
@@ -608,17 +599,43 @@ static char *container_types[] = {
* files instead of in OS dependant driver source.
*/
-static void setinqstr(int devtype, void *data, int tindex)
+static void setinqstr(struct aac_dev *dev, void *data, int tindex)
{
struct scsi_inq *str;
- struct aac_driver_ident *mp;
- mp = aac_get_driver_ident(devtype);
-
str = (struct scsi_inq *)(data); /* cast data to scsi inq block */
-
- inqstrcpy (mp->vname, str->vid);
- inqstrcpy (mp->model, str->pid); /* last six chars reserved for vol type */
+ memset(str, ' ', sizeof(*str));
+
+ if (dev->supplement_adapter_info.AdapterTypeText[0]) {
+ char * cp = dev->supplement_adapter_info.AdapterTypeText;
+ int c = sizeof(str->vid);
+ while (*cp && *cp != ' ' && --c)
+ ++cp;
+ c = *cp;
+ *cp = '\0';
+ inqstrcpy (dev->supplement_adapter_info.AdapterTypeText,
+ str->vid);
+ *cp = c;
+ while (*cp && *cp != ' ')
+ ++cp;
+ while (*cp == ' ')
+ ++cp;
+ /* last six chars reserved for vol type */
+ c = 0;
+ if (strlen(cp) > sizeof(str->pid)) {
+ c = cp[sizeof(str->pid)];
+ cp[sizeof(str->pid)] = '\0';
+ }
+ inqstrcpy (cp, str->pid);
+ if (c)
+ cp[sizeof(str->pid)] = c;
+ } else {
+ struct aac_driver_ident *mp = aac_get_driver_ident(dev->cardtype);
+
+ inqstrcpy (mp->vname, str->vid);
+ /* last six chars reserved for vol type */
+ inqstrcpy (mp->model, str->pid);
+ }
if (tindex < (sizeof(container_types)/sizeof(char *))){
char *findit = str->pid;
@@ -627,7 +644,9 @@ static void setinqstr(int devtype, void *data, int tindex)
/* RAID is superfluous in the context of a RAID device */
if (memcmp(findit-4, "RAID", 4) == 0)
*(findit -= 4) = ' ';
- inqstrcpy (container_types[tindex], findit + 1);
+ if (((findit - str->pid) + strlen(container_types[tindex]))
+ < (sizeof(str->pid) + sizeof(str->prl)))
+ inqstrcpy (container_types[tindex], findit + 1);
}
inqstrcpy ("V1.0", str->prl);
}
@@ -822,12 +841,12 @@ int aac_get_adapter_info(struct aac_dev* dev)
dev->dac_support = (dacmode!=0);
}
if(dev->dac_support != 0) {
- if (!pci_set_dma_mask(dev->pdev, 0xFFFFFFFFFFFFFFFFULL) &&
- !pci_set_consistent_dma_mask(dev->pdev, 0xFFFFFFFFFFFFFFFFULL)) {
+ if (!pci_set_dma_mask(dev->pdev, DMA_64BIT_MASK) &&
+ !pci_set_consistent_dma_mask(dev->pdev, DMA_64BIT_MASK)) {
printk(KERN_INFO"%s%d: 64 Bit DAC enabled\n",
dev->name, dev->id);
- } else if (!pci_set_dma_mask(dev->pdev, 0xFFFFFFFFULL) &&
- !pci_set_consistent_dma_mask(dev->pdev, 0xFFFFFFFFULL)) {
+ } else if (!pci_set_dma_mask(dev->pdev, DMA_32BIT_MASK) &&
+ !pci_set_consistent_dma_mask(dev->pdev, DMA_32BIT_MASK)) {
printk(KERN_INFO"%s%d: DMA mask set failed, 64 Bit DAC disabled\n",
dev->name, dev->id);
dev->dac_support = 0;
@@ -960,7 +979,7 @@ static void io_callback(void *context, struct fib * fibptr)
fib_complete(fibptr);
fib_free(fibptr);
- aac_io_done(scsicmd);
+ scsicmd->scsi_done(scsicmd);
}
static int aac_read(struct scsi_cmnd * scsicmd, int cid)
@@ -1139,7 +1158,7 @@ static int aac_read(struct scsi_cmnd * scsicmd, int cid)
* For some reason, the Fib didn't queue, return QUEUE_FULL
*/
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_TASK_SET_FULL;
- aac_io_done(scsicmd);
+ scsicmd->scsi_done(scsicmd);
fib_complete(cmd_fibcontext);
fib_free(cmd_fibcontext);
return 0;
@@ -1211,7 +1230,7 @@ static int aac_write(struct scsi_cmnd * scsicmd, int cid)
*/
if (!(cmd_fibcontext = fib_alloc(dev))) {
scsicmd->result = DID_ERROR << 16;
- aac_io_done(scsicmd);
+ scsicmd->scsi_done(scsicmd);
return 0;
}
fib_init(cmd_fibcontext);
@@ -1308,7 +1327,7 @@ static int aac_write(struct scsi_cmnd * scsicmd, int cid)
* For some reason, the Fib didn't queue, return QUEUE_FULL
*/
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_TASK_SET_FULL;
- aac_io_done(scsicmd);
+ scsicmd->scsi_done(scsicmd);
fib_complete(cmd_fibcontext);
fib_free(cmd_fibcontext);
@@ -1352,7 +1371,7 @@ static void synchronize_callback(void *context, struct fib *fibptr)
fib_complete(fibptr);
fib_free(fibptr);
- aac_io_done(cmd);
+ cmd->scsi_done(cmd);
}
static int aac_synchronize(struct scsi_cmnd *scsicmd, int cid)
@@ -1438,7 +1457,6 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
struct Scsi_Host *host = scsicmd->device->host;
struct aac_dev *dev = (struct aac_dev *)host->hostdata;
struct fsa_dev_info *fsa_dev_ptr = dev->fsa_dev;
- int cardtype = dev->cardtype;
int ret;
/*
@@ -1446,7 +1464,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
* Test does not apply to ID 16, the pseudo id for the controller
* itself.
*/
- if (scsicmd->device->id != host->this_id) {
+ if (scmd_id(scsicmd) != host->this_id) {
if ((scsicmd->device->channel == 0) ){
if( (scsicmd->device->id >= dev->maximum_num_containers) || (scsicmd->device->lun != 0)){
scsicmd->result = DID_NO_CONNECT << 16;
@@ -1541,15 +1559,15 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
* Set the Vendor, Product, and Revision Level
* see: <vendor>.c i.e. aac.c
*/
- if (scsicmd->device->id == host->this_id) {
- setinqstr(cardtype, (void *) (inq_data.inqd_vid), (sizeof(container_types)/sizeof(char *)));
+ if (scmd_id(scsicmd) == host->this_id) {
+ setinqstr(dev, (void *) (inq_data.inqd_vid), (sizeof(container_types)/sizeof(char *)));
inq_data.inqd_pdt = INQD_PDT_PROC; /* Processor device */
aac_internal_transfer(scsicmd, &inq_data, 0, sizeof(inq_data));
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
scsicmd->scsi_done(scsicmd);
return 0;
}
- setinqstr(cardtype, (void *) (inq_data.inqd_vid), fsa_dev_ptr[cid].type);
+ setinqstr(dev, (void *) (inq_data.inqd_vid), fsa_dev_ptr[cid].type);
inq_data.inqd_pdt = INQD_PDT_DA; /* Direct/random access device */
aac_internal_transfer(scsicmd, &inq_data, 0, sizeof(inq_data));
return aac_get_container_name(scsicmd, cid);
@@ -1931,7 +1949,7 @@ static void aac_srb_callback(void *context, struct fib * fibptr)
* the channel is 2
*/
} else if ((dev->raid_scsi_mode) &&
- (scsicmd->device->channel == 2)) {
+ (scmd_channel(scsicmd) == 2)) {
scsicmd->result = DID_OK << 16 |
COMMAND_COMPLETE << 8;
} else {
@@ -1975,7 +1993,7 @@ static void aac_srb_callback(void *context, struct fib * fibptr)
* the channel is 2
*/
} else if ((dev->raid_scsi_mode) &&
- (scsicmd->device->channel == 2)) {
+ (scmd_channel(scsicmd) == 2)) {
scsicmd->result = DID_OK << 16 |
COMMAND_COMPLETE << 8;
} else {
@@ -2070,7 +2088,7 @@ static void aac_srb_callback(void *context, struct fib * fibptr)
fib_complete(fibptr);
fib_free(fibptr);
- aac_io_done(scsicmd);
+ scsicmd->scsi_done(scsicmd);
}
/**
diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h
index d54b1cc88d0d..30fd8d6e3f31 100644
--- a/drivers/scsi/aacraid/aacraid.h
+++ b/drivers/scsi/aacraid/aacraid.h
@@ -481,6 +481,7 @@ enum aac_log_level {
#define FSAFS_NTC_FIB_CONTEXT 0x030c
struct aac_dev;
+struct fib;
struct adapter_ops
{
@@ -489,6 +490,7 @@ struct adapter_ops
void (*adapter_disable_int)(struct aac_dev *dev);
int (*adapter_sync_cmd)(struct aac_dev *dev, u32 command, u32 p1, u32 p2, u32 p3, u32 p4, u32 p5, u32 p6, u32 *status, u32 *r1, u32 *r2, u32 *r3, u32 *r4);
int (*adapter_check_health)(struct aac_dev *dev);
+ int (*adapter_send)(struct fib * fib);
};
/*
@@ -659,6 +661,10 @@ struct rx_mu_registers {
Status Register */
__le32 OIMR; /* 1334h | 34h | Outbound Interrupt
Mask Register */
+ __le32 reserved2; /* 1338h | 38h | Reserved */
+ __le32 reserved3; /* 133Ch | 3Ch | Reserved */
+ __le32 InboundQueue;/* 1340h | 40h | Inbound Queue Port relative to firmware */
+ __le32 OutboundQueue;/*1344h | 44h | Outbound Queue Port relative to firmware */
/* * Must access through ATU Inbound
Translation Window */
};
@@ -693,8 +699,8 @@ struct rx_inbound {
#define OutboundDoorbellReg MUnit.ODR
struct rx_registers {
- struct rx_mu_registers MUnit; /* 1300h - 1334h */
- __le32 reserved1[6]; /* 1338h - 134ch */
+ struct rx_mu_registers MUnit; /* 1300h - 1344h */
+ __le32 reserved1[2]; /* 1348h - 134ch */
struct rx_inbound IndexRegs;
};
@@ -711,8 +717,8 @@ struct rx_registers {
#define rkt_inbound rx_inbound
struct rkt_registers {
- struct rkt_mu_registers MUnit; /* 1300h - 1334h */
- __le32 reserved1[1010]; /* 1338h - 22fch */
+ struct rkt_mu_registers MUnit; /* 1300h - 1344h */
+ __le32 reserved1[1006]; /* 1348h - 22fch */
struct rkt_inbound IndexRegs; /* 2300h - */
};
@@ -721,8 +727,6 @@ struct rkt_registers {
#define rkt_writeb(AEP, CSR, value) writeb(value, &((AEP)->regs.rkt->CSR))
#define rkt_writel(AEP, CSR, value) writel(value, &((AEP)->regs.rkt->CSR))
-struct fib;
-
typedef void (*fib_callback)(void *ctxt, struct fib *fibctx);
struct aac_fib_context {
@@ -937,7 +941,6 @@ struct aac_dev
const char *name;
int id;
- u16 irq_mask;
/*
* negotiated FIB settings
*/
@@ -972,6 +975,7 @@ struct aac_dev
struct adapter_ops a_ops;
unsigned long fsrev; /* Main driver's revision number */
+ unsigned base_size; /* Size of mapped in region */
struct aac_init *init; /* Holds initialization info to communicate with adapter */
dma_addr_t init_pa; /* Holds physical address of the init struct */
@@ -992,6 +996,9 @@ struct aac_dev
/*
* The following is the device specific extension.
*/
+#if (!defined(AAC_MIN_FOOTPRINT_SIZE))
+# define AAC_MIN_FOOTPRINT_SIZE 8192
+#endif
union
{
struct sa_registers __iomem *sa;
@@ -1012,6 +1019,7 @@ struct aac_dev
u8 nondasd_support;
u8 dac_support;
u8 raid_scsi_mode;
+ u8 new_comm_interface;
/* macro side-effects BEWARE */
# define raw_io_interface \
init->InitStructRevision==cpu_to_le32(ADAPTER_INIT_STRUCT_REVISION_4)
@@ -1034,6 +1042,8 @@ struct aac_dev
#define aac_adapter_check_health(dev) \
(dev)->a_ops.adapter_check_health(dev)
+#define aac_adapter_send(fib) \
+ ((fib)->dev)->a_ops.adapter_send(fib)
#define FIB_CONTEXT_FLAG_TIMED_OUT (0x00000001)
@@ -1560,7 +1570,7 @@ struct fib_ioctl
struct revision
{
- __le32 compat;
+ u32 compat;
__le32 version;
__le32 build;
};
@@ -1779,6 +1789,7 @@ int aac_rkt_init(struct aac_dev *dev);
int aac_sa_init(struct aac_dev *dev);
unsigned int aac_response_normal(struct aac_queue * q);
unsigned int aac_command_normal(struct aac_queue * q);
+unsigned int aac_intr_normal(struct aac_dev * dev, u32 Index);
int aac_command_thread(struct aac_dev * dev);
int aac_close_fib_context(struct aac_dev * dev, struct aac_fib_context *fibctx);
int fib_adapter_complete(struct fib * fibptr, unsigned short size);
diff --git a/drivers/scsi/aacraid/commctrl.c b/drivers/scsi/aacraid/commctrl.c
index 71f1cad9b5f0..ef623bd965f5 100644
--- a/drivers/scsi/aacraid/commctrl.c
+++ b/drivers/scsi/aacraid/commctrl.c
@@ -408,7 +408,7 @@ static int check_revision(struct aac_dev *dev, void __user *arg)
char *driver_version = aac_driver_version;
u32 version;
- response.compat = cpu_to_le32(1);
+ response.compat = 1;
version = (simple_strtol(driver_version,
&driver_version, 10) << 24) | 0x00000400;
version += simple_strtol(driver_version + 1, &driver_version, 10) << 16;
@@ -574,7 +574,7 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg)
rcode = -ENOMEM;
goto cleanup;
}
- sg_user[i] = (void __user *)usg->sg[i].addr;
+ sg_user[i] = (void __user *)(long)usg->sg[i].addr;
sg_list[i] = p; // save so we can clean up later
sg_indx = i;
@@ -624,7 +624,7 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg)
rcode = -ENOMEM;
goto cleanup;
}
- sg_user[i] = (void __user *)upsg->sg[i].addr;
+ sg_user[i] = (void __user *)(long)upsg->sg[i].addr;
sg_list[i] = p; // save so we can clean up later
sg_indx = i;
diff --git a/drivers/scsi/aacraid/comminit.c b/drivers/scsi/aacraid/comminit.c
index 59a341b2aedc..82821d331c07 100644
--- a/drivers/scsi/aacraid/comminit.c
+++ b/drivers/scsi/aacraid/comminit.c
@@ -116,6 +116,10 @@ static int aac_alloc_comm(struct aac_dev *dev, void **commaddr, unsigned long co
}
init->InitFlags = 0;
+ if (dev->new_comm_interface) {
+ init->InitFlags = cpu_to_le32(INITFLAGS_NEW_COMM_SUPPORTED);
+ dprintk((KERN_WARNING"aacraid: New Comm Interface enabled\n"));
+ }
init->MaxIoCommands = cpu_to_le32(dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB);
init->MaxIoSize = cpu_to_le32(dev->scsi_host_ptr->max_sectors << 9);
init->MaxFibSize = cpu_to_le32(dev->max_fib_size);
@@ -315,12 +319,33 @@ struct aac_dev *aac_init_adapter(struct aac_dev *dev)
- sizeof(struct aac_fibhdr)
- sizeof(struct aac_write) + sizeof(struct sgentry))
/ sizeof(struct sgentry);
+ dev->new_comm_interface = 0;
dev->raw_io_64 = 0;
if ((!aac_adapter_sync_cmd(dev, GET_ADAPTER_PROPERTIES,
0, 0, 0, 0, 0, 0, status+0, status+1, status+2, NULL, NULL)) &&
(status[0] == 0x00000001)) {
if (status[1] & AAC_OPT_NEW_COMM_64)
dev->raw_io_64 = 1;
+ if (status[1] & AAC_OPT_NEW_COMM)
+ dev->new_comm_interface = dev->a_ops.adapter_send != 0;
+ if (dev->new_comm_interface && (status[2] > dev->base_size)) {
+ iounmap(dev->regs.sa);
+ dev->base_size = status[2];
+ dprintk((KERN_DEBUG "ioremap(%lx,%d)\n",
+ host->base, status[2]));
+ dev->regs.sa = ioremap(host->base, status[2]);
+ if (dev->regs.sa == NULL) {
+ /* remap failed, go back ... */
+ dev->new_comm_interface = 0;
+ dev->regs.sa = ioremap(host->base,
+ AAC_MIN_FOOTPRINT_SIZE);
+ if (dev->regs.sa == NULL) {
+ printk(KERN_WARNING
+ "aacraid: unable to map adapter.\n");
+ return NULL;
+ }
+ }
+ }
}
if ((!aac_adapter_sync_cmd(dev, GET_COMM_PREFERRED_SETTINGS,
0, 0, 0, 0, 0, 0,
diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c
index e4d543a474ae..723c0cea7c04 100644
--- a/drivers/scsi/aacraid/commsup.c
+++ b/drivers/scsi/aacraid/commsup.c
@@ -212,7 +212,7 @@ void fib_init(struct fib *fibptr)
hw_fib->header.StructType = FIB_MAGIC;
hw_fib->header.Size = cpu_to_le16(fibptr->dev->max_fib_size);
hw_fib->header.XferState = cpu_to_le32(HostOwned | FibInitialized | FibEmpty | FastResponseCapable);
- hw_fib->header.SenderFibAddress = cpu_to_le32(fibptr->hw_fib_pa);
+ hw_fib->header.SenderFibAddress = 0; /* Filled in later if needed */
hw_fib->header.ReceiverFibAddress = cpu_to_le32(fibptr->hw_fib_pa);
hw_fib->header.SenderSize = cpu_to_le16(fibptr->dev->max_fib_size);
}
@@ -380,9 +380,7 @@ static int aac_queue_get(struct aac_dev * dev, u32 * index, u32 qid, struct hw_f
int fib_send(u16 command, struct fib * fibptr, unsigned long size, int priority, int wait, int reply, fib_callback callback, void * callback_data)
{
- u32 index;
struct aac_dev * dev = fibptr->dev;
- unsigned long nointr = 0;
struct hw_fib * hw_fib = fibptr->hw_fib;
struct aac_queue * q;
unsigned long flags = 0;
@@ -417,7 +415,7 @@ int fib_send(u16 command, struct fib * fibptr, unsigned long size, int priority
* Map the fib into 32bits by using the fib number
*/
- hw_fib->header.SenderFibAddress = cpu_to_le32(((u32)(fibptr-dev->fibs)) << 1);
+ hw_fib->header.SenderFibAddress = cpu_to_le32(((u32)(fibptr - dev->fibs)) << 2);
hw_fib->header.SenderData = (u32)(fibptr - dev->fibs);
/*
* Set FIB state to indicate where it came from and if we want a
@@ -456,10 +454,10 @@ int fib_send(u16 command, struct fib * fibptr, unsigned long size, int priority
FIB_COUNTER_INCREMENT(aac_config.FibsSent);
- dprintk((KERN_DEBUG "fib_send: inserting a queue entry at index %d.\n",index));
dprintk((KERN_DEBUG "Fib contents:.\n"));
- dprintk((KERN_DEBUG " Command = %d.\n", hw_fib->header.Command));
- dprintk((KERN_DEBUG " XferState = %x.\n", hw_fib->header.XferState));
+ dprintk((KERN_DEBUG " Command = %d.\n", le32_to_cpu(hw_fib->header.Command)));
+ dprintk((KERN_DEBUG " SubCommand = %d.\n", le32_to_cpu(((struct aac_query_mount *)fib_data(fibptr))->command)));
+ dprintk((KERN_DEBUG " XferState = %x.\n", le32_to_cpu(hw_fib->header.XferState)));
dprintk((KERN_DEBUG " hw_fib va being sent=%p\n",fibptr->hw_fib));
dprintk((KERN_DEBUG " hw_fib pa being sent=%lx\n",(ulong)fibptr->hw_fib_pa));
dprintk((KERN_DEBUG " fib being sent=%p\n",fibptr));
@@ -469,14 +467,37 @@ int fib_send(u16 command, struct fib * fibptr, unsigned long size, int priority
if(wait)
spin_lock_irqsave(&fibptr->event_lock, flags);
spin_lock_irqsave(q->lock, qflags);
- aac_queue_get( dev, &index, AdapNormCmdQueue, hw_fib, 1, fibptr, &nointr);
-
- list_add_tail(&fibptr->queue, &q->pendingq);
- q->numpending++;
- *(q->headers.producer) = cpu_to_le32(index + 1);
- spin_unlock_irqrestore(q->lock, qflags);
- if (!(nointr & aac_config.irq_mod))
- aac_adapter_notify(dev, AdapNormCmdQueue);
+ if (dev->new_comm_interface) {
+ unsigned long count = 10000000L; /* 50 seconds */
+ list_add_tail(&fibptr->queue, &q->pendingq);
+ q->numpending++;
+ spin_unlock_irqrestore(q->lock, qflags);
+ while (aac_adapter_send(fibptr) != 0) {
+ if (--count == 0) {
+ if (wait)
+ spin_unlock_irqrestore(&fibptr->event_lock, flags);
+ spin_lock_irqsave(q->lock, qflags);
+ q->numpending--;
+ list_del(&fibptr->queue);
+ spin_unlock_irqrestore(q->lock, qflags);
+ return -ETIMEDOUT;
+ }
+ udelay(5);
+ }
+ } else {
+ u32 index;
+ unsigned long nointr = 0;
+ aac_queue_get( dev, &index, AdapNormCmdQueue, hw_fib, 1, fibptr, &nointr);
+
+ list_add_tail(&fibptr->queue, &q->pendingq);
+ q->numpending++;
+ *(q->headers.producer) = cpu_to_le32(index + 1);
+ spin_unlock_irqrestore(q->lock, qflags);
+ dprintk((KERN_DEBUG "fib_send: inserting a queue entry at index %d.\n",index));
+ if (!(nointr & aac_config.irq_mod))
+ aac_adapter_notify(dev, AdapNormCmdQueue);
+ }
+
/*
* If the caller wanted us to wait for response wait now.
*/
@@ -492,7 +513,6 @@ int fib_send(u16 command, struct fib * fibptr, unsigned long size, int priority
* hardware failure has occurred.
*/
unsigned long count = 36000000L; /* 3 minutes */
- unsigned long qflags;
while (down_trylock(&fibptr->event_wait)) {
if (--count == 0) {
spin_lock_irqsave(q->lock, qflags);
@@ -621,12 +641,16 @@ int fib_adapter_complete(struct fib * fibptr, unsigned short size)
unsigned long qflags;
if (hw_fib->header.XferState == 0) {
+ if (dev->new_comm_interface)
+ kfree (hw_fib);
return 0;
}
/*
* If we plan to do anything check the structure type first.
*/
if ( hw_fib->header.StructType != FIB_MAGIC ) {
+ if (dev->new_comm_interface)
+ kfree (hw_fib);
return -EINVAL;
}
/*
@@ -637,21 +661,25 @@ int fib_adapter_complete(struct fib * fibptr, unsigned short size)
* send the completed cdb to the adapter.
*/
if (hw_fib->header.XferState & cpu_to_le32(SentFromAdapter)) {
- u32 index;
- hw_fib->header.XferState |= cpu_to_le32(HostProcessed);
- if (size) {
- size += sizeof(struct aac_fibhdr);
- if (size > le16_to_cpu(hw_fib->header.SenderSize))
- return -EMSGSIZE;
- hw_fib->header.Size = cpu_to_le16(size);
+ if (dev->new_comm_interface) {
+ kfree (hw_fib);
+ } else {
+ u32 index;
+ hw_fib->header.XferState |= cpu_to_le32(HostProcessed);
+ if (size) {
+ size += sizeof(struct aac_fibhdr);
+ if (size > le16_to_cpu(hw_fib->header.SenderSize))
+ return -EMSGSIZE;
+ hw_fib->header.Size = cpu_to_le16(size);
+ }
+ q = &dev->queues->queue[AdapNormRespQueue];
+ spin_lock_irqsave(q->lock, qflags);
+ aac_queue_get(dev, &index, AdapNormRespQueue, hw_fib, 1, NULL, &nointr);
+ *(q->headers.producer) = cpu_to_le32(index + 1);
+ spin_unlock_irqrestore(q->lock, qflags);
+ if (!(nointr & (int)aac_config.irq_mod))
+ aac_adapter_notify(dev, AdapNormRespQueue);
}
- q = &dev->queues->queue[AdapNormRespQueue];
- spin_lock_irqsave(q->lock, qflags);
- aac_queue_get(dev, &index, AdapNormRespQueue, hw_fib, 1, NULL, &nointr);
- *(q->headers.producer) = cpu_to_le32(index + 1);
- spin_unlock_irqrestore(q->lock, qflags);
- if (!(nointr & (int)aac_config.irq_mod))
- aac_adapter_notify(dev, AdapNormRespQueue);
}
else
{
@@ -1136,7 +1164,7 @@ int aac_command_thread(struct aac_dev * dev)
kfree(hw_fib_pool);
hw_fib_pool = NULL;
}
- } else if (hw_fib_pool) {
+ } else {
kfree(hw_fib_pool);
hw_fib_pool = NULL;
}
@@ -1219,17 +1247,13 @@ int aac_command_thread(struct aac_dev * dev)
hw_fib_p = hw_fib_pool;
fib_p = fib_pool;
while (hw_fib_p < &hw_fib_pool[num]) {
- if (*hw_fib_p)
- kfree(*hw_fib_p);
- if (*fib_p)
- kfree(*fib_p);
+ kfree(*hw_fib_p);
+ kfree(*fib_p);
++fib_p;
++hw_fib_p;
}
- if (hw_fib_pool)
- kfree(hw_fib_pool);
- if (fib_pool)
- kfree(fib_pool);
+ kfree(hw_fib_pool);
+ kfree(fib_pool);
}
kfree(fib);
spin_lock_irqsave(dev->queues->queue[HostNormCmdQueue].lock, flags);
diff --git a/drivers/scsi/aacraid/dpcsup.c b/drivers/scsi/aacraid/dpcsup.c
index be2e98de9fab..439948ef8251 100644
--- a/drivers/scsi/aacraid/dpcsup.c
+++ b/drivers/scsi/aacraid/dpcsup.c
@@ -73,7 +73,7 @@ unsigned int aac_response_normal(struct aac_queue * q)
int fast;
u32 index = le32_to_cpu(entry->addr);
fast = index & 0x01;
- fib = &dev->fibs[index >> 1];
+ fib = &dev->fibs[index >> 2];
hwfib = fib->hw_fib;
aac_consumer_free(dev, q, HostNormRespQueue);
@@ -213,3 +213,116 @@ unsigned int aac_command_normal(struct aac_queue *q)
spin_unlock_irqrestore(q->lock, flags);
return 0;
}
+
+
+/**
+ * aac_intr_normal - Handle command replies
+ * @dev: Device
+ * @index: completion reference
+ *
+ * This DPC routine will be run when the adapter interrupts us to let us
+ * know there is a response on our normal priority queue. We will pull off
+ * all QE there are and wake up all the waiters before exiting.
+ */
+
+unsigned int aac_intr_normal(struct aac_dev * dev, u32 Index)
+{
+ u32 index = le32_to_cpu(Index);
+
+ dprintk((KERN_INFO "aac_intr_normal(%p,%x)\n", dev, Index));
+ if ((index & 0x00000002L)) {
+ struct hw_fib * hw_fib;
+ struct fib * fib;
+ struct aac_queue *q = &dev->queues->queue[HostNormCmdQueue];
+ unsigned long flags;
+
+ if (index == 0xFFFFFFFEL) /* Special Case */
+ return 0; /* Do nothing */
+ /*
+ * Allocate a FIB. For non queued stuff we can just use
+ * the stack so we are happy. We need a fib object in order to
+ * manage the linked lists.
+ */
+ if ((!dev->aif_thread)
+ || (!(fib = kmalloc(sizeof(struct fib),GFP_ATOMIC))))
+ return 1;
+ if (!(hw_fib = kmalloc(sizeof(struct hw_fib),GFP_ATOMIC))) {
+ kfree (fib);
+ return 1;
+ }
+ memset(hw_fib, 0, sizeof(struct hw_fib));
+ memcpy(hw_fib, (struct hw_fib *)(((unsigned long)(dev->regs.sa)) + (index & ~0x00000002L)), sizeof(struct hw_fib));
+ memset(fib, 0, sizeof(struct fib));
+ INIT_LIST_HEAD(&fib->fiblink);
+ fib->type = FSAFS_NTC_FIB_CONTEXT;
+ fib->size = sizeof(struct fib);
+ fib->hw_fib = hw_fib;
+ fib->data = hw_fib->data;
+ fib->dev = dev;
+
+ spin_lock_irqsave(q->lock, flags);
+ list_add_tail(&fib->fiblink, &q->cmdq);
+ wake_up_interruptible(&q->cmdready);
+ spin_unlock_irqrestore(q->lock, flags);
+ return 1;
+ } else {
+ int fast = index & 0x01;
+ struct fib * fib = &dev->fibs[index >> 2];
+ struct hw_fib * hwfib = fib->hw_fib;
+
+ /*
+ * Remove this fib from the Outstanding I/O queue.
+ * But only if it has not already been timed out.
+ *
+ * If the fib has been timed out already, then just
+ * continue. The caller has already been notified that
+ * the fib timed out.
+ */
+ if ((fib->flags & FIB_CONTEXT_FLAG_TIMED_OUT)) {
+ printk(KERN_WARNING "aacraid: FIB timeout (%x).\n", fib->flags);
+ printk(KERN_DEBUG"aacraid: hwfib=%p index=%i fib=%p\n",hwfib, hwfib->header.SenderData,fib);
+ return 0;
+ }
+
+ list_del(&fib->queue);
+ dev->queues->queue[AdapNormCmdQueue].numpending--;
+
+ if (fast) {
+ /*
+ * Doctor the fib
+ */
+ *(__le32 *)hwfib->data = cpu_to_le32(ST_OK);
+ hwfib->header.XferState |= cpu_to_le32(AdapterProcessed);
+ }
+
+ FIB_COUNTER_INCREMENT(aac_config.FibRecved);
+
+ if (hwfib->header.Command == cpu_to_le16(NuFileSystem))
+ {
+ u32 *pstatus = (u32 *)hwfib->data;
+ if (*pstatus & cpu_to_le32(0xffff0000))
+ *pstatus = cpu_to_le32(ST_OK);
+ }
+ if (hwfib->header.XferState & cpu_to_le32(NoResponseExpected | Async))
+ {
+ if (hwfib->header.XferState & cpu_to_le32(NoResponseExpected))
+ FIB_COUNTER_INCREMENT(aac_config.NoResponseRecved);
+ else
+ FIB_COUNTER_INCREMENT(aac_config.AsyncRecved);
+ /*
+ * NOTE: we cannot touch the fib after this
+ * call, because it may have been deallocated.
+ */
+ fib->callback(fib->callback_data, fib);
+ } else {
+ unsigned long flagv;
+ dprintk((KERN_INFO "event_wait up\n"));
+ spin_lock_irqsave(&fib->event_lock, flagv);
+ fib->done = 1;
+ up(&fib->event_wait);
+ spin_unlock_irqrestore(&fib->event_lock, flagv);
+ FIB_COUNTER_INCREMENT(aac_config.NormalRecved);
+ }
+ return 0;
+ }
+}
diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c
index a1f9ceef0ac9..ab383d1f59e2 100644
--- a/drivers/scsi/aacraid/linit.c
+++ b/drivers/scsi/aacraid/linit.c
@@ -752,8 +752,8 @@ static int __devinit aac_probe_one(struct pci_dev *pdev,
if (error)
goto out;
- if (pci_set_dma_mask(pdev, 0xFFFFFFFFULL) ||
- pci_set_consistent_dma_mask(pdev, 0xFFFFFFFFULL))
+ if (pci_set_dma_mask(pdev, DMA_32BIT_MASK) ||
+ pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK))
goto out;
/*
* If the quirk31 bit is set, the adapter needs adapter
@@ -788,8 +788,29 @@ static int __devinit aac_probe_one(struct pci_dev *pdev,
goto out_free_host;
spin_lock_init(&aac->fib_lock);
- if ((*aac_drivers[index].init)(aac))
+ /*
+ * Map in the registers from the adapter.
+ */
+ aac->base_size = AAC_MIN_FOOTPRINT_SIZE;
+ if ((aac->regs.sa = ioremap(
+ (unsigned long)aac->scsi_host_ptr->base, AAC_MIN_FOOTPRINT_SIZE))
+ == NULL) {
+ printk(KERN_WARNING "%s: unable to map adapter.\n",
+ AAC_DRIVERNAME);
goto out_free_fibs;
+ }
+ if ((*aac_drivers[index].init)(aac))
+ goto out_unmap;
+
+ /*
+ * Start any kernel threads needed
+ */
+ aac->thread_pid = kernel_thread((int (*)(void *))aac_command_thread,
+ aac, 0);
+ if (aac->thread_pid < 0) {
+ printk(KERN_ERR "aacraid: Unable to create command thread.\n");
+ goto out_deinit;
+ }
/*
* If we had set a smaller DMA mask earlier, set it to 4gig
@@ -797,9 +818,9 @@ static int __devinit aac_probe_one(struct pci_dev *pdev,
* address space.
*/
if (aac_drivers[index].quirks & AAC_QUIRK_31BIT)
- if (pci_set_dma_mask(pdev, 0xFFFFFFFFULL))
- goto out_free_fibs;
-
+ if (pci_set_dma_mask(pdev, DMA_32BIT_MASK))
+ goto out_deinit;
+
aac->maximum_num_channels = aac_drivers[index].channels;
error = aac_get_adapter_info(aac);
if (error < 0)
@@ -866,10 +887,11 @@ static int __devinit aac_probe_one(struct pci_dev *pdev,
aac_send_shutdown(aac);
aac_adapter_disable_int(aac);
+ free_irq(pdev->irq, aac);
+ out_unmap:
fib_map_free(aac);
pci_free_consistent(aac->pdev, aac->comm_size, aac->comm_addr, aac->comm_phys);
kfree(aac->queues);
- free_irq(pdev->irq, aac);
iounmap(aac->regs.sa);
out_free_fibs:
kfree(aac->fibs);
@@ -910,6 +932,7 @@ static void __devexit aac_remove_one(struct pci_dev *pdev)
iounmap(aac->regs.sa);
kfree(aac->fibs);
+ kfree(aac->fsa_dev);
list_del(&aac->entry);
scsi_host_put(shost);
diff --git a/drivers/scsi/aacraid/rkt.c b/drivers/scsi/aacraid/rkt.c
index 557287a0b80b..e9b775d6bec9 100644
--- a/drivers/scsi/aacraid/rkt.c
+++ b/drivers/scsi/aacraid/rkt.c
@@ -49,40 +49,57 @@
static irqreturn_t aac_rkt_intr(int irq, void *dev_id, struct pt_regs *regs)
{
struct aac_dev *dev = dev_id;
- unsigned long bellbits;
- u8 intstat, mask;
- intstat = rkt_readb(dev, MUnit.OISR);
- /*
- * Read mask and invert because drawbridge is reversed.
- * This allows us to only service interrupts that have
- * been enabled.
- */
- mask = ~(dev->OIMR);
- /* Check to see if this is our interrupt. If it isn't just return */
- if (intstat & mask)
- {
- bellbits = rkt_readl(dev, OutboundDoorbellReg);
- if (bellbits & DoorBellPrintfReady) {
- aac_printf(dev, rkt_readl(dev, IndexRegs.Mailbox[5]));
- rkt_writel(dev, MUnit.ODR,DoorBellPrintfReady);
- rkt_writel(dev, InboundDoorbellReg,DoorBellPrintfDone);
- }
- else if (bellbits & DoorBellAdapterNormCmdReady) {
- rkt_writel(dev, MUnit.ODR, DoorBellAdapterNormCmdReady);
- aac_command_normal(&dev->queues->queue[HostNormCmdQueue]);
- }
- else if (bellbits & DoorBellAdapterNormRespReady) {
- aac_response_normal(&dev->queues->queue[HostNormRespQueue]);
- rkt_writel(dev, MUnit.ODR,DoorBellAdapterNormRespReady);
- }
- else if (bellbits & DoorBellAdapterNormCmdNotFull) {
- rkt_writel(dev, MUnit.ODR, DoorBellAdapterNormCmdNotFull);
+
+ if (dev->new_comm_interface) {
+ u32 Index = rkt_readl(dev, MUnit.OutboundQueue);
+ if (Index == 0xFFFFFFFFL)
+ Index = rkt_readl(dev, MUnit.OutboundQueue);
+ if (Index != 0xFFFFFFFFL) {
+ do {
+ if (aac_intr_normal(dev, Index)) {
+ rkt_writel(dev, MUnit.OutboundQueue, Index);
+ rkt_writel(dev, MUnit.ODR, DoorBellAdapterNormRespReady);
+ }
+ Index = rkt_readl(dev, MUnit.OutboundQueue);
+ } while (Index != 0xFFFFFFFFL);
+ return IRQ_HANDLED;
}
- else if (bellbits & DoorBellAdapterNormRespNotFull) {
- rkt_writel(dev, MUnit.ODR, DoorBellAdapterNormCmdNotFull);
- rkt_writel(dev, MUnit.ODR, DoorBellAdapterNormRespNotFull);
+ } else {
+ unsigned long bellbits;
+ u8 intstat;
+ intstat = rkt_readb(dev, MUnit.OISR);
+ /*
+ * Read mask and invert because drawbridge is reversed.
+ * This allows us to only service interrupts that have
+ * been enabled.
+ * Check to see if this is our interrupt. If it isn't just return
+ */
+ if (intstat & ~(dev->OIMR))
+ {
+ bellbits = rkt_readl(dev, OutboundDoorbellReg);
+ if (bellbits & DoorBellPrintfReady) {
+ aac_printf(dev, rkt_readl (dev, IndexRegs.Mailbox[5]));
+ rkt_writel(dev, MUnit.ODR,DoorBellPrintfReady);
+ rkt_writel(dev, InboundDoorbellReg,DoorBellPrintfDone);
+ }
+ else if (bellbits & DoorBellAdapterNormCmdReady) {
+ rkt_writel(dev, MUnit.ODR, DoorBellAdapterNormCmdReady);
+ aac_command_normal(&dev->queues->queue[HostNormCmdQueue]);
+// rkt_writel(dev, MUnit.ODR, DoorBellAdapterNormCmdReady);
+ }
+ else if (bellbits & DoorBellAdapterNormRespReady) {
+ rkt_writel(dev, MUnit.ODR,DoorBellAdapterNormRespReady);
+ aac_response_normal(&dev->queues->queue[HostNormRespQueue]);
+ }
+ else if (bellbits & DoorBellAdapterNormCmdNotFull) {
+ rkt_writel(dev, MUnit.ODR, DoorBellAdapterNormCmdNotFull);
+ }
+ else if (bellbits & DoorBellAdapterNormRespNotFull) {
+ rkt_writel(dev, MUnit.ODR, DoorBellAdapterNormCmdNotFull);
+ rkt_writel(dev, MUnit.ODR, DoorBellAdapterNormRespNotFull);
+ }
+ return IRQ_HANDLED;
}
- return IRQ_HANDLED;
}
return IRQ_NONE;
}
@@ -166,14 +183,16 @@ static int rkt_sync_cmd(struct aac_dev *dev, u32 command,
/*
* Yield the processor in case we are slow
*/
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(1);
+ schedule_timeout_uninterruptible(1);
}
if (ok != 1) {
/*
* Restore interrupt mask even though we timed out
*/
- rkt_writeb(dev, MUnit.OIMR, dev->OIMR = 0xfb);
+ if (dev->new_comm_interface)
+ rkt_writeb(dev, MUnit.OIMR, dev->OIMR = 0xf7);
+ else
+ rkt_writeb(dev, MUnit.OIMR, dev->OIMR = 0xfb);
return -ETIMEDOUT;
}
/*
@@ -196,7 +215,10 @@ static int rkt_sync_cmd(struct aac_dev *dev, u32 command,
/*
* Restore interrupt mask
*/
- rkt_writeb(dev, MUnit.OIMR, dev->OIMR = 0xfb);
+ if (dev->new_comm_interface)
+ rkt_writeb(dev, MUnit.OIMR, dev->OIMR = 0xf7);
+ else
+ rkt_writeb(dev, MUnit.OIMR, dev->OIMR = 0xfb);
return 0;
}
@@ -268,15 +290,6 @@ static void aac_rkt_start_adapter(struct aac_dev *dev)
init = dev->init;
init->HostElapsedSeconds = cpu_to_le32(get_seconds());
- /*
- * First clear out all interrupts. Then enable the one's that we
- * can handle.
- */
- rkt_writeb(dev, MUnit.OIMR, 0xff);
- rkt_writel(dev, MUnit.ODR, 0xffffffff);
-// rkt_writeb(dev, MUnit.OIMR, ~(u8)OUTBOUND_DOORBELL_INTERRUPT_MASK);
- rkt_writeb(dev, MUnit.OIMR, dev->OIMR = 0xfb);
-
// We can only use a 32 bit address here
rkt_sync_cmd(dev, INIT_STRUCT_BASE_ADDRESS, (u32)(ulong)dev->init_pa,
0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL);
@@ -350,6 +363,39 @@ static int aac_rkt_check_health(struct aac_dev *dev)
}
/**
+ * aac_rkt_send
+ * @fib: fib to issue
+ *
+ * Will send a fib, returning 0 if successful.
+ */
+static int aac_rkt_send(struct fib * fib)
+{
+ u64 addr = fib->hw_fib_pa;
+ struct aac_dev *dev = fib->dev;
+ volatile void __iomem *device = dev->regs.rkt;
+ u32 Index;
+
+ dprintk((KERN_DEBUG "%p->aac_rkt_send(%p->%llx)\n", dev, fib, addr));
+ Index = rkt_readl(dev, MUnit.InboundQueue);
+ if (Index == 0xFFFFFFFFL)
+ Index = rkt_readl(dev, MUnit.InboundQueue);
+ dprintk((KERN_DEBUG "Index = 0x%x\n", Index));
+ if (Index == 0xFFFFFFFFL)
+ return Index;
+ device += Index;
+ dprintk((KERN_DEBUG "entry = %x %x %u\n", (u32)(addr & 0xffffffff),
+ (u32)(addr >> 32), (u32)le16_to_cpu(fib->hw_fib->header.Size)));
+ writel((u32)(addr & 0xffffffff), device);
+ device += sizeof(u32);
+ writel((u32)(addr >> 32), device);
+ device += sizeof(u32);
+ writel(le16_to_cpu(fib->hw_fib->header.Size), device);
+ rkt_writel(dev, MUnit.InboundQueue, Index);
+ dprintk((KERN_DEBUG "aac_rkt_send - return 0\n"));
+ return 0;
+}
+
+/**
* aac_rkt_init - initialize an i960 based AAC card
* @dev: device to configure
*
@@ -369,13 +415,8 @@ int aac_rkt_init(struct aac_dev *dev)
name = dev->name;
/*
- * Map in the registers from the adapter.
+ * Check to see if the board panic'd while booting.
*/
- if((dev->regs.rkt = ioremap((unsigned long)dev->scsi_host_ptr->base, 8192))==NULL)
- {
- printk(KERN_WARNING "aacraid: unable to map i960.\n" );
- goto error_iounmap;
- }
/*
* Check to see if the board failed any self tests.
*/
@@ -410,8 +451,7 @@ int aac_rkt_init(struct aac_dev *dev)
dev->name, instance, status);
goto error_iounmap;
}
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(1);
+ schedule_timeout_uninterruptible(1);
}
if (request_irq(dev->scsi_host_ptr->irq, aac_rkt_intr, SA_SHIRQ|SA_INTERRUPT, "aacraid", (void *)dev)<0)
{
@@ -426,6 +466,7 @@ int aac_rkt_init(struct aac_dev *dev)
dev->a_ops.adapter_notify = aac_rkt_notify_adapter;
dev->a_ops.adapter_sync_cmd = rkt_sync_cmd;
dev->a_ops.adapter_check_health = aac_rkt_check_health;
+ dev->a_ops.adapter_send = aac_rkt_send;
/*
* First clear out all interrupts. Then enable the one's that we
@@ -437,15 +478,24 @@ int aac_rkt_init(struct aac_dev *dev)
if (aac_init_adapter(dev) == NULL)
goto error_irq;
- /*
- * Start any kernel threads needed
- */
- dev->thread_pid = kernel_thread((int (*)(void *))aac_command_thread, dev, 0);
- if(dev->thread_pid < 0)
- {
- printk(KERN_ERR "aacraid: Unable to create rkt thread.\n");
- goto error_kfree;
- }
+ if (dev->new_comm_interface) {
+ /*
+ * FIB Setup has already been done, but we can minimize the
+ * damage by at least ensuring the OS never issues more
+ * commands than we can handle. The Rocket adapters currently
+ * can only handle 246 commands and 8 AIFs at the same time,
+ * and in fact do notify us accordingly if we negotiate the
+ * FIB size. The problem that causes us to add this check is
+ * to ensure that we do not overdo it with the adapter when a
+ * hard coded FIB override is being utilized. This special
+ * case warrants this half baked, but convenient, check here.
+ */
+ if (dev->scsi_host_ptr->can_queue > (246 - AAC_NUM_MGT_FIB)) {
+ dev->init->MaxIoCommands = cpu_to_le32(246);
+ dev->scsi_host_ptr->can_queue = 246 - AAC_NUM_MGT_FIB;
+ }
+ rkt_writeb(dev, MUnit.OIMR, dev->OIMR = 0xf7);
+ }
/*
* Tell the adapter that all is configured, and it can start
* accepting requests
@@ -453,15 +503,11 @@ int aac_rkt_init(struct aac_dev *dev)
aac_rkt_start_adapter(dev);
return 0;
-error_kfree:
- kfree(dev->queues);
-
error_irq:
rkt_writeb(dev, MUnit.OIMR, dev->OIMR = 0xff);
free_irq(dev->scsi_host_ptr->irq, (void *)dev);
error_iounmap:
- iounmap(dev->regs.rkt);
return -1;
}
diff --git a/drivers/scsi/aacraid/rx.c b/drivers/scsi/aacraid/rx.c
index a8459faf87ca..6998bc877dd6 100644
--- a/drivers/scsi/aacraid/rx.c
+++ b/drivers/scsi/aacraid/rx.c
@@ -49,40 +49,57 @@
static irqreturn_t aac_rx_intr(int irq, void *dev_id, struct pt_regs *regs)
{
struct aac_dev *dev = dev_id;
- unsigned long bellbits;
- u8 intstat, mask;
- intstat = rx_readb(dev, MUnit.OISR);
- /*
- * Read mask and invert because drawbridge is reversed.
- * This allows us to only service interrupts that have
- * been enabled.
- */
- mask = ~(dev->OIMR);
- /* Check to see if this is our interrupt. If it isn't just return */
- if (intstat & mask)
- {
- bellbits = rx_readl(dev, OutboundDoorbellReg);
- if (bellbits & DoorBellPrintfReady) {
- aac_printf(dev, rx_readl(dev, IndexRegs.Mailbox[5]));
- rx_writel(dev, MUnit.ODR,DoorBellPrintfReady);
- rx_writel(dev, InboundDoorbellReg,DoorBellPrintfDone);
- }
- else if (bellbits & DoorBellAdapterNormCmdReady) {
- rx_writel(dev, MUnit.ODR, DoorBellAdapterNormCmdReady);
- aac_command_normal(&dev->queues->queue[HostNormCmdQueue]);
- }
- else if (bellbits & DoorBellAdapterNormRespReady) {
- aac_response_normal(&dev->queues->queue[HostNormRespQueue]);
- rx_writel(dev, MUnit.ODR,DoorBellAdapterNormRespReady);
- }
- else if (bellbits & DoorBellAdapterNormCmdNotFull) {
- rx_writel(dev, MUnit.ODR, DoorBellAdapterNormCmdNotFull);
+
+ dprintk((KERN_DEBUG "aac_rx_intr(%d,%p,%p)\n", irq, dev_id, regs));
+ if (dev->new_comm_interface) {
+ u32 Index = rx_readl(dev, MUnit.OutboundQueue);
+ if (Index == 0xFFFFFFFFL)
+ Index = rx_readl(dev, MUnit.OutboundQueue);
+ if (Index != 0xFFFFFFFFL) {
+ do {
+ if (aac_intr_normal(dev, Index)) {
+ rx_writel(dev, MUnit.OutboundQueue, Index);
+ rx_writel(dev, MUnit.ODR, DoorBellAdapterNormRespReady);
+ }
+ Index = rx_readl(dev, MUnit.OutboundQueue);
+ } while (Index != 0xFFFFFFFFL);
+ return IRQ_HANDLED;
}
- else if (bellbits & DoorBellAdapterNormRespNotFull) {
- rx_writel(dev, MUnit.ODR, DoorBellAdapterNormCmdNotFull);
- rx_writel(dev, MUnit.ODR, DoorBellAdapterNormRespNotFull);
+ } else {
+ unsigned long bellbits;
+ u8 intstat;
+ intstat = rx_readb(dev, MUnit.OISR);
+ /*
+ * Read mask and invert because drawbridge is reversed.
+ * This allows us to only service interrupts that have
+ * been enabled.
+ * Check to see if this is our interrupt. If it isn't just return
+ */
+ if (intstat & ~(dev->OIMR))
+ {
+ bellbits = rx_readl(dev, OutboundDoorbellReg);
+ if (bellbits & DoorBellPrintfReady) {
+ aac_printf(dev, rx_readl (dev, IndexRegs.Mailbox[5]));
+ rx_writel(dev, MUnit.ODR,DoorBellPrintfReady);
+ rx_writel(dev, InboundDoorbellReg,DoorBellPrintfDone);
+ }
+ else if (bellbits & DoorBellAdapterNormCmdReady) {
+ rx_writel(dev, MUnit.ODR, DoorBellAdapterNormCmdReady);
+ aac_command_normal(&dev->queues->queue[HostNormCmdQueue]);
+ }
+ else if (bellbits & DoorBellAdapterNormRespReady) {
+ rx_writel(dev, MUnit.ODR,DoorBellAdapterNormRespReady);
+ aac_response_normal(&dev->queues->queue[HostNormRespQueue]);
+ }
+ else if (bellbits & DoorBellAdapterNormCmdNotFull) {
+ rx_writel(dev, MUnit.ODR, DoorBellAdapterNormCmdNotFull);
+ }
+ else if (bellbits & DoorBellAdapterNormRespNotFull) {
+ rx_writel(dev, MUnit.ODR, DoorBellAdapterNormCmdNotFull);
+ rx_writel(dev, MUnit.ODR, DoorBellAdapterNormRespNotFull);
+ }
+ return IRQ_HANDLED;
}
- return IRQ_HANDLED;
}
return IRQ_NONE;
}
@@ -166,14 +183,16 @@ static int rx_sync_cmd(struct aac_dev *dev, u32 command,
/*
* Yield the processor in case we are slow
*/
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(1);
+ schedule_timeout_uninterruptible(1);
}
if (ok != 1) {
/*
* Restore interrupt mask even though we timed out
*/
- rx_writeb(dev, MUnit.OIMR, dev->OIMR &= 0xfb);
+ if (dev->new_comm_interface)
+ rx_writeb(dev, MUnit.OIMR, dev->OIMR = 0xf7);
+ else
+ rx_writeb(dev, MUnit.OIMR, dev->OIMR = 0xfb);
return -ETIMEDOUT;
}
/*
@@ -196,7 +215,10 @@ static int rx_sync_cmd(struct aac_dev *dev, u32 command,
/*
* Restore interrupt mask
*/
- rx_writeb(dev, MUnit.OIMR, dev->OIMR &= 0xfb);
+ if (dev->new_comm_interface)
+ rx_writeb(dev, MUnit.OIMR, dev->OIMR = 0xf7);
+ else
+ rx_writeb(dev, MUnit.OIMR, dev->OIMR = 0xfb);
return 0;
}
@@ -267,15 +289,6 @@ static void aac_rx_start_adapter(struct aac_dev *dev)
init = dev->init;
init->HostElapsedSeconds = cpu_to_le32(get_seconds());
- /*
- * First clear out all interrupts. Then enable the one's that we
- * can handle.
- */
- rx_writeb(dev, MUnit.OIMR, 0xff);
- rx_writel(dev, MUnit.ODR, 0xffffffff);
-// rx_writeb(dev, MUnit.OIMR, ~(u8)OUTBOUND_DOORBELL_INTERRUPT_MASK);
- rx_writeb(dev, MUnit.OIMR, dev->OIMR = 0xfb);
-
// We can only use a 32 bit address here
rx_sync_cmd(dev, INIT_STRUCT_BASE_ADDRESS, (u32)(ulong)dev->init_pa,
0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL);
@@ -349,6 +362,39 @@ static int aac_rx_check_health(struct aac_dev *dev)
}
/**
+ * aac_rx_send
+ * @fib: fib to issue
+ *
+ * Will send a fib, returning 0 if successful.
+ */
+static int aac_rx_send(struct fib * fib)
+{
+ u64 addr = fib->hw_fib_pa;
+ struct aac_dev *dev = fib->dev;
+ volatile void __iomem *device = dev->regs.rx;
+ u32 Index;
+
+ dprintk((KERN_DEBUG "%p->aac_rx_send(%p->%llx)\n", dev, fib, addr));
+ Index = rx_readl(dev, MUnit.InboundQueue);
+ if (Index == 0xFFFFFFFFL)
+ Index = rx_readl(dev, MUnit.InboundQueue);
+ dprintk((KERN_DEBUG "Index = 0x%x\n", Index));
+ if (Index == 0xFFFFFFFFL)
+ return Index;
+ device += Index;
+ dprintk((KERN_DEBUG "entry = %x %x %u\n", (u32)(addr & 0xffffffff),
+ (u32)(addr >> 32), (u32)le16_to_cpu(fib->hw_fib->header.Size)));
+ writel((u32)(addr & 0xffffffff), device);
+ device += sizeof(u32);
+ writel((u32)(addr >> 32), device);
+ device += sizeof(u32);
+ writel(le16_to_cpu(fib->hw_fib->header.Size), device);
+ rx_writel(dev, MUnit.InboundQueue, Index);
+ dprintk((KERN_DEBUG "aac_rx_send - return 0\n"));
+ return 0;
+}
+
+/**
* aac_rx_init - initialize an i960 based AAC card
* @dev: device to configure
*
@@ -368,13 +414,8 @@ int aac_rx_init(struct aac_dev *dev)
name = dev->name;
/*
- * Map in the registers from the adapter.
+ * Check to see if the board panic'd while booting.
*/
- if((dev->regs.rx = ioremap((unsigned long)dev->scsi_host_ptr->base, 8192))==NULL)
- {
- printk(KERN_WARNING "aacraid: unable to map i960.\n" );
- return -1;
- }
/*
* Check to see if the board failed any self tests.
*/
@@ -410,8 +451,7 @@ int aac_rx_init(struct aac_dev *dev)
dev->name, instance, status);
goto error_iounmap;
}
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(1);
+ schedule_timeout_uninterruptible(1);
}
if (request_irq(dev->scsi_host_ptr->irq, aac_rx_intr, SA_SHIRQ|SA_INTERRUPT, "aacraid", (void *)dev)<0)
{
@@ -426,6 +466,7 @@ int aac_rx_init(struct aac_dev *dev)
dev->a_ops.adapter_notify = aac_rx_notify_adapter;
dev->a_ops.adapter_sync_cmd = rx_sync_cmd;
dev->a_ops.adapter_check_health = aac_rx_check_health;
+ dev->a_ops.adapter_send = aac_rx_send;
/*
* First clear out all interrupts. Then enable the one's that we
@@ -437,15 +478,9 @@ int aac_rx_init(struct aac_dev *dev)
if (aac_init_adapter(dev) == NULL)
goto error_irq;
- /*
- * Start any kernel threads needed
- */
- dev->thread_pid = kernel_thread((int (*)(void *))aac_command_thread, dev, 0);
- if(dev->thread_pid < 0)
- {
- printk(KERN_ERR "aacraid: Unable to create rx thread.\n");
- goto error_kfree;
- }
+ if (dev->new_comm_interface)
+ rx_writeb(dev, MUnit.OIMR, dev->OIMR = 0xf7);
+
/*
* Tell the adapter that all is configured, and it can start
* accepting requests
@@ -453,15 +488,11 @@ int aac_rx_init(struct aac_dev *dev)
aac_rx_start_adapter(dev);
return 0;
-error_kfree:
- kfree(dev->queues);
-
error_irq:
rx_writeb(dev, MUnit.OIMR, dev->OIMR = 0xff);
free_irq(dev->scsi_host_ptr->irq, (void *)dev);
error_iounmap:
- iounmap(dev->regs.rx);
return -1;
}
diff --git a/drivers/scsi/aacraid/sa.c b/drivers/scsi/aacraid/sa.c
index 3900abc5850d..466f05cfbf0c 100644
--- a/drivers/scsi/aacraid/sa.c
+++ b/drivers/scsi/aacraid/sa.c
@@ -189,8 +189,7 @@ static int sa_sync_cmd(struct aac_dev *dev, u32 command,
ok = 1;
break;
}
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(1);
+ schedule_timeout_uninterruptible(1);
}
if (ok != 1)
@@ -237,29 +236,16 @@ static void aac_sa_interrupt_adapter (struct aac_dev *dev)
static void aac_sa_start_adapter(struct aac_dev *dev)
{
- u32 ret;
struct aac_init *init;
/*
* Fill in the remaining pieces of the init.
*/
init = dev->init;
init->HostElapsedSeconds = cpu_to_le32(get_seconds());
-
- /*
- * Tell the adapter we are back and up and running so it will scan its command
- * queues and enable our interrupts
- */
- dev->irq_mask = (PrintfReady | DOORBELL_1 | DOORBELL_2 | DOORBELL_3 | DOORBELL_4);
- /*
- * First clear out all interrupts. Then enable the one's that
- * we can handle.
- */
- sa_writew(dev, SaDbCSR.PRISETIRQMASK, 0xffff);
- sa_writew(dev, SaDbCSR.PRICLEARIRQMASK, (PrintfReady | DOORBELL_1 | DOORBELL_2 | DOORBELL_3 | DOORBELL_4));
/* We can only use a 32 bit address here */
sa_sync_cmd(dev, INIT_STRUCT_BASE_ADDRESS,
(u32)(ulong)dev->init_pa, 0, 0, 0, 0, 0,
- &ret, NULL, NULL, NULL, NULL);
+ NULL, NULL, NULL, NULL, NULL);
}
/**
@@ -314,15 +300,6 @@ int aac_sa_init(struct aac_dev *dev)
name = dev->name;
/*
- * Map in the registers from the adapter.
- */
-
- if((dev->regs.sa = ioremap((unsigned long)dev->scsi_host_ptr->base, 8192))==NULL)
- {
- printk(KERN_WARNING "aacraid: unable to map ARM.\n" );
- goto error_iounmap;
- }
- /*
* Check to see if the board failed any self tests.
*/
if (sa_readl(dev, Mailbox7) & SELF_TEST_FAILED) {
@@ -347,8 +324,7 @@ int aac_sa_init(struct aac_dev *dev)
name, instance, status);
goto error_iounmap;
}
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(1);
+ schedule_timeout_uninterruptible(1);
}
if (request_irq(dev->scsi_host_ptr->irq, aac_sa_intr, SA_SHIRQ|SA_INTERRUPT, "aacraid", (void *)dev ) < 0) {
@@ -378,31 +354,17 @@ int aac_sa_init(struct aac_dev *dev)
goto error_irq;
/*
- * Start any kernel threads needed
- */
- dev->thread_pid = kernel_thread((int (*)(void *))aac_command_thread, dev, 0);
- if (dev->thread_pid < 0) {
- printk(KERN_ERR "aacraid: Unable to create command thread.\n");
- goto error_kfree;
- }
-
- /*
* Tell the adapter that all is configure, and it can start
* accepting requests
*/
aac_sa_start_adapter(dev);
return 0;
-
-error_kfree:
- kfree(dev->queues);
-
error_irq:
sa_writew(dev, SaDbCSR.PRISETIRQMASK, 0xffff);
free_irq(dev->scsi_host_ptr->irq, (void *)dev);
error_iounmap:
- iounmap(dev->regs.sa);
return -1;
}
diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c
index 37ec5411e325..f4cfb8f29620 100644
--- a/drivers/scsi/advansys.c
+++ b/drivers/scsi/advansys.c
@@ -5402,10 +5402,8 @@ advansys_detect(struct scsi_host_template *tpnt)
release_region(shp->io_port, boardp->asc_n_io_port);
if (ASC_WIDE_BOARD(boardp)) {
iounmap(boardp->ioremap_addr);
- if (boardp->orig_carrp) {
- kfree(boardp->orig_carrp);
- boardp->orig_carrp = NULL;
- }
+ kfree(boardp->orig_carrp);
+ boardp->orig_carrp = NULL;
if (boardp->orig_reqp) {
kfree(boardp->orig_reqp);
boardp->orig_reqp = boardp->adv_reqp = NULL;
@@ -5457,10 +5455,8 @@ advansys_release(struct Scsi_Host *shp)
adv_sgblk_t *sgp = NULL;
iounmap(boardp->ioremap_addr);
- if (boardp->orig_carrp) {
- kfree(boardp->orig_carrp);
- boardp->orig_carrp = NULL;
- }
+ kfree(boardp->orig_carrp);
+ boardp->orig_carrp = NULL;
if (boardp->orig_reqp) {
kfree(boardp->orig_reqp);
boardp->orig_reqp = boardp->adv_reqp = NULL;
diff --git a/drivers/scsi/aha152x.c b/drivers/scsi/aha152x.c
index 630b11575230..9b7caf504a56 100644
--- a/drivers/scsi/aha152x.c
+++ b/drivers/scsi/aha152x.c
@@ -2921,8 +2921,7 @@ static void disp_enintr(struct Scsi_Host *shpnt)
*/
static void show_command(Scsi_Cmnd *ptr)
{
- printk(KERN_DEBUG "0x%08x: target=%d; lun=%d; cmnd=(",
- (unsigned int) ptr, ptr->device->id, ptr->device->lun);
+ scmd_printk(KERN_DEBUG, ptr, "%p: cmnd=(", ptr);
__scsi_print_command(ptr->cmnd);
diff --git a/drivers/scsi/aha1542.c b/drivers/scsi/aha1542.c
index 9ec4641a6348..1b1adfb384cb 100644
--- a/drivers/scsi/aha1542.c
+++ b/drivers/scsi/aha1542.c
@@ -543,10 +543,8 @@ static void aha1542_intr_handle(struct Scsi_Host *shost, void *dev_id, struct pt
return;
}
my_done = SCtmp->scsi_done;
- if (SCtmp->host_scribble) {
- kfree(SCtmp->host_scribble);
- SCtmp->host_scribble = NULL;
- }
+ kfree(SCtmp->host_scribble);
+ SCtmp->host_scribble = NULL;
/* Fetch the sense data, and tuck it away, in the required slot. The
Adaptec automatically fetches it, and there is no guarantee that
we will still have it in the cdb when we come back */
@@ -1405,7 +1403,8 @@ static int aha1542_dev_reset(Scsi_Cmnd * SCpnt)
*/
aha1542_out(SCpnt->device->host->io_port, &ahacmd, 1);
- printk(KERN_WARNING "aha1542.c: Trying device reset for target %d\n", SCpnt->device->id);
+ scmd_printk(KERN_WARNING, SCpnt,
+ "Trying device reset for target\n");
return SUCCESS;
@@ -1431,10 +1430,8 @@ static int aha1542_dev_reset(Scsi_Cmnd * SCpnt)
HOSTDATA(SCpnt->host)->SCint[i]->target == SCpnt->target) {
Scsi_Cmnd *SCtmp;
SCtmp = HOSTDATA(SCpnt->host)->SCint[i];
- if (SCtmp->host_scribble) {
- kfree(SCtmp->host_scribble);
- SCtmp->host_scribble = NULL;
- }
+ kfree(SCtmp->host_scribble);
+ SCtmp->host_scribble = NULL;
HOSTDATA(SCpnt->host)->SCint[i] = NULL;
HOSTDATA(SCpnt->host)->mb[i].status = 0;
}
@@ -1494,10 +1491,8 @@ static int aha1542_bus_reset(Scsi_Cmnd * SCpnt)
*/
continue;
}
- if (SCtmp->host_scribble) {
- kfree(SCtmp->host_scribble);
- SCtmp->host_scribble = NULL;
- }
+ kfree(SCtmp->host_scribble);
+ SCtmp->host_scribble = NULL;
HOSTDATA(SCpnt->device->host)->SCint[i] = NULL;
HOSTDATA(SCpnt->device->host)->mb[i].status = 0;
}
@@ -1564,10 +1559,8 @@ static int aha1542_host_reset(Scsi_Cmnd * SCpnt)
*/
continue;
}
- if (SCtmp->host_scribble) {
- kfree(SCtmp->host_scribble);
- SCtmp->host_scribble = NULL;
- }
+ kfree(SCtmp->host_scribble);
+ SCtmp->host_scribble = NULL;
HOSTDATA(SCpnt->device->host)->SCint[i] = NULL;
HOSTDATA(SCpnt->device->host)->mb[i].status = 0;
}
@@ -1710,10 +1703,8 @@ static int aha1542_old_reset(Scsi_Cmnd * SCpnt, unsigned int reset_flags)
Scsi_Cmnd *SCtmp;
SCtmp = HOSTDATA(SCpnt->host)->SCint[i];
SCtmp->result = DID_RESET << 16;
- if (SCtmp->host_scribble) {
- kfree(SCtmp->host_scribble);
- SCtmp->host_scribble = NULL;
- }
+ kfree(SCtmp->host_scribble);
+ SCtmp->host_scribble = NULL;
printk(KERN_WARNING "Sending DID_RESET for target %d\n", SCpnt->target);
SCtmp->scsi_done(SCpnt);
@@ -1756,10 +1747,8 @@ fail:
Scsi_Cmnd *SCtmp;
SCtmp = HOSTDATA(SCpnt->host)->SCint[i];
SCtmp->result = DID_RESET << 16;
- if (SCtmp->host_scribble) {
- kfree(SCtmp->host_scribble);
- SCtmp->host_scribble = NULL;
- }
+ kfree(SCtmp->host_scribble);
+ SCtmp->host_scribble = NULL;
printk(KERN_WARNING "Sending DID_RESET for target %d\n", SCpnt->target);
SCtmp->scsi_done(SCpnt);
diff --git a/drivers/scsi/aha1740.c b/drivers/scsi/aha1740.c
index 73f33e716a0c..8f85dcc0e7fa 100644
--- a/drivers/scsi/aha1740.c
+++ b/drivers/scsi/aha1740.c
@@ -347,7 +347,7 @@ static int aha1740_queuecommand(Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *))
{
unchar direction;
unchar *cmd = (unchar *) SCpnt->cmnd;
- unchar target = SCpnt->device->id;
+ unchar target = scmd_id(SCpnt);
struct aha1740_hostdata *host = HOSTDATA(SCpnt->device->host);
unsigned long flags;
void *buff = SCpnt->request_buffer;
diff --git a/drivers/scsi/ahci.c b/drivers/scsi/ahci.c
index c2c8fa828e24..10c470e7d316 100644
--- a/drivers/scsi/ahci.c
+++ b/drivers/scsi/ahci.c
@@ -41,8 +41,9 @@
#include <linux/interrupt.h>
#include <linux/sched.h>
#include <linux/dma-mapping.h>
-#include "scsi.h"
+#include <linux/device.h>
#include <scsi/scsi_host.h>
+#include <scsi/scsi_cmnd.h>
#include <linux/libata.h>
#include <asm/io.h>
@@ -192,11 +193,10 @@ static void ahci_port_stop(struct ata_port *ap);
static void ahci_tf_read(struct ata_port *ap, struct ata_taskfile *tf);
static void ahci_qc_prep(struct ata_queued_cmd *qc);
static u8 ahci_check_status(struct ata_port *ap);
-static u8 ahci_check_err(struct ata_port *ap);
static inline int ahci_host_intr(struct ata_port *ap, struct ata_queued_cmd *qc);
static void ahci_remove_one (struct pci_dev *pdev);
-static Scsi_Host_Template ahci_sht = {
+static struct scsi_host_template ahci_sht = {
.module = THIS_MODULE,
.name = DRV_NAME,
.ioctl = ata_scsi_ioctl,
@@ -216,12 +216,11 @@ static Scsi_Host_Template ahci_sht = {
.ordered_flush = 1,
};
-static struct ata_port_operations ahci_ops = {
+static const struct ata_port_operations ahci_ops = {
.port_disable = ata_port_disable,
.check_status = ahci_check_status,
.check_altstatus = ahci_check_status,
- .check_err = ahci_check_err,
.dev_select = ata_noop_dev_select,
.tf_read = ahci_tf_read,
@@ -308,14 +307,22 @@ static int ahci_port_start(struct ata_port *ap)
void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
void *mem;
dma_addr_t mem_dma;
+ int rc;
pp = kmalloc(sizeof(*pp), GFP_KERNEL);
if (!pp)
return -ENOMEM;
memset(pp, 0, sizeof(*pp));
+ rc = ata_pad_alloc(ap, dev);
+ if (rc) {
+ kfree(pp);
+ return rc;
+ }
+
mem = dma_alloc_coherent(dev, AHCI_PORT_PRIV_DMA_SZ, &mem_dma, GFP_KERNEL);
if (!mem) {
+ ata_pad_free(ap, dev);
kfree(pp);
return -ENOMEM;
}
@@ -391,6 +398,7 @@ static void ahci_port_stop(struct ata_port *ap)
ap->private_data = NULL;
dma_free_coherent(dev, AHCI_PORT_PRIV_DMA_SZ,
pp->cmd_slot, pp->cmd_slot_dma);
+ ata_pad_free(ap, dev);
kfree(pp);
}
@@ -407,7 +415,7 @@ static u32 ahci_scr_read (struct ata_port *ap, unsigned int sc_reg_in)
return 0xffffffffU;
}
- return readl((void *) ap->ioaddr.scr_addr + (sc_reg * 4));
+ return readl((void __iomem *) ap->ioaddr.scr_addr + (sc_reg * 4));
}
@@ -425,7 +433,7 @@ static void ahci_scr_write (struct ata_port *ap, unsigned int sc_reg_in,
return;
}
- writel(val, (void *) ap->ioaddr.scr_addr + (sc_reg * 4));
+ writel(val, (void __iomem *) ap->ioaddr.scr_addr + (sc_reg * 4));
}
static void ahci_phy_reset(struct ata_port *ap)
@@ -453,18 +461,11 @@ static void ahci_phy_reset(struct ata_port *ap)
static u8 ahci_check_status(struct ata_port *ap)
{
- void *mmio = (void *) ap->ioaddr.cmd_addr;
+ void __iomem *mmio = (void __iomem *) ap->ioaddr.cmd_addr;
return readl(mmio + PORT_TFDATA) & 0xFF;
}
-static u8 ahci_check_err(struct ata_port *ap)
-{
- void *mmio = (void *) ap->ioaddr.cmd_addr;
-
- return (readl(mmio + PORT_TFDATA) >> 8) & 0xFF;
-}
-
static void ahci_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
{
struct ahci_port_priv *pp = ap->private_data;
@@ -476,23 +477,23 @@ static void ahci_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
static void ahci_fill_sg(struct ata_queued_cmd *qc)
{
struct ahci_port_priv *pp = qc->ap->private_data;
- unsigned int i;
+ struct scatterlist *sg;
+ struct ahci_sg *ahci_sg;
VPRINTK("ENTER\n");
/*
* Next, the S/G list.
*/
- for (i = 0; i < qc->n_elem; i++) {
- u32 sg_len;
- dma_addr_t addr;
-
- addr = sg_dma_address(&qc->sg[i]);
- sg_len = sg_dma_len(&qc->sg[i]);
-
- pp->cmd_tbl_sg[i].addr = cpu_to_le32(addr & 0xffffffff);
- pp->cmd_tbl_sg[i].addr_hi = cpu_to_le32((addr >> 16) >> 16);
- pp->cmd_tbl_sg[i].flags_size = cpu_to_le32(sg_len - 1);
+ ahci_sg = pp->cmd_tbl_sg;
+ ata_for_each_sg(sg, qc) {
+ dma_addr_t addr = sg_dma_address(sg);
+ u32 sg_len = sg_dma_len(sg);
+
+ ahci_sg->addr = cpu_to_le32(addr & 0xffffffff);
+ ahci_sg->addr_hi = cpu_to_le32((addr >> 16) >> 16);
+ ahci_sg->flags_size = cpu_to_le32(sg_len - 1);
+ ahci_sg++;
}
}
@@ -609,7 +610,7 @@ static void ahci_eng_timeout(struct ata_port *ap)
* not being called from the SCSI EH.
*/
qc->scsidone = scsi_finish_command;
- ata_qc_complete(qc, ATA_ERR);
+ ata_qc_complete(qc, AC_ERR_OTHER);
}
spin_unlock_irqrestore(&host_set->lock, flags);
@@ -638,7 +639,7 @@ static inline int ahci_host_intr(struct ata_port *ap, struct ata_queued_cmd *qc)
if (status & PORT_IRQ_FATAL) {
ahci_intr_error(ap, status);
if (qc)
- ata_qc_complete(qc, ATA_ERR);
+ ata_qc_complete(qc, AC_ERR_OTHER);
}
return 1;
@@ -672,17 +673,35 @@ static irqreturn_t ahci_interrupt (int irq, void *dev_instance, struct pt_regs *
for (i = 0; i < host_set->n_ports; i++) {
struct ata_port *ap;
- u32 tmp;
- VPRINTK("port %u\n", i);
+ if (!(irq_stat & (1 << i)))
+ continue;
+
ap = host_set->ports[i];
- tmp = irq_stat & (1 << i);
- if (tmp && ap) {
+ if (ap) {
struct ata_queued_cmd *qc;
qc = ata_qc_from_tag(ap, ap->active_tag);
- if (ahci_host_intr(ap, qc))
- irq_ack |= (1 << i);
+ if (!ahci_host_intr(ap, qc))
+ if (ata_ratelimit()) {
+ struct pci_dev *pdev =
+ to_pci_dev(ap->host_set->dev);
+ dev_printk(KERN_WARNING, &pdev->dev,
+ "unhandled interrupt on port %u\n",
+ i);
+ }
+
+ VPRINTK("port %u\n", i);
+ } else {
+ VPRINTK("port %u (no irq)\n", i);
+ if (ata_ratelimit()) {
+ struct pci_dev *pdev =
+ to_pci_dev(ap->host_set->dev);
+ dev_printk(KERN_WARNING, &pdev->dev,
+ "interrupt on disabled port %u\n", i);
+ }
}
+
+ irq_ack |= (1 << i);
}
if (irq_ack) {
@@ -750,8 +769,8 @@ static int ahci_host_init(struct ata_probe_ent *probe_ent)
tmp = readl(mmio + HOST_CTL);
if (tmp & HOST_RESET) {
- printk(KERN_ERR DRV_NAME "(%s): controller reset failed (0x%x)\n",
- pci_name(pdev), tmp);
+ dev_printk(KERN_ERR, &pdev->dev,
+ "controller reset failed (0x%x)\n", tmp);
return -EIO;
}
@@ -779,22 +798,22 @@ static int ahci_host_init(struct ata_probe_ent *probe_ent)
if (rc) {
rc = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
if (rc) {
- printk(KERN_ERR DRV_NAME "(%s): 64-bit DMA enable failed\n",
- pci_name(pdev));
+ dev_printk(KERN_ERR, &pdev->dev,
+ "64-bit DMA enable failed\n");
return rc;
}
}
} else {
rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
if (rc) {
- printk(KERN_ERR DRV_NAME "(%s): 32-bit DMA enable failed\n",
- pci_name(pdev));
+ dev_printk(KERN_ERR, &pdev->dev,
+ "32-bit DMA enable failed\n");
return rc;
}
rc = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
if (rc) {
- printk(KERN_ERR DRV_NAME "(%s): 32-bit consistent DMA enable failed\n",
- pci_name(pdev));
+ dev_printk(KERN_ERR, &pdev->dev,
+ "32-bit consistent DMA enable failed\n");
return rc;
}
}
@@ -897,10 +916,10 @@ static void ahci_print_info(struct ata_probe_ent *probe_ent)
else
scc_s = "unknown";
- printk(KERN_INFO DRV_NAME "(%s) AHCI %02x%02x.%02x%02x "
+ dev_printk(KERN_INFO, &pdev->dev,
+ "AHCI %02x%02x.%02x%02x "
"%u slots %u ports %s Gbps 0x%x impl %s mode\n"
,
- pci_name(pdev),
(vers >> 24) & 0xff,
(vers >> 16) & 0xff,
@@ -913,11 +932,11 @@ static void ahci_print_info(struct ata_probe_ent *probe_ent)
impl,
scc_s);
- printk(KERN_INFO DRV_NAME "(%s) flags: "
+ dev_printk(KERN_INFO, &pdev->dev,
+ "flags: "
"%s%s%s%s%s%s"
"%s%s%s%s%s%s%s\n"
,
- pci_name(pdev),
cap & (1 << 31) ? "64bit " : "",
cap & (1 << 30) ? "ncq " : "",
@@ -950,7 +969,7 @@ static int ahci_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
VPRINTK("ENTER\n");
if (!printed_version++)
- printk(KERN_DEBUG DRV_NAME " version " DRV_VERSION "\n");
+ dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
rc = pci_enable_device(pdev);
if (rc)
diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.c b/drivers/scsi/aic7xxx/aic79xx_osm.c
index 95c285cc83e4..cfb46c241b38 100644
--- a/drivers/scsi/aic7xxx/aic79xx_osm.c
+++ b/drivers/scsi/aic7xxx/aic79xx_osm.c
@@ -52,6 +52,7 @@ static struct scsi_transport_template *ahd_linux_transport_template = NULL;
#include <linux/mm.h> /* For fetching system memory size */
#include <linux/blkdev.h> /* For block_size() */
#include <linux/delay.h> /* For ssleep/msleep */
+#include <linux/device.h>
/*
* Bucket size for counting good commands in between bad ones.
@@ -397,7 +398,7 @@ ahd_linux_unmap_scb(struct ahd_softc *ahd, struct scb *scb)
/******************************** Macros **************************************/
#define BUILD_SCSIID(ahd, cmd) \
- ((((cmd)->device->id << TID_SHIFT) & TID) | (ahd)->our_id)
+ (((scmd_id(cmd) << TID_SHIFT) & TID) | (ahd)->our_id)
/*
* Return a string describing the driver.
@@ -565,7 +566,7 @@ ahd_linux_slave_configure(struct scsi_device *sdev)
ahd = *((struct ahd_softc **)sdev->host->hostdata);
if (bootverbose)
- printf("%s: Slave Configure %d\n", ahd_name(ahd), sdev->id);
+ sdev_printk(KERN_INFO, sdev, "Slave Configure\n");
ahd_linux_device_queue_depth(sdev);
@@ -684,7 +685,7 @@ ahd_linux_bus_reset(struct scsi_cmnd *cmd)
ahd_name(ahd), cmd);
#endif
ahd_lock(ahd, &s);
- found = ahd_reset_channel(ahd, cmd->device->channel + 'A',
+ found = ahd_reset_channel(ahd, scmd_channel(cmd) + 'A',
/*initiate reset*/TRUE);
ahd_unlock(ahd, &s);
@@ -2067,9 +2068,8 @@ ahd_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag)
wait = FALSE;
ahd = *(struct ahd_softc **)cmd->device->host->hostdata;
- printf("%s:%d:%d:%d: Attempting to queue a%s message:",
- ahd_name(ahd), cmd->device->channel,
- cmd->device->id, cmd->device->lun,
+ scmd_printk(KERN_INFO, cmd,
+ "Attempting to queue a%s message:",
flag == SCB_ABORT ? "n ABORT" : " TARGET RESET");
printf("CDB:");
@@ -2093,9 +2093,7 @@ ahd_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag)
* No target device for this command exists,
* so we must not still own the command.
*/
- printf("%s:%d:%d:%d: Is not an active device\n",
- ahd_name(ahd), cmd->device->channel, cmd->device->id,
- cmd->device->lun);
+ scmd_printk(KERN_INFO, cmd, "Is not an active device\n");
retval = SUCCESS;
goto no_cmd;
}
@@ -2112,8 +2110,9 @@ ahd_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag)
/* Any SCB for this device will do for a target reset */
LIST_FOREACH(pending_scb, &ahd->pending_scbs, pending_links) {
- if (ahd_match_scb(ahd, pending_scb, cmd->device->id,
- cmd->device->channel + 'A',
+ if (ahd_match_scb(ahd, pending_scb,
+ scmd_id(cmd),
+ scmd_channel(cmd) + 'A',
CAM_LUN_WILDCARD,
SCB_LIST_NULL, ROLE_INITIATOR) == 0)
break;
@@ -2121,9 +2120,7 @@ ahd_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag)
}
if (pending_scb == NULL) {
- printf("%s:%d:%d:%d: Command not found\n",
- ahd_name(ahd), cmd->device->channel, cmd->device->id,
- cmd->device->lun);
+ scmd_printk(KERN_INFO, cmd, "Command not found\n");
goto no_cmd;
}
@@ -2146,9 +2143,7 @@ ahd_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag)
paused = TRUE;
if ((pending_scb->flags & SCB_ACTIVE) == 0) {
- printf("%s:%d:%d:%d: Command already completed\n",
- ahd_name(ahd), cmd->device->channel, cmd->device->id,
- cmd->device->lun);
+ scmd_printk(KERN_INFO, cmd, "Command already completed\n");
goto no_cmd;
}
@@ -2204,7 +2199,7 @@ ahd_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag)
if (last_phase != P_BUSFREE
&& (SCB_GET_TAG(pending_scb) == active_scbptr
|| (flag == SCB_DEVICE_RESET
- && SCSIID_TARGET(ahd, saved_scsiid) == cmd->device->id))) {
+ && SCSIID_TARGET(ahd, saved_scsiid) == scmd_id(cmd)))) {
/*
* We're active on the bus, so assert ATN
@@ -2214,9 +2209,7 @@ ahd_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag)
pending_scb->flags |= SCB_RECOVERY_SCB|flag;
ahd_outb(ahd, MSG_OUT, HOST_MSG);
ahd_outb(ahd, SCSISIGO, last_phase|ATNO);
- printf("%s:%d:%d:%d: Device is active, asserting ATN\n",
- ahd_name(ahd), cmd->device->channel,
- cmd->device->id, cmd->device->lun);
+ scmd_printk(KERN_INFO, cmd, "Device is active, asserting ATN\n");
wait = TRUE;
} else if (disconnected) {
@@ -2277,9 +2270,7 @@ ahd_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag)
printf("Device is disconnected, re-queuing SCB\n");
wait = TRUE;
} else {
- printf("%s:%d:%d:%d: Unable to deliver message\n",
- ahd_name(ahd), cmd->device->channel,
- cmd->device->id, cmd->device->lun);
+ scmd_printk(KERN_INFO, cmd, "Unable to deliver message\n");
retval = FAILED;
goto done;
}
diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.h b/drivers/scsi/aic7xxx/aic79xx_osm.h
index 052c6619accc..bc44222d6cc3 100644
--- a/drivers/scsi/aic7xxx/aic79xx_osm.h
+++ b/drivers/scsi/aic7xxx/aic79xx_osm.h
@@ -49,7 +49,6 @@
#include <linux/ioport.h>
#include <linux/pci.h>
#include <linux/smp_lock.h>
-#include <linux/version.h>
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/slab.h>
diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.c b/drivers/scsi/aic7xxx/aic7xxx_osm.c
index 6ee1435d37fa..1861407422e4 100644
--- a/drivers/scsi/aic7xxx/aic7xxx_osm.c
+++ b/drivers/scsi/aic7xxx/aic7xxx_osm.c
@@ -641,7 +641,7 @@ ahc_linux_slave_configure(struct scsi_device *sdev)
ahc = *((struct ahc_softc **)sdev->host->hostdata);
if (bootverbose)
- printf("%s: Slave Configure %d\n", ahc_name(ahc), sdev->id);
+ sdev_printk(KERN_INFO, sdev, "Slave Configure\n");
ahc_linux_device_queue_depth(sdev);
@@ -686,7 +686,7 @@ ahc_linux_biosparam(struct scsi_device *sdev, struct block_device *bdev,
u_int channel;
ahc = *((struct ahc_softc **)sdev->host->hostdata);
- channel = sdev->channel;
+ channel = sdev_channel(sdev);
bh = scsi_bios_ptable(bdev);
if (bh) {
@@ -759,7 +759,7 @@ ahc_linux_bus_reset(struct scsi_cmnd *cmd)
ahc = *(struct ahc_softc **)cmd->device->host->hostdata;
ahc_lock(ahc, &flags);
- found = ahc_reset_channel(ahc, cmd->device->channel + 'A',
+ found = ahc_reset_channel(ahc, scmd_channel(cmd) + 'A',
/*initiate reset*/TRUE);
ahc_unlock(ahc, &flags);
@@ -2117,9 +2117,7 @@ ahc_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag)
wait = FALSE;
ahc = *(struct ahc_softc **)cmd->device->host->hostdata;
- printf("%s:%d:%d:%d: Attempting to queue a%s message\n",
- ahc_name(ahc), cmd->device->channel,
- cmd->device->id, cmd->device->lun,
+ scmd_printk(KERN_INFO, cmd, "Attempting to queue a%s message\n",
flag == SCB_ABORT ? "n ABORT" : " TARGET RESET");
printf("CDB:");
@@ -2174,8 +2172,8 @@ ahc_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag)
/* Any SCB for this device will do for a target reset */
LIST_FOREACH(pending_scb, &ahc->pending_scbs, pending_links) {
- if (ahc_match_scb(ahc, pending_scb, cmd->device->id,
- cmd->device->channel + 'A',
+ if (ahc_match_scb(ahc, pending_scb, scmd_id(cmd),
+ scmd_channel(cmd) + 'A',
CAM_LUN_WILDCARD,
SCB_LIST_NULL, ROLE_INITIATOR) == 0)
break;
@@ -2183,9 +2181,7 @@ ahc_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag)
}
if (pending_scb == NULL) {
- printf("%s:%d:%d:%d: Command not found\n",
- ahc_name(ahc), cmd->device->channel, cmd->device->id,
- cmd->device->lun);
+ scmd_printk(KERN_INFO, cmd, "Command not found\n");
goto no_cmd;
}
@@ -2207,9 +2203,7 @@ ahc_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag)
paused = TRUE;
if ((pending_scb->flags & SCB_ACTIVE) == 0) {
- printf("%s:%d:%d:%d: Command already completed\n",
- ahc_name(ahc), cmd->device->channel, cmd->device->id,
- cmd->device->lun);
+ scmd_printk(KERN_INFO, cmd, "Command already completed\n");
goto no_cmd;
}
@@ -2266,7 +2260,7 @@ ahc_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag)
if (last_phase != P_BUSFREE
&& (pending_scb->hscb->tag == active_scb_index
|| (flag == SCB_DEVICE_RESET
- && SCSIID_TARGET(ahc, saved_scsiid) == cmd->device->id))) {
+ && SCSIID_TARGET(ahc, saved_scsiid) == scmd_id(cmd)))) {
/*
* We're active on the bus, so assert ATN
@@ -2276,9 +2270,7 @@ ahc_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag)
pending_scb->flags |= SCB_RECOVERY_SCB|flag;
ahc_outb(ahc, MSG_OUT, HOST_MSG);
ahc_outb(ahc, SCSISIGO, last_phase|ATNO);
- printf("%s:%d:%d:%d: Device is active, asserting ATN\n",
- ahc_name(ahc), cmd->device->channel, cmd->device->id,
- cmd->device->lun);
+ scmd_printk(KERN_INFO, cmd, "Device is active, asserting ATN\n");
wait = TRUE;
} else if (disconnected) {
@@ -2344,9 +2336,7 @@ ahc_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag)
printf("Device is disconnected, re-queuing SCB\n");
wait = TRUE;
} else {
- printf("%s:%d:%d:%d: Unable to deliver message\n",
- ahc_name(ahc), cmd->device->channel, cmd->device->id,
- cmd->device->lun);
+ scmd_printk(KERN_INFO, cmd, "Unable to deliver message\n");
retval = FAILED;
goto done;
}
diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.h b/drivers/scsi/aic7xxx/aic7xxx_osm.h
index be9edbe26dbe..f2a95447142c 100644
--- a/drivers/scsi/aic7xxx/aic7xxx_osm.h
+++ b/drivers/scsi/aic7xxx/aic7xxx_osm.h
@@ -66,7 +66,6 @@
#include <linux/ioport.h>
#include <linux/pci.h>
#include <linux/smp_lock.h>
-#include <linux/version.h>
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/slab.h>
diff --git a/drivers/scsi/aic7xxx_old.c b/drivers/scsi/aic7xxx_old.c
index 52b72d7794f5..880e2d9ffe9b 100644
--- a/drivers/scsi/aic7xxx_old.c
+++ b/drivers/scsi/aic7xxx_old.c
@@ -8492,8 +8492,7 @@ aic7xxx_free(struct aic7xxx_host *p)
- scb_dma->dma_offset),
scb_dma->dma_address);
}
- if (p->scb_data->scb_array[i]->kmalloc_ptr != NULL)
- kfree(p->scb_data->scb_array[i]->kmalloc_ptr);
+ kfree(p->scb_data->scb_array[i]->kmalloc_ptr);
p->scb_data->scb_array[i] = NULL;
}
diff --git a/drivers/scsi/amiga7xx.c b/drivers/scsi/amiga7xx.c
index 5f13546d6392..dea8446f5360 100644
--- a/drivers/scsi/amiga7xx.c
+++ b/drivers/scsi/amiga7xx.c
@@ -11,7 +11,6 @@
#include <linux/mm.h>
#include <linux/blkdev.h>
#include <linux/sched.h>
-#include <linux/version.h>
#include <linux/config.h>
#include <linux/zorro.h>
#include <linux/stat.h>
diff --git a/drivers/scsi/arm/queue.c b/drivers/scsi/arm/queue.c
index e6d159270d29..b10750bb5c09 100644
--- a/drivers/scsi/arm/queue.c
+++ b/drivers/scsi/arm/queue.c
@@ -91,8 +91,7 @@ void queue_free (Queue_t *queue)
{
if (!list_empty(&queue->head))
printk(KERN_WARNING "freeing non-empty queue %p\n", queue);
- if (queue->alloc)
- kfree(queue->alloc);
+ kfree(queue->alloc);
}
diff --git a/drivers/scsi/arm/scsi.h b/drivers/scsi/arm/scsi.h
index 48e1c4d9738b..19937640e2e7 100644
--- a/drivers/scsi/arm/scsi.h
+++ b/drivers/scsi/arm/scsi.h
@@ -10,6 +10,8 @@
* Commonly used scsi driver functions.
*/
+#include <linux/scatterlist.h>
+
#define BELT_AND_BRACES
/*
@@ -22,9 +24,7 @@ static inline int copy_SCp_to_sg(struct scatterlist *sg, Scsi_Pointer *SCp, int
BUG_ON(bufs + 1 > max);
- sg->page = virt_to_page(SCp->ptr);
- sg->offset = offset_in_page(SCp->ptr);
- sg->length = SCp->this_residual;
+ sg_set_buf(sg, SCp->ptr, SCp->this_residual);
if (bufs)
memcpy(sg + 1, SCp->buffer + 1,
diff --git a/drivers/scsi/ata_piix.c b/drivers/scsi/ata_piix.c
index d71cef767cec..a1bd8d95623c 100644
--- a/drivers/scsi/ata_piix.c
+++ b/drivers/scsi/ata_piix.c
@@ -45,7 +45,7 @@
#include <linux/init.h>
#include <linux/blkdev.h>
#include <linux/delay.h>
-#include "scsi.h"
+#include <linux/device.h>
#include <scsi/scsi_host.h>
#include <linux/libata.h>
@@ -127,7 +127,7 @@ static struct pci_driver piix_pci_driver = {
.remove = ata_pci_remove_one,
};
-static Scsi_Host_Template piix_sht = {
+static struct scsi_host_template piix_sht = {
.module = THIS_MODULE,
.name = DRV_NAME,
.ioctl = ata_scsi_ioctl,
@@ -147,7 +147,7 @@ static Scsi_Host_Template piix_sht = {
.ordered_flush = 1,
};
-static struct ata_port_operations piix_pata_ops = {
+static const struct ata_port_operations piix_pata_ops = {
.port_disable = ata_port_disable,
.set_piomode = piix_set_piomode,
.set_dmamode = piix_set_dmamode,
@@ -177,7 +177,7 @@ static struct ata_port_operations piix_pata_ops = {
.host_stop = ata_host_stop,
};
-static struct ata_port_operations piix_sata_ops = {
+static const struct ata_port_operations piix_sata_ops = {
.port_disable = ata_port_disable,
.tf_load = ata_tf_load,
@@ -621,18 +621,19 @@ static int piix_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
{
static int printed_version;
struct ata_port_info *port_info[2];
- unsigned int combined = 0, n_ports = 1;
+ unsigned int combined = 0;
unsigned int pata_chan = 0, sata_chan = 0;
if (!printed_version++)
- printk(KERN_DEBUG DRV_NAME " version " DRV_VERSION "\n");
+ dev_printk(KERN_DEBUG, &pdev->dev,
+ "version " DRV_VERSION "\n");
/* no hotplugging support (FIXME) */
if (!in_module_init)
return -ENODEV;
port_info[0] = &piix_port_info[ent->driver_data];
- port_info[1] = NULL;
+ port_info[1] = &piix_port_info[ent->driver_data];
if (port_info[0]->host_flags & PIIX_FLAG_AHCI) {
u8 tmp;
@@ -670,12 +671,13 @@ static int piix_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
port_info[sata_chan] = &piix_port_info[ent->driver_data];
port_info[sata_chan]->host_flags |= ATA_FLAG_SLAVE_POSS;
port_info[pata_chan] = &piix_port_info[ich5_pata];
- n_ports++;
- printk(KERN_WARNING DRV_NAME ": combined mode detected\n");
+ dev_printk(KERN_WARNING, &pdev->dev,
+ "combined mode detected (p=%u, s=%u)\n",
+ pata_chan, sata_chan);
}
- return ata_pci_init_one(pdev, port_info, n_ports);
+ return ata_pci_init_one(pdev, port_info, 2);
}
static int __init piix_init(void)
diff --git a/drivers/scsi/atari_dma_emul.c b/drivers/scsi/atari_dma_emul.c
index 7026045527fd..8d5d2a5da961 100644
--- a/drivers/scsi/atari_dma_emul.c
+++ b/drivers/scsi/atari_dma_emul.c
@@ -19,6 +19,8 @@
* this code.
*/
+#include <linux/compiler.h>
+#include <asm/thread_info.h>
#include <asm/uaccess.h>
#define hades_dma_ctrl (*(unsigned char *) 0xffff8717)
diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c
index a8cfbef304b5..5227a779c05c 100644
--- a/drivers/scsi/atp870u.c
+++ b/drivers/scsi/atp870u.c
@@ -297,11 +297,10 @@ stop_dma:
}
workreq = dev->id[c][target_id].curr_req;
#ifdef ED_DBGP
- printk(KERN_DEBUG "Channel = %d ID = %d LUN = %d CDB",c,workreq->device->id,workreq->device->lun);
- for(l=0;l<workreq->cmd_len;l++)
- {
+ scmd_printk(KERN_DEBUG, workreq, "CDB");
+ for (l = 0; l < workreq->cmd_len; l++)
printk(KERN_DEBUG " %x",workreq->cmnd[l]);
- }
+ printk("\n");
#endif
tmport = workport + 0x0f;
@@ -622,10 +621,10 @@ static int atp870u_queuecommand(struct scsi_cmnd * req_p,
struct atp_unit *dev;
struct Scsi_Host *host;
- c = req_p->device->channel;
+ c = scmd_channel(req_p);
req_p->sense_buffer[0]=0;
req_p->resid = 0;
- if (req_p->device->channel > 1) {
+ if (scmd_channel(req_p) > 1) {
req_p->result = 0x00040000;
done(req_p);
#ifdef ED_DBGP
@@ -640,7 +639,7 @@ static int atp870u_queuecommand(struct scsi_cmnd * req_p,
m = 1;
- m = m << req_p->device->id;
+ m = m << scmd_id(req_p);
/*
* Fake a timeout for missing targets
@@ -758,9 +757,9 @@ static void send_s870(struct atp_unit *dev,unsigned char c)
dev->quhd[c] = 0;
}
workreq = dev->quereq[c][dev->quhd[c]];
- if (dev->id[c][workreq->device->id].curr_req == 0) {
- dev->id[c][workreq->device->id].curr_req = workreq;
- dev->last_cmd[c] = workreq->device->id;
+ if (dev->id[c][scmd_id(workreq)].curr_req == 0) {
+ dev->id[c][scmd_id(workreq)].curr_req = workreq;
+ dev->last_cmd[c] = scmd_id(workreq);
goto cmd_subp;
}
dev->quhd[c] = j;
@@ -787,16 +786,16 @@ abortsnd:
oktosend:
#ifdef ED_DBGP
printk("OK to Send\n");
- printk("CDB");
+ scmd_printk(KERN_DEBUG, workreq, "CDB");
for(i=0;i<workreq->cmd_len;i++) {
printk(" %x",workreq->cmnd[i]);
}
- printk("\nChannel = %d ID = %d LUN = %d\n",c,workreq->device->id,workreq->device->lun);
+ printk("\n");
#endif
if (dev->dev_id == ATP885_DEVID) {
j = inb(dev->baseport + 0x29) & 0xfe;
outb(j, dev->baseport + 0x29);
- dev->r1f[c][workreq->device->id] = 0;
+ dev->r1f[c][scmd_id(workreq)] = 0;
}
if (workreq->cmnd[0] == READ_CAPACITY) {
@@ -810,7 +809,7 @@ oktosend:
tmport = workport + 0x1b;
j = 0;
- target_id = workreq->device->id;
+ target_id = scmd_id(workreq);
/*
* Wide ?
@@ -3109,7 +3108,7 @@ static int atp870u_abort(struct scsi_cmnd * SCpnt)
host = SCpnt->device->host;
dev = (struct atp_unit *)&host->hostdata;
- c=SCpnt->device->channel;
+ c = scmd_channel(SCpnt);
printk(" atp870u: abort Channel = %x \n", c);
printk("working=%x last_cmd=%x ", dev->working[c], dev->last_cmd[c]);
printk(" quhdu=%x quendu=%x ", dev->quhd[c], dev->quend[c]);
diff --git a/drivers/scsi/bvme6000.c b/drivers/scsi/bvme6000.c
index 29c7ed30c09e..130f30f51a9b 100644
--- a/drivers/scsi/bvme6000.c
+++ b/drivers/scsi/bvme6000.c
@@ -7,7 +7,6 @@
#include <linux/mm.h>
#include <linux/blkdev.h>
#include <linux/sched.h>
-#include <linux/version.h>
#include <linux/zorro.h>
#include <asm/setup.h>
diff --git a/drivers/scsi/ch.c b/drivers/scsi/ch.c
index da6e51c7fe69..ccbbae2bf478 100644
--- a/drivers/scsi/ch.c
+++ b/drivers/scsi/ch.c
@@ -936,13 +936,11 @@ static int ch_probe(struct device *dev)
if (init)
ch_init_elem(ch);
- class_device_create(ch_sysfs_class,
+ class_device_create(ch_sysfs_class, NULL,
MKDEV(SCSI_CHANGER_MAJOR,ch->minor),
dev, "s%s", ch->name);
- printk(KERN_INFO "Attached scsi changer %s "
- "at scsi%d, channel %d, id %d, lun %d\n",
- ch->name, sd->host->host_no, sd->channel, sd->id, sd->lun);
+ sdev_printk(KERN_INFO, sd, "Attached scsi changer %s\n", ch->name);
spin_lock(&ch_devlist_lock);
list_add_tail(&ch->list,&ch_devlist);
diff --git a/drivers/scsi/constants.c b/drivers/scsi/constants.c
index f6be2c1c3942..09bc81557b6e 100644
--- a/drivers/scsi/constants.c
+++ b/drivers/scsi/constants.c
@@ -1389,10 +1389,7 @@ EXPORT_SYMBOL(scsi_print_msg);
void scsi_print_command(struct scsi_cmnd *cmd)
{
/* Assume appended output (i.e. not at start of line) */
- printk("scsi%d : destination target %d, lun %d\n",
- cmd->device->host->host_no,
- cmd->device->id,
- cmd->device->lun);
+ sdev_printk("", cmd->device, "\n");
printk(KERN_INFO " command: ");
scsi_print_cdb(cmd->cmnd, cmd->cmd_len, 0);
}
diff --git a/drivers/scsi/cpqfcTS.h b/drivers/scsi/cpqfcTS.h
deleted file mode 100644
index 7ce53d88cb96..000000000000
--- a/drivers/scsi/cpqfcTS.h
+++ /dev/null
@@ -1,19 +0,0 @@
-#ifndef CPQFCTS_H
-#define CPQFCTS_H
-#include "cpqfcTSstructs.h"
-
-// These functions are required by the Linux SCSI layers
-extern int cpqfcTS_detect(Scsi_Host_Template *);
-extern int cpqfcTS_release(struct Scsi_Host *);
-extern const char * cpqfcTS_info(struct Scsi_Host *);
-extern int cpqfcTS_proc_info(struct Scsi_Host *, char *, char **, off_t, int, int);
-extern int cpqfcTS_queuecommand(Scsi_Cmnd *, void (* done)(Scsi_Cmnd *));
-extern int cpqfcTS_abort(Scsi_Cmnd *);
-extern int cpqfcTS_reset(Scsi_Cmnd *, unsigned int);
-extern int cpqfcTS_eh_abort(Scsi_Cmnd *Cmnd);
-extern int cpqfcTS_eh_device_reset(Scsi_Cmnd *);
-extern int cpqfcTS_biosparam(struct scsi_device *, struct block_device *,
- sector_t, int[]);
-extern int cpqfcTS_ioctl( Scsi_Device *ScsiDev, int Cmnd, void *arg);
-
-#endif /* CPQFCTS_H */
diff --git a/drivers/scsi/cpqfcTSchip.h b/drivers/scsi/cpqfcTSchip.h
deleted file mode 100644
index 14b83373861f..000000000000
--- a/drivers/scsi/cpqfcTSchip.h
+++ /dev/null
@@ -1,238 +0,0 @@
-/* Copyright(c) 2000, Compaq Computer Corporation
- * Fibre Channel Host Bus Adapter
- * 64-bit, 66MHz PCI
- * Originally developed and tested on:
- * (front): [chip] Tachyon TS HPFC-5166A/1.2 L2C1090 ...
- * SP# P225CXCBFIEL6T, Rev XC
- * SP# 161290-001, Rev XD
- * (back): Board No. 010008-001 A/W Rev X5, FAB REV X5
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2, or (at your option) any
- * later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- * Written by Don Zimmerman
-*/
-#ifndef CPQFCTSCHIP_H
-#define CPQFCTSCHIP_H
-#ifndef TACHYON_CHIP_INC
-
-// FC-PH (Physical) specification levels for Login payloads
-// NOTE: These are NOT strictly complied with by any FC vendors
-
-#define FC_PH42 0x08
-#define FC_PH43 0x09
-#define FC_PH3 0x20
-
-#define TACHLITE_TS_RX_SIZE 1024 // max inbound frame size
-// "I" prefix is for Include
-
-#define IVENDID 0x00 // word
-#define IDEVID 0x02
-#define ITLCFGCMD 0x04
-#define IMEMBASE 0x18 // Tachyon
-#define ITLMEMBASE 0x1C // Tachlite
-#define IIOBASEL 0x10 // Tachyon I/O base address, lower 256 bytes
-#define IIOBASEU 0x14 // Tachyon I/O base address, upper 256 bytes
-#define ITLIOBASEL 0x14 // TachLite I/O base address, lower 256 bytes
-#define ITLIOBASEU 0x18 // TachLite I/O base address, upper 256 bytes
-#define ITLRAMBASE 0x20 // TL on-board RAM start
-#define ISROMBASE 0x24
-#define IROMBASE 0x30
-
-#define ICFGCMD 0x04 // PCI config - PCI config access (word)
-#define ICFGSTAT 0x06 // PCI status (R - word)
-#define IRCTR_WCTR 0x1F2 // ROM control / pre-fetch wait counter
-#define IPCIMCTR 0x1F3 // PCI master control register
-#define IINTPEND 0x1FD // Interrupt pending (I/O Upper - Tachyon & TL)
-#define IINTEN 0x1FE // Interrupt enable (I/O Upper - Tachyon & TL)
-#define IINTSTAT 0x1FF // Interrupt status (I/O Upper - Tachyon & TL)
-
-#define IMQ_BASE 0x80
-#define IMQ_LENGTH 0x84
-#define IMQ_CONSUMER_INDEX 0x88
-#define IMQ_PRODUCER_INDEX 0x8C // Tach copies its INDX to bits 0-7 of value
-
-/*
-// IOBASE UPPER
-#define SFSBQ_BASE 0x00 // single-frame sequences
-#define SFSBQ_LENGTH 0x04
-#define SFSBQ_PRODUCER_INDEX 0x08
-#define SFSBQ_CONSUMER_INDEX 0x0C // (R)
-#define SFS_BUFFER_LENGTH 0X10
- // SCSI-FCP hardware assists
-#define SEST_BASE 0x40 // SSCI Exchange State Table
-#define SEST_LENGTH 0x44
-#define SCSI_BUFFER_LENGTH 0x48
-#define SEST_LINKED_LIST 0x4C
-
-#define TACHYON_My_ID 0x6C
-#define TACHYON_CONFIGURATION 0x84 // (R/W) reset val 2
-#define TACHYON_CONTROL 0x88
-#define TACHYON_STATUS 0x8C // (R)
-#define TACHYON_FLUSH_SEST 0x90 // (R/W)
-#define TACHYON_EE_CREDIT_TMR 0x94 // (R)
-#define TACHYON_BB_CREDIT_TMR 0x98 // (R)
-#define TACHYON_RCV_FRAME_ERR 0x9C // (R)
-#define FRAME_MANAGER_CONFIG 0xC0 // (R/W)
-#define FRAME_MANAGER_CONTROL 0xC4
-#define FRAME_MANAGER_STATUS 0xC8 // (R)
-#define FRAME_MANAGER_ED_TOV 0xCC
-#define FRAME_MANAGER_LINK_ERR1 0xD0 // (R)
-#define FRAME_MANAGER_LINK_ERR2 0xD4 // (R)
-#define FRAME_MANAGER_TIMEOUT2 0xD8 // (W)
-#define FRAME_MANAGER_BB_CREDIT 0xDC // (R)
-#define FRAME_MANAGER_WWN_HI 0xE0 // (R/W)
-#define FRAME_MANAGER_WWN_LO 0xE4 // (R/W)
-#define FRAME_MANAGER_RCV_AL_PA 0xE8 // (R)
-#define FRAME_MANAGER_PRIMITIVE 0xEC // {K28.5} byte1 byte2 byte3
-*/
-
-#define TL_MEM_ERQ_BASE 0x0 //ERQ Base
-#define TL_IO_ERQ_BASE 0x0 //ERQ base
-
-#define TL_MEM_ERQ_LENGTH 0x4 //ERQ Length
-#define TL_IO_ERQ_LENGTH 0x4 //ERQ Length
-
-#define TL_MEM_ERQ_PRODUCER_INDEX 0x8 //ERQ Producer Index register
-#define TL_IO_ERQ_PRODUCER_INDEX 0x8 //ERQ Producer Index register
-
-#define TL_MEM_ERQ_CONSUMER_INDEX_ADR 0xC //ERQ Consumer Index address register
-#define TL_IO_ERQ_CONSUMER_INDEX_ADR 0xC //ERQ Consumer Index address register
-
-#define TL_MEM_ERQ_CONSUMER_INDEX 0xC //ERQ Consumer Index
-#define TL_IO_ERQ_CONSUMER_INDEX 0xC //ERQ Consumer Index
-
-#define TL_MEM_SFQ_BASE 0x50 //SFQ Base
-#define TL_IO_SFQ_BASE 0x50 //SFQ base
-
-#define TL_MEM_SFQ_LENGTH 0x54 //SFQ Length
-#define TL_IO_SFQ_LENGTH 0x54 //SFQ Length
-
-#define TL_MEM_SFQ_CONSUMER_INDEX 0x58 //SFQ Consumer Index
-#define TL_IO_SFQ_CONSUMER_INDEX 0x58 //SFQ Consumer Index
-
-#define TL_MEM_IMQ_BASE 0x80 //IMQ Base
-#define TL_IO_IMQ_BASE 0x80 //IMQ base
-
-#define TL_MEM_IMQ_LENGTH 0x84 //IMQ Length
-#define TL_IO_IMQ_LENGTH 0x84 //IMQ Length
-
-#define TL_MEM_IMQ_CONSUMER_INDEX 0x88 //IMQ Consumer Index
-#define TL_IO_IMQ_CONSUMER_INDEX 0x88 //IMQ Consumer Index
-
-#define TL_MEM_IMQ_PRODUCER_INDEX_ADR 0x8C //IMQ Producer Index address register
-#define TL_IO_IMQ_PRODUCER_INDEX_ADR 0x8C //IMQ Producer Index address register
-
-#define TL_MEM_SEST_BASE 0x140 //SFQ Base
-#define TL_IO_SEST_BASE 0x40 //SFQ base
-
-#define TL_MEM_SEST_LENGTH 0x144 //SFQ Length
-#define TL_IO_SEST_LENGTH 0x44 //SFQ Length
-
-#define TL_MEM_SEST_LINKED_LIST 0x14C
-
-#define TL_MEM_SEST_SG_PAGE 0x168 // Extended Scatter/Gather page size
-
-#define TL_MEM_TACH_My_ID 0x16C
-#define TL_IO_TACH_My_ID 0x6C //My AL_PA ID
-
-#define TL_MEM_TACH_CONFIG 0x184 //Tachlite Configuration register
-#define TL_IO_CONFIG 0x84 //Tachlite Configuration register
-
-#define TL_MEM_TACH_CONTROL 0x188 //Tachlite Control register
-#define TL_IO_CTR 0x88 //Tachlite Control register
-
-#define TL_MEM_TACH_STATUS 0x18C //Tachlite Status register
-#define TL_IO_STAT 0x8C //Tachlite Status register
-
-#define TL_MEM_FM_CONFIG 0x1C0 //Frame Manager Configuration register
-#define TL_IO_FM_CONFIG 0xC0 //Frame Manager Configuration register
-
-#define TL_MEM_FM_CONTROL 0x1C4 //Frame Manager Control
-#define TL_IO_FM_CTL 0xC4 //Frame Manager Control
-
-#define TL_MEM_FM_STATUS 0x1C8 //Frame Manager Status
-#define TL_IO_FM_STAT 0xC8 //Frame Manager Status
-
-#define TL_MEM_FM_LINK_STAT1 0x1D0 //Frame Manager Link Status 1
-#define TL_IO_FM_LINK_STAT1 0xD0 //Frame Manager Link Status 1
-
-#define TL_MEM_FM_LINK_STAT2 0x1D4 //Frame Manager Link Status 2
-#define TL_IO_FM_LINK_STAT2 0xD4 //Frame Manager Link Status 2
-
-#define TL_MEM_FM_TIMEOUT2 0x1D8 // (W)
-
-#define TL_MEM_FM_BB_CREDIT0 0x1DC
-
-#define TL_MEM_FM_WWN_HI 0x1E0 //Frame Manager World Wide Name High
-#define TL_IO_FM_WWN_HI 0xE0 //Frame Manager World Wide Name High
-
-#define TL_MEM_FM_WWN_LO 0x1E4 //Frame Manager World Wide Name LOW
-#define TL_IO_FM_WWN_LO 0xE4 //Frame Manager World Wide Name Low
-
-#define TL_MEM_FM_RCV_AL_PA 0x1E8 //Frame Manager AL_PA Received register
-#define TL_IO_FM_ALPA 0xE8 //Frame Manager AL_PA Received register
-
-#define TL_MEM_FM_ED_TOV 0x1CC
-
-#define TL_IO_ROMCTR 0xFA //TL PCI ROM Control Register
-#define TL_IO_PCIMCTR 0xFB //TL PCI Master Control Register
-#define TL_IO_SOFTRST 0xFC //Tachlite Configuration register
-#define TL_MEM_SOFTRST 0x1FC //Tachlite Configuration register
-
-// completion message types (bit 8 set means Interrupt generated)
-// CM_Type
-#define OUTBOUND_COMPLETION 0
-#define ERROR_IDLE_COMPLETION 0x01
-#define OUT_HI_PRI_COMPLETION 0x01
-#define INBOUND_MFS_COMPLETION 0x02
-#define INBOUND_000_COMPLETION 0x03
-#define INBOUND_SFS_COMPLETION 0x04 // Tachyon & TachLite
-#define ERQ_FROZEN_COMPLETION 0x06 // TachLite
-#define INBOUND_C1_TIMEOUT 0x05
-#define INBOUND_BUSIED_FRAME 0x06
-#define SFS_BUF_WARN 0x07
-#define FCP_FROZEN_COMPLETION 0x07 // TachLite
-#define MFS_BUF_WARN 0x08
-#define IMQ_BUF_WARN 0x09
-#define FRAME_MGR_INTERRUPT 0x0A
-#define READ_STATUS 0x0B
-#define INBOUND_SCSI_DATA_COMPLETION 0x0C
-#define INBOUND_FCP_XCHG_COMPLETION 0x0C // TachLite
-#define INBOUND_SCSI_DATA_COMMAND 0x0D
-#define BAD_SCSI_FRAME 0x0E
-#define INB_SCSI_STATUS_COMPLETION 0x0F
-#define BUFFER_PROCESSED_COMPLETION 0x11
-
-// FC-AL (Tachyon) Loop Port State Machine defs
-// (loop "Up" states)
-#define MONITORING 0x0
-#define ARBITRATING 0x1
-#define ARBITRAT_WON 0x2
-#define OPEN 0x3
-#define OPENED 0x4
-#define XMITTD_CLOSE 0x5
-#define RCVD_CLOSE 0x6
-#define TRANSFER 0x7
-
-// (loop "Down" states)
-#define INITIALIZING 0x8
-#define O_I_INIT 0x9
-#define O_I_PROTOCOL 0xa
-#define O_I_LIP_RCVD 0xb
-#define HOST_CONTROL 0xc
-#define LOOP_FAIL 0xd
-// (no 0xe)
-#define OLD_PORT 0xf
-
-
-
-#define TACHYON_CHIP_INC
-#endif
-#endif /* CPQFCTSCHIP_H */
diff --git a/drivers/scsi/cpqfcTScontrol.c b/drivers/scsi/cpqfcTScontrol.c
deleted file mode 100644
index bd94c70f473d..000000000000
--- a/drivers/scsi/cpqfcTScontrol.c
+++ /dev/null
@@ -1,2231 +0,0 @@
-/* Copyright 2000, Compaq Computer Corporation
- * Fibre Channel Host Bus Adapter
- * 64-bit, 66MHz PCI
- * Originally developed and tested on:
- * (front): [chip] Tachyon TS HPFC-5166A/1.2 L2C1090 ...
- * SP# P225CXCBFIEL6T, Rev XC
- * SP# 161290-001, Rev XD
- * (back): Board No. 010008-001 A/W Rev X5, FAB REV X5
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2, or (at your option) any
- * later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- * Written by Don Zimmerman
-*/
-/* These functions control the host bus adapter (HBA) hardware. The main chip
- control takes place in the interrupt handler where we process the IMQ
- (Inbound Message Queue). The IMQ is Tachyon's way of communicating FC link
- events and state information to the driver. The Single Frame Queue (SFQ)
- buffers incoming FC frames for processing by the driver. References to
- "TL/TS UG" are for:
- "HP HPFC-5100/5166 Tachyon TL/TS ICs User Guide", August 16, 1999, 1st Ed.
- Hewlitt Packard Manual Part Number 5968-1083E.
-*/
-
-#define LinuxVersionCode(v, p, s) (((v)<<16)+((p)<<8)+(s))
-
-#include <linux/blkdev.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/ioport.h> // request_region() prototype
-#include <linux/sched.h>
-#include <linux/slab.h> // need "kfree" for ext. S/G pages
-#include <linux/types.h>
-#include <linux/pci.h>
-#include <linux/delay.h>
-#include <linux/unistd.h>
-#include <asm/io.h> // struct pt_regs for IRQ handler & Port I/O
-#include <asm/irq.h>
-#include <linux/spinlock.h>
-
-#include "scsi.h"
-#include <scsi/scsi_host.h> // Scsi_Host definition for INT handler
-#include "cpqfcTSchip.h"
-#include "cpqfcTSstructs.h"
-
-//#define IMQ_DEBUG 1
-
-static void fcParseLinkStatusCounters(TACHYON * fcChip);
-static void CpqTsGetSFQEntry(TACHYON * fcChip,
- USHORT pi, ULONG * buffr, BOOLEAN UpdateChip);
-
-static void
-cpqfc_free_dma_consistent(CPQFCHBA *cpqfcHBAdata)
-{
- // free up the primary EXCHANGES struct and Link Q
- PTACHYON fcChip = &cpqfcHBAdata->fcChip;
-
- if (fcChip->Exchanges != NULL)
- pci_free_consistent(cpqfcHBAdata->PciDev, sizeof(FC_EXCHANGES),
- fcChip->Exchanges, fcChip->exch_dma_handle);
- fcChip->Exchanges = NULL;
- if (cpqfcHBAdata->fcLQ != NULL)
- pci_free_consistent(cpqfcHBAdata->PciDev, sizeof(FC_LINK_QUE),
- cpqfcHBAdata->fcLQ, cpqfcHBAdata->fcLQ_dma_handle);
- cpqfcHBAdata->fcLQ = NULL;
-}
-
-// Note special requirements for Q alignment! (TL/TS UG pg. 190)
-// We place critical index pointers at end of QUE elements to assist
-// in non-symbolic (i.e. memory dump) debugging
-// opcode defines placement of Queues (e.g. local/external RAM)
-
-int CpqTsCreateTachLiteQues( void* pHBA, int opcode)
-{
- CPQFCHBA *cpqfcHBAdata = (CPQFCHBA*)pHBA;
- PTACHYON fcChip = &cpqfcHBAdata->fcChip;
-
- int iStatus=0;
- unsigned long ulAddr;
- dma_addr_t ERQdma, IMQdma, SPQdma, SESTdma;
- int i;
-
- // NOTE! fcMemManager() will return system virtual addresses.
- // System (kernel) virtual addresses, though non-paged, still
- // aren't physical addresses. Convert to PHYSICAL_ADDRESS for Tachyon's
- // DMA use.
- ENTER("CreateTachLiteQues");
-
-
- // Allocate primary EXCHANGES array...
- fcChip->Exchanges = NULL;
- cpqfcHBAdata->fcLQ = NULL;
-
- /* printk("Allocating %u for %u Exchanges ",
- (ULONG)sizeof(FC_EXCHANGES), TACH_MAX_XID); */
- fcChip->Exchanges = pci_alloc_consistent(cpqfcHBAdata->PciDev,
- sizeof(FC_EXCHANGES), &fcChip->exch_dma_handle);
- /* printk("@ %p\n", fcChip->Exchanges); */
-
- if( fcChip->Exchanges == NULL ) // fatal error!!
- {
- printk("pci_alloc_consistent failure on Exchanges: fatal error\n");
- return -1;
- }
- // zero out the entire EXCHANGE space
- memset( fcChip->Exchanges, 0, sizeof( FC_EXCHANGES));
-
-
- /* printk("Allocating %u for LinkQ ", (ULONG)sizeof(FC_LINK_QUE)); */
- cpqfcHBAdata->fcLQ = pci_alloc_consistent(cpqfcHBAdata->PciDev,
- sizeof( FC_LINK_QUE), &cpqfcHBAdata->fcLQ_dma_handle);
- /* printk("@ %p (%u elements)\n", cpqfcHBAdata->fcLQ, FC_LINKQ_DEPTH); */
-
- if( cpqfcHBAdata->fcLQ == NULL ) // fatal error!!
- {
- cpqfc_free_dma_consistent(cpqfcHBAdata);
- printk("pci_alloc_consistent() failure on fc Link Que: fatal error\n");
- return -1;
- }
- // zero out the entire EXCHANGE space
- memset( cpqfcHBAdata->fcLQ, 0, sizeof( FC_LINK_QUE));
-
- // Verify that basic Tach I/O registers are not NULL
- if( !fcChip->Registers.ReMapMemBase )
- {
- cpqfc_free_dma_consistent(cpqfcHBAdata);
- printk("HBA base address NULL: fatal error\n");
- return -1;
- }
-
-
- // Initialize the fcMemManager memory pairs (stores allocated/aligned
- // pairs for future freeing)
- memset( cpqfcHBAdata->dynamic_mem, 0, sizeof(cpqfcHBAdata->dynamic_mem));
-
-
- // Allocate Tach's Exchange Request Queue (each ERQ entry 32 bytes)
-
- fcChip->ERQ = fcMemManager( cpqfcHBAdata->PciDev,
- &cpqfcHBAdata->dynamic_mem[0],
- sizeof( TachLiteERQ ), 32*(ERQ_LEN), 0L, &ERQdma);
- if( !fcChip->ERQ )
- {
- cpqfc_free_dma_consistent(cpqfcHBAdata);
- printk("pci_alloc_consistent/alignment failure on ERQ: fatal error\n");
- return -1;
- }
- fcChip->ERQ->length = ERQ_LEN-1;
- ulAddr = (ULONG) ERQdma;
-#if BITS_PER_LONG > 32
- if( (ulAddr >> 32) )
- {
- cpqfc_free_dma_consistent(cpqfcHBAdata);
- printk(" FATAL! ERQ ptr %p exceeds Tachyon's 32-bit register size\n",
- (void*)ulAddr);
- return -1; // failed
- }
-#endif
- fcChip->ERQ->base = (ULONG)ulAddr; // copy for quick reference
-
-
- // Allocate Tach's Inbound Message Queue (32 bytes per entry)
-
- fcChip->IMQ = fcMemManager( cpqfcHBAdata->PciDev,
- &cpqfcHBAdata->dynamic_mem[0],
- sizeof( TachyonIMQ ), 32*(IMQ_LEN), 0L, &IMQdma );
- if( !fcChip->IMQ )
- {
- cpqfc_free_dma_consistent(cpqfcHBAdata);
- printk("pci_alloc_consistent/alignment failure on IMQ: fatal error\n");
- return -1;
- }
- fcChip->IMQ->length = IMQ_LEN-1;
-
- ulAddr = IMQdma;
-#if BITS_PER_LONG > 32
- if( (ulAddr >> 32) )
- {
- cpqfc_free_dma_consistent(cpqfcHBAdata);
- printk(" FATAL! IMQ ptr %p exceeds Tachyon's 32-bit register size\n",
- (void*)ulAddr);
- return -1; // failed
- }
-#endif
- fcChip->IMQ->base = (ULONG)ulAddr; // copy for quick reference
-
-
- // Allocate Tach's Single Frame Queue (64 bytes per entry)
- fcChip->SFQ = fcMemManager( cpqfcHBAdata->PciDev,
- &cpqfcHBAdata->dynamic_mem[0],
- sizeof( TachLiteSFQ ), 64*(SFQ_LEN),0L, &SPQdma );
- if( !fcChip->SFQ )
- {
- cpqfc_free_dma_consistent(cpqfcHBAdata);
- printk("pci_alloc_consistent/alignment failure on SFQ: fatal error\n");
- return -1;
- }
- fcChip->SFQ->length = SFQ_LEN-1; // i.e. Que length [# entries -
- // min. 32; max. 4096 (0xffff)]
-
- ulAddr = SPQdma;
-#if BITS_PER_LONG > 32
- if( (ulAddr >> 32) )
- {
- cpqfc_free_dma_consistent(cpqfcHBAdata);
- printk(" FATAL! SFQ ptr %p exceeds Tachyon's 32-bit register size\n",
- (void*)ulAddr);
- return -1; // failed
- }
-#endif
- fcChip->SFQ->base = (ULONG)ulAddr; // copy for quick reference
-
-
- // Allocate SCSI Exchange State Table; aligned nearest @sizeof
- // power-of-2 boundary
- // LIVE DANGEROUSLY! Assume the boundary for SEST mem will
- // be on physical page (e.g. 4k) boundary.
- /* printk("Allocating %u for TachSEST for %u Exchanges\n",
- (ULONG)sizeof(TachSEST), TACH_SEST_LEN); */
- fcChip->SEST = fcMemManager( cpqfcHBAdata->PciDev,
- &cpqfcHBAdata->dynamic_mem[0],
- sizeof(TachSEST), 4, 0L, &SESTdma );
-// sizeof(TachSEST), 64*TACH_SEST_LEN, 0L );
- if( !fcChip->SEST )
- {
- cpqfc_free_dma_consistent(cpqfcHBAdata);
- printk("pci_alloc_consistent/alignment failure on SEST: fatal error\n");
- return -1;
- }
-
- for( i=0; i < TACH_SEST_LEN; i++) // for each exchange
- fcChip->SEST->sgPages[i] = NULL;
-
- fcChip->SEST->length = TACH_SEST_LEN; // e.g. DON'T subtract one
- // (TL/TS UG, pg 153)
-
- ulAddr = SESTdma;
-#if BITS_PER_LONG > 32
- if( (ulAddr >> 32) )
- {
- cpqfc_free_dma_consistent(cpqfcHBAdata);
- printk(" FATAL! SFQ ptr %p exceeds Tachyon's 32-bit register size\n",
- (void*)ulAddr);
- return -1; // failed
- }
-#endif
- fcChip->SEST->base = (ULONG)ulAddr; // copy for quick reference
-
-
- // Now that structures are defined,
- // fill in Tachyon chip registers...
-
- // EEEEEEEE EXCHANGE REQUEST QUEUE
-
- writel( fcChip->ERQ->base,
- (fcChip->Registers.ReMapMemBase + TL_MEM_ERQ_BASE));
-
- writel( fcChip->ERQ->length,
- (fcChip->Registers.ReMapMemBase + TL_MEM_ERQ_LENGTH));
-
-
- fcChip->ERQ->producerIndex = 0L;
- writel( fcChip->ERQ->producerIndex,
- (fcChip->Registers.ReMapMemBase + TL_MEM_ERQ_PRODUCER_INDEX));
-
-
- // NOTE! write consumer index last, since the write
- // causes Tachyon to process the other registers
-
- ulAddr = ((unsigned long)&fcChip->ERQ->consumerIndex -
- (unsigned long)fcChip->ERQ) + (unsigned long) ERQdma;
-
- // NOTE! Tachyon DMAs to the ERQ consumer Index host
- // address; must be correctly aligned
- writel( (ULONG)ulAddr,
- (fcChip->Registers.ReMapMemBase + TL_MEM_ERQ_CONSUMER_INDEX_ADR));
-
-
-
- // IIIIIIIIIIIII INBOUND MESSAGE QUEUE
- // Tell Tachyon where the Que starts
-
- // set the Host's pointer for Tachyon to access
-
- /* printk(" cpqfcTS: writing IMQ BASE %Xh ", fcChip->IMQ->base ); */
- writel( fcChip->IMQ->base,
- (fcChip->Registers.ReMapMemBase + IMQ_BASE));
-
- writel( fcChip->IMQ->length,
- (fcChip->Registers.ReMapMemBase + IMQ_LENGTH));
-
- writel( fcChip->IMQ->consumerIndex,
- (fcChip->Registers.ReMapMemBase + IMQ_CONSUMER_INDEX));
-
-
- // NOTE: TachLite DMAs to the producerIndex host address
- // must be correctly aligned with address bits 1-0 cleared
- // Writing the BASE register clears the PI register, so write it last
- ulAddr = ((unsigned long)&fcChip->IMQ->producerIndex -
- (unsigned long)fcChip->IMQ) + (unsigned long) IMQdma;
-
-#if BITS_PER_LONG > 32
- if( (ulAddr >> 32) )
- {
- cpqfc_free_dma_consistent(cpqfcHBAdata);
- printk(" FATAL! IMQ ptr %p exceeds Tachyon's 32-bit register size\n",
- (void*)ulAddr);
- return -1; // failed
- }
-#endif
-#if DBG
- printk(" PI %Xh\n", (ULONG)ulAddr );
-#endif
- writel( (ULONG)ulAddr,
- (fcChip->Registers.ReMapMemBase + IMQ_PRODUCER_INDEX));
-
-
-
- // SSSSSSSSSSSSSSS SINGLE FRAME SEQUENCE
- // Tell TachLite where the Que starts
-
- writel( fcChip->SFQ->base,
- (fcChip->Registers.ReMapMemBase + TL_MEM_SFQ_BASE));
-
- writel( fcChip->SFQ->length,
- (fcChip->Registers.ReMapMemBase + TL_MEM_SFQ_LENGTH));
-
-
- // tell TachLite where SEST table is & how long
- writel( fcChip->SEST->base,
- (fcChip->Registers.ReMapMemBase + TL_MEM_SEST_BASE));
-
- /* printk(" cpqfcTS: SEST %p(virt): Wrote base %Xh @ %p\n",
- fcChip->SEST, fcChip->SEST->base,
- fcChip->Registers.ReMapMemBase + TL_MEM_SEST_BASE); */
-
- writel( fcChip->SEST->length,
- (fcChip->Registers.ReMapMemBase + TL_MEM_SEST_LENGTH));
-
- writel( (TL_EXT_SG_PAGE_COUNT-1),
- (fcChip->Registers.ReMapMemBase + TL_MEM_SEST_SG_PAGE));
-
-
- LEAVE("CreateTachLiteQues");
-
- return iStatus;
-}
-
-
-
-// function to return TachLite to Power On state
-// 1st - reset tachyon ('SOFT' reset)
-// others - future
-
-int CpqTsResetTachLite(void *pHBA, int type)
-{
- CPQFCHBA *cpqfcHBAdata = (CPQFCHBA*)pHBA;
- PTACHYON fcChip = &cpqfcHBAdata->fcChip;
- ULONG ulBuff, i;
- int ret_status=0; // def. success
-
- ENTER("ResetTach");
-
- switch(type)
- {
-
- case CLEAR_FCPORTS:
-
- // in case he was running previously, mask Tach's interrupt
- writeb( 0, (fcChip->Registers.ReMapMemBase + IINTEN));
-
- // de-allocate mem for any Logged in ports
- // (e.g., our module is unloading)
- // search the forward linked list, de-allocating
- // the memory we allocated when the port was initially logged in
- {
- PFC_LOGGEDIN_PORT pLoggedInPort = fcChip->fcPorts.pNextPort;
- PFC_LOGGEDIN_PORT ptr;
-// printk("checking for allocated LoggedInPorts...\n");
-
- while( pLoggedInPort )
- {
- ptr = pLoggedInPort;
- pLoggedInPort = ptr->pNextPort;
-// printk("kfree(%p) on FC LoggedInPort port_id 0x%06lX\n",
-// ptr, ptr->port_id);
- kfree( ptr );
- }
- }
- // (continue resetting hardware...)
-
- case 1: // RESTART Tachyon (power-up state)
-
- // in case he was running previously, mask Tach's interrupt
- writeb( 0, (fcChip->Registers.ReMapMemBase + IINTEN));
- // turn OFF laser (NOTE: laser is turned
- // off during reset, because GPIO4 is cleared
- // to 0 by reset action - see TLUM, sec 7.22)
- // However, CPQ 64-bit HBAs have a "health
- // circuit" which keeps laser ON for a brief
- // period after it is turned off ( < 1s)
-
- fcChip->LaserControl( fcChip->Registers.ReMapMemBase, 0);
-
-
-
- // soft reset timing constraints require:
- // 1. set RST to 1
- // 2. read SOFTRST register
- // (128 times per R. Callison code)
- // 3. clear PCI ints
- // 4. clear RST to 0
- writel( 0xff000001L,
- (fcChip->Registers.ReMapMemBase + TL_MEM_SOFTRST));
-
- for( i=0; i<128; i++)
- ulBuff = readl( fcChip->Registers.ReMapMemBase + TL_MEM_SOFTRST);
-
- // clear the soft reset
- for( i=0; i<8; i++)
- writel( 0, (fcChip->Registers.ReMapMemBase + TL_MEM_SOFTRST));
-
-
-
- // clear out our copy of Tach regs,
- // because they must be invalid now,
- // since TachLite reset all his regs.
- CpqTsDestroyTachLiteQues(cpqfcHBAdata,0); // remove Host-based Que structs
- cpqfcTSClearLinkStatusCounters(fcChip); // clear our s/w accumulators
- // lower bits give GBIC info
- fcChip->Registers.TYstatus.value =
- readl( fcChip->Registers.TYstatus.address );
- break;
-
-/*
- case 2: // freeze SCSI
- case 3: // reset Outbound command que (ERQ)
- case 4: // unfreeze OSM (Outbound Seq. Man.) 'er'
- case 5: // report status
-
- break;
-*/
- default:
- ret_status = -1; // invalid option passed to RESET function
- break;
- }
- LEAVE("ResetTach");
- return ret_status;
-}
-
-
-
-
-
-
-// 'addrBase' is IOBaseU for both TachLite and (older) Tachyon
-int CpqTsLaserControl( void* addrBase, int opcode )
-{
- ULONG dwBuff;
-
- dwBuff = readl((addrBase + TL_MEM_TACH_CONTROL) ); // read TL Control reg
- // (change only bit 4)
- if( opcode == 1)
- dwBuff |= ~0xffffffefL; // set - ON
- else
- dwBuff &= 0xffffffefL; // clear - OFF
- writel( dwBuff, (addrBase + TL_MEM_TACH_CONTROL)); // write TL Control reg
- return 0;
-}
-
-
-
-
-
-// Use controller's "Options" field to determine loopback mode (if any)
-// internal loopback (silicon - no GBIC)
-// external loopback (GBIC - no FC loop)
-// no loopback: L_PORT, external cable from GBIC required
-
-int CpqTsInitializeFrameManager( void *pChip, int opcode)
-{
- PTACHYON fcChip;
- int iStatus;
- ULONG wwnLo, wwnHi; // for readback verification
-
- ENTER("InitializeFrameManager");
- fcChip = (PTACHYON)pChip;
- if( !fcChip->Registers.ReMapMemBase ) // undefined controller?
- return -1;
-
- // TL/TS UG, pg. 184
- // 0x0065 = 100ms for RT_TOV
- // 0x01f5 = 500ms for ED_TOV
- // 0x07D1 = 2000ms
- fcChip->Registers.ed_tov.value = 0x006507D1;
- writel( fcChip->Registers.ed_tov.value,
- (fcChip->Registers.ed_tov.address));
-
-
- // Set LP_TOV to the FC-AL2 specified 2 secs.
- // TL/TS UG, pg. 185
- writel( 0x07d00010, fcChip->Registers.ReMapMemBase +TL_MEM_FM_TIMEOUT2);
-
-
- // Now try to read the WWN from the adapter's NVRAM
- iStatus = CpqTsReadWriteWWN( fcChip, 1); // '1' for READ
-
- if( iStatus ) // NVRAM read failed?
- {
- printk(" WARNING! HBA NVRAM WWN read failed - make alias\n");
- // make up a WWN. If NULL or duplicated on loop, FC loop may hang!
-
-
- fcChip->Registers.wwn_hi = (__u32)jiffies;
- fcChip->Registers.wwn_hi |= 0x50000000L;
- fcChip->Registers.wwn_lo = 0x44556677L;
- }
-
-
- writel( fcChip->Registers.wwn_hi,
- fcChip->Registers.ReMapMemBase + TL_MEM_FM_WWN_HI);
-
- writel( fcChip->Registers.wwn_lo,
- fcChip->Registers.ReMapMemBase + TL_MEM_FM_WWN_LO);
-
-
- // readback for verification:
- wwnHi = readl( fcChip->Registers.ReMapMemBase + TL_MEM_FM_WWN_HI );
-
- wwnLo = readl( fcChip->Registers.ReMapMemBase + TL_MEM_FM_WWN_LO);
- // test for correct chip register WRITE/READ
- DEBUG_PCI( printk(" WWN %08X%08X\n",
- fcChip->Registers.wwn_hi, fcChip->Registers.wwn_lo ) );
-
- if( wwnHi != fcChip->Registers.wwn_hi ||
- wwnLo != fcChip->Registers.wwn_lo )
- {
- printk( "cpqfcTS: WorldWideName register load failed\n");
- return -1; // FAILED!
- }
-
-
-
- // set Frame Manager Initialize command
- fcChip->Registers.FMcontrol.value = 0x06;
-
- // Note: for test/debug purposes, we may use "Hard" address,
- // but we completely support "soft" addressing, including
- // dynamically changing our address.
- if( fcChip->Options.intLoopback == 1 ) // internal loopback
- fcChip->Registers.FMconfig.value = 0x0f002080L;
- else if( fcChip->Options.extLoopback == 1 ) // internal loopback
- fcChip->Registers.FMconfig.value = 0x0f004080L;
- else // L_Port
- fcChip->Registers.FMconfig.value = 0x55000100L; // hard address (55h start)
-// fcChip->Registers.FMconfig.value = 0x01000080L; // soft address (can't pick)
-// fcChip->Registers.FMconfig.value = 0x55000100L; // hard address (55h start)
-
- // write config to FM
-
- if( !fcChip->Options.intLoopback && !fcChip->Options.extLoopback )
- // (also need LASER for real LOOP)
- fcChip->LaserControl( fcChip->Registers.ReMapMemBase, 1); // turn on LASER
-
- writel( fcChip->Registers.FMconfig.value,
- fcChip->Registers.FMconfig.address);
-
-
- // issue INITIALIZE command to FM - ACTION!
- writel( fcChip->Registers.FMcontrol.value,
- fcChip->Registers.FMcontrol.address);
-
- LEAVE("InitializeFrameManager");
-
- return 0;
-}
-
-
-
-
-
-// This "look ahead" function examines the IMQ for occurrence of
-// "type". Returns 1 if found, 0 if not.
-static int PeekIMQEntry( PTACHYON fcChip, ULONG type)
-{
- ULONG CI = fcChip->IMQ->consumerIndex;
- ULONG PI = fcChip->IMQ->producerIndex; // snapshot of IMQ indexes
-
- while( CI != PI )
- { // proceed with search
- if( (++CI) >= IMQ_LEN ) CI = 0; // rollover check
-
- switch( type )
- {
- case ELS_LILP_FRAME:
- {
- // first, we need to find an Inbound Completion message,
- // If we find it, check the incoming frame payload (1st word)
- // for LILP frame
- if( (fcChip->IMQ->QEntry[CI].type & 0x1FF) == 0x104 )
- {
- TachFCHDR_GCMND* fchs;
-#error This is too much stack
- ULONG ulFibreFrame[2048/4]; // max DWORDS in incoming FC Frame
- USHORT SFQpi = (USHORT)(fcChip->IMQ->QEntry[CI].word[0] & 0x0fffL);
-
- CpqTsGetSFQEntry( fcChip,
- SFQpi, // SFQ producer ndx
- ulFibreFrame, // contiguous dest. buffer
- FALSE); // DON'T update chip--this is a "lookahead"
-
- fchs = (TachFCHDR_GCMND*)&ulFibreFrame;
- if( fchs->pl[0] == ELS_LILP_FRAME)
- {
- return 1; // found the LILP frame!
- }
- else
- {
- // keep looking...
- }
- }
- }
- break;
-
- case OUTBOUND_COMPLETION:
- if( (fcChip->IMQ->QEntry[CI].type & 0x1FF) == 0x00 )
- {
-
- // any OCM errors?
- if( fcChip->IMQ->QEntry[CI].word[2] & 0x7a000000L )
- return 1; // found OCM error
- }
- break;
-
-
-
- default:
- break;
- }
- }
- return 0; // failed to find "type"
-}
-
-
-static void SetTachTOV( CPQFCHBA* cpqfcHBAdata)
-{
- PTACHYON fcChip = &cpqfcHBAdata->fcChip;
-
- // TL/TS UG, pg. 184
- // 0x0065 = 100ms for RT_TOV
- // 0x01f5 = 500ms for ED_TOV
- // 0x07d1 = 2000ms for ED_TOV
-
- // SANMark Level 1 requires an "initialization backoff"
- // (See "SANMark Test Suite Level 1":
- // initialization_timeout.fcal.SANMark-1.fc)
- // We have to use 2sec, 24sec, then 128sec when login/
- // port discovery processes fail to complete.
-
- // when port discovery completes (logins done), we set
- // ED_TOV to 500ms -- this is the normal operational case
- // On the first Link Down, we'll move to 2 secs (7D1 ms)
- if( (fcChip->Registers.ed_tov.value &0xFFFF) <= 0x1f5)
- fcChip->Registers.ed_tov.value = 0x006507D1;
-
- // If we get another LST after we moved TOV to 2 sec,
- // increase to 24 seconds (5DC1 ms) per SANMark!
- else if( (fcChip->Registers.ed_tov.value &0xFFFF) <= 0x7D1)
- fcChip->Registers.ed_tov.value = 0x00655DC1;
-
- // If we get still another LST, set the max TOV (Tachyon
- // has only 16 bits for ms timer, so the max is 65.5 sec)
- else if( (fcChip->Registers.ed_tov.value &0xFFFF) <= 0x5DC1)
- fcChip->Registers.ed_tov.value = 0x0065FFFF;
-
- writel( fcChip->Registers.ed_tov.value,
- (fcChip->Registers.ed_tov.address));
- // keep the same 2sec LP_TOV
- writel( 0x07D00010, fcChip->Registers.ReMapMemBase +TL_MEM_FM_TIMEOUT2);
-}
-
-
-// The IMQ is an array with IMQ_LEN length, each element (QEntry)
-// with eight 32-bit words. Tachyon PRODUCES a QEntry with each
-// message it wants to send to the host. The host CONSUMES IMQ entries
-
-// This function copies the current
-// (or oldest not-yet-processed) QEntry to
-// the caller, clears/ re-enables the interrupt, and updates the
-// (Host) Consumer Index.
-// Return value:
-// 0 message processed, none remain (producer and consumer
-// indexes match)
-// 1 message processed, more messages remain
-// -1 no message processed - none were available to process
-// Remarks:
-// TL/TS UG specifices that the following actions for
-// INTA_L handling:
-// 1. read PCI Interrupt Status register (0xff)
-// 2. all IMQ messages should be processed before writing the
-// IMQ consumer index.
-
-
-int CpqTsProcessIMQEntry(void *host)
-{
- struct Scsi_Host *HostAdapter = (struct Scsi_Host *)host;
- CPQFCHBA *cpqfcHBAdata = (CPQFCHBA *)HostAdapter->hostdata;
- PTACHYON fcChip = &cpqfcHBAdata->fcChip;
- FC_EXCHANGES *Exchanges = fcChip->Exchanges;
- int iStatus;
- USHORT i, RPCset, DPCset;
- ULONG x_ID;
- ULONG ulBuff, dwStatus;
- TachFCHDR_GCMND* fchs;
-#error This is too much stack
- ULONG ulFibreFrame[2048/4]; // max number of DWORDS in incoming Fibre Frame
- UCHAR ucInboundMessageType; // Inbound CM, dword 3 "type" field
-
- ENTER("ProcessIMQEntry");
-
-
- // check TachLite's IMQ producer index -
- // is a new message waiting for us?
- // equal indexes means empty que
-
- if( fcChip->IMQ->producerIndex != fcChip->IMQ->consumerIndex )
- { // need to process message
-
-
-#ifdef IMQ_DEBUG
- printk("PI %X, CI %X type: %X\n",
- fcChip->IMQ->producerIndex,fcChip->IMQ->consumerIndex,
- fcChip->IMQ->QEntry[fcChip->IMQ->consumerIndex].type);
-#endif
- // Examine Completion Messages in IMQ
- // what CM_Type?
- switch( (UCHAR)(fcChip->IMQ->QEntry[fcChip->IMQ->consumerIndex].type
- & 0xffL) )
- {
- case OUTBOUND_COMPLETION:
-
- // Remarks:
- // x_IDs (OX_ID, RX_ID) are partitioned by SEST entries
- // (starting at 0), and SFS entries (starting at
- // SEST_LEN -- outside the SEST space).
- // Psuedo code:
- // x_ID (OX_ID or RX_ID) from message is Trans_ID or SEST index
- // range check - x_ID
- // if x_ID outside 'Transactions' length, error - exit
- // if any OCM error, copy error status to Exchange slot
- // if FCP ASSIST transaction (x_ID within SEST),
- // call fcComplete (to App)
- // ...
-
-
- ulBuff = fcChip->IMQ->QEntry[fcChip->IMQ->consumerIndex].word[1];
- x_ID = ulBuff & 0x7fffL; // lower 14 bits SEST_Index/Trans_ID
- // Range check CM OX/RX_ID value...
- if( x_ID < TACH_MAX_XID ) // don't go beyond array space
- {
-
-
- if( ulBuff & 0x20000000L ) // RPC -Response Phase Complete?
- RPCset = 1; // (SEST transactions only)
- else
- RPCset = 0;
-
- if( ulBuff & 0x40000000L ) // DPC -Data Phase Complete?
- DPCset = 1; // (SEST transactions only)
- else
- DPCset = 0;
- // set the status for this Outbound transaction's ID
- dwStatus = 0L;
- if( ulBuff & 0x10000000L ) // SPE? (SEST Programming Error)
- dwStatus |= SESTPROG_ERR;
-
- ulBuff = fcChip->IMQ->QEntry[fcChip->IMQ->consumerIndex].word[2];
- if( ulBuff & 0x7a000000L ) // any other errs?
- {
- if( ulBuff & 0x40000000L )
- dwStatus |= INV_ENTRY;
- if( ulBuff & 0x20000000L )
- dwStatus |= FRAME_TO; // FTO
- if( ulBuff & 0x10000000L )
- dwStatus |= HOSTPROG_ERR;
- if( ulBuff & 0x08000000L )
- dwStatus |= LINKFAIL_TX;
- if( ulBuff & 0x02000000L )
- dwStatus |= ABORTSEQ_NOTIFY; // ASN
- }
-
-
- if( dwStatus ) // any errors?
- {
- // set the Outbound Completion status
- Exchanges->fcExchange[ x_ID ].status |= dwStatus;
-
- // if this Outbound frame was for a SEST entry, automatically
- // reque it in the case of LINKFAIL (it will restart on PDISC)
- if( x_ID < TACH_SEST_LEN )
- {
-
- printk(" #OCM error %Xh x_ID %X# ",
- dwStatus, x_ID);
-
- Exchanges->fcExchange[x_ID].timeOut = 30000; // seconds default
-
-
- // We Q ABTS for each exchange.
- // NOTE: We can get FRAME_TO on bad alpa (device gone). Since
- // bad alpa is reported before FRAME_TO, examine the status
- // flags to see if the device is removed. If so, DON'T
- // post an ABTS, since it will be terminated by the bad alpa
- // message.
- if( dwStatus & FRAME_TO ) // check for device removed...
- {
- if( !(Exchanges->fcExchange[x_ID].status & DEVICE_REMOVED) )
- {
- // presumes device is still there: send ABTS.
-
- cpqfcTSPutLinkQue( cpqfcHBAdata, BLS_ABTS, &x_ID);
- }
- }
- else // Abort all other errors
- {
- cpqfcTSPutLinkQue( cpqfcHBAdata, BLS_ABTS, &x_ID);
- }
-
- // if the HPE bit is set, we have to CLose the LOOP
- // (see TL/TS UG, pg. 239)
-
- if( dwStatus &= HOSTPROG_ERR )
- // set CL bit (see TL/TS UG, pg. 172)
- writel( 4, fcChip->Registers.FMcontrol.address);
- }
- }
- // NOTE: we don't necessarily care about ALL completion messages...
- // SCSI resp. complete OR
- if( ((x_ID < TACH_SEST_LEN) && RPCset)||
- (x_ID >= TACH_SEST_LEN) ) // non-SCSI command
- {
- // exchange done; complete to upper levels with status
- // (if necessary) and free the exchange slot
-
-
- if( x_ID >= TACH_SEST_LEN ) // Link Service Outbound frame?
- // A Request or Reply has been sent
- { // signal waiting WorkerThread
-
- up( cpqfcHBAdata->TYOBcomplete); // frame is OUT of Tach
-
- // WorkerThread will complete Xchng
- }
- else // X_ID is for FCP assist (SEST)
- {
- // TBD (target mode)
-// fcCompleteExchange( fcChip, x_ID); // TRE completed
- }
- }
- }
- else // ERROR CONDITION! bogus x_ID in completion message
- {
-
- printk(" ProcessIMQ (OBCM) x_id out of range %Xh\n", x_ID);
-
- }
-
-
-
- // Load the Frame Manager's error counters. We check them here
- // because presumably the link is up and healthy enough for the
- // counters to be meaningful (i.e., don't check them while loop
- // is initializing).
- fcChip->Registers.FMLinkStatus1.value = // get TL's counter
- readl(fcChip->Registers.FMLinkStatus1.address);
-
- fcChip->Registers.FMLinkStatus2.value = // get TL's counter
- readl(fcChip->Registers.FMLinkStatus2.address);
-
-
- fcParseLinkStatusCounters( fcChip); // load into 6 s/w accumulators
- break;
-
-
-
- case ERROR_IDLE_COMPLETION: // TachLite Error Idle...
-
- // We usually get this when the link goes down during heavy traffic.
- // For now, presume that if SEST Exchanges are open, we will
- // get this as our cue to INVALIDATE all SEST entries
- // (and we OWN all the SEST entries).
- // See TL/TS UG, pg. 53
-
- for( x_ID = 0; x_ID < TACH_SEST_LEN; x_ID++)
- {
-
- // Does this VALid SEST entry need to be invalidated for Abort?
- fcChip->SEST->u[ x_ID].IWE.Hdr_Len &= 0x7FFFFFFF;
- }
-
- CpqTsUnFreezeTachlite( fcChip, 2); // unfreeze Tachyon, if Link OK
-
- break;
-
-
- case INBOUND_SFS_COMPLETION: //0x04
- // NOTE! we must process this SFQ message to avoid SFQ filling
- // up and stopping TachLite. Incoming commands are placed here,
- // as well as 'unknown' frames (e.g. LIP loop position data)
- // write this CM's producer index to global...
- // TL/TS UG, pg 234:
- // Type: 0 - reserved
- // 1 - Unassisted FCP
- // 2 - BAD FCP
- // 3 - Unkown Frame
- // 4-F reserved
-
-
- fcChip->SFQ->producerIndex = (USHORT)
- (fcChip->IMQ->QEntry[fcChip->IMQ->consumerIndex].word[0] & 0x0fffL);
-
-
- ucInboundMessageType = 0; // default to useless frame
-
- // we can only process two Types: 1, Unassisted FCP, and 3, Unknown
- // Also, we aren't interested in processing frame fragments
- // so don't Que anything with 'LKF' bit set
- if( !(fcChip->IMQ->QEntry[fcChip->IMQ->consumerIndex].word[2]
- & 0x40000000) ) // 'LKF' link failure bit clear?
- {
- ucInboundMessageType = (UCHAR) // ICM DWord3, "Type"
- (fcChip->IMQ->QEntry[fcChip->IMQ->consumerIndex].word[2] & 0x0fL);
- }
- else
- {
- fcChip->fcStats.linkFailRX++;
-// printk("LKF (link failure) bit set on inbound message\n");
- }
-
- // clears SFQ entry from Tachyon buffer; copies to contiguous ulBuff
- CpqTsGetSFQEntry(
- fcChip, // i.e. this Device Object
- (USHORT)fcChip->SFQ->producerIndex, // SFQ producer ndx
- ulFibreFrame, TRUE); // contiguous destination buffer, update chip
-
- // analyze the incoming frame outside the INT handler...
- // (i.e., Worker)
-
- if( ucInboundMessageType == 1 )
- {
- fchs = (TachFCHDR_GCMND*)ulFibreFrame; // cast to examine IB frame
- // don't fill up our Q with garbage - only accept FCP-CMND
- // or XRDY frames
- if( (fchs->d_id & 0xFF000000) == 0x06000000 ) // CMND
- {
- // someone sent us a SCSI command
-
-// fcPutScsiQue( cpqfcHBAdata,
-// SFQ_UNASSISTED_FCP, ulFibreFrame);
- }
- else if( ((fchs->d_id & 0xFF000000) == 0x07000000) || // RSP (status)
- (fchs->d_id & 0xFF000000) == 0x05000000 ) // XRDY
- {
- ULONG x_ID;
- // Unfortunately, ABTS requires a Freeze on the chip so
- // we can modify the shared memory SEST. When frozen,
- // any received Exchange frames cannot be processed by
- // Tachyon, so they will be dumped in here. It is too
- // complex to attempt the reconstruct these frames in
- // the correct Exchange context, so we simply seek to
- // find status or transfer ready frames, and cause the
- // exchange to complete with errors before the timeout
- // expires. We use a Linux Scsi Cmnd result code that
- // causes immediate retry.
-
-
- // Do we have an open exchange that matches this s_id
- // and ox_id?
- for( x_ID = 0; x_ID < TACH_SEST_LEN; x_ID++)
- {
- if( (fchs->s_id & 0xFFFFFF) ==
- (Exchanges->fcExchange[x_ID].fchs.d_id & 0xFFFFFF)
- &&
- (fchs->ox_rx_id & 0xFFFF0000) ==
- (Exchanges->fcExchange[x_ID].fchs.ox_rx_id & 0xFFFF0000) )
- {
- // printk(" #R/X frame x_ID %08X# ", fchs->ox_rx_id );
- // simulate the anticipated error - since the
- // SEST was frozen, frames were lost...
- Exchanges->fcExchange[ x_ID ].status |= SFQ_FRAME;
-
- // presumes device is still there: send ABTS.
- cpqfcTSPutLinkQue( cpqfcHBAdata, BLS_ABTS, &x_ID);
- break; // done
- }
- }
- }
-
- }
-
- else if( ucInboundMessageType == 3)
- {
- // FC Link Service frames (e.g. PLOGI, ACC) come in here.
- cpqfcTSPutLinkQue( cpqfcHBAdata, SFQ_UNKNOWN, ulFibreFrame);
-
- }
-
- else if( ucInboundMessageType == 2 ) // "bad FCP"?
- {
-#ifdef IMQ_DEBUG
- printk("Bad FCP incoming frame discarded\n");
-#endif
- }
-
- else // don't know this type
- {
-#ifdef IMQ_DEBUG
- printk("Incoming frame discarded, type: %Xh\n", ucInboundMessageType);
-#endif
- }
-
- // Check the Frame Manager's error counters. We check them here
- // because presumably the link is up and healthy enough for the
- // counters to be meaningful (i.e., don't check them while loop
- // is initializing).
- fcChip->Registers.FMLinkStatus1.value = // get TL's counter
- readl(fcChip->Registers.FMLinkStatus1.address);
-
-
- fcChip->Registers.FMLinkStatus2.value = // get TL's counter
- readl(fcChip->Registers.FMLinkStatus2.address);
-
-
- break;
-
-
-
-
- // We get this CM because we issued a freeze
- // command to stop outbound frames. We issue the
- // freeze command at Link Up time; when this message
- // is received, the ERQ base can be switched and PDISC
- // frames can be sent.
-
-
- case ERQ_FROZEN_COMPLETION: // note: expect ERQ followed immediately
- // by FCP when freezing TL
- fcChip->Registers.TYstatus.value = // read what's frozen
- readl(fcChip->Registers.TYstatus.address);
- // (do nothing; wait for FCP frozen message)
- break;
- case FCP_FROZEN_COMPLETION:
-
- fcChip->Registers.TYstatus.value = // read what's frozen
- readl(fcChip->Registers.TYstatus.address);
-
- // Signal the kernel thread to proceed with SEST modification
- up( cpqfcHBAdata->TachFrozen);
-
- break;
-
-
-
- case INBOUND_C1_TIMEOUT:
- case MFS_BUF_WARN:
- case IMQ_BUF_WARN:
- break;
-
-
-
-
-
- // In older Tachyons, we 'clear' the internal 'core' interrupt state
- // by reading the FMstatus register. In newer TachLite (Tachyon),
- // we must WRITE the register
- // to clear the condition (TL/TS UG, pg 179)
- case FRAME_MGR_INTERRUPT:
- {
- PFC_LOGGEDIN_PORT pLoggedInPort;
-
- fcChip->Registers.FMstatus.value =
- readl( fcChip->Registers.FMstatus.address );
-
- // PROBLEM: It is possible, especially with "dumb" hubs that
- // don't automatically LIP on by-pass of ports that are going
- // away, for the hub by-pass process to destroy critical
- // ordered sets of a frame. The result of this is a hung LPSM
- // (Loop Port State Machine), which on Tachyon results in a
- // (default 2 sec) Loop State Timeout (LST) FM message. We
- // want to avoid this relatively huge timeout by detecting
- // likely scenarios which will result in LST.
- // To do this, we could examine FMstatus for Loss of Synchronization
- // and/or Elastic Store (ES) errors. Of these, Elastic Store is better
- // because we get this indication more quickly than the LOS.
- // Not all ES errors are harmfull, so we don't want to LIP on every
- // ES. Instead, on every ES, detect whether our LPSM in in one
- // of the LST states: ARBITRATING, OPEN, OPENED, XMITTED CLOSE,
- // or RECEIVED CLOSE. (See TL/TS UG, pg. 181)
- // If any of these LPSM states are detected
- // in combination with the LIP while LDn is not set,
- // send an FM init (LIP F7,F7 for loops)!
- // It is critical to the physical link stability NOT to reset (LIP)
- // more than absolutely necessary; this is a basic premise of the
- // SANMark level 1 spec.
- {
- ULONG Lpsm = (fcChip->Registers.FMstatus.value & 0xF0) >>4;
-
- if( (fcChip->Registers.FMstatus.value & 0x400) // ElasticStore?
- &&
- !(fcChip->Registers.FMstatus.value & 0x100) // NOT LDn
- &&
- !(fcChip->Registers.FMstatus.value & 0x1000)) // NOT LF
- {
- if( (Lpsm != 0) || // not MONITORING? or
- !(Lpsm & 0x8) )// not already offline?
- {
- // now check the particular LST states...
- if( (Lpsm == ARBITRATING) || (Lpsm == OPEN) ||
- (Lpsm == OPENED) || (Lpsm == XMITTD_CLOSE) ||
- (Lpsm == RCVD_CLOSE) )
- {
- // re-init the loop before it hangs itself!
- printk(" #req FMinit on E-S: LPSM %Xh# ",Lpsm);
-
-
- fcChip->fcStats.FMinits++;
- writel( 6, fcChip->Registers.FMcontrol.address); // LIP
- }
- }
- }
- else if( fcChip->Registers.FMstatus.value & 0x40000 ) // LST?
- {
- printk(" #req FMinit on LST, LPSM %Xh# ",Lpsm);
-
- fcChip->fcStats.FMinits++;
- writel( 6, fcChip->Registers.FMcontrol.address); // LIP
- }
- }
-
-
- // clear only the 'interrupting' type bits for this REG read
- writel( (fcChip->Registers.FMstatus.value & 0xff3fff00L),
- fcChip->Registers.FMstatus.address);
-
-
- // copy frame manager status to unused ULONG slot
- fcChip->IMQ->QEntry[fcChip->IMQ->consumerIndex].word[0] =
- fcChip->Registers.FMstatus.value; // (for debugging)
-
-
- // Load the Frame Manager's error counters. We check them here
- // because presumably the link is up and healthy enough for the
- // counters to be meaningful (i.e., don't check them while loop
- // is initializing).
- fcChip->Registers.FMLinkStatus1.value = // get TL's counter
- readl(fcChip->Registers.FMLinkStatus1.address);
-
- fcChip->Registers.FMLinkStatus2.value = // get TL's counter
- readl(fcChip->Registers.FMLinkStatus2.address);
-
- // Get FM BB_Credit Zero Reg - does not clear on READ
- fcChip->Registers.FMBB_CreditZero.value = // get TL's counter
- readl(fcChip->Registers.FMBB_CreditZero.address);
-
-
-
- fcParseLinkStatusCounters( fcChip); // load into 6 s/w accumulators
-
-
- // LINK DOWN
-
- if( fcChip->Registers.FMstatus.value & 0x100L ) // Link DOWN bit
- {
-
-#ifdef IMQ_DEBUG
- printk("LinkDn\n");
-#endif
- printk(" #LDn# ");
-
- fcChip->fcStats.linkDown++;
-
- SetTachTOV( cpqfcHBAdata); // must set according to SANMark
-
- // Check the ERQ - force it to be "empty" to prevent Tach
- // from sending out frames before we do logins.
-
-
- if( fcChip->ERQ->producerIndex != fcChip->ERQ->consumerIndex)
- {
-// printk("#ERQ PI != CI#");
- CpqTsFreezeTachlite( fcChip, 1); // freeze ERQ only
- fcChip->ERQ->producerIndex = fcChip->ERQ->consumerIndex = 0;
- writel( fcChip->ERQ->base,
- (fcChip->Registers.ReMapMemBase + TL_MEM_ERQ_BASE));
- // re-writing base forces ERQ PI to equal CI
-
- }
-
- // link down transition occurred -- port_ids can change
- // on next LinkUp, so we must invalidate current logins
- // (and any I/O in progress) until PDISC or PLOGI/PRLI
- // completes
- {
- pLoggedInPort = &fcChip->fcPorts;
- while( pLoggedInPort ) // for all ports which are expecting
- // PDISC after the next LIP, set the
- // logoutTimer
- {
-
- if( pLoggedInPort->pdisc) // expecting PDISC within 2 sec?
- {
- pLoggedInPort->LOGO_timer = 3; // we want 2 seconds
- // but Timer granularity
- // is 1 second
- }
- // suspend any I/O in progress until
- // PDISC received...
- pLoggedInPort->prli = FALSE; // block FCP-SCSI commands
-
- pLoggedInPort = pLoggedInPort->pNextPort;
- } // ... all Previously known ports checked
- }
-
- // since any hot plugging device may NOT support LILP frames
- // (such as early Tachyon chips), clear this flag indicating
- // we shouldn't use (our copy of) a LILP map.
- // If we receive an LILP frame, we'll set it again.
- fcChip->Options.LILPin = 0; // our LILPmap is invalid
- cpqfcHBAdata->PortDiscDone = 0; // must re-validate FC ports!
-
- // also, we want to invalidate (i.e. INITIATOR_ABORT) any
- // open Login exchanges, in case the LinkDown happened in the
- // middle of logins. It's possible that some ports already
- // ACCepted login commands which we have not processed before
- // another LinkDown occurred. Any accepted Login exhanges are
- // invalidated by LinkDown, even before they are acknowledged.
- // It's also possible for a port to have a Queued Reply or Request
- // for login which was interrupted by LinkDown; it may come later,
- // but it will be unacceptable to us.
-
- // we must scan the entire exchange space, find every Login type
- // originated by us, and abort it. This is NOT an abort due to
- // timeout, so we don't actually send abort to the other port -
- // we just complete it to free up the fcExchange slot.
-
- for( i=TACH_SEST_LEN; i< TACH_MAX_XID; i++)
- { // looking for Extended Link Serv.Exchanges
- if( Exchanges->fcExchange[i].type == ELS_PDISC ||
- Exchanges->fcExchange[i].type == ELS_PLOGI ||
- Exchanges->fcExchange[i].type == ELS_PRLI )
- {
- // ABORT the exchange!
-#ifdef IMQ_DEBUG
- printk("Originator ABORT x_id %Xh, type %Xh, port_id %Xh on LDn\n",
- i, Exchanges->fcExchange[i].type,
- Exchanges->fcExchange[i].fchs.d_id);
-#endif
-
- Exchanges->fcExchange[i].status |= INITIATOR_ABORT;
- cpqfcTSCompleteExchange( cpqfcHBAdata->PciDev, fcChip, i); // abort on LDn
- }
- }
-
- }
-
- // ################ LINK UP ##################
- if( fcChip->Registers.FMstatus.value & 0x200L ) // Link Up bit
- { // AL_PA could have changed
-
- // We need the following code, duplicated from LinkDn condition,
- // because it's possible for the Tachyon to re-initialize (hard
- // reset) without ever getting a LinkDn indication.
- pLoggedInPort = &fcChip->fcPorts;
- while( pLoggedInPort ) // for all ports which are expecting
- // PDISC after the next LIP, set the
- // logoutTimer
- {
- if( pLoggedInPort->pdisc) // expecting PDISC within 2 sec?
- {
- pLoggedInPort->LOGO_timer = 3; // we want 2 seconds
- // but Timer granularity
- // is 1 second
-
- // suspend any I/O in progress until
- // PDISC received...
-
- }
- pLoggedInPort = pLoggedInPort->pNextPort;
- } // ... all Previously known ports checked
-
- // CpqTs acquired AL_PA in register AL_PA (ACQ_ALPA)
- fcChip->Registers.rcv_al_pa.value =
- readl(fcChip->Registers.rcv_al_pa.address);
-
- // Now, if our acquired address is DIFFERENT from our
- // previous one, we are not allow to do PDISC - we
- // must go back to PLOGI, which will terminate I/O in
- // progress for ALL logged in FC devices...
- // (This is highly unlikely).
-
- if( (fcChip->Registers.my_al_pa & 0xFF) !=
- ((fcChip->Registers.rcv_al_pa.value >> 16) &0xFF) )
- {
-
-// printk(" #our HBA port_id changed!# "); // FC port_id changed!!
-
- pLoggedInPort = &fcChip->fcPorts;
- while( pLoggedInPort ) // for all ports which are expecting
- // PDISC after the next LIP, set the
- // logoutTimer
- {
- pLoggedInPort->pdisc = FALSE;
- pLoggedInPort->prli = FALSE;
- pLoggedInPort = pLoggedInPort->pNextPort;
- } // ... all Previously known ports checked
-
- // when the port_id changes, we must terminate
- // all open exchanges.
- cpqfcTSTerminateExchange( cpqfcHBAdata, NULL, PORTID_CHANGED);
-
- }
-
- // Replace the entire 24-bit port_id. We only know the
- // lower 8 bits (alpa) from Tachyon; if a FLOGI is done,
- // we'll get the upper 16-bits from the FLOGI ACC frame.
- // If someone plugs into Fabric switch, we'll do FLOGI and
- // get full 24-bit port_id; someone could then remove and
- // hot-plug us into a dumb hub. If we send a 24-bit PLOGI
- // to a "private" loop device, it might blow up.
- // Consequently, we force the upper 16-bits of port_id to
- // be re-set on every LinkUp transition
- fcChip->Registers.my_al_pa =
- (fcChip->Registers.rcv_al_pa.value >> 16) & 0xFF;
-
-
- // copy frame manager status to unused ULONG slot
- fcChip->IMQ->QEntry[fcChip->IMQ->consumerIndex].word[1] =
- fcChip->Registers.my_al_pa; // (for debugging)
-
- // for TachLite, we need to write the acquired al_pa
- // back into the FMconfig register, because after
- // first initialization, the AQ (prev. acq.) bit gets
- // set, causing TL FM to use the AL_PA field in FMconfig.
- // (In Tachyon, FM writes the acquired AL_PA for us.)
- ulBuff = readl( fcChip->Registers.FMconfig.address);
- ulBuff &= 0x00ffffffL; // mask out current al_pa
- ulBuff |= ( fcChip->Registers.my_al_pa << 24 ); // or in acq. al_pa
- fcChip->Registers.FMconfig.value = ulBuff; // copy it back
- writel( fcChip->Registers.FMconfig.value, // put in TachLite
- fcChip->Registers.FMconfig.address);
-
-
-#ifdef IMQ_DEBUG
- printk("#LUp %Xh, FMstat 0x%08X#",
- fcChip->Registers.my_al_pa, fcChip->Registers.FMstatus.value);
-#endif
-
- // also set the WRITE-ONLY My_ID Register (for Fabric
- // initialization)
- writel( fcChip->Registers.my_al_pa,
- fcChip->Registers.ReMapMemBase +TL_MEM_TACH_My_ID);
-
-
- fcChip->fcStats.linkUp++;
-
- // reset TL statistics counters
- // (we ignore these error counters
- // while link is down)
- ulBuff = // just reset TL's counter
- readl( fcChip->Registers.FMLinkStatus1.address);
-
- ulBuff = // just reset TL's counter
- readl( fcChip->Registers.FMLinkStatus2.address);
-
- // for initiator, need to start verifying ports (e.g. PDISC)
-
-
-
-
-
-
- CpqTsUnFreezeTachlite( fcChip, 2); // unfreeze Tachlite, if Link OK
-
- // Tachyon creates an interesting problem for us on LILP frames.
- // Instead of writing the incoming LILP frame into the SFQ before
- // indicating LINK UP (the actual order of events), Tachyon tells
- // us LINK UP, and later us the LILP. So we delay, then examine the
- // IMQ for an Inbound CM (x04); if found, we can set
- // LINKACTIVE after processing the LILP. Otherwise, just proceed.
- // Since Tachyon imposes this time delay (and doesn't tell us
- // what it is), we have to impose a delay before "Peeking" the IMQ
- // for Tach hardware (DMA) delivery.
- // Processing LILP is required by SANMark
- udelay( 1000); // microsec delay waiting for LILP (if it comes)
- if( PeekIMQEntry( fcChip, ELS_LILP_FRAME) )
- { // found SFQ LILP, which will post LINKACTIVE
-// printk("skipping LINKACTIVE post\n");
-
- }
- else
- cpqfcTSPutLinkQue( cpqfcHBAdata, LINKACTIVE, ulFibreFrame);
- }
-
-
-
- // ******* Set Fabric Login indication ********
- if( fcChip->Registers.FMstatus.value & 0x2000 )
- {
- printk(" #Fabric# ");
- fcChip->Options.fabric = 1;
- }
- else
- fcChip->Options.fabric = 0;
-
-
-
- // ******* LIP(F8,x) or BAD AL_PA? ********
- if( fcChip->Registers.FMstatus.value & 0x30000L )
- {
- // copy the error AL_PAs
- fcChip->Registers.rcv_al_pa.value =
- readl(fcChip->Registers.rcv_al_pa.address);
-
- // Bad AL_PA?
- if( fcChip->Registers.FMstatus.value & 0x10000L )
- {
- PFC_LOGGEDIN_PORT pLoggedInPort;
-
- // copy "BAD" al_pa field
- fcChip->IMQ->QEntry[fcChip->IMQ->consumerIndex].word[1] =
- (fcChip->Registers.rcv_al_pa.value & 0xff00L) >> 8;
-
- pLoggedInPort = fcFindLoggedInPort( fcChip,
- NULL, // DON'T search Scsi Nexus
- fcChip->IMQ->QEntry[fcChip->IMQ->consumerIndex].word[1], // port id
- NULL, // DON'T search linked list for FC WWN
- NULL); // DON'T care about end of list
-
- if( pLoggedInPort )
- {
- // Just in case we got this BAD_ALPA because a device
- // quietly disappeared (can happen on non-managed hubs such
- // as the Vixel Rapport 1000),
- // do an Implicit Logout. We never expect this on a Logged
- // in port (but do expect it on port discovery).
- // (As a reasonable alternative, this could be changed to
- // simply start the implicit logout timer, giving the device
- // several seconds to "come back".)
- //
- printk(" #BAD alpa %Xh# ",
- fcChip->IMQ->QEntry[fcChip->IMQ->consumerIndex].word[1]);
- cpqfcTSImplicitLogout( cpqfcHBAdata, pLoggedInPort);
- }
- }
- // LIP(f8,x)?
- if( fcChip->Registers.FMstatus.value & 0x20000L )
- {
- // for debugging, copy al_pa field
- fcChip->IMQ->QEntry[fcChip->IMQ->consumerIndex].word[2] =
- (fcChip->Registers.rcv_al_pa.value & 0xffL);
- // get the other port's al_pa
- // (one that sent LIP(F8,?) )
- }
- }
-
- // Elastic store err
- if( fcChip->Registers.FMstatus.value & 0x400L )
- {
- // don't count e-s if loop is down!
- if( !(USHORT)(fcChip->Registers.FMstatus.value & 0x80) )
- fcChip->fcStats.e_stores++;
-
- }
- }
- break;
-
-
- case INBOUND_FCP_XCHG_COMPLETION: // 0x0C
-
- // Remarks:
- // On Tachlite TL/TS, we get this message when the data phase
- // of a SEST inbound transfer is complete. For example, if a WRITE command
- // was received with OX_ID 0, we might respond with XFER_RDY with
- // RX_ID 8001. This would start the SEST controlled data phases. When
- // all data frames are received, we get this inbound completion. This means
- // we should send a status frame to complete the status phase of the
- // FCP-SCSI exchange, using the same OX_ID,RX_ID that we used for data
- // frames.
- // See Outbound CM discussion of x_IDs
- // Psuedo Code
- // Get SEST index (x_ID)
- // x_ID out of range, return (err condition)
- // set status bits from 2nd dword
- // free transactionID & SEST entry
- // call fcComplete with transactionID & status
-
- ulBuff = fcChip->IMQ->QEntry[fcChip->IMQ->consumerIndex].word[0];
- x_ID = ulBuff & 0x7fffL; // lower 14 bits SEST_Index/Trans_ID
- // (mask out MSB "direction" bit)
- // Range check CM OX/RX_ID value...
- if( x_ID < TACH_SEST_LEN ) // don't go beyond SEST array space
- {
-
-//#define FCP_COMPLETION_DBG 1
-#ifdef FCP_COMPLETION_DBG
- printk(" FCP_CM x_ID %Xh, status %Xh, Cmnd %p\n",
- x_ID, ulBuff, Exchanges->fcExchange[x_ID].Cmnd);
-#endif
- if( ulBuff & 0x08000000L ) // RPC -Response Phase Complete - or -
- // time to send response frame?
- RPCset = 1; // (SEST transaction)
- else
- RPCset = 0;
- // set the status for this Inbound SCSI transaction's ID
- dwStatus = 0L;
- if( ulBuff & 0x70000000L ) // any errs?
- {
-
- if( ulBuff & 0x40000000L )
- dwStatus |= LINKFAIL_RX;
-
- if( ulBuff & 0x20000000L )
- dwStatus |= COUNT_ERROR;
-
- if( ulBuff & 0x10000000L )
- dwStatus |= OVERFLOW;
- }
-
-
- // FCP transaction done - copy status
- Exchanges->fcExchange[ x_ID ].status = dwStatus;
-
-
- // Did the exchange get an FCP-RSP response frame?
- // (Note the little endian/big endian FC payload difference)
-
- if( RPCset ) // SEST transaction Response frame rec'd
- {
- // complete the command in our driver...
- cpqfcTSCompleteExchange( cpqfcHBAdata->PciDev,fcChip, x_ID);
-
- } // end "RPCset"
-
- else // ("target" logic)
- {
- // Tachlite says all data frames have been received - now it's time
- // to analyze data transfer (successful?), then send a response
- // frame for this exchange
-
- ulFibreFrame[0] = x_ID; // copy for later reference
-
- // if this was a TWE, we have to send satus response
- if( Exchanges->fcExchange[ x_ID].type == SCSI_TWE )
- {
-// fcPutScsiQue( cpqfcHBAdata,
-// NEED_FCP_RSP, ulFibreFrame); // (ulFibreFrame not used here)
- }
- }
- }
- else // ERROR CONDITION! bogus x_ID in completion message
- {
- printk("IN FCP_XCHG: bad x_ID: %Xh\n", x_ID);
- }
-
- break;
-
-
-
-
- case INBOUND_SCSI_DATA_COMMAND:
- case BAD_SCSI_FRAME:
- case INB_SCSI_STATUS_COMPLETION:
- case BUFFER_PROCESSED_COMPLETION:
- break;
- }
-
- // Tachyon is producing;
- // we are consuming
- fcChip->IMQ->consumerIndex++; // increment OUR consumerIndex
- if( fcChip->IMQ->consumerIndex >= IMQ_LEN)// check for rollover
- fcChip->IMQ->consumerIndex = 0L; // reset it
-
-
- if( fcChip->IMQ->producerIndex == fcChip->IMQ->consumerIndex )
- { // all Messages are processed -
- iStatus = 0; // no more messages to process
-
- }
- else
- iStatus = 1; // more messages to process
-
- // update TachLite's ConsumerIndex... (clears INTA_L)
- // NOTE: according to TL/TS UG, the
- // "host must return completion messages in sequential order".
- // Does this mean one at a time, in the order received? We
- // presume so.
-
- writel( fcChip->IMQ->consumerIndex,
- (fcChip->Registers.ReMapMemBase + IMQ_CONSUMER_INDEX));
-
-#if IMQ_DEBUG
- printk("Process IMQ: writing consumer ndx %d\n ",
- fcChip->IMQ->consumerIndex);
- printk("PI %X, CI %X\n",
- fcChip->IMQ->producerIndex,fcChip->IMQ->consumerIndex );
-#endif
-
-
-
- }
- else
- {
- // hmmm... why did we get interrupted/called with no message?
- iStatus = -1; // nothing to process
-#if IMQ_DEBUG
- printk("Process IMQ: no message PI %Xh CI %Xh",
- fcChip->IMQ->producerIndex,
- fcChip->IMQ->consumerIndex);
-#endif
- }
-
- LEAVE("ProcessIMQEntry");
-
- return iStatus;
-}
-
-
-
-
-
-// This routine initializes Tachyon according to the following
-// options (opcode1):
-// 1 - RESTART Tachyon, simulate power on condition by shutting
-// down laser, resetting the hardware, de-allocating all buffers;
-// continue
-// 2 - Config Tachyon / PCI registers;
-// continue
-// 3 - Allocating memory and setting Tachyon queues (write Tachyon regs);
-// continue
-// 4 - Config frame manager registers, initialize, turn on laser
-//
-// Returns:
-// -1 on fatal error
-// 0 on success
-
-int CpqTsInitializeTachLite( void *pHBA, int opcode1, int opcode2)
-{
- CPQFCHBA *cpqfcHBAdata = (CPQFCHBA*)pHBA;
- PTACHYON fcChip = &cpqfcHBAdata->fcChip;
- ULONG ulBuff;
- UCHAR bBuff;
- int iStatus=-1; // assume failure
-
- ENTER("InitializeTachLite");
-
- // verify board's base address (sanity check)
-
- if( !fcChip->Registers.ReMapMemBase) // NULL address for card?
- return -1; // FATAL error!
-
-
-
- switch( opcode1 )
- {
- case 1: // restore hardware to power-on (hard) restart
-
-
- iStatus = fcChip->ResetTachyon(
- cpqfcHBAdata, opcode2); // laser off, reset hardware
- // de-allocate aligned buffers
-
-
-/* TBD // reset FC link Q (producer and consumer = 0)
- fcLinkQReset(cpqfcHBAdata);
-
-*/
-
- if( iStatus )
- break;
-
- case 2: // Config PCI/Tachyon registers
- // NOTE: For Tach TL/TS, bit 31 must be set to 1. For TS chips, a read
- // of bit 31 indicates state of M66EN signal; if 1, chip may run at
- // 33-66MHz (see TL/TS UG, pg 159)
-
- ulBuff = 0x80000000; // TachLite Configuration Register
-
- writel( ulBuff, fcChip->Registers.TYconfig.address);
-// ulBuff = 0x0147L; // CpqTs PCI CFGCMD register
-// WritePCIConfiguration( fcChip->Backplane.bus,
-// fcChip->Backplane.slot, TLCFGCMD, ulBuff, 4);
-// ulBuff = 0x0L; // test!
-// ReadPCIConfiguration( fcChip->Backplane.bus,
-// fcChip->Backplane.slot, TLCFGCMD, &ulBuff, 4);
-
- // read back for reference...
- fcChip->Registers.TYconfig.value =
- readl( fcChip->Registers.TYconfig.address );
-
- // what is the PCI bus width?
- pci_read_config_byte( cpqfcHBAdata->PciDev,
- 0x43, // PCIMCTR offset
- &bBuff);
-
- fcChip->Registers.PCIMCTR = bBuff;
-
- // set string identifying the chip on the circuit board
-
- fcChip->Registers.TYstatus.value =
- readl( fcChip->Registers.TYstatus.address);
-
- {
-// Now that we are supporting multiple boards, we need to change
-// this logic to check for PCI vendor/device IDs...
-// for now, quick & dirty is simply checking Chip rev
-
- ULONG RevId = (fcChip->Registers.TYstatus.value &0x3E0)>>5;
- UCHAR Minor = (UCHAR)(RevId & 0x3);
- UCHAR Major = (UCHAR)((RevId & 0x1C) >>2);
-
- /* printk(" HBA Tachyon RevId %d.%d\n", Major, Minor); */
- if( (Major == 1) && (Minor == 2) )
- {
- sprintf( cpqfcHBAdata->fcChip.Name, STACHLITE66_TS12);
-
- }
- else if( (Major == 1) && (Minor == 3) )
- {
- sprintf( cpqfcHBAdata->fcChip.Name, STACHLITE66_TS13);
- }
- else if( (Major == 2) && (Minor == 1) )
- {
- sprintf( cpqfcHBAdata->fcChip.Name, SAGILENT_XL2_21);
- }
- else
- sprintf( cpqfcHBAdata->fcChip.Name, STACHLITE_UNKNOWN);
- }
-
-
-
- case 3: // allocate mem, set Tachyon Que registers
- iStatus = CpqTsCreateTachLiteQues( cpqfcHBAdata, opcode2);
-
- if( iStatus )
- break;
-
- // now that the Queues exist, Tach can DMA to them, so
- // we can begin processing INTs
- // INTEN register - enable INT (TachLite interrupt)
- writeb( 0x1F, fcChip->Registers.ReMapMemBase + IINTEN);
-
- // Fall through
- case 4: // Config Fame Manager, Init Loop Command, laser on
-
- // L_PORT or loopback
- // depending on Options
- iStatus = CpqTsInitializeFrameManager( fcChip,0 );
- if( iStatus )
- {
- // failed to initialize Frame Manager
- break;
- }
-
- default:
- break;
- }
- LEAVE("InitializeTachLite");
-
- return iStatus;
-}
-
-
-
-
-// Depending on the type of platform memory allocation (e.g. dynamic),
-// it's probably best to free memory in opposite order as it was allocated.
-// Order of allocation: see other function
-
-
-int CpqTsDestroyTachLiteQues( void *pHBA, int opcode)
-{
- CPQFCHBA *cpqfcHBAdata = (CPQFCHBA*)pHBA;
- PTACHYON fcChip = &cpqfcHBAdata->fcChip;
- USHORT i, iStatus=0;
- void* vPtr; // mem Align manager sets this to the freed address on success
- unsigned long ulPtr; // for 64-bit pointer cast (e.g. Alpa machine)
- FC_EXCHANGES *Exchanges = fcChip->Exchanges;
- PSGPAGES j, next;
-
- ENTER("DestroyTachLiteQues");
-
- if( fcChip->SEST )
- {
- // search out and free Pool for Extended S/G list pages
-
- for( i=0; i < TACH_SEST_LEN; i++) // for each exchange
- {
- // It's possible that extended S/G pages were allocated, mapped, and
- // not cleared due to error conditions or O/S driver termination.
- // Make sure they're all gone.
- if (Exchanges->fcExchange[i].Cmnd != NULL)
- cpqfc_pci_unmap(cpqfcHBAdata->PciDev, Exchanges->fcExchange[i].Cmnd,
- fcChip, i); // undo DMA mappings.
-
- for (j=fcChip->SEST->sgPages[i] ; j != NULL ; j = next) {
- next = j->next;
- kfree(j);
- }
- fcChip->SEST->sgPages[i] = NULL;
- }
- ulPtr = (unsigned long)fcChip->SEST;
- vPtr = fcMemManager( cpqfcHBAdata->PciDev,
- &cpqfcHBAdata->dynamic_mem[0],
- 0,0, (ULONG)ulPtr, NULL ); // 'free' mem
- fcChip->SEST = 0L; // null invalid ptr
- if( !vPtr )
- {
- printk("SEST mem not freed\n");
- iStatus = -1;
- }
- }
-
- if( fcChip->SFQ )
- {
-
- ulPtr = (unsigned long)fcChip->SFQ;
- vPtr = fcMemManager( cpqfcHBAdata->PciDev,
- &cpqfcHBAdata->dynamic_mem[0],
- 0,0, (ULONG)ulPtr, NULL ); // 'free' mem
- fcChip->SFQ = 0L; // null invalid ptr
- if( !vPtr )
- {
- printk("SFQ mem not freed\n");
- iStatus = -2;
- }
- }
-
-
- if( fcChip->IMQ )
- {
- // clear Indexes to show empty Queue
- fcChip->IMQ->producerIndex = 0;
- fcChip->IMQ->consumerIndex = 0;
-
- ulPtr = (unsigned long)fcChip->IMQ;
- vPtr = fcMemManager( cpqfcHBAdata->PciDev, &cpqfcHBAdata->dynamic_mem[0],
- 0,0, (ULONG)ulPtr, NULL ); // 'free' mem
- fcChip->IMQ = 0L; // null invalid ptr
- if( !vPtr )
- {
- printk("IMQ mem not freed\n");
- iStatus = -3;
- }
- }
-
- if( fcChip->ERQ ) // release memory blocks used by the queues
- {
- ulPtr = (unsigned long)fcChip->ERQ;
- vPtr = fcMemManager( cpqfcHBAdata->PciDev, &cpqfcHBAdata->dynamic_mem[0],
- 0,0, (ULONG)ulPtr, NULL ); // 'free' mem
- fcChip->ERQ = 0L; // null invalid ptr
- if( !vPtr )
- {
- printk("ERQ mem not freed\n");
- iStatus = -4;
- }
- }
-
- // free up the primary EXCHANGES struct and Link Q
- cpqfc_free_dma_consistent(cpqfcHBAdata);
-
- LEAVE("DestroyTachLiteQues");
-
- return iStatus; // non-zero (failed) if any memory not freed
-}
-
-
-
-
-
-// The SFQ is an array with SFQ_LEN length, each element (QEntry)
-// with eight 32-bit words. TachLite places incoming FC frames (i.e.
-// a valid FC frame with our AL_PA ) in contiguous SFQ entries
-// and sends a completion message telling the host where the frame is
-// in the que.
-// This function copies the current (or oldest not-yet-processed) QEntry to
-// a caller's contiguous buffer and updates the Tachyon chip's consumer index
-//
-// NOTE:
-// An FC frame may consume one or many SFQ entries. We know the total
-// length from the completion message. The caller passes a buffer large
-// enough for the complete message (max 2k).
-
-static void CpqTsGetSFQEntry(
- PTACHYON fcChip,
- USHORT producerNdx,
- ULONG *ulDestPtr, // contiguous destination buffer
- BOOLEAN UpdateChip)
-{
- ULONG total_bytes=0;
- ULONG consumerIndex = fcChip->SFQ->consumerIndex;
-
- // check passed copy of SFQ producer index -
- // is a new message waiting for us?
- // equal indexes means SFS is copied
-
- while( producerNdx != consumerIndex )
- { // need to process message
- total_bytes += 64; // maintain count to prevent writing past buffer
- // don't allow copies over Fibre Channel defined length!
- if( total_bytes <= 2048 )
- {
- memcpy( ulDestPtr,
- &fcChip->SFQ->QEntry[consumerIndex],
- 64 ); // each SFQ entry is 64 bytes
- ulDestPtr += 16; // advance pointer to next 64 byte block
- }
- // Tachyon is producing,
- // and we are consuming
-
- if( ++consumerIndex >= SFQ_LEN)// check for rollover
- consumerIndex = 0L; // reset it
- }
-
- // if specified, update the Tachlite chip ConsumerIndex...
- if( UpdateChip )
- {
- fcChip->SFQ->consumerIndex = consumerIndex;
- writel( fcChip->SFQ->consumerIndex,
- fcChip->Registers.SFQconsumerIndex.address);
- }
-}
-
-
-
-// TachLite routinely freezes it's core ques - Outbound FIFO, Inbound FIFO,
-// and Exchange Request Queue (ERQ) on error recover -
-// (e.g. whenever a LIP occurs). Here
-// we routinely RESUME by clearing these bits, but only if the loop is up
-// to avoid ERROR IDLE messages forever.
-
-void CpqTsUnFreezeTachlite( void *pChip, int type )
-{
- PTACHYON fcChip = (PTACHYON)pChip;
- fcChip->Registers.TYcontrol.value =
- readl(fcChip->Registers.TYcontrol.address);
-
- // (bit 4 of value is GBIC LASER)
- // if we 'unfreeze' the core machines before the loop is healthy
- // (i.e. FLT, OS, LS failure bits set in FMstatus)
- // we can get 'error idle' messages forever. Verify that
- // FMstatus (Link Status) is OK before unfreezing.
-
- if( !(fcChip->Registers.FMstatus.value & 0x07000000L) && // bits clear?
- !(fcChip->Registers.FMstatus.value & 0x80 )) // Active LPSM?
- {
- fcChip->Registers.TYcontrol.value &= ~0x300L; // clear FEQ, FFA
- if( type == 1 ) // unfreeze ERQ only
- {
-// printk("Unfreezing ERQ\n");
- fcChip->Registers.TYcontrol.value |= 0x10000L; // set REQ
- }
- else // unfreeze both ERQ and FCP-ASSIST (SEST)
- {
-// printk("Unfreezing ERQ & FCP-ASSIST\n");
-
- // set ROF, RIF, REQ - resume Outbound FCP, Inbnd FCP, ERQ
- fcChip->Registers.TYcontrol.value |= 0x70000L; // set ROF, RIF, REQ
- }
-
- writel( fcChip->Registers.TYcontrol.value,
- fcChip->Registers.TYcontrol.address);
-
- }
- // readback for verify (TachLite still frozen?)
- fcChip->Registers.TYstatus.value =
- readl(fcChip->Registers.TYstatus.address);
-}
-
-
-// Whenever an FC Exchange Abort is required, we must manipulate the
-// Host/Tachyon shared memory SEST table. Before doing this, we
-// must freeze Tachyon, which flushes certain buffers and ensure we
-// can manipulate the SEST without contention.
-// This freeze function will result in FCP & ERQ FROZEN completion
-// messages (per argument "type").
-
-void CpqTsFreezeTachlite( void *pChip, int type )
-{
- PTACHYON fcChip = (PTACHYON)pChip;
- fcChip->Registers.TYcontrol.value =
- readl(fcChip->Registers.TYcontrol.address);
-
- //set FFA, FEQ - freezes SCSI assist and ERQ
- if( type == 1) // freeze ERQ only
- fcChip->Registers.TYcontrol.value |= 0x100L; // (bit 4 is laser)
- else // freeze both FCP assists (SEST) and ERQ
- fcChip->Registers.TYcontrol.value |= 0x300L; // (bit 4 is laser)
-
- writel( fcChip->Registers.TYcontrol.value,
- fcChip->Registers.TYcontrol.address);
-
-}
-
-
-
-
-// TL has two Frame Manager Link Status Registers, with three 8-bit
-// fields each. These eight bit counters are cleared after each read,
-// so we define six 32-bit accumulators for these TL counters. This
-// function breaks out each 8-bit field and adds the value to the existing
-// sum. (s/w counters cleared independently)
-
-void fcParseLinkStatusCounters(PTACHYON fcChip)
-{
- UCHAR bBuff;
- ULONG ulBuff;
-
-
-// The BB0 timer usually increments when TL is initialized, resulting
-// in an initially bogus count. If our own counter is ZERO, it means we
-// are reading this thing for the first time, so we ignore the first count.
-// Also, reading the register does not clear it, so we have to keep an
-// additional static counter to detect rollover (yuk).
-
- if( fcChip->fcStats.lastBB0timer == 0L) // TL was reset? (ignore 1st values)
- {
- // get TL's register counter - the "last" count
- fcChip->fcStats.lastBB0timer =
- fcChip->Registers.FMBB_CreditZero.value & 0x00ffffffL;
- }
- else // subsequent pass - check for rollover
- {
- // "this" count
- ulBuff = fcChip->Registers.FMBB_CreditZero.value & 0x00ffffffL;
- if( fcChip->fcStats.lastBB0timer > ulBuff ) // rollover happened
- {
- // counter advanced to max...
- fcChip->fcStats.BB0_Timer += (0x00FFFFFFL - fcChip->fcStats.lastBB0timer);
- fcChip->fcStats.BB0_Timer += ulBuff; // plus some more
-
-
- }
- else // no rollover -- more counts or no change
- {
- fcChip->fcStats.BB0_Timer += (ulBuff - fcChip->fcStats.lastBB0timer);
-
- }
-
- fcChip->fcStats.lastBB0timer = ulBuff;
- }
-
-
-
- bBuff = (UCHAR)(fcChip->Registers.FMLinkStatus1.value >> 24);
- fcChip->fcStats.LossofSignal += bBuff;
-
- bBuff = (UCHAR)(fcChip->Registers.FMLinkStatus1.value >> 16);
- fcChip->fcStats.BadRXChar += bBuff;
-
- bBuff = (UCHAR)(fcChip->Registers.FMLinkStatus1.value >> 8);
- fcChip->fcStats.LossofSync += bBuff;
-
-
- bBuff = (UCHAR)(fcChip->Registers.FMLinkStatus2.value >> 24);
- fcChip->fcStats.Rx_EOFa += bBuff;
-
- bBuff = (UCHAR)(fcChip->Registers.FMLinkStatus2.value >> 16);
- fcChip->fcStats.Dis_Frm += bBuff;
-
- bBuff = (UCHAR)(fcChip->Registers.FMLinkStatus2.value >> 8);
- fcChip->fcStats.Bad_CRC += bBuff;
-}
-
-
-void cpqfcTSClearLinkStatusCounters(PTACHYON fcChip)
-{
- ENTER("ClearLinkStatusCounters");
- memset( &fcChip->fcStats, 0, sizeof( FCSTATS));
- LEAVE("ClearLinkStatusCounters");
-
-}
-
-
-
-
-// The following function reads the I2C hardware to get the adapter's
-// World Wide Name (WWN).
-// If the WWN is "500805f1fadb43e8" (as printed on the card), the
-// Tachyon WWN_hi (32-bit) register is 500805f1, and WWN_lo register
-// is fadb43e8.
-// In the NVRAM, the bytes appear as:
-// [2d] ..
-// [2e] ..
-// [2f] 50
-// [30] 08
-// [31] 05
-// [32] f1
-// [33] fa
-// [34] db
-// [35] 43
-// [36] e8
-//
-// In the Fibre Channel (Big Endian) format, the FC-AL LISM frame will
-// be correctly loaded by Tachyon silicon. In the login payload, bytes
-// must be correctly swapped for Big Endian format.
-
-int CpqTsReadWriteWWN( PVOID pChip, int Read)
-{
- PTACHYON fcChip = (PTACHYON)pChip;
-#define NVRAM_SIZE 512
- unsigned short i, count = NVRAM_SIZE;
- UCHAR nvRam[NVRAM_SIZE], WWNbuf[8];
- ULONG ulBuff;
- int iStatus=-1; // assume failure
- int WWNoffset;
-
- ENTER("ReadWriteWWN");
- // Now try to read the WWN from the adapter's NVRAM
-
- if( Read ) // READing NVRAM WWN?
- {
- ulBuff = cpqfcTS_ReadNVRAM( fcChip->Registers.TYstatus.address,
- fcChip->Registers.TYcontrol.address,
- count, &nvRam[0] );
-
- if( ulBuff ) // NVRAM read successful?
- {
- iStatus = 0; // success!
-
- // for engineering/ prototype boards, the data may be
- // invalid (GIGO, usually all "FF"); this prevents the
- // parse routine from working correctly, which means
- // nothing will be written to our passed buffer.
-
- WWNoffset = cpqfcTS_GetNVRAM_data( WWNbuf, nvRam );
-
- if( !WWNoffset ) // uninitialized NVRAM -- copy bytes directly
- {
- printk( "CAUTION: Copying NVRAM data on fcChip\n");
- for( i= 0; i < 8; i++)
- WWNbuf[i] = nvRam[i +0x2f]; // dangerous! some formats won't work
- }
-
- fcChip->Registers.wwn_hi = 0L;
- fcChip->Registers.wwn_lo = 0L;
- for( i=0; i<4; i++) // WWN bytes are big endian in NVRAM
- {
- ulBuff = 0L;
- ulBuff = (ULONG)(WWNbuf[i]) << (8 * (3-i));
- fcChip->Registers.wwn_hi |= ulBuff;
- }
- for( i=0; i<4; i++) // WWN bytes are big endian in NVRAM
- {
- ulBuff = 0L;
- ulBuff = (ULONG)(WWNbuf[i+4]) << (8 * (3-i));
- fcChip->Registers.wwn_lo |= ulBuff;
- }
- } // done reading
- else
- {
-
- printk( "cpqfcTS: NVRAM read failed\n");
-
- }
- }
-
- else // WRITE
- {
-
- // NOTE: WRITE not supported & not used in released driver.
-
-
- printk("ReadWriteNRAM: can't write NVRAM; aborting write\n");
- }
-
- LEAVE("ReadWriteWWN");
- return iStatus;
-}
-
-
-
-
-
-// The following function reads or writes the entire "NVRAM" contents of
-// the I2C hardware (i.e. the NM24C03). Note that HP's 5121A (TS 66Mhz)
-// adapter does not use the NM24C03 chip, so this function only works on
-// Compaq's adapters.
-
-int CpqTsReadWriteNVRAM( PVOID pChip, PVOID buf, int Read)
-{
- PTACHYON fcChip = (PTACHYON)pChip;
-#define NVRAM_SIZE 512
- ULONG ulBuff;
- UCHAR *ucPtr = buf; // cast caller's void ptr to UCHAR array
- int iStatus=-1; // assume failure
-
-
- if( Read ) // READing NVRAM?
- {
- ulBuff = cpqfcTS_ReadNVRAM( // TRUE on success
- fcChip->Registers.TYstatus.address,
- fcChip->Registers.TYcontrol.address,
- 256, // bytes to write
- ucPtr ); // source ptr
-
-
- if( ulBuff )
- iStatus = 0; // success
- else
- {
-#ifdef DBG
- printk( "CAUTION: NVRAM read failed\n");
-#endif
- }
- } // done reading
-
- else // WRITING NVRAM
- {
-
- printk("cpqfcTS: WRITE of FC Controller's NVRAM disabled\n");
- }
-
- return iStatus;
-}
diff --git a/drivers/scsi/cpqfcTSi2c.c b/drivers/scsi/cpqfcTSi2c.c
deleted file mode 100644
index b38a6a9a55a3..000000000000
--- a/drivers/scsi/cpqfcTSi2c.c
+++ /dev/null
@@ -1,493 +0,0 @@
-/* Copyright(c) 2000, Compaq Computer Corporation
- * Fibre Channel Host Bus Adapter
- * 64-bit, 66MHz PCI
- * Originally developed and tested on:
- * (front): [chip] Tachyon TS HPFC-5166A/1.2 L2C1090 ...
- * SP# P225CXCBFIEL6T, Rev XC
- * SP# 161290-001, Rev XD
- * (back): Board No. 010008-001 A/W Rev X5, FAB REV X5
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2, or (at your option) any
- * later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- * Written by Don Zimmerman
-*/
-// These functions control the NVRAM I2C hardware on
-// non-intelligent Fibre Host Adapters.
-// The primary purpose is to read the HBA's NVRAM to get adapter's
-// manufactured WWN to copy into Tachyon chip registers
-// Orignal source author unknown
-
-#include <linux/types.h>
-enum boolean { FALSE, TRUE } ;
-
-
-#ifndef UCHAR
-typedef __u8 UCHAR;
-#endif
-#ifndef BOOLEAN
-typedef __u8 BOOLEAN;
-#endif
-#ifndef USHORT
-typedef __u16 USHORT;
-#endif
-#ifndef ULONG
-typedef __u32 ULONG;
-#endif
-
-
-#include <linux/string.h>
-#include <linux/pci.h>
-#include <linux/delay.h>
-#include <linux/sched.h>
-#include <asm/io.h> // struct pt_regs for IRQ handler & Port I/O
-
-#include "cpqfcTSchip.h"
-
-static void tl_i2c_tx_byte( void* GPIOout, UCHAR data );
-/*static BOOLEAN tl_write_i2c_page_portion( void* GPIOin, void* GPIOout,
- USHORT startOffset, // e.g. 0x2f for WWN start
- USHORT count,
- UCHAR *buf );
-*/
-
-//
-// Tachlite GPIO2, GPIO3 (I2C) DEFINES
-// The NVRAM chip NM24C03 defines SCL (serial clock) and SDA (serial data)
-// GPIO2 drives SDA, and GPIO3 drives SCL
-//
-// Since Tachlite inverts the state of the GPIO 0-3 outputs, SET writes 0
-// and clear writes 1. The input lines (read in TL status) is NOT inverted
-// This really helps confuse the code and debugging.
-
-#define SET_DATA_HI 0x0
-#define SET_DATA_LO 0x8
-#define SET_CLOCK_HI 0x0
-#define SET_CLOCK_LO 0x4
-
-#define SENSE_DATA_HI 0x8
-#define SENSE_DATA_LO 0x0
-#define SENSE_CLOCK_HI 0x4
-#define SENSE_CLOCK_LO 0x0
-
-#define SLAVE_READ_ADDRESS 0xA1
-#define SLAVE_WRITE_ADDRESS 0xA0
-
-
-static void i2c_delay(ULONG mstime);
-static void tl_i2c_clock_pulse( UCHAR , void* GPIOout);
-static UCHAR tl_read_i2c_data( void* );
-
-
-//-----------------------------------------------------------------------------
-//
-// Name: I2C_RX_ACK
-//
-// This routine receives an acknowledge over the I2C bus.
-//
-//-----------------------------------------------------------------------------
-static unsigned short tl_i2c_rx_ack( void* GPIOin, void* GPIOout )
-{
- unsigned long value;
-
- // do clock pulse, let data line float high
- tl_i2c_clock_pulse( SET_DATA_HI, GPIOout );
-
- // slave must drive data low for acknowledge
- value = tl_read_i2c_data( GPIOin);
- if (value & SENSE_DATA_HI )
- return( FALSE );
-
- return( TRUE );
-}
-//-----------------------------------------------------------------------------
-//
-// Name: READ_I2C_REG
-//
-// This routine reads the I2C control register using the global
-// IO address stored in gpioreg.
-//
-//-----------------------------------------------------------------------------
-static UCHAR tl_read_i2c_data( void* gpioreg )
-{
- return( (UCHAR)(readl( gpioreg ) & 0x08L) ); // GPIO3
-}
-//-----------------------------------------------------------------------------
-//
-// Name: WRITE_I2C_REG
-//
-// This routine writes the I2C control register using the global
-// IO address stored in gpioreg.
-// In Tachlite, we don't want to modify other bits in TL Control reg.
-//
-//-----------------------------------------------------------------------------
-static void tl_write_i2c_reg( void* gpioregOUT, UCHAR value )
-{
- ULONG temp;
-
- // First read the register and clear out the old bits
- temp = readl( gpioregOUT ) & 0xfffffff3L;
-
- // Now or in the new data and send it back out
- writel( temp | value, gpioregOUT);
-}
-//-----------------------------------------------------------------------------
-//
-// Name: I2C_TX_START
-//
-// This routine transmits a start condition over the I2C bus.
-// 1. Set SCL (clock, GPIO2) HIGH, set SDA (data, GPIO3) HIGH,
-// wait 5us to stabilize.
-// 2. With SCL still HIGH, drive SDA low. The low transition marks
-// the start condition to NM24Cxx (the chip)
-// NOTE! In TL control reg., output 1 means chip sees LOW
-//
-//-----------------------------------------------------------------------------
-static unsigned short tl_i2c_tx_start( void* GPIOin, void* GPIOout )
-{
- unsigned short i;
- ULONG value;
-
- if ( !(tl_read_i2c_data(GPIOin) & SENSE_DATA_HI))
- {
- // start with clock high, let data float high
- tl_write_i2c_reg( GPIOout, SET_DATA_HI | SET_CLOCK_HI );
-
- // keep sending clock pulses if slave is driving data line
- for (i = 0; i < 10; i++)
- {
- tl_i2c_clock_pulse( SET_DATA_HI, GPIOout );
-
- if ( tl_read_i2c_data(GPIOin) & SENSE_DATA_HI )
- break;
- }
-
- // if he's still driving data low after 10 clocks, abort
- value = tl_read_i2c_data( GPIOin ); // read status
- if (!(value & 0x08) )
- return( FALSE );
- }
-
-
- // To START, bring data low while clock high
- tl_write_i2c_reg( GPIOout, SET_CLOCK_HI | SET_DATA_LO );
-
- i2c_delay(0);
-
- return( TRUE ); // TX start successful
-}
-//-----------------------------------------------------------------------------
-//
-// Name: I2C_TX_STOP
-//
-// This routine transmits a stop condition over the I2C bus.
-//
-//-----------------------------------------------------------------------------
-
-static unsigned short tl_i2c_tx_stop( void* GPIOin, void* GPIOout )
-{
- int i;
-
- for (i = 0; i < 10; i++)
- {
- // Send clock pulse, drive data line low
- tl_i2c_clock_pulse( SET_DATA_LO, GPIOout );
-
- // To STOP, bring data high while clock high
- tl_write_i2c_reg( GPIOout, SET_DATA_HI | SET_CLOCK_HI );
-
- // Give the data line time to float high
- i2c_delay(0);
-
- // If slave is driving data line low, there's a problem; retry
- if ( tl_read_i2c_data(GPIOin) & SENSE_DATA_HI )
- return( TRUE ); // TX STOP successful!
- }
-
- return( FALSE ); // error
-}
-//-----------------------------------------------------------------------------
-//
-// Name: I2C_TX_uchar
-//
-// This routine transmits a byte across the I2C bus.
-//
-//-----------------------------------------------------------------------------
-static void tl_i2c_tx_byte( void* GPIOout, UCHAR data )
-{
- UCHAR bit;
-
- for (bit = 0x80; bit; bit >>= 1)
- {
- if( data & bit )
- tl_i2c_clock_pulse( (UCHAR)SET_DATA_HI, GPIOout);
- else
- tl_i2c_clock_pulse( (UCHAR)SET_DATA_LO, GPIOout);
- }
-}
-//-----------------------------------------------------------------------------
-//
-// Name: I2C_RX_uchar
-//
-// This routine receives a byte across the I2C bus.
-//
-//-----------------------------------------------------------------------------
-static UCHAR tl_i2c_rx_byte( void* GPIOin, void* GPIOout )
-{
- UCHAR bit;
- UCHAR data = 0;
-
-
- for (bit = 0x80; bit; bit >>= 1) {
- // do clock pulse, let data line float high
- tl_i2c_clock_pulse( SET_DATA_HI, GPIOout );
-
- // read data line
- if ( tl_read_i2c_data( GPIOin) & 0x08 )
- data |= bit;
- }
-
- return (data);
-}
-//*****************************************************************************
-//*****************************************************************************
-// Function: read_i2c_nvram
-// Arguments: UCHAR count number of bytes to read
-// UCHAR *buf area to store the bytes read
-// Returns: 0 - failed
-// 1 - success
-//*****************************************************************************
-//*****************************************************************************
-unsigned long cpqfcTS_ReadNVRAM( void* GPIOin, void* GPIOout , USHORT count,
- UCHAR *buf )
-{
- unsigned short i;
-
- if( !( tl_i2c_tx_start(GPIOin, GPIOout) ))
- return FALSE;
-
- // Select the NVRAM for "dummy" write, to set the address
- tl_i2c_tx_byte( GPIOout , SLAVE_WRITE_ADDRESS );
- if ( !tl_i2c_rx_ack(GPIOin, GPIOout ) )
- return( FALSE );
-
- // Now send the address where we want to start reading
- tl_i2c_tx_byte( GPIOout , 0 );
- if ( !tl_i2c_rx_ack(GPIOin, GPIOout ) )
- return( FALSE );
-
- // Send a repeated start condition and select the
- // slave for reading now.
- if( tl_i2c_tx_start(GPIOin, GPIOout) )
- tl_i2c_tx_byte( GPIOout, SLAVE_READ_ADDRESS );
-
- if ( !tl_i2c_rx_ack(GPIOin, GPIOout) )
- return( FALSE );
-
- // this loop will now read out the data and store it
- // in the buffer pointed to by buf
- for ( i=0; i<count; i++)
- {
- *buf++ = tl_i2c_rx_byte(GPIOin, GPIOout);
-
- // Send ACK by holding data line low for 1 clock
- if ( i < (count-1) )
- tl_i2c_clock_pulse( 0x08, GPIOout );
- else {
- // Don't send ack for final byte
- tl_i2c_clock_pulse( SET_DATA_HI, GPIOout );
- }
- }
-
- tl_i2c_tx_stop(GPIOin, GPIOout);
-
- return( TRUE );
-}
-
-//****************************************************************
-//
-//
-//
-// routines to set and clear the data and clock bits
-//
-//
-//
-//****************************************************************
-
-static void tl_set_clock(void* gpioreg)
-{
- ULONG ret_val;
-
- ret_val = readl( gpioreg );
- ret_val &= 0xffffffFBL; // clear GPIO2 (SCL)
- writel( ret_val, gpioreg);
-}
-
-static void tl_clr_clock(void* gpioreg)
-{
- ULONG ret_val;
-
- ret_val = readl( gpioreg );
- ret_val |= SET_CLOCK_LO;
- writel( ret_val, gpioreg);
-}
-
-//*****************************************************************
-//
-//
-// This routine will advance the clock by one period
-//
-//
-//*****************************************************************
-static void tl_i2c_clock_pulse( UCHAR value, void* GPIOout )
-{
- ULONG ret_val;
-
- // clear the clock bit
- tl_clr_clock( GPIOout );
-
- i2c_delay(0);
-
-
- // read the port to preserve non-I2C bits
- ret_val = readl( GPIOout );
-
- // clear the data & clock bits
- ret_val &= 0xFFFFFFf3;
-
- // write the value passed in...
- // data can only change while clock is LOW!
- ret_val |= value; // the data
- ret_val |= SET_CLOCK_LO; // the clock
- writel( ret_val, GPIOout );
-
- i2c_delay(0);
-
-
- //set clock bit
- tl_set_clock( GPIOout);
-}
-
-
-
-
-//*****************************************************************
-//
-//
-// This routine returns the 64-bit WWN
-//
-//
-//*****************************************************************
-int cpqfcTS_GetNVRAM_data( UCHAR *wwnbuf, UCHAR *buf )
-{
- ULONG len;
- ULONG sub_len;
- ULONG ptr_inc;
- ULONG i;
- ULONG j;
- UCHAR *data_ptr;
- UCHAR z;
- UCHAR name;
- UCHAR sub_name;
- UCHAR done;
- int iReturn=0; // def. 0 offset is failure to find WWN field
-
-
-
- data_ptr = (UCHAR *)buf;
-
- done = FALSE;
- i = 0;
-
- while ( (i < 128) && (!done) )
- {
- z = data_ptr[i];\
- if ( !(z & 0x80) )
- {
- len = 1 + (z & 0x07);
-
- name = (z & 0x78) >> 3;
- if (name == 0x0F)
- done = TRUE;
- }
- else
- {
- name = z & 0x7F;
- len = 3 + data_ptr[i+1] + (data_ptr[i+2] << 8);
-
- switch (name)
- {
- case 0x0D:
- //
- j = i + 3;
- //
- if ( data_ptr[j] == 0x3b ) {
- len = 6;
- break;
- }
-
- while ( j<(i+len) ) {
- sub_name = (data_ptr[j] & 0x3f);
- sub_len = data_ptr[j+1] +
- (data_ptr[j+2] << 8);
- ptr_inc = sub_len + 3;
- switch (sub_name)
- {
- case 0x3C:
- memcpy( wwnbuf, &data_ptr[j+3], 8);
- iReturn = j+3;
- break;
- default:
- break;
- }
- j += ptr_inc;
- }
- break;
- default:
- break;
- }
- }
- //
- i += len;
- } // end while
- return iReturn;
-}
-
-
-
-
-
-// define a short 5 micro sec delay, and longer (ms) delay
-
-static void i2c_delay(ULONG mstime)
-{
- ULONG i;
-
-// NOTE: we only expect to use these delays when reading
-// our adapter's NVRAM, which happens only during adapter reset.
-// Delay technique from "Linux Device Drivers", A. Rubini
-// (1st Ed.) pg 137.
-
-// printk(" delay %lx ", mstime);
- if( mstime ) // ms delay?
- {
- // delay technique
- for( i=0; i < mstime; i++)
- udelay(1000); // 1ms per loop
-
- }
- else // 5 micro sec delay
-
- udelay( 5 ); // micro secs
-
-// printk("done\n");
-}
-
-
-
diff --git a/drivers/scsi/cpqfcTSinit.c b/drivers/scsi/cpqfcTSinit.c
deleted file mode 100644
index 3fda8d455c5b..000000000000
--- a/drivers/scsi/cpqfcTSinit.c
+++ /dev/null
@@ -1,2096 +0,0 @@
-/* Copyright(c) 2000, Compaq Computer Corporation
- * Fibre Channel Host Bus Adapter
- * 64-bit, 66MHz PCI
- * Originally developed and tested on:
- * (front): [chip] Tachyon TS HPFC-5166A/1.2 L2C1090 ...
- * SP# P225CXCBFIEL6T, Rev XC
- * SP# 161290-001, Rev XD
- * (back): Board No. 010008-001 A/W Rev X5, FAB REV X5
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2, or (at your option) any
- * later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- * Written by Don Zimmerman
- * IOCTL and procfs added by Jouke Numan
- * SMP testing by Chel Van Gennip
- *
- * portions copied from:
- * QLogic CPQFCTS SCSI-FCP
- * Written by Erik H. Moe, ehm@cris.com
- * Copyright 1995, Erik H. Moe
- * Renamed and updated to 1.3.x by Michael Griffith <grif@cs.ucr.edu>
- * Chris Loveland <cwl@iol.unh.edu> to support the isp2100 and isp2200
-*/
-
-
-#define LinuxVersionCode(v, p, s) (((v)<<16)+((p)<<8)+(s))
-
-#include <linux/config.h>
-#include <linux/interrupt.h>
-#include <linux/module.h>
-#include <linux/version.h>
-#include <linux/blkdev.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/types.h>
-#include <linux/pci.h>
-#include <linux/delay.h>
-#include <linux/timer.h>
-#include <linux/init.h>
-#include <linux/ioport.h> // request_region() prototype
-#include <linux/completion.h>
-
-#include <asm/io.h>
-#include <asm/uaccess.h> // ioctl related
-#include <asm/irq.h>
-#include <linux/spinlock.h>
-#include "scsi.h"
-#include <scsi/scsi_host.h>
-#include <scsi/scsi_ioctl.h>
-#include "cpqfcTSchip.h"
-#include "cpqfcTSstructs.h"
-#include "cpqfcTStrigger.h"
-
-#include "cpqfcTS.h"
-
-/* Embedded module documentation macros - see module.h */
-MODULE_AUTHOR("Compaq Computer Corporation");
-MODULE_DESCRIPTION("Driver for Compaq 64-bit/66Mhz PCI Fibre Channel HBA v. 2.5.4");
-MODULE_LICENSE("GPL");
-
-int cpqfcTS_TargetDeviceReset( Scsi_Device *ScsiDev, unsigned int reset_flags);
-
-// This struct was originally defined in
-// /usr/src/linux/include/linux/proc_fs.h
-// since it's only partially implemented, we only use first
-// few fields...
-// NOTE: proc_fs changes in 2.4 kernel
-
-#if LINUX_VERSION_CODE < LinuxVersionCode(2,3,27)
-static struct proc_dir_entry proc_scsi_cpqfcTS =
-{
- PROC_SCSI_CPQFCTS, // ushort low_ino (enumerated list)
- 7, // ushort namelen
- DEV_NAME, // const char* name
- S_IFDIR | S_IRUGO | S_IXUGO, // mode_t mode
- 2 // nlink_t nlink
- // etc. ...
-};
-
-
-#endif
-
-#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,7)
-# define CPQFC_DECLARE_COMPLETION(x) DECLARE_COMPLETION(x)
-# define CPQFC_WAITING waiting
-# define CPQFC_COMPLETE(x) complete(x)
-# define CPQFC_WAIT_FOR_COMPLETION(x) wait_for_completion(x);
-#else
-# define CPQFC_DECLARE_COMPLETION(x) DECLARE_MUTEX_LOCKED(x)
-# define CPQFC_WAITING sem
-# define CPQFC_COMPLETE(x) up(x)
-# define CPQFC_WAIT_FOR_COMPLETION(x) down(x)
-#endif
-
-static int cpqfc_alloc_private_data_pool(CPQFCHBA *hba);
-
-/* local function to load our per-HBA (local) data for chip
- registers, FC link state, all FC exchanges, etc.
-
- We allocate space and compute address offsets for the
- most frequently accessed addresses; others (like World Wide
- Name) are not necessary.
-*/
-static void Cpqfc_initHBAdata(CPQFCHBA *cpqfcHBAdata, struct pci_dev *PciDev )
-{
-
- cpqfcHBAdata->PciDev = PciDev; // copy PCI info ptr
-
- // since x86 port space is 64k, we only need the lower 16 bits
- cpqfcHBAdata->fcChip.Registers.IOBaseL =
- PciDev->resource[1].start & PCI_BASE_ADDRESS_IO_MASK;
-
- cpqfcHBAdata->fcChip.Registers.IOBaseU =
- PciDev->resource[2].start & PCI_BASE_ADDRESS_IO_MASK;
-
- // 32-bit memory addresses
- cpqfcHBAdata->fcChip.Registers.MemBase =
- PciDev->resource[3].start & PCI_BASE_ADDRESS_MEM_MASK;
-
- cpqfcHBAdata->fcChip.Registers.ReMapMemBase =
- ioremap( PciDev->resource[3].start & PCI_BASE_ADDRESS_MEM_MASK,
- 0x200);
-
- cpqfcHBAdata->fcChip.Registers.RAMBase =
- PciDev->resource[4].start;
-
- cpqfcHBAdata->fcChip.Registers.SROMBase = // NULL for HP TS adapter
- PciDev->resource[5].start;
-
- // now the Tachlite chip registers
- // the REGISTER struct holds both the physical address & last
- // written value (some TL registers are WRITE ONLY)
-
- cpqfcHBAdata->fcChip.Registers.SFQconsumerIndex.address =
- cpqfcHBAdata->fcChip.Registers.ReMapMemBase + TL_MEM_SFQ_CONSUMER_INDEX;
-
- cpqfcHBAdata->fcChip.Registers.ERQproducerIndex.address =
- cpqfcHBAdata->fcChip.Registers.ReMapMemBase + TL_MEM_ERQ_PRODUCER_INDEX;
-
- // TL Frame Manager
- cpqfcHBAdata->fcChip.Registers.FMconfig.address =
- cpqfcHBAdata->fcChip.Registers.ReMapMemBase + TL_MEM_FM_CONFIG;
- cpqfcHBAdata->fcChip.Registers.FMcontrol.address =
- cpqfcHBAdata->fcChip.Registers.ReMapMemBase + TL_MEM_FM_CONTROL;
- cpqfcHBAdata->fcChip.Registers.FMstatus.address =
- cpqfcHBAdata->fcChip.Registers.ReMapMemBase + TL_MEM_FM_STATUS;
- cpqfcHBAdata->fcChip.Registers.FMLinkStatus1.address =
- cpqfcHBAdata->fcChip.Registers.ReMapMemBase + TL_MEM_FM_LINK_STAT1;
- cpqfcHBAdata->fcChip.Registers.FMLinkStatus2.address =
- cpqfcHBAdata->fcChip.Registers.ReMapMemBase + TL_MEM_FM_LINK_STAT2;
- cpqfcHBAdata->fcChip.Registers.FMBB_CreditZero.address =
- cpqfcHBAdata->fcChip.Registers.ReMapMemBase + TL_MEM_FM_BB_CREDIT0;
-
- // TL Control Regs
- cpqfcHBAdata->fcChip.Registers.TYconfig.address =
- cpqfcHBAdata->fcChip.Registers.ReMapMemBase + TL_MEM_TACH_CONFIG;
- cpqfcHBAdata->fcChip.Registers.TYcontrol.address =
- cpqfcHBAdata->fcChip.Registers.ReMapMemBase + TL_MEM_TACH_CONTROL;
- cpqfcHBAdata->fcChip.Registers.TYstatus.address =
- cpqfcHBAdata->fcChip.Registers.ReMapMemBase + TL_MEM_TACH_STATUS;
- cpqfcHBAdata->fcChip.Registers.rcv_al_pa.address =
- cpqfcHBAdata->fcChip.Registers.ReMapMemBase + TL_MEM_FM_RCV_AL_PA;
- cpqfcHBAdata->fcChip.Registers.ed_tov.address =
- cpqfcHBAdata->fcChip.Registers.ReMapMemBase + TL_MEM_FM_ED_TOV;
-
-
- cpqfcHBAdata->fcChip.Registers.INTEN.address =
- cpqfcHBAdata->fcChip.Registers.ReMapMemBase + IINTEN;
- cpqfcHBAdata->fcChip.Registers.INTPEND.address =
- cpqfcHBAdata->fcChip.Registers.ReMapMemBase + IINTPEND;
- cpqfcHBAdata->fcChip.Registers.INTSTAT.address =
- cpqfcHBAdata->fcChip.Registers.ReMapMemBase + IINTSTAT;
-
- DEBUG_PCI(printk(" cpqfcHBAdata->fcChip.Registers. :\n"));
- DEBUG_PCI(printk(" IOBaseL = %x\n",
- cpqfcHBAdata->fcChip.Registers.IOBaseL));
- DEBUG_PCI(printk(" IOBaseU = %x\n",
- cpqfcHBAdata->fcChip.Registers.IOBaseU));
-
- /* printk(" ioremap'd Membase: %p\n", cpqfcHBAdata->fcChip.Registers.ReMapMemBase); */
-
- DEBUG_PCI(printk(" SFQconsumerIndex.address = %p\n",
- cpqfcHBAdata->fcChip.Registers.SFQconsumerIndex.address));
- DEBUG_PCI(printk(" ERQproducerIndex.address = %p\n",
- cpqfcHBAdata->fcChip.Registers.ERQproducerIndex.address));
- DEBUG_PCI(printk(" TYconfig.address = %p\n",
- cpqfcHBAdata->fcChip.Registers.TYconfig.address));
- DEBUG_PCI(printk(" FMconfig.address = %p\n",
- cpqfcHBAdata->fcChip.Registers.FMconfig.address));
- DEBUG_PCI(printk(" FMcontrol.address = %p\n",
- cpqfcHBAdata->fcChip.Registers.FMcontrol.address));
-
- // set default options for FC controller (chip)
- cpqfcHBAdata->fcChip.Options.initiator = 1; // default: SCSI initiator
- cpqfcHBAdata->fcChip.Options.target = 0; // default: SCSI target
- cpqfcHBAdata->fcChip.Options.extLoopback = 0;// default: no loopback @GBIC
- cpqfcHBAdata->fcChip.Options.intLoopback = 0;// default: no loopback inside chip
-
- // set highest and lowest FC-PH version the adapter/driver supports
- // (NOT strict compliance)
- cpqfcHBAdata->fcChip.highest_FCPH_ver = FC_PH3;
- cpqfcHBAdata->fcChip.lowest_FCPH_ver = FC_PH43;
-
- // set function points for this controller / adapter
- cpqfcHBAdata->fcChip.ResetTachyon = CpqTsResetTachLite;
- cpqfcHBAdata->fcChip.FreezeTachyon = CpqTsFreezeTachlite;
- cpqfcHBAdata->fcChip.UnFreezeTachyon = CpqTsUnFreezeTachlite;
- cpqfcHBAdata->fcChip.CreateTachyonQues = CpqTsCreateTachLiteQues;
- cpqfcHBAdata->fcChip.DestroyTachyonQues = CpqTsDestroyTachLiteQues;
- cpqfcHBAdata->fcChip.InitializeTachyon = CpqTsInitializeTachLite;
- cpqfcHBAdata->fcChip.LaserControl = CpqTsLaserControl;
- cpqfcHBAdata->fcChip.ProcessIMQEntry = CpqTsProcessIMQEntry;
- cpqfcHBAdata->fcChip.InitializeFrameManager = CpqTsInitializeFrameManager;
- cpqfcHBAdata->fcChip.ReadWriteWWN = CpqTsReadWriteWWN;
- cpqfcHBAdata->fcChip.ReadWriteNVRAM = CpqTsReadWriteNVRAM;
-
- if (cpqfc_alloc_private_data_pool(cpqfcHBAdata) != 0) {
- printk(KERN_WARNING
- "cpqfc: unable to allocate pool for passthru ioctls. "
- "Passthru ioctls disabled.\n");
- }
-}
-
-
-/* (borrowed from linux/drivers/scsi/hosts.c) */
-static void launch_FCworker_thread(struct Scsi_Host *HostAdapter)
-{
- DECLARE_MUTEX_LOCKED(sem);
-
- CPQFCHBA *cpqfcHBAdata = (CPQFCHBA *)HostAdapter->hostdata;
-
- ENTER("launch_FC_worker_thread");
-
- cpqfcHBAdata->notify_wt = &sem;
-
- /* must unlock before kernel_thread(), for it may cause a reschedule. */
- spin_unlock_irq(HostAdapter->host_lock);
- kernel_thread((int (*)(void *))cpqfcTSWorkerThread,
- (void *) HostAdapter, 0);
- /*
- * Now wait for the kernel error thread to initialize itself
-
- */
- down (&sem);
- spin_lock_irq(HostAdapter->host_lock);
- cpqfcHBAdata->notify_wt = NULL;
-
- LEAVE("launch_FC_worker_thread");
-
-}
-
-
-/* "Entry" point to discover if any supported PCI
- bus adapter can be found
-*/
-/* We're supporting:
- * Compaq 64-bit, 66MHz HBA with Tachyon TS
- * Agilent XL2
- * HP Tachyon
- */
-#define HBA_TYPES 3
-
-#ifndef PCI_DEVICE_ID_COMPAQ_
-#define PCI_DEVICE_ID_COMPAQ_TACHYON 0xa0fc
-#endif
-
-static struct SupportedPCIcards cpqfc_boards[] __initdata = {
- {PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_TACHYON},
- {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_TACHLITE},
- {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_TACHYON},
-};
-
-
-int cpqfcTS_detect(Scsi_Host_Template *ScsiHostTemplate)
-{
- int NumberOfAdapters=0; // how many of our PCI adapters are found?
- struct pci_dev *PciDev = NULL;
- struct Scsi_Host *HostAdapter = NULL;
- CPQFCHBA *cpqfcHBAdata = NULL;
- struct timer_list *cpqfcTStimer = NULL;
- int i;
-
- ENTER("cpqfcTS_detect");
-
-#if LINUX_VERSION_CODE < LinuxVersionCode(2,3,27)
- ScsiHostTemplate->proc_dir = &proc_scsi_cpqfcTS;
-#else
- ScsiHostTemplate->proc_name = "cpqfcTS";
-#endif
-
- for( i=0; i < HBA_TYPES; i++)
- {
- // look for all HBAs of each type
-
- while((PciDev = pci_find_device(cpqfc_boards[i].vendor_id,
- cpqfc_boards[i].device_id, PciDev)))
- {
-
- if (pci_enable_device(PciDev)) {
- printk(KERN_ERR
- "cpqfc: can't enable PCI device at %s\n", pci_name(PciDev));
- goto err_continue;
- }
-
- if (pci_set_dma_mask(PciDev, CPQFCTS_DMA_MASK) != 0) {
- printk(KERN_WARNING
- "cpqfc: HBA cannot support required DMA mask, skipping.\n");
- goto err_disable_dev;
- }
-
- // NOTE: (kernel 2.2.12-32) limits allocation to 128k bytes...
- /* printk(" scsi_register allocating %d bytes for FC HBA\n",
- (ULONG)sizeof(CPQFCHBA)); */
-
- HostAdapter = scsi_register( ScsiHostTemplate, sizeof( CPQFCHBA ) );
-
- if(HostAdapter == NULL) {
- printk(KERN_WARNING
- "cpqfc: can't register SCSI HBA, skipping.\n");
- goto err_disable_dev;
- }
- DEBUG_PCI( printk(" HBA found!\n"));
- DEBUG_PCI( printk(" HostAdapter->PciDev->irq = %u\n", PciDev->irq) );
- DEBUG_PCI(printk(" PciDev->baseaddress[0]= %lx\n",
- PciDev->resource[0].start));
- DEBUG_PCI(printk(" PciDev->baseaddress[1]= %lx\n",
- PciDev->resource[1].start));
- DEBUG_PCI(printk(" PciDev->baseaddress[2]= %lx\n",
- PciDev->resource[2].start));
- DEBUG_PCI(printk(" PciDev->baseaddress[3]= %lx\n",
- PciDev->resource[3].start));
-
- HostAdapter->irq = PciDev->irq; // copy for Scsi layers
-
- // HP Tachlite uses two (255-byte) ranges of Port I/O (lower & upper),
- // for a total I/O port address space of 512 bytes.
- // mask out the I/O port address (lower) & record
- HostAdapter->io_port = (unsigned int)
- PciDev->resource[1].start & PCI_BASE_ADDRESS_IO_MASK;
- HostAdapter->n_io_port = 0xff;
-
- // i.e., expect 128 targets (arbitrary number), while the
- // RA-4000 supports 32 LUNs
- HostAdapter->max_id = 0; // incremented as devices log in
- HostAdapter->max_lun = CPQFCTS_MAX_LUN; // LUNs per FC device
- HostAdapter->max_channel = CPQFCTS_MAX_CHANNEL; // multiple busses?
-
- // get the pointer to our HBA specific data... (one for
- // each HBA on the PCI bus(ses)).
- cpqfcHBAdata = (CPQFCHBA *)HostAdapter->hostdata;
-
- // make certain our data struct is clear
- memset( cpqfcHBAdata, 0, sizeof( CPQFCHBA ) );
-
-
- // initialize our HBA info
- cpqfcHBAdata->HBAnum = NumberOfAdapters;
-
- cpqfcHBAdata->HostAdapter = HostAdapter; // back ptr
- Cpqfc_initHBAdata( cpqfcHBAdata, PciDev ); // fill MOST fields
-
- cpqfcHBAdata->HBAnum = NumberOfAdapters;
- spin_lock_init(&cpqfcHBAdata->hba_spinlock);
-
- // request necessary resources and check for conflicts
- if( request_irq( HostAdapter->irq,
- cpqfcTS_intr_handler,
- SA_INTERRUPT | SA_SHIRQ,
- DEV_NAME,
- HostAdapter) )
- {
- printk(KERN_WARNING "cpqfc: IRQ %u already used\n", HostAdapter->irq);
- goto err_unregister;
- }
-
- // Since we have two 256-byte I/O port ranges (upper
- // and lower), check them both
- if( !request_region( cpqfcHBAdata->fcChip.Registers.IOBaseU,
- 0xff, DEV_NAME ) )
- {
- printk(KERN_WARNING "cpqfc: address in use: %x\n",
- cpqfcHBAdata->fcChip.Registers.IOBaseU);
- goto err_free_irq;
- }
-
- if( !request_region( cpqfcHBAdata->fcChip.Registers.IOBaseL,
- 0xff, DEV_NAME ) )
- {
- printk(KERN_WARNING "cpqfc: address in use: %x\n",
- cpqfcHBAdata->fcChip.Registers.IOBaseL);
- goto err_release_region_U;
- }
-
- // OK, we have grabbed everything we need now.
- DEBUG_PCI(printk(" Reserved 255 I/O addresses @ %x\n",
- cpqfcHBAdata->fcChip.Registers.IOBaseL ));
- DEBUG_PCI(printk(" Reserved 255 I/O addresses @ %x\n",
- cpqfcHBAdata->fcChip.Registers.IOBaseU ));
-
-
-
- // start our kernel worker thread
-
- spin_lock_irq(HostAdapter->host_lock);
- launch_FCworker_thread(HostAdapter);
-
-
- // start our TimerTask...
-
- cpqfcTStimer = &cpqfcHBAdata->cpqfcTStimer;
-
- init_timer( cpqfcTStimer); // Linux clears next/prev values
- cpqfcTStimer->expires = jiffies + HZ; // one second
- cpqfcTStimer->data = (unsigned long)cpqfcHBAdata; // this adapter
- cpqfcTStimer->function = cpqfcTSheartbeat; // handles timeouts, housekeeping
-
- add_timer( cpqfcTStimer); // give it to Linux
-
-
- // now initialize our hardware...
- if (cpqfcHBAdata->fcChip.InitializeTachyon( cpqfcHBAdata, 1,1)) {
- printk(KERN_WARNING "cpqfc: initialization of HBA hardware failed.\n");
- goto err_release_region_L;
- }
-
- cpqfcHBAdata->fcStatsTime = jiffies; // (for FC Statistics delta)
-
- // give our HBA time to initialize and login current devices...
- {
- // The Brocade switch (e.g. 2400, 2010, etc.) as of March 2000,
- // has the following algorithm for FL_Port startup:
- // Time(sec) Action
- // 0: Device Plugin and LIP(F7,F7) transmission
- // 1.0 LIP incoming
- // 1.027 LISA incoming, no CLS! (link not up)
- // 1.028 NOS incoming (switch test for N_Port)
- // 1.577 ED_TOV expired, transmit LIPs again
- // 3.0 LIP(F8,F7) incoming (switch passes Tach Prim.Sig)
- // 3.028 LILP received, link up, FLOGI starts
- // slowest(worst) case, measured on 1Gb Finisar GT analyzer
-
- unsigned long stop_time;
-
- spin_unlock_irq(HostAdapter->host_lock);
- stop_time = jiffies + 4*HZ;
- while ( time_before(jiffies, stop_time) )
- schedule(); // (our worker task needs to run)
-
- }
-
- spin_lock_irq(HostAdapter->host_lock);
- NumberOfAdapters++;
- spin_unlock_irq(HostAdapter->host_lock);
-
- continue;
-
-err_release_region_L:
- release_region( cpqfcHBAdata->fcChip.Registers.IOBaseL, 0xff );
-err_release_region_U:
- release_region( cpqfcHBAdata->fcChip.Registers.IOBaseU, 0xff );
-err_free_irq:
- free_irq( HostAdapter->irq, HostAdapter);
-err_unregister:
- scsi_unregister( HostAdapter);
-err_disable_dev:
- pci_disable_device( PciDev );
-err_continue:
- continue;
- } // end of while()
- }
-
- LEAVE("cpqfcTS_detect");
-
- return NumberOfAdapters;
-}
-
-#ifdef SUPPORT_RESET
-static void my_ioctl_done (Scsi_Cmnd * SCpnt)
-{
- struct request * req;
-
- req = SCpnt->request;
- req->rq_status = RQ_SCSI_DONE; /* Busy, but indicate request done */
-
- if (req->CPQFC_WAITING != NULL)
- CPQFC_COMPLETE(req->CPQFC_WAITING);
-}
-#endif
-
-static int cpqfc_alloc_private_data_pool(CPQFCHBA *hba)
-{
- hba->private_data_bits = NULL;
- hba->private_data_pool = NULL;
- hba->private_data_bits =
- kmalloc(((CPQFC_MAX_PASSTHRU_CMDS+BITS_PER_LONG-1) /
- BITS_PER_LONG)*sizeof(unsigned long),
- GFP_KERNEL);
- if (hba->private_data_bits == NULL)
- return -1;
- memset(hba->private_data_bits, 0,
- ((CPQFC_MAX_PASSTHRU_CMDS+BITS_PER_LONG-1) /
- BITS_PER_LONG)*sizeof(unsigned long));
- hba->private_data_pool = kmalloc(sizeof(cpqfc_passthru_private_t) *
- CPQFC_MAX_PASSTHRU_CMDS, GFP_KERNEL);
- if (hba->private_data_pool == NULL) {
- kfree(hba->private_data_bits);
- hba->private_data_bits = NULL;
- return -1;
- }
- return 0;
-}
-
-static void cpqfc_free_private_data_pool(CPQFCHBA *hba)
-{
- kfree(hba->private_data_bits);
- kfree(hba->private_data_pool);
-}
-
-int is_private_data_of_cpqfc(CPQFCHBA *hba, void *pointer)
-{
- /* Is pointer within our private data pool?
- We use Scsi_Request->upper_private_data (normally
- reserved for upper layer drivers, e.g. the sg driver)
- We check to see if the pointer is ours by looking at
- its address. Is this ok? Hmm, it occurs to me that
- a user app might do something bad by using sg to send
- a cpqfc passthrough ioctl with upper_data_private
- forged to be somewhere in our pool..., though they'd
- normally have to be root already to do this. */
-
- return (pointer != NULL &&
- pointer >= (void *) hba->private_data_pool &&
- pointer < (void *) hba->private_data_pool +
- sizeof(*hba->private_data_pool) *
- CPQFC_MAX_PASSTHRU_CMDS);
-}
-
-cpqfc_passthru_private_t *cpqfc_alloc_private_data(CPQFCHBA *hba)
-{
- int i;
-
- do {
- i = find_first_zero_bit(hba->private_data_bits,
- CPQFC_MAX_PASSTHRU_CMDS);
- if (i == CPQFC_MAX_PASSTHRU_CMDS)
- return NULL;
- } while ( test_and_set_bit(i & (BITS_PER_LONG - 1),
- hba->private_data_bits+(i/BITS_PER_LONG)) != 0);
- return &hba->private_data_pool[i];
-}
-
-void cpqfc_free_private_data(CPQFCHBA *hba, cpqfc_passthru_private_t *data)
-{
- int i;
- i = data - hba->private_data_pool;
- clear_bit(i&(BITS_PER_LONG-1),
- hba->private_data_bits+(i/BITS_PER_LONG));
-}
-
-int cpqfcTS_ioctl( struct scsi_device *ScsiDev, int Cmnd, void *arg)
-{
- int result = 0;
- struct Scsi_Host *HostAdapter = ScsiDev->host;
- CPQFCHBA *cpqfcHBAdata = (CPQFCHBA *)HostAdapter->hostdata;
- PTACHYON fcChip = &cpqfcHBAdata->fcChip;
- PFC_LOGGEDIN_PORT pLoggedInPort = NULL;
- struct scsi_cmnd *DumCmnd;
- int i, j;
- VENDOR_IOCTL_REQ ioc;
- cpqfc_passthru_t *vendor_cmd;
- Scsi_Device *SDpnt;
- Scsi_Request *ScsiPassThruReq;
- cpqfc_passthru_private_t *privatedata;
-
- ENTER("cpqfcTS_ioctl ");
-
- // printk("ioctl CMND %d", Cmnd);
- switch (Cmnd) {
- // Passthrough provides a mechanism to bypass the RAID
- // or other controller and talk directly to the devices
- // (e.g. physical disk drive)
- // Passthrough commands, unfortunately, tend to be vendor
- // specific; this is tailored to COMPAQ's RAID (RA4x00)
- case CPQFCTS_SCSI_PASSTHRU:
- {
- void *buf = NULL; // for kernel space buffer for user data
-
- /* Check that our pool got allocated ok. */
- if (cpqfcHBAdata->private_data_pool == NULL)
- return -ENOMEM;
-
- if( !arg)
- return -EINVAL;
-
- // must be super user to send stuff directly to the
- // controller and/or physical drives...
- if( !capable(CAP_SYS_RAWIO) )
- return -EPERM;
-
- // copy the caller's struct to our space.
- if( copy_from_user( &ioc, arg, sizeof( VENDOR_IOCTL_REQ)))
- return( -EFAULT);
-
- vendor_cmd = ioc.argp; // i.e., CPQ specific command struct
-
- // If necessary, grab a kernel/DMA buffer
- if( vendor_cmd->len)
- {
- buf = kmalloc( vendor_cmd->len, GFP_KERNEL);
- if( !buf)
- return -ENOMEM;
- }
- // Now build a Scsi_Request to pass down...
- ScsiPassThruReq = scsi_allocate_request(ScsiDev, GFP_KERNEL);
- if (ScsiPassThruReq == NULL) {
- kfree(buf);
- return -ENOMEM;
- }
- ScsiPassThruReq->upper_private_data =
- cpqfc_alloc_private_data(cpqfcHBAdata);
- if (ScsiPassThruReq->upper_private_data == NULL) {
- kfree(buf);
- scsi_release_request(ScsiPassThruReq); // "de-allocate"
- return -ENOMEM;
- }
-
- if (vendor_cmd->rw_flag == VENDOR_WRITE_OPCODE) {
- if (vendor_cmd->len) { // Need data from user?
- if (copy_from_user(buf, vendor_cmd->bufp,
- vendor_cmd->len)) {
- kfree(buf);
- cpqfc_free_private_data(cpqfcHBAdata,
- ScsiPassThruReq->upper_private_data);
- scsi_release_request(ScsiPassThruReq);
- return( -EFAULT);
- }
- }
- ScsiPassThruReq->sr_data_direction = DMA_TO_DEVICE;
- } else if (vendor_cmd->rw_flag == VENDOR_READ_OPCODE) {
- ScsiPassThruReq->sr_data_direction = DMA_FROM_DEVICE;
- } else
- // maybe this means a bug in the user app
- ScsiPassThruReq->sr_data_direction = DMA_BIDIRECTIONAL;
-
- ScsiPassThruReq->sr_cmd_len = 0; // set correctly by scsi_do_req()
- ScsiPassThruReq->sr_sense_buffer[0] = 0;
- ScsiPassThruReq->sr_sense_buffer[2] = 0;
-
- // We copy the scheme used by sd.c:spinup_disk() to submit commands
- // to our own HBA. We do this in order to stall the
- // thread calling the IOCTL until it completes, and use
- // the same "_quecommand" function for synchronizing
- // FC Link events with our "worker thread".
-
- privatedata = ScsiPassThruReq->upper_private_data;
- privatedata->bus = vendor_cmd->bus;
- privatedata->pdrive = vendor_cmd->pdrive;
-
- // eventually gets us to our own _quecommand routine
- scsi_wait_req(ScsiPassThruReq,
- &vendor_cmd->cdb[0], buf, vendor_cmd->len,
- 10*HZ, // timeout
- 1); // retries
- result = ScsiPassThruReq->sr_result;
-
- // copy any sense data back to caller
- if( result != 0 )
- {
- memcpy( vendor_cmd->sense_data, // see struct def - size=40
- ScsiPassThruReq->sr_sense_buffer,
- sizeof(ScsiPassThruReq->sr_sense_buffer) <
- sizeof(vendor_cmd->sense_data) ?
- sizeof(ScsiPassThruReq->sr_sense_buffer) :
- sizeof(vendor_cmd->sense_data)
- );
- }
- SDpnt = ScsiPassThruReq->sr_device;
- /* upper_private_data is already freed in call_scsi_done() */
- scsi_release_request(ScsiPassThruReq); // "de-allocate"
- ScsiPassThruReq = NULL;
-
- // need to pass data back to user (space)?
- if( (vendor_cmd->rw_flag == VENDOR_READ_OPCODE) &&
- vendor_cmd->len )
- if( copy_to_user( vendor_cmd->bufp, buf, vendor_cmd->len))
- result = -EFAULT;
-
- kfree(buf);
-
- return result;
- }
-
- case CPQFCTS_GETPCIINFO:
- {
- cpqfc_pci_info_struct pciinfo;
-
- if( !arg)
- return -EINVAL;
-
-
-
- pciinfo.bus = cpqfcHBAdata->PciDev->bus->number;
- pciinfo.dev_fn = cpqfcHBAdata->PciDev->devfn;
- pciinfo.board_id = cpqfcHBAdata->PciDev->device |
- (cpqfcHBAdata->PciDev->vendor <<16);
-
- if(copy_to_user( arg, &pciinfo, sizeof(cpqfc_pci_info_struct)))
- return( -EFAULT);
- return 0;
- }
-
- case CPQFCTS_GETDRIVVER:
- {
- DriverVer_type DriverVer =
- CPQFCTS_DRIVER_VER( VER_MAJOR,VER_MINOR,VER_SUBMINOR);
-
- if( !arg)
- return -EINVAL;
-
- if(copy_to_user( arg, &DriverVer, sizeof(DriverVer)))
- return( -EFAULT);
- return 0;
- }
-
-
-
- case CPQFC_IOCTL_FC_TARGET_ADDRESS:
- // can we find an FC device mapping to this SCSI target?
-/* DumCmnd.channel = ScsiDev->channel; */ // For searching
-/* DumCmnd.target = ScsiDev->id; */
-/* DumCmnd.lun = ScsiDev->lun; */
-
- DumCmnd = scsi_get_command (ScsiDev, GFP_KERNEL);
- if (!DumCmnd)
- return -ENOMEM;
-
- pLoggedInPort = fcFindLoggedInPort( fcChip,
- DumCmnd, // search Scsi Nexus
- 0, // DON'T search linked list for FC port id
- NULL, // DON'T search linked list for FC WWN
- NULL); // DON'T care about end of list
- scsi_put_command (DumCmnd);
- if (pLoggedInPort == NULL) {
- result = -ENXIO;
- break;
- }
- result = access_ok(VERIFY_WRITE, arg, sizeof(Scsi_FCTargAddress)) ? 0 : -EFAULT;
- if (result) break;
-
- put_user(pLoggedInPort->port_id,
- &((Scsi_FCTargAddress *) arg)->host_port_id);
-
- for( i=3,j=0; i>=0; i--) // copy the LOGIN port's WWN
- put_user(pLoggedInPort->u.ucWWN[i],
- &((Scsi_FCTargAddress *) arg)->host_wwn[j++]);
- for( i=7; i>3; i--) // copy the LOGIN port's WWN
- put_user(pLoggedInPort->u.ucWWN[i],
- &((Scsi_FCTargAddress *) arg)->host_wwn[j++]);
- break;
-
-
- case CPQFC_IOCTL_FC_TDR:
-
- result = cpqfcTS_TargetDeviceReset( ScsiDev, 0);
-
- break;
-
-
-
-
- default:
- result = -EINVAL;
- break;
- }
-
- LEAVE("cpqfcTS_ioctl");
- return result;
-}
-
-
-/* "Release" the Host Bus Adapter...
- disable interrupts, stop the HBA, release the interrupt,
- and free all resources */
-
-int cpqfcTS_release(struct Scsi_Host *HostAdapter)
-{
- CPQFCHBA *cpqfcHBAdata = (CPQFCHBA *)HostAdapter->hostdata;
-
-
- ENTER("cpqfcTS_release");
-
- DEBUG_PCI( printk(" cpqfcTS: delete timer...\n"));
- del_timer( &cpqfcHBAdata->cpqfcTStimer);
-
- // disable the hardware...
- DEBUG_PCI( printk(" disable hardware, destroy queues, free mem\n"));
- cpqfcHBAdata->fcChip.ResetTachyon( cpqfcHBAdata, CLEAR_FCPORTS);
-
- // kill kernel thread
- if( cpqfcHBAdata->worker_thread ) // (only if exists)
- {
- DECLARE_MUTEX_LOCKED(sem); // synchronize thread kill
-
- cpqfcHBAdata->notify_wt = &sem;
- DEBUG_PCI( printk(" killing kernel thread\n"));
- send_sig( SIGKILL, cpqfcHBAdata->worker_thread, 1);
- down( &sem);
- cpqfcHBAdata->notify_wt = NULL;
-
- }
-
- cpqfc_free_private_data_pool(cpqfcHBAdata);
- // free Linux resources
- DEBUG_PCI( printk(" cpqfcTS: freeing resources...\n"));
- free_irq( HostAdapter->irq, HostAdapter);
- scsi_unregister( HostAdapter);
- release_region( cpqfcHBAdata->fcChip.Registers.IOBaseL, 0xff);
- release_region( cpqfcHBAdata->fcChip.Registers.IOBaseU, 0xff);
- /* we get "vfree: bad address" executing this - need to investigate...
- if( (void*)((unsigned long)cpqfcHBAdata->fcChip.Registers.MemBase) !=
- cpqfcHBAdata->fcChip.Registers.ReMapMemBase)
- vfree( cpqfcHBAdata->fcChip.Registers.ReMapMemBase);
-*/
- pci_disable_device( cpqfcHBAdata->PciDev);
-
- LEAVE("cpqfcTS_release");
- return 0;
-}
-
-
-const char * cpqfcTS_info(struct Scsi_Host *HostAdapter)
-{
- static char buf[300];
- CPQFCHBA *cpqfcHBA;
- int BusSpeed, BusWidth;
-
- // get the pointer to our Scsi layer HBA buffer
- cpqfcHBA = (CPQFCHBA *)HostAdapter->hostdata;
-
- BusWidth = (cpqfcHBA->fcChip.Registers.PCIMCTR &0x4) > 0 ?
- 64 : 32;
-
- if( cpqfcHBA->fcChip.Registers.TYconfig.value & 0x80000000)
- BusSpeed = 66;
- else
- BusSpeed = 33;
-
- sprintf(buf,
-"%s: WWN %08X%08X\n on PCI bus %d device 0x%02x irq %d IObaseL 0x%x, MEMBASE 0x%x\nPCI bus width %d bits, bus speed %d MHz\nFCP-SCSI Driver v%d.%d.%d",
- cpqfcHBA->fcChip.Name,
- cpqfcHBA->fcChip.Registers.wwn_hi,
- cpqfcHBA->fcChip.Registers.wwn_lo,
- cpqfcHBA->PciDev->bus->number,
- cpqfcHBA->PciDev->device,
- HostAdapter->irq,
- cpqfcHBA->fcChip.Registers.IOBaseL,
- cpqfcHBA->fcChip.Registers.MemBase,
- BusWidth,
- BusSpeed,
- VER_MAJOR, VER_MINOR, VER_SUBMINOR
-);
-
-
- cpqfcTSDecodeGBICtype( &cpqfcHBA->fcChip, &buf[ strlen(buf)]);
- cpqfcTSGetLPSM( &cpqfcHBA->fcChip, &buf[ strlen(buf)]);
- return buf;
-}
-
-//
-// /proc/scsi support. The following routines allow us to do 'normal'
-// sprintf like calls to return the currently requested piece (buflenght
-// chars, starting at bufoffset) of the file. Although procfs allows for
-// a 1 Kb bytes overflow after te supplied buffer, I consider it bad
-// programming to use it to make programming a little simpler. This piece
-// of coding is borrowed from ncr53c8xx.c with some modifications
-//
-struct info_str
-{
- char *buffer; // Pointer to output buffer
- int buflength; // It's length
- int bufoffset; // File offset corresponding with buf[0]
- int buffillen; // Current filled length
- int filpos; // Current file offset
-};
-
-static void copy_mem_info(struct info_str *info, char *data, int datalen)
-{
-
- if (info->filpos < info->bufoffset) { // Current offset before buffer offset
- if (info->filpos + datalen <= info->bufoffset) {
- info->filpos += datalen; // Discard if completely before buffer
- return;
- } else { // Partial copy, set to begin
- data += (info->bufoffset - info->filpos);
- datalen -= (info->bufoffset - info->filpos);
- info->filpos = info->bufoffset;
- }
- }
-
- info->filpos += datalen; // Update current offset
-
- if (info->buffillen == info->buflength) // Buffer full, discard
- return;
-
- if (info->buflength - info->buffillen < datalen) // Overflows buffer ?
- datalen = info->buflength - info->buffillen;
-
- memcpy(info->buffer + info->buffillen, data, datalen);
- info->buffillen += datalen;
-}
-
-static int copy_info(struct info_str *info, char *fmt, ...)
-{
- va_list args;
- char buf[400];
- int len;
-
- va_start(args, fmt);
- len = vsprintf(buf, fmt, args);
- va_end(args);
-
- copy_mem_info(info, buf, len);
- return len;
-}
-
-
-// Routine to get data for /proc RAM filesystem
-//
-int cpqfcTS_proc_info (struct Scsi_Host *host, char *buffer, char **start, off_t offset, int length,
- int inout)
-{
- struct scsi_cmnd *DumCmnd;
- struct scsi_device *ScsiDev;
- int Chan, Targ, i;
- struct info_str info;
- CPQFCHBA *cpqfcHBA;
- PTACHYON fcChip;
- PFC_LOGGEDIN_PORT pLoggedInPort;
- char buf[81];
-
- if (inout) return -EINVAL;
-
- // get the pointer to our Scsi layer HBA buffer
- cpqfcHBA = (CPQFCHBA *)host->hostdata;
- fcChip = &cpqfcHBA->fcChip;
-
- *start = buffer;
-
- info.buffer = buffer;
- info.buflength = length;
- info.bufoffset = offset;
- info.filpos = 0;
- info.buffillen = 0;
- copy_info(&info, "Driver version = %d.%d.%d", VER_MAJOR, VER_MINOR, VER_SUBMINOR);
- cpqfcTSDecodeGBICtype( &cpqfcHBA->fcChip, &buf[0]);
- cpqfcTSGetLPSM( &cpqfcHBA->fcChip, &buf[ strlen(buf)]);
- copy_info(&info, "%s\n", buf);
-
-#define DISPLAY_WWN_INFO
-#ifdef DISPLAY_WWN_INFO
- ScsiDev = scsi_get_host_dev (host);
- if (!ScsiDev)
- return -ENOMEM;
- DumCmnd = scsi_get_command (ScsiDev, GFP_KERNEL);
- if (!DumCmnd) {
- scsi_free_host_dev (ScsiDev);
- return -ENOMEM;
- }
- copy_info(&info, "WWN database: (\"port_id: 000000\" means disconnected)\n");
- for ( Chan=0; Chan <= host->max_channel; Chan++) {
- DumCmnd->device->channel = Chan;
- for (Targ=0; Targ <= host->max_id; Targ++) {
- DumCmnd->device->id = Targ;
- if ((pLoggedInPort = fcFindLoggedInPort( fcChip,
- DumCmnd, // search Scsi Nexus
- 0, // DON'T search list for FC port id
- NULL, // DON'T search list for FC WWN
- NULL))){ // DON'T care about end of list
- copy_info(&info, "Host: scsi%d Channel: %02d TargetId: %02d -> WWN: ",
- host->host_no, Chan, Targ);
- for( i=3; i>=0; i--) // copy the LOGIN port's WWN
- copy_info(&info, "%02X", pLoggedInPort->u.ucWWN[i]);
- for( i=7; i>3; i--) // copy the LOGIN port's WWN
- copy_info(&info, "%02X", pLoggedInPort->u.ucWWN[i]);
- copy_info(&info, " port_id: %06X\n", pLoggedInPort->port_id);
- }
- }
- }
-
- scsi_put_command (DumCmnd);
- scsi_free_host_dev (ScsiDev);
-#endif
-
-
-
-
-
-// Unfortunately, the proc_info buffer isn't big enough
-// for everything we would like...
-// For FC stats, compile this and turn off WWN stuff above
-//#define DISPLAY_FC_STATS
-#ifdef DISPLAY_FC_STATS
-// get the Fibre Channel statistics
- {
- int DeltaSecs = (jiffies - cpqfcHBA->fcStatsTime) / HZ;
- int days,hours,minutes,secs;
-
- days = DeltaSecs / (3600*24); // days
- hours = (DeltaSecs% (3600*24)) / 3600; // hours
- minutes = (DeltaSecs%3600 /60); // minutes
- secs = DeltaSecs%60; // secs
-copy_info( &info, "Fibre Channel Stats (time dd:hh:mm:ss %02u:%02u:%02u:%02u\n",
- days, hours, minutes, secs);
- }
-
- cpqfcHBA->fcStatsTime = jiffies; // (for next delta)
-
- copy_info( &info, " LinkUp %9u LinkDown %u\n",
- fcChip->fcStats.linkUp, fcChip->fcStats.linkDown);
-
- copy_info( &info, " Loss of Signal %9u Loss of Sync %u\n",
- fcChip->fcStats.LossofSignal, fcChip->fcStats.LossofSync);
-
- copy_info( &info, " Discarded Frames %9u Bad CRC Frame %u\n",
- fcChip->fcStats.Dis_Frm, fcChip->fcStats.Bad_CRC);
-
- copy_info( &info, " TACH LinkFailTX %9u TACH LinkFailRX %u\n",
- fcChip->fcStats.linkFailTX, fcChip->fcStats.linkFailRX);
-
- copy_info( &info, " TACH RxEOFa %9u TACH Elastic Store %u\n",
- fcChip->fcStats.Rx_EOFa, fcChip->fcStats.e_stores);
-
- copy_info( &info, " BufferCreditWait %9uus TACH FM Inits %u\n",
- fcChip->fcStats.BB0_Timer*10, fcChip->fcStats.FMinits );
-
- copy_info( &info, " FC-2 Timeouts %9u FC-2 Logouts %u\n",
- fcChip->fcStats.timeouts, fcChip->fcStats.logouts);
-
- copy_info( &info, " FC-2 Aborts %9u FC-4 Aborts %u\n",
- fcChip->fcStats.FC2aborted, fcChip->fcStats.FC4aborted);
-
- // clear the counters
- cpqfcTSClearLinkStatusCounters( fcChip);
-#endif
-
- return info.buffillen;
-}
-
-
-#if DEBUG_CMND
-
-UCHAR *ScsiToAscii( UCHAR ScsiCommand)
-{
-
-/*++
-
-Routine Description:
-
- Converts a SCSI command to a text string for debugging purposes.
-
-
-Arguments:
-
- ScsiCommand -- hex value SCSI Command
-
-
-Return Value:
-
- An ASCII, null-terminated string if found, else returns NULL.
-
-Original code from M. McGowen, Compaq
---*/
-
-
- switch (ScsiCommand)
- {
- case 0x00:
- return( "Test Unit Ready" );
-
- case 0x01:
- return( "Rezero Unit or Rewind" );
-
- case 0x02:
- return( "Request Block Address" );
-
- case 0x03:
- return( "Requese Sense" );
-
- case 0x04:
- return( "Format Unit" );
-
- case 0x05:
- return( "Read Block Limits" );
-
- case 0x07:
- return( "Reassign Blocks" );
-
- case 0x08:
- return( "Read (6)" );
-
- case 0x0a:
- return( "Write (6)" );
-
- case 0x0b:
- return( "Seek (6)" );
-
- case 0x12:
- return( "Inquiry" );
-
- case 0x15:
- return( "Mode Select (6)" );
-
- case 0x16:
- return( "Reserve" );
-
- case 0x17:
- return( "Release" );
-
- case 0x1a:
- return( "ModeSen(6)" );
-
- case 0x1b:
- return( "Start/Stop Unit" );
-
- case 0x1c:
- return( "Receive Diagnostic Results" );
-
- case 0x1d:
- return( "Send Diagnostic" );
-
- case 0x25:
- return( "Read Capacity" );
-
- case 0x28:
- return( "Read (10)" );
-
- case 0x2a:
- return( "Write (10)" );
-
- case 0x2b:
- return( "Seek (10)" );
-
- case 0x2e:
- return( "Write and Verify" );
-
- case 0x2f:
- return( "Verify" );
-
- case 0x34:
- return( "Pre-Fetch" );
-
- case 0x35:
- return( "Synchronize Cache" );
-
- case 0x37:
- return( "Read Defect Data (10)" );
-
- case 0x3b:
- return( "Write Buffer" );
-
- case 0x3c:
- return( "Read Buffer" );
-
- case 0x3e:
- return( "Read Long" );
-
- case 0x3f:
- return( "Write Long" );
-
- case 0x41:
- return( "Write Same" );
-
- case 0x4c:
- return( "Log Select" );
-
- case 0x4d:
- return( "Log Sense" );
-
- case 0x56:
- return( "Reserve (10)" );
-
- case 0x57:
- return( "Release (10)" );
-
- case 0xa0:
- return( "ReportLuns" );
-
- case 0xb7:
- return( "Read Defect Data (12)" );
-
- case 0xca:
- return( "Peripheral Device Addressing SCSI Passthrough" );
-
- case 0xcb:
- return( "Compaq Array Firmware Passthrough" );
-
- default:
- return( NULL );
- }
-
-} // end ScsiToAscii()
-
-void cpqfcTS_print_scsi_cmd(Scsi_Cmnd * cmd)
-{
-
-printk("cpqfcTS: (%s) chnl 0x%02x, trgt = 0x%02x, lun = 0x%02x, cmd_len = 0x%02x\n",
- ScsiToAscii( cmd->cmnd[0]), cmd->channel, cmd->target, cmd->lun, cmd->cmd_len);
-
-if( cmd->cmnd[0] == 0) // Test Unit Ready?
-{
- int i;
-
- printk("Cmnd->request_bufflen = 0x%X, ->use_sg = %d, ->bufflen = %d\n",
- cmd->request_bufflen, cmd->use_sg, cmd->bufflen);
- printk("Cmnd->request_buffer = %p, ->sglist_len = %d, ->buffer = %p\n",
- cmd->request_buffer, cmd->sglist_len, cmd->buffer);
- for (i = 0; i < cmd->cmd_len; i++)
- printk("0x%02x ", cmd->cmnd[i]);
- printk("\n");
-}
-
-}
-
-#endif /* DEBUG_CMND */
-
-
-
-
-static void QueCmndOnBoardLock( CPQFCHBA *cpqfcHBAdata, Scsi_Cmnd *Cmnd)
-{
- int i;
-
- for( i=0; i< CPQFCTS_REQ_QUEUE_LEN; i++)
- { // find spare slot
- if( cpqfcHBAdata->BoardLockCmnd[i] == NULL )
- {
- cpqfcHBAdata->BoardLockCmnd[i] = Cmnd;
-// printk(" BoardLockCmnd[%d] %p Queued, chnl/target/lun %d/%d/%d\n",
-// i,Cmnd, Cmnd->channel, Cmnd->target, Cmnd->lun);
- break;
- }
- }
- if( i >= CPQFCTS_REQ_QUEUE_LEN)
- {
- printk(" cpqfcTS WARNING: Lost Cmnd %p on BoardLock Q full!", Cmnd);
- }
-
-}
-
-
-static void QueLinkDownCmnd( CPQFCHBA *cpqfcHBAdata, Scsi_Cmnd *Cmnd)
-{
- int indx;
-
- // Remember the command ptr so we can return; we'll complete when
- // the device comes back, causing immediate retry
- for( indx=0; indx < CPQFCTS_REQ_QUEUE_LEN; indx++)//, SCptr++)
- {
- if( cpqfcHBAdata->LinkDnCmnd[indx] == NULL ) // available?
- {
-#ifdef DUMMYCMND_DBG
- printk(" @add Cmnd %p to LnkDnCmnd[%d]@ ", Cmnd,indx);
-#endif
- cpqfcHBAdata->LinkDnCmnd[indx] = Cmnd;
- break;
- }
- }
-
- if( indx >= CPQFCTS_REQ_QUEUE_LEN ) // no space for Cmnd??
- {
- // this will result in an _abort call later (with possible trouble)
- printk("no buffer for LinkDnCmnd!! %p\n", Cmnd);
- }
-}
-
-
-
-
-
-// The file <scsi/scsi_host.h> says not to call scsi_done from
-// inside _queuecommand, so we'll do it from the heartbeat timer
-// (clarification: Turns out it's ok to call scsi_done from queuecommand
-// for cases that don't go to the hardware like scsi cmds destined
-// for LUNs we know don't exist, so this code might be simplified...)
-
-static void QueBadTargetCmnd( CPQFCHBA *cpqfcHBAdata, Scsi_Cmnd *Cmnd)
-{
- int i;
- // printk(" can't find target %d\n", Cmnd->target);
-
- for( i=0; i< CPQFCTS_MAX_TARGET_ID; i++)
- { // find spare slot
- if( cpqfcHBAdata->BadTargetCmnd[i] == NULL )
- {
- cpqfcHBAdata->BadTargetCmnd[i] = Cmnd;
-// printk(" BadTargetCmnd[%d] %p Queued, chnl/target/lun %d/%d/%d\n",
-// i,Cmnd, Cmnd->channel, Cmnd->target, Cmnd->lun);
- break;
- }
- }
-}
-
-
-// This is the "main" entry point for Linux Scsi commands --
-// it all starts here.
-
-int cpqfcTS_queuecommand(Scsi_Cmnd *Cmnd, void (* done)(Scsi_Cmnd *))
-{
- struct Scsi_Host *HostAdapter = Cmnd->device->host;
- CPQFCHBA *cpqfcHBAdata = (CPQFCHBA *)HostAdapter->hostdata;
- PTACHYON fcChip = &cpqfcHBAdata->fcChip;
- TachFCHDR_GCMND fchs; // only use for FC destination id field
- PFC_LOGGEDIN_PORT pLoggedInPort;
- ULONG ulStatus, SESTtype;
- LONG ExchangeID;
-
-
-
-
- ENTER("cpqfcTS_queuecommand");
-
- PCI_TRACEO( (ULONG)Cmnd, 0x98)
-
-
- Cmnd->scsi_done = done;
-#ifdef DEBUG_CMND
- cpqfcTS_print_scsi_cmd( Cmnd);
-#endif
-
- // prevent board contention with kernel thread...
-
- if( cpqfcHBAdata->BoardLock )
- {
-// printk(" @BrdLck Hld@ ");
- QueCmndOnBoardLock( cpqfcHBAdata, Cmnd);
- }
-
- else
- {
-
- // in the current system (2.2.12), this routine is called
- // after spin_lock_irqsave(), so INTs are disabled. However,
- // we might have something pending in the LinkQ, which
- // might cause the WorkerTask to run. In case that
- // happens, make sure we lock it out.
-
-
-
- PCI_TRACE( 0x98)
- CPQ_SPINLOCK_HBA( cpqfcHBAdata)
- PCI_TRACE( 0x98)
-
- // can we find an FC device mapping to this SCSI target?
- pLoggedInPort = fcFindLoggedInPort( fcChip,
- Cmnd, // search Scsi Nexus
- 0, // DON'T search linked list for FC port id
- NULL, // DON'T search linked list for FC WWN
- NULL); // DON'T care about end of list
-
- if( pLoggedInPort == NULL ) // not found!
- {
-// printk(" @Q bad targ cmnd %p@ ", Cmnd);
- QueBadTargetCmnd( cpqfcHBAdata, Cmnd);
- }
- else if (Cmnd->device->lun >= CPQFCTS_MAX_LUN)
- {
- printk(KERN_WARNING "cpqfc: Invalid LUN: %d\n", Cmnd->device->lun);
- QueBadTargetCmnd( cpqfcHBAdata, Cmnd);
- }
-
- else // we know what FC device to send to...
- {
-
- // does this device support FCP target functions?
- // (determined by PRLI field)
-
- if( !(pLoggedInPort->fcp_info & TARGET_FUNCTION) )
- {
- printk(" Doesn't support TARGET functions port_id %Xh\n",
- pLoggedInPort->port_id );
- QueBadTargetCmnd( cpqfcHBAdata, Cmnd);
- }
-
- // In this case (previous login OK), the device is temporarily
- // unavailable waiting for re-login, in which case we expect it
- // to be back in between 25 - 500ms.
- // If the FC port doesn't log back in within several seconds
- // (i.e. implicit "logout"), or we get an explicit logout,
- // we set "device_blocked" in Scsi_Device struct; in this
- // case 30 seconds will elapse before Linux/Scsi sends another
- // command to the device.
- else if( pLoggedInPort->prli != TRUE )
- {
-// printk("Device (Chnl/Target %d/%d) invalid PRLI, port_id %06lXh\n",
-// Cmnd->channel, Cmnd->target, pLoggedInPort->port_id);
- QueLinkDownCmnd( cpqfcHBAdata, Cmnd);
-// Need to use "blocked" flag??
-// Cmnd->device->device_blocked = TRUE; // just let it timeout
- }
- else // device supports TARGET functions, and is logged in...
- {
- // (context of fchs is to "reply" to...)
- fchs.s_id = pLoggedInPort->port_id; // destination FC address
-
- // what is the data direction? For data TO the device,
- // we need IWE (Intiator Write Entry). Otherwise, IRE.
-
- if( Cmnd->cmnd[0] == WRITE_10 ||
- Cmnd->cmnd[0] == WRITE_6 ||
- Cmnd->cmnd[0] == WRITE_BUFFER ||
- Cmnd->cmnd[0] == VENDOR_WRITE_OPCODE || // CPQ specific
- Cmnd->cmnd[0] == MODE_SELECT )
- {
- SESTtype = SCSI_IWE; // data from HBA to Device
- }
- else
- SESTtype = SCSI_IRE; // data from Device to HBA
-
- ulStatus = cpqfcTSBuildExchange(
- cpqfcHBAdata,
- SESTtype, // e.g. Initiator Read Entry (IRE)
- &fchs, // we are originator; only use d_id
- Cmnd, // Linux SCSI command (with scatter/gather list)
- &ExchangeID );// fcController->fcExchanges index, -1 if failed
-
- if( !ulStatus ) // Exchange setup?
-
- {
- if( cpqfcHBAdata->BoardLock )
- {
- TriggerHBA( fcChip->Registers.ReMapMemBase, 0);
- printk(" @bl! %d, xID %Xh@ ", current->pid, ExchangeID);
- }
-
- ulStatus = cpqfcTSStartExchange( cpqfcHBAdata, ExchangeID );
- if( !ulStatus )
- {
- PCI_TRACEO( ExchangeID, 0xB8)
- // submitted to Tach's Outbound Que (ERQ PI incremented)
- // waited for completion for ELS type (Login frames issued
- // synchronously)
- }
- else
- // check reason for Exchange not being started - we might
- // want to Queue and start later, or fail with error
- {
- printk("quecommand: cpqfcTSStartExchange failed: %Xh\n", ulStatus );
- }
- } // end good BuildExchange status
-
- else // SEST table probably full -- why? hardware hang?
- {
- printk("quecommand: cpqfcTSBuildExchange faild: %Xh\n", ulStatus);
- }
- } // end can't do FCP-SCSI target functions
- } // end can't find target (FC device)
-
- CPQ_SPINUNLOCK_HBA( cpqfcHBAdata)
- }
-
- PCI_TRACEO( (ULONG)Cmnd, 0x9C)
- LEAVE("cpqfcTS_queuecommand");
- return 0;
-}
-
-
-// Entry point for upper Scsi layer intiated abort. Typically
-// this is called if the command (for hard disk) fails to complete
-// in 30 seconds. This driver intends to complete all disk commands
-// within Exchange ".timeOut" seconds (now 7) with target status, or
-// in case of ".timeOut" expiration, a DID_SOFT_ERROR which causes
-// immediate retry.
-// If any disk commands get the _abort call, except for the case that
-// the physical device was removed or unavailable due to hardware
-// errors, it should be considered a driver error and reported to
-// the author.
-
-int cpqfcTS_abort(Scsi_Cmnd *Cmnd)
-{
-// printk(" cpqfcTS_abort called?? \n");
- return 0;
-}
-
-int cpqfcTS_eh_abort(Scsi_Cmnd *Cmnd)
-{
-
- struct Scsi_Host *HostAdapter = Cmnd->device->host;
- // get the pointer to our Scsi layer HBA buffer
- CPQFCHBA *cpqfcHBAdata = (CPQFCHBA *)HostAdapter->hostdata;
- PTACHYON fcChip = &cpqfcHBAdata->fcChip;
- FC_EXCHANGES *Exchanges = fcChip->Exchanges;
- int i;
- ENTER("cpqfcTS_eh_abort");
-
- Cmnd->result = DID_ABORT <<16; // assume we'll find it
-
- printk(" @Linux _abort Scsi_Cmnd %p ", Cmnd);
- // See if we can find a Cmnd pointer that matches...
- // The most likely case is we accepted the command
- // from Linux Scsi (e.g. ceated a SEST entry) and it
- // got lost somehow. If we can't find any reference
- // to the passed pointer, we can only presume it
- // got completed as far as our driver is concerned.
- // If we found it, we will try to abort it through
- // common mechanism. If FC ABTS is successful (ACC)
- // or is rejected (RJT) by target, we will call
- // Scsi "done" quickly. Otherwise, the ABTS will timeout
- // and we'll call "done" later.
-
- // Search the SEST exchanges for a matching Cmnd ptr.
- for( i=0; i< TACH_SEST_LEN; i++)
- {
- if( Exchanges->fcExchange[i].Cmnd == Cmnd )
- {
-
- // found it!
- printk(" x_ID %Xh, type %Xh\n", i, Exchanges->fcExchange[i].type);
-
- Exchanges->fcExchange[i].status = INITIATOR_ABORT; // seconds default
- Exchanges->fcExchange[i].timeOut = 10; // seconds default (changed later)
-
- // Since we need to immediately return the aborted Cmnd to Scsi
- // upper layers, we can't make future reference to any of its
- // fields (e.g the Nexus).
-
- cpqfcTSPutLinkQue( cpqfcHBAdata, BLS_ABTS, &i);
-
- break;
- }
- }
-
- if( i >= TACH_SEST_LEN ) // didn't find Cmnd ptr in chip's SEST?
- {
- // now search our non-SEST buffers (i.e. Cmnd waiting to
- // start on the HBA or waiting to complete with error for retry).
-
- // first check BadTargetCmnd
- for( i=0; i< CPQFCTS_MAX_TARGET_ID; i++)
- {
- if( cpqfcHBAdata->BadTargetCmnd[i] == Cmnd )
- {
- cpqfcHBAdata->BadTargetCmnd[i] = NULL;
- printk("in BadTargetCmnd Q\n");
- goto Done; // exit
- }
- }
-
- // if not found above...
-
- for( i=0; i < CPQFCTS_REQ_QUEUE_LEN; i++)
- {
- if( cpqfcHBAdata->LinkDnCmnd[i] == Cmnd )
- {
- cpqfcHBAdata->LinkDnCmnd[i] = NULL;
- printk("in LinkDnCmnd Q\n");
- goto Done;
- }
- }
-
-
- for( i=0; i< CPQFCTS_REQ_QUEUE_LEN; i++)
- { // find spare slot
- if( cpqfcHBAdata->BoardLockCmnd[i] == Cmnd )
- {
- cpqfcHBAdata->BoardLockCmnd[i] = NULL;
- printk("in BoardLockCmnd Q\n");
- goto Done;
- }
- }
-
- Cmnd->result = DID_ERROR <<16; // Hmmm...
- printk("Not found! ");
-// panic("_abort");
- }
-
-Done:
-
-// panic("_abort");
- LEAVE("cpqfcTS_eh_abort");
- return 0; // (see scsi.h)
-}
-
-
-// FCP-SCSI Target Device Reset
-// See dpANS Fibre Channel Protocol for SCSI
-// X3.269-199X revision 12, pg 25
-
-#ifdef SUPPORT_RESET
-
-int cpqfcTS_TargetDeviceReset( Scsi_Device *ScsiDev,
- unsigned int reset_flags)
-{
- int timeout = 10*HZ;
- int retries = 1;
- char scsi_cdb[12];
- int result;
- Scsi_Cmnd * SCpnt;
- Scsi_Device * SDpnt;
-
-// FIXME, cpqfcTS_TargetDeviceReset needs to be fixed
-// similarly to how the passthrough ioctl was fixed
-// around the 2.5.30 kernel. Scsi_Cmnd replaced with
-// Scsi_Request, etc.
-// For now, so people don't fall into a hole...
-
- // printk(" ENTERING cpqfcTS_TargetDeviceReset() - flag=%d \n",reset_flags);
-
- if (ScsiDev->host->eh_active) return FAILED;
-
- memset( scsi_cdb, 0, sizeof( scsi_cdb));
-
- scsi_cdb[0] = RELEASE;
-
- SCpnt = scsi_get_command(ScsiDev, GFP_KERNEL);
- {
- CPQFC_DECLARE_COMPLETION(wait);
-
- SCpnt->SCp.buffers_residual = FCP_TARGET_RESET;
-
- // FIXME: this would panic, SCpnt->request would be NULL.
- SCpnt->request->CPQFC_WAITING = &wait;
- scsi_do_cmd(SCpnt, scsi_cdb, NULL, 0, my_ioctl_done, timeout, retries);
- CPQFC_WAIT_FOR_COMPLETION(&wait);
- SCpnt->request->CPQFC_WAITING = NULL;
- }
-
-
- if(driver_byte(SCpnt->result) != 0)
- switch(SCpnt->sense_buffer[2] & 0xf) {
- case ILLEGAL_REQUEST:
- if(cmd[0] == ALLOW_MEDIUM_REMOVAL) dev->lockable = 0;
- else printk("SCSI device (ioctl) reports ILLEGAL REQUEST.\n");
- break;
- case NOT_READY: // This happens if there is no disc in drive
- if(dev->removable && (cmd[0] != TEST_UNIT_READY)){
- printk(KERN_INFO "Device not ready. Make sure there is a disc in the drive.\n");
- break;
- }
- case UNIT_ATTENTION:
- if (dev->removable){
- dev->changed = 1;
- SCpnt->result = 0; // This is no longer considered an error
- // gag this error, VFS will log it anyway /axboe
- // printk(KERN_INFO "Disc change detected.\n");
- break;
- };
- default: // Fall through for non-removable media
- printk("SCSI error: host %d id %d lun %d return code = %x\n",
- dev->host->host_no,
- dev->id,
- dev->lun,
- SCpnt->result);
- printk("\tSense class %x, sense error %x, extended sense %x\n",
- sense_class(SCpnt->sense_buffer[0]),
- sense_error(SCpnt->sense_buffer[0]),
- SCpnt->sense_buffer[2] & 0xf);
-
- };
- result = SCpnt->result;
-
- SDpnt = SCpnt->device;
- scsi_put_command(SCpnt);
- SCpnt = NULL;
-
- // printk(" LEAVING cpqfcTS_TargetDeviceReset() - return SUCCESS \n");
- return SUCCESS;
-}
-
-#else
-int cpqfcTS_TargetDeviceReset( Scsi_Device *ScsiDev,
- unsigned int reset_flags)
-{
- return -ENOTSUPP;
-}
-
-#endif /* SUPPORT_RESET */
-
-int cpqfcTS_eh_device_reset(Scsi_Cmnd *Cmnd)
-{
- int retval;
- Scsi_Device *SDpnt = Cmnd->device;
- // printk(" ENTERING cpqfcTS_eh_device_reset() \n");
- spin_unlock_irq(Cmnd->device->host->host_lock);
- retval = cpqfcTS_TargetDeviceReset( SDpnt, 0);
- spin_lock_irq(Cmnd->device->host->host_lock);
- return retval;
-}
-
-
-int cpqfcTS_reset(Scsi_Cmnd *Cmnd, unsigned int reset_flags)
-{
-
- ENTER("cpqfcTS_reset");
-
- LEAVE("cpqfcTS_reset");
- return SCSI_RESET_ERROR; /* Bus Reset Not supported */
-}
-
-/* This function determines the bios parameters for a given
- harddisk. These tend to be numbers that are made up by the
- host adapter. Parameters:
- size, device number, list (heads, sectors,cylinders).
- (from hosts.h)
-*/
-
-int cpqfcTS_biosparam(struct scsi_device *sdev, struct block_device *n,
- sector_t capacity, int ip[])
-{
- int size = capacity;
-
- ENTER("cpqfcTS_biosparam");
- ip[0] = 64;
- ip[1] = 32;
- ip[2] = size >> 11;
-
- if( ip[2] > 1024 )
- {
- ip[0] = 255;
- ip[1] = 63;
- ip[2] = size / (ip[0] * ip[1]);
- }
-
- LEAVE("cpqfcTS_biosparam");
- return 0;
-}
-
-
-
-irqreturn_t cpqfcTS_intr_handler( int irq,
- void *dev_id,
- struct pt_regs *regs)
-{
-
- unsigned long flags, InfLoopBrk=0;
- struct Scsi_Host *HostAdapter = dev_id;
- CPQFCHBA *cpqfcHBA = (CPQFCHBA *)HostAdapter->hostdata;
- int MoreMessages = 1; // assume we have something to do
- UCHAR IntPending;
- int handled = 0;
-
- ENTER("intr_handler");
- spin_lock_irqsave( HostAdapter->host_lock, flags);
- // is this our INT?
- IntPending = readb( cpqfcHBA->fcChip.Registers.INTPEND.address);
-
- // broken boards can generate messages forever, so
- // prevent the infinite loop
-#define INFINITE_IMQ_BREAK 10000
- if( IntPending )
- {
- handled = 1;
- // mask our HBA interrupts until we handle it...
- writeb( 0, cpqfcHBA->fcChip.Registers.INTEN.address);
-
- if( IntPending & 0x4) // "INT" - Tach wrote to IMQ
- {
- while( (++InfLoopBrk < INFINITE_IMQ_BREAK) && (MoreMessages ==1) )
- {
- MoreMessages = CpqTsProcessIMQEntry( HostAdapter); // ret 0 when done
- }
- if( InfLoopBrk >= INFINITE_IMQ_BREAK )
- {
- printk("WARNING: Compaq FC adapter generating excessive INTs -REPLACE\n");
- printk("or investigate alternate causes (e.g. physical FC layer)\n");
- }
-
- else // working normally - re-enable INTs and continue
- writeb( 0x1F, cpqfcHBA->fcChip.Registers.INTEN.address);
-
- } // (...ProcessIMQEntry() clears INT by writing IMQ consumer)
- else // indications of errors or problems...
- // these usually indicate critical system hardware problems.
- {
- if( IntPending & 0x10 )
- printk(" cpqfcTS adapter external memory parity error detected\n");
- if( IntPending & 0x8 )
- printk(" cpqfcTS adapter PCI master address crossed 45-bit boundary\n");
- if( IntPending & 0x2 )
- printk(" cpqfcTS adapter DMA error detected\n");
- if( IntPending & 0x1 ) {
- UCHAR IntStat;
- printk(" cpqfcTS adapter PCI error detected\n");
- IntStat = readb( cpqfcHBA->fcChip.Registers.INTSTAT.address);
- printk("cpqfc: ISR = 0x%02x\n", IntStat);
- if (IntStat & 0x1) {
- __u16 pcistat;
- /* read the pci status register */
- pci_read_config_word(cpqfcHBA->PciDev, 0x06, &pcistat);
- printk("PCI status register is 0x%04x\n", pcistat);
- if (pcistat & 0x8000) printk("Parity Error Detected.\n");
- if (pcistat & 0x4000) printk("Signalled System Error\n");
- if (pcistat & 0x2000) printk("Received Master Abort\n");
- if (pcistat & 0x1000) printk("Received Target Abort\n");
- if (pcistat & 0x0800) printk("Signalled Target Abort\n");
- }
- if (IntStat & 0x4) printk("(INT)\n");
- if (IntStat & 0x8)
- printk("CRS: PCI master address crossed 46 bit bouandary\n");
- if (IntStat & 0x10) printk("MRE: external memory parity error.\n");
- }
- }
- }
- spin_unlock_irqrestore( HostAdapter->host_lock, flags);
- LEAVE("intr_handler");
- return IRQ_RETVAL(handled);
-}
-
-
-
-
-int cpqfcTSDecodeGBICtype( PTACHYON fcChip, char cErrorString[])
-{
- // Verify GBIC type (if any) and correct Tachyon Port State Machine
- // (GBIC) module definition is:
- // GPIO1, GPIO0, GPIO4 for MD2, MD1, MD0. The input states appear
- // to be inverted -- i.e., a setting of 111 is read when there is NO
- // GBIC present. The Module Def (MD) spec says 000 is "no GBIC"
- // Hard code the bit states to detect Copper,
- // Long wave (single mode), Short wave (multi-mode), and absent GBIC
-
- ULONG ulBuff;
-
- sprintf( cErrorString, "\nGBIC detected: ");
-
- ulBuff = fcChip->Registers.TYstatus.value & 0x13;
- switch( ulBuff )
- {
- case 0x13: // GPIO4, GPIO1, GPIO0 = 111; no GBIC!
- sprintf( &cErrorString[ strlen( cErrorString)],
- "NONE! ");
- return FALSE;
-
-
- case 0x11: // Copper GBIC detected
- sprintf( &cErrorString[ strlen( cErrorString)],
- "Copper. ");
- break;
-
- case 0x10: // Long-wave (single mode) GBIC detected
- sprintf( &cErrorString[ strlen( cErrorString)],
- "Long-wave. ");
- break;
- case 0x1: // Short-wave (multi mode) GBIC detected
- sprintf( &cErrorString[ strlen( cErrorString)],
- "Short-wave. ");
- break;
- default: // unknown GBIC - presumably it will work (?)
- sprintf( &cErrorString[ strlen( cErrorString)],
- "Unknown. ");
-
- break;
- } // end switch GBIC detection
-
- return TRUE;
-}
-
-
-
-
-
-
-int cpqfcTSGetLPSM( PTACHYON fcChip, char cErrorString[])
-{
- // Tachyon's Frame Manager LPSM in LinkDown state?
- // (For non-loop port, check PSM instead.)
- // return string with state and FALSE is Link Down
-
- int LinkUp;
-
- if( fcChip->Registers.FMstatus.value & 0x80 )
- LinkUp = FALSE;
- else
- LinkUp = TRUE;
-
- sprintf( &cErrorString[ strlen( cErrorString)],
- " LPSM %Xh ",
- (fcChip->Registers.FMstatus.value >>4) & 0xf );
-
-
- switch( fcChip->Registers.FMstatus.value & 0xF0)
- {
- // bits set in LPSM
- case 0x10:
- sprintf( &cErrorString[ strlen( cErrorString)], "ARB");
- break;
- case 0x20:
- sprintf( &cErrorString[ strlen( cErrorString)], "ARBwon");
- break;
- case 0x30:
- sprintf( &cErrorString[ strlen( cErrorString)], "OPEN");
- break;
- case 0x40:
- sprintf( &cErrorString[ strlen( cErrorString)], "OPENed");
- break;
- case 0x50:
- sprintf( &cErrorString[ strlen( cErrorString)], "XmitCLS");
- break;
- case 0x60:
- sprintf( &cErrorString[ strlen( cErrorString)], "RxCLS");
- break;
- case 0x70:
- sprintf( &cErrorString[ strlen( cErrorString)], "Xfer");
- break;
- case 0x80:
- sprintf( &cErrorString[ strlen( cErrorString)], "Init");
- break;
- case 0x90:
- sprintf( &cErrorString[ strlen( cErrorString)], "O-IInitFin");
- break;
- case 0xa0:
- sprintf( &cErrorString[ strlen( cErrorString)], "O-IProtocol");
- break;
- case 0xb0:
- sprintf( &cErrorString[ strlen( cErrorString)], "O-ILipRcvd");
- break;
- case 0xc0:
- sprintf( &cErrorString[ strlen( cErrorString)], "HostControl");
- break;
- case 0xd0:
- sprintf( &cErrorString[ strlen( cErrorString)], "LoopFail");
- break;
- case 0xe0:
- sprintf( &cErrorString[ strlen( cErrorString)], "Offline");
- break;
- case 0xf0:
- sprintf( &cErrorString[ strlen( cErrorString)], "OldPort");
- break;
- case 0:
- default:
- sprintf( &cErrorString[ strlen( cErrorString)], "Monitor");
- break;
-
- }
-
- return LinkUp;
-}
-
-
-
-
-#include "linux/slab.h"
-
-// Dynamic memory allocation alignment routines
-// HP's Tachyon Fibre Channel Controller chips require
-// certain memory queues and register pointers to be aligned
-// on various boundaries, usually the size of the Queue in question.
-// Alignment might be on 2, 4, 8, ... or even 512 byte boundaries.
-// Since most O/Ss don't allow this (usually only Cache aligned -
-// 32-byte boundary), these routines provide generic alignment (after
-// O/S allocation) at any boundary, and store the original allocated
-// pointer for deletion (O/S free function). Typically, we expect
-// these functions to only be called at HBA initialization and
-// removal time (load and unload times)
-// ALGORITHM notes:
-// Memory allocation varies by compiler and platform. In the worst case,
-// we are only assured BYTE alignment, but in the best case, we can
-// request allocation on any desired boundary. Our strategy: pad the
-// allocation request size (i.e. waste memory) so that we are assured
-// of passing desired boundary near beginning of contiguous space, then
-// mask out lower address bits.
-// We define the following algorithm:
-// allocBoundary - compiler/platform specific address alignment
-// in number of bytes (default is single byte; i.e. 1)
-// n_alloc - number of bytes application wants @ aligned address
-// ab - alignment boundary, in bytes (e.g. 4, 32, ...)
-// t_alloc - total allocation needed to ensure desired boundary
-// mask - to clear least significant address bits for boundary
-// Compute:
-// t_alloc = n_alloc + (ab - allocBoundary)
-// allocate t_alloc bytes @ alloc_address
-// mask = NOT (ab - 1)
-// (e.g. if ab=32 _0001 1111 -> _1110 0000
-// aligned_address = alloc_address & mask
-// set n_alloc bytes to 0
-// return aligned_address (NULL if failed)
-//
-// If u32_AlignedAddress is non-zero, then search for BaseAddress (stored
-// from previous allocation). If found, invoke call to FREE the memory.
-// Return NULL if BaseAddress not found
-
-// we need about 8 allocations per HBA. Figuring at most 10 HBAs per server
-// size the dynamic_mem array at 80.
-
-void* fcMemManager( struct pci_dev *pdev, ALIGNED_MEM *dynamic_mem,
- ULONG n_alloc, ULONG ab, ULONG u32_AlignedAddress,
- dma_addr_t *dma_handle)
-{
- USHORT allocBoundary=1; // compiler specific - worst case 1
- // best case - replace malloc() call
- // with function that allocates exactly
- // at desired boundary
-
- unsigned long ulAddress;
- ULONG t_alloc, i;
- void *alloc_address = 0; // def. error code / address not found
- LONG mask; // must be 32-bits wide!
-
- ENTER("fcMemManager");
- if( u32_AlignedAddress ) // are we freeing existing memory?
- {
-// printk(" freeing AlignedAddress %Xh\n", u32_AlignedAddress);
- for( i=0; i<DYNAMIC_ALLOCATIONS; i++) // look for the base address
- {
-// printk("dynamic_mem[%u].AlignedAddress %lX\n", i, dynamic_mem[i].AlignedAddress);
- if( dynamic_mem[i].AlignedAddress == u32_AlignedAddress )
- {
- alloc_address = dynamic_mem[i].BaseAllocated; // 'success' status
- pci_free_consistent(pdev,dynamic_mem[i].size,
- alloc_address,
- dynamic_mem[i].dma_handle);
- dynamic_mem[i].BaseAllocated = 0; // clear for next use
- dynamic_mem[i].AlignedAddress = 0;
- dynamic_mem[i].size = 0;
- break; // quit for loop; done
- }
- }
- }
- else if( n_alloc ) // want new memory?
- {
- dma_addr_t handle;
- t_alloc = n_alloc + (ab - allocBoundary); // pad bytes for alignment
-// printk("pci_alloc_consistent() for Tach alignment: %ld bytes\n", t_alloc);
-
-// (would like to) allow thread block to free pages
- alloc_address = // total bytes (NumberOfBytes)
- pci_alloc_consistent(pdev, t_alloc, &handle);
-
- // now mask off least sig. bits of address
- if( alloc_address ) // (only if non-NULL)
- {
- // find place to store ptr, so we
- // can free it later...
-
- mask = (LONG)(ab - 1); // mask all low-order bits
- mask = ~mask; // invert bits
- for( i=0; i<DYNAMIC_ALLOCATIONS; i++) // look for free slot
- {
- if( dynamic_mem[i].BaseAllocated == 0) // take 1st available
- {
- dynamic_mem[i].BaseAllocated = alloc_address;// address from O/S
- dynamic_mem[i].dma_handle = handle;
- if (dma_handle != NULL)
- {
-// printk("handle = %p, ab=%d, boundary = %d, mask=0x%08x\n",
-// handle, ab, allocBoundary, mask);
- *dma_handle = (dma_addr_t)
- ((((ULONG)handle) + (ab - allocBoundary)) & mask);
- }
- dynamic_mem[i].size = t_alloc;
- break;
- }
- }
- ulAddress = (unsigned long)alloc_address;
-
- ulAddress += (ab - allocBoundary); // add the alignment bytes-
- // then truncate address...
- alloc_address = (void*)(ulAddress & mask);
-
- dynamic_mem[i].AlignedAddress =
- (ULONG)(ulAddress & mask); // 32bit Tach address
- memset( alloc_address, 0, n_alloc ); // clear new memory
- }
- else // O/S dynamic mem alloc failed!
- alloc_address = 0; // (for debugging breakpt)
-
- }
-
- LEAVE("fcMemManager");
- return alloc_address; // good (or NULL) address
-}
-
-
-static Scsi_Host_Template driver_template = {
- .detect = cpqfcTS_detect,
- .release = cpqfcTS_release,
- .info = cpqfcTS_info,
- .proc_info = cpqfcTS_proc_info,
- .ioctl = cpqfcTS_ioctl,
- .queuecommand = cpqfcTS_queuecommand,
- .eh_device_reset_handler = cpqfcTS_eh_device_reset,
- .eh_abort_handler = cpqfcTS_eh_abort,
- .bios_param = cpqfcTS_biosparam,
- .can_queue = CPQFCTS_REQ_QUEUE_LEN,
- .this_id = -1,
- .sg_tablesize = SG_ALL,
- .cmd_per_lun = CPQFCTS_CMD_PER_LUN,
- .use_clustering = ENABLE_CLUSTERING,
-};
-#include "scsi_module.c"
-
diff --git a/drivers/scsi/cpqfcTSioctl.h b/drivers/scsi/cpqfcTSioctl.h
deleted file mode 100644
index 825536969126..000000000000
--- a/drivers/scsi/cpqfcTSioctl.h
+++ /dev/null
@@ -1,94 +0,0 @@
-// for user apps, make sure data size types are defined
-// with
-
-
-#define CCPQFCTS_IOC_MAGIC 'Z'
-
-typedef struct
-{
- __u8 bus;
- __u8 dev_fn;
- __u32 board_id;
-} cpqfc_pci_info_struct;
-
-typedef __u32 DriverVer_type;
-/*
-typedef union
-{
- struct // Peripheral Unit Device
- {
- __u8 Bus:6;
- __u8 Mode:2; // b00
- __u8 Dev;
- } PeripDev;
- struct // Volume Set Address
- {
- __u8 DevMSB:6;
- __u8 Mode:2; // b01
- __u8 DevLSB;
- } LogDev;
- struct // Logical Unit Device (SCSI-3, SCC-2 defined)
- {
- __u8 Targ:6;
- __u8 Mode:2; // b10
- __u8 Dev:5;
- __u8 Bus:3;
-
- } LogUnit;
-} SCSI3Addr_struct;
-
-
-typedef struct
-{
- SCSI3Addr_struct FCP_Nexus;
- __u8 cdb[16];
-} PassThru_Command_struct;
-*/
-
-/* this is nearly duplicated in idashare.h */
-typedef struct {
- int lc; /* Controller number */
- int node; /* Node (box) number */
- int ld; /* Logical Drive on this box, if required */
- __u32 nexus; /* SCSI Nexus */
- void *argp; /* Argument pointer */
-} VENDOR_IOCTL_REQ;
-
-
-typedef struct {
- char cdb[16]; /* SCSI CDB for the pass-through */
- ushort bus; /* Target bus on the box */
- ushort pdrive; /* Physical drive on the box */
- int len; /* Length of the data area of the CDB */
- int sense_len; /* Length of the sense data */
- char sense_data[40]; /* Sense data */
- void *bufp; /* Data area for the CDB */
- char rw_flag; /* Read CDB or Write CDB */
-} cpqfc_passthru_t;
-
-/*
-** Defines for the IOCTLS.
-*/
-
-#define VENDOR_READ_OPCODE 0x26
-#define VENDOR_WRITE_OPCODE 0x27
-
-#define CPQFCTS_GETPCIINFO _IOR( CCPQFCTS_IOC_MAGIC, 1, cpqfc_pci_info_struct)
-#define CPQFCTS_GETDRIVVER _IOR( CCPQFCTS_IOC_MAGIC, 9, DriverVer_type)
-
-#define CPQFCTS_SCSI_PASSTHRU _IOWR( CCPQFCTS_IOC_MAGIC,11, VENDOR_IOCTL_REQ)
-
-/* We would rather have equivalent generic, low-level driver agnostic
-ioctls that do what CPQFC_IOCTL_FC_TARGET_ADDRESS and
-CPQFC_IOCTL_FC_TDR 0x5388 do, but currently, we do not have them,
-consequently applications would have to know they are talking to cpqfc. */
-
-/* Used to get Fibre Channel WWN and port_id from device */
-// #define CPQFC_IOCTL_FC_TARGET_ADDRESS 0x5387
-#define CPQFC_IOCTL_FC_TARGET_ADDRESS \
- _IOR( CCPQFCTS_IOC_MAGIC, 13, Scsi_FCTargAddress)
-
-/* Used to invoke Target Defice Reset for Fibre Channel */
-// #define CPQFC_IOCTL_FC_TDR 0x5388
-#define CPQFC_IOCTL_FC_TDR _IO( CCPQFCTS_IOC_MAGIC, 15)
-
diff --git a/drivers/scsi/cpqfcTSstructs.h b/drivers/scsi/cpqfcTSstructs.h
deleted file mode 100644
index 0bae3298c44b..000000000000
--- a/drivers/scsi/cpqfcTSstructs.h
+++ /dev/null
@@ -1,1530 +0,0 @@
-/* Copyright(c) 2000, Compaq Computer Corporation
- * Fibre Channel Host Bus Adapter 64-bit, 66MHz PCI
- * Originally developed and tested on:
- * (front): [chip] Tachyon TS HPFC-5166A/1.2 L2C1090 ...
- * SP# P225CXCBFIEL6T, Rev XC
- * SP# 161290-001, Rev XD
- * (back): Board No. 010008-001 A/W Rev X5, FAB REV X5
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2, or (at your option) any
- * later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- * Written by Don Zimmerman
-*/
-#ifndef CPQFCTSSTRUCTS_H
-#define CPQFCTSSTRUCTS_H
-
-#include <linux/timer.h> // timer declaration in our host data
-#include <linux/interrupt.h>
-#include <asm/atomic.h>
-#include "cpqfcTSioctl.h"
-
-#define DbgDelay(secs) { int wait_time; printk( " DbgDelay %ds ", secs); \
- for( wait_time=jiffies + (secs*HZ); \
- time_before(jiffies, wait_time) ;) ; }
-
-#define CPQFCTS_DRIVER_VER(maj,min,submin) ((maj<<16)|(min<<8)|(submin))
-// don't forget to also change MODULE_DESCRIPTION in cpqfcTSinit.c
-#define VER_MAJOR 2
-#define VER_MINOR 5
-#define VER_SUBMINOR 4
-
-// Macros for kernel (esp. SMP) tracing using a PCI analyzer
-// (e.g. x86).
-//#define PCI_KERNEL_TRACE
-#ifdef PCI_KERNEL_TRACE
-#define PCI_TRACE(x) inl( fcChip->Registers.IOBaseL +x);
-#define PCI_TRACEO(x,y) outl( x, (fcChip->Registers.IOBaseL +y));
-#else
-
-#define PCI_TRACE(x)
-#define PCI_TRACEO(x,y)
-#endif
-
-
-//#define DEBUG_CMND 1 // debug output for Linux Scsi CDBs
-//#define DUMMYCMND_DBG 1
-
-//#define DEBUG_CPQFCTS 1
-//#undef DEBUG_CPQFCTS
-#ifdef DEBUG_CPQFCTS
-#define ENTER(x) printk("cpqfcts : entering %s()\n", x);
-#define LEAVE(x) printk("cpqfcts : leaving %s()\n", x);
-#define DEBUG(x) x
-#else
-#define ENTER(x)
-#define LEAVE(x)
-#define DEBUG(x)
-#endif /* DEBUG_CPQFCTS */
-
-//#define DEBUG_CPQFCTS_PCI 1
-//#undef DEBUG_CPQFCTS_PCI
-#if DEBUG_CPQFCTS_PCI
-#define DEBUG_PCI(x) x
-#else
-#define DEBUG_PCI(x)
-#endif /* DEBUG_CPQFCTS_PCI */
-
-#define STACHLITE66_TS12 "Compaq FibreChannel HBA Tachyon TS HPFC-5166A/1.2"
-#define STACHLITE66_TS13 "Compaq FibreChannel HBA Tachyon TS HPFC-5166A/1.3"
-#define STACHLITE_UNKNOWN "Compaq FibreChannel HBA Tachyon Chip/Board Ver??"
-#define SAGILENT_XL2_21 "Agilent FC HBA, Tachyon XL2 HPFC-5200B/2.1"
-
-// PDA is Peripheral Device Address, VSA is Volume Set Addressing
-// Linux SCSI parameters
-#define CPQFCTS_MAX_TARGET_ID 64
-
-// Note, changing CPQFCTS_MAX_LUN to less than 32 (e.g, 8) will result in
-// strange behavior if a box with more than, e.g. 8, is on the loop.
-#define CPQFCTS_MAX_LUN 32 // The RA-4x00 supports 32 (Linux SCSI supports 8)
-#define CPQFCTS_MAX_CHANNEL 0 // One FC port on cpqfcTS HBA
-
-#define CPQFCTS_CMD_PER_LUN 15 // power of 2 -1, must be >0
-#define CPQFCTS_REQ_QUEUE_LEN (TACH_SEST_LEN/2) // must be < TACH_SEST_LEN
-
-#define LinuxVersionCode(v, p, s) (((v)<<16)+((p)<<8)+(s))
-#ifndef DECLARE_MUTEX_LOCKED
-#define DECLARE_MUTEX_LOCKED(sem) struct semaphore sem = MUTEX_LOCKED
-#endif
-
-#define DEV_NAME "cpqfcTS"
-
-struct SupportedPCIcards
-{
- __u16 vendor_id;
- __u16 device_id;
-};
-
-// nn:nn denotes bit field
- // TachyonHeader struct def.
- // the fields shared with ODB
- // need to have same value
-
-
-
-
-#ifndef BYTE
-//typedef UCHAR BYTE;
-typedef __u8 BYTE;
-#endif
-#ifndef UCHAR
-typedef __u8 UCHAR;
-#endif
-#ifndef LONG
-typedef __s32 LONG;
-#endif
-#ifndef ULONG
-typedef __u32 ULONG;
-#endif
-#ifndef PVOID
-typedef void * PVOID;
-#endif
-#ifndef USHORT
-typedef __u16 USHORT;
-#endif
-#ifndef BOOLEAN
-typedef __u8 BOOLEAN;
-#endif
-
-
-// macro for FC-PH reject codes
-// payload format for LS_RJT (FC payloads are big endian):
-// byte 0 1 2 3 (MSB)
-// DWORD 0 01 00 00 00
-// DWORD 1 resvd code expl. vendor
-
-#define LS_RJT_REASON( code, expl) (( code<<8) | (expl <<16))
-
-
-#define TachLiteSTATUS 0x12
-
-// Fibre Channel EXCHANGE status codes for Tachyon chips/ driver software
-// 32-bit ERROR word defines
-#define INVALID_ARGS 0x1
-#define LNKDWN_OSLS 0x2
-#define LNKDWN_LASER 0x4
-#define OUTQUE_FULL 0x8
-#define DRIVERQ_FULL 0x10
-#define SEST_FULL 0x20
-#define BAD_ALPA 0x40
-#define OVERFLOW 0x80 // inbound CM
-#define COUNT_ERROR 0x100 // inbound CM
-#define LINKFAIL_RX 0x200 // inbound CM
-#define ABORTSEQ_NOTIFY 0x400 // outbound CM
-#define LINKFAIL_TX 0x800 // outbound CM
-#define HOSTPROG_ERR 0x1000 // outbound CM
-#define FRAME_TO 0x2000 // outbound CM
-#define INV_ENTRY 0x4000 // outbound CM
-#define SESTPROG_ERR 0x8000 // outbound CM
-#define OUTBOUND_TIMEOUT 0x10000L // timeout waiting for Tachyon outbound CM
-#define INITIATOR_ABORT 0x20000L // initiator exchange timeout or O/S ABORT
-#define MEMPOOL_FAIL 0x40000L // O/S memory pool allocation failed
-#define FC2_TIMEOUT 0x80000L // driver timeout for lost frames
-#define TARGET_ABORT 0x100000L // ABTS received from FC port
-#define EXCHANGE_QUEUED 0x200000L // e.g. Link State was LDn on fcStart
-#define PORTID_CHANGED 0x400000L // fc Port address changed
-#define DEVICE_REMOVED 0x800000L // fc Port address changed
-// Several error scenarios result in SEST Exchange frames
-// unexpectedly arriving in the SFQ
-#define SFQ_FRAME 0x1000000L // SFQ frames from open Exchange
-
-// Maximum number of Host Bus Adapters (HBA) / controllers supported
-// only important for mem allocation dimensions - increase as necessary
-
-#define MAX_ADAPTERS 8
-#define MAX_RX_PAYLOAD 1024 // hardware dependent max frame payload
-// Tach header struc defines
-#define SOFi3 0x7
-#define SOFf 0x8
-#define SOFn3 0xB
-#define EOFn 0x5
-#define EOFt 0x6
-
-// FCP R_CTL defines
-#define FCP_CMND 0x6
-#define FCP_XFER_RDY 0x5
-#define FCP_RSP 0x7
-#define FCP_RESPONSE 0x777 // (arbitrary #)
-#define NEED_FCP_RSP 0x77 // (arbitrary #)
-#define FCP_DATA 0x1
-
-#define RESET_TACH 0x100 // Reset Tachyon/TachLite
-#define SCSI_IWE 0x2000 // initiator write entry (for SEST)
-#define SCSI_IRE 0x3000 // initiator read entry (for SEST)
-#define SCSI_TRE 0x400 // target read entry (for SEST)
-#define SCSI_TWE 0x500 // target write entry (for SEST)
-#define TOGGLE_LASER 0x800
-#define LIP 0x900
-#define CLEAR_FCPORTS 99 // (arbitrary #) free mem for Logged in ports
-#define FMINIT 0x707 // (arbitrary) for Frame Manager Init command
-
-// BLS == Basic Link Service
-// ELS == Extended Link Service
-#define BLS_NOP 4
-#define BLS_ABTS 0x10 // FC-PH Basic Link Service Abort Sequence
-#define BLS_ABTS_ACC 0x100 // FC-PH Basic Link Service Abort Sequence Accept
-#define BLS_ABTS_RJT 0x101 // FC-PH Basic Link Service Abort Sequence Reject
-#define ELS_PLOGI 0x03 // FC-PH Port Login (arbitrary assign)
-#define ELS_SCR 0x70 // (arb assign) State Change Registration (Fabric)
-#define FCS_NSR 0x72 // (arb assign) Name Service Request (Fabric)
-#define ELS_FLOGI 0x44 // (arb assign) Fabric Login
-#define ELS_FDISC 0x41 // (arb assign) Fabric Discovery (Login)
-#define ELS_PDISC 0x50 // FC-PH2 Port Discovery
-#define ELS_ABTX 0x06 // FC-PH Abort Exchange
-#define ELS_LOGO 0x05 // FC-PH Port Logout
-#define ELS_PRLI 0x20 // FCP-SCSI Process Login
-#define ELS_PRLO 0x21 // FCP-SCSI Process Logout
-#define ELS_LOGO_ACC 0x07 // {FC-PH} Port Logout Accept
-#define ELS_PLOGI_ACC 0x08 // {FC-PH} Port Login Accept
-#define ELS_ACC 0x18 // {FC-PH} (generic) ACCept
-#define ELS_PRLI_ACC 0x22 // {FCP-SCSI} Process Login Accept
-#define ELS_RJT 0x1000000
-#define SCSI_REPORT_LUNS 0x0A0
-#define FCP_TARGET_RESET 0x200
-
-#define ELS_LILP_FRAME 0x00000711 // 1st payload word of LILP frame
-
-#define SFQ_UNASSISTED_FCP 1 // ICM, DWord3, "Type" unassisted FCP
-#define SFQ_UNKNOWN 0x31 // (arbitrary) ICM, DWord3, "Type" unknown
-
-// these "LINK" bits refer to loop or non-loop
-#define LINKACTIVE 0x2 // fcLinkQ type - LINK UP Tachyon FM 'Lup' bit set
-#define LINKDOWN 0xf2 // fcLinkQ type - LINK DOWN Tachyon FM 'Ldn' bit set
-
-//#define VOLUME_SET_ADDRESSING 1 // "channel" or "bus" 1
-
-typedef struct // 32 bytes hdr ONLY (e.g. FCP_DATA buffer for SEST)
-{
- ULONG reserved; // dword 0 (don't use)
- ULONG sof_eof;
- ULONG d_id; // dword 2 - 31:24 R_CTL, 23:0 D_ID
- ULONG s_id; // dword 3 - 31:24 CS_CTL, 23:0 S_ID
- ULONG f_ctl; // dword 4 - 31:24 Type, 23:0 F_CTL
- ULONG seq_cnt; // dword 5 - 31:24 SEQ_ID, 23:16 DF_CTL, 15:0 SEQ_CNT
- ULONG ox_rx_id; // dword 6 - 31:16 OX_ID, 15:0 RX_ID
- ULONG ro; // dword 7 - relative offset
-} TachFCHDR;
-
- // NOTE!! the following struct MUST be 64 bytes.
-typedef struct // 32 bytes hdr + 32 bytes payload
-{
- ULONG reserved; // dword 0 (don't use - must clear to 0)
- ULONG sof_eof; // dword 1 - 31:24 SOF:EOF, UAM,CLS, LCr, TFV, TimeStamp
- ULONG d_id; // dword 2 - 31:24 R_CTL, 23:0 D_ID
- ULONG s_id; // dword 3 - 31:24 CS_CTL, 23:0 S_ID
- ULONG f_ctl; // dword 4 - 31:24 Type, 23:0 F_CTL
- ULONG seq_cnt; // dword 5 - 31:24 SEQ_ID, 23:16 DF_CTL, 15:0 SEQ_CNT
- ULONG ox_rx_id; // dword 6 - 31:16 OX_ID, 15:0 RX_ID
- ULONG ro; // dword 7 - relative offset
-//---------
- __u32 pl[8]; // dwords 8-15 frame data payload
-} TachFCHDR_CMND;
-
-
-typedef struct // 32 bytes hdr + 120 bytes payload
-{
- ULONG reserved; // dword 0 (don't use - must clear to 0)
- ULONG sof_eof; // dword 1 - 31:24 SOF:EOF, UAM,CLS, LCr, TFV, TimeStamp
- ULONG d_id; // dword 2 - 31:24 R_CTL, 23:0 D_ID
- ULONG s_id; // dword 3 - 31:24 CS_CTL, 23:0 S_ID
- ULONG f_ctl; // dword 4 - 31:24 Type, 23:0 F_CTL
- ULONG seq_cnt; // dword 5 - 31:24 SEQ_ID, 23:16 DF_CTL, 15:0 SEQ_CNT
- ULONG ox_rx_id; // dword 6 - 31:16 OX_ID, 15:0 RX_ID
- ULONG ro; // dword 7 - relative offset
-//---------
- __u32 pl[30]; // largest necessary payload (for LOGIN cmnds)
-} TachFCHDR_GCMND;
-
-typedef struct // 32 bytes hdr + 64 bytes payload
-{
- ULONG reserved; // dword 0 (don't use)
- ULONG sof_eof;
- ULONG d_id; // dword 2 - 31:24 R_CTL, 23:0 D_ID
- ULONG s_id; // dword 3 - 31:24 CS_CTL, 23:0 S_ID
- ULONG f_ctl; // dword 4 - 31:24 Type, 23:0 F_CTL
- ULONG seq_cnt; // dword 5 - 31:24 SEQ_ID, 23:16 DF_CTL, 15:0 SEQ_CNT
- ULONG ox_rx_id; // dword 6 - 31:16 OX_ID, 15:0 RX_ID
- ULONG ro; // dword 7 - relative offset
-//---------
- __u32 pl[18]; // payload for FCP-RSP (response buffer) RA-4x00 is 72bytes
-} TachFCHDR_RSP;
-
-
-
-
-
-
-// Inbound Message Queue structures...
-typedef struct // each entry 8 words (32 bytes)
-{
- ULONG type; // IMQ completion message types
- ULONG word[7]; // remainder of structure
- // interpreted by IMQ type
-} TachyonIMQE;
-
-
-// Queues for TachLite not in original Tachyon
-// ERQ - Exchange Request Queue (for outbound commands)
-// SFQ - Single Frame Queue (for incoming frames)
-
- // Define Tachyon Outbound Command Que
- // (Since many Tachyon registers are Read
- // only, maintain copies for debugging)
- // most Tach ques need power-of-2 sizes,
- // where registers are loaded with po2 -1
-#define TACH_SEST_LEN 512 // TachLite SEST
-
-#define ELS_EXCHANGES 64 // e.g. PLOGI, RSCN, ...
-// define the total number of outstanding (simultaneous) exchanges
-#define TACH_MAX_XID (TACH_SEST_LEN + ELS_EXCHANGES) // ELS exchanges
-
-#define ERQ_LEN 128 // power of 2, max 4096
-
-// Inbound Message Queue structures...
-#define IMQ_LEN 512 // minimum 4 entries [(power of 2) - 1]
-typedef struct // 8 words - 32 bytes
-{
- TachyonIMQE QEntry[IMQ_LEN];
- ULONG producerIndex; // IMQ Producer Index register
- // @32 byte align
- ULONG consumerIndex; // Consumer Index register (in Tachyon)
- ULONG length; // Length register
- ULONG base;
-} TachyonIMQ; // @ 32 * IMQ_LEN align
-
-
-
-typedef struct // inbound completion message
-{
- ULONG Type;
- ULONG Index;
- ULONG TransferLength;
-} TachyonInbCM;
-
-
-
-// arbitrary numeric tags for TL structures
-#define TL_FCHS 1 // TachLite Fibre Channel Header Structure
-#define TL_IWE 2 // initiator write entry (for SEST)
-#define TL_TWE 3 // target write entry (for SEST)
-#define TL_IRE 4 // initiator read entry (for SEST)
-#define TL_TRE 5 // target read entry (for SEST)
-#define TL_IRB 6 // I/O request block
-
- // for INCOMING frames
-#define SFQ_LEN 32 // minimum 32 entries, max 4096
-
-typedef struct // Single Frame Que
-{
- TachFCHDR_CMND QEntry[SFQ_LEN]; // must be 64 bytes!!
- ULONG producerIndex; // IMQ Producer Index register
- // @32 byte align
- ULONG consumerIndex; // Consumer Index register (in Tachyon)
- ULONG length; // Length register
- ULONG base;
-} TachLiteSFQ;
-
-
-typedef struct // I/O Request Block flags
-{
- UCHAR BRD : 1;
- UCHAR : 1; // reserved
- UCHAR SFA : 1;
- UCHAR DNC : 1;
- UCHAR DIN : 1;
- UCHAR DCM : 1;
- UCHAR CTS : 1;
- UCHAR SBV : 1; // IRB entry valid - IRB'B' only
-} IRBflags;
-
-typedef struct // I/O Request Block
-{ // Request 'A'
- ULONG Req_A_SFS_Len; // total frame len (hdr + payload), min 32
- ULONG Req_A_SFS_Addr; // 32-bit pointer to FCHS struct (to be sent)
- ULONG Req_A_SFS_D_ID; // 24-bit FC destination (i.e. 8 bit al_pa)
- ULONG Req_A_Trans_ID; // X_ID (OX_ID or RX_ID) and/or Index in SEST
- // Request 'B'
- ULONG Req_B_SFS_Len; // total frame len (hdr + payload), min 32
- ULONG Req_B_SFS_Addr; // 32-bit pointer to FCHS struct (to be sent)
- ULONG Req_B_SFS_D_ID; // 24-bit FC destination (i.e. 8 bit al_pa)
- ULONG Req_B_Trans_ID; // X_ID (OX_ID or RX_ID) and/or Index in SEST
-} TachLiteIRB;
-
-
-typedef struct // TachLite placeholder for IRBs
-{ // aligned @sizeof(ERQ) for TachLite
- // MAX commands is sum of SEST len and ERQ
- // we know that each SEST entry requires an
- // IRB (ERQ) entry; in addition, we provide
- // ERQ_LEN
- TachLiteIRB QEntry[ERQ_LEN]; // Base register; entries 32 bytes ea.
- ULONG consumerIndex; // Consumer Index register
- ULONG producerIndex; // ERQ Producer Index register
- ULONG length; // Length register
- ULONG base; // copy of base ptr for debug
- // struct is sized for largest expected cmnd (LOGIN)
-} TachLiteERQ;
-
-// for now, just 32 bit DMA, eventually 40something, with code changes
-#define CPQFCTS_DMA_MASK ((unsigned long) (0x00000000FFFFFFFF))
-
-#define TL_MAX_SG_ELEM_LEN 0x7ffff // Max buffer length a single S/G entry
- // may represent (a hardware limitation). The
- // only reason to ever change this is if you
- // want to exercise very-hard-to-reach code in
- // cpqfcTSworker.c:build_SEST_sglist().
-
-#define TL_DANGER_SGPAGES 7 // arbitrary high water mark for # of S/G pages
- // we must exceed to elicit a warning indicative
- // of EXTREMELY large data transfers or
- // EXTREME memory fragmentation.
- // (means we just used up 2048 S/G elements,
- // Never seen this is real life, only in
- // testing with tricked up driver.)
-
-#define TL_EXT_SG_PAGE_COUNT 256 // Number of Extended Scatter/Gather a/l PAIRS
- // Tachyon register (IOBaseU 0x68)
- // power-of-2 value ONLY! 4 min, 256 max
-
- // byte len is #Pairs * 2 ULONG/Pair * 4 bytes/ULONG
-#define TL_EXT_SG_PAGE_BYTELEN (TL_EXT_SG_PAGE_COUNT *2 *4)
-
-
-
-// SEST entry types: IWE, IRE, TWE, TRE
-typedef struct
-{
- ULONG Hdr_Len;
- ULONG Hdr_Addr;
- ULONG RSP_Len;
- ULONG RSP_Addr;
- ULONG Buff_Off;
-#define USES_EXTENDED_SGLIST(this_sest, x_ID) \
- (!((this_sest)->u[ x_ID ].IWE.Buff_Off & 0x80000000))
- ULONG Link;
- ULONG RX_ID;
- ULONG Data_Len;
- ULONG Exp_RO;
- ULONG Exp_Byte_Cnt;
- // --- extended/local Gather Len/Address pairs
- ULONG GLen1;
- ULONG GAddr1;
- ULONG GLen2;
- ULONG GAddr2;
- ULONG GLen3;
- ULONG GAddr3;
-} TachLiteIWE;
-
-
-typedef struct
-{
- ULONG Seq_Accum;
- ULONG reserved; // must clear to 0
- ULONG RSP_Len;
- ULONG RSP_Addr;
- ULONG Buff_Off;
- ULONG Buff_Index; // ULONG 5
- ULONG Exp_RO;
- ULONG Byte_Count;
- ULONG reserved_; // ULONG 8
- ULONG Exp_Byte_Cnt;
- // --- extended/local Scatter Len/Address pairs
- ULONG SLen1;
- ULONG SAddr1;
- ULONG SLen2;
- ULONG SAddr2;
- ULONG SLen3;
- ULONG SAddr3;
-} TachLiteIRE;
-
-
-typedef struct // Target Write Entry
-{
- ULONG Seq_Accum; // dword 0
- ULONG reserved; // dword 1 must clear to 0
- ULONG Remote_Node_ID;
- ULONG reserved1; // dword 3 must clear to 0
- ULONG Buff_Off;
- ULONG Buff_Index; // ULONG 5
- ULONG Exp_RO;
- ULONG Byte_Count;
- ULONG reserved_; // ULONG 8
- ULONG Exp_Byte_Cnt;
- // --- extended/local Scatter Len/Address pairs
- ULONG SLen1;
- ULONG SAddr1;
- ULONG SLen2;
- ULONG SAddr2;
- ULONG SLen3;
- ULONG SAddr3;
-} TachLiteTWE;
-
-typedef struct
-{
- ULONG Hdr_Len;
- ULONG Hdr_Addr;
- ULONG RSP_Len; // DWord 2
- ULONG RSP_Addr;
- ULONG Buff_Off;
- ULONG Buff_Index; // DWord 5
- ULONG reserved;
- ULONG Data_Len;
- ULONG reserved_;
- ULONG reserved__;
- // --- extended/local Gather Len/Address pairs
- ULONG GLen1; // DWord A
- ULONG GAddr1;
- ULONG GLen2;
- ULONG GAddr2;
- ULONG GLen3;
- ULONG GAddr3;
-} TachLiteTRE;
-
-typedef struct ext_sg_page_ptr_t *PSGPAGES;
-typedef struct ext_sg_page_ptr_t
-{
- unsigned char page[TL_EXT_SG_PAGE_BYTELEN * 2]; // 2x for alignment
- dma_addr_t busaddr; // need the bus addresses and
- unsigned int maplen; // lengths for later pci unmapping.
- PSGPAGES next;
-} SGPAGES; // linked list of S/G pairs, by Exchange
-
-typedef struct // SCSI Exchange State Table
-{
- union // Entry can be IWE, IRE, TWE, TRE
- { // 64 bytes per entry
- TachLiteIWE IWE;
- TachLiteIRE IRE;
- TachLiteTWE TWE;
- TachLiteTRE TRE;
- } u[TACH_SEST_LEN];
-
- TachFCHDR DataHDR[TACH_SEST_LEN]; // for SEST FCP_DATA frame hdr (no pl)
- TachFCHDR_RSP RspHDR[TACH_SEST_LEN]; // space for SEST FCP_RSP frame
- PSGPAGES sgPages[TACH_SEST_LEN]; // head of linked list of Pool-allocations
- ULONG length; // Length register
- ULONG base; // copy of base ptr for debug
-} TachSEST;
-
-
-
-typedef struct // each register has it's own address
- // and value (used for write-only regs)
-{
- void* address;
- volatile ULONG value;
-} FCREGISTER;
-
-typedef struct // Host copy - TachLite Registers
-{
- ULONG IOBaseL, IOBaseU; // I/O port lower and upper TL register addresses
- ULONG MemBase; // memory mapped register addresses
- void* ReMapMemBase; // O/S VM reference for MemBase
- ULONG wwn_hi; // WWN is set once at startup
- ULONG wwn_lo;
- ULONG my_al_pa; // al_pa received after LIP()
- ULONG ROMCTR; // flags for on-board RAM/ROM
- ULONG RAMBase; // on-board RAM (i.e. some Tachlites)
- ULONG SROMBase; // on-board EEPROM (some Tachlites)
- ULONG PCIMCTR; // PCI Master Control Reg (has bus width)
-
- FCREGISTER INTEN; // copy of interrupt enable mask
- FCREGISTER INTPEND; // interrupt pending
- FCREGISTER INTSTAT; // interrupt status
- FCREGISTER SFQconsumerIndex;
- FCREGISTER ERQproducerIndex;
- FCREGISTER TYconfig; // TachYon (chip level)
- FCREGISTER TYcontrol;
- FCREGISTER TYstatus;
- FCREGISTER FMconfig; // Frame Manager (FC loop level)
- FCREGISTER FMcontrol;
- FCREGISTER FMstatus;
- FCREGISTER FMLinkStatus1;
- FCREGISTER FMLinkStatus2;
- FCREGISTER FMBB_CreditZero;
- FCREGISTER status;
- FCREGISTER ed_tov; // error detect time-out value
- FCREGISTER rcv_al_pa; // received arb. loop physical address
- FCREGISTER primitive; // e.g. LIP(), OPN(), ...
-} TL_REGISTERS;
-
-
-
-typedef struct
-{
- ULONG ok;
- ULONG invalidArgs;
- ULONG linkDown;
- ULONG linkUp;
- ULONG outQueFull;
- ULONG SESTFull;
- ULONG hpe; // host programming err (from Tach)
- ULONG FC4aborted; // aborts from Application or upper driver layer
- ULONG FC2aborted; // aborts from our driver's timeouts
- ULONG timeouts; // our driver timeout (on individual exchanges)
- ULONG logouts; // explicit - sent LOGO; implicit - device removed
- ULONG retries;
- ULONG linkFailTX;
- ULONG linkFailRX;
- ULONG CntErrors; // byte count expected != count received (typ. SEST)
- ULONG e_stores; // elastic store errs
- ULONG resets; // hard or soft controller resets
- ULONG FMinits; // TACH Frame Manager Init (e.g. LIPs)
- ULONG lnkQueFull; // too many LOGIN, loop commands
- ULONG ScsiQueFull; // too many FCP-SCSI inbound frames
- ULONG LossofSignal; // FM link status 1 regs
- ULONG BadRXChar; // FM link status 1 regs
- ULONG LossofSync; // FM link status 1 regs
- ULONG Rx_EOFa; // FM link status 2 regs (received EOFa)
- ULONG Dis_Frm; // FM link status 2 regs (discarded frames)
- ULONG Bad_CRC; // FM link status 2 regs
- ULONG BB0_Timer; // FM BB_Credit Zero Timer Reg
- ULONG loopBreaks; // infinite loop exits
- ULONG lastBB0timer; // static accum. buffer needed by Tachlite
-} FCSTATS;
-
-
-typedef struct // Config Options
-{ // LS Bit first
- USHORT : 1; // bit0:
- USHORT flogi : 1; // bit1: We sent FLOGI - wait for Fabric logins
- USHORT fabric: 1; // bit2: Tachyon detected Fabric (FM stat LG)
- USHORT LILPin: 1; // bit3: We can use an FC-AL LILP frame
- USHORT target: 1; // bit4: this Port has SCSI target capability
- USHORT initiator: 1; // bit5: this Port has SCSI initiator capability
- USHORT extLoopback: 1; // bit6: loopback at GBIC
- USHORT intLoopback: 1; // bit7: loopback in HP silicon
- USHORT : 1; // bit8:
- USHORT : 1; // bit9:
- USHORT : 1; // bit10:
- USHORT : 1; // bit11:
- USHORT : 1; // bit12:
- USHORT : 1; // bit13:
- USHORT : 1; // bit14:
- USHORT : 1; // bit15:
-} FC_OPTIONS;
-
-
-
-typedef struct dyn_mem_pair
-{
- void *BaseAllocated; // address as allocated from O/S;
- unsigned long AlignedAddress; // aligned address (used by Tachyon DMA)
- dma_addr_t dma_handle;
- size_t size;
-} ALIGNED_MEM;
-
-
-
-
-// these structs contain only CRUCIAL (stuff we actually use) parameters
-// from FC-PH(n) logins. (Don't save entire LOGIN payload to save mem.)
-
-// Implicit logout happens when the loop goes down - we require PDISC
-// to restore. Explicit logout is when WE decide never to talk to someone,
-// or when a target refuses to talk to us, i.e. sends us a LOGO frame or
-// LS_RJT reject in response to our PLOGI request.
-
-#define IMPLICIT_LOGOUT 1
-#define EXPLICIT_LOGOUT 2
-
-typedef struct
-{
- UCHAR channel; // SCSI "bus"
- UCHAR target;
- UCHAR InqDeviceType; // byte 0 from SCSI Inquiry response
- UCHAR VolumeSetAddressing; // FCP-SCSI LUN coding (40h for VSA)
- UCHAR LunMasking; // True if selective presentation supported
- UCHAR lun[CPQFCTS_MAX_LUN];
-} SCSI_NEXUS;
-
-
-typedef struct
-{
- union
- {
- UCHAR ucWWN[8]; // a FC 64-bit World Wide Name/ PortID of target
- // addressing of single target on single loop...
- u64 liWWN;
- } u;
-
- ULONG port_id; // a FC 24-bit address of port (lower 8 bits = al_pa)
-
-#define REPORT_LUNS_PL 256
- UCHAR ReportLunsPayload[REPORT_LUNS_PL];
-
- SCSI_NEXUS ScsiNexus; // LUNs per FC device
-
- ULONG LOGO_counter; // might try several times before logging out for good
- ULONG LOGO_timer; // after LIP, ports expecting PDISC must time-out and
- // LOGOut if successful PDISC not completed in 2 secs
-
- ULONG concurrent_seq; // must be 1 or greater
- ULONG rx_data_size; // e.g. 128, 256, 1024, 2048 per FC-PH spec
- ULONG BB_credit;
- ULONG EE_credit;
-
- ULONG fcp_info; // from PRLI (i.e. INITIATOR/ TARGET flags)
- // flags for login process
- BOOLEAN Originator; // Login sequence Originated (if false, we
- // responded to another port's login sequence)
- BOOLEAN plogi; // PLOGI frame ACCepted (originated or responded)
- BOOLEAN pdisc; // PDISC frame was ORIGINATED (self-login logic)
- BOOLEAN prli; // PRLI frame ACCepted (originated or responded)
- BOOLEAN flogi; // FLOGI frame ACCepted (originated or responded)
- BOOLEAN logo; // port permanently logged out (invalid login param)
- BOOLEAN flogiReq; // Fabric login required (set in LIP process)
- UCHAR highest_ver;
- UCHAR lowest_ver;
-
-
- // when the "target" (actually FC Port) is waiting for login
- // (e.g. after Link reset), set the device_blocked bit;
- // after Port completes login, un-block target.
- UCHAR device_blocked; // see Scsi_Device struct
-
- // define singly-linked list of logged-in ports
- // once a port_id is identified, it is remembered,
- // even if the port is removed indefinitely
- PVOID pNextPort; // actually, type PFC_LOGGEDIN_PORT; void for Compiler
-
-} FC_LOGGEDIN_PORT, *PFC_LOGGEDIN_PORT;
-
-
-
-// This serves as the ESB (Exchange Status Block),
-// and has timeout counter; used for ABORTs
-typedef struct
-{ // FC-1 X_IDs
- ULONG type; // ELS_PLOGI, SCSI_IWE, ... (0 if free)
- PFC_LOGGEDIN_PORT pLoggedInPort; // FC device on other end of Exchange
- Scsi_Cmnd *Cmnd; // Linux SCSI command packet includes S/G list
- ULONG timeOut; // units of ??, DEC by driver, Abort when 0
- ULONG reTries; // need one or more retries?
- ULONG status; // flags indicating errors (0 if none)
- TachLiteIRB IRB; // I/O Request Block, gets copied to ERQ
- TachFCHDR_GCMND fchs; // location of IRB's Req_A_SFS_Addr
-} FC_EXCHANGE, *PFC_EXCHANGE;
-
-// Unfortunately, Linux limits our kmalloc() allocations to 128k.
-// Because of this and the fact that our ScsiRegister allocation
-// is also constrained, we move this large structure out for
-// allocation after Scsi Register.
-// (In other words, this cumbersome indirection is necessary
-// because of kernel memory allocation constraints!)
-
-typedef struct // we will allocate this dynamically
-{
- FC_EXCHANGE fcExchange[ TACH_MAX_XID ];
-} FC_EXCHANGES;
-
-
-
-
-
-
-
-
-
-
-
-typedef struct
-{
- char Name[64]; // name of controller ("HP Tachlite TL Rev2.0, 33MHz, 64bit bus")
- //PVOID pAdapterDevExt; // back pointer to device object/extension
- ULONG ChipType; // local numeric key for Tachyon Type / Rev.
- ULONG status; // our Driver - logical status
-
- TL_REGISTERS Registers; // reg addresses & host memory copies
- // FC-4 mapping of 'transaction' to X_IDs
- UCHAR LILPmap[32*4]; // Loop Position Map of ALPAs (late FC-AL only)
- FC_OPTIONS Options; // e.g. Target, Initiator, loopback...
- UCHAR highest_FCPH_ver; // FC-PH version limits
- UCHAR lowest_FCPH_ver; // FC-PH version limits
-
- FC_EXCHANGES *Exchanges;
- ULONG fcLsExchangeLRU; // Least Recently Used counter (Link Service)
- ULONG fcSestExchangeLRU; // Least Recently Used counter (FCP-SCSI)
- FC_LOGGEDIN_PORT fcPorts; // linked list of every FC port ever seen
- FCSTATS fcStats; // FC comm err counters
-
- // Host memory QUEUE pointers
- TachLiteERQ *ERQ; // Exchange Request Que
- TachyonIMQ *IMQ; // Inbound Message Que
- TachLiteSFQ *SFQ; // Single Frame Queue
- TachSEST *SEST; // SCSI Exchange State Table
-
- dma_addr_t exch_dma_handle;
-
- // these function pointers are for "generic" functions, which are
- // replaced with Host Bus Adapter types at
- // runtime.
- int (*CreateTachyonQues)( void* , int);
- int (*DestroyTachyonQues)( void* , int);
- int (*LaserControl)(void*, int ); // e.g. On/Off
- int (*ResetTachyon)(void*, int );
- void (*FreezeTachyon)(void*, int );
- void (*UnFreezeTachyon)(void*, int );
- int (*InitializeTachyon)(void*, int, int );
- int (*InitializeFrameManager)(void*, int );
- int (*ProcessIMQEntry)(void*);
- int (*ReadWriteWWN)(void*, int ReadWrite);
- int (*ReadWriteNVRAM)(void*, void*, int ReadWrite);
-
-} TACHYON, *PTACHYON;
-
-
-void cpqfcTSClearLinkStatusCounters(TACHYON * fcChip);
-
-int CpqTsCreateTachLiteQues( void* pHBA, int opcode);
-int CpqTsDestroyTachLiteQues( void* , int);
-int CpqTsInitializeTachLite( void *pHBA, int opcode1, int opcode2);
-
-int CpqTsProcessIMQEntry(void* pHBA);
-int CpqTsResetTachLite(void *pHBA, int type);
-void CpqTsFreezeTachlite(void *pHBA, int type);
-void CpqTsUnFreezeTachlite(void *pHBA, int type);
-int CpqTsInitializeFrameManager(void *pHBA, int);
-int CpqTsLaserControl( void* addrBase, int opcode );
-int CpqTsReadWriteWWN(void*, int ReadWrite);
-int CpqTsReadWriteNVRAM(void*, void* data, int ReadWrite);
-
-void cpqfcTS_WorkTask( struct Scsi_Host *HostAdapter);
-void cpqfcTSWorkerThread( void *host);
-
-int cpqfcTS_GetNVRAM_data( UCHAR *wwnbuf, UCHAR *buf );
-ULONG cpqfcTS_ReadNVRAM( void* GPIOin, void* GPIOout , USHORT count,
- UCHAR *buf );
-
-BOOLEAN tl_write_i2c_nvram( void* GPIOin, void* GPIOout,
- USHORT startOffset, // e.g. 0x2f for WWN start
- USHORT count,
- UCHAR *buf );
-
-
-// define misc functions
-int cpqfcTSGetLPSM( PTACHYON fcChip, char cErrorString[]);
-int cpqfcTSDecodeGBICtype( PTACHYON fcChip, char cErrorString[]);
-void* fcMemManager( struct pci_dev *pdev,
- ALIGNED_MEM *dyn_mem_pair, ULONG n_alloc, ULONG ab,
- ULONG ulAlignedAddress, dma_addr_t *dma_handle);
-
-void BigEndianSwap( UCHAR *source, UCHAR *dest, USHORT cnt);
-
-//ULONG virt_to_phys( PVOID virtaddr );
-
-
-// Linux interrupt handler
-irqreturn_t cpqfcTS_intr_handler( int irq,void *dev_id,struct pt_regs *regs);
-void cpqfcTSheartbeat( unsigned long ptr );
-
-
-
-// The biggest Q element we deal with is Aborts - we
-// need 4 bytes for x_ID, and a Scsi_Cmnd (~284 bytes)
-//#define LINKQ_ITEM_SIZE ((4+sizeof(Scsi_Cmnd)+3)/4)
-#define LINKQ_ITEM_SIZE (3*16)
-typedef struct
-{
- ULONG Type; // e.g. LINKUP, SFQENTRY, PDISC, BLS_ABTS, ...
- ULONG ulBuff[ LINKQ_ITEM_SIZE ];
-} LINKQ_ITEM;
-
-#define FC_LINKQ_DEPTH TACH_MAX_XID
-typedef struct
-{
- ULONG producer;
- ULONG consumer; // when producer equals consumer, Q empty
-
- LINKQ_ITEM Qitem[ FC_LINKQ_DEPTH ];
-
-} FC_LINK_QUE, *PFC_LINK_QUE;
-
-
- // DPC routines post to here on Inbound SCSI frames
- // User thread processes
-#define FC_SCSIQ_DEPTH 32
-
-typedef struct
-{
- int Type; // e.g. SCSI
- ULONG ulBuff[ 3*16 ];
-} SCSIQ_ITEM;
-
-typedef struct
-{
- ULONG producer;
- ULONG consumer; // when producer equals consumer, Q empty
-
- SCSIQ_ITEM Qitem[ FC_SCSIQ_DEPTH ];
-
-} FC_SCSI_QUE, *PFC_SCSI_QUE;
-
-typedef struct {
- /* This is tacked on to a Scsi_Request in upper_private_data
- for pasthrough ioctls, as a place to hold data that can't
- be stashed anywhere else in the Scsi_Request. We differentiate
- this from _real_ upper_private_data by checking if the virt addr
- is within our special pool. */
- ushort bus;
- ushort pdrive;
-} cpqfc_passthru_private_t;
-
-#define CPQFC_MAX_PASSTHRU_CMDS 100
-
-#define DYNAMIC_ALLOCATIONS 4 // Tachyon aligned allocations: ERQ,IMQ,SFQ,SEST
-
-// Linux space allocated per HBA (chip state, etc.)
-typedef struct
-{
- struct Scsi_Host *HostAdapter; // back pointer to Linux Scsi struct
-
- TACHYON fcChip; // All Tachyon registers, Queues, functions
- ALIGNED_MEM dynamic_mem[DYNAMIC_ALLOCATIONS];
-
- struct pci_dev *PciDev;
- dma_addr_t fcLQ_dma_handle;
-
- Scsi_Cmnd *LinkDnCmnd[CPQFCTS_REQ_QUEUE_LEN]; // collects Cmnds during LDn
- // (for Acceptable targets)
- Scsi_Cmnd *BoardLockCmnd[CPQFCTS_REQ_QUEUE_LEN]; // SEST was full
-
- Scsi_Cmnd *BadTargetCmnd[CPQFCTS_MAX_TARGET_ID]; // missing targets
-
- u_char HBAnum; // 0-based host number
-
-
- struct timer_list cpqfcTStimer; // FC utility timer for implicit
- // logouts, FC protocol timeouts, etc.
- int fcStatsTime; // Statistics delta reporting time
-
- struct task_struct *worker_thread; // our kernel thread
- int PortDiscDone; // set by SendLogins(), cleared by LDn
-
- struct semaphore *TachFrozen;
- struct semaphore *TYOBcomplete; // handshake for Tach outbound frames
- struct semaphore *fcQueReady; // FibreChannel work for our kernel thread
- struct semaphore *notify_wt; // synchronizes kernel thread kill
- struct semaphore *BoardLock;
-
- PFC_LINK_QUE fcLQ; // the WorkerThread operates on this
-
- spinlock_t hba_spinlock; // held/released by WorkerThread
- cpqfc_passthru_private_t *private_data_pool;
- unsigned long *private_data_bits;
-
-} CPQFCHBA;
-
-#define CPQ_SPINLOCK_HBA( x ) spin_lock(&x->hba_spinlock);
-#define CPQ_SPINUNLOCK_HBA(x) spin_unlock(&x->hba_spinlock);
-
-
-
-void cpqfcTSImplicitLogout( CPQFCHBA* cpqfcHBAdata,
- PFC_LOGGEDIN_PORT pFcPort);
-
-
-void cpqfcTSTerminateExchange( CPQFCHBA*, SCSI_NEXUS *target, int );
-
-PFC_LOGGEDIN_PORT fcPortLoggedIn(
- CPQFCHBA *cpqfcHBAdata,
- TachFCHDR_GCMND* fchs,
- BOOLEAN,
- BOOLEAN);
-void fcProcessLoggedIn(
- CPQFCHBA *cpqfcHBAdata, TachFCHDR_GCMND* fchs);
-
-
-ULONG cpqfcTSBuildExchange(
- CPQFCHBA *cpqfcHBAdata,
- ULONG type, // e.g. PLOGI
- TachFCHDR_GCMND* InFCHS, // incoming FCHS
- void *Data, // the CDB, scatter/gather, etc.
- LONG *ExchangeID ); // allocated exchange ID
-
-ULONG cpqfcTSStartExchange(
- CPQFCHBA *cpqfcHBAdata,
- LONG ExchangeID );
-
-void cpqfcTSCompleteExchange(
- struct pci_dev *pcidev,
- PTACHYON fcChip,
- ULONG exchange_ID);
-
-
-PFC_LOGGEDIN_PORT fcFindLoggedInPort(
- PTACHYON fcChip,
- Scsi_Cmnd *Cmnd, // (We want the channel/target/lun Nexus from Cmnd)
- ULONG port_id, // search linked list for al_pa, or
- UCHAR wwn[8], // search linked list for WWN, or...
- PFC_LOGGEDIN_PORT *pLastLoggedInPort
-);
-
-void cpqfcTSPutLinkQue(
- CPQFCHBA *cpqfcHBAdata,
- int Type,
- void *QueContent);
-
-void fcPutScsiQue(
- CPQFCHBA *cpqfcHBAdata,
- int Type,
- void *QueContent);
-
-void fcLinkQReset(
- CPQFCHBA *);
-void fcScsiQReset(
- CPQFCHBA *);
-void fcSestReset(
- CPQFCHBA *);
-
-void cpqfc_pci_unmap(struct pci_dev *pcidev,
- Scsi_Cmnd *cmd,
- PTACHYON fcChip,
- ULONG x_ID);
-
-extern const UCHAR valid_al_pa[];
-extern const int number_of_al_pa;
-
-#define FCP_RESID_UNDER 0x80000
-#define FCP_RESID_OVER 0x40000
-#define FCP_SNS_LEN_VALID 0x20000
-#define FCP_RSP_LEN_VALID 0x10000
-
-// RSP_CODE definitions (dpANS Fibre Channel Protocol for SCSI, pg 34)
-#define FCP_DATA_LEN_NOT_BURST_LEN 0x1000000
-#define FCP_CMND_FIELD_INVALID 0x2000000
-#define FCP_DATA_RO_NOT_XRDY_RO 0x3000000
-#define FCP_TASKFUNCTION_NS 0x4000000
-#define FCP_TASKFUNCTION_FAIL 0x5000000
-
-// FCP-SCSI response status struct
-typedef struct // see "TachFCHDR_RSP" definition - 64 bytes
-{
- __u32 reserved;
- __u32 reserved1;
- __u32 fcp_status; // field validity and SCSI status
- __u32 fcp_resid;
- __u32 fcp_sns_len; // length of FCP_SNS_INFO field
- __u32 fcp_rsp_len; // length of FCP_RSP_INFO field (expect 8)
- __u32 fcp_rsp_info; // 4 bytes of FCP protocol response information
- __u32 fcp_rsp_info2; // (4 more bytes, since most implementations use 8)
- __u8 fcp_sns_info[36]; // bytes for SCSI sense (ASC, ASCQ)
-
-} FCP_STATUS_RESPONSE, *PFCP_STATUS_RESPONSE;
-
-
-// Fabric State Change Registration
-typedef struct scrpl
-{
- __u32 command;
- __u32 function;
-} SCR_PL;
-
-// Fabric Name Service Request
-typedef struct nsrpl
-{
- __u32 CT_Rev; // (& IN_ID) WORD 0
- __u32 FCS_Type; // WORD 1
- __u32 Command_code; // WORD 2
- __u32 reason_code; // WORD 3
- __u32 FCP; // WORD 4 (lower byte)
-
-} NSR_PL;
-
-
-
-// "FC.H"
-#define MAX_RX_SIZE 0x800 // Max Receive Buffer Size is 2048
-#define MIN_RX_SIZE 0x100 // Min Size is 256, per FC-PLDA Spec
-#define MAX_TARGET_RXIDS SEST_DEPTH
-#define TARGET_RX_SIZE SEST_BUFFER_LENGTH
-
-#define CLASS_1 0x01
-#define CLASS_2 0x02
-#define CLASS_3 0x03
-
-#define FC_PH42 0x08
-#define FC_PH43 0x09
-#define FC_PH3 0x20
-
-#define RR_TOV 2 // Minimum Time for target to wait for
- // PDISC after a LIP.
-#define E_D_TOV 2 // Minimum Time to wait for Sequence
- // Completion.
-#define R_A_TOV 0 // Minimum Time for Target to wait
- // before reclaiming resources.
-//
-// R_CTL Field
-//
-// Routing Bits (31-28)
-//
-#define FC4_DEVICE_DATA 0x00000000
-#define EXT_LINK_DATA 0x20000000
-#define FC4_LINK_DATA 0x30000000
-#define VIDEO_DATA 0x40000000
-#define BASIC_LINK_DATA 0x80000000
-#define LINK_CONTROL 0xC0000000
-#define ROUTING_MASK 0xF0000000
-
-//
-// Information Bits (27-24)
-//
-#define UNCAT_INFORMATION 0x00000000
-#define SOLICITED_DATA 0x01000000
-#define UNSOLICITED_CONTROL 0x02000000
-#define SOLICITED_CONTROL 0x03000000
-#define UNSOLICITED_DATA 0x04000000
-#define DATA_DESCRIPTOR 0x05000000
-#define UNSOLICITED_COMMAND 0x06000000
-#define COMMAND_STATUS 0x07000000
-#define INFO_MASK 0x0F000000
-//
-// (Link Control Codes)
-//
-#define ACK_1 0x00000000
-#define ACK_0_OR_N 0x01000000
-#define P_RJT 0x02000000
-#define F_RJT 0x03000000
-#define P_BSY 0x04000000
-#define FABRIC_BUSY_TO_DF 0x05000000 // Fabric Busy to Data Frame
-#define FABRIC_BUSY_TO_LC 0x06000000 // Fabric Busy to Link Ctl Frame
-#define LINK_CREDIT_RESET 0x07000000
-//
-// (Link Service Command Codes)
-//
-//#define LS_RJT 0x01000000 // LS Reject
-
-#define LS_ACC 0x02000000 // LS Accept
-#define LS_PLOGI 0x03000000 // N_PORT Login
-#define LS_FLOGI 0x04000000 // F_PORT Login
-#define LS_LOGO 0x05000000 // Logout
-#define LS_ABTX 0x06000000 // Abort Exchange
-#define LS_RCS 0x07000000 // Read Connection Status
-#define LS_RES 0x08000000 // Read Exchange Status
-#define LS_RSS 0x09000000 // Read Sequence Status
-#define LS_RSI 0x0A000000 // Request Seq Initiative
-#define LS_ESTS 0x0B000000 // Establish Steaming
-#define LS_ESTC 0x0C000000 // Estimate Credit
-#define LS_ADVC 0x0D000000 // Advice Credit
-#define LS_RTV 0x0E000000 // Read Timeout Value
-#define LS_RLS 0x0F000000 // Read Link Status
-#define LS_ECHO 0x10000000 // Echo
-#define LS_TEST 0x11000000 // Test
-#define LS_RRQ 0x12000000 // Reinstate Rec. Qual.
-#define LS_PRLI 0x20000000 // Process Login
-#define LS_PRLO 0x21000000 // Process Logout
-#define LS_TPRLO 0x24000000 // 3rd Party Process Logout
-#define LS_PDISC 0x50000000 // Process Discovery
-#define LS_FDISC 0x51000000 // Fabric Discovery
-#define LS_ADISC 0x52000000 // Discover Address
-#define LS_RNC 0x53000000 // Report Node Capability
-#define LS_SCR 0x62000000 // State Change Registration
-#define LS_MASK 0xFF000000
-
-//
-// TYPE Bit Masks
-//
-#define BASIC_LINK_SERVICE 0x00000000
-#define EXT_LINK_SERVICE 0x01000000
-
-#define LLC 0x04000000
-#define LLC_SNAP 0x05000000
-#define SCSI_FCP 0x08000000
-#define SCSI_GPP 0x09000000
-#define IPI3_MASTER 0x11000000
-#define IPI3_SLAVE 0x12000000
-#define IPI3_PEER 0x13000000
-#define CP_IPI3_MASTER 0x15000000
-#define CP_IPI3_SLAVE 0x16000000
-#define CP_IPI3_PEER 0x17000000
-#define SBCCS_CHANNEL 0x19000000
-#define SBCCS_CONTROL 0x1A000000
-#define FIBRE_SERVICES 0x20000000
-#define FC_FG 0x21000000
-#define FC_XS 0x22000000
-#define FC_AL 0x23000000
-#define SNMP 0x24000000
-#define HIPPI_FP 0x40000000
-#define TYPE_MASK 0xFF000000
-
-typedef struct {
- UCHAR seq_id_valid;
- UCHAR seq_id;
- USHORT reserved; // 2 bytes reserved
- ULONG ox_rx_id;
- USHORT low_seq_cnt;
- USHORT high_seq_cnt;
-} BA_ACC_PAYLOAD;
-
-typedef struct {
- UCHAR reserved;
- UCHAR reason_code;
- UCHAR reason_explain;
- UCHAR vendor_unique;
-} BA_RJT_PAYLOAD;
-
-
-typedef struct {
- ULONG command_code;
- ULONG sid;
- USHORT ox_id;
- USHORT rx_id;
-} RRQ_MESSAGE;
-
-typedef struct {
- ULONG command_code;
- UCHAR vendor;
- UCHAR explain;
- UCHAR reason;
- UCHAR reserved;
-} REJECT_MESSAGE;
-
-
-#define N_OR_F_PORT 0x1000
-#define RANDOM_RELATIVE_OFFSET 0x4000
-#define CONTINUOSLY_INCREASING 0x8000
-
-#define CLASS_VALID 0x8000
-#define INTERMIX_MODE 0x4000
-#define TRANSPARENT_STACKED 0x2000
-#define LOCKDOWN_STACKED 0x1000
-#define SEQ_DELIVERY 0x800
-
-#define XID_NOT_SUPPORTED 0x00
-#define XID_SUPPORTED 0x4000
-#define XID_REQUIRED 0xC000
-
-#define ASSOCIATOR_NOT_SUPPORTED 0x00
-#define ASSOCIATOR_SUPPORTED 0x1000
-#define ASSOCIATOR_REQUIRED 0x3000
-
-#define INIT_ACK0_SUPPORT 0x800
-#define INIT_ACKN_SUPPORT 0x400
-
-#define RECIP_ACK0_SUPPORT 0x8000
-#define RECIP_ACKN_SUPPORT 0x4000
-
-#define X_ID_INTERLOCK 0x2000
-
-#define ERROR_POLICY 0x1800 // Error Policy Supported
-#define ERROR_DISCARD 0x00 // Only Discard Supported
-#define ERROR_DISC_PROCESS 0x02 // Discard and process supported
-
-#define NODE_ID 0x01
-#define IEEE_EXT 0x20
-
-//
-// Categories Supported Per Sequence
-//
-#define CATEGORIES_PER_SEQUENCE 0x300
-#define ONE_CATEGORY_SEQUENCE 0x00 // 1 Category per Sequence
-#define TWO_CATEGORY_SEQUENCE 0x01 // 2 Categories per Sequence
-#define MANY_CATEGORY_SEQUENCE 0x03 // > 2 Categories/Sequence
-
-typedef struct {
-
- USHORT initiator_control;
- USHORT service_options;
-
- USHORT rx_data_size;
- USHORT recipient_control;
-
- USHORT ee_credit;
- USHORT concurrent_sequences;
-
- USHORT reserved;
- USHORT open_sequences;
-
-} CLASS_PARAMETERS;
-
-typedef struct {
- ULONG login_cmd;
- //
- // Common Service Parameters
- //
- struct {
-
- USHORT bb_credit;
- UCHAR lowest_ver;
- UCHAR highest_ver;
-
- USHORT bb_rx_size;
- USHORT common_features;
-
- USHORT rel_offset;
- USHORT concurrent_seq;
-
-
- ULONG e_d_tov;
- } cmn_services;
-
- //
- // Port Name
- //
- UCHAR port_name[8];
-
- //
- // Node/Fabric Name
- //
- UCHAR node_name[8];
-
- //
- // Class 1, 2 and 3 Service Parameters
- //
- CLASS_PARAMETERS class1;
- CLASS_PARAMETERS class2;
- CLASS_PARAMETERS class3;
-
- ULONG reserved[4];
-
- //
- // Vendor Version Level
- //
- UCHAR vendor_id[2];
- UCHAR vendor_version[6];
- ULONG buffer_size;
- USHORT rxid_start;
- USHORT total_rxids;
-} LOGIN_PAYLOAD;
-
-
-typedef struct
-{
- ULONG cmd; // 4 bytes
- UCHAR n_port_identifier[3];
- UCHAR reserved;
- UCHAR port_name[8];
-} LOGOUT_PAYLOAD;
-
-
-//
-// PRLI Request Service Parameter Defines
-//
-#define PRLI_ACC 0x01
-#define PRLI_REQ 0x02
-#define ORIG_PROCESS_ASSOC_VALID 0x8000
-#define RESP_PROCESS_ASSOC_VALID 0x4000
-#define ESTABLISH_PAIR 0x2000
-#define DATA_OVERLAY_ALLOWED 0x40
-#define INITIATOR_FUNCTION 0x20
-#define TARGET_FUNCTION 0x10
-#define CMD_DATA_MIXED 0x08
-#define DATA_RESP_MIXED 0x04
-#define READ_XFER_RDY 0x02
-#define WRITE_XFER_RDY 0x01
-
-#define RESPONSE_CODE_MASK 0xF00
-#define REQUEST_EXECUTED 0x100
-#define NO_RESOURCES 0x200
-#define INIT_NOT_COMPLETE 0x300
-#define IMAGE_DOES_NOT_EXIST 0x400
-#define BAD_PREDEFINED_COND 0x500
-#define REQ_EXEC_COND 0x600
-#define NO_MULTI_PAGE 0x700
-
-typedef struct {
- USHORT payload_length;
- UCHAR page_length;
- UCHAR cmd;
-
-
- ULONG valid;
-
- ULONG orig_process_associator;
-
- ULONG resp_process_associator;
-
- ULONG fcp_info;
-} PRLI_REQUEST;
-
-typedef struct {
-
- USHORT payload_length;
- UCHAR page_length;
- UCHAR cmd;
-
- ULONG valid;
- ULONG orig_process_associator;
-
- ULONG resp_process_associator;
- ULONG reserved;
-} PRLO_REQUEST;
-
-typedef struct {
- ULONG cmd;
-
- ULONG hard_address;
-
- UCHAR port_name[8];
-
- UCHAR node_name[8];
-
- ULONG s_id;
-} ADISC_PAYLOAD;
-
-struct ext_sg_entry_t {
- __u32 len:18; /* buffer length, bits 0-17 */
- __u32 uba:13; /* upper bus address bits 18-31 */
- __u32 lba; /* lower bus address bits 0-31 */
-};
-
-
-// J. McCarty's LINK.H
-//
-// LS_RJT Reason Codes
-//
-
-#define INVALID_COMMAND_CODE 0x01
-#define LOGICAL_ERROR 0x03
-#define LOGICAL_BUSY 0x05
-#define PROTOCOL_ERROR 0x07
-#define UNABLE_TO_PERFORM 0x09
-#define COMMAND_NOT_SUPPORTED 0x0B
-#define LS_VENDOR_UNIQUE 0xFF
-
-//
-// LS_RJT Reason Codes Explanations
-//
-#define NO_REASON 0x00
-#define OPTIONS_ERROR 0x01
-#define INITIATOR_CTL_ERROR 0x03
-#define RECIPIENT_CTL_ERROR 0x05
-#define DATA_FIELD_SIZE_ERROR 0x07
-#define CONCURRENT_SEQ_ERROR 0x09
-#define CREDIT_ERROR 0x0B
-#define INVALID_PORT_NAME 0x0D
-#define INVALID_NODE_NAME 0x0E
-#define INVALID_CSP 0x0F // Invalid Service Parameters
-#define INVALID_ASSOC_HDR 0x11 // Invalid Association Header
-#define ASSOC_HDR_REQUIRED 0x13 // Association Header Required
-#define LS_INVALID_S_ID 0x15
-#define INVALID_OX_RX_ID 0x17 // Invalid OX_ID RX_ID Combination
-#define CMD_IN_PROCESS 0x19
-#define INVALID_IDENTIFIER 0x1F // Invalid N_PORT Identifier
-#define INVALID_SEQ_ID 0x21
-#define ABT_INVALID_XCHNG 0x23 // Attempt to Abort an invalid Exchange
-#define ABT_INACTIVE_XCHNG 0x25 // Attempt to Abort an inactive Exchange
-#define NEED_REC_QUAL 0x27 // Recovery Qualifier required
-#define NO_LOGIN_RESOURCES 0x29 // No resources to support login
-#define NO_DATA 0x2A // Unable to supply requested data
-#define REQUEST_NOT_SUPPORTED 0x2C // Request Not Supported
-
-//
-// Link Control Codes
-//
-
-//
-// P_BSY Action Codes
-//
-#define SEQUENCE_TERMINATED 0x01000000
-#define SEQUENCE_ACTIVE 0x02000000
-
-//
-// P_BSY Reason Codes
-//
-#define PHYS_NPORT_BUSY 0x010000
-#define NPORT_RESOURCE_BUSY 0x020000
-
-//
-// P_RJT, F_RJT Action Codes
-//
-
-#define RETRYABLE_ERROR 0x01000000
-#define NON_RETRYABLE_ERROR 0x02000000
-
-//
-// P_RJT, F_RJT Reason Codes
-//
-#define INVALID_D_ID 0x010000
-#define INVALID_S_ID 0x020000
-#define NPORT_NOT_AVAIL_TMP 0x030000
-#define NPORT_NOT_AVAIL_PERM 0x040000
-#define CLASS_NOT_SUPPORTED 0x050000
-#define USAGE_ERROR 0x060000
-#define TYPE_NOT_SUPPORTED 0x070000
-#define INVAL_LINK_CONTROL 0x080000
-#define INVAL_R_CTL 0x090000
-#define INVAL_F_CTL 0x0A0000
-#define INVAL_OX_ID 0x0B0000
-#define INVAL_RX_ID 0x0C0000
-#define INVAL_SEQ_ID 0x0D0000
-#define INVAL_DF_CTL 0x0E0000
-#define INVAL_SEQ_CNT 0x0F0000
-#define INVAL_PARAMS 0x100000
-#define EXCHANGE_ERROR 0x110000
-#define LS_PROTOCOL_ERROR 0x120000
-#define INCORRECT_LENGTH 0x130000
-#define UNEXPECTED_ACK 0x140000
-#define LOGIN_REQ 0x160000
-#define EXCESSIVE_SEQ 0x170000
-#define NO_EXCHANGE 0x180000
-#define SEC_HDR_NOT_SUPPORTED 0x190000
-#define NO_FABRIC 0x1A0000
-#define P_VENDOR_UNIQUE 0xFF0000
-
-//
-// BA_RJT Reason Codes
-//
-#define BA_INVALID_COMMAND 0x00010000
-#define BA_LOGICAL_ERROR 0x00030000
-#define BA_LOGICAL_BUSY 0x00050000
-#define BA_PROTOCOL_ERROR 0x00070000
-#define BA_UNABLE_TO_PERFORM 0x00090000
-
-//
-// BA_RJT Reason Explanation Codes
-//
-#define BA_NO_REASON 0x00000000
-#define BA_INVALID_OX_RX 0x00000300
-#define BA_SEQUENCE_ABORTED 0x00000500
-
-
-
-#endif /* CPQFCTSSTRUCTS_H */
-
diff --git a/drivers/scsi/cpqfcTStrigger.c b/drivers/scsi/cpqfcTStrigger.c
deleted file mode 100644
index dbb7e65159a0..000000000000
--- a/drivers/scsi/cpqfcTStrigger.c
+++ /dev/null
@@ -1,33 +0,0 @@
-// Routine to trigger Finisar GTA analyzer. Runs of GPIO2
-// NOTE: DEBUG ONLY! Could interfere with FCMNGR/Miniport operation
-// since it writes directly to the Tachyon board. This function
-// developed for Compaq HBA Tachyon TS v1.2 (Rev X5 PCB)
-
-#include "cpqfcTStrigger.h"
-#if TRIGGERABLE_HBA
-
-#include <linux/kernel.h>
-#include <linux/ioport.h>
-#include <linux/types.h>
-#include <linux/pci.h>
-#include <asm/io.h>
-
-void TriggerHBA( void* IOBaseUpper, int Print)
-{
- __u32 long value;
-
- // get initial value in hopes of not modifying any other GPIO line
- IOBaseUpper += 0x188; // TachTL/TS Control reg
-
- value = readl( IOBaseUpper);
- // set HIGH to trigger external analyzer (tested on Dolche Finisar 1Gb GTA)
- // The Finisar anaylzer triggers on low-to-high TTL transition
- value |= 0x01; // set bit 0
-
- writel( value, IOBaseUpper);
-
- if( Print)
- printk( " -GPIO0 set- ");
-}
-
-#endif
diff --git a/drivers/scsi/cpqfcTStrigger.h b/drivers/scsi/cpqfcTStrigger.h
deleted file mode 100644
index c961792e6be0..000000000000
--- a/drivers/scsi/cpqfcTStrigger.h
+++ /dev/null
@@ -1,8 +0,0 @@
-// don't do this unless you have the right hardware!
-#define TRIGGERABLE_HBA 0
-#if TRIGGERABLE_HBA
-void TriggerHBA( void*, int);
-#else
-#define TriggerHBA(x, y)
-#endif
-
diff --git a/drivers/scsi/cpqfcTSworker.c b/drivers/scsi/cpqfcTSworker.c
deleted file mode 100644
index d822ddcc52b2..000000000000
--- a/drivers/scsi/cpqfcTSworker.c
+++ /dev/null
@@ -1,6516 +0,0 @@
-/* Copyright(c) 2000, Compaq Computer Corporation
- * Fibre Channel Host Bus Adapter
- * 64-bit, 66MHz PCI
- * Originally developed and tested on:
- * (front): [chip] Tachyon TS HPFC-5166A/1.2 L2C1090 ...
- * SP# P225CXCBFIEL6T, Rev XC
- * SP# 161290-001, Rev XD
- * (back): Board No. 010008-001 A/W Rev X5, FAB REV X5
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2, or (at your option) any
- * later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- * Written by Don Zimmerman
-*/
-
-#include <linux/sched.h>
-#include <linux/timer.h>
-#include <linux/string.h>
-#include <linux/slab.h>
-#include <linux/ioport.h>
-#include <linux/kernel.h>
-#include <linux/stat.h>
-#include <linux/blkdev.h>
-#include <linux/interrupt.h>
-#include <linux/delay.h>
-#include <linux/smp_lock.h>
-#include <linux/pci.h>
-
-#define SHUTDOWN_SIGS (sigmask(SIGKILL)|sigmask(SIGINT)|sigmask(SIGTERM))
-
-#include <asm/system.h>
-#include <asm/irq.h>
-#include <asm/dma.h>
-
-#include "scsi.h"
-#include <scsi/scsi_host.h> // struct Scsi_Host definition for T handler
-#include "cpqfcTSchip.h"
-#include "cpqfcTSstructs.h"
-#include "cpqfcTStrigger.h"
-
-//#define LOGIN_DBG 1
-
-// REMARKS:
-// Since Tachyon chips may be permitted to wait from 500ms up to 2 sec
-// to empty an outgoing frame from its FIFO to the Fibre Channel stream,
-// we cannot do everything we need to in the interrupt handler. Specifically,
-// every time a link re-init (e.g. LIP) takes place, all SCSI I/O has to be
-// suspended until the login sequences have been completed. Login commands
-// are frames just like SCSI commands are frames; they are subject to the same
-// timeout issues and delays. Also, various specs provide up to 2 seconds for
-// devices to log back in (i.e. respond with ACC to a login frame), so I/O to
-// that device has to be suspended.
-// A serious problem here occurs on highly loaded FC-AL systems. If our FC port
-// has a low priority (e.g. high arbitrated loop physical address, alpa), and
-// some other device is hogging bandwidth (permissible under FC-AL), we might
-// time out thinking the link is hung, when it's simply busy. Many such
-// considerations complicate the design. Although Tachyon assumes control
-// (in silicon) for many link-specific issues, the Linux driver is left with the
-// rest, which turns out to be a difficult, time critical chore.
-
-// These "worker" functions will handle things like FC Logins; all
-// processes with I/O to our device must wait for the Login to complete
-// and (if successful) I/O to resume. In the event of a malfunctioning or
-// very busy loop, it may take hundreds of millisecs or even seconds to complete
-// a frame send. We don't want to hang up the entire server (and all
-// processes which don't depend on Fibre) during this wait.
-
-// The Tachyon chip can have around 30,000 I/O operations ("exchanges")
-// open at one time. However, each exchange must be initiated
-// synchronously (i.e. each of the 30k I/O had to be started one at a
-// time by sending a starting frame via Tachyon's outbound que).
-
-// To accommodate kernel "module" build, this driver limits the exchanges
-// to 256, because of the contiguous physical memory limitation of 128M.
-
-// Typical FC Exchanges are opened presuming the FC frames start without errors,
-// while Exchange completion is handled in the interrupt handler. This
-// optimizes performance for the "everything's working" case.
-// However, when we have FC related errors or hot plugging of FC ports, we pause
-// I/O and handle FC-specific tasks in the worker thread. These FC-specific
-// functions will handle things like FC Logins and Aborts. As the Login sequence
-// completes to each and every target, I/O can resume to that target.
-
-// Our kernel "worker thread" must share the HBA with threads calling
-// "queuecommand". We define a "BoardLock" semaphore which indicates
-// to "queuecommand" that the HBA is unavailable, and Cmnds are added to a
-// board lock Q. When the worker thread finishes with the board, the board
-// lock Q commands are completed with status causing immediate retry.
-// Typically, the board is locked while Logins are in progress after an
-// FC Link Down condition. When Cmnds are re-queued after board lock, the
-// particular Scsi channel/target may or may not have logged back in. When
-// the device is waiting for login, the "prli" flag is clear, in which case
-// commands are passed to a Link Down Q. Whenever the login finally completes,
-// the LinkDown Q is completed, again with status causing immediate retry.
-// When FC devices are logged in, we build and start FC commands to the
-// devices.
-
-// NOTE!! As of May 2000, kernel 2.2.14, the error recovery logic for devices
-// that never log back in (e.g. physically removed) is NOT completely
-// understood. I've still seen instances of system hangs on failed Write
-// commands (possibly from the ext2 layer?) on device removal. Such special
-// cases need to be evaluated from a system/application view - e.g., how
-// exactly does the system want me to complete commands when the device is
-// physically removed??
-
-// local functions
-
-static void SetLoginFields(
- PFC_LOGGEDIN_PORT pLoggedInPort,
- TachFCHDR_GCMND* fchs,
- BOOLEAN PDisc,
- BOOLEAN Originator);
-
-static void AnalyzeIncomingFrame(
- CPQFCHBA *cpqfcHBAdata,
- ULONG QNdx );
-
-static void SendLogins( CPQFCHBA *cpqfcHBAdata, __u32 *FabricPortIds );
-
-static int verify_PLOGI( PTACHYON fcChip,
- TachFCHDR_GCMND* fchs, ULONG* reject_explain);
-static int verify_PRLI( TachFCHDR_GCMND* fchs, ULONG* reject_explain);
-
-static void LoadWWN( PTACHYON fcChip, UCHAR* dest, UCHAR type);
-static void BuildLinkServicePayload(
- PTACHYON fcChip, ULONG type, void* payload);
-
-static void UnblockScsiDevice( struct Scsi_Host *HostAdapter,
- PFC_LOGGEDIN_PORT pLoggedInPort);
-
-static void cpqfcTSCheckandSnoopFCP( PTACHYON fcChip, ULONG x_ID);
-
-static void CompleteBoardLockCmnd( CPQFCHBA *cpqfcHBAdata);
-
-static void RevalidateSEST( struct Scsi_Host *HostAdapter,
- PFC_LOGGEDIN_PORT pLoggedInPort);
-
-static void IssueReportLunsCommand(
- CPQFCHBA* cpqfcHBAdata,
- TachFCHDR_GCMND* fchs);
-
-// (see scsi_error.c comments on kernel task creation)
-
-void cpqfcTSWorkerThread( void *host)
-{
- struct Scsi_Host *HostAdapter = (struct Scsi_Host*)host;
- CPQFCHBA *cpqfcHBAdata = (CPQFCHBA *)HostAdapter->hostdata;
-#ifdef PCI_KERNEL_TRACE
- PTACHYON fcChip = &cpqfcHBAdata->fcChip;
-#endif
- DECLARE_MUTEX_LOCKED(fcQueReady);
- DECLARE_MUTEX_LOCKED(fcTYOBcomplete);
- DECLARE_MUTEX_LOCKED(TachFrozen);
- DECLARE_MUTEX_LOCKED(BoardLock);
-
- ENTER("WorkerThread");
-
- lock_kernel();
- daemonize("cpqfcTS_wt_%d", HostAdapter->host_no);
- siginitsetinv(&current->blocked, SHUTDOWN_SIGS);
-
-
- cpqfcHBAdata->fcQueReady = &fcQueReady; // primary wait point
- cpqfcHBAdata->TYOBcomplete = &fcTYOBcomplete;
- cpqfcHBAdata->TachFrozen = &TachFrozen;
-
-
- cpqfcHBAdata->worker_thread = current;
-
- unlock_kernel();
-
- if( cpqfcHBAdata->notify_wt != NULL )
- up( cpqfcHBAdata->notify_wt); // OK to continue
-
- while(1)
- {
- unsigned long flags;
-
- down_interruptible( &fcQueReady); // wait for something to do
-
- if (signal_pending(current) )
- break;
-
- PCI_TRACE( 0x90)
- // first, take the IO lock so the SCSI upper layers can't call
- // into our _quecommand function (this also disables INTs)
- spin_lock_irqsave( HostAdapter->host_lock, flags); // STOP _que function
- PCI_TRACE( 0x90)
-
- CPQ_SPINLOCK_HBA( cpqfcHBAdata)
- // next, set this pointer to indicate to the _quecommand function
- // that the board is in use, so it should que the command and
- // immediately return (we don't actually require the semaphore function
- // in this driver rev)
-
- cpqfcHBAdata->BoardLock = &BoardLock;
-
- PCI_TRACE( 0x90)
-
- // release the IO lock (and re-enable interrupts)
- spin_unlock_irqrestore( HostAdapter->host_lock, flags);
-
- // disable OUR HBA interrupt (keep them off as much as possible
- // during error recovery)
- disable_irq( cpqfcHBAdata->HostAdapter->irq);
-
- // OK, let's process the Fibre Channel Link Q and do the work
- cpqfcTS_WorkTask( HostAdapter);
-
- // hopefully, no more "work" to do;
- // re-enable our INTs for "normal" completion processing
- enable_irq( cpqfcHBAdata->HostAdapter->irq);
-
-
- cpqfcHBAdata->BoardLock = NULL; // allow commands to be queued
- CPQ_SPINUNLOCK_HBA( cpqfcHBAdata)
-
-
- // Now, complete any Cmnd we Q'd up while BoardLock was held
-
- CompleteBoardLockCmnd( cpqfcHBAdata);
-
-
- }
- // hopefully, the signal was for our module exit...
- if( cpqfcHBAdata->notify_wt != NULL )
- up( cpqfcHBAdata->notify_wt); // yep, we're outta here
-}
-
-
-// Freeze Tachyon routine.
-// If Tachyon is already frozen, return FALSE
-// If Tachyon is not frozen, call freeze function, return TRUE
-//
-static BOOLEAN FreezeTach( CPQFCHBA *cpqfcHBAdata)
-{
- PTACHYON fcChip = &cpqfcHBAdata->fcChip;
- BOOLEAN FrozeTach = FALSE;
- // It's possible that the chip is already frozen; if so,
- // "Freezing" again will NOT! generate another Freeze
- // Completion Message.
-
- if( (fcChip->Registers.TYstatus.value & 0x70000) != 0x70000)
- { // (need to freeze...)
- fcChip->FreezeTachyon( fcChip, 2); // both ERQ and FCP assists
-
- // 2. Get Tach freeze confirmation
- // (synchronize SEST manipulation with Freeze Completion Message)
- // we need INTs on so semaphore can be set.
- enable_irq( cpqfcHBAdata->HostAdapter->irq); // only way to get Semaphore
- down_interruptible( cpqfcHBAdata->TachFrozen); // wait for INT handler sem.
- // can we TIMEOUT semaphore wait?? TBD
- disable_irq( cpqfcHBAdata->HostAdapter->irq);
-
- FrozeTach = TRUE;
- } // (else, already frozen)
-
- return FrozeTach;
-}
-
-
-
-
-// This is the kernel worker thread task, which processes FC
-// tasks which were queued by the Interrupt handler or by
-// other WorkTask functions.
-
-#define DBG 1
-//#undef DBG
-void cpqfcTS_WorkTask( struct Scsi_Host *HostAdapter)
-{
- CPQFCHBA *cpqfcHBAdata = (CPQFCHBA *)HostAdapter->hostdata;
- PTACHYON fcChip = &cpqfcHBAdata->fcChip;
- FC_EXCHANGES *Exchanges = fcChip->Exchanges;
- ULONG QconsumerNdx;
- LONG ExchangeID;
- ULONG ulStatus=0;
- TachFCHDR_GCMND fchs;
- PFC_LINK_QUE fcLQ = cpqfcHBAdata->fcLQ;
-
- ENTER("WorkTask");
-
- // copy current index to work on
- QconsumerNdx = fcLQ->consumer;
-
- PCI_TRACEO( fcLQ->Qitem[QconsumerNdx].Type, 0x90)
-
-
- // NOTE: when this switch completes, we will "consume" the Que item
-// printk("Que type %Xh\n", fcLQ->Qitem[QconsumerNdx].Type);
- switch( fcLQ->Qitem[QconsumerNdx].Type )
- {
- // incoming frame - link service (ACC, UNSOL REQ, etc.)
- // or FCP-SCSI command
- case SFQ_UNKNOWN:
- AnalyzeIncomingFrame( cpqfcHBAdata, QconsumerNdx );
-
- break;
-
-
-
- case EXCHANGE_QUEUED: // an Exchange (i.e. FCP-SCSI) was previously
- // Queued because the link was down. The
- // heartbeat timer detected it and Queued it here.
- // We attempt to start it again, and if
- // successful we clear the EXCHANGE_Q flag.
- // If the link doesn't come up, the Exchange
- // will eventually time-out.
-
- ExchangeID = (LONG) // x_ID copied from DPC timeout function
- fcLQ->Qitem[QconsumerNdx].ulBuff[0];
-
- // It's possible that a Q'd exchange could have already
- // been started by other logic (e.g. ABTS process)
- // Don't start if already started (Q'd flag clear)
-
- if( Exchanges->fcExchange[ExchangeID].status & EXCHANGE_QUEUED )
- {
-// printk(" *Start Q'd x_ID %Xh: type %Xh ",
-// ExchangeID, Exchanges->fcExchange[ExchangeID].type);
-
- ulStatus = cpqfcTSStartExchange( cpqfcHBAdata, ExchangeID);
- if( !ulStatus )
- {
-// printk("success* ");
- }
- else
- {
-#ifdef DBG
-
- if( ulStatus == EXCHANGE_QUEUED)
- printk("Queued* ");
- else
- printk("failed* ");
-
-#endif
- }
- }
- break;
-
-
- case LINKDOWN:
- // (lots of things already done in INT handler) future here?
- break;
-
-
- case LINKACTIVE: // Tachyon set the Lup bit in FM status
- // NOTE: some misbehaving FC ports (like Tach2.1)
- // can re-LIP immediately after a LIP completes.
-
- // if "initiator", need to verify LOGs with ports
-// printk("\n*LNKUP* ");
-
- if( fcChip->Options.initiator )
- SendLogins( cpqfcHBAdata, NULL ); // PLOGI or PDISC, based on fcPort data
- // if SendLogins successfully completes, PortDiscDone
- // will be set.
-
-
- // If SendLogins was successful, then we expect to get incoming
- // ACCepts or REJECTs, which are handled below.
-
- break;
-
- // LinkService and Fabric request/reply processing
- case ELS_FDISC: // need to send Fabric Discovery (Login)
- case ELS_FLOGI: // need to send Fabric Login
- case ELS_SCR: // need to send State Change Registration
- case FCS_NSR: // need to send Name Service Request
- case ELS_PLOGI: // need to send PLOGI
- case ELS_ACC: // send generic ACCept
- case ELS_PLOGI_ACC: // need to send ELS ACCept frame to recv'd PLOGI
- case ELS_PRLI_ACC: // need to send ELS ACCept frame to recv'd PRLI
- case ELS_LOGO: // need to send ELS LOGO (logout)
- case ELS_LOGO_ACC: // need to send ELS ACCept frame to recv'd PLOGI
- case ELS_RJT: // ReJecT reply
- case ELS_PRLI: // need to send ELS PRLI
-
-
-// printk(" *ELS %Xh* ", fcLQ->Qitem[QconsumerNdx].Type);
- // if PortDiscDone is not set, it means the SendLogins routine
- // failed to complete -- assume that LDn occurred, so login frames
- // are invalid
- if( !cpqfcHBAdata->PortDiscDone) // cleared by LDn
- {
- printk("Discard Q'd ELS login frame\n");
- break;
- }
-
- ulStatus = cpqfcTSBuildExchange(
- cpqfcHBAdata,
- fcLQ->Qitem[QconsumerNdx].Type, // e.g. PLOGI
- (TachFCHDR_GCMND*)
- fcLQ->Qitem[QconsumerNdx].ulBuff, // incoming fchs
- NULL, // no data (no scatter/gather list)
- &ExchangeID );// fcController->fcExchanges index, -1 if failed
-
- if( !ulStatus ) // Exchange setup?
- {
- ulStatus = cpqfcTSStartExchange( cpqfcHBAdata, ExchangeID );
- if( !ulStatus )
- {
- // submitted to Tach's Outbound Que (ERQ PI incremented)
- // waited for completion for ELS type (Login frames issued
- // synchronously)
- }
- else
- // check reason for Exchange not being started - we might
- // want to Queue and start later, or fail with error
- {
-
- }
- }
-
- else // Xchange setup failed...
- printk(" cpqfcTSBuildExchange failed: %Xh\n", ulStatus );
-
- break;
-
- case SCSI_REPORT_LUNS:
- // pass the incoming frame (actually, it's a PRLI frame)
- // so we can send REPORT_LUNS, in order to determine VSA/PDU
- // FCP-SCSI Lun address mode
- IssueReportLunsCommand( cpqfcHBAdata, (TachFCHDR_GCMND*)
- fcLQ->Qitem[QconsumerNdx].ulBuff);
-
- break;
-
-
-
-
- case BLS_ABTS: // need to ABORT one or more exchanges
- {
- LONG x_ID = fcLQ->Qitem[QconsumerNdx].ulBuff[0];
- BOOLEAN FrozeTach = FALSE;
-
- if ( x_ID >= TACH_SEST_LEN ) // (in)sanity check
- {
-// printk( " cpqfcTS ERROR! BOGUS x_ID %Xh", x_ID);
- break;
- }
-
-
- if( Exchanges->fcExchange[ x_ID].Cmnd == NULL ) // should be RARE
- {
-// printk(" ABTS %Xh Scsi Cmnd null! ", x_ID);
-
- break; // nothing to abort!
- }
-
-//#define ABTS_DBG
-#ifdef ABTS_DBG
- printk("INV SEST[%X] ", x_ID);
- if( Exchanges->fcExchange[x_ID].status & FC2_TIMEOUT)
- {
- printk("FC2TO");
- }
- if( Exchanges->fcExchange[x_ID].status & INITIATOR_ABORT)
- {
- printk("IA");
- }
- if( Exchanges->fcExchange[x_ID].status & PORTID_CHANGED)
- {
- printk("PORTID");
- }
- if( Exchanges->fcExchange[x_ID].status & DEVICE_REMOVED)
- {
- printk("DEVRM");
- }
- if( Exchanges->fcExchange[x_ID].status & LINKFAIL_TX)
- {
- printk("LKF");
- }
- if( Exchanges->fcExchange[x_ID].status & FRAME_TO)
- {
- printk("FRMTO");
- }
- if( Exchanges->fcExchange[x_ID].status & ABORTSEQ_NOTIFY)
- {
- printk("ABSQ");
- }
- if( Exchanges->fcExchange[x_ID].status & SFQ_FRAME)
- {
- printk("SFQFR");
- }
-
- if( Exchanges->fcExchange[ x_ID].type == 0x2000)
- printk(" WR");
- else if( Exchanges->fcExchange[ x_ID].type == 0x3000)
- printk(" RD");
- else if( Exchanges->fcExchange[ x_ID].type == 0x10)
- printk(" ABTS");
- else
- printk(" %Xh", Exchanges->fcExchange[ x_ID].type);
-
- if( !(Exchanges->fcExchange[x_ID].status & INITIATOR_ABORT))
- {
- printk(" Cmd %p, ",
- Exchanges->fcExchange[ x_ID].Cmnd);
-
- printk(" brd/chn/trg/lun %d/%d/%d/%d port_id %06X\n",
- cpqfcHBAdata->HBAnum,
- Exchanges->fcExchange[ x_ID].Cmnd->channel,
- Exchanges->fcExchange[ x_ID].Cmnd->target,
- Exchanges->fcExchange[ x_ID].Cmnd->lun,
- Exchanges->fcExchange[ x_ID].fchs.d_id & 0xFFFFFF);
- }
- else // assume that Cmnd ptr is invalid on _abort()
- {
- printk(" Cmd ptr invalid\n");
- }
-
-#endif
-
-
- // Steps to ABORT a SEST exchange:
- // 1. Freeze TL SCSI assists & ERQ (everything)
- // 2. Receive FROZEN inbound CM (must succeed!)
- // 3. Invalidate x_ID SEST entry
- // 4. Resume TL SCSI assists & ERQ (everything)
- // 5. Build/start on exchange - change "type" to BLS_ABTS,
- // timeout to X sec (RA_TOV from PLDA is actually 0)
- // 6. Set Exchange Q'd status if ABTS cannot be started,
- // or simply complete Exchange in "Terminate" condition
-
- PCI_TRACEO( x_ID, 0xB4)
-
- // 1 & 2 . Freeze Tach & get confirmation of freeze
- FrozeTach = FreezeTach( cpqfcHBAdata);
-
- // 3. OK, Tachyon is frozen, so we can invalidate SEST exchange.
- // FC2_TIMEOUT means we are originating the abort, while
- // TARGET_ABORT means we are ACCepting an abort.
- // LINKFAIL_TX, ABORTSEQ_NOFITY, INV_ENTRY or FRAME_TO are
- // all from Tachyon:
- // Exchange was corrupted by LDn or other FC physical failure
- // INITIATOR_ABORT means the upper layer driver/application
- // requested the abort.
-
-
-
- // clear bit 31 (VALid), to invalidate & take control from TL
- fcChip->SEST->u[ x_ID].IWE.Hdr_Len &= 0x7FFFFFFF;
-
-
- // examine and Tach's "Linked List" for IWEs that
- // received (nearly) simultaneous transfer ready (XRDY)
- // repair linked list if necessary (TBD!)
- // (If we ignore the "Linked List", we will time out
- // WRITE commands where we received the FCP-SCSI XFRDY
- // frame (because Tachyon didn't processes it). Linked List
- // management should be done as an optimization.
-
-// readl( fcChip->Registers.ReMapMemBase+TL_MEM_SEST_LINKED_LIST ));
-
-
-
-
- // 4. Resume all Tachlite functions (for other open Exchanges)
- // as quickly as possible to allow other exchanges to other ports
- // to resume. Freezing Tachyon may cause cascading errors, because
- // any received SEST frame cannot be processed by the SEST.
- // Don't "unfreeze" unless Link is operational
- if( FrozeTach ) // did we just freeze it (above)?
- fcChip->UnFreezeTachyon( fcChip, 2); // both ERQ and FCP assists
-
-
- PCI_TRACEO( x_ID, 0xB4)
-
- // Note there is no confirmation that the chip is "unfrozen". Also,
- // if the Link is down when unfreeze is called, it has no effect.
- // Chip will unfreeze when the Link is back up.
-
- // 5. Now send out Abort commands if possible
- // Some Aborts can't be "sent" (Port_id changed or gone);
- // if the device is gone, there is no port_id to send the ABTS to.
-
- if( !(Exchanges->fcExchange[ x_ID].status & PORTID_CHANGED)
- &&
- !(Exchanges->fcExchange[ x_ID].status & DEVICE_REMOVED) )
- {
- Exchanges->fcExchange[ x_ID].type = BLS_ABTS;
- fchs.s_id = Exchanges->fcExchange[ x_ID].fchs.d_id;
- ulStatus = cpqfcTSBuildExchange(
- cpqfcHBAdata,
- BLS_ABTS,
- &fchs, // (uses only s_id)
- NULL, // (no scatter/gather list for ABTS)
- &x_ID );// ABTS on this Exchange ID
-
- if( !ulStatus ) // Exchange setup build OK?
- {
-
- // ABTS may be needed because an Exchange was corrupted
- // by a Link disruption. If the Link is UP, we can
- // presume that this ABTS can start immediately; otherwise,
- // set Que'd status so the Login functions
- // can restart it when the FC physical Link is restored
- if( ((fcChip->Registers.FMstatus.value &0xF0) &0x80)) // loop init?
- {
-// printk(" *set Q status x_ID %Xh on LDn* ", x_ID);
- Exchanges->fcExchange[ x_ID].status |= EXCHANGE_QUEUED;
- }
-
- else // what FC device (port_id) does the Cmd belong to?
- {
- PFC_LOGGEDIN_PORT pLoggedInPort =
- Exchanges->fcExchange[ x_ID].pLoggedInPort;
-
- // if Port is logged in, we might start the abort.
-
- if( (pLoggedInPort != NULL)
- &&
- (pLoggedInPort->prli == TRUE) )
- {
- // it's possible that an Exchange has already been Queued
- // to start after Login completes. Check and don't
- // start it (again) here if Q'd status set
-// printk(" ABTS xchg %Xh ", x_ID);
- if( Exchanges->fcExchange[x_ID].status & EXCHANGE_QUEUED)
- {
-// printk("already Q'd ");
- }
- else
- {
-// printk("starting ");
-
- fcChip->fcStats.FC2aborted++;
- ulStatus = cpqfcTSStartExchange( cpqfcHBAdata, x_ID );
- if( !ulStatus )
- {
- // OK
- // submitted to Tach's Outbound Que (ERQ PI incremented)
- }
- else
- {
-/* printk("ABTS exchange start failed -status %Xh, x_ID %Xh ",
- ulStatus, x_ID);
-*/
- }
- }
- }
- else
- {
-/* printk(" ABTS NOT starting xchg %Xh, %p ",
- x_ID, pLoggedInPort);
- if( pLoggedInPort )
- printk("prli %d ", pLoggedInPort->prli);
-*/
- }
- }
- }
- else // what the #@!
- { // how do we fail to build an Exchange for ABTS??
- printk("ABTS exchange build failed -status %Xh, x_ID %Xh\n",
- ulStatus, x_ID);
- }
- }
- else // abort without ABTS -- just complete exchange/Cmnd to Linux
- {
-// printk(" *Terminating x_ID %Xh on %Xh* ",
-// x_ID, Exchanges->fcExchange[x_ID].status);
- cpqfcTSCompleteExchange( cpqfcHBAdata->PciDev, fcChip, x_ID);
-
- }
- } // end of ABTS case
- break;
-
-
-
- case BLS_ABTS_ACC: // need to ACCept one ABTS
- // (NOTE! this code not updated for Linux yet..)
-
-
- printk(" *ABTS_ACC* ");
- // 1. Freeze TL
-
- fcChip->FreezeTachyon( fcChip, 2); // both ERQ and FCP assists
-
- memcpy( // copy the incoming ABTS frame
- &fchs,
- fcLQ->Qitem[QconsumerNdx].ulBuff, // incoming fchs
- sizeof( fchs));
-
- // 3. OK, Tachyon is frozen so we can invalidate SEST entry
- // (if necessary)
- // Status FC2_TIMEOUT means we are originating the abort, while
- // TARGET_ABORT means we are ACCepting an abort
-
- ExchangeID = fchs.ox_rx_id & 0x7FFF; // RX_ID for exchange
-// printk("ABTS ACC for Target ExchangeID %Xh\n", ExchangeID);
-
-
- // sanity check on received ExchangeID
- if( Exchanges->fcExchange[ ExchangeID].status == TARGET_ABORT )
- {
- // clear bit 31 (VALid), to invalidate & take control from TL
-// printk("Invalidating SEST exchange %Xh\n", ExchangeID);
- fcChip->SEST->u[ ExchangeID].IWE.Hdr_Len &= 0x7FFFFFFF;
- }
-
-
- // 4. Resume all Tachlite functions (for other open Exchanges)
- // as quickly as possible to allow other exchanges to other ports
- // to resume. Freezing Tachyon for too long may royally screw
- // up everything!
- fcChip->UnFreezeTachyon( fcChip, 2); // both ERQ and FCP assists
-
- // Note there is no confirmation that the chip is "unfrozen". Also,
- // if the Link is down when unfreeze is called, it has no effect.
- // Chip will unfreeze when the Link is back up.
-
- // 5. Now send out Abort ACC reply for this exchange
- Exchanges->fcExchange[ ExchangeID].type = BLS_ABTS_ACC;
-
- fchs.s_id = Exchanges->fcExchange[ ExchangeID].fchs.d_id;
- ulStatus = cpqfcTSBuildExchange(
- cpqfcHBAdata,
- BLS_ABTS_ACC,
- &fchs,
- NULL, // no data (no scatter/gather list)
- &ExchangeID );// fcController->fcExchanges index, -1 if failed
-
- if( !ulStatus ) // Exchange setup?
- {
- ulStatus = cpqfcTSStartExchange( cpqfcHBAdata, ExchangeID );
- if( !ulStatus )
- {
- // submitted to Tach's Outbound Que (ERQ PI incremented)
- // waited for completion for ELS type (Login frames issued
- // synchronously)
- }
- else
- // check reason for Exchange not being started - we might
- // want to Queue and start later, or fail with error
- {
-
- }
- }
- break;
-
-
- case BLS_ABTS_RJT: // need to ReJecT one ABTS; reject implies the
- // exchange doesn't exist in the TARGET context.
- // ExchangeID has to come from LinkService space.
-
- printk(" *ABTS_RJT* ");
- ulStatus = cpqfcTSBuildExchange(
- cpqfcHBAdata,
- BLS_ABTS_RJT,
- (TachFCHDR_GCMND*)
- fcLQ->Qitem[QconsumerNdx].ulBuff, // incoming fchs
- NULL, // no data (no scatter/gather list)
- &ExchangeID );// fcController->fcExchanges index, -1 if failed
-
- if( !ulStatus ) // Exchange setup OK?
- {
- ulStatus = cpqfcTSStartExchange( cpqfcHBAdata, ExchangeID );
- // If it fails, we aren't required to retry.
- }
- if( ulStatus )
- {
- printk("Failed to send BLS_RJT for ABTS, X_ID %Xh\n", ExchangeID);
- }
- else
- {
- printk("Sent BLS_RJT for ABTS, X_ID %Xh\n", ExchangeID);
-
- }
-
- break;
-
-
-
- default:
- break;
- } // end switch
-//doNothing:
- // done with this item - now set the NEXT index
-
- if( QconsumerNdx+1 >= FC_LINKQ_DEPTH ) // rollover test
- {
- fcLQ->consumer = 0;
- }
- else
- {
- fcLQ->consumer++;
- }
-
- PCI_TRACEO( fcLQ->Qitem[QconsumerNdx].Type, 0x94)
-
- LEAVE("WorkTask");
- return;
-}
-
-
-
-
-// When Tachyon reports link down, bad al_pa, or Link Service (e.g. Login)
-// commands come in, post to the LinkQ so that action can be taken outside the
-// interrupt handler.
-// This circular Q works like Tachyon's que - the producer points to the next
-// (unused) entry. Called by Interrupt handler, WorkerThread, Timer
-// sputlinkq
-void cpqfcTSPutLinkQue( CPQFCHBA *cpqfcHBAdata,
- int Type,
- void *QueContent)
-{
- PTACHYON fcChip = &cpqfcHBAdata->fcChip;
-// FC_EXCHANGES *Exchanges = fcChip->Exchanges;
- PFC_LINK_QUE fcLQ = cpqfcHBAdata->fcLQ;
- ULONG ndx;
-
- ENTER("cpqfcTSPutLinkQ");
-
- ndx = fcLQ->producer;
-
- ndx += 1; // test for Que full
-
-
-
- if( ndx >= FC_LINKQ_DEPTH ) // rollover test
- ndx = 0;
-
- if( ndx == fcLQ->consumer ) // QUE full test
- {
- // QUE was full! lost LK command (fatal to logic)
- fcChip->fcStats.lnkQueFull++;
-
- printk("*LinkQ Full!*");
- TriggerHBA( fcChip->Registers.ReMapMemBase, 1);
-/*
- {
- int i;
- printk("LinkQ PI %d, CI %d\n", fcLQ->producer,
- fcLQ->consumer);
-
- for( i=0; i< FC_LINKQ_DEPTH; )
- {
- printk(" [%d]%Xh ", i, fcLQ->Qitem[i].Type);
- if( (++i %8) == 0) printk("\n");
- }
-
- }
-*/
- printk( "cpqfcTS: WARNING!! PutLinkQue - FULL!\n"); // we're hung
- }
- else // QUE next element
- {
- // Prevent certain multiple (back-to-back) requests.
- // This is important in that we don't want to issue multiple
- // ABTS for the same Exchange, or do multiple FM inits, etc.
- // We can never be sure of the timing of events reported to
- // us by Tach's IMQ, which can depend on system/bus speeds,
- // FC physical link circumstances, etc.
-
- if( (fcLQ->producer != fcLQ->consumer)
- &&
- (Type == FMINIT) )
- {
- LONG lastNdx; // compute previous producer index
- if( fcLQ->producer)
- lastNdx = fcLQ->producer- 1;
- else
- lastNdx = FC_LINKQ_DEPTH-1;
-
-
- if( fcLQ->Qitem[lastNdx].Type == FMINIT)
- {
-// printk(" *skip FMINIT Q post* ");
-// goto DoneWithPutQ;
- }
-
- }
-
- // OK, add the Q'd item...
-
- fcLQ->Qitem[fcLQ->producer].Type = Type;
-
- memcpy(
- fcLQ->Qitem[fcLQ->producer].ulBuff,
- QueContent,
- sizeof(fcLQ->Qitem[fcLQ->producer].ulBuff));
-
- fcLQ->producer = ndx; // increment Que producer
-
- // set semaphore to wake up Kernel (worker) thread
- //
- up( cpqfcHBAdata->fcQueReady );
- }
-
-//DoneWithPutQ:
-
- LEAVE("cpqfcTSPutLinkQ");
-}
-
-
-
-
-// reset device ext FC link Q
-void cpqfcTSLinkQReset( CPQFCHBA *cpqfcHBAdata)
-
-{
- PFC_LINK_QUE fcLQ = cpqfcHBAdata->fcLQ;
- fcLQ->producer = 0;
- fcLQ->consumer = 0;
-
-}
-
-
-
-
-
-// When Tachyon gets an unassisted FCP-SCSI frame, post here so
-// an arbitrary context thread (e.g. IOCTL loopback test function)
-// can process it.
-
-// (NOTE: Not revised for Linux)
-// This Q works like Tachyon's que - the producer points to the next
-// (unused) entry.
-void cpqfcTSPutScsiQue( CPQFCHBA *cpqfcHBAdata,
- int Type,
- void *QueContent)
-{
-// CPQFCHBA *cpqfcHBAdata = (CPQFCHBA *)HostAdapter->hostdata;
-// PTACHYON fcChip = &cpqfcHBAdata->fcChip;
-
-// ULONG ndx;
-
-// ULONG *pExchangeID;
-// LONG ExchangeID;
-
-/*
- KeAcquireSpinLockAtDpcLevel( &pDevExt->fcScsiQueLock);
- ndx = pDevExt->fcScsiQue.producer + 1; // test for Que full
-
- if( ndx >= FC_SCSIQ_DEPTH ) // rollover test
- ndx = 0;
-
- if( ndx == pDevExt->fcScsiQue.consumer ) // QUE full test
- {
- // QUE was full! lost LK command (fatal to logic)
- fcChip->fcStats.ScsiQueFull++;
-#ifdef DBG
- printk( "fcPutScsiQue - FULL!\n");
-#endif
-
- }
- else // QUE next element
- {
- pDevExt->fcScsiQue.Qitem[pDevExt->fcScsiQue.producer].Type = Type;
-
- if( Type == FCP_RSP )
- {
- // this TL inbound message type means that a TL SEST exchange has
- // copied an FCP response frame into a buffer pointed to by the SEST
- // entry. That buffer is allocated in the SEST structure at ->RspHDR.
- // Copy the RspHDR for use by the Que handler.
- pExchangeID = (ULONG *)QueContent;
-
- memcpy(
- pDevExt->fcScsiQue.Qitem[pDevExt->fcScsiQue.producer].ulBuff,
- &fcChip->SEST->RspHDR[ *pExchangeID ],
- sizeof(pDevExt->fcScsiQue.Qitem[0].ulBuff)); // (any element for size)
-
- }
- else
- {
- memcpy(
- pDevExt->fcScsiQue.Qitem[pDevExt->fcScsiQue.producer].ulBuff,
- QueContent,
- sizeof(pDevExt->fcScsiQue.Qitem[pDevExt->fcScsiQue.producer].ulBuff));
- }
-
- pDevExt->fcScsiQue.producer = ndx; // increment Que
-
-
- KeSetEvent( &pDevExt->TYIBscsi, // signal any waiting thread
- 0, // no priority boost
- FALSE ); // no waiting later for this event
- }
- KeReleaseSpinLockFromDpcLevel( &pDevExt->fcScsiQueLock);
-*/
-}
-
-
-
-
-
-
-
-static void ProcessELS_Request( CPQFCHBA*,TachFCHDR_GCMND*);
-
-static void ProcessELS_Reply( CPQFCHBA*,TachFCHDR_GCMND*);
-
-static void ProcessFCS_Reply( CPQFCHBA*,TachFCHDR_GCMND*);
-
-void cpqfcTSImplicitLogout( CPQFCHBA* cpqfcHBAdata,
- PFC_LOGGEDIN_PORT pFcPort)
-{
- PTACHYON fcChip = &cpqfcHBAdata->fcChip;
-
- if( pFcPort->port_id != 0xFFFC01 ) // don't care about Fabric
- {
- fcChip->fcStats.logouts++;
- printk("cpqfcTS: Implicit logout of WWN %08X%08X, port_id %06X\n",
- (ULONG)pFcPort->u.liWWN,
- (ULONG)(pFcPort->u.liWWN >>32),
- pFcPort->port_id);
-
- // Terminate I/O with this (Linux) Scsi target
- cpqfcTSTerminateExchange( cpqfcHBAdata,
- &pFcPort->ScsiNexus,
- DEVICE_REMOVED);
- }
-
- // Do an "implicit logout" - we can't really Logout the device
- // (i.e. with LOGOut Request) because of port_id confusion
- // (i.e. the Other port has no port_id).
- // A new login for that WWN will have to re-write port_id (0 invalid)
- pFcPort->port_id = 0; // invalid!
- pFcPort->pdisc = FALSE;
- pFcPort->prli = FALSE;
- pFcPort->plogi = FALSE;
- pFcPort->flogi = FALSE;
- pFcPort->LOGO_timer = 0;
- pFcPort->device_blocked = TRUE; // block Scsi Requests
- pFcPort->ScsiNexus.VolumeSetAddressing=0;
-}
-
-
-// On FC-AL, there is a chance that a previously known device can
-// be quietly removed (e.g. with non-managed hub),
-// while a NEW device (with different WWN) took the same alpa or
-// even 24-bit port_id. This chance is unlikely but we must always
-// check for it.
-static void TestDuplicatePortId( CPQFCHBA* cpqfcHBAdata,
- PFC_LOGGEDIN_PORT pLoggedInPort)
-{
- PTACHYON fcChip = &cpqfcHBAdata->fcChip;
- // set "other port" at beginning of fcPorts list
- PFC_LOGGEDIN_PORT pOtherPortWithPortId = fcChip->fcPorts.pNextPort;
- while( pOtherPortWithPortId )
- {
- if( (pOtherPortWithPortId->port_id ==
- pLoggedInPort->port_id)
- &&
- (pOtherPortWithPortId != pLoggedInPort) )
- {
- // trouble! (Implicitly) Log the other guy out
- printk(" *port_id %Xh is duplicated!* ",
- pOtherPortWithPortId->port_id);
- cpqfcTSImplicitLogout( cpqfcHBAdata, pOtherPortWithPortId);
- }
- pOtherPortWithPortId = pOtherPortWithPortId->pNextPort;
- }
-}
-
-
-
-
-
-
-// Dynamic Memory Allocation for newly discovered FC Ports.
-// For simplicity, maintain fcPorts structs for ALL
-// for discovered devices, including those we never do I/O with
-// (e.g. Fabric addresses)
-
-static PFC_LOGGEDIN_PORT CreateFcPort(
- CPQFCHBA* cpqfcHBAdata,
- PFC_LOGGEDIN_PORT pLastLoggedInPort,
- TachFCHDR_GCMND* fchs,
- LOGIN_PAYLOAD* plogi)
-{
- PTACHYON fcChip = &cpqfcHBAdata->fcChip;
- PFC_LOGGEDIN_PORT pNextLoggedInPort = NULL;
- int i;
-
-
- printk("cpqfcTS: New FC port %06Xh WWN: ", fchs->s_id);
- for( i=3; i>=0; i--) // copy the LOGIN port's WWN
- printk("%02X", plogi->port_name[i]);
- for( i=7; i>3; i--) // copy the LOGIN port's WWN
- printk("%02X", plogi->port_name[i]);
-
-
- // allocate mem for new port
- // (these are small and rare allocations...)
- pNextLoggedInPort = kmalloc( sizeof( FC_LOGGEDIN_PORT), GFP_ATOMIC );
-
-
- // allocation succeeded? Fill out NEW PORT
- if( pNextLoggedInPort )
- {
- // clear out any garbage (sometimes exists)
- memset( pNextLoggedInPort, 0, sizeof( FC_LOGGEDIN_PORT));
-
-
- // If we login to a Fabric, we don't want to treat it
- // as a SCSI device...
- if( (fchs->s_id & 0xFFF000) != 0xFFF000)
- {
- int i;
-
- // create a unique "virtual" SCSI Nexus (for now, just a
- // new target ID) -- we will update channel/target on REPORT_LUNS
- // special case for very first SCSI target...
- if( cpqfcHBAdata->HostAdapter->max_id == 0)
- {
- pNextLoggedInPort->ScsiNexus.target = 0;
- fcChip->fcPorts.ScsiNexus.target = -1; // don't use "stub"
- }
- else
- {
- pNextLoggedInPort->ScsiNexus.target =
- cpqfcHBAdata->HostAdapter->max_id;
- }
-
- // initialize the lun[] Nexus struct for lun masking
- for( i=0; i< CPQFCTS_MAX_LUN; i++)
- pNextLoggedInPort->ScsiNexus.lun[i] = 0xFF; // init to NOT USED
-
- pNextLoggedInPort->ScsiNexus.channel = 0; // cpqfcTS has 1 FC port
-
- printk(" SCSI Chan/Trgt %d/%d",
- pNextLoggedInPort->ScsiNexus.channel,
- pNextLoggedInPort->ScsiNexus.target);
-
- // tell Scsi layers about the new target...
- cpqfcHBAdata->HostAdapter->max_id++;
-// printk("HostAdapter->max_id = %d\n",
-// cpqfcHBAdata->HostAdapter->max_id);
- }
- else
- {
- // device is NOT SCSI (in case of Fabric)
- pNextLoggedInPort->ScsiNexus.target = -1; // invalid
- }
-
- // create forward link to new port
- pLastLoggedInPort->pNextPort = pNextLoggedInPort;
- printk("\n");
-
- }
- return pNextLoggedInPort; // NULL on allocation failure
-} // end NEW PORT (WWN) logic
-
-
-
-// For certain cases, we want to terminate exchanges without
-// sending ABTS to the device. Examples include when an FC
-// device changed it's port_id after Loop re-init, or when
-// the device sent us a logout. In the case of changed port_id,
-// we want to complete the command and return SOFT_ERROR to
-// force a re-try. In the case of LOGOut, we might return
-// BAD_TARGET if the device is really gone.
-// Since we must ensure that Tachyon is not operating on the
-// exchange, we have to freeze the chip
-// sterminateex
-void cpqfcTSTerminateExchange(
- CPQFCHBA* cpqfcHBAdata, SCSI_NEXUS *ScsiNexus, int TerminateStatus)
-{
- PTACHYON fcChip = &cpqfcHBAdata->fcChip;
- FC_EXCHANGES *Exchanges = fcChip->Exchanges;
- ULONG x_ID;
-
- if( ScsiNexus )
- {
-// printk("TerminateExchange: ScsiNexus chan/target %d/%d\n",
-// ScsiNexus->channel, ScsiNexus->target);
-
- }
-
- for( x_ID = 0; x_ID < TACH_SEST_LEN; x_ID++)
- {
- if( Exchanges->fcExchange[x_ID].type ) // in use?
- {
- if( ScsiNexus == NULL ) // our HBA changed - term. all
- {
- Exchanges->fcExchange[x_ID].status = TerminateStatus;
- cpqfcTSPutLinkQue( cpqfcHBAdata, BLS_ABTS, &x_ID );
- }
- else
- {
- // If a device, according to WWN, has been removed, it's
- // port_id may be used by another working device, so we
- // have to terminate by SCSI target, NOT port_id.
- if( Exchanges->fcExchange[x_ID].Cmnd) // Cmnd in progress?
- {
- if( (Exchanges->fcExchange[x_ID].Cmnd->device->id == ScsiNexus->target)
- &&
- (Exchanges->fcExchange[x_ID].Cmnd->device->channel == ScsiNexus->channel))
- {
- Exchanges->fcExchange[x_ID].status = TerminateStatus;
- cpqfcTSPutLinkQue( cpqfcHBAdata, BLS_ABTS, &x_ID ); // timed-out
- }
- }
-
- // (in case we ever need it...)
- // all SEST structures have a remote node ID at SEST DWORD 2
- // if( (fcChip->SEST->u[ x_ID ].TWE.Remote_Node_ID >> 8)
- // == port_id)
- }
- }
- }
-}
-
-
-static void ProcessELS_Request(
- CPQFCHBA* cpqfcHBAdata, TachFCHDR_GCMND* fchs)
-{
- PTACHYON fcChip = &cpqfcHBAdata->fcChip;
-// FC_EXCHANGES *Exchanges = fcChip->Exchanges;
-// ULONG ox_id = (fchs->ox_rx_id >>16);
- PFC_LOGGEDIN_PORT pLoggedInPort=NULL, pLastLoggedInPort;
- BOOLEAN NeedReject = FALSE;
- ULONG ls_reject_code = 0; // default don'n know??
-
-
- // Check the incoming frame for a supported ELS type
- switch( fchs->pl[0] & 0xFFFF)
- {
- case 0x0050: // PDISC?
-
- // Payload for PLOGI and PDISC is identical (request & reply)
- if( !verify_PLOGI( fcChip, fchs, &ls_reject_code) ) // valid payload?
- {
- LOGIN_PAYLOAD logi; // FC-PH Port Login
-
- // PDISC payload OK. If critical login fields
- // (e.g. WWN) matches last login for this port_id,
- // we may resume any prior exchanges
- // with the other port
-
-
- BigEndianSwap( (UCHAR*)&fchs->pl[0], (UCHAR*)&logi, sizeof(logi));
-
- pLoggedInPort = fcFindLoggedInPort(
- fcChip,
- NULL, // don't search Scsi Nexus
- 0, // don't search linked list for port_id
- &logi.port_name[0], // search linked list for WWN
- &pLastLoggedInPort); // must return non-NULL; when a port_id
- // is not found, this pointer marks the
- // end of the singly linked list
-
- if( pLoggedInPort != NULL) // WWN found (prior login OK)
- {
-
- if( (fchs->s_id & 0xFFFFFF) == pLoggedInPort->port_id)
- {
- // Yes. We were expecting PDISC?
- if( pLoggedInPort->pdisc )
- {
- // Yes; set fields accordingly. (PDISC, not Originator)
- SetLoginFields( pLoggedInPort, fchs, TRUE, FALSE);
-
- // send 'ACC' reply
- cpqfcTSPutLinkQue( cpqfcHBAdata,
- ELS_PLOGI_ACC, // (PDISC same as PLOGI ACC)
- fchs );
-
- // OK to resume I/O...
- }
- else
- {
- printk("Not expecting PDISC (pdisc=FALSE)\n");
- NeedReject = TRUE;
- // set reject reason code
- ls_reject_code =
- LS_RJT_REASON( PROTOCOL_ERROR, INITIATOR_CTL_ERROR);
- }
- }
- else
- {
- if( pLoggedInPort->port_id != 0)
- {
- printk("PDISC PortID change: old %Xh, new %Xh\n",
- pLoggedInPort->port_id, fchs->s_id &0xFFFFFF);
- }
- NeedReject = TRUE;
- // set reject reason code
- ls_reject_code =
- LS_RJT_REASON( PROTOCOL_ERROR, INITIATOR_CTL_ERROR);
-
- }
- }
- else
- {
- printk("PDISC Request from unknown WWN\n");
- NeedReject = TRUE;
-
- // set reject reason code
- ls_reject_code =
- LS_RJT_REASON( LOGICAL_ERROR, INVALID_PORT_NAME);
- }
-
- }
- else // Payload unacceptable
- {
- printk("payload unacceptable\n");
- NeedReject = TRUE; // reject code already set
-
- }
-
- if( NeedReject)
- {
- ULONG port_id;
- // The PDISC failed. Set login struct flags accordingly,
- // terminate any I/O to this port, and Q a PLOGI
- if( pLoggedInPort )
- {
- pLoggedInPort->pdisc = FALSE;
- pLoggedInPort->prli = FALSE;
- pLoggedInPort->plogi = FALSE;
-
- cpqfcTSTerminateExchange( cpqfcHBAdata,
- &pLoggedInPort->ScsiNexus, PORTID_CHANGED);
- port_id = pLoggedInPort->port_id;
- }
- else
- {
- port_id = fchs->s_id &0xFFFFFF;
- }
- fchs->reserved = ls_reject_code; // borrow this (unused) field
- cpqfcTSPutLinkQue( cpqfcHBAdata, ELS_RJT, fchs );
- }
-
- break;
-
-
-
- case 0x0003: // PLOGI?
-
- // Payload for PLOGI and PDISC is identical (request & reply)
- if( !verify_PLOGI( fcChip, fchs, &ls_reject_code) ) // valid payload?
- {
- LOGIN_PAYLOAD logi; // FC-PH Port Login
- BOOLEAN NeedReject = FALSE;
-
- // PDISC payload OK. If critical login fields
- // (e.g. WWN) matches last login for this port_id,
- // we may resume any prior exchanges
- // with the other port
-
-
- BigEndianSwap( (UCHAR*)&fchs->pl[0], (UCHAR*)&logi, sizeof(logi));
-
- pLoggedInPort = fcFindLoggedInPort(
- fcChip,
- NULL, // don't search Scsi Nexus
- 0, // don't search linked list for port_id
- &logi.port_name[0], // search linked list for WWN
- &pLastLoggedInPort); // must return non-NULL; when a port_id
- // is not found, this pointer marks the
- // end of the singly linked list
-
- if( pLoggedInPort == NULL) // WWN not found -New Port
- {
- pLoggedInPort = CreateFcPort(
- cpqfcHBAdata,
- pLastLoggedInPort,
- fchs,
- &logi);
- if( pLoggedInPort == NULL )
- {
- printk(" cpqfcTS: New port allocation failed - lost FC device!\n");
- // Now Q a LOGOut Request, since we won't be talking to that device
-
- NeedReject = TRUE;
-
- // set reject reason code
- ls_reject_code =
- LS_RJT_REASON( LOGICAL_ERROR, NO_LOGIN_RESOURCES);
-
- }
- }
- if( !NeedReject )
- {
-
- // OK - we have valid fcPort ptr; set fields accordingly.
- // (not PDISC, not Originator)
- SetLoginFields( pLoggedInPort, fchs, FALSE, FALSE);
-
- // send 'ACC' reply
- cpqfcTSPutLinkQue( cpqfcHBAdata,
- ELS_PLOGI_ACC, // (PDISC same as PLOGI ACC)
- fchs );
- }
- }
- else // Payload unacceptable
- {
- printk("payload unacceptable\n");
- NeedReject = TRUE; // reject code already set
- }
-
- if( NeedReject)
- {
- // The PDISC failed. Set login struct flags accordingly,
- // terminate any I/O to this port, and Q a PLOGI
- pLoggedInPort->pdisc = FALSE;
- pLoggedInPort->prli = FALSE;
- pLoggedInPort->plogi = FALSE;
-
- fchs->reserved = ls_reject_code; // borrow this (unused) field
-
- // send 'RJT' reply
- cpqfcTSPutLinkQue( cpqfcHBAdata, ELS_RJT, fchs );
- }
-
- // terminate any exchanges with this device...
- if( pLoggedInPort )
- {
- cpqfcTSTerminateExchange( cpqfcHBAdata,
- &pLoggedInPort->ScsiNexus, PORTID_CHANGED);
- }
- break;
-
-
-
- case 0x1020: // PRLI?
- {
- BOOLEAN NeedReject = TRUE;
- pLoggedInPort = fcFindLoggedInPort(
- fcChip,
- NULL, // don't search Scsi Nexus
- (fchs->s_id & 0xFFFFFF), // search linked list for port_id
- NULL, // DON'T search linked list for WWN
- NULL); // don't care
-
- if( pLoggedInPort == NULL )
- {
- // huh?
- printk(" Unexpected PRLI Request -not logged in!\n");
-
- // set reject reason code
- ls_reject_code = LS_RJT_REASON( PROTOCOL_ERROR, INITIATOR_CTL_ERROR);
-
- // Q a LOGOut here?
- }
- else
- {
- // verify the PRLI ACC payload
- if( !verify_PRLI( fchs, &ls_reject_code) )
- {
- // PRLI Reply is acceptable; were we expecting it?
- if( pLoggedInPort->plogi )
- {
- // yes, we expected the PRLI ACC (not PDISC; not Originator)
- SetLoginFields( pLoggedInPort, fchs, FALSE, FALSE);
-
- // Q an ACCept Reply
- cpqfcTSPutLinkQue( cpqfcHBAdata,
- ELS_PRLI_ACC,
- fchs );
-
- NeedReject = FALSE;
- }
- else
- {
- // huh?
- printk(" (unexpected) PRLI REQEST with plogi FALSE\n");
-
- // set reject reason code
- ls_reject_code = LS_RJT_REASON( PROTOCOL_ERROR, INITIATOR_CTL_ERROR);
-
- // Q a LOGOut here?
-
- }
- }
- else
- {
- printk(" PRLI REQUEST payload failed verify\n");
- // (reject code set by "verify")
-
- // Q a LOGOut here?
- }
- }
-
- if( NeedReject )
- {
- // Q a ReJecT Reply with reason code
- fchs->reserved = ls_reject_code;
- cpqfcTSPutLinkQue( cpqfcHBAdata,
- ELS_RJT, // Q Type
- fchs );
- }
- }
- break;
-
-
-
-
- case 0x0005: // LOGOut?
- {
- // was this LOGOUT because we sent a ELS_PDISC to an FC device
- // with changed (or new) port_id, or does the port refuse
- // to communicate to us?
- // We maintain a logout counter - if we get 3 consecutive LOGOuts,
- // give up!
- LOGOUT_PAYLOAD logo;
- BOOLEAN GiveUpOnDevice = FALSE;
- ULONG ls_reject_code = 0;
-
- BigEndianSwap( (UCHAR*)&fchs->pl[0], (UCHAR*)&logo, sizeof(logo));
-
- pLoggedInPort = fcFindLoggedInPort(
- fcChip,
- NULL, // don't search Scsi Nexus
- 0, // don't search linked list for port_id
- &logo.port_name[0], // search linked list for WWN
- NULL); // don't care about end of list
-
- if( pLoggedInPort ) // found the device?
- {
- // Q an ACC reply
- cpqfcTSPutLinkQue( cpqfcHBAdata,
- ELS_LOGO_ACC, // Q Type
- fchs ); // device to respond to
-
- // set login struct fields (LOGO_counter increment)
- SetLoginFields( pLoggedInPort, fchs, FALSE, FALSE);
-
- // are we an Initiator?
- if( fcChip->Options.initiator)
- {
- // we're an Initiator, so check if we should
- // try (another?) login
-
- // Fabrics routinely log out from us after
- // getting device info - don't try to log them
- // back in.
- if( (fchs->s_id & 0xFFF000) == 0xFFF000 )
- {
- ; // do nothing
- }
- else if( pLoggedInPort->LOGO_counter <= 3)
- {
- // try (another) login (PLOGI request)
-
- cpqfcTSPutLinkQue( cpqfcHBAdata,
- ELS_PLOGI, // Q Type
- fchs );
-
- // Terminate I/O with "retry" potential
- cpqfcTSTerminateExchange( cpqfcHBAdata,
- &pLoggedInPort->ScsiNexus,
- PORTID_CHANGED);
- }
- else
- {
- printk(" Got 3 LOGOuts - terminating comm. with port_id %Xh\n",
- fchs->s_id &&0xFFFFFF);
- GiveUpOnDevice = TRUE;
- }
- }
- else
- {
- GiveUpOnDevice = TRUE;
- }
-
-
- if( GiveUpOnDevice == TRUE )
- {
- cpqfcTSTerminateExchange( cpqfcHBAdata,
- &pLoggedInPort->ScsiNexus,
- DEVICE_REMOVED);
- }
- }
- else // we don't know this WWN!
- {
- // Q a ReJecT Reply with reason code
- fchs->reserved = ls_reject_code;
- cpqfcTSPutLinkQue( cpqfcHBAdata,
- ELS_RJT, // Q Type
- fchs );
- }
- }
- break;
-
-
-
-
- // FABRIC only case
- case 0x0461: // ELS RSCN (Registered State Change Notification)?
- {
- int Ports;
- int i;
- __u32 Buff;
- // Typically, one or more devices have been added to or dropped
- // from the Fabric.
- // The format of this frame is defined in FC-FLA (Rev 2.7, Aug 1997)
- // The first 32-bit word has a 2-byte Payload Length, which
- // includes the 4 bytes of the first word. Consequently,
- // this PL len must never be less than 4, must be a multiple of 4,
- // and has a specified max value 256.
- // (Endianess!)
- Ports = ((fchs->pl[0] >>24) - 4) / 4;
- Ports = Ports > 63 ? 63 : Ports;
-
- printk(" RSCN ports: %d\n", Ports);
- if( Ports <= 0 ) // huh?
- {
- // ReJecT the command
- fchs->reserved = LS_RJT_REASON( UNABLE_TO_PERFORM, 0);
-
- cpqfcTSPutLinkQue( cpqfcHBAdata,
- ELS_RJT, // Q Type
- fchs );
-
- break;
- }
- else // Accept the command
- {
- cpqfcTSPutLinkQue( cpqfcHBAdata,
- ELS_ACC, // Q Type
- fchs );
- }
-
- // Check the "address format" to determine action.
- // We have 3 cases:
- // 0 = Port Address; 24-bit address of affected device
- // 1 = Area Address; MS 16 bits valid
- // 2 = Domain Address; MS 8 bits valid
- for( i=0; i<Ports; i++)
- {
- BigEndianSwap( (UCHAR*)&fchs->pl[i+1],(UCHAR*)&Buff, 4);
- switch( Buff & 0xFF000000)
- {
-
- case 0: // Port Address?
-
- case 0x01000000: // Area Domain?
- case 0x02000000: // Domain Address
- // For example, "port_id" 0x201300
- // OK, let's try a Name Service Request (Query)
- fchs->s_id = 0xFFFFFC; // Name Server Address
- cpqfcTSPutLinkQue( cpqfcHBAdata, FCS_NSR, fchs);
-
- break;
-
-
- default: // huh? new value on version change?
- break;
- }
- }
- }
- break;
-
-
-
-
- default: // don't support this request (yet)
- // set reject reason code
- fchs->reserved = LS_RJT_REASON( UNABLE_TO_PERFORM,
- REQUEST_NOT_SUPPORTED);
-
- cpqfcTSPutLinkQue( cpqfcHBAdata,
- ELS_RJT, // Q Type
- fchs );
- break;
- }
-}
-
-
-static void ProcessELS_Reply(
- CPQFCHBA* cpqfcHBAdata, TachFCHDR_GCMND* fchs)
-{
- PTACHYON fcChip = &cpqfcHBAdata->fcChip;
- FC_EXCHANGES *Exchanges = fcChip->Exchanges;
- ULONG ox_id = (fchs->ox_rx_id >>16);
- ULONG ls_reject_code;
- PFC_LOGGEDIN_PORT pLoggedInPort, pLastLoggedInPort;
-
- // If this is a valid reply, then we MUST have sent a request.
- // Verify that we can find a valid request OX_ID corresponding to
- // this reply
-
-
- if( Exchanges->fcExchange[(fchs->ox_rx_id >>16)].type == 0)
- {
- printk(" *Discarding ACC/RJT frame, xID %04X/%04X* ",
- ox_id, fchs->ox_rx_id & 0xffff);
- goto Quit; // exit this routine
- }
-
-
- // Is the reply a RJT (reject)?
- if( (fchs->pl[0] & 0xFFFFL) == 0x01) // Reject reply?
- {
-// ****** REJECT REPLY ********
- switch( Exchanges->fcExchange[ox_id].type )
- {
-
- case ELS_FDISC: // we sent out Fabric Discovery
- case ELS_FLOGI: // we sent out FLOGI
-
- printk("RJT received on Fabric Login from %Xh, reason %Xh\n",
- fchs->s_id, fchs->pl[1]);
-
- break;
-
- default:
- break;
- }
-
- goto Done;
- }
-
- // OK, we have an ACCept...
- // What's the ACC type? (according to what we sent)
- switch( Exchanges->fcExchange[ox_id].type )
- {
-
- case ELS_PLOGI: // we sent out PLOGI
- if( !verify_PLOGI( fcChip, fchs, &ls_reject_code) )
- {
- LOGIN_PAYLOAD logi; // FC-PH Port Login
-
- // login ACC payload acceptable; search for WWN in our list
- // of fcPorts
-
- BigEndianSwap( (UCHAR*)&fchs->pl[0], (UCHAR*)&logi, sizeof(logi));
-
- pLoggedInPort = fcFindLoggedInPort(
- fcChip,
- NULL, // don't search Scsi Nexus
- 0, // don't search linked list for port_id
- &logi.port_name[0], // search linked list for WWN
- &pLastLoggedInPort); // must return non-NULL; when a port_id
- // is not found, this pointer marks the
- // end of the singly linked list
-
- if( pLoggedInPort == NULL) // WWN not found - new port
- {
-
- pLoggedInPort = CreateFcPort(
- cpqfcHBAdata,
- pLastLoggedInPort,
- fchs,
- &logi);
-
- if( pLoggedInPort == NULL )
- {
- printk(" cpqfcTS: New port allocation failed - lost FC device!\n");
- // Now Q a LOGOut Request, since we won't be talking to that device
-
- goto Done; // exit with error! dropped login frame
- }
- }
- else // WWN was already known. Ensure that any open
- // exchanges for this WWN are terminated.
- // NOTE: It's possible that a device can change its
- // 24-bit port_id after a Link init or Fabric change
- // (e.g. LIP or Fabric RSCN). In that case, the old
- // 24-bit port_id may be duplicated, or no longer exist.
- {
-
- cpqfcTSTerminateExchange( cpqfcHBAdata,
- &pLoggedInPort->ScsiNexus, PORTID_CHANGED);
- }
-
- // We have an fcPort struct - set fields accordingly
- // not PDISC, originator
- SetLoginFields( pLoggedInPort, fchs, FALSE, TRUE);
-
- // We just set a "port_id"; is it duplicated?
- TestDuplicatePortId( cpqfcHBAdata, pLoggedInPort);
-
- // For Fabric operation, we issued PLOGI to 0xFFFFFC
- // so we can send SCR (State Change Registration)
- // Check for this special case...
- if( fchs->s_id == 0xFFFFFC )
- {
- // PLOGI ACC was a Fabric response... issue SCR
- fchs->s_id = 0xFFFFFD; // address for SCR
- cpqfcTSPutLinkQue( cpqfcHBAdata, ELS_SCR, fchs);
- }
-
- else
- {
- // Now we need a PRLI to enable FCP-SCSI operation
- // set flags and Q up a ELS_PRLI
- cpqfcTSPutLinkQue( cpqfcHBAdata, ELS_PRLI, fchs);
- }
- }
- else
- {
- // login payload unacceptable - reason in ls_reject_code
- // Q up a Logout Request
- printk("Login Payload unacceptable\n");
-
- }
- break;
-
-
- // PDISC logic very similar to PLOGI, except we never want
- // to allocate mem for "new" port, and we set flags differently
- // (might combine later with PLOGI logic for efficiency)
- case ELS_PDISC: // we sent out PDISC
- if( !verify_PLOGI( fcChip, fchs, &ls_reject_code) )
- {
- LOGIN_PAYLOAD logi; // FC-PH Port Login
- BOOLEAN NeedLogin = FALSE;
-
- // login payload acceptable; search for WWN in our list
- // of (previously seen) fcPorts
-
- BigEndianSwap( (UCHAR*)&fchs->pl[0], (UCHAR*)&logi, sizeof(logi));
-
- pLoggedInPort = fcFindLoggedInPort(
- fcChip,
- NULL, // don't search Scsi Nexus
- 0, // don't search linked list for port_id
- &logi.port_name[0], // search linked list for WWN
- &pLastLoggedInPort); // must return non-NULL; when a port_id
- // is not found, this pointer marks the
- // end of the singly linked list
-
- if( pLoggedInPort != NULL) // WWN found?
- {
- // WWN has same port_id as last login? (Of course, a properly
- // working FC device should NEVER ACCept a PDISC if it's
- // port_id changed, but check just in case...)
- if( (fchs->s_id & 0xFFFFFF) == pLoggedInPort->port_id)
- {
- // Yes. We were expecting PDISC?
- if( pLoggedInPort->pdisc )
- {
- int i;
-
-
- // PDISC expected -- set fields. (PDISC, Originator)
- SetLoginFields( pLoggedInPort, fchs, TRUE, TRUE);
-
- // We are ready to resume FCP-SCSI to this device...
- // Do we need to start anything that was Queued?
-
- for( i=0; i< TACH_SEST_LEN; i++)
- {
- // see if any exchange for this PDISC'd port was queued
- if( ((fchs->s_id &0xFFFFFF) ==
- (Exchanges->fcExchange[i].fchs.d_id & 0xFFFFFF))
- &&
- (Exchanges->fcExchange[i].status & EXCHANGE_QUEUED))
- {
- fchs->reserved = i; // copy ExchangeID
-// printk(" *Q x_ID %Xh after PDISC* ",i);
-
- cpqfcTSPutLinkQue( cpqfcHBAdata, EXCHANGE_QUEUED, fchs );
- }
- }
-
- // Complete commands Q'd while we were waiting for Login
-
- UnblockScsiDevice( cpqfcHBAdata->HostAdapter, pLoggedInPort);
- }
- else
- {
- printk("Not expecting PDISC (pdisc=FALSE)\n");
- NeedLogin = TRUE;
- }
- }
- else
- {
- printk("PDISC PortID change: old %Xh, new %Xh\n",
- pLoggedInPort->port_id, fchs->s_id &0xFFFFFF);
- NeedLogin = TRUE;
-
- }
- }
- else
- {
- printk("PDISC ACC from unknown WWN\n");
- NeedLogin = TRUE;
- }
-
- if( NeedLogin)
- {
-
- // The PDISC failed. Set login struct flags accordingly,
- // terminate any I/O to this port, and Q a PLOGI
- if( pLoggedInPort ) // FC device previously known?
- {
-
- cpqfcTSPutLinkQue( cpqfcHBAdata,
- ELS_LOGO, // Q Type
- fchs ); // has port_id to send to
-
- // There are a variety of error scenarios which can result
- // in PDISC failure, so as a catchall, add the check for
- // duplicate port_id.
- TestDuplicatePortId( cpqfcHBAdata, pLoggedInPort);
-
-// TriggerHBA( fcChip->Registers.ReMapMemBase, 0);
- pLoggedInPort->pdisc = FALSE;
- pLoggedInPort->prli = FALSE;
- pLoggedInPort->plogi = FALSE;
-
- cpqfcTSTerminateExchange( cpqfcHBAdata,
- &pLoggedInPort->ScsiNexus, PORTID_CHANGED);
- }
- cpqfcTSPutLinkQue( cpqfcHBAdata, ELS_PLOGI, fchs );
- }
- }
- else
- {
- // login payload unacceptable - reason in ls_reject_code
- // Q up a Logout Request
- printk("ERROR: Login Payload unacceptable!\n");
-
- }
-
- break;
-
-
-
- case ELS_PRLI: // we sent out PRLI
-
-
- pLoggedInPort = fcFindLoggedInPort(
- fcChip,
- NULL, // don't search Scsi Nexus
- (fchs->s_id & 0xFFFFFF), // search linked list for port_id
- NULL, // DON'T search linked list for WWN
- NULL); // don't care
-
- if( pLoggedInPort == NULL )
- {
- // huh?
- printk(" Unexpected PRLI ACCept frame!\n");
-
- // Q a LOGOut here?
-
- goto Done;
- }
-
- // verify the PRLI ACC payload
- if( !verify_PRLI( fchs, &ls_reject_code) )
- {
- // PRLI Reply is acceptable; were we expecting it?
- if( pLoggedInPort->plogi )
- {
- // yes, we expected the PRLI ACC (not PDISC; Originator)
- SetLoginFields( pLoggedInPort, fchs, FALSE, TRUE);
-
- // OK, let's send a REPORT_LUNS command to determine
- // whether VSA or PDA FCP-LUN addressing is used.
-
- cpqfcTSPutLinkQue( cpqfcHBAdata, SCSI_REPORT_LUNS, fchs );
-
- // It's possible that a device we were talking to changed
- // port_id, and has logged back in. This function ensures
- // that I/O will resume.
- UnblockScsiDevice( cpqfcHBAdata->HostAdapter, pLoggedInPort);
-
- }
- else
- {
- // huh?
- printk(" (unexpected) PRLI ACCept with plogi FALSE\n");
-
- // Q a LOGOut here?
- goto Done;
- }
- }
- else
- {
- printk(" PRLI ACCept payload failed verify\n");
-
- // Q a LOGOut here?
- }
-
- break;
-
- case ELS_FLOGI: // we sent out FLOGI (Fabric Login)
-
- // update the upper 16 bits of our port_id in Tachyon
- // the switch adds those upper 16 bits when responding
- // to us (i.e. we are the destination_id)
- fcChip->Registers.my_al_pa = (fchs->d_id & 0xFFFFFF);
- writel( fcChip->Registers.my_al_pa,
- fcChip->Registers.ReMapMemBase + TL_MEM_TACH_My_ID);
-
- // now send out a PLOGI to the well known port_id 0xFFFFFC
- fchs->s_id = 0xFFFFFC;
- cpqfcTSPutLinkQue( cpqfcHBAdata, ELS_PLOGI, fchs);
-
- break;
-
-
- case ELS_FDISC: // we sent out FDISC (Fabric Discovery (Login))
-
- printk( " ELS_FDISC success ");
- break;
-
-
- case ELS_SCR: // we sent out State Change Registration
- // now we can issue Name Service Request to find any
- // Fabric-connected devices we might want to login to.
-
-
- fchs->s_id = 0xFFFFFC; // Name Server Address
- cpqfcTSPutLinkQue( cpqfcHBAdata, FCS_NSR, fchs);
-
-
- break;
-
-
- default:
- printk(" *Discarding unknown ACC frame, xID %04X/%04X* ",
- ox_id, fchs->ox_rx_id & 0xffff);
- break;
- }
-
-
-Done:
- // Regardless of whether the Reply is valid or not, the
- // the exchange is done - complete
- cpqfcTSCompleteExchange(cpqfcHBAdata->PciDev, fcChip, (fchs->ox_rx_id >>16));
-
-Quit:
- return;
-}
-
-
-
-
-
-
-// **************** Fibre Channel Services **************
-// This is where we process the Directory (Name) Service Reply
-// to know which devices are on the Fabric
-
-static void ProcessFCS_Reply(
- CPQFCHBA* cpqfcHBAdata, TachFCHDR_GCMND* fchs)
-{
- PTACHYON fcChip = &cpqfcHBAdata->fcChip;
- FC_EXCHANGES *Exchanges = fcChip->Exchanges;
- ULONG ox_id = (fchs->ox_rx_id >>16);
-// ULONG ls_reject_code;
-// PFC_LOGGEDIN_PORT pLoggedInPort, pLastLoggedInPort;
-
- // If this is a valid reply, then we MUST have sent a request.
- // Verify that we can find a valid request OX_ID corresponding to
- // this reply
-
- if( Exchanges->fcExchange[(fchs->ox_rx_id >>16)].type == 0)
- {
- printk(" *Discarding Reply frame, xID %04X/%04X* ",
- ox_id, fchs->ox_rx_id & 0xffff);
- goto Quit; // exit this routine
- }
-
-
- // OK, we were expecting it. Now check to see if it's a
- // "Name Service" Reply, and if so force a re-validation of
- // Fabric device logins (i.e. Start the login timeout and
- // send PDISC or PLOGI)
- // (Endianess Byte Swap?)
- if( fchs->pl[1] == 0x02FC ) // Name Service
- {
- // got a new (or NULL) list of Fabric attach devices...
- // Invalidate current logins
-
- PFC_LOGGEDIN_PORT pLoggedInPort = &fcChip->fcPorts;
- while( pLoggedInPort ) // for all ports which are expecting
- // PDISC after the next LIP, set the
- // logoutTimer
- {
-
- if( (pLoggedInPort->port_id & 0xFFFF00) // Fabric device?
- &&
- (pLoggedInPort->port_id != 0xFFFFFC) ) // NOT the F_Port
- {
- pLoggedInPort->LOGO_timer = 6; // what's the Fabric timeout??
- // suspend any I/O in progress until
- // PDISC received...
- pLoggedInPort->prli = FALSE; // block FCP-SCSI commands
- }
-
- pLoggedInPort = pLoggedInPort->pNextPort;
- }
-
- if( fchs->pl[2] == 0x0280) // ACCept?
- {
- // Send PLOGI or PDISC to these Fabric devices
- SendLogins( cpqfcHBAdata, &fchs->pl[4] );
- }
-
-
- // As of this writing, the only reason to reject is because NO
- // devices are left on the Fabric. We already started
- // "logged out" timers; if the device(s) don't come
- // back, we'll do the implicit logout in the heart beat
- // timer routine
- else // ReJecT
- {
- // this just means no Fabric device is visible at this instant
- }
- }
-
- // Regardless of whether the Reply is valid or not, the
- // the exchange is done - complete
- cpqfcTSCompleteExchange(cpqfcHBAdata->PciDev, fcChip, (fchs->ox_rx_id >>16));
-
-Quit:
- return;
-}
-
-
-
-
-
-
-
-static void AnalyzeIncomingFrame(
- CPQFCHBA *cpqfcHBAdata,
- ULONG QNdx )
-{
- PTACHYON fcChip = &cpqfcHBAdata->fcChip;
- FC_EXCHANGES *Exchanges = fcChip->Exchanges;
- PFC_LINK_QUE fcLQ = cpqfcHBAdata->fcLQ;
- TachFCHDR_GCMND* fchs =
- (TachFCHDR_GCMND*)fcLQ->Qitem[QNdx].ulBuff;
-// ULONG ls_reject_code; // reason for rejecting login
- LONG ExchangeID;
-// FC_LOGGEDIN_PORT *pLoggedInPort;
- BOOLEAN AbortAccept;
-
- ENTER("AnalyzeIncomingFrame");
-
-
-
- switch( fcLQ->Qitem[QNdx].Type) // FCP or Unknown
- {
-
- case SFQ_UNKNOWN: // unknown frame (e.g. LIP position frame, NOP, etc.)
-
-
- // ********* FC-4 Device Data/ Fibre Channel Service *************
- if( ((fchs->d_id &0xF0000000) == 0) // R_CTL (upper nibble) 0x0?
- &&
- (fchs->f_ctl & 0x20000000) ) // TYPE 20h is Fibre Channel Service
- {
-
- // ************** FCS Reply **********************
-
- if( (fchs->d_id & 0xff000000L) == 0x03000000L) // (31:23 R_CTL)
- {
- ProcessFCS_Reply( cpqfcHBAdata, fchs );
-
- } // end of FCS logic
-
- }
-
-
- // *********** Extended Link Service **************
-
- else if( fchs->d_id & 0x20000000 // R_CTL 0x2?
- &&
- (fchs->f_ctl & 0x01000000) ) // TYPE = 1
- {
-
- // these frames are either a response to
- // something we sent (0x23) or "unsolicited"
- // frames (0x22).
-
-
- // **************Extended Link REPLY **********************
- // R_CTL Solicited Control Reply
-
- if( (fchs->d_id & 0xff000000L) == 0x23000000L) // (31:23 R_CTL)
- {
-
- ProcessELS_Reply( cpqfcHBAdata, fchs );
-
- } // end of "R_CTL Solicited Control Reply"
-
-
-
-
- // **************Extended Link REQUEST **********************
- // (unsolicited commands from another port or task...)
-
- // R_CTL Ext Link REQUEST
- else if( (fchs->d_id & 0xff000000L) == 0x22000000L &&
- (fchs->ox_rx_id != 0xFFFFFFFFL) ) // (ignore LIP frame)
- {
-
-
-
- ProcessELS_Request( cpqfcHBAdata, fchs );
-
- }
-
-
-
- // ************** LILP **********************
- else if( (fchs->d_id & 0xff000000L) == 0x22000000L &&
- (fchs->ox_rx_id == 0xFFFFFFFFL)) // (e.g., LIP frames)
-
- {
- // SANMark specifies that when available, we must use
- // the LILP frame to determine which ALPAs to send Port Discovery
- // to...
-
- if( fchs->pl[0] == 0x0711L) // ELS_PLOGI?
- {
-// UCHAR *ptr = (UCHAR*)&fchs->pl[1];
-// printk(" %d ALPAs found\n", *ptr);
- memcpy( fcChip->LILPmap, &fchs->pl[1], 32*4); // 32 DWORDs
- fcChip->Options.LILPin = 1; // our LILPmap is valid!
- // now post to make Port Discovery happen...
- cpqfcTSPutLinkQue( cpqfcHBAdata, LINKACTIVE, fchs);
- }
- }
- }
-
-
- // ***************** BASIC LINK SERVICE *****************
-
- else if( fchs->d_id & 0x80000000 // R_CTL:
- && // Basic Link Service Request
- !(fchs->f_ctl & 0xFF000000) ) // type=0 for BLS
- {
-
- // Check for ABTS (Abort Sequence)
- if( (fchs->d_id & 0x8F000000) == 0x81000000)
- {
- // look for OX_ID, S_ID pair that matches in our
- // fcExchanges table; if found, reply with ACCept and complete
- // the exchange
-
- // Per PLDA, an ABTS is sent by an initiator; therefore
- // assume that if we have an exhange open to the port who
- // sent ABTS, it will be the d_id of what we sent.
- for( ExchangeID = 0, AbortAccept=FALSE;
- ExchangeID < TACH_SEST_LEN; ExchangeID++)
- {
- // Valid "target" exchange 24-bit port_id matches?
- // NOTE: For the case of handling Intiator AND Target
- // functions on the same chip, we can have TWO Exchanges
- // with the same OX_ID -- OX_ID/FFFF for the CMND, and
- // OX_ID/RX_ID for the XRDY or DATA frame(s). Ideally,
- // we would like to support ABTS from Initiators or Targets,
- // but it's not clear that can be supported on Tachyon for
- // all cases (requires more investigation).
-
- if( (Exchanges->fcExchange[ ExchangeID].type == SCSI_TWE ||
- Exchanges->fcExchange[ ExchangeID].type == SCSI_TRE)
- &&
- ((Exchanges->fcExchange[ ExchangeID].fchs.d_id & 0xFFFFFF) ==
- (fchs->s_id & 0xFFFFFF)) )
- {
-
- // target xchnge port_id matches -- how about OX_ID?
- if( (Exchanges->fcExchange[ ExchangeID].fchs.ox_rx_id &0xFFFF0000)
- == (fchs->ox_rx_id & 0xFFFF0000) )
- // yes! post ACCept response; will be completed by fcStart
- {
- Exchanges->fcExchange[ ExchangeID].status = TARGET_ABORT;
-
- // copy (add) rx_id field for simplified ACCept reply
- fchs->ox_rx_id =
- Exchanges->fcExchange[ ExchangeID].fchs.ox_rx_id;
-
- cpqfcTSPutLinkQue( cpqfcHBAdata,
- BLS_ABTS_ACC, // Q Type
- fchs ); // void QueContent
- AbortAccept = TRUE;
- printk("ACCepting ABTS for x_ID %8.8Xh, SEST pair %8.8Xh\n",
- fchs->ox_rx_id, Exchanges->fcExchange[ ExchangeID].fchs.ox_rx_id);
- break; // ABTS can affect only ONE exchange -exit loop
- }
- }
- } // end of FOR loop
- if( !AbortAccept ) // can't ACCept ABTS - send Reject
- {
- printk("ReJecTing: can't find ExchangeID %8.8Xh for ABTS command\n",
- fchs->ox_rx_id);
- if( Exchanges->fcExchange[ ExchangeID].type
- &&
- !(fcChip->SEST->u[ ExchangeID].IWE.Hdr_Len
- & 0x80000000))
- {
- cpqfcTSCompleteExchange( cpqfcHBAdata->PciDev, fcChip, ExchangeID);
- }
- else
- {
- printk("Unexpected ABTS ReJecT! SEST[%X] Dword 0: %Xh\n",
- ExchangeID, fcChip->SEST->u[ ExchangeID].IWE.Hdr_Len);
- }
- }
- }
-
- // Check for BLS {ABTS? (Abort Sequence)} ACCept
- else if( (fchs->d_id & 0x8F000000) == 0x84000000)
- {
- // target has responded with ACC for our ABTS;
- // complete the indicated exchange with ABORTED status
- // Make no checks for correct RX_ID, since
- // all we need to conform ABTS ACC is the OX_ID.
- // Verify that the d_id matches!
-
- ExchangeID = (fchs->ox_rx_id >> 16) & 0x7FFF; // x_id from ACC
-// printk("ABTS ACC x_ID 0x%04X 0x%04X, status %Xh\n",
-// fchs->ox_rx_id >> 16, fchs->ox_rx_id & 0xffff,
-// Exchanges->fcExchange[ExchangeID].status);
-
-
-
- if( ExchangeID < TACH_SEST_LEN ) // x_ID makes sense
- {
- // Does "target" exchange 24-bit port_id match?
- // (See "NOTE" above for handling Intiator AND Target in
- // the same device driver)
- // First, if this is a target response, then we originated
- // (initiated) it with BLS_ABTS:
-
- if( (Exchanges->fcExchange[ ExchangeID].type == BLS_ABTS)
-
- &&
- // Second, does the source of this ACC match the destination
- // of who we originally sent it to?
- ((Exchanges->fcExchange[ ExchangeID].fchs.d_id & 0xFFFFFF) ==
- (fchs->s_id & 0xFFFFFF)) )
- {
- cpqfcTSCompleteExchange( cpqfcHBAdata->PciDev, fcChip, ExchangeID );
- }
- }
- }
- // Check for BLS {ABTS? (Abort Sequence)} ReJecT
- else if( (fchs->d_id & 0x8F000000) == 0x85000000)
- {
- // target has responded with RJT for our ABTS;
- // complete the indicated exchange with ABORTED status
- // Make no checks for correct RX_ID, since
- // all we need to conform ABTS ACC is the OX_ID.
- // Verify that the d_id matches!
-
- ExchangeID = (fchs->ox_rx_id >> 16) & 0x7FFF; // x_id from ACC
-// printk("BLS_ABTS RJT on Exchange 0x%04X 0x%04X\n",
-// fchs->ox_rx_id >> 16, fchs->ox_rx_id & 0xffff);
-
- if( ExchangeID < TACH_SEST_LEN ) // x_ID makes sense
- {
- // Does "target" exchange 24-bit port_id match?
- // (See "NOTE" above for handling Intiator AND Target in
- // the same device driver)
- // First, if this is a target response, then we originated
- // (initiated) it with BLS_ABTS:
-
- if( (Exchanges->fcExchange[ ExchangeID].type == BLS_ABTS)
-
- &&
- // Second, does the source of this ACC match the destination
- // of who we originally sent it to?
- ((Exchanges->fcExchange[ ExchangeID].fchs.d_id & 0xFFFFFF) ==
- (fchs->s_id & 0xFFFFFF)) )
- {
- // YES! NOTE: There is a bug in CPQ's RA-4000 box
- // where the "reason code" isn't returned in the payload
- // For now, simply presume the reject is because the target
- // already completed the exchange...
-
-// printk("complete x_ID %Xh on ABTS RJT\n", ExchangeID);
- cpqfcTSCompleteExchange( cpqfcHBAdata->PciDev, fcChip, ExchangeID );
- }
- }
- } // end of ABTS check
- } // end of Basic Link Service Request
- break;
-
- default:
- printk("AnalyzeIncomingFrame: unknown type: %Xh(%d)\n",
- fcLQ->Qitem[QNdx].Type,
- fcLQ->Qitem[QNdx].Type);
- break;
- }
-}
-
-
-// Function for Port Discovery necessary after every FC
-// initialization (e.g. LIP).
-// Also may be called if from Fabric Name Service logic.
-
-static void SendLogins( CPQFCHBA *cpqfcHBAdata, __u32 *FabricPortIds )
-{
- PTACHYON fcChip = &cpqfcHBAdata->fcChip;
- FC_EXCHANGES *Exchanges = fcChip->Exchanges;
- ULONG ulStatus=0;
- TachFCHDR_GCMND fchs; // copy fields for transmission
- int i;
- ULONG loginType;
- LONG ExchangeID;
- PFC_LOGGEDIN_PORT pLoggedInPort;
- __u32 PortIds[ number_of_al_pa];
- int NumberOfPorts=0;
-
- // We're going to presume (for now) that our limit of Fabric devices
- // is the same as the number of alpa on a private loop (126 devices).
- // (Of course this could be changed to support however many we have
- // memory for).
- memset( &PortIds[0], 0, sizeof(PortIds));
-
- // First, check if this login is for our own Link Initialization
- // (e.g. LIP on FC-AL), or if we have knowledge of Fabric devices
- // from a switch. If we are logging into Fabric devices, we'll
- // have a non-NULL FabricPortId pointer
-
- if( FabricPortIds != NULL) // may need logins
- {
- int LastPort=FALSE;
- i = 0;
- while( !LastPort)
- {
- // port IDs From NSR payload; byte swap needed?
- BigEndianSwap( (UCHAR*)FabricPortIds, (UCHAR*)&PortIds[i], 4);
-
-// printk("FPortId[%d] %Xh ", i, PortIds[i]);
- if( PortIds[i] & 0x80000000)
- LastPort = TRUE;
-
- PortIds[i] &= 0xFFFFFF; // get 24-bit port_id
- // some non-Fabric devices (like the Crossroads Fibre/Scsi bridge)
- // erroneously use ALPA 0.
- if( PortIds[i] ) // need non-zero port_id...
- i++;
-
- if( i >= number_of_al_pa ) // (in)sanity check
- break;
- FabricPortIds++; // next...
- }
-
- NumberOfPorts = i;
-// printk("NumberOf Fabric ports %d", NumberOfPorts);
- }
-
- else // need to send logins on our "local" link
- {
-
- // are we a loop port? If so, check for reception of LILP frame,
- // and if received use it (SANMark requirement)
- if( fcChip->Options.LILPin )
- {
- int j=0;
- // sanity check on number of ALPAs from LILP frame...
- // For format of LILP frame, see FC-AL specs or
- // "Fibre Channel Bench Reference", J. Stai, 1995 (ISBN 1-879936-17-8)
- // First byte is number of ALPAs
- i = fcChip->LILPmap[0] >= (32*4) ? 32*4 : fcChip->LILPmap[0];
- NumberOfPorts = i;
-// printk(" LILP alpa count %d ", i);
- while( i > 0)
- {
- PortIds[j] = fcChip->LILPmap[1+ j];
- j++; i--;
- }
- }
- else // have to send login to everybody
- {
- int j=0;
- i = number_of_al_pa;
- NumberOfPorts = i;
- while( i > 0)
- {
- PortIds[j] = valid_al_pa[j]; // all legal ALPAs
- j++; i--;
- }
- }
- }
-
-
- // Now we have a copy of the port_ids (and how many)...
- for( i = 0; i < NumberOfPorts; i++)
- {
- // 24-bit FC Port ID
- fchs.s_id = PortIds[i]; // note: only 8-bits used for ALPA
-
-
- // don't log into ourselves (Linux Scsi disk scan will stop on
- // no TARGET support error on us, and quit trying for rest of devices)
- if( (fchs.s_id & 0xFF ) == (fcChip->Registers.my_al_pa & 0xFF) )
- continue;
-
- // fabric login needed?
- if( (fchs.s_id == 0) ||
- (fcChip->Options.fabric == 1) )
- {
- fcChip->Options.flogi = 1; // fabric needs longer for login
- // Do we need FLOGI or FDISC?
- pLoggedInPort = fcFindLoggedInPort(
- fcChip,
- NULL, // don't search SCSI Nexus
- 0xFFFFFC, // search linked list for Fabric port_id
- NULL, // don't search WWN
- NULL); // (don't care about end of list)
-
- if( pLoggedInPort ) // If found, we have prior experience with
- // this port -- check whether PDISC is needed
- {
- if( pLoggedInPort->flogi )
- {
- // does the switch support FDISC?? (FLOGI for now...)
- loginType = ELS_FLOGI; // prior FLOGI still valid
- }
- else
- loginType = ELS_FLOGI; // expired FLOGI
- }
- else // first FLOGI?
- loginType = ELS_FLOGI;
-
-
- fchs.s_id = 0xFFFFFE; // well known F_Port address
-
- // Fabrics are not required to support FDISC, and
- // it's not clear if that helps us anyway, since
- // we'll want a Name Service Request to re-verify
- // visible devices...
- // Consequently, we always want our upper 16 bit
- // port_id to be zero (we'll be rejected if we
- // use our prior port_id if we've been plugged into
- // a different switch port).
- // Trick Tachyon to send to ALPA 0 (see TL/TS UG, pg 87)
- // If our ALPA is 55h for instance, we want the FC frame
- // s_id to be 0x000055, while Tach's my_al_pa register
- // must be 0x000155, to force an OPN at ALPA 0
- // (the Fabric port)
- fcChip->Registers.my_al_pa &= 0xFF; // only use ALPA for FLOGI
- writel( fcChip->Registers.my_al_pa | 0x0100,
- fcChip->Registers.ReMapMemBase + TL_MEM_TACH_My_ID);
- }
-
- else // not FLOGI...
- {
- // should we send PLOGI or PDISC? Check if any prior port_id
- // (e.g. alpa) completed a PLOGI/PRLI exchange by checking
- // the pdisc flag.
-
- pLoggedInPort = fcFindLoggedInPort(
- fcChip,
- NULL, // don't search SCSI Nexus
- fchs.s_id, // search linked list for al_pa
- NULL, // don't search WWN
- NULL); // (don't care about end of list)
-
-
-
- if( pLoggedInPort ) // If found, we have prior experience with
- // this port -- check whether PDISC is needed
- {
- if( pLoggedInPort->pdisc )
- {
- loginType = ELS_PDISC; // prior PLOGI and PRLI maybe still valid
-
- }
- else
- loginType = ELS_PLOGI; // prior knowledge, but can't use PDISC
- }
- else // never talked to this port_id before
- loginType = ELS_PLOGI; // prior knowledge, but can't use PDISC
- }
-
-
-
- ulStatus = cpqfcTSBuildExchange(
- cpqfcHBAdata,
- loginType, // e.g. PLOGI
- &fchs, // no incoming frame (we are originator)
- NULL, // no data (no scatter/gather list)
- &ExchangeID );// fcController->fcExchanges index, -1 if failed
-
- if( !ulStatus ) // Exchange setup OK?
- {
- ulStatus = cpqfcTSStartExchange( cpqfcHBAdata, ExchangeID );
- if( !ulStatus )
- {
- // submitted to Tach's Outbound Que (ERQ PI incremented)
- // waited for completion for ELS type (Login frames issued
- // synchronously)
-
- if( loginType == ELS_PDISC )
- {
- // now, we really shouldn't Revalidate SEST exchanges until
- // we get an ACC reply from our target and verify that
- // the target address/WWN is unchanged. However, when a fast
- // target gets the PDISC, they can send SEST Exchange data
- // before we even get around to processing the PDISC ACC.
- // Consequently, we lose the I/O.
- // To avoid this, go ahead and Revalidate when the PDISC goes
- // out, anticipating that the ACC will be truly acceptable
- // (this happens 99.9999....% of the time).
- // If we revalidate a SEST write, and write data goes to a
- // target that is NOT the one we originated the WRITE to,
- // that target is required (FCP-SCSI specs, etc) to discard
- // our WRITE data.
-
- // Re-validate SEST entries (Tachyon hardware assists)
- RevalidateSEST( cpqfcHBAdata->HostAdapter, pLoggedInPort);
- //TriggerHBA( fcChip->Registers.ReMapMemBase, 1);
- }
- }
- else // give up immediately on error
- {
-#ifdef LOGIN_DBG
- printk("SendLogins: fcStartExchange failed: %Xh\n", ulStatus );
-#endif
- break;
- }
-
-
- if( fcChip->Registers.FMstatus.value & 0x080 ) // LDn during Port Disc.
- {
- ulStatus = LNKDWN_OSLS;
-#ifdef LOGIN_DBG
- printk("SendLogins: PortDisc aborted (LDn) @alpa %Xh\n", fchs.s_id);
-#endif
- break;
- }
- // Check the exchange for bad status (i.e. FrameTimeOut),
- // and complete on bad status (most likely due to BAD_ALPA)
- // on LDn, DPC function may already complete (ABORT) a started
- // exchange, so check type first (type = 0 on complete).
- if( Exchanges->fcExchange[ExchangeID].status )
- {
-#ifdef LOGIN_DBG
- printk("completing x_ID %X on status %Xh\n",
- ExchangeID, Exchanges->fcExchange[ExchangeID].status);
-#endif
- cpqfcTSCompleteExchange( cpqfcHBAdata->PciDev, fcChip, ExchangeID);
- }
- }
- else // Xchange setup failed...
- {
-#ifdef LOGIN_DBG
- printk("FC: cpqfcTSBuildExchange failed: %Xh\n", ulStatus );
-#endif
- break;
- }
- }
- if( !ulStatus )
- {
- // set the event signifying that all ALPAs were sent out.
-#ifdef LOGIN_DBG
- printk("SendLogins: PortDiscDone\n");
-#endif
- cpqfcHBAdata->PortDiscDone = 1;
-
-
- // TL/TS UG, pg. 184
- // 0x0065 = 100ms for RT_TOV
- // 0x01f5 = 500ms for ED_TOV
- fcChip->Registers.ed_tov.value = 0x006501f5L;
- writel( fcChip->Registers.ed_tov.value,
- (fcChip->Registers.ed_tov.address));
-
- // set the LP_TOV back to ED_TOV (i.e. 500 ms)
- writel( 0x00000010, fcChip->Registers.ReMapMemBase +TL_MEM_FM_TIMEOUT2);
- }
- else
- {
- printk("SendLogins: failed at xchng %Xh, alpa %Xh, status %Xh\n",
- ExchangeID, fchs.s_id, ulStatus);
- }
- LEAVE("SendLogins");
-
-}
-
-
-// for REPORT_LUNS documentation, see "In-Depth Exploration of Scsi",
-// D. Deming, 1994, pg 7-19 (ISBN 1-879936-08-9)
-static void ScsiReportLunsDone(Scsi_Cmnd *Cmnd)
-{
- struct Scsi_Host *HostAdapter = Cmnd->device->host;
- CPQFCHBA *cpqfcHBAdata = (CPQFCHBA *)HostAdapter->hostdata;
- PTACHYON fcChip = &cpqfcHBAdata->fcChip;
- FC_EXCHANGES *Exchanges = fcChip->Exchanges;
- PFC_LOGGEDIN_PORT pLoggedInPort;
- int LunListLen=0;
- int i;
- ULONG x_ID = 0xFFFFFFFF;
- UCHAR *ucBuff = Cmnd->request_buffer;
-
-// printk("cpqfcTS: ReportLunsDone \n");
- // first, we need to find the Exchange for this command,
- // so we can find the fcPort struct to make the indicated
- // changes.
- for( i=0; i< TACH_SEST_LEN; i++)
- {
- if( Exchanges->fcExchange[i].type // exchange defined?
- &&
- (Exchanges->fcExchange[i].Cmnd == Cmnd) ) // matches?
-
- {
- x_ID = i; // found exchange!
- break;
- }
- }
- if( x_ID == 0xFFFFFFFF)
- {
-// printk("cpqfcTS: ReportLuns failed - no FC Exchange\n");
- goto Done; // Report Luns FC Exchange gone;
- // exchange probably Terminated by Implicit logout
- }
-
-
- // search linked list for the port_id we sent INQUIRY to
- pLoggedInPort = fcFindLoggedInPort( fcChip,
- NULL, // DON'T search Scsi Nexus (we will set it)
- Exchanges->fcExchange[ x_ID].fchs.d_id & 0xFFFFFF,
- NULL, // DON'T search linked list for FC WWN
- NULL); // DON'T care about end of list
-
- if( !pLoggedInPort )
- {
-// printk("cpqfcTS: ReportLuns failed - device gone\n");
- goto Done; // error! can't find logged in Port
- }
- LunListLen = ucBuff[3];
- LunListLen += ucBuff[2]>>8;
-
- if( !LunListLen ) // failed
- {
- // generically speaking, a soft error means we should retry...
- if( (Cmnd->result >> 16) == DID_SOFT_ERROR )
- {
- if( ((Cmnd->sense_buffer[2] & 0xF) == 0x6) &&
- (Cmnd->sense_buffer[12] == 0x29) ) // Sense Code "reset"
- {
- TachFCHDR_GCMND *fchs = &Exchanges->fcExchange[ x_ID].fchs;
- // did we fail because of "check condition, device reset?"
- // e.g. the device was reset (i.e., at every power up)
- // retry the Report Luns
-
- // who are we sending it to?
- // we know this because we have a copy of the command
- // frame from the original Report Lun command -
- // switch the d_id/s_id fields, because the Exchange Build
- // context is "reply to source".
-
- fchs->s_id = fchs->d_id; // (temporarily re-use the struct)
- cpqfcTSPutLinkQue( cpqfcHBAdata, SCSI_REPORT_LUNS, fchs );
- }
- }
- else // probably, the device doesn't support Report Luns
- pLoggedInPort->ScsiNexus.VolumeSetAddressing = 0;
- }
- else // we have LUN info - check VSA mode
- {
- // for now, assume all LUNs will have same addr mode
- // for VSA, payload byte 8 will be 0x40; otherwise, 0
- pLoggedInPort->ScsiNexus.VolumeSetAddressing = ucBuff[8];
-
- // Since we got a Report Luns answer, set lun masking flag
- pLoggedInPort->ScsiNexus.LunMasking = 1;
-
- if( LunListLen > 8*CPQFCTS_MAX_LUN) // We expect CPQFCTS_MAX_LUN max
- LunListLen = 8*CPQFCTS_MAX_LUN;
-
-/*
- printk("Device WWN %08X%08X Reports Luns @: ",
- (ULONG)(pLoggedInPort->u.liWWN &0xFFFFFFFF),
- (ULONG)(pLoggedInPort->u.liWWN>>32));
-
- for( i=8; i<LunListLen+8; i+=8)
- {
- printk("%02X%02X ", ucBuff[i], ucBuff[i+1] );
- }
- printk("\n");
-*/
-
- // Since the device was kind enough to tell us where the
- // LUNs are, lets ensure they are contiguous for Linux's
- // SCSI driver scan, which expects them to start at 0.
- // Since Linux only supports 8 LUNs, only copy the first
- // eight from the report luns command
-
- // e.g., the Compaq RA4x00 f/w Rev 2.54 and above may report
- // LUNs 4001, 4004, etc., because other LUNs are masked from
- // this HBA (owned by someone else). We'll make those appear as
- // LUN 0, 1... to Linux
- {
- int j;
- int AppendLunList = 0;
- // Walk through the LUN list. The 'j' array number is
- // Linux's lun #, while the value of .lun[j] is the target's
- // lun #.
- // Once we build a LUN list, it's possible for a known device
- // to go offline while volumes (LUNs) are added. Later,
- // the device will do another PLOGI ... Report Luns command,
- // and we must not alter the existing Linux Lun map.
- // (This will be very rare).
- for( j=0; j < CPQFCTS_MAX_LUN; j++)
- {
- if( pLoggedInPort->ScsiNexus.lun[j] != 0xFF )
- {
- AppendLunList = 1;
- break;
- }
- }
- if( AppendLunList )
- {
- int k;
- int FreeLunIndex;
-// printk("cpqfcTS: AppendLunList\n");
-
- // If we get a new Report Luns, we cannot change
- // any existing LUN mapping! (Only additive entry)
- // For all LUNs in ReportLun list
- // if RL lun != ScsiNexus lun
- // if RL lun present in ScsiNexus lun[], continue
- // else find ScsiNexus lun[]==FF and add, continue
-
- for( i=8, j=0; i<LunListLen+8 && j< CPQFCTS_MAX_LUN; i+=8, j++)
- {
- if( pLoggedInPort->ScsiNexus.lun[j] != ucBuff[i+1] )
- {
- // something changed from the last Report Luns
- printk(" cpqfcTS: Report Lun change!\n");
- for( k=0, FreeLunIndex=CPQFCTS_MAX_LUN;
- k < CPQFCTS_MAX_LUN; k++)
- {
- if( pLoggedInPort->ScsiNexus.lun[k] == 0xFF)
- {
- FreeLunIndex = k;
- break;
- }
- if( pLoggedInPort->ScsiNexus.lun[k] == ucBuff[i+1] )
- break; // we already masked this lun
- }
- if( k >= CPQFCTS_MAX_LUN )
- {
- printk(" no room for new LUN %d\n", ucBuff[i+1]);
- }
- else if( k == FreeLunIndex ) // need to add LUN
- {
- pLoggedInPort->ScsiNexus.lun[k] = ucBuff[i+1];
-// printk("add [%d]->%02d\n", k, pLoggedInPort->ScsiNexus.lun[k]);
-
- }
- else
- {
- // lun already known
- }
- break;
- }
- }
- // print out the new list...
- for( j=0; j< CPQFCTS_MAX_LUN; j++)
- {
- if( pLoggedInPort->ScsiNexus.lun[j] == 0xFF)
- break; // done
-// printk("[%d]->%02d ", j, pLoggedInPort->ScsiNexus.lun[j]);
- }
- }
- else
- {
-// printk("Linux SCSI LUNs[] -> Device LUNs: ");
- // first time - this is easy
- for( i=8, j=0; i<LunListLen+8 && j< CPQFCTS_MAX_LUN; i+=8, j++)
- {
- pLoggedInPort->ScsiNexus.lun[j] = ucBuff[i+1];
-// printk("[%d]->%02d ", j, pLoggedInPort->ScsiNexus.lun[j]);
- }
-// printk("\n");
- }
- }
- }
-
-Done: ;
-}
-
-extern int is_private_data_of_cpqfc(CPQFCHBA *hba, void * pointer);
-extern void cpqfc_free_private_data(CPQFCHBA *hba, cpqfc_passthru_private_t *data);
-
-static void
-call_scsi_done(Scsi_Cmnd *Cmnd)
-{
- CPQFCHBA *hba;
- hba = (CPQFCHBA *) Cmnd->device->host->hostdata;
- // Was this command a cpqfc passthru ioctl ?
- if (Cmnd->sc_request != NULL && Cmnd->device->host != NULL &&
- Cmnd->device->host->hostdata != NULL &&
- is_private_data_of_cpqfc((CPQFCHBA *) Cmnd->device->host->hostdata,
- Cmnd->sc_request->upper_private_data)) {
- cpqfc_free_private_data(hba,
- Cmnd->sc_request->upper_private_data);
- Cmnd->sc_request->upper_private_data = NULL;
- Cmnd->result &= 0xff00ffff;
- Cmnd->result |= (DID_PASSTHROUGH << 16); // prevents retry
- }
- if (Cmnd->scsi_done != NULL)
- (*Cmnd->scsi_done)(Cmnd);
-}
-
-// After successfully getting a "Process Login" (PRLI) from an
-// FC port, we want to Discover the LUNs so that we know the
-// addressing type (e.g., FCP-SCSI Volume Set Address, Peripheral
-// Unit Device), and whether SSP (Selective Storage Presentation or
-// Lun Masking) has made the LUN numbers non-zero based or
-// non-contiguous. To remain backward compatible with the SCSI-2
-// driver model, which expects a contiguous LUNs starting at 0,
-// will use the ReportLuns info to map from "device" to "Linux"
-// LUNs.
-static void IssueReportLunsCommand(
- CPQFCHBA* cpqfcHBAdata,
- TachFCHDR_GCMND* fchs)
-{
- PTACHYON fcChip = &cpqfcHBAdata->fcChip;
- PFC_LOGGEDIN_PORT pLoggedInPort;
- struct scsi_cmnd *Cmnd = NULL;
- struct scsi_device *ScsiDev = NULL;
- LONG x_ID;
- ULONG ulStatus;
- UCHAR *ucBuff;
-
- if( !cpqfcHBAdata->PortDiscDone) // cleared by LDn
- {
- printk("Discard Q'd ReportLun command\n");
- goto Done;
- }
-
- // find the device (from port_id) we're talking to
- pLoggedInPort = fcFindLoggedInPort( fcChip,
- NULL, // DON'T search Scsi Nexus
- fchs->s_id & 0xFFFFFF,
- NULL, // DON'T search linked list for FC WWN
- NULL); // DON'T care about end of list
- if( pLoggedInPort ) // we'd BETTER find it!
- {
-
-
- if( !(pLoggedInPort->fcp_info & TARGET_FUNCTION) )
- goto Done; // forget it - FC device not a "target"
-
-
- ScsiDev = scsi_get_host_dev (cpqfcHBAdata->HostAdapter);
- if (!ScsiDev)
- goto Done;
-
- Cmnd = scsi_get_command (ScsiDev, GFP_KERNEL);
- if (!Cmnd)
- goto Done;
-
- ucBuff = pLoggedInPort->ReportLunsPayload;
-
- memset( ucBuff, 0, REPORT_LUNS_PL);
-
- Cmnd->scsi_done = ScsiReportLunsDone;
-
- Cmnd->request_buffer = pLoggedInPort->ReportLunsPayload;
- Cmnd->request_bufflen = REPORT_LUNS_PL;
-
- Cmnd->cmnd[0] = 0xA0;
- Cmnd->cmnd[8] = REPORT_LUNS_PL >> 8;
- Cmnd->cmnd[9] = (UCHAR)REPORT_LUNS_PL;
- Cmnd->cmd_len = 12;
-
- Cmnd->device->channel = pLoggedInPort->ScsiNexus.channel;
- Cmnd->device->id = pLoggedInPort->ScsiNexus.target;
-
-
- ulStatus = cpqfcTSBuildExchange(
- cpqfcHBAdata,
- SCSI_IRE,
- fchs,
- Cmnd, // buffer for Report Lun data
- &x_ID );// fcController->fcExchanges index, -1 if failed
-
- if( !ulStatus ) // Exchange setup?
- {
- ulStatus = cpqfcTSStartExchange( cpqfcHBAdata, x_ID );
- if( !ulStatus )
- {
- // submitted to Tach's Outbound Que (ERQ PI incremented)
- // waited for completion for ELS type (Login frames issued
- // synchronously)
- }
- else
- // check reason for Exchange not being started - we might
- // want to Queue and start later, or fail with error
- {
-
- }
- }
-
- else // Xchange setup failed...
- printk(" cpqfcTSBuildExchange failed: %Xh\n", ulStatus );
- }
- else // like, we just got a PRLI ACC, and now the port is gone?
- {
- printk(" can't send ReportLuns - no login for port_id %Xh\n",
- fchs->s_id & 0xFFFFFF);
- }
-
-
-
-Done:
-
- if (Cmnd)
- scsi_put_command (Cmnd);
- if (ScsiDev)
- scsi_free_host_dev (ScsiDev);
-}
-
-
-
-
-
-
-
-static void CompleteBoardLockCmnd( CPQFCHBA *cpqfcHBAdata)
-{
- int i;
- for( i = CPQFCTS_REQ_QUEUE_LEN-1; i>= 0; i--)
- {
- if( cpqfcHBAdata->BoardLockCmnd[i] != NULL )
- {
- Scsi_Cmnd *Cmnd = cpqfcHBAdata->BoardLockCmnd[i];
- cpqfcHBAdata->BoardLockCmnd[i] = NULL;
- Cmnd->result = (DID_SOFT_ERROR << 16); // ask for retry
-// printk(" BoardLockCmnd[%d] %p Complete, chnl/target/lun %d/%d/%d\n",
-// i,Cmnd, Cmnd->channel, Cmnd->target, Cmnd->lun);
- call_scsi_done(Cmnd);
- }
- }
-}
-
-
-
-
-
-
-// runs every 1 second for FC exchange timeouts and implicit FC device logouts
-
-void cpqfcTSheartbeat( unsigned long ptr )
-{
- CPQFCHBA *cpqfcHBAdata = (CPQFCHBA *)ptr;
- PTACHYON fcChip = &cpqfcHBAdata->fcChip;
- FC_EXCHANGES *Exchanges = fcChip->Exchanges;
- PFC_LOGGEDIN_PORT pLoggedInPort = &fcChip->fcPorts;
- ULONG i;
- unsigned long flags;
- DECLARE_MUTEX_LOCKED(BoardLock);
-
- PCI_TRACE( 0xA8)
-
- if( cpqfcHBAdata->BoardLock) // Worker Task Running?
- goto Skip;
-
- // STOP _que function
- spin_lock_irqsave( cpqfcHBAdata->HostAdapter->host_lock, flags);
-
- PCI_TRACE( 0xA8)
-
-
- cpqfcHBAdata->BoardLock = &BoardLock; // stop Linux SCSI command queuing
-
- // release the IO lock (and re-enable interrupts)
- spin_unlock_irqrestore( cpqfcHBAdata->HostAdapter->host_lock, flags);
-
- // Ensure no contention from _quecommand or Worker process
- CPQ_SPINLOCK_HBA( cpqfcHBAdata)
-
- PCI_TRACE( 0xA8)
-
-
- disable_irq( cpqfcHBAdata->HostAdapter->irq); // our IRQ
-
- // Complete the "bad target" commands (normally only used during
- // initialization, since we aren't supposed to call "scsi_done"
- // inside the queuecommand() function). (this is overly contorted,
- // scsi_done can be safely called from queuecommand for
- // this bad target case. May want to simplify this later)
-
- for( i=0; i< CPQFCTS_MAX_TARGET_ID; i++)
- {
- if( cpqfcHBAdata->BadTargetCmnd[i] )
- {
- Scsi_Cmnd *Cmnd = cpqfcHBAdata->BadTargetCmnd[i];
- cpqfcHBAdata->BadTargetCmnd[i] = NULL;
- Cmnd->result = (DID_BAD_TARGET << 16);
- call_scsi_done(Cmnd);
- }
- else
- break;
- }
-
-
- // logged in ports -- re-login check (ports required to verify login with
- // PDISC after LIP within 2 secs)
-
- // prevent contention
- while( pLoggedInPort ) // for all ports which are expecting
- // PDISC after the next LIP, check to see if
- // time is up!
- {
- // Important: we only detect "timeout" condition on TRANSITION
- // from non-zero to zero
- if( pLoggedInPort->LOGO_timer ) // time-out "armed"?
- {
- if( !(--pLoggedInPort->LOGO_timer) ) // DEC from 1 to 0?
- {
- // LOGOUT time! Per PLDA, PDISC hasn't complete in 2 secs, so
- // issue LOGO request and destroy all I/O with other FC port(s).
-
-/*
- printk(" ~cpqfcTS heartbeat: LOGOut!~ ");
- printk("Linux SCSI Chanl/Target %d/%d (port_id %06Xh) WWN %08X%08X\n",
- pLoggedInPort->ScsiNexus.channel,
- pLoggedInPort->ScsiNexus.target,
- pLoggedInPort->port_id,
- (ULONG)(pLoggedInPort->u.liWWN &0xFFFFFFFF),
- (ULONG)(pLoggedInPort->u.liWWN>>32));
-
-*/
- cpqfcTSImplicitLogout( cpqfcHBAdata, pLoggedInPort);
-
- }
- // else simply decremented - maybe next time...
- }
- pLoggedInPort = pLoggedInPort->pNextPort;
- }
-
-
-
-
-
- // ************ FC EXCHANGE TIMEOUT CHECK **************
-
- for( i=0; i< TACH_MAX_XID; i++)
- {
- if( Exchanges->fcExchange[i].type ) // exchange defined?
- {
-
- if( !Exchanges->fcExchange[i].timeOut ) // time expired
- {
- // Set Exchange timeout status
- Exchanges->fcExchange[i].status |= FC2_TIMEOUT;
-
- if( i >= TACH_SEST_LEN ) // Link Service Exchange
- {
- cpqfcTSCompleteExchange( cpqfcHBAdata->PciDev, fcChip, i); // Don't "abort" LinkService
- }
-
- else // SEST Exchange TO -- may post ABTS to Worker Thread Que
- {
- // (Make sure we don't keep timing it out; let other functions
- // complete it or set the timeOut as needed)
- Exchanges->fcExchange[i].timeOut = 30000; // seconds default
-
- if( Exchanges->fcExchange[i].type
- &
- (BLS_ABTS | BLS_ABTS_ACC ) )
- {
- // For BLS_ABTS*, an upper level might still have
- // an outstanding command waiting for low-level completion.
- // Also, in the case of a WRITE, we MUST get confirmation
- // of either ABTS ACC or RJT before re-using the Exchange.
- // It's possible that the RAID cache algorithm can hang
- // if we fail to complete a WRITE to a LBA, when a READ
- // comes later to that same LBA. Therefore, we must
- // ensure that the target verifies receipt of ABTS for
- // the exchange
-
- printk("~TO Q'd ABTS (x_ID %Xh)~ ", i);
-// TriggerHBA( fcChip->Registers.ReMapMemBase);
-
- // On timeout of a ABTS exchange, check to
- // see if the FC device has a current valid login.
- // If so, restart it.
- pLoggedInPort = fcFindLoggedInPort( fcChip,
- Exchanges->fcExchange[i].Cmnd, // find Scsi Nexus
- 0, // DON'T search linked list for FC port id
- NULL, // DON'T search linked list for FC WWN
- NULL); // DON'T care about end of list
-
- // device exists?
- if( pLoggedInPort ) // device exists?
- {
- if( pLoggedInPort->prli ) // logged in for FCP-SCSI?
- {
- // attempt to restart the ABTS
- printk(" ~restarting ABTS~ ");
- cpqfcTSStartExchange( cpqfcHBAdata, i );
-
- }
- }
- }
- else // not an ABTS
- {
-
- // We expect the WorkerThread to change the xchng type to
- // abort and set appropriate timeout.
- cpqfcTSPutLinkQue( cpqfcHBAdata, BLS_ABTS, &i ); // timed-out
- }
- }
- }
- else // time not expired...
- {
- // decrement timeout: 1 or more seconds left
- --Exchanges->fcExchange[i].timeOut;
- }
- }
- }
-
-
- enable_irq( cpqfcHBAdata->HostAdapter->irq);
-
-
- CPQ_SPINUNLOCK_HBA( cpqfcHBAdata)
-
- cpqfcHBAdata->BoardLock = NULL; // Linux SCSI commands may be queued
-
- // Now, complete any Cmnd we Q'd up while BoardLock was held
-
- CompleteBoardLockCmnd( cpqfcHBAdata);
-
-
- // restart the timer to run again (1 sec later)
-Skip:
- mod_timer( &cpqfcHBAdata->cpqfcTStimer, jiffies + HZ);
-
- PCI_TRACEO( i, 0xA8)
- return;
-}
-
-
-// put valid FC-AL physical address in spec order
-static const UCHAR valid_al_pa[]={
- 0xef, 0xe8, 0xe4, 0xe2,
- 0xe1, 0xE0, 0xDC, 0xDA,
- 0xD9, 0xD6, 0xD5, 0xD4,
- 0xD3, 0xD2, 0xD1, 0xCe,
- 0xCd, 0xCc, 0xCb, 0xCa,
- 0xC9, 0xC7, 0xC6, 0xC5,
- 0xC3, 0xBc, 0xBa, 0xB9,
- 0xB6, 0xB5, 0xB4, 0xB3,
- 0xB2, 0xB1, 0xae, 0xad,
- 0xAc, 0xAb, 0xAa, 0xA9,
-
- 0xA7, 0xA6, 0xA5, 0xA3,
- 0x9f, 0x9e, 0x9d, 0x9b,
- 0x98, 0x97, 0x90, 0x8f,
- 0x88, 0x84, 0x82, 0x81,
- 0x80, 0x7c, 0x7a, 0x79,
- 0x76, 0x75, 0x74, 0x73,
- 0x72, 0x71, 0x6e, 0x6d,
- 0x6c, 0x6b, 0x6a, 0x69,
- 0x67, 0x66, 0x65, 0x63,
- 0x5c, 0x5a, 0x59, 0x56,
-
- 0x55, 0x54, 0x53, 0x52,
- 0x51, 0x4e, 0x4d, 0x4c,
- 0x4b, 0x4a, 0x49, 0x47,
- 0x46, 0x45, 0x43, 0x3c,
- 0x3a, 0x39, 0x36, 0x35,
- 0x34, 0x33, 0x32, 0x31,
- 0x2e, 0x2d, 0x2c, 0x2b,
- 0x2a, 0x29, 0x27, 0x26,
- 0x25, 0x23, 0x1f, 0x1E,
- 0x1d, 0x1b, 0x18, 0x17,
-
- 0x10, 0x0f, 8, 4, 2, 1 }; // ALPA 0 (Fabric) is special case
-
-const int number_of_al_pa = (sizeof(valid_al_pa) );
-
-
-
-// this function looks up an al_pa from the table of valid al_pa's
-// we decrement from the last decimal loop ID, because soft al_pa
-// (our typical case) are assigned with highest priority (and high al_pa)
-// first. See "In-Depth FC-AL", R. Kembel pg. 38
-// INPUTS:
-// al_pa - 24 bit port identifier (8 bit al_pa on private loop)
-// RETURN:
-// Loop ID - serves are index to array of logged in ports
-// -1 - invalid al_pa (not all 8 bit values are legal)
-
-#if (0)
-static int GetLoopID( ULONG al_pa )
-{
- int i;
-
- for( i = number_of_al_pa -1; i >= 0; i--) // dec.
- {
- if( valid_al_pa[i] == (UCHAR)al_pa ) // take lowest 8 bits
- return i; // success - found valid al_pa; return decimal LoopID
- }
- return -1; // failed - not found
-}
-#endif
-
-extern cpqfc_passthru_private_t *cpqfc_private(Scsi_Request *sr);
-
-// Search the singly (forward) linked list "fcPorts" looking for
-// either the SCSI target (if != -1), port_id (if not NULL),
-// or WWN (if not null), in that specific order.
-// If we find a SCSI nexus (from Cmnd arg), set the SCp.phase
-// field according to VSA or PDU
-// RETURNS:
-// Ptr to logged in port struct if found
-// (NULL if not found)
-// pLastLoggedInPort - ptr to last struct (for adding new ones)
-//
-PFC_LOGGEDIN_PORT fcFindLoggedInPort(
- PTACHYON fcChip,
- Scsi_Cmnd *Cmnd, // search linked list for Scsi Nexus (channel/target/lun)
- ULONG port_id, // search linked list for al_pa, or
- UCHAR wwn[8], // search linked list for WWN, or...
- PFC_LOGGEDIN_PORT *pLastLoggedInPort )
-
-{
- PFC_LOGGEDIN_PORT pLoggedInPort = &fcChip->fcPorts;
- BOOLEAN target_id_valid=FALSE;
- BOOLEAN port_id_valid=FALSE;
- BOOLEAN wwn_valid=FALSE;
- int i;
-
-
- if( Cmnd != NULL )
- target_id_valid = TRUE;
-
- else if( port_id ) // note! 24-bit NULL address is illegal
- port_id_valid = TRUE;
-
- else
- {
- if( wwn ) // non-null arg? (OK to pass NULL when not searching WWN)
- {
- for( i=0; i<8; i++) // valid WWN passed? NULL WWN invalid
- {
- if( wwn[i] != 0 )
- wwn_valid = TRUE; // any non-zero byte makes (presumably) valid
- }
- }
- }
- // check other options ...
-
-
- // In case multiple search options are given, we use a priority
- // scheme:
- // While valid pLoggedIn Ptr
- // If port_id is valid
- // if port_id matches, return Ptr
- // If wwn is valid
- // if wwn matches, return Ptr
- // Next Ptr in list
- //
- // Return NULL (not found)
-
-
- while( pLoggedInPort ) // NULL marks end of list (1st ptr always valid)
- {
- if( pLastLoggedInPort ) // caller's pointer valid?
- *pLastLoggedInPort = pLoggedInPort; // end of linked list
-
- if( target_id_valid )
- {
- // check Linux Scsi Cmnd for channel/target Nexus match
- // (all luns are accessed through matching "pLoggedInPort")
- if( (pLoggedInPort->ScsiNexus.target == Cmnd->device->id)
- &&
- (pLoggedInPort->ScsiNexus.channel == Cmnd->device->channel))
- {
- // For "passthru" modes, the IOCTL caller is responsible
- // for setting the FCP-LUN addressing
- if (Cmnd->sc_request != NULL && Cmnd->device->host != NULL &&
- Cmnd->device->host->hostdata != NULL &&
- is_private_data_of_cpqfc((CPQFCHBA *) Cmnd->device->host->hostdata,
- Cmnd->sc_request->upper_private_data)) {
- /* This is a passthru... */
- cpqfc_passthru_private_t *pd;
- pd = Cmnd->sc_request->upper_private_data;
- Cmnd->SCp.phase = pd->bus;
- // Cmnd->SCp.have_data_in = pd->pdrive;
- Cmnd->SCp.have_data_in = Cmnd->device->lun;
- } else {
- /* This is not a passthru... */
-
- // set the FCP-LUN addressing type
- Cmnd->SCp.phase = pLoggedInPort->ScsiNexus.VolumeSetAddressing;
-
- // set the Device Type we got from the snooped INQUIRY string
- Cmnd->SCp.Message = pLoggedInPort->ScsiNexus.InqDeviceType;
-
- // handle LUN masking; if not "default" (illegal) lun value,
- // the use it. These lun values are set by a successful
- // Report Luns command
- if( pLoggedInPort->ScsiNexus.LunMasking == 1)
- {
- if (Cmnd->device->lun > sizeof(pLoggedInPort->ScsiNexus.lun))
- return NULL;
- // we KNOW all the valid LUNs... 0xFF is invalid!
- Cmnd->SCp.have_data_in = pLoggedInPort->ScsiNexus.lun[Cmnd->device->lun];
- if (pLoggedInPort->ScsiNexus.lun[Cmnd->device->lun] == 0xFF)
- return NULL;
- // printk("xlating lun %d to 0x%02x\n", Cmnd->lun,
- // pLoggedInPort->ScsiNexus.lun[Cmnd->lun]);
- }
- else
- Cmnd->SCp.have_data_in = Cmnd->device->lun; // Linux & target luns match
- }
- break; // found it!
- }
- }
-
- if( port_id_valid ) // look for alpa first
- {
- if( pLoggedInPort->port_id == port_id )
- break; // found it!
- }
- if( wwn_valid ) // look for wwn second
- {
-
- if( !memcmp( &pLoggedInPort->u.ucWWN[0], &wwn[0], 8))
- {
- // all 8 bytes of WWN match
- break; // found it!
- }
- }
-
- pLoggedInPort = pLoggedInPort->pNextPort; // try next port
- }
-
- return pLoggedInPort;
-}
-
-
-
-
-//
-// We need to examine the SEST table and re-validate
-// any open Exchanges for this LoggedInPort
-// To make Tachyon pay attention, Freeze FCP assists,
-// set VAL bits, Unfreeze FCP assists
-static void RevalidateSEST( struct Scsi_Host *HostAdapter,
- PFC_LOGGEDIN_PORT pLoggedInPort)
-{
- CPQFCHBA *cpqfcHBAdata = (CPQFCHBA *)HostAdapter->hostdata;
- PTACHYON fcChip = &cpqfcHBAdata->fcChip;
- FC_EXCHANGES *Exchanges = fcChip->Exchanges;
- ULONG x_ID;
- BOOLEAN TachFroze = FALSE;
-
-
- // re-validate any SEST exchanges that are permitted
- // to survive the link down (e.g., good PDISC performed)
- for( x_ID = 0; x_ID < TACH_SEST_LEN; x_ID++)
- {
-
- // If the SEST entry port_id matches the pLoggedInPort,
- // we need to re-validate
- if( (Exchanges->fcExchange[ x_ID].type == SCSI_IRE)
- ||
- (Exchanges->fcExchange[ x_ID].type == SCSI_IWE))
- {
-
- if( (Exchanges->fcExchange[ x_ID].fchs.d_id & 0xFFFFFF) // (24-bit port ID)
- == pLoggedInPort->port_id)
- {
-// printk(" re-val xID %Xh ", x_ID);
- if( !TachFroze ) // freeze if not already frozen
- TachFroze |= FreezeTach( cpqfcHBAdata);
- fcChip->SEST->u[ x_ID].IWE.Hdr_Len |= 0x80000000; // set VAL bit
- }
- }
- }
-
- if( TachFroze)
- {
- fcChip->UnFreezeTachyon( fcChip, 2); // both ERQ and FCP assists
- }
-}
-
-
-// Complete an Linux Cmnds that we Queued because
-// our FC link was down (cause immediate retry)
-
-static void UnblockScsiDevice( struct Scsi_Host *HostAdapter,
- PFC_LOGGEDIN_PORT pLoggedInPort)
-{
- CPQFCHBA *cpqfcHBAdata = (CPQFCHBA *)HostAdapter->hostdata;
- Scsi_Cmnd* *SCptr = &cpqfcHBAdata->LinkDnCmnd[0];
- Scsi_Cmnd *Cmnd;
- int indx;
-
-
-
- // if the device was previously "blocked", make sure
- // we unblock it so Linux SCSI will resume
-
- pLoggedInPort->device_blocked = FALSE; // clear our flag
-
- // check the Link Down command ptr buffer;
- // we can complete now causing immediate retry
- for( indx=0; indx < CPQFCTS_REQ_QUEUE_LEN; indx++, SCptr++)
- {
- if( *SCptr != NULL ) // scsi command to complete?
- {
-#ifdef DUMMYCMND_DBG
- printk("complete Cmnd %p in LinkDnCmnd[%d]\n", *SCptr,indx);
-#endif
- Cmnd = *SCptr;
-
-
- // Are there any Q'd commands for this target?
- if( (Cmnd->device->id == pLoggedInPort->ScsiNexus.target)
- &&
- (Cmnd->device->channel == pLoggedInPort->ScsiNexus.channel) )
- {
- Cmnd->result = (DID_SOFT_ERROR <<16); // force retry
- if( Cmnd->scsi_done == NULL)
- {
- printk("LinkDnCmnd scsi_done ptr null, port_id %Xh\n",
- pLoggedInPort->port_id);
- }
- else
- call_scsi_done(Cmnd);
- *SCptr = NULL; // free this slot for next use
- }
- }
- }
-}
-
-
-//#define WWN_DBG 1
-
-static void SetLoginFields(
- PFC_LOGGEDIN_PORT pLoggedInPort,
- TachFCHDR_GCMND* fchs,
- BOOLEAN PDisc,
- BOOLEAN Originator)
-{
- LOGIN_PAYLOAD logi; // FC-PH Port Login
- PRLI_REQUEST prli; // copy for BIG ENDIAN switch
- int i;
-#ifdef WWN_DBG
- ULONG ulBuff;
-#endif
-
- BigEndianSwap( (UCHAR*)&fchs->pl[0], (UCHAR*)&logi, sizeof(logi));
-
- pLoggedInPort->Originator = Originator;
- pLoggedInPort->port_id = fchs->s_id & 0xFFFFFF;
-
- switch( fchs->pl[0] & 0xffff )
- {
- case 0x00000002: // PLOGI or PDISC ACCept?
- if( PDisc ) // PDISC accept
- goto PDISC_case;
-
- case 0x00000003: // ELS_PLOGI or ELS_PLOGI_ACC
-
- // Login BB_credit typically 0 for Tachyons
- pLoggedInPort->BB_credit = logi.cmn_services.bb_credit;
-
- // e.g. 128, 256, 1024, 2048 per FC-PH spec
- // We have to use this when setting up SEST Writes,
- // since that determines frame size we send.
- pLoggedInPort->rx_data_size = logi.class3.rx_data_size;
- pLoggedInPort->plogi = TRUE;
- pLoggedInPort->pdisc = FALSE;
- pLoggedInPort->prli = FALSE; // ELS_PLOGI resets
- pLoggedInPort->flogi = FALSE; // ELS_PLOGI resets
- pLoggedInPort->logo = FALSE; // ELS_PLOGI resets
- pLoggedInPort->LOGO_counter = 0;// ELS_PLOGI resets
- pLoggedInPort->LOGO_timer = 0;// ELS_PLOGI resets
-
- // was this PLOGI to a Fabric?
- if( pLoggedInPort->port_id == 0xFFFFFC ) // well know address
- pLoggedInPort->flogi = TRUE;
-
-
- for( i=0; i<8; i++) // copy the LOGIN port's WWN
- pLoggedInPort->u.ucWWN[i] = logi.port_name[i];
-
-#ifdef WWN_DBG
- ulBuff = (ULONG)pLoggedInPort->u.liWWN;
- if( pLoggedInPort->Originator)
- printk("o");
- else
- printk("r");
- printk("PLOGI port_id %Xh, WWN %08X",
- pLoggedInPort->port_id, ulBuff);
-
- ulBuff = (ULONG)(pLoggedInPort->u.liWWN >> 32);
- printk("%08Xh fcPort %p\n", ulBuff, pLoggedInPort);
-#endif
- break;
-
-
-
-
- case 0x00000005: // ELS_LOGO (logout)
-
-
- pLoggedInPort->plogi = FALSE;
- pLoggedInPort->pdisc = FALSE;
- pLoggedInPort->prli = FALSE; // ELS_PLOGI resets
- pLoggedInPort->flogi = FALSE; // ELS_PLOGI resets
- pLoggedInPort->logo = TRUE; // ELS_PLOGI resets
- pLoggedInPort->LOGO_counter++; // ELS_PLOGI resets
- pLoggedInPort->LOGO_timer = 0;
-#ifdef WWN_DBG
- ulBuff = (ULONG)pLoggedInPort->u.liWWN;
- if( pLoggedInPort->Originator)
- printk("o");
- else
- printk("r");
- printk("LOGO port_id %Xh, WWN %08X",
- pLoggedInPort->port_id, ulBuff);
-
- ulBuff = (ULONG)(pLoggedInPort->u.liWWN >> 32);
- printk("%08Xh\n", ulBuff);
-#endif
- break;
-
-
-
-PDISC_case:
- case 0x00000050: // ELS_PDISC or ELS_PDISC_ACC
- pLoggedInPort->LOGO_timer = 0; // stop the time-out
-
- pLoggedInPort->prli = TRUE; // ready to accept FCP-SCSI I/O
-
-
-
-#ifdef WWN_DBG
- ulBuff = (ULONG)pLoggedInPort->u.liWWN;
- if( pLoggedInPort->Originator)
- printk("o");
- else
- printk("r");
- printk("PDISC port_id %Xh, WWN %08X",
- pLoggedInPort->port_id, ulBuff);
-
- ulBuff = (ULONG)(pLoggedInPort->u.liWWN >> 32);
- printk("%08Xh\n", ulBuff);
-#endif
-
-
-
- break;
-
-
-
- case 0x1020L: // PRLI?
- case 0x1002L: // PRLI ACCept?
- BigEndianSwap( (UCHAR*)&fchs->pl[0], (UCHAR*)&prli, sizeof(prli));
-
- pLoggedInPort->fcp_info = prli.fcp_info; // target/initiator flags
- pLoggedInPort->prli = TRUE; // PLOGI resets, PDISC doesn't
-
- pLoggedInPort->pdisc = TRUE; // expect to send (or receive) PDISC
- // next time
- pLoggedInPort->LOGO_timer = 0; // will be set next LinkDown
-#ifdef WWN_DBG
- ulBuff = (ULONG)pLoggedInPort->u.liWWN;
- if( pLoggedInPort->Originator)
- printk("o");
- else
- printk("r");
- printk("PRLI port_id %Xh, WWN %08X",
- pLoggedInPort->port_id, ulBuff);
-
- ulBuff = (ULONG)(pLoggedInPort->u.liWWN >> 32);
- printk("%08Xh\n", ulBuff);
-#endif
-
- break;
-
- }
-
- return;
-}
-
-
-
-
-
-
-static void BuildLinkServicePayload( PTACHYON fcChip, ULONG type, void* payload)
-{
- LOGIN_PAYLOAD *plogi; // FC-PH Port Login
- LOGIN_PAYLOAD PlogiPayload; // copy for BIG ENDIAN switch
- PRLI_REQUEST *prli; // FCP-SCSI Process Login
- PRLI_REQUEST PrliPayload; // copy for BIG ENDIAN switch
- LOGOUT_PAYLOAD *logo;
- LOGOUT_PAYLOAD LogoutPayload;
-// PRLO_REQUEST *prlo;
-// PRLO_REQUEST PrloPayload;
- REJECT_MESSAGE rjt, *prjt;
-
- memset( &PlogiPayload, 0, sizeof( PlogiPayload));
- plogi = &PlogiPayload; // load into stack buffer,
- // then BIG-ENDIAN switch a copy to caller
-
-
- switch( type ) // payload type can be ELS_PLOGI, ELS_PRLI, ADISC, ...
- {
- case ELS_FDISC:
- case ELS_FLOGI:
- case ELS_PLOGI_ACC: // FC-PH PORT Login Accept
- case ELS_PLOGI: // FC-PH PORT Login
- case ELS_PDISC: // FC-PH2 Port Discovery - same payload as ELS_PLOGI
- plogi->login_cmd = LS_PLOGI;
- if( type == ELS_PDISC)
- plogi->login_cmd = LS_PDISC;
- else if( type == ELS_PLOGI_ACC )
- plogi->login_cmd = LS_ACC;
-
- plogi->cmn_services.bb_credit = 0x00;
- plogi->cmn_services.lowest_ver = fcChip->lowest_FCPH_ver;
- plogi->cmn_services.highest_ver = fcChip->highest_FCPH_ver;
- plogi->cmn_services.bb_rx_size = TACHLITE_TS_RX_SIZE;
- plogi->cmn_services.common_features = CONTINUOSLY_INCREASING |
- RANDOM_RELATIVE_OFFSET;
-
- // fill in with World Wide Name based Port Name - 8 UCHARs
- // get from Tach registers WWN hi & lo
- LoadWWN( fcChip, plogi->port_name, 0);
- // fill in with World Wide Name based Node/Fabric Name - 8 UCHARs
- // get from Tach registers WWN hi & lo
- LoadWWN( fcChip, plogi->node_name, 1);
-
- // For Seagate Drives.
- //
- plogi->cmn_services.common_features |= 0x800;
- plogi->cmn_services.rel_offset = 0xFE;
- plogi->cmn_services.concurrent_seq = 1;
- plogi->class1.service_options = 0x00;
- plogi->class2.service_options = 0x00;
- plogi->class3.service_options = CLASS_VALID;
- plogi->class3.initiator_control = 0x00;
- plogi->class3.rx_data_size = MAX_RX_PAYLOAD;
- plogi->class3.recipient_control =
- ERROR_DISCARD | ONE_CATEGORY_SEQUENCE;
- plogi->class3.concurrent_sequences = 1;
- plogi->class3.open_sequences = 1;
- plogi->vendor_id[0] = 'C'; plogi->vendor_id[1] = 'Q';
- plogi->vendor_version[0] = 'C'; plogi->vendor_version[1] = 'Q';
- plogi->vendor_version[2] = ' '; plogi->vendor_version[3] = '0';
- plogi->vendor_version[4] = '0'; plogi->vendor_version[5] = '0';
-
-
- // FLOGI specific fields... (see FC-FLA, Rev 2.7, Aug 1999, sec 5.1)
- if( (type == ELS_FLOGI) || (type == ELS_FDISC) )
- {
- if( type == ELS_FLOGI )
- plogi->login_cmd = LS_FLOGI;
- else
- plogi->login_cmd = LS_FDISC;
-
- plogi->cmn_services.lowest_ver = 0x20;
- plogi->cmn_services.common_features = 0x0800;
- plogi->cmn_services.rel_offset = 0;
- plogi->cmn_services.concurrent_seq = 0;
-
- plogi->class3.service_options = 0x8800;
- plogi->class3.rx_data_size = 0;
- plogi->class3.recipient_control = 0;
- plogi->class3.concurrent_sequences = 0;
- plogi->class3.open_sequences = 0;
- }
-
- // copy back to caller's buff, w/ BIG ENDIAN swap
- BigEndianSwap( (UCHAR*)&PlogiPayload, payload, sizeof(PlogiPayload));
- break;
-
-
- case ELS_ACC: // generic Extended Link Service ACCept
- plogi->login_cmd = LS_ACC;
- // copy back to caller's buff, w/ BIG ENDIAN swap
- BigEndianSwap( (UCHAR*)&PlogiPayload, payload, 4);
- break;
-
-
-
- case ELS_SCR: // Fabric State Change Registration
- {
- SCR_PL scr; // state change registration
-
- memset( &scr, 0, sizeof(scr));
-
- scr.command = LS_SCR; // 0x62000000
- // see FC-FLA, Rev 2.7, Table A.22 (pg 82)
- scr.function = 3; // 1 = Events detected by Fabric
- // 2 = N_Port detected registration
- // 3 = Full registration
-
- // copy back to caller's buff, w/ BIG ENDIAN swap
- BigEndianSwap( (UCHAR*)&scr, payload, sizeof(SCR_PL));
- }
-
- break;
-
-
- case FCS_NSR: // Fabric Name Service Request
- {
- NSR_PL nsr; // Name Server Req. payload
-
- memset( &nsr, 0, sizeof(NSR_PL));
-
- // see Brocade Fabric Programming Guide,
- // Rev 1.3, pg 4-44
- nsr.CT_Rev = 0x01000000;
- nsr.FCS_Type = 0xFC020000;
- nsr.Command_code = 0x01710000;
- nsr.FCP = 8;
-
- // copy back to caller's buff, w/ BIG ENDIAN swap
- BigEndianSwap( (UCHAR*)&nsr, payload, sizeof(NSR_PL));
- }
-
- break;
-
-
-
-
- case ELS_LOGO: // FC-PH PORT LogOut
- logo = &LogoutPayload; // load into stack buffer,
- // then BIG-ENDIAN switch a copy to caller
- logo->cmd = LS_LOGO;
- // load the 3 UCHARs of the node name
- // (if private loop, upper two UCHARs 0)
- logo->reserved = 0;
-
- logo->n_port_identifier[0] = (UCHAR)(fcChip->Registers.my_al_pa);
- logo->n_port_identifier[1] =
- (UCHAR)(fcChip->Registers.my_al_pa>>8);
- logo->n_port_identifier[2] =
- (UCHAR)(fcChip->Registers.my_al_pa>>16);
- // fill in with World Wide Name based Port Name - 8 UCHARs
- // get from Tach registers WWN hi & lo
- LoadWWN( fcChip, logo->port_name, 0);
-
- BigEndianSwap( (UCHAR*)&LogoutPayload,
- payload, sizeof(LogoutPayload) ); // 16 UCHAR struct
- break;
-
-
- case ELS_LOGO_ACC: // Logout Accept (FH-PH pg 149, table 74)
- logo = &LogoutPayload; // load into stack buffer,
- // then BIG-ENDIAN switch a copy to caller
- logo->cmd = LS_ACC;
- BigEndianSwap( (UCHAR*)&LogoutPayload, payload, 4 ); // 4 UCHAR cmnd
- break;
-
-
- case ELS_RJT: // ELS_RJT link service reject (FH-PH pg 155)
-
- prjt = (REJECT_MESSAGE*)payload; // pick up passed data
- rjt.command_code = ELS_RJT;
- // reverse fields, because of Swap that follows...
- rjt.vendor = prjt->reserved; // vendor specific
- rjt.explain = prjt->reason; //
- rjt.reason = prjt->explain; //
- rjt.reserved = prjt->vendor; //
- // BIG-ENDIAN switch a copy to caller
- BigEndianSwap( (UCHAR*)&rjt, payload, 8 ); // 8 UCHAR cmnd
- break;
-
-
-
-
-
- case ELS_PRLI_ACC: // Process Login ACCept
- case ELS_PRLI: // Process Login
- case ELS_PRLO: // Process Logout
- memset( &PrliPayload, 0, sizeof( PrliPayload));
- prli = &PrliPayload; // load into stack buffer,
-
- if( type == ELS_PRLI )
- prli->cmd = 0x20; // Login
- else if( type == ELS_PRLO )
- prli->cmd = 0x21; // Logout
- else if( type == ELS_PRLI_ACC )
- {
- prli->cmd = 0x02; // Login ACCept
- prli->valid = REQUEST_EXECUTED;
- }
-
-
- prli->valid |= SCSI_FCP | ESTABLISH_PAIR;
- prli->fcp_info = READ_XFER_RDY;
- prli->page_length = 0x10;
- prli->payload_length = 20;
- // Can be initiator AND target
-
- if( fcChip->Options.initiator )
- prli->fcp_info |= INITIATOR_FUNCTION;
- if( fcChip->Options.target )
- prli->fcp_info |= TARGET_FUNCTION;
-
- BigEndianSwap( (UCHAR*)&PrliPayload, payload, prli->payload_length);
- break;
-
-
-
- default: // no can do - programming error
- printk(" BuildLinkServicePayload unknown!\n");
- break;
- }
-}
-
-// loads 8 UCHARs for PORT name or NODE name base on
-// controller's WWN.
-void LoadWWN( PTACHYON fcChip, UCHAR* dest, UCHAR type)
-{
- UCHAR* bPtr, i;
-
- switch( type )
- {
- case 0: // Port_Name
- bPtr = (UCHAR*)&fcChip->Registers.wwn_hi;
- for( i =0; i<4; i++)
- dest[i] = *bPtr++;
- bPtr = (UCHAR*)&fcChip->Registers.wwn_lo;
- for( i =4; i<8; i++)
- dest[i] = *bPtr++;
- break;
- case 1: // Node/Fabric _Name
- bPtr = (UCHAR*)&fcChip->Registers.wwn_hi;
- for( i =0; i<4; i++)
- dest[i] = *bPtr++;
- bPtr = (UCHAR*)&fcChip->Registers.wwn_lo;
- for( i =4; i<8; i++)
- dest[i] = *bPtr++;
- break;
- }
-
-}
-
-
-
-// We check the Port Login payload for required values. Note that
-// ELS_PLOGI and ELS_PDISC (Port DISCover) use the same payload.
-
-
-int verify_PLOGI( PTACHYON fcChip,
- TachFCHDR_GCMND* fchs,
- ULONG* reject_explain)
-{
- LOGIN_PAYLOAD login;
-
- // source, dest, len (should be mult. of 4)
- BigEndianSwap( (UCHAR*)&fchs->pl[0], (UCHAR*)&login, sizeof(login));
-
- // check FC version
- // if other port's highest supported version
- // is less than our lowest, and
- // if other port's lowest
- if( login.cmn_services.highest_ver < fcChip->lowest_FCPH_ver ||
- login.cmn_services.lowest_ver > fcChip->highest_FCPH_ver )
- {
- *reject_explain = LS_RJT_REASON( LOGICAL_ERROR, OPTIONS_ERROR);
- return LOGICAL_ERROR;
- }
-
- // Receive Data Field Size must be >=128
- // per FC-PH
- if (login.cmn_services.bb_rx_size < 128)
- {
- *reject_explain = LS_RJT_REASON( LOGICAL_ERROR, DATA_FIELD_SIZE_ERROR);
- return LOGICAL_ERROR;
- }
-
- // Only check Class 3 params
- if( login.class3.service_options & CLASS_VALID)
- {
- if (login.class3.rx_data_size < 128)
- {
- *reject_explain = LS_RJT_REASON( LOGICAL_ERROR, INVALID_CSP);
- return LOGICAL_ERROR;
- }
- if( login.class3.initiator_control & XID_REQUIRED)
- {
- *reject_explain = LS_RJT_REASON( LOGICAL_ERROR, INITIATOR_CTL_ERROR);
- return LOGICAL_ERROR;
- }
- }
- return 0; // success
-}
-
-
-
-
-int verify_PRLI( TachFCHDR_GCMND* fchs, ULONG* reject_explain)
-{
- PRLI_REQUEST prli; // buffer for BIG ENDIAN
-
- // source, dest, len (should be mult. of 4)
- BigEndianSwap( (UCHAR*)&fchs->pl[0], (UCHAR*)&prli, sizeof(prli));
-
- if( prli.fcp_info == 0 ) // i.e., not target or initiator?
- {
- *reject_explain = LS_RJT_REASON( LOGICAL_ERROR, OPTIONS_ERROR);
- return LOGICAL_ERROR;
- }
-
- return 0; // success
-}
-
-
-// SWAP UCHARs as required by Fibre Channel (i.e. BIG ENDIAN)
-// INPUTS:
-// source - ptr to LITTLE ENDIAN ULONGS
-// cnt - number of UCHARs to switch (should be mult. of ULONG)
-// OUTPUTS:
-// dest - ptr to BIG ENDIAN copy
-// RETURN:
-// none
-//
-void BigEndianSwap( UCHAR *source, UCHAR *dest, USHORT cnt)
-{
- int i,j;
-
- source+=3; // start at MSB of 1st ULONG
- for( j=0; j < cnt; j+=4, source+=4, dest+=4) // every ULONG
- {
- for( i=0; i<4; i++) // every UCHAR in ULONG
- *(dest+i) = *(source-i);
- }
-}
-
-
-
-
-// Build FC Exchanges............
-
-static void buildFCPstatus(
- PTACHYON fcChip,
- ULONG ExchangeID);
-
-static LONG FindFreeExchange( PTACHYON fcChip, ULONG type );
-
-static ULONG build_SEST_sgList(
- struct pci_dev *pcidev,
- ULONG *SESTalPairStart,
- Scsi_Cmnd *Cmnd,
- ULONG *sgPairs,
- PSGPAGES *sgPages_head // link list of TL Ext. S/G pages from O/S Pool
-);
-
-static int build_FCP_payload( Scsi_Cmnd *Cmnd,
- UCHAR* payload, ULONG type, ULONG fcp_dl );
-
-
-/*
- IRB
- ERQ __________________
- | | / | Req_A_SFS_Len | ____________________
- |----------| / | Req_A_SFS_Addr |------->| Reserved |
- | IRB | / | Req_A_D_ID | | SOF EOF TimeStamp |
- |-----------/ | Req_A_SEST_Index |-+ | R_CTL | D_ID |
- | IRB | | Req_B... | | | CS_CTL| S_ID |
- |-----------\ | | | | TYPE | F_CTL |
- | IRB | \ | | | | SEQ_ID | SEQ_CNT |
- |----------- \ | | +-->+--| OX_ID | RX_ID |
- | | \ |__________________| | | RO |
- | | pl (payload/cmnd) |
- | | ..... |
- | |___________________|
- |
- |
-+-------------------------------------------+
-|
-|
-| e.g. IWE
-| SEST __________________ for FCP_DATA
-| | | / | | Hdr_Len | ____________________
-| |----------| / | Hdr_Addr_Addr |------->| Reserved |
-| | [0] | / |Remote_ID| RSP_Len| | SOF EOF TimeStamp |
-| |-----------/ | RSP_Addr |---+ | R_CTL | D_ID |
-+-> [1] | | | Buff_Off | | | CS_CTL| S_ID |
- |-----------\ |BuffIndex| Link | | | TYPE | F_CTL |
- | [2] | \ | Rsvd | RX_ID | | | SEQ_ID | SEQ_CNT |
- |----------- \ | Data_Len | | | OX_ID | RX_ID |
- | ... | \ | Exp_RO | | | RO |
- |----------| | Exp_Byte_Cnt | | |___________________|
- | SEST_LEN | +--| Len | |
- |__________| | | Address | |
- | | ... | | for FCP_RSP
- | |__________________| | ____________________
- | +----| Reserved |
- | | SOF EOF TimeStamp |
- | | R_CTL | D_ID |
- | | CS_CTL| S_ID |
- +--- local or extended | .... |
- scatter/gather lists
- defining upper-layer
- data (e.g. from user's App)
-
-
-*/
-// All TachLite commands must start with a SFS (Single Frame Sequence)
-// command. In the simplest case (a NOP Basic Link command),
-// only one frame header and ERQ entry is required. The most complex
-// case is the SCSI assisted command, which requires an ERQ entry,
-// SEST entry, and several frame headers and data buffers all
-// logically linked together.
-// Inputs:
-// cpqfcHBAdata - controller struct
-// type - PLOGI, SCSI_IWE, etc.
-// InFCHS - Incoming Tachlite FCHS which prompted this exchange
-// (only s_id set if we are originating)
-// Data - PVOID to data struct consistent with "type"
-// fcExchangeIndex - pointer to OX/RD ID value of built exchange
-// Return:
-// fcExchangeIndex - OX/RD ID value if successful
-// 0 - success
-// INVALID_ARGS - NULL/ invalid passed args
-// BAD_ALPA - Bad source al_pa address
-// LNKDWN_OSLS - Link Down (according to this controller)
-// OUTQUE_FULL - Outbound Que full
-// DRIVERQ_FULL - controller's Exchange array full
-// SEST_FULL - SEST table full
-//
-// Remarks:
-// Psuedo code:
-// Check for NULL pointers / bad args
-// Build outgoing FCHS - the header/payload struct
-// Build IRB (for ERQ entry)
-// if SCSI command, build SEST entry (e.g. IWE, TRE,...)
-// return success
-
-//sbuildex
-ULONG cpqfcTSBuildExchange(
- CPQFCHBA *cpqfcHBAdata,
- ULONG type, // e.g. PLOGI
- TachFCHDR_GCMND* InFCHS, // incoming FCHS
- void *Data, // the CDB, scatter/gather, etc.
- LONG *fcExchangeIndex ) // points to allocated exchange,
-{
- PTACHYON fcChip = &cpqfcHBAdata->fcChip;
- FC_EXCHANGES *Exchanges = fcChip->Exchanges;
- ULONG ulStatus = 0; // assume OK
- USHORT ox_ID, rx_ID=0xFFFF;
- ULONG SfsLen=0L;
- TachLiteIRB* pIRB;
- IRBflags IRB_flags;
- UCHAR *pIRB_flags = (UCHAR*)&IRB_flags;
- TachFCHDR_GCMND* CMDfchs;
- TachFCHDR* dataHDR; // 32 byte HEADER ONLY FCP-DATA buffer
- TachFCHDR_RSP* rspHDR; // 32 byte header + RSP payload
- Scsi_Cmnd *Cmnd = (Scsi_Cmnd*)Data; // Linux Scsi CDB, S/G, ...
- TachLiteIWE* pIWE;
- TachLiteIRE* pIRE;
- TachLiteTWE* pTWE;
- TachLiteTRE* pTRE;
- ULONG fcp_dl; // total byte length of DATA transferred
- ULONG fl; // frame length (FC frame size, 128, 256, 512, 1024)
- ULONG sgPairs; // number of valid scatter/gather pairs
- int FCP_SCSI_command;
- BA_ACC_PAYLOAD *ba_acc;
- BA_RJT_PAYLOAD *ba_rjt;
-
- // check passed ARGS
- if( !fcChip->ERQ ) // NULL ptr means uninitialized Tachlite chip
- return INVALID_ARGS;
-
-
- if( type == SCSI_IRE ||
- type == SCSI_TRE ||
- type == SCSI_IWE ||
- type == SCSI_TWE)
- FCP_SCSI_command = 1;
-
- else
- FCP_SCSI_command = 0;
-
-
- // for commands that pass payload data (e.g. SCSI write)
- // examine command struct - verify that the
- // length of s/g buffers is adequate for total payload
- // length (end of list is NULL address)
-
- if( FCP_SCSI_command )
- {
- if( Data ) // must have data descriptor (S/G list -- at least
- // one address with at least 1 byte of data)
- {
- // something to do (later)?
- }
-
- else
- return INVALID_ARGS; // invalid DATA ptr
- }
-
-
-
- // we can build an Exchange for later Queuing (on the TL chip)
- // if an empty slot is available in the DevExt for this controller
- // look for available Exchange slot...
-
- if( type != FCP_RESPONSE &&
- type != BLS_ABTS &&
- type != BLS_ABTS_ACC ) // already have Exchange slot!
- *fcExchangeIndex = FindFreeExchange( fcChip, type );
-
- if( *fcExchangeIndex != -1 ) // Exchange is available?
- {
- // assign tmp ptr (shorthand)
- CMDfchs = &Exchanges->fcExchange[ *fcExchangeIndex].fchs;
-
- if( Cmnd != NULL ) // (necessary for ABTS cases)
- {
- Exchanges->fcExchange[ *fcExchangeIndex].Cmnd = Cmnd; // Linux Scsi
- Exchanges->fcExchange[ *fcExchangeIndex].pLoggedInPort =
- fcFindLoggedInPort( fcChip,
- Exchanges->fcExchange[ *fcExchangeIndex].Cmnd, // find Scsi Nexus
- 0, // DON'T search linked list for FC port id
- NULL, // DON'T search linked list for FC WWN
- NULL); // DON'T care about end of list
-
- }
-
-
- // Build the command frame header (& data) according
- // to command type
-
- // fields common for all SFS frame types
- CMDfchs->reserved = 0L; // must clear
- CMDfchs->sof_eof = 0x75000000L; // SOFi3:EOFn no UAM; LCr=0, no TS
-
- // get the destination port_id from incoming FCHS
- // (initialized before calling if we're Originator)
- // Frame goes to port it was from - the source_id
-
- CMDfchs->d_id = InFCHS->s_id &0xFFFFFF; // destination (add R_CTL later)
- CMDfchs->s_id = fcChip->Registers.my_al_pa; // CS_CTL = 0
-
-
- // now enter command-specific fields
- switch( type )
- {
-
- case BLS_NOP: // FC defined basic link service command NO-OP
- // ensure unique X_IDs! (use tracking function)
-
- *pIRB_flags = 0; // clear IRB flags
- IRB_flags.SFA = 1; // send SFS (not SEST index)
- SfsLen = *pIRB_flags;
-
- SfsLen <<= 24; // shift flags to MSB
- SfsLen += 32L; // add len to LSB (header only - no payload)
-
- // TYPE[31-24] 00 Basic Link Service
- // f_ctl[23:0] exchg originator, 1st seq, xfer S.I.
- CMDfchs->d_id |= 0x80000000L; // R_CTL = 80 for NOP (Basic Link Ser.)
- CMDfchs->f_ctl = 0x00310000L; // xchng originator, 1st seq,....
- CMDfchs->seq_cnt = 0x0L;
- CMDfchs->ox_rx_id = 0xFFFF; // RX_ID for now; OX_ID on start
- CMDfchs->ro = 0x0L; // relative offset (n/a)
- CMDfchs->pl[0] = 0xaabbccddL; // words 8-15 frame data payload (n/a)
- Exchanges->fcExchange[ *fcExchangeIndex].timeOut = 1; // seconds
- // (NOP should complete ~instantly)
- break;
-
-
-
-
- case BLS_ABTS_ACC: // Abort Sequence ACCept
- *pIRB_flags = 0; // clear IRB flags
- IRB_flags.SFA = 1; // send SFS (not SEST index)
- SfsLen = *pIRB_flags;
-
- SfsLen <<= 24; // shift flags to MSB
- SfsLen += 32 + 12; // add len to LSB (header + 3 DWORD payload)
-
- CMDfchs->d_id |= 0x84000000L; // R_CTL = 84 for BASIC ACCept
- // TYPE[31-24] 00 Basic Link Service
- // f_ctl[23:0] exchg originator, not 1st seq, xfer S.I.
- CMDfchs->f_ctl = 0x00910000L; // xchnge responder, last seq, xfer SI
- // CMDfchs->seq_id & count might be set from DataHdr?
- CMDfchs->ro = 0x0L; // relative offset (n/a)
- Exchanges->fcExchange[ *fcExchangeIndex].timeOut = 5; // seconds
- // (Timeout in case of weird error)
-
- // now set the ACCept payload...
- ba_acc = (BA_ACC_PAYLOAD*)&CMDfchs->pl[0];
- memset( ba_acc, 0, sizeof( BA_ACC_PAYLOAD));
- // Since PLDA requires (only) entire Exchange aborts, we don't need
- // to worry about what the last sequence was.
-
- // We expect that a "target" task is accepting the abort, so we
- // can use the OX/RX ID pair
- ba_acc->ox_rx_id = CMDfchs->ox_rx_id;
-
- // source, dest, #bytes
- BigEndianSwap((UCHAR *)&CMDfchs->ox_rx_id, (UCHAR *)&ba_acc->ox_rx_id, 4);
-
- ba_acc->low_seq_cnt = 0;
- ba_acc->high_seq_cnt = 0xFFFF;
-
-
- break;
-
-
- case BLS_ABTS_RJT: // Abort Sequence ACCept
- *pIRB_flags = 0; // clear IRB flags
- IRB_flags.SFA = 1; // send SFS (not SEST index)
- SfsLen = *pIRB_flags;
-
- SfsLen <<= 24; // shift flags to MSB
- SfsLen += 32 + 12; // add len to LSB (header + 3 DWORD payload)
-
- CMDfchs->d_id |= 0x85000000L; // R_CTL = 85 for BASIC ReJecT
- // f_ctl[23:0] exchg originator, not 1st seq, xfer S.I.
- // TYPE[31-24] 00 Basic Link Service
- CMDfchs->f_ctl = 0x00910000L; // xchnge responder, last seq, xfer SI
- // CMDfchs->seq_id & count might be set from DataHdr?
- CMDfchs->ro = 0x0L; // relative offset (n/a)
- Exchanges->fcExchange[ *fcExchangeIndex].timeOut = 5; // seconds
- // (Timeout in case of weird error)
-
- CMDfchs->ox_rx_id = InFCHS->ox_rx_id; // copy from sender!
-
- // now set the ReJecT payload...
- ba_rjt = (BA_RJT_PAYLOAD*)&CMDfchs->pl[0];
- memset( ba_rjt, 0, sizeof( BA_RJT_PAYLOAD));
-
- // We expect that a "target" task couldn't find the Exhange in the
- // array of active exchanges, so we use a new LinkService X_ID.
- // See Reject payload description in FC-PH (Rev 4.3), pg. 140
- ba_rjt->reason_code = 0x09; // "unable to perform command request"
- ba_rjt->reason_explain = 0x03; // invalid OX/RX ID pair
-
-
- break;
-
-
- case BLS_ABTS: // FC defined basic link service command ABTS
- // Abort Sequence
-
-
- *pIRB_flags = 0; // clear IRB flags
- IRB_flags.SFA = 1; // send SFS (not SEST index)
- SfsLen = *pIRB_flags;
-
- SfsLen <<= 24; // shift flags to MSB
- SfsLen += 32L; // add len to LSB (header only - no payload)
-
- // TYPE[31-24] 00 Basic Link Service
- // f_ctl[23:0] exchg originator, not 1st seq, xfer S.I.
- CMDfchs->d_id |= 0x81000000L; // R_CTL = 81 for ABTS
- CMDfchs->f_ctl = 0x00110000L; // xchnge originator, last seq, xfer SI
- // CMDfchs->seq_id & count might be set from DataHdr?
- CMDfchs->ro = 0x0L; // relative offset (n/a)
- Exchanges->fcExchange[ *fcExchangeIndex].timeOut = 2; // seconds
- // (ABTS must timeout when responder is gone)
- break;
-
-
-
- case FCS_NSR: // Fabric Name Service Request
- Exchanges->fcExchange[ *fcExchangeIndex].reTries = 2;
-
-
- Exchanges->fcExchange[ *fcExchangeIndex].timeOut = 2; // seconds
- // OX_ID, linked to Driver Transaction ID
- // (fix-up at Queing time)
- CMDfchs->ox_rx_id = 0xFFFF; // RX_ID - Responder (target) to modify
- // OX_ID set at ERQueing time
- *pIRB_flags = 0; // clear IRB flags
- IRB_flags.SFA = 1; // send SFS (not SEST index)
- SfsLen = *pIRB_flags;
-
- SfsLen <<= 24; // shift flags to MSB
- SfsLen += (32L + sizeof(NSR_PL)); // add len (header & NSR payload)
-
- CMDfchs->d_id |= 0x02000000L; // R_CTL = 02 for -
- // Name Service Request: Unsolicited
- // TYPE[31-24] 01 Extended Link Service
- // f_ctl[23:0] exchg originator, 1st seq, xfer S.I.
- CMDfchs->f_ctl = 0x20210000L;
- // OX_ID will be fixed-up at Tachyon enqueing time
- CMDfchs->seq_cnt = 0; // seq ID, DF_ctl, seq cnt
- CMDfchs->ro = 0x0L; // relative offset (n/a)
-
- BuildLinkServicePayload( fcChip, type, &CMDfchs->pl[0]);
-
-
-
-
-
-
- break;
-
-
-
-
- case ELS_PLOGI: // FC-PH extended link service command Port Login
- // (May, 2000)
- // NOTE! This special case facilitates SANMark testing. The SANMark
- // test script for initialization-timeout.fcal.SANMark-1.fc
- // "eats" the OPN() primitive without issuing an R_RDY, causing
- // Tachyon to report LST (loop state timeout), which causes a
- // LIP. To avoid this, simply send out the frame (i.e. assuming a
- // buffer credit of 1) without waiting for R_RDY. Many FC devices
- // (other than Tachyon) have been doing this for years. We don't
- // ever want to do this for non-Link Service frames unless the
- // other device really did report non-zero login BB credit (i.e.
- // in the PLOGI ACCept frame).
-// CMDfchs->sof_eof |= 0x00000400L; // LCr=1
-
- case ELS_FDISC: // Fabric Discovery (Login)
- case ELS_FLOGI: // Fabric Login
- case ELS_SCR: // Fabric State Change Registration
- case ELS_LOGO: // FC-PH extended link service command Port Logout
- case ELS_PDISC: // FC-PH extended link service cmnd Port Discovery
- case ELS_PRLI: // FC-PH extended link service cmnd Process Login
-
- Exchanges->fcExchange[ *fcExchangeIndex].reTries = 2;
-
-
- Exchanges->fcExchange[ *fcExchangeIndex].timeOut = 2; // seconds
- // OX_ID, linked to Driver Transaction ID
- // (fix-up at Queing time)
- CMDfchs->ox_rx_id = 0xFFFF; // RX_ID - Responder (target) to modify
- // OX_ID set at ERQueing time
- *pIRB_flags = 0; // clear IRB flags
- IRB_flags.SFA = 1; // send SFS (not SEST index)
- SfsLen = *pIRB_flags;
-
- SfsLen <<= 24; // shift flags to MSB
- if( type == ELS_LOGO )
- SfsLen += (32L + 16L); // add len (header & PLOGI payload)
- else if( type == ELS_PRLI )
- SfsLen += (32L + 20L); // add len (header & PRLI payload)
- else if( type == ELS_SCR )
- SfsLen += (32L + sizeof(SCR_PL)); // add len (header & SCR payload)
- else
- SfsLen += (32L + 116L); // add len (header & PLOGI payload)
-
- CMDfchs->d_id |= 0x22000000L; // R_CTL = 22 for -
- // Extended Link_Data: Unsolicited Control
- // TYPE[31-24] 01 Extended Link Service
- // f_ctl[23:0] exchg originator, 1st seq, xfer S.I.
- CMDfchs->f_ctl = 0x01210000L;
- // OX_ID will be fixed-up at Tachyon enqueing time
- CMDfchs->seq_cnt = 0; // seq ID, DF_ctl, seq cnt
- CMDfchs->ro = 0x0L; // relative offset (n/a)
-
- BuildLinkServicePayload( fcChip, type, &CMDfchs->pl[0]);
-
- break;
-
-
-
- case ELS_LOGO_ACC: // FC-PH extended link service logout accept
- case ELS_RJT: // extended link service reject (add reason)
- case ELS_ACC: // ext. link service generic accept
- case ELS_PLOGI_ACC:// ext. link service login accept (PLOGI or PDISC)
- case ELS_PRLI_ACC: // ext. link service process login accept
-
-
- Exchanges->fcExchange[ *fcExchangeIndex].timeOut = 1; // assume done
- // ensure unique X_IDs! (use tracking function)
- // OX_ID from initiator cmd
- ox_ID = (USHORT)(InFCHS->ox_rx_id >> 16);
- rx_ID = 0xFFFF; // RX_ID, linked to Driver Exchange ID
-
- *pIRB_flags = 0; // clear IRB flags
- IRB_flags.SFA = 1; // send SFS (not SEST index)
- SfsLen = *pIRB_flags;
-
- SfsLen <<= 24; // shift flags to MSB
- if( type == ELS_RJT )
- {
- SfsLen += (32L + 8L); // add len (header + payload)
-
- // ELS_RJT reason codes (utilize unused "reserved" field)
- CMDfchs->pl[0] = 1;
- CMDfchs->pl[1] = InFCHS->reserved;
-
- }
- else if( (type == ELS_LOGO_ACC) || (type == ELS_ACC) )
- SfsLen += (32L + 4L); // add len (header + payload)
- else if( type == ELS_PLOGI_ACC )
- SfsLen += (32L + 116L); // add len (header + payload)
- else if( type == ELS_PRLI_ACC )
- SfsLen += (32L + 20L); // add len (header + payload)
-
- CMDfchs->d_id |= 0x23000000L; // R_CTL = 23 for -
- // Extended Link_Data: Control Reply
- // TYPE[31-24] 01 Extended Link Service
- // f_ctl[23:0] exchg responder, last seq, e_s, tsi
- CMDfchs->f_ctl = 0x01990000L;
- CMDfchs->seq_cnt = 0x0L;
- CMDfchs->ox_rx_id = 0L; // clear
- CMDfchs->ox_rx_id = ox_ID; // load upper 16 bits
- CMDfchs->ox_rx_id <<= 16; // shift them
-
- CMDfchs->ro = 0x0L; // relative offset (n/a)
-
- BuildLinkServicePayload( fcChip, type, &CMDfchs->pl[0]);
-
- break;
-
-
- // Fibre Channel SCSI 'originator' sequences...
- // (originator means 'initiator' in FCP-SCSI)
-
- case SCSI_IWE: // TachLite Initiator Write Entry
- {
- PFC_LOGGEDIN_PORT pLoggedInPort =
- Exchanges->fcExchange[ *fcExchangeIndex].pLoggedInPort;
-
- Exchanges->fcExchange[ *fcExchangeIndex].reTries = 1;
- Exchanges->fcExchange[ *fcExchangeIndex].timeOut = 7; // FC2 timeout
-
- // first, build FCP_CMND
- // unique X_ID fix-ups in StartExchange
-
- *pIRB_flags = 0; // clear IRB flags
- IRB_flags.SFA = 1; // send SFS FCP-CMND (not SEST index)
-
- // NOTE: unlike FC LinkService login frames, normal
- // SCSI commands are sent without outgoing verification
- IRB_flags.DCM = 1; // Disable completion message for Cmnd frame
- SfsLen = *pIRB_flags;
-
- SfsLen <<= 24; // shift flags to MSB
- SfsLen += 64L; // add len to LSB (header & CMND payload)
-
- CMDfchs->d_id |= (0x06000000L); // R_CTL = 6 for command
-
- // TYPE[31-24] 8 for FCP SCSI
- // f_ctl[23:0] exchg originator, 1st seq, xfer S.I.
- // valid RO
- CMDfchs->f_ctl = 0x08210008L;
- CMDfchs->seq_cnt = 0x0L;
- CMDfchs->ox_rx_id = 0L; // clear for now (-or- in later)
- CMDfchs->ro = 0x0L; // relative offset (n/a)
-
- // now, fill out FCP-DATA header
- // (use buffer inside SEST object)
- dataHDR = &fcChip->SEST->DataHDR[ *fcExchangeIndex ];
- dataHDR->reserved = 0L; // must clear
- dataHDR->sof_eof = 0x75002000L; // SOFi3:EOFn no UAM; no CLS, noLCr, no TS
- dataHDR->d_id = (InFCHS->s_id | 0x01000000L); // R_CTL= FCP_DATA
- dataHDR->s_id = fcChip->Registers.my_al_pa; // CS_CTL = 0
- // TYPE[31-24] 8 for FCP SCSI
- // f_ctl[23:0] xfer S.I.| valid RO
- dataHDR->f_ctl = 0x08010008L;
- dataHDR->seq_cnt = 0x02000000L; // sequence ID: df_ctl : seqence count
- dataHDR->ox_rx_id = 0L; // clear; fix-up dataHDR fields later
- dataHDR->ro = 0x0L; // relative offset (n/a)
-
- // Now setup the SEST entry
- pIWE = &fcChip->SEST->u[ *fcExchangeIndex ].IWE;
-
- // fill out the IWE:
-
- // VALid entry:Dir outbound:DCM:enable CM:enal INT: FC frame len
- pIWE->Hdr_Len = 0x8e000020L; // data frame Len always 32 bytes
-
-
- // from login parameters with other port, what's the largest frame
- // we can send?
- if( pLoggedInPort == NULL)
- {
- ulStatus = INVALID_ARGS; // failed! give up
- break;
- }
- if( pLoggedInPort->rx_data_size >= 2048)
- fl = 0x00020000; // 2048 code (only support 1024!)
- else if( pLoggedInPort->rx_data_size >= 1024)
- fl = 0x00020000; // 1024 code
- else if( pLoggedInPort->rx_data_size >= 512)
- fl = 0x00010000; // 512 code
- else
- fl = 0; // 128 bytes -- should never happen
-
-
- pIWE->Hdr_Len |= fl; // add xmit FC frame len for data phase
- pIWE->Hdr_Addr = fcChip->SEST->base +
- ((unsigned long)&fcChip->SEST->DataHDR[*fcExchangeIndex] -
- (unsigned long)fcChip->SEST);
-
- pIWE->RSP_Len = sizeof(TachFCHDR_RSP) ; // hdr+data (recv'd RSP frame)
- pIWE->RSP_Len |= (InFCHS->s_id << 8); // MS 24 bits Remote_ID
-
- memset( &fcChip->SEST->RspHDR[ *fcExchangeIndex].pl, 0,
- sizeof( FCP_STATUS_RESPONSE) ); // clear out previous status
-
- pIWE->RSP_Addr = fcChip->SEST->base +
- ((unsigned long)&fcChip->SEST->RspHDR[*fcExchangeIndex] -
- (unsigned long)fcChip->SEST);
-
- // Do we need local or extended gather list?
- // depends on size - we can handle 3 len/addr pairs
- // locally.
-
- fcp_dl = build_SEST_sgList(
- cpqfcHBAdata->PciDev,
- &pIWE->GLen1,
- Cmnd, // S/G list
- &sgPairs, // return # of pairs in S/G list (from "Data" descriptor)
- &fcChip->SEST->sgPages[ *fcExchangeIndex ]);// (for Freeing later)
-
- if( !fcp_dl ) // error building S/G list?
- {
- ulStatus = MEMPOOL_FAIL;
- break; // give up
- }
-
- // Now that we know total data length in
- // the passed S/G buffer, set FCP CMND frame
- build_FCP_payload( Cmnd, (UCHAR*)&CMDfchs->pl[0], type, fcp_dl );
-
-
-
- if( sgPairs > 3 ) // need extended s/g list
- pIWE->Buff_Off = 0x78000000L; // extended data | (no offset)
- else // local data pointers (in SEST)
- pIWE->Buff_Off = 0xf8000000L; // local data | (no offset)
-
- // ULONG 5
- pIWE->Link = 0x0000ffffL; // Buff_Index | Link
-
- pIWE->RX_ID = 0x0L; // DWord 6: RX_ID set by target XFER_RDY
-
- // DWord 7
- pIWE->Data_Len = 0L; // TL enters rcv'd XFER_RDY BURST_LEN
- pIWE->Exp_RO = 0L; // DWord 8
- // DWord 9
- pIWE->Exp_Byte_Cnt = fcp_dl; // sum of gather buffers
- }
- break;
-
-
-
-
-
- case SCSI_IRE: // TachLite Initiator Read Entry
-
- if( Cmnd->timeout != 0)
- {
-// printk("Cmnd->timeout %d\n", Cmnd->timeout);
- // per Linux Scsi
- Exchanges->fcExchange[ *fcExchangeIndex].timeOut = Cmnd->timeout;
- }
- else // use our best guess, based on FC & device
- {
-
- if( Cmnd->SCp.Message == 1 ) // Tape device? (from INQUIRY)
- {
- // turn off our timeouts (for now...)
- Exchanges->fcExchange[ *fcExchangeIndex].timeOut = 0xFFFFFFFF;
- }
- else
- {
- Exchanges->fcExchange[ *fcExchangeIndex].reTries = 1;
- Exchanges->fcExchange[ *fcExchangeIndex].timeOut = 7; // per SCSI req.
- }
- }
-
-
- // first, build FCP_CMND
-
-
- *pIRB_flags = 0; // clear IRB flags
- IRB_flags.SFA = 1; // send SFS FCP-CMND (not SEST index)
- // NOTE: unlike FC LinkService login frames,
- // normal SCSI commands are sent "open loop"
- IRB_flags.DCM = 1; // Disable completion message for Cmnd frame
- SfsLen = *pIRB_flags;
-
- SfsLen <<= 24; // shift flags to MSB
- SfsLen += 64L; // add len to LSB (header & CMND payload)
-
- CMDfchs->d_id |= (0x06000000L); // R_CTL = 6 for command
-
- // TYPE[31-24] 8 for FCP SCSI
- // f_ctl[23:0] exchg originator, 1st seq, xfer S.I.
- // valid RO
- CMDfchs->f_ctl = 0x08210008L;
- CMDfchs->seq_cnt = 0x0L;
- // x_ID & data direction bit set later
- CMDfchs->ox_rx_id = 0xFFFF; // clear
- CMDfchs->ro = 0x0L; // relative offset (n/a)
-
-
-
- // Now setup the SEST entry
- pIRE = &fcChip->SEST->u[ *fcExchangeIndex ].IRE;
-
- // fill out the IRE:
- // VALid entry:Dir outbound:enable CM:enal INT:
- pIRE->Seq_Accum = 0xCE000000L; // VAL,DIR inbound,DCM| INI,DAT,RSP
-
- pIRE->reserved = 0L;
- pIRE->RSP_Len = sizeof(TachFCHDR_RSP) ; // hdr+data (recv'd RSP frame)
- pIRE->RSP_Len |= (InFCHS->s_id << 8); // MS 24 bits Remote_ID
-
- pIRE->RSP_Addr = fcChip->SEST->base +
- ((unsigned long)&fcChip->SEST->RspHDR[*fcExchangeIndex] -
- (unsigned long)fcChip->SEST);
-
- // Do we need local or extended gather list?
- // depends on size - we can handle 3 len/addr pairs
- // locally.
-
- fcp_dl = build_SEST_sgList(
- cpqfcHBAdata->PciDev,
- &pIRE->SLen1,
- Cmnd, // SCSI command Data desc. with S/G list
- &sgPairs, // return # of pairs in S/G list (from "Data" descriptor)
- &fcChip->SEST->sgPages[ *fcExchangeIndex ]);// (for Freeing later)
-
-
- if( !fcp_dl ) // error building S/G list?
- {
- // It is permissible to have a ZERO LENGTH Read command.
- // If there is the case, simply set fcp_dl (and Exp_Byte_Cnt)
- // to 0 and continue.
- if( Cmnd->request_bufflen == 0 )
- {
- fcp_dl = 0; // no FC DATA frames expected
-
- }
- else
- {
- ulStatus = MEMPOOL_FAIL;
- break; // give up
- }
- }
-
- // now that we know the S/G length, build CMND payload
- build_FCP_payload( Cmnd, (UCHAR*)&CMDfchs->pl[0], type, fcp_dl );
-
-
- if( sgPairs > 3 ) // need extended s/g list
- pIRE->Buff_Off = 0x00000000; // DWord 4: extended s/g list, no offset
- else
- pIRE->Buff_Off = 0x80000000; // local data, no offset
-
- pIRE->Buff_Index = 0x0L; // DWord 5: Buff_Index | Reserved
-
- pIRE->Exp_RO = 0x0L; // DWord 6: Expected Rel. Offset
-
- pIRE->Byte_Count = 0; // DWord 7: filled in by TL on err
- pIRE->reserved_ = 0; // DWord 8: reserved
- // NOTE: 0 length READ is OK.
- pIRE->Exp_Byte_Cnt = fcp_dl;// DWord 9: sum of scatter buffers
-
- break;
-
-
-
-
- // Fibre Channel SCSI 'responder' sequences...
- // (originator means 'target' in FCP-SCSI)
- case SCSI_TWE: // TachLite Target Write Entry
-
- Exchanges->fcExchange[ *fcExchangeIndex].timeOut = 10; // per SCSI req.
-
- // first, build FCP_CMND
-
- *pIRB_flags = 0; // clear IRB flags
- IRB_flags.SFA = 1; // send SFS (XFER_RDY)
- SfsLen = *pIRB_flags;
-
- SfsLen <<= 24; // shift flags to MSB
- SfsLen += (32L + 12L);// add SFS len (header & XFER_RDY payload)
-
- CMDfchs->d_id |= (0x05000000L); // R_CTL = 5 for XFER_RDY
-
- // TYPE[31-24] 8 for FCP SCSI
- // f_ctl[23:0] exchg responder, 1st seq, xfer S.I.
- // valid RO
- CMDfchs->f_ctl = 0x08810008L;
- CMDfchs->seq_cnt = 0x01000000; // sequence ID: df_ctl: sequence count
- // use originator (other port's) OX_ID
- CMDfchs->ox_rx_id = InFCHS->ox_rx_id; // we want upper 16 bits
- CMDfchs->ro = 0x0L; // relative offset (n/a)
-
- // now, fill out FCP-RSP header
- // (use buffer inside SEST object)
-
- rspHDR = &fcChip->SEST->RspHDR[ *fcExchangeIndex ];
- rspHDR->reserved = 0L; // must clear
- rspHDR->sof_eof = 0x75000000L; // SOFi3:EOFn no UAM; no CLS, noLCr, no TS
- rspHDR->d_id = (InFCHS->s_id | 0x07000000L); // R_CTL= FCP_RSP
- rspHDR->s_id = fcChip->Registers.my_al_pa; // CS_CTL = 0
- // TYPE[31-24] 8 for FCP SCSI
- // f_ctl[23:0] responder|last seq| xfer S.I.
- rspHDR->f_ctl = 0x08910000L;
- rspHDR->seq_cnt = 0x03000000; // sequence ID
- rspHDR->ox_rx_id = InFCHS->ox_rx_id; // gives us OX_ID
- rspHDR->ro = 0x0L; // relative offset (n/a)
-
-
- // Now setup the SEST entry
-
- pTWE = &fcChip->SEST->u[ *fcExchangeIndex ].TWE;
-
- // fill out the TWE:
-
- // VALid entry:Dir outbound:enable CM:enal INT:
- pTWE->Seq_Accum = 0xC4000000L; // upper word flags
- pTWE->reserved = 0L;
- pTWE->Remote_Node_ID = 0L; // no more auto RSP frame! (TL/TS change)
- pTWE->Remote_Node_ID |= (InFCHS->s_id << 8); // MS 24 bits Remote_ID
-
-
- // Do we need local or extended gather list?
- // depends on size - we can handle 3 len/addr pairs
- // locally.
-
- fcp_dl = build_SEST_sgList(
- cpqfcHBAdata->PciDev,
- &pTWE->SLen1,
- Cmnd, // S/G list
- &sgPairs, // return # of pairs in S/G list (from "Data" descriptor)
- &fcChip->SEST->sgPages[ *fcExchangeIndex ]);// (for Freeing later)
-
-
- if( !fcp_dl ) // error building S/G list?
- {
- ulStatus = MEMPOOL_FAIL;
- break; // give up
- }
-
- // now that we know the S/G length, build CMND payload
- build_FCP_payload( Cmnd, (UCHAR*)&CMDfchs->pl[0], type, fcp_dl );
-
-
- if( sgPairs > 3 ) // need extended s/g list
- pTWE->Buff_Off = 0x00000000; // extended s/g list, no offset
- else
- pTWE->Buff_Off = 0x80000000; // local data, no offset
-
- pTWE->Buff_Index = 0; // Buff_Index | Link
- pTWE->Exp_RO = 0;
- pTWE->Byte_Count = 0; // filled in by TL on err
- pTWE->reserved_ = 0;
- pTWE->Exp_Byte_Cnt = fcp_dl;// sum of scatter buffers
-
- break;
-
-
-
-
-
-
- case SCSI_TRE: // TachLite Target Read Entry
-
- // It doesn't make much sense for us to "time-out" a READ,
- // but we'll use it for design consistency and internal error recovery.
- Exchanges->fcExchange[ *fcExchangeIndex].timeOut = 10; // per SCSI req.
-
- // I/O request block settings...
- *pIRB_flags = 0; // clear IRB flags
- // check PRLI (process login) info
- // to see if Initiator Requires XFER_RDY
- // if not, don't send one!
- // { PRLI check...}
- IRB_flags.SFA = 0; // don't send XFER_RDY - start data
- SfsLen = *pIRB_flags;
-
- SfsLen <<= 24; // shift flags to MSB
- SfsLen += (32L + 12L);// add SFS len (header & XFER_RDY payload)
-
-
-
- // now, fill out FCP-DATA header
- // (use buffer inside SEST object)
- dataHDR = &fcChip->SEST->DataHDR[ *fcExchangeIndex ];
-
- dataHDR->reserved = 0L; // must clear
- dataHDR->sof_eof = 0x75000000L; // SOFi3:EOFn no UAM; no CLS,noLCr,no TS
- dataHDR->d_id = (InFCHS->s_id | 0x01000000L); // R_CTL= FCP_DATA
- dataHDR->s_id = fcChip->Registers.my_al_pa; // CS_CTL = 0
-
-
- // TYPE[31-24] 8 for FCP SCSI
- // f_ctl[23:0] exchg responder, not 1st seq, xfer S.I.
- // valid RO
- dataHDR->f_ctl = 0x08810008L;
- dataHDR->seq_cnt = 0x01000000; // sequence ID (no XRDY)
- dataHDR->ox_rx_id = InFCHS->ox_rx_id & 0xFFFF0000; // we want upper 16 bits
- dataHDR->ro = 0x0L; // relative offset (n/a)
-
- // now, fill out FCP-RSP header
- // (use buffer inside SEST object)
- rspHDR = &fcChip->SEST->RspHDR[ *fcExchangeIndex ];
-
- rspHDR->reserved = 0L; // must clear
- rspHDR->sof_eof = 0x75000000L; // SOFi3:EOFn no UAM; no CLS, noLCr, no TS
- rspHDR->d_id = (InFCHS->s_id | 0x07000000L); // R_CTL= FCP_RSP
- rspHDR->s_id = fcChip->Registers.my_al_pa; // CS_CTL = 0
- // TYPE[31-24] 8 for FCP SCSI
- // f_ctl[23:0] responder|last seq| xfer S.I.
- rspHDR->f_ctl = 0x08910000L;
- rspHDR->seq_cnt = 0x02000000; // sequence ID: df_ctl: sequence count
-
- rspHDR->ro = 0x0L; // relative offset (n/a)
-
-
- // Now setup the SEST entry
- pTRE = &fcChip->SEST->u[ *fcExchangeIndex ].TRE;
-
-
- // VALid entry:Dir outbound:enable CM:enal INT:
- pTRE->Hdr_Len = 0x86010020L; // data frame Len always 32 bytes
- pTRE->Hdr_Addr = // bus address of dataHDR;
- fcChip->SEST->base +
- ((unsigned long)&fcChip->SEST->DataHDR[ *fcExchangeIndex ] -
- (unsigned long)fcChip->SEST);
-
- pTRE->RSP_Len = 64L; // hdr+data (TL assisted RSP frame)
- pTRE->RSP_Len |= (InFCHS->s_id << 8); // MS 24 bits Remote_ID
- pTRE->RSP_Addr = // bus address of rspHDR
- fcChip->SEST->base +
- ((unsigned long)&fcChip->SEST->RspHDR[ *fcExchangeIndex ] -
- (unsigned long)fcChip->SEST);
-
- // Do we need local or extended gather list?
- // depends on size - we can handle 3 len/addr pairs
- // locally.
-
- fcp_dl = build_SEST_sgList(
- cpqfcHBAdata->PciDev,
- &pTRE->GLen1,
- Cmnd, // S/G list
- &sgPairs, // return # of pairs in S/G list (from "Data" descriptor)
- &fcChip->SEST->sgPages[ *fcExchangeIndex ]);// (for Freeing later)
-
-
- if( !fcp_dl ) // error building S/G list?
- {
- ulStatus = MEMPOOL_FAIL;
- break; // give up
- }
-
- // no payload or command to build -- READ doesn't need XRDY
-
-
- if( sgPairs > 3 ) // need extended s/g list
- pTRE->Buff_Off = 0x78000000L; // extended data | (no offset)
- else // local data pointers (in SEST)
- pTRE->Buff_Off = 0xf8000000L; // local data | (no offset)
-
- // ULONG 5
- pTRE->Buff_Index = 0L; // Buff_Index | reserved
- pTRE->reserved = 0x0L; // DWord 6
-
- // DWord 7: NOTE: zero length will
- // hang TachLite!
- pTRE->Data_Len = fcp_dl; // e.g. sum of scatter buffers
-
- pTRE->reserved_ = 0L; // DWord 8
- pTRE->reserved__ = 0L; // DWord 9
-
- break;
-
-
-
-
-
-
-
- case FCP_RESPONSE:
- // Target response frame: this sequence uses an OX/RX ID
- // pair from a completed SEST exchange. We built most
- // of the response frame when we created the TWE/TRE.
-
- *pIRB_flags = 0; // clear IRB flags
- IRB_flags.SFA = 1; // send SFS (RSP)
- SfsLen = *pIRB_flags;
-
- SfsLen <<= 24; // shift flags to MSB
- SfsLen += sizeof(TachFCHDR_RSP);// add SFS len (header & RSP payload)
-
-
- Exchanges->fcExchange[ *fcExchangeIndex].type =
- FCP_RESPONSE; // change Exchange type to "response" phase
-
- // take advantage of prior knowledge of OX/RX_ID pair from
- // previous XFER outbound frame (still in fchs of exchange)
- fcChip->SEST->RspHDR[ *fcExchangeIndex ].ox_rx_id =
- CMDfchs->ox_rx_id;
-
- // Check the status of the DATA phase of the exchange so we can report
- // status to the initiator
- buildFCPstatus( fcChip, *fcExchangeIndex); // set RSP payload fields
-
- memcpy(
- CMDfchs, // re-use same XFER fchs for Response frame
- &fcChip->SEST->RspHDR[ *fcExchangeIndex ],
- sizeof( TachFCHDR_RSP ));
-
-
- break;
-
- default:
- printk("cpqfcTS: don't know how to build FC type: %Xh(%d)\n", type,type);
- break;
-
- }
-
-
-
- if( !ulStatus) // no errors above?
- {
- // FCHS is built; now build IRB
-
- // link the just built FCHS (the "command") to the IRB entry
- // for this Exchange.
- pIRB = &Exchanges->fcExchange[ *fcExchangeIndex].IRB;
-
- // len & flags according to command type above
- pIRB->Req_A_SFS_Len = SfsLen; // includes IRB flags & len
- pIRB->Req_A_SFS_Addr = // TL needs physical addr of frame to send
- fcChip->exch_dma_handle + (unsigned long)CMDfchs -
- (unsigned long)Exchanges;
-
- pIRB->Req_A_SFS_D_ID = CMDfchs->d_id << 8; // Dest_ID must be consistent!
-
- // Exchange is complete except for "fix-up" fields to be set
- // at Tachyon Queuing time:
- // IRB->Req_A_Trans_ID (OX_ID/ RX_ID):
- // for SEST entry, lower bits correspond to actual FC Exchange ID
- // fchs->OX_ID or RX_ID
- }
- else
- {
-#ifdef DBG
- printk( "FC Error: SEST build Pool Allocation failed\n");
-#endif
- // return resources...
- cpqfcTSCompleteExchange( cpqfcHBAdata->PciDev, fcChip, *fcExchangeIndex); // SEST build failed
- }
- }
- else // no Exchanges available
- {
- ulStatus = SEST_FULL;
- printk( "FC Error: no fcExchanges available\n");
- }
- return ulStatus;
-}
-
-
-
-
-
-
-// set RSP payload fields
-static void buildFCPstatus( PTACHYON fcChip, ULONG ExchangeID)
-{
- FC_EXCHANGES *Exchanges = fcChip->Exchanges;
- FC_EXCHANGE *pExchange = &Exchanges->fcExchange[ExchangeID]; // shorthand
- PFCP_STATUS_RESPONSE pFcpStatus;
-
- memset( &fcChip->SEST->RspHDR[ ExchangeID ].pl, 0,
- sizeof( FCP_STATUS_RESPONSE) );
- if( pExchange->status ) // something wrong?
- {
- pFcpStatus = (PFCP_STATUS_RESPONSE) // cast RSP buffer for this xchng
- &fcChip->SEST->RspHDR[ ExchangeID ].pl;
- if( pExchange->status & COUNT_ERROR )
- {
-
- // set FCP response len valid (so we can report count error)
- pFcpStatus->fcp_status |= FCP_RSP_LEN_VALID;
- pFcpStatus->fcp_rsp_len = 0x04000000; // 4 byte len (BIG Endian)
-
- pFcpStatus->fcp_rsp_info = FCP_DATA_LEN_NOT_BURST_LEN; // RSP_CODE
- }
- }
-}
-
-
-static dma_addr_t
-cpqfc_pci_map_sg_page(
- struct pci_dev *pcidev,
- ULONG *hw_paddr, // where to put phys addr for HW use
- void *sgp_vaddr, // the virtual address of the sg page
- dma_addr_t *umap_paddr, // where to put phys addr for unmap
- unsigned int *maplen, // where to store sg entry length
- int PairCount) // number of sg pairs used in the page.
-{
- unsigned long aligned_addr = (unsigned long) sgp_vaddr;
-
- *maplen = PairCount * 8;
- aligned_addr += TL_EXT_SG_PAGE_BYTELEN;
- aligned_addr &= ~(TL_EXT_SG_PAGE_BYTELEN -1);
-
- *umap_paddr = pci_map_single(pcidev, (void *) aligned_addr,
- *maplen, PCI_DMA_TODEVICE);
- *hw_paddr = (ULONG) *umap_paddr;
-
-# if BITS_PER_LONG > 32
- if( *umap_paddr >>32 ) {
- printk("cqpfcTS:Tach SG DMA addr %p>32 bits\n",
- (void*)umap_paddr);
- return 0;
- }
-# endif
- return *umap_paddr;
-}
-
-static void
-cpqfc_undo_SEST_mappings(struct pci_dev *pcidev,
- unsigned long contigaddr, int len, int dir,
- struct scatterlist *sgl, int use_sg,
- PSGPAGES *sgPages_head,
- int allocated_pages)
-{
- PSGPAGES i, next;
-
- if (contigaddr != (unsigned long) NULL)
- pci_unmap_single(pcidev, contigaddr, len, dir);
-
- if (sgl != NULL)
- pci_unmap_sg(pcidev, sgl, use_sg, dir);
-
- for (i=*sgPages_head; i != NULL ;i = next)
- {
- pci_unmap_single(pcidev, i->busaddr, i->maplen,
- PCI_DMA_TODEVICE);
- i->busaddr = (dma_addr_t) NULL;
- i->maplen = 0L;
- next = i->next;
- kfree(i);
- }
- *sgPages_head = NULL;
-}
-
-// This routine builds scatter/gather lists into SEST entries
-// INPUTS:
-// SESTalPair - SEST address @DWordA "Local Buffer Length"
-// sgList - Scatter/Gather linked list of Len/Address data buffers
-// OUTPUT:
-// sgPairs - number of valid address/length pairs
-// Remarks:
-// The SEST data buffer pointers only depend on number of
-// length/ address pairs, NOT on the type (IWE, TRE,...)
-// Up to 3 pairs can be referenced in the SEST - more than 3
-// require this Extended S/G list page. The page holds 4, 8, 16...
-// len/addr pairs, per Scatter/Gather List Page Length Reg.
-// TachLite allows pages to be linked to any depth.
-
-//#define DBG_SEST_SGLIST 1 // for printing out S/G pairs with Ext. pages
-
-static int ap_hi_water = TL_DANGER_SGPAGES;
-
-static ULONG build_SEST_sgList(
- struct pci_dev *pcidev,
- ULONG *SESTalPairStart, // the 3 len/address buffers in SEST
- Scsi_Cmnd *Cmnd,
- ULONG *sgPairs,
- PSGPAGES *sgPages_head) // link list of TL Ext. S/G pages from O/S Pool
-
-{
- ULONG i, AllocatedPages=0; // Tach Ext. S/G page allocations
- ULONG* alPair = SESTalPairStart;
- ULONG* ext_sg_page_phys_addr_place = NULL;
- int PairCount;
- unsigned long ulBuff, contigaddr;
- ULONG total_data_len=0; // (in bytes)
- ULONG bytes_to_go = Cmnd->request_bufflen; // total xfer (S/G sum)
- ULONG thisMappingLen;
- struct scatterlist *sgl = NULL; // S/G list (Linux format)
- int sg_count, totalsgs;
- dma_addr_t busaddr;
- unsigned long thislen, offset;
- PSGPAGES *sgpage = sgPages_head;
- PSGPAGES prev_page = NULL;
-
-# define WE_HAVE_SG_LIST (sgl != (unsigned long) NULL)
- contigaddr = (unsigned long) NULL;
-
- if( !Cmnd->use_sg ) // no S/G list?
- {
- if (bytes_to_go <= TL_MAX_SG_ELEM_LEN)
- {
- *sgPairs = 1; // use "local" S/G pair in SEST entry
- // (for now, ignore address bits above #31)
-
- *alPair++ = bytes_to_go; // bits 18-0, length
-
- if (bytes_to_go != 0) {
- contigaddr = ulBuff = pci_map_single(pcidev,
- Cmnd->request_buffer,
- Cmnd->request_bufflen,
- Cmnd->sc_data_direction);
- // printk("ms %p ", ulBuff);
- }
- else {
- // No data transfer, (e.g.: Test Unit Ready)
- // printk("btg=0 ");
- *sgPairs = 0;
- memset(alPair, 0, sizeof(*alPair));
- return 0;
- }
-
-# if BITS_PER_LONG > 32
- if( ulBuff >>32 ) {
- printk("FATAL! Tachyon DMA address %p "
- "exceeds 32 bits\n", (void*)ulBuff );
- return 0;
- }
-# endif
- *alPair = (ULONG)ulBuff;
- return bytes_to_go;
- }
- else // We have a single large (too big) contiguous buffer.
- { // We will have to break it up. We'll use the scatter
- // gather code way below, but use contigaddr instead
- // of sg_dma_addr(). (this is a very rare case).
-
- unsigned long btg;
- contigaddr = pci_map_single(pcidev, Cmnd->request_buffer,
- Cmnd->request_bufflen,
- Cmnd->sc_data_direction);
-
- // printk("contigaddr = %p, len = %d\n",
- // (void *) contigaddr, bytes_to_go);
- totalsgs = 0;
- for (btg = bytes_to_go; btg > 0; ) {
- btg -= ( btg > TL_MAX_SG_ELEM_LEN ?
- TL_MAX_SG_ELEM_LEN : btg );
- totalsgs++;
- }
- sgl = NULL;
- *sgPairs = totalsgs;
- }
- }
- else // we do have a scatter gather list
- {
- // [TBD - update for Linux to support > 32 bits addressing]
- // since the format for local & extended S/G lists is different,
- // check if S/G pairs exceeds 3.
- // *sgPairs = Cmnd->use_sg; Nope, that's wrong.
-
- sgl = (struct scatterlist*)Cmnd->request_buffer;
- sg_count = pci_map_sg(pcidev, sgl, Cmnd->use_sg,
- Cmnd->sc_data_direction);
- if( sg_count <= 3 ) {
-
- // we need to be careful here that no individual mapping
- // is too large, and if any is, that breaking it up
- // doesn't push us over 3 sgs, or, if it does, that we
- // handle that case. Tachyon can take 0x7FFFF bits for length,
- // but sg structure uses "unsigned int", on the face of it,
- // up to 0xFFFFFFFF or even more.
-
- int i;
- unsigned long thislen;
-
- totalsgs = 0;
- for (i=0;i<sg_count;i++) {
- thislen = sg_dma_len(&sgl[i]);
- while (thislen >= TL_MAX_SG_ELEM_LEN) {
- totalsgs++;
- thislen -= TL_MAX_SG_ELEM_LEN;
- }
- if (thislen > 0) totalsgs++;
- }
- *sgPairs = totalsgs;
- } else totalsgs = 999; // as a first estimate, definitely >3,
-
- // if (totalsgs != sg_count)
- // printk("totalsgs = %d, sgcount=%d\n",totalsgs,sg_count);
- }
-
- if( totalsgs <= 3 ) // can (must) use "local" SEST list
- {
- while( bytes_to_go)
- {
- offset = 0L;
-
- if ( WE_HAVE_SG_LIST )
- thisMappingLen = sg_dma_len(sgl);
- else // or contiguous buffer?
- thisMappingLen = bytes_to_go;
-
- while (thisMappingLen > 0)
- {
- thislen = thisMappingLen > TL_MAX_SG_ELEM_LEN ?
- TL_MAX_SG_ELEM_LEN : thisMappingLen;
- bytes_to_go = bytes_to_go - thislen;
-
- // we have L/A pair; L = thislen, A = physicalAddress
- // load into SEST...
-
- total_data_len += thislen;
- *alPair = thislen; // bits 18-0, length
-
- alPair++;
-
- if ( WE_HAVE_SG_LIST )
- ulBuff = sg_dma_address(sgl) + offset;
- else
- ulBuff = contigaddr + offset;
-
- offset += thislen;
-
-# if BITS_PER_LONG > 32
- if( ulBuff >>32 ) {
- printk("cqpfcTS: 2Tach DMA address %p > 32 bits\n",
- (void*)ulBuff );
- printk("%s = %p, offset = %ld\n",
- WE_HAVE_SG_LIST ? "ulBuff" : "contigaddr",
- WE_HAVE_SG_LIST ? (void *) ulBuff : (void *) contigaddr,
- offset);
- return 0;
- }
-# endif
- *alPair++ = (ULONG)ulBuff; // lower 32 bits (31-0)
- thisMappingLen -= thislen;
- }
-
- if ( WE_HAVE_SG_LIST ) ++sgl; // next S/G pair
- else if (bytes_to_go != 0) printk("BTG not zero!\n");
-
-# ifdef DBG_SEST_SGLIST
- printk("L=%d ", thisMappingLen);
- printk("btg=%d ", bytes_to_go);
-# endif
-
- }
- // printk("i:%d\n", *sgPairs);
- }
- else // more than 3 pairs requires Extended S/G page (Pool Allocation)
- {
- // clear out SEST DWORDs (local S/G addr) C-F (A-B set in following logic)
- for( i=2; i<6; i++)
- alPair[i] = 0;
-
- PairCount = TL_EXT_SG_PAGE_COUNT; // forces initial page allocation
- totalsgs = 0;
- while( bytes_to_go )
- {
- // Per SEST format, we can support 524287 byte lengths per
- // S/G pair. Typical user buffers are 4k, and very rarely
- // exceed 12k due to fragmentation of physical memory pages.
- // However, on certain O/S system (not "user") buffers (on platforms
- // with huge memories), it's possible to exceed this
- // length in a single S/G address/len mapping, so we have to handle
- // that.
-
- offset = 0L;
- if ( WE_HAVE_SG_LIST )
- thisMappingLen = sg_dma_len(sgl);
- else
- thisMappingLen = bytes_to_go;
-
- while (thisMappingLen > 0)
- {
- thislen = thisMappingLen > TL_MAX_SG_ELEM_LEN ?
- TL_MAX_SG_ELEM_LEN : thisMappingLen;
- // printk("%d/%d/%d\n", thislen, thisMappingLen, bytes_to_go);
-
- // should we load into "this" extended S/G page, or allocate
- // new page?
-
- if( PairCount >= TL_EXT_SG_PAGE_COUNT )
- {
- // Now, we have to map the previous page, (triggering buffer bounce)
- // The first time thru the loop, there won't be a previous page.
- if (prev_page != NULL) // is there a prev page?
- {
- // this code is normally kind of hard to trigger,
- // you have to use up more than 256 scatter gather
- // elements to get here. Cranking down TL_MAX_SG_ELEM_LEN
- // to an absurdly low value (128 bytes or so) to artificially
- // break i/o's into a zillion pieces is how I tested it.
- busaddr = cpqfc_pci_map_sg_page(pcidev,
- ext_sg_page_phys_addr_place,
- prev_page->page,
- &prev_page->busaddr,
- &prev_page->maplen,
- PairCount);
- }
- // Allocate the TL Extended S/G list page. We have
- // to allocate twice what we want to ensure required TL alignment
- // (Tachlite TL/TS User Man. Rev 6.0, p 168)
- // We store the original allocated PVOID so we can free later
- *sgpage = kmalloc( sizeof(SGPAGES), GFP_ATOMIC);
- if ( ! *sgpage )
- {
- printk("cpqfc: Allocation failed @ %d S/G page allocations\n",
- AllocatedPages);
- total_data_len = 0; // failure!! Ext. S/G is All-or-none affair
-
- // unmap the previous mappings, if any.
-
- cpqfc_undo_SEST_mappings(pcidev, contigaddr,
- Cmnd->request_bufflen,
- Cmnd->sc_data_direction,
- sgl, Cmnd->use_sg, sgPages_head, AllocatedPages+1);
-
- // FIXME: testing shows that if we get here,
- // it's bad news. (this has been this way for a long
- // time though, AFAIK. Not that that excuses it.)
-
- return 0; // give up (and probably hang the system)
- }
- // clear out memory we just allocated
- memset( (*sgpage)->page,0,TL_EXT_SG_PAGE_BYTELEN*2);
- (*sgpage)->next = NULL;
- (*sgpage)->busaddr = (dma_addr_t) NULL;
- (*sgpage)->maplen = 0L;
-
- // align the memory - TL requires sizeof() Ext. S/G page alignment.
- // We doubled the actual required size so we could mask off LSBs
- // to get desired offset
-
- ulBuff = (unsigned long) (*sgpage)->page;
- ulBuff += TL_EXT_SG_PAGE_BYTELEN;
- ulBuff &= ~(TL_EXT_SG_PAGE_BYTELEN -1);
-
- // set pointer, in SEST if first Ext. S/G page, or in last pair
- // of linked Ext. S/G pages... (Only 32-bit PVOIDs, so just
- // load lower 32 bits)
- // NOTE: the Len field must be '0' if this is the first Ext. S/G
- // pointer in SEST, and not 0 otherwise (we know thislen != 0).
-
- *alPair = (alPair != SESTalPairStart) ? thislen : 0;
-
-# ifdef DBG_SEST_SGLIST
- printk("PairCount %d @%p even %Xh, ",
- PairCount, alPair, *alPair);
-# endif
-
- // Save the place where we need to store the physical
- // address of this scatter gather page which we get when we map it
- // (and mapping we can do only after we fill it in.)
- alPair++; // next DWORD, will contain phys addr of the ext page
- ext_sg_page_phys_addr_place = alPair;
-
- // Now, set alPair = the virtual addr of the (Extended) S/G page
- // which will accept the Len/ PhysicalAddress pairs
- alPair = (ULONG *) ulBuff;
-
- AllocatedPages++;
- if (AllocatedPages >= ap_hi_water)
- {
- // This message should rarely, if ever, come out.
- // Previously (cpqfc version <= 2.0.5) the driver would
- // just puke if more than 4 SG pages were used, and nobody
- // ever complained about that. This only comes out if
- // more than 8 pages are used.
-
- printk(KERN_WARNING
- "cpqfc: Possible danger. %d scatter gather pages used.\n"
- "cpqfc: detected seemingly extreme memory "
- "fragmentation or huge data transfers.\n",
- AllocatedPages);
- ap_hi_water = AllocatedPages+1;
- }
-
- PairCount = 1; // starting new Ext. S/G page
- prev_page = (*sgpage); // remember this page, for next time thru
- sgpage = &((*sgpage)->next);
- } // end of new TL Ext. S/G page allocation
-
- *alPair = thislen; // bits 18-0, length (range check above)
-
-# ifdef DBG_SEST_SGLIST
- printk("PairCount %d @%p, even %Xh, ", PairCount, alPair, *alPair);
-# endif
-
- alPair++; // next DWORD, physical address
-
- if ( WE_HAVE_SG_LIST )
- ulBuff = sg_dma_address(sgl) + offset;
- else
- ulBuff = contigaddr + offset;
- offset += thislen;
-
-# if BITS_PER_LONG > 32
- if( ulBuff >>32 )
- {
- printk("cqpfcTS: 1Tach DMA address %p > 32 bits\n", (void*)ulBuff );
- printk("%s = %p, offset = %ld\n",
- WE_HAVE_SG_LIST ? "ulBuff" : "contigaddr",
- WE_HAVE_SG_LIST ? (void *) ulBuff : (void *) contigaddr,
- offset);
- return 0;
- }
-# endif
-
- *alPair = (ULONG) ulBuff; // lower 32 bits (31-0)
-
-# ifdef DBG_SEST_SGLIST
- printk("odd %Xh\n", *alPair);
-# endif
- alPair++; // next DWORD, next address/length pair
-
- PairCount++; // next Length/Address pair
-
- // if (PairCount > pc_hi_water)
- // {
- // printk("pc hi = %d ", PairCount);
- // pc_hi_water = PairCount;
- // }
- bytes_to_go -= thislen;
- total_data_len += thislen;
- thisMappingLen -= thislen;
- totalsgs++;
- } // while (thisMappingLen > 0)
- if ( WE_HAVE_SG_LIST ) sgl++; // next S/G pair
- } // while (bytes_to_go)
-
- // printk("Totalsgs=%d\n", totalsgs);
- *sgPairs = totalsgs;
-
- // PCI map (and bounce) the last (and usually only) extended SG page
- busaddr = cpqfc_pci_map_sg_page(pcidev,
- ext_sg_page_phys_addr_place,
- prev_page->page,
- &prev_page->busaddr,
- &prev_page->maplen,
- PairCount);
- }
- return total_data_len;
-}
-
-
-
-// The Tachlite SEST table is referenced to OX_ID (or RX_ID). To optimize
-// performance and debuggability, we index the Exchange structure to FC X_ID
-// This enables us to build exchanges for later en-queing to Tachyon,
-// provided we have an open X_ID slot. At Tachyon queing time, we only
-// need an ERQ slot; then "fix-up" references in the
-// IRB, FCHS, etc. as needed.
-// RETURNS:
-// 0 if successful
-// non-zero on error
-//sstartex
-ULONG cpqfcTSStartExchange(
- CPQFCHBA *cpqfcHBAdata,
- LONG ExchangeID )
-{
- PTACHYON fcChip = &cpqfcHBAdata->fcChip;
- FC_EXCHANGES *Exchanges = fcChip->Exchanges;
- FC_EXCHANGE *pExchange = &Exchanges->fcExchange[ ExchangeID ]; // shorthand
- USHORT producer, consumer;
- ULONG ulStatus=0;
- short int ErqIndex;
- BOOLEAN CompleteExchange = FALSE; // e.g. ACC replies are complete
- BOOLEAN SestType=FALSE;
- ULONG InboundData=0;
-
- // We will manipulate Tachlite chip registers here to successfully
- // start exchanges.
-
- // Check that link is not down -- we can't start an exchange on a
- // down link!
-
- if( fcChip->Registers.FMstatus.value & 0x80) // LPSM offline?
- {
-printk("fcStartExchange: PSM offline (%Xh), x_ID %Xh, type %Xh, port_id %Xh\n",
- fcChip->Registers.FMstatus.value & 0xFF,
- ExchangeID,
- pExchange->type,
- pExchange->fchs.d_id);
-
- if( ExchangeID >= TACH_SEST_LEN ) // Link Service Outbound frame?
- {
- // Our most popular LinkService commands are port discovery types
- // (PLOGI/ PDISC...), which are implicitly nullified by Link Down
- // events, so it makes no sense to Que them. However, ABTS should
- // be queued, since exchange sequences are likely destroyed by
- // Link Down events, and we want to notify other ports of broken
- // sequences by aborting the corresponding exchanges.
- if( pExchange->type != BLS_ABTS )
- {
- ulStatus = LNKDWN_OSLS;
- goto Done;
- // don't Que most LinkServ exchanges on LINK DOWN
- }
- }
-
- printk("fcStartExchange: Que x_ID %Xh, type %Xh\n",
- ExchangeID, pExchange->type);
- pExchange->status |= EXCHANGE_QUEUED;
- ulStatus = EXCHANGE_QUEUED;
- goto Done;
- }
-
- // Make sure ERQ has available space.
-
- producer = (USHORT)fcChip->ERQ->producerIndex; // copies for logical arith.
- consumer = (USHORT)fcChip->ERQ->consumerIndex;
- producer++; // We are testing for full que by incrementing
-
- if( producer >= ERQ_LEN ) // rollover condition?
- producer = 0;
- if( consumer != producer ) // ERQ not full?
- {
- // ****************** Need Atomic access to chip registers!!********
-
- // remember ERQ PI for copying IRB
- ErqIndex = (USHORT)fcChip->ERQ->producerIndex;
- fcChip->ERQ->producerIndex = producer; // this is written to Tachyon
- // we have an ERQ slot! If SCSI command, need SEST slot
- // otherwise we are done.
-
- // Note that Tachyon requires that bit 15 of the OX_ID or RX_ID be
- // set according to direction of data to/from Tachyon for SEST assists.
- // For consistency, enforce this rule for Link Service (non-SEST)
- // exchanges as well.
-
- // fix-up the X_ID field in IRB
- pExchange->IRB.Req_A_Trans_ID = ExchangeID & 0x7FFF; // 15-bit field
-
- // fix-up the X_ID field in fchs -- depends on Originator or Responder,
- // outgoing or incoming data?
- switch( pExchange->type )
- {
- // ORIGINATOR types... we're setting our OX_ID and
- // defaulting the responder's RX_ID to 0xFFFF
-
- case SCSI_IRE:
- // Requirement: set MSB of x_ID for Incoming TL data
- // (see "Tachyon TL/TS User's Manual", Rev 6.0, Sept.'98, pg. 50)
- InboundData = 0x8000;
-
- case SCSI_IWE:
- SestType = TRUE;
- pExchange->fchs.ox_rx_id = (ExchangeID | InboundData);
- pExchange->fchs.ox_rx_id <<= 16; // MSW shift
- pExchange->fchs.ox_rx_id |= 0xffff; // add default RX_ID
-
- // now fix-up the Data HDR OX_ID (TL automatically does rx_id)
- // (not necessary for IRE -- data buffer unused)
- if( pExchange->type == SCSI_IWE)
- {
- fcChip->SEST->DataHDR[ ExchangeID ].ox_rx_id =
- pExchange->fchs.ox_rx_id;
-
- }
-
- break;
-
-
- case FCS_NSR: // ext. link service Name Service Request
- case ELS_SCR: // ext. link service State Change Registration
- case ELS_FDISC:// ext. link service login
- case ELS_FLOGI:// ext. link service login
- case ELS_LOGO: // FC-PH extended link service logout
- case BLS_NOP: // Basic link service No OPeration
- case ELS_PLOGI:// ext. link service login (PLOGI)
- case ELS_PDISC:// ext. link service login (PDISC)
- case ELS_PRLI: // ext. link service process login
-
- pExchange->fchs.ox_rx_id = ExchangeID;
- pExchange->fchs.ox_rx_id <<= 16; // MSW shift
- pExchange->fchs.ox_rx_id |= 0xffff; // and RX_ID
-
- break;
-
-
-
-
- // RESPONDER types... we must set our RX_ID while preserving
- // sender's OX_ID
- // outgoing (or no) data
- case ELS_RJT: // extended link service reject
- case ELS_LOGO_ACC: // FC-PH extended link service logout accept
- case ELS_ACC: // ext. generic link service accept
- case ELS_PLOGI_ACC:// ext. link service login accept (PLOGI or PDISC)
- case ELS_PRLI_ACC: // ext. link service process login accept
-
- CompleteExchange = TRUE; // Reply (ACC or RJT) is end of exchange
- pExchange->fchs.ox_rx_id |= (ExchangeID & 0xFFFF);
-
- break;
-
-
- // since we are a Responder, OX_ID should already be set by
- // cpqfcTSBuildExchange(). We need to -OR- in RX_ID
- case SCSI_TWE:
- SestType = TRUE;
- // Requirement: set MSB of x_ID for Incoming TL data
- // (see "Tachyon TL/TS User's Manual", Rev 6.0, Sept.'98, pg. 50)
-
- pExchange->fchs.ox_rx_id &= 0xFFFF0000; // clear RX_ID
- // Requirement: set MSB of RX_ID for Incoming TL data
- // (see "Tachyon TL/TS User's Manual", Rev 6.0, Sept.'98, pg. 50)
- pExchange->fchs.ox_rx_id |= (ExchangeID | 0x8000);
- break;
-
-
- case SCSI_TRE:
- SestType = TRUE;
-
- // there is no XRDY for SEST target read; the data
- // header needs to be updated. Also update the RSP
- // exchange IDs for the status frame, in case it is sent automatically
- fcChip->SEST->DataHDR[ ExchangeID ].ox_rx_id |= ExchangeID;
- fcChip->SEST->RspHDR[ ExchangeID ].ox_rx_id =
- fcChip->SEST->DataHDR[ ExchangeID ].ox_rx_id;
-
- // for easier FCP response logic (works for TWE and TRE),
- // copy exchange IDs. (Not needed if TRE 'RSP' bit set)
- pExchange->fchs.ox_rx_id =
- fcChip->SEST->DataHDR[ ExchangeID ].ox_rx_id;
-
- break;
-
-
- case FCP_RESPONSE: // using existing OX_ID/ RX_ID pair,
- // start SFS FCP-RESPONSE frame
- // OX/RX_ID should already be set! (See "fcBuild" above)
- CompleteExchange = TRUE; // RSP is end of FCP-SCSI exchange
-
-
- break;
-
-
- case BLS_ABTS_RJT: // uses new RX_ID, since SEST x_ID non-existent
- case BLS_ABTS_ACC: // using existing OX_ID/ RX_ID pair from SEST entry
- CompleteExchange = TRUE; // ACC or RJT marks end of FCP-SCSI exchange
- case BLS_ABTS: // using existing OX_ID/ RX_ID pair from SEST entry
-
-
- break;
-
-
- default:
- printk("Error on fcStartExchange: undefined type %Xh(%d)\n",
- pExchange->type, pExchange->type);
- return INVALID_ARGS;
- }
-
-
- // X_ID fields are entered -- copy IRB to Tachyon's ERQ
-
-
- memcpy(
- &fcChip->ERQ->QEntry[ ErqIndex ], // dest.
- &pExchange->IRB,
- 32); // fixed (hardware) length!
-
- PCI_TRACEO( ExchangeID, 0xA0)
-
- // ACTION! May generate INT and IMQ entry
- writel( fcChip->ERQ->producerIndex,
- fcChip->Registers.ERQproducerIndex.address);
-
-
- if( ExchangeID >= TACH_SEST_LEN ) // Link Service Outbound frame?
- {
-
- // wait for completion! (TDB -- timeout and chip reset)
-
-
- PCI_TRACEO( ExchangeID, 0xA4)
-
- enable_irq( cpqfcHBAdata->HostAdapter->irq); // only way to get Sem.
-
- down_interruptible( cpqfcHBAdata->TYOBcomplete);
-
- disable_irq( cpqfcHBAdata->HostAdapter->irq);
- PCI_TRACE( 0xA4)
-
- // On login exchanges, BAD_ALPA (non-existent port_id) results in
- // FTO (Frame Time Out) on the Outbound Completion message.
- // If we got an FTO status, complete the exchange (free up slot)
- if( CompleteExchange || // flag from Reply frames
- pExchange->status ) // typically, can get FRAME_TO
- {
- cpqfcTSCompleteExchange( cpqfcHBAdata->PciDev, fcChip, ExchangeID);
- }
- }
-
- else // SEST Exchange
- {
- ulStatus = 0; // ship & pray success (e.g. FCP-SCSI)
-
- if( CompleteExchange ) // by Type of exchange (e.g. end-of-xchng)
- {
- cpqfcTSCompleteExchange( cpqfcHBAdata->PciDev, fcChip, ExchangeID);
- }
-
- else
- pExchange->status &= ~EXCHANGE_QUEUED; // clear ExchangeQueued flag
-
- }
- }
-
-
- else // ERQ 'producer' = 'consumer' and QUE is full
- {
- ulStatus = OUTQUE_FULL; // Outbound (ERQ) Que full
- }
-
-Done:
- PCI_TRACE( 0xA0)
- return ulStatus;
-}
-
-
-
-
-
-// Scan fcController->fcExchanges array for a usuable index (a "free"
-// exchange).
-// Inputs:
-// fcChip - pointer to TachLite chip structure
-// Return:
-// index - exchange array element where exchange can be built
-// -1 - exchange array is full
-// REMARKS:
-// Although this is a (yuk!) linear search, we presume
-// that the system will complete exchanges about as quickly as
-// they are submitted. A full Exchange array (and hence, max linear
-// search time for free exchange slot) almost guarantees a Fibre problem
-// of some sort.
-// In the interest of making exchanges easier to debug, we want a LRU
-// (Least Recently Used) scheme.
-
-
-static LONG FindFreeExchange( PTACHYON fcChip, ULONG type )
-{
- FC_EXCHANGES *Exchanges = fcChip->Exchanges;
- ULONG i;
- ULONG ulStatus=-1; // assume failure
-
-
- if( type == SCSI_IRE ||
- type == SCSI_TRE ||
- type == SCSI_IWE ||
- type == SCSI_TWE)
- {
- // SCSI type - X_IDs should be from 0 to TACH_SEST_LEN-1
- if( fcChip->fcSestExchangeLRU >= TACH_SEST_LEN) // rollover?
- fcChip->fcSestExchangeLRU = 0;
- i = fcChip->fcSestExchangeLRU; // typically it's already free!
-
- if( Exchanges->fcExchange[i].type == 0 ) // check for "free" element
- {
- ulStatus = 0; // success!
- }
-
- else
- { // YUK! we need to do a linear search for free element.
- // Fragmentation of the fcExchange array is due to excessively
- // long completions or timeouts.
-
- while( TRUE )
- {
- if( ++i >= TACH_SEST_LEN ) // rollover check
- i = 0; // beginning of SEST X_IDs
-
-// printk( "looping for SCSI xchng ID: i=%d, type=%Xh\n",
-// i, Exchanges->fcExchange[i].type);
-
- if( Exchanges->fcExchange[i].type == 0 ) // "free"?
- {
- ulStatus = 0; // success!
- break;
- }
- if( i == fcChip->fcSestExchangeLRU ) // wrapped-around array?
- {
- printk( "SEST X_ID space full\n");
- break; // failed - prevent inf. loop
- }
- }
- }
- fcChip->fcSestExchangeLRU = i + 1; // next! (rollover check next pass)
- }
-
-
-
- else // Link Service type - X_IDs should be from TACH_SEST_LEN
- // to TACH_MAX_XID
- {
- if( fcChip->fcLsExchangeLRU >= TACH_MAX_XID || // range check
- fcChip->fcLsExchangeLRU < TACH_SEST_LEN ) // (e.g. startup)
- fcChip->fcLsExchangeLRU = TACH_SEST_LEN;
-
- i = fcChip->fcLsExchangeLRU; // typically it's already free!
- if( Exchanges->fcExchange[i].type == 0 ) // check for "free" element
- {
- ulStatus = 0; // success!
- }
-
- else
- { // YUK! we need to do a linear search for free element
- // Fragmentation of the fcExchange array is due to excessively
- // long completions or timeouts.
-
- while( TRUE )
- {
- if( ++i >= TACH_MAX_XID ) // rollover check
- i = TACH_SEST_LEN;// beginning of Link Service X_IDs
-
-// printk( "looping for xchng ID: i=%d, type=%Xh\n",
-// i, Exchanges->fcExchange[i].type);
-
- if( Exchanges->fcExchange[i].type == 0 ) // "free"?
- {
- ulStatus = 0; // success!
- break;
- }
- if( i == fcChip->fcLsExchangeLRU ) // wrapped-around array?
- {
- printk( "LinkService X_ID space full\n");
- break; // failed - prevent inf. loop
- }
- }
- }
- fcChip->fcLsExchangeLRU = i + 1; // next! (rollover check next pass)
-
- }
-
- if( !ulStatus ) // success?
- Exchanges->fcExchange[i].type = type; // allocate it.
-
- else
- i = -1; // error - all exchanges "open"
-
- return i;
-}
-
-static void
-cpqfc_pci_unmap_extended_sg(struct pci_dev *pcidev,
- PTACHYON fcChip,
- ULONG x_ID)
-{
- // Unmaps the memory regions used to hold the scatter gather lists
-
- PSGPAGES i;
-
- // Were there any such regions needing unmapping?
- if (! USES_EXTENDED_SGLIST(fcChip->SEST, x_ID))
- return; // No such regions, we're outta here.
-
- // for each extended scatter gather region needing unmapping...
- for (i=fcChip->SEST->sgPages[x_ID] ; i != NULL ; i = i->next)
- pci_unmap_single(pcidev, i->busaddr, i->maplen,
- PCI_DMA_TODEVICE);
-}
-
-// Called also from cpqfcTScontrol.o, so can't be static
-void
-cpqfc_pci_unmap(struct pci_dev *pcidev,
- Scsi_Cmnd *cmd,
- PTACHYON fcChip,
- ULONG x_ID)
-{
- // Undo the DMA mappings
- if (cmd->use_sg) { // Used scatter gather list for data buffer?
- cpqfc_pci_unmap_extended_sg(pcidev, fcChip, x_ID);
- pci_unmap_sg(pcidev, cmd->buffer, cmd->use_sg,
- cmd->sc_data_direction);
- // printk("umsg %d\n", cmd->use_sg);
- }
- else if (cmd->request_bufflen) {
- // printk("ums %p ", fcChip->SEST->u[ x_ID ].IWE.GAddr1);
- pci_unmap_single(pcidev, fcChip->SEST->u[ x_ID ].IWE.GAddr1,
- cmd->request_bufflen,
- cmd->sc_data_direction);
- }
-}
-
-// We call this routine to free an Exchange for any reason:
-// completed successfully, completed with error, aborted, etc.
-
-// returns FALSE if Exchange failed and "retry" is acceptable
-// returns TRUE if Exchange was successful, or retry is impossible
-// (e.g. port/device gone).
-//scompleteexchange
-
-void cpqfcTSCompleteExchange(
- struct pci_dev *pcidev,
- PTACHYON fcChip,
- ULONG x_ID)
-{
- FC_EXCHANGES *Exchanges = fcChip->Exchanges;
- int already_unmapped = 0;
-
- if( x_ID < TACH_SEST_LEN ) // SEST-based (or LinkServ for FCP exchange)
- {
- if( Exchanges->fcExchange[ x_ID ].Cmnd == NULL ) // what#@!
- {
-// TriggerHBA( fcChip->Registers.ReMapMemBase, 0);
- printk(" x_ID %Xh, type %Xh, NULL ptr!\n", x_ID,
- Exchanges->fcExchange[ x_ID ].type);
-
- goto CleanUpSestResources; // this path should be very rare.
- }
-
- // we have Linux Scsi Cmnd ptr..., now check our Exchange status
- // to decide how to complete this SEST FCP exchange
-
- if( Exchanges->fcExchange[ x_ID ].status ) // perhaps a Tach indicated problem,
- // or abnormal exchange completion
- {
- // set FCP Link statistics
-
- if( Exchanges->fcExchange[ x_ID ].status & FC2_TIMEOUT)
- fcChip->fcStats.timeouts++;
- if( Exchanges->fcExchange[ x_ID ].status & INITIATOR_ABORT)
- fcChip->fcStats.FC4aborted++;
- if( Exchanges->fcExchange[ x_ID ].status & COUNT_ERROR)
- fcChip->fcStats.CntErrors++;
- if( Exchanges->fcExchange[ x_ID ].status & LINKFAIL_TX)
- fcChip->fcStats.linkFailTX++;
- if( Exchanges->fcExchange[ x_ID ].status & LINKFAIL_RX)
- fcChip->fcStats.linkFailRX++;
- if( Exchanges->fcExchange[ x_ID ].status & OVERFLOW)
- fcChip->fcStats.CntErrors++;
-
- // First, see if the Scsi upper level initiated an ABORT on this
- // exchange...
- if( Exchanges->fcExchange[ x_ID ].status == INITIATOR_ABORT )
- {
- printk(" DID_ABORT, x_ID %Xh, Cmnd %p ",
- x_ID, Exchanges->fcExchange[ x_ID ].Cmnd);
- goto CleanUpSestResources; // (we don't expect Linux _aborts)
- }
-
- // Did our driver timeout the Exchange, or did Tachyon indicate
- // a failure during transmission? Ask for retry with "SOFT_ERROR"
- else if( Exchanges->fcExchange[ x_ID ].status & FC2_TIMEOUT)
- {
-// printk("result DID_SOFT_ERROR, x_ID %Xh, Cmnd %p\n",
-// x_ID, Exchanges->fcExchange[ x_ID ].Cmnd);
- Exchanges->fcExchange[ x_ID ].Cmnd->result = (DID_SOFT_ERROR <<16);
- }
-
- // Did frame(s) for an open exchange arrive in the SFQ,
- // meaning the SEST was unable to process them?
- else if( Exchanges->fcExchange[ x_ID ].status & SFQ_FRAME)
- {
-// printk("result DID_SOFT_ERROR, x_ID %Xh, Cmnd %p\n",
-// x_ID, Exchanges->fcExchange[ x_ID ].Cmnd);
- Exchanges->fcExchange[ x_ID ].Cmnd->result = (DID_SOFT_ERROR <<16);
- }
-
- // Did our driver timeout the Exchange, or did Tachyon indicate
- // a failure during transmission? Ask for retry with "SOFT_ERROR"
- else if(
- (Exchanges->fcExchange[ x_ID ].status & LINKFAIL_TX) ||
- (Exchanges->fcExchange[ x_ID ].status & PORTID_CHANGED) ||
- (Exchanges->fcExchange[ x_ID ].status & FRAME_TO) ||
- (Exchanges->fcExchange[ x_ID ].status & INV_ENTRY) ||
- (Exchanges->fcExchange[ x_ID ].status & ABORTSEQ_NOTIFY) )
-
-
- {
-// printk("result DID_SOFT_ERROR, x_ID %Xh, Cmnd %p\n",
-// x_ID, Exchanges->fcExchange[ x_ID ].Cmnd);
- Exchanges->fcExchange[ x_ID ].Cmnd->result = (DID_SOFT_ERROR <<16);
-
-
- }
-
- // e.g., a LOGOut happened, or device never logged back in.
- else if( Exchanges->fcExchange[ x_ID ].status & DEVICE_REMOVED)
- {
-// printk(" *LOGOut or timeout on login!* ");
- // trigger?
-// TriggerHBA( fcChip->Registers.ReMapMemBase, 0);
-
- Exchanges->fcExchange[ x_ID ].Cmnd->result = (DID_BAD_TARGET <<16);
- }
-
-
- // Did Tachyon indicate a CNT error? We need further analysis
- // to determine if the exchange is acceptable
- else if( Exchanges->fcExchange[ x_ID ].status == COUNT_ERROR)
- {
- UCHAR ScsiStatus;
- FCP_STATUS_RESPONSE *pFcpStatus =
- (PFCP_STATUS_RESPONSE)&fcChip->SEST->RspHDR[ x_ID ].pl;
-
- ScsiStatus = pFcpStatus->fcp_status >>24;
-
- // If the command is a SCSI Read/Write type, we don't tolerate
- // count errors of any kind; assume the count error is due to
- // a dropped frame and ask for retry...
-
- if(( (Exchanges->fcExchange[ x_ID ].Cmnd->cmnd[0] == 0x8) ||
- (Exchanges->fcExchange[ x_ID ].Cmnd->cmnd[0] == 0x28) ||
- (Exchanges->fcExchange[ x_ID ].Cmnd->cmnd[0] == 0xA) ||
- (Exchanges->fcExchange[ x_ID ].Cmnd->cmnd[0] == 0x2A) )
- &&
- ScsiStatus == 0 )
- {
- // ask for retry
-/* printk("COUNT_ERROR retry, x_ID %Xh, status %Xh, Cmnd %p\n",
- x_ID, Exchanges->fcExchange[ x_ID ].status,
- Exchanges->fcExchange[ x_ID ].Cmnd);*/
- Exchanges->fcExchange[ x_ID ].Cmnd->result = (DID_SOFT_ERROR <<16);
- }
-
- else // need more analysis
- {
- cpqfcTSCheckandSnoopFCP(fcChip, x_ID); // (will set ->result)
- }
- }
-
- // default: NOTE! We don't ever want to get here. Getting here
- // implies something new is happening that we've never had a test
- // case for. Need code maintenance! Return "ERROR"
- else
- {
- unsigned int stat = Exchanges->fcExchange[ x_ID ].status;
- printk("DEFAULT result %Xh, x_ID %Xh, Cmnd %p",
- Exchanges->fcExchange[ x_ID ].status, x_ID,
- Exchanges->fcExchange[ x_ID ].Cmnd);
-
- if (stat & INVALID_ARGS) printk(" INVALID_ARGS ");
- if (stat & LNKDWN_OSLS) printk(" LNKDWN_OSLS ");
- if (stat & LNKDWN_LASER) printk(" LNKDWN_LASER ");
- if (stat & OUTQUE_FULL) printk(" OUTQUE_FULL ");
- if (stat & DRIVERQ_FULL) printk(" DRIVERQ_FULL ");
- if (stat & SEST_FULL) printk(" SEST_FULL ");
- if (stat & BAD_ALPA) printk(" BAD_ALPA ");
- if (stat & OVERFLOW) printk(" OVERFLOW ");
- if (stat & COUNT_ERROR) printk(" COUNT_ERROR ");
- if (stat & LINKFAIL_RX) printk(" LINKFAIL_RX ");
- if (stat & ABORTSEQ_NOTIFY) printk(" ABORTSEQ_NOTIFY ");
- if (stat & LINKFAIL_TX) printk(" LINKFAIL_TX ");
- if (stat & HOSTPROG_ERR) printk(" HOSTPROG_ERR ");
- if (stat & FRAME_TO) printk(" FRAME_TO ");
- if (stat & INV_ENTRY) printk(" INV_ENTRY ");
- if (stat & SESTPROG_ERR) printk(" SESTPROG_ERR ");
- if (stat & OUTBOUND_TIMEOUT) printk(" OUTBOUND_TIMEOUT ");
- if (stat & INITIATOR_ABORT) printk(" INITIATOR_ABORT ");
- if (stat & MEMPOOL_FAIL) printk(" MEMPOOL_FAIL ");
- if (stat & FC2_TIMEOUT) printk(" FC2_TIMEOUT ");
- if (stat & TARGET_ABORT) printk(" TARGET_ABORT ");
- if (stat & EXCHANGE_QUEUED) printk(" EXCHANGE_QUEUED ");
- if (stat & PORTID_CHANGED) printk(" PORTID_CHANGED ");
- if (stat & DEVICE_REMOVED) printk(" DEVICE_REMOVED ");
- if (stat & SFQ_FRAME) printk(" SFQ_FRAME ");
- printk("\n");
-
- Exchanges->fcExchange[ x_ID ].Cmnd->result = (DID_ERROR <<16);
- }
- }
- else // definitely no Tach problem, but perhaps an FCP problem
- {
- // set FCP Link statistic
- fcChip->fcStats.ok++;
- cpqfcTSCheckandSnoopFCP( fcChip, x_ID); // (will set ->result)
- }
-
- cpqfc_pci_unmap(pcidev, Exchanges->fcExchange[x_ID].Cmnd,
- fcChip, x_ID); // undo DMA mappings.
- already_unmapped = 1;
-
- // OK, we've set the Scsi "->result" field, so proceed with calling
- // Linux Scsi "done" (if not NULL), and free any kernel memory we
- // may have allocated for the exchange.
-
- PCI_TRACEO( (ULONG)Exchanges->fcExchange[x_ID].Cmnd, 0xAC);
- // complete the command back to upper Scsi drivers
- if( Exchanges->fcExchange[ x_ID ].Cmnd->scsi_done != NULL)
- {
- // Calling "done" on an Linux _abort() aborted
- // Cmnd causes a kernel panic trying to re-free mem.
- // Actually, we shouldn't do anything with an _abort CMND
- if( Exchanges->fcExchange[ x_ID ].Cmnd->result != (DID_ABORT<<16) )
- {
- PCI_TRACE(0xAC)
- call_scsi_done(Exchanges->fcExchange[ x_ID ].Cmnd);
- }
- else
- {
-// printk(" not calling scsi_done on x_ID %Xh, Cmnd %p\n",
-// x_ID, Exchanges->fcExchange[ x_ID ].Cmnd);
- }
- }
- else{
- printk(" x_ID %Xh, type %Xh, Cdb0 %Xh\n", x_ID,
- Exchanges->fcExchange[ x_ID ].type,
- Exchanges->fcExchange[ x_ID ].Cmnd->cmnd[0]);
- printk(" cpqfcTS: Null scsi_done function pointer!\n");
- }
-
-
- // Now, clean up non-Scsi_Cmnd items...
-CleanUpSestResources:
-
- if (!already_unmapped)
- cpqfc_pci_unmap(pcidev, Exchanges->fcExchange[x_ID].Cmnd,
- fcChip, x_ID); // undo DMA mappings.
-
- // Was an Extended Scatter/Gather page allocated? We know
- // this by checking DWORD 4, bit 31 ("LOC") of SEST entry
- if( !(fcChip->SEST->u[ x_ID ].IWE.Buff_Off & 0x80000000))
- {
- PSGPAGES p, next;
-
- // extended S/G list was used -- Free the allocated ext. S/G pages
- for (p = fcChip->SEST->sgPages[x_ID]; p != NULL; p = next) {
- next = p->next;
- kfree(p);
- }
- fcChip->SEST->sgPages[x_ID] = NULL;
- }
-
- Exchanges->fcExchange[ x_ID ].Cmnd = NULL;
- } // Done with FCP (SEST) exchanges
-
-
- // the remaining logic is common to ALL Exchanges:
- // FCP(SEST) and LinkServ.
-
- Exchanges->fcExchange[ x_ID ].type = 0; // there -- FREE!
- Exchanges->fcExchange[ x_ID ].status = 0;
-
- PCI_TRACEO( x_ID, 0xAC)
-
-
- return;
-} // (END of CompleteExchange function)
-
-
-
-
-// Unfortunately, we must snoop all command completions in
-// order to manipulate certain return fields, and take note of
-// device types, etc., to facilitate the Fibre-Channel to SCSI
-// "mapping".
-// (Watch for BIG Endian confusion on some payload fields)
-void cpqfcTSCheckandSnoopFCP( PTACHYON fcChip, ULONG x_ID)
-{
- FC_EXCHANGES *Exchanges = fcChip->Exchanges;
- Scsi_Cmnd *Cmnd = Exchanges->fcExchange[ x_ID].Cmnd;
- FCP_STATUS_RESPONSE *pFcpStatus =
- (PFCP_STATUS_RESPONSE)&fcChip->SEST->RspHDR[ x_ID ].pl;
- UCHAR ScsiStatus;
-
- ScsiStatus = pFcpStatus->fcp_status >>24;
-
-#ifdef FCP_COMPLETION_DBG
- printk("ScsiStatus = 0x%X\n", ScsiStatus);
-#endif
-
- // First, check FCP status
- if( pFcpStatus->fcp_status & FCP_RSP_LEN_VALID )
- {
- // check response code (RSP_CODE) -- most popular is bad len
- // 1st 4 bytes of rsp info -- only byte 3 interesting
- if( pFcpStatus->fcp_rsp_info & FCP_DATA_LEN_NOT_BURST_LEN )
- {
-
- // do we EVER get here?
- printk("cpqfcTS: FCP data len not burst len, x_ID %Xh\n", x_ID);
- }
- }
-
- // for now, go by the ScsiStatus, and manipulate certain
- // commands when necessary...
- if( ScsiStatus == 0) // SCSI status byte "good"?
- {
- Cmnd->result = 0; // everything's OK
-
- if( (Cmnd->cmnd[0] == INQUIRY))
- {
- UCHAR *InquiryData = Cmnd->request_buffer;
- PFC_LOGGEDIN_PORT pLoggedInPort;
-
- // We need to manipulate INQUIRY
- // strings for COMPAQ RAID controllers to force
- // Linux to scan additional LUNs. Namely, set
- // the Inquiry string byte 2 (ANSI-approved version)
- // to 2.
-
- if( !memcmp( &InquiryData[8], "COMPAQ", 6 ))
- {
- InquiryData[2] = 0x2; // claim SCSI-2 compliance,
- // so multiple LUNs may be scanned.
- // (no SCSI-2 problems known in CPQ)
- }
-
- // snoop the Inquiry to detect Disk, Tape, etc. type
- // (search linked list for the port_id we sent INQUIRY to)
- pLoggedInPort = fcFindLoggedInPort( fcChip,
- NULL, // DON'T search Scsi Nexus (we will set it)
- Exchanges->fcExchange[ x_ID].fchs.d_id & 0xFFFFFF,
- NULL, // DON'T search linked list for FC WWN
- NULL); // DON'T care about end of list
-
- if( pLoggedInPort )
- {
- pLoggedInPort->ScsiNexus.InqDeviceType = InquiryData[0];
- }
- else
- {
- printk("cpqfcTS: can't find LoggedIn FC port %06X for INQUIRY\n",
- Exchanges->fcExchange[ x_ID].fchs.d_id & 0xFFFFFF);
- }
- }
- }
-
-
- // Scsi Status not good -- pass it back to caller
-
- else
- {
- Cmnd->result = ScsiStatus; // SCSI status byte is 1st
-
- // check for valid "sense" data
-
- if( pFcpStatus->fcp_status & FCP_SNS_LEN_VALID )
- { // limit Scsi Sense field length!
- int SenseLen = pFcpStatus->fcp_sns_len >>24; // (BigEndian) lower byte
-
- SenseLen = SenseLen > sizeof( Cmnd->sense_buffer) ?
- sizeof( Cmnd->sense_buffer) : SenseLen;
-
-
-#ifdef FCP_COMPLETION_DBG
- printk("copy sense_buffer %p, len %d, result %Xh\n",
- Cmnd->sense_buffer, SenseLen, Cmnd->result);
-#endif
-
- // NOTE: There is some dispute over the FCP response
- // format. Most FC devices assume that FCP_RSP_INFO
- // is 8 bytes long, in spite of the fact that FCP_RSP_LEN
- // is (virtually) always 0 and the field is "invalid".
- // Some other devices assume that
- // the FCP_SNS_INFO begins after FCP_RSP_LEN bytes (i.e. 0)
- // when the FCP_RSP is invalid (this almost appears to be
- // one of those "religious" issues).
- // Consequently, we test the usual position of FCP_SNS_INFO
- // for 7Xh, since the SCSI sense format says the first
- // byte ("error code") should be 0x70 or 0x71. In practice,
- // we find that every device does in fact have 0x70 or 0x71
- // in the first byte position, so this test works for all
- // FC devices.
- // (This logic is especially effective for the CPQ/DEC HSG80
- // & HSG60 controllers).
-
- if( (pFcpStatus->fcp_sns_info[0] & 0x70) == 0x70 )
- memcpy( Cmnd->sense_buffer,
- &pFcpStatus->fcp_sns_info[0], SenseLen);
- else
- {
- unsigned char *sbPtr =
- (unsigned char *)&pFcpStatus->fcp_sns_info[0];
- sbPtr -= 8; // back up 8 bytes hoping to find the
- // start of the sense buffer
- memcpy( Cmnd->sense_buffer, sbPtr, SenseLen);
- }
-
- // in the special case of Device Reset, tell upper layer
- // to immediately retry (with SOFT_ERROR status)
- // look for Sense Key Unit Attention (0x6) with ASC Device
- // Reset (0x29)
- // printk("SenseLen %d, Key = 0x%X, ASC = 0x%X\n",
- // SenseLen, Cmnd->sense_buffer[2],
- // Cmnd->sense_buffer[12]);
- if( ((Cmnd->sense_buffer[2] & 0xF) == 0x6) &&
- (Cmnd->sense_buffer[12] == 0x29) ) // Sense Code "reset"
- {
- Cmnd->result |= (DID_SOFT_ERROR << 16); // "Host" status byte 3rd
- }
-
- // check for SenseKey "HARDWARE ERROR", ASC InternalTargetFailure
- else if( ((Cmnd->sense_buffer[2] & 0xF) == 0x4) && // "hardware error"
- (Cmnd->sense_buffer[12] == 0x44) ) // Addtl. Sense Code
- {
-// printk("HARDWARE_ERROR, Channel/Target/Lun %d/%d/%d\n",
-// Cmnd->channel, Cmnd->target, Cmnd->lun);
- Cmnd->result |= (DID_ERROR << 16); // "Host" status byte 3rd
- }
-
- } // (end of sense len valid)
-
- // there is no sense data to help out Linux's Scsi layers...
- // We'll just return the Scsi status and hope he will "do the
- // right thing"
- else
- {
- // as far as we know, the Scsi status is sufficient
- Cmnd->result |= (DID_OK << 16); // "Host" status byte 3rd
- }
- }
-}
-
-
-
-//PPPPPPPPPPPPPPPPPPPPPPPPP PAYLOAD PPPPPPPPP
-// build data PAYLOAD; SCSI FCP_CMND I.U.
-// remember BIG ENDIAN payload - DWord values must be byte-reversed
-// (hence the affinity for byte pointer building).
-
-static int build_FCP_payload( Scsi_Cmnd *Cmnd,
- UCHAR* payload, ULONG type, ULONG fcp_dl )
-{
- int i;
-
-
- switch( type)
- {
-
- case SCSI_IWE:
- case SCSI_IRE:
- // 8 bytes FCP_LUN
- // Peripheral Device or Volume Set addressing, and LUN mapping
- // When the FC port was looked up, we copied address mode
- // and any LUN mask to the scratch pad SCp.phase & .mode
-
- *payload++ = (UCHAR)Cmnd->SCp.phase;
-
- // Now, because of "lun masking"
- // (aka selective storage presentation),
- // the contiguous Linux Scsi lun number may not match the
- // device's lun number, so we may have to "map".
-
- *payload++ = (UCHAR)Cmnd->SCp.have_data_in;
-
- // We don't know of anyone in the FC business using these
- // extra "levels" of addressing. In fact, confusion still exists
- // just using the FIRST level... ;-)
-
- *payload++ = 0; // 2nd level addressing
- *payload++ = 0;
- *payload++ = 0; // 3rd level addressing
- *payload++ = 0;
- *payload++ = 0; // 4th level addressing
- *payload++ = 0;
-
- // 4 bytes Control Field FCP_CNTL
- *payload++ = 0; // byte 0: (MSB) reserved
- *payload++ = 0; // byte 1: task codes
-
- // byte 2: task management flags
- // another "use" of the spare field to accomplish TDR
- // note combination needed
- if( (Cmnd->cmnd[0] == RELEASE) &&
- (Cmnd->SCp.buffers_residual == FCP_TARGET_RESET) )
- {
- Cmnd->cmnd[0] = 0; // issue "Test Unit Ready" for TDR
- *payload++ = 0x20; // target device reset bit
- }
- else
- *payload++ = 0; // no TDR
- // byte 3: (LSB) execution management codes
- // bit 0 write, bit 1 read (don't set together)
-
- if( fcp_dl != 0 )
- {
- if( type == SCSI_IWE ) // WRITE
- *payload++ = 1;
- else // READ
- *payload++ = 2;
- }
- else
- {
- // On some devices, if RD or WR bits are set,
- // and fcp_dl is 0, they will generate an error on the command.
- // (i.e., if direction is specified, they insist on a length).
- *payload++ = 0; // no data (necessary for CPQ)
- }
-
-
- // NOTE: clean this up if/when MAX_COMMAND_SIZE is increased to 16
- // FCP_CDB allows 16 byte SCSI command descriptor blk;
- // Linux SCSI CDB array is MAX_COMMAND_SIZE (12 at this time...)
- for( i=0; (i < Cmnd->cmd_len) && i < MAX_COMMAND_SIZE; i++)
- *payload++ = Cmnd->cmnd[i];
-
- // if( Cmnd->cmd_len == 16 )
- // {
- // memcpy( payload, &Cmnd->SCp.buffers_residual, 4);
- // }
- payload+= (16 - i);
-
- // FCP_DL is largest number of expected data bytes
- // per CDB (i.e. read/write command)
- *payload++ = (UCHAR)(fcp_dl >>24); // (MSB) 8 bytes data len FCP_DL
- *payload++ = (UCHAR)(fcp_dl >>16);
- *payload++ = (UCHAR)(fcp_dl >>8);
- *payload++ = (UCHAR)fcp_dl; // (LSB)
- break;
-
- case SCSI_TWE: // need FCP_XFER_RDY
- *payload++ = 0; // (4 bytes) DATA_RO (MSB byte 0)
- *payload++ = 0;
- *payload++ = 0;
- *payload++ = 0; // LSB (byte 3)
- // (4 bytes) BURST_LEN
- // size of following FCP_DATA payload
- *payload++ = (UCHAR)(fcp_dl >>24); // (MSB) 8 bytes data len FCP_DL
- *payload++ = (UCHAR)(fcp_dl >>16);
- *payload++ = (UCHAR)(fcp_dl >>8);
- *payload++ = (UCHAR)fcp_dl; // (LSB)
- // 4 bytes RESERVED
- *payload++ = 0;
- *payload++ = 0;
- *payload++ = 0;
- *payload++ = 0;
- break;
-
- default:
- break;
- }
-
- return 0;
-}
-
diff --git a/drivers/scsi/dc395x.c b/drivers/scsi/dc395x.c
index 600ba1202864..c8a32cf47d73 100644
--- a/drivers/scsi/dc395x.c
+++ b/drivers/scsi/dc395x.c
@@ -976,6 +976,16 @@ static void send_srb(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb)
}
}
+static inline void pio_trigger(void)
+{
+ static int feedback_requested;
+
+ if (!feedback_requested) {
+ feedback_requested = 1;
+ printk(KERN_WARNING "%s: Please, contact <linux-scsi@vger.kernel.org> "
+ "to help improve support for your system.\n", __FILE__);
+ }
+}
/* Prepare SRB for being sent to Device DCB w/ command *cmd */
static void build_srb(struct scsi_cmnd *cmd, struct DeviceCtlBlk *dcb,
@@ -2320,6 +2330,7 @@ static void data_in_phase0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
CFG2_WIDEFIFO);
while (DC395x_read8(acb, TRM_S1040_SCSI_FIFOCNT) != 0x40) {
u8 byte = DC395x_read8(acb, TRM_S1040_SCSI_FIFO);
+ pio_trigger();
*(srb->virt_addr)++ = byte;
if (debug_enabled(DBG_PIO))
printk(" %02x", byte);
@@ -2331,6 +2342,7 @@ static void data_in_phase0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
/* Read the last byte ... */
if (srb->total_xfer_length > 0) {
u8 byte = DC395x_read8(acb, TRM_S1040_SCSI_FIFO);
+ pio_trigger();
*(srb->virt_addr)++ = byte;
srb->total_xfer_length--;
if (debug_enabled(DBG_PIO))
@@ -2507,6 +2519,7 @@ static void data_io_transfer(struct AdapterCtlBlk *acb,
if (debug_enabled(DBG_PIO))
printk(" %02x", (unsigned char) *(srb->virt_addr));
+ pio_trigger();
DC395x_write8(acb, TRM_S1040_SCSI_FIFO,
*(srb->virt_addr)++);
@@ -4257,8 +4270,7 @@ static void adapter_sg_tables_free(struct AdapterCtlBlk *acb)
const unsigned srbs_per_page = PAGE_SIZE/SEGMENTX_LEN;
for (i = 0; i < DC395x_MAX_SRB_CNT; i += srbs_per_page)
- if (acb->srb_array[i].segment_x)
- kfree(acb->srb_array[i].segment_x);
+ kfree(acb->srb_array[i].segment_x);
}
diff --git a/drivers/scsi/dec_esp.c b/drivers/scsi/dec_esp.c
index 315f95a0d6c0..256d6baf8df3 100644
--- a/drivers/scsi/dec_esp.c
+++ b/drivers/scsi/dec_esp.c
@@ -18,7 +18,7 @@
* 20001005 - Initialization fixes for 2.4.0-test9
* Florian Lohoff <flo@rfc822.org>
*
- * Copyright (C) 2002, 2003 Maciej W. Rozycki
+ * Copyright (C) 2002, 2003, 2005 Maciej W. Rozycki
*/
#include <linux/kernel.h>
@@ -41,6 +41,7 @@
#include <asm/dec/ioasic_addrs.h>
#include <asm/dec/ioasic_ints.h>
#include <asm/dec/machtype.h>
+#include <asm/dec/system.h>
#include <asm/dec/tc.h>
#define DEC_SCSI_SREG 0
@@ -183,7 +184,8 @@ static int dec_esp_detect(Scsi_Host_Template * tpnt)
esp->dregs = 0;
/* ESP register base */
- esp->eregs = (struct ESP_regs *) (system_base + IOASIC_SCSI);
+ esp->eregs = (void *)CKSEG1ADDR(dec_kn_slot_base +
+ IOASIC_SCSI);
/* Set the command buffer */
esp->esp_command = (volatile unsigned char *) cmd_buffer;
@@ -228,10 +230,11 @@ static int dec_esp_detect(Scsi_Host_Template * tpnt)
mem_start = get_tc_base_addr(slot);
/* Store base addr into esp struct */
- esp->slot = PHYSADDR(mem_start);
+ esp->slot = CPHYSADDR(mem_start);
esp->dregs = 0;
- esp->eregs = (struct ESP_regs *) (mem_start + DEC_SCSI_SREG);
+ esp->eregs = (void *)CKSEG1ADDR(mem_start +
+ DEC_SCSI_SREG);
esp->do_pio_cmds = 1;
/* Set the command buffer */
@@ -513,14 +516,15 @@ static void dma_advance_sg(struct scsi_cmnd * sp)
static void pmaz_dma_drain(struct NCR_ESP *esp)
{
memcpy(phys_to_virt(esp_virt_buffer),
- (void *)KSEG1ADDR(esp->slot + DEC_SCSI_SRAM + ESP_TGT_DMA_SIZE),
- scsi_current_length);
+ (void *)CKSEG1ADDR(esp->slot + DEC_SCSI_SRAM +
+ ESP_TGT_DMA_SIZE),
+ scsi_current_length);
}
static void pmaz_dma_init_read(struct NCR_ESP *esp, u32 vaddress, int length)
{
volatile u32 *dmareg =
- (volatile u32 *)KSEG1ADDR(esp->slot + DEC_SCSI_DMAREG);
+ (volatile u32 *)CKSEG1ADDR(esp->slot + DEC_SCSI_DMAREG);
if (length > ESP_TGT_DMA_SIZE)
length = ESP_TGT_DMA_SIZE;
@@ -536,9 +540,10 @@ static void pmaz_dma_init_read(struct NCR_ESP *esp, u32 vaddress, int length)
static void pmaz_dma_init_write(struct NCR_ESP *esp, u32 vaddress, int length)
{
volatile u32 *dmareg =
- (volatile u32 *)KSEG1ADDR(esp->slot + DEC_SCSI_DMAREG);
+ (volatile u32 *)CKSEG1ADDR(esp->slot + DEC_SCSI_DMAREG);
- memcpy((void *)KSEG1ADDR(esp->slot + DEC_SCSI_SRAM + ESP_TGT_DMA_SIZE),
+ memcpy((void *)CKSEG1ADDR(esp->slot + DEC_SCSI_SRAM +
+ ESP_TGT_DMA_SIZE),
phys_to_virt(vaddress), length);
wmb();
diff --git a/drivers/scsi/dpt_i2o.c b/drivers/scsi/dpt_i2o.c
index 7235f94f1191..c28e3aea1c3c 100644
--- a/drivers/scsi/dpt_i2o.c
+++ b/drivers/scsi/dpt_i2o.c
@@ -1037,18 +1037,10 @@ static void adpt_i2o_delete_hba(adpt_hba* pHba)
if(pHba->msg_addr_virt != pHba->base_addr_virt){
iounmap(pHba->msg_addr_virt);
}
- if(pHba->hrt) {
- kfree(pHba->hrt);
- }
- if(pHba->lct){
- kfree(pHba->lct);
- }
- if(pHba->status_block) {
- kfree(pHba->status_block);
- }
- if(pHba->reply_pool){
- kfree(pHba->reply_pool);
- }
+ kfree(pHba->hrt);
+ kfree(pHba->lct);
+ kfree(pHba->status_block);
+ kfree(pHba->reply_pool);
for(d = pHba->devices; d ; d = next){
next = d->next;
@@ -1218,8 +1210,7 @@ static s32 adpt_i2o_post_this(adpt_hba* pHba, u32* data, int len)
printk(KERN_WARNING"dpti%d: Timeout waiting for message frame!\n", pHba->unit);
return -ETIMEDOUT;
}
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(1);
+ schedule_timeout_uninterruptible(1);
} while(m == EMPTY_QUEUE);
msg = pHba->msg_addr_virt + m;
@@ -1294,8 +1285,7 @@ static s32 adpt_i2o_reset_hba(adpt_hba* pHba)
printk(KERN_WARNING"Timeout waiting for message!\n");
return -ETIMEDOUT;
}
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(1);
+ schedule_timeout_uninterruptible(1);
} while (m == EMPTY_QUEUE);
status = (u8*)kmalloc(4, GFP_KERNEL|ADDR32);
@@ -1327,8 +1317,7 @@ static s32 adpt_i2o_reset_hba(adpt_hba* pHba)
return -ETIMEDOUT;
}
rmb();
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(1);
+ schedule_timeout_uninterruptible(1);
}
if(*status == 0x01 /*I2O_EXEC_IOP_RESET_IN_PROGRESS*/) {
@@ -1345,8 +1334,7 @@ static s32 adpt_i2o_reset_hba(adpt_hba* pHba)
printk(KERN_ERR "%s:Timeout waiting for IOP Reset.\n",pHba->name);
return -ETIMEDOUT;
}
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(1);
+ schedule_timeout_uninterruptible(1);
} while (m == EMPTY_QUEUE);
// Flush the offset
adpt_send_nop(pHba, m);
@@ -1917,11 +1905,8 @@ static int adpt_ioctl(struct inode *inode, struct file *file, uint cmd,
return -ENXIO;
}
- while((volatile u32) pHba->state & DPTI_STATE_RESET ) {
- set_task_state(current,TASK_UNINTERRUPTIBLE);
- schedule_timeout(2);
-
- }
+ while((volatile u32) pHba->state & DPTI_STATE_RESET )
+ schedule_timeout_uninterruptible(2);
switch (cmd) {
// TODO: handle 3 cases
@@ -2635,8 +2620,7 @@ static s32 adpt_send_nop(adpt_hba*pHba,u32 m)
printk(KERN_ERR "%s: Timeout waiting for message frame!\n",pHba->name);
return 2;
}
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(1);
+ schedule_timeout_uninterruptible(1);
}
msg = (u32 __iomem *)(pHba->msg_addr_virt + m);
writel( THREE_WORD_MSG_SIZE | SGL_OFFSET_0,&msg[0]);
@@ -2670,8 +2654,7 @@ static s32 adpt_i2o_init_outbound_q(adpt_hba* pHba)
printk(KERN_WARNING"%s: Timeout waiting for message frame\n",pHba->name);
return -ETIMEDOUT;
}
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(1);
+ schedule_timeout_uninterruptible(1);
} while(m == EMPTY_QUEUE);
msg=(u32 __iomem *)(pHba->msg_addr_virt+m);
@@ -2709,21 +2692,18 @@ static s32 adpt_i2o_init_outbound_q(adpt_hba* pHba)
printk(KERN_WARNING"%s: Timeout Initializing\n",pHba->name);
return -ETIMEDOUT;
}
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(1);
+ schedule_timeout_uninterruptible(1);
} while (1);
// If the command was successful, fill the fifo with our reply
// message packets
if(*status != 0x04 /*I2O_EXEC_OUTBOUND_INIT_COMPLETE*/) {
- kfree((void*)status);
+ kfree(status);
return -2;
}
- kfree((void*)status);
+ kfree(status);
- if(pHba->reply_pool != NULL){
- kfree(pHba->reply_pool);
- }
+ kfree(pHba->reply_pool);
pHba->reply_pool = (u32*)kmalloc(pHba->reply_fifo_size * REPLY_FRAME_SIZE * 4, GFP_KERNEL|ADDR32);
if(!pHba->reply_pool){
@@ -2788,8 +2768,7 @@ static s32 adpt_i2o_status_get(adpt_hba* pHba)
pHba->name);
return -ETIMEDOUT;
}
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(1);
+ schedule_timeout_uninterruptible(1);
} while(m==EMPTY_QUEUE);
@@ -2816,8 +2795,7 @@ static s32 adpt_i2o_status_get(adpt_hba* pHba)
return -ETIMEDOUT;
}
rmb();
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(1);
+ schedule_timeout_uninterruptible(1);
}
// Set up our number of outbound and inbound messages
@@ -2941,8 +2919,7 @@ static int adpt_i2o_build_sys_table(void)
sys_tbl_len = sizeof(struct i2o_sys_tbl) + // Header + IOPs
(hba_count) * sizeof(struct i2o_sys_tbl_entry);
- if(sys_tbl)
- kfree(sys_tbl);
+ kfree(sys_tbl);
sys_tbl = kmalloc(sys_tbl_len, GFP_KERNEL|ADDR32);
if(!sys_tbl) {
diff --git a/drivers/scsi/eata.c b/drivers/scsi/eata.c
index c10e45b94b62..b3f9de8f7595 100644
--- a/drivers/scsi/eata.c
+++ b/drivers/scsi/eata.c
@@ -941,8 +941,6 @@ static int eata2x_slave_configure(struct scsi_device *dev)
{
int tqd, utqd;
char *tag_suffix, *link_suffix;
- struct Scsi_Host *shost = dev->host;
- struct hostdata *ha = (struct hostdata *)shost->hostdata;
utqd = MAX_CMD_PER_LUN;
tqd = max_queue_depth;
@@ -973,8 +971,8 @@ static int eata2x_slave_configure(struct scsi_device *dev)
else
link_suffix = "";
- printk("%s: scsi%d, channel %d, id %d, lun %d, cmds/lun %d%s%s.\n",
- ha->board_name, shost->host_no, dev->channel, dev->id, dev->lun,
+ sdev_printk(KERN_INFO, dev,
+ "cmds/lun %d%s%s.\n",
dev->queue_depth, link_suffix, tag_suffix);
return 0;
@@ -1357,7 +1355,7 @@ static int port_detect(unsigned long port_base, unsigned int j,
for (i = 0; i < shost->can_queue; i++) {
size_t sz = shost->sg_tablesize *sizeof(struct sg_list);
- unsigned int gfp_mask = (shost->unchecked_isa_dma ? GFP_DMA : 0) | GFP_ATOMIC;
+ gfp_t gfp_mask = (shost->unchecked_isa_dma ? GFP_DMA : 0) | GFP_ATOMIC;
ha->cp[i].sglist = kmalloc(sz, gfp_mask);
if (!ha->cp[i].sglist) {
printk
@@ -1813,9 +1811,8 @@ static int eata2x_queuecommand(struct scsi_cmnd *SCpnt,
SCpnt->host_scribble = (unsigned char *)&cpp->cpp_index;
if (do_trace)
- printk("%s: qcomm, mbox %d, target %d.%d:%d, pid %ld.\n",
- ha->board_name, i, SCpnt->device->channel, SCpnt->device->id,
- SCpnt->device->lun, SCpnt->pid);
+ scmd_printk(KERN_INFO, SCpnt,
+ "qcomm, mbox %d, pid %ld.\n", i, SCpnt->pid);
cpp->reqsen = 1;
cpp->dispri = 1;
@@ -1847,9 +1844,8 @@ static int eata2x_queuecommand(struct scsi_cmnd *SCpnt,
if (do_dma(shost->io_port, cpp->cp_dma_addr, SEND_CP_DMA)) {
unmap_dma(i, ha);
SCpnt->host_scribble = NULL;
- printk("%s: qcomm, target %d.%d:%d, pid %ld, adapter busy.\n",
- ha->board_name, SCpnt->device->channel, SCpnt->device->id,
- SCpnt->device->lun, SCpnt->pid);
+ scmd_printk(KERN_INFO, SCpnt,
+ "qcomm, pid %ld, adapter busy.\n", SCpnt->pid);
return 1;
}
@@ -1864,16 +1860,14 @@ static int eata2x_eh_abort(struct scsi_cmnd *SCarg)
unsigned int i;
if (SCarg->host_scribble == NULL) {
- printk("%s: abort, target %d.%d:%d, pid %ld inactive.\n",
- ha->board_name, SCarg->device->channel, SCarg->device->id,
- SCarg->device->lun, SCarg->pid);
+ scmd_printk(KERN_INFO, SCarg,
+ "abort, pid %ld inactive.\n", SCarg->pid);
return SUCCESS;
}
i = *(unsigned int *)SCarg->host_scribble;
- printk("%s: abort, mbox %d, target %d.%d:%d, pid %ld.\n",
- ha->board_name, i, SCarg->device->channel, SCarg->device->id,
- SCarg->device->lun, SCarg->pid);
+ scmd_printk(KERN_WARNING, SCarg,
+ "abort, mbox %d, pid %ld.\n", i, SCarg->pid);
if (i >= shost->can_queue)
panic("%s: abort, invalid SCarg->host_scribble.\n", ha->board_name);
@@ -1934,9 +1928,8 @@ static int eata2x_eh_host_reset(struct scsi_cmnd *SCarg)
struct Scsi_Host *shost = SCarg->device->host;
struct hostdata *ha = (struct hostdata *)shost->hostdata;
- printk("%s: reset, enter, target %d.%d:%d, pid %ld.\n",
- ha->board_name, SCarg->device->channel, SCarg->device->id,
- SCarg->device->lun, SCarg->pid);
+ scmd_printk(KERN_INFO, SCarg,
+ "reset, enter, pid %ld.\n", SCarg->pid);
spin_lock_irq(shost->host_lock);
@@ -2253,12 +2246,11 @@ static int reorder(struct hostdata *ha, unsigned long cursec,
k = il[n];
cpp = &ha->cp[k];
SCpnt = cpp->SCpnt;
- printk
- ("%s %d.%d:%d pid %ld mb %d fc %d nr %d sec %ld ns %ld"
+ scmd_printk(KERN_INFO, SCpnt,
+ "%s pid %ld mb %d fc %d nr %d sec %ld ns %ld"
" cur %ld s:%c r:%c rev:%c in:%c ov:%c xd %d.\n",
(ihdlr ? "ihdlr" : "qcomm"),
- SCpnt->device->channel, SCpnt->device->id,
- SCpnt->device->lun, SCpnt->pid, k, flushcount,
+ SCpnt->pid, k, flushcount,
n_ready, SCpnt->request->sector,
SCpnt->request->nr_sectors, cursec, YESNO(s),
YESNO(r), YESNO(rev), YESNO(input_only),
@@ -2301,12 +2293,11 @@ static void flush_dev(struct scsi_device *dev, unsigned long cursec,
SCpnt = cpp->SCpnt;
if (do_dma(dev->host->io_port, cpp->cp_dma_addr, SEND_CP_DMA)) {
- printk
- ("%s: %s, target %d.%d:%d, pid %ld, mbox %d, adapter"
- " busy, will abort.\n", ha->board_name,
+ scmd_printk(KERN_INFO, SCpnt,
+ "%s, pid %ld, mbox %d, adapter"
+ " busy, will abort.\n",
(ihdlr ? "ihdlr" : "qcomm"),
- SCpnt->device->channel, SCpnt->device->id,
- SCpnt->device->lun, SCpnt->pid, k);
+ SCpnt->pid, k);
ha->cp_stat[k] = ABORTING;
continue;
}
@@ -2542,11 +2533,10 @@ static irqreturn_t ihdlr(int irq, struct Scsi_Host *shost)
spp->adapter_status != ASST && ha->iocount <= 1000) ||
do_trace || msg_byte(spp->target_status))
#endif
- printk("%s: ihdlr, mbox %2d, err 0x%x:%x,"
- " target %d.%d:%d, pid %ld, reg 0x%x, count %d.\n",
- ha->board_name, i, spp->adapter_status, spp->target_status,
- SCpnt->device->channel, SCpnt->device->id,
- SCpnt->device->lun, SCpnt->pid, reg, ha->iocount);
+ scmd_printk(KERN_INFO, SCpnt, "ihdlr, mbox %2d, err 0x%x:%x,"
+ " pid %ld, reg 0x%x, count %d.\n",
+ i, spp->adapter_status, spp->target_status,
+ SCpnt->pid, reg, ha->iocount);
unmap_dma(i, ha);
@@ -2590,8 +2580,7 @@ static int eata2x_release(struct Scsi_Host *shost)
unsigned int i;
for (i = 0; i < shost->can_queue; i++)
- if ((&ha->cp[i])->sglist)
- kfree((&ha->cp[i])->sglist);
+ kfree((&ha->cp[i])->sglist);
for (i = 0; i < shost->can_queue; i++)
pci_unmap_single(ha->pdev, ha->cp[i].cp_dma_addr,
diff --git a/drivers/scsi/eata_pio.c b/drivers/scsi/eata_pio.c
index 42c6e35f801c..23beb48c79c5 100644
--- a/drivers/scsi/eata_pio.c
+++ b/drivers/scsi/eata_pio.c
@@ -384,7 +384,9 @@ static int eata_pio_queue(struct scsi_cmnd *cmd,
cp->status = USED; /* claim free slot */
- DBG(DBG_QUEUE, printk(KERN_DEBUG "eata_pio_queue pid %ld, target: %x, lun:" " %x, y %d\n", cmd->pid, cmd->device->id, cmd->device->lun, y));
+ DBG(DBG_QUEUE, scmd_printk(KERN_DEBUG, cmd,
+ "eata_pio_queue pid %ld, y %d\n",
+ cmd->pid, y));
cmd->scsi_done = (void *) done;
@@ -427,7 +429,9 @@ static int eata_pio_queue(struct scsi_cmnd *cmd,
if (eata_pio_send_command(base, EATA_CMD_PIO_SEND_CP)) {
cmd->result = DID_BUS_BUSY << 16;
- printk(KERN_NOTICE "eata_pio_queue target %d, pid %ld, HBA busy, " "returning DID_BUS_BUSY, done.\n", cmd->device->id, cmd->pid);
+ scmd_printk(KERN_NOTICE, cmd,
+ "eata_pio_queue pid %ld, HBA busy, "
+ "returning DID_BUS_BUSY, done.\n", cmd->pid);
done(cmd);
cp->status = FREE;
return (0);
@@ -440,7 +444,9 @@ static int eata_pio_queue(struct scsi_cmnd *cmd,
for (x = 0; x < hd->cppadlen; x++)
outw(0, base + HA_RDATA);
- DBG(DBG_QUEUE, printk(KERN_DEBUG "Queued base %#.4lx pid: %ld target: %x " "lun: %x slot %d irq %d\n", (long) sh->base, cmd->pid, cmd->device->id, cmd->device->lun, y, sh->irq));
+ DBG(DBG_QUEUE, scmd_printk(KERN_DEBUG, cmd,
+ "Queued base %#.4lx pid: %ld "
+ "slot %d irq %d\n", (long) sh->base, cmd->pid, y, sh->irq));
return (0);
}
@@ -449,8 +455,9 @@ static int eata_pio_abort(struct scsi_cmnd *cmd)
{
uint loop = HZ;
- DBG(DBG_ABNORM, printk(KERN_WARNING "eata_pio_abort called pid: %ld " "target: %x lun: %x\n", cmd->pid, cmd->device->id, cmd->device->lun));
-
+ DBG(DBG_ABNORM, scmd_printk(KERN_WARNING, cmd,
+ "eata_pio_abort called pid: %ld\n",
+ cmd->pid));
while (inb(cmd->device->host->base + HA_RAUXSTAT) & HA_ABUSY)
if (--loop == 0) {
@@ -484,7 +491,9 @@ static int eata_pio_host_reset(struct scsi_cmnd *cmd)
struct scsi_cmnd *sp;
struct Scsi_Host *host = cmd->device->host;
- DBG(DBG_ABNORM, printk(KERN_WARNING "eata_pio_reset called pid:%ld target:" " %x lun: %x\n", cmd->pid, cmd->device->id, cmd->device->lun));
+ DBG(DBG_ABNORM, scmd_printk(KERN_WARNING, cmd,
+ "eata_pio_reset called pid:%ld\n",
+ cmd->pid));
spin_lock_irq(host->host_lock);
diff --git a/drivers/scsi/fd_mcs.c b/drivers/scsi/fd_mcs.c
index d59d449a9e4d..6d44602aae78 100644
--- a/drivers/scsi/fd_mcs.c
+++ b/drivers/scsi/fd_mcs.c
@@ -671,7 +671,7 @@ static irqreturn_t fd_mcs_intr(int irq, void *dev_id, struct pt_regs *regs)
outb(0x40 | FIFO_COUNT, Interrupt_Cntl_port);
outb(0x82, SCSI_Cntl_port); /* Bus Enable + Select */
- outb(adapter_mask | (1 << current_SC->device->id), SCSI_Data_NoACK_port);
+ outb(adapter_mask | (1 << scmd_id(current_SC)), SCSI_Data_NoACK_port);
/* Stop arbitration and enable parity */
outb(0x10 | PARITY_MASK, TMC_Cntl_port);
@@ -683,7 +683,7 @@ static irqreturn_t fd_mcs_intr(int irq, void *dev_id, struct pt_regs *regs)
status = inb(SCSI_Status_port);
if (!(status & 0x01)) {
/* Try again, for slow devices */
- if (fd_mcs_select(shpnt, current_SC->device->id)) {
+ if (fd_mcs_select(shpnt, scmd_id(current_SC))) {
#if EVERY_ACCESS
printk(" SFAIL ");
#endif
diff --git a/drivers/scsi/fdomain.c b/drivers/scsi/fdomain.c
index 3b2a5bf5c43e..7334244397d1 100644
--- a/drivers/scsi/fdomain.c
+++ b/drivers/scsi/fdomain.c
@@ -1154,7 +1154,7 @@ static irqreturn_t do_fdomain_16x0_intr(int irq, void *dev_id,
outb(0x40 | FIFO_COUNT, port_base + Interrupt_Cntl);
outb(0x82, port_base + SCSI_Cntl); /* Bus Enable + Select */
- outb(adapter_mask | (1 << current_SC->device->id), port_base + SCSI_Data_NoACK);
+ outb(adapter_mask | (1 << scmd_id(current_SC)), port_base + SCSI_Data_NoACK);
/* Stop arbitration and enable parity */
outb(0x10 | PARITY_MASK, port_base + TMC_Cntl);
@@ -1166,7 +1166,7 @@ static irqreturn_t do_fdomain_16x0_intr(int irq, void *dev_id,
status = inb(port_base + SCSI_Status);
if (!(status & 0x01)) {
/* Try again, for slow devices */
- if (fdomain_select( current_SC->device->id )) {
+ if (fdomain_select( scmd_id(current_SC) )) {
#if EVERY_ACCESS
printk( " SFAIL " );
#endif
diff --git a/drivers/scsi/gvp11.c b/drivers/scsi/gvp11.c
index d12342fa8199..ab22387c9df1 100644
--- a/drivers/scsi/gvp11.c
+++ b/drivers/scsi/gvp11.c
@@ -2,7 +2,6 @@
#include <linux/mm.h>
#include <linux/blkdev.h>
#include <linux/sched.h>
-#include <linux/version.h>
#include <linux/init.h>
#include <linux/interrupt.h>
diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c
index 02fe371b0ab8..5b9c2c5a7f0e 100644
--- a/drivers/scsi/hosts.c
+++ b/drivers/scsi/hosts.c
@@ -30,6 +30,7 @@
#include <linux/init.h>
#include <linux/completion.h>
#include <linux/transport_class.h>
+#include <linux/platform_device.h>
#include <scsi/scsi_device.h>
#include <scsi/scsi_host.h>
@@ -139,11 +140,11 @@ int scsi_host_set_state(struct Scsi_Host *shost, enum scsi_host_state state)
illegal:
SCSI_LOG_ERROR_RECOVERY(1,
- dev_printk(KERN_ERR, &shost->shost_gendev,
- "Illegal host state transition"
- "%s->%s\n",
- scsi_host_state_name(oldstate),
- scsi_host_state_name(state)));
+ shost_printk(KERN_ERR, shost,
+ "Illegal host state transition"
+ "%s->%s\n",
+ scsi_host_state_name(oldstate),
+ scsi_host_state_name(state)));
return -EINVAL;
}
EXPORT_SYMBOL(scsi_host_set_state);
@@ -287,7 +288,8 @@ static void scsi_host_dev_release(struct device *dev)
struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize)
{
struct Scsi_Host *shost;
- int gfp_mask = GFP_KERNEL, rval;
+ gfp_t gfp_mask = GFP_KERNEL;
+ int rval;
if (sht->unchecked_isa_dma && privsize)
gfp_mask |= __GFP_DMA;
diff --git a/drivers/scsi/ibmmca.c b/drivers/scsi/ibmmca.c
index 19392f651272..8d97999db60e 100644
--- a/drivers/scsi/ibmmca.c
+++ b/drivers/scsi/ibmmca.c
@@ -18,12 +18,6 @@
*/
#include <linux/config.h>
-#ifndef LINUX_VERSION_CODE
-#include <linux/version.h>
-#endif
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,45)
-#error "This driver works only with kernel 2.5.45 or higher!"
-#endif
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/types.h>
@@ -1860,7 +1854,10 @@ static int ibmmca_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
next_ldn(host_index) = 7;
if (current_ldn == next_ldn(host_index)) { /* One circle done ? */
/* no non-processing ldn found */
- printk("IBM MCA SCSI: Cannot assign SCSI-device dynamically!\n" " On ldn 7-14 SCSI-commands everywhere in progress.\n" " Reporting DID_NO_CONNECT for device (%d,%d).\n", target, cmd->device->lun);
+ scmd_printk(KERN_WARNING, cmd,
+ "IBM MCA SCSI: Cannot assign SCSI-device dynamically!\n"
+ " On ldn 7-14 SCSI-commands everywhere in progress.\n"
+ " Reporting DID_NO_CONNECT for device.\n");
cmd->result = DID_NO_CONNECT << 16; /* return no connect */
if (done)
done(cmd);
diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.c b/drivers/scsi/ibmvscsi/ibmvscsi.c
index ff25210b00ba..822b9fa706f3 100644
--- a/drivers/scsi/ibmvscsi/ibmvscsi.c
+++ b/drivers/scsi/ibmvscsi/ibmvscsi.c
@@ -1543,13 +1543,16 @@ static struct vio_device_id ibmvscsi_device_table[] __devinitdata = {
{"vscsi", "IBM,v-scsi"},
{ "", "" }
};
-
MODULE_DEVICE_TABLE(vio, ibmvscsi_device_table);
+
static struct vio_driver ibmvscsi_driver = {
- .name = "ibmvscsi",
.id_table = ibmvscsi_device_table,
.probe = ibmvscsi_probe,
- .remove = ibmvscsi_remove
+ .remove = ibmvscsi_remove,
+ .driver = {
+ .name = "ibmvscsi",
+ .owner = THIS_MODULE,
+ }
};
int __init ibmvscsi_module_init(void)
diff --git a/drivers/scsi/ibmvscsi/iseries_vscsi.c b/drivers/scsi/ibmvscsi/iseries_vscsi.c
index e9202f2a8276..1045872b0175 100644
--- a/drivers/scsi/ibmvscsi/iseries_vscsi.c
+++ b/drivers/scsi/ibmvscsi/iseries_vscsi.c
@@ -28,10 +28,10 @@
* hypervisor system or a converged hypervisor system.
*/
-#include <asm/iSeries/vio.h>
-#include <asm/iSeries/HvLpEvent.h>
-#include <asm/iSeries/HvTypes.h>
-#include <asm/iSeries/HvLpConfig.h>
+#include <asm/iseries/vio.h>
+#include <asm/iseries/hv_lp_event.h>
+#include <asm/iseries/hv_types.h>
+#include <asm/iseries/hv_lp_config.h>
#include <asm/vio.h>
#include <linux/device.h>
#include "ibmvscsi.h"
diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c
index 3d62c9bcbff7..3553da0e1cd5 100644
--- a/drivers/scsi/ide-scsi.c
+++ b/drivers/scsi/ide-scsi.c
@@ -184,13 +184,16 @@ static void idescsi_input_buffers (ide_drive_t *drive, idescsi_pc_t *pc, unsigne
unsigned long flags;
local_irq_save(flags);
- buf = kmap_atomic(pc->sg->page, KM_IRQ0) + pc->sg->offset;
- drive->hwif->atapi_input_bytes(drive, buf + pc->b_count, count);
+ buf = kmap_atomic(pc->sg->page, KM_IRQ0) +
+ pc->sg->offset;
+ drive->hwif->atapi_input_bytes(drive,
+ buf + pc->b_count, count);
kunmap_atomic(buf - pc->sg->offset, KM_IRQ0);
local_irq_restore(flags);
} else {
buf = page_address(pc->sg->page) + pc->sg->offset;
- drive->hwif->atapi_input_bytes(drive, buf + pc->b_count, count);
+ drive->hwif->atapi_input_bytes(drive,
+ buf + pc->b_count, count);
}
bcount -= count; pc->b_count += count;
if (pc->b_count == pc->sg->length) {
@@ -216,13 +219,16 @@ static void idescsi_output_buffers (ide_drive_t *drive, idescsi_pc_t *pc, unsign
unsigned long flags;
local_irq_save(flags);
- buf = kmap_atomic(pc->sg->page, KM_IRQ0) + pc->sg->offset;
- drive->hwif->atapi_output_bytes(drive, buf + pc->b_count, count);
+ buf = kmap_atomic(pc->sg->page, KM_IRQ0) +
+ pc->sg->offset;
+ drive->hwif->atapi_output_bytes(drive,
+ buf + pc->b_count, count);
kunmap_atomic(buf - pc->sg->offset, KM_IRQ0);
local_irq_restore(flags);
} else {
buf = page_address(pc->sg->page) + pc->sg->offset;
- drive->hwif->atapi_output_bytes(drive, buf + pc->b_count, count);
+ drive->hwif->atapi_output_bytes(drive,
+ buf + pc->b_count, count);
}
bcount -= count; pc->b_count += count;
if (pc->b_count == pc->sg->length) {
@@ -325,9 +331,9 @@ static int idescsi_check_condition(ide_drive_t *drive, struct request *failed_co
rq = kmalloc (sizeof (struct request), GFP_ATOMIC);
buf = kmalloc(SCSI_SENSE_BUFFERSIZE, GFP_ATOMIC);
if (pc == NULL || rq == NULL || buf == NULL) {
- if (pc) kfree(pc);
- if (rq) kfree(rq);
- if (buf) kfree(buf);
+ kfree(buf);
+ kfree(rq);
+ kfree(pc);
return -ENOMEM;
}
memset (pc, 0, sizeof (idescsi_pc_t));
@@ -389,6 +395,7 @@ static int idescsi_end_request (ide_drive_t *drive, int uptodate, int nrsecs)
int log = test_bit(IDESCSI_LOG_CMD, &scsi->log);
struct Scsi_Host *host;
u8 *scsi_buf;
+ int errors = rq->errors;
unsigned long flags;
if (!(rq->flags & (REQ_SPECIAL|REQ_SENSE))) {
@@ -415,11 +422,11 @@ static int idescsi_end_request (ide_drive_t *drive, int uptodate, int nrsecs)
printk (KERN_WARNING "ide-scsi: %s: timed out for %lu\n",
drive->name, pc->scsi_cmd->serial_number);
pc->scsi_cmd->result = DID_TIME_OUT << 16;
- } else if (rq->errors >= ERROR_MAX) {
+ } else if (errors >= ERROR_MAX) {
pc->scsi_cmd->result = DID_ERROR << 16;
if (log)
printk ("ide-scsi: %s: I/O error for %lu\n", drive->name, pc->scsi_cmd->serial_number);
- } else if (rq->errors) {
+ } else if (errors) {
if (log)
printk ("ide-scsi: %s: check condition for %lu\n", drive->name, pc->scsi_cmd->serial_number);
if (!idescsi_check_condition(drive, rq))
@@ -893,7 +900,7 @@ static int idescsi_queue (struct scsi_cmnd *cmd,
idescsi_pc_t *pc = NULL;
if (!drive) {
- printk (KERN_ERR "ide-scsi: drive id %d not present\n", cmd->device->id);
+ scmd_printk (KERN_ERR, cmd, "drive not present\n");
goto abort;
}
scsi = drive_to_idescsi(drive);
@@ -943,8 +950,8 @@ static int idescsi_queue (struct scsi_cmnd *cmd,
spin_lock_irq(host->host_lock);
return 0;
abort:
- if (pc) kfree (pc);
- if (rq) kfree (rq);
+ kfree (pc);
+ kfree (rq);
cmd->result = DID_ERROR << 16;
done(cmd);
return 0;
diff --git a/drivers/scsi/imm.c b/drivers/scsi/imm.c
index 65e845665b85..fc0f30ae0f77 100644
--- a/drivers/scsi/imm.c
+++ b/drivers/scsi/imm.c
@@ -830,7 +830,7 @@ static int imm_engine(imm_struct *dev, struct scsi_cmnd *cmd)
/* Phase 2 - We are now talking to the scsi bus */
case 2:
- if (!imm_select(dev, cmd->device->id)) {
+ if (!imm_select(dev, scmd_id(cmd))) {
imm_fail(dev, DID_NO_CONNECT);
return 0;
}
diff --git a/drivers/scsi/in2000.c b/drivers/scsi/in2000.c
index aed7e64865fa..fe387b5ce8bd 100644
--- a/drivers/scsi/in2000.c
+++ b/drivers/scsi/in2000.c
@@ -343,7 +343,7 @@ static int in2000_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
instance = cmd->device->host;
hostdata = (struct IN2000_hostdata *) instance->hostdata;
- DB(DB_QUEUE_COMMAND, printk("Q-%d-%02x-%ld(", cmd->device->id, cmd->cmnd[0], cmd->pid))
+ DB(DB_QUEUE_COMMAND, scmd_printk(KERN_DEBUG, cmd, "Q-%02x-%ld(", cmd->cmnd[0], cmd->pid))
/* Set up a few fields in the Scsi_Cmnd structure for our own use:
* - host_scribble is the pointer to the next cmd in the input queue
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
index babd48363402..e0039dfae8e5 100644
--- a/drivers/scsi/ipr.c
+++ b/drivers/scsi/ipr.c
@@ -4944,6 +4944,7 @@ static int ipr_reset_restore_cfg_space(struct ipr_cmnd *ipr_cmd)
int rc;
ENTER;
+ pci_unblock_user_cfg_access(ioa_cfg->pdev);
rc = pci_restore_state(ioa_cfg->pdev);
if (rc != PCIBIOS_SUCCESSFUL) {
@@ -4998,6 +4999,7 @@ static int ipr_reset_start_bist(struct ipr_cmnd *ipr_cmd)
int rc;
ENTER;
+ pci_block_user_cfg_access(ioa_cfg->pdev);
rc = pci_write_config_byte(ioa_cfg->pdev, PCI_BIST, PCI_BIST_START);
if (rc != PCIBIOS_SUCCESSFUL) {
diff --git a/drivers/scsi/ipr.h b/drivers/scsi/ipr.h
index cbff3ea3cd89..8cf967108500 100644
--- a/drivers/scsi/ipr.h
+++ b/drivers/scsi/ipr.h
@@ -1114,9 +1114,8 @@ struct ipr_ucode_image_header {
#define ipr_warn(...) printk(KERN_WARNING IPR_NAME": "__VA_ARGS__)
#define ipr_dbg(...) IPR_DBG_CMD(printk(KERN_INFO IPR_NAME ": "__VA_ARGS__))
-#define ipr_sdev_printk(level, sdev, fmt, ...) \
- printk(level IPR_NAME ": %d:%d:%d:%d: " fmt, sdev->host->host_no, \
- sdev->channel, sdev->id, sdev->lun, ##__VA_ARGS__)
+#define ipr_sdev_printk(level, sdev, fmt, args...) \
+ sdev_printk(level, sdev, fmt, ## args)
#define ipr_sdev_err(sdev, fmt, ...) \
ipr_sdev_printk(KERN_ERR, sdev, fmt, ##__VA_ARGS__)
diff --git a/drivers/scsi/ips.c b/drivers/scsi/ips.c
index 4cdd891781b1..cd9b95db5a7d 100644
--- a/drivers/scsi/ips.c
+++ b/drivers/scsi/ips.c
@@ -219,15 +219,12 @@ module_param(ips, charp, 0);
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,0)
#include <linux/blk.h>
#include "sd.h"
-#define IPS_SG_ADDRESS(sg) ((sg)->address)
#define IPS_LOCK_SAVE(lock,flags) spin_lock_irqsave(&io_request_lock,flags)
#define IPS_UNLOCK_RESTORE(lock,flags) spin_unlock_irqrestore(&io_request_lock,flags)
#ifndef __devexit_p
#define __devexit_p(x) x
#endif
#else
-#define IPS_SG_ADDRESS(sg) (page_address((sg)->page) ? \
- page_address((sg)->page)+(sg)->offset : NULL)
#define IPS_LOCK_SAVE(lock,flags) do{spin_lock(lock);(void)flags;}while(0)
#define IPS_UNLOCK_RESTORE(lock,flags) do{spin_unlock(lock);(void)flags;}while(0)
#endif
@@ -358,6 +355,9 @@ static int ips_init_phase2(int index);
static int ips_init_phase1(struct pci_dev *pci_dev, int *indexPtr);
static int ips_register_scsi(int index);
+static int ips_poll_for_flush_complete(ips_ha_t * ha);
+static void ips_flush_and_reset(ips_ha_t *ha);
+
/*
* global variables
*/
@@ -1125,8 +1125,8 @@ ips_queue(Scsi_Cmnd * SC, void (*done) (Scsi_Cmnd *))
SC->device->channel, SC->device->id, SC->device->lun);
/* Check for command to initiator IDs */
- if ((SC->device->channel > 0)
- && (SC->device->id == ha->ha_id[SC->device->channel])) {
+ if ((scmd_channel(SC) > 0)
+ && (scmd_id(SC) == ha->ha_id[scmd_channel(SC)])) {
SC->result = DID_NO_CONNECT << 16;
done(SC);
@@ -1605,6 +1605,8 @@ ips_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset,
static int
ips_is_passthru(Scsi_Cmnd * SC)
{
+ unsigned long flags;
+
METHOD_TRACE("ips_is_passthru", 1);
if (!SC)
@@ -1622,10 +1624,20 @@ ips_is_passthru(Scsi_Cmnd * SC)
return 1;
else if (SC->use_sg) {
struct scatterlist *sg = SC->request_buffer;
- char *buffer = IPS_SG_ADDRESS(sg);
+ char *buffer;
+
+ /* kmap_atomic() ensures addressability of the user buffer.*/
+ /* local_irq_save() protects the KM_IRQ0 address slot. */
+ local_irq_save(flags);
+ buffer = kmap_atomic(sg->page, KM_IRQ0) + sg->offset;
if (buffer && buffer[0] == 'C' && buffer[1] == 'O' &&
- buffer[2] == 'P' && buffer[3] == 'P')
+ buffer[2] == 'P' && buffer[3] == 'P') {
+ kunmap_atomic(buffer - sg->offset, KM_IRQ0);
+ local_irq_restore(flags);
return 1;
+ }
+ kunmap_atomic(buffer - sg->offset, KM_IRQ0);
+ local_irq_restore(flags);
}
}
return 0;
@@ -2830,10 +2842,10 @@ ips_next(ips_ha_t * ha, int intr)
p = ha->scb_waitlist.head;
while ((p) && (scb = ips_getscb(ha))) {
- if ((p->device->channel > 0)
+ if ((scmd_channel(p) > 0)
&& (ha->
- dcdb_active[p->device->channel -
- 1] & (1 << p->device->id))) {
+ dcdb_active[scmd_channel(p) -
+ 1] & (1 << scmd_id(p)))) {
ips_freescb(ha, scb);
p = (Scsi_Cmnd *) p->host_scribble;
continue;
@@ -3656,14 +3668,21 @@ ips_scmd_buf_write(Scsi_Cmnd * scmd, void *data, unsigned
int i;
unsigned int min_cnt, xfer_cnt;
char *cdata = (char *) data;
+ unsigned char *buffer;
+ unsigned long flags;
struct scatterlist *sg = scmd->request_buffer;
for (i = 0, xfer_cnt = 0;
(i < scmd->use_sg) && (xfer_cnt < count); i++) {
- if (!IPS_SG_ADDRESS(&sg[i]))
- return;
min_cnt = min(count - xfer_cnt, sg[i].length);
- memcpy(IPS_SG_ADDRESS(&sg[i]), &cdata[xfer_cnt],
- min_cnt);
+
+ /* kmap_atomic() ensures addressability of the data buffer.*/
+ /* local_irq_save() protects the KM_IRQ0 address slot. */
+ local_irq_save(flags);
+ buffer = kmap_atomic(sg[i].page, KM_IRQ0) + sg[i].offset;
+ memcpy(buffer, &cdata[xfer_cnt], min_cnt);
+ kunmap_atomic(buffer - sg[i].offset, KM_IRQ0);
+ local_irq_restore(flags);
+
xfer_cnt += min_cnt;
}
@@ -3688,14 +3707,21 @@ ips_scmd_buf_read(Scsi_Cmnd * scmd, void *data, unsigned
int i;
unsigned int min_cnt, xfer_cnt;
char *cdata = (char *) data;
+ unsigned char *buffer;
+ unsigned long flags;
struct scatterlist *sg = scmd->request_buffer;
for (i = 0, xfer_cnt = 0;
(i < scmd->use_sg) && (xfer_cnt < count); i++) {
- if (!IPS_SG_ADDRESS(&sg[i]))
- return;
min_cnt = min(count - xfer_cnt, sg[i].length);
- memcpy(&cdata[xfer_cnt], IPS_SG_ADDRESS(&sg[i]),
- min_cnt);
+
+ /* kmap_atomic() ensures addressability of the data buffer.*/
+ /* local_irq_save() protects the KM_IRQ0 address slot. */
+ local_irq_save(flags);
+ buffer = kmap_atomic(sg[i].page, KM_IRQ0) + sg[i].offset;
+ memcpy(&cdata[xfer_cnt], buffer, min_cnt);
+ kunmap_atomic(buffer - sg[i].offset, KM_IRQ0);
+ local_irq_restore(flags);
+
xfer_cnt += min_cnt;
}
@@ -4491,10 +4517,8 @@ ips_free(ips_ha_t * ha)
ha->enq = NULL;
}
- if (ha->conf) {
- kfree(ha->conf);
- ha->conf = NULL;
- }
+ kfree(ha->conf);
+ ha->conf = NULL;
if (ha->adapt) {
pci_free_consistent(ha->pcidev,
@@ -4512,15 +4536,11 @@ ips_free(ips_ha_t * ha)
ha->logical_drive_info = NULL;
}
- if (ha->nvram) {
- kfree(ha->nvram);
- ha->nvram = NULL;
- }
+ kfree(ha->nvram);
+ ha->nvram = NULL;
- if (ha->subsys) {
- kfree(ha->subsys);
- ha->subsys = NULL;
- }
+ kfree(ha->subsys);
+ ha->subsys = NULL;
if (ha->ioctl_data) {
pci_free_consistent(ha->pcidev, ha->ioctl_len,
@@ -4807,6 +4827,9 @@ ips_isinit_morpheus(ips_ha_t * ha)
uint32_t bits;
METHOD_TRACE("ips_is_init_morpheus", 1);
+
+ if (ips_isintr_morpheus(ha))
+ ips_flush_and_reset(ha);
post = readl(ha->mem_ptr + IPS_REG_I960_MSG0);
bits = readl(ha->mem_ptr + IPS_REG_I2O_HIR);
@@ -4821,6 +4844,94 @@ ips_isinit_morpheus(ips_ha_t * ha)
/****************************************************************************/
/* */
+/* Routine Name: ips_flush_and_reset */
+/* */
+/* Routine Description: */
+/* */
+/* Perform cleanup ( FLUSH and RESET ) when the adapter is in an unknown */
+/* state ( was trying to INIT and an interrupt was already pending ) ... */
+/* */
+/****************************************************************************/
+static void
+ips_flush_and_reset(ips_ha_t *ha)
+{
+ ips_scb_t *scb;
+ int ret;
+ int time;
+ int done;
+ dma_addr_t command_dma;
+
+ /* Create a usuable SCB */
+ scb = pci_alloc_consistent(ha->pcidev, sizeof(ips_scb_t), &command_dma);
+ if (scb) {
+ memset(scb, 0, sizeof(ips_scb_t));
+ ips_init_scb(ha, scb);
+ scb->scb_busaddr = command_dma;
+
+ scb->timeout = ips_cmd_timeout;
+ scb->cdb[0] = IPS_CMD_FLUSH;
+
+ scb->cmd.flush_cache.op_code = IPS_CMD_FLUSH;
+ scb->cmd.flush_cache.command_id = IPS_MAX_CMDS; /* Use an ID that would otherwise not exist */
+ scb->cmd.flush_cache.state = IPS_NORM_STATE;
+ scb->cmd.flush_cache.reserved = 0;
+ scb->cmd.flush_cache.reserved2 = 0;
+ scb->cmd.flush_cache.reserved3 = 0;
+ scb->cmd.flush_cache.reserved4 = 0;
+
+ ret = ips_send_cmd(ha, scb); /* Send the Flush Command */
+
+ if (ret == IPS_SUCCESS) {
+ time = 60 * IPS_ONE_SEC; /* Max Wait time is 60 seconds */
+ done = 0;
+
+ while ((time > 0) && (!done)) {
+ done = ips_poll_for_flush_complete(ha);
+ /* This may look evil, but it's only done during extremely rare start-up conditions ! */
+ udelay(1000);
+ time--;
+ }
+ }
+ }
+
+ /* Now RESET and INIT the adapter */
+ (*ha->func.reset) (ha);
+
+ pci_free_consistent(ha->pcidev, sizeof(ips_scb_t), scb, command_dma);
+ return;
+}
+
+/****************************************************************************/
+/* */
+/* Routine Name: ips_poll_for_flush_complete */
+/* */
+/* Routine Description: */
+/* */
+/* Poll for the Flush Command issued by ips_flush_and_reset() to complete */
+/* All other responses are just taken off the queue and ignored */
+/* */
+/****************************************************************************/
+static int
+ips_poll_for_flush_complete(ips_ha_t * ha)
+{
+ IPS_STATUS cstatus;
+
+ while (TRUE) {
+ cstatus.value = (*ha->func.statupd) (ha);
+
+ if (cstatus.value == 0xffffffff) /* If No Interrupt to process */
+ break;
+
+ /* Success is when we see the Flush Command ID */
+ if (cstatus.fields.command_id == IPS_MAX_CMDS )
+ return 1;
+ }
+
+ return 0;
+}
+
+/****************************************************************************/
+/* */
/* Routine Name: ips_enable_int_copperhead */
/* */
/* Routine Description: */
diff --git a/drivers/scsi/ips.h b/drivers/scsi/ips.h
index 505e967013de..adc6eabbf610 100644
--- a/drivers/scsi/ips.h
+++ b/drivers/scsi/ips.h
@@ -50,6 +50,7 @@
#ifndef _IPS_H_
#define _IPS_H_
+#include <linux/version.h>
#include <asm/uaccess.h>
#include <asm/io.h>
diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c
new file mode 100644
index 000000000000..4fea3e4edaa7
--- /dev/null
+++ b/drivers/scsi/iscsi_tcp.c
@@ -0,0 +1,3642 @@
+/*
+ * iSCSI Initiator over TCP/IP Data-Path
+ *
+ * Copyright (C) 2004 Dmitry Yusupov
+ * Copyright (C) 2004 Alex Aizman
+ * Copyright (C) 2005 Mike Christie
+ * maintained by open-iscsi@googlegroups.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.
+ *
+ * See the file COPYING included with this distribution for more details.
+ *
+ * Credits:
+ * Christoph Hellwig
+ * FUJITA Tomonori
+ * Arne Redlich
+ * Zhenyu Wang
+ */
+
+#include <linux/types.h>
+#include <linux/list.h>
+#include <linux/inet.h>
+#include <linux/blkdev.h>
+#include <linux/crypto.h>
+#include <linux/delay.h>
+#include <linux/kfifo.h>
+#include <linux/scatterlist.h>
+#include <net/tcp.h>
+#include <scsi/scsi_cmnd.h>
+#include <scsi/scsi_device.h>
+#include <scsi/scsi_eh.h>
+#include <scsi/scsi_request.h>
+#include <scsi/scsi_tcq.h>
+#include <scsi/scsi_host.h>
+#include <scsi/scsi.h>
+#include <scsi/scsi_transport_iscsi.h>
+
+#include "iscsi_tcp.h"
+
+MODULE_AUTHOR("Dmitry Yusupov <dmitry_yus@yahoo.com>, "
+ "Alex Aizman <itn780@yahoo.com>");
+MODULE_DESCRIPTION("iSCSI/TCP data-path");
+MODULE_LICENSE("GPL");
+MODULE_VERSION("0:4.409");
+/* #define DEBUG_TCP */
+/* #define DEBUG_SCSI */
+#define DEBUG_ASSERT
+
+#ifdef DEBUG_TCP
+#define debug_tcp(fmt...) printk(KERN_DEBUG "tcp: " fmt)
+#else
+#define debug_tcp(fmt...)
+#endif
+
+#ifdef DEBUG_SCSI
+#define debug_scsi(fmt...) printk(KERN_DEBUG "scsi: " fmt)
+#else
+#define debug_scsi(fmt...)
+#endif
+
+#ifndef DEBUG_ASSERT
+#ifdef BUG_ON
+#undef BUG_ON
+#endif
+#define BUG_ON(expr)
+#endif
+
+#define INVALID_SN_DELTA 0xffff
+
+static unsigned int iscsi_max_lun = 512;
+module_param_named(max_lun, iscsi_max_lun, uint, S_IRUGO);
+
+/* global data */
+static kmem_cache_t *taskcache;
+
+static inline void
+iscsi_buf_init_virt(struct iscsi_buf *ibuf, char *vbuf, int size)
+{
+ sg_init_one(&ibuf->sg, (u8 *)vbuf, size);
+ ibuf->sent = 0;
+}
+
+static inline void
+iscsi_buf_init_iov(struct iscsi_buf *ibuf, char *vbuf, int size)
+{
+ ibuf->sg.page = (void*)vbuf;
+ ibuf->sg.offset = (unsigned int)-1;
+ ibuf->sg.length = size;
+ ibuf->sent = 0;
+}
+
+static inline void*
+iscsi_buf_iov_base(struct iscsi_buf *ibuf)
+{
+ return (char*)ibuf->sg.page + ibuf->sent;
+}
+
+static inline void
+iscsi_buf_init_sg(struct iscsi_buf *ibuf, struct scatterlist *sg)
+{
+ /*
+ * Fastpath: sg element fits into single page
+ */
+ if (sg->length + sg->offset <= PAGE_SIZE && page_count(sg->page) >= 2) {
+ ibuf->sg.page = sg->page;
+ ibuf->sg.offset = sg->offset;
+ ibuf->sg.length = sg->length;
+ } else
+ iscsi_buf_init_iov(ibuf, page_address(sg->page), sg->length);
+ ibuf->sent = 0;
+}
+
+static inline int
+iscsi_buf_left(struct iscsi_buf *ibuf)
+{
+ int rc;
+
+ rc = ibuf->sg.length - ibuf->sent;
+ BUG_ON(rc < 0);
+ return rc;
+}
+
+static inline void
+iscsi_hdr_digest(struct iscsi_conn *conn, struct iscsi_buf *buf,
+ u8* crc)
+{
+ crypto_digest_digest(conn->tx_tfm, &buf->sg, 1, crc);
+ buf->sg.length += sizeof(uint32_t);
+}
+
+static void
+iscsi_conn_failure(struct iscsi_conn *conn, enum iscsi_err err)
+{
+ struct iscsi_session *session = conn->session;
+ unsigned long flags;
+
+ spin_lock_irqsave(&session->lock, flags);
+ if (session->conn_cnt == 1 || session->leadconn == conn)
+ session->state = ISCSI_STATE_FAILED;
+ spin_unlock_irqrestore(&session->lock, flags);
+ set_bit(SUSPEND_BIT, &conn->suspend_tx);
+ set_bit(SUSPEND_BIT, &conn->suspend_rx);
+ iscsi_conn_error(iscsi_handle(conn), err);
+}
+
+static inline int
+iscsi_check_assign_cmdsn(struct iscsi_session *session, struct iscsi_nopin *hdr)
+{
+ uint32_t max_cmdsn = be32_to_cpu(hdr->max_cmdsn);
+ uint32_t exp_cmdsn = be32_to_cpu(hdr->exp_cmdsn);
+
+ if (max_cmdsn < exp_cmdsn -1 &&
+ max_cmdsn > exp_cmdsn - INVALID_SN_DELTA)
+ return ISCSI_ERR_MAX_CMDSN;
+ if (max_cmdsn > session->max_cmdsn ||
+ max_cmdsn < session->max_cmdsn - INVALID_SN_DELTA)
+ session->max_cmdsn = max_cmdsn;
+ if (exp_cmdsn > session->exp_cmdsn ||
+ exp_cmdsn < session->exp_cmdsn - INVALID_SN_DELTA)
+ session->exp_cmdsn = exp_cmdsn;
+
+ return 0;
+}
+
+static inline int
+iscsi_hdr_extract(struct iscsi_conn *conn)
+{
+ struct sk_buff *skb = conn->in.skb;
+
+ if (conn->in.copy >= conn->hdr_size &&
+ conn->in_progress == IN_PROGRESS_WAIT_HEADER) {
+ /*
+ * Zero-copy PDU Header: using connection context
+ * to store header pointer.
+ */
+ if (skb_shinfo(skb)->frag_list == NULL &&
+ !skb_shinfo(skb)->nr_frags)
+ conn->in.hdr = (struct iscsi_hdr *)
+ ((char*)skb->data + conn->in.offset);
+ else {
+ /* ignoring return code since we checked
+ * in.copy before */
+ skb_copy_bits(skb, conn->in.offset,
+ &conn->hdr, conn->hdr_size);
+ conn->in.hdr = &conn->hdr;
+ }
+ conn->in.offset += conn->hdr_size;
+ conn->in.copy -= conn->hdr_size;
+ } else {
+ int hdr_remains;
+ int copylen;
+
+ /*
+ * PDU header scattered across SKB's,
+ * copying it... This'll happen quite rarely.
+ */
+
+ if (conn->in_progress == IN_PROGRESS_WAIT_HEADER)
+ conn->in.hdr_offset = 0;
+
+ hdr_remains = conn->hdr_size - conn->in.hdr_offset;
+ BUG_ON(hdr_remains <= 0);
+
+ copylen = min(conn->in.copy, hdr_remains);
+ skb_copy_bits(skb, conn->in.offset,
+ (char*)&conn->hdr + conn->in.hdr_offset, copylen);
+
+ debug_tcp("PDU gather offset %d bytes %d in.offset %d "
+ "in.copy %d\n", conn->in.hdr_offset, copylen,
+ conn->in.offset, conn->in.copy);
+
+ conn->in.offset += copylen;
+ conn->in.copy -= copylen;
+ if (copylen < hdr_remains) {
+ conn->in_progress = IN_PROGRESS_HEADER_GATHER;
+ conn->in.hdr_offset += copylen;
+ return -EAGAIN;
+ }
+ conn->in.hdr = &conn->hdr;
+ conn->discontiguous_hdr_cnt++;
+ conn->in_progress = IN_PROGRESS_WAIT_HEADER;
+ }
+
+ return 0;
+}
+
+static inline void
+iscsi_ctask_cleanup(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
+{
+ struct scsi_cmnd *sc = ctask->sc;
+ struct iscsi_session *session = conn->session;
+
+ spin_lock(&session->lock);
+ if (unlikely(!sc)) {
+ spin_unlock(&session->lock);
+ return;
+ }
+ if (sc->sc_data_direction == DMA_TO_DEVICE) {
+ struct iscsi_data_task *dtask, *n;
+ /* WRITE: cleanup Data-Out's if any */
+ spin_lock(&conn->lock);
+ list_for_each_entry_safe(dtask, n, &ctask->dataqueue, item) {
+ list_del(&dtask->item);
+ mempool_free(dtask, ctask->datapool);
+ }
+ spin_unlock(&conn->lock);
+ }
+ ctask->xmstate = XMSTATE_IDLE;
+ ctask->r2t = NULL;
+ ctask->sc = NULL;
+ __kfifo_put(session->cmdpool.queue, (void*)&ctask, sizeof(void*));
+ spin_unlock(&session->lock);
+}
+
+/**
+ * iscsi_cmd_rsp - SCSI Command Response processing
+ * @conn: iscsi connection
+ * @ctask: scsi command task
+ **/
+static int
+iscsi_cmd_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
+{
+ int rc;
+ struct iscsi_cmd_rsp *rhdr = (struct iscsi_cmd_rsp *)conn->in.hdr;
+ struct iscsi_session *session = conn->session;
+ struct scsi_cmnd *sc = ctask->sc;
+
+ rc = iscsi_check_assign_cmdsn(session, (struct iscsi_nopin*)rhdr);
+ if (rc) {
+ sc->result = (DID_ERROR << 16);
+ goto out;
+ }
+
+ conn->exp_statsn = be32_to_cpu(rhdr->statsn) + 1;
+
+ sc->result = (DID_OK << 16) | rhdr->cmd_status;
+
+ if (rhdr->response != ISCSI_STATUS_CMD_COMPLETED) {
+ sc->result = (DID_ERROR << 16);
+ goto out;
+ }
+
+ if (rhdr->cmd_status == SAM_STAT_CHECK_CONDITION && conn->senselen) {
+ int sensecopy = min(conn->senselen, SCSI_SENSE_BUFFERSIZE);
+
+ memcpy(sc->sense_buffer, conn->data + 2, sensecopy);
+ debug_scsi("copied %d bytes of sense\n", sensecopy);
+ }
+
+ if (sc->sc_data_direction == DMA_TO_DEVICE)
+ goto out;
+
+ if (rhdr->flags & ISCSI_FLAG_CMD_UNDERFLOW) {
+ int res_count = be32_to_cpu(rhdr->residual_count);
+
+ if (res_count > 0 && res_count <= sc->request_bufflen)
+ sc->resid = res_count;
+ else
+ sc->result = (DID_BAD_TARGET << 16) | rhdr->cmd_status;
+ } else if (rhdr->flags & ISCSI_FLAG_CMD_BIDI_UNDERFLOW)
+ sc->result = (DID_BAD_TARGET << 16) | rhdr->cmd_status;
+ else if (rhdr->flags & ISCSI_FLAG_CMD_OVERFLOW)
+ sc->resid = be32_to_cpu(rhdr->residual_count);
+
+out:
+ debug_scsi("done [sc %lx res %d itt 0x%x]\n",
+ (long)sc, sc->result, ctask->itt);
+ conn->scsirsp_pdus_cnt++;
+ iscsi_ctask_cleanup(conn, ctask);
+ sc->scsi_done(sc);
+ return rc;
+}
+
+/**
+ * iscsi_data_rsp - SCSI Data-In Response processing
+ * @conn: iscsi connection
+ * @ctask: scsi command task
+ **/
+static int
+iscsi_data_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
+{
+ int rc;
+ struct iscsi_data_rsp *rhdr = (struct iscsi_data_rsp *)conn->in.hdr;
+ struct iscsi_session *session = conn->session;
+ int datasn = be32_to_cpu(rhdr->datasn);
+
+ rc = iscsi_check_assign_cmdsn(session, (struct iscsi_nopin*)rhdr);
+ if (rc)
+ return rc;
+ /*
+ * setup Data-In byte counter (gets decremented..)
+ */
+ ctask->data_count = conn->in.datalen;
+
+ if (conn->in.datalen == 0)
+ return 0;
+
+ if (ctask->datasn != datasn)
+ return ISCSI_ERR_DATASN;
+
+ ctask->datasn++;
+
+ ctask->data_offset = be32_to_cpu(rhdr->offset);
+ if (ctask->data_offset + conn->in.datalen > ctask->total_length)
+ return ISCSI_ERR_DATA_OFFSET;
+
+ if (rhdr->flags & ISCSI_FLAG_DATA_STATUS) {
+ struct scsi_cmnd *sc = ctask->sc;
+
+ conn->exp_statsn = be32_to_cpu(rhdr->statsn) + 1;
+ if (rhdr->flags & ISCSI_FLAG_CMD_UNDERFLOW) {
+ int res_count = be32_to_cpu(rhdr->residual_count);
+
+ if (res_count > 0 &&
+ res_count <= sc->request_bufflen) {
+ sc->resid = res_count;
+ sc->result = (DID_OK << 16) | rhdr->cmd_status;
+ } else
+ sc->result = (DID_BAD_TARGET << 16) |
+ rhdr->cmd_status;
+ } else if (rhdr->flags & ISCSI_FLAG_CMD_BIDI_UNDERFLOW)
+ sc->result = (DID_BAD_TARGET << 16) | rhdr->cmd_status;
+ else if (rhdr->flags & ISCSI_FLAG_CMD_OVERFLOW) {
+ sc->resid = be32_to_cpu(rhdr->residual_count);
+ sc->result = (DID_OK << 16) | rhdr->cmd_status;
+ } else
+ sc->result = (DID_OK << 16) | rhdr->cmd_status;
+ }
+
+ conn->datain_pdus_cnt++;
+ return 0;
+}
+
+/**
+ * iscsi_solicit_data_init - initialize first Data-Out
+ * @conn: iscsi connection
+ * @ctask: scsi command task
+ * @r2t: R2T info
+ *
+ * Notes:
+ * Initialize first Data-Out within this R2T sequence and finds
+ * proper data_offset within this SCSI command.
+ *
+ * This function is called with connection lock taken.
+ **/
+static void
+iscsi_solicit_data_init(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask,
+ struct iscsi_r2t_info *r2t)
+{
+ struct iscsi_data *hdr;
+ struct iscsi_data_task *dtask;
+ struct scsi_cmnd *sc = ctask->sc;
+
+ dtask = mempool_alloc(ctask->datapool, GFP_ATOMIC);
+ BUG_ON(!dtask);
+ hdr = &dtask->hdr;
+ memset(hdr, 0, sizeof(struct iscsi_data));
+ hdr->ttt = r2t->ttt;
+ hdr->datasn = cpu_to_be32(r2t->solicit_datasn);
+ r2t->solicit_datasn++;
+ hdr->opcode = ISCSI_OP_SCSI_DATA_OUT;
+ memcpy(hdr->lun, ctask->hdr.lun, sizeof(hdr->lun));
+ hdr->itt = ctask->hdr.itt;
+ hdr->exp_statsn = r2t->exp_statsn;
+ hdr->offset = cpu_to_be32(r2t->data_offset);
+ if (r2t->data_length > conn->max_xmit_dlength) {
+ hton24(hdr->dlength, conn->max_xmit_dlength);
+ r2t->data_count = conn->max_xmit_dlength;
+ hdr->flags = 0;
+ } else {
+ hton24(hdr->dlength, r2t->data_length);
+ r2t->data_count = r2t->data_length;
+ hdr->flags = ISCSI_FLAG_CMD_FINAL;
+ }
+ conn->dataout_pdus_cnt++;
+
+ r2t->sent = 0;
+
+ iscsi_buf_init_virt(&r2t->headbuf, (char*)hdr,
+ sizeof(struct iscsi_hdr));
+
+ r2t->dtask = dtask;
+
+ if (sc->use_sg) {
+ int i, sg_count = 0;
+ struct scatterlist *sg = sc->request_buffer;
+
+ r2t->sg = NULL;
+ for (i = 0; i < sc->use_sg; i++, sg += 1) {
+ /* FIXME: prefetch ? */
+ if (sg_count + sg->length > r2t->data_offset) {
+ int page_offset;
+
+ /* sg page found! */
+
+ /* offset within this page */
+ page_offset = r2t->data_offset - sg_count;
+
+ /* fill in this buffer */
+ iscsi_buf_init_sg(&r2t->sendbuf, sg);
+ r2t->sendbuf.sg.offset += page_offset;
+ r2t->sendbuf.sg.length -= page_offset;
+
+ /* xmit logic will continue with next one */
+ r2t->sg = sg + 1;
+ break;
+ }
+ sg_count += sg->length;
+ }
+ BUG_ON(r2t->sg == NULL);
+ } else
+ iscsi_buf_init_iov(&ctask->sendbuf,
+ (char*)sc->request_buffer + r2t->data_offset,
+ r2t->data_count);
+
+ list_add(&dtask->item, &ctask->dataqueue);
+}
+
+/**
+ * iscsi_r2t_rsp - iSCSI R2T Response processing
+ * @conn: iscsi connection
+ * @ctask: scsi command task
+ **/
+static int
+iscsi_r2t_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
+{
+ struct iscsi_r2t_info *r2t;
+ struct iscsi_session *session = conn->session;
+ struct iscsi_r2t_rsp *rhdr = (struct iscsi_r2t_rsp *)conn->in.hdr;
+ int r2tsn = be32_to_cpu(rhdr->r2tsn);
+ int rc;
+
+ if (conn->in.ahslen)
+ return ISCSI_ERR_AHSLEN;
+
+ if (conn->in.datalen)
+ return ISCSI_ERR_DATALEN;
+
+ if (ctask->exp_r2tsn && ctask->exp_r2tsn != r2tsn)
+ return ISCSI_ERR_R2TSN;
+
+ rc = iscsi_check_assign_cmdsn(session, (struct iscsi_nopin*)rhdr);
+ if (rc)
+ return rc;
+
+ /* FIXME: use R2TSN to detect missing R2T */
+
+ /* fill-in new R2T associated with the task */
+ spin_lock(&session->lock);
+ if (!ctask->sc || ctask->mtask ||
+ session->state != ISCSI_STATE_LOGGED_IN) {
+ printk(KERN_INFO "iscsi_tcp: dropping R2T itt %d in "
+ "recovery...\n", ctask->itt);
+ spin_unlock(&session->lock);
+ return 0;
+ }
+ rc = __kfifo_get(ctask->r2tpool.queue, (void*)&r2t, sizeof(void*));
+ BUG_ON(!rc);
+
+ r2t->exp_statsn = rhdr->statsn;
+ r2t->data_length = be32_to_cpu(rhdr->data_length);
+ if (r2t->data_length == 0 ||
+ r2t->data_length > session->max_burst) {
+ spin_unlock(&session->lock);
+ return ISCSI_ERR_DATALEN;
+ }
+
+ r2t->data_offset = be32_to_cpu(rhdr->data_offset);
+ if (r2t->data_offset + r2t->data_length > ctask->total_length) {
+ spin_unlock(&session->lock);
+ return ISCSI_ERR_DATALEN;
+ }
+
+ r2t->ttt = rhdr->ttt; /* no flip */
+ r2t->solicit_datasn = 0;
+
+ iscsi_solicit_data_init(conn, ctask, r2t);
+
+ ctask->exp_r2tsn = r2tsn + 1;
+ ctask->xmstate |= XMSTATE_SOL_HDR;
+ __kfifo_put(ctask->r2tqueue, (void*)&r2t, sizeof(void*));
+ __kfifo_put(conn->writequeue, (void*)&ctask, sizeof(void*));
+
+ schedule_work(&conn->xmitwork);
+ conn->r2t_pdus_cnt++;
+ spin_unlock(&session->lock);
+
+ return 0;
+}
+
+static int
+iscsi_hdr_recv(struct iscsi_conn *conn)
+{
+ int rc = 0;
+ struct iscsi_hdr *hdr;
+ struct iscsi_cmd_task *ctask;
+ struct iscsi_session *session = conn->session;
+ uint32_t cdgst, rdgst = 0;
+
+ hdr = conn->in.hdr;
+
+ /* verify PDU length */
+ conn->in.datalen = ntoh24(hdr->dlength);
+ if (conn->in.datalen > conn->max_recv_dlength) {
+ printk(KERN_ERR "iscsi_tcp: datalen %d > %d\n",
+ conn->in.datalen, conn->max_recv_dlength);
+ return ISCSI_ERR_DATALEN;
+ }
+ conn->data_copied = 0;
+
+ /* read AHS */
+ conn->in.ahslen = hdr->hlength * 4;
+ conn->in.offset += conn->in.ahslen;
+ conn->in.copy -= conn->in.ahslen;
+ if (conn->in.copy < 0) {
+ printk(KERN_ERR "iscsi_tcp: can't handle AHS with length "
+ "%d bytes\n", conn->in.ahslen);
+ return ISCSI_ERR_AHSLEN;
+ }
+
+ /* calculate read padding */
+ conn->in.padding = conn->in.datalen & (ISCSI_PAD_LEN-1);
+ if (conn->in.padding) {
+ conn->in.padding = ISCSI_PAD_LEN - conn->in.padding;
+ debug_scsi("read padding %d bytes\n", conn->in.padding);
+ }
+
+ if (conn->hdrdgst_en) {
+ struct scatterlist sg;
+
+ sg_init_one(&sg, (u8 *)hdr,
+ sizeof(struct iscsi_hdr) + conn->in.ahslen);
+ crypto_digest_digest(conn->rx_tfm, &sg, 1, (u8 *)&cdgst);
+ rdgst = *(uint32_t*)((char*)hdr + sizeof(struct iscsi_hdr) +
+ conn->in.ahslen);
+ }
+
+ /* save opcode for later */
+ conn->in.opcode = hdr->opcode;
+
+ /* verify itt (itt encoding: age+cid+itt) */
+ if (hdr->itt != cpu_to_be32(ISCSI_RESERVED_TAG)) {
+ if ((hdr->itt & AGE_MASK) !=
+ (session->age << AGE_SHIFT)) {
+ printk(KERN_ERR "iscsi_tcp: received itt %x expected "
+ "session age (%x)\n", hdr->itt,
+ session->age & AGE_MASK);
+ return ISCSI_ERR_BAD_ITT;
+ }
+
+ if ((hdr->itt & CID_MASK) != (conn->id << CID_SHIFT)) {
+ printk(KERN_ERR "iscsi_tcp: received itt %x, expected "
+ "CID (%x)\n", hdr->itt, conn->id);
+ return ISCSI_ERR_BAD_ITT;
+ }
+ conn->in.itt = hdr->itt & ITT_MASK;
+ } else
+ conn->in.itt = hdr->itt;
+
+ debug_tcp("opcode 0x%x offset %d copy %d ahslen %d datalen %d\n",
+ hdr->opcode, conn->in.offset, conn->in.copy,
+ conn->in.ahslen, conn->in.datalen);
+
+ if (conn->in.itt < session->cmds_max) {
+ if (conn->hdrdgst_en && cdgst != rdgst) {
+ printk(KERN_ERR "iscsi_tcp: itt %x: hdrdgst error "
+ "recv 0x%x calc 0x%x\n", conn->in.itt, rdgst,
+ cdgst);
+ return ISCSI_ERR_HDR_DGST;
+ }
+
+ ctask = (struct iscsi_cmd_task *)session->cmds[conn->in.itt];
+
+ if (!ctask->sc) {
+ printk(KERN_INFO "iscsi_tcp: dropping ctask with "
+ "itt 0x%x\n", ctask->itt);
+ conn->in.datalen = 0; /* force drop */
+ return 0;
+ }
+
+ if (ctask->sc->SCp.phase != session->age) {
+ printk(KERN_ERR "iscsi_tcp: ctask's session age %d, "
+ "expected %d\n", ctask->sc->SCp.phase,
+ session->age);
+ return ISCSI_ERR_SESSION_FAILED;
+ }
+
+ conn->in.ctask = ctask;
+
+ debug_scsi("rsp [op 0x%x cid %d sc %lx itt 0x%x len %d]\n",
+ hdr->opcode, conn->id, (long)ctask->sc,
+ ctask->itt, conn->in.datalen);
+
+ switch(conn->in.opcode) {
+ case ISCSI_OP_SCSI_CMD_RSP:
+ BUG_ON((void*)ctask != ctask->sc->SCp.ptr);
+ if (ctask->hdr.flags & ISCSI_FLAG_CMD_WRITE)
+ rc = iscsi_cmd_rsp(conn, ctask);
+ else if (!conn->in.datalen)
+ rc = iscsi_cmd_rsp(conn, ctask);
+ else
+ /*
+ * got sense or response data; copying PDU
+ * Header to the connection's header
+ * placeholder
+ */
+ memcpy(&conn->hdr, hdr,
+ sizeof(struct iscsi_hdr));
+ break;
+ case ISCSI_OP_SCSI_DATA_IN:
+ BUG_ON((void*)ctask != ctask->sc->SCp.ptr);
+ /* save flags for non-exceptional status */
+ conn->in.flags = hdr->flags;
+ /* save cmd_status for sense data */
+ conn->in.cmd_status =
+ ((struct iscsi_data_rsp*)hdr)->cmd_status;
+ rc = iscsi_data_rsp(conn, ctask);
+ break;
+ case ISCSI_OP_R2T:
+ BUG_ON((void*)ctask != ctask->sc->SCp.ptr);
+ if (ctask->hdr.flags & ISCSI_FLAG_CMD_WRITE &&
+ ctask->sc->sc_data_direction == DMA_TO_DEVICE)
+ rc = iscsi_r2t_rsp(conn, ctask);
+ else
+ rc = ISCSI_ERR_PROTO;
+ break;
+ default:
+ rc = ISCSI_ERR_BAD_OPCODE;
+ break;
+ }
+ } else if (conn->in.itt >= ISCSI_MGMT_ITT_OFFSET &&
+ conn->in.itt < ISCSI_MGMT_ITT_OFFSET +
+ session->mgmtpool_max) {
+ struct iscsi_mgmt_task *mtask = (struct iscsi_mgmt_task *)
+ session->mgmt_cmds[conn->in.itt -
+ ISCSI_MGMT_ITT_OFFSET];
+
+ debug_scsi("immrsp [op 0x%x cid %d itt 0x%x len %d]\n",
+ conn->in.opcode, conn->id, mtask->itt,
+ conn->in.datalen);
+
+ switch(conn->in.opcode) {
+ case ISCSI_OP_LOGIN_RSP:
+ case ISCSI_OP_TEXT_RSP:
+ case ISCSI_OP_LOGOUT_RSP:
+ rc = iscsi_check_assign_cmdsn(session,
+ (struct iscsi_nopin*)hdr);
+ if (rc)
+ break;
+
+ if (!conn->in.datalen) {
+ rc = iscsi_recv_pdu(iscsi_handle(conn), hdr,
+ NULL, 0);
+ if (conn->login_mtask != mtask) {
+ spin_lock(&session->lock);
+ __kfifo_put(session->mgmtpool.queue,
+ (void*)&mtask, sizeof(void*));
+ spin_unlock(&session->lock);
+ }
+ }
+ break;
+ case ISCSI_OP_SCSI_TMFUNC_RSP:
+ rc = iscsi_check_assign_cmdsn(session,
+ (struct iscsi_nopin*)hdr);
+ if (rc)
+ break;
+
+ if (conn->in.datalen || conn->in.ahslen) {
+ rc = ISCSI_ERR_PROTO;
+ break;
+ }
+ conn->tmfrsp_pdus_cnt++;
+ spin_lock(&session->lock);
+ if (conn->tmabort_state == TMABORT_INITIAL) {
+ __kfifo_put(session->mgmtpool.queue,
+ (void*)&mtask, sizeof(void*));
+ conn->tmabort_state =
+ ((struct iscsi_tm_rsp *)hdr)->
+ response == ISCSI_TMF_RSP_COMPLETE ?
+ TMABORT_SUCCESS:TMABORT_FAILED;
+ /* unblock eh_abort() */
+ wake_up(&conn->ehwait);
+ }
+ spin_unlock(&session->lock);
+ break;
+ case ISCSI_OP_NOOP_IN:
+ if (hdr->ttt != ISCSI_RESERVED_TAG) {
+ rc = ISCSI_ERR_PROTO;
+ break;
+ }
+ rc = iscsi_check_assign_cmdsn(session,
+ (struct iscsi_nopin*)hdr);
+ if (rc)
+ break;
+ conn->exp_statsn = be32_to_cpu(hdr->statsn) + 1;
+
+ if (!conn->in.datalen) {
+ struct iscsi_mgmt_task *mtask;
+
+ rc = iscsi_recv_pdu(iscsi_handle(conn), hdr,
+ NULL, 0);
+ mtask = (struct iscsi_mgmt_task *)
+ session->mgmt_cmds[conn->in.itt -
+ ISCSI_MGMT_ITT_OFFSET];
+ if (conn->login_mtask != mtask) {
+ spin_lock(&session->lock);
+ __kfifo_put(session->mgmtpool.queue,
+ (void*)&mtask, sizeof(void*));
+ spin_unlock(&session->lock);
+ }
+ }
+ break;
+ default:
+ rc = ISCSI_ERR_BAD_OPCODE;
+ break;
+ }
+ } else if (conn->in.itt == ISCSI_RESERVED_TAG) {
+ switch(conn->in.opcode) {
+ case ISCSI_OP_NOOP_IN:
+ if (!conn->in.datalen) {
+ rc = iscsi_check_assign_cmdsn(session,
+ (struct iscsi_nopin*)hdr);
+ if (!rc && hdr->ttt != ISCSI_RESERVED_TAG)
+ rc = iscsi_recv_pdu(iscsi_handle(conn),
+ hdr, NULL, 0);
+ } else
+ rc = ISCSI_ERR_PROTO;
+ break;
+ case ISCSI_OP_REJECT:
+ /* we need sth like iscsi_reject_rsp()*/
+ case ISCSI_OP_ASYNC_EVENT:
+ /* we need sth like iscsi_async_event_rsp() */
+ rc = ISCSI_ERR_BAD_OPCODE;
+ break;
+ default:
+ rc = ISCSI_ERR_BAD_OPCODE;
+ break;
+ }
+ } else
+ rc = ISCSI_ERR_BAD_ITT;
+
+ return rc;
+}
+
+/**
+ * iscsi_ctask_copy - copy skb bits to the destanation cmd task
+ * @conn: iscsi connection
+ * @ctask: scsi command task
+ * @buf: buffer to copy to
+ * @buf_size: size of buffer
+ * @offset: offset within the buffer
+ *
+ * Notes:
+ * The function calls skb_copy_bits() and updates per-connection and
+ * per-cmd byte counters.
+ *
+ * Read counters (in bytes):
+ *
+ * conn->in.offset offset within in progress SKB
+ * conn->in.copy left to copy from in progress SKB
+ * including padding
+ * conn->in.copied copied already from in progress SKB
+ * conn->data_copied copied already from in progress buffer
+ * ctask->sent total bytes sent up to the MidLayer
+ * ctask->data_count left to copy from in progress Data-In
+ * buf_left left to copy from in progress buffer
+ **/
+static inline int
+iscsi_ctask_copy(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask,
+ void *buf, int buf_size, int offset)
+{
+ int buf_left = buf_size - (conn->data_copied + offset);
+ int size = min(conn->in.copy, buf_left);
+ int rc;
+
+ size = min(size, ctask->data_count);
+
+ debug_tcp("ctask_copy %d bytes at offset %d copied %d\n",
+ size, conn->in.offset, conn->in.copied);
+
+ BUG_ON(size <= 0);
+ BUG_ON(ctask->sent + size > ctask->total_length);
+
+ rc = skb_copy_bits(conn->in.skb, conn->in.offset,
+ (char*)buf + (offset + conn->data_copied), size);
+ /* must fit into skb->len */
+ BUG_ON(rc);
+
+ conn->in.offset += size;
+ conn->in.copy -= size;
+ conn->in.copied += size;
+ conn->data_copied += size;
+ ctask->sent += size;
+ ctask->data_count -= size;
+
+ BUG_ON(conn->in.copy < 0);
+ BUG_ON(ctask->data_count < 0);
+
+ if (buf_size != (conn->data_copied + offset)) {
+ if (!ctask->data_count) {
+ BUG_ON(buf_size - conn->data_copied < 0);
+ /* done with this PDU */
+ return buf_size - conn->data_copied;
+ }
+ return -EAGAIN;
+ }
+
+ /* done with this buffer or with both - PDU and buffer */
+ conn->data_copied = 0;
+ return 0;
+}
+
+/**
+ * iscsi_tcp_copy - copy skb bits to the destanation buffer
+ * @conn: iscsi connection
+ * @buf: buffer to copy to
+ * @buf_size: number of bytes to copy
+ *
+ * Notes:
+ * The function calls skb_copy_bits() and updates per-connection
+ * byte counters.
+ **/
+static inline int
+iscsi_tcp_copy(struct iscsi_conn *conn, void *buf, int buf_size)
+{
+ int buf_left = buf_size - conn->data_copied;
+ int size = min(conn->in.copy, buf_left);
+ int rc;
+
+ debug_tcp("tcp_copy %d bytes at offset %d copied %d\n",
+ size, conn->in.offset, conn->data_copied);
+ BUG_ON(size <= 0);
+
+ rc = skb_copy_bits(conn->in.skb, conn->in.offset,
+ (char*)buf + conn->data_copied, size);
+ BUG_ON(rc);
+
+ conn->in.offset += size;
+ conn->in.copy -= size;
+ conn->in.copied += size;
+ conn->data_copied += size;
+
+ if (buf_size != conn->data_copied)
+ return -EAGAIN;
+
+ return 0;
+}
+
+static inline void
+partial_sg_digest_update(struct iscsi_conn *conn, struct scatterlist *sg,
+ int offset, int length)
+{
+ struct scatterlist temp;
+
+ memcpy(&temp, sg, sizeof(struct scatterlist));
+ temp.offset = offset;
+ temp.length = length;
+ crypto_digest_update(conn->data_rx_tfm, &temp, 1);
+}
+
+static int iscsi_scsi_data_in(struct iscsi_conn *conn)
+{
+ struct iscsi_cmd_task *ctask = conn->in.ctask;
+ struct scsi_cmnd *sc = ctask->sc;
+ struct scatterlist tmp, *sg;
+ int i, offset, rc = 0;
+
+ BUG_ON((void*)ctask != sc->SCp.ptr);
+
+ /*
+ * copying Data-In into the Scsi_Cmnd
+ */
+ if (!sc->use_sg) {
+ i = ctask->data_count;
+ rc = iscsi_ctask_copy(conn, ctask, sc->request_buffer,
+ sc->request_bufflen, ctask->data_offset);
+ if (rc == -EAGAIN)
+ return rc;
+ if (conn->datadgst_en) {
+ sg_init_one(&tmp, sc->request_buffer, i);
+ crypto_digest_update(conn->data_rx_tfm, &tmp, 1);
+ }
+ rc = 0;
+ goto done;
+ }
+
+ offset = ctask->data_offset;
+ sg = sc->request_buffer;
+
+ if (ctask->data_offset)
+ for (i = 0; i < ctask->sg_count; i++)
+ offset -= sg[i].length;
+ /* we've passed through partial sg*/
+ if (offset < 0)
+ offset = 0;
+
+ for (i = ctask->sg_count; i < sc->use_sg; i++) {
+ char *dest;
+
+ dest = kmap_atomic(sg[i].page, KM_SOFTIRQ0);
+ rc = iscsi_ctask_copy(conn, ctask, dest + sg[i].offset,
+ sg[i].length, offset);
+ kunmap_atomic(dest, KM_SOFTIRQ0);
+ if (rc == -EAGAIN)
+ /* continue with the next SKB/PDU */
+ return rc;
+ if (!rc) {
+ if (conn->datadgst_en) {
+ if (!offset)
+ crypto_digest_update(conn->data_rx_tfm,
+ &sg[i], 1);
+ else
+ partial_sg_digest_update(conn, &sg[i],
+ sg[i].offset + offset,
+ sg[i].length - offset);
+ }
+ offset = 0;
+ ctask->sg_count++;
+ }
+
+ if (!ctask->data_count) {
+ if (rc && conn->datadgst_en)
+ /*
+ * data-in is complete, but buffer not...
+ */
+ partial_sg_digest_update(conn, &sg[i],
+ sg[i].offset, sg[i].length-rc);
+ rc = 0;
+ break;
+ }
+
+ if (!conn->in.copy)
+ return -EAGAIN;
+ }
+ BUG_ON(ctask->data_count);
+
+done:
+ /* check for non-exceptional status */
+ if (conn->in.flags & ISCSI_FLAG_DATA_STATUS) {
+ debug_scsi("done [sc %lx res %d itt 0x%x]\n",
+ (long)sc, sc->result, ctask->itt);
+ conn->scsirsp_pdus_cnt++;
+ iscsi_ctask_cleanup(conn, ctask);
+ sc->scsi_done(sc);
+ }
+
+ return rc;
+}
+
+static int
+iscsi_data_recv(struct iscsi_conn *conn)
+{
+ struct iscsi_session *session = conn->session;
+ int rc = 0;
+
+ switch(conn->in.opcode) {
+ case ISCSI_OP_SCSI_DATA_IN:
+ rc = iscsi_scsi_data_in(conn);
+ break;
+ case ISCSI_OP_SCSI_CMD_RSP: {
+ /*
+ * SCSI Sense Data:
+ * copying the entire Data Segment.
+ */
+ if (iscsi_tcp_copy(conn, conn->data, conn->in.datalen)) {
+ rc = -EAGAIN;
+ goto exit;
+ }
+
+ /*
+ * check for sense
+ */
+ conn->in.hdr = &conn->hdr;
+ conn->senselen = (conn->data[0] << 8) | conn->data[1];
+ rc = iscsi_cmd_rsp(conn, conn->in.ctask);
+ }
+ break;
+ case ISCSI_OP_TEXT_RSP:
+ case ISCSI_OP_LOGIN_RSP:
+ case ISCSI_OP_NOOP_IN: {
+ struct iscsi_mgmt_task *mtask = NULL;
+
+ if (conn->in.itt != ISCSI_RESERVED_TAG)
+ mtask = (struct iscsi_mgmt_task *)
+ session->mgmt_cmds[conn->in.itt -
+ ISCSI_MGMT_ITT_OFFSET];
+
+ /*
+ * Collect data segment to the connection's data
+ * placeholder
+ */
+ if (iscsi_tcp_copy(conn, conn->data, conn->in.datalen)) {
+ rc = -EAGAIN;
+ goto exit;
+ }
+
+ rc = iscsi_recv_pdu(iscsi_handle(conn), conn->in.hdr,
+ conn->data, conn->in.datalen);
+
+ if (mtask && conn->login_mtask != mtask) {
+ spin_lock(&session->lock);
+ __kfifo_put(session->mgmtpool.queue, (void*)&mtask,
+ sizeof(void*));
+ spin_unlock(&session->lock);
+ }
+ }
+ break;
+ default:
+ BUG_ON(1);
+ }
+exit:
+ return rc;
+}
+
+/**
+ * iscsi_tcp_data_recv - TCP receive in sendfile fashion
+ * @rd_desc: read descriptor
+ * @skb: socket buffer
+ * @offset: offset in skb
+ * @len: skb->len - offset
+ **/
+static int
+iscsi_tcp_data_recv(read_descriptor_t *rd_desc, struct sk_buff *skb,
+ unsigned int offset, size_t len)
+{
+ int rc;
+ struct iscsi_conn *conn = rd_desc->arg.data;
+ int processed;
+ char pad[ISCSI_PAD_LEN];
+ struct scatterlist sg;
+
+ /*
+ * Save current SKB and its offset in the corresponding
+ * connection context.
+ */
+ conn->in.copy = skb->len - offset;
+ conn->in.offset = offset;
+ conn->in.skb = skb;
+ conn->in.len = conn->in.copy;
+ BUG_ON(conn->in.copy <= 0);
+ debug_tcp("in %d bytes\n", conn->in.copy);
+
+more:
+ conn->in.copied = 0;
+ rc = 0;
+
+ if (unlikely(conn->suspend_rx)) {
+ debug_tcp("conn %d Rx suspended!\n", conn->id);
+ return 0;
+ }
+
+ if (conn->in_progress == IN_PROGRESS_WAIT_HEADER ||
+ conn->in_progress == IN_PROGRESS_HEADER_GATHER) {
+ rc = iscsi_hdr_extract(conn);
+ if (rc) {
+ if (rc == -EAGAIN)
+ goto nomore;
+ else {
+ iscsi_conn_failure(conn, rc);
+ return 0;
+ }
+ }
+
+ /*
+ * Verify and process incoming PDU header.
+ */
+ rc = iscsi_hdr_recv(conn);
+ if (!rc && conn->in.datalen) {
+ if (conn->datadgst_en &&
+ conn->in.opcode == ISCSI_OP_SCSI_DATA_IN) {
+ BUG_ON(!conn->data_rx_tfm);
+ crypto_digest_init(conn->data_rx_tfm);
+ }
+ conn->in_progress = IN_PROGRESS_DATA_RECV;
+ } else if (rc) {
+ iscsi_conn_failure(conn, rc);
+ return 0;
+ }
+ }
+
+ if (conn->in_progress == IN_PROGRESS_DDIGEST_RECV) {
+ debug_tcp("extra data_recv offset %d copy %d\n",
+ conn->in.offset, conn->in.copy);
+ if (conn->in.opcode == ISCSI_OP_SCSI_DATA_IN) {
+ uint32_t recv_digest;
+ skb_copy_bits(conn->in.skb, conn->in.offset,
+ &recv_digest, 4);
+ conn->in.offset += 4;
+ conn->in.copy -= 4;
+ if (recv_digest != conn->in.datadgst) {
+ debug_tcp("iscsi_tcp: data digest error!"
+ "0x%x != 0x%x\n", recv_digest,
+ conn->in.datadgst);
+ iscsi_conn_failure(conn, ISCSI_ERR_DATA_DGST);
+ return 0;
+ } else {
+ debug_tcp("iscsi_tcp: data digest match!"
+ "0x%x == 0x%x\n", recv_digest,
+ conn->in.datadgst);
+ conn->in_progress = IN_PROGRESS_WAIT_HEADER;
+ }
+ }
+ }
+
+ if (conn->in_progress == IN_PROGRESS_DATA_RECV && conn->in.copy) {
+
+ debug_tcp("data_recv offset %d copy %d\n",
+ conn->in.offset, conn->in.copy);
+
+ rc = iscsi_data_recv(conn);
+ if (rc) {
+ if (rc == -EAGAIN) {
+ rd_desc->count = conn->in.datalen -
+ conn->in.ctask->data_count;
+ goto again;
+ }
+ iscsi_conn_failure(conn, rc);
+ return 0;
+ }
+ conn->in.copy -= conn->in.padding;
+ conn->in.offset += conn->in.padding;
+ if (conn->datadgst_en &&
+ conn->in.opcode == ISCSI_OP_SCSI_DATA_IN) {
+ if (conn->in.padding) {
+ debug_tcp("padding -> %d\n", conn->in.padding);
+ memset(pad, 0, conn->in.padding);
+ sg_init_one(&sg, pad, conn->in.padding);
+ crypto_digest_update(conn->data_rx_tfm, &sg, 1);
+ }
+ crypto_digest_final(conn->data_rx_tfm,
+ (u8 *) & conn->in.datadgst);
+ debug_tcp("rx digest 0x%x\n", conn->in.datadgst);
+ conn->in_progress = IN_PROGRESS_DDIGEST_RECV;
+ } else
+ conn->in_progress = IN_PROGRESS_WAIT_HEADER;
+ }
+
+ debug_tcp("f, processed %d from out of %d padding %d\n",
+ conn->in.offset - offset, (int)len, conn->in.padding);
+ BUG_ON(conn->in.offset - offset > len);
+
+ if (conn->in.offset - offset != len) {
+ debug_tcp("continue to process %d bytes\n",
+ (int)len - (conn->in.offset - offset));
+ goto more;
+ }
+
+nomore:
+ processed = conn->in.offset - offset;
+ BUG_ON(processed == 0);
+ return processed;
+
+again:
+ processed = conn->in.offset - offset;
+ debug_tcp("c, processed %d from out of %d rd_desc_cnt %d\n",
+ processed, (int)len, (int)rd_desc->count);
+ BUG_ON(processed == 0);
+ BUG_ON(processed > len);
+
+ conn->rxdata_octets += processed;
+ return processed;
+}
+
+static void
+iscsi_tcp_data_ready(struct sock *sk, int flag)
+{
+ struct iscsi_conn *conn = sk->sk_user_data;
+ read_descriptor_t rd_desc;
+
+ read_lock(&sk->sk_callback_lock);
+
+ /* use rd_desc to pass 'conn' to iscsi_tcp_data_recv */
+ rd_desc.arg.data = conn;
+ rd_desc.count = 0;
+ tcp_read_sock(sk, &rd_desc, iscsi_tcp_data_recv);
+
+ read_unlock(&sk->sk_callback_lock);
+}
+
+static void
+iscsi_tcp_state_change(struct sock *sk)
+{
+ struct iscsi_conn *conn;
+ struct iscsi_session *session;
+ void (*old_state_change)(struct sock *);
+
+ read_lock(&sk->sk_callback_lock);
+
+ conn = (struct iscsi_conn*)sk->sk_user_data;
+ session = conn->session;
+
+ if (sk->sk_state == TCP_CLOSE_WAIT ||
+ sk->sk_state == TCP_CLOSE) {
+ debug_tcp("iscsi_tcp_state_change: TCP_CLOSE|TCP_CLOSE_WAIT\n");
+ iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED);
+ }
+
+ old_state_change = conn->old_state_change;
+
+ read_unlock(&sk->sk_callback_lock);
+
+ old_state_change(sk);
+}
+
+/**
+ * iscsi_write_space - Called when more output buffer space is available
+ * @sk: socket space is available for
+ **/
+static void
+iscsi_write_space(struct sock *sk)
+{
+ struct iscsi_conn *conn = (struct iscsi_conn*)sk->sk_user_data;
+ conn->old_write_space(sk);
+ debug_tcp("iscsi_write_space: cid %d\n", conn->id);
+ clear_bit(SUSPEND_BIT, &conn->suspend_tx);
+ schedule_work(&conn->xmitwork);
+}
+
+static void
+iscsi_conn_set_callbacks(struct iscsi_conn *conn)
+{
+ struct sock *sk = conn->sock->sk;
+
+ /* assign new callbacks */
+ write_lock_bh(&sk->sk_callback_lock);
+ sk->sk_user_data = conn;
+ conn->old_data_ready = sk->sk_data_ready;
+ conn->old_state_change = sk->sk_state_change;
+ conn->old_write_space = sk->sk_write_space;
+ sk->sk_data_ready = iscsi_tcp_data_ready;
+ sk->sk_state_change = iscsi_tcp_state_change;
+ sk->sk_write_space = iscsi_write_space;
+ write_unlock_bh(&sk->sk_callback_lock);
+}
+
+static void
+iscsi_conn_restore_callbacks(struct iscsi_conn *conn)
+{
+ struct sock *sk = conn->sock->sk;
+
+ /* restore socket callbacks, see also: iscsi_conn_set_callbacks() */
+ write_lock_bh(&sk->sk_callback_lock);
+ sk->sk_user_data = NULL;
+ sk->sk_data_ready = conn->old_data_ready;
+ sk->sk_state_change = conn->old_state_change;
+ sk->sk_write_space = conn->old_write_space;
+ sk->sk_no_check = 0;
+ write_unlock_bh(&sk->sk_callback_lock);
+}
+
+/**
+ * iscsi_send - generic send routine
+ * @sk: kernel's socket
+ * @buf: buffer to write from
+ * @size: actual size to write
+ * @flags: socket's flags
+ *
+ * Notes:
+ * depending on buffer will use tcp_sendpage() or tcp_sendmsg().
+ * buf->sg.offset == -1 tells us that buffer is non S/G and forces
+ * to use tcp_sendmsg().
+ */
+static inline int
+iscsi_send(struct socket *sk, struct iscsi_buf *buf, int size, int flags)
+{
+ int res;
+
+ if ((int)buf->sg.offset >= 0) {
+ int offset = buf->sg.offset + buf->sent;
+
+ /* tcp_sendpage */
+ res = sk->ops->sendpage(sk, buf->sg.page, offset, size, flags);
+ } else {
+ struct msghdr msg;
+
+ buf->iov.iov_base = iscsi_buf_iov_base(buf);
+ buf->iov.iov_len = size;
+
+ memset(&msg, 0, sizeof(struct msghdr));
+
+ /* tcp_sendmsg */
+ res = kernel_sendmsg(sk, &msg, &buf->iov, 1, size);
+ }
+
+ return res;
+}
+
+/**
+ * iscsi_sendhdr - send PDU Header via tcp_sendpage()
+ * @conn: iscsi connection
+ * @buf: buffer to write from
+ * @datalen: lenght of data to be sent after the header
+ *
+ * Notes:
+ * (Tx, Fast Path)
+ **/
+static inline int
+iscsi_sendhdr(struct iscsi_conn *conn, struct iscsi_buf *buf, int datalen)
+{
+ struct socket *sk = conn->sock;
+ int flags = 0; /* MSG_DONTWAIT; */
+ int res, size;
+
+ size = buf->sg.length - buf->sent;
+ BUG_ON(buf->sent + size > buf->sg.length);
+ if (buf->sent + size != buf->sg.length || datalen)
+ flags |= MSG_MORE;
+
+ res = iscsi_send(sk, buf, size, flags);
+ debug_tcp("sendhdr %d bytes, sent %d res %d\n", size, buf->sent, res);
+ if (res >= 0) {
+ conn->txdata_octets += res;
+ buf->sent += res;
+ if (size != res)
+ return -EAGAIN;
+ return 0;
+ } else if (res == -EAGAIN) {
+ conn->sendpage_failures_cnt++;
+ set_bit(SUSPEND_BIT, &conn->suspend_tx);
+ } else if (res == -EPIPE)
+ iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED);
+
+ return res;
+}
+
+/**
+ * iscsi_sendpage - send one page of iSCSI Data-Out.
+ * @conn: iscsi connection
+ * @buf: buffer to write from
+ * @count: remaining data
+ * @sent: number of bytes sent
+ *
+ * Notes:
+ * (Tx, Fast Path)
+ **/
+static inline int
+iscsi_sendpage(struct iscsi_conn *conn, struct iscsi_buf *buf,
+ int *count, int *sent)
+{
+ struct socket *sk = conn->sock;
+ int flags = 0; /* MSG_DONTWAIT; */
+ int res, size;
+
+ size = buf->sg.length - buf->sent;
+ BUG_ON(buf->sent + size > buf->sg.length);
+ if (size > *count)
+ size = *count;
+ if (buf->sent + size != buf->sg.length || *count != size)
+ flags |= MSG_MORE;
+
+ res = iscsi_send(sk, buf, size, flags);
+ debug_tcp("sendpage: %d bytes, sent %d left %d sent %d res %d\n",
+ size, buf->sent, *count, *sent, res);
+ if (res >= 0) {
+ conn->txdata_octets += res;
+ buf->sent += res;
+ *count -= res;
+ *sent += res;
+ if (size != res)
+ return -EAGAIN;
+ return 0;
+ } else if (res == -EAGAIN) {
+ conn->sendpage_failures_cnt++;
+ set_bit(SUSPEND_BIT, &conn->suspend_tx);
+ } else if (res == -EPIPE)
+ iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED);
+
+ return res;
+}
+
+static inline void
+iscsi_data_digest_init(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
+{
+ BUG_ON(!conn->data_tx_tfm);
+ crypto_digest_init(conn->data_tx_tfm);
+ ctask->digest_count = 4;
+}
+
+static inline void
+iscsi_buf_data_digest_update(struct iscsi_conn *conn, struct iscsi_buf *buf)
+{
+ struct scatterlist sg;
+
+ if (buf->sg.offset != -1)
+ crypto_digest_update(conn->data_tx_tfm, &buf->sg, 1);
+ else {
+ sg_init_one(&sg, (char *)buf->sg.page, buf->sg.length);
+ crypto_digest_update(conn->data_tx_tfm, &sg, 1);
+ }
+}
+
+static inline int
+iscsi_digest_final_send(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask,
+ struct iscsi_buf *buf, uint32_t *digest, int final)
+{
+ int rc = 0;
+ int sent = 0;
+
+ if (final)
+ crypto_digest_final(conn->data_tx_tfm, (u8*)digest);
+
+ iscsi_buf_init_virt(buf, (char*)digest, 4);
+ rc = iscsi_sendpage(conn, buf, &ctask->digest_count, &sent);
+ if (rc) {
+ ctask->datadigest = *digest;
+ ctask->xmstate |= XMSTATE_DATA_DIGEST;
+ } else
+ ctask->digest_count = 4;
+ return rc;
+}
+
+/**
+ * iscsi_solicit_data_cont - initialize next Data-Out
+ * @conn: iscsi connection
+ * @ctask: scsi command task
+ * @r2t: R2T info
+ * @left: bytes left to transfer
+ *
+ * Notes:
+ * Initialize next Data-Out within this R2T sequence and continue
+ * to process next Scatter-Gather element(if any) of this SCSI command.
+ *
+ * Called under connection lock.
+ **/
+static void
+iscsi_solicit_data_cont(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask,
+ struct iscsi_r2t_info *r2t, int left)
+{
+ struct iscsi_data *hdr;
+ struct iscsi_data_task *dtask;
+ struct scsi_cmnd *sc = ctask->sc;
+ int new_offset;
+
+ dtask = mempool_alloc(ctask->datapool, GFP_ATOMIC);
+ BUG_ON(!dtask);
+ hdr = &dtask->hdr;
+ memset(hdr, 0, sizeof(struct iscsi_data));
+ hdr->ttt = r2t->ttt;
+ hdr->datasn = cpu_to_be32(r2t->solicit_datasn);
+ r2t->solicit_datasn++;
+ hdr->opcode = ISCSI_OP_SCSI_DATA_OUT;
+ memcpy(hdr->lun, ctask->hdr.lun, sizeof(hdr->lun));
+ hdr->itt = ctask->hdr.itt;
+ hdr->exp_statsn = r2t->exp_statsn;
+ new_offset = r2t->data_offset + r2t->sent;
+ hdr->offset = cpu_to_be32(new_offset);
+ if (left > conn->max_xmit_dlength) {
+ hton24(hdr->dlength, conn->max_xmit_dlength);
+ r2t->data_count = conn->max_xmit_dlength;
+ } else {
+ hton24(hdr->dlength, left);
+ r2t->data_count = left;
+ hdr->flags = ISCSI_FLAG_CMD_FINAL;
+ }
+ conn->dataout_pdus_cnt++;
+
+ iscsi_buf_init_virt(&r2t->headbuf, (char*)hdr,
+ sizeof(struct iscsi_hdr));
+
+ r2t->dtask = dtask;
+
+ if (sc->use_sg && !iscsi_buf_left(&r2t->sendbuf)) {
+ BUG_ON(ctask->bad_sg == r2t->sg);
+ iscsi_buf_init_sg(&r2t->sendbuf, r2t->sg);
+ r2t->sg += 1;
+ } else
+ iscsi_buf_init_iov(&ctask->sendbuf,
+ (char*)sc->request_buffer + new_offset,
+ r2t->data_count);
+
+ list_add(&dtask->item, &ctask->dataqueue);
+}
+
+static void
+iscsi_unsolicit_data_init(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
+{
+ struct iscsi_data *hdr;
+ struct iscsi_data_task *dtask;
+
+ dtask = mempool_alloc(ctask->datapool, GFP_ATOMIC);
+ BUG_ON(!dtask);
+ hdr = &dtask->hdr;
+ memset(hdr, 0, sizeof(struct iscsi_data));
+ hdr->ttt = cpu_to_be32(ISCSI_RESERVED_TAG);
+ hdr->datasn = cpu_to_be32(ctask->unsol_datasn);
+ ctask->unsol_datasn++;
+ hdr->opcode = ISCSI_OP_SCSI_DATA_OUT;
+ memcpy(hdr->lun, ctask->hdr.lun, sizeof(hdr->lun));
+ hdr->itt = ctask->hdr.itt;
+ hdr->exp_statsn = cpu_to_be32(conn->exp_statsn);
+ hdr->offset = cpu_to_be32(ctask->total_length -
+ ctask->r2t_data_count -
+ ctask->unsol_count);
+ if (ctask->unsol_count > conn->max_xmit_dlength) {
+ hton24(hdr->dlength, conn->max_xmit_dlength);
+ ctask->data_count = conn->max_xmit_dlength;
+ hdr->flags = 0;
+ } else {
+ hton24(hdr->dlength, ctask->unsol_count);
+ ctask->data_count = ctask->unsol_count;
+ hdr->flags = ISCSI_FLAG_CMD_FINAL;
+ }
+
+ iscsi_buf_init_virt(&ctask->headbuf, (char*)hdr,
+ sizeof(struct iscsi_hdr));
+
+ list_add(&dtask->item, &ctask->dataqueue);
+
+ ctask->dtask = dtask;
+}
+
+/**
+ * iscsi_cmd_init - Initialize iSCSI SCSI_READ or SCSI_WRITE commands
+ * @conn: iscsi connection
+ * @ctask: scsi command task
+ * @sc: scsi command
+ **/
+static void
+iscsi_cmd_init(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask,
+ struct scsi_cmnd *sc)
+{
+ struct iscsi_session *session = conn->session;
+
+ BUG_ON(__kfifo_len(ctask->r2tqueue));
+
+ ctask->sc = sc;
+ ctask->conn = conn;
+ ctask->hdr.opcode = ISCSI_OP_SCSI_CMD;
+ ctask->hdr.flags = ISCSI_ATTR_SIMPLE;
+ int_to_scsilun(sc->device->lun, (struct scsi_lun *)ctask->hdr.lun);
+ ctask->hdr.itt = ctask->itt | (conn->id << CID_SHIFT) |
+ (session->age << AGE_SHIFT);
+ ctask->hdr.data_length = cpu_to_be32(sc->request_bufflen);
+ ctask->hdr.cmdsn = cpu_to_be32(session->cmdsn); session->cmdsn++;
+ ctask->hdr.exp_statsn = cpu_to_be32(conn->exp_statsn);
+ memcpy(ctask->hdr.cdb, sc->cmnd, sc->cmd_len);
+ memset(&ctask->hdr.cdb[sc->cmd_len], 0, MAX_COMMAND_SIZE - sc->cmd_len);
+
+ ctask->mtask = NULL;
+ ctask->sent = 0;
+ ctask->sg_count = 0;
+
+ ctask->total_length = sc->request_bufflen;
+
+ if (sc->sc_data_direction == DMA_TO_DEVICE) {
+ ctask->exp_r2tsn = 0;
+ ctask->hdr.flags |= ISCSI_FLAG_CMD_WRITE;
+ BUG_ON(ctask->total_length == 0);
+ if (sc->use_sg) {
+ struct scatterlist *sg = sc->request_buffer;
+
+ iscsi_buf_init_sg(&ctask->sendbuf,
+ &sg[ctask->sg_count++]);
+ ctask->sg = sg;
+ ctask->bad_sg = sg + sc->use_sg;
+ } else {
+ iscsi_buf_init_iov(&ctask->sendbuf, sc->request_buffer,
+ sc->request_bufflen);
+ }
+
+ /*
+ * Write counters:
+ *
+ * imm_count bytes to be sent right after
+ * SCSI PDU Header
+ *
+ * unsol_count bytes(as Data-Out) to be sent
+ * without R2T ack right after
+ * immediate data
+ *
+ * r2t_data_count bytes to be sent via R2T ack's
+ *
+ * pad_count bytes to be sent as zero-padding
+ */
+ ctask->imm_count = 0;
+ ctask->unsol_count = 0;
+ ctask->unsol_datasn = 0;
+ ctask->xmstate = XMSTATE_W_HDR;
+ /* calculate write padding */
+ ctask->pad_count = ctask->total_length & (ISCSI_PAD_LEN-1);
+ if (ctask->pad_count) {
+ ctask->pad_count = ISCSI_PAD_LEN - ctask->pad_count;
+ debug_scsi("write padding %d bytes\n",
+ ctask->pad_count);
+ ctask->xmstate |= XMSTATE_W_PAD;
+ }
+ if (session->imm_data_en) {
+ if (ctask->total_length >= session->first_burst)
+ ctask->imm_count = min(session->first_burst,
+ conn->max_xmit_dlength);
+ else
+ ctask->imm_count = min(ctask->total_length,
+ conn->max_xmit_dlength);
+ hton24(ctask->hdr.dlength, ctask->imm_count);
+ ctask->xmstate |= XMSTATE_IMM_DATA;
+ } else
+ zero_data(ctask->hdr.dlength);
+
+ if (!session->initial_r2t_en)
+ ctask->unsol_count = min(session->first_burst,
+ ctask->total_length) - ctask->imm_count;
+ if (!ctask->unsol_count)
+ /* No unsolicit Data-Out's */
+ ctask->hdr.flags |= ISCSI_FLAG_CMD_FINAL;
+ else
+ ctask->xmstate |= XMSTATE_UNS_HDR | XMSTATE_UNS_INIT;
+
+ ctask->r2t_data_count = ctask->total_length -
+ ctask->imm_count -
+ ctask->unsol_count;
+
+ debug_scsi("cmd [itt %x total %d imm %d imm_data %d "
+ "r2t_data %d]\n",
+ ctask->itt, ctask->total_length, ctask->imm_count,
+ ctask->unsol_count, ctask->r2t_data_count);
+ } else {
+ ctask->hdr.flags |= ISCSI_FLAG_CMD_FINAL;
+ if (sc->sc_data_direction == DMA_FROM_DEVICE)
+ ctask->hdr.flags |= ISCSI_FLAG_CMD_READ;
+ ctask->datasn = 0;
+ ctask->xmstate = XMSTATE_R_HDR;
+ zero_data(ctask->hdr.dlength);
+ }
+
+ iscsi_buf_init_virt(&ctask->headbuf, (char*)&ctask->hdr,
+ sizeof(struct iscsi_hdr));
+ conn->scsicmd_pdus_cnt++;
+}
+
+/**
+ * iscsi_mtask_xmit - xmit management(immediate) task
+ * @conn: iscsi connection
+ * @mtask: task management task
+ *
+ * Notes:
+ * The function can return -EAGAIN in which case caller must
+ * call it again later, or recover. '0' return code means successful
+ * xmit.
+ *
+ * Management xmit state machine consists of two states:
+ * IN_PROGRESS_IMM_HEAD - PDU Header xmit in progress
+ * IN_PROGRESS_IMM_DATA - PDU Data xmit in progress
+ **/
+static int
+iscsi_mtask_xmit(struct iscsi_conn *conn, struct iscsi_mgmt_task *mtask)
+{
+
+ debug_scsi("mtask deq [cid %d state %x itt 0x%x]\n",
+ conn->id, mtask->xmstate, mtask->itt);
+
+ if (mtask->xmstate & XMSTATE_IMM_HDR) {
+ mtask->xmstate &= ~XMSTATE_IMM_HDR;
+ if (mtask->data_count)
+ mtask->xmstate |= XMSTATE_IMM_DATA;
+ if (conn->c_stage != ISCSI_CONN_INITIAL_STAGE &&
+ conn->stop_stage != STOP_CONN_RECOVER &&
+ conn->hdrdgst_en)
+ iscsi_hdr_digest(conn, &mtask->headbuf,
+ (u8*)mtask->hdrext);
+ if (iscsi_sendhdr(conn, &mtask->headbuf, mtask->data_count)) {
+ mtask->xmstate |= XMSTATE_IMM_HDR;
+ if (mtask->data_count)
+ mtask->xmstate &= ~XMSTATE_IMM_DATA;
+ return -EAGAIN;
+ }
+ }
+
+ if (mtask->xmstate & XMSTATE_IMM_DATA) {
+ BUG_ON(!mtask->data_count);
+ mtask->xmstate &= ~XMSTATE_IMM_DATA;
+ /* FIXME: implement.
+ * Virtual buffer could be spreaded across multiple pages...
+ */
+ do {
+ if (iscsi_sendpage(conn, &mtask->sendbuf,
+ &mtask->data_count, &mtask->sent)) {
+ mtask->xmstate |= XMSTATE_IMM_DATA;
+ return -EAGAIN;
+ }
+ } while (mtask->data_count);
+ }
+
+ BUG_ON(mtask->xmstate != XMSTATE_IDLE);
+ return 0;
+}
+
+static inline int
+handle_xmstate_r_hdr(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
+{
+ ctask->xmstate &= ~XMSTATE_R_HDR;
+ if (conn->hdrdgst_en)
+ iscsi_hdr_digest(conn, &ctask->headbuf, (u8*)ctask->hdrext);
+ if (!iscsi_sendhdr(conn, &ctask->headbuf, 0)) {
+ BUG_ON(ctask->xmstate != XMSTATE_IDLE);
+ return 0; /* wait for Data-In */
+ }
+ ctask->xmstate |= XMSTATE_R_HDR;
+ return -EAGAIN;
+}
+
+static inline int
+handle_xmstate_w_hdr(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
+{
+ ctask->xmstate &= ~XMSTATE_W_HDR;
+ if (conn->hdrdgst_en)
+ iscsi_hdr_digest(conn, &ctask->headbuf, (u8*)ctask->hdrext);
+ if (iscsi_sendhdr(conn, &ctask->headbuf, ctask->imm_count)) {
+ ctask->xmstate |= XMSTATE_W_HDR;
+ return -EAGAIN;
+ }
+ return 0;
+}
+
+static inline int
+handle_xmstate_data_digest(struct iscsi_conn *conn,
+ struct iscsi_cmd_task *ctask)
+{
+ ctask->xmstate &= ~XMSTATE_DATA_DIGEST;
+ debug_tcp("resent data digest 0x%x\n", ctask->datadigest);
+ if (iscsi_digest_final_send(conn, ctask, &ctask->immbuf,
+ &ctask->datadigest, 0)) {
+ ctask->xmstate |= XMSTATE_DATA_DIGEST;
+ debug_tcp("resent data digest 0x%x fail!\n",
+ ctask->datadigest);
+ return -EAGAIN;
+ }
+ return 0;
+}
+
+static inline int
+handle_xmstate_imm_data(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
+{
+ BUG_ON(!ctask->imm_count);
+ ctask->xmstate &= ~XMSTATE_IMM_DATA;
+
+ if (conn->datadgst_en) {
+ iscsi_data_digest_init(conn, ctask);
+ ctask->immdigest = 0;
+ }
+
+ for (;;) {
+ if (iscsi_sendpage(conn, &ctask->sendbuf, &ctask->imm_count,
+ &ctask->sent)) {
+ ctask->xmstate |= XMSTATE_IMM_DATA;
+ if (conn->datadgst_en) {
+ crypto_digest_final(conn->data_tx_tfm,
+ (u8*)&ctask->immdigest);
+ debug_tcp("tx imm sendpage fail 0x%x\n",
+ ctask->datadigest);
+ }
+ return -EAGAIN;
+ }
+ if (conn->datadgst_en)
+ iscsi_buf_data_digest_update(conn, &ctask->sendbuf);
+
+ if (!ctask->imm_count)
+ break;
+ iscsi_buf_init_sg(&ctask->sendbuf,
+ &ctask->sg[ctask->sg_count++]);
+ }
+
+ if (conn->datadgst_en && !(ctask->xmstate & XMSTATE_W_PAD)) {
+ if (iscsi_digest_final_send(conn, ctask, &ctask->immbuf,
+ &ctask->immdigest, 1)) {
+ debug_tcp("sending imm digest 0x%x fail!\n",
+ ctask->immdigest);
+ return -EAGAIN;
+ }
+ debug_tcp("sending imm digest 0x%x\n", ctask->immdigest);
+ }
+
+ return 0;
+}
+
+static inline int
+handle_xmstate_uns_hdr(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
+{
+ struct iscsi_data_task *dtask;
+
+ ctask->xmstate |= XMSTATE_UNS_DATA;
+ if (ctask->xmstate & XMSTATE_UNS_INIT) {
+ iscsi_unsolicit_data_init(conn, ctask);
+ BUG_ON(!ctask->dtask);
+ dtask = ctask->dtask;
+ if (conn->hdrdgst_en)
+ iscsi_hdr_digest(conn, &ctask->headbuf,
+ (u8*)dtask->hdrext);
+ ctask->xmstate &= ~XMSTATE_UNS_INIT;
+ }
+ if (iscsi_sendhdr(conn, &ctask->headbuf, ctask->data_count)) {
+ ctask->xmstate &= ~XMSTATE_UNS_DATA;
+ ctask->xmstate |= XMSTATE_UNS_HDR;
+ return -EAGAIN;
+ }
+
+ debug_scsi("uns dout [itt 0x%x dlen %d sent %d]\n",
+ ctask->itt, ctask->unsol_count, ctask->sent);
+ return 0;
+}
+
+static inline int
+handle_xmstate_uns_data(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
+{
+ struct iscsi_data_task *dtask = ctask->dtask;
+
+ BUG_ON(!ctask->data_count);
+ ctask->xmstate &= ~XMSTATE_UNS_DATA;
+
+ if (conn->datadgst_en) {
+ iscsi_data_digest_init(conn, ctask);
+ dtask->digest = 0;
+ }
+
+ for (;;) {
+ int start = ctask->sent;
+
+ if (iscsi_sendpage(conn, &ctask->sendbuf, &ctask->data_count,
+ &ctask->sent)) {
+ ctask->unsol_count -= ctask->sent - start;
+ ctask->xmstate |= XMSTATE_UNS_DATA;
+ /* will continue with this ctask later.. */
+ if (conn->datadgst_en) {
+ crypto_digest_final(conn->data_tx_tfm,
+ (u8 *)&dtask->digest);
+ debug_tcp("tx uns data fail 0x%x\n",
+ dtask->digest);
+ }
+ return -EAGAIN;
+ }
+
+ BUG_ON(ctask->sent > ctask->total_length);
+ ctask->unsol_count -= ctask->sent - start;
+
+ /*
+ * XXX:we may run here with un-initial sendbuf.
+ * so pass it
+ */
+ if (conn->datadgst_en && ctask->sent - start > 0)
+ iscsi_buf_data_digest_update(conn, &ctask->sendbuf);
+
+ if (!ctask->data_count)
+ break;
+ iscsi_buf_init_sg(&ctask->sendbuf,
+ &ctask->sg[ctask->sg_count++]);
+ }
+ BUG_ON(ctask->unsol_count < 0);
+
+ /*
+ * Done with the Data-Out. Next, check if we need
+ * to send another unsolicited Data-Out.
+ */
+ if (ctask->unsol_count) {
+ if (conn->datadgst_en) {
+ if (iscsi_digest_final_send(conn, ctask,
+ &dtask->digestbuf,
+ &dtask->digest, 1)) {
+ debug_tcp("send uns digest 0x%x fail\n",
+ dtask->digest);
+ return -EAGAIN;
+ }
+ debug_tcp("sending uns digest 0x%x, more uns\n",
+ dtask->digest);
+ }
+ ctask->xmstate |= XMSTATE_UNS_INIT;
+ return 1;
+ }
+
+ if (conn->datadgst_en && !(ctask->xmstate & XMSTATE_W_PAD)) {
+ if (iscsi_digest_final_send(conn, ctask,
+ &dtask->digestbuf,
+ &dtask->digest, 1)) {
+ debug_tcp("send last uns digest 0x%x fail\n",
+ dtask->digest);
+ return -EAGAIN;
+ }
+ debug_tcp("sending uns digest 0x%x\n",dtask->digest);
+ }
+
+ return 0;
+}
+
+static inline int
+handle_xmstate_sol_data(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
+{
+ struct iscsi_session *session = conn->session;
+ struct iscsi_r2t_info *r2t = ctask->r2t;
+ struct iscsi_data_task *dtask = r2t->dtask;
+ int left;
+
+ ctask->xmstate &= ~XMSTATE_SOL_DATA;
+ ctask->dtask = dtask;
+
+ if (conn->datadgst_en) {
+ iscsi_data_digest_init(conn, ctask);
+ dtask->digest = 0;
+ }
+solicit_again:
+ /*
+ * send Data-Out whitnin this R2T sequence.
+ */
+ if (!r2t->data_count)
+ goto data_out_done;
+
+ if (iscsi_sendpage(conn, &r2t->sendbuf, &r2t->data_count, &r2t->sent)) {
+ ctask->xmstate |= XMSTATE_SOL_DATA;
+ /* will continue with this ctask later.. */
+ if (conn->datadgst_en) {
+ crypto_digest_final(conn->data_tx_tfm,
+ (u8 *)&dtask->digest);
+ debug_tcp("r2t data send fail 0x%x\n", dtask->digest);
+ }
+ return -EAGAIN;
+ }
+
+ BUG_ON(r2t->data_count < 0);
+ if (conn->datadgst_en)
+ iscsi_buf_data_digest_update(conn, &r2t->sendbuf);
+
+ if (r2t->data_count) {
+ BUG_ON(ctask->sc->use_sg == 0);
+ if (!iscsi_buf_left(&r2t->sendbuf)) {
+ BUG_ON(ctask->bad_sg == r2t->sg);
+ iscsi_buf_init_sg(&r2t->sendbuf, r2t->sg);
+ r2t->sg += 1;
+ }
+ goto solicit_again;
+ }
+
+data_out_done:
+ /*
+ * Done with this Data-Out. Next, check if we have
+ * to send another Data-Out for this R2T.
+ */
+ BUG_ON(r2t->data_length - r2t->sent < 0);
+ left = r2t->data_length - r2t->sent;
+ if (left) {
+ if (conn->datadgst_en) {
+ if (iscsi_digest_final_send(conn, ctask,
+ &dtask->digestbuf,
+ &dtask->digest, 1)) {
+ debug_tcp("send r2t data digest 0x%x"
+ "fail\n", dtask->digest);
+ return -EAGAIN;
+ }
+ debug_tcp("r2t data send digest 0x%x\n",
+ dtask->digest);
+ }
+ iscsi_solicit_data_cont(conn, ctask, r2t, left);
+ ctask->xmstate |= XMSTATE_SOL_DATA;
+ ctask->xmstate &= ~XMSTATE_SOL_HDR;
+ return 1;
+ }
+
+ /*
+ * Done with this R2T. Check if there are more
+ * outstanding R2Ts ready to be processed.
+ */
+ BUG_ON(ctask->r2t_data_count - r2t->data_length < 0);
+ if (conn->datadgst_en) {
+ if (iscsi_digest_final_send(conn, ctask, &dtask->digestbuf,
+ &dtask->digest, 1)) {
+ debug_tcp("send last r2t data digest 0x%x"
+ "fail\n", dtask->digest);
+ return -EAGAIN;
+ }
+ debug_tcp("r2t done dout digest 0x%x\n", dtask->digest);
+ }
+
+ ctask->r2t_data_count -= r2t->data_length;
+ ctask->r2t = NULL;
+ spin_lock_bh(&session->lock);
+ __kfifo_put(ctask->r2tpool.queue, (void*)&r2t, sizeof(void*));
+ spin_unlock_bh(&session->lock);
+ if (__kfifo_get(ctask->r2tqueue, (void*)&r2t, sizeof(void*))) {
+ ctask->r2t = r2t;
+ ctask->xmstate |= XMSTATE_SOL_DATA;
+ ctask->xmstate &= ~XMSTATE_SOL_HDR;
+ return 1;
+ }
+
+ return 0;
+}
+
+static inline int
+handle_xmstate_w_pad(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
+{
+ struct iscsi_data_task *dtask = ctask->dtask;
+ int sent;
+
+ ctask->xmstate &= ~XMSTATE_W_PAD;
+ iscsi_buf_init_virt(&ctask->sendbuf, (char*)&ctask->pad,
+ ctask->pad_count);
+ if (iscsi_sendpage(conn, &ctask->sendbuf, &ctask->pad_count, &sent)) {
+ ctask->xmstate |= XMSTATE_W_PAD;
+ return -EAGAIN;
+ }
+
+ if (conn->datadgst_en) {
+ iscsi_buf_data_digest_update(conn, &ctask->sendbuf);
+ /* imm data? */
+ if (!dtask) {
+ if (iscsi_digest_final_send(conn, ctask, &ctask->immbuf,
+ &ctask->immdigest, 1)) {
+ debug_tcp("send padding digest 0x%x"
+ "fail!\n", ctask->immdigest);
+ return -EAGAIN;
+ }
+ debug_tcp("done with padding, digest 0x%x\n",
+ ctask->datadigest);
+ } else {
+ if (iscsi_digest_final_send(conn, ctask,
+ &dtask->digestbuf,
+ &dtask->digest, 1)) {
+ debug_tcp("send padding digest 0x%x"
+ "fail\n", dtask->digest);
+ return -EAGAIN;
+ }
+ debug_tcp("done with padding, digest 0x%x\n",
+ dtask->digest);
+ }
+ }
+
+ return 0;
+}
+
+static int
+iscsi_ctask_xmit(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
+{
+ int rc = 0;
+
+ debug_scsi("ctask deq [cid %d xmstate %x itt 0x%x]\n",
+ conn->id, ctask->xmstate, ctask->itt);
+
+ /*
+ * serialize with TMF AbortTask
+ */
+ if (ctask->mtask)
+ return rc;
+
+ if (ctask->xmstate & XMSTATE_R_HDR) {
+ rc = handle_xmstate_r_hdr(conn, ctask);
+ return rc;
+ }
+
+ if (ctask->xmstate & XMSTATE_W_HDR) {
+ rc = handle_xmstate_w_hdr(conn, ctask);
+ if (rc)
+ return rc;
+ }
+
+ /* XXX: for data digest xmit recover */
+ if (ctask->xmstate & XMSTATE_DATA_DIGEST) {
+ rc = handle_xmstate_data_digest(conn, ctask);
+ if (rc)
+ return rc;
+ }
+
+ if (ctask->xmstate & XMSTATE_IMM_DATA) {
+ rc = handle_xmstate_imm_data(conn, ctask);
+ if (rc)
+ return rc;
+ }
+
+ if (ctask->xmstate & XMSTATE_UNS_HDR) {
+ BUG_ON(!ctask->unsol_count);
+ ctask->xmstate &= ~XMSTATE_UNS_HDR;
+unsolicit_head_again:
+ rc = handle_xmstate_uns_hdr(conn, ctask);
+ if (rc)
+ return rc;
+ }
+
+ if (ctask->xmstate & XMSTATE_UNS_DATA) {
+ rc = handle_xmstate_uns_data(conn, ctask);
+ if (rc == 1)
+ goto unsolicit_head_again;
+ else if (rc)
+ return rc;
+ goto done;
+ }
+
+ if (ctask->xmstate & XMSTATE_SOL_HDR) {
+ struct iscsi_r2t_info *r2t;
+
+ ctask->xmstate &= ~XMSTATE_SOL_HDR;
+ ctask->xmstate |= XMSTATE_SOL_DATA;
+ if (!ctask->r2t)
+ __kfifo_get(ctask->r2tqueue, (void*)&ctask->r2t,
+ sizeof(void*));
+solicit_head_again:
+ r2t = ctask->r2t;
+ if (conn->hdrdgst_en)
+ iscsi_hdr_digest(conn, &r2t->headbuf,
+ (u8*)r2t->dtask->hdrext);
+ if (iscsi_sendhdr(conn, &r2t->headbuf, r2t->data_count)) {
+ ctask->xmstate &= ~XMSTATE_SOL_DATA;
+ ctask->xmstate |= XMSTATE_SOL_HDR;
+ return -EAGAIN;
+ }
+
+ debug_scsi("sol dout [dsn %d itt 0x%x dlen %d sent %d]\n",
+ r2t->solicit_datasn - 1, ctask->itt, r2t->data_count,
+ r2t->sent);
+ }
+
+ if (ctask->xmstate & XMSTATE_SOL_DATA) {
+ rc = handle_xmstate_sol_data(conn, ctask);
+ if (rc == 1)
+ goto solicit_head_again;
+ if (rc)
+ return rc;
+ }
+
+done:
+ /*
+ * Last thing to check is whether we need to send write
+ * padding. Note that we check for xmstate equality, not just the bit.
+ */
+ if (ctask->xmstate == XMSTATE_W_PAD)
+ rc = handle_xmstate_w_pad(conn, ctask);
+
+ return rc;
+}
+
+/**
+ * iscsi_data_xmit - xmit any command into the scheduled connection
+ * @conn: iscsi connection
+ *
+ * Notes:
+ * The function can return -EAGAIN in which case the caller must
+ * re-schedule it again later or recover. '0' return code means
+ * successful xmit.
+ **/
+static int
+iscsi_data_xmit(struct iscsi_conn *conn)
+{
+ if (unlikely(conn->suspend_tx)) {
+ debug_tcp("conn %d Tx suspended!\n", conn->id);
+ return 0;
+ }
+
+ /*
+ * Transmit in the following order:
+ *
+ * 1) un-finished xmit (ctask or mtask)
+ * 2) immediate control PDUs
+ * 3) write data
+ * 4) SCSI commands
+ * 5) non-immediate control PDUs
+ *
+ * No need to lock around __kfifo_get as long as
+ * there's one producer and one consumer.
+ */
+
+ BUG_ON(conn->ctask && conn->mtask);
+
+ if (conn->ctask) {
+ if (iscsi_ctask_xmit(conn, conn->ctask))
+ goto again;
+ /* done with this in-progress ctask */
+ conn->ctask = NULL;
+ }
+ if (conn->mtask) {
+ if (iscsi_mtask_xmit(conn, conn->mtask))
+ goto again;
+ /* done with this in-progress mtask */
+ conn->mtask = NULL;
+ }
+
+ /* process immediate first */
+ if (unlikely(__kfifo_len(conn->immqueue))) {
+ struct iscsi_session *session = conn->session;
+ while (__kfifo_get(conn->immqueue, (void*)&conn->mtask,
+ sizeof(void*))) {
+ if (iscsi_mtask_xmit(conn, conn->mtask))
+ goto again;
+
+ if (conn->mtask->hdr.itt ==
+ cpu_to_be32(ISCSI_RESERVED_TAG)) {
+ spin_lock_bh(&session->lock);
+ __kfifo_put(session->mgmtpool.queue,
+ (void*)&conn->mtask, sizeof(void*));
+ spin_unlock_bh(&session->lock);
+ }
+ }
+ /* done with this mtask */
+ conn->mtask = NULL;
+ }
+
+ /* process write queue */
+ while (__kfifo_get(conn->writequeue, (void*)&conn->ctask,
+ sizeof(void*))) {
+ if (iscsi_ctask_xmit(conn, conn->ctask))
+ goto again;
+ }
+
+ /* process command queue */
+ while (__kfifo_get(conn->xmitqueue, (void*)&conn->ctask,
+ sizeof(void*))) {
+ if (iscsi_ctask_xmit(conn, conn->ctask))
+ goto again;
+ }
+ /* done with this ctask */
+ conn->ctask = NULL;
+
+ /* process the rest control plane PDUs, if any */
+ if (unlikely(__kfifo_len(conn->mgmtqueue))) {
+ struct iscsi_session *session = conn->session;
+
+ while (__kfifo_get(conn->mgmtqueue, (void*)&conn->mtask,
+ sizeof(void*))) {
+ if (iscsi_mtask_xmit(conn, conn->mtask))
+ goto again;
+
+ if (conn->mtask->hdr.itt ==
+ cpu_to_be32(ISCSI_RESERVED_TAG)) {
+ spin_lock_bh(&session->lock);
+ __kfifo_put(session->mgmtpool.queue,
+ (void*)&conn->mtask,
+ sizeof(void*));
+ spin_unlock_bh(&session->lock);
+ }
+ }
+ /* done with this mtask */
+ conn->mtask = NULL;
+ }
+
+ return 0;
+
+again:
+ if (unlikely(conn->suspend_tx))
+ return 0;
+
+ return -EAGAIN;
+}
+
+static void
+iscsi_xmitworker(void *data)
+{
+ struct iscsi_conn *conn = data;
+
+ /*
+ * serialize Xmit worker on a per-connection basis.
+ */
+ down(&conn->xmitsema);
+ if (iscsi_data_xmit(conn))
+ schedule_work(&conn->xmitwork);
+ up(&conn->xmitsema);
+}
+
+#define FAILURE_BAD_HOST 1
+#define FAILURE_SESSION_FAILED 2
+#define FAILURE_SESSION_FREED 3
+#define FAILURE_WINDOW_CLOSED 4
+#define FAILURE_SESSION_TERMINATE 5
+
+static int
+iscsi_queuecommand(struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *))
+{
+ struct Scsi_Host *host;
+ int reason = 0;
+ struct iscsi_session *session;
+ struct iscsi_conn *conn = NULL;
+ struct iscsi_cmd_task *ctask = NULL;
+
+ sc->scsi_done = done;
+ sc->result = 0;
+
+ host = sc->device->host;
+ session = iscsi_hostdata(host->hostdata);
+ BUG_ON(host != session->host);
+
+ spin_lock(&session->lock);
+
+ if (session->state != ISCSI_STATE_LOGGED_IN) {
+ if (session->state == ISCSI_STATE_FAILED) {
+ reason = FAILURE_SESSION_FAILED;
+ goto reject;
+ } else if (session->state == ISCSI_STATE_TERMINATE) {
+ reason = FAILURE_SESSION_TERMINATE;
+ goto fault;
+ }
+ reason = FAILURE_SESSION_FREED;
+ goto fault;
+ }
+
+ /*
+ * Check for iSCSI window and take care of CmdSN wrap-around
+ */
+ if ((int)(session->max_cmdsn - session->cmdsn) < 0) {
+ reason = FAILURE_WINDOW_CLOSED;
+ goto reject;
+ }
+
+ conn = session->leadconn;
+
+ __kfifo_get(session->cmdpool.queue, (void*)&ctask, sizeof(void*));
+ BUG_ON(ctask->sc);
+
+ sc->SCp.phase = session->age;
+ sc->SCp.ptr = (char*)ctask;
+ iscsi_cmd_init(conn, ctask, sc);
+
+ __kfifo_put(conn->xmitqueue, (void*)&ctask, sizeof(void*));
+ debug_scsi(
+ "ctask enq [%s cid %d sc %lx itt 0x%x len %d cmdsn %d win %d]\n",
+ sc->sc_data_direction == DMA_TO_DEVICE ? "write" : "read",
+ conn->id, (long)sc, ctask->itt, sc->request_bufflen,
+ session->cmdsn, session->max_cmdsn - session->exp_cmdsn + 1);
+ spin_unlock(&session->lock);
+
+ if (!in_interrupt() && !down_trylock(&conn->xmitsema)) {
+ spin_unlock_irq(host->host_lock);
+ if (iscsi_data_xmit(conn))
+ schedule_work(&conn->xmitwork);
+ up(&conn->xmitsema);
+ spin_lock_irq(host->host_lock);
+ } else
+ schedule_work(&conn->xmitwork);
+
+ return 0;
+
+reject:
+ spin_unlock(&session->lock);
+ debug_scsi("cmd 0x%x rejected (%d)\n", sc->cmnd[0], reason);
+ return SCSI_MLQUEUE_HOST_BUSY;
+
+fault:
+ spin_unlock(&session->lock);
+ printk(KERN_ERR "iscsi_tcp: cmd 0x%x is not queued (%d)\n",
+ sc->cmnd[0], reason);
+ sc->sense_buffer[0] = 0x70;
+ sc->sense_buffer[2] = NOT_READY;
+ sc->sense_buffer[7] = 0x6;
+ sc->sense_buffer[12] = 0x08;
+ sc->sense_buffer[13] = 0x00;
+ sc->result = (DID_NO_CONNECT << 16);
+ sc->resid = sc->request_bufflen;
+ sc->scsi_done(sc);
+ return 0;
+}
+
+static int
+iscsi_pool_init(struct iscsi_queue *q, int max, void ***items, int item_size)
+{
+ int i;
+
+ *items = kmalloc(max * sizeof(void*), GFP_KERNEL);
+ if (*items == NULL)
+ return -ENOMEM;
+
+ q->max = max;
+ q->pool = kmalloc(max * sizeof(void*), GFP_KERNEL);
+ if (q->pool == NULL) {
+ kfree(*items);
+ return -ENOMEM;
+ }
+
+ q->queue = kfifo_init((void*)q->pool, max * sizeof(void*),
+ GFP_KERNEL, NULL);
+ if (q->queue == ERR_PTR(-ENOMEM)) {
+ kfree(q->pool);
+ kfree(*items);
+ return -ENOMEM;
+ }
+
+ for (i = 0; i < max; i++) {
+ q->pool[i] = kmalloc(item_size, GFP_KERNEL);
+ if (q->pool[i] == NULL) {
+ int j;
+
+ for (j = 0; j < i; j++)
+ kfree(q->pool[j]);
+
+ kfifo_free(q->queue);
+ kfree(q->pool);
+ kfree(*items);
+ return -ENOMEM;
+ }
+ memset(q->pool[i], 0, item_size);
+ (*items)[i] = q->pool[i];
+ __kfifo_put(q->queue, (void*)&q->pool[i], sizeof(void*));
+ }
+ return 0;
+}
+
+static void
+iscsi_pool_free(struct iscsi_queue *q, void **items)
+{
+ int i;
+
+ for (i = 0; i < q->max; i++)
+ kfree(items[i]);
+ kfree(q->pool);
+ kfree(items);
+}
+
+static iscsi_connh_t
+iscsi_conn_create(iscsi_sessionh_t sessionh, uint32_t conn_idx)
+{
+ struct iscsi_session *session = iscsi_ptr(sessionh);
+ struct iscsi_conn *conn = NULL;
+
+ conn = kmalloc(sizeof(struct iscsi_conn), GFP_KERNEL);
+ if (conn == NULL)
+ goto conn_alloc_fail;
+ memset(conn, 0, sizeof(struct iscsi_conn));
+
+ conn->c_stage = ISCSI_CONN_INITIAL_STAGE;
+ conn->in_progress = IN_PROGRESS_WAIT_HEADER;
+ conn->id = conn_idx;
+ conn->exp_statsn = 0;
+ conn->tmabort_state = TMABORT_INITIAL;
+
+ /* initial operational parameters */
+ conn->hdr_size = sizeof(struct iscsi_hdr);
+ conn->data_size = DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH;
+ conn->max_recv_dlength = DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH;
+
+ spin_lock_init(&conn->lock);
+
+ /* initialize general xmit PDU commands queue */
+ conn->xmitqueue = kfifo_alloc(session->cmds_max * sizeof(void*),
+ GFP_KERNEL, NULL);
+ if (conn->xmitqueue == ERR_PTR(-ENOMEM))
+ goto xmitqueue_alloc_fail;
+
+ /* initialize write response PDU commands queue */
+ conn->writequeue = kfifo_alloc(session->cmds_max * sizeof(void*),
+ GFP_KERNEL, NULL);
+ if (conn->writequeue == ERR_PTR(-ENOMEM))
+ goto writequeue_alloc_fail;
+
+ /* initialize general immediate & non-immediate PDU commands queue */
+ conn->immqueue = kfifo_alloc(session->mgmtpool_max * sizeof(void*),
+ GFP_KERNEL, NULL);
+ if (conn->immqueue == ERR_PTR(-ENOMEM))
+ goto immqueue_alloc_fail;
+
+ conn->mgmtqueue = kfifo_alloc(session->mgmtpool_max * sizeof(void*),
+ GFP_KERNEL, NULL);
+ if (conn->mgmtqueue == ERR_PTR(-ENOMEM))
+ goto mgmtqueue_alloc_fail;
+
+ INIT_WORK(&conn->xmitwork, iscsi_xmitworker, conn);
+
+ /* allocate login_mtask used for the login/text sequences */
+ spin_lock_bh(&session->lock);
+ if (!__kfifo_get(session->mgmtpool.queue,
+ (void*)&conn->login_mtask,
+ sizeof(void*))) {
+ spin_unlock_bh(&session->lock);
+ goto login_mtask_alloc_fail;
+ }
+ spin_unlock_bh(&session->lock);
+
+ /* allocate initial PDU receive place holder */
+ if (conn->data_size <= PAGE_SIZE)
+ conn->data = kmalloc(conn->data_size, GFP_KERNEL);
+ else
+ conn->data = (void*)__get_free_pages(GFP_KERNEL,
+ get_order(conn->data_size));
+ if (!conn->data)
+ goto max_recv_dlenght_alloc_fail;
+
+ init_timer(&conn->tmabort_timer);
+ init_MUTEX(&conn->xmitsema);
+ init_waitqueue_head(&conn->ehwait);
+
+ return iscsi_handle(conn);
+
+max_recv_dlenght_alloc_fail:
+ spin_lock_bh(&session->lock);
+ __kfifo_put(session->mgmtpool.queue, (void*)&conn->login_mtask,
+ sizeof(void*));
+ spin_unlock_bh(&session->lock);
+login_mtask_alloc_fail:
+ kfifo_free(conn->mgmtqueue);
+mgmtqueue_alloc_fail:
+ kfifo_free(conn->immqueue);
+immqueue_alloc_fail:
+ kfifo_free(conn->writequeue);
+writequeue_alloc_fail:
+ kfifo_free(conn->xmitqueue);
+xmitqueue_alloc_fail:
+ kfree(conn);
+conn_alloc_fail:
+ return iscsi_handle(NULL);
+}
+
+static void
+iscsi_conn_destroy(iscsi_connh_t connh)
+{
+ struct iscsi_conn *conn = iscsi_ptr(connh);
+ struct iscsi_session *session = conn->session;
+
+ down(&conn->xmitsema);
+ set_bit(SUSPEND_BIT, &conn->suspend_tx);
+ if (conn->c_stage == ISCSI_CONN_INITIAL_STAGE && conn->sock) {
+ struct sock *sk = conn->sock->sk;
+
+ /*
+ * conn_start() has never been called!
+ * need to cleanup the socket.
+ */
+ write_lock_bh(&sk->sk_callback_lock);
+ set_bit(SUSPEND_BIT, &conn->suspend_rx);
+ write_unlock_bh(&sk->sk_callback_lock);
+
+ sock_hold(conn->sock->sk);
+ iscsi_conn_restore_callbacks(conn);
+ sock_put(conn->sock->sk);
+ sock_release(conn->sock);
+ conn->sock = NULL;
+ }
+
+ spin_lock_bh(&session->lock);
+ conn->c_stage = ISCSI_CONN_CLEANUP_WAIT;
+ if (session->leadconn == conn) {
+ /*
+ * leading connection? then give up on recovery.
+ */
+ session->state = ISCSI_STATE_TERMINATE;
+ wake_up(&conn->ehwait);
+ }
+ spin_unlock_bh(&session->lock);
+
+ up(&conn->xmitsema);
+
+ /*
+ * Block until all in-progress commands for this connection
+ * time out or fail.
+ */
+ for (;;) {
+ spin_lock_bh(&conn->lock);
+ if (!session->host->host_busy) { /* OK for ERL == 0 */
+ spin_unlock_bh(&conn->lock);
+ break;
+ }
+ spin_unlock_bh(&conn->lock);
+ msleep_interruptible(500);
+ printk("conn_destroy(): host_busy %d host_failed %d\n",
+ session->host->host_busy, session->host->host_failed);
+ /*
+ * force eh_abort() to unblock
+ */
+ wake_up(&conn->ehwait);
+ }
+
+ /* now free crypto */
+ if (conn->hdrdgst_en || conn->datadgst_en) {
+ if (conn->tx_tfm)
+ crypto_free_tfm(conn->tx_tfm);
+ if (conn->rx_tfm)
+ crypto_free_tfm(conn->rx_tfm);
+ if (conn->data_tx_tfm)
+ crypto_free_tfm(conn->data_tx_tfm);
+ if (conn->data_rx_tfm)
+ crypto_free_tfm(conn->data_rx_tfm);
+ }
+
+ /* free conn->data, size = MaxRecvDataSegmentLength */
+ if (conn->data_size <= PAGE_SIZE)
+ kfree(conn->data);
+ else
+ free_pages((unsigned long)conn->data,
+ get_order(conn->data_size));
+
+ spin_lock_bh(&session->lock);
+ __kfifo_put(session->mgmtpool.queue, (void*)&conn->login_mtask,
+ sizeof(void*));
+ list_del(&conn->item);
+ if (list_empty(&session->connections))
+ session->leadconn = NULL;
+ if (session->leadconn && session->leadconn == conn)
+ session->leadconn = container_of(session->connections.next,
+ struct iscsi_conn, item);
+
+ if (session->leadconn == NULL)
+ /* none connections exits.. reset sequencing */
+ session->cmdsn = session->max_cmdsn = session->exp_cmdsn = 1;
+ spin_unlock_bh(&session->lock);
+
+ kfifo_free(conn->xmitqueue);
+ kfifo_free(conn->writequeue);
+ kfifo_free(conn->immqueue);
+ kfifo_free(conn->mgmtqueue);
+ kfree(conn);
+}
+
+static int
+iscsi_conn_bind(iscsi_sessionh_t sessionh, iscsi_connh_t connh,
+ uint32_t transport_fd, int is_leading)
+{
+ struct iscsi_session *session = iscsi_ptr(sessionh);
+ struct iscsi_conn *tmp = ERR_PTR(-EEXIST), *conn = iscsi_ptr(connh);
+ struct sock *sk;
+ struct socket *sock;
+ int err;
+
+ /* lookup for existing socket */
+ sock = sockfd_lookup(transport_fd, &err);
+ if (!sock) {
+ printk(KERN_ERR "iscsi_tcp: sockfd_lookup failed %d\n", err);
+ return -EEXIST;
+ }
+
+ /* lookup for existing connection */
+ spin_lock_bh(&session->lock);
+ list_for_each_entry(tmp, &session->connections, item) {
+ if (tmp == conn) {
+ if (conn->c_stage != ISCSI_CONN_STOPPED ||
+ conn->stop_stage == STOP_CONN_TERM) {
+ printk(KERN_ERR "iscsi_tcp: can't bind "
+ "non-stopped connection (%d:%d)\n",
+ conn->c_stage, conn->stop_stage);
+ spin_unlock_bh(&session->lock);
+ return -EIO;
+ }
+ break;
+ }
+ }
+ if (tmp != conn) {
+ /* bind new iSCSI connection to session */
+ conn->session = session;
+
+ list_add(&conn->item, &session->connections);
+ }
+ spin_unlock_bh(&session->lock);
+
+ if (conn->stop_stage != STOP_CONN_SUSPEND) {
+ /* bind iSCSI connection and socket */
+ conn->sock = sock;
+
+ /* setup Socket parameters */
+ sk = sock->sk;
+ sk->sk_reuse = 1;
+ sk->sk_sndtimeo = 15 * HZ; /* FIXME: make it configurable */
+ sk->sk_allocation = GFP_ATOMIC;
+
+ /* FIXME: disable Nagle's algorithm */
+
+ /*
+ * Intercept TCP callbacks for sendfile like receive
+ * processing.
+ */
+ iscsi_conn_set_callbacks(conn);
+
+ /*
+ * set receive state machine into initial state
+ */
+ conn->in_progress = IN_PROGRESS_WAIT_HEADER;
+ }
+
+ if (is_leading)
+ session->leadconn = conn;
+
+ /*
+ * Unblock xmitworker(), Login Phase will pass through.
+ */
+ clear_bit(SUSPEND_BIT, &conn->suspend_rx);
+ clear_bit(SUSPEND_BIT, &conn->suspend_tx);
+
+ return 0;
+}
+
+static int
+iscsi_conn_start(iscsi_connh_t connh)
+{
+ struct iscsi_conn *conn = iscsi_ptr(connh);
+ struct iscsi_session *session = conn->session;
+ struct sock *sk;
+
+ /* FF phase warming up... */
+
+ if (session == NULL) {
+ printk(KERN_ERR "iscsi_tcp: can't start unbound connection\n");
+ return -EPERM;
+ }
+
+ sk = conn->sock->sk;
+
+ write_lock_bh(&sk->sk_callback_lock);
+ spin_lock_bh(&session->lock);
+ conn->c_stage = ISCSI_CONN_STARTED;
+ session->state = ISCSI_STATE_LOGGED_IN;
+
+ switch(conn->stop_stage) {
+ case STOP_CONN_RECOVER:
+ /*
+ * unblock eh_abort() if it is blocked. re-try all
+ * commands after successful recovery
+ */
+ session->conn_cnt++;
+ conn->stop_stage = 0;
+ conn->tmabort_state = TMABORT_INITIAL;
+ session->age++;
+ wake_up(&conn->ehwait);
+ break;
+ case STOP_CONN_TERM:
+ session->conn_cnt++;
+ conn->stop_stage = 0;
+ break;
+ case STOP_CONN_SUSPEND:
+ conn->stop_stage = 0;
+ clear_bit(SUSPEND_BIT, &conn->suspend_rx);
+ clear_bit(SUSPEND_BIT, &conn->suspend_tx);
+ break;
+ default:
+ break;
+ }
+ spin_unlock_bh(&session->lock);
+ write_unlock_bh(&sk->sk_callback_lock);
+
+ return 0;
+}
+
+static void
+iscsi_conn_stop(iscsi_connh_t connh, int flag)
+{
+ struct iscsi_conn *conn = iscsi_ptr(connh);
+ struct iscsi_session *session = conn->session;
+ struct sock *sk;
+ unsigned long flags;
+
+ BUG_ON(!conn->sock);
+ sk = conn->sock->sk;
+ write_lock_bh(&sk->sk_callback_lock);
+ set_bit(SUSPEND_BIT, &conn->suspend_rx);
+ write_unlock_bh(&sk->sk_callback_lock);
+
+ down(&conn->xmitsema);
+
+ spin_lock_irqsave(session->host->host_lock, flags);
+ spin_lock(&session->lock);
+ conn->stop_stage = flag;
+ conn->c_stage = ISCSI_CONN_STOPPED;
+ set_bit(SUSPEND_BIT, &conn->suspend_tx);
+
+ if (flag != STOP_CONN_SUSPEND)
+ session->conn_cnt--;
+
+ if (session->conn_cnt == 0 || session->leadconn == conn)
+ session->state = ISCSI_STATE_FAILED;
+
+ spin_unlock(&session->lock);
+ spin_unlock_irqrestore(session->host->host_lock, flags);
+
+ if (flag == STOP_CONN_TERM || flag == STOP_CONN_RECOVER) {
+ struct iscsi_cmd_task *ctask;
+ struct iscsi_mgmt_task *mtask;
+
+ /*
+ * Socket must go now.
+ */
+ sock_hold(conn->sock->sk);
+ iscsi_conn_restore_callbacks(conn);
+ sock_put(conn->sock->sk);
+
+ /*
+ * flush xmit queues.
+ */
+ spin_lock_bh(&session->lock);
+ while (__kfifo_get(conn->writequeue, (void*)&ctask,
+ sizeof(void*)) ||
+ __kfifo_get(conn->xmitqueue, (void*)&ctask,
+ sizeof(void*))) {
+ struct iscsi_r2t_info *r2t;
+
+ /*
+ * flush ctask's r2t queues
+ */
+ while (__kfifo_get(ctask->r2tqueue, (void*)&r2t,
+ sizeof(void*)))
+ __kfifo_put(ctask->r2tpool.queue, (void*)&r2t,
+ sizeof(void*));
+
+ spin_unlock_bh(&session->lock);
+ local_bh_disable();
+ iscsi_ctask_cleanup(conn, ctask);
+ local_bh_enable();
+ spin_lock_bh(&session->lock);
+ }
+ conn->ctask = NULL;
+ while (__kfifo_get(conn->immqueue, (void*)&mtask,
+ sizeof(void*)) ||
+ __kfifo_get(conn->mgmtqueue, (void*)&mtask,
+ sizeof(void*))) {
+ __kfifo_put(session->mgmtpool.queue,
+ (void*)&mtask, sizeof(void*));
+ }
+ conn->mtask = NULL;
+ spin_unlock_bh(&session->lock);
+
+ /*
+ * release socket only after we stopped data_xmit()
+ * activity and flushed all outstandings
+ */
+ sock_release(conn->sock);
+ conn->sock = NULL;
+
+ /*
+ * for connection level recovery we should not calculate
+ * header digest. conn->hdr_size used for optimization
+ * in hdr_extract() and will be re-negotiated at
+ * set_param() time.
+ */
+ if (flag == STOP_CONN_RECOVER)
+ conn->hdr_size = sizeof(struct iscsi_hdr);
+ }
+ up(&conn->xmitsema);
+}
+
+static int
+iscsi_conn_send_generic(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
+ char *data, uint32_t data_size)
+{
+ struct iscsi_session *session = conn->session;
+ struct iscsi_nopout *nop = (struct iscsi_nopout *)hdr;
+ struct iscsi_mgmt_task *mtask;
+
+ spin_lock_bh(&session->lock);
+ if (session->state == ISCSI_STATE_TERMINATE) {
+ spin_unlock_bh(&session->lock);
+ return -EPERM;
+ }
+ if (hdr->opcode == (ISCSI_OP_LOGIN | ISCSI_OP_IMMEDIATE) ||
+ hdr->opcode == (ISCSI_OP_TEXT | ISCSI_OP_IMMEDIATE))
+ /*
+ * Login and Text are sent serially, in
+ * request-followed-by-response sequence.
+ * Same mtask can be used. Same ITT must be used.
+ * Note that login_mtask is preallocated at conn_create().
+ */
+ mtask = conn->login_mtask;
+ else {
+ BUG_ON(conn->c_stage == ISCSI_CONN_INITIAL_STAGE);
+ BUG_ON(conn->c_stage == ISCSI_CONN_STOPPED);
+
+ if (!__kfifo_get(session->mgmtpool.queue,
+ (void*)&mtask, sizeof(void*))) {
+ spin_unlock_bh(&session->lock);
+ return -ENOSPC;
+ }
+ }
+
+ /*
+ * pre-format CmdSN and ExpStatSN for outgoing PDU.
+ */
+ if (hdr->itt != cpu_to_be32(ISCSI_RESERVED_TAG)) {
+ hdr->itt = mtask->itt | (conn->id << CID_SHIFT) |
+ (session->age << AGE_SHIFT);
+ nop->cmdsn = cpu_to_be32(session->cmdsn);
+ if (conn->c_stage == ISCSI_CONN_STARTED &&
+ !(hdr->opcode & ISCSI_OP_IMMEDIATE))
+ session->cmdsn++;
+ } else
+ /* do not advance CmdSN */
+ nop->cmdsn = cpu_to_be32(session->cmdsn);
+
+ nop->exp_statsn = cpu_to_be32(conn->exp_statsn);
+
+ memcpy(&mtask->hdr, hdr, sizeof(struct iscsi_hdr));
+
+ iscsi_buf_init_virt(&mtask->headbuf, (char*)&mtask->hdr,
+ sizeof(struct iscsi_hdr));
+
+ spin_unlock_bh(&session->lock);
+
+ if (data_size) {
+ memcpy(mtask->data, data, data_size);
+ mtask->data_count = data_size;
+ } else
+ mtask->data_count = 0;
+
+ mtask->xmstate = XMSTATE_IMM_HDR;
+
+ if (mtask->data_count) {
+ iscsi_buf_init_iov(&mtask->sendbuf, (char*)mtask->data,
+ mtask->data_count);
+ }
+
+ debug_scsi("mgmtpdu [op 0x%x hdr->itt 0x%x datalen %d]\n",
+ hdr->opcode, hdr->itt, data_size);
+
+ /*
+ * since send_pdu() could be called at least from two contexts,
+ * we need to serialize __kfifo_put, so we don't have to take
+ * additional lock on fast data-path
+ */
+ if (hdr->opcode & ISCSI_OP_IMMEDIATE)
+ __kfifo_put(conn->immqueue, (void*)&mtask, sizeof(void*));
+ else
+ __kfifo_put(conn->mgmtqueue, (void*)&mtask, sizeof(void*));
+
+ schedule_work(&conn->xmitwork);
+
+ return 0;
+}
+
+static int
+iscsi_eh_host_reset(struct scsi_cmnd *sc)
+{
+ struct iscsi_cmd_task *ctask = (struct iscsi_cmd_task *)sc->SCp.ptr;
+ struct iscsi_conn *conn = ctask->conn;
+ struct iscsi_session *session = conn->session;
+
+ spin_lock_bh(&session->lock);
+ if (session->state == ISCSI_STATE_TERMINATE) {
+ debug_scsi("failing host reset: session terminated "
+ "[CID %d age %d]", conn->id, session->age);
+ spin_unlock_bh(&session->lock);
+ return FAILED;
+ }
+ spin_unlock_bh(&session->lock);
+
+ debug_scsi("failing connection CID %d due to SCSI host reset "
+ "[itt 0x%x age %d]", conn->id, ctask->itt,
+ session->age);
+ iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED);
+
+ return SUCCESS;
+}
+
+static void
+iscsi_tmabort_timedout(unsigned long data)
+{
+ struct iscsi_cmd_task *ctask = (struct iscsi_cmd_task *)data;
+ struct iscsi_conn *conn = ctask->conn;
+ struct iscsi_session *session = conn->session;
+
+ spin_lock(&session->lock);
+ if (conn->tmabort_state == TMABORT_INITIAL) {
+ __kfifo_put(session->mgmtpool.queue,
+ (void*)&ctask->mtask, sizeof(void*));
+ conn->tmabort_state = TMABORT_TIMEDOUT;
+ debug_scsi("tmabort timedout [sc %lx itt 0x%x]\n",
+ (long)ctask->sc, ctask->itt);
+ /* unblock eh_abort() */
+ wake_up(&conn->ehwait);
+ }
+ spin_unlock(&session->lock);
+}
+
+static int
+iscsi_eh_abort(struct scsi_cmnd *sc)
+{
+ int rc;
+ struct iscsi_cmd_task *ctask = (struct iscsi_cmd_task *)sc->SCp.ptr;
+ struct iscsi_conn *conn = ctask->conn;
+ struct iscsi_session *session = conn->session;
+
+ conn->eh_abort_cnt++;
+ debug_scsi("aborting [sc %lx itt 0x%x]\n", (long)sc, ctask->itt);
+
+ /*
+ * two cases for ERL=0 here:
+ *
+ * 1) connection-level failure;
+ * 2) recovery due protocol error;
+ */
+ down(&conn->xmitsema);
+ spin_lock_bh(&session->lock);
+ if (session->state != ISCSI_STATE_LOGGED_IN) {
+ if (session->state == ISCSI_STATE_TERMINATE) {
+ spin_unlock_bh(&session->lock);
+ up(&conn->xmitsema);
+ goto failed;
+ }
+ spin_unlock_bh(&session->lock);
+ } else {
+ struct iscsi_tm *hdr = &conn->tmhdr;
+
+ /*
+ * Still LOGGED_IN...
+ */
+
+ if (!ctask->sc || sc->SCp.phase != session->age) {
+ /*
+ * 1) ctask completed before time out. But session
+ * is still ok => Happy Retry.
+ * 2) session was re-open during time out of ctask.
+ */
+ spin_unlock_bh(&session->lock);
+ up(&conn->xmitsema);
+ goto success;
+ }
+ conn->tmabort_state = TMABORT_INITIAL;
+ spin_unlock_bh(&session->lock);
+
+ /*
+ * ctask timed out but session is OK
+ * ERL=0 requires task mgmt abort to be issued on each
+ * failed command. requests must be serialized.
+ */
+ memset(hdr, 0, sizeof(struct iscsi_tm));
+ hdr->opcode = ISCSI_OP_SCSI_TMFUNC | ISCSI_OP_IMMEDIATE;
+ hdr->flags = ISCSI_TM_FUNC_ABORT_TASK;
+ hdr->flags |= ISCSI_FLAG_CMD_FINAL;
+ memcpy(hdr->lun, ctask->hdr.lun, sizeof(hdr->lun));
+ hdr->rtt = ctask->hdr.itt;
+ hdr->refcmdsn = ctask->hdr.cmdsn;
+
+ rc = iscsi_conn_send_generic(conn, (struct iscsi_hdr *)hdr,
+ NULL, 0);
+ if (rc) {
+ iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED);
+ debug_scsi("abort sent failure [itt 0x%x]", ctask->itt);
+ } else {
+ struct iscsi_r2t_info *r2t;
+
+ /*
+ * TMF abort vs. TMF response race logic
+ */
+ spin_lock_bh(&session->lock);
+ ctask->mtask = (struct iscsi_mgmt_task *)
+ session->mgmt_cmds[(hdr->itt & ITT_MASK) -
+ ISCSI_MGMT_ITT_OFFSET];
+ /*
+ * have to flush r2tqueue to avoid r2t leaks
+ */
+ while (__kfifo_get(ctask->r2tqueue, (void*)&r2t,
+ sizeof(void*))) {
+ __kfifo_put(ctask->r2tpool.queue, (void*)&r2t,
+ sizeof(void*));
+ }
+ if (conn->tmabort_state == TMABORT_INITIAL) {
+ conn->tmfcmd_pdus_cnt++;
+ conn->tmabort_timer.expires = 3*HZ + jiffies;
+ conn->tmabort_timer.function =
+ iscsi_tmabort_timedout;
+ conn->tmabort_timer.data = (unsigned long)ctask;
+ add_timer(&conn->tmabort_timer);
+ debug_scsi("abort sent [itt 0x%x]", ctask->itt);
+ } else {
+ if (!ctask->sc ||
+ conn->tmabort_state == TMABORT_SUCCESS) {
+ conn->tmabort_state = TMABORT_INITIAL;
+ spin_unlock_bh(&session->lock);
+ up(&conn->xmitsema);
+ goto success;
+ }
+ conn->tmabort_state = TMABORT_INITIAL;
+ iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED);
+ }
+ spin_unlock_bh(&session->lock);
+ }
+ }
+ up(&conn->xmitsema);
+
+
+ /*
+ * block eh thread until:
+ *
+ * 1) abort response;
+ * 2) abort timeout;
+ * 3) session re-opened;
+ * 4) session terminated;
+ */
+ for (;;) {
+ int p_state = session->state;
+
+ rc = wait_event_interruptible(conn->ehwait,
+ (p_state == ISCSI_STATE_LOGGED_IN ?
+ (session->state == ISCSI_STATE_TERMINATE ||
+ conn->tmabort_state != TMABORT_INITIAL) :
+ (session->state == ISCSI_STATE_TERMINATE ||
+ session->state == ISCSI_STATE_LOGGED_IN)));
+ if (rc) {
+ /* shutdown.. */
+ session->state = ISCSI_STATE_TERMINATE;
+ goto failed;
+ }
+
+ if (signal_pending(current))
+ flush_signals(current);
+
+ if (session->state == ISCSI_STATE_TERMINATE)
+ goto failed;
+
+ spin_lock_bh(&session->lock);
+ if (sc->SCp.phase == session->age &&
+ (conn->tmabort_state == TMABORT_TIMEDOUT ||
+ conn->tmabort_state == TMABORT_FAILED)) {
+ conn->tmabort_state = TMABORT_INITIAL;
+ if (!ctask->sc) {
+ /*
+ * ctask completed before tmf abort response or
+ * time out.
+ * But session is still ok => Happy Retry.
+ */
+ spin_unlock_bh(&session->lock);
+ break;
+ }
+ spin_unlock_bh(&session->lock);
+ iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED);
+ continue;
+ }
+ spin_unlock_bh(&session->lock);
+ break;
+ }
+
+success:
+ debug_scsi("abort success [sc %lx itt 0x%x]\n", (long)sc, ctask->itt);
+ rc = SUCCESS;
+ goto exit;
+
+failed:
+ debug_scsi("abort failed [sc %lx itt 0x%x]\n", (long)sc, ctask->itt);
+ rc = FAILED;
+
+exit:
+ del_timer_sync(&conn->tmabort_timer);
+
+ down(&conn->xmitsema);
+ if (conn->sock) {
+ struct sock *sk = conn->sock->sk;
+
+ write_lock_bh(&sk->sk_callback_lock);
+ iscsi_ctask_cleanup(conn, ctask);
+ write_unlock_bh(&sk->sk_callback_lock);
+ }
+ up(&conn->xmitsema);
+ return rc;
+}
+
+static int
+iscsi_r2tpool_alloc(struct iscsi_session *session)
+{
+ int i;
+ int cmd_i;
+
+ /*
+ * initialize per-task: R2T pool and xmit queue
+ */
+ for (cmd_i = 0; cmd_i < session->cmds_max; cmd_i++) {
+ struct iscsi_cmd_task *ctask = session->cmds[cmd_i];
+
+ /*
+ * pre-allocated x4 as much r2ts to handle race when
+ * target acks DataOut faster than we data_xmit() queues
+ * could replenish r2tqueue.
+ */
+
+ /* R2T pool */
+ if (iscsi_pool_init(&ctask->r2tpool, session->max_r2t * 4,
+ (void***)&ctask->r2ts, sizeof(struct iscsi_r2t_info))) {
+ goto r2t_alloc_fail;
+ }
+
+ /* R2T xmit queue */
+ ctask->r2tqueue = kfifo_alloc(
+ session->max_r2t * 4 * sizeof(void*), GFP_KERNEL, NULL);
+ if (ctask->r2tqueue == ERR_PTR(-ENOMEM)) {
+ iscsi_pool_free(&ctask->r2tpool, (void**)ctask->r2ts);
+ goto r2t_alloc_fail;
+ }
+
+ /*
+ * number of
+ * Data-Out PDU's within R2T-sequence can be quite big;
+ * using mempool
+ */
+ ctask->datapool = mempool_create(ISCSI_DTASK_DEFAULT_MAX,
+ mempool_alloc_slab, mempool_free_slab, taskcache);
+ if (ctask->datapool == NULL) {
+ kfifo_free(ctask->r2tqueue);
+ iscsi_pool_free(&ctask->r2tpool, (void**)ctask->r2ts);
+ goto r2t_alloc_fail;
+ }
+ INIT_LIST_HEAD(&ctask->dataqueue);
+ }
+
+ return 0;
+
+r2t_alloc_fail:
+ for (i = 0; i < cmd_i; i++) {
+ mempool_destroy(session->cmds[i]->datapool);
+ kfifo_free(session->cmds[i]->r2tqueue);
+ iscsi_pool_free(&session->cmds[i]->r2tpool,
+ (void**)session->cmds[i]->r2ts);
+ }
+ return -ENOMEM;
+}
+
+static void
+iscsi_r2tpool_free(struct iscsi_session *session)
+{
+ int i;
+
+ for (i = 0; i < session->cmds_max; i++) {
+ mempool_destroy(session->cmds[i]->datapool);
+ kfifo_free(session->cmds[i]->r2tqueue);
+ iscsi_pool_free(&session->cmds[i]->r2tpool,
+ (void**)session->cmds[i]->r2ts);
+ }
+}
+
+static struct scsi_host_template iscsi_sht = {
+ .name = "iSCSI Initiator over TCP/IP, v."
+ ISCSI_VERSION_STR,
+ .queuecommand = iscsi_queuecommand,
+ .can_queue = ISCSI_XMIT_CMDS_MAX - 1,
+ .sg_tablesize = ISCSI_SG_TABLESIZE,
+ .cmd_per_lun = ISCSI_CMD_PER_LUN,
+ .eh_abort_handler = iscsi_eh_abort,
+ .eh_host_reset_handler = iscsi_eh_host_reset,
+ .use_clustering = DISABLE_CLUSTERING,
+ .proc_name = "iscsi_tcp",
+ .this_id = -1,
+};
+
+static iscsi_sessionh_t
+iscsi_session_create(uint32_t initial_cmdsn, struct Scsi_Host *host)
+{
+ int cmd_i;
+ struct iscsi_session *session;
+
+ session = iscsi_hostdata(host->hostdata);
+ memset(session, 0, sizeof(struct iscsi_session));
+
+ session->host = host;
+ session->id = host->host_no;
+ session->state = ISCSI_STATE_LOGGED_IN;
+ session->mgmtpool_max = ISCSI_MGMT_CMDS_MAX;
+ session->cmds_max = ISCSI_XMIT_CMDS_MAX;
+ session->cmdsn = initial_cmdsn;
+ session->exp_cmdsn = initial_cmdsn + 1;
+ session->max_cmdsn = initial_cmdsn + 1;
+ session->max_r2t = 1;
+
+ /* initialize SCSI PDU commands pool */
+ if (iscsi_pool_init(&session->cmdpool, session->cmds_max,
+ (void***)&session->cmds, sizeof(struct iscsi_cmd_task)))
+ goto cmdpool_alloc_fail;
+
+ /* pre-format cmds pool with ITT */
+ for (cmd_i = 0; cmd_i < session->cmds_max; cmd_i++)
+ session->cmds[cmd_i]->itt = cmd_i;
+
+ spin_lock_init(&session->lock);
+ INIT_LIST_HEAD(&session->connections);
+
+ /* initialize immediate command pool */
+ if (iscsi_pool_init(&session->mgmtpool, session->mgmtpool_max,
+ (void***)&session->mgmt_cmds, sizeof(struct iscsi_mgmt_task)))
+ goto mgmtpool_alloc_fail;
+
+
+ /* pre-format immediate cmds pool with ITT */
+ for (cmd_i = 0; cmd_i < session->mgmtpool_max; cmd_i++) {
+ session->mgmt_cmds[cmd_i]->itt = ISCSI_MGMT_ITT_OFFSET + cmd_i;
+ session->mgmt_cmds[cmd_i]->data = kmalloc(
+ DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH, GFP_KERNEL);
+ if (!session->mgmt_cmds[cmd_i]->data) {
+ int j;
+
+ for (j = 0; j < cmd_i; j++)
+ kfree(session->mgmt_cmds[j]->data);
+ goto immdata_alloc_fail;
+ }
+ }
+
+ if (iscsi_r2tpool_alloc(session))
+ goto r2tpool_alloc_fail;
+
+ return iscsi_handle(session);
+
+r2tpool_alloc_fail:
+ for (cmd_i = 0; cmd_i < session->mgmtpool_max; cmd_i++)
+ kfree(session->mgmt_cmds[cmd_i]->data);
+ iscsi_pool_free(&session->mgmtpool, (void**)session->mgmt_cmds);
+immdata_alloc_fail:
+mgmtpool_alloc_fail:
+ iscsi_pool_free(&session->cmdpool, (void**)session->cmds);
+cmdpool_alloc_fail:
+ return iscsi_handle(NULL);
+}
+
+static void
+iscsi_session_destroy(iscsi_sessionh_t sessionh)
+{
+ int cmd_i;
+ struct iscsi_data_task *dtask, *n;
+ struct iscsi_session *session = iscsi_ptr(sessionh);
+
+ for (cmd_i = 0; cmd_i < session->cmds_max; cmd_i++) {
+ struct iscsi_cmd_task *ctask = session->cmds[cmd_i];
+ list_for_each_entry_safe(dtask, n, &ctask->dataqueue, item) {
+ list_del(&dtask->item);
+ mempool_free(dtask, ctask->datapool);
+ }
+ }
+
+ for (cmd_i = 0; cmd_i < session->mgmtpool_max; cmd_i++)
+ kfree(session->mgmt_cmds[cmd_i]->data);
+
+ iscsi_r2tpool_free(session);
+ iscsi_pool_free(&session->mgmtpool, (void**)session->mgmt_cmds);
+ iscsi_pool_free(&session->cmdpool, (void**)session->cmds);
+}
+
+static int
+iscsi_conn_set_param(iscsi_connh_t connh, enum iscsi_param param,
+ uint32_t value)
+{
+ struct iscsi_conn *conn = iscsi_ptr(connh);
+ struct iscsi_session *session = conn->session;
+
+ spin_lock_bh(&session->lock);
+ if (conn->c_stage != ISCSI_CONN_INITIAL_STAGE &&
+ conn->stop_stage != STOP_CONN_RECOVER) {
+ printk(KERN_ERR "iscsi_tcp: can not change parameter [%d]\n",
+ param);
+ spin_unlock_bh(&session->lock);
+ return 0;
+ }
+ spin_unlock_bh(&session->lock);
+
+ switch(param) {
+ case ISCSI_PARAM_MAX_RECV_DLENGTH: {
+ char *saveptr = conn->data;
+ int flags = GFP_KERNEL;
+
+ if (conn->data_size >= value) {
+ conn->max_recv_dlength = value;
+ break;
+ }
+
+ spin_lock_bh(&session->lock);
+ if (conn->stop_stage == STOP_CONN_RECOVER)
+ flags = GFP_ATOMIC;
+ spin_unlock_bh(&session->lock);
+
+ if (value <= PAGE_SIZE)
+ conn->data = kmalloc(value, flags);
+ else
+ conn->data = (void*)__get_free_pages(flags,
+ get_order(value));
+ if (conn->data == NULL) {
+ conn->data = saveptr;
+ return -ENOMEM;
+ }
+ if (conn->data_size <= PAGE_SIZE)
+ kfree(saveptr);
+ else
+ free_pages((unsigned long)saveptr,
+ get_order(conn->data_size));
+ conn->max_recv_dlength = value;
+ conn->data_size = value;
+ }
+ break;
+ case ISCSI_PARAM_MAX_XMIT_DLENGTH:
+ conn->max_xmit_dlength = value;
+ break;
+ case ISCSI_PARAM_HDRDGST_EN:
+ conn->hdrdgst_en = value;
+ conn->hdr_size = sizeof(struct iscsi_hdr);
+ if (conn->hdrdgst_en) {
+ conn->hdr_size += sizeof(__u32);
+ if (!conn->tx_tfm)
+ conn->tx_tfm = crypto_alloc_tfm("crc32c", 0);
+ if (!conn->tx_tfm)
+ return -ENOMEM;
+ if (!conn->rx_tfm)
+ conn->rx_tfm = crypto_alloc_tfm("crc32c", 0);
+ if (!conn->rx_tfm) {
+ crypto_free_tfm(conn->tx_tfm);
+ return -ENOMEM;
+ }
+ } else {
+ if (conn->tx_tfm)
+ crypto_free_tfm(conn->tx_tfm);
+ if (conn->rx_tfm)
+ crypto_free_tfm(conn->rx_tfm);
+ }
+ break;
+ case ISCSI_PARAM_DATADGST_EN:
+ conn->datadgst_en = value;
+ if (conn->datadgst_en) {
+ if (!conn->data_tx_tfm)
+ conn->data_tx_tfm =
+ crypto_alloc_tfm("crc32c", 0);
+ if (!conn->data_tx_tfm)
+ return -ENOMEM;
+ if (!conn->data_rx_tfm)
+ conn->data_rx_tfm =
+ crypto_alloc_tfm("crc32c", 0);
+ if (!conn->data_rx_tfm) {
+ crypto_free_tfm(conn->data_tx_tfm);
+ return -ENOMEM;
+ }
+ } else {
+ if (conn->data_tx_tfm)
+ crypto_free_tfm(conn->data_tx_tfm);
+ if (conn->data_rx_tfm)
+ crypto_free_tfm(conn->data_rx_tfm);
+ }
+ break;
+ case ISCSI_PARAM_INITIAL_R2T_EN:
+ session->initial_r2t_en = value;
+ break;
+ case ISCSI_PARAM_MAX_R2T:
+ if (session->max_r2t == roundup_pow_of_two(value))
+ break;
+ iscsi_r2tpool_free(session);
+ session->max_r2t = value;
+ if (session->max_r2t & (session->max_r2t - 1))
+ session->max_r2t = roundup_pow_of_two(session->max_r2t);
+ if (iscsi_r2tpool_alloc(session))
+ return -ENOMEM;
+ break;
+ case ISCSI_PARAM_IMM_DATA_EN:
+ session->imm_data_en = value;
+ break;
+ case ISCSI_PARAM_FIRST_BURST:
+ session->first_burst = value;
+ break;
+ case ISCSI_PARAM_MAX_BURST:
+ session->max_burst = value;
+ break;
+ case ISCSI_PARAM_PDU_INORDER_EN:
+ session->pdu_inorder_en = value;
+ break;
+ case ISCSI_PARAM_DATASEQ_INORDER_EN:
+ session->dataseq_inorder_en = value;
+ break;
+ case ISCSI_PARAM_ERL:
+ session->erl = value;
+ break;
+ case ISCSI_PARAM_IFMARKER_EN:
+ BUG_ON(value);
+ session->ifmarker_en = value;
+ break;
+ case ISCSI_PARAM_OFMARKER_EN:
+ BUG_ON(value);
+ session->ofmarker_en = value;
+ break;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+static int
+iscsi_conn_get_param(iscsi_connh_t connh, enum iscsi_param param,
+ uint32_t *value)
+{
+ struct iscsi_conn *conn = iscsi_ptr(connh);
+ struct iscsi_session *session = conn->session;
+
+ switch(param) {
+ case ISCSI_PARAM_MAX_RECV_DLENGTH:
+ *value = conn->max_recv_dlength;
+ break;
+ case ISCSI_PARAM_MAX_XMIT_DLENGTH:
+ *value = conn->max_xmit_dlength;
+ break;
+ case ISCSI_PARAM_HDRDGST_EN:
+ *value = conn->hdrdgst_en;
+ break;
+ case ISCSI_PARAM_DATADGST_EN:
+ *value = conn->datadgst_en;
+ break;
+ case ISCSI_PARAM_INITIAL_R2T_EN:
+ *value = session->initial_r2t_en;
+ break;
+ case ISCSI_PARAM_MAX_R2T:
+ *value = session->max_r2t;
+ break;
+ case ISCSI_PARAM_IMM_DATA_EN:
+ *value = session->imm_data_en;
+ break;
+ case ISCSI_PARAM_FIRST_BURST:
+ *value = session->first_burst;
+ break;
+ case ISCSI_PARAM_MAX_BURST:
+ *value = session->max_burst;
+ break;
+ case ISCSI_PARAM_PDU_INORDER_EN:
+ *value = session->pdu_inorder_en;
+ break;
+ case ISCSI_PARAM_DATASEQ_INORDER_EN:
+ *value = session->dataseq_inorder_en;
+ break;
+ case ISCSI_PARAM_ERL:
+ *value = session->erl;
+ break;
+ case ISCSI_PARAM_IFMARKER_EN:
+ *value = session->ifmarker_en;
+ break;
+ case ISCSI_PARAM_OFMARKER_EN:
+ *value = session->ofmarker_en;
+ break;
+ default:
+ return ISCSI_ERR_PARAM_NOT_FOUND;
+ }
+
+ return 0;
+}
+
+static void
+iscsi_conn_get_stats(iscsi_connh_t connh, struct iscsi_stats *stats)
+{
+ struct iscsi_conn *conn = iscsi_ptr(connh);
+
+ stats->txdata_octets = conn->txdata_octets;
+ stats->rxdata_octets = conn->rxdata_octets;
+ stats->scsicmd_pdus = conn->scsicmd_pdus_cnt;
+ stats->dataout_pdus = conn->dataout_pdus_cnt;
+ stats->scsirsp_pdus = conn->scsirsp_pdus_cnt;
+ stats->datain_pdus = conn->datain_pdus_cnt;
+ stats->r2t_pdus = conn->r2t_pdus_cnt;
+ stats->tmfcmd_pdus = conn->tmfcmd_pdus_cnt;
+ stats->tmfrsp_pdus = conn->tmfrsp_pdus_cnt;
+ stats->custom_length = 3;
+ strcpy(stats->custom[0].desc, "tx_sendpage_failures");
+ stats->custom[0].value = conn->sendpage_failures_cnt;
+ strcpy(stats->custom[1].desc, "rx_discontiguous_hdr");
+ stats->custom[1].value = conn->discontiguous_hdr_cnt;
+ strcpy(stats->custom[2].desc, "eh_abort_cnt");
+ stats->custom[2].value = conn->eh_abort_cnt;
+}
+
+static int
+iscsi_conn_send_pdu(iscsi_connh_t connh, struct iscsi_hdr *hdr, char *data,
+ uint32_t data_size)
+{
+ struct iscsi_conn *conn = iscsi_ptr(connh);
+ int rc;
+
+ down(&conn->xmitsema);
+ rc = iscsi_conn_send_generic(conn, hdr, data, data_size);
+ up(&conn->xmitsema);
+
+ return rc;
+}
+
+static struct iscsi_transport iscsi_tcp_transport = {
+ .owner = THIS_MODULE,
+ .name = "tcp",
+ .caps = CAP_RECOVERY_L0 | CAP_MULTI_R2T | CAP_HDRDGST
+ | CAP_DATADGST,
+ .host_template = &iscsi_sht,
+ .hostdata_size = sizeof(struct iscsi_session),
+ .max_conn = 1,
+ .max_cmd_len = ISCSI_TCP_MAX_CMD_LEN,
+ .create_session = iscsi_session_create,
+ .destroy_session = iscsi_session_destroy,
+ .create_conn = iscsi_conn_create,
+ .bind_conn = iscsi_conn_bind,
+ .destroy_conn = iscsi_conn_destroy,
+ .set_param = iscsi_conn_set_param,
+ .get_param = iscsi_conn_get_param,
+ .start_conn = iscsi_conn_start,
+ .stop_conn = iscsi_conn_stop,
+ .send_pdu = iscsi_conn_send_pdu,
+ .get_stats = iscsi_conn_get_stats,
+};
+
+static int __init
+iscsi_tcp_init(void)
+{
+ int error;
+
+ if (iscsi_max_lun < 1) {
+ printk(KERN_ERR "Invalid max_lun value of %u\n", iscsi_max_lun);
+ return -EINVAL;
+ }
+ iscsi_tcp_transport.max_lun = iscsi_max_lun;
+
+ taskcache = kmem_cache_create("iscsi_taskcache",
+ sizeof(struct iscsi_data_task), 0,
+ SLAB_HWCACHE_ALIGN | SLAB_NO_REAP, NULL, NULL);
+ if (!taskcache)
+ return -ENOMEM;
+
+ error = iscsi_register_transport(&iscsi_tcp_transport);
+ if (error)
+ kmem_cache_destroy(taskcache);
+
+ return error;
+}
+
+static void __exit
+iscsi_tcp_exit(void)
+{
+ iscsi_unregister_transport(&iscsi_tcp_transport);
+ kmem_cache_destroy(taskcache);
+}
+
+module_init(iscsi_tcp_init);
+module_exit(iscsi_tcp_exit);
diff --git a/drivers/scsi/iscsi_tcp.h b/drivers/scsi/iscsi_tcp.h
new file mode 100644
index 000000000000..d23ae68fae0d
--- /dev/null
+++ b/drivers/scsi/iscsi_tcp.h
@@ -0,0 +1,322 @@
+/*
+ * iSCSI Initiator TCP Transport
+ * Copyright (C) 2004 Dmitry Yusupov
+ * Copyright (C) 2004 Alex Aizman
+ * Copyright (C) 2005 Mike Christie
+ * maintained by open-iscsi@googlegroups.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.
+ *
+ * See the file COPYING included with this distribution for more details.
+ */
+
+#ifndef ISCSI_TCP_H
+#define ISCSI_TCP_H
+
+/* Session's states */
+#define ISCSI_STATE_FREE 1
+#define ISCSI_STATE_LOGGED_IN 2
+#define ISCSI_STATE_FAILED 3
+#define ISCSI_STATE_TERMINATE 4
+
+/* Connection's states */
+#define ISCSI_CONN_INITIAL_STAGE 0
+#define ISCSI_CONN_STARTED 1
+#define ISCSI_CONN_STOPPED 2
+#define ISCSI_CONN_CLEANUP_WAIT 3
+
+/* Connection suspend "bit" */
+#define SUSPEND_BIT 1
+
+/* Socket's Receive state machine */
+#define IN_PROGRESS_WAIT_HEADER 0x0
+#define IN_PROGRESS_HEADER_GATHER 0x1
+#define IN_PROGRESS_DATA_RECV 0x2
+#define IN_PROGRESS_DDIGEST_RECV 0x3
+
+/* Task Mgmt states */
+#define TMABORT_INITIAL 0x0
+#define TMABORT_SUCCESS 0x1
+#define TMABORT_FAILED 0x2
+#define TMABORT_TIMEDOUT 0x3
+
+/* xmit state machine */
+#define XMSTATE_IDLE 0x0
+#define XMSTATE_R_HDR 0x1
+#define XMSTATE_W_HDR 0x2
+#define XMSTATE_IMM_HDR 0x4
+#define XMSTATE_IMM_DATA 0x8
+#define XMSTATE_UNS_INIT 0x10
+#define XMSTATE_UNS_HDR 0x20
+#define XMSTATE_UNS_DATA 0x40
+#define XMSTATE_SOL_HDR 0x80
+#define XMSTATE_SOL_DATA 0x100
+#define XMSTATE_W_PAD 0x200
+#define XMSTATE_DATA_DIGEST 0x400
+
+#define ISCSI_CONN_MAX 1
+#define ISCSI_CONN_RCVBUF_MIN 262144
+#define ISCSI_CONN_SNDBUF_MIN 262144
+#define ISCSI_PAD_LEN 4
+#define ISCSI_R2T_MAX 16
+#define ISCSI_XMIT_CMDS_MAX 128 /* must be power of 2 */
+#define ISCSI_MGMT_CMDS_MAX 32 /* must be power of 2 */
+#define ISCSI_MGMT_ITT_OFFSET 0xa00
+#define ISCSI_SG_TABLESIZE SG_ALL
+#define ISCSI_CMD_PER_LUN 128
+#define ISCSI_TCP_MAX_CMD_LEN 16
+
+#define ITT_MASK (0xfff)
+#define CID_SHIFT 12
+#define CID_MASK (0xffff<<CID_SHIFT)
+#define AGE_SHIFT 28
+#define AGE_MASK (0xf<<AGE_SHIFT)
+
+struct iscsi_queue {
+ struct kfifo *queue; /* FIFO Queue */
+ void **pool; /* Pool of elements */
+ int max; /* Max number of elements */
+};
+
+struct iscsi_session;
+struct iscsi_cmd_task;
+struct iscsi_mgmt_task;
+
+/* Socket connection recieve helper */
+struct iscsi_tcp_recv {
+ struct iscsi_hdr *hdr;
+ struct sk_buff *skb;
+ int offset;
+ int len;
+ int hdr_offset;
+ int copy;
+ int copied;
+ int padding;
+ struct iscsi_cmd_task *ctask; /* current cmd in progress */
+
+ /* copied and flipped values */
+ int opcode;
+ int flags;
+ int cmd_status;
+ int ahslen;
+ int datalen;
+ uint32_t itt;
+ int datadgst;
+};
+
+struct iscsi_conn {
+ struct iscsi_hdr hdr; /* header placeholder */
+ char hdrext[4*sizeof(__u16) +
+ sizeof(__u32)];
+ int data_copied;
+ char *data; /* data placeholder */
+ struct socket *sock; /* TCP socket */
+ int data_size; /* actual recv_dlength */
+ int stop_stage; /* conn_stop() flag: *
+ * stop to recover, *
+ * stop to terminate */
+ /* iSCSI connection-wide sequencing */
+ uint32_t exp_statsn;
+ int hdr_size; /* PDU header size */
+ unsigned long suspend_rx; /* suspend Rx */
+
+ struct crypto_tfm *rx_tfm; /* CRC32C (Rx) */
+ struct crypto_tfm *data_rx_tfm; /* CRC32C (Rx) for data */
+
+ /* control data */
+ int senselen; /* scsi sense length */
+ int id; /* CID */
+ struct iscsi_tcp_recv in; /* TCP receive context */
+ struct iscsi_session *session; /* parent session */
+ struct list_head item; /* maintains list of conns */
+ int in_progress; /* connection state machine */
+ int c_stage; /* connection state */
+ struct iscsi_mgmt_task *login_mtask; /* mtask used for login/text */
+ struct iscsi_mgmt_task *mtask; /* xmit mtask in progress */
+ struct iscsi_cmd_task *ctask; /* xmit ctask in progress */
+ spinlock_t lock; /* FIXME: to be removed */
+
+ /* old values for socket callbacks */
+ void (*old_data_ready)(struct sock *, int);
+ void (*old_state_change)(struct sock *);
+ void (*old_write_space)(struct sock *);
+
+ /* xmit */
+ struct crypto_tfm *tx_tfm; /* CRC32C (Tx) */
+ struct crypto_tfm *data_tx_tfm; /* CRC32C (Tx) for data */
+ struct kfifo *writequeue; /* write cmds for Data-Outs */
+ struct kfifo *immqueue; /* immediate xmit queue */
+ struct kfifo *mgmtqueue; /* mgmt (control) xmit queue */
+ struct kfifo *xmitqueue; /* data-path cmd queue */
+ struct work_struct xmitwork; /* per-conn. xmit workqueue */
+ struct semaphore xmitsema; /* serializes connection xmit,
+ * access to kfifos: *
+ * xmitqueue, writequeue, *
+ * immqueue, mgmtqueue */
+ unsigned long suspend_tx; /* suspend Tx */
+
+ /* abort */
+ wait_queue_head_t ehwait; /* used in eh_abort() */
+ struct iscsi_tm tmhdr;
+ struct timer_list tmabort_timer; /* abort timer */
+ int tmabort_state; /* see TMABORT_INITIAL, etc.*/
+
+ /* negotiated params */
+ int max_recv_dlength;
+ int max_xmit_dlength;
+ int hdrdgst_en;
+ int datadgst_en;
+
+ /* MIB-statistics */
+ uint64_t txdata_octets;
+ uint64_t rxdata_octets;
+ uint32_t scsicmd_pdus_cnt;
+ uint32_t dataout_pdus_cnt;
+ uint32_t scsirsp_pdus_cnt;
+ uint32_t datain_pdus_cnt;
+ uint32_t r2t_pdus_cnt;
+ uint32_t tmfcmd_pdus_cnt;
+ int32_t tmfrsp_pdus_cnt;
+
+ /* custom statistics */
+ uint32_t sendpage_failures_cnt;
+ uint32_t discontiguous_hdr_cnt;
+ uint32_t eh_abort_cnt;
+};
+
+struct iscsi_session {
+ /* iSCSI session-wide sequencing */
+ uint32_t cmdsn;
+ uint32_t exp_cmdsn;
+ uint32_t max_cmdsn;
+
+ /* configuration */
+ int initial_r2t_en;
+ int max_r2t;
+ int imm_data_en;
+ int first_burst;
+ int max_burst;
+ int time2wait;
+ int time2retain;
+ int pdu_inorder_en;
+ int dataseq_inorder_en;
+ int erl;
+ int ifmarker_en;
+ int ofmarker_en;
+
+ /* control data */
+ struct Scsi_Host *host;
+ int id;
+ struct iscsi_conn *leadconn; /* leading connection */
+ spinlock_t lock; /* protects session state, *
+ * sequence numbers, *
+ * session resources: *
+ * - cmdpool, *
+ * - mgmtpool, *
+ * - r2tpool */
+ int state; /* session state */
+ struct list_head item;
+ void *auth_client;
+ int conn_cnt;
+ int age; /* counts session re-opens */
+
+ struct list_head connections; /* list of connections */
+ int cmds_max; /* size of cmds array */
+ struct iscsi_cmd_task **cmds; /* Original Cmds arr */
+ struct iscsi_queue cmdpool; /* PDU's pool */
+ int mgmtpool_max; /* size of mgmt array */
+ struct iscsi_mgmt_task **mgmt_cmds; /* Original mgmt arr */
+ struct iscsi_queue mgmtpool; /* Mgmt PDU's pool */
+};
+
+struct iscsi_buf {
+ struct scatterlist sg;
+ struct kvec iov;
+ unsigned int sent;
+};
+
+struct iscsi_data_task {
+ struct iscsi_data hdr; /* PDU */
+ char hdrext[sizeof(__u32)]; /* Header-Digest */
+ struct list_head item; /* data queue item */
+ struct iscsi_buf digestbuf; /* digest buffer */
+ uint32_t digest; /* data digest */
+};
+#define ISCSI_DTASK_DEFAULT_MAX ISCSI_SG_TABLESIZE * PAGE_SIZE / 512
+
+struct iscsi_mgmt_task {
+ struct iscsi_hdr hdr; /* mgmt. PDU */
+ char hdrext[sizeof(__u32)]; /* Header-Digest */
+ char *data; /* mgmt payload */
+ int xmstate; /* mgmt xmit progress */
+ int data_count; /* counts data to be sent */
+ struct iscsi_buf headbuf; /* header buffer */
+ struct iscsi_buf sendbuf; /* in progress buffer */
+ int sent;
+ uint32_t itt; /* this ITT */
+};
+
+struct iscsi_r2t_info {
+ __be32 ttt; /* copied from R2T */
+ __be32 exp_statsn; /* copied from R2T */
+ uint32_t data_length; /* copied from R2T */
+ uint32_t data_offset; /* copied from R2T */
+ struct iscsi_buf headbuf; /* Data-Out Header Buffer */
+ struct iscsi_buf sendbuf; /* Data-Out in progress buffer*/
+ int sent; /* R2T sequence progress */
+ int data_count; /* DATA-Out payload progress */
+ struct scatterlist *sg; /* per-R2T SG list */
+ int solicit_datasn;
+ struct iscsi_data_task *dtask; /* which data task */
+};
+
+struct iscsi_cmd_task {
+ struct iscsi_cmd hdr; /* iSCSI PDU header */
+ char hdrext[4*sizeof(__u16)+ /* AHS */
+ sizeof(__u32)]; /* HeaderDigest */
+ char pad[ISCSI_PAD_LEN];
+ int itt; /* this ITT */
+ int datasn; /* DataSN */
+ struct iscsi_buf headbuf; /* header buf (xmit) */
+ struct iscsi_buf sendbuf; /* in progress buffer*/
+ int sent;
+ struct scatterlist *sg; /* per-cmd SG list */
+ struct scatterlist *bad_sg; /* assert statement */
+ int sg_count; /* SG's to process */
+ uint32_t unsol_datasn;
+ uint32_t exp_r2tsn;
+ int xmstate; /* xmit xtate machine */
+ int imm_count; /* imm-data (bytes) */
+ int unsol_count; /* unsolicited (bytes)*/
+ int r2t_data_count; /* R2T Data-Out bytes */
+ int data_count; /* remaining Data-Out */
+ int pad_count; /* padded bytes */
+ struct scsi_cmnd *sc; /* associated SCSI cmd*/
+ int total_length;
+ int data_offset;
+ struct iscsi_conn *conn; /* used connection */
+ struct iscsi_mgmt_task *mtask; /* tmf mtask in progr */
+
+ struct iscsi_r2t_info *r2t; /* in progress R2T */
+ struct iscsi_queue r2tpool;
+ struct kfifo *r2tqueue;
+ struct iscsi_r2t_info **r2ts;
+ struct list_head dataqueue; /* Data-Out dataqueue */
+ mempool_t *datapool;
+ uint32_t datadigest; /* for recover digest */
+ int digest_count;
+ uint32_t immdigest; /* for imm data */
+ struct iscsi_buf immbuf; /* for imm data digest */
+ struct iscsi_data_task *dtask; /* data task in progress*/
+ int digest_offset; /* for partial buff digest */
+};
+
+#endif /* ISCSI_H */
diff --git a/drivers/scsi/lasi700.c b/drivers/scsi/lasi700.c
index 4cbb6187cc44..459a4daebece 100644
--- a/drivers/scsi/lasi700.c
+++ b/drivers/scsi/lasi700.c
@@ -98,7 +98,7 @@ MODULE_DEVICE_TABLE(parisc, lasi700_ids);
static int __init
lasi700_probe(struct parisc_device *dev)
{
- unsigned long base = dev->hpa + LASI_SCSI_CORE_OFFSET;
+ unsigned long base = dev->hpa.start + LASI_SCSI_CORE_OFFSET;
struct NCR_700_Host_Parameters *hostdata;
struct Scsi_Host *host;
@@ -125,8 +125,6 @@ lasi700_probe(struct parisc_device *dev)
hostdata->dmode_extra = DMODE_FC2;
}
- NCR_700_set_mem_mapped(hostdata);
-
host = NCR_700_detect(&lasi700_template, hostdata, &dev->dev);
if (!host)
goto out_kfree;
@@ -168,7 +166,7 @@ lasi700_driver_remove(struct parisc_device *dev)
}
static struct parisc_driver lasi700_driver = {
- .name = "Lasi SCSI",
+ .name = "lasi_scsi",
.id_table = lasi700_ids,
.probe = lasi700_probe,
.remove = __devexit_p(lasi700_driver_remove),
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c
index e5b01997117a..a74b4071a662 100644
--- a/drivers/scsi/libata-core.c
+++ b/drivers/scsi/libata-core.c
@@ -48,9 +48,11 @@
#include <linux/completion.h>
#include <linux/suspend.h>
#include <linux/workqueue.h>
+#include <linux/jiffies.h>
+#include <linux/scatterlist.h>
#include <scsi/scsi.h>
-#include "scsi.h"
#include "scsi_priv.h"
+#include <scsi/scsi_cmnd.h>
#include <scsi/scsi_host.h>
#include <linux/libata.h>
#include <asm/io.h>
@@ -62,14 +64,15 @@
static unsigned int ata_busy_sleep (struct ata_port *ap,
unsigned long tmout_pat,
unsigned long tmout);
+static void ata_dev_reread_id(struct ata_port *ap, struct ata_device *dev);
+static void ata_dev_init_params(struct ata_port *ap, struct ata_device *dev);
static void ata_set_mode(struct ata_port *ap);
static void ata_dev_set_xfermode(struct ata_port *ap, struct ata_device *dev);
-static unsigned int ata_get_mode_mask(struct ata_port *ap, int shift);
+static unsigned int ata_get_mode_mask(const struct ata_port *ap, int shift);
static int fgb(u32 bitmap);
-static int ata_choose_xfer_mode(struct ata_port *ap,
+static int ata_choose_xfer_mode(const struct ata_port *ap,
u8 *xfer_mode_out,
unsigned int *xfer_shift_out);
-static int ata_qc_complete_noop(struct ata_queued_cmd *qc, u8 drv_stat);
static void __ata_qc_complete(struct ata_queued_cmd *qc);
static unsigned int ata_unique_id = 1;
@@ -85,7 +88,7 @@ MODULE_LICENSE("GPL");
MODULE_VERSION(DRV_VERSION);
/**
- * ata_tf_load - send taskfile registers to host controller
+ * ata_tf_load_pio - send taskfile registers to host controller
* @ap: Port to which output is sent
* @tf: ATA taskfile register set
*
@@ -95,7 +98,7 @@ MODULE_VERSION(DRV_VERSION);
* Inherited from caller.
*/
-static void ata_tf_load_pio(struct ata_port *ap, struct ata_taskfile *tf)
+static void ata_tf_load_pio(struct ata_port *ap, const struct ata_taskfile *tf)
{
struct ata_ioports *ioaddr = &ap->ioaddr;
unsigned int is_addr = tf->flags & ATA_TFLAG_ISADDR;
@@ -153,7 +156,7 @@ static void ata_tf_load_pio(struct ata_port *ap, struct ata_taskfile *tf)
* Inherited from caller.
*/
-static void ata_tf_load_mmio(struct ata_port *ap, struct ata_taskfile *tf)
+static void ata_tf_load_mmio(struct ata_port *ap, const struct ata_taskfile *tf)
{
struct ata_ioports *ioaddr = &ap->ioaddr;
unsigned int is_addr = tf->flags & ATA_TFLAG_ISADDR;
@@ -222,7 +225,7 @@ static void ata_tf_load_mmio(struct ata_port *ap, struct ata_taskfile *tf)
* LOCKING:
* Inherited from caller.
*/
-void ata_tf_load(struct ata_port *ap, struct ata_taskfile *tf)
+void ata_tf_load(struct ata_port *ap, const struct ata_taskfile *tf)
{
if (ap->flags & ATA_FLAG_MMIO)
ata_tf_load_mmio(ap, tf);
@@ -242,7 +245,7 @@ void ata_tf_load(struct ata_port *ap, struct ata_taskfile *tf)
* spin_lock_irqsave(host_set lock)
*/
-static void ata_exec_command_pio(struct ata_port *ap, struct ata_taskfile *tf)
+static void ata_exec_command_pio(struct ata_port *ap, const struct ata_taskfile *tf)
{
DPRINTK("ata%u: cmd 0x%X\n", ap->id, tf->command);
@@ -263,7 +266,7 @@ static void ata_exec_command_pio(struct ata_port *ap, struct ata_taskfile *tf)
* spin_lock_irqsave(host_set lock)
*/
-static void ata_exec_command_mmio(struct ata_port *ap, struct ata_taskfile *tf)
+static void ata_exec_command_mmio(struct ata_port *ap, const struct ata_taskfile *tf)
{
DPRINTK("ata%u: cmd 0x%X\n", ap->id, tf->command);
@@ -283,7 +286,7 @@ static void ata_exec_command_mmio(struct ata_port *ap, struct ata_taskfile *tf)
* LOCKING:
* spin_lock_irqsave(host_set lock)
*/
-void ata_exec_command(struct ata_port *ap, struct ata_taskfile *tf)
+void ata_exec_command(struct ata_port *ap, const struct ata_taskfile *tf)
{
if (ap->flags & ATA_FLAG_MMIO)
ata_exec_command_mmio(ap, tf);
@@ -292,28 +295,6 @@ void ata_exec_command(struct ata_port *ap, struct ata_taskfile *tf)
}
/**
- * ata_exec - issue ATA command to host controller
- * @ap: port to which command is being issued
- * @tf: ATA taskfile register set
- *
- * Issues PIO/MMIO write to ATA command register, with proper
- * synchronization with interrupt handler / other threads.
- *
- * LOCKING:
- * Obtains host_set lock.
- */
-
-static inline void ata_exec(struct ata_port *ap, struct ata_taskfile *tf)
-{
- unsigned long flags;
-
- DPRINTK("ata%u: cmd 0x%X\n", ap->id, tf->command);
- spin_lock_irqsave(&ap->host_set->lock, flags);
- ap->ops->exec_command(ap, tf);
- spin_unlock_irqrestore(&ap->host_set->lock, flags);
-}
-
-/**
* ata_tf_to_host - issue ATA taskfile to host controller
* @ap: port to which command is being issued
* @tf: ATA taskfile register set
@@ -323,30 +304,11 @@ static inline void ata_exec(struct ata_port *ap, struct ata_taskfile *tf)
* other threads.
*
* LOCKING:
- * Obtains host_set lock.
- */
-
-static void ata_tf_to_host(struct ata_port *ap, struct ata_taskfile *tf)
-{
- ap->ops->tf_load(ap, tf);
-
- ata_exec(ap, tf);
-}
-
-/**
- * ata_tf_to_host_nolock - issue ATA taskfile to host controller
- * @ap: port to which command is being issued
- * @tf: ATA taskfile register set
- *
- * Issues ATA taskfile register set to ATA host controller,
- * with proper synchronization with interrupt handler and
- * other threads.
- *
- * LOCKING:
* spin_lock_irqsave(host_set lock)
*/
-void ata_tf_to_host_nolock(struct ata_port *ap, struct ata_taskfile *tf)
+static inline void ata_tf_to_host(struct ata_port *ap,
+ const struct ata_taskfile *tf)
{
ap->ops->tf_load(ap, tf);
ap->ops->exec_command(ap, tf);
@@ -368,6 +330,8 @@ static void ata_tf_read_pio(struct ata_port *ap, struct ata_taskfile *tf)
{
struct ata_ioports *ioaddr = &ap->ioaddr;
+ tf->command = ata_check_status(ap);
+ tf->feature = inb(ioaddr->error_addr);
tf->nsect = inb(ioaddr->nsect_addr);
tf->lbal = inb(ioaddr->lbal_addr);
tf->lbam = inb(ioaddr->lbam_addr);
@@ -400,6 +364,8 @@ static void ata_tf_read_mmio(struct ata_port *ap, struct ata_taskfile *tf)
{
struct ata_ioports *ioaddr = &ap->ioaddr;
+ tf->command = ata_check_status(ap);
+ tf->feature = readb((void __iomem *)ioaddr->error_addr);
tf->nsect = readb((void __iomem *)ioaddr->nsect_addr);
tf->lbal = readb((void __iomem *)ioaddr->lbal_addr);
tf->lbam = readb((void __iomem *)ioaddr->lbam_addr);
@@ -520,30 +486,6 @@ u8 ata_altstatus(struct ata_port *ap)
/**
- * ata_chk_err - Read device error reg
- * @ap: port where the device is
- *
- * Reads ATA taskfile error register for
- * currently-selected device and return its value.
- *
- * Note: may NOT be used as the check_err() entry in
- * ata_port_operations.
- *
- * LOCKING:
- * Inherited from caller.
- */
-u8 ata_chk_err(struct ata_port *ap)
-{
- if (ap->ops->check_err)
- return ap->ops->check_err(ap);
-
- if (ap->flags & ATA_FLAG_MMIO) {
- return readb((void __iomem *) ap->ioaddr.error_addr);
- }
- return inb(ap->ioaddr.error_addr);
-}
-
-/**
* ata_tf_to_fis - Convert ATA taskfile to SATA FIS structure
* @tf: Taskfile to convert
* @fis: Buffer into which data will output
@@ -556,7 +498,7 @@ u8 ata_chk_err(struct ata_port *ap)
* Inherited from caller.
*/
-void ata_tf_to_fis(struct ata_taskfile *tf, u8 *fis, u8 pmp)
+void ata_tf_to_fis(const struct ata_taskfile *tf, u8 *fis, u8 pmp)
{
fis[0] = 0x27; /* Register - Host to Device FIS */
fis[1] = (pmp & 0xf) | (1 << 7); /* Port multiplier number,
@@ -597,7 +539,7 @@ void ata_tf_to_fis(struct ata_taskfile *tf, u8 *fis, u8 pmp)
* Inherited from caller.
*/
-void ata_tf_from_fis(u8 *fis, struct ata_taskfile *tf)
+void ata_tf_from_fis(const u8 *fis, struct ata_taskfile *tf)
{
tf->command = fis[2]; /* status */
tf->feature = fis[3]; /* error */
@@ -615,79 +557,53 @@ void ata_tf_from_fis(u8 *fis, struct ata_taskfile *tf)
tf->hob_nsect = fis[13];
}
-/**
- * ata_prot_to_cmd - determine which read/write opcodes to use
- * @protocol: ATA_PROT_xxx taskfile protocol
- * @lba48: true is lba48 is present
- *
- * Given necessary input, determine which read/write commands
- * to use to transfer data.
- *
- * LOCKING:
- * None.
- */
-static int ata_prot_to_cmd(int protocol, int lba48)
-{
- int rcmd = 0, wcmd = 0;
-
- switch (protocol) {
- case ATA_PROT_PIO:
- if (lba48) {
- rcmd = ATA_CMD_PIO_READ_EXT;
- wcmd = ATA_CMD_PIO_WRITE_EXT;
- } else {
- rcmd = ATA_CMD_PIO_READ;
- wcmd = ATA_CMD_PIO_WRITE;
- }
- break;
-
- case ATA_PROT_DMA:
- if (lba48) {
- rcmd = ATA_CMD_READ_EXT;
- wcmd = ATA_CMD_WRITE_EXT;
- } else {
- rcmd = ATA_CMD_READ;
- wcmd = ATA_CMD_WRITE;
- }
- break;
-
- default:
- return -1;
- }
-
- return rcmd | (wcmd << 8);
-}
+static const u8 ata_rw_cmds[] = {
+ /* pio multi */
+ ATA_CMD_READ_MULTI,
+ ATA_CMD_WRITE_MULTI,
+ ATA_CMD_READ_MULTI_EXT,
+ ATA_CMD_WRITE_MULTI_EXT,
+ /* pio */
+ ATA_CMD_PIO_READ,
+ ATA_CMD_PIO_WRITE,
+ ATA_CMD_PIO_READ_EXT,
+ ATA_CMD_PIO_WRITE_EXT,
+ /* dma */
+ ATA_CMD_READ,
+ ATA_CMD_WRITE,
+ ATA_CMD_READ_EXT,
+ ATA_CMD_WRITE_EXT
+};
/**
- * ata_dev_set_protocol - set taskfile protocol and r/w commands
- * @dev: device to examine and configure
+ * ata_rwcmd_protocol - set taskfile r/w commands and protocol
+ * @qc: command to examine and configure
*
- * Examine the device configuration, after we have
- * read the identify-device page and configured the
- * data transfer mode. Set internal state related to
- * the ATA taskfile protocol (pio, pio mult, dma, etc.)
- * and calculate the proper read/write commands to use.
+ * Examine the device configuration and tf->flags to calculate
+ * the proper read/write commands and protocol to use.
*
* LOCKING:
* caller.
*/
-static void ata_dev_set_protocol(struct ata_device *dev)
+void ata_rwcmd_protocol(struct ata_queued_cmd *qc)
{
- int pio = (dev->flags & ATA_DFLAG_PIO);
- int lba48 = (dev->flags & ATA_DFLAG_LBA48);
- int proto, cmd;
+ struct ata_taskfile *tf = &qc->tf;
+ struct ata_device *dev = qc->dev;
- if (pio)
- proto = dev->xfer_protocol = ATA_PROT_PIO;
- else
- proto = dev->xfer_protocol = ATA_PROT_DMA;
+ int index, lba48, write;
+
+ lba48 = (tf->flags & ATA_TFLAG_LBA48) ? 2 : 0;
+ write = (tf->flags & ATA_TFLAG_WRITE) ? 1 : 0;
- cmd = ata_prot_to_cmd(proto, lba48);
- if (cmd < 0)
- BUG();
+ if (dev->flags & ATA_DFLAG_PIO) {
+ tf->protocol = ATA_PROT_PIO;
+ index = dev->multi_count ? 0 : 4;
+ } else {
+ tf->protocol = ATA_PROT_DMA;
+ index = 8;
+ }
- dev->read_cmd = cmd & 0xff;
- dev->write_cmd = (cmd >> 8) & 0xff;
+ tf->command = ata_rw_cmds[index + lba48 + write];
}
static const char * xfer_mode_str[] = {
@@ -869,7 +785,7 @@ static unsigned int ata_devchk(struct ata_port *ap,
* the event of failure.
*/
-unsigned int ata_dev_classify(struct ata_taskfile *tf)
+unsigned int ata_dev_classify(const struct ata_taskfile *tf)
{
/* Apple's open source Darwin code hints that some devices only
* put a proper signature into the LBA mid/high registers,
@@ -921,8 +837,8 @@ static u8 ata_dev_try_classify(struct ata_port *ap, unsigned int device)
memset(&tf, 0, sizeof(tf));
- err = ata_chk_err(ap);
ap->ops->tf_read(ap, &tf);
+ err = tf.feature;
dev->class = ATA_DEV_NONE;
@@ -961,7 +877,7 @@ static u8 ata_dev_try_classify(struct ata_port *ap, unsigned int device)
* caller.
*/
-void ata_dev_id_string(u16 *id, unsigned char *s,
+void ata_dev_id_string(const u16 *id, unsigned char *s,
unsigned int ofs, unsigned int len)
{
unsigned int c;
@@ -1078,7 +994,7 @@ void ata_dev_select(struct ata_port *ap, unsigned int device,
* caller.
*/
-static inline void ata_dump_id(struct ata_device *dev)
+static inline void ata_dump_id(const struct ata_device *dev)
{
DPRINTK("49==0x%04x "
"53==0x%04x "
@@ -1106,6 +1022,31 @@ static inline void ata_dump_id(struct ata_device *dev)
dev->id[93]);
}
+/*
+ * Compute the PIO modes available for this device. This is not as
+ * trivial as it seems if we must consider early devices correctly.
+ *
+ * FIXME: pre IDE drive timing (do we care ?).
+ */
+
+static unsigned int ata_pio_modes(const struct ata_device *adev)
+{
+ u16 modes;
+
+ /* Usual case. Word 53 indicates word 88 is valid */
+ if (adev->id[ATA_ID_FIELD_VALID] & (1 << 2)) {
+ modes = adev->id[ATA_ID_PIO_MODES] & 0x03;
+ modes <<= 3;
+ modes |= 0x7;
+ return modes;
+ }
+
+ /* If word 88 isn't valid then Word 51 holds the PIO timing number
+ for the maximum. Turn it into a mask and return it */
+ modes = (2 << (adev->id[ATA_ID_OLD_PIO_MODES] & 0xFF)) - 1 ;
+ return modes;
+}
+
/**
* ata_dev_identify - obtain IDENTIFY x DEVICE page
* @ap: port on which device we wish to probe resides
@@ -1131,10 +1072,9 @@ static inline void ata_dump_id(struct ata_device *dev)
static void ata_dev_identify(struct ata_port *ap, unsigned int device)
{
struct ata_device *dev = &ap->device[device];
- unsigned int i;
+ unsigned int major_version;
u16 tmp;
unsigned long xfer_modes;
- u8 status;
unsigned int using_edd;
DECLARE_COMPLETION(wait);
struct ata_queued_cmd *qc;
@@ -1188,8 +1128,11 @@ retry:
else
wait_for_completion(&wait);
- status = ata_chk_status(ap);
- if (status & ATA_ERR) {
+ spin_lock_irqsave(&ap->host_set->lock, flags);
+ ap->ops->tf_read(ap, &qc->tf);
+ spin_unlock_irqrestore(&ap->host_set->lock, flags);
+
+ if (qc->tf.command & ATA_ERR) {
/*
* arg! EDD works for all test cases, but seems to return
* the ATA signature for some ATAPI devices. Until the
@@ -1201,8 +1144,8 @@ retry:
* ATA software reset (SRST, the default) does not appear
* to have this problem.
*/
- if ((using_edd) && (qc->tf.command == ATA_CMD_ID_ATA)) {
- u8 err = ata_chk_err(ap);
+ if ((using_edd) && (dev->class == ATA_DEV_ATA)) {
+ u8 err = qc->tf.feature;
if (err & ATA_ABORTED) {
dev->class = ATA_DEV_ATAPI;
qc->cursg = 0;
@@ -1229,9 +1172,9 @@ retry:
* common ATA, ATAPI feature tests
*/
- /* we require LBA and DMA support (bits 8 & 9 of word 49) */
- if (!ata_id_has_dma(dev->id) || !ata_id_has_lba(dev->id)) {
- printk(KERN_DEBUG "ata%u: no dma/lba\n", ap->id);
+ /* we require DMA support (bits 8 of word 49) */
+ if (!ata_id_has_dma(dev->id)) {
+ printk(KERN_DEBUG "ata%u: no dma\n", ap->id);
goto err_out_nosup;
}
@@ -1239,10 +1182,8 @@ retry:
xfer_modes = dev->id[ATA_ID_UDMA_MODES];
if (!xfer_modes)
xfer_modes = (dev->id[ATA_ID_MWDMA_MODES]) << ATA_SHIFT_MWDMA;
- if (!xfer_modes) {
- xfer_modes = (dev->id[ATA_ID_PIO_MODES]) << (ATA_SHIFT_PIO + 3);
- xfer_modes |= (0x7 << ATA_SHIFT_PIO);
- }
+ if (!xfer_modes)
+ xfer_modes = ata_pio_modes(dev);
ata_dump_id(dev);
@@ -1251,32 +1192,75 @@ retry:
if (!ata_id_is_ata(dev->id)) /* sanity check */
goto err_out_nosup;
+ /* get major version */
tmp = dev->id[ATA_ID_MAJOR_VER];
- for (i = 14; i >= 1; i--)
- if (tmp & (1 << i))
+ for (major_version = 14; major_version >= 1; major_version--)
+ if (tmp & (1 << major_version))
break;
- /* we require at least ATA-3 */
- if (i < 3) {
- printk(KERN_DEBUG "ata%u: no ATA-3\n", ap->id);
- goto err_out_nosup;
+ /*
+ * The exact sequence expected by certain pre-ATA4 drives is:
+ * SRST RESET
+ * IDENTIFY
+ * INITIALIZE DEVICE PARAMETERS
+ * anything else..
+ * Some drives were very specific about that exact sequence.
+ */
+ if (major_version < 4 || (!ata_id_has_lba(dev->id))) {
+ ata_dev_init_params(ap, dev);
+
+ /* current CHS translation info (id[53-58]) might be
+ * changed. reread the identify device info.
+ */
+ ata_dev_reread_id(ap, dev);
}
- if (ata_id_has_lba48(dev->id)) {
- dev->flags |= ATA_DFLAG_LBA48;
- dev->n_sectors = ata_id_u64(dev->id, 100);
- } else {
- dev->n_sectors = ata_id_u32(dev->id, 60);
+ if (ata_id_has_lba(dev->id)) {
+ dev->flags |= ATA_DFLAG_LBA;
+
+ if (ata_id_has_lba48(dev->id)) {
+ dev->flags |= ATA_DFLAG_LBA48;
+ dev->n_sectors = ata_id_u64(dev->id, 100);
+ } else {
+ dev->n_sectors = ata_id_u32(dev->id, 60);
+ }
+
+ /* print device info to dmesg */
+ printk(KERN_INFO "ata%u: dev %u ATA-%d, max %s, %Lu sectors:%s\n",
+ ap->id, device,
+ major_version,
+ ata_mode_string(xfer_modes),
+ (unsigned long long)dev->n_sectors,
+ dev->flags & ATA_DFLAG_LBA48 ? " LBA48" : " LBA");
+ } else {
+ /* CHS */
+
+ /* Default translation */
+ dev->cylinders = dev->id[1];
+ dev->heads = dev->id[3];
+ dev->sectors = dev->id[6];
+ dev->n_sectors = dev->cylinders * dev->heads * dev->sectors;
+
+ if (ata_id_current_chs_valid(dev->id)) {
+ /* Current CHS translation is valid. */
+ dev->cylinders = dev->id[54];
+ dev->heads = dev->id[55];
+ dev->sectors = dev->id[56];
+
+ dev->n_sectors = ata_id_u32(dev->id, 57);
+ }
+
+ /* print device info to dmesg */
+ printk(KERN_INFO "ata%u: dev %u ATA-%d, max %s, %Lu sectors: CHS %d/%d/%d\n",
+ ap->id, device,
+ major_version,
+ ata_mode_string(xfer_modes),
+ (unsigned long long)dev->n_sectors,
+ (int)dev->cylinders, (int)dev->heads, (int)dev->sectors);
+
}
ap->host->max_cmd_len = 16;
-
- /* print device info to dmesg */
- printk(KERN_INFO "ata%u: dev %u ATA, max %s, %Lu sectors:%s\n",
- ap->id, device,
- ata_mode_string(xfer_modes),
- (unsigned long long)dev->n_sectors,
- dev->flags & ATA_DFLAG_LBA48 ? " lba48" : "");
}
/* ATAPI-specific feature tests */
@@ -1310,7 +1294,7 @@ err_out:
}
-static inline u8 ata_dev_knobble(struct ata_port *ap)
+static inline u8 ata_dev_knobble(const struct ata_port *ap)
{
return ((ap->cbl == ATA_CBL_SATA) && (!ata_id_is_sata(ap->device->id)));
}
@@ -1496,7 +1480,153 @@ void ata_port_disable(struct ata_port *ap)
ap->flags |= ATA_FLAG_PORT_DISABLED;
}
-static struct {
+/*
+ * This mode timing computation functionality is ported over from
+ * drivers/ide/ide-timing.h and was originally written by Vojtech Pavlik
+ */
+/*
+ * PIO 0-5, MWDMA 0-2 and UDMA 0-6 timings (in nanoseconds).
+ * These were taken from ATA/ATAPI-6 standard, rev 0a, except
+ * for PIO 5, which is a nonstandard extension and UDMA6, which
+ * is currently supported only by Maxtor drives.
+ */
+
+static const struct ata_timing ata_timing[] = {
+
+ { XFER_UDMA_6, 0, 0, 0, 0, 0, 0, 0, 15 },
+ { XFER_UDMA_5, 0, 0, 0, 0, 0, 0, 0, 20 },
+ { XFER_UDMA_4, 0, 0, 0, 0, 0, 0, 0, 30 },
+ { XFER_UDMA_3, 0, 0, 0, 0, 0, 0, 0, 45 },
+
+ { XFER_UDMA_2, 0, 0, 0, 0, 0, 0, 0, 60 },
+ { XFER_UDMA_1, 0, 0, 0, 0, 0, 0, 0, 80 },
+ { XFER_UDMA_0, 0, 0, 0, 0, 0, 0, 0, 120 },
+
+/* { XFER_UDMA_SLOW, 0, 0, 0, 0, 0, 0, 0, 150 }, */
+
+ { XFER_MW_DMA_2, 25, 0, 0, 0, 70, 25, 120, 0 },
+ { XFER_MW_DMA_1, 45, 0, 0, 0, 80, 50, 150, 0 },
+ { XFER_MW_DMA_0, 60, 0, 0, 0, 215, 215, 480, 0 },
+
+ { XFER_SW_DMA_2, 60, 0, 0, 0, 120, 120, 240, 0 },
+ { XFER_SW_DMA_1, 90, 0, 0, 0, 240, 240, 480, 0 },
+ { XFER_SW_DMA_0, 120, 0, 0, 0, 480, 480, 960, 0 },
+
+/* { XFER_PIO_5, 20, 50, 30, 100, 50, 30, 100, 0 }, */
+ { XFER_PIO_4, 25, 70, 25, 120, 70, 25, 120, 0 },
+ { XFER_PIO_3, 30, 80, 70, 180, 80, 70, 180, 0 },
+
+ { XFER_PIO_2, 30, 290, 40, 330, 100, 90, 240, 0 },
+ { XFER_PIO_1, 50, 290, 93, 383, 125, 100, 383, 0 },
+ { XFER_PIO_0, 70, 290, 240, 600, 165, 150, 600, 0 },
+
+/* { XFER_PIO_SLOW, 120, 290, 240, 960, 290, 240, 960, 0 }, */
+
+ { 0xFF }
+};
+
+#define ENOUGH(v,unit) (((v)-1)/(unit)+1)
+#define EZ(v,unit) ((v)?ENOUGH(v,unit):0)
+
+static void ata_timing_quantize(const struct ata_timing *t, struct ata_timing *q, int T, int UT)
+{
+ q->setup = EZ(t->setup * 1000, T);
+ q->act8b = EZ(t->act8b * 1000, T);
+ q->rec8b = EZ(t->rec8b * 1000, T);
+ q->cyc8b = EZ(t->cyc8b * 1000, T);
+ q->active = EZ(t->active * 1000, T);
+ q->recover = EZ(t->recover * 1000, T);
+ q->cycle = EZ(t->cycle * 1000, T);
+ q->udma = EZ(t->udma * 1000, UT);
+}
+
+void ata_timing_merge(const struct ata_timing *a, const struct ata_timing *b,
+ struct ata_timing *m, unsigned int what)
+{
+ if (what & ATA_TIMING_SETUP ) m->setup = max(a->setup, b->setup);
+ if (what & ATA_TIMING_ACT8B ) m->act8b = max(a->act8b, b->act8b);
+ if (what & ATA_TIMING_REC8B ) m->rec8b = max(a->rec8b, b->rec8b);
+ if (what & ATA_TIMING_CYC8B ) m->cyc8b = max(a->cyc8b, b->cyc8b);
+ if (what & ATA_TIMING_ACTIVE ) m->active = max(a->active, b->active);
+ if (what & ATA_TIMING_RECOVER) m->recover = max(a->recover, b->recover);
+ if (what & ATA_TIMING_CYCLE ) m->cycle = max(a->cycle, b->cycle);
+ if (what & ATA_TIMING_UDMA ) m->udma = max(a->udma, b->udma);
+}
+
+static const struct ata_timing* ata_timing_find_mode(unsigned short speed)
+{
+ const struct ata_timing *t;
+
+ for (t = ata_timing; t->mode != speed; t++)
+ if (t->mode == 0xFF)
+ return NULL;
+ return t;
+}
+
+int ata_timing_compute(struct ata_device *adev, unsigned short speed,
+ struct ata_timing *t, int T, int UT)
+{
+ const struct ata_timing *s;
+ struct ata_timing p;
+
+ /*
+ * Find the mode.
+ */
+
+ if (!(s = ata_timing_find_mode(speed)))
+ return -EINVAL;
+
+ /*
+ * If the drive is an EIDE drive, it can tell us it needs extended
+ * PIO/MW_DMA cycle timing.
+ */
+
+ if (adev->id[ATA_ID_FIELD_VALID] & 2) { /* EIDE drive */
+ memset(&p, 0, sizeof(p));
+ if(speed >= XFER_PIO_0 && speed <= XFER_SW_DMA_0) {
+ if (speed <= XFER_PIO_2) p.cycle = p.cyc8b = adev->id[ATA_ID_EIDE_PIO];
+ else p.cycle = p.cyc8b = adev->id[ATA_ID_EIDE_PIO_IORDY];
+ } else if(speed >= XFER_MW_DMA_0 && speed <= XFER_MW_DMA_2) {
+ p.cycle = adev->id[ATA_ID_EIDE_DMA_MIN];
+ }
+ ata_timing_merge(&p, t, t, ATA_TIMING_CYCLE | ATA_TIMING_CYC8B);
+ }
+
+ /*
+ * Convert the timing to bus clock counts.
+ */
+
+ ata_timing_quantize(s, t, T, UT);
+
+ /*
+ * Even in DMA/UDMA modes we still use PIO access for IDENTIFY, S.M.A.R.T
+ * and some other commands. We have to ensure that the DMA cycle timing is
+ * slower/equal than the fastest PIO timing.
+ */
+
+ if (speed > XFER_PIO_4) {
+ ata_timing_compute(adev, adev->pio_mode, &p, T, UT);
+ ata_timing_merge(&p, t, t, ATA_TIMING_ALL);
+ }
+
+ /*
+ * Lenghten active & recovery time so that cycle time is correct.
+ */
+
+ if (t->act8b + t->rec8b < t->cyc8b) {
+ t->act8b += (t->cyc8b - (t->act8b + t->rec8b)) / 2;
+ t->rec8b = t->cyc8b - t->act8b;
+ }
+
+ if (t->active + t->recover < t->cycle) {
+ t->active += (t->cycle - (t->active + t->recover)) / 2;
+ t->recover = t->cycle - t->active;
+ }
+
+ return 0;
+}
+
+static const struct {
unsigned int shift;
u8 base;
} xfer_mode_classes[] = {
@@ -1603,7 +1733,7 @@ static void ata_host_set_dma(struct ata_port *ap, u8 xfer_mode,
*/
static void ata_set_mode(struct ata_port *ap)
{
- unsigned int i, xfer_shift;
+ unsigned int xfer_shift;
u8 xfer_mode;
int rc;
@@ -1632,11 +1762,6 @@ static void ata_set_mode(struct ata_port *ap)
if (ap->ops->post_set_mode)
ap->ops->post_set_mode(ap);
- for (i = 0; i < 2; i++) {
- struct ata_device *dev = &ap->device[i];
- ata_dev_set_protocol(dev);
- }
-
return;
err_out:
@@ -1746,12 +1871,14 @@ static void ata_bus_post_reset(struct ata_port *ap, unsigned int devmask)
*
* LOCKING:
* PCI/etc. bus probe sem.
+ * Obtains host_set lock.
*
*/
static unsigned int ata_bus_edd(struct ata_port *ap)
{
struct ata_taskfile tf;
+ unsigned long flags;
/* set up execute-device-diag (bus reset) taskfile */
/* also, take interrupts to a known state (disabled) */
@@ -1762,7 +1889,9 @@ static unsigned int ata_bus_edd(struct ata_port *ap)
tf.protocol = ATA_PROT_NODATA;
/* do bus reset */
+ spin_lock_irqsave(&ap->host_set->lock, flags);
ata_tf_to_host(ap, &tf);
+ spin_unlock_irqrestore(&ap->host_set->lock, flags);
/* spec says at least 2ms. but who knows with those
* crazy ATAPI devices...
@@ -1910,7 +2039,8 @@ err_out:
DPRINTK("EXIT\n");
}
-static void ata_pr_blacklisted(struct ata_port *ap, struct ata_device *dev)
+static void ata_pr_blacklisted(const struct ata_port *ap,
+ const struct ata_device *dev)
{
printk(KERN_WARNING "ata%u: dev %u is on DMA blacklist, disabling DMA\n",
ap->id, dev->devno);
@@ -1948,7 +2078,7 @@ static const char * ata_dma_blacklist [] = {
"_NEC DV5800A",
};
-static int ata_dma_blacklisted(struct ata_port *ap, struct ata_device *dev)
+static int ata_dma_blacklisted(const struct ata_device *dev)
{
unsigned char model_num[40];
char *s;
@@ -1973,9 +2103,9 @@ static int ata_dma_blacklisted(struct ata_port *ap, struct ata_device *dev)
return 0;
}
-static unsigned int ata_get_mode_mask(struct ata_port *ap, int shift)
+static unsigned int ata_get_mode_mask(const struct ata_port *ap, int shift)
{
- struct ata_device *master, *slave;
+ const struct ata_device *master, *slave;
unsigned int mask;
master = &ap->device[0];
@@ -1987,14 +2117,14 @@ static unsigned int ata_get_mode_mask(struct ata_port *ap, int shift)
mask = ap->udma_mask;
if (ata_dev_present(master)) {
mask &= (master->id[ATA_ID_UDMA_MODES] & 0xff);
- if (ata_dma_blacklisted(ap, master)) {
+ if (ata_dma_blacklisted(master)) {
mask = 0;
ata_pr_blacklisted(ap, master);
}
}
if (ata_dev_present(slave)) {
mask &= (slave->id[ATA_ID_UDMA_MODES] & 0xff);
- if (ata_dma_blacklisted(ap, slave)) {
+ if (ata_dma_blacklisted(slave)) {
mask = 0;
ata_pr_blacklisted(ap, slave);
}
@@ -2004,14 +2134,14 @@ static unsigned int ata_get_mode_mask(struct ata_port *ap, int shift)
mask = ap->mwdma_mask;
if (ata_dev_present(master)) {
mask &= (master->id[ATA_ID_MWDMA_MODES] & 0x07);
- if (ata_dma_blacklisted(ap, master)) {
+ if (ata_dma_blacklisted(master)) {
mask = 0;
ata_pr_blacklisted(ap, master);
}
}
if (ata_dev_present(slave)) {
mask &= (slave->id[ATA_ID_MWDMA_MODES] & 0x07);
- if (ata_dma_blacklisted(ap, slave)) {
+ if (ata_dma_blacklisted(slave)) {
mask = 0;
ata_pr_blacklisted(ap, slave);
}
@@ -2075,7 +2205,7 @@ static int fgb(u32 bitmap)
* Zero on success, negative on error.
*/
-static int ata_choose_xfer_mode(struct ata_port *ap,
+static int ata_choose_xfer_mode(const struct ata_port *ap,
u8 *xfer_mode_out,
unsigned int *xfer_shift_out)
{
@@ -2144,6 +2274,110 @@ static void ata_dev_set_xfermode(struct ata_port *ap, struct ata_device *dev)
}
/**
+ * ata_dev_reread_id - Reread the device identify device info
+ * @ap: port where the device is
+ * @dev: device to reread the identify device info
+ *
+ * LOCKING:
+ */
+
+static void ata_dev_reread_id(struct ata_port *ap, struct ata_device *dev)
+{
+ DECLARE_COMPLETION(wait);
+ struct ata_queued_cmd *qc;
+ unsigned long flags;
+ int rc;
+
+ qc = ata_qc_new_init(ap, dev);
+ BUG_ON(qc == NULL);
+
+ ata_sg_init_one(qc, dev->id, sizeof(dev->id));
+ qc->dma_dir = DMA_FROM_DEVICE;
+
+ if (dev->class == ATA_DEV_ATA) {
+ qc->tf.command = ATA_CMD_ID_ATA;
+ DPRINTK("do ATA identify\n");
+ } else {
+ qc->tf.command = ATA_CMD_ID_ATAPI;
+ DPRINTK("do ATAPI identify\n");
+ }
+
+ qc->tf.flags |= ATA_TFLAG_DEVICE;
+ qc->tf.protocol = ATA_PROT_PIO;
+ qc->nsect = 1;
+
+ qc->waiting = &wait;
+ qc->complete_fn = ata_qc_complete_noop;
+
+ spin_lock_irqsave(&ap->host_set->lock, flags);
+ rc = ata_qc_issue(qc);
+ spin_unlock_irqrestore(&ap->host_set->lock, flags);
+
+ if (rc)
+ goto err_out;
+
+ wait_for_completion(&wait);
+
+ swap_buf_le16(dev->id, ATA_ID_WORDS);
+
+ ata_dump_id(dev);
+
+ DPRINTK("EXIT\n");
+
+ return;
+err_out:
+ ata_port_disable(ap);
+}
+
+/**
+ * ata_dev_init_params - Issue INIT DEV PARAMS command
+ * @ap: Port associated with device @dev
+ * @dev: Device to which command will be sent
+ *
+ * LOCKING:
+ */
+
+static void ata_dev_init_params(struct ata_port *ap, struct ata_device *dev)
+{
+ DECLARE_COMPLETION(wait);
+ struct ata_queued_cmd *qc;
+ int rc;
+ unsigned long flags;
+ u16 sectors = dev->id[6];
+ u16 heads = dev->id[3];
+
+ /* Number of sectors per track 1-255. Number of heads 1-16 */
+ if (sectors < 1 || sectors > 255 || heads < 1 || heads > 16)
+ return;
+
+ /* set up init dev params taskfile */
+ DPRINTK("init dev params \n");
+
+ qc = ata_qc_new_init(ap, dev);
+ BUG_ON(qc == NULL);
+
+ qc->tf.command = ATA_CMD_INIT_DEV_PARAMS;
+ qc->tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
+ qc->tf.protocol = ATA_PROT_NODATA;
+ qc->tf.nsect = sectors;
+ qc->tf.device |= (heads - 1) & 0x0f; /* max head = num. of heads - 1 */
+
+ qc->waiting = &wait;
+ qc->complete_fn = ata_qc_complete_noop;
+
+ spin_lock_irqsave(&ap->host_set->lock, flags);
+ rc = ata_qc_issue(qc);
+ spin_unlock_irqrestore(&ap->host_set->lock, flags);
+
+ if (rc)
+ ata_port_disable(ap);
+ else
+ wait_for_completion(&wait);
+
+ DPRINTK("EXIT\n");
+}
+
+/**
* ata_sg_clean - Unmap DMA memory associated with command
* @qc: Command containing DMA memory to be released
*
@@ -2156,8 +2390,9 @@ static void ata_dev_set_xfermode(struct ata_port *ap, struct ata_device *dev)
static void ata_sg_clean(struct ata_queued_cmd *qc)
{
struct ata_port *ap = qc->ap;
- struct scatterlist *sg = qc->sg;
+ struct scatterlist *sg = qc->__sg;
int dir = qc->dma_dir;
+ void *pad_buf = NULL;
assert(qc->flags & ATA_QCFLAG_DMAMAP);
assert(sg != NULL);
@@ -2167,14 +2402,35 @@ static void ata_sg_clean(struct ata_queued_cmd *qc)
DPRINTK("unmapping %u sg elements\n", qc->n_elem);
- if (qc->flags & ATA_QCFLAG_SG)
+ /* if we padded the buffer out to 32-bit bound, and data
+ * xfer direction is from-device, we must copy from the
+ * pad buffer back into the supplied buffer
+ */
+ if (qc->pad_len && !(qc->tf.flags & ATA_TFLAG_WRITE))
+ pad_buf = ap->pad + (qc->tag * ATA_DMA_PAD_SZ);
+
+ if (qc->flags & ATA_QCFLAG_SG) {
dma_unmap_sg(ap->host_set->dev, sg, qc->n_elem, dir);
- else
+ /* restore last sg */
+ sg[qc->orig_n_elem - 1].length += qc->pad_len;
+ if (pad_buf) {
+ struct scatterlist *psg = &qc->pad_sgent;
+ void *addr = kmap_atomic(psg->page, KM_IRQ0);
+ memcpy(addr + psg->offset, pad_buf, qc->pad_len);
+ kunmap_atomic(psg->page, KM_IRQ0);
+ }
+ } else {
dma_unmap_single(ap->host_set->dev, sg_dma_address(&sg[0]),
sg_dma_len(&sg[0]), dir);
+ /* restore sg */
+ sg->length += qc->pad_len;
+ if (pad_buf)
+ memcpy(qc->buf_virt + sg->length - qc->pad_len,
+ pad_buf, qc->pad_len);
+ }
qc->flags &= ~ATA_QCFLAG_DMAMAP;
- qc->sg = NULL;
+ qc->__sg = NULL;
}
/**
@@ -2190,15 +2446,15 @@ static void ata_sg_clean(struct ata_queued_cmd *qc)
*/
static void ata_fill_sg(struct ata_queued_cmd *qc)
{
- struct scatterlist *sg = qc->sg;
struct ata_port *ap = qc->ap;
- unsigned int idx, nelem;
+ struct scatterlist *sg;
+ unsigned int idx;
- assert(sg != NULL);
+ assert(qc->__sg != NULL);
assert(qc->n_elem > 0);
idx = 0;
- for (nelem = qc->n_elem; nelem; nelem--,sg++) {
+ ata_for_each_sg(sg, qc) {
u32 addr, offset;
u32 sg_len, len;
@@ -2289,14 +2545,13 @@ void ata_sg_init_one(struct ata_queued_cmd *qc, void *buf, unsigned int buflen)
qc->flags |= ATA_QCFLAG_SINGLE;
memset(&qc->sgent, 0, sizeof(qc->sgent));
- qc->sg = &qc->sgent;
+ qc->__sg = &qc->sgent;
qc->n_elem = 1;
+ qc->orig_n_elem = 1;
qc->buf_virt = buf;
- sg = qc->sg;
- sg->page = virt_to_page(buf);
- sg->offset = (unsigned long) buf & ~PAGE_MASK;
- sg->length = buflen;
+ sg = qc->__sg;
+ sg_init_one(sg, buf, buflen);
}
/**
@@ -2317,8 +2572,9 @@ void ata_sg_init(struct ata_queued_cmd *qc, struct scatterlist *sg,
unsigned int n_elem)
{
qc->flags |= ATA_QCFLAG_SG;
- qc->sg = sg;
+ qc->__sg = sg;
qc->n_elem = n_elem;
+ qc->orig_n_elem = n_elem;
}
/**
@@ -2338,13 +2594,39 @@ static int ata_sg_setup_one(struct ata_queued_cmd *qc)
{
struct ata_port *ap = qc->ap;
int dir = qc->dma_dir;
- struct scatterlist *sg = qc->sg;
+ struct scatterlist *sg = qc->__sg;
dma_addr_t dma_address;
+ /* we must lengthen transfers to end on a 32-bit boundary */
+ qc->pad_len = sg->length & 3;
+ if (qc->pad_len) {
+ void *pad_buf = ap->pad + (qc->tag * ATA_DMA_PAD_SZ);
+ struct scatterlist *psg = &qc->pad_sgent;
+
+ assert(qc->dev->class == ATA_DEV_ATAPI);
+
+ memset(pad_buf, 0, ATA_DMA_PAD_SZ);
+
+ if (qc->tf.flags & ATA_TFLAG_WRITE)
+ memcpy(pad_buf, qc->buf_virt + sg->length - qc->pad_len,
+ qc->pad_len);
+
+ sg_dma_address(psg) = ap->pad_dma + (qc->tag * ATA_DMA_PAD_SZ);
+ sg_dma_len(psg) = ATA_DMA_PAD_SZ;
+ /* trim sg */
+ sg->length -= qc->pad_len;
+
+ DPRINTK("padding done, sg->length=%u pad_len=%u\n",
+ sg->length, qc->pad_len);
+ }
+
dma_address = dma_map_single(ap->host_set->dev, qc->buf_virt,
sg->length, dir);
- if (dma_mapping_error(dma_address))
+ if (dma_mapping_error(dma_address)) {
+ /* restore sg */
+ sg->length += qc->pad_len;
return -1;
+ }
sg_dma_address(sg) = dma_address;
sg_dma_len(sg) = sg->length;
@@ -2372,16 +2654,54 @@ static int ata_sg_setup_one(struct ata_queued_cmd *qc)
static int ata_sg_setup(struct ata_queued_cmd *qc)
{
struct ata_port *ap = qc->ap;
- struct scatterlist *sg = qc->sg;
+ struct scatterlist *sg = qc->__sg;
+ struct scatterlist *lsg = &sg[qc->n_elem - 1];
int n_elem, dir;
VPRINTK("ENTER, ata%u\n", ap->id);
assert(qc->flags & ATA_QCFLAG_SG);
+ /* we must lengthen transfers to end on a 32-bit boundary */
+ qc->pad_len = lsg->length & 3;
+ if (qc->pad_len) {
+ void *pad_buf = ap->pad + (qc->tag * ATA_DMA_PAD_SZ);
+ struct scatterlist *psg = &qc->pad_sgent;
+ unsigned int offset;
+
+ assert(qc->dev->class == ATA_DEV_ATAPI);
+
+ memset(pad_buf, 0, ATA_DMA_PAD_SZ);
+
+ /*
+ * psg->page/offset are used to copy to-be-written
+ * data in this function or read data in ata_sg_clean.
+ */
+ offset = lsg->offset + lsg->length - qc->pad_len;
+ psg->page = nth_page(lsg->page, offset >> PAGE_SHIFT);
+ psg->offset = offset_in_page(offset);
+
+ if (qc->tf.flags & ATA_TFLAG_WRITE) {
+ void *addr = kmap_atomic(psg->page, KM_IRQ0);
+ memcpy(pad_buf, addr + psg->offset, qc->pad_len);
+ kunmap_atomic(psg->page, KM_IRQ0);
+ }
+
+ sg_dma_address(psg) = ap->pad_dma + (qc->tag * ATA_DMA_PAD_SZ);
+ sg_dma_len(psg) = ATA_DMA_PAD_SZ;
+ /* trim last sg */
+ lsg->length -= qc->pad_len;
+
+ DPRINTK("padding done, sg[%d].length=%u pad_len=%u\n",
+ qc->n_elem - 1, lsg->length, qc->pad_len);
+ }
+
dir = qc->dma_dir;
n_elem = dma_map_sg(ap->host_set->dev, sg, qc->n_elem, dir);
- if (n_elem < 1)
+ if (n_elem < 1) {
+ /* restore last sg */
+ lsg->length += qc->pad_len;
return -1;
+ }
DPRINTK("%d sg elements mapped\n", n_elem);
@@ -2393,13 +2713,13 @@ static int ata_sg_setup(struct ata_queued_cmd *qc)
/**
* ata_poll_qc_complete - turn irq back on and finish qc
* @qc: Command to complete
- * @drv_stat: ATA status register content
+ * @err_mask: ATA status register content
*
* LOCKING:
* None. (grabs host lock)
*/
-void ata_poll_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat)
+void ata_poll_qc_complete(struct ata_queued_cmd *qc, unsigned int err_mask)
{
struct ata_port *ap = qc->ap;
unsigned long flags;
@@ -2407,38 +2727,37 @@ void ata_poll_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat)
spin_lock_irqsave(&ap->host_set->lock, flags);
ap->flags &= ~ATA_FLAG_NOINTR;
ata_irq_on(ap);
- ata_qc_complete(qc, drv_stat);
+ ata_qc_complete(qc, err_mask);
spin_unlock_irqrestore(&ap->host_set->lock, flags);
}
/**
* ata_pio_poll -
- * @ap:
+ * @ap: the target ata_port
*
* LOCKING:
* None. (executing in kernel thread context)
*
* RETURNS:
- *
+ * timeout value to use
*/
static unsigned long ata_pio_poll(struct ata_port *ap)
{
u8 status;
- unsigned int poll_state = PIO_ST_UNKNOWN;
- unsigned int reg_state = PIO_ST_UNKNOWN;
- const unsigned int tmout_state = PIO_ST_TMOUT;
-
- switch (ap->pio_task_state) {
- case PIO_ST:
- case PIO_ST_POLL:
- poll_state = PIO_ST_POLL;
- reg_state = PIO_ST;
+ unsigned int poll_state = HSM_ST_UNKNOWN;
+ unsigned int reg_state = HSM_ST_UNKNOWN;
+
+ switch (ap->hsm_task_state) {
+ case HSM_ST:
+ case HSM_ST_POLL:
+ poll_state = HSM_ST_POLL;
+ reg_state = HSM_ST;
break;
- case PIO_ST_LAST:
- case PIO_ST_LAST_POLL:
- poll_state = PIO_ST_LAST_POLL;
- reg_state = PIO_ST_LAST;
+ case HSM_ST_LAST:
+ case HSM_ST_LAST_POLL:
+ poll_state = HSM_ST_LAST_POLL;
+ reg_state = HSM_ST_LAST;
break;
default:
BUG();
@@ -2448,20 +2767,20 @@ static unsigned long ata_pio_poll(struct ata_port *ap)
status = ata_chk_status(ap);
if (status & ATA_BUSY) {
if (time_after(jiffies, ap->pio_task_timeout)) {
- ap->pio_task_state = tmout_state;
+ ap->hsm_task_state = HSM_ST_TMOUT;
return 0;
}
- ap->pio_task_state = poll_state;
+ ap->hsm_task_state = poll_state;
return ATA_SHORT_PAUSE;
}
- ap->pio_task_state = reg_state;
+ ap->hsm_task_state = reg_state;
return 0;
}
/**
- * ata_pio_complete -
- * @ap:
+ * ata_pio_complete - check if drive is busy or idle
+ * @ap: the target ata_port
*
* LOCKING:
* None. (executing in kernel thread context)
@@ -2480,14 +2799,14 @@ static int ata_pio_complete (struct ata_port *ap)
* we enter, BSY will be cleared in a chk-status or two. If not,
* the drive is probably seeking or something. Snooze for a couple
* msecs, then chk-status again. If still busy, fall back to
- * PIO_ST_POLL state.
+ * HSM_ST_POLL state.
*/
drv_stat = ata_busy_wait(ap, ATA_BUSY | ATA_DRQ, 10);
if (drv_stat & (ATA_BUSY | ATA_DRQ)) {
msleep(2);
drv_stat = ata_busy_wait(ap, ATA_BUSY | ATA_DRQ, 10);
if (drv_stat & (ATA_BUSY | ATA_DRQ)) {
- ap->pio_task_state = PIO_ST_LAST_POLL;
+ ap->hsm_task_state = HSM_ST_LAST_POLL;
ap->pio_task_timeout = jiffies + ATA_TMOUT_PIO;
return 0;
}
@@ -2495,16 +2814,16 @@ static int ata_pio_complete (struct ata_port *ap)
drv_stat = ata_wait_idle(ap);
if (!ata_ok(drv_stat)) {
- ap->pio_task_state = PIO_ST_ERR;
+ ap->hsm_task_state = HSM_ST_ERR;
return 0;
}
qc = ata_qc_from_tag(ap, ap->active_tag);
assert(qc != NULL);
- ap->pio_task_state = PIO_ST_IDLE;
+ ap->hsm_task_state = HSM_ST_IDLE;
- ata_poll_qc_complete(qc, drv_stat);
+ ata_poll_qc_complete(qc, 0);
/* another command may start at this point */
@@ -2513,7 +2832,7 @@ static int ata_pio_complete (struct ata_port *ap)
/**
- * swap_buf_le16 -
+ * swap_buf_le16 - swap halves of 16-words in place
* @buf: Buffer to swap
* @buf_words: Number of 16-bit words in buffer.
*
@@ -2522,6 +2841,7 @@ static int ata_pio_complete (struct ata_port *ap)
* vice-versa.
*
* LOCKING:
+ * Inherited from caller.
*/
void swap_buf_le16(u16 *buf, unsigned int buf_words)
{
@@ -2544,7 +2864,6 @@ void swap_buf_le16(u16 *buf, unsigned int buf_words)
*
* LOCKING:
* Inherited from caller.
- *
*/
static void ata_mmio_data_xfer(struct ata_port *ap, unsigned char *buf,
@@ -2590,7 +2909,6 @@ static void ata_mmio_data_xfer(struct ata_port *ap, unsigned char *buf,
*
* LOCKING:
* Inherited from caller.
- *
*/
static void ata_pio_data_xfer(struct ata_port *ap, unsigned char *buf,
@@ -2630,7 +2948,6 @@ static void ata_pio_data_xfer(struct ata_port *ap, unsigned char *buf,
*
* LOCKING:
* Inherited from caller.
- *
*/
static void ata_data_xfer(struct ata_port *ap, unsigned char *buf,
@@ -2655,14 +2972,14 @@ static void ata_data_xfer(struct ata_port *ap, unsigned char *buf,
static void ata_pio_sector(struct ata_queued_cmd *qc)
{
int do_write = (qc->tf.flags & ATA_TFLAG_WRITE);
- struct scatterlist *sg = qc->sg;
+ struct scatterlist *sg = qc->__sg;
struct ata_port *ap = qc->ap;
struct page *page;
unsigned int offset;
unsigned char *buf;
if (qc->cursect == (qc->nsect - 1))
- ap->pio_task_state = PIO_ST_LAST;
+ ap->hsm_task_state = HSM_ST_LAST;
page = sg[qc->cursg].page;
offset = sg[qc->cursg].offset + qc->cursg_ofs * ATA_SECT_SIZE;
@@ -2705,14 +3022,14 @@ static void ata_pio_sector(struct ata_queued_cmd *qc)
static void __atapi_pio_bytes(struct ata_queued_cmd *qc, unsigned int bytes)
{
int do_write = (qc->tf.flags & ATA_TFLAG_WRITE);
- struct scatterlist *sg = qc->sg;
+ struct scatterlist *sg = qc->__sg;
struct ata_port *ap = qc->ap;
struct page *page;
unsigned char *buf;
unsigned int offset, count;
if (qc->curbytes + bytes >= qc->nbytes)
- ap->pio_task_state = PIO_ST_LAST;
+ ap->hsm_task_state = HSM_ST_LAST;
next_sg:
if (unlikely(qc->cursg >= qc->n_elem)) {
@@ -2734,11 +3051,11 @@ next_sg:
for (i = 0; i < words; i++)
ata_data_xfer(ap, (unsigned char*)pad_buf, 2, do_write);
- ap->pio_task_state = PIO_ST_LAST;
+ ap->hsm_task_state = HSM_ST_LAST;
return;
}
- sg = &qc->sg[qc->cursg];
+ sg = &qc->__sg[qc->cursg];
page = sg->page;
offset = sg->offset + qc->cursg_ofs;
@@ -2783,7 +3100,6 @@ next_sg:
*
* LOCKING:
* Inherited from caller.
- *
*/
static void atapi_pio_bytes(struct ata_queued_cmd *qc)
@@ -2815,12 +3131,12 @@ static void atapi_pio_bytes(struct ata_queued_cmd *qc)
err_out:
printk(KERN_INFO "ata%u: dev %u: ATAPI check failed\n",
ap->id, dev->devno);
- ap->pio_task_state = PIO_ST_ERR;
+ ap->hsm_task_state = HSM_ST_ERR;
}
/**
- * ata_pio_sector -
- * @ap:
+ * ata_pio_block - start PIO on a block
+ * @ap: the target ata_port
*
* LOCKING:
* None. (executing in kernel thread context)
@@ -2832,19 +3148,19 @@ static void ata_pio_block(struct ata_port *ap)
u8 status;
/*
- * This is purely hueristic. This is a fast path.
+ * This is purely heuristic. This is a fast path.
* Sometimes when we enter, BSY will be cleared in
* a chk-status or two. If not, the drive is probably seeking
* or something. Snooze for a couple msecs, then
* chk-status again. If still busy, fall back to
- * PIO_ST_POLL state.
+ * HSM_ST_POLL state.
*/
status = ata_busy_wait(ap, ATA_BUSY, 5);
if (status & ATA_BUSY) {
msleep(2);
status = ata_busy_wait(ap, ATA_BUSY, 10);
if (status & ATA_BUSY) {
- ap->pio_task_state = PIO_ST_POLL;
+ ap->hsm_task_state = HSM_ST_POLL;
ap->pio_task_timeout = jiffies + ATA_TMOUT_PIO;
return;
}
@@ -2856,7 +3172,7 @@ static void ata_pio_block(struct ata_port *ap)
if (is_atapi_taskfile(&qc->tf)) {
/* no more data to transfer or unsupported ATAPI command */
if ((status & ATA_DRQ) == 0) {
- ap->pio_task_state = PIO_ST_LAST;
+ ap->hsm_task_state = HSM_ST_LAST;
return;
}
@@ -2864,7 +3180,7 @@ static void ata_pio_block(struct ata_port *ap)
} else {
/* handle BSY=0, DRQ=0 as error */
if ((status & ATA_DRQ) == 0) {
- ap->pio_task_state = PIO_ST_ERR;
+ ap->hsm_task_state = HSM_ST_ERR;
return;
}
@@ -2875,18 +3191,15 @@ static void ata_pio_block(struct ata_port *ap)
static void ata_pio_error(struct ata_port *ap)
{
struct ata_queued_cmd *qc;
- u8 drv_stat;
+
+ printk(KERN_WARNING "ata%u: PIO error\n", ap->id);
qc = ata_qc_from_tag(ap, ap->active_tag);
assert(qc != NULL);
- drv_stat = ata_chk_status(ap);
- printk(KERN_WARNING "ata%u: PIO error, drv_stat 0x%x\n",
- ap->id, drv_stat);
-
- ap->pio_task_state = PIO_ST_IDLE;
+ ap->hsm_task_state = HSM_ST_IDLE;
- ata_poll_qc_complete(qc, drv_stat | ATA_ERR);
+ ata_poll_qc_complete(qc, AC_ERR_ATA_BUS);
}
static void ata_pio_task(void *_data)
@@ -2899,25 +3212,25 @@ fsm_start:
timeout = 0;
qc_completed = 0;
- switch (ap->pio_task_state) {
- case PIO_ST_IDLE:
+ switch (ap->hsm_task_state) {
+ case HSM_ST_IDLE:
return;
- case PIO_ST:
+ case HSM_ST:
ata_pio_block(ap);
break;
- case PIO_ST_LAST:
+ case HSM_ST_LAST:
qc_completed = ata_pio_complete(ap);
break;
- case PIO_ST_POLL:
- case PIO_ST_LAST_POLL:
+ case HSM_ST_POLL:
+ case HSM_ST_LAST_POLL:
timeout = ata_pio_poll(ap);
break;
- case PIO_ST_TMOUT:
- case PIO_ST_ERR:
+ case HSM_ST_TMOUT:
+ case HSM_ST_ERR:
ata_pio_error(ap);
return;
}
@@ -2928,52 +3241,6 @@ fsm_start:
goto fsm_start;
}
-static void atapi_request_sense(struct ata_port *ap, struct ata_device *dev,
- struct scsi_cmnd *cmd)
-{
- DECLARE_COMPLETION(wait);
- struct ata_queued_cmd *qc;
- unsigned long flags;
- int rc;
-
- DPRINTK("ATAPI request sense\n");
-
- qc = ata_qc_new_init(ap, dev);
- BUG_ON(qc == NULL);
-
- /* FIXME: is this needed? */
- memset(cmd->sense_buffer, 0, sizeof(cmd->sense_buffer));
-
- ata_sg_init_one(qc, cmd->sense_buffer, sizeof(cmd->sense_buffer));
- qc->dma_dir = DMA_FROM_DEVICE;
-
- memset(&qc->cdb, 0, ap->cdb_len);
- qc->cdb[0] = REQUEST_SENSE;
- qc->cdb[4] = SCSI_SENSE_BUFFERSIZE;
-
- qc->tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
- qc->tf.command = ATA_CMD_PACKET;
-
- qc->tf.protocol = ATA_PROT_ATAPI;
- qc->tf.lbam = (8 * 1024) & 0xff;
- qc->tf.lbah = (8 * 1024) >> 8;
- qc->nbytes = SCSI_SENSE_BUFFERSIZE;
-
- qc->waiting = &wait;
- qc->complete_fn = ata_qc_complete_noop;
-
- spin_lock_irqsave(&ap->host_set->lock, flags);
- rc = ata_qc_issue(qc);
- spin_unlock_irqrestore(&ap->host_set->lock, flags);
-
- if (rc)
- ata_port_disable(ap);
- else
- wait_for_completion(&wait);
-
- DPRINTK("EXIT\n");
-}
-
/**
* ata_qc_timeout - Handle timeout of queued command
* @qc: Command that timed out
@@ -3055,7 +3322,7 @@ static void ata_qc_timeout(struct ata_queued_cmd *qc)
ap->id, qc->tf.command, drv_stat, host_stat);
/* complete taskfile transaction */
- ata_qc_complete(qc, drv_stat);
+ ata_qc_complete(qc, ac_err_mask(drv_stat));
break;
}
@@ -3091,14 +3358,14 @@ void ata_eng_timeout(struct ata_port *ap)
DPRINTK("ENTER\n");
qc = ata_qc_from_tag(ap, ap->active_tag);
- if (!qc) {
+ if (qc)
+ ata_qc_timeout(qc);
+ else {
printk(KERN_ERR "ata%u: BUG: timeout without command\n",
ap->id);
goto out;
}
- ata_qc_timeout(qc);
-
out:
DPRINTK("EXIT\n");
}
@@ -3145,7 +3412,7 @@ struct ata_queued_cmd *ata_qc_new_init(struct ata_port *ap,
qc = ata_qc_new(ap);
if (qc) {
- qc->sg = NULL;
+ qc->__sg = NULL;
qc->flags = 0;
qc->scsicmd = NULL;
qc->ap = ap;
@@ -3155,15 +3422,12 @@ struct ata_queued_cmd *ata_qc_new_init(struct ata_port *ap,
qc->nbytes = qc->curbytes = 0;
ata_tf_init(ap, &qc->tf, dev->devno);
-
- if (dev->flags & ATA_DFLAG_LBA48)
- qc->tf.flags |= ATA_TFLAG_LBA48;
}
return qc;
}
-static int ata_qc_complete_noop(struct ata_queued_cmd *qc, u8 drv_stat)
+int ata_qc_complete_noop(struct ata_queued_cmd *qc, unsigned int err_mask)
{
return 0;
}
@@ -3201,7 +3465,6 @@ static void __ata_qc_complete(struct ata_queued_cmd *qc)
*
* LOCKING:
* spin_lock_irqsave(host_set lock)
- *
*/
void ata_qc_free(struct ata_queued_cmd *qc)
{
@@ -3214,17 +3477,16 @@ void ata_qc_free(struct ata_queued_cmd *qc)
/**
* ata_qc_complete - Complete an active ATA command
* @qc: Command to complete
- * @drv_stat: ATA Status register contents
+ * @err_mask: ATA Status register contents
*
* Indicate to the mid and upper layers that an ATA
* command has completed, with either an ok or not-ok status.
*
* LOCKING:
* spin_lock_irqsave(host_set lock)
- *
*/
-void ata_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat)
+void ata_qc_complete(struct ata_queued_cmd *qc, unsigned int err_mask)
{
int rc;
@@ -3241,7 +3503,7 @@ void ata_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat)
qc->flags &= ~ATA_QCFLAG_ACTIVE;
/* call completion callback */
- rc = qc->complete_fn(qc, drv_stat);
+ rc = qc->complete_fn(qc, err_mask);
/* if callback indicates not to complete command (non-zero),
* return immediately
@@ -3348,7 +3610,7 @@ int ata_qc_issue_prot(struct ata_queued_cmd *qc)
switch (qc->tf.protocol) {
case ATA_PROT_NODATA:
- ata_tf_to_host_nolock(ap, &qc->tf);
+ ata_tf_to_host(ap, &qc->tf);
break;
case ATA_PROT_DMA:
@@ -3359,20 +3621,20 @@ int ata_qc_issue_prot(struct ata_queued_cmd *qc)
case ATA_PROT_PIO: /* load tf registers, initiate polling pio */
ata_qc_set_polling(qc);
- ata_tf_to_host_nolock(ap, &qc->tf);
- ap->pio_task_state = PIO_ST;
+ ata_tf_to_host(ap, &qc->tf);
+ ap->hsm_task_state = HSM_ST;
queue_work(ata_wq, &ap->pio_task);
break;
case ATA_PROT_ATAPI:
ata_qc_set_polling(qc);
- ata_tf_to_host_nolock(ap, &qc->tf);
+ ata_tf_to_host(ap, &qc->tf);
queue_work(ata_wq, &ap->packet_task);
break;
case ATA_PROT_ATAPI_NODATA:
ap->flags |= ATA_FLAG_NOINTR;
- ata_tf_to_host_nolock(ap, &qc->tf);
+ ata_tf_to_host(ap, &qc->tf);
queue_work(ata_wq, &ap->packet_task);
break;
@@ -3586,7 +3848,7 @@ u8 ata_bmdma_status(struct ata_port *ap)
void __iomem *mmio = (void __iomem *) ap->ioaddr.bmdma_addr;
host_stat = readb(mmio + ATA_DMA_STATUS);
} else
- host_stat = inb(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
+ host_stat = inb(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
return host_stat;
}
@@ -3679,7 +3941,7 @@ inline unsigned int ata_host_intr (struct ata_port *ap,
ap->ops->irq_clear(ap);
/* complete taskfile transaction */
- ata_qc_complete(qc, status);
+ ata_qc_complete(qc, ac_err_mask(status));
break;
default:
@@ -3715,7 +3977,6 @@ idle_irq:
*
* RETURNS:
* IRQ_NONE or IRQ_HANDLED.
- *
*/
irqreturn_t ata_interrupt (int irq, void *dev_instance, struct pt_regs *regs)
@@ -3775,7 +4036,7 @@ static void atapi_packet_task(void *_data)
/* sleep-wait for BSY to clear */
DPRINTK("busy wait\n");
if (ata_busy_sleep(ap, ATA_TMOUT_CDB_QUICK, ATA_TMOUT_CDB))
- goto err_out;
+ goto err_out_status;
/* make sure DRQ is set */
status = ata_chk_status(ap);
@@ -3806,14 +4067,16 @@ static void atapi_packet_task(void *_data)
ata_data_xfer(ap, qc->cdb, ap->cdb_len, 1);
/* PIO commands are handled by polling */
- ap->pio_task_state = PIO_ST;
+ ap->hsm_task_state = HSM_ST;
queue_work(ata_wq, &ap->pio_task);
}
return;
+err_out_status:
+ status = ata_chk_status(ap);
err_out:
- ata_poll_qc_complete(qc, ATA_ERR);
+ ata_poll_qc_complete(qc, __ac_err_mask(status));
}
@@ -3827,16 +4090,24 @@ err_out:
* May be used as the port_start() entry in ata_port_operations.
*
* LOCKING:
+ * Inherited from caller.
*/
int ata_port_start (struct ata_port *ap)
{
struct device *dev = ap->host_set->dev;
+ int rc;
ap->prd = dma_alloc_coherent(dev, ATA_PRD_TBL_SZ, &ap->prd_dma, GFP_KERNEL);
if (!ap->prd)
return -ENOMEM;
+ rc = ata_pad_alloc(ap, dev);
+ if (rc) {
+ dma_free_coherent(dev, ATA_PRD_TBL_SZ, ap->prd, ap->prd_dma);
+ return rc;
+ }
+
DPRINTK("prd alloc, virt %p, dma %llx\n", ap->prd, (unsigned long long) ap->prd_dma);
return 0;
@@ -3852,6 +4123,7 @@ int ata_port_start (struct ata_port *ap)
* May be used as the port_stop() entry in ata_port_operations.
*
* LOCKING:
+ * Inherited from caller.
*/
void ata_port_stop (struct ata_port *ap)
@@ -3859,6 +4131,7 @@ void ata_port_stop (struct ata_port *ap)
struct device *dev = ap->host_set->dev;
dma_free_coherent(dev, ATA_PRD_TBL_SZ, ap->prd, ap->prd_dma);
+ ata_pad_free(ap, dev);
}
void ata_host_stop (struct ata_host_set *host_set)
@@ -3874,6 +4147,7 @@ void ata_host_stop (struct ata_host_set *host_set)
* @do_unregister: 1 if we fully unregister, 0 to just stop the port
*
* LOCKING:
+ * Inherited from caller.
*/
static void ata_host_remove(struct ata_port *ap, unsigned int do_unregister)
@@ -3901,12 +4175,11 @@ static void ata_host_remove(struct ata_port *ap, unsigned int do_unregister)
*
* LOCKING:
* Inherited from caller.
- *
*/
static void ata_host_init(struct ata_port *ap, struct Scsi_Host *host,
struct ata_host_set *host_set,
- struct ata_probe_ent *ent, unsigned int port_no)
+ const struct ata_probe_ent *ent, unsigned int port_no)
{
unsigned int i;
@@ -3916,8 +4189,6 @@ static void ata_host_init(struct ata_port *ap, struct Scsi_Host *host,
host->unique_id = ata_unique_id++;
host->max_cmd_len = 12;
- scsi_assign_lock(host, &host_set->lock);
-
ap->flags = ATA_FLAG_PORT_DISABLED;
ap->id = host->unique_id;
ap->host = host;
@@ -3962,10 +4233,9 @@ static void ata_host_init(struct ata_port *ap, struct Scsi_Host *host,
*
* RETURNS:
* New ata_port on success, for NULL on error.
- *
*/
-static struct ata_port * ata_host_add(struct ata_probe_ent *ent,
+static struct ata_port * ata_host_add(const struct ata_probe_ent *ent,
struct ata_host_set *host_set,
unsigned int port_no)
{
@@ -4010,10 +4280,9 @@ err_out:
*
* RETURNS:
* Number of ports registered. Zero on error (no ports registered).
- *
*/
-int ata_device_add(struct ata_probe_ent *ent)
+int ata_device_add(const struct ata_probe_ent *ent)
{
unsigned int count = 0, i;
struct device *dev = ent->dev;
@@ -4021,11 +4290,10 @@ int ata_device_add(struct ata_probe_ent *ent)
DPRINTK("ENTER\n");
/* alloc a container for our list of ATA ports (buses) */
- host_set = kmalloc(sizeof(struct ata_host_set) +
+ host_set = kzalloc(sizeof(struct ata_host_set) +
(ent->n_ports * sizeof(void *)), GFP_KERNEL);
if (!host_set)
return 0;
- memset(host_set, 0, sizeof(struct ata_host_set) + (ent->n_ports * sizeof(void *)));
spin_lock_init(&host_set->lock);
host_set->dev = dev;
@@ -4065,10 +4333,8 @@ int ata_device_add(struct ata_probe_ent *ent)
count++;
}
- if (!count) {
- kfree(host_set);
- return 0;
- }
+ if (!count)
+ goto err_free_ret;
/* obtain irq, that is shared between channels */
if (request_irq(ent->irq, ent->port_ops->irq_handler, ent->irq_flags,
@@ -4113,7 +4379,7 @@ int ata_device_add(struct ata_probe_ent *ent)
for (i = 0; i < count; i++) {
struct ata_port *ap = host_set->ports[i];
- scsi_scan_host(ap->host);
+ ata_scsi_scan_host(ap);
}
dev_set_drvdata(dev, host_set);
@@ -4126,6 +4392,7 @@ err_out:
ata_host_remove(host_set->ports[i], 1);
scsi_host_put(host_set->ports[i]->host);
}
+err_free_ret:
kfree(host_set);
VPRINTK("EXIT, returning 0\n");
return 0;
@@ -4142,7 +4409,6 @@ err_out:
* Inherited from calling layer (may sleep).
*/
-
void ata_host_set_remove(struct ata_host_set *host_set)
{
struct ata_port *ap;
@@ -4232,19 +4498,17 @@ void ata_std_ports(struct ata_ioports *ioaddr)
}
static struct ata_probe_ent *
-ata_probe_ent_alloc(struct device *dev, struct ata_port_info *port)
+ata_probe_ent_alloc(struct device *dev, const struct ata_port_info *port)
{
struct ata_probe_ent *probe_ent;
- probe_ent = kmalloc(sizeof(*probe_ent), GFP_KERNEL);
+ probe_ent = kzalloc(sizeof(*probe_ent), GFP_KERNEL);
if (!probe_ent) {
printk(KERN_ERR DRV_NAME "(%s): out of memory\n",
kobject_name(&(dev->kobj)));
return NULL;
}
- memset(probe_ent, 0, sizeof(*probe_ent));
-
INIT_LIST_HEAD(&probe_ent->node);
probe_ent->dev = dev;
@@ -4273,85 +4537,86 @@ void ata_pci_host_stop (struct ata_host_set *host_set)
* ata_pci_init_native_mode - Initialize native-mode driver
* @pdev: pci device to be initialized
* @port: array[2] of pointers to port info structures.
+ * @ports: bitmap of ports present
*
* Utility function which allocates and initializes an
* ata_probe_ent structure for a standard dual-port
* PIO-based IDE controller. The returned ata_probe_ent
* structure can be passed to ata_device_add(). The returned
* ata_probe_ent structure should then be freed with kfree().
+ *
+ * The caller need only pass the address of the primary port, the
+ * secondary will be deduced automatically. If the device has non
+ * standard secondary port mappings this function can be called twice,
+ * once for each interface.
*/
struct ata_probe_ent *
-ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port)
+ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port, int ports)
{
struct ata_probe_ent *probe_ent =
ata_probe_ent_alloc(pci_dev_to_dev(pdev), port[0]);
+ int p = 0;
+
if (!probe_ent)
return NULL;
- probe_ent->n_ports = 2;
probe_ent->irq = pdev->irq;
probe_ent->irq_flags = SA_SHIRQ;
- probe_ent->port[0].cmd_addr = pci_resource_start(pdev, 0);
- probe_ent->port[0].altstatus_addr =
- probe_ent->port[0].ctl_addr =
- pci_resource_start(pdev, 1) | ATA_PCI_CTL_OFS;
- probe_ent->port[0].bmdma_addr = pci_resource_start(pdev, 4);
-
- probe_ent->port[1].cmd_addr = pci_resource_start(pdev, 2);
- probe_ent->port[1].altstatus_addr =
- probe_ent->port[1].ctl_addr =
- pci_resource_start(pdev, 3) | ATA_PCI_CTL_OFS;
- probe_ent->port[1].bmdma_addr = pci_resource_start(pdev, 4) + 8;
+ if (ports & ATA_PORT_PRIMARY) {
+ probe_ent->port[p].cmd_addr = pci_resource_start(pdev, 0);
+ probe_ent->port[p].altstatus_addr =
+ probe_ent->port[p].ctl_addr =
+ pci_resource_start(pdev, 1) | ATA_PCI_CTL_OFS;
+ probe_ent->port[p].bmdma_addr = pci_resource_start(pdev, 4);
+ ata_std_ports(&probe_ent->port[p]);
+ p++;
+ }
- ata_std_ports(&probe_ent->port[0]);
- ata_std_ports(&probe_ent->port[1]);
+ if (ports & ATA_PORT_SECONDARY) {
+ probe_ent->port[p].cmd_addr = pci_resource_start(pdev, 2);
+ probe_ent->port[p].altstatus_addr =
+ probe_ent->port[p].ctl_addr =
+ pci_resource_start(pdev, 3) | ATA_PCI_CTL_OFS;
+ probe_ent->port[p].bmdma_addr = pci_resource_start(pdev, 4) + 8;
+ ata_std_ports(&probe_ent->port[p]);
+ p++;
+ }
+ probe_ent->n_ports = p;
return probe_ent;
}
-static struct ata_probe_ent *
-ata_pci_init_legacy_mode(struct pci_dev *pdev, struct ata_port_info **port,
- struct ata_probe_ent **ppe2)
+static struct ata_probe_ent *ata_pci_init_legacy_port(struct pci_dev *pdev, struct ata_port_info *port, int port_num)
{
- struct ata_probe_ent *probe_ent, *probe_ent2;
+ struct ata_probe_ent *probe_ent;
- probe_ent = ata_probe_ent_alloc(pci_dev_to_dev(pdev), port[0]);
+ probe_ent = ata_probe_ent_alloc(pci_dev_to_dev(pdev), port);
if (!probe_ent)
return NULL;
- probe_ent2 = ata_probe_ent_alloc(pci_dev_to_dev(pdev), port[1]);
- if (!probe_ent2) {
- kfree(probe_ent);
- return NULL;
- }
- probe_ent->n_ports = 1;
- probe_ent->irq = 14;
-
- probe_ent->hard_port_no = 0;
probe_ent->legacy_mode = 1;
-
- probe_ent2->n_ports = 1;
- probe_ent2->irq = 15;
-
- probe_ent2->hard_port_no = 1;
- probe_ent2->legacy_mode = 1;
-
- probe_ent->port[0].cmd_addr = 0x1f0;
- probe_ent->port[0].altstatus_addr =
- probe_ent->port[0].ctl_addr = 0x3f6;
- probe_ent->port[0].bmdma_addr = pci_resource_start(pdev, 4);
-
- probe_ent2->port[0].cmd_addr = 0x170;
- probe_ent2->port[0].altstatus_addr =
- probe_ent2->port[0].ctl_addr = 0x376;
- probe_ent2->port[0].bmdma_addr = pci_resource_start(pdev, 4)+8;
-
+ probe_ent->n_ports = 1;
+ probe_ent->hard_port_no = port_num;
+
+ switch(port_num)
+ {
+ case 0:
+ probe_ent->irq = 14;
+ probe_ent->port[0].cmd_addr = 0x1f0;
+ probe_ent->port[0].altstatus_addr =
+ probe_ent->port[0].ctl_addr = 0x3f6;
+ break;
+ case 1:
+ probe_ent->irq = 15;
+ probe_ent->port[0].cmd_addr = 0x170;
+ probe_ent->port[0].altstatus_addr =
+ probe_ent->port[0].ctl_addr = 0x376;
+ break;
+ }
+ probe_ent->port[0].bmdma_addr = pci_resource_start(pdev, 4) + 8 * port_num;
ata_std_ports(&probe_ent->port[0]);
- ata_std_ports(&probe_ent2->port[0]);
-
- *ppe2 = probe_ent2;
return probe_ent;
}
@@ -4374,13 +4639,12 @@ ata_pci_init_legacy_mode(struct pci_dev *pdev, struct ata_port_info **port,
*
* RETURNS:
* Zero on success, negative on errno-based value on error.
- *
*/
int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
unsigned int n_ports)
{
- struct ata_probe_ent *probe_ent, *probe_ent2 = NULL;
+ struct ata_probe_ent *probe_ent = NULL, *probe_ent2 = NULL;
struct ata_port_info *port[2];
u8 tmp8, mask;
unsigned int legacy_mode = 0;
@@ -4397,7 +4661,7 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
if ((port[0]->host_flags & ATA_FLAG_NO_LEGACY) == 0
&& (pdev->class >> 8) == PCI_CLASS_STORAGE_IDE) {
- /* TODO: support transitioning to native mode? */
+ /* TODO: What if one channel is in native mode ... */
pci_read_config_byte(pdev, PCI_CLASS_PROG, &tmp8);
mask = (1 << 2) | (1 << 0);
if ((tmp8 & mask) != mask)
@@ -4405,11 +4669,20 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
}
/* FIXME... */
- if ((!legacy_mode) && (n_ports > 1)) {
- printk(KERN_ERR "ata: BUG: native mode, n_ports > 1\n");
- return -EINVAL;
+ if ((!legacy_mode) && (n_ports > 2)) {
+ printk(KERN_ERR "ata: BUG: native mode, n_ports > 2\n");
+ n_ports = 2;
+ /* For now */
}
+ /* FIXME: Really for ATA it isn't safe because the device may be
+ multi-purpose and we want to leave it alone if it was already
+ enabled. Secondly for shared use as Arjan says we want refcounting
+
+ Checking dev->is_enabled is insufficient as this is not set at
+ boot for the primary video which is BIOS enabled
+ */
+
rc = pci_enable_device(pdev);
if (rc)
return rc;
@@ -4420,6 +4693,7 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
goto err_out;
}
+ /* FIXME: Should use platform specific mappers for legacy port ranges */
if (legacy_mode) {
if (!request_region(0x1f0, 8, "libata")) {
struct resource *conflict, res;
@@ -4464,10 +4738,17 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
goto err_out_regions;
if (legacy_mode) {
- probe_ent = ata_pci_init_legacy_mode(pdev, port, &probe_ent2);
- } else
- probe_ent = ata_pci_init_native_mode(pdev, port);
- if (!probe_ent) {
+ if (legacy_mode & (1 << 0))
+ probe_ent = ata_pci_init_legacy_port(pdev, port[0], 0);
+ if (legacy_mode & (1 << 1))
+ probe_ent2 = ata_pci_init_legacy_port(pdev, port[1], 1);
+ } else {
+ if (n_ports == 2)
+ probe_ent = ata_pci_init_native_mode(pdev, port, ATA_PORT_PRIMARY | ATA_PORT_SECONDARY);
+ else
+ probe_ent = ata_pci_init_native_mode(pdev, port, ATA_PORT_PRIMARY);
+ }
+ if (!probe_ent && !probe_ent2) {
rc = -ENOMEM;
goto err_out_regions;
}
@@ -4505,7 +4786,7 @@ err_out:
* @pdev: PCI device that was removed
*
* PCI layer indicates to libata via this hook that
- * hot-unplug or module unload event has occured.
+ * hot-unplug or module unload event has occurred.
* Handle this by unregistering all objects associated
* with this PCI device. Free those objects. Then finally
* release PCI resources and disable device.
@@ -4526,7 +4807,7 @@ void ata_pci_remove_one (struct pci_dev *pdev)
}
/* move to PCI subsystem */
-int pci_test_config_bits(struct pci_dev *pdev, struct pci_bits *bits)
+int pci_test_config_bits(struct pci_dev *pdev, const struct pci_bits *bits)
{
unsigned long tmp = 0;
@@ -4579,6 +4860,27 @@ static void __exit ata_exit(void)
module_init(ata_init);
module_exit(ata_exit);
+static unsigned long ratelimit_time;
+static spinlock_t ata_ratelimit_lock = SPIN_LOCK_UNLOCKED;
+
+int ata_ratelimit(void)
+{
+ int rc;
+ unsigned long flags;
+
+ spin_lock_irqsave(&ata_ratelimit_lock, flags);
+
+ if (time_after(jiffies, ratelimit_time)) {
+ rc = 1;
+ ratelimit_time = jiffies + (HZ/5);
+ } else
+ rc = 0;
+
+ spin_unlock_irqrestore(&ata_ratelimit_lock, flags);
+
+ return rc;
+}
+
/*
* libata is essentially a library of internal helper functions for
* low-level ATA host controller drivers. As such, the API/ABI is
@@ -4603,7 +4905,6 @@ EXPORT_SYMBOL_GPL(ata_tf_to_fis);
EXPORT_SYMBOL_GPL(ata_tf_from_fis);
EXPORT_SYMBOL_GPL(ata_check_status);
EXPORT_SYMBOL_GPL(ata_altstatus);
-EXPORT_SYMBOL_GPL(ata_chk_err);
EXPORT_SYMBOL_GPL(ata_exec_command);
EXPORT_SYMBOL_GPL(ata_port_start);
EXPORT_SYMBOL_GPL(ata_port_stop);
@@ -4620,6 +4921,7 @@ EXPORT_SYMBOL_GPL(sata_phy_reset);
EXPORT_SYMBOL_GPL(__sata_phy_reset);
EXPORT_SYMBOL_GPL(ata_bus_reset);
EXPORT_SYMBOL_GPL(ata_port_disable);
+EXPORT_SYMBOL_GPL(ata_ratelimit);
EXPORT_SYMBOL_GPL(ata_scsi_ioctl);
EXPORT_SYMBOL_GPL(ata_scsi_queuecmd);
EXPORT_SYMBOL_GPL(ata_scsi_error);
@@ -4631,6 +4933,9 @@ EXPORT_SYMBOL_GPL(ata_dev_id_string);
EXPORT_SYMBOL_GPL(ata_dev_config);
EXPORT_SYMBOL_GPL(ata_scsi_simulate);
+EXPORT_SYMBOL_GPL(ata_timing_compute);
+EXPORT_SYMBOL_GPL(ata_timing_merge);
+
#ifdef CONFIG_PCI
EXPORT_SYMBOL_GPL(pci_test_config_bits);
EXPORT_SYMBOL_GPL(ata_pci_host_stop);
diff --git a/drivers/scsi/libata-scsi.c b/drivers/scsi/libata-scsi.c
index 104fd9a63e73..bb30fcdc9297 100644
--- a/drivers/scsi/libata-scsi.c
+++ b/drivers/scsi/libata-scsi.c
@@ -37,17 +37,68 @@
#include <linux/blkdev.h>
#include <linux/spinlock.h>
#include <scsi/scsi.h>
-#include "scsi.h"
#include <scsi/scsi_host.h>
+#include <scsi/scsi_device.h>
+#include <scsi/scsi_request.h>
#include <linux/libata.h>
+#include <linux/hdreg.h>
#include <asm/uaccess.h>
#include "libata.h"
-typedef unsigned int (*ata_xlat_func_t)(struct ata_queued_cmd *qc, u8 *scsicmd);
-static struct ata_device *
-ata_scsi_find_dev(struct ata_port *ap, struct scsi_device *scsidev);
+#define SECTOR_SIZE 512
+typedef unsigned int (*ata_xlat_func_t)(struct ata_queued_cmd *qc, const u8 *scsicmd);
+static struct ata_device *
+ata_scsi_find_dev(struct ata_port *ap, const struct scsi_device *scsidev);
+
+#define RW_RECOVERY_MPAGE 0x1
+#define RW_RECOVERY_MPAGE_LEN 12
+#define CACHE_MPAGE 0x8
+#define CACHE_MPAGE_LEN 20
+#define CONTROL_MPAGE 0xa
+#define CONTROL_MPAGE_LEN 12
+#define ALL_MPAGES 0x3f
+#define ALL_SUB_MPAGES 0xff
+
+
+static const u8 def_rw_recovery_mpage[] = {
+ RW_RECOVERY_MPAGE,
+ RW_RECOVERY_MPAGE_LEN - 2,
+ (1 << 7) | /* AWRE, sat-r06 say it shall be 0 */
+ (1 << 6), /* ARRE (auto read reallocation) */
+ 0, /* read retry count */
+ 0, 0, 0, 0,
+ 0, /* write retry count */
+ 0, 0, 0
+};
+
+static const u8 def_cache_mpage[CACHE_MPAGE_LEN] = {
+ CACHE_MPAGE,
+ CACHE_MPAGE_LEN - 2,
+ 0, /* contains WCE, needs to be 0 for logic */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, /* contains DRA, needs to be 0 for logic */
+ 0, 0, 0, 0, 0, 0, 0
+};
+
+static const u8 def_control_mpage[CONTROL_MPAGE_LEN] = {
+ CONTROL_MPAGE,
+ CONTROL_MPAGE_LEN - 2,
+ 2, /* DSENSE=0, GLTSD=1 */
+ 0, /* [QAM+QERR may be 1, see 05-359r1] */
+ 0, 0, 0, 0, 0xff, 0xff,
+ 0, 30 /* extended self test time, see 05-359r1 */
+};
+
+
+static void ata_scsi_invalid_field(struct scsi_cmnd *cmd,
+ void (*done)(struct scsi_cmnd *))
+{
+ ata_scsi_set_sense(cmd, ILLEGAL_REQUEST, 0x24, 0x0);
+ /* "Invalid field in cbd" */
+ done(cmd);
+}
/**
* ata_std_bios_param - generic bios head/sector/cylinder calculator used by sd.
@@ -78,6 +129,150 @@ int ata_std_bios_param(struct scsi_device *sdev, struct block_device *bdev,
return 0;
}
+/**
+ * ata_cmd_ioctl - Handler for HDIO_DRIVE_CMD ioctl
+ * @scsidev: Device to which we are issuing command
+ * @arg: User provided data for issuing command
+ *
+ * LOCKING:
+ * Defined by the SCSI layer. We don't really care.
+ *
+ * RETURNS:
+ * Zero on success, negative errno on error.
+ */
+
+int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg)
+{
+ int rc = 0;
+ u8 scsi_cmd[MAX_COMMAND_SIZE];
+ u8 args[4], *argbuf = NULL;
+ int argsize = 0;
+ struct scsi_request *sreq;
+
+ if (NULL == (void *)arg)
+ return -EINVAL;
+
+ if (copy_from_user(args, arg, sizeof(args)))
+ return -EFAULT;
+
+ sreq = scsi_allocate_request(scsidev, GFP_KERNEL);
+ if (!sreq)
+ return -EINTR;
+
+ memset(scsi_cmd, 0, sizeof(scsi_cmd));
+
+ if (args[3]) {
+ argsize = SECTOR_SIZE * args[3];
+ argbuf = kmalloc(argsize, GFP_KERNEL);
+ if (argbuf == NULL) {
+ rc = -ENOMEM;
+ goto error;
+ }
+
+ scsi_cmd[1] = (4 << 1); /* PIO Data-in */
+ scsi_cmd[2] = 0x0e; /* no off.line or cc, read from dev,
+ block count in sector count field */
+ sreq->sr_data_direction = DMA_FROM_DEVICE;
+ } else {
+ scsi_cmd[1] = (3 << 1); /* Non-data */
+ /* scsi_cmd[2] is already 0 -- no off.line, cc, or data xfer */
+ sreq->sr_data_direction = DMA_NONE;
+ }
+
+ scsi_cmd[0] = ATA_16;
+
+ scsi_cmd[4] = args[2];
+ if (args[0] == WIN_SMART) { /* hack -- ide driver does this too... */
+ scsi_cmd[6] = args[3];
+ scsi_cmd[8] = args[1];
+ scsi_cmd[10] = 0x4f;
+ scsi_cmd[12] = 0xc2;
+ } else {
+ scsi_cmd[6] = args[1];
+ }
+ scsi_cmd[14] = args[0];
+
+ /* Good values for timeout and retries? Values below
+ from scsi_ioctl_send_command() for default case... */
+ scsi_wait_req(sreq, scsi_cmd, argbuf, argsize, (10*HZ), 5);
+
+ if (sreq->sr_result) {
+ rc = -EIO;
+ goto error;
+ }
+
+ /* Need code to retrieve data from check condition? */
+
+ if ((argbuf)
+ && copy_to_user((void *)(arg + sizeof(args)), argbuf, argsize))
+ rc = -EFAULT;
+error:
+ scsi_release_request(sreq);
+
+ if (argbuf)
+ kfree(argbuf);
+
+ return rc;
+}
+
+/**
+ * ata_task_ioctl - Handler for HDIO_DRIVE_TASK ioctl
+ * @scsidev: Device to which we are issuing command
+ * @arg: User provided data for issuing command
+ *
+ * LOCKING:
+ * Defined by the SCSI layer. We don't really care.
+ *
+ * RETURNS:
+ * Zero on success, negative errno on error.
+ */
+int ata_task_ioctl(struct scsi_device *scsidev, void __user *arg)
+{
+ int rc = 0;
+ u8 scsi_cmd[MAX_COMMAND_SIZE];
+ u8 args[7];
+ struct scsi_request *sreq;
+
+ if (NULL == (void *)arg)
+ return -EINVAL;
+
+ if (copy_from_user(args, arg, sizeof(args)))
+ return -EFAULT;
+
+ memset(scsi_cmd, 0, sizeof(scsi_cmd));
+ scsi_cmd[0] = ATA_16;
+ scsi_cmd[1] = (3 << 1); /* Non-data */
+ /* scsi_cmd[2] is already 0 -- no off.line, cc, or data xfer */
+ scsi_cmd[4] = args[1];
+ scsi_cmd[6] = args[2];
+ scsi_cmd[8] = args[3];
+ scsi_cmd[10] = args[4];
+ scsi_cmd[12] = args[5];
+ scsi_cmd[14] = args[0];
+
+ sreq = scsi_allocate_request(scsidev, GFP_KERNEL);
+ if (!sreq) {
+ rc = -EINTR;
+ goto error;
+ }
+
+ sreq->sr_data_direction = DMA_NONE;
+ /* Good values for timeout and retries? Values below
+ from scsi_ioctl_send_command() for default case... */
+ scsi_wait_req(sreq, scsi_cmd, NULL, 0, (10*HZ), 5);
+
+ if (sreq->sr_result) {
+ rc = -EIO;
+ goto error;
+ }
+
+ /* Need code to retrieve data from check condition? */
+
+error:
+ scsi_release_request(sreq);
+ return rc;
+}
+
int ata_scsi_ioctl(struct scsi_device *scsidev, int cmd, void __user *arg)
{
struct ata_port *ap;
@@ -107,6 +302,16 @@ int ata_scsi_ioctl(struct scsi_device *scsidev, int cmd, void __user *arg)
return -EINVAL;
return 0;
+ case HDIO_DRIVE_CMD:
+ if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO))
+ return -EACCES;
+ return ata_cmd_ioctl(scsidev, arg);
+
+ case HDIO_DRIVE_TASK:
+ if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO))
+ return -EACCES;
+ return ata_task_ioctl(scsidev, arg);
+
default:
rc = -ENOTTY;
break;
@@ -150,10 +355,10 @@ struct ata_queued_cmd *ata_scsi_qc_new(struct ata_port *ap,
qc->scsidone = done;
if (cmd->use_sg) {
- qc->sg = (struct scatterlist *) cmd->request_buffer;
+ qc->__sg = (struct scatterlist *) cmd->request_buffer;
qc->n_elem = cmd->use_sg;
} else {
- qc->sg = &qc->sgent;
+ qc->__sg = &qc->sgent;
qc->n_elem = 1;
}
} else {
@@ -165,24 +370,71 @@ struct ata_queued_cmd *ata_scsi_qc_new(struct ata_port *ap,
}
/**
+ * ata_dump_status - user friendly display of error info
+ * @id: id of the port in question
+ * @tf: ptr to filled out taskfile
+ *
+ * Decode and dump the ATA error/status registers for the user so
+ * that they have some idea what really happened at the non
+ * make-believe layer.
+ *
+ * LOCKING:
+ * inherited from caller
+ */
+void ata_dump_status(unsigned id, struct ata_taskfile *tf)
+{
+ u8 stat = tf->command, err = tf->feature;
+
+ printk(KERN_WARNING "ata%u: status=0x%02x { ", id, stat);
+ if (stat & ATA_BUSY) {
+ printk("Busy }\n"); /* Data is not valid in this case */
+ } else {
+ if (stat & 0x40) printk("DriveReady ");
+ if (stat & 0x20) printk("DeviceFault ");
+ if (stat & 0x10) printk("SeekComplete ");
+ if (stat & 0x08) printk("DataRequest ");
+ if (stat & 0x04) printk("CorrectedError ");
+ if (stat & 0x02) printk("Index ");
+ if (stat & 0x01) printk("Error ");
+ printk("}\n");
+
+ if (err) {
+ printk(KERN_WARNING "ata%u: error=0x%02x { ", id, err);
+ if (err & 0x04) printk("DriveStatusError ");
+ if (err & 0x80) {
+ if (err & 0x04) printk("BadCRC ");
+ else printk("Sector ");
+ }
+ if (err & 0x40) printk("UncorrectableError ");
+ if (err & 0x10) printk("SectorIdNotFound ");
+ if (err & 0x02) printk("TrackZeroNotFound ");
+ if (err & 0x01) printk("AddrMarkNotFound ");
+ printk("}\n");
+ }
+ }
+}
+
+/**
* ata_to_sense_error - convert ATA error to SCSI error
- * @qc: Command that we are erroring out
+ * @id: ATA device number
* @drv_stat: value contained in ATA status register
+ * @drv_err: value contained in ATA error register
+ * @sk: the sense key we'll fill out
+ * @asc: the additional sense code we'll fill out
+ * @ascq: the additional sense code qualifier we'll fill out
*
- * Converts an ATA error into a SCSI error. While we are at it
- * we decode and dump the ATA error for the user so that they
- * have some idea what really happened at the non make-believe
- * layer.
+ * Converts an ATA error into a SCSI error. Fill out pointers to
+ * SK, ASC, and ASCQ bytes for later use in fixed or descriptor
+ * format sense blocks.
*
* LOCKING:
* spin_lock_irqsave(host_set lock)
*/
-
-void ata_to_sense_error(struct ata_queued_cmd *qc, u8 drv_stat)
+void ata_to_sense_error(unsigned id, u8 drv_stat, u8 drv_err, u8 *sk, u8 *asc,
+ u8 *ascq)
{
- struct scsi_cmnd *cmd = qc->scsicmd;
- u8 err = 0;
- unsigned char *sb = cmd->sense_buffer;
+ int i;
+
/* Based on the 3ware driver translation table */
static unsigned char sense_table[][4] = {
/* BBD|ECC|ID|MAR */
@@ -223,105 +475,192 @@ void ata_to_sense_error(struct ata_queued_cmd *qc, u8 drv_stat)
{0x04, RECOVERED_ERROR, 0x11, 0x00}, // Recovered ECC error Medium error, recovered
{0xFF, 0xFF, 0xFF, 0xFF}, // END mark
};
- int i = 0;
-
- cmd->result = SAM_STAT_CHECK_CONDITION;
/*
* Is this an error we can process/parse
*/
+ if (drv_stat & ATA_BUSY) {
+ drv_err = 0; /* Ignore the err bits, they're invalid */
+ }
- if(drv_stat & ATA_ERR)
- /* Read the err bits */
- err = ata_chk_err(qc->ap);
+ if (drv_err) {
+ /* Look for drv_err */
+ for (i = 0; sense_table[i][0] != 0xFF; i++) {
+ /* Look for best matches first */
+ if ((sense_table[i][0] & drv_err) ==
+ sense_table[i][0]) {
+ *sk = sense_table[i][1];
+ *asc = sense_table[i][2];
+ *ascq = sense_table[i][3];
+ goto translate_done;
+ }
+ }
+ /* No immediate match */
+ printk(KERN_WARNING "ata%u: no sense translation for "
+ "error 0x%02x\n", id, drv_err);
+ }
- /* Display the ATA level error info */
+ /* Fall back to interpreting status bits */
+ for (i = 0; stat_table[i][0] != 0xFF; i++) {
+ if (stat_table[i][0] & drv_stat) {
+ *sk = stat_table[i][1];
+ *asc = stat_table[i][2];
+ *ascq = stat_table[i][3];
+ goto translate_done;
+ }
+ }
+ /* No error? Undecoded? */
+ printk(KERN_WARNING "ata%u: no sense translation for status: 0x%02x\n",
+ id, drv_stat);
+
+ /* For our last chance pick, use medium read error because
+ * it's much more common than an ATA drive telling you a write
+ * has failed.
+ */
+ *sk = MEDIUM_ERROR;
+ *asc = 0x11; /* "unrecovered read error" */
+ *ascq = 0x04; /* "auto-reallocation failed" */
+
+ translate_done:
+ printk(KERN_ERR "ata%u: translated ATA stat/err 0x%02x/%02x to "
+ "SCSI SK/ASC/ASCQ 0x%x/%02x/%02x\n", id, drv_stat, drv_err,
+ *sk, *asc, *ascq);
+ return;
+}
- printk(KERN_WARNING "ata%u: status=0x%02x { ", qc->ap->id, drv_stat);
- if(drv_stat & 0x80)
- {
- printk("Busy ");
- err = 0; /* Data is not valid in this case */
+/*
+ * ata_gen_ata_desc_sense - Generate check condition sense block.
+ * @qc: Command that completed.
+ *
+ * This function is specific to the ATA descriptor format sense
+ * block specified for the ATA pass through commands. Regardless
+ * of whether the command errored or not, return a sense
+ * block. Copy all controller registers into the sense
+ * block. Clear sense key, ASC & ASCQ if there is no error.
+ *
+ * LOCKING:
+ * spin_lock_irqsave(host_set lock)
+ */
+void ata_gen_ata_desc_sense(struct ata_queued_cmd *qc)
+{
+ struct scsi_cmnd *cmd = qc->scsicmd;
+ struct ata_taskfile *tf = &qc->tf;
+ unsigned char *sb = cmd->sense_buffer;
+ unsigned char *desc = sb + 8;
+
+ memset(sb, 0, SCSI_SENSE_BUFFERSIZE);
+
+ cmd->result = (DRIVER_SENSE << 24) | SAM_STAT_CHECK_CONDITION;
+
+ /*
+ * Read the controller registers.
+ */
+ assert(NULL != qc->ap->ops->tf_read);
+ qc->ap->ops->tf_read(qc->ap, tf);
+
+ /*
+ * Use ata_to_sense_error() to map status register bits
+ * onto sense key, asc & ascq.
+ */
+ if (tf->command & (ATA_BUSY | ATA_DF | ATA_ERR | ATA_DRQ)) {
+ ata_to_sense_error(qc->ap->id, tf->command, tf->feature,
+ &sb[1], &sb[2], &sb[3]);
+ sb[1] &= 0x0f;
}
- else {
- if(drv_stat & 0x40) printk("DriveReady ");
- if(drv_stat & 0x20) printk("DeviceFault ");
- if(drv_stat & 0x10) printk("SeekComplete ");
- if(drv_stat & 0x08) printk("DataRequest ");
- if(drv_stat & 0x04) printk("CorrectedError ");
- if(drv_stat & 0x02) printk("Index ");
- if(drv_stat & 0x01) printk("Error ");
+
+ /*
+ * Sense data is current and format is descriptor.
+ */
+ sb[0] = 0x72;
+
+ desc[0] = 0x09;
+
+ /*
+ * Set length of additional sense data.
+ * Since we only populate descriptor 0, the total
+ * length is the same (fixed) length as descriptor 0.
+ */
+ desc[1] = sb[7] = 14;
+
+ /*
+ * Copy registers into sense buffer.
+ */
+ desc[2] = 0x00;
+ desc[3] = tf->feature; /* == error reg */
+ desc[5] = tf->nsect;
+ desc[7] = tf->lbal;
+ desc[9] = tf->lbam;
+ desc[11] = tf->lbah;
+ desc[12] = tf->device;
+ desc[13] = tf->command; /* == status reg */
+
+ /*
+ * Fill in Extend bit, and the high order bytes
+ * if applicable.
+ */
+ if (tf->flags & ATA_TFLAG_LBA48) {
+ desc[2] |= 0x01;
+ desc[4] = tf->hob_nsect;
+ desc[6] = tf->hob_lbal;
+ desc[8] = tf->hob_lbam;
+ desc[10] = tf->hob_lbah;
}
- printk("}\n");
-
- if(err)
- {
- printk(KERN_WARNING "ata%u: error=0x%02x { ", qc->ap->id, err);
- if(err & 0x04) printk("DriveStatusError ");
- if(err & 0x80)
- {
- if(err & 0x04)
- printk("BadCRC ");
- else
- printk("Sector ");
- }
- if(err & 0x40) printk("UncorrectableError ");
- if(err & 0x10) printk("SectorIdNotFound ");
- if(err & 0x02) printk("TrackZeroNotFound ");
- if(err & 0x01) printk("AddrMarkNotFound ");
- printk("}\n");
+}
- /* Should we dump sector info here too ?? */
+/**
+ * ata_gen_fixed_sense - generate a SCSI fixed sense block
+ * @qc: Command that we are erroring out
+ *
+ * Leverage ata_to_sense_error() to give us the codes. Fit our
+ * LBA in here if there's room.
+ *
+ * LOCKING:
+ * inherited from caller
+ */
+void ata_gen_fixed_sense(struct ata_queued_cmd *qc)
+{
+ struct scsi_cmnd *cmd = qc->scsicmd;
+ struct ata_taskfile *tf = &qc->tf;
+ unsigned char *sb = cmd->sense_buffer;
+
+ memset(sb, 0, SCSI_SENSE_BUFFERSIZE);
+
+ cmd->result = (DRIVER_SENSE << 24) | SAM_STAT_CHECK_CONDITION;
+
+ /*
+ * Read the controller registers.
+ */
+ assert(NULL != qc->ap->ops->tf_read);
+ qc->ap->ops->tf_read(qc->ap, tf);
+
+ /*
+ * Use ata_to_sense_error() to map status register bits
+ * onto sense key, asc & ascq.
+ */
+ if (tf->command & (ATA_BUSY | ATA_DF | ATA_ERR | ATA_DRQ)) {
+ ata_to_sense_error(qc->ap->id, tf->command, tf->feature,
+ &sb[2], &sb[12], &sb[13]);
+ sb[2] &= 0x0f;
}
+ sb[0] = 0x70;
+ sb[7] = 0x0a;
- /* Look for err */
- while(sense_table[i][0] != 0xFF)
- {
- /* Look for best matches first */
- if((sense_table[i][0] & err) == sense_table[i][0])
- {
- sb[0] = 0x70;
- sb[2] = sense_table[i][1];
- sb[7] = 0x0a;
- sb[12] = sense_table[i][2];
- sb[13] = sense_table[i][3];
- return;
- }
- i++;
+ if (tf->flags & ATA_TFLAG_LBA48) {
+ /* TODO: find solution for LBA48 descriptors */
}
- /* No immediate match */
- if(err)
- printk(KERN_DEBUG "ata%u: no sense translation for 0x%02x\n", qc->ap->id, err);
- i = 0;
- /* Fall back to interpreting status bits */
- while(stat_table[i][0] != 0xFF)
- {
- if(stat_table[i][0] & drv_stat)
- {
- sb[0] = 0x70;
- sb[2] = stat_table[i][1];
- sb[7] = 0x0a;
- sb[12] = stat_table[i][2];
- sb[13] = stat_table[i][3];
- return;
- }
- i++;
+ else if (tf->flags & ATA_TFLAG_LBA) {
+ /* A small (28b) LBA will fit in the 32b info field */
+ sb[0] |= 0x80; /* set valid bit */
+ sb[3] = tf->device & 0x0f;
+ sb[4] = tf->lbah;
+ sb[5] = tf->lbam;
+ sb[6] = tf->lbal;
}
- /* No error ?? */
- printk(KERN_ERR "ata%u: called with no error (%02X)!\n", qc->ap->id, drv_stat);
- /* additional-sense-code[-qualifier] */
- sb[0] = 0x70;
- sb[2] = MEDIUM_ERROR;
- sb[7] = 0x0A;
- if (cmd->sc_data_direction == DMA_FROM_DEVICE) {
- sb[12] = 0x11; /* "unrecovered read error" */
- sb[13] = 0x04;
- } else {
- sb[12] = 0x0C; /* "write error - */
- sb[13] = 0x02; /* auto-reallocation failed" */
+ else {
+ /* TODO: C/H/S */
}
}
@@ -364,6 +703,16 @@ int ata_scsi_slave_config(struct scsi_device *sdev)
*/
blk_queue_max_sectors(sdev->request_queue, 2048);
}
+
+ /*
+ * SATA DMA transfers must be multiples of 4 byte, so
+ * we need to pad ATAPI transfers using an extra sg.
+ * Decrement max hw segments accordingly.
+ */
+ if (dev->class == ATA_DEV_ATAPI) {
+ request_queue_t *q = sdev->request_queue;
+ blk_queue_max_hw_segments(q, q->max_hw_segments - 1);
+ }
}
return 0; /* scsi layer doesn't check return value, sigh */
@@ -420,7 +769,7 @@ int ata_scsi_error(struct Scsi_Host *host)
*/
static unsigned int ata_scsi_start_stop_xlat(struct ata_queued_cmd *qc,
- u8 *scsicmd)
+ const u8 *scsicmd)
{
struct ata_taskfile *tf = &qc->tf;
@@ -430,15 +779,26 @@ static unsigned int ata_scsi_start_stop_xlat(struct ata_queued_cmd *qc,
; /* ignore IMMED bit, violates sat-r05 */
}
if (scsicmd[4] & 0x2)
- return 1; /* LOEJ bit set not supported */
+ goto invalid_fld; /* LOEJ bit set not supported */
if (((scsicmd[4] >> 4) & 0xf) != 0)
- return 1; /* power conditions not supported */
+ goto invalid_fld; /* power conditions not supported */
if (scsicmd[4] & 0x1) {
tf->nsect = 1; /* 1 sector, lba=0 */
- tf->lbah = 0x0;
- tf->lbam = 0x0;
- tf->lbal = 0x0;
- tf->device |= ATA_LBA;
+
+ if (qc->dev->flags & ATA_DFLAG_LBA) {
+ qc->tf.flags |= ATA_TFLAG_LBA;
+
+ tf->lbah = 0x0;
+ tf->lbam = 0x0;
+ tf->lbal = 0x0;
+ tf->device |= ATA_LBA;
+ } else {
+ /* CHS */
+ tf->lbal = 0x1; /* sect */
+ tf->lbam = 0x0; /* cyl low */
+ tf->lbah = 0x0; /* cyl high */
+ }
+
tf->command = ATA_CMD_VERIFY; /* READ VERIFY */
} else {
tf->nsect = 0; /* time period value (0 implies now) */
@@ -453,6 +813,11 @@ static unsigned int ata_scsi_start_stop_xlat(struct ata_queued_cmd *qc,
*/
return 0;
+
+invalid_fld:
+ ata_scsi_set_sense(qc->scsicmd, ILLEGAL_REQUEST, 0x24, 0x0);
+ /* "Invalid field in cbd" */
+ return 1;
}
@@ -471,14 +836,14 @@ static unsigned int ata_scsi_start_stop_xlat(struct ata_queued_cmd *qc,
* Zero on success, non-zero on error.
*/
-static unsigned int ata_scsi_flush_xlat(struct ata_queued_cmd *qc, u8 *scsicmd)
+static unsigned int ata_scsi_flush_xlat(struct ata_queued_cmd *qc, const u8 *scsicmd)
{
struct ata_taskfile *tf = &qc->tf;
tf->flags |= ATA_TFLAG_DEVICE;
tf->protocol = ATA_PROT_NODATA;
- if ((tf->flags & ATA_TFLAG_LBA48) &&
+ if ((qc->dev->flags & ATA_DFLAG_LBA48) &&
(ata_id_has_flush_ext(qc->dev->id)))
tf->command = ATA_CMD_FLUSH_EXT;
else
@@ -488,6 +853,99 @@ static unsigned int ata_scsi_flush_xlat(struct ata_queued_cmd *qc, u8 *scsicmd)
}
/**
+ * scsi_6_lba_len - Get LBA and transfer length
+ * @scsicmd: SCSI command to translate
+ *
+ * Calculate LBA and transfer length for 6-byte commands.
+ *
+ * RETURNS:
+ * @plba: the LBA
+ * @plen: the transfer length
+ */
+
+static void scsi_6_lba_len(const u8 *scsicmd, u64 *plba, u32 *plen)
+{
+ u64 lba = 0;
+ u32 len = 0;
+
+ VPRINTK("six-byte command\n");
+
+ lba |= ((u64)scsicmd[2]) << 8;
+ lba |= ((u64)scsicmd[3]);
+
+ len |= ((u32)scsicmd[4]);
+
+ *plba = lba;
+ *plen = len;
+}
+
+/**
+ * scsi_10_lba_len - Get LBA and transfer length
+ * @scsicmd: SCSI command to translate
+ *
+ * Calculate LBA and transfer length for 10-byte commands.
+ *
+ * RETURNS:
+ * @plba: the LBA
+ * @plen: the transfer length
+ */
+
+static void scsi_10_lba_len(const u8 *scsicmd, u64 *plba, u32 *plen)
+{
+ u64 lba = 0;
+ u32 len = 0;
+
+ VPRINTK("ten-byte command\n");
+
+ lba |= ((u64)scsicmd[2]) << 24;
+ lba |= ((u64)scsicmd[3]) << 16;
+ lba |= ((u64)scsicmd[4]) << 8;
+ lba |= ((u64)scsicmd[5]);
+
+ len |= ((u32)scsicmd[7]) << 8;
+ len |= ((u32)scsicmd[8]);
+
+ *plba = lba;
+ *plen = len;
+}
+
+/**
+ * scsi_16_lba_len - Get LBA and transfer length
+ * @scsicmd: SCSI command to translate
+ *
+ * Calculate LBA and transfer length for 16-byte commands.
+ *
+ * RETURNS:
+ * @plba: the LBA
+ * @plen: the transfer length
+ */
+
+static void scsi_16_lba_len(const u8 *scsicmd, u64 *plba, u32 *plen)
+{
+ u64 lba = 0;
+ u32 len = 0;
+
+ VPRINTK("sixteen-byte command\n");
+
+ lba |= ((u64)scsicmd[2]) << 56;
+ lba |= ((u64)scsicmd[3]) << 48;
+ lba |= ((u64)scsicmd[4]) << 40;
+ lba |= ((u64)scsicmd[5]) << 32;
+ lba |= ((u64)scsicmd[6]) << 24;
+ lba |= ((u64)scsicmd[7]) << 16;
+ lba |= ((u64)scsicmd[8]) << 8;
+ lba |= ((u64)scsicmd[9]);
+
+ len |= ((u32)scsicmd[10]) << 24;
+ len |= ((u32)scsicmd[11]) << 16;
+ len |= ((u32)scsicmd[12]) << 8;
+ len |= ((u32)scsicmd[13]);
+
+ *plba = lba;
+ *plen = len;
+}
+
+/**
* ata_scsi_verify_xlat - Translate SCSI VERIFY command into an ATA one
* @qc: Storage for translated ATA taskfile
* @scsicmd: SCSI command to translate
@@ -501,82 +959,110 @@ static unsigned int ata_scsi_flush_xlat(struct ata_queued_cmd *qc, u8 *scsicmd)
* Zero on success, non-zero on error.
*/
-static unsigned int ata_scsi_verify_xlat(struct ata_queued_cmd *qc, u8 *scsicmd)
+static unsigned int ata_scsi_verify_xlat(struct ata_queued_cmd *qc, const u8 *scsicmd)
{
struct ata_taskfile *tf = &qc->tf;
- unsigned int lba48 = tf->flags & ATA_TFLAG_LBA48;
+ struct ata_device *dev = qc->dev;
u64 dev_sectors = qc->dev->n_sectors;
- u64 sect = 0;
- u32 n_sect = 0;
+ u64 block;
+ u32 n_block;
tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
tf->protocol = ATA_PROT_NODATA;
- tf->device |= ATA_LBA;
- if (scsicmd[0] == VERIFY) {
- sect |= ((u64)scsicmd[2]) << 24;
- sect |= ((u64)scsicmd[3]) << 16;
- sect |= ((u64)scsicmd[4]) << 8;
- sect |= ((u64)scsicmd[5]);
+ if (scsicmd[0] == VERIFY)
+ scsi_10_lba_len(scsicmd, &block, &n_block);
+ else if (scsicmd[0] == VERIFY_16)
+ scsi_16_lba_len(scsicmd, &block, &n_block);
+ else
+ goto invalid_fld;
- n_sect |= ((u32)scsicmd[7]) << 8;
- n_sect |= ((u32)scsicmd[8]);
- }
+ if (!n_block)
+ goto nothing_to_do;
+ if (block >= dev_sectors)
+ goto out_of_range;
+ if ((block + n_block) > dev_sectors)
+ goto out_of_range;
- else if (scsicmd[0] == VERIFY_16) {
- sect |= ((u64)scsicmd[2]) << 56;
- sect |= ((u64)scsicmd[3]) << 48;
- sect |= ((u64)scsicmd[4]) << 40;
- sect |= ((u64)scsicmd[5]) << 32;
- sect |= ((u64)scsicmd[6]) << 24;
- sect |= ((u64)scsicmd[7]) << 16;
- sect |= ((u64)scsicmd[8]) << 8;
- sect |= ((u64)scsicmd[9]);
-
- n_sect |= ((u32)scsicmd[10]) << 24;
- n_sect |= ((u32)scsicmd[11]) << 16;
- n_sect |= ((u32)scsicmd[12]) << 8;
- n_sect |= ((u32)scsicmd[13]);
- }
+ if (dev->flags & ATA_DFLAG_LBA) {
+ tf->flags |= ATA_TFLAG_LBA;
- else
- return 1;
+ if (dev->flags & ATA_DFLAG_LBA48) {
+ if (n_block > (64 * 1024))
+ goto invalid_fld;
- if (!n_sect)
- return 1;
- if (sect >= dev_sectors)
- return 1;
- if ((sect + n_sect) > dev_sectors)
- return 1;
- if (lba48) {
- if (n_sect > (64 * 1024))
- return 1;
- } else {
- if (n_sect > 256)
- return 1;
- }
+ /* use LBA48 */
+ tf->flags |= ATA_TFLAG_LBA48;
+ tf->command = ATA_CMD_VERIFY_EXT;
- if (lba48) {
- tf->command = ATA_CMD_VERIFY_EXT;
+ tf->hob_nsect = (n_block >> 8) & 0xff;
+
+ tf->hob_lbah = (block >> 40) & 0xff;
+ tf->hob_lbam = (block >> 32) & 0xff;
+ tf->hob_lbal = (block >> 24) & 0xff;
+ } else {
+ if (n_block > 256)
+ goto invalid_fld;
+
+ /* use LBA28 */
+ tf->command = ATA_CMD_VERIFY;
+
+ tf->device |= (block >> 24) & 0xf;
+ }
- tf->hob_nsect = (n_sect >> 8) & 0xff;
+ tf->nsect = n_block & 0xff;
- tf->hob_lbah = (sect >> 40) & 0xff;
- tf->hob_lbam = (sect >> 32) & 0xff;
- tf->hob_lbal = (sect >> 24) & 0xff;
+ tf->lbah = (block >> 16) & 0xff;
+ tf->lbam = (block >> 8) & 0xff;
+ tf->lbal = block & 0xff;
+
+ tf->device |= ATA_LBA;
} else {
+ /* CHS */
+ u32 sect, head, cyl, track;
+
+ if (n_block > 256)
+ goto invalid_fld;
+
+ /* Convert LBA to CHS */
+ track = (u32)block / dev->sectors;
+ cyl = track / dev->heads;
+ head = track % dev->heads;
+ sect = (u32)block % dev->sectors + 1;
+
+ DPRINTK("block %u track %u cyl %u head %u sect %u\n",
+ (u32)block, track, cyl, head, sect);
+
+ /* Check whether the converted CHS can fit.
+ Cylinder: 0-65535
+ Head: 0-15
+ Sector: 1-255*/
+ if ((cyl >> 16) || (head >> 4) || (sect >> 8) || (!sect))
+ goto out_of_range;
+
tf->command = ATA_CMD_VERIFY;
-
- tf->device |= (sect >> 24) & 0xf;
+ tf->nsect = n_block & 0xff; /* Sector count 0 means 256 sectors */
+ tf->lbal = sect;
+ tf->lbam = cyl;
+ tf->lbah = cyl >> 8;
+ tf->device |= head;
}
- tf->nsect = n_sect & 0xff;
+ return 0;
- tf->lbah = (sect >> 16) & 0xff;
- tf->lbam = (sect >> 8) & 0xff;
- tf->lbal = sect & 0xff;
+invalid_fld:
+ ata_scsi_set_sense(qc->scsicmd, ILLEGAL_REQUEST, 0x24, 0x0);
+ /* "Invalid field in cbd" */
+ return 1;
- return 0;
+out_of_range:
+ ata_scsi_set_sense(qc->scsicmd, ILLEGAL_REQUEST, 0x21, 0x0);
+ /* "Logical Block Address out of range" */
+ return 1;
+
+nothing_to_do:
+ qc->scsicmd->result = SAM_STAT_GOOD;
+ return 1;
}
/**
@@ -599,117 +1085,175 @@ static unsigned int ata_scsi_verify_xlat(struct ata_queued_cmd *qc, u8 *scsicmd)
* Zero on success, non-zero on error.
*/
-static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, u8 *scsicmd)
+static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, const u8 *scsicmd)
{
struct ata_taskfile *tf = &qc->tf;
- unsigned int lba48 = tf->flags & ATA_TFLAG_LBA48;
+ struct ata_device *dev = qc->dev;
+ u64 block;
+ u32 n_block;
tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
- tf->protocol = qc->dev->xfer_protocol;
- tf->device |= ATA_LBA;
- if (scsicmd[0] == READ_10 || scsicmd[0] == READ_6 ||
- scsicmd[0] == READ_16) {
- tf->command = qc->dev->read_cmd;
- } else {
- tf->command = qc->dev->write_cmd;
+ if (scsicmd[0] == WRITE_10 || scsicmd[0] == WRITE_6 ||
+ scsicmd[0] == WRITE_16)
tf->flags |= ATA_TFLAG_WRITE;
- }
- if (scsicmd[0] == READ_10 || scsicmd[0] == WRITE_10) {
- if (lba48) {
- tf->hob_nsect = scsicmd[7];
- tf->hob_lbal = scsicmd[2];
+ /* Calculate the SCSI LBA and transfer length. */
+ switch (scsicmd[0]) {
+ case READ_10:
+ case WRITE_10:
+ scsi_10_lba_len(scsicmd, &block, &n_block);
+ break;
+ case READ_6:
+ case WRITE_6:
+ scsi_6_lba_len(scsicmd, &block, &n_block);
- qc->nsect = ((unsigned int)scsicmd[7] << 8) |
- scsicmd[8];
- } else {
- /* if we don't support LBA48 addressing, the request
- * -may- be too large. */
- if ((scsicmd[2] & 0xf0) || scsicmd[7])
- return 1;
+ /* for 6-byte r/w commands, transfer length 0
+ * means 256 blocks of data, not 0 block.
+ */
+ if (!n_block)
+ n_block = 256;
+ break;
+ case READ_16:
+ case WRITE_16:
+ scsi_16_lba_len(scsicmd, &block, &n_block);
+ break;
+ default:
+ DPRINTK("no-byte command\n");
+ goto invalid_fld;
+ }
- /* stores LBA27:24 in lower 4 bits of device reg */
- tf->device |= scsicmd[2];
+ /* Check and compose ATA command */
+ if (!n_block)
+ /* For 10-byte and 16-byte SCSI R/W commands, transfer
+ * length 0 means transfer 0 block of data.
+ * However, for ATA R/W commands, sector count 0 means
+ * 256 or 65536 sectors, not 0 sectors as in SCSI.
+ */
+ goto nothing_to_do;
- qc->nsect = scsicmd[8];
- }
+ if (dev->flags & ATA_DFLAG_LBA) {
+ tf->flags |= ATA_TFLAG_LBA;
- tf->nsect = scsicmd[8];
- tf->lbal = scsicmd[5];
- tf->lbam = scsicmd[4];
- tf->lbah = scsicmd[3];
+ if (dev->flags & ATA_DFLAG_LBA48) {
+ /* The request -may- be too large for LBA48. */
+ if ((block >> 48) || (n_block > 65536))
+ goto out_of_range;
- VPRINTK("ten-byte command\n");
- if (qc->nsect == 0) /* we don't support length==0 cmds */
- return 1;
- return 0;
- }
+ /* use LBA48 */
+ tf->flags |= ATA_TFLAG_LBA48;
- if (scsicmd[0] == READ_6 || scsicmd[0] == WRITE_6) {
- qc->nsect = tf->nsect = scsicmd[4];
- if (!qc->nsect) {
- qc->nsect = 256;
- if (lba48)
- tf->hob_nsect = 1;
- }
+ tf->hob_nsect = (n_block >> 8) & 0xff;
- tf->lbal = scsicmd[3];
- tf->lbam = scsicmd[2];
- tf->lbah = scsicmd[1] & 0x1f; /* mask out reserved bits */
+ tf->hob_lbah = (block >> 40) & 0xff;
+ tf->hob_lbam = (block >> 32) & 0xff;
+ tf->hob_lbal = (block >> 24) & 0xff;
+ } else {
+ /* use LBA28 */
- VPRINTK("six-byte command\n");
- return 0;
- }
+ /* The request -may- be too large for LBA28. */
+ if ((block >> 28) || (n_block > 256))
+ goto out_of_range;
- if (scsicmd[0] == READ_16 || scsicmd[0] == WRITE_16) {
- /* rule out impossible LBAs and sector counts */
- if (scsicmd[2] || scsicmd[3] || scsicmd[10] || scsicmd[11])
- return 1;
+ tf->device |= (block >> 24) & 0xf;
+ }
- if (lba48) {
- tf->hob_nsect = scsicmd[12];
- tf->hob_lbal = scsicmd[6];
- tf->hob_lbam = scsicmd[5];
- tf->hob_lbah = scsicmd[4];
+ ata_rwcmd_protocol(qc);
- qc->nsect = ((unsigned int)scsicmd[12] << 8) |
- scsicmd[13];
- } else {
- /* once again, filter out impossible non-zero values */
- if (scsicmd[4] || scsicmd[5] || scsicmd[12] ||
- (scsicmd[6] & 0xf0))
- return 1;
+ qc->nsect = n_block;
+ tf->nsect = n_block & 0xff;
- /* stores LBA27:24 in lower 4 bits of device reg */
- tf->device |= scsicmd[6];
+ tf->lbah = (block >> 16) & 0xff;
+ tf->lbam = (block >> 8) & 0xff;
+ tf->lbal = block & 0xff;
- qc->nsect = scsicmd[13];
- }
+ tf->device |= ATA_LBA;
+ } else {
+ /* CHS */
+ u32 sect, head, cyl, track;
+
+ /* The request -may- be too large for CHS addressing. */
+ if ((block >> 28) || (n_block > 256))
+ goto out_of_range;
+
+ ata_rwcmd_protocol(qc);
+
+ /* Convert LBA to CHS */
+ track = (u32)block / dev->sectors;
+ cyl = track / dev->heads;
+ head = track % dev->heads;
+ sect = (u32)block % dev->sectors + 1;
+
+ DPRINTK("block %u track %u cyl %u head %u sect %u\n",
+ (u32)block, track, cyl, head, sect);
+
+ /* Check whether the converted CHS can fit.
+ Cylinder: 0-65535
+ Head: 0-15
+ Sector: 1-255*/
+ if ((cyl >> 16) || (head >> 4) || (sect >> 8) || (!sect))
+ goto out_of_range;
+
+ qc->nsect = n_block;
+ tf->nsect = n_block & 0xff; /* Sector count 0 means 256 sectors */
+ tf->lbal = sect;
+ tf->lbam = cyl;
+ tf->lbah = cyl >> 8;
+ tf->device |= head;
+ }
- tf->nsect = scsicmd[13];
- tf->lbal = scsicmd[9];
- tf->lbam = scsicmd[8];
- tf->lbah = scsicmd[7];
+ return 0;
- VPRINTK("sixteen-byte command\n");
- if (qc->nsect == 0) /* we don't support length==0 cmds */
- return 1;
- return 0;
- }
+invalid_fld:
+ ata_scsi_set_sense(qc->scsicmd, ILLEGAL_REQUEST, 0x24, 0x0);
+ /* "Invalid field in cbd" */
+ return 1;
- DPRINTK("no-byte command\n");
+out_of_range:
+ ata_scsi_set_sense(qc->scsicmd, ILLEGAL_REQUEST, 0x21, 0x0);
+ /* "Logical Block Address out of range" */
+ return 1;
+
+nothing_to_do:
+ qc->scsicmd->result = SAM_STAT_GOOD;
return 1;
}
-static int ata_scsi_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat)
+static int ata_scsi_qc_complete(struct ata_queued_cmd *qc,
+ unsigned int err_mask)
{
struct scsi_cmnd *cmd = qc->scsicmd;
+ u8 *cdb = cmd->cmnd;
+ int need_sense = (err_mask != 0);
+
+ /* For ATA pass thru (SAT) commands, generate a sense block if
+ * user mandated it or if there's an error. Note that if we
+ * generate because the user forced us to, a check condition
+ * is generated and the ATA register values are returned
+ * whether the command completed successfully or not. If there
+ * was no error, SK, ASC and ASCQ will all be zero.
+ */
+ if (((cdb[0] == ATA_16) || (cdb[0] == ATA_12)) &&
+ ((cdb[2] & 0x20) || need_sense)) {
+ ata_gen_ata_desc_sense(qc);
+ } else {
+ if (!need_sense) {
+ cmd->result = SAM_STAT_GOOD;
+ } else {
+ /* TODO: decide which descriptor format to use
+ * for 48b LBA devices and call that here
+ * instead of the fixed desc, which is only
+ * good for smaller LBA (and maybe CHS?)
+ * devices.
+ */
+ ata_gen_fixed_sense(qc);
+ }
+ }
- if (unlikely(drv_stat & (ATA_ERR | ATA_BUSY | ATA_DRQ)))
- ata_to_sense_error(qc, drv_stat);
- else
- cmd->result = SAM_STAT_GOOD;
+ if (need_sense) {
+ /* The ata_gen_..._sense routines fill in tf */
+ ata_dump_status(qc->ap->id, &qc->tf);
+ }
qc->scsidone(cmd);
@@ -731,6 +1275,12 @@ static int ata_scsi_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat)
* This function sets up an ata_queued_cmd structure for the
* SCSI command, and sends that ata_queued_cmd to the hardware.
*
+ * The xlat_func argument (actor) returns 0 if ready to execute
+ * ATA command, else 1 to finish translation. If 1 is returned
+ * then cmd->result (and possibly cmd->sense_buffer) are assumed
+ * to be set reflecting an error condition or clean (early)
+ * termination.
+ *
* LOCKING:
* spin_lock_irqsave(host_set lock)
*/
@@ -747,7 +1297,7 @@ static void ata_scsi_translate(struct ata_port *ap, struct ata_device *dev,
qc = ata_scsi_qc_new(ap, dev, cmd, done);
if (!qc)
- return;
+ goto err_mem;
/* data is present; dma-map it */
if (cmd->sc_data_direction == DMA_FROM_DEVICE ||
@@ -755,7 +1305,7 @@ static void ata_scsi_translate(struct ata_port *ap, struct ata_device *dev,
if (unlikely(cmd->request_bufflen < 1)) {
printk(KERN_WARNING "ata%u(%u): WARNING: zero len r/w req\n",
ap->id, dev->devno);
- goto err_out;
+ goto err_did;
}
if (cmd->use_sg)
@@ -770,19 +1320,28 @@ static void ata_scsi_translate(struct ata_port *ap, struct ata_device *dev,
qc->complete_fn = ata_scsi_qc_complete;
if (xlat_func(qc, scsicmd))
- goto err_out;
+ goto early_finish;
/* select device, send command to hardware */
if (ata_qc_issue(qc))
- goto err_out;
+ goto err_did;
VPRINTK("EXIT\n");
return;
-err_out:
+early_finish:
+ ata_qc_free(qc);
+ done(cmd);
+ DPRINTK("EXIT - early finish (good or error)\n");
+ return;
+
+err_did:
ata_qc_free(qc);
- ata_bad_cdb(cmd, done);
- DPRINTK("EXIT - badcmd\n");
+err_mem:
+ cmd->result = (DID_ERROR << 16);
+ done(cmd);
+ DPRINTK("EXIT - internal\n");
+ return;
}
/**
@@ -849,7 +1408,8 @@ static inline void ata_scsi_rbuf_put(struct scsi_cmnd *cmd, u8 *buf)
* Mapping the response buffer, calling the command's handler,
* and handling the handler's return value. This return value
* indicates whether the handler wishes the SCSI command to be
- * completed successfully, or not.
+ * completed successfully (0), or not (in which case cmd->result
+ * and sense buffer are assumed to be set).
*
* LOCKING:
* spin_lock_irqsave(host_set lock)
@@ -868,12 +1428,9 @@ void ata_scsi_rbuf_fill(struct ata_scsi_args *args,
rc = actor(args, rbuf, buflen);
ata_scsi_rbuf_put(cmd, rbuf);
- if (rc)
- ata_bad_cdb(cmd, args->done);
- else {
+ if (rc == 0)
cmd->result = SAM_STAT_GOOD;
- args->done(cmd);
- }
+ args->done(cmd);
}
/**
@@ -1087,13 +1644,9 @@ static void ata_msense_push(u8 **ptr_io, const u8 *last,
static unsigned int ata_msense_caching(u16 *id, u8 **ptr_io,
const u8 *last)
{
- u8 page[] = {
- 0x8, /* page code */
- 0x12, /* page length */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 10 zeroes */
- 0, 0, 0, 0, 0, 0, 0, 0 /* 8 zeroes */
- };
+ u8 page[CACHE_MPAGE_LEN];
+ memcpy(page, def_cache_mpage, sizeof(page));
if (ata_id_wcache_enabled(id))
page[2] |= (1 << 2); /* write cache enable */
if (!ata_id_rahead_enabled(id))
@@ -1117,15 +1670,9 @@ static unsigned int ata_msense_caching(u16 *id, u8 **ptr_io,
static unsigned int ata_msense_ctl_mode(u8 **ptr_io, const u8 *last)
{
- const u8 page[] = {0xa, 0xa, 6, 0, 0, 0, 0, 0, 0xff, 0xff, 0, 30};
-
- /* byte 2: set the descriptor format sense data bit (bit 2)
- * since we need to support returning this format for SAT
- * commands and any SCSI commands against a 48b LBA device.
- */
-
- ata_msense_push(ptr_io, last, page, sizeof(page));
- return sizeof(page);
+ ata_msense_push(ptr_io, last, def_control_mpage,
+ sizeof(def_control_mpage));
+ return sizeof(def_control_mpage);
}
/**
@@ -1142,15 +1689,10 @@ static unsigned int ata_msense_ctl_mode(u8 **ptr_io, const u8 *last)
static unsigned int ata_msense_rw_recovery(u8 **ptr_io, const u8 *last)
{
- const u8 page[] = {
- 0x1, /* page code */
- 0xa, /* page length */
- (1 << 7) | (1 << 6), /* note auto r/w reallocation */
- 0, 0, 0, 0, 0, 0, 0, 0, 0 /* 9 zeroes */
- };
- ata_msense_push(ptr_io, last, page, sizeof(page));
- return sizeof(page);
+ ata_msense_push(ptr_io, last, def_rw_recovery_mpage,
+ sizeof(def_rw_recovery_mpage));
+ return sizeof(def_rw_recovery_mpage);
}
/**
@@ -1159,7 +1701,9 @@ static unsigned int ata_msense_rw_recovery(u8 **ptr_io, const u8 *last)
* @rbuf: Response buffer, to which simulated SCSI cmd output is sent.
* @buflen: Response buffer length.
*
- * Simulate MODE SENSE commands.
+ * Simulate MODE SENSE commands. Assume this is invoked for direct
+ * access devices (e.g. disks) only. There should be no block
+ * descriptor for other device types.
*
* LOCKING:
* spin_lock_irqsave(host_set lock)
@@ -1169,61 +1713,115 @@ unsigned int ata_scsiop_mode_sense(struct ata_scsi_args *args, u8 *rbuf,
unsigned int buflen)
{
u8 *scsicmd = args->cmd->cmnd, *p, *last;
- unsigned int page_control, six_byte, output_len;
+ const u8 sat_blk_desc[] = {
+ 0, 0, 0, 0, /* number of blocks: sat unspecified */
+ 0,
+ 0, 0x2, 0x0 /* block length: 512 bytes */
+ };
+ u8 pg, spg;
+ unsigned int ebd, page_control, six_byte, output_len, alloc_len, minlen;
VPRINTK("ENTER\n");
six_byte = (scsicmd[0] == MODE_SENSE);
-
- /* we only support saved and current values (which we treat
- * in the same manner)
+ ebd = !(scsicmd[1] & 0x8); /* dbd bit inverted == edb */
+ /*
+ * LLBA bit in msense(10) ignored (compliant)
*/
+
page_control = scsicmd[2] >> 6;
- if ((page_control != 0) && (page_control != 3))
- return 1;
+ switch (page_control) {
+ case 0: /* current */
+ break; /* supported */
+ case 3: /* saved */
+ goto saving_not_supp;
+ case 1: /* changeable */
+ case 2: /* defaults */
+ default:
+ goto invalid_fld;
+ }
- if (six_byte)
- output_len = 4;
- else
- output_len = 8;
+ if (six_byte) {
+ output_len = 4 + (ebd ? 8 : 0);
+ alloc_len = scsicmd[4];
+ } else {
+ output_len = 8 + (ebd ? 8 : 0);
+ alloc_len = (scsicmd[7] << 8) + scsicmd[8];
+ }
+ minlen = (alloc_len < buflen) ? alloc_len : buflen;
p = rbuf + output_len;
- last = rbuf + buflen - 1;
+ last = rbuf + minlen - 1;
- switch(scsicmd[2] & 0x3f) {
- case 0x01: /* r/w error recovery */
+ pg = scsicmd[2] & 0x3f;
+ spg = scsicmd[3];
+ /*
+ * No mode subpages supported (yet) but asking for _all_
+ * subpages may be valid
+ */
+ if (spg && (spg != ALL_SUB_MPAGES))
+ goto invalid_fld;
+
+ switch(pg) {
+ case RW_RECOVERY_MPAGE:
output_len += ata_msense_rw_recovery(&p, last);
break;
- case 0x08: /* caching */
+ case CACHE_MPAGE:
output_len += ata_msense_caching(args->id, &p, last);
break;
- case 0x0a: { /* control mode */
+ case CONTROL_MPAGE: {
output_len += ata_msense_ctl_mode(&p, last);
break;
}
- case 0x3f: /* all pages */
+ case ALL_MPAGES:
output_len += ata_msense_rw_recovery(&p, last);
output_len += ata_msense_caching(args->id, &p, last);
output_len += ata_msense_ctl_mode(&p, last);
break;
default: /* invalid page code */
- return 1;
+ goto invalid_fld;
}
+ if (minlen < 1)
+ return 0;
if (six_byte) {
output_len--;
rbuf[0] = output_len;
+ if (ebd) {
+ if (minlen > 3)
+ rbuf[3] = sizeof(sat_blk_desc);
+ if (minlen > 11)
+ memcpy(rbuf + 4, sat_blk_desc,
+ sizeof(sat_blk_desc));
+ }
} else {
output_len -= 2;
rbuf[0] = output_len >> 8;
- rbuf[1] = output_len;
+ if (minlen > 1)
+ rbuf[1] = output_len;
+ if (ebd) {
+ if (minlen > 7)
+ rbuf[7] = sizeof(sat_blk_desc);
+ if (minlen > 15)
+ memcpy(rbuf + 8, sat_blk_desc,
+ sizeof(sat_blk_desc));
+ }
}
-
return 0;
+
+invalid_fld:
+ ata_scsi_set_sense(args->cmd, ILLEGAL_REQUEST, 0x24, 0x0);
+ /* "Invalid field in cbd" */
+ return 1;
+
+saving_not_supp:
+ ata_scsi_set_sense(args->cmd, ILLEGAL_REQUEST, 0x39, 0x0);
+ /* "Saving parameters not supported" */
+ return 1;
}
/**
@@ -1246,10 +1844,20 @@ unsigned int ata_scsiop_read_cap(struct ata_scsi_args *args, u8 *rbuf,
VPRINTK("ENTER\n");
- if (ata_id_has_lba48(args->id))
- n_sectors = ata_id_u64(args->id, 100);
- else
- n_sectors = ata_id_u32(args->id, 60);
+ if (ata_id_has_lba(args->id)) {
+ if (ata_id_has_lba48(args->id))
+ n_sectors = ata_id_u64(args->id, 100);
+ else
+ n_sectors = ata_id_u32(args->id, 60);
+ } else {
+ /* CHS default translation */
+ n_sectors = args->id[1] * args->id[3] * args->id[6];
+
+ if (ata_id_current_chs_valid(args->id))
+ /* CHS current translation */
+ n_sectors = ata_id_u32(args->id, 57);
+ }
+
n_sectors--; /* ATA TotalUserSectors - 1 */
if (args->cmd->cmnd[0] == READ_CAPACITY) {
@@ -1313,6 +1921,34 @@ unsigned int ata_scsiop_report_luns(struct ata_scsi_args *args, u8 *rbuf,
}
/**
+ * ata_scsi_set_sense - Set SCSI sense data and status
+ * @cmd: SCSI request to be handled
+ * @sk: SCSI-defined sense key
+ * @asc: SCSI-defined additional sense code
+ * @ascq: SCSI-defined additional sense code qualifier
+ *
+ * Helper function that builds a valid fixed format, current
+ * response code and the given sense key (sk), additional sense
+ * code (asc) and additional sense code qualifier (ascq) with
+ * a SCSI command status of %SAM_STAT_CHECK_CONDITION and
+ * DRIVER_SENSE set in the upper bits of scsi_cmnd::result .
+ *
+ * LOCKING:
+ * Not required
+ */
+
+void ata_scsi_set_sense(struct scsi_cmnd *cmd, u8 sk, u8 asc, u8 ascq)
+{
+ cmd->result = (DRIVER_SENSE << 24) | SAM_STAT_CHECK_CONDITION;
+
+ cmd->sense_buffer[0] = 0x70; /* fixed format, current */
+ cmd->sense_buffer[2] = sk;
+ cmd->sense_buffer[7] = 18 - 8; /* additional sense length */
+ cmd->sense_buffer[12] = asc;
+ cmd->sense_buffer[13] = ascq;
+}
+
+/**
* ata_scsi_badcmd - End a SCSI request with an error
* @cmd: SCSI request to be handled
* @done: SCSI command completion function
@@ -1330,30 +1966,89 @@ unsigned int ata_scsiop_report_luns(struct ata_scsi_args *args, u8 *rbuf,
void ata_scsi_badcmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *), u8 asc, u8 ascq)
{
DPRINTK("ENTER\n");
- cmd->result = SAM_STAT_CHECK_CONDITION;
-
- cmd->sense_buffer[0] = 0x70;
- cmd->sense_buffer[2] = ILLEGAL_REQUEST;
- cmd->sense_buffer[7] = 14 - 8; /* addnl. sense len. FIXME: correct? */
- cmd->sense_buffer[12] = asc;
- cmd->sense_buffer[13] = ascq;
+ ata_scsi_set_sense(cmd, ILLEGAL_REQUEST, asc, ascq);
done(cmd);
}
-static int atapi_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat)
+void atapi_request_sense(struct ata_port *ap, struct ata_device *dev,
+ struct scsi_cmnd *cmd)
+{
+ DECLARE_COMPLETION(wait);
+ struct ata_queued_cmd *qc;
+ unsigned long flags;
+ int rc;
+
+ DPRINTK("ATAPI request sense\n");
+
+ qc = ata_qc_new_init(ap, dev);
+ BUG_ON(qc == NULL);
+
+ /* FIXME: is this needed? */
+ memset(cmd->sense_buffer, 0, sizeof(cmd->sense_buffer));
+
+ ata_sg_init_one(qc, cmd->sense_buffer, sizeof(cmd->sense_buffer));
+ qc->dma_dir = DMA_FROM_DEVICE;
+
+ memset(&qc->cdb, 0, ap->cdb_len);
+ qc->cdb[0] = REQUEST_SENSE;
+ qc->cdb[4] = SCSI_SENSE_BUFFERSIZE;
+
+ qc->tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
+ qc->tf.command = ATA_CMD_PACKET;
+
+ qc->tf.protocol = ATA_PROT_ATAPI;
+ qc->tf.lbam = (8 * 1024) & 0xff;
+ qc->tf.lbah = (8 * 1024) >> 8;
+ qc->nbytes = SCSI_SENSE_BUFFERSIZE;
+
+ qc->waiting = &wait;
+ qc->complete_fn = ata_qc_complete_noop;
+
+ spin_lock_irqsave(&ap->host_set->lock, flags);
+ rc = ata_qc_issue(qc);
+ spin_unlock_irqrestore(&ap->host_set->lock, flags);
+
+ if (rc)
+ ata_port_disable(ap);
+ else
+ wait_for_completion(&wait);
+
+ DPRINTK("EXIT\n");
+}
+
+static int atapi_qc_complete(struct ata_queued_cmd *qc, unsigned int err_mask)
{
struct scsi_cmnd *cmd = qc->scsicmd;
- if (unlikely(drv_stat & (ATA_ERR | ATA_BUSY | ATA_DRQ))) {
+ VPRINTK("ENTER, err_mask 0x%X\n", err_mask);
+
+ if (unlikely(err_mask & AC_ERR_DEV)) {
DPRINTK("request check condition\n");
+ /* FIXME: command completion with check condition
+ * but no sense causes the error handler to run,
+ * which then issues REQUEST SENSE, fills in the sense
+ * buffer, and completes the command (for the second
+ * time). We need to issue REQUEST SENSE some other
+ * way, to avoid completing the command twice.
+ */
cmd->result = SAM_STAT_CHECK_CONDITION;
qc->scsidone(cmd);
return 1;
- } else {
+ }
+
+ else if (unlikely(err_mask))
+ /* FIXME: not quite right; we don't want the
+ * translation of taskfile registers into
+ * a sense descriptors, since that's only
+ * correct for ATA, not ATAPI
+ */
+ ata_gen_ata_desc_sense(qc);
+
+ else {
u8 *scsicmd = cmd->cmnd;
if (scsicmd[0] == INQUIRY) {
@@ -1361,15 +2056,30 @@ static int atapi_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat)
unsigned int buflen;
buflen = ata_scsi_rbuf_get(cmd, &buf);
- buf[2] = 0x5;
- buf[3] = (buf[3] & 0xf0) | 2;
+
+ /* ATAPI devices typically report zero for their SCSI version,
+ * and sometimes deviate from the spec WRT response data
+ * format. If SCSI version is reported as zero like normal,
+ * then we make the following fixups: 1) Fake MMC-5 version,
+ * to indicate to the Linux scsi midlayer this is a modern
+ * device. 2) Ensure response data format / ATAPI information
+ * are always correct.
+ */
+ /* FIXME: do we ever override EVPD pages and the like, with
+ * this code?
+ */
+ if (buf[2] == 0) {
+ buf[2] = 0x5;
+ buf[3] = 0x32;
+ }
+
ata_scsi_rbuf_put(cmd, buf);
}
+
cmd->result = SAM_STAT_GOOD;
}
qc->scsidone(cmd);
-
return 0;
}
/**
@@ -1384,7 +2094,7 @@ static int atapi_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat)
* Zero on success, non-zero on failure.
*/
-static unsigned int atapi_xlat(struct ata_queued_cmd *qc, u8 *scsicmd)
+static unsigned int atapi_xlat(struct ata_queued_cmd *qc, const u8 *scsicmd)
{
struct scsi_cmnd *cmd = qc->scsicmd;
struct ata_device *dev = qc->dev;
@@ -1453,7 +2163,7 @@ static unsigned int atapi_xlat(struct ata_queued_cmd *qc, u8 *scsicmd)
*/
static struct ata_device *
-ata_scsi_find_dev(struct ata_port *ap, struct scsi_device *scsidev)
+ata_scsi_find_dev(struct ata_port *ap, const struct scsi_device *scsidev)
{
struct ata_device *dev;
@@ -1478,6 +2188,143 @@ ata_scsi_find_dev(struct ata_port *ap, struct scsi_device *scsidev)
return dev;
}
+/*
+ * ata_scsi_map_proto - Map pass-thru protocol value to taskfile value.
+ * @byte1: Byte 1 from pass-thru CDB.
+ *
+ * RETURNS:
+ * ATA_PROT_UNKNOWN if mapping failed/unimplemented, protocol otherwise.
+ */
+static u8
+ata_scsi_map_proto(u8 byte1)
+{
+ switch((byte1 & 0x1e) >> 1) {
+ case 3: /* Non-data */
+ return ATA_PROT_NODATA;
+
+ case 6: /* DMA */
+ return ATA_PROT_DMA;
+
+ case 4: /* PIO Data-in */
+ case 5: /* PIO Data-out */
+ if (byte1 & 0xe0) {
+ return ATA_PROT_PIO_MULT;
+ }
+ return ATA_PROT_PIO;
+
+ case 10: /* Device Reset */
+ case 0: /* Hard Reset */
+ case 1: /* SRST */
+ case 2: /* Bus Idle */
+ case 7: /* Packet */
+ case 8: /* DMA Queued */
+ case 9: /* Device Diagnostic */
+ case 11: /* UDMA Data-in */
+ case 12: /* UDMA Data-Out */
+ case 13: /* FPDMA */
+ default: /* Reserved */
+ break;
+ }
+
+ return ATA_PROT_UNKNOWN;
+}
+
+/**
+ * ata_scsi_pass_thru - convert ATA pass-thru CDB to taskfile
+ * @qc: command structure to be initialized
+ * @scsicmd: SCSI command to convert
+ *
+ * Handles either 12 or 16-byte versions of the CDB.
+ *
+ * RETURNS:
+ * Zero on success, non-zero on failure.
+ */
+static unsigned int
+ata_scsi_pass_thru(struct ata_queued_cmd *qc, const u8 *scsicmd)
+{
+ struct ata_taskfile *tf = &(qc->tf);
+ struct scsi_cmnd *cmd = qc->scsicmd;
+
+ if ((tf->protocol = ata_scsi_map_proto(scsicmd[1])) == ATA_PROT_UNKNOWN)
+ return 1;
+
+ /*
+ * 12 and 16 byte CDBs use different offsets to
+ * provide the various register values.
+ */
+ if (scsicmd[0] == ATA_16) {
+ /*
+ * 16-byte CDB - may contain extended commands.
+ *
+ * If that is the case, copy the upper byte register values.
+ */
+ if (scsicmd[1] & 0x01) {
+ tf->hob_feature = scsicmd[3];
+ tf->hob_nsect = scsicmd[5];
+ tf->hob_lbal = scsicmd[7];
+ tf->hob_lbam = scsicmd[9];
+ tf->hob_lbah = scsicmd[11];
+ tf->flags |= ATA_TFLAG_LBA48;
+ } else
+ tf->flags &= ~ATA_TFLAG_LBA48;
+
+ /*
+ * Always copy low byte, device and command registers.
+ */
+ tf->feature = scsicmd[4];
+ tf->nsect = scsicmd[6];
+ tf->lbal = scsicmd[8];
+ tf->lbam = scsicmd[10];
+ tf->lbah = scsicmd[12];
+ tf->device = scsicmd[13];
+ tf->command = scsicmd[14];
+ } else {
+ /*
+ * 12-byte CDB - incapable of extended commands.
+ */
+ tf->flags &= ~ATA_TFLAG_LBA48;
+
+ tf->feature = scsicmd[3];
+ tf->nsect = scsicmd[4];
+ tf->lbal = scsicmd[5];
+ tf->lbam = scsicmd[6];
+ tf->lbah = scsicmd[7];
+ tf->device = scsicmd[8];
+ tf->command = scsicmd[9];
+ }
+
+ /*
+ * Filter SET_FEATURES - XFER MODE command -- otherwise,
+ * SET_FEATURES - XFER MODE must be preceded/succeeded
+ * by an update to hardware-specific registers for each
+ * controller (i.e. the reason for ->set_piomode(),
+ * ->set_dmamode(), and ->post_set_mode() hooks).
+ */
+ if ((tf->command == ATA_CMD_SET_FEATURES)
+ && (tf->feature == SETFEATURES_XFER))
+ return 1;
+
+ /*
+ * Set flags so that all registers will be written,
+ * and pass on write indication (used for PIO/DMA
+ * setup.)
+ */
+ tf->flags |= (ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE);
+
+ if (cmd->sc_data_direction == DMA_TO_DEVICE)
+ tf->flags |= ATA_TFLAG_WRITE;
+
+ /*
+ * Set transfer length.
+ *
+ * TODO: find out if we need to do more here to
+ * cover scatter/gather case.
+ */
+ qc->nsect = cmd->bufflen / ATA_SECT_SIZE;
+
+ return 0;
+}
+
/**
* ata_get_xlat_func - check if SCSI to ATA translation is possible
* @dev: ATA device
@@ -1510,6 +2357,11 @@ static inline ata_xlat_func_t ata_get_xlat_func(struct ata_device *dev, u8 cmd)
case VERIFY:
case VERIFY_16:
return ata_scsi_verify_xlat;
+
+ case ATA_12:
+ case ATA_16:
+ return ata_scsi_pass_thru;
+
case START_STOP:
return ata_scsi_start_stop_xlat;
}
@@ -1565,8 +2417,12 @@ int ata_scsi_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
struct ata_port *ap;
struct ata_device *dev;
struct scsi_device *scsidev = cmd->device;
+ struct Scsi_Host *shost = scsidev->host;
- ap = (struct ata_port *) &scsidev->host->hostdata[0];
+ ap = (struct ata_port *) &shost->hostdata[0];
+
+ spin_unlock(shost->host_lock);
+ spin_lock(&ap->host_set->lock);
ata_scsi_dump_cdb(ap, cmd);
@@ -1589,6 +2445,8 @@ int ata_scsi_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
ata_scsi_translate(ap, dev, cmd, done, atapi_xlat);
out_unlock:
+ spin_unlock(&ap->host_set->lock);
+ spin_lock(shost->host_lock);
return 0;
}
@@ -1610,7 +2468,7 @@ void ata_scsi_simulate(u16 *id,
void (*done)(struct scsi_cmnd *))
{
struct ata_scsi_args args;
- u8 *scsicmd = cmd->cmnd;
+ const u8 *scsicmd = cmd->cmnd;
args.id = id;
args.cmd = cmd;
@@ -1630,7 +2488,7 @@ void ata_scsi_simulate(u16 *id,
case INQUIRY:
if (scsicmd[1] & 2) /* is CmdDt set? */
- ata_bad_cdb(cmd, done);
+ ata_scsi_invalid_field(cmd, done);
else if ((scsicmd[1] & 1) == 0) /* is EVPD clear? */
ata_scsi_rbuf_fill(&args, ata_scsiop_inq_std);
else if (scsicmd[2] == 0x00)
@@ -1640,7 +2498,7 @@ void ata_scsi_simulate(u16 *id,
else if (scsicmd[2] == 0x83)
ata_scsi_rbuf_fill(&args, ata_scsiop_inq_83);
else
- ata_bad_cdb(cmd, done);
+ ata_scsi_invalid_field(cmd, done);
break;
case MODE_SENSE:
@@ -1650,7 +2508,7 @@ void ata_scsi_simulate(u16 *id,
case MODE_SELECT: /* unconditionally return */
case MODE_SELECT_10: /* bad-field-in-cdb */
- ata_bad_cdb(cmd, done);
+ ata_scsi_invalid_field(cmd, done);
break;
case READ_CAPACITY:
@@ -1661,20 +2519,38 @@ void ata_scsi_simulate(u16 *id,
if ((scsicmd[1] & 0x1f) == SAI_READ_CAPACITY_16)
ata_scsi_rbuf_fill(&args, ata_scsiop_read_cap);
else
- ata_bad_cdb(cmd, done);
+ ata_scsi_invalid_field(cmd, done);
break;
case REPORT_LUNS:
ata_scsi_rbuf_fill(&args, ata_scsiop_report_luns);
break;
- /* mandantory commands we haven't implemented yet */
+ /* mandatory commands we haven't implemented yet */
case REQUEST_SENSE:
/* all other commands */
default:
- ata_bad_scsiop(cmd, done);
+ ata_scsi_set_sense(cmd, ILLEGAL_REQUEST, 0x20, 0x0);
+ /* "Invalid command operation code" */
+ done(cmd);
break;
}
}
+void ata_scsi_scan_host(struct ata_port *ap)
+{
+ struct ata_device *dev;
+ unsigned int i;
+
+ if (ap->flags & ATA_FLAG_PORT_DISABLED)
+ return;
+
+ for (i = 0; i < ATA_MAX_DEVICES; i++) {
+ dev = &ap->device[i];
+
+ if (ata_dev_present(dev))
+ scsi_scan_target(&ap->host->shost_gendev, 0, i, 0, 0);
+ }
+}
+
diff --git a/drivers/scsi/libata.h b/drivers/scsi/libata.h
index d608b3a0f6fe..fad051ca4672 100644
--- a/drivers/scsi/libata.h
+++ b/drivers/scsi/libata.h
@@ -39,19 +39,24 @@ struct ata_scsi_args {
/* libata-core.c */
extern int atapi_enabled;
+extern int ata_qc_complete_noop(struct ata_queued_cmd *qc, unsigned int err_mask);
extern struct ata_queued_cmd *ata_qc_new_init(struct ata_port *ap,
struct ata_device *dev);
+extern void ata_rwcmd_protocol(struct ata_queued_cmd *qc);
extern void ata_qc_free(struct ata_queued_cmd *qc);
extern int ata_qc_issue(struct ata_queued_cmd *qc);
extern int ata_check_atapi_dma(struct ata_queued_cmd *qc);
extern void ata_dev_select(struct ata_port *ap, unsigned int device,
unsigned int wait, unsigned int can_sleep);
-extern void ata_tf_to_host_nolock(struct ata_port *ap, struct ata_taskfile *tf);
extern void swap_buf_le16(u16 *buf, unsigned int buf_words);
+extern int ata_task_ioctl(struct scsi_device *scsidev, void __user *arg);
+extern int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg);
/* libata-scsi.c */
-extern void ata_to_sense_error(struct ata_queued_cmd *qc, u8 drv_stat);
+extern void atapi_request_sense(struct ata_port *ap, struct ata_device *dev,
+ struct scsi_cmnd *cmd);
+extern void ata_scsi_scan_host(struct ata_port *ap);
extern int ata_scsi_error(struct Scsi_Host *host);
extern unsigned int ata_scsiop_inq_std(struct ata_scsi_args *args, u8 *rbuf,
unsigned int buflen);
@@ -76,18 +81,10 @@ extern unsigned int ata_scsiop_report_luns(struct ata_scsi_args *args, u8 *rbuf,
extern void ata_scsi_badcmd(struct scsi_cmnd *cmd,
void (*done)(struct scsi_cmnd *),
u8 asc, u8 ascq);
+extern void ata_scsi_set_sense(struct scsi_cmnd *cmd,
+ u8 sk, u8 asc, u8 ascq);
extern void ata_scsi_rbuf_fill(struct ata_scsi_args *args,
unsigned int (*actor) (struct ata_scsi_args *args,
u8 *rbuf, unsigned int buflen));
-static inline void ata_bad_scsiop(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
-{
- ata_scsi_badcmd(cmd, done, 0x20, 0x00);
-}
-
-static inline void ata_bad_cdb(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
-{
- ata_scsi_badcmd(cmd, done, 0x24, 0x00);
-}
-
#endif /* __LIBATA_H__ */
diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h
index adb95674823f..3062b39fbdb9 100644
--- a/drivers/scsi/lpfc/lpfc.h
+++ b/drivers/scsi/lpfc/lpfc.h
@@ -267,10 +267,6 @@ struct lpfc_hba {
struct lpfc_nodelist fc_fcpnodev; /* nodelist entry for no device */
uint32_t nport_event_cnt; /* timestamp for nlplist entry */
-#define LPFC_RPI_HASH_SIZE 64
-#define LPFC_RPI_HASH_FUNC(x) ((x) & (0x3f))
- /* ptr to active D_ID / RPIs */
- struct lpfc_nodelist *fc_nlplookup[LPFC_RPI_HASH_SIZE];
uint32_t wwnn[2];
uint32_t RandomData[7];
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c
index acae7c48ef7d..89e8222bc7cc 100644
--- a/drivers/scsi/lpfc/lpfc_attr.c
+++ b/drivers/scsi/lpfc/lpfc_attr.c
@@ -200,19 +200,13 @@ lpfc_num_discovered_ports_show(struct class_device *cdev, char *buf)
}
-static ssize_t
-lpfc_issue_lip (struct class_device *cdev, const char *buf, size_t count)
+static int
+lpfc_issue_lip(struct Scsi_Host *host)
{
- struct Scsi_Host *host = class_to_shost(cdev);
struct lpfc_hba *phba = (struct lpfc_hba *) host->hostdata[0];
- int val = 0;
LPFC_MBOXQ_t *pmboxq;
int mbxstatus = MBXERR_ERROR;
- if ((sscanf(buf, "%d", &val) != 1) ||
- (val != 1))
- return -EINVAL;
-
if ((phba->fc_flag & FC_OFFLINE_MODE) ||
(phba->hba_state != LPFC_HBA_READY))
return -EPERM;
@@ -229,12 +223,12 @@ lpfc_issue_lip (struct class_device *cdev, const char *buf, size_t count)
if (mbxstatus == MBX_TIMEOUT)
pmboxq->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
else
- mempool_free( pmboxq, phba->mbox_mem_pool);
+ mempool_free(pmboxq, phba->mbox_mem_pool);
if (mbxstatus == MBXERR_ERROR)
return -EIO;
- return strlen(buf);
+ return 0;
}
static ssize_t
@@ -251,8 +245,6 @@ lpfc_board_online_show(struct class_device *cdev, char *buf)
struct Scsi_Host *host = class_to_shost(cdev);
struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];
- if (!phba) return 0;
-
if (phba->fc_flag & FC_OFFLINE_MODE)
return snprintf(buf, PAGE_SIZE, "0\n");
else
@@ -269,7 +261,7 @@ lpfc_board_online_store(struct class_device *cdev, const char *buf,
int val=0, status=0;
if (sscanf(buf, "%d", &val) != 1)
- return 0;
+ return -EINVAL;
init_completion(&online_compl);
@@ -283,7 +275,7 @@ lpfc_board_online_store(struct class_device *cdev, const char *buf,
if (!status)
return strlen(buf);
else
- return 0;
+ return -EIO;
}
@@ -294,47 +286,83 @@ lpfc_##attr##_show(struct class_device *cdev, char *buf) \
struct Scsi_Host *host = class_to_shost(cdev);\
struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];\
int val = 0;\
- if (phba){\
- val = phba->cfg_##attr;\
- return snprintf(buf, PAGE_SIZE, "%d\n",\
- phba->cfg_##attr);\
+ val = phba->cfg_##attr;\
+ return snprintf(buf, PAGE_SIZE, "%d\n",\
+ phba->cfg_##attr);\
+}
+
+#define lpfc_param_hex_show(attr) \
+static ssize_t \
+lpfc_##attr##_show(struct class_device *cdev, char *buf) \
+{ \
+ struct Scsi_Host *host = class_to_shost(cdev);\
+ struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];\
+ int val = 0;\
+ val = phba->cfg_##attr;\
+ return snprintf(buf, PAGE_SIZE, "%#x\n",\
+ phba->cfg_##attr);\
+}
+
+#define lpfc_param_init(attr, default, minval, maxval) \
+static int \
+lpfc_##attr##_init(struct lpfc_hba *phba, int val) \
+{ \
+ if (val >= minval && val <= maxval) {\
+ phba->cfg_##attr = val;\
+ return 0;\
}\
- return 0;\
+ lpfc_printf_log(phba, KERN_ERR, LOG_INIT, \
+ "%d:0449 lpfc_"#attr" attribute cannot be set to %d, "\
+ "allowed range is ["#minval", "#maxval"]\n", \
+ phba->brd_no, val); \
+ phba->cfg_##attr = default;\
+ return -EINVAL;\
}
-#define lpfc_param_store(attr, minval, maxval) \
+#define lpfc_param_set(attr, default, minval, maxval) \
+static int \
+lpfc_##attr##_set(struct lpfc_hba *phba, int val) \
+{ \
+ if (val >= minval && val <= maxval) {\
+ phba->cfg_##attr = val;\
+ return 0;\
+ }\
+ lpfc_printf_log(phba, KERN_ERR, LOG_INIT, \
+ "%d:0450 lpfc_"#attr" attribute cannot be set to %d, "\
+ "allowed range is ["#minval", "#maxval"]\n", \
+ phba->brd_no, val); \
+ return -EINVAL;\
+}
+
+#define lpfc_param_store(attr) \
static ssize_t \
lpfc_##attr##_store(struct class_device *cdev, const char *buf, size_t count) \
{ \
struct Scsi_Host *host = class_to_shost(cdev);\
struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];\
- int val = 0;\
+ int val=0;\
if (!isdigit(buf[0]))\
return -EINVAL;\
- if (sscanf(buf, "0x%x", &val) != 1)\
- if (sscanf(buf, "%d", &val) != 1)\
- return -EINVAL;\
- if (phba){\
- if (val >= minval && val <= maxval) {\
- phba->cfg_##attr = val;\
- return strlen(buf);\
- }\
- }\
- return 0;\
+ if (sscanf(buf, "%i", &val) != 1)\
+ return -EINVAL;\
+ if (lpfc_##attr##_set(phba, val) == 0) \
+ return strlen(buf);\
+ else \
+ return -EINVAL;\
}
-#define LPFC_ATTR_R_NOINIT(name, desc) \
-extern int lpfc_##name;\
+#define LPFC_ATTR(name, defval, minval, maxval, desc) \
+static int lpfc_##name = defval;\
module_param(lpfc_##name, int, 0);\
MODULE_PARM_DESC(lpfc_##name, desc);\
-lpfc_param_show(name)\
-static CLASS_DEVICE_ATTR(lpfc_##name, S_IRUGO , lpfc_##name##_show, NULL)
+lpfc_param_init(name, defval, minval, maxval)
#define LPFC_ATTR_R(name, defval, minval, maxval, desc) \
static int lpfc_##name = defval;\
module_param(lpfc_##name, int, 0);\
MODULE_PARM_DESC(lpfc_##name, desc);\
lpfc_param_show(name)\
+lpfc_param_init(name, defval, minval, maxval)\
static CLASS_DEVICE_ATTR(lpfc_##name, S_IRUGO , lpfc_##name##_show, NULL)
#define LPFC_ATTR_RW(name, defval, minval, maxval, desc) \
@@ -342,7 +370,28 @@ static int lpfc_##name = defval;\
module_param(lpfc_##name, int, 0);\
MODULE_PARM_DESC(lpfc_##name, desc);\
lpfc_param_show(name)\
-lpfc_param_store(name, minval, maxval)\
+lpfc_param_init(name, defval, minval, maxval)\
+lpfc_param_set(name, defval, minval, maxval)\
+lpfc_param_store(name)\
+static CLASS_DEVICE_ATTR(lpfc_##name, S_IRUGO | S_IWUSR,\
+ lpfc_##name##_show, lpfc_##name##_store)
+
+#define LPFC_ATTR_HEX_R(name, defval, minval, maxval, desc) \
+static int lpfc_##name = defval;\
+module_param(lpfc_##name, int, 0);\
+MODULE_PARM_DESC(lpfc_##name, desc);\
+lpfc_param_hex_show(name)\
+lpfc_param_init(name, defval, minval, maxval)\
+static CLASS_DEVICE_ATTR(lpfc_##name, S_IRUGO , lpfc_##name##_show, NULL)
+
+#define LPFC_ATTR_HEX_RW(name, defval, minval, maxval, desc) \
+static int lpfc_##name = defval;\
+module_param(lpfc_##name, int, 0);\
+MODULE_PARM_DESC(lpfc_##name, desc);\
+lpfc_param_hex_show(name)\
+lpfc_param_init(name, defval, minval, maxval)\
+lpfc_param_set(name, defval, minval, maxval)\
+lpfc_param_store(name)\
static CLASS_DEVICE_ATTR(lpfc_##name, S_IRUGO | S_IWUSR,\
lpfc_##name##_show, lpfc_##name##_store)
@@ -364,7 +413,6 @@ static CLASS_DEVICE_ATTR(lpfc_drvr_version, S_IRUGO, lpfc_drvr_version_show,
NULL);
static CLASS_DEVICE_ATTR(management_version, S_IRUGO, management_version_show,
NULL);
-static CLASS_DEVICE_ATTR(issue_lip, S_IWUSR, NULL, lpfc_issue_lip);
static CLASS_DEVICE_ATTR(board_online, S_IRUGO | S_IWUSR,
lpfc_board_online_show, lpfc_board_online_store);
@@ -388,7 +436,7 @@ static CLASS_DEVICE_ATTR(board_online, S_IRUGO | S_IWUSR,
# LOG_LIBDFC 0x2000 LIBDFC events
# LOG_ALL_MSG 0xffff LOG all messages
*/
-LPFC_ATTR_RW(log_verbose, 0x0, 0x0, 0xffff, "Verbose logging bit-mask");
+LPFC_ATTR_HEX_RW(log_verbose, 0x0, 0x0, 0xffff, "Verbose logging bit-mask");
/*
# lun_queue_depth: This parameter is used to limit the number of outstanding
@@ -419,7 +467,7 @@ LPFC_ATTR_R(scan_down, 1, 0, 1,
/*
# lpfc_nodev_tmo: If set, it will hold all I/O errors on devices that disappear
-# until the timer expires. Value range is [0,255]. Default value is 20.
+# until the timer expires. Value range is [0,255]. Default value is 30.
# NOTE: this MUST be less then the SCSI Layer command timeout - 1.
*/
LPFC_ATTR_RW(nodev_tmo, 30, 0, 255,
@@ -475,14 +523,10 @@ LPFC_ATTR_R(ack0, 0, 0, 1, "Enable ACK0 support");
# is 0. Default value of cr_count is 1. The cr_count feature is disabled if
# cr_delay is set to 0.
*/
-static int lpfc_cr_delay = 0;
-module_param(lpfc_cr_delay, int , 0);
-MODULE_PARM_DESC(lpfc_cr_delay, "A count of milliseconds after which an "
+LPFC_ATTR(cr_delay, 0, 0, 63, "A count of milliseconds after which an"
"interrupt response is generated");
-static int lpfc_cr_count = 1;
-module_param(lpfc_cr_count, int, 0);
-MODULE_PARM_DESC(lpfc_cr_count, "A count of I/O completions after which an "
+LPFC_ATTR(cr_count, 1, 1, 255, "A count of I/O completions after which an"
"interrupt response is generated");
/*
@@ -498,9 +542,7 @@ LPFC_ATTR_RW(fdmi_on, 0, 0, 2, "Enable FDMI support");
# Specifies the maximum number of ELS cmds we can have outstanding (for
# discovery). Value range is [1,64]. Default value = 32.
*/
-static int lpfc_discovery_threads = 32;
-module_param(lpfc_discovery_threads, int, 0);
-MODULE_PARM_DESC(lpfc_discovery_threads, "Maximum number of ELS commands "
+LPFC_ATTR(discovery_threads, 32, 1, 64, "Maximum number of ELS commands"
"during discovery");
/*
@@ -537,7 +579,6 @@ struct class_device_attribute *lpfc_host_attrs[] = {
&class_device_attr_lpfc_max_luns,
&class_device_attr_nport_evt_cnt,
&class_device_attr_management_version,
- &class_device_attr_issue_lip,
&class_device_attr_board_online,
NULL,
};
@@ -992,7 +1033,7 @@ lpfc_get_stats(struct Scsi_Host *shost)
struct fc_host_statistics *hs = &phba->link_stats;
LPFC_MBOXQ_t *pmboxq;
MAILBOX_t *pmb;
- int rc=0;
+ int rc = 0;
pmboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
if (!pmboxq)
@@ -1005,18 +1046,16 @@ lpfc_get_stats(struct Scsi_Host *shost)
pmboxq->context1 = NULL;
if ((phba->fc_flag & FC_OFFLINE_MODE) ||
- (!(psli->sli_flag & LPFC_SLI2_ACTIVE))){
+ (!(psli->sli_flag & LPFC_SLI2_ACTIVE)))
rc = lpfc_sli_issue_mbox(phba, pmboxq, MBX_POLL);
- } else
+ else
rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2);
if (rc != MBX_SUCCESS) {
- if (pmboxq) {
- if (rc == MBX_TIMEOUT)
- pmboxq->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
- else
- mempool_free( pmboxq, phba->mbox_mem_pool);
- }
+ if (rc == MBX_TIMEOUT)
+ pmboxq->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
+ else
+ mempool_free(pmboxq, phba->mbox_mem_pool);
return NULL;
}
@@ -1027,24 +1066,22 @@ lpfc_get_stats(struct Scsi_Host *shost)
hs->rx_frames = pmb->un.varRdStatus.rcvFrameCnt;
hs->rx_words = (pmb->un.varRdStatus.rcvByteCnt * 256);
- memset((void *)pmboxq, 0, sizeof (LPFC_MBOXQ_t));
+ memset(pmboxq, 0, sizeof (LPFC_MBOXQ_t));
pmb->mbxCommand = MBX_READ_LNK_STAT;
pmb->mbxOwner = OWN_HOST;
pmboxq->context1 = NULL;
if ((phba->fc_flag & FC_OFFLINE_MODE) ||
- (!(psli->sli_flag & LPFC_SLI2_ACTIVE))) {
+ (!(psli->sli_flag & LPFC_SLI2_ACTIVE)))
rc = lpfc_sli_issue_mbox(phba, pmboxq, MBX_POLL);
- } else
+ else
rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2);
if (rc != MBX_SUCCESS) {
- if (pmboxq) {
- if (rc == MBX_TIMEOUT)
- pmboxq->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
- else
- mempool_free( pmboxq, phba->mbox_mem_pool);
- }
+ if (rc == MBX_TIMEOUT)
+ pmboxq->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
+ else
+ mempool_free( pmboxq, phba->mbox_mem_pool);
return NULL;
}
@@ -1234,25 +1271,27 @@ struct fc_function_template lpfc_transport_functions = {
.get_starget_port_name = lpfc_get_starget_port_name,
.show_starget_port_name = 1,
+
+ .issue_fc_host_lip = lpfc_issue_lip,
};
void
lpfc_get_cfgparam(struct lpfc_hba *phba)
{
- phba->cfg_log_verbose = lpfc_log_verbose;
- phba->cfg_cr_delay = lpfc_cr_delay;
- phba->cfg_cr_count = lpfc_cr_count;
- phba->cfg_lun_queue_depth = lpfc_lun_queue_depth;
- phba->cfg_fcp_class = lpfc_fcp_class;
- phba->cfg_use_adisc = lpfc_use_adisc;
- phba->cfg_ack0 = lpfc_ack0;
- phba->cfg_topology = lpfc_topology;
- phba->cfg_scan_down = lpfc_scan_down;
- phba->cfg_nodev_tmo = lpfc_nodev_tmo;
- phba->cfg_link_speed = lpfc_link_speed;
- phba->cfg_fdmi_on = lpfc_fdmi_on;
- phba->cfg_discovery_threads = lpfc_discovery_threads;
- phba->cfg_max_luns = lpfc_max_luns;
+ lpfc_log_verbose_init(phba, lpfc_log_verbose);
+ lpfc_cr_delay_init(phba, lpfc_cr_delay);
+ lpfc_cr_count_init(phba, lpfc_cr_count);
+ lpfc_lun_queue_depth_init(phba, lpfc_lun_queue_depth);
+ lpfc_fcp_class_init(phba, lpfc_fcp_class);
+ lpfc_use_adisc_init(phba, lpfc_use_adisc);
+ lpfc_ack0_init(phba, lpfc_ack0);
+ lpfc_topology_init(phba, lpfc_topology);
+ lpfc_scan_down_init(phba, lpfc_scan_down);
+ lpfc_nodev_tmo_init(phba, lpfc_nodev_tmo);
+ lpfc_link_speed_init(phba, lpfc_link_speed);
+ lpfc_fdmi_on_init(phba, lpfc_fdmi_on);
+ lpfc_discovery_threads_init(phba, lpfc_discovery_threads);
+ lpfc_max_luns_init(phba, lpfc_max_luns);
/*
* The total number of segments is the configuration value plus 2
diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h
index bd5135d3eee4..d527d05a607f 100644
--- a/drivers/scsi/lpfc/lpfc_crtn.h
+++ b/drivers/scsi/lpfc/lpfc_crtn.h
@@ -62,10 +62,6 @@ void lpfc_disc_timeout(unsigned long);
void lpfc_scan_timeout(unsigned long);
struct lpfc_nodelist *lpfc_findnode_rpi(struct lpfc_hba * phba, uint16_t rpi);
-struct lpfc_nodelist *lpfc_findnode_remove_rpi(struct lpfc_hba * phba,
- uint16_t rpi);
-void lpfc_addnode_rpi(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp,
- uint16_t rpi);
int lpfc_workq_post_event(struct lpfc_hba *, void *, void *, uint32_t);
int lpfc_do_work(void *);
@@ -147,6 +143,9 @@ LPFC_MBOXQ_t *lpfc_mbox_get(struct lpfc_hba *);
int lpfc_mem_alloc(struct lpfc_hba *);
void lpfc_mem_free(struct lpfc_hba *);
+struct lpfc_iocbq * lpfc_sli_get_iocbq(struct lpfc_hba *);
+void lpfc_sli_release_iocbq(struct lpfc_hba * phba, struct lpfc_iocbq * iocb);
+uint16_t lpfc_sli_next_iotag(struct lpfc_hba * phba, struct lpfc_iocbq * iocb);
int lpfc_sli_hba_setup(struct lpfc_hba *);
int lpfc_sli_hba_down(struct lpfc_hba *);
int lpfc_sli_issue_mbox(struct lpfc_hba *, LPFC_MBOXQ_t *, uint32_t);
@@ -182,15 +181,11 @@ struct lpfc_nodelist *lpfc_findnode_did(struct lpfc_hba * phba, uint32_t order,
int lpfc_sli_issue_mbox_wait(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmboxq,
uint32_t timeout);
-int lpfc_sli_issue_iocb_wait_high_priority(struct lpfc_hba * phba,
- struct lpfc_sli_ring * pring,
- struct lpfc_iocbq * piocb,
- uint32_t flag,
- struct lpfc_iocbq * prspiocbq,
- uint32_t timeout);
-void lpfc_sli_wake_iocb_high_priority(struct lpfc_hba * phba,
- struct lpfc_iocbq * queue1,
- struct lpfc_iocbq * queue2);
+int lpfc_sli_issue_iocb_wait(struct lpfc_hba * phba,
+ struct lpfc_sli_ring * pring,
+ struct lpfc_iocbq * piocb,
+ struct lpfc_iocbq * prspiocbq,
+ uint32_t timeout);
void lpfc_sli_abort_fcp_cmpl(struct lpfc_hba * phba,
struct lpfc_iocbq * cmdiocb,
struct lpfc_iocbq * rspiocb);
diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c
index 1280f0e54636..7f427f9c4688 100644
--- a/drivers/scsi/lpfc/lpfc_ct.c
+++ b/drivers/scsi/lpfc/lpfc_ct.c
@@ -224,18 +224,16 @@ lpfc_gen_req(struct lpfc_hba *phba, struct lpfc_dmabuf *bmp,
struct lpfc_sli *psli = &phba->sli;
struct lpfc_sli_ring *pring = &psli->ring[LPFC_ELS_RING];
- struct list_head *lpfc_iocb_list = &phba->lpfc_iocb_list;
IOCB_t *icmd;
- struct lpfc_iocbq *geniocb = NULL;
+ struct lpfc_iocbq *geniocb;
/* Allocate buffer for command iocb */
spin_lock_irq(phba->host->host_lock);
- list_remove_head(lpfc_iocb_list, geniocb, struct lpfc_iocbq, list);
+ geniocb = lpfc_sli_get_iocbq(phba);
spin_unlock_irq(phba->host->host_lock);
if (geniocb == NULL)
return 1;
- memset(geniocb, 0, sizeof (struct lpfc_iocbq));
icmd = &geniocb->iocb;
icmd->un.genreq64.bdl.ulpIoTag32 = 0;
@@ -279,7 +277,7 @@ lpfc_gen_req(struct lpfc_hba *phba, struct lpfc_dmabuf *bmp,
geniocb->drvrTimeout = icmd->ulpTimeout + LPFC_DRVR_TIMEOUT;
spin_lock_irq(phba->host->host_lock);
if (lpfc_sli_issue_iocb(phba, pring, geniocb, 0) == IOCB_ERROR) {
- list_add_tail(&geniocb->list, lpfc_iocb_list);
+ lpfc_sli_release_iocbq(phba, geniocb);
spin_unlock_irq(phba->host->host_lock);
return 1;
}
@@ -487,7 +485,7 @@ out:
kfree(inp);
kfree(bmp);
spin_lock_irq(phba->host->host_lock);
- list_add_tail(&cmdiocb->list, &phba->lpfc_iocb_list);
+ lpfc_sli_release_iocbq(phba, cmdiocb);
spin_unlock_irq(phba->host->host_lock);
return;
}
@@ -526,7 +524,7 @@ lpfc_cmpl_ct_cmd_rft_id(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
kfree(inp);
kfree(bmp);
spin_lock_irq(phba->host->host_lock);
- list_add_tail(&cmdiocb->list, &phba->lpfc_iocb_list);
+ lpfc_sli_release_iocbq(phba, cmdiocb);
spin_unlock_irq(phba->host->host_lock);
return;
}
@@ -735,7 +733,7 @@ lpfc_cmpl_ct_cmd_fdmi(struct lpfc_hba * phba,
kfree(inp);
kfree(bmp);
spin_lock_irq(phba->host->host_lock);
- list_add_tail(&cmdiocb->list, &phba->lpfc_iocb_list);
+ lpfc_sli_release_iocbq(phba, cmdiocb);
spin_unlock_irq(phba->host->host_lock);
return;
}
diff --git a/drivers/scsi/lpfc/lpfc_disc.h b/drivers/scsi/lpfc/lpfc_disc.h
index 098b8b45c7f1..084e7628ce17 100644
--- a/drivers/scsi/lpfc/lpfc_disc.h
+++ b/drivers/scsi/lpfc/lpfc_disc.h
@@ -70,7 +70,6 @@ struct lpfc_nodelist {
struct timer_list nlp_tmofunc; /* Used for nodev tmo */
struct fc_rport *rport; /* Corresponding FC transport
port structure */
- struct lpfc_nodelist *nlp_rpi_hash_next;
struct lpfc_hba *nlp_phba;
struct lpfc_work_evt nodev_timeout_evt;
struct lpfc_work_evt els_retry_evt;
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
index 63caf7fe9725..bcc29ec126dc 100644
--- a/drivers/scsi/lpfc/lpfc_els.c
+++ b/drivers/scsi/lpfc/lpfc_els.c
@@ -102,9 +102,8 @@ lpfc_prep_els_iocb(struct lpfc_hba * phba,
uint16_t cmdSize,
uint8_t retry, struct lpfc_nodelist * ndlp, uint32_t elscmd)
{
- struct list_head *lpfc_iocb_list = &phba->lpfc_iocb_list;
struct lpfc_sli_ring *pring;
- struct lpfc_iocbq *elsiocb = NULL;
+ struct lpfc_iocbq *elsiocb;
struct lpfc_dmabuf *pcmd, *prsp, *pbuflist;
struct ulp_bde64 *bpl;
IOCB_t *icmd;
@@ -114,15 +113,13 @@ lpfc_prep_els_iocb(struct lpfc_hba * phba,
if (phba->hba_state < LPFC_LINK_UP)
return NULL;
-
/* Allocate buffer for command iocb */
spin_lock_irq(phba->host->host_lock);
- list_remove_head(lpfc_iocb_list, elsiocb, struct lpfc_iocbq, list);
+ elsiocb = lpfc_sli_get_iocbq(phba);
spin_unlock_irq(phba->host->host_lock);
if (elsiocb == NULL)
return NULL;
- memset(elsiocb, 0, sizeof (struct lpfc_iocbq));
icmd = &elsiocb->iocb;
/* fill in BDEs for command */
@@ -130,10 +127,11 @@ lpfc_prep_els_iocb(struct lpfc_hba * phba,
if (((pcmd = kmalloc(sizeof (struct lpfc_dmabuf), GFP_KERNEL)) == 0) ||
((pcmd->virt = lpfc_mbuf_alloc(phba,
MEM_PRI, &(pcmd->phys))) == 0)) {
- if (pcmd)
- kfree(pcmd);
+ kfree(pcmd);
- list_add_tail(&elsiocb->list, lpfc_iocb_list);
+ spin_lock_irq(phba->host->host_lock);
+ lpfc_sli_release_iocbq(phba, elsiocb);
+ spin_unlock_irq(phba->host->host_lock);
return NULL;
}
@@ -146,11 +144,12 @@ lpfc_prep_els_iocb(struct lpfc_hba * phba,
prsp->virt = lpfc_mbuf_alloc(phba, MEM_PRI,
&prsp->phys);
if (prsp == 0 || prsp->virt == 0) {
- if (prsp)
- kfree(prsp);
+ kfree(prsp);
lpfc_mbuf_free(phba, pcmd->virt, pcmd->phys);
kfree(pcmd);
- list_add_tail(&elsiocb->list, lpfc_iocb_list);
+ spin_lock_irq(phba->host->host_lock);
+ lpfc_sli_release_iocbq(phba, elsiocb);
+ spin_unlock_irq(phba->host->host_lock);
return NULL;
}
INIT_LIST_HEAD(&prsp->list);
@@ -164,13 +163,14 @@ lpfc_prep_els_iocb(struct lpfc_hba * phba,
pbuflist->virt = lpfc_mbuf_alloc(phba, MEM_PRI,
&pbuflist->phys);
if (pbuflist == 0 || pbuflist->virt == 0) {
- list_add_tail(&elsiocb->list, lpfc_iocb_list);
+ spin_lock_irq(phba->host->host_lock);
+ lpfc_sli_release_iocbq(phba, elsiocb);
+ spin_unlock_irq(phba->host->host_lock);
lpfc_mbuf_free(phba, pcmd->virt, pcmd->phys);
lpfc_mbuf_free(phba, prsp->virt, prsp->phys);
kfree(pcmd);
kfree(prsp);
- if (pbuflist)
- kfree(pbuflist);
+ kfree(pbuflist);
return NULL;
}
@@ -596,10 +596,8 @@ lpfc_els_abort_flogi(struct lpfc_hba * phba)
spin_unlock_irq(phba->host->host_lock);
(iocb->iocb_cmpl) (phba, iocb, iocb);
spin_lock_irq(phba->host->host_lock);
- } else {
- list_add_tail(&iocb->list,
- &phba->lpfc_iocb_list);
- }
+ } else
+ lpfc_sli_release_iocbq(phba, iocb);
}
}
}
@@ -1713,7 +1711,7 @@ lpfc_els_free_iocb(struct lpfc_hba * phba, struct lpfc_iocbq * elsiocb)
kfree(buf_ptr);
}
spin_lock_irq(phba->host->host_lock);
- list_add_tail(&elsiocb->list, &phba->lpfc_iocb_list);
+ lpfc_sli_release_iocbq(phba, elsiocb);
spin_unlock_irq(phba->host->host_lock);
return 0;
}
@@ -2929,9 +2927,8 @@ lpfc_els_timeout_handler(struct lpfc_hba *phba)
spin_unlock_irq(phba->host->host_lock);
(piocb->iocb_cmpl) (phba, piocb, piocb);
spin_lock_irq(phba->host->host_lock);
- } else {
- list_add_tail(&piocb->list, &phba->lpfc_iocb_list);
- }
+ } else
+ lpfc_sli_release_iocbq(phba, piocb);
}
if (phba->sli.ring[LPFC_ELS_RING].txcmplq_cnt) {
phba->els_tmofunc.expires = jiffies + HZ * timeout;
@@ -2996,7 +2993,7 @@ lpfc_els_flush_cmd(struct lpfc_hba * phba)
spin_lock_irq(phba->host->host_lock);
}
else
- list_add_tail(&piocb->list, &phba->lpfc_iocb_list);
+ lpfc_sli_release_iocbq(phba, piocb);
}
list_for_each_entry_safe(piocb, tmp_iocb, &pring->txcmplq, list) {
@@ -3033,7 +3030,7 @@ lpfc_els_flush_cmd(struct lpfc_hba * phba)
spin_lock_irq(phba->host->host_lock);
}
else
- list_add_tail(&piocb->list, &phba->lpfc_iocb_list);
+ lpfc_sli_release_iocbq(phba, piocb);
}
spin_unlock_irq(phba->host->host_lock);
return;
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c
index 56052f4510c3..259eeb161b82 100644
--- a/drivers/scsi/lpfc/lpfc_hbadisc.c
+++ b/drivers/scsi/lpfc/lpfc_hbadisc.c
@@ -890,10 +890,7 @@ lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
pmb->context1 = NULL;
- if (ndlp->nlp_rpi != 0)
- lpfc_findnode_remove_rpi(phba, ndlp->nlp_rpi);
ndlp->nlp_rpi = mb->un.varWords[0];
- lpfc_addnode_rpi(phba, ndlp, ndlp->nlp_rpi);
ndlp->nlp_type |= NLP_FABRIC;
ndlp->nlp_state = NLP_STE_UNMAPPED_NODE;
lpfc_nlp_list(phba, ndlp, NLP_UNMAPPED_LIST);
@@ -981,10 +978,7 @@ lpfc_mbx_cmpl_ns_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
pmb->context1 = NULL;
- if (ndlp->nlp_rpi != 0)
- lpfc_findnode_remove_rpi(phba, ndlp->nlp_rpi);
ndlp->nlp_rpi = mb->un.varWords[0];
- lpfc_addnode_rpi(phba, ndlp, ndlp->nlp_rpi);
ndlp->nlp_type |= NLP_FABRIC;
ndlp->nlp_state = NLP_STE_UNMAPPED_NODE;
lpfc_nlp_list(phba, ndlp, NLP_UNMAPPED_LIST);
@@ -1028,6 +1022,7 @@ lpfc_register_remote_port(struct lpfc_hba * phba,
if (ndlp->nlp_type & NLP_FCP_INITIATOR)
rport_ids.roles |= FC_RPORT_ROLE_FCP_INITIATOR;
+ scsi_block_requests(phba->host);
ndlp->rport = rport = fc_remote_port_add(phba->host, 0, &rport_ids);
if (!rport) {
dev_printk(KERN_WARNING, &phba->pcidev->dev,
@@ -1044,6 +1039,23 @@ lpfc_register_remote_port(struct lpfc_hba * phba,
}
rdata = rport->dd_data;
rdata->pnode = ndlp;
+ scsi_unblock_requests(phba->host);
+
+ return;
+}
+
+static void
+lpfc_unregister_remote_port(struct lpfc_hba * phba,
+ struct lpfc_nodelist * ndlp)
+{
+ struct fc_rport *rport = ndlp->rport;
+ struct lpfc_rport_data *rdata = rport->dd_data;
+
+ ndlp->rport = NULL;
+ rdata->pnode = NULL;
+ scsi_block_requests(phba->host);
+ fc_remote_port_delete(rport);
+ scsi_unblock_requests(phba->host);
return;
}
@@ -1260,7 +1272,7 @@ lpfc_nlp_list(struct lpfc_hba * phba, struct lpfc_nodelist * nlp, int list)
* may have removed the remote port.
*/
if ((rport_del != none) && nlp->rport)
- fc_remote_port_block(nlp->rport);
+ lpfc_unregister_remote_port(phba, nlp);
if (rport_add != none) {
/*
@@ -1270,8 +1282,6 @@ lpfc_nlp_list(struct lpfc_hba * phba, struct lpfc_nodelist * nlp, int list)
*/
if (!nlp->rport)
lpfc_register_remote_port(phba, nlp);
- else
- fc_remote_port_unblock(nlp->rport);
/*
* if we added to Mapped list, but the remote port
@@ -1435,10 +1445,9 @@ lpfc_no_rpi(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp)
iocb, iocb);
spin_lock_irq(phba->host->
host_lock);
- } else {
- list_add_tail(&iocb->list,
- &phba->lpfc_iocb_list);
- }
+ } else
+ lpfc_sli_release_iocbq(phba,
+ iocb);
}
}
spin_unlock_irq(phba->host->host_lock);
@@ -1472,7 +1481,6 @@ lpfc_unreg_rpi(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp)
if (rc == MBX_NOT_FINISHED)
mempool_free( mbox, phba->mbox_mem_pool);
}
- lpfc_findnode_remove_rpi(phba, ndlp->nlp_rpi);
lpfc_no_rpi(phba, ndlp);
ndlp->nlp_rpi = 0;
return 1;
@@ -1490,7 +1498,6 @@ lpfc_freenode(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp)
LPFC_MBOXQ_t *mb;
LPFC_MBOXQ_t *nextmb;
struct lpfc_dmabuf *mp;
- struct fc_rport *rport;
/* Cleanup node for NPort <nlp_DID> */
lpfc_printf_log(phba, KERN_INFO, LOG_NODE,
@@ -1507,10 +1514,7 @@ lpfc_freenode(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp)
* and flush cache's w/o generating flush errors.
*/
if ((ndlp->rport) && !(phba->fc_flag & FC_UNLOADING)) {
- rport = ndlp->rport;
- ndlp->rport = NULL;
- fc_remote_port_unblock(rport);
- fc_remote_port_delete(rport);
+ lpfc_unregister_remote_port(phba, ndlp);
ndlp->nlp_sid = NLP_NO_SID;
}
@@ -2422,10 +2426,7 @@ lpfc_mbx_cmpl_fdmi_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
pmb->context1 = NULL;
- if (ndlp->nlp_rpi != 0)
- lpfc_findnode_remove_rpi(phba, ndlp->nlp_rpi);
ndlp->nlp_rpi = mb->un.varWords[0];
- lpfc_addnode_rpi(phba, ndlp, ndlp->nlp_rpi);
ndlp->nlp_type |= NLP_FABRIC;
ndlp->nlp_state = NLP_STE_UNMAPPED_NODE;
lpfc_nlp_list(phba, ndlp, NLP_UNMAPPED_LIST);
@@ -2451,75 +2452,28 @@ lpfc_mbx_cmpl_fdmi_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
}
/*
- * This routine looks up the ndlp hash
- * table for the given RPI. If rpi found
+ * This routine looks up the ndlp lists
+ * for the given RPI. If rpi found
* it return the node list pointer
- * else return 0.
+ * else return NULL.
*/
struct lpfc_nodelist *
lpfc_findnode_rpi(struct lpfc_hba * phba, uint16_t rpi)
{
- struct lpfc_nodelist *ret;
-
- ret = phba->fc_nlplookup[LPFC_RPI_HASH_FUNC(rpi)];
- while ((ret != 0) && (ret->nlp_rpi != rpi)) {
- ret = ret->nlp_rpi_hash_next;
- }
- return ret;
-}
-
-/*
- * This routine looks up the ndlp hash table for the
- * given RPI. If rpi found it return the node list
- * pointer else return 0 after deleting the entry
- * from hash table.
- */
-struct lpfc_nodelist *
-lpfc_findnode_remove_rpi(struct lpfc_hba * phba, uint16_t rpi)
-{
- struct lpfc_nodelist *ret, *temp;;
-
- ret = phba->fc_nlplookup[LPFC_RPI_HASH_FUNC(rpi)];
- if (ret == 0)
- return NULL;
-
- if (ret->nlp_rpi == rpi) {
- phba->fc_nlplookup[LPFC_RPI_HASH_FUNC(rpi)] =
- ret->nlp_rpi_hash_next;
- ret->nlp_rpi_hash_next = NULL;
- return ret;
- }
-
- while ((ret->nlp_rpi_hash_next != 0) &&
- (ret->nlp_rpi_hash_next->nlp_rpi != rpi)) {
- ret = ret->nlp_rpi_hash_next;
- }
-
- if (ret->nlp_rpi_hash_next != 0) {
- temp = ret->nlp_rpi_hash_next;
- ret->nlp_rpi_hash_next = temp->nlp_rpi_hash_next;
- temp->nlp_rpi_hash_next = NULL;
- return temp;
- } else {
- return NULL;
- }
-}
-
-/*
- * This routine adds the node list entry to the
- * ndlp hash table.
- */
-void
-lpfc_addnode_rpi(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp,
- uint16_t rpi)
-{
+ struct lpfc_nodelist *ndlp;
+ struct list_head * lists[]={&phba->fc_nlpunmap_list,
+ &phba->fc_nlpmap_list,
+ &phba->fc_plogi_list,
+ &phba->fc_adisc_list,
+ &phba->fc_reglogin_list};
+ int i;
- uint32_t index;
+ for (i = 0; i < ARRAY_SIZE(lists); i++ )
+ list_for_each_entry(ndlp, lists[i], nlp_listp)
+ if (ndlp->nlp_rpi == rpi)
+ return (ndlp);
- index = LPFC_RPI_HASH_FUNC(rpi);
- ndlp->nlp_rpi_hash_next = phba->fc_nlplookup[index];
- phba->fc_nlplookup[index] = ndlp;
- return;
+ return NULL;
}
void
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index 0856ff7d3b33..07498118359d 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -537,12 +537,6 @@ lpfc_handle_eratt(struct lpfc_hba * phba)
lpfc_offline(phba);
- /*
- * Restart all traffic to this host. Since the fc_transport
- * block functions (future) were not called in lpfc_offline,
- * don't call them here.
- */
- scsi_unblock_requests(phba->host);
}
}
@@ -772,10 +766,12 @@ lpfc_get_hba_model_desc(struct lpfc_hba * phba, uint8_t * mdp, uint8_t * descp)
{
lpfc_vpd_t *vp;
uint32_t id;
+ uint8_t hdrtype;
char str[16];
vp = &phba->vpd;
pci_read_config_dword(phba->pcidev, PCI_VENDOR_ID, &id);
+ pci_read_config_byte(phba->pcidev, PCI_HEADER_TYPE, &hdrtype);
switch ((id >> 16) & 0xffff) {
case PCI_DEVICE_ID_FIREFLY:
@@ -803,7 +799,10 @@ lpfc_get_hba_model_desc(struct lpfc_hba * phba, uint8_t * mdp, uint8_t * descp)
strcpy(str, "LP9802 2");
break;
case PCI_DEVICE_ID_THOR:
- strcpy(str, "LP10000 2");
+ if (hdrtype == 0x80)
+ strcpy(str, "LP10000DC 2");
+ else
+ strcpy(str, "LP10000 2");
break;
case PCI_DEVICE_ID_VIPER:
strcpy(str, "LPX1000 10");
@@ -812,10 +811,16 @@ lpfc_get_hba_model_desc(struct lpfc_hba * phba, uint8_t * mdp, uint8_t * descp)
strcpy(str, "LP982 2");
break;
case PCI_DEVICE_ID_TFLY:
- strcpy(str, "LP1050 2");
+ if (hdrtype == 0x80)
+ strcpy(str, "LP1050DC 2");
+ else
+ strcpy(str, "LP1050 2");
break;
case PCI_DEVICE_ID_HELIOS:
- strcpy(str, "LP11000 4");
+ if (hdrtype == 0x80)
+ strcpy(str, "LP11002 4");
+ else
+ strcpy(str, "LP11000 4");
break;
case PCI_DEVICE_ID_BMID:
strcpy(str, "LP1150 4");
@@ -824,13 +829,16 @@ lpfc_get_hba_model_desc(struct lpfc_hba * phba, uint8_t * mdp, uint8_t * descp)
strcpy(str, "LP111 4");
break;
case PCI_DEVICE_ID_ZEPHYR:
- strcpy(str, "LP11000e 4");
+ if (hdrtype == 0x80)
+ strcpy(str, "LPe11002 4");
+ else
+ strcpy(str, "LPe11000 4");
break;
case PCI_DEVICE_ID_ZMID:
- strcpy(str, "LP1150e 4");
+ strcpy(str, "LPe1150 4");
break;
case PCI_DEVICE_ID_ZSMB:
- strcpy(str, "LP111e 4");
+ strcpy(str, "LPe111 4");
break;
case PCI_DEVICE_ID_LP101:
strcpy(str, "LP101 2");
@@ -862,8 +870,7 @@ lpfc_post_buffer(struct lpfc_hba * phba, struct lpfc_sli_ring * pring, int cnt,
int type)
{
IOCB_t *icmd;
- struct list_head *lpfc_iocb_list = &phba->lpfc_iocb_list;
- struct lpfc_iocbq *iocb = NULL;
+ struct lpfc_iocbq *iocb;
struct lpfc_dmabuf *mp1, *mp2;
cnt += pring->missbufcnt;
@@ -872,13 +879,12 @@ lpfc_post_buffer(struct lpfc_hba * phba, struct lpfc_sli_ring * pring, int cnt,
while (cnt > 0) {
/* Allocate buffer for command iocb */
spin_lock_irq(phba->host->host_lock);
- list_remove_head(lpfc_iocb_list, iocb, struct lpfc_iocbq, list);
+ iocb = lpfc_sli_get_iocbq(phba);
spin_unlock_irq(phba->host->host_lock);
if (iocb == NULL) {
pring->missbufcnt = cnt;
return cnt;
}
- memset(iocb, 0, sizeof (struct lpfc_iocbq));
icmd = &iocb->iocb;
/* 2 buffers can be posted per command */
@@ -888,10 +894,9 @@ lpfc_post_buffer(struct lpfc_hba * phba, struct lpfc_sli_ring * pring, int cnt,
mp1->virt = lpfc_mbuf_alloc(phba, MEM_PRI,
&mp1->phys);
if (mp1 == 0 || mp1->virt == 0) {
- if (mp1)
- kfree(mp1);
+ kfree(mp1);
spin_lock_irq(phba->host->host_lock);
- list_add_tail(&iocb->list, lpfc_iocb_list);
+ lpfc_sli_release_iocbq(phba, iocb);
spin_unlock_irq(phba->host->host_lock);
pring->missbufcnt = cnt;
return cnt;
@@ -905,12 +910,11 @@ lpfc_post_buffer(struct lpfc_hba * phba, struct lpfc_sli_ring * pring, int cnt,
mp2->virt = lpfc_mbuf_alloc(phba, MEM_PRI,
&mp2->phys);
if (mp2 == 0 || mp2->virt == 0) {
- if (mp2)
- kfree(mp2);
+ kfree(mp2);
lpfc_mbuf_free(phba, mp1->virt, mp1->phys);
kfree(mp1);
spin_lock_irq(phba->host->host_lock);
- list_add_tail(&iocb->list, lpfc_iocb_list);
+ lpfc_sli_release_iocbq(phba, iocb);
spin_unlock_irq(phba->host->host_lock);
pring->missbufcnt = cnt;
return cnt;
@@ -947,7 +951,7 @@ lpfc_post_buffer(struct lpfc_hba * phba, struct lpfc_sli_ring * pring, int cnt,
kfree(mp2);
cnt++;
}
- list_add_tail(&iocb->list, lpfc_iocb_list);
+ lpfc_sli_release_iocbq(phba, iocb);
pring->missbufcnt = cnt;
spin_unlock_irq(phba->host->host_lock);
return cnt;
@@ -1226,12 +1230,6 @@ lpfc_online(struct lpfc_hba * phba)
phba->fc_flag &= ~FC_OFFLINE_MODE;
spin_unlock_irq(phba->host->host_lock);
- /*
- * Restart all traffic to this host. Since the fc_transport block
- * functions (future) were not called in lpfc_offline, don't call them
- * here.
- */
- scsi_unblock_requests(phba->host);
return 0;
}
@@ -1249,13 +1247,6 @@ lpfc_offline(struct lpfc_hba * phba)
if (phba->fc_flag & FC_OFFLINE_MODE)
return 0;
- /*
- * Don't call the fc_transport block api (future). The device is
- * going offline and causing a timer to fire in the midlayer is
- * unproductive. Just block all new requests until the driver
- * comes back online.
- */
- scsi_block_requests(phba->host);
psli = &phba->sli;
pring = &psli->ring[psli->fcp_ring];
@@ -1333,6 +1324,7 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid)
unsigned long bar0map_len, bar2map_len;
int error = -ENODEV, retval;
int i;
+ uint16_t iotag;
if (pci_enable_device(pdev))
goto out;
@@ -1434,6 +1426,7 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid)
if (!phba->slim2p)
goto out_iounmap;
+ memset(phba->slim2p, 0, SLI2_SLIM_SIZE);
/* Initialize the SLI Layer to run with lpfc HBAs. */
lpfc_sli_setup(phba);
@@ -1456,6 +1449,15 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid)
}
memset(iocbq_entry, 0, sizeof(struct lpfc_iocbq));
+ iotag = lpfc_sli_next_iotag(phba, iocbq_entry);
+ if (iotag == 0) {
+ kfree (iocbq_entry);
+ printk(KERN_ERR "%s: failed to allocate IOTAG. "
+ "Unloading driver.\n",
+ __FUNCTION__);
+ error = -ENOMEM;
+ goto out_free_iocbq;
+ }
spin_lock_irq(phba->host->host_lock);
list_add(&iocbq_entry->list, &phba->lpfc_iocb_list);
phba->total_iocbq_bufs++;
diff --git a/drivers/scsi/lpfc/lpfc_mbox.c b/drivers/scsi/lpfc/lpfc_mbox.c
index 73eb89f91593..e3bc8d3f7302 100644
--- a/drivers/scsi/lpfc/lpfc_mbox.c
+++ b/drivers/scsi/lpfc/lpfc_mbox.c
@@ -248,8 +248,7 @@ lpfc_read_sparam(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
if (((mp = kmalloc(sizeof (struct lpfc_dmabuf), GFP_KERNEL)) == 0) ||
((mp->virt = lpfc_mbuf_alloc(phba, 0, &(mp->phys))) == 0)) {
- if (mp)
- kfree(mp);
+ kfree(mp);
mb->mbxCommand = MBX_READ_SPARM64;
/* READ_SPARAM: no buffers */
lpfc_printf_log(phba,
@@ -363,9 +362,7 @@ lpfc_reg_login(struct lpfc_hba * phba,
/* Get a buffer to hold NPorts Service Parameters */
if (((mp = kmalloc(sizeof (struct lpfc_dmabuf), GFP_KERNEL)) == NULL) ||
((mp->virt = lpfc_mbuf_alloc(phba, 0, &(mp->phys))) == 0)) {
- if (mp)
- kfree(mp);
-
+ kfree(mp);
mb->mbxCommand = MBX_REG_LOGIN64;
/* REG_LOGIN: no buffers */
lpfc_printf_log(phba,
@@ -531,6 +528,7 @@ lpfc_config_port(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
size_t offset;
struct lpfc_hgp hgp;
void __iomem *to_slim;
+ int i;
memset(pmb, 0, sizeof(LPFC_MBOXQ_t));
mb->mbxCommand = MBX_CONFIG_PORT;
@@ -587,7 +585,11 @@ lpfc_config_port(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
/* write HGP data to SLIM at the required longword offset */
memset(&hgp, 0, sizeof(struct lpfc_hgp));
to_slim = phba->MBslimaddr + (SLIMOFF*sizeof (uint32_t));
- lpfc_memcpy_to_slim(to_slim, &hgp, sizeof(struct lpfc_hgp));
+
+ for (i=0; i < phba->sli.num_rings; i++) {
+ lpfc_memcpy_to_slim(to_slim, &hgp, sizeof(struct lpfc_hgp));
+ to_slim += sizeof (struct lpfc_hgp);
+ }
/* Setup Port Group ring pointer */
offset = (uint8_t *)&phba->slim2p->mbx.us.s2.port -
diff --git a/drivers/scsi/lpfc/lpfc_mem.c b/drivers/scsi/lpfc/lpfc_mem.c
index 0aba13ceaacf..352df47bcaca 100644
--- a/drivers/scsi/lpfc/lpfc_mem.c
+++ b/drivers/scsi/lpfc/lpfc_mem.c
@@ -39,7 +39,7 @@
#define LPFC_MEM_POOL_SIZE 64 /* max elem in non-DMA safety pool */
static void *
-lpfc_pool_kmalloc(unsigned int gfp_flags, void *data)
+lpfc_pool_kmalloc(gfp_t gfp_flags, void *data)
{
return kmalloc((unsigned long)data, gfp_flags);
}
diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c
index 9b35eaac781d..507a6af56f42 100644
--- a/drivers/scsi/lpfc/lpfc_nportdisc.c
+++ b/drivers/scsi/lpfc/lpfc_nportdisc.c
@@ -187,10 +187,8 @@ lpfc_els_abort(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp,
spin_unlock_irq(phba->host->host_lock);
(iocb->iocb_cmpl) (phba, iocb, iocb);
spin_lock_irq(phba->host->host_lock);
- } else {
- list_add_tail(&iocb->list,
- &phba->lpfc_iocb_list);
- }
+ } else
+ lpfc_sli_release_iocbq(phba, iocb);
break;
}
}
@@ -232,10 +230,8 @@ lpfc_els_abort(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp,
spin_unlock_irq(phba->host->host_lock);
(iocb->iocb_cmpl) (phba, iocb, iocb);
spin_lock_irq(phba->host->host_lock);
- } else {
- list_add_tail(&iocb->list,
- &phba->lpfc_iocb_list);
- }
+ } else
+ lpfc_sli_release_iocbq(phba, iocb);
break;
}
}
@@ -1086,11 +1082,7 @@ lpfc_cmpl_reglogin_reglogin_issue(struct lpfc_hba * phba,
return (ndlp->nlp_state);
}
- if (ndlp->nlp_rpi != 0)
- lpfc_findnode_remove_rpi(phba, ndlp->nlp_rpi);
-
ndlp->nlp_rpi = mb->un.varWords[0];
- lpfc_addnode_rpi(phba, ndlp, ndlp->nlp_rpi);
/* Only if we are not a fabric nport do we issue PRLI */
if (!(ndlp->nlp_type & NLP_FABRIC)) {
@@ -1593,12 +1585,7 @@ lpfc_cmpl_reglogin_npr_node(struct lpfc_hba * phba,
pmb = (LPFC_MBOXQ_t *) arg;
mb = &pmb->mb;
- /* save rpi */
- if (ndlp->nlp_rpi != 0)
- lpfc_findnode_remove_rpi(phba, ndlp->nlp_rpi);
-
ndlp->nlp_rpi = mb->un.varWords[0];
- lpfc_addnode_rpi(phba, ndlp, ndlp->nlp_rpi);
return (ndlp->nlp_state);
}
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c
index b5ad1871d34b..c63275e66e2e 100644
--- a/drivers/scsi/lpfc/lpfc_scsi.c
+++ b/drivers/scsi/lpfc/lpfc_scsi.c
@@ -50,12 +50,13 @@
* and the BPL BDE is setup in the IOCB.
*/
static struct lpfc_scsi_buf *
-lpfc_get_scsi_buf(struct lpfc_hba * phba)
+lpfc_new_scsi_buf(struct lpfc_hba * phba)
{
struct lpfc_scsi_buf *psb;
struct ulp_bde64 *bpl;
IOCB_t *iocb;
dma_addr_t pdma_phys;
+ uint16_t iotag;
psb = kmalloc(sizeof(struct lpfc_scsi_buf), GFP_KERNEL);
if (!psb)
@@ -79,6 +80,16 @@ lpfc_get_scsi_buf(struct lpfc_hba * phba)
/* Initialize virtual ptrs to dma_buf region. */
memset(psb->data, 0, phba->cfg_sg_dma_buf_size);
+ /* Allocate iotag for psb->cur_iocbq. */
+ iotag = lpfc_sli_next_iotag(phba, &psb->cur_iocbq);
+ if (iotag == 0) {
+ pci_pool_free(phba->lpfc_scsi_dma_buf_pool,
+ psb->data, psb->dma_handle);
+ kfree (psb);
+ return NULL;
+ }
+ psb->cur_iocbq.iocb_flag |= LPFC_IO_FCP;
+
psb->fcp_cmnd = psb->data;
psb->fcp_rsp = psb->data + sizeof(struct fcp_cmnd);
psb->fcp_bpl = psb->data + sizeof(struct fcp_cmnd) +
@@ -125,11 +136,19 @@ lpfc_get_scsi_buf(struct lpfc_hba * phba)
return psb;
}
-static void
-lpfc_free_scsi_buf(struct lpfc_scsi_buf * psb)
+struct lpfc_scsi_buf*
+lpfc_sli_get_scsi_buf(struct lpfc_hba * phba)
{
- struct lpfc_hba *phba = psb->scsi_hba;
+ struct lpfc_scsi_buf * lpfc_cmd = NULL;
+ struct list_head *scsi_buf_list = &phba->lpfc_scsi_buf_list;
+
+ list_remove_head(scsi_buf_list, lpfc_cmd, struct lpfc_scsi_buf, list);
+ return lpfc_cmd;
+}
+static void
+lpfc_release_scsi_buf(struct lpfc_hba * phba, struct lpfc_scsi_buf * psb)
+{
/*
* There are only two special cases to consider. (1) the scsi command
* requested scatter-gather usage or (2) the scsi command allocated
@@ -147,6 +166,7 @@ lpfc_free_scsi_buf(struct lpfc_scsi_buf * psb)
}
}
+ psb->pCmd = NULL;
list_add_tail(&psb->list, &phba->lpfc_scsi_buf_list);
}
@@ -403,14 +423,9 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn,
break;
}
- if (pnode) {
- if (pnode->nlp_state != NLP_STE_MAPPED_NODE)
- cmd->result = ScsiResult(DID_BUS_BUSY,
- SAM_STAT_BUSY);
- }
- else {
- cmd->result = ScsiResult(DID_NO_CONNECT, 0);
- }
+ if ((pnode == NULL )
+ || (pnode->nlp_state != NLP_STE_MAPPED_NODE))
+ cmd->result = ScsiResult(DID_BUS_BUSY, SAM_STAT_BUSY);
} else {
cmd->result = ScsiResult(DID_OK, 0);
}
@@ -426,12 +441,11 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn,
*lp, *(lp + 3), cmd->retries, cmd->resid);
}
+ cmd->scsi_done(cmd);
+
spin_lock_irqsave(phba->host->host_lock, iflag);
- lpfc_free_scsi_buf(lpfc_cmd);
- cmd->host_scribble = NULL;
+ lpfc_release_scsi_buf(phba, lpfc_cmd);
spin_unlock_irqrestore(phba->host->host_lock, iflag);
-
- cmd->scsi_done(cmd);
}
static void
@@ -539,7 +553,7 @@ lpfc_scsi_prep_task_mgmt_cmd(struct lpfc_hba *phba,
struct lpfc_rport_data *rdata = scsi_dev->hostdata;
struct lpfc_nodelist *ndlp = rdata->pnode;
- if ((ndlp == 0) || (ndlp->nlp_state != NLP_STE_MAPPED_NODE)) {
+ if ((ndlp == NULL) || (ndlp->nlp_state != NLP_STE_MAPPED_NODE)) {
return 0;
}
@@ -618,8 +632,7 @@ static int
lpfc_scsi_tgt_reset(struct lpfc_scsi_buf * lpfc_cmd, struct lpfc_hba * phba)
{
struct lpfc_iocbq *iocbq;
- struct lpfc_iocbq *iocbqrsp = NULL;
- struct list_head *lpfc_iocb_list = &phba->lpfc_iocb_list;
+ struct lpfc_iocbq *iocbqrsp;
int ret;
ret = lpfc_scsi_prep_task_mgmt_cmd(phba, lpfc_cmd, FCP_TARGET_RESET);
@@ -628,17 +641,14 @@ lpfc_scsi_tgt_reset(struct lpfc_scsi_buf * lpfc_cmd, struct lpfc_hba * phba)
lpfc_cmd->scsi_hba = phba;
iocbq = &lpfc_cmd->cur_iocbq;
- list_remove_head(lpfc_iocb_list, iocbqrsp, struct lpfc_iocbq, list);
+ iocbqrsp = lpfc_sli_get_iocbq(phba);
+
if (!iocbqrsp)
return FAILED;
- memset(iocbqrsp, 0, sizeof (struct lpfc_iocbq));
-
- iocbq->iocb_flag |= LPFC_IO_POLL;
- ret = lpfc_sli_issue_iocb_wait_high_priority(phba,
- &phba->sli.ring[phba->sli.fcp_ring],
- iocbq, SLI_IOCB_HIGH_PRIORITY,
- iocbqrsp,
- lpfc_cmd->timeout);
+
+ ret = lpfc_sli_issue_iocb_wait(phba,
+ &phba->sli.ring[phba->sli.fcp_ring],
+ iocbq, iocbqrsp, lpfc_cmd->timeout);
if (ret != IOCB_SUCCESS) {
lpfc_cmd->status = IOSTAT_DRIVER_REJECT;
ret = FAILED;
@@ -651,45 +661,10 @@ lpfc_scsi_tgt_reset(struct lpfc_scsi_buf * lpfc_cmd, struct lpfc_hba * phba)
lpfc_cmd->status = IOSTAT_DRIVER_REJECT;
}
- /*
- * All outstanding txcmplq I/Os should have been aborted by the target.
- * Unfortunately, some targets do not abide by this forcing the driver
- * to double check.
- */
- lpfc_sli_abort_iocb(phba, &phba->sli.ring[phba->sli.fcp_ring],
- lpfc_cmd->pCmd->device->id,
- lpfc_cmd->pCmd->device->lun, 0, LPFC_CTX_TGT);
-
- /* Return response IOCB to free list. */
- list_add_tail(&iocbqrsp->list, lpfc_iocb_list);
+ lpfc_sli_release_iocbq(phba, iocbqrsp);
return ret;
}
-static void
-lpfc_scsi_cmd_iocb_cleanup (struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn,
- struct lpfc_iocbq *pIocbOut)
-{
- unsigned long iflag;
- struct lpfc_scsi_buf *lpfc_cmd =
- (struct lpfc_scsi_buf *) pIocbIn->context1;
-
- spin_lock_irqsave(phba->host->host_lock, iflag);
- lpfc_free_scsi_buf(lpfc_cmd);
- spin_unlock_irqrestore(phba->host->host_lock, iflag);
-}
-
-static void
-lpfc_scsi_cmd_iocb_cmpl_aborted(struct lpfc_hba *phba,
- struct lpfc_iocbq *pIocbIn,
- struct lpfc_iocbq *pIocbOut)
-{
- struct scsi_cmnd *ml_cmd =
- ((struct lpfc_scsi_buf *) pIocbIn->context1)->pCmd;
-
- lpfc_scsi_cmd_iocb_cleanup (phba, pIocbIn, pIocbOut);
- ml_cmd->host_scribble = NULL;
-}
-
const char *
lpfc_info(struct Scsi_Host *host)
{
@@ -726,43 +701,25 @@ lpfc_queuecommand(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *))
struct lpfc_sli *psli = &phba->sli;
struct lpfc_rport_data *rdata = cmnd->device->hostdata;
struct lpfc_nodelist *ndlp = rdata->pnode;
- struct lpfc_scsi_buf *lpfc_cmd = NULL;
- struct list_head *scsi_buf_list = &phba->lpfc_scsi_buf_list;
- int err = 0;
+ struct lpfc_scsi_buf *lpfc_cmd;
+ struct fc_rport *rport = starget_to_rport(scsi_target(cmnd->device));
+ int err;
- /*
- * The target pointer is guaranteed not to be NULL because the driver
- * only clears the device->hostdata field in lpfc_slave_destroy. This
- * approach guarantees no further IO calls on this target.
- */
- if (!ndlp) {
- cmnd->result = ScsiResult(DID_NO_CONNECT, 0);
+ err = fc_remote_port_chkready(rport);
+ if (err) {
+ cmnd->result = err;
goto out_fail_command;
}
/*
- * A Fibre Channel target is present and functioning only when the node
- * state is MAPPED. Any other state is a failure.
+ * Catch race where our node has transitioned, but the
+ * transport is still transitioning.
*/
- if (ndlp->nlp_state != NLP_STE_MAPPED_NODE) {
- if ((ndlp->nlp_state == NLP_STE_UNMAPPED_NODE) ||
- (ndlp->nlp_state == NLP_STE_UNUSED_NODE)) {
- cmnd->result = ScsiResult(DID_NO_CONNECT, 0);
- goto out_fail_command;
- }
- else if (ndlp->nlp_state == NLP_STE_NPR_NODE) {
- cmnd->result = ScsiResult(DID_BUS_BUSY, 0);
- goto out_fail_command;
- }
- /*
- * The device is most likely recovered and the driver
- * needs a bit more time to finish. Ask the midlayer
- * to retry.
- */
- goto out_host_busy;
+ if (!ndlp) {
+ cmnd->result = ScsiResult(DID_BUS_BUSY, 0);
+ goto out_fail_command;
}
-
- list_remove_head(scsi_buf_list, lpfc_cmd, struct lpfc_scsi_buf, list);
+ lpfc_cmd = lpfc_sli_get_scsi_buf (phba);
if (lpfc_cmd == NULL) {
printk(KERN_WARNING "%s: No buffer available - list empty, "
"total count %d\n", __FUNCTION__, phba->total_scsi_bufs);
@@ -792,7 +749,7 @@ lpfc_queuecommand(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *))
return 0;
out_host_busy_free_buf:
- lpfc_free_scsi_buf(lpfc_cmd);
+ lpfc_release_scsi_buf(phba, lpfc_cmd);
cmnd->host_scribble = NULL;
out_host_busy:
return SCSI_MLQUEUE_HOST_BUSY;
@@ -808,119 +765,91 @@ __lpfc_abort_handler(struct scsi_cmnd *cmnd)
struct lpfc_hba *phba =
(struct lpfc_hba *)cmnd->device->host->hostdata[0];
struct lpfc_sli_ring *pring = &phba->sli.ring[phba->sli.fcp_ring];
- struct lpfc_iocbq *iocb, *next_iocb;
- struct lpfc_iocbq *abtsiocb = NULL;
+ struct lpfc_iocbq *iocb;
+ struct lpfc_iocbq *abtsiocb;
struct lpfc_scsi_buf *lpfc_cmd;
- struct list_head *lpfc_iocb_list = &phba->lpfc_iocb_list;
IOCB_t *cmd, *icmd;
- unsigned long snum;
- unsigned int id, lun;
unsigned int loop_count = 0;
- int ret = IOCB_SUCCESS;
+ int ret = SUCCESS;
- /*
- * If the host_scribble data area is NULL, then the driver has already
- * completed this command, but the midlayer did not see the completion
- * before the eh fired. Just return SUCCESS.
- */
- lpfc_cmd = (struct lpfc_scsi_buf *)cmnd->host_scribble;
- if (!lpfc_cmd)
- return SUCCESS;
- /* save these now since lpfc_cmd can be freed */
- id = lpfc_cmd->pCmd->device->id;
- lun = lpfc_cmd->pCmd->device->lun;
- snum = lpfc_cmd->pCmd->serial_number;
+ lpfc_cmd = (struct lpfc_scsi_buf *)cmnd->host_scribble;
+ BUG_ON(!lpfc_cmd);
- list_for_each_entry_safe(iocb, next_iocb, &pring->txq, list) {
- cmd = &iocb->iocb;
- if (iocb->context1 != lpfc_cmd)
- continue;
+ /*
+ * If pCmd field of the corresponding lpfc_scsi_buf structure
+ * points to a different SCSI command, then the driver has
+ * already completed this command, but the midlayer did not
+ * see the completion before the eh fired. Just return
+ * SUCCESS.
+ */
+ iocb = &lpfc_cmd->cur_iocbq;
+ if (lpfc_cmd->pCmd != cmnd)
+ goto out;
- list_del_init(&iocb->list);
- pring->txq_cnt--;
- if (!iocb->iocb_cmpl) {
- list_add_tail(&iocb->list, lpfc_iocb_list);
- }
- else {
- cmd->ulpStatus = IOSTAT_LOCAL_REJECT;
- cmd->un.ulpWord[4] = IOERR_SLI_ABORTED;
- lpfc_scsi_cmd_iocb_cmpl_aborted(phba, iocb, iocb);
- }
+ BUG_ON(iocb->context1 != lpfc_cmd);
+ abtsiocb = lpfc_sli_get_iocbq(phba);
+ if (abtsiocb == NULL) {
+ ret = FAILED;
goto out;
}
- list_remove_head(lpfc_iocb_list, abtsiocb, struct lpfc_iocbq, list);
- if (abtsiocb == NULL)
- return FAILED;
-
- memset(abtsiocb, 0, sizeof (struct lpfc_iocbq));
-
/*
- * The scsi command was not in the txq. Check the txcmplq and if it is
- * found, send an abort to the FW.
+ * The scsi command can not be in txq and it is in flight because the
+ * pCmd is still pointig at the SCSI command we have to abort. There
+ * is no need to search the txcmplq. Just send an abort to the FW.
*/
- list_for_each_entry_safe(iocb, next_iocb, &pring->txcmplq, list) {
- if (iocb->context1 != lpfc_cmd)
- continue;
- iocb->iocb_cmpl = lpfc_scsi_cmd_iocb_cmpl_aborted;
- cmd = &iocb->iocb;
- icmd = &abtsiocb->iocb;
- icmd->un.acxri.abortType = ABORT_TYPE_ABTS;
- icmd->un.acxri.abortContextTag = cmd->ulpContext;
- icmd->un.acxri.abortIoTag = cmd->ulpIoTag;
-
- icmd->ulpLe = 1;
- icmd->ulpClass = cmd->ulpClass;
- if (phba->hba_state >= LPFC_LINK_UP)
- icmd->ulpCommand = CMD_ABORT_XRI_CN;
- else
- icmd->ulpCommand = CMD_CLOSE_XRI_CN;
+ cmd = &iocb->iocb;
+ icmd = &abtsiocb->iocb;
+ icmd->un.acxri.abortType = ABORT_TYPE_ABTS;
+ icmd->un.acxri.abortContextTag = cmd->ulpContext;
+ icmd->un.acxri.abortIoTag = cmd->ulpIoTag;
- abtsiocb->iocb_cmpl = lpfc_sli_abort_fcp_cmpl;
- if (lpfc_sli_issue_iocb(phba, pring, abtsiocb, 0) ==
- IOCB_ERROR) {
- list_add_tail(&abtsiocb->list, lpfc_iocb_list);
- ret = IOCB_ERROR;
- break;
- }
+ icmd->ulpLe = 1;
+ icmd->ulpClass = cmd->ulpClass;
+ if (phba->hba_state >= LPFC_LINK_UP)
+ icmd->ulpCommand = CMD_ABORT_XRI_CN;
+ else
+ icmd->ulpCommand = CMD_CLOSE_XRI_CN;
- /* Wait for abort to complete */
- while (cmnd->host_scribble)
- {
- spin_unlock_irq(phba->host->host_lock);
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(LPFC_ABORT_WAIT*HZ);
- spin_lock_irq(phba->host->host_lock);
- if (++loop_count
- > (2 * phba->cfg_nodev_tmo)/LPFC_ABORT_WAIT)
- break;
- }
+ abtsiocb->iocb_cmpl = lpfc_sli_abort_fcp_cmpl;
+ if (lpfc_sli_issue_iocb(phba, pring, abtsiocb, 0) == IOCB_ERROR) {
+ lpfc_sli_release_iocbq(phba, abtsiocb);
+ ret = FAILED;
+ goto out;
+ }
- if(cmnd->host_scribble) {
- lpfc_printf_log(phba, KERN_ERR, LOG_FCP,
- "%d:0748 abort handler timed "
- "out waiting for abort to "
- "complete. Data: "
- "x%x x%x x%x x%lx\n",
- phba->brd_no, ret, id, lun, snum);
- cmnd->host_scribble = NULL;
- iocb->iocb_cmpl = lpfc_scsi_cmd_iocb_cleanup;
- ret = IOCB_ERROR;
- }
+ /* Wait for abort to complete */
+ while (lpfc_cmd->pCmd == cmnd)
+ {
+ spin_unlock_irq(phba->host->host_lock);
+ schedule_timeout_uninterruptible(LPFC_ABORT_WAIT*HZ);
+ spin_lock_irq(phba->host->host_lock);
+ if (++loop_count
+ > (2 * phba->cfg_nodev_tmo)/LPFC_ABORT_WAIT)
+ break;
+ }
- break;
+ if (lpfc_cmd->pCmd == cmnd) {
+ ret = FAILED;
+ lpfc_printf_log(phba, KERN_ERR, LOG_FCP,
+ "%d:0748 abort handler timed out waiting for "
+ "abort to complete: ret %#x, ID %d, LUN %d, "
+ "snum %#lx\n",
+ phba->brd_no, ret, cmnd->device->id,
+ cmnd->device->lun, cmnd->serial_number);
}
out:
lpfc_printf_log(phba, KERN_WARNING, LOG_FCP,
- "%d:0749 SCSI layer issued abort device "
- "Data: x%x x%x x%x x%lx\n",
- phba->brd_no, ret, id, lun, snum);
+ "%d:0749 SCSI layer issued abort device: ret %#x, "
+ "ID %d, LUN %d, snum %#lx\n",
+ phba->brd_no, ret, cmnd->device->id,
+ cmnd->device->lun, cmnd->serial_number);
- return ret == IOCB_SUCCESS ? SUCCESS : FAILED;
+ return ret;
}
static int
@@ -938,11 +867,8 @@ __lpfc_reset_lun_handler(struct scsi_cmnd *cmnd)
{
struct Scsi_Host *shost = cmnd->device->host;
struct lpfc_hba *phba = (struct lpfc_hba *)shost->hostdata[0];
- struct lpfc_sli *psli = &phba->sli;
- struct lpfc_scsi_buf *lpfc_cmd = NULL;
- struct list_head *scsi_buf_list = &phba->lpfc_scsi_buf_list;
- struct list_head *lpfc_iocb_list = &phba->lpfc_iocb_list;
- struct lpfc_iocbq *iocbq, *iocbqrsp = NULL;
+ struct lpfc_scsi_buf *lpfc_cmd;
+ struct lpfc_iocbq *iocbq, *iocbqrsp;
struct lpfc_rport_data *rdata = cmnd->device->hostdata;
struct lpfc_nodelist *pnode = rdata->pnode;
int ret = FAILED;
@@ -958,15 +884,14 @@ __lpfc_reset_lun_handler(struct scsi_cmnd *cmnd)
if (pnode->nlp_state != NLP_STE_MAPPED_NODE) {
spin_unlock_irq(phba->host->host_lock);
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout( HZ/2);
+ schedule_timeout_uninterruptible(msecs_to_jiffies(500));
spin_lock_irq(phba->host->host_lock);
}
if ((pnode) && (pnode->nlp_state == NLP_STE_MAPPED_NODE))
break;
}
- list_remove_head(scsi_buf_list, lpfc_cmd, struct lpfc_scsi_buf, list);
+ lpfc_cmd = lpfc_sli_get_scsi_buf (phba);
if (lpfc_cmd == NULL)
goto out;
@@ -981,18 +906,13 @@ __lpfc_reset_lun_handler(struct scsi_cmnd *cmnd)
iocbq = &lpfc_cmd->cur_iocbq;
/* get a buffer for this IOCB command response */
- list_remove_head(lpfc_iocb_list, iocbqrsp, struct lpfc_iocbq, list);
+ iocbqrsp = lpfc_sli_get_iocbq(phba);
if (iocbqrsp == NULL)
goto out_free_scsi_buf;
- memset(iocbqrsp, 0, sizeof (struct lpfc_iocbq));
-
- iocbq->iocb_flag |= LPFC_IO_POLL;
- iocbq->iocb_cmpl = lpfc_sli_wake_iocb_high_priority;
-
- ret = lpfc_sli_issue_iocb_wait_high_priority(phba,
- &phba->sli.ring[psli->fcp_ring],
- iocbq, 0, iocbqrsp, 60);
+ ret = lpfc_sli_issue_iocb_wait(phba,
+ &phba->sli.ring[phba->sli.fcp_ring],
+ iocbq, iocbqrsp, lpfc_cmd->timeout);
if (ret == IOCB_SUCCESS)
ret = SUCCESS;
@@ -1017,8 +937,7 @@ __lpfc_reset_lun_handler(struct scsi_cmnd *cmnd)
cmnd->device->id, cmnd->device->lun,
LPFC_CTX_LUN))) {
spin_unlock_irq(phba->host->host_lock);
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(LPFC_RESET_WAIT*HZ);
+ schedule_timeout_uninterruptible(LPFC_RESET_WAIT*HZ);
spin_lock_irq(phba->host->host_lock);
if (++loopcnt
@@ -1027,12 +946,13 @@ __lpfc_reset_lun_handler(struct scsi_cmnd *cmnd)
}
if (cnt) {
- lpfc_printf_log(phba, KERN_INFO, LOG_FCP,
+ lpfc_printf_log(phba, KERN_ERR, LOG_FCP,
"%d:0719 LUN Reset I/O flush failure: cnt x%x\n",
phba->brd_no, cnt);
+ ret = FAILED;
}
- list_add_tail(&iocbqrsp->list, lpfc_iocb_list);
+ lpfc_sli_release_iocbq(phba, iocbqrsp);
out_free_scsi_buf:
lpfc_printf_log(phba, KERN_ERR, LOG_FCP,
@@ -1041,7 +961,7 @@ out_free_scsi_buf:
phba->brd_no, lpfc_cmd->pCmd->device->id,
lpfc_cmd->pCmd->device->lun, ret, lpfc_cmd->status,
lpfc_cmd->result);
- lpfc_free_scsi_buf(lpfc_cmd);
+ lpfc_release_scsi_buf(phba, lpfc_cmd);
out:
return ret;
}
@@ -1069,10 +989,9 @@ __lpfc_reset_bus_handler(struct scsi_cmnd *cmnd)
int ret = FAILED, i, err_count = 0;
int cnt, loopcnt;
unsigned int midlayer_id = 0;
- struct lpfc_scsi_buf * lpfc_cmd = NULL;
- struct list_head *scsi_buf_list = &phba->lpfc_scsi_buf_list;
+ struct lpfc_scsi_buf * lpfc_cmd;
- list_remove_head(scsi_buf_list, lpfc_cmd, struct lpfc_scsi_buf, list);
+ lpfc_cmd = lpfc_sli_get_scsi_buf (phba);
if (lpfc_cmd == NULL)
goto out;
@@ -1116,8 +1035,7 @@ __lpfc_reset_bus_handler(struct scsi_cmnd *cmnd)
&phba->sli.ring[phba->sli.fcp_ring],
0, 0, LPFC_CTX_HOST))) {
spin_unlock_irq(phba->host->host_lock);
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(LPFC_RESET_WAIT*HZ);
+ schedule_timeout_uninterruptible(LPFC_RESET_WAIT*HZ);
spin_lock_irq(phba->host->host_lock);
if (++loopcnt
@@ -1136,10 +1054,12 @@ __lpfc_reset_bus_handler(struct scsi_cmnd *cmnd)
phba->brd_no, cnt, i);
}
- if (!err_count)
+ if (cnt == 0)
ret = SUCCESS;
+ else
+ ret = FAILED;
- lpfc_free_scsi_buf(lpfc_cmd);
+ lpfc_release_scsi_buf(phba, lpfc_cmd);
lpfc_printf_log(phba,
KERN_ERR,
LOG_FCP,
@@ -1163,66 +1083,47 @@ static int
lpfc_slave_alloc(struct scsi_device *sdev)
{
struct lpfc_hba *phba = (struct lpfc_hba *)sdev->host->hostdata[0];
- struct lpfc_nodelist *ndlp = NULL;
- int match = 0;
struct lpfc_scsi_buf *scsi_buf = NULL;
+ struct fc_rport *rport = starget_to_rport(scsi_target(sdev));
uint32_t total = 0, i;
uint32_t num_to_alloc = 0;
unsigned long flags;
- struct list_head *listp;
- struct list_head *node_list[6];
-
- /*
- * Store the target pointer in the scsi_device hostdata pointer provided
- * the driver has already discovered the target id.
- */
-
- /* Search the nlp lists other than unmap_list for this target ID */
- node_list[0] = &phba->fc_npr_list;
- node_list[1] = &phba->fc_nlpmap_list;
- node_list[2] = &phba->fc_prli_list;
- node_list[3] = &phba->fc_reglogin_list;
- node_list[4] = &phba->fc_adisc_list;
- node_list[5] = &phba->fc_plogi_list;
-
- for (i = 0; i < 6 && !match; i++) {
- listp = node_list[i];
- if (list_empty(listp))
- continue;
- list_for_each_entry(ndlp, listp, nlp_listp) {
- if ((sdev->id == ndlp->nlp_sid) && ndlp->rport) {
- match = 1;
- break;
- }
- }
- }
- if (!match)
+ if (!rport || fc_remote_port_chkready(rport))
return -ENXIO;
- sdev->hostdata = ndlp->rport->dd_data;
+ sdev->hostdata = rport->dd_data;
/*
* Populate the cmds_per_lun count scsi_bufs into this host's globally
* available list of scsi buffers. Don't allocate more than the
- * HBA limit conveyed to the midlayer via the host structure. Note
- * that this list of scsi bufs exists for the lifetime of the driver.
+ * HBA limit conveyed to the midlayer via the host structure. The
+ * formula accounts for the lun_queue_depth + error handlers + 1
+ * extra. This list of scsi bufs exists for the lifetime of the driver.
*/
total = phba->total_scsi_bufs;
- num_to_alloc = LPFC_CMD_PER_LUN;
+ num_to_alloc = phba->cfg_lun_queue_depth + 2;
if (total >= phba->cfg_hba_queue_depth) {
- printk(KERN_WARNING "%s, At config limitation of "
- "%d allocated scsi_bufs\n", __FUNCTION__, total);
+ lpfc_printf_log(phba, KERN_WARNING, LOG_FCP,
+ "%d:0704 At limitation of %d preallocated "
+ "command buffers\n", phba->brd_no, total);
return 0;
} else if (total + num_to_alloc > phba->cfg_hba_queue_depth) {
+ lpfc_printf_log(phba, KERN_WARNING, LOG_FCP,
+ "%d:0705 Allocation request of %d command "
+ "buffers will exceed max of %d. Reducing "
+ "allocation request to %d.\n", phba->brd_no,
+ num_to_alloc, phba->cfg_hba_queue_depth,
+ (phba->cfg_hba_queue_depth - total));
num_to_alloc = phba->cfg_hba_queue_depth - total;
}
for (i = 0; i < num_to_alloc; i++) {
- scsi_buf = lpfc_get_scsi_buf(phba);
+ scsi_buf = lpfc_new_scsi_buf(phba);
if (!scsi_buf) {
- printk(KERN_ERR "%s, failed to allocate "
- "scsi_buf\n", __FUNCTION__);
+ lpfc_printf_log(phba, KERN_ERR, LOG_FCP,
+ "%d:0706 Failed to allocate command "
+ "buffer\n", phba->brd_no);
break;
}
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
index e74e224fd77c..e2c08c5d83fb 100644
--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -65,6 +65,28 @@ typedef enum _lpfc_iocb_type {
LPFC_ABORT_IOCB
} lpfc_iocb_type;
+struct lpfc_iocbq *
+lpfc_sli_get_iocbq(struct lpfc_hba * phba)
+{
+ struct list_head *lpfc_iocb_list = &phba->lpfc_iocb_list;
+ struct lpfc_iocbq * iocbq = NULL;
+
+ list_remove_head(lpfc_iocb_list, iocbq, struct lpfc_iocbq, list);
+ return iocbq;
+}
+
+void
+lpfc_sli_release_iocbq(struct lpfc_hba * phba, struct lpfc_iocbq * iocbq)
+{
+ size_t start_clean = (size_t)(&((struct lpfc_iocbq *)NULL)->iocb);
+
+ /*
+ * Clean all volatile data fields, preserve iotag and node struct.
+ */
+ memset((char*)iocbq + start_clean, 0, sizeof(*iocbq) - start_clean);
+ list_add_tail(&iocbq->list, &phba->lpfc_iocb_list);
+}
+
/*
* Translate the iocb command to an iocb command type used to decide the final
* disposition of each completed IOCB.
@@ -265,41 +287,69 @@ lpfc_sli_next_iocb_slot (struct lpfc_hba *phba, struct lpfc_sli_ring *pring)
return iocb;
}
-static uint32_t
-lpfc_sli_next_iotag(struct lpfc_hba * phba, struct lpfc_sli_ring * pring)
+uint16_t
+lpfc_sli_next_iotag(struct lpfc_hba * phba, struct lpfc_iocbq * iocbq)
{
- uint32_t search_start;
+ struct lpfc_iocbq ** new_arr;
+ struct lpfc_iocbq ** old_arr;
+ size_t new_len;
+ struct lpfc_sli *psli = &phba->sli;
+ uint16_t iotag;
- if (pring->fast_lookup == NULL) {
- pring->iotag_ctr++;
- if (pring->iotag_ctr >= pring->iotag_max)
- pring->iotag_ctr = 1;
- return pring->iotag_ctr;
+ spin_lock_irq(phba->host->host_lock);
+ iotag = psli->last_iotag;
+ if(++iotag < psli->iocbq_lookup_len) {
+ psli->last_iotag = iotag;
+ psli->iocbq_lookup[iotag] = iocbq;
+ spin_unlock_irq(phba->host->host_lock);
+ iocbq->iotag = iotag;
+ return iotag;
+ }
+ else if (psli->iocbq_lookup_len < (0xffff
+ - LPFC_IOCBQ_LOOKUP_INCREMENT)) {
+ new_len = psli->iocbq_lookup_len + LPFC_IOCBQ_LOOKUP_INCREMENT;
+ spin_unlock_irq(phba->host->host_lock);
+ new_arr = kmalloc(new_len * sizeof (struct lpfc_iocbq *),
+ GFP_KERNEL);
+ if (new_arr) {
+ memset((char *)new_arr, 0,
+ new_len * sizeof (struct lpfc_iocbq *));
+ spin_lock_irq(phba->host->host_lock);
+ old_arr = psli->iocbq_lookup;
+ if (new_len <= psli->iocbq_lookup_len) {
+ /* highly unprobable case */
+ kfree(new_arr);
+ iotag = psli->last_iotag;
+ if(++iotag < psli->iocbq_lookup_len) {
+ psli->last_iotag = iotag;
+ psli->iocbq_lookup[iotag] = iocbq;
+ spin_unlock_irq(phba->host->host_lock);
+ iocbq->iotag = iotag;
+ return iotag;
+ }
+ spin_unlock_irq(phba->host->host_lock);
+ return 0;
+ }
+ if (psli->iocbq_lookup)
+ memcpy(new_arr, old_arr,
+ ((psli->last_iotag + 1) *
+ sizeof (struct lpfc_iocbq *)));
+ psli->iocbq_lookup = new_arr;
+ psli->iocbq_lookup_len = new_len;
+ psli->last_iotag = iotag;
+ psli->iocbq_lookup[iotag] = iocbq;
+ spin_unlock_irq(phba->host->host_lock);
+ iocbq->iotag = iotag;
+ kfree(old_arr);
+ return iotag;
+ }
}
- search_start = pring->iotag_ctr;
-
- do {
- pring->iotag_ctr++;
- if (pring->iotag_ctr >= pring->fast_iotag)
- pring->iotag_ctr = 1;
-
- if (*(pring->fast_lookup + pring->iotag_ctr) == NULL)
- return pring->iotag_ctr;
-
- } while (pring->iotag_ctr != search_start);
+ lpfc_printf_log(phba, KERN_ERR,LOG_SLI,
+ "%d:0318 Failed to allocate IOTAG.last IOTAG is %d\n",
+ phba->brd_no, psli->last_iotag);
- /*
- * Outstanding I/O count for ring <ringno> is at max <fast_iotag>
- */
- lpfc_printf_log(phba,
- KERN_ERR,
- LOG_SLI,
- "%d:0318 Outstanding I/O count for ring %d is at max x%x\n",
- phba->brd_no,
- pring->ringno,
- pring->fast_iotag);
- return (0);
+ return 0;
}
static void
@@ -307,10 +357,9 @@ lpfc_sli_submit_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
IOCB_t *iocb, struct lpfc_iocbq *nextiocb)
{
/*
- * Allocate and set up an iotag
+ * Set up an iotag
*/
- nextiocb->iocb.ulpIoTag =
- lpfc_sli_next_iotag(phba, &phba->sli.ring[phba->sli.fcp_ring]);
+ nextiocb->iocb.ulpIoTag = (nextiocb->iocb_cmpl) ? nextiocb->iotag : 0;
/*
* Issue iocb command to adapter
@@ -326,16 +375,15 @@ lpfc_sli_submit_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
*/
if (nextiocb->iocb_cmpl)
lpfc_sli_ringtxcmpl_put(phba, pring, nextiocb);
- else {
- list_add_tail(&nextiocb->list, &phba->lpfc_iocb_list);
- }
+ else
+ lpfc_sli_release_iocbq(phba, nextiocb);
/*
* Let the HBA know what IOCB slot will be the next one the
* driver will put a command into.
*/
pring->cmdidx = pring->next_cmdidx;
- writeb(pring->cmdidx, phba->MBslimaddr
+ writel(pring->cmdidx, phba->MBslimaddr
+ (SLIMOFF + (pring->ringno * 2)) * 4);
}
@@ -752,80 +800,28 @@ lpfc_sli_process_unsol_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
}
static struct lpfc_iocbq *
-lpfc_sli_txcmpl_ring_search_slow(struct lpfc_sli_ring * pring,
- struct lpfc_iocbq * prspiocb)
-{
- IOCB_t *icmd = NULL;
- IOCB_t *irsp = NULL;
- struct lpfc_iocbq *cmd_iocb;
- struct lpfc_iocbq *iocb, *next_iocb;
- uint16_t iotag;
-
- irsp = &prspiocb->iocb;
- iotag = irsp->ulpIoTag;
- cmd_iocb = NULL;
-
- /* Search through txcmpl from the begining */
- list_for_each_entry_safe(iocb, next_iocb, &(pring->txcmplq), list) {
- icmd = &iocb->iocb;
- if (iotag == icmd->ulpIoTag) {
- /* Found a match. */
- cmd_iocb = iocb;
- list_del(&iocb->list);
- pring->txcmplq_cnt--;
- break;
- }
- }
-
- return (cmd_iocb);
-}
-
-static struct lpfc_iocbq *
-lpfc_sli_txcmpl_ring_iotag_lookup(struct lpfc_hba * phba,
- struct lpfc_sli_ring * pring,
- struct lpfc_iocbq * prspiocb)
+lpfc_sli_iocbq_lookup(struct lpfc_hba * phba,
+ struct lpfc_sli_ring * pring,
+ struct lpfc_iocbq * prspiocb)
{
- IOCB_t *irsp = NULL;
struct lpfc_iocbq *cmd_iocb = NULL;
uint16_t iotag;
- if (unlikely(pring->fast_lookup == NULL))
- return NULL;
-
- /* Use fast lookup based on iotag for completion */
- irsp = &prspiocb->iocb;
- iotag = irsp->ulpIoTag;
- if (iotag < pring->fast_iotag) {
- cmd_iocb = *(pring->fast_lookup + iotag);
- *(pring->fast_lookup + iotag) = NULL;
- if (cmd_iocb) {
- list_del(&cmd_iocb->list);
- pring->txcmplq_cnt--;
- return cmd_iocb;
- } else {
- /*
- * This is clearly an error. A ring that uses iotags
- * should never have a interrupt for a completion that
- * is not on the ring. Return NULL and log a error.
- */
- lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
- "%d:0327 Rsp ring %d error - command "
- "completion for iotag x%x not found\n",
- phba->brd_no, pring->ringno, iotag);
- return NULL;
- }
+ iotag = prspiocb->iocb.ulpIoTag;
+
+ if (iotag != 0 && iotag <= phba->sli.last_iotag) {
+ cmd_iocb = phba->sli.iocbq_lookup[iotag];
+ list_del(&cmd_iocb->list);
+ pring->txcmplq_cnt--;
+ return cmd_iocb;
}
- /*
- * Rsp ring <ringno> get: iotag <iotag> greater then
- * configured max <fast_iotag> wd0 <irsp>. This is an
- * error. Just return NULL.
- */
lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
- "%d:0317 Rsp ring %d get: iotag x%x greater then "
- "configured max x%x wd0 x%x\n",
- phba->brd_no, pring->ringno, iotag, pring->fast_iotag,
- *(((uint32_t *) irsp) + 7));
+ "%d:0317 iotag x%x is out off "
+ "range: max iotag x%x wd0 x%x\n",
+ phba->brd_no, iotag,
+ phba->sli.last_iotag,
+ *(((uint32_t *) &prspiocb->iocb) + 7));
return NULL;
}
@@ -839,7 +835,7 @@ lpfc_sli_process_sol_iocb(struct lpfc_hba * phba, struct lpfc_sli_ring * pring,
/* Based on the iotag field, get the cmd IOCB from the txcmplq */
spin_lock_irqsave(phba->host->host_lock, iflag);
- cmdiocbp = lpfc_sli_txcmpl_ring_search_slow(pring, saveq);
+ cmdiocbp = lpfc_sli_iocbq_lookup(phba, pring, saveq);
if (cmdiocbp) {
if (cmdiocbp->iocb_cmpl) {
/*
@@ -853,17 +849,13 @@ lpfc_sli_process_sol_iocb(struct lpfc_hba * phba, struct lpfc_sli_ring * pring,
spin_lock_irqsave(phba->host->host_lock, iflag);
}
else {
- if (cmdiocbp->iocb_flag & LPFC_IO_POLL)
- rc = 0;
-
spin_unlock_irqrestore(phba->host->host_lock,
iflag);
(cmdiocbp->iocb_cmpl) (phba, cmdiocbp, saveq);
spin_lock_irqsave(phba->host->host_lock, iflag);
}
- } else {
- list_add_tail(&cmdiocbp->list, &phba->lpfc_iocb_list);
- }
+ } else
+ lpfc_sli_release_iocbq(phba, cmdiocbp);
} else {
/*
* Unknown initiating command based on the response iotag.
@@ -889,6 +881,7 @@ lpfc_sli_process_sol_iocb(struct lpfc_hba * phba, struct lpfc_sli_ring * pring,
saveq->iocb.ulpContext);
}
}
+
spin_unlock_irqrestore(phba->host->host_lock, iflag);
return rc;
}
@@ -953,7 +946,7 @@ lpfc_sli_handle_fast_ring_event(struct lpfc_hba * phba,
* structure. The copy involves a byte-swap since the
* network byte order and pci byte orders are different.
*/
- entry = (IOCB_t *) IOCB_ENTRY(pring->rspringaddr, pring->rspidx);
+ entry = IOCB_ENTRY(pring->rspringaddr, pring->rspidx);
lpfc_sli_pcimem_bcopy((uint32_t *) entry,
(uint32_t *) &rspiocbq.iocb,
sizeof (IOCB_t));
@@ -990,9 +983,8 @@ lpfc_sli_handle_fast_ring_event(struct lpfc_hba * phba,
break;
}
- cmdiocbq = lpfc_sli_txcmpl_ring_iotag_lookup(phba,
- pring,
- &rspiocbq);
+ cmdiocbq = lpfc_sli_iocbq_lookup(phba, pring,
+ &rspiocbq);
if ((cmdiocbq) && (cmdiocbq->iocb_cmpl)) {
spin_unlock_irqrestore(
phba->host->host_lock, iflag);
@@ -1033,7 +1025,7 @@ lpfc_sli_handle_fast_ring_event(struct lpfc_hba * phba,
to_slim = phba->MBslimaddr +
(SLIMOFF + (pring->ringno * 2) + 1) * 4;
- writeb(pring->rspidx, to_slim);
+ writel(pring->rspidx, to_slim);
if (pring->rspidx == portRspPut)
portRspPut = le32_to_cpu(pgp->rspPutInx);
@@ -1073,7 +1065,6 @@ lpfc_sli_handle_slow_ring_event(struct lpfc_hba * phba,
struct lpfc_iocbq *next_iocb;
struct lpfc_iocbq *cmdiocbp;
struct lpfc_iocbq *saveq;
- struct list_head *lpfc_iocb_list = &phba->lpfc_iocb_list;
struct lpfc_pgp *pgp = &phba->slim2p->mbx.us.s2.port[pring->ringno];
uint8_t iocb_cmd_type;
lpfc_iocb_type type;
@@ -1115,7 +1106,6 @@ lpfc_sli_handle_slow_ring_event(struct lpfc_hba * phba,
}
rmb();
- lpfc_iocb_list = &phba->lpfc_iocb_list;
while (pring->rspidx != portRspPut) {
/*
* Build a completion list and call the appropriate handler.
@@ -1131,8 +1121,7 @@ lpfc_sli_handle_slow_ring_event(struct lpfc_hba * phba,
* received.
*/
entry = IOCB_ENTRY(pring->rspringaddr, pring->rspidx);
- list_remove_head(lpfc_iocb_list, rspiocbp, struct lpfc_iocbq,
- list);
+ rspiocbp = lpfc_sli_get_iocbq(phba);
if (rspiocbp == NULL) {
printk(KERN_ERR "%s: out of buffers! Failing "
"completion.\n", __FUNCTION__);
@@ -1147,7 +1136,7 @@ lpfc_sli_handle_slow_ring_event(struct lpfc_hba * phba,
to_slim = phba->MBslimaddr + (SLIMOFF + (pring->ringno * 2)
+ 1) * 4;
- writeb(pring->rspidx, to_slim);
+ writel(pring->rspidx, to_slim);
if (list_empty(&(pring->iocb_continueq))) {
list_add(&rspiocbp->list, &(pring->iocb_continueq));
@@ -1213,8 +1202,8 @@ lpfc_sli_handle_slow_ring_event(struct lpfc_hba * phba,
} else if (type == LPFC_ABORT_IOCB) {
if ((irsp->ulpCommand != CMD_XRI_ABORTED_CX) &&
((cmdiocbp =
- lpfc_sli_txcmpl_ring_search_slow(pring,
- saveq)))) {
+ lpfc_sli_iocbq_lookup(phba, pring,
+ saveq)))) {
/* Call the specified completion
routine */
if (cmdiocbp->iocb_cmpl) {
@@ -1226,10 +1215,9 @@ lpfc_sli_handle_slow_ring_event(struct lpfc_hba * phba,
spin_lock_irqsave(
phba->host->host_lock,
iflag);
- } else {
- list_add_tail(&cmdiocbp->list,
- lpfc_iocb_list);
- }
+ } else
+ lpfc_sli_release_iocbq(phba,
+ cmdiocbp);
}
} else if (type == LPFC_UNKNOWN_IOCB) {
if (irsp->ulpCommand == CMD_ADAPTER_MSG) {
@@ -1264,12 +1252,12 @@ lpfc_sli_handle_slow_ring_event(struct lpfc_hba * phba,
next_iocb,
&saveq->list,
list) {
- list_add_tail(&rspiocbp->list,
- lpfc_iocb_list);
+ lpfc_sli_release_iocbq(phba,
+ rspiocbp);
}
}
- list_add_tail(&saveq->list, lpfc_iocb_list);
+ lpfc_sli_release_iocbq(phba, saveq);
}
}
@@ -1314,7 +1302,6 @@ lpfc_sli_abort_iocb_ring(struct lpfc_hba *phba, struct lpfc_sli_ring *pring)
struct lpfc_iocbq *iocb, *next_iocb;
IOCB_t *icmd = NULL, *cmd = NULL;
int errcnt;
- uint16_t iotag;
errcnt = 0;
@@ -1331,9 +1318,8 @@ lpfc_sli_abort_iocb_ring(struct lpfc_hba *phba, struct lpfc_sli_ring *pring)
spin_unlock_irq(phba->host->host_lock);
(iocb->iocb_cmpl) (phba, iocb, iocb);
spin_lock_irq(phba->host->host_lock);
- } else {
- list_add_tail(&iocb->list, &phba->lpfc_iocb_list);
- }
+ } else
+ lpfc_sli_release_iocbq(phba, iocb);
}
pring->txq_cnt = 0;
INIT_LIST_HEAD(&(pring->txq));
@@ -1343,13 +1329,8 @@ lpfc_sli_abort_iocb_ring(struct lpfc_hba *phba, struct lpfc_sli_ring *pring)
cmd = &iocb->iocb;
/*
- * Imediate abort of IOCB, clear fast_lookup entry,
- * if any, deque and call compl
+ * Imediate abort of IOCB, deque and call compl
*/
- iotag = cmd->ulpIoTag;
- if (iotag && pring->fast_lookup &&
- (iotag < pring->fast_iotag))
- pring->fast_lookup[iotag] = NULL;
list_del_init(&iocb->list);
pring->txcmplq_cnt--;
@@ -1360,9 +1341,8 @@ lpfc_sli_abort_iocb_ring(struct lpfc_hba *phba, struct lpfc_sli_ring *pring)
spin_unlock_irq(phba->host->host_lock);
(iocb->iocb_cmpl) (phba, iocb, iocb);
spin_lock_irq(phba->host->host_lock);
- } else {
- list_add_tail(&iocb->list, &phba->lpfc_iocb_list);
- }
+ } else
+ lpfc_sli_release_iocbq(phba, iocb);
}
INIT_LIST_HEAD(&pring->txcmplq);
@@ -2147,6 +2127,10 @@ lpfc_sli_setup(struct lpfc_hba *phba)
psli->next_ring = LPFC_FCP_NEXT_RING;
psli->ip_ring = LPFC_IP_RING;
+ psli->iocbq_lookup = NULL;
+ psli->iocbq_lookup_len = 0;
+ psli->last_iotag = 0;
+
for (i = 0; i < psli->num_rings; i++) {
pring = &psli->ring[i];
switch (i) {
@@ -2222,7 +2206,7 @@ lpfc_sli_queue_setup(struct lpfc_hba * phba)
{
struct lpfc_sli *psli;
struct lpfc_sli_ring *pring;
- int i, cnt;
+ int i;
psli = &phba->sli;
spin_lock_irq(phba->host->host_lock);
@@ -2238,19 +2222,6 @@ lpfc_sli_queue_setup(struct lpfc_hba * phba)
INIT_LIST_HEAD(&pring->txcmplq);
INIT_LIST_HEAD(&pring->iocb_continueq);
INIT_LIST_HEAD(&pring->postbufq);
- cnt = pring->fast_iotag;
- spin_unlock_irq(phba->host->host_lock);
- if (cnt) {
- pring->fast_lookup =
- kmalloc(cnt * sizeof (struct lpfc_iocbq *),
- GFP_KERNEL);
- if (pring->fast_lookup == 0) {
- return (0);
- }
- memset((char *)pring->fast_lookup, 0,
- cnt * sizeof (struct lpfc_iocbq *));
- }
- spin_lock_irq(phba->host->host_lock);
}
spin_unlock_irq(phba->host->host_lock);
return (1);
@@ -2292,19 +2263,14 @@ lpfc_sli_hba_down(struct lpfc_hba * phba)
flags);
(iocb->iocb_cmpl) (phba, iocb, iocb);
spin_lock_irqsave(phba->host->host_lock, flags);
- } else {
- list_add_tail(&iocb->list,
- &phba->lpfc_iocb_list);
- }
+ } else
+ lpfc_sli_release_iocbq(phba, iocb);
}
INIT_LIST_HEAD(&(pring->txq));
- if (pring->fast_lookup) {
- kfree(pring->fast_lookup);
- pring->fast_lookup = NULL;
- }
-
+ kfree(pring->fast_lookup);
+ pring->fast_lookup = NULL;
}
spin_unlock_irqrestore(phba->host->host_lock, flags);
@@ -2436,7 +2402,7 @@ lpfc_sli_abort_elsreq_cmpl(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
kfree(buf_ptr);
}
- list_add_tail(&cmdiocb->list, &phba->lpfc_iocb_list);
+ lpfc_sli_release_iocbq(phba, cmdiocb);
return;
}
@@ -2445,16 +2411,14 @@ lpfc_sli_issue_abort_iotag32(struct lpfc_hba * phba,
struct lpfc_sli_ring * pring,
struct lpfc_iocbq * cmdiocb)
{
- struct list_head *lpfc_iocb_list = &phba->lpfc_iocb_list;
- struct lpfc_iocbq *abtsiocbp = NULL;
+ struct lpfc_iocbq *abtsiocbp;
IOCB_t *icmd = NULL;
IOCB_t *iabt = NULL;
/* issue ABTS for this IOCB based on iotag */
- list_remove_head(lpfc_iocb_list, abtsiocbp, struct lpfc_iocbq, list);
+ abtsiocbp = lpfc_sli_get_iocbq(phba);
if (abtsiocbp == NULL)
return 0;
- memset(abtsiocbp, 0, sizeof (struct lpfc_iocbq));
iabt = &abtsiocbp->iocb;
icmd = &cmdiocb->iocb;
@@ -2473,7 +2437,7 @@ lpfc_sli_issue_abort_iotag32(struct lpfc_hba * phba,
abtsiocbp->iocb_cmpl = lpfc_sli_abort_elsreq_cmpl;
break;
default:
- list_add_tail(&abtsiocbp->list, lpfc_iocb_list);
+ lpfc_sli_release_iocbq(phba, abtsiocbp);
return 0;
}
@@ -2485,7 +2449,7 @@ lpfc_sli_issue_abort_iotag32(struct lpfc_hba * phba,
iabt->ulpCommand = CMD_ABORT_MXRI64_CN;
if (lpfc_sli_issue_iocb(phba, pring, abtsiocbp, 0) == IOCB_ERROR) {
- list_add_tail(&abtsiocbp->list, lpfc_iocb_list);
+ lpfc_sli_release_iocbq(phba, abtsiocbp);
return 0;
}
@@ -2493,28 +2457,37 @@ lpfc_sli_issue_abort_iotag32(struct lpfc_hba * phba,
}
static int
-lpfc_sli_validate_iocb_cmd(struct lpfc_scsi_buf *lpfc_cmd, uint16_t tgt_id,
- uint64_t lun_id, struct lpfc_iocbq *iocb,
- uint32_t ctx, lpfc_ctx_cmd ctx_cmd)
+lpfc_sli_validate_fcp_iocb(struct lpfc_iocbq *iocbq, uint16_t tgt_id,
+ uint64_t lun_id, uint32_t ctx,
+ lpfc_ctx_cmd ctx_cmd)
{
+ struct lpfc_scsi_buf *lpfc_cmd;
+ struct scsi_cmnd *cmnd;
int rc = 1;
- if (lpfc_cmd == NULL)
+ if (!(iocbq->iocb_flag & LPFC_IO_FCP))
+ return rc;
+
+ lpfc_cmd = container_of(iocbq, struct lpfc_scsi_buf, cur_iocbq);
+ cmnd = lpfc_cmd->pCmd;
+
+ if (cmnd == NULL)
return rc;
switch (ctx_cmd) {
case LPFC_CTX_LUN:
- if ((lpfc_cmd->pCmd->device->id == tgt_id) &&
- (lpfc_cmd->pCmd->device->lun == lun_id))
+ if ((cmnd->device->id == tgt_id) &&
+ (cmnd->device->lun == lun_id))
rc = 0;
break;
case LPFC_CTX_TGT:
- if (lpfc_cmd->pCmd->device->id == tgt_id)
+ if (cmnd->device->id == tgt_id)
rc = 0;
break;
case LPFC_CTX_CTX:
- if (iocb->iocb.ulpContext == ctx)
+ if (iocbq->iocb.ulpContext == ctx)
rc = 0;
+ break;
case LPFC_CTX_HOST:
rc = 0;
break;
@@ -2531,30 +2504,17 @@ int
lpfc_sli_sum_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
uint16_t tgt_id, uint64_t lun_id, lpfc_ctx_cmd ctx_cmd)
{
- struct lpfc_iocbq *iocb, *next_iocb;
- IOCB_t *cmd = NULL;
- struct lpfc_scsi_buf *lpfc_cmd;
- int sum = 0, ret_val = 0;
-
- /* Next check the txcmplq */
- list_for_each_entry_safe(iocb, next_iocb, &pring->txcmplq, list) {
- cmd = &iocb->iocb;
+ struct lpfc_iocbq *iocbq;
+ int sum, i;
- /* Must be a FCP command */
- if ((cmd->ulpCommand != CMD_FCP_ICMND64_CR) &&
- (cmd->ulpCommand != CMD_FCP_IWRITE64_CR) &&
- (cmd->ulpCommand != CMD_FCP_IREAD64_CR)) {
- continue;
- }
+ for (i = 1, sum = 0; i <= phba->sli.last_iotag; i++) {
+ iocbq = phba->sli.iocbq_lookup[i];
- /* context1 MUST be a struct lpfc_scsi_buf */
- lpfc_cmd = (struct lpfc_scsi_buf *) (iocb->context1);
- ret_val = lpfc_sli_validate_iocb_cmd(lpfc_cmd, tgt_id, lun_id,
- NULL, 0, ctx_cmd);
- if (ret_val != 0)
- continue;
- sum++;
+ if (lpfc_sli_validate_fcp_iocb (iocbq, tgt_id, lun_id,
+ 0, ctx_cmd) == 0)
+ sum++;
}
+
return sum;
}
@@ -2563,7 +2523,7 @@ lpfc_sli_abort_fcp_cmpl(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
struct lpfc_iocbq * rspiocb)
{
spin_lock_irq(phba->host->host_lock);
- list_add_tail(&cmdiocb->list, &phba->lpfc_iocb_list);
+ lpfc_sli_release_iocbq(phba, cmdiocb);
spin_unlock_irq(phba->host->host_lock);
return;
}
@@ -2573,39 +2533,27 @@ lpfc_sli_abort_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
uint16_t tgt_id, uint64_t lun_id, uint32_t ctx,
lpfc_ctx_cmd abort_cmd)
{
- struct lpfc_iocbq *iocb, *next_iocb;
- struct lpfc_iocbq *abtsiocb = NULL;
- struct list_head *lpfc_iocb_list = &phba->lpfc_iocb_list;
+ struct lpfc_iocbq *iocbq;
+ struct lpfc_iocbq *abtsiocb;
IOCB_t *cmd = NULL;
- struct lpfc_scsi_buf *lpfc_cmd;
int errcnt = 0, ret_val = 0;
+ int i;
- list_for_each_entry_safe(iocb, next_iocb, &pring->txcmplq, list) {
- cmd = &iocb->iocb;
-
- /* Must be a FCP command */
- if ((cmd->ulpCommand != CMD_FCP_ICMND64_CR) &&
- (cmd->ulpCommand != CMD_FCP_IWRITE64_CR) &&
- (cmd->ulpCommand != CMD_FCP_IREAD64_CR)) {
- continue;
- }
+ for (i = 1; i <= phba->sli.last_iotag; i++) {
+ iocbq = phba->sli.iocbq_lookup[i];
- /* context1 MUST be a struct lpfc_scsi_buf */
- lpfc_cmd = (struct lpfc_scsi_buf *) (iocb->context1);
- ret_val = lpfc_sli_validate_iocb_cmd(lpfc_cmd, tgt_id, lun_id,
- iocb, ctx, abort_cmd);
- if (ret_val != 0)
+ if (lpfc_sli_validate_fcp_iocb (iocbq, tgt_id, lun_id,
+ 0, abort_cmd) != 0)
continue;
/* issue ABTS for this IOCB based on iotag */
- list_remove_head(lpfc_iocb_list, abtsiocb, struct lpfc_iocbq,
- list);
+ abtsiocb = lpfc_sli_get_iocbq(phba);
if (abtsiocb == NULL) {
errcnt++;
continue;
}
- memset(abtsiocb, 0, sizeof (struct lpfc_iocbq));
+ cmd = &iocbq->iocb;
abtsiocb->iocb.un.acxri.abortType = ABORT_TYPE_ABTS;
abtsiocb->iocb.un.acxri.abortContextTag = cmd->ulpContext;
abtsiocb->iocb.un.acxri.abortIoTag = cmd->ulpIoTag;
@@ -2621,7 +2569,7 @@ lpfc_sli_abort_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
abtsiocb->iocb_cmpl = lpfc_sli_abort_fcp_cmpl;
ret_val = lpfc_sli_issue_iocb(phba, pring, abtsiocb, 0);
if (ret_val == IOCB_ERROR) {
- list_add_tail(&abtsiocb->list, lpfc_iocb_list);
+ lpfc_sli_release_iocbq(phba, abtsiocb);
errcnt++;
continue;
}
@@ -2630,83 +2578,99 @@ lpfc_sli_abort_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
return errcnt;
}
-void
-lpfc_sli_wake_iocb_high_priority(struct lpfc_hba * phba,
- struct lpfc_iocbq * queue1,
- struct lpfc_iocbq * queue2)
+static void
+lpfc_sli_wake_iocb_wait(struct lpfc_hba *phba,
+ struct lpfc_iocbq *cmdiocbq,
+ struct lpfc_iocbq *rspiocbq)
{
- if (queue1->context2 && queue2)
- memcpy(queue1->context2, queue2, sizeof (struct lpfc_iocbq));
+ wait_queue_head_t *pdone_q;
+ unsigned long iflags;
- /* The waiter is looking for LPFC_IO_HIPRI bit to be set
- as a signal to wake up */
- queue1->iocb_flag |= LPFC_IO_HIPRI;
+ spin_lock_irqsave(phba->host->host_lock, iflags);
+ cmdiocbq->iocb_flag |= LPFC_IO_WAKE;
+ if (cmdiocbq->context2 && rspiocbq)
+ memcpy(&((struct lpfc_iocbq *)cmdiocbq->context2)->iocb,
+ &rspiocbq->iocb, sizeof(IOCB_t));
+
+ pdone_q = cmdiocbq->context_un.wait_queue;
+ spin_unlock_irqrestore(phba->host->host_lock, iflags);
+ if (pdone_q)
+ wake_up(pdone_q);
return;
}
+/*
+ * Issue the caller's iocb and wait for its completion, but no longer than the
+ * caller's timeout. Note that iocb_flags is cleared before the
+ * lpfc_sli_issue_call since the wake routine sets a unique value and by
+ * definition this is a wait function.
+ */
int
-lpfc_sli_issue_iocb_wait_high_priority(struct lpfc_hba * phba,
- struct lpfc_sli_ring * pring,
- struct lpfc_iocbq * piocb,
- uint32_t flag,
- struct lpfc_iocbq * prspiocbq,
- uint32_t timeout)
+lpfc_sli_issue_iocb_wait(struct lpfc_hba * phba,
+ struct lpfc_sli_ring * pring,
+ struct lpfc_iocbq * piocb,
+ struct lpfc_iocbq * prspiocbq,
+ uint32_t timeout)
{
- int j, delay_time, retval = IOCB_ERROR;
-
- /* The caller must left context1 empty. */
- if (piocb->context_un.hipri_wait_queue != 0) {
- return IOCB_ERROR;
- }
+ DECLARE_WAIT_QUEUE_HEAD(done_q);
+ long timeleft, timeout_req = 0;
+ int retval = IOCB_SUCCESS;
/*
- * If the caller has provided a response iocbq buffer, context2 must
- * be NULL or its an error.
+ * If the caller has provided a response iocbq buffer, then context2
+ * is NULL or its an error.
*/
- if (prspiocbq && piocb->context2) {
- return IOCB_ERROR;
+ if (prspiocbq) {
+ if (piocb->context2)
+ return IOCB_ERROR;
+ piocb->context2 = prspiocbq;
}
- piocb->context2 = prspiocbq;
-
- /* Setup callback routine and issue the command. */
- piocb->iocb_cmpl = lpfc_sli_wake_iocb_high_priority;
- retval = lpfc_sli_issue_iocb(phba, pring, piocb,
- flag | SLI_IOCB_HIGH_PRIORITY);
- if (retval != IOCB_SUCCESS) {
- piocb->context2 = NULL;
- return IOCB_ERROR;
- }
+ piocb->iocb_cmpl = lpfc_sli_wake_iocb_wait;
+ piocb->context_un.wait_queue = &done_q;
+ piocb->iocb_flag &= ~LPFC_IO_WAKE;
- /*
- * This high-priority iocb was sent out-of-band. Poll for its
- * completion rather than wait for a signal. Note that the host_lock
- * is held by the midlayer and must be released here to allow the
- * interrupt handlers to complete the IO and signal this routine via
- * the iocb_flag.
- * Also, the delay_time is computed to be one second longer than
- * the scsi command timeout to give the FW time to abort on
- * timeout rather than the driver just giving up. Typically,
- * the midlayer does not specify a time for this command so the
- * driver is free to enforce its own timeout.
- */
+ retval = lpfc_sli_issue_iocb(phba, pring, piocb, 0);
+ if (retval == IOCB_SUCCESS) {
+ timeout_req = timeout * HZ;
+ spin_unlock_irq(phba->host->host_lock);
+ timeleft = wait_event_timeout(done_q,
+ piocb->iocb_flag & LPFC_IO_WAKE,
+ timeout_req);
+ spin_lock_irq(phba->host->host_lock);
- delay_time = ((timeout + 1) * 1000) >> 6;
- retval = IOCB_ERROR;
- spin_unlock_irq(phba->host->host_lock);
- for (j = 0; j < 64; j++) {
- msleep(delay_time);
- if (piocb->iocb_flag & LPFC_IO_HIPRI) {
- piocb->iocb_flag &= ~LPFC_IO_HIPRI;
- retval = IOCB_SUCCESS;
- break;
+ if (timeleft == 0) {
+ lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
+ "%d:0329 IOCB wait timeout error - no "
+ "wake response Data x%x\n",
+ phba->brd_no, timeout);
+ retval = IOCB_TIMEDOUT;
+ } else if (!(piocb->iocb_flag & LPFC_IO_WAKE)) {
+ lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
+ "%d:0330 IOCB wake NOT set, "
+ "Data x%x x%lx\n", phba->brd_no,
+ timeout, (timeleft / jiffies));
+ retval = IOCB_TIMEDOUT;
+ } else {
+ lpfc_printf_log(phba, KERN_INFO, LOG_SLI,
+ "%d:0331 IOCB wake signaled\n",
+ phba->brd_no);
}
+ } else {
+ lpfc_printf_log(phba, KERN_INFO, LOG_SLI,
+ "%d:0332 IOCB wait issue failed, Data x%x\n",
+ phba->brd_no, retval);
+ retval = IOCB_ERROR;
}
- spin_lock_irq(phba->host->host_lock);
- piocb->context2 = NULL;
+ if (prspiocbq)
+ piocb->context2 = NULL;
+
+ piocb->context_un.wait_queue = NULL;
+ piocb->iocb_cmpl = NULL;
return retval;
}
+
int
lpfc_sli_issue_mbox_wait(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmboxq,
uint32_t timeout)
diff --git a/drivers/scsi/lpfc/lpfc_sli.h b/drivers/scsi/lpfc/lpfc_sli.h
index 6c74f3c85ff7..b7a9f970f565 100644
--- a/drivers/scsi/lpfc/lpfc_sli.h
+++ b/drivers/scsi/lpfc/lpfc_sli.h
@@ -33,13 +33,15 @@ typedef enum _lpfc_ctx_cmd {
struct lpfc_iocbq {
/* lpfc_iocbqs are used in double linked lists */
struct list_head list;
+ uint16_t iotag; /* pre-assigned IO tag */
+ uint16_t rsvd1;
+
IOCB_t iocb; /* IOCB cmd */
uint8_t retry; /* retry counter for IOCB cmd - if needed */
uint8_t iocb_flag;
-#define LPFC_IO_POLL 1 /* Polling mode iocb */
-#define LPFC_IO_LIBDFC 2 /* libdfc iocb */
-#define LPFC_IO_WAIT 4
-#define LPFC_IO_HIPRI 8 /* High Priority Queue signal flag */
+#define LPFC_IO_LIBDFC 1 /* libdfc iocb */
+#define LPFC_IO_WAKE 2 /* High Priority Queue signal flag */
+#define LPFC_IO_FCP 4 /* FCP command -- iocbq in scsi_buf */
uint8_t abort_count;
uint8_t rsvd2;
@@ -48,8 +50,7 @@ struct lpfc_iocbq {
void *context2; /* caller context information */
void *context3; /* caller context information */
union {
- wait_queue_head_t *hipri_wait_queue; /* High Priority Queue wait
- queue */
+ wait_queue_head_t *wait_queue;
struct lpfc_iocbq *rsp_iocb;
struct lpfcMboxq *mbox;
} context_un;
@@ -125,10 +126,10 @@ struct lpfc_sli_ring {
uint32_t local_getidx; /* last available cmd index (from cmdGetInx) */
uint32_t next_cmdidx; /* next_cmd index */
+ uint32_t rspidx; /* current index in response ring */
+ uint32_t cmdidx; /* current index in command ring */
uint8_t rsvd;
uint8_t ringno; /* ring number */
- uint8_t rspidx; /* current index in response ring */
- uint8_t cmdidx; /* current index in command ring */
uint16_t numCiocb; /* number of command iocb's per ring */
uint16_t numRiocb; /* number of rsp iocb's per ring */
@@ -200,6 +201,11 @@ struct lpfc_sli {
cmd */
uint32_t *MBhostaddr; /* virtual address for mbox cmds */
+
+#define LPFC_IOCBQ_LOOKUP_INCREMENT 1024
+ struct lpfc_iocbq ** iocbq_lookup; /* array to lookup IOCB by IOTAG */
+ size_t iocbq_lookup_len; /* current lengs of the array */
+ uint16_t last_iotag; /* last allocated IOTAG */
};
/* Given a pointer to the start of the ring, and the slot number of
diff --git a/drivers/scsi/lpfc/lpfc_version.h b/drivers/scsi/lpfc/lpfc_version.h
index 7e6747b06f90..4f0466fbd5f2 100644
--- a/drivers/scsi/lpfc/lpfc_version.h
+++ b/drivers/scsi/lpfc/lpfc_version.h
@@ -18,7 +18,7 @@
* included with this package. *
*******************************************************************/
-#define LPFC_DRIVER_VERSION "8.0.30"
+#define LPFC_DRIVER_VERSION "8.1.0"
#define LPFC_DRIVER_NAME "lpfc"
diff --git a/drivers/scsi/megaraid/mega_common.h b/drivers/scsi/megaraid/mega_common.h
index 69df1a9b935d..8e547130e97d 100644
--- a/drivers/scsi/megaraid/mega_common.h
+++ b/drivers/scsi/megaraid/mega_common.h
@@ -25,7 +25,6 @@
#include <linux/delay.h>
#include <linux/blkdev.h>
#include <linux/list.h>
-#include <linux/version.h>
#include <linux/moduleparam.h>
#include <linux/dma-mapping.h>
#include <asm/semaphore.h>
diff --git a/drivers/scsi/megaraid/megaraid_mbox.c b/drivers/scsi/megaraid/megaraid_mbox.c
index d47be8e0ea3a..1a3d195a2d36 100644
--- a/drivers/scsi/megaraid/megaraid_mbox.c
+++ b/drivers/scsi/megaraid/megaraid_mbox.c
@@ -76,7 +76,7 @@ static void megaraid_exit(void);
static int megaraid_probe_one(struct pci_dev*, const struct pci_device_id *);
static void megaraid_detach_one(struct pci_dev *);
-static void megaraid_mbox_shutdown(struct device *);
+static void megaraid_mbox_shutdown(struct pci_dev *);
static int megaraid_io_attach(adapter_t *);
static void megaraid_io_detach(adapter_t *);
@@ -369,9 +369,7 @@ static struct pci_driver megaraid_pci_driver_g = {
.id_table = pci_id_table_g,
.probe = megaraid_probe_one,
.remove = __devexit_p(megaraid_detach_one),
- .driver = {
- .shutdown = megaraid_mbox_shutdown,
- }
+ .shutdown = megaraid_mbox_shutdown,
};
@@ -673,9 +671,9 @@ megaraid_detach_one(struct pci_dev *pdev)
* Shutdown notification, perform flush cache
*/
static void
-megaraid_mbox_shutdown(struct device *device)
+megaraid_mbox_shutdown(struct pci_dev *pdev)
{
- adapter_t *adapter = pci_get_drvdata(to_pci_dev(device));
+ adapter_t *adapter = pci_get_drvdata(pdev);
static int counter;
if (!adapter) {
@@ -3939,9 +3937,8 @@ megaraid_sysfs_free_resources(adapter_t *adapter)
{
mraid_device_t *raid_dev = ADAP2RAIDDEV(adapter);
- if (raid_dev->sysfs_uioc) kfree(raid_dev->sysfs_uioc);
-
- if (raid_dev->sysfs_mbox64) kfree(raid_dev->sysfs_mbox64);
+ kfree(raid_dev->sysfs_uioc);
+ kfree(raid_dev->sysfs_mbox64);
if (raid_dev->sysfs_buffer) {
pci_free_consistent(adapter->pdev, PAGE_SIZE,
diff --git a/drivers/scsi/megaraid/megaraid_mm.c b/drivers/scsi/megaraid/megaraid_mm.c
index 37d110e864c4..8f3ce0432295 100644
--- a/drivers/scsi/megaraid/megaraid_mm.c
+++ b/drivers/scsi/megaraid/megaraid_mm.c
@@ -995,17 +995,13 @@ pthru_dma_pool_error:
memalloc_error:
- if (adapter->kioc_list)
- kfree(adapter->kioc_list);
-
- if (adapter->mbox_list)
- kfree(adapter->mbox_list);
+ kfree(adapter->kioc_list);
+ kfree(adapter->mbox_list);
if (adapter->pthru_dma_pool)
pci_pool_destroy(adapter->pthru_dma_pool);
- if (adapter)
- kfree(adapter);
+ kfree(adapter);
return rval;
}
@@ -1157,7 +1153,6 @@ mraid_mm_free_adp_resources(mraid_mmadp_t *adp)
}
kfree(adp->kioc_list);
-
kfree(adp->mbox_list);
pci_pool_destroy(adp->pthru_dma_pool);
diff --git a/drivers/scsi/megaraid/megaraid_mm.h b/drivers/scsi/megaraid/megaraid_mm.h
index 7e36c46e7c43..eb8c390a0fa3 100644
--- a/drivers/scsi/megaraid/megaraid_mm.h
+++ b/drivers/scsi/megaraid/megaraid_mm.h
@@ -18,7 +18,6 @@
#include <linux/spinlock.h>
#include <linux/fs.h>
#include <asm/uaccess.h>
-#include <linux/version.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/pci.h>
diff --git a/drivers/scsi/megaraid/megaraid_sas.c b/drivers/scsi/megaraid/megaraid_sas.c
index c3f637395734..801a63bea8a5 100644
--- a/drivers/scsi/megaraid/megaraid_sas.c
+++ b/drivers/scsi/megaraid/megaraid_sas.c
@@ -26,7 +26,6 @@
#include <linux/types.h>
#include <linux/pci.h>
#include <linux/list.h>
-#include <linux/version.h>
#include <linux/moduleparam.h>
#include <linux/module.h>
#include <linux/spinlock.h>
@@ -758,9 +757,8 @@ static int megasas_generic_reset(struct scsi_cmnd *scmd)
instance = (struct megasas_instance *)scmd->device->host->hostdata;
- printk(KERN_NOTICE "megasas: RESET -%ld cmd=%x <c=%d t=%d l=%d>\n",
- scmd->serial_number, scmd->cmnd[0], scmd->device->channel,
- scmd->device->id, scmd->device->lun);
+ scmd_printk(KERN_NOTICE, scmd, "megasas: RESET -%ld cmd=%x\n",
+ scmd->serial_number, scmd->cmnd[0]);
if (instance->hw_crit_error) {
printk(KERN_ERR "megasas: cannot recover from previous reset "
diff --git a/drivers/scsi/mesh.c b/drivers/scsi/mesh.c
index b235556b7b65..bdccf73cf9fe 100644
--- a/drivers/scsi/mesh.c
+++ b/drivers/scsi/mesh.c
@@ -730,7 +730,7 @@ static void start_phase(struct mesh_state *ms)
* issue a SEQ_MSGOUT to get the mesh to drop ACK.
*/
if ((in_8(&mr->bus_status0) & BS0_ATN) == 0) {
- dlog(ms, "bus0 was %.2x explictly asserting ATN", mr->bus_status0);
+ dlog(ms, "bus0 was %.2x explicitly asserting ATN", mr->bus_status0);
out_8(&mr->bus_status0, BS0_ATN); /* explicit ATN */
mesh_flush_io(mr);
udelay(1);
diff --git a/drivers/scsi/mvme147.c b/drivers/scsi/mvme147.c
index 2fb31ee6d9f5..33380cee9b77 100644
--- a/drivers/scsi/mvme147.c
+++ b/drivers/scsi/mvme147.c
@@ -2,7 +2,6 @@
#include <linux/mm.h>
#include <linux/blkdev.h>
#include <linux/sched.h>
-#include <linux/version.h>
#include <linux/interrupt.h>
#include <asm/page.h>
diff --git a/drivers/scsi/mvme16x.c b/drivers/scsi/mvme16x.c
index b2d8d8ea1604..29ec699e0e4d 100644
--- a/drivers/scsi/mvme16x.c
+++ b/drivers/scsi/mvme16x.c
@@ -7,7 +7,6 @@
#include <linux/mm.h>
#include <linux/blkdev.h>
#include <linux/sched.h>
-#include <linux/version.h>
#include <asm/page.h>
#include <asm/pgtable.h>
diff --git a/drivers/scsi/ncr53c8xx.c b/drivers/scsi/ncr53c8xx.c
index 519486d24b28..243470936fab 100644
--- a/drivers/scsi/ncr53c8xx.c
+++ b/drivers/scsi/ncr53c8xx.c
@@ -3481,8 +3481,8 @@ static int ncr_queue_command (struct ncb *np, struct scsi_cmnd *cmd)
**----------------------------------------------------
*/
if (np->settle_time && cmd->timeout_per_command >= HZ) {
- u_long tlimit = ktime_get(cmd->timeout_per_command - HZ);
- if (ktime_dif(np->settle_time, tlimit) > 0)
+ u_long tlimit = jiffies + cmd->timeout_per_command - HZ;
+ if (time_after(np->settle_time, tlimit))
np->settle_time = tlimit;
}
@@ -3516,7 +3516,7 @@ static int ncr_queue_command (struct ncb *np, struct scsi_cmnd *cmd)
** Force ordered tag if necessary to avoid timeouts
** and to preserve interactivity.
*/
- if (lp && ktime_exp(lp->tags_stime)) {
+ if (lp && time_after(jiffies, lp->tags_stime)) {
if (lp->tags_smap) {
order = M_ORDERED_TAG;
if ((DEBUG_FLAGS & DEBUG_TAGS)||bootverbose>2){
@@ -3524,7 +3524,7 @@ static int ncr_queue_command (struct ncb *np, struct scsi_cmnd *cmd)
"ordered tag forced.\n");
}
}
- lp->tags_stime = ktime_get(3*HZ);
+ lp->tags_stime = jiffies + 3*HZ;
lp->tags_smap = lp->tags_umap;
}
@@ -3669,7 +3669,7 @@ static int ncr_queue_command (struct ncb *np, struct scsi_cmnd *cmd)
/*
** select
*/
- cp->phys.select.sel_id = sdev->id;
+ cp->phys.select.sel_id = sdev_id(sdev);
cp->phys.select.sel_scntl3 = tp->wval;
cp->phys.select.sel_sxfer = tp->sval;
/*
@@ -3792,7 +3792,7 @@ static int ncr_reset_scsi_bus(struct ncb *np, int enab_int, int settle_delay)
u32 term;
int retv = 0;
- np->settle_time = ktime_get(settle_delay * HZ);
+ np->settle_time = jiffies + settle_delay * HZ;
if (bootverbose > 1)
printk("%s: resetting, "
@@ -4820,7 +4820,7 @@ static void ncr_set_sync_wide_status (struct ncb *np, u_char target)
*/
for (cp = np->ccb; cp; cp = cp->link_ccb) {
if (!cp->cmd) continue;
- if (cp->cmd->device->id != target) continue;
+ if (scmd_id(cp->cmd) != target) continue;
#if 0
cp->sync_status = tp->sval;
cp->wide_status = tp->wval;
@@ -4844,7 +4844,7 @@ static void ncr_setsync (struct ncb *np, struct ccb *cp, u_char scntl3, u_char s
u_char target = INB (nc_sdid) & 0x0f;
u_char idiv;
- BUG_ON(target != (cmd->device->id & 0xf));
+ BUG_ON(target != (scmd_id(cmd) & 0xf));
tp = &np->target[target];
@@ -4902,7 +4902,7 @@ static void ncr_setwide (struct ncb *np, struct ccb *cp, u_char wide, u_char ack
u_char scntl3;
u_char sxfer;
- BUG_ON(target != (cmd->device->id & 0xf));
+ BUG_ON(target != (scmd_id(cmd) & 0xf));
tp = &np->target[target];
tp->widedone = wide+1;
@@ -5044,7 +5044,7 @@ static void ncr_setup_tags (struct ncb *np, struct scsi_device *sdev)
static void ncr_timeout (struct ncb *np)
{
- u_long thistime = ktime_get(0);
+ u_long thistime = jiffies;
/*
** If release process in progress, let's go
@@ -5057,7 +5057,7 @@ static void ncr_timeout (struct ncb *np)
return;
}
- np->timer.expires = ktime_get(SCSI_NCR_TIMER_INTERVAL);
+ np->timer.expires = jiffies + SCSI_NCR_TIMER_INTERVAL;
add_timer(&np->timer);
/*
@@ -5336,8 +5336,8 @@ void ncr_exception (struct ncb *np)
**=========================================================
*/
- if (ktime_exp(np->regtime)) {
- np->regtime = ktime_get(10*HZ);
+ if (time_after(jiffies, np->regtime)) {
+ np->regtime = jiffies + 10*HZ;
for (i = 0; i<sizeof(np->regdump); i++)
((char*)&np->regdump)[i] = INB_OFF(i);
np->regdump.nc_dstat = dstat;
@@ -5453,7 +5453,7 @@ static int ncr_int_sbmc (struct ncb *np)
** Suspend command processing for 1 second and
** reinitialize all except the chip.
*/
- np->settle_time = ktime_get(1*HZ);
+ np->settle_time = jiffies + HZ;
ncr_init (np, 0, bootverbose ? "scsi mode change" : NULL, HS_RESET);
return 1;
}
@@ -6923,7 +6923,7 @@ static struct lcb *ncr_setup_lcb (struct ncb *np, struct scsi_device *sdev)
for (i = 0 ; i < MAX_TAGS ; i++)
lp->cb_tags[i] = i;
lp->maxnxs = MAX_TAGS;
- lp->tags_stime = ktime_get(3*HZ);
+ lp->tags_stime = jiffies + 3*HZ;
ncr_setup_tags (np, sdev);
}
diff --git a/drivers/scsi/nsp32.c b/drivers/scsi/nsp32.c
index 6367f009cd74..e4ff4f00676d 100644
--- a/drivers/scsi/nsp32.c
+++ b/drivers/scsi/nsp32.c
@@ -481,7 +481,7 @@ static int nsp32_selection_autopara(struct scsi_cmnd *SCpnt)
nsp32_hw_data *data = (nsp32_hw_data *)SCpnt->device->host->hostdata;
unsigned int base = SCpnt->device->host->io_port;
unsigned int host_id = SCpnt->device->host->this_id;
- unsigned char target = SCpnt->device->id;
+ unsigned char target = scmd_id(SCpnt);
nsp32_autoparam *param = data->autoparam;
unsigned char phase;
int i, ret;
@@ -612,7 +612,7 @@ static int nsp32_selection_autoscsi(struct scsi_cmnd *SCpnt)
nsp32_hw_data *data = (nsp32_hw_data *)SCpnt->device->host->hostdata;
unsigned int base = SCpnt->device->host->io_port;
unsigned int host_id = SCpnt->device->host->this_id;
- unsigned char target = SCpnt->device->id;
+ unsigned char target = scmd_id(SCpnt);
unsigned char phase;
int status;
unsigned short command = 0;
@@ -973,7 +973,7 @@ static int nsp32_queuecommand(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_
}
/* check target ID is not same as this initiator ID */
- if (SCpnt->device->id == SCpnt->device->host->this_id) {
+ if (scmd_id(SCpnt) == SCpnt->device->host->this_id) {
nsp32_dbg(NSP32_DEBUG_QUEUECOMMAND, "terget==host???");
SCpnt->result = DID_BAD_TARGET << 16;
done(SCpnt);
@@ -1028,7 +1028,7 @@ static int nsp32_queuecommand(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_
* (target don't have SDTR_DONE and SDTR_INITIATOR), sync
* message SDTR is needed to do synchronous transfer.
*/
- target = &data->target[SCpnt->device->id];
+ target = &data->target[scmd_id(SCpnt)];
data->cur_target = target;
if (!(target->sync_flag & (SDTR_DONE | SDTR_INITIATOR | SDTR_TARGET))) {
diff --git a/drivers/scsi/nsp32.h b/drivers/scsi/nsp32.h
index 5664398fa0ad..5addf9fb1e15 100644
--- a/drivers/scsi/nsp32.h
+++ b/drivers/scsi/nsp32.h
@@ -16,6 +16,7 @@
#ifndef _NSP32_H
#define _NSP32_H
+#include <linux/version.h>
//#define NSP32_DEBUG 9
/*
diff --git a/drivers/scsi/osst.c b/drivers/scsi/osst.c
index 3f2f2464fa63..d9946bd95492 100644
--- a/drivers/scsi/osst.c
+++ b/drivers/scsi/osst.c
@@ -862,8 +862,7 @@ static int osst_recover_wait_frame(struct osst_tape * STp, struct scsi_request *
retval = osst_write_error_recovery(STp, aSRpnt, 0);
break;
}
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout (HZ / OSST_POLL_PER_SEC);
+ schedule_timeout_interruptible(HZ / OSST_POLL_PER_SEC);
STp->buffer->b_data = mybuf; STp->buffer->buffer_size = 24;
memset(cmd, 0, MAX_COMMAND_SIZE);
@@ -1558,8 +1557,7 @@ static int osst_reposition_and_retry(struct osst_tape * STp, struct scsi_request
osst_set_frame_position(STp, aSRpnt, frame + skip, 1);
flag = 0;
attempts--;
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(HZ / 10);
+ schedule_timeout_interruptible(msecs_to_jiffies(100));
}
if (osst_get_frame_position(STp, aSRpnt) < 0) { /* additional write error */
#if DEBUG
@@ -1620,8 +1618,7 @@ static int osst_reposition_and_retry(struct osst_tape * STp, struct scsi_request
debugging = 0;
}
#endif
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(HZ / 10);
+ schedule_timeout_interruptible(msecs_to_jiffies(100));
}
printk(KERN_ERR "%s:E: Failed to find valid tape media\n", name);
#if DEBUG
@@ -5146,7 +5143,8 @@ static long osst_compat_ioctl(struct file * file, unsigned int cmd_in, unsigned
/* Try to allocate a new tape buffer skeleton. Caller must not hold os_scsi_tapes_lock */
static struct osst_buffer * new_tape_buffer( int from_initialization, int need_dma, int max_sg )
{
- int i, priority;
+ int i;
+ gfp_t priority;
struct osst_buffer *tb;
if (from_initialization)
@@ -5178,7 +5176,8 @@ static struct osst_buffer * new_tape_buffer( int from_initialization, int need_d
/* Try to allocate a temporary (while a user has the device open) enlarged tape buffer */
static int enlarge_buffer(struct osst_buffer *STbuffer, int need_dma)
{
- int segs, nbr, max_segs, b_size, priority, order, got;
+ int segs, nbr, max_segs, b_size, order, got;
+ gfp_t priority;
if (STbuffer->buffer_size >= OS_FRAME_SIZE)
return 1;
@@ -5627,7 +5626,7 @@ static void osst_sysfs_add(dev_t dev, struct device *device, struct osst_tape *
if (!osst_sysfs_valid) return;
- osst_class_member = class_device_create(osst_sysfs_class, dev, device, "%s", name);
+ osst_class_member = class_device_create(osst_sysfs_class, NULL, dev, device, "%s", name);
if (IS_ERR(osst_class_member)) {
printk(KERN_WARNING "osst :W: Unable to add sysfs class member %s\n", name);
return;
@@ -5817,9 +5816,9 @@ static int osst_probe(struct device *dev)
}
drive->number = devfs_register_tape(SDp->devfs_name);
- printk(KERN_INFO
- "osst :I: Attached OnStream %.5s tape at scsi%d, channel %d, id %d, lun %d as %s\n",
- SDp->model, SDp->host->host_no, SDp->channel, SDp->id, SDp->lun, tape_name(tpnt));
+ sdev_printk(KERN_INFO, SDp,
+ "osst :I: Attached OnStream %.5s tape as %s\n",
+ SDp->model, tape_name(tpnt));
return 0;
diff --git a/drivers/scsi/pci2000.h b/drivers/scsi/pci2000.h
index c65afc964121..6c962d7dca47 100644
--- a/drivers/scsi/pci2000.h
+++ b/drivers/scsi/pci2000.h
@@ -26,9 +26,6 @@
#ifndef PSI_EIDE_SCSIOP
#define PSI_EIDE_SCSIOP 1
-#ifndef LINUX_VERSION_CODE
-#include <linux/version.h>
-#endif
#define LINUXVERSION(v,p,s) (((v)<<16) + ((p)<<8) + (s))
/************************************************/
diff --git a/drivers/scsi/pcmcia/nsp_cs.c b/drivers/scsi/pcmcia/nsp_cs.c
index 3cd3b40b1a4c..3d2f71051fe5 100644
--- a/drivers/scsi/pcmcia/nsp_cs.c
+++ b/drivers/scsi/pcmcia/nsp_cs.c
@@ -201,7 +201,7 @@ static int nsp_queuecommand(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
#ifdef NSP_DEBUG
/*unsigned int host_id = SCpnt->device->host->this_id;*/
/*unsigned int base = SCpnt->device->host->io_port;*/
- unsigned char target = SCpnt->device->id;
+ unsigned char target = scmd_id(SCpnt);
#endif
nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
@@ -373,7 +373,7 @@ static int nsphw_start_selection(Scsi_Cmnd *SCpnt)
{
unsigned int host_id = SCpnt->device->host->this_id;
unsigned int base = SCpnt->device->host->io_port;
- unsigned char target = SCpnt->device->id;
+ unsigned char target = scmd_id(SCpnt);
nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
int time_out;
unsigned char phase, arbit;
@@ -452,7 +452,7 @@ static struct nsp_sync_table nsp_sync_table_20M[] = {
*/
static int nsp_analyze_sdtr(Scsi_Cmnd *SCpnt)
{
- unsigned char target = SCpnt->device->id;
+ unsigned char target = scmd_id(SCpnt);
// unsigned char lun = SCpnt->device->lun;
nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
sync_data *sync = &(data->Sync[target]);
@@ -677,7 +677,7 @@ static int nsp_reselected(Scsi_Cmnd *SCpnt)
target++;
}
- if (SCpnt->device->id != target) {
+ if (scmd_id(SCpnt) != target) {
nsp_msg(KERN_ERR, "XXX: reselect ID must be %d in this implementation.", target);
}
@@ -912,7 +912,7 @@ static void nsp_pio_write(Scsi_Cmnd *SCpnt)
static int nsp_nexus(Scsi_Cmnd *SCpnt)
{
unsigned int base = SCpnt->device->host->io_port;
- unsigned char target = SCpnt->device->id;
+ unsigned char target = scmd_id(SCpnt);
// unsigned char lun = SCpnt->device->lun;
nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
sync_data *sync = &(data->Sync[target]);
diff --git a/drivers/scsi/pcmcia/sym53c500_cs.c b/drivers/scsi/pcmcia/sym53c500_cs.c
index b4b3a1a8a0c7..98b64b2aa8ee 100644
--- a/drivers/scsi/pcmcia/sym53c500_cs.c
+++ b/drivers/scsi/pcmcia/sym53c500_cs.c
@@ -610,7 +610,7 @@ SYM53C500_queue(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
/* We are locked here already by the mid layer */
REG0(port_base);
- outb(SCpnt->device->id, port_base + DEST_ID); /* set destination */
+ outb(scmd_id(SCpnt), port_base + DEST_ID); /* set destination */
outb(FLUSH_FIFO, port_base + CMD_REG); /* reset the fifos */
for (i = 0; i < SCpnt->cmd_len; i++) {
diff --git a/drivers/scsi/pdc_adma.c b/drivers/scsi/pdc_adma.c
new file mode 100644
index 000000000000..78b4ff117af6
--- /dev/null
+++ b/drivers/scsi/pdc_adma.c
@@ -0,0 +1,740 @@
+/*
+ * pdc_adma.c - Pacific Digital Corporation ADMA
+ *
+ * Maintained by: Mark Lord <mlord@pobox.com>
+ *
+ * Copyright 2005 Mark Lord
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *
+ * libata documentation is available via 'make {ps|pdf}docs',
+ * as Documentation/DocBook/libata.*
+ *
+ *
+ * Supports ATA disks in single-packet ADMA mode.
+ * Uses PIO for everything else.
+ *
+ * TODO: Use ADMA transfers for ATAPI devices, when possible.
+ * This requires careful attention to a number of quirks of the chip.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/blkdev.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/sched.h>
+#include <linux/device.h>
+#include <scsi/scsi_host.h>
+#include <asm/io.h>
+#include <linux/libata.h>
+
+#define DRV_NAME "pdc_adma"
+#define DRV_VERSION "0.03"
+
+/* macro to calculate base address for ATA regs */
+#define ADMA_ATA_REGS(base,port_no) ((base) + ((port_no) * 0x40))
+
+/* macro to calculate base address for ADMA regs */
+#define ADMA_REGS(base,port_no) ((base) + 0x80 + ((port_no) * 0x20))
+
+enum {
+ ADMA_PORTS = 2,
+ ADMA_CPB_BYTES = 40,
+ ADMA_PRD_BYTES = LIBATA_MAX_PRD * 16,
+ ADMA_PKT_BYTES = ADMA_CPB_BYTES + ADMA_PRD_BYTES,
+
+ ADMA_DMA_BOUNDARY = 0xffffffff,
+
+ /* global register offsets */
+ ADMA_MODE_LOCK = 0x00c7,
+
+ /* per-channel register offsets */
+ ADMA_CONTROL = 0x0000, /* ADMA control */
+ ADMA_STATUS = 0x0002, /* ADMA status */
+ ADMA_CPB_COUNT = 0x0004, /* CPB count */
+ ADMA_CPB_CURRENT = 0x000c, /* current CPB address */
+ ADMA_CPB_NEXT = 0x000c, /* next CPB address */
+ ADMA_CPB_LOOKUP = 0x0010, /* CPB lookup table */
+ ADMA_FIFO_IN = 0x0014, /* input FIFO threshold */
+ ADMA_FIFO_OUT = 0x0016, /* output FIFO threshold */
+
+ /* ADMA_CONTROL register bits */
+ aNIEN = (1 << 8), /* irq mask: 1==masked */
+ aGO = (1 << 7), /* packet trigger ("Go!") */
+ aRSTADM = (1 << 5), /* ADMA logic reset */
+ aPIOMD4 = 0x0003, /* PIO mode 4 */
+
+ /* ADMA_STATUS register bits */
+ aPSD = (1 << 6),
+ aUIRQ = (1 << 4),
+ aPERR = (1 << 0),
+
+ /* CPB bits */
+ cDONE = (1 << 0),
+ cVLD = (1 << 0),
+ cDAT = (1 << 2),
+ cIEN = (1 << 3),
+
+ /* PRD bits */
+ pORD = (1 << 4),
+ pDIRO = (1 << 5),
+ pEND = (1 << 7),
+
+ /* ATA register flags */
+ rIGN = (1 << 5),
+ rEND = (1 << 7),
+
+ /* ATA register addresses */
+ ADMA_REGS_CONTROL = 0x0e,
+ ADMA_REGS_SECTOR_COUNT = 0x12,
+ ADMA_REGS_LBA_LOW = 0x13,
+ ADMA_REGS_LBA_MID = 0x14,
+ ADMA_REGS_LBA_HIGH = 0x15,
+ ADMA_REGS_DEVICE = 0x16,
+ ADMA_REGS_COMMAND = 0x17,
+
+ /* PCI device IDs */
+ board_1841_idx = 0, /* ADMA 2-port controller */
+};
+
+typedef enum { adma_state_idle, adma_state_pkt, adma_state_mmio } adma_state_t;
+
+struct adma_port_priv {
+ u8 *pkt;
+ dma_addr_t pkt_dma;
+ adma_state_t state;
+};
+
+static int adma_ata_init_one (struct pci_dev *pdev,
+ const struct pci_device_id *ent);
+static irqreturn_t adma_intr (int irq, void *dev_instance,
+ struct pt_regs *regs);
+static int adma_port_start(struct ata_port *ap);
+static void adma_host_stop(struct ata_host_set *host_set);
+static void adma_port_stop(struct ata_port *ap);
+static void adma_phy_reset(struct ata_port *ap);
+static void adma_qc_prep(struct ata_queued_cmd *qc);
+static int adma_qc_issue(struct ata_queued_cmd *qc);
+static int adma_check_atapi_dma(struct ata_queued_cmd *qc);
+static void adma_bmdma_stop(struct ata_queued_cmd *qc);
+static u8 adma_bmdma_status(struct ata_port *ap);
+static void adma_irq_clear(struct ata_port *ap);
+static void adma_eng_timeout(struct ata_port *ap);
+
+static struct scsi_host_template adma_ata_sht = {
+ .module = THIS_MODULE,
+ .name = DRV_NAME,
+ .ioctl = ata_scsi_ioctl,
+ .queuecommand = ata_scsi_queuecmd,
+ .eh_strategy_handler = ata_scsi_error,
+ .can_queue = ATA_DEF_QUEUE,
+ .this_id = ATA_SHT_THIS_ID,
+ .sg_tablesize = LIBATA_MAX_PRD,
+ .max_sectors = ATA_MAX_SECTORS,
+ .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
+ .emulated = ATA_SHT_EMULATED,
+ .use_clustering = ENABLE_CLUSTERING,
+ .proc_name = DRV_NAME,
+ .dma_boundary = ADMA_DMA_BOUNDARY,
+ .slave_configure = ata_scsi_slave_config,
+ .bios_param = ata_std_bios_param,
+};
+
+static const struct ata_port_operations adma_ata_ops = {
+ .port_disable = ata_port_disable,
+ .tf_load = ata_tf_load,
+ .tf_read = ata_tf_read,
+ .check_status = ata_check_status,
+ .check_atapi_dma = adma_check_atapi_dma,
+ .exec_command = ata_exec_command,
+ .dev_select = ata_std_dev_select,
+ .phy_reset = adma_phy_reset,
+ .qc_prep = adma_qc_prep,
+ .qc_issue = adma_qc_issue,
+ .eng_timeout = adma_eng_timeout,
+ .irq_handler = adma_intr,
+ .irq_clear = adma_irq_clear,
+ .port_start = adma_port_start,
+ .port_stop = adma_port_stop,
+ .host_stop = adma_host_stop,
+ .bmdma_stop = adma_bmdma_stop,
+ .bmdma_status = adma_bmdma_status,
+};
+
+static struct ata_port_info adma_port_info[] = {
+ /* board_1841_idx */
+ {
+ .sht = &adma_ata_sht,
+ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST |
+ ATA_FLAG_NO_LEGACY | ATA_FLAG_MMIO,
+ .pio_mask = 0x10, /* pio4 */
+ .udma_mask = 0x1f, /* udma0-4 */
+ .port_ops = &adma_ata_ops,
+ },
+};
+
+static struct pci_device_id adma_ata_pci_tbl[] = {
+ { PCI_VENDOR_ID_PDC, 0x1841, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ board_1841_idx },
+
+ { } /* terminate list */
+};
+
+static struct pci_driver adma_ata_pci_driver = {
+ .name = DRV_NAME,
+ .id_table = adma_ata_pci_tbl,
+ .probe = adma_ata_init_one,
+ .remove = ata_pci_remove_one,
+};
+
+static int adma_check_atapi_dma(struct ata_queued_cmd *qc)
+{
+ return 1; /* ATAPI DMA not yet supported */
+}
+
+static void adma_bmdma_stop(struct ata_queued_cmd *qc)
+{
+ /* nothing */
+}
+
+static u8 adma_bmdma_status(struct ata_port *ap)
+{
+ return 0;
+}
+
+static void adma_irq_clear(struct ata_port *ap)
+{
+ /* nothing */
+}
+
+static void adma_reset_engine(void __iomem *chan)
+{
+ /* reset ADMA to idle state */
+ writew(aPIOMD4 | aNIEN | aRSTADM, chan + ADMA_CONTROL);
+ udelay(2);
+ writew(aPIOMD4, chan + ADMA_CONTROL);
+ udelay(2);
+}
+
+static void adma_reinit_engine(struct ata_port *ap)
+{
+ struct adma_port_priv *pp = ap->private_data;
+ void __iomem *mmio_base = ap->host_set->mmio_base;
+ void __iomem *chan = ADMA_REGS(mmio_base, ap->port_no);
+
+ /* mask/clear ATA interrupts */
+ writeb(ATA_NIEN, (void __iomem *)ap->ioaddr.ctl_addr);
+ ata_check_status(ap);
+
+ /* reset the ADMA engine */
+ adma_reset_engine(chan);
+
+ /* set in-FIFO threshold to 0x100 */
+ writew(0x100, chan + ADMA_FIFO_IN);
+
+ /* set CPB pointer */
+ writel((u32)pp->pkt_dma, chan + ADMA_CPB_NEXT);
+
+ /* set out-FIFO threshold to 0x100 */
+ writew(0x100, chan + ADMA_FIFO_OUT);
+
+ /* set CPB count */
+ writew(1, chan + ADMA_CPB_COUNT);
+
+ /* read/discard ADMA status */
+ readb(chan + ADMA_STATUS);
+}
+
+static inline void adma_enter_reg_mode(struct ata_port *ap)
+{
+ void __iomem *chan = ADMA_REGS(ap->host_set->mmio_base, ap->port_no);
+
+ writew(aPIOMD4, chan + ADMA_CONTROL);
+ readb(chan + ADMA_STATUS); /* flush */
+}
+
+static void adma_phy_reset(struct ata_port *ap)
+{
+ struct adma_port_priv *pp = ap->private_data;
+
+ pp->state = adma_state_idle;
+ adma_reinit_engine(ap);
+ ata_port_probe(ap);
+ ata_bus_reset(ap);
+}
+
+static void adma_eng_timeout(struct ata_port *ap)
+{
+ struct adma_port_priv *pp = ap->private_data;
+
+ if (pp->state != adma_state_idle) /* healthy paranoia */
+ pp->state = adma_state_mmio;
+ adma_reinit_engine(ap);
+ ata_eng_timeout(ap);
+}
+
+static int adma_fill_sg(struct ata_queued_cmd *qc)
+{
+ struct scatterlist *sg;
+ struct ata_port *ap = qc->ap;
+ struct adma_port_priv *pp = ap->private_data;
+ u8 *buf = pp->pkt;
+ int i = (2 + buf[3]) * 8;
+ u8 pFLAGS = pORD | ((qc->tf.flags & ATA_TFLAG_WRITE) ? pDIRO : 0);
+
+ ata_for_each_sg(sg, qc) {
+ u32 addr;
+ u32 len;
+
+ addr = (u32)sg_dma_address(sg);
+ *(__le32 *)(buf + i) = cpu_to_le32(addr);
+ i += 4;
+
+ len = sg_dma_len(sg) >> 3;
+ *(__le32 *)(buf + i) = cpu_to_le32(len);
+ i += 4;
+
+ if (ata_sg_is_last(sg, qc))
+ pFLAGS |= pEND;
+ buf[i++] = pFLAGS;
+ buf[i++] = qc->dev->dma_mode & 0xf;
+ buf[i++] = 0; /* pPKLW */
+ buf[i++] = 0; /* reserved */
+
+ *(__le32 *)(buf + i)
+ = (pFLAGS & pEND) ? 0 : cpu_to_le32(pp->pkt_dma + i + 4);
+ i += 4;
+
+ VPRINTK("PRD[%u] = (0x%lX, 0x%X)\n", nelem,
+ (unsigned long)addr, len);
+ }
+ return i;
+}
+
+static void adma_qc_prep(struct ata_queued_cmd *qc)
+{
+ struct adma_port_priv *pp = qc->ap->private_data;
+ u8 *buf = pp->pkt;
+ u32 pkt_dma = (u32)pp->pkt_dma;
+ int i = 0;
+
+ VPRINTK("ENTER\n");
+
+ adma_enter_reg_mode(qc->ap);
+ if (qc->tf.protocol != ATA_PROT_DMA) {
+ ata_qc_prep(qc);
+ return;
+ }
+
+ buf[i++] = 0; /* Response flags */
+ buf[i++] = 0; /* reserved */
+ buf[i++] = cVLD | cDAT | cIEN;
+ i++; /* cLEN, gets filled in below */
+
+ *(__le32 *)(buf+i) = cpu_to_le32(pkt_dma); /* cNCPB */
+ i += 4; /* cNCPB */
+ i += 4; /* cPRD, gets filled in below */
+
+ buf[i++] = 0; /* reserved */
+ buf[i++] = 0; /* reserved */
+ buf[i++] = 0; /* reserved */
+ buf[i++] = 0; /* reserved */
+
+ /* ATA registers; must be a multiple of 4 */
+ buf[i++] = qc->tf.device;
+ buf[i++] = ADMA_REGS_DEVICE;
+ if ((qc->tf.flags & ATA_TFLAG_LBA48)) {
+ buf[i++] = qc->tf.hob_nsect;
+ buf[i++] = ADMA_REGS_SECTOR_COUNT;
+ buf[i++] = qc->tf.hob_lbal;
+ buf[i++] = ADMA_REGS_LBA_LOW;
+ buf[i++] = qc->tf.hob_lbam;
+ buf[i++] = ADMA_REGS_LBA_MID;
+ buf[i++] = qc->tf.hob_lbah;
+ buf[i++] = ADMA_REGS_LBA_HIGH;
+ }
+ buf[i++] = qc->tf.nsect;
+ buf[i++] = ADMA_REGS_SECTOR_COUNT;
+ buf[i++] = qc->tf.lbal;
+ buf[i++] = ADMA_REGS_LBA_LOW;
+ buf[i++] = qc->tf.lbam;
+ buf[i++] = ADMA_REGS_LBA_MID;
+ buf[i++] = qc->tf.lbah;
+ buf[i++] = ADMA_REGS_LBA_HIGH;
+ buf[i++] = 0;
+ buf[i++] = ADMA_REGS_CONTROL;
+ buf[i++] = rIGN;
+ buf[i++] = 0;
+ buf[i++] = qc->tf.command;
+ buf[i++] = ADMA_REGS_COMMAND | rEND;
+
+ buf[3] = (i >> 3) - 2; /* cLEN */
+ *(__le32 *)(buf+8) = cpu_to_le32(pkt_dma + i); /* cPRD */
+
+ i = adma_fill_sg(qc);
+ wmb(); /* flush PRDs and pkt to memory */
+#if 0
+ /* dump out CPB + PRDs for debug */
+ {
+ int j, len = 0;
+ static char obuf[2048];
+ for (j = 0; j < i; ++j) {
+ len += sprintf(obuf+len, "%02x ", buf[j]);
+ if ((j & 7) == 7) {
+ printk("%s\n", obuf);
+ len = 0;
+ }
+ }
+ if (len)
+ printk("%s\n", obuf);
+ }
+#endif
+}
+
+static inline void adma_packet_start(struct ata_queued_cmd *qc)
+{
+ struct ata_port *ap = qc->ap;
+ void __iomem *chan = ADMA_REGS(ap->host_set->mmio_base, ap->port_no);
+
+ VPRINTK("ENTER, ap %p\n", ap);
+
+ /* fire up the ADMA engine */
+ writew(aPIOMD4 | aGO, chan + ADMA_CONTROL);
+}
+
+static int adma_qc_issue(struct ata_queued_cmd *qc)
+{
+ struct adma_port_priv *pp = qc->ap->private_data;
+
+ switch (qc->tf.protocol) {
+ case ATA_PROT_DMA:
+ pp->state = adma_state_pkt;
+ adma_packet_start(qc);
+ return 0;
+
+ case ATA_PROT_ATAPI_DMA:
+ BUG();
+ break;
+
+ default:
+ break;
+ }
+
+ pp->state = adma_state_mmio;
+ return ata_qc_issue_prot(qc);
+}
+
+static inline unsigned int adma_intr_pkt(struct ata_host_set *host_set)
+{
+ unsigned int handled = 0, port_no;
+ u8 __iomem *mmio_base = host_set->mmio_base;
+
+ for (port_no = 0; port_no < host_set->n_ports; ++port_no) {
+ struct ata_port *ap = host_set->ports[port_no];
+ struct adma_port_priv *pp;
+ struct ata_queued_cmd *qc;
+ void __iomem *chan = ADMA_REGS(mmio_base, port_no);
+ u8 status = readb(chan + ADMA_STATUS);
+
+ if (status == 0)
+ continue;
+ handled = 1;
+ adma_enter_reg_mode(ap);
+ if (ap->flags & (ATA_FLAG_PORT_DISABLED | ATA_FLAG_NOINTR))
+ continue;
+ pp = ap->private_data;
+ if (!pp || pp->state != adma_state_pkt)
+ continue;
+ qc = ata_qc_from_tag(ap, ap->active_tag);
+ if (qc && (!(qc->tf.ctl & ATA_NIEN))) {
+ unsigned int err_mask = 0;
+
+ if ((status & (aPERR | aPSD | aUIRQ)))
+ err_mask = AC_ERR_OTHER;
+ else if (pp->pkt[0] != cDONE)
+ err_mask = AC_ERR_OTHER;
+
+ ata_qc_complete(qc, err_mask);
+ }
+ }
+ return handled;
+}
+
+static inline unsigned int adma_intr_mmio(struct ata_host_set *host_set)
+{
+ unsigned int handled = 0, port_no;
+
+ for (port_no = 0; port_no < host_set->n_ports; ++port_no) {
+ struct ata_port *ap;
+ ap = host_set->ports[port_no];
+ if (ap && (!(ap->flags & (ATA_FLAG_PORT_DISABLED | ATA_FLAG_NOINTR)))) {
+ struct ata_queued_cmd *qc;
+ struct adma_port_priv *pp = ap->private_data;
+ if (!pp || pp->state != adma_state_mmio)
+ continue;
+ qc = ata_qc_from_tag(ap, ap->active_tag);
+ if (qc && (!(qc->tf.ctl & ATA_NIEN))) {
+
+ /* check main status, clearing INTRQ */
+ u8 status = ata_check_status(ap);
+ if ((status & ATA_BUSY))
+ continue;
+ DPRINTK("ata%u: protocol %d (dev_stat 0x%X)\n",
+ ap->id, qc->tf.protocol, status);
+
+ /* complete taskfile transaction */
+ pp->state = adma_state_idle;
+ ata_qc_complete(qc, ac_err_mask(status));
+ handled = 1;
+ }
+ }
+ }
+ return handled;
+}
+
+static irqreturn_t adma_intr(int irq, void *dev_instance, struct pt_regs *regs)
+{
+ struct ata_host_set *host_set = dev_instance;
+ unsigned int handled = 0;
+
+ VPRINTK("ENTER\n");
+
+ spin_lock(&host_set->lock);
+ handled = adma_intr_pkt(host_set) | adma_intr_mmio(host_set);
+ spin_unlock(&host_set->lock);
+
+ VPRINTK("EXIT\n");
+
+ return IRQ_RETVAL(handled);
+}
+
+static void adma_ata_setup_port(struct ata_ioports *port, unsigned long base)
+{
+ port->cmd_addr =
+ port->data_addr = base + 0x000;
+ port->error_addr =
+ port->feature_addr = base + 0x004;
+ port->nsect_addr = base + 0x008;
+ port->lbal_addr = base + 0x00c;
+ port->lbam_addr = base + 0x010;
+ port->lbah_addr = base + 0x014;
+ port->device_addr = base + 0x018;
+ port->status_addr =
+ port->command_addr = base + 0x01c;
+ port->altstatus_addr =
+ port->ctl_addr = base + 0x038;
+}
+
+static int adma_port_start(struct ata_port *ap)
+{
+ struct device *dev = ap->host_set->dev;
+ struct adma_port_priv *pp;
+ int rc;
+
+ rc = ata_port_start(ap);
+ if (rc)
+ return rc;
+ adma_enter_reg_mode(ap);
+ rc = -ENOMEM;
+ pp = kcalloc(1, sizeof(*pp), GFP_KERNEL);
+ if (!pp)
+ goto err_out;
+ pp->pkt = dma_alloc_coherent(dev, ADMA_PKT_BYTES, &pp->pkt_dma,
+ GFP_KERNEL);
+ if (!pp->pkt)
+ goto err_out_kfree;
+ /* paranoia? */
+ if ((pp->pkt_dma & 7) != 0) {
+ printk("bad alignment for pp->pkt_dma: %08x\n",
+ (u32)pp->pkt_dma);
+ dma_free_coherent(dev, ADMA_PKT_BYTES,
+ pp->pkt, pp->pkt_dma);
+ goto err_out_kfree;
+ }
+ memset(pp->pkt, 0, ADMA_PKT_BYTES);
+ ap->private_data = pp;
+ adma_reinit_engine(ap);
+ return 0;
+
+err_out_kfree:
+ kfree(pp);
+err_out:
+ ata_port_stop(ap);
+ return rc;
+}
+
+static void adma_port_stop(struct ata_port *ap)
+{
+ struct device *dev = ap->host_set->dev;
+ struct adma_port_priv *pp = ap->private_data;
+
+ adma_reset_engine(ADMA_REGS(ap->host_set->mmio_base, ap->port_no));
+ if (pp != NULL) {
+ ap->private_data = NULL;
+ if (pp->pkt != NULL)
+ dma_free_coherent(dev, ADMA_PKT_BYTES,
+ pp->pkt, pp->pkt_dma);
+ kfree(pp);
+ }
+ ata_port_stop(ap);
+}
+
+static void adma_host_stop(struct ata_host_set *host_set)
+{
+ unsigned int port_no;
+
+ for (port_no = 0; port_no < ADMA_PORTS; ++port_no)
+ adma_reset_engine(ADMA_REGS(host_set->mmio_base, port_no));
+
+ ata_pci_host_stop(host_set);
+}
+
+static void adma_host_init(unsigned int chip_id,
+ struct ata_probe_ent *probe_ent)
+{
+ unsigned int port_no;
+ void __iomem *mmio_base = probe_ent->mmio_base;
+
+ /* enable/lock aGO operation */
+ writeb(7, mmio_base + ADMA_MODE_LOCK);
+
+ /* reset the ADMA logic */
+ for (port_no = 0; port_no < ADMA_PORTS; ++port_no)
+ adma_reset_engine(ADMA_REGS(mmio_base, port_no));
+}
+
+static int adma_set_dma_masks(struct pci_dev *pdev, void __iomem *mmio_base)
+{
+ int rc;
+
+ rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+ if (rc) {
+ dev_printk(KERN_ERR, &pdev->dev,
+ "32-bit DMA enable failed\n");
+ return rc;
+ }
+ rc = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
+ if (rc) {
+ dev_printk(KERN_ERR, &pdev->dev,
+ "32-bit consistent DMA enable failed\n");
+ return rc;
+ }
+ return 0;
+}
+
+static int adma_ata_init_one(struct pci_dev *pdev,
+ const struct pci_device_id *ent)
+{
+ static int printed_version;
+ struct ata_probe_ent *probe_ent = NULL;
+ void __iomem *mmio_base;
+ unsigned int board_idx = (unsigned int) ent->driver_data;
+ int rc, port_no;
+
+ if (!printed_version++)
+ dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
+
+ rc = pci_enable_device(pdev);
+ if (rc)
+ return rc;
+
+ rc = pci_request_regions(pdev, DRV_NAME);
+ if (rc)
+ goto err_out;
+
+ if ((pci_resource_flags(pdev, 4) & IORESOURCE_MEM) == 0) {
+ rc = -ENODEV;
+ goto err_out_regions;
+ }
+
+ mmio_base = pci_iomap(pdev, 4, 0);
+ if (mmio_base == NULL) {
+ rc = -ENOMEM;
+ goto err_out_regions;
+ }
+
+ rc = adma_set_dma_masks(pdev, mmio_base);
+ if (rc)
+ goto err_out_iounmap;
+
+ probe_ent = kcalloc(1, sizeof(*probe_ent), GFP_KERNEL);
+ if (probe_ent == NULL) {
+ rc = -ENOMEM;
+ goto err_out_iounmap;
+ }
+
+ probe_ent->dev = pci_dev_to_dev(pdev);
+ INIT_LIST_HEAD(&probe_ent->node);
+
+ probe_ent->sht = adma_port_info[board_idx].sht;
+ probe_ent->host_flags = adma_port_info[board_idx].host_flags;
+ probe_ent->pio_mask = adma_port_info[board_idx].pio_mask;
+ probe_ent->mwdma_mask = adma_port_info[board_idx].mwdma_mask;
+ probe_ent->udma_mask = adma_port_info[board_idx].udma_mask;
+ probe_ent->port_ops = adma_port_info[board_idx].port_ops;
+
+ probe_ent->irq = pdev->irq;
+ probe_ent->irq_flags = SA_SHIRQ;
+ probe_ent->mmio_base = mmio_base;
+ probe_ent->n_ports = ADMA_PORTS;
+
+ for (port_no = 0; port_no < probe_ent->n_ports; ++port_no) {
+ adma_ata_setup_port(&probe_ent->port[port_no],
+ ADMA_ATA_REGS((unsigned long)mmio_base, port_no));
+ }
+
+ pci_set_master(pdev);
+
+ /* initialize adapter */
+ adma_host_init(board_idx, probe_ent);
+
+ rc = ata_device_add(probe_ent);
+ kfree(probe_ent);
+ if (rc != ADMA_PORTS)
+ goto err_out_iounmap;
+ return 0;
+
+err_out_iounmap:
+ pci_iounmap(pdev, mmio_base);
+err_out_regions:
+ pci_release_regions(pdev);
+err_out:
+ pci_disable_device(pdev);
+ return rc;
+}
+
+static int __init adma_ata_init(void)
+{
+ return pci_module_init(&adma_ata_pci_driver);
+}
+
+static void __exit adma_ata_exit(void)
+{
+ pci_unregister_driver(&adma_ata_pci_driver);
+}
+
+MODULE_AUTHOR("Mark Lord");
+MODULE_DESCRIPTION("Pacific Digital Corporation ADMA low-level driver");
+MODULE_LICENSE("GPL");
+MODULE_DEVICE_TABLE(pci, adma_ata_pci_tbl);
+MODULE_VERSION(DRV_VERSION);
+
+module_init(adma_ata_init);
+module_exit(adma_ata_exit);
diff --git a/drivers/scsi/ppa.c b/drivers/scsi/ppa.c
index fafcf5d185e7..05347eed9dd5 100644
--- a/drivers/scsi/ppa.c
+++ b/drivers/scsi/ppa.c
@@ -740,7 +740,7 @@ static int ppa_engine(ppa_struct *dev, struct scsi_cmnd *cmd)
}
case 2: /* Phase 2 - We are now talking to the scsi bus */
- if (!ppa_select(dev, cmd->device->id)) {
+ if (!ppa_select(dev, scmd_id(cmd))) {
ppa_fail(dev, DID_NO_CONNECT);
return 0;
}
diff --git a/drivers/scsi/psi240i.c b/drivers/scsi/psi240i.c
index 0f576d4ad0dd..4322c95c995c 100644
--- a/drivers/scsi/psi240i.c
+++ b/drivers/scsi/psi240i.c
@@ -659,7 +659,7 @@ static int Psi240i_BiosParam (struct scsi_device *sdev, struct block_device *dev
{
POUR_DEVICE pdev;
- pdev = &(HOSTDATA(sdev->host)->device[sdev->id]);
+ pdev = &(HOSTDATA(sdev->host)->device[sdev_id(sdev)]);
geom[0] = pdev->heads;
geom[1] = pdev->sectors;
diff --git a/drivers/scsi/qla2xxx/ql2100.c b/drivers/scsi/qla2xxx/ql2100.c
index 058733d98d6b..f5db2235e432 100644
--- a/drivers/scsi/qla2xxx/ql2100.c
+++ b/drivers/scsi/qla2xxx/ql2100.c
@@ -1,11 +1,10 @@
/*
- * QLogic ISP2100 device driver for Linux 2.6.x
- * Copyright (C) 2003 Christoph Hellwig.
- * Copyright (C) 2003-2005 QLogic Corporation (www.qlogic.com)
+ * QLogic Fibre Channel HBA Driver
+ * Copyright (C) 2003 Christoph Hellwig.
+ * Copyright (c) 2003-2005 QLogic Corporation
*
- * Released under GPL v2.
+ * See LICENSE.qla2xxx for copyright and licensing details.
*/
-
#include <linux/init.h>
#include <linux/module.h>
#include <linux/pci.h>
diff --git a/drivers/scsi/qla2xxx/ql2100_fw.c b/drivers/scsi/qla2xxx/ql2100_fw.c
index 18376b883845..56006162da40 100644
--- a/drivers/scsi/qla2xxx/ql2100_fw.c
+++ b/drivers/scsi/qla2xxx/ql2100_fw.c
@@ -1,21 +1,9 @@
-/******************************************************************************
- * QLOGIC LINUX SOFTWARE
- *
- * QLogic ISP2x00 device driver for Linux 2.6.x
- * Copyright (C) 2003-2005 QLogic Corporation
- * (www.qlogic.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, 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.
+/*
+ * QLogic Fibre Channel HBA Driver
+ * Copyright (c) 2003-2005 QLogic Corporation
*
- *************************************************************************/
+ * See LICENSE.qla2xxx for copyright and licensing details.
+ */
/*
* Firmware Version 1.19.25 (13:12 Dec 10, 2003)
diff --git a/drivers/scsi/qla2xxx/ql2200.c b/drivers/scsi/qla2xxx/ql2200.c
index 5b5ee73744b2..0eef72dc8da0 100644
--- a/drivers/scsi/qla2xxx/ql2200.c
+++ b/drivers/scsi/qla2xxx/ql2200.c
@@ -1,11 +1,10 @@
/*
- * QLogic ISP2200 device driver for Linux 2.6.x
- * Copyright (C) 2003 Christoph Hellwig.
- * Copyright (C) 2003-2005 QLogic Corporation (www.qlogic.com)
+ * QLogic Fibre Channel HBA Driver
+ * Copyright (C) 2003 Christoph Hellwig.
+ * Copyright (c) 2003-2005 QLogic Corporation
*
- * Released under GPL v2.
+ * See LICENSE.qla2xxx for copyright and licensing details.
*/
-
#include <linux/init.h>
#include <linux/module.h>
#include <linux/pci.h>
diff --git a/drivers/scsi/qla2xxx/ql2200_fw.c b/drivers/scsi/qla2xxx/ql2200_fw.c
index 6f103fd8b657..ac07e18abb1d 100644
--- a/drivers/scsi/qla2xxx/ql2200_fw.c
+++ b/drivers/scsi/qla2xxx/ql2200_fw.c
@@ -1,21 +1,9 @@
-/******************************************************************************
- * QLOGIC LINUX SOFTWARE
- *
- * QLogic ISP2x00 device driver for Linux 2.6.x
- * Copyright (C) 2003-2005 QLogic Corporation
- * (www.qlogic.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, 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.
+/*
+ * QLogic Fibre Channel HBA Driver
+ * Copyright (c) 2003-2005 QLogic Corporation
*
- *************************************************************************/
+ * See LICENSE.qla2xxx for copyright and licensing details.
+ */
/*
* Firmware Version 2.02.08 (17:06 Mar 22, 2005)
diff --git a/drivers/scsi/qla2xxx/ql2300.c b/drivers/scsi/qla2xxx/ql2300.c
index 22371c864f0c..fd2f4b795a8a 100644
--- a/drivers/scsi/qla2xxx/ql2300.c
+++ b/drivers/scsi/qla2xxx/ql2300.c
@@ -1,11 +1,10 @@
/*
- * QLogic ISP2300 device driver for Linux 2.6.x
- * Copyright (C) 2003 Christoph Hellwig.
- * Copyright (C) 2003-2005 QLogic Corporation (www.qlogic.com)
+ * QLogic Fibre Channel HBA Driver
+ * Copyright (C) 2003 Christoph Hellwig.
+ * Copyright (c) 2003-2005 QLogic Corporation
*
- * Released under GPL v2.
+ * See LICENSE.qla2xxx for copyright and licensing details.
*/
-
#include <linux/init.h>
#include <linux/module.h>
#include <linux/pci.h>
diff --git a/drivers/scsi/qla2xxx/ql2300_fw.c b/drivers/scsi/qla2xxx/ql2300_fw.c
index 4917ec509720..dfc9cd58dc06 100644
--- a/drivers/scsi/qla2xxx/ql2300_fw.c
+++ b/drivers/scsi/qla2xxx/ql2300_fw.c
@@ -1,24 +1,12 @@
-/******************************************************************************
- * QLOGIC LINUX SOFTWARE
- *
- * QLogic ISP2x00 device driver for Linux 2.6.x
- * Copyright (C) 2005 QLogic Corporation
- * (www.qlogic.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, 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.
+/*
+ * QLogic Fibre Channel HBA Driver
+ * Copyright (c) 2003-2005 QLogic Corporation
*
- ******************************************************************************/
+ * See LICENSE.qla2xxx for copyright and licensing details.
+ */
/*
- * Firmware Version 3.03.15 (10:03 May 26, 2005)
+ * Firmware Version 3.03.18 (12:09 Sep 20, 2005)
*/
#ifdef UNIQUE_FW_NAME
@@ -28,15 +16,15 @@ unsigned short risc_code_version = 3*1024+3;
#endif
#ifdef UNIQUE_FW_NAME
-unsigned char fw2300ipx_version_str[] = {3, 3,15};
+unsigned char fw2300ipx_version_str[] = {3, 3,18};
#else
-unsigned char firmware_version[] = {3, 3,15};
+unsigned char firmware_version[] = {3, 3,18};
#endif
#ifdef UNIQUE_FW_NAME
-#define fw2300ipx_VERSION_STRING "3.03.15"
+#define fw2300ipx_VERSION_STRING "3.03.18"
#else
-#define FW_VERSION_STRING "3.03.15"
+#define FW_VERSION_STRING "3.03.18"
#endif
#ifdef UNIQUE_FW_NAME
@@ -50,12 +38,12 @@ unsigned short fw2300ipx_code01[] = {
#else
unsigned short risc_code01[] = {
#endif
- 0x0470, 0x0000, 0x0000, 0xed9d, 0x0000, 0x0003, 0x0003, 0x000f,
+ 0x0470, 0x0000, 0x0000, 0xee08, 0x0000, 0x0003, 0x0003, 0x0012,
0x0137, 0x2043, 0x4f50, 0x5952, 0x4947, 0x4854, 0x2032, 0x3030,
0x3120, 0x514c, 0x4f47, 0x4943, 0x2043, 0x4f52, 0x504f, 0x5241,
0x5449, 0x4f4e, 0x2049, 0x5350, 0x3233, 0x3030, 0x2046, 0x6972,
0x6d77, 0x6172, 0x6520, 0x2056, 0x6572, 0x7369, 0x6f6e, 0x2030,
- 0x332e, 0x3033, 0x2e31, 0x3520, 0x2020, 0x2020, 0x2400, 0x20a9,
+ 0x332e, 0x3033, 0x2e31, 0x3820, 0x2020, 0x2020, 0x2400, 0x20a9,
0x000f, 0x2001, 0x0000, 0x400f, 0x2091, 0x2200, 0x20a9, 0x000f,
0x2001, 0x0000, 0x400f, 0x2091, 0x2400, 0x20a9, 0x000f, 0x2001,
0x0000, 0x400f, 0x2091, 0x2600, 0x20a9, 0x000f, 0x2001, 0x0000,
@@ -64,7 +52,7 @@ unsigned short risc_code01[] = {
0x2c00, 0x20a9, 0x000f, 0x2001, 0x0000, 0x400f, 0x2091, 0x2e00,
0x20a9, 0x000f, 0x2001, 0x0000, 0x400f, 0x2091, 0x2000, 0x2001,
0x0000, 0x20c1, 0x0004, 0x20c9, 0x1bff, 0x2059, 0x0000, 0x2b78,
- 0x7883, 0x0004, 0x2089, 0x2db5, 0x2051, 0x1800, 0x2a70, 0x20e1,
+ 0x7883, 0x0004, 0x2089, 0x2dac, 0x2051, 0x1800, 0x2a70, 0x20e1,
0x0001, 0x20e9, 0x0001, 0x2009, 0x0000, 0x080c, 0x0e52, 0x2029,
0x4d00, 0x2031, 0xffff, 0x2039, 0x4cd0, 0x2021, 0x0200, 0x20e9,
0x0001, 0x20a1, 0x0000, 0x20a9, 0x0800, 0x900e, 0x4104, 0x20e9,
@@ -78,159 +66,159 @@ unsigned short risc_code01[] = {
0x1800, 0x810d, 0x810d, 0x810d, 0x810d, 0x810d, 0x918c, 0x001f,
0x2001, 0x0001, 0x9112, 0x20e9, 0x0001, 0x20a1, 0x0800, 0x900e,
0x20a9, 0x0800, 0x4104, 0x8211, 0x1dd8, 0x080c, 0x0f26, 0x080c,
- 0x612f, 0x080c, 0xb07d, 0x080c, 0x10dd, 0x080c, 0x12fc, 0x080c,
- 0x1bf8, 0x080c, 0x0d57, 0x080c, 0x1062, 0x080c, 0x34b1, 0x080c,
- 0x785c, 0x080c, 0x6ab0, 0x080c, 0x892f, 0x080c, 0x8610, 0x080c,
- 0x24d0, 0x080c, 0x91db, 0x080c, 0x7f2c, 0x080c, 0x2309, 0x080c,
- 0x243d, 0x080c, 0x24c5, 0x2091, 0x3009, 0x7883, 0x0000, 0x1004,
+ 0x6135, 0x080c, 0xb097, 0x080c, 0x10dd, 0x080c, 0x12fc, 0x080c,
+ 0x1c00, 0x080c, 0x0d57, 0x080c, 0x1062, 0x080c, 0x34ac, 0x080c,
+ 0x7862, 0x080c, 0x6ab6, 0x080c, 0x8935, 0x080c, 0x8616, 0x080c,
+ 0x24d8, 0x080c, 0x91e1, 0x080c, 0x7f32, 0x080c, 0x2311, 0x080c,
+ 0x2445, 0x080c, 0x24cd, 0x2091, 0x3009, 0x7883, 0x0000, 0x1004,
0x091f, 0x7880, 0x9086, 0x0002, 0x1190, 0x7883, 0x4000, 0x7837,
0x4000, 0x7833, 0x0010, 0x0e04, 0x0913, 0x2091, 0x5000, 0x2091,
0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x11aa, 0x2071,
0x1800, 0x7003, 0x0000, 0x2071, 0x1800, 0x7000, 0x908e, 0x0003,
- 0x1178, 0x080c, 0x4ca8, 0x080c, 0x34d8, 0x080c, 0x78cd, 0x080c,
- 0x704e, 0x080c, 0x8a16, 0x080c, 0x863c, 0x080c, 0x2cff, 0x0c58,
+ 0x1178, 0x080c, 0x4cae, 0x080c, 0x34d3, 0x080c, 0x78d3, 0x080c,
+ 0x7054, 0x080c, 0x8a1c, 0x080c, 0x8642, 0x080c, 0x2cf6, 0x0c58,
0x000b, 0x0c78, 0x0944, 0x0945, 0x0ae0, 0x0942, 0x0ba0, 0x0d56,
0x0d56, 0x0d56, 0x080c, 0x0dc5, 0x0005, 0x0126, 0x00f6, 0x2091,
0x8000, 0x7000, 0x9086, 0x0001, 0x1904, 0x0ab3, 0x080c, 0x0e94,
- 0x080c, 0x7563, 0x0150, 0x080c, 0x7586, 0x15a0, 0x2079, 0x0100,
- 0x7828, 0x9085, 0x1800, 0x782a, 0x0468, 0x080c, 0x748f, 0x7000,
+ 0x080c, 0x7569, 0x0150, 0x080c, 0x758c, 0x15a0, 0x2079, 0x0100,
+ 0x7828, 0x9085, 0x1800, 0x782a, 0x0468, 0x080c, 0x7495, 0x7000,
0x9086, 0x0001, 0x1904, 0x0ab3, 0x7098, 0x9086, 0x0029, 0x1904,
- 0x0ab3, 0x080c, 0x85f9, 0x080c, 0x85eb, 0x2001, 0x0161, 0x2003,
+ 0x0ab3, 0x080c, 0x85ff, 0x080c, 0x85f1, 0x2001, 0x0161, 0x2003,
0x0001, 0x2079, 0x0100, 0x7827, 0xffff, 0x7a28, 0x9295, 0x5e2f,
- 0x7a2a, 0x2011, 0x73de, 0x080c, 0x8703, 0x2011, 0x73d1, 0x080c,
- 0x87dd, 0x2011, 0x5f8a, 0x080c, 0x8703, 0x2011, 0x8030, 0x901e,
- 0x7396, 0x04d0, 0x080c, 0x5837, 0x2079, 0x0100, 0x7844, 0x9005,
- 0x1904, 0x0ab3, 0x2011, 0x5f8a, 0x080c, 0x8703, 0x2011, 0x73de,
- 0x080c, 0x8703, 0x2011, 0x73d1, 0x080c, 0x87dd, 0x2001, 0x0265,
+ 0x7a2a, 0x2011, 0x73e4, 0x080c, 0x8709, 0x2011, 0x73d7, 0x080c,
+ 0x87e3, 0x2011, 0x5f90, 0x080c, 0x8709, 0x2011, 0x8030, 0x901e,
+ 0x7396, 0x04d0, 0x080c, 0x583d, 0x2079, 0x0100, 0x7844, 0x9005,
+ 0x1904, 0x0ab3, 0x2011, 0x5f90, 0x080c, 0x8709, 0x2011, 0x73e4,
+ 0x080c, 0x8709, 0x2011, 0x73d7, 0x080c, 0x87e3, 0x2001, 0x0265,
0x2001, 0x0205, 0x2003, 0x0000, 0x7840, 0x9084, 0xfffb, 0x7842,
- 0x2001, 0x19a7, 0x2004, 0x9005, 0x1140, 0x00c6, 0x2061, 0x0100,
- 0x080c, 0x60d7, 0x00ce, 0x0804, 0x0ab3, 0x780f, 0x006b, 0x7a28,
- 0x080c, 0x756b, 0x0118, 0x9295, 0x5e2f, 0x0010, 0x9295, 0x402f,
- 0x7a2a, 0x2011, 0x8010, 0x73d8, 0x2001, 0x19a8, 0x2003, 0x0001,
- 0x080c, 0x2ba4, 0x080c, 0x4be3, 0x7248, 0xc284, 0x724a, 0x2001,
- 0x180c, 0x200c, 0xc1ac, 0xc1cc, 0x2102, 0x080c, 0xa7c4, 0x2011,
- 0x0004, 0x080c, 0xce4f, 0x080c, 0x693a, 0x080c, 0x7563, 0x1120,
- 0x080c, 0x2be8, 0x02e0, 0x0400, 0x080c, 0x60de, 0x0140, 0x7097,
- 0x0001, 0x70d3, 0x0000, 0x080c, 0x5a04, 0x0804, 0x0ab3, 0x080c,
- 0x57cd, 0xd094, 0x0188, 0x2011, 0x180c, 0x2204, 0xc0cd, 0x2012,
- 0x080c, 0x57d1, 0xd0d4, 0x1118, 0x080c, 0x2be8, 0x1270, 0x2011,
- 0x180c, 0x2204, 0xc0bc, 0x00a8, 0x080c, 0x57d1, 0xd0d4, 0x1db8,
+ 0x2001, 0x19a8, 0x2004, 0x9005, 0x1140, 0x00c6, 0x2061, 0x0100,
+ 0x080c, 0x60dd, 0x00ce, 0x0804, 0x0ab3, 0x780f, 0x006b, 0x7a28,
+ 0x080c, 0x7571, 0x0118, 0x9295, 0x5e2f, 0x0010, 0x9295, 0x402f,
+ 0x7a2a, 0x2011, 0x8010, 0x73d8, 0x2001, 0x19a9, 0x2003, 0x0001,
+ 0x080c, 0x2b9b, 0x080c, 0x4be9, 0x7248, 0xc284, 0x724a, 0x2001,
+ 0x180c, 0x200c, 0xc1ac, 0xc1cc, 0x2102, 0x080c, 0xa7de, 0x2011,
+ 0x0004, 0x080c, 0xce66, 0x080c, 0x6940, 0x080c, 0x7569, 0x1120,
+ 0x080c, 0x2bdf, 0x02e0, 0x0400, 0x080c, 0x60e4, 0x0140, 0x7097,
+ 0x0001, 0x70d3, 0x0000, 0x080c, 0x5a0a, 0x0804, 0x0ab3, 0x080c,
+ 0x57d3, 0xd094, 0x0188, 0x2011, 0x180c, 0x2204, 0xc0cd, 0x2012,
+ 0x080c, 0x57d7, 0xd0d4, 0x1118, 0x080c, 0x2bdf, 0x1270, 0x2011,
+ 0x180c, 0x2204, 0xc0bc, 0x00a8, 0x080c, 0x57d7, 0xd0d4, 0x1db8,
0x2011, 0x180c, 0x2204, 0xc0bd, 0x0060, 0x2011, 0x180c, 0x2204,
- 0xc0bd, 0x2012, 0x080c, 0x6a84, 0x1128, 0xd0a4, 0x0118, 0x2204,
- 0xc0fd, 0x2012, 0x080c, 0x6a4a, 0x0120, 0x7a0c, 0xc2b4, 0x7a0e,
- 0x00a8, 0x707f, 0x0000, 0x080c, 0x7563, 0x1130, 0x70b0, 0x9005,
- 0x1168, 0x080c, 0xd292, 0x0050, 0x080c, 0xd292, 0x70dc, 0xd09c,
- 0x1128, 0x70b0, 0x9005, 0x0110, 0x080c, 0x60b4, 0x70e7, 0x0000,
- 0x70e3, 0x0000, 0x70a7, 0x0000, 0x080c, 0x2bf0, 0x0228, 0x2011,
- 0x0101, 0x2204, 0xc0c4, 0x2012, 0x72dc, 0x080c, 0x7563, 0x1178,
- 0x9016, 0x0016, 0x080c, 0x29a1, 0x2019, 0x196e, 0x211a, 0x001e,
+ 0xc0bd, 0x2012, 0x080c, 0x6a8a, 0x1128, 0xd0a4, 0x0118, 0x2204,
+ 0xc0fd, 0x2012, 0x080c, 0x6a50, 0x0120, 0x7a0c, 0xc2b4, 0x7a0e,
+ 0x00a8, 0x707f, 0x0000, 0x080c, 0x7569, 0x1130, 0x70b0, 0x9005,
+ 0x1168, 0x080c, 0xd2a9, 0x0050, 0x080c, 0xd2a9, 0x70dc, 0xd09c,
+ 0x1128, 0x70b0, 0x9005, 0x0110, 0x080c, 0x60ba, 0x70e7, 0x0000,
+ 0x70e3, 0x0000, 0x70a7, 0x0000, 0x080c, 0x2be7, 0x0228, 0x2011,
+ 0x0101, 0x2204, 0xc0c4, 0x2012, 0x72dc, 0x080c, 0x7569, 0x1178,
+ 0x9016, 0x0016, 0x080c, 0x29ac, 0x2019, 0x196e, 0x211a, 0x001e,
0x705f, 0xffff, 0x7063, 0x00ef, 0x7083, 0x0000, 0x0020, 0x2019,
0x196e, 0x201b, 0x0000, 0x2079, 0x1847, 0x7804, 0xd0ac, 0x0108,
- 0xc295, 0x72de, 0x080c, 0x7563, 0x0118, 0x9296, 0x0004, 0x0548,
- 0x2011, 0x0001, 0x080c, 0xce4f, 0x70ab, 0x0000, 0x70af, 0xffff,
+ 0xc295, 0x72de, 0x080c, 0x7569, 0x0118, 0x9296, 0x0004, 0x0548,
+ 0x2011, 0x0001, 0x080c, 0xce66, 0x70ab, 0x0000, 0x70af, 0xffff,
0x7003, 0x0002, 0x2079, 0x0100, 0x7827, 0x0003, 0x7828, 0x9085,
- 0x0003, 0x782a, 0x00fe, 0x080c, 0x3022, 0x2011, 0x0005, 0x080c,
- 0xa8d3, 0x080c, 0x98e7, 0x080c, 0x7563, 0x0148, 0x00c6, 0x2061,
- 0x0100, 0x0016, 0x080c, 0x29a1, 0x61e2, 0x001e, 0x00ce, 0x012e,
+ 0x0003, 0x782a, 0x00fe, 0x080c, 0x3019, 0x2011, 0x0005, 0x080c,
+ 0xa8ed, 0x080c, 0x98ed, 0x080c, 0x7569, 0x0148, 0x00c6, 0x2061,
+ 0x0100, 0x0016, 0x080c, 0x29ac, 0x61e2, 0x001e, 0x00ce, 0x012e,
0x0420, 0x70ab, 0x0000, 0x70af, 0xffff, 0x7003, 0x0002, 0x00f6,
0x2079, 0x0100, 0x7827, 0x0003, 0x7828, 0x9085, 0x0003, 0x782a,
- 0x00fe, 0x2011, 0x0005, 0x080c, 0xa8d3, 0x080c, 0x98e7, 0x080c,
- 0x7563, 0x0148, 0x00c6, 0x2061, 0x0100, 0x0016, 0x080c, 0x29a1,
+ 0x00fe, 0x2011, 0x0005, 0x080c, 0xa8ed, 0x080c, 0x98ed, 0x080c,
+ 0x7569, 0x0148, 0x00c6, 0x2061, 0x0100, 0x0016, 0x080c, 0x29ac,
0x61e2, 0x001e, 0x00ce, 0x00fe, 0x012e, 0x0005, 0x00c6, 0x00b6,
- 0x080c, 0x7563, 0x1118, 0x20a9, 0x0800, 0x0010, 0x20a9, 0x0782,
- 0x080c, 0x7563, 0x1110, 0x900e, 0x0010, 0x2009, 0x007e, 0x86ff,
+ 0x080c, 0x7569, 0x1118, 0x20a9, 0x0800, 0x0010, 0x20a9, 0x0782,
+ 0x080c, 0x7569, 0x1110, 0x900e, 0x0010, 0x2009, 0x007e, 0x86ff,
0x0138, 0x9180, 0x1000, 0x2004, 0x905d, 0x0110, 0xb800, 0xd0bc,
- 0x090c, 0x3347, 0x8108, 0x1f04, 0x0ac7, 0x707f, 0x0000, 0x7080,
+ 0x090c, 0x3342, 0x8108, 0x1f04, 0x0ac7, 0x707f, 0x0000, 0x7080,
0x9084, 0x00ff, 0x7082, 0x70b3, 0x0000, 0x00be, 0x00ce, 0x0005,
0x00b6, 0x0126, 0x2091, 0x8000, 0x7000, 0x9086, 0x0002, 0x1904,
- 0x0b9d, 0x70ac, 0x9086, 0xffff, 0x0130, 0x080c, 0x3022, 0x080c,
- 0x98e7, 0x0804, 0x0b9d, 0x70dc, 0xd0ac, 0x1110, 0xd09c, 0x0558,
+ 0x0b9d, 0x70ac, 0x9086, 0xffff, 0x0130, 0x080c, 0x3019, 0x080c,
+ 0x98ed, 0x0804, 0x0b9d, 0x70dc, 0xd0ac, 0x1110, 0xd09c, 0x0558,
0xd084, 0x0548, 0x0006, 0x2001, 0x0103, 0x2003, 0x002b, 0x000e,
- 0xd08c, 0x0508, 0x080c, 0x33aa, 0x11d0, 0x70e0, 0x9086, 0xffff,
- 0x01b0, 0x080c, 0x31b7, 0x080c, 0x98e7, 0x70dc, 0xd094, 0x1904,
- 0x0b9d, 0x2011, 0x0001, 0x080c, 0xd548, 0x0110, 0x2011, 0x0003,
- 0x901e, 0x080c, 0x31f1, 0x080c, 0x98e7, 0x0804, 0x0b9d, 0x70e4,
+ 0xd08c, 0x0508, 0x080c, 0x33a5, 0x11d0, 0x70e0, 0x9086, 0xffff,
+ 0x01b0, 0x080c, 0x31b2, 0x080c, 0x98ed, 0x70dc, 0xd094, 0x1904,
+ 0x0b9d, 0x2011, 0x0001, 0x080c, 0xd561, 0x0110, 0x2011, 0x0003,
+ 0x901e, 0x080c, 0x31ec, 0x080c, 0x98ed, 0x0804, 0x0b9d, 0x70e4,
0x9005, 0x1904, 0x0b9d, 0x70a8, 0x9005, 0x1904, 0x0b9d, 0x70dc,
- 0xd0a4, 0x0118, 0xd0b4, 0x0904, 0x0b9d, 0x080c, 0x6a4a, 0x1904,
- 0x0b9d, 0x080c, 0x6a9d, 0x1904, 0x0b9d, 0x080c, 0x6a84, 0x01c0,
- 0x0156, 0x00c6, 0x20a9, 0x007f, 0x900e, 0x0016, 0x080c, 0x6717,
+ 0xd0a4, 0x0118, 0xd0b4, 0x0904, 0x0b9d, 0x080c, 0x6a50, 0x1904,
+ 0x0b9d, 0x080c, 0x6aa3, 0x1904, 0x0b9d, 0x080c, 0x6a8a, 0x01c0,
+ 0x0156, 0x00c6, 0x20a9, 0x007f, 0x900e, 0x0016, 0x080c, 0x671d,
0x1118, 0xb800, 0xd0ec, 0x1138, 0x001e, 0x8108, 0x1f04, 0x0b3d,
0x00ce, 0x015e, 0x0028, 0x001e, 0x00ce, 0x015e, 0x0804, 0x0b9d,
0x0006, 0x2001, 0x0103, 0x2003, 0x002b, 0x000e, 0x2011, 0x19b5,
0x080c, 0x0f96, 0x2011, 0x19cf, 0x080c, 0x0f96, 0x7030, 0xc08c,
0x7032, 0x7003, 0x0003, 0x70af, 0xffff, 0x080c, 0x0e76, 0x9006,
- 0x080c, 0x2832, 0x080c, 0x33aa, 0x0118, 0x080c, 0x4d80, 0x0050,
- 0x0036, 0x0046, 0x2019, 0xffff, 0x2021, 0x0006, 0x080c, 0x4d9a,
- 0x004e, 0x003e, 0x00f6, 0x2079, 0x0100, 0x080c, 0x7586, 0x0150,
- 0x080c, 0x7563, 0x7828, 0x0118, 0x9084, 0xe1ff, 0x0010, 0x9084,
+ 0x080c, 0x283d, 0x080c, 0x33a5, 0x0118, 0x080c, 0x4d86, 0x0050,
+ 0x0036, 0x0046, 0x2019, 0xffff, 0x2021, 0x0006, 0x080c, 0x4da0,
+ 0x004e, 0x003e, 0x00f6, 0x2079, 0x0100, 0x080c, 0x758c, 0x0150,
+ 0x080c, 0x7569, 0x7828, 0x0118, 0x9084, 0xe1ff, 0x0010, 0x9084,
0xffdf, 0x782a, 0x00fe, 0x2001, 0x19ea, 0x2004, 0x9086, 0x0005,
- 0x1120, 0x2011, 0x0000, 0x080c, 0xa8d3, 0x2011, 0x0000, 0x080c,
- 0xa8dd, 0x080c, 0x98e7, 0x080c, 0x9a09, 0x012e, 0x00be, 0x0005,
+ 0x1120, 0x2011, 0x0000, 0x080c, 0xa8ed, 0x2011, 0x0000, 0x080c,
+ 0xa8f7, 0x080c, 0x98ed, 0x080c, 0x9a0f, 0x012e, 0x00be, 0x0005,
0x0016, 0x0046, 0x00f6, 0x0126, 0x2091, 0x8000, 0x2079, 0x0100,
- 0x7904, 0x918c, 0xfffd, 0x7906, 0x2009, 0x00f7, 0x080c, 0x609d,
+ 0x7904, 0x918c, 0xfffd, 0x7906, 0x2009, 0x00f7, 0x080c, 0x60a3,
0x7940, 0x918c, 0x0010, 0x7942, 0x7924, 0xd1b4, 0x0110, 0x7827,
0x0040, 0xd19c, 0x0110, 0x7827, 0x0008, 0x0006, 0x0036, 0x0156,
- 0x7954, 0xd1ac, 0x1904, 0x0c2d, 0x2001, 0x19a8, 0x2004, 0x9005,
- 0x1518, 0x080c, 0x2c6b, 0x1148, 0x2001, 0x0001, 0x080c, 0x2bd3,
- 0x2001, 0x0001, 0x080c, 0x2bb6, 0x00b8, 0x080c, 0x2c73, 0x1138,
- 0x9006, 0x080c, 0x2bd3, 0x9006, 0x080c, 0x2bb6, 0x0068, 0x080c,
- 0x2c7b, 0x1d50, 0x2001, 0x1999, 0x2004, 0xd0fc, 0x0108, 0x0020,
- 0x080c, 0x29cd, 0x0804, 0x0d0d, 0x080c, 0x7574, 0x0148, 0x080c,
- 0x7586, 0x1118, 0x080c, 0x7857, 0x0050, 0x080c, 0x756b, 0x0dd0,
- 0x080c, 0x7852, 0x080c, 0x7848, 0x080c, 0x748f, 0x0058, 0x080c,
- 0x7563, 0x0140, 0x2009, 0x00f8, 0x080c, 0x609d, 0x7843, 0x0090,
+ 0x7954, 0xd1ac, 0x1904, 0x0c2d, 0x2001, 0x19a9, 0x2004, 0x9005,
+ 0x1518, 0x080c, 0x2c62, 0x1148, 0x2001, 0x0001, 0x080c, 0x2bca,
+ 0x2001, 0x0001, 0x080c, 0x2bad, 0x00b8, 0x080c, 0x2c6a, 0x1138,
+ 0x9006, 0x080c, 0x2bca, 0x9006, 0x080c, 0x2bad, 0x0068, 0x080c,
+ 0x2c72, 0x1d50, 0x2001, 0x1999, 0x2004, 0xd0fc, 0x0108, 0x0020,
+ 0x080c, 0x29d8, 0x0804, 0x0d0d, 0x080c, 0x757a, 0x0148, 0x080c,
+ 0x758c, 0x1118, 0x080c, 0x785d, 0x0050, 0x080c, 0x7571, 0x0dd0,
+ 0x080c, 0x7858, 0x080c, 0x784e, 0x080c, 0x7495, 0x0058, 0x080c,
+ 0x7569, 0x0140, 0x2009, 0x00f8, 0x080c, 0x60a3, 0x7843, 0x0090,
0x7843, 0x0010, 0x20a9, 0x09c4, 0x7820, 0xd09c, 0x1138, 0x080c,
- 0x7563, 0x0138, 0x7824, 0xd0ac, 0x1904, 0x0d12, 0x1f04, 0x0c0c,
- 0x0070, 0x7824, 0x080c, 0x757d, 0x0118, 0xd0ac, 0x1904, 0x0d12,
+ 0x7569, 0x0138, 0x7824, 0xd0ac, 0x1904, 0x0d12, 0x1f04, 0x0c0c,
+ 0x0070, 0x7824, 0x080c, 0x7583, 0x0118, 0xd0ac, 0x1904, 0x0d12,
0x9084, 0x1800, 0x0d98, 0x7003, 0x0001, 0x0804, 0x0d12, 0x2001,
- 0x0001, 0x080c, 0x2832, 0x0804, 0x0d25, 0x2001, 0x19a8, 0x2004,
- 0x9005, 0x1518, 0x080c, 0x2c6b, 0x1148, 0x2001, 0x0001, 0x080c,
- 0x2bd3, 0x2001, 0x0001, 0x080c, 0x2bb6, 0x00b8, 0x080c, 0x2c73,
- 0x1138, 0x9006, 0x080c, 0x2bd3, 0x9006, 0x080c, 0x2bb6, 0x0068,
- 0x080c, 0x2c7b, 0x1d50, 0x2001, 0x1999, 0x2004, 0xd0fc, 0x0108,
- 0x0020, 0x080c, 0x29cd, 0x0804, 0x0d0d, 0x7850, 0x9085, 0x0040,
- 0x7852, 0x7938, 0x7850, 0x9084, 0xfbcf, 0x7852, 0x080c, 0x2c83,
+ 0x0001, 0x080c, 0x283d, 0x0804, 0x0d25, 0x2001, 0x19a9, 0x2004,
+ 0x9005, 0x1518, 0x080c, 0x2c62, 0x1148, 0x2001, 0x0001, 0x080c,
+ 0x2bca, 0x2001, 0x0001, 0x080c, 0x2bad, 0x00b8, 0x080c, 0x2c6a,
+ 0x1138, 0x9006, 0x080c, 0x2bca, 0x9006, 0x080c, 0x2bad, 0x0068,
+ 0x080c, 0x2c72, 0x1d50, 0x2001, 0x1999, 0x2004, 0xd0fc, 0x0108,
+ 0x0020, 0x080c, 0x29d8, 0x0804, 0x0d0d, 0x7850, 0x9085, 0x0040,
+ 0x7852, 0x7938, 0x7850, 0x9084, 0xfbcf, 0x7852, 0x080c, 0x2c7a,
0x9085, 0x2000, 0x7852, 0x793a, 0x20a9, 0x0046, 0x1d04, 0x0c66,
- 0x080c, 0x87bd, 0x1f04, 0x0c66, 0x7850, 0x9085, 0x0400, 0x9084,
- 0xdfbf, 0x7852, 0x793a, 0x080c, 0x7574, 0x0148, 0x080c, 0x7586,
- 0x1118, 0x080c, 0x7857, 0x0050, 0x080c, 0x756b, 0x0dd0, 0x080c,
- 0x7852, 0x080c, 0x7848, 0x080c, 0x748f, 0x0020, 0x2009, 0x00f8,
- 0x080c, 0x609d, 0x20a9, 0x0028, 0xa001, 0x1f04, 0x0c8c, 0x7850,
- 0x9085, 0x1400, 0x7852, 0x080c, 0x7563, 0x0120, 0x7843, 0x0090,
- 0x7843, 0x0010, 0x2021, 0xe678, 0x2019, 0xea60, 0x0d0c, 0x87bd,
- 0x7820, 0xd09c, 0x1588, 0x080c, 0x7563, 0x0904, 0x0cf2, 0x7824,
- 0xd0ac, 0x1904, 0x0d12, 0x080c, 0x7586, 0x1530, 0x0046, 0x2021,
- 0x0320, 0x8421, 0x1df0, 0x004e, 0x7827, 0x1800, 0x080c, 0x2c83,
+ 0x080c, 0x87c3, 0x1f04, 0x0c66, 0x7850, 0x9085, 0x0400, 0x9084,
+ 0xdfbf, 0x7852, 0x793a, 0x080c, 0x757a, 0x0148, 0x080c, 0x758c,
+ 0x1118, 0x080c, 0x785d, 0x0050, 0x080c, 0x7571, 0x0dd0, 0x080c,
+ 0x7858, 0x080c, 0x784e, 0x080c, 0x7495, 0x0020, 0x2009, 0x00f8,
+ 0x080c, 0x60a3, 0x20a9, 0x0028, 0xa001, 0x1f04, 0x0c8c, 0x7850,
+ 0x9085, 0x1400, 0x7852, 0x080c, 0x7569, 0x0120, 0x7843, 0x0090,
+ 0x7843, 0x0010, 0x2021, 0xe678, 0x2019, 0xea60, 0x0d0c, 0x87c3,
+ 0x7820, 0xd09c, 0x1588, 0x080c, 0x7569, 0x0904, 0x0cf2, 0x7824,
+ 0xd0ac, 0x1904, 0x0d12, 0x080c, 0x758c, 0x1530, 0x0046, 0x2021,
+ 0x0320, 0x8421, 0x1df0, 0x004e, 0x7827, 0x1800, 0x080c, 0x2c7a,
0x7824, 0x9084, 0x1800, 0x1168, 0x9484, 0x0fff, 0x1140, 0x2001,
0x1810, 0x2004, 0x9084, 0x9000, 0x0110, 0x080c, 0x0d33, 0x8421,
- 0x1158, 0x1d04, 0x0ccd, 0x080c, 0x87bd, 0x080c, 0x7852, 0x080c,
- 0x7848, 0x7003, 0x0001, 0x04f0, 0x8319, 0x1940, 0x1d04, 0x0cda,
- 0x080c, 0x87bd, 0x2009, 0x199c, 0x2104, 0x9005, 0x0118, 0x8001,
+ 0x1158, 0x1d04, 0x0ccd, 0x080c, 0x87c3, 0x080c, 0x7858, 0x080c,
+ 0x784e, 0x7003, 0x0001, 0x04f0, 0x8319, 0x1940, 0x1d04, 0x0cda,
+ 0x080c, 0x87c3, 0x2009, 0x199c, 0x2104, 0x9005, 0x0118, 0x8001,
0x200a, 0x1178, 0x200b, 0x000a, 0x7827, 0x0048, 0x20a9, 0x0002,
- 0x080c, 0x2c64, 0x7924, 0x080c, 0x2c83, 0xd19c, 0x0110, 0x080c,
- 0x2ba4, 0x00d8, 0x080c, 0x7574, 0x1140, 0x94a2, 0x03e8, 0x1128,
- 0x080c, 0x753b, 0x7003, 0x0001, 0x00a8, 0x7827, 0x1800, 0x080c,
- 0x2c83, 0x7824, 0x080c, 0x757d, 0x0110, 0xd0ac, 0x1158, 0x9084,
+ 0x080c, 0x2c5b, 0x7924, 0x080c, 0x2c7a, 0xd19c, 0x0110, 0x080c,
+ 0x2b9b, 0x00d8, 0x080c, 0x757a, 0x1140, 0x94a2, 0x03e8, 0x1128,
+ 0x080c, 0x7541, 0x7003, 0x0001, 0x00a8, 0x7827, 0x1800, 0x080c,
+ 0x2c7a, 0x7824, 0x080c, 0x7583, 0x0110, 0xd0ac, 0x1158, 0x9084,
0x1800, 0x0950, 0x7003, 0x0001, 0x0028, 0x2001, 0x0001, 0x080c,
- 0x2832, 0x0078, 0x2009, 0x180c, 0x210c, 0xd19c, 0x1120, 0x7904,
+ 0x283d, 0x0078, 0x2009, 0x180c, 0x210c, 0xd19c, 0x1120, 0x7904,
0x918d, 0x0002, 0x7906, 0x7827, 0x0048, 0x7828, 0x9085, 0x0028,
- 0x782a, 0x7850, 0x9085, 0x0400, 0x7852, 0x2001, 0x19a8, 0x2003,
+ 0x782a, 0x7850, 0x9085, 0x0400, 0x7852, 0x2001, 0x19a9, 0x2003,
0x0000, 0x9006, 0x78f2, 0x015e, 0x003e, 0x000e, 0x012e, 0x00fe,
0x004e, 0x001e, 0x0005, 0x0006, 0x0016, 0x0036, 0x0046, 0x00b6,
- 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x0156, 0x0069, 0x0d0c, 0x87bd,
+ 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x0156, 0x0069, 0x0d0c, 0x87c3,
0x015e, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x00be, 0x004e, 0x003e,
0x001e, 0x000e, 0x0005, 0x00e6, 0x2071, 0x189e, 0x7004, 0x9086,
- 0x0001, 0x1110, 0x080c, 0x34d8, 0x00ee, 0x0005, 0x0005, 0x2a70,
- 0x2061, 0x19ac, 0x2063, 0x0003, 0x6007, 0x0003, 0x600b, 0x000f,
+ 0x0001, 0x1110, 0x080c, 0x34d3, 0x00ee, 0x0005, 0x0005, 0x2a70,
+ 0x2061, 0x19ad, 0x2063, 0x0003, 0x6007, 0x0003, 0x600b, 0x0012,
0x600f, 0x0137, 0x2001, 0x197d, 0x900e, 0x2102, 0x7196, 0x2001,
0x0100, 0x2004, 0x9082, 0x0002, 0x0218, 0x705f, 0xffff, 0x0008,
- 0x715e, 0x7067, 0xffff, 0x717e, 0x7182, 0x080c, 0xd292, 0x70eb,
+ 0x715e, 0x7067, 0xffff, 0x717e, 0x7182, 0x080c, 0xd2a9, 0x70eb,
0x00c0, 0x2061, 0x196d, 0x6003, 0x0909, 0x6106, 0x600b, 0x8800,
0x600f, 0x0200, 0x6013, 0x00ff, 0x6017, 0x001f, 0x611a, 0x601f,
0x07d0, 0x2061, 0x1975, 0x6003, 0x8000, 0x6106, 0x610a, 0x600f,
0x0200, 0x6013, 0x00ff, 0x6116, 0x601b, 0x0001, 0x611e, 0x2061,
0x198a, 0x6003, 0x514c, 0x6007, 0x4f47, 0x600b, 0x4943, 0x600f,
- 0x2020, 0x2001, 0x182c, 0x2102, 0x0005, 0x9016, 0x080c, 0x6717,
+ 0x2020, 0x2001, 0x182c, 0x2102, 0x0005, 0x9016, 0x080c, 0x671d,
0x1178, 0xb804, 0x90c4, 0x00ff, 0x98c6, 0x0006, 0x0128, 0x90c4,
0xff00, 0x98c6, 0x0600, 0x1120, 0x9186, 0x0080, 0x0108, 0x8210,
0x8108, 0x9186, 0x0800, 0x1d50, 0x2208, 0x0005, 0x2091, 0x8000,
@@ -251,7 +239,7 @@ unsigned short risc_code01[] = {
0x015e, 0x2079, 0x1800, 0x7803, 0x0005, 0x2091, 0x4080, 0x2001,
0x0089, 0x2004, 0xd084, 0x0180, 0x2001, 0x1a1d, 0x2004, 0x9005,
0x0128, 0x2001, 0x008b, 0x2004, 0xd0fc, 0x0dd8, 0x2001, 0x008a,
- 0x2003, 0x0002, 0x2003, 0x1001, 0x080c, 0x57dc, 0x1108, 0x0099,
+ 0x2003, 0x0002, 0x2003, 0x1001, 0x080c, 0x57e2, 0x1108, 0x0099,
0x0cd8, 0x0005, 0x918c, 0x03ff, 0x2001, 0x0003, 0x2004, 0x9084,
0x0600, 0x1118, 0x918d, 0x2800, 0x0010, 0x918d, 0x2000, 0x2001,
0x017f, 0x2102, 0x0005, 0x0026, 0x0126, 0x2011, 0x0080, 0x080c,
@@ -263,8 +251,8 @@ unsigned short risc_code01[] = {
0x080c, 0x0f00, 0x002e, 0x0005, 0x0026, 0x080c, 0x0efb, 0x0128,
0xd0a4, 0x1138, 0x2011, 0xcdd5, 0x0010, 0x2011, 0x0080, 0x080c,
0x0f00, 0x002e, 0x0005, 0x0026, 0x70ef, 0x0000, 0x080c, 0x0efb,
- 0x1148, 0x080c, 0x2c7b, 0x1118, 0x2011, 0x8484, 0x0058, 0x2011,
- 0x8282, 0x0040, 0x080c, 0x2c7b, 0x1118, 0x2011, 0xcdc5, 0x0010,
+ 0x1148, 0x080c, 0x2c72, 0x1118, 0x2011, 0x8484, 0x0058, 0x2011,
+ 0x8282, 0x0040, 0x080c, 0x2c72, 0x1118, 0x2011, 0xcdc5, 0x0010,
0x2011, 0xcac2, 0x080c, 0x0f00, 0x002e, 0x0005, 0x00e6, 0x0006,
0x2071, 0x1800, 0xd0b4, 0x70e8, 0x1110, 0xc0e4, 0x0048, 0x0006,
0x3b00, 0x9084, 0xff3f, 0x20d8, 0x000e, 0x70ef, 0x0000, 0xc0e5,
@@ -317,7 +305,7 @@ unsigned short risc_code01[] = {
0x00e6, 0x0126, 0x2091, 0x8000, 0x0016, 0x890e, 0x810e, 0x810f,
0x9184, 0x003f, 0xa862, 0x9184, 0xffc0, 0xa85e, 0x001e, 0x0020,
0x00e6, 0x0126, 0x2091, 0x8000, 0x2071, 0x1800, 0x702c, 0xa802,
- 0x2900, 0x702e, 0x70c0, 0x8000, 0x70c2, 0x080c, 0x85eb, 0x012e,
+ 0x2900, 0x702e, 0x70c0, 0x8000, 0x70c2, 0x080c, 0x85f1, 0x012e,
0x00ee, 0x0005, 0x2071, 0x1800, 0x9026, 0x2009, 0x0000, 0x2049,
0x0400, 0x2900, 0x702e, 0x8940, 0x2800, 0xa802, 0xa95e, 0xa863,
0x0001, 0x8420, 0x9886, 0x0440, 0x0120, 0x2848, 0x9188, 0x0040,
@@ -382,15 +370,15 @@ unsigned short risc_code01[] = {
0x1117, 0x0005, 0x00de, 0x009e, 0x080c, 0x1117, 0x0005, 0xa8a8,
0xd08c, 0x0005, 0x0096, 0xa0a0, 0x904d, 0x090c, 0x0dc5, 0xa06c,
0x908e, 0x0100, 0x0130, 0xa87b, 0x0030, 0xa883, 0x0000, 0xa897,
- 0x4002, 0x080c, 0x6dbe, 0xa09f, 0x0000, 0xa0a3, 0x0000, 0x2848,
+ 0x4002, 0x080c, 0x6dc4, 0xa09f, 0x0000, 0xa0a3, 0x0000, 0x2848,
0x080c, 0x1040, 0x009e, 0x0005, 0x00a6, 0xa0a0, 0x904d, 0x090c,
0x0dc5, 0xa06c, 0x908e, 0x0100, 0x0128, 0xa87b, 0x0001, 0xa883,
0x0000, 0x00c0, 0xa80c, 0x2050, 0xb004, 0x9005, 0x0198, 0xa80e,
0x2050, 0x8006, 0x8006, 0x8007, 0x908c, 0x003f, 0x9084, 0xffc0,
0x9080, 0x0002, 0xa076, 0xa172, 0xb000, 0xa07a, 0x2810, 0x080c,
- 0x10f8, 0x00e8, 0xa97c, 0xa894, 0x0016, 0x0006, 0x080c, 0x6dbe,
+ 0x10f8, 0x00e8, 0xa97c, 0xa894, 0x0016, 0x0006, 0x080c, 0x6dc4,
0x000e, 0x001e, 0xd1fc, 0x1138, 0xd1f4, 0x0128, 0x00c6, 0x2060,
- 0x080c, 0xb0e7, 0x00ce, 0x7008, 0x2048, 0xa89f, 0x0000, 0xa8a3,
+ 0x080c, 0xb101, 0x00ce, 0x7008, 0x2048, 0xa89f, 0x0000, 0xa8a3,
0x0000, 0x080c, 0x1040, 0x7007, 0x0000, 0x080c, 0x1117, 0x00ae,
0x0005, 0x0126, 0x2091, 0x8000, 0x782b, 0x1001, 0x7007, 0x0005,
0x7000, 0xc094, 0x7002, 0x012e, 0x0005, 0x0096, 0x2001, 0x1930,
@@ -399,12 +387,12 @@ unsigned short risc_code01[] = {
0x782b, 0x0041, 0x7007, 0x0003, 0x7000, 0xc084, 0x7002, 0x2900,
0x700a, 0x012e, 0x009e, 0x0005, 0x20e1, 0x0000, 0x2099, 0x0088,
0x782b, 0x0040, 0x0096, 0x2001, 0x1930, 0x204c, 0xaa7c, 0x009e,
- 0x080c, 0x8c54, 0x2009, 0x188c, 0x2104, 0x9084, 0xfffc, 0x200a,
- 0x080c, 0x8ab9, 0x7007, 0x0000, 0x080c, 0x1128, 0x0005, 0x7007,
+ 0x080c, 0x8c5a, 0x2009, 0x188c, 0x2104, 0x9084, 0xfffc, 0x200a,
+ 0x080c, 0x8abf, 0x7007, 0x0000, 0x080c, 0x1128, 0x0005, 0x7007,
0x0000, 0x080c, 0x1128, 0x0005, 0x0126, 0x2091, 0x2200, 0x2079,
0x0300, 0x2071, 0x1a66, 0x7003, 0x0000, 0x78bf, 0x00f6, 0x781b,
- 0x4800, 0x00c1, 0x7803, 0x0003, 0x780f, 0x0000, 0x20a9, 0x03e5,
- 0x2061, 0xedc4, 0x2c0d, 0x7912, 0xe104, 0x9ce0, 0x0002, 0x7916,
+ 0x4800, 0x00c1, 0x7803, 0x0003, 0x780f, 0x0000, 0x20a9, 0x03e8,
+ 0x2061, 0xee29, 0x2c0d, 0x7912, 0xe104, 0x9ce0, 0x0002, 0x7916,
0x1f04, 0x1312, 0x7807, 0x0007, 0x7803, 0x0000, 0x7803, 0x0001,
0x012e, 0x0005, 0x00c6, 0x7803, 0x0000, 0x7808, 0xd09c, 0x0120,
0x7820, 0x080c, 0x1376, 0x0cc8, 0x2001, 0x1a67, 0x2003, 0x0000,
@@ -412,15 +400,15 @@ unsigned short risc_code01[] = {
0x0007, 0x7827, 0x0030, 0x782b, 0x0400, 0x7827, 0x0031, 0x782b,
0x1a8a, 0x781f, 0xff00, 0x781b, 0xb700, 0x2001, 0x0200, 0x2004,
0xd0dc, 0x0110, 0x781f, 0x0303, 0x2061, 0x1a8a, 0x602f, 0x1cd0,
- 0x2001, 0x181a, 0x2004, 0x9082, 0x1cd0, 0x6032, 0x603b, 0x20e8,
- 0x2001, 0x33b1, 0xd0fc, 0x190c, 0x0dc5, 0x2001, 0x1810, 0x2004,
+ 0x2001, 0x181a, 0x2004, 0x9082, 0x1cd0, 0x6032, 0x603b, 0x20f0,
+ 0x2001, 0x33ac, 0xd0fc, 0x190c, 0x0dc5, 0x2001, 0x1810, 0x2004,
0xd0c4, 0x1128, 0x2001, 0x0003, 0x2004, 0xd0d4, 0x1118, 0x783f,
- 0x33b1, 0x0020, 0x9084, 0xc000, 0x783f, 0xb3b1, 0x604f, 0x193e,
+ 0x33ac, 0x0020, 0x9084, 0xc000, 0x783f, 0xb3ac, 0x604f, 0x193e,
0x2001, 0x1929, 0x2004, 0x6042, 0x00ce, 0x0005, 0x9086, 0x000d,
0x11d0, 0x7808, 0xd09c, 0x01b8, 0x7820, 0x0026, 0x2010, 0x080c,
- 0xce2d, 0x0180, 0x2260, 0x6000, 0x9086, 0x0004, 0x1158, 0x0016,
+ 0xce44, 0x0180, 0x2260, 0x6000, 0x9086, 0x0004, 0x1158, 0x0016,
0x6120, 0x9186, 0x0009, 0x0108, 0x0020, 0x2009, 0x004c, 0x080c,
- 0xb166, 0x001e, 0x002e, 0x0005, 0x0126, 0x2091, 0x2200, 0x7908,
+ 0xb180, 0x001e, 0x002e, 0x0005, 0x0126, 0x2091, 0x2200, 0x7908,
0x9184, 0x0070, 0x190c, 0x0dbe, 0xd19c, 0x0158, 0x7820, 0x908c,
0xf000, 0x15e8, 0x908a, 0x0024, 0x1a0c, 0x0dc5, 0x0023, 0x012e,
0x0005, 0x012e, 0x0005, 0x13cf, 0x13cf, 0x13e6, 0x13eb, 0x13ef,
@@ -429,17 +417,17 @@ unsigned short risc_code01[] = {
0x13cf, 0x13cf, 0x13cf, 0x13cf, 0x13cf, 0x13cf, 0x13f6, 0x13cf,
0x13cf, 0x13cf, 0x13cf, 0x13cf, 0x13cf, 0x13d3, 0x13d1, 0x080c,
0x0dc5, 0x080c, 0x0dbe, 0x080c, 0x159b, 0x2009, 0x1a7f, 0x2104,
- 0x8000, 0x200a, 0x080c, 0x8000, 0x080c, 0x1b02, 0x0005, 0x2009,
- 0x0048, 0x2060, 0x080c, 0xb166, 0x012e, 0x0005, 0x7004, 0xc085,
+ 0x8000, 0x200a, 0x080c, 0x8006, 0x080c, 0x1b02, 0x0005, 0x2009,
+ 0x0048, 0x2060, 0x080c, 0xb180, 0x012e, 0x0005, 0x7004, 0xc085,
0xc0b5, 0x7006, 0x0005, 0x7004, 0xc085, 0x7006, 0x0005, 0x080c,
0x159b, 0x080c, 0x16fb, 0x0005, 0x080c, 0x0dc5, 0x080c, 0x159b,
0x2060, 0x6014, 0x0096, 0x2048, 0xa83b, 0xffff, 0x009e, 0x2009,
- 0x0048, 0x080c, 0xb166, 0x2001, 0x015d, 0x2003, 0x0000, 0x2009,
+ 0x0048, 0x080c, 0xb180, 0x2001, 0x015d, 0x2003, 0x0000, 0x2009,
0x03e8, 0x8109, 0x0160, 0x2001, 0x0201, 0x2004, 0x9005, 0x0dc8,
0x2001, 0x0218, 0x2004, 0xd0ec, 0x1110, 0x080c, 0x15a0, 0x2001,
0x0307, 0x2003, 0x8000, 0x0005, 0x7004, 0xc095, 0x7006, 0x0005,
0x080c, 0x159b, 0x2060, 0x6014, 0x0096, 0x2048, 0xa83b, 0xffff,
- 0x009e, 0x2009, 0x0048, 0x080c, 0xb166, 0x0005, 0x080c, 0x159b,
+ 0x009e, 0x2009, 0x0048, 0x080c, 0xb180, 0x0005, 0x080c, 0x159b,
0x080c, 0x0dc5, 0x080c, 0x159b, 0x080c, 0x14ea, 0x7827, 0x0018,
0x79ac, 0xd1dc, 0x0904, 0x149b, 0x7827, 0x0015, 0x7828, 0x782b,
0x0000, 0x9065, 0x0140, 0x2001, 0x020d, 0x2003, 0x0050, 0x2003,
@@ -455,14 +443,14 @@ unsigned short risc_code01[] = {
0x78ab, 0x0004, 0x7803, 0x0001, 0x080c, 0x1503, 0x2001, 0x020d,
0x2003, 0x0020, 0x0005, 0x7828, 0x782b, 0x0000, 0x9065, 0x090c,
0x0dc5, 0x6014, 0x2048, 0x78ab, 0x0004, 0x918c, 0x0700, 0x01a8,
- 0x080c, 0x8000, 0x080c, 0x1b02, 0x080c, 0xce3f, 0x0158, 0xa9ac,
+ 0x080c, 0x8006, 0x080c, 0x1b02, 0x080c, 0xce56, 0x0158, 0xa9ac,
0xa936, 0xa9b0, 0xa93a, 0xa83f, 0xffff, 0xa843, 0xffff, 0xa880,
- 0xc0bd, 0xa882, 0x080c, 0xca5e, 0x0005, 0x6020, 0x9086, 0x0009,
- 0x1128, 0x2009, 0x004c, 0x080c, 0xb166, 0x0048, 0x6010, 0x00b6,
- 0x2058, 0xb800, 0x00be, 0xd0bc, 0x6024, 0x190c, 0xd22b, 0x2029,
+ 0xc0bd, 0xa882, 0x080c, 0xca71, 0x0005, 0x6020, 0x9086, 0x0009,
+ 0x1128, 0x2009, 0x004c, 0x080c, 0xb180, 0x0048, 0x6010, 0x00b6,
+ 0x2058, 0xb800, 0x00be, 0xd0bc, 0x6024, 0x190c, 0xd242, 0x2029,
0x00c8, 0x8529, 0x0128, 0x2001, 0x0201, 0x2004, 0x9005, 0x0dc8,
- 0x7dbc, 0x080c, 0xed6d, 0xd5a4, 0x1118, 0x080c, 0x15a0, 0x0005,
- 0x080c, 0x8000, 0x080c, 0x1b02, 0x0005, 0x781f, 0x0300, 0x7803,
+ 0x7dbc, 0x080c, 0xedd2, 0xd5a4, 0x1118, 0x080c, 0x15a0, 0x0005,
+ 0x080c, 0x8006, 0x080c, 0x1b02, 0x0005, 0x781f, 0x0300, 0x7803,
0x0001, 0x0005, 0x0016, 0x0066, 0x0076, 0x00f6, 0x2079, 0x0300,
0x7908, 0x918c, 0x0007, 0x9186, 0x0003, 0x0120, 0x2001, 0x0016,
0x080c, 0x1611, 0x00fe, 0x007e, 0x006e, 0x001e, 0x0005, 0x7004,
@@ -481,9 +469,9 @@ unsigned short risc_code01[] = {
0x020d, 0x2003, 0x0020, 0x080c, 0x1322, 0x7803, 0x0001, 0x00ee,
0x001e, 0x0005, 0x080c, 0x16de, 0x0dd0, 0x2001, 0x020d, 0x2003,
0x0050, 0x2003, 0x0020, 0x0461, 0x0c90, 0x0429, 0x2060, 0x2009,
- 0x0053, 0x080c, 0xb166, 0x0005, 0x0005, 0x0005, 0x00e1, 0x2008,
- 0x00d1, 0x0006, 0x7004, 0xc09d, 0x7006, 0x000e, 0x080c, 0x8fa5,
- 0x0005, 0x0089, 0x9005, 0x0118, 0x080c, 0x8ba8, 0x0cd0, 0x0005,
+ 0x0053, 0x080c, 0xb180, 0x0005, 0x0005, 0x0005, 0x00e1, 0x2008,
+ 0x00d1, 0x0006, 0x7004, 0xc09d, 0x7006, 0x000e, 0x080c, 0x8fab,
+ 0x0005, 0x0089, 0x9005, 0x0118, 0x080c, 0x8bae, 0x0cd0, 0x0005,
0x2001, 0x0036, 0x2009, 0x1820, 0x210c, 0x2011, 0x181f, 0x2214,
0x080c, 0x1611, 0x0005, 0x7808, 0xd09c, 0x0de8, 0x7820, 0x0005,
0x080c, 0x14ea, 0x00d6, 0x2069, 0x0200, 0x2009, 0x01f4, 0x8109,
@@ -493,7 +481,7 @@ unsigned short risc_code01[] = {
0x810c, 0x080c, 0x1603, 0x6827, 0x0001, 0x8109, 0x1dd0, 0x04d9,
0x6827, 0x0002, 0x04c1, 0x6804, 0x9005, 0x1130, 0x682c, 0xd0e4,
0x1500, 0x6804, 0x9005, 0x0de8, 0x79b8, 0xd1ec, 0x1130, 0x08c0,
- 0x080c, 0x8000, 0x080c, 0x1b02, 0x0090, 0x7827, 0x0015, 0x782b,
+ 0x080c, 0x8006, 0x080c, 0x1b02, 0x0090, 0x7827, 0x0015, 0x782b,
0x0000, 0x7827, 0x0018, 0x782b, 0x0000, 0x2001, 0x020d, 0x2003,
0x0020, 0x2001, 0x0307, 0x2003, 0x0300, 0x7803, 0x0001, 0x00de,
0x0005, 0x682c, 0x9084, 0x5400, 0x9086, 0x5400, 0x0d30, 0x7827,
@@ -510,16 +498,16 @@ unsigned short risc_code01[] = {
0x2001, 0x0109, 0x2004, 0xd08c, 0x01f0, 0x0006, 0x01c6, 0x01d6,
0x0136, 0x0146, 0x0156, 0x0126, 0x2091, 0x2800, 0x00f6, 0x0026,
0x0016, 0x2009, 0x1a82, 0x2104, 0x8000, 0x0208, 0x200a, 0x080c,
- 0x92e7, 0x001e, 0x002e, 0x00fe, 0x012e, 0x015e, 0x014e, 0x013e,
+ 0x92ed, 0x001e, 0x002e, 0x00fe, 0x012e, 0x015e, 0x014e, 0x013e,
0x01de, 0x01ce, 0x000e, 0x2001, 0x009b, 0x2004, 0xd0fc, 0x01d0,
0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x00f6,
0x0016, 0x2009, 0x1a83, 0x2104, 0x8000, 0x0208, 0x200a, 0x080c,
- 0x1f0c, 0x001e, 0x00fe, 0x015e, 0x014e, 0x013e, 0x01de, 0x01ce,
+ 0x1f14, 0x001e, 0x00fe, 0x015e, 0x014e, 0x013e, 0x01de, 0x01ce,
0x012e, 0x000e, 0x7818, 0xd0bc, 0x1904, 0x163a, 0x0005, 0x2001,
0x180c, 0x2004, 0xd0f4, 0x1528, 0x7a18, 0x9284, 0x0030, 0x0508,
0x9284, 0x0048, 0x9086, 0x0008, 0x11e0, 0x2001, 0x19f8, 0x2004,
0x9005, 0x01b8, 0x2001, 0x1a6a, 0x2004, 0x9086, 0x0000, 0x0188,
- 0x2009, 0x1a81, 0x2104, 0x8000, 0x0208, 0x200a, 0x080c, 0xa57b,
+ 0x2009, 0x1a81, 0x2104, 0x8000, 0x0208, 0x200a, 0x080c, 0xa595,
0x2009, 0x180c, 0x2104, 0xc0f5, 0x200a, 0x2009, 0xff00, 0x0804,
0x163a, 0x9085, 0x0001, 0x0005, 0x7832, 0x7936, 0x7a3a, 0x781b,
0x8080, 0x080c, 0x1633, 0x1108, 0x0005, 0x792c, 0x3900, 0x8000,
@@ -528,39 +516,39 @@ unsigned short risc_code01[] = {
0x9186, 0x0500, 0x0110, 0x9085, 0x0001, 0x0005, 0x0006, 0x0046,
0x00e6, 0x2071, 0x0200, 0x7037, 0x0002, 0x7058, 0x9084, 0xff00,
0x8007, 0x9086, 0x00bc, 0x1158, 0x2021, 0x1a80, 0x2404, 0x8000,
- 0x0208, 0x2022, 0x080c, 0x8000, 0x080c, 0x1b02, 0x9006, 0x00ee,
+ 0x0208, 0x2022, 0x080c, 0x8006, 0x080c, 0x1b02, 0x9006, 0x00ee,
0x004e, 0x000e, 0x0005, 0x0c11, 0x1108, 0x0005, 0x00e6, 0x0016,
0x2071, 0x0200, 0x0841, 0x6124, 0xd1dc, 0x01f8, 0x701c, 0xd08c,
0x0904, 0x175d, 0x7017, 0x0000, 0x2001, 0x0264, 0x2004, 0xd0bc,
0x0904, 0x175d, 0x2001, 0x0268, 0x00c6, 0x2064, 0x6104, 0x6038,
0x00ce, 0x918e, 0x0039, 0x1904, 0x175d, 0x9c06, 0x15f0, 0x0126,
- 0x2091, 0x2600, 0x080c, 0x7f47, 0x012e, 0x7358, 0x745c, 0x6014,
+ 0x2091, 0x2600, 0x080c, 0x7f4d, 0x012e, 0x7358, 0x745c, 0x6014,
0x905d, 0x0598, 0x2b48, 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be,
- 0xd0bc, 0x190c, 0xd206, 0xab42, 0xac3e, 0x2001, 0x1869, 0x2004,
+ 0xd0bc, 0x190c, 0xd21d, 0xab42, 0xac3e, 0x2001, 0x1869, 0x2004,
0xd0b4, 0x1170, 0x601c, 0xd0e4, 0x1158, 0x6010, 0x00b6, 0x2058,
0xb800, 0x00be, 0xd0bc, 0x1120, 0xa83b, 0x7fff, 0xa837, 0xffff,
- 0x080c, 0x2108, 0x1190, 0x080c, 0x194e, 0x2a00, 0xa816, 0x0130,
+ 0x080c, 0x2110, 0x1190, 0x080c, 0x194e, 0x2a00, 0xa816, 0x0130,
0x2800, 0xa80e, 0x2c05, 0xa80a, 0x2c00, 0xa812, 0x7037, 0x0020,
0x781f, 0x0300, 0x001e, 0x00ee, 0x0005, 0x7037, 0x0050, 0x7037,
0x0020, 0x001e, 0x00ee, 0x080c, 0x15a0, 0x0005, 0x080c, 0x0dc5,
0x2ff0, 0x0126, 0x2091, 0x2200, 0x0016, 0x00c6, 0x3e60, 0x6014,
0x2048, 0x2940, 0x903e, 0x2730, 0xa864, 0x2068, 0xa81a, 0x9d84,
- 0x000f, 0x9088, 0x20e8, 0x2165, 0x0002, 0x1794, 0x1802, 0x1794,
+ 0x000f, 0x9088, 0x20f0, 0x2165, 0x0002, 0x1794, 0x1802, 0x1794,
0x1794, 0x1798, 0x17e3, 0x1794, 0x17b8, 0x178d, 0x17f9, 0x1794,
0x1794, 0x179d, 0x18ef, 0x17cc, 0x17c2, 0xa964, 0x918c, 0x00ff,
0x918e, 0x0048, 0x0904, 0x17f9, 0x9085, 0x0001, 0x0804, 0x18e5,
0xa87c, 0xd0ac, 0x0dc8, 0x0804, 0x1809, 0xa87c, 0xd0ac, 0x0da0,
0x0804, 0x1874, 0xa898, 0x901d, 0x1108, 0xab9c, 0x9016, 0xaab2,
- 0xaa3e, 0xaa42, 0x3e00, 0x9080, 0x0008, 0x2004, 0x9080, 0x9173,
+ 0xaa3e, 0xaa42, 0x3e00, 0x9080, 0x0008, 0x2004, 0x9080, 0x9179,
0x2005, 0x9005, 0x090c, 0x0dc5, 0x2004, 0xa8ae, 0x0804, 0x18cd,
0xa87c, 0xd0bc, 0x09c8, 0xa890, 0xa842, 0xa88c, 0xa83e, 0xa888,
0x0804, 0x1809, 0xa87c, 0xd0bc, 0x0978, 0xa890, 0xa842, 0xa88c,
0xa83e, 0xa888, 0x0804, 0x1874, 0xa87c, 0xd0bc, 0x0928, 0xa890,
0xa842, 0xa88c, 0xa83e, 0xa804, 0x9045, 0x090c, 0x0dc5, 0xa164,
- 0xa91a, 0x91ec, 0x000f, 0x9d80, 0x20e8, 0x2065, 0xa888, 0xd19c,
+ 0xa91a, 0x91ec, 0x000f, 0x9d80, 0x20f0, 0x2065, 0xa888, 0xd19c,
0x1904, 0x1874, 0x0430, 0xa87c, 0xd0ac, 0x0904, 0x1794, 0xa804,
0x9045, 0x090c, 0x0dc5, 0xa164, 0xa91a, 0x91ec, 0x000f, 0x9d80,
- 0x20e8, 0x2065, 0x9006, 0xa842, 0xa83e, 0xd19c, 0x1904, 0x1874,
+ 0x20f0, 0x2065, 0x9006, 0xa842, 0xa83e, 0xd19c, 0x1904, 0x1874,
0x0080, 0xa87c, 0xd0ac, 0x0904, 0x1794, 0x9006, 0xa842, 0xa83e,
0x0804, 0x1874, 0xa87c, 0xd0ac, 0x0904, 0x1794, 0x9006, 0xa842,
0xa83e, 0x2c05, 0x908a, 0x0036, 0x1a0c, 0x0dc5, 0x9082, 0x001b,
@@ -593,7 +581,7 @@ unsigned short risc_code01[] = {
0x601e, 0xa87c, 0xc0dd, 0xa87e, 0x9006, 0x00ce, 0x001e, 0x012e,
0x0005, 0x2800, 0xa80e, 0xab0a, 0x2c00, 0xa812, 0x0c70, 0x0804,
0x1794, 0x2ff0, 0x0126, 0x2091, 0x2200, 0x0016, 0x00c6, 0x3e60,
- 0x6014, 0x2048, 0x2940, 0xa80e, 0x2061, 0x20e3, 0xa813, 0x20e3,
+ 0x6014, 0x2048, 0x2940, 0xa80e, 0x2061, 0x20eb, 0xa813, 0x20eb,
0x2c05, 0xa80a, 0xa964, 0xa91a, 0xa87c, 0xd0ac, 0x090c, 0x0dc5,
0x9006, 0xa842, 0xa83e, 0x2c05, 0x908a, 0x0034, 0x1a0c, 0x0dc5,
0xadcc, 0xacd0, 0xafd4, 0xaed8, 0xabdc, 0xaae0, 0xab2e, 0xaa32,
@@ -602,7 +590,7 @@ unsigned short risc_code01[] = {
0xa916, 0x0128, 0x0080, 0x918a, 0x0002, 0xa916, 0x1160, 0x3e60,
0x601c, 0xc085, 0x601e, 0xa87c, 0xc0dd, 0xa87e, 0x9006, 0x00ce,
0x001e, 0x012e, 0x0005, 0xa804, 0x9045, 0x090c, 0x0dc5, 0xa80e,
- 0xa064, 0xa81a, 0x9084, 0x000f, 0x9080, 0x20e8, 0x2015, 0x82ff,
+ 0xa064, 0xa81a, 0x9084, 0x000f, 0x9080, 0x20f0, 0x2015, 0x82ff,
0x090c, 0x0dc5, 0xaa12, 0x2205, 0xa80a, 0x0c08, 0x903e, 0x2730,
0xa880, 0xd0fc, 0x1190, 0x2d00, 0x0002, 0x1a78, 0x19a5, 0x19a5,
0x1a78, 0x19a5, 0x1a72, 0x1a78, 0x19a5, 0x1a15, 0x1a15, 0x1a15,
@@ -640,36 +628,37 @@ unsigned short risc_code01[] = {
0xa3ac, 0xa2b0, 0x00f8, 0xa5b4, 0xa4b8, 0xa7bc, 0xa6c0, 0x9d86,
0x000c, 0x01c0, 0xa3c4, 0xa2c8, 0x00a8, 0xa5cc, 0xa4d0, 0xa7d4,
0xa6d8, 0x9d86, 0x000c, 0x0170, 0xa3dc, 0xa2e0, 0x0058, 0x9d86,
- 0x000e, 0x1130, 0x080c, 0x20a0, 0x1904, 0x194e, 0x900e, 0x0050,
+ 0x000e, 0x1130, 0x080c, 0x20a8, 0x1904, 0x194e, 0x900e, 0x0050,
0x080c, 0x0dc5, 0xab2e, 0xaa32, 0xad1e, 0xac22, 0xaf26, 0xae2a,
- 0x080c, 0x20a0, 0x0005, 0x6014, 0x2048, 0x6118, 0x81ff, 0x0148,
+ 0x080c, 0x20a8, 0x0005, 0x6014, 0x2048, 0x6118, 0x81ff, 0x0148,
0x810c, 0x810c, 0x810c, 0x81ff, 0x1118, 0xa887, 0x0001, 0x0008,
0xa986, 0x601b, 0x0002, 0xa874, 0x9084, 0x00ff, 0x9084, 0x0008,
0x0150, 0x00e9, 0x6000, 0x9086, 0x0004, 0x1120, 0x2009, 0x0048,
- 0x080c, 0xb166, 0x0005, 0xa974, 0xd1dc, 0x1108, 0x0005, 0xa934,
+ 0x080c, 0xb180, 0x0005, 0xa974, 0xd1dc, 0x1108, 0x0005, 0xa934,
0xa88c, 0x9106, 0x1158, 0xa938, 0xa890, 0x9106, 0x1138, 0x601c,
- 0xc084, 0x601e, 0x2009, 0x0048, 0x0804, 0xb166, 0x0005, 0x0126,
+ 0xc084, 0x601e, 0x2009, 0x0048, 0x0804, 0xb180, 0x0005, 0x0126,
0x00c6, 0x2091, 0x2200, 0x00ce, 0x7908, 0x918c, 0x0007, 0x9186,
0x0000, 0x05b0, 0x9186, 0x0003, 0x0598, 0x6020, 0x6023, 0x0000,
0x0006, 0x2031, 0x0008, 0x00c6, 0x781f, 0x0808, 0x7808, 0xd09c,
0x0120, 0x080c, 0x1394, 0x8631, 0x1db8, 0x00ce, 0x781f, 0x0800,
0x2031, 0x0168, 0x00c6, 0x7808, 0xd09c, 0x190c, 0x1394, 0x00ce,
- 0x2001, 0x0038, 0x080c, 0x1b8a, 0x7930, 0x9186, 0x0040, 0x0160,
+ 0x2001, 0x0038, 0x080c, 0x1b92, 0x7930, 0x9186, 0x0040, 0x0160,
0x9186, 0x0042, 0x190c, 0x0dc5, 0x2001, 0x001e, 0x8001, 0x1df0,
- 0x8631, 0x1d40, 0x080c, 0x1b99, 0x000e, 0x6022, 0x012e, 0x0005,
- 0x080c, 0x1b86, 0x7827, 0x0015, 0x7828, 0x9c06, 0x1db8, 0x782b,
+ 0x8631, 0x1d40, 0x080c, 0x1ba1, 0x000e, 0x6022, 0x012e, 0x0005,
+ 0x080c, 0x1b8e, 0x7827, 0x0015, 0x7828, 0x9c06, 0x1db8, 0x782b,
0x0000, 0x0ca0, 0x00f6, 0x2079, 0x0300, 0x7803, 0x0000, 0x78ab,
- 0x0004, 0x00fe, 0x080c, 0x7563, 0x1188, 0x2001, 0x0138, 0x2003,
+ 0x0004, 0x2001, 0xf000, 0x8001, 0x090c, 0x0dc5, 0x7aac, 0xd2ac,
+ 0x1dd0, 0x00fe, 0x080c, 0x7569, 0x1188, 0x2001, 0x0138, 0x2003,
0x0000, 0x2001, 0x0160, 0x2003, 0x0000, 0x2011, 0x012c, 0xa001,
- 0xa001, 0x8211, 0x1de0, 0x0059, 0x0804, 0x7610, 0x0479, 0x0039,
+ 0xa001, 0x8211, 0x1de0, 0x0059, 0x0804, 0x7616, 0x0479, 0x0039,
0x2001, 0x0160, 0x2502, 0x2001, 0x0138, 0x2202, 0x0005, 0x00e6,
- 0x2071, 0x0200, 0x080c, 0x2c8f, 0x2009, 0x003c, 0x080c, 0x242a,
+ 0x2071, 0x0200, 0x080c, 0x2c86, 0x2009, 0x003c, 0x080c, 0x2432,
0x2001, 0x015d, 0x2003, 0x0000, 0x7000, 0x9084, 0x003c, 0x1de0,
- 0x080c, 0x85eb, 0x70a0, 0x70a2, 0x7098, 0x709a, 0x709c, 0x709e,
+ 0x080c, 0x85f1, 0x70a0, 0x70a2, 0x7098, 0x709a, 0x709c, 0x709e,
0x2001, 0x020d, 0x2003, 0x0020, 0x00f6, 0x2079, 0x0300, 0x080c,
0x1322, 0x7803, 0x0001, 0x00fe, 0x00ee, 0x0005, 0x2001, 0x0138,
0x2014, 0x2003, 0x0000, 0x2001, 0x0160, 0x202c, 0x2003, 0x0000,
- 0x080c, 0x7563, 0x1108, 0x0005, 0x2021, 0x0260, 0x2001, 0x0141,
+ 0x080c, 0x7569, 0x1108, 0x0005, 0x2021, 0x0260, 0x2001, 0x0141,
0x201c, 0xd3dc, 0x1168, 0x2001, 0x0109, 0x201c, 0x939c, 0x0048,
0x1160, 0x2001, 0x0111, 0x201c, 0x83ff, 0x1110, 0x8421, 0x1d70,
0x2001, 0x015d, 0x2003, 0x0000, 0x0005, 0x0046, 0x2021, 0x0019,
@@ -678,39 +667,39 @@ unsigned short risc_code01[] = {
0x601e, 0x0005, 0x2c08, 0x621c, 0x080c, 0x1611, 0x7930, 0x0005,
0x2c08, 0x621c, 0x080c, 0x16bc, 0x7930, 0x0005, 0x8001, 0x1df0,
0x0005, 0x2031, 0x0064, 0x781c, 0x9084, 0x0007, 0x0170, 0x2001,
- 0x0038, 0x0c41, 0x9186, 0x0040, 0x0904, 0x1bf7, 0x2001, 0x001e,
+ 0x0038, 0x0c41, 0x9186, 0x0040, 0x0904, 0x1bff, 0x2001, 0x001e,
0x0c69, 0x8631, 0x1d80, 0x080c, 0x0dc5, 0x781f, 0x0202, 0x2001,
0x015d, 0x2003, 0x0000, 0x2001, 0x0dac, 0x0c01, 0x781c, 0xd084,
0x0110, 0x0861, 0x04e0, 0x2001, 0x0030, 0x0891, 0x9186, 0x0040,
0x0568, 0x781c, 0xd084, 0x1da8, 0x781f, 0x0101, 0x2001, 0x0014,
0x0869, 0x2001, 0x0037, 0x0821, 0x9186, 0x0040, 0x0140, 0x2001,
- 0x0030, 0x080c, 0x1b90, 0x9186, 0x0040, 0x190c, 0x0dc5, 0x00d6,
+ 0x0030, 0x080c, 0x1b98, 0x9186, 0x0040, 0x190c, 0x0dc5, 0x00d6,
0x2069, 0x0200, 0x692c, 0xd1f4, 0x1170, 0xd1c4, 0x0160, 0xd19c,
0x0130, 0x6800, 0x9085, 0x1800, 0x6802, 0x00de, 0x0080, 0x6908,
0x9184, 0x0007, 0x1db0, 0x00de, 0x781f, 0x0100, 0x791c, 0x9184,
0x0007, 0x090c, 0x0dc5, 0xa001, 0xa001, 0x781f, 0x0200, 0x0005,
0x0126, 0x2091, 0x2400, 0x2071, 0x1a6a, 0x2079, 0x0090, 0x012e,
0x0005, 0x9280, 0x0005, 0x2004, 0x2048, 0xa97c, 0xd1dc, 0x1904,
- 0x1c99, 0xa964, 0x9184, 0x0007, 0x0002, 0x1c15, 0x1c84, 0x1c2c,
- 0x1c2e, 0x1c2c, 0x1c6c, 0x1c4c, 0x1c3b, 0x918c, 0x00ff, 0x9186,
- 0x0008, 0x1170, 0xa87c, 0xd0b4, 0x0904, 0x1ec6, 0x9006, 0xa842,
- 0xa83e, 0xa988, 0x2900, 0xa85a, 0xa813, 0x20e3, 0x0804, 0x1c95,
- 0x9186, 0x0048, 0x0904, 0x1c84, 0x080c, 0x0dc5, 0x9184, 0x00ff,
- 0x9086, 0x0013, 0x0904, 0x1c84, 0x9184, 0x00ff, 0x9086, 0x001b,
- 0x0904, 0x1c84, 0x0c88, 0xa87c, 0xd0b4, 0x0904, 0x1ec6, 0xa890,
+ 0x1ca1, 0xa964, 0x9184, 0x0007, 0x0002, 0x1c1d, 0x1c8c, 0x1c34,
+ 0x1c36, 0x1c34, 0x1c74, 0x1c54, 0x1c43, 0x918c, 0x00ff, 0x9186,
+ 0x0008, 0x1170, 0xa87c, 0xd0b4, 0x0904, 0x1ece, 0x9006, 0xa842,
+ 0xa83e, 0xa988, 0x2900, 0xa85a, 0xa813, 0x20eb, 0x0804, 0x1c9d,
+ 0x9186, 0x0048, 0x0904, 0x1c8c, 0x080c, 0x0dc5, 0x9184, 0x00ff,
+ 0x9086, 0x0013, 0x0904, 0x1c8c, 0x9184, 0x00ff, 0x9086, 0x001b,
+ 0x0904, 0x1c8c, 0x0c88, 0xa87c, 0xd0b4, 0x0904, 0x1ece, 0xa890,
0xa842, 0xa83a, 0xa88c, 0xa83e, 0xa836, 0xa8ac, 0xa846, 0xa8b0,
- 0xa84a, 0xa988, 0x0804, 0x1c8c, 0xa864, 0x9084, 0x00ff, 0x9086,
- 0x001e, 0x19d0, 0xa87c, 0xd0b4, 0x0904, 0x1ec6, 0xa890, 0xa842,
+ 0xa84a, 0xa988, 0x0804, 0x1c94, 0xa864, 0x9084, 0x00ff, 0x9086,
+ 0x001e, 0x19d0, 0xa87c, 0xd0b4, 0x0904, 0x1ece, 0xa890, 0xa842,
0xa83a, 0xa88c, 0xa83e, 0xa836, 0xa8ac, 0xa846, 0xa8b0, 0xa84a,
- 0xa804, 0xa85a, 0x2040, 0xa064, 0x9084, 0x000f, 0x9080, 0x20e8,
+ 0xa804, 0xa85a, 0x2040, 0xa064, 0x9084, 0x000f, 0x9080, 0x20f0,
0x2005, 0xa812, 0xa988, 0x0448, 0x918c, 0x00ff, 0x9186, 0x0015,
- 0x1540, 0xa87c, 0xd0b4, 0x0904, 0x1ec6, 0xa804, 0xa85a, 0x2040,
- 0xa064, 0x9084, 0x000f, 0x9080, 0x20e8, 0x2005, 0xa812, 0xa988,
- 0x9006, 0xa842, 0xa83e, 0x0088, 0xa87c, 0xd0b4, 0x0904, 0x1ec6,
+ 0x1540, 0xa87c, 0xd0b4, 0x0904, 0x1ece, 0xa804, 0xa85a, 0x2040,
+ 0xa064, 0x9084, 0x000f, 0x9080, 0x20f0, 0x2005, 0xa812, 0xa988,
+ 0x9006, 0xa842, 0xa83e, 0x0088, 0xa87c, 0xd0b4, 0x0904, 0x1ece,
0xa988, 0x9006, 0xa842, 0xa83e, 0x2900, 0xa85a, 0xa864, 0x9084,
- 0x000f, 0x9080, 0x20e8, 0x2005, 0xa812, 0xa916, 0xa87c, 0xc0dd,
+ 0x000f, 0x9080, 0x20f0, 0x2005, 0xa812, 0xa916, 0xa87c, 0xc0dd,
0xa87e, 0x0005, 0x00f6, 0x2079, 0x0090, 0x782c, 0xd0fc, 0x190c,
- 0x1f0c, 0x00e6, 0x2071, 0x1a6a, 0x7000, 0x9005, 0x1904, 0x1d00,
+ 0x1f14, 0x00e6, 0x2071, 0x1a6a, 0x7000, 0x9005, 0x1904, 0x1d08,
0x7206, 0x9280, 0x0005, 0x204c, 0x9280, 0x0004, 0x2004, 0x782b,
0x0004, 0x00f6, 0x2079, 0x0200, 0x7803, 0x0040, 0x00fe, 0x00b6,
0x2058, 0xb86c, 0x7836, 0xb890, 0x00be, 0x00f6, 0x2079, 0x0200,
@@ -723,47 +712,47 @@ unsigned short risc_code01[] = {
0x001e, 0x000e, 0x8aff, 0x01c8, 0x0126, 0x2091, 0x8000, 0x2009,
0x0306, 0x200b, 0x0808, 0x00d9, 0x0108, 0x00c9, 0x012e, 0x9006,
0x00ee, 0x00fe, 0x0005, 0x0036, 0x0046, 0xab38, 0xac34, 0x080c,
- 0x2108, 0x004e, 0x003e, 0x0d30, 0x0c98, 0x9085, 0x0001, 0x0c80,
+ 0x2110, 0x004e, 0x003e, 0x0d30, 0x0c98, 0x9085, 0x0001, 0x0c80,
0x2009, 0x0306, 0x200b, 0x4800, 0x7027, 0x0000, 0x0005, 0x0076,
- 0x0066, 0x0056, 0x0046, 0x0036, 0x0026, 0x8aff, 0x0904, 0x1ebf,
- 0x700c, 0x7214, 0x923a, 0x7010, 0x7218, 0x9203, 0x0a04, 0x1ebe,
- 0x9705, 0x0904, 0x1ebe, 0x903e, 0x2730, 0xa880, 0xd0fc, 0x1190,
- 0x2d00, 0x0002, 0x1e43, 0x1d82, 0x1d82, 0x1e43, 0x1e43, 0x1e20,
- 0x1e43, 0x1d82, 0x1e27, 0x1dd1, 0x1dd1, 0x1e43, 0x1e43, 0x1e43,
- 0x1e1a, 0x1dd1, 0xc0fc, 0xa882, 0xab2c, 0xaa30, 0xad1c, 0xac20,
- 0xdd9c, 0x0904, 0x1e50, 0x2c05, 0x908a, 0x0034, 0x1a0c, 0x0dc5,
- 0x9082, 0x001b, 0x0002, 0x1d6e, 0x1d6c, 0x1d6c, 0x1d6c, 0x1d6c,
- 0x1d6c, 0x1d72, 0x1d6c, 0x1d6c, 0x1d6c, 0x1d6c, 0x1d6c, 0x1d76,
- 0x1d6c, 0x1d6c, 0x1d6c, 0x1d6c, 0x1d6c, 0x1d7a, 0x1d6c, 0x1d6c,
- 0x1d6c, 0x1d6c, 0x1d6c, 0x1d7e, 0x080c, 0x0dc5, 0xa774, 0xa678,
- 0x0804, 0x1e50, 0xa78c, 0xa690, 0x0804, 0x1e50, 0xa7a4, 0xa6a8,
- 0x0804, 0x1e50, 0xa7bc, 0xa6c0, 0x0804, 0x1e50, 0xa7d4, 0xa6d8,
- 0x0804, 0x1e50, 0x2c05, 0x908a, 0x0036, 0x1a0c, 0x0dc5, 0x9082,
- 0x001b, 0x0002, 0x1da5, 0x1da5, 0x1da7, 0x1da5, 0x1da5, 0x1da5,
- 0x1dad, 0x1da5, 0x1da5, 0x1da5, 0x1db3, 0x1da5, 0x1da5, 0x1da5,
- 0x1db9, 0x1da5, 0x1da5, 0x1da5, 0x1dbf, 0x1da5, 0x1da5, 0x1da5,
- 0x1dc5, 0x1da5, 0x1da5, 0x1da5, 0x1dcb, 0x080c, 0x0dc5, 0xa574,
- 0xa478, 0xa37c, 0xa280, 0x0804, 0x1e50, 0xa584, 0xa488, 0xa38c,
- 0xa290, 0x0804, 0x1e50, 0xa594, 0xa498, 0xa39c, 0xa2a0, 0x0804,
- 0x1e50, 0xa5a4, 0xa4a8, 0xa3ac, 0xa2b0, 0x0804, 0x1e50, 0xa5b4,
- 0xa4b8, 0xa3bc, 0xa2c0, 0x0804, 0x1e50, 0xa5c4, 0xa4c8, 0xa3cc,
- 0xa2d0, 0x0804, 0x1e50, 0xa5d4, 0xa4d8, 0xa3dc, 0xa2e0, 0x0804,
- 0x1e50, 0x2c05, 0x908a, 0x0034, 0x1a0c, 0x0dc5, 0x9082, 0x001b,
- 0x0002, 0x1df4, 0x1df2, 0x1df2, 0x1df2, 0x1df2, 0x1df2, 0x1dfc,
- 0x1df2, 0x1df2, 0x1df2, 0x1df2, 0x1df2, 0x1e04, 0x1df2, 0x1df2,
- 0x1df2, 0x1df2, 0x1df2, 0x1e0c, 0x1df2, 0x1df2, 0x1df2, 0x1df2,
- 0x1df2, 0x1e13, 0x080c, 0x0dc5, 0xa56c, 0xa470, 0xa774, 0xa678,
- 0xa37c, 0xa280, 0x0804, 0x1e50, 0xa584, 0xa488, 0xa78c, 0xa690,
- 0xa394, 0xa298, 0x0804, 0x1e50, 0xa59c, 0xa4a0, 0xa7a4, 0xa6a8,
- 0xa3ac, 0xa2b0, 0x0804, 0x1e50, 0xa5b4, 0xa4b8, 0xa7bc, 0xa6c0,
+ 0x0066, 0x0056, 0x0046, 0x0036, 0x0026, 0x8aff, 0x0904, 0x1ec7,
+ 0x700c, 0x7214, 0x923a, 0x7010, 0x7218, 0x9203, 0x0a04, 0x1ec6,
+ 0x9705, 0x0904, 0x1ec6, 0x903e, 0x2730, 0xa880, 0xd0fc, 0x1190,
+ 0x2d00, 0x0002, 0x1e4b, 0x1d8a, 0x1d8a, 0x1e4b, 0x1e4b, 0x1e28,
+ 0x1e4b, 0x1d8a, 0x1e2f, 0x1dd9, 0x1dd9, 0x1e4b, 0x1e4b, 0x1e4b,
+ 0x1e22, 0x1dd9, 0xc0fc, 0xa882, 0xab2c, 0xaa30, 0xad1c, 0xac20,
+ 0xdd9c, 0x0904, 0x1e58, 0x2c05, 0x908a, 0x0034, 0x1a0c, 0x0dc5,
+ 0x9082, 0x001b, 0x0002, 0x1d76, 0x1d74, 0x1d74, 0x1d74, 0x1d74,
+ 0x1d74, 0x1d7a, 0x1d74, 0x1d74, 0x1d74, 0x1d74, 0x1d74, 0x1d7e,
+ 0x1d74, 0x1d74, 0x1d74, 0x1d74, 0x1d74, 0x1d82, 0x1d74, 0x1d74,
+ 0x1d74, 0x1d74, 0x1d74, 0x1d86, 0x080c, 0x0dc5, 0xa774, 0xa678,
+ 0x0804, 0x1e58, 0xa78c, 0xa690, 0x0804, 0x1e58, 0xa7a4, 0xa6a8,
+ 0x0804, 0x1e58, 0xa7bc, 0xa6c0, 0x0804, 0x1e58, 0xa7d4, 0xa6d8,
+ 0x0804, 0x1e58, 0x2c05, 0x908a, 0x0036, 0x1a0c, 0x0dc5, 0x9082,
+ 0x001b, 0x0002, 0x1dad, 0x1dad, 0x1daf, 0x1dad, 0x1dad, 0x1dad,
+ 0x1db5, 0x1dad, 0x1dad, 0x1dad, 0x1dbb, 0x1dad, 0x1dad, 0x1dad,
+ 0x1dc1, 0x1dad, 0x1dad, 0x1dad, 0x1dc7, 0x1dad, 0x1dad, 0x1dad,
+ 0x1dcd, 0x1dad, 0x1dad, 0x1dad, 0x1dd3, 0x080c, 0x0dc5, 0xa574,
+ 0xa478, 0xa37c, 0xa280, 0x0804, 0x1e58, 0xa584, 0xa488, 0xa38c,
+ 0xa290, 0x0804, 0x1e58, 0xa594, 0xa498, 0xa39c, 0xa2a0, 0x0804,
+ 0x1e58, 0xa5a4, 0xa4a8, 0xa3ac, 0xa2b0, 0x0804, 0x1e58, 0xa5b4,
+ 0xa4b8, 0xa3bc, 0xa2c0, 0x0804, 0x1e58, 0xa5c4, 0xa4c8, 0xa3cc,
+ 0xa2d0, 0x0804, 0x1e58, 0xa5d4, 0xa4d8, 0xa3dc, 0xa2e0, 0x0804,
+ 0x1e58, 0x2c05, 0x908a, 0x0034, 0x1a0c, 0x0dc5, 0x9082, 0x001b,
+ 0x0002, 0x1dfc, 0x1dfa, 0x1dfa, 0x1dfa, 0x1dfa, 0x1dfa, 0x1e04,
+ 0x1dfa, 0x1dfa, 0x1dfa, 0x1dfa, 0x1dfa, 0x1e0c, 0x1dfa, 0x1dfa,
+ 0x1dfa, 0x1dfa, 0x1dfa, 0x1e14, 0x1dfa, 0x1dfa, 0x1dfa, 0x1dfa,
+ 0x1dfa, 0x1e1b, 0x080c, 0x0dc5, 0xa56c, 0xa470, 0xa774, 0xa678,
+ 0xa37c, 0xa280, 0x0804, 0x1e58, 0xa584, 0xa488, 0xa78c, 0xa690,
+ 0xa394, 0xa298, 0x0804, 0x1e58, 0xa59c, 0xa4a0, 0xa7a4, 0xa6a8,
+ 0xa3ac, 0xa2b0, 0x0804, 0x1e58, 0xa5b4, 0xa4b8, 0xa7bc, 0xa6c0,
0xa3c4, 0xa2c8, 0x04e8, 0xa5cc, 0xa4d0, 0xa7d4, 0xa6d8, 0xa3dc,
0xa2e0, 0x04b0, 0xa864, 0x9084, 0x00ff, 0x9086, 0x001e, 0x1518,
- 0x080c, 0x20a0, 0x1904, 0x1d1d, 0x900e, 0x0804, 0x1ebf, 0xab64,
+ 0x080c, 0x20a8, 0x1904, 0x1d25, 0x900e, 0x0804, 0x1ec7, 0xab64,
0x939c, 0x00ff, 0x9386, 0x0048, 0x1180, 0x00c6, 0x7004, 0x2060,
- 0x6004, 0x9086, 0x0043, 0x00ce, 0x0904, 0x1dd1, 0xab9c, 0x9016,
+ 0x6004, 0x9086, 0x0043, 0x00ce, 0x0904, 0x1dd9, 0xab9c, 0x9016,
0xad8c, 0xac90, 0xaf94, 0xae98, 0x0098, 0x9386, 0x0008, 0x0904,
- 0x1dd1, 0x080c, 0x0dc5, 0xa964, 0x918c, 0x00ff, 0x9186, 0x0013,
- 0x0904, 0x1d82, 0x9186, 0x001b, 0x0904, 0x1dd1, 0x080c, 0x0dc5,
+ 0x1dd9, 0x080c, 0x0dc5, 0xa964, 0x918c, 0x00ff, 0x9186, 0x0013,
+ 0x0904, 0x1d8a, 0x9186, 0x001b, 0x0904, 0x1dd9, 0x080c, 0x0dc5,
0x2009, 0x030f, 0x2104, 0xd0fc, 0x0538, 0x0066, 0x2009, 0x0306,
0x2134, 0x200b, 0x4000, 0x2104, 0x9084, 0x0030, 0x15b8, 0x2031,
0x1000, 0x2600, 0x9302, 0x928b, 0x0000, 0xa82e, 0xa932, 0x0278,
@@ -772,135 +761,135 @@ unsigned short risc_code01[] = {
0x0000, 0xa833, 0x0000, 0x006e, 0x7b12, 0x7a16, 0x7d02, 0x7c06,
0x7f0a, 0x7e0e, 0x782b, 0x0001, 0x7000, 0x8000, 0x7002, 0xa83c,
0x9300, 0xa83e, 0xa840, 0x9201, 0xa842, 0x700c, 0x9300, 0x700e,
- 0x7010, 0x9201, 0x7012, 0x080c, 0x20a0, 0x0448, 0xd6b4, 0x0110,
+ 0x7010, 0x9201, 0x7012, 0x080c, 0x20a8, 0x0448, 0xd6b4, 0x0110,
0x200b, 0x4040, 0x2031, 0x0080, 0x9584, 0x007f, 0x0108, 0x9632,
0x7124, 0x7000, 0x9086, 0x0000, 0x1198, 0xc185, 0x7126, 0x2009,
- 0x0306, 0x2104, 0xd0b4, 0x1904, 0x1e61, 0x200b, 0x4040, 0x2009,
- 0x1a84, 0x2104, 0x8000, 0x0a04, 0x1e61, 0x200a, 0x0804, 0x1e61,
- 0xc18d, 0x7126, 0xd184, 0x1d58, 0x0804, 0x1e61, 0x9006, 0x002e,
+ 0x0306, 0x2104, 0xd0b4, 0x1904, 0x1e69, 0x200b, 0x4040, 0x2009,
+ 0x1a84, 0x2104, 0x8000, 0x0a04, 0x1e69, 0x200a, 0x0804, 0x1e69,
+ 0xc18d, 0x7126, 0xd184, 0x1d58, 0x0804, 0x1e69, 0x9006, 0x002e,
0x003e, 0x004e, 0x005e, 0x006e, 0x007e, 0x0005, 0x080c, 0x0dc5,
0x0026, 0x2001, 0x0105, 0x2003, 0x0010, 0x782b, 0x0004, 0x7003,
- 0x0000, 0x7004, 0x2060, 0x6014, 0x2048, 0x080c, 0xce3f, 0x0118,
- 0xa880, 0xc0bd, 0xa882, 0x782c, 0xd0ac, 0x1de8, 0x080c, 0x1d10,
+ 0x0000, 0x7004, 0x2060, 0x6014, 0x2048, 0x080c, 0xce56, 0x0118,
+ 0xa880, 0xc0bd, 0xa882, 0x782c, 0xd0ac, 0x1de8, 0x080c, 0x1d18,
0x6020, 0x9086, 0x0006, 0x1180, 0x2061, 0x0100, 0x62c8, 0x2001,
0x00fa, 0x8001, 0x1df0, 0x60c8, 0x9206, 0x1dc0, 0x60c4, 0xa89a,
- 0x60c8, 0xa896, 0x7004, 0x2060, 0x00c6, 0x080c, 0xca5e, 0x00ce,
+ 0x60c8, 0xa896, 0x7004, 0x2060, 0x00c6, 0x080c, 0xca71, 0x00ce,
0x2001, 0x19f8, 0x2004, 0x9c06, 0x1160, 0x2009, 0x0040, 0x080c,
- 0x242a, 0x080c, 0xaa3f, 0x2011, 0x0000, 0x080c, 0xa8dd, 0x080c,
- 0x9a09, 0x002e, 0x0804, 0x2050, 0x0126, 0x2091, 0x2400, 0xa858,
- 0x2040, 0x792c, 0x782b, 0x0002, 0x9184, 0x0700, 0x1904, 0x1ec8,
- 0x7000, 0x0002, 0x2050, 0x1f1e, 0x1f9e, 0x204e, 0x8001, 0x7002,
- 0x7027, 0x0000, 0xd19c, 0x1158, 0x8aff, 0x0904, 0x1f6b, 0x080c,
- 0x1d17, 0x0904, 0x2050, 0x080c, 0x1d17, 0x0804, 0x2050, 0x782b,
+ 0x2432, 0x080c, 0xaa59, 0x2011, 0x0000, 0x080c, 0xa8f7, 0x080c,
+ 0x9a0f, 0x002e, 0x0804, 0x2058, 0x0126, 0x2091, 0x2400, 0xa858,
+ 0x2040, 0x792c, 0x782b, 0x0002, 0x9184, 0x0700, 0x1904, 0x1ed0,
+ 0x7000, 0x0002, 0x2058, 0x1f26, 0x1fa6, 0x2056, 0x8001, 0x7002,
+ 0x7027, 0x0000, 0xd19c, 0x1158, 0x8aff, 0x0904, 0x1f73, 0x080c,
+ 0x1d1f, 0x0904, 0x2058, 0x080c, 0x1d1f, 0x0804, 0x2058, 0x782b,
0x0004, 0xd194, 0x0148, 0xa880, 0xc0fc, 0xa882, 0x8aff, 0x1518,
0xa87c, 0xc0f5, 0xa87e, 0x00f8, 0x0026, 0x0036, 0xab3c, 0xaa40,
0x0016, 0x7910, 0xa82c, 0x9100, 0xa82e, 0x7914, 0xa830, 0x9101,
0xa832, 0x001e, 0x7810, 0x931a, 0x7814, 0x9213, 0x7800, 0xa81e,
- 0x7804, 0xa822, 0xab3e, 0xaa42, 0x003e, 0x002e, 0x080c, 0x20bb,
+ 0x7804, 0xa822, 0xab3e, 0xaa42, 0x003e, 0x002e, 0x080c, 0x20c3,
0xa880, 0xc0fd, 0xa882, 0x2a00, 0xa816, 0x2800, 0xa85a, 0x2c00,
0xa812, 0x7003, 0x0000, 0x2009, 0x0306, 0x200b, 0x4800, 0x7027,
- 0x0000, 0x0804, 0x2050, 0x00f6, 0x0026, 0x781c, 0x0006, 0x7818,
+ 0x0000, 0x0804, 0x2058, 0x00f6, 0x0026, 0x781c, 0x0006, 0x7818,
0x0006, 0x2079, 0x0100, 0x7a14, 0x9284, 0x1984, 0x9085, 0x0012,
0x7816, 0x0036, 0x2019, 0x1000, 0x8319, 0x090c, 0x0dc5, 0x7820,
0xd0bc, 0x1dd0, 0x003e, 0x79c8, 0x000e, 0x9102, 0x001e, 0x0006,
0x0016, 0x79c4, 0x000e, 0x9103, 0x78c6, 0x000e, 0x78ca, 0x9284,
0x1984, 0x9085, 0x0012, 0x7816, 0x002e, 0x00fe, 0x782b, 0x0008,
- 0x7003, 0x0000, 0x080c, 0x1d10, 0x0804, 0x2050, 0x8001, 0x7002,
+ 0x7003, 0x0000, 0x080c, 0x1d18, 0x0804, 0x2058, 0x8001, 0x7002,
0x7024, 0x8004, 0x7026, 0xd194, 0x0170, 0x782c, 0xd0fc, 0x1904,
- 0x1f11, 0xd19c, 0x1904, 0x204c, 0x8aff, 0x0904, 0x2050, 0x080c,
- 0x1d17, 0x0804, 0x2050, 0x0026, 0x0036, 0xab3c, 0xaa40, 0x080c,
- 0x20bb, 0xdd9c, 0x1904, 0x200b, 0x2c05, 0x908a, 0x0036, 0x1a0c,
- 0x0dc5, 0x9082, 0x001b, 0x0002, 0x1fdf, 0x1fdf, 0x1fe1, 0x1fdf,
- 0x1fdf, 0x1fdf, 0x1fe7, 0x1fdf, 0x1fdf, 0x1fdf, 0x1fed, 0x1fdf,
- 0x1fdf, 0x1fdf, 0x1ff3, 0x1fdf, 0x1fdf, 0x1fdf, 0x1ff9, 0x1fdf,
- 0x1fdf, 0x1fdf, 0x1fff, 0x1fdf, 0x1fdf, 0x1fdf, 0x2005, 0x080c,
- 0x0dc5, 0xa07c, 0x931a, 0xa080, 0x9213, 0x0804, 0x1f40, 0xa08c,
- 0x931a, 0xa090, 0x9213, 0x0804, 0x1f40, 0xa09c, 0x931a, 0xa0a0,
- 0x9213, 0x0804, 0x1f40, 0xa0ac, 0x931a, 0xa0b0, 0x9213, 0x0804,
- 0x1f40, 0xa0bc, 0x931a, 0xa0c0, 0x9213, 0x0804, 0x1f40, 0xa0cc,
- 0x931a, 0xa0d0, 0x9213, 0x0804, 0x1f40, 0xa0dc, 0x931a, 0xa0e0,
- 0x9213, 0x0804, 0x1f40, 0x2c05, 0x908a, 0x0034, 0x1a0c, 0x0dc5,
- 0x9082, 0x001b, 0x0002, 0x202e, 0x202c, 0x202c, 0x202c, 0x202c,
- 0x202c, 0x2034, 0x202c, 0x202c, 0x202c, 0x202c, 0x202c, 0x203a,
- 0x202c, 0x202c, 0x202c, 0x202c, 0x202c, 0x2040, 0x202c, 0x202c,
- 0x202c, 0x202c, 0x202c, 0x2046, 0x080c, 0x0dc5, 0xa07c, 0x931a,
- 0xa080, 0x9213, 0x0804, 0x1f40, 0xa094, 0x931a, 0xa098, 0x9213,
- 0x0804, 0x1f40, 0xa0ac, 0x931a, 0xa0b0, 0x9213, 0x0804, 0x1f40,
- 0xa0c4, 0x931a, 0xa0c8, 0x9213, 0x0804, 0x1f40, 0xa0dc, 0x931a,
- 0xa0e0, 0x9213, 0x0804, 0x1f40, 0x0804, 0x1f3c, 0x080c, 0x0dc5,
+ 0x1f19, 0xd19c, 0x1904, 0x2054, 0x8aff, 0x0904, 0x2058, 0x080c,
+ 0x1d1f, 0x0804, 0x2058, 0x0026, 0x0036, 0xab3c, 0xaa40, 0x080c,
+ 0x20c3, 0xdd9c, 0x1904, 0x2013, 0x2c05, 0x908a, 0x0036, 0x1a0c,
+ 0x0dc5, 0x9082, 0x001b, 0x0002, 0x1fe7, 0x1fe7, 0x1fe9, 0x1fe7,
+ 0x1fe7, 0x1fe7, 0x1fef, 0x1fe7, 0x1fe7, 0x1fe7, 0x1ff5, 0x1fe7,
+ 0x1fe7, 0x1fe7, 0x1ffb, 0x1fe7, 0x1fe7, 0x1fe7, 0x2001, 0x1fe7,
+ 0x1fe7, 0x1fe7, 0x2007, 0x1fe7, 0x1fe7, 0x1fe7, 0x200d, 0x080c,
+ 0x0dc5, 0xa07c, 0x931a, 0xa080, 0x9213, 0x0804, 0x1f48, 0xa08c,
+ 0x931a, 0xa090, 0x9213, 0x0804, 0x1f48, 0xa09c, 0x931a, 0xa0a0,
+ 0x9213, 0x0804, 0x1f48, 0xa0ac, 0x931a, 0xa0b0, 0x9213, 0x0804,
+ 0x1f48, 0xa0bc, 0x931a, 0xa0c0, 0x9213, 0x0804, 0x1f48, 0xa0cc,
+ 0x931a, 0xa0d0, 0x9213, 0x0804, 0x1f48, 0xa0dc, 0x931a, 0xa0e0,
+ 0x9213, 0x0804, 0x1f48, 0x2c05, 0x908a, 0x0034, 0x1a0c, 0x0dc5,
+ 0x9082, 0x001b, 0x0002, 0x2036, 0x2034, 0x2034, 0x2034, 0x2034,
+ 0x2034, 0x203c, 0x2034, 0x2034, 0x2034, 0x2034, 0x2034, 0x2042,
+ 0x2034, 0x2034, 0x2034, 0x2034, 0x2034, 0x2048, 0x2034, 0x2034,
+ 0x2034, 0x2034, 0x2034, 0x204e, 0x080c, 0x0dc5, 0xa07c, 0x931a,
+ 0xa080, 0x9213, 0x0804, 0x1f48, 0xa094, 0x931a, 0xa098, 0x9213,
+ 0x0804, 0x1f48, 0xa0ac, 0x931a, 0xa0b0, 0x9213, 0x0804, 0x1f48,
+ 0xa0c4, 0x931a, 0xa0c8, 0x9213, 0x0804, 0x1f48, 0xa0dc, 0x931a,
+ 0xa0e0, 0x9213, 0x0804, 0x1f48, 0x0804, 0x1f44, 0x080c, 0x0dc5,
0x012e, 0x0005, 0x00f6, 0x00e6, 0x2071, 0x1a6a, 0x7000, 0x9086,
- 0x0000, 0x0904, 0x209b, 0x2079, 0x0090, 0x2009, 0x0207, 0x210c,
+ 0x0000, 0x0904, 0x20a3, 0x2079, 0x0090, 0x2009, 0x0207, 0x210c,
0xd194, 0x01b8, 0x2009, 0x020c, 0x210c, 0x9184, 0x0003, 0x0188,
- 0x080c, 0xedb6, 0x2001, 0x0133, 0x2004, 0x9005, 0x090c, 0x0dc5,
- 0x0016, 0x2009, 0x0040, 0x080c, 0x242a, 0x001e, 0x2001, 0x020c,
+ 0x080c, 0xee1b, 0x2001, 0x0133, 0x2004, 0x9005, 0x090c, 0x0dc5,
+ 0x0016, 0x2009, 0x0040, 0x080c, 0x2432, 0x001e, 0x2001, 0x020c,
0x2102, 0x2009, 0x0206, 0x2104, 0x2009, 0x0203, 0x210c, 0x9106,
- 0x1120, 0x2009, 0x0040, 0x080c, 0x242a, 0x782c, 0xd0fc, 0x09a8,
- 0x080c, 0x1f0c, 0x7000, 0x9086, 0x0000, 0x1978, 0x782b, 0x0004,
- 0x782c, 0xd0ac, 0x1de8, 0x2009, 0x0040, 0x080c, 0x242a, 0x782b,
- 0x0002, 0x7003, 0x0000, 0x080c, 0x1d10, 0x00ee, 0x00fe, 0x0005,
+ 0x1120, 0x2009, 0x0040, 0x080c, 0x2432, 0x782c, 0xd0fc, 0x09a8,
+ 0x080c, 0x1f14, 0x7000, 0x9086, 0x0000, 0x1978, 0x782b, 0x0004,
+ 0x782c, 0xd0ac, 0x1de8, 0x2009, 0x0040, 0x080c, 0x2432, 0x782b,
+ 0x0002, 0x7003, 0x0000, 0x080c, 0x1d18, 0x00ee, 0x00fe, 0x0005,
0xa880, 0xd0fc, 0x11a8, 0x8c60, 0x2c05, 0x9005, 0x0110, 0x8a51,
0x0005, 0xa004, 0x9005, 0x0168, 0xa85a, 0x2040, 0xa064, 0x9084,
- 0x000f, 0x9080, 0x20e8, 0x2065, 0x8cff, 0x090c, 0x0dc5, 0x8a51,
+ 0x000f, 0x9080, 0x20f0, 0x2065, 0x8cff, 0x090c, 0x0dc5, 0x8a51,
0x0005, 0x2050, 0x0005, 0xa880, 0xd0fc, 0x11b8, 0x8a50, 0x8c61,
0x2c05, 0x9005, 0x1190, 0x2800, 0x9906, 0x0120, 0xa000, 0x9005,
0x1108, 0x2900, 0x2040, 0xa85a, 0xa064, 0x9084, 0x000f, 0x9080,
- 0x20f8, 0x2065, 0x8cff, 0x090c, 0x0dc5, 0x0005, 0x0000, 0x001d,
+ 0x2100, 0x2065, 0x8cff, 0x090c, 0x0dc5, 0x0005, 0x0000, 0x001d,
0x0021, 0x0025, 0x0029, 0x002d, 0x0031, 0x0035, 0x0000, 0x001b,
0x0021, 0x0027, 0x002d, 0x0033, 0x0000, 0x0000, 0x0023, 0x0000,
- 0x0000, 0x20db, 0x20d7, 0x20db, 0x20db, 0x20e5, 0x0000, 0x20db,
- 0x20e2, 0x20e2, 0x20df, 0x20e2, 0x20e2, 0x0000, 0x20e5, 0x20e2,
- 0x0000, 0x20dd, 0x20dd, 0x0000, 0x20dd, 0x20e5, 0x0000, 0x20dd,
- 0x20e3, 0x20e3, 0x20e3, 0x0000, 0x20e3, 0x0000, 0x20e5, 0x20e3,
+ 0x0000, 0x20e3, 0x20df, 0x20e3, 0x20e3, 0x20ed, 0x0000, 0x20e3,
+ 0x20ea, 0x20ea, 0x20e7, 0x20ea, 0x20ea, 0x0000, 0x20ed, 0x20ea,
+ 0x0000, 0x20e5, 0x20e5, 0x0000, 0x20e5, 0x20ed, 0x0000, 0x20e5,
+ 0x20eb, 0x20eb, 0x20eb, 0x0000, 0x20eb, 0x0000, 0x20ed, 0x20eb,
0x00c6, 0x00d6, 0x0086, 0xab42, 0xac3e, 0xa888, 0x9055, 0x0904,
- 0x22e7, 0x2940, 0xa064, 0x90ec, 0x000f, 0x9084, 0x00ff, 0x9086,
- 0x0008, 0x1118, 0x2061, 0x20e3, 0x00d0, 0x9de0, 0x20e8, 0x9d86,
+ 0x22ef, 0x2940, 0xa064, 0x90ec, 0x000f, 0x9084, 0x00ff, 0x9086,
+ 0x0008, 0x1118, 0x2061, 0x20eb, 0x00d0, 0x9de0, 0x20f0, 0x9d86,
0x0007, 0x0130, 0x9d86, 0x000e, 0x0118, 0x9d86, 0x000f, 0x1120,
0xa08c, 0x9422, 0xa090, 0x931b, 0x2c05, 0x9065, 0x1140, 0x0310,
- 0x0804, 0x22e7, 0xa004, 0x9045, 0x0904, 0x22e7, 0x08d8, 0x2c05,
- 0x9005, 0x0904, 0x21cf, 0xdd9c, 0x1904, 0x218b, 0x908a, 0x0036,
- 0x1a0c, 0x0dc5, 0x9082, 0x001b, 0x0002, 0x2160, 0x2160, 0x2162,
- 0x2160, 0x2160, 0x2160, 0x2168, 0x2160, 0x2160, 0x2160, 0x216e,
- 0x2160, 0x2160, 0x2160, 0x2174, 0x2160, 0x2160, 0x2160, 0x217a,
- 0x2160, 0x2160, 0x2160, 0x2180, 0x2160, 0x2160, 0x2160, 0x2186,
- 0x080c, 0x0dc5, 0xa07c, 0x9422, 0xa080, 0x931b, 0x0804, 0x21c5,
- 0xa08c, 0x9422, 0xa090, 0x931b, 0x0804, 0x21c5, 0xa09c, 0x9422,
- 0xa0a0, 0x931b, 0x0804, 0x21c5, 0xa0ac, 0x9422, 0xa0b0, 0x931b,
- 0x0804, 0x21c5, 0xa0bc, 0x9422, 0xa0c0, 0x931b, 0x0804, 0x21c5,
- 0xa0cc, 0x9422, 0xa0d0, 0x931b, 0x0804, 0x21c5, 0xa0dc, 0x9422,
+ 0x0804, 0x22ef, 0xa004, 0x9045, 0x0904, 0x22ef, 0x08d8, 0x2c05,
+ 0x9005, 0x0904, 0x21d7, 0xdd9c, 0x1904, 0x2193, 0x908a, 0x0036,
+ 0x1a0c, 0x0dc5, 0x9082, 0x001b, 0x0002, 0x2168, 0x2168, 0x216a,
+ 0x2168, 0x2168, 0x2168, 0x2170, 0x2168, 0x2168, 0x2168, 0x2176,
+ 0x2168, 0x2168, 0x2168, 0x217c, 0x2168, 0x2168, 0x2168, 0x2182,
+ 0x2168, 0x2168, 0x2168, 0x2188, 0x2168, 0x2168, 0x2168, 0x218e,
+ 0x080c, 0x0dc5, 0xa07c, 0x9422, 0xa080, 0x931b, 0x0804, 0x21cd,
+ 0xa08c, 0x9422, 0xa090, 0x931b, 0x0804, 0x21cd, 0xa09c, 0x9422,
+ 0xa0a0, 0x931b, 0x0804, 0x21cd, 0xa0ac, 0x9422, 0xa0b0, 0x931b,
+ 0x0804, 0x21cd, 0xa0bc, 0x9422, 0xa0c0, 0x931b, 0x0804, 0x21cd,
+ 0xa0cc, 0x9422, 0xa0d0, 0x931b, 0x0804, 0x21cd, 0xa0dc, 0x9422,
0xa0e0, 0x931b, 0x04d0, 0x908a, 0x0034, 0x1a0c, 0x0dc5, 0x9082,
- 0x001b, 0x0002, 0x21ad, 0x21ab, 0x21ab, 0x21ab, 0x21ab, 0x21ab,
- 0x21b2, 0x21ab, 0x21ab, 0x21ab, 0x21ab, 0x21ab, 0x21b7, 0x21ab,
- 0x21ab, 0x21ab, 0x21ab, 0x21ab, 0x21bc, 0x21ab, 0x21ab, 0x21ab,
- 0x21ab, 0x21ab, 0x21c1, 0x080c, 0x0dc5, 0xa07c, 0x9422, 0xa080,
+ 0x001b, 0x0002, 0x21b5, 0x21b3, 0x21b3, 0x21b3, 0x21b3, 0x21b3,
+ 0x21ba, 0x21b3, 0x21b3, 0x21b3, 0x21b3, 0x21b3, 0x21bf, 0x21b3,
+ 0x21b3, 0x21b3, 0x21b3, 0x21b3, 0x21c4, 0x21b3, 0x21b3, 0x21b3,
+ 0x21b3, 0x21b3, 0x21c9, 0x080c, 0x0dc5, 0xa07c, 0x9422, 0xa080,
0x931b, 0x0098, 0xa094, 0x9422, 0xa098, 0x931b, 0x0070, 0xa0ac,
0x9422, 0xa0b0, 0x931b, 0x0048, 0xa0c4, 0x9422, 0xa0c8, 0x931b,
0x0020, 0xa0dc, 0x9422, 0xa0e0, 0x931b, 0x0630, 0x2300, 0x9405,
- 0x0160, 0x8a51, 0x0904, 0x22e7, 0x8c60, 0x0804, 0x2137, 0xa004,
- 0x9045, 0x0904, 0x22e7, 0x0804, 0x2112, 0x8a51, 0x0904, 0x22e7,
- 0x8c60, 0x2c05, 0x9005, 0x1158, 0xa004, 0x9045, 0x0904, 0x22e7,
- 0xa064, 0x90ec, 0x000f, 0x9de0, 0x20e8, 0x2c05, 0x2060, 0xa880,
- 0xc0fc, 0xa882, 0x0804, 0x22dc, 0x2c05, 0x8422, 0x8420, 0x831a,
- 0x9399, 0x0000, 0xac2e, 0xab32, 0xdd9c, 0x1904, 0x2279, 0x9082,
- 0x001b, 0x0002, 0x2215, 0x2215, 0x2217, 0x2215, 0x2215, 0x2215,
- 0x2225, 0x2215, 0x2215, 0x2215, 0x2233, 0x2215, 0x2215, 0x2215,
- 0x2241, 0x2215, 0x2215, 0x2215, 0x224f, 0x2215, 0x2215, 0x2215,
- 0x225d, 0x2215, 0x2215, 0x2215, 0x226b, 0x080c, 0x0dc5, 0xa17c,
+ 0x0160, 0x8a51, 0x0904, 0x22ef, 0x8c60, 0x0804, 0x213f, 0xa004,
+ 0x9045, 0x0904, 0x22ef, 0x0804, 0x211a, 0x8a51, 0x0904, 0x22ef,
+ 0x8c60, 0x2c05, 0x9005, 0x1158, 0xa004, 0x9045, 0x0904, 0x22ef,
+ 0xa064, 0x90ec, 0x000f, 0x9de0, 0x20f0, 0x2c05, 0x2060, 0xa880,
+ 0xc0fc, 0xa882, 0x0804, 0x22e4, 0x2c05, 0x8422, 0x8420, 0x831a,
+ 0x9399, 0x0000, 0xac2e, 0xab32, 0xdd9c, 0x1904, 0x2281, 0x9082,
+ 0x001b, 0x0002, 0x221d, 0x221d, 0x221f, 0x221d, 0x221d, 0x221d,
+ 0x222d, 0x221d, 0x221d, 0x221d, 0x223b, 0x221d, 0x221d, 0x221d,
+ 0x2249, 0x221d, 0x221d, 0x221d, 0x2257, 0x221d, 0x221d, 0x221d,
+ 0x2265, 0x221d, 0x221d, 0x221d, 0x2273, 0x080c, 0x0dc5, 0xa17c,
0x2400, 0x9122, 0xa180, 0x2300, 0x911b, 0x0a0c, 0x0dc5, 0xa074,
- 0x9420, 0xa078, 0x9319, 0x0804, 0x22d7, 0xa18c, 0x2400, 0x9122,
+ 0x9420, 0xa078, 0x9319, 0x0804, 0x22df, 0xa18c, 0x2400, 0x9122,
0xa190, 0x2300, 0x911b, 0x0a0c, 0x0dc5, 0xa084, 0x9420, 0xa088,
- 0x9319, 0x0804, 0x22d7, 0xa19c, 0x2400, 0x9122, 0xa1a0, 0x2300,
+ 0x9319, 0x0804, 0x22df, 0xa19c, 0x2400, 0x9122, 0xa1a0, 0x2300,
0x911b, 0x0a0c, 0x0dc5, 0xa094, 0x9420, 0xa098, 0x9319, 0x0804,
- 0x22d7, 0xa1ac, 0x2400, 0x9122, 0xa1b0, 0x2300, 0x911b, 0x0a0c,
- 0x0dc5, 0xa0a4, 0x9420, 0xa0a8, 0x9319, 0x0804, 0x22d7, 0xa1bc,
+ 0x22df, 0xa1ac, 0x2400, 0x9122, 0xa1b0, 0x2300, 0x911b, 0x0a0c,
+ 0x0dc5, 0xa0a4, 0x9420, 0xa0a8, 0x9319, 0x0804, 0x22df, 0xa1bc,
0x2400, 0x9122, 0xa1c0, 0x2300, 0x911b, 0x0a0c, 0x0dc5, 0xa0b4,
- 0x9420, 0xa0b8, 0x9319, 0x0804, 0x22d7, 0xa1cc, 0x2400, 0x9122,
+ 0x9420, 0xa0b8, 0x9319, 0x0804, 0x22df, 0xa1cc, 0x2400, 0x9122,
0xa1d0, 0x2300, 0x911b, 0x0a0c, 0x0dc5, 0xa0c4, 0x9420, 0xa0c8,
- 0x9319, 0x0804, 0x22d7, 0xa1dc, 0x2400, 0x9122, 0xa1e0, 0x2300,
+ 0x9319, 0x0804, 0x22df, 0xa1dc, 0x2400, 0x9122, 0xa1e0, 0x2300,
0x911b, 0x0a0c, 0x0dc5, 0xa0d4, 0x9420, 0xa0d8, 0x9319, 0x0804,
- 0x22d7, 0x9082, 0x001b, 0x0002, 0x2297, 0x2295, 0x2295, 0x2295,
- 0x2295, 0x2295, 0x22a4, 0x2295, 0x2295, 0x2295, 0x2295, 0x2295,
- 0x22b1, 0x2295, 0x2295, 0x2295, 0x2295, 0x2295, 0x22be, 0x2295,
- 0x2295, 0x2295, 0x2295, 0x2295, 0x22cb, 0x080c, 0x0dc5, 0xa17c,
+ 0x22df, 0x9082, 0x001b, 0x0002, 0x229f, 0x229d, 0x229d, 0x229d,
+ 0x229d, 0x229d, 0x22ac, 0x229d, 0x229d, 0x229d, 0x229d, 0x229d,
+ 0x22b9, 0x229d, 0x229d, 0x229d, 0x229d, 0x229d, 0x22c6, 0x229d,
+ 0x229d, 0x229d, 0x229d, 0x229d, 0x22d3, 0x080c, 0x0dc5, 0xa17c,
0x2400, 0x9122, 0xa180, 0x2300, 0x911b, 0x0a0c, 0x0dc5, 0xa06c,
0x9420, 0xa070, 0x9319, 0x0498, 0xa194, 0x2400, 0x9122, 0xa198,
0x2300, 0x911b, 0x0a0c, 0x0dc5, 0xa084, 0x9420, 0xa088, 0x9319,
@@ -912,25 +901,25 @@ unsigned short risc_code01[] = {
0xab22, 0xa880, 0xc0fd, 0xa882, 0x2800, 0xa85a, 0x2c00, 0xa812,
0x2a00, 0xa816, 0x000e, 0x000e, 0x000e, 0x9006, 0x0028, 0x008e,
0x00de, 0x00ce, 0x9085, 0x0001, 0x0005, 0x2001, 0x0005, 0x2004,
- 0xd0bc, 0x190c, 0x0dbe, 0x9084, 0x0007, 0x0002, 0x2308, 0x1f0c,
- 0x2308, 0x22fe, 0x2301, 0x2304, 0x2301, 0x2304, 0x080c, 0x1f0c,
- 0x0005, 0x080c, 0x11b2, 0x0005, 0x080c, 0x1f0c, 0x080c, 0x11b2,
+ 0xd0bc, 0x190c, 0x0dbe, 0x9084, 0x0007, 0x0002, 0x2310, 0x1f14,
+ 0x2310, 0x2306, 0x2309, 0x230c, 0x2309, 0x230c, 0x080c, 0x1f14,
+ 0x0005, 0x080c, 0x11b2, 0x0005, 0x080c, 0x1f14, 0x080c, 0x11b2,
0x0005, 0x0126, 0x2091, 0x2600, 0x2079, 0x0200, 0x2071, 0x0260,
0x2069, 0x1800, 0x7817, 0x0000, 0x789b, 0x0814, 0x78a3, 0x0406,
0x789f, 0x0410, 0x2009, 0x013b, 0x200b, 0x0400, 0x781b, 0x0002,
0x783b, 0x001f, 0x7837, 0x0020, 0x7803, 0x1600, 0x012e, 0x0005,
- 0x2091, 0x2600, 0x781c, 0xd0a4, 0x190c, 0x2427, 0x7900, 0xd1dc,
- 0x1118, 0x9084, 0x0006, 0x001a, 0x9084, 0x000e, 0x0002, 0x234f,
- 0x2347, 0x7f47, 0x2347, 0x2349, 0x2349, 0x2349, 0x2349, 0x7f2d,
- 0x2347, 0x234b, 0x2347, 0x2349, 0x2347, 0x2349, 0x2347, 0x080c,
- 0x0dc5, 0x0031, 0x0020, 0x080c, 0x7f2d, 0x080c, 0x7f47, 0x0005,
- 0x0006, 0x0016, 0x0026, 0x080c, 0xedb6, 0x7930, 0x9184, 0x0003,
+ 0x2091, 0x2600, 0x781c, 0xd0a4, 0x190c, 0x242f, 0x7900, 0xd1dc,
+ 0x1118, 0x9084, 0x0006, 0x001a, 0x9084, 0x000e, 0x0002, 0x2357,
+ 0x234f, 0x7f4d, 0x234f, 0x2351, 0x2351, 0x2351, 0x2351, 0x7f33,
+ 0x234f, 0x2353, 0x234f, 0x2351, 0x234f, 0x2351, 0x234f, 0x080c,
+ 0x0dc5, 0x0031, 0x0020, 0x080c, 0x7f33, 0x080c, 0x7f4d, 0x0005,
+ 0x0006, 0x0016, 0x0026, 0x080c, 0xee1b, 0x7930, 0x9184, 0x0003,
0x01c0, 0x2001, 0x19f8, 0x2004, 0x9005, 0x0170, 0x2001, 0x0133,
0x2004, 0x9005, 0x090c, 0x0dc5, 0x00c6, 0x2001, 0x19f8, 0x2064,
- 0x080c, 0xca5e, 0x00ce, 0x00f8, 0x2009, 0x0040, 0x080c, 0x242a,
+ 0x080c, 0xca71, 0x00ce, 0x00f8, 0x2009, 0x0040, 0x080c, 0x2432,
0x00d0, 0x9184, 0x0014, 0x01a0, 0x6a00, 0x9286, 0x0003, 0x0160,
- 0x080c, 0x7563, 0x1138, 0x080c, 0x7848, 0x080c, 0x6121, 0x080c,
- 0x748f, 0x0010, 0x080c, 0x5fe0, 0x080c, 0x7ff6, 0x0041, 0x0018,
+ 0x080c, 0x7569, 0x1138, 0x080c, 0x784e, 0x080c, 0x6127, 0x080c,
+ 0x7495, 0x0010, 0x080c, 0x5fe6, 0x080c, 0x7ffc, 0x0041, 0x0018,
0x9184, 0x9540, 0x1dc8, 0x002e, 0x001e, 0x000e, 0x0005, 0x00e6,
0x0036, 0x0046, 0x0056, 0x2071, 0x1a66, 0x080c, 0x1b02, 0x005e,
0x004e, 0x003e, 0x00ee, 0x0005, 0x0126, 0x2091, 0x2e00, 0x2071,
@@ -954,20 +943,20 @@ unsigned short risc_code01[] = {
0x080c, 0x0dbe, 0x00f6, 0x2079, 0x0200, 0x7902, 0xa001, 0xa001,
0xa001, 0xa001, 0xa001, 0xa001, 0x7902, 0xa001, 0xa001, 0xa001,
0xa001, 0xa001, 0xa001, 0x00fe, 0x0005, 0x0126, 0x2091, 0x2800,
- 0x2061, 0x0100, 0x2071, 0x1800, 0x2009, 0x0000, 0x080c, 0x2c89,
- 0x080c, 0x2ba4, 0x6054, 0x8004, 0x8004, 0x8004, 0x8004, 0x9084,
+ 0x2061, 0x0100, 0x2071, 0x1800, 0x2009, 0x0000, 0x080c, 0x2c80,
+ 0x080c, 0x2b9b, 0x6054, 0x8004, 0x8004, 0x8004, 0x8004, 0x9084,
0x000c, 0x6150, 0x918c, 0xfff3, 0x9105, 0x6052, 0x6050, 0x9084,
0xb17f, 0x9085, 0x2000, 0x6052, 0x2009, 0x199e, 0x2011, 0x199f,
- 0x6358, 0x939c, 0x38f0, 0x2320, 0x080c, 0x2be8, 0x1238, 0x939d,
+ 0x6358, 0x939c, 0x38f0, 0x2320, 0x080c, 0x2bdf, 0x1238, 0x939d,
0x4003, 0x94a5, 0x8603, 0x230a, 0x2412, 0x0030, 0x939d, 0x0203,
- 0x94a5, 0x8603, 0x230a, 0x2412, 0x9006, 0x080c, 0x2bd3, 0x9006,
- 0x080c, 0x2bb6, 0x20a9, 0x0012, 0x1d04, 0x247c, 0x2091, 0x6000,
- 0x1f04, 0x247c, 0x602f, 0x0100, 0x602f, 0x0000, 0x6050, 0x9085,
- 0x0400, 0x9084, 0xdfff, 0x6052, 0x6024, 0x6026, 0x080c, 0x28c2,
- 0x2009, 0x00ef, 0x6132, 0x6136, 0x080c, 0x28d2, 0x60e7, 0x0000,
+ 0x94a5, 0x8603, 0x230a, 0x2412, 0x9006, 0x080c, 0x2bca, 0x9006,
+ 0x080c, 0x2bad, 0x20a9, 0x0012, 0x1d04, 0x2484, 0x2091, 0x6000,
+ 0x1f04, 0x2484, 0x602f, 0x0100, 0x602f, 0x0000, 0x6050, 0x9085,
+ 0x0400, 0x9084, 0xdfff, 0x6052, 0x6024, 0x6026, 0x080c, 0x28cd,
+ 0x2009, 0x00ef, 0x6132, 0x6136, 0x080c, 0x28dd, 0x60e7, 0x0000,
0x61ea, 0x60e3, 0x0008, 0x604b, 0xf7f7, 0x6043, 0x0000, 0x602f,
0x0080, 0x602f, 0x0000, 0x6007, 0x349f, 0x60bb, 0x0000, 0x20a9,
- 0x0018, 0x60bf, 0x0000, 0x1f04, 0x24a9, 0x60bb, 0x0000, 0x60bf,
+ 0x0018, 0x60bf, 0x0000, 0x1f04, 0x24b1, 0x60bb, 0x0000, 0x60bf,
0x0108, 0x60bf, 0x0012, 0x60bf, 0x0405, 0x60bf, 0x0014, 0x60bf,
0x0320, 0x60bf, 0x0018, 0x601b, 0x00f0, 0x601f, 0x001e, 0x600f,
0x006b, 0x602b, 0x402f, 0x012e, 0x0005, 0x00f6, 0x2079, 0x0140,
@@ -979,4969 +968,4970 @@ unsigned short risc_code01[] = {
0x5e2c, 0x1118, 0x9184, 0x0007, 0x00aa, 0x9195, 0x0004, 0x9284,
0x0007, 0x0082, 0x0016, 0x2001, 0x188b, 0x200c, 0xd184, 0x001e,
0x0d70, 0x0c98, 0x0016, 0x2001, 0x188b, 0x200c, 0xd194, 0x001e,
- 0x0d30, 0x0c58, 0x252c, 0x2512, 0x2515, 0x2518, 0x251d, 0x251f,
- 0x2523, 0x2527, 0x080c, 0x9218, 0x00b8, 0x080c, 0x92e7, 0x00a0,
- 0x080c, 0x92e7, 0x080c, 0x9218, 0x0078, 0x0099, 0x0068, 0x080c,
- 0x9218, 0x0079, 0x0048, 0x080c, 0x92e7, 0x0059, 0x0028, 0x080c,
- 0x92e7, 0x080c, 0x9218, 0x0029, 0x002e, 0x001e, 0x000e, 0x012e,
+ 0x0d30, 0x0c58, 0x2534, 0x251a, 0x251d, 0x2520, 0x2525, 0x2527,
+ 0x252b, 0x252f, 0x080c, 0x921e, 0x00b8, 0x080c, 0x92ed, 0x00a0,
+ 0x080c, 0x92ed, 0x080c, 0x921e, 0x0078, 0x0099, 0x0068, 0x080c,
+ 0x921e, 0x0079, 0x0048, 0x080c, 0x92ed, 0x0059, 0x0028, 0x080c,
+ 0x92ed, 0x080c, 0x921e, 0x0029, 0x002e, 0x001e, 0x000e, 0x012e,
0x0005, 0x00a6, 0x6124, 0x6028, 0xd09c, 0x0118, 0xd19c, 0x1904,
- 0x279a, 0xd1f4, 0x190c, 0x0dbe, 0x080c, 0x7563, 0x0904, 0x2587,
- 0x080c, 0xd548, 0x1120, 0x7000, 0x9086, 0x0003, 0x0570, 0x6024,
- 0x9084, 0x1800, 0x0550, 0x080c, 0x7586, 0x0118, 0x080c, 0x7574,
- 0x1520, 0x6027, 0x0020, 0x6043, 0x0000, 0x080c, 0xd548, 0x0168,
- 0x080c, 0x7586, 0x1150, 0x2001, 0x19a8, 0x2003, 0x0001, 0x6027,
- 0x1800, 0x080c, 0x73de, 0x0804, 0x279d, 0x70a4, 0x9005, 0x1150,
- 0x70a7, 0x0001, 0x00d6, 0x2069, 0x0140, 0x080c, 0x75b7, 0x00de,
- 0x1904, 0x279d, 0x080c, 0x7852, 0x0428, 0x080c, 0x7586, 0x1590,
- 0x6024, 0x9084, 0x1800, 0x1108, 0x0468, 0x080c, 0x7852, 0x080c,
- 0x7848, 0x080c, 0x6121, 0x080c, 0x748f, 0x0804, 0x279a, 0xd1ac,
+ 0x27a5, 0xd1f4, 0x190c, 0x0dbe, 0x080c, 0x7569, 0x0904, 0x258f,
+ 0x080c, 0xd561, 0x1120, 0x7000, 0x9086, 0x0003, 0x0570, 0x6024,
+ 0x9084, 0x1800, 0x0550, 0x080c, 0x758c, 0x0118, 0x080c, 0x757a,
+ 0x1520, 0x6027, 0x0020, 0x6043, 0x0000, 0x080c, 0xd561, 0x0168,
+ 0x080c, 0x758c, 0x1150, 0x2001, 0x19a9, 0x2003, 0x0001, 0x6027,
+ 0x1800, 0x080c, 0x73e4, 0x0804, 0x27a8, 0x70a4, 0x9005, 0x1150,
+ 0x70a7, 0x0001, 0x00d6, 0x2069, 0x0140, 0x080c, 0x75bd, 0x00de,
+ 0x1904, 0x27a8, 0x080c, 0x7858, 0x0428, 0x080c, 0x758c, 0x1590,
+ 0x6024, 0x9084, 0x1800, 0x1108, 0x0468, 0x080c, 0x7858, 0x080c,
+ 0x784e, 0x080c, 0x6127, 0x080c, 0x7495, 0x0804, 0x27a5, 0xd1ac,
0x1508, 0x6024, 0xd0dc, 0x1170, 0xd0e4, 0x1178, 0xd0d4, 0x1190,
- 0xd0cc, 0x0130, 0x7098, 0x9086, 0x0029, 0x1110, 0x080c, 0x7735,
- 0x0804, 0x279a, 0x080c, 0x784d, 0x0048, 0x2001, 0x197e, 0x2003,
- 0x0002, 0x0020, 0x080c, 0x7698, 0x0804, 0x279a, 0x080c, 0x77d0,
- 0x0804, 0x279a, 0x6220, 0xd1bc, 0x0138, 0xd2bc, 0x1904, 0x27f7,
- 0xd2b4, 0x1904, 0x280a, 0x0000, 0xd1ac, 0x0904, 0x26af, 0x0036,
- 0x6328, 0xc3bc, 0x632a, 0x003e, 0x080c, 0x7563, 0x11c0, 0x6027,
- 0x0020, 0x0006, 0x0026, 0x0036, 0x080c, 0x757d, 0x1158, 0x080c,
- 0x7848, 0x080c, 0x6121, 0x080c, 0x748f, 0x003e, 0x002e, 0x000e,
- 0x00ae, 0x0005, 0x003e, 0x002e, 0x000e, 0x080c, 0x753b, 0x0016,
+ 0xd0cc, 0x0130, 0x7098, 0x9086, 0x0029, 0x1110, 0x080c, 0x773b,
+ 0x0804, 0x27a5, 0x080c, 0x7853, 0x0048, 0x2001, 0x197e, 0x2003,
+ 0x0002, 0x0020, 0x080c, 0x769e, 0x0804, 0x27a5, 0x080c, 0x77d6,
+ 0x0804, 0x27a5, 0x6220, 0xd1bc, 0x0138, 0xd2bc, 0x1904, 0x2802,
+ 0xd2b4, 0x1904, 0x2815, 0x0000, 0xd1ac, 0x0904, 0x26ba, 0x0036,
+ 0x6328, 0xc3bc, 0x632a, 0x003e, 0x080c, 0x7569, 0x11c0, 0x6027,
+ 0x0020, 0x0006, 0x0026, 0x0036, 0x080c, 0x7583, 0x1158, 0x080c,
+ 0x784e, 0x080c, 0x6127, 0x080c, 0x7495, 0x003e, 0x002e, 0x000e,
+ 0x00ae, 0x0005, 0x003e, 0x002e, 0x000e, 0x080c, 0x7541, 0x0016,
0x0046, 0x00c6, 0x644c, 0x9486, 0xf0f0, 0x1138, 0x2061, 0x0100,
0x644a, 0x6043, 0x0090, 0x6043, 0x0010, 0x74da, 0x948c, 0xff00,
- 0x7038, 0xd084, 0x0178, 0x9186, 0xf800, 0x1160, 0x7048, 0xd084,
- 0x1148, 0xc085, 0x704a, 0x0036, 0x2418, 0x2011, 0x8016, 0x080c,
- 0x4be3, 0x003e, 0x080c, 0xd541, 0x1904, 0x268c, 0x9196, 0xff00,
- 0x05a8, 0x7060, 0x9084, 0x00ff, 0x810f, 0x81ff, 0x0110, 0x9116,
- 0x0568, 0x7130, 0xd184, 0x1550, 0x080c, 0x33a5, 0x0128, 0xc18d,
- 0x7132, 0x080c, 0x6a84, 0x1510, 0x6240, 0x9294, 0x0010, 0x0130,
- 0x6248, 0x9294, 0xff00, 0x9296, 0xff00, 0x01c0, 0x7030, 0xd08c,
- 0x0904, 0x268c, 0x7038, 0xd08c, 0x1140, 0x2001, 0x180c, 0x200c,
- 0xd1ac, 0x1904, 0x268c, 0xc1ad, 0x2102, 0x0036, 0x73d8, 0x2011,
- 0x8013, 0x080c, 0x4be3, 0x003e, 0x0804, 0x268c, 0x7038, 0xd08c,
- 0x1140, 0x2001, 0x180c, 0x200c, 0xd1ac, 0x1904, 0x268c, 0xc1ad,
- 0x2102, 0x0036, 0x73d8, 0x2011, 0x8013, 0x080c, 0x4be3, 0x003e,
- 0x7130, 0xc185, 0x7132, 0x2011, 0x1848, 0x220c, 0xd1a4, 0x01f0,
- 0x0016, 0x2009, 0x0001, 0x2011, 0x0100, 0x080c, 0x8916, 0x2019,
- 0x000e, 0x00c6, 0x2061, 0x0000, 0x080c, 0xe8b0, 0x00ce, 0x9484,
- 0x00ff, 0x9080, 0x33b1, 0x200d, 0x918c, 0xff00, 0x810f, 0x2120,
- 0x9006, 0x2009, 0x000e, 0x080c, 0xe940, 0x001e, 0x0016, 0x2009,
- 0x0002, 0x2019, 0x0004, 0x080c, 0x3216, 0x001e, 0x00a8, 0x0156,
- 0x00b6, 0x20a9, 0x007f, 0x900e, 0x080c, 0x6717, 0x1140, 0x7030,
- 0xd084, 0x1118, 0xb800, 0xd0bc, 0x1110, 0x080c, 0x613b, 0x8108,
- 0x1f04, 0x267c, 0x00be, 0x015e, 0x00ce, 0x004e, 0x080c, 0xb058,
- 0x60e3, 0x0000, 0x001e, 0x2001, 0x1800, 0x2014, 0x9296, 0x0004,
- 0x1170, 0xd19c, 0x11a0, 0x2011, 0x180c, 0x2214, 0xd29c, 0x1120,
- 0x6204, 0x9295, 0x0002, 0x6206, 0x6228, 0xc29d, 0x622a, 0x2003,
- 0x0001, 0x2001, 0x1826, 0x2003, 0x0000, 0x6027, 0x0020, 0xd194,
- 0x0904, 0x279a, 0x0016, 0x6220, 0xd2b4, 0x0904, 0x2737, 0x080c,
- 0x8789, 0x080c, 0xa4fd, 0x6027, 0x0004, 0x00f6, 0x2019, 0x19f2,
- 0x2304, 0x907d, 0x0904, 0x2706, 0x7804, 0x9086, 0x0032, 0x15f0,
- 0x00d6, 0x00c6, 0x00e6, 0x0096, 0x2069, 0x0140, 0x782c, 0x685e,
- 0x7808, 0x685a, 0x6043, 0x0002, 0x2001, 0x0003, 0x8001, 0x1df0,
- 0x6043, 0x0000, 0x2001, 0x003c, 0x8001, 0x1df0, 0x080c, 0x2d6b,
- 0x2001, 0x001e, 0x8001, 0x0240, 0x20a9, 0x0009, 0x080c, 0x2c64,
- 0x6904, 0xd1dc, 0x1140, 0x0cb0, 0x2001, 0x0100, 0x080c, 0x2d5b,
- 0x9006, 0x080c, 0x2d5b, 0x080c, 0x97db, 0x080c, 0x98e7, 0x7814,
- 0x2048, 0xa867, 0x0103, 0x2f60, 0x080c, 0xb0e7, 0x009e, 0x00ee,
- 0x00ce, 0x00de, 0x00fe, 0x001e, 0x00ae, 0x0005, 0x00fe, 0x00d6,
- 0x2069, 0x0140, 0x6804, 0x9084, 0x4000, 0x0110, 0x080c, 0x2d6b,
- 0x00de, 0x00c6, 0x2061, 0x19e9, 0x6028, 0x080c, 0xd548, 0x0120,
- 0x909a, 0x0003, 0x1258, 0x0018, 0x909a, 0x00c8, 0x1238, 0x8000,
- 0x602a, 0x00ce, 0x080c, 0xa4d9, 0x0804, 0x2799, 0x2061, 0x0100,
- 0x62c0, 0x080c, 0xaede, 0x2019, 0x19f2, 0x2304, 0x9065, 0x0120,
- 0x2009, 0x0027, 0x080c, 0xb166, 0x00ce, 0x0804, 0x2799, 0xd2bc,
- 0x0904, 0x2780, 0x080c, 0x8796, 0x6014, 0x9084, 0x1984, 0x9085,
- 0x0010, 0x6016, 0x6027, 0x0004, 0x00d6, 0x2069, 0x0140, 0x6804,
- 0x9084, 0x4000, 0x0110, 0x080c, 0x2d6b, 0x00de, 0x00c6, 0x2061,
- 0x19e9, 0x6044, 0x080c, 0xd548, 0x0120, 0x909a, 0x0003, 0x1658,
- 0x0018, 0x909a, 0x00c8, 0x1638, 0x8000, 0x6046, 0x603c, 0x00ce,
- 0x9005, 0x05b8, 0x2009, 0x07d0, 0x080c, 0x878e, 0x9080, 0x0008,
- 0x2004, 0x9086, 0x0006, 0x1138, 0x6114, 0x918c, 0x1984, 0x918d,
- 0x0012, 0x6116, 0x0430, 0x9080, 0x0008, 0x2004, 0x9086, 0x0009,
- 0x0d98, 0x6114, 0x918c, 0x1984, 0x918d, 0x0016, 0x6116, 0x00c8,
- 0x6027, 0x0004, 0x00b0, 0x0036, 0x2019, 0x0001, 0x080c, 0xa85d,
- 0x003e, 0x2019, 0x19f8, 0x2304, 0x9065, 0x0150, 0x2009, 0x004f,
- 0x6020, 0x9086, 0x0009, 0x1110, 0x2009, 0x004f, 0x080c, 0xb166,
- 0x00ce, 0x001e, 0xd19c, 0x0904, 0x27f2, 0x7038, 0xd0ac, 0x1538,
- 0x0016, 0x0156, 0x6027, 0x0008, 0x080c, 0x2d95, 0x20a9, 0x0028,
- 0xa001, 0x1f04, 0x27a8, 0x6150, 0x9185, 0x1400, 0x6052, 0x20a9,
- 0x0366, 0x1d04, 0x27b1, 0x080c, 0x87bd, 0x6020, 0xd09c, 0x1130,
- 0x015e, 0x6152, 0x001e, 0x6027, 0x0008, 0x04a0, 0x080c, 0x2c4b,
- 0x1f04, 0x27b1, 0x015e, 0x6152, 0x001e, 0x6027, 0x0008, 0x0016,
- 0x6028, 0xc09c, 0x602a, 0x080c, 0xb058, 0x60e3, 0x0000, 0x080c,
- 0xed95, 0x080c, 0xedb0, 0x080c, 0x57d1, 0xd0fc, 0x1138, 0x080c,
- 0xd541, 0x1120, 0x9085, 0x0001, 0x080c, 0x75a7, 0x9006, 0x080c,
- 0x2d5b, 0x2009, 0x0002, 0x080c, 0x2c89, 0x00e6, 0x2071, 0x1800,
- 0x7003, 0x0004, 0x080c, 0x0ea3, 0x00ee, 0x6027, 0x0008, 0x080c,
- 0x0ba0, 0x001e, 0x918c, 0xffd0, 0x6126, 0x00ae, 0x0005, 0x0016,
- 0x2001, 0x188b, 0x200c, 0xd184, 0x001e, 0x0904, 0x25b4, 0x0016,
- 0x2009, 0x2803, 0x00d0, 0x2001, 0x188b, 0x200c, 0xc184, 0x2102,
- 0x001e, 0x0c40, 0x0016, 0x2001, 0x188b, 0x200c, 0xd194, 0x001e,
- 0x0904, 0x25b4, 0x0016, 0x2009, 0x2816, 0x0038, 0x2001, 0x188b,
- 0x200c, 0xc194, 0x2102, 0x001e, 0x08a8, 0x6028, 0xc0bc, 0x602a,
- 0x2001, 0x0156, 0x2003, 0xbc91, 0x8000, 0x2003, 0xffff, 0x6043,
- 0x0001, 0x080c, 0x2c83, 0x6027, 0x0080, 0x6017, 0x0000, 0x6043,
- 0x0000, 0x0817, 0x0006, 0x0016, 0x0026, 0x0036, 0x00e6, 0x00f6,
- 0x0126, 0x2091, 0x8000, 0x2071, 0x1800, 0x71d0, 0x70d2, 0x9116,
- 0x0904, 0x2881, 0x81ff, 0x01a0, 0x2009, 0x0000, 0x080c, 0x2c89,
- 0x2011, 0x8011, 0x2019, 0x010e, 0x231c, 0x939e, 0x0007, 0x1118,
- 0x2019, 0x0001, 0x0010, 0x2019, 0x0000, 0x080c, 0x4be3, 0x0448,
- 0x2001, 0x19a9, 0x200c, 0x81ff, 0x1140, 0x2001, 0x0109, 0x2004,
- 0xd0b4, 0x0118, 0x2019, 0x0003, 0x0008, 0x2118, 0x2011, 0x8012,
- 0x080c, 0x4be3, 0x080c, 0x0ea3, 0x080c, 0x57d1, 0xd0fc, 0x1188,
- 0x080c, 0xd541, 0x1170, 0x00c6, 0x080c, 0x291d, 0x080c, 0xa7c4,
- 0x2061, 0x0100, 0x2019, 0x0028, 0x2009, 0x0002, 0x080c, 0x3216,
- 0x00ce, 0x012e, 0x00fe, 0x00ee, 0x003e, 0x002e, 0x001e, 0x000e,
- 0x0005, 0x2028, 0x918c, 0x00ff, 0x2130, 0x9094, 0xff00, 0x11f0,
- 0x2011, 0x1837, 0x2214, 0xd2ac, 0x11c8, 0x81ff, 0x01e8, 0x2011,
- 0x181f, 0x2204, 0x9106, 0x1190, 0x2011, 0x1820, 0x2214, 0x9294,
- 0xff00, 0x9584, 0xff00, 0x9206, 0x1148, 0x2011, 0x1820, 0x2214,
- 0x9294, 0x00ff, 0x9584, 0x00ff, 0x9206, 0x1120, 0x2500, 0x080c,
- 0x826b, 0x0048, 0x9584, 0x00ff, 0x9080, 0x33b1, 0x200d, 0x918c,
- 0xff00, 0x810f, 0x9006, 0x0005, 0x9080, 0x33b1, 0x200d, 0x918c,
- 0x00ff, 0x0005, 0x00d6, 0x2069, 0x0140, 0x2001, 0x1818, 0x2003,
- 0x00ef, 0x20a9, 0x0010, 0x9006, 0x6852, 0x6856, 0x1f04, 0x28cd,
- 0x00de, 0x0005, 0x0006, 0x00d6, 0x0026, 0x2069, 0x0140, 0x2001,
- 0x1818, 0x2102, 0x8114, 0x8214, 0x8214, 0x8214, 0x20a9, 0x0010,
- 0x6853, 0x0000, 0x9006, 0x82ff, 0x1128, 0x9184, 0x000f, 0x9080,
- 0xf58c, 0x2005, 0x6856, 0x8211, 0x1f04, 0x28e2, 0x002e, 0x00de,
- 0x000e, 0x0005, 0x00c6, 0x2061, 0x1800, 0x6030, 0x0110, 0xc09d,
- 0x0008, 0xc09c, 0x6032, 0x00ce, 0x0005, 0x0156, 0x00d6, 0x0026,
- 0x0016, 0x0006, 0x2069, 0x0140, 0x6980, 0x9116, 0x0180, 0x9112,
- 0x1230, 0x8212, 0x8210, 0x22a8, 0x2001, 0x0402, 0x0018, 0x22a8,
- 0x2001, 0x0404, 0x680e, 0x1f04, 0x2912, 0x680f, 0x0000, 0x000e,
- 0x001e, 0x002e, 0x00de, 0x015e, 0x0005, 0x080c, 0x57cd, 0xd0c4,
- 0x0150, 0xd0a4, 0x0140, 0x9006, 0x0046, 0x2020, 0x2009, 0x002e,
- 0x080c, 0xe940, 0x004e, 0x0005, 0x00f6, 0x0016, 0x0026, 0x2079,
- 0x0140, 0x78c4, 0xd0dc, 0x0904, 0x2989, 0x080c, 0x2be8, 0x0660,
- 0x9084, 0x0700, 0x908e, 0x0600, 0x1120, 0x2011, 0x4000, 0x900e,
- 0x0458, 0x908e, 0x0500, 0x1120, 0x2011, 0x8000, 0x900e, 0x0420,
- 0x908e, 0x0400, 0x1120, 0x9016, 0x2009, 0x0001, 0x00e8, 0x908e,
- 0x0300, 0x1120, 0x9016, 0x2009, 0x0002, 0x00b0, 0x908e, 0x0200,
- 0x1120, 0x9016, 0x2009, 0x0004, 0x0078, 0x908e, 0x0100, 0x1548,
- 0x9016, 0x2009, 0x0008, 0x0040, 0x9084, 0x0700, 0x908e, 0x0300,
- 0x1500, 0x2011, 0x0030, 0x0058, 0x2300, 0x9080, 0x0020, 0x2018,
- 0x080c, 0x91ab, 0x928c, 0xff00, 0x0110, 0x2011, 0x00ff, 0x2200,
- 0x8007, 0x9085, 0x004c, 0x78c2, 0x2009, 0x0138, 0x220a, 0x080c,
- 0x7563, 0x1118, 0x2009, 0x196e, 0x220a, 0x002e, 0x001e, 0x00fe,
- 0x0005, 0x78c3, 0x0000, 0x0cc8, 0x0126, 0x2091, 0x2800, 0x0006,
- 0x0016, 0x0026, 0x2001, 0x0170, 0x200c, 0x8000, 0x2014, 0x9184,
- 0x0003, 0x0110, 0x080c, 0x0dbe, 0x002e, 0x001e, 0x000e, 0x012e,
- 0x0005, 0x2001, 0x0171, 0x2004, 0xd0dc, 0x0168, 0x2001, 0x0170,
- 0x200c, 0x918c, 0x00ff, 0x918e, 0x004c, 0x1128, 0x200c, 0x918c,
- 0xff00, 0x810f, 0x0005, 0x900e, 0x2001, 0x0227, 0x2004, 0x8007,
- 0x9084, 0x00ff, 0x8004, 0x9108, 0x2001, 0x0226, 0x2004, 0x8007,
- 0x9084, 0x00ff, 0x8004, 0x9108, 0x0005, 0x0018, 0x000c, 0x0018,
- 0x0020, 0x1000, 0x0800, 0x1000, 0x1800, 0x0156, 0x0006, 0x0016,
- 0x0026, 0x00e6, 0x2001, 0x1991, 0x2004, 0x908a, 0x0007, 0x1a0c,
- 0x0dc5, 0x0033, 0x00ee, 0x002e, 0x001e, 0x000e, 0x015e, 0x0005,
- 0x29e7, 0x2a05, 0x2a29, 0x2a2b, 0x2a54, 0x2a56, 0x2a58, 0x2001,
- 0x0001, 0x080c, 0x2832, 0x080c, 0x2c46, 0x2001, 0x1993, 0x2003,
- 0x0000, 0x7828, 0x9084, 0xe1d7, 0x782a, 0x9006, 0x20a9, 0x0009,
- 0x080c, 0x2c04, 0x2001, 0x1991, 0x2003, 0x0006, 0x2009, 0x001e,
- 0x2011, 0x2a59, 0x080c, 0x879b, 0x0005, 0x2009, 0x1996, 0x200b,
- 0x0000, 0x2001, 0x199b, 0x2003, 0x0036, 0x2001, 0x199a, 0x2003,
- 0x002a, 0x2001, 0x1993, 0x2003, 0x0001, 0x9006, 0x080c, 0x2bb6,
- 0x2001, 0xffff, 0x20a9, 0x0009, 0x080c, 0x2c04, 0x2001, 0x1991,
- 0x2003, 0x0006, 0x2009, 0x001e, 0x2011, 0x2a59, 0x080c, 0x879b,
- 0x0005, 0x080c, 0x0dc5, 0x2001, 0x199b, 0x2003, 0x0036, 0x2001,
- 0x1993, 0x2003, 0x0003, 0x7a38, 0x9294, 0x0005, 0x9296, 0x0004,
- 0x0110, 0x9006, 0x0010, 0x2001, 0x0001, 0x080c, 0x2bb6, 0x2001,
- 0x1997, 0x2003, 0x0000, 0x2001, 0xffff, 0x20a9, 0x0009, 0x080c,
- 0x2c04, 0x2001, 0x1991, 0x2003, 0x0006, 0x2009, 0x001e, 0x2011,
- 0x2a59, 0x080c, 0x879b, 0x0005, 0x080c, 0x0dc5, 0x080c, 0x0dc5,
- 0x0005, 0x0006, 0x0016, 0x0026, 0x00e6, 0x00f6, 0x0156, 0x0126,
- 0x2091, 0x8000, 0x2079, 0x0100, 0x2001, 0x1993, 0x2004, 0x908a,
- 0x0007, 0x1a0c, 0x0dc5, 0x0043, 0x012e, 0x015e, 0x00fe, 0x00ee,
- 0x002e, 0x001e, 0x000e, 0x0005, 0x2a7b, 0x2a9b, 0x2adb, 0x2b0b,
- 0x2b2f, 0x2b3f, 0x2b41, 0x080c, 0x2bf8, 0x11b0, 0x7850, 0x9084,
- 0xefff, 0x7852, 0x2009, 0x1999, 0x2104, 0x7a38, 0x9294, 0x0005,
- 0x9296, 0x0004, 0x0110, 0xc08d, 0x0008, 0xc085, 0x200a, 0x2001,
- 0x1991, 0x2003, 0x0001, 0x0030, 0x080c, 0x2b65, 0x2001, 0xffff,
- 0x080c, 0x29f6, 0x0005, 0x080c, 0x2b43, 0x05e0, 0x2009, 0x199a,
- 0x2104, 0x8001, 0x200a, 0x080c, 0x2bf8, 0x1178, 0x7850, 0x9084,
- 0xefff, 0x7852, 0x7a38, 0x9294, 0x0005, 0x9296, 0x0005, 0x0518,
- 0x2009, 0x1999, 0x2104, 0xc085, 0x200a, 0x2009, 0x1996, 0x2104,
- 0x8000, 0x200a, 0x9086, 0x0005, 0x0118, 0x080c, 0x2b4b, 0x00c0,
- 0x200b, 0x0000, 0x7a38, 0x9294, 0x0006, 0x9296, 0x0004, 0x0110,
- 0x9006, 0x0010, 0x2001, 0x0001, 0x080c, 0x2bd3, 0x2001, 0x1993,
- 0x2003, 0x0002, 0x0028, 0x2001, 0x1991, 0x2003, 0x0003, 0x0010,
- 0x080c, 0x2a18, 0x0005, 0x080c, 0x2b43, 0x0560, 0x2009, 0x199a,
- 0x2104, 0x8001, 0x200a, 0x080c, 0x2bf8, 0x1168, 0x7850, 0x9084,
- 0xefff, 0x7852, 0x2001, 0x1991, 0x2003, 0x0003, 0x2001, 0x1992,
- 0x2003, 0x0000, 0x00b8, 0x2009, 0x199a, 0x2104, 0x9005, 0x1118,
- 0x080c, 0x2b88, 0x0010, 0x080c, 0x2b58, 0x080c, 0x2b4b, 0x2009,
- 0x1996, 0x200b, 0x0000, 0x2001, 0x1993, 0x2003, 0x0001, 0x080c,
- 0x2a18, 0x0000, 0x0005, 0x04b9, 0x0508, 0x080c, 0x2bf8, 0x11b8,
- 0x7850, 0x9084, 0xefff, 0x7852, 0x2009, 0x1997, 0x2104, 0x8000,
- 0x200a, 0x9086, 0x0007, 0x0108, 0x0078, 0x2001, 0x199c, 0x2003,
- 0x000a, 0x2009, 0x1999, 0x2104, 0xc0fd, 0x200a, 0x0038, 0x0419,
- 0x2001, 0x1993, 0x2003, 0x0004, 0x080c, 0x2a43, 0x0005, 0x0099,
- 0x0168, 0x080c, 0x2bf8, 0x1138, 0x7850, 0x9084, 0xefff, 0x7852,
- 0x080c, 0x2a2f, 0x0018, 0x0079, 0x080c, 0x2a43, 0x0005, 0x080c,
- 0x0dc5, 0x080c, 0x0dc5, 0x2009, 0x199b, 0x2104, 0x8001, 0x200a,
- 0x090c, 0x2ba4, 0x0005, 0x7a38, 0x9294, 0x0005, 0x9296, 0x0005,
- 0x0110, 0x9006, 0x0010, 0x2001, 0x0001, 0x080c, 0x2bd3, 0x0005,
- 0x7a38, 0x9294, 0x0006, 0x9296, 0x0006, 0x0110, 0x9006, 0x0010,
- 0x2001, 0x0001, 0x080c, 0x2bb6, 0x0005, 0x2009, 0x1996, 0x2104,
- 0x8000, 0x200a, 0x9086, 0x0005, 0x0108, 0x0068, 0x200b, 0x0000,
- 0x7a38, 0x9294, 0x0006, 0x9296, 0x0006, 0x0110, 0x9006, 0x0010,
- 0x2001, 0x0001, 0x04d9, 0x7a38, 0x9294, 0x0005, 0x9296, 0x0005,
- 0x0110, 0x9006, 0x0010, 0x2001, 0x0001, 0x080c, 0x2bd3, 0x0005,
- 0x0086, 0x2001, 0x1999, 0x2004, 0x9084, 0x7fff, 0x090c, 0x0dc5,
- 0x2009, 0x1998, 0x2144, 0x8846, 0x280a, 0x9844, 0x0dd8, 0xd08c,
- 0x1120, 0xd084, 0x1120, 0x080c, 0x0dc5, 0x9006, 0x0010, 0x2001,
- 0x0001, 0x00a1, 0x008e, 0x0005, 0x0006, 0x0156, 0x2001, 0x1991,
- 0x20a9, 0x0009, 0x2003, 0x0000, 0x8000, 0x1f04, 0x2baa, 0x2001,
- 0x1998, 0x2003, 0x8000, 0x015e, 0x000e, 0x0005, 0x00f6, 0x2079,
- 0x0100, 0x9085, 0x0000, 0x0158, 0x7838, 0x9084, 0xfff9, 0x9085,
- 0x0004, 0x783a, 0x2009, 0x199e, 0x210c, 0x795a, 0x0050, 0x7838,
- 0x9084, 0xfffb, 0x9085, 0x0006, 0x783a, 0x2009, 0x199f, 0x210c,
- 0x795a, 0x00fe, 0x0005, 0x00f6, 0x2079, 0x0100, 0x9085, 0x0000,
- 0x0138, 0x7838, 0x9084, 0xfffa, 0x9085, 0x0004, 0x783a, 0x0030,
- 0x7838, 0x9084, 0xfffb, 0x9085, 0x0005, 0x783a, 0x00fe, 0x0005,
- 0x0006, 0x2001, 0x0100, 0x2004, 0x9082, 0x0007, 0x000e, 0x0005,
- 0x0006, 0x2001, 0x0100, 0x2004, 0x9082, 0x0009, 0x000e, 0x0005,
- 0x0156, 0x20a9, 0x0064, 0x7820, 0x080c, 0x2c83, 0xd09c, 0x1110,
- 0x1f04, 0x2bfb, 0x015e, 0x0005, 0x0126, 0x0016, 0x0006, 0x2091,
- 0x8000, 0x7850, 0x9085, 0x0040, 0x7852, 0x7850, 0x9084, 0xfbcf,
- 0x7852, 0x080c, 0x2c83, 0x9085, 0x2000, 0x7852, 0x000e, 0x2008,
- 0x9186, 0x0000, 0x1118, 0x783b, 0x0007, 0x0090, 0x9186, 0x0001,
- 0x1118, 0x783b, 0x0006, 0x0060, 0x9186, 0x0002, 0x1118, 0x783b,
- 0x0005, 0x0030, 0x9186, 0x0003, 0x1118, 0x783b, 0x0004, 0x0000,
- 0x0006, 0x1d04, 0x2c31, 0x080c, 0x87bd, 0x1f04, 0x2c31, 0x7850,
- 0x9085, 0x0400, 0x9084, 0xdfbf, 0x7852, 0x080c, 0x2c83, 0x9085,
- 0x1000, 0x7852, 0x000e, 0x001e, 0x012e, 0x0005, 0x7850, 0x9084,
- 0xffcf, 0x7852, 0x0005, 0x0006, 0x0156, 0x00f6, 0x2079, 0x0100,
- 0x20a9, 0x000a, 0x7854, 0xd0ac, 0x1130, 0x7820, 0xd0e4, 0x1140,
- 0x1f04, 0x2c55, 0x0028, 0x7854, 0xd08c, 0x1110, 0x1f04, 0x2c5b,
- 0x00fe, 0x015e, 0x000e, 0x0005, 0x1d04, 0x2c64, 0x080c, 0x87bd,
- 0x1f04, 0x2c64, 0x0005, 0x0006, 0x2001, 0x199d, 0x2004, 0x9086,
- 0x0000, 0x000e, 0x0005, 0x0006, 0x2001, 0x199d, 0x2004, 0x9086,
- 0x0001, 0x000e, 0x0005, 0x0006, 0x2001, 0x199d, 0x2004, 0x9086,
- 0x0002, 0x000e, 0x0005, 0xa001, 0xa001, 0xa001, 0xa001, 0xa001,
- 0x0005, 0x0006, 0x2001, 0x19a9, 0x2102, 0x000e, 0x0005, 0x2009,
- 0x0171, 0x2104, 0xd0dc, 0x0140, 0x2009, 0x0170, 0x2104, 0x200b,
- 0x0080, 0xa001, 0xa001, 0x200a, 0x0005, 0x0036, 0x0046, 0x2001,
- 0x0141, 0x200c, 0x918c, 0xff00, 0x9186, 0x2100, 0x0140, 0x9186,
- 0x2000, 0x0170, 0x9186, 0x0100, 0x1904, 0x2cfc, 0x0048, 0x0016,
- 0x2009, 0x1a88, 0x2104, 0x8000, 0x0208, 0x200a, 0x001e, 0x04f0,
- 0x2009, 0x00a2, 0x080c, 0x0e52, 0x2019, 0x0160, 0x2324, 0x2011,
- 0x0003, 0x2009, 0x0169, 0x2104, 0x9084, 0x0007, 0x210c, 0x918c,
- 0x0007, 0x910e, 0x1db0, 0x9086, 0x0003, 0x1548, 0x2304, 0x0066,
- 0x0076, 0x2031, 0x0002, 0x233c, 0x973e, 0x0148, 0x8631, 0x1dd8,
- 0x2031, 0x1a89, 0x263c, 0x8738, 0x0208, 0x2732, 0x2304, 0x007e,
- 0x006e, 0x9402, 0x02a0, 0x19d0, 0x8211, 0x19d8, 0x84ff, 0x0170,
- 0x2001, 0x0141, 0x200c, 0x918c, 0xff00, 0x9186, 0x0100, 0x0130,
- 0x2009, 0x180c, 0x2104, 0xc0dd, 0x200a, 0x0008, 0x0421, 0x2001,
- 0x1982, 0x200c, 0x080c, 0x0e52, 0x004e, 0x003e, 0x0005, 0x2001,
- 0x180c, 0x2004, 0xd0dc, 0x01b0, 0x2001, 0x0160, 0x2004, 0x9005,
- 0x0140, 0x2001, 0x0141, 0x2004, 0x9084, 0xff00, 0x9086, 0x0100,
- 0x1148, 0x0126, 0x2091, 0x8000, 0x0016, 0x0026, 0x0021, 0x002e,
- 0x001e, 0x012e, 0x0005, 0x00c6, 0x2061, 0x0100, 0x6014, 0x0006,
- 0x2001, 0x0161, 0x2003, 0x0000, 0x6017, 0x0018, 0xa001, 0xa001,
- 0x602f, 0x0008, 0x6104, 0x918e, 0x0010, 0x6106, 0x918e, 0x0010,
- 0x6106, 0x6017, 0x0040, 0x04b9, 0x001e, 0x9184, 0x0003, 0x01e0,
- 0x0036, 0x0016, 0x2019, 0x0141, 0x6124, 0x918c, 0x0028, 0x1120,
- 0x2304, 0x9084, 0x2800, 0x0dc0, 0x001e, 0x919c, 0xffe4, 0x9184,
- 0x0001, 0x0118, 0x9385, 0x0009, 0x6016, 0x9184, 0x0002, 0x0118,
- 0x9385, 0x0012, 0x6016, 0x003e, 0x2001, 0x180c, 0x200c, 0xc1dc,
- 0x2102, 0x00ce, 0x0005, 0x0016, 0x0026, 0x080c, 0x757d, 0x0108,
- 0xc0bc, 0x2009, 0x0140, 0x2114, 0x9294, 0x0001, 0x9215, 0x220a,
- 0x002e, 0x001e, 0x0005, 0x0016, 0x0026, 0x2009, 0x0140, 0x2114,
- 0x9294, 0x0001, 0x9285, 0x1000, 0x200a, 0x220a, 0x002e, 0x001e,
- 0x0005, 0x0016, 0x0026, 0x2009, 0x0140, 0x2114, 0x9294, 0x0001,
- 0x9215, 0x220a, 0x002e, 0x001e, 0x0005, 0x0006, 0x0016, 0x2009,
- 0x0140, 0x2104, 0x1128, 0x080c, 0x757d, 0x0110, 0xc0bc, 0x0008,
- 0xc0bd, 0x200a, 0x001e, 0x000e, 0x0005, 0x0006, 0x0156, 0x6050,
- 0x9085, 0x0040, 0x6052, 0x6050, 0x9084, 0xfbcf, 0x6052, 0x080c,
- 0x2c83, 0x9085, 0x2000, 0x6052, 0x20a9, 0x0012, 0x1d04, 0x2da6,
- 0x080c, 0x87bd, 0x1f04, 0x2da6, 0x6050, 0x9085, 0x0400, 0x9084,
- 0xdfbf, 0x6052, 0x015e, 0x000e, 0x0005, 0x3021, 0x3021, 0x2e45,
- 0x2e45, 0x2e51, 0x2e51, 0x2e5d, 0x2e5d, 0x2e6b, 0x2e6b, 0x2e77,
- 0x2e77, 0x2e85, 0x2e85, 0x2e93, 0x2e93, 0x2ea5, 0x2ea5, 0x2eb1,
- 0x2eb1, 0x2ebf, 0x2ebf, 0x2edd, 0x2edd, 0x2efd, 0x2efd, 0x2ecd,
- 0x2ecd, 0x2eed, 0x2eed, 0x2f0b, 0x2f0b, 0x2ea3, 0x2ea3, 0x2ea3,
- 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3,
- 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3,
- 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3,
- 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3, 0x2f1d, 0x2f1d, 0x2f29,
- 0x2f29, 0x2f37, 0x2f37, 0x2f45, 0x2f45, 0x2f55, 0x2f55, 0x2f63,
- 0x2f63, 0x2f73, 0x2f73, 0x2f83, 0x2f83, 0x2f95, 0x2f95, 0x2fa3,
- 0x2fa3, 0x2fb3, 0x2fb3, 0x2fd5, 0x2fd5, 0x2ff7, 0x2ff7, 0x2fc3,
- 0x2fc3, 0x2fe6, 0x2fe6, 0x3006, 0x3006, 0x2ea3, 0x2ea3, 0x2ea3,
- 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3,
- 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3,
- 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3,
- 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3,
- 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3,
- 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3, 0x0106, 0x0006, 0x0126,
- 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x24d9, 0x0804,
- 0x3019, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146,
- 0x0156, 0x080c, 0x22ed, 0x0804, 0x3019, 0x0106, 0x0006, 0x0126,
- 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x22ed, 0x080c,
- 0x24d9, 0x0804, 0x3019, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6,
- 0x0136, 0x0146, 0x0156, 0x080c, 0x2328, 0x0804, 0x3019, 0x0106,
- 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c,
- 0x24d9, 0x080c, 0x2328, 0x0804, 0x3019, 0x0106, 0x0006, 0x0126,
- 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x22ed, 0x080c,
- 0x2328, 0x0804, 0x3019, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6,
- 0x0136, 0x0146, 0x0156, 0x080c, 0x22ed, 0x080c, 0x24d9, 0x080c,
- 0x2328, 0x0804, 0x3019, 0xa001, 0x0cf0, 0x0106, 0x0006, 0x0126,
- 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x1394, 0x0804,
- 0x3019, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146,
- 0x0156, 0x080c, 0x24d9, 0x080c, 0x1394, 0x0804, 0x3019, 0x0106,
- 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c,
- 0x22ed, 0x080c, 0x1394, 0x0804, 0x3019, 0x0106, 0x0006, 0x0126,
- 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x24d9, 0x080c,
- 0x1394, 0x080c, 0x2328, 0x0804, 0x3019, 0x0106, 0x0006, 0x0126,
- 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x22ed, 0x080c,
- 0x24d9, 0x080c, 0x1394, 0x0804, 0x3019, 0x0106, 0x0006, 0x0126,
- 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x22ed, 0x080c,
- 0x1394, 0x080c, 0x2328, 0x0804, 0x3019, 0x0106, 0x0006, 0x0126,
- 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x1394, 0x080c,
- 0x2328, 0x0804, 0x3019, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6,
- 0x0136, 0x0146, 0x0156, 0x080c, 0x22ed, 0x080c, 0x24d9, 0x080c,
- 0x1394, 0x080c, 0x2328, 0x0804, 0x3019, 0x0106, 0x0006, 0x0126,
- 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x298c, 0x0804,
- 0x3019, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146,
- 0x0156, 0x080c, 0x298c, 0x080c, 0x24d9, 0x0804, 0x3019, 0x0106,
- 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c,
- 0x298c, 0x080c, 0x22ed, 0x0804, 0x3019, 0x0106, 0x0006, 0x0126,
- 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x298c, 0x080c,
- 0x22ed, 0x080c, 0x24d9, 0x0804, 0x3019, 0x0106, 0x0006, 0x0126,
- 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x298c, 0x080c,
- 0x2328, 0x0804, 0x3019, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6,
- 0x0136, 0x0146, 0x0156, 0x080c, 0x298c, 0x080c, 0x24d9, 0x080c,
- 0x2328, 0x0804, 0x3019, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6,
- 0x0136, 0x0146, 0x0156, 0x080c, 0x298c, 0x080c, 0x22ed, 0x080c,
- 0x2328, 0x0804, 0x3019, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6,
- 0x0136, 0x0146, 0x0156, 0x080c, 0x298c, 0x080c, 0x22ed, 0x080c,
- 0x24d9, 0x080c, 0x2328, 0x0804, 0x3019, 0x0106, 0x0006, 0x0126,
- 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x298c, 0x080c,
- 0x1394, 0x0804, 0x3019, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6,
- 0x0136, 0x0146, 0x0156, 0x080c, 0x298c, 0x080c, 0x24d9, 0x080c,
- 0x1394, 0x0804, 0x3019, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6,
- 0x0136, 0x0146, 0x0156, 0x080c, 0x298c, 0x080c, 0x22ed, 0x080c,
- 0x1394, 0x0804, 0x3019, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6,
- 0x0136, 0x0146, 0x0156, 0x080c, 0x298c, 0x080c, 0x24d9, 0x080c,
- 0x1394, 0x080c, 0x2328, 0x0804, 0x3019, 0x0106, 0x0006, 0x0126,
- 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x298c, 0x080c,
- 0x22ed, 0x080c, 0x24d9, 0x080c, 0x1394, 0x0498, 0x0106, 0x0006,
- 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x298c,
- 0x080c, 0x22ed, 0x080c, 0x1394, 0x080c, 0x2328, 0x0410, 0x0106,
- 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c,
- 0x298c, 0x080c, 0x1394, 0x080c, 0x2328, 0x0098, 0x0106, 0x0006,
- 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x298c,
- 0x080c, 0x22ed, 0x080c, 0x24d9, 0x080c, 0x1394, 0x080c, 0x2328,
- 0x0000, 0x015e, 0x014e, 0x013e, 0x01de, 0x01ce, 0x012e, 0x000e,
- 0x010e, 0x000d, 0x00b6, 0x00c6, 0x0026, 0x0046, 0x9026, 0x080c,
- 0x6a4a, 0x1904, 0x3132, 0x72dc, 0x2001, 0x197d, 0x2004, 0x9005,
- 0x1110, 0xd29c, 0x0148, 0xd284, 0x1138, 0xd2bc, 0x1904, 0x3132,
- 0x080c, 0x3137, 0x0804, 0x3132, 0xd2cc, 0x1904, 0x3132, 0x080c,
- 0x7563, 0x1120, 0x70af, 0xffff, 0x0804, 0x3132, 0xd294, 0x0120,
- 0x70af, 0xffff, 0x0804, 0x3132, 0x080c, 0x33a0, 0x0160, 0x080c,
- 0xd548, 0x0128, 0x2001, 0x1818, 0x203c, 0x0804, 0x30bf, 0x70af,
- 0xffff, 0x0804, 0x3132, 0x2001, 0x1818, 0x203c, 0x7294, 0xd284,
- 0x0904, 0x30bf, 0xd28c, 0x1904, 0x30bf, 0x0036, 0x73ac, 0x938e,
- 0xffff, 0x1110, 0x2019, 0x0001, 0x8314, 0x92e0, 0x1c80, 0x2c04,
- 0x938c, 0x0001, 0x0120, 0x9084, 0xff00, 0x8007, 0x0010, 0x9084,
- 0x00ff, 0x970e, 0x05d0, 0x908e, 0x0000, 0x05b8, 0x908e, 0x00ff,
- 0x1150, 0x7230, 0xd284, 0x15b0, 0x7294, 0xc28d, 0x7296, 0x70af,
- 0xffff, 0x003e, 0x04a0, 0x900e, 0x080c, 0x2889, 0x080c, 0x66ac,
- 0x1538, 0x9006, 0xb8bb, 0x0520, 0xb8ac, 0x9005, 0x0148, 0x00c6,
- 0x2060, 0x080c, 0x8bbd, 0x00ce, 0x090c, 0x8f5e, 0xb8af, 0x0000,
- 0x080c, 0x6a8c, 0x1168, 0x7030, 0xd08c, 0x0130, 0xb800, 0xd0bc,
- 0x0138, 0x080c, 0x6937, 0x0120, 0x080c, 0x3150, 0x0148, 0x0028,
- 0x080c, 0x3290, 0x080c, 0x317c, 0x0118, 0x8318, 0x0804, 0x306c,
- 0x73ae, 0x0010, 0x70af, 0xffff, 0x003e, 0x0804, 0x3132, 0x9780,
- 0x33b1, 0x203d, 0x97bc, 0xff00, 0x873f, 0x2041, 0x007e, 0x70ac,
- 0x9096, 0xffff, 0x1118, 0x900e, 0x28a8, 0x0050, 0x9812, 0x0220,
- 0x2008, 0x9802, 0x20a8, 0x0020, 0x70af, 0xffff, 0x0804, 0x3132,
- 0x2700, 0x0156, 0x0016, 0x9106, 0x0904, 0x3127, 0xc484, 0x080c,
- 0x6717, 0x0148, 0x080c, 0xd548, 0x1904, 0x3127, 0x080c, 0x66ac,
- 0x1904, 0x312f, 0x0008, 0xc485, 0xb8bb, 0x0520, 0xb8ac, 0x9005,
- 0x0148, 0x00c6, 0x2060, 0x080c, 0x8bbd, 0x00ce, 0x090c, 0x8f5e,
- 0xb8af, 0x0000, 0x080c, 0x6a8c, 0x1130, 0x7030, 0xd08c, 0x01f8,
- 0xb800, 0xd0bc, 0x11e0, 0x7294, 0xd28c, 0x0180, 0x080c, 0x6a8c,
- 0x9082, 0x0006, 0x02e0, 0xd484, 0x1118, 0x080c, 0x66d1, 0x0028,
- 0x080c, 0x331c, 0x01a0, 0x080c, 0x3347, 0x0088, 0x080c, 0x3290,
- 0x080c, 0xd548, 0x1160, 0x080c, 0x317c, 0x0188, 0x0040, 0x080c,
- 0xd548, 0x1118, 0x080c, 0x331c, 0x0110, 0x0451, 0x0140, 0x001e,
- 0x8108, 0x015e, 0x1f04, 0x30d8, 0x70af, 0xffff, 0x0018, 0x001e,
- 0x015e, 0x71ae, 0x004e, 0x002e, 0x00ce, 0x00be, 0x0005, 0x00c6,
- 0x0016, 0x70af, 0x0001, 0x2009, 0x007e, 0x080c, 0x66ac, 0x1168,
- 0xb813, 0x00ff, 0xb817, 0xfffe, 0x080c, 0x3290, 0x04a9, 0x0128,
- 0x70dc, 0xc0bd, 0x70de, 0x080c, 0xd292, 0x001e, 0x00ce, 0x0005,
- 0x0016, 0x0076, 0x00d6, 0x00c6, 0x2001, 0x184c, 0x2004, 0x9084,
- 0x00ff, 0xb842, 0x080c, 0xb139, 0x01d0, 0x2b00, 0x6012, 0x080c,
- 0xd2bb, 0x6023, 0x0001, 0x9006, 0x080c, 0x6649, 0x2001, 0x0000,
- 0x080c, 0x665d, 0x0126, 0x2091, 0x8000, 0x70a8, 0x8000, 0x70aa,
- 0x012e, 0x2009, 0x0004, 0x080c, 0xb166, 0x9085, 0x0001, 0x00ce,
- 0x00de, 0x007e, 0x001e, 0x0005, 0x0016, 0x0076, 0x00d6, 0x00c6,
- 0x2001, 0x184c, 0x2004, 0x9084, 0x00ff, 0xb842, 0x080c, 0xb139,
- 0x0548, 0x2b00, 0x6012, 0xb800, 0xc0c4, 0xb802, 0xb8a0, 0x9086,
- 0x007e, 0x0140, 0xb804, 0x9084, 0x00ff, 0x9086, 0x0006, 0x1110,
- 0x080c, 0x324b, 0x080c, 0xd2bb, 0x6023, 0x0001, 0x9006, 0x080c,
- 0x6649, 0x2001, 0x0002, 0x080c, 0x665d, 0x0126, 0x2091, 0x8000,
- 0x70a8, 0x8000, 0x70aa, 0x012e, 0x2009, 0x0002, 0x080c, 0xb166,
- 0x9085, 0x0001, 0x00ce, 0x00de, 0x007e, 0x001e, 0x0005, 0x00b6,
- 0x00c6, 0x0026, 0x2009, 0x0080, 0x080c, 0x66ac, 0x1140, 0xb813,
- 0x00ff, 0xb817, 0xfffc, 0x0039, 0x0110, 0x70e3, 0xffff, 0x002e,
- 0x00ce, 0x00be, 0x0005, 0x0016, 0x0076, 0x00d6, 0x00c6, 0x080c,
- 0xb091, 0x01d0, 0x2b00, 0x6012, 0x080c, 0xd2bb, 0x6023, 0x0001,
- 0x9006, 0x080c, 0x6649, 0x2001, 0x0002, 0x080c, 0x665d, 0x0126,
- 0x2091, 0x8000, 0x70e4, 0x8000, 0x70e6, 0x012e, 0x2009, 0x0002,
- 0x080c, 0xb166, 0x9085, 0x0001, 0x00ce, 0x00de, 0x007e, 0x001e,
- 0x0005, 0x00c6, 0x00d6, 0x0126, 0x2091, 0x8000, 0x2009, 0x007f,
- 0x080c, 0x66ac, 0x11b8, 0xb813, 0x00ff, 0xb817, 0xfffd, 0xb8cf,
- 0x0004, 0x080c, 0xb091, 0x0170, 0x2b00, 0x6012, 0x6316, 0x6023,
- 0x0001, 0x620a, 0x080c, 0xd2bb, 0x2009, 0x0022, 0x080c, 0xb166,
- 0x9085, 0x0001, 0x012e, 0x00de, 0x00ce, 0x0005, 0x00e6, 0x00c6,
- 0x0066, 0x0036, 0x0026, 0x00b6, 0x21f0, 0x080c, 0x94e5, 0x080c,
- 0x9465, 0x080c, 0xaf25, 0x080c, 0xc041, 0x3e08, 0x2130, 0x81ff,
- 0x0120, 0x20a9, 0x007e, 0x900e, 0x0018, 0x20a9, 0x007f, 0x900e,
- 0x0016, 0x080c, 0x6717, 0x1140, 0x9686, 0x0002, 0x1118, 0xb800,
- 0xd0bc, 0x1110, 0x080c, 0x613b, 0x001e, 0x8108, 0x1f04, 0x3230,
- 0x9686, 0x0001, 0x190c, 0x3374, 0x00be, 0x002e, 0x003e, 0x006e,
- 0x00ce, 0x00ee, 0x0005, 0x00e6, 0x00c6, 0x0046, 0x0036, 0x0026,
- 0x0016, 0x00b6, 0x6210, 0x2258, 0xbaa0, 0x0026, 0x2019, 0x0029,
- 0x080c, 0x94da, 0x0076, 0x2039, 0x0000, 0x080c, 0x93ad, 0x2c08,
- 0x080c, 0xe671, 0x007e, 0x001e, 0xba10, 0xbb14, 0xbcc0, 0x080c,
- 0x613b, 0xba12, 0xbb16, 0xbcc2, 0x00be, 0x001e, 0x002e, 0x003e,
- 0x004e, 0x00ce, 0x00ee, 0x0005, 0x00e6, 0x0006, 0x00b6, 0x6010,
- 0x2058, 0xb8a0, 0x00be, 0x9086, 0x0080, 0x0150, 0x2071, 0x1800,
- 0x70a8, 0x9005, 0x0110, 0x8001, 0x70aa, 0x000e, 0x00ee, 0x0005,
- 0x2071, 0x1800, 0x70e4, 0x9005, 0x0dc0, 0x8001, 0x70e6, 0x0ca8,
- 0xb800, 0xc08c, 0xb802, 0x0005, 0x00f6, 0x00e6, 0x00c6, 0x00b6,
- 0x0046, 0x0036, 0x0026, 0x0016, 0x0156, 0x2178, 0x81ff, 0x1118,
- 0x20a9, 0x0001, 0x0078, 0x080c, 0x57cd, 0xd0c4, 0x0140, 0xd0a4,
- 0x0130, 0x9006, 0x2020, 0x2009, 0x002d, 0x080c, 0xe940, 0x20a9,
- 0x0800, 0x9016, 0x0026, 0x928e, 0x007e, 0x0904, 0x32fb, 0x928e,
- 0x007f, 0x0904, 0x32fb, 0x928e, 0x0080, 0x05e8, 0x9288, 0x1000,
- 0x210c, 0x81ff, 0x05c0, 0x8fff, 0x1148, 0x2001, 0x198f, 0x0006,
- 0x2003, 0x0001, 0x04f1, 0x000e, 0x2003, 0x0000, 0x00b6, 0x00c6,
- 0x2158, 0x2001, 0x0001, 0x080c, 0x6a56, 0x00ce, 0x00be, 0x2019,
- 0x0029, 0x080c, 0x94da, 0x0076, 0x2039, 0x0000, 0x080c, 0x93ad,
- 0x00b6, 0x00c6, 0x0026, 0x2158, 0xba04, 0x9294, 0x00ff, 0x9286,
- 0x0006, 0x1118, 0xb807, 0x0404, 0x0028, 0x2001, 0x0004, 0x8007,
- 0x9215, 0xba06, 0x002e, 0x00ce, 0x00be, 0x0016, 0x2c08, 0x080c,
- 0xe671, 0x001e, 0x007e, 0x002e, 0x8210, 0x1f04, 0x32b2, 0x015e,
- 0x001e, 0x002e, 0x003e, 0x004e, 0x00be, 0x00ce, 0x00ee, 0x00fe,
- 0x0005, 0x0046, 0x0026, 0x0016, 0x080c, 0x57cd, 0xd0c4, 0x0140,
- 0xd0a4, 0x0130, 0x9006, 0x2220, 0x2009, 0x0029, 0x080c, 0xe940,
- 0x001e, 0x002e, 0x004e, 0x0005, 0x0016, 0x0026, 0x0036, 0x00c6,
- 0x7294, 0x82ff, 0x01e8, 0x080c, 0x6a84, 0x11d0, 0x2100, 0x080c,
- 0x28bc, 0x81ff, 0x01b8, 0x2019, 0x0001, 0x8314, 0x92e0, 0x1c80,
- 0x2c04, 0xd384, 0x0120, 0x9084, 0xff00, 0x8007, 0x0010, 0x9084,
- 0x00ff, 0x9116, 0x0138, 0x9096, 0x00ff, 0x0110, 0x8318, 0x0c68,
- 0x9085, 0x0001, 0x00ce, 0x003e, 0x002e, 0x001e, 0x0005, 0x0016,
- 0x00c6, 0x0126, 0x2091, 0x8000, 0x0036, 0x2019, 0x0029, 0x00a9,
- 0x003e, 0x9180, 0x1000, 0x2004, 0x9065, 0x0158, 0x0016, 0x00c6,
- 0x2061, 0x1ab8, 0x001e, 0x6112, 0x080c, 0x324b, 0x001e, 0x080c,
- 0x66d1, 0x012e, 0x00ce, 0x001e, 0x0005, 0x0016, 0x0026, 0x2110,
- 0x080c, 0xaa80, 0x080c, 0xecaa, 0x002e, 0x001e, 0x0005, 0x2001,
- 0x1837, 0x2004, 0xd0cc, 0x0005, 0x00c6, 0x00b6, 0x080c, 0x7563,
- 0x1118, 0x20a9, 0x0800, 0x0010, 0x20a9, 0x0782, 0x080c, 0x7563,
- 0x1110, 0x900e, 0x0010, 0x2009, 0x007e, 0x9180, 0x1000, 0x2004,
- 0x905d, 0x0130, 0x86ff, 0x0110, 0xb800, 0xd0bc, 0x090c, 0x66d1,
- 0x8108, 0x1f04, 0x3385, 0x2061, 0x1800, 0x607f, 0x0000, 0x6080,
- 0x9084, 0x00ff, 0x6082, 0x60b3, 0x0000, 0x00be, 0x00ce, 0x0005,
- 0x2001, 0x1869, 0x2004, 0xd0bc, 0x0005, 0x2011, 0x1848, 0x2214,
- 0xd2ec, 0x0005, 0x0026, 0x2011, 0x1867, 0x2214, 0xd2dc, 0x002e,
- 0x0005, 0x7eef, 0x7de8, 0x7ce4, 0x80e2, 0x7be1, 0x80e0, 0x80dc,
- 0x80da, 0x7ad9, 0x80d6, 0x80d5, 0x80d4, 0x80d3, 0x80d2, 0x80d1,
- 0x79ce, 0x78cd, 0x80cc, 0x80cb, 0x80ca, 0x80c9, 0x80c7, 0x80c6,
- 0x77c5, 0x76c3, 0x80bc, 0x80ba, 0x75b9, 0x80b6, 0x74b5, 0x73b4,
- 0x72b3, 0x80b2, 0x80b1, 0x80ae, 0x71ad, 0x80ac, 0x70ab, 0x6faa,
- 0x6ea9, 0x80a7, 0x6da6, 0x6ca5, 0x6ba3, 0x6a9f, 0x699e, 0x689d,
- 0x809b, 0x8098, 0x6797, 0x6690, 0x658f, 0x6488, 0x6384, 0x6282,
- 0x8081, 0x8080, 0x617c, 0x607a, 0x8079, 0x5f76, 0x8075, 0x8074,
- 0x8073, 0x8072, 0x8071, 0x806e, 0x5e6d, 0x806c, 0x5d6b, 0x5c6a,
- 0x5b69, 0x8067, 0x5a66, 0x5965, 0x5863, 0x575c, 0x565a, 0x5559,
- 0x8056, 0x8055, 0x5454, 0x5353, 0x5252, 0x5151, 0x504e, 0x4f4d,
- 0x804c, 0x804b, 0x4e4a, 0x4d49, 0x8047, 0x4c46, 0x8045, 0x8043,
- 0x803c, 0x803a, 0x8039, 0x8036, 0x4b35, 0x8034, 0x4a33, 0x4932,
- 0x4831, 0x802e, 0x472d, 0x462c, 0x452b, 0x442a, 0x4329, 0x4227,
- 0x8026, 0x8025, 0x4123, 0x401f, 0x3f1e, 0x3e1d, 0x3d1b, 0x3c18,
- 0x8017, 0x8010, 0x3b0f, 0x3a08, 0x8004, 0x3902, 0x8001, 0x8000,
- 0x8000, 0x3800, 0x3700, 0x3600, 0x8000, 0x3500, 0x8000, 0x8000,
- 0x8000, 0x3400, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
- 0x3300, 0x3200, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
- 0x3100, 0x3000, 0x8000, 0x8000, 0x2f00, 0x8000, 0x2e00, 0x2d00,
- 0x2c00, 0x8000, 0x8000, 0x8000, 0x2b00, 0x8000, 0x2a00, 0x2900,
- 0x2800, 0x8000, 0x2700, 0x2600, 0x2500, 0x2400, 0x2300, 0x2200,
- 0x8000, 0x8000, 0x2100, 0x2000, 0x1f00, 0x1e00, 0x1d00, 0x1c00,
- 0x8000, 0x8000, 0x1b00, 0x1a00, 0x8000, 0x1900, 0x8000, 0x8000,
- 0x8000, 0x8000, 0x8000, 0x8000, 0x1800, 0x8000, 0x1700, 0x1600,
- 0x1500, 0x8000, 0x1400, 0x1300, 0x1200, 0x1100, 0x1000, 0x0f00,
- 0x8000, 0x8000, 0x0e00, 0x0d00, 0x0c00, 0x0b00, 0x0a00, 0x0900,
- 0x8000, 0x8000, 0x0800, 0x0700, 0x8000, 0x0600, 0x8000, 0x8000,
- 0x8000, 0x0500, 0x0400, 0x0300, 0x8000, 0x0200, 0x8000, 0x8000,
- 0x8000, 0x0100, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
- 0x0000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
+ 0x7038, 0xd084, 0x0190, 0x080c, 0xd561, 0x1118, 0x9186, 0xf800,
+ 0x1160, 0x7048, 0xd084, 0x1148, 0xc085, 0x704a, 0x0036, 0x2418,
+ 0x2011, 0x8016, 0x080c, 0x4be9, 0x003e, 0x080c, 0xd55a, 0x1904,
+ 0x2697, 0x9196, 0xff00, 0x05a8, 0x7060, 0x9084, 0x00ff, 0x810f,
+ 0x81ff, 0x0110, 0x9116, 0x0568, 0x7130, 0xd184, 0x1550, 0x080c,
+ 0x33a0, 0x0128, 0xc18d, 0x7132, 0x080c, 0x6a8a, 0x1510, 0x6240,
+ 0x9294, 0x0010, 0x0130, 0x6248, 0x9294, 0xff00, 0x9296, 0xff00,
+ 0x01c0, 0x7030, 0xd08c, 0x0904, 0x2697, 0x7038, 0xd08c, 0x1140,
+ 0x2001, 0x180c, 0x200c, 0xd1ac, 0x1904, 0x2697, 0xc1ad, 0x2102,
+ 0x0036, 0x73d8, 0x2011, 0x8013, 0x080c, 0x4be9, 0x003e, 0x0804,
+ 0x2697, 0x7038, 0xd08c, 0x1140, 0x2001, 0x180c, 0x200c, 0xd1ac,
+ 0x1904, 0x2697, 0xc1ad, 0x2102, 0x0036, 0x73d8, 0x2011, 0x8013,
+ 0x080c, 0x4be9, 0x003e, 0x7130, 0xc185, 0x7132, 0x2011, 0x1848,
+ 0x220c, 0xd1a4, 0x01f0, 0x0016, 0x2009, 0x0001, 0x2011, 0x0100,
+ 0x080c, 0x891c, 0x2019, 0x000e, 0x00c6, 0x2061, 0x0000, 0x080c,
+ 0xe915, 0x00ce, 0x9484, 0x00ff, 0x9080, 0x33ac, 0x200d, 0x918c,
+ 0xff00, 0x810f, 0x2120, 0x9006, 0x2009, 0x000e, 0x080c, 0xe9a5,
+ 0x001e, 0x0016, 0x2009, 0x0002, 0x2019, 0x0004, 0x080c, 0x3211,
+ 0x001e, 0x00a8, 0x0156, 0x00b6, 0x20a9, 0x007f, 0x900e, 0x080c,
+ 0x671d, 0x1140, 0x7030, 0xd084, 0x1118, 0xb800, 0xd0bc, 0x1110,
+ 0x080c, 0x6141, 0x8108, 0x1f04, 0x2687, 0x00be, 0x015e, 0x00ce,
+ 0x004e, 0x080c, 0xb072, 0x60e3, 0x0000, 0x001e, 0x2001, 0x1800,
+ 0x2014, 0x9296, 0x0004, 0x1170, 0xd19c, 0x11a0, 0x2011, 0x180c,
+ 0x2214, 0xd29c, 0x1120, 0x6204, 0x9295, 0x0002, 0x6206, 0x6228,
+ 0xc29d, 0x622a, 0x2003, 0x0001, 0x2001, 0x1826, 0x2003, 0x0000,
+ 0x6027, 0x0020, 0xd194, 0x0904, 0x27a5, 0x0016, 0x6220, 0xd2b4,
+ 0x0904, 0x2742, 0x080c, 0x878f, 0x080c, 0xa517, 0x6027, 0x0004,
+ 0x00f6, 0x2019, 0x19f2, 0x2304, 0x907d, 0x0904, 0x2711, 0x7804,
+ 0x9086, 0x0032, 0x15f0, 0x00d6, 0x00c6, 0x00e6, 0x0096, 0x2069,
+ 0x0140, 0x782c, 0x685e, 0x7808, 0x685a, 0x6043, 0x0002, 0x2001,
+ 0x0003, 0x8001, 0x1df0, 0x6043, 0x0000, 0x2001, 0x003c, 0x8001,
+ 0x1df0, 0x080c, 0x2d62, 0x2001, 0x001e, 0x8001, 0x0240, 0x20a9,
+ 0x0009, 0x080c, 0x2c5b, 0x6904, 0xd1dc, 0x1140, 0x0cb0, 0x2001,
+ 0x0100, 0x080c, 0x2d52, 0x9006, 0x080c, 0x2d52, 0x080c, 0x97e1,
+ 0x080c, 0x98ed, 0x7814, 0x2048, 0xa867, 0x0103, 0x2f60, 0x080c,
+ 0xb101, 0x009e, 0x00ee, 0x00ce, 0x00de, 0x00fe, 0x001e, 0x00ae,
+ 0x0005, 0x00fe, 0x00d6, 0x2069, 0x0140, 0x6804, 0x9084, 0x4000,
+ 0x0110, 0x080c, 0x2d62, 0x00de, 0x00c6, 0x2061, 0x19e9, 0x6028,
+ 0x080c, 0xd561, 0x0120, 0x909a, 0x0003, 0x1258, 0x0018, 0x909a,
+ 0x00c8, 0x1238, 0x8000, 0x602a, 0x00ce, 0x080c, 0xa4f3, 0x0804,
+ 0x27a4, 0x2061, 0x0100, 0x62c0, 0x080c, 0xaef8, 0x2019, 0x19f2,
+ 0x2304, 0x9065, 0x0120, 0x2009, 0x0027, 0x080c, 0xb180, 0x00ce,
+ 0x0804, 0x27a4, 0xd2bc, 0x0904, 0x278b, 0x080c, 0x879c, 0x6014,
+ 0x9084, 0x1984, 0x9085, 0x0010, 0x6016, 0x6027, 0x0004, 0x00d6,
+ 0x2069, 0x0140, 0x6804, 0x9084, 0x4000, 0x0110, 0x080c, 0x2d62,
+ 0x00de, 0x00c6, 0x2061, 0x19e9, 0x6044, 0x080c, 0xd561, 0x0120,
+ 0x909a, 0x0003, 0x1658, 0x0018, 0x909a, 0x00c8, 0x1638, 0x8000,
+ 0x6046, 0x603c, 0x00ce, 0x9005, 0x05b8, 0x2009, 0x07d0, 0x080c,
+ 0x8794, 0x9080, 0x0008, 0x2004, 0x9086, 0x0006, 0x1138, 0x6114,
+ 0x918c, 0x1984, 0x918d, 0x0012, 0x6116, 0x0430, 0x9080, 0x0008,
+ 0x2004, 0x9086, 0x0009, 0x0d98, 0x6114, 0x918c, 0x1984, 0x918d,
+ 0x0016, 0x6116, 0x00c8, 0x6027, 0x0004, 0x00b0, 0x0036, 0x2019,
+ 0x0001, 0x080c, 0xa877, 0x003e, 0x2019, 0x19f8, 0x2304, 0x9065,
+ 0x0150, 0x2009, 0x004f, 0x6020, 0x9086, 0x0009, 0x1110, 0x2009,
+ 0x004f, 0x080c, 0xb180, 0x00ce, 0x001e, 0xd19c, 0x0904, 0x27fd,
+ 0x7038, 0xd0ac, 0x1538, 0x0016, 0x0156, 0x6027, 0x0008, 0x080c,
+ 0x2d8c, 0x20a9, 0x0028, 0xa001, 0x1f04, 0x27b3, 0x6150, 0x9185,
+ 0x1400, 0x6052, 0x20a9, 0x0366, 0x1d04, 0x27bc, 0x080c, 0x87c3,
+ 0x6020, 0xd09c, 0x1130, 0x015e, 0x6152, 0x001e, 0x6027, 0x0008,
+ 0x04a0, 0x080c, 0x2c42, 0x1f04, 0x27bc, 0x015e, 0x6152, 0x001e,
+ 0x6027, 0x0008, 0x0016, 0x6028, 0xc09c, 0x602a, 0x080c, 0xb072,
+ 0x60e3, 0x0000, 0x080c, 0xedfa, 0x080c, 0xee15, 0x080c, 0x57d7,
+ 0xd0fc, 0x1138, 0x080c, 0xd55a, 0x1120, 0x9085, 0x0001, 0x080c,
+ 0x75ad, 0x9006, 0x080c, 0x2d52, 0x2009, 0x0002, 0x080c, 0x2c80,
+ 0x00e6, 0x2071, 0x1800, 0x7003, 0x0004, 0x080c, 0x0ea3, 0x00ee,
+ 0x6027, 0x0008, 0x080c, 0x0ba0, 0x001e, 0x918c, 0xffd0, 0x6126,
+ 0x00ae, 0x0005, 0x0016, 0x2001, 0x188b, 0x200c, 0xd184, 0x001e,
+ 0x0904, 0x25bc, 0x0016, 0x2009, 0x280e, 0x00d0, 0x2001, 0x188b,
+ 0x200c, 0xc184, 0x2102, 0x001e, 0x0c40, 0x0016, 0x2001, 0x188b,
+ 0x200c, 0xd194, 0x001e, 0x0904, 0x25bc, 0x0016, 0x2009, 0x2821,
+ 0x0038, 0x2001, 0x188b, 0x200c, 0xc194, 0x2102, 0x001e, 0x08a8,
+ 0x6028, 0xc0bc, 0x602a, 0x2001, 0x0156, 0x2003, 0xbc91, 0x8000,
+ 0x2003, 0xffff, 0x6043, 0x0001, 0x080c, 0x2c7a, 0x6027, 0x0080,
+ 0x6017, 0x0000, 0x6043, 0x0000, 0x0817, 0x0006, 0x0016, 0x0026,
+ 0x0036, 0x00e6, 0x00f6, 0x0126, 0x2091, 0x8000, 0x2071, 0x1800,
+ 0x71d0, 0x70d2, 0x9116, 0x0904, 0x288c, 0x81ff, 0x01a0, 0x2009,
+ 0x0000, 0x080c, 0x2c80, 0x2011, 0x8011, 0x2019, 0x010e, 0x231c,
+ 0x939e, 0x0007, 0x1118, 0x2019, 0x0001, 0x0010, 0x2019, 0x0000,
+ 0x080c, 0x4be9, 0x0448, 0x2001, 0x19aa, 0x200c, 0x81ff, 0x1140,
+ 0x2001, 0x0109, 0x2004, 0xd0b4, 0x0118, 0x2019, 0x0003, 0x0008,
+ 0x2118, 0x2011, 0x8012, 0x080c, 0x4be9, 0x080c, 0x0ea3, 0x080c,
+ 0x57d7, 0xd0fc, 0x1188, 0x080c, 0xd55a, 0x1170, 0x00c6, 0x080c,
+ 0x2928, 0x080c, 0xa7de, 0x2061, 0x0100, 0x2019, 0x0028, 0x2009,
+ 0x0002, 0x080c, 0x3211, 0x00ce, 0x012e, 0x00fe, 0x00ee, 0x003e,
+ 0x002e, 0x001e, 0x000e, 0x0005, 0x2028, 0x918c, 0x00ff, 0x2130,
+ 0x9094, 0xff00, 0x11f0, 0x2011, 0x1837, 0x2214, 0xd2ac, 0x11c8,
+ 0x81ff, 0x01e8, 0x2011, 0x181f, 0x2204, 0x9106, 0x1190, 0x2011,
+ 0x1820, 0x2214, 0x9294, 0xff00, 0x9584, 0xff00, 0x9206, 0x1148,
+ 0x2011, 0x1820, 0x2214, 0x9294, 0x00ff, 0x9584, 0x00ff, 0x9206,
+ 0x1120, 0x2500, 0x080c, 0x8271, 0x0048, 0x9584, 0x00ff, 0x9080,
+ 0x33ac, 0x200d, 0x918c, 0xff00, 0x810f, 0x9006, 0x0005, 0x9080,
+ 0x33ac, 0x200d, 0x918c, 0x00ff, 0x0005, 0x00d6, 0x2069, 0x0140,
+ 0x2001, 0x1818, 0x2003, 0x00ef, 0x20a9, 0x0010, 0x9006, 0x6852,
+ 0x6856, 0x1f04, 0x28d8, 0x00de, 0x0005, 0x0006, 0x00d6, 0x0026,
+ 0x2069, 0x0140, 0x2001, 0x1818, 0x2102, 0x8114, 0x8214, 0x8214,
+ 0x8214, 0x20a9, 0x0010, 0x6853, 0x0000, 0x9006, 0x82ff, 0x1128,
+ 0x9184, 0x000f, 0x9080, 0xf5f7, 0x2005, 0x6856, 0x8211, 0x1f04,
+ 0x28ed, 0x002e, 0x00de, 0x000e, 0x0005, 0x00c6, 0x2061, 0x1800,
+ 0x6030, 0x0110, 0xc09d, 0x0008, 0xc09c, 0x6032, 0x00ce, 0x0005,
+ 0x0156, 0x00d6, 0x0026, 0x0016, 0x0006, 0x2069, 0x0140, 0x6980,
+ 0x9116, 0x0180, 0x9112, 0x1230, 0x8212, 0x8210, 0x22a8, 0x2001,
+ 0x0402, 0x0018, 0x22a8, 0x2001, 0x0404, 0x680e, 0x1f04, 0x291d,
+ 0x680f, 0x0000, 0x000e, 0x001e, 0x002e, 0x00de, 0x015e, 0x0005,
+ 0x080c, 0x57d3, 0xd0c4, 0x0150, 0xd0a4, 0x0140, 0x9006, 0x0046,
+ 0x2020, 0x2009, 0x002e, 0x080c, 0xe9a5, 0x004e, 0x0005, 0x00f6,
+ 0x0016, 0x0026, 0x2079, 0x0140, 0x78c4, 0xd0dc, 0x0904, 0x2994,
+ 0x080c, 0x2bdf, 0x0660, 0x9084, 0x0700, 0x908e, 0x0600, 0x1120,
+ 0x2011, 0x4000, 0x900e, 0x0458, 0x908e, 0x0500, 0x1120, 0x2011,
+ 0x8000, 0x900e, 0x0420, 0x908e, 0x0400, 0x1120, 0x9016, 0x2009,
+ 0x0001, 0x00e8, 0x908e, 0x0300, 0x1120, 0x9016, 0x2009, 0x0002,
+ 0x00b0, 0x908e, 0x0200, 0x1120, 0x9016, 0x2009, 0x0004, 0x0078,
+ 0x908e, 0x0100, 0x1548, 0x9016, 0x2009, 0x0008, 0x0040, 0x9084,
+ 0x0700, 0x908e, 0x0300, 0x1500, 0x2011, 0x0030, 0x0058, 0x2300,
+ 0x9080, 0x0020, 0x2018, 0x080c, 0x91b1, 0x928c, 0xff00, 0x0110,
+ 0x2011, 0x00ff, 0x2200, 0x8007, 0x9085, 0x004c, 0x78c2, 0x2009,
+ 0x0138, 0x220a, 0x080c, 0x7569, 0x1118, 0x2009, 0x196e, 0x220a,
+ 0x002e, 0x001e, 0x00fe, 0x0005, 0x78c3, 0x0000, 0x0cc8, 0x0126,
+ 0x2091, 0x2800, 0x0006, 0x0016, 0x0026, 0x2001, 0x0170, 0x200c,
+ 0x8000, 0x2014, 0x9184, 0x0003, 0x0110, 0x080c, 0x0dbe, 0x002e,
+ 0x001e, 0x000e, 0x012e, 0x0005, 0x2001, 0x0171, 0x2004, 0xd0dc,
+ 0x0168, 0x2001, 0x0170, 0x200c, 0x918c, 0x00ff, 0x918e, 0x004c,
+ 0x1128, 0x200c, 0x918c, 0xff00, 0x810f, 0x0005, 0x900e, 0x2001,
+ 0x0227, 0x2004, 0x8007, 0x9084, 0x00ff, 0x8004, 0x9108, 0x2001,
+ 0x0226, 0x2004, 0x8007, 0x9084, 0x00ff, 0x8004, 0x9108, 0x0005,
+ 0x0018, 0x000c, 0x0018, 0x0020, 0x1000, 0x0800, 0x1000, 0x1800,
+ 0x0156, 0x0006, 0x0016, 0x0026, 0x00e6, 0x2001, 0x1991, 0x2004,
+ 0x908a, 0x0007, 0x1a0c, 0x0dc5, 0x0033, 0x00ee, 0x002e, 0x001e,
+ 0x000e, 0x015e, 0x0005, 0x29f2, 0x2a10, 0x2a34, 0x2a36, 0x2a5f,
+ 0x2a61, 0x2a63, 0x2001, 0x0001, 0x080c, 0x283d, 0x080c, 0x2c3d,
+ 0x2001, 0x1993, 0x2003, 0x0000, 0x7828, 0x9084, 0xe1d7, 0x782a,
+ 0x9006, 0x20a9, 0x0009, 0x080c, 0x2bfb, 0x2001, 0x1991, 0x2003,
+ 0x0006, 0x2009, 0x001e, 0x2011, 0x2a64, 0x080c, 0x87a1, 0x0005,
+ 0x2009, 0x1996, 0x200b, 0x0000, 0x2001, 0x199b, 0x2003, 0x0036,
+ 0x2001, 0x199a, 0x2003, 0x002a, 0x2001, 0x1993, 0x2003, 0x0001,
+ 0x9006, 0x080c, 0x2bad, 0x2001, 0xffff, 0x20a9, 0x0009, 0x080c,
+ 0x2bfb, 0x2001, 0x1991, 0x2003, 0x0006, 0x2009, 0x001e, 0x2011,
+ 0x2a64, 0x080c, 0x87a1, 0x0005, 0x080c, 0x0dc5, 0x2001, 0x199b,
+ 0x2003, 0x0036, 0x2001, 0x1993, 0x2003, 0x0003, 0x7a38, 0x9294,
+ 0x0005, 0x9296, 0x0004, 0x0110, 0x9006, 0x0010, 0x2001, 0x0001,
+ 0x080c, 0x2bad, 0x2001, 0x1997, 0x2003, 0x0000, 0x2001, 0xffff,
+ 0x20a9, 0x0009, 0x080c, 0x2bfb, 0x2001, 0x1991, 0x2003, 0x0006,
+ 0x2009, 0x001e, 0x2011, 0x2a64, 0x080c, 0x87a1, 0x0005, 0x080c,
+ 0x0dc5, 0x080c, 0x0dc5, 0x0005, 0x0006, 0x0016, 0x0026, 0x00e6,
+ 0x00f6, 0x0156, 0x0126, 0x2091, 0x8000, 0x2079, 0x0100, 0x2001,
+ 0x1993, 0x2004, 0x908a, 0x0007, 0x1a0c, 0x0dc5, 0x0043, 0x012e,
+ 0x015e, 0x00fe, 0x00ee, 0x002e, 0x001e, 0x000e, 0x0005, 0x2a86,
+ 0x2aa2, 0x2ade, 0x2b0a, 0x2b2a, 0x2b36, 0x2b38, 0x080c, 0x2bef,
+ 0x1190, 0x2009, 0x1999, 0x2104, 0x7a38, 0x9294, 0x0005, 0x9296,
+ 0x0004, 0x0110, 0xc08d, 0x0008, 0xc085, 0x200a, 0x2001, 0x1991,
+ 0x2003, 0x0001, 0x0030, 0x080c, 0x2b5c, 0x2001, 0xffff, 0x080c,
+ 0x2a01, 0x0005, 0x080c, 0x2b3a, 0x05c0, 0x2009, 0x199a, 0x2104,
+ 0x8001, 0x200a, 0x080c, 0x2bef, 0x1158, 0x7a38, 0x9294, 0x0005,
+ 0x9296, 0x0005, 0x0518, 0x2009, 0x1999, 0x2104, 0xc085, 0x200a,
+ 0x2009, 0x1996, 0x2104, 0x8000, 0x200a, 0x9086, 0x0005, 0x0118,
+ 0x080c, 0x2b42, 0x00c0, 0x200b, 0x0000, 0x7a38, 0x9294, 0x0006,
+ 0x9296, 0x0004, 0x0110, 0x9006, 0x0010, 0x2001, 0x0001, 0x080c,
+ 0x2bca, 0x2001, 0x1993, 0x2003, 0x0002, 0x0028, 0x2001, 0x1991,
+ 0x2003, 0x0003, 0x0010, 0x080c, 0x2a23, 0x0005, 0x080c, 0x2b3a,
+ 0x0540, 0x2009, 0x199a, 0x2104, 0x8001, 0x200a, 0x080c, 0x2bef,
+ 0x1148, 0x2001, 0x1991, 0x2003, 0x0003, 0x2001, 0x1992, 0x2003,
+ 0x0000, 0x00b8, 0x2009, 0x199a, 0x2104, 0x9005, 0x1118, 0x080c,
+ 0x2b7f, 0x0010, 0x080c, 0x2b4f, 0x080c, 0x2b42, 0x2009, 0x1996,
+ 0x200b, 0x0000, 0x2001, 0x1993, 0x2003, 0x0001, 0x080c, 0x2a23,
+ 0x0000, 0x0005, 0x0479, 0x01e8, 0x080c, 0x2bef, 0x1198, 0x2009,
+ 0x1997, 0x2104, 0x8000, 0x200a, 0x9086, 0x0007, 0x0108, 0x0078,
+ 0x2001, 0x199c, 0x2003, 0x000a, 0x2009, 0x1999, 0x2104, 0xc0fd,
+ 0x200a, 0x0038, 0x00f9, 0x2001, 0x1993, 0x2003, 0x0004, 0x080c,
+ 0x2a4e, 0x0005, 0x0079, 0x0148, 0x080c, 0x2bef, 0x1118, 0x080c,
+ 0x2a3a, 0x0018, 0x0079, 0x080c, 0x2a4e, 0x0005, 0x080c, 0x0dc5,
+ 0x080c, 0x0dc5, 0x2009, 0x199b, 0x2104, 0x8001, 0x200a, 0x090c,
+ 0x2b9b, 0x0005, 0x7a38, 0x9294, 0x0005, 0x9296, 0x0005, 0x0110,
+ 0x9006, 0x0010, 0x2001, 0x0001, 0x080c, 0x2bca, 0x0005, 0x7a38,
+ 0x9294, 0x0006, 0x9296, 0x0006, 0x0110, 0x9006, 0x0010, 0x2001,
+ 0x0001, 0x080c, 0x2bad, 0x0005, 0x2009, 0x1996, 0x2104, 0x8000,
+ 0x200a, 0x9086, 0x0005, 0x0108, 0x0068, 0x200b, 0x0000, 0x7a38,
+ 0x9294, 0x0006, 0x9296, 0x0006, 0x0110, 0x9006, 0x0010, 0x2001,
+ 0x0001, 0x04d9, 0x7a38, 0x9294, 0x0005, 0x9296, 0x0005, 0x0110,
+ 0x9006, 0x0010, 0x2001, 0x0001, 0x080c, 0x2bca, 0x0005, 0x0086,
+ 0x2001, 0x1999, 0x2004, 0x9084, 0x7fff, 0x090c, 0x0dc5, 0x2009,
+ 0x1998, 0x2144, 0x8846, 0x280a, 0x9844, 0x0dd8, 0xd08c, 0x1120,
+ 0xd084, 0x1120, 0x080c, 0x0dc5, 0x9006, 0x0010, 0x2001, 0x0001,
+ 0x00a1, 0x008e, 0x0005, 0x0006, 0x0156, 0x2001, 0x1991, 0x20a9,
+ 0x0009, 0x2003, 0x0000, 0x8000, 0x1f04, 0x2ba1, 0x2001, 0x1998,
+ 0x2003, 0x8000, 0x015e, 0x000e, 0x0005, 0x00f6, 0x2079, 0x0100,
+ 0x9085, 0x0000, 0x0158, 0x7838, 0x9084, 0xfff9, 0x9085, 0x0004,
+ 0x783a, 0x2009, 0x199e, 0x210c, 0x795a, 0x0050, 0x7838, 0x9084,
+ 0xfffb, 0x9085, 0x0006, 0x783a, 0x2009, 0x199f, 0x210c, 0x795a,
+ 0x00fe, 0x0005, 0x00f6, 0x2079, 0x0100, 0x9085, 0x0000, 0x0138,
+ 0x7838, 0x9084, 0xfffa, 0x9085, 0x0004, 0x783a, 0x0030, 0x7838,
+ 0x9084, 0xfffb, 0x9085, 0x0005, 0x783a, 0x00fe, 0x0005, 0x0006,
+ 0x2001, 0x0100, 0x2004, 0x9082, 0x0007, 0x000e, 0x0005, 0x0006,
+ 0x2001, 0x0100, 0x2004, 0x9082, 0x0009, 0x000e, 0x0005, 0x0156,
+ 0x20a9, 0x0064, 0x7820, 0x080c, 0x2c7a, 0xd09c, 0x1110, 0x1f04,
+ 0x2bf2, 0x015e, 0x0005, 0x0126, 0x0016, 0x0006, 0x2091, 0x8000,
+ 0x7850, 0x9085, 0x0040, 0x7852, 0x7850, 0x9084, 0xfbcf, 0x7852,
+ 0x080c, 0x2c7a, 0x9085, 0x2000, 0x7852, 0x000e, 0x2008, 0x9186,
+ 0x0000, 0x1118, 0x783b, 0x0007, 0x0090, 0x9186, 0x0001, 0x1118,
+ 0x783b, 0x0006, 0x0060, 0x9186, 0x0002, 0x1118, 0x783b, 0x0005,
+ 0x0030, 0x9186, 0x0003, 0x1118, 0x783b, 0x0004, 0x0000, 0x0006,
+ 0x1d04, 0x2c28, 0x080c, 0x87c3, 0x1f04, 0x2c28, 0x7850, 0x9085,
+ 0x0400, 0x9084, 0xdfbf, 0x7852, 0x080c, 0x2c7a, 0x9085, 0x1000,
+ 0x7852, 0x000e, 0x001e, 0x012e, 0x0005, 0x7850, 0x9084, 0xffcf,
+ 0x7852, 0x0005, 0x0006, 0x0156, 0x00f6, 0x2079, 0x0100, 0x20a9,
+ 0x000a, 0x7854, 0xd0ac, 0x1130, 0x7820, 0xd0e4, 0x1140, 0x1f04,
+ 0x2c4c, 0x0028, 0x7854, 0xd08c, 0x1110, 0x1f04, 0x2c52, 0x00fe,
+ 0x015e, 0x000e, 0x0005, 0x1d04, 0x2c5b, 0x080c, 0x87c3, 0x1f04,
+ 0x2c5b, 0x0005, 0x0006, 0x2001, 0x199d, 0x2004, 0x9086, 0x0000,
+ 0x000e, 0x0005, 0x0006, 0x2001, 0x199d, 0x2004, 0x9086, 0x0001,
+ 0x000e, 0x0005, 0x0006, 0x2001, 0x199d, 0x2004, 0x9086, 0x0002,
+ 0x000e, 0x0005, 0xa001, 0xa001, 0xa001, 0xa001, 0xa001, 0x0005,
+ 0x0006, 0x2001, 0x19aa, 0x2102, 0x000e, 0x0005, 0x2009, 0x0171,
+ 0x2104, 0xd0dc, 0x0140, 0x2009, 0x0170, 0x2104, 0x200b, 0x0080,
+ 0xa001, 0xa001, 0x200a, 0x0005, 0x0036, 0x0046, 0x2001, 0x0141,
+ 0x200c, 0x918c, 0xff00, 0x9186, 0x2100, 0x0140, 0x9186, 0x2000,
+ 0x0170, 0x9186, 0x0100, 0x1904, 0x2cf3, 0x0048, 0x0016, 0x2009,
+ 0x1a88, 0x2104, 0x8000, 0x0208, 0x200a, 0x001e, 0x04f0, 0x2009,
+ 0x00a2, 0x080c, 0x0e52, 0x2019, 0x0160, 0x2324, 0x2011, 0x0003,
+ 0x2009, 0x0169, 0x2104, 0x9084, 0x0007, 0x210c, 0x918c, 0x0007,
+ 0x910e, 0x1db0, 0x9086, 0x0003, 0x1548, 0x2304, 0x0066, 0x0076,
+ 0x2031, 0x0002, 0x233c, 0x973e, 0x0148, 0x8631, 0x1dd8, 0x2031,
+ 0x1a89, 0x263c, 0x8738, 0x0208, 0x2732, 0x2304, 0x007e, 0x006e,
+ 0x9402, 0x02a0, 0x19d0, 0x8211, 0x19d8, 0x84ff, 0x0170, 0x2001,
+ 0x0141, 0x200c, 0x918c, 0xff00, 0x9186, 0x0100, 0x0130, 0x2009,
+ 0x180c, 0x2104, 0xc0dd, 0x200a, 0x0008, 0x0421, 0x2001, 0x1982,
+ 0x200c, 0x080c, 0x0e52, 0x004e, 0x003e, 0x0005, 0x2001, 0x180c,
+ 0x2004, 0xd0dc, 0x01b0, 0x2001, 0x0160, 0x2004, 0x9005, 0x0140,
+ 0x2001, 0x0141, 0x2004, 0x9084, 0xff00, 0x9086, 0x0100, 0x1148,
+ 0x0126, 0x2091, 0x8000, 0x0016, 0x0026, 0x0021, 0x002e, 0x001e,
+ 0x012e, 0x0005, 0x00c6, 0x2061, 0x0100, 0x6014, 0x0006, 0x2001,
+ 0x0161, 0x2003, 0x0000, 0x6017, 0x0018, 0xa001, 0xa001, 0x602f,
+ 0x0008, 0x6104, 0x918e, 0x0010, 0x6106, 0x918e, 0x0010, 0x6106,
+ 0x6017, 0x0040, 0x04b9, 0x001e, 0x9184, 0x0003, 0x01e0, 0x0036,
+ 0x0016, 0x2019, 0x0141, 0x6124, 0x918c, 0x0028, 0x1120, 0x2304,
+ 0x9084, 0x2800, 0x0dc0, 0x001e, 0x919c, 0xffe4, 0x9184, 0x0001,
+ 0x0118, 0x9385, 0x0009, 0x6016, 0x9184, 0x0002, 0x0118, 0x9385,
+ 0x0012, 0x6016, 0x003e, 0x2001, 0x180c, 0x200c, 0xc1dc, 0x2102,
+ 0x00ce, 0x0005, 0x0016, 0x0026, 0x080c, 0x7583, 0x0108, 0xc0bc,
+ 0x2009, 0x0140, 0x2114, 0x9294, 0x0001, 0x9215, 0x220a, 0x002e,
+ 0x001e, 0x0005, 0x0016, 0x0026, 0x2009, 0x0140, 0x2114, 0x9294,
+ 0x0001, 0x9285, 0x1000, 0x200a, 0x220a, 0x002e, 0x001e, 0x0005,
+ 0x0016, 0x0026, 0x2009, 0x0140, 0x2114, 0x9294, 0x0001, 0x9215,
+ 0x220a, 0x002e, 0x001e, 0x0005, 0x0006, 0x0016, 0x2009, 0x0140,
+ 0x2104, 0x1128, 0x080c, 0x7583, 0x0110, 0xc0bc, 0x0008, 0xc0bd,
+ 0x200a, 0x001e, 0x000e, 0x0005, 0x0006, 0x0156, 0x6050, 0x9085,
+ 0x0040, 0x6052, 0x6050, 0x9084, 0xfbcf, 0x6052, 0x080c, 0x2c7a,
+ 0x9085, 0x2000, 0x6052, 0x20a9, 0x0012, 0x1d04, 0x2d9d, 0x080c,
+ 0x87c3, 0x1f04, 0x2d9d, 0x6050, 0x9085, 0x0400, 0x9084, 0xdfbf,
+ 0x6052, 0x015e, 0x000e, 0x0005, 0x3018, 0x3018, 0x2e3c, 0x2e3c,
+ 0x2e48, 0x2e48, 0x2e54, 0x2e54, 0x2e62, 0x2e62, 0x2e6e, 0x2e6e,
+ 0x2e7c, 0x2e7c, 0x2e8a, 0x2e8a, 0x2e9c, 0x2e9c, 0x2ea8, 0x2ea8,
+ 0x2eb6, 0x2eb6, 0x2ed4, 0x2ed4, 0x2ef4, 0x2ef4, 0x2ec4, 0x2ec4,
+ 0x2ee4, 0x2ee4, 0x2f02, 0x2f02, 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a,
+ 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a,
+ 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a,
+ 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a,
+ 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, 0x2f14, 0x2f14, 0x2f20, 0x2f20,
+ 0x2f2e, 0x2f2e, 0x2f3c, 0x2f3c, 0x2f4c, 0x2f4c, 0x2f5a, 0x2f5a,
+ 0x2f6a, 0x2f6a, 0x2f7a, 0x2f7a, 0x2f8c, 0x2f8c, 0x2f9a, 0x2f9a,
+ 0x2faa, 0x2faa, 0x2fcc, 0x2fcc, 0x2fee, 0x2fee, 0x2fba, 0x2fba,
+ 0x2fdd, 0x2fdd, 0x2ffd, 0x2ffd, 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a,
+ 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a,
+ 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a,
+ 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a,
+ 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a,
+ 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a,
+ 0x2e9a, 0x2e9a, 0x2e9a, 0x2e9a, 0x0106, 0x0006, 0x0126, 0x01c6,
+ 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x24e1, 0x0804, 0x3010,
+ 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156,
+ 0x080c, 0x22f5, 0x0804, 0x3010, 0x0106, 0x0006, 0x0126, 0x01c6,
+ 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x22f5, 0x080c, 0x24e1,
+ 0x0804, 0x3010, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136,
+ 0x0146, 0x0156, 0x080c, 0x2330, 0x0804, 0x3010, 0x0106, 0x0006,
+ 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x24e1,
+ 0x080c, 0x2330, 0x0804, 0x3010, 0x0106, 0x0006, 0x0126, 0x01c6,
+ 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x22f5, 0x080c, 0x2330,
+ 0x0804, 0x3010, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136,
+ 0x0146, 0x0156, 0x080c, 0x22f5, 0x080c, 0x24e1, 0x080c, 0x2330,
+ 0x0804, 0x3010, 0xa001, 0x0cf0, 0x0106, 0x0006, 0x0126, 0x01c6,
+ 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x1394, 0x0804, 0x3010,
+ 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156,
+ 0x080c, 0x24e1, 0x080c, 0x1394, 0x0804, 0x3010, 0x0106, 0x0006,
+ 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x22f5,
+ 0x080c, 0x1394, 0x0804, 0x3010, 0x0106, 0x0006, 0x0126, 0x01c6,
+ 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x24e1, 0x080c, 0x1394,
+ 0x080c, 0x2330, 0x0804, 0x3010, 0x0106, 0x0006, 0x0126, 0x01c6,
+ 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x22f5, 0x080c, 0x24e1,
+ 0x080c, 0x1394, 0x0804, 0x3010, 0x0106, 0x0006, 0x0126, 0x01c6,
+ 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x22f5, 0x080c, 0x1394,
+ 0x080c, 0x2330, 0x0804, 0x3010, 0x0106, 0x0006, 0x0126, 0x01c6,
+ 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x1394, 0x080c, 0x2330,
+ 0x0804, 0x3010, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136,
+ 0x0146, 0x0156, 0x080c, 0x22f5, 0x080c, 0x24e1, 0x080c, 0x1394,
+ 0x080c, 0x2330, 0x0804, 0x3010, 0x0106, 0x0006, 0x0126, 0x01c6,
+ 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2997, 0x0804, 0x3010,
+ 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156,
+ 0x080c, 0x2997, 0x080c, 0x24e1, 0x0804, 0x3010, 0x0106, 0x0006,
+ 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2997,
+ 0x080c, 0x22f5, 0x0804, 0x3010, 0x0106, 0x0006, 0x0126, 0x01c6,
+ 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2997, 0x080c, 0x22f5,
+ 0x080c, 0x24e1, 0x0804, 0x3010, 0x0106, 0x0006, 0x0126, 0x01c6,
+ 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2997, 0x080c, 0x2330,
+ 0x0804, 0x3010, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136,
+ 0x0146, 0x0156, 0x080c, 0x2997, 0x080c, 0x24e1, 0x080c, 0x2330,
+ 0x0804, 0x3010, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136,
+ 0x0146, 0x0156, 0x080c, 0x2997, 0x080c, 0x22f5, 0x080c, 0x2330,
+ 0x0804, 0x3010, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136,
+ 0x0146, 0x0156, 0x080c, 0x2997, 0x080c, 0x22f5, 0x080c, 0x24e1,
+ 0x080c, 0x2330, 0x0804, 0x3010, 0x0106, 0x0006, 0x0126, 0x01c6,
+ 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2997, 0x080c, 0x1394,
+ 0x0804, 0x3010, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136,
+ 0x0146, 0x0156, 0x080c, 0x2997, 0x080c, 0x24e1, 0x080c, 0x1394,
+ 0x0804, 0x3010, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136,
+ 0x0146, 0x0156, 0x080c, 0x2997, 0x080c, 0x22f5, 0x080c, 0x1394,
+ 0x0804, 0x3010, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136,
+ 0x0146, 0x0156, 0x080c, 0x2997, 0x080c, 0x24e1, 0x080c, 0x1394,
+ 0x080c, 0x2330, 0x0804, 0x3010, 0x0106, 0x0006, 0x0126, 0x01c6,
+ 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2997, 0x080c, 0x22f5,
+ 0x080c, 0x24e1, 0x080c, 0x1394, 0x0498, 0x0106, 0x0006, 0x0126,
+ 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2997, 0x080c,
+ 0x22f5, 0x080c, 0x1394, 0x080c, 0x2330, 0x0410, 0x0106, 0x0006,
+ 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2997,
+ 0x080c, 0x1394, 0x080c, 0x2330, 0x0098, 0x0106, 0x0006, 0x0126,
+ 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2997, 0x080c,
+ 0x22f5, 0x080c, 0x24e1, 0x080c, 0x1394, 0x080c, 0x2330, 0x0000,
+ 0x015e, 0x014e, 0x013e, 0x01de, 0x01ce, 0x012e, 0x000e, 0x010e,
+ 0x000d, 0x00b6, 0x00c6, 0x0026, 0x0046, 0x9026, 0x080c, 0x6a50,
+ 0x1904, 0x312d, 0x72dc, 0x2001, 0x197d, 0x2004, 0x9005, 0x1110,
+ 0xd29c, 0x0148, 0xd284, 0x1138, 0xd2bc, 0x1904, 0x312d, 0x080c,
+ 0x3132, 0x0804, 0x312d, 0xd2cc, 0x1904, 0x312d, 0x080c, 0x7569,
+ 0x1120, 0x70af, 0xffff, 0x0804, 0x312d, 0xd294, 0x0120, 0x70af,
+ 0xffff, 0x0804, 0x312d, 0x080c, 0x339b, 0x0160, 0x080c, 0xd561,
+ 0x0128, 0x2001, 0x1818, 0x203c, 0x0804, 0x30b6, 0x70af, 0xffff,
+ 0x0804, 0x312d, 0x2001, 0x1818, 0x203c, 0x7294, 0xd284, 0x0904,
+ 0x30b6, 0xd28c, 0x1904, 0x30b6, 0x0036, 0x73ac, 0x938e, 0xffff,
+ 0x1110, 0x2019, 0x0001, 0x8314, 0x92e0, 0x1c80, 0x2c04, 0x938c,
+ 0x0001, 0x0120, 0x9084, 0xff00, 0x8007, 0x0010, 0x9084, 0x00ff,
+ 0x970e, 0x05d0, 0x908e, 0x0000, 0x05b8, 0x908e, 0x00ff, 0x1150,
+ 0x7230, 0xd284, 0x15b0, 0x7294, 0xc28d, 0x7296, 0x70af, 0xffff,
+ 0x003e, 0x04a0, 0x900e, 0x080c, 0x2894, 0x080c, 0x66b2, 0x1538,
+ 0x9006, 0xb8bb, 0x0520, 0xb8ac, 0x9005, 0x0148, 0x00c6, 0x2060,
+ 0x080c, 0x8bc3, 0x00ce, 0x090c, 0x8f64, 0xb8af, 0x0000, 0x080c,
+ 0x6a92, 0x1168, 0x7030, 0xd08c, 0x0130, 0xb800, 0xd0bc, 0x0138,
+ 0x080c, 0x693d, 0x0120, 0x080c, 0x314b, 0x0148, 0x0028, 0x080c,
+ 0x328b, 0x080c, 0x3177, 0x0118, 0x8318, 0x0804, 0x3063, 0x73ae,
+ 0x0010, 0x70af, 0xffff, 0x003e, 0x0804, 0x312d, 0x9780, 0x33ac,
+ 0x203d, 0x97bc, 0xff00, 0x873f, 0x2041, 0x007e, 0x70ac, 0x9096,
+ 0xffff, 0x1118, 0x900e, 0x28a8, 0x0050, 0x9812, 0x0220, 0x2008,
+ 0x9802, 0x20a8, 0x0020, 0x70af, 0xffff, 0x0804, 0x312d, 0x2700,
+ 0x0156, 0x0016, 0x9106, 0x0904, 0x3122, 0xc484, 0x080c, 0x671d,
+ 0x0168, 0x080c, 0xd561, 0x1904, 0x3122, 0x080c, 0x339b, 0x1904,
+ 0x3122, 0x080c, 0x66b2, 0x1904, 0x312a, 0x0008, 0xc485, 0xb8bb,
+ 0x0520, 0xb8ac, 0x9005, 0x0148, 0x00c6, 0x2060, 0x080c, 0x8bc3,
+ 0x00ce, 0x090c, 0x8f64, 0xb8af, 0x0000, 0x080c, 0x6a92, 0x1130,
+ 0x7030, 0xd08c, 0x01f8, 0xb800, 0xd0bc, 0x11e0, 0x7294, 0xd28c,
+ 0x0180, 0x080c, 0x6a92, 0x9082, 0x0006, 0x02e0, 0xd484, 0x1118,
+ 0x080c, 0x66d7, 0x0028, 0x080c, 0x3317, 0x01a0, 0x080c, 0x3342,
+ 0x0088, 0x080c, 0x328b, 0x080c, 0xd561, 0x1160, 0x080c, 0x3177,
+ 0x0188, 0x0040, 0x080c, 0xd561, 0x1118, 0x080c, 0x3317, 0x0110,
+ 0x0451, 0x0140, 0x001e, 0x8108, 0x015e, 0x1f04, 0x30cf, 0x70af,
+ 0xffff, 0x0018, 0x001e, 0x015e, 0x71ae, 0x004e, 0x002e, 0x00ce,
+ 0x00be, 0x0005, 0x00c6, 0x0016, 0x70af, 0x0001, 0x2009, 0x007e,
+ 0x080c, 0x66b2, 0x1168, 0xb813, 0x00ff, 0xb817, 0xfffe, 0x080c,
+ 0x328b, 0x04a9, 0x0128, 0x70dc, 0xc0bd, 0x70de, 0x080c, 0xd2a9,
+ 0x001e, 0x00ce, 0x0005, 0x0016, 0x0076, 0x00d6, 0x00c6, 0x2001,
+ 0x184c, 0x2004, 0x9084, 0x00ff, 0xb842, 0x080c, 0xb153, 0x01d0,
+ 0x2b00, 0x6012, 0x080c, 0xd2d2, 0x6023, 0x0001, 0x9006, 0x080c,
+ 0x664f, 0x2001, 0x0000, 0x080c, 0x6663, 0x0126, 0x2091, 0x8000,
+ 0x70a8, 0x8000, 0x70aa, 0x012e, 0x2009, 0x0004, 0x080c, 0xb180,
+ 0x9085, 0x0001, 0x00ce, 0x00de, 0x007e, 0x001e, 0x0005, 0x0016,
+ 0x0076, 0x00d6, 0x00c6, 0x2001, 0x184c, 0x2004, 0x9084, 0x00ff,
+ 0xb842, 0x080c, 0xb153, 0x0548, 0x2b00, 0x6012, 0xb800, 0xc0c4,
+ 0xb802, 0xb8a0, 0x9086, 0x007e, 0x0140, 0xb804, 0x9084, 0x00ff,
+ 0x9086, 0x0006, 0x1110, 0x080c, 0x3246, 0x080c, 0xd2d2, 0x6023,
+ 0x0001, 0x9006, 0x080c, 0x664f, 0x2001, 0x0002, 0x080c, 0x6663,
+ 0x0126, 0x2091, 0x8000, 0x70a8, 0x8000, 0x70aa, 0x012e, 0x2009,
+ 0x0002, 0x080c, 0xb180, 0x9085, 0x0001, 0x00ce, 0x00de, 0x007e,
+ 0x001e, 0x0005, 0x00b6, 0x00c6, 0x0026, 0x2009, 0x0080, 0x080c,
+ 0x66b2, 0x1140, 0xb813, 0x00ff, 0xb817, 0xfffc, 0x0039, 0x0110,
+ 0x70e3, 0xffff, 0x002e, 0x00ce, 0x00be, 0x0005, 0x0016, 0x0076,
+ 0x00d6, 0x00c6, 0x080c, 0xb0ab, 0x01d0, 0x2b00, 0x6012, 0x080c,
+ 0xd2d2, 0x6023, 0x0001, 0x9006, 0x080c, 0x664f, 0x2001, 0x0002,
+ 0x080c, 0x6663, 0x0126, 0x2091, 0x8000, 0x70e4, 0x8000, 0x70e6,
+ 0x012e, 0x2009, 0x0002, 0x080c, 0xb180, 0x9085, 0x0001, 0x00ce,
+ 0x00de, 0x007e, 0x001e, 0x0005, 0x00c6, 0x00d6, 0x0126, 0x2091,
+ 0x8000, 0x2009, 0x007f, 0x080c, 0x66b2, 0x11b8, 0xb813, 0x00ff,
+ 0xb817, 0xfffd, 0xb8cf, 0x0004, 0x080c, 0xb0ab, 0x0170, 0x2b00,
+ 0x6012, 0x6316, 0x6023, 0x0001, 0x620a, 0x080c, 0xd2d2, 0x2009,
+ 0x0022, 0x080c, 0xb180, 0x9085, 0x0001, 0x012e, 0x00de, 0x00ce,
+ 0x0005, 0x00e6, 0x00c6, 0x0066, 0x0036, 0x0026, 0x00b6, 0x21f0,
+ 0x080c, 0x94eb, 0x080c, 0x946b, 0x080c, 0xaf3f, 0x080c, 0xc051,
+ 0x3e08, 0x2130, 0x81ff, 0x0120, 0x20a9, 0x007e, 0x900e, 0x0018,
+ 0x20a9, 0x007f, 0x900e, 0x0016, 0x080c, 0x671d, 0x1140, 0x9686,
+ 0x0002, 0x1118, 0xb800, 0xd0bc, 0x1110, 0x080c, 0x6141, 0x001e,
+ 0x8108, 0x1f04, 0x322b, 0x9686, 0x0001, 0x190c, 0x336f, 0x00be,
+ 0x002e, 0x003e, 0x006e, 0x00ce, 0x00ee, 0x0005, 0x00e6, 0x00c6,
+ 0x0046, 0x0036, 0x0026, 0x0016, 0x00b6, 0x6210, 0x2258, 0xbaa0,
+ 0x0026, 0x2019, 0x0029, 0x080c, 0x94e0, 0x0076, 0x2039, 0x0000,
+ 0x080c, 0x93b3, 0x2c08, 0x080c, 0xe690, 0x007e, 0x001e, 0xba10,
+ 0xbb14, 0xbcc0, 0x080c, 0x6141, 0xba12, 0xbb16, 0xbcc2, 0x00be,
+ 0x001e, 0x002e, 0x003e, 0x004e, 0x00ce, 0x00ee, 0x0005, 0x00e6,
+ 0x0006, 0x00b6, 0x6010, 0x2058, 0xb8a0, 0x00be, 0x9086, 0x0080,
+ 0x0150, 0x2071, 0x1800, 0x70a8, 0x9005, 0x0110, 0x8001, 0x70aa,
+ 0x000e, 0x00ee, 0x0005, 0x2071, 0x1800, 0x70e4, 0x9005, 0x0dc0,
+ 0x8001, 0x70e6, 0x0ca8, 0xb800, 0xc08c, 0xb802, 0x0005, 0x00f6,
+ 0x00e6, 0x00c6, 0x00b6, 0x0046, 0x0036, 0x0026, 0x0016, 0x0156,
+ 0x2178, 0x81ff, 0x1118, 0x20a9, 0x0001, 0x0078, 0x080c, 0x57d3,
+ 0xd0c4, 0x0140, 0xd0a4, 0x0130, 0x9006, 0x2020, 0x2009, 0x002d,
+ 0x080c, 0xe9a5, 0x20a9, 0x0800, 0x9016, 0x0026, 0x928e, 0x007e,
+ 0x0904, 0x32f6, 0x928e, 0x007f, 0x0904, 0x32f6, 0x928e, 0x0080,
+ 0x05e8, 0x9288, 0x1000, 0x210c, 0x81ff, 0x05c0, 0x8fff, 0x1148,
+ 0x2001, 0x198f, 0x0006, 0x2003, 0x0001, 0x04f1, 0x000e, 0x2003,
+ 0x0000, 0x00b6, 0x00c6, 0x2158, 0x2001, 0x0001, 0x080c, 0x6a5c,
+ 0x00ce, 0x00be, 0x2019, 0x0029, 0x080c, 0x94e0, 0x0076, 0x2039,
+ 0x0000, 0x080c, 0x93b3, 0x00b6, 0x00c6, 0x0026, 0x2158, 0xba04,
+ 0x9294, 0x00ff, 0x9286, 0x0006, 0x1118, 0xb807, 0x0404, 0x0028,
+ 0x2001, 0x0004, 0x8007, 0x9215, 0xba06, 0x002e, 0x00ce, 0x00be,
+ 0x0016, 0x2c08, 0x080c, 0xe690, 0x001e, 0x007e, 0x002e, 0x8210,
+ 0x1f04, 0x32ad, 0x015e, 0x001e, 0x002e, 0x003e, 0x004e, 0x00be,
+ 0x00ce, 0x00ee, 0x00fe, 0x0005, 0x0046, 0x0026, 0x0016, 0x080c,
+ 0x57d3, 0xd0c4, 0x0140, 0xd0a4, 0x0130, 0x9006, 0x2220, 0x2009,
+ 0x0029, 0x080c, 0xe9a5, 0x001e, 0x002e, 0x004e, 0x0005, 0x0016,
+ 0x0026, 0x0036, 0x00c6, 0x7294, 0x82ff, 0x01e8, 0x080c, 0x6a8a,
+ 0x11d0, 0x2100, 0x080c, 0x28c7, 0x81ff, 0x01b8, 0x2019, 0x0001,
+ 0x8314, 0x92e0, 0x1c80, 0x2c04, 0xd384, 0x0120, 0x9084, 0xff00,
+ 0x8007, 0x0010, 0x9084, 0x00ff, 0x9116, 0x0138, 0x9096, 0x00ff,
+ 0x0110, 0x8318, 0x0c68, 0x9085, 0x0001, 0x00ce, 0x003e, 0x002e,
+ 0x001e, 0x0005, 0x0016, 0x00c6, 0x0126, 0x2091, 0x8000, 0x0036,
+ 0x2019, 0x0029, 0x00a9, 0x003e, 0x9180, 0x1000, 0x2004, 0x9065,
+ 0x0158, 0x0016, 0x00c6, 0x2061, 0x1ab8, 0x001e, 0x6112, 0x080c,
+ 0x3246, 0x001e, 0x080c, 0x66d7, 0x012e, 0x00ce, 0x001e, 0x0005,
+ 0x0016, 0x0026, 0x2110, 0x080c, 0xaa9a, 0x080c, 0xed0f, 0x002e,
+ 0x001e, 0x0005, 0x2001, 0x1837, 0x2004, 0xd0cc, 0x0005, 0x00c6,
+ 0x00b6, 0x080c, 0x7569, 0x1118, 0x20a9, 0x0800, 0x0010, 0x20a9,
+ 0x0782, 0x080c, 0x7569, 0x1110, 0x900e, 0x0010, 0x2009, 0x007e,
+ 0x9180, 0x1000, 0x2004, 0x905d, 0x0130, 0x86ff, 0x0110, 0xb800,
+ 0xd0bc, 0x090c, 0x66d7, 0x8108, 0x1f04, 0x3380, 0x2061, 0x1800,
+ 0x607f, 0x0000, 0x6080, 0x9084, 0x00ff, 0x6082, 0x60b3, 0x0000,
+ 0x00be, 0x00ce, 0x0005, 0x2001, 0x1869, 0x2004, 0xd0bc, 0x0005,
+ 0x2011, 0x1848, 0x2214, 0xd2ec, 0x0005, 0x0026, 0x2011, 0x1867,
+ 0x2214, 0xd2dc, 0x002e, 0x0005, 0x7eef, 0x7de8, 0x7ce4, 0x80e2,
+ 0x7be1, 0x80e0, 0x80dc, 0x80da, 0x7ad9, 0x80d6, 0x80d5, 0x80d4,
+ 0x80d3, 0x80d2, 0x80d1, 0x79ce, 0x78cd, 0x80cc, 0x80cb, 0x80ca,
+ 0x80c9, 0x80c7, 0x80c6, 0x77c5, 0x76c3, 0x80bc, 0x80ba, 0x75b9,
+ 0x80b6, 0x74b5, 0x73b4, 0x72b3, 0x80b2, 0x80b1, 0x80ae, 0x71ad,
+ 0x80ac, 0x70ab, 0x6faa, 0x6ea9, 0x80a7, 0x6da6, 0x6ca5, 0x6ba3,
+ 0x6a9f, 0x699e, 0x689d, 0x809b, 0x8098, 0x6797, 0x6690, 0x658f,
+ 0x6488, 0x6384, 0x6282, 0x8081, 0x8080, 0x617c, 0x607a, 0x8079,
+ 0x5f76, 0x8075, 0x8074, 0x8073, 0x8072, 0x8071, 0x806e, 0x5e6d,
+ 0x806c, 0x5d6b, 0x5c6a, 0x5b69, 0x8067, 0x5a66, 0x5965, 0x5863,
+ 0x575c, 0x565a, 0x5559, 0x8056, 0x8055, 0x5454, 0x5353, 0x5252,
+ 0x5151, 0x504e, 0x4f4d, 0x804c, 0x804b, 0x4e4a, 0x4d49, 0x8047,
+ 0x4c46, 0x8045, 0x8043, 0x803c, 0x803a, 0x8039, 0x8036, 0x4b35,
+ 0x8034, 0x4a33, 0x4932, 0x4831, 0x802e, 0x472d, 0x462c, 0x452b,
+ 0x442a, 0x4329, 0x4227, 0x8026, 0x8025, 0x4123, 0x401f, 0x3f1e,
+ 0x3e1d, 0x3d1b, 0x3c18, 0x8017, 0x8010, 0x3b0f, 0x3a08, 0x8004,
+ 0x3902, 0x8001, 0x8000, 0x8000, 0x3800, 0x3700, 0x3600, 0x8000,
+ 0x3500, 0x8000, 0x8000, 0x8000, 0x3400, 0x8000, 0x8000, 0x8000,
+ 0x8000, 0x8000, 0x8000, 0x3300, 0x3200, 0x8000, 0x8000, 0x8000,
+ 0x8000, 0x8000, 0x8000, 0x3100, 0x3000, 0x8000, 0x8000, 0x2f00,
+ 0x8000, 0x2e00, 0x2d00, 0x2c00, 0x8000, 0x8000, 0x8000, 0x2b00,
+ 0x8000, 0x2a00, 0x2900, 0x2800, 0x8000, 0x2700, 0x2600, 0x2500,
+ 0x2400, 0x2300, 0x2200, 0x8000, 0x8000, 0x2100, 0x2000, 0x1f00,
+ 0x1e00, 0x1d00, 0x1c00, 0x8000, 0x8000, 0x1b00, 0x1a00, 0x8000,
+ 0x1900, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x1800,
+ 0x8000, 0x1700, 0x1600, 0x1500, 0x8000, 0x1400, 0x1300, 0x1200,
+ 0x1100, 0x1000, 0x0f00, 0x8000, 0x8000, 0x0e00, 0x0d00, 0x0c00,
+ 0x0b00, 0x0a00, 0x0900, 0x8000, 0x8000, 0x0800, 0x0700, 0x8000,
+ 0x0600, 0x8000, 0x8000, 0x8000, 0x0500, 0x0400, 0x0300, 0x8000,
+ 0x0200, 0x8000, 0x8000, 0x8000, 0x0100, 0x8000, 0x8000, 0x8000,
+ 0x8000, 0x8000, 0x8000, 0x0000, 0x8000, 0x8000, 0x8000, 0x8000,
0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
- 0x8000, 0x2071, 0x189e, 0x7003, 0x0002, 0x9006, 0x7016, 0x701a,
- 0x704a, 0x704e, 0x700e, 0x7042, 0x7046, 0x703b, 0x18ba, 0x703f,
- 0x18ba, 0x7007, 0x0001, 0x080c, 0x1027, 0x090c, 0x0dc5, 0x2900,
- 0x706a, 0xa867, 0x0002, 0xa8ab, 0xdcb0, 0x080c, 0x1027, 0x090c,
- 0x0dc5, 0x2900, 0x706e, 0xa867, 0x0002, 0xa8ab, 0xdcb0, 0x0005,
- 0x2071, 0x189e, 0x7004, 0x0002, 0x34e0, 0x34e1, 0x34f4, 0x3508,
- 0x0005, 0x1004, 0x34f1, 0x0e04, 0x34f1, 0x2079, 0x0000, 0x0126,
- 0x2091, 0x8000, 0x700c, 0x9005, 0x1128, 0x700f, 0x0001, 0x012e,
- 0x0468, 0x0005, 0x012e, 0x0ce8, 0x2079, 0x0000, 0x2061, 0x18b8,
- 0x2c4c, 0xa86c, 0x908e, 0x0100, 0x0128, 0x9086, 0x0200, 0x0904,
- 0x35dc, 0x0005, 0x7018, 0x2048, 0x2061, 0x1800, 0x701c, 0x0807,
- 0x7014, 0x2048, 0xa864, 0x9094, 0x00ff, 0x9296, 0x0029, 0x1120,
- 0xaa78, 0xd2fc, 0x0128, 0x0005, 0x9086, 0x0103, 0x0108, 0x0005,
- 0x2079, 0x0000, 0x2061, 0x1800, 0x701c, 0x0807, 0x2061, 0x1800,
- 0x7880, 0x908a, 0x0040, 0x1210, 0x61d0, 0x0042, 0x2100, 0x908a,
- 0x003f, 0x1a04, 0x35d9, 0x61d0, 0x0804, 0x356e, 0x35b0, 0x35e8,
- 0x35d9, 0x35f4, 0x35fe, 0x3604, 0x3608, 0x3618, 0x361c, 0x3632,
- 0x3638, 0x363e, 0x3649, 0x3654, 0x3663, 0x3672, 0x3680, 0x3697,
- 0x36b2, 0x35d9, 0x375b, 0x3799, 0x383f, 0x3850, 0x3873, 0x35d9,
- 0x35d9, 0x35d9, 0x38ab, 0x38c7, 0x38d0, 0x38ff, 0x3905, 0x35d9,
- 0x394b, 0x35d9, 0x35d9, 0x35d9, 0x35d9, 0x35d9, 0x3956, 0x395f,
- 0x3967, 0x3969, 0x35d9, 0x35d9, 0x35d9, 0x35d9, 0x35d9, 0x35d9,
- 0x3995, 0x35d9, 0x35d9, 0x35d9, 0x35d9, 0x35d9, 0x39b2, 0x3a27,
- 0x35d9, 0x35d9, 0x35d9, 0x35d9, 0x35d9, 0x35d9, 0x0002, 0x3a51,
- 0x3a54, 0x3ab3, 0x3acc, 0x3afc, 0x3d9e, 0x35d9, 0x5390, 0x35d9,
- 0x35d9, 0x35d9, 0x35d9, 0x35d9, 0x35d9, 0x35d9, 0x35d9, 0x3632,
- 0x3638, 0x42c8, 0x57f1, 0x42e6, 0x541f, 0x5471, 0x557c, 0x35d9,
- 0x55de, 0x561a, 0x564b, 0x5753, 0x5678, 0x56d3, 0x35d9, 0x42ea,
- 0x44b0, 0x44c6, 0x44eb, 0x4550, 0x45c4, 0x45e4, 0x465b, 0x46b7,
- 0x4713, 0x4716, 0x473b, 0x47f2, 0x4858, 0x4860, 0x4995, 0x4b0d,
- 0x4b41, 0x4da5, 0x35d9, 0x4dc3, 0x4e69, 0x4f52, 0x4fac, 0x35d9,
- 0x5063, 0x35d9, 0x50cf, 0x50ea, 0x4860, 0x5330, 0x714c, 0x0000,
- 0x2021, 0x4000, 0x080c, 0x4bbf, 0x0126, 0x2091, 0x8000, 0x0e04,
- 0x35ba, 0x0010, 0x012e, 0x0cc0, 0x7c36, 0x9486, 0x4000, 0x0118,
- 0x7833, 0x0011, 0x0010, 0x7833, 0x0010, 0x7c82, 0x7986, 0x7a8a,
- 0x7b8e, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c,
- 0x11aa, 0x7007, 0x0001, 0x2091, 0x5000, 0x700f, 0x0000, 0x012e,
- 0x0005, 0x2021, 0x4001, 0x08b0, 0x2021, 0x4002, 0x0898, 0x2021,
- 0x4003, 0x0880, 0x2021, 0x4005, 0x0868, 0x2021, 0x4006, 0x0850,
- 0x2039, 0x0001, 0x902e, 0x2520, 0x7b88, 0x7a8c, 0x7884, 0x7990,
- 0x81ff, 0x0d98, 0x0804, 0x4bcc, 0x2039, 0x0001, 0x902e, 0x2520,
- 0x7b88, 0x7a8c, 0x7884, 0x7990, 0x0804, 0x4bcf, 0x7984, 0x7888,
- 0x2114, 0x200a, 0x0804, 0x35b0, 0x7984, 0x2114, 0x0804, 0x35b0,
- 0x20e1, 0x0000, 0x2099, 0x0021, 0x20e9, 0x0000, 0x20a1, 0x0021,
- 0x20a9, 0x001f, 0x4003, 0x7984, 0x7a88, 0x7b8c, 0x0804, 0x35b0,
- 0x7884, 0x2060, 0x0804, 0x3665, 0x2009, 0x0003, 0x2011, 0x0003,
- 0x2019, 0x000f, 0x789b, 0x0137, 0x7893, 0xffff, 0x2001, 0x188f,
- 0x2004, 0x9005, 0x0118, 0x7896, 0x0804, 0x35b0, 0x7897, 0x0001,
- 0x0804, 0x35b0, 0x2039, 0x0001, 0x7d98, 0x7c9c, 0x0804, 0x35ec,
- 0x2039, 0x0001, 0x7d98, 0x7c9c, 0x0804, 0x35f8, 0x79a0, 0x9182,
- 0x0040, 0x0210, 0x0804, 0x35e5, 0x2138, 0x7d98, 0x7c9c, 0x0804,
- 0x35ec, 0x79a0, 0x9182, 0x0040, 0x0210, 0x0804, 0x35e5, 0x2138,
- 0x7d98, 0x7c9c, 0x0804, 0x35f8, 0x79a0, 0x9182, 0x0040, 0x0210,
- 0x0804, 0x35e5, 0x21e8, 0x7984, 0x7888, 0x20a9, 0x0001, 0x21a0,
- 0x4004, 0x0804, 0x35b0, 0x2061, 0x0800, 0xe10c, 0x9006, 0x2c15,
- 0x9200, 0x8c60, 0x8109, 0x1dd8, 0x2010, 0x9005, 0x0904, 0x35b0,
- 0x0804, 0x35df, 0x79a0, 0x9182, 0x0040, 0x0210, 0x0804, 0x35e5,
- 0x21e0, 0x20a9, 0x0001, 0x7984, 0x2198, 0x4012, 0x0804, 0x35b0,
- 0x2069, 0x1847, 0x7884, 0x7990, 0x911a, 0x1a04, 0x35e5, 0x8019,
- 0x0904, 0x35e5, 0x684a, 0x6942, 0x788c, 0x6852, 0x7888, 0x6856,
- 0x9006, 0x685a, 0x685e, 0x080c, 0x7879, 0x0804, 0x35b0, 0x2069,
- 0x1847, 0x7884, 0x7994, 0x911a, 0x1a04, 0x35e5, 0x8019, 0x0904,
- 0x35e5, 0x684e, 0x6946, 0x788c, 0x6862, 0x7888, 0x6866, 0x9006,
- 0x686a, 0x686e, 0x0126, 0x2091, 0x8000, 0x080c, 0x6b24, 0x012e,
- 0x0804, 0x35b0, 0x902e, 0x2520, 0x81ff, 0x0120, 0x2009, 0x0001,
- 0x0804, 0x35e2, 0x7984, 0x7b88, 0x7a8c, 0x20a9, 0x0005, 0x20e9,
- 0x0001, 0x20a1, 0x18a6, 0x4101, 0x080c, 0x4b83, 0x1120, 0x2009,
- 0x0002, 0x0804, 0x35e2, 0x2009, 0x0020, 0xa85c, 0x9080, 0x0019,
- 0xaf60, 0x080c, 0x4bcc, 0x701f, 0x36d6, 0x0005, 0xa864, 0x2008,
- 0x9084, 0x00ff, 0x9096, 0x0011, 0x0168, 0x9096, 0x0019, 0x0150,
- 0x9096, 0x0015, 0x0138, 0x9096, 0x0048, 0x0120, 0x9096, 0x0029,
- 0x1904, 0x35e2, 0x810f, 0x918c, 0x00ff, 0x0904, 0x35e2, 0x7112,
- 0x7010, 0x8001, 0x0560, 0x7012, 0x080c, 0x4b83, 0x1120, 0x2009,
- 0x0002, 0x0804, 0x35e2, 0x2009, 0x0020, 0x7068, 0x2040, 0xa28c,
- 0xa390, 0xa494, 0xa598, 0x9290, 0x0040, 0x9399, 0x0000, 0x94a1,
- 0x0000, 0x95a9, 0x0000, 0xa85c, 0x9080, 0x0019, 0xaf60, 0x080c,
- 0x4bcc, 0x701f, 0x3714, 0x0005, 0xa864, 0x9084, 0x00ff, 0x9096,
- 0x0002, 0x0120, 0x9096, 0x000a, 0x1904, 0x35e2, 0x0888, 0x7014,
- 0x2048, 0xa868, 0xc0fd, 0xa86a, 0xa864, 0x9084, 0x00ff, 0x9096,
- 0x0029, 0x1160, 0xc2fd, 0xaa7a, 0x080c, 0x6292, 0x0150, 0x0126,
- 0x2091, 0x8000, 0xa87a, 0xa982, 0x012e, 0x0050, 0x080c, 0x65c2,
- 0x1128, 0x7007, 0x0003, 0x701f, 0x3740, 0x0005, 0x080c, 0x7037,
- 0x0126, 0x2091, 0x8000, 0x20a9, 0x0005, 0x20e1, 0x0001, 0x2099,
- 0x18a6, 0x400a, 0x2100, 0x9210, 0x9399, 0x0000, 0x94a1, 0x0000,
- 0x95a9, 0x0000, 0xa85c, 0x9080, 0x0019, 0x2009, 0x0020, 0x012e,
- 0xaf60, 0x0804, 0x4bcf, 0x2091, 0x8000, 0x7837, 0x4000, 0x7833,
- 0x0010, 0x7883, 0x4000, 0x7887, 0x4953, 0x788b, 0x5020, 0x788f,
- 0x2020, 0x2009, 0x017f, 0x2104, 0x7892, 0x3f00, 0x7896, 0x2061,
- 0x0100, 0x6200, 0x2061, 0x0200, 0x603c, 0x8007, 0x9205, 0x789a,
- 0x2009, 0x04fd, 0x2104, 0x789e, 0x2091, 0x5000, 0x2091, 0x4080,
- 0x2001, 0x0089, 0x2004, 0xd084, 0x0180, 0x2001, 0x1a1d, 0x2004,
- 0x9005, 0x0128, 0x2001, 0x008b, 0x2004, 0xd0fc, 0x0dd8, 0x2001,
- 0x008a, 0x2003, 0x0002, 0x2003, 0x1001, 0x2071, 0x0080, 0x0804,
- 0x0427, 0x81ff, 0x1904, 0x35e2, 0x7984, 0x080c, 0x6717, 0x1904,
- 0x35e5, 0x7e98, 0x9684, 0x3fff, 0x9082, 0x4000, 0x1a04, 0x35e5,
- 0x7c88, 0x7d8c, 0x080c, 0x687a, 0x080c, 0x6849, 0x0000, 0x1518,
- 0x2061, 0x1cd0, 0x0126, 0x2091, 0x8000, 0x6000, 0x9086, 0x0000,
- 0x0148, 0x6014, 0x904d, 0x0130, 0xa86c, 0x9406, 0x1118, 0xa870,
- 0x9506, 0x0150, 0x012e, 0x9ce0, 0x0018, 0x2001, 0x181a, 0x2004,
- 0x9c02, 0x1a04, 0x35e2, 0x0c30, 0x080c, 0xca5e, 0x012e, 0x0904,
- 0x35e2, 0x0804, 0x35b0, 0x900e, 0x2001, 0x0005, 0x080c, 0x7037,
- 0x0126, 0x2091, 0x8000, 0x080c, 0xd13b, 0x080c, 0x6dcb, 0x012e,
- 0x0804, 0x35b0, 0x00a6, 0x2950, 0xb198, 0x080c, 0x6717, 0x1904,
- 0x382c, 0xb6a4, 0x9684, 0x3fff, 0x9082, 0x4000, 0x16e8, 0xb49c,
- 0xb5a0, 0x080c, 0x687a, 0x080c, 0x6849, 0x1520, 0x2061, 0x1cd0,
- 0x0126, 0x2091, 0x8000, 0x6000, 0x9086, 0x0000, 0x0148, 0x6014,
- 0x904d, 0x0130, 0xa86c, 0x9406, 0x1118, 0xa870, 0x9506, 0x0158,
- 0x012e, 0x9ce0, 0x0018, 0x2001, 0x181a, 0x2004, 0x9c02, 0x2009,
- 0x000d, 0x12b0, 0x0c28, 0x080c, 0xca5e, 0x012e, 0x2009, 0x0003,
- 0x0178, 0x00e0, 0x900e, 0x2001, 0x0005, 0x080c, 0x7037, 0x0126,
- 0x2091, 0x8000, 0x080c, 0xd13b, 0x080c, 0x6dbe, 0x012e, 0x0070,
- 0xb097, 0x4005, 0xb19a, 0x0010, 0xb097, 0x4006, 0x900e, 0x9085,
- 0x0001, 0x2001, 0x0030, 0x2a48, 0x00ae, 0x0005, 0xb097, 0x4000,
- 0x9006, 0x918d, 0x0001, 0x2008, 0x2a48, 0x00ae, 0x0005, 0x81ff,
- 0x1904, 0x35e2, 0x080c, 0x4b9a, 0x0904, 0x35e5, 0x080c, 0x67de,
- 0x0904, 0x35e2, 0x080c, 0x6880, 0x0904, 0x35e2, 0x0804, 0x45db,
- 0x81ff, 0x1904, 0x35e2, 0x080c, 0x4bb6, 0x0904, 0x35e5, 0x080c,
- 0x690e, 0x0904, 0x35e2, 0x2019, 0x0005, 0x79a8, 0x080c, 0x689b,
- 0x0904, 0x35e2, 0x7888, 0x908a, 0x1000, 0x1a04, 0x35e5, 0x8003,
- 0x800b, 0x810b, 0x9108, 0x080c, 0x8711, 0x79a8, 0xd184, 0x1904,
- 0x35b0, 0x0804, 0x45db, 0x0126, 0x2091, 0x8000, 0x81ff, 0x0118,
- 0x2009, 0x0001, 0x0450, 0x2029, 0x07ff, 0x645c, 0x2400, 0x9506,
- 0x01f8, 0x2508, 0x080c, 0x6717, 0x11d8, 0x080c, 0x690e, 0x1128,
- 0x2009, 0x0002, 0x62c0, 0x2518, 0x00c0, 0x2019, 0x0004, 0x900e,
- 0x080c, 0x689b, 0x1118, 0x2009, 0x0006, 0x0078, 0x7884, 0x908a,
- 0x1000, 0x1270, 0x8003, 0x800b, 0x810b, 0x9108, 0x080c, 0x8711,
- 0x8529, 0x1ae0, 0x012e, 0x0804, 0x35b0, 0x012e, 0x0804, 0x35e2,
- 0x012e, 0x0804, 0x35e5, 0x080c, 0x4b9a, 0x0904, 0x35e5, 0x080c,
- 0x67de, 0x0904, 0x35e2, 0xbaa0, 0x2019, 0x0005, 0x00c6, 0x9066,
- 0x080c, 0x94da, 0x0076, 0x903e, 0x080c, 0x93ad, 0x900e, 0x080c,
- 0xe671, 0x007e, 0x00ce, 0x080c, 0x687a, 0x0804, 0x35b0, 0x080c,
- 0x4b9a, 0x0904, 0x35e5, 0x080c, 0x687a, 0x2208, 0x0804, 0x35b0,
- 0x0156, 0x00d6, 0x00e6, 0x2069, 0x1910, 0x6810, 0x6914, 0x910a,
- 0x1208, 0x900e, 0x6816, 0x9016, 0x901e, 0x20a9, 0x007e, 0x2069,
- 0x1000, 0x2d04, 0x905d, 0x0118, 0xb84c, 0x0059, 0x9210, 0x8d68,
- 0x1f04, 0x38e1, 0x2300, 0x9218, 0x00ee, 0x00de, 0x015e, 0x0804,
- 0x35b0, 0x00f6, 0x0016, 0x907d, 0x0138, 0x9006, 0x8000, 0x2f0c,
- 0x81ff, 0x0110, 0x2178, 0x0cd0, 0x001e, 0x00fe, 0x0005, 0x2069,
- 0x1910, 0x6910, 0x62bc, 0x0804, 0x35b0, 0x81ff, 0x0120, 0x2009,
- 0x0001, 0x0804, 0x35e2, 0x0126, 0x2091, 0x8000, 0x080c, 0x57e1,
- 0x0128, 0x2009, 0x0007, 0x012e, 0x0804, 0x35e2, 0x012e, 0x615c,
- 0x9190, 0x33b1, 0x2215, 0x9294, 0x00ff, 0x637c, 0x83ff, 0x0108,
- 0x6280, 0x67dc, 0x97c4, 0x000a, 0x98c6, 0x000a, 0x1118, 0x2031,
- 0x0001, 0x00e8, 0x97c4, 0x0022, 0x98c6, 0x0022, 0x1118, 0x2031,
- 0x0003, 0x00a8, 0x97c4, 0x0012, 0x98c6, 0x0012, 0x1118, 0x2031,
- 0x0002, 0x0068, 0x080c, 0x7563, 0x1118, 0x2031, 0x0004, 0x0038,
- 0xd79c, 0x0120, 0x2009, 0x0005, 0x0804, 0x35e2, 0x9036, 0x7e9a,
- 0x7f9e, 0x0804, 0x35b0, 0x614c, 0x6250, 0x2019, 0x1987, 0x231c,
- 0x2001, 0x1988, 0x2004, 0x789a, 0x0804, 0x35b0, 0x0126, 0x2091,
- 0x8000, 0x6138, 0x623c, 0x6340, 0x012e, 0x0804, 0x35b0, 0x080c,
- 0x4bb6, 0x0904, 0x35e5, 0xba44, 0xbb38, 0x0804, 0x35b0, 0x080c,
- 0x0dc5, 0x080c, 0x4bb6, 0x2110, 0x0904, 0x35e5, 0xb804, 0x908c,
- 0x00ff, 0x918e, 0x0006, 0x0140, 0x9084, 0xff00, 0x9086, 0x0600,
- 0x2009, 0x0009, 0x1904, 0x35e2, 0x0126, 0x2091, 0x8000, 0x2019,
- 0x0005, 0x00c6, 0x9066, 0x080c, 0xaa80, 0x080c, 0x94da, 0x0076,
- 0x903e, 0x080c, 0x93ad, 0x900e, 0x080c, 0xe671, 0x007e, 0x00ce,
- 0xb807, 0x0407, 0x012e, 0x0804, 0x35b0, 0x614c, 0x6250, 0x7884,
- 0x604e, 0x7b88, 0x6352, 0x2069, 0x1847, 0x831f, 0x9305, 0x6816,
- 0x788c, 0x2069, 0x1987, 0x2d1c, 0x206a, 0x7e98, 0x9682, 0x0014,
- 0x1210, 0x2031, 0x07d0, 0x2069, 0x1988, 0x2d04, 0x266a, 0x789a,
- 0x0804, 0x35b0, 0x0126, 0x2091, 0x8000, 0x6138, 0x7884, 0x603a,
- 0x910e, 0xd1b4, 0x190c, 0x0ebe, 0xd094, 0x0148, 0x00e6, 0x2071,
- 0x19fc, 0x79b4, 0x9192, 0x07d0, 0x1208, 0x713e, 0x00ee, 0xd0c4,
- 0x01a8, 0x00d6, 0x78a8, 0x2009, 0x199e, 0x200a, 0x78ac, 0x2011,
- 0x199f, 0x2012, 0x2069, 0x0100, 0x6838, 0x9086, 0x0007, 0x1118,
- 0x2214, 0x6a5a, 0x0010, 0x210c, 0x695a, 0x00de, 0x2011, 0x0114,
- 0x220c, 0x7888, 0xd08c, 0x0118, 0x918d, 0x0080, 0x0010, 0x918c,
- 0xff7f, 0x2112, 0x603c, 0x7988, 0x613e, 0x6140, 0x910d, 0x788c,
- 0x6042, 0x7a88, 0x9294, 0x1000, 0x9205, 0x910e, 0xd1e4, 0x190c,
- 0x0ed4, 0x9084, 0x0020, 0x0130, 0x78b4, 0x6046, 0x9084, 0x0001,
- 0x090c, 0x42c8, 0x6040, 0xd0cc, 0x0120, 0x78b0, 0x2011, 0x0114,
- 0x2012, 0x012e, 0x0804, 0x35b0, 0x00f6, 0x2079, 0x1800, 0x7a38,
- 0xa898, 0x9084, 0xfebf, 0x9215, 0xa89c, 0x9084, 0xfebf, 0x8002,
- 0x9214, 0x7838, 0x9084, 0x0140, 0x9215, 0x7a3a, 0xa897, 0x4000,
- 0x900e, 0x9085, 0x0001, 0x2001, 0x0000, 0x00fe, 0x0005, 0x7898,
- 0x9005, 0x01a8, 0x7888, 0x9025, 0x0904, 0x35e5, 0x788c, 0x902d,
- 0x0904, 0x35e5, 0x900e, 0x080c, 0x6717, 0x1120, 0xba44, 0xbb38,
- 0xbc46, 0xbd3a, 0x9186, 0x07ff, 0x0190, 0x8108, 0x0ca0, 0x080c,
- 0x4bb6, 0x0904, 0x35e5, 0x7888, 0x900d, 0x0904, 0x35e5, 0x788c,
- 0x9005, 0x0904, 0x35e5, 0xba44, 0xb946, 0xbb38, 0xb83a, 0x0804,
- 0x35b0, 0x2011, 0xbc09, 0x0010, 0x2011, 0xbc05, 0x080c, 0x57e1,
- 0x1904, 0x35e2, 0x00c6, 0x2061, 0x0100, 0x7984, 0x9186, 0x00ff,
- 0x1130, 0x2001, 0x1818, 0x2004, 0x9085, 0xff00, 0x0088, 0x9182,
- 0x007f, 0x16e0, 0x9188, 0x33b1, 0x210d, 0x918c, 0x00ff, 0x2001,
- 0x1818, 0x2004, 0x0026, 0x9116, 0x002e, 0x0580, 0x810f, 0x9105,
- 0x0126, 0x2091, 0x8000, 0x0006, 0x080c, 0xb091, 0x000e, 0x0510,
- 0x602e, 0x620a, 0x7984, 0x00b6, 0x080c, 0x66b2, 0x2b08, 0x00be,
- 0x1500, 0x6112, 0x6023, 0x0001, 0x080c, 0x4b83, 0x01d0, 0x9006,
- 0xa866, 0x7007, 0x0003, 0xa832, 0xa868, 0xc0fd, 0xa86a, 0x701f,
- 0x3aac, 0x2900, 0x6016, 0x2009, 0x0032, 0x080c, 0xb166, 0x012e,
- 0x00ce, 0x0005, 0x012e, 0x00ce, 0x0804, 0x35e2, 0x00ce, 0x0804,
- 0x35e5, 0x080c, 0xb0e7, 0x0cb0, 0xa830, 0x9086, 0x0100, 0x0904,
- 0x35e2, 0x0804, 0x35b0, 0x2061, 0x1a75, 0x0126, 0x2091, 0x8000,
- 0x6000, 0xd084, 0x0170, 0x6104, 0x6208, 0x2061, 0x1800, 0x6354,
- 0x6074, 0x789a, 0x60c0, 0x789e, 0x60bc, 0x78aa, 0x012e, 0x0804,
- 0x35b0, 0x900e, 0x2110, 0x0c88, 0x81ff, 0x1904, 0x35e2, 0x080c,
- 0x7563, 0x0904, 0x35e2, 0x0126, 0x2091, 0x8000, 0x6254, 0x6074,
- 0x9202, 0x0248, 0x9085, 0x0001, 0x080c, 0x28f2, 0x080c, 0x5a04,
- 0x012e, 0x0804, 0x35b0, 0x012e, 0x0804, 0x35e5, 0x0006, 0x0016,
- 0x00c6, 0x00e6, 0x2001, 0x19aa, 0x2070, 0x2061, 0x1847, 0x6008,
- 0x2072, 0x900e, 0x2011, 0x1400, 0x080c, 0x91ab, 0x7206, 0x00ee,
- 0x00ce, 0x001e, 0x000e, 0x0005, 0x0126, 0x2091, 0x8000, 0x81ff,
- 0x0128, 0x012e, 0x2021, 0x400b, 0x0804, 0x35b2, 0x7884, 0xd0fc,
- 0x0158, 0x2001, 0x002a, 0x2004, 0x9005, 0x0180, 0x9082, 0x00e1,
- 0x0298, 0x012e, 0x0804, 0x35e5, 0x2001, 0x002a, 0x2004, 0x9005,
- 0x0128, 0x2069, 0x1847, 0x6908, 0x9102, 0x1230, 0x012e, 0x0804,
- 0x35e5, 0x012e, 0x0804, 0x35e2, 0x080c, 0xb051, 0x0dd0, 0x7884,
- 0xd0fc, 0x0904, 0x3b7b, 0x00c6, 0x080c, 0x4b83, 0x00ce, 0x0d88,
- 0xa867, 0x0000, 0x7884, 0xa80a, 0x7898, 0xa80e, 0x789c, 0xa812,
- 0x2001, 0x002e, 0x2004, 0xa81a, 0x2001, 0x002f, 0x2004, 0xa81e,
- 0x2001, 0x0030, 0x2004, 0xa822, 0x2001, 0x0031, 0x2004, 0xa826,
- 0x2001, 0x0034, 0x2004, 0xa82a, 0x2001, 0x0035, 0x2004, 0xa82e,
- 0x2001, 0x002a, 0x2004, 0x9080, 0x0003, 0x9084, 0x00fc, 0x8004,
- 0xa816, 0x080c, 0x3d01, 0x0928, 0x7014, 0x2048, 0xad2c, 0xac28,
- 0xab1c, 0xaa18, 0xa930, 0xa808, 0xd0b4, 0x1120, 0x2029, 0x0000,
- 0x2021, 0x0000, 0x8906, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084,
- 0xffc0, 0x9080, 0x001b, 0x080c, 0x4bcc, 0x701f, 0x3c3e, 0x7023,
- 0x0001, 0x012e, 0x0005, 0x0046, 0x0086, 0x0096, 0x00a6, 0x00b6,
- 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x080c, 0x3ae6, 0x2001, 0x19a0,
- 0x2003, 0x0000, 0x2021, 0x000a, 0x2061, 0x0100, 0x6104, 0x0016,
- 0x60bb, 0x0000, 0x60bf, 0x32e1, 0x60bf, 0x0012, 0x080c, 0x3d70,
- 0x080c, 0x3d2f, 0x00f6, 0x00e6, 0x0086, 0x2940, 0x2071, 0x1a6a,
- 0x2079, 0x0090, 0x00d6, 0x2069, 0x0000, 0x6884, 0xd0b4, 0x0140,
- 0x2001, 0x0035, 0x2004, 0x780e, 0x2001, 0x0034, 0x2004, 0x780a,
- 0x00de, 0x2011, 0x0001, 0x080c, 0x410c, 0x008e, 0x00ee, 0x00fe,
- 0x080c, 0x4039, 0x080c, 0x3f3e, 0x05b8, 0x2001, 0x020b, 0x2004,
- 0x9084, 0x0140, 0x1db8, 0x080c, 0x4180, 0x00f6, 0x2079, 0x0300,
- 0x78bc, 0x00fe, 0x908c, 0x0070, 0x1560, 0x2071, 0x0200, 0x7037,
- 0x0000, 0x7050, 0x9084, 0xff00, 0x9086, 0x3200, 0x1510, 0x7037,
- 0x0001, 0x7050, 0x9084, 0xff00, 0x9086, 0xe100, 0x11d0, 0x7037,
- 0x0000, 0x7054, 0x7037, 0x0000, 0x715c, 0x9106, 0x1190, 0x2001,
- 0x1820, 0x2004, 0x9106, 0x1168, 0x00c6, 0x2061, 0x0100, 0x6024,
- 0x9084, 0x1e00, 0x00ce, 0x0138, 0x080c, 0x3f48, 0x080c, 0x3d2a,
- 0x0058, 0x080c, 0x3d2a, 0x080c, 0x40a4, 0x080c, 0x402f, 0x2001,
- 0x020b, 0x2004, 0xd0e4, 0x0dd8, 0x2001, 0x032a, 0x2003, 0x0004,
- 0x2061, 0x0100, 0x6027, 0x0002, 0x001e, 0x6106, 0x2011, 0x020d,
- 0x2013, 0x0020, 0x60bb, 0x0000, 0x60bf, 0x0108, 0x60bf, 0x0012,
- 0x2001, 0x0004, 0x200c, 0x918c, 0xfffd, 0x2102, 0x080c, 0x12fc,
- 0x2009, 0x0028, 0x080c, 0x242a, 0x2001, 0x0227, 0x200c, 0x2102,
- 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x00be, 0x00ae, 0x009e, 0x008e,
- 0x004e, 0x2001, 0x19a0, 0x2004, 0x9005, 0x1118, 0x012e, 0x0804,
- 0x35b0, 0x012e, 0x2021, 0x400c, 0x0804, 0x35b2, 0x0016, 0x0026,
- 0x0036, 0x0046, 0x0056, 0x0076, 0x0086, 0x0096, 0x00d6, 0x0156,
- 0x7014, 0x2048, 0x7020, 0x20a8, 0x8000, 0x7022, 0xa804, 0x9005,
- 0x0904, 0x3c9a, 0x2048, 0x1f04, 0x3c4e, 0x7068, 0x2040, 0xa28c,
- 0xa390, 0xa494, 0xa598, 0xa930, 0xa808, 0xd0b4, 0x1120, 0x2029,
- 0x0000, 0x2021, 0x0000, 0x0096, 0x7014, 0x2048, 0xa864, 0x009e,
- 0x9086, 0x0103, 0x0170, 0x8906, 0x8006, 0x8007, 0x90bc, 0x003f,
- 0x9084, 0xffc0, 0x9080, 0x001b, 0x080c, 0x4bcc, 0x701f, 0x3c3e,
- 0x00b0, 0x8906, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0,
- 0x9080, 0x001b, 0x21a8, 0x27e0, 0x2098, 0x27e8, 0x20a0, 0x0006,
- 0x080c, 0x0f8b, 0x000e, 0x080c, 0x4bcf, 0x701f, 0x3c3e, 0x015e,
- 0x00de, 0x009e, 0x008e, 0x007e, 0x005e, 0x004e, 0x003e, 0x002e,
- 0x001e, 0x0005, 0x7014, 0x2048, 0xa864, 0x9086, 0x0103, 0x1118,
- 0x701f, 0x3cff, 0x0450, 0x7014, 0x2048, 0xa868, 0xc0fd, 0xa86a,
- 0x2009, 0x007f, 0x080c, 0x66ac, 0x0110, 0x9006, 0x0030, 0xb813,
- 0x00ff, 0xb817, 0xfffd, 0x080c, 0xd30e, 0x015e, 0x00de, 0x009e,
- 0x008e, 0x007e, 0x005e, 0x004e, 0x003e, 0x002e, 0x001e, 0x0904,
- 0x35e2, 0x0016, 0x0026, 0x0036, 0x0046, 0x0056, 0x0076, 0x0086,
- 0x0096, 0x00d6, 0x0156, 0x701f, 0x3cd1, 0x7007, 0x0003, 0x0804,
- 0x3c8f, 0xa830, 0x9086, 0x0100, 0x2021, 0x400c, 0x0904, 0x35b2,
- 0x0076, 0xad10, 0xac0c, 0xab24, 0xaa20, 0xa930, 0xa808, 0xd0b4,
+ 0x8000, 0x8000, 0x8000, 0x8000, 0x2071, 0x189e, 0x7003, 0x0002,
+ 0x9006, 0x7016, 0x701a, 0x704a, 0x704e, 0x700e, 0x7042, 0x7046,
+ 0x703b, 0x18ba, 0x703f, 0x18ba, 0x7007, 0x0001, 0x080c, 0x1027,
+ 0x090c, 0x0dc5, 0x2900, 0x706a, 0xa867, 0x0002, 0xa8ab, 0xdcb0,
+ 0x080c, 0x1027, 0x090c, 0x0dc5, 0x2900, 0x706e, 0xa867, 0x0002,
+ 0xa8ab, 0xdcb0, 0x0005, 0x2071, 0x189e, 0x7004, 0x0002, 0x34db,
+ 0x34dc, 0x34ef, 0x3503, 0x0005, 0x1004, 0x34ec, 0x0e04, 0x34ec,
+ 0x2079, 0x0000, 0x0126, 0x2091, 0x8000, 0x700c, 0x9005, 0x1128,
+ 0x700f, 0x0001, 0x012e, 0x0468, 0x0005, 0x012e, 0x0ce8, 0x2079,
+ 0x0000, 0x2061, 0x18b8, 0x2c4c, 0xa86c, 0x908e, 0x0100, 0x0128,
+ 0x9086, 0x0200, 0x0904, 0x35d7, 0x0005, 0x7018, 0x2048, 0x2061,
+ 0x1800, 0x701c, 0x0807, 0x7014, 0x2048, 0xa864, 0x9094, 0x00ff,
+ 0x9296, 0x0029, 0x1120, 0xaa78, 0xd2fc, 0x0128, 0x0005, 0x9086,
+ 0x0103, 0x0108, 0x0005, 0x2079, 0x0000, 0x2061, 0x1800, 0x701c,
+ 0x0807, 0x2061, 0x1800, 0x7880, 0x908a, 0x0040, 0x1210, 0x61d0,
+ 0x0042, 0x2100, 0x908a, 0x003f, 0x1a04, 0x35d4, 0x61d0, 0x0804,
+ 0x3569, 0x35ab, 0x35e3, 0x35d4, 0x35ef, 0x35f9, 0x35ff, 0x3603,
+ 0x3613, 0x3617, 0x362d, 0x3633, 0x3639, 0x3644, 0x364f, 0x365e,
+ 0x366d, 0x367b, 0x3692, 0x36ad, 0x35d4, 0x3756, 0x3794, 0x383a,
+ 0x384b, 0x386e, 0x35d4, 0x35d4, 0x35d4, 0x38a6, 0x38c2, 0x38cb,
+ 0x38fa, 0x3900, 0x35d4, 0x3946, 0x35d4, 0x35d4, 0x35d4, 0x35d4,
+ 0x35d4, 0x3951, 0x395a, 0x3962, 0x3964, 0x35d4, 0x35d4, 0x35d4,
+ 0x35d4, 0x35d4, 0x35d4, 0x3990, 0x35d4, 0x35d4, 0x35d4, 0x35d4,
+ 0x35d4, 0x39ad, 0x3a22, 0x35d4, 0x35d4, 0x35d4, 0x35d4, 0x35d4,
+ 0x35d4, 0x0002, 0x3a4c, 0x3a4f, 0x3aae, 0x3ac7, 0x3af7, 0x3d99,
+ 0x35d4, 0x5396, 0x35d4, 0x35d4, 0x35d4, 0x35d4, 0x35d4, 0x35d4,
+ 0x35d4, 0x35d4, 0x362d, 0x3633, 0x42ce, 0x57f7, 0x42ec, 0x5425,
+ 0x5477, 0x5582, 0x35d4, 0x55e4, 0x5620, 0x5651, 0x5759, 0x567e,
+ 0x56d9, 0x35d4, 0x42f0, 0x44b6, 0x44cc, 0x44f1, 0x4556, 0x45ca,
+ 0x45ea, 0x4661, 0x46bd, 0x4719, 0x471c, 0x4741, 0x47f8, 0x485e,
+ 0x4866, 0x499b, 0x4b13, 0x4b47, 0x4dab, 0x35d4, 0x4dc9, 0x4e6f,
+ 0x4f58, 0x4fb2, 0x35d4, 0x5069, 0x35d4, 0x50d5, 0x50f0, 0x4866,
+ 0x5336, 0x714c, 0x0000, 0x2021, 0x4000, 0x080c, 0x4bc5, 0x0126,
+ 0x2091, 0x8000, 0x0e04, 0x35b5, 0x0010, 0x012e, 0x0cc0, 0x7c36,
+ 0x9486, 0x4000, 0x0118, 0x7833, 0x0011, 0x0010, 0x7833, 0x0010,
+ 0x7c82, 0x7986, 0x7a8a, 0x7b8e, 0x2091, 0x4080, 0x2001, 0x0089,
+ 0x2004, 0xd084, 0x190c, 0x11aa, 0x7007, 0x0001, 0x2091, 0x5000,
+ 0x700f, 0x0000, 0x012e, 0x0005, 0x2021, 0x4001, 0x08b0, 0x2021,
+ 0x4002, 0x0898, 0x2021, 0x4003, 0x0880, 0x2021, 0x4005, 0x0868,
+ 0x2021, 0x4006, 0x0850, 0x2039, 0x0001, 0x902e, 0x2520, 0x7b88,
+ 0x7a8c, 0x7884, 0x7990, 0x81ff, 0x0d98, 0x0804, 0x4bd2, 0x2039,
+ 0x0001, 0x902e, 0x2520, 0x7b88, 0x7a8c, 0x7884, 0x7990, 0x0804,
+ 0x4bd5, 0x7984, 0x7888, 0x2114, 0x200a, 0x0804, 0x35ab, 0x7984,
+ 0x2114, 0x0804, 0x35ab, 0x20e1, 0x0000, 0x2099, 0x0021, 0x20e9,
+ 0x0000, 0x20a1, 0x0021, 0x20a9, 0x001f, 0x4003, 0x7984, 0x7a88,
+ 0x7b8c, 0x0804, 0x35ab, 0x7884, 0x2060, 0x0804, 0x3660, 0x2009,
+ 0x0003, 0x2011, 0x0003, 0x2019, 0x0012, 0x789b, 0x0137, 0x7893,
+ 0xffff, 0x2001, 0x188f, 0x2004, 0x9005, 0x0118, 0x7896, 0x0804,
+ 0x35ab, 0x7897, 0x0001, 0x0804, 0x35ab, 0x2039, 0x0001, 0x7d98,
+ 0x7c9c, 0x0804, 0x35e7, 0x2039, 0x0001, 0x7d98, 0x7c9c, 0x0804,
+ 0x35f3, 0x79a0, 0x9182, 0x0040, 0x0210, 0x0804, 0x35e0, 0x2138,
+ 0x7d98, 0x7c9c, 0x0804, 0x35e7, 0x79a0, 0x9182, 0x0040, 0x0210,
+ 0x0804, 0x35e0, 0x2138, 0x7d98, 0x7c9c, 0x0804, 0x35f3, 0x79a0,
+ 0x9182, 0x0040, 0x0210, 0x0804, 0x35e0, 0x21e8, 0x7984, 0x7888,
+ 0x20a9, 0x0001, 0x21a0, 0x4004, 0x0804, 0x35ab, 0x2061, 0x0800,
+ 0xe10c, 0x9006, 0x2c15, 0x9200, 0x8c60, 0x8109, 0x1dd8, 0x2010,
+ 0x9005, 0x0904, 0x35ab, 0x0804, 0x35da, 0x79a0, 0x9182, 0x0040,
+ 0x0210, 0x0804, 0x35e0, 0x21e0, 0x20a9, 0x0001, 0x7984, 0x2198,
+ 0x4012, 0x0804, 0x35ab, 0x2069, 0x1847, 0x7884, 0x7990, 0x911a,
+ 0x1a04, 0x35e0, 0x8019, 0x0904, 0x35e0, 0x684a, 0x6942, 0x788c,
+ 0x6852, 0x7888, 0x6856, 0x9006, 0x685a, 0x685e, 0x080c, 0x787f,
+ 0x0804, 0x35ab, 0x2069, 0x1847, 0x7884, 0x7994, 0x911a, 0x1a04,
+ 0x35e0, 0x8019, 0x0904, 0x35e0, 0x684e, 0x6946, 0x788c, 0x6862,
+ 0x7888, 0x6866, 0x9006, 0x686a, 0x686e, 0x0126, 0x2091, 0x8000,
+ 0x080c, 0x6b2a, 0x012e, 0x0804, 0x35ab, 0x902e, 0x2520, 0x81ff,
+ 0x0120, 0x2009, 0x0001, 0x0804, 0x35dd, 0x7984, 0x7b88, 0x7a8c,
+ 0x20a9, 0x0005, 0x20e9, 0x0001, 0x20a1, 0x18a6, 0x4101, 0x080c,
+ 0x4b89, 0x1120, 0x2009, 0x0002, 0x0804, 0x35dd, 0x2009, 0x0020,
+ 0xa85c, 0x9080, 0x0019, 0xaf60, 0x080c, 0x4bd2, 0x701f, 0x36d1,
+ 0x0005, 0xa864, 0x2008, 0x9084, 0x00ff, 0x9096, 0x0011, 0x0168,
+ 0x9096, 0x0019, 0x0150, 0x9096, 0x0015, 0x0138, 0x9096, 0x0048,
+ 0x0120, 0x9096, 0x0029, 0x1904, 0x35dd, 0x810f, 0x918c, 0x00ff,
+ 0x0904, 0x35dd, 0x7112, 0x7010, 0x8001, 0x0560, 0x7012, 0x080c,
+ 0x4b89, 0x1120, 0x2009, 0x0002, 0x0804, 0x35dd, 0x2009, 0x0020,
+ 0x7068, 0x2040, 0xa28c, 0xa390, 0xa494, 0xa598, 0x9290, 0x0040,
+ 0x9399, 0x0000, 0x94a1, 0x0000, 0x95a9, 0x0000, 0xa85c, 0x9080,
+ 0x0019, 0xaf60, 0x080c, 0x4bd2, 0x701f, 0x370f, 0x0005, 0xa864,
+ 0x9084, 0x00ff, 0x9096, 0x0002, 0x0120, 0x9096, 0x000a, 0x1904,
+ 0x35dd, 0x0888, 0x7014, 0x2048, 0xa868, 0xc0fd, 0xa86a, 0xa864,
+ 0x9084, 0x00ff, 0x9096, 0x0029, 0x1160, 0xc2fd, 0xaa7a, 0x080c,
+ 0x6298, 0x0150, 0x0126, 0x2091, 0x8000, 0xa87a, 0xa982, 0x012e,
+ 0x0050, 0x080c, 0x65c8, 0x1128, 0x7007, 0x0003, 0x701f, 0x373b,
+ 0x0005, 0x080c, 0x703d, 0x0126, 0x2091, 0x8000, 0x20a9, 0x0005,
+ 0x20e1, 0x0001, 0x2099, 0x18a6, 0x400a, 0x2100, 0x9210, 0x9399,
+ 0x0000, 0x94a1, 0x0000, 0x95a9, 0x0000, 0xa85c, 0x9080, 0x0019,
+ 0x2009, 0x0020, 0x012e, 0xaf60, 0x0804, 0x4bd5, 0x2091, 0x8000,
+ 0x7837, 0x4000, 0x7833, 0x0010, 0x7883, 0x4000, 0x7887, 0x4953,
+ 0x788b, 0x5020, 0x788f, 0x2020, 0x2009, 0x017f, 0x2104, 0x7892,
+ 0x3f00, 0x7896, 0x2061, 0x0100, 0x6200, 0x2061, 0x0200, 0x603c,
+ 0x8007, 0x9205, 0x789a, 0x2009, 0x04fd, 0x2104, 0x789e, 0x2091,
+ 0x5000, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x0180,
+ 0x2001, 0x1a1d, 0x2004, 0x9005, 0x0128, 0x2001, 0x008b, 0x2004,
+ 0xd0fc, 0x0dd8, 0x2001, 0x008a, 0x2003, 0x0002, 0x2003, 0x1001,
+ 0x2071, 0x0080, 0x0804, 0x0427, 0x81ff, 0x1904, 0x35dd, 0x7984,
+ 0x080c, 0x671d, 0x1904, 0x35e0, 0x7e98, 0x9684, 0x3fff, 0x9082,
+ 0x4000, 0x1a04, 0x35e0, 0x7c88, 0x7d8c, 0x080c, 0x6880, 0x080c,
+ 0x684f, 0x0000, 0x1518, 0x2061, 0x1cd0, 0x0126, 0x2091, 0x8000,
+ 0x6000, 0x9086, 0x0000, 0x0148, 0x6014, 0x904d, 0x0130, 0xa86c,
+ 0x9406, 0x1118, 0xa870, 0x9506, 0x0150, 0x012e, 0x9ce0, 0x0018,
+ 0x2001, 0x181a, 0x2004, 0x9c02, 0x1a04, 0x35dd, 0x0c30, 0x080c,
+ 0xca71, 0x012e, 0x0904, 0x35dd, 0x0804, 0x35ab, 0x900e, 0x2001,
+ 0x0005, 0x080c, 0x703d, 0x0126, 0x2091, 0x8000, 0x080c, 0xd152,
+ 0x080c, 0x6dd1, 0x012e, 0x0804, 0x35ab, 0x00a6, 0x2950, 0xb198,
+ 0x080c, 0x671d, 0x1904, 0x3827, 0xb6a4, 0x9684, 0x3fff, 0x9082,
+ 0x4000, 0x16e8, 0xb49c, 0xb5a0, 0x080c, 0x6880, 0x080c, 0x684f,
+ 0x1520, 0x2061, 0x1cd0, 0x0126, 0x2091, 0x8000, 0x6000, 0x9086,
+ 0x0000, 0x0148, 0x6014, 0x904d, 0x0130, 0xa86c, 0x9406, 0x1118,
+ 0xa870, 0x9506, 0x0158, 0x012e, 0x9ce0, 0x0018, 0x2001, 0x181a,
+ 0x2004, 0x9c02, 0x2009, 0x000d, 0x12b0, 0x0c28, 0x080c, 0xca71,
+ 0x012e, 0x2009, 0x0003, 0x0178, 0x00e0, 0x900e, 0x2001, 0x0005,
+ 0x080c, 0x703d, 0x0126, 0x2091, 0x8000, 0x080c, 0xd152, 0x080c,
+ 0x6dc4, 0x012e, 0x0070, 0xb097, 0x4005, 0xb19a, 0x0010, 0xb097,
+ 0x4006, 0x900e, 0x9085, 0x0001, 0x2001, 0x0030, 0x2a48, 0x00ae,
+ 0x0005, 0xb097, 0x4000, 0x9006, 0x918d, 0x0001, 0x2008, 0x2a48,
+ 0x00ae, 0x0005, 0x81ff, 0x1904, 0x35dd, 0x080c, 0x4ba0, 0x0904,
+ 0x35e0, 0x080c, 0x67e4, 0x0904, 0x35dd, 0x080c, 0x6886, 0x0904,
+ 0x35dd, 0x0804, 0x45e1, 0x81ff, 0x1904, 0x35dd, 0x080c, 0x4bbc,
+ 0x0904, 0x35e0, 0x080c, 0x6914, 0x0904, 0x35dd, 0x2019, 0x0005,
+ 0x79a8, 0x080c, 0x68a1, 0x0904, 0x35dd, 0x7888, 0x908a, 0x1000,
+ 0x1a04, 0x35e0, 0x8003, 0x800b, 0x810b, 0x9108, 0x080c, 0x8717,
+ 0x79a8, 0xd184, 0x1904, 0x35ab, 0x0804, 0x45e1, 0x0126, 0x2091,
+ 0x8000, 0x81ff, 0x0118, 0x2009, 0x0001, 0x0450, 0x2029, 0x07ff,
+ 0x645c, 0x2400, 0x9506, 0x01f8, 0x2508, 0x080c, 0x671d, 0x11d8,
+ 0x080c, 0x6914, 0x1128, 0x2009, 0x0002, 0x62c0, 0x2518, 0x00c0,
+ 0x2019, 0x0004, 0x900e, 0x080c, 0x68a1, 0x1118, 0x2009, 0x0006,
+ 0x0078, 0x7884, 0x908a, 0x1000, 0x1270, 0x8003, 0x800b, 0x810b,
+ 0x9108, 0x080c, 0x8717, 0x8529, 0x1ae0, 0x012e, 0x0804, 0x35ab,
+ 0x012e, 0x0804, 0x35dd, 0x012e, 0x0804, 0x35e0, 0x080c, 0x4ba0,
+ 0x0904, 0x35e0, 0x080c, 0x67e4, 0x0904, 0x35dd, 0xbaa0, 0x2019,
+ 0x0005, 0x00c6, 0x9066, 0x080c, 0x94e0, 0x0076, 0x903e, 0x080c,
+ 0x93b3, 0x900e, 0x080c, 0xe690, 0x007e, 0x00ce, 0x080c, 0x6880,
+ 0x0804, 0x35ab, 0x080c, 0x4ba0, 0x0904, 0x35e0, 0x080c, 0x6880,
+ 0x2208, 0x0804, 0x35ab, 0x0156, 0x00d6, 0x00e6, 0x2069, 0x1910,
+ 0x6810, 0x6914, 0x910a, 0x1208, 0x900e, 0x6816, 0x9016, 0x901e,
+ 0x20a9, 0x007e, 0x2069, 0x1000, 0x2d04, 0x905d, 0x0118, 0xb84c,
+ 0x0059, 0x9210, 0x8d68, 0x1f04, 0x38dc, 0x2300, 0x9218, 0x00ee,
+ 0x00de, 0x015e, 0x0804, 0x35ab, 0x00f6, 0x0016, 0x907d, 0x0138,
+ 0x9006, 0x8000, 0x2f0c, 0x81ff, 0x0110, 0x2178, 0x0cd0, 0x001e,
+ 0x00fe, 0x0005, 0x2069, 0x1910, 0x6910, 0x62bc, 0x0804, 0x35ab,
+ 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x35dd, 0x0126, 0x2091,
+ 0x8000, 0x080c, 0x57e7, 0x0128, 0x2009, 0x0007, 0x012e, 0x0804,
+ 0x35dd, 0x012e, 0x615c, 0x9190, 0x33ac, 0x2215, 0x9294, 0x00ff,
+ 0x637c, 0x83ff, 0x0108, 0x6280, 0x67dc, 0x97c4, 0x000a, 0x98c6,
+ 0x000a, 0x1118, 0x2031, 0x0001, 0x00e8, 0x97c4, 0x0022, 0x98c6,
+ 0x0022, 0x1118, 0x2031, 0x0003, 0x00a8, 0x97c4, 0x0012, 0x98c6,
+ 0x0012, 0x1118, 0x2031, 0x0002, 0x0068, 0x080c, 0x7569, 0x1118,
+ 0x2031, 0x0004, 0x0038, 0xd79c, 0x0120, 0x2009, 0x0005, 0x0804,
+ 0x35dd, 0x9036, 0x7e9a, 0x7f9e, 0x0804, 0x35ab, 0x614c, 0x6250,
+ 0x2019, 0x1987, 0x231c, 0x2001, 0x1988, 0x2004, 0x789a, 0x0804,
+ 0x35ab, 0x0126, 0x2091, 0x8000, 0x6138, 0x623c, 0x6340, 0x012e,
+ 0x0804, 0x35ab, 0x080c, 0x4bbc, 0x0904, 0x35e0, 0xba44, 0xbb38,
+ 0x0804, 0x35ab, 0x080c, 0x0dc5, 0x080c, 0x4bbc, 0x2110, 0x0904,
+ 0x35e0, 0xb804, 0x908c, 0x00ff, 0x918e, 0x0006, 0x0140, 0x9084,
+ 0xff00, 0x9086, 0x0600, 0x2009, 0x0009, 0x1904, 0x35dd, 0x0126,
+ 0x2091, 0x8000, 0x2019, 0x0005, 0x00c6, 0x9066, 0x080c, 0xaa9a,
+ 0x080c, 0x94e0, 0x0076, 0x903e, 0x080c, 0x93b3, 0x900e, 0x080c,
+ 0xe690, 0x007e, 0x00ce, 0xb807, 0x0407, 0x012e, 0x0804, 0x35ab,
+ 0x614c, 0x6250, 0x7884, 0x604e, 0x7b88, 0x6352, 0x2069, 0x1847,
+ 0x831f, 0x9305, 0x6816, 0x788c, 0x2069, 0x1987, 0x2d1c, 0x206a,
+ 0x7e98, 0x9682, 0x0014, 0x1210, 0x2031, 0x07d0, 0x2069, 0x1988,
+ 0x2d04, 0x266a, 0x789a, 0x0804, 0x35ab, 0x0126, 0x2091, 0x8000,
+ 0x6138, 0x7884, 0x603a, 0x910e, 0xd1b4, 0x190c, 0x0ebe, 0xd094,
+ 0x0148, 0x00e6, 0x2071, 0x19fc, 0x79b4, 0x9192, 0x07d0, 0x1208,
+ 0x713e, 0x00ee, 0xd0c4, 0x01a8, 0x00d6, 0x78a8, 0x2009, 0x199e,
+ 0x200a, 0x78ac, 0x2011, 0x199f, 0x2012, 0x2069, 0x0100, 0x6838,
+ 0x9086, 0x0007, 0x1118, 0x2214, 0x6a5a, 0x0010, 0x210c, 0x695a,
+ 0x00de, 0x2011, 0x0114, 0x220c, 0x7888, 0xd08c, 0x0118, 0x918d,
+ 0x0080, 0x0010, 0x918c, 0xff7f, 0x2112, 0x603c, 0x7988, 0x613e,
+ 0x6140, 0x910d, 0x788c, 0x6042, 0x7a88, 0x9294, 0x1000, 0x9205,
+ 0x910e, 0xd1e4, 0x190c, 0x0ed4, 0x9084, 0x0020, 0x0130, 0x78b4,
+ 0x6046, 0x9084, 0x0001, 0x090c, 0x42ce, 0x6040, 0xd0cc, 0x0120,
+ 0x78b0, 0x2011, 0x0114, 0x2012, 0x012e, 0x0804, 0x35ab, 0x00f6,
+ 0x2079, 0x1800, 0x7a38, 0xa898, 0x9084, 0xfebf, 0x9215, 0xa89c,
+ 0x9084, 0xfebf, 0x8002, 0x9214, 0x7838, 0x9084, 0x0140, 0x9215,
+ 0x7a3a, 0xa897, 0x4000, 0x900e, 0x9085, 0x0001, 0x2001, 0x0000,
+ 0x00fe, 0x0005, 0x7898, 0x9005, 0x01a8, 0x7888, 0x9025, 0x0904,
+ 0x35e0, 0x788c, 0x902d, 0x0904, 0x35e0, 0x900e, 0x080c, 0x671d,
+ 0x1120, 0xba44, 0xbb38, 0xbc46, 0xbd3a, 0x9186, 0x07ff, 0x0190,
+ 0x8108, 0x0ca0, 0x080c, 0x4bbc, 0x0904, 0x35e0, 0x7888, 0x900d,
+ 0x0904, 0x35e0, 0x788c, 0x9005, 0x0904, 0x35e0, 0xba44, 0xb946,
+ 0xbb38, 0xb83a, 0x0804, 0x35ab, 0x2011, 0xbc09, 0x0010, 0x2011,
+ 0xbc05, 0x080c, 0x57e7, 0x1904, 0x35dd, 0x00c6, 0x2061, 0x0100,
+ 0x7984, 0x9186, 0x00ff, 0x1130, 0x2001, 0x1818, 0x2004, 0x9085,
+ 0xff00, 0x0088, 0x9182, 0x007f, 0x16e0, 0x9188, 0x33ac, 0x210d,
+ 0x918c, 0x00ff, 0x2001, 0x1818, 0x2004, 0x0026, 0x9116, 0x002e,
+ 0x0580, 0x810f, 0x9105, 0x0126, 0x2091, 0x8000, 0x0006, 0x080c,
+ 0xb0ab, 0x000e, 0x0510, 0x602e, 0x620a, 0x7984, 0x00b6, 0x080c,
+ 0x66b8, 0x2b08, 0x00be, 0x1500, 0x6112, 0x6023, 0x0001, 0x080c,
+ 0x4b89, 0x01d0, 0x9006, 0xa866, 0x7007, 0x0003, 0xa832, 0xa868,
+ 0xc0fd, 0xa86a, 0x701f, 0x3aa7, 0x2900, 0x6016, 0x2009, 0x0032,
+ 0x080c, 0xb180, 0x012e, 0x00ce, 0x0005, 0x012e, 0x00ce, 0x0804,
+ 0x35dd, 0x00ce, 0x0804, 0x35e0, 0x080c, 0xb101, 0x0cb0, 0xa830,
+ 0x9086, 0x0100, 0x0904, 0x35dd, 0x0804, 0x35ab, 0x2061, 0x1a75,
+ 0x0126, 0x2091, 0x8000, 0x6000, 0xd084, 0x0170, 0x6104, 0x6208,
+ 0x2061, 0x1800, 0x6354, 0x6074, 0x789a, 0x60c0, 0x789e, 0x60bc,
+ 0x78aa, 0x012e, 0x0804, 0x35ab, 0x900e, 0x2110, 0x0c88, 0x81ff,
+ 0x1904, 0x35dd, 0x080c, 0x7569, 0x0904, 0x35dd, 0x0126, 0x2091,
+ 0x8000, 0x6254, 0x6074, 0x9202, 0x0248, 0x9085, 0x0001, 0x080c,
+ 0x28fd, 0x080c, 0x5a0a, 0x012e, 0x0804, 0x35ab, 0x012e, 0x0804,
+ 0x35e0, 0x0006, 0x0016, 0x00c6, 0x00e6, 0x2001, 0x19ab, 0x2070,
+ 0x2061, 0x1847, 0x6008, 0x2072, 0x900e, 0x2011, 0x1400, 0x080c,
+ 0x91b1, 0x7206, 0x00ee, 0x00ce, 0x001e, 0x000e, 0x0005, 0x0126,
+ 0x2091, 0x8000, 0x81ff, 0x0128, 0x012e, 0x2021, 0x400b, 0x0804,
+ 0x35ad, 0x7884, 0xd0fc, 0x0158, 0x2001, 0x002a, 0x2004, 0x9005,
+ 0x0180, 0x9082, 0x00e1, 0x0298, 0x012e, 0x0804, 0x35e0, 0x2001,
+ 0x002a, 0x2004, 0x9005, 0x0128, 0x2069, 0x1847, 0x6908, 0x9102,
+ 0x1230, 0x012e, 0x0804, 0x35e0, 0x012e, 0x0804, 0x35dd, 0x080c,
+ 0xb06b, 0x0dd0, 0x7884, 0xd0fc, 0x0904, 0x3b76, 0x00c6, 0x080c,
+ 0x4b89, 0x00ce, 0x0d88, 0xa867, 0x0000, 0x7884, 0xa80a, 0x7898,
+ 0xa80e, 0x789c, 0xa812, 0x2001, 0x002e, 0x2004, 0xa81a, 0x2001,
+ 0x002f, 0x2004, 0xa81e, 0x2001, 0x0030, 0x2004, 0xa822, 0x2001,
+ 0x0031, 0x2004, 0xa826, 0x2001, 0x0034, 0x2004, 0xa82a, 0x2001,
+ 0x0035, 0x2004, 0xa82e, 0x2001, 0x002a, 0x2004, 0x9080, 0x0003,
+ 0x9084, 0x00fc, 0x8004, 0xa816, 0x080c, 0x3cfc, 0x0928, 0x7014,
+ 0x2048, 0xad2c, 0xac28, 0xab1c, 0xaa18, 0xa930, 0xa808, 0xd0b4,
0x1120, 0x2029, 0x0000, 0x2021, 0x0000, 0x8906, 0x8006, 0x8007,
- 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, 0x001b, 0x21a8, 0x27e0,
- 0x2098, 0x27e8, 0x20a0, 0x0006, 0x080c, 0x0f8b, 0x000e, 0x080c,
- 0x4bcf, 0x007e, 0x701f, 0x3c3e, 0x7023, 0x0001, 0x0005, 0x0804,
- 0x35b0, 0x0156, 0x00c6, 0xa814, 0x908a, 0x001e, 0x0218, 0xa833,
- 0x001e, 0x0010, 0xa832, 0x0078, 0x81ff, 0x0168, 0x0016, 0x080c,
- 0x4b83, 0x001e, 0x0130, 0xa800, 0x2040, 0xa008, 0xa80a, 0x2100,
- 0x0c58, 0x9006, 0x0010, 0x9085, 0x0001, 0x00ce, 0x015e, 0x0005,
- 0x0006, 0x00f6, 0x2079, 0x0000, 0x7880, 0x9086, 0x0044, 0x00fe,
- 0x000e, 0x0005, 0x2001, 0x19a0, 0x2003, 0x0001, 0x0005, 0x00f6,
- 0x00e6, 0x00c6, 0x2061, 0x0200, 0x2001, 0x19ab, 0x2004, 0x601a,
- 0x2061, 0x0100, 0x2001, 0x19aa, 0x2004, 0x60ce, 0x6104, 0xc1ac,
- 0x6106, 0x080c, 0x4b83, 0xa813, 0x0019, 0xa817, 0x0001, 0x2900,
- 0xa85a, 0x2001, 0x002e, 0x2004, 0xa866, 0x2001, 0x002f, 0x2004,
- 0xa86a, 0x2061, 0x0090, 0x2079, 0x0100, 0x2001, 0x19aa, 0x2004,
- 0x6036, 0x2009, 0x0040, 0x080c, 0x242a, 0x2001, 0x002a, 0x2004,
- 0x9084, 0xfff8, 0xa86e, 0x601a, 0xa873, 0x0000, 0x601f, 0x0000,
- 0x78ca, 0x9006, 0x600a, 0x600e, 0x00ce, 0x00ee, 0x00fe, 0x0005,
- 0x00e6, 0x080c, 0x4b83, 0x2940, 0xa013, 0x0019, 0xa017, 0x0001,
- 0x2800, 0xa05a, 0x2001, 0x0030, 0x2004, 0xa866, 0x2001, 0x0031,
- 0x2004, 0xa86a, 0x2001, 0x002a, 0x2004, 0x9084, 0xfff8, 0xa86e,
- 0xa873, 0x0000, 0x2001, 0x032a, 0x2003, 0x0004, 0x2001, 0x0300,
+ 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, 0x001b, 0x080c, 0x4bd2,
+ 0x701f, 0x3c39, 0x7023, 0x0001, 0x012e, 0x0005, 0x0046, 0x0086,
+ 0x0096, 0x00a6, 0x00b6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x080c,
+ 0x3ae1, 0x2001, 0x19a1, 0x2003, 0x0000, 0x2021, 0x000a, 0x2061,
+ 0x0100, 0x6104, 0x0016, 0x60bb, 0x0000, 0x60bf, 0x32e1, 0x60bf,
+ 0x0012, 0x080c, 0x3d6b, 0x080c, 0x3d2a, 0x00f6, 0x00e6, 0x0086,
+ 0x2940, 0x2071, 0x1a6a, 0x2079, 0x0090, 0x00d6, 0x2069, 0x0000,
+ 0x6884, 0xd0b4, 0x0140, 0x2001, 0x0035, 0x2004, 0x780e, 0x2001,
+ 0x0034, 0x2004, 0x780a, 0x00de, 0x2011, 0x0001, 0x080c, 0x4112,
+ 0x008e, 0x00ee, 0x00fe, 0x080c, 0x4034, 0x080c, 0x3f39, 0x05b8,
+ 0x2001, 0x020b, 0x2004, 0x9084, 0x0140, 0x1db8, 0x080c, 0x4186,
+ 0x00f6, 0x2079, 0x0300, 0x78bc, 0x00fe, 0x908c, 0x0070, 0x1560,
+ 0x2071, 0x0200, 0x7037, 0x0000, 0x7050, 0x9084, 0xff00, 0x9086,
+ 0x3200, 0x1510, 0x7037, 0x0001, 0x7050, 0x9084, 0xff00, 0x9086,
+ 0xe100, 0x11d0, 0x7037, 0x0000, 0x7054, 0x7037, 0x0000, 0x715c,
+ 0x9106, 0x1190, 0x2001, 0x1820, 0x2004, 0x9106, 0x1168, 0x00c6,
+ 0x2061, 0x0100, 0x6024, 0x9084, 0x1e00, 0x00ce, 0x0138, 0x080c,
+ 0x3f43, 0x080c, 0x3d25, 0x0058, 0x080c, 0x3d25, 0x080c, 0x40aa,
+ 0x080c, 0x402a, 0x2001, 0x020b, 0x2004, 0xd0e4, 0x0dd8, 0x2001,
+ 0x032a, 0x2003, 0x0004, 0x2061, 0x0100, 0x6027, 0x0002, 0x001e,
+ 0x6106, 0x2011, 0x020d, 0x2013, 0x0020, 0x60bb, 0x0000, 0x60bf,
+ 0x0108, 0x60bf, 0x0012, 0x2001, 0x0004, 0x200c, 0x918c, 0xfffd,
+ 0x2102, 0x080c, 0x12fc, 0x2009, 0x0028, 0x080c, 0x2432, 0x2001,
+ 0x0227, 0x200c, 0x2102, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x00be,
+ 0x00ae, 0x009e, 0x008e, 0x004e, 0x2001, 0x19a1, 0x2004, 0x9005,
+ 0x1118, 0x012e, 0x0804, 0x35ab, 0x012e, 0x2021, 0x400c, 0x0804,
+ 0x35ad, 0x0016, 0x0026, 0x0036, 0x0046, 0x0056, 0x0076, 0x0086,
+ 0x0096, 0x00d6, 0x0156, 0x7014, 0x2048, 0x7020, 0x20a8, 0x8000,
+ 0x7022, 0xa804, 0x9005, 0x0904, 0x3c95, 0x2048, 0x1f04, 0x3c49,
+ 0x7068, 0x2040, 0xa28c, 0xa390, 0xa494, 0xa598, 0xa930, 0xa808,
+ 0xd0b4, 0x1120, 0x2029, 0x0000, 0x2021, 0x0000, 0x0096, 0x7014,
+ 0x2048, 0xa864, 0x009e, 0x9086, 0x0103, 0x0170, 0x8906, 0x8006,
+ 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, 0x001b, 0x080c,
+ 0x4bd2, 0x701f, 0x3c39, 0x00b0, 0x8906, 0x8006, 0x8007, 0x90bc,
+ 0x003f, 0x9084, 0xffc0, 0x9080, 0x001b, 0x21a8, 0x27e0, 0x2098,
+ 0x27e8, 0x20a0, 0x0006, 0x080c, 0x0f8b, 0x000e, 0x080c, 0x4bd5,
+ 0x701f, 0x3c39, 0x015e, 0x00de, 0x009e, 0x008e, 0x007e, 0x005e,
+ 0x004e, 0x003e, 0x002e, 0x001e, 0x0005, 0x7014, 0x2048, 0xa864,
+ 0x9086, 0x0103, 0x1118, 0x701f, 0x3cfa, 0x0450, 0x7014, 0x2048,
+ 0xa868, 0xc0fd, 0xa86a, 0x2009, 0x007f, 0x080c, 0x66b2, 0x0110,
+ 0x9006, 0x0030, 0xb813, 0x00ff, 0xb817, 0xfffd, 0x080c, 0xd325,
+ 0x015e, 0x00de, 0x009e, 0x008e, 0x007e, 0x005e, 0x004e, 0x003e,
+ 0x002e, 0x001e, 0x0904, 0x35dd, 0x0016, 0x0026, 0x0036, 0x0046,
+ 0x0056, 0x0076, 0x0086, 0x0096, 0x00d6, 0x0156, 0x701f, 0x3ccc,
+ 0x7007, 0x0003, 0x0804, 0x3c8a, 0xa830, 0x9086, 0x0100, 0x2021,
+ 0x400c, 0x0904, 0x35ad, 0x0076, 0xad10, 0xac0c, 0xab24, 0xaa20,
+ 0xa930, 0xa808, 0xd0b4, 0x1120, 0x2029, 0x0000, 0x2021, 0x0000,
+ 0x8906, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080,
+ 0x001b, 0x21a8, 0x27e0, 0x2098, 0x27e8, 0x20a0, 0x0006, 0x080c,
+ 0x0f8b, 0x000e, 0x080c, 0x4bd5, 0x007e, 0x701f, 0x3c39, 0x7023,
+ 0x0001, 0x0005, 0x0804, 0x35ab, 0x0156, 0x00c6, 0xa814, 0x908a,
+ 0x001e, 0x0218, 0xa833, 0x001e, 0x0010, 0xa832, 0x0078, 0x81ff,
+ 0x0168, 0x0016, 0x080c, 0x4b89, 0x001e, 0x0130, 0xa800, 0x2040,
+ 0xa008, 0xa80a, 0x2100, 0x0c58, 0x9006, 0x0010, 0x9085, 0x0001,
+ 0x00ce, 0x015e, 0x0005, 0x0006, 0x00f6, 0x2079, 0x0000, 0x7880,
+ 0x9086, 0x0044, 0x00fe, 0x000e, 0x0005, 0x2001, 0x19a1, 0x2003,
+ 0x0001, 0x0005, 0x00f6, 0x00e6, 0x00c6, 0x2061, 0x0200, 0x2001,
+ 0x19ac, 0x2004, 0x601a, 0x2061, 0x0100, 0x2001, 0x19ab, 0x2004,
+ 0x60ce, 0x6104, 0xc1ac, 0x6106, 0x080c, 0x4b89, 0xa813, 0x0019,
+ 0xa817, 0x0001, 0x2900, 0xa85a, 0x2001, 0x002e, 0x2004, 0xa866,
+ 0x2001, 0x002f, 0x2004, 0xa86a, 0x2061, 0x0090, 0x2079, 0x0100,
+ 0x2001, 0x19ab, 0x2004, 0x6036, 0x2009, 0x0040, 0x080c, 0x2432,
+ 0x2001, 0x002a, 0x2004, 0x9084, 0xfff8, 0xa86e, 0x601a, 0xa873,
+ 0x0000, 0x601f, 0x0000, 0x78ca, 0x9006, 0x600a, 0x600e, 0x00ce,
+ 0x00ee, 0x00fe, 0x0005, 0x00e6, 0x080c, 0x4b89, 0x2940, 0xa013,
+ 0x0019, 0xa017, 0x0001, 0x2800, 0xa05a, 0x2001, 0x0030, 0x2004,
+ 0xa866, 0x2001, 0x0031, 0x2004, 0xa86a, 0x2001, 0x002a, 0x2004,
+ 0x9084, 0xfff8, 0xa86e, 0xa873, 0x0000, 0x2001, 0x032a, 0x2003,
+ 0x0004, 0x2001, 0x0300, 0x2003, 0x0000, 0x2001, 0x020d, 0x2003,
+ 0x0000, 0x2001, 0x0004, 0x200c, 0x918d, 0x0002, 0x2102, 0x00ee,
+ 0x0005, 0x0126, 0x2091, 0x8000, 0x81ff, 0x0148, 0x080c, 0x2c72,
+ 0x1130, 0x9006, 0x080c, 0x2bca, 0x9006, 0x080c, 0x2bad, 0x2001,
+ 0x19a0, 0x2003, 0x0000, 0x7884, 0x9084, 0x0007, 0x0002, 0x3dba,
+ 0x3dc3, 0x3dcc, 0x3db7, 0x3db7, 0x3db7, 0x3db7, 0x3db7, 0x012e,
+ 0x0804, 0x35e0, 0x2009, 0x0114, 0x2104, 0x9085, 0x0800, 0x200a,
+ 0x080c, 0x3f8d, 0x00c0, 0x2009, 0x0114, 0x2104, 0x9085, 0x4000,
+ 0x200a, 0x080c, 0x3f8d, 0x0078, 0x080c, 0x7569, 0x1128, 0x012e,
+ 0x2009, 0x0016, 0x0804, 0x35dd, 0x81ff, 0x0128, 0x012e, 0x2021,
+ 0x400b, 0x0804, 0x35ad, 0x2001, 0x0141, 0x2004, 0xd0dc, 0x0db0,
+ 0x0086, 0x0096, 0x00a6, 0x00b6, 0x00c6, 0x00d6, 0x00e6, 0x00f6,
+ 0x080c, 0x3ae1, 0x2009, 0x0101, 0x210c, 0x0016, 0x7ec8, 0x7dcc,
+ 0x9006, 0x2068, 0x2060, 0x2058, 0x080c, 0x4261, 0x080c, 0x41b1,
+ 0x903e, 0x2720, 0x00f6, 0x00e6, 0x0086, 0x2940, 0x2071, 0x1a6a,
+ 0x2079, 0x0090, 0x00d6, 0x2069, 0x0000, 0x6884, 0xd0b4, 0x0120,
+ 0x68d4, 0x780e, 0x68d0, 0x780a, 0x00de, 0x2011, 0x0001, 0x080c,
+ 0x4112, 0x080c, 0x2c7a, 0x080c, 0x2c7a, 0x080c, 0x2c7a, 0x080c,
+ 0x2c7a, 0x080c, 0x4112, 0x008e, 0x00ee, 0x00fe, 0x080c, 0x4034,
+ 0x2009, 0x9c40, 0x8109, 0x11b0, 0x080c, 0x3f43, 0x2001, 0x0004,
+ 0x200c, 0x918c, 0xfffd, 0x2102, 0x001e, 0x00fe, 0x00ee, 0x00de,
+ 0x00ce, 0x00be, 0x00ae, 0x009e, 0x008e, 0x2009, 0x0017, 0x080c,
+ 0x35dd, 0x0cf8, 0x2001, 0x020b, 0x2004, 0x9084, 0x0140, 0x1d10,
+ 0x00f6, 0x2079, 0x0000, 0x7884, 0x00fe, 0xd0bc, 0x0178, 0x2001,
+ 0x0201, 0x200c, 0x81ff, 0x0150, 0x080c, 0x4012, 0x2d00, 0x9c05,
+ 0x9b05, 0x0120, 0x080c, 0x3f43, 0x0804, 0x3ef0, 0x080c, 0x4186,
+ 0x080c, 0x40aa, 0x080c, 0x3ff5, 0x080c, 0x402a, 0x00f6, 0x2079,
+ 0x0100, 0x7824, 0xd0ac, 0x0130, 0x8b58, 0x080c, 0x3f43, 0x00fe,
+ 0x0804, 0x3ef0, 0x00fe, 0x080c, 0x3f39, 0x1150, 0x8d68, 0x2001,
+ 0x0032, 0x2602, 0x2001, 0x0033, 0x2502, 0x080c, 0x3f43, 0x0080,
+ 0x87ff, 0x0138, 0x2001, 0x0201, 0x2004, 0x9005, 0x1908, 0x8739,
+ 0x0038, 0x2001, 0x1a66, 0x2004, 0x9086, 0x0000, 0x1904, 0x3e40,
+ 0x2001, 0x032f, 0x2003, 0x00f6, 0x8631, 0x1208, 0x8529, 0x2500,
+ 0x9605, 0x0904, 0x3ef0, 0x7884, 0xd0bc, 0x0128, 0x2d00, 0x9c05,
+ 0x9b05, 0x1904, 0x3ef0, 0xa013, 0x0019, 0x2001, 0x032a, 0x2003,
+ 0x0004, 0x7884, 0xd0ac, 0x1148, 0x2001, 0x1a66, 0x2003, 0x0003,
+ 0x2001, 0x032a, 0x2003, 0x0009, 0x0030, 0xa017, 0x0001, 0x78b4,
+ 0x9005, 0x0108, 0xa016, 0x2800, 0xa05a, 0x2009, 0x0040, 0x080c,
+ 0x2432, 0x2900, 0xa85a, 0xa813, 0x0019, 0x7884, 0xd0a4, 0x1180,
+ 0xa817, 0x0000, 0x00c6, 0x20a9, 0x0004, 0x2061, 0x0090, 0x602b,
+ 0x0008, 0x2001, 0x0203, 0x2004, 0x1f04, 0x3ec7, 0x00ce, 0x0030,
+ 0xa817, 0x0001, 0x78b0, 0x9005, 0x0108, 0xa816, 0x00f6, 0x00c6,
+ 0x2079, 0x0100, 0x2061, 0x0090, 0x7827, 0x0002, 0x2001, 0x002a,
+ 0x2004, 0x9084, 0xfff8, 0x601a, 0x0006, 0x2001, 0x002b, 0x2004,
+ 0x601e, 0x78c6, 0x000e, 0x78ca, 0x00ce, 0x00fe, 0x0804, 0x3dfa,
+ 0x001e, 0x00c6, 0x2001, 0x032a, 0x2003, 0x0004, 0x2061, 0x0100,
+ 0x6027, 0x0002, 0x6106, 0x2011, 0x020d, 0x2013, 0x0020, 0x2001,
+ 0x0004, 0x200c, 0x918c, 0xfffd, 0x2102, 0x080c, 0x12fc, 0x7884,
+ 0x9084, 0x0003, 0x9086, 0x0002, 0x01a0, 0x2009, 0x0028, 0x080c,
+ 0x2432, 0x2001, 0x0227, 0x200c, 0x2102, 0x6050, 0x9084, 0xb7ef,
+ 0x6052, 0x602f, 0x0000, 0x604b, 0xf7f7, 0x6043, 0x0090, 0x6043,
+ 0x0010, 0x00ce, 0x2d08, 0x2c10, 0x2b18, 0x2b00, 0x9c05, 0x9d05,
+ 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x00be, 0x00ae, 0x009e, 0x008e,
+ 0x1118, 0x012e, 0x0804, 0x35ab, 0x012e, 0x2021, 0x400c, 0x0804,
+ 0x35ad, 0x9085, 0x0001, 0x1d04, 0x3f42, 0x2091, 0x6000, 0x8420,
+ 0x9486, 0x0064, 0x0005, 0x2001, 0x0105, 0x2003, 0x0010, 0x2001,
+ 0x032a, 0x2003, 0x0004, 0x2001, 0x1a66, 0x2003, 0x0000, 0x0071,
+ 0x2009, 0x0048, 0x080c, 0x2432, 0x2001, 0x0227, 0x2024, 0x2402,
+ 0x2001, 0x0109, 0x2003, 0x4000, 0x9026, 0x0005, 0x00f6, 0x00e6,
+ 0x2071, 0x1a6a, 0x7000, 0x9086, 0x0000, 0x0520, 0x2079, 0x0090,
+ 0x2009, 0x0206, 0x2104, 0x2009, 0x0203, 0x210c, 0x9106, 0x1120,
+ 0x2009, 0x0040, 0x080c, 0x2432, 0x782c, 0xd0fc, 0x0d88, 0x080c,
+ 0x4186, 0x7000, 0x9086, 0x0000, 0x1d58, 0x782b, 0x0004, 0x782c,
+ 0xd0ac, 0x1de8, 0x2009, 0x0040, 0x080c, 0x2432, 0x782b, 0x0002,
+ 0x7003, 0x0000, 0x00ee, 0x00fe, 0x0005, 0x00f6, 0x2079, 0x0100,
+ 0x2001, 0x1818, 0x200c, 0x7932, 0x7936, 0x080c, 0x28dd, 0x7850,
+ 0x9084, 0xfbff, 0x9085, 0x0030, 0x7852, 0x2019, 0x01f4, 0x8319,
+ 0x1df0, 0x9084, 0xffcf, 0x9085, 0x2000, 0x7852, 0x20a9, 0x0046,
+ 0x1d04, 0x3fa8, 0x2091, 0x6000, 0x1f04, 0x3fa8, 0x7850, 0x9085,
+ 0x0400, 0x9084, 0xdfff, 0x7852, 0x2001, 0x0021, 0x2004, 0x9084,
+ 0x0003, 0x9086, 0x0001, 0x1120, 0x7850, 0x9084, 0xdfff, 0x7852,
+ 0x784b, 0xf7f7, 0x7843, 0x0090, 0x7843, 0x0010, 0x20a9, 0x0028,
+ 0xa001, 0x1f04, 0x3fc8, 0x7850, 0x9085, 0x1400, 0x7852, 0x2019,
+ 0x61a8, 0x7854, 0xa001, 0xa001, 0xd08c, 0x1110, 0x8319, 0x1dc8,
+ 0x7827, 0x0048, 0x7850, 0x9085, 0x0400, 0x7852, 0x7843, 0x0040,
+ 0x2019, 0x01f4, 0xa001, 0xa001, 0x8319, 0x1de0, 0x2001, 0x0100,
+ 0x080c, 0x2d52, 0x7827, 0x0020, 0x7843, 0x0000, 0x9006, 0x080c,
+ 0x2d52, 0x7827, 0x0048, 0x00fe, 0x0005, 0x7884, 0xd0ac, 0x11c8,
+ 0x00f6, 0x00e6, 0x2071, 0x1a66, 0x2079, 0x0320, 0x2001, 0x0201,
+ 0x2004, 0x9005, 0x0160, 0x7000, 0x9086, 0x0000, 0x1140, 0x0051,
+ 0xd0bc, 0x0108, 0x8738, 0x7003, 0x0003, 0x782b, 0x0019, 0x00ee,
+ 0x00fe, 0x0005, 0x00f6, 0x2079, 0x0300, 0x78bc, 0x00fe, 0x908c,
+ 0x0070, 0x0178, 0x2009, 0x0032, 0x260a, 0x2009, 0x0033, 0x250a,
+ 0xd0b4, 0x0108, 0x8c60, 0xd0ac, 0x0108, 0x8d68, 0xd0a4, 0x0108,
+ 0x8b58, 0x0005, 0x00f6, 0x2079, 0x0200, 0x781c, 0xd084, 0x0110,
+ 0x7837, 0x0050, 0x00fe, 0x0005, 0x00e6, 0x2071, 0x0100, 0x2001,
+ 0x19ac, 0x2004, 0x70e2, 0x080c, 0x3d1b, 0x1188, 0x2001, 0x1820,
+ 0x2004, 0x2009, 0x181f, 0x210c, 0x918c, 0x00ff, 0x706e, 0x716a,
+ 0x7066, 0x918d, 0x3200, 0x7162, 0x7073, 0xe109, 0x0080, 0x702c,
+ 0x9085, 0x0002, 0x702e, 0x2009, 0x1818, 0x210c, 0x716e, 0x7063,
+ 0x0100, 0x7166, 0x719e, 0x706b, 0x0000, 0x7073, 0x0809, 0x7077,
+ 0x0008, 0x7078, 0x9080, 0x0100, 0x707a, 0x7080, 0x8000, 0x7082,
+ 0x7087, 0xaaaa, 0x9006, 0x708a, 0x708e, 0x707e, 0x70d6, 0x70ab,
+ 0x0036, 0x70af, 0x95d5, 0x7014, 0x9084, 0x1984, 0x9085, 0x0092,
+ 0x7016, 0x080c, 0x4186, 0x00f6, 0x2071, 0x1a66, 0x2079, 0x0320,
+ 0x00d6, 0x2069, 0x0000, 0x6884, 0xd0b4, 0x0120, 0x689c, 0x780e,
+ 0x6898, 0x780a, 0x00de, 0x080c, 0x3d1b, 0x0140, 0x2001, 0x19a0,
+ 0x200c, 0x2003, 0x0001, 0x918e, 0x0001, 0x0120, 0x2009, 0x03e8,
+ 0x8109, 0x1df0, 0x792c, 0xd1fc, 0x0110, 0x782b, 0x0004, 0x2011,
+ 0x0011, 0x080c, 0x4112, 0x2011, 0x0001, 0x080c, 0x4112, 0x00fe,
+ 0x00ee, 0x0005, 0x00f6, 0x00e6, 0x2071, 0x1a66, 0x2079, 0x0320,
+ 0x792c, 0xd1fc, 0x0904, 0x410f, 0x782b, 0x0002, 0x9026, 0xd19c,
+ 0x1904, 0x410b, 0x7000, 0x0002, 0x410f, 0x40c0, 0x40f0, 0x410b,
+ 0xd1bc, 0x1170, 0xd1dc, 0x1190, 0x8001, 0x7002, 0x2011, 0x0001,
+ 0x080c, 0x4112, 0x0904, 0x410f, 0x080c, 0x4112, 0x0804, 0x410f,
+ 0x00f6, 0x2079, 0x0300, 0x78bf, 0x0000, 0x00fe, 0x7810, 0x7914,
+ 0x782b, 0x0004, 0x7812, 0x7916, 0x2001, 0x0201, 0x200c, 0x81ff,
+ 0x0de8, 0x080c, 0x4012, 0x2009, 0x0001, 0x00f6, 0x2079, 0x0300,
+ 0x78b8, 0x00fe, 0xd0ec, 0x0110, 0x2009, 0x0011, 0x792a, 0x00f8,
+ 0x8001, 0x7002, 0x9184, 0x0880, 0x1140, 0x782c, 0xd0fc, 0x1904,
+ 0x40b4, 0x2011, 0x0001, 0x00b1, 0x0090, 0xa010, 0x9092, 0x0004,
+ 0x9086, 0x0015, 0x1120, 0xa000, 0xa05a, 0x2011, 0x0031, 0xa212,
+ 0xd1dc, 0x1960, 0x0828, 0x782b, 0x0004, 0x7003, 0x0000, 0x00ee,
+ 0x00fe, 0x0005, 0xa014, 0x9005, 0x0550, 0x8001, 0x0036, 0x0096,
+ 0xa016, 0xa058, 0x2048, 0xa010, 0x2009, 0x0031, 0x911a, 0x831c,
+ 0x831c, 0x938a, 0x0007, 0x1a0c, 0x0dc5, 0x9398, 0x4140, 0x231d,
+ 0x083f, 0x9080, 0x0004, 0x7a2a, 0x7100, 0x8108, 0x7102, 0x009e,
+ 0x003e, 0x908a, 0x0035, 0x1140, 0x0096, 0xa058, 0x2048, 0xa804,
+ 0xa05a, 0x2001, 0x0019, 0x009e, 0xa012, 0x9085, 0x0001, 0x0005,
+ 0x417d, 0x4174, 0x416b, 0x4162, 0x4159, 0x4150, 0x4147, 0xa964,
+ 0x7902, 0xa968, 0x7906, 0xa96c, 0x7912, 0xa970, 0x7916, 0x0005,
+ 0xa974, 0x7902, 0xa978, 0x7906, 0xa97c, 0x7912, 0xa980, 0x7916,
+ 0x0005, 0xa984, 0x7902, 0xa988, 0x7906, 0xa98c, 0x7912, 0xa990,
+ 0x7916, 0x0005, 0xa994, 0x7902, 0xa998, 0x7906, 0xa99c, 0x7912,
+ 0xa9a0, 0x7916, 0x0005, 0xa9a4, 0x7902, 0xa9a8, 0x7906, 0xa9ac,
+ 0x7912, 0xa9b0, 0x7916, 0x0005, 0xa9b4, 0x7902, 0xa9b8, 0x7906,
+ 0xa9bc, 0x7912, 0xa9c0, 0x7916, 0x0005, 0xa9c4, 0x7902, 0xa9c8,
+ 0x7906, 0xa9cc, 0x7912, 0xa9d0, 0x7916, 0x0005, 0x00f6, 0x00e6,
+ 0x0086, 0x2071, 0x1a6a, 0x2079, 0x0090, 0x792c, 0xd1fc, 0x01e8,
+ 0x782b, 0x0002, 0x2940, 0x9026, 0x7000, 0x0002, 0x41ad, 0x4199,
+ 0x41a4, 0x8001, 0x7002, 0xd19c, 0x1180, 0x2011, 0x0001, 0x080c,
+ 0x4112, 0x190c, 0x4112, 0x0048, 0x8001, 0x7002, 0x782c, 0xd0fc,
+ 0x1d38, 0x2011, 0x0001, 0x080c, 0x4112, 0x008e, 0x00ee, 0x00fe,
+ 0x0005, 0x00f6, 0x00e6, 0x00c6, 0x0086, 0x2061, 0x0200, 0x2001,
+ 0x19ac, 0x2004, 0x601a, 0x2061, 0x0100, 0x2001, 0x19ab, 0x2004,
+ 0x60ce, 0x6104, 0xc1ac, 0x6106, 0x2001, 0x002c, 0x2004, 0x9005,
+ 0x0520, 0x2038, 0x2001, 0x002e, 0x2024, 0x2001, 0x002f, 0x201c,
+ 0x080c, 0x4b89, 0xa813, 0x0019, 0xaf16, 0x2900, 0xa85a, 0x978a,
+ 0x0007, 0x0220, 0x2138, 0x2009, 0x0007, 0x0010, 0x2708, 0x903e,
+ 0x0096, 0xa858, 0x2048, 0xa85c, 0x9080, 0x0019, 0x009e, 0x080c,
+ 0x4229, 0x1d68, 0x2900, 0xa85a, 0x00d0, 0x080c, 0x4b89, 0xa813,
+ 0x0019, 0xa817, 0x0001, 0x2900, 0xa85a, 0x2001, 0x002e, 0x2004,
+ 0xa866, 0x2001, 0x002f, 0x2004, 0xa86a, 0x2001, 0x002a, 0x2004,
+ 0x9084, 0xfff8, 0xa86e, 0x2001, 0x002b, 0x2004, 0xa872, 0x2061,
+ 0x0090, 0x2079, 0x0100, 0x2001, 0x19ab, 0x2004, 0x6036, 0x2009,
+ 0x0040, 0x080c, 0x2432, 0x2001, 0x002a, 0x2004, 0x9084, 0xfff8,
+ 0x601a, 0x0006, 0x2001, 0x002b, 0x2004, 0x601e, 0x78c6, 0x000e,
+ 0x78ca, 0x9006, 0x600a, 0x600e, 0x008e, 0x00ce, 0x00ee, 0x00fe,
+ 0x0005, 0x00e6, 0x2071, 0x0080, 0xaa60, 0x22e8, 0x20a0, 0x20e1,
+ 0x0000, 0x2099, 0x0088, 0x702b, 0x0026, 0x7402, 0x7306, 0x9006,
+ 0x700a, 0x700e, 0x810b, 0x810b, 0x21a8, 0x810b, 0x7112, 0x702b,
+ 0x0041, 0x702c, 0xd0fc, 0x0de8, 0x702b, 0x0002, 0x702b, 0x0040,
+ 0x4005, 0x7400, 0x7304, 0x87ff, 0x0190, 0x0086, 0x0096, 0x2940,
+ 0x0086, 0x080c, 0x4b89, 0x008e, 0xa058, 0x00a6, 0x2050, 0x2900,
+ 0xb006, 0xa05a, 0x00ae, 0x009e, 0x008e, 0x9085, 0x0001, 0x00ee,
+ 0x0005, 0x00e6, 0x2001, 0x002d, 0x2004, 0x9005, 0x0528, 0x2038,
+ 0x2001, 0x0030, 0x2024, 0x2001, 0x0031, 0x201c, 0x080c, 0x4b89,
+ 0x2940, 0xa813, 0x0019, 0xaf16, 0x2900, 0xa85a, 0x978a, 0x0007,
+ 0x0220, 0x2138, 0x2009, 0x0007, 0x0010, 0x2708, 0x903e, 0x0096,
+ 0xa858, 0x2048, 0xa85c, 0x9080, 0x0019, 0x009e, 0x080c, 0x4229,
+ 0x1d68, 0x2900, 0xa85a, 0x00d8, 0x080c, 0x4b89, 0x2940, 0xa013,
+ 0x0019, 0xa017, 0x0001, 0x2800, 0xa05a, 0x2001, 0x0030, 0x2004,
+ 0xa066, 0x2001, 0x0031, 0x2004, 0xa06a, 0x2001, 0x002a, 0x2004,
+ 0x9084, 0xfff8, 0xa06e, 0x2001, 0x002b, 0x2004, 0xa072, 0x2001,
+ 0x032a, 0x2003, 0x0004, 0x7884, 0xd0ac, 0x1180, 0x2001, 0x0101,
+ 0x200c, 0x918d, 0x0200, 0x2102, 0xa017, 0x0000, 0x2001, 0x1a66,
+ 0x2003, 0x0003, 0x2001, 0x032a, 0x2003, 0x0009, 0x2001, 0x0300,
0x2003, 0x0000, 0x2001, 0x020d, 0x2003, 0x0000, 0x2001, 0x0004,
0x200c, 0x918d, 0x0002, 0x2102, 0x00ee, 0x0005, 0x0126, 0x2091,
- 0x8000, 0x81ff, 0x0148, 0x080c, 0x2c7b, 0x1130, 0x9006, 0x080c,
- 0x2bd3, 0x9006, 0x080c, 0x2bb6, 0x7884, 0x9084, 0x0007, 0x0002,
- 0x3dbb, 0x3dc4, 0x3dcd, 0x3db8, 0x3db8, 0x3db8, 0x3db8, 0x3db8,
- 0x012e, 0x0804, 0x35e5, 0x2009, 0x0114, 0x2104, 0x9085, 0x0800,
- 0x200a, 0x080c, 0x3f92, 0x00c0, 0x2009, 0x0114, 0x2104, 0x9085,
- 0x4000, 0x200a, 0x080c, 0x3f92, 0x0078, 0x080c, 0x7563, 0x1128,
- 0x012e, 0x2009, 0x0016, 0x0804, 0x35e2, 0x81ff, 0x0128, 0x012e,
- 0x2021, 0x400b, 0x0804, 0x35b2, 0x6000, 0x9086, 0x0003, 0x1db8,
- 0x2001, 0x0141, 0x2004, 0xd0dc, 0x0d90, 0x0086, 0x0096, 0x00a6,
- 0x00b6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x080c, 0x3ae6, 0x2009,
- 0x0101, 0x210c, 0x0016, 0x7ec8, 0x7dcc, 0x9006, 0x2068, 0x2060,
- 0x2058, 0x080c, 0x425b, 0x080c, 0x41ab, 0x903e, 0x2720, 0x00f6,
- 0x00e6, 0x0086, 0x2940, 0x2071, 0x1a6a, 0x2079, 0x0090, 0x00d6,
- 0x2069, 0x0000, 0x6884, 0xd0b4, 0x0120, 0x68d4, 0x780e, 0x68d0,
- 0x780a, 0x00de, 0x2011, 0x0001, 0x080c, 0x410c, 0x080c, 0x2c83,
- 0x080c, 0x2c83, 0x080c, 0x2c83, 0x080c, 0x2c83, 0x080c, 0x410c,
- 0x008e, 0x00ee, 0x00fe, 0x080c, 0x4039, 0x2009, 0x9c40, 0x8109,
- 0x11b0, 0x080c, 0x3f48, 0x2001, 0x0004, 0x200c, 0x918c, 0xfffd,
- 0x2102, 0x001e, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x00be, 0x00ae,
- 0x009e, 0x008e, 0x2009, 0x0017, 0x080c, 0x35e2, 0x0cf8, 0x2001,
- 0x020b, 0x2004, 0x9084, 0x0140, 0x1d10, 0x00f6, 0x2079, 0x0000,
- 0x7884, 0x00fe, 0xd0bc, 0x0178, 0x2001, 0x0201, 0x200c, 0x81ff,
- 0x0150, 0x080c, 0x4017, 0x2d00, 0x9c05, 0x9b05, 0x0120, 0x080c,
- 0x3f48, 0x0804, 0x3ef5, 0x080c, 0x4180, 0x080c, 0x40a4, 0x080c,
- 0x3ffa, 0x080c, 0x402f, 0x00f6, 0x2079, 0x0100, 0x7824, 0xd0ac,
- 0x0130, 0x8b58, 0x080c, 0x3f48, 0x00fe, 0x0804, 0x3ef5, 0x00fe,
- 0x080c, 0x3f3e, 0x1150, 0x8d68, 0x2001, 0x0032, 0x2602, 0x2001,
- 0x0033, 0x2502, 0x080c, 0x3f48, 0x0080, 0x87ff, 0x0138, 0x2001,
- 0x0201, 0x2004, 0x9005, 0x1908, 0x8739, 0x0038, 0x2001, 0x1a66,
- 0x2004, 0x9086, 0x0000, 0x1904, 0x3e45, 0x2001, 0x032f, 0x2003,
- 0x00f6, 0x8631, 0x1208, 0x8529, 0x2500, 0x9605, 0x0904, 0x3ef5,
- 0x7884, 0xd0bc, 0x0128, 0x2d00, 0x9c05, 0x9b05, 0x1904, 0x3ef5,
- 0xa013, 0x0019, 0x2001, 0x032a, 0x2003, 0x0004, 0x7884, 0xd0ac,
- 0x1148, 0x2001, 0x1a66, 0x2003, 0x0003, 0x2001, 0x032a, 0x2003,
- 0x0009, 0x0030, 0xa017, 0x0001, 0x78b4, 0x9005, 0x0108, 0xa016,
- 0x2800, 0xa05a, 0x2009, 0x0040, 0x080c, 0x242a, 0x2900, 0xa85a,
- 0xa813, 0x0019, 0x7884, 0xd0a4, 0x1180, 0xa817, 0x0000, 0x00c6,
- 0x20a9, 0x0004, 0x2061, 0x0090, 0x602b, 0x0008, 0x2001, 0x0203,
- 0x2004, 0x1f04, 0x3ecc, 0x00ce, 0x0030, 0xa817, 0x0001, 0x78b0,
- 0x9005, 0x0108, 0xa816, 0x00f6, 0x00c6, 0x2079, 0x0100, 0x2061,
- 0x0090, 0x7827, 0x0002, 0x2001, 0x002a, 0x2004, 0x9084, 0xfff8,
- 0x601a, 0x0006, 0x2001, 0x002b, 0x2004, 0x601e, 0x78c6, 0x000e,
- 0x78ca, 0x00ce, 0x00fe, 0x0804, 0x3dff, 0x001e, 0x00c6, 0x2001,
- 0x032a, 0x2003, 0x0004, 0x2061, 0x0100, 0x6027, 0x0002, 0x6106,
- 0x2011, 0x020d, 0x2013, 0x0020, 0x2001, 0x0004, 0x200c, 0x918c,
- 0xfffd, 0x2102, 0x080c, 0x12fc, 0x7884, 0x9084, 0x0003, 0x9086,
- 0x0002, 0x01a0, 0x2009, 0x0028, 0x080c, 0x242a, 0x2001, 0x0227,
- 0x200c, 0x2102, 0x6050, 0x9084, 0xb7ef, 0x6052, 0x602f, 0x0000,
- 0x604b, 0xf7f7, 0x6043, 0x0090, 0x6043, 0x0010, 0x00ce, 0x2d08,
- 0x2c10, 0x2b18, 0x2b00, 0x9c05, 0x9d05, 0x00fe, 0x00ee, 0x00de,
- 0x00ce, 0x00be, 0x00ae, 0x009e, 0x008e, 0x1118, 0x012e, 0x0804,
- 0x35b0, 0x012e, 0x2021, 0x400c, 0x0804, 0x35b2, 0x9085, 0x0001,
- 0x1d04, 0x3f47, 0x2091, 0x6000, 0x8420, 0x9486, 0x0064, 0x0005,
- 0x2001, 0x0105, 0x2003, 0x0010, 0x2001, 0x032a, 0x2003, 0x0004,
- 0x2001, 0x1a66, 0x2003, 0x0000, 0x0071, 0x2009, 0x0048, 0x080c,
- 0x242a, 0x2001, 0x0227, 0x2024, 0x2402, 0x2001, 0x0109, 0x2003,
- 0x4000, 0x9026, 0x0005, 0x00f6, 0x00e6, 0x2071, 0x1a6a, 0x7000,
- 0x9086, 0x0000, 0x0520, 0x2079, 0x0090, 0x2009, 0x0206, 0x2104,
- 0x2009, 0x0203, 0x210c, 0x9106, 0x1120, 0x2009, 0x0040, 0x080c,
- 0x242a, 0x782c, 0xd0fc, 0x0d88, 0x080c, 0x4180, 0x7000, 0x9086,
- 0x0000, 0x1d58, 0x782b, 0x0004, 0x782c, 0xd0ac, 0x1de8, 0x2009,
- 0x0040, 0x080c, 0x242a, 0x782b, 0x0002, 0x7003, 0x0000, 0x00ee,
- 0x00fe, 0x0005, 0x00f6, 0x2079, 0x0100, 0x2001, 0x1818, 0x200c,
- 0x7932, 0x7936, 0x080c, 0x28d2, 0x7850, 0x9084, 0xfbff, 0x9085,
- 0x0030, 0x7852, 0x2019, 0x01f4, 0x8319, 0x1df0, 0x9084, 0xffcf,
- 0x9085, 0x2000, 0x7852, 0x20a9, 0x0046, 0x1d04, 0x3fad, 0x2091,
- 0x6000, 0x1f04, 0x3fad, 0x7850, 0x9085, 0x0400, 0x9084, 0xdfff,
- 0x7852, 0x2001, 0x0021, 0x2004, 0x9084, 0x0003, 0x9086, 0x0001,
- 0x1120, 0x7850, 0x9084, 0xdfff, 0x7852, 0x784b, 0xf7f7, 0x7843,
- 0x0090, 0x7843, 0x0010, 0x20a9, 0x0028, 0xa001, 0x1f04, 0x3fcd,
- 0x7850, 0x9085, 0x1400, 0x7852, 0x2019, 0x61a8, 0x7854, 0xa001,
- 0xa001, 0xd08c, 0x1110, 0x8319, 0x1dc8, 0x7827, 0x0048, 0x7850,
- 0x9085, 0x0400, 0x7852, 0x7843, 0x0040, 0x2019, 0x01f4, 0xa001,
- 0xa001, 0x8319, 0x1de0, 0x2001, 0x0100, 0x080c, 0x2d5b, 0x7827,
- 0x0020, 0x7843, 0x0000, 0x9006, 0x080c, 0x2d5b, 0x7827, 0x0048,
- 0x00fe, 0x0005, 0x7884, 0xd0ac, 0x11c8, 0x00f6, 0x00e6, 0x2071,
- 0x1a66, 0x2079, 0x0320, 0x2001, 0x0201, 0x2004, 0x9005, 0x0160,
- 0x7000, 0x9086, 0x0000, 0x1140, 0x0051, 0xd0bc, 0x0108, 0x8738,
- 0x7003, 0x0003, 0x782b, 0x0019, 0x00ee, 0x00fe, 0x0005, 0x00f6,
- 0x2079, 0x0300, 0x78bc, 0x00fe, 0x908c, 0x0070, 0x0178, 0x2009,
- 0x0032, 0x260a, 0x2009, 0x0033, 0x250a, 0xd0b4, 0x0108, 0x8c60,
- 0xd0ac, 0x0108, 0x8d68, 0xd0a4, 0x0108, 0x8b58, 0x0005, 0x00f6,
- 0x2079, 0x0200, 0x781c, 0xd084, 0x0110, 0x7837, 0x0050, 0x00fe,
- 0x0005, 0x00e6, 0x2071, 0x0100, 0x2001, 0x19ab, 0x2004, 0x70e2,
- 0x080c, 0x3d20, 0x1188, 0x2001, 0x1820, 0x2004, 0x2009, 0x181f,
- 0x210c, 0x918c, 0x00ff, 0x706e, 0x716a, 0x7066, 0x918d, 0x3200,
- 0x7162, 0x7073, 0xe109, 0x0080, 0x702c, 0x9085, 0x0002, 0x702e,
- 0x2009, 0x1818, 0x210c, 0x716e, 0x7063, 0x0100, 0x7166, 0x719e,
- 0x706b, 0x0000, 0x7073, 0x0809, 0x7077, 0x0008, 0x7078, 0x9080,
- 0x0100, 0x707a, 0x7080, 0x8000, 0x7082, 0x7087, 0xaaaa, 0x9006,
- 0x708a, 0x708e, 0x707e, 0x70d6, 0x70ab, 0x0036, 0x70af, 0x95d5,
- 0x7014, 0x9084, 0x1984, 0x9085, 0x0092, 0x7016, 0x080c, 0x4180,
- 0x00f6, 0x2071, 0x1a66, 0x2079, 0x0320, 0x00d6, 0x2069, 0x0000,
- 0x6884, 0xd0b4, 0x0120, 0x689c, 0x780e, 0x6898, 0x780a, 0x00de,
- 0x2009, 0x03e8, 0x8109, 0x1df0, 0x792c, 0xd1fc, 0x0110, 0x782b,
- 0x0004, 0x2011, 0x0011, 0x080c, 0x410c, 0x2011, 0x0001, 0x080c,
- 0x410c, 0x00fe, 0x00ee, 0x0005, 0x00f6, 0x00e6, 0x2071, 0x1a66,
- 0x2079, 0x0320, 0x792c, 0xd1fc, 0x0904, 0x4109, 0x782b, 0x0002,
- 0x9026, 0xd19c, 0x1904, 0x4105, 0x7000, 0x0002, 0x4109, 0x40ba,
- 0x40ea, 0x4105, 0xd1bc, 0x1170, 0xd1dc, 0x1190, 0x8001, 0x7002,
- 0x2011, 0x0001, 0x080c, 0x410c, 0x0904, 0x4109, 0x080c, 0x410c,
- 0x0804, 0x4109, 0x00f6, 0x2079, 0x0300, 0x78bf, 0x0000, 0x00fe,
- 0x7810, 0x7914, 0x782b, 0x0004, 0x7812, 0x7916, 0x2001, 0x0201,
- 0x200c, 0x81ff, 0x0de8, 0x080c, 0x4017, 0x2009, 0x0001, 0x00f6,
- 0x2079, 0x0300, 0x78b8, 0x00fe, 0xd0ec, 0x0110, 0x2009, 0x0011,
- 0x792a, 0x00f8, 0x8001, 0x7002, 0x9184, 0x0880, 0x1140, 0x782c,
- 0xd0fc, 0x1904, 0x40ae, 0x2011, 0x0001, 0x00b1, 0x0090, 0xa010,
- 0x9092, 0x0004, 0x9086, 0x0015, 0x1120, 0xa000, 0xa05a, 0x2011,
- 0x0031, 0xa212, 0xd1dc, 0x1960, 0x0828, 0x782b, 0x0004, 0x7003,
- 0x0000, 0x00ee, 0x00fe, 0x0005, 0xa014, 0x9005, 0x0550, 0x8001,
- 0x0036, 0x0096, 0xa016, 0xa058, 0x2048, 0xa010, 0x2009, 0x0031,
- 0x911a, 0x831c, 0x831c, 0x938a, 0x0007, 0x1a0c, 0x0dc5, 0x9398,
- 0x413a, 0x231d, 0x083f, 0x9080, 0x0004, 0x7a2a, 0x7100, 0x8108,
- 0x7102, 0x009e, 0x003e, 0x908a, 0x0035, 0x1140, 0x0096, 0xa058,
- 0x2048, 0xa804, 0xa05a, 0x2001, 0x0019, 0x009e, 0xa012, 0x9085,
- 0x0001, 0x0005, 0x4177, 0x416e, 0x4165, 0x415c, 0x4153, 0x414a,
- 0x4141, 0xa964, 0x7902, 0xa968, 0x7906, 0xa96c, 0x7912, 0xa970,
- 0x7916, 0x0005, 0xa974, 0x7902, 0xa978, 0x7906, 0xa97c, 0x7912,
- 0xa980, 0x7916, 0x0005, 0xa984, 0x7902, 0xa988, 0x7906, 0xa98c,
- 0x7912, 0xa990, 0x7916, 0x0005, 0xa994, 0x7902, 0xa998, 0x7906,
- 0xa99c, 0x7912, 0xa9a0, 0x7916, 0x0005, 0xa9a4, 0x7902, 0xa9a8,
- 0x7906, 0xa9ac, 0x7912, 0xa9b0, 0x7916, 0x0005, 0xa9b4, 0x7902,
- 0xa9b8, 0x7906, 0xa9bc, 0x7912, 0xa9c0, 0x7916, 0x0005, 0xa9c4,
- 0x7902, 0xa9c8, 0x7906, 0xa9cc, 0x7912, 0xa9d0, 0x7916, 0x0005,
- 0x00f6, 0x00e6, 0x0086, 0x2071, 0x1a6a, 0x2079, 0x0090, 0x792c,
- 0xd1fc, 0x01e8, 0x782b, 0x0002, 0x2940, 0x9026, 0x7000, 0x0002,
- 0x41a7, 0x4193, 0x419e, 0x8001, 0x7002, 0xd19c, 0x1180, 0x2011,
- 0x0001, 0x080c, 0x410c, 0x190c, 0x410c, 0x0048, 0x8001, 0x7002,
- 0x782c, 0xd0fc, 0x1d38, 0x2011, 0x0001, 0x080c, 0x410c, 0x008e,
- 0x00ee, 0x00fe, 0x0005, 0x00f6, 0x00e6, 0x00c6, 0x0086, 0x2061,
- 0x0200, 0x2001, 0x19ab, 0x2004, 0x601a, 0x2061, 0x0100, 0x2001,
- 0x19aa, 0x2004, 0x60ce, 0x6104, 0xc1ac, 0x6106, 0x2001, 0x002c,
- 0x2004, 0x9005, 0x0520, 0x2038, 0x2001, 0x002e, 0x2024, 0x2001,
- 0x002f, 0x201c, 0x080c, 0x4b83, 0xa813, 0x0019, 0xaf16, 0x2900,
- 0xa85a, 0x978a, 0x0007, 0x0220, 0x2138, 0x2009, 0x0007, 0x0010,
- 0x2708, 0x903e, 0x0096, 0xa858, 0x2048, 0xa85c, 0x9080, 0x0019,
- 0x009e, 0x080c, 0x4223, 0x1d68, 0x2900, 0xa85a, 0x00d0, 0x080c,
- 0x4b83, 0xa813, 0x0019, 0xa817, 0x0001, 0x2900, 0xa85a, 0x2001,
- 0x002e, 0x2004, 0xa866, 0x2001, 0x002f, 0x2004, 0xa86a, 0x2001,
- 0x002a, 0x2004, 0x9084, 0xfff8, 0xa86e, 0x2001, 0x002b, 0x2004,
- 0xa872, 0x2061, 0x0090, 0x2079, 0x0100, 0x2001, 0x19aa, 0x2004,
- 0x6036, 0x2009, 0x0040, 0x080c, 0x242a, 0x2001, 0x002a, 0x2004,
- 0x9084, 0xfff8, 0x601a, 0x0006, 0x2001, 0x002b, 0x2004, 0x601e,
- 0x78c6, 0x000e, 0x78ca, 0x9006, 0x600a, 0x600e, 0x008e, 0x00ce,
- 0x00ee, 0x00fe, 0x0005, 0x00e6, 0x2071, 0x0080, 0xaa60, 0x22e8,
- 0x20a0, 0x20e1, 0x0000, 0x2099, 0x0088, 0x702b, 0x0026, 0x7402,
- 0x7306, 0x9006, 0x700a, 0x700e, 0x810b, 0x810b, 0x21a8, 0x810b,
- 0x7112, 0x702b, 0x0041, 0x702c, 0xd0fc, 0x0de8, 0x702b, 0x0002,
- 0x702b, 0x0040, 0x4005, 0x7400, 0x7304, 0x87ff, 0x0190, 0x0086,
- 0x0096, 0x2940, 0x0086, 0x080c, 0x4b83, 0x008e, 0xa058, 0x00a6,
- 0x2050, 0x2900, 0xb006, 0xa05a, 0x00ae, 0x009e, 0x008e, 0x9085,
- 0x0001, 0x00ee, 0x0005, 0x00e6, 0x2001, 0x002d, 0x2004, 0x9005,
- 0x0528, 0x2038, 0x2001, 0x0030, 0x2024, 0x2001, 0x0031, 0x201c,
- 0x080c, 0x4b83, 0x2940, 0xa813, 0x0019, 0xaf16, 0x2900, 0xa85a,
- 0x978a, 0x0007, 0x0220, 0x2138, 0x2009, 0x0007, 0x0010, 0x2708,
- 0x903e, 0x0096, 0xa858, 0x2048, 0xa85c, 0x9080, 0x0019, 0x009e,
- 0x080c, 0x4223, 0x1d68, 0x2900, 0xa85a, 0x00d8, 0x080c, 0x4b83,
- 0x2940, 0xa013, 0x0019, 0xa017, 0x0001, 0x2800, 0xa05a, 0x2001,
- 0x0030, 0x2004, 0xa066, 0x2001, 0x0031, 0x2004, 0xa06a, 0x2001,
- 0x002a, 0x2004, 0x9084, 0xfff8, 0xa06e, 0x2001, 0x002b, 0x2004,
- 0xa072, 0x2001, 0x032a, 0x2003, 0x0004, 0x7884, 0xd0ac, 0x1180,
- 0x2001, 0x0101, 0x200c, 0x918d, 0x0200, 0x2102, 0xa017, 0x0000,
- 0x2001, 0x1a66, 0x2003, 0x0003, 0x2001, 0x032a, 0x2003, 0x0009,
- 0x2001, 0x0300, 0x2003, 0x0000, 0x2001, 0x020d, 0x2003, 0x0000,
- 0x2001, 0x0004, 0x200c, 0x918d, 0x0002, 0x2102, 0x00ee, 0x0005,
- 0x0126, 0x2091, 0x8000, 0x20a9, 0x0007, 0x20a1, 0x1840, 0x20e9,
- 0x0001, 0x9006, 0x4004, 0x20a9, 0x0014, 0x20a1, 0xffec, 0x20e9,
- 0x0000, 0x9006, 0x4004, 0x2009, 0x013c, 0x200a, 0x012e, 0x7880,
- 0x9086, 0x0052, 0x0108, 0x0005, 0x0804, 0x35b0, 0x7d98, 0x7c9c,
- 0x0804, 0x36b4, 0x080c, 0x7563, 0x190c, 0x60e6, 0x6040, 0x9084,
- 0x0020, 0x09b1, 0x2069, 0x1847, 0x2d00, 0x2009, 0x0030, 0x7a8c,
- 0x7b88, 0x7c9c, 0x7d98, 0x2039, 0x0001, 0x080c, 0x4bcc, 0x701f,
- 0x4302, 0x0005, 0x080c, 0x57dc, 0x1130, 0x3b00, 0x3a08, 0xc194,
- 0xc095, 0x20d8, 0x21d0, 0x2069, 0x1847, 0x6800, 0x9005, 0x0904,
- 0x35e5, 0x6804, 0xd0ac, 0x0118, 0xd0a4, 0x0904, 0x35e5, 0xd094,
- 0x00c6, 0x2061, 0x0100, 0x6104, 0x0138, 0x6200, 0x9292, 0x0005,
- 0x0218, 0x918c, 0xffdf, 0x0010, 0x918d, 0x0020, 0x6106, 0x00ce,
- 0xd08c, 0x00c6, 0x2061, 0x0100, 0x6104, 0x0118, 0x918d, 0x0010,
- 0x0010, 0x918c, 0xffef, 0x6106, 0x00ce, 0xd084, 0x0158, 0x6a28,
- 0x928a, 0x007f, 0x1a04, 0x35e5, 0x9288, 0x33b1, 0x210d, 0x918c,
- 0x00ff, 0x6166, 0xd0dc, 0x0130, 0x6828, 0x908a, 0x007f, 0x1a04,
- 0x35e5, 0x605e, 0x6888, 0x9084, 0x0030, 0x8004, 0x8004, 0x8004,
- 0x8004, 0x0006, 0x2009, 0x19b3, 0x9080, 0x29c5, 0x2005, 0x200a,
- 0x000e, 0x2009, 0x19b4, 0x9080, 0x29c9, 0x2005, 0x200a, 0x6808,
- 0x908a, 0x0100, 0x0a04, 0x35e5, 0x908a, 0x0841, 0x1a04, 0x35e5,
- 0x9084, 0x0007, 0x1904, 0x35e5, 0x680c, 0x9005, 0x0904, 0x35e5,
- 0x6810, 0x9005, 0x0904, 0x35e5, 0x6848, 0x6940, 0x910a, 0x1a04,
- 0x35e5, 0x8001, 0x0904, 0x35e5, 0x684c, 0x6944, 0x910a, 0x1a04,
- 0x35e5, 0x8001, 0x0904, 0x35e5, 0x2009, 0x1982, 0x200b, 0x0000,
- 0x2001, 0x1869, 0x2004, 0xd0c4, 0x0140, 0x7884, 0x200a, 0x2008,
- 0x080c, 0x0e52, 0x3b00, 0xc085, 0x20d8, 0x6814, 0x908c, 0x00ff,
- 0x614e, 0x8007, 0x9084, 0x00ff, 0x6052, 0x080c, 0x7879, 0x080c,
- 0x6ac2, 0x080c, 0x6b24, 0x6808, 0x602a, 0x080c, 0x239c, 0x2009,
- 0x0170, 0x200b, 0x0080, 0xa001, 0xa001, 0x200b, 0x0000, 0x0036,
- 0x6b08, 0x080c, 0x292c, 0x003e, 0x6000, 0x9086, 0x0000, 0x1904,
- 0x449e, 0x6818, 0x691c, 0x6a20, 0x6b24, 0x8007, 0x810f, 0x8217,
- 0x831f, 0x6016, 0x611a, 0x621e, 0x6322, 0x6c04, 0xd4f4, 0x0148,
- 0x6830, 0x6934, 0x6a38, 0x6b3c, 0x8007, 0x810f, 0x8217, 0x831f,
- 0x0010, 0x9084, 0xf0ff, 0x6006, 0x610a, 0x620e, 0x6312, 0x8007,
- 0x810f, 0x8217, 0x831f, 0x20a9, 0x0004, 0x20a1, 0x19b5, 0x20e9,
- 0x0001, 0x4001, 0x20a9, 0x0004, 0x20a1, 0x19cf, 0x20e9, 0x0001,
- 0x4001, 0x080c, 0x8828, 0x00c6, 0x900e, 0x20a9, 0x0001, 0x6b70,
- 0xd384, 0x0510, 0x0068, 0x2009, 0x0100, 0x210c, 0x918e, 0x0008,
- 0x1110, 0x839d, 0x0010, 0x83f5, 0x3e18, 0x12b0, 0x3508, 0x8109,
- 0x080c, 0x7e35, 0x6878, 0x6016, 0x6874, 0x2008, 0x9084, 0xff00,
- 0x8007, 0x600a, 0x9184, 0x00ff, 0x6006, 0x8108, 0x1118, 0x6003,
- 0x0003, 0x0010, 0x6003, 0x0001, 0x1f04, 0x43f3, 0x00ce, 0x00c6,
- 0x2061, 0x199d, 0x6a88, 0x9284, 0xc000, 0x2010, 0x9286, 0x0000,
- 0x1158, 0x2063, 0x0000, 0x2001, 0x0001, 0x080c, 0x2bd3, 0x2001,
- 0x0001, 0x080c, 0x2bb6, 0x0088, 0x9286, 0x4000, 0x1148, 0x2063,
- 0x0001, 0x9006, 0x080c, 0x2bd3, 0x9006, 0x080c, 0x2bb6, 0x0028,
- 0x9286, 0x8000, 0x1d30, 0x2063, 0x0002, 0x00ce, 0x00e6, 0x2c70,
- 0x080c, 0x0ea3, 0x00ee, 0x6888, 0xd0ec, 0x0130, 0x2011, 0x0114,
- 0x2204, 0x9085, 0x0100, 0x2012, 0x6a80, 0x9284, 0x0030, 0x9086,
- 0x0030, 0x1128, 0x9294, 0xffcf, 0x9295, 0x0020, 0x6a82, 0x2001,
- 0x197d, 0x6a80, 0x9294, 0x0030, 0x928e, 0x0000, 0x0170, 0x928e,
- 0x0010, 0x0118, 0x928e, 0x0020, 0x0140, 0x2003, 0xaaaa, 0x080c,
- 0x29a1, 0x2001, 0x196e, 0x2102, 0x0008, 0x2102, 0x00c6, 0x2061,
- 0x0100, 0x602f, 0x0040, 0x602f, 0x0000, 0x00ce, 0x080c, 0x7563,
- 0x0128, 0x080c, 0x50c3, 0x0110, 0x080c, 0x28f2, 0x60d4, 0x9005,
- 0x01c0, 0x6003, 0x0001, 0x2009, 0x4486, 0x00e0, 0x080c, 0x7563,
- 0x1168, 0x2011, 0x73de, 0x080c, 0x8703, 0x2011, 0x73d1, 0x080c,
- 0x87dd, 0x080c, 0x784d, 0x080c, 0x748f, 0x0040, 0x080c, 0x5fe0,
- 0x0028, 0x6003, 0x0004, 0x2009, 0x449e, 0x0020, 0x080c, 0x69ee,
- 0x0804, 0x35b0, 0x2001, 0x0170, 0x2004, 0x9084, 0x00ff, 0x9086,
- 0x004c, 0x1118, 0x2091, 0x30bd, 0x0817, 0x2091, 0x303d, 0x0817,
- 0x6000, 0x9086, 0x0000, 0x0904, 0x35e2, 0x2069, 0x1847, 0x7890,
- 0x6842, 0x7894, 0x6846, 0x2d00, 0x2009, 0x0030, 0x7a8c, 0x7b88,
- 0x7c9c, 0x7d98, 0x2039, 0x0001, 0x0804, 0x4bcf, 0x9006, 0x080c,
- 0x28f2, 0x81ff, 0x1904, 0x35e2, 0x080c, 0x7563, 0x11b0, 0x080c,
- 0x7848, 0x080c, 0x6121, 0x080c, 0x33a5, 0x0118, 0x6130, 0xc18d,
- 0x6132, 0x080c, 0xd548, 0x0130, 0x080c, 0x7586, 0x1118, 0x080c,
- 0x753b, 0x0038, 0x080c, 0x748f, 0x0020, 0x080c, 0x60e6, 0x080c,
- 0x5fe0, 0x0804, 0x35b0, 0x81ff, 0x1904, 0x35e2, 0x080c, 0x7563,
- 0x1110, 0x0804, 0x35e2, 0x0126, 0x2091, 0x8000, 0x6194, 0x81ff,
- 0x0190, 0x704f, 0x0000, 0x2001, 0x1c80, 0x2009, 0x0040, 0x7a8c,
- 0x7b88, 0x7c9c, 0x7d98, 0x2039, 0x0001, 0x080c, 0x4bcf, 0x701f,
- 0x35ae, 0x012e, 0x0005, 0x704f, 0x0001, 0x00d6, 0x2069, 0x1c80,
- 0x20a9, 0x0040, 0x20e9, 0x0001, 0x20a1, 0x1c80, 0x2019, 0xffff,
- 0x4304, 0x655c, 0x9588, 0x33b1, 0x210d, 0x918c, 0x00ff, 0x216a,
- 0x900e, 0x2011, 0x0002, 0x2100, 0x9506, 0x01a8, 0x080c, 0x6717,
- 0x1190, 0xb814, 0x821c, 0x0238, 0x9398, 0x1c80, 0x9085, 0xff00,
- 0x8007, 0x201a, 0x0038, 0x9398, 0x1c80, 0x2324, 0x94a4, 0xff00,
- 0x9405, 0x201a, 0x8210, 0x8108, 0x9182, 0x0080, 0x1208, 0x0c18,
- 0x8201, 0x8007, 0x2d0c, 0x9105, 0x206a, 0x00de, 0x20a9, 0x0040,
- 0x20a1, 0x1c80, 0x2099, 0x1c80, 0x080c, 0x6071, 0x0804, 0x44fb,
- 0x080c, 0x4bb6, 0x0904, 0x35e5, 0x080c, 0x4b83, 0x1120, 0x2009,
- 0x0002, 0x0804, 0x35e2, 0x080c, 0x57cd, 0xd0b4, 0x0558, 0x7884,
- 0x908e, 0x007e, 0x0538, 0x908e, 0x007f, 0x0520, 0x908e, 0x0080,
- 0x0508, 0x080c, 0x33a0, 0x1148, 0xb800, 0xd08c, 0x11d8, 0xb804,
- 0x9084, 0x00ff, 0x9086, 0x0006, 0x11a8, 0xa867, 0x0000, 0xa868,
- 0xc0fd, 0xa86a, 0x080c, 0xd00a, 0x1120, 0x2009, 0x0003, 0x0804,
- 0x35e2, 0x7007, 0x0003, 0x701f, 0x4586, 0x0005, 0x080c, 0x4bb6,
- 0x0904, 0x35e5, 0x20a9, 0x002b, 0xb8c4, 0x20e0, 0xb8c8, 0x2098,
- 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0002, 0x20a0, 0x4003, 0x20a9,
- 0x0008, 0x9080, 0x0006, 0x20a0, 0xb8c4, 0x20e0, 0xb8c8, 0x9080,
- 0x0006, 0x2098, 0x080c, 0x0f8b, 0x0070, 0x20a9, 0x0004, 0xa85c,
- 0x9080, 0x000a, 0x20a0, 0xb8c4, 0x20e0, 0xb8c8, 0x9080, 0x000a,
- 0x2098, 0x080c, 0x0f8b, 0x8906, 0x8006, 0x8007, 0x90bc, 0x003f,
- 0x9084, 0xffc0, 0x9080, 0x0002, 0x2009, 0x002b, 0x7a8c, 0x7b88,
- 0x7c9c, 0x7d98, 0x0804, 0x4bcf, 0x81ff, 0x1904, 0x35e2, 0x080c,
- 0x4b9a, 0x0904, 0x35e5, 0x080c, 0x6889, 0x0904, 0x35e2, 0x0058,
- 0xa878, 0x9005, 0x0120, 0x2009, 0x0004, 0x0804, 0x35e2, 0xa974,
- 0xaa94, 0x0804, 0x35b0, 0x080c, 0x57d5, 0x0904, 0x35b0, 0x701f,
- 0x45d0, 0x7007, 0x0003, 0x0005, 0x81ff, 0x1904, 0x35e2, 0x7888,
- 0x908a, 0x1000, 0x1a04, 0x35e5, 0x080c, 0x4bb6, 0x0904, 0x35e5,
- 0x080c, 0x6a8c, 0x0120, 0x080c, 0x6a94, 0x1904, 0x35e5, 0x080c,
- 0x690e, 0x0904, 0x35e2, 0x2019, 0x0004, 0x900e, 0x080c, 0x689b,
- 0x0904, 0x35e2, 0x7984, 0x7a88, 0x04c9, 0x08a8, 0xa89c, 0x908a,
- 0x1000, 0x12f8, 0x080c, 0x4bb4, 0x01e0, 0x080c, 0x6a8c, 0x0118,
- 0x080c, 0x6a94, 0x11b0, 0x080c, 0x690e, 0x2009, 0x0002, 0x0168,
- 0x2009, 0x0002, 0x2019, 0x0004, 0x080c, 0x689b, 0x2009, 0x0003,
- 0x0120, 0xa998, 0xaa9c, 0x00d1, 0x0060, 0xa897, 0x4005, 0xa99a,
- 0x0010, 0xa897, 0x4006, 0x900e, 0x9085, 0x0001, 0x2001, 0x0030,
- 0x0005, 0xa897, 0x4000, 0x080c, 0x57d5, 0x0110, 0x9006, 0x0018,
- 0x900e, 0x9085, 0x0001, 0x2001, 0x0000, 0x0005, 0x9186, 0x00ff,
- 0x0110, 0x0071, 0x0060, 0x2029, 0x007e, 0x2061, 0x1800, 0x645c,
- 0x2400, 0x9506, 0x0110, 0x2508, 0x0019, 0x8529, 0x1ec8, 0x0005,
- 0x080c, 0x6717, 0x1138, 0x2200, 0x8003, 0x800b, 0x810b, 0x9108,
- 0x080c, 0x8711, 0x0005, 0x81ff, 0x1904, 0x35e2, 0x798c, 0x2001,
- 0x1981, 0x918c, 0x8000, 0x2102, 0x080c, 0x4b9a, 0x0904, 0x35e5,
- 0x080c, 0x6a8c, 0x0120, 0x080c, 0x6a94, 0x1904, 0x35e5, 0x080c,
- 0x67de, 0x0904, 0x35e2, 0x080c, 0x6892, 0x0904, 0x35e2, 0x2001,
- 0x1981, 0x2004, 0xd0fc, 0x1904, 0x35b0, 0x0804, 0x45db, 0xa9a0,
- 0x2001, 0x1981, 0x918c, 0x8000, 0xc18d, 0x2102, 0x080c, 0x4ba7,
- 0x01a0, 0x080c, 0x6a8c, 0x0118, 0x080c, 0x6a94, 0x1170, 0x080c,
- 0x67de, 0x2009, 0x0002, 0x0128, 0x080c, 0x6892, 0x1170, 0x2009,
- 0x0003, 0xa897, 0x4005, 0xa99a, 0x0010, 0xa897, 0x4006, 0x900e,
- 0x9085, 0x0001, 0x2001, 0x0030, 0x0005, 0xa897, 0x4000, 0x2001,
- 0x1981, 0x2004, 0xd0fc, 0x1128, 0x080c, 0x57d5, 0x0110, 0x9006,
- 0x0018, 0x900e, 0x9085, 0x0001, 0x2001, 0x0000, 0x0005, 0x81ff,
- 0x1904, 0x35e2, 0x798c, 0x2001, 0x1980, 0x918c, 0x8000, 0x2102,
- 0x080c, 0x4b9a, 0x0904, 0x35e5, 0x080c, 0x6a8c, 0x0120, 0x080c,
- 0x6a94, 0x1904, 0x35e5, 0x080c, 0x67de, 0x0904, 0x35e2, 0x080c,
- 0x6880, 0x0904, 0x35e2, 0x2001, 0x1980, 0x2004, 0xd0fc, 0x1904,
- 0x35b0, 0x0804, 0x45db, 0xa9a0, 0x2001, 0x1980, 0x918c, 0x8000,
- 0xc18d, 0x2102, 0x080c, 0x4ba7, 0x01a0, 0x080c, 0x6a8c, 0x0118,
- 0x080c, 0x6a94, 0x1170, 0x080c, 0x67de, 0x2009, 0x0002, 0x0128,
- 0x080c, 0x6880, 0x1170, 0x2009, 0x0003, 0xa897, 0x4005, 0xa99a,
- 0x0010, 0xa897, 0x4006, 0x900e, 0x9085, 0x0001, 0x2001, 0x0030,
- 0x0005, 0xa897, 0x4000, 0x2001, 0x1980, 0x2004, 0xd0fc, 0x1128,
- 0x080c, 0x57d5, 0x0110, 0x9006, 0x0018, 0x900e, 0x9085, 0x0001,
- 0x2001, 0x0000, 0x0005, 0x6100, 0x0804, 0x35b0, 0x080c, 0x4bb6,
- 0x0904, 0x35e5, 0x080c, 0x57e1, 0x1904, 0x35e2, 0x79a8, 0xd184,
- 0x1158, 0xb834, 0x8007, 0x789e, 0xb830, 0x8007, 0x789a, 0xbb2c,
- 0x831f, 0xba28, 0x8217, 0x0050, 0xb824, 0x8007, 0x789e, 0xb820,
- 0x8007, 0x789a, 0xbb1c, 0x831f, 0xba18, 0x8217, 0xb900, 0x918c,
- 0x0202, 0x0804, 0x35b0, 0x78a8, 0x909c, 0x0003, 0xd0ac, 0x1158,
- 0xd0b4, 0x1148, 0x939a, 0x0003, 0x1a04, 0x35e2, 0x625c, 0x7884,
- 0x9206, 0x1904, 0x4796, 0x080c, 0x8812, 0x2001, 0xffec, 0x2009,
- 0x000c, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0x2039, 0x0000, 0x0006,
- 0x78a8, 0x9084, 0x0080, 0x1528, 0x0006, 0x0036, 0x2001, 0x1a84,
- 0x201c, 0x7b9a, 0x2003, 0x0000, 0x2001, 0x1a85, 0x201c, 0x7b9e,
- 0x2003, 0x0000, 0x2001, 0x1a86, 0x201c, 0x7bae, 0x2003, 0x0000,
- 0x2001, 0x1a80, 0x201c, 0x7baa, 0x2003, 0x0000, 0x2001, 0x1a87,
- 0x201c, 0x7bb2, 0x2003, 0x0000, 0x003e, 0x000e, 0x000e, 0x0804,
- 0x4bcf, 0x000e, 0x2031, 0x0000, 0x2061, 0x18b8, 0x2c44, 0xa66a,
- 0xa17a, 0xa772, 0xa076, 0xa28e, 0xa392, 0xa496, 0xa59a, 0x080c,
- 0x10f8, 0x7007, 0x0002, 0x701f, 0x47b6, 0x0005, 0x81ff, 0x1904,
- 0x35e2, 0x080c, 0x4bb6, 0x0904, 0x35e5, 0x080c, 0x6a8c, 0x1904,
- 0x35e2, 0x00c6, 0x080c, 0x4b83, 0x00ce, 0x0904, 0x35e2, 0xa867,
- 0x0000, 0xa868, 0xc0fd, 0xa86a, 0x7ea8, 0x080c, 0xcfb0, 0x0904,
- 0x35e2, 0x7007, 0x0003, 0x701f, 0x47dc, 0x0005, 0x080c, 0x42c8,
- 0x0006, 0x0036, 0x2001, 0x1a84, 0x201c, 0x7b9a, 0x2003, 0x0000,
- 0x2001, 0x1a85, 0x201c, 0x7b9e, 0x2003, 0x0000, 0x2001, 0x1a86,
- 0x201c, 0x7bae, 0x2003, 0x0000, 0x2001, 0x1a80, 0x201c, 0x7baa,
- 0x2003, 0x0000, 0x2001, 0x1a87, 0x201c, 0x7bb2, 0x2003, 0x0000,
- 0x003e, 0x000e, 0x0804, 0x35b0, 0xa830, 0x9086, 0x0100, 0x0904,
- 0x35e2, 0x8906, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0,
- 0x9080, 0x001b, 0x2009, 0x000c, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98,
- 0x0804, 0x4bcf, 0x9006, 0x080c, 0x28f2, 0x78a8, 0x9084, 0x00ff,
- 0x9086, 0x00ff, 0x0118, 0x81ff, 0x1904, 0x35e2, 0x080c, 0x7563,
- 0x0110, 0x080c, 0x60e6, 0x7888, 0x908a, 0x1000, 0x1a04, 0x35e5,
- 0x7984, 0x9186, 0x00ff, 0x0138, 0x9182, 0x007f, 0x1a04, 0x35e5,
- 0x2100, 0x080c, 0x28bc, 0x0026, 0x00c6, 0x0126, 0x2091, 0x8000,
- 0x2061, 0x19fc, 0x601b, 0x0000, 0x601f, 0x0000, 0x607b, 0x0000,
- 0x607f, 0x0000, 0x080c, 0x7563, 0x1158, 0x080c, 0x7848, 0x080c,
- 0x6121, 0x9085, 0x0001, 0x080c, 0x75a7, 0x080c, 0x748f, 0x00d0,
- 0x080c, 0xb058, 0x2061, 0x0100, 0x2001, 0x1818, 0x2004, 0x9084,
- 0x00ff, 0x810f, 0x9105, 0x604a, 0x6043, 0x0090, 0x6043, 0x0010,
- 0x2009, 0x199a, 0x200b, 0x0000, 0x2009, 0x002d, 0x2011, 0x600c,
- 0x080c, 0x879b, 0x7984, 0x080c, 0x7563, 0x1110, 0x2009, 0x00ff,
- 0x7a88, 0x080c, 0x463e, 0x012e, 0x00ce, 0x002e, 0x0804, 0x35b0,
- 0x7984, 0x080c, 0x66ac, 0x2b08, 0x1904, 0x35e5, 0x0804, 0x35b0,
- 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x35e2, 0x60dc, 0xd0ac,
- 0x1130, 0xd09c, 0x1120, 0x2009, 0x0005, 0x0804, 0x35e2, 0x080c,
- 0x4b83, 0x1120, 0x2009, 0x0002, 0x0804, 0x35e2, 0x7984, 0x81ff,
- 0x0904, 0x35e5, 0x9192, 0x0021, 0x1a04, 0x35e5, 0x7a8c, 0x7b88,
- 0x7c9c, 0x7d98, 0xa85c, 0x9080, 0x0019, 0x702a, 0xaf60, 0x7736,
- 0x080c, 0x4bcc, 0x701f, 0x4893, 0x7880, 0x9086, 0x006e, 0x0110,
- 0x701f, 0x5275, 0x0005, 0x2009, 0x0080, 0x080c, 0x6717, 0x1118,
- 0x080c, 0x6a8c, 0x0120, 0x2021, 0x400a, 0x0804, 0x35b2, 0x00d6,
- 0x0096, 0xa964, 0xaa6c, 0xab70, 0xac74, 0xad78, 0xae7c, 0xa884,
- 0x90be, 0x0100, 0x0904, 0x492c, 0x90be, 0x0112, 0x0904, 0x492c,
- 0x90be, 0x0113, 0x0904, 0x492c, 0x90be, 0x0114, 0x0904, 0x492c,
- 0x90be, 0x0117, 0x0904, 0x492c, 0x90be, 0x011a, 0x0904, 0x492c,
- 0x90be, 0x011c, 0x0904, 0x492c, 0x90be, 0x0121, 0x0904, 0x4913,
- 0x90be, 0x0131, 0x0904, 0x4913, 0x90be, 0x0171, 0x0904, 0x492c,
- 0x90be, 0x0173, 0x0904, 0x492c, 0x90be, 0x01a1, 0x1128, 0xa894,
- 0x8007, 0xa896, 0x0804, 0x4937, 0x90be, 0x0212, 0x0904, 0x4920,
- 0x90be, 0x0213, 0x05e8, 0x90be, 0x0214, 0x0500, 0x90be, 0x0217,
- 0x0188, 0x90be, 0x021a, 0x1120, 0xa89c, 0x8007, 0xa89e, 0x04e0,
- 0x90be, 0x021f, 0x05c8, 0x90be, 0x0300, 0x05b0, 0x009e, 0x00de,
- 0x0804, 0x35e5, 0x7028, 0x9080, 0x0010, 0x2098, 0x20a0, 0x7034,
- 0x20e0, 0x20e8, 0x20a9, 0x0007, 0x080c, 0x4975, 0x7028, 0x9080,
+ 0x8000, 0x20a9, 0x0007, 0x20a1, 0x1840, 0x20e9, 0x0001, 0x9006,
+ 0x4004, 0x20a9, 0x0014, 0x20a1, 0xffec, 0x20e9, 0x0000, 0x9006,
+ 0x4004, 0x2009, 0x013c, 0x200a, 0x012e, 0x7880, 0x9086, 0x0052,
+ 0x0108, 0x0005, 0x0804, 0x35ab, 0x7d98, 0x7c9c, 0x0804, 0x36af,
+ 0x080c, 0x7569, 0x190c, 0x60ec, 0x6040, 0x9084, 0x0020, 0x09b1,
+ 0x2069, 0x1847, 0x2d00, 0x2009, 0x0030, 0x7a8c, 0x7b88, 0x7c9c,
+ 0x7d98, 0x2039, 0x0001, 0x080c, 0x4bd2, 0x701f, 0x4308, 0x0005,
+ 0x080c, 0x57e2, 0x1130, 0x3b00, 0x3a08, 0xc194, 0xc095, 0x20d8,
+ 0x21d0, 0x2069, 0x1847, 0x6800, 0x9005, 0x0904, 0x35e0, 0x6804,
+ 0xd0ac, 0x0118, 0xd0a4, 0x0904, 0x35e0, 0xd094, 0x00c6, 0x2061,
+ 0x0100, 0x6104, 0x0138, 0x6200, 0x9292, 0x0005, 0x0218, 0x918c,
+ 0xffdf, 0x0010, 0x918d, 0x0020, 0x6106, 0x00ce, 0xd08c, 0x00c6,
+ 0x2061, 0x0100, 0x6104, 0x0118, 0x918d, 0x0010, 0x0010, 0x918c,
+ 0xffef, 0x6106, 0x00ce, 0xd084, 0x0158, 0x6a28, 0x928a, 0x007f,
+ 0x1a04, 0x35e0, 0x9288, 0x33ac, 0x210d, 0x918c, 0x00ff, 0x6166,
+ 0xd0dc, 0x0130, 0x6828, 0x908a, 0x007f, 0x1a04, 0x35e0, 0x605e,
+ 0x6888, 0x9084, 0x0030, 0x8004, 0x8004, 0x8004, 0x8004, 0x0006,
+ 0x2009, 0x19b3, 0x9080, 0x29d0, 0x2005, 0x200a, 0x000e, 0x2009,
+ 0x19b4, 0x9080, 0x29d4, 0x2005, 0x200a, 0x6808, 0x908a, 0x0100,
+ 0x0a04, 0x35e0, 0x908a, 0x0841, 0x1a04, 0x35e0, 0x9084, 0x0007,
+ 0x1904, 0x35e0, 0x680c, 0x9005, 0x0904, 0x35e0, 0x6810, 0x9005,
+ 0x0904, 0x35e0, 0x6848, 0x6940, 0x910a, 0x1a04, 0x35e0, 0x8001,
+ 0x0904, 0x35e0, 0x684c, 0x6944, 0x910a, 0x1a04, 0x35e0, 0x8001,
+ 0x0904, 0x35e0, 0x2009, 0x1982, 0x200b, 0x0000, 0x2001, 0x1869,
+ 0x2004, 0xd0c4, 0x0140, 0x7884, 0x200a, 0x2008, 0x080c, 0x0e52,
+ 0x3b00, 0xc085, 0x20d8, 0x6814, 0x908c, 0x00ff, 0x614e, 0x8007,
+ 0x9084, 0x00ff, 0x6052, 0x080c, 0x787f, 0x080c, 0x6ac8, 0x080c,
+ 0x6b2a, 0x6808, 0x602a, 0x080c, 0x23a4, 0x2009, 0x0170, 0x200b,
+ 0x0080, 0xa001, 0xa001, 0x200b, 0x0000, 0x0036, 0x6b08, 0x080c,
+ 0x2937, 0x003e, 0x6000, 0x9086, 0x0000, 0x1904, 0x44a4, 0x6818,
+ 0x691c, 0x6a20, 0x6b24, 0x8007, 0x810f, 0x8217, 0x831f, 0x6016,
+ 0x611a, 0x621e, 0x6322, 0x6c04, 0xd4f4, 0x0148, 0x6830, 0x6934,
+ 0x6a38, 0x6b3c, 0x8007, 0x810f, 0x8217, 0x831f, 0x0010, 0x9084,
+ 0xf0ff, 0x6006, 0x610a, 0x620e, 0x6312, 0x8007, 0x810f, 0x8217,
+ 0x831f, 0x20a9, 0x0004, 0x20a1, 0x19b5, 0x20e9, 0x0001, 0x4001,
+ 0x20a9, 0x0004, 0x20a1, 0x19cf, 0x20e9, 0x0001, 0x4001, 0x080c,
+ 0x882e, 0x00c6, 0x900e, 0x20a9, 0x0001, 0x6b70, 0xd384, 0x0510,
+ 0x0068, 0x2009, 0x0100, 0x210c, 0x918e, 0x0008, 0x1110, 0x839d,
+ 0x0010, 0x83f5, 0x3e18, 0x12b0, 0x3508, 0x8109, 0x080c, 0x7e3b,
+ 0x6878, 0x6016, 0x6874, 0x2008, 0x9084, 0xff00, 0x8007, 0x600a,
+ 0x9184, 0x00ff, 0x6006, 0x8108, 0x1118, 0x6003, 0x0003, 0x0010,
+ 0x6003, 0x0001, 0x1f04, 0x43f9, 0x00ce, 0x00c6, 0x2061, 0x199d,
+ 0x6a88, 0x9284, 0xc000, 0x2010, 0x9286, 0x0000, 0x1158, 0x2063,
+ 0x0000, 0x2001, 0x0001, 0x080c, 0x2bca, 0x2001, 0x0001, 0x080c,
+ 0x2bad, 0x0088, 0x9286, 0x4000, 0x1148, 0x2063, 0x0001, 0x9006,
+ 0x080c, 0x2bca, 0x9006, 0x080c, 0x2bad, 0x0028, 0x9286, 0x8000,
+ 0x1d30, 0x2063, 0x0002, 0x00ce, 0x00e6, 0x2c70, 0x080c, 0x0ea3,
+ 0x00ee, 0x6888, 0xd0ec, 0x0130, 0x2011, 0x0114, 0x2204, 0x9085,
+ 0x0100, 0x2012, 0x6a80, 0x9284, 0x0030, 0x9086, 0x0030, 0x1128,
+ 0x9294, 0xffcf, 0x9295, 0x0020, 0x6a82, 0x2001, 0x197d, 0x6a80,
+ 0x9294, 0x0030, 0x928e, 0x0000, 0x0170, 0x928e, 0x0010, 0x0118,
+ 0x928e, 0x0020, 0x0140, 0x2003, 0xaaaa, 0x080c, 0x29ac, 0x2001,
+ 0x196e, 0x2102, 0x0008, 0x2102, 0x00c6, 0x2061, 0x0100, 0x602f,
+ 0x0040, 0x602f, 0x0000, 0x00ce, 0x080c, 0x7569, 0x0128, 0x080c,
+ 0x50c9, 0x0110, 0x080c, 0x28fd, 0x60d4, 0x9005, 0x01c0, 0x6003,
+ 0x0001, 0x2009, 0x448c, 0x00e0, 0x080c, 0x7569, 0x1168, 0x2011,
+ 0x73e4, 0x080c, 0x8709, 0x2011, 0x73d7, 0x080c, 0x87e3, 0x080c,
+ 0x7853, 0x080c, 0x7495, 0x0040, 0x080c, 0x5fe6, 0x0028, 0x6003,
+ 0x0004, 0x2009, 0x44a4, 0x0020, 0x080c, 0x69f4, 0x0804, 0x35ab,
+ 0x2001, 0x0170, 0x2004, 0x9084, 0x00ff, 0x9086, 0x004c, 0x1118,
+ 0x2091, 0x30bd, 0x0817, 0x2091, 0x303d, 0x0817, 0x6000, 0x9086,
+ 0x0000, 0x0904, 0x35dd, 0x2069, 0x1847, 0x7890, 0x6842, 0x7894,
+ 0x6846, 0x2d00, 0x2009, 0x0030, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98,
+ 0x2039, 0x0001, 0x0804, 0x4bd5, 0x9006, 0x080c, 0x28fd, 0x81ff,
+ 0x1904, 0x35dd, 0x080c, 0x7569, 0x11b0, 0x080c, 0x784e, 0x080c,
+ 0x6127, 0x080c, 0x33a0, 0x0118, 0x6130, 0xc18d, 0x6132, 0x080c,
+ 0xd561, 0x0130, 0x080c, 0x758c, 0x1118, 0x080c, 0x7541, 0x0038,
+ 0x080c, 0x7495, 0x0020, 0x080c, 0x60ec, 0x080c, 0x5fe6, 0x0804,
+ 0x35ab, 0x81ff, 0x1904, 0x35dd, 0x080c, 0x7569, 0x1110, 0x0804,
+ 0x35dd, 0x0126, 0x2091, 0x8000, 0x6194, 0x81ff, 0x0190, 0x704f,
+ 0x0000, 0x2001, 0x1c80, 0x2009, 0x0040, 0x7a8c, 0x7b88, 0x7c9c,
+ 0x7d98, 0x2039, 0x0001, 0x080c, 0x4bd5, 0x701f, 0x35a9, 0x012e,
+ 0x0005, 0x704f, 0x0001, 0x00d6, 0x2069, 0x1c80, 0x20a9, 0x0040,
+ 0x20e9, 0x0001, 0x20a1, 0x1c80, 0x2019, 0xffff, 0x4304, 0x655c,
+ 0x9588, 0x33ac, 0x210d, 0x918c, 0x00ff, 0x216a, 0x900e, 0x2011,
+ 0x0002, 0x2100, 0x9506, 0x01a8, 0x080c, 0x671d, 0x1190, 0xb814,
+ 0x821c, 0x0238, 0x9398, 0x1c80, 0x9085, 0xff00, 0x8007, 0x201a,
+ 0x0038, 0x9398, 0x1c80, 0x2324, 0x94a4, 0xff00, 0x9405, 0x201a,
+ 0x8210, 0x8108, 0x9182, 0x0080, 0x1208, 0x0c18, 0x8201, 0x8007,
+ 0x2d0c, 0x9105, 0x206a, 0x00de, 0x20a9, 0x0040, 0x20a1, 0x1c80,
+ 0x2099, 0x1c80, 0x080c, 0x6077, 0x0804, 0x4501, 0x080c, 0x4bbc,
+ 0x0904, 0x35e0, 0x080c, 0x4b89, 0x1120, 0x2009, 0x0002, 0x0804,
+ 0x35dd, 0x080c, 0x57d3, 0xd0b4, 0x0558, 0x7884, 0x908e, 0x007e,
+ 0x0538, 0x908e, 0x007f, 0x0520, 0x908e, 0x0080, 0x0508, 0x080c,
+ 0x339b, 0x1148, 0xb800, 0xd08c, 0x11d8, 0xb804, 0x9084, 0x00ff,
+ 0x9086, 0x0006, 0x11a8, 0xa867, 0x0000, 0xa868, 0xc0fd, 0xa86a,
+ 0x080c, 0xd021, 0x1120, 0x2009, 0x0003, 0x0804, 0x35dd, 0x7007,
+ 0x0003, 0x701f, 0x458c, 0x0005, 0x080c, 0x4bbc, 0x0904, 0x35e0,
+ 0x20a9, 0x002b, 0xb8c4, 0x20e0, 0xb8c8, 0x2098, 0xa860, 0x20e8,
+ 0xa85c, 0x9080, 0x0002, 0x20a0, 0x4003, 0x20a9, 0x0008, 0x9080,
+ 0x0006, 0x20a0, 0xb8c4, 0x20e0, 0xb8c8, 0x9080, 0x0006, 0x2098,
+ 0x080c, 0x0f8b, 0x0070, 0x20a9, 0x0004, 0xa85c, 0x9080, 0x000a,
+ 0x20a0, 0xb8c4, 0x20e0, 0xb8c8, 0x9080, 0x000a, 0x2098, 0x080c,
+ 0x0f8b, 0x8906, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0,
+ 0x9080, 0x0002, 0x2009, 0x002b, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98,
+ 0x0804, 0x4bd5, 0x81ff, 0x1904, 0x35dd, 0x080c, 0x4ba0, 0x0904,
+ 0x35e0, 0x080c, 0x688f, 0x0904, 0x35dd, 0x0058, 0xa878, 0x9005,
+ 0x0120, 0x2009, 0x0004, 0x0804, 0x35dd, 0xa974, 0xaa94, 0x0804,
+ 0x35ab, 0x080c, 0x57db, 0x0904, 0x35ab, 0x701f, 0x45d6, 0x7007,
+ 0x0003, 0x0005, 0x81ff, 0x1904, 0x35dd, 0x7888, 0x908a, 0x1000,
+ 0x1a04, 0x35e0, 0x080c, 0x4bbc, 0x0904, 0x35e0, 0x080c, 0x6a92,
+ 0x0120, 0x080c, 0x6a9a, 0x1904, 0x35e0, 0x080c, 0x6914, 0x0904,
+ 0x35dd, 0x2019, 0x0004, 0x900e, 0x080c, 0x68a1, 0x0904, 0x35dd,
+ 0x7984, 0x7a88, 0x04c9, 0x08a8, 0xa89c, 0x908a, 0x1000, 0x12f8,
+ 0x080c, 0x4bba, 0x01e0, 0x080c, 0x6a92, 0x0118, 0x080c, 0x6a9a,
+ 0x11b0, 0x080c, 0x6914, 0x2009, 0x0002, 0x0168, 0x2009, 0x0002,
+ 0x2019, 0x0004, 0x080c, 0x68a1, 0x2009, 0x0003, 0x0120, 0xa998,
+ 0xaa9c, 0x00d1, 0x0060, 0xa897, 0x4005, 0xa99a, 0x0010, 0xa897,
+ 0x4006, 0x900e, 0x9085, 0x0001, 0x2001, 0x0030, 0x0005, 0xa897,
+ 0x4000, 0x080c, 0x57db, 0x0110, 0x9006, 0x0018, 0x900e, 0x9085,
+ 0x0001, 0x2001, 0x0000, 0x0005, 0x9186, 0x00ff, 0x0110, 0x0071,
+ 0x0060, 0x2029, 0x007e, 0x2061, 0x1800, 0x645c, 0x2400, 0x9506,
+ 0x0110, 0x2508, 0x0019, 0x8529, 0x1ec8, 0x0005, 0x080c, 0x671d,
+ 0x1138, 0x2200, 0x8003, 0x800b, 0x810b, 0x9108, 0x080c, 0x8717,
+ 0x0005, 0x81ff, 0x1904, 0x35dd, 0x798c, 0x2001, 0x1981, 0x918c,
+ 0x8000, 0x2102, 0x080c, 0x4ba0, 0x0904, 0x35e0, 0x080c, 0x6a92,
+ 0x0120, 0x080c, 0x6a9a, 0x1904, 0x35e0, 0x080c, 0x67e4, 0x0904,
+ 0x35dd, 0x080c, 0x6898, 0x0904, 0x35dd, 0x2001, 0x1981, 0x2004,
+ 0xd0fc, 0x1904, 0x35ab, 0x0804, 0x45e1, 0xa9a0, 0x2001, 0x1981,
+ 0x918c, 0x8000, 0xc18d, 0x2102, 0x080c, 0x4bad, 0x01a0, 0x080c,
+ 0x6a92, 0x0118, 0x080c, 0x6a9a, 0x1170, 0x080c, 0x67e4, 0x2009,
+ 0x0002, 0x0128, 0x080c, 0x6898, 0x1170, 0x2009, 0x0003, 0xa897,
+ 0x4005, 0xa99a, 0x0010, 0xa897, 0x4006, 0x900e, 0x9085, 0x0001,
+ 0x2001, 0x0030, 0x0005, 0xa897, 0x4000, 0x2001, 0x1981, 0x2004,
+ 0xd0fc, 0x1128, 0x080c, 0x57db, 0x0110, 0x9006, 0x0018, 0x900e,
+ 0x9085, 0x0001, 0x2001, 0x0000, 0x0005, 0x81ff, 0x1904, 0x35dd,
+ 0x798c, 0x2001, 0x1980, 0x918c, 0x8000, 0x2102, 0x080c, 0x4ba0,
+ 0x0904, 0x35e0, 0x080c, 0x6a92, 0x0120, 0x080c, 0x6a9a, 0x1904,
+ 0x35e0, 0x080c, 0x67e4, 0x0904, 0x35dd, 0x080c, 0x6886, 0x0904,
+ 0x35dd, 0x2001, 0x1980, 0x2004, 0xd0fc, 0x1904, 0x35ab, 0x0804,
+ 0x45e1, 0xa9a0, 0x2001, 0x1980, 0x918c, 0x8000, 0xc18d, 0x2102,
+ 0x080c, 0x4bad, 0x01a0, 0x080c, 0x6a92, 0x0118, 0x080c, 0x6a9a,
+ 0x1170, 0x080c, 0x67e4, 0x2009, 0x0002, 0x0128, 0x080c, 0x6886,
+ 0x1170, 0x2009, 0x0003, 0xa897, 0x4005, 0xa99a, 0x0010, 0xa897,
+ 0x4006, 0x900e, 0x9085, 0x0001, 0x2001, 0x0030, 0x0005, 0xa897,
+ 0x4000, 0x2001, 0x1980, 0x2004, 0xd0fc, 0x1128, 0x080c, 0x57db,
+ 0x0110, 0x9006, 0x0018, 0x900e, 0x9085, 0x0001, 0x2001, 0x0000,
+ 0x0005, 0x6100, 0x0804, 0x35ab, 0x080c, 0x4bbc, 0x0904, 0x35e0,
+ 0x080c, 0x57e7, 0x1904, 0x35dd, 0x79a8, 0xd184, 0x1158, 0xb834,
+ 0x8007, 0x789e, 0xb830, 0x8007, 0x789a, 0xbb2c, 0x831f, 0xba28,
+ 0x8217, 0x0050, 0xb824, 0x8007, 0x789e, 0xb820, 0x8007, 0x789a,
+ 0xbb1c, 0x831f, 0xba18, 0x8217, 0xb900, 0x918c, 0x0202, 0x0804,
+ 0x35ab, 0x78a8, 0x909c, 0x0003, 0xd0ac, 0x1158, 0xd0b4, 0x1148,
+ 0x939a, 0x0003, 0x1a04, 0x35dd, 0x625c, 0x7884, 0x9206, 0x1904,
+ 0x479c, 0x080c, 0x8818, 0x2001, 0xffec, 0x2009, 0x000c, 0x7a8c,
+ 0x7b88, 0x7c9c, 0x7d98, 0x2039, 0x0000, 0x0006, 0x78a8, 0x9084,
+ 0x0080, 0x1528, 0x0006, 0x0036, 0x2001, 0x1a84, 0x201c, 0x7b9a,
+ 0x2003, 0x0000, 0x2001, 0x1a85, 0x201c, 0x7b9e, 0x2003, 0x0000,
+ 0x2001, 0x1a86, 0x201c, 0x7bae, 0x2003, 0x0000, 0x2001, 0x1a80,
+ 0x201c, 0x7baa, 0x2003, 0x0000, 0x2001, 0x1a87, 0x201c, 0x7bb2,
+ 0x2003, 0x0000, 0x003e, 0x000e, 0x000e, 0x0804, 0x4bd5, 0x000e,
+ 0x2031, 0x0000, 0x2061, 0x18b8, 0x2c44, 0xa66a, 0xa17a, 0xa772,
+ 0xa076, 0xa28e, 0xa392, 0xa496, 0xa59a, 0x080c, 0x10f8, 0x7007,
+ 0x0002, 0x701f, 0x47bc, 0x0005, 0x81ff, 0x1904, 0x35dd, 0x080c,
+ 0x4bbc, 0x0904, 0x35e0, 0x080c, 0x6a92, 0x1904, 0x35dd, 0x00c6,
+ 0x080c, 0x4b89, 0x00ce, 0x0904, 0x35dd, 0xa867, 0x0000, 0xa868,
+ 0xc0fd, 0xa86a, 0x7ea8, 0x080c, 0xcfc7, 0x0904, 0x35dd, 0x7007,
+ 0x0003, 0x701f, 0x47e2, 0x0005, 0x080c, 0x42ce, 0x0006, 0x0036,
+ 0x2001, 0x1a84, 0x201c, 0x7b9a, 0x2003, 0x0000, 0x2001, 0x1a85,
+ 0x201c, 0x7b9e, 0x2003, 0x0000, 0x2001, 0x1a86, 0x201c, 0x7bae,
+ 0x2003, 0x0000, 0x2001, 0x1a80, 0x201c, 0x7baa, 0x2003, 0x0000,
+ 0x2001, 0x1a87, 0x201c, 0x7bb2, 0x2003, 0x0000, 0x003e, 0x000e,
+ 0x0804, 0x35ab, 0xa830, 0x9086, 0x0100, 0x0904, 0x35dd, 0x8906,
+ 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, 0x001b,
+ 0x2009, 0x000c, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0x0804, 0x4bd5,
+ 0x9006, 0x080c, 0x28fd, 0x78a8, 0x9084, 0x00ff, 0x9086, 0x00ff,
+ 0x0118, 0x81ff, 0x1904, 0x35dd, 0x080c, 0x7569, 0x0110, 0x080c,
+ 0x60ec, 0x7888, 0x908a, 0x1000, 0x1a04, 0x35e0, 0x7984, 0x9186,
+ 0x00ff, 0x0138, 0x9182, 0x007f, 0x1a04, 0x35e0, 0x2100, 0x080c,
+ 0x28c7, 0x0026, 0x00c6, 0x0126, 0x2091, 0x8000, 0x2061, 0x19fc,
+ 0x601b, 0x0000, 0x601f, 0x0000, 0x607b, 0x0000, 0x607f, 0x0000,
+ 0x080c, 0x7569, 0x1158, 0x080c, 0x784e, 0x080c, 0x6127, 0x9085,
+ 0x0001, 0x080c, 0x75ad, 0x080c, 0x7495, 0x00d0, 0x080c, 0xb072,
+ 0x2061, 0x0100, 0x2001, 0x1818, 0x2004, 0x9084, 0x00ff, 0x810f,
+ 0x9105, 0x604a, 0x6043, 0x0090, 0x6043, 0x0010, 0x2009, 0x199a,
+ 0x200b, 0x0000, 0x2009, 0x002d, 0x2011, 0x6012, 0x080c, 0x87a1,
+ 0x7984, 0x080c, 0x7569, 0x1110, 0x2009, 0x00ff, 0x7a88, 0x080c,
+ 0x4644, 0x012e, 0x00ce, 0x002e, 0x0804, 0x35ab, 0x7984, 0x080c,
+ 0x66b2, 0x2b08, 0x1904, 0x35e0, 0x0804, 0x35ab, 0x81ff, 0x0120,
+ 0x2009, 0x0001, 0x0804, 0x35dd, 0x60dc, 0xd0ac, 0x1130, 0xd09c,
+ 0x1120, 0x2009, 0x0005, 0x0804, 0x35dd, 0x080c, 0x4b89, 0x1120,
+ 0x2009, 0x0002, 0x0804, 0x35dd, 0x7984, 0x81ff, 0x0904, 0x35e0,
+ 0x9192, 0x0021, 0x1a04, 0x35e0, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98,
+ 0xa85c, 0x9080, 0x0019, 0x702a, 0xaf60, 0x7736, 0x080c, 0x4bd2,
+ 0x701f, 0x4899, 0x7880, 0x9086, 0x006e, 0x0110, 0x701f, 0x527b,
+ 0x0005, 0x2009, 0x0080, 0x080c, 0x671d, 0x1118, 0x080c, 0x6a92,
+ 0x0120, 0x2021, 0x400a, 0x0804, 0x35ad, 0x00d6, 0x0096, 0xa964,
+ 0xaa6c, 0xab70, 0xac74, 0xad78, 0xae7c, 0xa884, 0x90be, 0x0100,
+ 0x0904, 0x4932, 0x90be, 0x0112, 0x0904, 0x4932, 0x90be, 0x0113,
+ 0x0904, 0x4932, 0x90be, 0x0114, 0x0904, 0x4932, 0x90be, 0x0117,
+ 0x0904, 0x4932, 0x90be, 0x011a, 0x0904, 0x4932, 0x90be, 0x011c,
+ 0x0904, 0x4932, 0x90be, 0x0121, 0x0904, 0x4919, 0x90be, 0x0131,
+ 0x0904, 0x4919, 0x90be, 0x0171, 0x0904, 0x4932, 0x90be, 0x0173,
+ 0x0904, 0x4932, 0x90be, 0x01a1, 0x1128, 0xa894, 0x8007, 0xa896,
+ 0x0804, 0x493d, 0x90be, 0x0212, 0x0904, 0x4926, 0x90be, 0x0213,
+ 0x05e8, 0x90be, 0x0214, 0x0500, 0x90be, 0x0217, 0x0188, 0x90be,
+ 0x021a, 0x1120, 0xa89c, 0x8007, 0xa89e, 0x04e0, 0x90be, 0x021f,
+ 0x05c8, 0x90be, 0x0300, 0x05b0, 0x009e, 0x00de, 0x0804, 0x35e0,
+ 0x7028, 0x9080, 0x0010, 0x2098, 0x20a0, 0x7034, 0x20e0, 0x20e8,
+ 0x20a9, 0x0007, 0x080c, 0x497b, 0x7028, 0x9080, 0x000e, 0x2098,
+ 0x20a0, 0x7034, 0x20e0, 0x20e8, 0x20a9, 0x0001, 0x080c, 0x497b,
+ 0x00c8, 0x7028, 0x9080, 0x000c, 0x2098, 0x20a0, 0x7034, 0x20e0,
+ 0x20e8, 0x20a9, 0x0001, 0x080c, 0x4988, 0x00b8, 0x7028, 0x9080,
0x000e, 0x2098, 0x20a0, 0x7034, 0x20e0, 0x20e8, 0x20a9, 0x0001,
- 0x080c, 0x4975, 0x00c8, 0x7028, 0x9080, 0x000c, 0x2098, 0x20a0,
- 0x7034, 0x20e0, 0x20e8, 0x20a9, 0x0001, 0x080c, 0x4982, 0x00b8,
- 0x7028, 0x9080, 0x000e, 0x2098, 0x20a0, 0x7034, 0x20e0, 0x20e8,
- 0x20a9, 0x0001, 0x080c, 0x4982, 0x7028, 0x9080, 0x000c, 0x2098,
- 0x20a0, 0x7034, 0x20e0, 0x20e8, 0x20a9, 0x0001, 0x04f1, 0x00c6,
- 0x080c, 0x4b83, 0x0550, 0xa868, 0xc0fd, 0xa86a, 0xa867, 0x0119,
- 0x9006, 0xa882, 0xa87f, 0x0020, 0xa88b, 0x0001, 0x810b, 0xa9ae,
- 0xa8b2, 0xaab6, 0xabba, 0xacbe, 0xadc2, 0xa9c6, 0xa8ca, 0x00ce,
- 0x009e, 0x00de, 0xa866, 0xa822, 0xa868, 0xc0fd, 0xa86a, 0xa804,
- 0x2048, 0x080c, 0xcfcb, 0x1120, 0x2009, 0x0003, 0x0804, 0x35e2,
- 0x7007, 0x0003, 0x701f, 0x496c, 0x0005, 0x00ce, 0x009e, 0x00de,
- 0x2009, 0x0002, 0x0804, 0x35e2, 0xa820, 0x9086, 0x8001, 0x1904,
- 0x35b0, 0x2009, 0x0004, 0x0804, 0x35e2, 0x0016, 0x0026, 0x3510,
- 0x20a9, 0x0002, 0x4002, 0x4104, 0x4004, 0x8211, 0x1dc8, 0x002e,
- 0x001e, 0x0005, 0x0016, 0x0026, 0x0036, 0x0046, 0x3520, 0x20a9,
- 0x0004, 0x4002, 0x4304, 0x4204, 0x4104, 0x4004, 0x8421, 0x1db8,
- 0x004e, 0x003e, 0x002e, 0x001e, 0x0005, 0x81ff, 0x0120, 0x2009,
- 0x0001, 0x0804, 0x35e2, 0x60dc, 0xd0ac, 0x1130, 0xd09c, 0x1120,
- 0x2009, 0x0005, 0x0804, 0x35e2, 0x7984, 0x78a8, 0x2040, 0x080c,
- 0xb051, 0x1120, 0x9182, 0x007f, 0x0a04, 0x35e5, 0x9186, 0x00ff,
- 0x0904, 0x35e5, 0x9182, 0x0800, 0x1a04, 0x35e5, 0x7a8c, 0x7b88,
- 0x607c, 0x9306, 0x1158, 0x6080, 0x924e, 0x0904, 0x35e5, 0x080c,
- 0xb051, 0x1120, 0x99cc, 0xff00, 0x0904, 0x35e5, 0x0126, 0x2091,
- 0x8000, 0x080c, 0x4a96, 0x0904, 0x4a16, 0x0086, 0x90c6, 0x4000,
- 0x008e, 0x1538, 0x00c6, 0x0006, 0x0036, 0xb818, 0xbb1c, 0x9305,
- 0xbb20, 0x9305, 0xbb24, 0x9305, 0xbb28, 0x9305, 0xbb2c, 0x9305,
- 0xbb30, 0x9305, 0xbb34, 0x9305, 0x003e, 0x0570, 0xd88c, 0x1128,
- 0x080c, 0x6a8c, 0x0110, 0xc89d, 0x0438, 0x900e, 0x080c, 0x6937,
- 0x1108, 0xc185, 0xb800, 0xd0bc, 0x0108, 0xc18d, 0x000e, 0x00ce,
- 0x00b8, 0x90c6, 0x4007, 0x1110, 0x2408, 0x0090, 0x90c6, 0x4008,
- 0x1118, 0x2708, 0x2610, 0x0060, 0x90c6, 0x4009, 0x1108, 0x0040,
- 0x90c6, 0x4006, 0x1108, 0x0020, 0x2001, 0x4005, 0x2009, 0x000a,
- 0x2020, 0x012e, 0x0804, 0x35b2, 0x000e, 0x00ce, 0x2b00, 0x7026,
- 0x0016, 0x00b6, 0x00c6, 0x00e6, 0x2c70, 0x080c, 0xb139, 0x0904,
- 0x4a6b, 0x2b00, 0x6012, 0x080c, 0xd2bb, 0x2e58, 0x00ee, 0x00e6,
- 0x00c6, 0x080c, 0x4b83, 0x00ce, 0x2b70, 0x1158, 0x080c, 0xb0e7,
- 0x00ee, 0x00ce, 0x00be, 0x001e, 0x012e, 0x2009, 0x0002, 0x0804,
- 0x35e2, 0x900e, 0xa966, 0xa96a, 0x2900, 0x6016, 0xa932, 0xa868,
- 0xc0fd, 0xd88c, 0x0108, 0xc0f5, 0xa86a, 0xd89c, 0x1110, 0x080c,
- 0x324b, 0x6023, 0x0001, 0x9006, 0x080c, 0x6649, 0xd89c, 0x0138,
- 0x2001, 0x0004, 0x080c, 0x665d, 0x2009, 0x0003, 0x0030, 0x2001,
- 0x0002, 0x080c, 0x665d, 0x2009, 0x0002, 0x080c, 0xb166, 0x78a8,
- 0xd094, 0x0138, 0x00ee, 0x7024, 0x00e6, 0x2058, 0xb8cc, 0xc08d,
- 0xb8ce, 0x9085, 0x0001, 0x00ee, 0x00ce, 0x00be, 0x001e, 0x012e,
- 0x1120, 0x2009, 0x0003, 0x0804, 0x35e2, 0x7007, 0x0003, 0x701f,
- 0x4a7a, 0x0005, 0xa830, 0x9086, 0x0100, 0x7024, 0x2058, 0x1138,
- 0x2009, 0x0004, 0xba04, 0x9294, 0x00ff, 0x0804, 0x5721, 0x900e,
- 0xa868, 0xd0f4, 0x1904, 0x35b0, 0x080c, 0x6937, 0x1108, 0xc185,
- 0xb800, 0xd0bc, 0x0108, 0xc18d, 0x0804, 0x35b0, 0x00e6, 0x00d6,
- 0x0096, 0x83ff, 0x0904, 0x4ae5, 0x902e, 0x080c, 0xb051, 0x0130,
- 0x9026, 0x20a9, 0x0800, 0x2071, 0x1000, 0x0030, 0x2021, 0x007f,
- 0x20a9, 0x0781, 0x2071, 0x107f, 0x2e04, 0x9005, 0x11b8, 0x2100,
- 0x9406, 0x1904, 0x4af6, 0x2428, 0x94ce, 0x007f, 0x1120, 0x92ce,
- 0xfffd, 0x1558, 0x0030, 0x94ce, 0x0080, 0x1130, 0x92ce, 0xfffc,
- 0x1520, 0x93ce, 0x00ff, 0x1508, 0xc5fd, 0x0480, 0x2058, 0xbf10,
- 0x2700, 0x9306, 0x11e8, 0xbe14, 0x2600, 0x9206, 0x11c8, 0x2400,
- 0x9106, 0x1180, 0xd884, 0x0598, 0xd894, 0x1588, 0x080c, 0x6a2c,
- 0x1570, 0x2001, 0x4000, 0x0460, 0x080c, 0x6a8c, 0x1540, 0x2001,
- 0x4000, 0x0430, 0x2001, 0x4007, 0x0418, 0x2001, 0x4006, 0x0400,
- 0x2400, 0x9106, 0x1158, 0xbe14, 0x87ff, 0x1128, 0x86ff, 0x0918,
- 0x080c, 0xb051, 0x1900, 0x2001, 0x4008, 0x0090, 0x8420, 0x8e70,
- 0x1f04, 0x4aac, 0x85ff, 0x1130, 0x2001, 0x4009, 0x0048, 0x2001,
- 0x0001, 0x0030, 0x080c, 0x66ac, 0x1dd0, 0xbb12, 0xba16, 0x9006,
- 0x9005, 0x009e, 0x00de, 0x00ee, 0x0005, 0x81ff, 0x0120, 0x2009,
- 0x0001, 0x0804, 0x35e2, 0x080c, 0x4b83, 0x1120, 0x2009, 0x0002,
- 0x0804, 0x35e2, 0xa867, 0x0000, 0xa868, 0xc0fd, 0xa86a, 0x7884,
- 0x9005, 0x0904, 0x35e5, 0x9096, 0x00ff, 0x0120, 0x9092, 0x0004,
- 0x1a04, 0x35e5, 0x2010, 0x2918, 0x080c, 0x31f1, 0x1120, 0x2009,
- 0x0003, 0x0804, 0x35e2, 0x7007, 0x0003, 0x701f, 0x4b38, 0x0005,
- 0xa830, 0x9086, 0x0100, 0x1904, 0x35b0, 0x2009, 0x0004, 0x0804,
- 0x35e2, 0x7984, 0x080c, 0xb051, 0x1120, 0x9182, 0x007f, 0x0a04,
- 0x35e5, 0x9186, 0x00ff, 0x0904, 0x35e5, 0x9182, 0x0800, 0x1a04,
- 0x35e5, 0x2001, 0x9400, 0x080c, 0x577c, 0x1904, 0x35e2, 0x0804,
- 0x35b0, 0xa998, 0x080c, 0xb051, 0x1118, 0x9182, 0x007f, 0x0280,
- 0x9186, 0x00ff, 0x0168, 0x9182, 0x0800, 0x1250, 0x2001, 0x9400,
- 0x080c, 0x577c, 0x11a8, 0x0060, 0xa897, 0x4005, 0xa99a, 0x0010,
- 0xa897, 0x4006, 0x900e, 0x9085, 0x0001, 0x2001, 0x0030, 0x0005,
- 0xa897, 0x4000, 0x900e, 0x9085, 0x0001, 0x2001, 0x0000, 0x0005,
- 0x2009, 0x000a, 0x0c48, 0x080c, 0x100e, 0x0198, 0x9006, 0xa802,
- 0x7014, 0x9005, 0x1120, 0x2900, 0x7016, 0x701a, 0x0040, 0x7018,
- 0xa802, 0x0086, 0x2040, 0x2900, 0xa006, 0x701a, 0x008e, 0x9085,
- 0x0001, 0x0005, 0x7984, 0x080c, 0x6717, 0x1130, 0x7e88, 0x9684,
- 0x3fff, 0x9082, 0x4000, 0x0208, 0x905e, 0x8bff, 0x0005, 0xa998,
- 0x080c, 0x6717, 0x1130, 0xae9c, 0x9684, 0x3fff, 0x9082, 0x4000,
- 0x0208, 0x905e, 0x8bff, 0x0005, 0xae98, 0x0008, 0x7e84, 0x2608,
- 0x080c, 0x6717, 0x1108, 0x0008, 0x905e, 0x8bff, 0x0005, 0x0016,
- 0x7114, 0x81ff, 0x0128, 0x2148, 0xa904, 0x080c, 0x1040, 0x0cc8,
- 0x7116, 0x711a, 0x001e, 0x0005, 0x2031, 0x0001, 0x0010, 0x2031,
- 0x0000, 0x2061, 0x18b8, 0x2c44, 0xa66a, 0xa17a, 0xa772, 0xa076,
- 0xa28e, 0xa392, 0xa496, 0xa59a, 0x080c, 0x10f8, 0x7007, 0x0002,
- 0x701f, 0x35b0, 0x0005, 0x00f6, 0x0126, 0x2091, 0x8000, 0x2079,
- 0x0000, 0x2001, 0x18b0, 0x2004, 0x9005, 0x1190, 0x0e04, 0x4c00,
- 0x7a36, 0x7833, 0x0012, 0x7a82, 0x7b86, 0x7c8a, 0x2091, 0x4080,
- 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x11aa, 0x0804, 0x4c66,
- 0x0016, 0x0086, 0x0096, 0x00c6, 0x00e6, 0x2071, 0x189e, 0x7044,
- 0x9005, 0x1540, 0x7148, 0x9182, 0x0010, 0x0288, 0x7038, 0x2060,
- 0x080c, 0x100e, 0x0904, 0x4c5e, 0xa84b, 0x0000, 0x2900, 0x7046,
- 0x2001, 0x0002, 0x9080, 0x20e8, 0x2005, 0xa846, 0x0098, 0x7038,
- 0x90e0, 0x0004, 0x2001, 0x18ba, 0x9c82, 0x18fa, 0x0210, 0x2061,
- 0x18ba, 0x2c00, 0x703a, 0x7148, 0x81ff, 0x1108, 0x703e, 0x8108,
- 0x714a, 0x0460, 0x7148, 0x8108, 0x714a, 0x7044, 0x2040, 0xa144,
+ 0x080c, 0x4988, 0x7028, 0x9080, 0x000c, 0x2098, 0x20a0, 0x7034,
+ 0x20e0, 0x20e8, 0x20a9, 0x0001, 0x04f1, 0x00c6, 0x080c, 0x4b89,
+ 0x0550, 0xa868, 0xc0fd, 0xa86a, 0xa867, 0x0119, 0x9006, 0xa882,
+ 0xa87f, 0x0020, 0xa88b, 0x0001, 0x810b, 0xa9ae, 0xa8b2, 0xaab6,
+ 0xabba, 0xacbe, 0xadc2, 0xa9c6, 0xa8ca, 0x00ce, 0x009e, 0x00de,
+ 0xa866, 0xa822, 0xa868, 0xc0fd, 0xa86a, 0xa804, 0x2048, 0x080c,
+ 0xcfe2, 0x1120, 0x2009, 0x0003, 0x0804, 0x35dd, 0x7007, 0x0003,
+ 0x701f, 0x4972, 0x0005, 0x00ce, 0x009e, 0x00de, 0x2009, 0x0002,
+ 0x0804, 0x35dd, 0xa820, 0x9086, 0x8001, 0x1904, 0x35ab, 0x2009,
+ 0x0004, 0x0804, 0x35dd, 0x0016, 0x0026, 0x3510, 0x20a9, 0x0002,
+ 0x4002, 0x4104, 0x4004, 0x8211, 0x1dc8, 0x002e, 0x001e, 0x0005,
+ 0x0016, 0x0026, 0x0036, 0x0046, 0x3520, 0x20a9, 0x0004, 0x4002,
+ 0x4304, 0x4204, 0x4104, 0x4004, 0x8421, 0x1db8, 0x004e, 0x003e,
+ 0x002e, 0x001e, 0x0005, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804,
+ 0x35dd, 0x60dc, 0xd0ac, 0x1130, 0xd09c, 0x1120, 0x2009, 0x0005,
+ 0x0804, 0x35dd, 0x7984, 0x78a8, 0x2040, 0x080c, 0xb06b, 0x1120,
+ 0x9182, 0x007f, 0x0a04, 0x35e0, 0x9186, 0x00ff, 0x0904, 0x35e0,
+ 0x9182, 0x0800, 0x1a04, 0x35e0, 0x7a8c, 0x7b88, 0x607c, 0x9306,
+ 0x1158, 0x6080, 0x924e, 0x0904, 0x35e0, 0x080c, 0xb06b, 0x1120,
+ 0x99cc, 0xff00, 0x0904, 0x35e0, 0x0126, 0x2091, 0x8000, 0x080c,
+ 0x4a9c, 0x0904, 0x4a1c, 0x0086, 0x90c6, 0x4000, 0x008e, 0x1538,
+ 0x00c6, 0x0006, 0x0036, 0xb818, 0xbb1c, 0x9305, 0xbb20, 0x9305,
+ 0xbb24, 0x9305, 0xbb28, 0x9305, 0xbb2c, 0x9305, 0xbb30, 0x9305,
+ 0xbb34, 0x9305, 0x003e, 0x0570, 0xd88c, 0x1128, 0x080c, 0x6a92,
+ 0x0110, 0xc89d, 0x0438, 0x900e, 0x080c, 0x693d, 0x1108, 0xc185,
+ 0xb800, 0xd0bc, 0x0108, 0xc18d, 0x000e, 0x00ce, 0x00b8, 0x90c6,
+ 0x4007, 0x1110, 0x2408, 0x0090, 0x90c6, 0x4008, 0x1118, 0x2708,
+ 0x2610, 0x0060, 0x90c6, 0x4009, 0x1108, 0x0040, 0x90c6, 0x4006,
+ 0x1108, 0x0020, 0x2001, 0x4005, 0x2009, 0x000a, 0x2020, 0x012e,
+ 0x0804, 0x35ad, 0x000e, 0x00ce, 0x2b00, 0x7026, 0x0016, 0x00b6,
+ 0x00c6, 0x00e6, 0x2c70, 0x080c, 0xb153, 0x0904, 0x4a71, 0x2b00,
+ 0x6012, 0x080c, 0xd2d2, 0x2e58, 0x00ee, 0x00e6, 0x00c6, 0x080c,
+ 0x4b89, 0x00ce, 0x2b70, 0x1158, 0x080c, 0xb101, 0x00ee, 0x00ce,
+ 0x00be, 0x001e, 0x012e, 0x2009, 0x0002, 0x0804, 0x35dd, 0x900e,
+ 0xa966, 0xa96a, 0x2900, 0x6016, 0xa932, 0xa868, 0xc0fd, 0xd88c,
+ 0x0108, 0xc0f5, 0xa86a, 0xd89c, 0x1110, 0x080c, 0x3246, 0x6023,
+ 0x0001, 0x9006, 0x080c, 0x664f, 0xd89c, 0x0138, 0x2001, 0x0004,
+ 0x080c, 0x6663, 0x2009, 0x0003, 0x0030, 0x2001, 0x0002, 0x080c,
+ 0x6663, 0x2009, 0x0002, 0x080c, 0xb180, 0x78a8, 0xd094, 0x0138,
+ 0x00ee, 0x7024, 0x00e6, 0x2058, 0xb8cc, 0xc08d, 0xb8ce, 0x9085,
+ 0x0001, 0x00ee, 0x00ce, 0x00be, 0x001e, 0x012e, 0x1120, 0x2009,
+ 0x0003, 0x0804, 0x35dd, 0x7007, 0x0003, 0x701f, 0x4a80, 0x0005,
+ 0xa830, 0x9086, 0x0100, 0x7024, 0x2058, 0x1138, 0x2009, 0x0004,
+ 0xba04, 0x9294, 0x00ff, 0x0804, 0x5727, 0x900e, 0xa868, 0xd0f4,
+ 0x1904, 0x35ab, 0x080c, 0x693d, 0x1108, 0xc185, 0xb800, 0xd0bc,
+ 0x0108, 0xc18d, 0x0804, 0x35ab, 0x00e6, 0x00d6, 0x0096, 0x83ff,
+ 0x0904, 0x4aeb, 0x902e, 0x080c, 0xb06b, 0x0130, 0x9026, 0x20a9,
+ 0x0800, 0x2071, 0x1000, 0x0030, 0x2021, 0x007f, 0x20a9, 0x0781,
+ 0x2071, 0x107f, 0x2e04, 0x9005, 0x11b8, 0x2100, 0x9406, 0x1904,
+ 0x4afc, 0x2428, 0x94ce, 0x007f, 0x1120, 0x92ce, 0xfffd, 0x1558,
+ 0x0030, 0x94ce, 0x0080, 0x1130, 0x92ce, 0xfffc, 0x1520, 0x93ce,
+ 0x00ff, 0x1508, 0xc5fd, 0x0480, 0x2058, 0xbf10, 0x2700, 0x9306,
+ 0x11e8, 0xbe14, 0x2600, 0x9206, 0x11c8, 0x2400, 0x9106, 0x1180,
+ 0xd884, 0x0598, 0xd894, 0x1588, 0x080c, 0x6a32, 0x1570, 0x2001,
+ 0x4000, 0x0460, 0x080c, 0x6a92, 0x1540, 0x2001, 0x4000, 0x0430,
+ 0x2001, 0x4007, 0x0418, 0x2001, 0x4006, 0x0400, 0x2400, 0x9106,
+ 0x1158, 0xbe14, 0x87ff, 0x1128, 0x86ff, 0x0918, 0x080c, 0xb06b,
+ 0x1900, 0x2001, 0x4008, 0x0090, 0x8420, 0x8e70, 0x1f04, 0x4ab2,
+ 0x85ff, 0x1130, 0x2001, 0x4009, 0x0048, 0x2001, 0x0001, 0x0030,
+ 0x080c, 0x66b2, 0x1dd0, 0xbb12, 0xba16, 0x9006, 0x9005, 0x009e,
+ 0x00de, 0x00ee, 0x0005, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804,
+ 0x35dd, 0x080c, 0x4b89, 0x1120, 0x2009, 0x0002, 0x0804, 0x35dd,
+ 0xa867, 0x0000, 0xa868, 0xc0fd, 0xa86a, 0x7884, 0x9005, 0x0904,
+ 0x35e0, 0x9096, 0x00ff, 0x0120, 0x9092, 0x0004, 0x1a04, 0x35e0,
+ 0x2010, 0x2918, 0x080c, 0x31ec, 0x1120, 0x2009, 0x0003, 0x0804,
+ 0x35dd, 0x7007, 0x0003, 0x701f, 0x4b3e, 0x0005, 0xa830, 0x9086,
+ 0x0100, 0x1904, 0x35ab, 0x2009, 0x0004, 0x0804, 0x35dd, 0x7984,
+ 0x080c, 0xb06b, 0x1120, 0x9182, 0x007f, 0x0a04, 0x35e0, 0x9186,
+ 0x00ff, 0x0904, 0x35e0, 0x9182, 0x0800, 0x1a04, 0x35e0, 0x2001,
+ 0x9400, 0x080c, 0x5782, 0x1904, 0x35dd, 0x0804, 0x35ab, 0xa998,
+ 0x080c, 0xb06b, 0x1118, 0x9182, 0x007f, 0x0280, 0x9186, 0x00ff,
+ 0x0168, 0x9182, 0x0800, 0x1250, 0x2001, 0x9400, 0x080c, 0x5782,
+ 0x11a8, 0x0060, 0xa897, 0x4005, 0xa99a, 0x0010, 0xa897, 0x4006,
+ 0x900e, 0x9085, 0x0001, 0x2001, 0x0030, 0x0005, 0xa897, 0x4000,
+ 0x900e, 0x9085, 0x0001, 0x2001, 0x0000, 0x0005, 0x2009, 0x000a,
+ 0x0c48, 0x080c, 0x100e, 0x0198, 0x9006, 0xa802, 0x7014, 0x9005,
+ 0x1120, 0x2900, 0x7016, 0x701a, 0x0040, 0x7018, 0xa802, 0x0086,
+ 0x2040, 0x2900, 0xa006, 0x701a, 0x008e, 0x9085, 0x0001, 0x0005,
+ 0x7984, 0x080c, 0x671d, 0x1130, 0x7e88, 0x9684, 0x3fff, 0x9082,
+ 0x4000, 0x0208, 0x905e, 0x8bff, 0x0005, 0xa998, 0x080c, 0x671d,
+ 0x1130, 0xae9c, 0x9684, 0x3fff, 0x9082, 0x4000, 0x0208, 0x905e,
+ 0x8bff, 0x0005, 0xae98, 0x0008, 0x7e84, 0x2608, 0x080c, 0x671d,
+ 0x1108, 0x0008, 0x905e, 0x8bff, 0x0005, 0x0016, 0x7114, 0x81ff,
+ 0x0128, 0x2148, 0xa904, 0x080c, 0x1040, 0x0cc8, 0x7116, 0x711a,
+ 0x001e, 0x0005, 0x2031, 0x0001, 0x0010, 0x2031, 0x0000, 0x2061,
+ 0x18b8, 0x2c44, 0xa66a, 0xa17a, 0xa772, 0xa076, 0xa28e, 0xa392,
+ 0xa496, 0xa59a, 0x080c, 0x10f8, 0x7007, 0x0002, 0x701f, 0x35ab,
+ 0x0005, 0x00f6, 0x0126, 0x2091, 0x8000, 0x2079, 0x0000, 0x2001,
+ 0x18b0, 0x2004, 0x9005, 0x1190, 0x0e04, 0x4c06, 0x7a36, 0x7833,
+ 0x0012, 0x7a82, 0x7b86, 0x7c8a, 0x2091, 0x4080, 0x2001, 0x0089,
+ 0x2004, 0xd084, 0x190c, 0x11aa, 0x0804, 0x4c6c, 0x0016, 0x0086,
+ 0x0096, 0x00c6, 0x00e6, 0x2071, 0x189e, 0x7044, 0x9005, 0x1540,
+ 0x7148, 0x9182, 0x0010, 0x0288, 0x7038, 0x2060, 0x080c, 0x100e,
+ 0x0904, 0x4c64, 0xa84b, 0x0000, 0x2900, 0x7046, 0x2001, 0x0002,
+ 0x9080, 0x20f0, 0x2005, 0xa846, 0x0098, 0x7038, 0x90e0, 0x0004,
+ 0x2001, 0x18ba, 0x9c82, 0x18fa, 0x0210, 0x2061, 0x18ba, 0x2c00,
+ 0x703a, 0x7148, 0x81ff, 0x1108, 0x703e, 0x8108, 0x714a, 0x0460,
+ 0x7148, 0x8108, 0x714a, 0x7044, 0x2040, 0xa144, 0x2105, 0x0016,
+ 0x908a, 0x0036, 0x1a0c, 0x0dc5, 0x2060, 0x001e, 0x8108, 0x2105,
+ 0x9005, 0xa146, 0x1520, 0x080c, 0x100e, 0x1130, 0x8109, 0xa946,
+ 0x7148, 0x8109, 0x714a, 0x00d8, 0x9006, 0xa806, 0xa84a, 0xa046,
+ 0x2800, 0xa802, 0x2900, 0xa006, 0x7046, 0x2001, 0x0002, 0x9080,
+ 0x20f0, 0x2005, 0xa846, 0x0058, 0x2262, 0x6306, 0x640a, 0x00ee,
+ 0x00ce, 0x009e, 0x008e, 0x001e, 0x012e, 0x00fe, 0x0005, 0x2c00,
+ 0x9082, 0x001b, 0x0002, 0x4c8e, 0x4c8e, 0x4c90, 0x4c8e, 0x4c8e,
+ 0x4c8e, 0x4c94, 0x4c8e, 0x4c8e, 0x4c8e, 0x4c98, 0x4c8e, 0x4c8e,
+ 0x4c8e, 0x4c9c, 0x4c8e, 0x4c8e, 0x4c8e, 0x4ca0, 0x4c8e, 0x4c8e,
+ 0x4c8e, 0x4ca4, 0x4c8e, 0x4c8e, 0x4c8e, 0x4ca9, 0x080c, 0x0dc5,
+ 0xa276, 0xa37a, 0xa47e, 0x0898, 0xa286, 0xa38a, 0xa48e, 0x0878,
+ 0xa296, 0xa39a, 0xa49e, 0x0858, 0xa2a6, 0xa3aa, 0xa4ae, 0x0838,
+ 0xa2b6, 0xa3ba, 0xa4be, 0x0818, 0xa2c6, 0xa3ca, 0xa4ce, 0x0804,
+ 0x4c67, 0xa2d6, 0xa3da, 0xa4de, 0x0804, 0x4c67, 0x00e6, 0x2071,
+ 0x189e, 0x7048, 0x9005, 0x0904, 0x4d40, 0x0126, 0x2091, 0x8000,
+ 0x0e04, 0x4d3f, 0x00f6, 0x2079, 0x0000, 0x00c6, 0x0096, 0x0086,
+ 0x0076, 0x9006, 0x2038, 0x7040, 0x2048, 0x9005, 0x0500, 0xa948,
0x2105, 0x0016, 0x908a, 0x0036, 0x1a0c, 0x0dc5, 0x2060, 0x001e,
- 0x8108, 0x2105, 0x9005, 0xa146, 0x1520, 0x080c, 0x100e, 0x1130,
- 0x8109, 0xa946, 0x7148, 0x8109, 0x714a, 0x00d8, 0x9006, 0xa806,
- 0xa84a, 0xa046, 0x2800, 0xa802, 0x2900, 0xa006, 0x7046, 0x2001,
- 0x0002, 0x9080, 0x20e8, 0x2005, 0xa846, 0x0058, 0x2262, 0x6306,
- 0x640a, 0x00ee, 0x00ce, 0x009e, 0x008e, 0x001e, 0x012e, 0x00fe,
- 0x0005, 0x2c00, 0x9082, 0x001b, 0x0002, 0x4c88, 0x4c88, 0x4c8a,
- 0x4c88, 0x4c88, 0x4c88, 0x4c8e, 0x4c88, 0x4c88, 0x4c88, 0x4c92,
- 0x4c88, 0x4c88, 0x4c88, 0x4c96, 0x4c88, 0x4c88, 0x4c88, 0x4c9a,
- 0x4c88, 0x4c88, 0x4c88, 0x4c9e, 0x4c88, 0x4c88, 0x4c88, 0x4ca3,
- 0x080c, 0x0dc5, 0xa276, 0xa37a, 0xa47e, 0x0898, 0xa286, 0xa38a,
- 0xa48e, 0x0878, 0xa296, 0xa39a, 0xa49e, 0x0858, 0xa2a6, 0xa3aa,
- 0xa4ae, 0x0838, 0xa2b6, 0xa3ba, 0xa4be, 0x0818, 0xa2c6, 0xa3ca,
- 0xa4ce, 0x0804, 0x4c61, 0xa2d6, 0xa3da, 0xa4de, 0x0804, 0x4c61,
- 0x00e6, 0x2071, 0x189e, 0x7048, 0x9005, 0x0904, 0x4d3a, 0x0126,
- 0x2091, 0x8000, 0x0e04, 0x4d39, 0x00f6, 0x2079, 0x0000, 0x00c6,
- 0x0096, 0x0086, 0x0076, 0x9006, 0x2038, 0x7040, 0x2048, 0x9005,
- 0x0500, 0xa948, 0x2105, 0x0016, 0x908a, 0x0036, 0x1a0c, 0x0dc5,
- 0x2060, 0x001e, 0x8108, 0x2105, 0x9005, 0xa94a, 0x1904, 0x4d3c,
- 0xa804, 0x9005, 0x090c, 0x0dc5, 0x7042, 0x2938, 0x2040, 0xa003,
- 0x0000, 0x2001, 0x0002, 0x9080, 0x20e8, 0x2005, 0xa04a, 0x0804,
- 0x4d3c, 0x703c, 0x2060, 0x2c14, 0x6304, 0x6408, 0x650c, 0x2200,
- 0x7836, 0x7833, 0x0012, 0x7882, 0x2300, 0x7886, 0x2400, 0x788a,
- 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x11aa,
- 0x87ff, 0x0118, 0x2748, 0x080c, 0x1040, 0x7048, 0x8001, 0x704a,
- 0x9005, 0x1170, 0x7040, 0x2048, 0x9005, 0x0128, 0x080c, 0x1040,
- 0x9006, 0x7042, 0x7046, 0x703b, 0x18ba, 0x703f, 0x18ba, 0x0420,
- 0x7040, 0x9005, 0x1508, 0x7238, 0x2c00, 0x9206, 0x0148, 0x9c80,
- 0x0004, 0x90fa, 0x18fa, 0x0210, 0x2001, 0x18ba, 0x703e, 0x00a0,
- 0x9006, 0x703e, 0x703a, 0x7044, 0x9005, 0x090c, 0x0dc5, 0x2048,
- 0xa800, 0x9005, 0x1de0, 0x2900, 0x7042, 0x2001, 0x0002, 0x9080,
- 0x20e8, 0x2005, 0xa84a, 0x0000, 0x007e, 0x008e, 0x009e, 0x00ce,
- 0x00fe, 0x012e, 0x00ee, 0x0005, 0x2c00, 0x9082, 0x001b, 0x0002,
- 0x4d5b, 0x4d5b, 0x4d5d, 0x4d5b, 0x4d5b, 0x4d5b, 0x4d62, 0x4d5b,
- 0x4d5b, 0x4d5b, 0x4d67, 0x4d5b, 0x4d5b, 0x4d5b, 0x4d6c, 0x4d5b,
- 0x4d5b, 0x4d5b, 0x4d71, 0x4d5b, 0x4d5b, 0x4d5b, 0x4d76, 0x4d5b,
- 0x4d5b, 0x4d5b, 0x4d7b, 0x080c, 0x0dc5, 0xaa74, 0xab78, 0xac7c,
- 0x0804, 0x4ce7, 0xaa84, 0xab88, 0xac8c, 0x0804, 0x4ce7, 0xaa94,
- 0xab98, 0xac9c, 0x0804, 0x4ce7, 0xaaa4, 0xaba8, 0xacac, 0x0804,
- 0x4ce7, 0xaab4, 0xabb8, 0xacbc, 0x0804, 0x4ce7, 0xaac4, 0xabc8,
- 0xaccc, 0x0804, 0x4ce7, 0xaad4, 0xabd8, 0xacdc, 0x0804, 0x4ce7,
- 0x0016, 0x0026, 0x0036, 0x00b6, 0x00c6, 0x2009, 0x007e, 0x080c,
- 0x6717, 0x2019, 0x0001, 0xb85c, 0xd0ac, 0x0110, 0x2019, 0x0000,
- 0x2011, 0x801b, 0x080c, 0x4be3, 0x00ce, 0x00be, 0x003e, 0x002e,
- 0x001e, 0x0005, 0x0026, 0x080c, 0x57cd, 0xd0c4, 0x0120, 0x2011,
- 0x8014, 0x080c, 0x4be3, 0x002e, 0x0005, 0x81ff, 0x1904, 0x35e2,
- 0x0126, 0x2091, 0x8000, 0x6030, 0xc08d, 0xc085, 0xc0ac, 0x6032,
- 0x080c, 0x7563, 0x1158, 0x080c, 0x7848, 0x080c, 0x6121, 0x9085,
- 0x0001, 0x080c, 0x75a7, 0x080c, 0x748f, 0x0010, 0x080c, 0x5fe0,
- 0x012e, 0x0804, 0x35b0, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804,
- 0x35e2, 0x080c, 0x57e1, 0x0120, 0x2009, 0x0007, 0x0804, 0x35e2,
- 0x080c, 0x6a84, 0x0120, 0x2009, 0x0008, 0x0804, 0x35e2, 0x7984,
- 0x080c, 0x66ac, 0x1904, 0x35e5, 0x080c, 0x4bb6, 0x0904, 0x35e5,
- 0x2b00, 0x7026, 0x080c, 0x6a8c, 0x7888, 0x1170, 0x9084, 0x0005,
- 0x1158, 0x900e, 0x080c, 0x6937, 0x1108, 0xc185, 0xb800, 0xd0bc,
- 0x0108, 0xc18d, 0x0804, 0x35b0, 0x080c, 0x4b83, 0x0904, 0x35e2,
- 0x9006, 0xa866, 0xa832, 0xa868, 0xc0fd, 0xa86a, 0x080c, 0xd069,
- 0x0904, 0x35e2, 0x7888, 0xd094, 0x0118, 0xb8cc, 0xc08d, 0xb8ce,
- 0x7007, 0x0003, 0x701f, 0x4e56, 0x0005, 0x2061, 0x1800, 0x080c,
- 0x57e1, 0x2009, 0x0007, 0x1560, 0x080c, 0x6a84, 0x0118, 0x2009,
- 0x0008, 0x0430, 0xa998, 0x080c, 0x66ac, 0x1530, 0x080c, 0x4bb4,
- 0x0518, 0x080c, 0x6a8c, 0xa89c, 0x1168, 0x9084, 0x0005, 0x1150,
- 0x900e, 0x080c, 0x6937, 0x1108, 0xc185, 0xb800, 0xd0bc, 0x0108,
- 0xc18d, 0x00d0, 0xa868, 0xc0fc, 0xa86a, 0x080c, 0xd069, 0x11e0,
- 0xa89c, 0xd094, 0x0118, 0xb8cc, 0xc08d, 0xb8ce, 0x2009, 0x0003,
- 0xa897, 0x4005, 0xa99a, 0x0010, 0xa897, 0x4006, 0x900e, 0x9085,
- 0x0001, 0x2001, 0x0030, 0x0005, 0xa897, 0x4000, 0xa99a, 0x9006,
- 0x918d, 0x0001, 0x2008, 0x0005, 0x9006, 0x0005, 0xa830, 0x9086,
- 0x0100, 0x7024, 0x2058, 0x1110, 0x0804, 0x5721, 0x900e, 0x080c,
- 0x6937, 0x1108, 0xc185, 0xb800, 0xd0bc, 0x0108, 0xc18d, 0x0804,
- 0x35b0, 0x080c, 0x57e1, 0x0120, 0x2009, 0x0007, 0x0804, 0x35e2,
- 0x7f84, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0x080c, 0x4b83, 0x1120,
- 0x2009, 0x0002, 0x0804, 0x35e2, 0x900e, 0x2130, 0x7126, 0x7132,
- 0xa860, 0x20e8, 0x7036, 0xa85c, 0x9080, 0x0005, 0x702a, 0x20a0,
- 0x080c, 0x6717, 0x1904, 0x4eff, 0x080c, 0x6a8c, 0x0138, 0x080c,
- 0x6a94, 0x0120, 0x080c, 0x6a2c, 0x1904, 0x4eff, 0xd794, 0x1110,
- 0xd784, 0x01a8, 0xb8c4, 0x20e0, 0xb8c8, 0x9080, 0x0006, 0x2098,
- 0x3400, 0xd794, 0x0198, 0x20a9, 0x0008, 0x4003, 0x2098, 0x20a0,
- 0x3d00, 0x20e0, 0x20a9, 0x0002, 0x080c, 0x4982, 0x0080, 0xb8c4,
- 0x20e0, 0xb8c8, 0x9080, 0x000a, 0x2098, 0x3400, 0x20a9, 0x0004,
- 0x4003, 0x2098, 0x20a0, 0x3d00, 0x20e0, 0x080c, 0x4982, 0x9186,
- 0x007e, 0x0170, 0x9186, 0x0080, 0x0158, 0x080c, 0x6a8c, 0x90c2,
- 0x0006, 0x1210, 0xc1fd, 0x0020, 0x080c, 0x6937, 0x1108, 0xc1fd,
- 0x4104, 0xc1fc, 0xd794, 0x0528, 0xb8c4, 0x20e0, 0xb8c8, 0x2060,
- 0x9c80, 0x0000, 0x2098, 0x20a9, 0x0002, 0x4003, 0x9c80, 0x0003,
- 0x2098, 0x20a9, 0x0001, 0x4005, 0x9c80, 0x0004, 0x2098, 0x3400,
- 0x20a9, 0x0002, 0x4003, 0x2098, 0x20a0, 0x3d00, 0x20e0, 0x080c,
- 0x4975, 0x9c80, 0x0026, 0x2098, 0xb8c4, 0x20e0, 0x20a9, 0x0002,
- 0x4003, 0xd794, 0x0110, 0x96b0, 0x000b, 0x96b0, 0x0005, 0x8108,
- 0x080c, 0xb051, 0x0118, 0x9186, 0x0800, 0x0040, 0xd78c, 0x0120,
- 0x9186, 0x0800, 0x0170, 0x0018, 0x9186, 0x007e, 0x0150, 0xd794,
- 0x0118, 0x9686, 0x0020, 0x0010, 0x9686, 0x0028, 0x0150, 0x0804,
- 0x4e88, 0x86ff, 0x1120, 0x7124, 0x810b, 0x0804, 0x35b0, 0x7033,
- 0x0001, 0x7122, 0x7024, 0x9600, 0x7026, 0x772e, 0x2061, 0x18b8,
- 0x2c44, 0xa06b, 0x0000, 0xa67a, 0x7034, 0xa072, 0x7028, 0xa076,
- 0xa28e, 0xa392, 0xa496, 0xa59a, 0x080c, 0x10f8, 0x7007, 0x0002,
- 0x701f, 0x4f3b, 0x0005, 0x7030, 0x9005, 0x1180, 0x7120, 0x7028,
- 0x20a0, 0x772c, 0x9036, 0x7034, 0x20e8, 0x2061, 0x18b8, 0x2c44,
- 0xa28c, 0xa390, 0xa494, 0xa598, 0x0804, 0x4e88, 0x7124, 0x810b,
- 0x0804, 0x35b0, 0x2029, 0x007e, 0x7984, 0x7a88, 0x7b8c, 0x7c98,
- 0x9184, 0xff00, 0x8007, 0x90e2, 0x0020, 0x0a04, 0x35e5, 0x9502,
- 0x0a04, 0x35e5, 0x9184, 0x00ff, 0x90e2, 0x0020, 0x0a04, 0x35e5,
- 0x9502, 0x0a04, 0x35e5, 0x9284, 0xff00, 0x8007, 0x90e2, 0x0020,
- 0x0a04, 0x35e5, 0x9502, 0x0a04, 0x35e5, 0x9284, 0x00ff, 0x90e2,
- 0x0020, 0x0a04, 0x35e5, 0x9502, 0x0a04, 0x35e5, 0x9384, 0xff00,
- 0x8007, 0x90e2, 0x0020, 0x0a04, 0x35e5, 0x9502, 0x0a04, 0x35e5,
- 0x9384, 0x00ff, 0x90e2, 0x0020, 0x0a04, 0x35e5, 0x9502, 0x0a04,
- 0x35e5, 0x9484, 0xff00, 0x8007, 0x90e2, 0x0020, 0x0a04, 0x35e5,
- 0x9502, 0x0a04, 0x35e5, 0x9484, 0x00ff, 0x90e2, 0x0020, 0x0a04,
- 0x35e5, 0x9502, 0x0a04, 0x35e5, 0x2061, 0x198a, 0x6102, 0x6206,
- 0x630a, 0x640e, 0x0804, 0x35b0, 0x080c, 0x4b83, 0x0904, 0x35e2,
- 0x2009, 0x0016, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0xa85c, 0x9080,
- 0x0019, 0xaf60, 0x080c, 0x4bcc, 0x701f, 0x4fbf, 0x0005, 0x2001,
- 0x0138, 0x2003, 0x0000, 0x00e6, 0x2071, 0x0300, 0x701c, 0xd0a4,
- 0x1de8, 0x00ee, 0x20a9, 0x0016, 0x896e, 0x8d6e, 0x8d6f, 0x9d84,
- 0xffc0, 0x9080, 0x0019, 0x2098, 0x9d84, 0x003f, 0x20e0, 0x2069,
- 0x1877, 0x20e9, 0x0001, 0x2da0, 0x4003, 0x6800, 0x9005, 0x0904,
- 0x5040, 0x6804, 0x2008, 0x918c, 0xfff8, 0x1904, 0x5040, 0x680c,
- 0x9005, 0x0904, 0x5040, 0x9082, 0xff01, 0x1a04, 0x5040, 0x6810,
- 0x9082, 0x005c, 0x0a04, 0x5040, 0x6824, 0x2008, 0x9082, 0x0008,
- 0x0a04, 0x5040, 0x9182, 0x0400, 0x1a04, 0x5040, 0x0056, 0x2029,
- 0x0000, 0x080c, 0x8d43, 0x005e, 0x6944, 0x6820, 0x9102, 0x06c0,
- 0x6820, 0x9082, 0x0019, 0x16a0, 0x6828, 0x6944, 0x810c, 0x9102,
- 0x0678, 0x6840, 0x9082, 0x000f, 0x1658, 0x080c, 0x1027, 0x2900,
- 0x0904, 0x505c, 0x684e, 0x00e6, 0x2071, 0x1932, 0x00b6, 0x2059,
- 0x0000, 0x080c, 0x8bff, 0x00be, 0x00ee, 0x0568, 0x080c, 0x894a,
- 0x080c, 0x8999, 0x11e0, 0x6857, 0x0000, 0x00c6, 0x2061, 0x0100,
- 0x6104, 0x918d, 0x2000, 0x6106, 0x6b10, 0x2061, 0x1a66, 0x630a,
- 0x00ce, 0x080c, 0x29a1, 0x2001, 0x0138, 0x2102, 0x0804, 0x35b0,
- 0x080c, 0x29a1, 0x2001, 0x0138, 0x2102, 0x0804, 0x35e5, 0x080c,
- 0x8992, 0x00e6, 0x2071, 0x1932, 0x080c, 0x8dc3, 0x080c, 0x8dd2,
- 0x080c, 0x8be2, 0x00ee, 0x2001, 0x188a, 0x204c, 0x080c, 0x1040,
- 0x2001, 0x188a, 0x2003, 0x0000, 0x080c, 0x29a1, 0x2001, 0x0138,
- 0x2102, 0x0804, 0x35e2, 0x2001, 0x1926, 0x200c, 0x918e, 0x0000,
- 0x0904, 0x50c1, 0x080c, 0x8bdd, 0x0904, 0x50c1, 0x2001, 0x0101,
- 0x200c, 0x918c, 0xdfff, 0x2102, 0x2001, 0x0138, 0x2003, 0x0000,
- 0x00e6, 0x2071, 0x0300, 0x701c, 0xd0a4, 0x1de8, 0x00ee, 0x080c,
- 0x8be2, 0x0126, 0x2091, 0x8000, 0x2001, 0x0035, 0x080c, 0x1611,
- 0x012e, 0x00c6, 0x2061, 0x193e, 0x6004, 0x6100, 0x9106, 0x1de0,
- 0x00ce, 0x080c, 0x29a1, 0x2001, 0x0138, 0x2102, 0x00e6, 0x00f6,
- 0x2071, 0x1925, 0x080c, 0x8b1c, 0x0120, 0x2f00, 0x080c, 0x8ba8,
- 0x0cc8, 0x00fe, 0x00ee, 0x0126, 0x2091, 0x8000, 0x2001, 0x188a,
- 0x200c, 0x81ff, 0x0138, 0x2148, 0x080c, 0x1040, 0x2001, 0x188a,
- 0x2003, 0x0000, 0x2001, 0x183d, 0x2003, 0x0020, 0x080c, 0x8992,
- 0x00e6, 0x2071, 0x1932, 0x080c, 0x8dc3, 0x080c, 0x8dd2, 0x00ee,
- 0x012e, 0x0804, 0x35b0, 0x0006, 0x080c, 0x57cd, 0xd0cc, 0x000e,
- 0x0005, 0x0006, 0x080c, 0x57d1, 0xd0bc, 0x000e, 0x0005, 0x6174,
- 0x7a84, 0x6300, 0x82ff, 0x1118, 0x7986, 0x0804, 0x35b0, 0x83ff,
- 0x1904, 0x35e5, 0x2001, 0xfff0, 0x9200, 0x1a04, 0x35e5, 0x2019,
- 0xffff, 0x6078, 0x9302, 0x9200, 0x0a04, 0x35e5, 0x7986, 0x6276,
- 0x0804, 0x35b0, 0x080c, 0x57e1, 0x1904, 0x35e2, 0x7c88, 0x7d84,
- 0x7e98, 0x7f8c, 0x080c, 0x4b83, 0x0904, 0x35e2, 0x900e, 0x901e,
- 0x7326, 0x7332, 0xa860, 0x20e8, 0x7036, 0xa85c, 0x9080, 0x0003,
- 0x702a, 0x20a0, 0x91d8, 0x1000, 0x2b5c, 0x8bff, 0x0178, 0x080c,
- 0x6a8c, 0x0118, 0x080c, 0x6a94, 0x1148, 0x20a9, 0x0001, 0xb814,
- 0x4004, 0xb810, 0x4004, 0x4104, 0x9398, 0x0003, 0x8108, 0x9182,
- 0x0800, 0x0120, 0x9386, 0x003c, 0x0170, 0x0c20, 0x83ff, 0x1148,
- 0x7224, 0x900e, 0x2001, 0x0003, 0x080c, 0x91ab, 0x2208, 0x0804,
- 0x35b0, 0x7033, 0x0001, 0x7122, 0x7024, 0x9300, 0x7026, 0x2061,
- 0x18b8, 0x2c44, 0xa06b, 0x0000, 0xa37a, 0x7028, 0xa076, 0x7034,
- 0xa072, 0xa48e, 0xa592, 0xa696, 0xa79a, 0x080c, 0x10f8, 0x7007,
- 0x0002, 0x701f, 0x5144, 0x0005, 0x7030, 0x9005, 0x1178, 0x7120,
- 0x7028, 0x20a0, 0x901e, 0x7034, 0x20e8, 0x2061, 0x18b8, 0x2c44,
- 0xa48c, 0xa590, 0xa694, 0xa798, 0x0804, 0x5102, 0x7224, 0x900e,
- 0x2001, 0x0003, 0x080c, 0x91ab, 0x2208, 0x0804, 0x35b0, 0x00f6,
- 0x00e6, 0x080c, 0x57e1, 0x2009, 0x0007, 0x1904, 0x51d7, 0x2071,
- 0x189e, 0x745c, 0x84ff, 0x2009, 0x000e, 0x1904, 0x51d7, 0xac9c,
- 0xad98, 0xaea4, 0xafa0, 0x0096, 0x080c, 0x1027, 0x2009, 0x0002,
- 0x0904, 0x51d7, 0x2900, 0x705e, 0x900e, 0x901e, 0x7356, 0x7362,
- 0xa860, 0x7066, 0xa85c, 0x9080, 0x0003, 0x705a, 0x20a0, 0x91d8,
- 0x1000, 0x2b5c, 0x8bff, 0x0178, 0x080c, 0x6a8c, 0x0118, 0x080c,
- 0x6a94, 0x1148, 0xb814, 0x20a9, 0x0001, 0x4004, 0xb810, 0x4004,
+ 0x8108, 0x2105, 0x9005, 0xa94a, 0x1904, 0x4d42, 0xa804, 0x9005,
+ 0x090c, 0x0dc5, 0x7042, 0x2938, 0x2040, 0xa003, 0x0000, 0x2001,
+ 0x0002, 0x9080, 0x20f0, 0x2005, 0xa04a, 0x0804, 0x4d42, 0x703c,
+ 0x2060, 0x2c14, 0x6304, 0x6408, 0x650c, 0x2200, 0x7836, 0x7833,
+ 0x0012, 0x7882, 0x2300, 0x7886, 0x2400, 0x788a, 0x2091, 0x4080,
+ 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x11aa, 0x87ff, 0x0118,
+ 0x2748, 0x080c, 0x1040, 0x7048, 0x8001, 0x704a, 0x9005, 0x1170,
+ 0x7040, 0x2048, 0x9005, 0x0128, 0x080c, 0x1040, 0x9006, 0x7042,
+ 0x7046, 0x703b, 0x18ba, 0x703f, 0x18ba, 0x0420, 0x7040, 0x9005,
+ 0x1508, 0x7238, 0x2c00, 0x9206, 0x0148, 0x9c80, 0x0004, 0x90fa,
+ 0x18fa, 0x0210, 0x2001, 0x18ba, 0x703e, 0x00a0, 0x9006, 0x703e,
+ 0x703a, 0x7044, 0x9005, 0x090c, 0x0dc5, 0x2048, 0xa800, 0x9005,
+ 0x1de0, 0x2900, 0x7042, 0x2001, 0x0002, 0x9080, 0x20f0, 0x2005,
+ 0xa84a, 0x0000, 0x007e, 0x008e, 0x009e, 0x00ce, 0x00fe, 0x012e,
+ 0x00ee, 0x0005, 0x2c00, 0x9082, 0x001b, 0x0002, 0x4d61, 0x4d61,
+ 0x4d63, 0x4d61, 0x4d61, 0x4d61, 0x4d68, 0x4d61, 0x4d61, 0x4d61,
+ 0x4d6d, 0x4d61, 0x4d61, 0x4d61, 0x4d72, 0x4d61, 0x4d61, 0x4d61,
+ 0x4d77, 0x4d61, 0x4d61, 0x4d61, 0x4d7c, 0x4d61, 0x4d61, 0x4d61,
+ 0x4d81, 0x080c, 0x0dc5, 0xaa74, 0xab78, 0xac7c, 0x0804, 0x4ced,
+ 0xaa84, 0xab88, 0xac8c, 0x0804, 0x4ced, 0xaa94, 0xab98, 0xac9c,
+ 0x0804, 0x4ced, 0xaaa4, 0xaba8, 0xacac, 0x0804, 0x4ced, 0xaab4,
+ 0xabb8, 0xacbc, 0x0804, 0x4ced, 0xaac4, 0xabc8, 0xaccc, 0x0804,
+ 0x4ced, 0xaad4, 0xabd8, 0xacdc, 0x0804, 0x4ced, 0x0016, 0x0026,
+ 0x0036, 0x00b6, 0x00c6, 0x2009, 0x007e, 0x080c, 0x671d, 0x2019,
+ 0x0001, 0xb85c, 0xd0ac, 0x0110, 0x2019, 0x0000, 0x2011, 0x801b,
+ 0x080c, 0x4be9, 0x00ce, 0x00be, 0x003e, 0x002e, 0x001e, 0x0005,
+ 0x0026, 0x080c, 0x57d3, 0xd0c4, 0x0120, 0x2011, 0x8014, 0x080c,
+ 0x4be9, 0x002e, 0x0005, 0x81ff, 0x1904, 0x35dd, 0x0126, 0x2091,
+ 0x8000, 0x6030, 0xc08d, 0xc085, 0xc0ac, 0x6032, 0x080c, 0x7569,
+ 0x1158, 0x080c, 0x784e, 0x080c, 0x6127, 0x9085, 0x0001, 0x080c,
+ 0x75ad, 0x080c, 0x7495, 0x0010, 0x080c, 0x5fe6, 0x012e, 0x0804,
+ 0x35ab, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x35dd, 0x080c,
+ 0x57e7, 0x0120, 0x2009, 0x0007, 0x0804, 0x35dd, 0x080c, 0x6a8a,
+ 0x0120, 0x2009, 0x0008, 0x0804, 0x35dd, 0x7984, 0x080c, 0x66b2,
+ 0x1904, 0x35e0, 0x080c, 0x4bbc, 0x0904, 0x35e0, 0x2b00, 0x7026,
+ 0x080c, 0x6a92, 0x7888, 0x1170, 0x9084, 0x0005, 0x1158, 0x900e,
+ 0x080c, 0x693d, 0x1108, 0xc185, 0xb800, 0xd0bc, 0x0108, 0xc18d,
+ 0x0804, 0x35ab, 0x080c, 0x4b89, 0x0904, 0x35dd, 0x9006, 0xa866,
+ 0xa832, 0xa868, 0xc0fd, 0xa86a, 0x080c, 0xd080, 0x0904, 0x35dd,
+ 0x7888, 0xd094, 0x0118, 0xb8cc, 0xc08d, 0xb8ce, 0x7007, 0x0003,
+ 0x701f, 0x4e5c, 0x0005, 0x2061, 0x1800, 0x080c, 0x57e7, 0x2009,
+ 0x0007, 0x1560, 0x080c, 0x6a8a, 0x0118, 0x2009, 0x0008, 0x0430,
+ 0xa998, 0x080c, 0x66b2, 0x1530, 0x080c, 0x4bba, 0x0518, 0x080c,
+ 0x6a92, 0xa89c, 0x1168, 0x9084, 0x0005, 0x1150, 0x900e, 0x080c,
+ 0x693d, 0x1108, 0xc185, 0xb800, 0xd0bc, 0x0108, 0xc18d, 0x00d0,
+ 0xa868, 0xc0fc, 0xa86a, 0x080c, 0xd080, 0x11e0, 0xa89c, 0xd094,
+ 0x0118, 0xb8cc, 0xc08d, 0xb8ce, 0x2009, 0x0003, 0xa897, 0x4005,
+ 0xa99a, 0x0010, 0xa897, 0x4006, 0x900e, 0x9085, 0x0001, 0x2001,
+ 0x0030, 0x0005, 0xa897, 0x4000, 0xa99a, 0x9006, 0x918d, 0x0001,
+ 0x2008, 0x0005, 0x9006, 0x0005, 0xa830, 0x9086, 0x0100, 0x7024,
+ 0x2058, 0x1110, 0x0804, 0x5727, 0x900e, 0x080c, 0x693d, 0x1108,
+ 0xc185, 0xb800, 0xd0bc, 0x0108, 0xc18d, 0x0804, 0x35ab, 0x080c,
+ 0x57e7, 0x0120, 0x2009, 0x0007, 0x0804, 0x35dd, 0x7f84, 0x7a8c,
+ 0x7b88, 0x7c9c, 0x7d98, 0x080c, 0x4b89, 0x1120, 0x2009, 0x0002,
+ 0x0804, 0x35dd, 0x900e, 0x2130, 0x7126, 0x7132, 0xa860, 0x20e8,
+ 0x7036, 0xa85c, 0x9080, 0x0005, 0x702a, 0x20a0, 0x080c, 0x671d,
+ 0x1904, 0x4f05, 0x080c, 0x6a92, 0x0138, 0x080c, 0x6a9a, 0x0120,
+ 0x080c, 0x6a32, 0x1904, 0x4f05, 0xd794, 0x1110, 0xd784, 0x01a8,
+ 0xb8c4, 0x20e0, 0xb8c8, 0x9080, 0x0006, 0x2098, 0x3400, 0xd794,
+ 0x0198, 0x20a9, 0x0008, 0x4003, 0x2098, 0x20a0, 0x3d00, 0x20e0,
+ 0x20a9, 0x0002, 0x080c, 0x4988, 0x0080, 0xb8c4, 0x20e0, 0xb8c8,
+ 0x9080, 0x000a, 0x2098, 0x3400, 0x20a9, 0x0004, 0x4003, 0x2098,
+ 0x20a0, 0x3d00, 0x20e0, 0x080c, 0x4988, 0x9186, 0x007e, 0x0170,
+ 0x9186, 0x0080, 0x0158, 0x080c, 0x6a92, 0x90c2, 0x0006, 0x1210,
+ 0xc1fd, 0x0020, 0x080c, 0x693d, 0x1108, 0xc1fd, 0x4104, 0xc1fc,
+ 0xd794, 0x0528, 0xb8c4, 0x20e0, 0xb8c8, 0x2060, 0x9c80, 0x0000,
+ 0x2098, 0x20a9, 0x0002, 0x4003, 0x9c80, 0x0003, 0x2098, 0x20a9,
+ 0x0001, 0x4005, 0x9c80, 0x0004, 0x2098, 0x3400, 0x20a9, 0x0002,
+ 0x4003, 0x2098, 0x20a0, 0x3d00, 0x20e0, 0x080c, 0x497b, 0x9c80,
+ 0x0026, 0x2098, 0xb8c4, 0x20e0, 0x20a9, 0x0002, 0x4003, 0xd794,
+ 0x0110, 0x96b0, 0x000b, 0x96b0, 0x0005, 0x8108, 0x080c, 0xb06b,
+ 0x0118, 0x9186, 0x0800, 0x0040, 0xd78c, 0x0120, 0x9186, 0x0800,
+ 0x0170, 0x0018, 0x9186, 0x007e, 0x0150, 0xd794, 0x0118, 0x9686,
+ 0x0020, 0x0010, 0x9686, 0x0028, 0x0150, 0x0804, 0x4e8e, 0x86ff,
+ 0x1120, 0x7124, 0x810b, 0x0804, 0x35ab, 0x7033, 0x0001, 0x7122,
+ 0x7024, 0x9600, 0x7026, 0x772e, 0x2061, 0x18b8, 0x2c44, 0xa06b,
+ 0x0000, 0xa67a, 0x7034, 0xa072, 0x7028, 0xa076, 0xa28e, 0xa392,
+ 0xa496, 0xa59a, 0x080c, 0x10f8, 0x7007, 0x0002, 0x701f, 0x4f41,
+ 0x0005, 0x7030, 0x9005, 0x1180, 0x7120, 0x7028, 0x20a0, 0x772c,
+ 0x9036, 0x7034, 0x20e8, 0x2061, 0x18b8, 0x2c44, 0xa28c, 0xa390,
+ 0xa494, 0xa598, 0x0804, 0x4e8e, 0x7124, 0x810b, 0x0804, 0x35ab,
+ 0x2029, 0x007e, 0x7984, 0x7a88, 0x7b8c, 0x7c98, 0x9184, 0xff00,
+ 0x8007, 0x90e2, 0x0020, 0x0a04, 0x35e0, 0x9502, 0x0a04, 0x35e0,
+ 0x9184, 0x00ff, 0x90e2, 0x0020, 0x0a04, 0x35e0, 0x9502, 0x0a04,
+ 0x35e0, 0x9284, 0xff00, 0x8007, 0x90e2, 0x0020, 0x0a04, 0x35e0,
+ 0x9502, 0x0a04, 0x35e0, 0x9284, 0x00ff, 0x90e2, 0x0020, 0x0a04,
+ 0x35e0, 0x9502, 0x0a04, 0x35e0, 0x9384, 0xff00, 0x8007, 0x90e2,
+ 0x0020, 0x0a04, 0x35e0, 0x9502, 0x0a04, 0x35e0, 0x9384, 0x00ff,
+ 0x90e2, 0x0020, 0x0a04, 0x35e0, 0x9502, 0x0a04, 0x35e0, 0x9484,
+ 0xff00, 0x8007, 0x90e2, 0x0020, 0x0a04, 0x35e0, 0x9502, 0x0a04,
+ 0x35e0, 0x9484, 0x00ff, 0x90e2, 0x0020, 0x0a04, 0x35e0, 0x9502,
+ 0x0a04, 0x35e0, 0x2061, 0x198a, 0x6102, 0x6206, 0x630a, 0x640e,
+ 0x0804, 0x35ab, 0x080c, 0x4b89, 0x0904, 0x35dd, 0x2009, 0x0016,
+ 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0xa85c, 0x9080, 0x0019, 0xaf60,
+ 0x080c, 0x4bd2, 0x701f, 0x4fc5, 0x0005, 0x2001, 0x0138, 0x2003,
+ 0x0000, 0x00e6, 0x2071, 0x0300, 0x701c, 0xd0a4, 0x1de8, 0x00ee,
+ 0x20a9, 0x0016, 0x896e, 0x8d6e, 0x8d6f, 0x9d84, 0xffc0, 0x9080,
+ 0x0019, 0x2098, 0x9d84, 0x003f, 0x20e0, 0x2069, 0x1877, 0x20e9,
+ 0x0001, 0x2da0, 0x4003, 0x6800, 0x9005, 0x0904, 0x5046, 0x6804,
+ 0x2008, 0x918c, 0xfff8, 0x1904, 0x5046, 0x680c, 0x9005, 0x0904,
+ 0x5046, 0x9082, 0xff01, 0x1a04, 0x5046, 0x6810, 0x9082, 0x005c,
+ 0x0a04, 0x5046, 0x6824, 0x2008, 0x9082, 0x0008, 0x0a04, 0x5046,
+ 0x9182, 0x0400, 0x1a04, 0x5046, 0x0056, 0x2029, 0x0000, 0x080c,
+ 0x8d49, 0x005e, 0x6944, 0x6820, 0x9102, 0x06c0, 0x6820, 0x9082,
+ 0x0019, 0x16a0, 0x6828, 0x6944, 0x810c, 0x9102, 0x0678, 0x6840,
+ 0x9082, 0x000f, 0x1658, 0x080c, 0x1027, 0x2900, 0x0904, 0x5062,
+ 0x684e, 0x00e6, 0x2071, 0x1932, 0x00b6, 0x2059, 0x0000, 0x080c,
+ 0x8c05, 0x00be, 0x00ee, 0x0568, 0x080c, 0x8950, 0x080c, 0x899f,
+ 0x11e0, 0x6857, 0x0000, 0x00c6, 0x2061, 0x0100, 0x6104, 0x918d,
+ 0x2000, 0x6106, 0x6b10, 0x2061, 0x1a66, 0x630a, 0x00ce, 0x080c,
+ 0x29ac, 0x2001, 0x0138, 0x2102, 0x0804, 0x35ab, 0x080c, 0x29ac,
+ 0x2001, 0x0138, 0x2102, 0x0804, 0x35e0, 0x080c, 0x8998, 0x00e6,
+ 0x2071, 0x1932, 0x080c, 0x8dc9, 0x080c, 0x8dd8, 0x080c, 0x8be8,
+ 0x00ee, 0x2001, 0x188a, 0x204c, 0x080c, 0x1040, 0x2001, 0x188a,
+ 0x2003, 0x0000, 0x080c, 0x29ac, 0x2001, 0x0138, 0x2102, 0x0804,
+ 0x35dd, 0x2001, 0x1926, 0x200c, 0x918e, 0x0000, 0x0904, 0x50c7,
+ 0x080c, 0x8be3, 0x0904, 0x50c7, 0x2001, 0x0101, 0x200c, 0x918c,
+ 0xdfff, 0x2102, 0x2001, 0x0138, 0x2003, 0x0000, 0x00e6, 0x2071,
+ 0x0300, 0x701c, 0xd0a4, 0x1de8, 0x00ee, 0x080c, 0x8be8, 0x0126,
+ 0x2091, 0x8000, 0x2001, 0x0035, 0x080c, 0x1611, 0x012e, 0x00c6,
+ 0x2061, 0x193e, 0x6004, 0x6100, 0x9106, 0x1de0, 0x00ce, 0x080c,
+ 0x29ac, 0x2001, 0x0138, 0x2102, 0x00e6, 0x00f6, 0x2071, 0x1925,
+ 0x080c, 0x8b22, 0x0120, 0x2f00, 0x080c, 0x8bae, 0x0cc8, 0x00fe,
+ 0x00ee, 0x0126, 0x2091, 0x8000, 0x2001, 0x188a, 0x200c, 0x81ff,
+ 0x0138, 0x2148, 0x080c, 0x1040, 0x2001, 0x188a, 0x2003, 0x0000,
+ 0x2001, 0x183d, 0x2003, 0x0020, 0x080c, 0x8998, 0x00e6, 0x2071,
+ 0x1932, 0x080c, 0x8dc9, 0x080c, 0x8dd8, 0x00ee, 0x012e, 0x0804,
+ 0x35ab, 0x0006, 0x080c, 0x57d3, 0xd0cc, 0x000e, 0x0005, 0x0006,
+ 0x080c, 0x57d7, 0xd0bc, 0x000e, 0x0005, 0x6174, 0x7a84, 0x6300,
+ 0x82ff, 0x1118, 0x7986, 0x0804, 0x35ab, 0x83ff, 0x1904, 0x35e0,
+ 0x2001, 0xfff0, 0x9200, 0x1a04, 0x35e0, 0x2019, 0xffff, 0x6078,
+ 0x9302, 0x9200, 0x0a04, 0x35e0, 0x7986, 0x6276, 0x0804, 0x35ab,
+ 0x080c, 0x57e7, 0x1904, 0x35dd, 0x7c88, 0x7d84, 0x7e98, 0x7f8c,
+ 0x080c, 0x4b89, 0x0904, 0x35dd, 0x900e, 0x901e, 0x7326, 0x7332,
+ 0xa860, 0x20e8, 0x7036, 0xa85c, 0x9080, 0x0003, 0x702a, 0x20a0,
+ 0x91d8, 0x1000, 0x2b5c, 0x8bff, 0x0178, 0x080c, 0x6a92, 0x0118,
+ 0x080c, 0x6a9a, 0x1148, 0x20a9, 0x0001, 0xb814, 0x4004, 0xb810,
+ 0x4004, 0x4104, 0x9398, 0x0003, 0x8108, 0x9182, 0x0800, 0x0120,
+ 0x9386, 0x003c, 0x0170, 0x0c20, 0x83ff, 0x1148, 0x7224, 0x900e,
+ 0x2001, 0x0003, 0x080c, 0x91b1, 0x2208, 0x0804, 0x35ab, 0x7033,
+ 0x0001, 0x7122, 0x7024, 0x9300, 0x7026, 0x2061, 0x18b8, 0x2c44,
+ 0xa06b, 0x0000, 0xa37a, 0x7028, 0xa076, 0x7034, 0xa072, 0xa48e,
+ 0xa592, 0xa696, 0xa79a, 0x080c, 0x10f8, 0x7007, 0x0002, 0x701f,
+ 0x514a, 0x0005, 0x7030, 0x9005, 0x1178, 0x7120, 0x7028, 0x20a0,
+ 0x901e, 0x7034, 0x20e8, 0x2061, 0x18b8, 0x2c44, 0xa48c, 0xa590,
+ 0xa694, 0xa798, 0x0804, 0x5108, 0x7224, 0x900e, 0x2001, 0x0003,
+ 0x080c, 0x91b1, 0x2208, 0x0804, 0x35ab, 0x00f6, 0x00e6, 0x080c,
+ 0x57e7, 0x2009, 0x0007, 0x1904, 0x51dd, 0x2071, 0x189e, 0x745c,
+ 0x84ff, 0x2009, 0x000e, 0x1904, 0x51dd, 0xac9c, 0xad98, 0xaea4,
+ 0xafa0, 0x0096, 0x080c, 0x1027, 0x2009, 0x0002, 0x0904, 0x51dd,
+ 0x2900, 0x705e, 0x900e, 0x901e, 0x7356, 0x7362, 0xa860, 0x7066,
+ 0xa85c, 0x9080, 0x0003, 0x705a, 0x20a0, 0x91d8, 0x1000, 0x2b5c,
+ 0x8bff, 0x0178, 0x080c, 0x6a92, 0x0118, 0x080c, 0x6a9a, 0x1148,
+ 0xb814, 0x20a9, 0x0001, 0x4004, 0xb810, 0x4004, 0x4104, 0x9398,
+ 0x0003, 0x8108, 0x9182, 0x0800, 0x0120, 0x9386, 0x003c, 0x01e8,
+ 0x0c20, 0x83ff, 0x11c0, 0x7254, 0x900e, 0x2001, 0x0003, 0x080c,
+ 0x91b1, 0x2208, 0x009e, 0xa897, 0x4000, 0xa99a, 0x715c, 0x81ff,
+ 0x090c, 0x0dc5, 0x2148, 0x080c, 0x1040, 0x9006, 0x705e, 0x918d,
+ 0x0001, 0x2008, 0x0418, 0x7063, 0x0001, 0x7152, 0x7054, 0x9300,
+ 0x7056, 0x2061, 0x18b9, 0x2c44, 0xa37a, 0x7058, 0xa076, 0x7064,
+ 0xa072, 0xa48e, 0xa592, 0xa696, 0xa79a, 0xa09f, 0x51e9, 0x000e,
+ 0xa0a2, 0x080c, 0x10f8, 0x9006, 0x0048, 0x009e, 0xa897, 0x4005,
+ 0xa99a, 0x900e, 0x9085, 0x0001, 0x2001, 0x0030, 0x00ee, 0x00fe,
+ 0x0005, 0x00f6, 0xa0a0, 0x904d, 0x090c, 0x0dc5, 0x00e6, 0x2071,
+ 0x189e, 0xa06c, 0x908e, 0x0100, 0x0138, 0xa87b, 0x0030, 0xa883,
+ 0x0000, 0xa897, 0x4002, 0x00d8, 0x7060, 0x9005, 0x1158, 0x7150,
+ 0x7058, 0x20a0, 0x901e, 0x7064, 0x20e8, 0xa48c, 0xa590, 0xa694,
+ 0xa798, 0x0428, 0xa87b, 0x0000, 0xa883, 0x0000, 0xa897, 0x4000,
+ 0x7254, 0x900e, 0x2001, 0x0003, 0x080c, 0x91b1, 0xaa9a, 0x715c,
+ 0x81ff, 0x090c, 0x0dc5, 0x2148, 0x080c, 0x1040, 0x705f, 0x0000,
+ 0xa0a0, 0x2048, 0x0126, 0x2091, 0x8000, 0x080c, 0x6dd1, 0x012e,
+ 0xa09f, 0x0000, 0xa0a3, 0x0000, 0x00ee, 0x00fe, 0x0005, 0x91d8,
+ 0x1000, 0x2b5c, 0x8bff, 0x0178, 0x080c, 0x6a92, 0x0118, 0x080c,
+ 0x6a9a, 0x1148, 0xb814, 0x20a9, 0x0001, 0x4004, 0xb810, 0x4004,
0x4104, 0x9398, 0x0003, 0x8108, 0x9182, 0x0800, 0x0120, 0x9386,
- 0x003c, 0x01e8, 0x0c20, 0x83ff, 0x11c0, 0x7254, 0x900e, 0x2001,
- 0x0003, 0x080c, 0x91ab, 0x2208, 0x009e, 0xa897, 0x4000, 0xa99a,
- 0x715c, 0x81ff, 0x090c, 0x0dc5, 0x2148, 0x080c, 0x1040, 0x9006,
- 0x705e, 0x918d, 0x0001, 0x2008, 0x0418, 0x7063, 0x0001, 0x7152,
- 0x7054, 0x9300, 0x7056, 0x2061, 0x18b9, 0x2c44, 0xa37a, 0x7058,
- 0xa076, 0x7064, 0xa072, 0xa48e, 0xa592, 0xa696, 0xa79a, 0xa09f,
- 0x51e3, 0x000e, 0xa0a2, 0x080c, 0x10f8, 0x9006, 0x0048, 0x009e,
- 0xa897, 0x4005, 0xa99a, 0x900e, 0x9085, 0x0001, 0x2001, 0x0030,
- 0x00ee, 0x00fe, 0x0005, 0x00f6, 0xa0a0, 0x904d, 0x090c, 0x0dc5,
- 0x00e6, 0x2071, 0x189e, 0xa06c, 0x908e, 0x0100, 0x0138, 0xa87b,
- 0x0030, 0xa883, 0x0000, 0xa897, 0x4002, 0x00d8, 0x7060, 0x9005,
- 0x1158, 0x7150, 0x7058, 0x20a0, 0x901e, 0x7064, 0x20e8, 0xa48c,
- 0xa590, 0xa694, 0xa798, 0x0428, 0xa87b, 0x0000, 0xa883, 0x0000,
- 0xa897, 0x4000, 0x7254, 0x900e, 0x2001, 0x0003, 0x080c, 0x91ab,
- 0xaa9a, 0x715c, 0x81ff, 0x090c, 0x0dc5, 0x2148, 0x080c, 0x1040,
- 0x705f, 0x0000, 0xa0a0, 0x2048, 0x0126, 0x2091, 0x8000, 0x080c,
- 0x6dcb, 0x012e, 0xa09f, 0x0000, 0xa0a3, 0x0000, 0x00ee, 0x00fe,
- 0x0005, 0x91d8, 0x1000, 0x2b5c, 0x8bff, 0x0178, 0x080c, 0x6a8c,
- 0x0118, 0x080c, 0x6a94, 0x1148, 0xb814, 0x20a9, 0x0001, 0x4004,
- 0xb810, 0x4004, 0x4104, 0x9398, 0x0003, 0x8108, 0x9182, 0x0800,
- 0x0120, 0x9386, 0x003c, 0x0518, 0x0c20, 0x83ff, 0x11f0, 0x7154,
- 0x810c, 0xa99a, 0xa897, 0x4000, 0x715c, 0x81ff, 0x090c, 0x0dc5,
- 0x2148, 0x080c, 0x1040, 0x9006, 0x705e, 0x918d, 0x0001, 0x2008,
- 0xa0a0, 0x2048, 0x0126, 0x2091, 0x8000, 0x080c, 0x6dcb, 0x012e,
- 0xa09f, 0x0000, 0xa0a3, 0x0000, 0x0070, 0x7063, 0x0001, 0x7152,
- 0x7054, 0x9300, 0x7056, 0xa37a, 0xa48e, 0xa592, 0xa696, 0xa79a,
- 0x080c, 0x10f8, 0x9006, 0x00ee, 0x0005, 0x0096, 0xa88c, 0x90be,
- 0x7000, 0x0148, 0x90be, 0x7100, 0x0130, 0x90be, 0x7200, 0x0118,
- 0x009e, 0x0804, 0x35e5, 0xa884, 0xa988, 0x080c, 0x2889, 0x1518,
- 0x080c, 0x66ac, 0x1500, 0x7126, 0xbe12, 0xbd16, 0xae7c, 0x080c,
- 0x4b83, 0x01c8, 0x080c, 0x4b83, 0x01b0, 0x009e, 0xa867, 0x0000,
- 0xa868, 0xc0fd, 0xa86a, 0xa823, 0x0000, 0xa804, 0x2048, 0x080c,
- 0xcfeb, 0x1120, 0x2009, 0x0003, 0x0804, 0x35e2, 0x7007, 0x0003,
- 0x701f, 0x52b0, 0x0005, 0x009e, 0x2009, 0x0002, 0x0804, 0x35e2,
- 0x7124, 0x080c, 0x3347, 0xa820, 0x9086, 0x8001, 0x1120, 0x2009,
- 0x0004, 0x0804, 0x35e2, 0x2900, 0x7022, 0xa804, 0x0096, 0x2048,
- 0x8906, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x009e,
- 0x9080, 0x0002, 0x0076, 0x0006, 0x2098, 0x20a0, 0x27e0, 0x27e8,
- 0x20a9, 0x002a, 0x080c, 0x0f8b, 0xaa6c, 0xab70, 0xac74, 0xad78,
- 0x2061, 0x18b8, 0x2c44, 0xa06b, 0x0000, 0xae64, 0xaf8c, 0x97c6,
- 0x7000, 0x0118, 0x97c6, 0x7100, 0x1148, 0x96c2, 0x0004, 0x0600,
- 0x2009, 0x0004, 0x000e, 0x007e, 0x0804, 0x4bcf, 0x97c6, 0x7200,
- 0x11b8, 0x96c2, 0x0054, 0x02a0, 0x000e, 0x007e, 0x2061, 0x18b8,
- 0x2c44, 0xa076, 0xa772, 0xa07b, 0x002a, 0xa28e, 0xa392, 0xa496,
- 0xa59a, 0x080c, 0x10f8, 0x7007, 0x0002, 0x701f, 0x530c, 0x0005,
- 0x000e, 0x007e, 0x0804, 0x35e5, 0x7020, 0x2048, 0xa804, 0x2048,
- 0xa804, 0x2048, 0x8906, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084,
- 0xffc0, 0x9080, 0x0002, 0x2098, 0x20a0, 0x27e0, 0x27e8, 0x20a9,
- 0x002a, 0x080c, 0x0f8b, 0x2100, 0x2238, 0x2061, 0x18b8, 0x2c44,
- 0xa28c, 0xa390, 0xa494, 0xa598, 0x2009, 0x002a, 0x0804, 0x4bcf,
- 0x81ff, 0x1904, 0x35e2, 0x798c, 0x2001, 0x197f, 0x918c, 0x8000,
- 0x2102, 0x080c, 0x4b9a, 0x0904, 0x35e5, 0x080c, 0x6a8c, 0x0120,
- 0x080c, 0x6a94, 0x1904, 0x35e5, 0x080c, 0x67de, 0x0904, 0x35e2,
- 0x0126, 0x2091, 0x8000, 0x080c, 0x68a4, 0x012e, 0x0904, 0x35e2,
- 0x2001, 0x197f, 0x2004, 0xd0fc, 0x1904, 0x35b0, 0x0804, 0x45db,
- 0xa9a0, 0x2001, 0x197f, 0x918c, 0x8000, 0xc18d, 0x2102, 0x080c,
- 0x4ba7, 0x01a0, 0x080c, 0x6a8c, 0x0118, 0x080c, 0x6a94, 0x1170,
- 0x080c, 0x67de, 0x2009, 0x0002, 0x0128, 0x080c, 0x68a4, 0x1170,
- 0x2009, 0x0003, 0xa897, 0x4005, 0xa99a, 0x0010, 0xa897, 0x4006,
- 0x900e, 0x9085, 0x0001, 0x2001, 0x0030, 0x0005, 0xa897, 0x4000,
- 0x2001, 0x197f, 0x2004, 0xd0fc, 0x1128, 0x080c, 0x57d5, 0x0110,
- 0x9006, 0x0018, 0x900e, 0x9085, 0x0001, 0x2001, 0x0000, 0x0005,
- 0x78a8, 0xd08c, 0x1118, 0xd084, 0x0904, 0x4550, 0x080c, 0x4bb6,
- 0x0904, 0x35e5, 0x080c, 0x4b83, 0x1120, 0x2009, 0x0002, 0x0804,
- 0x35e2, 0x080c, 0x6a8c, 0x0130, 0x908e, 0x0004, 0x0118, 0x908e,
- 0x0005, 0x15a0, 0x78a8, 0xd08c, 0x0120, 0xb800, 0xc08c, 0xb802,
- 0x0028, 0x080c, 0x57cd, 0xd0b4, 0x0904, 0x458a, 0x7884, 0x908e,
- 0x007e, 0x0904, 0x458a, 0x908e, 0x007f, 0x0904, 0x458a, 0x908e,
- 0x0080, 0x0904, 0x458a, 0xb800, 0xd08c, 0x1904, 0x458a, 0xa867,
- 0x0000, 0xa868, 0xc0fd, 0xa86a, 0x080c, 0xd00a, 0x1120, 0x2009,
- 0x0003, 0x0804, 0x35e2, 0x7007, 0x0003, 0x701f, 0x53d8, 0x0005,
- 0x080c, 0x4bb6, 0x0904, 0x35e5, 0x0804, 0x458a, 0x080c, 0x33a0,
- 0x0108, 0x0005, 0x2009, 0x1834, 0x210c, 0x81ff, 0x0120, 0x2009,
- 0x0001, 0x0804, 0x35e2, 0x080c, 0x57e1, 0x0120, 0x2009, 0x0007,
- 0x0804, 0x35e2, 0x080c, 0x6a84, 0x0120, 0x2009, 0x0008, 0x0804,
- 0x35e2, 0xb89c, 0xd0a4, 0x1118, 0xd0ac, 0x1904, 0x458a, 0x9006,
- 0xa866, 0xa832, 0xa868, 0xc0fd, 0xa86a, 0x080c, 0xd069, 0x1120,
- 0x2009, 0x0003, 0x0804, 0x35e2, 0x7007, 0x0003, 0x701f, 0x5411,
- 0x0005, 0xa830, 0x9086, 0x0100, 0x1120, 0x2009, 0x0004, 0x0804,
- 0x5721, 0x080c, 0x4bb6, 0x0904, 0x35e5, 0x0804, 0x53aa, 0x81ff,
- 0x2009, 0x0001, 0x1904, 0x35e2, 0x080c, 0x57e1, 0x2009, 0x0007,
- 0x1904, 0x35e2, 0x080c, 0x6a84, 0x0120, 0x2009, 0x0008, 0x0804,
- 0x35e2, 0x080c, 0x4bb6, 0x0904, 0x35e5, 0x080c, 0x6a8c, 0x2009,
- 0x0009, 0x1904, 0x35e2, 0x080c, 0x4b83, 0x2009, 0x0002, 0x0904,
- 0x35e2, 0x9006, 0xa866, 0xa832, 0xa868, 0xc0fd, 0xa86a, 0x7988,
- 0xa95a, 0x9194, 0xfd00, 0x918c, 0x00ff, 0x9006, 0x82ff, 0x1128,
- 0xc0ed, 0xa952, 0x798c, 0xa956, 0x0038, 0x928e, 0x0100, 0x1904,
- 0x35e5, 0xc0e5, 0xa952, 0xa956, 0xa83e, 0x080c, 0xd2bc, 0x2009,
- 0x0003, 0x0904, 0x35e2, 0x7007, 0x0003, 0x701f, 0x5468, 0x0005,
- 0xa830, 0x9086, 0x0100, 0x2009, 0x0004, 0x0904, 0x35e2, 0x0804,
- 0x35b0, 0x7aa8, 0x9284, 0xc000, 0x0148, 0xd2ec, 0x01a0, 0x080c,
- 0x57e1, 0x1188, 0x2009, 0x0014, 0x0804, 0x35e2, 0xd2dc, 0x1578,
- 0x81ff, 0x2009, 0x0001, 0x1904, 0x35e2, 0x080c, 0x57e1, 0x2009,
- 0x0007, 0x1904, 0x35e2, 0xd2f4, 0x0138, 0x9284, 0x5000, 0xc0d5,
- 0x080c, 0x57a7, 0x0804, 0x35b0, 0xd2fc, 0x0160, 0x080c, 0x4bb6,
- 0x0904, 0x35e5, 0x7984, 0x9284, 0x9000, 0xc0d5, 0x080c, 0x577c,
- 0x0804, 0x35b0, 0x080c, 0x4bb6, 0x0904, 0x35e5, 0xb804, 0x9084,
- 0x00ff, 0x9086, 0x0006, 0x2009, 0x0009, 0x1904, 0x5557, 0x080c,
- 0x4b83, 0x2009, 0x0002, 0x0904, 0x5557, 0xa85c, 0x9080, 0x001b,
- 0xaf60, 0x2009, 0x0008, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0x080c,
- 0x4bcc, 0x701f, 0x54c4, 0x0005, 0xa86c, 0x9086, 0x0500, 0x1138,
- 0xa870, 0x9005, 0x1120, 0xa874, 0x9084, 0xff00, 0x0110, 0x1904,
- 0x35e5, 0xa866, 0xa832, 0xa868, 0xc0fd, 0xa86a, 0x080c, 0x4bb6,
- 0x1110, 0x0804, 0x35e5, 0x2009, 0x0043, 0x080c, 0xd328, 0x2009,
- 0x0003, 0x0904, 0x5557, 0x7007, 0x0003, 0x701f, 0x54e8, 0x0005,
- 0xa830, 0x9086, 0x0100, 0x2009, 0x0004, 0x0904, 0x5557, 0x7984,
- 0x7aa8, 0x9284, 0x1000, 0xc0d5, 0x080c, 0x577c, 0x0804, 0x35b0,
- 0x00c6, 0xaab0, 0x9284, 0xc000, 0x0148, 0xd2ec, 0x0170, 0x080c,
- 0x57e1, 0x1158, 0x2009, 0x0014, 0x0804, 0x5546, 0x2061, 0x1800,
- 0x080c, 0x57e1, 0x2009, 0x0007, 0x15c8, 0xd2f4, 0x0130, 0x9284,
- 0x5000, 0xc0d5, 0x080c, 0x57a7, 0x0058, 0xd2fc, 0x0180, 0x080c,
- 0x4bb4, 0x0590, 0xa998, 0x9284, 0x9000, 0xc0d5, 0x080c, 0x577c,
- 0xa87b, 0x0000, 0xa883, 0x0000, 0xa897, 0x4000, 0x0438, 0x080c,
- 0x4bb4, 0x0510, 0x080c, 0x6a8c, 0x2009, 0x0009, 0x11b8, 0xa8c4,
- 0x9086, 0x0500, 0x11c8, 0xa8c8, 0x9005, 0x11b0, 0xa8cc, 0x9084,
- 0xff00, 0x1190, 0x080c, 0x4bb4, 0x1108, 0x0070, 0x2009, 0x004b,
- 0x080c, 0xd328, 0x2009, 0x0003, 0x0108, 0x0078, 0x0431, 0x19c0,
+ 0x003c, 0x0518, 0x0c20, 0x83ff, 0x11f0, 0x7154, 0x810c, 0xa99a,
+ 0xa897, 0x4000, 0x715c, 0x81ff, 0x090c, 0x0dc5, 0x2148, 0x080c,
+ 0x1040, 0x9006, 0x705e, 0x918d, 0x0001, 0x2008, 0xa0a0, 0x2048,
+ 0x0126, 0x2091, 0x8000, 0x080c, 0x6dd1, 0x012e, 0xa09f, 0x0000,
+ 0xa0a3, 0x0000, 0x0070, 0x7063, 0x0001, 0x7152, 0x7054, 0x9300,
+ 0x7056, 0xa37a, 0xa48e, 0xa592, 0xa696, 0xa79a, 0x080c, 0x10f8,
+ 0x9006, 0x00ee, 0x0005, 0x0096, 0xa88c, 0x90be, 0x7000, 0x0148,
+ 0x90be, 0x7100, 0x0130, 0x90be, 0x7200, 0x0118, 0x009e, 0x0804,
+ 0x35e0, 0xa884, 0xa988, 0x080c, 0x2894, 0x1518, 0x080c, 0x66b2,
+ 0x1500, 0x7126, 0xbe12, 0xbd16, 0xae7c, 0x080c, 0x4b89, 0x01c8,
+ 0x080c, 0x4b89, 0x01b0, 0x009e, 0xa867, 0x0000, 0xa868, 0xc0fd,
+ 0xa86a, 0xa823, 0x0000, 0xa804, 0x2048, 0x080c, 0xd002, 0x1120,
+ 0x2009, 0x0003, 0x0804, 0x35dd, 0x7007, 0x0003, 0x701f, 0x52b6,
+ 0x0005, 0x009e, 0x2009, 0x0002, 0x0804, 0x35dd, 0x7124, 0x080c,
+ 0x3342, 0xa820, 0x9086, 0x8001, 0x1120, 0x2009, 0x0004, 0x0804,
+ 0x35dd, 0x2900, 0x7022, 0xa804, 0x0096, 0x2048, 0x8906, 0x8006,
+ 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x009e, 0x9080, 0x0002,
+ 0x0076, 0x0006, 0x2098, 0x20a0, 0x27e0, 0x27e8, 0x20a9, 0x002a,
+ 0x080c, 0x0f8b, 0xaa6c, 0xab70, 0xac74, 0xad78, 0x2061, 0x18b8,
+ 0x2c44, 0xa06b, 0x0000, 0xae64, 0xaf8c, 0x97c6, 0x7000, 0x0118,
+ 0x97c6, 0x7100, 0x1148, 0x96c2, 0x0004, 0x0600, 0x2009, 0x0004,
+ 0x000e, 0x007e, 0x0804, 0x4bd5, 0x97c6, 0x7200, 0x11b8, 0x96c2,
+ 0x0054, 0x02a0, 0x000e, 0x007e, 0x2061, 0x18b8, 0x2c44, 0xa076,
+ 0xa772, 0xa07b, 0x002a, 0xa28e, 0xa392, 0xa496, 0xa59a, 0x080c,
+ 0x10f8, 0x7007, 0x0002, 0x701f, 0x5312, 0x0005, 0x000e, 0x007e,
+ 0x0804, 0x35e0, 0x7020, 0x2048, 0xa804, 0x2048, 0xa804, 0x2048,
+ 0x8906, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080,
+ 0x0002, 0x2098, 0x20a0, 0x27e0, 0x27e8, 0x20a9, 0x002a, 0x080c,
+ 0x0f8b, 0x2100, 0x2238, 0x2061, 0x18b8, 0x2c44, 0xa28c, 0xa390,
+ 0xa494, 0xa598, 0x2009, 0x002a, 0x0804, 0x4bd5, 0x81ff, 0x1904,
+ 0x35dd, 0x798c, 0x2001, 0x197f, 0x918c, 0x8000, 0x2102, 0x080c,
+ 0x4ba0, 0x0904, 0x35e0, 0x080c, 0x6a92, 0x0120, 0x080c, 0x6a9a,
+ 0x1904, 0x35e0, 0x080c, 0x67e4, 0x0904, 0x35dd, 0x0126, 0x2091,
+ 0x8000, 0x080c, 0x68aa, 0x012e, 0x0904, 0x35dd, 0x2001, 0x197f,
+ 0x2004, 0xd0fc, 0x1904, 0x35ab, 0x0804, 0x45e1, 0xa9a0, 0x2001,
+ 0x197f, 0x918c, 0x8000, 0xc18d, 0x2102, 0x080c, 0x4bad, 0x01a0,
+ 0x080c, 0x6a92, 0x0118, 0x080c, 0x6a9a, 0x1170, 0x080c, 0x67e4,
+ 0x2009, 0x0002, 0x0128, 0x080c, 0x68aa, 0x1170, 0x2009, 0x0003,
0xa897, 0x4005, 0xa99a, 0x0010, 0xa897, 0x4006, 0x900e, 0x9085,
- 0x0001, 0x2001, 0x0030, 0x00ce, 0x0005, 0x9006, 0x0ce0, 0x7aa8,
- 0xd2dc, 0x0904, 0x35e2, 0x0016, 0x7984, 0x9284, 0x1000, 0xc0fd,
- 0x080c, 0x577c, 0x001e, 0x1904, 0x35e2, 0x0804, 0x35b0, 0x00f6,
- 0x2d78, 0xaab0, 0x0021, 0x00fe, 0x0005, 0xaab0, 0xc2d5, 0xd2dc,
- 0x0150, 0x0016, 0xa998, 0x9284, 0x1400, 0xc0fd, 0x080c, 0x577c,
- 0x001e, 0x9085, 0x0001, 0x0005, 0x81ff, 0x0120, 0x2009, 0x0001,
- 0x0804, 0x35e2, 0x080c, 0x57e1, 0x0120, 0x2009, 0x0007, 0x0804,
- 0x35e2, 0x7984, 0x7ea8, 0x96b4, 0x00ff, 0x080c, 0x6717, 0x1904,
- 0x35e5, 0x9186, 0x007f, 0x0138, 0x080c, 0x6a8c, 0x0120, 0x2009,
- 0x0009, 0x0804, 0x35e2, 0x080c, 0x4b83, 0x1120, 0x2009, 0x0002,
- 0x0804, 0x35e2, 0xa867, 0x0000, 0xa868, 0xc0fd, 0xa86a, 0x2001,
- 0x0100, 0x8007, 0xa80a, 0x080c, 0xd024, 0x1120, 0x2009, 0x0003,
- 0x0804, 0x35e2, 0x7007, 0x0003, 0x701f, 0x55b7, 0x0005, 0xa808,
- 0x8007, 0x9086, 0x0100, 0x1120, 0x2009, 0x0004, 0x0804, 0x35e2,
- 0xa8e0, 0xa866, 0xa810, 0x8007, 0x9084, 0x00ff, 0x800c, 0xa814,
- 0x8007, 0x9084, 0x00ff, 0x8004, 0x9080, 0x0002, 0x9108, 0x8906,
- 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, 0x0004,
- 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0x0804, 0x4bcf, 0x080c, 0x4b83,
- 0x1120, 0x2009, 0x0002, 0x0804, 0x35e2, 0x7984, 0x9194, 0xff00,
- 0x918c, 0x00ff, 0x8217, 0x82ff, 0x1118, 0x7023, 0x19b5, 0x0040,
- 0x92c6, 0x0001, 0x1118, 0x7023, 0x19cf, 0x0010, 0x0804, 0x35e5,
- 0x2009, 0x001a, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0xa85c, 0x9080,
- 0x0019, 0xaf60, 0x080c, 0x4bcc, 0x701f, 0x5607, 0x0005, 0x2001,
- 0x182e, 0x2003, 0x0001, 0xa85c, 0x9080, 0x0019, 0x2098, 0xa860,
- 0x20e0, 0x20a9, 0x001a, 0x7020, 0x20a0, 0x20e9, 0x0001, 0x4003,
- 0x0804, 0x35b0, 0x080c, 0x4b83, 0x1120, 0x2009, 0x0002, 0x0804,
- 0x35e2, 0x7984, 0x9194, 0xff00, 0x918c, 0x00ff, 0x8217, 0x82ff,
- 0x1118, 0x2099, 0x19b5, 0x0040, 0x92c6, 0x0001, 0x1118, 0x2099,
- 0x19cf, 0x0010, 0x0804, 0x35e5, 0xa85c, 0x9080, 0x0019, 0x20a0,
- 0xa860, 0x20e8, 0x20a9, 0x001a, 0x20e1, 0x0001, 0x4003, 0x2009,
- 0x001a, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0xa85c, 0x9080, 0x0019,
- 0xaf60, 0x0804, 0x4bcf, 0x7884, 0x908a, 0x1000, 0x1a04, 0x35e5,
- 0x0126, 0x2091, 0x8000, 0x8003, 0x800b, 0x810b, 0x9108, 0x00c6,
- 0x2061, 0x19fc, 0x614a, 0x00ce, 0x012e, 0x0804, 0x35b0, 0x00c6,
- 0x080c, 0x7563, 0x1160, 0x080c, 0x7848, 0x080c, 0x6121, 0x9085,
- 0x0001, 0x080c, 0x75a7, 0x080c, 0x748f, 0x080c, 0x0dc5, 0x2061,
- 0x1800, 0x6030, 0xc09d, 0x6032, 0x080c, 0x5fe0, 0x00ce, 0x0005,
- 0x00c6, 0x2001, 0x1800, 0x2004, 0x908e, 0x0000, 0x0904, 0x35e2,
- 0x7884, 0x9005, 0x0188, 0x7888, 0x2061, 0x199d, 0x2c0c, 0x2062,
- 0x080c, 0x2c6b, 0x01a0, 0x080c, 0x2c73, 0x0188, 0x080c, 0x2c7b,
- 0x0170, 0x2162, 0x0804, 0x35e5, 0x2061, 0x0100, 0x6038, 0x9086,
- 0x0007, 0x1118, 0x2009, 0x0001, 0x0010, 0x2009, 0x0000, 0x7884,
- 0x9086, 0x0002, 0x1568, 0x2061, 0x0100, 0x6028, 0xc09c, 0x602a,
- 0x0026, 0x2011, 0x0003, 0x080c, 0xa8d3, 0x2011, 0x0002, 0x080c,
- 0xa8dd, 0x002e, 0x080c, 0xa7e7, 0x0036, 0x901e, 0x080c, 0xa85d,
- 0x003e, 0x60e3, 0x0000, 0x080c, 0xed95, 0x080c, 0xedb0, 0x9085,
- 0x0001, 0x080c, 0x75a7, 0x9006, 0x080c, 0x2d5b, 0x2001, 0x1800,
- 0x2003, 0x0004, 0x2001, 0x19a8, 0x2003, 0x0000, 0x6027, 0x0008,
- 0x00ce, 0x0804, 0x35b0, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804,
- 0x35e2, 0x080c, 0x57e1, 0x0120, 0x2009, 0x0007, 0x0804, 0x35e2,
- 0x7984, 0x7ea8, 0x96b4, 0x00ff, 0x080c, 0x6717, 0x1904, 0x35e5,
- 0x9186, 0x007f, 0x0138, 0x080c, 0x6a8c, 0x0120, 0x2009, 0x0009,
- 0x0804, 0x35e2, 0x080c, 0x4b83, 0x1120, 0x2009, 0x0002, 0x0804,
- 0x35e2, 0xa867, 0x0000, 0xa868, 0xc0fd, 0xa86a, 0x080c, 0xd027,
- 0x1120, 0x2009, 0x0003, 0x0804, 0x35e2, 0x7007, 0x0003, 0x701f,
- 0x570a, 0x0005, 0xa830, 0x9086, 0x0100, 0x1120, 0x2009, 0x0004,
- 0x0804, 0x35e2, 0xa8e0, 0xa866, 0xa834, 0x8007, 0x800c, 0xa85c,
- 0x9080, 0x000c, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0xaf60, 0x0804,
- 0x4bcf, 0xa898, 0x9086, 0x000d, 0x1904, 0x35e2, 0x2021, 0x4005,
- 0x0126, 0x2091, 0x8000, 0x0e04, 0x572e, 0x0010, 0x012e, 0x0cc0,
- 0x7c36, 0x9486, 0x4000, 0x0118, 0x7833, 0x0011, 0x0010, 0x7833,
- 0x0010, 0x7883, 0x4005, 0xa998, 0x7986, 0xa9a4, 0x799a, 0xa9a8,
- 0x799e, 0x080c, 0x4bbf, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004,
- 0xd084, 0x190c, 0x11aa, 0x7007, 0x0001, 0x2091, 0x5000, 0x700f,
- 0x0000, 0x012e, 0x0005, 0x0126, 0x2091, 0x8000, 0x00c6, 0x2061,
- 0x19fc, 0x7984, 0x615a, 0x6156, 0x605f, 0x0000, 0x6053, 0x0009,
- 0x7898, 0x6072, 0x789c, 0x606e, 0x7888, 0x606a, 0x788c, 0x6066,
- 0x2001, 0x1a0c, 0x2044, 0x2001, 0x1a13, 0xa076, 0xa060, 0xa072,
- 0xa07b, 0x0001, 0xa07f, 0x0002, 0xa06b, 0x0000, 0xa09f, 0x0000,
- 0x00ce, 0x012e, 0x0804, 0x35b0, 0x0126, 0x2091, 0x8000, 0x00b6,
- 0x00c6, 0x90e4, 0xc000, 0x0168, 0x0006, 0xd0d4, 0x0130, 0x0036,
- 0x2019, 0x0029, 0x080c, 0x3365, 0x003e, 0x080c, 0xce8c, 0x000e,
- 0x1198, 0xd0e4, 0x0160, 0x9180, 0x1000, 0x2004, 0x905d, 0x0160,
- 0x080c, 0x613b, 0x080c, 0xb051, 0x0110, 0xb817, 0x0000, 0x9006,
- 0x00ce, 0x00be, 0x012e, 0x0005, 0x9085, 0x0001, 0x0cc8, 0x0126,
- 0x2091, 0x8000, 0x0156, 0x2010, 0x900e, 0x20a9, 0x0800, 0x0016,
- 0x9180, 0x1000, 0x2004, 0x9005, 0x0188, 0x9186, 0x007e, 0x0170,
- 0x9186, 0x007f, 0x0158, 0x9186, 0x0080, 0x0140, 0x9186, 0x00ff,
- 0x0128, 0x0026, 0x2200, 0x080c, 0x577c, 0x002e, 0x001e, 0x8108,
- 0x1f04, 0x57af, 0x015e, 0x012e, 0x0005, 0x2001, 0x1848, 0x2004,
- 0x0005, 0x2001, 0x1867, 0x2004, 0x0005, 0x0006, 0x2001, 0x1810,
- 0x2004, 0xd0d4, 0x000e, 0x0005, 0x2001, 0x180e, 0x2004, 0xd0b4,
- 0x0005, 0x2001, 0x1800, 0x2004, 0x9086, 0x0003, 0x0005, 0x0016,
- 0x00e6, 0x2071, 0x189e, 0x7108, 0x910d, 0x710a, 0x00ee, 0x001e,
- 0x0005, 0x79a4, 0x81ff, 0x0904, 0x35e5, 0x9182, 0x0081, 0x1a04,
- 0x35e5, 0x810c, 0x0016, 0x080c, 0x4b83, 0x0170, 0x080c, 0x0f16,
- 0x2100, 0x2238, 0x7d84, 0x7c88, 0x7b8c, 0x7a90, 0x001e, 0x080c,
- 0x4bcc, 0x701f, 0x5811, 0x0005, 0x001e, 0x2009, 0x0002, 0x0804,
- 0x35e2, 0x2079, 0x0000, 0x7d94, 0x7c98, 0x7ba8, 0x7aac, 0x79a4,
- 0x810c, 0x2061, 0x18b8, 0x2c44, 0xa770, 0xa074, 0x2071, 0x189e,
- 0x080c, 0x4bcf, 0x701f, 0x5825, 0x0005, 0x2061, 0x18b8, 0x2c44,
- 0x0016, 0x0026, 0xa270, 0xa174, 0x080c, 0x0f1e, 0x002e, 0x001e,
- 0x080c, 0x0fcb, 0x9006, 0xa802, 0xa806, 0x0804, 0x35b0, 0x0126,
- 0x0156, 0x0136, 0x0146, 0x01c6, 0x01d6, 0x00c6, 0x00d6, 0x00e6,
- 0x00f6, 0x2061, 0x0100, 0x2069, 0x0200, 0x2071, 0x1800, 0x6044,
- 0xd0a4, 0x11e8, 0xd084, 0x0118, 0x080c, 0x59e0, 0x0068, 0xd08c,
- 0x0118, 0x080c, 0x58e9, 0x0040, 0xd094, 0x0118, 0x080c, 0x58b9,
- 0x0018, 0xd09c, 0x0108, 0x0099, 0x00fe, 0x00ee, 0x00de, 0x00ce,
- 0x01de, 0x01ce, 0x014e, 0x013e, 0x015e, 0x012e, 0x0005, 0x0016,
- 0x6128, 0xd19c, 0x1110, 0xc19d, 0x612a, 0x001e, 0x0c68, 0x0006,
- 0x7098, 0x9005, 0x000e, 0x0120, 0x709b, 0x0000, 0x7093, 0x0000,
- 0x624c, 0x9286, 0xf0f0, 0x1150, 0x6048, 0x9086, 0xf0f0, 0x0130,
- 0x624a, 0x6043, 0x0090, 0x6043, 0x0010, 0x0490, 0x9294, 0xff00,
- 0x9296, 0xf700, 0x0178, 0x7138, 0xd1a4, 0x1160, 0x6240, 0x9295,
- 0x0100, 0x6242, 0x9294, 0x0010, 0x0128, 0x2009, 0x00f7, 0x080c,
- 0x609d, 0x00f0, 0x6040, 0x9084, 0x0010, 0x9085, 0x0140, 0x6042,
- 0x6043, 0x0000, 0x7087, 0x0000, 0x70a3, 0x0001, 0x70c7, 0x0000,
- 0x70df, 0x0000, 0x2009, 0x1c80, 0x200b, 0x0000, 0x7097, 0x0000,
- 0x708b, 0x000f, 0x2009, 0x000f, 0x2011, 0x5f83, 0x080c, 0x879b,
- 0x0005, 0x2001, 0x1869, 0x2004, 0xd08c, 0x0110, 0x705f, 0xffff,
- 0x7088, 0x9005, 0x1528, 0x2011, 0x5f83, 0x080c, 0x8703, 0x6040,
- 0x9094, 0x0010, 0x9285, 0x0020, 0x6042, 0x20a9, 0x00c8, 0x6044,
- 0xd08c, 0x1168, 0x1f04, 0x58cf, 0x6242, 0x709b, 0x0000, 0x6040,
- 0x9094, 0x0010, 0x9285, 0x0080, 0x6042, 0x6242, 0x0048, 0x6242,
- 0x709b, 0x0000, 0x708f, 0x0000, 0x9006, 0x080c, 0x6126, 0x0000,
- 0x0005, 0x708c, 0x908a, 0x0003, 0x1a0c, 0x0dc5, 0x000b, 0x0005,
- 0x58f3, 0x5944, 0x59df, 0x00f6, 0x0016, 0x6900, 0x918c, 0x0800,
- 0x708f, 0x0001, 0x2001, 0x015d, 0x2003, 0x0000, 0x6803, 0x00fc,
- 0x20a9, 0x0004, 0x6800, 0x9084, 0x00fc, 0x0120, 0x1f04, 0x5902,
- 0x080c, 0x0dc5, 0x68a0, 0x68a2, 0x689c, 0x689e, 0x6898, 0x689a,
- 0xa001, 0x918d, 0x1600, 0x6902, 0x001e, 0x6837, 0x0020, 0x080c,
- 0x6102, 0x2079, 0x1c00, 0x7833, 0x1101, 0x7837, 0x0000, 0x20e1,
- 0x0001, 0x2099, 0x1805, 0x20e9, 0x0001, 0x20a1, 0x1c0e, 0x20a9,
- 0x0004, 0x4003, 0x080c, 0xada2, 0x20e1, 0x0001, 0x2099, 0x1c00,
- 0x20e9, 0x0000, 0x20a1, 0x0240, 0x20a9, 0x0014, 0x4003, 0x60c3,
- 0x000c, 0x600f, 0x0000, 0x080c, 0x5fb4, 0x00fe, 0x9006, 0x7092,
- 0x6043, 0x0008, 0x6042, 0x0005, 0x00f6, 0x7090, 0x7093, 0x0000,
- 0x9025, 0x0904, 0x59bc, 0x6020, 0xd0b4, 0x1904, 0x59ba, 0x71a0,
- 0x81ff, 0x0904, 0x59a8, 0x9486, 0x000c, 0x1904, 0x59b5, 0x9480,
- 0x0018, 0x8004, 0x20a8, 0x080c, 0x60fb, 0x2011, 0x0260, 0x2019,
- 0x1c00, 0x220c, 0x2304, 0x9106, 0x11e8, 0x8210, 0x8318, 0x1f04,
- 0x5961, 0x6043, 0x0004, 0x2061, 0x0140, 0x605b, 0xbc94, 0x605f,
- 0xf0f0, 0x2061, 0x0100, 0x6043, 0x0006, 0x708f, 0x0002, 0x709b,
- 0x0002, 0x2009, 0x07d0, 0x2011, 0x5f8a, 0x080c, 0x879b, 0x080c,
- 0x6102, 0x04c0, 0x080c, 0x60fb, 0x2079, 0x0260, 0x7930, 0x918e,
- 0x1101, 0x1558, 0x7834, 0x9005, 0x1540, 0x7900, 0x918c, 0x00ff,
- 0x1118, 0x7804, 0x9005, 0x0190, 0x080c, 0x60fb, 0x2011, 0x026e,
- 0x2019, 0x1805, 0x20a9, 0x0004, 0x220c, 0x2304, 0x9102, 0x0230,
- 0x11a0, 0x8210, 0x8318, 0x1f04, 0x599c, 0x0078, 0x70a3, 0x0000,
- 0x080c, 0x60fb, 0x20e1, 0x0000, 0x2099, 0x0260, 0x20e9, 0x0001,
- 0x20a1, 0x1c00, 0x20a9, 0x0014, 0x4003, 0x6043, 0x0008, 0x6043,
- 0x0000, 0x0010, 0x00fe, 0x0005, 0x6040, 0x9085, 0x0100, 0x6042,
- 0x6020, 0xd0b4, 0x1db8, 0x080c, 0xada2, 0x20e1, 0x0001, 0x2099,
- 0x1c00, 0x20e9, 0x0000, 0x20a1, 0x0240, 0x20a9, 0x0014, 0x4003,
- 0x60c3, 0x000c, 0x2011, 0x19f3, 0x2013, 0x0000, 0x7093, 0x0000,
- 0x60a3, 0x0056, 0x60a7, 0x9575, 0x080c, 0xa4f4, 0x08d8, 0x0005,
- 0x7098, 0x908a, 0x001d, 0x1a0c, 0x0dc5, 0x000b, 0x0005, 0x5a11,
- 0x5a24, 0x5a4d, 0x5a6d, 0x5a93, 0x5ac2, 0x5ae8, 0x5b20, 0x5b46,
- 0x5b74, 0x5baf, 0x5be7, 0x5c05, 0x5c30, 0x5c52, 0x5c6d, 0x5c77,
- 0x5cab, 0x5cd1, 0x5d00, 0x5d26, 0x5d5e, 0x5da2, 0x5ddf, 0x5e00,
- 0x5e59, 0x5e7b, 0x5ea9, 0x5ea9, 0x00c6, 0x2061, 0x1800, 0x6003,
- 0x0007, 0x2061, 0x0100, 0x6004, 0x9084, 0xfff9, 0x6006, 0x00ce,
- 0x0005, 0x2061, 0x0140, 0x605b, 0xbc94, 0x605f, 0xf0f0, 0x2061,
- 0x0100, 0x6043, 0x0002, 0x709b, 0x0001, 0x2009, 0x07d0, 0x2011,
- 0x5f8a, 0x080c, 0x879b, 0x0005, 0x00f6, 0x7090, 0x9086, 0x0014,
- 0x1510, 0x6042, 0x6020, 0xd0b4, 0x11f0, 0x080c, 0x60fb, 0x2079,
- 0x0260, 0x7a30, 0x9296, 0x1102, 0x11a0, 0x7834, 0x9005, 0x1188,
- 0x7a38, 0xd2fc, 0x0128, 0x70c4, 0x9005, 0x1110, 0x70c7, 0x0001,
- 0x2011, 0x5f8a, 0x080c, 0x8703, 0x709b, 0x0010, 0x080c, 0x5c77,
- 0x0010, 0x7093, 0x0000, 0x00fe, 0x0005, 0x00f6, 0x709b, 0x0003,
- 0x6043, 0x0004, 0x2011, 0x5f8a, 0x080c, 0x8703, 0x080c, 0x607f,
- 0x2079, 0x0240, 0x7833, 0x1102, 0x7837, 0x0000, 0x20a9, 0x0008,
- 0x9f88, 0x000e, 0x200b, 0x0000, 0x8108, 0x1f04, 0x5a62, 0x60c3,
- 0x0014, 0x080c, 0x5fb4, 0x00fe, 0x0005, 0x00f6, 0x7090, 0x9005,
- 0x0500, 0x2011, 0x5f8a, 0x080c, 0x8703, 0x9086, 0x0014, 0x11b8,
- 0x080c, 0x60fb, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1102, 0x1178,
- 0x7834, 0x9005, 0x1160, 0x7a38, 0xd2fc, 0x0128, 0x70c4, 0x9005,
- 0x1110, 0x70c7, 0x0001, 0x709b, 0x0004, 0x0029, 0x0010, 0x080c,
- 0x60d7, 0x00fe, 0x0005, 0x00f6, 0x709b, 0x0005, 0x080c, 0x607f,
- 0x2079, 0x0240, 0x7833, 0x1103, 0x7837, 0x0000, 0x080c, 0x60fb,
- 0x080c, 0x60de, 0x1170, 0x7084, 0x9005, 0x1158, 0x715c, 0x9186,
- 0xffff, 0x0138, 0x2011, 0x0008, 0x080c, 0x5f37, 0x0168, 0x080c,
- 0x60b4, 0x20a9, 0x0008, 0x20e1, 0x0000, 0x2099, 0x026e, 0x20e9,
- 0x0000, 0x20a1, 0x024e, 0x4003, 0x60c3, 0x0014, 0x080c, 0x5fb4,
- 0x00fe, 0x0005, 0x00f6, 0x7090, 0x9005, 0x0500, 0x2011, 0x5f8a,
- 0x080c, 0x8703, 0x9086, 0x0014, 0x11b8, 0x080c, 0x60fb, 0x2079,
- 0x0260, 0x7a30, 0x9296, 0x1103, 0x1178, 0x7834, 0x9005, 0x1160,
- 0x7a38, 0xd2fc, 0x0128, 0x70c4, 0x9005, 0x1110, 0x70c7, 0x0001,
- 0x709b, 0x0006, 0x0029, 0x0010, 0x080c, 0x60d7, 0x00fe, 0x0005,
- 0x00f6, 0x709b, 0x0007, 0x080c, 0x607f, 0x2079, 0x0240, 0x7833,
- 0x1104, 0x7837, 0x0000, 0x080c, 0x60fb, 0x080c, 0x60de, 0x11b8,
- 0x7084, 0x9005, 0x11a0, 0x7164, 0x9186, 0xffff, 0x0180, 0x9180,
- 0x33b1, 0x200d, 0x918c, 0xff00, 0x810f, 0x2011, 0x0008, 0x080c,
- 0x5f37, 0x0180, 0x080c, 0x50c9, 0x0110, 0x080c, 0x28f2, 0x20a9,
- 0x0008, 0x20e1, 0x0000, 0x2099, 0x026e, 0x20e9, 0x0000, 0x20a1,
- 0x024e, 0x4003, 0x60c3, 0x0014, 0x080c, 0x5fb4, 0x00fe, 0x0005,
- 0x00f6, 0x7090, 0x9005, 0x0500, 0x2011, 0x5f8a, 0x080c, 0x8703,
- 0x9086, 0x0014, 0x11b8, 0x080c, 0x60fb, 0x2079, 0x0260, 0x7a30,
- 0x9296, 0x1104, 0x1178, 0x7834, 0x9005, 0x1160, 0x7a38, 0xd2fc,
- 0x0128, 0x70c4, 0x9005, 0x1110, 0x70c7, 0x0001, 0x709b, 0x0008,
- 0x0029, 0x0010, 0x080c, 0x60d7, 0x00fe, 0x0005, 0x00f6, 0x709b,
- 0x0009, 0x080c, 0x607f, 0x2079, 0x0240, 0x7833, 0x1105, 0x7837,
- 0x0100, 0x080c, 0x60de, 0x1150, 0x7084, 0x9005, 0x1138, 0x080c,
- 0x5eaa, 0x1188, 0x9085, 0x0001, 0x080c, 0x28f2, 0x20a9, 0x0008,
- 0x080c, 0x60fb, 0x20e1, 0x0000, 0x2099, 0x026e, 0x20e9, 0x0000,
- 0x20a1, 0x024e, 0x4003, 0x60c3, 0x0014, 0x080c, 0x5fb4, 0x0010,
- 0x080c, 0x5a04, 0x00fe, 0x0005, 0x00f6, 0x7090, 0x9005, 0x05a8,
- 0x2011, 0x5f8a, 0x080c, 0x8703, 0x9086, 0x0014, 0x1560, 0x080c,
- 0x60fb, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1105, 0x1520, 0x7834,
- 0x9084, 0x0100, 0x2011, 0x0100, 0x921e, 0x1160, 0x7a38, 0xd2fc,
- 0x0128, 0x70c4, 0x9005, 0x1110, 0x70c7, 0x0001, 0x709b, 0x000a,
- 0x00b1, 0x0098, 0x9005, 0x1178, 0x7a38, 0xd2fc, 0x0128, 0x70c4,
- 0x9005, 0x1110, 0x70c7, 0x0001, 0x7097, 0x0000, 0x709b, 0x000e,
- 0x080c, 0x5c52, 0x0010, 0x080c, 0x60d7, 0x00fe, 0x0005, 0x00f6,
- 0x709b, 0x000b, 0x2011, 0x1c0e, 0x20e9, 0x0001, 0x22a0, 0x20a9,
- 0x0040, 0x2019, 0xffff, 0x4304, 0x080c, 0x607f, 0x2079, 0x0240,
- 0x7833, 0x1106, 0x7837, 0x0000, 0x080c, 0x60de, 0x0118, 0x2013,
- 0x0000, 0x0020, 0x7060, 0x9085, 0x0100, 0x2012, 0x20a9, 0x0040,
- 0x2009, 0x024e, 0x2011, 0x1c0e, 0x220e, 0x8210, 0x8108, 0x9186,
- 0x0260, 0x1128, 0x6810, 0x8000, 0x6812, 0x2009, 0x0240, 0x1f04,
- 0x5bd4, 0x60c3, 0x0084, 0x080c, 0x5fb4, 0x00fe, 0x0005, 0x00f6,
- 0x7090, 0x9005, 0x01c0, 0x2011, 0x5f8a, 0x080c, 0x8703, 0x9086,
- 0x0084, 0x1178, 0x080c, 0x60fb, 0x2079, 0x0260, 0x7a30, 0x9296,
- 0x1106, 0x1138, 0x7834, 0x9005, 0x1120, 0x709b, 0x000c, 0x0029,
- 0x0010, 0x080c, 0x60d7, 0x00fe, 0x0005, 0x00f6, 0x709b, 0x000d,
- 0x080c, 0x607f, 0x2079, 0x0240, 0x7833, 0x1107, 0x7837, 0x0000,
- 0x080c, 0x60fb, 0x20a9, 0x0040, 0x2011, 0x026e, 0x2009, 0x024e,
- 0x220e, 0x8210, 0x8108, 0x9186, 0x0260, 0x1150, 0x6810, 0x8000,
- 0x6812, 0x2009, 0x0240, 0x6814, 0x8000, 0x6816, 0x2011, 0x0260,
- 0x1f04, 0x5c18, 0x60c3, 0x0084, 0x080c, 0x5fb4, 0x00fe, 0x0005,
- 0x00f6, 0x7090, 0x9005, 0x01e0, 0x2011, 0x5f8a, 0x080c, 0x8703,
- 0x9086, 0x0084, 0x1198, 0x080c, 0x60fb, 0x2079, 0x0260, 0x7a30,
- 0x9296, 0x1107, 0x1158, 0x7834, 0x9005, 0x1140, 0x7097, 0x0001,
- 0x080c, 0x6051, 0x709b, 0x000e, 0x0029, 0x0010, 0x080c, 0x60d7,
- 0x00fe, 0x0005, 0x918d, 0x0001, 0x080c, 0x6126, 0x709b, 0x000f,
- 0x7093, 0x0000, 0x2061, 0x0140, 0x605b, 0xbc85, 0x605f, 0xb5b5,
- 0x2061, 0x0100, 0x6043, 0x0005, 0x6043, 0x0004, 0x2009, 0x07d0,
- 0x2011, 0x5f8a, 0x080c, 0x86f7, 0x0005, 0x7090, 0x9005, 0x0130,
- 0x2011, 0x5f8a, 0x080c, 0x8703, 0x709b, 0x0000, 0x0005, 0x709b,
- 0x0011, 0x080c, 0xada2, 0x080c, 0x60fb, 0x20e1, 0x0000, 0x2099,
- 0x0260, 0x20e9, 0x0000, 0x20a1, 0x0240, 0x7490, 0x9480, 0x0018,
- 0x9080, 0x0007, 0x9084, 0x03f8, 0x8004, 0x20a8, 0x4003, 0x080c,
- 0x60de, 0x11a0, 0x717c, 0x81ff, 0x0188, 0x900e, 0x7080, 0x9084,
- 0x00ff, 0x0160, 0x080c, 0x2889, 0x9186, 0x007e, 0x0138, 0x9186,
- 0x0080, 0x0120, 0x2011, 0x0008, 0x080c, 0x5f37, 0x60c3, 0x0014,
- 0x080c, 0x5fb4, 0x0005, 0x00f6, 0x7090, 0x9005, 0x0500, 0x2011,
- 0x5f8a, 0x080c, 0x8703, 0x9086, 0x0014, 0x11b8, 0x080c, 0x60fb,
- 0x2079, 0x0260, 0x7a30, 0x9296, 0x1103, 0x1178, 0x7834, 0x9005,
+ 0x0001, 0x2001, 0x0030, 0x0005, 0xa897, 0x4000, 0x2001, 0x197f,
+ 0x2004, 0xd0fc, 0x1128, 0x080c, 0x57db, 0x0110, 0x9006, 0x0018,
+ 0x900e, 0x9085, 0x0001, 0x2001, 0x0000, 0x0005, 0x78a8, 0xd08c,
+ 0x1118, 0xd084, 0x0904, 0x4556, 0x080c, 0x4bbc, 0x0904, 0x35e0,
+ 0x080c, 0x4b89, 0x1120, 0x2009, 0x0002, 0x0804, 0x35dd, 0x080c,
+ 0x6a92, 0x0130, 0x908e, 0x0004, 0x0118, 0x908e, 0x0005, 0x15a0,
+ 0x78a8, 0xd08c, 0x0120, 0xb800, 0xc08c, 0xb802, 0x0028, 0x080c,
+ 0x57d3, 0xd0b4, 0x0904, 0x4590, 0x7884, 0x908e, 0x007e, 0x0904,
+ 0x4590, 0x908e, 0x007f, 0x0904, 0x4590, 0x908e, 0x0080, 0x0904,
+ 0x4590, 0xb800, 0xd08c, 0x1904, 0x4590, 0xa867, 0x0000, 0xa868,
+ 0xc0fd, 0xa86a, 0x080c, 0xd021, 0x1120, 0x2009, 0x0003, 0x0804,
+ 0x35dd, 0x7007, 0x0003, 0x701f, 0x53de, 0x0005, 0x080c, 0x4bbc,
+ 0x0904, 0x35e0, 0x0804, 0x4590, 0x080c, 0x339b, 0x0108, 0x0005,
+ 0x2009, 0x1834, 0x210c, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804,
+ 0x35dd, 0x080c, 0x57e7, 0x0120, 0x2009, 0x0007, 0x0804, 0x35dd,
+ 0x080c, 0x6a8a, 0x0120, 0x2009, 0x0008, 0x0804, 0x35dd, 0xb89c,
+ 0xd0a4, 0x1118, 0xd0ac, 0x1904, 0x4590, 0x9006, 0xa866, 0xa832,
+ 0xa868, 0xc0fd, 0xa86a, 0x080c, 0xd080, 0x1120, 0x2009, 0x0003,
+ 0x0804, 0x35dd, 0x7007, 0x0003, 0x701f, 0x5417, 0x0005, 0xa830,
+ 0x9086, 0x0100, 0x1120, 0x2009, 0x0004, 0x0804, 0x5727, 0x080c,
+ 0x4bbc, 0x0904, 0x35e0, 0x0804, 0x53b0, 0x81ff, 0x2009, 0x0001,
+ 0x1904, 0x35dd, 0x080c, 0x57e7, 0x2009, 0x0007, 0x1904, 0x35dd,
+ 0x080c, 0x6a8a, 0x0120, 0x2009, 0x0008, 0x0804, 0x35dd, 0x080c,
+ 0x4bbc, 0x0904, 0x35e0, 0x080c, 0x6a92, 0x2009, 0x0009, 0x1904,
+ 0x35dd, 0x080c, 0x4b89, 0x2009, 0x0002, 0x0904, 0x35dd, 0x9006,
+ 0xa866, 0xa832, 0xa868, 0xc0fd, 0xa86a, 0x7988, 0xa95a, 0x9194,
+ 0xfd00, 0x918c, 0x00ff, 0x9006, 0x82ff, 0x1128, 0xc0ed, 0xa952,
+ 0x798c, 0xa956, 0x0038, 0x928e, 0x0100, 0x1904, 0x35e0, 0xc0e5,
+ 0xa952, 0xa956, 0xa83e, 0x080c, 0xd2d3, 0x2009, 0x0003, 0x0904,
+ 0x35dd, 0x7007, 0x0003, 0x701f, 0x546e, 0x0005, 0xa830, 0x9086,
+ 0x0100, 0x2009, 0x0004, 0x0904, 0x35dd, 0x0804, 0x35ab, 0x7aa8,
+ 0x9284, 0xc000, 0x0148, 0xd2ec, 0x01a0, 0x080c, 0x57e7, 0x1188,
+ 0x2009, 0x0014, 0x0804, 0x35dd, 0xd2dc, 0x1578, 0x81ff, 0x2009,
+ 0x0001, 0x1904, 0x35dd, 0x080c, 0x57e7, 0x2009, 0x0007, 0x1904,
+ 0x35dd, 0xd2f4, 0x0138, 0x9284, 0x5000, 0xc0d5, 0x080c, 0x57ad,
+ 0x0804, 0x35ab, 0xd2fc, 0x0160, 0x080c, 0x4bbc, 0x0904, 0x35e0,
+ 0x7984, 0x9284, 0x9000, 0xc0d5, 0x080c, 0x5782, 0x0804, 0x35ab,
+ 0x080c, 0x4bbc, 0x0904, 0x35e0, 0xb804, 0x9084, 0x00ff, 0x9086,
+ 0x0006, 0x2009, 0x0009, 0x1904, 0x555d, 0x080c, 0x4b89, 0x2009,
+ 0x0002, 0x0904, 0x555d, 0xa85c, 0x9080, 0x001b, 0xaf60, 0x2009,
+ 0x0008, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0x080c, 0x4bd2, 0x701f,
+ 0x54ca, 0x0005, 0xa86c, 0x9086, 0x0500, 0x1138, 0xa870, 0x9005,
+ 0x1120, 0xa874, 0x9084, 0xff00, 0x0110, 0x1904, 0x35e0, 0xa866,
+ 0xa832, 0xa868, 0xc0fd, 0xa86a, 0x080c, 0x4bbc, 0x1110, 0x0804,
+ 0x35e0, 0x2009, 0x0043, 0x080c, 0xd33f, 0x2009, 0x0003, 0x0904,
+ 0x555d, 0x7007, 0x0003, 0x701f, 0x54ee, 0x0005, 0xa830, 0x9086,
+ 0x0100, 0x2009, 0x0004, 0x0904, 0x555d, 0x7984, 0x7aa8, 0x9284,
+ 0x1000, 0xc0d5, 0x080c, 0x5782, 0x0804, 0x35ab, 0x00c6, 0xaab0,
+ 0x9284, 0xc000, 0x0148, 0xd2ec, 0x0170, 0x080c, 0x57e7, 0x1158,
+ 0x2009, 0x0014, 0x0804, 0x554c, 0x2061, 0x1800, 0x080c, 0x57e7,
+ 0x2009, 0x0007, 0x15c8, 0xd2f4, 0x0130, 0x9284, 0x5000, 0xc0d5,
+ 0x080c, 0x57ad, 0x0058, 0xd2fc, 0x0180, 0x080c, 0x4bba, 0x0590,
+ 0xa998, 0x9284, 0x9000, 0xc0d5, 0x080c, 0x5782, 0xa87b, 0x0000,
+ 0xa883, 0x0000, 0xa897, 0x4000, 0x0438, 0x080c, 0x4bba, 0x0510,
+ 0x080c, 0x6a92, 0x2009, 0x0009, 0x11b8, 0xa8c4, 0x9086, 0x0500,
+ 0x11c8, 0xa8c8, 0x9005, 0x11b0, 0xa8cc, 0x9084, 0xff00, 0x1190,
+ 0x080c, 0x4bba, 0x1108, 0x0070, 0x2009, 0x004b, 0x080c, 0xd33f,
+ 0x2009, 0x0003, 0x0108, 0x0078, 0x0431, 0x19c0, 0xa897, 0x4005,
+ 0xa99a, 0x0010, 0xa897, 0x4006, 0x900e, 0x9085, 0x0001, 0x2001,
+ 0x0030, 0x00ce, 0x0005, 0x9006, 0x0ce0, 0x7aa8, 0xd2dc, 0x0904,
+ 0x35dd, 0x0016, 0x7984, 0x9284, 0x1000, 0xc0fd, 0x080c, 0x5782,
+ 0x001e, 0x1904, 0x35dd, 0x0804, 0x35ab, 0x00f6, 0x2d78, 0xaab0,
+ 0x0021, 0x00fe, 0x0005, 0xaab0, 0xc2d5, 0xd2dc, 0x0150, 0x0016,
+ 0xa998, 0x9284, 0x1400, 0xc0fd, 0x080c, 0x5782, 0x001e, 0x9085,
+ 0x0001, 0x0005, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x35dd,
+ 0x080c, 0x57e7, 0x0120, 0x2009, 0x0007, 0x0804, 0x35dd, 0x7984,
+ 0x7ea8, 0x96b4, 0x00ff, 0x080c, 0x671d, 0x1904, 0x35e0, 0x9186,
+ 0x007f, 0x0138, 0x080c, 0x6a92, 0x0120, 0x2009, 0x0009, 0x0804,
+ 0x35dd, 0x080c, 0x4b89, 0x1120, 0x2009, 0x0002, 0x0804, 0x35dd,
+ 0xa867, 0x0000, 0xa868, 0xc0fd, 0xa86a, 0x2001, 0x0100, 0x8007,
+ 0xa80a, 0x080c, 0xd03b, 0x1120, 0x2009, 0x0003, 0x0804, 0x35dd,
+ 0x7007, 0x0003, 0x701f, 0x55bd, 0x0005, 0xa808, 0x8007, 0x9086,
+ 0x0100, 0x1120, 0x2009, 0x0004, 0x0804, 0x35dd, 0xa8e0, 0xa866,
+ 0xa810, 0x8007, 0x9084, 0x00ff, 0x800c, 0xa814, 0x8007, 0x9084,
+ 0x00ff, 0x8004, 0x9080, 0x0002, 0x9108, 0x8906, 0x8006, 0x8007,
+ 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, 0x0004, 0x7a8c, 0x7b88,
+ 0x7c9c, 0x7d98, 0x0804, 0x4bd5, 0x080c, 0x4b89, 0x1120, 0x2009,
+ 0x0002, 0x0804, 0x35dd, 0x7984, 0x9194, 0xff00, 0x918c, 0x00ff,
+ 0x8217, 0x82ff, 0x1118, 0x7023, 0x19b5, 0x0040, 0x92c6, 0x0001,
+ 0x1118, 0x7023, 0x19cf, 0x0010, 0x0804, 0x35e0, 0x2009, 0x001a,
+ 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0xa85c, 0x9080, 0x0019, 0xaf60,
+ 0x080c, 0x4bd2, 0x701f, 0x560d, 0x0005, 0x2001, 0x182e, 0x2003,
+ 0x0001, 0xa85c, 0x9080, 0x0019, 0x2098, 0xa860, 0x20e0, 0x20a9,
+ 0x001a, 0x7020, 0x20a0, 0x20e9, 0x0001, 0x4003, 0x0804, 0x35ab,
+ 0x080c, 0x4b89, 0x1120, 0x2009, 0x0002, 0x0804, 0x35dd, 0x7984,
+ 0x9194, 0xff00, 0x918c, 0x00ff, 0x8217, 0x82ff, 0x1118, 0x2099,
+ 0x19b5, 0x0040, 0x92c6, 0x0001, 0x1118, 0x2099, 0x19cf, 0x0010,
+ 0x0804, 0x35e0, 0xa85c, 0x9080, 0x0019, 0x20a0, 0xa860, 0x20e8,
+ 0x20a9, 0x001a, 0x20e1, 0x0001, 0x4003, 0x2009, 0x001a, 0x7a8c,
+ 0x7b88, 0x7c9c, 0x7d98, 0xa85c, 0x9080, 0x0019, 0xaf60, 0x0804,
+ 0x4bd5, 0x7884, 0x908a, 0x1000, 0x1a04, 0x35e0, 0x0126, 0x2091,
+ 0x8000, 0x8003, 0x800b, 0x810b, 0x9108, 0x00c6, 0x2061, 0x19fc,
+ 0x614a, 0x00ce, 0x012e, 0x0804, 0x35ab, 0x00c6, 0x080c, 0x7569,
+ 0x1160, 0x080c, 0x784e, 0x080c, 0x6127, 0x9085, 0x0001, 0x080c,
+ 0x75ad, 0x080c, 0x7495, 0x080c, 0x0dc5, 0x2061, 0x1800, 0x6030,
+ 0xc09d, 0x6032, 0x080c, 0x5fe6, 0x00ce, 0x0005, 0x00c6, 0x2001,
+ 0x1800, 0x2004, 0x908e, 0x0000, 0x0904, 0x35dd, 0x7884, 0x9005,
+ 0x0188, 0x7888, 0x2061, 0x199d, 0x2c0c, 0x2062, 0x080c, 0x2c62,
+ 0x01a0, 0x080c, 0x2c6a, 0x0188, 0x080c, 0x2c72, 0x0170, 0x2162,
+ 0x0804, 0x35e0, 0x2061, 0x0100, 0x6038, 0x9086, 0x0007, 0x1118,
+ 0x2009, 0x0001, 0x0010, 0x2009, 0x0000, 0x7884, 0x9086, 0x0002,
+ 0x1568, 0x2061, 0x0100, 0x6028, 0xc09c, 0x602a, 0x0026, 0x2011,
+ 0x0003, 0x080c, 0xa8ed, 0x2011, 0x0002, 0x080c, 0xa8f7, 0x002e,
+ 0x080c, 0xa801, 0x0036, 0x901e, 0x080c, 0xa877, 0x003e, 0x60e3,
+ 0x0000, 0x080c, 0xedfa, 0x080c, 0xee15, 0x9085, 0x0001, 0x080c,
+ 0x75ad, 0x9006, 0x080c, 0x2d52, 0x2001, 0x1800, 0x2003, 0x0004,
+ 0x2001, 0x19a9, 0x2003, 0x0000, 0x6027, 0x0008, 0x00ce, 0x0804,
+ 0x35ab, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x35dd, 0x080c,
+ 0x57e7, 0x0120, 0x2009, 0x0007, 0x0804, 0x35dd, 0x7984, 0x7ea8,
+ 0x96b4, 0x00ff, 0x080c, 0x671d, 0x1904, 0x35e0, 0x9186, 0x007f,
+ 0x0138, 0x080c, 0x6a92, 0x0120, 0x2009, 0x0009, 0x0804, 0x35dd,
+ 0x080c, 0x4b89, 0x1120, 0x2009, 0x0002, 0x0804, 0x35dd, 0xa867,
+ 0x0000, 0xa868, 0xc0fd, 0xa86a, 0x080c, 0xd03e, 0x1120, 0x2009,
+ 0x0003, 0x0804, 0x35dd, 0x7007, 0x0003, 0x701f, 0x5710, 0x0005,
+ 0xa830, 0x9086, 0x0100, 0x1120, 0x2009, 0x0004, 0x0804, 0x35dd,
+ 0xa8e0, 0xa866, 0xa834, 0x8007, 0x800c, 0xa85c, 0x9080, 0x000c,
+ 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0xaf60, 0x0804, 0x4bd5, 0xa898,
+ 0x9086, 0x000d, 0x1904, 0x35dd, 0x2021, 0x4005, 0x0126, 0x2091,
+ 0x8000, 0x0e04, 0x5734, 0x0010, 0x012e, 0x0cc0, 0x7c36, 0x9486,
+ 0x4000, 0x0118, 0x7833, 0x0011, 0x0010, 0x7833, 0x0010, 0x7883,
+ 0x4005, 0xa998, 0x7986, 0xa9a4, 0x799a, 0xa9a8, 0x799e, 0x080c,
+ 0x4bc5, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c,
+ 0x11aa, 0x7007, 0x0001, 0x2091, 0x5000, 0x700f, 0x0000, 0x012e,
+ 0x0005, 0x0126, 0x2091, 0x8000, 0x00c6, 0x2061, 0x19fc, 0x7984,
+ 0x615a, 0x6156, 0x605f, 0x0000, 0x6053, 0x0009, 0x7898, 0x6072,
+ 0x789c, 0x606e, 0x7888, 0x606a, 0x788c, 0x6066, 0x2001, 0x1a0c,
+ 0x2044, 0x2001, 0x1a13, 0xa076, 0xa060, 0xa072, 0xa07b, 0x0001,
+ 0xa07f, 0x0002, 0xa06b, 0x0000, 0xa09f, 0x0000, 0x00ce, 0x012e,
+ 0x0804, 0x35ab, 0x0126, 0x2091, 0x8000, 0x00b6, 0x00c6, 0x90e4,
+ 0xc000, 0x0168, 0x0006, 0xd0d4, 0x0130, 0x0036, 0x2019, 0x0029,
+ 0x080c, 0x3360, 0x003e, 0x080c, 0xcea3, 0x000e, 0x1198, 0xd0e4,
+ 0x0160, 0x9180, 0x1000, 0x2004, 0x905d, 0x0160, 0x080c, 0x6141,
+ 0x080c, 0xb06b, 0x0110, 0xb817, 0x0000, 0x9006, 0x00ce, 0x00be,
+ 0x012e, 0x0005, 0x9085, 0x0001, 0x0cc8, 0x0126, 0x2091, 0x8000,
+ 0x0156, 0x2010, 0x900e, 0x20a9, 0x0800, 0x0016, 0x9180, 0x1000,
+ 0x2004, 0x9005, 0x0188, 0x9186, 0x007e, 0x0170, 0x9186, 0x007f,
+ 0x0158, 0x9186, 0x0080, 0x0140, 0x9186, 0x00ff, 0x0128, 0x0026,
+ 0x2200, 0x080c, 0x5782, 0x002e, 0x001e, 0x8108, 0x1f04, 0x57b5,
+ 0x015e, 0x012e, 0x0005, 0x2001, 0x1848, 0x2004, 0x0005, 0x2001,
+ 0x1867, 0x2004, 0x0005, 0x0006, 0x2001, 0x1810, 0x2004, 0xd0d4,
+ 0x000e, 0x0005, 0x2001, 0x180e, 0x2004, 0xd0b4, 0x0005, 0x2001,
+ 0x1800, 0x2004, 0x9086, 0x0003, 0x0005, 0x0016, 0x00e6, 0x2071,
+ 0x189e, 0x7108, 0x910d, 0x710a, 0x00ee, 0x001e, 0x0005, 0x79a4,
+ 0x81ff, 0x0904, 0x35e0, 0x9182, 0x0081, 0x1a04, 0x35e0, 0x810c,
+ 0x0016, 0x080c, 0x4b89, 0x0170, 0x080c, 0x0f16, 0x2100, 0x2238,
+ 0x7d84, 0x7c88, 0x7b8c, 0x7a90, 0x001e, 0x080c, 0x4bd2, 0x701f,
+ 0x5817, 0x0005, 0x001e, 0x2009, 0x0002, 0x0804, 0x35dd, 0x2079,
+ 0x0000, 0x7d94, 0x7c98, 0x7ba8, 0x7aac, 0x79a4, 0x810c, 0x2061,
+ 0x18b8, 0x2c44, 0xa770, 0xa074, 0x2071, 0x189e, 0x080c, 0x4bd5,
+ 0x701f, 0x582b, 0x0005, 0x2061, 0x18b8, 0x2c44, 0x0016, 0x0026,
+ 0xa270, 0xa174, 0x080c, 0x0f1e, 0x002e, 0x001e, 0x080c, 0x0fcb,
+ 0x9006, 0xa802, 0xa806, 0x0804, 0x35ab, 0x0126, 0x0156, 0x0136,
+ 0x0146, 0x01c6, 0x01d6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x2061,
+ 0x0100, 0x2069, 0x0200, 0x2071, 0x1800, 0x6044, 0xd0a4, 0x11e8,
+ 0xd084, 0x0118, 0x080c, 0x59e6, 0x0068, 0xd08c, 0x0118, 0x080c,
+ 0x58ef, 0x0040, 0xd094, 0x0118, 0x080c, 0x58bf, 0x0018, 0xd09c,
+ 0x0108, 0x0099, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x01de, 0x01ce,
+ 0x014e, 0x013e, 0x015e, 0x012e, 0x0005, 0x0016, 0x6128, 0xd19c,
+ 0x1110, 0xc19d, 0x612a, 0x001e, 0x0c68, 0x0006, 0x7098, 0x9005,
+ 0x000e, 0x0120, 0x709b, 0x0000, 0x7093, 0x0000, 0x624c, 0x9286,
+ 0xf0f0, 0x1150, 0x6048, 0x9086, 0xf0f0, 0x0130, 0x624a, 0x6043,
+ 0x0090, 0x6043, 0x0010, 0x0490, 0x9294, 0xff00, 0x9296, 0xf700,
+ 0x0178, 0x7138, 0xd1a4, 0x1160, 0x6240, 0x9295, 0x0100, 0x6242,
+ 0x9294, 0x0010, 0x0128, 0x2009, 0x00f7, 0x080c, 0x60a3, 0x00f0,
+ 0x6040, 0x9084, 0x0010, 0x9085, 0x0140, 0x6042, 0x6043, 0x0000,
+ 0x7087, 0x0000, 0x70a3, 0x0001, 0x70c7, 0x0000, 0x70df, 0x0000,
+ 0x2009, 0x1c80, 0x200b, 0x0000, 0x7097, 0x0000, 0x708b, 0x000f,
+ 0x2009, 0x000f, 0x2011, 0x5f89, 0x080c, 0x87a1, 0x0005, 0x2001,
+ 0x1869, 0x2004, 0xd08c, 0x0110, 0x705f, 0xffff, 0x7088, 0x9005,
+ 0x1528, 0x2011, 0x5f89, 0x080c, 0x8709, 0x6040, 0x9094, 0x0010,
+ 0x9285, 0x0020, 0x6042, 0x20a9, 0x00c8, 0x6044, 0xd08c, 0x1168,
+ 0x1f04, 0x58d5, 0x6242, 0x709b, 0x0000, 0x6040, 0x9094, 0x0010,
+ 0x9285, 0x0080, 0x6042, 0x6242, 0x0048, 0x6242, 0x709b, 0x0000,
+ 0x708f, 0x0000, 0x9006, 0x080c, 0x612c, 0x0000, 0x0005, 0x708c,
+ 0x908a, 0x0003, 0x1a0c, 0x0dc5, 0x000b, 0x0005, 0x58f9, 0x594a,
+ 0x59e5, 0x00f6, 0x0016, 0x6900, 0x918c, 0x0800, 0x708f, 0x0001,
+ 0x2001, 0x015d, 0x2003, 0x0000, 0x6803, 0x00fc, 0x20a9, 0x0004,
+ 0x6800, 0x9084, 0x00fc, 0x0120, 0x1f04, 0x5908, 0x080c, 0x0dc5,
+ 0x68a0, 0x68a2, 0x689c, 0x689e, 0x6898, 0x689a, 0xa001, 0x918d,
+ 0x1600, 0x6902, 0x001e, 0x6837, 0x0020, 0x080c, 0x6108, 0x2079,
+ 0x1c00, 0x7833, 0x1101, 0x7837, 0x0000, 0x20e1, 0x0001, 0x2099,
+ 0x1805, 0x20e9, 0x0001, 0x20a1, 0x1c0e, 0x20a9, 0x0004, 0x4003,
+ 0x080c, 0xadbc, 0x20e1, 0x0001, 0x2099, 0x1c00, 0x20e9, 0x0000,
+ 0x20a1, 0x0240, 0x20a9, 0x0014, 0x4003, 0x60c3, 0x000c, 0x600f,
+ 0x0000, 0x080c, 0x5fba, 0x00fe, 0x9006, 0x7092, 0x6043, 0x0008,
+ 0x6042, 0x0005, 0x00f6, 0x7090, 0x7093, 0x0000, 0x9025, 0x0904,
+ 0x59c2, 0x6020, 0xd0b4, 0x1904, 0x59c0, 0x71a0, 0x81ff, 0x0904,
+ 0x59ae, 0x9486, 0x000c, 0x1904, 0x59bb, 0x9480, 0x0018, 0x8004,
+ 0x20a8, 0x080c, 0x6101, 0x2011, 0x0260, 0x2019, 0x1c00, 0x220c,
+ 0x2304, 0x9106, 0x11e8, 0x8210, 0x8318, 0x1f04, 0x5967, 0x6043,
+ 0x0004, 0x2061, 0x0140, 0x605b, 0xbc94, 0x605f, 0xf0f0, 0x2061,
+ 0x0100, 0x6043, 0x0006, 0x708f, 0x0002, 0x709b, 0x0002, 0x2009,
+ 0x07d0, 0x2011, 0x5f90, 0x080c, 0x87a1, 0x080c, 0x6108, 0x04c0,
+ 0x080c, 0x6101, 0x2079, 0x0260, 0x7930, 0x918e, 0x1101, 0x1558,
+ 0x7834, 0x9005, 0x1540, 0x7900, 0x918c, 0x00ff, 0x1118, 0x7804,
+ 0x9005, 0x0190, 0x080c, 0x6101, 0x2011, 0x026e, 0x2019, 0x1805,
+ 0x20a9, 0x0004, 0x220c, 0x2304, 0x9102, 0x0230, 0x11a0, 0x8210,
+ 0x8318, 0x1f04, 0x59a2, 0x0078, 0x70a3, 0x0000, 0x080c, 0x6101,
+ 0x20e1, 0x0000, 0x2099, 0x0260, 0x20e9, 0x0001, 0x20a1, 0x1c00,
+ 0x20a9, 0x0014, 0x4003, 0x6043, 0x0008, 0x6043, 0x0000, 0x0010,
+ 0x00fe, 0x0005, 0x6040, 0x9085, 0x0100, 0x6042, 0x6020, 0xd0b4,
+ 0x1db8, 0x080c, 0xadbc, 0x20e1, 0x0001, 0x2099, 0x1c00, 0x20e9,
+ 0x0000, 0x20a1, 0x0240, 0x20a9, 0x0014, 0x4003, 0x60c3, 0x000c,
+ 0x2011, 0x19f3, 0x2013, 0x0000, 0x7093, 0x0000, 0x60a3, 0x0056,
+ 0x60a7, 0x9575, 0x080c, 0xa50e, 0x08d8, 0x0005, 0x7098, 0x908a,
+ 0x001d, 0x1a0c, 0x0dc5, 0x000b, 0x0005, 0x5a17, 0x5a2a, 0x5a53,
+ 0x5a73, 0x5a99, 0x5ac8, 0x5aee, 0x5b26, 0x5b4c, 0x5b7a, 0x5bb5,
+ 0x5bed, 0x5c0b, 0x5c36, 0x5c58, 0x5c73, 0x5c7d, 0x5cb1, 0x5cd7,
+ 0x5d06, 0x5d2c, 0x5d64, 0x5da8, 0x5de5, 0x5e06, 0x5e5f, 0x5e81,
+ 0x5eaf, 0x5eaf, 0x00c6, 0x2061, 0x1800, 0x6003, 0x0007, 0x2061,
+ 0x0100, 0x6004, 0x9084, 0xfff9, 0x6006, 0x00ce, 0x0005, 0x2061,
+ 0x0140, 0x605b, 0xbc94, 0x605f, 0xf0f0, 0x2061, 0x0100, 0x6043,
+ 0x0002, 0x709b, 0x0001, 0x2009, 0x07d0, 0x2011, 0x5f90, 0x080c,
+ 0x87a1, 0x0005, 0x00f6, 0x7090, 0x9086, 0x0014, 0x1510, 0x6042,
+ 0x6020, 0xd0b4, 0x11f0, 0x080c, 0x6101, 0x2079, 0x0260, 0x7a30,
+ 0x9296, 0x1102, 0x11a0, 0x7834, 0x9005, 0x1188, 0x7a38, 0xd2fc,
+ 0x0128, 0x70c4, 0x9005, 0x1110, 0x70c7, 0x0001, 0x2011, 0x5f90,
+ 0x080c, 0x8709, 0x709b, 0x0010, 0x080c, 0x5c7d, 0x0010, 0x7093,
+ 0x0000, 0x00fe, 0x0005, 0x00f6, 0x709b, 0x0003, 0x6043, 0x0004,
+ 0x2011, 0x5f90, 0x080c, 0x8709, 0x080c, 0x6085, 0x2079, 0x0240,
+ 0x7833, 0x1102, 0x7837, 0x0000, 0x20a9, 0x0008, 0x9f88, 0x000e,
+ 0x200b, 0x0000, 0x8108, 0x1f04, 0x5a68, 0x60c3, 0x0014, 0x080c,
+ 0x5fba, 0x00fe, 0x0005, 0x00f6, 0x7090, 0x9005, 0x0500, 0x2011,
+ 0x5f90, 0x080c, 0x8709, 0x9086, 0x0014, 0x11b8, 0x080c, 0x6101,
+ 0x2079, 0x0260, 0x7a30, 0x9296, 0x1102, 0x1178, 0x7834, 0x9005,
0x1160, 0x7a38, 0xd2fc, 0x0128, 0x70c4, 0x9005, 0x1110, 0x70c7,
- 0x0001, 0x709b, 0x0012, 0x0029, 0x0010, 0x7093, 0x0000, 0x00fe,
- 0x0005, 0x00f6, 0x709b, 0x0013, 0x080c, 0x608d, 0x2079, 0x0240,
- 0x7833, 0x1103, 0x7837, 0x0000, 0x080c, 0x60fb, 0x080c, 0x60de,
+ 0x0001, 0x709b, 0x0004, 0x0029, 0x0010, 0x080c, 0x60dd, 0x00fe,
+ 0x0005, 0x00f6, 0x709b, 0x0005, 0x080c, 0x6085, 0x2079, 0x0240,
+ 0x7833, 0x1103, 0x7837, 0x0000, 0x080c, 0x6101, 0x080c, 0x60e4,
0x1170, 0x7084, 0x9005, 0x1158, 0x715c, 0x9186, 0xffff, 0x0138,
- 0x2011, 0x0008, 0x080c, 0x5f37, 0x0168, 0x080c, 0x60b4, 0x20a9,
+ 0x2011, 0x0008, 0x080c, 0x5f3d, 0x0168, 0x080c, 0x60ba, 0x20a9,
0x0008, 0x20e1, 0x0000, 0x2099, 0x026e, 0x20e9, 0x0000, 0x20a1,
- 0x024e, 0x4003, 0x60c3, 0x0014, 0x080c, 0x5fb4, 0x00fe, 0x0005,
- 0x00f6, 0x7090, 0x9005, 0x0500, 0x2011, 0x5f8a, 0x080c, 0x8703,
- 0x9086, 0x0014, 0x11b8, 0x080c, 0x60fb, 0x2079, 0x0260, 0x7a30,
- 0x9296, 0x1104, 0x1178, 0x7834, 0x9005, 0x1160, 0x7a38, 0xd2fc,
- 0x0128, 0x70c4, 0x9005, 0x1110, 0x70c7, 0x0001, 0x709b, 0x0014,
- 0x0029, 0x0010, 0x7093, 0x0000, 0x00fe, 0x0005, 0x00f6, 0x709b,
- 0x0015, 0x080c, 0x608d, 0x2079, 0x0240, 0x7833, 0x1104, 0x7837,
- 0x0000, 0x080c, 0x60fb, 0x080c, 0x60de, 0x11b8, 0x7084, 0x9005,
- 0x11a0, 0x7164, 0x9186, 0xffff, 0x0180, 0x9180, 0x33b1, 0x200d,
- 0x918c, 0xff00, 0x810f, 0x2011, 0x0008, 0x080c, 0x5f37, 0x0180,
- 0x080c, 0x50c9, 0x0110, 0x080c, 0x28f2, 0x20a9, 0x0008, 0x20e1,
+ 0x024e, 0x4003, 0x60c3, 0x0014, 0x080c, 0x5fba, 0x00fe, 0x0005,
+ 0x00f6, 0x7090, 0x9005, 0x0500, 0x2011, 0x5f90, 0x080c, 0x8709,
+ 0x9086, 0x0014, 0x11b8, 0x080c, 0x6101, 0x2079, 0x0260, 0x7a30,
+ 0x9296, 0x1103, 0x1178, 0x7834, 0x9005, 0x1160, 0x7a38, 0xd2fc,
+ 0x0128, 0x70c4, 0x9005, 0x1110, 0x70c7, 0x0001, 0x709b, 0x0006,
+ 0x0029, 0x0010, 0x080c, 0x60dd, 0x00fe, 0x0005, 0x00f6, 0x709b,
+ 0x0007, 0x080c, 0x6085, 0x2079, 0x0240, 0x7833, 0x1104, 0x7837,
+ 0x0000, 0x080c, 0x6101, 0x080c, 0x60e4, 0x11b8, 0x7084, 0x9005,
+ 0x11a0, 0x7164, 0x9186, 0xffff, 0x0180, 0x9180, 0x33ac, 0x200d,
+ 0x918c, 0xff00, 0x810f, 0x2011, 0x0008, 0x080c, 0x5f3d, 0x0180,
+ 0x080c, 0x50cf, 0x0110, 0x080c, 0x28fd, 0x20a9, 0x0008, 0x20e1,
+ 0x0000, 0x2099, 0x026e, 0x20e9, 0x0000, 0x20a1, 0x024e, 0x4003,
+ 0x60c3, 0x0014, 0x080c, 0x5fba, 0x00fe, 0x0005, 0x00f6, 0x7090,
+ 0x9005, 0x0500, 0x2011, 0x5f90, 0x080c, 0x8709, 0x9086, 0x0014,
+ 0x11b8, 0x080c, 0x6101, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1104,
+ 0x1178, 0x7834, 0x9005, 0x1160, 0x7a38, 0xd2fc, 0x0128, 0x70c4,
+ 0x9005, 0x1110, 0x70c7, 0x0001, 0x709b, 0x0008, 0x0029, 0x0010,
+ 0x080c, 0x60dd, 0x00fe, 0x0005, 0x00f6, 0x709b, 0x0009, 0x080c,
+ 0x6085, 0x2079, 0x0240, 0x7833, 0x1105, 0x7837, 0x0100, 0x080c,
+ 0x60e4, 0x1150, 0x7084, 0x9005, 0x1138, 0x080c, 0x5eb0, 0x1188,
+ 0x9085, 0x0001, 0x080c, 0x28fd, 0x20a9, 0x0008, 0x080c, 0x6101,
+ 0x20e1, 0x0000, 0x2099, 0x026e, 0x20e9, 0x0000, 0x20a1, 0x024e,
+ 0x4003, 0x60c3, 0x0014, 0x080c, 0x5fba, 0x0010, 0x080c, 0x5a0a,
+ 0x00fe, 0x0005, 0x00f6, 0x7090, 0x9005, 0x05a8, 0x2011, 0x5f90,
+ 0x080c, 0x8709, 0x9086, 0x0014, 0x1560, 0x080c, 0x6101, 0x2079,
+ 0x0260, 0x7a30, 0x9296, 0x1105, 0x1520, 0x7834, 0x9084, 0x0100,
+ 0x2011, 0x0100, 0x921e, 0x1160, 0x7a38, 0xd2fc, 0x0128, 0x70c4,
+ 0x9005, 0x1110, 0x70c7, 0x0001, 0x709b, 0x000a, 0x00b1, 0x0098,
+ 0x9005, 0x1178, 0x7a38, 0xd2fc, 0x0128, 0x70c4, 0x9005, 0x1110,
+ 0x70c7, 0x0001, 0x7097, 0x0000, 0x709b, 0x000e, 0x080c, 0x5c58,
+ 0x0010, 0x080c, 0x60dd, 0x00fe, 0x0005, 0x00f6, 0x709b, 0x000b,
+ 0x2011, 0x1c0e, 0x20e9, 0x0001, 0x22a0, 0x20a9, 0x0040, 0x2019,
+ 0xffff, 0x4304, 0x080c, 0x6085, 0x2079, 0x0240, 0x7833, 0x1106,
+ 0x7837, 0x0000, 0x080c, 0x60e4, 0x0118, 0x2013, 0x0000, 0x0020,
+ 0x7060, 0x9085, 0x0100, 0x2012, 0x20a9, 0x0040, 0x2009, 0x024e,
+ 0x2011, 0x1c0e, 0x220e, 0x8210, 0x8108, 0x9186, 0x0260, 0x1128,
+ 0x6810, 0x8000, 0x6812, 0x2009, 0x0240, 0x1f04, 0x5bda, 0x60c3,
+ 0x0084, 0x080c, 0x5fba, 0x00fe, 0x0005, 0x00f6, 0x7090, 0x9005,
+ 0x01c0, 0x2011, 0x5f90, 0x080c, 0x8709, 0x9086, 0x0084, 0x1178,
+ 0x080c, 0x6101, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1106, 0x1138,
+ 0x7834, 0x9005, 0x1120, 0x709b, 0x000c, 0x0029, 0x0010, 0x080c,
+ 0x60dd, 0x00fe, 0x0005, 0x00f6, 0x709b, 0x000d, 0x080c, 0x6085,
+ 0x2079, 0x0240, 0x7833, 0x1107, 0x7837, 0x0000, 0x080c, 0x6101,
+ 0x20a9, 0x0040, 0x2011, 0x026e, 0x2009, 0x024e, 0x220e, 0x8210,
+ 0x8108, 0x9186, 0x0260, 0x1150, 0x6810, 0x8000, 0x6812, 0x2009,
+ 0x0240, 0x6814, 0x8000, 0x6816, 0x2011, 0x0260, 0x1f04, 0x5c1e,
+ 0x60c3, 0x0084, 0x080c, 0x5fba, 0x00fe, 0x0005, 0x00f6, 0x7090,
+ 0x9005, 0x01e0, 0x2011, 0x5f90, 0x080c, 0x8709, 0x9086, 0x0084,
+ 0x1198, 0x080c, 0x6101, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1107,
+ 0x1158, 0x7834, 0x9005, 0x1140, 0x7097, 0x0001, 0x080c, 0x6057,
+ 0x709b, 0x000e, 0x0029, 0x0010, 0x080c, 0x60dd, 0x00fe, 0x0005,
+ 0x918d, 0x0001, 0x080c, 0x612c, 0x709b, 0x000f, 0x7093, 0x0000,
+ 0x2061, 0x0140, 0x605b, 0xbc85, 0x605f, 0xb5b5, 0x2061, 0x0100,
+ 0x6043, 0x0005, 0x6043, 0x0004, 0x2009, 0x07d0, 0x2011, 0x5f90,
+ 0x080c, 0x86fd, 0x0005, 0x7090, 0x9005, 0x0130, 0x2011, 0x5f90,
+ 0x080c, 0x8709, 0x709b, 0x0000, 0x0005, 0x709b, 0x0011, 0x080c,
+ 0xadbc, 0x080c, 0x6101, 0x20e1, 0x0000, 0x2099, 0x0260, 0x20e9,
+ 0x0000, 0x20a1, 0x0240, 0x7490, 0x9480, 0x0018, 0x9080, 0x0007,
+ 0x9084, 0x03f8, 0x8004, 0x20a8, 0x4003, 0x080c, 0x60e4, 0x11a0,
+ 0x717c, 0x81ff, 0x0188, 0x900e, 0x7080, 0x9084, 0x00ff, 0x0160,
+ 0x080c, 0x2894, 0x9186, 0x007e, 0x0138, 0x9186, 0x0080, 0x0120,
+ 0x2011, 0x0008, 0x080c, 0x5f3d, 0x60c3, 0x0014, 0x080c, 0x5fba,
+ 0x0005, 0x00f6, 0x7090, 0x9005, 0x0500, 0x2011, 0x5f90, 0x080c,
+ 0x8709, 0x9086, 0x0014, 0x11b8, 0x080c, 0x6101, 0x2079, 0x0260,
+ 0x7a30, 0x9296, 0x1103, 0x1178, 0x7834, 0x9005, 0x1160, 0x7a38,
+ 0xd2fc, 0x0128, 0x70c4, 0x9005, 0x1110, 0x70c7, 0x0001, 0x709b,
+ 0x0012, 0x0029, 0x0010, 0x7093, 0x0000, 0x00fe, 0x0005, 0x00f6,
+ 0x709b, 0x0013, 0x080c, 0x6093, 0x2079, 0x0240, 0x7833, 0x1103,
+ 0x7837, 0x0000, 0x080c, 0x6101, 0x080c, 0x60e4, 0x1170, 0x7084,
+ 0x9005, 0x1158, 0x715c, 0x9186, 0xffff, 0x0138, 0x2011, 0x0008,
+ 0x080c, 0x5f3d, 0x0168, 0x080c, 0x60ba, 0x20a9, 0x0008, 0x20e1,
0x0000, 0x2099, 0x026e, 0x20e9, 0x0000, 0x20a1, 0x024e, 0x4003,
- 0x60c3, 0x0014, 0x080c, 0x5fb4, 0x00fe, 0x0005, 0x00f6, 0x7090,
- 0x9005, 0x05f0, 0x2011, 0x5f8a, 0x080c, 0x8703, 0x9086, 0x0014,
- 0x15a8, 0x080c, 0x60fb, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1105,
- 0x1568, 0x7834, 0x9084, 0x0100, 0x2011, 0x0100, 0x921e, 0x1168,
- 0x9085, 0x0001, 0x080c, 0x6126, 0x7a38, 0xd2fc, 0x0128, 0x70c4,
- 0x9005, 0x1110, 0x70c7, 0x0001, 0x0080, 0x9005, 0x11b8, 0x7a38,
- 0xd2fc, 0x0128, 0x70c4, 0x9005, 0x1110, 0x70c7, 0x0001, 0x9085,
- 0x0001, 0x080c, 0x6126, 0x7097, 0x0000, 0x7a38, 0xd2f4, 0x0110,
- 0x70df, 0x0008, 0x709b, 0x0016, 0x0029, 0x0010, 0x7093, 0x0000,
- 0x00fe, 0x0005, 0x080c, 0xada2, 0x080c, 0x60fb, 0x20e1, 0x0000,
- 0x2099, 0x0260, 0x20e9, 0x0000, 0x20a1, 0x0240, 0x20a9, 0x000e,
- 0x4003, 0x2011, 0x026d, 0x2204, 0x9084, 0x0100, 0x2011, 0x024d,
- 0x2012, 0x2011, 0x026e, 0x709b, 0x0017, 0x080c, 0x60de, 0x1150,
- 0x7084, 0x9005, 0x1138, 0x080c, 0x5eaa, 0x1188, 0x9085, 0x0001,
- 0x080c, 0x28f2, 0x20a9, 0x0008, 0x080c, 0x60fb, 0x20e1, 0x0000,
- 0x2099, 0x026e, 0x20e9, 0x0000, 0x20a1, 0x024e, 0x4003, 0x60c3,
- 0x0014, 0x080c, 0x5fb4, 0x0010, 0x080c, 0x5a04, 0x0005, 0x00f6,
- 0x7090, 0x9005, 0x01d8, 0x2011, 0x5f8a, 0x080c, 0x8703, 0x9086,
- 0x0084, 0x1190, 0x080c, 0x60fb, 0x2079, 0x0260, 0x7a30, 0x9296,
- 0x1106, 0x1150, 0x7834, 0x9005, 0x1138, 0x9006, 0x080c, 0x6126,
- 0x709b, 0x0018, 0x0029, 0x0010, 0x7093, 0x0000, 0x00fe, 0x0005,
- 0x00f6, 0x709b, 0x0019, 0x080c, 0x608d, 0x2079, 0x0240, 0x7833,
- 0x1106, 0x7837, 0x0000, 0x080c, 0x60fb, 0x2009, 0x026e, 0x2039,
- 0x1c0e, 0x20a9, 0x0040, 0x213e, 0x8738, 0x8108, 0x9186, 0x0280,
- 0x1128, 0x6814, 0x8000, 0x6816, 0x2009, 0x0260, 0x1f04, 0x5e13,
- 0x2039, 0x1c0e, 0x080c, 0x60de, 0x11e8, 0x2728, 0x2514, 0x8207,
- 0x9084, 0x00ff, 0x8000, 0x2018, 0x9294, 0x00ff, 0x8007, 0x9205,
- 0x202a, 0x7060, 0x2310, 0x8214, 0x92a0, 0x1c0e, 0x2414, 0x938c,
- 0x0001, 0x0118, 0x9294, 0xff00, 0x0018, 0x9294, 0x00ff, 0x8007,
- 0x9215, 0x2222, 0x20a9, 0x0040, 0x2009, 0x024e, 0x270e, 0x8738,
- 0x8108, 0x9186, 0x0260, 0x1128, 0x6810, 0x8000, 0x6812, 0x2009,
- 0x0240, 0x1f04, 0x5e46, 0x60c3, 0x0084, 0x080c, 0x5fb4, 0x00fe,
- 0x0005, 0x00f6, 0x7090, 0x9005, 0x01e0, 0x2011, 0x5f8a, 0x080c,
- 0x8703, 0x9086, 0x0084, 0x1198, 0x080c, 0x60fb, 0x2079, 0x0260,
- 0x7a30, 0x9296, 0x1107, 0x1158, 0x7834, 0x9005, 0x1140, 0x7097,
- 0x0001, 0x080c, 0x6051, 0x709b, 0x001a, 0x0029, 0x0010, 0x7093,
- 0x0000, 0x00fe, 0x0005, 0x9085, 0x0001, 0x080c, 0x6126, 0x709b,
- 0x001b, 0x080c, 0xada2, 0x080c, 0x60fb, 0x2011, 0x0260, 0x2009,
- 0x0240, 0x7490, 0x9480, 0x0018, 0x9080, 0x0007, 0x9084, 0x03f8,
- 0x8004, 0x20a8, 0x220e, 0x8210, 0x8108, 0x9186, 0x0260, 0x1150,
- 0x6810, 0x8000, 0x6812, 0x2009, 0x0240, 0x6814, 0x8000, 0x6816,
- 0x2011, 0x0260, 0x1f04, 0x5e92, 0x60c3, 0x0084, 0x080c, 0x5fb4,
- 0x0005, 0x0005, 0x0086, 0x0096, 0x2029, 0x1848, 0x252c, 0x20a9,
- 0x0008, 0x2041, 0x1c0e, 0x20e9, 0x0001, 0x28a0, 0x080c, 0x60fb,
- 0x20e1, 0x0000, 0x2099, 0x026e, 0x4003, 0x20a9, 0x0008, 0x2011,
- 0x0007, 0xd5d4, 0x0108, 0x9016, 0x2800, 0x9200, 0x200c, 0x91a6,
- 0xffff, 0x1148, 0xd5d4, 0x0110, 0x8210, 0x0008, 0x8211, 0x1f04,
- 0x5ec4, 0x0804, 0x5f33, 0x82ff, 0x1160, 0xd5d4, 0x0120, 0x91a6,
- 0x3fff, 0x0d90, 0x0020, 0x91a6, 0x3fff, 0x0904, 0x5f33, 0x918d,
- 0xc000, 0x20a9, 0x0010, 0x2019, 0x0001, 0xd5d4, 0x0110, 0x2019,
- 0x0010, 0x2120, 0xd5d4, 0x0110, 0x8423, 0x0008, 0x8424, 0x1240,
- 0xd5d4, 0x0110, 0x8319, 0x0008, 0x8318, 0x1f04, 0x5eea, 0x04d8,
- 0x23a8, 0x2021, 0x0001, 0x8426, 0x8425, 0x1f04, 0x5efc, 0x2328,
- 0x8529, 0x92be, 0x0007, 0x0158, 0x0006, 0x2039, 0x0007, 0x2200,
- 0x973a, 0x000e, 0x27a8, 0x95a8, 0x0010, 0x1f04, 0x5f0b, 0x755e,
- 0x95c8, 0x33b1, 0x292d, 0x95ac, 0x00ff, 0x7582, 0x6532, 0x6536,
- 0x0016, 0x2508, 0x080c, 0x28d2, 0x001e, 0x60e7, 0x0000, 0x65ea,
- 0x2018, 0x2304, 0x9405, 0x201a, 0x7087, 0x0001, 0x20e9, 0x0000,
- 0x20a1, 0x024e, 0x20e1, 0x0001, 0x2898, 0x20a9, 0x0008, 0x4003,
- 0x9085, 0x0001, 0x0008, 0x9006, 0x009e, 0x008e, 0x0005, 0x0156,
- 0x01c6, 0x01d6, 0x0136, 0x0146, 0x22a8, 0x20e1, 0x0000, 0x2099,
- 0x026e, 0x20e9, 0x0000, 0x2011, 0x024e, 0x22a0, 0x4003, 0x014e,
- 0x013e, 0x01de, 0x01ce, 0x015e, 0x2118, 0x9026, 0x2001, 0x0007,
- 0x939a, 0x0010, 0x0218, 0x8420, 0x8001, 0x0cd0, 0x2118, 0x84ff,
- 0x0120, 0x939a, 0x0010, 0x8421, 0x1de0, 0x2021, 0x0001, 0x83ff,
- 0x0118, 0x8423, 0x8319, 0x1de8, 0x9238, 0x2029, 0x026e, 0x9528,
- 0x2504, 0x942c, 0x11b8, 0x9405, 0x203a, 0x715e, 0x91a0, 0x33b1,
- 0x242d, 0x95ac, 0x00ff, 0x7582, 0x6532, 0x6536, 0x0016, 0x2508,
- 0x080c, 0x28d2, 0x001e, 0x60e7, 0x0000, 0x65ea, 0x7087, 0x0001,
- 0x9084, 0x0000, 0x0005, 0x00e6, 0x2071, 0x1800, 0x708b, 0x0000,
- 0x00ee, 0x0005, 0x00e6, 0x00f6, 0x2079, 0x0100, 0x2071, 0x0140,
- 0x080c, 0x6040, 0x080c, 0xa4fd, 0x7004, 0x9084, 0x4000, 0x0110,
- 0x080c, 0x2d6b, 0x0126, 0x2091, 0x8000, 0x2071, 0x1826, 0x2073,
- 0x0000, 0x7840, 0x0026, 0x0016, 0x2009, 0x00f7, 0x080c, 0x609d,
- 0x001e, 0x9094, 0x0010, 0x9285, 0x0080, 0x7842, 0x7a42, 0x002e,
- 0x012e, 0x00fe, 0x00ee, 0x0005, 0x0126, 0x2091, 0x8000, 0x080c,
- 0x2bf0, 0x0228, 0x2011, 0x0101, 0x2204, 0xc0c5, 0x2012, 0x2011,
- 0x19f3, 0x2013, 0x0000, 0x7093, 0x0000, 0x012e, 0x60a3, 0x0056,
- 0x60a7, 0x9575, 0x080c, 0xa4f4, 0x6144, 0xd184, 0x0120, 0x7198,
- 0x918d, 0x2000, 0x0018, 0x718c, 0x918d, 0x1000, 0x2011, 0x199a,
- 0x2112, 0x2009, 0x07d0, 0x2011, 0x5f8a, 0x080c, 0x879b, 0x0005,
- 0x0016, 0x0026, 0x00c6, 0x0126, 0x2091, 0x8000, 0x080c, 0xb058,
- 0x2009, 0x00f7, 0x080c, 0x609d, 0x2061, 0x19fc, 0x900e, 0x611a,
- 0x611e, 0x617a, 0x617e, 0x2061, 0x1800, 0x6003, 0x0001, 0x2061,
- 0x0100, 0x6043, 0x0090, 0x6043, 0x0010, 0x2009, 0x199a, 0x200b,
- 0x0000, 0x2009, 0x002d, 0x2011, 0x600c, 0x080c, 0x86f7, 0x012e,
- 0x00ce, 0x002e, 0x001e, 0x0005, 0x00e6, 0x0006, 0x0126, 0x2091,
- 0x8000, 0x0471, 0x2071, 0x0100, 0x080c, 0xa4fd, 0x2071, 0x0140,
- 0x7004, 0x9084, 0x4000, 0x0110, 0x080c, 0x2d6b, 0x080c, 0x756b,
- 0x0188, 0x080c, 0x7586, 0x1170, 0x080c, 0x7852, 0x0016, 0x080c,
- 0x29a1, 0x2001, 0x196e, 0x2102, 0x001e, 0x080c, 0x784d, 0x080c,
- 0x748f, 0x0050, 0x2009, 0x0001, 0x080c, 0x2c89, 0x2001, 0x0001,
- 0x080c, 0x2832, 0x080c, 0x5fe0, 0x012e, 0x000e, 0x00ee, 0x0005,
- 0x2001, 0x180e, 0x2004, 0xd0bc, 0x0158, 0x0026, 0x0036, 0x2011,
- 0x8017, 0x2001, 0x199a, 0x201c, 0x080c, 0x4be3, 0x003e, 0x002e,
- 0x0005, 0x20a9, 0x0012, 0x20e9, 0x0001, 0x20a1, 0x1c80, 0x080c,
- 0x60fb, 0x20e9, 0x0000, 0x2099, 0x026e, 0x0099, 0x20a9, 0x0020,
- 0x080c, 0x60f5, 0x2099, 0x0260, 0x20a1, 0x1c92, 0x0051, 0x20a9,
- 0x000e, 0x080c, 0x60f8, 0x2099, 0x0260, 0x20a1, 0x1cb2, 0x0009,
- 0x0005, 0x0016, 0x0026, 0x3410, 0x3308, 0x2104, 0x8007, 0x2012,
- 0x8108, 0x8210, 0x1f04, 0x6075, 0x002e, 0x001e, 0x0005, 0x080c,
- 0xada2, 0x20e1, 0x0001, 0x2099, 0x1c00, 0x20e9, 0x0000, 0x20a1,
- 0x0240, 0x20a9, 0x000c, 0x4003, 0x0005, 0x080c, 0xada2, 0x080c,
- 0x60fb, 0x20e1, 0x0000, 0x2099, 0x0260, 0x20e9, 0x0000, 0x20a1,
- 0x0240, 0x20a9, 0x000c, 0x4003, 0x0005, 0x00c6, 0x0006, 0x2061,
- 0x0100, 0x810f, 0x2001, 0x1834, 0x2004, 0x9005, 0x1138, 0x2001,
- 0x1818, 0x2004, 0x9084, 0x00ff, 0x9105, 0x0010, 0x9185, 0x00f7,
- 0x604a, 0x000e, 0x00ce, 0x0005, 0x0016, 0x0046, 0x080c, 0x6a88,
- 0x0158, 0x9006, 0x2020, 0x2009, 0x002a, 0x080c, 0xe940, 0x2001,
- 0x180c, 0x200c, 0xc195, 0x2102, 0x2019, 0x002a, 0x900e, 0x080c,
- 0x3216, 0x080c, 0xd548, 0x0140, 0x0036, 0x2019, 0xffff, 0x2021,
- 0x0007, 0x080c, 0x4d9a, 0x003e, 0x004e, 0x001e, 0x0005, 0x080c,
- 0x5fe0, 0x709b, 0x0000, 0x7093, 0x0000, 0x0005, 0x0006, 0x2001,
- 0x180c, 0x2004, 0xd09c, 0x0100, 0x000e, 0x0005, 0x0006, 0x0016,
- 0x0126, 0x2091, 0x8000, 0x2001, 0x0101, 0x200c, 0x918d, 0x0006,
- 0x2102, 0x012e, 0x001e, 0x000e, 0x0005, 0x2009, 0x0001, 0x0020,
- 0x2009, 0x0002, 0x0008, 0x900e, 0x6814, 0x9084, 0xffc0, 0x910d,
- 0x6916, 0x0005, 0x00f6, 0x0156, 0x0146, 0x01d6, 0x9006, 0x20a9,
- 0x0080, 0x20e9, 0x0001, 0x20a1, 0x1c00, 0x4004, 0x2079, 0x1c00,
- 0x7803, 0x2200, 0x7807, 0x00ef, 0x780f, 0x00ef, 0x7813, 0x0138,
- 0x7823, 0xffff, 0x7827, 0xffff, 0x01de, 0x014e, 0x015e, 0x00fe,
- 0x0005, 0x2001, 0x1800, 0x2003, 0x0001, 0x0005, 0x2001, 0x19a7,
- 0x0118, 0x2003, 0x0001, 0x0010, 0x2003, 0x0000, 0x0005, 0x0156,
- 0x20a9, 0x0800, 0x2009, 0x1000, 0x9006, 0x200a, 0x8108, 0x1f04,
- 0x6135, 0x015e, 0x0005, 0x00d6, 0x0036, 0x0156, 0x0136, 0x0146,
- 0x2069, 0x1847, 0x9006, 0xb802, 0xb8ce, 0xb807, 0x0707, 0xb80a,
- 0xb80e, 0xb812, 0x9198, 0x33b1, 0x231d, 0x939c, 0x00ff, 0xbb16,
- 0x0016, 0x0026, 0xb8c2, 0x080c, 0xb051, 0x1120, 0x9192, 0x007e,
- 0x1208, 0xbbc2, 0x20a9, 0x0004, 0xb8c4, 0x20e8, 0xb9c8, 0x9198,
- 0x0006, 0x9006, 0x23a0, 0x4004, 0x20a9, 0x0004, 0x9198, 0x000a,
- 0x23a0, 0x4004, 0x002e, 0x001e, 0xb83e, 0xb842, 0xb84e, 0xb852,
- 0xb856, 0xb85a, 0xb85e, 0xb862, 0xb866, 0xb86a, 0xb86f, 0x0100,
- 0xb872, 0xb876, 0xb87a, 0xb88a, 0xb88e, 0xb893, 0x0008, 0xb896,
- 0xb89a, 0xb89e, 0xb8be, 0xb9a2, 0x0096, 0xb8a4, 0x904d, 0x0110,
- 0x080c, 0x1040, 0xb8a7, 0x0000, 0x009e, 0x9006, 0xb84a, 0x6810,
- 0xb83a, 0x680c, 0xb846, 0xb8bb, 0x0520, 0xb8ac, 0x9005, 0x0198,
- 0x00c6, 0x2060, 0x9c82, 0x1cd0, 0x0a0c, 0x0dc5, 0x2001, 0x181a,
- 0x2004, 0x9c02, 0x1a0c, 0x0dc5, 0x080c, 0x8bbd, 0x00ce, 0x090c,
- 0x8f5e, 0xb8af, 0x0000, 0x6814, 0x9084, 0x00ff, 0xb842, 0x014e,
- 0x013e, 0x015e, 0x003e, 0x00de, 0x0005, 0x0126, 0x2091, 0x8000,
- 0xa974, 0xae78, 0x9684, 0x3fff, 0x9082, 0x4000, 0x1a04, 0x6223,
- 0x9182, 0x0800, 0x1a04, 0x6227, 0x2001, 0x180c, 0x2004, 0x9084,
- 0x0003, 0x1904, 0x622d, 0x9188, 0x1000, 0x2104, 0x905d, 0x0518,
- 0xb804, 0x9084, 0x00ff, 0x908e, 0x0006, 0x1508, 0xb8a4, 0x900d,
- 0x1904, 0x623f, 0xb850, 0x900d, 0x1148, 0xa802, 0x2900, 0xb852,
- 0xb84e, 0x080c, 0x9352, 0x9006, 0x012e, 0x0005, 0x00a6, 0x2150,
- 0x2900, 0xb002, 0xa803, 0x0000, 0x00ae, 0xb852, 0x0c90, 0x2001,
- 0x0005, 0x900e, 0x04b8, 0x2001, 0x0028, 0x900e, 0x0498, 0x9082,
- 0x0006, 0x1290, 0x080c, 0xb051, 0x1160, 0xb8a0, 0x9084, 0xff80,
- 0x1140, 0xb900, 0xd1fc, 0x0990, 0x2001, 0x0029, 0x2009, 0x1000,
- 0x0408, 0x2001, 0x0028, 0x00a8, 0x2009, 0x180c, 0x210c, 0xd18c,
- 0x0118, 0x2001, 0x0004, 0x0068, 0xd184, 0x0118, 0x2001, 0x0004,
- 0x0040, 0x2001, 0x0029, 0xb900, 0xd1fc, 0x0118, 0x2009, 0x1000,
- 0x0048, 0x900e, 0x0038, 0x2001, 0x0029, 0x900e, 0x0018, 0x2001,
- 0x0029, 0x900e, 0x9005, 0x012e, 0x0005, 0x2001, 0x180c, 0x2004,
- 0xd084, 0x19d0, 0x9188, 0x1000, 0x2104, 0x905d, 0x09a8, 0x080c,
- 0x6a8c, 0x1990, 0xb800, 0xd0bc, 0x0978, 0x0804, 0x61d6, 0x080c,
- 0x68b3, 0x0904, 0x61ef, 0x0804, 0x61da, 0x00b6, 0x00e6, 0x0126,
- 0x2091, 0x8000, 0xa874, 0x908e, 0x00ff, 0x1120, 0x2001, 0x196c,
- 0x205c, 0x0060, 0xa974, 0x9182, 0x0800, 0x1690, 0x9188, 0x1000,
- 0x2104, 0x905d, 0x01d0, 0x080c, 0x6a2c, 0x11d0, 0x080c, 0xb091,
- 0x0570, 0x2b00, 0x6012, 0x2900, 0x6016, 0x6023, 0x0009, 0x600b,
- 0x0000, 0xa874, 0x908e, 0x00ff, 0x1110, 0x600b, 0x8000, 0x2009,
- 0x0043, 0x080c, 0xb166, 0x9006, 0x00b0, 0x2001, 0x0028, 0x0090,
- 0x2009, 0x180c, 0x210c, 0xd18c, 0x0118, 0x2001, 0x0004, 0x0038,
- 0xd184, 0x0118, 0x2001, 0x0004, 0x0010, 0x2001, 0x0029, 0x0010,
- 0x2001, 0x0029, 0x9005, 0x012e, 0x00ee, 0x00be, 0x0005, 0x2001,
- 0x002c, 0x0cc0, 0x00b6, 0x00e6, 0x0126, 0x2091, 0x8000, 0xa974,
- 0x9182, 0x0800, 0x1a04, 0x6310, 0x9188, 0x1000, 0x2104, 0x905d,
- 0x0904, 0x62e8, 0xb8a0, 0x9086, 0x007f, 0x0190, 0xa87c, 0xd0fc,
- 0x1178, 0x080c, 0x6a94, 0x0160, 0xa994, 0x81ff, 0x0130, 0x908e,
- 0x0004, 0x0130, 0x908e, 0x0005, 0x0118, 0x080c, 0x6a8c, 0x1598,
- 0xa87c, 0xd0fc, 0x01e0, 0xa894, 0x9005, 0x01c8, 0x2060, 0x0026,
- 0x2010, 0x080c, 0xce2d, 0x002e, 0x1120, 0x2001, 0x0008, 0x0804,
- 0x6312, 0x6020, 0x9086, 0x000a, 0x0120, 0x2001, 0x0008, 0x0804,
- 0x6312, 0x601a, 0x6003, 0x0008, 0x2900, 0x6016, 0x0058, 0x080c,
- 0xb091, 0x05e8, 0x2b00, 0x6012, 0x2900, 0x6016, 0x600b, 0xffff,
- 0x6023, 0x000a, 0x2009, 0x0003, 0x080c, 0xb166, 0x9006, 0x0458,
- 0x2001, 0x0028, 0x0438, 0x9082, 0x0006, 0x1290, 0x080c, 0xb051,
- 0x1160, 0xb8a0, 0x9084, 0xff80, 0x1140, 0xb900, 0xd1fc, 0x0900,
- 0x2001, 0x0029, 0x2009, 0x1000, 0x00a8, 0x2001, 0x0028, 0x0090,
- 0x2009, 0x180c, 0x210c, 0xd18c, 0x0118, 0x2001, 0x0004, 0x0050,
- 0xd184, 0x0118, 0x2001, 0x0004, 0x0028, 0x2001, 0x0029, 0x0010,
- 0x2001, 0x0029, 0x9005, 0x012e, 0x00ee, 0x00be, 0x0005, 0x2001,
- 0x002c, 0x0cc0, 0x00f6, 0x00b6, 0x0126, 0x2091, 0x8000, 0xa8e0,
- 0x9005, 0x1550, 0xa8dc, 0x9082, 0x0101, 0x1630, 0xa8c8, 0x9005,
- 0x1518, 0xa8c4, 0x9082, 0x0101, 0x12f8, 0xa974, 0x2079, 0x1800,
- 0x9182, 0x0800, 0x12e8, 0x7830, 0x9084, 0x0003, 0x1130, 0xaa98,
- 0xab94, 0xa878, 0x9084, 0x0007, 0x00ea, 0x7930, 0xd18c, 0x0118,
- 0x2001, 0x0004, 0x0038, 0xd184, 0x0118, 0x2001, 0x0004, 0x0010,
- 0x2001, 0x0029, 0x900e, 0x0038, 0x2001, 0x002c, 0x900e, 0x0018,
- 0x2001, 0x0029, 0x900e, 0x9006, 0x0008, 0x9005, 0x012e, 0x00be,
- 0x00fe, 0x0005, 0x63a7, 0x6362, 0x6379, 0x63a7, 0x63a7, 0x63a7,
- 0x63a7, 0x63a7, 0x2100, 0x9082, 0x007e, 0x1278, 0x080c, 0x66ac,
- 0x0148, 0x9046, 0xb810, 0x9306, 0x1904, 0x63af, 0xb814, 0x9206,
- 0x15f0, 0x0028, 0xbb12, 0xba16, 0x0010, 0x080c, 0x4a96, 0x0150,
- 0x04b0, 0x080c, 0x6717, 0x1598, 0xb810, 0x9306, 0x1580, 0xb814,
- 0x9206, 0x1568, 0x080c, 0xb091, 0x0530, 0x2b00, 0x6012, 0x080c,
- 0xd2bb, 0x2900, 0x6016, 0x600b, 0xffff, 0x6023, 0x000a, 0xa878,
- 0x9086, 0x0001, 0x1170, 0x080c, 0x324b, 0x9006, 0x080c, 0x6649,
- 0x2001, 0x0002, 0x080c, 0x665d, 0x2001, 0x0200, 0xb86e, 0xb893,
- 0x0002, 0x2009, 0x0003, 0x080c, 0xb166, 0x9006, 0x0068, 0x2001,
- 0x0001, 0x900e, 0x0038, 0x2001, 0x002c, 0x900e, 0x0018, 0x2001,
- 0x0028, 0x900e, 0x9005, 0x0000, 0x012e, 0x00be, 0x00fe, 0x0005,
- 0x00b6, 0x00f6, 0x00e6, 0x0126, 0x2091, 0x8000, 0xa894, 0x90c6,
- 0x0015, 0x0904, 0x659a, 0x90c6, 0x0056, 0x0904, 0x659e, 0x90c6,
- 0x0066, 0x0904, 0x65a2, 0x90c6, 0x0067, 0x0904, 0x65a6, 0x90c6,
- 0x0068, 0x0904, 0x65aa, 0x90c6, 0x0071, 0x0904, 0x65ae, 0x90c6,
- 0x0074, 0x0904, 0x65b2, 0x90c6, 0x007c, 0x0904, 0x65b6, 0x90c6,
- 0x007e, 0x0904, 0x65ba, 0x90c6, 0x0037, 0x0904, 0x65be, 0x9016,
- 0x2079, 0x1800, 0xa974, 0x9186, 0x00ff, 0x0904, 0x6595, 0x9182,
- 0x0800, 0x1a04, 0x6595, 0x080c, 0x6717, 0x1198, 0xb804, 0x9084,
- 0x00ff, 0x9082, 0x0006, 0x1268, 0xa894, 0x90c6, 0x006f, 0x0148,
- 0x080c, 0xb051, 0x1904, 0x657e, 0xb8a0, 0x9084, 0xff80, 0x1904,
- 0x657e, 0xa894, 0x90c6, 0x006f, 0x0158, 0x90c6, 0x005e, 0x0904,
- 0x64de, 0x90c6, 0x0064, 0x0904, 0x6507, 0x2008, 0x0804, 0x64a0,
- 0xa998, 0xa8b0, 0x2040, 0x080c, 0xb051, 0x1120, 0x9182, 0x007f,
- 0x0a04, 0x64a0, 0x9186, 0x00ff, 0x0904, 0x64a0, 0x9182, 0x0800,
- 0x1a04, 0x64a0, 0xaaa0, 0xab9c, 0x787c, 0x9306, 0x11a8, 0x7880,
- 0x0096, 0x924e, 0x1128, 0x2208, 0x2310, 0x009e, 0x0804, 0x64a0,
- 0x080c, 0xb051, 0x1140, 0x99cc, 0xff00, 0x009e, 0x1128, 0x2208,
- 0x2310, 0x0804, 0x64a0, 0x009e, 0x080c, 0x4a96, 0x0904, 0x64aa,
- 0x900e, 0x9016, 0x90c6, 0x4000, 0x15e0, 0x0006, 0x080c, 0x6937,
- 0x1108, 0xc185, 0xb800, 0xd0bc, 0x0108, 0xc18d, 0x20a9, 0x0004,
- 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0031, 0x20a0, 0xb8c4, 0x20e0,
- 0xb8c8, 0x9080, 0x0006, 0x2098, 0x080c, 0x0f8b, 0x20a9, 0x0004,
- 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0035, 0x20a0, 0xb8c4, 0x20e0,
- 0xb8c8, 0x9080, 0x000a, 0x2098, 0x080c, 0x0f8b, 0xa8c4, 0xabc8,
- 0x9305, 0xabcc, 0x9305, 0xabd0, 0x9305, 0xabd4, 0x9305, 0xabd8,
- 0x9305, 0xabdc, 0x9305, 0xabe0, 0x9305, 0x9005, 0x0510, 0x000e,
- 0x00c8, 0x90c6, 0x4007, 0x1110, 0x2408, 0x00a0, 0x90c6, 0x4008,
- 0x1118, 0x2708, 0x2610, 0x0070, 0x90c6, 0x4009, 0x1108, 0x0050,
- 0x90c6, 0x4006, 0x0138, 0x2001, 0x4005, 0x2009, 0x000a, 0x0010,
- 0x2001, 0x4006, 0xa896, 0xa99a, 0xaa9e, 0x2001, 0x0030, 0x900e,
- 0x0478, 0x000e, 0x080c, 0xb091, 0x1130, 0x2001, 0x4005, 0x2009,
- 0x0003, 0x9016, 0x0c78, 0x2b00, 0x6012, 0x080c, 0xd2bb, 0x2900,
- 0x6016, 0x6023, 0x0001, 0xa868, 0xd88c, 0x0108, 0xc0f5, 0xa86a,
- 0x0126, 0x2091, 0x8000, 0x080c, 0x324b, 0x012e, 0x9006, 0x080c,
- 0x6649, 0x2001, 0x0002, 0x080c, 0x665d, 0x2009, 0x0002, 0x080c,
- 0xb166, 0xa8b0, 0xd094, 0x0118, 0xb8cc, 0xc08d, 0xb8ce, 0x9006,
- 0x9005, 0x012e, 0x00ee, 0x00fe, 0x00be, 0x0005, 0x080c, 0x57e1,
- 0x0118, 0x2009, 0x0007, 0x00f8, 0xa998, 0xaeb0, 0x080c, 0x6717,
- 0x1904, 0x649b, 0x9186, 0x007f, 0x0130, 0x080c, 0x6a8c, 0x0118,
- 0x2009, 0x0009, 0x0080, 0x0096, 0x080c, 0x100e, 0x1120, 0x009e,
- 0x2009, 0x0002, 0x0040, 0x2900, 0x009e, 0xa806, 0x080c, 0xd027,
- 0x19b0, 0x2009, 0x0003, 0x2001, 0x4005, 0x0804, 0x64a2, 0xa998,
- 0xaeb0, 0x080c, 0x6717, 0x1904, 0x649b, 0x0096, 0x080c, 0x100e,
- 0x1128, 0x009e, 0x2009, 0x0002, 0x0804, 0x655b, 0x2900, 0x009e,
- 0xa806, 0x0096, 0x2048, 0x20a9, 0x002b, 0xb8c4, 0x20e0, 0xb8c8,
- 0x2098, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0002, 0x20a0, 0x4003,
- 0x20a9, 0x0008, 0x9080, 0x0006, 0x20a0, 0xbbc8, 0x9398, 0x0006,
- 0x2398, 0x080c, 0x0f8b, 0x009e, 0xa87b, 0x0000, 0xa883, 0x0000,
- 0xa897, 0x4000, 0xd684, 0x1168, 0x080c, 0x57cd, 0xd0b4, 0x1118,
- 0xa89b, 0x000b, 0x00e0, 0xb800, 0xd08c, 0x0118, 0xa89b, 0x000c,
- 0x00b0, 0x080c, 0x6a8c, 0x0118, 0xa89b, 0x0009, 0x0080, 0x080c,
- 0x57e1, 0x0118, 0xa89b, 0x0007, 0x0050, 0x080c, 0xd00a, 0x1904,
- 0x64d7, 0x2009, 0x0003, 0x2001, 0x4005, 0x0804, 0x64a2, 0xa87b,
- 0x0030, 0xa897, 0x4005, 0xa804, 0x8006, 0x8006, 0x8007, 0x90bc,
- 0x003f, 0x9084, 0xffc0, 0x9080, 0x0002, 0x2009, 0x002b, 0xaaa0,
- 0xab9c, 0xaca8, 0xada4, 0x2031, 0x0000, 0x2041, 0x1252, 0x080c,
- 0xb608, 0x1904, 0x64d7, 0x2009, 0x0002, 0x08e8, 0x2001, 0x0028,
- 0x900e, 0x0804, 0x64d8, 0x2009, 0x180c, 0x210c, 0xd18c, 0x0118,
- 0x2001, 0x0004, 0x0038, 0xd184, 0x0118, 0x2001, 0x0004, 0x0010,
- 0x2001, 0x0029, 0x900e, 0x0804, 0x64d8, 0x2001, 0x0029, 0x900e,
- 0x0804, 0x64d8, 0x080c, 0x37e2, 0x0804, 0x64d9, 0x080c, 0x54f8,
- 0x0804, 0x64d9, 0x080c, 0x4606, 0x0804, 0x64d9, 0x080c, 0x467f,
- 0x0804, 0x64d9, 0x080c, 0x46db, 0x0804, 0x64d9, 0x080c, 0x4b59,
- 0x0804, 0x64d9, 0x080c, 0x4e0d, 0x0804, 0x64d9, 0x080c, 0x515f,
- 0x0804, 0x64d9, 0x080c, 0x5358, 0x0804, 0x64d9, 0x080c, 0x3a0c,
- 0x0804, 0x64d9, 0x00b6, 0xa974, 0xae78, 0x9684, 0x3fff, 0x9082,
- 0x4000, 0x1618, 0x9182, 0x0800, 0x1268, 0x9188, 0x1000, 0x2104,
- 0x905d, 0x0140, 0x080c, 0x6a8c, 0x1148, 0x00e9, 0x080c, 0x6842,
- 0x9006, 0x00b0, 0x2001, 0x0028, 0x900e, 0x0090, 0x9082, 0x0006,
- 0x1240, 0xb900, 0xd1fc, 0x0d88, 0x2001, 0x0029, 0x2009, 0x1000,
+ 0x60c3, 0x0014, 0x080c, 0x5fba, 0x00fe, 0x0005, 0x00f6, 0x7090,
+ 0x9005, 0x0500, 0x2011, 0x5f90, 0x080c, 0x8709, 0x9086, 0x0014,
+ 0x11b8, 0x080c, 0x6101, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1104,
+ 0x1178, 0x7834, 0x9005, 0x1160, 0x7a38, 0xd2fc, 0x0128, 0x70c4,
+ 0x9005, 0x1110, 0x70c7, 0x0001, 0x709b, 0x0014, 0x0029, 0x0010,
+ 0x7093, 0x0000, 0x00fe, 0x0005, 0x00f6, 0x709b, 0x0015, 0x080c,
+ 0x6093, 0x2079, 0x0240, 0x7833, 0x1104, 0x7837, 0x0000, 0x080c,
+ 0x6101, 0x080c, 0x60e4, 0x11b8, 0x7084, 0x9005, 0x11a0, 0x7164,
+ 0x9186, 0xffff, 0x0180, 0x9180, 0x33ac, 0x200d, 0x918c, 0xff00,
+ 0x810f, 0x2011, 0x0008, 0x080c, 0x5f3d, 0x0180, 0x080c, 0x50cf,
+ 0x0110, 0x080c, 0x28fd, 0x20a9, 0x0008, 0x20e1, 0x0000, 0x2099,
+ 0x026e, 0x20e9, 0x0000, 0x20a1, 0x024e, 0x4003, 0x60c3, 0x0014,
+ 0x080c, 0x5fba, 0x00fe, 0x0005, 0x00f6, 0x7090, 0x9005, 0x05f0,
+ 0x2011, 0x5f90, 0x080c, 0x8709, 0x9086, 0x0014, 0x15a8, 0x080c,
+ 0x6101, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1105, 0x1568, 0x7834,
+ 0x9084, 0x0100, 0x2011, 0x0100, 0x921e, 0x1168, 0x9085, 0x0001,
+ 0x080c, 0x612c, 0x7a38, 0xd2fc, 0x0128, 0x70c4, 0x9005, 0x1110,
+ 0x70c7, 0x0001, 0x0080, 0x9005, 0x11b8, 0x7a38, 0xd2fc, 0x0128,
+ 0x70c4, 0x9005, 0x1110, 0x70c7, 0x0001, 0x9085, 0x0001, 0x080c,
+ 0x612c, 0x7097, 0x0000, 0x7a38, 0xd2f4, 0x0110, 0x70df, 0x0008,
+ 0x709b, 0x0016, 0x0029, 0x0010, 0x7093, 0x0000, 0x00fe, 0x0005,
+ 0x080c, 0xadbc, 0x080c, 0x6101, 0x20e1, 0x0000, 0x2099, 0x0260,
+ 0x20e9, 0x0000, 0x20a1, 0x0240, 0x20a9, 0x000e, 0x4003, 0x2011,
+ 0x026d, 0x2204, 0x9084, 0x0100, 0x2011, 0x024d, 0x2012, 0x2011,
+ 0x026e, 0x709b, 0x0017, 0x080c, 0x60e4, 0x1150, 0x7084, 0x9005,
+ 0x1138, 0x080c, 0x5eb0, 0x1188, 0x9085, 0x0001, 0x080c, 0x28fd,
+ 0x20a9, 0x0008, 0x080c, 0x6101, 0x20e1, 0x0000, 0x2099, 0x026e,
+ 0x20e9, 0x0000, 0x20a1, 0x024e, 0x4003, 0x60c3, 0x0014, 0x080c,
+ 0x5fba, 0x0010, 0x080c, 0x5a0a, 0x0005, 0x00f6, 0x7090, 0x9005,
+ 0x01d8, 0x2011, 0x5f90, 0x080c, 0x8709, 0x9086, 0x0084, 0x1190,
+ 0x080c, 0x6101, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1106, 0x1150,
+ 0x7834, 0x9005, 0x1138, 0x9006, 0x080c, 0x612c, 0x709b, 0x0018,
+ 0x0029, 0x0010, 0x7093, 0x0000, 0x00fe, 0x0005, 0x00f6, 0x709b,
+ 0x0019, 0x080c, 0x6093, 0x2079, 0x0240, 0x7833, 0x1106, 0x7837,
+ 0x0000, 0x080c, 0x6101, 0x2009, 0x026e, 0x2039, 0x1c0e, 0x20a9,
+ 0x0040, 0x213e, 0x8738, 0x8108, 0x9186, 0x0280, 0x1128, 0x6814,
+ 0x8000, 0x6816, 0x2009, 0x0260, 0x1f04, 0x5e19, 0x2039, 0x1c0e,
+ 0x080c, 0x60e4, 0x11e8, 0x2728, 0x2514, 0x8207, 0x9084, 0x00ff,
+ 0x8000, 0x2018, 0x9294, 0x00ff, 0x8007, 0x9205, 0x202a, 0x7060,
+ 0x2310, 0x8214, 0x92a0, 0x1c0e, 0x2414, 0x938c, 0x0001, 0x0118,
+ 0x9294, 0xff00, 0x0018, 0x9294, 0x00ff, 0x8007, 0x9215, 0x2222,
+ 0x20a9, 0x0040, 0x2009, 0x024e, 0x270e, 0x8738, 0x8108, 0x9186,
+ 0x0260, 0x1128, 0x6810, 0x8000, 0x6812, 0x2009, 0x0240, 0x1f04,
+ 0x5e4c, 0x60c3, 0x0084, 0x080c, 0x5fba, 0x00fe, 0x0005, 0x00f6,
+ 0x7090, 0x9005, 0x01e0, 0x2011, 0x5f90, 0x080c, 0x8709, 0x9086,
+ 0x0084, 0x1198, 0x080c, 0x6101, 0x2079, 0x0260, 0x7a30, 0x9296,
+ 0x1107, 0x1158, 0x7834, 0x9005, 0x1140, 0x7097, 0x0001, 0x080c,
+ 0x6057, 0x709b, 0x001a, 0x0029, 0x0010, 0x7093, 0x0000, 0x00fe,
+ 0x0005, 0x9085, 0x0001, 0x080c, 0x612c, 0x709b, 0x001b, 0x080c,
+ 0xadbc, 0x080c, 0x6101, 0x2011, 0x0260, 0x2009, 0x0240, 0x7490,
+ 0x9480, 0x0018, 0x9080, 0x0007, 0x9084, 0x03f8, 0x8004, 0x20a8,
+ 0x220e, 0x8210, 0x8108, 0x9186, 0x0260, 0x1150, 0x6810, 0x8000,
+ 0x6812, 0x2009, 0x0240, 0x6814, 0x8000, 0x6816, 0x2011, 0x0260,
+ 0x1f04, 0x5e98, 0x60c3, 0x0084, 0x080c, 0x5fba, 0x0005, 0x0005,
+ 0x0086, 0x0096, 0x2029, 0x1848, 0x252c, 0x20a9, 0x0008, 0x2041,
+ 0x1c0e, 0x20e9, 0x0001, 0x28a0, 0x080c, 0x6101, 0x20e1, 0x0000,
+ 0x2099, 0x026e, 0x4003, 0x20a9, 0x0008, 0x2011, 0x0007, 0xd5d4,
+ 0x0108, 0x9016, 0x2800, 0x9200, 0x200c, 0x91a6, 0xffff, 0x1148,
+ 0xd5d4, 0x0110, 0x8210, 0x0008, 0x8211, 0x1f04, 0x5eca, 0x0804,
+ 0x5f39, 0x82ff, 0x1160, 0xd5d4, 0x0120, 0x91a6, 0x3fff, 0x0d90,
+ 0x0020, 0x91a6, 0x3fff, 0x0904, 0x5f39, 0x918d, 0xc000, 0x20a9,
+ 0x0010, 0x2019, 0x0001, 0xd5d4, 0x0110, 0x2019, 0x0010, 0x2120,
+ 0xd5d4, 0x0110, 0x8423, 0x0008, 0x8424, 0x1240, 0xd5d4, 0x0110,
+ 0x8319, 0x0008, 0x8318, 0x1f04, 0x5ef0, 0x04d8, 0x23a8, 0x2021,
+ 0x0001, 0x8426, 0x8425, 0x1f04, 0x5f02, 0x2328, 0x8529, 0x92be,
+ 0x0007, 0x0158, 0x0006, 0x2039, 0x0007, 0x2200, 0x973a, 0x000e,
+ 0x27a8, 0x95a8, 0x0010, 0x1f04, 0x5f11, 0x755e, 0x95c8, 0x33ac,
+ 0x292d, 0x95ac, 0x00ff, 0x7582, 0x6532, 0x6536, 0x0016, 0x2508,
+ 0x080c, 0x28dd, 0x001e, 0x60e7, 0x0000, 0x65ea, 0x2018, 0x2304,
+ 0x9405, 0x201a, 0x7087, 0x0001, 0x20e9, 0x0000, 0x20a1, 0x024e,
+ 0x20e1, 0x0001, 0x2898, 0x20a9, 0x0008, 0x4003, 0x9085, 0x0001,
+ 0x0008, 0x9006, 0x009e, 0x008e, 0x0005, 0x0156, 0x01c6, 0x01d6,
+ 0x0136, 0x0146, 0x22a8, 0x20e1, 0x0000, 0x2099, 0x026e, 0x20e9,
+ 0x0000, 0x2011, 0x024e, 0x22a0, 0x4003, 0x014e, 0x013e, 0x01de,
+ 0x01ce, 0x015e, 0x2118, 0x9026, 0x2001, 0x0007, 0x939a, 0x0010,
+ 0x0218, 0x8420, 0x8001, 0x0cd0, 0x2118, 0x84ff, 0x0120, 0x939a,
+ 0x0010, 0x8421, 0x1de0, 0x2021, 0x0001, 0x83ff, 0x0118, 0x8423,
+ 0x8319, 0x1de8, 0x9238, 0x2029, 0x026e, 0x9528, 0x2504, 0x942c,
+ 0x11b8, 0x9405, 0x203a, 0x715e, 0x91a0, 0x33ac, 0x242d, 0x95ac,
+ 0x00ff, 0x7582, 0x6532, 0x6536, 0x0016, 0x2508, 0x080c, 0x28dd,
+ 0x001e, 0x60e7, 0x0000, 0x65ea, 0x7087, 0x0001, 0x9084, 0x0000,
+ 0x0005, 0x00e6, 0x2071, 0x1800, 0x708b, 0x0000, 0x00ee, 0x0005,
+ 0x00e6, 0x00f6, 0x2079, 0x0100, 0x2071, 0x0140, 0x080c, 0x6046,
+ 0x080c, 0xa517, 0x7004, 0x9084, 0x4000, 0x0110, 0x080c, 0x2d62,
+ 0x0126, 0x2091, 0x8000, 0x2071, 0x1826, 0x2073, 0x0000, 0x7840,
+ 0x0026, 0x0016, 0x2009, 0x00f7, 0x080c, 0x60a3, 0x001e, 0x9094,
+ 0x0010, 0x9285, 0x0080, 0x7842, 0x7a42, 0x002e, 0x012e, 0x00fe,
+ 0x00ee, 0x0005, 0x0126, 0x2091, 0x8000, 0x080c, 0x2be7, 0x0228,
+ 0x2011, 0x0101, 0x2204, 0xc0c5, 0x2012, 0x2011, 0x19f3, 0x2013,
+ 0x0000, 0x7093, 0x0000, 0x012e, 0x60a3, 0x0056, 0x60a7, 0x9575,
+ 0x080c, 0xa50e, 0x6144, 0xd184, 0x0120, 0x7198, 0x918d, 0x2000,
+ 0x0018, 0x718c, 0x918d, 0x1000, 0x2011, 0x199a, 0x2112, 0x2009,
+ 0x07d0, 0x2011, 0x5f90, 0x080c, 0x87a1, 0x0005, 0x0016, 0x0026,
+ 0x00c6, 0x0126, 0x2091, 0x8000, 0x080c, 0xb072, 0x2009, 0x00f7,
+ 0x080c, 0x60a3, 0x2061, 0x19fc, 0x900e, 0x611a, 0x611e, 0x617a,
+ 0x617e, 0x2061, 0x1800, 0x6003, 0x0001, 0x2061, 0x0100, 0x6043,
+ 0x0090, 0x6043, 0x0010, 0x2009, 0x199a, 0x200b, 0x0000, 0x2009,
+ 0x002d, 0x2011, 0x6012, 0x080c, 0x86fd, 0x012e, 0x00ce, 0x002e,
+ 0x001e, 0x0005, 0x00e6, 0x0006, 0x0126, 0x2091, 0x8000, 0x0471,
+ 0x2071, 0x0100, 0x080c, 0xa517, 0x2071, 0x0140, 0x7004, 0x9084,
+ 0x4000, 0x0110, 0x080c, 0x2d62, 0x080c, 0x7571, 0x0188, 0x080c,
+ 0x758c, 0x1170, 0x080c, 0x7858, 0x0016, 0x080c, 0x29ac, 0x2001,
+ 0x196e, 0x2102, 0x001e, 0x080c, 0x7853, 0x080c, 0x7495, 0x0050,
+ 0x2009, 0x0001, 0x080c, 0x2c80, 0x2001, 0x0001, 0x080c, 0x283d,
+ 0x080c, 0x5fe6, 0x012e, 0x000e, 0x00ee, 0x0005, 0x2001, 0x180e,
+ 0x2004, 0xd0bc, 0x0158, 0x0026, 0x0036, 0x2011, 0x8017, 0x2001,
+ 0x199a, 0x201c, 0x080c, 0x4be9, 0x003e, 0x002e, 0x0005, 0x20a9,
+ 0x0012, 0x20e9, 0x0001, 0x20a1, 0x1c80, 0x080c, 0x6101, 0x20e9,
+ 0x0000, 0x2099, 0x026e, 0x0099, 0x20a9, 0x0020, 0x080c, 0x60fb,
+ 0x2099, 0x0260, 0x20a1, 0x1c92, 0x0051, 0x20a9, 0x000e, 0x080c,
+ 0x60fe, 0x2099, 0x0260, 0x20a1, 0x1cb2, 0x0009, 0x0005, 0x0016,
+ 0x0026, 0x3410, 0x3308, 0x2104, 0x8007, 0x2012, 0x8108, 0x8210,
+ 0x1f04, 0x607b, 0x002e, 0x001e, 0x0005, 0x080c, 0xadbc, 0x20e1,
+ 0x0001, 0x2099, 0x1c00, 0x20e9, 0x0000, 0x20a1, 0x0240, 0x20a9,
+ 0x000c, 0x4003, 0x0005, 0x080c, 0xadbc, 0x080c, 0x6101, 0x20e1,
+ 0x0000, 0x2099, 0x0260, 0x20e9, 0x0000, 0x20a1, 0x0240, 0x20a9,
+ 0x000c, 0x4003, 0x0005, 0x00c6, 0x0006, 0x2061, 0x0100, 0x810f,
+ 0x2001, 0x1834, 0x2004, 0x9005, 0x1138, 0x2001, 0x1818, 0x2004,
+ 0x9084, 0x00ff, 0x9105, 0x0010, 0x9185, 0x00f7, 0x604a, 0x000e,
+ 0x00ce, 0x0005, 0x0016, 0x0046, 0x080c, 0x6a8e, 0x0158, 0x9006,
+ 0x2020, 0x2009, 0x002a, 0x080c, 0xe9a5, 0x2001, 0x180c, 0x200c,
+ 0xc195, 0x2102, 0x2019, 0x002a, 0x900e, 0x080c, 0x3211, 0x080c,
+ 0xd561, 0x0140, 0x0036, 0x2019, 0xffff, 0x2021, 0x0007, 0x080c,
+ 0x4da0, 0x003e, 0x004e, 0x001e, 0x0005, 0x080c, 0x5fe6, 0x709b,
+ 0x0000, 0x7093, 0x0000, 0x0005, 0x0006, 0x2001, 0x180c, 0x2004,
+ 0xd09c, 0x0100, 0x000e, 0x0005, 0x0006, 0x0016, 0x0126, 0x2091,
+ 0x8000, 0x2001, 0x0101, 0x200c, 0x918d, 0x0006, 0x2102, 0x012e,
+ 0x001e, 0x000e, 0x0005, 0x2009, 0x0001, 0x0020, 0x2009, 0x0002,
+ 0x0008, 0x900e, 0x6814, 0x9084, 0xffc0, 0x910d, 0x6916, 0x0005,
+ 0x00f6, 0x0156, 0x0146, 0x01d6, 0x9006, 0x20a9, 0x0080, 0x20e9,
+ 0x0001, 0x20a1, 0x1c00, 0x4004, 0x2079, 0x1c00, 0x7803, 0x2200,
+ 0x7807, 0x00ef, 0x780f, 0x00ef, 0x7813, 0x0138, 0x7823, 0xffff,
+ 0x7827, 0xffff, 0x01de, 0x014e, 0x015e, 0x00fe, 0x0005, 0x2001,
+ 0x1800, 0x2003, 0x0001, 0x0005, 0x2001, 0x19a8, 0x0118, 0x2003,
+ 0x0001, 0x0010, 0x2003, 0x0000, 0x0005, 0x0156, 0x20a9, 0x0800,
+ 0x2009, 0x1000, 0x9006, 0x200a, 0x8108, 0x1f04, 0x613b, 0x015e,
+ 0x0005, 0x00d6, 0x0036, 0x0156, 0x0136, 0x0146, 0x2069, 0x1847,
+ 0x9006, 0xb802, 0xb8ce, 0xb807, 0x0707, 0xb80a, 0xb80e, 0xb812,
+ 0x9198, 0x33ac, 0x231d, 0x939c, 0x00ff, 0xbb16, 0x0016, 0x0026,
+ 0xb8c2, 0x080c, 0xb06b, 0x1120, 0x9192, 0x007e, 0x1208, 0xbbc2,
+ 0x20a9, 0x0004, 0xb8c4, 0x20e8, 0xb9c8, 0x9198, 0x0006, 0x9006,
+ 0x23a0, 0x4004, 0x20a9, 0x0004, 0x9198, 0x000a, 0x23a0, 0x4004,
+ 0x002e, 0x001e, 0xb83e, 0xb842, 0xb84e, 0xb852, 0xb856, 0xb85a,
+ 0xb85e, 0xb862, 0xb866, 0xb86a, 0xb86f, 0x0100, 0xb872, 0xb876,
+ 0xb87a, 0xb88a, 0xb88e, 0xb893, 0x0008, 0xb896, 0xb89a, 0xb89e,
+ 0xb8be, 0xb9a2, 0x0096, 0xb8a4, 0x904d, 0x0110, 0x080c, 0x1040,
+ 0xb8a7, 0x0000, 0x009e, 0x9006, 0xb84a, 0x6810, 0xb83a, 0x680c,
+ 0xb846, 0xb8bb, 0x0520, 0xb8ac, 0x9005, 0x0198, 0x00c6, 0x2060,
+ 0x9c82, 0x1cd0, 0x0a0c, 0x0dc5, 0x2001, 0x181a, 0x2004, 0x9c02,
+ 0x1a0c, 0x0dc5, 0x080c, 0x8bc3, 0x00ce, 0x090c, 0x8f64, 0xb8af,
+ 0x0000, 0x6814, 0x9084, 0x00ff, 0xb842, 0x014e, 0x013e, 0x015e,
+ 0x003e, 0x00de, 0x0005, 0x0126, 0x2091, 0x8000, 0xa974, 0xae78,
+ 0x9684, 0x3fff, 0x9082, 0x4000, 0x1a04, 0x6229, 0x9182, 0x0800,
+ 0x1a04, 0x622d, 0x2001, 0x180c, 0x2004, 0x9084, 0x0003, 0x1904,
+ 0x6233, 0x9188, 0x1000, 0x2104, 0x905d, 0x0518, 0xb804, 0x9084,
+ 0x00ff, 0x908e, 0x0006, 0x1508, 0xb8a4, 0x900d, 0x1904, 0x6245,
+ 0xb850, 0x900d, 0x1148, 0xa802, 0x2900, 0xb852, 0xb84e, 0x080c,
+ 0x9358, 0x9006, 0x012e, 0x0005, 0x00a6, 0x2150, 0x2900, 0xb002,
+ 0xa803, 0x0000, 0x00ae, 0xb852, 0x0c90, 0x2001, 0x0005, 0x900e,
+ 0x04b8, 0x2001, 0x0028, 0x900e, 0x0498, 0x9082, 0x0006, 0x1290,
+ 0x080c, 0xb06b, 0x1160, 0xb8a0, 0x9084, 0xff80, 0x1140, 0xb900,
+ 0xd1fc, 0x0990, 0x2001, 0x0029, 0x2009, 0x1000, 0x0408, 0x2001,
+ 0x0028, 0x00a8, 0x2009, 0x180c, 0x210c, 0xd18c, 0x0118, 0x2001,
+ 0x0004, 0x0068, 0xd184, 0x0118, 0x2001, 0x0004, 0x0040, 0x2001,
+ 0x0029, 0xb900, 0xd1fc, 0x0118, 0x2009, 0x1000, 0x0048, 0x900e,
0x0038, 0x2001, 0x0029, 0x900e, 0x0018, 0x2001, 0x0029, 0x900e,
- 0x9005, 0x00be, 0x0005, 0x0126, 0x2091, 0x8000, 0xb850, 0x900d,
- 0x0150, 0x2900, 0x0096, 0x2148, 0xa802, 0x009e, 0xa803, 0x0000,
- 0xb852, 0x012e, 0x0005, 0x2900, 0xb852, 0xb84e, 0xa803, 0x0000,
- 0x0cc0, 0x0126, 0x2091, 0x8000, 0xb84c, 0x9005, 0x0170, 0x00e6,
- 0x2071, 0x19e9, 0x7004, 0x9086, 0x0002, 0x0168, 0x00ee, 0xb84c,
- 0xa802, 0x2900, 0xb84e, 0x012e, 0x0005, 0x2900, 0xb852, 0xb84e,
- 0xa803, 0x0000, 0x0cc0, 0x701c, 0x9b06, 0x1d80, 0xb84c, 0x00a6,
- 0x2050, 0xb000, 0xa802, 0x2900, 0xb002, 0x00ae, 0x00ee, 0x012e,
- 0x0005, 0x0126, 0x2091, 0x8000, 0xb84c, 0x904d, 0x0130, 0xa800,
- 0x9005, 0x1108, 0xb852, 0xb84e, 0x9905, 0x012e, 0x0005, 0xb84c,
- 0x904d, 0x0130, 0xa800, 0x9005, 0x1108, 0xb852, 0xb84e, 0x9905,
- 0x0005, 0x00b6, 0x0126, 0x00c6, 0x0026, 0x2091, 0x8000, 0x6210,
- 0x2258, 0xba00, 0x9005, 0x0110, 0xc285, 0x0008, 0xc284, 0xba02,
- 0x002e, 0x00ce, 0x012e, 0x00be, 0x0005, 0x00b6, 0x0126, 0x00c6,
- 0x2091, 0x8000, 0x6210, 0x2258, 0xba04, 0x0006, 0x9086, 0x0006,
- 0x1170, 0xb89c, 0xd0ac, 0x0158, 0x080c, 0x6a88, 0x0140, 0x9284,
- 0xff00, 0x8007, 0x9086, 0x0007, 0x1110, 0x2011, 0x0600, 0x000e,
- 0x9294, 0xff00, 0x9215, 0xba06, 0x0006, 0x9086, 0x0006, 0x1120,
- 0xba90, 0x82ff, 0x090c, 0x0dc5, 0x000e, 0x00ce, 0x012e, 0x00be,
- 0x0005, 0x00b6, 0x0126, 0x00c6, 0x2091, 0x8000, 0x6210, 0x2258,
- 0xba04, 0x0006, 0x9086, 0x0006, 0x1168, 0xb89c, 0xd0a4, 0x0150,
- 0x080c, 0x6a84, 0x1138, 0x9284, 0x00ff, 0x9086, 0x0007, 0x1110,
- 0x2011, 0x0006, 0x000e, 0x9294, 0x00ff, 0x8007, 0x9215, 0xba06,
- 0x00ce, 0x012e, 0x00be, 0x0005, 0x9182, 0x0800, 0x0218, 0x9085,
- 0x0001, 0x0005, 0x00d6, 0x0026, 0x9190, 0x1000, 0x2204, 0x905d,
- 0x1188, 0x0096, 0x080c, 0x100e, 0x2958, 0x009e, 0x0168, 0x2b00,
- 0x2012, 0xb85c, 0xb8ca, 0xb860, 0xb8c6, 0x9006, 0xb8a6, 0xb8ae,
- 0x080c, 0x613b, 0x9006, 0x0010, 0x9085, 0x0001, 0x002e, 0x00de,
- 0x0005, 0x00b6, 0x0096, 0x0126, 0x2091, 0x8000, 0x0026, 0x9182,
- 0x0800, 0x0218, 0x9085, 0x0001, 0x04a8, 0x00d6, 0x9190, 0x1000,
- 0x2204, 0x905d, 0x0568, 0x2013, 0x0000, 0xb8a4, 0x904d, 0x0110,
- 0x080c, 0x1040, 0x00d6, 0x00c6, 0xb8bc, 0x2060, 0x8cff, 0x0168,
- 0x600c, 0x0006, 0x6014, 0x2048, 0x080c, 0xce3f, 0x0110, 0x080c,
- 0x0fc0, 0x080c, 0xb0e7, 0x00ce, 0x0c88, 0x00ce, 0x00de, 0x00c6,
- 0xb8ac, 0x9065, 0x0128, 0x621c, 0xd2c4, 0x0110, 0x080c, 0x8f5e,
- 0x00ce, 0x2b48, 0xb8c8, 0xb85e, 0xb8c4, 0xb862, 0x080c, 0x1050,
- 0x00de, 0x9006, 0x002e, 0x012e, 0x009e, 0x00be, 0x0005, 0x0016,
- 0x9182, 0x0800, 0x0218, 0x9085, 0x0001, 0x0030, 0x9188, 0x1000,
- 0x2104, 0x905d, 0x0dc0, 0x9006, 0x001e, 0x0005, 0x00d6, 0x0156,
- 0x0136, 0x0146, 0x9006, 0xb80a, 0xb80e, 0xb800, 0xc08c, 0xb802,
- 0x080c, 0x7563, 0x1510, 0xb8a0, 0x9086, 0x007e, 0x0120, 0x080c,
- 0xb051, 0x11d8, 0x0078, 0x7040, 0xd0e4, 0x01b8, 0x00c6, 0x2061,
- 0x1983, 0x7048, 0x2062, 0x704c, 0x6006, 0x7050, 0x600a, 0x7054,
- 0x600e, 0x00ce, 0x703c, 0x2069, 0x0140, 0x9005, 0x1110, 0x2001,
- 0x0001, 0x6886, 0x2069, 0x1800, 0x68b6, 0x7040, 0xb85e, 0x7048,
- 0xb862, 0x704c, 0xb866, 0x20e1, 0x0000, 0x2099, 0x0276, 0xb8c4,
- 0x20e8, 0xb8c8, 0x9088, 0x000a, 0x21a0, 0x20a9, 0x0004, 0x4003,
- 0x2099, 0x027a, 0x9088, 0x0006, 0x21a0, 0x20a9, 0x0004, 0x4003,
- 0x2069, 0x0200, 0x6817, 0x0001, 0x7040, 0xb86a, 0x7144, 0xb96e,
- 0x7048, 0xb872, 0x7050, 0xb876, 0x2069, 0x0200, 0x6817, 0x0000,
- 0xb8a0, 0x9086, 0x007e, 0x1110, 0x7144, 0xb96e, 0x9182, 0x0211,
- 0x1218, 0x2009, 0x0008, 0x0400, 0x9182, 0x0259, 0x1218, 0x2009,
- 0x0007, 0x00d0, 0x9182, 0x02c1, 0x1218, 0x2009, 0x0006, 0x00a0,
- 0x9182, 0x0349, 0x1218, 0x2009, 0x0005, 0x0070, 0x9182, 0x0421,
- 0x1218, 0x2009, 0x0004, 0x0040, 0x9182, 0x0581, 0x1218, 0x2009,
- 0x0003, 0x0010, 0x2009, 0x0002, 0xb992, 0x014e, 0x013e, 0x015e,
- 0x00de, 0x0005, 0x0016, 0x0026, 0x00e6, 0x2071, 0x0260, 0x7034,
- 0xb896, 0x703c, 0xb89a, 0x7054, 0xb89e, 0x0036, 0xbbcc, 0xc384,
- 0xba00, 0x2009, 0x1867, 0x210c, 0xd0bc, 0x0120, 0xd1ec, 0x0110,
- 0xc2ad, 0x0008, 0xc2ac, 0xd0c4, 0x0148, 0xd1e4, 0x0138, 0xc2bd,
- 0xd0cc, 0x0128, 0xd38c, 0x1108, 0xc385, 0x0008, 0xc2bc, 0xba02,
- 0xbbce, 0x003e, 0x00ee, 0x002e, 0x001e, 0x0005, 0x0096, 0x0126,
- 0x2091, 0x8000, 0xb8a4, 0x904d, 0x0578, 0xa900, 0x81ff, 0x15c0,
- 0xaa04, 0x9282, 0x0010, 0x16c8, 0x0136, 0x0146, 0x01c6, 0x01d6,
- 0x8906, 0x8006, 0x8007, 0x908c, 0x003f, 0x21e0, 0x9084, 0xffc0,
- 0x9080, 0x0004, 0x2098, 0x2009, 0x0010, 0x20a9, 0x0001, 0x4002,
- 0x9086, 0xffff, 0x0120, 0x8109, 0x1dd0, 0x080c, 0x0dc5, 0x3c00,
- 0x20e8, 0x3300, 0x8001, 0x20a0, 0x4604, 0x8210, 0xaa06, 0x01de,
- 0x01ce, 0x014e, 0x013e, 0x0060, 0x080c, 0x100e, 0x0170, 0x2900,
- 0xb8a6, 0xa803, 0x0000, 0x080c, 0x68d3, 0xa807, 0x0001, 0xae12,
- 0x9085, 0x0001, 0x012e, 0x009e, 0x0005, 0x9006, 0x0cd8, 0x0126,
- 0x2091, 0x8000, 0x0096, 0xb8a4, 0x904d, 0x0188, 0xa800, 0x9005,
- 0x1150, 0x080c, 0x68e2, 0x1158, 0xa804, 0x908a, 0x0002, 0x0218,
- 0x8001, 0xa806, 0x0020, 0x080c, 0x1040, 0xb8a7, 0x0000, 0x009e,
- 0x012e, 0x0005, 0x0126, 0x2091, 0x8000, 0x080c, 0x9352, 0x012e,
- 0x0005, 0x901e, 0x0010, 0x2019, 0x0001, 0x900e, 0x0126, 0x2091,
- 0x8000, 0xb84c, 0x2048, 0xb800, 0xd0dc, 0x1170, 0x89ff, 0x0500,
- 0x83ff, 0x0120, 0xa878, 0x9606, 0x0158, 0x0030, 0xa86c, 0x9406,
- 0x1118, 0xa870, 0x9506, 0x0120, 0x2908, 0xa800, 0x2048, 0x0c70,
- 0x080c, 0xa905, 0xaa00, 0xb84c, 0x9906, 0x1110, 0xba4e, 0x0020,
- 0x00a6, 0x2150, 0xb202, 0x00ae, 0x82ff, 0x1110, 0xb952, 0x89ff,
- 0x012e, 0x0005, 0x9016, 0x0489, 0x1110, 0x2011, 0x0001, 0x0005,
- 0x080c, 0x6937, 0x0128, 0x080c, 0xcefc, 0x0010, 0x9085, 0x0001,
- 0x0005, 0x080c, 0x6937, 0x0128, 0x080c, 0xcea1, 0x0010, 0x9085,
- 0x0001, 0x0005, 0x080c, 0x6937, 0x0128, 0x080c, 0xcef9, 0x0010,
- 0x9085, 0x0001, 0x0005, 0x080c, 0x6937, 0x0128, 0x080c, 0xcec0,
- 0x0010, 0x9085, 0x0001, 0x0005, 0x080c, 0x6937, 0x0128, 0x080c,
- 0xcf3f, 0x0010, 0x9085, 0x0001, 0x0005, 0xb8a4, 0x900d, 0x1118,
- 0x9085, 0x0001, 0x0005, 0x0136, 0x01c6, 0xa800, 0x9005, 0x11b8,
- 0x890e, 0x810e, 0x810f, 0x9184, 0x003f, 0x20e0, 0x9184, 0xffc0,
- 0x9080, 0x0004, 0x2098, 0x20a9, 0x0001, 0x2009, 0x0010, 0x4002,
- 0x9606, 0x0128, 0x8109, 0x1dd8, 0x9085, 0x0001, 0x0008, 0x9006,
- 0x01ce, 0x013e, 0x0005, 0x0146, 0x01d6, 0xa860, 0x20e8, 0xa85c,
- 0x9080, 0x0004, 0x20a0, 0x20a9, 0x0010, 0x2009, 0xffff, 0x4104,
- 0x01de, 0x014e, 0x0136, 0x01c6, 0xa800, 0x9005, 0x11b8, 0x890e,
- 0x810e, 0x810f, 0x9184, 0x003f, 0x20e0, 0x9184, 0xffc0, 0x9080,
- 0x0004, 0x2098, 0x20a9, 0x0001, 0x2009, 0x0010, 0x4002, 0x9606,
- 0x0128, 0x8109, 0x1dd8, 0x9085, 0x0001, 0x0068, 0x0146, 0x01d6,
- 0x3300, 0x8001, 0x20a0, 0x3c00, 0x20e8, 0x2001, 0xffff, 0x4004,
- 0x01de, 0x014e, 0x9006, 0x01ce, 0x013e, 0x0005, 0x0096, 0x0126,
- 0x2091, 0x8000, 0xb8a4, 0x904d, 0x1128, 0x080c, 0x100e, 0x0168,
- 0x2900, 0xb8a6, 0x080c, 0x68d3, 0xa803, 0x0001, 0xa807, 0x0000,
- 0x9085, 0x0001, 0x012e, 0x009e, 0x0005, 0x9006, 0x0cd8, 0x0096,
- 0x0126, 0x2091, 0x8000, 0xb8a4, 0x904d, 0x0130, 0xb8a7, 0x0000,
- 0x080c, 0x1040, 0x9085, 0x0001, 0x012e, 0x009e, 0x0005, 0xb89c,
- 0xd0a4, 0x0005, 0x00b6, 0x00f6, 0x080c, 0x7563, 0x01b0, 0x71c4,
- 0x81ff, 0x1198, 0x71dc, 0xd19c, 0x0180, 0x2001, 0x007e, 0x9080,
- 0x1000, 0x2004, 0x905d, 0x0148, 0xb804, 0x9084, 0x00ff, 0x9086,
- 0x0006, 0x1118, 0xb800, 0xc0ed, 0xb802, 0x2079, 0x1847, 0x7804,
- 0xd0a4, 0x01d0, 0x0156, 0x20a9, 0x007f, 0x900e, 0x0016, 0x080c,
- 0x6717, 0x1168, 0xb804, 0x9084, 0xff00, 0x8007, 0x9096, 0x0004,
- 0x0118, 0x9086, 0x0006, 0x1118, 0xb800, 0xc0ed, 0xb802, 0x001e,
- 0x8108, 0x1f04, 0x695e, 0x015e, 0x080c, 0x6a4a, 0x0120, 0x2001,
- 0x1986, 0x200c, 0x0038, 0x2079, 0x1847, 0x7804, 0xd0a4, 0x0130,
- 0x2009, 0x07d0, 0x2011, 0x6989, 0x080c, 0x879b, 0x00fe, 0x00be,
- 0x0005, 0x00b6, 0x2011, 0x6989, 0x080c, 0x8703, 0x080c, 0x6a4a,
- 0x01d8, 0x2001, 0x107e, 0x2004, 0x2058, 0xb900, 0xc1ec, 0xb902,
- 0x080c, 0x6a88, 0x0130, 0x2009, 0x07d0, 0x2011, 0x6989, 0x080c,
- 0x879b, 0x00e6, 0x2071, 0x1800, 0x9006, 0x707e, 0x7060, 0x7082,
- 0x080c, 0x3022, 0x00ee, 0x04c0, 0x0156, 0x00c6, 0x20a9, 0x007f,
- 0x900e, 0x0016, 0x080c, 0x6717, 0x1548, 0xb800, 0xd0ec, 0x0530,
- 0xd0bc, 0x1520, 0x0046, 0xbaa0, 0x2220, 0x9006, 0x2009, 0x0029,
- 0x080c, 0xe940, 0xb800, 0xc0e5, 0xc0ec, 0xb802, 0x080c, 0x6a84,
- 0x2001, 0x0707, 0x1128, 0xb804, 0x9084, 0x00ff, 0x9085, 0x0700,
- 0xb806, 0x2019, 0x0029, 0x080c, 0x94da, 0x0076, 0x903e, 0x080c,
- 0x93ad, 0x900e, 0x080c, 0xe671, 0x007e, 0x004e, 0x001e, 0x8108,
- 0x1f04, 0x69b1, 0x00ce, 0x015e, 0x00be, 0x0005, 0x00b6, 0x6010,
- 0x2058, 0xb800, 0xc0ec, 0xb802, 0x00be, 0x0005, 0x00b6, 0x00c6,
- 0x0096, 0x080c, 0x1027, 0x090c, 0x0dc5, 0x2958, 0x009e, 0x2001,
- 0x196c, 0x2b02, 0x8b07, 0x8006, 0x8006, 0x908c, 0x003f, 0xb9c6,
- 0x908c, 0xffc0, 0xb9ca, 0xb8af, 0x0000, 0x2009, 0x00ff, 0x080c,
- 0x613b, 0xb807, 0x0006, 0xb813, 0x00ff, 0xb817, 0xffff, 0xb86f,
- 0x0200, 0xb86c, 0xb893, 0x0002, 0xb8bb, 0x0520, 0xb8a3, 0x00ff,
- 0xb8af, 0x0000, 0x00ce, 0x00be, 0x0005, 0x7810, 0x00b6, 0x2058,
- 0xb800, 0x00be, 0xd0ac, 0x0005, 0x6010, 0x00b6, 0x905d, 0x0108,
- 0xb800, 0x00be, 0xd0bc, 0x0005, 0x0006, 0x0016, 0x0026, 0xb804,
- 0x908c, 0x00ff, 0x9196, 0x0006, 0x0188, 0x9196, 0x0004, 0x0170,
- 0x9196, 0x0005, 0x0158, 0x908c, 0xff00, 0x810f, 0x9196, 0x0006,
- 0x0128, 0x9196, 0x0004, 0x0110, 0x9196, 0x0005, 0x002e, 0x001e,
- 0x000e, 0x0005, 0x00b6, 0x00f6, 0x2001, 0x107e, 0x2004, 0x905d,
- 0x0110, 0xb800, 0xd0ec, 0x00fe, 0x00be, 0x0005, 0x0126, 0x0026,
- 0x2091, 0x8000, 0x0006, 0xbaa0, 0x9290, 0x1000, 0x2204, 0x9b06,
- 0x190c, 0x0dc5, 0x000e, 0xba00, 0x9005, 0x0110, 0xc2fd, 0x0008,
- 0xc2fc, 0xba02, 0x002e, 0x012e, 0x0005, 0x2011, 0x1837, 0x2204,
- 0xd0cc, 0x0138, 0x2001, 0x1984, 0x200c, 0x2011, 0x6a7a, 0x080c,
- 0x879b, 0x0005, 0x2011, 0x6a7a, 0x080c, 0x8703, 0x2011, 0x1837,
- 0x2204, 0xc0cc, 0x2012, 0x0005, 0x080c, 0x57cd, 0xd0ac, 0x0005,
- 0x080c, 0x57cd, 0xd0a4, 0x0005, 0x0016, 0xb904, 0x9184, 0x00ff,
- 0x908e, 0x0006, 0x001e, 0x0005, 0x0016, 0xb904, 0x9184, 0xff00,
- 0x8007, 0x908e, 0x0006, 0x001e, 0x0005, 0x00b6, 0x00f6, 0x080c,
- 0xd548, 0x0158, 0x70dc, 0x9084, 0x0028, 0x0138, 0x2001, 0x107f,
- 0x2004, 0x905d, 0x0110, 0xb8cc, 0xd094, 0x00fe, 0x00be, 0x0005,
- 0x2071, 0x1910, 0x7003, 0x0001, 0x7007, 0x0000, 0x9006, 0x7012,
- 0x7016, 0x701a, 0x701e, 0x700a, 0x7046, 0x2001, 0x1922, 0x2003,
- 0x0000, 0x0005, 0x0016, 0x00e6, 0x2071, 0x1949, 0x900e, 0x710a,
- 0x080c, 0x57cd, 0xd0fc, 0x1140, 0x080c, 0x57cd, 0x900e, 0xd09c,
- 0x0108, 0x8108, 0x7102, 0x0430, 0x2001, 0x1867, 0x200c, 0x9184,
- 0x0007, 0x0002, 0x6acc, 0x6acc, 0x6acc, 0x6acc, 0x6acc, 0x6ae2,
- 0x6af7, 0x6b05, 0x7003, 0x0003, 0x2009, 0x1868, 0x210c, 0x9184,
- 0xff00, 0x908e, 0xff00, 0x0140, 0x8007, 0x9005, 0x1110, 0x2001,
- 0x0002, 0x8003, 0x7006, 0x0030, 0x7007, 0x0001, 0x0018, 0x7003,
- 0x0005, 0x0c50, 0x2071, 0x1910, 0x704f, 0x0000, 0x2071, 0x1800,
- 0x70f3, 0x0001, 0x00ee, 0x001e, 0x0005, 0x7003, 0x0000, 0x2071,
- 0x1910, 0x2009, 0x1868, 0x210c, 0x9184, 0x7f00, 0x8007, 0x908c,
- 0x000f, 0x0160, 0x714e, 0x8004, 0x8004, 0x8004, 0x8004, 0x2071,
- 0x1800, 0x908c, 0x0007, 0x0128, 0x70f2, 0x0c20, 0x704f, 0x000f,
- 0x0c90, 0x70f3, 0x0005, 0x08f0, 0x00e6, 0x2071, 0x0050, 0x684c,
- 0x9005, 0x1150, 0x00e6, 0x2071, 0x1910, 0x7028, 0xc085, 0x702a,
- 0x00ee, 0x9085, 0x0001, 0x0488, 0x6844, 0x9005, 0x0158, 0x080c,
- 0x78ba, 0x6a60, 0x9200, 0x7002, 0x6864, 0x9101, 0x7006, 0x9006,
- 0x7012, 0x7016, 0x6860, 0x7002, 0x6864, 0x7006, 0x6868, 0x700a,
- 0x686c, 0x700e, 0x6844, 0x9005, 0x1110, 0x7012, 0x7016, 0x684c,
- 0x701a, 0x701c, 0x9085, 0x0040, 0x701e, 0x7037, 0x0019, 0x702b,
- 0x0001, 0x00e6, 0x2071, 0x1910, 0x7028, 0xc084, 0x702a, 0x7007,
- 0x0001, 0x700b, 0x0000, 0x00ee, 0x9006, 0x00ee, 0x0005, 0x00e6,
- 0x0026, 0x2071, 0x1949, 0x7000, 0x9015, 0x0904, 0x6dd1, 0x9286,
- 0x0003, 0x0904, 0x6c6a, 0x9286, 0x0005, 0x0904, 0x6c6a, 0x2071,
- 0x1877, 0xa87c, 0x9005, 0x0904, 0x6bc5, 0x7140, 0xa868, 0x9102,
- 0x0a04, 0x6dd1, 0xa878, 0xd084, 0x15d8, 0xa853, 0x0019, 0x2001,
- 0x8023, 0xa84e, 0x2071, 0x1910, 0x701c, 0x9005, 0x1904, 0x6f9f,
- 0x0e04, 0x700d, 0x2071, 0x0000, 0xa850, 0x7032, 0xa84c, 0x7082,
- 0xa870, 0x7086, 0xa86c, 0x708a, 0xa880, 0x708e, 0x7036, 0x0146,
- 0x01d6, 0x0136, 0x01c6, 0x0156, 0x20e9, 0x0000, 0x20a1, 0x002a,
- 0xa868, 0x20a8, 0xa860, 0x20e0, 0xa85c, 0x9080, 0x0021, 0x2098,
- 0x4003, 0x015e, 0x01ce, 0x013e, 0x01de, 0x014e, 0x2091, 0x4080,
- 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x11aa, 0x0804, 0x6c4d,
- 0xa853, 0x001b, 0x2001, 0x8027, 0x0820, 0x7004, 0xd08c, 0x1904,
- 0x6dd1, 0xa853, 0x001a, 0x2001, 0x8024, 0x0804, 0x6b89, 0x00e6,
- 0x0026, 0x2071, 0x1949, 0x7000, 0x9015, 0x0904, 0x6dd1, 0x9286,
- 0x0003, 0x0904, 0x6c6a, 0x9286, 0x0005, 0x0904, 0x6c6a, 0xa84f,
- 0x8022, 0xa853, 0x0018, 0x0804, 0x6c32, 0xa868, 0xd0fc, 0x1508,
- 0x00e6, 0x0026, 0x2001, 0x1949, 0x2004, 0x9015, 0x0904, 0x6dd1,
- 0xa978, 0xa874, 0x9105, 0x1904, 0x6dd1, 0x9286, 0x0003, 0x0904,
- 0x6c6a, 0x9286, 0x0005, 0x0904, 0x6c6a, 0xa87c, 0xd0bc, 0x1904,
- 0x6dd1, 0x2200, 0x0002, 0x6dd1, 0x6c2e, 0x6c6a, 0x6c6a, 0x6dd1,
- 0x6c6a, 0x0005, 0xa868, 0xd0fc, 0x1500, 0x00e6, 0x0026, 0x2009,
- 0x1949, 0x210c, 0x81ff, 0x0904, 0x6dd1, 0xa880, 0x9084, 0x00ff,
- 0x9086, 0x0001, 0x1904, 0x6dd1, 0x9186, 0x0003, 0x0904, 0x6c6a,
- 0x9186, 0x0005, 0x0904, 0x6c6a, 0xa87c, 0xd0cc, 0x0904, 0x6dd1,
- 0xa84f, 0x8021, 0xa853, 0x0017, 0x0028, 0x0005, 0xa84f, 0x8020,
- 0xa853, 0x0016, 0x2071, 0x1910, 0x701c, 0x9005, 0x1904, 0x6f9f,
- 0x0e04, 0x700d, 0x2071, 0x0000, 0xa84c, 0x7082, 0xa850, 0x7032,
- 0xa86c, 0x7086, 0x7036, 0xa870, 0x708a, 0x2091, 0x4080, 0x2001,
- 0x0089, 0x2004, 0xd084, 0x190c, 0x11aa, 0x2071, 0x1800, 0x2011,
- 0x0001, 0xa804, 0x900d, 0x702c, 0x1158, 0xa802, 0x2900, 0x702e,
- 0x70c0, 0x9200, 0x70c2, 0x080c, 0x85eb, 0x002e, 0x00ee, 0x0005,
- 0x0096, 0x2148, 0xa904, 0xa802, 0x8210, 0x2900, 0x81ff, 0x1dc8,
- 0x009e, 0x0c58, 0xa84f, 0x0000, 0x00f6, 0x2079, 0x0050, 0x2071,
- 0x1910, 0xa803, 0x0000, 0x7010, 0x9005, 0x1904, 0x6d55, 0x782c,
- 0x908c, 0x0780, 0x190c, 0x715b, 0x8004, 0x8004, 0x8004, 0x9084,
- 0x0003, 0x0002, 0x6c88, 0x6d55, 0x6cac, 0x6cf2, 0x080c, 0x0dc5,
- 0x2071, 0x1800, 0x2900, 0x7822, 0xa804, 0x900d, 0x1168, 0x2071,
- 0x19fc, 0x7044, 0x9005, 0x1320, 0x2001, 0x194a, 0x2004, 0x7046,
- 0x00fe, 0x002e, 0x00ee, 0x0005, 0x9016, 0x702c, 0x2148, 0xa904,
- 0xa802, 0x8210, 0x2900, 0x81ff, 0x1dc8, 0x702e, 0x70c0, 0x9200,
- 0x70c2, 0x080c, 0x85eb, 0x0c18, 0x2071, 0x1800, 0x2900, 0x7822,
- 0xa804, 0x900d, 0x1578, 0x7824, 0x00e6, 0x2071, 0x0040, 0x712c,
- 0xd19c, 0x1148, 0x2009, 0x1830, 0x210c, 0x918a, 0x0020, 0x0218,
- 0x7022, 0x00ee, 0x0058, 0x00ee, 0x2048, 0x702c, 0xa802, 0x2900,
- 0x702e, 0x70c0, 0x8000, 0x70c2, 0x080c, 0x85eb, 0x782c, 0x9094,
- 0x0780, 0x190c, 0x715b, 0xd0a4, 0x19f0, 0x2071, 0x19fc, 0x7044,
+ 0x9005, 0x012e, 0x0005, 0x2001, 0x180c, 0x2004, 0xd084, 0x19d0,
+ 0x9188, 0x1000, 0x2104, 0x905d, 0x09a8, 0x080c, 0x6a92, 0x1990,
+ 0xb800, 0xd0bc, 0x0978, 0x0804, 0x61dc, 0x080c, 0x68b9, 0x0904,
+ 0x61f5, 0x0804, 0x61e0, 0x00b6, 0x00e6, 0x0126, 0x2091, 0x8000,
+ 0xa874, 0x908e, 0x00ff, 0x1120, 0x2001, 0x196c, 0x205c, 0x0060,
+ 0xa974, 0x9182, 0x0800, 0x1690, 0x9188, 0x1000, 0x2104, 0x905d,
+ 0x01d0, 0x080c, 0x6a32, 0x11d0, 0x080c, 0xb0ab, 0x0570, 0x2b00,
+ 0x6012, 0x2900, 0x6016, 0x6023, 0x0009, 0x600b, 0x0000, 0xa874,
+ 0x908e, 0x00ff, 0x1110, 0x600b, 0x8000, 0x2009, 0x0043, 0x080c,
+ 0xb180, 0x9006, 0x00b0, 0x2001, 0x0028, 0x0090, 0x2009, 0x180c,
+ 0x210c, 0xd18c, 0x0118, 0x2001, 0x0004, 0x0038, 0xd184, 0x0118,
+ 0x2001, 0x0004, 0x0010, 0x2001, 0x0029, 0x0010, 0x2001, 0x0029,
+ 0x9005, 0x012e, 0x00ee, 0x00be, 0x0005, 0x2001, 0x002c, 0x0cc0,
+ 0x00b6, 0x00e6, 0x0126, 0x2091, 0x8000, 0xa974, 0x9182, 0x0800,
+ 0x1a04, 0x6316, 0x9188, 0x1000, 0x2104, 0x905d, 0x0904, 0x62ee,
+ 0xb8a0, 0x9086, 0x007f, 0x0190, 0xa87c, 0xd0fc, 0x1178, 0x080c,
+ 0x6a9a, 0x0160, 0xa994, 0x81ff, 0x0130, 0x908e, 0x0004, 0x0130,
+ 0x908e, 0x0005, 0x0118, 0x080c, 0x6a92, 0x1598, 0xa87c, 0xd0fc,
+ 0x01e0, 0xa894, 0x9005, 0x01c8, 0x2060, 0x0026, 0x2010, 0x080c,
+ 0xce44, 0x002e, 0x1120, 0x2001, 0x0008, 0x0804, 0x6318, 0x6020,
+ 0x9086, 0x000a, 0x0120, 0x2001, 0x0008, 0x0804, 0x6318, 0x601a,
+ 0x6003, 0x0008, 0x2900, 0x6016, 0x0058, 0x080c, 0xb0ab, 0x05e8,
+ 0x2b00, 0x6012, 0x2900, 0x6016, 0x600b, 0xffff, 0x6023, 0x000a,
+ 0x2009, 0x0003, 0x080c, 0xb180, 0x9006, 0x0458, 0x2001, 0x0028,
+ 0x0438, 0x9082, 0x0006, 0x1290, 0x080c, 0xb06b, 0x1160, 0xb8a0,
+ 0x9084, 0xff80, 0x1140, 0xb900, 0xd1fc, 0x0900, 0x2001, 0x0029,
+ 0x2009, 0x1000, 0x00a8, 0x2001, 0x0028, 0x0090, 0x2009, 0x180c,
+ 0x210c, 0xd18c, 0x0118, 0x2001, 0x0004, 0x0050, 0xd184, 0x0118,
+ 0x2001, 0x0004, 0x0028, 0x2001, 0x0029, 0x0010, 0x2001, 0x0029,
+ 0x9005, 0x012e, 0x00ee, 0x00be, 0x0005, 0x2001, 0x002c, 0x0cc0,
+ 0x00f6, 0x00b6, 0x0126, 0x2091, 0x8000, 0xa8e0, 0x9005, 0x1550,
+ 0xa8dc, 0x9082, 0x0101, 0x1630, 0xa8c8, 0x9005, 0x1518, 0xa8c4,
+ 0x9082, 0x0101, 0x12f8, 0xa974, 0x2079, 0x1800, 0x9182, 0x0800,
+ 0x12e8, 0x7830, 0x9084, 0x0003, 0x1130, 0xaa98, 0xab94, 0xa878,
+ 0x9084, 0x0007, 0x00ea, 0x7930, 0xd18c, 0x0118, 0x2001, 0x0004,
+ 0x0038, 0xd184, 0x0118, 0x2001, 0x0004, 0x0010, 0x2001, 0x0029,
+ 0x900e, 0x0038, 0x2001, 0x002c, 0x900e, 0x0018, 0x2001, 0x0029,
+ 0x900e, 0x9006, 0x0008, 0x9005, 0x012e, 0x00be, 0x00fe, 0x0005,
+ 0x63ad, 0x6368, 0x637f, 0x63ad, 0x63ad, 0x63ad, 0x63ad, 0x63ad,
+ 0x2100, 0x9082, 0x007e, 0x1278, 0x080c, 0x66b2, 0x0148, 0x9046,
+ 0xb810, 0x9306, 0x1904, 0x63b5, 0xb814, 0x9206, 0x15f0, 0x0028,
+ 0xbb12, 0xba16, 0x0010, 0x080c, 0x4a9c, 0x0150, 0x04b0, 0x080c,
+ 0x671d, 0x1598, 0xb810, 0x9306, 0x1580, 0xb814, 0x9206, 0x1568,
+ 0x080c, 0xb0ab, 0x0530, 0x2b00, 0x6012, 0x080c, 0xd2d2, 0x2900,
+ 0x6016, 0x600b, 0xffff, 0x6023, 0x000a, 0xa878, 0x9086, 0x0001,
+ 0x1170, 0x080c, 0x3246, 0x9006, 0x080c, 0x664f, 0x2001, 0x0002,
+ 0x080c, 0x6663, 0x2001, 0x0200, 0xb86e, 0xb893, 0x0002, 0x2009,
+ 0x0003, 0x080c, 0xb180, 0x9006, 0x0068, 0x2001, 0x0001, 0x900e,
+ 0x0038, 0x2001, 0x002c, 0x900e, 0x0018, 0x2001, 0x0028, 0x900e,
+ 0x9005, 0x0000, 0x012e, 0x00be, 0x00fe, 0x0005, 0x00b6, 0x00f6,
+ 0x00e6, 0x0126, 0x2091, 0x8000, 0xa894, 0x90c6, 0x0015, 0x0904,
+ 0x65a0, 0x90c6, 0x0056, 0x0904, 0x65a4, 0x90c6, 0x0066, 0x0904,
+ 0x65a8, 0x90c6, 0x0067, 0x0904, 0x65ac, 0x90c6, 0x0068, 0x0904,
+ 0x65b0, 0x90c6, 0x0071, 0x0904, 0x65b4, 0x90c6, 0x0074, 0x0904,
+ 0x65b8, 0x90c6, 0x007c, 0x0904, 0x65bc, 0x90c6, 0x007e, 0x0904,
+ 0x65c0, 0x90c6, 0x0037, 0x0904, 0x65c4, 0x9016, 0x2079, 0x1800,
+ 0xa974, 0x9186, 0x00ff, 0x0904, 0x659b, 0x9182, 0x0800, 0x1a04,
+ 0x659b, 0x080c, 0x671d, 0x1198, 0xb804, 0x9084, 0x00ff, 0x9082,
+ 0x0006, 0x1268, 0xa894, 0x90c6, 0x006f, 0x0148, 0x080c, 0xb06b,
+ 0x1904, 0x6584, 0xb8a0, 0x9084, 0xff80, 0x1904, 0x6584, 0xa894,
+ 0x90c6, 0x006f, 0x0158, 0x90c6, 0x005e, 0x0904, 0x64e4, 0x90c6,
+ 0x0064, 0x0904, 0x650d, 0x2008, 0x0804, 0x64a6, 0xa998, 0xa8b0,
+ 0x2040, 0x080c, 0xb06b, 0x1120, 0x9182, 0x007f, 0x0a04, 0x64a6,
+ 0x9186, 0x00ff, 0x0904, 0x64a6, 0x9182, 0x0800, 0x1a04, 0x64a6,
+ 0xaaa0, 0xab9c, 0x787c, 0x9306, 0x11a8, 0x7880, 0x0096, 0x924e,
+ 0x1128, 0x2208, 0x2310, 0x009e, 0x0804, 0x64a6, 0x080c, 0xb06b,
+ 0x1140, 0x99cc, 0xff00, 0x009e, 0x1128, 0x2208, 0x2310, 0x0804,
+ 0x64a6, 0x009e, 0x080c, 0x4a9c, 0x0904, 0x64b0, 0x900e, 0x9016,
+ 0x90c6, 0x4000, 0x15e0, 0x0006, 0x080c, 0x693d, 0x1108, 0xc185,
+ 0xb800, 0xd0bc, 0x0108, 0xc18d, 0x20a9, 0x0004, 0xa860, 0x20e8,
+ 0xa85c, 0x9080, 0x0031, 0x20a0, 0xb8c4, 0x20e0, 0xb8c8, 0x9080,
+ 0x0006, 0x2098, 0x080c, 0x0f8b, 0x20a9, 0x0004, 0xa860, 0x20e8,
+ 0xa85c, 0x9080, 0x0035, 0x20a0, 0xb8c4, 0x20e0, 0xb8c8, 0x9080,
+ 0x000a, 0x2098, 0x080c, 0x0f8b, 0xa8c4, 0xabc8, 0x9305, 0xabcc,
+ 0x9305, 0xabd0, 0x9305, 0xabd4, 0x9305, 0xabd8, 0x9305, 0xabdc,
+ 0x9305, 0xabe0, 0x9305, 0x9005, 0x0510, 0x000e, 0x00c8, 0x90c6,
+ 0x4007, 0x1110, 0x2408, 0x00a0, 0x90c6, 0x4008, 0x1118, 0x2708,
+ 0x2610, 0x0070, 0x90c6, 0x4009, 0x1108, 0x0050, 0x90c6, 0x4006,
+ 0x0138, 0x2001, 0x4005, 0x2009, 0x000a, 0x0010, 0x2001, 0x4006,
+ 0xa896, 0xa99a, 0xaa9e, 0x2001, 0x0030, 0x900e, 0x0478, 0x000e,
+ 0x080c, 0xb0ab, 0x1130, 0x2001, 0x4005, 0x2009, 0x0003, 0x9016,
+ 0x0c78, 0x2b00, 0x6012, 0x080c, 0xd2d2, 0x2900, 0x6016, 0x6023,
+ 0x0001, 0xa868, 0xd88c, 0x0108, 0xc0f5, 0xa86a, 0x0126, 0x2091,
+ 0x8000, 0x080c, 0x3246, 0x012e, 0x9006, 0x080c, 0x664f, 0x2001,
+ 0x0002, 0x080c, 0x6663, 0x2009, 0x0002, 0x080c, 0xb180, 0xa8b0,
+ 0xd094, 0x0118, 0xb8cc, 0xc08d, 0xb8ce, 0x9006, 0x9005, 0x012e,
+ 0x00ee, 0x00fe, 0x00be, 0x0005, 0x080c, 0x57e7, 0x0118, 0x2009,
+ 0x0007, 0x00f8, 0xa998, 0xaeb0, 0x080c, 0x671d, 0x1904, 0x64a1,
+ 0x9186, 0x007f, 0x0130, 0x080c, 0x6a92, 0x0118, 0x2009, 0x0009,
+ 0x0080, 0x0096, 0x080c, 0x100e, 0x1120, 0x009e, 0x2009, 0x0002,
+ 0x0040, 0x2900, 0x009e, 0xa806, 0x080c, 0xd03e, 0x19b0, 0x2009,
+ 0x0003, 0x2001, 0x4005, 0x0804, 0x64a8, 0xa998, 0xaeb0, 0x080c,
+ 0x671d, 0x1904, 0x64a1, 0x0096, 0x080c, 0x100e, 0x1128, 0x009e,
+ 0x2009, 0x0002, 0x0804, 0x6561, 0x2900, 0x009e, 0xa806, 0x0096,
+ 0x2048, 0x20a9, 0x002b, 0xb8c4, 0x20e0, 0xb8c8, 0x2098, 0xa860,
+ 0x20e8, 0xa85c, 0x9080, 0x0002, 0x20a0, 0x4003, 0x20a9, 0x0008,
+ 0x9080, 0x0006, 0x20a0, 0xbbc8, 0x9398, 0x0006, 0x2398, 0x080c,
+ 0x0f8b, 0x009e, 0xa87b, 0x0000, 0xa883, 0x0000, 0xa897, 0x4000,
+ 0xd684, 0x1168, 0x080c, 0x57d3, 0xd0b4, 0x1118, 0xa89b, 0x000b,
+ 0x00e0, 0xb800, 0xd08c, 0x0118, 0xa89b, 0x000c, 0x00b0, 0x080c,
+ 0x6a92, 0x0118, 0xa89b, 0x0009, 0x0080, 0x080c, 0x57e7, 0x0118,
+ 0xa89b, 0x0007, 0x0050, 0x080c, 0xd021, 0x1904, 0x64dd, 0x2009,
+ 0x0003, 0x2001, 0x4005, 0x0804, 0x64a8, 0xa87b, 0x0030, 0xa897,
+ 0x4005, 0xa804, 0x8006, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084,
+ 0xffc0, 0x9080, 0x0002, 0x2009, 0x002b, 0xaaa0, 0xab9c, 0xaca8,
+ 0xada4, 0x2031, 0x0000, 0x2041, 0x1252, 0x080c, 0xb61f, 0x1904,
+ 0x64dd, 0x2009, 0x0002, 0x08e8, 0x2001, 0x0028, 0x900e, 0x0804,
+ 0x64de, 0x2009, 0x180c, 0x210c, 0xd18c, 0x0118, 0x2001, 0x0004,
+ 0x0038, 0xd184, 0x0118, 0x2001, 0x0004, 0x0010, 0x2001, 0x0029,
+ 0x900e, 0x0804, 0x64de, 0x2001, 0x0029, 0x900e, 0x0804, 0x64de,
+ 0x080c, 0x37dd, 0x0804, 0x64df, 0x080c, 0x54fe, 0x0804, 0x64df,
+ 0x080c, 0x460c, 0x0804, 0x64df, 0x080c, 0x4685, 0x0804, 0x64df,
+ 0x080c, 0x46e1, 0x0804, 0x64df, 0x080c, 0x4b5f, 0x0804, 0x64df,
+ 0x080c, 0x4e13, 0x0804, 0x64df, 0x080c, 0x5165, 0x0804, 0x64df,
+ 0x080c, 0x535e, 0x0804, 0x64df, 0x080c, 0x3a07, 0x0804, 0x64df,
+ 0x00b6, 0xa974, 0xae78, 0x9684, 0x3fff, 0x9082, 0x4000, 0x1618,
+ 0x9182, 0x0800, 0x1268, 0x9188, 0x1000, 0x2104, 0x905d, 0x0140,
+ 0x080c, 0x6a92, 0x1148, 0x00e9, 0x080c, 0x6848, 0x9006, 0x00b0,
+ 0x2001, 0x0028, 0x900e, 0x0090, 0x9082, 0x0006, 0x1240, 0xb900,
+ 0xd1fc, 0x0d88, 0x2001, 0x0029, 0x2009, 0x1000, 0x0038, 0x2001,
+ 0x0029, 0x900e, 0x0018, 0x2001, 0x0029, 0x900e, 0x9005, 0x00be,
+ 0x0005, 0x0126, 0x2091, 0x8000, 0xb850, 0x900d, 0x0150, 0x2900,
+ 0x0096, 0x2148, 0xa802, 0x009e, 0xa803, 0x0000, 0xb852, 0x012e,
+ 0x0005, 0x2900, 0xb852, 0xb84e, 0xa803, 0x0000, 0x0cc0, 0x0126,
+ 0x2091, 0x8000, 0xb84c, 0x9005, 0x0170, 0x00e6, 0x2071, 0x19e9,
+ 0x7004, 0x9086, 0x0002, 0x0168, 0x00ee, 0xb84c, 0xa802, 0x2900,
+ 0xb84e, 0x012e, 0x0005, 0x2900, 0xb852, 0xb84e, 0xa803, 0x0000,
+ 0x0cc0, 0x701c, 0x9b06, 0x1d80, 0xb84c, 0x00a6, 0x2050, 0xb000,
+ 0xa802, 0x2900, 0xb002, 0x00ae, 0x00ee, 0x012e, 0x0005, 0x0126,
+ 0x2091, 0x8000, 0xb84c, 0x904d, 0x0130, 0xa800, 0x9005, 0x1108,
+ 0xb852, 0xb84e, 0x9905, 0x012e, 0x0005, 0xb84c, 0x904d, 0x0130,
+ 0xa800, 0x9005, 0x1108, 0xb852, 0xb84e, 0x9905, 0x0005, 0x00b6,
+ 0x0126, 0x00c6, 0x0026, 0x2091, 0x8000, 0x6210, 0x2258, 0xba00,
+ 0x9005, 0x0110, 0xc285, 0x0008, 0xc284, 0xba02, 0x002e, 0x00ce,
+ 0x012e, 0x00be, 0x0005, 0x00b6, 0x0126, 0x00c6, 0x2091, 0x8000,
+ 0x6210, 0x2258, 0xba04, 0x0006, 0x9086, 0x0006, 0x1170, 0xb89c,
+ 0xd0ac, 0x0158, 0x080c, 0x6a8e, 0x0140, 0x9284, 0xff00, 0x8007,
+ 0x9086, 0x0007, 0x1110, 0x2011, 0x0600, 0x000e, 0x9294, 0xff00,
+ 0x9215, 0xba06, 0x0006, 0x9086, 0x0006, 0x1120, 0xba90, 0x82ff,
+ 0x090c, 0x0dc5, 0x000e, 0x00ce, 0x012e, 0x00be, 0x0005, 0x00b6,
+ 0x0126, 0x00c6, 0x2091, 0x8000, 0x6210, 0x2258, 0xba04, 0x0006,
+ 0x9086, 0x0006, 0x1168, 0xb89c, 0xd0a4, 0x0150, 0x080c, 0x6a8a,
+ 0x1138, 0x9284, 0x00ff, 0x9086, 0x0007, 0x1110, 0x2011, 0x0006,
+ 0x000e, 0x9294, 0x00ff, 0x8007, 0x9215, 0xba06, 0x00ce, 0x012e,
+ 0x00be, 0x0005, 0x9182, 0x0800, 0x0218, 0x9085, 0x0001, 0x0005,
+ 0x00d6, 0x0026, 0x9190, 0x1000, 0x2204, 0x905d, 0x1188, 0x0096,
+ 0x080c, 0x100e, 0x2958, 0x009e, 0x0168, 0x2b00, 0x2012, 0xb85c,
+ 0xb8ca, 0xb860, 0xb8c6, 0x9006, 0xb8a6, 0xb8ae, 0x080c, 0x6141,
+ 0x9006, 0x0010, 0x9085, 0x0001, 0x002e, 0x00de, 0x0005, 0x00b6,
+ 0x0096, 0x0126, 0x2091, 0x8000, 0x0026, 0x9182, 0x0800, 0x0218,
+ 0x9085, 0x0001, 0x04a8, 0x00d6, 0x9190, 0x1000, 0x2204, 0x905d,
+ 0x0568, 0x2013, 0x0000, 0xb8a4, 0x904d, 0x0110, 0x080c, 0x1040,
+ 0x00d6, 0x00c6, 0xb8bc, 0x2060, 0x8cff, 0x0168, 0x600c, 0x0006,
+ 0x6014, 0x2048, 0x080c, 0xce56, 0x0110, 0x080c, 0x0fc0, 0x080c,
+ 0xb101, 0x00ce, 0x0c88, 0x00ce, 0x00de, 0x00c6, 0xb8ac, 0x9065,
+ 0x0128, 0x621c, 0xd2c4, 0x0110, 0x080c, 0x8f64, 0x00ce, 0x2b48,
+ 0xb8c8, 0xb85e, 0xb8c4, 0xb862, 0x080c, 0x1050, 0x00de, 0x9006,
+ 0x002e, 0x012e, 0x009e, 0x00be, 0x0005, 0x0016, 0x9182, 0x0800,
+ 0x0218, 0x9085, 0x0001, 0x0030, 0x9188, 0x1000, 0x2104, 0x905d,
+ 0x0dc0, 0x9006, 0x001e, 0x0005, 0x00d6, 0x0156, 0x0136, 0x0146,
+ 0x9006, 0xb80a, 0xb80e, 0xb800, 0xc08c, 0xb802, 0x080c, 0x7569,
+ 0x1510, 0xb8a0, 0x9086, 0x007e, 0x0120, 0x080c, 0xb06b, 0x11d8,
+ 0x0078, 0x7040, 0xd0e4, 0x01b8, 0x00c6, 0x2061, 0x1983, 0x7048,
+ 0x2062, 0x704c, 0x6006, 0x7050, 0x600a, 0x7054, 0x600e, 0x00ce,
+ 0x703c, 0x2069, 0x0140, 0x9005, 0x1110, 0x2001, 0x0001, 0x6886,
+ 0x2069, 0x1800, 0x68b6, 0x7040, 0xb85e, 0x7048, 0xb862, 0x704c,
+ 0xb866, 0x20e1, 0x0000, 0x2099, 0x0276, 0xb8c4, 0x20e8, 0xb8c8,
+ 0x9088, 0x000a, 0x21a0, 0x20a9, 0x0004, 0x4003, 0x2099, 0x027a,
+ 0x9088, 0x0006, 0x21a0, 0x20a9, 0x0004, 0x4003, 0x2069, 0x0200,
+ 0x6817, 0x0001, 0x7040, 0xb86a, 0x7144, 0xb96e, 0x7048, 0xb872,
+ 0x7050, 0xb876, 0x2069, 0x0200, 0x6817, 0x0000, 0xb8a0, 0x9086,
+ 0x007e, 0x1110, 0x7144, 0xb96e, 0x9182, 0x0211, 0x1218, 0x2009,
+ 0x0008, 0x0400, 0x9182, 0x0259, 0x1218, 0x2009, 0x0007, 0x00d0,
+ 0x9182, 0x02c1, 0x1218, 0x2009, 0x0006, 0x00a0, 0x9182, 0x0349,
+ 0x1218, 0x2009, 0x0005, 0x0070, 0x9182, 0x0421, 0x1218, 0x2009,
+ 0x0004, 0x0040, 0x9182, 0x0581, 0x1218, 0x2009, 0x0003, 0x0010,
+ 0x2009, 0x0002, 0xb992, 0x014e, 0x013e, 0x015e, 0x00de, 0x0005,
+ 0x0016, 0x0026, 0x00e6, 0x2071, 0x0260, 0x7034, 0xb896, 0x703c,
+ 0xb89a, 0x7054, 0xb89e, 0x0036, 0xbbcc, 0xc384, 0xba00, 0x2009,
+ 0x1867, 0x210c, 0xd0bc, 0x0120, 0xd1ec, 0x0110, 0xc2ad, 0x0008,
+ 0xc2ac, 0xd0c4, 0x0148, 0xd1e4, 0x0138, 0xc2bd, 0xd0cc, 0x0128,
+ 0xd38c, 0x1108, 0xc385, 0x0008, 0xc2bc, 0xba02, 0xbbce, 0x003e,
+ 0x00ee, 0x002e, 0x001e, 0x0005, 0x0096, 0x0126, 0x2091, 0x8000,
+ 0xb8a4, 0x904d, 0x0578, 0xa900, 0x81ff, 0x15c0, 0xaa04, 0x9282,
+ 0x0010, 0x16c8, 0x0136, 0x0146, 0x01c6, 0x01d6, 0x8906, 0x8006,
+ 0x8007, 0x908c, 0x003f, 0x21e0, 0x9084, 0xffc0, 0x9080, 0x0004,
+ 0x2098, 0x2009, 0x0010, 0x20a9, 0x0001, 0x4002, 0x9086, 0xffff,
+ 0x0120, 0x8109, 0x1dd0, 0x080c, 0x0dc5, 0x3c00, 0x20e8, 0x3300,
+ 0x8001, 0x20a0, 0x4604, 0x8210, 0xaa06, 0x01de, 0x01ce, 0x014e,
+ 0x013e, 0x0060, 0x080c, 0x100e, 0x0170, 0x2900, 0xb8a6, 0xa803,
+ 0x0000, 0x080c, 0x68d9, 0xa807, 0x0001, 0xae12, 0x9085, 0x0001,
+ 0x012e, 0x009e, 0x0005, 0x9006, 0x0cd8, 0x0126, 0x2091, 0x8000,
+ 0x0096, 0xb8a4, 0x904d, 0x0188, 0xa800, 0x9005, 0x1150, 0x080c,
+ 0x68e8, 0x1158, 0xa804, 0x908a, 0x0002, 0x0218, 0x8001, 0xa806,
+ 0x0020, 0x080c, 0x1040, 0xb8a7, 0x0000, 0x009e, 0x012e, 0x0005,
+ 0x0126, 0x2091, 0x8000, 0x080c, 0x9358, 0x012e, 0x0005, 0x901e,
+ 0x0010, 0x2019, 0x0001, 0x900e, 0x0126, 0x2091, 0x8000, 0xb84c,
+ 0x2048, 0xb800, 0xd0dc, 0x1170, 0x89ff, 0x0500, 0x83ff, 0x0120,
+ 0xa878, 0x9606, 0x0158, 0x0030, 0xa86c, 0x9406, 0x1118, 0xa870,
+ 0x9506, 0x0120, 0x2908, 0xa800, 0x2048, 0x0c70, 0x080c, 0xa91f,
+ 0xaa00, 0xb84c, 0x9906, 0x1110, 0xba4e, 0x0020, 0x00a6, 0x2150,
+ 0xb202, 0x00ae, 0x82ff, 0x1110, 0xb952, 0x89ff, 0x012e, 0x0005,
+ 0x9016, 0x0489, 0x1110, 0x2011, 0x0001, 0x0005, 0x080c, 0x693d,
+ 0x0128, 0x080c, 0xcf13, 0x0010, 0x9085, 0x0001, 0x0005, 0x080c,
+ 0x693d, 0x0128, 0x080c, 0xceb8, 0x0010, 0x9085, 0x0001, 0x0005,
+ 0x080c, 0x693d, 0x0128, 0x080c, 0xcf10, 0x0010, 0x9085, 0x0001,
+ 0x0005, 0x080c, 0x693d, 0x0128, 0x080c, 0xced7, 0x0010, 0x9085,
+ 0x0001, 0x0005, 0x080c, 0x693d, 0x0128, 0x080c, 0xcf56, 0x0010,
+ 0x9085, 0x0001, 0x0005, 0xb8a4, 0x900d, 0x1118, 0x9085, 0x0001,
+ 0x0005, 0x0136, 0x01c6, 0xa800, 0x9005, 0x11b8, 0x890e, 0x810e,
+ 0x810f, 0x9184, 0x003f, 0x20e0, 0x9184, 0xffc0, 0x9080, 0x0004,
+ 0x2098, 0x20a9, 0x0001, 0x2009, 0x0010, 0x4002, 0x9606, 0x0128,
+ 0x8109, 0x1dd8, 0x9085, 0x0001, 0x0008, 0x9006, 0x01ce, 0x013e,
+ 0x0005, 0x0146, 0x01d6, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0004,
+ 0x20a0, 0x20a9, 0x0010, 0x2009, 0xffff, 0x4104, 0x01de, 0x014e,
+ 0x0136, 0x01c6, 0xa800, 0x9005, 0x11b8, 0x890e, 0x810e, 0x810f,
+ 0x9184, 0x003f, 0x20e0, 0x9184, 0xffc0, 0x9080, 0x0004, 0x2098,
+ 0x20a9, 0x0001, 0x2009, 0x0010, 0x4002, 0x9606, 0x0128, 0x8109,
+ 0x1dd8, 0x9085, 0x0001, 0x0068, 0x0146, 0x01d6, 0x3300, 0x8001,
+ 0x20a0, 0x3c00, 0x20e8, 0x2001, 0xffff, 0x4004, 0x01de, 0x014e,
+ 0x9006, 0x01ce, 0x013e, 0x0005, 0x0096, 0x0126, 0x2091, 0x8000,
+ 0xb8a4, 0x904d, 0x1128, 0x080c, 0x100e, 0x0168, 0x2900, 0xb8a6,
+ 0x080c, 0x68d9, 0xa803, 0x0001, 0xa807, 0x0000, 0x9085, 0x0001,
+ 0x012e, 0x009e, 0x0005, 0x9006, 0x0cd8, 0x0096, 0x0126, 0x2091,
+ 0x8000, 0xb8a4, 0x904d, 0x0130, 0xb8a7, 0x0000, 0x080c, 0x1040,
+ 0x9085, 0x0001, 0x012e, 0x009e, 0x0005, 0xb89c, 0xd0a4, 0x0005,
+ 0x00b6, 0x00f6, 0x080c, 0x7569, 0x01b0, 0x71c4, 0x81ff, 0x1198,
+ 0x71dc, 0xd19c, 0x0180, 0x2001, 0x007e, 0x9080, 0x1000, 0x2004,
+ 0x905d, 0x0148, 0xb804, 0x9084, 0x00ff, 0x9086, 0x0006, 0x1118,
+ 0xb800, 0xc0ed, 0xb802, 0x2079, 0x1847, 0x7804, 0xd0a4, 0x01d0,
+ 0x0156, 0x20a9, 0x007f, 0x900e, 0x0016, 0x080c, 0x671d, 0x1168,
+ 0xb804, 0x9084, 0xff00, 0x8007, 0x9096, 0x0004, 0x0118, 0x9086,
+ 0x0006, 0x1118, 0xb800, 0xc0ed, 0xb802, 0x001e, 0x8108, 0x1f04,
+ 0x6964, 0x015e, 0x080c, 0x6a50, 0x0120, 0x2001, 0x1986, 0x200c,
+ 0x0038, 0x2079, 0x1847, 0x7804, 0xd0a4, 0x0130, 0x2009, 0x07d0,
+ 0x2011, 0x698f, 0x080c, 0x87a1, 0x00fe, 0x00be, 0x0005, 0x00b6,
+ 0x2011, 0x698f, 0x080c, 0x8709, 0x080c, 0x6a50, 0x01d8, 0x2001,
+ 0x107e, 0x2004, 0x2058, 0xb900, 0xc1ec, 0xb902, 0x080c, 0x6a8e,
+ 0x0130, 0x2009, 0x07d0, 0x2011, 0x698f, 0x080c, 0x87a1, 0x00e6,
+ 0x2071, 0x1800, 0x9006, 0x707e, 0x7060, 0x7082, 0x080c, 0x3019,
+ 0x00ee, 0x04c0, 0x0156, 0x00c6, 0x20a9, 0x007f, 0x900e, 0x0016,
+ 0x080c, 0x671d, 0x1548, 0xb800, 0xd0ec, 0x0530, 0xd0bc, 0x1520,
+ 0x0046, 0xbaa0, 0x2220, 0x9006, 0x2009, 0x0029, 0x080c, 0xe9a5,
+ 0xb800, 0xc0e5, 0xc0ec, 0xb802, 0x080c, 0x6a8a, 0x2001, 0x0707,
+ 0x1128, 0xb804, 0x9084, 0x00ff, 0x9085, 0x0700, 0xb806, 0x2019,
+ 0x0029, 0x080c, 0x94e0, 0x0076, 0x903e, 0x080c, 0x93b3, 0x900e,
+ 0x080c, 0xe690, 0x007e, 0x004e, 0x001e, 0x8108, 0x1f04, 0x69b7,
+ 0x00ce, 0x015e, 0x00be, 0x0005, 0x00b6, 0x6010, 0x2058, 0xb800,
+ 0xc0ec, 0xb802, 0x00be, 0x0005, 0x00b6, 0x00c6, 0x0096, 0x080c,
+ 0x1027, 0x090c, 0x0dc5, 0x2958, 0x009e, 0x2001, 0x196c, 0x2b02,
+ 0x8b07, 0x8006, 0x8006, 0x908c, 0x003f, 0xb9c6, 0x908c, 0xffc0,
+ 0xb9ca, 0xb8af, 0x0000, 0x2009, 0x00ff, 0x080c, 0x6141, 0xb807,
+ 0x0006, 0xb813, 0x00ff, 0xb817, 0xffff, 0xb86f, 0x0200, 0xb86c,
+ 0xb893, 0x0002, 0xb8bb, 0x0520, 0xb8a3, 0x00ff, 0xb8af, 0x0000,
+ 0x00ce, 0x00be, 0x0005, 0x7810, 0x00b6, 0x2058, 0xb800, 0x00be,
+ 0xd0ac, 0x0005, 0x6010, 0x00b6, 0x905d, 0x0108, 0xb800, 0x00be,
+ 0xd0bc, 0x0005, 0x0006, 0x0016, 0x0026, 0xb804, 0x908c, 0x00ff,
+ 0x9196, 0x0006, 0x0188, 0x9196, 0x0004, 0x0170, 0x9196, 0x0005,
+ 0x0158, 0x908c, 0xff00, 0x810f, 0x9196, 0x0006, 0x0128, 0x9196,
+ 0x0004, 0x0110, 0x9196, 0x0005, 0x002e, 0x001e, 0x000e, 0x0005,
+ 0x00b6, 0x00f6, 0x2001, 0x107e, 0x2004, 0x905d, 0x0110, 0xb800,
+ 0xd0ec, 0x00fe, 0x00be, 0x0005, 0x0126, 0x0026, 0x2091, 0x8000,
+ 0x0006, 0xbaa0, 0x9290, 0x1000, 0x2204, 0x9b06, 0x190c, 0x0dc5,
+ 0x000e, 0xba00, 0x9005, 0x0110, 0xc2fd, 0x0008, 0xc2fc, 0xba02,
+ 0x002e, 0x012e, 0x0005, 0x2011, 0x1837, 0x2204, 0xd0cc, 0x0138,
+ 0x2001, 0x1984, 0x200c, 0x2011, 0x6a80, 0x080c, 0x87a1, 0x0005,
+ 0x2011, 0x6a80, 0x080c, 0x8709, 0x2011, 0x1837, 0x2204, 0xc0cc,
+ 0x2012, 0x0005, 0x080c, 0x57d3, 0xd0ac, 0x0005, 0x080c, 0x57d3,
+ 0xd0a4, 0x0005, 0x0016, 0xb904, 0x9184, 0x00ff, 0x908e, 0x0006,
+ 0x001e, 0x0005, 0x0016, 0xb904, 0x9184, 0xff00, 0x8007, 0x908e,
+ 0x0006, 0x001e, 0x0005, 0x00b6, 0x00f6, 0x080c, 0xd561, 0x0158,
+ 0x70dc, 0x9084, 0x0028, 0x0138, 0x2001, 0x107f, 0x2004, 0x905d,
+ 0x0110, 0xb8cc, 0xd094, 0x00fe, 0x00be, 0x0005, 0x2071, 0x1910,
+ 0x7003, 0x0001, 0x7007, 0x0000, 0x9006, 0x7012, 0x7016, 0x701a,
+ 0x701e, 0x700a, 0x7046, 0x2001, 0x1922, 0x2003, 0x0000, 0x0005,
+ 0x0016, 0x00e6, 0x2071, 0x1949, 0x900e, 0x710a, 0x080c, 0x57d3,
+ 0xd0fc, 0x1140, 0x080c, 0x57d3, 0x900e, 0xd09c, 0x0108, 0x8108,
+ 0x7102, 0x0430, 0x2001, 0x1867, 0x200c, 0x9184, 0x0007, 0x0002,
+ 0x6ad2, 0x6ad2, 0x6ad2, 0x6ad2, 0x6ad2, 0x6ae8, 0x6afd, 0x6b0b,
+ 0x7003, 0x0003, 0x2009, 0x1868, 0x210c, 0x9184, 0xff00, 0x908e,
+ 0xff00, 0x0140, 0x8007, 0x9005, 0x1110, 0x2001, 0x0002, 0x8003,
+ 0x7006, 0x0030, 0x7007, 0x0001, 0x0018, 0x7003, 0x0005, 0x0c50,
+ 0x2071, 0x1910, 0x704f, 0x0000, 0x2071, 0x1800, 0x70f3, 0x0001,
+ 0x00ee, 0x001e, 0x0005, 0x7003, 0x0000, 0x2071, 0x1910, 0x2009,
+ 0x1868, 0x210c, 0x9184, 0x7f00, 0x8007, 0x908c, 0x000f, 0x0160,
+ 0x714e, 0x8004, 0x8004, 0x8004, 0x8004, 0x2071, 0x1800, 0x908c,
+ 0x0007, 0x0128, 0x70f2, 0x0c20, 0x704f, 0x000f, 0x0c90, 0x70f3,
+ 0x0005, 0x08f0, 0x00e6, 0x2071, 0x0050, 0x684c, 0x9005, 0x1150,
+ 0x00e6, 0x2071, 0x1910, 0x7028, 0xc085, 0x702a, 0x00ee, 0x9085,
+ 0x0001, 0x0488, 0x6844, 0x9005, 0x0158, 0x080c, 0x78c0, 0x6a60,
+ 0x9200, 0x7002, 0x6864, 0x9101, 0x7006, 0x9006, 0x7012, 0x7016,
+ 0x6860, 0x7002, 0x6864, 0x7006, 0x6868, 0x700a, 0x686c, 0x700e,
+ 0x6844, 0x9005, 0x1110, 0x7012, 0x7016, 0x684c, 0x701a, 0x701c,
+ 0x9085, 0x0040, 0x701e, 0x7037, 0x0019, 0x702b, 0x0001, 0x00e6,
+ 0x2071, 0x1910, 0x7028, 0xc084, 0x702a, 0x7007, 0x0001, 0x700b,
+ 0x0000, 0x00ee, 0x9006, 0x00ee, 0x0005, 0x00e6, 0x0026, 0x2071,
+ 0x1949, 0x7000, 0x9015, 0x0904, 0x6dd7, 0x9286, 0x0003, 0x0904,
+ 0x6c70, 0x9286, 0x0005, 0x0904, 0x6c70, 0x2071, 0x1877, 0xa87c,
+ 0x9005, 0x0904, 0x6bcb, 0x7140, 0xa868, 0x9102, 0x0a04, 0x6dd7,
+ 0xa878, 0xd084, 0x15d8, 0xa853, 0x0019, 0x2001, 0x8023, 0xa84e,
+ 0x2071, 0x1910, 0x701c, 0x9005, 0x1904, 0x6fa5, 0x0e04, 0x7013,
+ 0x2071, 0x0000, 0xa850, 0x7032, 0xa84c, 0x7082, 0xa870, 0x7086,
+ 0xa86c, 0x708a, 0xa880, 0x708e, 0x7036, 0x0146, 0x01d6, 0x0136,
+ 0x01c6, 0x0156, 0x20e9, 0x0000, 0x20a1, 0x002a, 0xa868, 0x20a8,
+ 0xa860, 0x20e0, 0xa85c, 0x9080, 0x0021, 0x2098, 0x4003, 0x015e,
+ 0x01ce, 0x013e, 0x01de, 0x014e, 0x2091, 0x4080, 0x2001, 0x0089,
+ 0x2004, 0xd084, 0x190c, 0x11aa, 0x0804, 0x6c53, 0xa853, 0x001b,
+ 0x2001, 0x8027, 0x0820, 0x7004, 0xd08c, 0x1904, 0x6dd7, 0xa853,
+ 0x001a, 0x2001, 0x8024, 0x0804, 0x6b8f, 0x00e6, 0x0026, 0x2071,
+ 0x1949, 0x7000, 0x9015, 0x0904, 0x6dd7, 0x9286, 0x0003, 0x0904,
+ 0x6c70, 0x9286, 0x0005, 0x0904, 0x6c70, 0xa84f, 0x8022, 0xa853,
+ 0x0018, 0x0804, 0x6c38, 0xa868, 0xd0fc, 0x1508, 0x00e6, 0x0026,
+ 0x2001, 0x1949, 0x2004, 0x9015, 0x0904, 0x6dd7, 0xa978, 0xa874,
+ 0x9105, 0x1904, 0x6dd7, 0x9286, 0x0003, 0x0904, 0x6c70, 0x9286,
+ 0x0005, 0x0904, 0x6c70, 0xa87c, 0xd0bc, 0x1904, 0x6dd7, 0x2200,
+ 0x0002, 0x6dd7, 0x6c34, 0x6c70, 0x6c70, 0x6dd7, 0x6c70, 0x0005,
+ 0xa868, 0xd0fc, 0x1500, 0x00e6, 0x0026, 0x2009, 0x1949, 0x210c,
+ 0x81ff, 0x0904, 0x6dd7, 0xa880, 0x9084, 0x00ff, 0x9086, 0x0001,
+ 0x1904, 0x6dd7, 0x9186, 0x0003, 0x0904, 0x6c70, 0x9186, 0x0005,
+ 0x0904, 0x6c70, 0xa87c, 0xd0cc, 0x0904, 0x6dd7, 0xa84f, 0x8021,
+ 0xa853, 0x0017, 0x0028, 0x0005, 0xa84f, 0x8020, 0xa853, 0x0016,
+ 0x2071, 0x1910, 0x701c, 0x9005, 0x1904, 0x6fa5, 0x0e04, 0x7013,
+ 0x2071, 0x0000, 0xa84c, 0x7082, 0xa850, 0x7032, 0xa86c, 0x7086,
+ 0x7036, 0xa870, 0x708a, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004,
+ 0xd084, 0x190c, 0x11aa, 0x2071, 0x1800, 0x2011, 0x0001, 0xa804,
+ 0x900d, 0x702c, 0x1158, 0xa802, 0x2900, 0x702e, 0x70c0, 0x9200,
+ 0x70c2, 0x080c, 0x85f1, 0x002e, 0x00ee, 0x0005, 0x0096, 0x2148,
+ 0xa904, 0xa802, 0x8210, 0x2900, 0x81ff, 0x1dc8, 0x009e, 0x0c58,
+ 0xa84f, 0x0000, 0x00f6, 0x2079, 0x0050, 0x2071, 0x1910, 0xa803,
+ 0x0000, 0x7010, 0x9005, 0x1904, 0x6d5b, 0x782c, 0x908c, 0x0780,
+ 0x190c, 0x7161, 0x8004, 0x8004, 0x8004, 0x9084, 0x0003, 0x0002,
+ 0x6c8e, 0x6d5b, 0x6cb2, 0x6cf8, 0x080c, 0x0dc5, 0x2071, 0x1800,
+ 0x2900, 0x7822, 0xa804, 0x900d, 0x1168, 0x2071, 0x19fc, 0x7044,
0x9005, 0x1320, 0x2001, 0x194a, 0x2004, 0x7046, 0x00fe, 0x002e,
0x00ee, 0x0005, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802, 0x8210,
0x2900, 0x81ff, 0x1dc8, 0x702e, 0x70c0, 0x9200, 0x70c2, 0x080c,
- 0x85eb, 0x0808, 0x0096, 0x00e6, 0x7824, 0x2048, 0x2071, 0x1800,
- 0x702c, 0xa802, 0x2900, 0x702e, 0x70c0, 0x8000, 0x70c2, 0x080c,
- 0x85eb, 0x782c, 0x9094, 0x0780, 0x190c, 0x715b, 0xd0a4, 0x1d60,
- 0x00ee, 0x782c, 0x9094, 0x0780, 0x190c, 0x715b, 0xd09c, 0x1198,
- 0x009e, 0x2900, 0x7822, 0xa804, 0x900d, 0x1550, 0x2071, 0x19fc,
- 0x7044, 0x9005, 0x1320, 0x2001, 0x194a, 0x2004, 0x7046, 0x00fe,
- 0x002e, 0x00ee, 0x0005, 0x009e, 0x2908, 0x7010, 0x8000, 0x7012,
- 0x7018, 0x904d, 0x711a, 0x0110, 0xa902, 0x0008, 0x711e, 0x2148,
- 0xa804, 0x900d, 0x1168, 0x2071, 0x19fc, 0x7044, 0x9005, 0x1320,
+ 0x85f1, 0x0c18, 0x2071, 0x1800, 0x2900, 0x7822, 0xa804, 0x900d,
+ 0x1578, 0x7824, 0x00e6, 0x2071, 0x0040, 0x712c, 0xd19c, 0x1148,
+ 0x2009, 0x1830, 0x210c, 0x918a, 0x0020, 0x0218, 0x7022, 0x00ee,
+ 0x0058, 0x00ee, 0x2048, 0x702c, 0xa802, 0x2900, 0x702e, 0x70c0,
+ 0x8000, 0x70c2, 0x080c, 0x85f1, 0x782c, 0x9094, 0x0780, 0x190c,
+ 0x7161, 0xd0a4, 0x19f0, 0x2071, 0x19fc, 0x7044, 0x9005, 0x1320,
0x2001, 0x194a, 0x2004, 0x7046, 0x00fe, 0x002e, 0x00ee, 0x0005,
+ 0x9016, 0x702c, 0x2148, 0xa904, 0xa802, 0x8210, 0x2900, 0x81ff,
+ 0x1dc8, 0x702e, 0x70c0, 0x9200, 0x70c2, 0x080c, 0x85f1, 0x0808,
+ 0x0096, 0x00e6, 0x7824, 0x2048, 0x2071, 0x1800, 0x702c, 0xa802,
+ 0x2900, 0x702e, 0x70c0, 0x8000, 0x70c2, 0x080c, 0x85f1, 0x782c,
+ 0x9094, 0x0780, 0x190c, 0x7161, 0xd0a4, 0x1d60, 0x00ee, 0x782c,
+ 0x9094, 0x0780, 0x190c, 0x7161, 0xd09c, 0x1198, 0x009e, 0x2900,
+ 0x7822, 0xa804, 0x900d, 0x1550, 0x2071, 0x19fc, 0x7044, 0x9005,
+ 0x1320, 0x2001, 0x194a, 0x2004, 0x7046, 0x00fe, 0x002e, 0x00ee,
+ 0x0005, 0x009e, 0x2908, 0x7010, 0x8000, 0x7012, 0x7018, 0x904d,
+ 0x711a, 0x0110, 0xa902, 0x0008, 0x711e, 0x2148, 0xa804, 0x900d,
+ 0x1168, 0x2071, 0x19fc, 0x7044, 0x9005, 0x1320, 0x2001, 0x194a,
+ 0x2004, 0x7046, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x2071, 0x1800,
+ 0x9016, 0x702c, 0x2148, 0xa904, 0xa802, 0x8210, 0x2900, 0x81ff,
+ 0x1dc8, 0x702e, 0x70c0, 0x9200, 0x70c2, 0x080c, 0x85f1, 0x00fe,
+ 0x002e, 0x00ee, 0x0005, 0x2908, 0x7010, 0x8000, 0x7012, 0x7018,
+ 0x904d, 0x711a, 0x0110, 0xa902, 0x0008, 0x711e, 0x2148, 0xa804,
+ 0x900d, 0x1904, 0x6daf, 0x782c, 0x9094, 0x0780, 0x190c, 0x7161,
+ 0xd09c, 0x1198, 0x701c, 0x904d, 0x0180, 0x7010, 0x8001, 0x7012,
+ 0x1108, 0x701a, 0xa800, 0x701e, 0x2900, 0x7822, 0x782c, 0x9094,
+ 0x0780, 0x190c, 0x7161, 0xd09c, 0x0d68, 0x782c, 0x9094, 0x0780,
+ 0x190c, 0x7161, 0xd0a4, 0x01b0, 0x00e6, 0x7824, 0x2048, 0x2071,
+ 0x1800, 0x702c, 0xa802, 0x2900, 0x702e, 0x70c0, 0x8000, 0x70c2,
+ 0x080c, 0x85f1, 0x782c, 0x9094, 0x0780, 0x190c, 0x7161, 0xd0a4,
+ 0x1d60, 0x00ee, 0x2071, 0x19fc, 0x7044, 0x9005, 0x1320, 0x2001,
+ 0x194a, 0x2004, 0x7046, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x00e6,
0x2071, 0x1800, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802, 0x8210,
0x2900, 0x81ff, 0x1dc8, 0x702e, 0x70c0, 0x9200, 0x70c2, 0x080c,
- 0x85eb, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x2908, 0x7010, 0x8000,
- 0x7012, 0x7018, 0x904d, 0x711a, 0x0110, 0xa902, 0x0008, 0x711e,
- 0x2148, 0xa804, 0x900d, 0x1904, 0x6da9, 0x782c, 0x9094, 0x0780,
- 0x190c, 0x715b, 0xd09c, 0x1198, 0x701c, 0x904d, 0x0180, 0x7010,
- 0x8001, 0x7012, 0x1108, 0x701a, 0xa800, 0x701e, 0x2900, 0x7822,
- 0x782c, 0x9094, 0x0780, 0x190c, 0x715b, 0xd09c, 0x0d68, 0x782c,
- 0x9094, 0x0780, 0x190c, 0x715b, 0xd0a4, 0x01b0, 0x00e6, 0x7824,
- 0x2048, 0x2071, 0x1800, 0x702c, 0xa802, 0x2900, 0x702e, 0x70c0,
- 0x8000, 0x70c2, 0x080c, 0x85eb, 0x782c, 0x9094, 0x0780, 0x190c,
- 0x715b, 0xd0a4, 0x1d60, 0x00ee, 0x2071, 0x19fc, 0x7044, 0x9005,
- 0x1320, 0x2001, 0x194a, 0x2004, 0x7046, 0x00fe, 0x002e, 0x00ee,
- 0x0005, 0x00e6, 0x2071, 0x1800, 0x9016, 0x702c, 0x2148, 0xa904,
- 0xa802, 0x8210, 0x2900, 0x81ff, 0x1dc8, 0x702e, 0x70c0, 0x9200,
- 0x70c2, 0x080c, 0x85eb, 0x00ee, 0x0804, 0x6d65, 0xa868, 0xd0fc,
- 0x1904, 0x6e1f, 0x0096, 0xa804, 0xa807, 0x0000, 0x904d, 0x190c,
- 0x0fc0, 0x009e, 0x0020, 0xa868, 0xd0fc, 0x1904, 0x6e1f, 0x00e6,
- 0x0026, 0xa84f, 0x0000, 0x00f6, 0x2079, 0x0050, 0x2071, 0x1800,
- 0x70ec, 0x8001, 0x0558, 0x1a04, 0x6e1c, 0x2071, 0x1910, 0xa803,
- 0x0000, 0xa864, 0x9084, 0x00ff, 0x908e, 0x0016, 0x01a8, 0x7010,
- 0x9005, 0x1904, 0x6f1b, 0x782c, 0x908c, 0x0780, 0x190c, 0x715b,
- 0x8004, 0x8004, 0x8004, 0x9084, 0x0003, 0x0002, 0x6e20, 0x6f1b,
- 0x6e3b, 0x6eac, 0x080c, 0x0dc5, 0x2009, 0x1949, 0x2104, 0x0002,
- 0x6de7, 0x6de7, 0x6de7, 0x6c73, 0x6de7, 0x6c73, 0x70ef, 0x0fa0,
- 0x71e8, 0x8107, 0x9106, 0x9094, 0x00c0, 0x9184, 0xff3f, 0x9205,
- 0x70ea, 0x3b08, 0x3a00, 0x9104, 0x918d, 0x00c0, 0x21d8, 0x9084,
- 0xff3f, 0x9205, 0x20d0, 0x0808, 0x70ee, 0x0804, 0x6ddd, 0x0005,
- 0x2071, 0x1800, 0x2900, 0x7822, 0xa804, 0x900d, 0x1120, 0x00fe,
- 0x002e, 0x00ee, 0x0005, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802,
- 0x8210, 0x2900, 0x81ff, 0x1dc8, 0x702e, 0x70c0, 0x9200, 0x70c2,
- 0x080c, 0x85eb, 0x0c60, 0x2071, 0x1800, 0x2900, 0x7822, 0xa804,
- 0x900d, 0x1904, 0x6e9b, 0x7830, 0x8007, 0x908c, 0x001f, 0x70f0,
- 0x9102, 0x1220, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x7824, 0x00e6,
- 0x2071, 0x0040, 0x712c, 0xd19c, 0x1148, 0x2009, 0x1830, 0x210c,
- 0x918a, 0x0020, 0x0218, 0x7022, 0x00ee, 0x0058, 0x00ee, 0x2048,
+ 0x85f1, 0x00ee, 0x0804, 0x6d6b, 0xa868, 0xd0fc, 0x1904, 0x6e25,
+ 0x0096, 0xa804, 0xa807, 0x0000, 0x904d, 0x190c, 0x0fc0, 0x009e,
+ 0x0020, 0xa868, 0xd0fc, 0x1904, 0x6e25, 0x00e6, 0x0026, 0xa84f,
+ 0x0000, 0x00f6, 0x2079, 0x0050, 0x2071, 0x1800, 0x70ec, 0x8001,
+ 0x0558, 0x1a04, 0x6e22, 0x2071, 0x1910, 0xa803, 0x0000, 0xa864,
+ 0x9084, 0x00ff, 0x908e, 0x0016, 0x01a8, 0x7010, 0x9005, 0x1904,
+ 0x6f21, 0x782c, 0x908c, 0x0780, 0x190c, 0x7161, 0x8004, 0x8004,
+ 0x8004, 0x9084, 0x0003, 0x0002, 0x6e26, 0x6f21, 0x6e41, 0x6eb2,
+ 0x080c, 0x0dc5, 0x2009, 0x1949, 0x2104, 0x0002, 0x6ded, 0x6ded,
+ 0x6ded, 0x6c79, 0x6ded, 0x6c79, 0x70ef, 0x0fa0, 0x71e8, 0x8107,
+ 0x9106, 0x9094, 0x00c0, 0x9184, 0xff3f, 0x9205, 0x70ea, 0x3b08,
+ 0x3a00, 0x9104, 0x918d, 0x00c0, 0x21d8, 0x9084, 0xff3f, 0x9205,
+ 0x20d0, 0x0808, 0x70ee, 0x0804, 0x6de3, 0x0005, 0x2071, 0x1800,
+ 0x2900, 0x7822, 0xa804, 0x900d, 0x1120, 0x00fe, 0x002e, 0x00ee,
+ 0x0005, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802, 0x8210, 0x2900,
+ 0x81ff, 0x1dc8, 0x702e, 0x70c0, 0x9200, 0x70c2, 0x080c, 0x85f1,
+ 0x0c60, 0x2071, 0x1800, 0x2900, 0x7822, 0xa804, 0x900d, 0x1904,
+ 0x6ea1, 0x7830, 0x8007, 0x908c, 0x001f, 0x70f0, 0x9102, 0x1220,
+ 0x00fe, 0x002e, 0x00ee, 0x0005, 0x7824, 0x00e6, 0x2071, 0x0040,
+ 0x712c, 0xd19c, 0x1148, 0x2009, 0x1830, 0x210c, 0x918a, 0x0020,
+ 0x0218, 0x7022, 0x00ee, 0x0058, 0x00ee, 0x2048, 0x702c, 0xa802,
+ 0x2900, 0x702e, 0x70c0, 0x8000, 0x70c2, 0x080c, 0x85f1, 0x782c,
+ 0x9094, 0x0780, 0x190c, 0x7161, 0xd0a4, 0x19f0, 0x0e04, 0x6e98,
+ 0x7838, 0x7938, 0x910e, 0x1de0, 0x00d6, 0x2069, 0x0000, 0x6836,
+ 0x6833, 0x0013, 0x00de, 0x2001, 0x1921, 0x200c, 0xc184, 0x2102,
+ 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x11aa,
+ 0x2001, 0x1922, 0x2003, 0x0000, 0x00fe, 0x002e, 0x00ee, 0x0005,
+ 0x2001, 0x1921, 0x200c, 0xc185, 0x2102, 0x00fe, 0x002e, 0x00ee,
+ 0x0005, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802, 0x8210, 0x2900,
+ 0x81ff, 0x1dc8, 0x702e, 0x70c0, 0x9200, 0x70c2, 0x080c, 0x85f1,
+ 0x0804, 0x6e54, 0x0096, 0x00e6, 0x7824, 0x2048, 0x2071, 0x1800,
0x702c, 0xa802, 0x2900, 0x702e, 0x70c0, 0x8000, 0x70c2, 0x080c,
- 0x85eb, 0x782c, 0x9094, 0x0780, 0x190c, 0x715b, 0xd0a4, 0x19f0,
- 0x0e04, 0x6e92, 0x7838, 0x7938, 0x910e, 0x1de0, 0x00d6, 0x2069,
- 0x0000, 0x6836, 0x6833, 0x0013, 0x00de, 0x2001, 0x1921, 0x200c,
- 0xc184, 0x2102, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084,
- 0x190c, 0x11aa, 0x2001, 0x1922, 0x2003, 0x0000, 0x00fe, 0x002e,
- 0x00ee, 0x0005, 0x2001, 0x1921, 0x200c, 0xc185, 0x2102, 0x00fe,
- 0x002e, 0x00ee, 0x0005, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802,
- 0x8210, 0x2900, 0x81ff, 0x1dc8, 0x702e, 0x70c0, 0x9200, 0x70c2,
- 0x080c, 0x85eb, 0x0804, 0x6e4e, 0x0096, 0x00e6, 0x7824, 0x2048,
+ 0x85f1, 0x782c, 0x9094, 0x0780, 0x190c, 0x7161, 0xd0a4, 0x1d60,
+ 0x00ee, 0x0e04, 0x6ef4, 0x7838, 0x7938, 0x910e, 0x1de0, 0x00d6,
+ 0x2069, 0x0000, 0x6836, 0x6833, 0x0013, 0x00de, 0x7044, 0xc084,
+ 0x7046, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c,
+ 0x11aa, 0x704b, 0x0000, 0x782c, 0x9094, 0x0780, 0x190c, 0x7161,
+ 0xd09c, 0x1170, 0x009e, 0x2900, 0x7822, 0xa804, 0x900d, 0x11e0,
+ 0x00fe, 0x002e, 0x00ee, 0x0005, 0x7044, 0xc085, 0x7046, 0x0c58,
+ 0x009e, 0x2908, 0x7010, 0x8000, 0x7012, 0x7018, 0x904d, 0x711a,
+ 0x0110, 0xa902, 0x0008, 0x711e, 0x2148, 0xa804, 0x900d, 0x1120,
+ 0x00fe, 0x002e, 0x00ee, 0x0005, 0x2071, 0x1800, 0x9016, 0x702c,
+ 0x2148, 0xa904, 0xa802, 0x8210, 0x2900, 0x81ff, 0x1dc8, 0x702e,
+ 0x70c0, 0x9200, 0x70c2, 0x080c, 0x85f1, 0x00fe, 0x002e, 0x00ee,
+ 0x0005, 0x2908, 0x7010, 0x8000, 0x7012, 0x7018, 0x904d, 0x711a,
+ 0x0110, 0xa902, 0x0008, 0x711e, 0x2148, 0xa804, 0x900d, 0x1904,
+ 0x6f90, 0x782c, 0x9094, 0x0780, 0x190c, 0x7161, 0xd09c, 0x11b0,
+ 0x701c, 0x904d, 0x0198, 0xa84c, 0x9005, 0x1180, 0x7010, 0x8001,
+ 0x7012, 0x1108, 0x701a, 0xa800, 0x701e, 0x2900, 0x7822, 0x782c,
+ 0x9094, 0x0780, 0x190c, 0x7161, 0xd09c, 0x0d50, 0x782c, 0x9094,
+ 0x0780, 0x190c, 0x7161, 0xd0a4, 0x05b8, 0x00e6, 0x7824, 0x2048,
0x2071, 0x1800, 0x702c, 0xa802, 0x2900, 0x702e, 0x70c0, 0x8000,
- 0x70c2, 0x080c, 0x85eb, 0x782c, 0x9094, 0x0780, 0x190c, 0x715b,
- 0xd0a4, 0x1d60, 0x00ee, 0x0e04, 0x6eee, 0x7838, 0x7938, 0x910e,
+ 0x70c2, 0x080c, 0x85f1, 0x782c, 0x9094, 0x0780, 0x190c, 0x7161,
+ 0xd0a4, 0x1d60, 0x00ee, 0x0e04, 0x6f89, 0x7838, 0x7938, 0x910e,
0x1de0, 0x00d6, 0x2069, 0x0000, 0x6836, 0x6833, 0x0013, 0x00de,
0x7044, 0xc084, 0x7046, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004,
- 0xd084, 0x190c, 0x11aa, 0x704b, 0x0000, 0x782c, 0x9094, 0x0780,
- 0x190c, 0x715b, 0xd09c, 0x1170, 0x009e, 0x2900, 0x7822, 0xa804,
- 0x900d, 0x11e0, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x7044, 0xc085,
- 0x7046, 0x0c58, 0x009e, 0x2908, 0x7010, 0x8000, 0x7012, 0x7018,
- 0x904d, 0x711a, 0x0110, 0xa902, 0x0008, 0x711e, 0x2148, 0xa804,
- 0x900d, 0x1120, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x2071, 0x1800,
- 0x9016, 0x702c, 0x2148, 0xa904, 0xa802, 0x8210, 0x2900, 0x81ff,
- 0x1dc8, 0x702e, 0x70c0, 0x9200, 0x70c2, 0x080c, 0x85eb, 0x00fe,
- 0x002e, 0x00ee, 0x0005, 0x2908, 0x7010, 0x8000, 0x7012, 0x7018,
- 0x904d, 0x711a, 0x0110, 0xa902, 0x0008, 0x711e, 0x2148, 0xa804,
- 0x900d, 0x1904, 0x6f8a, 0x782c, 0x9094, 0x0780, 0x190c, 0x715b,
- 0xd09c, 0x11b0, 0x701c, 0x904d, 0x0198, 0xa84c, 0x9005, 0x1180,
- 0x7010, 0x8001, 0x7012, 0x1108, 0x701a, 0xa800, 0x701e, 0x2900,
- 0x7822, 0x782c, 0x9094, 0x0780, 0x190c, 0x715b, 0xd09c, 0x0d50,
- 0x782c, 0x9094, 0x0780, 0x190c, 0x715b, 0xd0a4, 0x05b8, 0x00e6,
- 0x7824, 0x2048, 0x2071, 0x1800, 0x702c, 0xa802, 0x2900, 0x702e,
- 0x70c0, 0x8000, 0x70c2, 0x080c, 0x85eb, 0x782c, 0x9094, 0x0780,
- 0x190c, 0x715b, 0xd0a4, 0x1d60, 0x00ee, 0x0e04, 0x6f83, 0x7838,
- 0x7938, 0x910e, 0x1de0, 0x00d6, 0x2069, 0x0000, 0x6836, 0x6833,
- 0x0013, 0x00de, 0x7044, 0xc084, 0x7046, 0x2091, 0x4080, 0x2001,
- 0x0089, 0x2004, 0xd084, 0x190c, 0x11aa, 0x704b, 0x0000, 0x00fe,
- 0x002e, 0x00ee, 0x0005, 0x7044, 0xc085, 0x7046, 0x00fe, 0x002e,
- 0x00ee, 0x0005, 0x00e6, 0x2071, 0x1800, 0x9016, 0x702c, 0x2148,
- 0xa904, 0xa802, 0x8210, 0x2900, 0x81ff, 0x1dc8, 0x702e, 0x70c0,
- 0x9200, 0x70c2, 0x080c, 0x85eb, 0x00ee, 0x0804, 0x6f2b, 0x2071,
- 0x1910, 0xa803, 0x0000, 0x2908, 0x7010, 0x8000, 0x7012, 0x7018,
- 0x904d, 0x711a, 0x0110, 0xa902, 0x0008, 0x711e, 0x2148, 0xa804,
- 0x900d, 0x1128, 0x1e04, 0x6fca, 0x002e, 0x00ee, 0x0005, 0x2071,
- 0x1800, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802, 0x8210, 0x2900,
- 0x81ff, 0x1dc8, 0x702e, 0x70c0, 0x9200, 0x70c2, 0x080c, 0x85eb,
- 0x0e04, 0x6fb4, 0x2071, 0x1910, 0x701c, 0x2048, 0xa84c, 0x900d,
- 0x0d18, 0x2071, 0x0000, 0x7182, 0xa850, 0x7032, 0xa86c, 0x7086,
- 0x7036, 0xa870, 0x708a, 0xa850, 0x9082, 0x0019, 0x1278, 0x2091,
- 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x11aa, 0x2071,
- 0x1910, 0x080c, 0x7147, 0x002e, 0x00ee, 0x0005, 0xa850, 0x9082,
- 0x001c, 0x1e68, 0xa880, 0x708e, 0x7036, 0x0146, 0x01d6, 0x0136,
- 0x01c6, 0x0156, 0x20e9, 0x0000, 0x20a1, 0x002a, 0xa868, 0x20a8,
- 0xa860, 0x20e0, 0xa85c, 0x9080, 0x0021, 0x2098, 0x4003, 0x015e,
- 0x01ce, 0x013e, 0x01de, 0x014e, 0x0890, 0x2071, 0x1910, 0xa803,
+ 0xd084, 0x190c, 0x11aa, 0x704b, 0x0000, 0x00fe, 0x002e, 0x00ee,
+ 0x0005, 0x7044, 0xc085, 0x7046, 0x00fe, 0x002e, 0x00ee, 0x0005,
+ 0x00e6, 0x2071, 0x1800, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802,
+ 0x8210, 0x2900, 0x81ff, 0x1dc8, 0x702e, 0x70c0, 0x9200, 0x70c2,
+ 0x080c, 0x85f1, 0x00ee, 0x0804, 0x6f31, 0x2071, 0x1910, 0xa803,
0x0000, 0x2908, 0x7010, 0x8000, 0x7012, 0x7018, 0x904d, 0x711a,
- 0x0110, 0xa902, 0x0008, 0x711e, 0x2148, 0xa804, 0x900d, 0x1118,
- 0x002e, 0x00ee, 0x0005, 0x2071, 0x1800, 0x9016, 0x702c, 0x2148,
- 0xa904, 0xa802, 0x8210, 0x2900, 0x81ff, 0x1dc8, 0x702e, 0x70c0,
- 0x9200, 0x70c2, 0x080c, 0x85eb, 0x002e, 0x00ee, 0x0005, 0x0006,
- 0xa87c, 0x0006, 0xa867, 0x0103, 0x20a9, 0x001c, 0xa860, 0x20e8,
- 0xa85c, 0x9080, 0x001d, 0x20a0, 0x9006, 0x4004, 0x000e, 0x9084,
- 0x00ff, 0xa87e, 0x000e, 0xa87a, 0xa982, 0x0005, 0x2071, 0x1910,
- 0x7004, 0x0002, 0x705a, 0x705b, 0x7146, 0x705b, 0x7058, 0x7146,
- 0x080c, 0x0dc5, 0x0005, 0x2001, 0x1949, 0x2004, 0x0002, 0x7065,
- 0x7065, 0x70df, 0x70e0, 0x7065, 0x70e0, 0x0126, 0x2091, 0x8000,
- 0x1e0c, 0x7166, 0x701c, 0x904d, 0x0508, 0xa84c, 0x9005, 0x0904,
- 0x70b0, 0x0e04, 0x708e, 0xa94c, 0x2071, 0x0000, 0x7182, 0xa850,
- 0x7032, 0xa86c, 0x7086, 0x7036, 0xa870, 0x708a, 0xa850, 0x9082,
- 0x0019, 0x1278, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084,
- 0x190c, 0x11aa, 0x2071, 0x1910, 0x080c, 0x7147, 0x012e, 0x0804,
- 0x70de, 0xa850, 0x9082, 0x001c, 0x1e68, 0xa880, 0x708e, 0x7036,
- 0x0146, 0x01d6, 0x0136, 0x01c6, 0x0156, 0x20e9, 0x0000, 0x20a1,
- 0x002a, 0xa868, 0x20a8, 0xa860, 0x20e0, 0xa85c, 0x9080, 0x0021,
- 0x2098, 0x4003, 0x015e, 0x01ce, 0x013e, 0x01de, 0x014e, 0x0890,
- 0x2001, 0x005b, 0x2004, 0x9094, 0x0780, 0x190c, 0x715b, 0xd09c,
- 0x2071, 0x1910, 0x1510, 0x2071, 0x1910, 0x700f, 0x0001, 0xa964,
- 0x9184, 0x00ff, 0x9086, 0x0003, 0x1130, 0x810f, 0x918c, 0x00ff,
- 0x8101, 0x0108, 0x710e, 0x2900, 0x00d6, 0x2069, 0x0050, 0x6822,
- 0x00de, 0x2071, 0x1910, 0x701c, 0x2048, 0x7010, 0x8001, 0x7012,
- 0xa800, 0x701e, 0x9005, 0x1108, 0x701a, 0x012e, 0x0005, 0x0005,
- 0x00d6, 0x2008, 0x2069, 0x19fc, 0x6844, 0x9005, 0x0760, 0x0158,
- 0x9186, 0x0003, 0x0540, 0x2001, 0x1815, 0x2004, 0x2009, 0x1ad2,
- 0x210c, 0x9102, 0x1500, 0x0126, 0x2091, 0x8000, 0x2069, 0x0050,
- 0x693c, 0x6838, 0x9106, 0x0190, 0x0e04, 0x7112, 0x2069, 0x0000,
- 0x6837, 0x8040, 0x6833, 0x0012, 0x6883, 0x8040, 0x2091, 0x4080,
- 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x11aa, 0x2069, 0x19fc,
- 0x6847, 0xffff, 0x012e, 0x00de, 0x0126, 0x2091, 0x8000, 0x1e0c,
- 0x71d1, 0x701c, 0x904d, 0x0540, 0x2001, 0x005b, 0x2004, 0x9094,
- 0x0780, 0x15c9, 0xd09c, 0x1500, 0x2071, 0x1910, 0x700f, 0x0001,
- 0xa964, 0x9184, 0x00ff, 0x9086, 0x0003, 0x1130, 0x810f, 0x918c,
- 0x00ff, 0x8101, 0x0108, 0x710e, 0x2900, 0x00d6, 0x2069, 0x0050,
- 0x6822, 0x00de, 0x701c, 0x2048, 0x7010, 0x8001, 0x7012, 0xa800,
- 0x701e, 0x9005, 0x1108, 0x701a, 0x012e, 0x0005, 0x0005, 0x0126,
- 0x2091, 0x8000, 0x701c, 0x904d, 0x0160, 0x7010, 0x8001, 0x7012,
- 0xa800, 0x701e, 0x9005, 0x1108, 0x701a, 0x012e, 0x080c, 0x1040,
- 0x0005, 0x012e, 0x0005, 0x2091, 0x8000, 0x0e04, 0x715d, 0x0006,
- 0x0016, 0x2001, 0x8004, 0x0006, 0x0804, 0x0dce, 0x0096, 0x00f6,
- 0x2079, 0x0050, 0x7044, 0xd084, 0x01d0, 0xc084, 0x7046, 0x7838,
+ 0x0110, 0xa902, 0x0008, 0x711e, 0x2148, 0xa804, 0x900d, 0x1128,
+ 0x1e04, 0x6fd0, 0x002e, 0x00ee, 0x0005, 0x2071, 0x1800, 0x9016,
+ 0x702c, 0x2148, 0xa904, 0xa802, 0x8210, 0x2900, 0x81ff, 0x1dc8,
+ 0x702e, 0x70c0, 0x9200, 0x70c2, 0x080c, 0x85f1, 0x0e04, 0x6fba,
+ 0x2071, 0x1910, 0x701c, 0x2048, 0xa84c, 0x900d, 0x0d18, 0x2071,
+ 0x0000, 0x7182, 0xa850, 0x7032, 0xa86c, 0x7086, 0x7036, 0xa870,
+ 0x708a, 0xa850, 0x9082, 0x0019, 0x1278, 0x2091, 0x4080, 0x2001,
+ 0x0089, 0x2004, 0xd084, 0x190c, 0x11aa, 0x2071, 0x1910, 0x080c,
+ 0x714d, 0x002e, 0x00ee, 0x0005, 0xa850, 0x9082, 0x001c, 0x1e68,
+ 0xa880, 0x708e, 0x7036, 0x0146, 0x01d6, 0x0136, 0x01c6, 0x0156,
+ 0x20e9, 0x0000, 0x20a1, 0x002a, 0xa868, 0x20a8, 0xa860, 0x20e0,
+ 0xa85c, 0x9080, 0x0021, 0x2098, 0x4003, 0x015e, 0x01ce, 0x013e,
+ 0x01de, 0x014e, 0x0890, 0x2071, 0x1910, 0xa803, 0x0000, 0x2908,
+ 0x7010, 0x8000, 0x7012, 0x7018, 0x904d, 0x711a, 0x0110, 0xa902,
+ 0x0008, 0x711e, 0x2148, 0xa804, 0x900d, 0x1118, 0x002e, 0x00ee,
+ 0x0005, 0x2071, 0x1800, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802,
+ 0x8210, 0x2900, 0x81ff, 0x1dc8, 0x702e, 0x70c0, 0x9200, 0x70c2,
+ 0x080c, 0x85f1, 0x002e, 0x00ee, 0x0005, 0x0006, 0xa87c, 0x0006,
+ 0xa867, 0x0103, 0x20a9, 0x001c, 0xa860, 0x20e8, 0xa85c, 0x9080,
+ 0x001d, 0x20a0, 0x9006, 0x4004, 0x000e, 0x9084, 0x00ff, 0xa87e,
+ 0x000e, 0xa87a, 0xa982, 0x0005, 0x2071, 0x1910, 0x7004, 0x0002,
+ 0x7060, 0x7061, 0x714c, 0x7061, 0x705e, 0x714c, 0x080c, 0x0dc5,
+ 0x0005, 0x2001, 0x1949, 0x2004, 0x0002, 0x706b, 0x706b, 0x70e5,
+ 0x70e6, 0x706b, 0x70e6, 0x0126, 0x2091, 0x8000, 0x1e0c, 0x716c,
+ 0x701c, 0x904d, 0x0508, 0xa84c, 0x9005, 0x0904, 0x70b6, 0x0e04,
+ 0x7094, 0xa94c, 0x2071, 0x0000, 0x7182, 0xa850, 0x7032, 0xa86c,
+ 0x7086, 0x7036, 0xa870, 0x708a, 0xa850, 0x9082, 0x0019, 0x1278,
+ 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x11aa,
+ 0x2071, 0x1910, 0x080c, 0x714d, 0x012e, 0x0804, 0x70e4, 0xa850,
+ 0x9082, 0x001c, 0x1e68, 0xa880, 0x708e, 0x7036, 0x0146, 0x01d6,
+ 0x0136, 0x01c6, 0x0156, 0x20e9, 0x0000, 0x20a1, 0x002a, 0xa868,
+ 0x20a8, 0xa860, 0x20e0, 0xa85c, 0x9080, 0x0021, 0x2098, 0x4003,
+ 0x015e, 0x01ce, 0x013e, 0x01de, 0x014e, 0x0890, 0x2001, 0x005b,
+ 0x2004, 0x9094, 0x0780, 0x190c, 0x7161, 0xd09c, 0x2071, 0x1910,
+ 0x1510, 0x2071, 0x1910, 0x700f, 0x0001, 0xa964, 0x9184, 0x00ff,
+ 0x9086, 0x0003, 0x1130, 0x810f, 0x918c, 0x00ff, 0x8101, 0x0108,
+ 0x710e, 0x2900, 0x00d6, 0x2069, 0x0050, 0x6822, 0x00de, 0x2071,
+ 0x1910, 0x701c, 0x2048, 0x7010, 0x8001, 0x7012, 0xa800, 0x701e,
+ 0x9005, 0x1108, 0x701a, 0x012e, 0x0005, 0x0005, 0x00d6, 0x2008,
+ 0x2069, 0x19fc, 0x6844, 0x9005, 0x0760, 0x0158, 0x9186, 0x0003,
+ 0x0540, 0x2001, 0x1815, 0x2004, 0x2009, 0x1ad2, 0x210c, 0x9102,
+ 0x1500, 0x0126, 0x2091, 0x8000, 0x2069, 0x0050, 0x693c, 0x6838,
+ 0x9106, 0x0190, 0x0e04, 0x7118, 0x2069, 0x0000, 0x6837, 0x8040,
+ 0x6833, 0x0012, 0x6883, 0x8040, 0x2091, 0x4080, 0x2001, 0x0089,
+ 0x2004, 0xd084, 0x190c, 0x11aa, 0x2069, 0x19fc, 0x6847, 0xffff,
+ 0x012e, 0x00de, 0x0126, 0x2091, 0x8000, 0x1e0c, 0x71d7, 0x701c,
+ 0x904d, 0x0540, 0x2001, 0x005b, 0x2004, 0x9094, 0x0780, 0x15c9,
+ 0xd09c, 0x1500, 0x2071, 0x1910, 0x700f, 0x0001, 0xa964, 0x9184,
+ 0x00ff, 0x9086, 0x0003, 0x1130, 0x810f, 0x918c, 0x00ff, 0x8101,
+ 0x0108, 0x710e, 0x2900, 0x00d6, 0x2069, 0x0050, 0x6822, 0x00de,
+ 0x701c, 0x2048, 0x7010, 0x8001, 0x7012, 0xa800, 0x701e, 0x9005,
+ 0x1108, 0x701a, 0x012e, 0x0005, 0x0005, 0x0126, 0x2091, 0x8000,
+ 0x701c, 0x904d, 0x0160, 0x7010, 0x8001, 0x7012, 0xa800, 0x701e,
+ 0x9005, 0x1108, 0x701a, 0x012e, 0x080c, 0x1040, 0x0005, 0x012e,
+ 0x0005, 0x2091, 0x8000, 0x0e04, 0x7163, 0x0006, 0x0016, 0x2001,
+ 0x8004, 0x0006, 0x0804, 0x0dce, 0x0096, 0x00f6, 0x2079, 0x0050,
+ 0x7044, 0xd084, 0x01d0, 0xc084, 0x7046, 0x7838, 0x7938, 0x910e,
+ 0x1de0, 0x00d6, 0x2069, 0x0000, 0x6836, 0x6833, 0x0013, 0x00de,
+ 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x11aa,
+ 0x704b, 0x0000, 0x00fe, 0x009e, 0x0005, 0x782c, 0x9094, 0x0780,
+ 0x1981, 0xd0a4, 0x0db8, 0x7148, 0x704c, 0x8108, 0x714a, 0x9102,
+ 0x0e88, 0x00e6, 0x2071, 0x1800, 0x7824, 0x00e6, 0x2071, 0x0040,
+ 0x712c, 0xd19c, 0x1148, 0x2009, 0x1830, 0x210c, 0x918a, 0x0020,
+ 0x0218, 0x7022, 0x00ee, 0x0058, 0x00ee, 0x2048, 0x702c, 0xa802,
+ 0x2900, 0x702e, 0x70c0, 0x8000, 0x70c2, 0x080c, 0x85f1, 0x782c,
+ 0x9094, 0x0780, 0x190c, 0x7161, 0xd0a4, 0x19f0, 0x7838, 0x7938,
+ 0x910e, 0x1de0, 0x00d6, 0x2069, 0x0000, 0x6836, 0x6833, 0x0013,
+ 0x00de, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c,
+ 0x11aa, 0x00ee, 0x704b, 0x0000, 0x00fe, 0x009e, 0x0005, 0x00f6,
+ 0x2079, 0x0050, 0x7044, 0xd084, 0x01b8, 0xc084, 0x7046, 0x7838,
0x7938, 0x910e, 0x1de0, 0x00d6, 0x2069, 0x0000, 0x6836, 0x6833,
0x0013, 0x00de, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084,
- 0x190c, 0x11aa, 0x704b, 0x0000, 0x00fe, 0x009e, 0x0005, 0x782c,
- 0x9094, 0x0780, 0x1981, 0xd0a4, 0x0db8, 0x7148, 0x704c, 0x8108,
- 0x714a, 0x9102, 0x0e88, 0x00e6, 0x2071, 0x1800, 0x7824, 0x00e6,
- 0x2071, 0x0040, 0x712c, 0xd19c, 0x1148, 0x2009, 0x1830, 0x210c,
- 0x918a, 0x0020, 0x0218, 0x7022, 0x00ee, 0x0058, 0x00ee, 0x2048,
+ 0x190c, 0x11aa, 0x00fe, 0x0005, 0x782c, 0x9094, 0x0780, 0x190c,
+ 0x7161, 0xd0a4, 0x0db8, 0x00e6, 0x2071, 0x1800, 0x7824, 0x2048,
0x702c, 0xa802, 0x2900, 0x702e, 0x70c0, 0x8000, 0x70c2, 0x080c,
- 0x85eb, 0x782c, 0x9094, 0x0780, 0x190c, 0x715b, 0xd0a4, 0x19f0,
- 0x7838, 0x7938, 0x910e, 0x1de0, 0x00d6, 0x2069, 0x0000, 0x6836,
- 0x6833, 0x0013, 0x00de, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004,
- 0xd084, 0x190c, 0x11aa, 0x00ee, 0x704b, 0x0000, 0x00fe, 0x009e,
- 0x0005, 0x00f6, 0x2079, 0x0050, 0x7044, 0xd084, 0x01b8, 0xc084,
- 0x7046, 0x7838, 0x7938, 0x910e, 0x1de0, 0x00d6, 0x2069, 0x0000,
- 0x6836, 0x6833, 0x0013, 0x00de, 0x2091, 0x4080, 0x2001, 0x0089,
- 0x2004, 0xd084, 0x190c, 0x11aa, 0x00fe, 0x0005, 0x782c, 0x9094,
- 0x0780, 0x190c, 0x715b, 0xd0a4, 0x0db8, 0x00e6, 0x2071, 0x1800,
- 0x7824, 0x2048, 0x702c, 0xa802, 0x2900, 0x702e, 0x70c0, 0x8000,
- 0x70c2, 0x080c, 0x85eb, 0x782c, 0x9094, 0x0780, 0x190c, 0x715b,
- 0xd0a4, 0x1d70, 0x00d6, 0x2069, 0x0050, 0x693c, 0x2069, 0x1949,
- 0x6808, 0x690a, 0x2069, 0x19fc, 0x9102, 0x1118, 0x6844, 0x9005,
- 0x1320, 0x2001, 0x194a, 0x200c, 0x6946, 0x00de, 0x00ee, 0x00fe,
- 0x0005, 0x7098, 0x908a, 0x002a, 0x1a0c, 0x0dc5, 0x9082, 0x001d,
- 0x001b, 0x6027, 0x1e00, 0x0005, 0x7312, 0x727f, 0x729b, 0x72c5,
- 0x7301, 0x7341, 0x7353, 0x729b, 0x7329, 0x723a, 0x7268, 0x72eb,
- 0x7239, 0x0005, 0x00d6, 0x2069, 0x0200, 0x6804, 0x9005, 0x1180,
- 0x6808, 0x9005, 0x1518, 0x709b, 0x0029, 0x2069, 0x1990, 0x2d04,
- 0x7002, 0x080c, 0x7698, 0x6028, 0x9085, 0x0600, 0x602a, 0x00b0,
- 0x709b, 0x0029, 0x2069, 0x1990, 0x2d04, 0x7002, 0x6028, 0x9085,
- 0x0600, 0x602a, 0x00e6, 0x0036, 0x0046, 0x0056, 0x2071, 0x1a66,
- 0x080c, 0x1b02, 0x005e, 0x004e, 0x003e, 0x00ee, 0x00de, 0x0005,
- 0x00d6, 0x2069, 0x0200, 0x6804, 0x9005, 0x1178, 0x6808, 0x9005,
- 0x1160, 0x709b, 0x0029, 0x2069, 0x1990, 0x2d04, 0x7002, 0x080c,
- 0x7735, 0x6028, 0x9085, 0x0600, 0x602a, 0x00de, 0x0005, 0x0006,
- 0x2001, 0x0090, 0x080c, 0x2d5b, 0x000e, 0x6124, 0xd1e4, 0x1190,
- 0x080c, 0x73c0, 0xd1d4, 0x1160, 0xd1dc, 0x1138, 0xd1cc, 0x0150,
- 0x709b, 0x0020, 0x080c, 0x73c0, 0x0028, 0x709b, 0x001d, 0x0010,
- 0x709b, 0x001f, 0x0005, 0x2001, 0x0088, 0x080c, 0x2d5b, 0x6124,
- 0xd1cc, 0x11e8, 0xd1dc, 0x11c0, 0xd1e4, 0x1198, 0x9184, 0x1e00,
- 0x11d8, 0x080c, 0x1b27, 0x60e3, 0x0001, 0x600c, 0xc0b4, 0x600e,
- 0x080c, 0x758f, 0x2001, 0x0080, 0x080c, 0x2d5b, 0x709b, 0x0029,
- 0x0058, 0x709b, 0x001e, 0x0040, 0x709b, 0x001d, 0x0028, 0x709b,
- 0x0020, 0x0010, 0x709b, 0x001f, 0x0005, 0x080c, 0x1b27, 0x60e3,
- 0x0001, 0x600c, 0xc0b4, 0x600e, 0x080c, 0x758f, 0x2001, 0x0080,
- 0x080c, 0x2d5b, 0x6124, 0xd1d4, 0x1198, 0xd1dc, 0x1170, 0xd1e4,
- 0x1148, 0x9184, 0x1e00, 0x1118, 0x709b, 0x0029, 0x0058, 0x709b,
- 0x0028, 0x0040, 0x709b, 0x001e, 0x0028, 0x709b, 0x001d, 0x0010,
- 0x709b, 0x001f, 0x0005, 0x6124, 0xd1d4, 0x1180, 0xd1dc, 0x1158,
- 0xd1e4, 0x1130, 0x9184, 0x1e00, 0x1158, 0x709b, 0x0029, 0x0040,
+ 0x85f1, 0x782c, 0x9094, 0x0780, 0x190c, 0x7161, 0xd0a4, 0x1d70,
+ 0x00d6, 0x2069, 0x0050, 0x693c, 0x2069, 0x1949, 0x6808, 0x690a,
+ 0x2069, 0x19fc, 0x9102, 0x1118, 0x6844, 0x9005, 0x1320, 0x2001,
+ 0x194a, 0x200c, 0x6946, 0x00de, 0x00ee, 0x00fe, 0x0005, 0x7098,
+ 0x908a, 0x002a, 0x1a0c, 0x0dc5, 0x9082, 0x001d, 0x001b, 0x6027,
+ 0x1e00, 0x0005, 0x7318, 0x7285, 0x72a1, 0x72cb, 0x7307, 0x7347,
+ 0x7359, 0x72a1, 0x732f, 0x7240, 0x726e, 0x72f1, 0x723f, 0x0005,
+ 0x00d6, 0x2069, 0x0200, 0x6804, 0x9005, 0x1180, 0x6808, 0x9005,
+ 0x1518, 0x709b, 0x0029, 0x2069, 0x1990, 0x2d04, 0x7002, 0x080c,
+ 0x769e, 0x6028, 0x9085, 0x0600, 0x602a, 0x00b0, 0x709b, 0x0029,
+ 0x2069, 0x1990, 0x2d04, 0x7002, 0x6028, 0x9085, 0x0600, 0x602a,
+ 0x00e6, 0x0036, 0x0046, 0x0056, 0x2071, 0x1a66, 0x080c, 0x1b02,
+ 0x005e, 0x004e, 0x003e, 0x00ee, 0x00de, 0x0005, 0x00d6, 0x2069,
+ 0x0200, 0x6804, 0x9005, 0x1178, 0x6808, 0x9005, 0x1160, 0x709b,
+ 0x0029, 0x2069, 0x1990, 0x2d04, 0x7002, 0x080c, 0x773b, 0x6028,
+ 0x9085, 0x0600, 0x602a, 0x00de, 0x0005, 0x0006, 0x2001, 0x0090,
+ 0x080c, 0x2d52, 0x000e, 0x6124, 0xd1e4, 0x1190, 0x080c, 0x73c6,
+ 0xd1d4, 0x1160, 0xd1dc, 0x1138, 0xd1cc, 0x0150, 0x709b, 0x0020,
+ 0x080c, 0x73c6, 0x0028, 0x709b, 0x001d, 0x0010, 0x709b, 0x001f,
+ 0x0005, 0x2001, 0x0088, 0x080c, 0x2d52, 0x6124, 0xd1cc, 0x11e8,
+ 0xd1dc, 0x11c0, 0xd1e4, 0x1198, 0x9184, 0x1e00, 0x11d8, 0x080c,
+ 0x1b2f, 0x60e3, 0x0001, 0x600c, 0xc0b4, 0x600e, 0x080c, 0x7595,
+ 0x2001, 0x0080, 0x080c, 0x2d52, 0x709b, 0x0029, 0x0058, 0x709b,
+ 0x001e, 0x0040, 0x709b, 0x001d, 0x0028, 0x709b, 0x0020, 0x0010,
+ 0x709b, 0x001f, 0x0005, 0x080c, 0x1b2f, 0x60e3, 0x0001, 0x600c,
+ 0xc0b4, 0x600e, 0x080c, 0x7595, 0x2001, 0x0080, 0x080c, 0x2d52,
+ 0x6124, 0xd1d4, 0x1198, 0xd1dc, 0x1170, 0xd1e4, 0x1148, 0x9184,
+ 0x1e00, 0x1118, 0x709b, 0x0029, 0x0058, 0x709b, 0x0028, 0x0040,
+ 0x709b, 0x001e, 0x0028, 0x709b, 0x001d, 0x0010, 0x709b, 0x001f,
+ 0x0005, 0x6124, 0xd1d4, 0x1180, 0xd1dc, 0x1158, 0xd1e4, 0x1130,
+ 0x9184, 0x1e00, 0x1158, 0x709b, 0x0029, 0x0040, 0x709b, 0x001e,
+ 0x0028, 0x709b, 0x001d, 0x0010, 0x709b, 0x001f, 0x0005, 0x2001,
+ 0x00a0, 0x080c, 0x2d52, 0x6124, 0xd1dc, 0x1138, 0xd1e4, 0x0138,
+ 0x080c, 0x1b2f, 0x709b, 0x001e, 0x0010, 0x709b, 0x001d, 0x0005,
+ 0x080c, 0x7449, 0x6124, 0xd1dc, 0x1188, 0x080c, 0x73c6, 0x0016,
+ 0x080c, 0x1b2f, 0x001e, 0xd1d4, 0x1128, 0xd1e4, 0x0138, 0x709b,
+ 0x001e, 0x0020, 0x709b, 0x001f, 0x080c, 0x73c6, 0x0005, 0x0006,
+ 0x2001, 0x00a0, 0x080c, 0x2d52, 0x000e, 0x6124, 0xd1d4, 0x1160,
+ 0xd1cc, 0x1150, 0xd1dc, 0x1128, 0xd1e4, 0x0140, 0x709b, 0x001e,
+ 0x0028, 0x709b, 0x001d, 0x0010, 0x709b, 0x0021, 0x0005, 0x080c,
+ 0x7449, 0x6124, 0xd1d4, 0x1150, 0xd1dc, 0x1128, 0xd1e4, 0x0140,
0x709b, 0x001e, 0x0028, 0x709b, 0x001d, 0x0010, 0x709b, 0x001f,
- 0x0005, 0x2001, 0x00a0, 0x080c, 0x2d5b, 0x6124, 0xd1dc, 0x1138,
- 0xd1e4, 0x0138, 0x080c, 0x1b27, 0x709b, 0x001e, 0x0010, 0x709b,
- 0x001d, 0x0005, 0x080c, 0x7443, 0x6124, 0xd1dc, 0x1188, 0x080c,
- 0x73c0, 0x0016, 0x080c, 0x1b27, 0x001e, 0xd1d4, 0x1128, 0xd1e4,
- 0x0138, 0x709b, 0x001e, 0x0020, 0x709b, 0x001f, 0x080c, 0x73c0,
- 0x0005, 0x0006, 0x2001, 0x00a0, 0x080c, 0x2d5b, 0x000e, 0x6124,
- 0xd1d4, 0x1160, 0xd1cc, 0x1150, 0xd1dc, 0x1128, 0xd1e4, 0x0140,
- 0x709b, 0x001e, 0x0028, 0x709b, 0x001d, 0x0010, 0x709b, 0x0021,
- 0x0005, 0x080c, 0x7443, 0x6124, 0xd1d4, 0x1150, 0xd1dc, 0x1128,
- 0xd1e4, 0x0140, 0x709b, 0x001e, 0x0028, 0x709b, 0x001d, 0x0010,
- 0x709b, 0x001f, 0x0005, 0x0006, 0x2001, 0x0090, 0x080c, 0x2d5b,
- 0x000e, 0x6124, 0xd1d4, 0x1178, 0xd1cc, 0x1150, 0xd1dc, 0x1128,
- 0xd1e4, 0x0158, 0x709b, 0x001e, 0x0040, 0x709b, 0x001d, 0x0028,
- 0x709b, 0x0020, 0x0010, 0x709b, 0x001f, 0x0005, 0x0016, 0x00c6,
- 0x00d6, 0x00e6, 0x0126, 0x2061, 0x0100, 0x2069, 0x0140, 0x2071,
- 0x1800, 0x2091, 0x8000, 0x080c, 0x7563, 0x11d8, 0x2001, 0x180c,
- 0x200c, 0xd1b4, 0x01b0, 0xc1b4, 0x2102, 0x6027, 0x0200, 0x080c,
- 0x2c83, 0x6024, 0xd0cc, 0x0148, 0x2001, 0x00a0, 0x080c, 0x2d5b,
- 0x080c, 0x7848, 0x080c, 0x6121, 0x0428, 0x6028, 0xc0cd, 0x602a,
- 0x0408, 0x080c, 0x757d, 0x0150, 0x080c, 0x7574, 0x1138, 0x2001,
- 0x0001, 0x080c, 0x2832, 0x080c, 0x753b, 0x00a0, 0x080c, 0x7440,
- 0x0178, 0x2001, 0x0001, 0x080c, 0x2832, 0x7098, 0x9086, 0x001e,
- 0x0120, 0x7098, 0x9086, 0x0022, 0x1118, 0x709b, 0x0025, 0x0010,
- 0x709b, 0x0021, 0x012e, 0x00ee, 0x00de, 0x00ce, 0x001e, 0x0005,
- 0x0026, 0x2011, 0x73d1, 0x080c, 0x87dd, 0x002e, 0x0016, 0x0026,
- 0x2009, 0x0064, 0x2011, 0x73d1, 0x080c, 0x87d4, 0x002e, 0x001e,
- 0x0005, 0x00e6, 0x00f6, 0x0016, 0x080c, 0xa4fd, 0x2071, 0x1800,
- 0x080c, 0x736e, 0x001e, 0x00fe, 0x00ee, 0x0005, 0x0016, 0x0026,
- 0x0036, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x0126, 0x2071, 0x1800,
- 0x080c, 0xa4fd, 0x2061, 0x0100, 0x2069, 0x0140, 0x2091, 0x8000,
- 0x6028, 0xc09c, 0x602a, 0x2011, 0x0003, 0x080c, 0xa8d3, 0x2011,
- 0x0002, 0x080c, 0xa8dd, 0x080c, 0xa7e7, 0x080c, 0x8789, 0x0036,
- 0x901e, 0x080c, 0xa85d, 0x003e, 0x60e3, 0x0000, 0x080c, 0xed95,
- 0x080c, 0xedb0, 0x2009, 0x0004, 0x080c, 0x2c89, 0x080c, 0x2ba4,
- 0x2001, 0x1800, 0x2003, 0x0004, 0x6027, 0x0008, 0x2011, 0x73d1,
- 0x080c, 0x87dd, 0x080c, 0x757d, 0x0118, 0x9006, 0x080c, 0x2d5b,
- 0x080c, 0x0ba0, 0x2001, 0x0001, 0x080c, 0x2832, 0x012e, 0x00fe,
- 0x00ee, 0x00de, 0x00ce, 0x003e, 0x002e, 0x001e, 0x0005, 0x0026,
- 0x00e6, 0x2011, 0x73de, 0x2071, 0x19fc, 0x701c, 0x9206, 0x1118,
- 0x7018, 0x9005, 0x0110, 0x9085, 0x0001, 0x00ee, 0x002e, 0x0005,
- 0x6020, 0xd09c, 0x0005, 0x6800, 0x9084, 0xfffe, 0x9086, 0x00c0,
- 0x01b8, 0x2001, 0x00c0, 0x080c, 0x2d5b, 0x0156, 0x20a9, 0x002d,
- 0x1d04, 0x7450, 0x2091, 0x6000, 0x1f04, 0x7450, 0x015e, 0x00d6,
- 0x2069, 0x1800, 0x689c, 0x8001, 0x0220, 0x0118, 0x689e, 0x00de,
- 0x0005, 0x689f, 0x0014, 0x68e8, 0xd0dc, 0x0dc8, 0x6800, 0x9086,
- 0x0001, 0x1da8, 0x080c, 0x87e9, 0x0c90, 0x00c6, 0x00d6, 0x00e6,
- 0x2061, 0x0100, 0x2069, 0x0140, 0x2071, 0x1800, 0x080c, 0x7857,
+ 0x0005, 0x0006, 0x2001, 0x0090, 0x080c, 0x2d52, 0x000e, 0x6124,
+ 0xd1d4, 0x1178, 0xd1cc, 0x1150, 0xd1dc, 0x1128, 0xd1e4, 0x0158,
+ 0x709b, 0x001e, 0x0040, 0x709b, 0x001d, 0x0028, 0x709b, 0x0020,
+ 0x0010, 0x709b, 0x001f, 0x0005, 0x0016, 0x00c6, 0x00d6, 0x00e6,
+ 0x0126, 0x2061, 0x0100, 0x2069, 0x0140, 0x2071, 0x1800, 0x2091,
+ 0x8000, 0x080c, 0x7569, 0x11d8, 0x2001, 0x180c, 0x200c, 0xd1b4,
+ 0x01b0, 0xc1b4, 0x2102, 0x6027, 0x0200, 0x080c, 0x2c7a, 0x6024,
+ 0xd0cc, 0x0148, 0x2001, 0x00a0, 0x080c, 0x2d52, 0x080c, 0x784e,
+ 0x080c, 0x6127, 0x0428, 0x6028, 0xc0cd, 0x602a, 0x0408, 0x080c,
+ 0x7583, 0x0150, 0x080c, 0x757a, 0x1138, 0x2001, 0x0001, 0x080c,
+ 0x283d, 0x080c, 0x7541, 0x00a0, 0x080c, 0x7446, 0x0178, 0x2001,
+ 0x0001, 0x080c, 0x283d, 0x7098, 0x9086, 0x001e, 0x0120, 0x7098,
+ 0x9086, 0x0022, 0x1118, 0x709b, 0x0025, 0x0010, 0x709b, 0x0021,
+ 0x012e, 0x00ee, 0x00de, 0x00ce, 0x001e, 0x0005, 0x0026, 0x2011,
+ 0x73d7, 0x080c, 0x87e3, 0x002e, 0x0016, 0x0026, 0x2009, 0x0064,
+ 0x2011, 0x73d7, 0x080c, 0x87da, 0x002e, 0x001e, 0x0005, 0x00e6,
+ 0x00f6, 0x0016, 0x080c, 0xa517, 0x2071, 0x1800, 0x080c, 0x7374,
+ 0x001e, 0x00fe, 0x00ee, 0x0005, 0x0016, 0x0026, 0x0036, 0x00c6,
+ 0x00d6, 0x00e6, 0x00f6, 0x0126, 0x2071, 0x1800, 0x080c, 0xa517,
+ 0x2061, 0x0100, 0x2069, 0x0140, 0x2091, 0x8000, 0x6028, 0xc09c,
+ 0x602a, 0x2011, 0x0003, 0x080c, 0xa8ed, 0x2011, 0x0002, 0x080c,
+ 0xa8f7, 0x080c, 0xa801, 0x080c, 0x878f, 0x0036, 0x901e, 0x080c,
+ 0xa877, 0x003e, 0x60e3, 0x0000, 0x080c, 0xedfa, 0x080c, 0xee15,
+ 0x2009, 0x0004, 0x080c, 0x2c80, 0x080c, 0x2b9b, 0x2001, 0x1800,
+ 0x2003, 0x0004, 0x6027, 0x0008, 0x2011, 0x73d7, 0x080c, 0x87e3,
+ 0x080c, 0x7583, 0x0118, 0x9006, 0x080c, 0x2d52, 0x080c, 0x0ba0,
+ 0x2001, 0x0001, 0x080c, 0x283d, 0x012e, 0x00fe, 0x00ee, 0x00de,
+ 0x00ce, 0x003e, 0x002e, 0x001e, 0x0005, 0x0026, 0x00e6, 0x2011,
+ 0x73e4, 0x2071, 0x19fc, 0x701c, 0x9206, 0x1118, 0x7018, 0x9005,
+ 0x0110, 0x9085, 0x0001, 0x00ee, 0x002e, 0x0005, 0x6020, 0xd09c,
+ 0x0005, 0x6800, 0x9084, 0xfffe, 0x9086, 0x00c0, 0x01b8, 0x2001,
+ 0x00c0, 0x080c, 0x2d52, 0x0156, 0x20a9, 0x002d, 0x1d04, 0x7456,
+ 0x2091, 0x6000, 0x1f04, 0x7456, 0x015e, 0x00d6, 0x2069, 0x1800,
+ 0x689c, 0x8001, 0x0220, 0x0118, 0x689e, 0x00de, 0x0005, 0x689f,
+ 0x0014, 0x68e8, 0xd0dc, 0x0dc8, 0x6800, 0x9086, 0x0001, 0x1da8,
+ 0x080c, 0x87ef, 0x0c90, 0x00c6, 0x00d6, 0x00e6, 0x2061, 0x0100,
+ 0x2069, 0x0140, 0x2071, 0x1800, 0x080c, 0x785d, 0x2001, 0x196e,
+ 0x2003, 0x0000, 0x9006, 0x709a, 0x60e2, 0x6886, 0x080c, 0x2908,
+ 0x9006, 0x080c, 0x2d52, 0x080c, 0x5fe6, 0x6027, 0xffff, 0x602b,
+ 0x182f, 0x00ee, 0x00de, 0x00ce, 0x0005, 0x00c6, 0x00d6, 0x00e6,
+ 0x2061, 0x0100, 0x2069, 0x0140, 0x2071, 0x1800, 0x2001, 0x197e,
+ 0x200c, 0x9186, 0x0000, 0x0158, 0x9186, 0x0001, 0x0158, 0x9186,
+ 0x0002, 0x0158, 0x9186, 0x0003, 0x0158, 0x0804, 0x7531, 0x709b,
+ 0x0022, 0x0040, 0x709b, 0x0021, 0x0028, 0x709b, 0x0023, 0x0010,
+ 0x709b, 0x0024, 0x60e3, 0x0000, 0x6887, 0x0001, 0x2001, 0x0001,
+ 0x080c, 0x2908, 0x0026, 0x080c, 0xb072, 0x002e, 0x7000, 0x908e,
+ 0x0004, 0x0118, 0x602b, 0x0028, 0x0010, 0x602b, 0x0020, 0x0156,
+ 0x0126, 0x2091, 0x8000, 0x20a9, 0x0005, 0x6024, 0xd0ac, 0x0150,
+ 0x012e, 0x015e, 0x080c, 0xd561, 0x0118, 0x9006, 0x080c, 0x2d7c,
+ 0x0804, 0x753d, 0x6800, 0x9084, 0x00a1, 0xc0bd, 0x6802, 0x080c,
+ 0x2c7a, 0x6904, 0xd1d4, 0x1140, 0x2001, 0x0100, 0x080c, 0x2d52,
+ 0x1f04, 0x74d5, 0x080c, 0x75bd, 0x012e, 0x015e, 0x080c, 0x757a,
+ 0x01d8, 0x6044, 0x9005, 0x0198, 0x2011, 0x0114, 0x2204, 0x9085,
+ 0x0100, 0x2012, 0x6050, 0x0006, 0x9085, 0x0020, 0x6052, 0x080c,
+ 0x75bd, 0x9006, 0x8001, 0x1df0, 0x000e, 0x6052, 0x0028, 0x6804,
+ 0xd0d4, 0x1110, 0x080c, 0x75bd, 0x080c, 0xd561, 0x0118, 0x9006,
+ 0x080c, 0x2d7c, 0x0016, 0x0026, 0x7000, 0x908e, 0x0004, 0x0130,
+ 0x2009, 0x00c8, 0x2011, 0x73e4, 0x080c, 0x87a1, 0x002e, 0x001e,
+ 0x080c, 0x85e8, 0x7034, 0xc085, 0x7036, 0x2001, 0x197e, 0x2003,
+ 0x0004, 0x080c, 0x7227, 0x080c, 0x757a, 0x0138, 0x6804, 0xd0d4,
+ 0x1120, 0xd0dc, 0x1100, 0x080c, 0x7853, 0x00ee, 0x00de, 0x00ce,
+ 0x0005, 0x00c6, 0x00d6, 0x00e6, 0x2061, 0x0100, 0x2069, 0x0140,
+ 0x2071, 0x1800, 0x080c, 0x85ff, 0x080c, 0x85f1, 0x080c, 0x785d,
0x2001, 0x196e, 0x2003, 0x0000, 0x9006, 0x709a, 0x60e2, 0x6886,
- 0x080c, 0x28fd, 0x9006, 0x080c, 0x2d5b, 0x080c, 0x5fe0, 0x6027,
- 0xffff, 0x602b, 0x182f, 0x00ee, 0x00de, 0x00ce, 0x0005, 0x00c6,
- 0x00d6, 0x00e6, 0x2061, 0x0100, 0x2069, 0x0140, 0x2071, 0x1800,
- 0x2001, 0x197e, 0x200c, 0x9186, 0x0000, 0x0158, 0x9186, 0x0001,
- 0x0158, 0x9186, 0x0002, 0x0158, 0x9186, 0x0003, 0x0158, 0x0804,
- 0x752b, 0x709b, 0x0022, 0x0040, 0x709b, 0x0021, 0x0028, 0x709b,
- 0x0023, 0x0010, 0x709b, 0x0024, 0x60e3, 0x0000, 0x6887, 0x0001,
- 0x2001, 0x0001, 0x080c, 0x28fd, 0x0026, 0x080c, 0xb058, 0x002e,
- 0x7000, 0x908e, 0x0004, 0x0118, 0x602b, 0x0028, 0x0010, 0x602b,
- 0x0020, 0x0156, 0x0126, 0x2091, 0x8000, 0x20a9, 0x0005, 0x6024,
- 0xd0ac, 0x0150, 0x012e, 0x015e, 0x080c, 0xd548, 0x0118, 0x9006,
- 0x080c, 0x2d85, 0x0804, 0x7537, 0x6800, 0x9084, 0x00a1, 0xc0bd,
- 0x6802, 0x080c, 0x2c83, 0x6904, 0xd1d4, 0x1140, 0x2001, 0x0100,
- 0x080c, 0x2d5b, 0x1f04, 0x74cf, 0x080c, 0x75b7, 0x012e, 0x015e,
- 0x080c, 0x7574, 0x01d8, 0x6044, 0x9005, 0x0198, 0x2011, 0x0114,
- 0x2204, 0x9085, 0x0100, 0x2012, 0x6050, 0x0006, 0x9085, 0x0020,
- 0x6052, 0x080c, 0x75b7, 0x9006, 0x8001, 0x1df0, 0x000e, 0x6052,
- 0x0028, 0x6804, 0xd0d4, 0x1110, 0x080c, 0x75b7, 0x080c, 0xd548,
- 0x0118, 0x9006, 0x080c, 0x2d85, 0x0016, 0x0026, 0x7000, 0x908e,
- 0x0004, 0x0130, 0x2009, 0x00c8, 0x2011, 0x73de, 0x080c, 0x879b,
- 0x002e, 0x001e, 0x080c, 0x85e2, 0x7034, 0xc085, 0x7036, 0x2001,
- 0x197e, 0x2003, 0x0004, 0x080c, 0x7221, 0x080c, 0x7574, 0x0138,
- 0x6804, 0xd0d4, 0x1120, 0xd0dc, 0x1100, 0x080c, 0x784d, 0x00ee,
- 0x00de, 0x00ce, 0x0005, 0x00c6, 0x00d6, 0x00e6, 0x2061, 0x0100,
- 0x2069, 0x0140, 0x2071, 0x1800, 0x080c, 0x85f9, 0x080c, 0x85eb,
- 0x080c, 0x7857, 0x2001, 0x196e, 0x2003, 0x0000, 0x9006, 0x709a,
- 0x60e2, 0x6886, 0x080c, 0x28fd, 0x9006, 0x080c, 0x2d5b, 0x6043,
- 0x0090, 0x6043, 0x0010, 0x6027, 0xffff, 0x602b, 0x182f, 0x00ee,
- 0x00de, 0x00ce, 0x0005, 0x0006, 0x2001, 0x197d, 0x2004, 0x9086,
- 0xaaaa, 0x000e, 0x0005, 0x0006, 0x080c, 0x57d1, 0x9084, 0x0030,
- 0x9086, 0x0000, 0x000e, 0x0005, 0x0006, 0x080c, 0x57d1, 0x9084,
- 0x0030, 0x9086, 0x0030, 0x000e, 0x0005, 0x0006, 0x080c, 0x57d1,
- 0x9084, 0x0030, 0x9086, 0x0010, 0x000e, 0x0005, 0x0006, 0x080c,
- 0x57d1, 0x9084, 0x0030, 0x9086, 0x0020, 0x000e, 0x0005, 0x0036,
- 0x0016, 0x2001, 0x180c, 0x2004, 0x908c, 0x0013, 0x0168, 0x0020,
- 0x080c, 0x291d, 0x900e, 0x0010, 0x2009, 0x0002, 0x2019, 0x0028,
- 0x080c, 0x3216, 0x9006, 0x0019, 0x001e, 0x003e, 0x0005, 0x00e6,
- 0x2071, 0x180c, 0x2e04, 0x0130, 0x080c, 0xd541, 0x1128, 0x9085,
- 0x0010, 0x0010, 0x9084, 0xffef, 0x2072, 0x00ee, 0x0005, 0x6050,
- 0x0006, 0x60ec, 0x0006, 0x600c, 0x0006, 0x6004, 0x0006, 0x6028,
- 0x0006, 0x0016, 0x6138, 0x6050, 0x9084, 0xfbff, 0x9085, 0x2000,
- 0x6052, 0x613a, 0x20a9, 0x0012, 0x1d04, 0x75cc, 0x2091, 0x6000,
- 0x1f04, 0x75cc, 0x602f, 0x0100, 0x602f, 0x0000, 0x6050, 0x9085,
- 0x0400, 0x9084, 0xdfff, 0x6052, 0x613a, 0x001e, 0x602f, 0x0040,
- 0x602f, 0x0000, 0x000e, 0x602a, 0x000e, 0x6006, 0x000e, 0x600e,
- 0x000e, 0x60ee, 0x60e3, 0x0000, 0x6887, 0x0001, 0x2001, 0x0001,
- 0x080c, 0x28fd, 0x2001, 0x00a0, 0x0006, 0x080c, 0xd548, 0x000e,
- 0x0130, 0x080c, 0x2d79, 0x9006, 0x080c, 0x2d85, 0x0010, 0x080c,
- 0x2d5b, 0x000e, 0x6052, 0x6050, 0x0006, 0xc0e5, 0x6052, 0x00f6,
- 0x2079, 0x0100, 0x080c, 0x2bf8, 0x00fe, 0x000e, 0x6052, 0x0005,
- 0x0156, 0x0016, 0x0026, 0x0036, 0x00c6, 0x00d6, 0x00e6, 0x2061,
- 0x0100, 0x2069, 0x0140, 0x2071, 0x1800, 0x6020, 0x9084, 0x0080,
- 0x0138, 0x2001, 0x180c, 0x200c, 0xc1c5, 0x2102, 0x0804, 0x768a,
- 0x2001, 0x180c, 0x200c, 0xc1c4, 0x2102, 0x6028, 0x9084, 0xe1ff,
- 0x602a, 0x6027, 0x0200, 0x2001, 0x0090, 0x080c, 0x2d5b, 0x20a9,
- 0x0366, 0x6024, 0xd0cc, 0x1518, 0x1d04, 0x7639, 0x2091, 0x6000,
- 0x1f04, 0x7639, 0x2011, 0x0003, 0x080c, 0xa8d3, 0x2011, 0x0002,
- 0x080c, 0xa8dd, 0x080c, 0xa7e7, 0x901e, 0x080c, 0xa85d, 0x2001,
- 0x00a0, 0x080c, 0x2d5b, 0x080c, 0x7848, 0x080c, 0x6121, 0x080c,
- 0xd548, 0x0110, 0x080c, 0x0d33, 0x9085, 0x0001, 0x0488, 0x080c,
- 0x1b27, 0x60e3, 0x0000, 0x2001, 0x196e, 0x2004, 0x080c, 0x28fd,
- 0x60e2, 0x2001, 0x0080, 0x080c, 0x2d5b, 0x20a9, 0x0366, 0x6027,
- 0x1e00, 0x2009, 0x1e00, 0x080c, 0x2c83, 0x6024, 0x910c, 0x0138,
- 0x1d04, 0x766f, 0x2091, 0x6000, 0x1f04, 0x766f, 0x0818, 0x6028,
- 0x9085, 0x1e00, 0x602a, 0x70b4, 0x9005, 0x1118, 0x6887, 0x0001,
- 0x0008, 0x6886, 0x080c, 0xd548, 0x0110, 0x080c, 0x0d33, 0x9006,
- 0x00ee, 0x00de, 0x00ce, 0x003e, 0x002e, 0x001e, 0x015e, 0x0005,
- 0x0156, 0x0016, 0x0026, 0x0036, 0x00c6, 0x00d6, 0x00e6, 0x2061,
- 0x0100, 0x2071, 0x1800, 0x7000, 0x9086, 0x0003, 0x1168, 0x2001,
- 0x020b, 0x2004, 0x9084, 0x5540, 0x9086, 0x5540, 0x1128, 0x2069,
- 0x1a7d, 0x2d04, 0x8000, 0x206a, 0x2069, 0x0140, 0x6020, 0x9084,
- 0x00c0, 0x0120, 0x6884, 0x9005, 0x1904, 0x76fd, 0x2001, 0x0088,
- 0x080c, 0x2d5b, 0x9006, 0x60e2, 0x6886, 0x080c, 0x28fd, 0x2069,
- 0x0200, 0x6804, 0x9005, 0x1118, 0x6808, 0x9005, 0x01c0, 0x6028,
- 0x9084, 0xfbff, 0x602a, 0x6027, 0x0400, 0x2069, 0x1990, 0x7000,
- 0x206a, 0x709b, 0x0026, 0x7003, 0x0001, 0x20a9, 0x0002, 0x1d04,
- 0x76df, 0x2091, 0x6000, 0x1f04, 0x76df, 0x0804, 0x772d, 0x2069,
- 0x0140, 0x20a9, 0x0384, 0x6027, 0x1e00, 0x2009, 0x1e00, 0x080c,
- 0x2c83, 0x6024, 0x910c, 0x0508, 0x9084, 0x1a00, 0x11f0, 0x1d04,
- 0x76eb, 0x2091, 0x6000, 0x1f04, 0x76eb, 0x2011, 0x0003, 0x080c,
- 0xa8d3, 0x2011, 0x0002, 0x080c, 0xa8dd, 0x080c, 0xa7e7, 0x901e,
- 0x080c, 0xa85d, 0x2001, 0x00a0, 0x080c, 0x2d5b, 0x080c, 0x7848,
- 0x080c, 0x6121, 0x9085, 0x0001, 0x00c0, 0x080c, 0x1b27, 0x2001,
- 0x0080, 0x080c, 0x2d5b, 0x2069, 0x0140, 0x60e3, 0x0000, 0x70b4,
- 0x9005, 0x1118, 0x6887, 0x0001, 0x0008, 0x6886, 0x2001, 0x196e,
- 0x2004, 0x080c, 0x28fd, 0x60e2, 0x9006, 0x00ee, 0x00de, 0x00ce,
- 0x003e, 0x002e, 0x001e, 0x015e, 0x0005, 0x0156, 0x0016, 0x0026,
- 0x0036, 0x00c6, 0x00d6, 0x00e6, 0x2061, 0x0100, 0x2071, 0x1800,
- 0x6020, 0x9084, 0x00c0, 0x01c8, 0x2011, 0x0003, 0x080c, 0xa8d3,
- 0x2011, 0x0002, 0x080c, 0xa8dd, 0x080c, 0xa7e7, 0x901e, 0x080c,
- 0xa85d, 0x2069, 0x0140, 0x2001, 0x00a0, 0x080c, 0x2d5b, 0x080c,
- 0x7848, 0x080c, 0x6121, 0x0804, 0x77c8, 0x2001, 0x180c, 0x200c,
- 0xd1b4, 0x1160, 0xc1b5, 0x2102, 0x080c, 0x73c6, 0x2069, 0x0140,
- 0x2001, 0x0080, 0x080c, 0x2d5b, 0x60e3, 0x0000, 0x2069, 0x0200,
- 0x6804, 0x9005, 0x1118, 0x6808, 0x9005, 0x0180, 0x6028, 0x9084,
- 0xfdff, 0x602a, 0x6027, 0x0200, 0x2069, 0x1990, 0x7000, 0x206a,
- 0x709b, 0x0027, 0x7003, 0x0001, 0x0804, 0x77c8, 0x6027, 0x1e00,
- 0x2009, 0x1e00, 0x080c, 0x2c83, 0x6024, 0x910c, 0x01c8, 0x9084,
- 0x1c00, 0x11b0, 0x1d04, 0x7786, 0x0006, 0x0016, 0x00c6, 0x00d6,
- 0x00e6, 0x080c, 0x863c, 0x00ee, 0x00de, 0x00ce, 0x001e, 0x000e,
- 0x00e6, 0x2071, 0x19fc, 0x7078, 0x00ee, 0x9005, 0x19f8, 0x0400,
- 0x0026, 0x2011, 0x73de, 0x080c, 0x8703, 0x2011, 0x73d1, 0x080c,
- 0x87dd, 0x002e, 0x2069, 0x0140, 0x60e3, 0x0000, 0x70b4, 0x9005,
- 0x1118, 0x6887, 0x0001, 0x0008, 0x6886, 0x2001, 0x196e, 0x2004,
- 0x080c, 0x28fd, 0x60e2, 0x2001, 0x180c, 0x200c, 0xc1b4, 0x2102,
- 0x00ee, 0x00de, 0x00ce, 0x003e, 0x002e, 0x001e, 0x015e, 0x0005,
- 0x0156, 0x0016, 0x0026, 0x0036, 0x0046, 0x00c6, 0x00e6, 0x2061,
- 0x0100, 0x2071, 0x1800, 0x080c, 0xd541, 0x1904, 0x7836, 0x7130,
- 0xd184, 0x1170, 0x080c, 0x33a5, 0x0138, 0xc18d, 0x7132, 0x2011,
- 0x1848, 0x2214, 0xd2ac, 0x1120, 0x7030, 0xd08c, 0x0904, 0x7836,
- 0x2011, 0x1848, 0x220c, 0xd1a4, 0x0538, 0x0016, 0x2019, 0x000e,
- 0x080c, 0xe8b0, 0x0156, 0x00b6, 0x20a9, 0x007f, 0x900e, 0x9186,
- 0x007e, 0x01a0, 0x9186, 0x0080, 0x0188, 0x080c, 0x6717, 0x1170,
- 0x2120, 0x9006, 0x0016, 0x2009, 0x000e, 0x080c, 0xe940, 0x2009,
- 0x0001, 0x2011, 0x0100, 0x080c, 0x8916, 0x001e, 0x8108, 0x1f04,
- 0x77ff, 0x00be, 0x015e, 0x001e, 0xd1ac, 0x1148, 0x0016, 0x2009,
- 0x0002, 0x2019, 0x0004, 0x080c, 0x3216, 0x001e, 0x0078, 0x0156,
- 0x00b6, 0x20a9, 0x007f, 0x900e, 0x080c, 0x6717, 0x1110, 0x080c,
- 0x613b, 0x8108, 0x1f04, 0x782c, 0x00be, 0x015e, 0x080c, 0x1b27,
- 0x080c, 0xb058, 0x60e3, 0x0000, 0x080c, 0x6121, 0x080c, 0x748f,
- 0x00ee, 0x00ce, 0x004e, 0x003e, 0x002e, 0x001e, 0x015e, 0x0005,
- 0x2001, 0x197e, 0x2003, 0x0001, 0x0005, 0x2001, 0x197e, 0x2003,
- 0x0000, 0x0005, 0x2001, 0x197d, 0x2003, 0xaaaa, 0x0005, 0x2001,
- 0x197d, 0x2003, 0x0000, 0x0005, 0x2071, 0x18fa, 0x7003, 0x0000,
- 0x7007, 0x0000, 0x080c, 0x1027, 0x090c, 0x0dc5, 0xa8ab, 0xdcb0,
- 0x2900, 0x704e, 0x080c, 0x1027, 0x090c, 0x0dc5, 0xa8ab, 0xdcb0,
- 0x2900, 0x7052, 0xa867, 0x0000, 0xa86b, 0x0001, 0xa89f, 0x0000,
- 0x0005, 0x00e6, 0x2071, 0x0040, 0x6848, 0x9005, 0x1118, 0x9085,
- 0x0001, 0x04b0, 0x6840, 0x9005, 0x0150, 0x04a1, 0x6a50, 0x9200,
- 0x7002, 0x6854, 0x9101, 0x7006, 0x9006, 0x7012, 0x7016, 0x6850,
- 0x7002, 0x6854, 0x7006, 0x6858, 0x700a, 0x685c, 0x700e, 0x6840,
- 0x9005, 0x1110, 0x7012, 0x7016, 0x6848, 0x701a, 0x701c, 0x9085,
- 0x0040, 0x701e, 0x2001, 0x0019, 0x7036, 0x702b, 0x0001, 0x2001,
- 0x0004, 0x200c, 0x918c, 0xfff7, 0x918d, 0x8000, 0x2102, 0x00d6,
- 0x2069, 0x18fa, 0x6807, 0x0001, 0x00de, 0x080c, 0x7e3a, 0x9006,
- 0x00ee, 0x0005, 0x900e, 0x0156, 0x20a9, 0x0006, 0x8003, 0x2011,
- 0x0100, 0x2214, 0x9296, 0x0008, 0x1110, 0x818d, 0x0010, 0x81f5,
- 0x3e08, 0x1f04, 0x78be, 0x015e, 0x0005, 0x2079, 0x0040, 0x2071,
- 0x18fa, 0x7004, 0x0002, 0x78dd, 0x78de, 0x7916, 0x7971, 0x7a81,
- 0x78db, 0x78db, 0x7aab, 0x080c, 0x0dc5, 0x0005, 0x2079, 0x0040,
- 0x782c, 0x908c, 0x0780, 0x190c, 0x7f1c, 0xd0a4, 0x01f8, 0x7824,
- 0x2048, 0x9006, 0xa802, 0xa806, 0xa864, 0x9084, 0x00ff, 0x908a,
- 0x0040, 0x0610, 0x00c0, 0x2001, 0x1800, 0x200c, 0x9186, 0x0003,
- 0x1168, 0x7004, 0x0002, 0x7906, 0x78e0, 0x7906, 0x7904, 0x7906,
- 0x7906, 0x7906, 0x7906, 0x7906, 0x080c, 0x7971, 0x782c, 0xd09c,
- 0x090c, 0x7e3a, 0x0005, 0x9082, 0x005a, 0x1218, 0x2100, 0x003b,
- 0x0c10, 0x080c, 0x79a7, 0x0c90, 0x00e3, 0x08e8, 0x0005, 0x79a7,
- 0x79a7, 0x79a7, 0x79a7, 0x79a7, 0x79a7, 0x79a7, 0x79a7, 0x79c9,
- 0x79a7, 0x79a7, 0x79a7, 0x79a7, 0x79a7, 0x79a7, 0x79a7, 0x79a7,
- 0x79a7, 0x79a7, 0x79a7, 0x79a7, 0x79a7, 0x79a7, 0x79a7, 0x79a7,
- 0x79a7, 0x79a7, 0x79a7, 0x79b3, 0x79a7, 0x7ba1, 0x79a7, 0x79a7,
- 0x79a7, 0x79c9, 0x79a7, 0x79b3, 0x7be2, 0x7c23, 0x7c6a, 0x7c7e,
- 0x79a7, 0x79a7, 0x79c9, 0x79b3, 0x79dd, 0x79a7, 0x7a55, 0x7d29,
- 0x7d44, 0x79a7, 0x79c9, 0x79a7, 0x79dd, 0x79a7, 0x79a7, 0x7a4b,
- 0x7d44, 0x79a7, 0x79a7, 0x79a7, 0x79a7, 0x79a7, 0x79a7, 0x79a7,
- 0x79a7, 0x79a7, 0x79f1, 0x79a7, 0x79a7, 0x79a7, 0x79a7, 0x79a7,
- 0x79a7, 0x79a7, 0x79a7, 0x79a7, 0x7ec0, 0x79a7, 0x7e6a, 0x79a7,
- 0x7e6a, 0x79a7, 0x7a06, 0x79a7, 0x79a7, 0x79a7, 0x79a7, 0x79a7,
- 0x79a7, 0x2079, 0x0040, 0x7004, 0x9086, 0x0003, 0x1198, 0x782c,
- 0x080c, 0x7e63, 0xd0a4, 0x0170, 0x7824, 0x2048, 0x9006, 0xa802,
- 0xa806, 0xa864, 0x9084, 0x00ff, 0x908a, 0x001a, 0x1210, 0x002b,
- 0x0c50, 0x00e9, 0x080c, 0x7e3a, 0x0005, 0x79a7, 0x79b3, 0x7b8d,
- 0x79a7, 0x79b3, 0x79a7, 0x79b3, 0x79b3, 0x79a7, 0x79b3, 0x7b8d,
- 0x79b3, 0x79b3, 0x79b3, 0x79b3, 0x79b3, 0x79a7, 0x79b3, 0x7b8d,
- 0x79a7, 0x79a7, 0x79b3, 0x79a7, 0x79a7, 0x79a7, 0x79b3, 0x00e6,
- 0x2071, 0x18fa, 0x2009, 0x0400, 0x0071, 0x00ee, 0x0005, 0x2009,
- 0x1000, 0x0049, 0x0005, 0x2009, 0x2000, 0x0029, 0x0005, 0x2009,
- 0x0800, 0x0009, 0x0005, 0x7007, 0x0001, 0xa868, 0x9084, 0x00ff,
- 0x9105, 0xa86a, 0x0126, 0x2091, 0x8000, 0x080c, 0x6dcb, 0x012e,
- 0x0005, 0xa864, 0x8007, 0x9084, 0x00ff, 0x0d08, 0x8001, 0x1120,
- 0x7007, 0x0001, 0x0804, 0x7b2a, 0x7007, 0x0003, 0x7012, 0x2900,
- 0x7016, 0x701a, 0x704b, 0x7b2a, 0x0005, 0xa864, 0x8007, 0x9084,
- 0x00ff, 0x0968, 0x8001, 0x1120, 0x7007, 0x0001, 0x0804, 0x7b45,
- 0x7007, 0x0003, 0x7012, 0x2900, 0x7016, 0x701a, 0x704b, 0x7b45,
- 0x0005, 0xa864, 0x8007, 0x9084, 0x00ff, 0x0904, 0x79af, 0x8001,
- 0x1120, 0x7007, 0x0001, 0x0804, 0x7b61, 0x7007, 0x0003, 0x7012,
- 0x2900, 0x7016, 0x701a, 0x704b, 0x7b61, 0x0005, 0xa864, 0x8007,
- 0x9084, 0x00ff, 0x9086, 0x0001, 0x1904, 0x79af, 0x7007, 0x0001,
- 0x2009, 0x1834, 0x210c, 0x81ff, 0x11a8, 0xa868, 0x9084, 0x00ff,
- 0xa86a, 0xa883, 0x0000, 0x080c, 0x63b8, 0x1108, 0x0005, 0x0126,
- 0x2091, 0x8000, 0xa867, 0x0139, 0xa87a, 0xa982, 0x080c, 0x6dcb,
- 0x012e, 0x0ca0, 0xa994, 0x9186, 0x0071, 0x0d38, 0x9186, 0x0064,
- 0x0d20, 0x9186, 0x007c, 0x0d08, 0x9186, 0x0028, 0x09f0, 0x9186,
- 0x0038, 0x09d8, 0x9186, 0x0078, 0x09c0, 0x9186, 0x005f, 0x09a8,
- 0x9186, 0x0056, 0x0990, 0xa897, 0x4005, 0xa89b, 0x0001, 0x2001,
- 0x0030, 0x900e, 0x08a0, 0xa87c, 0x9084, 0x00c0, 0x9086, 0x00c0,
- 0x1120, 0x7007, 0x0001, 0x0804, 0x7d5b, 0x2900, 0x7016, 0x701a,
- 0x20a9, 0x0004, 0xa860, 0x20e0, 0xa85c, 0x9080, 0x0030, 0x2098,
- 0x7050, 0x2040, 0xa060, 0x20e8, 0xa05c, 0x9080, 0x0023, 0x20a0,
- 0x4003, 0xa888, 0x7012, 0x9082, 0x0401, 0x1a04, 0x79b7, 0xaab4,
- 0x928a, 0x0002, 0x1a04, 0x79b7, 0x82ff, 0x1138, 0xa8b8, 0xa9bc,
- 0x9105, 0x0118, 0x2001, 0x7ae8, 0x0018, 0x9280, 0x7ade, 0x2005,
- 0x7056, 0x7010, 0x9015, 0x0904, 0x7ac9, 0x080c, 0x1027, 0x1118,
- 0x7007, 0x0004, 0x0005, 0x2900, 0x7022, 0x7054, 0x2060, 0xe000,
- 0xa866, 0x7050, 0x2040, 0xa95c, 0xe004, 0x9100, 0xa076, 0xa860,
- 0xa072, 0xe008, 0x920a, 0x1210, 0x900e, 0x2200, 0x7112, 0xe20c,
- 0x8003, 0x800b, 0x9296, 0x0004, 0x0108, 0x9108, 0xa17a, 0x810b,
- 0xa17e, 0x080c, 0x10f8, 0xa06c, 0x908e, 0x0100, 0x0170, 0x9086,
- 0x0200, 0x0118, 0x7007, 0x0007, 0x0005, 0x7020, 0x2048, 0x080c,
- 0x1040, 0x7014, 0x2048, 0x0804, 0x79b7, 0x7020, 0x2048, 0x7018,
- 0xa802, 0xa807, 0x0000, 0x2908, 0x2048, 0xa906, 0x711a, 0x0804,
- 0x7a81, 0x7014, 0x2048, 0x7007, 0x0001, 0xa8b4, 0x9005, 0x1128,
- 0xa8b8, 0xa9bc, 0x9105, 0x0108, 0x00b9, 0xa864, 0x9084, 0x00ff,
- 0x9086, 0x001e, 0x0904, 0x7d5b, 0x0804, 0x7b2a, 0x7ae0, 0x7ae4,
- 0x0002, 0x001d, 0x0007, 0x0004, 0x000a, 0x001b, 0x0005, 0x0006,
- 0x000a, 0x001d, 0x0005, 0x0004, 0x0076, 0x0066, 0xafb8, 0xaebc,
- 0xa804, 0x2050, 0xb0c0, 0xb0e2, 0xb0bc, 0xb0de, 0xb0b8, 0xb0d2,
- 0xb0b4, 0xb0ce, 0xb6da, 0xb7d6, 0xb0b0, 0xb0ca, 0xb0ac, 0xb0c6,
- 0xb0a8, 0xb0ba, 0xb0a4, 0xb0b6, 0xb6c2, 0xb7be, 0xb0a0, 0xb0b2,
- 0xb09c, 0xb0ae, 0xb098, 0xb0a2, 0xb094, 0xb09e, 0xb6aa, 0xb7a6,
- 0xb090, 0xb09a, 0xb08c, 0xb096, 0xb088, 0xb08a, 0xb084, 0xb086,
- 0xb692, 0xb78e, 0xb080, 0xb082, 0xb07c, 0xb07e, 0xb078, 0xb072,
- 0xb074, 0xb06e, 0xb67a, 0xb776, 0xb004, 0x9055, 0x1958, 0x006e,
- 0x007e, 0x0005, 0x2009, 0x1834, 0x210c, 0x81ff, 0x1178, 0x080c,
- 0x61b5, 0x1108, 0x0005, 0x080c, 0x7037, 0x0126, 0x2091, 0x8000,
- 0x080c, 0xd135, 0x080c, 0x6dcb, 0x012e, 0x0ca0, 0x080c, 0xd541,
- 0x1d70, 0x2001, 0x0028, 0x900e, 0x0c70, 0x2009, 0x1834, 0x210c,
- 0x81ff, 0x1188, 0xa888, 0x9005, 0x0188, 0xa883, 0x0000, 0x080c,
- 0x6245, 0x1108, 0x0005, 0xa87a, 0x0126, 0x2091, 0x8000, 0x080c,
- 0x6dcb, 0x012e, 0x0cb8, 0x2001, 0x0028, 0x0ca8, 0x2001, 0x0000,
- 0x0c90, 0x0419, 0x11d8, 0xa888, 0x9005, 0x01e0, 0xa883, 0x0000,
- 0xa87c, 0xd0f4, 0x0120, 0x080c, 0x631a, 0x1138, 0x0005, 0x9006,
- 0xa87a, 0x080c, 0x6292, 0x1108, 0x0005, 0x0126, 0x2091, 0x8000,
- 0xa87a, 0xa982, 0x080c, 0x6dcb, 0x012e, 0x0cb0, 0x2001, 0x0028,
- 0x900e, 0x0c98, 0x2001, 0x0000, 0x0c80, 0x00c6, 0x2061, 0x1800,
- 0x60d0, 0x9005, 0x0100, 0x00ce, 0x0005, 0x7018, 0xa802, 0x2908,
- 0x2048, 0xa906, 0x711a, 0x7010, 0x8001, 0x7012, 0x0118, 0x7007,
- 0x0003, 0x0030, 0x7014, 0x2048, 0x7007, 0x0001, 0x7048, 0x080f,
- 0x0005, 0x00b6, 0x7007, 0x0001, 0xa974, 0xa878, 0x9084, 0x00ff,
- 0x9096, 0x0004, 0x0540, 0x20a9, 0x0001, 0x9096, 0x0001, 0x0190,
- 0x900e, 0x20a9, 0x0800, 0x9096, 0x0002, 0x0160, 0x9005, 0x11d8,
- 0xa974, 0x080c, 0x6717, 0x11b8, 0x0066, 0xae80, 0x080c, 0x6827,
- 0x006e, 0x0088, 0x0046, 0x2011, 0x180c, 0x2224, 0xc484, 0x2412,
- 0x004e, 0x00c6, 0x080c, 0x6717, 0x1110, 0x080c, 0x6927, 0x8108,
- 0x1f04, 0x7bca, 0x00ce, 0xa87c, 0xd084, 0x1120, 0x080c, 0x1040,
- 0x00be, 0x0005, 0x0126, 0x2091, 0x8000, 0x080c, 0x6dcb, 0x012e,
- 0x00be, 0x0005, 0x0126, 0x2091, 0x8000, 0x7007, 0x0001, 0x080c,
- 0x6a88, 0x0580, 0x2061, 0x1a75, 0x6100, 0xd184, 0x0178, 0xa888,
- 0x9084, 0x00ff, 0x1550, 0x6000, 0xd084, 0x0520, 0x6004, 0x9005,
- 0x1538, 0x6003, 0x0000, 0x600b, 0x0000, 0x00c8, 0x2011, 0x0001,
- 0xa890, 0x9005, 0x1110, 0x2001, 0x001e, 0x8000, 0x6016, 0xa888,
- 0x9084, 0x00ff, 0x0178, 0x6006, 0xa888, 0x8007, 0x9084, 0x00ff,
- 0x0148, 0x600a, 0xa888, 0x8000, 0x1108, 0xc28d, 0x6202, 0x012e,
- 0x0804, 0x7e24, 0x012e, 0x0804, 0x7e1e, 0x012e, 0x0804, 0x7e18,
- 0x012e, 0x0804, 0x7e1b, 0x0126, 0x2091, 0x8000, 0x7007, 0x0001,
- 0x080c, 0x6a88, 0x05e0, 0x2061, 0x1a75, 0x6000, 0xd084, 0x05b8,
- 0x6204, 0x6308, 0xd08c, 0x1530, 0xac78, 0x9484, 0x0003, 0x0170,
- 0xa988, 0x918c, 0x00ff, 0x8001, 0x1120, 0x2100, 0x9210, 0x0620,
- 0x0028, 0x8001, 0x1508, 0x2100, 0x9212, 0x02f0, 0x9484, 0x000c,
- 0x0188, 0xa988, 0x810f, 0x918c, 0x00ff, 0x9082, 0x0004, 0x1120,
- 0x2100, 0x9318, 0x0288, 0x0030, 0x9082, 0x0004, 0x1168, 0x2100,
- 0x931a, 0x0250, 0xa890, 0x9005, 0x0110, 0x8000, 0x6016, 0x6206,
- 0x630a, 0x012e, 0x0804, 0x7e24, 0x012e, 0x0804, 0x7e21, 0x012e,
- 0x0804, 0x7e1e, 0x0126, 0x2091, 0x8000, 0x7007, 0x0001, 0x2061,
- 0x1a75, 0x6300, 0xd38c, 0x1120, 0x6308, 0x8318, 0x0220, 0x630a,
- 0x012e, 0x0804, 0x7e32, 0x012e, 0x0804, 0x7e21, 0x00b6, 0x0126,
- 0x00c6, 0x2091, 0x8000, 0x7007, 0x0001, 0xa87c, 0xd0ac, 0x0148,
- 0x00c6, 0x2061, 0x1a75, 0x6000, 0x9084, 0xfcff, 0x6002, 0x00ce,
- 0x0440, 0xa888, 0x9005, 0x05d8, 0xa88c, 0x9065, 0x0598, 0x2001,
- 0x1834, 0x2004, 0x9005, 0x0118, 0x080c, 0xb11a, 0x0068, 0x6017,
- 0xf400, 0x605b, 0x0000, 0xa97c, 0xd1a4, 0x0110, 0xa980, 0x615a,
- 0x2009, 0x0041, 0x080c, 0xb166, 0xa988, 0x918c, 0xff00, 0x9186,
- 0x2000, 0x1138, 0x0026, 0x900e, 0x2011, 0xfdff, 0x080c, 0x8916,
- 0x002e, 0xa87c, 0xd0c4, 0x0148, 0x2061, 0x1a75, 0x6000, 0xd08c,
- 0x1120, 0x6008, 0x8000, 0x0208, 0x600a, 0x00ce, 0x012e, 0x00be,
- 0x0804, 0x7e24, 0x00ce, 0x012e, 0x00be, 0x0804, 0x7e1e, 0xa984,
- 0x9186, 0x002e, 0x0d30, 0x9186, 0x002d, 0x0d18, 0x9186, 0x0045,
- 0x0510, 0x9186, 0x002a, 0x1130, 0x2001, 0x180c, 0x200c, 0xc194,
- 0x2102, 0x08b8, 0x9186, 0x0020, 0x0158, 0x9186, 0x0029, 0x1d10,
- 0xa974, 0x080c, 0x6717, 0x1968, 0xb800, 0xc0e4, 0xb802, 0x0848,
- 0xa88c, 0x9065, 0x09b8, 0x6007, 0x0024, 0x2001, 0x1987, 0x2004,
- 0x601a, 0x0804, 0x7cb9, 0xa88c, 0x9065, 0x0960, 0x00e6, 0xa890,
- 0x9075, 0x2001, 0x1834, 0x2004, 0x9005, 0x0150, 0x080c, 0xb11a,
- 0x8eff, 0x0118, 0x2e60, 0x080c, 0xb11a, 0x00ee, 0x0804, 0x7cb9,
- 0x6024, 0xc0dc, 0xc0d5, 0x6026, 0x2e60, 0x6007, 0x003a, 0xa8a0,
- 0x9005, 0x0130, 0x6007, 0x003b, 0xa8a4, 0x602e, 0xa8a8, 0x6016,
- 0x6003, 0x0001, 0x080c, 0x9335, 0x080c, 0x98e7, 0x00ee, 0x0804,
- 0x7cb9, 0x2061, 0x1a75, 0x6000, 0xd084, 0x0190, 0xd08c, 0x1904,
- 0x7e32, 0x0126, 0x2091, 0x8000, 0x6204, 0x8210, 0x0220, 0x6206,
- 0x012e, 0x0804, 0x7e32, 0x012e, 0xa883, 0x0016, 0x0804, 0x7e2b,
- 0xa883, 0x0007, 0x0804, 0x7e2b, 0xa864, 0x8007, 0x9084, 0x00ff,
- 0x0130, 0x8001, 0x1138, 0x7007, 0x0001, 0x0069, 0x0005, 0x080c,
- 0x79af, 0x0040, 0x7007, 0x0003, 0x7012, 0x2900, 0x7016, 0x701a,
- 0x704b, 0x7d5b, 0x0005, 0x00b6, 0x00e6, 0x0126, 0x2091, 0x8000,
- 0x903e, 0x2061, 0x1800, 0x61d0, 0x81ff, 0x1904, 0x7ddd, 0x6130,
- 0xd194, 0x1904, 0x7e07, 0xa878, 0x2070, 0x9e82, 0x1cd0, 0x0a04,
- 0x7dd1, 0x6068, 0x9e02, 0x1a04, 0x7dd1, 0x7120, 0x9186, 0x0006,
- 0x1904, 0x7dc3, 0x7010, 0x905d, 0x0904, 0x7ddd, 0xb800, 0xd0e4,
- 0x1904, 0x7e01, 0x2061, 0x1a75, 0x6100, 0x9184, 0x0301, 0x9086,
- 0x0001, 0x15a0, 0x7024, 0xd0dc, 0x1904, 0x7e0a, 0xa883, 0x0000,
- 0xa803, 0x0000, 0x2908, 0x7014, 0x9005, 0x1198, 0x7116, 0xa87c,
- 0xd0f4, 0x1904, 0x7e0d, 0x080c, 0x57cd, 0xd09c, 0x1118, 0xa87c,
- 0xc0cc, 0xa87e, 0x2e60, 0x080c, 0x8836, 0x012e, 0x00ee, 0x00be,
- 0x0005, 0x2048, 0xa800, 0x9005, 0x1de0, 0xa902, 0x2148, 0xa87c,
- 0xd0f4, 0x1904, 0x7e0d, 0x012e, 0x00ee, 0x00be, 0x0005, 0x012e,
- 0x00ee, 0xa883, 0x0006, 0x00be, 0x0804, 0x7e2b, 0xd184, 0x0db8,
- 0xd1c4, 0x1190, 0x00a0, 0xa974, 0x080c, 0x6717, 0x15d0, 0xb800,
- 0xd0e4, 0x15b8, 0x7120, 0x9186, 0x0007, 0x1118, 0xa883, 0x0002,
- 0x0490, 0xa883, 0x0008, 0x0478, 0xa883, 0x000e, 0x0460, 0xa883,
- 0x0017, 0x0448, 0xa883, 0x0035, 0x0430, 0x080c, 0x57d1, 0xd0fc,
- 0x01e8, 0xa878, 0x2070, 0x9e82, 0x1cd0, 0x02c0, 0x6068, 0x9e02,
- 0x12a8, 0x7120, 0x9186, 0x0006, 0x1188, 0x7010, 0x905d, 0x0170,
- 0xb800, 0xd0bc, 0x0158, 0x2039, 0x0001, 0x7000, 0x9086, 0x0007,
- 0x1904, 0x7d67, 0x7003, 0x0002, 0x0804, 0x7d67, 0xa883, 0x0028,
- 0x0010, 0xa883, 0x0029, 0x012e, 0x00ee, 0x00be, 0x0420, 0xa883,
- 0x002a, 0x0cc8, 0xa883, 0x0045, 0x0cb0, 0x2e60, 0x2019, 0x0002,
- 0x601b, 0x0014, 0x080c, 0xe4ba, 0x012e, 0x00ee, 0x00be, 0x0005,
- 0x2009, 0x003e, 0x0058, 0x2009, 0x0004, 0x0040, 0x2009, 0x0006,
- 0x0028, 0x2009, 0x0016, 0x0010, 0x2009, 0x0001, 0xa884, 0x9084,
- 0xff00, 0x9105, 0xa886, 0x0126, 0x2091, 0x8000, 0x080c, 0x6dcb,
- 0x012e, 0x0005, 0x080c, 0x1040, 0x0005, 0x00d6, 0x080c, 0x882d,
- 0x00de, 0x0005, 0x00d6, 0x00e6, 0x0126, 0x2091, 0x8000, 0x2071,
- 0x0040, 0x702c, 0xd084, 0x01d8, 0x908c, 0x0780, 0x190c, 0x7f1c,
- 0xd09c, 0x11a8, 0x2071, 0x1800, 0x70c0, 0x90ea, 0x0020, 0x0278,
- 0x8001, 0x70c2, 0x702c, 0x2048, 0xa800, 0x702e, 0x9006, 0xa802,
- 0xa806, 0x2071, 0x0040, 0x2900, 0x7022, 0x702c, 0x0c28, 0x012e,
- 0x00ee, 0x00de, 0x0005, 0x0006, 0x9084, 0x0780, 0x190c, 0x7f1c,
- 0x000e, 0x0005, 0xa898, 0x9084, 0x0003, 0x05a8, 0x080c, 0xb091,
- 0x05d8, 0x2900, 0x6016, 0xa864, 0x9084, 0x00ff, 0x9086, 0x0035,
- 0x1138, 0x6008, 0xc0fd, 0x600a, 0x2001, 0x196c, 0x2004, 0x0098,
- 0xa8a0, 0x9084, 0x00ff, 0xa99c, 0x918c, 0xff00, 0x9105, 0xa99c,
- 0x918c, 0x00ff, 0x080c, 0x2889, 0x1540, 0x00b6, 0x080c, 0x6717,
- 0x2b00, 0x00be, 0x1510, 0x6012, 0x6023, 0x0001, 0x2009, 0x0040,
- 0xa864, 0x9084, 0x00ff, 0x9086, 0x0035, 0x0110, 0x2009, 0x0041,
- 0x080c, 0xb166, 0x0005, 0xa87b, 0x0101, 0x0126, 0x2091, 0x8000,
- 0x080c, 0x6dcb, 0x012e, 0x0005, 0xa87b, 0x002c, 0x0126, 0x2091,
- 0x8000, 0x080c, 0x6dcb, 0x012e, 0x0005, 0xa87b, 0x0028, 0x0126,
- 0x2091, 0x8000, 0x080c, 0x6dcb, 0x012e, 0x080c, 0xb0e7, 0x0005,
- 0x00d6, 0x00c6, 0x0036, 0x0026, 0x0016, 0x00b6, 0x7007, 0x0001,
- 0xaa74, 0x9282, 0x0004, 0x1a04, 0x7f0d, 0xa97c, 0x9188, 0x1000,
- 0x2104, 0x905d, 0xb804, 0xd284, 0x0140, 0x05e8, 0x8007, 0x9084,
- 0x00ff, 0x9084, 0x0006, 0x1108, 0x04b0, 0x2b10, 0x080c, 0xb091,
- 0x1118, 0x080c, 0xb139, 0x05a8, 0x6212, 0xa874, 0x0002, 0x7eeb,
- 0x7ef0, 0x7ef3, 0x7ef9, 0x2019, 0x0002, 0x080c, 0xe8b0, 0x0060,
- 0x080c, 0xe847, 0x0048, 0x2019, 0x0002, 0xa980, 0x080c, 0xe862,
- 0x0018, 0xa980, 0x080c, 0xe847, 0x080c, 0xb0e7, 0xa887, 0x0000,
- 0x0126, 0x2091, 0x8000, 0x080c, 0x6dcb, 0x012e, 0x00be, 0x001e,
- 0x002e, 0x003e, 0x00ce, 0x00de, 0x0005, 0xa887, 0x0006, 0x0c80,
- 0xa887, 0x0002, 0x0c68, 0xa887, 0x0005, 0x0c50, 0xa887, 0x0004,
- 0x0c38, 0xa887, 0x0007, 0x0c20, 0x2091, 0x8000, 0x0e04, 0x7f1e,
- 0x0006, 0x0016, 0x2001, 0x8003, 0x0006, 0x0804, 0x0dce, 0x2001,
- 0x1834, 0x2004, 0x9005, 0x0005, 0x0005, 0x00f6, 0x2079, 0x0300,
- 0x2001, 0x0200, 0x200c, 0xc1e5, 0xc1dc, 0x2102, 0x2009, 0x0218,
- 0x210c, 0xd1ec, 0x1120, 0x080c, 0x15a0, 0x00fe, 0x0005, 0x2001,
- 0x020d, 0x2003, 0x0020, 0x781f, 0x0300, 0x00fe, 0x0005, 0x781c,
- 0xd08c, 0x0904, 0x7f9e, 0x68c0, 0x90aa, 0x0005, 0x0a04, 0x85e2,
- 0x7d44, 0x7c40, 0x9584, 0x00f6, 0x1510, 0x9484, 0x7000, 0x0140,
- 0x908a, 0x2000, 0x1260, 0x9584, 0x0700, 0x8007, 0x0804, 0x7fa5,
- 0x7000, 0x9084, 0xff00, 0x9086, 0x8100, 0x0da8, 0x00b0, 0x9484,
- 0x0fff, 0x1130, 0x7000, 0x9084, 0xff00, 0x9086, 0x8100, 0x11c0,
- 0x080c, 0xed6d, 0x080c, 0x84c7, 0x7817, 0x0140, 0x00a8, 0x9584,
- 0x0076, 0x1118, 0x080c, 0x8525, 0x19c0, 0xd5a4, 0x0148, 0x0046,
- 0x0056, 0x080c, 0x8000, 0x080c, 0x238f, 0x005e, 0x004e, 0x0020,
- 0x080c, 0xed6d, 0x7817, 0x0140, 0x080c, 0x7563, 0x0168, 0x2001,
- 0x0111, 0x2004, 0xd08c, 0x0140, 0x6893, 0x0000, 0x2001, 0x0110,
- 0x2003, 0x0008, 0x2003, 0x0000, 0x080c, 0x7fe1, 0x2001, 0x19f2,
- 0x2004, 0x9005, 0x090c, 0x98e7, 0x0005, 0x0002, 0x7fb7, 0x82cf,
- 0x7fae, 0x7fae, 0x7fae, 0x7fae, 0x7fae, 0x7fae, 0x7817, 0x0140,
- 0x2001, 0x19f2, 0x2004, 0x9005, 0x090c, 0x98e7, 0x0005, 0x7000,
- 0x908c, 0xff00, 0x9194, 0xf000, 0x810f, 0x9484, 0x0fff, 0x6892,
- 0x9286, 0x2000, 0x1150, 0x6800, 0x9086, 0x0001, 0x1118, 0x080c,
- 0x5837, 0x0070, 0x080c, 0x8020, 0x0058, 0x9286, 0x3000, 0x1118,
- 0x080c, 0x8207, 0x0028, 0x9286, 0x8000, 0x1110, 0x080c, 0x83ee,
- 0x7817, 0x0140, 0x2001, 0x19f2, 0x2004, 0x9005, 0x090c, 0x98e7,
- 0x0005, 0x2001, 0x1810, 0x2004, 0xd08c, 0x0178, 0x2001, 0x1800,
- 0x2004, 0x9086, 0x0003, 0x1148, 0x0026, 0x0036, 0x2011, 0x8048,
- 0x2518, 0x080c, 0x4be3, 0x003e, 0x002e, 0x0005, 0x0036, 0x0046,
- 0x0056, 0x00f6, 0x2079, 0x0200, 0x2019, 0xfffe, 0x7c30, 0x0050,
- 0x0036, 0x0046, 0x0056, 0x00f6, 0x2079, 0x0200, 0x7d44, 0x7c40,
- 0x2019, 0xffff, 0x2001, 0x1810, 0x2004, 0xd08c, 0x0160, 0x2001,
- 0x1800, 0x2004, 0x9086, 0x0003, 0x1130, 0x0026, 0x2011, 0x8048,
- 0x080c, 0x4be3, 0x002e, 0x00fe, 0x005e, 0x004e, 0x003e, 0x0005,
- 0x00b6, 0x00c6, 0x7010, 0x9084, 0xff00, 0x8007, 0x9096, 0x0001,
- 0x0120, 0x9096, 0x0023, 0x1904, 0x81d8, 0x9186, 0x0023, 0x15c0,
- 0x080c, 0x848c, 0x0904, 0x81d8, 0x6120, 0x9186, 0x0001, 0x0150,
- 0x9186, 0x0004, 0x0138, 0x9186, 0x0008, 0x0120, 0x9186, 0x000a,
- 0x1904, 0x81d8, 0x7124, 0x610a, 0x7030, 0x908e, 0x0200, 0x1130,
- 0x2009, 0x0015, 0x080c, 0xb166, 0x0804, 0x81d8, 0x908e, 0x0214,
- 0x0118, 0x908e, 0x0210, 0x1130, 0x2009, 0x0015, 0x080c, 0xb166,
- 0x0804, 0x81d8, 0x908e, 0x0100, 0x1904, 0x81d8, 0x7034, 0x9005,
- 0x1904, 0x81d8, 0x2009, 0x0016, 0x080c, 0xb166, 0x0804, 0x81d8,
- 0x9186, 0x0022, 0x1904, 0x81d8, 0x7030, 0x908e, 0x0300, 0x1580,
- 0x68dc, 0xd0a4, 0x0528, 0xc0b5, 0x68de, 0x7100, 0x918c, 0x00ff,
- 0x697e, 0x7004, 0x6882, 0x00f6, 0x2079, 0x0100, 0x79e6, 0x78ea,
- 0x0006, 0x9084, 0x00ff, 0x0016, 0x2008, 0x080c, 0x28d2, 0x7932,
- 0x7936, 0x001e, 0x000e, 0x00fe, 0x080c, 0x2889, 0x695e, 0x703c,
- 0x00e6, 0x2071, 0x0140, 0x7086, 0x2071, 0x1800, 0x70b6, 0x00ee,
- 0x7034, 0x9005, 0x1904, 0x81d8, 0x2009, 0x0017, 0x0804, 0x8188,
- 0x908e, 0x0400, 0x1190, 0x7034, 0x9005, 0x1904, 0x81d8, 0x080c,
- 0x7563, 0x0120, 0x2009, 0x001d, 0x0804, 0x8188, 0x68dc, 0xc0a5,
- 0x68de, 0x2009, 0x0030, 0x0804, 0x8188, 0x908e, 0x0500, 0x1140,
- 0x7034, 0x9005, 0x1904, 0x81d8, 0x2009, 0x0018, 0x0804, 0x8188,
- 0x908e, 0x2010, 0x1120, 0x2009, 0x0019, 0x0804, 0x8188, 0x908e,
- 0x2110, 0x1120, 0x2009, 0x001a, 0x0804, 0x8188, 0x908e, 0x5200,
- 0x1140, 0x7034, 0x9005, 0x1904, 0x81d8, 0x2009, 0x001b, 0x0804,
- 0x8188, 0x908e, 0x5000, 0x1140, 0x7034, 0x9005, 0x1904, 0x81d8,
- 0x2009, 0x001c, 0x0804, 0x8188, 0x908e, 0x1300, 0x1120, 0x2009,
- 0x0034, 0x0804, 0x8188, 0x908e, 0x1200, 0x1140, 0x7034, 0x9005,
- 0x1904, 0x81d8, 0x2009, 0x0024, 0x0804, 0x8188, 0x908c, 0xff00,
- 0x918e, 0x2400, 0x1170, 0x2009, 0x002d, 0x2001, 0x1810, 0x2004,
- 0xd09c, 0x0904, 0x8188, 0x080c, 0xdc7f, 0x1904, 0x81d8, 0x0804,
- 0x8186, 0x908c, 0xff00, 0x918e, 0x5300, 0x1120, 0x2009, 0x002a,
- 0x0804, 0x8188, 0x908e, 0x0f00, 0x1120, 0x2009, 0x0020, 0x0804,
- 0x8188, 0x908e, 0x6104, 0x1530, 0x2029, 0x0205, 0x2011, 0x026d,
- 0x8208, 0x2204, 0x9082, 0x0004, 0x8004, 0x8004, 0x20a8, 0x2011,
- 0x8015, 0x211c, 0x8108, 0x0046, 0x2124, 0x080c, 0x4be3, 0x004e,
- 0x8108, 0x0f04, 0x813c, 0x9186, 0x0280, 0x1d88, 0x2504, 0x8000,
- 0x202a, 0x2009, 0x0260, 0x0c58, 0x202b, 0x0000, 0x2009, 0x0023,
- 0x0804, 0x8188, 0x908e, 0x6000, 0x1120, 0x2009, 0x003f, 0x0804,
- 0x8188, 0x908e, 0x5400, 0x1138, 0x080c, 0x8592, 0x1904, 0x81d8,
- 0x2009, 0x0046, 0x04a8, 0x908e, 0x5500, 0x1148, 0x080c, 0x85ba,
- 0x1118, 0x2009, 0x0041, 0x0460, 0x2009, 0x0042, 0x0448, 0x908e,
- 0x7800, 0x1118, 0x2009, 0x0045, 0x0418, 0x908e, 0x1000, 0x1118,
- 0x2009, 0x004e, 0x00e8, 0x908e, 0x6300, 0x1118, 0x2009, 0x004a,
- 0x00b8, 0x908c, 0xff00, 0x918e, 0x5600, 0x1118, 0x2009, 0x004f,
- 0x0078, 0x908c, 0xff00, 0x918e, 0x5700, 0x1118, 0x2009, 0x0050,
- 0x0038, 0x2009, 0x001d, 0x6838, 0xd0d4, 0x0110, 0x2009, 0x004c,
- 0x0016, 0x2011, 0x0263, 0x2204, 0x8211, 0x220c, 0x080c, 0x2889,
- 0x1904, 0x81db, 0x080c, 0x66ac, 0x1904, 0x81db, 0xbe12, 0xbd16,
- 0x001e, 0x0016, 0x080c, 0x7563, 0x01c0, 0x68dc, 0xd08c, 0x1148,
- 0x7000, 0x9084, 0x00ff, 0x1188, 0x7004, 0x9084, 0xff00, 0x1168,
- 0x0040, 0x687c, 0x9606, 0x1148, 0x6880, 0x9506, 0x9084, 0xff00,
- 0x1120, 0x9584, 0x00ff, 0xb8c2, 0x0080, 0xb8c0, 0x9005, 0x1168,
- 0x9186, 0x0046, 0x1150, 0x687c, 0x9606, 0x1138, 0x6880, 0x9506,
- 0x9084, 0xff00, 0x1110, 0x001e, 0x0098, 0x080c, 0xb091, 0x01a8,
- 0x2b08, 0x6112, 0x6023, 0x0004, 0x7120, 0x610a, 0x001e, 0x9186,
- 0x004c, 0x1110, 0x6023, 0x000a, 0x0016, 0x001e, 0x080c, 0xb166,
- 0x00ce, 0x00be, 0x0005, 0x001e, 0x0cd8, 0x2001, 0x180e, 0x2004,
- 0xd0ec, 0x0120, 0x2011, 0x8049, 0x080c, 0x4be3, 0x080c, 0xb139,
- 0x0d90, 0x2b08, 0x6112, 0x6023, 0x0004, 0x7120, 0x610a, 0x001e,
- 0x0016, 0x9186, 0x0017, 0x0118, 0x9186, 0x0030, 0x1128, 0x6007,
- 0x0009, 0x6017, 0x2900, 0x0020, 0x6007, 0x0051, 0x6017, 0x0000,
- 0x602f, 0x0009, 0x6003, 0x0001, 0x080c, 0x937d, 0x08a0, 0x080c,
- 0x8601, 0x1158, 0x080c, 0x336f, 0x1140, 0x7010, 0x9084, 0xff00,
- 0x8007, 0x908e, 0x0008, 0x1108, 0x0009, 0x0005, 0x00b6, 0x00c6,
- 0x0046, 0x7000, 0x908c, 0xff00, 0x810f, 0x9186, 0x0033, 0x11e8,
- 0x080c, 0x848c, 0x0904, 0x8267, 0x7124, 0x610a, 0x7030, 0x908e,
- 0x0200, 0x1140, 0x7034, 0x9005, 0x15d0, 0x2009, 0x0015, 0x080c,
- 0xb166, 0x04a8, 0x908e, 0x0100, 0x1590, 0x7034, 0x9005, 0x1578,
- 0x2009, 0x0016, 0x080c, 0xb166, 0x0450, 0x9186, 0x0032, 0x1538,
- 0x7030, 0x908e, 0x1400, 0x1518, 0x2009, 0x0038, 0x0016, 0x2011,
- 0x0263, 0x2204, 0x8211, 0x220c, 0x080c, 0x2889, 0x11b8, 0x080c,
- 0x66ac, 0x11a0, 0xbe12, 0xbd16, 0x080c, 0xb091, 0x0178, 0x2b08,
- 0x6112, 0x080c, 0xd2bb, 0x6023, 0x0004, 0x7120, 0x610a, 0x001e,
- 0x080c, 0xb166, 0x080c, 0x98e7, 0x0010, 0x00ce, 0x001e, 0x004e,
- 0x00ce, 0x00be, 0x0005, 0x00b6, 0x0046, 0x00e6, 0x00d6, 0x2028,
- 0x2130, 0x9696, 0x00ff, 0x11b8, 0x9592, 0xfffc, 0x02a0, 0x9596,
- 0xfffd, 0x1120, 0x2009, 0x007f, 0x0804, 0x82c9, 0x9596, 0xfffe,
- 0x1120, 0x2009, 0x007e, 0x0804, 0x82c9, 0x9596, 0xfffc, 0x1118,
- 0x2009, 0x0080, 0x04f0, 0x2011, 0x0000, 0x2019, 0x1837, 0x231c,
- 0xd3ac, 0x0130, 0x9026, 0x20a9, 0x0800, 0x2071, 0x1000, 0x0030,
- 0x2021, 0x0081, 0x20a9, 0x077f, 0x2071, 0x1081, 0x2e1c, 0x93dd,
- 0x0000, 0x1140, 0x82ff, 0x11d0, 0x9496, 0x00ff, 0x01b8, 0x2410,
- 0xc2fd, 0x00a0, 0xbf10, 0x2600, 0x9706, 0xb814, 0x1120, 0x9546,
- 0x1110, 0x2408, 0x00b0, 0x9745, 0x1148, 0x94c6, 0x007e, 0x0130,
- 0x94c6, 0x007f, 0x0118, 0x94c6, 0x0080, 0x1d20, 0x8420, 0x8e70,
- 0x1f04, 0x829e, 0x82ff, 0x1118, 0x9085, 0x0001, 0x0018, 0xc2fc,
- 0x2208, 0x9006, 0x00de, 0x00ee, 0x004e, 0x00be, 0x0005, 0x2001,
- 0x1837, 0x200c, 0x9184, 0x0080, 0x0110, 0xd18c, 0x0138, 0x7000,
- 0x908c, 0xff00, 0x810f, 0x9184, 0x000f, 0x004a, 0x7817, 0x0140,
- 0x2001, 0x19f2, 0x2004, 0x9005, 0x090c, 0x98e7, 0x0005, 0x82f7,
- 0x82f7, 0x82f7, 0x849e, 0x82f7, 0x8300, 0x832b, 0x83b9, 0x82f7,
- 0x82f7, 0x82f7, 0x82f7, 0x82f7, 0x82f7, 0x82f7, 0x82f7, 0x7817,
- 0x0140, 0x2001, 0x19f2, 0x2004, 0x9005, 0x090c, 0x98e7, 0x0005,
- 0x00b6, 0x7110, 0xd1bc, 0x01e8, 0x7120, 0x2160, 0x9c8c, 0x0007,
- 0x11c0, 0x9c8a, 0x1cd0, 0x02a8, 0x6868, 0x9c02, 0x1290, 0x7008,
- 0x9084, 0x00ff, 0x6110, 0x2158, 0xb910, 0x9106, 0x1150, 0x700c,
- 0xb914, 0x9106, 0x1130, 0x7124, 0x610a, 0x2009, 0x0046, 0x080c,
- 0xb166, 0x7817, 0x0140, 0x2001, 0x19f2, 0x2004, 0x9005, 0x090c,
- 0x98e7, 0x00be, 0x0005, 0x00b6, 0x00c6, 0x9484, 0x0fff, 0x0904,
- 0x838f, 0x7110, 0xd1bc, 0x1904, 0x838f, 0x7108, 0x700c, 0x2028,
- 0x918c, 0x00ff, 0x2130, 0x9094, 0xff00, 0x15b0, 0x81ff, 0x15a0,
- 0x9080, 0x33b1, 0x200d, 0x918c, 0xff00, 0x810f, 0x2001, 0x0080,
- 0x9106, 0x0904, 0x838f, 0x080c, 0x66ac, 0x1904, 0x838f, 0xbe12,
- 0xbd16, 0xb800, 0xd0ec, 0x15d8, 0xba04, 0x9294, 0xff00, 0x9286,
- 0x0600, 0x11a0, 0x080c, 0xb091, 0x05e8, 0x2b08, 0x7028, 0x6046,
- 0x702c, 0x604a, 0x6112, 0x6023, 0x0006, 0x7120, 0x610a, 0x7130,
- 0x6156, 0x2009, 0x0044, 0x080c, 0xdf02, 0x0408, 0x080c, 0x6a8c,
- 0x1138, 0xb807, 0x0606, 0x0c30, 0x190c, 0x826b, 0x11c0, 0x0898,
- 0x080c, 0xb091, 0x2b08, 0x0198, 0x6112, 0x6023, 0x0004, 0x7120,
- 0x610a, 0x9286, 0x0400, 0x1118, 0x6007, 0x0005, 0x0010, 0x6007,
- 0x0001, 0x6003, 0x0001, 0x080c, 0x937d, 0x080c, 0x98e7, 0x7817,
- 0x0140, 0x2001, 0x19f2, 0x2004, 0x9005, 0x090c, 0x98e7, 0x00ce,
- 0x00be, 0x0005, 0x2001, 0x180e, 0x2004, 0xd0ec, 0x0120, 0x2011,
- 0x8049, 0x080c, 0x4be3, 0x080c, 0xb139, 0x0d48, 0x2b08, 0x6112,
- 0x6023, 0x0006, 0x7120, 0x610a, 0x7130, 0x6156, 0x6017, 0xf300,
- 0x6003, 0x0001, 0x6007, 0x0041, 0x080c, 0x9335, 0x080c, 0x98e7,
- 0x08b0, 0x00b6, 0x7110, 0xd1bc, 0x01e8, 0x7020, 0x2060, 0x9c84,
- 0x0007, 0x11c0, 0x9c82, 0x1cd0, 0x02a8, 0x6868, 0x9c02, 0x1290,
- 0x7008, 0x9084, 0x00ff, 0x6110, 0x2158, 0xb910, 0x9106, 0x1150,
- 0x700c, 0xb914, 0x9106, 0x1130, 0x7124, 0x610a, 0x2009, 0x0045,
- 0x080c, 0xb166, 0x7817, 0x0140, 0x2001, 0x19f2, 0x2004, 0x9005,
- 0x090c, 0x98e7, 0x00be, 0x0005, 0x6120, 0x9186, 0x0002, 0x0128,
- 0x9186, 0x0005, 0x0110, 0x9085, 0x0001, 0x0005, 0x080c, 0x8601,
- 0x1180, 0x080c, 0x336f, 0x1168, 0x7010, 0x9084, 0xff00, 0x8007,
- 0x9086, 0x0000, 0x1130, 0x9184, 0x000f, 0x908a, 0x0006, 0x1208,
- 0x000b, 0x0005, 0x8408, 0x8409, 0x8408, 0x8408, 0x846e, 0x847d,
- 0x0005, 0x00b6, 0x700c, 0x7108, 0x080c, 0x2889, 0x1904, 0x846c,
- 0x080c, 0x66ac, 0x1904, 0x846c, 0xbe12, 0xbd16, 0x7110, 0xd1bc,
- 0x0540, 0x702c, 0xd084, 0x1120, 0xb800, 0xd0bc, 0x1904, 0x846c,
- 0x080c, 0x6a8c, 0x0148, 0x9086, 0x0004, 0x0130, 0x080c, 0x6a94,
- 0x0118, 0x9086, 0x0004, 0x1588, 0x00c6, 0x080c, 0x848c, 0x00ce,
- 0x05d8, 0x080c, 0xb091, 0x2b08, 0x05b8, 0x6112, 0x080c, 0xd2bb,
- 0x6023, 0x0002, 0x7120, 0x610a, 0x2009, 0x0088, 0x080c, 0xb166,
- 0x0458, 0x080c, 0x6a8c, 0x0148, 0x9086, 0x0004, 0x0130, 0x080c,
- 0x6a94, 0x0118, 0x9086, 0x0004, 0x1180, 0x080c, 0xb091, 0x2b08,
- 0x01d8, 0x6112, 0x080c, 0xd2bb, 0x6023, 0x0005, 0x7120, 0x610a,
- 0x2009, 0x0088, 0x080c, 0xb166, 0x0078, 0x080c, 0xb091, 0x2b08,
- 0x0158, 0x6112, 0x080c, 0xd2bb, 0x6023, 0x0004, 0x7120, 0x610a,
- 0x2009, 0x0001, 0x080c, 0xb166, 0x00be, 0x0005, 0x7110, 0xd1bc,
- 0x0158, 0x00d1, 0x0148, 0x080c, 0x83e4, 0x1130, 0x7124, 0x610a,
- 0x2009, 0x0089, 0x080c, 0xb166, 0x0005, 0x7110, 0xd1bc, 0x0158,
- 0x0059, 0x0148, 0x080c, 0x83e4, 0x1130, 0x7124, 0x610a, 0x2009,
- 0x008a, 0x080c, 0xb166, 0x0005, 0x7020, 0x2060, 0x9c84, 0x0007,
- 0x1158, 0x9c82, 0x1cd0, 0x0240, 0x2001, 0x181a, 0x2004, 0x9c02,
- 0x1218, 0x9085, 0x0001, 0x0005, 0x9006, 0x0ce8, 0x00b6, 0x7110,
- 0xd1bc, 0x11d8, 0x7024, 0x2060, 0x9c84, 0x0007, 0x11b0, 0x9c82,
- 0x1cd0, 0x0298, 0x6868, 0x9c02, 0x1280, 0x7008, 0x9084, 0x00ff,
- 0x6110, 0x2158, 0xb910, 0x9106, 0x1140, 0x700c, 0xb914, 0x9106,
- 0x1120, 0x2009, 0x0051, 0x080c, 0xb166, 0x7817, 0x0140, 0x2001,
- 0x19f2, 0x2004, 0x9005, 0x090c, 0x98e7, 0x00be, 0x0005, 0x2031,
- 0x0105, 0x0069, 0x0005, 0x2031, 0x0206, 0x0049, 0x0005, 0x2031,
- 0x0207, 0x0029, 0x0005, 0x2031, 0x0213, 0x0009, 0x0005, 0x00c6,
- 0x0096, 0x00f6, 0x7000, 0x9084, 0xf000, 0x9086, 0xc000, 0x05d0,
- 0x080c, 0xb091, 0x05b8, 0x0066, 0x00c6, 0x0046, 0x2011, 0x0263,
- 0x2204, 0x8211, 0x220c, 0x080c, 0x2889, 0x15a0, 0x080c, 0x66ac,
- 0x1588, 0xbe12, 0xbd16, 0x2b00, 0x004e, 0x00ce, 0x6012, 0x080c,
- 0xd2bb, 0x080c, 0x100e, 0x0510, 0x2900, 0x605a, 0x9006, 0xa802,
- 0xa866, 0xac6a, 0xa85c, 0x90f8, 0x001b, 0x20a9, 0x000e, 0xa860,
- 0x20e8, 0x20e1, 0x0000, 0x2fa0, 0x2e98, 0x4003, 0x006e, 0x6616,
- 0x6007, 0x003e, 0x6023, 0x0001, 0x6003, 0x0001, 0x080c, 0x937d,
- 0x080c, 0x98e7, 0x00fe, 0x009e, 0x00ce, 0x0005, 0x080c, 0xb0e7,
- 0x006e, 0x0cc0, 0x004e, 0x00ce, 0x0cc8, 0x00c6, 0x7000, 0x908c,
- 0xff00, 0x9184, 0xf000, 0x810f, 0x9086, 0x2000, 0x1904, 0x857c,
- 0x9186, 0x0022, 0x15f0, 0x2001, 0x0111, 0x2004, 0x9005, 0x1904,
- 0x857e, 0x7030, 0x908e, 0x0400, 0x0904, 0x857e, 0x908e, 0x6000,
- 0x05e8, 0x908e, 0x5400, 0x05d0, 0x908e, 0x0300, 0x11d8, 0x2009,
- 0x1837, 0x210c, 0xd18c, 0x1590, 0xd1a4, 0x1580, 0x080c, 0x6a4a,
- 0x0588, 0x68b0, 0x9084, 0x00ff, 0x7100, 0x918c, 0x00ff, 0x9106,
- 0x1518, 0x6880, 0x69b0, 0x918c, 0xff00, 0x9105, 0x7104, 0x9106,
- 0x11d8, 0x00e0, 0x2009, 0x0103, 0x210c, 0xd1b4, 0x11a8, 0x908e,
- 0x5200, 0x09e8, 0x908e, 0x0500, 0x09d0, 0x908e, 0x5000, 0x09b8,
- 0x0058, 0x9186, 0x0023, 0x1140, 0x080c, 0x848c, 0x0128, 0x6004,
- 0x9086, 0x0002, 0x0118, 0x0000, 0x9006, 0x0010, 0x9085, 0x0001,
- 0x00ce, 0x0005, 0x7030, 0x908e, 0x0300, 0x0118, 0x908e, 0x5200,
- 0x1d98, 0x2001, 0x1837, 0x2004, 0x9084, 0x0009, 0x9086, 0x0008,
- 0x0d68, 0x0c50, 0x0156, 0x0046, 0x0016, 0x0036, 0x7038, 0x2020,
- 0x8427, 0x94a4, 0x0007, 0xd484, 0x0148, 0x20a9, 0x0004, 0x2019,
- 0x1805, 0x2011, 0x027a, 0x080c, 0xc0d3, 0x1178, 0xd48c, 0x0148,
- 0x20a9, 0x0004, 0x2019, 0x1801, 0x2011, 0x027e, 0x080c, 0xc0d3,
- 0x1120, 0xd494, 0x0110, 0x9085, 0x0001, 0x003e, 0x001e, 0x004e,
- 0x015e, 0x0005, 0x0156, 0x0046, 0x0016, 0x0036, 0x7038, 0x2020,
- 0x8427, 0x94a4, 0x0007, 0xd484, 0x0148, 0x20a9, 0x0004, 0x2019,
- 0x1805, 0x2011, 0x0272, 0x080c, 0xc0d3, 0x1178, 0xd48c, 0x0148,
- 0x20a9, 0x0004, 0x2019, 0x1801, 0x2011, 0x0276, 0x080c, 0xc0d3,
- 0x1120, 0xd494, 0x0110, 0x9085, 0x0001, 0x003e, 0x001e, 0x004e,
- 0x015e, 0x0005, 0x00f6, 0x2079, 0x0200, 0x7800, 0xc0e5, 0xc0cc,
- 0x7802, 0x00fe, 0x0005, 0x00f6, 0x2079, 0x1800, 0x7834, 0xd084,
- 0x1130, 0x2079, 0x0200, 0x7800, 0x9085, 0x1200, 0x7802, 0x00fe,
- 0x0005, 0x00e6, 0x2071, 0x1800, 0x7034, 0xc084, 0x7036, 0x00ee,
- 0x0005, 0x0016, 0x2001, 0x1837, 0x200c, 0x9184, 0x0080, 0x0118,
- 0xd18c, 0x0118, 0x9006, 0x001e, 0x0005, 0x9085, 0x0001, 0x0cd8,
- 0x2071, 0x19fc, 0x7003, 0x0003, 0x700f, 0x0361, 0x9006, 0x701a,
- 0x707a, 0x7012, 0x7017, 0x1cd0, 0x7007, 0x0000, 0x7026, 0x702b,
- 0xa513, 0x7032, 0x703a, 0x703f, 0x0064, 0x7037, 0xa57b, 0x7047,
- 0xffff, 0x704a, 0x704f, 0x565f, 0x7052, 0x7063, 0x87a4, 0x080c,
- 0x1027, 0x090c, 0x0dc5, 0x2900, 0x7042, 0xa867, 0x0003, 0xa86f,
- 0x0100, 0xa8ab, 0xdcb0, 0x0005, 0x2071, 0x19fc, 0x1d04, 0x86f2,
- 0x2091, 0x6000, 0x700c, 0x8001, 0x700e, 0x1540, 0x2001, 0x013c,
- 0x2004, 0x9005, 0x190c, 0x8812, 0x2001, 0x1869, 0x2004, 0xd0c4,
- 0x0158, 0x3a00, 0xd08c, 0x1140, 0x20d1, 0x0000, 0x20d1, 0x0001,
- 0x20d1, 0x0000, 0x080c, 0x0dc5, 0x700f, 0x0361, 0x7007, 0x0001,
- 0x0126, 0x2091, 0x8000, 0x080c, 0x87e9, 0x7048, 0x900d, 0x0148,
- 0x8109, 0x714a, 0x1130, 0x704c, 0x080f, 0x0018, 0x0126, 0x2091,
- 0x8000, 0x7024, 0x900d, 0x0188, 0x7020, 0x8001, 0x7022, 0x1168,
- 0x7023, 0x0009, 0x8109, 0x7126, 0x9186, 0x03e8, 0x1110, 0x7028,
- 0x080f, 0x81ff, 0x1110, 0x7028, 0x080f, 0x7030, 0x900d, 0x05a8,
- 0x702c, 0x8001, 0x702e, 0x1588, 0x0016, 0x2009, 0x0306, 0x210c,
- 0x9184, 0x0030, 0x01e8, 0x9184, 0x0048, 0x9086, 0x0008, 0x11c0,
- 0x7038, 0x9005, 0x01a8, 0x8001, 0x703a, 0x1190, 0x080c, 0x7563,
- 0x0178, 0x00e6, 0x2071, 0x19e9, 0x080c, 0xa609, 0x00ee, 0x1140,
- 0x2009, 0x1a87, 0x2104, 0x8000, 0x0208, 0x200a, 0x001e, 0x0068,
- 0x001e, 0x702f, 0x0009, 0x8109, 0x7132, 0x0128, 0x9184, 0x007f,
- 0x090c, 0xa6bf, 0x0010, 0x7034, 0x080f, 0x7044, 0x9005, 0x0118,
- 0x0310, 0x8001, 0x7046, 0x7054, 0x900d, 0x0168, 0x7050, 0x8001,
- 0x7052, 0x1148, 0x7053, 0x0009, 0x8109, 0x7156, 0x1120, 0x7158,
- 0x7156, 0x7060, 0x080f, 0x7018, 0x900d, 0x01d8, 0x0016, 0x7078,
- 0x900d, 0x0158, 0x7074, 0x8001, 0x7076, 0x1138, 0x7077, 0x0009,
- 0x8109, 0x717a, 0x1110, 0x707c, 0x080f, 0x001e, 0x7008, 0x8001,
- 0x700a, 0x1138, 0x700b, 0x0009, 0x8109, 0x711a, 0x1110, 0x701c,
- 0x080f, 0x012e, 0x7004, 0x0002, 0x871a, 0x871b, 0x8737, 0x00e6,
- 0x2071, 0x19fc, 0x7018, 0x9005, 0x1120, 0x711a, 0x721e, 0x700b,
- 0x0009, 0x00ee, 0x0005, 0x00e6, 0x0006, 0x2071, 0x19fc, 0x701c,
- 0x9206, 0x1120, 0x701a, 0x701e, 0x707a, 0x707e, 0x000e, 0x00ee,
- 0x0005, 0x00e6, 0x2071, 0x19fc, 0xb888, 0x9102, 0x0208, 0xb98a,
- 0x00ee, 0x0005, 0x0005, 0x00b6, 0x7110, 0x080c, 0x6717, 0x1168,
- 0xb888, 0x8001, 0x0250, 0xb88a, 0x1140, 0x0126, 0x2091, 0x8000,
- 0x0016, 0x080c, 0x98e7, 0x001e, 0x012e, 0x8108, 0x9182, 0x0800,
- 0x0218, 0x900e, 0x7007, 0x0002, 0x7112, 0x00be, 0x0005, 0x7014,
- 0x2060, 0x0126, 0x2091, 0x8000, 0x6040, 0x9005, 0x0128, 0x8001,
- 0x6042, 0x1110, 0x080c, 0xd14c, 0x6018, 0x9005, 0x0558, 0x8001,
- 0x601a, 0x1540, 0x6120, 0x9186, 0x0003, 0x0148, 0x9186, 0x0006,
- 0x0130, 0x9186, 0x0009, 0x11e0, 0x611c, 0xd1c4, 0x1100, 0x080c,
- 0xce3f, 0x01b0, 0x6014, 0x2048, 0xa884, 0x908a, 0x199a, 0x0280,
- 0x9082, 0x1999, 0xa886, 0x908a, 0x199a, 0x0210, 0x2001, 0x1999,
- 0x8003, 0x800b, 0x810b, 0x9108, 0x611a, 0xa87c, 0xd0e4, 0x0110,
- 0x080c, 0xcb2b, 0x012e, 0x9c88, 0x0018, 0x7116, 0x2001, 0x181a,
- 0x2004, 0x9102, 0x0220, 0x7017, 0x1cd0, 0x7007, 0x0000, 0x0005,
- 0x00e6, 0x2071, 0x19fc, 0x7027, 0x07d0, 0x7023, 0x0009, 0x00ee,
- 0x0005, 0x2001, 0x1a05, 0x2003, 0x0000, 0x0005, 0x00e6, 0x2071,
- 0x19fc, 0x7132, 0x702f, 0x0009, 0x00ee, 0x0005, 0x2011, 0x1a08,
- 0x2013, 0x0000, 0x0005, 0x00e6, 0x2071, 0x19fc, 0x711a, 0x721e,
- 0x700b, 0x0009, 0x00ee, 0x0005, 0x0086, 0x0026, 0x705c, 0x8000,
- 0x705e, 0x2001, 0x1a0c, 0x2044, 0xa06c, 0x9086, 0x0000, 0x0150,
- 0x7070, 0xa09a, 0x706c, 0xa096, 0x7068, 0xa092, 0x7064, 0xa08e,
- 0x080c, 0x10f8, 0x002e, 0x008e, 0x0005, 0x0006, 0x0016, 0x0096,
- 0x00a6, 0x00b6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x0156, 0x080c,
- 0x863c, 0x015e, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x00be, 0x00ae,
- 0x009e, 0x001e, 0x000e, 0x0005, 0x00e6, 0x2071, 0x19fc, 0x717a,
- 0x727e, 0x7077, 0x0009, 0x00ee, 0x0005, 0x00e6, 0x0006, 0x2071,
- 0x19fc, 0x707c, 0x9206, 0x1110, 0x707a, 0x707e, 0x000e, 0x00ee,
- 0x0005, 0x2069, 0x1800, 0x69e8, 0xd1e4, 0x1518, 0x0026, 0xd1ec,
- 0x0140, 0x6a54, 0x6874, 0x9202, 0x0288, 0x8117, 0x9294, 0x00c0,
- 0x0088, 0x9184, 0x0007, 0x01a0, 0x8109, 0x9184, 0x0007, 0x0110,
- 0x69ea, 0x0070, 0x8107, 0x9084, 0x0007, 0x910d, 0x8107, 0x9106,
- 0x9094, 0x00c0, 0x9184, 0xff3f, 0x9205, 0x68ea, 0x080c, 0x0eee,
- 0x002e, 0x0005, 0x0016, 0x00c6, 0x2009, 0xfff4, 0x210d, 0x2061,
- 0x0100, 0x60f0, 0x9100, 0x60f3, 0x0000, 0x2009, 0xfff4, 0x200f,
- 0x1220, 0x8108, 0x2105, 0x8000, 0x200f, 0x00ce, 0x001e, 0x0005,
- 0x00c6, 0x2061, 0x1a75, 0x00ce, 0x0005, 0x9184, 0x000f, 0x8003,
- 0x8003, 0x8003, 0x9080, 0x1a75, 0x2060, 0x0005, 0xa884, 0x908a,
- 0x199a, 0x1638, 0x9005, 0x1150, 0x00c6, 0x2061, 0x1a75, 0x6014,
- 0x00ce, 0x9005, 0x1130, 0x2001, 0x001e, 0x0018, 0x908e, 0xffff,
- 0x01b0, 0x8003, 0x800b, 0x810b, 0x9108, 0x611a, 0xa87c, 0x908c,
- 0x00c0, 0x918e, 0x00c0, 0x0904, 0x88c0, 0xd0b4, 0x1168, 0xd0bc,
- 0x1904, 0x8899, 0x2009, 0x0006, 0x080c, 0x88ed, 0x0005, 0x900e,
- 0x0c60, 0x2001, 0x1999, 0x08b0, 0xd0fc, 0x0160, 0x908c, 0x0003,
- 0x0120, 0x918e, 0x0003, 0x1904, 0x88e7, 0x908c, 0x2020, 0x918e,
- 0x2020, 0x01a8, 0x6024, 0xd0d4, 0x11e8, 0x2009, 0x1869, 0x2104,
- 0xd084, 0x1138, 0x87ff, 0x1120, 0x2009, 0x0043, 0x0804, 0xb166,
- 0x0005, 0x87ff, 0x1de8, 0x2009, 0x0042, 0x0804, 0xb166, 0x6110,
- 0x00b6, 0x2158, 0xb900, 0x00be, 0xd1ac, 0x0d20, 0x6024, 0xc0cd,
- 0x6026, 0x0c00, 0xc0d4, 0x6026, 0xa890, 0x602e, 0xa88c, 0x6032,
- 0x08e0, 0xd0fc, 0x0160, 0x908c, 0x0003, 0x0120, 0x918e, 0x0003,
- 0x1904, 0x88e7, 0x908c, 0x2020, 0x918e, 0x2020, 0x0170, 0x0076,
- 0x00f6, 0x2c78, 0x080c, 0x1768, 0x00fe, 0x007e, 0x87ff, 0x1120,
- 0x2009, 0x0042, 0x080c, 0xb166, 0x0005, 0x6110, 0x00b6, 0x2158,
- 0xb900, 0x00be, 0xd1ac, 0x0d58, 0x6124, 0xc1cd, 0x6126, 0x0c38,
- 0xd0fc, 0x0188, 0x908c, 0x2020, 0x918e, 0x2020, 0x01a8, 0x9084,
- 0x0003, 0x908e, 0x0002, 0x0148, 0x87ff, 0x1120, 0x2009, 0x0041,
- 0x080c, 0xb166, 0x0005, 0x00b9, 0x0ce8, 0x87ff, 0x1dd8, 0x2009,
- 0x0043, 0x080c, 0xb166, 0x0cb0, 0x6110, 0x00b6, 0x2158, 0xb900,
- 0x00be, 0xd1ac, 0x0d20, 0x6124, 0xc1cd, 0x6126, 0x0c00, 0x2009,
- 0x0004, 0x0019, 0x0005, 0x2009, 0x0001, 0x0096, 0x080c, 0xce3f,
- 0x0518, 0x6014, 0x2048, 0xa982, 0xa800, 0x6016, 0x9186, 0x0001,
- 0x1188, 0xa97c, 0x918c, 0x8100, 0x918e, 0x8100, 0x1158, 0x00c6,
- 0x2061, 0x1a75, 0x6200, 0xd28c, 0x1120, 0x6204, 0x8210, 0x0208,
- 0x6206, 0x00ce, 0x080c, 0x6c0a, 0x6014, 0x904d, 0x0076, 0x2039,
- 0x0000, 0x190c, 0x8836, 0x007e, 0x009e, 0x0005, 0x0156, 0x00c6,
- 0x2061, 0x1a75, 0x6000, 0x81ff, 0x0110, 0x9205, 0x0008, 0x9204,
- 0x6002, 0x00ce, 0x015e, 0x0005, 0x6800, 0xd08c, 0x1138, 0x6808,
- 0x9005, 0x0120, 0x8001, 0x680a, 0x9085, 0x0001, 0x0005, 0x2071,
- 0x1925, 0x7003, 0x0006, 0x7007, 0x0000, 0x700f, 0x0000, 0x7013,
- 0x0001, 0x080c, 0x1027, 0x090c, 0x0dc5, 0xa867, 0x0006, 0xa86b,
- 0x0001, 0xa8ab, 0xdcb0, 0xa89f, 0x0000, 0x2900, 0x702e, 0x7033,
- 0x0000, 0x0005, 0x0126, 0x2091, 0x8000, 0x0096, 0x00e6, 0x2071,
- 0x1925, 0x702c, 0x2048, 0x6a2c, 0x721e, 0x6b30, 0x7322, 0x6834,
- 0x7026, 0xa896, 0x6838, 0x702a, 0xa89a, 0x6824, 0x7016, 0x683c,
- 0x701a, 0x2009, 0x0028, 0x200a, 0x9005, 0x0148, 0x900e, 0x9188,
- 0x000c, 0x8001, 0x1de0, 0x2100, 0x9210, 0x1208, 0x8318, 0xaa8e,
- 0xab92, 0x7010, 0xd084, 0x0168, 0xc084, 0x7007, 0x0001, 0x700f,
- 0x0000, 0x0006, 0x2009, 0x1ad2, 0x2104, 0x9082, 0x0007, 0x200a,
- 0x000e, 0xc095, 0x7012, 0x2008, 0x2001, 0x003b, 0x080c, 0x1611,
- 0x9006, 0x2071, 0x193e, 0x7002, 0x7006, 0x702a, 0x00ee, 0x009e,
- 0x012e, 0x0005, 0x2009, 0x1ad2, 0x2104, 0x9080, 0x0007, 0x200a,
- 0x0005, 0x00e6, 0x0126, 0x0156, 0x2091, 0x8000, 0x2071, 0x1800,
- 0x7154, 0x2001, 0x0008, 0x910a, 0x0638, 0x2001, 0x187d, 0x20ac,
- 0x9006, 0x9080, 0x0008, 0x1f04, 0x89a9, 0x71c0, 0x9102, 0x02e0,
- 0x2071, 0x1877, 0x20a9, 0x0007, 0x00c6, 0x080c, 0xb091, 0x6023,
- 0x0009, 0x6003, 0x0004, 0x601f, 0x0101, 0x0089, 0x0126, 0x2091,
- 0x8000, 0x080c, 0x8b27, 0x012e, 0x1f04, 0x89b5, 0x9006, 0x00ce,
- 0x015e, 0x012e, 0x00ee, 0x0005, 0x9085, 0x0001, 0x0cc8, 0x00e6,
- 0x00b6, 0x0096, 0x0086, 0x0056, 0x0046, 0x0026, 0x7118, 0x720c,
- 0x7620, 0x7004, 0xd084, 0x1128, 0x2021, 0x0024, 0x2029, 0x0002,
- 0x0020, 0x2021, 0x002c, 0x2029, 0x000a, 0x080c, 0x100e, 0x090c,
- 0x0dc5, 0x2900, 0x6016, 0x2058, 0xac66, 0x9006, 0xa802, 0xa806,
- 0xa86a, 0xa87a, 0xa8aa, 0xa887, 0x0005, 0xa87f, 0x0020, 0x7008,
- 0xa89a, 0x7010, 0xa89e, 0xae8a, 0xa8af, 0xffff, 0xa8b3, 0x0000,
- 0x8109, 0x0160, 0x080c, 0x100e, 0x090c, 0x0dc5, 0xad66, 0x2b00,
- 0xa802, 0x2900, 0xb806, 0x2058, 0x8109, 0x1da0, 0x002e, 0x004e,
- 0x005e, 0x008e, 0x009e, 0x00be, 0x00ee, 0x0005, 0x2079, 0x0000,
- 0x2071, 0x1925, 0x7004, 0x004b, 0x700c, 0x0002, 0x8a21, 0x8a1a,
- 0x8a1a, 0x0005, 0x8a2b, 0x8a81, 0x8a81, 0x8a81, 0x8a82, 0x8a93,
- 0x8a93, 0x700c, 0x0cba, 0x0126, 0x2091, 0x8000, 0x78a0, 0x79a0,
- 0x9106, 0x1904, 0x8a73, 0x7814, 0xd0bc, 0x1904, 0x8a7c, 0x012e,
- 0x7018, 0x910a, 0x1128, 0x7030, 0x9005, 0x1904, 0x8ac5, 0x0005,
- 0x1210, 0x7114, 0x910a, 0x9192, 0x000a, 0x0210, 0x2009, 0x000a,
- 0x2001, 0x1888, 0x2014, 0x2001, 0x1937, 0x2004, 0x9100, 0x9202,
- 0x0e50, 0x080c, 0x8c1f, 0x2200, 0x9102, 0x0208, 0x2208, 0x0096,
- 0x702c, 0x2048, 0xa873, 0x0001, 0xa976, 0x080c, 0x8d28, 0x2100,
- 0xa87e, 0xa86f, 0x0000, 0x009e, 0x0126, 0x2091, 0x8000, 0x2009,
- 0x1a1c, 0x2104, 0xc085, 0x200a, 0x700f, 0x0002, 0x012e, 0x080c,
- 0x1117, 0x1de8, 0x0005, 0x78a0, 0x79a0, 0x9106, 0x0904, 0x8a33,
- 0x080c, 0x8bf7, 0x012e, 0x0005, 0x7810, 0xc0c5, 0x7812, 0x0804,
- 0x8a33, 0x0005, 0x700c, 0x0002, 0x8a87, 0x8a8a, 0x8a89, 0x080c,
- 0x8a29, 0x0005, 0x8001, 0x700e, 0x0096, 0x702c, 0x2048, 0xa974,
- 0x009e, 0x0011, 0x0ca0, 0x0005, 0x0096, 0x702c, 0x2048, 0x7018,
- 0x9100, 0x7214, 0x921a, 0x1130, 0x701c, 0xa88e, 0x7020, 0xa892,
- 0x9006, 0x0068, 0x0006, 0x080c, 0x8d28, 0x2100, 0xaa8c, 0x9210,
- 0xaa8e, 0x1220, 0xa890, 0x9081, 0x0000, 0xa892, 0x000e, 0x009e,
- 0x0126, 0x2091, 0x8000, 0x78a2, 0x701a, 0x080c, 0x8bf7, 0x012e,
- 0x0005, 0x00e6, 0x2071, 0x1925, 0x700c, 0x0002, 0x8ac3, 0x8ac3,
- 0x8ac1, 0x700f, 0x0001, 0x00ee, 0x0005, 0x0126, 0x2091, 0x8000,
- 0x7030, 0x9005, 0x0508, 0x2078, 0x7814, 0x2048, 0xae88, 0x00b6,
- 0x2059, 0x0000, 0x080c, 0x8b30, 0x00be, 0x01b0, 0x00e6, 0x2071,
- 0x193e, 0x080c, 0x8b77, 0x00ee, 0x0178, 0x0096, 0x080c, 0x1027,
- 0x2900, 0x009e, 0x0148, 0xa8aa, 0x04b9, 0x0041, 0x2001, 0x1948,
- 0x2003, 0x0000, 0x012e, 0x08c8, 0x012e, 0x0005, 0x00d6, 0x00c6,
- 0x0086, 0x00a6, 0x2940, 0x2650, 0x2600, 0x9005, 0x0180, 0xa864,
- 0x9084, 0x000f, 0x2068, 0x9d88, 0x20e8, 0x2165, 0x0056, 0x2029,
- 0x0000, 0x080c, 0x8cad, 0x080c, 0x20a0, 0x1dd8, 0x005e, 0x00ae,
- 0x2001, 0x187f, 0x2004, 0xa88a, 0x080c, 0x1768, 0x781f, 0x0101,
- 0x7813, 0x0000, 0x0126, 0x2091, 0x8000, 0x080c, 0x8b86, 0x012e,
- 0x008e, 0x00ce, 0x00de, 0x0005, 0x7030, 0x9005, 0x0138, 0x2078,
- 0x780c, 0x7032, 0x2001, 0x1948, 0x2003, 0x0001, 0x0005, 0x00e6,
- 0x2071, 0x1925, 0x7030, 0x600e, 0x2c00, 0x7032, 0x00ee, 0x0005,
- 0x00d6, 0x00c6, 0x0026, 0x9b80, 0x8df6, 0x2005, 0x906d, 0x090c,
- 0x0dc5, 0x9b80, 0x8dee, 0x2005, 0x9065, 0x090c, 0x0dc5, 0x6114,
- 0x2600, 0x9102, 0x0248, 0x6828, 0x9102, 0x02f0, 0x9085, 0x0001,
- 0x002e, 0x00ce, 0x00de, 0x0005, 0x6804, 0xd094, 0x0148, 0x6854,
- 0xd084, 0x1178, 0xc085, 0x6856, 0x2011, 0x8026, 0x080c, 0x4be3,
- 0x684c, 0x0096, 0x904d, 0x090c, 0x0dc5, 0xa804, 0x8000, 0xa806,
- 0x009e, 0x9006, 0x2030, 0x0c20, 0x6854, 0xd08c, 0x1d08, 0xc08d,
- 0x6856, 0x2011, 0x8025, 0x080c, 0x4be3, 0x684c, 0x0096, 0x904d,
- 0x090c, 0x0dc5, 0xa800, 0x8000, 0xa802, 0x009e, 0x0888, 0x7000,
- 0x2019, 0x0008, 0x8319, 0x7104, 0x9102, 0x1118, 0x2300, 0x9005,
- 0x0020, 0x0210, 0x9302, 0x0008, 0x8002, 0x0005, 0x00d6, 0x7814,
- 0x9005, 0x090c, 0x0dc5, 0x781c, 0x9084, 0x0101, 0x9086, 0x0101,
- 0x190c, 0x0dc5, 0x7827, 0x0000, 0x2069, 0x193e, 0x6804, 0x9080,
- 0x1940, 0x2f08, 0x2102, 0x6904, 0x8108, 0x9182, 0x0008, 0x0208,
- 0x900e, 0x6906, 0x9180, 0x1940, 0x2003, 0x0000, 0x00de, 0x0005,
- 0x0096, 0x00c6, 0x2060, 0x6014, 0x2048, 0xa8a8, 0x0096, 0x2048,
- 0x9005, 0x190c, 0x1040, 0x009e, 0xa8ab, 0x0000, 0x080c, 0x0fc0,
- 0x080c, 0xb0e7, 0x00ce, 0x009e, 0x0005, 0x6020, 0x9086, 0x0009,
- 0x1128, 0x601c, 0xd0c4, 0x0110, 0x9006, 0x0005, 0x9085, 0x0001,
- 0x0005, 0x6000, 0x9086, 0x0000, 0x0178, 0x6010, 0x9005, 0x0150,
- 0x00b6, 0x2058, 0x080c, 0x8f2b, 0x00be, 0x6013, 0x0000, 0x601b,
- 0x0000, 0x0010, 0x2c00, 0x0861, 0x0005, 0x2009, 0x1929, 0x210c,
- 0xd194, 0x0005, 0x0126, 0x2091, 0x8000, 0x00e6, 0x2071, 0x1925,
- 0x7110, 0xc194, 0xd19c, 0x1118, 0xc185, 0x7007, 0x0000, 0x7112,
- 0x2001, 0x003b, 0x080c, 0x1611, 0x00ee, 0x012e, 0x0005, 0x7814,
- 0xd0bc, 0x1108, 0x0005, 0x7810, 0xc0c5, 0x7812, 0x0cc0, 0x0096,
- 0x00d6, 0x9006, 0x7006, 0x700e, 0x701a, 0x701e, 0x7022, 0x7016,
- 0x702a, 0x7026, 0x702f, 0x0000, 0x080c, 0x8d76, 0x0170, 0x080c,
- 0x8dab, 0x0158, 0x2900, 0x7002, 0x700a, 0x701a, 0x7013, 0x0001,
- 0x701f, 0x000a, 0x00de, 0x009e, 0x0005, 0x900e, 0x0cd8, 0x00e6,
- 0x0096, 0x0086, 0x00d6, 0x00c6, 0x2071, 0x1932, 0x721c, 0x2100,
- 0x9202, 0x1618, 0x080c, 0x8dab, 0x090c, 0x0dc5, 0x7018, 0x9005,
- 0x1160, 0x2900, 0x7002, 0x700a, 0x701a, 0x9006, 0x7006, 0x700e,
- 0xa806, 0xa802, 0x7012, 0x701e, 0x0038, 0x2040, 0xa806, 0x2900,
- 0xa002, 0x701a, 0xa803, 0x0000, 0x7010, 0x8000, 0x7012, 0x701c,
- 0x9080, 0x000a, 0x701e, 0x721c, 0x08d0, 0x721c, 0x00ce, 0x00de,
- 0x008e, 0x009e, 0x00ee, 0x0005, 0x0096, 0x0156, 0x0136, 0x0146,
- 0x00e6, 0x0126, 0x2091, 0x8000, 0x2071, 0x1932, 0x7300, 0x831f,
- 0x831e, 0x831e, 0x9384, 0x003f, 0x20e8, 0x939c, 0xffc0, 0x9398,
- 0x0003, 0x7104, 0x080c, 0x8d28, 0x810c, 0x2100, 0x9318, 0x8003,
- 0x2228, 0x2021, 0x0078, 0x9402, 0x9532, 0x0208, 0x2028, 0x2500,
- 0x8004, 0x20a8, 0x23a0, 0xa001, 0xa001, 0x4005, 0x2508, 0x080c,
- 0x8d31, 0x2130, 0x7014, 0x9600, 0x7016, 0x2600, 0x711c, 0x9102,
- 0x701e, 0x7004, 0x9600, 0x2008, 0x9082, 0x000a, 0x1190, 0x7000,
- 0x2048, 0xa800, 0x9005, 0x1148, 0x2009, 0x0001, 0x0026, 0x080c,
- 0x8c1f, 0x002e, 0x7000, 0x2048, 0xa800, 0x7002, 0x7007, 0x0000,
- 0x0008, 0x7106, 0x2500, 0x9212, 0x1904, 0x8c5e, 0x012e, 0x00ee,
- 0x014e, 0x013e, 0x015e, 0x009e, 0x0005, 0x0016, 0x0026, 0x00e6,
- 0x0126, 0x2091, 0x8000, 0x9580, 0x8dee, 0x2005, 0x9075, 0x090c,
- 0x0dc5, 0x080c, 0x8d03, 0x012e, 0x9580, 0x8dea, 0x2005, 0x9075,
- 0x090c, 0x0dc5, 0x0156, 0x0136, 0x01c6, 0x0146, 0x01d6, 0x831f,
- 0x831e, 0x831e, 0x9384, 0x003f, 0x20e0, 0x9384, 0xffc0, 0x9100,
- 0x2098, 0xa860, 0x20e8, 0xa95c, 0x2c05, 0x9100, 0x20a0, 0x20a9,
- 0x0002, 0x4003, 0x2e0c, 0x2d00, 0x0002, 0x8ced, 0x8ced, 0x8cef,
- 0x8ced, 0x8cef, 0x8ced, 0x8ced, 0x8ced, 0x8ced, 0x8ced, 0x8cf5,
- 0x8ced, 0x8cf5, 0x8ced, 0x8ced, 0x8ced, 0x080c, 0x0dc5, 0x4104,
- 0x20a9, 0x0002, 0x4002, 0x4003, 0x0028, 0x20a9, 0x0002, 0x4003,
- 0x4104, 0x4003, 0x01de, 0x014e, 0x01ce, 0x013e, 0x015e, 0x00ee,
- 0x002e, 0x001e, 0x0005, 0x0096, 0x7014, 0x8001, 0x7016, 0x710c,
- 0x2110, 0x00f1, 0x810c, 0x9188, 0x0003, 0x7308, 0x8210, 0x9282,
- 0x000a, 0x1198, 0x7008, 0x2048, 0xa800, 0x9005, 0x0158, 0x0006,
- 0x080c, 0x8dba, 0x009e, 0xa807, 0x0000, 0x2900, 0x700a, 0x7010,
- 0x8001, 0x7012, 0x700f, 0x0000, 0x0008, 0x720e, 0x009e, 0x0005,
- 0x0006, 0x810b, 0x810b, 0x2100, 0x810b, 0x9100, 0x2008, 0x000e,
- 0x0005, 0x0006, 0x0026, 0x2100, 0x9005, 0x0158, 0x9092, 0x000c,
- 0x0240, 0x900e, 0x8108, 0x9082, 0x000c, 0x1de0, 0x002e, 0x000e,
- 0x0005, 0x900e, 0x0cd8, 0x2d00, 0x90b8, 0x0008, 0x2031, 0x8d74,
- 0x901e, 0x6808, 0x9005, 0x0108, 0x8318, 0x690c, 0x910a, 0x0248,
- 0x0140, 0x8318, 0x6810, 0x9112, 0x0220, 0x0118, 0x8318, 0x2208,
- 0x0cd0, 0x233a, 0x6804, 0xd084, 0x2300, 0x2021, 0x0001, 0x1150,
- 0x9082, 0x0003, 0x0967, 0x0a67, 0x8420, 0x9082, 0x0007, 0x0967,
- 0x0a67, 0x0cd0, 0x9082, 0x0002, 0x0967, 0x0a67, 0x8420, 0x9082,
- 0x0005, 0x0967, 0x0a67, 0x0cd0, 0x6c1a, 0x0005, 0x0096, 0x0046,
- 0x0126, 0x2091, 0x8000, 0x2b00, 0x9080, 0x8df2, 0x2005, 0x9005,
- 0x090c, 0x0dc5, 0x2004, 0x90a0, 0x000a, 0x080c, 0x1027, 0x01d0,
- 0x2900, 0x7026, 0xa803, 0x0000, 0xa807, 0x0000, 0x080c, 0x1027,
- 0x0188, 0x7024, 0xa802, 0xa807, 0x0000, 0x2900, 0x7026, 0x94a2,
- 0x000a, 0x0110, 0x0208, 0x0c90, 0x9085, 0x0001, 0x012e, 0x004e,
- 0x009e, 0x0005, 0x7024, 0x9005, 0x0dc8, 0x2048, 0xac00, 0x080c,
- 0x1040, 0x2400, 0x0cc0, 0x0126, 0x2091, 0x8000, 0x7024, 0x2048,
- 0x9005, 0x0130, 0xa800, 0x7026, 0xa803, 0x0000, 0xa807, 0x0000,
- 0x012e, 0x0005, 0x0126, 0x2091, 0x8000, 0x7024, 0xa802, 0x2900,
- 0x7026, 0x012e, 0x0005, 0x0096, 0x9e80, 0x0009, 0x2004, 0x9005,
- 0x0138, 0x2048, 0xa800, 0x0006, 0x080c, 0x1040, 0x000e, 0x0cb8,
- 0x009e, 0x0005, 0x0096, 0x7008, 0x9005, 0x0138, 0x2048, 0xa800,
- 0x0006, 0x080c, 0x1040, 0x000e, 0x0cb8, 0x9006, 0x7002, 0x700a,
- 0x7006, 0x700e, 0x701a, 0x701e, 0x7022, 0x702a, 0x7026, 0x702e,
- 0x009e, 0x0005, 0x1a68, 0x0000, 0x0000, 0x0000, 0x1932, 0x0000,
- 0x0000, 0x0000, 0x1888, 0x0000, 0x0000, 0x0000, 0x1877, 0x0000,
- 0x0000, 0x0000, 0x00e6, 0x00c6, 0x00b6, 0x00a6, 0xa8a8, 0x2040,
- 0x2071, 0x1877, 0x080c, 0x8f16, 0xa067, 0x0023, 0x6010, 0x905d,
- 0x0904, 0x8eeb, 0xb814, 0xa06e, 0xb910, 0xa172, 0xb9a0, 0xa176,
- 0x2001, 0x0003, 0xa07e, 0xa834, 0xa082, 0xa07b, 0x0000, 0xa898,
- 0x9005, 0x0118, 0xa078, 0xc085, 0xa07a, 0x2858, 0x2031, 0x0018,
- 0xa068, 0x908a, 0x0019, 0x1a0c, 0x0dc5, 0x2020, 0x2050, 0x2940,
- 0xa864, 0x90bc, 0x00ff, 0x908c, 0x000f, 0x91e0, 0x20e8, 0x2c65,
- 0x9786, 0x0024, 0x2c05, 0x1590, 0x908a, 0x0036, 0x1a0c, 0x0dc5,
- 0x9082, 0x001b, 0x0002, 0x8e56, 0x8e56, 0x8e58, 0x8e56, 0x8e56,
- 0x8e56, 0x8e5a, 0x8e56, 0x8e56, 0x8e56, 0x8e5c, 0x8e56, 0x8e56,
- 0x8e56, 0x8e5e, 0x8e56, 0x8e56, 0x8e56, 0x8e60, 0x8e56, 0x8e56,
- 0x8e56, 0x8e62, 0x8e56, 0x8e56, 0x8e56, 0x8e64, 0x080c, 0x0dc5,
- 0xa180, 0x04b8, 0xa190, 0x04a8, 0xa1a0, 0x0498, 0xa1b0, 0x0488,
- 0xa1c0, 0x0478, 0xa1d0, 0x0468, 0xa1e0, 0x0458, 0x908a, 0x0034,
- 0x1a0c, 0x0dc5, 0x9082, 0x001b, 0x0002, 0x8e88, 0x8e86, 0x8e86,
- 0x8e86, 0x8e86, 0x8e86, 0x8e8a, 0x8e86, 0x8e86, 0x8e86, 0x8e86,
- 0x8e86, 0x8e8c, 0x8e86, 0x8e86, 0x8e86, 0x8e86, 0x8e86, 0x8e8e,
- 0x8e86, 0x8e86, 0x8e86, 0x8e86, 0x8e86, 0x8e90, 0x080c, 0x0dc5,
- 0xa180, 0x0038, 0xa198, 0x0028, 0xa1b0, 0x0018, 0xa1c8, 0x0008,
- 0xa1e0, 0x2600, 0x0002, 0x8eac, 0x8eae, 0x8eb0, 0x8eb2, 0x8eb4,
- 0x8eb6, 0x8eb8, 0x8eba, 0x8ebc, 0x8ebe, 0x8ec0, 0x8ec2, 0x8ec4,
- 0x8ec6, 0x8ec8, 0x8eca, 0x8ecc, 0x8ece, 0x8ed0, 0x8ed2, 0x8ed4,
- 0x8ed6, 0x8ed8, 0x8eda, 0x8edc, 0x080c, 0x0dc5, 0xb9e2, 0x0468,
- 0xb9de, 0x0458, 0xb9da, 0x0448, 0xb9d6, 0x0438, 0xb9d2, 0x0428,
- 0xb9ce, 0x0418, 0xb9ca, 0x0408, 0xb9c6, 0x00f8, 0xb9c2, 0x00e8,
- 0xb9be, 0x00d8, 0xb9ba, 0x00c8, 0xb9b6, 0x00b8, 0xb9b2, 0x00a8,
- 0xb9ae, 0x0098, 0xb9aa, 0x0088, 0xb9a6, 0x0078, 0xb9a2, 0x0068,
- 0xb99e, 0x0058, 0xb99a, 0x0048, 0xb996, 0x0038, 0xb992, 0x0028,
- 0xb98e, 0x0018, 0xb98a, 0x0008, 0xb986, 0x8631, 0x8421, 0x0130,
- 0x080c, 0x20a0, 0x090c, 0x0dc5, 0x0804, 0x8e30, 0x00ae, 0x00be,
- 0x00ce, 0x00ee, 0x0005, 0xa86c, 0xa06e, 0xa870, 0xa072, 0xa077,
- 0x00ff, 0x9006, 0x0804, 0x8e12, 0x0006, 0x0016, 0x00b6, 0x6010,
- 0x2058, 0xb810, 0x9005, 0x01b0, 0x2001, 0x1926, 0x2004, 0x9005,
- 0x0188, 0x2001, 0x1800, 0x2004, 0x9086, 0x0003, 0x1158, 0x0036,
- 0x0046, 0xbba0, 0x2021, 0x0004, 0x2011, 0x8014, 0x080c, 0x4be3,
- 0x004e, 0x003e, 0x00be, 0x001e, 0x000e, 0x0005, 0x9016, 0x710c,
- 0xa834, 0x910a, 0xa936, 0x7008, 0x9005, 0x0120, 0x8210, 0x910a,
- 0x0238, 0x0130, 0x7010, 0x8210, 0x910a, 0x0210, 0x0108, 0x0cd8,
- 0xaa8a, 0xa26a, 0x0005, 0x00f6, 0x00d6, 0x0036, 0x2079, 0x0300,
- 0x781b, 0x0200, 0x7818, 0xd094, 0x1dd8, 0x781b, 0x0202, 0xa001,
- 0xa001, 0x7818, 0xd094, 0x1da0, 0xb8ac, 0x9005, 0x01b8, 0x2068,
- 0x2079, 0x0000, 0x2c08, 0x911e, 0x1118, 0x680c, 0xb8ae, 0x0060,
- 0x9106, 0x0140, 0x2d00, 0x2078, 0x680c, 0x9005, 0x090c, 0x0dc5,
- 0x2068, 0x0cb0, 0x6b0c, 0x7b0e, 0x600f, 0x0000, 0x2079, 0x0300,
- 0x781b, 0x0200, 0x003e, 0x00de, 0x00fe, 0x0005, 0x00e6, 0x00d6,
- 0x0096, 0x00c6, 0x0036, 0x0126, 0x2091, 0x8000, 0x0156, 0x20a9,
- 0x01ff, 0x2071, 0x0300, 0x701b, 0x0200, 0x7018, 0xd094, 0x0110,
- 0x1f04, 0x8f6b, 0x701b, 0x0202, 0xa001, 0xa001, 0x7018, 0xd094,
- 0x1d90, 0xb8ac, 0x9005, 0x01e8, 0x2060, 0x600c, 0xb8ae, 0x6024,
- 0xc08d, 0x6026, 0x6003, 0x0004, 0x601b, 0x0000, 0x6013, 0x0000,
- 0x601f, 0x0101, 0x6014, 0x2048, 0xa88b, 0x0000, 0xa8a8, 0xa8ab,
- 0x0000, 0x904d, 0x090c, 0x0dc5, 0x080c, 0x1040, 0x080c, 0x8b27,
- 0x0c00, 0x2071, 0x0300, 0x701b, 0x0200, 0x015e, 0x012e, 0x003e,
- 0x00ce, 0x009e, 0x00de, 0x00ee, 0x0005, 0x00c6, 0x00b6, 0x0016,
- 0x0006, 0x0156, 0x080c, 0x2889, 0x015e, 0x11b0, 0x080c, 0x66ac,
- 0x190c, 0x0dc5, 0x000e, 0x001e, 0xb912, 0xb816, 0x080c, 0xb091,
- 0x0140, 0x2b00, 0x6012, 0x6023, 0x0001, 0x2009, 0x0001, 0x080c,
- 0xb166, 0x00be, 0x00ce, 0x0005, 0x000e, 0x001e, 0x0cd0, 0x0066,
- 0x6000, 0x90b2, 0x0016, 0x1a0c, 0x0dc5, 0x0013, 0x006e, 0x0005,
- 0x8fe0, 0x8fe0, 0x8fe0, 0x8fe2, 0x9033, 0x8fe0, 0x8fe0, 0x8fe0,
- 0x909a, 0x8fe0, 0x90d7, 0x8fe0, 0x8fe0, 0x8fe0, 0x8fe0, 0x8fe0,
- 0x080c, 0x0dc5, 0x9182, 0x0040, 0x0002, 0x8ff5, 0x8ff5, 0x8ff5,
- 0x8ff5, 0x8ff5, 0x8ff5, 0x8ff5, 0x8ff5, 0x8ff5, 0x8ff7, 0x900c,
- 0x8ff5, 0x8ff5, 0x8ff5, 0x8ff5, 0x901f, 0x080c, 0x0dc5, 0x0096,
- 0x080c, 0x9897, 0x080c, 0x9a09, 0x6114, 0x2148, 0xa87b, 0x0000,
- 0x6010, 0x00b6, 0x2058, 0xb8bb, 0x0500, 0x00be, 0x080c, 0x6bcf,
- 0x080c, 0xb0e7, 0x009e, 0x0005, 0x080c, 0x9897, 0x00d6, 0x6114,
- 0x080c, 0xce3f, 0x0130, 0x0096, 0x6114, 0x2148, 0x080c, 0x6dcb,
- 0x009e, 0x00de, 0x080c, 0xb0e7, 0x080c, 0x9a09, 0x0005, 0x080c,
- 0x9897, 0x080c, 0x324b, 0x6114, 0x0096, 0x2148, 0x080c, 0xce3f,
- 0x0120, 0xa87b, 0x0029, 0x080c, 0x6dcb, 0x009e, 0x080c, 0xb0e7,
- 0x080c, 0x9a09, 0x0005, 0x601b, 0x0000, 0x9182, 0x0040, 0x0096,
- 0x0002, 0x904e, 0x904e, 0x904e, 0x904e, 0x904e, 0x904e, 0x904e,
- 0x904e, 0x9050, 0x904e, 0x904e, 0x904e, 0x9096, 0x904e, 0x904e,
- 0x904e, 0x904e, 0x904e, 0x904e, 0x9057, 0x904e, 0x080c, 0x0dc5,
- 0x6114, 0x2148, 0xa938, 0x918e, 0xffff, 0x0904, 0x9096, 0x6024,
- 0xd08c, 0x15c0, 0x00e6, 0x6114, 0x2148, 0x080c, 0x8dfa, 0x0096,
- 0xa8a8, 0x2048, 0x080c, 0x6b67, 0x009e, 0xa8ab, 0x0000, 0x6010,
- 0x9005, 0x0128, 0x00b6, 0x2058, 0x080c, 0x8f2b, 0x00be, 0xae88,
- 0x00b6, 0x2059, 0x0000, 0x080c, 0x8b30, 0x00be, 0x01e0, 0x2071,
- 0x193e, 0x080c, 0x8b77, 0x01b8, 0x9086, 0x0001, 0x1128, 0x2001,
- 0x1948, 0x2004, 0x9005, 0x1178, 0x0096, 0x080c, 0x100e, 0x2900,
- 0x009e, 0x0148, 0xa8aa, 0x00f6, 0x2c78, 0x080c, 0x8aee, 0x00fe,
- 0x00ee, 0x009e, 0x0005, 0x080c, 0x8b27, 0x0cd0, 0x080c, 0x9144,
- 0x009e, 0x0005, 0x9182, 0x0040, 0x0096, 0x0002, 0x90ae, 0x90ae,
- 0x90ae, 0x90b0, 0x90ae, 0x90ae, 0x90ae, 0x90d5, 0x90ae, 0x90ae,
- 0x90ae, 0x90ae, 0x90ae, 0x90ae, 0x90ae, 0x90ae, 0x080c, 0x0dc5,
- 0x6003, 0x0003, 0x6106, 0x6014, 0x2048, 0xa8ac, 0xa846, 0xa8b0,
- 0xa84a, 0xa837, 0x0000, 0xa83b, 0x0000, 0xa884, 0x9092, 0x199a,
- 0x0210, 0x2001, 0x1999, 0x8003, 0x8013, 0x8213, 0x9210, 0x621a,
- 0x2c10, 0x080c, 0x1c01, 0x080c, 0x939a, 0x0126, 0x2091, 0x8000,
- 0x080c, 0x9a09, 0x012e, 0x009e, 0x0005, 0x080c, 0x0dc5, 0x080c,
- 0x9897, 0x080c, 0x9a09, 0x6114, 0x2148, 0xa87b, 0x0000, 0x6010,
- 0x00b6, 0x2058, 0xb8bb, 0x0500, 0x00be, 0x080c, 0x6dcb, 0x080c,
- 0xb0e7, 0x009e, 0x0005, 0x6000, 0x908a, 0x0016, 0x1a0c, 0x0dc5,
- 0x0096, 0x0013, 0x009e, 0x0005, 0x9104, 0x9104, 0x9104, 0x9106,
- 0x9117, 0x9104, 0x9104, 0x9104, 0x9104, 0x9104, 0x9104, 0x9104,
- 0x9104, 0x9104, 0x9104, 0x9104, 0x080c, 0x0dc5, 0x080c, 0xaa3f,
- 0x6114, 0x2148, 0xa87b, 0x0006, 0x6010, 0x00b6, 0x2058, 0xb8bb,
- 0x0500, 0x00be, 0x080c, 0x6dcb, 0x080c, 0xb0e7, 0x0005, 0x0461,
- 0x0005, 0x6000, 0x908a, 0x0016, 0x1a0c, 0x0dc5, 0x0096, 0x0013,
- 0x009e, 0x0005, 0x9132, 0x9132, 0x9132, 0x9134, 0x9144, 0x9132,
- 0x9132, 0x9132, 0x9132, 0x9132, 0x9132, 0x9132, 0x9132, 0x9132,
- 0x9132, 0x9132, 0x080c, 0x0dc5, 0x0036, 0x00e6, 0x2071, 0x19e9,
- 0x703c, 0x9c06, 0x1120, 0x2019, 0x0000, 0x080c, 0xa85d, 0x080c,
- 0xaa3f, 0x00ee, 0x003e, 0x0005, 0x6024, 0xd08c, 0x11f0, 0x00f6,
- 0x00e6, 0x601b, 0x0000, 0x6014, 0x2048, 0x6010, 0x9005, 0x0128,
- 0x00b6, 0x2058, 0x080c, 0x8f2b, 0x00be, 0x2071, 0x193e, 0x080c,
- 0x8b77, 0x0160, 0x2001, 0x187f, 0x2004, 0xa88a, 0x2031, 0x0000,
- 0x2c78, 0x080c, 0x8aee, 0x00ee, 0x00fe, 0x0005, 0x0096, 0xa88b,
- 0x0000, 0xa8a8, 0x2048, 0x080c, 0x1040, 0x009e, 0xa8ab, 0x0000,
- 0x080c, 0x8b27, 0x0c80, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x187a, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0126, 0x2091, 0x8000, 0x0036, 0x0046,
- 0x20a9, 0x0010, 0x9006, 0x8004, 0x2019, 0x0100, 0x231c, 0x93a6,
- 0x0008, 0x1118, 0x8086, 0x818e, 0x0020, 0x80f6, 0x3e00, 0x81f6,
- 0x3e08, 0x1208, 0x9200, 0x1f04, 0x918c, 0x93a6, 0x0008, 0x1118,
- 0x8086, 0x818e, 0x0020, 0x80f6, 0x3e00, 0x81f6, 0x3e08, 0x004e,
- 0x003e, 0x012e, 0x0005, 0x0126, 0x2091, 0x8000, 0x0076, 0x0156,
- 0x20a9, 0x0010, 0x9005, 0x0510, 0x911a, 0x1600, 0x8213, 0x2039,
- 0x0100, 0x273c, 0x97be, 0x0008, 0x1110, 0x818d, 0x0010, 0x81f5,
- 0x3e08, 0x0228, 0x911a, 0x1220, 0x1f04, 0x91b6, 0x0028, 0x911a,
- 0x2308, 0x8210, 0x1f04, 0x91b6, 0x0006, 0x3200, 0x9084, 0xefff,
- 0x2080, 0x000e, 0x015e, 0x007e, 0x012e, 0x0005, 0x0006, 0x3200,
- 0x9085, 0x1000, 0x0ca8, 0x0126, 0x2091, 0x2800, 0x2079, 0x19e9,
- 0x012e, 0x00d6, 0x2069, 0x19e9, 0x6803, 0x0005, 0x0156, 0x0146,
- 0x01d6, 0x20e9, 0x0000, 0x2069, 0x0200, 0x080c, 0xada2, 0x0401,
- 0x080c, 0xad8d, 0x00e9, 0x080c, 0xad90, 0x00d1, 0x080c, 0xad93,
- 0x00b9, 0x080c, 0xad96, 0x00a1, 0x080c, 0xad99, 0x0089, 0x080c,
- 0xad9c, 0x0071, 0x080c, 0xad9f, 0x0059, 0x01de, 0x014e, 0x015e,
- 0x2069, 0x0004, 0x2d04, 0x9085, 0x8001, 0x206a, 0x00de, 0x0005,
- 0x20a9, 0x0020, 0x20a1, 0x0240, 0x2001, 0x0000, 0x4004, 0x0005,
- 0x00c6, 0x6027, 0x0001, 0x7804, 0x9084, 0x0007, 0x0002, 0x9229,
- 0x924d, 0x928e, 0x922f, 0x924d, 0x9229, 0x9227, 0x9227, 0x080c,
- 0x0dc5, 0x080c, 0x8789, 0x080c, 0x98e7, 0x00ce, 0x0005, 0x62c0,
- 0x82ff, 0x1110, 0x00ce, 0x0005, 0x2011, 0x5f8a, 0x080c, 0x8703,
- 0x7828, 0x9092, 0x00c8, 0x1228, 0x8000, 0x782a, 0x080c, 0x5fca,
- 0x0c88, 0x62c0, 0x080c, 0xaede, 0x080c, 0x5f8a, 0x7807, 0x0003,
- 0x7827, 0x0000, 0x782b, 0x0000, 0x0c28, 0x080c, 0x8789, 0x6220,
- 0xd2a4, 0x0170, 0xd2cc, 0x0160, 0x782b, 0x0000, 0x7824, 0x9065,
- 0x090c, 0x0dc5, 0x2009, 0x0013, 0x080c, 0xb166, 0x00ce, 0x0005,
- 0x00c6, 0x7824, 0x9065, 0x090c, 0x0dc5, 0x7828, 0x9092, 0xc350,
- 0x12c0, 0x8000, 0x782a, 0x00ce, 0x080c, 0x2bf0, 0x0278, 0x00c6,
- 0x7924, 0x2160, 0x6010, 0x906d, 0x090c, 0x0dc5, 0x7807, 0x0000,
- 0x7827, 0x0000, 0x00ce, 0x080c, 0x98e7, 0x0c00, 0x080c, 0xa4d9,
- 0x08e8, 0x2011, 0x0130, 0x2214, 0x080c, 0xaede, 0x080c, 0xedaa,
- 0x2009, 0x0014, 0x080c, 0xb166, 0x00ce, 0x0880, 0x2001, 0x1a05,
- 0x2003, 0x0000, 0x62c0, 0x82ff, 0x1160, 0x782b, 0x0000, 0x7824,
- 0x9065, 0x090c, 0x0dc5, 0x2009, 0x0013, 0x080c, 0xb1b8, 0x00ce,
- 0x0005, 0x00b6, 0x00c6, 0x00d6, 0x7824, 0x9005, 0x090c, 0x0dc5,
- 0x7828, 0x9092, 0xc350, 0x1648, 0x8000, 0x782a, 0x00de, 0x00ce,
- 0x00be, 0x080c, 0x2bf0, 0x02f0, 0x00b6, 0x00c6, 0x00d6, 0x781c,
- 0x905d, 0x090c, 0x0dc5, 0xb800, 0xc0dc, 0xb802, 0x7924, 0x2160,
- 0x080c, 0xb0e7, 0xb93c, 0x81ff, 0x090c, 0x0dc5, 0x8109, 0xb93e,
- 0x7807, 0x0000, 0x7827, 0x0000, 0x00de, 0x00ce, 0x00be, 0x080c,
- 0x98e7, 0x0868, 0x080c, 0xa4d9, 0x0850, 0x2011, 0x0130, 0x2214,
- 0x080c, 0xaede, 0x080c, 0xedaa, 0x7824, 0x9065, 0x2009, 0x0014,
- 0x080c, 0xb166, 0x00de, 0x00ce, 0x00be, 0x0804, 0x929f, 0x00c6,
- 0x2001, 0x009b, 0x2004, 0xd0fc, 0x190c, 0x1f0c, 0x6024, 0x6027,
- 0x0002, 0xd0f4, 0x15b8, 0x62c8, 0x60c4, 0x9205, 0x1170, 0x783c,
- 0x9065, 0x0130, 0x2009, 0x0049, 0x080c, 0xb166, 0x00ce, 0x0005,
- 0x2011, 0x1a08, 0x2013, 0x0000, 0x0cc8, 0x793c, 0x81ff, 0x0dc0,
- 0x7944, 0x9192, 0x7530, 0x1628, 0x8108, 0x7946, 0x793c, 0x9188,
- 0x0008, 0x210c, 0x918e, 0x0006, 0x1138, 0x6014, 0x9084, 0x1984,
- 0x9085, 0x0012, 0x6016, 0x0c10, 0x793c, 0x9188, 0x0008, 0x210c,
- 0x918e, 0x0009, 0x0d90, 0x6014, 0x9084, 0x1984, 0x9085, 0x0016,
- 0x6016, 0x08a0, 0x793c, 0x2160, 0x2009, 0x004a, 0x080c, 0xb166,
- 0x0868, 0x7848, 0xc085, 0x784a, 0x0848, 0x0006, 0x0016, 0x00c6,
- 0x0126, 0x2091, 0x8000, 0x600f, 0x0000, 0x2c08, 0x2061, 0x19e9,
- 0x6020, 0x8000, 0x6022, 0x6010, 0x9005, 0x0148, 0x9080, 0x0003,
- 0x2102, 0x6112, 0x012e, 0x00ce, 0x001e, 0x000e, 0x0005, 0x6116,
- 0x6112, 0x0cc0, 0x00d6, 0x2069, 0x19e9, 0xb800, 0xd0d4, 0x0168,
- 0x6820, 0x8000, 0x6822, 0x9086, 0x0001, 0x1110, 0x2b00, 0x681e,
- 0x00de, 0x0804, 0x98e7, 0x00de, 0x0005, 0xc0d5, 0xb802, 0x6818,
- 0x9005, 0x0168, 0xb856, 0xb85b, 0x0000, 0x0086, 0x0006, 0x2b00,
- 0x681a, 0x008e, 0xa05a, 0x008e, 0x2069, 0x19e9, 0x0c08, 0xb856,
- 0xb85a, 0x2b00, 0x681a, 0x681e, 0x08d8, 0x0006, 0x0016, 0x00c6,
- 0x0126, 0x2091, 0x8000, 0x600f, 0x0000, 0x2c08, 0x2061, 0x19e9,
- 0x6020, 0x8000, 0x6022, 0x6008, 0x9005, 0x0148, 0x9080, 0x0003,
- 0x2102, 0x610a, 0x012e, 0x00ce, 0x001e, 0x000e, 0x0005, 0x610e,
- 0x610a, 0x0cc0, 0x00c6, 0x600f, 0x0000, 0x2c08, 0x2061, 0x19e9,
- 0x6034, 0x9005, 0x0130, 0x9080, 0x0003, 0x2102, 0x6136, 0x00ce,
- 0x0005, 0x613a, 0x6136, 0x00ce, 0x0005, 0x00f6, 0x00e6, 0x00d6,
- 0x00c6, 0x00b6, 0x0096, 0x0076, 0x0066, 0x0056, 0x0036, 0x0026,
- 0x0016, 0x0006, 0x0126, 0x902e, 0x2071, 0x19e9, 0x7638, 0x2660,
- 0x2678, 0x2091, 0x8000, 0x8cff, 0x0904, 0x9429, 0x6010, 0x2058,
- 0xb8a0, 0x9206, 0x1904, 0x9424, 0x87ff, 0x0120, 0x6054, 0x9106,
- 0x1904, 0x9424, 0x703c, 0x9c06, 0x1178, 0x0036, 0x2019, 0x0001,
- 0x080c, 0xa85d, 0x7033, 0x0000, 0x9006, 0x703e, 0x7042, 0x7046,
- 0x704a, 0x003e, 0x2029, 0x0001, 0x7038, 0x9c36, 0x1110, 0x660c,
- 0x763a, 0x7034, 0x9c36, 0x1140, 0x2c00, 0x9f36, 0x0118, 0x2f00,
- 0x7036, 0x0010, 0x7037, 0x0000, 0x660c, 0x0066, 0x2c00, 0x9f06,
- 0x0110, 0x7e0e, 0x0008, 0x2678, 0x600f, 0x0000, 0x080c, 0xce3f,
- 0x01f0, 0x6014, 0x2048, 0x6020, 0x9086, 0x0003, 0x15b8, 0x6004,
- 0x9086, 0x0040, 0x090c, 0xaa2f, 0xa867, 0x0103, 0xab7a, 0xa877,
- 0x0000, 0x0016, 0x0036, 0x0076, 0x080c, 0xd135, 0x080c, 0xec9b,
- 0x080c, 0x6dcb, 0x007e, 0x003e, 0x001e, 0x080c, 0xd02a, 0x080c,
- 0xb11a, 0x00ce, 0x0804, 0x93c3, 0x2c78, 0x600c, 0x2060, 0x0804,
- 0x93c3, 0x85ff, 0x0120, 0x0036, 0x080c, 0x9a09, 0x003e, 0x012e,
- 0x000e, 0x001e, 0x002e, 0x003e, 0x005e, 0x006e, 0x007e, 0x009e,
- 0x00be, 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x0005, 0x6020, 0x9086,
- 0x0006, 0x1158, 0x0016, 0x0036, 0x0076, 0x080c, 0xec9b, 0x080c,
- 0xe8e3, 0x007e, 0x003e, 0x001e, 0x0890, 0x6020, 0x9086, 0x0009,
- 0x1168, 0xa87b, 0x0006, 0x0016, 0x0036, 0x0076, 0x080c, 0x6dcb,
- 0x080c, 0xb0e7, 0x007e, 0x003e, 0x001e, 0x0818, 0x6020, 0x9086,
- 0x000a, 0x0904, 0x940e, 0x0804, 0x9407, 0x0006, 0x0066, 0x0096,
- 0x00c6, 0x00d6, 0x00f6, 0x9036, 0x0126, 0x2091, 0x8000, 0x2079,
- 0x19e9, 0x7838, 0x9065, 0x0904, 0x94ba, 0x600c, 0x0006, 0x600f,
- 0x0000, 0x783c, 0x9c06, 0x1168, 0x0036, 0x2019, 0x0001, 0x080c,
- 0xa85d, 0x7833, 0x0000, 0x901e, 0x7b3e, 0x7b42, 0x7b46, 0x7b4a,
- 0x003e, 0x080c, 0xce3f, 0x0548, 0x6014, 0x2048, 0x6020, 0x9086,
- 0x0003, 0x1590, 0x3e08, 0x918e, 0x0002, 0x1188, 0x6010, 0x9005,
- 0x0170, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x0140, 0x6040,
- 0x9005, 0x11a8, 0x2001, 0x1989, 0x2004, 0x6042, 0x0080, 0x6004,
- 0x9086, 0x0040, 0x090c, 0xaa2f, 0xa867, 0x0103, 0xab7a, 0xa877,
- 0x0000, 0x080c, 0x6dbe, 0x080c, 0xd02a, 0x080c, 0xb11a, 0x000e,
- 0x0804, 0x9472, 0x7e3a, 0x7e36, 0x012e, 0x00fe, 0x00de, 0x00ce,
- 0x009e, 0x006e, 0x000e, 0x0005, 0x6020, 0x9086, 0x0006, 0x1118,
- 0x080c, 0xe8e3, 0x0c50, 0x6020, 0x9086, 0x0009, 0x1130, 0xab7a,
- 0x080c, 0x6dcb, 0x080c, 0xb0e7, 0x0c10, 0x6020, 0x9086, 0x000a,
- 0x09a8, 0x0868, 0x0016, 0x0026, 0x0086, 0x9046, 0x0099, 0x080c,
- 0x95c5, 0x008e, 0x002e, 0x001e, 0x0005, 0x00f6, 0x0126, 0x2079,
- 0x19e9, 0x2091, 0x8000, 0x080c, 0x965c, 0x080c, 0x96ec, 0x012e,
- 0x00fe, 0x0005, 0x00b6, 0x0096, 0x00f6, 0x00e6, 0x00d6, 0x00c6,
- 0x0066, 0x0016, 0x0006, 0x0126, 0x2091, 0x8000, 0x2071, 0x19e9,
- 0x7614, 0x2660, 0x2678, 0x8cff, 0x0904, 0x958a, 0x6010, 0x2058,
- 0xb8a0, 0x9206, 0x1904, 0x9585, 0x88ff, 0x0120, 0x6054, 0x9106,
- 0x1904, 0x9585, 0x7024, 0x9c06, 0x1568, 0x2069, 0x0100, 0x6820,
- 0xd0a4, 0x0110, 0xd0cc, 0x1508, 0x080c, 0x8789, 0x080c, 0xa4fd,
- 0x68c3, 0x0000, 0x080c, 0xaa2f, 0x7027, 0x0000, 0x0036, 0x2069,
- 0x0140, 0x6b04, 0x9384, 0x1000, 0x0138, 0x2001, 0x0100, 0x080c,
- 0x2d5b, 0x9006, 0x080c, 0x2d5b, 0x2069, 0x0100, 0x6824, 0xd084,
- 0x0110, 0x6827, 0x0001, 0x003e, 0x0028, 0x6003, 0x0009, 0x630a,
- 0x0804, 0x9585, 0x7014, 0x9c36, 0x1110, 0x660c, 0x7616, 0x7010,
- 0x9c36, 0x1140, 0x2c00, 0x9f36, 0x0118, 0x2f00, 0x7012, 0x0010,
- 0x7013, 0x0000, 0x660c, 0x0066, 0x2c00, 0x9f06, 0x0110, 0x7e0e,
- 0x0008, 0x2678, 0x600f, 0x0000, 0x6014, 0x2048, 0x080c, 0xce3f,
- 0x01e8, 0x6020, 0x9086, 0x0003, 0x1580, 0x080c, 0xd047, 0x1118,
- 0x080c, 0xbacb, 0x0098, 0xa867, 0x0103, 0xab7a, 0xa877, 0x0000,
- 0x0016, 0x0036, 0x0086, 0x080c, 0xd135, 0x080c, 0xec9b, 0x080c,
- 0x6dcb, 0x008e, 0x003e, 0x001e, 0x080c, 0xd02a, 0x080c, 0xb11a,
- 0x080c, 0xa905, 0x00ce, 0x0804, 0x9503, 0x2c78, 0x600c, 0x2060,
- 0x0804, 0x9503, 0x012e, 0x000e, 0x001e, 0x006e, 0x00ce, 0x00de,
- 0x00ee, 0x00fe, 0x009e, 0x00be, 0x0005, 0x6020, 0x9086, 0x0006,
- 0x1158, 0x0016, 0x0036, 0x0086, 0x080c, 0xec9b, 0x080c, 0xe8e3,
- 0x008e, 0x003e, 0x001e, 0x08d0, 0x080c, 0xbacb, 0x6020, 0x9086,
- 0x0002, 0x1160, 0x6004, 0x0006, 0x9086, 0x0085, 0x000e, 0x0904,
- 0x956b, 0x9086, 0x008b, 0x0904, 0x956b, 0x0840, 0x6020, 0x9086,
- 0x0005, 0x1920, 0x6004, 0x0006, 0x9086, 0x0085, 0x000e, 0x09c8,
- 0x9086, 0x008b, 0x09b0, 0x0804, 0x957e, 0x00b6, 0x00a6, 0x0096,
- 0x00c6, 0x0006, 0x0126, 0x2091, 0x8000, 0x9280, 0x1000, 0x2004,
- 0x905d, 0x0904, 0x9655, 0x00f6, 0x00e6, 0x00d6, 0x0066, 0x2071,
- 0x19e9, 0xbe54, 0x7018, 0x9b06, 0x1108, 0x761a, 0x701c, 0x9b06,
- 0x1130, 0x86ff, 0x1118, 0x7018, 0x701e, 0x0008, 0x761e, 0xb858,
- 0x904d, 0x0108, 0xae56, 0x96d5, 0x0000, 0x0110, 0x2900, 0xb05a,
- 0xb857, 0x0000, 0xb85b, 0x0000, 0xb800, 0xc0d4, 0xc0dc, 0xb802,
- 0x080c, 0x663f, 0x0904, 0x9651, 0x7624, 0x86ff, 0x0904, 0x9640,
- 0x9680, 0x0005, 0x2004, 0x9906, 0x15d8, 0x00d6, 0x2069, 0x0100,
- 0x68c0, 0x9005, 0x0560, 0x080c, 0x8789, 0x080c, 0xa4fd, 0x68c3,
- 0x0000, 0x080c, 0xaa2f, 0x7027, 0x0000, 0x0036, 0x2069, 0x0140,
- 0x6b04, 0x9384, 0x1000, 0x0138, 0x2001, 0x0100, 0x080c, 0x2d5b,
- 0x9006, 0x080c, 0x2d5b, 0x2069, 0x0100, 0x6824, 0xd084, 0x0110,
- 0x6827, 0x0001, 0x003e, 0x00de, 0x00c6, 0xb83c, 0x9005, 0x0110,
- 0x8001, 0xb83e, 0x2660, 0x080c, 0xb11a, 0x00ce, 0x0048, 0x00de,
- 0x00c6, 0x2660, 0x6003, 0x0009, 0x630a, 0x00ce, 0x0804, 0x95f8,
- 0x89ff, 0x0158, 0xa867, 0x0103, 0xab7a, 0xa877, 0x0000, 0x080c,
- 0xd135, 0x080c, 0xec9b, 0x080c, 0x6dcb, 0x080c, 0xa905, 0x0804,
- 0x95f8, 0x006e, 0x00de, 0x00ee, 0x00fe, 0x012e, 0x000e, 0x00ce,
- 0x009e, 0x00ae, 0x00be, 0x0005, 0x0096, 0x0006, 0x0066, 0x00c6,
- 0x00d6, 0x9036, 0x7814, 0x9065, 0x0904, 0x96bf, 0x600c, 0x0006,
- 0x600f, 0x0000, 0x7824, 0x9c06, 0x1580, 0x2069, 0x0100, 0x6820,
- 0xd0a4, 0x0110, 0xd0cc, 0x1508, 0x080c, 0x8789, 0x080c, 0xa4fd,
- 0x68c3, 0x0000, 0x080c, 0xaa2f, 0x7827, 0x0000, 0x0036, 0x2069,
- 0x0140, 0x6b04, 0x9384, 0x1000, 0x0138, 0x2001, 0x0100, 0x080c,
- 0x2d5b, 0x9006, 0x080c, 0x2d5b, 0x2069, 0x0100, 0x6824, 0xd084,
- 0x0110, 0x6827, 0x0001, 0x003e, 0x0040, 0x080c, 0x6a24, 0x1520,
- 0x6003, 0x0009, 0x630a, 0x2c30, 0x00f8, 0x6014, 0x2048, 0x080c,
- 0xce3d, 0x01b0, 0x6020, 0x9086, 0x0003, 0x1508, 0x080c, 0xd047,
- 0x1118, 0x080c, 0xbacb, 0x0060, 0x080c, 0x6a24, 0x1168, 0xa867,
- 0x0103, 0xab7a, 0xa877, 0x0000, 0x080c, 0x6dcb, 0x080c, 0xd02a,
- 0x080c, 0xb11a, 0x080c, 0xa905, 0x000e, 0x0804, 0x9663, 0x7e16,
- 0x7e12, 0x00de, 0x00ce, 0x006e, 0x000e, 0x009e, 0x0005, 0x6020,
- 0x9086, 0x0006, 0x1118, 0x080c, 0xe8e3, 0x0c50, 0x080c, 0xbacb,
- 0x6020, 0x9086, 0x0002, 0x1150, 0x6004, 0x0006, 0x9086, 0x0085,
- 0x000e, 0x0990, 0x9086, 0x008b, 0x0978, 0x08d0, 0x6020, 0x9086,
- 0x0005, 0x19b0, 0x6004, 0x0006, 0x9086, 0x0085, 0x000e, 0x0d18,
- 0x9086, 0x008b, 0x0d00, 0x0860, 0x0006, 0x0066, 0x0096, 0x00b6,
- 0x00c6, 0x00d6, 0x7818, 0x905d, 0x0904, 0x976c, 0xb854, 0x0006,
- 0x9006, 0xb856, 0xb85a, 0xb800, 0xc0d4, 0xc0dc, 0xb802, 0x080c,
- 0x663f, 0x0904, 0x9769, 0x7e24, 0x86ff, 0x0904, 0x975c, 0x9680,
- 0x0005, 0x2004, 0x9906, 0x1904, 0x975c, 0x00d6, 0x2069, 0x0100,
- 0x68c0, 0x9005, 0x0904, 0x9753, 0x080c, 0x8789, 0x080c, 0xa4fd,
- 0x68c3, 0x0000, 0x080c, 0xaa2f, 0x7827, 0x0000, 0x0036, 0x2069,
- 0x0140, 0x6b04, 0x9384, 0x1000, 0x0138, 0x2001, 0x0100, 0x080c,
- 0x2d5b, 0x9006, 0x080c, 0x2d5b, 0x2069, 0x0100, 0x6824, 0xd084,
- 0x0110, 0x6827, 0x0001, 0x003e, 0x00de, 0x00c6, 0x3e08, 0x918e,
- 0x0002, 0x1168, 0xb800, 0xd0bc, 0x0150, 0x9680, 0x0010, 0x200c,
- 0x81ff, 0x1518, 0x2009, 0x1989, 0x210c, 0x2102, 0x00f0, 0xb83c,
- 0x9005, 0x0110, 0x8001, 0xb83e, 0x2660, 0x600f, 0x0000, 0x080c,
- 0xb11a, 0x00ce, 0x0048, 0x00de, 0x00c6, 0x2660, 0x6003, 0x0009,
- 0x630a, 0x00ce, 0x0804, 0x96ff, 0x89ff, 0x0138, 0xa867, 0x0103,
- 0xab7a, 0xa877, 0x0000, 0x080c, 0x6dcb, 0x080c, 0xa905, 0x0804,
- 0x96ff, 0x000e, 0x0804, 0x96f3, 0x781e, 0x781a, 0x00de, 0x00ce,
- 0x00be, 0x009e, 0x006e, 0x000e, 0x0005, 0x00e6, 0x00d6, 0x0096,
- 0x0066, 0xb800, 0xd0dc, 0x01a0, 0xb84c, 0x904d, 0x0188, 0xa878,
- 0x9606, 0x1170, 0x2071, 0x19e9, 0x7024, 0x9035, 0x0148, 0x9080,
- 0x0005, 0x2004, 0x9906, 0x1120, 0xb800, 0xc0dc, 0xb802, 0x0029,
- 0x006e, 0x009e, 0x00de, 0x00ee, 0x0005, 0x00f6, 0x2079, 0x0100,
- 0x78c0, 0x9005, 0x1138, 0x00c6, 0x2660, 0x6003, 0x0009, 0x630a,
- 0x00ce, 0x04b8, 0x080c, 0xa4fd, 0x78c3, 0x0000, 0x080c, 0xaa2f,
- 0x7027, 0x0000, 0x0036, 0x2079, 0x0140, 0x7b04, 0x9384, 0x1000,
- 0x0138, 0x2001, 0x0100, 0x080c, 0x2d5b, 0x9006, 0x080c, 0x2d5b,
- 0x2079, 0x0100, 0x7824, 0xd084, 0x0110, 0x7827, 0x0001, 0x080c,
- 0xaa2f, 0x003e, 0x080c, 0x663f, 0x00c6, 0xb83c, 0x9005, 0x0110,
- 0x8001, 0xb83e, 0x2660, 0x080c, 0xb0e7, 0x00ce, 0xa867, 0x0103,
- 0xab7a, 0xa877, 0x0000, 0x080c, 0xd135, 0x080c, 0x6dcb, 0x080c,
- 0xa905, 0x00fe, 0x0005, 0x00b6, 0x00e6, 0x00c6, 0x2011, 0x0101,
- 0x2204, 0xc0c4, 0x2012, 0x2001, 0x180c, 0x2014, 0xc2e4, 0x2202,
- 0x2071, 0x19e9, 0x7004, 0x9084, 0x0007, 0x0002, 0x97f8, 0x97fc,
- 0x981a, 0x9843, 0x9881, 0x97f8, 0x9813, 0x97f6, 0x080c, 0x0dc5,
- 0x00ce, 0x00ee, 0x00be, 0x0005, 0x7024, 0x9065, 0x0148, 0x7020,
- 0x8001, 0x7022, 0x600c, 0x9015, 0x0158, 0x7216, 0x600f, 0x0000,
- 0x7007, 0x0000, 0x7027, 0x0000, 0x00ce, 0x00ee, 0x00be, 0x0005,
- 0x7216, 0x7212, 0x0ca8, 0x7007, 0x0000, 0x7027, 0x0000, 0x7020,
- 0x9005, 0x0070, 0x6010, 0x2058, 0x080c, 0x663f, 0xb800, 0xc0dc,
- 0xb802, 0x7007, 0x0000, 0x7027, 0x0000, 0x7020, 0x8001, 0x7022,
- 0x1148, 0x2001, 0x180c, 0x2014, 0xd2ec, 0x1180, 0x00ce, 0x00ee,
- 0x00be, 0x0005, 0xb854, 0x9015, 0x0120, 0x721e, 0x080c, 0x98e7,
- 0x0ca8, 0x7218, 0x721e, 0x080c, 0x98e7, 0x0c80, 0xc2ec, 0x2202,
- 0x080c, 0x9a09, 0x0c58, 0x7024, 0x9065, 0x05b8, 0x700c, 0x9c06,
- 0x1160, 0x080c, 0xa905, 0x600c, 0x9015, 0x0120, 0x720e, 0x600f,
- 0x0000, 0x0448, 0x720e, 0x720a, 0x0430, 0x7014, 0x9c06, 0x1160,
- 0x080c, 0xa905, 0x600c, 0x9015, 0x0120, 0x7216, 0x600f, 0x0000,
- 0x00d0, 0x7216, 0x7212, 0x00b8, 0x6020, 0x9086, 0x0003, 0x1198,
- 0x6010, 0x2058, 0x080c, 0x663f, 0xb800, 0xc0dc, 0xb802, 0x080c,
- 0xa905, 0x701c, 0x9065, 0x0138, 0xb854, 0x9015, 0x0110, 0x721e,
- 0x0010, 0x7218, 0x721e, 0x7027, 0x0000, 0x00ce, 0x00ee, 0x00be,
- 0x0005, 0x7024, 0x9065, 0x0140, 0x080c, 0xa905, 0x600c, 0x9015,
- 0x0158, 0x720e, 0x600f, 0x0000, 0x080c, 0xaa2f, 0x7027, 0x0000,
- 0x00ce, 0x00ee, 0x00be, 0x0005, 0x720e, 0x720a, 0x0ca8, 0x00d6,
- 0x2069, 0x19e9, 0x6830, 0x9084, 0x0003, 0x0002, 0x98a4, 0x98a6,
- 0x98ca, 0x98a2, 0x080c, 0x0dc5, 0x00de, 0x0005, 0x00c6, 0x6840,
- 0x9086, 0x0001, 0x01b8, 0x683c, 0x9065, 0x0130, 0x600c, 0x9015,
- 0x0170, 0x6a3a, 0x600f, 0x0000, 0x6833, 0x0000, 0x683f, 0x0000,
- 0x2011, 0x1a08, 0x2013, 0x0000, 0x00ce, 0x00de, 0x0005, 0x683a,
- 0x6836, 0x0c90, 0x6843, 0x0000, 0x6838, 0x9065, 0x0d68, 0x6003,
- 0x0003, 0x0c50, 0x00c6, 0x9006, 0x6842, 0x6846, 0x684a, 0x683c,
- 0x9065, 0x0160, 0x600c, 0x9015, 0x0130, 0x6a3a, 0x600f, 0x0000,
- 0x683f, 0x0000, 0x0018, 0x683e, 0x683a, 0x6836, 0x00ce, 0x00de,
- 0x0005, 0x2001, 0x180c, 0x200c, 0xc1e5, 0x2102, 0x0005, 0x2001,
- 0x180c, 0x200c, 0xd1ec, 0x0120, 0xc1ec, 0x2102, 0x080c, 0x9a09,
- 0x2001, 0x19f5, 0x2004, 0x9086, 0x0001, 0x0d58, 0x00d6, 0x2069,
- 0x19e9, 0x6804, 0x9084, 0x0007, 0x0006, 0x9005, 0x11c8, 0x2001,
- 0x1837, 0x2004, 0x9084, 0x0028, 0x1198, 0x2001, 0x197d, 0x2004,
- 0x9086, 0xaaaa, 0x0168, 0x2001, 0x188b, 0x2004, 0xd08c, 0x1118,
- 0xd084, 0x1118, 0x0028, 0x080c, 0x9a09, 0x000e, 0x00de, 0x0005,
- 0x000e, 0x0002, 0x9924, 0x99dd, 0x99dd, 0x99dd, 0x99dd, 0x99df,
- 0x99dd, 0x9922, 0x080c, 0x0dc5, 0x6820, 0x9005, 0x1110, 0x00de,
- 0x0005, 0x00c6, 0x680c, 0x9065, 0x01f0, 0x6104, 0x918e, 0x0040,
- 0x1180, 0x2009, 0x1837, 0x210c, 0x918c, 0x0028, 0x1150, 0x080c,
- 0x7563, 0x0138, 0x0006, 0x2009, 0x188b, 0x2104, 0xc095, 0x200a,
- 0x000e, 0x6807, 0x0004, 0x6826, 0x682b, 0x0000, 0x080c, 0x9ab2,
- 0x00ce, 0x00de, 0x0005, 0x6814, 0x9065, 0x0150, 0x6807, 0x0001,
- 0x6826, 0x682b, 0x0000, 0x080c, 0x9ab2, 0x00ce, 0x00de, 0x0005,
- 0x00b6, 0x00e6, 0x6a1c, 0x92dd, 0x0000, 0x0904, 0x99c7, 0xb84c,
- 0x900d, 0x0118, 0xb888, 0x9005, 0x01a0, 0xb854, 0x905d, 0x0120,
- 0x920e, 0x0904, 0x99c7, 0x0028, 0x6818, 0x920e, 0x0904, 0x99c7,
- 0x2058, 0xb84c, 0x900d, 0x0d88, 0xb888, 0x9005, 0x1d70, 0x2b00,
- 0x681e, 0xbb3c, 0xb838, 0x9302, 0x1e40, 0x080c, 0xb0be, 0x0904,
- 0x99c7, 0x8318, 0xbb3e, 0x6116, 0x2b10, 0x6212, 0x0096, 0x2148,
- 0xa880, 0x9084, 0x00ff, 0x605e, 0xa883, 0x0000, 0xa884, 0x009e,
- 0x908a, 0x199a, 0x0210, 0x2001, 0x1999, 0x8003, 0x801b, 0x831b,
- 0x9318, 0x631a, 0x6114, 0x0096, 0x2148, 0xa964, 0x009e, 0x918c,
- 0x00ff, 0x918e, 0x0048, 0x0538, 0x00f6, 0x2c78, 0x2061, 0x0100,
- 0xbac0, 0x629a, 0x2069, 0x0200, 0x2071, 0x0240, 0x080c, 0xa02d,
- 0x2069, 0x19e9, 0xbb00, 0xc3dd, 0xbb02, 0x6807, 0x0002, 0x2f18,
- 0x6b26, 0x682b, 0x0000, 0x7823, 0x0003, 0x7803, 0x0001, 0x7807,
- 0x0040, 0x00fe, 0x00ee, 0x00be, 0x00ce, 0x00de, 0x0005, 0x00ee,
- 0x00be, 0x00ce, 0x0cd0, 0x6807, 0x0006, 0x2c18, 0x6b26, 0x6820,
- 0x8001, 0x6822, 0x682b, 0x0000, 0x080c, 0x663f, 0x080c, 0xaefe,
- 0x00ee, 0x00be, 0x00ce, 0x00de, 0x0005, 0x00de, 0x0005, 0x00c6,
- 0x680c, 0x9065, 0x01d8, 0x6104, 0x918e, 0x0040, 0x1180, 0x2009,
- 0x1837, 0x210c, 0x918c, 0x0028, 0x1150, 0x080c, 0x7563, 0x0138,
+ 0x080c, 0x2908, 0x9006, 0x080c, 0x2d52, 0x6043, 0x0090, 0x6043,
+ 0x0010, 0x6027, 0xffff, 0x602b, 0x182f, 0x00ee, 0x00de, 0x00ce,
+ 0x0005, 0x0006, 0x2001, 0x197d, 0x2004, 0x9086, 0xaaaa, 0x000e,
+ 0x0005, 0x0006, 0x080c, 0x57d7, 0x9084, 0x0030, 0x9086, 0x0000,
+ 0x000e, 0x0005, 0x0006, 0x080c, 0x57d7, 0x9084, 0x0030, 0x9086,
+ 0x0030, 0x000e, 0x0005, 0x0006, 0x080c, 0x57d7, 0x9084, 0x0030,
+ 0x9086, 0x0010, 0x000e, 0x0005, 0x0006, 0x080c, 0x57d7, 0x9084,
+ 0x0030, 0x9086, 0x0020, 0x000e, 0x0005, 0x0036, 0x0016, 0x2001,
+ 0x180c, 0x2004, 0x908c, 0x0013, 0x0168, 0x0020, 0x080c, 0x2928,
+ 0x900e, 0x0010, 0x2009, 0x0002, 0x2019, 0x0028, 0x080c, 0x3211,
+ 0x9006, 0x0019, 0x001e, 0x003e, 0x0005, 0x00e6, 0x2071, 0x180c,
+ 0x2e04, 0x0130, 0x080c, 0xd55a, 0x1128, 0x9085, 0x0010, 0x0010,
+ 0x9084, 0xffef, 0x2072, 0x00ee, 0x0005, 0x6050, 0x0006, 0x60ec,
+ 0x0006, 0x600c, 0x0006, 0x6004, 0x0006, 0x6028, 0x0006, 0x0016,
+ 0x6138, 0x6050, 0x9084, 0xfbff, 0x9085, 0x2000, 0x6052, 0x613a,
+ 0x20a9, 0x0012, 0x1d04, 0x75d2, 0x2091, 0x6000, 0x1f04, 0x75d2,
+ 0x602f, 0x0100, 0x602f, 0x0000, 0x6050, 0x9085, 0x0400, 0x9084,
+ 0xdfff, 0x6052, 0x613a, 0x001e, 0x602f, 0x0040, 0x602f, 0x0000,
+ 0x000e, 0x602a, 0x000e, 0x6006, 0x000e, 0x600e, 0x000e, 0x60ee,
+ 0x60e3, 0x0000, 0x6887, 0x0001, 0x2001, 0x0001, 0x080c, 0x2908,
+ 0x2001, 0x00a0, 0x0006, 0x080c, 0xd561, 0x000e, 0x0130, 0x080c,
+ 0x2d70, 0x9006, 0x080c, 0x2d7c, 0x0010, 0x080c, 0x2d52, 0x000e,
+ 0x6052, 0x6050, 0x0006, 0xc0e5, 0x6052, 0x00f6, 0x2079, 0x0100,
+ 0x080c, 0x2bef, 0x00fe, 0x000e, 0x6052, 0x0005, 0x0156, 0x0016,
+ 0x0026, 0x0036, 0x00c6, 0x00d6, 0x00e6, 0x2061, 0x0100, 0x2069,
+ 0x0140, 0x2071, 0x1800, 0x6020, 0x9084, 0x0080, 0x0138, 0x2001,
+ 0x180c, 0x200c, 0xc1c5, 0x2102, 0x0804, 0x7690, 0x2001, 0x180c,
+ 0x200c, 0xc1c4, 0x2102, 0x6028, 0x9084, 0xe1ff, 0x602a, 0x6027,
+ 0x0200, 0x2001, 0x0090, 0x080c, 0x2d52, 0x20a9, 0x0366, 0x6024,
+ 0xd0cc, 0x1518, 0x1d04, 0x763f, 0x2091, 0x6000, 0x1f04, 0x763f,
+ 0x2011, 0x0003, 0x080c, 0xa8ed, 0x2011, 0x0002, 0x080c, 0xa8f7,
+ 0x080c, 0xa801, 0x901e, 0x080c, 0xa877, 0x2001, 0x00a0, 0x080c,
+ 0x2d52, 0x080c, 0x784e, 0x080c, 0x6127, 0x080c, 0xd561, 0x0110,
+ 0x080c, 0x0d33, 0x9085, 0x0001, 0x0488, 0x080c, 0x1b2f, 0x60e3,
+ 0x0000, 0x2001, 0x196e, 0x2004, 0x080c, 0x2908, 0x60e2, 0x2001,
+ 0x0080, 0x080c, 0x2d52, 0x20a9, 0x0366, 0x6027, 0x1e00, 0x2009,
+ 0x1e00, 0x080c, 0x2c7a, 0x6024, 0x910c, 0x0138, 0x1d04, 0x7675,
+ 0x2091, 0x6000, 0x1f04, 0x7675, 0x0818, 0x6028, 0x9085, 0x1e00,
+ 0x602a, 0x70b4, 0x9005, 0x1118, 0x6887, 0x0001, 0x0008, 0x6886,
+ 0x080c, 0xd561, 0x0110, 0x080c, 0x0d33, 0x9006, 0x00ee, 0x00de,
+ 0x00ce, 0x003e, 0x002e, 0x001e, 0x015e, 0x0005, 0x0156, 0x0016,
+ 0x0026, 0x0036, 0x00c6, 0x00d6, 0x00e6, 0x2061, 0x0100, 0x2071,
+ 0x1800, 0x7000, 0x9086, 0x0003, 0x1168, 0x2001, 0x020b, 0x2004,
+ 0x9084, 0x5540, 0x9086, 0x5540, 0x1128, 0x2069, 0x1a7d, 0x2d04,
+ 0x8000, 0x206a, 0x2069, 0x0140, 0x6020, 0x9084, 0x00c0, 0x0120,
+ 0x6884, 0x9005, 0x1904, 0x7703, 0x2001, 0x0088, 0x080c, 0x2d52,
+ 0x9006, 0x60e2, 0x6886, 0x080c, 0x2908, 0x2069, 0x0200, 0x6804,
+ 0x9005, 0x1118, 0x6808, 0x9005, 0x01c0, 0x6028, 0x9084, 0xfbff,
+ 0x602a, 0x6027, 0x0400, 0x2069, 0x1990, 0x7000, 0x206a, 0x709b,
+ 0x0026, 0x7003, 0x0001, 0x20a9, 0x0002, 0x1d04, 0x76e5, 0x2091,
+ 0x6000, 0x1f04, 0x76e5, 0x0804, 0x7733, 0x2069, 0x0140, 0x20a9,
+ 0x0384, 0x6027, 0x1e00, 0x2009, 0x1e00, 0x080c, 0x2c7a, 0x6024,
+ 0x910c, 0x0508, 0x9084, 0x1a00, 0x11f0, 0x1d04, 0x76f1, 0x2091,
+ 0x6000, 0x1f04, 0x76f1, 0x2011, 0x0003, 0x080c, 0xa8ed, 0x2011,
+ 0x0002, 0x080c, 0xa8f7, 0x080c, 0xa801, 0x901e, 0x080c, 0xa877,
+ 0x2001, 0x00a0, 0x080c, 0x2d52, 0x080c, 0x784e, 0x080c, 0x6127,
+ 0x9085, 0x0001, 0x00c0, 0x080c, 0x1b2f, 0x2001, 0x0080, 0x080c,
+ 0x2d52, 0x2069, 0x0140, 0x60e3, 0x0000, 0x70b4, 0x9005, 0x1118,
+ 0x6887, 0x0001, 0x0008, 0x6886, 0x2001, 0x196e, 0x2004, 0x080c,
+ 0x2908, 0x60e2, 0x9006, 0x00ee, 0x00de, 0x00ce, 0x003e, 0x002e,
+ 0x001e, 0x015e, 0x0005, 0x0156, 0x0016, 0x0026, 0x0036, 0x00c6,
+ 0x00d6, 0x00e6, 0x2061, 0x0100, 0x2071, 0x1800, 0x6020, 0x9084,
+ 0x00c0, 0x01c8, 0x2011, 0x0003, 0x080c, 0xa8ed, 0x2011, 0x0002,
+ 0x080c, 0xa8f7, 0x080c, 0xa801, 0x901e, 0x080c, 0xa877, 0x2069,
+ 0x0140, 0x2001, 0x00a0, 0x080c, 0x2d52, 0x080c, 0x784e, 0x080c,
+ 0x6127, 0x0804, 0x77ce, 0x2001, 0x180c, 0x200c, 0xd1b4, 0x1160,
+ 0xc1b5, 0x2102, 0x080c, 0x73cc, 0x2069, 0x0140, 0x2001, 0x0080,
+ 0x080c, 0x2d52, 0x60e3, 0x0000, 0x2069, 0x0200, 0x6804, 0x9005,
+ 0x1118, 0x6808, 0x9005, 0x0180, 0x6028, 0x9084, 0xfdff, 0x602a,
+ 0x6027, 0x0200, 0x2069, 0x1990, 0x7000, 0x206a, 0x709b, 0x0027,
+ 0x7003, 0x0001, 0x0804, 0x77ce, 0x6027, 0x1e00, 0x2009, 0x1e00,
+ 0x080c, 0x2c7a, 0x6024, 0x910c, 0x01c8, 0x9084, 0x1c00, 0x11b0,
+ 0x1d04, 0x778c, 0x0006, 0x0016, 0x00c6, 0x00d6, 0x00e6, 0x080c,
+ 0x8642, 0x00ee, 0x00de, 0x00ce, 0x001e, 0x000e, 0x00e6, 0x2071,
+ 0x19fc, 0x7078, 0x00ee, 0x9005, 0x19f8, 0x0400, 0x0026, 0x2011,
+ 0x73e4, 0x080c, 0x8709, 0x2011, 0x73d7, 0x080c, 0x87e3, 0x002e,
+ 0x2069, 0x0140, 0x60e3, 0x0000, 0x70b4, 0x9005, 0x1118, 0x6887,
+ 0x0001, 0x0008, 0x6886, 0x2001, 0x196e, 0x2004, 0x080c, 0x2908,
+ 0x60e2, 0x2001, 0x180c, 0x200c, 0xc1b4, 0x2102, 0x00ee, 0x00de,
+ 0x00ce, 0x003e, 0x002e, 0x001e, 0x015e, 0x0005, 0x0156, 0x0016,
+ 0x0026, 0x0036, 0x0046, 0x00c6, 0x00e6, 0x2061, 0x0100, 0x2071,
+ 0x1800, 0x080c, 0xd55a, 0x1904, 0x783c, 0x7130, 0xd184, 0x1170,
+ 0x080c, 0x33a0, 0x0138, 0xc18d, 0x7132, 0x2011, 0x1848, 0x2214,
+ 0xd2ac, 0x1120, 0x7030, 0xd08c, 0x0904, 0x783c, 0x2011, 0x1848,
+ 0x220c, 0xd1a4, 0x0538, 0x0016, 0x2019, 0x000e, 0x080c, 0xe915,
+ 0x0156, 0x00b6, 0x20a9, 0x007f, 0x900e, 0x9186, 0x007e, 0x01a0,
+ 0x9186, 0x0080, 0x0188, 0x080c, 0x671d, 0x1170, 0x2120, 0x9006,
+ 0x0016, 0x2009, 0x000e, 0x080c, 0xe9a5, 0x2009, 0x0001, 0x2011,
+ 0x0100, 0x080c, 0x891c, 0x001e, 0x8108, 0x1f04, 0x7805, 0x00be,
+ 0x015e, 0x001e, 0xd1ac, 0x1148, 0x0016, 0x2009, 0x0002, 0x2019,
+ 0x0004, 0x080c, 0x3211, 0x001e, 0x0078, 0x0156, 0x00b6, 0x20a9,
+ 0x007f, 0x900e, 0x080c, 0x671d, 0x1110, 0x080c, 0x6141, 0x8108,
+ 0x1f04, 0x7832, 0x00be, 0x015e, 0x080c, 0x1b2f, 0x080c, 0xb072,
+ 0x60e3, 0x0000, 0x080c, 0x6127, 0x080c, 0x7495, 0x00ee, 0x00ce,
+ 0x004e, 0x003e, 0x002e, 0x001e, 0x015e, 0x0005, 0x2001, 0x197e,
+ 0x2003, 0x0001, 0x0005, 0x2001, 0x197e, 0x2003, 0x0000, 0x0005,
+ 0x2001, 0x197d, 0x2003, 0xaaaa, 0x0005, 0x2001, 0x197d, 0x2003,
+ 0x0000, 0x0005, 0x2071, 0x18fa, 0x7003, 0x0000, 0x7007, 0x0000,
+ 0x080c, 0x1027, 0x090c, 0x0dc5, 0xa8ab, 0xdcb0, 0x2900, 0x704e,
+ 0x080c, 0x1027, 0x090c, 0x0dc5, 0xa8ab, 0xdcb0, 0x2900, 0x7052,
+ 0xa867, 0x0000, 0xa86b, 0x0001, 0xa89f, 0x0000, 0x0005, 0x00e6,
+ 0x2071, 0x0040, 0x6848, 0x9005, 0x1118, 0x9085, 0x0001, 0x04b0,
+ 0x6840, 0x9005, 0x0150, 0x04a1, 0x6a50, 0x9200, 0x7002, 0x6854,
+ 0x9101, 0x7006, 0x9006, 0x7012, 0x7016, 0x6850, 0x7002, 0x6854,
+ 0x7006, 0x6858, 0x700a, 0x685c, 0x700e, 0x6840, 0x9005, 0x1110,
+ 0x7012, 0x7016, 0x6848, 0x701a, 0x701c, 0x9085, 0x0040, 0x701e,
+ 0x2001, 0x0019, 0x7036, 0x702b, 0x0001, 0x2001, 0x0004, 0x200c,
+ 0x918c, 0xfff7, 0x918d, 0x8000, 0x2102, 0x00d6, 0x2069, 0x18fa,
+ 0x6807, 0x0001, 0x00de, 0x080c, 0x7e40, 0x9006, 0x00ee, 0x0005,
+ 0x900e, 0x0156, 0x20a9, 0x0006, 0x8003, 0x2011, 0x0100, 0x2214,
+ 0x9296, 0x0008, 0x1110, 0x818d, 0x0010, 0x81f5, 0x3e08, 0x1f04,
+ 0x78c4, 0x015e, 0x0005, 0x2079, 0x0040, 0x2071, 0x18fa, 0x7004,
+ 0x0002, 0x78e3, 0x78e4, 0x791c, 0x7977, 0x7a87, 0x78e1, 0x78e1,
+ 0x7ab1, 0x080c, 0x0dc5, 0x0005, 0x2079, 0x0040, 0x782c, 0x908c,
+ 0x0780, 0x190c, 0x7f22, 0xd0a4, 0x01f8, 0x7824, 0x2048, 0x9006,
+ 0xa802, 0xa806, 0xa864, 0x9084, 0x00ff, 0x908a, 0x0040, 0x0610,
+ 0x00c0, 0x2001, 0x1800, 0x200c, 0x9186, 0x0003, 0x1168, 0x7004,
+ 0x0002, 0x790c, 0x78e6, 0x790c, 0x790a, 0x790c, 0x790c, 0x790c,
+ 0x790c, 0x790c, 0x080c, 0x7977, 0x782c, 0xd09c, 0x090c, 0x7e40,
+ 0x0005, 0x9082, 0x005a, 0x1218, 0x2100, 0x003b, 0x0c10, 0x080c,
+ 0x79ad, 0x0c90, 0x00e3, 0x08e8, 0x0005, 0x79ad, 0x79ad, 0x79ad,
+ 0x79ad, 0x79ad, 0x79ad, 0x79ad, 0x79ad, 0x79cf, 0x79ad, 0x79ad,
+ 0x79ad, 0x79ad, 0x79ad, 0x79ad, 0x79ad, 0x79ad, 0x79ad, 0x79ad,
+ 0x79ad, 0x79ad, 0x79ad, 0x79ad, 0x79ad, 0x79ad, 0x79ad, 0x79ad,
+ 0x79ad, 0x79b9, 0x79ad, 0x7ba7, 0x79ad, 0x79ad, 0x79ad, 0x79cf,
+ 0x79ad, 0x79b9, 0x7be8, 0x7c29, 0x7c70, 0x7c84, 0x79ad, 0x79ad,
+ 0x79cf, 0x79b9, 0x79e3, 0x79ad, 0x7a5b, 0x7d2f, 0x7d4a, 0x79ad,
+ 0x79cf, 0x79ad, 0x79e3, 0x79ad, 0x79ad, 0x7a51, 0x7d4a, 0x79ad,
+ 0x79ad, 0x79ad, 0x79ad, 0x79ad, 0x79ad, 0x79ad, 0x79ad, 0x79ad,
+ 0x79f7, 0x79ad, 0x79ad, 0x79ad, 0x79ad, 0x79ad, 0x79ad, 0x79ad,
+ 0x79ad, 0x79ad, 0x7ec6, 0x79ad, 0x7e70, 0x79ad, 0x7e70, 0x79ad,
+ 0x7a0c, 0x79ad, 0x79ad, 0x79ad, 0x79ad, 0x79ad, 0x79ad, 0x2079,
+ 0x0040, 0x7004, 0x9086, 0x0003, 0x1198, 0x782c, 0x080c, 0x7e69,
+ 0xd0a4, 0x0170, 0x7824, 0x2048, 0x9006, 0xa802, 0xa806, 0xa864,
+ 0x9084, 0x00ff, 0x908a, 0x001a, 0x1210, 0x002b, 0x0c50, 0x00e9,
+ 0x080c, 0x7e40, 0x0005, 0x79ad, 0x79b9, 0x7b93, 0x79ad, 0x79b9,
+ 0x79ad, 0x79b9, 0x79b9, 0x79ad, 0x79b9, 0x7b93, 0x79b9, 0x79b9,
+ 0x79b9, 0x79b9, 0x79b9, 0x79ad, 0x79b9, 0x7b93, 0x79ad, 0x79ad,
+ 0x79b9, 0x79ad, 0x79ad, 0x79ad, 0x79b9, 0x00e6, 0x2071, 0x18fa,
+ 0x2009, 0x0400, 0x0071, 0x00ee, 0x0005, 0x2009, 0x1000, 0x0049,
+ 0x0005, 0x2009, 0x2000, 0x0029, 0x0005, 0x2009, 0x0800, 0x0009,
+ 0x0005, 0x7007, 0x0001, 0xa868, 0x9084, 0x00ff, 0x9105, 0xa86a,
+ 0x0126, 0x2091, 0x8000, 0x080c, 0x6dd1, 0x012e, 0x0005, 0xa864,
+ 0x8007, 0x9084, 0x00ff, 0x0d08, 0x8001, 0x1120, 0x7007, 0x0001,
+ 0x0804, 0x7b30, 0x7007, 0x0003, 0x7012, 0x2900, 0x7016, 0x701a,
+ 0x704b, 0x7b30, 0x0005, 0xa864, 0x8007, 0x9084, 0x00ff, 0x0968,
+ 0x8001, 0x1120, 0x7007, 0x0001, 0x0804, 0x7b4b, 0x7007, 0x0003,
+ 0x7012, 0x2900, 0x7016, 0x701a, 0x704b, 0x7b4b, 0x0005, 0xa864,
+ 0x8007, 0x9084, 0x00ff, 0x0904, 0x79b5, 0x8001, 0x1120, 0x7007,
+ 0x0001, 0x0804, 0x7b67, 0x7007, 0x0003, 0x7012, 0x2900, 0x7016,
+ 0x701a, 0x704b, 0x7b67, 0x0005, 0xa864, 0x8007, 0x9084, 0x00ff,
+ 0x9086, 0x0001, 0x1904, 0x79b5, 0x7007, 0x0001, 0x2009, 0x1834,
+ 0x210c, 0x81ff, 0x11a8, 0xa868, 0x9084, 0x00ff, 0xa86a, 0xa883,
+ 0x0000, 0x080c, 0x63be, 0x1108, 0x0005, 0x0126, 0x2091, 0x8000,
+ 0xa867, 0x0139, 0xa87a, 0xa982, 0x080c, 0x6dd1, 0x012e, 0x0ca0,
+ 0xa994, 0x9186, 0x0071, 0x0d38, 0x9186, 0x0064, 0x0d20, 0x9186,
+ 0x007c, 0x0d08, 0x9186, 0x0028, 0x09f0, 0x9186, 0x0038, 0x09d8,
+ 0x9186, 0x0078, 0x09c0, 0x9186, 0x005f, 0x09a8, 0x9186, 0x0056,
+ 0x0990, 0xa897, 0x4005, 0xa89b, 0x0001, 0x2001, 0x0030, 0x900e,
+ 0x08a0, 0xa87c, 0x9084, 0x00c0, 0x9086, 0x00c0, 0x1120, 0x7007,
+ 0x0001, 0x0804, 0x7d61, 0x2900, 0x7016, 0x701a, 0x20a9, 0x0004,
+ 0xa860, 0x20e0, 0xa85c, 0x9080, 0x0030, 0x2098, 0x7050, 0x2040,
+ 0xa060, 0x20e8, 0xa05c, 0x9080, 0x0023, 0x20a0, 0x4003, 0xa888,
+ 0x7012, 0x9082, 0x0401, 0x1a04, 0x79bd, 0xaab4, 0x928a, 0x0002,
+ 0x1a04, 0x79bd, 0x82ff, 0x1138, 0xa8b8, 0xa9bc, 0x9105, 0x0118,
+ 0x2001, 0x7aee, 0x0018, 0x9280, 0x7ae4, 0x2005, 0x7056, 0x7010,
+ 0x9015, 0x0904, 0x7acf, 0x080c, 0x1027, 0x1118, 0x7007, 0x0004,
+ 0x0005, 0x2900, 0x7022, 0x7054, 0x2060, 0xe000, 0xa866, 0x7050,
+ 0x2040, 0xa95c, 0xe004, 0x9100, 0xa076, 0xa860, 0xa072, 0xe008,
+ 0x920a, 0x1210, 0x900e, 0x2200, 0x7112, 0xe20c, 0x8003, 0x800b,
+ 0x9296, 0x0004, 0x0108, 0x9108, 0xa17a, 0x810b, 0xa17e, 0x080c,
+ 0x10f8, 0xa06c, 0x908e, 0x0100, 0x0170, 0x9086, 0x0200, 0x0118,
+ 0x7007, 0x0007, 0x0005, 0x7020, 0x2048, 0x080c, 0x1040, 0x7014,
+ 0x2048, 0x0804, 0x79bd, 0x7020, 0x2048, 0x7018, 0xa802, 0xa807,
+ 0x0000, 0x2908, 0x2048, 0xa906, 0x711a, 0x0804, 0x7a87, 0x7014,
+ 0x2048, 0x7007, 0x0001, 0xa8b4, 0x9005, 0x1128, 0xa8b8, 0xa9bc,
+ 0x9105, 0x0108, 0x00b9, 0xa864, 0x9084, 0x00ff, 0x9086, 0x001e,
+ 0x0904, 0x7d61, 0x0804, 0x7b30, 0x7ae6, 0x7aea, 0x0002, 0x001d,
+ 0x0007, 0x0004, 0x000a, 0x001b, 0x0005, 0x0006, 0x000a, 0x001d,
+ 0x0005, 0x0004, 0x0076, 0x0066, 0xafb8, 0xaebc, 0xa804, 0x2050,
+ 0xb0c0, 0xb0e2, 0xb0bc, 0xb0de, 0xb0b8, 0xb0d2, 0xb0b4, 0xb0ce,
+ 0xb6da, 0xb7d6, 0xb0b0, 0xb0ca, 0xb0ac, 0xb0c6, 0xb0a8, 0xb0ba,
+ 0xb0a4, 0xb0b6, 0xb6c2, 0xb7be, 0xb0a0, 0xb0b2, 0xb09c, 0xb0ae,
+ 0xb098, 0xb0a2, 0xb094, 0xb09e, 0xb6aa, 0xb7a6, 0xb090, 0xb09a,
+ 0xb08c, 0xb096, 0xb088, 0xb08a, 0xb084, 0xb086, 0xb692, 0xb78e,
+ 0xb080, 0xb082, 0xb07c, 0xb07e, 0xb078, 0xb072, 0xb074, 0xb06e,
+ 0xb67a, 0xb776, 0xb004, 0x9055, 0x1958, 0x006e, 0x007e, 0x0005,
+ 0x2009, 0x1834, 0x210c, 0x81ff, 0x1178, 0x080c, 0x61bb, 0x1108,
+ 0x0005, 0x080c, 0x703d, 0x0126, 0x2091, 0x8000, 0x080c, 0xd14c,
+ 0x080c, 0x6dd1, 0x012e, 0x0ca0, 0x080c, 0xd55a, 0x1d70, 0x2001,
+ 0x0028, 0x900e, 0x0c70, 0x2009, 0x1834, 0x210c, 0x81ff, 0x1188,
+ 0xa888, 0x9005, 0x0188, 0xa883, 0x0000, 0x080c, 0x624b, 0x1108,
+ 0x0005, 0xa87a, 0x0126, 0x2091, 0x8000, 0x080c, 0x6dd1, 0x012e,
+ 0x0cb8, 0x2001, 0x0028, 0x0ca8, 0x2001, 0x0000, 0x0c90, 0x0419,
+ 0x11d8, 0xa888, 0x9005, 0x01e0, 0xa883, 0x0000, 0xa87c, 0xd0f4,
+ 0x0120, 0x080c, 0x6320, 0x1138, 0x0005, 0x9006, 0xa87a, 0x080c,
+ 0x6298, 0x1108, 0x0005, 0x0126, 0x2091, 0x8000, 0xa87a, 0xa982,
+ 0x080c, 0x6dd1, 0x012e, 0x0cb0, 0x2001, 0x0028, 0x900e, 0x0c98,
+ 0x2001, 0x0000, 0x0c80, 0x00c6, 0x2061, 0x1800, 0x60d0, 0x9005,
+ 0x0100, 0x00ce, 0x0005, 0x7018, 0xa802, 0x2908, 0x2048, 0xa906,
+ 0x711a, 0x7010, 0x8001, 0x7012, 0x0118, 0x7007, 0x0003, 0x0030,
+ 0x7014, 0x2048, 0x7007, 0x0001, 0x7048, 0x080f, 0x0005, 0x00b6,
+ 0x7007, 0x0001, 0xa974, 0xa878, 0x9084, 0x00ff, 0x9096, 0x0004,
+ 0x0540, 0x20a9, 0x0001, 0x9096, 0x0001, 0x0190, 0x900e, 0x20a9,
+ 0x0800, 0x9096, 0x0002, 0x0160, 0x9005, 0x11d8, 0xa974, 0x080c,
+ 0x671d, 0x11b8, 0x0066, 0xae80, 0x080c, 0x682d, 0x006e, 0x0088,
+ 0x0046, 0x2011, 0x180c, 0x2224, 0xc484, 0x2412, 0x004e, 0x00c6,
+ 0x080c, 0x671d, 0x1110, 0x080c, 0x692d, 0x8108, 0x1f04, 0x7bd0,
+ 0x00ce, 0xa87c, 0xd084, 0x1120, 0x080c, 0x1040, 0x00be, 0x0005,
+ 0x0126, 0x2091, 0x8000, 0x080c, 0x6dd1, 0x012e, 0x00be, 0x0005,
+ 0x0126, 0x2091, 0x8000, 0x7007, 0x0001, 0x080c, 0x6a8e, 0x0580,
+ 0x2061, 0x1a75, 0x6100, 0xd184, 0x0178, 0xa888, 0x9084, 0x00ff,
+ 0x1550, 0x6000, 0xd084, 0x0520, 0x6004, 0x9005, 0x1538, 0x6003,
+ 0x0000, 0x600b, 0x0000, 0x00c8, 0x2011, 0x0001, 0xa890, 0x9005,
+ 0x1110, 0x2001, 0x001e, 0x8000, 0x6016, 0xa888, 0x9084, 0x00ff,
+ 0x0178, 0x6006, 0xa888, 0x8007, 0x9084, 0x00ff, 0x0148, 0x600a,
+ 0xa888, 0x8000, 0x1108, 0xc28d, 0x6202, 0x012e, 0x0804, 0x7e2a,
+ 0x012e, 0x0804, 0x7e24, 0x012e, 0x0804, 0x7e1e, 0x012e, 0x0804,
+ 0x7e21, 0x0126, 0x2091, 0x8000, 0x7007, 0x0001, 0x080c, 0x6a8e,
+ 0x05e0, 0x2061, 0x1a75, 0x6000, 0xd084, 0x05b8, 0x6204, 0x6308,
+ 0xd08c, 0x1530, 0xac78, 0x9484, 0x0003, 0x0170, 0xa988, 0x918c,
+ 0x00ff, 0x8001, 0x1120, 0x2100, 0x9210, 0x0620, 0x0028, 0x8001,
+ 0x1508, 0x2100, 0x9212, 0x02f0, 0x9484, 0x000c, 0x0188, 0xa988,
+ 0x810f, 0x918c, 0x00ff, 0x9082, 0x0004, 0x1120, 0x2100, 0x9318,
+ 0x0288, 0x0030, 0x9082, 0x0004, 0x1168, 0x2100, 0x931a, 0x0250,
+ 0xa890, 0x9005, 0x0110, 0x8000, 0x6016, 0x6206, 0x630a, 0x012e,
+ 0x0804, 0x7e2a, 0x012e, 0x0804, 0x7e27, 0x012e, 0x0804, 0x7e24,
+ 0x0126, 0x2091, 0x8000, 0x7007, 0x0001, 0x2061, 0x1a75, 0x6300,
+ 0xd38c, 0x1120, 0x6308, 0x8318, 0x0220, 0x630a, 0x012e, 0x0804,
+ 0x7e38, 0x012e, 0x0804, 0x7e27, 0x00b6, 0x0126, 0x00c6, 0x2091,
+ 0x8000, 0x7007, 0x0001, 0xa87c, 0xd0ac, 0x0148, 0x00c6, 0x2061,
+ 0x1a75, 0x6000, 0x9084, 0xfcff, 0x6002, 0x00ce, 0x0440, 0xa888,
+ 0x9005, 0x05d8, 0xa88c, 0x9065, 0x0598, 0x2001, 0x1834, 0x2004,
+ 0x9005, 0x0118, 0x080c, 0xb134, 0x0068, 0x6017, 0xf400, 0x605b,
+ 0x0000, 0xa97c, 0xd1a4, 0x0110, 0xa980, 0x615a, 0x2009, 0x0041,
+ 0x080c, 0xb180, 0xa988, 0x918c, 0xff00, 0x9186, 0x2000, 0x1138,
+ 0x0026, 0x900e, 0x2011, 0xfdff, 0x080c, 0x891c, 0x002e, 0xa87c,
+ 0xd0c4, 0x0148, 0x2061, 0x1a75, 0x6000, 0xd08c, 0x1120, 0x6008,
+ 0x8000, 0x0208, 0x600a, 0x00ce, 0x012e, 0x00be, 0x0804, 0x7e2a,
+ 0x00ce, 0x012e, 0x00be, 0x0804, 0x7e24, 0xa984, 0x9186, 0x002e,
+ 0x0d30, 0x9186, 0x002d, 0x0d18, 0x9186, 0x0045, 0x0510, 0x9186,
+ 0x002a, 0x1130, 0x2001, 0x180c, 0x200c, 0xc194, 0x2102, 0x08b8,
+ 0x9186, 0x0020, 0x0158, 0x9186, 0x0029, 0x1d10, 0xa974, 0x080c,
+ 0x671d, 0x1968, 0xb800, 0xc0e4, 0xb802, 0x0848, 0xa88c, 0x9065,
+ 0x09b8, 0x6007, 0x0024, 0x2001, 0x1987, 0x2004, 0x601a, 0x0804,
+ 0x7cbf, 0xa88c, 0x9065, 0x0960, 0x00e6, 0xa890, 0x9075, 0x2001,
+ 0x1834, 0x2004, 0x9005, 0x0150, 0x080c, 0xb134, 0x8eff, 0x0118,
+ 0x2e60, 0x080c, 0xb134, 0x00ee, 0x0804, 0x7cbf, 0x6024, 0xc0dc,
+ 0xc0d5, 0x6026, 0x2e60, 0x6007, 0x003a, 0xa8a0, 0x9005, 0x0130,
+ 0x6007, 0x003b, 0xa8a4, 0x602e, 0xa8a8, 0x6016, 0x6003, 0x0001,
+ 0x080c, 0x933b, 0x080c, 0x98ed, 0x00ee, 0x0804, 0x7cbf, 0x2061,
+ 0x1a75, 0x6000, 0xd084, 0x0190, 0xd08c, 0x1904, 0x7e38, 0x0126,
+ 0x2091, 0x8000, 0x6204, 0x8210, 0x0220, 0x6206, 0x012e, 0x0804,
+ 0x7e38, 0x012e, 0xa883, 0x0016, 0x0804, 0x7e31, 0xa883, 0x0007,
+ 0x0804, 0x7e31, 0xa864, 0x8007, 0x9084, 0x00ff, 0x0130, 0x8001,
+ 0x1138, 0x7007, 0x0001, 0x0069, 0x0005, 0x080c, 0x79b5, 0x0040,
+ 0x7007, 0x0003, 0x7012, 0x2900, 0x7016, 0x701a, 0x704b, 0x7d61,
+ 0x0005, 0x00b6, 0x00e6, 0x0126, 0x2091, 0x8000, 0x903e, 0x2061,
+ 0x1800, 0x61d0, 0x81ff, 0x1904, 0x7de3, 0x6130, 0xd194, 0x1904,
+ 0x7e0d, 0xa878, 0x2070, 0x9e82, 0x1cd0, 0x0a04, 0x7dd7, 0x6068,
+ 0x9e02, 0x1a04, 0x7dd7, 0x7120, 0x9186, 0x0006, 0x1904, 0x7dc9,
+ 0x7010, 0x905d, 0x0904, 0x7de3, 0xb800, 0xd0e4, 0x1904, 0x7e07,
+ 0x2061, 0x1a75, 0x6100, 0x9184, 0x0301, 0x9086, 0x0001, 0x15a0,
+ 0x7024, 0xd0dc, 0x1904, 0x7e10, 0xa883, 0x0000, 0xa803, 0x0000,
+ 0x2908, 0x7014, 0x9005, 0x1198, 0x7116, 0xa87c, 0xd0f4, 0x1904,
+ 0x7e13, 0x080c, 0x57d3, 0xd09c, 0x1118, 0xa87c, 0xc0cc, 0xa87e,
+ 0x2e60, 0x080c, 0x883c, 0x012e, 0x00ee, 0x00be, 0x0005, 0x2048,
+ 0xa800, 0x9005, 0x1de0, 0xa902, 0x2148, 0xa87c, 0xd0f4, 0x1904,
+ 0x7e13, 0x012e, 0x00ee, 0x00be, 0x0005, 0x012e, 0x00ee, 0xa883,
+ 0x0006, 0x00be, 0x0804, 0x7e31, 0xd184, 0x0db8, 0xd1c4, 0x1190,
+ 0x00a0, 0xa974, 0x080c, 0x671d, 0x15d0, 0xb800, 0xd0e4, 0x15b8,
+ 0x7120, 0x9186, 0x0007, 0x1118, 0xa883, 0x0002, 0x0490, 0xa883,
+ 0x0008, 0x0478, 0xa883, 0x000e, 0x0460, 0xa883, 0x0017, 0x0448,
+ 0xa883, 0x0035, 0x0430, 0x080c, 0x57d7, 0xd0fc, 0x01e8, 0xa878,
+ 0x2070, 0x9e82, 0x1cd0, 0x02c0, 0x6068, 0x9e02, 0x12a8, 0x7120,
+ 0x9186, 0x0006, 0x1188, 0x7010, 0x905d, 0x0170, 0xb800, 0xd0bc,
+ 0x0158, 0x2039, 0x0001, 0x7000, 0x9086, 0x0007, 0x1904, 0x7d6d,
+ 0x7003, 0x0002, 0x0804, 0x7d6d, 0xa883, 0x0028, 0x0010, 0xa883,
+ 0x0029, 0x012e, 0x00ee, 0x00be, 0x0420, 0xa883, 0x002a, 0x0cc8,
+ 0xa883, 0x0045, 0x0cb0, 0x2e60, 0x2019, 0x0002, 0x601b, 0x0014,
+ 0x080c, 0xe4c8, 0x012e, 0x00ee, 0x00be, 0x0005, 0x2009, 0x003e,
+ 0x0058, 0x2009, 0x0004, 0x0040, 0x2009, 0x0006, 0x0028, 0x2009,
+ 0x0016, 0x0010, 0x2009, 0x0001, 0xa884, 0x9084, 0xff00, 0x9105,
+ 0xa886, 0x0126, 0x2091, 0x8000, 0x080c, 0x6dd1, 0x012e, 0x0005,
+ 0x080c, 0x1040, 0x0005, 0x00d6, 0x080c, 0x8833, 0x00de, 0x0005,
+ 0x00d6, 0x00e6, 0x0126, 0x2091, 0x8000, 0x2071, 0x0040, 0x702c,
+ 0xd084, 0x01d8, 0x908c, 0x0780, 0x190c, 0x7f22, 0xd09c, 0x11a8,
+ 0x2071, 0x1800, 0x70c0, 0x90ea, 0x0020, 0x0278, 0x8001, 0x70c2,
+ 0x702c, 0x2048, 0xa800, 0x702e, 0x9006, 0xa802, 0xa806, 0x2071,
+ 0x0040, 0x2900, 0x7022, 0x702c, 0x0c28, 0x012e, 0x00ee, 0x00de,
+ 0x0005, 0x0006, 0x9084, 0x0780, 0x190c, 0x7f22, 0x000e, 0x0005,
+ 0xa898, 0x9084, 0x0003, 0x05a8, 0x080c, 0xb0ab, 0x05d8, 0x2900,
+ 0x6016, 0xa864, 0x9084, 0x00ff, 0x9086, 0x0035, 0x1138, 0x6008,
+ 0xc0fd, 0x600a, 0x2001, 0x196c, 0x2004, 0x0098, 0xa8a0, 0x9084,
+ 0x00ff, 0xa99c, 0x918c, 0xff00, 0x9105, 0xa99c, 0x918c, 0x00ff,
+ 0x080c, 0x2894, 0x1540, 0x00b6, 0x080c, 0x671d, 0x2b00, 0x00be,
+ 0x1510, 0x6012, 0x6023, 0x0001, 0x2009, 0x0040, 0xa864, 0x9084,
+ 0x00ff, 0x9086, 0x0035, 0x0110, 0x2009, 0x0041, 0x080c, 0xb180,
+ 0x0005, 0xa87b, 0x0101, 0x0126, 0x2091, 0x8000, 0x080c, 0x6dd1,
+ 0x012e, 0x0005, 0xa87b, 0x002c, 0x0126, 0x2091, 0x8000, 0x080c,
+ 0x6dd1, 0x012e, 0x0005, 0xa87b, 0x0028, 0x0126, 0x2091, 0x8000,
+ 0x080c, 0x6dd1, 0x012e, 0x080c, 0xb101, 0x0005, 0x00d6, 0x00c6,
+ 0x0036, 0x0026, 0x0016, 0x00b6, 0x7007, 0x0001, 0xaa74, 0x9282,
+ 0x0004, 0x1a04, 0x7f13, 0xa97c, 0x9188, 0x1000, 0x2104, 0x905d,
+ 0xb804, 0xd284, 0x0140, 0x05e8, 0x8007, 0x9084, 0x00ff, 0x9084,
+ 0x0006, 0x1108, 0x04b0, 0x2b10, 0x080c, 0xb0ab, 0x1118, 0x080c,
+ 0xb153, 0x05a8, 0x6212, 0xa874, 0x0002, 0x7ef1, 0x7ef6, 0x7ef9,
+ 0x7eff, 0x2019, 0x0002, 0x080c, 0xe915, 0x0060, 0x080c, 0xe8ac,
+ 0x0048, 0x2019, 0x0002, 0xa980, 0x080c, 0xe8c7, 0x0018, 0xa980,
+ 0x080c, 0xe8ac, 0x080c, 0xb101, 0xa887, 0x0000, 0x0126, 0x2091,
+ 0x8000, 0x080c, 0x6dd1, 0x012e, 0x00be, 0x001e, 0x002e, 0x003e,
+ 0x00ce, 0x00de, 0x0005, 0xa887, 0x0006, 0x0c80, 0xa887, 0x0002,
+ 0x0c68, 0xa887, 0x0005, 0x0c50, 0xa887, 0x0004, 0x0c38, 0xa887,
+ 0x0007, 0x0c20, 0x2091, 0x8000, 0x0e04, 0x7f24, 0x0006, 0x0016,
+ 0x2001, 0x8003, 0x0006, 0x0804, 0x0dce, 0x2001, 0x1834, 0x2004,
+ 0x9005, 0x0005, 0x0005, 0x00f6, 0x2079, 0x0300, 0x2001, 0x0200,
+ 0x200c, 0xc1e5, 0xc1dc, 0x2102, 0x2009, 0x0218, 0x210c, 0xd1ec,
+ 0x1120, 0x080c, 0x15a0, 0x00fe, 0x0005, 0x2001, 0x020d, 0x2003,
+ 0x0020, 0x781f, 0x0300, 0x00fe, 0x0005, 0x781c, 0xd08c, 0x0904,
+ 0x7fa4, 0x68c0, 0x90aa, 0x0005, 0x0a04, 0x85e8, 0x7d44, 0x7c40,
+ 0x9584, 0x00f6, 0x1510, 0x9484, 0x7000, 0x0140, 0x908a, 0x2000,
+ 0x1260, 0x9584, 0x0700, 0x8007, 0x0804, 0x7fab, 0x7000, 0x9084,
+ 0xff00, 0x9086, 0x8100, 0x0da8, 0x00b0, 0x9484, 0x0fff, 0x1130,
+ 0x7000, 0x9084, 0xff00, 0x9086, 0x8100, 0x11c0, 0x080c, 0xedd2,
+ 0x080c, 0x84cd, 0x7817, 0x0140, 0x00a8, 0x9584, 0x0076, 0x1118,
+ 0x080c, 0x852b, 0x19c0, 0xd5a4, 0x0148, 0x0046, 0x0056, 0x080c,
+ 0x8006, 0x080c, 0x2397, 0x005e, 0x004e, 0x0020, 0x080c, 0xedd2,
+ 0x7817, 0x0140, 0x080c, 0x7569, 0x0168, 0x2001, 0x0111, 0x2004,
+ 0xd08c, 0x0140, 0x6893, 0x0000, 0x2001, 0x0110, 0x2003, 0x0008,
+ 0x2003, 0x0000, 0x080c, 0x7fe7, 0x2001, 0x19f2, 0x2004, 0x9005,
+ 0x090c, 0x98ed, 0x0005, 0x0002, 0x7fbd, 0x82d5, 0x7fb4, 0x7fb4,
+ 0x7fb4, 0x7fb4, 0x7fb4, 0x7fb4, 0x7817, 0x0140, 0x2001, 0x19f2,
+ 0x2004, 0x9005, 0x090c, 0x98ed, 0x0005, 0x7000, 0x908c, 0xff00,
+ 0x9194, 0xf000, 0x810f, 0x9484, 0x0fff, 0x6892, 0x9286, 0x2000,
+ 0x1150, 0x6800, 0x9086, 0x0001, 0x1118, 0x080c, 0x583d, 0x0070,
+ 0x080c, 0x8026, 0x0058, 0x9286, 0x3000, 0x1118, 0x080c, 0x820d,
+ 0x0028, 0x9286, 0x8000, 0x1110, 0x080c, 0x83f4, 0x7817, 0x0140,
+ 0x2001, 0x19f2, 0x2004, 0x9005, 0x090c, 0x98ed, 0x0005, 0x2001,
+ 0x1810, 0x2004, 0xd08c, 0x0178, 0x2001, 0x1800, 0x2004, 0x9086,
+ 0x0003, 0x1148, 0x0026, 0x0036, 0x2011, 0x8048, 0x2518, 0x080c,
+ 0x4be9, 0x003e, 0x002e, 0x0005, 0x0036, 0x0046, 0x0056, 0x00f6,
+ 0x2079, 0x0200, 0x2019, 0xfffe, 0x7c30, 0x0050, 0x0036, 0x0046,
+ 0x0056, 0x00f6, 0x2079, 0x0200, 0x7d44, 0x7c40, 0x2019, 0xffff,
+ 0x2001, 0x1810, 0x2004, 0xd08c, 0x0160, 0x2001, 0x1800, 0x2004,
+ 0x9086, 0x0003, 0x1130, 0x0026, 0x2011, 0x8048, 0x080c, 0x4be9,
+ 0x002e, 0x00fe, 0x005e, 0x004e, 0x003e, 0x0005, 0x00b6, 0x00c6,
+ 0x7010, 0x9084, 0xff00, 0x8007, 0x9096, 0x0001, 0x0120, 0x9096,
+ 0x0023, 0x1904, 0x81de, 0x9186, 0x0023, 0x15c0, 0x080c, 0x8492,
+ 0x0904, 0x81de, 0x6120, 0x9186, 0x0001, 0x0150, 0x9186, 0x0004,
+ 0x0138, 0x9186, 0x0008, 0x0120, 0x9186, 0x000a, 0x1904, 0x81de,
+ 0x7124, 0x610a, 0x7030, 0x908e, 0x0200, 0x1130, 0x2009, 0x0015,
+ 0x080c, 0xb180, 0x0804, 0x81de, 0x908e, 0x0214, 0x0118, 0x908e,
+ 0x0210, 0x1130, 0x2009, 0x0015, 0x080c, 0xb180, 0x0804, 0x81de,
+ 0x908e, 0x0100, 0x1904, 0x81de, 0x7034, 0x9005, 0x1904, 0x81de,
+ 0x2009, 0x0016, 0x080c, 0xb180, 0x0804, 0x81de, 0x9186, 0x0022,
+ 0x1904, 0x81de, 0x7030, 0x908e, 0x0300, 0x1580, 0x68dc, 0xd0a4,
+ 0x0528, 0xc0b5, 0x68de, 0x7100, 0x918c, 0x00ff, 0x697e, 0x7004,
+ 0x6882, 0x00f6, 0x2079, 0x0100, 0x79e6, 0x78ea, 0x0006, 0x9084,
+ 0x00ff, 0x0016, 0x2008, 0x080c, 0x28dd, 0x7932, 0x7936, 0x001e,
+ 0x000e, 0x00fe, 0x080c, 0x2894, 0x695e, 0x703c, 0x00e6, 0x2071,
+ 0x0140, 0x7086, 0x2071, 0x1800, 0x70b6, 0x00ee, 0x7034, 0x9005,
+ 0x1904, 0x81de, 0x2009, 0x0017, 0x0804, 0x818e, 0x908e, 0x0400,
+ 0x1190, 0x7034, 0x9005, 0x1904, 0x81de, 0x080c, 0x7569, 0x0120,
+ 0x2009, 0x001d, 0x0804, 0x818e, 0x68dc, 0xc0a5, 0x68de, 0x2009,
+ 0x0030, 0x0804, 0x818e, 0x908e, 0x0500, 0x1140, 0x7034, 0x9005,
+ 0x1904, 0x81de, 0x2009, 0x0018, 0x0804, 0x818e, 0x908e, 0x2010,
+ 0x1120, 0x2009, 0x0019, 0x0804, 0x818e, 0x908e, 0x2110, 0x1120,
+ 0x2009, 0x001a, 0x0804, 0x818e, 0x908e, 0x5200, 0x1140, 0x7034,
+ 0x9005, 0x1904, 0x81de, 0x2009, 0x001b, 0x0804, 0x818e, 0x908e,
+ 0x5000, 0x1140, 0x7034, 0x9005, 0x1904, 0x81de, 0x2009, 0x001c,
+ 0x0804, 0x818e, 0x908e, 0x1300, 0x1120, 0x2009, 0x0034, 0x0804,
+ 0x818e, 0x908e, 0x1200, 0x1140, 0x7034, 0x9005, 0x1904, 0x81de,
+ 0x2009, 0x0024, 0x0804, 0x818e, 0x908c, 0xff00, 0x918e, 0x2400,
+ 0x1170, 0x2009, 0x002d, 0x2001, 0x1810, 0x2004, 0xd09c, 0x0904,
+ 0x818e, 0x080c, 0xdc98, 0x1904, 0x81de, 0x0804, 0x818c, 0x908c,
+ 0xff00, 0x918e, 0x5300, 0x1120, 0x2009, 0x002a, 0x0804, 0x818e,
+ 0x908e, 0x0f00, 0x1120, 0x2009, 0x0020, 0x0804, 0x818e, 0x908e,
+ 0x6104, 0x1530, 0x2029, 0x0205, 0x2011, 0x026d, 0x8208, 0x2204,
+ 0x9082, 0x0004, 0x8004, 0x8004, 0x20a8, 0x2011, 0x8015, 0x211c,
+ 0x8108, 0x0046, 0x2124, 0x080c, 0x4be9, 0x004e, 0x8108, 0x0f04,
+ 0x8142, 0x9186, 0x0280, 0x1d88, 0x2504, 0x8000, 0x202a, 0x2009,
+ 0x0260, 0x0c58, 0x202b, 0x0000, 0x2009, 0x0023, 0x0804, 0x818e,
+ 0x908e, 0x6000, 0x1120, 0x2009, 0x003f, 0x0804, 0x818e, 0x908e,
+ 0x5400, 0x1138, 0x080c, 0x8598, 0x1904, 0x81de, 0x2009, 0x0046,
+ 0x04a8, 0x908e, 0x5500, 0x1148, 0x080c, 0x85c0, 0x1118, 0x2009,
+ 0x0041, 0x0460, 0x2009, 0x0042, 0x0448, 0x908e, 0x7800, 0x1118,
+ 0x2009, 0x0045, 0x0418, 0x908e, 0x1000, 0x1118, 0x2009, 0x004e,
+ 0x00e8, 0x908e, 0x6300, 0x1118, 0x2009, 0x004a, 0x00b8, 0x908c,
+ 0xff00, 0x918e, 0x5600, 0x1118, 0x2009, 0x004f, 0x0078, 0x908c,
+ 0xff00, 0x918e, 0x5700, 0x1118, 0x2009, 0x0050, 0x0038, 0x2009,
+ 0x001d, 0x6838, 0xd0d4, 0x0110, 0x2009, 0x004c, 0x0016, 0x2011,
+ 0x0263, 0x2204, 0x8211, 0x220c, 0x080c, 0x2894, 0x1904, 0x81e1,
+ 0x080c, 0x66b2, 0x1904, 0x81e1, 0xbe12, 0xbd16, 0x001e, 0x0016,
+ 0x080c, 0x7569, 0x01c0, 0x68dc, 0xd08c, 0x1148, 0x7000, 0x9084,
+ 0x00ff, 0x1188, 0x7004, 0x9084, 0xff00, 0x1168, 0x0040, 0x687c,
+ 0x9606, 0x1148, 0x6880, 0x9506, 0x9084, 0xff00, 0x1120, 0x9584,
+ 0x00ff, 0xb8c2, 0x0080, 0xb8c0, 0x9005, 0x1168, 0x9186, 0x0046,
+ 0x1150, 0x687c, 0x9606, 0x1138, 0x6880, 0x9506, 0x9084, 0xff00,
+ 0x1110, 0x001e, 0x0098, 0x080c, 0xb0ab, 0x01a8, 0x2b08, 0x6112,
+ 0x6023, 0x0004, 0x7120, 0x610a, 0x001e, 0x9186, 0x004c, 0x1110,
+ 0x6023, 0x000a, 0x0016, 0x001e, 0x080c, 0xb180, 0x00ce, 0x00be,
+ 0x0005, 0x001e, 0x0cd8, 0x2001, 0x180e, 0x2004, 0xd0ec, 0x0120,
+ 0x2011, 0x8049, 0x080c, 0x4be9, 0x080c, 0xb153, 0x0d90, 0x2b08,
+ 0x6112, 0x6023, 0x0004, 0x7120, 0x610a, 0x001e, 0x0016, 0x9186,
+ 0x0017, 0x0118, 0x9186, 0x0030, 0x1128, 0x6007, 0x0009, 0x6017,
+ 0x2900, 0x0020, 0x6007, 0x0051, 0x6017, 0x0000, 0x602f, 0x0009,
+ 0x6003, 0x0001, 0x080c, 0x9383, 0x08a0, 0x080c, 0x8607, 0x1158,
+ 0x080c, 0x336a, 0x1140, 0x7010, 0x9084, 0xff00, 0x8007, 0x908e,
+ 0x0008, 0x1108, 0x0009, 0x0005, 0x00b6, 0x00c6, 0x0046, 0x7000,
+ 0x908c, 0xff00, 0x810f, 0x9186, 0x0033, 0x11e8, 0x080c, 0x8492,
+ 0x0904, 0x826d, 0x7124, 0x610a, 0x7030, 0x908e, 0x0200, 0x1140,
+ 0x7034, 0x9005, 0x15d0, 0x2009, 0x0015, 0x080c, 0xb180, 0x04a8,
+ 0x908e, 0x0100, 0x1590, 0x7034, 0x9005, 0x1578, 0x2009, 0x0016,
+ 0x080c, 0xb180, 0x0450, 0x9186, 0x0032, 0x1538, 0x7030, 0x908e,
+ 0x1400, 0x1518, 0x2009, 0x0038, 0x0016, 0x2011, 0x0263, 0x2204,
+ 0x8211, 0x220c, 0x080c, 0x2894, 0x11b8, 0x080c, 0x66b2, 0x11a0,
+ 0xbe12, 0xbd16, 0x080c, 0xb0ab, 0x0178, 0x2b08, 0x6112, 0x080c,
+ 0xd2d2, 0x6023, 0x0004, 0x7120, 0x610a, 0x001e, 0x080c, 0xb180,
+ 0x080c, 0x98ed, 0x0010, 0x00ce, 0x001e, 0x004e, 0x00ce, 0x00be,
+ 0x0005, 0x00b6, 0x0046, 0x00e6, 0x00d6, 0x2028, 0x2130, 0x9696,
+ 0x00ff, 0x11b8, 0x9592, 0xfffc, 0x02a0, 0x9596, 0xfffd, 0x1120,
+ 0x2009, 0x007f, 0x0804, 0x82cf, 0x9596, 0xfffe, 0x1120, 0x2009,
+ 0x007e, 0x0804, 0x82cf, 0x9596, 0xfffc, 0x1118, 0x2009, 0x0080,
+ 0x04f0, 0x2011, 0x0000, 0x2019, 0x1837, 0x231c, 0xd3ac, 0x0130,
+ 0x9026, 0x20a9, 0x0800, 0x2071, 0x1000, 0x0030, 0x2021, 0x0081,
+ 0x20a9, 0x077f, 0x2071, 0x1081, 0x2e1c, 0x93dd, 0x0000, 0x1140,
+ 0x82ff, 0x11d0, 0x9496, 0x00ff, 0x01b8, 0x2410, 0xc2fd, 0x00a0,
+ 0xbf10, 0x2600, 0x9706, 0xb814, 0x1120, 0x9546, 0x1110, 0x2408,
+ 0x00b0, 0x9745, 0x1148, 0x94c6, 0x007e, 0x0130, 0x94c6, 0x007f,
+ 0x0118, 0x94c6, 0x0080, 0x1d20, 0x8420, 0x8e70, 0x1f04, 0x82a4,
+ 0x82ff, 0x1118, 0x9085, 0x0001, 0x0018, 0xc2fc, 0x2208, 0x9006,
+ 0x00de, 0x00ee, 0x004e, 0x00be, 0x0005, 0x2001, 0x1837, 0x200c,
+ 0x9184, 0x0080, 0x0110, 0xd18c, 0x0138, 0x7000, 0x908c, 0xff00,
+ 0x810f, 0x9184, 0x000f, 0x004a, 0x7817, 0x0140, 0x2001, 0x19f2,
+ 0x2004, 0x9005, 0x090c, 0x98ed, 0x0005, 0x82fd, 0x82fd, 0x82fd,
+ 0x84a4, 0x82fd, 0x8306, 0x8331, 0x83bf, 0x82fd, 0x82fd, 0x82fd,
+ 0x82fd, 0x82fd, 0x82fd, 0x82fd, 0x82fd, 0x7817, 0x0140, 0x2001,
+ 0x19f2, 0x2004, 0x9005, 0x090c, 0x98ed, 0x0005, 0x00b6, 0x7110,
+ 0xd1bc, 0x01e8, 0x7120, 0x2160, 0x9c8c, 0x0007, 0x11c0, 0x9c8a,
+ 0x1cd0, 0x02a8, 0x6868, 0x9c02, 0x1290, 0x7008, 0x9084, 0x00ff,
+ 0x6110, 0x2158, 0xb910, 0x9106, 0x1150, 0x700c, 0xb914, 0x9106,
+ 0x1130, 0x7124, 0x610a, 0x2009, 0x0046, 0x080c, 0xb180, 0x7817,
+ 0x0140, 0x2001, 0x19f2, 0x2004, 0x9005, 0x090c, 0x98ed, 0x00be,
+ 0x0005, 0x00b6, 0x00c6, 0x9484, 0x0fff, 0x0904, 0x8395, 0x7110,
+ 0xd1bc, 0x1904, 0x8395, 0x7108, 0x700c, 0x2028, 0x918c, 0x00ff,
+ 0x2130, 0x9094, 0xff00, 0x15b0, 0x81ff, 0x15a0, 0x9080, 0x33ac,
+ 0x200d, 0x918c, 0xff00, 0x810f, 0x2001, 0x0080, 0x9106, 0x0904,
+ 0x8395, 0x080c, 0x66b2, 0x1904, 0x8395, 0xbe12, 0xbd16, 0xb800,
+ 0xd0ec, 0x15d8, 0xba04, 0x9294, 0xff00, 0x9286, 0x0600, 0x11a0,
+ 0x080c, 0xb0ab, 0x05e8, 0x2b08, 0x7028, 0x6046, 0x702c, 0x604a,
+ 0x6112, 0x6023, 0x0006, 0x7120, 0x610a, 0x7130, 0x6156, 0x2009,
+ 0x0044, 0x080c, 0xdf10, 0x0408, 0x080c, 0x6a92, 0x1138, 0xb807,
+ 0x0606, 0x0c30, 0x190c, 0x8271, 0x11c0, 0x0898, 0x080c, 0xb0ab,
+ 0x2b08, 0x0198, 0x6112, 0x6023, 0x0004, 0x7120, 0x610a, 0x9286,
+ 0x0400, 0x1118, 0x6007, 0x0005, 0x0010, 0x6007, 0x0001, 0x6003,
+ 0x0001, 0x080c, 0x9383, 0x080c, 0x98ed, 0x7817, 0x0140, 0x2001,
+ 0x19f2, 0x2004, 0x9005, 0x090c, 0x98ed, 0x00ce, 0x00be, 0x0005,
+ 0x2001, 0x180e, 0x2004, 0xd0ec, 0x0120, 0x2011, 0x8049, 0x080c,
+ 0x4be9, 0x080c, 0xb153, 0x0d48, 0x2b08, 0x6112, 0x6023, 0x0006,
+ 0x7120, 0x610a, 0x7130, 0x6156, 0x6017, 0xf300, 0x6003, 0x0001,
+ 0x6007, 0x0041, 0x080c, 0x933b, 0x080c, 0x98ed, 0x08b0, 0x00b6,
+ 0x7110, 0xd1bc, 0x01e8, 0x7020, 0x2060, 0x9c84, 0x0007, 0x11c0,
+ 0x9c82, 0x1cd0, 0x02a8, 0x6868, 0x9c02, 0x1290, 0x7008, 0x9084,
+ 0x00ff, 0x6110, 0x2158, 0xb910, 0x9106, 0x1150, 0x700c, 0xb914,
+ 0x9106, 0x1130, 0x7124, 0x610a, 0x2009, 0x0045, 0x080c, 0xb180,
+ 0x7817, 0x0140, 0x2001, 0x19f2, 0x2004, 0x9005, 0x090c, 0x98ed,
+ 0x00be, 0x0005, 0x6120, 0x9186, 0x0002, 0x0128, 0x9186, 0x0005,
+ 0x0110, 0x9085, 0x0001, 0x0005, 0x080c, 0x8607, 0x1180, 0x080c,
+ 0x336a, 0x1168, 0x7010, 0x9084, 0xff00, 0x8007, 0x9086, 0x0000,
+ 0x1130, 0x9184, 0x000f, 0x908a, 0x0006, 0x1208, 0x000b, 0x0005,
+ 0x840e, 0x840f, 0x840e, 0x840e, 0x8474, 0x8483, 0x0005, 0x00b6,
+ 0x700c, 0x7108, 0x080c, 0x2894, 0x1904, 0x8472, 0x080c, 0x66b2,
+ 0x1904, 0x8472, 0xbe12, 0xbd16, 0x7110, 0xd1bc, 0x0540, 0x702c,
+ 0xd084, 0x1120, 0xb800, 0xd0bc, 0x1904, 0x8472, 0x080c, 0x6a92,
+ 0x0148, 0x9086, 0x0004, 0x0130, 0x080c, 0x6a9a, 0x0118, 0x9086,
+ 0x0004, 0x1588, 0x00c6, 0x080c, 0x8492, 0x00ce, 0x05d8, 0x080c,
+ 0xb0ab, 0x2b08, 0x05b8, 0x6112, 0x080c, 0xd2d2, 0x6023, 0x0002,
+ 0x7120, 0x610a, 0x2009, 0x0088, 0x080c, 0xb180, 0x0458, 0x080c,
+ 0x6a92, 0x0148, 0x9086, 0x0004, 0x0130, 0x080c, 0x6a9a, 0x0118,
+ 0x9086, 0x0004, 0x1180, 0x080c, 0xb0ab, 0x2b08, 0x01d8, 0x6112,
+ 0x080c, 0xd2d2, 0x6023, 0x0005, 0x7120, 0x610a, 0x2009, 0x0088,
+ 0x080c, 0xb180, 0x0078, 0x080c, 0xb0ab, 0x2b08, 0x0158, 0x6112,
+ 0x080c, 0xd2d2, 0x6023, 0x0004, 0x7120, 0x610a, 0x2009, 0x0001,
+ 0x080c, 0xb180, 0x00be, 0x0005, 0x7110, 0xd1bc, 0x0158, 0x00d1,
+ 0x0148, 0x080c, 0x83ea, 0x1130, 0x7124, 0x610a, 0x2009, 0x0089,
+ 0x080c, 0xb180, 0x0005, 0x7110, 0xd1bc, 0x0158, 0x0059, 0x0148,
+ 0x080c, 0x83ea, 0x1130, 0x7124, 0x610a, 0x2009, 0x008a, 0x080c,
+ 0xb180, 0x0005, 0x7020, 0x2060, 0x9c84, 0x0007, 0x1158, 0x9c82,
+ 0x1cd0, 0x0240, 0x2001, 0x181a, 0x2004, 0x9c02, 0x1218, 0x9085,
+ 0x0001, 0x0005, 0x9006, 0x0ce8, 0x00b6, 0x7110, 0xd1bc, 0x11d8,
+ 0x7024, 0x2060, 0x9c84, 0x0007, 0x11b0, 0x9c82, 0x1cd0, 0x0298,
+ 0x6868, 0x9c02, 0x1280, 0x7008, 0x9084, 0x00ff, 0x6110, 0x2158,
+ 0xb910, 0x9106, 0x1140, 0x700c, 0xb914, 0x9106, 0x1120, 0x2009,
+ 0x0051, 0x080c, 0xb180, 0x7817, 0x0140, 0x2001, 0x19f2, 0x2004,
+ 0x9005, 0x090c, 0x98ed, 0x00be, 0x0005, 0x2031, 0x0105, 0x0069,
+ 0x0005, 0x2031, 0x0206, 0x0049, 0x0005, 0x2031, 0x0207, 0x0029,
+ 0x0005, 0x2031, 0x0213, 0x0009, 0x0005, 0x00c6, 0x0096, 0x00f6,
+ 0x7000, 0x9084, 0xf000, 0x9086, 0xc000, 0x05d0, 0x080c, 0xb0ab,
+ 0x05b8, 0x0066, 0x00c6, 0x0046, 0x2011, 0x0263, 0x2204, 0x8211,
+ 0x220c, 0x080c, 0x2894, 0x15a0, 0x080c, 0x66b2, 0x1588, 0xbe12,
+ 0xbd16, 0x2b00, 0x004e, 0x00ce, 0x6012, 0x080c, 0xd2d2, 0x080c,
+ 0x100e, 0x0510, 0x2900, 0x605a, 0x9006, 0xa802, 0xa866, 0xac6a,
+ 0xa85c, 0x90f8, 0x001b, 0x20a9, 0x000e, 0xa860, 0x20e8, 0x20e1,
+ 0x0000, 0x2fa0, 0x2e98, 0x4003, 0x006e, 0x6616, 0x6007, 0x003e,
+ 0x6023, 0x0001, 0x6003, 0x0001, 0x080c, 0x9383, 0x080c, 0x98ed,
+ 0x00fe, 0x009e, 0x00ce, 0x0005, 0x080c, 0xb101, 0x006e, 0x0cc0,
+ 0x004e, 0x00ce, 0x0cc8, 0x00c6, 0x7000, 0x908c, 0xff00, 0x9184,
+ 0xf000, 0x810f, 0x9086, 0x2000, 0x1904, 0x8582, 0x9186, 0x0022,
+ 0x15f0, 0x2001, 0x0111, 0x2004, 0x9005, 0x1904, 0x8584, 0x7030,
+ 0x908e, 0x0400, 0x0904, 0x8584, 0x908e, 0x6000, 0x05e8, 0x908e,
+ 0x5400, 0x05d0, 0x908e, 0x0300, 0x11d8, 0x2009, 0x1837, 0x210c,
+ 0xd18c, 0x1590, 0xd1a4, 0x1580, 0x080c, 0x6a50, 0x0588, 0x68b0,
+ 0x9084, 0x00ff, 0x7100, 0x918c, 0x00ff, 0x9106, 0x1518, 0x6880,
+ 0x69b0, 0x918c, 0xff00, 0x9105, 0x7104, 0x9106, 0x11d8, 0x00e0,
+ 0x2009, 0x0103, 0x210c, 0xd1b4, 0x11a8, 0x908e, 0x5200, 0x09e8,
+ 0x908e, 0x0500, 0x09d0, 0x908e, 0x5000, 0x09b8, 0x0058, 0x9186,
+ 0x0023, 0x1140, 0x080c, 0x8492, 0x0128, 0x6004, 0x9086, 0x0002,
+ 0x0118, 0x0000, 0x9006, 0x0010, 0x9085, 0x0001, 0x00ce, 0x0005,
+ 0x7030, 0x908e, 0x0300, 0x0118, 0x908e, 0x5200, 0x1d98, 0x2001,
+ 0x1837, 0x2004, 0x9084, 0x0009, 0x9086, 0x0008, 0x0d68, 0x0c50,
+ 0x0156, 0x0046, 0x0016, 0x0036, 0x7038, 0x2020, 0x8427, 0x94a4,
+ 0x0007, 0xd484, 0x0148, 0x20a9, 0x0004, 0x2019, 0x1805, 0x2011,
+ 0x027a, 0x080c, 0xc0e3, 0x1178, 0xd48c, 0x0148, 0x20a9, 0x0004,
+ 0x2019, 0x1801, 0x2011, 0x027e, 0x080c, 0xc0e3, 0x1120, 0xd494,
+ 0x0110, 0x9085, 0x0001, 0x003e, 0x001e, 0x004e, 0x015e, 0x0005,
+ 0x0156, 0x0046, 0x0016, 0x0036, 0x7038, 0x2020, 0x8427, 0x94a4,
+ 0x0007, 0xd484, 0x0148, 0x20a9, 0x0004, 0x2019, 0x1805, 0x2011,
+ 0x0272, 0x080c, 0xc0e3, 0x1178, 0xd48c, 0x0148, 0x20a9, 0x0004,
+ 0x2019, 0x1801, 0x2011, 0x0276, 0x080c, 0xc0e3, 0x1120, 0xd494,
+ 0x0110, 0x9085, 0x0001, 0x003e, 0x001e, 0x004e, 0x015e, 0x0005,
+ 0x00f6, 0x2079, 0x0200, 0x7800, 0xc0e5, 0xc0cc, 0x7802, 0x00fe,
+ 0x0005, 0x00f6, 0x2079, 0x1800, 0x7834, 0xd084, 0x1130, 0x2079,
+ 0x0200, 0x7800, 0x9085, 0x1200, 0x7802, 0x00fe, 0x0005, 0x00e6,
+ 0x2071, 0x1800, 0x7034, 0xc084, 0x7036, 0x00ee, 0x0005, 0x0016,
+ 0x2001, 0x1837, 0x200c, 0x9184, 0x0080, 0x0118, 0xd18c, 0x0118,
+ 0x9006, 0x001e, 0x0005, 0x9085, 0x0001, 0x0cd8, 0x2071, 0x19fc,
+ 0x7003, 0x0003, 0x700f, 0x0361, 0x9006, 0x701a, 0x707a, 0x7012,
+ 0x7017, 0x1cd0, 0x7007, 0x0000, 0x7026, 0x702b, 0xa52d, 0x7032,
+ 0x703a, 0x703f, 0x0064, 0x7037, 0xa595, 0x7047, 0xffff, 0x704a,
+ 0x704f, 0x5665, 0x7052, 0x7063, 0x87aa, 0x080c, 0x1027, 0x090c,
+ 0x0dc5, 0x2900, 0x7042, 0xa867, 0x0003, 0xa86f, 0x0100, 0xa8ab,
+ 0xdcb0, 0x0005, 0x2071, 0x19fc, 0x1d04, 0x86f8, 0x2091, 0x6000,
+ 0x700c, 0x8001, 0x700e, 0x1540, 0x2001, 0x013c, 0x2004, 0x9005,
+ 0x190c, 0x8818, 0x2001, 0x1869, 0x2004, 0xd0c4, 0x0158, 0x3a00,
+ 0xd08c, 0x1140, 0x20d1, 0x0000, 0x20d1, 0x0001, 0x20d1, 0x0000,
+ 0x080c, 0x0dc5, 0x700f, 0x0361, 0x7007, 0x0001, 0x0126, 0x2091,
+ 0x8000, 0x080c, 0x87ef, 0x7048, 0x900d, 0x0148, 0x8109, 0x714a,
+ 0x1130, 0x704c, 0x080f, 0x0018, 0x0126, 0x2091, 0x8000, 0x7024,
+ 0x900d, 0x0188, 0x7020, 0x8001, 0x7022, 0x1168, 0x7023, 0x0009,
+ 0x8109, 0x7126, 0x9186, 0x03e8, 0x1110, 0x7028, 0x080f, 0x81ff,
+ 0x1110, 0x7028, 0x080f, 0x7030, 0x900d, 0x05a8, 0x702c, 0x8001,
+ 0x702e, 0x1588, 0x0016, 0x2009, 0x0306, 0x210c, 0x9184, 0x0030,
+ 0x01e8, 0x9184, 0x0048, 0x9086, 0x0008, 0x11c0, 0x7038, 0x9005,
+ 0x01a8, 0x8001, 0x703a, 0x1190, 0x080c, 0x7569, 0x0178, 0x00e6,
+ 0x2071, 0x19e9, 0x080c, 0xa623, 0x00ee, 0x1140, 0x2009, 0x1a87,
+ 0x2104, 0x8000, 0x0208, 0x200a, 0x001e, 0x0068, 0x001e, 0x702f,
+ 0x0009, 0x8109, 0x7132, 0x0128, 0x9184, 0x007f, 0x090c, 0xa6d9,
+ 0x0010, 0x7034, 0x080f, 0x7044, 0x9005, 0x0118, 0x0310, 0x8001,
+ 0x7046, 0x7054, 0x900d, 0x0168, 0x7050, 0x8001, 0x7052, 0x1148,
+ 0x7053, 0x0009, 0x8109, 0x7156, 0x1120, 0x7158, 0x7156, 0x7060,
+ 0x080f, 0x7018, 0x900d, 0x01d8, 0x0016, 0x7078, 0x900d, 0x0158,
+ 0x7074, 0x8001, 0x7076, 0x1138, 0x7077, 0x0009, 0x8109, 0x717a,
+ 0x1110, 0x707c, 0x080f, 0x001e, 0x7008, 0x8001, 0x700a, 0x1138,
+ 0x700b, 0x0009, 0x8109, 0x711a, 0x1110, 0x701c, 0x080f, 0x012e,
+ 0x7004, 0x0002, 0x8720, 0x8721, 0x873d, 0x00e6, 0x2071, 0x19fc,
+ 0x7018, 0x9005, 0x1120, 0x711a, 0x721e, 0x700b, 0x0009, 0x00ee,
+ 0x0005, 0x00e6, 0x0006, 0x2071, 0x19fc, 0x701c, 0x9206, 0x1120,
+ 0x701a, 0x701e, 0x707a, 0x707e, 0x000e, 0x00ee, 0x0005, 0x00e6,
+ 0x2071, 0x19fc, 0xb888, 0x9102, 0x0208, 0xb98a, 0x00ee, 0x0005,
+ 0x0005, 0x00b6, 0x7110, 0x080c, 0x671d, 0x1168, 0xb888, 0x8001,
+ 0x0250, 0xb88a, 0x1140, 0x0126, 0x2091, 0x8000, 0x0016, 0x080c,
+ 0x98ed, 0x001e, 0x012e, 0x8108, 0x9182, 0x0800, 0x0218, 0x900e,
+ 0x7007, 0x0002, 0x7112, 0x00be, 0x0005, 0x7014, 0x2060, 0x0126,
+ 0x2091, 0x8000, 0x6040, 0x9005, 0x0128, 0x8001, 0x6042, 0x1110,
+ 0x080c, 0xd163, 0x6018, 0x9005, 0x0558, 0x8001, 0x601a, 0x1540,
+ 0x6120, 0x9186, 0x0003, 0x0148, 0x9186, 0x0006, 0x0130, 0x9186,
+ 0x0009, 0x11e0, 0x611c, 0xd1c4, 0x1100, 0x080c, 0xce56, 0x01b0,
+ 0x6014, 0x2048, 0xa884, 0x908a, 0x199a, 0x0280, 0x9082, 0x1999,
+ 0xa886, 0x908a, 0x199a, 0x0210, 0x2001, 0x1999, 0x8003, 0x800b,
+ 0x810b, 0x9108, 0x611a, 0xa87c, 0xd0e4, 0x0110, 0x080c, 0xcb3e,
+ 0x012e, 0x9c88, 0x0018, 0x7116, 0x2001, 0x181a, 0x2004, 0x9102,
+ 0x0220, 0x7017, 0x1cd0, 0x7007, 0x0000, 0x0005, 0x00e6, 0x2071,
+ 0x19fc, 0x7027, 0x07d0, 0x7023, 0x0009, 0x00ee, 0x0005, 0x2001,
+ 0x1a05, 0x2003, 0x0000, 0x0005, 0x00e6, 0x2071, 0x19fc, 0x7132,
+ 0x702f, 0x0009, 0x00ee, 0x0005, 0x2011, 0x1a08, 0x2013, 0x0000,
+ 0x0005, 0x00e6, 0x2071, 0x19fc, 0x711a, 0x721e, 0x700b, 0x0009,
+ 0x00ee, 0x0005, 0x0086, 0x0026, 0x705c, 0x8000, 0x705e, 0x2001,
+ 0x1a0c, 0x2044, 0xa06c, 0x9086, 0x0000, 0x0150, 0x7070, 0xa09a,
+ 0x706c, 0xa096, 0x7068, 0xa092, 0x7064, 0xa08e, 0x080c, 0x10f8,
+ 0x002e, 0x008e, 0x0005, 0x0006, 0x0016, 0x0096, 0x00a6, 0x00b6,
+ 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x0156, 0x080c, 0x8642, 0x015e,
+ 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x00be, 0x00ae, 0x009e, 0x001e,
+ 0x000e, 0x0005, 0x00e6, 0x2071, 0x19fc, 0x717a, 0x727e, 0x7077,
+ 0x0009, 0x00ee, 0x0005, 0x00e6, 0x0006, 0x2071, 0x19fc, 0x707c,
+ 0x9206, 0x1110, 0x707a, 0x707e, 0x000e, 0x00ee, 0x0005, 0x2069,
+ 0x1800, 0x69e8, 0xd1e4, 0x1518, 0x0026, 0xd1ec, 0x0140, 0x6a54,
+ 0x6874, 0x9202, 0x0288, 0x8117, 0x9294, 0x00c0, 0x0088, 0x9184,
+ 0x0007, 0x01a0, 0x8109, 0x9184, 0x0007, 0x0110, 0x69ea, 0x0070,
+ 0x8107, 0x9084, 0x0007, 0x910d, 0x8107, 0x9106, 0x9094, 0x00c0,
+ 0x9184, 0xff3f, 0x9205, 0x68ea, 0x080c, 0x0eee, 0x002e, 0x0005,
+ 0x0016, 0x00c6, 0x2009, 0xfff4, 0x210d, 0x2061, 0x0100, 0x60f0,
+ 0x9100, 0x60f3, 0x0000, 0x2009, 0xfff4, 0x200f, 0x1220, 0x8108,
+ 0x2105, 0x8000, 0x200f, 0x00ce, 0x001e, 0x0005, 0x00c6, 0x2061,
+ 0x1a75, 0x00ce, 0x0005, 0x9184, 0x000f, 0x8003, 0x8003, 0x8003,
+ 0x9080, 0x1a75, 0x2060, 0x0005, 0xa884, 0x908a, 0x199a, 0x1638,
+ 0x9005, 0x1150, 0x00c6, 0x2061, 0x1a75, 0x6014, 0x00ce, 0x9005,
+ 0x1130, 0x2001, 0x001e, 0x0018, 0x908e, 0xffff, 0x01b0, 0x8003,
+ 0x800b, 0x810b, 0x9108, 0x611a, 0xa87c, 0x908c, 0x00c0, 0x918e,
+ 0x00c0, 0x0904, 0x88c6, 0xd0b4, 0x1168, 0xd0bc, 0x1904, 0x889f,
+ 0x2009, 0x0006, 0x080c, 0x88f3, 0x0005, 0x900e, 0x0c60, 0x2001,
+ 0x1999, 0x08b0, 0xd0fc, 0x0160, 0x908c, 0x0003, 0x0120, 0x918e,
+ 0x0003, 0x1904, 0x88ed, 0x908c, 0x2020, 0x918e, 0x2020, 0x01a8,
+ 0x6024, 0xd0d4, 0x11e8, 0x2009, 0x1869, 0x2104, 0xd084, 0x1138,
+ 0x87ff, 0x1120, 0x2009, 0x0043, 0x0804, 0xb180, 0x0005, 0x87ff,
+ 0x1de8, 0x2009, 0x0042, 0x0804, 0xb180, 0x6110, 0x00b6, 0x2158,
+ 0xb900, 0x00be, 0xd1ac, 0x0d20, 0x6024, 0xc0cd, 0x6026, 0x0c00,
+ 0xc0d4, 0x6026, 0xa890, 0x602e, 0xa88c, 0x6032, 0x08e0, 0xd0fc,
+ 0x0160, 0x908c, 0x0003, 0x0120, 0x918e, 0x0003, 0x1904, 0x88ed,
+ 0x908c, 0x2020, 0x918e, 0x2020, 0x0170, 0x0076, 0x00f6, 0x2c78,
+ 0x080c, 0x1768, 0x00fe, 0x007e, 0x87ff, 0x1120, 0x2009, 0x0042,
+ 0x080c, 0xb180, 0x0005, 0x6110, 0x00b6, 0x2158, 0xb900, 0x00be,
+ 0xd1ac, 0x0d58, 0x6124, 0xc1cd, 0x6126, 0x0c38, 0xd0fc, 0x0188,
+ 0x908c, 0x2020, 0x918e, 0x2020, 0x01a8, 0x9084, 0x0003, 0x908e,
+ 0x0002, 0x0148, 0x87ff, 0x1120, 0x2009, 0x0041, 0x080c, 0xb180,
+ 0x0005, 0x00b9, 0x0ce8, 0x87ff, 0x1dd8, 0x2009, 0x0043, 0x080c,
+ 0xb180, 0x0cb0, 0x6110, 0x00b6, 0x2158, 0xb900, 0x00be, 0xd1ac,
+ 0x0d20, 0x6124, 0xc1cd, 0x6126, 0x0c00, 0x2009, 0x0004, 0x0019,
+ 0x0005, 0x2009, 0x0001, 0x0096, 0x080c, 0xce56, 0x0518, 0x6014,
+ 0x2048, 0xa982, 0xa800, 0x6016, 0x9186, 0x0001, 0x1188, 0xa97c,
+ 0x918c, 0x8100, 0x918e, 0x8100, 0x1158, 0x00c6, 0x2061, 0x1a75,
+ 0x6200, 0xd28c, 0x1120, 0x6204, 0x8210, 0x0208, 0x6206, 0x00ce,
+ 0x080c, 0x6c10, 0x6014, 0x904d, 0x0076, 0x2039, 0x0000, 0x190c,
+ 0x883c, 0x007e, 0x009e, 0x0005, 0x0156, 0x00c6, 0x2061, 0x1a75,
+ 0x6000, 0x81ff, 0x0110, 0x9205, 0x0008, 0x9204, 0x6002, 0x00ce,
+ 0x015e, 0x0005, 0x6800, 0xd08c, 0x1138, 0x6808, 0x9005, 0x0120,
+ 0x8001, 0x680a, 0x9085, 0x0001, 0x0005, 0x2071, 0x1925, 0x7003,
+ 0x0006, 0x7007, 0x0000, 0x700f, 0x0000, 0x7013, 0x0001, 0x080c,
+ 0x1027, 0x090c, 0x0dc5, 0xa867, 0x0006, 0xa86b, 0x0001, 0xa8ab,
+ 0xdcb0, 0xa89f, 0x0000, 0x2900, 0x702e, 0x7033, 0x0000, 0x0005,
+ 0x0126, 0x2091, 0x8000, 0x0096, 0x00e6, 0x2071, 0x1925, 0x702c,
+ 0x2048, 0x6a2c, 0x721e, 0x6b30, 0x7322, 0x6834, 0x7026, 0xa896,
+ 0x6838, 0x702a, 0xa89a, 0x6824, 0x7016, 0x683c, 0x701a, 0x2009,
+ 0x0028, 0x200a, 0x9005, 0x0148, 0x900e, 0x9188, 0x000c, 0x8001,
+ 0x1de0, 0x2100, 0x9210, 0x1208, 0x8318, 0xaa8e, 0xab92, 0x7010,
+ 0xd084, 0x0168, 0xc084, 0x7007, 0x0001, 0x700f, 0x0000, 0x0006,
+ 0x2009, 0x1ad2, 0x2104, 0x9082, 0x0007, 0x200a, 0x000e, 0xc095,
+ 0x7012, 0x2008, 0x2001, 0x003b, 0x080c, 0x1611, 0x9006, 0x2071,
+ 0x193e, 0x7002, 0x7006, 0x702a, 0x00ee, 0x009e, 0x012e, 0x0005,
+ 0x2009, 0x1ad2, 0x2104, 0x9080, 0x0007, 0x200a, 0x0005, 0x00e6,
+ 0x0126, 0x0156, 0x2091, 0x8000, 0x2071, 0x1800, 0x7154, 0x2001,
+ 0x0008, 0x910a, 0x0638, 0x2001, 0x187d, 0x20ac, 0x9006, 0x9080,
+ 0x0008, 0x1f04, 0x89af, 0x71c0, 0x9102, 0x02e0, 0x2071, 0x1877,
+ 0x20a9, 0x0007, 0x00c6, 0x080c, 0xb0ab, 0x6023, 0x0009, 0x6003,
+ 0x0004, 0x601f, 0x0101, 0x0089, 0x0126, 0x2091, 0x8000, 0x080c,
+ 0x8b2d, 0x012e, 0x1f04, 0x89bb, 0x9006, 0x00ce, 0x015e, 0x012e,
+ 0x00ee, 0x0005, 0x9085, 0x0001, 0x0cc8, 0x00e6, 0x00b6, 0x0096,
+ 0x0086, 0x0056, 0x0046, 0x0026, 0x7118, 0x720c, 0x7620, 0x7004,
+ 0xd084, 0x1128, 0x2021, 0x0024, 0x2029, 0x0002, 0x0020, 0x2021,
+ 0x002c, 0x2029, 0x000a, 0x080c, 0x100e, 0x090c, 0x0dc5, 0x2900,
+ 0x6016, 0x2058, 0xac66, 0x9006, 0xa802, 0xa806, 0xa86a, 0xa87a,
+ 0xa8aa, 0xa887, 0x0005, 0xa87f, 0x0020, 0x7008, 0xa89a, 0x7010,
+ 0xa89e, 0xae8a, 0xa8af, 0xffff, 0xa8b3, 0x0000, 0x8109, 0x0160,
+ 0x080c, 0x100e, 0x090c, 0x0dc5, 0xad66, 0x2b00, 0xa802, 0x2900,
+ 0xb806, 0x2058, 0x8109, 0x1da0, 0x002e, 0x004e, 0x005e, 0x008e,
+ 0x009e, 0x00be, 0x00ee, 0x0005, 0x2079, 0x0000, 0x2071, 0x1925,
+ 0x7004, 0x004b, 0x700c, 0x0002, 0x8a27, 0x8a20, 0x8a20, 0x0005,
+ 0x8a31, 0x8a87, 0x8a87, 0x8a87, 0x8a88, 0x8a99, 0x8a99, 0x700c,
+ 0x0cba, 0x0126, 0x2091, 0x8000, 0x78a0, 0x79a0, 0x9106, 0x1904,
+ 0x8a79, 0x7814, 0xd0bc, 0x1904, 0x8a82, 0x012e, 0x7018, 0x910a,
+ 0x1128, 0x7030, 0x9005, 0x1904, 0x8acb, 0x0005, 0x1210, 0x7114,
+ 0x910a, 0x9192, 0x000a, 0x0210, 0x2009, 0x000a, 0x2001, 0x1888,
+ 0x2014, 0x2001, 0x1937, 0x2004, 0x9100, 0x9202, 0x0e50, 0x080c,
+ 0x8c25, 0x2200, 0x9102, 0x0208, 0x2208, 0x0096, 0x702c, 0x2048,
+ 0xa873, 0x0001, 0xa976, 0x080c, 0x8d2e, 0x2100, 0xa87e, 0xa86f,
+ 0x0000, 0x009e, 0x0126, 0x2091, 0x8000, 0x2009, 0x1a1c, 0x2104,
+ 0xc085, 0x200a, 0x700f, 0x0002, 0x012e, 0x080c, 0x1117, 0x1de8,
+ 0x0005, 0x78a0, 0x79a0, 0x9106, 0x0904, 0x8a39, 0x080c, 0x8bfd,
+ 0x012e, 0x0005, 0x7810, 0xc0c5, 0x7812, 0x0804, 0x8a39, 0x0005,
+ 0x700c, 0x0002, 0x8a8d, 0x8a90, 0x8a8f, 0x080c, 0x8a2f, 0x0005,
+ 0x8001, 0x700e, 0x0096, 0x702c, 0x2048, 0xa974, 0x009e, 0x0011,
+ 0x0ca0, 0x0005, 0x0096, 0x702c, 0x2048, 0x7018, 0x9100, 0x7214,
+ 0x921a, 0x1130, 0x701c, 0xa88e, 0x7020, 0xa892, 0x9006, 0x0068,
+ 0x0006, 0x080c, 0x8d2e, 0x2100, 0xaa8c, 0x9210, 0xaa8e, 0x1220,
+ 0xa890, 0x9081, 0x0000, 0xa892, 0x000e, 0x009e, 0x0126, 0x2091,
+ 0x8000, 0x78a2, 0x701a, 0x080c, 0x8bfd, 0x012e, 0x0005, 0x00e6,
+ 0x2071, 0x1925, 0x700c, 0x0002, 0x8ac9, 0x8ac9, 0x8ac7, 0x700f,
+ 0x0001, 0x00ee, 0x0005, 0x0126, 0x2091, 0x8000, 0x7030, 0x9005,
+ 0x0508, 0x2078, 0x7814, 0x2048, 0xae88, 0x00b6, 0x2059, 0x0000,
+ 0x080c, 0x8b36, 0x00be, 0x01b0, 0x00e6, 0x2071, 0x193e, 0x080c,
+ 0x8b7d, 0x00ee, 0x0178, 0x0096, 0x080c, 0x1027, 0x2900, 0x009e,
+ 0x0148, 0xa8aa, 0x04b9, 0x0041, 0x2001, 0x1948, 0x2003, 0x0000,
+ 0x012e, 0x08c8, 0x012e, 0x0005, 0x00d6, 0x00c6, 0x0086, 0x00a6,
+ 0x2940, 0x2650, 0x2600, 0x9005, 0x0180, 0xa864, 0x9084, 0x000f,
+ 0x2068, 0x9d88, 0x20f0, 0x2165, 0x0056, 0x2029, 0x0000, 0x080c,
+ 0x8cb3, 0x080c, 0x20a8, 0x1dd8, 0x005e, 0x00ae, 0x2001, 0x187f,
+ 0x2004, 0xa88a, 0x080c, 0x1768, 0x781f, 0x0101, 0x7813, 0x0000,
+ 0x0126, 0x2091, 0x8000, 0x080c, 0x8b8c, 0x012e, 0x008e, 0x00ce,
+ 0x00de, 0x0005, 0x7030, 0x9005, 0x0138, 0x2078, 0x780c, 0x7032,
+ 0x2001, 0x1948, 0x2003, 0x0001, 0x0005, 0x00e6, 0x2071, 0x1925,
+ 0x7030, 0x600e, 0x2c00, 0x7032, 0x00ee, 0x0005, 0x00d6, 0x00c6,
+ 0x0026, 0x9b80, 0x8dfc, 0x2005, 0x906d, 0x090c, 0x0dc5, 0x9b80,
+ 0x8df4, 0x2005, 0x9065, 0x090c, 0x0dc5, 0x6114, 0x2600, 0x9102,
+ 0x0248, 0x6828, 0x9102, 0x02f0, 0x9085, 0x0001, 0x002e, 0x00ce,
+ 0x00de, 0x0005, 0x6804, 0xd094, 0x0148, 0x6854, 0xd084, 0x1178,
+ 0xc085, 0x6856, 0x2011, 0x8026, 0x080c, 0x4be9, 0x684c, 0x0096,
+ 0x904d, 0x090c, 0x0dc5, 0xa804, 0x8000, 0xa806, 0x009e, 0x9006,
+ 0x2030, 0x0c20, 0x6854, 0xd08c, 0x1d08, 0xc08d, 0x6856, 0x2011,
+ 0x8025, 0x080c, 0x4be9, 0x684c, 0x0096, 0x904d, 0x090c, 0x0dc5,
+ 0xa800, 0x8000, 0xa802, 0x009e, 0x0888, 0x7000, 0x2019, 0x0008,
+ 0x8319, 0x7104, 0x9102, 0x1118, 0x2300, 0x9005, 0x0020, 0x0210,
+ 0x9302, 0x0008, 0x8002, 0x0005, 0x00d6, 0x7814, 0x9005, 0x090c,
+ 0x0dc5, 0x781c, 0x9084, 0x0101, 0x9086, 0x0101, 0x190c, 0x0dc5,
+ 0x7827, 0x0000, 0x2069, 0x193e, 0x6804, 0x9080, 0x1940, 0x2f08,
+ 0x2102, 0x6904, 0x8108, 0x9182, 0x0008, 0x0208, 0x900e, 0x6906,
+ 0x9180, 0x1940, 0x2003, 0x0000, 0x00de, 0x0005, 0x0096, 0x00c6,
+ 0x2060, 0x6014, 0x2048, 0xa8a8, 0x0096, 0x2048, 0x9005, 0x190c,
+ 0x1040, 0x009e, 0xa8ab, 0x0000, 0x080c, 0x0fc0, 0x080c, 0xb101,
+ 0x00ce, 0x009e, 0x0005, 0x6020, 0x9086, 0x0009, 0x1128, 0x601c,
+ 0xd0c4, 0x0110, 0x9006, 0x0005, 0x9085, 0x0001, 0x0005, 0x6000,
+ 0x9086, 0x0000, 0x0178, 0x6010, 0x9005, 0x0150, 0x00b6, 0x2058,
+ 0x080c, 0x8f31, 0x00be, 0x6013, 0x0000, 0x601b, 0x0000, 0x0010,
+ 0x2c00, 0x0861, 0x0005, 0x2009, 0x1929, 0x210c, 0xd194, 0x0005,
+ 0x0126, 0x2091, 0x8000, 0x00e6, 0x2071, 0x1925, 0x7110, 0xc194,
+ 0xd19c, 0x1118, 0xc185, 0x7007, 0x0000, 0x7112, 0x2001, 0x003b,
+ 0x080c, 0x1611, 0x00ee, 0x012e, 0x0005, 0x7814, 0xd0bc, 0x1108,
+ 0x0005, 0x7810, 0xc0c5, 0x7812, 0x0cc0, 0x0096, 0x00d6, 0x9006,
+ 0x7006, 0x700e, 0x701a, 0x701e, 0x7022, 0x7016, 0x702a, 0x7026,
+ 0x702f, 0x0000, 0x080c, 0x8d7c, 0x0170, 0x080c, 0x8db1, 0x0158,
+ 0x2900, 0x7002, 0x700a, 0x701a, 0x7013, 0x0001, 0x701f, 0x000a,
+ 0x00de, 0x009e, 0x0005, 0x900e, 0x0cd8, 0x00e6, 0x0096, 0x0086,
+ 0x00d6, 0x00c6, 0x2071, 0x1932, 0x721c, 0x2100, 0x9202, 0x1618,
+ 0x080c, 0x8db1, 0x090c, 0x0dc5, 0x7018, 0x9005, 0x1160, 0x2900,
+ 0x7002, 0x700a, 0x701a, 0x9006, 0x7006, 0x700e, 0xa806, 0xa802,
+ 0x7012, 0x701e, 0x0038, 0x2040, 0xa806, 0x2900, 0xa002, 0x701a,
+ 0xa803, 0x0000, 0x7010, 0x8000, 0x7012, 0x701c, 0x9080, 0x000a,
+ 0x701e, 0x721c, 0x08d0, 0x721c, 0x00ce, 0x00de, 0x008e, 0x009e,
+ 0x00ee, 0x0005, 0x0096, 0x0156, 0x0136, 0x0146, 0x00e6, 0x0126,
+ 0x2091, 0x8000, 0x2071, 0x1932, 0x7300, 0x831f, 0x831e, 0x831e,
+ 0x9384, 0x003f, 0x20e8, 0x939c, 0xffc0, 0x9398, 0x0003, 0x7104,
+ 0x080c, 0x8d2e, 0x810c, 0x2100, 0x9318, 0x8003, 0x2228, 0x2021,
+ 0x0078, 0x9402, 0x9532, 0x0208, 0x2028, 0x2500, 0x8004, 0x20a8,
+ 0x23a0, 0xa001, 0xa001, 0x4005, 0x2508, 0x080c, 0x8d37, 0x2130,
+ 0x7014, 0x9600, 0x7016, 0x2600, 0x711c, 0x9102, 0x701e, 0x7004,
+ 0x9600, 0x2008, 0x9082, 0x000a, 0x1190, 0x7000, 0x2048, 0xa800,
+ 0x9005, 0x1148, 0x2009, 0x0001, 0x0026, 0x080c, 0x8c25, 0x002e,
+ 0x7000, 0x2048, 0xa800, 0x7002, 0x7007, 0x0000, 0x0008, 0x7106,
+ 0x2500, 0x9212, 0x1904, 0x8c64, 0x012e, 0x00ee, 0x014e, 0x013e,
+ 0x015e, 0x009e, 0x0005, 0x0016, 0x0026, 0x00e6, 0x0126, 0x2091,
+ 0x8000, 0x9580, 0x8df4, 0x2005, 0x9075, 0x090c, 0x0dc5, 0x080c,
+ 0x8d09, 0x012e, 0x9580, 0x8df0, 0x2005, 0x9075, 0x090c, 0x0dc5,
+ 0x0156, 0x0136, 0x01c6, 0x0146, 0x01d6, 0x831f, 0x831e, 0x831e,
+ 0x9384, 0x003f, 0x20e0, 0x9384, 0xffc0, 0x9100, 0x2098, 0xa860,
+ 0x20e8, 0xa95c, 0x2c05, 0x9100, 0x20a0, 0x20a9, 0x0002, 0x4003,
+ 0x2e0c, 0x2d00, 0x0002, 0x8cf3, 0x8cf3, 0x8cf5, 0x8cf3, 0x8cf5,
+ 0x8cf3, 0x8cf3, 0x8cf3, 0x8cf3, 0x8cf3, 0x8cfb, 0x8cf3, 0x8cfb,
+ 0x8cf3, 0x8cf3, 0x8cf3, 0x080c, 0x0dc5, 0x4104, 0x20a9, 0x0002,
+ 0x4002, 0x4003, 0x0028, 0x20a9, 0x0002, 0x4003, 0x4104, 0x4003,
+ 0x01de, 0x014e, 0x01ce, 0x013e, 0x015e, 0x00ee, 0x002e, 0x001e,
+ 0x0005, 0x0096, 0x7014, 0x8001, 0x7016, 0x710c, 0x2110, 0x00f1,
+ 0x810c, 0x9188, 0x0003, 0x7308, 0x8210, 0x9282, 0x000a, 0x1198,
+ 0x7008, 0x2048, 0xa800, 0x9005, 0x0158, 0x0006, 0x080c, 0x8dc0,
+ 0x009e, 0xa807, 0x0000, 0x2900, 0x700a, 0x7010, 0x8001, 0x7012,
+ 0x700f, 0x0000, 0x0008, 0x720e, 0x009e, 0x0005, 0x0006, 0x810b,
+ 0x810b, 0x2100, 0x810b, 0x9100, 0x2008, 0x000e, 0x0005, 0x0006,
+ 0x0026, 0x2100, 0x9005, 0x0158, 0x9092, 0x000c, 0x0240, 0x900e,
+ 0x8108, 0x9082, 0x000c, 0x1de0, 0x002e, 0x000e, 0x0005, 0x900e,
+ 0x0cd8, 0x2d00, 0x90b8, 0x0008, 0x2031, 0x8d7a, 0x901e, 0x6808,
+ 0x9005, 0x0108, 0x8318, 0x690c, 0x910a, 0x0248, 0x0140, 0x8318,
+ 0x6810, 0x9112, 0x0220, 0x0118, 0x8318, 0x2208, 0x0cd0, 0x233a,
+ 0x6804, 0xd084, 0x2300, 0x2021, 0x0001, 0x1150, 0x9082, 0x0003,
+ 0x0967, 0x0a67, 0x8420, 0x9082, 0x0007, 0x0967, 0x0a67, 0x0cd0,
+ 0x9082, 0x0002, 0x0967, 0x0a67, 0x8420, 0x9082, 0x0005, 0x0967,
+ 0x0a67, 0x0cd0, 0x6c1a, 0x0005, 0x0096, 0x0046, 0x0126, 0x2091,
+ 0x8000, 0x2b00, 0x9080, 0x8df8, 0x2005, 0x9005, 0x090c, 0x0dc5,
+ 0x2004, 0x90a0, 0x000a, 0x080c, 0x1027, 0x01d0, 0x2900, 0x7026,
+ 0xa803, 0x0000, 0xa807, 0x0000, 0x080c, 0x1027, 0x0188, 0x7024,
+ 0xa802, 0xa807, 0x0000, 0x2900, 0x7026, 0x94a2, 0x000a, 0x0110,
+ 0x0208, 0x0c90, 0x9085, 0x0001, 0x012e, 0x004e, 0x009e, 0x0005,
+ 0x7024, 0x9005, 0x0dc8, 0x2048, 0xac00, 0x080c, 0x1040, 0x2400,
+ 0x0cc0, 0x0126, 0x2091, 0x8000, 0x7024, 0x2048, 0x9005, 0x0130,
+ 0xa800, 0x7026, 0xa803, 0x0000, 0xa807, 0x0000, 0x012e, 0x0005,
+ 0x0126, 0x2091, 0x8000, 0x7024, 0xa802, 0x2900, 0x7026, 0x012e,
+ 0x0005, 0x0096, 0x9e80, 0x0009, 0x2004, 0x9005, 0x0138, 0x2048,
+ 0xa800, 0x0006, 0x080c, 0x1040, 0x000e, 0x0cb8, 0x009e, 0x0005,
+ 0x0096, 0x7008, 0x9005, 0x0138, 0x2048, 0xa800, 0x0006, 0x080c,
+ 0x1040, 0x000e, 0x0cb8, 0x9006, 0x7002, 0x700a, 0x7006, 0x700e,
+ 0x701a, 0x701e, 0x7022, 0x702a, 0x7026, 0x702e, 0x009e, 0x0005,
+ 0x1a68, 0x0000, 0x0000, 0x0000, 0x1932, 0x0000, 0x0000, 0x0000,
+ 0x1888, 0x0000, 0x0000, 0x0000, 0x1877, 0x0000, 0x0000, 0x0000,
+ 0x00e6, 0x00c6, 0x00b6, 0x00a6, 0xa8a8, 0x2040, 0x2071, 0x1877,
+ 0x080c, 0x8f1c, 0xa067, 0x0023, 0x6010, 0x905d, 0x0904, 0x8ef1,
+ 0xb814, 0xa06e, 0xb910, 0xa172, 0xb9a0, 0xa176, 0x2001, 0x0003,
+ 0xa07e, 0xa834, 0xa082, 0xa07b, 0x0000, 0xa898, 0x9005, 0x0118,
+ 0xa078, 0xc085, 0xa07a, 0x2858, 0x2031, 0x0018, 0xa068, 0x908a,
+ 0x0019, 0x1a0c, 0x0dc5, 0x2020, 0x2050, 0x2940, 0xa864, 0x90bc,
+ 0x00ff, 0x908c, 0x000f, 0x91e0, 0x20f0, 0x2c65, 0x9786, 0x0024,
+ 0x2c05, 0x1590, 0x908a, 0x0036, 0x1a0c, 0x0dc5, 0x9082, 0x001b,
+ 0x0002, 0x8e5c, 0x8e5c, 0x8e5e, 0x8e5c, 0x8e5c, 0x8e5c, 0x8e60,
+ 0x8e5c, 0x8e5c, 0x8e5c, 0x8e62, 0x8e5c, 0x8e5c, 0x8e5c, 0x8e64,
+ 0x8e5c, 0x8e5c, 0x8e5c, 0x8e66, 0x8e5c, 0x8e5c, 0x8e5c, 0x8e68,
+ 0x8e5c, 0x8e5c, 0x8e5c, 0x8e6a, 0x080c, 0x0dc5, 0xa180, 0x04b8,
+ 0xa190, 0x04a8, 0xa1a0, 0x0498, 0xa1b0, 0x0488, 0xa1c0, 0x0478,
+ 0xa1d0, 0x0468, 0xa1e0, 0x0458, 0x908a, 0x0034, 0x1a0c, 0x0dc5,
+ 0x9082, 0x001b, 0x0002, 0x8e8e, 0x8e8c, 0x8e8c, 0x8e8c, 0x8e8c,
+ 0x8e8c, 0x8e90, 0x8e8c, 0x8e8c, 0x8e8c, 0x8e8c, 0x8e8c, 0x8e92,
+ 0x8e8c, 0x8e8c, 0x8e8c, 0x8e8c, 0x8e8c, 0x8e94, 0x8e8c, 0x8e8c,
+ 0x8e8c, 0x8e8c, 0x8e8c, 0x8e96, 0x080c, 0x0dc5, 0xa180, 0x0038,
+ 0xa198, 0x0028, 0xa1b0, 0x0018, 0xa1c8, 0x0008, 0xa1e0, 0x2600,
+ 0x0002, 0x8eb2, 0x8eb4, 0x8eb6, 0x8eb8, 0x8eba, 0x8ebc, 0x8ebe,
+ 0x8ec0, 0x8ec2, 0x8ec4, 0x8ec6, 0x8ec8, 0x8eca, 0x8ecc, 0x8ece,
+ 0x8ed0, 0x8ed2, 0x8ed4, 0x8ed6, 0x8ed8, 0x8eda, 0x8edc, 0x8ede,
+ 0x8ee0, 0x8ee2, 0x080c, 0x0dc5, 0xb9e2, 0x0468, 0xb9de, 0x0458,
+ 0xb9da, 0x0448, 0xb9d6, 0x0438, 0xb9d2, 0x0428, 0xb9ce, 0x0418,
+ 0xb9ca, 0x0408, 0xb9c6, 0x00f8, 0xb9c2, 0x00e8, 0xb9be, 0x00d8,
+ 0xb9ba, 0x00c8, 0xb9b6, 0x00b8, 0xb9b2, 0x00a8, 0xb9ae, 0x0098,
+ 0xb9aa, 0x0088, 0xb9a6, 0x0078, 0xb9a2, 0x0068, 0xb99e, 0x0058,
+ 0xb99a, 0x0048, 0xb996, 0x0038, 0xb992, 0x0028, 0xb98e, 0x0018,
+ 0xb98a, 0x0008, 0xb986, 0x8631, 0x8421, 0x0130, 0x080c, 0x20a8,
+ 0x090c, 0x0dc5, 0x0804, 0x8e36, 0x00ae, 0x00be, 0x00ce, 0x00ee,
+ 0x0005, 0xa86c, 0xa06e, 0xa870, 0xa072, 0xa077, 0x00ff, 0x9006,
+ 0x0804, 0x8e18, 0x0006, 0x0016, 0x00b6, 0x6010, 0x2058, 0xb810,
+ 0x9005, 0x01b0, 0x2001, 0x1926, 0x2004, 0x9005, 0x0188, 0x2001,
+ 0x1800, 0x2004, 0x9086, 0x0003, 0x1158, 0x0036, 0x0046, 0xbba0,
+ 0x2021, 0x0004, 0x2011, 0x8014, 0x080c, 0x4be9, 0x004e, 0x003e,
+ 0x00be, 0x001e, 0x000e, 0x0005, 0x9016, 0x710c, 0xa834, 0x910a,
+ 0xa936, 0x7008, 0x9005, 0x0120, 0x8210, 0x910a, 0x0238, 0x0130,
+ 0x7010, 0x8210, 0x910a, 0x0210, 0x0108, 0x0cd8, 0xaa8a, 0xa26a,
+ 0x0005, 0x00f6, 0x00d6, 0x0036, 0x2079, 0x0300, 0x781b, 0x0200,
+ 0x7818, 0xd094, 0x1dd8, 0x781b, 0x0202, 0xa001, 0xa001, 0x7818,
+ 0xd094, 0x1da0, 0xb8ac, 0x9005, 0x01b8, 0x2068, 0x2079, 0x0000,
+ 0x2c08, 0x911e, 0x1118, 0x680c, 0xb8ae, 0x0060, 0x9106, 0x0140,
+ 0x2d00, 0x2078, 0x680c, 0x9005, 0x090c, 0x0dc5, 0x2068, 0x0cb0,
+ 0x6b0c, 0x7b0e, 0x600f, 0x0000, 0x2079, 0x0300, 0x781b, 0x0200,
+ 0x003e, 0x00de, 0x00fe, 0x0005, 0x00e6, 0x00d6, 0x0096, 0x00c6,
+ 0x0036, 0x0126, 0x2091, 0x8000, 0x0156, 0x20a9, 0x01ff, 0x2071,
+ 0x0300, 0x701b, 0x0200, 0x7018, 0xd094, 0x0110, 0x1f04, 0x8f71,
+ 0x701b, 0x0202, 0xa001, 0xa001, 0x7018, 0xd094, 0x1d90, 0xb8ac,
+ 0x9005, 0x01e8, 0x2060, 0x600c, 0xb8ae, 0x6024, 0xc08d, 0x6026,
+ 0x6003, 0x0004, 0x601b, 0x0000, 0x6013, 0x0000, 0x601f, 0x0101,
+ 0x6014, 0x2048, 0xa88b, 0x0000, 0xa8a8, 0xa8ab, 0x0000, 0x904d,
+ 0x090c, 0x0dc5, 0x080c, 0x1040, 0x080c, 0x8b2d, 0x0c00, 0x2071,
+ 0x0300, 0x701b, 0x0200, 0x015e, 0x012e, 0x003e, 0x00ce, 0x009e,
+ 0x00de, 0x00ee, 0x0005, 0x00c6, 0x00b6, 0x0016, 0x0006, 0x0156,
+ 0x080c, 0x2894, 0x015e, 0x11b0, 0x080c, 0x66b2, 0x190c, 0x0dc5,
+ 0x000e, 0x001e, 0xb912, 0xb816, 0x080c, 0xb0ab, 0x0140, 0x2b00,
+ 0x6012, 0x6023, 0x0001, 0x2009, 0x0001, 0x080c, 0xb180, 0x00be,
+ 0x00ce, 0x0005, 0x000e, 0x001e, 0x0cd0, 0x0066, 0x6000, 0x90b2,
+ 0x0010, 0x1a0c, 0x0dc5, 0x0013, 0x006e, 0x0005, 0x8fe6, 0x8fe6,
+ 0x8fe6, 0x8fe8, 0x9039, 0x8fe6, 0x8fe6, 0x8fe6, 0x90a0, 0x8fe6,
+ 0x90dd, 0x8fe6, 0x8fe6, 0x8fe6, 0x8fe6, 0x8fe6, 0x080c, 0x0dc5,
+ 0x9182, 0x0040, 0x0002, 0x8ffb, 0x8ffb, 0x8ffb, 0x8ffb, 0x8ffb,
+ 0x8ffb, 0x8ffb, 0x8ffb, 0x8ffb, 0x8ffd, 0x9012, 0x8ffb, 0x8ffb,
+ 0x8ffb, 0x8ffb, 0x9025, 0x080c, 0x0dc5, 0x0096, 0x080c, 0x989d,
+ 0x080c, 0x9a0f, 0x6114, 0x2148, 0xa87b, 0x0000, 0x6010, 0x00b6,
+ 0x2058, 0xb8bb, 0x0500, 0x00be, 0x080c, 0x6bd5, 0x080c, 0xb101,
+ 0x009e, 0x0005, 0x080c, 0x989d, 0x00d6, 0x6114, 0x080c, 0xce56,
+ 0x0130, 0x0096, 0x6114, 0x2148, 0x080c, 0x6dd1, 0x009e, 0x00de,
+ 0x080c, 0xb101, 0x080c, 0x9a0f, 0x0005, 0x080c, 0x989d, 0x080c,
+ 0x3246, 0x6114, 0x0096, 0x2148, 0x080c, 0xce56, 0x0120, 0xa87b,
+ 0x0029, 0x080c, 0x6dd1, 0x009e, 0x080c, 0xb101, 0x080c, 0x9a0f,
+ 0x0005, 0x601b, 0x0000, 0x9182, 0x0040, 0x0096, 0x0002, 0x9054,
+ 0x9054, 0x9054, 0x9054, 0x9054, 0x9054, 0x9054, 0x9054, 0x9056,
+ 0x9054, 0x9054, 0x9054, 0x909c, 0x9054, 0x9054, 0x9054, 0x9054,
+ 0x9054, 0x9054, 0x905d, 0x9054, 0x080c, 0x0dc5, 0x6114, 0x2148,
+ 0xa938, 0x918e, 0xffff, 0x0904, 0x909c, 0x6024, 0xd08c, 0x15c0,
+ 0x00e6, 0x6114, 0x2148, 0x080c, 0x8e00, 0x0096, 0xa8a8, 0x2048,
+ 0x080c, 0x6b6d, 0x009e, 0xa8ab, 0x0000, 0x6010, 0x9005, 0x0128,
+ 0x00b6, 0x2058, 0x080c, 0x8f31, 0x00be, 0xae88, 0x00b6, 0x2059,
+ 0x0000, 0x080c, 0x8b36, 0x00be, 0x01e0, 0x2071, 0x193e, 0x080c,
+ 0x8b7d, 0x01b8, 0x9086, 0x0001, 0x1128, 0x2001, 0x1948, 0x2004,
+ 0x9005, 0x1178, 0x0096, 0x080c, 0x100e, 0x2900, 0x009e, 0x0148,
+ 0xa8aa, 0x00f6, 0x2c78, 0x080c, 0x8af4, 0x00fe, 0x00ee, 0x009e,
+ 0x0005, 0x080c, 0x8b2d, 0x0cd0, 0x080c, 0x914a, 0x009e, 0x0005,
+ 0x9182, 0x0040, 0x0096, 0x0002, 0x90b4, 0x90b4, 0x90b4, 0x90b6,
+ 0x90b4, 0x90b4, 0x90b4, 0x90db, 0x90b4, 0x90b4, 0x90b4, 0x90b4,
+ 0x90b4, 0x90b4, 0x90b4, 0x90b4, 0x080c, 0x0dc5, 0x6003, 0x0003,
+ 0x6106, 0x6014, 0x2048, 0xa8ac, 0xa846, 0xa8b0, 0xa84a, 0xa837,
+ 0x0000, 0xa83b, 0x0000, 0xa884, 0x9092, 0x199a, 0x0210, 0x2001,
+ 0x1999, 0x8003, 0x8013, 0x8213, 0x9210, 0x621a, 0x2c10, 0x080c,
+ 0x1c09, 0x080c, 0x93a0, 0x0126, 0x2091, 0x8000, 0x080c, 0x9a0f,
+ 0x012e, 0x009e, 0x0005, 0x080c, 0x0dc5, 0x080c, 0x989d, 0x080c,
+ 0x9a0f, 0x6114, 0x2148, 0xa87b, 0x0000, 0x6010, 0x00b6, 0x2058,
+ 0xb8bb, 0x0500, 0x00be, 0x080c, 0x6dd1, 0x080c, 0xb101, 0x009e,
+ 0x0005, 0x6000, 0x908a, 0x0010, 0x1a0c, 0x0dc5, 0x0096, 0x0013,
+ 0x009e, 0x0005, 0x910a, 0x910a, 0x910a, 0x910c, 0x911d, 0x910a,
+ 0x910a, 0x910a, 0x910a, 0x910a, 0x910a, 0x910a, 0x910a, 0x910a,
+ 0x910a, 0x910a, 0x080c, 0x0dc5, 0x080c, 0xaa59, 0x6114, 0x2148,
+ 0xa87b, 0x0006, 0x6010, 0x00b6, 0x2058, 0xb8bb, 0x0500, 0x00be,
+ 0x080c, 0x6dd1, 0x080c, 0xb101, 0x0005, 0x0461, 0x0005, 0x6000,
+ 0x908a, 0x0010, 0x1a0c, 0x0dc5, 0x0096, 0x0013, 0x009e, 0x0005,
+ 0x9138, 0x9138, 0x9138, 0x913a, 0x914a, 0x9138, 0x9138, 0x9138,
+ 0x9138, 0x9138, 0x9138, 0x9138, 0x9138, 0x9138, 0x9138, 0x9138,
+ 0x080c, 0x0dc5, 0x0036, 0x00e6, 0x2071, 0x19e9, 0x703c, 0x9c06,
+ 0x1120, 0x2019, 0x0000, 0x080c, 0xa877, 0x080c, 0xaa59, 0x00ee,
+ 0x003e, 0x0005, 0x6024, 0xd08c, 0x11f0, 0x00f6, 0x00e6, 0x601b,
+ 0x0000, 0x6014, 0x2048, 0x6010, 0x9005, 0x0128, 0x00b6, 0x2058,
+ 0x080c, 0x8f31, 0x00be, 0x2071, 0x193e, 0x080c, 0x8b7d, 0x0160,
+ 0x2001, 0x187f, 0x2004, 0xa88a, 0x2031, 0x0000, 0x2c78, 0x080c,
+ 0x8af4, 0x00ee, 0x00fe, 0x0005, 0x0096, 0xa88b, 0x0000, 0xa8a8,
+ 0x2048, 0x080c, 0x1040, 0x009e, 0xa8ab, 0x0000, 0x080c, 0x8b2d,
+ 0x0c80, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x187a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0126, 0x2091, 0x8000, 0x0036, 0x0046, 0x20a9, 0x0010,
+ 0x9006, 0x8004, 0x2019, 0x0100, 0x231c, 0x93a6, 0x0008, 0x1118,
+ 0x8086, 0x818e, 0x0020, 0x80f6, 0x3e00, 0x81f6, 0x3e08, 0x1208,
+ 0x9200, 0x1f04, 0x9192, 0x93a6, 0x0008, 0x1118, 0x8086, 0x818e,
+ 0x0020, 0x80f6, 0x3e00, 0x81f6, 0x3e08, 0x004e, 0x003e, 0x012e,
+ 0x0005, 0x0126, 0x2091, 0x8000, 0x0076, 0x0156, 0x20a9, 0x0010,
+ 0x9005, 0x0510, 0x911a, 0x1600, 0x8213, 0x2039, 0x0100, 0x273c,
+ 0x97be, 0x0008, 0x1110, 0x818d, 0x0010, 0x81f5, 0x3e08, 0x0228,
+ 0x911a, 0x1220, 0x1f04, 0x91bc, 0x0028, 0x911a, 0x2308, 0x8210,
+ 0x1f04, 0x91bc, 0x0006, 0x3200, 0x9084, 0xefff, 0x2080, 0x000e,
+ 0x015e, 0x007e, 0x012e, 0x0005, 0x0006, 0x3200, 0x9085, 0x1000,
+ 0x0ca8, 0x0126, 0x2091, 0x2800, 0x2079, 0x19e9, 0x012e, 0x00d6,
+ 0x2069, 0x19e9, 0x6803, 0x0005, 0x0156, 0x0146, 0x01d6, 0x20e9,
+ 0x0000, 0x2069, 0x0200, 0x080c, 0xadbc, 0x0401, 0x080c, 0xada7,
+ 0x00e9, 0x080c, 0xadaa, 0x00d1, 0x080c, 0xadad, 0x00b9, 0x080c,
+ 0xadb0, 0x00a1, 0x080c, 0xadb3, 0x0089, 0x080c, 0xadb6, 0x0071,
+ 0x080c, 0xadb9, 0x0059, 0x01de, 0x014e, 0x015e, 0x2069, 0x0004,
+ 0x2d04, 0x9085, 0x8001, 0x206a, 0x00de, 0x0005, 0x20a9, 0x0020,
+ 0x20a1, 0x0240, 0x2001, 0x0000, 0x4004, 0x0005, 0x00c6, 0x6027,
+ 0x0001, 0x7804, 0x9084, 0x0007, 0x0002, 0x922f, 0x9253, 0x9294,
+ 0x9235, 0x9253, 0x922f, 0x922d, 0x922d, 0x080c, 0x0dc5, 0x080c,
+ 0x878f, 0x080c, 0x98ed, 0x00ce, 0x0005, 0x62c0, 0x82ff, 0x1110,
+ 0x00ce, 0x0005, 0x2011, 0x5f90, 0x080c, 0x8709, 0x7828, 0x9092,
+ 0x00c8, 0x1228, 0x8000, 0x782a, 0x080c, 0x5fd0, 0x0c88, 0x62c0,
+ 0x080c, 0xaef8, 0x080c, 0x5f90, 0x7807, 0x0003, 0x7827, 0x0000,
+ 0x782b, 0x0000, 0x0c28, 0x080c, 0x878f, 0x6220, 0xd2a4, 0x0170,
+ 0xd2cc, 0x0160, 0x782b, 0x0000, 0x7824, 0x9065, 0x090c, 0x0dc5,
+ 0x2009, 0x0013, 0x080c, 0xb180, 0x00ce, 0x0005, 0x00c6, 0x7824,
+ 0x9065, 0x090c, 0x0dc5, 0x7828, 0x9092, 0xc350, 0x12c0, 0x8000,
+ 0x782a, 0x00ce, 0x080c, 0x2be7, 0x0278, 0x00c6, 0x7924, 0x2160,
+ 0x6010, 0x906d, 0x090c, 0x0dc5, 0x7807, 0x0000, 0x7827, 0x0000,
+ 0x00ce, 0x080c, 0x98ed, 0x0c00, 0x080c, 0xa4f3, 0x08e8, 0x2011,
+ 0x0130, 0x2214, 0x080c, 0xaef8, 0x080c, 0xee0f, 0x2009, 0x0014,
+ 0x080c, 0xb180, 0x00ce, 0x0880, 0x2001, 0x1a05, 0x2003, 0x0000,
+ 0x62c0, 0x82ff, 0x1160, 0x782b, 0x0000, 0x7824, 0x9065, 0x090c,
+ 0x0dc5, 0x2009, 0x0013, 0x080c, 0xb1d2, 0x00ce, 0x0005, 0x00b6,
+ 0x00c6, 0x00d6, 0x7824, 0x9005, 0x090c, 0x0dc5, 0x7828, 0x9092,
+ 0xc350, 0x1648, 0x8000, 0x782a, 0x00de, 0x00ce, 0x00be, 0x080c,
+ 0x2be7, 0x02f0, 0x00b6, 0x00c6, 0x00d6, 0x781c, 0x905d, 0x090c,
+ 0x0dc5, 0xb800, 0xc0dc, 0xb802, 0x7924, 0x2160, 0x080c, 0xb101,
+ 0xb93c, 0x81ff, 0x090c, 0x0dc5, 0x8109, 0xb93e, 0x7807, 0x0000,
+ 0x7827, 0x0000, 0x00de, 0x00ce, 0x00be, 0x080c, 0x98ed, 0x0868,
+ 0x080c, 0xa4f3, 0x0850, 0x2011, 0x0130, 0x2214, 0x080c, 0xaef8,
+ 0x080c, 0xee0f, 0x7824, 0x9065, 0x2009, 0x0014, 0x080c, 0xb180,
+ 0x00de, 0x00ce, 0x00be, 0x0804, 0x92a5, 0x00c6, 0x2001, 0x009b,
+ 0x2004, 0xd0fc, 0x190c, 0x1f14, 0x6024, 0x6027, 0x0002, 0xd0f4,
+ 0x15b8, 0x62c8, 0x60c4, 0x9205, 0x1170, 0x783c, 0x9065, 0x0130,
+ 0x2009, 0x0049, 0x080c, 0xb180, 0x00ce, 0x0005, 0x2011, 0x1a08,
+ 0x2013, 0x0000, 0x0cc8, 0x793c, 0x81ff, 0x0dc0, 0x7944, 0x9192,
+ 0x7530, 0x1628, 0x8108, 0x7946, 0x793c, 0x9188, 0x0008, 0x210c,
+ 0x918e, 0x0006, 0x1138, 0x6014, 0x9084, 0x1984, 0x9085, 0x0012,
+ 0x6016, 0x0c10, 0x793c, 0x9188, 0x0008, 0x210c, 0x918e, 0x0009,
+ 0x0d90, 0x6014, 0x9084, 0x1984, 0x9085, 0x0016, 0x6016, 0x08a0,
+ 0x793c, 0x2160, 0x2009, 0x004a, 0x080c, 0xb180, 0x0868, 0x7848,
+ 0xc085, 0x784a, 0x0848, 0x0006, 0x0016, 0x00c6, 0x0126, 0x2091,
+ 0x8000, 0x600f, 0x0000, 0x2c08, 0x2061, 0x19e9, 0x6020, 0x8000,
+ 0x6022, 0x6010, 0x9005, 0x0148, 0x9080, 0x0003, 0x2102, 0x6112,
+ 0x012e, 0x00ce, 0x001e, 0x000e, 0x0005, 0x6116, 0x6112, 0x0cc0,
+ 0x00d6, 0x2069, 0x19e9, 0xb800, 0xd0d4, 0x0168, 0x6820, 0x8000,
+ 0x6822, 0x9086, 0x0001, 0x1110, 0x2b00, 0x681e, 0x00de, 0x0804,
+ 0x98ed, 0x00de, 0x0005, 0xc0d5, 0xb802, 0x6818, 0x9005, 0x0168,
+ 0xb856, 0xb85b, 0x0000, 0x0086, 0x0006, 0x2b00, 0x681a, 0x008e,
+ 0xa05a, 0x008e, 0x2069, 0x19e9, 0x0c08, 0xb856, 0xb85a, 0x2b00,
+ 0x681a, 0x681e, 0x08d8, 0x0006, 0x0016, 0x00c6, 0x0126, 0x2091,
+ 0x8000, 0x600f, 0x0000, 0x2c08, 0x2061, 0x19e9, 0x6020, 0x8000,
+ 0x6022, 0x6008, 0x9005, 0x0148, 0x9080, 0x0003, 0x2102, 0x610a,
+ 0x012e, 0x00ce, 0x001e, 0x000e, 0x0005, 0x610e, 0x610a, 0x0cc0,
+ 0x00c6, 0x600f, 0x0000, 0x2c08, 0x2061, 0x19e9, 0x6034, 0x9005,
+ 0x0130, 0x9080, 0x0003, 0x2102, 0x6136, 0x00ce, 0x0005, 0x613a,
+ 0x6136, 0x00ce, 0x0005, 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x00b6,
+ 0x0096, 0x0076, 0x0066, 0x0056, 0x0036, 0x0026, 0x0016, 0x0006,
+ 0x0126, 0x902e, 0x2071, 0x19e9, 0x7638, 0x2660, 0x2678, 0x2091,
+ 0x8000, 0x8cff, 0x0904, 0x942f, 0x6010, 0x2058, 0xb8a0, 0x9206,
+ 0x1904, 0x942a, 0x87ff, 0x0120, 0x6054, 0x9106, 0x1904, 0x942a,
+ 0x703c, 0x9c06, 0x1178, 0x0036, 0x2019, 0x0001, 0x080c, 0xa877,
+ 0x7033, 0x0000, 0x9006, 0x703e, 0x7042, 0x7046, 0x704a, 0x003e,
+ 0x2029, 0x0001, 0x7038, 0x9c36, 0x1110, 0x660c, 0x763a, 0x7034,
+ 0x9c36, 0x1140, 0x2c00, 0x9f36, 0x0118, 0x2f00, 0x7036, 0x0010,
+ 0x7037, 0x0000, 0x660c, 0x0066, 0x2c00, 0x9f06, 0x0110, 0x7e0e,
+ 0x0008, 0x2678, 0x600f, 0x0000, 0x080c, 0xce56, 0x01f0, 0x6014,
+ 0x2048, 0x6020, 0x9086, 0x0003, 0x15b8, 0x6004, 0x9086, 0x0040,
+ 0x090c, 0xaa49, 0xa867, 0x0103, 0xab7a, 0xa877, 0x0000, 0x0016,
+ 0x0036, 0x0076, 0x080c, 0xd14c, 0x080c, 0xed00, 0x080c, 0x6dd1,
+ 0x007e, 0x003e, 0x001e, 0x080c, 0xd041, 0x080c, 0xb134, 0x00ce,
+ 0x0804, 0x93c9, 0x2c78, 0x600c, 0x2060, 0x0804, 0x93c9, 0x85ff,
+ 0x0120, 0x0036, 0x080c, 0x9a0f, 0x003e, 0x012e, 0x000e, 0x001e,
+ 0x002e, 0x003e, 0x005e, 0x006e, 0x007e, 0x009e, 0x00be, 0x00ce,
+ 0x00de, 0x00ee, 0x00fe, 0x0005, 0x6020, 0x9086, 0x0006, 0x1158,
+ 0x0016, 0x0036, 0x0076, 0x080c, 0xed00, 0x080c, 0xe948, 0x007e,
+ 0x003e, 0x001e, 0x0890, 0x6020, 0x9086, 0x0009, 0x1168, 0xa87b,
+ 0x0006, 0x0016, 0x0036, 0x0076, 0x080c, 0x6dd1, 0x080c, 0xb101,
+ 0x007e, 0x003e, 0x001e, 0x0818, 0x6020, 0x9086, 0x000a, 0x0904,
+ 0x9414, 0x0804, 0x940d, 0x0006, 0x0066, 0x0096, 0x00c6, 0x00d6,
+ 0x00f6, 0x9036, 0x0126, 0x2091, 0x8000, 0x2079, 0x19e9, 0x7838,
+ 0x9065, 0x0904, 0x94c0, 0x600c, 0x0006, 0x600f, 0x0000, 0x783c,
+ 0x9c06, 0x1168, 0x0036, 0x2019, 0x0001, 0x080c, 0xa877, 0x7833,
+ 0x0000, 0x901e, 0x7b3e, 0x7b42, 0x7b46, 0x7b4a, 0x003e, 0x080c,
+ 0xce56, 0x0548, 0x6014, 0x2048, 0x6020, 0x9086, 0x0003, 0x1590,
+ 0x3e08, 0x918e, 0x0002, 0x1188, 0x6010, 0x9005, 0x0170, 0x00b6,
+ 0x2058, 0xb800, 0x00be, 0xd0bc, 0x0140, 0x6040, 0x9005, 0x11a8,
+ 0x2001, 0x1989, 0x2004, 0x6042, 0x0080, 0x6004, 0x9086, 0x0040,
+ 0x090c, 0xaa49, 0xa867, 0x0103, 0xab7a, 0xa877, 0x0000, 0x080c,
+ 0x6dc4, 0x080c, 0xd041, 0x080c, 0xb134, 0x000e, 0x0804, 0x9478,
+ 0x7e3a, 0x7e36, 0x012e, 0x00fe, 0x00de, 0x00ce, 0x009e, 0x006e,
+ 0x000e, 0x0005, 0x6020, 0x9086, 0x0006, 0x1118, 0x080c, 0xe948,
+ 0x0c50, 0x6020, 0x9086, 0x0009, 0x1130, 0xab7a, 0x080c, 0x6dd1,
+ 0x080c, 0xb101, 0x0c10, 0x6020, 0x9086, 0x000a, 0x09a8, 0x0868,
+ 0x0016, 0x0026, 0x0086, 0x9046, 0x0099, 0x080c, 0x95cb, 0x008e,
+ 0x002e, 0x001e, 0x0005, 0x00f6, 0x0126, 0x2079, 0x19e9, 0x2091,
+ 0x8000, 0x080c, 0x9662, 0x080c, 0x96f2, 0x012e, 0x00fe, 0x0005,
+ 0x00b6, 0x0096, 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x0066, 0x0016,
+ 0x0006, 0x0126, 0x2091, 0x8000, 0x2071, 0x19e9, 0x7614, 0x2660,
+ 0x2678, 0x8cff, 0x0904, 0x9590, 0x6010, 0x2058, 0xb8a0, 0x9206,
+ 0x1904, 0x958b, 0x88ff, 0x0120, 0x6054, 0x9106, 0x1904, 0x958b,
+ 0x7024, 0x9c06, 0x1568, 0x2069, 0x0100, 0x6820, 0xd0a4, 0x0110,
+ 0xd0cc, 0x1508, 0x080c, 0x878f, 0x080c, 0xa517, 0x68c3, 0x0000,
+ 0x080c, 0xaa49, 0x7027, 0x0000, 0x0036, 0x2069, 0x0140, 0x6b04,
+ 0x9384, 0x1000, 0x0138, 0x2001, 0x0100, 0x080c, 0x2d52, 0x9006,
+ 0x080c, 0x2d52, 0x2069, 0x0100, 0x6824, 0xd084, 0x0110, 0x6827,
+ 0x0001, 0x003e, 0x0028, 0x6003, 0x0009, 0x630a, 0x0804, 0x958b,
+ 0x7014, 0x9c36, 0x1110, 0x660c, 0x7616, 0x7010, 0x9c36, 0x1140,
+ 0x2c00, 0x9f36, 0x0118, 0x2f00, 0x7012, 0x0010, 0x7013, 0x0000,
+ 0x660c, 0x0066, 0x2c00, 0x9f06, 0x0110, 0x7e0e, 0x0008, 0x2678,
+ 0x600f, 0x0000, 0x6014, 0x2048, 0x080c, 0xce56, 0x01e8, 0x6020,
+ 0x9086, 0x0003, 0x1580, 0x080c, 0xd05e, 0x1118, 0x080c, 0xbae2,
+ 0x0098, 0xa867, 0x0103, 0xab7a, 0xa877, 0x0000, 0x0016, 0x0036,
+ 0x0086, 0x080c, 0xd14c, 0x080c, 0xed00, 0x080c, 0x6dd1, 0x008e,
+ 0x003e, 0x001e, 0x080c, 0xd041, 0x080c, 0xb134, 0x080c, 0xa91f,
+ 0x00ce, 0x0804, 0x9509, 0x2c78, 0x600c, 0x2060, 0x0804, 0x9509,
+ 0x012e, 0x000e, 0x001e, 0x006e, 0x00ce, 0x00de, 0x00ee, 0x00fe,
+ 0x009e, 0x00be, 0x0005, 0x6020, 0x9086, 0x0006, 0x1158, 0x0016,
+ 0x0036, 0x0086, 0x080c, 0xed00, 0x080c, 0xe948, 0x008e, 0x003e,
+ 0x001e, 0x08d0, 0x080c, 0xbae2, 0x6020, 0x9086, 0x0002, 0x1160,
+ 0x6004, 0x0006, 0x9086, 0x0085, 0x000e, 0x0904, 0x9571, 0x9086,
+ 0x008b, 0x0904, 0x9571, 0x0840, 0x6020, 0x9086, 0x0005, 0x1920,
+ 0x6004, 0x0006, 0x9086, 0x0085, 0x000e, 0x09c8, 0x9086, 0x008b,
+ 0x09b0, 0x0804, 0x9584, 0x00b6, 0x00a6, 0x0096, 0x00c6, 0x0006,
+ 0x0126, 0x2091, 0x8000, 0x9280, 0x1000, 0x2004, 0x905d, 0x0904,
+ 0x965b, 0x00f6, 0x00e6, 0x00d6, 0x0066, 0x2071, 0x19e9, 0xbe54,
+ 0x7018, 0x9b06, 0x1108, 0x761a, 0x701c, 0x9b06, 0x1130, 0x86ff,
+ 0x1118, 0x7018, 0x701e, 0x0008, 0x761e, 0xb858, 0x904d, 0x0108,
+ 0xae56, 0x96d5, 0x0000, 0x0110, 0x2900, 0xb05a, 0xb857, 0x0000,
+ 0xb85b, 0x0000, 0xb800, 0xc0d4, 0xc0dc, 0xb802, 0x080c, 0x6645,
+ 0x0904, 0x9657, 0x7624, 0x86ff, 0x0904, 0x9646, 0x9680, 0x0005,
+ 0x2004, 0x9906, 0x15d8, 0x00d6, 0x2069, 0x0100, 0x68c0, 0x9005,
+ 0x0560, 0x080c, 0x878f, 0x080c, 0xa517, 0x68c3, 0x0000, 0x080c,
+ 0xaa49, 0x7027, 0x0000, 0x0036, 0x2069, 0x0140, 0x6b04, 0x9384,
+ 0x1000, 0x0138, 0x2001, 0x0100, 0x080c, 0x2d52, 0x9006, 0x080c,
+ 0x2d52, 0x2069, 0x0100, 0x6824, 0xd084, 0x0110, 0x6827, 0x0001,
+ 0x003e, 0x00de, 0x00c6, 0xb83c, 0x9005, 0x0110, 0x8001, 0xb83e,
+ 0x2660, 0x080c, 0xb134, 0x00ce, 0x0048, 0x00de, 0x00c6, 0x2660,
+ 0x6003, 0x0009, 0x630a, 0x00ce, 0x0804, 0x95fe, 0x89ff, 0x0158,
+ 0xa867, 0x0103, 0xab7a, 0xa877, 0x0000, 0x080c, 0xd14c, 0x080c,
+ 0xed00, 0x080c, 0x6dd1, 0x080c, 0xa91f, 0x0804, 0x95fe, 0x006e,
+ 0x00de, 0x00ee, 0x00fe, 0x012e, 0x000e, 0x00ce, 0x009e, 0x00ae,
+ 0x00be, 0x0005, 0x0096, 0x0006, 0x0066, 0x00c6, 0x00d6, 0x9036,
+ 0x7814, 0x9065, 0x0904, 0x96c5, 0x600c, 0x0006, 0x600f, 0x0000,
+ 0x7824, 0x9c06, 0x1580, 0x2069, 0x0100, 0x6820, 0xd0a4, 0x0110,
+ 0xd0cc, 0x1508, 0x080c, 0x878f, 0x080c, 0xa517, 0x68c3, 0x0000,
+ 0x080c, 0xaa49, 0x7827, 0x0000, 0x0036, 0x2069, 0x0140, 0x6b04,
+ 0x9384, 0x1000, 0x0138, 0x2001, 0x0100, 0x080c, 0x2d52, 0x9006,
+ 0x080c, 0x2d52, 0x2069, 0x0100, 0x6824, 0xd084, 0x0110, 0x6827,
+ 0x0001, 0x003e, 0x0040, 0x080c, 0x6a2a, 0x1520, 0x6003, 0x0009,
+ 0x630a, 0x2c30, 0x00f8, 0x6014, 0x2048, 0x080c, 0xce54, 0x01b0,
+ 0x6020, 0x9086, 0x0003, 0x1508, 0x080c, 0xd05e, 0x1118, 0x080c,
+ 0xbae2, 0x0060, 0x080c, 0x6a2a, 0x1168, 0xa867, 0x0103, 0xab7a,
+ 0xa877, 0x0000, 0x080c, 0x6dd1, 0x080c, 0xd041, 0x080c, 0xb134,
+ 0x080c, 0xa91f, 0x000e, 0x0804, 0x9669, 0x7e16, 0x7e12, 0x00de,
+ 0x00ce, 0x006e, 0x000e, 0x009e, 0x0005, 0x6020, 0x9086, 0x0006,
+ 0x1118, 0x080c, 0xe948, 0x0c50, 0x080c, 0xbae2, 0x6020, 0x9086,
+ 0x0002, 0x1150, 0x6004, 0x0006, 0x9086, 0x0085, 0x000e, 0x0990,
+ 0x9086, 0x008b, 0x0978, 0x08d0, 0x6020, 0x9086, 0x0005, 0x19b0,
+ 0x6004, 0x0006, 0x9086, 0x0085, 0x000e, 0x0d18, 0x9086, 0x008b,
+ 0x0d00, 0x0860, 0x0006, 0x0066, 0x0096, 0x00b6, 0x00c6, 0x00d6,
+ 0x7818, 0x905d, 0x0904, 0x9772, 0xb854, 0x0006, 0x9006, 0xb856,
+ 0xb85a, 0xb800, 0xc0d4, 0xc0dc, 0xb802, 0x080c, 0x6645, 0x0904,
+ 0x976f, 0x7e24, 0x86ff, 0x0904, 0x9762, 0x9680, 0x0005, 0x2004,
+ 0x9906, 0x1904, 0x9762, 0x00d6, 0x2069, 0x0100, 0x68c0, 0x9005,
+ 0x0904, 0x9759, 0x080c, 0x878f, 0x080c, 0xa517, 0x68c3, 0x0000,
+ 0x080c, 0xaa49, 0x7827, 0x0000, 0x0036, 0x2069, 0x0140, 0x6b04,
+ 0x9384, 0x1000, 0x0138, 0x2001, 0x0100, 0x080c, 0x2d52, 0x9006,
+ 0x080c, 0x2d52, 0x2069, 0x0100, 0x6824, 0xd084, 0x0110, 0x6827,
+ 0x0001, 0x003e, 0x00de, 0x00c6, 0x3e08, 0x918e, 0x0002, 0x1168,
+ 0xb800, 0xd0bc, 0x0150, 0x9680, 0x0010, 0x200c, 0x81ff, 0x1518,
+ 0x2009, 0x1989, 0x210c, 0x2102, 0x00f0, 0xb83c, 0x9005, 0x0110,
+ 0x8001, 0xb83e, 0x2660, 0x600f, 0x0000, 0x080c, 0xb134, 0x00ce,
+ 0x0048, 0x00de, 0x00c6, 0x2660, 0x6003, 0x0009, 0x630a, 0x00ce,
+ 0x0804, 0x9705, 0x89ff, 0x0138, 0xa867, 0x0103, 0xab7a, 0xa877,
+ 0x0000, 0x080c, 0x6dd1, 0x080c, 0xa91f, 0x0804, 0x9705, 0x000e,
+ 0x0804, 0x96f9, 0x781e, 0x781a, 0x00de, 0x00ce, 0x00be, 0x009e,
+ 0x006e, 0x000e, 0x0005, 0x00e6, 0x00d6, 0x0096, 0x0066, 0xb800,
+ 0xd0dc, 0x01a0, 0xb84c, 0x904d, 0x0188, 0xa878, 0x9606, 0x1170,
+ 0x2071, 0x19e9, 0x7024, 0x9035, 0x0148, 0x9080, 0x0005, 0x2004,
+ 0x9906, 0x1120, 0xb800, 0xc0dc, 0xb802, 0x0029, 0x006e, 0x009e,
+ 0x00de, 0x00ee, 0x0005, 0x00f6, 0x2079, 0x0100, 0x78c0, 0x9005,
+ 0x1138, 0x00c6, 0x2660, 0x6003, 0x0009, 0x630a, 0x00ce, 0x04b8,
+ 0x080c, 0xa517, 0x78c3, 0x0000, 0x080c, 0xaa49, 0x7027, 0x0000,
+ 0x0036, 0x2079, 0x0140, 0x7b04, 0x9384, 0x1000, 0x0138, 0x2001,
+ 0x0100, 0x080c, 0x2d52, 0x9006, 0x080c, 0x2d52, 0x2079, 0x0100,
+ 0x7824, 0xd084, 0x0110, 0x7827, 0x0001, 0x080c, 0xaa49, 0x003e,
+ 0x080c, 0x6645, 0x00c6, 0xb83c, 0x9005, 0x0110, 0x8001, 0xb83e,
+ 0x2660, 0x080c, 0xb101, 0x00ce, 0xa867, 0x0103, 0xab7a, 0xa877,
+ 0x0000, 0x080c, 0xd14c, 0x080c, 0x6dd1, 0x080c, 0xa91f, 0x00fe,
+ 0x0005, 0x00b6, 0x00e6, 0x00c6, 0x2011, 0x0101, 0x2204, 0xc0c4,
+ 0x2012, 0x2001, 0x180c, 0x2014, 0xc2e4, 0x2202, 0x2071, 0x19e9,
+ 0x7004, 0x9084, 0x0007, 0x0002, 0x97fe, 0x9802, 0x9820, 0x9849,
+ 0x9887, 0x97fe, 0x9819, 0x97fc, 0x080c, 0x0dc5, 0x00ce, 0x00ee,
+ 0x00be, 0x0005, 0x7024, 0x9065, 0x0148, 0x7020, 0x8001, 0x7022,
+ 0x600c, 0x9015, 0x0158, 0x7216, 0x600f, 0x0000, 0x7007, 0x0000,
+ 0x7027, 0x0000, 0x00ce, 0x00ee, 0x00be, 0x0005, 0x7216, 0x7212,
+ 0x0ca8, 0x7007, 0x0000, 0x7027, 0x0000, 0x7020, 0x9005, 0x0070,
+ 0x6010, 0x2058, 0x080c, 0x6645, 0xb800, 0xc0dc, 0xb802, 0x7007,
+ 0x0000, 0x7027, 0x0000, 0x7020, 0x8001, 0x7022, 0x1148, 0x2001,
+ 0x180c, 0x2014, 0xd2ec, 0x1180, 0x00ce, 0x00ee, 0x00be, 0x0005,
+ 0xb854, 0x9015, 0x0120, 0x721e, 0x080c, 0x98ed, 0x0ca8, 0x7218,
+ 0x721e, 0x080c, 0x98ed, 0x0c80, 0xc2ec, 0x2202, 0x080c, 0x9a0f,
+ 0x0c58, 0x7024, 0x9065, 0x05b8, 0x700c, 0x9c06, 0x1160, 0x080c,
+ 0xa91f, 0x600c, 0x9015, 0x0120, 0x720e, 0x600f, 0x0000, 0x0448,
+ 0x720e, 0x720a, 0x0430, 0x7014, 0x9c06, 0x1160, 0x080c, 0xa91f,
+ 0x600c, 0x9015, 0x0120, 0x7216, 0x600f, 0x0000, 0x00d0, 0x7216,
+ 0x7212, 0x00b8, 0x6020, 0x9086, 0x0003, 0x1198, 0x6010, 0x2058,
+ 0x080c, 0x6645, 0xb800, 0xc0dc, 0xb802, 0x080c, 0xa91f, 0x701c,
+ 0x9065, 0x0138, 0xb854, 0x9015, 0x0110, 0x721e, 0x0010, 0x7218,
+ 0x721e, 0x7027, 0x0000, 0x00ce, 0x00ee, 0x00be, 0x0005, 0x7024,
+ 0x9065, 0x0140, 0x080c, 0xa91f, 0x600c, 0x9015, 0x0158, 0x720e,
+ 0x600f, 0x0000, 0x080c, 0xaa49, 0x7027, 0x0000, 0x00ce, 0x00ee,
+ 0x00be, 0x0005, 0x720e, 0x720a, 0x0ca8, 0x00d6, 0x2069, 0x19e9,
+ 0x6830, 0x9084, 0x0003, 0x0002, 0x98aa, 0x98ac, 0x98d0, 0x98a8,
+ 0x080c, 0x0dc5, 0x00de, 0x0005, 0x00c6, 0x6840, 0x9086, 0x0001,
+ 0x01b8, 0x683c, 0x9065, 0x0130, 0x600c, 0x9015, 0x0170, 0x6a3a,
+ 0x600f, 0x0000, 0x6833, 0x0000, 0x683f, 0x0000, 0x2011, 0x1a08,
+ 0x2013, 0x0000, 0x00ce, 0x00de, 0x0005, 0x683a, 0x6836, 0x0c90,
+ 0x6843, 0x0000, 0x6838, 0x9065, 0x0d68, 0x6003, 0x0003, 0x0c50,
+ 0x00c6, 0x9006, 0x6842, 0x6846, 0x684a, 0x683c, 0x9065, 0x0160,
+ 0x600c, 0x9015, 0x0130, 0x6a3a, 0x600f, 0x0000, 0x683f, 0x0000,
+ 0x0018, 0x683e, 0x683a, 0x6836, 0x00ce, 0x00de, 0x0005, 0x2001,
+ 0x180c, 0x200c, 0xc1e5, 0x2102, 0x0005, 0x2001, 0x180c, 0x200c,
+ 0xd1ec, 0x0120, 0xc1ec, 0x2102, 0x080c, 0x9a0f, 0x2001, 0x19f5,
+ 0x2004, 0x9086, 0x0001, 0x0d58, 0x00d6, 0x2069, 0x19e9, 0x6804,
+ 0x9084, 0x0007, 0x0006, 0x9005, 0x11c8, 0x2001, 0x1837, 0x2004,
+ 0x9084, 0x0028, 0x1198, 0x2001, 0x197d, 0x2004, 0x9086, 0xaaaa,
+ 0x0168, 0x2001, 0x188b, 0x2004, 0xd08c, 0x1118, 0xd084, 0x1118,
+ 0x0028, 0x080c, 0x9a0f, 0x000e, 0x00de, 0x0005, 0x000e, 0x0002,
+ 0x992a, 0x99e3, 0x99e3, 0x99e3, 0x99e3, 0x99e5, 0x99e3, 0x9928,
+ 0x080c, 0x0dc5, 0x6820, 0x9005, 0x1110, 0x00de, 0x0005, 0x00c6,
+ 0x680c, 0x9065, 0x01f0, 0x6104, 0x918e, 0x0040, 0x1180, 0x2009,
+ 0x1837, 0x210c, 0x918c, 0x0028, 0x1150, 0x080c, 0x7569, 0x0138,
0x0006, 0x2009, 0x188b, 0x2104, 0xc095, 0x200a, 0x000e, 0x6807,
- 0x0004, 0x6826, 0x682b, 0x0000, 0x080c, 0x9ab2, 0x00ce, 0x00de,
- 0x0005, 0x2001, 0x180c, 0x2014, 0xc2ed, 0x2202, 0x00de, 0x00fe,
- 0x0005, 0x00f6, 0x00d6, 0x2069, 0x19e9, 0x6830, 0x9086, 0x0000,
- 0x1570, 0x2001, 0x180c, 0x2014, 0xd2e4, 0x0130, 0xc2e4, 0x2202,
- 0x080c, 0x98f6, 0x2069, 0x19e9, 0x2001, 0x180c, 0x200c, 0xd1c4,
- 0x1508, 0x6838, 0x907d, 0x01d8, 0x6a04, 0x9296, 0x0000, 0x1904,
- 0x9aa6, 0x7920, 0x918e, 0x0009, 0x0568, 0x6833, 0x0001, 0x683e,
- 0x6847, 0x0000, 0x684b, 0x0000, 0x0126, 0x00f6, 0x2091, 0x2400,
- 0x002e, 0x080c, 0x1c9a, 0x1158, 0x012e, 0x080c, 0xa35a, 0x00de,
- 0x00fe, 0x0005, 0xc1c4, 0x2102, 0x080c, 0x7610, 0x08d0, 0x012e,
- 0x6843, 0x0000, 0x7803, 0x0002, 0x780c, 0x9015, 0x0140, 0x6a3a,
- 0x780f, 0x0000, 0x6833, 0x0000, 0x683f, 0x0000, 0x0c40, 0x683a,
- 0x6836, 0x0cc0, 0x7908, 0xd1fc, 0x1198, 0x6833, 0x0001, 0x683e,
- 0x6847, 0x0000, 0x684b, 0x0000, 0x0126, 0x00f6, 0x2091, 0x2400,
- 0x002e, 0x080c, 0x1c9a, 0x19d8, 0x012e, 0x080c, 0xa2db, 0x0878,
- 0x2001, 0x1837, 0x2004, 0x9084, 0x0028, 0x1188, 0x2001, 0x197d,
- 0x2004, 0x9086, 0xaaaa, 0x0158, 0x2001, 0x19ea, 0x2004, 0x9005,
- 0x11f0, 0x2001, 0x188b, 0x200c, 0xc185, 0xc18c, 0x2102, 0x2f00,
- 0x6833, 0x0001, 0x683e, 0x6847, 0x0000, 0x684b, 0x0000, 0x0126,
- 0x00f6, 0x2091, 0x2400, 0x002e, 0x080c, 0x1c9a, 0x1904, 0x9a47,
- 0x012e, 0x6a3c, 0x2278, 0x080c, 0xa265, 0x0804, 0x9a3f, 0x2011,
- 0x188b, 0x2204, 0xc08d, 0x2012, 0x0804, 0x9a3f, 0x6a04, 0x9296,
- 0x0006, 0x1904, 0x9a01, 0x6a30, 0x9296, 0x0000, 0x0904, 0x9a29,
- 0x0804, 0x9a01, 0x6020, 0x9084, 0x000f, 0x000b, 0x0005, 0x9ac6,
- 0x9acb, 0x9f5d, 0x9ff6, 0x9acb, 0x9f5d, 0x9ff6, 0x9ac6, 0x9acb,
- 0x9ac6, 0x9ac6, 0x9ac6, 0x9ac6, 0x9ac6, 0x9ac6, 0x080c, 0x97db,
- 0x080c, 0x98e7, 0x0005, 0x00b6, 0x0156, 0x0136, 0x0146, 0x01c6,
- 0x01d6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x2069, 0x0200, 0x2071,
- 0x0240, 0x6004, 0x908a, 0x0053, 0x1a0c, 0x0dc5, 0x6110, 0x2158,
- 0xb9c0, 0x2c78, 0x2061, 0x0100, 0x619a, 0x908a, 0x0040, 0x1a04,
- 0x9b37, 0x005b, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x01de, 0x01ce,
- 0x014e, 0x013e, 0x015e, 0x00be, 0x0005, 0x9ce0, 0x9d1b, 0x9d44,
- 0x9dec, 0x9e0e, 0x9e14, 0x9e21, 0x9e29, 0x9e35, 0x9e3b, 0x9e4c,
- 0x9e3b, 0x9ea4, 0x9e29, 0x9eb0, 0x9eb6, 0x9e35, 0x9eb6, 0x9ec2,
- 0x9b35, 0x9b35, 0x9b35, 0x9b35, 0x9b35, 0x9b35, 0x9b35, 0x9b35,
- 0x9b35, 0x9b35, 0x9b35, 0xa714, 0xa737, 0xa748, 0xa768, 0xa79a,
- 0x9e21, 0x9b35, 0x9e21, 0x9e3b, 0x9b35, 0x9d44, 0x9dec, 0x9b35,
- 0xab26, 0x9e3b, 0x9b35, 0xab42, 0x9e3b, 0x9b35, 0x9e35, 0x9cda,
- 0x9b58, 0x9b35, 0xab5e, 0xabcb, 0xaca6, 0x9b35, 0xacb3, 0x9e1e,
- 0xacde, 0x9b35, 0xa7a4, 0xad0b, 0x9b35, 0x080c, 0x0dc5, 0x2100,
- 0x005b, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x01de, 0x01ce, 0x014e,
- 0x013e, 0x015e, 0x00be, 0x0005, 0xada6, 0xae58, 0x9b56, 0x9b90,
- 0x9c3c, 0x9c47, 0x9b56, 0x9e21, 0x9b56, 0x9ca1, 0x9cad, 0x9bab,
- 0x9b56, 0x9bc6, 0x9bfa, 0xafc5, 0xb00a, 0x9e3b, 0x080c, 0x0dc5,
- 0x00d6, 0x0096, 0x080c, 0x9ed5, 0x0026, 0x0036, 0x7814, 0x2048,
- 0xa958, 0xd1cc, 0x1138, 0x2009, 0x2414, 0x2011, 0x0018, 0x2019,
- 0x0018, 0x0030, 0x2009, 0x2410, 0x2011, 0x0014, 0x2019, 0x0014,
- 0x7102, 0x7206, 0x700b, 0x0800, 0xa83c, 0x700e, 0xa850, 0x7022,
- 0xa854, 0x7026, 0x63c2, 0x080c, 0xa4d1, 0x003e, 0x002e, 0x009e,
- 0x00de, 0x0005, 0x7810, 0x00b6, 0x2058, 0xb8a0, 0x00be, 0x080c,
- 0xb051, 0x1118, 0x9084, 0xff80, 0x0110, 0x9085, 0x0001, 0x0005,
- 0x00d6, 0x0096, 0x080c, 0x9ed5, 0x7003, 0x0500, 0x7814, 0x2048,
- 0xa874, 0x700a, 0xa878, 0x700e, 0xa87c, 0x7012, 0xa880, 0x7016,
- 0xa884, 0x701a, 0xa888, 0x701e, 0x60c3, 0x0010, 0x080c, 0xa4d1,
- 0x009e, 0x00de, 0x0005, 0x00d6, 0x0096, 0x080c, 0x9ed5, 0x7003,
- 0x0500, 0x7814, 0x2048, 0xa8cc, 0x700a, 0xa8d0, 0x700e, 0xa8d4,
- 0x7012, 0xa8d8, 0x7016, 0xa8dc, 0x701a, 0xa8e0, 0x701e, 0x60c3,
- 0x0010, 0x080c, 0xa4d1, 0x009e, 0x00de, 0x0005, 0x00d6, 0x0096,
- 0x0126, 0x2091, 0x8000, 0x080c, 0x9ed5, 0x20e9, 0x0000, 0x2001,
- 0x19a4, 0x2003, 0x0000, 0x7814, 0x2048, 0xa814, 0x8003, 0x60c2,
- 0xa830, 0x20a8, 0xa860, 0x20e0, 0xa85c, 0x9080, 0x001b, 0x2098,
- 0x2001, 0x19a4, 0x0016, 0x200c, 0x2001, 0x0001, 0x080c, 0x240f,
- 0x080c, 0xdbe1, 0x9006, 0x080c, 0x240f, 0x001e, 0xa804, 0x9005,
- 0x0110, 0x2048, 0x0c28, 0x04d9, 0x080c, 0xa4d1, 0x012e, 0x009e,
- 0x00de, 0x0005, 0x00d6, 0x0096, 0x0126, 0x2091, 0x8000, 0x080c,
- 0x9f20, 0x20e9, 0x0000, 0x2001, 0x19a4, 0x2003, 0x0000, 0x7814,
- 0x2048, 0xa86f, 0x0200, 0xa873, 0x0000, 0xa814, 0x8003, 0x60c2,
- 0xa830, 0x20a8, 0xa860, 0x20e0, 0xa85c, 0x9080, 0x001b, 0x2098,
- 0x2001, 0x19a4, 0x0016, 0x200c, 0x080c, 0xdbe1, 0x001e, 0xa804,
- 0x9005, 0x0110, 0x2048, 0x0c60, 0x0051, 0x7814, 0x2048, 0x080c,
- 0x0fc0, 0x080c, 0xa4d1, 0x012e, 0x009e, 0x00de, 0x0005, 0x60c0,
- 0x8004, 0x9084, 0x0003, 0x9005, 0x0130, 0x9082, 0x0004, 0x20a3,
- 0x0000, 0x8000, 0x1de0, 0x0005, 0x080c, 0x9ed5, 0x7003, 0x7800,
- 0x7808, 0x8007, 0x700a, 0x60c3, 0x0008, 0x0804, 0xa4d1, 0x00d6,
- 0x00e6, 0x080c, 0x9f20, 0x7814, 0x9084, 0xff00, 0x2073, 0x0200,
- 0x8e70, 0x8e70, 0x9096, 0xdf00, 0x0138, 0x9096, 0xe000, 0x0120,
- 0x2073, 0x0010, 0x8e70, 0x0030, 0x9095, 0x0010, 0x2272, 0x8e70,
- 0x2073, 0x0034, 0x8e70, 0x2069, 0x1805, 0x20a9, 0x0004, 0x2d76,
- 0x8d68, 0x8e70, 0x1f04, 0x9c67, 0x2069, 0x1801, 0x20a9, 0x0004,
- 0x2d76, 0x8d68, 0x8e70, 0x1f04, 0x9c70, 0x9096, 0xdf00, 0x0130,
- 0x9096, 0xe000, 0x0118, 0x60c3, 0x0018, 0x00f0, 0x2069, 0x19b5,
- 0x9086, 0xdf00, 0x0110, 0x2069, 0x19cf, 0x20a9, 0x001a, 0x9e86,
- 0x0260, 0x1148, 0x00c6, 0x2061, 0x0200, 0x6010, 0x8000, 0x6012,
- 0x00ce, 0x2071, 0x0240, 0x2d04, 0x8007, 0x2072, 0x8d68, 0x8e70,
- 0x1f04, 0x9c87, 0x60c3, 0x004c, 0x080c, 0xa4d1, 0x00ee, 0x00de,
- 0x0005, 0x080c, 0x9ed5, 0x7003, 0x6300, 0x7007, 0x0028, 0x7808,
- 0x700e, 0x60c3, 0x0008, 0x0804, 0xa4d1, 0x00d6, 0x0026, 0x0016,
- 0x080c, 0x9f20, 0x7003, 0x0200, 0x7814, 0x700e, 0x00e6, 0x9ef0,
- 0x0004, 0x2009, 0x0001, 0x2011, 0x000c, 0x2069, 0x1925, 0x6810,
- 0xd084, 0x1148, 0x2073, 0x0500, 0x8e70, 0x2073, 0x0000, 0x8e70,
- 0x8108, 0x9290, 0x0004, 0x2073, 0x0800, 0x8e70, 0x2073, 0x0000,
- 0x00ee, 0x7206, 0x710a, 0x62c2, 0x080c, 0xa4d1, 0x001e, 0x002e,
- 0x00de, 0x0005, 0x2001, 0x1818, 0x2004, 0x609a, 0x0804, 0xa4d1,
- 0x080c, 0x9ed5, 0x7003, 0x5200, 0x2069, 0x1847, 0x6804, 0xd084,
- 0x0130, 0x6828, 0x0016, 0x080c, 0x28bc, 0x710e, 0x001e, 0x20a9,
- 0x0004, 0x20e1, 0x0001, 0x2099, 0x1805, 0x20e9, 0x0000, 0x20a1,
- 0x0250, 0x4003, 0x20a9, 0x0004, 0x2099, 0x1801, 0x20a1, 0x0254,
- 0x4003, 0x080c, 0xb051, 0x1120, 0xb8a0, 0x9082, 0x007f, 0x0248,
- 0x2001, 0x181f, 0x2004, 0x7032, 0x2001, 0x1820, 0x2004, 0x7036,
- 0x0030, 0x2001, 0x1818, 0x2004, 0x9084, 0x00ff, 0x7036, 0x60c3,
- 0x001c, 0x0804, 0xa4d1, 0x080c, 0x9ed5, 0x7003, 0x0500, 0x080c,
- 0xb051, 0x1120, 0xb8a0, 0x9082, 0x007f, 0x0248, 0x2001, 0x181f,
- 0x2004, 0x700a, 0x2001, 0x1820, 0x2004, 0x700e, 0x0030, 0x2001,
- 0x1818, 0x2004, 0x9084, 0x00ff, 0x700e, 0x20a9, 0x0004, 0x20e1,
+ 0x0004, 0x6826, 0x682b, 0x0000, 0x080c, 0x9ab8, 0x00ce, 0x00de,
+ 0x0005, 0x6814, 0x9065, 0x0150, 0x6807, 0x0001, 0x6826, 0x682b,
+ 0x0000, 0x080c, 0x9ab8, 0x00ce, 0x00de, 0x0005, 0x00b6, 0x00e6,
+ 0x6a1c, 0x92dd, 0x0000, 0x0904, 0x99cd, 0xb84c, 0x900d, 0x0118,
+ 0xb888, 0x9005, 0x01a0, 0xb854, 0x905d, 0x0120, 0x920e, 0x0904,
+ 0x99cd, 0x0028, 0x6818, 0x920e, 0x0904, 0x99cd, 0x2058, 0xb84c,
+ 0x900d, 0x0d88, 0xb888, 0x9005, 0x1d70, 0x2b00, 0x681e, 0xbb3c,
+ 0xb838, 0x9302, 0x1e40, 0x080c, 0xb0d8, 0x0904, 0x99cd, 0x8318,
+ 0xbb3e, 0x6116, 0x2b10, 0x6212, 0x0096, 0x2148, 0xa880, 0x9084,
+ 0x00ff, 0x605e, 0xa883, 0x0000, 0xa884, 0x009e, 0x908a, 0x199a,
+ 0x0210, 0x2001, 0x1999, 0x8003, 0x801b, 0x831b, 0x9318, 0x631a,
+ 0x6114, 0x0096, 0x2148, 0xa964, 0x009e, 0x918c, 0x00ff, 0x918e,
+ 0x0048, 0x0538, 0x00f6, 0x2c78, 0x2061, 0x0100, 0xbac0, 0x629a,
+ 0x2069, 0x0200, 0x2071, 0x0240, 0x080c, 0xa047, 0x2069, 0x19e9,
+ 0xbb00, 0xc3dd, 0xbb02, 0x6807, 0x0002, 0x2f18, 0x6b26, 0x682b,
+ 0x0000, 0x7823, 0x0003, 0x7803, 0x0001, 0x7807, 0x0040, 0x00fe,
+ 0x00ee, 0x00be, 0x00ce, 0x00de, 0x0005, 0x00ee, 0x00be, 0x00ce,
+ 0x0cd0, 0x6807, 0x0006, 0x2c18, 0x6b26, 0x6820, 0x8001, 0x6822,
+ 0x682b, 0x0000, 0x080c, 0x6645, 0x080c, 0xaf18, 0x00ee, 0x00be,
+ 0x00ce, 0x00de, 0x0005, 0x00de, 0x0005, 0x00c6, 0x680c, 0x9065,
+ 0x01d8, 0x6104, 0x918e, 0x0040, 0x1180, 0x2009, 0x1837, 0x210c,
+ 0x918c, 0x0028, 0x1150, 0x080c, 0x7569, 0x0138, 0x0006, 0x2009,
+ 0x188b, 0x2104, 0xc095, 0x200a, 0x000e, 0x6807, 0x0004, 0x6826,
+ 0x682b, 0x0000, 0x080c, 0x9ab8, 0x00ce, 0x00de, 0x0005, 0x2001,
+ 0x180c, 0x2014, 0xc2ed, 0x2202, 0x00de, 0x00fe, 0x0005, 0x00f6,
+ 0x00d6, 0x2069, 0x19e9, 0x6830, 0x9086, 0x0000, 0x1570, 0x2001,
+ 0x180c, 0x2014, 0xd2e4, 0x0130, 0xc2e4, 0x2202, 0x080c, 0x98fc,
+ 0x2069, 0x19e9, 0x2001, 0x180c, 0x200c, 0xd1c4, 0x1508, 0x6838,
+ 0x907d, 0x01d8, 0x6a04, 0x9296, 0x0000, 0x1904, 0x9aac, 0x7920,
+ 0x918e, 0x0009, 0x0568, 0x6833, 0x0001, 0x683e, 0x6847, 0x0000,
+ 0x684b, 0x0000, 0x0126, 0x00f6, 0x2091, 0x2400, 0x002e, 0x080c,
+ 0x1ca2, 0x1158, 0x012e, 0x080c, 0xa374, 0x00de, 0x00fe, 0x0005,
+ 0xc1c4, 0x2102, 0x080c, 0x7616, 0x08d0, 0x012e, 0x6843, 0x0000,
+ 0x7803, 0x0002, 0x780c, 0x9015, 0x0140, 0x6a3a, 0x780f, 0x0000,
+ 0x6833, 0x0000, 0x683f, 0x0000, 0x0c40, 0x683a, 0x6836, 0x0cc0,
+ 0x7908, 0xd1fc, 0x1198, 0x6833, 0x0001, 0x683e, 0x6847, 0x0000,
+ 0x684b, 0x0000, 0x0126, 0x00f6, 0x2091, 0x2400, 0x002e, 0x080c,
+ 0x1ca2, 0x19d8, 0x012e, 0x080c, 0xa2f5, 0x0878, 0x2001, 0x1837,
+ 0x2004, 0x9084, 0x0028, 0x1188, 0x2001, 0x197d, 0x2004, 0x9086,
+ 0xaaaa, 0x0158, 0x2001, 0x19ea, 0x2004, 0x9005, 0x11f0, 0x2001,
+ 0x188b, 0x200c, 0xc185, 0xc18c, 0x2102, 0x2f00, 0x6833, 0x0001,
+ 0x683e, 0x6847, 0x0000, 0x684b, 0x0000, 0x0126, 0x00f6, 0x2091,
+ 0x2400, 0x002e, 0x080c, 0x1ca2, 0x1904, 0x9a4d, 0x012e, 0x6a3c,
+ 0x2278, 0x080c, 0xa27f, 0x0804, 0x9a45, 0x2011, 0x188b, 0x2204,
+ 0xc08d, 0x2012, 0x0804, 0x9a45, 0x6a04, 0x9296, 0x0006, 0x1904,
+ 0x9a07, 0x6a30, 0x9296, 0x0000, 0x0904, 0x9a2f, 0x0804, 0x9a07,
+ 0x6020, 0x9084, 0x000f, 0x000b, 0x0005, 0x9acc, 0x9ad1, 0x9f77,
+ 0xa010, 0x9ad1, 0x9f77, 0xa010, 0x9acc, 0x9ad1, 0x9acc, 0x9acc,
+ 0x9acc, 0x9acc, 0x9acc, 0x9acc, 0x080c, 0x97e1, 0x080c, 0x98ed,
+ 0x0005, 0x00b6, 0x0156, 0x0136, 0x0146, 0x01c6, 0x01d6, 0x00c6,
+ 0x00d6, 0x00e6, 0x00f6, 0x2069, 0x0200, 0x2071, 0x0240, 0x6004,
+ 0x908a, 0x0053, 0x1a0c, 0x0dc5, 0x6110, 0x2158, 0xb9c0, 0x2c78,
+ 0x2061, 0x0100, 0x619a, 0x908a, 0x0040, 0x1a04, 0x9b3d, 0x005b,
+ 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x01de, 0x01ce, 0x014e, 0x013e,
+ 0x015e, 0x00be, 0x0005, 0x9ce6, 0x9d21, 0x9d4a, 0x9e06, 0x9e28,
+ 0x9e2e, 0x9e3b, 0x9e43, 0x9e4f, 0x9e55, 0x9e66, 0x9e55, 0x9ebe,
+ 0x9e43, 0x9eca, 0x9ed0, 0x9e4f, 0x9ed0, 0x9edc, 0x9b3b, 0x9b3b,
+ 0x9b3b, 0x9b3b, 0x9b3b, 0x9b3b, 0x9b3b, 0x9b3b, 0x9b3b, 0x9b3b,
+ 0x9b3b, 0xa72e, 0xa751, 0xa762, 0xa782, 0xa7b4, 0x9e3b, 0x9b3b,
+ 0x9e3b, 0x9e55, 0x9b3b, 0x9d4a, 0x9e06, 0x9b3b, 0xab40, 0x9e55,
+ 0x9b3b, 0xab5c, 0x9e55, 0x9b3b, 0x9e4f, 0x9ce0, 0x9b5e, 0x9b3b,
+ 0xab78, 0xabe5, 0xacc0, 0x9b3b, 0xaccd, 0x9e38, 0xacf8, 0x9b3b,
+ 0xa7be, 0xad25, 0x9b3b, 0x080c, 0x0dc5, 0x2100, 0x005b, 0x00fe,
+ 0x00ee, 0x00de, 0x00ce, 0x01de, 0x01ce, 0x014e, 0x013e, 0x015e,
+ 0x00be, 0x0005, 0xadc0, 0xae72, 0x9b5c, 0x9b96, 0x9c42, 0x9c4d,
+ 0x9b5c, 0x9e3b, 0x9b5c, 0x9ca7, 0x9cb3, 0x9bb1, 0x9b5c, 0x9bcc,
+ 0x9c00, 0xafdf, 0xb024, 0x9e55, 0x080c, 0x0dc5, 0x00d6, 0x0096,
+ 0x080c, 0x9eef, 0x0026, 0x0036, 0x7814, 0x2048, 0xa958, 0xd1cc,
+ 0x1138, 0x2009, 0x2414, 0x2011, 0x0018, 0x2019, 0x0018, 0x0030,
+ 0x2009, 0x2410, 0x2011, 0x0014, 0x2019, 0x0014, 0x7102, 0x7206,
+ 0x700b, 0x0800, 0xa83c, 0x700e, 0xa850, 0x7022, 0xa854, 0x7026,
+ 0x63c2, 0x080c, 0xa4eb, 0x003e, 0x002e, 0x009e, 0x00de, 0x0005,
+ 0x7810, 0x00b6, 0x2058, 0xb8a0, 0x00be, 0x080c, 0xb06b, 0x1118,
+ 0x9084, 0xff80, 0x0110, 0x9085, 0x0001, 0x0005, 0x00d6, 0x0096,
+ 0x080c, 0x9eef, 0x7003, 0x0500, 0x7814, 0x2048, 0xa874, 0x700a,
+ 0xa878, 0x700e, 0xa87c, 0x7012, 0xa880, 0x7016, 0xa884, 0x701a,
+ 0xa888, 0x701e, 0x60c3, 0x0010, 0x080c, 0xa4eb, 0x009e, 0x00de,
+ 0x0005, 0x00d6, 0x0096, 0x080c, 0x9eef, 0x7003, 0x0500, 0x7814,
+ 0x2048, 0xa8cc, 0x700a, 0xa8d0, 0x700e, 0xa8d4, 0x7012, 0xa8d8,
+ 0x7016, 0xa8dc, 0x701a, 0xa8e0, 0x701e, 0x60c3, 0x0010, 0x080c,
+ 0xa4eb, 0x009e, 0x00de, 0x0005, 0x00d6, 0x0096, 0x0126, 0x2091,
+ 0x8000, 0x080c, 0x9eef, 0x20e9, 0x0000, 0x2001, 0x19a5, 0x2003,
+ 0x0000, 0x7814, 0x2048, 0xa814, 0x8003, 0x60c2, 0xa830, 0x20a8,
+ 0xa860, 0x20e0, 0xa85c, 0x9080, 0x001b, 0x2098, 0x2001, 0x19a5,
+ 0x0016, 0x200c, 0x2001, 0x0001, 0x080c, 0x2417, 0x080c, 0xdbfa,
+ 0x9006, 0x080c, 0x2417, 0x001e, 0xa804, 0x9005, 0x0110, 0x2048,
+ 0x0c28, 0x04d9, 0x080c, 0xa4eb, 0x012e, 0x009e, 0x00de, 0x0005,
+ 0x00d6, 0x0096, 0x0126, 0x2091, 0x8000, 0x080c, 0x9f3a, 0x20e9,
+ 0x0000, 0x2001, 0x19a5, 0x2003, 0x0000, 0x7814, 0x2048, 0xa86f,
+ 0x0200, 0xa873, 0x0000, 0xa814, 0x8003, 0x60c2, 0xa830, 0x20a8,
+ 0xa860, 0x20e0, 0xa85c, 0x9080, 0x001b, 0x2098, 0x2001, 0x19a5,
+ 0x0016, 0x200c, 0x080c, 0xdbfa, 0x001e, 0xa804, 0x9005, 0x0110,
+ 0x2048, 0x0c60, 0x0051, 0x7814, 0x2048, 0x080c, 0x0fc0, 0x080c,
+ 0xa4eb, 0x012e, 0x009e, 0x00de, 0x0005, 0x60c0, 0x8004, 0x9084,
+ 0x0003, 0x9005, 0x0130, 0x9082, 0x0004, 0x20a3, 0x0000, 0x8000,
+ 0x1de0, 0x0005, 0x080c, 0x9eef, 0x7003, 0x7800, 0x7808, 0x8007,
+ 0x700a, 0x60c3, 0x0008, 0x0804, 0xa4eb, 0x00d6, 0x00e6, 0x080c,
+ 0x9f3a, 0x7814, 0x9084, 0xff00, 0x2073, 0x0200, 0x8e70, 0x8e70,
+ 0x9096, 0xdf00, 0x0138, 0x9096, 0xe000, 0x0120, 0x2073, 0x0010,
+ 0x8e70, 0x0030, 0x9095, 0x0010, 0x2272, 0x8e70, 0x2073, 0x0034,
+ 0x8e70, 0x2069, 0x1805, 0x20a9, 0x0004, 0x2d76, 0x8d68, 0x8e70,
+ 0x1f04, 0x9c6d, 0x2069, 0x1801, 0x20a9, 0x0004, 0x2d76, 0x8d68,
+ 0x8e70, 0x1f04, 0x9c76, 0x9096, 0xdf00, 0x0130, 0x9096, 0xe000,
+ 0x0118, 0x60c3, 0x0018, 0x00f0, 0x2069, 0x19b5, 0x9086, 0xdf00,
+ 0x0110, 0x2069, 0x19cf, 0x20a9, 0x001a, 0x9e86, 0x0260, 0x1148,
+ 0x00c6, 0x2061, 0x0200, 0x6010, 0x8000, 0x6012, 0x00ce, 0x2071,
+ 0x0240, 0x2d04, 0x8007, 0x2072, 0x8d68, 0x8e70, 0x1f04, 0x9c8d,
+ 0x60c3, 0x004c, 0x080c, 0xa4eb, 0x00ee, 0x00de, 0x0005, 0x080c,
+ 0x9eef, 0x7003, 0x6300, 0x7007, 0x0028, 0x7808, 0x700e, 0x60c3,
+ 0x0008, 0x0804, 0xa4eb, 0x00d6, 0x0026, 0x0016, 0x080c, 0x9f3a,
+ 0x7003, 0x0200, 0x7814, 0x700e, 0x00e6, 0x9ef0, 0x0004, 0x2009,
+ 0x0001, 0x2011, 0x000c, 0x2069, 0x1925, 0x6810, 0xd084, 0x1148,
+ 0x2073, 0x0500, 0x8e70, 0x2073, 0x0000, 0x8e70, 0x8108, 0x9290,
+ 0x0004, 0x2073, 0x0800, 0x8e70, 0x2073, 0x0000, 0x00ee, 0x7206,
+ 0x710a, 0x62c2, 0x080c, 0xa4eb, 0x001e, 0x002e, 0x00de, 0x0005,
+ 0x2001, 0x1818, 0x2004, 0x609a, 0x0804, 0xa4eb, 0x080c, 0x9eef,
+ 0x7003, 0x5200, 0x2069, 0x1847, 0x6804, 0xd084, 0x0130, 0x6828,
+ 0x0016, 0x080c, 0x28c7, 0x710e, 0x001e, 0x20a9, 0x0004, 0x20e1,
0x0001, 0x2099, 0x1805, 0x20e9, 0x0000, 0x20a1, 0x0250, 0x4003,
- 0x60c3, 0x0010, 0x0804, 0xa4d1, 0x080c, 0x9ed5, 0x9006, 0x080c,
- 0x6a56, 0xb8a0, 0x9086, 0x007e, 0x1130, 0x7003, 0x0400, 0x620c,
- 0xc2b4, 0x620e, 0x0058, 0x7814, 0x0096, 0x904d, 0x0120, 0x9006,
- 0xa89a, 0xa8a6, 0xa8aa, 0x009e, 0x7003, 0x0300, 0xb8a0, 0x9086,
- 0x007e, 0x1904, 0x9db3, 0x00d6, 0x2069, 0x196d, 0x2001, 0x1837,
- 0x2004, 0xd0a4, 0x0188, 0x6800, 0x700a, 0x6808, 0x9084, 0x2000,
- 0x7012, 0x080c, 0xb068, 0x680c, 0x7016, 0x701f, 0x2710, 0x6818,
- 0x7022, 0x681c, 0x7026, 0x0090, 0x6800, 0x700a, 0x6804, 0x700e,
- 0x6808, 0x080c, 0x7563, 0x1118, 0x9084, 0x37ff, 0x0010, 0x9084,
- 0x3fff, 0x7012, 0x080c, 0xb068, 0x680c, 0x7016, 0x00de, 0x20a9,
- 0x0004, 0x20e1, 0x0001, 0x2099, 0x1805, 0x20e9, 0x0000, 0x20a1,
+ 0x20a9, 0x0004, 0x2099, 0x1801, 0x20a1, 0x0254, 0x4003, 0x080c,
+ 0xb06b, 0x1120, 0xb8a0, 0x9082, 0x007f, 0x0248, 0x2001, 0x181f,
+ 0x2004, 0x7032, 0x2001, 0x1820, 0x2004, 0x7036, 0x0030, 0x2001,
+ 0x1818, 0x2004, 0x9084, 0x00ff, 0x7036, 0x60c3, 0x001c, 0x0804,
+ 0xa4eb, 0x080c, 0x9eef, 0x7003, 0x0500, 0x080c, 0xb06b, 0x1120,
+ 0xb8a0, 0x9082, 0x007f, 0x0248, 0x2001, 0x181f, 0x2004, 0x700a,
+ 0x2001, 0x1820, 0x2004, 0x700e, 0x0030, 0x2001, 0x1818, 0x2004,
+ 0x9084, 0x00ff, 0x700e, 0x20a9, 0x0004, 0x20e1, 0x0001, 0x2099,
+ 0x1805, 0x20e9, 0x0000, 0x20a1, 0x0250, 0x4003, 0x60c3, 0x0010,
+ 0x0804, 0xa4eb, 0x080c, 0x9eef, 0x9006, 0x080c, 0x6a5c, 0xb8a0,
+ 0x9086, 0x007e, 0x1170, 0x2011, 0x0240, 0x2013, 0x22ff, 0x2011,
+ 0x0241, 0x2013, 0xfffe, 0x7003, 0x0400, 0x620c, 0xc2b4, 0x620e,
+ 0x0058, 0x7814, 0x0096, 0x904d, 0x0120, 0x9006, 0xa89a, 0xa8a6,
+ 0xa8aa, 0x009e, 0x7003, 0x0300, 0xb8a0, 0x9086, 0x007e, 0x1904,
+ 0x9dcd, 0x00d6, 0x2069, 0x196d, 0x2001, 0x1837, 0x2004, 0xd0a4,
+ 0x0188, 0x6800, 0x700a, 0x6808, 0x9084, 0x2000, 0x7012, 0x080c,
+ 0xb082, 0x680c, 0x7016, 0x701f, 0x2710, 0x6818, 0x7022, 0x681c,
+ 0x7026, 0x00f0, 0x6800, 0x700a, 0x6804, 0x700e, 0x00f6, 0x2079,
+ 0x0100, 0x080c, 0x7569, 0x1128, 0x78e3, 0x0000, 0x080c, 0x2908,
+ 0x78e2, 0x00fe, 0x6808, 0x080c, 0x7569, 0x1118, 0x9084, 0x37ff,
+ 0x0010, 0x9084, 0x3fff, 0x7012, 0x080c, 0xb082, 0x680c, 0x7016,
+ 0x00de, 0x20a9, 0x0004, 0x20e1, 0x0001, 0x2099, 0x1805, 0x20e9,
+ 0x0000, 0x20a1, 0x0256, 0x4003, 0x20a9, 0x0004, 0x2099, 0x1801,
+ 0x20a1, 0x025a, 0x4003, 0x00d6, 0x080c, 0xada7, 0x2069, 0x1975,
+ 0x2071, 0x024e, 0x6800, 0xc0dd, 0x7002, 0x080c, 0x57d7, 0xd0e4,
+ 0x0110, 0x680c, 0x700e, 0x00de, 0x04a8, 0x2001, 0x1837, 0x2004,
+ 0xd0a4, 0x0170, 0x0016, 0x2001, 0x196e, 0x200c, 0x60e0, 0x9106,
+ 0x0130, 0x2100, 0x60e3, 0x0000, 0x080c, 0x2908, 0x61e2, 0x001e,
+ 0x20e1, 0x0001, 0x2099, 0x196d, 0x20e9, 0x0000, 0x20a1, 0x024e,
+ 0x20a9, 0x0008, 0x4003, 0x20a9, 0x0004, 0x2099, 0x1805, 0x20a1,
0x0256, 0x4003, 0x20a9, 0x0004, 0x2099, 0x1801, 0x20a1, 0x025a,
- 0x4003, 0x00d6, 0x080c, 0xad8d, 0x2069, 0x1975, 0x2071, 0x024e,
- 0x6800, 0xc0dd, 0x7002, 0x080c, 0x57d1, 0xd0e4, 0x0110, 0x680c,
- 0x700e, 0x00de, 0x04a8, 0x2001, 0x1837, 0x2004, 0xd0a4, 0x0170,
- 0x0016, 0x2001, 0x196e, 0x200c, 0x60e0, 0x9106, 0x0130, 0x2100,
- 0x60e3, 0x0000, 0x080c, 0x28fd, 0x61e2, 0x001e, 0x20e1, 0x0001,
- 0x2099, 0x196d, 0x20e9, 0x0000, 0x20a1, 0x024e, 0x20a9, 0x0008,
- 0x4003, 0x20a9, 0x0004, 0x2099, 0x1805, 0x20a1, 0x0256, 0x4003,
- 0x20a9, 0x0004, 0x2099, 0x1801, 0x20a1, 0x025a, 0x4003, 0x080c,
- 0xad8d, 0x20a1, 0x024e, 0x20a9, 0x0008, 0x2099, 0x1975, 0x4003,
- 0x60c3, 0x0074, 0x0804, 0xa4d1, 0x080c, 0x9ed5, 0x7003, 0x2010,
- 0x7007, 0x0014, 0x700b, 0x0800, 0x700f, 0x2000, 0x9006, 0x00f6,
- 0x2079, 0x1847, 0x7904, 0x00fe, 0xd1ac, 0x1110, 0x9085, 0x0020,
- 0xd1a4, 0x0110, 0x9085, 0x0010, 0x9085, 0x0002, 0x00d6, 0x0804,
- 0x9e85, 0x7026, 0x60c3, 0x0014, 0x0804, 0xa4d1, 0x080c, 0x9ed5,
- 0x7003, 0x5000, 0x0804, 0x9d5e, 0x080c, 0x9ed5, 0x7003, 0x2110,
- 0x7007, 0x0014, 0x60c3, 0x0014, 0x0804, 0xa4d1, 0x080c, 0x9f17,
- 0x0010, 0x080c, 0x9f20, 0x7003, 0x0200, 0x60c3, 0x0004, 0x0804,
- 0xa4d1, 0x080c, 0x9f20, 0x7003, 0x0100, 0x700b, 0x0003, 0x700f,
- 0x2a00, 0x60c3, 0x0008, 0x0804, 0xa4d1, 0x080c, 0x9f20, 0x7003,
- 0x0200, 0x0804, 0x9d5e, 0x080c, 0x9f20, 0x7003, 0x0100, 0x782c,
- 0x9005, 0x0110, 0x700a, 0x0010, 0x700b, 0x0003, 0x7814, 0x700e,
- 0x60c3, 0x0008, 0x0804, 0xa4d1, 0x00d6, 0x080c, 0x9f20, 0x7003,
- 0x0210, 0x7007, 0x0014, 0x700b, 0x0800, 0xb894, 0x9086, 0x0014,
- 0x1198, 0xb99c, 0x9184, 0x0030, 0x0190, 0xb998, 0x9184, 0xc000,
- 0x1140, 0xd1ec, 0x0118, 0x700f, 0x2100, 0x0058, 0x700f, 0x0100,
- 0x0040, 0x700f, 0x0400, 0x0028, 0x700f, 0x0700, 0x0010, 0x700f,
- 0x0800, 0x00f6, 0x2079, 0x1847, 0x7904, 0x00fe, 0xd1ac, 0x1110,
- 0x9085, 0x0020, 0xd1a4, 0x0110, 0x9085, 0x0010, 0x2009, 0x1869,
- 0x210c, 0xd184, 0x1110, 0x9085, 0x0002, 0x0026, 0x2009, 0x1867,
- 0x210c, 0xd1e4, 0x0150, 0xc0c5, 0xbacc, 0xd28c, 0x1108, 0xc0cd,
- 0x9094, 0x0030, 0x9296, 0x0010, 0x0140, 0xd1ec, 0x0130, 0x9094,
- 0x0030, 0x9296, 0x0010, 0x0108, 0xc0bd, 0x002e, 0x7026, 0x60c3,
- 0x0014, 0x00de, 0x0804, 0xa4d1, 0x080c, 0x9f20, 0x7003, 0x0210,
- 0x7007, 0x0014, 0x700f, 0x0100, 0x60c3, 0x0014, 0x0804, 0xa4d1,
- 0x080c, 0x9f20, 0x7003, 0x0200, 0x0804, 0x9ce4, 0x080c, 0x9f20,
- 0x7003, 0x0100, 0x700b, 0x0003, 0x700f, 0x2a00, 0x60c3, 0x0008,
- 0x0804, 0xa4d1, 0x080c, 0x9f20, 0x7003, 0x0100, 0x700b, 0x000b,
- 0x60c3, 0x0008, 0x0804, 0xa4d1, 0x0026, 0x00d6, 0x0036, 0x0046,
- 0x2019, 0x3200, 0x2021, 0x0800, 0x0040, 0x0026, 0x00d6, 0x0036,
- 0x0046, 0x2019, 0x2200, 0x2021, 0x0100, 0x080c, 0xada2, 0xb810,
- 0x9305, 0x7002, 0xb814, 0x7006, 0x2069, 0x1800, 0x687c, 0x700a,
- 0x6880, 0x700e, 0x9485, 0x0029, 0x7012, 0x004e, 0x003e, 0x00de,
- 0x080c, 0xa4bf, 0x721a, 0x9f95, 0x0000, 0x7222, 0x7027, 0xffff,
- 0x2071, 0x024c, 0x002e, 0x0005, 0x0026, 0x080c, 0xada2, 0x7003,
- 0x02ff, 0x7007, 0xfffc, 0x00d6, 0x2069, 0x1800, 0x687c, 0x700a,
- 0x6880, 0x700e, 0x00de, 0x7013, 0x2029, 0x0c10, 0x7003, 0x0100,
- 0x7007, 0x0000, 0x700b, 0xfc02, 0x700f, 0x0000, 0x0005, 0x0026,
- 0x00d6, 0x0036, 0x0046, 0x2019, 0x3300, 0x2021, 0x0800, 0x0040,
- 0x0026, 0x00d6, 0x0036, 0x0046, 0x2019, 0x2300, 0x2021, 0x0100,
- 0x080c, 0xada2, 0xb810, 0x9305, 0x7002, 0xb814, 0x7006, 0x2069,
- 0x1800, 0xb810, 0x9005, 0x1140, 0xb814, 0x9005, 0x1128, 0x700b,
- 0x00ff, 0x700f, 0xfffe, 0x0020, 0x687c, 0x700a, 0x6880, 0x700e,
- 0x0000, 0x9485, 0x0098, 0x7012, 0x004e, 0x003e, 0x00de, 0x080c,
- 0xa4bf, 0x721a, 0x7a08, 0x7222, 0x2f10, 0x7226, 0x2071, 0x024c,
- 0x002e, 0x0005, 0x080c, 0xa4bf, 0x721a, 0x7a08, 0x7222, 0x7814,
- 0x7026, 0x2071, 0x024c, 0x002e, 0x0005, 0x00b6, 0x00c6, 0x00d6,
- 0x00e6, 0x00f6, 0x2069, 0x0200, 0x2071, 0x0240, 0x6004, 0x908a,
- 0x0085, 0x0a0c, 0x0dc5, 0x908a, 0x0092, 0x1a0c, 0x0dc5, 0x6110,
- 0x2158, 0xb9c0, 0x2c78, 0x2061, 0x0100, 0x619a, 0x9082, 0x0085,
- 0x0033, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x00be, 0x0005, 0x9f8e,
- 0x9f9d, 0x9fa8, 0x9f8c, 0x9f8c, 0x9f8c, 0x9f8e, 0x9f8c, 0x9f8c,
- 0x9f8c, 0x9f8c, 0x9f8c, 0x9f8c, 0x080c, 0x0dc5, 0x0411, 0x60c3,
- 0x0000, 0x0026, 0x080c, 0x2bf0, 0x0228, 0x2011, 0x0101, 0x2204,
- 0xc0c5, 0x2012, 0x002e, 0x0804, 0xa4d1, 0x0431, 0x7808, 0x700a,
- 0x7814, 0x700e, 0x7017, 0xffff, 0x60c3, 0x000c, 0x0804, 0xa4d1,
- 0x04a1, 0x7003, 0x0003, 0x7007, 0x0300, 0x60c3, 0x0004, 0x0804,
- 0xa4d1, 0x0026, 0x080c, 0xada2, 0xb810, 0x9085, 0x8100, 0x7002,
- 0xb814, 0x7006, 0x2069, 0x1800, 0x687c, 0x700a, 0x6880, 0x700e,
- 0x7013, 0x0009, 0x0804, 0x9ef0, 0x0026, 0x080c, 0xada2, 0xb810,
- 0x9085, 0x8400, 0x7002, 0xb814, 0x7006, 0x2069, 0x1800, 0x687c,
- 0x700a, 0x6880, 0x700e, 0x2001, 0x0099, 0x7a20, 0x9296, 0x0005,
- 0x0108, 0xc0bc, 0x7012, 0x0804, 0x9f52, 0x0026, 0x080c, 0xada2,
- 0xb810, 0x9085, 0x8500, 0x7002, 0xb814, 0x7006, 0x2069, 0x1800,
- 0x687c, 0x700a, 0x6880, 0x700e, 0x2001, 0x0099, 0x7a20, 0x9296,
- 0x0005, 0x0108, 0xc0bc, 0x7012, 0x0804, 0x9f52, 0x00b6, 0x00c6,
- 0x00d6, 0x00e6, 0x00f6, 0x2c78, 0x2069, 0x0200, 0x2071, 0x0240,
- 0x7804, 0x908a, 0x0040, 0x0a0c, 0x0dc5, 0x908a, 0x0054, 0x1a0c,
- 0x0dc5, 0x7910, 0x2158, 0xb9c0, 0x2061, 0x0100, 0x619a, 0x9082,
- 0x0040, 0x0033, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x00be, 0x0005,
- 0xa02d, 0xa0f4, 0xa0c7, 0xa216, 0xa02b, 0xa02b, 0xa02b, 0xa02b,
- 0xa02b, 0xa02b, 0xa02b, 0xa8ec, 0xa8f1, 0xa8f6, 0xa8fb, 0xa02b,
- 0xacea, 0xa02b, 0xa8e7, 0x080c, 0x0dc5, 0x0096, 0x780b, 0xffff,
- 0x080c, 0xa098, 0x7914, 0x2148, 0xa978, 0x7956, 0xae64, 0x96b4,
- 0x00ff, 0x9686, 0x0008, 0x1148, 0xa8b4, 0x7032, 0xa8b8, 0x7036,
- 0xa8bc, 0x703a, 0xa8c0, 0x703e, 0x0008, 0x7132, 0xa97c, 0x9184,
- 0x000f, 0x1118, 0x2001, 0x0005, 0x0040, 0xd184, 0x0118, 0x2001,
- 0x0004, 0x0018, 0x9084, 0x0006, 0x8004, 0x2010, 0x785c, 0x9084,
- 0x00ff, 0x8007, 0x9205, 0x7042, 0xd1ac, 0x0158, 0x7047, 0x0002,
- 0x9686, 0x0008, 0x1118, 0x080c, 0x18f1, 0x0010, 0x080c, 0x1768,
- 0x0050, 0xd1b4, 0x0118, 0x7047, 0x0001, 0x0028, 0x7047, 0x0000,
- 0x9016, 0x2230, 0x0010, 0xaab0, 0xaeac, 0x726a, 0x766e, 0x20a9,
- 0x0008, 0x20e9, 0x0000, 0xa860, 0x20e0, 0xa85c, 0x9080, 0x0023,
- 0x2098, 0x20a1, 0x0252, 0x2069, 0x0200, 0x6813, 0x0018, 0x4003,
- 0x6813, 0x0008, 0x60c3, 0x0020, 0x6017, 0x0009, 0x2001, 0x1a05,
- 0x2003, 0x07d0, 0x2001, 0x1a04, 0x2003, 0x0009, 0x009e, 0x0005,
- 0x6813, 0x0008, 0xba8c, 0x8210, 0xb8cc, 0xd084, 0x0180, 0x2001,
- 0x1ad1, 0x200c, 0x8108, 0x2102, 0x2001, 0x1ad0, 0x201c, 0x1218,
- 0x8318, 0x2302, 0x0ea0, 0x794a, 0x712e, 0x7b46, 0x732a, 0x9294,
- 0x00ff, 0xba8e, 0x8217, 0x721a, 0xba10, 0x9295, 0x0600, 0x7202,
- 0xba14, 0x7206, 0x2069, 0x1800, 0x6a7c, 0x720a, 0x6a80, 0x720e,
- 0x7013, 0x0829, 0x2f10, 0x7222, 0x7027, 0xffff, 0x0005, 0x00d6,
- 0x0096, 0x0081, 0x7814, 0x2048, 0xa890, 0x7002, 0xa88c, 0x7006,
- 0xa8b0, 0x700a, 0xa8ac, 0x700e, 0x60c3, 0x000c, 0x009e, 0x00de,
- 0x0804, 0xa4d1, 0x6813, 0x0008, 0xb810, 0x9085, 0x0500, 0x7002,
- 0xb814, 0x7006, 0x2069, 0x1800, 0x687c, 0x700a, 0x6880, 0x700e,
- 0x7013, 0x0889, 0x080c, 0xa4bf, 0x721a, 0x7a08, 0x7222, 0x2f10,
- 0x7226, 0x2071, 0x024c, 0x0005, 0x00d6, 0x0096, 0x080c, 0xa1f4,
- 0x7814, 0x2048, 0x080c, 0xce3d, 0x1130, 0x7814, 0x9084, 0x0700,
- 0x8007, 0x0033, 0x0010, 0x9006, 0x001b, 0x009e, 0x00de, 0x0005,
- 0xa112, 0xa17b, 0xa18b, 0xa1b1, 0xa1bd, 0xa1ce, 0xa1d6, 0xa110,
- 0x080c, 0x0dc5, 0x0016, 0x0036, 0xa97c, 0x918c, 0x0003, 0x0118,
- 0x9186, 0x0003, 0x1198, 0xaba8, 0x7824, 0xd0cc, 0x1168, 0x7316,
- 0xa898, 0x701a, 0xa894, 0x701e, 0x003e, 0x001e, 0x2001, 0x19b3,
- 0x2004, 0x60c2, 0x0804, 0xa4d1, 0xc3e5, 0x0c88, 0x9186, 0x0001,
- 0x190c, 0x0dc5, 0xaba8, 0x7824, 0xd0cc, 0x1904, 0xa178, 0x7316,
- 0xa898, 0x701a, 0xa894, 0x701e, 0xa8a4, 0x7026, 0xa8ac, 0x702e,
- 0x2009, 0x0018, 0x9384, 0x0300, 0x0570, 0xd3c4, 0x0110, 0xa8ac,
- 0x9108, 0xd3cc, 0x0110, 0xa8a4, 0x9108, 0x6810, 0x9085, 0x0010,
- 0x6812, 0x2011, 0x0258, 0x20e9, 0x0000, 0x22a0, 0x0156, 0x20a9,
- 0x0008, 0xa860, 0x20e0, 0xa85c, 0x9080, 0x002c, 0x2098, 0x4003,
- 0x6810, 0x8000, 0x6812, 0x2011, 0x0240, 0x22a0, 0x20a9, 0x0005,
- 0x4003, 0x6810, 0xc0a4, 0x6812, 0x015e, 0x9184, 0x0003, 0x0118,
- 0x2019, 0x0245, 0x201a, 0x61c2, 0x003e, 0x001e, 0x0804, 0xa4d1,
- 0xc3e5, 0x0804, 0xa137, 0x2011, 0x0008, 0x2001, 0x180f, 0x2004,
- 0xd0a4, 0x0110, 0x2011, 0x0028, 0x7824, 0xd0cc, 0x1110, 0x7216,
- 0x0470, 0x0ce8, 0xc2e5, 0x2011, 0x0302, 0x0016, 0x782c, 0x701a,
- 0x7930, 0x711e, 0x9105, 0x0108, 0xc2dd, 0x001e, 0x7824, 0xd0cc,
- 0x0108, 0xc2e5, 0x7216, 0x7027, 0x0012, 0x702f, 0x0008, 0x7043,
- 0x7000, 0x7047, 0x0500, 0x704f, 0x000a, 0x2069, 0x0200, 0x6813,
- 0x0009, 0x2071, 0x0240, 0x700b, 0x2500, 0x60c3, 0x0032, 0x0804,
- 0xa4d1, 0x2011, 0x0028, 0x7824, 0xd0cc, 0x1128, 0x7216, 0x60c3,
- 0x0018, 0x0804, 0xa4d1, 0x0cd0, 0xc2e5, 0x2011, 0x0100, 0x7824,
- 0xd0cc, 0x0108, 0xc2e5, 0x7216, 0x702f, 0x0008, 0x7858, 0x9084,
- 0x00ff, 0x7036, 0x60c3, 0x0020, 0x0804, 0xa4d1, 0x2011, 0x0008,
- 0x7824, 0xd0cc, 0x0108, 0xc2e5, 0x7216, 0x0c08, 0x0036, 0x7b14,
- 0x9384, 0xff00, 0x7816, 0x9384, 0x00ff, 0x8001, 0x1138, 0x7824,
- 0xd0cc, 0x0108, 0xc2e5, 0x7216, 0x003e, 0x0888, 0x0046, 0x2021,
- 0x0800, 0x0006, 0x7824, 0xd0cc, 0x000e, 0x0108, 0xc4e5, 0x7416,
- 0x004e, 0x701e, 0x003e, 0x0818, 0x00d6, 0x6813, 0x0008, 0xb810,
- 0x9085, 0x0700, 0x7002, 0xb814, 0x7006, 0x2069, 0x1800, 0x687c,
- 0x700a, 0x6880, 0x700e, 0x7824, 0xd0cc, 0x1168, 0x7013, 0x0898,
- 0x080c, 0xa4bf, 0x721a, 0x7a08, 0x7222, 0x2f10, 0x7226, 0x2071,
- 0x024c, 0x00de, 0x0005, 0x7013, 0x0889, 0x0c90, 0x0016, 0x7814,
- 0x9084, 0x0700, 0x8007, 0x0013, 0x001e, 0x0005, 0xa226, 0xa226,
- 0xa228, 0xa226, 0xa226, 0xa226, 0xa242, 0xa226, 0x080c, 0x0dc5,
- 0x7914, 0x918c, 0x08ff, 0x918d, 0xf600, 0x7916, 0x2009, 0x0003,
- 0x00b9, 0x2069, 0x1847, 0x6804, 0xd0bc, 0x0130, 0x682c, 0x9084,
- 0x00ff, 0x8007, 0x7032, 0x0010, 0x7033, 0x3f00, 0x60c3, 0x0001,
- 0x0804, 0xa4d1, 0x2009, 0x0003, 0x0019, 0x7033, 0x7f00, 0x0cb0,
- 0x0016, 0x080c, 0xada2, 0x001e, 0xb810, 0x9085, 0x0100, 0x7002,
- 0xb814, 0x7006, 0x2069, 0x1800, 0x6a7c, 0x720a, 0x6a80, 0x720e,
- 0x7013, 0x0888, 0x918d, 0x0008, 0x7116, 0x080c, 0xa4bf, 0x721a,
- 0x7a08, 0x7222, 0x2f10, 0x7226, 0x0005, 0x00b6, 0x00e6, 0x00d6,
+ 0x4003, 0x080c, 0xada7, 0x20a1, 0x024e, 0x20a9, 0x0008, 0x2099,
+ 0x1975, 0x4003, 0x60c3, 0x0074, 0x0804, 0xa4eb, 0x080c, 0x9eef,
+ 0x7003, 0x2010, 0x7007, 0x0014, 0x700b, 0x0800, 0x700f, 0x2000,
+ 0x9006, 0x00f6, 0x2079, 0x1847, 0x7904, 0x00fe, 0xd1ac, 0x1110,
+ 0x9085, 0x0020, 0xd1a4, 0x0110, 0x9085, 0x0010, 0x9085, 0x0002,
+ 0x00d6, 0x0804, 0x9e9f, 0x7026, 0x60c3, 0x0014, 0x0804, 0xa4eb,
+ 0x080c, 0x9eef, 0x7003, 0x5000, 0x0804, 0x9d6c, 0x080c, 0x9eef,
+ 0x7003, 0x2110, 0x7007, 0x0014, 0x60c3, 0x0014, 0x0804, 0xa4eb,
+ 0x080c, 0x9f31, 0x0010, 0x080c, 0x9f3a, 0x7003, 0x0200, 0x60c3,
+ 0x0004, 0x0804, 0xa4eb, 0x080c, 0x9f3a, 0x7003, 0x0100, 0x700b,
+ 0x0003, 0x700f, 0x2a00, 0x60c3, 0x0008, 0x0804, 0xa4eb, 0x080c,
+ 0x9f3a, 0x7003, 0x0200, 0x0804, 0x9d6c, 0x080c, 0x9f3a, 0x7003,
+ 0x0100, 0x782c, 0x9005, 0x0110, 0x700a, 0x0010, 0x700b, 0x0003,
+ 0x7814, 0x700e, 0x60c3, 0x0008, 0x0804, 0xa4eb, 0x00d6, 0x080c,
+ 0x9f3a, 0x7003, 0x0210, 0x7007, 0x0014, 0x700b, 0x0800, 0xb894,
+ 0x9086, 0x0014, 0x1198, 0xb99c, 0x9184, 0x0030, 0x0190, 0xb998,
+ 0x9184, 0xc000, 0x1140, 0xd1ec, 0x0118, 0x700f, 0x2100, 0x0058,
+ 0x700f, 0x0100, 0x0040, 0x700f, 0x0400, 0x0028, 0x700f, 0x0700,
+ 0x0010, 0x700f, 0x0800, 0x00f6, 0x2079, 0x1847, 0x7904, 0x00fe,
+ 0xd1ac, 0x1110, 0x9085, 0x0020, 0xd1a4, 0x0110, 0x9085, 0x0010,
+ 0x2009, 0x1869, 0x210c, 0xd184, 0x1110, 0x9085, 0x0002, 0x0026,
+ 0x2009, 0x1867, 0x210c, 0xd1e4, 0x0150, 0xc0c5, 0xbacc, 0xd28c,
+ 0x1108, 0xc0cd, 0x9094, 0x0030, 0x9296, 0x0010, 0x0140, 0xd1ec,
+ 0x0130, 0x9094, 0x0030, 0x9296, 0x0010, 0x0108, 0xc0bd, 0x002e,
+ 0x7026, 0x60c3, 0x0014, 0x00de, 0x0804, 0xa4eb, 0x080c, 0x9f3a,
+ 0x7003, 0x0210, 0x7007, 0x0014, 0x700f, 0x0100, 0x60c3, 0x0014,
+ 0x0804, 0xa4eb, 0x080c, 0x9f3a, 0x7003, 0x0200, 0x0804, 0x9cea,
+ 0x080c, 0x9f3a, 0x7003, 0x0100, 0x700b, 0x0003, 0x700f, 0x2a00,
+ 0x60c3, 0x0008, 0x0804, 0xa4eb, 0x080c, 0x9f3a, 0x7003, 0x0100,
+ 0x700b, 0x000b, 0x60c3, 0x0008, 0x0804, 0xa4eb, 0x0026, 0x00d6,
+ 0x0036, 0x0046, 0x2019, 0x3200, 0x2021, 0x0800, 0x0040, 0x0026,
+ 0x00d6, 0x0036, 0x0046, 0x2019, 0x2200, 0x2021, 0x0100, 0x080c,
+ 0xadbc, 0xb810, 0x9305, 0x7002, 0xb814, 0x7006, 0x2069, 0x1800,
+ 0x687c, 0x700a, 0x6880, 0x700e, 0x9485, 0x0029, 0x7012, 0x004e,
+ 0x003e, 0x00de, 0x080c, 0xa4d9, 0x721a, 0x9f95, 0x0000, 0x7222,
+ 0x7027, 0xffff, 0x2071, 0x024c, 0x002e, 0x0005, 0x0026, 0x080c,
+ 0xadbc, 0x7003, 0x02ff, 0x7007, 0xfffc, 0x00d6, 0x2069, 0x1800,
+ 0x687c, 0x700a, 0x6880, 0x700e, 0x00de, 0x7013, 0x2029, 0x0c10,
+ 0x7003, 0x0100, 0x7007, 0x0000, 0x700b, 0xfc02, 0x700f, 0x0000,
+ 0x0005, 0x0026, 0x00d6, 0x0036, 0x0046, 0x2019, 0x3300, 0x2021,
+ 0x0800, 0x0040, 0x0026, 0x00d6, 0x0036, 0x0046, 0x2019, 0x2300,
+ 0x2021, 0x0100, 0x080c, 0xadbc, 0xb810, 0x9305, 0x7002, 0xb814,
+ 0x7006, 0x2069, 0x1800, 0xb810, 0x9005, 0x1140, 0xb814, 0x9005,
+ 0x1128, 0x700b, 0x00ff, 0x700f, 0xfffe, 0x0020, 0x687c, 0x700a,
+ 0x6880, 0x700e, 0x0000, 0x9485, 0x0098, 0x7012, 0x004e, 0x003e,
+ 0x00de, 0x080c, 0xa4d9, 0x721a, 0x7a08, 0x7222, 0x2f10, 0x7226,
+ 0x2071, 0x024c, 0x002e, 0x0005, 0x080c, 0xa4d9, 0x721a, 0x7a08,
+ 0x7222, 0x7814, 0x7026, 0x2071, 0x024c, 0x002e, 0x0005, 0x00b6,
+ 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x2069, 0x0200, 0x2071, 0x0240,
+ 0x6004, 0x908a, 0x0085, 0x0a0c, 0x0dc5, 0x908a, 0x0092, 0x1a0c,
+ 0x0dc5, 0x6110, 0x2158, 0xb9c0, 0x2c78, 0x2061, 0x0100, 0x619a,
+ 0x9082, 0x0085, 0x0033, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x00be,
+ 0x0005, 0x9fa8, 0x9fb7, 0x9fc2, 0x9fa6, 0x9fa6, 0x9fa6, 0x9fa8,
+ 0x9fa6, 0x9fa6, 0x9fa6, 0x9fa6, 0x9fa6, 0x9fa6, 0x080c, 0x0dc5,
+ 0x0411, 0x60c3, 0x0000, 0x0026, 0x080c, 0x2be7, 0x0228, 0x2011,
+ 0x0101, 0x2204, 0xc0c5, 0x2012, 0x002e, 0x0804, 0xa4eb, 0x0431,
+ 0x7808, 0x700a, 0x7814, 0x700e, 0x7017, 0xffff, 0x60c3, 0x000c,
+ 0x0804, 0xa4eb, 0x04a1, 0x7003, 0x0003, 0x7007, 0x0300, 0x60c3,
+ 0x0004, 0x0804, 0xa4eb, 0x0026, 0x080c, 0xadbc, 0xb810, 0x9085,
+ 0x8100, 0x7002, 0xb814, 0x7006, 0x2069, 0x1800, 0x687c, 0x700a,
+ 0x6880, 0x700e, 0x7013, 0x0009, 0x0804, 0x9f0a, 0x0026, 0x080c,
+ 0xadbc, 0xb810, 0x9085, 0x8400, 0x7002, 0xb814, 0x7006, 0x2069,
+ 0x1800, 0x687c, 0x700a, 0x6880, 0x700e, 0x2001, 0x0099, 0x7a20,
+ 0x9296, 0x0005, 0x0108, 0xc0bc, 0x7012, 0x0804, 0x9f6c, 0x0026,
+ 0x080c, 0xadbc, 0xb810, 0x9085, 0x8500, 0x7002, 0xb814, 0x7006,
+ 0x2069, 0x1800, 0x687c, 0x700a, 0x6880, 0x700e, 0x2001, 0x0099,
+ 0x7a20, 0x9296, 0x0005, 0x0108, 0xc0bc, 0x7012, 0x0804, 0x9f6c,
+ 0x00b6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x2c78, 0x2069, 0x0200,
+ 0x2071, 0x0240, 0x7804, 0x908a, 0x0040, 0x0a0c, 0x0dc5, 0x908a,
+ 0x0054, 0x1a0c, 0x0dc5, 0x7910, 0x2158, 0xb9c0, 0x2061, 0x0100,
+ 0x619a, 0x9082, 0x0040, 0x0033, 0x00fe, 0x00ee, 0x00de, 0x00ce,
+ 0x00be, 0x0005, 0xa047, 0xa10e, 0xa0e1, 0xa230, 0xa045, 0xa045,
+ 0xa045, 0xa045, 0xa045, 0xa045, 0xa045, 0xa906, 0xa90b, 0xa910,
+ 0xa915, 0xa045, 0xad04, 0xa045, 0xa901, 0x080c, 0x0dc5, 0x0096,
+ 0x780b, 0xffff, 0x080c, 0xa0b2, 0x7914, 0x2148, 0xa978, 0x7956,
+ 0xae64, 0x96b4, 0x00ff, 0x9686, 0x0008, 0x1148, 0xa8b4, 0x7032,
+ 0xa8b8, 0x7036, 0xa8bc, 0x703a, 0xa8c0, 0x703e, 0x0008, 0x7132,
+ 0xa97c, 0x9184, 0x000f, 0x1118, 0x2001, 0x0005, 0x0040, 0xd184,
+ 0x0118, 0x2001, 0x0004, 0x0018, 0x9084, 0x0006, 0x8004, 0x2010,
+ 0x785c, 0x9084, 0x00ff, 0x8007, 0x9205, 0x7042, 0xd1ac, 0x0158,
+ 0x7047, 0x0002, 0x9686, 0x0008, 0x1118, 0x080c, 0x18f1, 0x0010,
+ 0x080c, 0x1768, 0x0050, 0xd1b4, 0x0118, 0x7047, 0x0001, 0x0028,
+ 0x7047, 0x0000, 0x9016, 0x2230, 0x0010, 0xaab0, 0xaeac, 0x726a,
+ 0x766e, 0x20a9, 0x0008, 0x20e9, 0x0000, 0xa860, 0x20e0, 0xa85c,
+ 0x9080, 0x0023, 0x2098, 0x20a1, 0x0252, 0x2069, 0x0200, 0x6813,
+ 0x0018, 0x4003, 0x6813, 0x0008, 0x60c3, 0x0020, 0x6017, 0x0009,
+ 0x2001, 0x1a05, 0x2003, 0x07d0, 0x2001, 0x1a04, 0x2003, 0x0009,
+ 0x009e, 0x0005, 0x6813, 0x0008, 0xba8c, 0x8210, 0xb8cc, 0xd084,
+ 0x0180, 0x2001, 0x1ad1, 0x200c, 0x8108, 0x2102, 0x2001, 0x1ad0,
+ 0x201c, 0x1218, 0x8318, 0x2302, 0x0ea0, 0x794a, 0x712e, 0x7b46,
+ 0x732a, 0x9294, 0x00ff, 0xba8e, 0x8217, 0x721a, 0xba10, 0x9295,
+ 0x0600, 0x7202, 0xba14, 0x7206, 0x2069, 0x1800, 0x6a7c, 0x720a,
+ 0x6a80, 0x720e, 0x7013, 0x0829, 0x2f10, 0x7222, 0x7027, 0xffff,
+ 0x0005, 0x00d6, 0x0096, 0x0081, 0x7814, 0x2048, 0xa890, 0x7002,
+ 0xa88c, 0x7006, 0xa8b0, 0x700a, 0xa8ac, 0x700e, 0x60c3, 0x000c,
+ 0x009e, 0x00de, 0x0804, 0xa4eb, 0x6813, 0x0008, 0xb810, 0x9085,
+ 0x0500, 0x7002, 0xb814, 0x7006, 0x2069, 0x1800, 0x687c, 0x700a,
+ 0x6880, 0x700e, 0x7013, 0x0889, 0x080c, 0xa4d9, 0x721a, 0x7a08,
+ 0x7222, 0x2f10, 0x7226, 0x2071, 0x024c, 0x0005, 0x00d6, 0x0096,
+ 0x080c, 0xa20e, 0x7814, 0x2048, 0x080c, 0xce54, 0x1130, 0x7814,
+ 0x9084, 0x0700, 0x8007, 0x0033, 0x0010, 0x9006, 0x001b, 0x009e,
+ 0x00de, 0x0005, 0xa12c, 0xa195, 0xa1a5, 0xa1cb, 0xa1d7, 0xa1e8,
+ 0xa1f0, 0xa12a, 0x080c, 0x0dc5, 0x0016, 0x0036, 0xa97c, 0x918c,
+ 0x0003, 0x0118, 0x9186, 0x0003, 0x1198, 0xaba8, 0x7824, 0xd0cc,
+ 0x1168, 0x7316, 0xa898, 0x701a, 0xa894, 0x701e, 0x003e, 0x001e,
+ 0x2001, 0x19b3, 0x2004, 0x60c2, 0x0804, 0xa4eb, 0xc3e5, 0x0c88,
+ 0x9186, 0x0001, 0x190c, 0x0dc5, 0xaba8, 0x7824, 0xd0cc, 0x1904,
+ 0xa192, 0x7316, 0xa898, 0x701a, 0xa894, 0x701e, 0xa8a4, 0x7026,
+ 0xa8ac, 0x702e, 0x2009, 0x0018, 0x9384, 0x0300, 0x0570, 0xd3c4,
+ 0x0110, 0xa8ac, 0x9108, 0xd3cc, 0x0110, 0xa8a4, 0x9108, 0x6810,
+ 0x9085, 0x0010, 0x6812, 0x2011, 0x0258, 0x20e9, 0x0000, 0x22a0,
+ 0x0156, 0x20a9, 0x0008, 0xa860, 0x20e0, 0xa85c, 0x9080, 0x002c,
+ 0x2098, 0x4003, 0x6810, 0x8000, 0x6812, 0x2011, 0x0240, 0x22a0,
+ 0x20a9, 0x0005, 0x4003, 0x6810, 0xc0a4, 0x6812, 0x015e, 0x9184,
+ 0x0003, 0x0118, 0x2019, 0x0245, 0x201a, 0x61c2, 0x003e, 0x001e,
+ 0x0804, 0xa4eb, 0xc3e5, 0x0804, 0xa151, 0x2011, 0x0008, 0x2001,
+ 0x180f, 0x2004, 0xd0a4, 0x0110, 0x2011, 0x0028, 0x7824, 0xd0cc,
+ 0x1110, 0x7216, 0x0470, 0x0ce8, 0xc2e5, 0x2011, 0x0302, 0x0016,
+ 0x782c, 0x701a, 0x7930, 0x711e, 0x9105, 0x0108, 0xc2dd, 0x001e,
+ 0x7824, 0xd0cc, 0x0108, 0xc2e5, 0x7216, 0x7027, 0x0012, 0x702f,
+ 0x0008, 0x7043, 0x7000, 0x7047, 0x0500, 0x704f, 0x000a, 0x2069,
+ 0x0200, 0x6813, 0x0009, 0x2071, 0x0240, 0x700b, 0x2500, 0x60c3,
+ 0x0032, 0x0804, 0xa4eb, 0x2011, 0x0028, 0x7824, 0xd0cc, 0x1128,
+ 0x7216, 0x60c3, 0x0018, 0x0804, 0xa4eb, 0x0cd0, 0xc2e5, 0x2011,
+ 0x0100, 0x7824, 0xd0cc, 0x0108, 0xc2e5, 0x7216, 0x702f, 0x0008,
+ 0x7858, 0x9084, 0x00ff, 0x7036, 0x60c3, 0x0020, 0x0804, 0xa4eb,
+ 0x2011, 0x0008, 0x7824, 0xd0cc, 0x0108, 0xc2e5, 0x7216, 0x0c08,
+ 0x0036, 0x7b14, 0x9384, 0xff00, 0x7816, 0x9384, 0x00ff, 0x8001,
+ 0x1138, 0x7824, 0xd0cc, 0x0108, 0xc2e5, 0x7216, 0x003e, 0x0888,
+ 0x0046, 0x2021, 0x0800, 0x0006, 0x7824, 0xd0cc, 0x000e, 0x0108,
+ 0xc4e5, 0x7416, 0x004e, 0x701e, 0x003e, 0x0818, 0x00d6, 0x6813,
+ 0x0008, 0xb810, 0x9085, 0x0700, 0x7002, 0xb814, 0x7006, 0x2069,
+ 0x1800, 0x687c, 0x700a, 0x6880, 0x700e, 0x7824, 0xd0cc, 0x1168,
+ 0x7013, 0x0898, 0x080c, 0xa4d9, 0x721a, 0x7a08, 0x7222, 0x2f10,
+ 0x7226, 0x2071, 0x024c, 0x00de, 0x0005, 0x7013, 0x0889, 0x0c90,
+ 0x0016, 0x7814, 0x9084, 0x0700, 0x8007, 0x0013, 0x001e, 0x0005,
+ 0xa240, 0xa240, 0xa242, 0xa240, 0xa240, 0xa240, 0xa25c, 0xa240,
+ 0x080c, 0x0dc5, 0x7914, 0x918c, 0x08ff, 0x918d, 0xf600, 0x7916,
+ 0x2009, 0x0003, 0x00b9, 0x2069, 0x1847, 0x6804, 0xd0bc, 0x0130,
+ 0x682c, 0x9084, 0x00ff, 0x8007, 0x7032, 0x0010, 0x7033, 0x3f00,
+ 0x60c3, 0x0001, 0x0804, 0xa4eb, 0x2009, 0x0003, 0x0019, 0x7033,
+ 0x7f00, 0x0cb0, 0x0016, 0x080c, 0xadbc, 0x001e, 0xb810, 0x9085,
+ 0x0100, 0x7002, 0xb814, 0x7006, 0x2069, 0x1800, 0x6a7c, 0x720a,
+ 0x6a80, 0x720e, 0x7013, 0x0888, 0x918d, 0x0008, 0x7116, 0x080c,
+ 0xa4d9, 0x721a, 0x7a08, 0x7222, 0x2f10, 0x7226, 0x0005, 0x00b6,
+ 0x00e6, 0x00d6, 0x00c6, 0x0066, 0x0056, 0x0046, 0x0036, 0x2061,
+ 0x0100, 0x2071, 0x1800, 0x7160, 0x7810, 0x2058, 0x76dc, 0x96b4,
+ 0x0028, 0x0110, 0x737c, 0x7480, 0x2500, 0x76dc, 0x96b4, 0x0028,
+ 0x0140, 0x2001, 0x04ff, 0x6062, 0x6067, 0xffff, 0x636a, 0x646e,
+ 0x0050, 0x2001, 0x00ff, 0x9085, 0x0400, 0x6062, 0x6067, 0xffff,
+ 0x606b, 0x0000, 0x616e, 0xb8b8, 0x6073, 0x0530, 0x6077, 0x0008,
+ 0xb88c, 0x8000, 0x9084, 0x00ff, 0xb88e, 0x8007, 0x9085, 0x0020,
+ 0x607a, 0x607f, 0x0000, 0x2b00, 0x6082, 0x6087, 0xffff, 0x7814,
+ 0x0096, 0x2048, 0xa838, 0x608a, 0xa834, 0x608e, 0xa848, 0x60c6,
+ 0xa844, 0x60ca, 0x009e, 0xb86c, 0x60ce, 0x60ab, 0x0036, 0x60af,
+ 0x95d5, 0x60d7, 0x0000, 0x2001, 0x1837, 0x2004, 0x9084, 0x0028,
+ 0x0128, 0x609f, 0x0000, 0x2001, 0x0092, 0x0048, 0x6028, 0xc0bd,
+ 0x602a, 0x609f, 0x00ff, 0x6027, 0xffff, 0x2001, 0x00b2, 0x6016,
+ 0x2009, 0x07d0, 0x080c, 0x8794, 0x003e, 0x004e, 0x005e, 0x006e,
+ 0x00ce, 0x00de, 0x00ee, 0x00be, 0x0005, 0x00b6, 0x00e6, 0x00d6,
0x00c6, 0x0066, 0x0056, 0x0046, 0x0036, 0x2061, 0x0100, 0x2071,
- 0x1800, 0x7160, 0x7810, 0x2058, 0x76dc, 0x96b4, 0x0028, 0x0110,
- 0x737c, 0x7480, 0x2500, 0x76dc, 0x96b4, 0x0028, 0x0140, 0x2001,
- 0x04ff, 0x6062, 0x6067, 0xffff, 0x636a, 0x646e, 0x0050, 0x2001,
- 0x00ff, 0x9085, 0x0400, 0x6062, 0x6067, 0xffff, 0x606b, 0x0000,
- 0x616e, 0xb8b8, 0x6073, 0x0530, 0x6077, 0x0008, 0xb88c, 0x8000,
- 0x9084, 0x00ff, 0xb88e, 0x8007, 0x9085, 0x0020, 0x607a, 0x607f,
- 0x0000, 0x2b00, 0x6082, 0x6087, 0xffff, 0x7814, 0x0096, 0x2048,
+ 0x1800, 0x7160, 0x7810, 0x2058, 0xb8a0, 0x2028, 0x76dc, 0xd6ac,
+ 0x1168, 0x9582, 0x007e, 0x1250, 0x2500, 0x9094, 0xff80, 0x1130,
+ 0x9080, 0x33ac, 0x2015, 0x9294, 0x00ff, 0x0020, 0xb910, 0xba14,
+ 0x737c, 0x7480, 0x70dc, 0xd0ac, 0x1130, 0x9582, 0x007e, 0x1218,
+ 0x9584, 0xff80, 0x0138, 0x9185, 0x0400, 0x6062, 0x6266, 0x636a,
+ 0x646e, 0x0030, 0x6063, 0x0400, 0x6266, 0x606b, 0x0000, 0x616e,
+ 0xb8b8, 0x6072, 0x6077, 0x0000, 0xb864, 0xd0a4, 0x0110, 0x6077,
+ 0x0008, 0xb88c, 0x8000, 0x9084, 0x00ff, 0xb88e, 0x8007, 0x9085,
+ 0x0020, 0x607a, 0x607f, 0x0000, 0x2b00, 0x6082, 0x6087, 0xffff,
+ 0x7814, 0x0096, 0x2048, 0xa838, 0x608a, 0xa834, 0x608e, 0xa848,
+ 0x60c6, 0xa844, 0x60ca, 0x009e, 0xb86c, 0x60ce, 0x60ab, 0x0036,
+ 0x60af, 0x95d5, 0x60d7, 0x0000, 0xbac0, 0x629e, 0x00f6, 0x2079,
+ 0x0140, 0x7803, 0x0000, 0x00fe, 0x2009, 0x0092, 0x6116, 0x2009,
+ 0x07d0, 0x080c, 0x8794, 0x003e, 0x004e, 0x005e, 0x006e, 0x00ce,
+ 0x00de, 0x00ee, 0x00be, 0x0005, 0x00b6, 0x0096, 0x00e6, 0x00d6,
+ 0x00c6, 0x0056, 0x0046, 0x0036, 0x2061, 0x0100, 0x2071, 0x1800,
+ 0x7810, 0x2058, 0xb8a0, 0x2028, 0xb910, 0xba14, 0x737c, 0x7480,
+ 0x7820, 0x90be, 0x0006, 0x0904, 0xa448, 0x90be, 0x000a, 0x1904,
+ 0xa404, 0xb8c0, 0x609e, 0x7814, 0x2048, 0xa87c, 0xd0fc, 0x0558,
+ 0xaf90, 0x9784, 0xff00, 0x9105, 0x6062, 0x873f, 0x9784, 0xff00,
+ 0x0006, 0x7814, 0x2048, 0xa878, 0xc0fc, 0x9005, 0x000e, 0x1160,
+ 0xaf94, 0x87ff, 0x0198, 0x2039, 0x0098, 0x9705, 0x6072, 0x7808,
+ 0x6082, 0x2f00, 0x6086, 0x0038, 0x9185, 0x2200, 0x6062, 0x6073,
+ 0x0129, 0x6077, 0x0000, 0xb8c0, 0x609e, 0x0050, 0x2039, 0x0029,
+ 0x9705, 0x6072, 0x0cc0, 0x9185, 0x0200, 0x6062, 0x6073, 0x2029,
+ 0xa87c, 0xd0fc, 0x0118, 0xaf94, 0x87ff, 0x1120, 0x2f00, 0x6082,
+ 0x7808, 0x6086, 0x6266, 0x636a, 0x646e, 0x6077, 0x0000, 0xb88c,
+ 0x8000, 0x9084, 0x00ff, 0xb88e, 0x8007, 0x607a, 0x607f, 0x0000,
0xa838, 0x608a, 0xa834, 0x608e, 0xa848, 0x60c6, 0xa844, 0x60ca,
- 0x009e, 0xb86c, 0x60ce, 0x60ab, 0x0036, 0x60af, 0x95d5, 0x60d7,
- 0x0000, 0x2001, 0x1837, 0x2004, 0x9084, 0x0028, 0x0128, 0x609f,
- 0x0000, 0x2001, 0x0092, 0x0048, 0x6028, 0xc0bd, 0x602a, 0x609f,
- 0x00ff, 0x6027, 0xffff, 0x2001, 0x00b2, 0x6016, 0x2009, 0x07d0,
- 0x080c, 0x878e, 0x003e, 0x004e, 0x005e, 0x006e, 0x00ce, 0x00de,
- 0x00ee, 0x00be, 0x0005, 0x00b6, 0x00e6, 0x00d6, 0x00c6, 0x0066,
- 0x0056, 0x0046, 0x0036, 0x2061, 0x0100, 0x2071, 0x1800, 0x7160,
- 0x7810, 0x2058, 0xb8a0, 0x2028, 0x76dc, 0xd6ac, 0x1168, 0x9582,
- 0x007e, 0x1250, 0x2500, 0x9094, 0xff80, 0x1130, 0x9080, 0x33b1,
- 0x2015, 0x9294, 0x00ff, 0x0020, 0xb910, 0xba14, 0x737c, 0x7480,
- 0x70dc, 0xd0ac, 0x1130, 0x9582, 0x007e, 0x1218, 0x9584, 0xff80,
- 0x0138, 0x9185, 0x0400, 0x6062, 0x6266, 0x636a, 0x646e, 0x0030,
- 0x6063, 0x0400, 0x6266, 0x606b, 0x0000, 0x616e, 0xb8b8, 0x6072,
- 0x6077, 0x0000, 0xb864, 0xd0a4, 0x0110, 0x6077, 0x0008, 0xb88c,
- 0x8000, 0x9084, 0x00ff, 0xb88e, 0x8007, 0x9085, 0x0020, 0x607a,
- 0x607f, 0x0000, 0x2b00, 0x6082, 0x6087, 0xffff, 0x7814, 0x0096,
- 0x2048, 0xa838, 0x608a, 0xa834, 0x608e, 0xa848, 0x60c6, 0xa844,
- 0x60ca, 0x009e, 0xb86c, 0x60ce, 0x60ab, 0x0036, 0x60af, 0x95d5,
- 0x60d7, 0x0000, 0xbac0, 0x629e, 0x00f6, 0x2079, 0x0140, 0x7803,
- 0x0000, 0x00fe, 0x2009, 0x0092, 0x6116, 0x2009, 0x07d0, 0x080c,
- 0x878e, 0x003e, 0x004e, 0x005e, 0x006e, 0x00ce, 0x00de, 0x00ee,
- 0x00be, 0x0005, 0x00b6, 0x0096, 0x00e6, 0x00d6, 0x00c6, 0x0056,
- 0x0046, 0x0036, 0x2061, 0x0100, 0x2071, 0x1800, 0x7810, 0x2058,
- 0xb8a0, 0x2028, 0xb910, 0xba14, 0x737c, 0x7480, 0x7820, 0x90be,
- 0x0006, 0x0904, 0xa42e, 0x90be, 0x000a, 0x1904, 0xa3ea, 0xb8c0,
- 0x609e, 0x7814, 0x2048, 0xa87c, 0xd0fc, 0x0558, 0xaf90, 0x9784,
- 0xff00, 0x9105, 0x6062, 0x873f, 0x9784, 0xff00, 0x0006, 0x7814,
- 0x2048, 0xa878, 0xc0fc, 0x9005, 0x000e, 0x1160, 0xaf94, 0x87ff,
- 0x0198, 0x2039, 0x0098, 0x9705, 0x6072, 0x7808, 0x6082, 0x2f00,
- 0x6086, 0x0038, 0x9185, 0x2200, 0x6062, 0x6073, 0x0129, 0x6077,
- 0x0000, 0xb8c0, 0x609e, 0x0050, 0x2039, 0x0029, 0x9705, 0x6072,
- 0x0cc0, 0x9185, 0x0200, 0x6062, 0x6073, 0x2029, 0xa87c, 0xd0fc,
- 0x0118, 0xaf94, 0x87ff, 0x1120, 0x2f00, 0x6082, 0x7808, 0x6086,
- 0x6266, 0x636a, 0x646e, 0x6077, 0x0000, 0xb88c, 0x8000, 0x9084,
- 0x00ff, 0xb88e, 0x8007, 0x607a, 0x607f, 0x0000, 0xa838, 0x608a,
- 0xa834, 0x608e, 0xa848, 0x60c6, 0xa844, 0x60ca, 0xb86c, 0x60ce,
- 0x60af, 0x95d5, 0x60d7, 0x0000, 0x080c, 0xad87, 0x2009, 0x07d0,
- 0x60c4, 0x9084, 0xfff0, 0x9005, 0x0110, 0x2009, 0x1b58, 0x080c,
- 0x878e, 0x003e, 0x004e, 0x005e, 0x00ce, 0x00de, 0x00ee, 0x009e,
- 0x00be, 0x0005, 0x7804, 0x9086, 0x0040, 0x0904, 0xa46a, 0x9185,
- 0x0100, 0x6062, 0x6266, 0x636a, 0x646e, 0x6073, 0x0809, 0x6077,
- 0x0008, 0x60af, 0x95d5, 0x60d7, 0x0000, 0xb88c, 0x8000, 0x9084,
- 0x00ff, 0xb88e, 0x8007, 0x607a, 0x607f, 0x0000, 0x2f00, 0x6082,
- 0x7808, 0x6086, 0x7814, 0x2048, 0xa838, 0x608a, 0xa834, 0x608e,
- 0xa848, 0x60c6, 0xa844, 0x60ca, 0xb86c, 0x60ce, 0xbac0, 0x629e,
- 0x080c, 0xad87, 0x2009, 0x07d0, 0x60c4, 0x9084, 0xfff0, 0x9005,
- 0x0110, 0x2009, 0x1b58, 0x080c, 0x878e, 0x003e, 0x004e, 0x005e,
- 0x00ce, 0x00de, 0x00ee, 0x009e, 0x00be, 0x0005, 0x7814, 0x2048,
- 0xa87c, 0x9084, 0x0003, 0x9086, 0x0002, 0x0904, 0xa486, 0x9185,
- 0x0100, 0x6062, 0x6266, 0x636a, 0x646e, 0x6073, 0x0880, 0x6077,
- 0x0008, 0xb88c, 0x8000, 0x9084, 0x00ff, 0xb88e, 0x8007, 0x607a,
- 0x7838, 0x607e, 0x2f00, 0x6086, 0x7808, 0x6082, 0xa890, 0x608a,
- 0xa88c, 0x608e, 0xa8b0, 0x60c6, 0xa8ac, 0x60ca, 0xa8ac, 0x7930,
- 0x9108, 0x7932, 0xa8b0, 0x792c, 0x9109, 0x792e, 0xb86c, 0x60ce,
- 0x60af, 0x95d5, 0x60d7, 0x0000, 0xbac0, 0x629e, 0x080c, 0xad64,
- 0x0804, 0xa41a, 0xb8cc, 0xd084, 0x0148, 0xb88c, 0x7814, 0x2048,
- 0xb88c, 0x784a, 0xa836, 0x2900, 0xa83a, 0xb046, 0x9185, 0x0600,
- 0x6062, 0x6266, 0x636a, 0x646e, 0x6073, 0x0829, 0x6077, 0x0000,
- 0x60af, 0x9575, 0x60d7, 0x0000, 0x0804, 0xa3fd, 0x9185, 0x0700,
- 0x6062, 0x6266, 0x636a, 0x646e, 0x7824, 0xd0cc, 0x7826, 0x0118,
- 0x6073, 0x0889, 0x0010, 0x6073, 0x0898, 0x6077, 0x0000, 0xb88c,
+ 0xb86c, 0x60ce, 0x60af, 0x95d5, 0x60d7, 0x0000, 0x080c, 0xada1,
+ 0x2009, 0x07d0, 0x60c4, 0x9084, 0xfff0, 0x9005, 0x0110, 0x2009,
+ 0x1b58, 0x080c, 0x8794, 0x003e, 0x004e, 0x005e, 0x00ce, 0x00de,
+ 0x00ee, 0x009e, 0x00be, 0x0005, 0x7804, 0x9086, 0x0040, 0x0904,
+ 0xa484, 0x9185, 0x0100, 0x6062, 0x6266, 0x636a, 0x646e, 0x6073,
+ 0x0809, 0x6077, 0x0008, 0x60af, 0x95d5, 0x60d7, 0x0000, 0xb88c,
0x8000, 0x9084, 0x00ff, 0xb88e, 0x8007, 0x607a, 0x607f, 0x0000,
- 0x2f00, 0x6086, 0x7808, 0x6082, 0xa838, 0x608a, 0xa834, 0x608e,
- 0xa848, 0x60c6, 0xa844, 0x60ca, 0xb86c, 0x60ce, 0x60af, 0x95d5,
- 0x60d7, 0x0000, 0xbac0, 0x629e, 0x7824, 0xd0cc, 0x0120, 0x080c,
- 0xad87, 0x0804, 0xa41a, 0x080c, 0xad64, 0x0804, 0xa41a, 0x7a10,
- 0x00b6, 0x2258, 0xba8c, 0x8210, 0x9294, 0x00ff, 0xba8e, 0x00be,
- 0x8217, 0x0005, 0x00d6, 0x2069, 0x19e9, 0x6843, 0x0001, 0x00de,
- 0x0005, 0x60a3, 0x0056, 0x60a7, 0x9575, 0x00f1, 0x080c, 0x8780,
- 0x0005, 0x0016, 0x2001, 0x180c, 0x200c, 0x9184, 0x0600, 0x9086,
- 0x0600, 0x0128, 0x0089, 0x080c, 0x8780, 0x001e, 0x0005, 0xc1e5,
- 0x2001, 0x180c, 0x2102, 0x2001, 0x19ea, 0x2003, 0x0000, 0x2001,
- 0x19f2, 0x2003, 0x0000, 0x0c88, 0x0006, 0x6014, 0x9084, 0x1804,
- 0x9085, 0x0009, 0x6016, 0x000e, 0x0005, 0x0016, 0x00c6, 0x0006,
- 0x2061, 0x0100, 0x61a4, 0x60a7, 0x95f5, 0x6014, 0x9084, 0x1804,
- 0x9085, 0x0008, 0x6016, 0x000e, 0xa001, 0xa001, 0xa001, 0x61a6,
- 0x00ce, 0x001e, 0x0005, 0x00c6, 0x00d6, 0x0016, 0x0026, 0x2061,
- 0x0100, 0x2069, 0x0140, 0x080c, 0x7563, 0x11c0, 0x2001, 0x1a05,
- 0x2004, 0x9005, 0x15d0, 0x080c, 0x7610, 0x1160, 0x2061, 0x0100,
- 0x6020, 0xd0b4, 0x1120, 0x6024, 0xd084, 0x090c, 0x0dc5, 0x080c,
- 0x8780, 0x0458, 0x00c6, 0x2061, 0x19e9, 0x00c8, 0x6904, 0x9194,
- 0x4000, 0x0540, 0x0811, 0x080c, 0x2d6b, 0x00c6, 0x2061, 0x19e9,
- 0x6128, 0x9192, 0x0008, 0x1258, 0x8108, 0x612a, 0x6124, 0x00ce,
- 0x81ff, 0x0198, 0x080c, 0x8780, 0x080c, 0xa4f4, 0x0070, 0x6124,
- 0x91e5, 0x0000, 0x0140, 0x080c, 0xedaa, 0x080c, 0x8789, 0x2009,
- 0x0014, 0x080c, 0xb166, 0x00ce, 0x0000, 0x002e, 0x001e, 0x00de,
- 0x00ce, 0x0005, 0x2001, 0x1a05, 0x2004, 0x9005, 0x1db0, 0x00c6,
- 0x2061, 0x19e9, 0x6128, 0x9192, 0x0003, 0x1e08, 0x8108, 0x612a,
- 0x00ce, 0x080c, 0x8780, 0x080c, 0x5fe0, 0x2009, 0x1846, 0x2114,
- 0x8210, 0x220a, 0x0c10, 0x0096, 0x00c6, 0x00d6, 0x00e6, 0x0016,
- 0x0026, 0x080c, 0x8796, 0x2071, 0x19e9, 0x713c, 0x81ff, 0x0904,
- 0xa5fd, 0x2061, 0x0100, 0x2069, 0x0140, 0x080c, 0x7563, 0x11e0,
- 0x0036, 0x2019, 0x0002, 0x080c, 0xa85d, 0x003e, 0x713c, 0x2160,
- 0x080c, 0xedaa, 0x2009, 0x004a, 0x6220, 0x9296, 0x0009, 0x1130,
- 0x6114, 0x2148, 0xa87b, 0x0006, 0x2009, 0x004a, 0x080c, 0xb166,
- 0x080c, 0x7610, 0x0804, 0xa5fd, 0x080c, 0xa609, 0x0904, 0xa5fd,
- 0x6904, 0xd1f4, 0x0904, 0xa604, 0x080c, 0x2d6b, 0x00c6, 0x703c,
- 0x9065, 0x090c, 0x0dc5, 0x6020, 0x00ce, 0x9086, 0x0006, 0x1528,
- 0x61c8, 0x60c4, 0x9105, 0x1508, 0x2009, 0x180c, 0x2104, 0xd0d4,
- 0x01e0, 0x6214, 0x9294, 0x1800, 0x1128, 0x6224, 0x9294, 0x0002,
- 0x1560, 0x0030, 0xc0d4, 0x200a, 0xd0cc, 0x0110, 0x080c, 0x2c9d,
- 0x6014, 0x9084, 0xe7fd, 0x9085, 0x0010, 0x6016, 0x703c, 0x2060,
- 0x2009, 0x0049, 0x080c, 0xb166, 0x00c0, 0x0036, 0x2019, 0x0001,
- 0x080c, 0xa85d, 0x003e, 0x713c, 0x2160, 0x080c, 0xedaa, 0x2009,
- 0x004a, 0x6220, 0x9296, 0x0009, 0x1130, 0x6114, 0x2148, 0xa87b,
- 0x0006, 0x2009, 0x004a, 0x080c, 0xb166, 0x002e, 0x001e, 0x00ee,
- 0x00de, 0x00ce, 0x009e, 0x0005, 0xd1ec, 0x1904, 0xa5b4, 0x0804,
- 0xa5b6, 0x00d6, 0x00c6, 0x0096, 0x703c, 0x9065, 0x090c, 0x0dc5,
- 0x2001, 0x0306, 0x200c, 0x9184, 0x0030, 0x0904, 0xa6bc, 0x9184,
- 0x0048, 0x9086, 0x0008, 0x1904, 0xa6bc, 0x2009, 0x0206, 0x2104,
- 0x2009, 0x0203, 0x210c, 0x9106, 0x1904, 0xa6bc, 0x2009, 0x022a,
- 0x2104, 0x2009, 0x022f, 0x210c, 0x9116, 0x9084, 0x03ff, 0x918c,
- 0x03ff, 0x9294, 0x0400, 0x0110, 0x9102, 0x0030, 0x2010, 0x2100,
- 0x9202, 0x2009, 0x0228, 0x9102, 0x9082, 0x0005, 0x0250, 0x2008,
- 0x2001, 0x013b, 0x2004, 0x8004, 0x8004, 0x8004, 0x9102, 0x1a04,
- 0xa6bc, 0x2009, 0x1a85, 0x2104, 0x8000, 0x0208, 0x200a, 0x2069,
- 0x0100, 0x6914, 0x918c, 0x1984, 0x918d, 0x0010, 0x6916, 0x69c8,
- 0x2011, 0x0020, 0x68c8, 0x9106, 0x15c0, 0x8211, 0x1dd8, 0x2001,
- 0x0306, 0x2003, 0x4800, 0x2001, 0x009a, 0x2003, 0x0004, 0x2001,
- 0x1a6a, 0x2003, 0x0000, 0x2001, 0x1a73, 0x2003, 0x0000, 0x6a88,
- 0x698c, 0x2200, 0x9105, 0x1170, 0x0096, 0x6014, 0x2048, 0xa87c,
- 0xc0dc, 0xa87e, 0xa880, 0xc0fc, 0xa882, 0x009e, 0x2c10, 0x080c,
- 0x1c01, 0x0040, 0x6014, 0x2048, 0xaa3a, 0xa936, 0x6ac4, 0x69c8,
- 0xa946, 0xaa4a, 0x0126, 0x00c6, 0x2091, 0x2400, 0x002e, 0x080c,
- 0x1c9a, 0x190c, 0x0dc5, 0x012e, 0x0090, 0x2009, 0x1a86, 0x2104,
- 0x8000, 0x0208, 0x200a, 0x69c8, 0x2011, 0x0020, 0x8211, 0x1df0,
- 0x68c8, 0x9106, 0x1dc0, 0x69c4, 0x68c8, 0x9105, 0x0160, 0x6824,
- 0xd08c, 0x0110, 0x6827, 0x0002, 0x7048, 0xc085, 0x704a, 0x0079,
- 0x7048, 0xc084, 0x704a, 0x2009, 0x07d0, 0x080c, 0x878e, 0x9006,
- 0x009e, 0x00ce, 0x00de, 0x0005, 0x9085, 0x0001, 0x0cc8, 0x0026,
- 0x00e6, 0x2071, 0x19e9, 0x7048, 0xd084, 0x01d8, 0x713c, 0x81ff,
- 0x01c0, 0x2071, 0x0100, 0x9188, 0x0008, 0x2114, 0x928e, 0x0006,
- 0x1138, 0x7014, 0x9084, 0x1984, 0x9085, 0x0012, 0x7016, 0x0048,
- 0x928e, 0x0009, 0x0db0, 0x7014, 0x9084, 0x1984, 0x9085, 0x0016,
- 0x7016, 0x00ee, 0x002e, 0x0005, 0x00b6, 0x00e6, 0x00d6, 0x00c6,
- 0x0066, 0x0056, 0x0046, 0x0006, 0x0126, 0x2091, 0x8000, 0x6010,
- 0x2058, 0xbca0, 0x2071, 0x19e9, 0x7018, 0x2058, 0x8bff, 0x0190,
- 0xb8a0, 0x9406, 0x0118, 0xb854, 0x2058, 0x0cc0, 0x6014, 0x0096,
- 0x2048, 0xac6c, 0xad70, 0xae78, 0x009e, 0x080c, 0x6849, 0x0110,
- 0x9085, 0x0001, 0x012e, 0x000e, 0x004e, 0x005e, 0x006e, 0x00ce,
- 0x00de, 0x00ee, 0x00be, 0x0005, 0x080c, 0x9ed5, 0x7003, 0x1200,
- 0x7838, 0x7012, 0x783c, 0x7016, 0x00c6, 0x7820, 0x9086, 0x0004,
- 0x1148, 0x7810, 0x9005, 0x0130, 0x00b6, 0x2058, 0xb810, 0xb914,
- 0x00be, 0x0020, 0x2061, 0x1800, 0x607c, 0x6180, 0x9084, 0x00ff,
- 0x700a, 0x710e, 0x00ce, 0x60c3, 0x002c, 0x0804, 0xa4d1, 0x080c,
- 0x9ed5, 0x7003, 0x0f00, 0x7808, 0xd09c, 0x0128, 0xb810, 0x9084,
- 0x00ff, 0x700a, 0xb814, 0x700e, 0x60c3, 0x0008, 0x0804, 0xa4d1,
- 0x0156, 0x080c, 0x9f20, 0x7003, 0x0200, 0x080c, 0x8812, 0x20a9,
- 0x0006, 0x2011, 0xffec, 0x2019, 0xffed, 0x9ef0, 0x0002, 0x2305,
- 0x2072, 0x8e70, 0x2205, 0x2072, 0x8e70, 0x9398, 0x0002, 0x9290,
- 0x0002, 0x1f04, 0xa757, 0x60c3, 0x001c, 0x015e, 0x0804, 0xa4d1,
- 0x0016, 0x0026, 0x080c, 0x9efc, 0x080c, 0x9f0e, 0x9e80, 0x0004,
- 0x20e9, 0x0000, 0x20a0, 0x7814, 0x0096, 0x2048, 0xa800, 0x2048,
- 0xa860, 0x20e0, 0xa85c, 0x9080, 0x0021, 0x2098, 0x009e, 0x7808,
- 0x9088, 0x0002, 0x21a8, 0x9192, 0x0010, 0x1250, 0x4003, 0x9080,
- 0x0004, 0x8003, 0x60c2, 0x080c, 0xa4d1, 0x002e, 0x001e, 0x0005,
- 0x20a9, 0x0010, 0x4003, 0x080c, 0xad8d, 0x20a1, 0x0240, 0x22a8,
- 0x4003, 0x0c68, 0x080c, 0x9ed5, 0x7003, 0x6200, 0x7808, 0x700e,
- 0x60c3, 0x0008, 0x0804, 0xa4d1, 0x0016, 0x0026, 0x080c, 0x9ed5,
- 0x20e9, 0x0000, 0x20a1, 0x024c, 0x7814, 0x0096, 0x2048, 0xa800,
- 0x2048, 0xa860, 0x20e0, 0xa85c, 0x9080, 0x0023, 0x2098, 0x009e,
- 0x7808, 0x9088, 0x0002, 0x21a8, 0x4003, 0x8003, 0x60c2, 0x080c,
- 0xa4d1, 0x002e, 0x001e, 0x0005, 0x00e6, 0x00c6, 0x0006, 0x0126,
- 0x2091, 0x8000, 0x2071, 0x19e9, 0x700c, 0x2060, 0x8cff, 0x0178,
- 0x080c, 0xd047, 0x1110, 0x080c, 0xbacb, 0x600c, 0x0006, 0x080c,
- 0xd2b3, 0x080c, 0xb0e7, 0x080c, 0xa905, 0x00ce, 0x0c78, 0x2c00,
- 0x700e, 0x700a, 0x012e, 0x000e, 0x00ce, 0x00ee, 0x0005, 0x0126,
+ 0x2f00, 0x6082, 0x7808, 0x6086, 0x7814, 0x2048, 0xa838, 0x608a,
+ 0xa834, 0x608e, 0xa848, 0x60c6, 0xa844, 0x60ca, 0xb86c, 0x60ce,
+ 0xbac0, 0x629e, 0x080c, 0xada1, 0x2009, 0x07d0, 0x60c4, 0x9084,
+ 0xfff0, 0x9005, 0x0110, 0x2009, 0x1b58, 0x080c, 0x8794, 0x003e,
+ 0x004e, 0x005e, 0x00ce, 0x00de, 0x00ee, 0x009e, 0x00be, 0x0005,
+ 0x7814, 0x2048, 0xa87c, 0x9084, 0x0003, 0x9086, 0x0002, 0x0904,
+ 0xa4a0, 0x9185, 0x0100, 0x6062, 0x6266, 0x636a, 0x646e, 0x6073,
+ 0x0880, 0x6077, 0x0008, 0xb88c, 0x8000, 0x9084, 0x00ff, 0xb88e,
+ 0x8007, 0x607a, 0x7838, 0x607e, 0x2f00, 0x6086, 0x7808, 0x6082,
+ 0xa890, 0x608a, 0xa88c, 0x608e, 0xa8b0, 0x60c6, 0xa8ac, 0x60ca,
+ 0xa8ac, 0x7930, 0x9108, 0x7932, 0xa8b0, 0x792c, 0x9109, 0x792e,
+ 0xb86c, 0x60ce, 0x60af, 0x95d5, 0x60d7, 0x0000, 0xbac0, 0x629e,
+ 0x080c, 0xad7e, 0x0804, 0xa434, 0xb8cc, 0xd084, 0x0148, 0xb88c,
+ 0x7814, 0x2048, 0xb88c, 0x784a, 0xa836, 0x2900, 0xa83a, 0xb046,
+ 0x9185, 0x0600, 0x6062, 0x6266, 0x636a, 0x646e, 0x6073, 0x0829,
+ 0x6077, 0x0000, 0x60af, 0x9575, 0x60d7, 0x0000, 0x0804, 0xa417,
+ 0x9185, 0x0700, 0x6062, 0x6266, 0x636a, 0x646e, 0x7824, 0xd0cc,
+ 0x7826, 0x0118, 0x6073, 0x0889, 0x0010, 0x6073, 0x0898, 0x6077,
+ 0x0000, 0xb88c, 0x8000, 0x9084, 0x00ff, 0xb88e, 0x8007, 0x607a,
+ 0x607f, 0x0000, 0x2f00, 0x6086, 0x7808, 0x6082, 0xa838, 0x608a,
+ 0xa834, 0x608e, 0xa848, 0x60c6, 0xa844, 0x60ca, 0xb86c, 0x60ce,
+ 0x60af, 0x95d5, 0x60d7, 0x0000, 0xbac0, 0x629e, 0x7824, 0xd0cc,
+ 0x0120, 0x080c, 0xada1, 0x0804, 0xa434, 0x080c, 0xad7e, 0x0804,
+ 0xa434, 0x7a10, 0x00b6, 0x2258, 0xba8c, 0x8210, 0x9294, 0x00ff,
+ 0xba8e, 0x00be, 0x8217, 0x0005, 0x00d6, 0x2069, 0x19e9, 0x6843,
+ 0x0001, 0x00de, 0x0005, 0x60a3, 0x0056, 0x60a7, 0x9575, 0x00f1,
+ 0x080c, 0x8786, 0x0005, 0x0016, 0x2001, 0x180c, 0x200c, 0x9184,
+ 0x0600, 0x9086, 0x0600, 0x0128, 0x0089, 0x080c, 0x8786, 0x001e,
+ 0x0005, 0xc1e5, 0x2001, 0x180c, 0x2102, 0x2001, 0x19ea, 0x2003,
+ 0x0000, 0x2001, 0x19f2, 0x2003, 0x0000, 0x0c88, 0x0006, 0x6014,
+ 0x9084, 0x1804, 0x9085, 0x0009, 0x6016, 0x000e, 0x0005, 0x0016,
+ 0x00c6, 0x0006, 0x2061, 0x0100, 0x61a4, 0x60a7, 0x95f5, 0x6014,
+ 0x9084, 0x1804, 0x9085, 0x0008, 0x6016, 0x000e, 0xa001, 0xa001,
+ 0xa001, 0x61a6, 0x00ce, 0x001e, 0x0005, 0x00c6, 0x00d6, 0x0016,
+ 0x0026, 0x2061, 0x0100, 0x2069, 0x0140, 0x080c, 0x7569, 0x11c0,
+ 0x2001, 0x1a05, 0x2004, 0x9005, 0x15d0, 0x080c, 0x7616, 0x1160,
+ 0x2061, 0x0100, 0x6020, 0xd0b4, 0x1120, 0x6024, 0xd084, 0x090c,
+ 0x0dc5, 0x080c, 0x8786, 0x0458, 0x00c6, 0x2061, 0x19e9, 0x00c8,
+ 0x6904, 0x9194, 0x4000, 0x0540, 0x0811, 0x080c, 0x2d62, 0x00c6,
+ 0x2061, 0x19e9, 0x6128, 0x9192, 0x0008, 0x1258, 0x8108, 0x612a,
+ 0x6124, 0x00ce, 0x81ff, 0x0198, 0x080c, 0x8786, 0x080c, 0xa50e,
+ 0x0070, 0x6124, 0x91e5, 0x0000, 0x0140, 0x080c, 0xee0f, 0x080c,
+ 0x878f, 0x2009, 0x0014, 0x080c, 0xb180, 0x00ce, 0x0000, 0x002e,
+ 0x001e, 0x00de, 0x00ce, 0x0005, 0x2001, 0x1a05, 0x2004, 0x9005,
+ 0x1db0, 0x00c6, 0x2061, 0x19e9, 0x6128, 0x9192, 0x0003, 0x1e08,
+ 0x8108, 0x612a, 0x00ce, 0x080c, 0x8786, 0x080c, 0x5fe6, 0x2009,
+ 0x1846, 0x2114, 0x8210, 0x220a, 0x0c10, 0x0096, 0x00c6, 0x00d6,
+ 0x00e6, 0x0016, 0x0026, 0x080c, 0x879c, 0x2071, 0x19e9, 0x713c,
+ 0x81ff, 0x0904, 0xa617, 0x2061, 0x0100, 0x2069, 0x0140, 0x080c,
+ 0x7569, 0x11e0, 0x0036, 0x2019, 0x0002, 0x080c, 0xa877, 0x003e,
+ 0x713c, 0x2160, 0x080c, 0xee0f, 0x2009, 0x004a, 0x6220, 0x9296,
+ 0x0009, 0x1130, 0x6114, 0x2148, 0xa87b, 0x0006, 0x2009, 0x004a,
+ 0x080c, 0xb180, 0x080c, 0x7616, 0x0804, 0xa617, 0x080c, 0xa623,
+ 0x0904, 0xa617, 0x6904, 0xd1f4, 0x0904, 0xa61e, 0x080c, 0x2d62,
+ 0x00c6, 0x703c, 0x9065, 0x090c, 0x0dc5, 0x6020, 0x00ce, 0x9086,
+ 0x0006, 0x1528, 0x61c8, 0x60c4, 0x9105, 0x1508, 0x2009, 0x180c,
+ 0x2104, 0xd0d4, 0x01e0, 0x6214, 0x9294, 0x1800, 0x1128, 0x6224,
+ 0x9294, 0x0002, 0x1560, 0x0030, 0xc0d4, 0x200a, 0xd0cc, 0x0110,
+ 0x080c, 0x2c94, 0x6014, 0x9084, 0xe7fd, 0x9085, 0x0010, 0x6016,
+ 0x703c, 0x2060, 0x2009, 0x0049, 0x080c, 0xb180, 0x00c0, 0x0036,
+ 0x2019, 0x0001, 0x080c, 0xa877, 0x003e, 0x713c, 0x2160, 0x080c,
+ 0xee0f, 0x2009, 0x004a, 0x6220, 0x9296, 0x0009, 0x1130, 0x6114,
+ 0x2148, 0xa87b, 0x0006, 0x2009, 0x004a, 0x080c, 0xb180, 0x002e,
+ 0x001e, 0x00ee, 0x00de, 0x00ce, 0x009e, 0x0005, 0xd1ec, 0x1904,
+ 0xa5ce, 0x0804, 0xa5d0, 0x00d6, 0x00c6, 0x0096, 0x703c, 0x9065,
+ 0x090c, 0x0dc5, 0x2001, 0x0306, 0x200c, 0x9184, 0x0030, 0x0904,
+ 0xa6d6, 0x9184, 0x0048, 0x9086, 0x0008, 0x1904, 0xa6d6, 0x2009,
+ 0x0206, 0x2104, 0x2009, 0x0203, 0x210c, 0x9106, 0x1904, 0xa6d6,
+ 0x2009, 0x022a, 0x2104, 0x2009, 0x022f, 0x210c, 0x9116, 0x9084,
+ 0x03ff, 0x918c, 0x03ff, 0x9294, 0x0400, 0x0110, 0x9102, 0x0030,
+ 0x2010, 0x2100, 0x9202, 0x2009, 0x0228, 0x9102, 0x9082, 0x0005,
+ 0x0250, 0x2008, 0x2001, 0x013b, 0x2004, 0x8004, 0x8004, 0x8004,
+ 0x9102, 0x1a04, 0xa6d6, 0x2009, 0x1a85, 0x2104, 0x8000, 0x0208,
+ 0x200a, 0x2069, 0x0100, 0x6914, 0x918c, 0x1984, 0x918d, 0x0010,
+ 0x6916, 0x69c8, 0x2011, 0x0020, 0x68c8, 0x9106, 0x15c0, 0x8211,
+ 0x1dd8, 0x2001, 0x0306, 0x2003, 0x4800, 0x2001, 0x009a, 0x2003,
+ 0x0004, 0x2001, 0x1a6a, 0x2003, 0x0000, 0x2001, 0x1a73, 0x2003,
+ 0x0000, 0x6a88, 0x698c, 0x2200, 0x9105, 0x1170, 0x0096, 0x6014,
+ 0x2048, 0xa87c, 0xc0dc, 0xa87e, 0xa880, 0xc0fc, 0xa882, 0x009e,
+ 0x2c10, 0x080c, 0x1c09, 0x0040, 0x6014, 0x2048, 0xaa3a, 0xa936,
+ 0x6ac4, 0x69c8, 0xa946, 0xaa4a, 0x0126, 0x00c6, 0x2091, 0x2400,
+ 0x002e, 0x080c, 0x1ca2, 0x190c, 0x0dc5, 0x012e, 0x0090, 0x2009,
+ 0x1a86, 0x2104, 0x8000, 0x0208, 0x200a, 0x69c8, 0x2011, 0x0020,
+ 0x8211, 0x1df0, 0x68c8, 0x9106, 0x1dc0, 0x69c4, 0x68c8, 0x9105,
+ 0x0160, 0x6824, 0xd08c, 0x0110, 0x6827, 0x0002, 0x7048, 0xc085,
+ 0x704a, 0x0079, 0x7048, 0xc084, 0x704a, 0x2009, 0x07d0, 0x080c,
+ 0x8794, 0x9006, 0x009e, 0x00ce, 0x00de, 0x0005, 0x9085, 0x0001,
+ 0x0cc8, 0x0026, 0x00e6, 0x2071, 0x19e9, 0x7048, 0xd084, 0x01d8,
+ 0x713c, 0x81ff, 0x01c0, 0x2071, 0x0100, 0x9188, 0x0008, 0x2114,
+ 0x928e, 0x0006, 0x1138, 0x7014, 0x9084, 0x1984, 0x9085, 0x0012,
+ 0x7016, 0x0048, 0x928e, 0x0009, 0x0db0, 0x7014, 0x9084, 0x1984,
+ 0x9085, 0x0016, 0x7016, 0x00ee, 0x002e, 0x0005, 0x00b6, 0x00e6,
+ 0x00d6, 0x00c6, 0x0066, 0x0056, 0x0046, 0x0006, 0x0126, 0x2091,
+ 0x8000, 0x6010, 0x2058, 0xbca0, 0x2071, 0x19e9, 0x7018, 0x2058,
+ 0x8bff, 0x0190, 0xb8a0, 0x9406, 0x0118, 0xb854, 0x2058, 0x0cc0,
+ 0x6014, 0x0096, 0x2048, 0xac6c, 0xad70, 0xae78, 0x009e, 0x080c,
+ 0x684f, 0x0110, 0x9085, 0x0001, 0x012e, 0x000e, 0x004e, 0x005e,
+ 0x006e, 0x00ce, 0x00de, 0x00ee, 0x00be, 0x0005, 0x080c, 0x9eef,
+ 0x7003, 0x1200, 0x7838, 0x7012, 0x783c, 0x7016, 0x00c6, 0x7820,
+ 0x9086, 0x0004, 0x1148, 0x7810, 0x9005, 0x0130, 0x00b6, 0x2058,
+ 0xb810, 0xb914, 0x00be, 0x0020, 0x2061, 0x1800, 0x607c, 0x6180,
+ 0x9084, 0x00ff, 0x700a, 0x710e, 0x00ce, 0x60c3, 0x002c, 0x0804,
+ 0xa4eb, 0x080c, 0x9eef, 0x7003, 0x0f00, 0x7808, 0xd09c, 0x0128,
+ 0xb810, 0x9084, 0x00ff, 0x700a, 0xb814, 0x700e, 0x60c3, 0x0008,
+ 0x0804, 0xa4eb, 0x0156, 0x080c, 0x9f3a, 0x7003, 0x0200, 0x080c,
+ 0x8818, 0x20a9, 0x0006, 0x2011, 0xffec, 0x2019, 0xffed, 0x9ef0,
+ 0x0002, 0x2305, 0x2072, 0x8e70, 0x2205, 0x2072, 0x8e70, 0x9398,
+ 0x0002, 0x9290, 0x0002, 0x1f04, 0xa771, 0x60c3, 0x001c, 0x015e,
+ 0x0804, 0xa4eb, 0x0016, 0x0026, 0x080c, 0x9f16, 0x080c, 0x9f28,
+ 0x9e80, 0x0004, 0x20e9, 0x0000, 0x20a0, 0x7814, 0x0096, 0x2048,
+ 0xa800, 0x2048, 0xa860, 0x20e0, 0xa85c, 0x9080, 0x0021, 0x2098,
+ 0x009e, 0x7808, 0x9088, 0x0002, 0x21a8, 0x9192, 0x0010, 0x1250,
+ 0x4003, 0x9080, 0x0004, 0x8003, 0x60c2, 0x080c, 0xa4eb, 0x002e,
+ 0x001e, 0x0005, 0x20a9, 0x0010, 0x4003, 0x080c, 0xada7, 0x20a1,
+ 0x0240, 0x22a8, 0x4003, 0x0c68, 0x080c, 0x9eef, 0x7003, 0x6200,
+ 0x7808, 0x700e, 0x60c3, 0x0008, 0x0804, 0xa4eb, 0x0016, 0x0026,
+ 0x080c, 0x9eef, 0x20e9, 0x0000, 0x20a1, 0x024c, 0x7814, 0x0096,
+ 0x2048, 0xa800, 0x2048, 0xa860, 0x20e0, 0xa85c, 0x9080, 0x0023,
+ 0x2098, 0x009e, 0x7808, 0x9088, 0x0002, 0x21a8, 0x4003, 0x8003,
+ 0x60c2, 0x080c, 0xa4eb, 0x002e, 0x001e, 0x0005, 0x00e6, 0x00c6,
+ 0x0006, 0x0126, 0x2091, 0x8000, 0x2071, 0x19e9, 0x700c, 0x2060,
+ 0x8cff, 0x0178, 0x080c, 0xd05e, 0x1110, 0x080c, 0xbae2, 0x600c,
+ 0x0006, 0x080c, 0xd2ca, 0x080c, 0xb101, 0x080c, 0xa91f, 0x00ce,
+ 0x0c78, 0x2c00, 0x700e, 0x700a, 0x012e, 0x000e, 0x00ce, 0x00ee,
+ 0x0005, 0x0126, 0x0156, 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x0066,
+ 0x0026, 0x0016, 0x0006, 0x2091, 0x8000, 0x2001, 0x180c, 0x200c,
+ 0x918c, 0xe7ff, 0x2102, 0x2069, 0x0100, 0x2079, 0x0140, 0x2071,
+ 0x19e9, 0x7024, 0x2060, 0x8cff, 0x01f8, 0x080c, 0xa517, 0x6ac0,
+ 0x68c3, 0x0000, 0x080c, 0x878f, 0x00c6, 0x2061, 0x0100, 0x080c,
+ 0xaef8, 0x00ce, 0x20a9, 0x01f4, 0x0461, 0x2009, 0x0013, 0x080c,
+ 0xb180, 0x000e, 0x001e, 0x002e, 0x006e, 0x00ce, 0x00de, 0x00ee,
+ 0x00fe, 0x015e, 0x012e, 0x0005, 0x2001, 0x1800, 0x2004, 0x9096,
+ 0x0001, 0x0d78, 0x9096, 0x0004, 0x0d60, 0x080c, 0x878f, 0x6814,
+ 0x9084, 0x0001, 0x0110, 0x68a7, 0x95f5, 0x6817, 0x0008, 0x68c3,
+ 0x0000, 0x2011, 0x5f90, 0x080c, 0x8709, 0x20a9, 0x01f4, 0x0009,
+ 0x08c0, 0x6824, 0xd094, 0x0140, 0x6827, 0x0004, 0x7804, 0x9084,
+ 0x4000, 0x190c, 0x2d62, 0x0090, 0xd084, 0x0118, 0x6827, 0x0001,
+ 0x0010, 0x1f04, 0xa859, 0x7804, 0x9084, 0x1000, 0x0138, 0x2001,
+ 0x0100, 0x080c, 0x2d52, 0x9006, 0x080c, 0x2d52, 0x0005, 0x0126,
0x0156, 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x0066, 0x0026, 0x0016,
- 0x0006, 0x2091, 0x8000, 0x2001, 0x180c, 0x200c, 0x918c, 0xe7ff,
- 0x2102, 0x2069, 0x0100, 0x2079, 0x0140, 0x2071, 0x19e9, 0x7024,
- 0x2060, 0x8cff, 0x01f8, 0x080c, 0xa4fd, 0x6ac0, 0x68c3, 0x0000,
- 0x080c, 0x8789, 0x00c6, 0x2061, 0x0100, 0x080c, 0xaede, 0x00ce,
- 0x20a9, 0x01f4, 0x0461, 0x2009, 0x0013, 0x080c, 0xb166, 0x000e,
- 0x001e, 0x002e, 0x006e, 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x015e,
- 0x012e, 0x0005, 0x2001, 0x1800, 0x2004, 0x9096, 0x0001, 0x0d78,
- 0x9096, 0x0004, 0x0d60, 0x080c, 0x8789, 0x6814, 0x9084, 0x0001,
- 0x0110, 0x68a7, 0x95f5, 0x6817, 0x0008, 0x68c3, 0x0000, 0x2011,
- 0x5f8a, 0x080c, 0x8703, 0x20a9, 0x01f4, 0x0009, 0x08c0, 0x6824,
- 0xd094, 0x0140, 0x6827, 0x0004, 0x7804, 0x9084, 0x4000, 0x190c,
- 0x2d6b, 0x0090, 0xd084, 0x0118, 0x6827, 0x0001, 0x0010, 0x1f04,
- 0xa83f, 0x7804, 0x9084, 0x1000, 0x0138, 0x2001, 0x0100, 0x080c,
- 0x2d5b, 0x9006, 0x080c, 0x2d5b, 0x0005, 0x0126, 0x0156, 0x00f6,
- 0x00e6, 0x00d6, 0x00c6, 0x0066, 0x0026, 0x0016, 0x0006, 0x2091,
- 0x8000, 0x2001, 0x180c, 0x200c, 0x918c, 0xdbff, 0x2102, 0x2069,
- 0x0100, 0x2079, 0x0140, 0x2071, 0x19e9, 0x703c, 0x2060, 0x8cff,
- 0x0904, 0xa8c8, 0x9386, 0x0002, 0x1128, 0x6814, 0x9084, 0x0002,
- 0x0904, 0xa8c8, 0x68af, 0x95f5, 0x6817, 0x0010, 0x2009, 0x00fa,
- 0x8109, 0x1df0, 0x69c6, 0x68cb, 0x0008, 0x080c, 0x8796, 0x080c,
- 0x2052, 0x2001, 0x0032, 0x6920, 0xd1bc, 0x0130, 0x8001, 0x1dd8,
- 0x692c, 0x918d, 0x0008, 0x692e, 0x20a9, 0x03e8, 0x6824, 0xd094,
- 0x0140, 0x6827, 0x0004, 0x7804, 0x9084, 0x4000, 0x190c, 0x2d6b,
- 0x0090, 0xd08c, 0x0118, 0x6827, 0x0002, 0x0010, 0x1f04, 0xa89e,
- 0x7804, 0x9084, 0x1000, 0x0138, 0x2001, 0x0100, 0x080c, 0x2d5b,
- 0x9006, 0x080c, 0x2d5b, 0x6827, 0x4000, 0x6824, 0x83ff, 0x1140,
- 0x2009, 0x0049, 0x6020, 0x9086, 0x0009, 0x0110, 0x080c, 0xb166,
- 0x000e, 0x001e, 0x002e, 0x006e, 0x00ce, 0x00de, 0x00ee, 0x00fe,
- 0x015e, 0x012e, 0x0005, 0x00d6, 0x0126, 0x2091, 0x8000, 0x2069,
- 0x19e9, 0x6a06, 0x012e, 0x00de, 0x0005, 0x00d6, 0x0126, 0x2091,
- 0x8000, 0x2069, 0x19e9, 0x6a32, 0x012e, 0x00de, 0x0005, 0x080c,
- 0xa098, 0x7047, 0x1000, 0x0098, 0x080c, 0xa098, 0x7047, 0x4000,
- 0x0070, 0x080c, 0xa098, 0x7047, 0x2000, 0x0048, 0x080c, 0xa098,
- 0x7047, 0x0400, 0x0020, 0x080c, 0xa098, 0x7047, 0x0200, 0x7854,
- 0x7032, 0x60c3, 0x0020, 0x0804, 0xa4d1, 0x00e6, 0x2071, 0x19e9,
- 0x7020, 0x9005, 0x0110, 0x8001, 0x7022, 0x00ee, 0x0005, 0x00f6,
- 0x00e6, 0x00d6, 0x00c6, 0x0076, 0x0066, 0x0006, 0x0126, 0x2091,
- 0x8000, 0x2071, 0x19e9, 0x7614, 0x2660, 0x2678, 0x2039, 0x0001,
- 0x87ff, 0x0904, 0xa9aa, 0x8cff, 0x0904, 0xa9aa, 0x6020, 0x9086,
- 0x0006, 0x1904, 0xa9a5, 0x88ff, 0x0138, 0x2800, 0x9c06, 0x1904,
- 0xa9a5, 0x2039, 0x0000, 0x0050, 0x6010, 0x9b06, 0x1904, 0xa9a5,
- 0x85ff, 0x0120, 0x6054, 0x9106, 0x1904, 0xa9a5, 0x7024, 0x9c06,
- 0x15b0, 0x2069, 0x0100, 0x68c0, 0x9005, 0x1160, 0x6824, 0xd084,
- 0x0148, 0x6827, 0x0001, 0x080c, 0x8789, 0x080c, 0xaa2f, 0x7027,
- 0x0000, 0x0428, 0x080c, 0x8789, 0x6820, 0xd0b4, 0x0110, 0x68a7,
- 0x95f5, 0x6817, 0x0008, 0x68c3, 0x0000, 0x080c, 0xaa2f, 0x7027,
- 0x0000, 0x0036, 0x2069, 0x0140, 0x6b04, 0x9384, 0x1000, 0x0138,
- 0x2001, 0x0100, 0x080c, 0x2d5b, 0x9006, 0x080c, 0x2d5b, 0x2069,
- 0x0100, 0x6824, 0xd084, 0x0110, 0x6827, 0x0001, 0x003e, 0x7014,
- 0x9c36, 0x1110, 0x660c, 0x7616, 0x7010, 0x9c36, 0x1140, 0x2c00,
- 0x9f36, 0x0118, 0x2f00, 0x7012, 0x0010, 0x7013, 0x0000, 0x660c,
- 0x0066, 0x2c00, 0x9f06, 0x0110, 0x7e0e, 0x0008, 0x2678, 0x89ff,
- 0x1168, 0x600f, 0x0000, 0x6014, 0x0096, 0x2048, 0x080c, 0xce3d,
- 0x0110, 0x080c, 0xe8e3, 0x009e, 0x080c, 0xb11a, 0x080c, 0xa905,
- 0x88ff, 0x1190, 0x00ce, 0x0804, 0xa920, 0x2c78, 0x600c, 0x2060,
- 0x0804, 0xa920, 0x9006, 0x012e, 0x000e, 0x006e, 0x007e, 0x00ce,
- 0x00de, 0x00ee, 0x00fe, 0x0005, 0x601b, 0x0000, 0x00ce, 0x98c5,
- 0x0001, 0x0c88, 0x00f6, 0x00e6, 0x00d6, 0x0096, 0x00c6, 0x0066,
- 0x0026, 0x0006, 0x0126, 0x2091, 0x8000, 0x2071, 0x19e9, 0x7638,
- 0x2660, 0x2678, 0x8cff, 0x0904, 0xaa1e, 0x6020, 0x9086, 0x0006,
- 0x1904, 0xaa19, 0x87ff, 0x0128, 0x2700, 0x9c06, 0x1904, 0xaa19,
- 0x0040, 0x6010, 0x9b06, 0x15e8, 0x85ff, 0x0118, 0x6054, 0x9106,
- 0x15c0, 0x703c, 0x9c06, 0x1168, 0x0036, 0x2019, 0x0001, 0x080c,
- 0xa85d, 0x7033, 0x0000, 0x9006, 0x703e, 0x7042, 0x7046, 0x704a,
- 0x003e, 0x7038, 0x9c36, 0x1110, 0x660c, 0x763a, 0x7034, 0x9c36,
- 0x1140, 0x2c00, 0x9f36, 0x0118, 0x2f00, 0x7036, 0x0010, 0x7037,
+ 0x0006, 0x2091, 0x8000, 0x2001, 0x180c, 0x200c, 0x918c, 0xdbff,
+ 0x2102, 0x2069, 0x0100, 0x2079, 0x0140, 0x2071, 0x19e9, 0x703c,
+ 0x2060, 0x8cff, 0x0904, 0xa8e2, 0x9386, 0x0002, 0x1128, 0x6814,
+ 0x9084, 0x0002, 0x0904, 0xa8e2, 0x68af, 0x95f5, 0x6817, 0x0010,
+ 0x2009, 0x00fa, 0x8109, 0x1df0, 0x69c6, 0x68cb, 0x0008, 0x080c,
+ 0x879c, 0x080c, 0x205a, 0x2001, 0x0032, 0x6920, 0xd1bc, 0x0130,
+ 0x8001, 0x1dd8, 0x692c, 0x918d, 0x0008, 0x692e, 0x20a9, 0x03e8,
+ 0x6824, 0xd094, 0x0140, 0x6827, 0x0004, 0x7804, 0x9084, 0x4000,
+ 0x190c, 0x2d62, 0x0090, 0xd08c, 0x0118, 0x6827, 0x0002, 0x0010,
+ 0x1f04, 0xa8b8, 0x7804, 0x9084, 0x1000, 0x0138, 0x2001, 0x0100,
+ 0x080c, 0x2d52, 0x9006, 0x080c, 0x2d52, 0x6827, 0x4000, 0x6824,
+ 0x83ff, 0x1140, 0x2009, 0x0049, 0x6020, 0x9086, 0x0009, 0x0110,
+ 0x080c, 0xb180, 0x000e, 0x001e, 0x002e, 0x006e, 0x00ce, 0x00de,
+ 0x00ee, 0x00fe, 0x015e, 0x012e, 0x0005, 0x00d6, 0x0126, 0x2091,
+ 0x8000, 0x2069, 0x19e9, 0x6a06, 0x012e, 0x00de, 0x0005, 0x00d6,
+ 0x0126, 0x2091, 0x8000, 0x2069, 0x19e9, 0x6a32, 0x012e, 0x00de,
+ 0x0005, 0x080c, 0xa0b2, 0x7047, 0x1000, 0x0098, 0x080c, 0xa0b2,
+ 0x7047, 0x4000, 0x0070, 0x080c, 0xa0b2, 0x7047, 0x2000, 0x0048,
+ 0x080c, 0xa0b2, 0x7047, 0x0400, 0x0020, 0x080c, 0xa0b2, 0x7047,
+ 0x0200, 0x7854, 0x7032, 0x60c3, 0x0020, 0x0804, 0xa4eb, 0x00e6,
+ 0x2071, 0x19e9, 0x7020, 0x9005, 0x0110, 0x8001, 0x7022, 0x00ee,
+ 0x0005, 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x0076, 0x0066, 0x0006,
+ 0x0126, 0x2091, 0x8000, 0x2071, 0x19e9, 0x7614, 0x2660, 0x2678,
+ 0x2039, 0x0001, 0x87ff, 0x0904, 0xa9c4, 0x8cff, 0x0904, 0xa9c4,
+ 0x6020, 0x9086, 0x0006, 0x1904, 0xa9bf, 0x88ff, 0x0138, 0x2800,
+ 0x9c06, 0x1904, 0xa9bf, 0x2039, 0x0000, 0x0050, 0x6010, 0x9b06,
+ 0x1904, 0xa9bf, 0x85ff, 0x0120, 0x6054, 0x9106, 0x1904, 0xa9bf,
+ 0x7024, 0x9c06, 0x15b0, 0x2069, 0x0100, 0x68c0, 0x9005, 0x1160,
+ 0x6824, 0xd084, 0x0148, 0x6827, 0x0001, 0x080c, 0x878f, 0x080c,
+ 0xaa49, 0x7027, 0x0000, 0x0428, 0x080c, 0x878f, 0x6820, 0xd0b4,
+ 0x0110, 0x68a7, 0x95f5, 0x6817, 0x0008, 0x68c3, 0x0000, 0x080c,
+ 0xaa49, 0x7027, 0x0000, 0x0036, 0x2069, 0x0140, 0x6b04, 0x9384,
+ 0x1000, 0x0138, 0x2001, 0x0100, 0x080c, 0x2d52, 0x9006, 0x080c,
+ 0x2d52, 0x2069, 0x0100, 0x6824, 0xd084, 0x0110, 0x6827, 0x0001,
+ 0x003e, 0x7014, 0x9c36, 0x1110, 0x660c, 0x7616, 0x7010, 0x9c36,
+ 0x1140, 0x2c00, 0x9f36, 0x0118, 0x2f00, 0x7012, 0x0010, 0x7013,
0x0000, 0x660c, 0x0066, 0x2c00, 0x9f06, 0x0110, 0x7e0e, 0x0008,
- 0x2678, 0x600f, 0x0000, 0x6014, 0x2048, 0x080c, 0xce3d, 0x0110,
- 0x080c, 0xe8e3, 0x080c, 0xb11a, 0x87ff, 0x1198, 0x00ce, 0x0804,
- 0xa9ca, 0x2c78, 0x600c, 0x2060, 0x0804, 0xa9ca, 0x9006, 0x012e,
- 0x000e, 0x002e, 0x006e, 0x00ce, 0x009e, 0x00de, 0x00ee, 0x00fe,
- 0x0005, 0x601b, 0x0000, 0x00ce, 0x97bd, 0x0001, 0x0c80, 0x00e6,
- 0x2071, 0x19e9, 0x2001, 0x1800, 0x2004, 0x9086, 0x0002, 0x1118,
- 0x7007, 0x0005, 0x0010, 0x7007, 0x0000, 0x00ee, 0x0005, 0x00f6,
- 0x00e6, 0x00c6, 0x0066, 0x0026, 0x0006, 0x0126, 0x2091, 0x8000,
- 0x2071, 0x19e9, 0x2c10, 0x7638, 0x2660, 0x2678, 0x8cff, 0x0540,
- 0x2200, 0x9c06, 0x1508, 0x7038, 0x9c36, 0x1110, 0x660c, 0x763a,
+ 0x2678, 0x89ff, 0x1168, 0x600f, 0x0000, 0x6014, 0x0096, 0x2048,
+ 0x080c, 0xce54, 0x0110, 0x080c, 0xe948, 0x009e, 0x080c, 0xb134,
+ 0x080c, 0xa91f, 0x88ff, 0x1190, 0x00ce, 0x0804, 0xa93a, 0x2c78,
+ 0x600c, 0x2060, 0x0804, 0xa93a, 0x9006, 0x012e, 0x000e, 0x006e,
+ 0x007e, 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x0005, 0x601b, 0x0000,
+ 0x00ce, 0x98c5, 0x0001, 0x0c88, 0x00f6, 0x00e6, 0x00d6, 0x0096,
+ 0x00c6, 0x0066, 0x0026, 0x0006, 0x0126, 0x2091, 0x8000, 0x2071,
+ 0x19e9, 0x7638, 0x2660, 0x2678, 0x8cff, 0x0904, 0xaa38, 0x6020,
+ 0x9086, 0x0006, 0x1904, 0xaa33, 0x87ff, 0x0128, 0x2700, 0x9c06,
+ 0x1904, 0xaa33, 0x0040, 0x6010, 0x9b06, 0x15e8, 0x85ff, 0x0118,
+ 0x6054, 0x9106, 0x15c0, 0x703c, 0x9c06, 0x1168, 0x0036, 0x2019,
+ 0x0001, 0x080c, 0xa877, 0x7033, 0x0000, 0x9006, 0x703e, 0x7042,
+ 0x7046, 0x704a, 0x003e, 0x7038, 0x9c36, 0x1110, 0x660c, 0x763a,
0x7034, 0x9c36, 0x1140, 0x2c00, 0x9f36, 0x0118, 0x2f00, 0x7036,
- 0x0010, 0x7037, 0x0000, 0x660c, 0x2c00, 0x9f06, 0x0110, 0x7e0e,
- 0x0008, 0x2678, 0x600f, 0x0000, 0x6004, 0x9086, 0x0040, 0x090c,
- 0x97db, 0x9085, 0x0001, 0x0020, 0x2c78, 0x600c, 0x2060, 0x08b0,
- 0x012e, 0x000e, 0x002e, 0x006e, 0x00ce, 0x00ee, 0x00fe, 0x0005,
- 0x0096, 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x0066, 0x0026, 0x0006,
- 0x0126, 0x2091, 0x8000, 0x2071, 0x19e9, 0x760c, 0x2660, 0x2678,
- 0x8cff, 0x0904, 0xab15, 0x6010, 0x00b6, 0x2058, 0xb8a0, 0x00be,
- 0x9206, 0x1904, 0xab10, 0x7024, 0x9c06, 0x1520, 0x2069, 0x0100,
- 0x68c0, 0x9005, 0x0904, 0xaae7, 0x080c, 0xa4fd, 0x68c3, 0x0000,
- 0x080c, 0xaa2f, 0x7027, 0x0000, 0x0036, 0x2069, 0x0140, 0x6b04,
- 0x9384, 0x1000, 0x0138, 0x2001, 0x0100, 0x080c, 0x2d5b, 0x9006,
- 0x080c, 0x2d5b, 0x2069, 0x0100, 0x6824, 0xd084, 0x0110, 0x6827,
- 0x0001, 0x003e, 0x700c, 0x9c36, 0x1110, 0x660c, 0x760e, 0x7008,
- 0x9c36, 0x1140, 0x2c00, 0x9f36, 0x0118, 0x2f00, 0x700a, 0x0010,
- 0x700b, 0x0000, 0x660c, 0x0066, 0x2c00, 0x9f06, 0x0110, 0x7e0e,
- 0x0008, 0x2678, 0x600f, 0x0000, 0x080c, 0xd036, 0x1180, 0x080c,
- 0x3274, 0x080c, 0xd047, 0x1518, 0x080c, 0xbacb, 0x0400, 0x080c,
- 0xaa2f, 0x6824, 0xd084, 0x09b0, 0x6827, 0x0001, 0x0898, 0x080c,
- 0xd047, 0x1118, 0x080c, 0xbacb, 0x0090, 0x6014, 0x2048, 0x080c,
- 0xce3d, 0x0168, 0x6020, 0x9086, 0x0003, 0x1508, 0xa867, 0x0103,
- 0xab7a, 0xa877, 0x0000, 0x080c, 0x6dbe, 0x080c, 0xd02a, 0x080c,
- 0xd2b3, 0x080c, 0xb11a, 0x080c, 0xa905, 0x00ce, 0x0804, 0xaa90,
- 0x2c78, 0x600c, 0x2060, 0x0804, 0xaa90, 0x012e, 0x000e, 0x002e,
- 0x006e, 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x009e, 0x0005, 0x6020,
- 0x9086, 0x0006, 0x1d20, 0x080c, 0xe8e3, 0x0c08, 0x00d6, 0x080c,
- 0x9f20, 0x7003, 0x0200, 0x7007, 0x0014, 0x60c3, 0x0014, 0x20e1,
- 0x0001, 0x2099, 0x198a, 0x20e9, 0x0000, 0x20a1, 0x0250, 0x20a9,
- 0x0004, 0x4003, 0x7023, 0x0004, 0x7027, 0x7878, 0x080c, 0xa4d1,
- 0x00de, 0x0005, 0x080c, 0x9f20, 0x700b, 0x0800, 0x7814, 0x9084,
- 0xff00, 0x700e, 0x7814, 0x9084, 0x00ff, 0x7022, 0x782c, 0x7026,
- 0x7858, 0x9084, 0x00ff, 0x9085, 0x0200, 0x7002, 0x7858, 0x9084,
- 0xff00, 0x8007, 0x7006, 0x60c2, 0x0804, 0xa4d1, 0x00b6, 0x00d6,
- 0x0016, 0x00d6, 0x2f68, 0x2009, 0x0035, 0x080c, 0xd4c0, 0x00de,
- 0x1904, 0xabc3, 0x080c, 0x9ed5, 0x7003, 0x1300, 0x782c, 0x080c,
- 0xacc9, 0x2068, 0x6820, 0x9086, 0x0003, 0x0560, 0x7810, 0x2058,
- 0xbaa0, 0x080c, 0xb051, 0x11d8, 0x9286, 0x007e, 0x1128, 0x700b,
- 0x00ff, 0x700f, 0xfffe, 0x0498, 0x9286, 0x007f, 0x1128, 0x700b,
- 0x00ff, 0x700f, 0xfffd, 0x0458, 0x9284, 0xff80, 0x0180, 0x9286,
- 0x0080, 0x1128, 0x700b, 0x00ff, 0x700f, 0xfffc, 0x0400, 0x92d8,
- 0x1000, 0x2b5c, 0xb810, 0x700a, 0xb814, 0x700e, 0x00c0, 0x6098,
- 0x700e, 0x00a8, 0x080c, 0xb051, 0x1130, 0x7810, 0x2058, 0xb8a0,
- 0x9082, 0x007e, 0x0250, 0x00d6, 0x2069, 0x181f, 0x2d04, 0x700a,
- 0x8d68, 0x2d04, 0x700e, 0x00de, 0x0010, 0x6034, 0x700e, 0x7838,
- 0x7012, 0x783c, 0x7016, 0x60c3, 0x000c, 0x001e, 0x00de, 0x080c,
- 0xa4d1, 0x00be, 0x0005, 0x781b, 0x0001, 0x7803, 0x0006, 0x001e,
- 0x00de, 0x00be, 0x0005, 0x792c, 0x9180, 0x0008, 0x200c, 0x9186,
- 0x0006, 0x01c0, 0x9186, 0x0003, 0x0904, 0xac3e, 0x9186, 0x0005,
- 0x0904, 0xac26, 0x9186, 0x0004, 0x05d8, 0x9186, 0x0008, 0x0904,
- 0xac2f, 0x7807, 0x0037, 0x782f, 0x0003, 0x7817, 0x1700, 0x080c,
- 0xaca6, 0x0005, 0x080c, 0xac67, 0x00d6, 0x0026, 0x792c, 0x2168,
- 0x2009, 0x4000, 0x6800, 0x0002, 0xac07, 0xac12, 0xac09, 0xac12,
- 0xac0e, 0xac07, 0xac07, 0xac12, 0xac12, 0xac12, 0xac12, 0xac07,
- 0xac07, 0xac07, 0xac07, 0xac07, 0xac12, 0xac07, 0xac12, 0x080c,
- 0x0dc5, 0x6824, 0xd0e4, 0x0110, 0xd0cc, 0x0110, 0x900e, 0x0010,
- 0x2009, 0x2000, 0x682c, 0x7022, 0x6830, 0x7026, 0x0804, 0xac60,
- 0x080c, 0xac67, 0x00d6, 0x0026, 0x792c, 0x2168, 0x2009, 0x4000,
- 0x6a00, 0x9286, 0x0002, 0x1108, 0x900e, 0x04d0, 0x080c, 0xac67,
- 0x00d6, 0x0026, 0x792c, 0x2168, 0x2009, 0x4000, 0x0488, 0x04b9,
- 0x00d6, 0x0026, 0x792c, 0x2168, 0x2009, 0x4000, 0x9286, 0x0005,
- 0x0118, 0x9286, 0x0002, 0x1108, 0x900e, 0x0410, 0x0441, 0x00d6,
- 0x0026, 0x792c, 0x2168, 0x6814, 0x6924, 0xc185, 0x6926, 0x0096,
- 0x2048, 0xa9ac, 0xa834, 0x9112, 0xa9b0, 0xa838, 0x009e, 0x9103,
- 0x7022, 0x7226, 0x792c, 0x9180, 0x0000, 0x2004, 0x908e, 0x0002,
- 0x0130, 0x908e, 0x0004, 0x0118, 0x2009, 0x4000, 0x0008, 0x900e,
- 0x712a, 0x60c3, 0x0018, 0x002e, 0x00de, 0x0804, 0xa4d1, 0x00b6,
- 0x0036, 0x0046, 0x0056, 0x0066, 0x080c, 0x9f20, 0x9006, 0x7003,
- 0x0200, 0x7938, 0x710a, 0x793c, 0x710e, 0x7810, 0x2058, 0xb8a0,
- 0x080c, 0xb051, 0x1118, 0x9092, 0x007e, 0x0268, 0x00d6, 0x2069,
- 0x181f, 0x2d2c, 0x8d68, 0x2d34, 0x90d8, 0x1000, 0x2b5c, 0xbb10,
- 0xbc14, 0x00de, 0x0028, 0x901e, 0x6498, 0x2029, 0x0000, 0x6634,
- 0x782c, 0x9080, 0x0008, 0x2004, 0x9086, 0x0003, 0x1128, 0x7512,
- 0x7616, 0x731a, 0x741e, 0x0020, 0x7312, 0x7416, 0x751a, 0x761e,
- 0x006e, 0x005e, 0x004e, 0x003e, 0x00be, 0x0005, 0x080c, 0x9f20,
- 0x7003, 0x0100, 0x782c, 0x700a, 0x7814, 0x700e, 0x700e, 0x60c3,
- 0x0008, 0x0804, 0xa4d1, 0x080c, 0x9ecc, 0x7003, 0x1400, 0x7838,
- 0x700a, 0x0079, 0x783c, 0x700e, 0x782c, 0x7012, 0x7830, 0x7016,
- 0x7834, 0x9084, 0x00ff, 0x8007, 0x701a, 0x60c3, 0x0010, 0x0804,
- 0xa4d1, 0x00e6, 0x2071, 0x0240, 0x0006, 0x00f6, 0x2078, 0x7810,
- 0x00b6, 0x2058, 0xb8cc, 0xd084, 0x0120, 0x7844, 0x702a, 0x7848,
- 0x702e, 0x00be, 0x00fe, 0x000e, 0x00ee, 0x0005, 0x080c, 0x9f17,
- 0x7003, 0x0100, 0x782c, 0x700a, 0x7814, 0x700e, 0x60c3, 0x0008,
- 0x0804, 0xa4d1, 0x0021, 0x60c3, 0x0000, 0x0804, 0xa4d1, 0x00d6,
- 0x080c, 0xada2, 0xb810, 0x9085, 0x0300, 0x7002, 0xb814, 0x7006,
- 0x2069, 0x1800, 0x687c, 0x700a, 0x6880, 0x700e, 0x7013, 0x0819,
- 0x080c, 0xa4bf, 0x721a, 0x2f10, 0x7222, 0x7a08, 0x7226, 0x2071,
- 0x024c, 0x00de, 0x0005, 0x00a9, 0x7914, 0x712a, 0x60c3, 0x0000,
- 0x60a7, 0x9575, 0x0026, 0x080c, 0x2bf0, 0x0228, 0x2011, 0x0101,
- 0x2204, 0xc0c5, 0x2012, 0x002e, 0x080c, 0xa4f4, 0x080c, 0x8780,
- 0x0005, 0x0036, 0x0096, 0x00d6, 0x00e6, 0x7858, 0x2048, 0xaa7c,
- 0x9296, 0x00c0, 0x9294, 0x00fd, 0xaa7e, 0xaa80, 0x9294, 0x0300,
- 0xaa82, 0xa96c, 0x9194, 0x00ff, 0xab74, 0x9384, 0x00ff, 0x908d,
- 0xc200, 0xa96e, 0x9384, 0xff00, 0x9215, 0xaa76, 0xa870, 0xaa78,
- 0xa87a, 0xaa72, 0x00d6, 0x2069, 0x0200, 0x080c, 0xada2, 0x00de,
- 0x20e9, 0x0000, 0x20a1, 0x0240, 0x20a9, 0x000a, 0xa860, 0x20e0,
- 0xa85c, 0x9080, 0x001b, 0x2098, 0x4003, 0x60a3, 0x0035, 0xaa68,
- 0x9294, 0x7000, 0x9286, 0x3000, 0x0110, 0x60a3, 0x0037, 0x00ee,
- 0x00de, 0x009e, 0x003e, 0x0005, 0x900e, 0x7814, 0x0096, 0x2048,
- 0xa87c, 0xd0fc, 0x01c0, 0x9084, 0x0003, 0x11a8, 0x2001, 0x180c,
- 0x2004, 0xd0bc, 0x0180, 0x7824, 0xd0cc, 0x1168, 0xd0c4, 0x1158,
- 0xa8a8, 0x9005, 0x1140, 0x2001, 0x180c, 0x200c, 0xc1d5, 0x2102,
- 0x2009, 0x19b4, 0x210c, 0x009e, 0x918d, 0x0092, 0x0010, 0x2009,
- 0x0096, 0x60ab, 0x0036, 0x6116, 0x0005, 0x2009, 0x0009, 0x00a0,
- 0x2009, 0x000a, 0x0088, 0x2009, 0x000b, 0x0070, 0x2009, 0x000c,
- 0x0058, 0x2009, 0x000d, 0x0040, 0x2009, 0x000e, 0x0028, 0x2009,
- 0x000f, 0x0010, 0x2009, 0x0008, 0x6912, 0x0005, 0x080c, 0x9ed5,
- 0x0016, 0x0026, 0x0096, 0x00d6, 0x7814, 0x2048, 0x7013, 0x0138,
- 0x2001, 0x1837, 0x2004, 0x9084, 0x0028, 0x1138, 0x2001, 0x197d,
- 0x2004, 0x9086, 0xaaaa, 0x1904, 0xae47, 0x7003, 0x5400, 0x00c6,
- 0x2061, 0x1800, 0x607c, 0x9084, 0x00ff, 0xa998, 0x810f, 0x918c,
- 0xff00, 0x9105, 0x700a, 0x6080, 0x700e, 0xa998, 0x918c, 0xff00,
- 0x7112, 0x20a9, 0x0004, 0x2009, 0x1805, 0x2e10, 0x9290, 0x0006,
- 0x2104, 0x2012, 0x8108, 0x8210, 0x1f04, 0xadd8, 0x20a9, 0x0004,
- 0x2009, 0x1801, 0x2104, 0x2012, 0x8108, 0x8210, 0x1f04, 0xade2,
- 0xa860, 0x20e0, 0xa85c, 0x9080, 0x0029, 0x2098, 0x2009, 0x0006,
+ 0x0010, 0x7037, 0x0000, 0x660c, 0x0066, 0x2c00, 0x9f06, 0x0110,
+ 0x7e0e, 0x0008, 0x2678, 0x600f, 0x0000, 0x6014, 0x2048, 0x080c,
+ 0xce54, 0x0110, 0x080c, 0xe948, 0x080c, 0xb134, 0x87ff, 0x1198,
+ 0x00ce, 0x0804, 0xa9e4, 0x2c78, 0x600c, 0x2060, 0x0804, 0xa9e4,
+ 0x9006, 0x012e, 0x000e, 0x002e, 0x006e, 0x00ce, 0x009e, 0x00de,
+ 0x00ee, 0x00fe, 0x0005, 0x601b, 0x0000, 0x00ce, 0x97bd, 0x0001,
+ 0x0c80, 0x00e6, 0x2071, 0x19e9, 0x2001, 0x1800, 0x2004, 0x9086,
+ 0x0002, 0x1118, 0x7007, 0x0005, 0x0010, 0x7007, 0x0000, 0x00ee,
+ 0x0005, 0x00f6, 0x00e6, 0x00c6, 0x0066, 0x0026, 0x0006, 0x0126,
+ 0x2091, 0x8000, 0x2071, 0x19e9, 0x2c10, 0x7638, 0x2660, 0x2678,
+ 0x8cff, 0x0540, 0x2200, 0x9c06, 0x1508, 0x7038, 0x9c36, 0x1110,
+ 0x660c, 0x763a, 0x7034, 0x9c36, 0x1140, 0x2c00, 0x9f36, 0x0118,
+ 0x2f00, 0x7036, 0x0010, 0x7037, 0x0000, 0x660c, 0x2c00, 0x9f06,
+ 0x0110, 0x7e0e, 0x0008, 0x2678, 0x600f, 0x0000, 0x6004, 0x9086,
+ 0x0040, 0x090c, 0x97e1, 0x9085, 0x0001, 0x0020, 0x2c78, 0x600c,
+ 0x2060, 0x08b0, 0x012e, 0x000e, 0x002e, 0x006e, 0x00ce, 0x00ee,
+ 0x00fe, 0x0005, 0x0096, 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x0066,
+ 0x0026, 0x0006, 0x0126, 0x2091, 0x8000, 0x2071, 0x19e9, 0x760c,
+ 0x2660, 0x2678, 0x8cff, 0x0904, 0xab2f, 0x6010, 0x00b6, 0x2058,
+ 0xb8a0, 0x00be, 0x9206, 0x1904, 0xab2a, 0x7024, 0x9c06, 0x1520,
+ 0x2069, 0x0100, 0x68c0, 0x9005, 0x0904, 0xab01, 0x080c, 0xa517,
+ 0x68c3, 0x0000, 0x080c, 0xaa49, 0x7027, 0x0000, 0x0036, 0x2069,
+ 0x0140, 0x6b04, 0x9384, 0x1000, 0x0138, 0x2001, 0x0100, 0x080c,
+ 0x2d52, 0x9006, 0x080c, 0x2d52, 0x2069, 0x0100, 0x6824, 0xd084,
+ 0x0110, 0x6827, 0x0001, 0x003e, 0x700c, 0x9c36, 0x1110, 0x660c,
+ 0x760e, 0x7008, 0x9c36, 0x1140, 0x2c00, 0x9f36, 0x0118, 0x2f00,
+ 0x700a, 0x0010, 0x700b, 0x0000, 0x660c, 0x0066, 0x2c00, 0x9f06,
+ 0x0110, 0x7e0e, 0x0008, 0x2678, 0x600f, 0x0000, 0x080c, 0xd04d,
+ 0x1180, 0x080c, 0x326f, 0x080c, 0xd05e, 0x1518, 0x080c, 0xbae2,
+ 0x0400, 0x080c, 0xaa49, 0x6824, 0xd084, 0x09b0, 0x6827, 0x0001,
+ 0x0898, 0x080c, 0xd05e, 0x1118, 0x080c, 0xbae2, 0x0090, 0x6014,
+ 0x2048, 0x080c, 0xce54, 0x0168, 0x6020, 0x9086, 0x0003, 0x1508,
+ 0xa867, 0x0103, 0xab7a, 0xa877, 0x0000, 0x080c, 0x6dc4, 0x080c,
+ 0xd041, 0x080c, 0xd2ca, 0x080c, 0xb134, 0x080c, 0xa91f, 0x00ce,
+ 0x0804, 0xaaaa, 0x2c78, 0x600c, 0x2060, 0x0804, 0xaaaa, 0x012e,
+ 0x000e, 0x002e, 0x006e, 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x009e,
+ 0x0005, 0x6020, 0x9086, 0x0006, 0x1d20, 0x080c, 0xe948, 0x0c08,
+ 0x00d6, 0x080c, 0x9f3a, 0x7003, 0x0200, 0x7007, 0x0014, 0x60c3,
+ 0x0014, 0x20e1, 0x0001, 0x2099, 0x198a, 0x20e9, 0x0000, 0x20a1,
+ 0x0250, 0x20a9, 0x0004, 0x4003, 0x7023, 0x0004, 0x7027, 0x7878,
+ 0x080c, 0xa4eb, 0x00de, 0x0005, 0x080c, 0x9f3a, 0x700b, 0x0800,
+ 0x7814, 0x9084, 0xff00, 0x700e, 0x7814, 0x9084, 0x00ff, 0x7022,
+ 0x782c, 0x7026, 0x7858, 0x9084, 0x00ff, 0x9085, 0x0200, 0x7002,
+ 0x7858, 0x9084, 0xff00, 0x8007, 0x7006, 0x60c2, 0x0804, 0xa4eb,
+ 0x00b6, 0x00d6, 0x0016, 0x00d6, 0x2f68, 0x2009, 0x0035, 0x080c,
+ 0xd4d7, 0x00de, 0x1904, 0xabdd, 0x080c, 0x9eef, 0x7003, 0x1300,
+ 0x782c, 0x080c, 0xace3, 0x2068, 0x6820, 0x9086, 0x0003, 0x0560,
+ 0x7810, 0x2058, 0xbaa0, 0x080c, 0xb06b, 0x11d8, 0x9286, 0x007e,
+ 0x1128, 0x700b, 0x00ff, 0x700f, 0xfffe, 0x0498, 0x9286, 0x007f,
+ 0x1128, 0x700b, 0x00ff, 0x700f, 0xfffd, 0x0458, 0x9284, 0xff80,
+ 0x0180, 0x9286, 0x0080, 0x1128, 0x700b, 0x00ff, 0x700f, 0xfffc,
+ 0x0400, 0x92d8, 0x1000, 0x2b5c, 0xb810, 0x700a, 0xb814, 0x700e,
+ 0x00c0, 0x6098, 0x700e, 0x00a8, 0x080c, 0xb06b, 0x1130, 0x7810,
+ 0x2058, 0xb8a0, 0x9082, 0x007e, 0x0250, 0x00d6, 0x2069, 0x181f,
+ 0x2d04, 0x700a, 0x8d68, 0x2d04, 0x700e, 0x00de, 0x0010, 0x6034,
+ 0x700e, 0x7838, 0x7012, 0x783c, 0x7016, 0x60c3, 0x000c, 0x001e,
+ 0x00de, 0x080c, 0xa4eb, 0x00be, 0x0005, 0x781b, 0x0001, 0x7803,
+ 0x0006, 0x001e, 0x00de, 0x00be, 0x0005, 0x792c, 0x9180, 0x0008,
+ 0x200c, 0x9186, 0x0006, 0x01c0, 0x9186, 0x0003, 0x0904, 0xac58,
+ 0x9186, 0x0005, 0x0904, 0xac40, 0x9186, 0x0004, 0x05d8, 0x9186,
+ 0x0008, 0x0904, 0xac49, 0x7807, 0x0037, 0x782f, 0x0003, 0x7817,
+ 0x1700, 0x080c, 0xacc0, 0x0005, 0x080c, 0xac81, 0x00d6, 0x0026,
+ 0x792c, 0x2168, 0x2009, 0x4000, 0x6800, 0x0002, 0xac21, 0xac2c,
+ 0xac23, 0xac2c, 0xac28, 0xac21, 0xac21, 0xac2c, 0xac2c, 0xac2c,
+ 0xac2c, 0xac21, 0xac21, 0xac21, 0xac21, 0xac21, 0xac2c, 0xac21,
+ 0xac2c, 0x080c, 0x0dc5, 0x6824, 0xd0e4, 0x0110, 0xd0cc, 0x0110,
+ 0x900e, 0x0010, 0x2009, 0x2000, 0x682c, 0x7022, 0x6830, 0x7026,
+ 0x0804, 0xac7a, 0x080c, 0xac81, 0x00d6, 0x0026, 0x792c, 0x2168,
+ 0x2009, 0x4000, 0x6a00, 0x9286, 0x0002, 0x1108, 0x900e, 0x04d0,
+ 0x080c, 0xac81, 0x00d6, 0x0026, 0x792c, 0x2168, 0x2009, 0x4000,
+ 0x0488, 0x04b9, 0x00d6, 0x0026, 0x792c, 0x2168, 0x2009, 0x4000,
+ 0x9286, 0x0005, 0x0118, 0x9286, 0x0002, 0x1108, 0x900e, 0x0410,
+ 0x0441, 0x00d6, 0x0026, 0x792c, 0x2168, 0x6814, 0x6924, 0xc185,
+ 0x6926, 0x0096, 0x2048, 0xa9ac, 0xa834, 0x9112, 0xa9b0, 0xa838,
+ 0x009e, 0x9103, 0x7022, 0x7226, 0x792c, 0x9180, 0x0000, 0x2004,
+ 0x908e, 0x0002, 0x0130, 0x908e, 0x0004, 0x0118, 0x2009, 0x4000,
+ 0x0008, 0x900e, 0x712a, 0x60c3, 0x0018, 0x002e, 0x00de, 0x0804,
+ 0xa4eb, 0x00b6, 0x0036, 0x0046, 0x0056, 0x0066, 0x080c, 0x9f3a,
+ 0x9006, 0x7003, 0x0200, 0x7938, 0x710a, 0x793c, 0x710e, 0x7810,
+ 0x2058, 0xb8a0, 0x080c, 0xb06b, 0x1118, 0x9092, 0x007e, 0x0268,
+ 0x00d6, 0x2069, 0x181f, 0x2d2c, 0x8d68, 0x2d34, 0x90d8, 0x1000,
+ 0x2b5c, 0xbb10, 0xbc14, 0x00de, 0x0028, 0x901e, 0x6498, 0x2029,
+ 0x0000, 0x6634, 0x782c, 0x9080, 0x0008, 0x2004, 0x9086, 0x0003,
+ 0x1128, 0x7512, 0x7616, 0x731a, 0x741e, 0x0020, 0x7312, 0x7416,
+ 0x751a, 0x761e, 0x006e, 0x005e, 0x004e, 0x003e, 0x00be, 0x0005,
+ 0x080c, 0x9f3a, 0x7003, 0x0100, 0x782c, 0x700a, 0x7814, 0x700e,
+ 0x700e, 0x60c3, 0x0008, 0x0804, 0xa4eb, 0x080c, 0x9ee6, 0x7003,
+ 0x1400, 0x7838, 0x700a, 0x0079, 0x783c, 0x700e, 0x782c, 0x7012,
+ 0x7830, 0x7016, 0x7834, 0x9084, 0x00ff, 0x8007, 0x701a, 0x60c3,
+ 0x0010, 0x0804, 0xa4eb, 0x00e6, 0x2071, 0x0240, 0x0006, 0x00f6,
+ 0x2078, 0x7810, 0x00b6, 0x2058, 0xb8cc, 0xd084, 0x0120, 0x7844,
+ 0x702a, 0x7848, 0x702e, 0x00be, 0x00fe, 0x000e, 0x00ee, 0x0005,
+ 0x080c, 0x9f31, 0x7003, 0x0100, 0x782c, 0x700a, 0x7814, 0x700e,
+ 0x60c3, 0x0008, 0x0804, 0xa4eb, 0x0021, 0x60c3, 0x0000, 0x0804,
+ 0xa4eb, 0x00d6, 0x080c, 0xadbc, 0xb810, 0x9085, 0x0300, 0x7002,
+ 0xb814, 0x7006, 0x2069, 0x1800, 0x687c, 0x700a, 0x6880, 0x700e,
+ 0x7013, 0x0819, 0x080c, 0xa4d9, 0x721a, 0x2f10, 0x7222, 0x7a08,
+ 0x7226, 0x2071, 0x024c, 0x00de, 0x0005, 0x00a9, 0x7914, 0x712a,
+ 0x60c3, 0x0000, 0x60a7, 0x9575, 0x0026, 0x080c, 0x2be7, 0x0228,
+ 0x2011, 0x0101, 0x2204, 0xc0c5, 0x2012, 0x002e, 0x080c, 0xa50e,
+ 0x080c, 0x8786, 0x0005, 0x0036, 0x0096, 0x00d6, 0x00e6, 0x7858,
+ 0x2048, 0xaa7c, 0x9296, 0x00c0, 0x9294, 0x00fd, 0xaa7e, 0xaa80,
+ 0x9294, 0x0300, 0xaa82, 0xa96c, 0x9194, 0x00ff, 0xab74, 0x9384,
+ 0x00ff, 0x908d, 0xc200, 0xa96e, 0x9384, 0xff00, 0x9215, 0xaa76,
+ 0xa870, 0xaa78, 0xa87a, 0xaa72, 0x00d6, 0x2069, 0x0200, 0x080c,
+ 0xadbc, 0x00de, 0x20e9, 0x0000, 0x20a1, 0x0240, 0x20a9, 0x000a,
+ 0xa860, 0x20e0, 0xa85c, 0x9080, 0x001b, 0x2098, 0x4003, 0x60a3,
+ 0x0035, 0xaa68, 0x9294, 0x7000, 0x9286, 0x3000, 0x0110, 0x60a3,
+ 0x0037, 0x00ee, 0x00de, 0x009e, 0x003e, 0x0005, 0x900e, 0x7814,
+ 0x0096, 0x2048, 0xa87c, 0xd0fc, 0x01c0, 0x9084, 0x0003, 0x11a8,
+ 0x2001, 0x180c, 0x2004, 0xd0bc, 0x0180, 0x7824, 0xd0cc, 0x1168,
+ 0xd0c4, 0x1158, 0xa8a8, 0x9005, 0x1140, 0x2001, 0x180c, 0x200c,
+ 0xc1d5, 0x2102, 0x2009, 0x19b4, 0x210c, 0x009e, 0x918d, 0x0092,
+ 0x0010, 0x2009, 0x0096, 0x60ab, 0x0036, 0x6116, 0x0005, 0x2009,
+ 0x0009, 0x00a0, 0x2009, 0x000a, 0x0088, 0x2009, 0x000b, 0x0070,
+ 0x2009, 0x000c, 0x0058, 0x2009, 0x000d, 0x0040, 0x2009, 0x000e,
+ 0x0028, 0x2009, 0x000f, 0x0010, 0x2009, 0x0008, 0x6912, 0x0005,
+ 0x080c, 0x9eef, 0x0016, 0x0026, 0x0096, 0x00d6, 0x7814, 0x2048,
+ 0x7013, 0x0138, 0x2001, 0x1837, 0x2004, 0x9084, 0x0028, 0x1138,
+ 0x2001, 0x197d, 0x2004, 0x9086, 0xaaaa, 0x1904, 0xae61, 0x7003,
+ 0x5400, 0x00c6, 0x2061, 0x1800, 0x607c, 0x9084, 0x00ff, 0xa998,
+ 0x810f, 0x918c, 0xff00, 0x9105, 0x700a, 0x6080, 0x700e, 0xa998,
+ 0x918c, 0xff00, 0x7112, 0x20a9, 0x0004, 0x2009, 0x1805, 0x2e10,
+ 0x9290, 0x0006, 0x2104, 0x2012, 0x8108, 0x8210, 0x1f04, 0xadf2,
+ 0x20a9, 0x0004, 0x2009, 0x1801, 0x2104, 0x2012, 0x8108, 0x8210,
+ 0x1f04, 0xadfc, 0xa860, 0x20e0, 0xa85c, 0x9080, 0x0029, 0x2098,
+ 0x2009, 0x0006, 0x20a9, 0x0001, 0x4002, 0x8007, 0x2012, 0x8210,
+ 0x8109, 0x1dc0, 0x00d6, 0x2069, 0x0200, 0x080c, 0xada7, 0x00de,
+ 0x2071, 0x0240, 0x2011, 0x0240, 0x2009, 0x0002, 0x20a9, 0x0001,
+ 0x4002, 0x8007, 0x2012, 0x8210, 0x8109, 0x1dc0, 0x2009, 0x0008,
0x20a9, 0x0001, 0x4002, 0x8007, 0x2012, 0x8210, 0x8109, 0x1dc0,
- 0x00d6, 0x2069, 0x0200, 0x080c, 0xad8d, 0x00de, 0x2071, 0x0240,
- 0x2011, 0x0240, 0x2009, 0x0002, 0x20a9, 0x0001, 0x4002, 0x8007,
- 0x2012, 0x8210, 0x8109, 0x1dc0, 0x2009, 0x0008, 0x20a9, 0x0001,
- 0x4002, 0x8007, 0x2012, 0x8210, 0x8109, 0x1dc0, 0xa85c, 0x9080,
- 0x0031, 0x2098, 0x2009, 0x0008, 0x20a9, 0x0001, 0x4002, 0x8007,
- 0x2012, 0x8210, 0x8109, 0x1dc0, 0x00ce, 0x60c3, 0x004c, 0x60a3,
- 0x0056, 0x60a7, 0x9575, 0x2001, 0x1837, 0x2004, 0x9084, 0x0028,
- 0x1168, 0x080c, 0x7563, 0x0150, 0x6028, 0xc0bd, 0x602a, 0x6014,
- 0x9084, 0x1804, 0x9085, 0x0029, 0x6016, 0x0010, 0x080c, 0xa4d1,
- 0x080c, 0x8780, 0x00de, 0x009e, 0x002e, 0x001e, 0x0005, 0x00e6,
- 0x2071, 0x0240, 0x2001, 0x2200, 0x9085, 0x00ff, 0x7002, 0x7007,
- 0xffff, 0x2071, 0x0100, 0x709b, 0x00ff, 0x00ee, 0x0804, 0xadbd,
- 0x080c, 0x9ed5, 0x0016, 0x0026, 0x0096, 0x00d6, 0x7814, 0x2048,
- 0x7013, 0x0138, 0x7003, 0x5500, 0x00c6, 0xa89c, 0x9084, 0x00ff,
- 0xa998, 0x810f, 0x918c, 0xff00, 0x9105, 0x700a, 0xa99c, 0x918c,
- 0xff00, 0xa8a0, 0x9084, 0x00ff, 0x9105, 0x700e, 0xa998, 0x918c,
- 0xff00, 0x2061, 0x1800, 0x607c, 0x9084, 0x00ff, 0x910d, 0x7112,
- 0x6180, 0x7116, 0x2009, 0x0008, 0xa860, 0x20e0, 0xa85c, 0x9080,
- 0x0029, 0x2098, 0x2e10, 0x9290, 0x0006, 0x20a9, 0x0001, 0x4002,
- 0x8007, 0x2012, 0x8210, 0x8109, 0x1dc0, 0x20a9, 0x0004, 0x2009,
- 0x1805, 0x2104, 0x2012, 0x8108, 0x8210, 0x1f04, 0xae99, 0x20a9,
- 0x0002, 0x2009, 0x1801, 0x2104, 0x2012, 0x8108, 0x8210, 0x1f04,
- 0xaea3, 0x00d6, 0x0016, 0x2069, 0x0200, 0x080c, 0xad8d, 0x001e,
- 0x00de, 0x2071, 0x0240, 0x20a9, 0x0002, 0x2009, 0x1803, 0x2011,
- 0x0240, 0x2104, 0x2012, 0x8108, 0x8210, 0x1f04, 0xaeb9, 0x2009,
- 0x0008, 0x4002, 0x8007, 0x2012, 0x8210, 0x8109, 0x1dd0, 0x9006,
- 0x20a9, 0x0008, 0x2012, 0x8210, 0x1f04, 0xaeca, 0x00ce, 0x60c3,
- 0x004c, 0x60a3, 0x0056, 0x60a7, 0x9575, 0x080c, 0xa4d1, 0x080c,
- 0x8780, 0x00de, 0x009e, 0x002e, 0x001e, 0x0005, 0x00d6, 0x9290,
- 0x0018, 0x8214, 0x20e9, 0x0000, 0x2069, 0x0200, 0x6813, 0x0000,
- 0x22a8, 0x9284, 0x00e0, 0x0128, 0x20a9, 0x0020, 0x9292, 0x0020,
- 0x0008, 0x9016, 0x20a1, 0x0240, 0x9006, 0x4004, 0x82ff, 0x0120,
- 0x6810, 0x8000, 0x6812, 0x0c60, 0x00de, 0x0005, 0x00d6, 0x0096,
- 0x6014, 0x2048, 0xa878, 0x6056, 0x9006, 0xa836, 0xa83a, 0xa99c,
- 0xa946, 0xa84a, 0x6023, 0x0003, 0x6007, 0x0040, 0x6003, 0x0003,
- 0x600b, 0xffff, 0xa817, 0x0001, 0xa842, 0xa83e, 0x2900, 0xa85a,
- 0xa813, 0x20e6, 0x080c, 0x939a, 0x0126, 0x2091, 0x8000, 0x080c,
- 0x9a09, 0x012e, 0x009e, 0x00de, 0x0005, 0x00f6, 0x00e6, 0x00d6,
- 0x00c6, 0x00a6, 0x0096, 0x0066, 0x0126, 0x2091, 0x8000, 0x2071,
- 0x19e9, 0x760c, 0x2660, 0x2678, 0x8cff, 0x0904, 0xafb1, 0x7024,
- 0x9c06, 0x1520, 0x2069, 0x0100, 0x68c0, 0x9005, 0x0904, 0xaf83,
- 0x080c, 0xa4fd, 0x68c3, 0x0000, 0x080c, 0xaa2f, 0x7027, 0x0000,
- 0x0036, 0x2069, 0x0140, 0x6b04, 0x9384, 0x1000, 0x0138, 0x2001,
- 0x0100, 0x080c, 0x2d5b, 0x9006, 0x080c, 0x2d5b, 0x2069, 0x0100,
- 0x6824, 0xd084, 0x0110, 0x6827, 0x0001, 0x003e, 0x700c, 0x9c36,
- 0x1110, 0x660c, 0x760e, 0x7008, 0x9c36, 0x1140, 0x2c00, 0x9f36,
- 0x0118, 0x2f00, 0x700a, 0x0010, 0x700b, 0x0000, 0x660c, 0x0066,
- 0x2c00, 0x9f06, 0x0110, 0x7e0e, 0x0008, 0x2678, 0x600f, 0x0000,
- 0x080c, 0xd036, 0x1180, 0x080c, 0x3274, 0x080c, 0xd047, 0x1518,
- 0x080c, 0xbacb, 0x0400, 0x080c, 0xaa2f, 0x6824, 0xd084, 0x09b0,
- 0x6827, 0x0001, 0x0898, 0x080c, 0xd047, 0x1118, 0x080c, 0xbacb,
- 0x0090, 0x6014, 0x2048, 0x080c, 0xce3d, 0x0168, 0x6020, 0x9086,
- 0x0003, 0x1520, 0xa867, 0x0103, 0xab7a, 0xa877, 0x0000, 0x080c,
- 0x6dcb, 0x080c, 0xd02a, 0x080c, 0xd2b3, 0x080c, 0xb11a, 0x080c,
- 0xa905, 0x00ce, 0x0804, 0xaf34, 0x2c78, 0x600c, 0x2060, 0x0804,
- 0xaf34, 0x700f, 0x0000, 0x700b, 0x0000, 0x012e, 0x006e, 0x009e,
- 0x00ae, 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x0005, 0x6020, 0x9086,
- 0x0006, 0x1d08, 0x080c, 0xe8e3, 0x08f0, 0x00d6, 0x0156, 0x080c,
- 0x9f20, 0x7a14, 0x82ff, 0x0138, 0x7003, 0x0100, 0x700b, 0x0003,
- 0x60c3, 0x0008, 0x0490, 0x7003, 0x0200, 0x7007, 0x0000, 0x2069,
- 0x1800, 0x901e, 0x6800, 0x9086, 0x0004, 0x1110, 0xc38d, 0x0060,
- 0x080c, 0x7563, 0x1110, 0xc3ad, 0x0008, 0xc3a5, 0x6adc, 0xd29c,
- 0x1110, 0xd2ac, 0x0108, 0xc39d, 0x730e, 0x080c, 0x8812, 0x20a9,
- 0x0006, 0x2011, 0xffec, 0x2019, 0xffed, 0x2071, 0x0250, 0x2305,
- 0x2072, 0x8e70, 0x2205, 0x2072, 0x8e70, 0x9398, 0x0002, 0x9290,
- 0x0002, 0x1f04, 0xaff7, 0x60c3, 0x0020, 0x080c, 0xa4d1, 0x015e,
- 0x00de, 0x0005, 0x0156, 0x080c, 0x9f20, 0x7a14, 0x82ff, 0x0168,
- 0x9286, 0xffff, 0x0118, 0x9282, 0x000e, 0x1238, 0x7003, 0x0100,
- 0x700b, 0x0003, 0x60c3, 0x0008, 0x0488, 0x7003, 0x0200, 0x7007,
- 0x001c, 0x700f, 0x0001, 0x2011, 0x19bf, 0x2204, 0x8007, 0x701a,
- 0x8210, 0x2204, 0x8007, 0x701e, 0x0421, 0x1120, 0xb8a0, 0x9082,
- 0x007f, 0x0248, 0x2001, 0x181f, 0x2004, 0x7022, 0x2001, 0x1820,
- 0x2004, 0x7026, 0x0030, 0x2001, 0x1818, 0x2004, 0x9084, 0x00ff,
- 0x7026, 0x20a9, 0x0004, 0x20e1, 0x0001, 0x2099, 0x1805, 0x20e9,
- 0x0000, 0x20a1, 0x0256, 0x4003, 0x60c3, 0x001c, 0x015e, 0x0804,
- 0xa4d1, 0x0006, 0x2001, 0x1837, 0x2004, 0xd0ac, 0x000e, 0x0005,
- 0x2011, 0x0003, 0x080c, 0xa8d3, 0x2011, 0x0002, 0x080c, 0xa8dd,
- 0x080c, 0xa7e7, 0x0036, 0x901e, 0x080c, 0xa85d, 0x003e, 0x0005,
- 0x080c, 0x33aa, 0x0188, 0x0016, 0x00b6, 0x00c6, 0x7010, 0x9085,
- 0x0020, 0x7012, 0x2009, 0x007e, 0x080c, 0x6717, 0xb85c, 0xc0ac,
- 0xb85e, 0x00ce, 0x00be, 0x001e, 0x0005, 0x2071, 0x188d, 0x7000,
- 0x9005, 0x0140, 0x2001, 0x0976, 0x2071, 0x1800, 0x7076, 0x707a,
- 0x706b, 0xffe0, 0x2071, 0x1800, 0x7074, 0x7056, 0x705b, 0x1cd0,
- 0x0005, 0x00e6, 0x0126, 0x2071, 0x1800, 0x2091, 0x8000, 0x7554,
- 0x9582, 0x0010, 0x0608, 0x7058, 0x2060, 0x6000, 0x9086, 0x0000,
- 0x0148, 0x9ce0, 0x0018, 0x7068, 0x9c02, 0x1208, 0x0cb0, 0x2061,
- 0x1cd0, 0x0c98, 0x6003, 0x0008, 0x8529, 0x7556, 0x9ca8, 0x0018,
- 0x7068, 0x9502, 0x1230, 0x755a, 0x9085, 0x0001, 0x012e, 0x00ee,
- 0x0005, 0x705b, 0x1cd0, 0x0cc0, 0x9006, 0x0cc0, 0x00e6, 0x2071,
- 0x1800, 0x7554, 0x9582, 0x0010, 0x0600, 0x7058, 0x2060, 0x6000,
+ 0xa85c, 0x9080, 0x0031, 0x2098, 0x2009, 0x0008, 0x20a9, 0x0001,
+ 0x4002, 0x8007, 0x2012, 0x8210, 0x8109, 0x1dc0, 0x00ce, 0x60c3,
+ 0x004c, 0x60a3, 0x0056, 0x60a7, 0x9575, 0x2001, 0x1837, 0x2004,
+ 0x9084, 0x0028, 0x1168, 0x080c, 0x7569, 0x0150, 0x6028, 0xc0bd,
+ 0x602a, 0x6014, 0x9084, 0x1804, 0x9085, 0x0029, 0x6016, 0x0010,
+ 0x080c, 0xa4eb, 0x080c, 0x8786, 0x00de, 0x009e, 0x002e, 0x001e,
+ 0x0005, 0x00e6, 0x2071, 0x0240, 0x2001, 0x2200, 0x9085, 0x00ff,
+ 0x7002, 0x7007, 0xffff, 0x2071, 0x0100, 0x709b, 0x00ff, 0x00ee,
+ 0x0804, 0xadd7, 0x080c, 0x9eef, 0x0016, 0x0026, 0x0096, 0x00d6,
+ 0x7814, 0x2048, 0x7013, 0x0138, 0x7003, 0x5500, 0x00c6, 0xa89c,
+ 0x9084, 0x00ff, 0xa998, 0x810f, 0x918c, 0xff00, 0x9105, 0x700a,
+ 0xa99c, 0x918c, 0xff00, 0xa8a0, 0x9084, 0x00ff, 0x9105, 0x700e,
+ 0xa998, 0x918c, 0xff00, 0x2061, 0x1800, 0x607c, 0x9084, 0x00ff,
+ 0x910d, 0x7112, 0x6180, 0x7116, 0x2009, 0x0008, 0xa860, 0x20e0,
+ 0xa85c, 0x9080, 0x0029, 0x2098, 0x2e10, 0x9290, 0x0006, 0x20a9,
+ 0x0001, 0x4002, 0x8007, 0x2012, 0x8210, 0x8109, 0x1dc0, 0x20a9,
+ 0x0004, 0x2009, 0x1805, 0x2104, 0x2012, 0x8108, 0x8210, 0x1f04,
+ 0xaeb3, 0x20a9, 0x0002, 0x2009, 0x1801, 0x2104, 0x2012, 0x8108,
+ 0x8210, 0x1f04, 0xaebd, 0x00d6, 0x0016, 0x2069, 0x0200, 0x080c,
+ 0xada7, 0x001e, 0x00de, 0x2071, 0x0240, 0x20a9, 0x0002, 0x2009,
+ 0x1803, 0x2011, 0x0240, 0x2104, 0x2012, 0x8108, 0x8210, 0x1f04,
+ 0xaed3, 0x2009, 0x0008, 0x4002, 0x8007, 0x2012, 0x8210, 0x8109,
+ 0x1dd0, 0x9006, 0x20a9, 0x0008, 0x2012, 0x8210, 0x1f04, 0xaee4,
+ 0x00ce, 0x60c3, 0x004c, 0x60a3, 0x0056, 0x60a7, 0x9575, 0x080c,
+ 0xa4eb, 0x080c, 0x8786, 0x00de, 0x009e, 0x002e, 0x001e, 0x0005,
+ 0x00d6, 0x9290, 0x0018, 0x8214, 0x20e9, 0x0000, 0x2069, 0x0200,
+ 0x6813, 0x0000, 0x22a8, 0x9284, 0x00e0, 0x0128, 0x20a9, 0x0020,
+ 0x9292, 0x0020, 0x0008, 0x9016, 0x20a1, 0x0240, 0x9006, 0x4004,
+ 0x82ff, 0x0120, 0x6810, 0x8000, 0x6812, 0x0c60, 0x00de, 0x0005,
+ 0x00d6, 0x0096, 0x6014, 0x2048, 0xa878, 0x6056, 0x9006, 0xa836,
+ 0xa83a, 0xa99c, 0xa946, 0xa84a, 0x6023, 0x0003, 0x6007, 0x0040,
+ 0x6003, 0x0003, 0x600b, 0xffff, 0xa817, 0x0001, 0xa842, 0xa83e,
+ 0x2900, 0xa85a, 0xa813, 0x20ee, 0x080c, 0x93a0, 0x0126, 0x2091,
+ 0x8000, 0x080c, 0x9a0f, 0x012e, 0x009e, 0x00de, 0x0005, 0x00f6,
+ 0x00e6, 0x00d6, 0x00c6, 0x00a6, 0x0096, 0x0066, 0x0126, 0x2091,
+ 0x8000, 0x2071, 0x19e9, 0x760c, 0x2660, 0x2678, 0x8cff, 0x0904,
+ 0xafcb, 0x7024, 0x9c06, 0x1520, 0x2069, 0x0100, 0x68c0, 0x9005,
+ 0x0904, 0xaf9d, 0x080c, 0xa517, 0x68c3, 0x0000, 0x080c, 0xaa49,
+ 0x7027, 0x0000, 0x0036, 0x2069, 0x0140, 0x6b04, 0x9384, 0x1000,
+ 0x0138, 0x2001, 0x0100, 0x080c, 0x2d52, 0x9006, 0x080c, 0x2d52,
+ 0x2069, 0x0100, 0x6824, 0xd084, 0x0110, 0x6827, 0x0001, 0x003e,
+ 0x700c, 0x9c36, 0x1110, 0x660c, 0x760e, 0x7008, 0x9c36, 0x1140,
+ 0x2c00, 0x9f36, 0x0118, 0x2f00, 0x700a, 0x0010, 0x700b, 0x0000,
+ 0x660c, 0x0066, 0x2c00, 0x9f06, 0x0110, 0x7e0e, 0x0008, 0x2678,
+ 0x600f, 0x0000, 0x080c, 0xd04d, 0x1180, 0x080c, 0x326f, 0x080c,
+ 0xd05e, 0x1518, 0x080c, 0xbae2, 0x0400, 0x080c, 0xaa49, 0x6824,
+ 0xd084, 0x09b0, 0x6827, 0x0001, 0x0898, 0x080c, 0xd05e, 0x1118,
+ 0x080c, 0xbae2, 0x0090, 0x6014, 0x2048, 0x080c, 0xce54, 0x0168,
+ 0x6020, 0x9086, 0x0003, 0x1520, 0xa867, 0x0103, 0xab7a, 0xa877,
+ 0x0000, 0x080c, 0x6dd1, 0x080c, 0xd041, 0x080c, 0xd2ca, 0x080c,
+ 0xb134, 0x080c, 0xa91f, 0x00ce, 0x0804, 0xaf4e, 0x2c78, 0x600c,
+ 0x2060, 0x0804, 0xaf4e, 0x700f, 0x0000, 0x700b, 0x0000, 0x012e,
+ 0x006e, 0x009e, 0x00ae, 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x0005,
+ 0x6020, 0x9086, 0x0006, 0x1d08, 0x080c, 0xe948, 0x08f0, 0x00d6,
+ 0x0156, 0x080c, 0x9f3a, 0x7a14, 0x82ff, 0x0138, 0x7003, 0x0100,
+ 0x700b, 0x0003, 0x60c3, 0x0008, 0x0490, 0x7003, 0x0200, 0x7007,
+ 0x0000, 0x2069, 0x1800, 0x901e, 0x6800, 0x9086, 0x0004, 0x1110,
+ 0xc38d, 0x0060, 0x080c, 0x7569, 0x1110, 0xc3ad, 0x0008, 0xc3a5,
+ 0x6adc, 0xd29c, 0x1110, 0xd2ac, 0x0108, 0xc39d, 0x730e, 0x080c,
+ 0x8818, 0x20a9, 0x0006, 0x2011, 0xffec, 0x2019, 0xffed, 0x2071,
+ 0x0250, 0x2305, 0x2072, 0x8e70, 0x2205, 0x2072, 0x8e70, 0x9398,
+ 0x0002, 0x9290, 0x0002, 0x1f04, 0xb011, 0x60c3, 0x0020, 0x080c,
+ 0xa4eb, 0x015e, 0x00de, 0x0005, 0x0156, 0x080c, 0x9f3a, 0x7a14,
+ 0x82ff, 0x0168, 0x9286, 0xffff, 0x0118, 0x9282, 0x000e, 0x1238,
+ 0x7003, 0x0100, 0x700b, 0x0003, 0x60c3, 0x0008, 0x0488, 0x7003,
+ 0x0200, 0x7007, 0x001c, 0x700f, 0x0001, 0x2011, 0x19bf, 0x2204,
+ 0x8007, 0x701a, 0x8210, 0x2204, 0x8007, 0x701e, 0x0421, 0x1120,
+ 0xb8a0, 0x9082, 0x007f, 0x0248, 0x2001, 0x181f, 0x2004, 0x7022,
+ 0x2001, 0x1820, 0x2004, 0x7026, 0x0030, 0x2001, 0x1818, 0x2004,
+ 0x9084, 0x00ff, 0x7026, 0x20a9, 0x0004, 0x20e1, 0x0001, 0x2099,
+ 0x1805, 0x20e9, 0x0000, 0x20a1, 0x0256, 0x4003, 0x60c3, 0x001c,
+ 0x015e, 0x0804, 0xa4eb, 0x0006, 0x2001, 0x1837, 0x2004, 0xd0ac,
+ 0x000e, 0x0005, 0x2011, 0x0003, 0x080c, 0xa8ed, 0x2011, 0x0002,
+ 0x080c, 0xa8f7, 0x080c, 0xa801, 0x0036, 0x901e, 0x080c, 0xa877,
+ 0x003e, 0x0005, 0x080c, 0x33a5, 0x0188, 0x0016, 0x00b6, 0x00c6,
+ 0x7010, 0x9085, 0x0020, 0x7012, 0x2009, 0x007e, 0x080c, 0x671d,
+ 0xb85c, 0xc0ac, 0xb85e, 0x00ce, 0x00be, 0x001e, 0x0005, 0x2071,
+ 0x188d, 0x7000, 0x9005, 0x0140, 0x2001, 0x0976, 0x2071, 0x1800,
+ 0x7076, 0x707a, 0x706b, 0xffe0, 0x2071, 0x1800, 0x7074, 0x7056,
+ 0x705b, 0x1cd0, 0x0005, 0x00e6, 0x0126, 0x2071, 0x1800, 0x2091,
+ 0x8000, 0x7554, 0x9582, 0x0010, 0x0608, 0x7058, 0x2060, 0x6000,
+ 0x9086, 0x0000, 0x0148, 0x9ce0, 0x0018, 0x7068, 0x9c02, 0x1208,
+ 0x0cb0, 0x2061, 0x1cd0, 0x0c98, 0x6003, 0x0008, 0x8529, 0x7556,
+ 0x9ca8, 0x0018, 0x7068, 0x9502, 0x1230, 0x755a, 0x9085, 0x0001,
+ 0x012e, 0x00ee, 0x0005, 0x705b, 0x1cd0, 0x0cc0, 0x9006, 0x0cc0,
+ 0x00e6, 0x2071, 0x1800, 0x7554, 0x9582, 0x0010, 0x0600, 0x7058,
+ 0x2060, 0x6000, 0x9086, 0x0000, 0x0148, 0x9ce0, 0x0018, 0x7068,
+ 0x9c02, 0x1208, 0x0cb0, 0x2061, 0x1cd0, 0x0c98, 0x6003, 0x0008,
+ 0x8529, 0x7556, 0x9ca8, 0x0018, 0x7068, 0x9502, 0x1228, 0x755a,
+ 0x9085, 0x0001, 0x00ee, 0x0005, 0x705b, 0x1cd0, 0x0cc8, 0x9006,
+ 0x0cc8, 0x9c82, 0x1cd0, 0x0a0c, 0x0dc5, 0x2001, 0x181a, 0x2004,
+ 0x9c02, 0x1a0c, 0x0dc5, 0x9006, 0x6006, 0x600a, 0x600e, 0x6016,
+ 0x601a, 0x6012, 0x6023, 0x0000, 0x6003, 0x0000, 0x601e, 0x6056,
+ 0x605a, 0x6026, 0x602a, 0x602e, 0x6032, 0x6036, 0x603a, 0x603e,
+ 0x6042, 0x602a, 0x2061, 0x1800, 0x6054, 0x8000, 0x6056, 0x9086,
+ 0x0001, 0x0108, 0x0005, 0x0126, 0x2091, 0x8000, 0x0016, 0x080c,
+ 0x98ed, 0x001e, 0x012e, 0x0cb0, 0x0006, 0x6000, 0x9086, 0x0000,
+ 0x01c0, 0x601c, 0xd084, 0x190c, 0x1ab7, 0x6017, 0x0000, 0x6023,
+ 0x0007, 0x2001, 0x1987, 0x2004, 0x0006, 0x9082, 0x0051, 0x000e,
+ 0x0208, 0x8004, 0x601a, 0x080c, 0xec02, 0x6043, 0x0000, 0x6013,
+ 0x0000, 0x000e, 0x0005, 0x00e6, 0x0126, 0x2071, 0x1800, 0x2091,
+ 0x8000, 0x7554, 0x9582, 0x0001, 0x0608, 0x7058, 0x2060, 0x6000,
0x9086, 0x0000, 0x0148, 0x9ce0, 0x0018, 0x7068, 0x9c02, 0x1208,
0x0cb0, 0x2061, 0x1cd0, 0x0c98, 0x6003, 0x0008, 0x8529, 0x7556,
- 0x9ca8, 0x0018, 0x7068, 0x9502, 0x1228, 0x755a, 0x9085, 0x0001,
- 0x00ee, 0x0005, 0x705b, 0x1cd0, 0x0cc8, 0x9006, 0x0cc8, 0x9c82,
- 0x1cd0, 0x0a0c, 0x0dc5, 0x2001, 0x181a, 0x2004, 0x9c02, 0x1a0c,
- 0x0dc5, 0x9006, 0x6006, 0x600a, 0x600e, 0x6016, 0x601a, 0x6012,
- 0x6023, 0x0000, 0x6003, 0x0000, 0x601e, 0x6056, 0x605a, 0x6026,
- 0x602a, 0x602e, 0x6032, 0x6036, 0x603a, 0x603e, 0x6042, 0x602a,
- 0x2061, 0x1800, 0x6054, 0x8000, 0x6056, 0x9086, 0x0001, 0x0108,
- 0x0005, 0x0126, 0x2091, 0x8000, 0x0016, 0x080c, 0x98e7, 0x001e,
- 0x012e, 0x0cb0, 0x0006, 0x6000, 0x9086, 0x0000, 0x01c0, 0x601c,
- 0xd084, 0x190c, 0x1ab7, 0x6017, 0x0000, 0x6023, 0x0007, 0x2001,
- 0x1987, 0x2004, 0x0006, 0x9082, 0x0051, 0x000e, 0x0208, 0x8004,
- 0x601a, 0x080c, 0xeb9d, 0x6043, 0x0000, 0x6013, 0x0000, 0x000e,
- 0x0005, 0x00e6, 0x0126, 0x2071, 0x1800, 0x2091, 0x8000, 0x7554,
- 0x9582, 0x0001, 0x0608, 0x7058, 0x2060, 0x6000, 0x9086, 0x0000,
- 0x0148, 0x9ce0, 0x0018, 0x7068, 0x9c02, 0x1208, 0x0cb0, 0x2061,
- 0x1cd0, 0x0c98, 0x6003, 0x0008, 0x8529, 0x7556, 0x9ca8, 0x0018,
- 0x7068, 0x9502, 0x1230, 0x755a, 0x9085, 0x0001, 0x012e, 0x00ee,
- 0x0005, 0x705b, 0x1cd0, 0x0cc0, 0x9006, 0x0cc0, 0x6020, 0x9084,
- 0x000f, 0x0002, 0xb179, 0xb182, 0xb19d, 0xb1b8, 0xd590, 0xd5ad,
- 0xd5c8, 0xb179, 0xb182, 0x8fc7, 0xb1d4, 0xb179, 0xb179, 0xb179,
- 0xb179, 0x9186, 0x0013, 0x1128, 0x080c, 0x97db, 0x080c, 0x98e7,
- 0x0005, 0x0005, 0x0066, 0x6000, 0x90b2, 0x0016, 0x1a0c, 0x0dc5,
- 0x0013, 0x006e, 0x0005, 0xb19b, 0xb91a, 0xbb12, 0xb19b, 0xbba8,
- 0xb4b7, 0xb19b, 0xb19b, 0xb89c, 0xc11f, 0xb19b, 0xb19b, 0xb19b,
- 0xb19b, 0xb19b, 0xb19b, 0x080c, 0x0dc5, 0x0066, 0x6000, 0x90b2,
- 0x0016, 0x1a0c, 0x0dc5, 0x0013, 0x006e, 0x0005, 0xb1b6, 0xc7e9,
- 0xb1b6, 0xb1b6, 0xb1b6, 0xb1b6, 0xb1b6, 0xb1b6, 0xc780, 0xc96b,
- 0xb1b6, 0xc82a, 0xc8a9, 0xc82a, 0xc8a9, 0xb1b6, 0x080c, 0x0dc5,
- 0x6000, 0x9082, 0x0016, 0x1a0c, 0x0dc5, 0x6000, 0x0002, 0xb1d2,
- 0xc166, 0xc22e, 0xc35e, 0xc50d, 0xb1d2, 0xb1d2, 0xb1d2, 0xc13a,
- 0xc70c, 0xc70f, 0xb1d2, 0xb1d2, 0xb1d2, 0xb1d2, 0xc73e, 0xb1d2,
- 0xb1d2, 0xb1d2, 0x080c, 0x0dc5, 0x0066, 0x6000, 0x90b2, 0x0016,
- 0x1a0c, 0x0dc5, 0x0013, 0x006e, 0x0005, 0xb1ed, 0xb1ed, 0xb230,
- 0xb2cf, 0xb364, 0xb1ed, 0xb1ed, 0xb1ed, 0xb1ef, 0xb1ed, 0xb1ed,
- 0xb1ed, 0xb1ed, 0xb1ed, 0xb1ed, 0xb1ed, 0x080c, 0x0dc5, 0x9186,
- 0x004c, 0x0588, 0x9186, 0x0003, 0x190c, 0x0dc5, 0x0096, 0x601c,
- 0xc0ed, 0x601e, 0x6003, 0x0003, 0x6106, 0x6014, 0x2048, 0xa87c,
- 0x9084, 0xa000, 0xc0b5, 0xa87e, 0xa8ac, 0xa846, 0xa8b0, 0xa84a,
- 0x9006, 0xa836, 0xa83a, 0xa884, 0x9092, 0x199a, 0x0210, 0x2001,
- 0x1999, 0x8003, 0x8013, 0x8213, 0x9210, 0x621a, 0x009e, 0x2c10,
- 0x080c, 0x1c01, 0x080c, 0x939a, 0x0126, 0x2091, 0x8000, 0x080c,
- 0x9a09, 0x012e, 0x0005, 0x6010, 0x00b6, 0x2058, 0xbca0, 0x00be,
- 0x2c00, 0x080c, 0xb386, 0x080c, 0xd560, 0x6003, 0x0007, 0x0005,
- 0x00d6, 0x0096, 0x00f6, 0x2079, 0x1800, 0x7a90, 0x6014, 0x2048,
- 0xa87c, 0xd0ec, 0x1110, 0x9290, 0x0018, 0xac78, 0xc4fc, 0x0046,
- 0xa8e0, 0x9005, 0x1140, 0xa8dc, 0x921a, 0x0140, 0x0220, 0xa87b,
- 0x0007, 0x2010, 0x0028, 0xa87b, 0x0015, 0x0010, 0xa87b, 0x0000,
- 0x8214, 0xa883, 0x0000, 0xaa02, 0x0006, 0x0016, 0x0026, 0x00c6,
- 0x00d6, 0x00e6, 0x00f6, 0x2400, 0x9005, 0x1108, 0x009a, 0x2100,
- 0x9086, 0x0015, 0x1118, 0x2001, 0x0001, 0x0038, 0x2100, 0x9086,
- 0x0016, 0x0118, 0x2001, 0x0001, 0x002a, 0x94a4, 0x0007, 0x8423,
- 0x9405, 0x0002, 0xb297, 0xb297, 0xb292, 0xb295, 0xb297, 0xb28f,
- 0xb282, 0xb282, 0xb282, 0xb282, 0xb282, 0xb282, 0xb282, 0xb282,
- 0xb282, 0xb282, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x002e, 0x001e,
- 0x000e, 0x004e, 0x00fe, 0x009e, 0x00de, 0x080c, 0x0dc5, 0x080c,
- 0xbd75, 0x0028, 0x080c, 0xbe5c, 0x0010, 0x080c, 0xbf52, 0x00fe,
- 0x00ee, 0x00de, 0x00ce, 0x002e, 0x001e, 0x2c00, 0xa896, 0x000e,
- 0x080c, 0xb444, 0x0530, 0xa804, 0xa80e, 0x00a6, 0x2050, 0xb100,
- 0x00ae, 0x8006, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0,
- 0x9080, 0x0002, 0xaacc, 0xabd0, 0xacd4, 0xadd8, 0x2031, 0x0000,
- 0x2041, 0x126c, 0x080c, 0xb608, 0x0160, 0x000e, 0x9005, 0x0120,
- 0x00fe, 0x009e, 0x00de, 0x0005, 0x00fe, 0x009e, 0x00de, 0x0804,
- 0xb0e7, 0x2001, 0x002c, 0x900e, 0x080c, 0xb4aa, 0x0c70, 0x91b6,
- 0x0015, 0x0170, 0x91b6, 0x0016, 0x0158, 0x91b2, 0x0047, 0x0a0c,
- 0x0dc5, 0x91b2, 0x0050, 0x1a0c, 0x0dc5, 0x9182, 0x0047, 0x00ca,
- 0x2001, 0x0109, 0x2004, 0xd08c, 0x0198, 0x0126, 0x2091, 0x2800,
- 0x0006, 0x0016, 0x0026, 0x080c, 0x92e7, 0x002e, 0x001e, 0x000e,
- 0x012e, 0xa001, 0x6000, 0x9086, 0x0002, 0x1110, 0x0804, 0xb230,
- 0x0005, 0xb302, 0xb302, 0xb304, 0xb33a, 0xb302, 0xb302, 0xb302,
- 0xb302, 0xb34d, 0x080c, 0x0dc5, 0x00d6, 0x0016, 0x0096, 0x080c,
- 0x9897, 0x080c, 0x9a09, 0x6003, 0x0004, 0x6114, 0x2148, 0xa87c,
- 0xd0fc, 0x01c0, 0xa878, 0xc0fc, 0x9005, 0x1158, 0xa894, 0x9005,
- 0x0140, 0x2001, 0x0000, 0x900e, 0x080c, 0xb4aa, 0x080c, 0xb0e7,
- 0x00a8, 0x6003, 0x0002, 0xa8a4, 0xa9a8, 0x9105, 0x1178, 0xa8ae,
- 0xa8b2, 0x0c78, 0xa87f, 0x0020, 0xa88c, 0xa88a, 0xa8a4, 0xa8ae,
- 0xa8a8, 0xa8b2, 0xa8c7, 0x0000, 0xa8cb, 0x0000, 0x009e, 0x001e,
- 0x00de, 0x0005, 0x080c, 0x9897, 0x00d6, 0x0096, 0x6114, 0x2148,
- 0x080c, 0xce3f, 0x0120, 0xa87b, 0x0006, 0x080c, 0x6dcb, 0x009e,
- 0x00de, 0x080c, 0xb0e7, 0x0804, 0x9a09, 0x080c, 0x9897, 0x080c,
- 0x324b, 0x080c, 0xd55d, 0x00d6, 0x0096, 0x6114, 0x2148, 0x080c,
- 0xce3f, 0x0120, 0xa87b, 0x0029, 0x080c, 0x6dcb, 0x009e, 0x00de,
- 0x080c, 0xb0e7, 0x0804, 0x9a09, 0x9182, 0x0047, 0x0002, 0xb374,
- 0xb376, 0xb374, 0xb374, 0xb374, 0xb374, 0xb374, 0xb374, 0xb374,
- 0xb374, 0xb374, 0xb374, 0xb376, 0x080c, 0x0dc5, 0x00d6, 0x0096,
- 0x601f, 0x0000, 0x6114, 0x2148, 0xa87b, 0x0000, 0xa883, 0x0000,
- 0x080c, 0x6dcb, 0x009e, 0x00de, 0x0804, 0xb0e7, 0x0026, 0x0036,
- 0x0056, 0x0066, 0x0096, 0x00a6, 0x00f6, 0x0006, 0x080c, 0x100e,
- 0x000e, 0x090c, 0x0dc5, 0xa960, 0x21e8, 0xa95c, 0x9188, 0x0019,
- 0x21a0, 0x900e, 0x20a9, 0x0020, 0x4104, 0xa87a, 0x2079, 0x1800,
- 0x7990, 0x9188, 0x0018, 0x918c, 0x0fff, 0xa972, 0xac76, 0x2950,
- 0x00a6, 0x2001, 0x0205, 0x2003, 0x0000, 0x901e, 0x2029, 0x0001,
- 0x9182, 0x0034, 0x1228, 0x2011, 0x001f, 0x080c, 0xc9f0, 0x04c0,
- 0x2130, 0x2009, 0x0034, 0x2011, 0x001f, 0x080c, 0xc9f0, 0x96b2,
- 0x0034, 0xb004, 0x904d, 0x0110, 0x080c, 0x0fc0, 0x080c, 0x100e,
- 0x01d0, 0x8528, 0xa867, 0x0110, 0xa86b, 0x0000, 0x2920, 0xb406,
- 0x968a, 0x003d, 0x1230, 0x2608, 0x2011, 0x001b, 0x080c, 0xc9f0,
- 0x00b8, 0x96b2, 0x003c, 0x2009, 0x003c, 0x2950, 0x2011, 0x001b,
- 0x080c, 0xc9f0, 0x0c18, 0x2001, 0x0205, 0x2003, 0x0000, 0x00ae,
- 0x852f, 0x95ad, 0x0050, 0xb566, 0xb070, 0xc0fd, 0xb072, 0x0048,
- 0x2001, 0x0205, 0x2003, 0x0000, 0x00ae, 0x852f, 0x95ad, 0x0050,
- 0xb566, 0x2a48, 0xa804, 0xa807, 0x0000, 0x0006, 0x080c, 0x6dcb,
- 0x000e, 0x2048, 0x9005, 0x1db0, 0x00fe, 0x00ae, 0x009e, 0x006e,
- 0x005e, 0x003e, 0x002e, 0x0005, 0x00d6, 0x00f6, 0x0096, 0x0006,
- 0x080c, 0x100e, 0x000e, 0x090c, 0x0dc5, 0xa960, 0x21e8, 0xa95c,
- 0x9188, 0x0019, 0x21a0, 0x900e, 0x20a9, 0x0020, 0x4104, 0xaa66,
- 0xa87a, 0x2079, 0x1800, 0x7990, 0x810c, 0x9188, 0x000c, 0x9182,
- 0x001a, 0x0210, 0x2009, 0x001a, 0x21a8, 0x810b, 0xa972, 0xac76,
- 0x2e98, 0xa85c, 0x9080, 0x001f, 0x20a0, 0x2001, 0x0205, 0x200c,
- 0x918d, 0x0080, 0x2102, 0x4003, 0x2003, 0x0000, 0x080c, 0x6dcb,
- 0x009e, 0x00fe, 0x00de, 0x0005, 0x0016, 0x00d6, 0x00f6, 0x0096,
- 0x0016, 0x2001, 0x0205, 0x200c, 0x918d, 0x0080, 0x2102, 0x001e,
- 0x2079, 0x0200, 0x2e98, 0xa87c, 0xd0ec, 0x0118, 0x9e80, 0x000c,
- 0x2098, 0x2021, 0x003e, 0x901e, 0x9282, 0x0020, 0x0218, 0x2011,
- 0x0020, 0x2018, 0x9486, 0x003e, 0x1170, 0x0096, 0x080c, 0x100e,
- 0x2900, 0x009e, 0x05c0, 0xa806, 0x2048, 0xa860, 0x20e8, 0xa85c,
- 0x9080, 0x0002, 0x20a0, 0x3300, 0x908e, 0x0260, 0x0140, 0x2009,
- 0x0280, 0x9102, 0x920a, 0x0218, 0x2010, 0x2100, 0x9318, 0x2200,
- 0x9402, 0x1228, 0x2400, 0x9202, 0x2410, 0x9318, 0x9006, 0x2020,
- 0x22a8, 0xa800, 0x9200, 0xa802, 0x20e1, 0x0000, 0x4003, 0x83ff,
- 0x0180, 0x3300, 0x9086, 0x0280, 0x1130, 0x7814, 0x8000, 0x9085,
- 0x0080, 0x7816, 0x2e98, 0x2310, 0x84ff, 0x0904, 0xb459, 0x0804,
- 0xb45b, 0x9085, 0x0001, 0x7817, 0x0000, 0x009e, 0x00fe, 0x00de,
- 0x001e, 0x0005, 0x00d6, 0x0036, 0x0096, 0x6314, 0x2348, 0xa87a,
- 0xa982, 0x080c, 0x6dbe, 0x009e, 0x003e, 0x00de, 0x0005, 0x91b6,
- 0x0015, 0x1118, 0x080c, 0xb0e7, 0x0030, 0x91b6, 0x0016, 0x190c,
- 0x0dc5, 0x080c, 0xb0e7, 0x0005, 0x20a9, 0x000e, 0x20e1, 0x0000,
- 0x2e98, 0x6014, 0x0096, 0x2048, 0xa860, 0x20e8, 0xa85c, 0x20a0,
- 0x009e, 0x4003, 0x9196, 0x0016, 0x01f0, 0x0136, 0x9080, 0x001b,
- 0x20a0, 0x2011, 0x0006, 0x20a9, 0x0001, 0x3418, 0x8318, 0x23a0,
- 0x4003, 0x3318, 0x8318, 0x2398, 0x8211, 0x1db8, 0x2011, 0x0006,
- 0x013e, 0x20a0, 0x3318, 0x8318, 0x2398, 0x4003, 0x3418, 0x8318,
- 0x23a0, 0x8211, 0x1db8, 0x0096, 0x080c, 0xce3f, 0x0130, 0x6014,
- 0x2048, 0xa807, 0x0000, 0xa867, 0x0103, 0x009e, 0x0804, 0xb0e7,
- 0x0096, 0x00d6, 0x0036, 0x7330, 0x9386, 0x0200, 0x11a8, 0x6010,
- 0x00b6, 0x2058, 0xb8cf, 0x0000, 0x00be, 0x6014, 0x9005, 0x0130,
- 0x2048, 0xa807, 0x0000, 0xa867, 0x0103, 0xab32, 0x080c, 0xb0e7,
- 0x003e, 0x00de, 0x009e, 0x0005, 0x0011, 0x1d48, 0x0cc8, 0x0006,
- 0x0016, 0x080c, 0xd548, 0x0188, 0x6014, 0x9005, 0x1170, 0x600b,
- 0x0003, 0x601b, 0x0000, 0x6043, 0x0000, 0x2009, 0x0022, 0x080c,
- 0xb8f2, 0x9006, 0x001e, 0x000e, 0x0005, 0x9085, 0x0001, 0x0cd0,
- 0x0096, 0x0016, 0x20a9, 0x0014, 0x9e80, 0x000c, 0x20e1, 0x0000,
- 0x2098, 0x6014, 0x2048, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0002,
- 0x20a0, 0x4003, 0x2001, 0x0205, 0x2003, 0x0001, 0x2099, 0x0260,
- 0x20a9, 0x0016, 0x4003, 0x20a9, 0x000a, 0xa804, 0x2048, 0xa860,
- 0x20e8, 0xa85c, 0x9080, 0x0002, 0x20a0, 0x4003, 0x2001, 0x0205,
- 0x2003, 0x0002, 0x2099, 0x0260, 0x20a9, 0x0020, 0x4003, 0x2003,
- 0x0000, 0x6014, 0x2048, 0xa800, 0x2048, 0xa867, 0x0103, 0x080c,
- 0xb0e7, 0x001e, 0x009e, 0x0005, 0x0096, 0x0016, 0x900e, 0x7030,
- 0x9086, 0x0100, 0x0140, 0x7038, 0x9084, 0x00ff, 0x800c, 0x703c,
- 0x9084, 0x00ff, 0x8004, 0x9080, 0x0004, 0x9108, 0x810b, 0x2011,
- 0x0002, 0x2019, 0x000c, 0x6014, 0x2048, 0x080c, 0xc9f0, 0x080c,
- 0xce3f, 0x0140, 0x6014, 0x2048, 0xa807, 0x0000, 0xa864, 0xa8e2,
- 0xa867, 0x0103, 0x080c, 0xb0e7, 0x001e, 0x009e, 0x0005, 0x0016,
- 0x2009, 0x0000, 0x7030, 0x9086, 0x0200, 0x0110, 0x2009, 0x0001,
- 0x0096, 0x6014, 0x904d, 0x090c, 0x0dc5, 0xa97a, 0x080c, 0x6dcb,
- 0x009e, 0x080c, 0xb0e7, 0x001e, 0x0005, 0x0016, 0x0096, 0x7030,
- 0x9086, 0x0100, 0x1118, 0x2009, 0x0004, 0x0010, 0x7034, 0x800c,
- 0x810b, 0x2011, 0x000c, 0x2019, 0x000c, 0x6014, 0x2048, 0xa804,
- 0x0096, 0x9005, 0x0108, 0x2048, 0x080c, 0xc9f0, 0x009e, 0x080c,
- 0xce3f, 0x0148, 0xa804, 0x9005, 0x1158, 0xa807, 0x0000, 0xa864,
- 0xa8e2, 0xa867, 0x0103, 0x080c, 0xb0e7, 0x009e, 0x001e, 0x0005,
- 0x0086, 0x2040, 0xa030, 0x8007, 0x9086, 0x0100, 0x1118, 0x080c,
- 0xbacb, 0x00e0, 0xa034, 0x8007, 0x800c, 0x8806, 0x8006, 0x8007,
- 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, 0x000c, 0xa87b, 0x0000,
- 0xa883, 0x0000, 0xa897, 0x4000, 0xaaa0, 0xab9c, 0xaca8, 0xada4,
- 0x2031, 0x0000, 0x2041, 0x1252, 0x0019, 0x0d08, 0x008e, 0x0898,
- 0x0096, 0x0006, 0x080c, 0x100e, 0x000e, 0x01b0, 0xa8ab, 0x0dcb,
- 0xa876, 0x000e, 0xa8a2, 0x0006, 0xae6a, 0x2800, 0xa89e, 0xa97a,
- 0xaf72, 0xaa8e, 0xab92, 0xac96, 0xad9a, 0x0086, 0x2940, 0x080c,
- 0x10f8, 0x008e, 0x9085, 0x0001, 0x009e, 0x0005, 0x00e6, 0x00d6,
+ 0x9ca8, 0x0018, 0x7068, 0x9502, 0x1230, 0x755a, 0x9085, 0x0001,
+ 0x012e, 0x00ee, 0x0005, 0x705b, 0x1cd0, 0x0cc0, 0x9006, 0x0cc0,
+ 0x6020, 0x9084, 0x000f, 0x0002, 0xb193, 0xb19c, 0xb1b7, 0xb1d2,
+ 0xd5a9, 0xd5c6, 0xd5e1, 0xb193, 0xb19c, 0x8fcd, 0xb1eb, 0xb193,
+ 0xb193, 0xb193, 0xb193, 0x9186, 0x0013, 0x1128, 0x080c, 0x97e1,
+ 0x080c, 0x98ed, 0x0005, 0x0005, 0x0066, 0x6000, 0x90b2, 0x0010,
+ 0x1a0c, 0x0dc5, 0x0013, 0x006e, 0x0005, 0xb1b5, 0xb931, 0xbb29,
+ 0xb1b5, 0xbbbf, 0xb4ce, 0xb1b5, 0xb1b5, 0xb8b3, 0xc12f, 0xb1b5,
+ 0xb1b5, 0xb1b5, 0xb1b5, 0xb1b5, 0xb1b5, 0x080c, 0x0dc5, 0x0066,
+ 0x6000, 0x90b2, 0x0010, 0x1a0c, 0x0dc5, 0x0013, 0x006e, 0x0005,
+ 0xb1d0, 0xc7fc, 0xb1d0, 0xb1d0, 0xb1d0, 0xb1d0, 0xb1d0, 0xb1d0,
+ 0xc793, 0xc97e, 0xb1d0, 0xc83d, 0xc8bc, 0xc83d, 0xc8bc, 0xb1d0,
+ 0x080c, 0x0dc5, 0x6000, 0x9082, 0x0010, 0x1a0c, 0x0dc5, 0x6000,
+ 0x0002, 0xb1e9, 0xc176, 0xc23e, 0xc371, 0xc520, 0xb1e9, 0xb1e9,
+ 0xb1e9, 0xc14a, 0xc71f, 0xc722, 0xb1e9, 0xb1e9, 0xb1e9, 0xb1e9,
+ 0xc751, 0x080c, 0x0dc5, 0x0066, 0x6000, 0x90b2, 0x0010, 0x1a0c,
+ 0x0dc5, 0x0013, 0x006e, 0x0005, 0xb204, 0xb204, 0xb247, 0xb2e6,
+ 0xb37b, 0xb204, 0xb204, 0xb204, 0xb206, 0xb204, 0xb204, 0xb204,
+ 0xb204, 0xb204, 0xb204, 0xb204, 0x080c, 0x0dc5, 0x9186, 0x004c,
+ 0x0588, 0x9186, 0x0003, 0x190c, 0x0dc5, 0x0096, 0x601c, 0xc0ed,
+ 0x601e, 0x6003, 0x0003, 0x6106, 0x6014, 0x2048, 0xa87c, 0x9084,
+ 0xa000, 0xc0b5, 0xa87e, 0xa8ac, 0xa846, 0xa8b0, 0xa84a, 0x9006,
+ 0xa836, 0xa83a, 0xa884, 0x9092, 0x199a, 0x0210, 0x2001, 0x1999,
+ 0x8003, 0x8013, 0x8213, 0x9210, 0x621a, 0x009e, 0x2c10, 0x080c,
+ 0x1c09, 0x080c, 0x93a0, 0x0126, 0x2091, 0x8000, 0x080c, 0x9a0f,
+ 0x012e, 0x0005, 0x6010, 0x00b6, 0x2058, 0xbca0, 0x00be, 0x2c00,
+ 0x080c, 0xb39d, 0x080c, 0xd579, 0x6003, 0x0007, 0x0005, 0x00d6,
+ 0x0096, 0x00f6, 0x2079, 0x1800, 0x7a90, 0x6014, 0x2048, 0xa87c,
+ 0xd0ec, 0x1110, 0x9290, 0x0018, 0xac78, 0xc4fc, 0x0046, 0xa8e0,
+ 0x9005, 0x1140, 0xa8dc, 0x921a, 0x0140, 0x0220, 0xa87b, 0x0007,
+ 0x2010, 0x0028, 0xa87b, 0x0015, 0x0010, 0xa87b, 0x0000, 0x8214,
+ 0xa883, 0x0000, 0xaa02, 0x0006, 0x0016, 0x0026, 0x00c6, 0x00d6,
+ 0x00e6, 0x00f6, 0x2400, 0x9005, 0x1108, 0x009a, 0x2100, 0x9086,
+ 0x0015, 0x1118, 0x2001, 0x0001, 0x0038, 0x2100, 0x9086, 0x0016,
+ 0x0118, 0x2001, 0x0001, 0x002a, 0x94a4, 0x0007, 0x8423, 0x9405,
+ 0x0002, 0xb2ae, 0xb2ae, 0xb2a9, 0xb2ac, 0xb2ae, 0xb2a6, 0xb299,
+ 0xb299, 0xb299, 0xb299, 0xb299, 0xb299, 0xb299, 0xb299, 0xb299,
+ 0xb299, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x002e, 0x001e, 0x000e,
+ 0x004e, 0x00fe, 0x009e, 0x00de, 0x080c, 0x0dc5, 0x080c, 0xbd80,
+ 0x0028, 0x080c, 0xbe67, 0x0010, 0x080c, 0xbf5d, 0x00fe, 0x00ee,
+ 0x00de, 0x00ce, 0x002e, 0x001e, 0x2c00, 0xa896, 0x000e, 0x080c,
+ 0xb45b, 0x0530, 0xa804, 0xa80e, 0x00a6, 0x2050, 0xb100, 0x00ae,
+ 0x8006, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080,
+ 0x0002, 0xaacc, 0xabd0, 0xacd4, 0xadd8, 0x2031, 0x0000, 0x2041,
+ 0x126c, 0x080c, 0xb61f, 0x0160, 0x000e, 0x9005, 0x0120, 0x00fe,
+ 0x009e, 0x00de, 0x0005, 0x00fe, 0x009e, 0x00de, 0x0804, 0xb101,
+ 0x2001, 0x002c, 0x900e, 0x080c, 0xb4c1, 0x0c70, 0x91b6, 0x0015,
+ 0x0170, 0x91b6, 0x0016, 0x0158, 0x91b2, 0x0047, 0x0a0c, 0x0dc5,
+ 0x91b2, 0x0050, 0x1a0c, 0x0dc5, 0x9182, 0x0047, 0x00ca, 0x2001,
+ 0x0109, 0x2004, 0xd08c, 0x0198, 0x0126, 0x2091, 0x2800, 0x0006,
+ 0x0016, 0x0026, 0x080c, 0x92ed, 0x002e, 0x001e, 0x000e, 0x012e,
+ 0xa001, 0x6000, 0x9086, 0x0002, 0x1110, 0x0804, 0xb247, 0x0005,
+ 0xb319, 0xb319, 0xb31b, 0xb351, 0xb319, 0xb319, 0xb319, 0xb319,
+ 0xb364, 0x080c, 0x0dc5, 0x00d6, 0x0016, 0x0096, 0x080c, 0x989d,
+ 0x080c, 0x9a0f, 0x6003, 0x0004, 0x6114, 0x2148, 0xa87c, 0xd0fc,
+ 0x01c0, 0xa878, 0xc0fc, 0x9005, 0x1158, 0xa894, 0x9005, 0x0140,
+ 0x2001, 0x0000, 0x900e, 0x080c, 0xb4c1, 0x080c, 0xb101, 0x00a8,
+ 0x6003, 0x0002, 0xa8a4, 0xa9a8, 0x9105, 0x1178, 0xa8ae, 0xa8b2,
+ 0x0c78, 0xa87f, 0x0020, 0xa88c, 0xa88a, 0xa8a4, 0xa8ae, 0xa8a8,
+ 0xa8b2, 0xa8c7, 0x0000, 0xa8cb, 0x0000, 0x009e, 0x001e, 0x00de,
+ 0x0005, 0x080c, 0x989d, 0x00d6, 0x0096, 0x6114, 0x2148, 0x080c,
+ 0xce56, 0x0120, 0xa87b, 0x0006, 0x080c, 0x6dd1, 0x009e, 0x00de,
+ 0x080c, 0xb101, 0x0804, 0x9a0f, 0x080c, 0x989d, 0x080c, 0x3246,
+ 0x080c, 0xd576, 0x00d6, 0x0096, 0x6114, 0x2148, 0x080c, 0xce56,
+ 0x0120, 0xa87b, 0x0029, 0x080c, 0x6dd1, 0x009e, 0x00de, 0x080c,
+ 0xb101, 0x0804, 0x9a0f, 0x9182, 0x0047, 0x0002, 0xb38b, 0xb38d,
+ 0xb38b, 0xb38b, 0xb38b, 0xb38b, 0xb38b, 0xb38b, 0xb38b, 0xb38b,
+ 0xb38b, 0xb38b, 0xb38d, 0x080c, 0x0dc5, 0x00d6, 0x0096, 0x601f,
+ 0x0000, 0x6114, 0x2148, 0xa87b, 0x0000, 0xa883, 0x0000, 0x080c,
+ 0x6dd1, 0x009e, 0x00de, 0x0804, 0xb101, 0x0026, 0x0036, 0x0056,
+ 0x0066, 0x0096, 0x00a6, 0x00f6, 0x0006, 0x080c, 0x100e, 0x000e,
+ 0x090c, 0x0dc5, 0xa960, 0x21e8, 0xa95c, 0x9188, 0x0019, 0x21a0,
+ 0x900e, 0x20a9, 0x0020, 0x4104, 0xa87a, 0x2079, 0x1800, 0x7990,
+ 0x9188, 0x0018, 0x918c, 0x0fff, 0xa972, 0xac76, 0x2950, 0x00a6,
+ 0x2001, 0x0205, 0x2003, 0x0000, 0x901e, 0x2029, 0x0001, 0x9182,
+ 0x0035, 0x1228, 0x2011, 0x001f, 0x080c, 0xca03, 0x04c0, 0x2130,
+ 0x2009, 0x0034, 0x2011, 0x001f, 0x080c, 0xca03, 0x96b2, 0x0034,
+ 0xb004, 0x904d, 0x0110, 0x080c, 0x0fc0, 0x080c, 0x100e, 0x01d0,
+ 0x8528, 0xa867, 0x0110, 0xa86b, 0x0000, 0x2920, 0xb406, 0x968a,
+ 0x003d, 0x1230, 0x2608, 0x2011, 0x001b, 0x080c, 0xca03, 0x00b8,
+ 0x96b2, 0x003c, 0x2009, 0x003c, 0x2950, 0x2011, 0x001b, 0x080c,
+ 0xca03, 0x0c18, 0x2001, 0x0205, 0x2003, 0x0000, 0x00ae, 0x852f,
+ 0x95ad, 0x0050, 0xb566, 0xb070, 0xc0fd, 0xb072, 0x0048, 0x2001,
+ 0x0205, 0x2003, 0x0000, 0x00ae, 0x852f, 0x95ad, 0x0050, 0xb566,
+ 0x2a48, 0xa804, 0xa807, 0x0000, 0x0006, 0x080c, 0x6dd1, 0x000e,
+ 0x2048, 0x9005, 0x1db0, 0x00fe, 0x00ae, 0x009e, 0x006e, 0x005e,
+ 0x003e, 0x002e, 0x0005, 0x00d6, 0x00f6, 0x0096, 0x0006, 0x080c,
+ 0x100e, 0x000e, 0x090c, 0x0dc5, 0xa960, 0x21e8, 0xa95c, 0x9188,
+ 0x0019, 0x21a0, 0x900e, 0x20a9, 0x0020, 0x4104, 0xaa66, 0xa87a,
+ 0x2079, 0x1800, 0x7990, 0x810c, 0x9188, 0x000c, 0x9182, 0x001a,
+ 0x0210, 0x2009, 0x001a, 0x21a8, 0x810b, 0xa972, 0xac76, 0x2e98,
+ 0xa85c, 0x9080, 0x001f, 0x20a0, 0x2001, 0x0205, 0x200c, 0x918d,
+ 0x0080, 0x2102, 0x4003, 0x2003, 0x0000, 0x080c, 0x6dd1, 0x009e,
+ 0x00fe, 0x00de, 0x0005, 0x0016, 0x00d6, 0x00f6, 0x0096, 0x0016,
+ 0x2001, 0x0205, 0x200c, 0x918d, 0x0080, 0x2102, 0x001e, 0x2079,
+ 0x0200, 0x2e98, 0xa87c, 0xd0ec, 0x0118, 0x9e80, 0x000c, 0x2098,
+ 0x2021, 0x003e, 0x901e, 0x9282, 0x0020, 0x0218, 0x2011, 0x0020,
+ 0x2018, 0x9486, 0x003e, 0x1170, 0x0096, 0x080c, 0x100e, 0x2900,
+ 0x009e, 0x05c0, 0xa806, 0x2048, 0xa860, 0x20e8, 0xa85c, 0x9080,
+ 0x0002, 0x20a0, 0x3300, 0x908e, 0x0260, 0x0140, 0x2009, 0x0280,
+ 0x9102, 0x920a, 0x0218, 0x2010, 0x2100, 0x9318, 0x2200, 0x9402,
+ 0x1228, 0x2400, 0x9202, 0x2410, 0x9318, 0x9006, 0x2020, 0x22a8,
+ 0xa800, 0x9200, 0xa802, 0x20e1, 0x0000, 0x4003, 0x83ff, 0x0180,
+ 0x3300, 0x9086, 0x0280, 0x1130, 0x7814, 0x8000, 0x9085, 0x0080,
+ 0x7816, 0x2e98, 0x2310, 0x84ff, 0x0904, 0xb470, 0x0804, 0xb472,
+ 0x9085, 0x0001, 0x7817, 0x0000, 0x009e, 0x00fe, 0x00de, 0x001e,
+ 0x0005, 0x00d6, 0x0036, 0x0096, 0x6314, 0x2348, 0xa87a, 0xa982,
+ 0x080c, 0x6dc4, 0x009e, 0x003e, 0x00de, 0x0005, 0x91b6, 0x0015,
+ 0x1118, 0x080c, 0xb101, 0x0030, 0x91b6, 0x0016, 0x190c, 0x0dc5,
+ 0x080c, 0xb101, 0x0005, 0x20a9, 0x000e, 0x20e1, 0x0000, 0x2e98,
+ 0x6014, 0x0096, 0x2048, 0xa860, 0x20e8, 0xa85c, 0x20a0, 0x009e,
+ 0x4003, 0x9196, 0x0016, 0x01f0, 0x0136, 0x9080, 0x001b, 0x20a0,
+ 0x2011, 0x0006, 0x20a9, 0x0001, 0x3418, 0x8318, 0x23a0, 0x4003,
+ 0x3318, 0x8318, 0x2398, 0x8211, 0x1db8, 0x2011, 0x0006, 0x013e,
+ 0x20a0, 0x3318, 0x8318, 0x2398, 0x4003, 0x3418, 0x8318, 0x23a0,
+ 0x8211, 0x1db8, 0x0096, 0x080c, 0xce56, 0x0130, 0x6014, 0x2048,
+ 0xa807, 0x0000, 0xa867, 0x0103, 0x009e, 0x0804, 0xb101, 0x0096,
+ 0x00d6, 0x0036, 0x7330, 0x9386, 0x0200, 0x11a8, 0x6010, 0x00b6,
+ 0x2058, 0xb8cf, 0x0000, 0x00be, 0x6014, 0x9005, 0x0130, 0x2048,
+ 0xa807, 0x0000, 0xa867, 0x0103, 0xab32, 0x080c, 0xb101, 0x003e,
+ 0x00de, 0x009e, 0x0005, 0x0011, 0x1d48, 0x0cc8, 0x0006, 0x0016,
+ 0x080c, 0xd561, 0x0188, 0x6014, 0x9005, 0x1170, 0x600b, 0x0003,
+ 0x601b, 0x0000, 0x6043, 0x0000, 0x2009, 0x0022, 0x080c, 0xb909,
+ 0x9006, 0x001e, 0x000e, 0x0005, 0x9085, 0x0001, 0x0cd0, 0x0096,
+ 0x0016, 0x20a9, 0x0014, 0x9e80, 0x000c, 0x20e1, 0x0000, 0x2098,
+ 0x6014, 0x2048, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0002, 0x20a0,
+ 0x4003, 0x2001, 0x0205, 0x2003, 0x0001, 0x2099, 0x0260, 0x20a9,
+ 0x0016, 0x4003, 0x20a9, 0x000a, 0xa804, 0x2048, 0xa860, 0x20e8,
+ 0xa85c, 0x9080, 0x0002, 0x20a0, 0x4003, 0x2001, 0x0205, 0x2003,
+ 0x0002, 0x2099, 0x0260, 0x20a9, 0x0020, 0x4003, 0x2003, 0x0000,
+ 0x6014, 0x2048, 0xa800, 0x2048, 0xa867, 0x0103, 0x080c, 0xb101,
+ 0x001e, 0x009e, 0x0005, 0x0096, 0x0016, 0x900e, 0x7030, 0x9086,
+ 0x0100, 0x0140, 0x7038, 0x9084, 0x00ff, 0x800c, 0x703c, 0x9084,
+ 0x00ff, 0x8004, 0x9080, 0x0004, 0x9108, 0x810b, 0x2011, 0x0002,
+ 0x2019, 0x000c, 0x6014, 0x2048, 0x080c, 0xca03, 0x080c, 0xce56,
+ 0x0140, 0x6014, 0x2048, 0xa807, 0x0000, 0xa864, 0xa8e2, 0xa867,
+ 0x0103, 0x080c, 0xb101, 0x001e, 0x009e, 0x0005, 0x0016, 0x2009,
+ 0x0000, 0x7030, 0x9086, 0x0200, 0x0110, 0x2009, 0x0001, 0x0096,
+ 0x6014, 0x904d, 0x090c, 0x0dc5, 0xa97a, 0x080c, 0x6dd1, 0x009e,
+ 0x080c, 0xb101, 0x001e, 0x0005, 0x0016, 0x0096, 0x7030, 0x9086,
+ 0x0100, 0x1118, 0x2009, 0x0004, 0x0010, 0x7034, 0x800c, 0x810b,
+ 0x2011, 0x000c, 0x2019, 0x000c, 0x6014, 0x2048, 0xa804, 0x0096,
+ 0x9005, 0x0108, 0x2048, 0x080c, 0xca03, 0x009e, 0x080c, 0xce56,
+ 0x0148, 0xa804, 0x9005, 0x1158, 0xa807, 0x0000, 0xa864, 0xa8e2,
+ 0xa867, 0x0103, 0x080c, 0xb101, 0x009e, 0x001e, 0x0005, 0x0086,
+ 0x2040, 0xa030, 0x8007, 0x9086, 0x0100, 0x1118, 0x080c, 0xbae2,
+ 0x00e0, 0xa034, 0x8007, 0x800c, 0x8806, 0x8006, 0x8007, 0x90bc,
+ 0x003f, 0x9084, 0xffc0, 0x9080, 0x000c, 0xa87b, 0x0000, 0xa883,
+ 0x0000, 0xa897, 0x4000, 0xaaa0, 0xab9c, 0xaca8, 0xada4, 0x2031,
+ 0x0000, 0x2041, 0x1252, 0x0019, 0x0d08, 0x008e, 0x0898, 0x0096,
+ 0x0006, 0x080c, 0x100e, 0x000e, 0x01b0, 0xa8ab, 0x0dcb, 0xa876,
+ 0x000e, 0xa8a2, 0x0006, 0xae6a, 0x2800, 0xa89e, 0xa97a, 0xaf72,
+ 0xaa8e, 0xab92, 0xac96, 0xad9a, 0x0086, 0x2940, 0x080c, 0x10f8,
+ 0x008e, 0x9085, 0x0001, 0x009e, 0x0005, 0x00e6, 0x00d6, 0x0026,
+ 0x7008, 0x9084, 0x00ff, 0x6210, 0x00b6, 0x2258, 0xba10, 0x00be,
+ 0x9206, 0x1520, 0x700c, 0x6210, 0x00b6, 0x2258, 0xba14, 0x00be,
+ 0x9206, 0x11e0, 0x6043, 0x0000, 0x2c68, 0x0016, 0x2009, 0x0035,
+ 0x080c, 0xd4d7, 0x001e, 0x1158, 0x622c, 0x2268, 0x2071, 0x026c,
+ 0x6b20, 0x9386, 0x0003, 0x0130, 0x9386, 0x0006, 0x0128, 0x080c,
+ 0xb101, 0x0020, 0x0039, 0x0010, 0x080c, 0xb73e, 0x002e, 0x00de,
+ 0x00ee, 0x0005, 0x0096, 0x6814, 0x2048, 0x9186, 0x0015, 0x0904,
+ 0xb726, 0x918e, 0x0016, 0x1904, 0xb73c, 0x700c, 0x908c, 0xff00,
+ 0x9186, 0x1700, 0x0120, 0x9186, 0x0300, 0x1904, 0xb700, 0x89ff,
+ 0x1138, 0x6800, 0x9086, 0x000f, 0x0904, 0xb6e3, 0x0804, 0xb73a,
+ 0x6808, 0x9086, 0xffff, 0x1904, 0xb728, 0xa87c, 0x9084, 0x0060,
+ 0x9086, 0x0020, 0x1128, 0xa83c, 0xa940, 0x9105, 0x1904, 0xb728,
+ 0x6824, 0xd084, 0x1904, 0xb728, 0xd0b4, 0x0158, 0x0016, 0x2001,
+ 0x1987, 0x200c, 0x6018, 0x9102, 0x9082, 0x0005, 0x001e, 0x1a04,
+ 0xb728, 0x080c, 0xd041, 0x685c, 0xa882, 0xa87c, 0xc0dc, 0xc0f4,
+ 0xc0d4, 0xa87e, 0x0026, 0x900e, 0x6a18, 0x2001, 0x000a, 0x080c,
+ 0x91b1, 0xa884, 0x920a, 0x0208, 0x8011, 0xaa86, 0x82ff, 0x002e,
+ 0x1138, 0x00c6, 0x2d60, 0x080c, 0xcb65, 0x00ce, 0x0804, 0xb73a,
+ 0x00c6, 0xa868, 0xd0fc, 0x1118, 0x080c, 0x61bb, 0x0010, 0x080c,
+ 0x65c8, 0x00ce, 0x1904, 0xb728, 0x00c6, 0x2d60, 0x080c, 0xb101,
+ 0x00ce, 0x0804, 0xb73a, 0x00c6, 0x080c, 0xb153, 0x0198, 0x6017,
+ 0x0000, 0x6810, 0x6012, 0x080c, 0xd2d2, 0x6023, 0x0003, 0x6904,
+ 0x00c6, 0x2d60, 0x080c, 0xb101, 0x00ce, 0x080c, 0xb180, 0x00ce,
+ 0x0804, 0xb73a, 0x2001, 0x1989, 0x2004, 0x6842, 0x00ce, 0x04d0,
+ 0x7008, 0x9086, 0x000b, 0x11c8, 0x6010, 0x00b6, 0x2058, 0xb900,
+ 0xc1bc, 0xb902, 0x00be, 0x00c6, 0x2d60, 0xa87b, 0x0003, 0x080c,
+ 0xd51b, 0x6007, 0x0085, 0x6003, 0x000b, 0x6023, 0x0002, 0x080c,
+ 0x933b, 0x080c, 0x98ed, 0x00ce, 0x00e8, 0x700c, 0x9086, 0x2a00,
+ 0x1138, 0x2001, 0x1989, 0x2004, 0x6842, 0x00a0, 0x0479, 0x00a0,
+ 0x89ff, 0x090c, 0x0dc5, 0x00c6, 0x00d6, 0x2d60, 0xa867, 0x0103,
+ 0xa87b, 0x0003, 0x080c, 0x6beb, 0x080c, 0xd041, 0x080c, 0xb134,
+ 0x00de, 0x00ce, 0x080c, 0xb101, 0x009e, 0x0005, 0x9186, 0x0015,
+ 0x1128, 0x2001, 0x1989, 0x2004, 0x6842, 0x0068, 0x918e, 0x0016,
+ 0x1160, 0x00c6, 0x2d00, 0x2060, 0x080c, 0xec02, 0x080c, 0x88f1,
+ 0x080c, 0xb101, 0x00ce, 0x080c, 0xb101, 0x0005, 0x0026, 0x0036,
+ 0x0046, 0x7228, 0xacb0, 0xabac, 0xd2f4, 0x0130, 0x2001, 0x1989,
+ 0x2004, 0x6842, 0x0804, 0xb7b8, 0x00c6, 0x2d60, 0x080c, 0xca64,
+ 0x00ce, 0x6804, 0x9086, 0x0050, 0x1168, 0x00c6, 0x2d00, 0x2060,
+ 0x6003, 0x0001, 0x6007, 0x0050, 0x080c, 0x933b, 0x080c, 0x98ed,
+ 0x00ce, 0x04f0, 0x6800, 0x9086, 0x000f, 0x01a8, 0x89ff, 0x090c,
+ 0x0dc5, 0x6800, 0x9086, 0x0004, 0x1190, 0xa87c, 0xd0ac, 0x0178,
+ 0xa843, 0x0fff, 0xa83f, 0x0fff, 0xa880, 0xc0fc, 0xa882, 0x2001,
+ 0x0001, 0x6832, 0x0400, 0x2001, 0x0007, 0x6832, 0x00e0, 0xa87c,
+ 0xd0b4, 0x1150, 0xd0ac, 0x0db8, 0x6824, 0xd0f4, 0x1d48, 0xa838,
+ 0xa934, 0x9105, 0x0d80, 0x0c20, 0xd2ec, 0x1d68, 0x7024, 0x9306,
+ 0x1118, 0x7020, 0x9406, 0x0d38, 0x7020, 0x683e, 0x7024, 0x683a,
+ 0x2001, 0x0005, 0x6832, 0x080c, 0xd1c9, 0x080c, 0x98ed, 0x0010,
+ 0x080c, 0xb101, 0x004e, 0x003e, 0x002e, 0x0005, 0x00e6, 0x00d6,
0x0026, 0x7008, 0x9084, 0x00ff, 0x6210, 0x00b6, 0x2258, 0xba10,
- 0x00be, 0x9206, 0x1520, 0x700c, 0x6210, 0x00b6, 0x2258, 0xba14,
- 0x00be, 0x9206, 0x11e0, 0x6043, 0x0000, 0x2c68, 0x0016, 0x2009,
- 0x0035, 0x080c, 0xd4c0, 0x001e, 0x1158, 0x622c, 0x2268, 0x2071,
- 0x026c, 0x6b20, 0x9386, 0x0003, 0x0130, 0x9386, 0x0006, 0x0128,
- 0x080c, 0xb0e7, 0x0020, 0x0039, 0x0010, 0x080c, 0xb727, 0x002e,
- 0x00de, 0x00ee, 0x0005, 0x0096, 0x6814, 0x2048, 0x9186, 0x0015,
- 0x0904, 0xb70f, 0x918e, 0x0016, 0x1904, 0xb725, 0x700c, 0x908c,
- 0xff00, 0x9186, 0x1700, 0x0120, 0x9186, 0x0300, 0x1904, 0xb6e9,
- 0x89ff, 0x1138, 0x6800, 0x9086, 0x000f, 0x0904, 0xb6cc, 0x0804,
- 0xb723, 0x6808, 0x9086, 0xffff, 0x1904, 0xb711, 0xa87c, 0x9084,
- 0x0060, 0x9086, 0x0020, 0x1128, 0xa83c, 0xa940, 0x9105, 0x1904,
- 0xb711, 0x6824, 0xd084, 0x1904, 0xb711, 0xd0b4, 0x0158, 0x0016,
- 0x2001, 0x1987, 0x200c, 0x6018, 0x9102, 0x9082, 0x0005, 0x001e,
- 0x1a04, 0xb711, 0x080c, 0xd02a, 0x685c, 0xa882, 0xa87c, 0xc0dc,
- 0xc0f4, 0xc0d4, 0xa87e, 0x0026, 0x900e, 0x6a18, 0x2001, 0x000a,
- 0x080c, 0x91ab, 0xa884, 0x920a, 0x0208, 0x8011, 0xaa86, 0x82ff,
- 0x002e, 0x1138, 0x00c6, 0x2d60, 0x080c, 0xcb52, 0x00ce, 0x0804,
- 0xb723, 0x00c6, 0xa868, 0xd0fc, 0x1118, 0x080c, 0x61b5, 0x0010,
- 0x080c, 0x65c2, 0x00ce, 0x1904, 0xb711, 0x00c6, 0x2d60, 0x080c,
- 0xb0e7, 0x00ce, 0x0804, 0xb723, 0x00c6, 0x080c, 0xb139, 0x0198,
- 0x6017, 0x0000, 0x6810, 0x6012, 0x080c, 0xd2bb, 0x6023, 0x0003,
- 0x6904, 0x00c6, 0x2d60, 0x080c, 0xb0e7, 0x00ce, 0x080c, 0xb166,
- 0x00ce, 0x0804, 0xb723, 0x2001, 0x1989, 0x2004, 0x6842, 0x00ce,
- 0x04d0, 0x7008, 0x9086, 0x000b, 0x11c8, 0x6010, 0x00b6, 0x2058,
- 0xb900, 0xc1bc, 0xb902, 0x00be, 0x00c6, 0x2d60, 0xa87b, 0x0003,
- 0x080c, 0xd502, 0x6007, 0x0085, 0x6003, 0x000b, 0x6023, 0x0002,
- 0x080c, 0x9335, 0x080c, 0x98e7, 0x00ce, 0x00e8, 0x700c, 0x9086,
- 0x2a00, 0x1138, 0x2001, 0x1989, 0x2004, 0x6842, 0x00a0, 0x0479,
- 0x00a0, 0x89ff, 0x090c, 0x0dc5, 0x00c6, 0x00d6, 0x2d60, 0xa867,
- 0x0103, 0xa87b, 0x0003, 0x080c, 0x6be5, 0x080c, 0xd02a, 0x080c,
- 0xb11a, 0x00de, 0x00ce, 0x080c, 0xb0e7, 0x009e, 0x0005, 0x9186,
- 0x0015, 0x1128, 0x2001, 0x1989, 0x2004, 0x6842, 0x0068, 0x918e,
- 0x0016, 0x1160, 0x00c6, 0x2d00, 0x2060, 0x080c, 0xeb9d, 0x080c,
- 0x88eb, 0x080c, 0xb0e7, 0x00ce, 0x080c, 0xb0e7, 0x0005, 0x0026,
- 0x0036, 0x0046, 0x7228, 0xacb0, 0xabac, 0xd2f4, 0x0130, 0x2001,
- 0x1989, 0x2004, 0x6842, 0x0804, 0xb7a1, 0x00c6, 0x2d60, 0x080c,
- 0xca51, 0x00ce, 0x6804, 0x9086, 0x0050, 0x1168, 0x00c6, 0x2d00,
- 0x2060, 0x6003, 0x0001, 0x6007, 0x0050, 0x080c, 0x9335, 0x080c,
- 0x98e7, 0x00ce, 0x04f0, 0x6800, 0x9086, 0x000f, 0x01a8, 0x89ff,
- 0x090c, 0x0dc5, 0x6800, 0x9086, 0x0004, 0x1190, 0xa87c, 0xd0ac,
- 0x0178, 0xa843, 0x0fff, 0xa83f, 0x0fff, 0xa880, 0xc0fc, 0xa882,
- 0x2001, 0x0001, 0x6832, 0x0400, 0x2001, 0x0007, 0x6832, 0x00e0,
- 0xa87c, 0xd0b4, 0x1150, 0xd0ac, 0x0db8, 0x6824, 0xd0f4, 0x1d48,
- 0xa838, 0xa934, 0x9105, 0x0d80, 0x0c20, 0xd2ec, 0x1d68, 0x7024,
- 0x9306, 0x1118, 0x7020, 0x9406, 0x0d38, 0x7020, 0x683e, 0x7024,
- 0x683a, 0x2001, 0x0005, 0x6832, 0x080c, 0xd1b2, 0x080c, 0x98e7,
- 0x0010, 0x080c, 0xb0e7, 0x004e, 0x003e, 0x002e, 0x0005, 0x00e6,
- 0x00d6, 0x0026, 0x7008, 0x9084, 0x00ff, 0x6210, 0x00b6, 0x2258,
- 0xba10, 0x00be, 0x9206, 0x1904, 0xb80c, 0x700c, 0x6210, 0x00b6,
- 0x2258, 0xba14, 0x00be, 0x9206, 0x1904, 0xb80c, 0x6038, 0x2068,
- 0x6824, 0xc0dc, 0x6826, 0x6a20, 0x9286, 0x0007, 0x0904, 0xb80c,
- 0x9286, 0x0002, 0x0904, 0xb80c, 0x9286, 0x0000, 0x05e8, 0x6808,
- 0x633c, 0x9306, 0x15c8, 0x2071, 0x026c, 0x9186, 0x0015, 0x0570,
- 0x918e, 0x0016, 0x1100, 0x00c6, 0x6038, 0x2060, 0x6104, 0x9186,
- 0x004b, 0x01c0, 0x9186, 0x004c, 0x01a8, 0x9186, 0x004d, 0x0190,
- 0x9186, 0x004e, 0x0178, 0x9186, 0x0052, 0x0160, 0x6014, 0x0096,
- 0x2048, 0x080c, 0xce3f, 0x090c, 0x0dc5, 0xa87b, 0x0003, 0x009e,
- 0x080c, 0xd502, 0x6007, 0x0085, 0x6003, 0x000b, 0x6023, 0x0002,
- 0x080c, 0x9335, 0x080c, 0x98e7, 0x00ce, 0x0030, 0x6038, 0x2070,
- 0x2001, 0x1989, 0x2004, 0x7042, 0x080c, 0xb0e7, 0x002e, 0x00de,
- 0x00ee, 0x0005, 0x00b6, 0x0096, 0x00f6, 0x6014, 0x2048, 0x6010,
- 0x2058, 0x91b6, 0x0015, 0x0130, 0xba08, 0xbb0c, 0xbc00, 0xc48c,
- 0xbc02, 0x0460, 0x0096, 0x0156, 0x0036, 0x0026, 0x2b48, 0x9e90,
- 0x0010, 0x2019, 0x000a, 0x20a9, 0x0004, 0x080c, 0xc0e7, 0x002e,
- 0x003e, 0x015e, 0x009e, 0x1904, 0xb87b, 0x0096, 0x0156, 0x0036,
- 0x0026, 0x2b48, 0x9e90, 0x0014, 0x2019, 0x0006, 0x20a9, 0x0004,
- 0x080c, 0xc0e7, 0x002e, 0x003e, 0x015e, 0x009e, 0x15a0, 0x7238,
- 0xba0a, 0x733c, 0xbb0e, 0xbc00, 0xc48d, 0xbc02, 0xa804, 0x9005,
- 0x1128, 0x00fe, 0x009e, 0x00be, 0x0804, 0xb4f3, 0x0096, 0x2048,
- 0xaa12, 0xab16, 0xac0a, 0x009e, 0x8006, 0x8006, 0x8007, 0x90bc,
- 0x003f, 0x9084, 0xffc0, 0x9080, 0x0002, 0x2009, 0x002b, 0xaaa0,
- 0xab9c, 0xaca8, 0xada4, 0x2031, 0x0000, 0x2041, 0x1252, 0x080c,
- 0xb608, 0x0130, 0x00fe, 0x009e, 0x080c, 0xb0e7, 0x00be, 0x0005,
- 0x080c, 0xbacb, 0x0cb8, 0x2b78, 0x00f6, 0x080c, 0x324b, 0x080c,
- 0xd55d, 0x00fe, 0x00c6, 0x080c, 0xb091, 0x2f00, 0x6012, 0x6017,
- 0x0000, 0x6023, 0x0001, 0x6007, 0x0001, 0x6003, 0x0001, 0x2001,
- 0x0007, 0x080c, 0x665d, 0x080c, 0x6689, 0x080c, 0x937d, 0x080c,
- 0x98e7, 0x00ce, 0x0804, 0xb84e, 0x2100, 0x91b2, 0x0053, 0x1a0c,
- 0x0dc5, 0x91b2, 0x0040, 0x1a04, 0xb904, 0x0002, 0xb8f2, 0xb8f2,
- 0xb8e8, 0xb8f2, 0xb8f2, 0xb8f2, 0xb8e6, 0xb8e6, 0xb8e6, 0xb8e6,
- 0xb8e6, 0xb8e6, 0xb8e6, 0xb8e6, 0xb8e6, 0xb8e6, 0xb8e6, 0xb8e6,
- 0xb8e6, 0xb8e6, 0xb8e6, 0xb8e6, 0xb8e6, 0xb8e6, 0xb8e6, 0xb8e6,
- 0xb8e6, 0xb8e6, 0xb8e6, 0xb8e6, 0xb8e6, 0xb8f2, 0xb8e6, 0xb8f2,
- 0xb8f2, 0xb8e6, 0xb8e6, 0xb8e6, 0xb8e6, 0xb8e6, 0xb8e8, 0xb8e6,
- 0xb8e6, 0xb8e6, 0xb8e6, 0xb8e6, 0xb8e6, 0xb8e6, 0xb8e6, 0xb8e6,
- 0xb8f2, 0xb8f2, 0xb8e6, 0xb8e6, 0xb8e6, 0xb8e6, 0xb8e6, 0xb8e6,
- 0xb8e6, 0xb8e6, 0xb8e6, 0xb8f2, 0xb8e6, 0xb8e6, 0x080c, 0x0dc5,
- 0x0066, 0x00b6, 0x6610, 0x2658, 0xb8cc, 0xc08c, 0xb8ce, 0x00be,
- 0x006e, 0x0000, 0x6003, 0x0001, 0x6106, 0x9186, 0x0032, 0x0118,
- 0x080c, 0x937d, 0x0010, 0x080c, 0x9335, 0x0126, 0x2091, 0x8000,
- 0x080c, 0x98e7, 0x012e, 0x0005, 0x2600, 0x0002, 0xb8f2, 0xb8f2,
- 0xb918, 0xb8f2, 0xb8f2, 0xb918, 0xb918, 0xb918, 0xb918, 0xb8f2,
- 0xb918, 0xb8f2, 0xb918, 0xb8f2, 0xb918, 0xb918, 0xb918, 0xb918,
- 0x080c, 0x0dc5, 0x6004, 0x90b2, 0x0053, 0x1a0c, 0x0dc5, 0x91b6,
- 0x0013, 0x0904, 0xb9ed, 0x91b6, 0x0027, 0x1904, 0xb997, 0x080c,
- 0x97db, 0x6004, 0x080c, 0xd036, 0x01b0, 0x080c, 0xd047, 0x01a8,
- 0x908e, 0x0021, 0x0904, 0xb994, 0x908e, 0x0022, 0x1130, 0x080c,
- 0xb51f, 0x0904, 0xb990, 0x0804, 0xb991, 0x908e, 0x003d, 0x0904,
- 0xb994, 0x0804, 0xb98a, 0x080c, 0x3274, 0x2001, 0x0007, 0x080c,
- 0x665d, 0x6010, 0x00b6, 0x2058, 0xb9a0, 0x00be, 0x080c, 0xbacb,
- 0x9186, 0x007e, 0x1148, 0x2001, 0x1837, 0x2014, 0xc285, 0x080c,
- 0x7563, 0x1108, 0xc2ad, 0x2202, 0x0036, 0x0026, 0x2019, 0x0028,
- 0x2110, 0x080c, 0xecaa, 0x002e, 0x003e, 0x0016, 0x0026, 0x0036,
- 0x2110, 0x2019, 0x0028, 0x080c, 0x94da, 0x0076, 0x903e, 0x080c,
- 0x93ad, 0x6010, 0x00b6, 0x905d, 0x0100, 0x00be, 0x2c08, 0x080c,
- 0xe671, 0x007e, 0x003e, 0x002e, 0x001e, 0x080c, 0xd55d, 0x0016,
- 0x080c, 0xd2b3, 0x080c, 0xb0e7, 0x001e, 0x080c, 0x3347, 0x080c,
- 0x98e7, 0x0030, 0x080c, 0xd2b3, 0x080c, 0xb0e7, 0x080c, 0x98e7,
- 0x0005, 0x080c, 0xbacb, 0x0cb0, 0x080c, 0xbb07, 0x0c98, 0x9186,
- 0x0015, 0x0118, 0x9186, 0x0016, 0x1148, 0x080c, 0xd56e, 0x0d80,
- 0x6000, 0x9086, 0x0002, 0x0904, 0xbb12, 0x0c50, 0x9186, 0x0014,
- 0x1d38, 0x080c, 0x97db, 0x6004, 0x908e, 0x0022, 0x1118, 0x080c,
- 0xb51f, 0x09f0, 0x080c, 0x324b, 0x080c, 0xd55d, 0x080c, 0xd036,
- 0x1198, 0x080c, 0x3274, 0x6010, 0x00b6, 0x2058, 0xb9a0, 0x00be,
- 0x080c, 0xbacb, 0x9186, 0x007e, 0x1128, 0x2001, 0x1837, 0x200c,
- 0xc185, 0x2102, 0x0804, 0xb98a, 0x080c, 0xd047, 0x1120, 0x080c,
- 0xbacb, 0x0804, 0xb98a, 0x6004, 0x908e, 0x0032, 0x1160, 0x00e6,
- 0x00f6, 0x2071, 0x189e, 0x2079, 0x0000, 0x080c, 0x35e2, 0x00fe,
- 0x00ee, 0x0804, 0xb98a, 0x6004, 0x908e, 0x0021, 0x0d40, 0x908e,
- 0x0022, 0x090c, 0xbacb, 0x0804, 0xb98a, 0x90b2, 0x0040, 0x1a04,
- 0xbaa7, 0x2008, 0x0002, 0xba35, 0xba36, 0xba39, 0xba3c, 0xba3f,
- 0xba4c, 0xba33, 0xba33, 0xba33, 0xba33, 0xba33, 0xba33, 0xba33,
- 0xba33, 0xba33, 0xba33, 0xba33, 0xba33, 0xba33, 0xba33, 0xba33,
- 0xba33, 0xba33, 0xba33, 0xba33, 0xba33, 0xba33, 0xba33, 0xba33,
- 0xba33, 0xba4f, 0xba5c, 0xba33, 0xba5e, 0xba5c, 0xba33, 0xba33,
- 0xba33, 0xba33, 0xba33, 0xba5c, 0xba5c, 0xba33, 0xba33, 0xba33,
- 0xba33, 0xba33, 0xba33, 0xba33, 0xba33, 0xba8e, 0xba5c, 0xba33,
- 0xba58, 0xba33, 0xba33, 0xba33, 0xba59, 0xba33, 0xba33, 0xba33,
- 0xba5c, 0xba85, 0xba33, 0x080c, 0x0dc5, 0x0430, 0x2001, 0x000b,
- 0x0470, 0x2001, 0x0003, 0x0458, 0x2001, 0x0005, 0x0440, 0x6010,
- 0x00b6, 0x2058, 0xb804, 0x00be, 0x9084, 0x00ff, 0x9086, 0x0000,
- 0x1500, 0x2001, 0x0001, 0x00d8, 0x2001, 0x0009, 0x00c0, 0x080c,
- 0x97db, 0x6003, 0x0005, 0x080c, 0xd560, 0x080c, 0x98e7, 0x0070,
- 0x0018, 0x0010, 0x080c, 0x665d, 0x0804, 0xba9f, 0x080c, 0x97db,
- 0x080c, 0xd560, 0x6003, 0x0004, 0x080c, 0x98e7, 0x0005, 0x080c,
- 0x665d, 0x080c, 0x97db, 0x6003, 0x0002, 0x0036, 0x2019, 0x1852,
- 0x2304, 0x9084, 0xff00, 0x1120, 0x2001, 0x1987, 0x201c, 0x0040,
- 0x8007, 0x909a, 0x0004, 0x0ec0, 0x8003, 0x801b, 0x831b, 0x9318,
- 0x631a, 0x003e, 0x080c, 0x98e7, 0x0c08, 0x080c, 0x97db, 0x080c,
- 0xd2b3, 0x080c, 0xb0e7, 0x080c, 0x98e7, 0x08c0, 0x00e6, 0x00f6,
- 0x2071, 0x189e, 0x2079, 0x0000, 0x080c, 0x35e2, 0x00fe, 0x00ee,
- 0x080c, 0x97db, 0x080c, 0xb0e7, 0x080c, 0x98e7, 0x0838, 0x080c,
- 0x97db, 0x6003, 0x0002, 0x080c, 0xd560, 0x0804, 0x98e7, 0x2600,
- 0x2008, 0x0002, 0xbabe, 0xba9f, 0xbabc, 0xba9f, 0xba9f, 0xbabc,
- 0xbabc, 0xbabc, 0xbabc, 0xba9f, 0xbabc, 0xba9f, 0xbabc, 0xba9f,
- 0xbabc, 0xbabc, 0xbabc, 0xbabc, 0x080c, 0x0dc5, 0x080c, 0x97db,
- 0x0096, 0x6014, 0x2048, 0x080c, 0x6dcb, 0x009e, 0x080c, 0xb0e7,
- 0x080c, 0x98e7, 0x0005, 0x00e6, 0x0096, 0x0026, 0x0016, 0x080c,
- 0xce3f, 0x0568, 0x6014, 0x2048, 0xa864, 0x9086, 0x0139, 0x11a8,
- 0xa894, 0x9086, 0x0056, 0x1148, 0x080c, 0x5567, 0x0130, 0x2001,
- 0x0000, 0x900e, 0x2011, 0x4000, 0x0028, 0x2001, 0x0030, 0x900e,
- 0x2011, 0x4005, 0x080c, 0xd424, 0x0090, 0xa868, 0xd0fc, 0x0178,
- 0xa807, 0x0000, 0x0016, 0x6004, 0x908e, 0x0021, 0x0168, 0x908e,
- 0x003d, 0x0150, 0x001e, 0xa867, 0x0103, 0xa833, 0x0100, 0x001e,
- 0x002e, 0x009e, 0x00ee, 0x0005, 0x001e, 0x0009, 0x0cc0, 0x0096,
- 0x6014, 0x2048, 0xa800, 0x2048, 0xa867, 0x0103, 0xa823, 0x8001,
- 0x009e, 0x0005, 0x00b6, 0x6610, 0x2658, 0xb804, 0x9084, 0x00ff,
- 0x90b2, 0x000c, 0x1a0c, 0x0dc5, 0x6604, 0x96b6, 0x004d, 0x1120,
- 0x080c, 0xd343, 0x0804, 0xbb97, 0x6604, 0x96b6, 0x0043, 0x1120,
- 0x080c, 0xd38c, 0x0804, 0xbb97, 0x6604, 0x96b6, 0x004b, 0x1120,
- 0x080c, 0xd3b8, 0x0804, 0xbb97, 0x6604, 0x96b6, 0x0033, 0x1120,
- 0x080c, 0xd2d5, 0x0804, 0xbb97, 0x6604, 0x96b6, 0x0028, 0x1120,
- 0x080c, 0xd085, 0x0804, 0xbb97, 0x6604, 0x96b6, 0x0029, 0x1120,
- 0x080c, 0xd0c6, 0x0804, 0xbb97, 0x6604, 0x96b6, 0x001f, 0x1120,
- 0x080c, 0xb4c4, 0x0804, 0xbb97, 0x6604, 0x96b6, 0x0000, 0x1118,
- 0x080c, 0xb812, 0x04e0, 0x6604, 0x96b6, 0x0022, 0x1118, 0x080c,
- 0xb500, 0x04a8, 0x6604, 0x96b6, 0x0035, 0x1118, 0x080c, 0xb626,
- 0x0470, 0x6604, 0x96b6, 0x0039, 0x1118, 0x080c, 0xb7a7, 0x0438,
- 0x6604, 0x96b6, 0x003d, 0x1118, 0x080c, 0xb538, 0x0400, 0x6604,
- 0x96b6, 0x0044, 0x1118, 0x080c, 0xb574, 0x00c8, 0x6604, 0x96b6,
- 0x0049, 0x1118, 0x080c, 0xb5b5, 0x0090, 0x6604, 0x96b6, 0x0041,
- 0x1118, 0x080c, 0xb59f, 0x0058, 0x91b6, 0x0015, 0x1110, 0x0063,
- 0x0030, 0x91b6, 0x0016, 0x1128, 0x00be, 0x0804, 0xbe01, 0x00be,
- 0x0005, 0x080c, 0xb181, 0x0cd8, 0xbbb4, 0xbbc2, 0xbbb4, 0xbc09,
- 0xbbb4, 0xbd75, 0xbe0e, 0xbbb4, 0xbbb4, 0xbdd7, 0xbbb4, 0xbded,
- 0x0096, 0x601f, 0x0000, 0x6014, 0x2048, 0xa800, 0x2048, 0xa867,
- 0x0103, 0x009e, 0x0804, 0xb0e7, 0xa001, 0xa001, 0x0005, 0x6604,
- 0x96b6, 0x0004, 0x1130, 0x2001, 0x0001, 0x080c, 0x6649, 0x0804,
- 0xb0e7, 0x0005, 0x00e6, 0x2071, 0x1800, 0x7090, 0x9086, 0x0074,
- 0x1540, 0x080c, 0xe642, 0x11b0, 0x6010, 0x00b6, 0x2058, 0x7030,
- 0xd08c, 0x0128, 0xb800, 0xd0bc, 0x0110, 0xc0c5, 0xb802, 0x00f9,
- 0x00be, 0x2001, 0x0006, 0x080c, 0x665d, 0x080c, 0x3274, 0x080c,
- 0xb0e7, 0x0098, 0x2001, 0x000a, 0x080c, 0x665d, 0x080c, 0x3274,
- 0x6003, 0x0001, 0x6007, 0x0001, 0x080c, 0x937d, 0x080c, 0x98e7,
- 0x0020, 0x2001, 0x0001, 0x080c, 0xbd45, 0x00ee, 0x0005, 0x00d6,
- 0xb800, 0xd084, 0x0160, 0x9006, 0x080c, 0x6649, 0x2069, 0x1847,
- 0x6804, 0xd0a4, 0x0120, 0x2001, 0x0006, 0x080c, 0x6689, 0x00de,
- 0x0005, 0x00b6, 0x0096, 0x00d6, 0x2011, 0x1824, 0x2204, 0x9086,
- 0x0074, 0x1904, 0xbd1a, 0x6010, 0x2058, 0xbaa0, 0x9286, 0x007e,
- 0x1120, 0x080c, 0xbf5d, 0x0804, 0xbc7b, 0x080c, 0xbf52, 0x6010,
- 0x2058, 0xbaa0, 0x9286, 0x0080, 0x1510, 0x6014, 0x9005, 0x01a8,
- 0x2048, 0xa864, 0x9084, 0x00ff, 0x9086, 0x0039, 0x1140, 0x2001,
- 0x0000, 0x900e, 0x2011, 0x4000, 0x080c, 0xd424, 0x0030, 0xa807,
- 0x0000, 0xa867, 0x0103, 0xa833, 0x0200, 0x2001, 0x0006, 0x080c,
- 0x665d, 0x080c, 0x3274, 0x080c, 0xb0e7, 0x0804, 0xbd1f, 0x080c,
- 0xbd2d, 0x6014, 0x9005, 0x0190, 0x2048, 0xa868, 0xd0f4, 0x01e8,
- 0xa864, 0x9084, 0x00ff, 0x9086, 0x0039, 0x1d08, 0x2001, 0x0000,
- 0x900e, 0x2011, 0x4000, 0x080c, 0xd424, 0x08f8, 0x080c, 0xbd23,
- 0x0160, 0x9006, 0x080c, 0x6649, 0x2001, 0x0004, 0x080c, 0x6689,
- 0x2001, 0x0007, 0x080c, 0x665d, 0x08a0, 0x2001, 0x0004, 0x080c,
- 0x665d, 0x6003, 0x0001, 0x6007, 0x0003, 0x080c, 0x937d, 0x080c,
- 0x98e7, 0x0804, 0xbd1f, 0xb85c, 0xd0e4, 0x01d8, 0x080c, 0xd255,
- 0x080c, 0x7563, 0x0118, 0xd0dc, 0x1904, 0xbc3d, 0x2011, 0x1837,
- 0x2204, 0xc0ad, 0x2012, 0x2001, 0x196e, 0x2004, 0x00f6, 0x2079,
- 0x0100, 0x78e3, 0x0000, 0x080c, 0x28fd, 0x78e2, 0x00fe, 0x0804,
- 0xbc3d, 0x080c, 0xd292, 0x2011, 0x1837, 0x2204, 0xc0a5, 0x2012,
- 0x0006, 0x080c, 0xe7c8, 0x000e, 0x1904, 0xbc3d, 0xc0b5, 0x2012,
- 0x2001, 0x0006, 0x080c, 0x665d, 0x9006, 0x080c, 0x6649, 0x00c6,
- 0x2001, 0x180f, 0x2004, 0xd09c, 0x0520, 0x00f6, 0x2079, 0x0100,
- 0x00e6, 0x2071, 0x1800, 0x700c, 0x9084, 0x00ff, 0x78e6, 0x707e,
- 0x7010, 0x78ea, 0x7082, 0x908c, 0x00ff, 0x00ee, 0x780c, 0xc0b5,
- 0x780e, 0x00fe, 0x080c, 0x28d2, 0x00f6, 0x2100, 0x900e, 0x080c,
- 0x2889, 0x795e, 0x00fe, 0x9186, 0x0081, 0x01f0, 0x2009, 0x0081,
- 0x00e0, 0x2009, 0x00ef, 0x00f6, 0x2079, 0x0100, 0x79ea, 0x78e7,
- 0x0000, 0x7932, 0x7936, 0x780c, 0xc0b5, 0x780e, 0x00fe, 0x080c,
- 0x28d2, 0x00f6, 0x2079, 0x1800, 0x7982, 0x2100, 0x900e, 0x797e,
- 0x080c, 0x2889, 0x795e, 0x00fe, 0x8108, 0x080c, 0x66ac, 0x2b00,
- 0x00ce, 0x1904, 0xbc3d, 0x6012, 0x2009, 0x180f, 0x210c, 0xd19c,
- 0x0150, 0x2009, 0x027c, 0x210c, 0x918c, 0x00ff, 0xb912, 0x2009,
- 0x027d, 0x210c, 0xb916, 0x2001, 0x0002, 0x080c, 0x665d, 0x6023,
- 0x0001, 0x6003, 0x0001, 0x6007, 0x0002, 0x080c, 0x937d, 0x080c,
- 0x98e7, 0x0028, 0x080c, 0xbacb, 0x2001, 0x0001, 0x0431, 0x00de,
- 0x009e, 0x00be, 0x0005, 0x2001, 0x1810, 0x2004, 0xd0a4, 0x0120,
- 0x2001, 0x1848, 0x2004, 0xd0ac, 0x0005, 0x00e6, 0x080c, 0xed03,
- 0x0190, 0x2071, 0x0260, 0x7108, 0x720c, 0x918c, 0x00ff, 0x1118,
- 0x9284, 0xff00, 0x0140, 0x6010, 0x2058, 0xb8a0, 0x9084, 0xff80,
- 0x1110, 0xb912, 0xba16, 0x00ee, 0x0005, 0x2030, 0x9005, 0x0158,
- 0x2001, 0x0007, 0x080c, 0x665d, 0x080c, 0x57e1, 0x1120, 0x2001,
- 0x0007, 0x080c, 0x6689, 0x2600, 0x9005, 0x11b0, 0x6014, 0x0096,
- 0x2048, 0xa868, 0x009e, 0xd0fc, 0x1178, 0x0036, 0x0046, 0x6010,
- 0x00b6, 0x2058, 0xbba0, 0x00be, 0x2021, 0x0004, 0x2011, 0x8014,
- 0x080c, 0x4be3, 0x004e, 0x003e, 0x080c, 0x3274, 0x6020, 0x9086,
- 0x000a, 0x1108, 0x0005, 0x0804, 0xb0e7, 0x00b6, 0x00e6, 0x0026,
- 0x0016, 0x2071, 0x1800, 0x7090, 0x9086, 0x0014, 0x1904, 0xbdcd,
- 0x080c, 0x57e1, 0x1170, 0x6014, 0x9005, 0x1158, 0x0036, 0x0046,
- 0x6010, 0x2058, 0xbba0, 0x2021, 0x0006, 0x080c, 0x4d9a, 0x004e,
- 0x003e, 0x00d6, 0x6010, 0x2058, 0x080c, 0x67b2, 0x080c, 0xbbf7,
- 0x00de, 0x080c, 0xc023, 0x1588, 0x6010, 0x2058, 0xb890, 0x9005,
- 0x0560, 0x2001, 0x0006, 0x080c, 0x665d, 0x0096, 0x6014, 0x904d,
- 0x01d0, 0xa864, 0x9084, 0x00ff, 0x9086, 0x0039, 0x1140, 0x2001,
- 0x0000, 0x900e, 0x2011, 0x4000, 0x080c, 0xd424, 0x0060, 0xa864,
- 0x9084, 0x00ff, 0x9086, 0x0029, 0x0130, 0xa807, 0x0000, 0xa867,
- 0x0103, 0xa833, 0x0200, 0x009e, 0x080c, 0x3274, 0x6020, 0x9086,
- 0x000a, 0x0140, 0x080c, 0xb0e7, 0x0028, 0x080c, 0xbacb, 0x9006,
- 0x080c, 0xbd45, 0x001e, 0x002e, 0x00ee, 0x00be, 0x0005, 0x2011,
- 0x1824, 0x2204, 0x9086, 0x0014, 0x1160, 0x2001, 0x0002, 0x080c,
- 0x665d, 0x6003, 0x0001, 0x6007, 0x0001, 0x080c, 0x937d, 0x0804,
- 0x98e7, 0x2001, 0x0001, 0x0804, 0xbd45, 0x2030, 0x2011, 0x1824,
- 0x2204, 0x9086, 0x0004, 0x1148, 0x96b6, 0x000b, 0x1120, 0x2001,
- 0x0007, 0x080c, 0x665d, 0x0804, 0xb0e7, 0x2001, 0x0001, 0x0804,
- 0xbd45, 0x0002, 0xbbb4, 0xbe19, 0xbbb4, 0xbe5c, 0xbbb4, 0xbf09,
- 0xbe0e, 0xbbb7, 0xbbb4, 0xbf1d, 0xbbb4, 0xbf2f, 0x6604, 0x9686,
- 0x0003, 0x0904, 0xbd75, 0x96b6, 0x001e, 0x1110, 0x080c, 0xb0e7,
- 0x0005, 0x00b6, 0x00d6, 0x00c6, 0x080c, 0xbf41, 0x11a0, 0x9006,
- 0x080c, 0x6649, 0x080c, 0x324b, 0x080c, 0xd55d, 0x2001, 0x0002,
- 0x080c, 0x665d, 0x6003, 0x0001, 0x6007, 0x0002, 0x080c, 0x937d,
- 0x080c, 0x98e7, 0x0428, 0x2009, 0x026e, 0x2104, 0x9086, 0x0009,
- 0x1160, 0x6010, 0x2058, 0xb840, 0x9084, 0x00ff, 0x9005, 0x0180,
- 0x8001, 0xb842, 0x601b, 0x000a, 0x0098, 0x2009, 0x026f, 0x2104,
- 0x9084, 0xff00, 0x908e, 0x1900, 0x0158, 0x908e, 0x1e00, 0x0990,
- 0x080c, 0x324b, 0x080c, 0xd55d, 0x2001, 0x0001, 0x080c, 0xbd45,
- 0x00ce, 0x00de, 0x00be, 0x0005, 0x0096, 0x00b6, 0x0026, 0x9016,
- 0x080c, 0xbf4f, 0x00d6, 0x2069, 0x197d, 0x2d04, 0x9005, 0x0168,
- 0x6010, 0x2058, 0xb8a0, 0x9086, 0x007e, 0x1138, 0x2069, 0x1820,
- 0x2d04, 0x8000, 0x206a, 0x00de, 0x0010, 0x00de, 0x0088, 0x9006,
- 0x080c, 0x6649, 0x2001, 0x0002, 0x080c, 0x665d, 0x6003, 0x0001,
- 0x6007, 0x0002, 0x080c, 0x937d, 0x080c, 0x98e7, 0x0804, 0xbed9,
- 0x080c, 0xce3f, 0x01b0, 0x6014, 0x2048, 0xa864, 0x2010, 0x9086,
- 0x0139, 0x1138, 0x6007, 0x0016, 0x2001, 0x0002, 0x080c, 0xd481,
- 0x00b0, 0x6014, 0x2048, 0xa864, 0xd0fc, 0x0118, 0x2001, 0x0001,
- 0x0ca8, 0x2001, 0x180e, 0x2004, 0xd0dc, 0x0148, 0x6010, 0x2058,
- 0xb840, 0x9084, 0x00ff, 0x9005, 0x1110, 0x9006, 0x0c38, 0x080c,
- 0xbacb, 0x2009, 0x026e, 0x2134, 0x96b4, 0x00ff, 0x9686, 0x0005,
- 0x0520, 0x9686, 0x000b, 0x01c8, 0x2009, 0x026f, 0x2104, 0x9084,
- 0xff00, 0x1118, 0x9686, 0x0009, 0x01c0, 0x9086, 0x1900, 0x1168,
- 0x9686, 0x0009, 0x0190, 0x2001, 0x0004, 0x080c, 0x665d, 0x2001,
- 0x0028, 0x601a, 0x6007, 0x0052, 0x0020, 0x2001, 0x0001, 0x080c,
- 0xbd45, 0x002e, 0x00be, 0x009e, 0x0005, 0x9286, 0x0139, 0x0160,
- 0x6014, 0x2048, 0x080c, 0xce3f, 0x0140, 0xa864, 0x9086, 0x0139,
- 0x0118, 0xa868, 0xd0fc, 0x0108, 0x0c40, 0x6010, 0x2058, 0xb840,
- 0x9084, 0x00ff, 0x9005, 0x0138, 0x8001, 0xb842, 0x601b, 0x000a,
- 0x6007, 0x0016, 0x08f0, 0xb8a0, 0x9086, 0x007e, 0x1138, 0x00e6,
- 0x2071, 0x1800, 0x080c, 0x60b4, 0x00ee, 0x0010, 0x080c, 0x324b,
- 0x0860, 0x2001, 0x0004, 0x080c, 0x665d, 0x080c, 0xbf4f, 0x1140,
- 0x6003, 0x0001, 0x6007, 0x0003, 0x080c, 0x937d, 0x0804, 0x98e7,
- 0x080c, 0xbacb, 0x9006, 0x0804, 0xbd45, 0x0489, 0x1160, 0x2001,
- 0x0008, 0x080c, 0x665d, 0x6003, 0x0001, 0x6007, 0x0005, 0x080c,
- 0x937d, 0x0804, 0x98e7, 0x2001, 0x0001, 0x0804, 0xbd45, 0x00f9,
- 0x1160, 0x2001, 0x000a, 0x080c, 0x665d, 0x6003, 0x0001, 0x6007,
- 0x0001, 0x080c, 0x937d, 0x0804, 0x98e7, 0x2001, 0x0001, 0x0804,
- 0xbd45, 0x2009, 0x026e, 0x2104, 0x9086, 0x0003, 0x1138, 0x2009,
- 0x026f, 0x2104, 0x9084, 0xff00, 0x9086, 0x2a00, 0x0005, 0x9085,
- 0x0001, 0x0005, 0x00b6, 0x00c6, 0x0016, 0x6110, 0x2158, 0x080c,
- 0x6726, 0x001e, 0x00ce, 0x00be, 0x0005, 0x00b6, 0x00f6, 0x00e6,
- 0x00d6, 0x0036, 0x0016, 0x6010, 0x2058, 0x2009, 0x1837, 0x2104,
- 0x9085, 0x0003, 0x200a, 0x080c, 0xbff5, 0x0560, 0x2009, 0x1837,
- 0x2104, 0xc0cd, 0x200a, 0x080c, 0x6a88, 0x0158, 0x9006, 0x2020,
- 0x2009, 0x002a, 0x080c, 0xe940, 0x2001, 0x180c, 0x200c, 0xc195,
- 0x2102, 0x2019, 0x002a, 0x2009, 0x0001, 0x080c, 0x3216, 0x00e6,
- 0x2071, 0x1800, 0x080c, 0x3022, 0x00ee, 0x00c6, 0x0156, 0x20a9,
- 0x0781, 0x2009, 0x007f, 0x080c, 0x3347, 0x8108, 0x1f04, 0xbf93,
- 0x015e, 0x00ce, 0x080c, 0xbf52, 0x2071, 0x0260, 0x2079, 0x0200,
- 0x7817, 0x0001, 0x2001, 0x1837, 0x200c, 0xc1c5, 0x7018, 0xd0fc,
- 0x0110, 0xd0dc, 0x0118, 0x7038, 0xd0dc, 0x1108, 0xc1c4, 0x7817,
- 0x0000, 0x2001, 0x1837, 0x2102, 0x2079, 0x0100, 0x2e04, 0x9084,
+ 0x00be, 0x9206, 0x1904, 0xb823, 0x700c, 0x6210, 0x00b6, 0x2258,
+ 0xba14, 0x00be, 0x9206, 0x1904, 0xb823, 0x6038, 0x2068, 0x6824,
+ 0xc0dc, 0x6826, 0x6a20, 0x9286, 0x0007, 0x0904, 0xb823, 0x9286,
+ 0x0002, 0x0904, 0xb823, 0x9286, 0x0000, 0x05e8, 0x6808, 0x633c,
+ 0x9306, 0x15c8, 0x2071, 0x026c, 0x9186, 0x0015, 0x0570, 0x918e,
+ 0x0016, 0x1100, 0x00c6, 0x6038, 0x2060, 0x6104, 0x9186, 0x004b,
+ 0x01c0, 0x9186, 0x004c, 0x01a8, 0x9186, 0x004d, 0x0190, 0x9186,
+ 0x004e, 0x0178, 0x9186, 0x0052, 0x0160, 0x6014, 0x0096, 0x2048,
+ 0x080c, 0xce56, 0x090c, 0x0dc5, 0xa87b, 0x0003, 0x009e, 0x080c,
+ 0xd51b, 0x6007, 0x0085, 0x6003, 0x000b, 0x6023, 0x0002, 0x080c,
+ 0x933b, 0x080c, 0x98ed, 0x00ce, 0x0030, 0x6038, 0x2070, 0x2001,
+ 0x1989, 0x2004, 0x7042, 0x080c, 0xb101, 0x002e, 0x00de, 0x00ee,
+ 0x0005, 0x00b6, 0x0096, 0x00f6, 0x6014, 0x2048, 0x6010, 0x2058,
+ 0x91b6, 0x0015, 0x0130, 0xba08, 0xbb0c, 0xbc00, 0xc48c, 0xbc02,
+ 0x0460, 0x0096, 0x0156, 0x0036, 0x0026, 0x2b48, 0x9e90, 0x0010,
+ 0x2019, 0x000a, 0x20a9, 0x0004, 0x080c, 0xc0f7, 0x002e, 0x003e,
+ 0x015e, 0x009e, 0x1904, 0xb892, 0x0096, 0x0156, 0x0036, 0x0026,
+ 0x2b48, 0x9e90, 0x0014, 0x2019, 0x0006, 0x20a9, 0x0004, 0x080c,
+ 0xc0f7, 0x002e, 0x003e, 0x015e, 0x009e, 0x15a0, 0x7238, 0xba0a,
+ 0x733c, 0xbb0e, 0xbc00, 0xc48d, 0xbc02, 0xa804, 0x9005, 0x1128,
+ 0x00fe, 0x009e, 0x00be, 0x0804, 0xb50a, 0x0096, 0x2048, 0xaa12,
+ 0xab16, 0xac0a, 0x009e, 0x8006, 0x8006, 0x8007, 0x90bc, 0x003f,
+ 0x9084, 0xffc0, 0x9080, 0x0002, 0x2009, 0x002b, 0xaaa0, 0xab9c,
+ 0xaca8, 0xada4, 0x2031, 0x0000, 0x2041, 0x1252, 0x080c, 0xb61f,
+ 0x0130, 0x00fe, 0x009e, 0x080c, 0xb101, 0x00be, 0x0005, 0x080c,
+ 0xbae2, 0x0cb8, 0x2b78, 0x00f6, 0x080c, 0x3246, 0x080c, 0xd576,
+ 0x00fe, 0x00c6, 0x080c, 0xb0ab, 0x2f00, 0x6012, 0x6017, 0x0000,
+ 0x6023, 0x0001, 0x6007, 0x0001, 0x6003, 0x0001, 0x2001, 0x0007,
+ 0x080c, 0x6663, 0x080c, 0x668f, 0x080c, 0x9383, 0x080c, 0x98ed,
+ 0x00ce, 0x0804, 0xb865, 0x2100, 0x91b2, 0x0053, 0x1a0c, 0x0dc5,
+ 0x91b2, 0x0040, 0x1a04, 0xb91b, 0x0002, 0xb909, 0xb909, 0xb8ff,
+ 0xb909, 0xb909, 0xb909, 0xb8fd, 0xb8fd, 0xb8fd, 0xb8fd, 0xb8fd,
+ 0xb8fd, 0xb8fd, 0xb8fd, 0xb8fd, 0xb8fd, 0xb8fd, 0xb8fd, 0xb8fd,
+ 0xb8fd, 0xb8fd, 0xb8fd, 0xb8fd, 0xb8fd, 0xb8fd, 0xb8fd, 0xb8fd,
+ 0xb8fd, 0xb8fd, 0xb8fd, 0xb8fd, 0xb909, 0xb8fd, 0xb909, 0xb909,
+ 0xb8fd, 0xb8fd, 0xb8fd, 0xb8fd, 0xb8fd, 0xb8ff, 0xb8fd, 0xb8fd,
+ 0xb8fd, 0xb8fd, 0xb8fd, 0xb8fd, 0xb8fd, 0xb8fd, 0xb8fd, 0xb909,
+ 0xb909, 0xb8fd, 0xb8fd, 0xb8fd, 0xb8fd, 0xb8fd, 0xb8fd, 0xb8fd,
+ 0xb8fd, 0xb8fd, 0xb909, 0xb8fd, 0xb8fd, 0x080c, 0x0dc5, 0x0066,
+ 0x00b6, 0x6610, 0x2658, 0xb8cc, 0xc08c, 0xb8ce, 0x00be, 0x006e,
+ 0x0000, 0x6003, 0x0001, 0x6106, 0x9186, 0x0032, 0x0118, 0x080c,
+ 0x9383, 0x0010, 0x080c, 0x933b, 0x0126, 0x2091, 0x8000, 0x080c,
+ 0x98ed, 0x012e, 0x0005, 0x2600, 0x0002, 0xb909, 0xb909, 0xb92f,
+ 0xb909, 0xb909, 0xb92f, 0xb92f, 0xb92f, 0xb92f, 0xb909, 0xb92f,
+ 0xb909, 0xb92f, 0xb909, 0xb92f, 0xb92f, 0xb92f, 0xb92f, 0x080c,
+ 0x0dc5, 0x6004, 0x90b2, 0x0053, 0x1a0c, 0x0dc5, 0x91b6, 0x0013,
+ 0x0904, 0xba04, 0x91b6, 0x0027, 0x1904, 0xb9ae, 0x080c, 0x97e1,
+ 0x6004, 0x080c, 0xd04d, 0x01b0, 0x080c, 0xd05e, 0x01a8, 0x908e,
+ 0x0021, 0x0904, 0xb9ab, 0x908e, 0x0022, 0x1130, 0x080c, 0xb536,
+ 0x0904, 0xb9a7, 0x0804, 0xb9a8, 0x908e, 0x003d, 0x0904, 0xb9ab,
+ 0x0804, 0xb9a1, 0x080c, 0x326f, 0x2001, 0x0007, 0x080c, 0x6663,
+ 0x6010, 0x00b6, 0x2058, 0xb9a0, 0x00be, 0x080c, 0xbae2, 0x9186,
+ 0x007e, 0x1148, 0x2001, 0x1837, 0x2014, 0xc285, 0x080c, 0x7569,
+ 0x1108, 0xc2ad, 0x2202, 0x0036, 0x0026, 0x2019, 0x0028, 0x2110,
+ 0x080c, 0xed0f, 0x002e, 0x003e, 0x0016, 0x0026, 0x0036, 0x2110,
+ 0x2019, 0x0028, 0x080c, 0x94e0, 0x0076, 0x903e, 0x080c, 0x93b3,
+ 0x6010, 0x00b6, 0x905d, 0x0100, 0x00be, 0x2c08, 0x080c, 0xe690,
+ 0x007e, 0x003e, 0x002e, 0x001e, 0x080c, 0xd576, 0x0016, 0x080c,
+ 0xd2ca, 0x080c, 0xb101, 0x001e, 0x080c, 0x3342, 0x080c, 0x98ed,
+ 0x0030, 0x080c, 0xd2ca, 0x080c, 0xb101, 0x080c, 0x98ed, 0x0005,
+ 0x080c, 0xbae2, 0x0cb0, 0x080c, 0xbb1e, 0x0c98, 0x9186, 0x0015,
+ 0x0118, 0x9186, 0x0016, 0x1148, 0x080c, 0xd587, 0x0d80, 0x6000,
+ 0x9086, 0x0002, 0x0904, 0xbb29, 0x0c50, 0x9186, 0x0014, 0x1d38,
+ 0x080c, 0x97e1, 0x6004, 0x908e, 0x0022, 0x1118, 0x080c, 0xb536,
+ 0x09f0, 0x080c, 0x3246, 0x080c, 0xd576, 0x080c, 0xd04d, 0x1198,
+ 0x080c, 0x326f, 0x6010, 0x00b6, 0x2058, 0xb9a0, 0x00be, 0x080c,
+ 0xbae2, 0x9186, 0x007e, 0x1128, 0x2001, 0x1837, 0x200c, 0xc185,
+ 0x2102, 0x0804, 0xb9a1, 0x080c, 0xd05e, 0x1120, 0x080c, 0xbae2,
+ 0x0804, 0xb9a1, 0x6004, 0x908e, 0x0032, 0x1160, 0x00e6, 0x00f6,
+ 0x2071, 0x189e, 0x2079, 0x0000, 0x080c, 0x35dd, 0x00fe, 0x00ee,
+ 0x0804, 0xb9a1, 0x6004, 0x908e, 0x0021, 0x0d40, 0x908e, 0x0022,
+ 0x090c, 0xbae2, 0x0804, 0xb9a1, 0x90b2, 0x0040, 0x1a04, 0xbabe,
+ 0x2008, 0x0002, 0xba4c, 0xba4d, 0xba50, 0xba53, 0xba56, 0xba63,
+ 0xba4a, 0xba4a, 0xba4a, 0xba4a, 0xba4a, 0xba4a, 0xba4a, 0xba4a,
+ 0xba4a, 0xba4a, 0xba4a, 0xba4a, 0xba4a, 0xba4a, 0xba4a, 0xba4a,
+ 0xba4a, 0xba4a, 0xba4a, 0xba4a, 0xba4a, 0xba4a, 0xba4a, 0xba4a,
+ 0xba66, 0xba73, 0xba4a, 0xba75, 0xba73, 0xba4a, 0xba4a, 0xba4a,
+ 0xba4a, 0xba4a, 0xba73, 0xba73, 0xba4a, 0xba4a, 0xba4a, 0xba4a,
+ 0xba4a, 0xba4a, 0xba4a, 0xba4a, 0xbaa5, 0xba73, 0xba4a, 0xba6f,
+ 0xba4a, 0xba4a, 0xba4a, 0xba70, 0xba4a, 0xba4a, 0xba4a, 0xba73,
+ 0xba9c, 0xba4a, 0x080c, 0x0dc5, 0x0430, 0x2001, 0x000b, 0x0470,
+ 0x2001, 0x0003, 0x0458, 0x2001, 0x0005, 0x0440, 0x6010, 0x00b6,
+ 0x2058, 0xb804, 0x00be, 0x9084, 0x00ff, 0x9086, 0x0000, 0x1500,
+ 0x2001, 0x0001, 0x00d8, 0x2001, 0x0009, 0x00c0, 0x080c, 0x97e1,
+ 0x6003, 0x0005, 0x080c, 0xd579, 0x080c, 0x98ed, 0x0070, 0x0018,
+ 0x0010, 0x080c, 0x6663, 0x0804, 0xbab6, 0x080c, 0x97e1, 0x080c,
+ 0xd579, 0x6003, 0x0004, 0x080c, 0x98ed, 0x0005, 0x080c, 0x6663,
+ 0x080c, 0x97e1, 0x6003, 0x0002, 0x0036, 0x2019, 0x1852, 0x2304,
+ 0x9084, 0xff00, 0x1120, 0x2001, 0x1987, 0x201c, 0x0040, 0x8007,
+ 0x909a, 0x0004, 0x0ec0, 0x8003, 0x801b, 0x831b, 0x9318, 0x631a,
+ 0x003e, 0x080c, 0x98ed, 0x0c08, 0x080c, 0x97e1, 0x080c, 0xd2ca,
+ 0x080c, 0xb101, 0x080c, 0x98ed, 0x08c0, 0x00e6, 0x00f6, 0x2071,
+ 0x189e, 0x2079, 0x0000, 0x080c, 0x35dd, 0x00fe, 0x00ee, 0x080c,
+ 0x97e1, 0x080c, 0xb101, 0x080c, 0x98ed, 0x0838, 0x080c, 0x97e1,
+ 0x6003, 0x0002, 0x080c, 0xd579, 0x0804, 0x98ed, 0x2600, 0x2008,
+ 0x0002, 0xbad5, 0xbab6, 0xbad3, 0xbab6, 0xbab6, 0xbad3, 0xbad3,
+ 0xbad3, 0xbad3, 0xbab6, 0xbad3, 0xbab6, 0xbad3, 0xbab6, 0xbad3,
+ 0xbad3, 0xbad3, 0xbad3, 0x080c, 0x0dc5, 0x080c, 0x97e1, 0x0096,
+ 0x6014, 0x2048, 0x080c, 0x6dd1, 0x009e, 0x080c, 0xb101, 0x080c,
+ 0x98ed, 0x0005, 0x00e6, 0x0096, 0x0026, 0x0016, 0x080c, 0xce56,
+ 0x0568, 0x6014, 0x2048, 0xa864, 0x9086, 0x0139, 0x11a8, 0xa894,
+ 0x9086, 0x0056, 0x1148, 0x080c, 0x556d, 0x0130, 0x2001, 0x0000,
+ 0x900e, 0x2011, 0x4000, 0x0028, 0x2001, 0x0030, 0x900e, 0x2011,
+ 0x4005, 0x080c, 0xd43b, 0x0090, 0xa868, 0xd0fc, 0x0178, 0xa807,
+ 0x0000, 0x0016, 0x6004, 0x908e, 0x0021, 0x0168, 0x908e, 0x003d,
+ 0x0150, 0x001e, 0xa867, 0x0103, 0xa833, 0x0100, 0x001e, 0x002e,
+ 0x009e, 0x00ee, 0x0005, 0x001e, 0x0009, 0x0cc0, 0x0096, 0x6014,
+ 0x2048, 0xa800, 0x2048, 0xa867, 0x0103, 0xa823, 0x8001, 0x009e,
+ 0x0005, 0x00b6, 0x6610, 0x2658, 0xb804, 0x9084, 0x00ff, 0x90b2,
+ 0x000c, 0x1a0c, 0x0dc5, 0x6604, 0x96b6, 0x004d, 0x1120, 0x080c,
+ 0xd35a, 0x0804, 0xbbae, 0x6604, 0x96b6, 0x0043, 0x1120, 0x080c,
+ 0xd3a3, 0x0804, 0xbbae, 0x6604, 0x96b6, 0x004b, 0x1120, 0x080c,
+ 0xd3cf, 0x0804, 0xbbae, 0x6604, 0x96b6, 0x0033, 0x1120, 0x080c,
+ 0xd2ec, 0x0804, 0xbbae, 0x6604, 0x96b6, 0x0028, 0x1120, 0x080c,
+ 0xd09c, 0x0804, 0xbbae, 0x6604, 0x96b6, 0x0029, 0x1120, 0x080c,
+ 0xd0dd, 0x0804, 0xbbae, 0x6604, 0x96b6, 0x001f, 0x1120, 0x080c,
+ 0xb4db, 0x0804, 0xbbae, 0x6604, 0x96b6, 0x0000, 0x1118, 0x080c,
+ 0xb829, 0x04e0, 0x6604, 0x96b6, 0x0022, 0x1118, 0x080c, 0xb517,
+ 0x04a8, 0x6604, 0x96b6, 0x0035, 0x1118, 0x080c, 0xb63d, 0x0470,
+ 0x6604, 0x96b6, 0x0039, 0x1118, 0x080c, 0xb7be, 0x0438, 0x6604,
+ 0x96b6, 0x003d, 0x1118, 0x080c, 0xb54f, 0x0400, 0x6604, 0x96b6,
+ 0x0044, 0x1118, 0x080c, 0xb58b, 0x00c8, 0x6604, 0x96b6, 0x0049,
+ 0x1118, 0x080c, 0xb5cc, 0x0090, 0x6604, 0x96b6, 0x0041, 0x1118,
+ 0x080c, 0xb5b6, 0x0058, 0x91b6, 0x0015, 0x1110, 0x0063, 0x0030,
+ 0x91b6, 0x0016, 0x1128, 0x00be, 0x0804, 0xbe0c, 0x00be, 0x0005,
+ 0x080c, 0xb19b, 0x0cd8, 0xbbcb, 0xbbd9, 0xbbcb, 0xbc20, 0xbbcb,
+ 0xbd80, 0xbe19, 0xbbcb, 0xbbcb, 0xbde2, 0xbbcb, 0xbdf8, 0x0096,
+ 0x601f, 0x0000, 0x6014, 0x2048, 0xa800, 0x2048, 0xa867, 0x0103,
+ 0x009e, 0x0804, 0xb101, 0xa001, 0xa001, 0x0005, 0x6604, 0x96b6,
+ 0x0004, 0x1130, 0x2001, 0x0001, 0x080c, 0x664f, 0x0804, 0xb101,
+ 0x0005, 0x00e6, 0x2071, 0x1800, 0x7090, 0x9086, 0x0074, 0x1540,
+ 0x080c, 0xe661, 0x11b0, 0x6010, 0x00b6, 0x2058, 0x7030, 0xd08c,
+ 0x0128, 0xb800, 0xd0bc, 0x0110, 0xc0c5, 0xb802, 0x00f9, 0x00be,
+ 0x2001, 0x0006, 0x080c, 0x6663, 0x080c, 0x326f, 0x080c, 0xb101,
+ 0x0098, 0x2001, 0x000a, 0x080c, 0x6663, 0x080c, 0x326f, 0x6003,
+ 0x0001, 0x6007, 0x0001, 0x080c, 0x9383, 0x080c, 0x98ed, 0x0020,
+ 0x2001, 0x0001, 0x080c, 0xbd50, 0x00ee, 0x0005, 0x00d6, 0xb800,
+ 0xd084, 0x0160, 0x9006, 0x080c, 0x664f, 0x2069, 0x1847, 0x6804,
+ 0xd0a4, 0x0120, 0x2001, 0x0006, 0x080c, 0x668f, 0x00de, 0x0005,
+ 0x00b6, 0x0096, 0x00d6, 0x2011, 0x1824, 0x2204, 0x9086, 0x0074,
+ 0x1904, 0xbd25, 0x6010, 0x2058, 0xbaa0, 0x9286, 0x007e, 0x1120,
+ 0x080c, 0xbf68, 0x0804, 0xbc92, 0x080c, 0xbf5d, 0x6010, 0x2058,
+ 0xbaa0, 0x9286, 0x0080, 0x1510, 0x6014, 0x9005, 0x01a8, 0x2048,
+ 0xa864, 0x9084, 0x00ff, 0x9086, 0x0039, 0x1140, 0x2001, 0x0000,
+ 0x900e, 0x2011, 0x4000, 0x080c, 0xd43b, 0x0030, 0xa807, 0x0000,
+ 0xa867, 0x0103, 0xa833, 0x0200, 0x2001, 0x0006, 0x080c, 0x6663,
+ 0x080c, 0x326f, 0x080c, 0xb101, 0x0804, 0xbd2a, 0x080c, 0xbd38,
+ 0x6014, 0x9005, 0x0190, 0x2048, 0xa868, 0xd0f4, 0x01e8, 0xa864,
+ 0x9084, 0x00ff, 0x9086, 0x0039, 0x1d08, 0x2001, 0x0000, 0x900e,
+ 0x2011, 0x4000, 0x080c, 0xd43b, 0x08f8, 0x080c, 0xbd2e, 0x0160,
+ 0x9006, 0x080c, 0x664f, 0x2001, 0x0004, 0x080c, 0x668f, 0x2001,
+ 0x0007, 0x080c, 0x6663, 0x08a0, 0x2001, 0x0004, 0x080c, 0x6663,
+ 0x6003, 0x0001, 0x6007, 0x0003, 0x080c, 0x9383, 0x080c, 0x98ed,
+ 0x0804, 0xbd2a, 0xb85c, 0xd0e4, 0x0178, 0x080c, 0xd26c, 0x080c,
+ 0x7569, 0x0118, 0xd0dc, 0x1904, 0xbc54, 0x2011, 0x1837, 0x2204,
+ 0xc0ad, 0x2012, 0x0804, 0xbc54, 0x080c, 0xd2a9, 0x2011, 0x1837,
+ 0x2204, 0xc0a5, 0x2012, 0x0006, 0x080c, 0xe82d, 0x000e, 0x1904,
+ 0xbc54, 0xc0b5, 0x2012, 0x2001, 0x0006, 0x080c, 0x6663, 0x9006,
+ 0x080c, 0x664f, 0x00c6, 0x2001, 0x180f, 0x2004, 0xd09c, 0x0520,
+ 0x00f6, 0x2079, 0x0100, 0x00e6, 0x2071, 0x1800, 0x700c, 0x9084,
+ 0x00ff, 0x78e6, 0x707e, 0x7010, 0x78ea, 0x7082, 0x908c, 0x00ff,
+ 0x00ee, 0x780c, 0xc0b5, 0x780e, 0x00fe, 0x080c, 0x28dd, 0x00f6,
+ 0x2100, 0x900e, 0x080c, 0x2894, 0x795e, 0x00fe, 0x9186, 0x0081,
+ 0x01f0, 0x2009, 0x0081, 0x00e0, 0x2009, 0x00ef, 0x00f6, 0x2079,
+ 0x0100, 0x79ea, 0x78e7, 0x0000, 0x7932, 0x7936, 0x780c, 0xc0b5,
+ 0x780e, 0x00fe, 0x080c, 0x28dd, 0x00f6, 0x2079, 0x1800, 0x7982,
+ 0x2100, 0x900e, 0x797e, 0x080c, 0x2894, 0x795e, 0x00fe, 0x8108,
+ 0x080c, 0x66b2, 0x2b00, 0x00ce, 0x1904, 0xbc54, 0x6012, 0x2009,
+ 0x180f, 0x210c, 0xd19c, 0x0150, 0x2009, 0x027c, 0x210c, 0x918c,
+ 0x00ff, 0xb912, 0x2009, 0x027d, 0x210c, 0xb916, 0x2001, 0x0002,
+ 0x080c, 0x6663, 0x6023, 0x0001, 0x6003, 0x0001, 0x6007, 0x0002,
+ 0x080c, 0x9383, 0x080c, 0x98ed, 0x0028, 0x080c, 0xbae2, 0x2001,
+ 0x0001, 0x0431, 0x00de, 0x009e, 0x00be, 0x0005, 0x2001, 0x1810,
+ 0x2004, 0xd0a4, 0x0120, 0x2001, 0x1848, 0x2004, 0xd0ac, 0x0005,
+ 0x00e6, 0x080c, 0xed68, 0x0190, 0x2071, 0x0260, 0x7108, 0x720c,
+ 0x918c, 0x00ff, 0x1118, 0x9284, 0xff00, 0x0140, 0x6010, 0x2058,
+ 0xb8a0, 0x9084, 0xff80, 0x1110, 0xb912, 0xba16, 0x00ee, 0x0005,
+ 0x2030, 0x9005, 0x0158, 0x2001, 0x0007, 0x080c, 0x6663, 0x080c,
+ 0x57e7, 0x1120, 0x2001, 0x0007, 0x080c, 0x668f, 0x2600, 0x9005,
+ 0x11b0, 0x6014, 0x0096, 0x2048, 0xa868, 0x009e, 0xd0fc, 0x1178,
+ 0x0036, 0x0046, 0x6010, 0x00b6, 0x2058, 0xbba0, 0x00be, 0x2021,
+ 0x0004, 0x2011, 0x8014, 0x080c, 0x4be9, 0x004e, 0x003e, 0x080c,
+ 0x326f, 0x6020, 0x9086, 0x000a, 0x1108, 0x0005, 0x0804, 0xb101,
+ 0x00b6, 0x00e6, 0x0026, 0x0016, 0x2071, 0x1800, 0x7090, 0x9086,
+ 0x0014, 0x1904, 0xbdd8, 0x080c, 0x57e7, 0x1170, 0x6014, 0x9005,
+ 0x1158, 0x0036, 0x0046, 0x6010, 0x2058, 0xbba0, 0x2021, 0x0006,
+ 0x080c, 0x4da0, 0x004e, 0x003e, 0x00d6, 0x6010, 0x2058, 0x080c,
+ 0x67b8, 0x080c, 0xbc0e, 0x00de, 0x080c, 0xc033, 0x1588, 0x6010,
+ 0x2058, 0xb890, 0x9005, 0x0560, 0x2001, 0x0006, 0x080c, 0x6663,
+ 0x0096, 0x6014, 0x904d, 0x01d0, 0xa864, 0x9084, 0x00ff, 0x9086,
+ 0x0039, 0x1140, 0x2001, 0x0000, 0x900e, 0x2011, 0x4000, 0x080c,
+ 0xd43b, 0x0060, 0xa864, 0x9084, 0x00ff, 0x9086, 0x0029, 0x0130,
+ 0xa807, 0x0000, 0xa867, 0x0103, 0xa833, 0x0200, 0x009e, 0x080c,
+ 0x326f, 0x6020, 0x9086, 0x000a, 0x0140, 0x080c, 0xb101, 0x0028,
+ 0x080c, 0xbae2, 0x9006, 0x080c, 0xbd50, 0x001e, 0x002e, 0x00ee,
+ 0x00be, 0x0005, 0x2011, 0x1824, 0x2204, 0x9086, 0x0014, 0x1160,
+ 0x2001, 0x0002, 0x080c, 0x6663, 0x6003, 0x0001, 0x6007, 0x0001,
+ 0x080c, 0x9383, 0x0804, 0x98ed, 0x2001, 0x0001, 0x0804, 0xbd50,
+ 0x2030, 0x2011, 0x1824, 0x2204, 0x9086, 0x0004, 0x1148, 0x96b6,
+ 0x000b, 0x1120, 0x2001, 0x0007, 0x080c, 0x6663, 0x0804, 0xb101,
+ 0x2001, 0x0001, 0x0804, 0xbd50, 0x0002, 0xbbcb, 0xbe24, 0xbbcb,
+ 0xbe67, 0xbbcb, 0xbf14, 0xbe19, 0xbbce, 0xbbcb, 0xbf28, 0xbbcb,
+ 0xbf3a, 0x6604, 0x9686, 0x0003, 0x0904, 0xbd80, 0x96b6, 0x001e,
+ 0x1110, 0x080c, 0xb101, 0x0005, 0x00b6, 0x00d6, 0x00c6, 0x080c,
+ 0xbf4c, 0x11a0, 0x9006, 0x080c, 0x664f, 0x080c, 0x3246, 0x080c,
+ 0xd576, 0x2001, 0x0002, 0x080c, 0x6663, 0x6003, 0x0001, 0x6007,
+ 0x0002, 0x080c, 0x9383, 0x080c, 0x98ed, 0x0428, 0x2009, 0x026e,
+ 0x2104, 0x9086, 0x0009, 0x1160, 0x6010, 0x2058, 0xb840, 0x9084,
+ 0x00ff, 0x9005, 0x0180, 0x8001, 0xb842, 0x601b, 0x000a, 0x0098,
+ 0x2009, 0x026f, 0x2104, 0x9084, 0xff00, 0x908e, 0x1900, 0x0158,
+ 0x908e, 0x1e00, 0x0990, 0x080c, 0x3246, 0x080c, 0xd576, 0x2001,
+ 0x0001, 0x080c, 0xbd50, 0x00ce, 0x00de, 0x00be, 0x0005, 0x0096,
+ 0x00b6, 0x0026, 0x9016, 0x080c, 0xbf5a, 0x00d6, 0x2069, 0x197d,
+ 0x2d04, 0x9005, 0x0168, 0x6010, 0x2058, 0xb8a0, 0x9086, 0x007e,
+ 0x1138, 0x2069, 0x1820, 0x2d04, 0x8000, 0x206a, 0x00de, 0x0010,
+ 0x00de, 0x0088, 0x9006, 0x080c, 0x664f, 0x2001, 0x0002, 0x080c,
+ 0x6663, 0x6003, 0x0001, 0x6007, 0x0002, 0x080c, 0x9383, 0x080c,
+ 0x98ed, 0x0804, 0xbee4, 0x080c, 0xce56, 0x01b0, 0x6014, 0x2048,
+ 0xa864, 0x2010, 0x9086, 0x0139, 0x1138, 0x6007, 0x0016, 0x2001,
+ 0x0002, 0x080c, 0xd498, 0x00b0, 0x6014, 0x2048, 0xa864, 0xd0fc,
+ 0x0118, 0x2001, 0x0001, 0x0ca8, 0x2001, 0x180e, 0x2004, 0xd0dc,
+ 0x0148, 0x6010, 0x2058, 0xb840, 0x9084, 0x00ff, 0x9005, 0x1110,
+ 0x9006, 0x0c38, 0x080c, 0xbae2, 0x2009, 0x026e, 0x2134, 0x96b4,
+ 0x00ff, 0x9686, 0x0005, 0x0520, 0x9686, 0x000b, 0x01c8, 0x2009,
+ 0x026f, 0x2104, 0x9084, 0xff00, 0x1118, 0x9686, 0x0009, 0x01c0,
+ 0x9086, 0x1900, 0x1168, 0x9686, 0x0009, 0x0190, 0x2001, 0x0004,
+ 0x080c, 0x6663, 0x2001, 0x0028, 0x601a, 0x6007, 0x0052, 0x0020,
+ 0x2001, 0x0001, 0x080c, 0xbd50, 0x002e, 0x00be, 0x009e, 0x0005,
+ 0x9286, 0x0139, 0x0160, 0x6014, 0x2048, 0x080c, 0xce56, 0x0140,
+ 0xa864, 0x9086, 0x0139, 0x0118, 0xa868, 0xd0fc, 0x0108, 0x0c40,
+ 0x6010, 0x2058, 0xb840, 0x9084, 0x00ff, 0x9005, 0x0138, 0x8001,
+ 0xb842, 0x601b, 0x000a, 0x6007, 0x0016, 0x08f0, 0xb8a0, 0x9086,
+ 0x007e, 0x1138, 0x00e6, 0x2071, 0x1800, 0x080c, 0x60ba, 0x00ee,
+ 0x0010, 0x080c, 0x3246, 0x0860, 0x2001, 0x0004, 0x080c, 0x6663,
+ 0x080c, 0xbf5a, 0x1140, 0x6003, 0x0001, 0x6007, 0x0003, 0x080c,
+ 0x9383, 0x0804, 0x98ed, 0x080c, 0xbae2, 0x9006, 0x0804, 0xbd50,
+ 0x0489, 0x1160, 0x2001, 0x0008, 0x080c, 0x6663, 0x6003, 0x0001,
+ 0x6007, 0x0005, 0x080c, 0x9383, 0x0804, 0x98ed, 0x2001, 0x0001,
+ 0x0804, 0xbd50, 0x00f9, 0x1160, 0x2001, 0x000a, 0x080c, 0x6663,
+ 0x6003, 0x0001, 0x6007, 0x0001, 0x080c, 0x9383, 0x0804, 0x98ed,
+ 0x2001, 0x0001, 0x0804, 0xbd50, 0x2009, 0x026e, 0x2104, 0x9086,
+ 0x0003, 0x1138, 0x2009, 0x026f, 0x2104, 0x9084, 0xff00, 0x9086,
+ 0x2a00, 0x0005, 0x9085, 0x0001, 0x0005, 0x00b6, 0x00c6, 0x0016,
+ 0x6110, 0x2158, 0x080c, 0x672c, 0x001e, 0x00ce, 0x00be, 0x0005,
+ 0x00b6, 0x00f6, 0x00e6, 0x00d6, 0x0036, 0x0016, 0x6010, 0x2058,
+ 0x2009, 0x1837, 0x2104, 0x9085, 0x0003, 0x200a, 0x080c, 0xc005,
+ 0x0560, 0x2009, 0x1837, 0x2104, 0xc0cd, 0x200a, 0x080c, 0x6a8e,
+ 0x0158, 0x9006, 0x2020, 0x2009, 0x002a, 0x080c, 0xe9a5, 0x2001,
+ 0x180c, 0x200c, 0xc195, 0x2102, 0x2019, 0x002a, 0x2009, 0x0001,
+ 0x080c, 0x3211, 0x00e6, 0x2071, 0x1800, 0x080c, 0x3019, 0x00ee,
+ 0x00c6, 0x0156, 0x20a9, 0x0781, 0x2009, 0x007f, 0x080c, 0x3342,
+ 0x8108, 0x1f04, 0xbf9e, 0x015e, 0x00ce, 0x080c, 0xbf5d, 0x2071,
+ 0x0260, 0x2079, 0x0200, 0x7817, 0x0001, 0x2001, 0x1837, 0x200c,
+ 0xc1c5, 0x7018, 0xd0fc, 0x0110, 0xd0dc, 0x0118, 0x7038, 0xd0dc,
+ 0x1108, 0xc1c4, 0x7817, 0x0000, 0x2001, 0x1837, 0x2102, 0x9184,
+ 0x0050, 0x9086, 0x0050, 0x05d0, 0x2079, 0x0100, 0x2e04, 0x9084,
0x00ff, 0x2069, 0x181f, 0x206a, 0x78e6, 0x0006, 0x8e70, 0x2e04,
0x2069, 0x1820, 0x206a, 0x78ea, 0x7832, 0x7836, 0x2010, 0x9084,
0xff00, 0x001e, 0x9105, 0x2009, 0x182c, 0x200a, 0x2200, 0x9084,
- 0x00ff, 0x2008, 0x080c, 0x28d2, 0x080c, 0x7563, 0x0170, 0x2071,
+ 0x00ff, 0x2008, 0x080c, 0x28dd, 0x080c, 0x7569, 0x0170, 0x2071,
0x0260, 0x2069, 0x1983, 0x7048, 0x206a, 0x704c, 0x6806, 0x7050,
- 0x680a, 0x7054, 0x680e, 0x080c, 0xd255, 0x0040, 0x2001, 0x0006,
- 0x080c, 0x665d, 0x080c, 0x3274, 0x080c, 0xb0e7, 0x001e, 0x003e,
+ 0x680a, 0x7054, 0x680e, 0x080c, 0xd26c, 0x0040, 0x2001, 0x0006,
+ 0x080c, 0x6663, 0x080c, 0x326f, 0x080c, 0xb101, 0x001e, 0x003e,
0x00de, 0x00ee, 0x00fe, 0x00be, 0x0005, 0x0096, 0x0026, 0x0036,
0x00e6, 0x0156, 0x2019, 0x182c, 0x231c, 0x83ff, 0x01f0, 0x2071,
0x0260, 0x7200, 0x9294, 0x00ff, 0x7004, 0x9084, 0xff00, 0x9205,
0x9306, 0x1198, 0x2011, 0x0276, 0x20a9, 0x0004, 0x2b48, 0x2019,
- 0x000a, 0x080c, 0xc0e7, 0x1148, 0x2011, 0x027a, 0x20a9, 0x0004,
- 0x2019, 0x0006, 0x080c, 0xc0e7, 0x1100, 0x015e, 0x00ee, 0x003e,
+ 0x000a, 0x080c, 0xc0f7, 0x1148, 0x2011, 0x027a, 0x20a9, 0x0004,
+ 0x2019, 0x0006, 0x080c, 0xc0f7, 0x1100, 0x015e, 0x00ee, 0x003e,
0x002e, 0x009e, 0x0005, 0x00e6, 0x2071, 0x0260, 0x7034, 0x9086,
0x0014, 0x11a8, 0x7038, 0x9086, 0x0800, 0x1188, 0x703c, 0xd0ec,
0x0160, 0x9084, 0x0f00, 0x9086, 0x0100, 0x1138, 0x7054, 0xd0a4,
@@ -5949,23 +5939,23 @@ unsigned short risc_code01[] = {
0x0005, 0x00e6, 0x0096, 0x00c6, 0x0076, 0x0056, 0x0046, 0x0026,
0x0006, 0x0126, 0x2091, 0x8000, 0x2029, 0x19f2, 0x252c, 0x2021,
0x19f8, 0x2424, 0x2061, 0x1cd0, 0x2071, 0x1800, 0x7254, 0x7074,
- 0x9202, 0x1a04, 0xc0b3, 0x080c, 0x8bbd, 0x0904, 0xc0ac, 0x080c,
- 0xe971, 0x0904, 0xc0ac, 0x6720, 0x9786, 0x0007, 0x0904, 0xc0ac,
- 0x2500, 0x9c06, 0x0904, 0xc0ac, 0x2400, 0x9c06, 0x05e8, 0x3e08,
+ 0x9202, 0x1a04, 0xc0c3, 0x080c, 0x8bc3, 0x0904, 0xc0bc, 0x080c,
+ 0xe9d6, 0x0904, 0xc0bc, 0x6720, 0x9786, 0x0007, 0x0904, 0xc0bc,
+ 0x2500, 0x9c06, 0x0904, 0xc0bc, 0x2400, 0x9c06, 0x05e8, 0x3e08,
0x9186, 0x0002, 0x1148, 0x6010, 0x9005, 0x0130, 0x00b6, 0x2058,
0xb800, 0x00be, 0xd0bc, 0x1580, 0x00c6, 0x6000, 0x9086, 0x0004,
- 0x1110, 0x080c, 0x1ab7, 0x9786, 0x000a, 0x0148, 0x080c, 0xd047,
- 0x1130, 0x00ce, 0x080c, 0xbacb, 0x080c, 0xb11a, 0x00e8, 0x6014,
- 0x2048, 0x080c, 0xce3f, 0x01a8, 0x9786, 0x0003, 0x1530, 0xa867,
+ 0x1110, 0x080c, 0x1ab7, 0x9786, 0x000a, 0x0148, 0x080c, 0xd05e,
+ 0x1130, 0x00ce, 0x080c, 0xbae2, 0x080c, 0xb134, 0x00e8, 0x6014,
+ 0x2048, 0x080c, 0xce56, 0x01a8, 0x9786, 0x0003, 0x1530, 0xa867,
0x0103, 0xa87c, 0xd0cc, 0x0130, 0x0096, 0xa878, 0x2048, 0x080c,
- 0x0fc0, 0x009e, 0xab7a, 0xa877, 0x0000, 0x080c, 0x6dbe, 0x080c,
- 0xd02a, 0x080c, 0xb11a, 0x00ce, 0x9ce0, 0x0018, 0x7068, 0x9c02,
- 0x1210, 0x0804, 0xc056, 0x012e, 0x000e, 0x002e, 0x004e, 0x005e,
+ 0x0fc0, 0x009e, 0xab7a, 0xa877, 0x0000, 0x080c, 0x6dc4, 0x080c,
+ 0xd041, 0x080c, 0xb134, 0x00ce, 0x9ce0, 0x0018, 0x7068, 0x9c02,
+ 0x1210, 0x0804, 0xc066, 0x012e, 0x000e, 0x002e, 0x004e, 0x005e,
0x007e, 0x00ce, 0x009e, 0x00ee, 0x0005, 0x9786, 0x0006, 0x1118,
- 0x080c, 0xe8e3, 0x0c30, 0x9786, 0x0009, 0x1148, 0x6000, 0x9086,
- 0x0004, 0x0d08, 0x2009, 0x004c, 0x080c, 0xb166, 0x08e0, 0x9786,
+ 0x080c, 0xe948, 0x0c30, 0x9786, 0x0009, 0x1148, 0x6000, 0x9086,
+ 0x0004, 0x0d08, 0x2009, 0x004c, 0x080c, 0xb180, 0x08e0, 0x9786,
0x000a, 0x0980, 0x0820, 0x220c, 0x2304, 0x9106, 0x1130, 0x8210,
- 0x8318, 0x1f04, 0xc0d3, 0x9006, 0x0005, 0x2304, 0x9102, 0x0218,
+ 0x8318, 0x1f04, 0xc0e3, 0x9006, 0x0005, 0x2304, 0x9102, 0x0218,
0x2001, 0x0001, 0x0008, 0x9006, 0x918d, 0x0001, 0x0005, 0x0136,
0x01c6, 0x0016, 0x8906, 0x8006, 0x8007, 0x908c, 0x003f, 0x21e0,
0x9084, 0xffc0, 0x9300, 0x2098, 0x3518, 0x20a9, 0x0001, 0x220c,
@@ -5973,1691 +5963,1702 @@ unsigned short risc_code01[] = {
0x01ce, 0x013e, 0x0005, 0x220c, 0x9102, 0x0218, 0x2001, 0x0001,
0x0010, 0x2001, 0x0000, 0x918d, 0x0001, 0x001e, 0x01ce, 0x013e,
0x0005, 0x220c, 0x810f, 0x2304, 0x9106, 0x1130, 0x8210, 0x8318,
- 0x1f04, 0xc111, 0x9006, 0x0005, 0x918d, 0x0001, 0x0005, 0x6004,
- 0x908a, 0x0053, 0x1a0c, 0x0dc5, 0x080c, 0xd036, 0x0120, 0x080c,
- 0xd047, 0x0168, 0x0028, 0x080c, 0x3274, 0x080c, 0xd047, 0x0138,
- 0x080c, 0x97db, 0x080c, 0xb0e7, 0x080c, 0x98e7, 0x0005, 0x080c,
- 0xbacb, 0x0cb0, 0x9182, 0x0054, 0x1220, 0x9182, 0x0040, 0x0208,
- 0x000a, 0x0005, 0xc156, 0xc156, 0xc156, 0xc156, 0xc156, 0xc156,
- 0xc156, 0xc156, 0xc156, 0xc156, 0xc156, 0xc158, 0xc158, 0xc158,
- 0xc158, 0xc156, 0xc156, 0xc156, 0xc158, 0xc156, 0x080c, 0x0dc5,
- 0x600b, 0xffff, 0x6003, 0x0001, 0x6106, 0x080c, 0x9335, 0x0126,
- 0x2091, 0x8000, 0x080c, 0x98e7, 0x012e, 0x0005, 0x9186, 0x0013,
- 0x1128, 0x6004, 0x9082, 0x0040, 0x0804, 0xc1f0, 0x9186, 0x0027,
- 0x1520, 0x080c, 0x97db, 0x080c, 0x324b, 0x080c, 0xd55d, 0x0096,
- 0x6114, 0x2148, 0x080c, 0xce3f, 0x0198, 0x080c, 0xd047, 0x1118,
- 0x080c, 0xbacb, 0x0068, 0xa867, 0x0103, 0xa87b, 0x0029, 0xa877,
- 0x0000, 0xa97c, 0xc1c5, 0xa97e, 0x080c, 0x6dcb, 0x080c, 0xd02a,
- 0x009e, 0x080c, 0xb0e7, 0x0804, 0x98e7, 0x9186, 0x0014, 0x1120,
+ 0x1f04, 0xc121, 0x9006, 0x0005, 0x918d, 0x0001, 0x0005, 0x6004,
+ 0x908a, 0x0053, 0x1a0c, 0x0dc5, 0x080c, 0xd04d, 0x0120, 0x080c,
+ 0xd05e, 0x0168, 0x0028, 0x080c, 0x326f, 0x080c, 0xd05e, 0x0138,
+ 0x080c, 0x97e1, 0x080c, 0xb101, 0x080c, 0x98ed, 0x0005, 0x080c,
+ 0xbae2, 0x0cb0, 0x9182, 0x0054, 0x1220, 0x9182, 0x0040, 0x0208,
+ 0x000a, 0x0005, 0xc166, 0xc166, 0xc166, 0xc166, 0xc166, 0xc166,
+ 0xc166, 0xc166, 0xc166, 0xc166, 0xc166, 0xc168, 0xc168, 0xc168,
+ 0xc168, 0xc166, 0xc166, 0xc166, 0xc168, 0xc166, 0x080c, 0x0dc5,
+ 0x600b, 0xffff, 0x6003, 0x0001, 0x6106, 0x080c, 0x933b, 0x0126,
+ 0x2091, 0x8000, 0x080c, 0x98ed, 0x012e, 0x0005, 0x9186, 0x0013,
+ 0x1128, 0x6004, 0x9082, 0x0040, 0x0804, 0xc200, 0x9186, 0x0027,
+ 0x1520, 0x080c, 0x97e1, 0x080c, 0x3246, 0x080c, 0xd576, 0x0096,
+ 0x6114, 0x2148, 0x080c, 0xce56, 0x0198, 0x080c, 0xd05e, 0x1118,
+ 0x080c, 0xbae2, 0x0068, 0xa867, 0x0103, 0xa87b, 0x0029, 0xa877,
+ 0x0000, 0xa97c, 0xc1c5, 0xa97e, 0x080c, 0x6dd1, 0x080c, 0xd041,
+ 0x009e, 0x080c, 0xb101, 0x0804, 0x98ed, 0x9186, 0x0014, 0x1120,
0x6004, 0x9082, 0x0040, 0x00b8, 0x9186, 0x0046, 0x0150, 0x9186,
0x0045, 0x0138, 0x9186, 0x0053, 0x0120, 0x9186, 0x0048, 0x190c,
- 0x0dc5, 0x080c, 0xd56e, 0x0130, 0x6000, 0x9086, 0x0002, 0x1110,
- 0x0804, 0xc22e, 0x0005, 0x0002, 0xc1ca, 0xc1c8, 0xc1c8, 0xc1c8,
- 0xc1c8, 0xc1c8, 0xc1c8, 0xc1c8, 0xc1c8, 0xc1c8, 0xc1c8, 0xc1e5,
- 0xc1e5, 0xc1e5, 0xc1e5, 0xc1c8, 0xc1e5, 0xc1c8, 0xc1e5, 0xc1c8,
- 0x080c, 0x0dc5, 0x080c, 0x97db, 0x0096, 0x6114, 0x2148, 0x080c,
- 0xce3f, 0x0168, 0xa867, 0x0103, 0xa87b, 0x0006, 0xa877, 0x0000,
- 0xa880, 0xc0ec, 0xa882, 0x080c, 0x6dcb, 0x080c, 0xd02a, 0x009e,
- 0x080c, 0xb0e7, 0x080c, 0x98e7, 0x0005, 0x080c, 0x97db, 0x080c,
- 0xd047, 0x090c, 0xbacb, 0x080c, 0xb0e7, 0x080c, 0x98e7, 0x0005,
- 0x0002, 0xc207, 0xc205, 0xc205, 0xc205, 0xc205, 0xc205, 0xc205,
- 0xc205, 0xc205, 0xc205, 0xc205, 0xc21e, 0xc21e, 0xc21e, 0xc21e,
- 0xc205, 0xc228, 0xc205, 0xc21e, 0xc205, 0x080c, 0x0dc5, 0x0096,
- 0x080c, 0x97db, 0x6014, 0x2048, 0x2001, 0x1989, 0x2004, 0x6042,
+ 0x0dc5, 0x080c, 0xd587, 0x0130, 0x6000, 0x9086, 0x0002, 0x1110,
+ 0x0804, 0xc23e, 0x0005, 0x0002, 0xc1da, 0xc1d8, 0xc1d8, 0xc1d8,
+ 0xc1d8, 0xc1d8, 0xc1d8, 0xc1d8, 0xc1d8, 0xc1d8, 0xc1d8, 0xc1f5,
+ 0xc1f5, 0xc1f5, 0xc1f5, 0xc1d8, 0xc1f5, 0xc1d8, 0xc1f5, 0xc1d8,
+ 0x080c, 0x0dc5, 0x080c, 0x97e1, 0x0096, 0x6114, 0x2148, 0x080c,
+ 0xce56, 0x0168, 0xa867, 0x0103, 0xa87b, 0x0006, 0xa877, 0x0000,
+ 0xa880, 0xc0ec, 0xa882, 0x080c, 0x6dd1, 0x080c, 0xd041, 0x009e,
+ 0x080c, 0xb101, 0x080c, 0x98ed, 0x0005, 0x080c, 0x97e1, 0x080c,
+ 0xd05e, 0x090c, 0xbae2, 0x080c, 0xb101, 0x080c, 0x98ed, 0x0005,
+ 0x0002, 0xc217, 0xc215, 0xc215, 0xc215, 0xc215, 0xc215, 0xc215,
+ 0xc215, 0xc215, 0xc215, 0xc215, 0xc22e, 0xc22e, 0xc22e, 0xc22e,
+ 0xc215, 0xc238, 0xc215, 0xc22e, 0xc215, 0x080c, 0x0dc5, 0x0096,
+ 0x080c, 0x97e1, 0x6014, 0x2048, 0x2001, 0x1989, 0x2004, 0x6042,
0xa97c, 0xd1ac, 0x0140, 0x6003, 0x0004, 0xa87c, 0x9085, 0x0400,
- 0xa87e, 0x009e, 0x0005, 0x6003, 0x0002, 0x0cb8, 0x080c, 0x97db,
- 0x080c, 0xd560, 0x080c, 0xd565, 0x6003, 0x000f, 0x0804, 0x98e7,
- 0x080c, 0x97db, 0x080c, 0xb0e7, 0x0804, 0x98e7, 0x9182, 0x0054,
- 0x1220, 0x9182, 0x0040, 0x0208, 0x000a, 0x0005, 0xc24a, 0xc24a,
- 0xc24a, 0xc24a, 0xc24a, 0xc24c, 0xc329, 0xc24a, 0xc35d, 0xc24a,
- 0xc24a, 0xc24a, 0xc24a, 0xc24a, 0xc24a, 0xc24a, 0xc24a, 0xc24a,
- 0xc24a, 0xc35d, 0x080c, 0x0dc5, 0x00b6, 0x0096, 0x6114, 0x2148,
+ 0xa87e, 0x009e, 0x0005, 0x6003, 0x0002, 0x0cb8, 0x080c, 0x97e1,
+ 0x080c, 0xd579, 0x080c, 0xd57e, 0x6003, 0x000f, 0x0804, 0x98ed,
+ 0x080c, 0x97e1, 0x080c, 0xb101, 0x0804, 0x98ed, 0x9182, 0x0054,
+ 0x1220, 0x9182, 0x0040, 0x0208, 0x000a, 0x0005, 0xc25a, 0xc25a,
+ 0xc25a, 0xc25a, 0xc25a, 0xc25c, 0xc33c, 0xc25a, 0xc370, 0xc25a,
+ 0xc25a, 0xc25a, 0xc25a, 0xc25a, 0xc25a, 0xc25a, 0xc25a, 0xc25a,
+ 0xc25a, 0xc370, 0x080c, 0x0dc5, 0x00b6, 0x0096, 0x6114, 0x2148,
0x7644, 0x96b4, 0x0fff, 0x86ff, 0x1528, 0x6010, 0x2058, 0xb800,
- 0xd0bc, 0x1904, 0xc318, 0xa87b, 0x0000, 0xa867, 0x0103, 0xae76,
- 0xa87c, 0xd0ac, 0x0128, 0xa834, 0xa938, 0x9115, 0x190c, 0xc4f6,
- 0x080c, 0x6be5, 0x6210, 0x2258, 0xba3c, 0x82ff, 0x0110, 0x8211,
- 0xba3e, 0x7044, 0xd0e4, 0x1904, 0xc2fc, 0x080c, 0xb0e7, 0x009e,
+ 0xd0bc, 0x1904, 0xc32b, 0xa87b, 0x0000, 0xa867, 0x0103, 0xae76,
+ 0xa87c, 0xd0ac, 0x0128, 0xa834, 0xa938, 0x9115, 0x190c, 0xc509,
+ 0x080c, 0x6beb, 0x6210, 0x2258, 0xba3c, 0x82ff, 0x0110, 0x8211,
+ 0xba3e, 0x7044, 0xd0e4, 0x1904, 0xc30c, 0x080c, 0xb101, 0x009e,
0x00be, 0x0005, 0x968c, 0x0c00, 0x0150, 0x6010, 0x2058, 0xb800,
- 0xd0bc, 0x1904, 0xc300, 0x7348, 0xab92, 0x734c, 0xab8e, 0x968c,
+ 0xd0bc, 0x1904, 0xc310, 0x7348, 0xab92, 0x734c, 0xab8e, 0x968c,
0x00ff, 0x9186, 0x0002, 0x0508, 0x9186, 0x0028, 0x1118, 0xa87b,
0x001c, 0x00e8, 0xd6dc, 0x01a0, 0xa87b, 0x0015, 0xa87c, 0xd0ac,
0x0170, 0xa938, 0xaa34, 0x2100, 0x9205, 0x0148, 0x7048, 0x9106,
0x1118, 0x704c, 0x9206, 0x0118, 0xa992, 0xaa8e, 0xc6dc, 0x0038,
0xd6d4, 0x0118, 0xa87b, 0x0007, 0x0010, 0xa87b, 0x0000, 0xa867,
0x0103, 0xae76, 0x901e, 0xd6c4, 0x01d8, 0x9686, 0x0100, 0x1130,
- 0x7064, 0x9005, 0x1118, 0xc6c4, 0x0804, 0xc253, 0x735c, 0xab86,
+ 0x7064, 0x9005, 0x1118, 0xc6c4, 0x0804, 0xc263, 0x735c, 0xab86,
0x83ff, 0x0170, 0x938a, 0x0009, 0x0210, 0x2019, 0x0008, 0x0036,
- 0x2308, 0x2019, 0x0018, 0x2011, 0x0025, 0x080c, 0xc9f0, 0x003e,
- 0xd6cc, 0x0904, 0xc268, 0x7154, 0xa98a, 0x81ff, 0x0904, 0xc268,
+ 0x2308, 0x2019, 0x0018, 0x2011, 0x0025, 0x080c, 0xca03, 0x003e,
+ 0xd6cc, 0x0904, 0xc278, 0x7154, 0xa98a, 0x81ff, 0x0904, 0xc278,
0x9192, 0x0021, 0x1278, 0x8304, 0x9098, 0x0018, 0x2011, 0x0029,
- 0x080c, 0xc9f0, 0x2011, 0x0205, 0x2013, 0x0000, 0x080c, 0xd4ed,
- 0x0804, 0xc268, 0xa868, 0xd0fc, 0x0120, 0x2009, 0x0020, 0xa98a,
- 0x0c50, 0x00a6, 0x2950, 0x080c, 0xc98f, 0x00ae, 0x080c, 0xd4ed,
- 0x080c, 0xc9e0, 0x0804, 0xc26a, 0x080c, 0xd13f, 0x0804, 0xc277,
- 0xa87c, 0xd0ac, 0x0904, 0xc283, 0xa880, 0xd0bc, 0x1904, 0xc283,
- 0x7348, 0xa838, 0x9306, 0x11c8, 0x734c, 0xa834, 0x931e, 0x0904,
- 0xc283, 0xd6d4, 0x0190, 0xab38, 0x9305, 0x0904, 0xc283, 0x0068,
- 0xa87c, 0xd0ac, 0x0904, 0xc25b, 0xa838, 0xa934, 0x9105, 0x0904,
- 0xc25b, 0xa880, 0xd0bc, 0x1904, 0xc25b, 0x080c, 0xd179, 0x0804,
- 0xc277, 0x0096, 0x00f6, 0x6003, 0x0003, 0x6007, 0x0043, 0x2079,
- 0x026c, 0x7c04, 0x7b00, 0x7e0c, 0x7d08, 0x6014, 0x2048, 0xa87c,
- 0xd0ac, 0x0140, 0x6003, 0x0002, 0x00fe, 0x009e, 0x0005, 0x2130,
- 0x2228, 0x0058, 0x2400, 0xa9ac, 0x910a, 0x2300, 0xaab0, 0x9213,
- 0x2600, 0x9102, 0x2500, 0x9203, 0x0e90, 0xac36, 0xab3a, 0xae46,
- 0xad4a, 0x00fe, 0x6043, 0x0000, 0x2c10, 0x080c, 0x1c01, 0x080c,
- 0x939a, 0x080c, 0x9a09, 0x009e, 0x0005, 0x0005, 0x9182, 0x0054,
- 0x1220, 0x9182, 0x0040, 0x0208, 0x000a, 0x0005, 0xc37a, 0xc37a,
- 0xc37a, 0xc37a, 0xc37a, 0xc37c, 0xc412, 0xc37a, 0xc37a, 0xc429,
- 0xc4b9, 0xc37a, 0xc37a, 0xc37a, 0xc37a, 0xc4ce, 0xc37a, 0xc37a,
- 0xc37a, 0xc37a, 0x080c, 0x0dc5, 0x0076, 0x00a6, 0x00e6, 0x0096,
- 0x2071, 0x0260, 0x6114, 0x2150, 0x7644, 0xb676, 0x96b4, 0x0fff,
- 0xb77c, 0xc7e5, 0xb77e, 0x6210, 0x00b6, 0x2258, 0xba3c, 0x82ff,
- 0x0110, 0x8211, 0xba3e, 0x00be, 0x86ff, 0x0904, 0xc40d, 0x9694,
- 0xff00, 0x9284, 0x0c00, 0x0120, 0x7048, 0xb092, 0x704c, 0xb08e,
- 0x9284, 0x0300, 0x0904, 0xc40d, 0x080c, 0x100e, 0x090c, 0x0dc5,
- 0x2900, 0xb07a, 0xb77c, 0xc7cd, 0xb77e, 0xa867, 0x0103, 0xb068,
- 0xa86a, 0xb06c, 0xa86e, 0xb070, 0xa872, 0xae76, 0x968c, 0x0c00,
+ 0x080c, 0xca03, 0x2011, 0x0205, 0x2013, 0x0000, 0x080c, 0xd504,
+ 0x0804, 0xc278, 0xa868, 0xd0fc, 0x0120, 0x2009, 0x0020, 0xa98a,
+ 0x0c50, 0x00a6, 0x2950, 0x080c, 0xc9a2, 0x00ae, 0x080c, 0xd504,
+ 0x080c, 0xc9f3, 0x0804, 0xc27a, 0x080c, 0xd156, 0x0804, 0xc287,
+ 0xa87c, 0xd0ac, 0x0904, 0xc293, 0xa880, 0xd0bc, 0x1904, 0xc293,
+ 0x9684, 0x0400, 0x0130, 0xa838, 0xab34, 0x9305, 0x0904, 0xc293,
+ 0x00b8, 0x7348, 0xa838, 0x9306, 0x1198, 0x734c, 0xa834, 0x931e,
+ 0x0904, 0xc293, 0x0068, 0xa87c, 0xd0ac, 0x0904, 0xc26b, 0xa838,
+ 0xa934, 0x9105, 0x0904, 0xc26b, 0xa880, 0xd0bc, 0x1904, 0xc26b,
+ 0x080c, 0xd190, 0x0804, 0xc287, 0x0096, 0x00f6, 0x6003, 0x0003,
+ 0x6007, 0x0043, 0x2079, 0x026c, 0x7c04, 0x7b00, 0x7e0c, 0x7d08,
+ 0x6014, 0x2048, 0xa87c, 0xd0ac, 0x0140, 0x6003, 0x0002, 0x00fe,
+ 0x009e, 0x0005, 0x2130, 0x2228, 0x0058, 0x2400, 0xa9ac, 0x910a,
+ 0x2300, 0xaab0, 0x9213, 0x2600, 0x9102, 0x2500, 0x9203, 0x0e90,
+ 0xac36, 0xab3a, 0xae46, 0xad4a, 0x00fe, 0x6043, 0x0000, 0x2c10,
+ 0x080c, 0x1c09, 0x080c, 0x93a0, 0x080c, 0x9a0f, 0x009e, 0x0005,
+ 0x0005, 0x9182, 0x0054, 0x1220, 0x9182, 0x0040, 0x0208, 0x000a,
+ 0x0005, 0xc38d, 0xc38d, 0xc38d, 0xc38d, 0xc38d, 0xc38f, 0xc425,
+ 0xc38d, 0xc38d, 0xc43c, 0xc4cc, 0xc38d, 0xc38d, 0xc38d, 0xc38d,
+ 0xc4e1, 0xc38d, 0xc38d, 0xc38d, 0xc38d, 0x080c, 0x0dc5, 0x0076,
+ 0x00a6, 0x00e6, 0x0096, 0x2071, 0x0260, 0x6114, 0x2150, 0x7644,
+ 0xb676, 0x96b4, 0x0fff, 0xb77c, 0xc7e5, 0xb77e, 0x6210, 0x00b6,
+ 0x2258, 0xba3c, 0x82ff, 0x0110, 0x8211, 0xba3e, 0x00be, 0x86ff,
+ 0x0904, 0xc420, 0x9694, 0xff00, 0x9284, 0x0c00, 0x0120, 0x7048,
+ 0xb092, 0x704c, 0xb08e, 0x9284, 0x0300, 0x0904, 0xc420, 0x080c,
+ 0x100e, 0x090c, 0x0dc5, 0x2900, 0xb07a, 0xb77c, 0xc7cd, 0xb77e,
+ 0xa867, 0x0103, 0xb068, 0xa86a, 0xb06c, 0xa86e, 0xb070, 0xa872,
+ 0xae76, 0x968c, 0x0c00, 0x0120, 0x7348, 0xab92, 0x734c, 0xab8e,
+ 0x968c, 0x00ff, 0x9186, 0x0002, 0x0180, 0x9186, 0x0028, 0x1118,
+ 0xa87b, 0x001c, 0x0060, 0xd6dc, 0x0118, 0xa87b, 0x0015, 0x0038,
+ 0xd6d4, 0x0118, 0xa87b, 0x0007, 0x0010, 0xa87b, 0x0000, 0xaf7e,
+ 0xb080, 0xa882, 0xb084, 0xa886, 0x901e, 0xd6c4, 0x0190, 0x735c,
+ 0xab86, 0x83ff, 0x0170, 0x938a, 0x0009, 0x0210, 0x2019, 0x0008,
+ 0x0036, 0x2308, 0x2019, 0x0018, 0x2011, 0x0025, 0x080c, 0xca03,
+ 0x003e, 0xd6cc, 0x01e8, 0x7154, 0xa98a, 0x81ff, 0x01c8, 0x9192,
+ 0x0021, 0x1260, 0x8304, 0x9098, 0x0018, 0x2011, 0x0029, 0x080c,
+ 0xca03, 0x2011, 0x0205, 0x2013, 0x0000, 0x0050, 0xb068, 0xd0fc,
+ 0x0120, 0x2009, 0x0020, 0xa98a, 0x0c68, 0x2950, 0x080c, 0xc9a2,
+ 0x009e, 0x00ee, 0x00ae, 0x007e, 0x0005, 0x00f6, 0x00a6, 0x6003,
+ 0x0003, 0x2079, 0x026c, 0x7c04, 0x7b00, 0x7e0c, 0x7d08, 0x6014,
+ 0x2050, 0xb436, 0xb33a, 0xb646, 0xb54a, 0x00ae, 0x00fe, 0x2c10,
+ 0x080c, 0x1c09, 0x0804, 0xa4e4, 0x6003, 0x0002, 0x6004, 0x9086,
+ 0x0040, 0x11c8, 0x0096, 0x6014, 0x2048, 0xa87c, 0xd0ac, 0x0160,
+ 0x601c, 0xd084, 0x1130, 0x00f6, 0x2c00, 0x2078, 0x080c, 0x1768,
+ 0x00fe, 0x6003, 0x0004, 0x0010, 0x6003, 0x0002, 0x009e, 0x080c,
+ 0x97e1, 0x080c, 0x98ed, 0x0096, 0x2001, 0x1989, 0x2004, 0x6042,
+ 0x080c, 0x989d, 0x080c, 0x9a0f, 0x6114, 0x2148, 0xa97c, 0xd1e4,
+ 0x0904, 0xc4c7, 0xd1cc, 0x05c8, 0xa978, 0xa868, 0xd0fc, 0x0540,
+ 0x0016, 0xa87c, 0x0006, 0xa880, 0x0006, 0xa860, 0x20e8, 0xa85c,
+ 0x9080, 0x0019, 0x20a0, 0x810e, 0x810e, 0x810f, 0x9184, 0x003f,
+ 0x20e0, 0x9184, 0xffc0, 0x9080, 0x0019, 0x2098, 0x0156, 0x20a9,
+ 0x0020, 0x4003, 0x015e, 0x000e, 0xa882, 0x000e, 0xc0cc, 0xa87e,
+ 0x001e, 0xa874, 0x0006, 0x2148, 0x080c, 0x0fc0, 0x001e, 0x0458,
+ 0x0016, 0x080c, 0x0fc0, 0x009e, 0xa87c, 0xc0cc, 0xa87e, 0xa974,
+ 0x0016, 0x080c, 0xc9f3, 0x001e, 0x00f0, 0xa867, 0x0103, 0xa974,
+ 0x9184, 0x00ff, 0x90b6, 0x0002, 0x0180, 0x9086, 0x0028, 0x1118,
+ 0xa87b, 0x001c, 0x0060, 0xd1dc, 0x0118, 0xa87b, 0x0015, 0x0038,
+ 0xd1d4, 0x0118, 0xa87b, 0x0007, 0x0010, 0xa87b, 0x0000, 0x0016,
+ 0x080c, 0x6beb, 0x001e, 0xd1e4, 0x1120, 0x080c, 0xb101, 0x009e,
+ 0x0005, 0x080c, 0xd156, 0x0cd8, 0x6004, 0x9086, 0x0040, 0x1120,
+ 0x080c, 0x97e1, 0x080c, 0x98ed, 0x2019, 0x0001, 0x080c, 0xa877,
+ 0x6003, 0x0002, 0x080c, 0xd57e, 0x080c, 0x989d, 0x080c, 0x9a0f,
+ 0x0005, 0x6004, 0x9086, 0x0040, 0x1120, 0x080c, 0x97e1, 0x080c,
+ 0x98ed, 0x2019, 0x0001, 0x080c, 0xa877, 0x080c, 0x989d, 0x080c,
+ 0x3246, 0x080c, 0xd576, 0x0096, 0x6114, 0x2148, 0x080c, 0xce56,
+ 0x0150, 0xa867, 0x0103, 0xa87b, 0x0029, 0xa877, 0x0000, 0x080c,
+ 0x6dd1, 0x080c, 0xd041, 0x009e, 0x080c, 0xb101, 0x080c, 0x9a0f,
+ 0x0005, 0xa87b, 0x0015, 0xd1fc, 0x0180, 0xa87b, 0x0007, 0x8002,
+ 0x8000, 0x810a, 0x9189, 0x0000, 0x0006, 0x0016, 0x2009, 0x1a7e,
+ 0x2104, 0x8000, 0x200a, 0x001e, 0x000e, 0xa992, 0xa88e, 0x0005,
+ 0x9182, 0x0054, 0x1220, 0x9182, 0x0040, 0x0208, 0x000a, 0x0005,
+ 0xc53c, 0xc53c, 0xc53c, 0xc53c, 0xc53c, 0xc53e, 0xc53c, 0xc53c,
+ 0xc5e4, 0xc53c, 0xc53c, 0xc53c, 0xc53c, 0xc53c, 0xc53c, 0xc53c,
+ 0xc53c, 0xc53c, 0xc53c, 0xc716, 0x080c, 0x0dc5, 0x0076, 0x00a6,
+ 0x00e6, 0x0096, 0x2071, 0x0260, 0x6114, 0x2150, 0x7644, 0xb676,
+ 0x96b4, 0x0fff, 0xb77c, 0xc7e5, 0xb77e, 0x6210, 0x00b6, 0x2258,
+ 0xba3c, 0x82ff, 0x0110, 0x8211, 0xba3e, 0x00be, 0x86ff, 0x0904,
+ 0xc5dd, 0x9694, 0xff00, 0x9284, 0x0c00, 0x0120, 0x7048, 0xb092,
+ 0x704c, 0xb08e, 0x9284, 0x0300, 0x0904, 0xc5dd, 0x9686, 0x0100,
+ 0x1130, 0x7064, 0x9005, 0x1118, 0xc6c4, 0xb676, 0x0c38, 0x080c,
+ 0x100e, 0x090c, 0x0dc5, 0x2900, 0xb07a, 0xb77c, 0x97bd, 0x0200,
+ 0xb77e, 0xa867, 0x0103, 0xb068, 0xa86a, 0xb06c, 0xa86e, 0xb070,
+ 0xa872, 0x7044, 0x9084, 0xf000, 0x9635, 0xae76, 0x968c, 0x0c00,
0x0120, 0x7348, 0xab92, 0x734c, 0xab8e, 0x968c, 0x00ff, 0x9186,
0x0002, 0x0180, 0x9186, 0x0028, 0x1118, 0xa87b, 0x001c, 0x0060,
0xd6dc, 0x0118, 0xa87b, 0x0015, 0x0038, 0xd6d4, 0x0118, 0xa87b,
0x0007, 0x0010, 0xa87b, 0x0000, 0xaf7e, 0xb080, 0xa882, 0xb084,
0xa886, 0x901e, 0xd6c4, 0x0190, 0x735c, 0xab86, 0x83ff, 0x0170,
0x938a, 0x0009, 0x0210, 0x2019, 0x0008, 0x0036, 0x2308, 0x2019,
- 0x0018, 0x2011, 0x0025, 0x080c, 0xc9f0, 0x003e, 0xd6cc, 0x01e8,
+ 0x0018, 0x2011, 0x0025, 0x080c, 0xca03, 0x003e, 0xd6cc, 0x01e8,
0x7154, 0xa98a, 0x81ff, 0x01c8, 0x9192, 0x0021, 0x1260, 0x8304,
- 0x9098, 0x0018, 0x2011, 0x0029, 0x080c, 0xc9f0, 0x2011, 0x0205,
+ 0x9098, 0x0018, 0x2011, 0x0029, 0x080c, 0xca03, 0x2011, 0x0205,
0x2013, 0x0000, 0x0050, 0xb068, 0xd0fc, 0x0120, 0x2009, 0x0020,
- 0xa98a, 0x0c68, 0x2950, 0x080c, 0xc98f, 0x009e, 0x00ee, 0x00ae,
- 0x007e, 0x0005, 0x00f6, 0x00a6, 0x6003, 0x0003, 0x2079, 0x026c,
- 0x7c04, 0x7b00, 0x7e0c, 0x7d08, 0x6014, 0x2050, 0xb436, 0xb33a,
- 0xb646, 0xb54a, 0x00ae, 0x00fe, 0x2c10, 0x080c, 0x1c01, 0x0804,
- 0xa4ca, 0x6003, 0x0002, 0x6004, 0x9086, 0x0040, 0x11c8, 0x0096,
- 0x6014, 0x2048, 0xa87c, 0xd0ac, 0x0160, 0x601c, 0xd084, 0x1130,
- 0x00f6, 0x2c00, 0x2078, 0x080c, 0x1768, 0x00fe, 0x6003, 0x0004,
- 0x0010, 0x6003, 0x0002, 0x009e, 0x080c, 0x97db, 0x080c, 0x98e7,
- 0x0096, 0x2001, 0x1989, 0x2004, 0x6042, 0x080c, 0x9897, 0x080c,
- 0x9a09, 0x6114, 0x2148, 0xa97c, 0xd1e4, 0x0904, 0xc4b4, 0xd1cc,
- 0x05c8, 0xa978, 0xa868, 0xd0fc, 0x0540, 0x0016, 0xa87c, 0x0006,
- 0xa880, 0x0006, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0019, 0x20a0,
- 0x810e, 0x810e, 0x810f, 0x9184, 0x003f, 0x20e0, 0x9184, 0xffc0,
- 0x9080, 0x0019, 0x2098, 0x0156, 0x20a9, 0x0020, 0x4003, 0x015e,
- 0x000e, 0xa882, 0x000e, 0xc0cc, 0xa87e, 0x001e, 0xa874, 0x0006,
- 0x2148, 0x080c, 0x0fc0, 0x001e, 0x0458, 0x0016, 0x080c, 0x0fc0,
- 0x009e, 0xa87c, 0xc0cc, 0xa87e, 0xa974, 0x0016, 0x080c, 0xc9e0,
- 0x001e, 0x00f0, 0xa867, 0x0103, 0xa974, 0x9184, 0x00ff, 0x90b6,
- 0x0002, 0x0180, 0x9086, 0x0028, 0x1118, 0xa87b, 0x001c, 0x0060,
- 0xd1dc, 0x0118, 0xa87b, 0x0015, 0x0038, 0xd1d4, 0x0118, 0xa87b,
- 0x0007, 0x0010, 0xa87b, 0x0000, 0x0016, 0x080c, 0x6be5, 0x001e,
- 0xd1e4, 0x1120, 0x080c, 0xb0e7, 0x009e, 0x0005, 0x080c, 0xd13f,
- 0x0cd8, 0x6004, 0x9086, 0x0040, 0x1120, 0x080c, 0x97db, 0x080c,
- 0x98e7, 0x2019, 0x0001, 0x080c, 0xa85d, 0x6003, 0x0002, 0x080c,
- 0xd565, 0x080c, 0x9897, 0x080c, 0x9a09, 0x0005, 0x6004, 0x9086,
- 0x0040, 0x1120, 0x080c, 0x97db, 0x080c, 0x98e7, 0x2019, 0x0001,
- 0x080c, 0xa85d, 0x080c, 0x9897, 0x080c, 0x324b, 0x080c, 0xd55d,
- 0x0096, 0x6114, 0x2148, 0x080c, 0xce3f, 0x0150, 0xa867, 0x0103,
- 0xa87b, 0x0029, 0xa877, 0x0000, 0x080c, 0x6dcb, 0x080c, 0xd02a,
- 0x009e, 0x080c, 0xb0e7, 0x080c, 0x9a09, 0x0005, 0xa87b, 0x0015,
- 0xd1fc, 0x0180, 0xa87b, 0x0007, 0x8002, 0x8000, 0x810a, 0x9189,
- 0x0000, 0x0006, 0x0016, 0x2009, 0x1a7e, 0x2104, 0x8000, 0x200a,
- 0x001e, 0x000e, 0xa992, 0xa88e, 0x0005, 0x9182, 0x0054, 0x1220,
- 0x9182, 0x0040, 0x0208, 0x000a, 0x0005, 0xc529, 0xc529, 0xc529,
- 0xc529, 0xc529, 0xc52b, 0xc529, 0xc529, 0xc5d1, 0xc529, 0xc529,
- 0xc529, 0xc529, 0xc529, 0xc529, 0xc529, 0xc529, 0xc529, 0xc529,
- 0xc703, 0x080c, 0x0dc5, 0x0076, 0x00a6, 0x00e6, 0x0096, 0x2071,
- 0x0260, 0x6114, 0x2150, 0x7644, 0xb676, 0x96b4, 0x0fff, 0xb77c,
- 0xc7e5, 0xb77e, 0x6210, 0x00b6, 0x2258, 0xba3c, 0x82ff, 0x0110,
- 0x8211, 0xba3e, 0x00be, 0x86ff, 0x0904, 0xc5ca, 0x9694, 0xff00,
- 0x9284, 0x0c00, 0x0120, 0x7048, 0xb092, 0x704c, 0xb08e, 0x9284,
- 0x0300, 0x0904, 0xc5ca, 0x9686, 0x0100, 0x1130, 0x7064, 0x9005,
- 0x1118, 0xc6c4, 0xb676, 0x0c38, 0x080c, 0x100e, 0x090c, 0x0dc5,
- 0x2900, 0xb07a, 0xb77c, 0x97bd, 0x0200, 0xb77e, 0xa867, 0x0103,
- 0xb068, 0xa86a, 0xb06c, 0xa86e, 0xb070, 0xa872, 0x7044, 0x9084,
- 0xf000, 0x9635, 0xae76, 0x968c, 0x0c00, 0x0120, 0x7348, 0xab92,
- 0x734c, 0xab8e, 0x968c, 0x00ff, 0x9186, 0x0002, 0x0180, 0x9186,
- 0x0028, 0x1118, 0xa87b, 0x001c, 0x0060, 0xd6dc, 0x0118, 0xa87b,
- 0x0015, 0x0038, 0xd6d4, 0x0118, 0xa87b, 0x0007, 0x0010, 0xa87b,
- 0x0000, 0xaf7e, 0xb080, 0xa882, 0xb084, 0xa886, 0x901e, 0xd6c4,
- 0x0190, 0x735c, 0xab86, 0x83ff, 0x0170, 0x938a, 0x0009, 0x0210,
- 0x2019, 0x0008, 0x0036, 0x2308, 0x2019, 0x0018, 0x2011, 0x0025,
- 0x080c, 0xc9f0, 0x003e, 0xd6cc, 0x01e8, 0x7154, 0xa98a, 0x81ff,
- 0x01c8, 0x9192, 0x0021, 0x1260, 0x8304, 0x9098, 0x0018, 0x2011,
- 0x0029, 0x080c, 0xc9f0, 0x2011, 0x0205, 0x2013, 0x0000, 0x0050,
- 0xb068, 0xd0fc, 0x0120, 0x2009, 0x0020, 0xa98a, 0x0c68, 0x2950,
- 0x080c, 0xc98f, 0x080c, 0x1a83, 0x009e, 0x00ee, 0x00ae, 0x007e,
- 0x0005, 0x2001, 0x1989, 0x2004, 0x6042, 0x0096, 0x6114, 0x2148,
- 0xa83c, 0xa940, 0x9105, 0x1118, 0xa87c, 0xc0dc, 0xa87e, 0x6003,
- 0x0002, 0xa97c, 0xd1e4, 0x0904, 0xc6fe, 0x6043, 0x0000, 0x6010,
- 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x1500, 0xd1cc, 0x0904,
- 0xc6cd, 0xa978, 0xa868, 0xd0fc, 0x0904, 0xc68e, 0x0016, 0xa87c,
- 0x0006, 0xa880, 0x0006, 0x00a6, 0x2150, 0xb174, 0x9184, 0x00ff,
- 0x90b6, 0x0002, 0x0904, 0xc65b, 0x9086, 0x0028, 0x1904, 0xc647,
- 0xa87b, 0x001c, 0xb07b, 0x001c, 0x0804, 0xc663, 0x6024, 0xd0f4,
- 0x11d0, 0xa838, 0xaa34, 0x9205, 0x09c8, 0xa838, 0xaa90, 0x9206,
- 0x1120, 0xa88c, 0xaa34, 0x9206, 0x0988, 0x6024, 0xd0d4, 0x1148,
- 0xa9ac, 0xa834, 0x9102, 0x603a, 0xa9b0, 0xa838, 0x9103, 0x603e,
- 0x6024, 0xc0f5, 0x6026, 0x6010, 0x00b6, 0x2058, 0xb83c, 0x8000,
- 0xb83e, 0x00be, 0x9006, 0xa876, 0xa892, 0xa88e, 0xa87c, 0xc0e4,
- 0xa87e, 0xd0cc, 0x0140, 0xc0cc, 0xa87e, 0x0096, 0xa878, 0x2048,
- 0x080c, 0x0fc0, 0x009e, 0x080c, 0xd179, 0x0804, 0xc6fe, 0xd1dc,
- 0x0158, 0xa87b, 0x0015, 0xb07b, 0x0015, 0x080c, 0xd40d, 0x0118,
- 0xb174, 0xc1dc, 0xb176, 0x0078, 0xd1d4, 0x0128, 0xa87b, 0x0007,
- 0xb07b, 0x0007, 0x0040, 0xa87c, 0xd0ac, 0x0128, 0xa834, 0xa938,
- 0x9115, 0x190c, 0xc4f6, 0xa87c, 0xb07e, 0xa890, 0xb092, 0xa88c,
- 0xb08e, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0019, 0x20a0, 0x20a9,
- 0x0020, 0x8a06, 0x8006, 0x8007, 0x9094, 0x003f, 0x22e0, 0x9084,
- 0xffc0, 0x9080, 0x0019, 0x2098, 0x4003, 0x00ae, 0x000e, 0xa882,
- 0x000e, 0xc0cc, 0xa87e, 0x080c, 0xd4ed, 0x001e, 0xa874, 0x0006,
- 0x2148, 0x080c, 0x0fc0, 0x001e, 0x0804, 0xc6fa, 0x0016, 0x00a6,
- 0x2150, 0xb174, 0x9184, 0x00ff, 0x90b6, 0x0002, 0x01e0, 0x9086,
- 0x0028, 0x1128, 0xa87b, 0x001c, 0xb07b, 0x001c, 0x00e0, 0xd1dc,
- 0x0158, 0xa87b, 0x0015, 0xb07b, 0x0015, 0x080c, 0xd40d, 0x0118,
- 0xb174, 0xc1dc, 0xb176, 0x0078, 0xd1d4, 0x0128, 0xa87b, 0x0007,
- 0xb07b, 0x0007, 0x0040, 0xa87c, 0xd0ac, 0x0128, 0xa834, 0xa938,
- 0x9115, 0x190c, 0xc4f6, 0xa890, 0xb092, 0xa88c, 0xb08e, 0xa87c,
- 0xb07e, 0x00ae, 0x080c, 0x0fc0, 0x009e, 0x080c, 0xd4ed, 0xa974,
- 0x0016, 0x080c, 0xc9e0, 0x001e, 0x0468, 0xa867, 0x0103, 0xa974,
- 0x9184, 0x00ff, 0x90b6, 0x0002, 0x01b0, 0x9086, 0x0028, 0x1118,
- 0xa87b, 0x001c, 0x00d0, 0xd1dc, 0x0148, 0xa87b, 0x0015, 0x080c,
- 0xd40d, 0x0118, 0xa974, 0xc1dc, 0xa976, 0x0078, 0xd1d4, 0x0118,
- 0xa87b, 0x0007, 0x0050, 0xa87b, 0x0000, 0xa87c, 0xd0ac, 0x0128,
- 0xa834, 0xa938, 0x9115, 0x190c, 0xc4f6, 0xa974, 0x0016, 0x080c,
- 0x6be5, 0x001e, 0xd1e4, 0x1120, 0x080c, 0xb0e7, 0x009e, 0x0005,
- 0x080c, 0xd13f, 0x0cd8, 0x6114, 0x0096, 0x2148, 0xa97c, 0xd1e4,
- 0x190c, 0x1aa3, 0x009e, 0x0005, 0x080c, 0x97db, 0x0010, 0x080c,
- 0x9897, 0x080c, 0xce3f, 0x01f0, 0x0096, 0x6114, 0x2148, 0x080c,
- 0xd047, 0x1118, 0x080c, 0xbacb, 0x00a0, 0xa867, 0x0103, 0x2009,
- 0x180c, 0x210c, 0xd18c, 0x11b8, 0xd184, 0x1190, 0x6108, 0xa97a,
- 0x918e, 0x0029, 0x1110, 0x080c, 0xec9b, 0xa877, 0x0000, 0x080c,
- 0x6dcb, 0x009e, 0x080c, 0xb0e7, 0x080c, 0x98e7, 0x0804, 0x9a09,
- 0xa87b, 0x0004, 0x0c90, 0xa87b, 0x0004, 0x0c78, 0x9182, 0x0054,
- 0x1220, 0x9182, 0x0040, 0x0208, 0x000a, 0x0005, 0xc75a, 0xc75a,
- 0xc75a, 0xc75a, 0xc75a, 0xc75c, 0xc75a, 0xc75a, 0xc75a, 0xc75a,
- 0xc75a, 0xc75a, 0xc75a, 0xc75a, 0xc75a, 0xc75a, 0xc75a, 0xc75a,
- 0xc75a, 0xc75a, 0x080c, 0x0dc5, 0x080c, 0x57d5, 0x01f8, 0x6014,
- 0x7144, 0x918c, 0x0fff, 0x9016, 0xd1c4, 0x0118, 0x7264, 0x9294,
- 0x00ff, 0x0096, 0x904d, 0x0188, 0xa87b, 0x0000, 0xa864, 0x9086,
- 0x0139, 0x0128, 0xa867, 0x0103, 0xa976, 0xaa96, 0x0030, 0xa897,
- 0x4000, 0xa99a, 0xaa9e, 0x080c, 0x6dcb, 0x009e, 0x0804, 0xb0e7,
- 0x9182, 0x0085, 0x0002, 0xc792, 0xc790, 0xc790, 0xc79e, 0xc790,
- 0xc790, 0xc790, 0xc790, 0xc790, 0xc790, 0xc790, 0xc790, 0xc790,
- 0x080c, 0x0dc5, 0x6003, 0x0001, 0x6106, 0x080c, 0x9335, 0x0126,
- 0x2091, 0x8000, 0x080c, 0x98e7, 0x012e, 0x0005, 0x0026, 0x0056,
- 0x00d6, 0x00e6, 0x2071, 0x0260, 0x7224, 0x6216, 0x7220, 0x080c,
- 0xce2d, 0x01f8, 0x2268, 0x6800, 0x9086, 0x0000, 0x01d0, 0x6010,
- 0x6d10, 0x952e, 0x11b0, 0x00c6, 0x2d60, 0x00d6, 0x080c, 0xca51,
- 0x00de, 0x00ce, 0x0158, 0x702c, 0xd084, 0x1118, 0x080c, 0xca1b,
- 0x0010, 0x6803, 0x0002, 0x6007, 0x0086, 0x0028, 0x080c, 0xca3d,
- 0x0d90, 0x6007, 0x0087, 0x6003, 0x0001, 0x080c, 0x9335, 0x080c,
- 0x98e7, 0x7220, 0x080c, 0xce2d, 0x0178, 0x6810, 0x00b6, 0x2058,
- 0xb800, 0x00be, 0xd0bc, 0x0140, 0x6824, 0xd0ec, 0x0128, 0x00c6,
- 0x2d60, 0x080c, 0xd179, 0x00ce, 0x00ee, 0x00de, 0x005e, 0x002e,
- 0x0005, 0x9186, 0x0013, 0x1160, 0x6004, 0x908a, 0x0085, 0x0a0c,
- 0x0dc5, 0x908a, 0x0092, 0x1a0c, 0x0dc5, 0x9082, 0x0085, 0x00e2,
- 0x9186, 0x0027, 0x0120, 0x9186, 0x0014, 0x190c, 0x0dc5, 0x080c,
- 0x97db, 0x0096, 0x6014, 0x2048, 0x080c, 0xce3f, 0x0140, 0xa867,
- 0x0103, 0xa877, 0x0000, 0xa87b, 0x0029, 0x080c, 0x6dcb, 0x009e,
- 0x080c, 0xb11a, 0x0804, 0x98e7, 0xc821, 0xc823, 0xc823, 0xc821,
- 0xc821, 0xc821, 0xc821, 0xc821, 0xc821, 0xc821, 0xc821, 0xc821,
- 0xc821, 0x080c, 0x0dc5, 0x080c, 0x97db, 0x080c, 0xb11a, 0x080c,
- 0x98e7, 0x0005, 0x9186, 0x0013, 0x1128, 0x6004, 0x9082, 0x0085,
- 0x2008, 0x04b8, 0x9186, 0x0027, 0x11f8, 0x080c, 0x97db, 0x080c,
- 0x324b, 0x080c, 0xd55d, 0x0096, 0x6014, 0x2048, 0x080c, 0xce3f,
- 0x0150, 0xa867, 0x0103, 0xa877, 0x0000, 0xa87b, 0x0029, 0x080c,
- 0x6dcb, 0x080c, 0xd02a, 0x009e, 0x080c, 0xb0e7, 0x080c, 0x98e7,
- 0x0005, 0x080c, 0xb181, 0x0ce0, 0x9186, 0x0014, 0x1dd0, 0x080c,
- 0x97db, 0x0096, 0x6014, 0x2048, 0x080c, 0xce3f, 0x0d60, 0xa867,
- 0x0103, 0xa877, 0x0000, 0xa87b, 0x0006, 0xa880, 0xc0ec, 0xa882,
- 0x08f0, 0x0002, 0xc879, 0xc877, 0xc877, 0xc877, 0xc877, 0xc877,
- 0xc891, 0xc877, 0xc877, 0xc877, 0xc877, 0xc877, 0xc877, 0x080c,
- 0x0dc5, 0x080c, 0x97db, 0x6034, 0x908c, 0xff00, 0x810f, 0x9186,
- 0x0039, 0x0118, 0x9186, 0x0035, 0x1118, 0x2001, 0x1987, 0x0010,
- 0x2001, 0x1988, 0x2004, 0x601a, 0x6003, 0x000c, 0x080c, 0x98e7,
- 0x0005, 0x080c, 0x97db, 0x6034, 0x908c, 0xff00, 0x810f, 0x9186,
- 0x0039, 0x0118, 0x9186, 0x0035, 0x1118, 0x2001, 0x1987, 0x0010,
- 0x2001, 0x1988, 0x2004, 0x601a, 0x6003, 0x000e, 0x080c, 0x98e7,
- 0x0005, 0x9182, 0x0092, 0x1220, 0x9182, 0x0085, 0x0208, 0x0012,
- 0x0804, 0xb181, 0xc8bf, 0xc8bf, 0xc8bf, 0xc8bf, 0xc8c1, 0xc90e,
- 0xc8bf, 0xc8bf, 0xc8bf, 0xc8bf, 0xc8bf, 0xc8bf, 0xc8bf, 0x080c,
- 0x0dc5, 0x0096, 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc,
- 0x0168, 0x6034, 0x908c, 0xff00, 0x810f, 0x9186, 0x0039, 0x0118,
- 0x9186, 0x0035, 0x1118, 0x009e, 0x0804, 0xc922, 0x080c, 0xce3f,
- 0x1118, 0x080c, 0xd02a, 0x0068, 0x6014, 0x2048, 0xa87c, 0xd0e4,
- 0x1110, 0x080c, 0xd02a, 0xa867, 0x0103, 0x080c, 0xd528, 0x080c,
- 0x6dcb, 0x00d6, 0x2c68, 0x080c, 0xb091, 0x01d0, 0x6003, 0x0001,
- 0x6007, 0x001e, 0x600b, 0xffff, 0x2009, 0x026e, 0x210c, 0x613a,
- 0x2009, 0x026f, 0x210c, 0x613e, 0x6910, 0x6112, 0x080c, 0xd2bb,
- 0x6954, 0x6156, 0x6023, 0x0001, 0x080c, 0x9335, 0x080c, 0x98e7,
- 0x2d60, 0x00de, 0x080c, 0xb0e7, 0x009e, 0x0005, 0x6010, 0x00b6,
- 0x2058, 0xb800, 0x00be, 0xd0bc, 0x05a0, 0x6034, 0x908c, 0xff00,
- 0x810f, 0x9186, 0x0035, 0x0130, 0x9186, 0x001e, 0x0118, 0x9186,
- 0x0039, 0x1538, 0x00d6, 0x2c68, 0x080c, 0xd4c0, 0x11f0, 0x080c,
- 0xb091, 0x01d8, 0x6106, 0x6003, 0x0001, 0x6023, 0x0001, 0x6910,
- 0x6112, 0x692c, 0x612e, 0x6930, 0x6132, 0x6934, 0x918c, 0x00ff,
- 0x6136, 0x6938, 0x613a, 0x693c, 0x613e, 0x6954, 0x6156, 0x080c,
- 0xd2bb, 0x080c, 0x9335, 0x080c, 0x98e7, 0x2d60, 0x00de, 0x0804,
- 0xb0e7, 0x0096, 0x6014, 0x2048, 0x080c, 0xce3f, 0x01c8, 0xa867,
- 0x0103, 0xa880, 0xd0b4, 0x0128, 0xc0ec, 0xa882, 0xa87b, 0x0006,
+ 0xa98a, 0x0c68, 0x2950, 0x080c, 0xc9a2, 0x080c, 0x1a83, 0x009e,
+ 0x00ee, 0x00ae, 0x007e, 0x0005, 0x2001, 0x1989, 0x2004, 0x6042,
+ 0x0096, 0x6114, 0x2148, 0xa83c, 0xa940, 0x9105, 0x1118, 0xa87c,
+ 0xc0dc, 0xa87e, 0x6003, 0x0002, 0xa97c, 0xd1e4, 0x0904, 0xc711,
+ 0x6043, 0x0000, 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc,
+ 0x1500, 0xd1cc, 0x0904, 0xc6e0, 0xa978, 0xa868, 0xd0fc, 0x0904,
+ 0xc6a1, 0x0016, 0xa87c, 0x0006, 0xa880, 0x0006, 0x00a6, 0x2150,
+ 0xb174, 0x9184, 0x00ff, 0x90b6, 0x0002, 0x0904, 0xc66e, 0x9086,
+ 0x0028, 0x1904, 0xc65a, 0xa87b, 0x001c, 0xb07b, 0x001c, 0x0804,
+ 0xc676, 0x6024, 0xd0f4, 0x11d0, 0xa838, 0xaa34, 0x9205, 0x09c8,
+ 0xa838, 0xaa90, 0x9206, 0x1120, 0xa88c, 0xaa34, 0x9206, 0x0988,
+ 0x6024, 0xd0d4, 0x1148, 0xa9ac, 0xa834, 0x9102, 0x603a, 0xa9b0,
+ 0xa838, 0x9103, 0x603e, 0x6024, 0xc0f5, 0x6026, 0x6010, 0x00b6,
+ 0x2058, 0xb83c, 0x8000, 0xb83e, 0x00be, 0x9006, 0xa876, 0xa892,
+ 0xa88e, 0xa87c, 0xc0e4, 0xa87e, 0xd0cc, 0x0140, 0xc0cc, 0xa87e,
+ 0x0096, 0xa878, 0x2048, 0x080c, 0x0fc0, 0x009e, 0x080c, 0xd190,
+ 0x0804, 0xc711, 0xd1dc, 0x0158, 0xa87b, 0x0015, 0xb07b, 0x0015,
+ 0x080c, 0xd424, 0x0118, 0xb174, 0xc1dc, 0xb176, 0x0078, 0xd1d4,
+ 0x0128, 0xa87b, 0x0007, 0xb07b, 0x0007, 0x0040, 0xa87c, 0xd0ac,
+ 0x0128, 0xa834, 0xa938, 0x9115, 0x190c, 0xc509, 0xa87c, 0xb07e,
+ 0xa890, 0xb092, 0xa88c, 0xb08e, 0xa860, 0x20e8, 0xa85c, 0x9080,
+ 0x0019, 0x20a0, 0x20a9, 0x0020, 0x8a06, 0x8006, 0x8007, 0x9094,
+ 0x003f, 0x22e0, 0x9084, 0xffc0, 0x9080, 0x0019, 0x2098, 0x4003,
+ 0x00ae, 0x000e, 0xa882, 0x000e, 0xc0cc, 0xa87e, 0x080c, 0xd504,
+ 0x001e, 0xa874, 0x0006, 0x2148, 0x080c, 0x0fc0, 0x001e, 0x0804,
+ 0xc70d, 0x0016, 0x00a6, 0x2150, 0xb174, 0x9184, 0x00ff, 0x90b6,
+ 0x0002, 0x01e0, 0x9086, 0x0028, 0x1128, 0xa87b, 0x001c, 0xb07b,
+ 0x001c, 0x00e0, 0xd1dc, 0x0158, 0xa87b, 0x0015, 0xb07b, 0x0015,
+ 0x080c, 0xd424, 0x0118, 0xb174, 0xc1dc, 0xb176, 0x0078, 0xd1d4,
+ 0x0128, 0xa87b, 0x0007, 0xb07b, 0x0007, 0x0040, 0xa87c, 0xd0ac,
+ 0x0128, 0xa834, 0xa938, 0x9115, 0x190c, 0xc509, 0xa890, 0xb092,
+ 0xa88c, 0xb08e, 0xa87c, 0xb07e, 0x00ae, 0x080c, 0x0fc0, 0x009e,
+ 0x080c, 0xd504, 0xa974, 0x0016, 0x080c, 0xc9f3, 0x001e, 0x0468,
+ 0xa867, 0x0103, 0xa974, 0x9184, 0x00ff, 0x90b6, 0x0002, 0x01b0,
+ 0x9086, 0x0028, 0x1118, 0xa87b, 0x001c, 0x00d0, 0xd1dc, 0x0148,
+ 0xa87b, 0x0015, 0x080c, 0xd424, 0x0118, 0xa974, 0xc1dc, 0xa976,
+ 0x0078, 0xd1d4, 0x0118, 0xa87b, 0x0007, 0x0050, 0xa87b, 0x0000,
+ 0xa87c, 0xd0ac, 0x0128, 0xa834, 0xa938, 0x9115, 0x190c, 0xc509,
+ 0xa974, 0x0016, 0x080c, 0x6beb, 0x001e, 0xd1e4, 0x1120, 0x080c,
+ 0xb101, 0x009e, 0x0005, 0x080c, 0xd156, 0x0cd8, 0x6114, 0x0096,
+ 0x2148, 0xa97c, 0xd1e4, 0x190c, 0x1aa3, 0x009e, 0x0005, 0x080c,
+ 0x97e1, 0x0010, 0x080c, 0x989d, 0x080c, 0xce56, 0x01f0, 0x0096,
+ 0x6114, 0x2148, 0x080c, 0xd05e, 0x1118, 0x080c, 0xbae2, 0x00a0,
+ 0xa867, 0x0103, 0x2009, 0x180c, 0x210c, 0xd18c, 0x11b8, 0xd184,
+ 0x1190, 0x6108, 0xa97a, 0x918e, 0x0029, 0x1110, 0x080c, 0xed00,
+ 0xa877, 0x0000, 0x080c, 0x6dd1, 0x009e, 0x080c, 0xb101, 0x080c,
+ 0x98ed, 0x0804, 0x9a0f, 0xa87b, 0x0004, 0x0c90, 0xa87b, 0x0004,
+ 0x0c78, 0x9182, 0x0054, 0x1220, 0x9182, 0x0040, 0x0208, 0x000a,
+ 0x0005, 0xc76d, 0xc76d, 0xc76d, 0xc76d, 0xc76d, 0xc76f, 0xc76d,
+ 0xc76d, 0xc76d, 0xc76d, 0xc76d, 0xc76d, 0xc76d, 0xc76d, 0xc76d,
+ 0xc76d, 0xc76d, 0xc76d, 0xc76d, 0xc76d, 0x080c, 0x0dc5, 0x080c,
+ 0x57db, 0x01f8, 0x6014, 0x7144, 0x918c, 0x0fff, 0x9016, 0xd1c4,
+ 0x0118, 0x7264, 0x9294, 0x00ff, 0x0096, 0x904d, 0x0188, 0xa87b,
+ 0x0000, 0xa864, 0x9086, 0x0139, 0x0128, 0xa867, 0x0103, 0xa976,
+ 0xaa96, 0x0030, 0xa897, 0x4000, 0xa99a, 0xaa9e, 0x080c, 0x6dd1,
+ 0x009e, 0x0804, 0xb101, 0x9182, 0x0085, 0x0002, 0xc7a5, 0xc7a3,
+ 0xc7a3, 0xc7b1, 0xc7a3, 0xc7a3, 0xc7a3, 0xc7a3, 0xc7a3, 0xc7a3,
+ 0xc7a3, 0xc7a3, 0xc7a3, 0x080c, 0x0dc5, 0x6003, 0x0001, 0x6106,
+ 0x080c, 0x933b, 0x0126, 0x2091, 0x8000, 0x080c, 0x98ed, 0x012e,
+ 0x0005, 0x0026, 0x0056, 0x00d6, 0x00e6, 0x2071, 0x0260, 0x7224,
+ 0x6216, 0x7220, 0x080c, 0xce44, 0x01f8, 0x2268, 0x6800, 0x9086,
+ 0x0000, 0x01d0, 0x6010, 0x6d10, 0x952e, 0x11b0, 0x00c6, 0x2d60,
+ 0x00d6, 0x080c, 0xca64, 0x00de, 0x00ce, 0x0158, 0x702c, 0xd084,
+ 0x1118, 0x080c, 0xca2e, 0x0010, 0x6803, 0x0002, 0x6007, 0x0086,
+ 0x0028, 0x080c, 0xca50, 0x0d90, 0x6007, 0x0087, 0x6003, 0x0001,
+ 0x080c, 0x933b, 0x080c, 0x98ed, 0x7220, 0x080c, 0xce44, 0x0178,
+ 0x6810, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x0140, 0x6824,
+ 0xd0ec, 0x0128, 0x00c6, 0x2d60, 0x080c, 0xd190, 0x00ce, 0x00ee,
+ 0x00de, 0x005e, 0x002e, 0x0005, 0x9186, 0x0013, 0x1160, 0x6004,
+ 0x908a, 0x0085, 0x0a0c, 0x0dc5, 0x908a, 0x0092, 0x1a0c, 0x0dc5,
+ 0x9082, 0x0085, 0x00e2, 0x9186, 0x0027, 0x0120, 0x9186, 0x0014,
+ 0x190c, 0x0dc5, 0x080c, 0x97e1, 0x0096, 0x6014, 0x2048, 0x080c,
+ 0xce56, 0x0140, 0xa867, 0x0103, 0xa877, 0x0000, 0xa87b, 0x0029,
+ 0x080c, 0x6dd1, 0x009e, 0x080c, 0xb134, 0x0804, 0x98ed, 0xc834,
+ 0xc836, 0xc836, 0xc834, 0xc834, 0xc834, 0xc834, 0xc834, 0xc834,
+ 0xc834, 0xc834, 0xc834, 0xc834, 0x080c, 0x0dc5, 0x080c, 0x97e1,
+ 0x080c, 0xb134, 0x080c, 0x98ed, 0x0005, 0x9186, 0x0013, 0x1128,
+ 0x6004, 0x9082, 0x0085, 0x2008, 0x04b8, 0x9186, 0x0027, 0x11f8,
+ 0x080c, 0x97e1, 0x080c, 0x3246, 0x080c, 0xd576, 0x0096, 0x6014,
+ 0x2048, 0x080c, 0xce56, 0x0150, 0xa867, 0x0103, 0xa877, 0x0000,
+ 0xa87b, 0x0029, 0x080c, 0x6dd1, 0x080c, 0xd041, 0x009e, 0x080c,
+ 0xb101, 0x080c, 0x98ed, 0x0005, 0x080c, 0xb19b, 0x0ce0, 0x9186,
+ 0x0014, 0x1dd0, 0x080c, 0x97e1, 0x0096, 0x6014, 0x2048, 0x080c,
+ 0xce56, 0x0d60, 0xa867, 0x0103, 0xa877, 0x0000, 0xa87b, 0x0006,
+ 0xa880, 0xc0ec, 0xa882, 0x08f0, 0x0002, 0xc88c, 0xc88a, 0xc88a,
+ 0xc88a, 0xc88a, 0xc88a, 0xc8a4, 0xc88a, 0xc88a, 0xc88a, 0xc88a,
+ 0xc88a, 0xc88a, 0x080c, 0x0dc5, 0x080c, 0x97e1, 0x6034, 0x908c,
+ 0xff00, 0x810f, 0x9186, 0x0039, 0x0118, 0x9186, 0x0035, 0x1118,
+ 0x2001, 0x1987, 0x0010, 0x2001, 0x1988, 0x2004, 0x601a, 0x6003,
+ 0x000c, 0x080c, 0x98ed, 0x0005, 0x080c, 0x97e1, 0x6034, 0x908c,
+ 0xff00, 0x810f, 0x9186, 0x0039, 0x0118, 0x9186, 0x0035, 0x1118,
+ 0x2001, 0x1987, 0x0010, 0x2001, 0x1988, 0x2004, 0x601a, 0x6003,
+ 0x000e, 0x080c, 0x98ed, 0x0005, 0x9182, 0x0092, 0x1220, 0x9182,
+ 0x0085, 0x0208, 0x0012, 0x0804, 0xb19b, 0xc8d2, 0xc8d2, 0xc8d2,
+ 0xc8d2, 0xc8d4, 0xc921, 0xc8d2, 0xc8d2, 0xc8d2, 0xc8d2, 0xc8d2,
+ 0xc8d2, 0xc8d2, 0x080c, 0x0dc5, 0x0096, 0x6010, 0x00b6, 0x2058,
+ 0xb800, 0x00be, 0xd0bc, 0x0168, 0x6034, 0x908c, 0xff00, 0x810f,
+ 0x9186, 0x0039, 0x0118, 0x9186, 0x0035, 0x1118, 0x009e, 0x0804,
+ 0xc935, 0x080c, 0xce56, 0x1118, 0x080c, 0xd041, 0x0068, 0x6014,
+ 0x2048, 0xa87c, 0xd0e4, 0x1110, 0x080c, 0xd041, 0xa867, 0x0103,
+ 0x080c, 0xd541, 0x080c, 0x6dd1, 0x00d6, 0x2c68, 0x080c, 0xb0ab,
+ 0x01d0, 0x6003, 0x0001, 0x6007, 0x001e, 0x600b, 0xffff, 0x2009,
+ 0x026e, 0x210c, 0x613a, 0x2009, 0x026f, 0x210c, 0x613e, 0x6910,
+ 0x6112, 0x080c, 0xd2d2, 0x6954, 0x6156, 0x6023, 0x0001, 0x080c,
+ 0x933b, 0x080c, 0x98ed, 0x2d60, 0x00de, 0x080c, 0xb101, 0x009e,
+ 0x0005, 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x05a0,
+ 0x6034, 0x908c, 0xff00, 0x810f, 0x9186, 0x0035, 0x0130, 0x9186,
+ 0x001e, 0x0118, 0x9186, 0x0039, 0x1538, 0x00d6, 0x2c68, 0x080c,
+ 0xd4d7, 0x11f0, 0x080c, 0xb0ab, 0x01d8, 0x6106, 0x6003, 0x0001,
+ 0x6023, 0x0001, 0x6910, 0x6112, 0x692c, 0x612e, 0x6930, 0x6132,
+ 0x6934, 0x918c, 0x00ff, 0x6136, 0x6938, 0x613a, 0x693c, 0x613e,
+ 0x6954, 0x6156, 0x080c, 0xd2d2, 0x080c, 0x933b, 0x080c, 0x98ed,
+ 0x2d60, 0x00de, 0x0804, 0xb101, 0x0096, 0x6014, 0x2048, 0x080c,
+ 0xce56, 0x01c8, 0xa867, 0x0103, 0xa880, 0xd0b4, 0x0128, 0xc0ec,
+ 0xa882, 0xa87b, 0x0006, 0x0048, 0xd0bc, 0x0118, 0xa87b, 0x0002,
+ 0x0020, 0xa87b, 0x0005, 0x080c, 0xd152, 0xa877, 0x0000, 0x080c,
+ 0x6dd1, 0x080c, 0xd041, 0x009e, 0x0804, 0xb101, 0x0016, 0x0096,
+ 0x6014, 0x2048, 0x080c, 0xce56, 0x0140, 0xa867, 0x0103, 0xa87b,
+ 0x0028, 0xa877, 0x0000, 0x080c, 0x6dd1, 0x009e, 0x001e, 0x9186,
+ 0x0013, 0x0148, 0x9186, 0x0014, 0x0130, 0x9186, 0x0027, 0x0118,
+ 0x080c, 0xb19b, 0x0030, 0x080c, 0x97e1, 0x080c, 0xb134, 0x080c,
+ 0x98ed, 0x0005, 0x0056, 0x0066, 0x0096, 0x00a6, 0x2029, 0x0001,
+ 0x9182, 0x0101, 0x1208, 0x0010, 0x2009, 0x0100, 0x2130, 0x8304,
+ 0x9098, 0x0018, 0x2009, 0x0020, 0x2011, 0x0029, 0x080c, 0xca03,
+ 0x96b2, 0x0020, 0xb004, 0x904d, 0x0110, 0x080c, 0x0fc0, 0x080c,
+ 0x100e, 0x0520, 0x8528, 0xa867, 0x0110, 0xa86b, 0x0000, 0x2920,
+ 0xb406, 0x968a, 0x003d, 0x1228, 0x2608, 0x2011, 0x001b, 0x0499,
+ 0x00a8, 0x96b2, 0x003c, 0x2009, 0x003c, 0x2950, 0x2011, 0x001b,
+ 0x0451, 0x0c28, 0x2001, 0x0205, 0x2003, 0x0000, 0x00ae, 0x852f,
+ 0x95ad, 0x0003, 0xb566, 0x95ac, 0x0000, 0x0048, 0x2001, 0x0205,
+ 0x2003, 0x0000, 0x00ae, 0x852f, 0x95ad, 0x0003, 0xb566, 0x009e,
+ 0x006e, 0x005e, 0x0005, 0x00a6, 0x89ff, 0x0158, 0xa804, 0x9055,
+ 0x0130, 0xa807, 0x0000, 0x080c, 0x6dd1, 0x2a48, 0x0cb8, 0x080c,
+ 0x6dd1, 0x00ae, 0x0005, 0x00f6, 0x2079, 0x0200, 0x7814, 0x9085,
+ 0x0080, 0x7816, 0xd184, 0x0108, 0x8108, 0x810c, 0x20a9, 0x0001,
+ 0xa860, 0x20e8, 0xa85c, 0x9200, 0x20a0, 0x20e1, 0x0000, 0x2300,
+ 0x9e00, 0x2098, 0x4003, 0x8318, 0x9386, 0x0020, 0x1148, 0x2018,
+ 0x2300, 0x9e00, 0x2098, 0x7814, 0x8000, 0x9085, 0x0080, 0x7816,
+ 0x8109, 0x1d80, 0x7817, 0x0000, 0x00fe, 0x0005, 0x6920, 0x9186,
+ 0x0003, 0x0118, 0x9186, 0x0002, 0x11d0, 0x00c6, 0x00d6, 0x00e6,
+ 0x2d60, 0x0096, 0x6014, 0x2048, 0x080c, 0xce56, 0x0150, 0x2001,
+ 0x0006, 0xa980, 0xc1d5, 0x080c, 0x703d, 0x080c, 0x6dc4, 0x080c,
+ 0xd041, 0x009e, 0x080c, 0xb134, 0x00ee, 0x00de, 0x00ce, 0x0005,
+ 0x00c6, 0x702c, 0xd084, 0x1170, 0x6008, 0x2060, 0x6020, 0x9086,
+ 0x0002, 0x1140, 0x6104, 0x9186, 0x0085, 0x0118, 0x9186, 0x008b,
+ 0x1108, 0x9006, 0x00ce, 0x0005, 0x0066, 0x0126, 0x2091, 0x8000,
+ 0x2031, 0x0001, 0x6020, 0x9084, 0x000f, 0x0083, 0x012e, 0x006e,
+ 0x0005, 0x0126, 0x2091, 0x8000, 0x0066, 0x2031, 0x0000, 0x6020,
+ 0x9084, 0x000f, 0x001b, 0x006e, 0x012e, 0x0005, 0xca9f, 0xca9f,
+ 0xca9a, 0xcac1, 0xca8d, 0xca9a, 0xcac1, 0xca9a, 0xca9a, 0x911f,
+ 0xca9a, 0xca9a, 0xca9a, 0xca8d, 0xca8d, 0x080c, 0x0dc5, 0x0036,
+ 0x2019, 0x0010, 0x080c, 0xe4c8, 0x6023, 0x0006, 0x6003, 0x0007,
+ 0x003e, 0x0005, 0x9006, 0x0005, 0x9085, 0x0001, 0x0005, 0x0096,
+ 0x86ff, 0x11d8, 0x6014, 0x2048, 0x080c, 0xce56, 0x01c0, 0xa864,
+ 0x9086, 0x0139, 0x1128, 0xa87b, 0x0005, 0xa883, 0x0000, 0x0028,
+ 0x900e, 0x2001, 0x0005, 0x080c, 0x703d, 0x080c, 0xd152, 0x080c,
+ 0x6dc4, 0x080c, 0xb134, 0x9085, 0x0001, 0x009e, 0x0005, 0x9006,
+ 0x0ce0, 0x6000, 0x908a, 0x0010, 0x1a0c, 0x0dc5, 0x0002, 0xcad7,
+ 0xcb07, 0xcad9, 0xcb28, 0xcb02, 0xcad7, 0xca9a, 0xca9f, 0xca9f,
+ 0xca9a, 0xca9a, 0xca9a, 0xca9a, 0xca9a, 0xca9a, 0xca9a, 0x080c,
+ 0x0dc5, 0x86ff, 0x1520, 0x6020, 0x9086, 0x0006, 0x0500, 0x0096,
+ 0x6014, 0x2048, 0x080c, 0xce56, 0x0168, 0xa87c, 0xd0cc, 0x0140,
+ 0x0096, 0xc0cc, 0xa87e, 0xa878, 0x2048, 0x080c, 0x0fc0, 0x009e,
+ 0x080c, 0xd152, 0x009e, 0x080c, 0xd51b, 0x6007, 0x0085, 0x6003,
+ 0x000b, 0x6023, 0x0002, 0x080c, 0x933b, 0x080c, 0x98ed, 0x9085,
+ 0x0001, 0x0005, 0x0066, 0x080c, 0x1ab7, 0x006e, 0x0890, 0x00e6,
+ 0x2071, 0x19e9, 0x7024, 0x9c06, 0x1120, 0x080c, 0xa801, 0x00ee,
+ 0x0840, 0x6020, 0x9084, 0x000f, 0x9086, 0x0006, 0x1150, 0x0086,
+ 0x0096, 0x2049, 0x0001, 0x2c40, 0x080c, 0xa929, 0x009e, 0x008e,
+ 0x0010, 0x080c, 0xa6fe, 0x00ee, 0x1904, 0xcad9, 0x0804, 0xca9a,
+ 0x0036, 0x00e6, 0x2071, 0x19e9, 0x703c, 0x9c06, 0x1138, 0x901e,
+ 0x080c, 0xa877, 0x00ee, 0x003e, 0x0804, 0xcad9, 0x080c, 0xaa59,
+ 0x00ee, 0x003e, 0x1904, 0xcad9, 0x0804, 0xca9a, 0x00c6, 0x6020,
+ 0x9084, 0x000f, 0x0013, 0x00ce, 0x0005, 0xcb5b, 0xcc25, 0xcd8f,
+ 0xcb65, 0xb134, 0xcb5b, 0xe4ba, 0xd583, 0xcc25, 0x90f1, 0xce1b,
+ 0xcb54, 0xcb54, 0xcb54, 0xcb54, 0x080c, 0x0dc5, 0x080c, 0xd05e,
+ 0x1110, 0x080c, 0xbae2, 0x0005, 0x080c, 0x97e1, 0x080c, 0x98ed,
+ 0x0804, 0xb101, 0x601b, 0x0001, 0x0005, 0x080c, 0xce56, 0x0130,
+ 0x6014, 0x0096, 0x2048, 0x2c00, 0xa896, 0x009e, 0x6000, 0x908a,
+ 0x0010, 0x1a0c, 0x0dc5, 0x0002, 0xcb84, 0xcb86, 0xcbaa, 0xcbbe,
+ 0xcbe4, 0xcb84, 0xcb5b, 0xcb5b, 0xcb5b, 0xcbbe, 0xcbbe, 0xcb84,
+ 0xcb84, 0xcb84, 0xcb84, 0xcbc8, 0x080c, 0x0dc5, 0x00e6, 0x6014,
+ 0x0096, 0x2048, 0xa880, 0xc0b5, 0xa882, 0x009e, 0x2071, 0x19e9,
+ 0x7024, 0x9c06, 0x01a0, 0x080c, 0xa6fe, 0x080c, 0xd51b, 0x6007,
+ 0x0085, 0x6003, 0x000b, 0x6023, 0x0002, 0x2001, 0x1988, 0x2004,
+ 0x601a, 0x080c, 0x933b, 0x080c, 0x98ed, 0x00ee, 0x0005, 0x601b,
+ 0x0001, 0x0cd8, 0x0096, 0x6014, 0x2048, 0xa880, 0xc0b5, 0xa882,
+ 0x009e, 0x080c, 0xd51b, 0x6007, 0x0085, 0x6003, 0x000b, 0x6023,
+ 0x0002, 0x080c, 0x933b, 0x080c, 0x98ed, 0x0005, 0x0096, 0x601b,
+ 0x0001, 0x6014, 0x2048, 0xa880, 0xc0b5, 0xa882, 0x009e, 0x0005,
+ 0x080c, 0x57db, 0x01b8, 0x6014, 0x0096, 0x904d, 0x0190, 0xa864,
+ 0xa867, 0x0103, 0xa87b, 0x0006, 0x9086, 0x0139, 0x1150, 0xa867,
+ 0x0139, 0xa87b, 0x0030, 0xa897, 0x4005, 0xa89b, 0x0004, 0x080c,
+ 0x6dd1, 0x009e, 0x0804, 0xb101, 0x6014, 0x0096, 0x904d, 0x05c0,
+ 0xa97c, 0xd1e4, 0x05a8, 0x2001, 0x180f, 0x2004, 0xd0c4, 0x0110,
+ 0x009e, 0x0005, 0xa884, 0x009e, 0x8003, 0x800b, 0x810b, 0x9108,
+ 0x611a, 0x2001, 0x0030, 0x2c08, 0x080c, 0x1611, 0x2001, 0x030c,
+ 0x2004, 0x9086, 0x0041, 0x1198, 0x6014, 0x0096, 0x904d, 0x090c,
+ 0x0dc5, 0xa880, 0xd0f4, 0x1130, 0xc0f5, 0xa882, 0x009e, 0x601b,
+ 0x0002, 0x0068, 0x009e, 0x00c6, 0x080c, 0x2397, 0x00ce, 0x6000,
+ 0x9086, 0x0004, 0x1120, 0x2009, 0x0048, 0x080c, 0xb180, 0x0005,
+ 0x009e, 0x080c, 0x1ab7, 0x0804, 0xcbaa, 0x6000, 0x908a, 0x0010,
+ 0x1a0c, 0x0dc5, 0x000b, 0x0005, 0xcc3c, 0xcb62, 0xcc3e, 0xcc3c,
+ 0xcc3e, 0xcc3e, 0xcb5c, 0xcc3c, 0xcb56, 0xcb56, 0xcc3c, 0xcc3c,
+ 0xcc3c, 0xcc3c, 0xcc3c, 0xcc3c, 0x080c, 0x0dc5, 0x6010, 0x00b6,
+ 0x2058, 0xb804, 0x9084, 0x00ff, 0x00be, 0x908a, 0x000c, 0x1a0c,
+ 0x0dc5, 0x00b6, 0x0013, 0x00be, 0x0005, 0xcc59, 0xcd26, 0xcc5b,
+ 0xcc9b, 0xcc5b, 0xcc9b, 0xcc5b, 0xcc69, 0xcc59, 0xcc9b, 0xcc59,
+ 0xcc8a, 0x080c, 0x0dc5, 0x6004, 0x908e, 0x0016, 0x05c0, 0x908e,
+ 0x0004, 0x05a8, 0x908e, 0x0002, 0x0590, 0x908e, 0x0052, 0x0904,
+ 0xcd22, 0x6004, 0x080c, 0xd05e, 0x0904, 0xcd3f, 0x908e, 0x0004,
+ 0x1110, 0x080c, 0x326f, 0x908e, 0x0021, 0x0904, 0xcd43, 0x908e,
+ 0x0022, 0x0904, 0xcd8a, 0x908e, 0x003d, 0x0904, 0xcd43, 0x908e,
+ 0x0039, 0x0904, 0xcd47, 0x908e, 0x0035, 0x0904, 0xcd47, 0x908e,
+ 0x001e, 0x0178, 0x908e, 0x0001, 0x1140, 0x6010, 0x2058, 0xb804,
+ 0x9084, 0x00ff, 0x9086, 0x0006, 0x0110, 0x080c, 0x3246, 0x080c,
+ 0xbae2, 0x0804, 0xb134, 0x00c6, 0x00d6, 0x6104, 0x9186, 0x0016,
+ 0x0904, 0xcd13, 0x9186, 0x0002, 0x1904, 0xcce8, 0x2001, 0x1837,
+ 0x2004, 0xd08c, 0x11c8, 0x080c, 0x7569, 0x11b0, 0x080c, 0xd561,
+ 0x0138, 0x080c, 0x758c, 0x1120, 0x080c, 0x7473, 0x0804, 0xcd73,
+ 0x2001, 0x197e, 0x2003, 0x0001, 0x2001, 0x1800, 0x2003, 0x0001,
+ 0x080c, 0x7495, 0x0804, 0xcd73, 0x6010, 0x2058, 0x2001, 0x1837,
+ 0x2004, 0xd0ac, 0x1904, 0xcd73, 0xb8a0, 0x9084, 0xff80, 0x1904,
+ 0xcd73, 0xb840, 0x9084, 0x00ff, 0x9005, 0x0190, 0x8001, 0xb842,
+ 0x6017, 0x0000, 0x6023, 0x0007, 0x601b, 0x0398, 0x6043, 0x0000,
+ 0x080c, 0xb0ab, 0x0128, 0x2b00, 0x6012, 0x6023, 0x0001, 0x0458,
+ 0x00de, 0x00ce, 0x6004, 0x908e, 0x0002, 0x11a0, 0x6010, 0x2058,
+ 0xb8a0, 0x9086, 0x007e, 0x1170, 0x2009, 0x1837, 0x2104, 0xc085,
+ 0x200a, 0x00e6, 0x2071, 0x1800, 0x080c, 0x60ba, 0x00ee, 0x080c,
+ 0xbae2, 0x0030, 0x080c, 0xbae2, 0x080c, 0x3246, 0x080c, 0xd576,
+ 0x00e6, 0x0126, 0x2091, 0x8000, 0x080c, 0x326f, 0x012e, 0x00ee,
+ 0x080c, 0xb134, 0x0005, 0x2001, 0x0002, 0x080c, 0x6663, 0x6003,
+ 0x0001, 0x6007, 0x0002, 0x080c, 0x9383, 0x080c, 0x98ed, 0x00de,
+ 0x00ce, 0x0c80, 0x080c, 0x326f, 0x0804, 0xcc97, 0x00c6, 0x00d6,
+ 0x6104, 0x9186, 0x0016, 0x0d38, 0x6010, 0x2058, 0xb840, 0x9084,
+ 0x00ff, 0x9005, 0x0904, 0xcce8, 0x8001, 0xb842, 0x6003, 0x0001,
+ 0x080c, 0x9383, 0x080c, 0x98ed, 0x00de, 0x00ce, 0x0898, 0x080c,
+ 0xbae2, 0x0804, 0xcc99, 0x080c, 0xbb1e, 0x0804, 0xcc99, 0x00d6,
+ 0x2c68, 0x6104, 0x080c, 0xd4d7, 0x00de, 0x0118, 0x080c, 0xb101,
+ 0x0408, 0x6004, 0x8007, 0x6134, 0x918c, 0x00ff, 0x9105, 0x6036,
+ 0x6007, 0x0085, 0x6003, 0x000b, 0x6023, 0x0002, 0x603c, 0x600a,
+ 0x2001, 0x1988, 0x2004, 0x601a, 0x602c, 0x2c08, 0x2060, 0x6024,
+ 0xd0b4, 0x0108, 0xc085, 0xc0b5, 0x6026, 0x2160, 0x080c, 0x933b,
+ 0x080c, 0x98ed, 0x0005, 0x00de, 0x00ce, 0x080c, 0xbae2, 0x080c,
+ 0x3246, 0x00e6, 0x0126, 0x2091, 0x8000, 0x080c, 0x326f, 0x6017,
+ 0x0000, 0x6023, 0x0007, 0x601b, 0x0398, 0x6043, 0x0000, 0x012e,
+ 0x00ee, 0x0005, 0x080c, 0xb536, 0x1904, 0xcd3f, 0x0005, 0x6000,
+ 0x908a, 0x0010, 0x1a0c, 0x0dc5, 0x0096, 0x00d6, 0x001b, 0x00de,
+ 0x009e, 0x0005, 0xcdaa, 0xcdaa, 0xcdaa, 0xcdaa, 0xcdaa, 0xcdaa,
+ 0xcdaa, 0xcdaa, 0xcdaa, 0xcb5b, 0xcdaa, 0xcb62, 0xcdac, 0xcb62,
+ 0xcdc6, 0xcdaa, 0x080c, 0x0dc5, 0x6004, 0x9086, 0x008b, 0x01b0,
+ 0x6034, 0x908c, 0xff00, 0x810f, 0x9186, 0x0035, 0x1130, 0x602c,
+ 0x9080, 0x0009, 0x200c, 0xc185, 0x2102, 0x6007, 0x008b, 0x6003,
+ 0x000d, 0x080c, 0x933b, 0x080c, 0x98ed, 0x0005, 0x080c, 0xd555,
+ 0x0118, 0x080c, 0xd568, 0x0010, 0x080c, 0xd576, 0x080c, 0xd041,
+ 0x080c, 0xce56, 0x0570, 0x080c, 0x3246, 0x080c, 0xce56, 0x0168,
+ 0x6014, 0x2048, 0xa867, 0x0103, 0xa87b, 0x0006, 0xa877, 0x0000,
+ 0xa880, 0xc0ed, 0xa882, 0x080c, 0x6dd1, 0x2c68, 0x080c, 0xb0ab,
+ 0x0150, 0x6810, 0x6012, 0x080c, 0xd2d2, 0x00c6, 0x2d60, 0x080c,
+ 0xb134, 0x00ce, 0x0008, 0x2d60, 0x6017, 0x0000, 0x6023, 0x0001,
+ 0x6007, 0x0001, 0x6003, 0x0001, 0x080c, 0x9383, 0x080c, 0x98ed,
+ 0x00c8, 0x080c, 0xd555, 0x0138, 0x6034, 0x9086, 0x4000, 0x1118,
+ 0x080c, 0x3246, 0x08d0, 0x6034, 0x908c, 0xff00, 0x810f, 0x9186,
+ 0x0039, 0x0118, 0x9186, 0x0035, 0x1118, 0x080c, 0x3246, 0x0868,
+ 0x080c, 0xb134, 0x0005, 0x6000, 0x908a, 0x0010, 0x1a0c, 0x0dc5,
+ 0x0002, 0xce31, 0xce31, 0xce35, 0xce33, 0xce3f, 0xce31, 0xce31,
+ 0xb134, 0xce31, 0xce31, 0xce31, 0xce31, 0xce31, 0xce31, 0xce31,
+ 0xce31, 0x080c, 0x0dc5, 0x080c, 0xaa59, 0x6114, 0x0096, 0x2148,
+ 0xa87b, 0x0006, 0x080c, 0x6dd1, 0x009e, 0x0804, 0xb101, 0x601c,
+ 0xd084, 0x190c, 0x1ab7, 0x0c88, 0x9284, 0x0007, 0x1158, 0x9282,
+ 0x1cd0, 0x0240, 0x2001, 0x181a, 0x2004, 0x9202, 0x1218, 0x9085,
+ 0x0001, 0x0005, 0x9006, 0x0ce8, 0x0096, 0x0028, 0x0096, 0x0006,
+ 0x6014, 0x2048, 0x000e, 0x0006, 0x9984, 0xf000, 0x9086, 0xf000,
+ 0x0110, 0x080c, 0x10b9, 0x000e, 0x009e, 0x0005, 0x00e6, 0x00c6,
+ 0x0036, 0x0006, 0x0126, 0x2091, 0x8000, 0x2061, 0x1cd0, 0x2071,
+ 0x1800, 0x7354, 0x7074, 0x9302, 0x1640, 0x6020, 0x9206, 0x11f8,
+ 0x080c, 0xd561, 0x0180, 0x9286, 0x0001, 0x1168, 0x6004, 0x9086,
+ 0x0004, 0x1148, 0x080c, 0x3246, 0x080c, 0xd576, 0x00c6, 0x080c,
+ 0xb134, 0x00ce, 0x0060, 0x080c, 0xd24c, 0x0148, 0x080c, 0xd05e,
+ 0x1110, 0x080c, 0xbae2, 0x00c6, 0x080c, 0xb101, 0x00ce, 0x9ce0,
+ 0x0018, 0x7068, 0x9c02, 0x1208, 0x08a0, 0x012e, 0x000e, 0x003e,
+ 0x00ce, 0x00ee, 0x0005, 0x00e6, 0x00c6, 0x0016, 0x9188, 0x1000,
+ 0x210c, 0x81ff, 0x0128, 0x2061, 0x1ab8, 0x6112, 0x080c, 0x3246,
+ 0x9006, 0x0010, 0x9085, 0x0001, 0x001e, 0x00ce, 0x00ee, 0x0005,
+ 0x00c6, 0x0126, 0x2091, 0x8000, 0x080c, 0xb0ab, 0x01b0, 0x6656,
+ 0x2b00, 0x6012, 0x080c, 0x57db, 0x0118, 0x080c, 0xcf85, 0x0168,
+ 0x080c, 0xd2d2, 0x6023, 0x0003, 0x2009, 0x004b, 0x080c, 0xb180,
+ 0x9085, 0x0001, 0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd8, 0x00c6,
+ 0x0126, 0x2091, 0x8000, 0xbaa0, 0x080c, 0xb153, 0x0560, 0x6057,
+ 0x0000, 0x2b00, 0x6012, 0x080c, 0xd2d2, 0x6023, 0x0003, 0x0016,
+ 0x080c, 0x94e0, 0x0076, 0x903e, 0x080c, 0x93b3, 0x2c08, 0x080c,
+ 0xe690, 0x007e, 0x001e, 0xd184, 0x0128, 0x080c, 0xb101, 0x9085,
+ 0x0001, 0x0070, 0x080c, 0x57db, 0x0128, 0xd18c, 0x1170, 0x080c,
+ 0xcf85, 0x0148, 0x2009, 0x004c, 0x080c, 0xb180, 0x9085, 0x0001,
+ 0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd8, 0x2900, 0x6016, 0x0c90,
+ 0x2009, 0x004d, 0x0010, 0x2009, 0x004e, 0x00f6, 0x00c6, 0x0046,
+ 0x0016, 0x080c, 0xb0ab, 0x2c78, 0x05a0, 0x7e56, 0x2b00, 0x7812,
+ 0x7823, 0x0003, 0x0016, 0x2021, 0x0005, 0x080c, 0xcf97, 0x001e,
+ 0x9186, 0x004d, 0x0118, 0x9186, 0x004e, 0x0148, 0x2001, 0x1981,
+ 0x200c, 0xd1fc, 0x0168, 0x2f60, 0x080c, 0xb101, 0x00d0, 0x2001,
+ 0x1980, 0x200c, 0xd1fc, 0x0120, 0x2f60, 0x080c, 0xb101, 0x0088,
+ 0x2f60, 0x080c, 0x57db, 0x0138, 0xd18c, 0x1118, 0x04f1, 0x0148,
+ 0x0010, 0x2900, 0x7816, 0x001e, 0x0016, 0x080c, 0xb180, 0x9085,
+ 0x0001, 0x001e, 0x004e, 0x00ce, 0x00fe, 0x0005, 0x00f6, 0x00c6,
+ 0x0046, 0x080c, 0xb0ab, 0x2c78, 0x0508, 0x7e56, 0x2b00, 0x7812,
+ 0x7823, 0x0003, 0x0096, 0x2021, 0x0004, 0x0489, 0x009e, 0x2001,
+ 0x197f, 0x200c, 0xd1fc, 0x0120, 0x2f60, 0x080c, 0xb101, 0x0060,
+ 0x2f60, 0x080c, 0x57db, 0x0120, 0xd18c, 0x1160, 0x0071, 0x0130,
+ 0x2009, 0x0052, 0x080c, 0xb180, 0x9085, 0x0001, 0x004e, 0x00ce,
+ 0x00fe, 0x0005, 0x2900, 0x7816, 0x0c98, 0x00c6, 0x080c, 0x4b89,
+ 0x00ce, 0x1120, 0x080c, 0xb101, 0x9006, 0x0005, 0xa867, 0x0000,
+ 0xa86b, 0x8000, 0x2900, 0x6016, 0x9085, 0x0001, 0x0005, 0x0096,
+ 0x0076, 0x0126, 0x2091, 0x8000, 0x080c, 0x6851, 0x0158, 0x2001,
+ 0xcf9c, 0x0006, 0x900e, 0x2400, 0x080c, 0x703d, 0x080c, 0x6dd1,
+ 0x000e, 0x0807, 0x2418, 0x080c, 0x977b, 0xbaa0, 0x0086, 0x2041,
+ 0x0001, 0x2039, 0x0001, 0x2608, 0x080c, 0x94f8, 0x008e, 0x080c,
+ 0x93b3, 0x2f08, 0x2648, 0x080c, 0xe690, 0xb93c, 0x81ff, 0x090c,
+ 0x95cb, 0x080c, 0x98ed, 0x012e, 0x007e, 0x009e, 0x0005, 0x00c6,
+ 0x0126, 0x2091, 0x8000, 0x080c, 0xb0ab, 0x0190, 0x660a, 0x2b08,
+ 0x6112, 0x080c, 0xd2d2, 0x6023, 0x0001, 0x2900, 0x6016, 0x2009,
+ 0x001f, 0x080c, 0xb180, 0x9085, 0x0001, 0x012e, 0x00ce, 0x0005,
+ 0x9006, 0x0cd8, 0x00c6, 0x0126, 0x2091, 0x8000, 0x080c, 0xb153,
+ 0x01b8, 0x660a, 0x2b08, 0x6112, 0x080c, 0xd2d2, 0x6023, 0x0008,
+ 0x2900, 0x6016, 0x00f6, 0x2c78, 0x080c, 0x1768, 0x00fe, 0x2009,
+ 0x0021, 0x080c, 0xb180, 0x9085, 0x0001, 0x012e, 0x00ce, 0x0005,
+ 0x9006, 0x0cd8, 0x2009, 0x003d, 0x00c6, 0x0126, 0x0016, 0x2091,
+ 0x8000, 0x080c, 0xb0ab, 0x0198, 0x660a, 0x2b08, 0x6112, 0x080c,
+ 0xd2d2, 0x6023, 0x0001, 0x2900, 0x6016, 0x001e, 0x0016, 0x080c,
+ 0xb180, 0x9085, 0x0001, 0x001e, 0x012e, 0x00ce, 0x0005, 0x9006,
+ 0x0cd0, 0x00c6, 0x0126, 0x2091, 0x8000, 0x080c, 0xb153, 0x0188,
+ 0x2b08, 0x6112, 0x080c, 0xd2d2, 0x6023, 0x0001, 0x2900, 0x6016,
+ 0x2009, 0x0000, 0x080c, 0xb180, 0x9085, 0x0001, 0x012e, 0x00ce,
+ 0x0005, 0x9006, 0x0cd8, 0x2009, 0x0044, 0x0830, 0x2009, 0x0049,
+ 0x0818, 0x0026, 0x00b6, 0x6210, 0x2258, 0xba3c, 0x82ff, 0x0110,
+ 0x8211, 0xba3e, 0x00be, 0x002e, 0x0005, 0x0006, 0x0016, 0x6004,
+ 0x908e, 0x0002, 0x0140, 0x908e, 0x0003, 0x0128, 0x908e, 0x0004,
+ 0x0110, 0x9085, 0x0001, 0x001e, 0x000e, 0x0005, 0x0006, 0x0086,
+ 0x0096, 0x6020, 0x9086, 0x0004, 0x01a8, 0x6014, 0x904d, 0x080c,
+ 0xce56, 0x0180, 0xa864, 0x9086, 0x0139, 0x0170, 0x6020, 0x90c6,
+ 0x0003, 0x0140, 0x90c6, 0x0002, 0x0128, 0xa868, 0xd0fc, 0x0110,
+ 0x9006, 0x0010, 0x9085, 0x0001, 0x009e, 0x008e, 0x000e, 0x0005,
+ 0x00c6, 0x0126, 0x2091, 0x8000, 0x080c, 0xb153, 0x0198, 0x2b08,
+ 0x6112, 0x080c, 0xd2d2, 0x6023, 0x0001, 0x2900, 0x6016, 0x080c,
+ 0x3246, 0x2009, 0x0028, 0x080c, 0xb180, 0x9085, 0x0001, 0x012e,
+ 0x00ce, 0x0005, 0x9006, 0x0cd8, 0x9186, 0x0015, 0x11a8, 0x2011,
+ 0x1824, 0x2204, 0x9086, 0x0074, 0x1178, 0x00b6, 0x080c, 0xbd38,
+ 0x00be, 0x080c, 0xbf5d, 0x6003, 0x0001, 0x6007, 0x0029, 0x080c,
+ 0x9383, 0x080c, 0x98ed, 0x0078, 0x6014, 0x0096, 0x2048, 0xa868,
+ 0x009e, 0xd0fc, 0x0148, 0x2001, 0x0001, 0x080c, 0xd498, 0x080c,
+ 0xbae2, 0x080c, 0xb101, 0x0005, 0x0096, 0x6014, 0x904d, 0x090c,
+ 0x0dc5, 0xa87b, 0x0030, 0xa883, 0x0000, 0xa897, 0x4005, 0xa89b,
+ 0x0004, 0xa867, 0x0139, 0x0126, 0x2091, 0x8000, 0x080c, 0x6dd1,
+ 0x012e, 0x009e, 0x080c, 0xb101, 0x0c30, 0x0096, 0x9186, 0x0016,
+ 0x1128, 0x2001, 0x0004, 0x080c, 0x6663, 0x00e8, 0x9186, 0x0015,
+ 0x1510, 0x2011, 0x1824, 0x2204, 0x9086, 0x0014, 0x11e0, 0x6010,
+ 0x00b6, 0x2058, 0x080c, 0x67b8, 0x00be, 0x080c, 0xc033, 0x1198,
+ 0x6010, 0x00b6, 0x2058, 0xb890, 0x00be, 0x9005, 0x0160, 0x2001,
+ 0x0006, 0x080c, 0x6663, 0x6014, 0x2048, 0xa868, 0xd0fc, 0x0170,
+ 0x080c, 0xb50a, 0x0048, 0x6014, 0x2048, 0xa868, 0xd0fc, 0x0528,
+ 0x080c, 0xbae2, 0x080c, 0xb101, 0x009e, 0x0005, 0x6014, 0x6310,
+ 0x2358, 0x904d, 0x090c, 0x0dc5, 0xa87b, 0x0000, 0xa883, 0x0000,
+ 0xa897, 0x4000, 0x900e, 0x080c, 0x693d, 0x1108, 0xc185, 0xb800,
+ 0xd0bc, 0x0108, 0xc18d, 0xa99a, 0x0126, 0x2091, 0x8000, 0x080c,
+ 0x6dd1, 0x012e, 0x080c, 0xb101, 0x08f8, 0x6014, 0x904d, 0x090c,
+ 0x0dc5, 0xa87b, 0x0030, 0xa883, 0x0000, 0xa897, 0x4005, 0xa89b,
+ 0x0004, 0xa867, 0x0139, 0x0126, 0x2091, 0x8000, 0x080c, 0x6dd1,
+ 0x012e, 0x080c, 0xb101, 0x0840, 0xa878, 0x9086, 0x0005, 0x1108,
+ 0x0009, 0x0005, 0xa880, 0xc0ad, 0xa882, 0x0005, 0x6043, 0x0000,
+ 0x6017, 0x0000, 0x6003, 0x0001, 0x6007, 0x0050, 0x080c, 0x933b,
+ 0x080c, 0x98ed, 0x0005, 0x00c6, 0x6010, 0x00b6, 0x2058, 0xb800,
+ 0x00be, 0xd0bc, 0x0120, 0x6020, 0x9084, 0x000f, 0x0013, 0x00ce,
+ 0x0005, 0xcb5b, 0xd182, 0xd182, 0xd185, 0xe9f4, 0xea0f, 0xea12,
+ 0xcb5b, 0xcb5b, 0xcb5b, 0xcb5b, 0xcb5b, 0xcb5b, 0xcb5b, 0xcb5b,
+ 0x080c, 0x0dc5, 0xa001, 0xa001, 0x0005, 0x0096, 0x6014, 0x904d,
+ 0x0118, 0xa87c, 0xd0e4, 0x1110, 0x009e, 0x0010, 0x009e, 0x0005,
+ 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x0550, 0x2001,
+ 0x1834, 0x2004, 0x9005, 0x1540, 0x00f6, 0x2c78, 0x080c, 0xb0ab,
+ 0x0508, 0x7810, 0x6012, 0x080c, 0xd2d2, 0x7820, 0x9086, 0x0003,
+ 0x0128, 0x7808, 0x603a, 0x2f00, 0x603e, 0x0020, 0x7808, 0x603e,
+ 0x2f00, 0x603a, 0x602e, 0x6023, 0x0001, 0x6007, 0x0035, 0x6003,
+ 0x0001, 0x7954, 0x6156, 0x080c, 0x933b, 0x080c, 0x98ed, 0x2f60,
+ 0x00fe, 0x0005, 0x2f60, 0x00fe, 0x2001, 0x1989, 0x2004, 0x6042,
+ 0x0005, 0x0016, 0x0096, 0x6814, 0x2048, 0xa87c, 0xd0e4, 0x0180,
+ 0xc0e4, 0xa87e, 0xa877, 0x0000, 0xa893, 0x0000, 0xa88f, 0x0000,
+ 0xd0cc, 0x0130, 0xc0cc, 0xa87e, 0xa878, 0x2048, 0x080c, 0x0fc0,
+ 0x6830, 0x6036, 0x908e, 0x0001, 0x0148, 0x6803, 0x0002, 0x9086,
+ 0x0005, 0x0170, 0x9006, 0x602e, 0x6032, 0x00d0, 0x681c, 0xc085,
+ 0x681e, 0x6803, 0x0004, 0x6824, 0xc0f4, 0x9085, 0x0c00, 0x6826,
+ 0x6814, 0x2048, 0xa8ac, 0x6938, 0x9102, 0xa8b0, 0x693c, 0x9103,
+ 0x1e48, 0x683c, 0x602e, 0x6838, 0x9084, 0xfffc, 0x683a, 0x6032,
+ 0x2d00, 0x603a, 0x6808, 0x603e, 0x6910, 0x6112, 0x6954, 0x6156,
+ 0x6023, 0x0001, 0x6007, 0x0039, 0x6003, 0x0001, 0x080c, 0x933b,
+ 0x080c, 0x98ed, 0x009e, 0x001e, 0x0005, 0x6024, 0xd0d4, 0x0510,
+ 0xd0f4, 0x11f8, 0x6038, 0x940a, 0x603c, 0x9303, 0x0230, 0x9105,
+ 0x0120, 0x6024, 0xc0d4, 0xc0f5, 0x0098, 0x643a, 0x633e, 0xac3e,
+ 0xab42, 0x0046, 0x0036, 0x2400, 0xacac, 0x9402, 0xa836, 0x2300,
+ 0xabb0, 0x9303, 0xa83a, 0x003e, 0x004e, 0x6024, 0xc0d4, 0x0000,
+ 0x6026, 0x0005, 0xd0f4, 0x1138, 0xa83c, 0x603a, 0xa840, 0x603e,
+ 0x6024, 0xc0f5, 0x6026, 0x0005, 0x0006, 0x0016, 0x6004, 0x908e,
+ 0x0034, 0x01b8, 0x908e, 0x0035, 0x01a0, 0x908e, 0x0036, 0x0188,
+ 0x908e, 0x0037, 0x0170, 0x908e, 0x0038, 0x0158, 0x908e, 0x0039,
+ 0x0140, 0x908e, 0x003a, 0x0128, 0x908e, 0x003b, 0x0110, 0x9085,
+ 0x0001, 0x001e, 0x000e, 0x0005, 0x0006, 0x0016, 0x0026, 0x0036,
+ 0x00e6, 0x2001, 0x1983, 0x200c, 0x8000, 0x2014, 0x2001, 0x0032,
+ 0x080c, 0x91b1, 0x2001, 0x1987, 0x82ff, 0x1110, 0x2011, 0x0014,
+ 0x2202, 0x2001, 0x1985, 0x200c, 0x8000, 0x2014, 0x2071, 0x196d,
+ 0x711a, 0x721e, 0x2001, 0x0064, 0x080c, 0x91b1, 0x2001, 0x1988,
+ 0x82ff, 0x1110, 0x2011, 0x0014, 0x2202, 0x2001, 0x1989, 0x9288,
+ 0x000a, 0x2102, 0x2001, 0x1a99, 0x2102, 0x2001, 0x0032, 0x080c,
+ 0x1611, 0x080c, 0x6a73, 0x00ee, 0x003e, 0x002e, 0x001e, 0x000e,
+ 0x0005, 0x0006, 0x0016, 0x00e6, 0x2001, 0x1987, 0x2003, 0x0028,
+ 0x2001, 0x1988, 0x2003, 0x0014, 0x2071, 0x196d, 0x701b, 0x0000,
+ 0x701f, 0x07d0, 0x2001, 0x1989, 0x2009, 0x001e, 0x2102, 0x2001,
+ 0x1a99, 0x2102, 0x2001, 0x0032, 0x080c, 0x1611, 0x00ee, 0x001e,
+ 0x000e, 0x0005, 0x0096, 0x6058, 0x904d, 0x0110, 0x080c, 0x1040,
+ 0x009e, 0x0005, 0x0005, 0x00c6, 0x0126, 0x2091, 0x8000, 0x080c,
+ 0xb0ab, 0x0180, 0x2b08, 0x6112, 0x0ca9, 0x6023, 0x0001, 0x2900,
+ 0x6016, 0x2009, 0x0033, 0x080c, 0xb180, 0x9085, 0x0001, 0x012e,
+ 0x00ce, 0x0005, 0x9006, 0x0cd8, 0x0096, 0x00e6, 0x00f6, 0x2071,
+ 0x1800, 0x9186, 0x0015, 0x1520, 0x7090, 0x9086, 0x0018, 0x0120,
+ 0x7090, 0x9086, 0x0014, 0x11e0, 0x6014, 0x2048, 0xaa3c, 0xd2e4,
+ 0x1160, 0x2c78, 0x080c, 0x9b88, 0x01d8, 0x707c, 0xaa50, 0x9206,
+ 0x1160, 0x7080, 0xaa54, 0x9206, 0x1140, 0x6210, 0x00b6, 0x2258,
+ 0xbaa0, 0x00be, 0x900e, 0x080c, 0x328f, 0x080c, 0xb50a, 0x0020,
+ 0x080c, 0xbae2, 0x080c, 0xb101, 0x00fe, 0x00ee, 0x009e, 0x0005,
+ 0x7060, 0xaa54, 0x9206, 0x0d48, 0x0c80, 0x00c6, 0x0126, 0x2091,
+ 0x8000, 0x080c, 0xb0ab, 0x0188, 0x2b08, 0x6112, 0x080c, 0xd2d2,
+ 0x6023, 0x0001, 0x2900, 0x6016, 0x2009, 0x004d, 0x080c, 0xb180,
+ 0x9085, 0x0001, 0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd8, 0x00c6,
+ 0x0126, 0x2091, 0x8000, 0x0016, 0x080c, 0xb0ab, 0x0180, 0x2b08,
+ 0x6112, 0x080c, 0xd2d2, 0x6023, 0x0001, 0x2900, 0x6016, 0x001e,
+ 0x080c, 0xb180, 0x9085, 0x0001, 0x012e, 0x00ce, 0x0005, 0x001e,
+ 0x9006, 0x0cd0, 0x0016, 0x0026, 0x0036, 0x0046, 0x0056, 0x0066,
+ 0x0096, 0x00e6, 0x00f6, 0x2071, 0x1800, 0x9186, 0x0015, 0x1568,
+ 0x7190, 0x6014, 0x2048, 0xa814, 0x8003, 0x9106, 0x1530, 0x20e1,
+ 0x0000, 0x2001, 0x19a2, 0x2003, 0x0000, 0x6014, 0x2048, 0xa830,
+ 0x20a8, 0x8906, 0x8006, 0x8007, 0x9094, 0x003f, 0x22e8, 0x9084,
+ 0xffc0, 0x9080, 0x001b, 0x20a0, 0x2001, 0x19a2, 0x0016, 0x200c,
+ 0x080c, 0xdbac, 0x001e, 0xa804, 0x9005, 0x0110, 0x2048, 0x0c38,
+ 0x6014, 0x2048, 0xa867, 0x0103, 0x0010, 0x080c, 0xbae2, 0x080c,
+ 0xb101, 0x00fe, 0x00ee, 0x009e, 0x006e, 0x005e, 0x004e, 0x003e,
+ 0x002e, 0x001e, 0x0005, 0x0096, 0x00e6, 0x00f6, 0x2071, 0x1800,
+ 0x9186, 0x0015, 0x11b8, 0x7090, 0x9086, 0x0004, 0x1198, 0x6014,
+ 0x2048, 0x2c78, 0x080c, 0x9b88, 0x01a8, 0x707c, 0xaa74, 0x9206,
+ 0x1130, 0x7080, 0xaa78, 0x9206, 0x1110, 0x080c, 0x3246, 0x080c,
+ 0xb50a, 0x0020, 0x080c, 0xbae2, 0x080c, 0xb101, 0x00fe, 0x00ee,
+ 0x009e, 0x0005, 0x7060, 0xaa78, 0x9206, 0x0d78, 0x0c80, 0x0096,
+ 0x00e6, 0x00f6, 0x2071, 0x1800, 0x9186, 0x0015, 0x1550, 0x7090,
+ 0x9086, 0x0004, 0x1530, 0x6014, 0x2048, 0x2c78, 0x080c, 0x9b88,
+ 0x05f0, 0x707c, 0xaacc, 0x9206, 0x1180, 0x7080, 0xaad0, 0x9206,
+ 0x1160, 0x080c, 0x3246, 0x0016, 0xa998, 0xaab0, 0x9284, 0x1000,
+ 0xc0fd, 0x080c, 0x5782, 0x001e, 0x0010, 0x080c, 0x556d, 0x080c,
+ 0xce56, 0x0508, 0xa87b, 0x0000, 0xa883, 0x0000, 0xa897, 0x4000,
+ 0x0080, 0x080c, 0xce56, 0x01b8, 0x6014, 0x2048, 0x080c, 0x556d,
+ 0x1d70, 0xa87b, 0x0030, 0xa883, 0x0000, 0xa897, 0x4005, 0xa89b,
+ 0x0004, 0x0126, 0x2091, 0x8000, 0xa867, 0x0139, 0x080c, 0x6dd1,
+ 0x012e, 0x080c, 0xb101, 0x00fe, 0x00ee, 0x009e, 0x0005, 0x7060,
+ 0xaad0, 0x9206, 0x0930, 0x0888, 0x0016, 0x0026, 0xa87c, 0xd0ac,
+ 0x0178, 0xa938, 0xaa34, 0x2100, 0x9205, 0x0150, 0xa890, 0x9106,
+ 0x1118, 0xa88c, 0x9206, 0x0120, 0xa992, 0xaa8e, 0x9085, 0x0001,
+ 0x002e, 0x001e, 0x0005, 0x00b6, 0x00d6, 0x0036, 0x080c, 0xce56,
+ 0x0904, 0xd494, 0x0096, 0x6314, 0x2348, 0xa87a, 0xa982, 0x929e,
+ 0x4000, 0x1580, 0x6310, 0x00c6, 0x2358, 0x2009, 0x0000, 0xa868,
+ 0xd0f4, 0x1140, 0x080c, 0x693d, 0x1108, 0xc185, 0xb800, 0xd0bc,
+ 0x0108, 0xc18d, 0xaa96, 0xa99a, 0x20a9, 0x0004, 0xa860, 0x20e8,
+ 0xa85c, 0x9080, 0x0031, 0x20a0, 0xb8c4, 0x20e0, 0xb8c8, 0x9080,
+ 0x0006, 0x2098, 0x080c, 0x0f8b, 0x20a9, 0x0004, 0xa85c, 0x9080,
+ 0x0035, 0x20a0, 0xb8c8, 0x9080, 0x000a, 0x2098, 0x080c, 0x0f8b,
+ 0x00ce, 0x0090, 0xaa96, 0x3918, 0x9398, 0x0007, 0x231c, 0x6004,
+ 0x9086, 0x0016, 0x0110, 0xa89b, 0x0004, 0xaba2, 0x6310, 0x2358,
+ 0xb804, 0x9084, 0x00ff, 0xa89e, 0xa868, 0xc0f4, 0xa86a, 0x080c,
+ 0x6dc4, 0x6017, 0x0000, 0x009e, 0x003e, 0x00de, 0x00be, 0x0005,
+ 0x0026, 0x0036, 0x0046, 0x00b6, 0x0096, 0x00f6, 0x6214, 0x2248,
+ 0x6210, 0x2258, 0x2079, 0x0260, 0x9096, 0x0000, 0x11a0, 0xb814,
+ 0x9084, 0x00ff, 0x900e, 0x080c, 0x2894, 0x2118, 0x831f, 0x939c,
+ 0xff00, 0x7838, 0x9084, 0x00ff, 0x931d, 0x7c3c, 0x2011, 0x8018,
+ 0x080c, 0x4be9, 0x00a8, 0x9096, 0x0001, 0x1148, 0x89ff, 0x0180,
+ 0xa89b, 0x000d, 0x7838, 0xa8a6, 0x783c, 0xa8aa, 0x0048, 0x9096,
+ 0x0002, 0x1130, 0xa89b, 0x000d, 0x7838, 0xa8a6, 0x783c, 0xa8aa,
+ 0x00fe, 0x009e, 0x00be, 0x004e, 0x003e, 0x002e, 0x0005, 0x00c6,
+ 0x0026, 0x0016, 0x9186, 0x0035, 0x0110, 0x6a38, 0x0008, 0x6a2c,
+ 0x080c, 0xce44, 0x01f0, 0x2260, 0x6120, 0x9186, 0x0003, 0x0118,
+ 0x9186, 0x0006, 0x1190, 0x6838, 0x9206, 0x0140, 0x683c, 0x9206,
+ 0x1160, 0x6108, 0x6838, 0x9106, 0x1140, 0x0020, 0x6008, 0x693c,
+ 0x9106, 0x1118, 0x6010, 0x6910, 0x9106, 0x001e, 0x002e, 0x00ce,
+ 0x0005, 0x9085, 0x0001, 0x0cc8, 0xa974, 0xd1cc, 0x0198, 0x918c,
+ 0x00ff, 0x918e, 0x0002, 0x1170, 0xa9a8, 0x918c, 0x000f, 0x918e,
+ 0x0001, 0x1140, 0xa87c, 0xd0ac, 0x0128, 0xa834, 0xa938, 0x9115,
+ 0x190c, 0xc509, 0x0005, 0x0036, 0x2019, 0x0001, 0x0010, 0x0036,
+ 0x901e, 0x0499, 0x01e0, 0x080c, 0xce56, 0x01c8, 0x080c, 0xd041,
+ 0x6037, 0x4000, 0x6014, 0x6017, 0x0000, 0x0096, 0x2048, 0xa87c,
+ 0x080c, 0xd05e, 0x1118, 0x080c, 0xbae2, 0x0040, 0xa867, 0x0103,
+ 0xa877, 0x0000, 0x83ff, 0x1129, 0x080c, 0x6dd1, 0x009e, 0x003e,
+ 0x0005, 0xa880, 0xd0b4, 0x0128, 0xa87b, 0x0006, 0xc0ec, 0xa882,
0x0048, 0xd0bc, 0x0118, 0xa87b, 0x0002, 0x0020, 0xa87b, 0x0005,
- 0x080c, 0xd13b, 0xa877, 0x0000, 0x080c, 0x6dcb, 0x080c, 0xd02a,
- 0x009e, 0x0804, 0xb0e7, 0x0016, 0x0096, 0x6014, 0x2048, 0x080c,
- 0xce3f, 0x0140, 0xa867, 0x0103, 0xa87b, 0x0028, 0xa877, 0x0000,
- 0x080c, 0x6dcb, 0x009e, 0x001e, 0x9186, 0x0013, 0x0148, 0x9186,
- 0x0014, 0x0130, 0x9186, 0x0027, 0x0118, 0x080c, 0xb181, 0x0030,
- 0x080c, 0x97db, 0x080c, 0xb11a, 0x080c, 0x98e7, 0x0005, 0x0056,
- 0x0066, 0x0096, 0x00a6, 0x2029, 0x0001, 0x9182, 0x0101, 0x1208,
- 0x0010, 0x2009, 0x0100, 0x2130, 0x8304, 0x9098, 0x0018, 0x2009,
- 0x0020, 0x2011, 0x0029, 0x080c, 0xc9f0, 0x96b2, 0x0020, 0xb004,
- 0x904d, 0x0110, 0x080c, 0x0fc0, 0x080c, 0x100e, 0x0520, 0x8528,
- 0xa867, 0x0110, 0xa86b, 0x0000, 0x2920, 0xb406, 0x968a, 0x003d,
- 0x1228, 0x2608, 0x2011, 0x001b, 0x0499, 0x00a8, 0x96b2, 0x003c,
- 0x2009, 0x003c, 0x2950, 0x2011, 0x001b, 0x0451, 0x0c28, 0x2001,
- 0x0205, 0x2003, 0x0000, 0x00ae, 0x852f, 0x95ad, 0x0003, 0xb566,
- 0x95ac, 0x0000, 0x0048, 0x2001, 0x0205, 0x2003, 0x0000, 0x00ae,
- 0x852f, 0x95ad, 0x0003, 0xb566, 0x009e, 0x006e, 0x005e, 0x0005,
- 0x00a6, 0x89ff, 0x0158, 0xa804, 0x9055, 0x0130, 0xa807, 0x0000,
- 0x080c, 0x6dcb, 0x2a48, 0x0cb8, 0x080c, 0x6dcb, 0x00ae, 0x0005,
- 0x00f6, 0x2079, 0x0200, 0x7814, 0x9085, 0x0080, 0x7816, 0xd184,
- 0x0108, 0x8108, 0x810c, 0x20a9, 0x0001, 0xa860, 0x20e8, 0xa85c,
- 0x9200, 0x20a0, 0x20e1, 0x0000, 0x2300, 0x9e00, 0x2098, 0x4003,
- 0x8318, 0x9386, 0x0020, 0x1148, 0x2018, 0x2300, 0x9e00, 0x2098,
- 0x7814, 0x8000, 0x9085, 0x0080, 0x7816, 0x8109, 0x1d80, 0x7817,
- 0x0000, 0x00fe, 0x0005, 0x6920, 0x9186, 0x0003, 0x0118, 0x9186,
- 0x0002, 0x11d0, 0x00c6, 0x00d6, 0x00e6, 0x2d60, 0x0096, 0x6014,
- 0x2048, 0x080c, 0xce3f, 0x0150, 0x2001, 0x0006, 0xa980, 0xc1d5,
- 0x080c, 0x7037, 0x080c, 0x6dbe, 0x080c, 0xd02a, 0x009e, 0x080c,
- 0xb11a, 0x00ee, 0x00de, 0x00ce, 0x0005, 0x00c6, 0x702c, 0xd084,
- 0x1170, 0x6008, 0x2060, 0x6020, 0x9086, 0x0002, 0x1140, 0x6104,
- 0x9186, 0x0085, 0x0118, 0x9186, 0x008b, 0x1108, 0x9006, 0x00ce,
- 0x0005, 0x0066, 0x0126, 0x2091, 0x8000, 0x2031, 0x0001, 0x6020,
- 0x9084, 0x000f, 0x0083, 0x012e, 0x006e, 0x0005, 0x0126, 0x2091,
- 0x8000, 0x0066, 0x2031, 0x0000, 0x6020, 0x9084, 0x000f, 0x001b,
- 0x006e, 0x012e, 0x0005, 0xca8c, 0xca8c, 0xca87, 0xcaae, 0xca7a,
- 0xca87, 0xcaae, 0xca87, 0xca7a, 0x9119, 0xca87, 0xca87, 0xca87,
- 0xca7a, 0xca7a, 0x080c, 0x0dc5, 0x0036, 0x2019, 0x0010, 0x080c,
- 0xe4ba, 0x6023, 0x0006, 0x6003, 0x0007, 0x003e, 0x0005, 0x9006,
- 0x0005, 0x9085, 0x0001, 0x0005, 0x0096, 0x86ff, 0x11d8, 0x6014,
- 0x2048, 0x080c, 0xce3f, 0x01c0, 0xa864, 0x9086, 0x0139, 0x1128,
- 0xa87b, 0x0005, 0xa883, 0x0000, 0x0028, 0x900e, 0x2001, 0x0005,
- 0x080c, 0x7037, 0x080c, 0xd13b, 0x080c, 0x6dbe, 0x080c, 0xb11a,
- 0x9085, 0x0001, 0x009e, 0x0005, 0x9006, 0x0ce0, 0x6000, 0x908a,
- 0x0016, 0x1a0c, 0x0dc5, 0x0002, 0xcac4, 0xcaf4, 0xcac6, 0xcb15,
- 0xcaef, 0xcac4, 0xca87, 0xca8c, 0xca8c, 0xca87, 0xca87, 0xca87,
- 0xca87, 0xca87, 0xca87, 0xca87, 0x080c, 0x0dc5, 0x86ff, 0x1520,
- 0x6020, 0x9086, 0x0006, 0x0500, 0x0096, 0x6014, 0x2048, 0x080c,
- 0xce3f, 0x0168, 0xa87c, 0xd0cc, 0x0140, 0x0096, 0xc0cc, 0xa87e,
- 0xa878, 0x2048, 0x080c, 0x0fc0, 0x009e, 0x080c, 0xd13b, 0x009e,
- 0x080c, 0xd502, 0x6007, 0x0085, 0x6003, 0x000b, 0x6023, 0x0002,
- 0x080c, 0x9335, 0x080c, 0x98e7, 0x9085, 0x0001, 0x0005, 0x0066,
- 0x080c, 0x1ab7, 0x006e, 0x0890, 0x00e6, 0x2071, 0x19e9, 0x7024,
- 0x9c06, 0x1120, 0x080c, 0xa7e7, 0x00ee, 0x0840, 0x6020, 0x9084,
- 0x000f, 0x9086, 0x0006, 0x1150, 0x0086, 0x0096, 0x2049, 0x0001,
- 0x2c40, 0x080c, 0xa90f, 0x009e, 0x008e, 0x0010, 0x080c, 0xa6e4,
- 0x00ee, 0x1904, 0xcac6, 0x0804, 0xca87, 0x0036, 0x00e6, 0x2071,
- 0x19e9, 0x703c, 0x9c06, 0x1138, 0x901e, 0x080c, 0xa85d, 0x00ee,
- 0x003e, 0x0804, 0xcac6, 0x080c, 0xaa3f, 0x00ee, 0x003e, 0x1904,
- 0xcac6, 0x0804, 0xca87, 0x00c6, 0x6020, 0x9084, 0x000f, 0x0013,
- 0x00ce, 0x0005, 0xcb48, 0xcc13, 0xcd7d, 0xcb52, 0xb11a, 0xcb48,
- 0xe4ac, 0xd56a, 0xcc13, 0x90eb, 0xce09, 0xcb41, 0xcb41, 0xcb41,
- 0xcb41, 0x080c, 0x0dc5, 0x080c, 0xd047, 0x1110, 0x080c, 0xbacb,
- 0x0005, 0x080c, 0x97db, 0x080c, 0x98e7, 0x0804, 0xb0e7, 0x601b,
- 0x0001, 0x0005, 0x080c, 0xce3f, 0x0130, 0x6014, 0x0096, 0x2048,
- 0x2c00, 0xa896, 0x009e, 0x6000, 0x908a, 0x0016, 0x1a0c, 0x0dc5,
- 0x0002, 0xcb71, 0xcb73, 0xcb97, 0xcbab, 0xcbd1, 0xcb71, 0xcb48,
- 0xcb48, 0xcb48, 0xcbab, 0xcbab, 0xcb71, 0xcb71, 0xcb71, 0xcb71,
- 0xcbb5, 0x080c, 0x0dc5, 0x00e6, 0x6014, 0x0096, 0x2048, 0xa880,
- 0xc0b5, 0xa882, 0x009e, 0x2071, 0x19e9, 0x7024, 0x9c06, 0x01a0,
- 0x080c, 0xa6e4, 0x080c, 0xd502, 0x6007, 0x0085, 0x6003, 0x000b,
- 0x6023, 0x0002, 0x2001, 0x1988, 0x2004, 0x601a, 0x080c, 0x9335,
- 0x080c, 0x98e7, 0x00ee, 0x0005, 0x601b, 0x0001, 0x0cd8, 0x0096,
- 0x6014, 0x2048, 0xa880, 0xc0b5, 0xa882, 0x009e, 0x080c, 0xd502,
- 0x6007, 0x0085, 0x6003, 0x000b, 0x6023, 0x0002, 0x080c, 0x9335,
- 0x080c, 0x98e7, 0x0005, 0x0096, 0x601b, 0x0001, 0x6014, 0x2048,
- 0xa880, 0xc0b5, 0xa882, 0x009e, 0x0005, 0x080c, 0x57d5, 0x01b8,
- 0x6014, 0x0096, 0x904d, 0x0190, 0xa864, 0xa867, 0x0103, 0xa87b,
- 0x0006, 0x9086, 0x0139, 0x1150, 0xa867, 0x0139, 0xa87b, 0x0030,
- 0xa897, 0x4005, 0xa89b, 0x0004, 0x080c, 0x6dcb, 0x009e, 0x0804,
- 0xb0e7, 0x6014, 0x0096, 0x904d, 0x05c8, 0xa97c, 0xd1e4, 0x05b0,
- 0x2001, 0x180f, 0x2004, 0xd0c4, 0x0110, 0x009e, 0x0005, 0xa884,
- 0x009e, 0x8003, 0x800b, 0x810b, 0x9108, 0x611a, 0x2001, 0x0030,
- 0x2c08, 0x080c, 0x1611, 0x2001, 0x030c, 0x2004, 0x9086, 0x0041,
- 0x11a0, 0x6014, 0x0096, 0x904d, 0x090c, 0x0dc5, 0xa880, 0xd0f4,
- 0x1130, 0xc0f5, 0xa882, 0x009e, 0x601b, 0x0002, 0x0070, 0x009e,
- 0x2001, 0x0037, 0x2c08, 0x080c, 0x1611, 0x6000, 0x9086, 0x0004,
- 0x1120, 0x2009, 0x0048, 0x080c, 0xb166, 0x0005, 0x009e, 0x080c,
- 0x1ab7, 0x0804, 0xcb97, 0x6000, 0x908a, 0x0016, 0x1a0c, 0x0dc5,
- 0x000b, 0x0005, 0xcc2a, 0xcb4f, 0xcc2c, 0xcc2a, 0xcc2c, 0xcc2c,
- 0xcb49, 0xcc2a, 0xcb43, 0xcb43, 0xcc2a, 0xcc2a, 0xcc2a, 0xcc2a,
- 0xcc2a, 0xcc2a, 0x080c, 0x0dc5, 0x6010, 0x00b6, 0x2058, 0xb804,
- 0x9084, 0x00ff, 0x00be, 0x908a, 0x000c, 0x1a0c, 0x0dc5, 0x00b6,
- 0x0013, 0x00be, 0x0005, 0xcc47, 0xcd14, 0xcc49, 0xcc89, 0xcc49,
- 0xcc89, 0xcc49, 0xcc57, 0xcc47, 0xcc89, 0xcc47, 0xcc78, 0x080c,
- 0x0dc5, 0x6004, 0x908e, 0x0016, 0x05c0, 0x908e, 0x0004, 0x05a8,
- 0x908e, 0x0002, 0x0590, 0x908e, 0x0052, 0x0904, 0xcd10, 0x6004,
- 0x080c, 0xd047, 0x0904, 0xcd2d, 0x908e, 0x0004, 0x1110, 0x080c,
- 0x3274, 0x908e, 0x0021, 0x0904, 0xcd31, 0x908e, 0x0022, 0x0904,
- 0xcd78, 0x908e, 0x003d, 0x0904, 0xcd31, 0x908e, 0x0039, 0x0904,
- 0xcd35, 0x908e, 0x0035, 0x0904, 0xcd35, 0x908e, 0x001e, 0x0178,
- 0x908e, 0x0001, 0x1140, 0x6010, 0x2058, 0xb804, 0x9084, 0x00ff,
- 0x9086, 0x0006, 0x0110, 0x080c, 0x324b, 0x080c, 0xbacb, 0x0804,
- 0xb11a, 0x00c6, 0x00d6, 0x6104, 0x9186, 0x0016, 0x0904, 0xcd01,
- 0x9186, 0x0002, 0x1904, 0xccd6, 0x2001, 0x1837, 0x2004, 0xd08c,
- 0x11c8, 0x080c, 0x7563, 0x11b0, 0x080c, 0xd548, 0x0138, 0x080c,
- 0x7586, 0x1120, 0x080c, 0x746d, 0x0804, 0xcd61, 0x2001, 0x197e,
- 0x2003, 0x0001, 0x2001, 0x1800, 0x2003, 0x0001, 0x080c, 0x748f,
- 0x0804, 0xcd61, 0x6010, 0x2058, 0x2001, 0x1837, 0x2004, 0xd0ac,
- 0x1904, 0xcd61, 0xb8a0, 0x9084, 0xff80, 0x1904, 0xcd61, 0xb840,
- 0x9084, 0x00ff, 0x9005, 0x0190, 0x8001, 0xb842, 0x6017, 0x0000,
- 0x6023, 0x0007, 0x601b, 0x0398, 0x6043, 0x0000, 0x080c, 0xb091,
- 0x0128, 0x2b00, 0x6012, 0x6023, 0x0001, 0x0458, 0x00de, 0x00ce,
- 0x6004, 0x908e, 0x0002, 0x11a0, 0x6010, 0x2058, 0xb8a0, 0x9086,
- 0x007e, 0x1170, 0x2009, 0x1837, 0x2104, 0xc085, 0x200a, 0x00e6,
- 0x2071, 0x1800, 0x080c, 0x60b4, 0x00ee, 0x080c, 0xbacb, 0x0030,
- 0x080c, 0xbacb, 0x080c, 0x324b, 0x080c, 0xd55d, 0x00e6, 0x0126,
- 0x2091, 0x8000, 0x080c, 0x3274, 0x012e, 0x00ee, 0x080c, 0xb11a,
- 0x0005, 0x2001, 0x0002, 0x080c, 0x665d, 0x6003, 0x0001, 0x6007,
- 0x0002, 0x080c, 0x937d, 0x080c, 0x98e7, 0x00de, 0x00ce, 0x0c80,
- 0x080c, 0x3274, 0x0804, 0xcc85, 0x00c6, 0x00d6, 0x6104, 0x9186,
- 0x0016, 0x0d38, 0x6010, 0x2058, 0xb840, 0x9084, 0x00ff, 0x9005,
- 0x0904, 0xccd6, 0x8001, 0xb842, 0x6003, 0x0001, 0x080c, 0x937d,
- 0x080c, 0x98e7, 0x00de, 0x00ce, 0x0898, 0x080c, 0xbacb, 0x0804,
- 0xcc87, 0x080c, 0xbb07, 0x0804, 0xcc87, 0x00d6, 0x2c68, 0x6104,
- 0x080c, 0xd4c0, 0x00de, 0x0118, 0x080c, 0xb0e7, 0x0408, 0x6004,
- 0x8007, 0x6134, 0x918c, 0x00ff, 0x9105, 0x6036, 0x6007, 0x0085,
- 0x6003, 0x000b, 0x6023, 0x0002, 0x603c, 0x600a, 0x2001, 0x1988,
- 0x2004, 0x601a, 0x602c, 0x2c08, 0x2060, 0x6024, 0xd0b4, 0x0108,
- 0xc085, 0xc0b5, 0x6026, 0x2160, 0x080c, 0x9335, 0x080c, 0x98e7,
- 0x0005, 0x00de, 0x00ce, 0x080c, 0xbacb, 0x080c, 0x324b, 0x00e6,
- 0x0126, 0x2091, 0x8000, 0x080c, 0x3274, 0x6017, 0x0000, 0x6023,
- 0x0007, 0x601b, 0x0398, 0x6043, 0x0000, 0x012e, 0x00ee, 0x0005,
- 0x080c, 0xb51f, 0x1904, 0xcd2d, 0x0005, 0x6000, 0x908a, 0x0016,
- 0x1a0c, 0x0dc5, 0x0096, 0x00d6, 0x001b, 0x00de, 0x009e, 0x0005,
- 0xcd98, 0xcd98, 0xcd98, 0xcd98, 0xcd98, 0xcd98, 0xcd98, 0xcd98,
- 0xcd98, 0xcb48, 0xcd98, 0xcb4f, 0xcd9a, 0xcb4f, 0xcdb4, 0xcd98,
- 0x080c, 0x0dc5, 0x6004, 0x9086, 0x008b, 0x01b0, 0x6034, 0x908c,
- 0xff00, 0x810f, 0x9186, 0x0035, 0x1130, 0x602c, 0x9080, 0x0009,
- 0x200c, 0xc185, 0x2102, 0x6007, 0x008b, 0x6003, 0x000d, 0x080c,
- 0x9335, 0x080c, 0x98e7, 0x0005, 0x080c, 0xd53c, 0x0118, 0x080c,
- 0xd54f, 0x0010, 0x080c, 0xd55d, 0x080c, 0xd02a, 0x080c, 0xce3f,
- 0x0570, 0x080c, 0x324b, 0x080c, 0xce3f, 0x0168, 0x6014, 0x2048,
- 0xa867, 0x0103, 0xa87b, 0x0006, 0xa877, 0x0000, 0xa880, 0xc0ed,
- 0xa882, 0x080c, 0x6dcb, 0x2c68, 0x080c, 0xb091, 0x0150, 0x6810,
- 0x6012, 0x080c, 0xd2bb, 0x00c6, 0x2d60, 0x080c, 0xb11a, 0x00ce,
- 0x0008, 0x2d60, 0x6017, 0x0000, 0x6023, 0x0001, 0x6007, 0x0001,
- 0x6003, 0x0001, 0x080c, 0x937d, 0x080c, 0x98e7, 0x00c8, 0x080c,
- 0xd53c, 0x0138, 0x6034, 0x9086, 0x4000, 0x1118, 0x080c, 0x324b,
- 0x08d0, 0x6034, 0x908c, 0xff00, 0x810f, 0x9186, 0x0039, 0x0118,
- 0x9186, 0x0035, 0x1118, 0x080c, 0x324b, 0x0868, 0x080c, 0xb11a,
- 0x0005, 0x6000, 0x908a, 0x0016, 0x1a0c, 0x0dc5, 0x0002, 0xce1f,
- 0xce1f, 0xce21, 0xce21, 0xce21, 0xce1f, 0xce1f, 0xb11a, 0xce1f,
- 0xce1f, 0xce1f, 0xce1f, 0xce1f, 0xce1f, 0xce1f, 0xce1f, 0x080c,
- 0x0dc5, 0x080c, 0xaa3f, 0x6114, 0x0096, 0x2148, 0xa87b, 0x0006,
- 0x080c, 0x6dcb, 0x009e, 0x0804, 0xb0e7, 0x9284, 0x0007, 0x1158,
- 0x9282, 0x1cd0, 0x0240, 0x2001, 0x181a, 0x2004, 0x9202, 0x1218,
- 0x9085, 0x0001, 0x0005, 0x9006, 0x0ce8, 0x0096, 0x0028, 0x0096,
- 0x0006, 0x6014, 0x2048, 0x000e, 0x0006, 0x9984, 0xf000, 0x9086,
- 0xf000, 0x0110, 0x080c, 0x10b9, 0x000e, 0x009e, 0x0005, 0x00e6,
- 0x00c6, 0x0036, 0x0006, 0x0126, 0x2091, 0x8000, 0x2061, 0x1cd0,
- 0x2071, 0x1800, 0x7354, 0x7074, 0x9302, 0x1640, 0x6020, 0x9206,
- 0x11f8, 0x080c, 0xd548, 0x0180, 0x9286, 0x0001, 0x1168, 0x6004,
- 0x9086, 0x0004, 0x1148, 0x080c, 0x324b, 0x080c, 0xd55d, 0x00c6,
- 0x080c, 0xb11a, 0x00ce, 0x0060, 0x080c, 0xd235, 0x0148, 0x080c,
- 0xd047, 0x1110, 0x080c, 0xbacb, 0x00c6, 0x080c, 0xb0e7, 0x00ce,
- 0x9ce0, 0x0018, 0x7068, 0x9c02, 0x1208, 0x08a0, 0x012e, 0x000e,
- 0x003e, 0x00ce, 0x00ee, 0x0005, 0x00e6, 0x00c6, 0x0016, 0x9188,
- 0x1000, 0x210c, 0x81ff, 0x0128, 0x2061, 0x1ab8, 0x6112, 0x080c,
- 0x324b, 0x9006, 0x0010, 0x9085, 0x0001, 0x001e, 0x00ce, 0x00ee,
- 0x0005, 0x00c6, 0x0126, 0x2091, 0x8000, 0x080c, 0xb091, 0x01b0,
- 0x6656, 0x2b00, 0x6012, 0x080c, 0x57d5, 0x0118, 0x080c, 0xcf6e,
- 0x0168, 0x080c, 0xd2bb, 0x6023, 0x0003, 0x2009, 0x004b, 0x080c,
- 0xb166, 0x9085, 0x0001, 0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd8,
- 0x00c6, 0x0126, 0x2091, 0x8000, 0xbaa0, 0x080c, 0xb139, 0x0560,
- 0x6057, 0x0000, 0x2b00, 0x6012, 0x080c, 0xd2bb, 0x6023, 0x0003,
- 0x0016, 0x080c, 0x94da, 0x0076, 0x903e, 0x080c, 0x93ad, 0x2c08,
- 0x080c, 0xe671, 0x007e, 0x001e, 0xd184, 0x0128, 0x080c, 0xb0e7,
- 0x9085, 0x0001, 0x0070, 0x080c, 0x57d5, 0x0128, 0xd18c, 0x1170,
- 0x080c, 0xcf6e, 0x0148, 0x2009, 0x004c, 0x080c, 0xb166, 0x9085,
- 0x0001, 0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd8, 0x2900, 0x6016,
- 0x0c90, 0x2009, 0x004d, 0x0010, 0x2009, 0x004e, 0x00f6, 0x00c6,
- 0x0046, 0x0016, 0x080c, 0xb091, 0x2c78, 0x05a0, 0x7e56, 0x2b00,
- 0x7812, 0x7823, 0x0003, 0x0016, 0x2021, 0x0005, 0x080c, 0xcf80,
- 0x001e, 0x9186, 0x004d, 0x0118, 0x9186, 0x004e, 0x0148, 0x2001,
- 0x1981, 0x200c, 0xd1fc, 0x0168, 0x2f60, 0x080c, 0xb0e7, 0x00d0,
- 0x2001, 0x1980, 0x200c, 0xd1fc, 0x0120, 0x2f60, 0x080c, 0xb0e7,
- 0x0088, 0x2f60, 0x080c, 0x57d5, 0x0138, 0xd18c, 0x1118, 0x04f1,
- 0x0148, 0x0010, 0x2900, 0x7816, 0x001e, 0x0016, 0x080c, 0xb166,
- 0x9085, 0x0001, 0x001e, 0x004e, 0x00ce, 0x00fe, 0x0005, 0x00f6,
- 0x00c6, 0x0046, 0x080c, 0xb091, 0x2c78, 0x0508, 0x7e56, 0x2b00,
- 0x7812, 0x7823, 0x0003, 0x0096, 0x2021, 0x0004, 0x0489, 0x009e,
- 0x2001, 0x197f, 0x200c, 0xd1fc, 0x0120, 0x2f60, 0x080c, 0xb0e7,
- 0x0060, 0x2f60, 0x080c, 0x57d5, 0x0120, 0xd18c, 0x1160, 0x0071,
- 0x0130, 0x2009, 0x0052, 0x080c, 0xb166, 0x9085, 0x0001, 0x004e,
- 0x00ce, 0x00fe, 0x0005, 0x2900, 0x7816, 0x0c98, 0x00c6, 0x080c,
- 0x4b83, 0x00ce, 0x1120, 0x080c, 0xb0e7, 0x9006, 0x0005, 0xa867,
- 0x0000, 0xa86b, 0x8000, 0x2900, 0x6016, 0x9085, 0x0001, 0x0005,
- 0x0096, 0x0076, 0x0126, 0x2091, 0x8000, 0x080c, 0x684b, 0x0158,
- 0x2001, 0xcf85, 0x0006, 0x900e, 0x2400, 0x080c, 0x7037, 0x080c,
- 0x6dcb, 0x000e, 0x0807, 0x2418, 0x080c, 0x9775, 0xbaa0, 0x0086,
- 0x2041, 0x0001, 0x2039, 0x0001, 0x2608, 0x080c, 0x94f2, 0x008e,
- 0x080c, 0x93ad, 0x2f08, 0x2648, 0x080c, 0xe671, 0xb93c, 0x81ff,
- 0x090c, 0x95c5, 0x080c, 0x98e7, 0x012e, 0x007e, 0x009e, 0x0005,
- 0x00c6, 0x0126, 0x2091, 0x8000, 0x080c, 0xb091, 0x0190, 0x660a,
- 0x2b08, 0x6112, 0x080c, 0xd2bb, 0x6023, 0x0001, 0x2900, 0x6016,
- 0x2009, 0x001f, 0x080c, 0xb166, 0x9085, 0x0001, 0x012e, 0x00ce,
- 0x0005, 0x9006, 0x0cd8, 0x00c6, 0x0126, 0x2091, 0x8000, 0x080c,
- 0xb139, 0x01b8, 0x660a, 0x2b08, 0x6112, 0x080c, 0xd2bb, 0x6023,
- 0x0008, 0x2900, 0x6016, 0x00f6, 0x2c78, 0x080c, 0x1768, 0x00fe,
- 0x2009, 0x0021, 0x080c, 0xb166, 0x9085, 0x0001, 0x012e, 0x00ce,
- 0x0005, 0x9006, 0x0cd8, 0x2009, 0x003d, 0x00c6, 0x0126, 0x0016,
- 0x2091, 0x8000, 0x080c, 0xb091, 0x0198, 0x660a, 0x2b08, 0x6112,
- 0x080c, 0xd2bb, 0x6023, 0x0001, 0x2900, 0x6016, 0x001e, 0x0016,
- 0x080c, 0xb166, 0x9085, 0x0001, 0x001e, 0x012e, 0x00ce, 0x0005,
- 0x9006, 0x0cd0, 0x00c6, 0x0126, 0x2091, 0x8000, 0x080c, 0xb139,
- 0x0188, 0x2b08, 0x6112, 0x080c, 0xd2bb, 0x6023, 0x0001, 0x2900,
- 0x6016, 0x2009, 0x0000, 0x080c, 0xb166, 0x9085, 0x0001, 0x012e,
- 0x00ce, 0x0005, 0x9006, 0x0cd8, 0x2009, 0x0044, 0x0830, 0x2009,
- 0x0049, 0x0818, 0x0026, 0x00b6, 0x6210, 0x2258, 0xba3c, 0x82ff,
- 0x0110, 0x8211, 0xba3e, 0x00be, 0x002e, 0x0005, 0x0006, 0x0016,
- 0x6004, 0x908e, 0x0002, 0x0140, 0x908e, 0x0003, 0x0128, 0x908e,
- 0x0004, 0x0110, 0x9085, 0x0001, 0x001e, 0x000e, 0x0005, 0x0006,
- 0x0086, 0x0096, 0x6020, 0x9086, 0x0004, 0x01a8, 0x6014, 0x904d,
- 0x080c, 0xce3f, 0x0180, 0xa864, 0x9086, 0x0139, 0x0170, 0x6020,
- 0x90c6, 0x0003, 0x0140, 0x90c6, 0x0002, 0x0128, 0xa868, 0xd0fc,
- 0x0110, 0x9006, 0x0010, 0x9085, 0x0001, 0x009e, 0x008e, 0x000e,
- 0x0005, 0x00c6, 0x0126, 0x2091, 0x8000, 0x080c, 0xb139, 0x0198,
- 0x2b08, 0x6112, 0x080c, 0xd2bb, 0x6023, 0x0001, 0x2900, 0x6016,
- 0x080c, 0x324b, 0x2009, 0x0028, 0x080c, 0xb166, 0x9085, 0x0001,
- 0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd8, 0x9186, 0x0015, 0x11a8,
- 0x2011, 0x1824, 0x2204, 0x9086, 0x0074, 0x1178, 0x00b6, 0x080c,
- 0xbd2d, 0x00be, 0x080c, 0xbf52, 0x6003, 0x0001, 0x6007, 0x0029,
- 0x080c, 0x937d, 0x080c, 0x98e7, 0x0078, 0x6014, 0x0096, 0x2048,
- 0xa868, 0x009e, 0xd0fc, 0x0148, 0x2001, 0x0001, 0x080c, 0xd481,
- 0x080c, 0xbacb, 0x080c, 0xb0e7, 0x0005, 0x0096, 0x6014, 0x904d,
- 0x090c, 0x0dc5, 0xa87b, 0x0030, 0xa883, 0x0000, 0xa897, 0x4005,
- 0xa89b, 0x0004, 0xa867, 0x0139, 0x0126, 0x2091, 0x8000, 0x080c,
- 0x6dcb, 0x012e, 0x009e, 0x080c, 0xb0e7, 0x0c30, 0x0096, 0x9186,
- 0x0016, 0x1128, 0x2001, 0x0004, 0x080c, 0x665d, 0x00e8, 0x9186,
- 0x0015, 0x1510, 0x2011, 0x1824, 0x2204, 0x9086, 0x0014, 0x11e0,
- 0x6010, 0x00b6, 0x2058, 0x080c, 0x67b2, 0x00be, 0x080c, 0xc023,
- 0x1198, 0x6010, 0x00b6, 0x2058, 0xb890, 0x00be, 0x9005, 0x0160,
- 0x2001, 0x0006, 0x080c, 0x665d, 0x6014, 0x2048, 0xa868, 0xd0fc,
- 0x0170, 0x080c, 0xb4f3, 0x0048, 0x6014, 0x2048, 0xa868, 0xd0fc,
- 0x0528, 0x080c, 0xbacb, 0x080c, 0xb0e7, 0x009e, 0x0005, 0x6014,
- 0x6310, 0x2358, 0x904d, 0x090c, 0x0dc5, 0xa87b, 0x0000, 0xa883,
- 0x0000, 0xa897, 0x4000, 0x900e, 0x080c, 0x6937, 0x1108, 0xc185,
- 0xb800, 0xd0bc, 0x0108, 0xc18d, 0xa99a, 0x0126, 0x2091, 0x8000,
- 0x080c, 0x6dcb, 0x012e, 0x080c, 0xb0e7, 0x08f8, 0x6014, 0x904d,
- 0x090c, 0x0dc5, 0xa87b, 0x0030, 0xa883, 0x0000, 0xa897, 0x4005,
- 0xa89b, 0x0004, 0xa867, 0x0139, 0x0126, 0x2091, 0x8000, 0x080c,
- 0x6dcb, 0x012e, 0x080c, 0xb0e7, 0x0840, 0xa878, 0x9086, 0x0005,
- 0x1108, 0x0009, 0x0005, 0xa880, 0xc0ad, 0xa882, 0x0005, 0x6043,
- 0x0000, 0x6017, 0x0000, 0x6003, 0x0001, 0x6007, 0x0050, 0x080c,
- 0x9335, 0x080c, 0x98e7, 0x0005, 0x00c6, 0x6010, 0x00b6, 0x2058,
- 0xb800, 0x00be, 0xd0bc, 0x0120, 0x6020, 0x9084, 0x000f, 0x0013,
- 0x00ce, 0x0005, 0xcb48, 0xd16b, 0xd16b, 0xd16e, 0xe98f, 0xe9aa,
- 0xe9ad, 0xcb48, 0xcb48, 0xcb48, 0xcb48, 0xcb48, 0xcb48, 0xcb48,
- 0xcb48, 0x080c, 0x0dc5, 0xa001, 0xa001, 0x0005, 0x0096, 0x6014,
- 0x904d, 0x0118, 0xa87c, 0xd0e4, 0x1110, 0x009e, 0x0010, 0x009e,
- 0x0005, 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x0550,
- 0x2001, 0x1834, 0x2004, 0x9005, 0x1540, 0x00f6, 0x2c78, 0x080c,
- 0xb091, 0x0508, 0x7810, 0x6012, 0x080c, 0xd2bb, 0x7820, 0x9086,
- 0x0003, 0x0128, 0x7808, 0x603a, 0x2f00, 0x603e, 0x0020, 0x7808,
- 0x603e, 0x2f00, 0x603a, 0x602e, 0x6023, 0x0001, 0x6007, 0x0035,
- 0x6003, 0x0001, 0x7954, 0x6156, 0x080c, 0x9335, 0x080c, 0x98e7,
- 0x2f60, 0x00fe, 0x0005, 0x2f60, 0x00fe, 0x2001, 0x1989, 0x2004,
- 0x6042, 0x0005, 0x0016, 0x0096, 0x6814, 0x2048, 0xa87c, 0xd0e4,
- 0x0180, 0xc0e4, 0xa87e, 0xa877, 0x0000, 0xa893, 0x0000, 0xa88f,
- 0x0000, 0xd0cc, 0x0130, 0xc0cc, 0xa87e, 0xa878, 0x2048, 0x080c,
- 0x0fc0, 0x6830, 0x6036, 0x908e, 0x0001, 0x0148, 0x6803, 0x0002,
- 0x9086, 0x0005, 0x0170, 0x9006, 0x602e, 0x6032, 0x00d0, 0x681c,
- 0xc085, 0x681e, 0x6803, 0x0004, 0x6824, 0xc0f4, 0x9085, 0x0c00,
- 0x6826, 0x6814, 0x2048, 0xa8ac, 0x6938, 0x9102, 0xa8b0, 0x693c,
- 0x9103, 0x1e48, 0x683c, 0x602e, 0x6838, 0x9084, 0xfffc, 0x683a,
- 0x6032, 0x2d00, 0x603a, 0x6808, 0x603e, 0x6910, 0x6112, 0x6954,
- 0x6156, 0x6023, 0x0001, 0x6007, 0x0039, 0x6003, 0x0001, 0x080c,
- 0x9335, 0x080c, 0x98e7, 0x009e, 0x001e, 0x0005, 0x6024, 0xd0d4,
- 0x0510, 0xd0f4, 0x11f8, 0x6038, 0x940a, 0x603c, 0x9303, 0x0230,
- 0x9105, 0x0120, 0x6024, 0xc0d4, 0xc0f5, 0x0098, 0x643a, 0x633e,
- 0xac3e, 0xab42, 0x0046, 0x0036, 0x2400, 0xacac, 0x9402, 0xa836,
- 0x2300, 0xabb0, 0x9303, 0xa83a, 0x003e, 0x004e, 0x6024, 0xc0d4,
- 0x0000, 0x6026, 0x0005, 0xd0f4, 0x1138, 0xa83c, 0x603a, 0xa840,
- 0x603e, 0x6024, 0xc0f5, 0x6026, 0x0005, 0x0006, 0x0016, 0x6004,
- 0x908e, 0x0034, 0x01b8, 0x908e, 0x0035, 0x01a0, 0x908e, 0x0036,
- 0x0188, 0x908e, 0x0037, 0x0170, 0x908e, 0x0038, 0x0158, 0x908e,
- 0x0039, 0x0140, 0x908e, 0x003a, 0x0128, 0x908e, 0x003b, 0x0110,
- 0x9085, 0x0001, 0x001e, 0x000e, 0x0005, 0x0006, 0x0016, 0x0026,
- 0x0036, 0x00e6, 0x2001, 0x1983, 0x200c, 0x8000, 0x2014, 0x2001,
- 0x0032, 0x080c, 0x91ab, 0x2001, 0x1987, 0x82ff, 0x1110, 0x2011,
- 0x0014, 0x2202, 0x2001, 0x1985, 0x200c, 0x8000, 0x2014, 0x2071,
- 0x196d, 0x711a, 0x721e, 0x2001, 0x0064, 0x080c, 0x91ab, 0x2001,
- 0x1988, 0x82ff, 0x1110, 0x2011, 0x0014, 0x2202, 0x2001, 0x1989,
- 0x9288, 0x000a, 0x2102, 0x2001, 0x1a99, 0x2102, 0x2001, 0x0032,
- 0x080c, 0x1611, 0x080c, 0x6a6d, 0x00ee, 0x003e, 0x002e, 0x001e,
- 0x000e, 0x0005, 0x0006, 0x0016, 0x00e6, 0x2001, 0x1987, 0x2003,
- 0x0028, 0x2001, 0x1988, 0x2003, 0x0014, 0x2071, 0x196d, 0x701b,
- 0x0000, 0x701f, 0x07d0, 0x2001, 0x1989, 0x2009, 0x001e, 0x2102,
- 0x2001, 0x1a99, 0x2102, 0x2001, 0x0032, 0x080c, 0x1611, 0x00ee,
- 0x001e, 0x000e, 0x0005, 0x0096, 0x6058, 0x904d, 0x0110, 0x080c,
- 0x1040, 0x009e, 0x0005, 0x0005, 0x00c6, 0x0126, 0x2091, 0x8000,
- 0x080c, 0xb091, 0x0180, 0x2b08, 0x6112, 0x0ca9, 0x6023, 0x0001,
- 0x2900, 0x6016, 0x2009, 0x0033, 0x080c, 0xb166, 0x9085, 0x0001,
- 0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd8, 0x0096, 0x00e6, 0x00f6,
- 0x2071, 0x1800, 0x9186, 0x0015, 0x1520, 0x7090, 0x9086, 0x0018,
- 0x0120, 0x7090, 0x9086, 0x0014, 0x11e0, 0x6014, 0x2048, 0xaa3c,
- 0xd2e4, 0x1160, 0x2c78, 0x080c, 0x9b82, 0x01d8, 0x707c, 0xaa50,
- 0x9206, 0x1160, 0x7080, 0xaa54, 0x9206, 0x1140, 0x6210, 0x00b6,
- 0x2258, 0xbaa0, 0x00be, 0x900e, 0x080c, 0x3294, 0x080c, 0xb4f3,
- 0x0020, 0x080c, 0xbacb, 0x080c, 0xb0e7, 0x00fe, 0x00ee, 0x009e,
- 0x0005, 0x7060, 0xaa54, 0x9206, 0x0d48, 0x0c80, 0x00c6, 0x0126,
- 0x2091, 0x8000, 0x080c, 0xb091, 0x0188, 0x2b08, 0x6112, 0x080c,
- 0xd2bb, 0x6023, 0x0001, 0x2900, 0x6016, 0x2009, 0x004d, 0x080c,
- 0xb166, 0x9085, 0x0001, 0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd8,
- 0x00c6, 0x0126, 0x2091, 0x8000, 0x0016, 0x080c, 0xb091, 0x0180,
- 0x2b08, 0x6112, 0x080c, 0xd2bb, 0x6023, 0x0001, 0x2900, 0x6016,
- 0x001e, 0x080c, 0xb166, 0x9085, 0x0001, 0x012e, 0x00ce, 0x0005,
- 0x001e, 0x9006, 0x0cd0, 0x0016, 0x0026, 0x0036, 0x0046, 0x0056,
- 0x0066, 0x0096, 0x00e6, 0x00f6, 0x2071, 0x1800, 0x9186, 0x0015,
- 0x1568, 0x7190, 0x6014, 0x2048, 0xa814, 0x8003, 0x9106, 0x1530,
- 0x20e1, 0x0000, 0x2001, 0x19a1, 0x2003, 0x0000, 0x6014, 0x2048,
- 0xa830, 0x20a8, 0x8906, 0x8006, 0x8007, 0x9094, 0x003f, 0x22e8,
- 0x9084, 0xffc0, 0x9080, 0x001b, 0x20a0, 0x2001, 0x19a1, 0x0016,
- 0x200c, 0x080c, 0xdb93, 0x001e, 0xa804, 0x9005, 0x0110, 0x2048,
- 0x0c38, 0x6014, 0x2048, 0xa867, 0x0103, 0x0010, 0x080c, 0xbacb,
- 0x080c, 0xb0e7, 0x00fe, 0x00ee, 0x009e, 0x006e, 0x005e, 0x004e,
- 0x003e, 0x002e, 0x001e, 0x0005, 0x0096, 0x00e6, 0x00f6, 0x2071,
- 0x1800, 0x9186, 0x0015, 0x11b8, 0x7090, 0x9086, 0x0004, 0x1198,
- 0x6014, 0x2048, 0x2c78, 0x080c, 0x9b82, 0x01a8, 0x707c, 0xaa74,
- 0x9206, 0x1130, 0x7080, 0xaa78, 0x9206, 0x1110, 0x080c, 0x324b,
- 0x080c, 0xb4f3, 0x0020, 0x080c, 0xbacb, 0x080c, 0xb0e7, 0x00fe,
- 0x00ee, 0x009e, 0x0005, 0x7060, 0xaa78, 0x9206, 0x0d78, 0x0c80,
- 0x0096, 0x00e6, 0x00f6, 0x2071, 0x1800, 0x9186, 0x0015, 0x1550,
- 0x7090, 0x9086, 0x0004, 0x1530, 0x6014, 0x2048, 0x2c78, 0x080c,
- 0x9b82, 0x05f0, 0x707c, 0xaacc, 0x9206, 0x1180, 0x7080, 0xaad0,
- 0x9206, 0x1160, 0x080c, 0x324b, 0x0016, 0xa998, 0xaab0, 0x9284,
- 0x1000, 0xc0fd, 0x080c, 0x577c, 0x001e, 0x0010, 0x080c, 0x5567,
- 0x080c, 0xce3f, 0x0508, 0xa87b, 0x0000, 0xa883, 0x0000, 0xa897,
- 0x4000, 0x0080, 0x080c, 0xce3f, 0x01b8, 0x6014, 0x2048, 0x080c,
- 0x5567, 0x1d70, 0xa87b, 0x0030, 0xa883, 0x0000, 0xa897, 0x4005,
- 0xa89b, 0x0004, 0x0126, 0x2091, 0x8000, 0xa867, 0x0139, 0x080c,
- 0x6dcb, 0x012e, 0x080c, 0xb0e7, 0x00fe, 0x00ee, 0x009e, 0x0005,
- 0x7060, 0xaad0, 0x9206, 0x0930, 0x0888, 0x0016, 0x0026, 0xa87c,
- 0xd0ac, 0x0178, 0xa938, 0xaa34, 0x2100, 0x9205, 0x0150, 0xa890,
- 0x9106, 0x1118, 0xa88c, 0x9206, 0x0120, 0xa992, 0xaa8e, 0x9085,
- 0x0001, 0x002e, 0x001e, 0x0005, 0x00b6, 0x00d6, 0x0036, 0x080c,
- 0xce3f, 0x0904, 0xd47d, 0x0096, 0x6314, 0x2348, 0xa87a, 0xa982,
- 0x929e, 0x4000, 0x1580, 0x6310, 0x00c6, 0x2358, 0x2009, 0x0000,
- 0xa868, 0xd0f4, 0x1140, 0x080c, 0x6937, 0x1108, 0xc185, 0xb800,
- 0xd0bc, 0x0108, 0xc18d, 0xaa96, 0xa99a, 0x20a9, 0x0004, 0xa860,
- 0x20e8, 0xa85c, 0x9080, 0x0031, 0x20a0, 0xb8c4, 0x20e0, 0xb8c8,
- 0x9080, 0x0006, 0x2098, 0x080c, 0x0f8b, 0x20a9, 0x0004, 0xa85c,
- 0x9080, 0x0035, 0x20a0, 0xb8c8, 0x9080, 0x000a, 0x2098, 0x080c,
- 0x0f8b, 0x00ce, 0x0090, 0xaa96, 0x3918, 0x9398, 0x0007, 0x231c,
- 0x6004, 0x9086, 0x0016, 0x0110, 0xa89b, 0x0004, 0xaba2, 0x6310,
- 0x2358, 0xb804, 0x9084, 0x00ff, 0xa89e, 0xa868, 0xc0f4, 0xa86a,
- 0x080c, 0x6dbe, 0x6017, 0x0000, 0x009e, 0x003e, 0x00de, 0x00be,
- 0x0005, 0x0026, 0x0036, 0x0046, 0x00b6, 0x0096, 0x00f6, 0x6214,
- 0x2248, 0x6210, 0x2258, 0x2079, 0x0260, 0x9096, 0x0000, 0x11a0,
- 0xb814, 0x9084, 0x00ff, 0x900e, 0x080c, 0x2889, 0x2118, 0x831f,
- 0x939c, 0xff00, 0x7838, 0x9084, 0x00ff, 0x931d, 0x7c3c, 0x2011,
- 0x8018, 0x080c, 0x4be3, 0x00a8, 0x9096, 0x0001, 0x1148, 0x89ff,
- 0x0180, 0xa89b, 0x000d, 0x7838, 0xa8a6, 0x783c, 0xa8aa, 0x0048,
- 0x9096, 0x0002, 0x1130, 0xa89b, 0x000d, 0x7838, 0xa8a6, 0x783c,
- 0xa8aa, 0x00fe, 0x009e, 0x00be, 0x004e, 0x003e, 0x002e, 0x0005,
- 0x00c6, 0x0026, 0x0016, 0x9186, 0x0035, 0x0110, 0x6a38, 0x0008,
- 0x6a2c, 0x080c, 0xce2d, 0x01f0, 0x2260, 0x6120, 0x9186, 0x0003,
- 0x0118, 0x9186, 0x0006, 0x1190, 0x6838, 0x9206, 0x0140, 0x683c,
- 0x9206, 0x1160, 0x6108, 0x6838, 0x9106, 0x1140, 0x0020, 0x6008,
- 0x693c, 0x9106, 0x1118, 0x6010, 0x6910, 0x9106, 0x001e, 0x002e,
- 0x00ce, 0x0005, 0x9085, 0x0001, 0x0cc8, 0xa974, 0xd1cc, 0x0188,
- 0x918c, 0x00ff, 0x918e, 0x0002, 0x1160, 0xa9a8, 0x918c, 0x0f00,
- 0x810f, 0x918e, 0x0001, 0x1128, 0xa834, 0xa938, 0x9115, 0x190c,
- 0xc4f6, 0x0005, 0x0036, 0x2019, 0x0001, 0x0010, 0x0036, 0x901e,
- 0x0499, 0x01e0, 0x080c, 0xce3f, 0x01c8, 0x080c, 0xd02a, 0x6037,
- 0x4000, 0x6014, 0x6017, 0x0000, 0x0096, 0x2048, 0xa87c, 0x080c,
- 0xd047, 0x1118, 0x080c, 0xbacb, 0x0040, 0xa867, 0x0103, 0xa877,
- 0x0000, 0x83ff, 0x1129, 0x080c, 0x6dcb, 0x009e, 0x003e, 0x0005,
- 0xa880, 0xd0b4, 0x0128, 0xa87b, 0x0006, 0xc0ec, 0xa882, 0x0048,
- 0xd0bc, 0x0118, 0xa87b, 0x0002, 0x0020, 0xa87b, 0x0005, 0x080c,
- 0xd13b, 0xa877, 0x0000, 0x0005, 0x2001, 0x1810, 0x2004, 0xd0ec,
- 0x0005, 0x0006, 0x2001, 0x1810, 0x2004, 0xd0f4, 0x000e, 0x0005,
- 0x0006, 0x2001, 0x1810, 0x2004, 0xd0e4, 0x000e, 0x0005, 0x0036,
- 0x0046, 0x6010, 0x00b6, 0x2058, 0xbba0, 0x00be, 0x2021, 0x0007,
- 0x080c, 0x4d9a, 0x004e, 0x003e, 0x0005, 0x0c51, 0x1d81, 0x0005,
- 0x2001, 0x1987, 0x2004, 0x601a, 0x0005, 0x2001, 0x1989, 0x2004,
- 0x6042, 0x0005, 0x080c, 0xb0e7, 0x0804, 0x98e7, 0x2001, 0x0109,
- 0x2004, 0xd084, 0x01e0, 0x0126, 0x2091, 0x2800, 0x0006, 0x0016,
- 0x0026, 0x0036, 0x00f6, 0x00e6, 0x00c6, 0x2079, 0x19e9, 0x2071,
- 0x1800, 0x2061, 0x0100, 0x080c, 0x9218, 0x00ce, 0x00ee, 0x00fe,
- 0x003e, 0x002e, 0x001e, 0x000e, 0x012e, 0x9085, 0x0001, 0x0005,
- 0x00b6, 0x0066, 0x6000, 0x90b2, 0x0016, 0x1a0c, 0x0dc5, 0x001b,
- 0x006e, 0x00be, 0x0005, 0xd5ab, 0xdcf2, 0xde72, 0xd5ab, 0xd5ab,
- 0xd5ab, 0xd5ab, 0xd5ab, 0xd5e2, 0xdef6, 0xd5ab, 0xd5ab, 0xd5ab,
- 0xd5ab, 0xd5ab, 0xd5ab, 0x080c, 0x0dc5, 0x0066, 0x6000, 0x90b2,
- 0x0016, 0x1a0c, 0x0dc5, 0x0013, 0x006e, 0x0005, 0xd5c6, 0xe445,
- 0xd5c6, 0xd5c6, 0xd5c6, 0xd5c6, 0xd5c6, 0xd5c6, 0xe3f2, 0xe499,
- 0xd5c6, 0xeaca, 0xeb00, 0xeaca, 0xeb00, 0xd5c6, 0x080c, 0x0dc5,
- 0x6000, 0x9082, 0x0016, 0x1a0c, 0x0dc5, 0x6000, 0x000a, 0x0005,
- 0xd5e0, 0xe0d4, 0xe1a3, 0xe1c6, 0xe286, 0xd5e0, 0xe365, 0xe30e,
- 0xdf02, 0xe3c8, 0xe3dd, 0xd5e0, 0xd5e0, 0xd5e0, 0xd5e0, 0xd5e0,
- 0x080c, 0x0dc5, 0x91b2, 0x0053, 0x1a0c, 0x0dc5, 0x2100, 0x91b2,
- 0x0040, 0x1a04, 0xda62, 0x0002, 0xd62c, 0xd830, 0xd62c, 0xd62c,
- 0xd62c, 0xd839, 0xd62c, 0xd62c, 0xd62c, 0xd62c, 0xd62c, 0xd62c,
- 0xd62c, 0xd62c, 0xd62c, 0xd62c, 0xd62c, 0xd62c, 0xd62c, 0xd62c,
- 0xd62c, 0xd62c, 0xd62c, 0xd62e, 0xd691, 0xd6a0, 0xd704, 0xd72f,
- 0xd7a8, 0xd81b, 0xd62c, 0xd62c, 0xd83c, 0xd62c, 0xd62c, 0xd851,
- 0xd85e, 0xd62c, 0xd62c, 0xd62c, 0xd62c, 0xd62c, 0xd904, 0xd62c,
- 0xd62c, 0xd918, 0xd62c, 0xd62c, 0xd8d3, 0xd62c, 0xd62c, 0xd62c,
- 0xd930, 0xd62c, 0xd62c, 0xd62c, 0xd9ad, 0xd62c, 0xd62c, 0xd62c,
- 0xd62c, 0xd62c, 0xd62c, 0xda2a, 0x080c, 0x0dc5, 0x080c, 0x6a4a,
- 0x1150, 0x2001, 0x1837, 0x2004, 0xd0cc, 0x1128, 0x9084, 0x0009,
- 0x9086, 0x0008, 0x1140, 0x6007, 0x0009, 0x602f, 0x0009, 0x6017,
- 0x0000, 0x0804, 0xd829, 0x080c, 0x69e6, 0x00e6, 0x00c6, 0x0036,
- 0x0026, 0x0016, 0x6210, 0x2258, 0xbaa0, 0x0026, 0x2019, 0x0029,
- 0x080c, 0x94da, 0x0076, 0x903e, 0x080c, 0x93ad, 0x2c08, 0x080c,
- 0xe671, 0x007e, 0x001e, 0x001e, 0x002e, 0x003e, 0x00ce, 0x00ee,
- 0x6610, 0x2658, 0x080c, 0x6726, 0xbe04, 0x9684, 0x00ff, 0x9082,
- 0x0006, 0x1268, 0x0016, 0x0026, 0x6210, 0x00b6, 0x2258, 0xbaa0,
- 0x00be, 0x2c08, 0x080c, 0xed2b, 0x002e, 0x001e, 0x1178, 0x080c,
- 0xe5a3, 0x1904, 0xd6fc, 0x080c, 0xe53f, 0x1120, 0x6007, 0x0008,
- 0x0804, 0xd829, 0x6007, 0x0009, 0x0804, 0xd829, 0x080c, 0xe7c8,
- 0x0128, 0x080c, 0xe5a3, 0x0d78, 0x0804, 0xd6fc, 0x6017, 0x1900,
- 0x0c88, 0x080c, 0x336f, 0x1904, 0xda5f, 0x6106, 0x080c, 0xe4f4,
- 0x6007, 0x0006, 0x0804, 0xd829, 0x6007, 0x0007, 0x0804, 0xd829,
- 0x080c, 0xeb3c, 0x1904, 0xda5f, 0x080c, 0x336f, 0x1904, 0xda5f,
- 0x00d6, 0x6610, 0x2658, 0xbe04, 0x9684, 0x00ff, 0x9082, 0x0006,
- 0x1220, 0x2001, 0x0001, 0x080c, 0x6649, 0x96b4, 0xff00, 0x8637,
- 0x9686, 0x0006, 0x0188, 0x9686, 0x0004, 0x0170, 0xbe04, 0x96b4,
- 0x00ff, 0x9686, 0x0006, 0x0140, 0x9686, 0x0004, 0x0128, 0x9686,
- 0x0005, 0x0110, 0x00de, 0x0480, 0x00e6, 0x2071, 0x0260, 0x7034,
- 0x9084, 0x0003, 0x1140, 0x7034, 0x9082, 0x0014, 0x0220, 0x7030,
- 0x9084, 0x0003, 0x0130, 0x00ee, 0x6017, 0x0000, 0x602f, 0x0007,
- 0x00b0, 0x00ee, 0x080c, 0xe607, 0x1190, 0x9686, 0x0006, 0x1140,
- 0x0026, 0x6210, 0x2258, 0xbaa0, 0x900e, 0x080c, 0x3294, 0x002e,
- 0x080c, 0x67b2, 0x6007, 0x000a, 0x00de, 0x0804, 0xd829, 0x6007,
- 0x000b, 0x00de, 0x0804, 0xd829, 0x080c, 0x324b, 0x080c, 0xd55d,
- 0x6007, 0x0001, 0x0804, 0xd829, 0x080c, 0xeb3c, 0x1904, 0xda5f,
- 0x080c, 0x336f, 0x1904, 0xda5f, 0x2071, 0x0260, 0x7034, 0x90b4,
- 0x0003, 0x1948, 0x90b2, 0x0014, 0x0a30, 0x7030, 0x9084, 0x0003,
- 0x1910, 0x6610, 0x2658, 0xbe04, 0x9686, 0x0707, 0x09e8, 0x0026,
- 0x6210, 0x2258, 0xbaa0, 0x900e, 0x080c, 0x3294, 0x002e, 0x6007,
- 0x000c, 0x2001, 0x0001, 0x080c, 0xed0a, 0x0804, 0xd829, 0x080c,
- 0x6a4a, 0x1140, 0x2001, 0x1837, 0x2004, 0x9084, 0x0009, 0x9086,
- 0x0008, 0x1110, 0x0804, 0xd63b, 0x080c, 0x69e6, 0x6610, 0x2658,
- 0xbe04, 0x9684, 0x00ff, 0x9082, 0x0006, 0x06c8, 0x1138, 0x0026,
- 0x2001, 0x0006, 0x080c, 0x6689, 0x002e, 0x0050, 0x96b4, 0xff00,
- 0x8637, 0x9686, 0x0004, 0x0120, 0x9686, 0x0006, 0x1904, 0xd6fc,
- 0x080c, 0xe614, 0x1120, 0x6007, 0x000e, 0x0804, 0xd829, 0x0046,
- 0x6410, 0x2458, 0xbca0, 0x0046, 0x080c, 0x324b, 0x080c, 0xd55d,
- 0x004e, 0x0016, 0x9006, 0x2009, 0x1848, 0x210c, 0xd1a4, 0x0148,
- 0x2009, 0x0029, 0x080c, 0xe940, 0x6010, 0x2058, 0xb800, 0xc0e5,
- 0xb802, 0x001e, 0x004e, 0x6007, 0x0001, 0x0804, 0xd829, 0x2001,
- 0x0001, 0x080c, 0x6649, 0x0156, 0x0016, 0x0026, 0x0036, 0x20a9,
- 0x0004, 0x2019, 0x1805, 0x2011, 0x0270, 0x080c, 0xc0d3, 0x003e,
- 0x002e, 0x001e, 0x015e, 0x9005, 0x0168, 0x96b4, 0xff00, 0x8637,
- 0x9682, 0x0004, 0x0a04, 0xd6fc, 0x9682, 0x0007, 0x0a04, 0xd758,
- 0x0804, 0xd6fc, 0x6017, 0x1900, 0x6007, 0x0009, 0x0804, 0xd829,
- 0x080c, 0x6a4a, 0x1140, 0x2001, 0x1837, 0x2004, 0x9084, 0x0009,
- 0x9086, 0x0008, 0x1110, 0x0804, 0xd63b, 0x080c, 0x69e6, 0x6610,
- 0x2658, 0xbe04, 0x9684, 0x00ff, 0x0006, 0x0016, 0x908e, 0x0001,
- 0x0118, 0x908e, 0x0000, 0x1118, 0x001e, 0x000e, 0x0080, 0x001e,
- 0x000e, 0x9082, 0x0006, 0x06a0, 0x0150, 0x96b4, 0xff00, 0x8637,
- 0x9686, 0x0004, 0x0120, 0x9686, 0x0006, 0x1904, 0xd6fc, 0x080c,
- 0xe642, 0x1138, 0x080c, 0xe53f, 0x1120, 0x6007, 0x0010, 0x0804,
- 0xd829, 0x0046, 0x6410, 0x2458, 0xbca0, 0x0046, 0x080c, 0x324b,
- 0x080c, 0xd55d, 0x004e, 0x0016, 0x9006, 0x2009, 0x1848, 0x210c,
- 0xd1a4, 0x0148, 0x2009, 0x0029, 0x080c, 0xe940, 0x6010, 0x2058,
- 0xb800, 0xc0e5, 0xb802, 0x001e, 0x004e, 0x6007, 0x0001, 0x0448,
- 0x080c, 0xe7c8, 0x0198, 0x0016, 0x968c, 0x00ff, 0x9186, 0x0002,
- 0x0160, 0x9186, 0x0003, 0x0148, 0x001e, 0x96b4, 0xff00, 0x8637,
- 0x9686, 0x0006, 0x0920, 0x0804, 0xd6fc, 0x001e, 0x6017, 0x1900,
- 0x6007, 0x0009, 0x0070, 0x080c, 0x336f, 0x1904, 0xda5f, 0x080c,
- 0xeb3c, 0x1904, 0xda5f, 0x080c, 0xdc30, 0x1904, 0xd6fc, 0x6007,
- 0x0012, 0x6003, 0x0001, 0x080c, 0x937d, 0x080c, 0x98e7, 0x0005,
- 0x6007, 0x0001, 0x6003, 0x0001, 0x080c, 0x937d, 0x080c, 0x98e7,
- 0x0cb0, 0x6007, 0x0005, 0x0c68, 0x080c, 0xeb3c, 0x1904, 0xda5f,
- 0x080c, 0x336f, 0x1904, 0xda5f, 0x080c, 0xdc30, 0x1904, 0xd6fc,
- 0x6007, 0x0020, 0x6003, 0x0001, 0x080c, 0x937d, 0x080c, 0x98e7,
- 0x0005, 0x080c, 0x336f, 0x1904, 0xda5f, 0x6007, 0x0023, 0x6003,
- 0x0001, 0x080c, 0x937d, 0x080c, 0x98e7, 0x0005, 0x080c, 0xeb3c,
- 0x1904, 0xda5f, 0x080c, 0x336f, 0x1904, 0xda5f, 0x080c, 0xdc30,
- 0x1904, 0xd6fc, 0x0016, 0x0026, 0x00e6, 0x2071, 0x0260, 0x2c08,
- 0x2011, 0x1820, 0x2214, 0x703c, 0x9206, 0x11e0, 0x2011, 0x181f,
- 0x2214, 0x7038, 0x9084, 0x00ff, 0x9206, 0x11a0, 0x7240, 0x080c,
- 0xce2d, 0x0570, 0x2260, 0x6008, 0x9086, 0xffff, 0x0120, 0x7244,
- 0x6008, 0x9206, 0x1528, 0x6020, 0x9086, 0x0007, 0x1508, 0x080c,
- 0xb0e7, 0x04a0, 0x7244, 0x9286, 0xffff, 0x0180, 0x2c08, 0x080c,
- 0xce2d, 0x01b0, 0x2260, 0x7240, 0x6008, 0x9206, 0x1188, 0x6010,
- 0x9190, 0x0004, 0x2214, 0x9206, 0x01b8, 0x0050, 0x7240, 0x2c08,
- 0x9006, 0x080c, 0xe90a, 0x1180, 0x7244, 0x9286, 0xffff, 0x01b0,
- 0x2160, 0x6007, 0x0026, 0x6017, 0x1700, 0x7214, 0x9296, 0xffff,
- 0x1180, 0x6007, 0x0025, 0x0068, 0x6020, 0x9086, 0x0007, 0x1d80,
- 0x6004, 0x9086, 0x0024, 0x1110, 0x080c, 0xb0e7, 0x2160, 0x6007,
- 0x0025, 0x6003, 0x0001, 0x080c, 0x937d, 0x080c, 0x98e7, 0x00ee,
- 0x002e, 0x001e, 0x0005, 0x2001, 0x0001, 0x080c, 0x6649, 0x0156,
- 0x0016, 0x0026, 0x0036, 0x20a9, 0x0004, 0x2019, 0x1805, 0x2011,
- 0x0276, 0x080c, 0xc0d3, 0x003e, 0x002e, 0x001e, 0x015e, 0x0120,
- 0x6007, 0x0031, 0x0804, 0xd829, 0x080c, 0xbd45, 0x080c, 0x7563,
- 0x1190, 0x0006, 0x0026, 0x0036, 0x080c, 0x757d, 0x1138, 0x080c,
- 0x7848, 0x080c, 0x6121, 0x080c, 0x748f, 0x0010, 0x080c, 0x753b,
- 0x003e, 0x002e, 0x000e, 0x0005, 0x080c, 0x336f, 0x1904, 0xda5f,
- 0x080c, 0xdc30, 0x1904, 0xd6fc, 0x6106, 0x080c, 0xdc4c, 0x1120,
- 0x6007, 0x002b, 0x0804, 0xd829, 0x6007, 0x002c, 0x0804, 0xd829,
- 0x080c, 0xeb3c, 0x1904, 0xda5f, 0x080c, 0x336f, 0x1904, 0xda5f,
- 0x080c, 0xdc30, 0x1904, 0xd6fc, 0x6106, 0x080c, 0xdc51, 0x1120,
- 0x6007, 0x002e, 0x0804, 0xd829, 0x6007, 0x002f, 0x0804, 0xd829,
- 0x080c, 0x336f, 0x1904, 0xda5f, 0x00e6, 0x00d6, 0x00c6, 0x6010,
- 0x2058, 0xb904, 0x9184, 0x00ff, 0x9086, 0x0006, 0x0158, 0x9184,
- 0xff00, 0x8007, 0x9086, 0x0006, 0x0128, 0x00ce, 0x00de, 0x00ee,
- 0x0804, 0xd830, 0x080c, 0x57d1, 0xd0e4, 0x0904, 0xd9aa, 0x2071,
- 0x026c, 0x7010, 0x603a, 0x7014, 0x603e, 0x7108, 0x720c, 0x080c,
- 0x6a88, 0x0140, 0x6010, 0x2058, 0xb810, 0x9106, 0x1118, 0xb814,
- 0x9206, 0x0510, 0x080c, 0x6a84, 0x15b8, 0x2069, 0x1800, 0x6880,
- 0x9206, 0x1590, 0x687c, 0x9106, 0x1578, 0x7210, 0x080c, 0xce2d,
- 0x0590, 0x080c, 0xdb1d, 0x0578, 0x080c, 0xe9bc, 0x0560, 0x622e,
- 0x6007, 0x0036, 0x6003, 0x0001, 0x080c, 0x9335, 0x080c, 0x98e7,
- 0x00ce, 0x00de, 0x00ee, 0x0005, 0x7214, 0x9286, 0xffff, 0x0150,
- 0x080c, 0xce2d, 0x01c0, 0x9280, 0x0002, 0x2004, 0x7110, 0x9106,
- 0x1190, 0x08e0, 0x7210, 0x2c08, 0x9085, 0x0001, 0x080c, 0xe90a,
- 0x2c10, 0x2160, 0x0140, 0x0890, 0x6007, 0x0037, 0x602f, 0x0009,
- 0x6017, 0x1500, 0x08b8, 0x6007, 0x0037, 0x602f, 0x0003, 0x6017,
- 0x1700, 0x0880, 0x6007, 0x0012, 0x0868, 0x080c, 0x336f, 0x1904,
- 0xda5f, 0x6010, 0x2058, 0xb804, 0x9084, 0xff00, 0x8007, 0x9086,
- 0x0006, 0x1904, 0xd830, 0x00e6, 0x00d6, 0x00c6, 0x080c, 0x57d1,
- 0xd0e4, 0x0904, 0xda22, 0x2069, 0x1800, 0x2071, 0x026c, 0x7008,
- 0x603a, 0x720c, 0x623e, 0x9286, 0xffff, 0x1150, 0x7208, 0x00c6,
- 0x2c08, 0x9085, 0x0001, 0x080c, 0xe90a, 0x2c10, 0x00ce, 0x05e8,
- 0x080c, 0xce2d, 0x05d0, 0x7108, 0x9280, 0x0002, 0x2004, 0x9106,
- 0x15a0, 0x00c6, 0x0026, 0x2260, 0x080c, 0xca51, 0x002e, 0x00ce,
- 0x7118, 0x918c, 0xff00, 0x810f, 0x9186, 0x0001, 0x0178, 0x9186,
- 0x0005, 0x0118, 0x9186, 0x0007, 0x1198, 0x9280, 0x0005, 0x2004,
- 0x9005, 0x0170, 0x080c, 0xdb1d, 0x0904, 0xd9a3, 0x0056, 0x7510,
- 0x7614, 0x080c, 0xe9d5, 0x005e, 0x00ce, 0x00de, 0x00ee, 0x0005,
- 0x6007, 0x003b, 0x602f, 0x0009, 0x6017, 0x2a00, 0x6003, 0x0001,
- 0x080c, 0x9335, 0x080c, 0x98e7, 0x0c78, 0x6007, 0x003b, 0x602f,
- 0x0003, 0x6017, 0x0300, 0x6003, 0x0001, 0x080c, 0x9335, 0x080c,
- 0x98e7, 0x0c10, 0x6007, 0x003b, 0x602f, 0x000b, 0x6017, 0x0000,
- 0x0804, 0xd97a, 0x00e6, 0x0026, 0x080c, 0x6a4a, 0x0550, 0x080c,
- 0x69e6, 0x080c, 0xebad, 0x1518, 0x2071, 0x1800, 0x70dc, 0x9085,
- 0x0003, 0x70de, 0x00f6, 0x2079, 0x0100, 0x72b0, 0x9284, 0x00ff,
- 0x707e, 0x78e6, 0x9284, 0xff00, 0x7280, 0x9205, 0x7082, 0x78ea,
- 0x00fe, 0x70e7, 0x0000, 0x080c, 0x6a88, 0x0120, 0x2011, 0x1a02,
- 0x2013, 0x07d0, 0xd0ac, 0x1128, 0x080c, 0x3022, 0x0010, 0x080c,
- 0xebe1, 0x002e, 0x00ee, 0x080c, 0xb0e7, 0x0804, 0xd82f, 0x080c,
- 0xb0e7, 0x0005, 0x2600, 0x0002, 0xda76, 0xdaa4, 0xdab5, 0xda76,
- 0xda76, 0xda78, 0xdac6, 0xda76, 0xda76, 0xda76, 0xda92, 0xda76,
- 0xda76, 0xda76, 0xdad1, 0xdae7, 0xdb18, 0xda76, 0x080c, 0x0dc5,
- 0x080c, 0xeb3c, 0x1d20, 0x080c, 0x336f, 0x1d08, 0x7038, 0x6016,
- 0x6007, 0x0045, 0x6003, 0x0001, 0x080c, 0x937d, 0x0005, 0x080c,
- 0x324b, 0x080c, 0xd55d, 0x6007, 0x0001, 0x6003, 0x0001, 0x080c,
- 0x937d, 0x0005, 0x080c, 0xeb3c, 0x1950, 0x080c, 0x336f, 0x1938,
- 0x080c, 0xdc30, 0x1d60, 0x703c, 0x6016, 0x6007, 0x004a, 0x6003,
- 0x0001, 0x080c, 0x937d, 0x0005, 0x080c, 0x336f, 0x1904, 0xda5f,
- 0x2009, 0x0041, 0x080c, 0xebea, 0x6007, 0x0047, 0x6003, 0x0001,
- 0x080c, 0x937d, 0x080c, 0x98e7, 0x0005, 0x080c, 0x336f, 0x1904,
- 0xda5f, 0x2009, 0x0042, 0x080c, 0xebea, 0x6007, 0x0047, 0x6003,
- 0x0001, 0x080c, 0x937d, 0x080c, 0x98e7, 0x0005, 0x080c, 0x336f,
- 0x1904, 0xda5f, 0x2009, 0x0046, 0x080c, 0xebea, 0x080c, 0xb0e7,
- 0x0005, 0x2001, 0x1824, 0x2004, 0x9082, 0x00e1, 0x1268, 0x080c,
- 0xdb3a, 0x0904, 0xda5f, 0x6007, 0x004e, 0x6003, 0x0001, 0x080c,
- 0x937d, 0x080c, 0x98e7, 0x0005, 0x6007, 0x0012, 0x0cb0, 0x6007,
- 0x004f, 0x6017, 0x0000, 0x7134, 0x918c, 0x00ff, 0x81ff, 0x0508,
- 0x9186, 0x0001, 0x1160, 0x7140, 0x2001, 0x19bf, 0x2004, 0x9106,
- 0x11b0, 0x7144, 0x2001, 0x19c0, 0x2004, 0x9106, 0x0190, 0x9186,
- 0x0002, 0x1168, 0x2011, 0x0276, 0x20a9, 0x0004, 0x6010, 0x0096,
- 0x2048, 0x2019, 0x000a, 0x080c, 0xc0e7, 0x009e, 0x0110, 0x6017,
- 0x0001, 0x6003, 0x0001, 0x080c, 0x937d, 0x080c, 0x98e7, 0x0005,
- 0x6007, 0x0050, 0x703c, 0x6016, 0x0ca0, 0x0016, 0x00e6, 0x2071,
- 0x0260, 0x00b6, 0x00c6, 0x2260, 0x6010, 0x2058, 0xb8cc, 0xd084,
- 0x0150, 0x7128, 0x6044, 0x9106, 0x1120, 0x712c, 0x6048, 0x9106,
- 0x0110, 0x9006, 0x0010, 0x9085, 0x0001, 0x00ce, 0x00be, 0x00ee,
- 0x001e, 0x0005, 0x0016, 0x0096, 0x0086, 0x00e6, 0x01c6, 0x01d6,
- 0x0126, 0x2091, 0x8000, 0x2071, 0x1800, 0x20e1, 0x0000, 0x2001,
- 0x19a1, 0x2003, 0x0000, 0x080c, 0x1027, 0x05a0, 0x2900, 0x6016,
- 0x7090, 0x8004, 0xa816, 0x908a, 0x001e, 0x02d0, 0xa833, 0x001e,
- 0x20a9, 0x001e, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x001b, 0x20a0,
- 0x2001, 0x19a1, 0x0016, 0x200c, 0x0471, 0x001e, 0x81ff, 0x01b8,
- 0x2940, 0x080c, 0x1027, 0x01b0, 0x2900, 0xa006, 0x2100, 0x0c18,
- 0xa832, 0x20a8, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x001b, 0x20a0,
- 0x2001, 0x19a1, 0x0016, 0x200c, 0x00b1, 0x001e, 0x0000, 0x9085,
- 0x0001, 0x0048, 0x2071, 0x1800, 0x7093, 0x0000, 0x6014, 0x2048,
- 0x080c, 0x0fc0, 0x9006, 0x012e, 0x01de, 0x01ce, 0x00ee, 0x008e,
- 0x009e, 0x001e, 0x0005, 0x0006, 0x0016, 0x0026, 0x0036, 0x00c6,
- 0x918c, 0xffff, 0x11b0, 0x080c, 0x2403, 0x2099, 0x026c, 0x2001,
- 0x0014, 0x3518, 0x9312, 0x0108, 0x1218, 0x23a8, 0x4003, 0x0400,
- 0x20a8, 0x4003, 0x22a8, 0x8108, 0x080c, 0x2403, 0x2099, 0x0260,
- 0x0ca8, 0x080c, 0x2403, 0x2061, 0x19a1, 0x6004, 0x2098, 0x6008,
- 0x3518, 0x9312, 0x0108, 0x1218, 0x23a8, 0x4003, 0x0048, 0x20a8,
- 0x4003, 0x22a8, 0x8108, 0x080c, 0x2403, 0x2099, 0x0260, 0x0ca8,
- 0x2061, 0x19a1, 0x2019, 0x0280, 0x3300, 0x931e, 0x0110, 0x6006,
- 0x0020, 0x2001, 0x0260, 0x6006, 0x8108, 0x2162, 0x9292, 0x0021,
+ 0x080c, 0xd152, 0xa877, 0x0000, 0x0005, 0x2001, 0x1810, 0x2004,
+ 0xd0ec, 0x0005, 0x0006, 0x2001, 0x1810, 0x2004, 0xd0f4, 0x000e,
+ 0x0005, 0x0006, 0x2001, 0x1810, 0x2004, 0xd0e4, 0x000e, 0x0005,
+ 0x0036, 0x0046, 0x6010, 0x00b6, 0x2058, 0xbba0, 0x00be, 0x2021,
+ 0x0007, 0x080c, 0x4da0, 0x004e, 0x003e, 0x0005, 0x0c51, 0x1d81,
+ 0x0005, 0x2001, 0x1987, 0x2004, 0x601a, 0x0005, 0x2001, 0x1989,
+ 0x2004, 0x6042, 0x0005, 0x080c, 0xb101, 0x0804, 0x98ed, 0x2001,
+ 0x0109, 0x2004, 0xd084, 0x01e0, 0x0126, 0x2091, 0x2800, 0x0006,
+ 0x0016, 0x0026, 0x0036, 0x00f6, 0x00e6, 0x00c6, 0x2079, 0x19e9,
+ 0x2071, 0x1800, 0x2061, 0x0100, 0x080c, 0x921e, 0x00ce, 0x00ee,
+ 0x00fe, 0x003e, 0x002e, 0x001e, 0x000e, 0x012e, 0x9085, 0x0001,
+ 0x0005, 0x00b6, 0x0066, 0x6000, 0x90b2, 0x0010, 0x1a0c, 0x0dc5,
+ 0x001b, 0x006e, 0x00be, 0x0005, 0xd5c4, 0xdd0b, 0xde80, 0xd5c4,
+ 0xd5c4, 0xd5c4, 0xd5c4, 0xd5c4, 0xd5fb, 0xdf04, 0xd5c4, 0xd5c4,
+ 0xd5c4, 0xd5c4, 0xd5c4, 0xd5c4, 0x080c, 0x0dc5, 0x0066, 0x6000,
+ 0x90b2, 0x0010, 0x1a0c, 0x0dc5, 0x0013, 0x006e, 0x0005, 0xd5df,
+ 0xe453, 0xd5df, 0xd5df, 0xd5df, 0xd5df, 0xd5df, 0xd5df, 0xe400,
+ 0xe4a7, 0xd5df, 0xeb2f, 0xeb65, 0xeb2f, 0xeb65, 0xd5df, 0x080c,
+ 0x0dc5, 0x6000, 0x9082, 0x0010, 0x1a0c, 0x0dc5, 0x6000, 0x000a,
+ 0x0005, 0xd5f9, 0xe0e2, 0xe1b1, 0xe1d4, 0xe294, 0xd5f9, 0xe373,
+ 0xe31c, 0xdf10, 0xe3d6, 0xe3eb, 0xd5f9, 0xd5f9, 0xd5f9, 0xd5f9,
+ 0xd5f9, 0x080c, 0x0dc5, 0x91b2, 0x0053, 0x1a0c, 0x0dc5, 0x2100,
+ 0x91b2, 0x0040, 0x1a04, 0xda7b, 0x0002, 0xd645, 0xd849, 0xd645,
+ 0xd645, 0xd645, 0xd852, 0xd645, 0xd645, 0xd645, 0xd645, 0xd645,
+ 0xd645, 0xd645, 0xd645, 0xd645, 0xd645, 0xd645, 0xd645, 0xd645,
+ 0xd645, 0xd645, 0xd645, 0xd645, 0xd647, 0xd6aa, 0xd6b9, 0xd71d,
+ 0xd748, 0xd7c1, 0xd834, 0xd645, 0xd645, 0xd855, 0xd645, 0xd645,
+ 0xd86a, 0xd877, 0xd645, 0xd645, 0xd645, 0xd645, 0xd645, 0xd91d,
+ 0xd645, 0xd645, 0xd931, 0xd645, 0xd645, 0xd8ec, 0xd645, 0xd645,
+ 0xd645, 0xd949, 0xd645, 0xd645, 0xd645, 0xd9c6, 0xd645, 0xd645,
+ 0xd645, 0xd645, 0xd645, 0xd645, 0xda43, 0x080c, 0x0dc5, 0x080c,
+ 0x6a50, 0x1150, 0x2001, 0x1837, 0x2004, 0xd0cc, 0x1128, 0x9084,
+ 0x0009, 0x9086, 0x0008, 0x1140, 0x6007, 0x0009, 0x602f, 0x0009,
+ 0x6017, 0x0000, 0x0804, 0xd842, 0x080c, 0x69ec, 0x00e6, 0x00c6,
+ 0x0036, 0x0026, 0x0016, 0x6210, 0x2258, 0xbaa0, 0x0026, 0x2019,
+ 0x0029, 0x080c, 0x94e0, 0x0076, 0x903e, 0x080c, 0x93b3, 0x2c08,
+ 0x080c, 0xe690, 0x007e, 0x001e, 0x001e, 0x002e, 0x003e, 0x00ce,
+ 0x00ee, 0x6610, 0x2658, 0x080c, 0x672c, 0xbe04, 0x9684, 0x00ff,
+ 0x9082, 0x0006, 0x1268, 0x0016, 0x0026, 0x6210, 0x00b6, 0x2258,
+ 0xbaa0, 0x00be, 0x2c08, 0x080c, 0xed90, 0x002e, 0x001e, 0x1178,
+ 0x080c, 0xe5c2, 0x1904, 0xd715, 0x080c, 0xe55e, 0x1120, 0x6007,
+ 0x0008, 0x0804, 0xd842, 0x6007, 0x0009, 0x0804, 0xd842, 0x080c,
+ 0xe82d, 0x0128, 0x080c, 0xe5c2, 0x0d78, 0x0804, 0xd715, 0x6017,
+ 0x1900, 0x0c88, 0x080c, 0x336a, 0x1904, 0xda78, 0x6106, 0x080c,
+ 0xe502, 0x6007, 0x0006, 0x0804, 0xd842, 0x6007, 0x0007, 0x0804,
+ 0xd842, 0x080c, 0xeba1, 0x1904, 0xda78, 0x080c, 0x336a, 0x1904,
+ 0xda78, 0x00d6, 0x6610, 0x2658, 0xbe04, 0x9684, 0x00ff, 0x9082,
+ 0x0006, 0x1220, 0x2001, 0x0001, 0x080c, 0x664f, 0x96b4, 0xff00,
+ 0x8637, 0x9686, 0x0006, 0x0188, 0x9686, 0x0004, 0x0170, 0xbe04,
+ 0x96b4, 0x00ff, 0x9686, 0x0006, 0x0140, 0x9686, 0x0004, 0x0128,
+ 0x9686, 0x0005, 0x0110, 0x00de, 0x0480, 0x00e6, 0x2071, 0x0260,
+ 0x7034, 0x9084, 0x0003, 0x1140, 0x7034, 0x9082, 0x0014, 0x0220,
+ 0x7030, 0x9084, 0x0003, 0x0130, 0x00ee, 0x6017, 0x0000, 0x602f,
+ 0x0007, 0x00b0, 0x00ee, 0x080c, 0xe626, 0x1190, 0x9686, 0x0006,
+ 0x1140, 0x0026, 0x6210, 0x2258, 0xbaa0, 0x900e, 0x080c, 0x328f,
+ 0x002e, 0x080c, 0x67b8, 0x6007, 0x000a, 0x00de, 0x0804, 0xd842,
+ 0x6007, 0x000b, 0x00de, 0x0804, 0xd842, 0x080c, 0x3246, 0x080c,
+ 0xd576, 0x6007, 0x0001, 0x0804, 0xd842, 0x080c, 0xeba1, 0x1904,
+ 0xda78, 0x080c, 0x336a, 0x1904, 0xda78, 0x2071, 0x0260, 0x7034,
+ 0x90b4, 0x0003, 0x1948, 0x90b2, 0x0014, 0x0a30, 0x7030, 0x9084,
+ 0x0003, 0x1910, 0x6610, 0x2658, 0xbe04, 0x9686, 0x0707, 0x09e8,
+ 0x0026, 0x6210, 0x2258, 0xbaa0, 0x900e, 0x080c, 0x328f, 0x002e,
+ 0x6007, 0x000c, 0x2001, 0x0001, 0x080c, 0xed6f, 0x0804, 0xd842,
+ 0x080c, 0x6a50, 0x1140, 0x2001, 0x1837, 0x2004, 0x9084, 0x0009,
+ 0x9086, 0x0008, 0x1110, 0x0804, 0xd654, 0x080c, 0x69ec, 0x6610,
+ 0x2658, 0xbe04, 0x9684, 0x00ff, 0x9082, 0x0006, 0x06c8, 0x1138,
+ 0x0026, 0x2001, 0x0006, 0x080c, 0x668f, 0x002e, 0x0050, 0x96b4,
+ 0xff00, 0x8637, 0x9686, 0x0004, 0x0120, 0x9686, 0x0006, 0x1904,
+ 0xd715, 0x080c, 0xe633, 0x1120, 0x6007, 0x000e, 0x0804, 0xd842,
+ 0x0046, 0x6410, 0x2458, 0xbca0, 0x0046, 0x080c, 0x3246, 0x080c,
+ 0xd576, 0x004e, 0x0016, 0x9006, 0x2009, 0x1848, 0x210c, 0xd1a4,
+ 0x0148, 0x2009, 0x0029, 0x080c, 0xe9a5, 0x6010, 0x2058, 0xb800,
+ 0xc0e5, 0xb802, 0x001e, 0x004e, 0x6007, 0x0001, 0x0804, 0xd842,
+ 0x2001, 0x0001, 0x080c, 0x664f, 0x0156, 0x0016, 0x0026, 0x0036,
+ 0x20a9, 0x0004, 0x2019, 0x1805, 0x2011, 0x0270, 0x080c, 0xc0e3,
+ 0x003e, 0x002e, 0x001e, 0x015e, 0x9005, 0x0168, 0x96b4, 0xff00,
+ 0x8637, 0x9682, 0x0004, 0x0a04, 0xd715, 0x9682, 0x0007, 0x0a04,
+ 0xd771, 0x0804, 0xd715, 0x6017, 0x1900, 0x6007, 0x0009, 0x0804,
+ 0xd842, 0x080c, 0x6a50, 0x1140, 0x2001, 0x1837, 0x2004, 0x9084,
+ 0x0009, 0x9086, 0x0008, 0x1110, 0x0804, 0xd654, 0x080c, 0x69ec,
+ 0x6610, 0x2658, 0xbe04, 0x9684, 0x00ff, 0x0006, 0x0016, 0x908e,
+ 0x0001, 0x0118, 0x908e, 0x0000, 0x1118, 0x001e, 0x000e, 0x0080,
+ 0x001e, 0x000e, 0x9082, 0x0006, 0x06a0, 0x0150, 0x96b4, 0xff00,
+ 0x8637, 0x9686, 0x0004, 0x0120, 0x9686, 0x0006, 0x1904, 0xd715,
+ 0x080c, 0xe661, 0x1138, 0x080c, 0xe55e, 0x1120, 0x6007, 0x0010,
+ 0x0804, 0xd842, 0x0046, 0x6410, 0x2458, 0xbca0, 0x0046, 0x080c,
+ 0x3246, 0x080c, 0xd576, 0x004e, 0x0016, 0x9006, 0x2009, 0x1848,
+ 0x210c, 0xd1a4, 0x0148, 0x2009, 0x0029, 0x080c, 0xe9a5, 0x6010,
+ 0x2058, 0xb800, 0xc0e5, 0xb802, 0x001e, 0x004e, 0x6007, 0x0001,
+ 0x0448, 0x080c, 0xe82d, 0x0198, 0x0016, 0x968c, 0x00ff, 0x9186,
+ 0x0002, 0x0160, 0x9186, 0x0003, 0x0148, 0x001e, 0x96b4, 0xff00,
+ 0x8637, 0x9686, 0x0006, 0x0920, 0x0804, 0xd715, 0x001e, 0x6017,
+ 0x1900, 0x6007, 0x0009, 0x0070, 0x080c, 0x336a, 0x1904, 0xda78,
+ 0x080c, 0xeba1, 0x1904, 0xda78, 0x080c, 0xdc49, 0x1904, 0xd715,
+ 0x6007, 0x0012, 0x6003, 0x0001, 0x080c, 0x9383, 0x080c, 0x98ed,
+ 0x0005, 0x6007, 0x0001, 0x6003, 0x0001, 0x080c, 0x9383, 0x080c,
+ 0x98ed, 0x0cb0, 0x6007, 0x0005, 0x0c68, 0x080c, 0xeba1, 0x1904,
+ 0xda78, 0x080c, 0x336a, 0x1904, 0xda78, 0x080c, 0xdc49, 0x1904,
+ 0xd715, 0x6007, 0x0020, 0x6003, 0x0001, 0x080c, 0x9383, 0x080c,
+ 0x98ed, 0x0005, 0x080c, 0x336a, 0x1904, 0xda78, 0x6007, 0x0023,
+ 0x6003, 0x0001, 0x080c, 0x9383, 0x080c, 0x98ed, 0x0005, 0x080c,
+ 0xeba1, 0x1904, 0xda78, 0x080c, 0x336a, 0x1904, 0xda78, 0x080c,
+ 0xdc49, 0x1904, 0xd715, 0x0016, 0x0026, 0x00e6, 0x2071, 0x0260,
+ 0x2c08, 0x2011, 0x1820, 0x2214, 0x703c, 0x9206, 0x11e0, 0x2011,
+ 0x181f, 0x2214, 0x7038, 0x9084, 0x00ff, 0x9206, 0x11a0, 0x7240,
+ 0x080c, 0xce44, 0x0570, 0x2260, 0x6008, 0x9086, 0xffff, 0x0120,
+ 0x7244, 0x6008, 0x9206, 0x1528, 0x6020, 0x9086, 0x0007, 0x1508,
+ 0x080c, 0xb101, 0x04a0, 0x7244, 0x9286, 0xffff, 0x0180, 0x2c08,
+ 0x080c, 0xce44, 0x01b0, 0x2260, 0x7240, 0x6008, 0x9206, 0x1188,
+ 0x6010, 0x9190, 0x0004, 0x2214, 0x9206, 0x01b8, 0x0050, 0x7240,
+ 0x2c08, 0x9006, 0x080c, 0xe96f, 0x1180, 0x7244, 0x9286, 0xffff,
+ 0x01b0, 0x2160, 0x6007, 0x0026, 0x6017, 0x1700, 0x7214, 0x9296,
+ 0xffff, 0x1180, 0x6007, 0x0025, 0x0068, 0x6020, 0x9086, 0x0007,
+ 0x1d80, 0x6004, 0x9086, 0x0024, 0x1110, 0x080c, 0xb101, 0x2160,
+ 0x6007, 0x0025, 0x6003, 0x0001, 0x080c, 0x9383, 0x080c, 0x98ed,
+ 0x00ee, 0x002e, 0x001e, 0x0005, 0x2001, 0x0001, 0x080c, 0x664f,
+ 0x0156, 0x0016, 0x0026, 0x0036, 0x20a9, 0x0004, 0x2019, 0x1805,
+ 0x2011, 0x0276, 0x080c, 0xc0e3, 0x003e, 0x002e, 0x001e, 0x015e,
+ 0x0120, 0x6007, 0x0031, 0x0804, 0xd842, 0x080c, 0xbd50, 0x080c,
+ 0x7569, 0x1190, 0x0006, 0x0026, 0x0036, 0x080c, 0x7583, 0x1138,
+ 0x080c, 0x784e, 0x080c, 0x6127, 0x080c, 0x7495, 0x0010, 0x080c,
+ 0x7541, 0x003e, 0x002e, 0x000e, 0x0005, 0x080c, 0x336a, 0x1904,
+ 0xda78, 0x080c, 0xdc49, 0x1904, 0xd715, 0x6106, 0x080c, 0xdc65,
+ 0x1120, 0x6007, 0x002b, 0x0804, 0xd842, 0x6007, 0x002c, 0x0804,
+ 0xd842, 0x080c, 0xeba1, 0x1904, 0xda78, 0x080c, 0x336a, 0x1904,
+ 0xda78, 0x080c, 0xdc49, 0x1904, 0xd715, 0x6106, 0x080c, 0xdc6a,
+ 0x1120, 0x6007, 0x002e, 0x0804, 0xd842, 0x6007, 0x002f, 0x0804,
+ 0xd842, 0x080c, 0x336a, 0x1904, 0xda78, 0x00e6, 0x00d6, 0x00c6,
+ 0x6010, 0x2058, 0xb904, 0x9184, 0x00ff, 0x9086, 0x0006, 0x0158,
+ 0x9184, 0xff00, 0x8007, 0x9086, 0x0006, 0x0128, 0x00ce, 0x00de,
+ 0x00ee, 0x0804, 0xd849, 0x080c, 0x57d7, 0xd0e4, 0x0904, 0xd9c3,
+ 0x2071, 0x026c, 0x7010, 0x603a, 0x7014, 0x603e, 0x7108, 0x720c,
+ 0x080c, 0x6a8e, 0x0140, 0x6010, 0x2058, 0xb810, 0x9106, 0x1118,
+ 0xb814, 0x9206, 0x0510, 0x080c, 0x6a8a, 0x15b8, 0x2069, 0x1800,
+ 0x6880, 0x9206, 0x1590, 0x687c, 0x9106, 0x1578, 0x7210, 0x080c,
+ 0xce44, 0x0590, 0x080c, 0xdb36, 0x0578, 0x080c, 0xea21, 0x0560,
+ 0x622e, 0x6007, 0x0036, 0x6003, 0x0001, 0x080c, 0x933b, 0x080c,
+ 0x98ed, 0x00ce, 0x00de, 0x00ee, 0x0005, 0x7214, 0x9286, 0xffff,
+ 0x0150, 0x080c, 0xce44, 0x01c0, 0x9280, 0x0002, 0x2004, 0x7110,
+ 0x9106, 0x1190, 0x08e0, 0x7210, 0x2c08, 0x9085, 0x0001, 0x080c,
+ 0xe96f, 0x2c10, 0x2160, 0x0140, 0x0890, 0x6007, 0x0037, 0x602f,
+ 0x0009, 0x6017, 0x1500, 0x08b8, 0x6007, 0x0037, 0x602f, 0x0003,
+ 0x6017, 0x1700, 0x0880, 0x6007, 0x0012, 0x0868, 0x080c, 0x336a,
+ 0x1904, 0xda78, 0x6010, 0x2058, 0xb804, 0x9084, 0xff00, 0x8007,
+ 0x9086, 0x0006, 0x1904, 0xd849, 0x00e6, 0x00d6, 0x00c6, 0x080c,
+ 0x57d7, 0xd0e4, 0x0904, 0xda3b, 0x2069, 0x1800, 0x2071, 0x026c,
+ 0x7008, 0x603a, 0x720c, 0x623e, 0x9286, 0xffff, 0x1150, 0x7208,
+ 0x00c6, 0x2c08, 0x9085, 0x0001, 0x080c, 0xe96f, 0x2c10, 0x00ce,
+ 0x05e8, 0x080c, 0xce44, 0x05d0, 0x7108, 0x9280, 0x0002, 0x2004,
+ 0x9106, 0x15a0, 0x00c6, 0x0026, 0x2260, 0x080c, 0xca64, 0x002e,
+ 0x00ce, 0x7118, 0x918c, 0xff00, 0x810f, 0x9186, 0x0001, 0x0178,
+ 0x9186, 0x0005, 0x0118, 0x9186, 0x0007, 0x1198, 0x9280, 0x0005,
+ 0x2004, 0x9005, 0x0170, 0x080c, 0xdb36, 0x0904, 0xd9bc, 0x0056,
+ 0x7510, 0x7614, 0x080c, 0xea3a, 0x005e, 0x00ce, 0x00de, 0x00ee,
+ 0x0005, 0x6007, 0x003b, 0x602f, 0x0009, 0x6017, 0x2a00, 0x6003,
+ 0x0001, 0x080c, 0x933b, 0x080c, 0x98ed, 0x0c78, 0x6007, 0x003b,
+ 0x602f, 0x0003, 0x6017, 0x0300, 0x6003, 0x0001, 0x080c, 0x933b,
+ 0x080c, 0x98ed, 0x0c10, 0x6007, 0x003b, 0x602f, 0x000b, 0x6017,
+ 0x0000, 0x0804, 0xd993, 0x00e6, 0x0026, 0x080c, 0x6a50, 0x0550,
+ 0x080c, 0x69ec, 0x080c, 0xec12, 0x1518, 0x2071, 0x1800, 0x70dc,
+ 0x9085, 0x0003, 0x70de, 0x00f6, 0x2079, 0x0100, 0x72b0, 0x9284,
+ 0x00ff, 0x707e, 0x78e6, 0x9284, 0xff00, 0x7280, 0x9205, 0x7082,
+ 0x78ea, 0x00fe, 0x70e7, 0x0000, 0x080c, 0x6a8e, 0x0120, 0x2011,
+ 0x1a02, 0x2013, 0x07d0, 0xd0ac, 0x1128, 0x080c, 0x3019, 0x0010,
+ 0x080c, 0xec46, 0x002e, 0x00ee, 0x080c, 0xb101, 0x0804, 0xd848,
+ 0x080c, 0xb101, 0x0005, 0x2600, 0x0002, 0xda8f, 0xdabd, 0xdace,
+ 0xda8f, 0xda8f, 0xda91, 0xdadf, 0xda8f, 0xda8f, 0xda8f, 0xdaab,
+ 0xda8f, 0xda8f, 0xda8f, 0xdaea, 0xdb00, 0xdb31, 0xda8f, 0x080c,
+ 0x0dc5, 0x080c, 0xeba1, 0x1d20, 0x080c, 0x336a, 0x1d08, 0x7038,
+ 0x6016, 0x6007, 0x0045, 0x6003, 0x0001, 0x080c, 0x9383, 0x0005,
+ 0x080c, 0x3246, 0x080c, 0xd576, 0x6007, 0x0001, 0x6003, 0x0001,
+ 0x080c, 0x9383, 0x0005, 0x080c, 0xeba1, 0x1950, 0x080c, 0x336a,
+ 0x1938, 0x080c, 0xdc49, 0x1d60, 0x703c, 0x6016, 0x6007, 0x004a,
+ 0x6003, 0x0001, 0x080c, 0x9383, 0x0005, 0x080c, 0x336a, 0x1904,
+ 0xda78, 0x2009, 0x0041, 0x080c, 0xec4f, 0x6007, 0x0047, 0x6003,
+ 0x0001, 0x080c, 0x9383, 0x080c, 0x98ed, 0x0005, 0x080c, 0x336a,
+ 0x1904, 0xda78, 0x2009, 0x0042, 0x080c, 0xec4f, 0x6007, 0x0047,
+ 0x6003, 0x0001, 0x080c, 0x9383, 0x080c, 0x98ed, 0x0005, 0x080c,
+ 0x336a, 0x1904, 0xda78, 0x2009, 0x0046, 0x080c, 0xec4f, 0x080c,
+ 0xb101, 0x0005, 0x2001, 0x1824, 0x2004, 0x9082, 0x00e1, 0x1268,
+ 0x080c, 0xdb53, 0x0904, 0xda78, 0x6007, 0x004e, 0x6003, 0x0001,
+ 0x080c, 0x9383, 0x080c, 0x98ed, 0x0005, 0x6007, 0x0012, 0x0cb0,
+ 0x6007, 0x004f, 0x6017, 0x0000, 0x7134, 0x918c, 0x00ff, 0x81ff,
+ 0x0508, 0x9186, 0x0001, 0x1160, 0x7140, 0x2001, 0x19bf, 0x2004,
+ 0x9106, 0x11b0, 0x7144, 0x2001, 0x19c0, 0x2004, 0x9106, 0x0190,
+ 0x9186, 0x0002, 0x1168, 0x2011, 0x0276, 0x20a9, 0x0004, 0x6010,
+ 0x0096, 0x2048, 0x2019, 0x000a, 0x080c, 0xc0f7, 0x009e, 0x0110,
+ 0x6017, 0x0001, 0x6003, 0x0001, 0x080c, 0x9383, 0x080c, 0x98ed,
+ 0x0005, 0x6007, 0x0050, 0x703c, 0x6016, 0x0ca0, 0x0016, 0x00e6,
+ 0x2071, 0x0260, 0x00b6, 0x00c6, 0x2260, 0x6010, 0x2058, 0xb8cc,
+ 0xd084, 0x0150, 0x7128, 0x6044, 0x9106, 0x1120, 0x712c, 0x6048,
+ 0x9106, 0x0110, 0x9006, 0x0010, 0x9085, 0x0001, 0x00ce, 0x00be,
+ 0x00ee, 0x001e, 0x0005, 0x0016, 0x0096, 0x0086, 0x00e6, 0x01c6,
+ 0x01d6, 0x0126, 0x2091, 0x8000, 0x2071, 0x1800, 0x20e1, 0x0000,
+ 0x2001, 0x19a2, 0x2003, 0x0000, 0x080c, 0x1027, 0x05a0, 0x2900,
+ 0x6016, 0x7090, 0x8004, 0xa816, 0x908a, 0x001e, 0x02d0, 0xa833,
+ 0x001e, 0x20a9, 0x001e, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x001b,
+ 0x20a0, 0x2001, 0x19a2, 0x0016, 0x200c, 0x0471, 0x001e, 0x81ff,
+ 0x01b8, 0x2940, 0x080c, 0x1027, 0x01b0, 0x2900, 0xa006, 0x2100,
+ 0x0c18, 0xa832, 0x20a8, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x001b,
+ 0x20a0, 0x2001, 0x19a2, 0x0016, 0x200c, 0x00b1, 0x001e, 0x0000,
+ 0x9085, 0x0001, 0x0048, 0x2071, 0x1800, 0x7093, 0x0000, 0x6014,
+ 0x2048, 0x080c, 0x0fc0, 0x9006, 0x012e, 0x01de, 0x01ce, 0x00ee,
+ 0x008e, 0x009e, 0x001e, 0x0005, 0x0006, 0x0016, 0x0026, 0x0036,
+ 0x00c6, 0x918c, 0xffff, 0x11b0, 0x080c, 0x240b, 0x2099, 0x026c,
+ 0x2001, 0x0014, 0x3518, 0x9312, 0x0108, 0x1218, 0x23a8, 0x4003,
+ 0x0400, 0x20a8, 0x4003, 0x22a8, 0x8108, 0x080c, 0x240b, 0x2099,
+ 0x0260, 0x0ca8, 0x080c, 0x240b, 0x2061, 0x19a2, 0x6004, 0x2098,
+ 0x6008, 0x3518, 0x9312, 0x0108, 0x1218, 0x23a8, 0x4003, 0x0048,
+ 0x20a8, 0x4003, 0x22a8, 0x8108, 0x080c, 0x240b, 0x2099, 0x0260,
+ 0x0ca8, 0x2061, 0x19a2, 0x2019, 0x0280, 0x3300, 0x931e, 0x0110,
+ 0x6006, 0x0020, 0x2001, 0x0260, 0x6006, 0x8108, 0x2162, 0x9292,
+ 0x0021, 0x9296, 0xffff, 0x620a, 0x00ce, 0x003e, 0x002e, 0x001e,
+ 0x000e, 0x0005, 0x0006, 0x0016, 0x0026, 0x0036, 0x00c6, 0x81ff,
+ 0x11b8, 0x080c, 0x2423, 0x20a1, 0x024c, 0x2001, 0x0014, 0x3518,
+ 0x9312, 0x1218, 0x23a8, 0x4003, 0x0418, 0x20a8, 0x4003, 0x82ff,
+ 0x01f8, 0x22a8, 0x8108, 0x080c, 0x2423, 0x20a1, 0x0240, 0x0c98,
+ 0x080c, 0x2423, 0x2061, 0x19a5, 0x6004, 0x20a0, 0x6008, 0x3518,
+ 0x9312, 0x1218, 0x23a8, 0x4003, 0x0058, 0x20a8, 0x4003, 0x82ff,
+ 0x0138, 0x22a8, 0x8108, 0x080c, 0x2423, 0x20a1, 0x0240, 0x0c98,
+ 0x2061, 0x19a5, 0x2019, 0x0260, 0x3400, 0x931e, 0x0110, 0x6006,
+ 0x0020, 0x2001, 0x0240, 0x6006, 0x8108, 0x2162, 0x9292, 0x0021,
0x9296, 0xffff, 0x620a, 0x00ce, 0x003e, 0x002e, 0x001e, 0x000e,
- 0x0005, 0x0006, 0x0016, 0x0026, 0x0036, 0x00c6, 0x81ff, 0x11b8,
- 0x080c, 0x241b, 0x20a1, 0x024c, 0x2001, 0x0014, 0x3518, 0x9312,
- 0x1218, 0x23a8, 0x4003, 0x0418, 0x20a8, 0x4003, 0x82ff, 0x01f8,
- 0x22a8, 0x8108, 0x080c, 0x241b, 0x20a1, 0x0240, 0x0c98, 0x080c,
- 0x241b, 0x2061, 0x19a4, 0x6004, 0x20a0, 0x6008, 0x3518, 0x9312,
- 0x1218, 0x23a8, 0x4003, 0x0058, 0x20a8, 0x4003, 0x82ff, 0x0138,
- 0x22a8, 0x8108, 0x080c, 0x241b, 0x20a1, 0x0240, 0x0c98, 0x2061,
- 0x19a4, 0x2019, 0x0260, 0x3400, 0x931e, 0x0110, 0x6006, 0x0020,
- 0x2001, 0x0240, 0x6006, 0x8108, 0x2162, 0x9292, 0x0021, 0x9296,
- 0xffff, 0x620a, 0x00ce, 0x003e, 0x002e, 0x001e, 0x000e, 0x0005,
- 0x00b6, 0x0066, 0x6610, 0x2658, 0xbe04, 0x96b4, 0xff00, 0x8637,
- 0x9686, 0x0006, 0x0170, 0x9686, 0x0004, 0x0158, 0xbe04, 0x96b4,
- 0x00ff, 0x9686, 0x0006, 0x0128, 0x9686, 0x0004, 0x0110, 0x9085,
- 0x0001, 0x006e, 0x00be, 0x0005, 0x00d6, 0x080c, 0xdcc8, 0x00de,
- 0x0005, 0x00d6, 0x080c, 0xdcd5, 0x1520, 0x680c, 0x908c, 0xff00,
- 0x6820, 0x9084, 0x00ff, 0x9115, 0x6216, 0x6824, 0x602e, 0xd1e4,
- 0x0130, 0x9006, 0x080c, 0xed0a, 0x2009, 0x0001, 0x0078, 0xd1ec,
- 0x0180, 0x6920, 0x918c, 0x00ff, 0x6824, 0x080c, 0x2889, 0x1148,
- 0x2001, 0x0001, 0x080c, 0xed0a, 0x2110, 0x900e, 0x080c, 0x3294,
- 0x0018, 0x9085, 0x0001, 0x0008, 0x9006, 0x00de, 0x0005, 0x00b6,
- 0x00c6, 0x080c, 0xb139, 0x05a8, 0x0016, 0x0026, 0x00c6, 0x2011,
- 0x0263, 0x2204, 0x8211, 0x220c, 0x080c, 0x2889, 0x1578, 0x080c,
- 0x66ac, 0x1560, 0xbe12, 0xbd16, 0x00ce, 0x002e, 0x001e, 0x2b00,
- 0x6012, 0x080c, 0xeb3c, 0x11d8, 0x080c, 0x336f, 0x11c0, 0x080c,
- 0xdc30, 0x0510, 0x2001, 0x0007, 0x080c, 0x665d, 0x2001, 0x0007,
- 0x080c, 0x6689, 0x6017, 0x0000, 0x6023, 0x0001, 0x6007, 0x0001,
- 0x6003, 0x0001, 0x080c, 0x937d, 0x080c, 0x98e7, 0x0010, 0x080c,
- 0xb0e7, 0x9085, 0x0001, 0x00ce, 0x00be, 0x0005, 0x080c, 0xb0e7,
- 0x00ce, 0x002e, 0x001e, 0x0ca8, 0x080c, 0xb0e7, 0x9006, 0x0c98,
- 0x2069, 0x026d, 0x6800, 0x9082, 0x0010, 0x1228, 0x6017, 0x0000,
- 0x9085, 0x0001, 0x0008, 0x9006, 0x0005, 0x6017, 0x0000, 0x2069,
- 0x026c, 0x6808, 0x9084, 0xff00, 0x9086, 0x0800, 0x1190, 0x6904,
- 0x9186, 0x0018, 0x0118, 0x9186, 0x0014, 0x1158, 0x810f, 0x6800,
- 0x9084, 0x00ff, 0x910d, 0x615a, 0x908e, 0x0014, 0x0110, 0x908e,
- 0x0010, 0x0005, 0x6004, 0x90b2, 0x0053, 0x1a0c, 0x0dc5, 0x91b6,
- 0x0013, 0x1130, 0x2008, 0x91b2, 0x0040, 0x1a04, 0xde42, 0x040a,
- 0x91b6, 0x0027, 0x0198, 0x9186, 0x0015, 0x0118, 0x9186, 0x0016,
- 0x1148, 0x080c, 0xd56e, 0x0128, 0x6000, 0x9086, 0x0002, 0x0904,
- 0xbb12, 0x0005, 0x91b6, 0x0014, 0x190c, 0x0dc5, 0x2001, 0x0007,
- 0x080c, 0x6689, 0x080c, 0x97db, 0x080c, 0xb11a, 0x080c, 0x98e7,
- 0x0005, 0xdd61, 0xdd63, 0xdd61, 0xdd61, 0xdd61, 0xdd63, 0xdd72,
- 0xde3b, 0xddc4, 0xde3b, 0xddec, 0xde3b, 0xdd72, 0xde3b, 0xde33,
- 0xde3b, 0xde33, 0xde3b, 0xde3b, 0xdd61, 0xdd61, 0xdd61, 0xdd61,
- 0xdd61, 0xdd61, 0xdd61, 0xdd61, 0xdd61, 0xdd61, 0xdd61, 0xdd63,
- 0xdd61, 0xde3b, 0xdd61, 0xdd61, 0xde3b, 0xdd61, 0xde38, 0xde3b,
- 0xdd61, 0xdd61, 0xdd61, 0xdd61, 0xde3b, 0xde3b, 0xdd61, 0xde3b,
- 0xde3b, 0xdd61, 0xdd6d, 0xdd61, 0xdd61, 0xdd61, 0xdd61, 0xde37,
- 0xde3b, 0xdd61, 0xdd61, 0xde3b, 0xde3b, 0xdd61, 0xdd61, 0xdd61,
- 0xdd61, 0x080c, 0x0dc5, 0x080c, 0x97db, 0x080c, 0xd560, 0x6003,
- 0x0002, 0x080c, 0x98e7, 0x0804, 0xde41, 0x9006, 0x080c, 0x6649,
- 0x0804, 0xde3b, 0x080c, 0x6a84, 0x1904, 0xde3b, 0x9006, 0x080c,
- 0x6649, 0x6010, 0x2058, 0xb810, 0x9086, 0x00ff, 0x1140, 0x00f6,
- 0x2079, 0x1800, 0x78a8, 0x8000, 0x78aa, 0x00fe, 0x0428, 0x6010,
- 0x2058, 0xb8c0, 0x9005, 0x1178, 0x080c, 0xd548, 0x1904, 0xde3b,
- 0x0036, 0x0046, 0xbba0, 0x2021, 0x0007, 0x080c, 0x4d9a, 0x004e,
- 0x003e, 0x0804, 0xde3b, 0x080c, 0x33a0, 0x1904, 0xde3b, 0x2001,
- 0x1800, 0x2004, 0x9086, 0x0002, 0x1138, 0x00f6, 0x2079, 0x1800,
- 0x78a8, 0x8000, 0x78aa, 0x00fe, 0x2001, 0x0002, 0x080c, 0x665d,
- 0x080c, 0x97db, 0x6023, 0x0001, 0x6003, 0x0001, 0x6007, 0x0002,
- 0x080c, 0x937d, 0x080c, 0x98e7, 0x6110, 0x2158, 0x2009, 0x0001,
- 0x080c, 0x8711, 0x0804, 0xde41, 0x6610, 0x2658, 0xbe04, 0x96b4,
- 0xff00, 0x8637, 0x9686, 0x0006, 0x0148, 0x9686, 0x0004, 0x0130,
- 0x080c, 0x8ef4, 0x2001, 0x0004, 0x080c, 0x6689, 0x080c, 0xed59,
- 0x0904, 0xde3b, 0x080c, 0x97db, 0x2001, 0x0004, 0x080c, 0x665d,
- 0x6023, 0x0001, 0x6003, 0x0001, 0x6007, 0x0003, 0x080c, 0x937d,
- 0x080c, 0x98e7, 0x0804, 0xde41, 0x2001, 0x1800, 0x2004, 0x9086,
- 0x0003, 0x1158, 0x0036, 0x0046, 0x6010, 0x2058, 0xbba0, 0x2021,
- 0x0006, 0x080c, 0x4d9a, 0x004e, 0x003e, 0x2001, 0x0006, 0x080c,
- 0xde5f, 0x6610, 0x2658, 0xbe04, 0x0066, 0x96b4, 0xff00, 0x8637,
- 0x9686, 0x0006, 0x006e, 0x0168, 0x2001, 0x0006, 0x080c, 0x6689,
- 0x9284, 0x00ff, 0x908e, 0x0007, 0x1120, 0x2001, 0x0006, 0x080c,
- 0x665d, 0x080c, 0x6a84, 0x11f8, 0x2001, 0x1837, 0x2004, 0xd0a4,
- 0x01d0, 0xbe04, 0x96b4, 0x00ff, 0x9686, 0x0006, 0x01a0, 0x00f6,
- 0x2079, 0x1800, 0x78a8, 0x8000, 0x78aa, 0x00fe, 0x0804, 0xddac,
- 0x2001, 0x0004, 0x0030, 0x2001, 0x0006, 0x0449, 0x0020, 0x0018,
- 0x0010, 0x080c, 0x6689, 0x080c, 0x97db, 0x080c, 0xb0e7, 0x080c,
- 0x98e7, 0x0005, 0x2600, 0x0002, 0xde56, 0xde56, 0xde56, 0xde56,
- 0xde56, 0xde58, 0xde56, 0xde58, 0xde56, 0xde56, 0xde58, 0xde56,
- 0xde56, 0xde56, 0xde58, 0xde58, 0xde58, 0xde58, 0x080c, 0x0dc5,
- 0x080c, 0x97db, 0x080c, 0xb0e7, 0x080c, 0x98e7, 0x0005, 0x0016,
- 0x00b6, 0x00d6, 0x6110, 0x2158, 0xb900, 0xd184, 0x0138, 0x080c,
- 0x665d, 0x9006, 0x080c, 0x6649, 0x080c, 0x3274, 0x00de, 0x00be,
- 0x001e, 0x0005, 0x6610, 0x2658, 0xb804, 0x9084, 0xff00, 0x8007,
- 0x90b2, 0x000c, 0x1a0c, 0x0dc5, 0x91b6, 0x0015, 0x1110, 0x003b,
- 0x0028, 0x91b6, 0x0016, 0x190c, 0x0dc5, 0x006b, 0x0005, 0xbbb4,
- 0xbbb4, 0xbbb4, 0xbbb4, 0xdef4, 0xbbb4, 0xdede, 0xde9f, 0xbbb4,
- 0xbbb4, 0xbbb4, 0xbbb4, 0xbbb4, 0xbbb4, 0xbbb4, 0xbbb4, 0xdef4,
- 0xbbb4, 0xdede, 0xdee5, 0xbbb4, 0xbbb4, 0xbbb4, 0xbbb4, 0x00f6,
- 0x080c, 0x6a84, 0x11d8, 0x080c, 0xd548, 0x11c0, 0x6010, 0x905d,
- 0x01a8, 0xb8c0, 0x9005, 0x0190, 0x9006, 0x080c, 0x6649, 0x2001,
- 0x0002, 0x080c, 0x665d, 0x6023, 0x0001, 0x6003, 0x0001, 0x6007,
- 0x0002, 0x080c, 0x937d, 0x080c, 0x98e7, 0x00f0, 0x2011, 0x0263,
- 0x2204, 0x8211, 0x220c, 0x080c, 0x2889, 0x11b0, 0x080c, 0x6717,
- 0x0118, 0x080c, 0xb0e7, 0x0080, 0xb810, 0x0006, 0xb814, 0x0006,
- 0xb8c0, 0x0006, 0x080c, 0x613b, 0x000e, 0xb8c2, 0x000e, 0xb816,
- 0x000e, 0xb812, 0x080c, 0xb0e7, 0x00fe, 0x0005, 0x6604, 0x96b6,
- 0x001e, 0x1110, 0x080c, 0xb0e7, 0x0005, 0x080c, 0xbf4f, 0x1148,
- 0x6003, 0x0001, 0x6007, 0x0001, 0x080c, 0x937d, 0x080c, 0x98e7,
- 0x0010, 0x080c, 0xb0e7, 0x0005, 0x0804, 0xb0e7, 0x6004, 0x908a,
- 0x0053, 0x1a0c, 0x0dc5, 0x080c, 0x97db, 0x080c, 0xb11a, 0x080c,
- 0x98e7, 0x0005, 0x9182, 0x0040, 0x0002, 0xdf19, 0xdf19, 0xdf19,
- 0xdf19, 0xdf1b, 0xdf19, 0xdf19, 0xdf19, 0xdf19, 0xdf19, 0xdf19,
- 0xdf19, 0xdf19, 0xdf19, 0xdf19, 0xdf19, 0xdf19, 0xdf19, 0xdf19,
- 0xdf19, 0x080c, 0x0dc5, 0x0096, 0x00b6, 0x00d6, 0x00e6, 0x00f6,
- 0x0046, 0x0026, 0x6210, 0x2258, 0xb8bc, 0x9005, 0x11a8, 0x6106,
- 0x2071, 0x0260, 0x7444, 0x94a4, 0xff00, 0x0904, 0xdf81, 0x080c,
- 0xecfe, 0x1170, 0x9486, 0x2000, 0x1158, 0x2009, 0x0001, 0x2011,
- 0x0200, 0x080c, 0x8916, 0x0020, 0x9026, 0x080c, 0xeb81, 0x0c38,
- 0x080c, 0x100e, 0x090c, 0x0dc5, 0x6003, 0x0007, 0xa867, 0x010d,
- 0x9006, 0xa802, 0xa86a, 0xac8a, 0x2c00, 0xa88e, 0x6008, 0xa8e2,
- 0x6010, 0x2058, 0xb8a0, 0x7130, 0xa97a, 0x0016, 0xa876, 0xa87f,
- 0x0000, 0xa883, 0x0000, 0xa887, 0x0036, 0x080c, 0x6dcb, 0x001e,
- 0x080c, 0xecfe, 0x1904, 0xdfe1, 0x9486, 0x2000, 0x1130, 0x2019,
- 0x0017, 0x080c, 0xe8b0, 0x0804, 0xdfe1, 0x9486, 0x0200, 0x1120,
- 0x080c, 0xe847, 0x0804, 0xdfe1, 0x9486, 0x0400, 0x0120, 0x9486,
- 0x1000, 0x1904, 0xdfe1, 0x2019, 0x0002, 0x080c, 0xe862, 0x0804,
- 0xdfe1, 0x2069, 0x1a75, 0x6a00, 0xd284, 0x0904, 0xe04b, 0x9284,
- 0x0300, 0x1904, 0xe044, 0x6804, 0x9005, 0x0904, 0xe02c, 0x2d78,
- 0x6003, 0x0007, 0x080c, 0x1027, 0x0904, 0xdfed, 0x7800, 0xd08c,
- 0x1118, 0x7804, 0x8001, 0x7806, 0x6017, 0x0000, 0x2001, 0x180f,
- 0x2004, 0xd084, 0x1904, 0xe04f, 0x9006, 0xa802, 0xa867, 0x0116,
- 0xa86a, 0x6008, 0xa8e2, 0x2c00, 0xa87a, 0x6010, 0x2058, 0xb8a0,
- 0x7130, 0xa9b6, 0xa876, 0xb928, 0xa9ba, 0xb92c, 0xa9be, 0xb930,
- 0xa9c2, 0xb934, 0xa9c6, 0xa883, 0x003d, 0x7044, 0x9084, 0x0003,
- 0x9080, 0xdfe9, 0x2005, 0xa87e, 0x20a9, 0x000a, 0x2001, 0x0270,
- 0xaa5c, 0x9290, 0x0021, 0x2009, 0x0205, 0x200b, 0x0080, 0x20e1,
- 0x0000, 0xab60, 0x23e8, 0x2098, 0x22a0, 0x4003, 0x200b, 0x0000,
- 0x2001, 0x027a, 0x200c, 0xa9b2, 0x8000, 0x200c, 0xa9ae, 0x080c,
- 0x6dcb, 0x002e, 0x004e, 0x00fe, 0x00ee, 0x00de, 0x00be, 0x009e,
- 0x0005, 0x0000, 0x0080, 0x0040, 0x0000, 0x2001, 0x1810, 0x2004,
- 0xd084, 0x0120, 0x080c, 0x100e, 0x1904, 0xdf96, 0x6017, 0xf100,
- 0x6003, 0x0001, 0x6007, 0x0041, 0x080c, 0x9335, 0x080c, 0x98e7,
- 0x0c00, 0x2069, 0x0260, 0x6848, 0x9084, 0xff00, 0x9086, 0x1200,
- 0x1198, 0x686c, 0x9084, 0x00ff, 0x0016, 0x6114, 0x918c, 0xf700,
- 0x910d, 0x6116, 0x001e, 0x6003, 0x0001, 0x6007, 0x0043, 0x080c,
- 0x9335, 0x080c, 0x98e7, 0x0828, 0x6868, 0x602e, 0x686c, 0x6032,
- 0x6017, 0xf200, 0x6003, 0x0001, 0x6007, 0x0041, 0x080c, 0x9335,
- 0x080c, 0x98e7, 0x0804, 0xdfe1, 0x2001, 0x180e, 0x2004, 0xd0ec,
- 0x0120, 0x2011, 0x8049, 0x080c, 0x4be3, 0x6017, 0xf300, 0x0010,
- 0x6017, 0xf100, 0x6003, 0x0001, 0x6007, 0x0041, 0x080c, 0x9335,
- 0x080c, 0x98e7, 0x0804, 0xdfe1, 0x6017, 0xf500, 0x0c98, 0x6017,
- 0xf600, 0x0804, 0xe001, 0x6017, 0xf200, 0x0804, 0xe001, 0xa867,
- 0x0146, 0xa86b, 0x0000, 0x6008, 0xa886, 0x2c00, 0xa87a, 0x7044,
- 0x9084, 0x0003, 0x9080, 0xdfe9, 0x2005, 0xa87e, 0x2928, 0x6010,
- 0x2058, 0xb8a0, 0xa876, 0xb828, 0xa88a, 0xb82c, 0xa88e, 0xb830,
- 0xa892, 0xb834, 0xa896, 0xa883, 0x003d, 0x2009, 0x0205, 0x2104,
- 0x9085, 0x0080, 0x200a, 0x20e1, 0x0000, 0x2011, 0x0210, 0x2214,
- 0x9294, 0x0fff, 0xaaa2, 0x9282, 0x0111, 0x1a0c, 0x0dc5, 0x8210,
- 0x821c, 0x2001, 0x026c, 0x2098, 0xa860, 0x20e8, 0xa85c, 0x9080,
- 0x0029, 0x20a0, 0x2011, 0xe0cb, 0x2041, 0x0001, 0x223d, 0x9784,
- 0x00ff, 0x9322, 0x1208, 0x2300, 0x20a8, 0x4003, 0x931a, 0x0530,
- 0x8210, 0xd7fc, 0x1130, 0x8d68, 0x2d0a, 0x2001, 0x0260, 0x2098,
- 0x0c68, 0x2950, 0x080c, 0x1027, 0x0170, 0x2900, 0xb002, 0xa867,
- 0x0147, 0xa86b, 0x0000, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x001b,
- 0x20a0, 0x8840, 0x08d8, 0x2548, 0xa800, 0x902d, 0x0118, 0x080c,
- 0x1040, 0x0cc8, 0x080c, 0x1040, 0x0804, 0xdfed, 0x2548, 0x8847,
- 0x9885, 0x0046, 0xa866, 0x2009, 0x0205, 0x200b, 0x0000, 0x080c,
- 0xe8e3, 0x0804, 0xdfe1, 0x8010, 0x0004, 0x801a, 0x0006, 0x8018,
- 0x0008, 0x8016, 0x000a, 0x8014, 0x9186, 0x0013, 0x1160, 0x6004,
- 0x908a, 0x0054, 0x1a0c, 0x0dc5, 0x9082, 0x0040, 0x0a0c, 0x0dc5,
- 0x2008, 0x0804, 0xe15a, 0x9186, 0x0051, 0x0108, 0x0048, 0x080c,
- 0xd56e, 0x0500, 0x6000, 0x9086, 0x0002, 0x11e0, 0x0804, 0xe1a3,
- 0x9186, 0x0027, 0x0190, 0x9186, 0x0048, 0x0128, 0x9186, 0x0014,
- 0x0160, 0x190c, 0x0dc5, 0x080c, 0xd56e, 0x0160, 0x6000, 0x9086,
- 0x0004, 0x190c, 0x0dc5, 0x0804, 0xe286, 0x6004, 0x9082, 0x0040,
- 0x2008, 0x001a, 0x080c, 0xb181, 0x0005, 0xe121, 0xe123, 0xe123,
- 0xe14a, 0xe121, 0xe121, 0xe121, 0xe121, 0xe121, 0xe121, 0xe121,
- 0xe121, 0xe121, 0xe121, 0xe121, 0xe121, 0xe121, 0xe121, 0xe121,
- 0xe121, 0x080c, 0x0dc5, 0x080c, 0x97db, 0x080c, 0x98e7, 0x0036,
- 0x0096, 0x6014, 0x904d, 0x01d8, 0x080c, 0xce3f, 0x01c0, 0x6003,
- 0x0002, 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x1178,
- 0x2019, 0x0004, 0x080c, 0xe8e3, 0x6017, 0x0000, 0x6018, 0x9005,
- 0x1120, 0x2001, 0x1988, 0x2004, 0x601a, 0x6003, 0x0007, 0x009e,
- 0x003e, 0x0005, 0x0096, 0x080c, 0x97db, 0x080c, 0x98e7, 0x080c,
- 0xce3f, 0x0120, 0x6014, 0x2048, 0x080c, 0x1040, 0x080c, 0xb11a,
- 0x009e, 0x0005, 0x0002, 0xe16f, 0xe186, 0xe171, 0xe19d, 0xe16f,
- 0xe16f, 0xe16f, 0xe16f, 0xe16f, 0xe16f, 0xe16f, 0xe16f, 0xe16f,
- 0xe16f, 0xe16f, 0xe16f, 0xe16f, 0xe16f, 0xe16f, 0xe16f, 0x080c,
- 0x0dc5, 0x0096, 0x080c, 0x97db, 0x6014, 0x2048, 0xa87c, 0xd0b4,
- 0x0138, 0x6003, 0x0007, 0x2009, 0x0043, 0x080c, 0xb166, 0x0010,
- 0x6003, 0x0004, 0x080c, 0x98e7, 0x009e, 0x0005, 0x080c, 0x97db,
- 0x080c, 0xce3f, 0x0138, 0x6114, 0x0096, 0x2148, 0xa97c, 0x009e,
- 0xd1ec, 0x1138, 0x080c, 0x88eb, 0x080c, 0xb0e7, 0x080c, 0x98e7,
- 0x0005, 0x080c, 0xeb45, 0x0db0, 0x0cc8, 0x080c, 0x97db, 0x2009,
- 0x0041, 0x0804, 0xe30e, 0x9182, 0x0040, 0x0002, 0xe1ba, 0xe1bc,
- 0xe1ba, 0xe1ba, 0xe1ba, 0xe1ba, 0xe1ba, 0xe1ba, 0xe1ba, 0xe1ba,
- 0xe1ba, 0xe1ba, 0xe1ba, 0xe1ba, 0xe1ba, 0xe1ba, 0xe1ba, 0xe1bd,
- 0xe1ba, 0xe1ba, 0x080c, 0x0dc5, 0x0005, 0x00d6, 0x080c, 0x88eb,
- 0x00de, 0x080c, 0xeb9d, 0x080c, 0xb0e7, 0x0005, 0x9182, 0x0040,
- 0x0002, 0xe1dd, 0xe1dd, 0xe1dd, 0xe1dd, 0xe1dd, 0xe1dd, 0xe1dd,
- 0xe1dd, 0xe1dd, 0xe1df, 0xe24e, 0xe1dd, 0xe1dd, 0xe1dd, 0xe1dd,
- 0xe24e, 0xe1dd, 0xe1dd, 0xe1dd, 0xe1dd, 0x080c, 0x0dc5, 0x2001,
- 0x0105, 0x2004, 0x9084, 0x1800, 0x01c8, 0x2001, 0x0132, 0x200c,
- 0x2001, 0x0131, 0x2004, 0x9105, 0x1904, 0xe24e, 0x2009, 0x180c,
- 0x2104, 0xd0d4, 0x0904, 0xe24e, 0xc0d4, 0x200a, 0x2009, 0x0105,
- 0x2104, 0x9084, 0xe7fd, 0x9085, 0x0010, 0x200a, 0x2001, 0x1867,
- 0x2004, 0xd0e4, 0x1528, 0x603b, 0x0000, 0x080c, 0x9897, 0x6014,
- 0x0096, 0x2048, 0xa87c, 0xd0fc, 0x0188, 0x908c, 0x0003, 0x918e,
- 0x0002, 0x0508, 0x2001, 0x180c, 0x2004, 0xd0d4, 0x11e0, 0x080c,
- 0x9a09, 0x2009, 0x0041, 0x009e, 0x0804, 0xe30e, 0x080c, 0x9a09,
- 0x6003, 0x0007, 0x601b, 0x0000, 0x080c, 0x88eb, 0x009e, 0x0005,
- 0x2001, 0x0100, 0x2004, 0x9082, 0x0005, 0x0aa8, 0x2001, 0x011f,
- 0x2004, 0x603a, 0x0890, 0x2001, 0x180c, 0x200c, 0xc1d4, 0x2102,
- 0xd1cc, 0x0110, 0x080c, 0x2c9d, 0x080c, 0x9a09, 0x6014, 0x2048,
- 0xa97c, 0xd1ec, 0x1130, 0x080c, 0x88eb, 0x080c, 0xb0e7, 0x009e,
- 0x0005, 0x080c, 0xeb45, 0x0db8, 0x009e, 0x0005, 0x2001, 0x180c,
- 0x200c, 0xc1d4, 0x2102, 0x0036, 0x080c, 0x9897, 0x080c, 0x9a09,
- 0x6014, 0x0096, 0x2048, 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be,
- 0xd0bc, 0x0188, 0xa87c, 0x9084, 0x0003, 0x9086, 0x0002, 0x0140,
- 0xa8ac, 0x6330, 0x931a, 0x6332, 0xa8b0, 0x632c, 0x931b, 0x632e,
- 0x6003, 0x0002, 0x0080, 0x2019, 0x0004, 0x080c, 0xe8e3, 0x6018,
- 0x9005, 0x1128, 0x2001, 0x1988, 0x2004, 0x8003, 0x601a, 0x6017,
- 0x0000, 0x6003, 0x0007, 0x009e, 0x003e, 0x0005, 0x9182, 0x0040,
- 0x0002, 0xe29d, 0xe29d, 0xe29d, 0xe29d, 0xe29d, 0xe29d, 0xe29d,
- 0xe29d, 0xe29f, 0xe29d, 0xe29d, 0xe29d, 0xe29d, 0xe29d, 0xe29d,
- 0xe29d, 0xe29d, 0xe29d, 0xe29d, 0xe2ea, 0x080c, 0x0dc5, 0x6014,
- 0x0096, 0x2048, 0xa834, 0xaa38, 0x6110, 0x00b6, 0x2158, 0xb900,
- 0x00be, 0xd1bc, 0x1190, 0x920d, 0x1518, 0xa87c, 0xd0fc, 0x0128,
- 0x2009, 0x0041, 0x009e, 0x0804, 0xe30e, 0x6003, 0x0007, 0x601b,
- 0x0000, 0x080c, 0x88eb, 0x009e, 0x0005, 0x6124, 0xd1f4, 0x1d58,
- 0x0006, 0x0046, 0xacac, 0x9422, 0xa9b0, 0x2200, 0x910b, 0x6030,
- 0x9420, 0x6432, 0x602c, 0x9109, 0x612e, 0x004e, 0x000e, 0x08d8,
- 0x6110, 0x00b6, 0x2158, 0xb900, 0x00be, 0xd1bc, 0x1178, 0x2009,
- 0x180e, 0x210c, 0xd19c, 0x0118, 0x6003, 0x0007, 0x0010, 0x6003,
- 0x0006, 0x00e9, 0x080c, 0x88ed, 0x009e, 0x0005, 0x6003, 0x0002,
- 0x009e, 0x0005, 0x6024, 0xd0f4, 0x0128, 0x080c, 0x1608, 0x1904,
- 0xe29f, 0x0005, 0x6014, 0x0096, 0x2048, 0xa834, 0xa938, 0x009e,
- 0x9105, 0x1120, 0x080c, 0x1608, 0x1904, 0xe29f, 0x0005, 0xd2fc,
- 0x0140, 0x8002, 0x8000, 0x8212, 0x9291, 0x0000, 0x2009, 0x0009,
- 0x0010, 0x2009, 0x0015, 0xaa9a, 0xa896, 0x0005, 0x9182, 0x0040,
- 0x0208, 0x0062, 0x9186, 0x0013, 0x0120, 0x9186, 0x0014, 0x190c,
- 0x0dc5, 0x6024, 0xd0dc, 0x090c, 0x0dc5, 0x0005, 0xe332, 0xe33e,
- 0xe34a, 0xe356, 0xe332, 0xe332, 0xe332, 0xe332, 0xe339, 0xe334,
- 0xe334, 0xe332, 0xe332, 0xe332, 0xe332, 0xe334, 0xe332, 0xe334,
- 0xe332, 0xe339, 0x080c, 0x0dc5, 0x6024, 0xd0dc, 0x090c, 0x0dc5,
- 0x0005, 0x6014, 0x9005, 0x190c, 0x0dc5, 0x0005, 0x6003, 0x0001,
- 0x6106, 0x080c, 0x9335, 0x0126, 0x2091, 0x8000, 0x080c, 0x98e7,
- 0x012e, 0x0005, 0x6003, 0x0001, 0x6106, 0x080c, 0x9335, 0x0126,
- 0x2091, 0x8000, 0x080c, 0x98e7, 0x012e, 0x0005, 0x6003, 0x0003,
- 0x6106, 0x2c10, 0x080c, 0x1c01, 0x0126, 0x2091, 0x8000, 0x080c,
- 0x939a, 0x080c, 0x9a09, 0x012e, 0x0005, 0x0126, 0x2091, 0x8000,
- 0x0036, 0x0096, 0x9182, 0x0040, 0x0023, 0x009e, 0x003e, 0x012e,
- 0x0005, 0xe385, 0xe387, 0xe399, 0xe3b3, 0xe385, 0xe385, 0xe385,
- 0xe385, 0xe385, 0xe385, 0xe385, 0xe385, 0xe385, 0xe385, 0xe385,
- 0xe385, 0xe385, 0xe385, 0xe385, 0xe385, 0x080c, 0x0dc5, 0x6014,
- 0x2048, 0xa87c, 0xd0fc, 0x01f8, 0x909c, 0x0003, 0x939e, 0x0003,
- 0x01d0, 0x6003, 0x0001, 0x6106, 0x080c, 0x9335, 0x080c, 0x98e7,
- 0x0470, 0x6014, 0x2048, 0xa87c, 0xd0fc, 0x0168, 0x909c, 0x0003,
- 0x939e, 0x0003, 0x0140, 0x6003, 0x0001, 0x6106, 0x080c, 0x9335,
- 0x080c, 0x98e7, 0x00e0, 0x901e, 0x6316, 0x631a, 0x2019, 0x0004,
- 0x080c, 0xe8e3, 0x00a0, 0x6014, 0x2048, 0xa87c, 0xd0fc, 0x0d98,
- 0x909c, 0x0003, 0x939e, 0x0003, 0x0d70, 0x6003, 0x0003, 0x6106,
- 0x2c10, 0x080c, 0x1c01, 0x080c, 0x939a, 0x080c, 0x9a09, 0x0005,
- 0x080c, 0x97db, 0x6114, 0x81ff, 0x0158, 0x0096, 0x2148, 0x080c,
- 0xec9b, 0x0036, 0x2019, 0x0029, 0x080c, 0xe8e3, 0x003e, 0x009e,
- 0x080c, 0xb11a, 0x080c, 0x98e7, 0x0005, 0x080c, 0x9897, 0x6114,
- 0x81ff, 0x0158, 0x0096, 0x2148, 0x080c, 0xec9b, 0x0036, 0x2019,
- 0x0029, 0x080c, 0xe8e3, 0x003e, 0x009e, 0x080c, 0xb11a, 0x080c,
- 0x9a09, 0x0005, 0x9182, 0x0085, 0x0002, 0xe404, 0xe402, 0xe402,
- 0xe410, 0xe402, 0xe402, 0xe402, 0xe402, 0xe402, 0xe402, 0xe402,
- 0xe402, 0xe402, 0x080c, 0x0dc5, 0x6003, 0x000b, 0x6106, 0x080c,
- 0x9335, 0x0126, 0x2091, 0x8000, 0x080c, 0x98e7, 0x012e, 0x0005,
- 0x0026, 0x00e6, 0x080c, 0xeb3c, 0x0118, 0x080c, 0xb0e7, 0x0450,
- 0x2071, 0x0260, 0x7224, 0x6216, 0x2001, 0x180e, 0x2004, 0xd0e4,
- 0x0150, 0x6010, 0x00b6, 0x2058, 0xbca0, 0x00be, 0x2c00, 0x2011,
- 0x014e, 0x080c, 0xb40c, 0x7220, 0x080c, 0xe77e, 0x0118, 0x6007,
- 0x0086, 0x0040, 0x6007, 0x0087, 0x7224, 0x9296, 0xffff, 0x1110,
- 0x6007, 0x0086, 0x6003, 0x0001, 0x080c, 0x9335, 0x080c, 0x98e7,
- 0x080c, 0x9a09, 0x00ee, 0x002e, 0x0005, 0x9186, 0x0013, 0x1160,
- 0x6004, 0x908a, 0x0085, 0x0a0c, 0x0dc5, 0x908a, 0x0092, 0x1a0c,
- 0x0dc5, 0x9082, 0x0085, 0x00a2, 0x9186, 0x0027, 0x0130, 0x9186,
- 0x0014, 0x0118, 0x080c, 0xb181, 0x0050, 0x2001, 0x0007, 0x080c,
- 0x6689, 0x080c, 0x97db, 0x080c, 0xb11a, 0x080c, 0x98e7, 0x0005,
- 0xe475, 0xe477, 0xe477, 0xe475, 0xe475, 0xe475, 0xe475, 0xe475,
- 0xe475, 0xe475, 0xe475, 0xe475, 0xe475, 0x080c, 0x0dc5, 0x080c,
- 0x97db, 0x080c, 0xb11a, 0x080c, 0x98e7, 0x0005, 0x9182, 0x0085,
- 0x0a0c, 0x0dc5, 0x9182, 0x0092, 0x1a0c, 0x0dc5, 0x9182, 0x0085,
- 0x0002, 0xe496, 0xe496, 0xe496, 0xe498, 0xe496, 0xe496, 0xe496,
- 0xe496, 0xe496, 0xe496, 0xe496, 0xe496, 0xe496, 0x080c, 0x0dc5,
- 0x0005, 0x9186, 0x0013, 0x0148, 0x9186, 0x0014, 0x0130, 0x9186,
- 0x0027, 0x0118, 0x080c, 0xb181, 0x0030, 0x080c, 0x97db, 0x080c,
- 0xb11a, 0x080c, 0x98e7, 0x0005, 0x0036, 0x080c, 0xeb9d, 0x6043,
- 0x0000, 0x2019, 0x000b, 0x0031, 0x6023, 0x0006, 0x6003, 0x0007,
- 0x003e, 0x0005, 0x0126, 0x0036, 0x2091, 0x8000, 0x0086, 0x2c40,
- 0x0096, 0x904e, 0x080c, 0xa90f, 0x009e, 0x008e, 0x1550, 0x0076,
- 0x2c38, 0x080c, 0xa9ba, 0x007e, 0x1520, 0x6000, 0x9086, 0x0000,
- 0x0500, 0x6020, 0x9086, 0x0007, 0x01e0, 0x0096, 0x601c, 0xd084,
- 0x0140, 0x080c, 0xeb9d, 0x080c, 0xd560, 0x080c, 0x1ab7, 0x6023,
- 0x0007, 0x6014, 0x2048, 0x080c, 0xce3f, 0x0110, 0x080c, 0xe8e3,
- 0x009e, 0x6017, 0x0000, 0x080c, 0xeb9d, 0x6023, 0x0007, 0x080c,
- 0xd560, 0x003e, 0x012e, 0x0005, 0x00f6, 0x00c6, 0x00b6, 0x0036,
- 0x0156, 0x2079, 0x0260, 0x7938, 0x783c, 0x080c, 0x2889, 0x15c8,
- 0x0016, 0x00c6, 0x080c, 0x6717, 0x1590, 0x001e, 0x00c6, 0x2160,
- 0x080c, 0xd55d, 0x00ce, 0x002e, 0x0026, 0x0016, 0x2019, 0x0029,
- 0x080c, 0xaa80, 0x080c, 0x94da, 0x0076, 0x903e, 0x080c, 0x93ad,
- 0x007e, 0x001e, 0x0076, 0x903e, 0x080c, 0xe671, 0x007e, 0x0026,
- 0xba04, 0x9294, 0xff00, 0x8217, 0x9286, 0x0006, 0x0118, 0x9286,
- 0x0004, 0x1118, 0xbaa0, 0x080c, 0x3309, 0x002e, 0xbcc0, 0x001e,
- 0x080c, 0x613b, 0xbe12, 0xbd16, 0xbcc2, 0x9006, 0x0010, 0x00ce,
- 0x001e, 0x015e, 0x003e, 0x00be, 0x00ce, 0x00fe, 0x0005, 0x00c6,
- 0x00d6, 0x00b6, 0x0016, 0x2009, 0x1824, 0x2104, 0x9086, 0x0074,
- 0x1904, 0xe598, 0x2069, 0x0260, 0x6944, 0x9182, 0x0100, 0x06e0,
- 0x6940, 0x9184, 0x8000, 0x0904, 0xe595, 0x2001, 0x197d, 0x2004,
- 0x9005, 0x1140, 0x6010, 0x2058, 0xb8c0, 0x9005, 0x0118, 0x9184,
- 0x0800, 0x0598, 0x6948, 0x918a, 0x0001, 0x0648, 0x080c, 0xed03,
- 0x0118, 0x6978, 0xd1fc, 0x11b8, 0x2009, 0x0205, 0x200b, 0x0001,
- 0x693c, 0x81ff, 0x1198, 0x6944, 0x9182, 0x0100, 0x02a8, 0x6940,
- 0x81ff, 0x1178, 0x6948, 0x918a, 0x0001, 0x0288, 0x6950, 0x918a,
- 0x0001, 0x0298, 0x00d0, 0x6017, 0x0100, 0x00a0, 0x6017, 0x0300,
- 0x0088, 0x6017, 0x0500, 0x0070, 0x6017, 0x0700, 0x0058, 0x6017,
- 0x0900, 0x0040, 0x6017, 0x0b00, 0x0028, 0x6017, 0x0f00, 0x0010,
- 0x6017, 0x2d00, 0x9085, 0x0001, 0x0008, 0x9006, 0x001e, 0x00be,
- 0x00de, 0x00ce, 0x0005, 0x00c6, 0x00b6, 0x0026, 0x0036, 0x0156,
- 0x6210, 0x2258, 0xbb04, 0x9394, 0x00ff, 0x9286, 0x0006, 0x0180,
- 0x9286, 0x0004, 0x0168, 0x9394, 0xff00, 0x8217, 0x9286, 0x0006,
- 0x0138, 0x9286, 0x0004, 0x0120, 0x080c, 0x6726, 0x0804, 0xe600,
- 0x2011, 0x0276, 0x20a9, 0x0004, 0x0096, 0x2b48, 0x2019, 0x000a,
- 0x080c, 0xc0e7, 0x009e, 0x15a8, 0x2011, 0x027a, 0x20a9, 0x0004,
- 0x0096, 0x2b48, 0x2019, 0x0006, 0x080c, 0xc0e7, 0x009e, 0x1548,
- 0x0046, 0x0016, 0xbaa0, 0x2220, 0x9006, 0x2009, 0x1848, 0x210c,
- 0xd1a4, 0x0138, 0x2009, 0x0029, 0x080c, 0xe940, 0xb800, 0xc0e5,
- 0xb802, 0x2019, 0x0029, 0x080c, 0x94da, 0x0076, 0x2039, 0x0000,
- 0x080c, 0x93ad, 0x2c08, 0x080c, 0xe671, 0x007e, 0x2001, 0x0007,
- 0x080c, 0x6689, 0x2001, 0x0007, 0x080c, 0x665d, 0x001e, 0x004e,
- 0x9006, 0x015e, 0x003e, 0x002e, 0x00be, 0x00ce, 0x0005, 0x00d6,
- 0x2069, 0x026e, 0x6800, 0x9086, 0x0800, 0x0118, 0x6017, 0x0000,
- 0x0008, 0x9006, 0x00de, 0x0005, 0x00b6, 0x00f6, 0x0016, 0x0026,
- 0x0036, 0x0156, 0x2079, 0x026c, 0x7930, 0x7834, 0x080c, 0x2889,
- 0x11d0, 0x080c, 0x6717, 0x11b8, 0x2011, 0x0270, 0x20a9, 0x0004,
- 0x0096, 0x2b48, 0x2019, 0x000a, 0x080c, 0xc0e7, 0x009e, 0x1158,
- 0x2011, 0x0274, 0x20a9, 0x0004, 0x0096, 0x2b48, 0x2019, 0x0006,
- 0x080c, 0xc0e7, 0x009e, 0x015e, 0x003e, 0x002e, 0x001e, 0x00fe,
- 0x00be, 0x0005, 0x00b6, 0x0006, 0x0016, 0x0026, 0x0036, 0x0156,
- 0x2011, 0x0263, 0x2204, 0x8211, 0x220c, 0x080c, 0x2889, 0x11d0,
- 0x080c, 0x6717, 0x11b8, 0x2011, 0x0276, 0x20a9, 0x0004, 0x0096,
- 0x2b48, 0x2019, 0x000a, 0x080c, 0xc0e7, 0x009e, 0x1158, 0x2011,
- 0x027a, 0x20a9, 0x0004, 0x0096, 0x2b48, 0x2019, 0x0006, 0x080c,
- 0xc0e7, 0x009e, 0x015e, 0x003e, 0x002e, 0x001e, 0x000e, 0x00be,
- 0x0005, 0x00e6, 0x00c6, 0x0086, 0x0076, 0x0066, 0x0056, 0x0046,
- 0x0026, 0x0126, 0x2091, 0x8000, 0x2740, 0x2029, 0x19f2, 0x252c,
- 0x2021, 0x19f8, 0x2424, 0x2061, 0x1cd0, 0x2071, 0x1800, 0x7654,
- 0x7074, 0x81ff, 0x0150, 0x0006, 0x9186, 0x1ab8, 0x000e, 0x0128,
- 0x8001, 0x9602, 0x1a04, 0xe70f, 0x0018, 0x9606, 0x0904, 0xe70f,
- 0x080c, 0x8bbd, 0x0904, 0xe706, 0x2100, 0x9c06, 0x0904, 0xe706,
- 0x6720, 0x9786, 0x0007, 0x0904, 0xe706, 0x080c, 0xe981, 0x1904,
- 0xe706, 0x080c, 0xed21, 0x0904, 0xe706, 0x080c, 0xe971, 0x0904,
- 0xe706, 0x6720, 0x9786, 0x0001, 0x1148, 0x080c, 0x33a0, 0x0904,
- 0xe74e, 0x6004, 0x9086, 0x0000, 0x1904, 0xe74e, 0x9786, 0x0004,
- 0x0904, 0xe74e, 0x2500, 0x9c06, 0x0904, 0xe706, 0x2400, 0x9c06,
- 0x05e8, 0x88ff, 0x0118, 0x6054, 0x9906, 0x15c0, 0x0096, 0x6000,
- 0x9086, 0x0004, 0x1120, 0x0016, 0x080c, 0x1ab7, 0x001e, 0x9786,
- 0x000a, 0x0148, 0x080c, 0xd047, 0x1130, 0x080c, 0xbacb, 0x009e,
- 0x080c, 0xb11a, 0x0418, 0x6014, 0x2048, 0x080c, 0xce3f, 0x01d8,
- 0x9786, 0x0003, 0x1570, 0xa867, 0x0103, 0xa87c, 0xd0cc, 0x0130,
- 0x0096, 0xa878, 0x2048, 0x080c, 0x0fc0, 0x009e, 0xab7a, 0xa877,
- 0x0000, 0x080c, 0xec9b, 0x0016, 0x080c, 0xd135, 0x080c, 0x6dbe,
- 0x001e, 0x080c, 0xd02a, 0x009e, 0x080c, 0xb11a, 0x9ce0, 0x0018,
- 0x2001, 0x181a, 0x2004, 0x9c02, 0x1210, 0x0804, 0xe685, 0x012e,
- 0x002e, 0x004e, 0x005e, 0x006e, 0x007e, 0x008e, 0x00ce, 0x00ee,
- 0x0005, 0x9786, 0x0006, 0x1150, 0x9386, 0x0005, 0x0128, 0x080c,
- 0xec9b, 0x080c, 0xe8e3, 0x08f8, 0x009e, 0x0c00, 0x9786, 0x0009,
- 0x11f8, 0x6000, 0x9086, 0x0004, 0x01c0, 0x6000, 0x9086, 0x0003,
- 0x11a0, 0x080c, 0x9897, 0x0096, 0x6114, 0x2148, 0x080c, 0xce3f,
- 0x0118, 0x6010, 0x080c, 0x6dcb, 0x009e, 0x00c6, 0x080c, 0xb0e7,
- 0x00ce, 0x0036, 0x080c, 0x9a09, 0x003e, 0x009e, 0x0804, 0xe706,
- 0x9786, 0x000a, 0x0904, 0xe6f6, 0x0804, 0xe6eb, 0x81ff, 0x0904,
- 0xe706, 0x9180, 0x0001, 0x2004, 0x9086, 0x0018, 0x0138, 0x9180,
- 0x0001, 0x2004, 0x9086, 0x002d, 0x1904, 0xe706, 0x6000, 0x9086,
- 0x0002, 0x1904, 0xe706, 0x080c, 0xd036, 0x0138, 0x080c, 0xd047,
- 0x1904, 0xe706, 0x080c, 0xbacb, 0x0038, 0x080c, 0x3274, 0x080c,
- 0xd047, 0x1110, 0x080c, 0xbacb, 0x080c, 0xb11a, 0x0804, 0xe706,
- 0xa864, 0x9084, 0x00ff, 0x9086, 0x0039, 0x0005, 0x00c6, 0x00e6,
- 0x0016, 0x2c08, 0x2170, 0x9006, 0x080c, 0xe90a, 0x001e, 0x0120,
- 0x6020, 0x9084, 0x000f, 0x001b, 0x00ee, 0x00ce, 0x0005, 0xe79d,
- 0xe79d, 0xe79d, 0xe79d, 0xe79d, 0xe79d, 0xe79f, 0xe79d, 0xe79d,
- 0xe79d, 0xe79d, 0xb11a, 0xb11a, 0xe79d, 0x9006, 0x0005, 0x0036,
- 0x0046, 0x0016, 0x7010, 0x00b6, 0x2058, 0xbca0, 0x00be, 0x2c00,
- 0x2009, 0x0020, 0x080c, 0xe940, 0x001e, 0x004e, 0x2019, 0x0002,
- 0x080c, 0xe4ba, 0x003e, 0x9085, 0x0001, 0x0005, 0x0096, 0x080c,
- 0xce3f, 0x0140, 0x6014, 0x904d, 0x080c, 0xca5e, 0x687b, 0x0005,
- 0x080c, 0x6dcb, 0x009e, 0x080c, 0xb11a, 0x9085, 0x0001, 0x0005,
- 0x2001, 0x0001, 0x080c, 0x6649, 0x0156, 0x0016, 0x0026, 0x0036,
- 0x20a9, 0x0004, 0x2019, 0x1805, 0x2011, 0x0276, 0x080c, 0xc0d3,
- 0x003e, 0x002e, 0x001e, 0x015e, 0x9005, 0x0005, 0x00f6, 0x00e6,
- 0x00c6, 0x0086, 0x0076, 0x0066, 0x00b6, 0x0126, 0x2091, 0x8000,
- 0x2740, 0x2061, 0x1cd0, 0x2079, 0x0001, 0x8fff, 0x0904, 0xe83a,
- 0x2071, 0x1800, 0x7654, 0x7074, 0x8001, 0x9602, 0x1a04, 0xe83a,
- 0x88ff, 0x0120, 0x2800, 0x9c06, 0x15a0, 0x2078, 0x080c, 0xe971,
- 0x0580, 0x2400, 0x9c06, 0x0568, 0x6720, 0x9786, 0x0006, 0x1548,
- 0x9786, 0x0007, 0x0530, 0x88ff, 0x1150, 0xd58c, 0x1118, 0x6010,
- 0x9b06, 0x11f8, 0xd584, 0x0118, 0x6054, 0x9106, 0x11d0, 0x0096,
- 0x601c, 0xd084, 0x0140, 0x080c, 0xeb9d, 0x080c, 0xd560, 0x080c,
- 0x1ab7, 0x6023, 0x0007, 0x6014, 0x2048, 0x080c, 0xce3f, 0x0120,
- 0x0046, 0x080c, 0xe8e3, 0x004e, 0x009e, 0x080c, 0xb11a, 0x88ff,
- 0x1198, 0x9ce0, 0x0018, 0x2001, 0x181a, 0x2004, 0x9c02, 0x1210,
- 0x0804, 0xe7ed, 0x9006, 0x012e, 0x00be, 0x006e, 0x007e, 0x008e,
- 0x00ce, 0x00ee, 0x00fe, 0x0005, 0x98c5, 0x0001, 0x0ca0, 0x00b6,
- 0x0076, 0x0056, 0x0086, 0x9046, 0x2029, 0x0001, 0x2c20, 0x2019,
- 0x0002, 0x6210, 0x2258, 0x0096, 0x904e, 0x080c, 0xa90f, 0x009e,
- 0x008e, 0x903e, 0x080c, 0xa9ba, 0x080c, 0xe7de, 0x005e, 0x007e,
- 0x00be, 0x0005, 0x00b6, 0x0046, 0x0056, 0x0076, 0x00c6, 0x0156,
- 0x2c20, 0x2128, 0x20a9, 0x007f, 0x900e, 0x0016, 0x0036, 0x080c,
- 0x6717, 0x1180, 0x0056, 0x0086, 0x9046, 0x2508, 0x2029, 0x0001,
- 0x0096, 0x904e, 0x080c, 0xa90f, 0x009e, 0x008e, 0x903e, 0x080c,
- 0xa9ba, 0x005e, 0x003e, 0x001e, 0x8108, 0x1f04, 0xe86d, 0x0036,
- 0x2508, 0x2029, 0x0003, 0x080c, 0xe7de, 0x003e, 0x015e, 0x00ce,
- 0x007e, 0x005e, 0x004e, 0x00be, 0x0005, 0x00b6, 0x0076, 0x0056,
- 0x6210, 0x2258, 0x0086, 0x9046, 0x2029, 0x0001, 0x2019, 0x0048,
- 0x0096, 0x904e, 0x080c, 0xa90f, 0x009e, 0x008e, 0x903e, 0x080c,
- 0xa9ba, 0x2c20, 0x080c, 0xe7de, 0x005e, 0x007e, 0x00be, 0x0005,
- 0x00b6, 0x0046, 0x0056, 0x0076, 0x00c6, 0x0156, 0x2c20, 0x20a9,
- 0x0800, 0x900e, 0x0016, 0x0036, 0x080c, 0x6717, 0x1190, 0x0086,
- 0x9046, 0x2828, 0x0046, 0x2021, 0x0001, 0x080c, 0xeb81, 0x004e,
- 0x0096, 0x904e, 0x080c, 0xa90f, 0x009e, 0x008e, 0x903e, 0x080c,
- 0xa9ba, 0x003e, 0x001e, 0x8108, 0x1f04, 0xe8ba, 0x0036, 0x2029,
- 0x0002, 0x080c, 0xe7de, 0x003e, 0x015e, 0x00ce, 0x007e, 0x005e,
- 0x004e, 0x00be, 0x0005, 0x0016, 0x00f6, 0x080c, 0xce3d, 0x0198,
- 0xa864, 0x9084, 0x00ff, 0x9086, 0x0046, 0x0180, 0xa800, 0x907d,
- 0x0138, 0xa803, 0x0000, 0xab82, 0x080c, 0x6dcb, 0x2f48, 0x0cb0,
- 0xab82, 0x080c, 0x6dcb, 0x00fe, 0x001e, 0x0005, 0xa800, 0x907d,
- 0x0130, 0xa803, 0x0000, 0x080c, 0x6dcb, 0x2f48, 0x0cb8, 0x080c,
- 0x6dcb, 0x0c88, 0x00e6, 0x0046, 0x0036, 0x2061, 0x1cd0, 0x9005,
- 0x1138, 0x2071, 0x1800, 0x7454, 0x7074, 0x8001, 0x9402, 0x12f8,
- 0x2100, 0x9c06, 0x0188, 0x6000, 0x9086, 0x0000, 0x0168, 0x6008,
- 0x9206, 0x1150, 0x6320, 0x9386, 0x0009, 0x01b0, 0x6010, 0x91a0,
- 0x0004, 0x2424, 0x9406, 0x0140, 0x9ce0, 0x0018, 0x2001, 0x181a,
- 0x2004, 0x9c02, 0x1220, 0x0c20, 0x9085, 0x0001, 0x0008, 0x9006,
- 0x003e, 0x004e, 0x00ee, 0x0005, 0x631c, 0xd3c4, 0x1d68, 0x0c30,
- 0x0096, 0x0006, 0x080c, 0x100e, 0x000e, 0x090c, 0x0dc5, 0xaae2,
- 0xa867, 0x010d, 0xa88e, 0x0026, 0x2010, 0x080c, 0xce2d, 0x2001,
- 0x0000, 0x0120, 0x2200, 0x9080, 0x0015, 0x2004, 0x002e, 0xa87a,
- 0x9186, 0x0020, 0x0110, 0xa8e3, 0xffff, 0xa986, 0xac76, 0xa87f,
- 0x0000, 0x2001, 0x198f, 0x2004, 0xa882, 0x9006, 0xa802, 0xa86a,
- 0xa88a, 0x0126, 0x2091, 0x8000, 0x080c, 0x6dcb, 0x012e, 0x009e,
- 0x0005, 0x6700, 0x9786, 0x0000, 0x0158, 0x9786, 0x0001, 0x0140,
- 0x9786, 0x000a, 0x0128, 0x9786, 0x0009, 0x0110, 0x9085, 0x0001,
- 0x0005, 0x00e6, 0x6010, 0x9075, 0x0138, 0x00b6, 0x2058, 0xb8a0,
- 0x00be, 0x9206, 0x00ee, 0x0005, 0x9085, 0x0001, 0x0cd8, 0x0016,
- 0x6004, 0x908e, 0x001e, 0x11a0, 0x8007, 0x6134, 0x918c, 0x00ff,
- 0x9105, 0x6036, 0x6007, 0x0085, 0x6003, 0x000b, 0x6023, 0x0005,
- 0x2001, 0x1988, 0x2004, 0x601a, 0x080c, 0x9335, 0x080c, 0x98e7,
- 0x001e, 0x0005, 0xa001, 0xa001, 0x0005, 0x6024, 0xd0e4, 0x0158,
- 0xd0cc, 0x0118, 0x080c, 0xd179, 0x0030, 0x080c, 0xeb9d, 0x080c,
- 0x88eb, 0x080c, 0xb0e7, 0x0005, 0x9280, 0x0008, 0x2004, 0x9084,
- 0x000f, 0x0002, 0xe9d0, 0xe9d0, 0xe9d0, 0xe9d2, 0xe9d0, 0xe9d2,
- 0xe9d2, 0xe9d0, 0xe9d2, 0xe9d0, 0xe9d0, 0xe9d0, 0xe9d0, 0xe9d0,
- 0x9006, 0x0005, 0x9085, 0x0001, 0x0005, 0x9280, 0x0008, 0x2004,
- 0x9084, 0x000f, 0x0002, 0xe9e9, 0xe9e9, 0xe9e9, 0xe9e9, 0xe9e9,
- 0xe9e9, 0xe9f6, 0xe9e9, 0xe9e9, 0xe9e9, 0xe9e9, 0xe9e9, 0xe9e9,
- 0xe9e9, 0x6007, 0x003b, 0x602f, 0x0009, 0x6017, 0x2a00, 0x6003,
- 0x0001, 0x080c, 0x9335, 0x080c, 0x98e7, 0x0005, 0x0096, 0x00c6,
- 0x2260, 0x080c, 0xeb9d, 0x6043, 0x0000, 0x6024, 0xc0f4, 0xc0e4,
- 0x6026, 0x603b, 0x0000, 0x00ce, 0x00d6, 0x2268, 0x9186, 0x0007,
- 0x1904, 0xea4f, 0x6814, 0x9005, 0x0138, 0x2048, 0xa87c, 0xd0fc,
- 0x1118, 0x00de, 0x009e, 0x08a8, 0x6007, 0x003a, 0x6003, 0x0001,
- 0x080c, 0x9335, 0x080c, 0x98e7, 0x00c6, 0x2d60, 0x6100, 0x9186,
- 0x0002, 0x1904, 0xeac6, 0x6014, 0x9005, 0x1138, 0x6000, 0x9086,
- 0x0007, 0x190c, 0x0dc5, 0x0804, 0xeac6, 0x2048, 0x080c, 0xce3f,
- 0x1130, 0x0028, 0x2048, 0xa800, 0x9005, 0x1de0, 0x2900, 0x2048,
- 0xa87c, 0x9084, 0x0003, 0x9086, 0x0002, 0x1168, 0xa87c, 0xc0dc,
- 0xc0f4, 0xa87e, 0xa880, 0xc0fc, 0xa882, 0x2009, 0x0043, 0x080c,
- 0xe30e, 0x0804, 0xeac6, 0x2009, 0x0041, 0x0804, 0xeac0, 0x9186,
- 0x0005, 0x15a0, 0x6814, 0x2048, 0xa87c, 0xd0bc, 0x1120, 0x00de,
- 0x009e, 0x0804, 0xe9e9, 0xd0b4, 0x0128, 0xd0fc, 0x090c, 0x0dc5,
- 0x0804, 0xea0a, 0x6007, 0x003a, 0x6003, 0x0001, 0x080c, 0x9335,
- 0x080c, 0x98e7, 0x00c6, 0x2d60, 0x6100, 0x9186, 0x0002, 0x0120,
- 0x9186, 0x0004, 0x1904, 0xeac6, 0x6814, 0x2048, 0xa97c, 0xc1f4,
- 0xc1dc, 0xa97e, 0xa980, 0xc1fc, 0xc1bc, 0xa982, 0x00f6, 0x2c78,
- 0x080c, 0x1768, 0x00fe, 0x2009, 0x0042, 0x04d0, 0x0036, 0x080c,
- 0x100e, 0x090c, 0x0dc5, 0xa867, 0x010d, 0x9006, 0xa802, 0xa86a,
- 0xa88a, 0x2d18, 0xab8e, 0xa887, 0x0045, 0x2c00, 0xa892, 0x6038,
- 0xa8a2, 0x2360, 0x6024, 0xc0dd, 0x6026, 0x6010, 0x00b6, 0x2058,
- 0xb8a0, 0x00be, 0x2004, 0x6354, 0xab7a, 0xa876, 0x9006, 0xa87e,
- 0xa882, 0xad9a, 0xae96, 0xa89f, 0x0001, 0x080c, 0x6dcb, 0x2019,
- 0x0045, 0x6008, 0x2068, 0x080c, 0xe4ba, 0x2d00, 0x600a, 0x6023,
- 0x0006, 0x6003, 0x0007, 0x901e, 0x631a, 0x6342, 0x003e, 0x0038,
- 0x6043, 0x0000, 0x6003, 0x0007, 0x080c, 0xe30e, 0x00ce, 0x00de,
- 0x009e, 0x0005, 0x9186, 0x0013, 0x1128, 0x6004, 0x9082, 0x0085,
- 0x2008, 0x00c2, 0x9186, 0x0027, 0x1178, 0x080c, 0x97db, 0x0036,
- 0x0096, 0x6014, 0x2048, 0x2019, 0x0004, 0x080c, 0xe8e3, 0x009e,
- 0x003e, 0x080c, 0x98e7, 0x0005, 0x9186, 0x0014, 0x0d70, 0x080c,
- 0xb181, 0x0005, 0xeaf9, 0xeaf7, 0xeaf7, 0xeaf7, 0xeaf7, 0xeaf7,
- 0xeaf9, 0xeaf7, 0xeaf7, 0xeaf7, 0xeaf7, 0xeaf7, 0xeaf7, 0x080c,
- 0x0dc5, 0x080c, 0x97db, 0x6003, 0x000c, 0x080c, 0x98e7, 0x0005,
- 0x9182, 0x0092, 0x1220, 0x9182, 0x0085, 0x0208, 0x001a, 0x080c,
- 0xb181, 0x0005, 0xeb17, 0xeb17, 0xeb17, 0xeb17, 0xeb19, 0xeb39,
- 0xeb17, 0xeb17, 0xeb17, 0xeb17, 0xeb17, 0xeb17, 0xeb17, 0x080c,
- 0x0dc5, 0x00d6, 0x2c68, 0x080c, 0xb091, 0x01b0, 0x6003, 0x0001,
- 0x6007, 0x001e, 0x2009, 0x026e, 0x210c, 0x613a, 0x2009, 0x026f,
- 0x210c, 0x613e, 0x600b, 0xffff, 0x6910, 0x6112, 0x6023, 0x0004,
- 0x080c, 0x9335, 0x080c, 0x98e7, 0x2d60, 0x080c, 0xb0e7, 0x00de,
- 0x0005, 0x080c, 0xb0e7, 0x0005, 0x00e6, 0x6010, 0x00b6, 0x2058,
- 0xb800, 0x00be, 0xd0ec, 0x00ee, 0x0005, 0x2009, 0x1867, 0x210c,
- 0xd1ec, 0x05b0, 0x6003, 0x0002, 0x6024, 0xc0e5, 0x6026, 0xd0cc,
- 0x0150, 0x2001, 0x1989, 0x2004, 0x6042, 0x2009, 0x1867, 0x210c,
- 0xd1f4, 0x1520, 0x00a0, 0x2009, 0x1867, 0x210c, 0xd1f4, 0x0128,
- 0x6024, 0xc0e4, 0x6026, 0x9006, 0x00d8, 0x2001, 0x1989, 0x200c,
- 0x2001, 0x1987, 0x2004, 0x9100, 0x9080, 0x000a, 0x6042, 0x6010,
- 0x00b6, 0x2058, 0xb8bc, 0x00be, 0x0008, 0x2104, 0x9005, 0x0118,
- 0x9088, 0x0003, 0x0cd0, 0x2c0a, 0x600f, 0x0000, 0x9085, 0x0001,
- 0x0005, 0x0016, 0x00c6, 0x00e6, 0x6154, 0xb8bc, 0x2060, 0x8cff,
- 0x0180, 0x84ff, 0x1118, 0x6054, 0x9106, 0x1138, 0x600c, 0x2072,
- 0x080c, 0x88eb, 0x080c, 0xb0e7, 0x0010, 0x9cf0, 0x0003, 0x2e64,
- 0x0c70, 0x00ee, 0x00ce, 0x001e, 0x0005, 0x00d6, 0x00b6, 0x6010,
- 0x2058, 0xb8bc, 0x906d, 0x0130, 0x9c06, 0x0110, 0x680c, 0x0cd0,
- 0x600c, 0x680e, 0x00be, 0x00de, 0x0005, 0x0026, 0x0036, 0x0156,
- 0x2011, 0x182c, 0x2204, 0x9084, 0x00ff, 0x2019, 0x026e, 0x2334,
- 0x96b4, 0x00ff, 0x9636, 0x1508, 0x8318, 0x2334, 0x2204, 0x9084,
- 0xff00, 0x9636, 0x11d0, 0x2011, 0x0270, 0x20a9, 0x0004, 0x6010,
- 0x0096, 0x2048, 0x2019, 0x000a, 0x080c, 0xc0e7, 0x009e, 0x1168,
- 0x2011, 0x0274, 0x20a9, 0x0004, 0x6010, 0x0096, 0x2048, 0x2019,
- 0x0006, 0x080c, 0xc0e7, 0x009e, 0x1100, 0x015e, 0x003e, 0x002e,
- 0x0005, 0x00e6, 0x2071, 0x1800, 0x080c, 0x60b4, 0x080c, 0x3022,
- 0x00ee, 0x0005, 0x0096, 0x0026, 0x080c, 0x100e, 0x090c, 0x0dc5,
- 0xa85c, 0x9080, 0x001a, 0x20a0, 0x20a9, 0x000c, 0xa860, 0x20e8,
- 0x9006, 0x4004, 0x9186, 0x0046, 0x1118, 0xa867, 0x0136, 0x0038,
- 0xa867, 0x0138, 0x9186, 0x0041, 0x0110, 0xa87b, 0x0001, 0x7038,
- 0x9084, 0xff00, 0x7240, 0x9294, 0xff00, 0x8007, 0x9215, 0xaa9a,
- 0x9186, 0x0046, 0x1168, 0x7038, 0x9084, 0x00ff, 0x723c, 0x9294,
- 0xff00, 0x9215, 0xaa9e, 0x723c, 0x9294, 0x00ff, 0xaaa2, 0x0060,
- 0x7040, 0x9084, 0x00ff, 0x7244, 0x9294, 0xff00, 0x9215, 0xaa9e,
- 0x7244, 0x9294, 0x00ff, 0xaaa2, 0x9186, 0x0046, 0x1118, 0x9e90,
- 0x0012, 0x0010, 0x9e90, 0x001a, 0x2204, 0x8007, 0xa8a6, 0x8210,
- 0x2204, 0x8007, 0xa8aa, 0x8210, 0x2204, 0x8007, 0xa8ae, 0x8210,
- 0x2204, 0x8007, 0xa8b2, 0x8210, 0x9186, 0x0046, 0x11b8, 0x9e90,
- 0x0016, 0x2204, 0x8007, 0xa8b6, 0x8210, 0x2204, 0x8007, 0xa8ba,
- 0x8210, 0x2204, 0x8007, 0xa8be, 0x8210, 0x2204, 0x8007, 0xa8c2,
- 0x8210, 0x2011, 0x0205, 0x2013, 0x0001, 0x00b0, 0x9e90, 0x001e,
- 0x2204, 0x8007, 0xa8b6, 0x8210, 0x2204, 0x8007, 0xa8ba, 0x2011,
- 0x0205, 0x2013, 0x0001, 0x2011, 0x0260, 0x2204, 0x8007, 0xa8be,
- 0x8210, 0x2204, 0x8007, 0xa8c2, 0x9186, 0x0046, 0x1118, 0x2011,
- 0x0262, 0x0010, 0x2011, 0x026a, 0x0146, 0x01d6, 0x0036, 0x20a9,
- 0x0001, 0x2019, 0x0008, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0031,
- 0x20a0, 0x2204, 0x8007, 0x4004, 0x8210, 0x8319, 0x1dd0, 0x003e,
- 0x01ce, 0x013e, 0x2011, 0x0205, 0x2013, 0x0000, 0x002e, 0x080c,
- 0x6dcb, 0x009e, 0x0005, 0x00e6, 0x6010, 0x00b6, 0x2058, 0xb800,
- 0x00be, 0xd0fc, 0x0108, 0x0011, 0x00ee, 0x0005, 0xa880, 0xc0e5,
- 0xa882, 0x0005, 0x00e6, 0x00d6, 0x00c6, 0x0076, 0x0066, 0x0056,
- 0x0046, 0x0026, 0x0016, 0x0126, 0x2091, 0x8000, 0x2029, 0x19f2,
- 0x252c, 0x2021, 0x19f8, 0x2424, 0x2061, 0x1cd0, 0x2071, 0x1800,
- 0x7654, 0x7074, 0x9606, 0x0578, 0x6720, 0x9786, 0x0001, 0x0118,
- 0x9786, 0x0008, 0x1500, 0x2500, 0x9c06, 0x01e8, 0x2400, 0x9c06,
- 0x01d0, 0x080c, 0xe971, 0x01b8, 0x080c, 0xe981, 0x11a0, 0x6000,
- 0x9086, 0x0004, 0x1120, 0x0016, 0x080c, 0x1ab7, 0x001e, 0x080c,
- 0xd036, 0x1110, 0x080c, 0x3274, 0x080c, 0xd047, 0x1110, 0x080c,
- 0xbacb, 0x080c, 0xb11a, 0x9ce0, 0x0018, 0x2001, 0x181a, 0x2004,
- 0x9c02, 0x1208, 0x0858, 0x012e, 0x001e, 0x002e, 0x004e, 0x005e,
- 0x006e, 0x007e, 0x00ce, 0x00de, 0x00ee, 0x0005, 0x2001, 0x1810,
- 0x2004, 0xd0dc, 0x0005, 0x0006, 0x2001, 0x1837, 0x2004, 0xd09c,
- 0x000e, 0x0005, 0x0006, 0x0036, 0x0046, 0x080c, 0xd548, 0x0168,
- 0x2019, 0xffff, 0x9005, 0x0128, 0x6010, 0x00b6, 0x2058, 0xbba0,
- 0x00be, 0x2021, 0x0004, 0x080c, 0x4d9a, 0x004e, 0x003e, 0x000e,
- 0x0005, 0x6004, 0x9086, 0x0001, 0x1128, 0x080c, 0xaa80, 0x080c,
- 0xb11a, 0x9006, 0x0005, 0x00e6, 0x00c6, 0x00b6, 0x0046, 0x2061,
- 0x1cd0, 0x2071, 0x1800, 0x7454, 0x7074, 0x8001, 0x9402, 0x12d8,
- 0x2100, 0x9c06, 0x0168, 0x6000, 0x9086, 0x0000, 0x0148, 0x6010,
- 0x2058, 0xb8a0, 0x9206, 0x1120, 0x6004, 0x9086, 0x0002, 0x0140,
- 0x9ce0, 0x0018, 0x2001, 0x181a, 0x2004, 0x9c02, 0x1220, 0x0c40,
- 0x9085, 0x0001, 0x0008, 0x9006, 0x004e, 0x00be, 0x00ce, 0x00ee,
- 0x0005, 0x2001, 0x1810, 0x2004, 0xd0a4, 0x0160, 0x2001, 0x1837,
- 0x2004, 0xd0a4, 0x0138, 0x2001, 0x1848, 0x2004, 0xd0a4, 0x1118,
- 0x9085, 0x0001, 0x0005, 0x9006, 0x0ce8, 0x0126, 0x0006, 0x00e6,
- 0x0016, 0x2091, 0x8000, 0x2071, 0x1840, 0xd5a4, 0x0118, 0x7004,
- 0x8000, 0x7006, 0xd5b4, 0x0118, 0x7000, 0x8000, 0x7002, 0xd5ac,
- 0x0178, 0x2500, 0x9084, 0x0007, 0x908e, 0x0003, 0x0148, 0x908e,
- 0x0004, 0x0130, 0x908e, 0x0005, 0x0118, 0x2071, 0xfff6, 0x0089,
- 0x001e, 0x00ee, 0x000e, 0x012e, 0x0005, 0x0126, 0x0006, 0x00e6,
- 0x2091, 0x8000, 0x2071, 0xffee, 0x0021, 0x00ee, 0x000e, 0x012e,
- 0x0005, 0x2e05, 0x8000, 0x2077, 0x1220, 0x8e70, 0x2e05, 0x8000,
- 0x2077, 0x0005, 0x00e6, 0x2071, 0xffec, 0x0c99, 0x00ee, 0x0005,
- 0x00e6, 0x2071, 0xfff0, 0x0c69, 0x00ee, 0x0005, 0x0126, 0x0006,
- 0x00e6, 0x2091, 0x8000, 0x2071, 0x1840, 0x7014, 0x8000, 0x7016,
- 0x00ee, 0x000e, 0x012e, 0x0005, 0x0003, 0x000b, 0x07c8, 0x0000,
- 0xc000, 0x0001, 0x8064, 0x0008, 0x0010, 0x0000, 0x8066, 0x0000,
- 0x0101, 0x0008, 0x4407, 0x0003, 0x8060, 0x0000, 0x0400, 0x0000,
- 0x580d, 0x000b, 0x79bd, 0x0003, 0x5103, 0x0003, 0x4c0a, 0x0003,
- 0xbac0, 0x0009, 0x008a, 0x0000, 0x0c0a, 0x000b, 0x15fe, 0x0008,
- 0x340a, 0x0003, 0xc4c0, 0x0009, 0x7000, 0x0000, 0xffa0, 0x0001,
- 0x2000, 0x0000, 0x167d, 0x0003, 0x808c, 0x0008, 0x0001, 0x0000,
- 0x0000, 0x0007, 0x4028, 0x0000, 0x4047, 0x000a, 0x808c, 0x0008,
- 0x0002, 0x0000, 0x0822, 0x0003, 0x4022, 0x0000, 0x0028, 0x000b,
- 0x4122, 0x0008, 0x94c0, 0x0009, 0xff00, 0x0008, 0xffe0, 0x0009,
- 0x0500, 0x0008, 0x0aa8, 0x0003, 0x4447, 0x0002, 0x0ea5, 0x0003,
- 0x0bfe, 0x0008, 0x11a0, 0x0001, 0x1283, 0x0003, 0x0ca0, 0x0001,
- 0x1283, 0x0003, 0x9180, 0x0001, 0x0004, 0x0000, 0x8060, 0x0000,
- 0x0400, 0x0000, 0x7f62, 0x0008, 0x8066, 0x0000, 0x0009, 0x0008,
- 0x4436, 0x000b, 0x808c, 0x0008, 0x0000, 0x0008, 0x0060, 0x0008,
- 0x8062, 0x0008, 0x0004, 0x0000, 0x8066, 0x0000, 0x0411, 0x0000,
- 0x443e, 0x0003, 0x03fe, 0x0000, 0x43e0, 0x0001, 0x0e80, 0x000b,
- 0xc2c0, 0x0009, 0x00ff, 0x0008, 0x02e0, 0x0001, 0x0e80, 0x000b,
- 0x9180, 0x0001, 0x0005, 0x0008, 0x8060, 0x0000, 0x0400, 0x0000,
- 0x7f62, 0x0008, 0x8066, 0x0000, 0x0019, 0x0000, 0x444d, 0x000b,
- 0x0240, 0x0002, 0x0a7d, 0x000b, 0x00fe, 0x0000, 0x3280, 0x000b,
- 0x0248, 0x000a, 0x085c, 0x0003, 0x9180, 0x0001, 0x0006, 0x0008,
- 0x7f62, 0x0008, 0x8002, 0x0008, 0x0003, 0x0008, 0x8066, 0x0000,
- 0x020a, 0x0000, 0x445b, 0x0003, 0x112a, 0x0000, 0x002e, 0x0008,
- 0x022c, 0x0008, 0x3a44, 0x0002, 0x0c0a, 0x000b, 0x808c, 0x0008,
- 0x0002, 0x0000, 0x1760, 0x0008, 0x8062, 0x0008, 0x000f, 0x0008,
- 0x8066, 0x0000, 0x0011, 0x0008, 0x4468, 0x0003, 0x01fe, 0x0008,
- 0x42e0, 0x0009, 0x0e71, 0x0003, 0x00fe, 0x0000, 0x43e0, 0x0001,
- 0x0e71, 0x0003, 0x1734, 0x0000, 0x1530, 0x0000, 0x1632, 0x0008,
- 0x0d2a, 0x0008, 0x9880, 0x0001, 0x0010, 0x0000, 0x8060, 0x0000,
- 0x0400, 0x0000, 0x7f62, 0x0008, 0x8066, 0x0000, 0x1e0a, 0x0008,
- 0x447a, 0x0003, 0x808a, 0x0008, 0x0003, 0x0008, 0x1a60, 0x0000,
- 0x8062, 0x0008, 0x0002, 0x0000, 0x5880, 0x000b, 0x8066, 0x0000,
- 0x3679, 0x0000, 0x4483, 0x0003, 0x5884, 0x0003, 0x3efe, 0x0008,
- 0x7f4f, 0x0002, 0x088a, 0x000b, 0x0d00, 0x0000, 0x0092, 0x000c,
- 0x8054, 0x0008, 0x0011, 0x0008, 0x8074, 0x0000, 0x1010, 0x0008,
- 0x1efe, 0x0000, 0x300a, 0x000b, 0x00dd, 0x0004, 0x000a, 0x000b,
- 0x00fe, 0x0000, 0x349a, 0x0003, 0x1a60, 0x0000, 0x8062, 0x0008,
- 0x0007, 0x0000, 0x8066, 0x0000, 0x0231, 0x0008, 0x4499, 0x000b,
- 0x03fe, 0x0000, 0x04d0, 0x0001, 0x0cd1, 0x000b, 0x82c0, 0x0001,
- 0x1f00, 0x0000, 0xffa0, 0x0001, 0x0400, 0x0000, 0x08af, 0x0003,
- 0x14d9, 0x0003, 0x01fe, 0x0008, 0x0580, 0x0009, 0x7f06, 0x0000,
- 0x02fe, 0x0008, 0xffc0, 0x0001, 0x00ff, 0x0008, 0x0690, 0x0001,
- 0x10af, 0x0003, 0x7f08, 0x0008, 0x84c0, 0x0001, 0xff00, 0x0008,
- 0x08d1, 0x0003, 0xb9c0, 0x0009, 0x0030, 0x0008, 0x0cc0, 0x000b,
- 0x8060, 0x0000, 0x0400, 0x0000, 0x80fe, 0x0008, 0x1a0b, 0x0001,
- 0x7f62, 0x0008, 0x8066, 0x0000, 0x0409, 0x0000, 0x44b9, 0x0003,
- 0x80fe, 0x0008, 0x1a0a, 0x0009, 0x7f62, 0x0008, 0x8066, 0x0000,
- 0x040a, 0x0000, 0x44bf, 0x0003, 0x00fe, 0x0000, 0x34c7, 0x000b,
- 0x8072, 0x0000, 0x1010, 0x0008, 0x3944, 0x0002, 0x08c2, 0x000b,
- 0x00cb, 0x0003, 0x8072, 0x0000, 0x2020, 0x0008, 0x3945, 0x000a,
- 0x08c7, 0x000b, 0x3946, 0x000a, 0x0cd8, 0x000b, 0x0000, 0x0007,
- 0x3943, 0x000a, 0x08d8, 0x0003, 0x00cb, 0x0003, 0x00fe, 0x0000,
- 0x34d6, 0x000b, 0x8072, 0x0000, 0x1000, 0x0000, 0x00d8, 0x000b,
- 0x8072, 0x0000, 0x2000, 0x0000, 0x4000, 0x000f, 0x86c0, 0x0009,
- 0xfc00, 0x0008, 0x08d1, 0x0003, 0x00af, 0x000b, 0x1c60, 0x0000,
- 0x1b62, 0x0000, 0x8066, 0x0000, 0x0231, 0x0008, 0x44e1, 0x000b,
- 0x58e2, 0x0003, 0x0140, 0x0008, 0x0242, 0x0000, 0x1f43, 0x0002,
- 0x0cf0, 0x000b, 0x0d44, 0x0000, 0x0d46, 0x0008, 0x0348, 0x0008,
- 0x044a, 0x0008, 0x030a, 0x0008, 0x040c, 0x0000, 0x0d06, 0x0000,
- 0x0d08, 0x0008, 0x00f4, 0x0003, 0x0344, 0x0008, 0x0446, 0x0008,
- 0x0548, 0x0008, 0x064a, 0x0000, 0x1948, 0x000a, 0x08f7, 0x000b,
- 0x0d4a, 0x0008, 0x58f7, 0x000b, 0x3efe, 0x0008, 0x7f4f, 0x0002,
- 0x08fe, 0x000b, 0x8000, 0x0000, 0x0001, 0x0000, 0x0092, 0x000c,
- 0x8054, 0x0008, 0x0001, 0x0000, 0x8074, 0x0000, 0x2020, 0x0008,
- 0x4000, 0x000f, 0x3a40, 0x000a, 0x0c0d, 0x0003, 0x2b24, 0x0008,
- 0x2b24, 0x0008, 0x5907, 0x0003, 0x8054, 0x0008, 0x0002, 0x0000,
- 0x1242, 0x0002, 0x0955, 0x000b, 0x3a45, 0x000a, 0x0944, 0x000b,
- 0x8072, 0x0000, 0x1000, 0x0000, 0x3945, 0x000a, 0x0914, 0x000b,
- 0x8072, 0x0000, 0x3010, 0x0000, 0x1e10, 0x000a, 0x7f3c, 0x0000,
- 0x093f, 0x000b, 0x1d00, 0x0002, 0x7f3a, 0x0000, 0x0d60, 0x0000,
- 0x7f62, 0x0008, 0x8066, 0x0000, 0x0009, 0x0008, 0x451d, 0x0003,
- 0x00fe, 0x0000, 0x353c, 0x000b, 0x1c60, 0x0000, 0x8062, 0x0008,
- 0x0001, 0x0000, 0x8066, 0x0000, 0x0009, 0x0008, 0x4525, 0x000b,
- 0x00fe, 0x0000, 0x3258, 0x000b, 0x0038, 0x0000, 0x0060, 0x0008,
- 0x8062, 0x0008, 0x0019, 0x0000, 0x8066, 0x0000, 0x0009, 0x0008,
- 0x452e, 0x0003, 0x80c0, 0x0009, 0x00ff, 0x0008, 0x7f3e, 0x0008,
- 0x0d60, 0x0000, 0x0efe, 0x0008, 0x1f80, 0x0001, 0x7f62, 0x0008,
- 0x8066, 0x0000, 0x0009, 0x0008, 0x4538, 0x000b, 0x003a, 0x0008,
- 0x1dfe, 0x0000, 0x0119, 0x000b, 0x0036, 0x0008, 0x00dd, 0x0004,
- 0x0155, 0x0003, 0x8074, 0x0000, 0x2000, 0x0000, 0x8072, 0x0000,
- 0x2000, 0x0000, 0x0155, 0x0003, 0x3a44, 0x0002, 0x0a86, 0x0003,
- 0x8074, 0x0000, 0x1000, 0x0000, 0x8072, 0x0000, 0x1000, 0x0000,
- 0x2d0e, 0x0000, 0x2d0e, 0x0000, 0x3655, 0x000b, 0x26fe, 0x0008,
- 0x26fe, 0x0008, 0x2700, 0x0008, 0x2700, 0x0008, 0x00d0, 0x0009,
- 0x0d67, 0x000b, 0x8074, 0x0000, 0x4040, 0x0008, 0x5955, 0x000b,
- 0x5103, 0x0003, 0x3a46, 0x000a, 0x0d67, 0x000b, 0x3a47, 0x0002,
- 0x0962, 0x0003, 0x8054, 0x0008, 0x0004, 0x0000, 0x8074, 0x0000,
- 0x8000, 0x0000, 0x8072, 0x0000, 0x3000, 0x0008, 0x01b1, 0x0003,
- 0x92c0, 0x0009, 0x0fc8, 0x0000, 0x080a, 0x0003, 0x1246, 0x000a,
- 0x0e4f, 0x000b, 0x1a60, 0x0000, 0x8062, 0x0008, 0x0002, 0x0000,
- 0x8066, 0x0000, 0x362a, 0x0000, 0x456c, 0x0003, 0x2000, 0x0000,
- 0x2000, 0x0000, 0x2102, 0x0000, 0x2102, 0x0000, 0x2204, 0x0000,
- 0x2204, 0x0000, 0x2306, 0x0000, 0x2306, 0x0000, 0x2408, 0x0000,
- 0x2408, 0x0000, 0x250a, 0x0000, 0x250a, 0x0000, 0x260c, 0x0000,
- 0x260c, 0x0000, 0x270e, 0x0000, 0x270e, 0x0000, 0x2810, 0x0000,
- 0x2810, 0x0000, 0x2912, 0x0000, 0x2912, 0x0000, 0x1a60, 0x0000,
- 0x8062, 0x0008, 0x0007, 0x0000, 0x8066, 0x0000, 0x0052, 0x0000,
- 0x4586, 0x000b, 0x92c0, 0x0009, 0x0780, 0x0008, 0x0e6b, 0x000b,
- 0x124b, 0x0002, 0x098f, 0x0003, 0x2e4d, 0x0002, 0x2e4d, 0x0002,
- 0x0a55, 0x000b, 0x3a46, 0x000a, 0x0d9f, 0x0003, 0x5991, 0x0003,
- 0x8054, 0x0008, 0x0004, 0x0000, 0x1243, 0x000a, 0x09ad, 0x0003,
- 0x8010, 0x0008, 0x000d, 0x0000, 0x0230, 0x000c, 0x1948, 0x000a,
- 0x099c, 0x000b, 0x0225, 0x0004, 0x1810, 0x0000, 0x0230, 0x000c,
- 0x01ad, 0x000b, 0x1948, 0x000a, 0x09a3, 0x000b, 0x1243, 0x000a,
- 0x0a58, 0x0003, 0x194d, 0x000a, 0x09a7, 0x0003, 0x1243, 0x000a,
- 0x0a5f, 0x000b, 0x59a7, 0x0003, 0x8054, 0x0008, 0x0004, 0x0000,
- 0x0225, 0x0004, 0x1810, 0x0000, 0x0230, 0x000c, 0x8074, 0x0000,
- 0xf000, 0x0008, 0x8072, 0x0000, 0x3000, 0x0008, 0x0d30, 0x0000,
- 0x3a42, 0x0002, 0x0db7, 0x0003, 0x15fe, 0x0008, 0x3461, 0x000b,
- 0x000a, 0x000b, 0x8074, 0x0000, 0x0501, 0x0000, 0x8010, 0x0008,
- 0x000c, 0x0008, 0x0230, 0x000c, 0x000a, 0x000b, 0xbbe0, 0x0009,
- 0x0030, 0x0008, 0x0dcd, 0x000b, 0x18fe, 0x0000, 0x3ce0, 0x0009,
- 0x09ca, 0x000b, 0x15fe, 0x0008, 0x3ce0, 0x0009, 0x09ca, 0x000b,
- 0x0220, 0x0004, 0x8076, 0x0008, 0x0040, 0x0000, 0x021d, 0x0003,
- 0x8076, 0x0008, 0x0041, 0x0008, 0x021d, 0x0003, 0xbbe0, 0x0009,
- 0x0032, 0x0000, 0x0dd2, 0x0003, 0x3c1e, 0x0008, 0x021d, 0x0003,
- 0xbbe0, 0x0009, 0x003b, 0x0000, 0x0dd7, 0x0003, 0x3c20, 0x0000,
- 0x021d, 0x0003, 0xbbe0, 0x0009, 0x0035, 0x0008, 0x0ddd, 0x0003,
- 0x8072, 0x0000, 0x8000, 0x0000, 0x0399, 0x000b, 0xbbe0, 0x0009,
- 0x0036, 0x0008, 0x0aba, 0x0003, 0xbbe0, 0x0009, 0x0037, 0x0000,
- 0x0dfe, 0x000b, 0x18fe, 0x0000, 0x3ce0, 0x0009, 0x0dca, 0x0003,
- 0x8076, 0x0008, 0x0040, 0x0000, 0x1a60, 0x0000, 0x8062, 0x0008,
- 0x000d, 0x0000, 0x2604, 0x0008, 0x2604, 0x0008, 0x2706, 0x0008,
- 0x2706, 0x0008, 0x2808, 0x0000, 0x2808, 0x0000, 0x290a, 0x0000,
- 0x290a, 0x0000, 0x8066, 0x0000, 0x0422, 0x0000, 0x45f5, 0x0003,
- 0x0225, 0x0004, 0x8054, 0x0008, 0x0004, 0x0000, 0x8074, 0x0000,
- 0xf000, 0x0008, 0x8072, 0x0000, 0xb000, 0x0000, 0x01b1, 0x0003,
- 0xbbe0, 0x0009, 0x0038, 0x0000, 0x0e10, 0x000b, 0x18fe, 0x0000,
- 0x3ce0, 0x0009, 0x0a0d, 0x0003, 0x15fe, 0x0008, 0x3ce0, 0x0009,
- 0x0dc6, 0x0003, 0x0220, 0x0004, 0x8076, 0x0008, 0x0040, 0x0000,
- 0x8072, 0x0000, 0x8000, 0x0000, 0x027d, 0x0003, 0x8076, 0x0008,
- 0x0042, 0x0008, 0x021d, 0x0003, 0xbbe0, 0x0009, 0x0016, 0x0000,
- 0x0e1d, 0x0003, 0x8074, 0x0000, 0x0808, 0x0008, 0x3a44, 0x0002,
- 0x0c0c, 0x000b, 0x8074, 0x0000, 0x0800, 0x0000, 0x8072, 0x0000,
- 0x8000, 0x0000, 0x8000, 0x000f, 0x000a, 0x000b, 0x8072, 0x0000,
- 0x8000, 0x0000, 0x000a, 0x000b, 0x3d30, 0x000a, 0x7f00, 0x0000,
- 0xbc80, 0x0001, 0x0007, 0x0000, 0x0229, 0x000b, 0x1930, 0x000a,
- 0x7f00, 0x0000, 0x9880, 0x0001, 0x0007, 0x0000, 0x8060, 0x0000,
- 0x0400, 0x0000, 0x7f62, 0x0008, 0x8066, 0x0000, 0x000a, 0x0008,
- 0x462e, 0x0003, 0x4000, 0x000f, 0x2233, 0x000b, 0x0870, 0x0008,
- 0x4000, 0x000f, 0x7e30, 0x000b, 0xbbe0, 0x0009, 0x0030, 0x0008,
- 0x0e30, 0x0003, 0x18fe, 0x0000, 0x3ce0, 0x0009, 0x0a41, 0x000b,
- 0x15fe, 0x0008, 0x3ce0, 0x0009, 0x0a41, 0x000b, 0x0220, 0x0004,
- 0x8076, 0x0008, 0x0040, 0x0000, 0x0243, 0x000b, 0x8076, 0x0008,
- 0x0041, 0x0008, 0x8072, 0x0000, 0x8000, 0x0000, 0x0230, 0x0003,
- 0xbac0, 0x0009, 0x0090, 0x0008, 0x0a4c, 0x0003, 0x8074, 0x0000,
- 0x0706, 0x0000, 0x024e, 0x0003, 0x8074, 0x0000, 0x0703, 0x0000,
- 0x4000, 0x000f, 0x8010, 0x0008, 0x0023, 0x0000, 0x028b, 0x0003,
- 0x8010, 0x0008, 0x0008, 0x0000, 0x028b, 0x0003, 0x8010, 0x0008,
- 0x0022, 0x0008, 0x028b, 0x0003, 0x0225, 0x0004, 0x8010, 0x0008,
- 0x0007, 0x0000, 0x0230, 0x000c, 0x1810, 0x0000, 0x0230, 0x000c,
- 0x0297, 0x000b, 0x0225, 0x0004, 0x8010, 0x0008, 0x001b, 0x0008,
- 0x0230, 0x000c, 0x1810, 0x0000, 0x0230, 0x000c, 0x8074, 0x0000,
- 0xf080, 0x0000, 0x8072, 0x0000, 0x3000, 0x0008, 0x0d30, 0x0000,
- 0x000a, 0x000b, 0x8010, 0x0008, 0x0009, 0x0008, 0x028b, 0x0003,
- 0x8010, 0x0008, 0x0005, 0x0008, 0x028b, 0x0003, 0x1648, 0x000a,
- 0x0c6f, 0x000b, 0x808c, 0x0008, 0x0001, 0x0000, 0x8010, 0x0008,
- 0x0004, 0x0000, 0x4143, 0x000a, 0x086f, 0x0003, 0x3a44, 0x0002,
- 0x0c0a, 0x000b, 0x0d2a, 0x0008, 0x028b, 0x0003, 0x8010, 0x0008,
- 0x0003, 0x0008, 0x028f, 0x000b, 0x8010, 0x0008, 0x000b, 0x0000,
- 0x028f, 0x000b, 0x8010, 0x0008, 0x0002, 0x0000, 0x028f, 0x000b,
- 0x3a47, 0x0002, 0x0d55, 0x0003, 0x8010, 0x0008, 0x0006, 0x0008,
- 0x028f, 0x000b, 0x8074, 0x0000, 0xf000, 0x0008, 0x8072, 0x0000,
- 0x3000, 0x0008, 0x0230, 0x000c, 0x0246, 0x0004, 0x3a40, 0x000a,
- 0x080a, 0x0003, 0x8010, 0x0008, 0x000c, 0x0008, 0x0230, 0x000c,
- 0x000a, 0x000b, 0x8074, 0x0000, 0xf080, 0x0000, 0x8072, 0x0000,
- 0x3000, 0x0008, 0x0d30, 0x0000, 0x2e4d, 0x0002, 0x2e4d, 0x0002,
- 0x0aa2, 0x0003, 0x8054, 0x0008, 0x0019, 0x0000, 0x000a, 0x000b,
- 0x8054, 0x0008, 0x0009, 0x0008, 0x000a, 0x000b, 0x3a44, 0x0002,
- 0x0c0a, 0x000b, 0x0280, 0x000b, 0x808c, 0x0008, 0x0000, 0x0008,
- 0x4447, 0x0002, 0x0ace, 0x0003, 0xc0c0, 0x0001, 0x00ff, 0x0008,
- 0xffe0, 0x0009, 0x00ff, 0x0008, 0x0ea5, 0x0003, 0xc1e0, 0x0001,
- 0xffff, 0x0008, 0x0ea5, 0x0003, 0x8010, 0x0008, 0x0013, 0x0000,
- 0x0230, 0x000c, 0x8074, 0x0000, 0x0202, 0x0008, 0x000a, 0x000b,
- 0x3a40, 0x000a, 0x0ecb, 0x000b, 0x8074, 0x0000, 0x0200, 0x0000,
- 0x3d00, 0x0000, 0x3cfe, 0x0000, 0x8072, 0x0000, 0x8000, 0x0000,
- 0x43e0, 0x0001, 0x0ec9, 0x0003, 0x42fe, 0x0000, 0xffc0, 0x0001,
- 0x00ff, 0x0008, 0x00e0, 0x0009, 0x0aa5, 0x000b, 0x0d08, 0x0008,
- 0x031e, 0x000b, 0x8072, 0x0000, 0x8000, 0x0000, 0x000a, 0x000b,
- 0x03a2, 0x000c, 0x808c, 0x0008, 0x0001, 0x0000, 0x04fe, 0x0008,
- 0x3385, 0x0003, 0x0460, 0x0000, 0x8062, 0x0008, 0x0001, 0x0000,
- 0x8066, 0x0000, 0x0009, 0x0008, 0x46d8, 0x0003, 0x0004, 0x0000,
- 0x80c0, 0x0009, 0x00ff, 0x0008, 0x7f00, 0x0000, 0x80e0, 0x0001,
- 0x0004, 0x0000, 0x0af2, 0x0003, 0x80e0, 0x0001, 0x0005, 0x0008,
- 0x0af2, 0x0003, 0x80e0, 0x0001, 0x0006, 0x0008, 0x0af2, 0x0003,
- 0x82c0, 0x0001, 0xff00, 0x0008, 0x7f04, 0x0008, 0x82e0, 0x0009,
- 0x0600, 0x0008, 0x0af2, 0x0003, 0x82e0, 0x0009, 0x0500, 0x0008,
- 0x0af2, 0x0003, 0x82e0, 0x0009, 0x0400, 0x0000, 0x0f85, 0x0003,
- 0xc4c0, 0x0009, 0x7000, 0x0000, 0xffe0, 0x0009, 0x1000, 0x0000,
- 0x0b1e, 0x0003, 0x0393, 0x0004, 0x3941, 0x0002, 0x0afd, 0x0003,
- 0x8072, 0x0000, 0x0400, 0x0000, 0x000a, 0x000b, 0x0460, 0x0000,
- 0x80fe, 0x0008, 0x002b, 0x0008, 0x7f62, 0x0008, 0x8066, 0x0000,
- 0x2209, 0x0008, 0x4703, 0x000b, 0x11fe, 0x0000, 0x3319, 0x0003,
- 0x9180, 0x0001, 0x0002, 0x0000, 0x8060, 0x0000, 0x0400, 0x0000,
- 0x7f62, 0x0008, 0x8066, 0x0000, 0x0609, 0x0008, 0x470d, 0x0003,
- 0x42fe, 0x0000, 0xffc0, 0x0001, 0xff00, 0x0008, 0x03e0, 0x0009,
- 0x0f16, 0x0003, 0x8072, 0x0000, 0x0400, 0x0000, 0x0046, 0x0003,
- 0x9180, 0x0001, 0x0003, 0x0008, 0x0300, 0x000b, 0x8072, 0x0000,
- 0x0400, 0x0000, 0x8010, 0x0008, 0x0010, 0x0000, 0x0376, 0x0003,
- 0x0393, 0x0004, 0x3941, 0x0002, 0x0b24, 0x0003, 0x8072, 0x0000,
- 0x0400, 0x0000, 0x000a, 0x000b, 0x035b, 0x000c, 0x11fe, 0x0000,
- 0x372c, 0x000b, 0x8072, 0x0000, 0x0400, 0x0000, 0x8010, 0x0008,
- 0x000e, 0x0000, 0x0376, 0x0003, 0x8060, 0x0000, 0x0400, 0x0000,
- 0x04fe, 0x0008, 0x3741, 0x0003, 0x808c, 0x0008, 0x0000, 0x0008,
- 0x9180, 0x0001, 0x0005, 0x0008, 0x7f62, 0x0008, 0x8066, 0x0000,
- 0x0009, 0x0008, 0x4737, 0x0003, 0x0060, 0x0008, 0x8062, 0x0008,
- 0x001b, 0x0008, 0x4304, 0x0008, 0x4206, 0x0008, 0x8066, 0x0000,
- 0x0412, 0x0000, 0x473f, 0x000b, 0x0358, 0x0003, 0x808c, 0x0008,
- 0x0001, 0x0000, 0x0460, 0x0000, 0x8062, 0x0008, 0x002b, 0x0008,
- 0x8066, 0x0000, 0x0609, 0x0008, 0x4748, 0x000b, 0x8066, 0x0000,
- 0x220a, 0x0008, 0x474b, 0x000b, 0x42fe, 0x0000, 0xffc0, 0x0001,
- 0xff00, 0x0008, 0x7f04, 0x0008, 0x8060, 0x0000, 0x0400, 0x0000,
- 0x9180, 0x0001, 0x0002, 0x0000, 0x7f62, 0x0008, 0x8066, 0x0000,
- 0x041a, 0x0008, 0x4757, 0x0003, 0x8072, 0x0000, 0x0400, 0x0000,
- 0x0046, 0x0003, 0x8060, 0x0000, 0x0400, 0x0000, 0x1362, 0x0008,
- 0x8066, 0x0000, 0x0411, 0x0000, 0x4760, 0x000b, 0x02fe, 0x0008,
- 0x03e0, 0x0009, 0x0f66, 0x000b, 0x0d22, 0x0000, 0x4000, 0x000f,
- 0x8280, 0x0009, 0x0002, 0x0000, 0x1380, 0x0001, 0x7f62, 0x0008,
- 0x8066, 0x0000, 0x2209, 0x0008, 0x476c, 0x000b, 0x0200, 0x000a,
- 0xffc0, 0x0001, 0x0007, 0x0000, 0x7f06, 0x0000, 0x1362, 0x0008,
- 0x8066, 0x0000, 0x060a, 0x0008, 0x4774, 0x000b, 0x4000, 0x000f,
- 0x3a44, 0x0002, 0x0c0a, 0x000b, 0x2f44, 0x000a, 0x2f44, 0x000a,
- 0x0e80, 0x000b, 0x808a, 0x0008, 0x0003, 0x0008, 0x8074, 0x0000,
- 0xf080, 0x0000, 0x8072, 0x0000, 0x3000, 0x0008, 0x5b81, 0x0003,
- 0x8054, 0x0008, 0x0019, 0x0000, 0x000a, 0x000b, 0x3a44, 0x0002,
- 0x0c0a, 0x000b, 0x808c, 0x0008, 0x0000, 0x0008, 0x8010, 0x0008,
- 0x0011, 0x0008, 0x0230, 0x000c, 0x42fe, 0x0000, 0xffc0, 0x0001,
- 0x00ff, 0x0008, 0x7f10, 0x0008, 0x0230, 0x000c, 0x4310, 0x0008,
- 0x028f, 0x000b, 0x3941, 0x0002, 0x0b96, 0x0003, 0x4000, 0x000f,
- 0x8072, 0x0000, 0x0404, 0x0008, 0x4000, 0x000f, 0x8010, 0x0008,
- 0x0012, 0x0008, 0x0230, 0x000c, 0x035b, 0x000c, 0x1110, 0x0000,
- 0x0230, 0x000c, 0x11fe, 0x0000, 0x379c, 0x0003, 0x000a, 0x000b,
- 0xc2c0, 0x0009, 0x00ff, 0x0008, 0x7f00, 0x0000, 0xc3c0, 0x0001,
- 0xff00, 0x0008, 0x00d0, 0x0009, 0x0bc7, 0x000b, 0x0d0a, 0x0000,
- 0x8580, 0x0001, 0x1000, 0x0000, 0x7f62, 0x0008, 0x8060, 0x0000,
- 0x0400, 0x0000, 0x8066, 0x0000, 0x0809, 0x0000, 0x47b1, 0x000b,
- 0x04fe, 0x0008, 0x33c0, 0x000b, 0x0460, 0x0000, 0x8062, 0x0008,
- 0x0004, 0x0000, 0x8066, 0x0000, 0x0211, 0x0000, 0x47b9, 0x0003,
- 0x01fe, 0x0008, 0x00e0, 0x0009, 0x0fc0, 0x000b, 0x02fe, 0x0008,
- 0x43e0, 0x0001, 0x0bc6, 0x0003, 0x0500, 0x0002, 0x7f0a, 0x0000,
- 0xffe0, 0x0009, 0x0800, 0x0000, 0x0faa, 0x000b, 0x0d08, 0x0008,
- 0x4000, 0x000f, 0x43fe, 0x0008, 0x3e80, 0x0001, 0xffc0, 0x0001,
- 0x7fff, 0x0000, 0x0d60, 0x0000, 0x7f62, 0x0008, 0x8066, 0x0000,
- 0x0809, 0x0000, 0x47cf, 0x000b, 0x8060, 0x0000, 0x0400, 0x0000,
- 0x84c0, 0x0001, 0xff00, 0x0008, 0x7f60, 0x000a, 0x7f60, 0x000a,
- 0x7f60, 0x000a, 0x7f60, 0x000a, 0x7f60, 0x000a, 0x7f60, 0x000a,
- 0x7f60, 0x000a, 0x7f60, 0x000a, 0xff80, 0x0009, 0x1000, 0x0000,
- 0x7f62, 0x0008, 0x8066, 0x0000, 0x0809, 0x0000, 0x47e1, 0x000b,
- 0x4000, 0x000f, 0xb10e, 0xebeb, 0x0001, 0x0002, 0x0004, 0x0008,
- 0x0010, 0x0020, 0x0040, 0x0080, 0x0100, 0x0200, 0x0400, 0x0800,
- 0x1000, 0x2000, 0x4000, 0x8000, 0x393e
+ 0x0005, 0x00b6, 0x0066, 0x6610, 0x2658, 0xbe04, 0x96b4, 0xff00,
+ 0x8637, 0x9686, 0x0006, 0x0170, 0x9686, 0x0004, 0x0158, 0xbe04,
+ 0x96b4, 0x00ff, 0x9686, 0x0006, 0x0128, 0x9686, 0x0004, 0x0110,
+ 0x9085, 0x0001, 0x006e, 0x00be, 0x0005, 0x00d6, 0x080c, 0xdce1,
+ 0x00de, 0x0005, 0x00d6, 0x080c, 0xdcee, 0x1520, 0x680c, 0x908c,
+ 0xff00, 0x6820, 0x9084, 0x00ff, 0x9115, 0x6216, 0x6824, 0x602e,
+ 0xd1e4, 0x0130, 0x9006, 0x080c, 0xed6f, 0x2009, 0x0001, 0x0078,
+ 0xd1ec, 0x0180, 0x6920, 0x918c, 0x00ff, 0x6824, 0x080c, 0x2894,
+ 0x1148, 0x2001, 0x0001, 0x080c, 0xed6f, 0x2110, 0x900e, 0x080c,
+ 0x328f, 0x0018, 0x9085, 0x0001, 0x0008, 0x9006, 0x00de, 0x0005,
+ 0x00b6, 0x00c6, 0x080c, 0xb153, 0x05a8, 0x0016, 0x0026, 0x00c6,
+ 0x2011, 0x0263, 0x2204, 0x8211, 0x220c, 0x080c, 0x2894, 0x1578,
+ 0x080c, 0x66b2, 0x1560, 0xbe12, 0xbd16, 0x00ce, 0x002e, 0x001e,
+ 0x2b00, 0x6012, 0x080c, 0xeba1, 0x11d8, 0x080c, 0x336a, 0x11c0,
+ 0x080c, 0xdc49, 0x0510, 0x2001, 0x0007, 0x080c, 0x6663, 0x2001,
+ 0x0007, 0x080c, 0x668f, 0x6017, 0x0000, 0x6023, 0x0001, 0x6007,
+ 0x0001, 0x6003, 0x0001, 0x080c, 0x9383, 0x080c, 0x98ed, 0x0010,
+ 0x080c, 0xb101, 0x9085, 0x0001, 0x00ce, 0x00be, 0x0005, 0x080c,
+ 0xb101, 0x00ce, 0x002e, 0x001e, 0x0ca8, 0x080c, 0xb101, 0x9006,
+ 0x0c98, 0x2069, 0x026d, 0x6800, 0x9082, 0x0010, 0x1228, 0x6017,
+ 0x0000, 0x9085, 0x0001, 0x0008, 0x9006, 0x0005, 0x6017, 0x0000,
+ 0x2069, 0x026c, 0x6808, 0x9084, 0xff00, 0x9086, 0x0800, 0x1190,
+ 0x6904, 0x9186, 0x0018, 0x0118, 0x9186, 0x0014, 0x1158, 0x810f,
+ 0x6800, 0x9084, 0x00ff, 0x910d, 0x615a, 0x908e, 0x0014, 0x0110,
+ 0x908e, 0x0010, 0x0005, 0x6004, 0x90b2, 0x0053, 0x1a0c, 0x0dc5,
+ 0x91b6, 0x0013, 0x1130, 0x2008, 0x91b2, 0x0040, 0x1a04, 0xde50,
+ 0x040a, 0x91b6, 0x0027, 0x0198, 0x9186, 0x0015, 0x0118, 0x9186,
+ 0x0016, 0x1148, 0x080c, 0xd587, 0x0128, 0x6000, 0x9086, 0x0002,
+ 0x0904, 0xbb29, 0x0005, 0x91b6, 0x0014, 0x190c, 0x0dc5, 0x2001,
+ 0x0007, 0x080c, 0x668f, 0x080c, 0x97e1, 0x080c, 0xb134, 0x080c,
+ 0x98ed, 0x0005, 0xdd7a, 0xdd7c, 0xdd7a, 0xdd7a, 0xdd7a, 0xdd7c,
+ 0xdd8b, 0xde49, 0xddcf, 0xde49, 0xddf7, 0xde49, 0xdd8b, 0xde49,
+ 0xde41, 0xde49, 0xde41, 0xde49, 0xde49, 0xdd7a, 0xdd7a, 0xdd7a,
+ 0xdd7a, 0xdd7a, 0xdd7a, 0xdd7a, 0xdd7a, 0xdd7a, 0xdd7a, 0xdd7a,
+ 0xdd7c, 0xdd7a, 0xde49, 0xdd7a, 0xdd7a, 0xde49, 0xdd7a, 0xde46,
+ 0xde49, 0xdd7a, 0xdd7a, 0xdd7a, 0xdd7a, 0xde49, 0xde49, 0xdd7a,
+ 0xde49, 0xde49, 0xdd7a, 0xdd86, 0xdd7a, 0xdd7a, 0xdd7a, 0xdd7a,
+ 0xde45, 0xde49, 0xdd7a, 0xdd7a, 0xde49, 0xde49, 0xdd7a, 0xdd7a,
+ 0xdd7a, 0xdd7a, 0x080c, 0x0dc5, 0x080c, 0x97e1, 0x080c, 0xd579,
+ 0x6003, 0x0002, 0x080c, 0x98ed, 0x0804, 0xde4f, 0x9006, 0x080c,
+ 0x664f, 0x0804, 0xde49, 0x080c, 0x6a8a, 0x1904, 0xde49, 0x9006,
+ 0x080c, 0x664f, 0x6010, 0x2058, 0xb810, 0x9086, 0x00ff, 0x1140,
+ 0x00f6, 0x2079, 0x1800, 0x78a8, 0x8000, 0x78aa, 0x00fe, 0x00b8,
+ 0x6010, 0x2058, 0xb8c0, 0x9005, 0x0904, 0xde49, 0x080c, 0x339b,
+ 0x1904, 0xde49, 0x2001, 0x1800, 0x2004, 0x9086, 0x0002, 0x1138,
+ 0x00f6, 0x2079, 0x1800, 0x78a8, 0x8000, 0x78aa, 0x00fe, 0x2001,
+ 0x0002, 0x080c, 0x6663, 0x080c, 0x97e1, 0x6023, 0x0001, 0x6003,
+ 0x0001, 0x6007, 0x0002, 0x080c, 0x9383, 0x080c, 0x98ed, 0x6110,
+ 0x2158, 0x2009, 0x0001, 0x080c, 0x8717, 0x0804, 0xde4f, 0x6610,
+ 0x2658, 0xbe04, 0x96b4, 0xff00, 0x8637, 0x9686, 0x0006, 0x0148,
+ 0x9686, 0x0004, 0x0130, 0x080c, 0x8efa, 0x2001, 0x0004, 0x080c,
+ 0x668f, 0x080c, 0xedbe, 0x0904, 0xde49, 0x080c, 0x97e1, 0x2001,
+ 0x0004, 0x080c, 0x6663, 0x6023, 0x0001, 0x6003, 0x0001, 0x6007,
+ 0x0003, 0x080c, 0x9383, 0x080c, 0x98ed, 0x0804, 0xde4f, 0x2001,
+ 0x1800, 0x2004, 0x9086, 0x0003, 0x1158, 0x0036, 0x0046, 0x6010,
+ 0x2058, 0xbba0, 0x2021, 0x0006, 0x080c, 0x4da0, 0x004e, 0x003e,
+ 0x2001, 0x0006, 0x080c, 0xde6d, 0x6610, 0x2658, 0xbe04, 0x0066,
+ 0x96b4, 0xff00, 0x8637, 0x9686, 0x0006, 0x006e, 0x0180, 0x2001,
+ 0x0006, 0x080c, 0x668f, 0x9284, 0x00ff, 0x908e, 0x0007, 0x0118,
+ 0x908e, 0x0004, 0x1120, 0x2001, 0x0006, 0x080c, 0x6663, 0x080c,
+ 0x6a8a, 0x11f8, 0x2001, 0x1837, 0x2004, 0xd0a4, 0x01d0, 0xbe04,
+ 0x96b4, 0x00ff, 0x9686, 0x0006, 0x01a0, 0x00f6, 0x2079, 0x1800,
+ 0x78a8, 0x8000, 0x78aa, 0x00fe, 0x0804, 0xddb7, 0x2001, 0x0004,
+ 0x0030, 0x2001, 0x0006, 0x0449, 0x0020, 0x0018, 0x0010, 0x080c,
+ 0x668f, 0x080c, 0x97e1, 0x080c, 0xb101, 0x080c, 0x98ed, 0x0005,
+ 0x2600, 0x0002, 0xde64, 0xde64, 0xde64, 0xde64, 0xde64, 0xde66,
+ 0xde64, 0xde66, 0xde64, 0xde64, 0xde66, 0xde64, 0xde64, 0xde64,
+ 0xde66, 0xde66, 0xde66, 0xde66, 0x080c, 0x0dc5, 0x080c, 0x97e1,
+ 0x080c, 0xb101, 0x080c, 0x98ed, 0x0005, 0x0016, 0x00b6, 0x00d6,
+ 0x6110, 0x2158, 0xb900, 0xd184, 0x0138, 0x080c, 0x6663, 0x9006,
+ 0x080c, 0x664f, 0x080c, 0x326f, 0x00de, 0x00be, 0x001e, 0x0005,
+ 0x6610, 0x2658, 0xb804, 0x9084, 0xff00, 0x8007, 0x90b2, 0x000c,
+ 0x1a0c, 0x0dc5, 0x91b6, 0x0015, 0x1110, 0x003b, 0x0028, 0x91b6,
+ 0x0016, 0x190c, 0x0dc5, 0x006b, 0x0005, 0xbbcb, 0xbbcb, 0xbbcb,
+ 0xbbcb, 0xdf02, 0xbbcb, 0xdeec, 0xdead, 0xbbcb, 0xbbcb, 0xbbcb,
+ 0xbbcb, 0xbbcb, 0xbbcb, 0xbbcb, 0xbbcb, 0xdf02, 0xbbcb, 0xdeec,
+ 0xdef3, 0xbbcb, 0xbbcb, 0xbbcb, 0xbbcb, 0x00f6, 0x080c, 0x6a8a,
+ 0x11d8, 0x080c, 0xd561, 0x11c0, 0x6010, 0x905d, 0x01a8, 0xb8c0,
+ 0x9005, 0x0190, 0x9006, 0x080c, 0x664f, 0x2001, 0x0002, 0x080c,
+ 0x6663, 0x6023, 0x0001, 0x6003, 0x0001, 0x6007, 0x0002, 0x080c,
+ 0x9383, 0x080c, 0x98ed, 0x00f0, 0x2011, 0x0263, 0x2204, 0x8211,
+ 0x220c, 0x080c, 0x2894, 0x11b0, 0x080c, 0x671d, 0x0118, 0x080c,
+ 0xb101, 0x0080, 0xb810, 0x0006, 0xb814, 0x0006, 0xb8c0, 0x0006,
+ 0x080c, 0x6141, 0x000e, 0xb8c2, 0x000e, 0xb816, 0x000e, 0xb812,
+ 0x080c, 0xb101, 0x00fe, 0x0005, 0x6604, 0x96b6, 0x001e, 0x1110,
+ 0x080c, 0xb101, 0x0005, 0x080c, 0xbf5a, 0x1148, 0x6003, 0x0001,
+ 0x6007, 0x0001, 0x080c, 0x9383, 0x080c, 0x98ed, 0x0010, 0x080c,
+ 0xb101, 0x0005, 0x0804, 0xb101, 0x6004, 0x908a, 0x0053, 0x1a0c,
+ 0x0dc5, 0x080c, 0x97e1, 0x080c, 0xb134, 0x080c, 0x98ed, 0x0005,
+ 0x9182, 0x0040, 0x0002, 0xdf27, 0xdf27, 0xdf27, 0xdf27, 0xdf29,
+ 0xdf27, 0xdf27, 0xdf27, 0xdf27, 0xdf27, 0xdf27, 0xdf27, 0xdf27,
+ 0xdf27, 0xdf27, 0xdf27, 0xdf27, 0xdf27, 0xdf27, 0xdf27, 0x080c,
+ 0x0dc5, 0x0096, 0x00b6, 0x00d6, 0x00e6, 0x00f6, 0x0046, 0x0026,
+ 0x6210, 0x2258, 0xb8bc, 0x9005, 0x11a8, 0x6106, 0x2071, 0x0260,
+ 0x7444, 0x94a4, 0xff00, 0x0904, 0xdf8f, 0x080c, 0xed63, 0x1170,
+ 0x9486, 0x2000, 0x1158, 0x2009, 0x0001, 0x2011, 0x0200, 0x080c,
+ 0x891c, 0x0020, 0x9026, 0x080c, 0xebe6, 0x0c38, 0x080c, 0x100e,
+ 0x090c, 0x0dc5, 0x6003, 0x0007, 0xa867, 0x010d, 0x9006, 0xa802,
+ 0xa86a, 0xac8a, 0x2c00, 0xa88e, 0x6008, 0xa8e2, 0x6010, 0x2058,
+ 0xb8a0, 0x7130, 0xa97a, 0x0016, 0xa876, 0xa87f, 0x0000, 0xa883,
+ 0x0000, 0xa887, 0x0036, 0x080c, 0x6dd1, 0x001e, 0x080c, 0xed63,
+ 0x1904, 0xdfef, 0x9486, 0x2000, 0x1130, 0x2019, 0x0017, 0x080c,
+ 0xe915, 0x0804, 0xdfef, 0x9486, 0x0200, 0x1120, 0x080c, 0xe8ac,
+ 0x0804, 0xdfef, 0x9486, 0x0400, 0x0120, 0x9486, 0x1000, 0x1904,
+ 0xdfef, 0x2019, 0x0002, 0x080c, 0xe8c7, 0x0804, 0xdfef, 0x2069,
+ 0x1a75, 0x6a00, 0xd284, 0x0904, 0xe059, 0x9284, 0x0300, 0x1904,
+ 0xe052, 0x6804, 0x9005, 0x0904, 0xe03a, 0x2d78, 0x6003, 0x0007,
+ 0x080c, 0x1027, 0x0904, 0xdffb, 0x7800, 0xd08c, 0x1118, 0x7804,
+ 0x8001, 0x7806, 0x6017, 0x0000, 0x2001, 0x180f, 0x2004, 0xd084,
+ 0x1904, 0xe05d, 0x9006, 0xa802, 0xa867, 0x0116, 0xa86a, 0x6008,
+ 0xa8e2, 0x2c00, 0xa87a, 0x6010, 0x2058, 0xb8a0, 0x7130, 0xa9b6,
+ 0xa876, 0xb928, 0xa9ba, 0xb92c, 0xa9be, 0xb930, 0xa9c2, 0xb934,
+ 0xa9c6, 0xa883, 0x003d, 0x7044, 0x9084, 0x0003, 0x9080, 0xdff7,
+ 0x2005, 0xa87e, 0x20a9, 0x000a, 0x2001, 0x0270, 0xaa5c, 0x9290,
+ 0x0021, 0x2009, 0x0205, 0x200b, 0x0080, 0x20e1, 0x0000, 0xab60,
+ 0x23e8, 0x2098, 0x22a0, 0x4003, 0x200b, 0x0000, 0x2001, 0x027a,
+ 0x200c, 0xa9b2, 0x8000, 0x200c, 0xa9ae, 0x080c, 0x6dd1, 0x002e,
+ 0x004e, 0x00fe, 0x00ee, 0x00de, 0x00be, 0x009e, 0x0005, 0x0000,
+ 0x0080, 0x0040, 0x0000, 0x2001, 0x1810, 0x2004, 0xd084, 0x0120,
+ 0x080c, 0x100e, 0x1904, 0xdfa4, 0x6017, 0xf100, 0x6003, 0x0001,
+ 0x6007, 0x0041, 0x080c, 0x933b, 0x080c, 0x98ed, 0x0c00, 0x2069,
+ 0x0260, 0x6848, 0x9084, 0xff00, 0x9086, 0x1200, 0x1198, 0x686c,
+ 0x9084, 0x00ff, 0x0016, 0x6114, 0x918c, 0xf700, 0x910d, 0x6116,
+ 0x001e, 0x6003, 0x0001, 0x6007, 0x0043, 0x080c, 0x933b, 0x080c,
+ 0x98ed, 0x0828, 0x6868, 0x602e, 0x686c, 0x6032, 0x6017, 0xf200,
+ 0x6003, 0x0001, 0x6007, 0x0041, 0x080c, 0x933b, 0x080c, 0x98ed,
+ 0x0804, 0xdfef, 0x2001, 0x180e, 0x2004, 0xd0ec, 0x0120, 0x2011,
+ 0x8049, 0x080c, 0x4be9, 0x6017, 0xf300, 0x0010, 0x6017, 0xf100,
+ 0x6003, 0x0001, 0x6007, 0x0041, 0x080c, 0x933b, 0x080c, 0x98ed,
+ 0x0804, 0xdfef, 0x6017, 0xf500, 0x0c98, 0x6017, 0xf600, 0x0804,
+ 0xe00f, 0x6017, 0xf200, 0x0804, 0xe00f, 0xa867, 0x0146, 0xa86b,
+ 0x0000, 0x6008, 0xa886, 0x2c00, 0xa87a, 0x7044, 0x9084, 0x0003,
+ 0x9080, 0xdff7, 0x2005, 0xa87e, 0x2928, 0x6010, 0x2058, 0xb8a0,
+ 0xa876, 0xb828, 0xa88a, 0xb82c, 0xa88e, 0xb830, 0xa892, 0xb834,
+ 0xa896, 0xa883, 0x003d, 0x2009, 0x0205, 0x2104, 0x9085, 0x0080,
+ 0x200a, 0x20e1, 0x0000, 0x2011, 0x0210, 0x2214, 0x9294, 0x0fff,
+ 0xaaa2, 0x9282, 0x0111, 0x1a0c, 0x0dc5, 0x8210, 0x821c, 0x2001,
+ 0x026c, 0x2098, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0029, 0x20a0,
+ 0x2011, 0xe0d9, 0x2041, 0x0001, 0x223d, 0x9784, 0x00ff, 0x9322,
+ 0x1208, 0x2300, 0x20a8, 0x4003, 0x931a, 0x0530, 0x8210, 0xd7fc,
+ 0x1130, 0x8d68, 0x2d0a, 0x2001, 0x0260, 0x2098, 0x0c68, 0x2950,
+ 0x080c, 0x1027, 0x0170, 0x2900, 0xb002, 0xa867, 0x0147, 0xa86b,
+ 0x0000, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x001b, 0x20a0, 0x8840,
+ 0x08d8, 0x2548, 0xa800, 0x902d, 0x0118, 0x080c, 0x1040, 0x0cc8,
+ 0x080c, 0x1040, 0x0804, 0xdffb, 0x2548, 0x8847, 0x9885, 0x0046,
+ 0xa866, 0x2009, 0x0205, 0x200b, 0x0000, 0x080c, 0xe948, 0x0804,
+ 0xdfef, 0x8010, 0x0004, 0x801a, 0x0006, 0x8018, 0x0008, 0x8016,
+ 0x000a, 0x8014, 0x9186, 0x0013, 0x1160, 0x6004, 0x908a, 0x0054,
+ 0x1a0c, 0x0dc5, 0x9082, 0x0040, 0x0a0c, 0x0dc5, 0x2008, 0x0804,
+ 0xe168, 0x9186, 0x0051, 0x0108, 0x0048, 0x080c, 0xd587, 0x0500,
+ 0x6000, 0x9086, 0x0002, 0x11e0, 0x0804, 0xe1b1, 0x9186, 0x0027,
+ 0x0190, 0x9186, 0x0048, 0x0128, 0x9186, 0x0014, 0x0160, 0x190c,
+ 0x0dc5, 0x080c, 0xd587, 0x0160, 0x6000, 0x9086, 0x0004, 0x190c,
+ 0x0dc5, 0x0804, 0xe294, 0x6004, 0x9082, 0x0040, 0x2008, 0x001a,
+ 0x080c, 0xb19b, 0x0005, 0xe12f, 0xe131, 0xe131, 0xe158, 0xe12f,
+ 0xe12f, 0xe12f, 0xe12f, 0xe12f, 0xe12f, 0xe12f, 0xe12f, 0xe12f,
+ 0xe12f, 0xe12f, 0xe12f, 0xe12f, 0xe12f, 0xe12f, 0xe12f, 0x080c,
+ 0x0dc5, 0x080c, 0x97e1, 0x080c, 0x98ed, 0x0036, 0x0096, 0x6014,
+ 0x904d, 0x01d8, 0x080c, 0xce56, 0x01c0, 0x6003, 0x0002, 0x6010,
+ 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x1178, 0x2019, 0x0004,
+ 0x080c, 0xe948, 0x6017, 0x0000, 0x6018, 0x9005, 0x1120, 0x2001,
+ 0x1988, 0x2004, 0x601a, 0x6003, 0x0007, 0x009e, 0x003e, 0x0005,
+ 0x0096, 0x080c, 0x97e1, 0x080c, 0x98ed, 0x080c, 0xce56, 0x0120,
+ 0x6014, 0x2048, 0x080c, 0x1040, 0x080c, 0xb134, 0x009e, 0x0005,
+ 0x0002, 0xe17d, 0xe194, 0xe17f, 0xe1ab, 0xe17d, 0xe17d, 0xe17d,
+ 0xe17d, 0xe17d, 0xe17d, 0xe17d, 0xe17d, 0xe17d, 0xe17d, 0xe17d,
+ 0xe17d, 0xe17d, 0xe17d, 0xe17d, 0xe17d, 0x080c, 0x0dc5, 0x0096,
+ 0x080c, 0x97e1, 0x6014, 0x2048, 0xa87c, 0xd0b4, 0x0138, 0x6003,
+ 0x0007, 0x2009, 0x0043, 0x080c, 0xb180, 0x0010, 0x6003, 0x0004,
+ 0x080c, 0x98ed, 0x009e, 0x0005, 0x080c, 0x97e1, 0x080c, 0xce56,
+ 0x0138, 0x6114, 0x0096, 0x2148, 0xa97c, 0x009e, 0xd1ec, 0x1138,
+ 0x080c, 0x88f1, 0x080c, 0xb101, 0x080c, 0x98ed, 0x0005, 0x080c,
+ 0xebaa, 0x0db0, 0x0cc8, 0x080c, 0x97e1, 0x2009, 0x0041, 0x0804,
+ 0xe31c, 0x9182, 0x0040, 0x0002, 0xe1c8, 0xe1ca, 0xe1c8, 0xe1c8,
+ 0xe1c8, 0xe1c8, 0xe1c8, 0xe1c8, 0xe1c8, 0xe1c8, 0xe1c8, 0xe1c8,
+ 0xe1c8, 0xe1c8, 0xe1c8, 0xe1c8, 0xe1c8, 0xe1cb, 0xe1c8, 0xe1c8,
+ 0x080c, 0x0dc5, 0x0005, 0x00d6, 0x080c, 0x88f1, 0x00de, 0x080c,
+ 0xec02, 0x080c, 0xb101, 0x0005, 0x9182, 0x0040, 0x0002, 0xe1eb,
+ 0xe1eb, 0xe1eb, 0xe1eb, 0xe1eb, 0xe1eb, 0xe1eb, 0xe1eb, 0xe1eb,
+ 0xe1ed, 0xe25c, 0xe1eb, 0xe1eb, 0xe1eb, 0xe1eb, 0xe25c, 0xe1eb,
+ 0xe1eb, 0xe1eb, 0xe1eb, 0x080c, 0x0dc5, 0x2001, 0x0105, 0x2004,
+ 0x9084, 0x1800, 0x01c8, 0x2001, 0x0132, 0x200c, 0x2001, 0x0131,
+ 0x2004, 0x9105, 0x1904, 0xe25c, 0x2009, 0x180c, 0x2104, 0xd0d4,
+ 0x0904, 0xe25c, 0xc0d4, 0x200a, 0x2009, 0x0105, 0x2104, 0x9084,
+ 0xe7fd, 0x9085, 0x0010, 0x200a, 0x2001, 0x1867, 0x2004, 0xd0e4,
+ 0x1528, 0x603b, 0x0000, 0x080c, 0x989d, 0x6014, 0x0096, 0x2048,
+ 0xa87c, 0xd0fc, 0x0188, 0x908c, 0x0003, 0x918e, 0x0002, 0x0508,
+ 0x2001, 0x180c, 0x2004, 0xd0d4, 0x11e0, 0x080c, 0x9a0f, 0x2009,
+ 0x0041, 0x009e, 0x0804, 0xe31c, 0x080c, 0x9a0f, 0x6003, 0x0007,
+ 0x601b, 0x0000, 0x080c, 0x88f1, 0x009e, 0x0005, 0x2001, 0x0100,
+ 0x2004, 0x9082, 0x0005, 0x0aa8, 0x2001, 0x011f, 0x2004, 0x603a,
+ 0x0890, 0x2001, 0x180c, 0x200c, 0xc1d4, 0x2102, 0xd1cc, 0x0110,
+ 0x080c, 0x2c94, 0x080c, 0x9a0f, 0x6014, 0x2048, 0xa97c, 0xd1ec,
+ 0x1130, 0x080c, 0x88f1, 0x080c, 0xb101, 0x009e, 0x0005, 0x080c,
+ 0xebaa, 0x0db8, 0x009e, 0x0005, 0x2001, 0x180c, 0x200c, 0xc1d4,
+ 0x2102, 0x0036, 0x080c, 0x989d, 0x080c, 0x9a0f, 0x6014, 0x0096,
+ 0x2048, 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x0188,
+ 0xa87c, 0x9084, 0x0003, 0x9086, 0x0002, 0x0140, 0xa8ac, 0x6330,
+ 0x931a, 0x6332, 0xa8b0, 0x632c, 0x931b, 0x632e, 0x6003, 0x0002,
+ 0x0080, 0x2019, 0x0004, 0x080c, 0xe948, 0x6018, 0x9005, 0x1128,
+ 0x2001, 0x1988, 0x2004, 0x8003, 0x601a, 0x6017, 0x0000, 0x6003,
+ 0x0007, 0x009e, 0x003e, 0x0005, 0x9182, 0x0040, 0x0002, 0xe2ab,
+ 0xe2ab, 0xe2ab, 0xe2ab, 0xe2ab, 0xe2ab, 0xe2ab, 0xe2ab, 0xe2ad,
+ 0xe2ab, 0xe2ab, 0xe2ab, 0xe2ab, 0xe2ab, 0xe2ab, 0xe2ab, 0xe2ab,
+ 0xe2ab, 0xe2ab, 0xe2f8, 0x080c, 0x0dc5, 0x6014, 0x0096, 0x2048,
+ 0xa834, 0xaa38, 0x6110, 0x00b6, 0x2158, 0xb900, 0x00be, 0xd1bc,
+ 0x1190, 0x920d, 0x1518, 0xa87c, 0xd0fc, 0x0128, 0x2009, 0x0041,
+ 0x009e, 0x0804, 0xe31c, 0x6003, 0x0007, 0x601b, 0x0000, 0x080c,
+ 0x88f1, 0x009e, 0x0005, 0x6124, 0xd1f4, 0x1d58, 0x0006, 0x0046,
+ 0xacac, 0x9422, 0xa9b0, 0x2200, 0x910b, 0x6030, 0x9420, 0x6432,
+ 0x602c, 0x9109, 0x612e, 0x004e, 0x000e, 0x08d8, 0x6110, 0x00b6,
+ 0x2158, 0xb900, 0x00be, 0xd1bc, 0x1178, 0x2009, 0x180e, 0x210c,
+ 0xd19c, 0x0118, 0x6003, 0x0007, 0x0010, 0x6003, 0x0006, 0x00e9,
+ 0x080c, 0x88f3, 0x009e, 0x0005, 0x6003, 0x0002, 0x009e, 0x0005,
+ 0x6024, 0xd0f4, 0x0128, 0x080c, 0x1608, 0x1904, 0xe2ad, 0x0005,
+ 0x6014, 0x0096, 0x2048, 0xa834, 0xa938, 0x009e, 0x9105, 0x1120,
+ 0x080c, 0x1608, 0x1904, 0xe2ad, 0x0005, 0xd2fc, 0x0140, 0x8002,
+ 0x8000, 0x8212, 0x9291, 0x0000, 0x2009, 0x0009, 0x0010, 0x2009,
+ 0x0015, 0xaa9a, 0xa896, 0x0005, 0x9182, 0x0040, 0x0208, 0x0062,
+ 0x9186, 0x0013, 0x0120, 0x9186, 0x0014, 0x190c, 0x0dc5, 0x6024,
+ 0xd0dc, 0x090c, 0x0dc5, 0x0005, 0xe340, 0xe34c, 0xe358, 0xe364,
+ 0xe340, 0xe340, 0xe340, 0xe340, 0xe347, 0xe342, 0xe342, 0xe340,
+ 0xe340, 0xe340, 0xe340, 0xe342, 0xe340, 0xe342, 0xe340, 0xe347,
+ 0x080c, 0x0dc5, 0x6024, 0xd0dc, 0x090c, 0x0dc5, 0x0005, 0x6014,
+ 0x9005, 0x190c, 0x0dc5, 0x0005, 0x6003, 0x0001, 0x6106, 0x080c,
+ 0x933b, 0x0126, 0x2091, 0x8000, 0x080c, 0x98ed, 0x012e, 0x0005,
+ 0x6003, 0x0001, 0x6106, 0x080c, 0x933b, 0x0126, 0x2091, 0x8000,
+ 0x080c, 0x98ed, 0x012e, 0x0005, 0x6003, 0x0003, 0x6106, 0x2c10,
+ 0x080c, 0x1c09, 0x0126, 0x2091, 0x8000, 0x080c, 0x93a0, 0x080c,
+ 0x9a0f, 0x012e, 0x0005, 0x0126, 0x2091, 0x8000, 0x0036, 0x0096,
+ 0x9182, 0x0040, 0x0023, 0x009e, 0x003e, 0x012e, 0x0005, 0xe393,
+ 0xe395, 0xe3a7, 0xe3c1, 0xe393, 0xe393, 0xe393, 0xe393, 0xe393,
+ 0xe393, 0xe393, 0xe393, 0xe393, 0xe393, 0xe393, 0xe393, 0xe393,
+ 0xe393, 0xe393, 0xe393, 0x080c, 0x0dc5, 0x6014, 0x2048, 0xa87c,
+ 0xd0fc, 0x01f8, 0x909c, 0x0003, 0x939e, 0x0003, 0x01d0, 0x6003,
+ 0x0001, 0x6106, 0x080c, 0x933b, 0x080c, 0x98ed, 0x0470, 0x6014,
+ 0x2048, 0xa87c, 0xd0fc, 0x0168, 0x909c, 0x0003, 0x939e, 0x0003,
+ 0x0140, 0x6003, 0x0001, 0x6106, 0x080c, 0x933b, 0x080c, 0x98ed,
+ 0x00e0, 0x901e, 0x6316, 0x631a, 0x2019, 0x0004, 0x080c, 0xe948,
+ 0x00a0, 0x6014, 0x2048, 0xa87c, 0xd0fc, 0x0d98, 0x909c, 0x0003,
+ 0x939e, 0x0003, 0x0d70, 0x6003, 0x0003, 0x6106, 0x2c10, 0x080c,
+ 0x1c09, 0x080c, 0x93a0, 0x080c, 0x9a0f, 0x0005, 0x080c, 0x97e1,
+ 0x6114, 0x81ff, 0x0158, 0x0096, 0x2148, 0x080c, 0xed00, 0x0036,
+ 0x2019, 0x0029, 0x080c, 0xe948, 0x003e, 0x009e, 0x080c, 0xb134,
+ 0x080c, 0x98ed, 0x0005, 0x080c, 0x989d, 0x6114, 0x81ff, 0x0158,
+ 0x0096, 0x2148, 0x080c, 0xed00, 0x0036, 0x2019, 0x0029, 0x080c,
+ 0xe948, 0x003e, 0x009e, 0x080c, 0xb134, 0x080c, 0x9a0f, 0x0005,
+ 0x9182, 0x0085, 0x0002, 0xe412, 0xe410, 0xe410, 0xe41e, 0xe410,
+ 0xe410, 0xe410, 0xe410, 0xe410, 0xe410, 0xe410, 0xe410, 0xe410,
+ 0x080c, 0x0dc5, 0x6003, 0x000b, 0x6106, 0x080c, 0x933b, 0x0126,
+ 0x2091, 0x8000, 0x080c, 0x98ed, 0x012e, 0x0005, 0x0026, 0x00e6,
+ 0x080c, 0xeba1, 0x0118, 0x080c, 0xb101, 0x0450, 0x2071, 0x0260,
+ 0x7224, 0x6216, 0x2001, 0x180e, 0x2004, 0xd0e4, 0x0150, 0x6010,
+ 0x00b6, 0x2058, 0xbca0, 0x00be, 0x2c00, 0x2011, 0x014e, 0x080c,
+ 0xb423, 0x7220, 0x080c, 0xe79d, 0x0118, 0x6007, 0x0086, 0x0040,
+ 0x6007, 0x0087, 0x7224, 0x9296, 0xffff, 0x1110, 0x6007, 0x0086,
+ 0x6003, 0x0001, 0x080c, 0x933b, 0x080c, 0x98ed, 0x080c, 0x9a0f,
+ 0x00ee, 0x002e, 0x0005, 0x9186, 0x0013, 0x1160, 0x6004, 0x908a,
+ 0x0085, 0x0a0c, 0x0dc5, 0x908a, 0x0092, 0x1a0c, 0x0dc5, 0x9082,
+ 0x0085, 0x00a2, 0x9186, 0x0027, 0x0130, 0x9186, 0x0014, 0x0118,
+ 0x080c, 0xb19b, 0x0050, 0x2001, 0x0007, 0x080c, 0x668f, 0x080c,
+ 0x97e1, 0x080c, 0xb134, 0x080c, 0x98ed, 0x0005, 0xe483, 0xe485,
+ 0xe485, 0xe483, 0xe483, 0xe483, 0xe483, 0xe483, 0xe483, 0xe483,
+ 0xe483, 0xe483, 0xe483, 0x080c, 0x0dc5, 0x080c, 0x97e1, 0x080c,
+ 0xb134, 0x080c, 0x98ed, 0x0005, 0x9182, 0x0085, 0x0a0c, 0x0dc5,
+ 0x9182, 0x0092, 0x1a0c, 0x0dc5, 0x9182, 0x0085, 0x0002, 0xe4a4,
+ 0xe4a4, 0xe4a4, 0xe4a6, 0xe4a4, 0xe4a4, 0xe4a4, 0xe4a4, 0xe4a4,
+ 0xe4a4, 0xe4a4, 0xe4a4, 0xe4a4, 0x080c, 0x0dc5, 0x0005, 0x9186,
+ 0x0013, 0x0148, 0x9186, 0x0014, 0x0130, 0x9186, 0x0027, 0x0118,
+ 0x080c, 0xb19b, 0x0030, 0x080c, 0x97e1, 0x080c, 0xb134, 0x080c,
+ 0x98ed, 0x0005, 0x0036, 0x080c, 0xec02, 0x6043, 0x0000, 0x2019,
+ 0x000b, 0x0031, 0x6023, 0x0006, 0x6003, 0x0007, 0x003e, 0x0005,
+ 0x0126, 0x0036, 0x2091, 0x8000, 0x0086, 0x2c40, 0x0096, 0x904e,
+ 0x080c, 0xa929, 0x009e, 0x008e, 0x1550, 0x0076, 0x2c38, 0x080c,
+ 0xa9d4, 0x007e, 0x1520, 0x6000, 0x9086, 0x0000, 0x0500, 0x6020,
+ 0x9086, 0x0007, 0x01e0, 0x0096, 0x601c, 0xd084, 0x0140, 0x080c,
+ 0xec02, 0x080c, 0xd579, 0x080c, 0x1ab7, 0x6023, 0x0007, 0x6014,
+ 0x2048, 0x080c, 0xce56, 0x0110, 0x080c, 0xe948, 0x009e, 0x6017,
+ 0x0000, 0x080c, 0xec02, 0x6023, 0x0007, 0x080c, 0xd579, 0x003e,
+ 0x012e, 0x0005, 0x00f6, 0x00c6, 0x00b6, 0x0036, 0x0156, 0x2079,
+ 0x0260, 0x7938, 0x783c, 0x080c, 0x2894, 0x1904, 0xe558, 0x0016,
+ 0x00c6, 0x080c, 0x671d, 0x1904, 0xe556, 0x001e, 0x00c6, 0x080c,
+ 0xd561, 0x1130, 0xb8c0, 0x9005, 0x0118, 0x080c, 0x339b, 0x0148,
+ 0x2b10, 0x2160, 0x6010, 0x0006, 0x6212, 0x080c, 0xd568, 0x000e,
+ 0x6012, 0x00ce, 0x002e, 0x0026, 0x0016, 0x2019, 0x0029, 0x080c,
+ 0xaa9a, 0x080c, 0x94e0, 0x0076, 0x903e, 0x080c, 0x93b3, 0x007e,
+ 0x001e, 0x0076, 0x903e, 0x080c, 0xe690, 0x007e, 0x0026, 0xba04,
+ 0x9294, 0xff00, 0x8217, 0x9286, 0x0006, 0x0118, 0x9286, 0x0004,
+ 0x1118, 0xbaa0, 0x080c, 0x3304, 0x002e, 0xbcc0, 0x001e, 0x080c,
+ 0x6141, 0xbe12, 0xbd16, 0xbcc2, 0x9006, 0x0010, 0x00ce, 0x001e,
+ 0x015e, 0x003e, 0x00be, 0x00ce, 0x00fe, 0x0005, 0x00c6, 0x00d6,
+ 0x00b6, 0x0016, 0x2009, 0x1824, 0x2104, 0x9086, 0x0074, 0x1904,
+ 0xe5b7, 0x2069, 0x0260, 0x6944, 0x9182, 0x0100, 0x06e0, 0x6940,
+ 0x9184, 0x8000, 0x0904, 0xe5b4, 0x2001, 0x197d, 0x2004, 0x9005,
+ 0x1140, 0x6010, 0x2058, 0xb8c0, 0x9005, 0x0118, 0x9184, 0x0800,
+ 0x0598, 0x6948, 0x918a, 0x0001, 0x0648, 0x080c, 0xed68, 0x0118,
+ 0x6978, 0xd1fc, 0x11b8, 0x2009, 0x0205, 0x200b, 0x0001, 0x693c,
+ 0x81ff, 0x1198, 0x6944, 0x9182, 0x0100, 0x02a8, 0x6940, 0x81ff,
+ 0x1178, 0x6948, 0x918a, 0x0001, 0x0288, 0x6950, 0x918a, 0x0001,
+ 0x0298, 0x00d0, 0x6017, 0x0100, 0x00a0, 0x6017, 0x0300, 0x0088,
+ 0x6017, 0x0500, 0x0070, 0x6017, 0x0700, 0x0058, 0x6017, 0x0900,
+ 0x0040, 0x6017, 0x0b00, 0x0028, 0x6017, 0x0f00, 0x0010, 0x6017,
+ 0x2d00, 0x9085, 0x0001, 0x0008, 0x9006, 0x001e, 0x00be, 0x00de,
+ 0x00ce, 0x0005, 0x00c6, 0x00b6, 0x0026, 0x0036, 0x0156, 0x6210,
+ 0x2258, 0xbb04, 0x9394, 0x00ff, 0x9286, 0x0006, 0x0180, 0x9286,
+ 0x0004, 0x0168, 0x9394, 0xff00, 0x8217, 0x9286, 0x0006, 0x0138,
+ 0x9286, 0x0004, 0x0120, 0x080c, 0x672c, 0x0804, 0xe61f, 0x2011,
+ 0x0276, 0x20a9, 0x0004, 0x0096, 0x2b48, 0x2019, 0x000a, 0x080c,
+ 0xc0f7, 0x009e, 0x15a8, 0x2011, 0x027a, 0x20a9, 0x0004, 0x0096,
+ 0x2b48, 0x2019, 0x0006, 0x080c, 0xc0f7, 0x009e, 0x1548, 0x0046,
+ 0x0016, 0xbaa0, 0x2220, 0x9006, 0x2009, 0x1848, 0x210c, 0xd1a4,
+ 0x0138, 0x2009, 0x0029, 0x080c, 0xe9a5, 0xb800, 0xc0e5, 0xb802,
+ 0x2019, 0x0029, 0x080c, 0x94e0, 0x0076, 0x2039, 0x0000, 0x080c,
+ 0x93b3, 0x2c08, 0x080c, 0xe690, 0x007e, 0x2001, 0x0007, 0x080c,
+ 0x668f, 0x2001, 0x0007, 0x080c, 0x6663, 0x001e, 0x004e, 0x9006,
+ 0x015e, 0x003e, 0x002e, 0x00be, 0x00ce, 0x0005, 0x00d6, 0x2069,
+ 0x026e, 0x6800, 0x9086, 0x0800, 0x0118, 0x6017, 0x0000, 0x0008,
+ 0x9006, 0x00de, 0x0005, 0x00b6, 0x00f6, 0x0016, 0x0026, 0x0036,
+ 0x0156, 0x2079, 0x026c, 0x7930, 0x7834, 0x080c, 0x2894, 0x11d0,
+ 0x080c, 0x671d, 0x11b8, 0x2011, 0x0270, 0x20a9, 0x0004, 0x0096,
+ 0x2b48, 0x2019, 0x000a, 0x080c, 0xc0f7, 0x009e, 0x1158, 0x2011,
+ 0x0274, 0x20a9, 0x0004, 0x0096, 0x2b48, 0x2019, 0x0006, 0x080c,
+ 0xc0f7, 0x009e, 0x015e, 0x003e, 0x002e, 0x001e, 0x00fe, 0x00be,
+ 0x0005, 0x00b6, 0x0006, 0x0016, 0x0026, 0x0036, 0x0156, 0x2011,
+ 0x0263, 0x2204, 0x8211, 0x220c, 0x080c, 0x2894, 0x11d0, 0x080c,
+ 0x671d, 0x11b8, 0x2011, 0x0276, 0x20a9, 0x0004, 0x0096, 0x2b48,
+ 0x2019, 0x000a, 0x080c, 0xc0f7, 0x009e, 0x1158, 0x2011, 0x027a,
+ 0x20a9, 0x0004, 0x0096, 0x2b48, 0x2019, 0x0006, 0x080c, 0xc0f7,
+ 0x009e, 0x015e, 0x003e, 0x002e, 0x001e, 0x000e, 0x00be, 0x0005,
+ 0x00e6, 0x00c6, 0x0086, 0x0076, 0x0066, 0x0056, 0x0046, 0x0026,
+ 0x0126, 0x2091, 0x8000, 0x2740, 0x2029, 0x19f2, 0x252c, 0x2021,
+ 0x19f8, 0x2424, 0x2061, 0x1cd0, 0x2071, 0x1800, 0x7654, 0x7074,
+ 0x81ff, 0x0150, 0x0006, 0x9186, 0x1ab8, 0x000e, 0x0128, 0x8001,
+ 0x9602, 0x1a04, 0xe72e, 0x0018, 0x9606, 0x0904, 0xe72e, 0x080c,
+ 0x8bc3, 0x0904, 0xe725, 0x2100, 0x9c06, 0x0904, 0xe725, 0x6720,
+ 0x9786, 0x0007, 0x0904, 0xe725, 0x080c, 0xe9e6, 0x1904, 0xe725,
+ 0x080c, 0xed86, 0x0904, 0xe725, 0x080c, 0xe9d6, 0x0904, 0xe725,
+ 0x6720, 0x9786, 0x0001, 0x1148, 0x080c, 0x339b, 0x0904, 0xe76d,
+ 0x6004, 0x9086, 0x0000, 0x1904, 0xe76d, 0x9786, 0x0004, 0x0904,
+ 0xe76d, 0x2500, 0x9c06, 0x0904, 0xe725, 0x2400, 0x9c06, 0x05e8,
+ 0x88ff, 0x0118, 0x6054, 0x9906, 0x15c0, 0x0096, 0x6000, 0x9086,
+ 0x0004, 0x1120, 0x0016, 0x080c, 0x1ab7, 0x001e, 0x9786, 0x000a,
+ 0x0148, 0x080c, 0xd05e, 0x1130, 0x080c, 0xbae2, 0x009e, 0x080c,
+ 0xb134, 0x0418, 0x6014, 0x2048, 0x080c, 0xce56, 0x01d8, 0x9786,
+ 0x0003, 0x1570, 0xa867, 0x0103, 0xa87c, 0xd0cc, 0x0130, 0x0096,
+ 0xa878, 0x2048, 0x080c, 0x0fc0, 0x009e, 0xab7a, 0xa877, 0x0000,
+ 0x080c, 0xed00, 0x0016, 0x080c, 0xd14c, 0x080c, 0x6dc4, 0x001e,
+ 0x080c, 0xd041, 0x009e, 0x080c, 0xb134, 0x9ce0, 0x0018, 0x2001,
+ 0x181a, 0x2004, 0x9c02, 0x1210, 0x0804, 0xe6a4, 0x012e, 0x002e,
+ 0x004e, 0x005e, 0x006e, 0x007e, 0x008e, 0x00ce, 0x00ee, 0x0005,
+ 0x9786, 0x0006, 0x1150, 0x9386, 0x0005, 0x0128, 0x080c, 0xed00,
+ 0x080c, 0xe948, 0x08f8, 0x009e, 0x0c00, 0x9786, 0x0009, 0x11f8,
+ 0x6000, 0x9086, 0x0004, 0x01c0, 0x6000, 0x9086, 0x0003, 0x11a0,
+ 0x080c, 0x989d, 0x0096, 0x6114, 0x2148, 0x080c, 0xce56, 0x0118,
+ 0x6010, 0x080c, 0x6dd1, 0x009e, 0x00c6, 0x080c, 0xb101, 0x00ce,
+ 0x0036, 0x080c, 0x9a0f, 0x003e, 0x009e, 0x0804, 0xe725, 0x9786,
+ 0x000a, 0x0904, 0xe715, 0x0804, 0xe70a, 0x81ff, 0x0904, 0xe725,
+ 0x9180, 0x0001, 0x2004, 0x9086, 0x0018, 0x0138, 0x9180, 0x0001,
+ 0x2004, 0x9086, 0x002d, 0x1904, 0xe725, 0x6000, 0x9086, 0x0002,
+ 0x1904, 0xe725, 0x080c, 0xd04d, 0x0138, 0x080c, 0xd05e, 0x1904,
+ 0xe725, 0x080c, 0xbae2, 0x0038, 0x080c, 0x326f, 0x080c, 0xd05e,
+ 0x1110, 0x080c, 0xbae2, 0x080c, 0xb134, 0x0804, 0xe725, 0xa864,
+ 0x9084, 0x00ff, 0x9086, 0x0039, 0x0005, 0x00c6, 0x00e6, 0x0016,
+ 0x2c08, 0x2170, 0x9006, 0x080c, 0xe96f, 0x001e, 0x0120, 0x6020,
+ 0x9084, 0x000f, 0x001b, 0x00ee, 0x00ce, 0x0005, 0xe7bc, 0xe7bc,
+ 0xe7bc, 0xe7bc, 0xe7bc, 0xe7bc, 0xe7be, 0xe7bc, 0xe7bc, 0xe7bc,
+ 0xe7e7, 0xb134, 0xb134, 0xe7bc, 0x9006, 0x0005, 0x0036, 0x0046,
+ 0x0016, 0x7010, 0x00b6, 0x2058, 0xbca0, 0x00be, 0x2c00, 0x2009,
+ 0x0020, 0x080c, 0xe9a5, 0x001e, 0x004e, 0x2019, 0x0002, 0x080c,
+ 0xe4c8, 0x003e, 0x9085, 0x0001, 0x0005, 0x0096, 0x080c, 0xce56,
+ 0x0140, 0x6014, 0x904d, 0x080c, 0xca71, 0x687b, 0x0005, 0x080c,
+ 0x6dd1, 0x009e, 0x080c, 0xb134, 0x9085, 0x0001, 0x0005, 0x0019,
+ 0x9085, 0x0001, 0x0005, 0x6000, 0x908a, 0x0010, 0x1a0c, 0x0dc5,
+ 0x000b, 0x0005, 0xe802, 0xe802, 0xe819, 0xe809, 0xe828, 0xe802,
+ 0xe802, 0xe804, 0xe802, 0xe802, 0xe802, 0xe802, 0xe802, 0xe802,
+ 0xe802, 0xe802, 0x080c, 0x0dc5, 0x080c, 0xb134, 0x9085, 0x0001,
+ 0x0005, 0x0036, 0x00e6, 0x2071, 0x19e9, 0x703c, 0x9c06, 0x1128,
+ 0x2019, 0x0001, 0x080c, 0xa877, 0x0010, 0x080c, 0xaa59, 0x00ee,
+ 0x003e, 0x0096, 0x00d6, 0x6014, 0x2048, 0xa87b, 0x0005, 0x080c,
+ 0x6dd1, 0x080c, 0xb134, 0x00de, 0x009e, 0x9085, 0x0001, 0x0005,
+ 0x601c, 0xd084, 0x190c, 0x1ab7, 0x0c60, 0x2001, 0x0001, 0x080c,
+ 0x664f, 0x0156, 0x0016, 0x0026, 0x0036, 0x20a9, 0x0004, 0x2019,
+ 0x1805, 0x2011, 0x0276, 0x080c, 0xc0e3, 0x003e, 0x002e, 0x001e,
+ 0x015e, 0x9005, 0x0005, 0x00f6, 0x00e6, 0x00c6, 0x0086, 0x0076,
+ 0x0066, 0x00b6, 0x0126, 0x2091, 0x8000, 0x2740, 0x2061, 0x1cd0,
+ 0x2079, 0x0001, 0x8fff, 0x0904, 0xe89f, 0x2071, 0x1800, 0x7654,
+ 0x7074, 0x8001, 0x9602, 0x1a04, 0xe89f, 0x88ff, 0x0120, 0x2800,
+ 0x9c06, 0x15a0, 0x2078, 0x080c, 0xe9d6, 0x0580, 0x2400, 0x9c06,
+ 0x0568, 0x6720, 0x9786, 0x0006, 0x1548, 0x9786, 0x0007, 0x0530,
+ 0x88ff, 0x1150, 0xd58c, 0x1118, 0x6010, 0x9b06, 0x11f8, 0xd584,
+ 0x0118, 0x6054, 0x9106, 0x11d0, 0x0096, 0x601c, 0xd084, 0x0140,
+ 0x080c, 0xec02, 0x080c, 0xd579, 0x080c, 0x1ab7, 0x6023, 0x0007,
+ 0x6014, 0x2048, 0x080c, 0xce56, 0x0120, 0x0046, 0x080c, 0xe948,
+ 0x004e, 0x009e, 0x080c, 0xb134, 0x88ff, 0x1198, 0x9ce0, 0x0018,
+ 0x2001, 0x181a, 0x2004, 0x9c02, 0x1210, 0x0804, 0xe852, 0x9006,
+ 0x012e, 0x00be, 0x006e, 0x007e, 0x008e, 0x00ce, 0x00ee, 0x00fe,
+ 0x0005, 0x98c5, 0x0001, 0x0ca0, 0x00b6, 0x0076, 0x0056, 0x0086,
+ 0x9046, 0x2029, 0x0001, 0x2c20, 0x2019, 0x0002, 0x6210, 0x2258,
+ 0x0096, 0x904e, 0x080c, 0xa929, 0x009e, 0x008e, 0x903e, 0x080c,
+ 0xa9d4, 0x080c, 0xe843, 0x005e, 0x007e, 0x00be, 0x0005, 0x00b6,
+ 0x0046, 0x0056, 0x0076, 0x00c6, 0x0156, 0x2c20, 0x2128, 0x20a9,
+ 0x007f, 0x900e, 0x0016, 0x0036, 0x080c, 0x671d, 0x1180, 0x0056,
+ 0x0086, 0x9046, 0x2508, 0x2029, 0x0001, 0x0096, 0x904e, 0x080c,
+ 0xa929, 0x009e, 0x008e, 0x903e, 0x080c, 0xa9d4, 0x005e, 0x003e,
+ 0x001e, 0x8108, 0x1f04, 0xe8d2, 0x0036, 0x2508, 0x2029, 0x0003,
+ 0x080c, 0xe843, 0x003e, 0x015e, 0x00ce, 0x007e, 0x005e, 0x004e,
+ 0x00be, 0x0005, 0x00b6, 0x0076, 0x0056, 0x6210, 0x2258, 0x0086,
+ 0x9046, 0x2029, 0x0001, 0x2019, 0x0048, 0x0096, 0x904e, 0x080c,
+ 0xa929, 0x009e, 0x008e, 0x903e, 0x080c, 0xa9d4, 0x2c20, 0x080c,
+ 0xe843, 0x005e, 0x007e, 0x00be, 0x0005, 0x00b6, 0x0046, 0x0056,
+ 0x0076, 0x00c6, 0x0156, 0x2c20, 0x20a9, 0x0800, 0x900e, 0x0016,
+ 0x0036, 0x080c, 0x671d, 0x1190, 0x0086, 0x9046, 0x2828, 0x0046,
+ 0x2021, 0x0001, 0x080c, 0xebe6, 0x004e, 0x0096, 0x904e, 0x080c,
+ 0xa929, 0x009e, 0x008e, 0x903e, 0x080c, 0xa9d4, 0x003e, 0x001e,
+ 0x8108, 0x1f04, 0xe91f, 0x0036, 0x2029, 0x0002, 0x080c, 0xe843,
+ 0x003e, 0x015e, 0x00ce, 0x007e, 0x005e, 0x004e, 0x00be, 0x0005,
+ 0x0016, 0x00f6, 0x080c, 0xce54, 0x0198, 0xa864, 0x9084, 0x00ff,
+ 0x9086, 0x0046, 0x0180, 0xa800, 0x907d, 0x0138, 0xa803, 0x0000,
+ 0xab82, 0x080c, 0x6dd1, 0x2f48, 0x0cb0, 0xab82, 0x080c, 0x6dd1,
+ 0x00fe, 0x001e, 0x0005, 0xa800, 0x907d, 0x0130, 0xa803, 0x0000,
+ 0x080c, 0x6dd1, 0x2f48, 0x0cb8, 0x080c, 0x6dd1, 0x0c88, 0x00e6,
+ 0x0046, 0x0036, 0x2061, 0x1cd0, 0x9005, 0x1138, 0x2071, 0x1800,
+ 0x7454, 0x7074, 0x8001, 0x9402, 0x12f8, 0x2100, 0x9c06, 0x0188,
+ 0x6000, 0x9086, 0x0000, 0x0168, 0x6008, 0x9206, 0x1150, 0x6320,
+ 0x9386, 0x0009, 0x01b0, 0x6010, 0x91a0, 0x0004, 0x2424, 0x9406,
+ 0x0140, 0x9ce0, 0x0018, 0x2001, 0x181a, 0x2004, 0x9c02, 0x1220,
+ 0x0c20, 0x9085, 0x0001, 0x0008, 0x9006, 0x003e, 0x004e, 0x00ee,
+ 0x0005, 0x631c, 0xd3c4, 0x1d68, 0x0c30, 0x0096, 0x0006, 0x080c,
+ 0x100e, 0x000e, 0x090c, 0x0dc5, 0xaae2, 0xa867, 0x010d, 0xa88e,
+ 0x0026, 0x2010, 0x080c, 0xce44, 0x2001, 0x0000, 0x0120, 0x2200,
+ 0x9080, 0x0015, 0x2004, 0x002e, 0xa87a, 0x9186, 0x0020, 0x0110,
+ 0xa8e3, 0xffff, 0xa986, 0xac76, 0xa87f, 0x0000, 0x2001, 0x198f,
+ 0x2004, 0xa882, 0x9006, 0xa802, 0xa86a, 0xa88a, 0x0126, 0x2091,
+ 0x8000, 0x080c, 0x6dd1, 0x012e, 0x009e, 0x0005, 0x6700, 0x9786,
+ 0x0000, 0x0158, 0x9786, 0x0001, 0x0140, 0x9786, 0x000a, 0x0128,
+ 0x9786, 0x0009, 0x0110, 0x9085, 0x0001, 0x0005, 0x00e6, 0x6010,
+ 0x9075, 0x0138, 0x00b6, 0x2058, 0xb8a0, 0x00be, 0x9206, 0x00ee,
+ 0x0005, 0x9085, 0x0001, 0x0cd8, 0x0016, 0x6004, 0x908e, 0x001e,
+ 0x11a0, 0x8007, 0x6134, 0x918c, 0x00ff, 0x9105, 0x6036, 0x6007,
+ 0x0085, 0x6003, 0x000b, 0x6023, 0x0005, 0x2001, 0x1988, 0x2004,
+ 0x601a, 0x080c, 0x933b, 0x080c, 0x98ed, 0x001e, 0x0005, 0xa001,
+ 0xa001, 0x0005, 0x6024, 0xd0e4, 0x0158, 0xd0cc, 0x0118, 0x080c,
+ 0xd190, 0x0030, 0x080c, 0xec02, 0x080c, 0x88f1, 0x080c, 0xb101,
+ 0x0005, 0x9280, 0x0008, 0x2004, 0x9084, 0x000f, 0x0002, 0xea35,
+ 0xea35, 0xea35, 0xea37, 0xea35, 0xea37, 0xea37, 0xea35, 0xea37,
+ 0xea35, 0xea35, 0xea35, 0xea35, 0xea35, 0x9006, 0x0005, 0x9085,
+ 0x0001, 0x0005, 0x9280, 0x0008, 0x2004, 0x9084, 0x000f, 0x0002,
+ 0xea4e, 0xea4e, 0xea4e, 0xea4e, 0xea4e, 0xea4e, 0xea5b, 0xea4e,
+ 0xea4e, 0xea4e, 0xea4e, 0xea4e, 0xea4e, 0xea4e, 0x6007, 0x003b,
+ 0x602f, 0x0009, 0x6017, 0x2a00, 0x6003, 0x0001, 0x080c, 0x933b,
+ 0x080c, 0x98ed, 0x0005, 0x0096, 0x00c6, 0x2260, 0x080c, 0xec02,
+ 0x6043, 0x0000, 0x6024, 0xc0f4, 0xc0e4, 0x6026, 0x603b, 0x0000,
+ 0x00ce, 0x00d6, 0x2268, 0x9186, 0x0007, 0x1904, 0xeab4, 0x6814,
+ 0x9005, 0x0138, 0x2048, 0xa87c, 0xd0fc, 0x1118, 0x00de, 0x009e,
+ 0x08a8, 0x6007, 0x003a, 0x6003, 0x0001, 0x080c, 0x933b, 0x080c,
+ 0x98ed, 0x00c6, 0x2d60, 0x6100, 0x9186, 0x0002, 0x1904, 0xeb2b,
+ 0x6014, 0x9005, 0x1138, 0x6000, 0x9086, 0x0007, 0x190c, 0x0dc5,
+ 0x0804, 0xeb2b, 0x2048, 0x080c, 0xce56, 0x1130, 0x0028, 0x2048,
+ 0xa800, 0x9005, 0x1de0, 0x2900, 0x2048, 0xa87c, 0x9084, 0x0003,
+ 0x9086, 0x0002, 0x1168, 0xa87c, 0xc0dc, 0xc0f4, 0xa87e, 0xa880,
+ 0xc0fc, 0xa882, 0x2009, 0x0043, 0x080c, 0xe31c, 0x0804, 0xeb2b,
+ 0x2009, 0x0041, 0x0804, 0xeb25, 0x9186, 0x0005, 0x15a0, 0x6814,
+ 0x2048, 0xa87c, 0xd0bc, 0x1120, 0x00de, 0x009e, 0x0804, 0xea4e,
+ 0xd0b4, 0x0128, 0xd0fc, 0x090c, 0x0dc5, 0x0804, 0xea6f, 0x6007,
+ 0x003a, 0x6003, 0x0001, 0x080c, 0x933b, 0x080c, 0x98ed, 0x00c6,
+ 0x2d60, 0x6100, 0x9186, 0x0002, 0x0120, 0x9186, 0x0004, 0x1904,
+ 0xeb2b, 0x6814, 0x2048, 0xa97c, 0xc1f4, 0xc1dc, 0xa97e, 0xa980,
+ 0xc1fc, 0xc1bc, 0xa982, 0x00f6, 0x2c78, 0x080c, 0x1768, 0x00fe,
+ 0x2009, 0x0042, 0x04d0, 0x0036, 0x080c, 0x100e, 0x090c, 0x0dc5,
+ 0xa867, 0x010d, 0x9006, 0xa802, 0xa86a, 0xa88a, 0x2d18, 0xab8e,
+ 0xa887, 0x0045, 0x2c00, 0xa892, 0x6038, 0xa8a2, 0x2360, 0x6024,
+ 0xc0dd, 0x6026, 0x6010, 0x00b6, 0x2058, 0xb8a0, 0x00be, 0x2004,
+ 0x6354, 0xab7a, 0xa876, 0x9006, 0xa87e, 0xa882, 0xad9a, 0xae96,
+ 0xa89f, 0x0001, 0x080c, 0x6dd1, 0x2019, 0x0045, 0x6008, 0x2068,
+ 0x080c, 0xe4c8, 0x2d00, 0x600a, 0x6023, 0x0006, 0x6003, 0x0007,
+ 0x901e, 0x631a, 0x6342, 0x003e, 0x0038, 0x6043, 0x0000, 0x6003,
+ 0x0007, 0x080c, 0xe31c, 0x00ce, 0x00de, 0x009e, 0x0005, 0x9186,
+ 0x0013, 0x1128, 0x6004, 0x9082, 0x0085, 0x2008, 0x00c2, 0x9186,
+ 0x0027, 0x1178, 0x080c, 0x97e1, 0x0036, 0x0096, 0x6014, 0x2048,
+ 0x2019, 0x0004, 0x080c, 0xe948, 0x009e, 0x003e, 0x080c, 0x98ed,
+ 0x0005, 0x9186, 0x0014, 0x0d70, 0x080c, 0xb19b, 0x0005, 0xeb5e,
+ 0xeb5c, 0xeb5c, 0xeb5c, 0xeb5c, 0xeb5c, 0xeb5e, 0xeb5c, 0xeb5c,
+ 0xeb5c, 0xeb5c, 0xeb5c, 0xeb5c, 0x080c, 0x0dc5, 0x080c, 0x97e1,
+ 0x6003, 0x000c, 0x080c, 0x98ed, 0x0005, 0x9182, 0x0092, 0x1220,
+ 0x9182, 0x0085, 0x0208, 0x001a, 0x080c, 0xb19b, 0x0005, 0xeb7c,
+ 0xeb7c, 0xeb7c, 0xeb7c, 0xeb7e, 0xeb9e, 0xeb7c, 0xeb7c, 0xeb7c,
+ 0xeb7c, 0xeb7c, 0xeb7c, 0xeb7c, 0x080c, 0x0dc5, 0x00d6, 0x2c68,
+ 0x080c, 0xb0ab, 0x01b0, 0x6003, 0x0001, 0x6007, 0x001e, 0x2009,
+ 0x026e, 0x210c, 0x613a, 0x2009, 0x026f, 0x210c, 0x613e, 0x600b,
+ 0xffff, 0x6910, 0x6112, 0x6023, 0x0004, 0x080c, 0x933b, 0x080c,
+ 0x98ed, 0x2d60, 0x080c, 0xb101, 0x00de, 0x0005, 0x080c, 0xb101,
+ 0x0005, 0x00e6, 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0ec,
+ 0x00ee, 0x0005, 0x2009, 0x1867, 0x210c, 0xd1ec, 0x05b0, 0x6003,
+ 0x0002, 0x6024, 0xc0e5, 0x6026, 0xd0cc, 0x0150, 0x2001, 0x1989,
+ 0x2004, 0x6042, 0x2009, 0x1867, 0x210c, 0xd1f4, 0x1520, 0x00a0,
+ 0x2009, 0x1867, 0x210c, 0xd1f4, 0x0128, 0x6024, 0xc0e4, 0x6026,
+ 0x9006, 0x00d8, 0x2001, 0x1989, 0x200c, 0x2001, 0x1987, 0x2004,
+ 0x9100, 0x9080, 0x000a, 0x6042, 0x6010, 0x00b6, 0x2058, 0xb8bc,
+ 0x00be, 0x0008, 0x2104, 0x9005, 0x0118, 0x9088, 0x0003, 0x0cd0,
+ 0x2c0a, 0x600f, 0x0000, 0x9085, 0x0001, 0x0005, 0x0016, 0x00c6,
+ 0x00e6, 0x6154, 0xb8bc, 0x2060, 0x8cff, 0x0180, 0x84ff, 0x1118,
+ 0x6054, 0x9106, 0x1138, 0x600c, 0x2072, 0x080c, 0x88f1, 0x080c,
+ 0xb101, 0x0010, 0x9cf0, 0x0003, 0x2e64, 0x0c70, 0x00ee, 0x00ce,
+ 0x001e, 0x0005, 0x00d6, 0x00b6, 0x6010, 0x2058, 0xb8bc, 0x906d,
+ 0x0130, 0x9c06, 0x0110, 0x680c, 0x0cd0, 0x600c, 0x680e, 0x00be,
+ 0x00de, 0x0005, 0x0026, 0x0036, 0x0156, 0x2011, 0x182c, 0x2204,
+ 0x9084, 0x00ff, 0x2019, 0x026e, 0x2334, 0x96b4, 0x00ff, 0x9636,
+ 0x1508, 0x8318, 0x2334, 0x2204, 0x9084, 0xff00, 0x9636, 0x11d0,
+ 0x2011, 0x0270, 0x20a9, 0x0004, 0x6010, 0x0096, 0x2048, 0x2019,
+ 0x000a, 0x080c, 0xc0f7, 0x009e, 0x1168, 0x2011, 0x0274, 0x20a9,
+ 0x0004, 0x6010, 0x0096, 0x2048, 0x2019, 0x0006, 0x080c, 0xc0f7,
+ 0x009e, 0x1100, 0x015e, 0x003e, 0x002e, 0x0005, 0x00e6, 0x2071,
+ 0x1800, 0x080c, 0x60ba, 0x080c, 0x3019, 0x00ee, 0x0005, 0x0096,
+ 0x0026, 0x080c, 0x100e, 0x090c, 0x0dc5, 0xa85c, 0x9080, 0x001a,
+ 0x20a0, 0x20a9, 0x000c, 0xa860, 0x20e8, 0x9006, 0x4004, 0x9186,
+ 0x0046, 0x1118, 0xa867, 0x0136, 0x0038, 0xa867, 0x0138, 0x9186,
+ 0x0041, 0x0110, 0xa87b, 0x0001, 0x7038, 0x9084, 0xff00, 0x7240,
+ 0x9294, 0xff00, 0x8007, 0x9215, 0xaa9a, 0x9186, 0x0046, 0x1168,
+ 0x7038, 0x9084, 0x00ff, 0x723c, 0x9294, 0xff00, 0x9215, 0xaa9e,
+ 0x723c, 0x9294, 0x00ff, 0xaaa2, 0x0060, 0x7040, 0x9084, 0x00ff,
+ 0x7244, 0x9294, 0xff00, 0x9215, 0xaa9e, 0x7244, 0x9294, 0x00ff,
+ 0xaaa2, 0x9186, 0x0046, 0x1118, 0x9e90, 0x0012, 0x0010, 0x9e90,
+ 0x001a, 0x2204, 0x8007, 0xa8a6, 0x8210, 0x2204, 0x8007, 0xa8aa,
+ 0x8210, 0x2204, 0x8007, 0xa8ae, 0x8210, 0x2204, 0x8007, 0xa8b2,
+ 0x8210, 0x9186, 0x0046, 0x11b8, 0x9e90, 0x0016, 0x2204, 0x8007,
+ 0xa8b6, 0x8210, 0x2204, 0x8007, 0xa8ba, 0x8210, 0x2204, 0x8007,
+ 0xa8be, 0x8210, 0x2204, 0x8007, 0xa8c2, 0x8210, 0x2011, 0x0205,
+ 0x2013, 0x0001, 0x00b0, 0x9e90, 0x001e, 0x2204, 0x8007, 0xa8b6,
+ 0x8210, 0x2204, 0x8007, 0xa8ba, 0x2011, 0x0205, 0x2013, 0x0001,
+ 0x2011, 0x0260, 0x2204, 0x8007, 0xa8be, 0x8210, 0x2204, 0x8007,
+ 0xa8c2, 0x9186, 0x0046, 0x1118, 0x2011, 0x0262, 0x0010, 0x2011,
+ 0x026a, 0x0146, 0x01d6, 0x0036, 0x20a9, 0x0001, 0x2019, 0x0008,
+ 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0031, 0x20a0, 0x2204, 0x8007,
+ 0x4004, 0x8210, 0x8319, 0x1dd0, 0x003e, 0x01ce, 0x013e, 0x2011,
+ 0x0205, 0x2013, 0x0000, 0x002e, 0x080c, 0x6dd1, 0x009e, 0x0005,
+ 0x00e6, 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0fc, 0x0108,
+ 0x0011, 0x00ee, 0x0005, 0xa880, 0xc0e5, 0xa882, 0x0005, 0x00e6,
+ 0x00d6, 0x00c6, 0x0076, 0x0066, 0x0056, 0x0046, 0x0026, 0x0016,
+ 0x0126, 0x2091, 0x8000, 0x2029, 0x19f2, 0x252c, 0x2021, 0x19f8,
+ 0x2424, 0x2061, 0x1cd0, 0x2071, 0x1800, 0x7654, 0x7074, 0x9606,
+ 0x0578, 0x6720, 0x9786, 0x0001, 0x0118, 0x9786, 0x0008, 0x1500,
+ 0x2500, 0x9c06, 0x01e8, 0x2400, 0x9c06, 0x01d0, 0x080c, 0xe9d6,
+ 0x01b8, 0x080c, 0xe9e6, 0x11a0, 0x6000, 0x9086, 0x0004, 0x1120,
+ 0x0016, 0x080c, 0x1ab7, 0x001e, 0x080c, 0xd04d, 0x1110, 0x080c,
+ 0x326f, 0x080c, 0xd05e, 0x1110, 0x080c, 0xbae2, 0x080c, 0xb134,
+ 0x9ce0, 0x0018, 0x2001, 0x181a, 0x2004, 0x9c02, 0x1208, 0x0858,
+ 0x012e, 0x001e, 0x002e, 0x004e, 0x005e, 0x006e, 0x007e, 0x00ce,
+ 0x00de, 0x00ee, 0x0005, 0x2001, 0x1810, 0x2004, 0xd0dc, 0x0005,
+ 0x0006, 0x2001, 0x1837, 0x2004, 0xd09c, 0x000e, 0x0005, 0x0006,
+ 0x0036, 0x0046, 0x080c, 0xd561, 0x0168, 0x2019, 0xffff, 0x9005,
+ 0x0128, 0x6010, 0x00b6, 0x2058, 0xbba0, 0x00be, 0x2021, 0x0004,
+ 0x080c, 0x4da0, 0x004e, 0x003e, 0x000e, 0x0005, 0x6004, 0x9086,
+ 0x0001, 0x1128, 0x080c, 0xaa9a, 0x080c, 0xb134, 0x9006, 0x0005,
+ 0x00e6, 0x00c6, 0x00b6, 0x0046, 0x2061, 0x1cd0, 0x2071, 0x1800,
+ 0x7454, 0x7074, 0x8001, 0x9402, 0x12d8, 0x2100, 0x9c06, 0x0168,
+ 0x6000, 0x9086, 0x0000, 0x0148, 0x6010, 0x2058, 0xb8a0, 0x9206,
+ 0x1120, 0x6004, 0x9086, 0x0002, 0x0140, 0x9ce0, 0x0018, 0x2001,
+ 0x181a, 0x2004, 0x9c02, 0x1220, 0x0c40, 0x9085, 0x0001, 0x0008,
+ 0x9006, 0x004e, 0x00be, 0x00ce, 0x00ee, 0x0005, 0x2001, 0x1810,
+ 0x2004, 0xd0a4, 0x0160, 0x2001, 0x1837, 0x2004, 0xd0a4, 0x0138,
+ 0x2001, 0x1848, 0x2004, 0xd0a4, 0x1118, 0x9085, 0x0001, 0x0005,
+ 0x9006, 0x0ce8, 0x0126, 0x0006, 0x00e6, 0x0016, 0x2091, 0x8000,
+ 0x2071, 0x1840, 0xd5a4, 0x0118, 0x7004, 0x8000, 0x7006, 0xd5b4,
+ 0x0118, 0x7000, 0x8000, 0x7002, 0xd5ac, 0x0178, 0x2500, 0x9084,
+ 0x0007, 0x908e, 0x0003, 0x0148, 0x908e, 0x0004, 0x0130, 0x908e,
+ 0x0005, 0x0118, 0x2071, 0xfff6, 0x0089, 0x001e, 0x00ee, 0x000e,
+ 0x012e, 0x0005, 0x0126, 0x0006, 0x00e6, 0x2091, 0x8000, 0x2071,
+ 0xffee, 0x0021, 0x00ee, 0x000e, 0x012e, 0x0005, 0x2e05, 0x8000,
+ 0x2077, 0x1220, 0x8e70, 0x2e05, 0x8000, 0x2077, 0x0005, 0x00e6,
+ 0x2071, 0xffec, 0x0c99, 0x00ee, 0x0005, 0x00e6, 0x2071, 0xfff0,
+ 0x0c69, 0x00ee, 0x0005, 0x0126, 0x0006, 0x00e6, 0x2091, 0x8000,
+ 0x2071, 0x1840, 0x7014, 0x8000, 0x7016, 0x00ee, 0x000e, 0x012e,
+ 0x0005, 0x0003, 0x000b, 0x07ce, 0x0000, 0xc000, 0x0001, 0x8064,
+ 0x0008, 0x0010, 0x0000, 0x8066, 0x0000, 0x0101, 0x0008, 0x4407,
+ 0x0003, 0x8060, 0x0000, 0x0400, 0x0000, 0x580d, 0x000b, 0x79c0,
+ 0x0003, 0x5106, 0x0003, 0x4c0a, 0x0003, 0xbac0, 0x0009, 0x008a,
+ 0x0000, 0x0c0a, 0x000b, 0x15fe, 0x0008, 0x340a, 0x0003, 0xc4c0,
+ 0x0009, 0x7000, 0x0000, 0xffa0, 0x0001, 0x2000, 0x0000, 0x1680,
+ 0x000b, 0x808c, 0x0008, 0x0001, 0x0000, 0x0000, 0x0007, 0x4028,
+ 0x0000, 0x4047, 0x000a, 0x808c, 0x0008, 0x0002, 0x0000, 0x0822,
+ 0x0003, 0x4022, 0x0000, 0x0028, 0x000b, 0x4122, 0x0008, 0x94c0,
+ 0x0009, 0xff00, 0x0008, 0xffe0, 0x0009, 0x0500, 0x0008, 0x0aab,
+ 0x0003, 0x4447, 0x0002, 0x0ea8, 0x000b, 0x0bfe, 0x0008, 0x11a0,
+ 0x0001, 0x1286, 0x0003, 0x0ca0, 0x0001, 0x1286, 0x0003, 0x9180,
+ 0x0001, 0x0004, 0x0000, 0x8060, 0x0000, 0x0400, 0x0000, 0x7f62,
+ 0x0008, 0x8066, 0x0000, 0x0009, 0x0008, 0x4436, 0x000b, 0x808c,
+ 0x0008, 0x0000, 0x0008, 0x0060, 0x0008, 0x8062, 0x0008, 0x0004,
+ 0x0000, 0x8066, 0x0000, 0x0411, 0x0000, 0x443e, 0x0003, 0x03fe,
+ 0x0000, 0x43e0, 0x0001, 0x0e83, 0x000b, 0xc2c0, 0x0009, 0x00ff,
+ 0x0008, 0x02e0, 0x0001, 0x0e83, 0x000b, 0x9180, 0x0001, 0x0005,
+ 0x0008, 0x8060, 0x0000, 0x0400, 0x0000, 0x7f62, 0x0008, 0x8066,
+ 0x0000, 0x0019, 0x0000, 0x444d, 0x000b, 0x0240, 0x0002, 0x0a80,
+ 0x0003, 0x00fe, 0x0000, 0x3283, 0x000b, 0x0248, 0x000a, 0x085c,
+ 0x0003, 0x9180, 0x0001, 0x0006, 0x0008, 0x7f62, 0x0008, 0x8002,
+ 0x0008, 0x0003, 0x0008, 0x8066, 0x0000, 0x020a, 0x0000, 0x445b,
+ 0x0003, 0x112a, 0x0000, 0x002e, 0x0008, 0x022c, 0x0008, 0x3a44,
+ 0x0002, 0x0c0a, 0x000b, 0x808c, 0x0008, 0x0002, 0x0000, 0x1760,
+ 0x0008, 0x8062, 0x0008, 0x000f, 0x0008, 0x8066, 0x0000, 0x0011,
+ 0x0008, 0x4468, 0x0003, 0x01fe, 0x0008, 0x42e0, 0x0009, 0x0e74,
+ 0x0003, 0x00fe, 0x0000, 0x43e0, 0x0001, 0x0e74, 0x0003, 0x1734,
+ 0x0000, 0x1530, 0x0000, 0x1632, 0x0008, 0x0d2a, 0x0008, 0x9880,
+ 0x0001, 0x0010, 0x0000, 0x8060, 0x0000, 0x0400, 0x0000, 0x7f62,
+ 0x0008, 0x8066, 0x0000, 0x1e0a, 0x0008, 0x447a, 0x0003, 0x808a,
+ 0x0008, 0x0003, 0x0008, 0x1a60, 0x0000, 0x8062, 0x0008, 0x0002,
+ 0x0000, 0x5880, 0x000b, 0x8066, 0x0000, 0x3679, 0x0000, 0x4483,
+ 0x0003, 0x5884, 0x0003, 0x3efe, 0x0008, 0x7f4f, 0x0002, 0x088a,
+ 0x000b, 0x0d00, 0x0000, 0x0092, 0x000c, 0x8054, 0x0008, 0x0011,
+ 0x0008, 0x8074, 0x0000, 0x1010, 0x0008, 0x1efe, 0x0000, 0x300a,
+ 0x000b, 0x00e0, 0x000c, 0x000a, 0x000b, 0x00fe, 0x0000, 0x349a,
+ 0x0003, 0x1a60, 0x0000, 0x8062, 0x0008, 0x0007, 0x0000, 0x8066,
+ 0x0000, 0x0231, 0x0008, 0x4499, 0x000b, 0x03fe, 0x0000, 0x04d0,
+ 0x0001, 0x0cd4, 0x000b, 0x82c0, 0x0001, 0x1f00, 0x0000, 0xffa0,
+ 0x0001, 0x0400, 0x0000, 0x08b2, 0x0003, 0x14dc, 0x0003, 0x01fe,
+ 0x0008, 0x0580, 0x0009, 0x7f06, 0x0000, 0x8690, 0x0009, 0x0000,
+ 0x0008, 0x7f0c, 0x0000, 0x02fe, 0x0008, 0xffc0, 0x0001, 0x00ff,
+ 0x0008, 0x0680, 0x0009, 0x10b2, 0x0003, 0x7f08, 0x0008, 0x84c0,
+ 0x0001, 0xff00, 0x0008, 0x08d4, 0x0003, 0xb9c0, 0x0009, 0x0030,
+ 0x0008, 0x0cc3, 0x000b, 0x8060, 0x0000, 0x0400, 0x0000, 0x80fe,
+ 0x0008, 0x1a0b, 0x0001, 0x7f62, 0x0008, 0x8066, 0x0000, 0x0409,
+ 0x0000, 0x44bc, 0x0003, 0x80fe, 0x0008, 0x1a0a, 0x0009, 0x7f62,
+ 0x0008, 0x8066, 0x0000, 0x040a, 0x0000, 0x44c2, 0x0003, 0x00fe,
+ 0x0000, 0x34ca, 0x0003, 0x8072, 0x0000, 0x1010, 0x0008, 0x3944,
+ 0x0002, 0x08c5, 0x0003, 0x00ce, 0x0003, 0x8072, 0x0000, 0x2020,
+ 0x0008, 0x3945, 0x000a, 0x08ca, 0x0003, 0x3946, 0x000a, 0x0cdb,
+ 0x000b, 0x0000, 0x0007, 0x3943, 0x000a, 0x08db, 0x0003, 0x00ce,
+ 0x0003, 0x00fe, 0x0000, 0x34d9, 0x000b, 0x8072, 0x0000, 0x1000,
+ 0x0000, 0x00db, 0x000b, 0x8072, 0x0000, 0x2000, 0x0000, 0x4000,
+ 0x000f, 0x86c0, 0x0009, 0xfc00, 0x0008, 0x08d4, 0x0003, 0x00b2,
+ 0x000b, 0x1c60, 0x0000, 0x1b62, 0x0000, 0x8066, 0x0000, 0x0231,
+ 0x0008, 0x44e4, 0x000b, 0x58e5, 0x000b, 0x0140, 0x0008, 0x0242,
+ 0x0000, 0x1f43, 0x0002, 0x0cf3, 0x000b, 0x0d44, 0x0000, 0x0d46,
+ 0x0008, 0x0348, 0x0008, 0x044a, 0x0008, 0x030a, 0x0008, 0x040c,
+ 0x0000, 0x0d06, 0x0000, 0x0d08, 0x0008, 0x00f7, 0x0003, 0x0344,
+ 0x0008, 0x0446, 0x0008, 0x0548, 0x0008, 0x064a, 0x0000, 0x1948,
+ 0x000a, 0x08fa, 0x0003, 0x0d4a, 0x0008, 0x58fa, 0x0003, 0x3efe,
+ 0x0008, 0x7f4f, 0x0002, 0x0901, 0x0003, 0x8000, 0x0000, 0x0001,
+ 0x0000, 0x0092, 0x000c, 0x8054, 0x0008, 0x0001, 0x0000, 0x8074,
+ 0x0000, 0x2020, 0x0008, 0x4000, 0x000f, 0x3a40, 0x000a, 0x0c0d,
+ 0x0003, 0x2b24, 0x0008, 0x2b24, 0x0008, 0x590a, 0x000b, 0x8054,
+ 0x0008, 0x0002, 0x0000, 0x1242, 0x0002, 0x0958, 0x0003, 0x3a45,
+ 0x000a, 0x0947, 0x000b, 0x8072, 0x0000, 0x1000, 0x0000, 0x3945,
+ 0x000a, 0x0917, 0x000b, 0x8072, 0x0000, 0x3010, 0x0000, 0x1e10,
+ 0x000a, 0x7f3c, 0x0000, 0x0942, 0x000b, 0x1d00, 0x0002, 0x7f3a,
+ 0x0000, 0x0d60, 0x0000, 0x7f62, 0x0008, 0x8066, 0x0000, 0x0009,
+ 0x0008, 0x4520, 0x000b, 0x00fe, 0x0000, 0x353f, 0x000b, 0x1c60,
+ 0x0000, 0x8062, 0x0008, 0x0001, 0x0000, 0x8066, 0x0000, 0x0009,
+ 0x0008, 0x4528, 0x0003, 0x00fe, 0x0000, 0x325b, 0x000b, 0x0038,
+ 0x0000, 0x0060, 0x0008, 0x8062, 0x0008, 0x0019, 0x0000, 0x8066,
+ 0x0000, 0x0009, 0x0008, 0x4531, 0x000b, 0x80c0, 0x0009, 0x00ff,
+ 0x0008, 0x7f3e, 0x0008, 0x0d60, 0x0000, 0x0efe, 0x0008, 0x1f80,
+ 0x0001, 0x7f62, 0x0008, 0x8066, 0x0000, 0x0009, 0x0008, 0x453b,
+ 0x000b, 0x003a, 0x0008, 0x1dfe, 0x0000, 0x011c, 0x000b, 0x0036,
+ 0x0008, 0x00e0, 0x000c, 0x0158, 0x000b, 0x8074, 0x0000, 0x2000,
+ 0x0000, 0x8072, 0x0000, 0x2000, 0x0000, 0x0158, 0x000b, 0x3a44,
+ 0x0002, 0x0a89, 0x0003, 0x8074, 0x0000, 0x1000, 0x0000, 0x8072,
+ 0x0000, 0x1000, 0x0000, 0x2d0e, 0x0000, 0x2d0e, 0x0000, 0x3658,
+ 0x0003, 0x26fe, 0x0008, 0x26fe, 0x0008, 0x2700, 0x0008, 0x2700,
+ 0x0008, 0x00d0, 0x0009, 0x0d6a, 0x0003, 0x8074, 0x0000, 0x4040,
+ 0x0008, 0x5958, 0x0003, 0x5106, 0x0003, 0x3a46, 0x000a, 0x0d6a,
+ 0x0003, 0x3a47, 0x0002, 0x0965, 0x000b, 0x8054, 0x0008, 0x0004,
+ 0x0000, 0x8074, 0x0000, 0x8000, 0x0000, 0x8072, 0x0000, 0x3000,
+ 0x0008, 0x01b4, 0x0003, 0x92c0, 0x0009, 0x0fc8, 0x0000, 0x080a,
+ 0x0003, 0x1246, 0x000a, 0x0e52, 0x000b, 0x1a60, 0x0000, 0x8062,
+ 0x0008, 0x0002, 0x0000, 0x8066, 0x0000, 0x362a, 0x0000, 0x456f,
+ 0x0003, 0x2000, 0x0000, 0x2000, 0x0000, 0x2102, 0x0000, 0x2102,
+ 0x0000, 0x2204, 0x0000, 0x2204, 0x0000, 0x2306, 0x0000, 0x2306,
+ 0x0000, 0x2408, 0x0000, 0x2408, 0x0000, 0x250a, 0x0000, 0x250a,
+ 0x0000, 0x260c, 0x0000, 0x260c, 0x0000, 0x270e, 0x0000, 0x270e,
+ 0x0000, 0x2810, 0x0000, 0x2810, 0x0000, 0x2912, 0x0000, 0x2912,
+ 0x0000, 0x1a60, 0x0000, 0x8062, 0x0008, 0x0007, 0x0000, 0x8066,
+ 0x0000, 0x0052, 0x0000, 0x4589, 0x000b, 0x92c0, 0x0009, 0x0780,
+ 0x0008, 0x0e6e, 0x000b, 0x124b, 0x0002, 0x0992, 0x0003, 0x2e4d,
+ 0x0002, 0x2e4d, 0x0002, 0x0a58, 0x0003, 0x3a46, 0x000a, 0x0da2,
+ 0x000b, 0x5994, 0x0003, 0x8054, 0x0008, 0x0004, 0x0000, 0x1243,
+ 0x000a, 0x09b0, 0x0003, 0x8010, 0x0008, 0x000d, 0x0000, 0x0233,
+ 0x000c, 0x1948, 0x000a, 0x099f, 0x000b, 0x0228, 0x000c, 0x1810,
+ 0x0000, 0x0233, 0x000c, 0x01b0, 0x000b, 0x1948, 0x000a, 0x09a6,
+ 0x000b, 0x1243, 0x000a, 0x0a5b, 0x0003, 0x194d, 0x000a, 0x09aa,
+ 0x000b, 0x1243, 0x000a, 0x0a62, 0x0003, 0x59aa, 0x000b, 0x8054,
+ 0x0008, 0x0004, 0x0000, 0x0228, 0x000c, 0x1810, 0x0000, 0x0233,
+ 0x000c, 0x8074, 0x0000, 0xf000, 0x0008, 0x8072, 0x0000, 0x3000,
+ 0x0008, 0x0d30, 0x0000, 0x3a42, 0x0002, 0x0dba, 0x000b, 0x15fe,
+ 0x0008, 0x3461, 0x000b, 0x000a, 0x000b, 0x8074, 0x0000, 0x0501,
+ 0x0000, 0x8010, 0x0008, 0x000c, 0x0008, 0x0233, 0x000c, 0x000a,
+ 0x000b, 0xbbe0, 0x0009, 0x0030, 0x0008, 0x0dd0, 0x000b, 0x18fe,
+ 0x0000, 0x3ce0, 0x0009, 0x09cd, 0x0003, 0x15fe, 0x0008, 0x3ce0,
+ 0x0009, 0x09cd, 0x0003, 0x0223, 0x0004, 0x8076, 0x0008, 0x0040,
+ 0x0000, 0x0220, 0x000b, 0x8076, 0x0008, 0x0041, 0x0008, 0x0220,
+ 0x000b, 0xbbe0, 0x0009, 0x0032, 0x0000, 0x0dd5, 0x000b, 0x3c1e,
+ 0x0008, 0x0220, 0x000b, 0xbbe0, 0x0009, 0x003b, 0x0000, 0x0dda,
+ 0x000b, 0x3c20, 0x0000, 0x0220, 0x000b, 0xbbe0, 0x0009, 0x0035,
+ 0x0008, 0x0de0, 0x000b, 0x8072, 0x0000, 0x8000, 0x0000, 0x039c,
+ 0x000b, 0xbbe0, 0x0009, 0x0036, 0x0008, 0x0abd, 0x000b, 0xbbe0,
+ 0x0009, 0x0037, 0x0000, 0x0e01, 0x000b, 0x18fe, 0x0000, 0x3ce0,
+ 0x0009, 0x0dcd, 0x000b, 0x8076, 0x0008, 0x0040, 0x0000, 0x1a60,
+ 0x0000, 0x8062, 0x0008, 0x000d, 0x0000, 0x2604, 0x0008, 0x2604,
+ 0x0008, 0x2706, 0x0008, 0x2706, 0x0008, 0x2808, 0x0000, 0x2808,
+ 0x0000, 0x290a, 0x0000, 0x290a, 0x0000, 0x8066, 0x0000, 0x0422,
+ 0x0000, 0x45f8, 0x000b, 0x0228, 0x000c, 0x8054, 0x0008, 0x0004,
+ 0x0000, 0x8074, 0x0000, 0xf000, 0x0008, 0x8072, 0x0000, 0xb000,
+ 0x0000, 0x01b4, 0x0003, 0xbbe0, 0x0009, 0x0038, 0x0000, 0x0e13,
+ 0x000b, 0x18fe, 0x0000, 0x3ce0, 0x0009, 0x0a10, 0x0003, 0x15fe,
+ 0x0008, 0x3ce0, 0x0009, 0x0dc9, 0x0003, 0x0223, 0x0004, 0x8076,
+ 0x0008, 0x0040, 0x0000, 0x8072, 0x0000, 0x8000, 0x0000, 0x0280,
+ 0x000b, 0x8076, 0x0008, 0x0042, 0x0008, 0x0220, 0x000b, 0xbbe0,
+ 0x0009, 0x0016, 0x0000, 0x0e20, 0x000b, 0x8074, 0x0000, 0x0808,
+ 0x0008, 0x3a44, 0x0002, 0x0c0c, 0x000b, 0x8074, 0x0000, 0x0800,
+ 0x0000, 0x8072, 0x0000, 0x8000, 0x0000, 0x8000, 0x000f, 0x000a,
+ 0x000b, 0x8072, 0x0000, 0x8000, 0x0000, 0x000a, 0x000b, 0x3d30,
+ 0x000a, 0x7f00, 0x0000, 0xbc80, 0x0001, 0x0007, 0x0000, 0x022c,
+ 0x000b, 0x1930, 0x000a, 0x7f00, 0x0000, 0x9880, 0x0001, 0x0007,
+ 0x0000, 0x8060, 0x0000, 0x0400, 0x0000, 0x7f62, 0x0008, 0x8066,
+ 0x0000, 0x000a, 0x0008, 0x4631, 0x000b, 0x4000, 0x000f, 0x2236,
+ 0x000b, 0x0870, 0x0008, 0x4000, 0x000f, 0x7e33, 0x000b, 0xbbe0,
+ 0x0009, 0x0030, 0x0008, 0x0e33, 0x0003, 0x18fe, 0x0000, 0x3ce0,
+ 0x0009, 0x0a44, 0x000b, 0x15fe, 0x0008, 0x3ce0, 0x0009, 0x0a44,
+ 0x000b, 0x0223, 0x0004, 0x8076, 0x0008, 0x0040, 0x0000, 0x0246,
+ 0x000b, 0x8076, 0x0008, 0x0041, 0x0008, 0x8072, 0x0000, 0x8000,
+ 0x0000, 0x0233, 0x0003, 0xbac0, 0x0009, 0x0090, 0x0008, 0x0a4f,
+ 0x0003, 0x8074, 0x0000, 0x0706, 0x0000, 0x0251, 0x000b, 0x8074,
+ 0x0000, 0x0703, 0x0000, 0x4000, 0x000f, 0x8010, 0x0008, 0x0023,
+ 0x0000, 0x028e, 0x0003, 0x8010, 0x0008, 0x0008, 0x0000, 0x028e,
+ 0x0003, 0x8010, 0x0008, 0x0022, 0x0008, 0x028e, 0x0003, 0x0228,
+ 0x000c, 0x8010, 0x0008, 0x0007, 0x0000, 0x0233, 0x000c, 0x1810,
+ 0x0000, 0x0233, 0x000c, 0x029a, 0x0003, 0x0228, 0x000c, 0x8010,
+ 0x0008, 0x001b, 0x0008, 0x0233, 0x000c, 0x1810, 0x0000, 0x0233,
+ 0x000c, 0x8074, 0x0000, 0xf080, 0x0000, 0x8072, 0x0000, 0x3000,
+ 0x0008, 0x0d30, 0x0000, 0x000a, 0x000b, 0x8010, 0x0008, 0x0009,
+ 0x0008, 0x028e, 0x0003, 0x8010, 0x0008, 0x0005, 0x0008, 0x028e,
+ 0x0003, 0x1648, 0x000a, 0x0c6f, 0x000b, 0x808c, 0x0008, 0x0001,
+ 0x0000, 0x8010, 0x0008, 0x0004, 0x0000, 0x4143, 0x000a, 0x086f,
+ 0x0003, 0x3a44, 0x0002, 0x0c0a, 0x000b, 0x0d2a, 0x0008, 0x028e,
+ 0x0003, 0x8010, 0x0008, 0x0003, 0x0008, 0x0292, 0x000b, 0x8010,
+ 0x0008, 0x000b, 0x0000, 0x0292, 0x000b, 0x8010, 0x0008, 0x0002,
+ 0x0000, 0x0292, 0x000b, 0x3a47, 0x0002, 0x0d58, 0x000b, 0x8010,
+ 0x0008, 0x0006, 0x0008, 0x0292, 0x000b, 0x8074, 0x0000, 0xf000,
+ 0x0008, 0x8072, 0x0000, 0x3000, 0x0008, 0x0233, 0x000c, 0x0249,
+ 0x0004, 0x3a40, 0x000a, 0x080a, 0x0003, 0x8010, 0x0008, 0x000c,
+ 0x0008, 0x0233, 0x000c, 0x000a, 0x000b, 0x8074, 0x0000, 0xf080,
+ 0x0000, 0x8072, 0x0000, 0x3000, 0x0008, 0x0d30, 0x0000, 0x2e4d,
+ 0x0002, 0x2e4d, 0x0002, 0x0aa5, 0x000b, 0x8054, 0x0008, 0x0019,
+ 0x0000, 0x000a, 0x000b, 0x8054, 0x0008, 0x0009, 0x0008, 0x000a,
+ 0x000b, 0x3a44, 0x0002, 0x0c0a, 0x000b, 0x0283, 0x000b, 0x808c,
+ 0x0008, 0x0000, 0x0008, 0x4447, 0x0002, 0x0ad1, 0x000b, 0xc0c0,
+ 0x0001, 0x00ff, 0x0008, 0xffe0, 0x0009, 0x00ff, 0x0008, 0x0ea8,
+ 0x000b, 0xc1e0, 0x0001, 0xffff, 0x0008, 0x0ea8, 0x000b, 0x8010,
+ 0x0008, 0x0013, 0x0000, 0x0233, 0x000c, 0x8074, 0x0000, 0x0202,
+ 0x0008, 0x000a, 0x000b, 0x3a40, 0x000a, 0x0ece, 0x000b, 0x8074,
+ 0x0000, 0x0200, 0x0000, 0x3d00, 0x0000, 0x3cfe, 0x0000, 0x8072,
+ 0x0000, 0x8000, 0x0000, 0x43e0, 0x0001, 0x0ecc, 0x0003, 0x42fe,
+ 0x0000, 0xffc0, 0x0001, 0x00ff, 0x0008, 0x00e0, 0x0009, 0x0aa8,
+ 0x0003, 0x0d08, 0x0008, 0x0321, 0x000b, 0x8072, 0x0000, 0x8000,
+ 0x0000, 0x000a, 0x000b, 0x03a5, 0x0004, 0x808c, 0x0008, 0x0001,
+ 0x0000, 0x04fe, 0x0008, 0x3388, 0x000b, 0x0460, 0x0000, 0x8062,
+ 0x0008, 0x0001, 0x0000, 0x8066, 0x0000, 0x0009, 0x0008, 0x46db,
+ 0x0003, 0x0004, 0x0000, 0x80c0, 0x0009, 0x00ff, 0x0008, 0x7f00,
+ 0x0000, 0x80e0, 0x0001, 0x0004, 0x0000, 0x0af5, 0x000b, 0x80e0,
+ 0x0001, 0x0005, 0x0008, 0x0af5, 0x000b, 0x80e0, 0x0001, 0x0006,
+ 0x0008, 0x0af5, 0x000b, 0x82c0, 0x0001, 0xff00, 0x0008, 0x7f04,
+ 0x0008, 0x82e0, 0x0009, 0x0600, 0x0008, 0x0af5, 0x000b, 0x82e0,
+ 0x0009, 0x0500, 0x0008, 0x0af5, 0x000b, 0x82e0, 0x0009, 0x0400,
+ 0x0000, 0x0f88, 0x000b, 0xc4c0, 0x0009, 0x7000, 0x0000, 0xffe0,
+ 0x0009, 0x1000, 0x0000, 0x0b21, 0x0003, 0x0396, 0x0004, 0x3941,
+ 0x0002, 0x0b00, 0x0003, 0x8072, 0x0000, 0x0400, 0x0000, 0x000a,
+ 0x000b, 0x0460, 0x0000, 0x80fe, 0x0008, 0x002b, 0x0008, 0x7f62,
+ 0x0008, 0x8066, 0x0000, 0x2209, 0x0008, 0x4706, 0x000b, 0x11fe,
+ 0x0000, 0x331c, 0x0003, 0x9180, 0x0001, 0x0002, 0x0000, 0x8060,
+ 0x0000, 0x0400, 0x0000, 0x7f62, 0x0008, 0x8066, 0x0000, 0x0609,
+ 0x0008, 0x4710, 0x0003, 0x42fe, 0x0000, 0xffc0, 0x0001, 0xff00,
+ 0x0008, 0x03e0, 0x0009, 0x0f19, 0x0003, 0x8072, 0x0000, 0x0400,
+ 0x0000, 0x0046, 0x0003, 0x9180, 0x0001, 0x0003, 0x0008, 0x0303,
+ 0x000b, 0x8072, 0x0000, 0x0400, 0x0000, 0x8010, 0x0008, 0x0010,
+ 0x0000, 0x0379, 0x0003, 0x0396, 0x0004, 0x3941, 0x0002, 0x0b27,
+ 0x0003, 0x8072, 0x0000, 0x0400, 0x0000, 0x000a, 0x000b, 0x035e,
+ 0x000c, 0x11fe, 0x0000, 0x372f, 0x000b, 0x8072, 0x0000, 0x0400,
+ 0x0000, 0x8010, 0x0008, 0x000e, 0x0000, 0x0379, 0x0003, 0x8060,
+ 0x0000, 0x0400, 0x0000, 0x04fe, 0x0008, 0x3744, 0x0003, 0x808c,
+ 0x0008, 0x0000, 0x0008, 0x9180, 0x0001, 0x0005, 0x0008, 0x7f62,
+ 0x0008, 0x8066, 0x0000, 0x0009, 0x0008, 0x473a, 0x000b, 0x0060,
+ 0x0008, 0x8062, 0x0008, 0x001b, 0x0008, 0x4304, 0x0008, 0x4206,
+ 0x0008, 0x8066, 0x0000, 0x0412, 0x0000, 0x4742, 0x000b, 0x035b,
+ 0x0003, 0x808c, 0x0008, 0x0001, 0x0000, 0x0460, 0x0000, 0x8062,
+ 0x0008, 0x002b, 0x0008, 0x8066, 0x0000, 0x0609, 0x0008, 0x474b,
+ 0x000b, 0x8066, 0x0000, 0x220a, 0x0008, 0x474e, 0x000b, 0x42fe,
+ 0x0000, 0xffc0, 0x0001, 0xff00, 0x0008, 0x7f04, 0x0008, 0x8060,
+ 0x0000, 0x0400, 0x0000, 0x9180, 0x0001, 0x0002, 0x0000, 0x7f62,
+ 0x0008, 0x8066, 0x0000, 0x041a, 0x0008, 0x475a, 0x000b, 0x8072,
+ 0x0000, 0x0400, 0x0000, 0x0046, 0x0003, 0x8060, 0x0000, 0x0400,
+ 0x0000, 0x1362, 0x0008, 0x8066, 0x0000, 0x0411, 0x0000, 0x4763,
+ 0x000b, 0x02fe, 0x0008, 0x03e0, 0x0009, 0x0f69, 0x000b, 0x0d22,
+ 0x0000, 0x4000, 0x000f, 0x8280, 0x0009, 0x0002, 0x0000, 0x1380,
+ 0x0001, 0x7f62, 0x0008, 0x8066, 0x0000, 0x2209, 0x0008, 0x476f,
+ 0x000b, 0x0200, 0x000a, 0xffc0, 0x0001, 0x0007, 0x0000, 0x7f06,
+ 0x0000, 0x1362, 0x0008, 0x8066, 0x0000, 0x060a, 0x0008, 0x4777,
+ 0x000b, 0x4000, 0x000f, 0x3a44, 0x0002, 0x0c0a, 0x000b, 0x2f44,
+ 0x000a, 0x2f44, 0x000a, 0x0e83, 0x000b, 0x808a, 0x0008, 0x0003,
+ 0x0008, 0x8074, 0x0000, 0xf080, 0x0000, 0x8072, 0x0000, 0x3000,
+ 0x0008, 0x5b84, 0x0003, 0x8054, 0x0008, 0x0019, 0x0000, 0x000a,
+ 0x000b, 0x3a44, 0x0002, 0x0c0a, 0x000b, 0x808c, 0x0008, 0x0000,
+ 0x0008, 0x8010, 0x0008, 0x0011, 0x0008, 0x0233, 0x000c, 0x42fe,
+ 0x0000, 0xffc0, 0x0001, 0x00ff, 0x0008, 0x7f10, 0x0008, 0x0233,
+ 0x000c, 0x4310, 0x0008, 0x0292, 0x000b, 0x3941, 0x0002, 0x0b99,
+ 0x0003, 0x4000, 0x000f, 0x8072, 0x0000, 0x0404, 0x0008, 0x4000,
+ 0x000f, 0x8010, 0x0008, 0x0012, 0x0008, 0x0233, 0x000c, 0x035e,
+ 0x000c, 0x1110, 0x0000, 0x0233, 0x000c, 0x11fe, 0x0000, 0x379f,
+ 0x0003, 0x000a, 0x000b, 0xc2c0, 0x0009, 0x00ff, 0x0008, 0x7f00,
+ 0x0000, 0xc3c0, 0x0001, 0xff00, 0x0008, 0x00d0, 0x0009, 0x0bca,
+ 0x0003, 0x0d0a, 0x0000, 0x8580, 0x0001, 0x1000, 0x0000, 0x7f62,
+ 0x0008, 0x8060, 0x0000, 0x0400, 0x0000, 0x8066, 0x0000, 0x0809,
+ 0x0000, 0x47b4, 0x000b, 0x04fe, 0x0008, 0x33c3, 0x000b, 0x0460,
+ 0x0000, 0x8062, 0x0008, 0x0004, 0x0000, 0x8066, 0x0000, 0x0211,
+ 0x0000, 0x47bc, 0x0003, 0x01fe, 0x0008, 0x00e0, 0x0009, 0x0fc3,
+ 0x000b, 0x02fe, 0x0008, 0x43e0, 0x0001, 0x0bc9, 0x0003, 0x0500,
+ 0x0002, 0x7f0a, 0x0000, 0xffe0, 0x0009, 0x0800, 0x0000, 0x0fad,
+ 0x0003, 0x0d08, 0x0008, 0x4000, 0x000f, 0x43fe, 0x0008, 0x3e80,
+ 0x0001, 0xffc0, 0x0001, 0x7fff, 0x0000, 0x0d60, 0x0000, 0x7f62,
+ 0x0008, 0x8066, 0x0000, 0x0809, 0x0000, 0x47d2, 0x000b, 0x8060,
+ 0x0000, 0x0400, 0x0000, 0x84c0, 0x0001, 0xff00, 0x0008, 0x7f60,
+ 0x000a, 0x7f60, 0x000a, 0x7f60, 0x000a, 0x7f60, 0x000a, 0x7f60,
+ 0x000a, 0x7f60, 0x000a, 0x7f60, 0x000a, 0x7f60, 0x000a, 0xff80,
+ 0x0009, 0x1000, 0x0000, 0x7f62, 0x0008, 0x8066, 0x0000, 0x0809,
+ 0x0000, 0x47e4, 0x000b, 0x4000, 0x000f, 0xa90f, 0xeaf9, 0x0001,
+ 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080, 0x0100,
+ 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000, 0x8000, 0x95d0
};
#ifdef UNIQUE_FW_NAME
-unsigned short fw2300ipx_length01 = 0xed9d;
+unsigned short fw2300ipx_length01 = 0xee08;
#else
-unsigned short risc_code_length01 = 0xed9d;
+unsigned short risc_code_length01 = 0xee08;
#endif
diff --git a/drivers/scsi/qla2xxx/ql2322.c b/drivers/scsi/qla2xxx/ql2322.c
index bfe918a4a2cf..c88a22c0d93a 100644
--- a/drivers/scsi/qla2xxx/ql2322.c
+++ b/drivers/scsi/qla2xxx/ql2322.c
@@ -1,10 +1,9 @@
/*
- * QLogic ISP2322 device driver for Linux 2.6.x
- * Copyright (C) 2003-2005 QLogic Corporation (www.qlogic.com)
+ * QLogic Fibre Channel HBA Driver
+ * Copyright (c) 2003-2005 QLogic Corporation
*
- * Released under GPL v2.
+ * See LICENSE.qla2xxx for copyright and licensing details.
*/
-
#include <linux/init.h>
#include <linux/module.h>
#include <linux/pci.h>
diff --git a/drivers/scsi/qla2xxx/ql2322_fw.c b/drivers/scsi/qla2xxx/ql2322_fw.c
index 2645d6239b74..cb968e7a0fcd 100644
--- a/drivers/scsi/qla2xxx/ql2322_fw.c
+++ b/drivers/scsi/qla2xxx/ql2322_fw.c
@@ -1,24 +1,12 @@
-/******************************************************************************
- * QLOGIC LINUX SOFTWARE
- *
- * QLogic ISP2x00 device driver for Linux 2.6.x
- * Copyright (C) 2005 QLogic Corporation
- * (www.qlogic.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, 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.
+/*
+ * QLogic Fibre Channel HBA Driver
+ * Copyright (c) 2003-2005 QLogic Corporation
*
- ******************************************************************************/
+ * See LICENSE.qla2xxx for copyright and licensing details.
+ */
/*
- * Firmware Version 3.03.15 (10:09 May 26, 2005)
+ * Firmware Version 3.03.18 (12:14 Sep 20, 2005)
*/
#ifdef UNIQUE_FW_NAME
@@ -28,15 +16,15 @@ unsigned short risc_code_version = 3*1024+3;
#endif
#ifdef UNIQUE_FW_NAME
-unsigned char fw2322ipx_version_str[] = {3, 3,15};
+unsigned char fw2322ipx_version_str[] = {3, 3,18};
#else
-unsigned char firmware_version[] = {3, 3,15};
+unsigned char firmware_version[] = {3, 3,18};
#endif
#ifdef UNIQUE_FW_NAME
-#define fw2322ipx_VERSION_STRING "3.03.15"
+#define fw2322ipx_VERSION_STRING "3.03.18"
#else
-#define FW_VERSION_STRING "3.03.15"
+#define FW_VERSION_STRING "3.03.18"
#endif
#ifdef UNIQUE_FW_NAME
@@ -50,12 +38,12 @@ unsigned short fw2322ipx_code01[] = {
#else
unsigned short risc_code01[] = {
#endif
- 0x0470, 0x0000, 0x0000, 0xe3bd, 0x0000, 0x0003, 0x0003, 0x000f,
+ 0x0470, 0x0000, 0x0000, 0xe428, 0x0000, 0x0003, 0x0003, 0x0012,
0x0137, 0x2043, 0x4f50, 0x5952, 0x4947, 0x4854, 0x2032, 0x3030,
0x3120, 0x514c, 0x4f47, 0x4943, 0x2043, 0x4f52, 0x504f, 0x5241,
0x5449, 0x4f4e, 0x2049, 0x5350, 0x3233, 0x3030, 0x2046, 0x6972,
0x6d77, 0x6172, 0x6520, 0x2056, 0x6572, 0x7369, 0x6f6e, 0x2030,
- 0x332e, 0x3033, 0x2e31, 0x3520, 0x2020, 0x2020, 0x2400, 0x20a9,
+ 0x332e, 0x3033, 0x2e31, 0x3820, 0x2020, 0x2020, 0x2400, 0x20a9,
0x000f, 0x2001, 0x0000, 0x400f, 0x2091, 0x2200, 0x20a9, 0x000f,
0x2001, 0x0000, 0x400f, 0x2091, 0x2400, 0x20a9, 0x000f, 0x2001,
0x0000, 0x400f, 0x2091, 0x2600, 0x20a9, 0x000f, 0x2001, 0x0000,
@@ -64,11 +52,11 @@ unsigned short risc_code01[] = {
0x2c00, 0x20a9, 0x000f, 0x2001, 0x0000, 0x400f, 0x2091, 0x2e00,
0x20a9, 0x000f, 0x2001, 0x0000, 0x400f, 0x2091, 0x2000, 0x2001,
0x0000, 0x20c1, 0x0004, 0x20c9, 0x1cff, 0x2059, 0x0000, 0x2b78,
- 0x7883, 0x0004, 0x2089, 0x2be4, 0x2051, 0x1800, 0x2a70, 0x20e1,
- 0x0001, 0x20e9, 0x0001, 0x2009, 0x0000, 0x080c, 0x0e74, 0x00f6,
- 0x7888, 0x9005, 0x11f8, 0x2061, 0xc000, 0x080c, 0x20e7, 0x1170,
- 0x2079, 0x0300, 0x080c, 0x20fd, 0x2061, 0xe000, 0x080c, 0x20e7,
- 0x1128, 0x2079, 0x0380, 0x080c, 0x20fd, 0x0060, 0x00fe, 0x7883,
+ 0x7883, 0x0004, 0x2089, 0x2bcb, 0x2051, 0x1800, 0x2a70, 0x20e1,
+ 0x0001, 0x20e9, 0x0001, 0x2009, 0x0000, 0x080c, 0x0e68, 0x00f6,
+ 0x7888, 0x9005, 0x11f8, 0x2061, 0xc000, 0x080c, 0x20e3, 0x1170,
+ 0x2079, 0x0300, 0x080c, 0x20f9, 0x2061, 0xe000, 0x080c, 0x20e3,
+ 0x1128, 0x2079, 0x0380, 0x080c, 0x20f9, 0x0060, 0x00fe, 0x7883,
0x4010, 0x7837, 0x4010, 0x7833, 0x0011, 0x2091, 0x5000, 0x2091,
0x4080, 0x0cf8, 0x00fe, 0x2029, 0x5600, 0x2031, 0xffff, 0x2039,
0x55dc, 0x2021, 0x0200, 0x20e9, 0x0001, 0x20a1, 0x0000, 0x20a9,
@@ -82,3087 +70,3086 @@ unsigned short risc_code01[] = {
0x20a8, 0x900e, 0x4104, 0x2009, 0x1800, 0x810d, 0x810d, 0x810d,
0x810d, 0x810d, 0x918c, 0x001f, 0x2001, 0x0001, 0x9112, 0x20e9,
0x0001, 0x20a1, 0x0800, 0x900e, 0x20a9, 0x0800, 0x4104, 0x8211,
- 0x1dd8, 0x080c, 0x0f71, 0x080c, 0x618c, 0x080c, 0xaec4, 0x080c,
- 0x1128, 0x080c, 0x1352, 0x080c, 0x1c3d, 0x080c, 0x9393, 0x080c,
- 0x0d17, 0x080c, 0x10ad, 0x080c, 0x3589, 0x080c, 0x79bb, 0x080c,
- 0x6bf9, 0x080c, 0x8afe, 0x080c, 0x875f, 0x080c, 0x22d8, 0x080c,
- 0x8096, 0x080c, 0x2116, 0x080c, 0x2254, 0x080c, 0x22cd, 0x2091,
+ 0x1dd8, 0x080c, 0x0f65, 0x080c, 0x6186, 0x080c, 0xaee4, 0x080c,
+ 0x111c, 0x080c, 0x1346, 0x080c, 0x1c39, 0x080c, 0x938b, 0x080c,
+ 0x0d0b, 0x080c, 0x10a1, 0x080c, 0x3574, 0x080c, 0x79b3, 0x080c,
+ 0x6bf1, 0x080c, 0x8af6, 0x080c, 0x8757, 0x080c, 0x22d4, 0x080c,
+ 0x808e, 0x080c, 0x2112, 0x080c, 0x2250, 0x080c, 0x22c9, 0x2091,
0x3009, 0x7883, 0x0000, 0x1004, 0x0943, 0x7880, 0x9086, 0x0002,
0x1190, 0x7883, 0x4000, 0x7837, 0x4000, 0x7833, 0x0010, 0x0e04,
0x0937, 0x2091, 0x5000, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004,
- 0xd084, 0x190c, 0x1200, 0x2071, 0x1800, 0x7003, 0x0000, 0x780c,
- 0x9084, 0x0030, 0x9086, 0x0000, 0x190c, 0x0d85, 0x2071, 0x1800,
- 0x7000, 0x908e, 0x0003, 0x1168, 0x080c, 0x4cf3, 0x080c, 0x35b0,
- 0x080c, 0x7a23, 0x080c, 0x717c, 0x080c, 0x8be5, 0x080c, 0x8788,
+ 0xd084, 0x190c, 0x11f4, 0x2071, 0x1800, 0x7003, 0x0000, 0x780c,
+ 0x9084, 0x0030, 0x9086, 0x0000, 0x190c, 0x0d79, 0x2071, 0x1800,
+ 0x7000, 0x908e, 0x0003, 0x1168, 0x080c, 0x4ced, 0x080c, 0x359b,
+ 0x080c, 0x7a1b, 0x080c, 0x7174, 0x080c, 0x8bdd, 0x080c, 0x8780,
0x0c68, 0x000b, 0x0c88, 0x096d, 0x096e, 0x0b09, 0x096b, 0x0bc3,
- 0x0d16, 0x0d16, 0x0d16, 0x080c, 0x0d85, 0x0005, 0x0126, 0x00f6,
+ 0x0d0a, 0x0d0a, 0x0d0a, 0x080c, 0x0d79, 0x0005, 0x0126, 0x00f6,
0x2091, 0x8000, 0x7000, 0x9086, 0x0001, 0x1904, 0x0adc, 0x080c,
- 0x0ec4, 0x080c, 0x76a5, 0x0150, 0x080c, 0x76c8, 0x15b0, 0x2079,
- 0x0100, 0x7828, 0x9085, 0x1800, 0x782a, 0x0478, 0x080c, 0x75d4,
+ 0x0eb8, 0x080c, 0x769d, 0x0150, 0x080c, 0x76c0, 0x15b0, 0x2079,
+ 0x0100, 0x7828, 0x9085, 0x1800, 0x782a, 0x0478, 0x080c, 0x75cc,
0x7000, 0x9086, 0x0001, 0x1904, 0x0adc, 0x7098, 0x9086, 0x0029,
- 0x1904, 0x0adc, 0x080c, 0x8748, 0x080c, 0x873a, 0x2001, 0x0161,
- 0x2003, 0x0001, 0x2079, 0x0100, 0x2011, 0xffff, 0x080c, 0x2af5,
- 0x7a28, 0x9295, 0x5e2c, 0x7a2a, 0x2011, 0x7519, 0x080c, 0x8834,
- 0x2011, 0x750c, 0x080c, 0x8940, 0x2011, 0x5fe3, 0x080c, 0x8834,
- 0x2011, 0x8030, 0x901e, 0x7396, 0x04d0, 0x080c, 0x5890, 0x2079,
- 0x0100, 0x7844, 0x9005, 0x1904, 0x0adc, 0x2011, 0x5fe3, 0x080c,
- 0x8834, 0x2011, 0x7519, 0x080c, 0x8834, 0x2011, 0x750c, 0x080c,
- 0x8940, 0x2001, 0x0265, 0x2001, 0x0205, 0x2003, 0x0000, 0x7840,
- 0x9084, 0xfffb, 0x7842, 0x2001, 0x19a7, 0x2004, 0x9005, 0x1140,
- 0x00c6, 0x2061, 0x0100, 0x080c, 0x6134, 0x00ce, 0x0804, 0x0adc,
- 0x780f, 0x006b, 0x7a28, 0x080c, 0x76ad, 0x0118, 0x9295, 0x5e2c,
+ 0x1904, 0x0adc, 0x080c, 0x8740, 0x080c, 0x8732, 0x2001, 0x0161,
+ 0x2003, 0x0001, 0x2079, 0x0100, 0x2011, 0xffff, 0x080c, 0x2adc,
+ 0x7a28, 0x9295, 0x5e2c, 0x7a2a, 0x2011, 0x7511, 0x080c, 0x882c,
+ 0x2011, 0x7504, 0x080c, 0x8938, 0x2011, 0x5fdd, 0x080c, 0x882c,
+ 0x2011, 0x8030, 0x901e, 0x7396, 0x04d0, 0x080c, 0x588a, 0x2079,
+ 0x0100, 0x7844, 0x9005, 0x1904, 0x0adc, 0x2011, 0x5fdd, 0x080c,
+ 0x882c, 0x2011, 0x7511, 0x080c, 0x882c, 0x2011, 0x7504, 0x080c,
+ 0x8938, 0x2001, 0x0265, 0x2001, 0x0205, 0x2003, 0x0000, 0x7840,
+ 0x9084, 0xfffb, 0x7842, 0x2001, 0x19a8, 0x2004, 0x9005, 0x1140,
+ 0x00c6, 0x2061, 0x0100, 0x080c, 0x612e, 0x00ce, 0x0804, 0x0adc,
+ 0x780f, 0x006b, 0x7a28, 0x080c, 0x76a5, 0x0118, 0x9295, 0x5e2c,
0x0010, 0x9295, 0x402c, 0x7a2a, 0x2011, 0x8010, 0x73d8, 0x2001,
- 0x19a8, 0x2003, 0x0001, 0x080c, 0x29bd, 0x080c, 0x4c2e, 0x7248,
+ 0x19a9, 0x2003, 0x0001, 0x080c, 0x29a8, 0x080c, 0x4c28, 0x7248,
0xc284, 0x724a, 0x2001, 0x180c, 0x200c, 0xc1ac, 0xc1cc, 0x2102,
- 0x2001, 0x0390, 0x2003, 0x0400, 0x080c, 0xaae0, 0x080c, 0xa2db,
- 0x2011, 0x0004, 0x080c, 0xcc26, 0x080c, 0xaafc, 0x080c, 0x6a7f,
- 0x080c, 0x76a5, 0x1120, 0x080c, 0x2a1e, 0x0600, 0x0420, 0x080c,
- 0x613b, 0x0140, 0x7097, 0x0001, 0x70d3, 0x0000, 0x080c, 0x5a5d,
- 0x0804, 0x0adc, 0x2001, 0x0390, 0x2003, 0x0404, 0x080c, 0x5826,
+ 0x2001, 0x0390, 0x2003, 0x0400, 0x080c, 0xaaf7, 0x080c, 0xa2ec,
+ 0x2011, 0x0004, 0x080c, 0xcc43, 0x080c, 0xab13, 0x080c, 0x6a77,
+ 0x080c, 0x769d, 0x1120, 0x080c, 0x2a09, 0x0600, 0x0420, 0x080c,
+ 0x6135, 0x0140, 0x7097, 0x0001, 0x70d3, 0x0000, 0x080c, 0x5a57,
+ 0x0804, 0x0adc, 0x2001, 0x0390, 0x2003, 0x0404, 0x080c, 0x5820,
0xd094, 0x0188, 0x2011, 0x180c, 0x2204, 0xc0cd, 0x2012, 0x080c,
- 0x582a, 0xd0d4, 0x1118, 0x080c, 0x2a1e, 0x1270, 0x2011, 0x180c,
- 0x2204, 0xc0bc, 0x00a8, 0x080c, 0x582a, 0xd0d4, 0x1db8, 0x2011,
+ 0x5824, 0xd0d4, 0x1118, 0x080c, 0x2a09, 0x1270, 0x2011, 0x180c,
+ 0x2204, 0xc0bc, 0x00a8, 0x080c, 0x5824, 0xd0d4, 0x1db8, 0x2011,
0x180c, 0x2204, 0xc0bd, 0x0060, 0x2011, 0x180c, 0x2204, 0xc0bd,
- 0x2012, 0x080c, 0x6bcd, 0x1128, 0xd0a4, 0x0118, 0x2204, 0xc0fd,
- 0x2012, 0x080c, 0x6b93, 0x0120, 0x7a0c, 0xc2b4, 0x7a0e, 0x00a8,
- 0x707f, 0x0000, 0x080c, 0x76a5, 0x1130, 0x70b0, 0x9005, 0x1168,
- 0x080c, 0xd084, 0x0050, 0x080c, 0xd084, 0x70dc, 0xd09c, 0x1128,
- 0x70b0, 0x9005, 0x0110, 0x080c, 0x6111, 0x70e7, 0x0000, 0x70e3,
- 0x0000, 0x70a7, 0x0000, 0x080c, 0x2a26, 0x0228, 0x2011, 0x0101,
- 0x2204, 0xc0c4, 0x2012, 0x72dc, 0x080c, 0x76a5, 0x1178, 0x9016,
- 0x0016, 0x080c, 0x27ba, 0x2019, 0x196e, 0x211a, 0x001e, 0x705f,
+ 0x2012, 0x080c, 0x6bc5, 0x1128, 0xd0a4, 0x0118, 0x2204, 0xc0fd,
+ 0x2012, 0x080c, 0x6b8b, 0x0120, 0x7a0c, 0xc2b4, 0x7a0e, 0x00a8,
+ 0x707f, 0x0000, 0x080c, 0x769d, 0x1130, 0x70b0, 0x9005, 0x1168,
+ 0x080c, 0xd0a1, 0x0050, 0x080c, 0xd0a1, 0x70dc, 0xd09c, 0x1128,
+ 0x70b0, 0x9005, 0x0110, 0x080c, 0x610b, 0x70e7, 0x0000, 0x70e3,
+ 0x0000, 0x70a7, 0x0000, 0x080c, 0x2a11, 0x0228, 0x2011, 0x0101,
+ 0x2204, 0xc0c4, 0x2012, 0x72dc, 0x080c, 0x769d, 0x1178, 0x9016,
+ 0x0016, 0x080c, 0x27b9, 0x2019, 0x196e, 0x211a, 0x001e, 0x705f,
0xffff, 0x7063, 0x00ef, 0x7083, 0x0000, 0x0020, 0x2019, 0x196e,
0x201b, 0x0000, 0x2079, 0x1847, 0x7804, 0xd0ac, 0x0108, 0xc295,
- 0x72de, 0x080c, 0x76a5, 0x0118, 0x9296, 0x0004, 0x0518, 0x2011,
- 0x0001, 0x080c, 0xcc26, 0x70ab, 0x0000, 0x70af, 0xffff, 0x7003,
- 0x0002, 0x00fe, 0x080c, 0x30e1, 0x080c, 0xaae0, 0x2011, 0x0005,
- 0x080c, 0xa40f, 0x080c, 0xaafc, 0x080c, 0x76a5, 0x0148, 0x00c6,
- 0x2061, 0x0100, 0x0016, 0x080c, 0x27ba, 0x61e2, 0x001e, 0x00ce,
+ 0x72de, 0x080c, 0x769d, 0x0118, 0x9296, 0x0004, 0x0518, 0x2011,
+ 0x0001, 0x080c, 0xcc43, 0x70ab, 0x0000, 0x70af, 0xffff, 0x7003,
+ 0x0002, 0x00fe, 0x080c, 0x30c8, 0x080c, 0xaaf7, 0x2011, 0x0005,
+ 0x080c, 0xa426, 0x080c, 0xab13, 0x080c, 0x769d, 0x0148, 0x00c6,
+ 0x2061, 0x0100, 0x0016, 0x080c, 0x27b9, 0x61e2, 0x001e, 0x00ce,
0x012e, 0x00e0, 0x70ab, 0x0000, 0x70af, 0xffff, 0x7003, 0x0002,
- 0x080c, 0xaae0, 0x2011, 0x0005, 0x080c, 0xa40f, 0x080c, 0xaafc,
- 0x080c, 0x76a5, 0x0148, 0x00c6, 0x2061, 0x0100, 0x0016, 0x080c,
- 0x27ba, 0x61e2, 0x001e, 0x00ce, 0x00fe, 0x012e, 0x0005, 0x00c6,
- 0x00b6, 0x080c, 0x76a5, 0x1118, 0x20a9, 0x0800, 0x0010, 0x20a9,
- 0x0782, 0x080c, 0x76a5, 0x1110, 0x900e, 0x0010, 0x2009, 0x007e,
+ 0x080c, 0xaaf7, 0x2011, 0x0005, 0x080c, 0xa426, 0x080c, 0xab13,
+ 0x080c, 0x769d, 0x0148, 0x00c6, 0x2061, 0x0100, 0x0016, 0x080c,
+ 0x27b9, 0x61e2, 0x001e, 0x00ce, 0x00fe, 0x012e, 0x0005, 0x00c6,
+ 0x00b6, 0x080c, 0x769d, 0x1118, 0x20a9, 0x0800, 0x0010, 0x20a9,
+ 0x0782, 0x080c, 0x769d, 0x1110, 0x900e, 0x0010, 0x2009, 0x007e,
0x86ff, 0x0138, 0x9180, 0x1000, 0x2004, 0x905d, 0x0110, 0xb800,
- 0xd0bc, 0x090c, 0x3419, 0x8108, 0x1f04, 0x0af0, 0x707f, 0x0000,
+ 0xd0bc, 0x090c, 0x3404, 0x8108, 0x1f04, 0x0af0, 0x707f, 0x0000,
0x7080, 0x9084, 0x00ff, 0x7082, 0x70b3, 0x0000, 0x00be, 0x00ce,
0x0005, 0x00b6, 0x0126, 0x2091, 0x8000, 0x7000, 0x9086, 0x0002,
- 0x1904, 0x0bc0, 0x70ac, 0x9086, 0xffff, 0x0120, 0x080c, 0x30e1,
+ 0x1904, 0x0bc0, 0x70ac, 0x9086, 0xffff, 0x0120, 0x080c, 0x30c8,
0x0804, 0x0bc0, 0x70dc, 0xd0ac, 0x1110, 0xd09c, 0x0538, 0xd084,
0x0528, 0x0006, 0x2001, 0x0103, 0x2003, 0x002b, 0x000e, 0xd08c,
- 0x01e8, 0x080c, 0x3482, 0x11b0, 0x70e0, 0x9086, 0xffff, 0x0190,
- 0x080c, 0x3276, 0x70dc, 0xd094, 0x1904, 0x0bc0, 0x2011, 0x0001,
- 0x080c, 0xd33e, 0x0110, 0x2011, 0x0003, 0x901e, 0x080c, 0x32b0,
+ 0x01e8, 0x080c, 0x346d, 0x11b0, 0x70e0, 0x9086, 0xffff, 0x0190,
+ 0x080c, 0x3261, 0x70dc, 0xd094, 0x1904, 0x0bc0, 0x2011, 0x0001,
+ 0x080c, 0xd35d, 0x0110, 0x2011, 0x0003, 0x901e, 0x080c, 0x329b,
0x0804, 0x0bc0, 0x70e4, 0x9005, 0x1904, 0x0bc0, 0x70a8, 0x9005,
0x1904, 0x0bc0, 0x70dc, 0xd0a4, 0x0118, 0xd0b4, 0x0904, 0x0bc0,
- 0x080c, 0x6b93, 0x1904, 0x0bc0, 0x080c, 0x6be6, 0x1904, 0x0bc0,
- 0x080c, 0x6bcd, 0x01c0, 0x0156, 0x00c6, 0x20a9, 0x007f, 0x900e,
- 0x0016, 0x080c, 0x6789, 0x1118, 0xb800, 0xd0ec, 0x1138, 0x001e,
+ 0x080c, 0x6b8b, 0x1904, 0x0bc0, 0x080c, 0x6bde, 0x1904, 0x0bc0,
+ 0x080c, 0x6bc5, 0x01c0, 0x0156, 0x00c6, 0x20a9, 0x007f, 0x900e,
+ 0x0016, 0x080c, 0x6783, 0x1118, 0xb800, 0xd0ec, 0x1138, 0x001e,
0x8108, 0x1f04, 0x0b60, 0x00ce, 0x015e, 0x0028, 0x001e, 0x00ce,
0x015e, 0x0804, 0x0bc0, 0x0006, 0x2001, 0x0103, 0x2003, 0x002b,
- 0x000e, 0x2011, 0x19b5, 0x080c, 0x0fe1, 0x2011, 0x19cf, 0x080c,
- 0x0fe1, 0x7030, 0xc08c, 0x7032, 0x7003, 0x0003, 0x70af, 0xffff,
- 0x080c, 0x0e98, 0x9006, 0x080c, 0x2647, 0x080c, 0x3482, 0x0118,
- 0x080c, 0x4dcb, 0x0050, 0x0036, 0x0046, 0x2019, 0xffff, 0x2021,
- 0x0006, 0x080c, 0x4de5, 0x004e, 0x003e, 0x00f6, 0x2079, 0x0100,
- 0x080c, 0x76c8, 0x0150, 0x080c, 0x76a5, 0x7828, 0x0118, 0x9084,
- 0xe1ff, 0x0010, 0x9084, 0xffdf, 0x782a, 0x00fe, 0x080c, 0xaae0,
+ 0x000e, 0x2011, 0x19b5, 0x080c, 0x0fd5, 0x2011, 0x19cf, 0x080c,
+ 0x0fd5, 0x7030, 0xc08c, 0x7032, 0x7003, 0x0003, 0x70af, 0xffff,
+ 0x080c, 0x0e8c, 0x9006, 0x080c, 0x2646, 0x080c, 0x346d, 0x0118,
+ 0x080c, 0x4dc5, 0x0050, 0x0036, 0x0046, 0x2019, 0xffff, 0x2021,
+ 0x0006, 0x080c, 0x4ddf, 0x004e, 0x003e, 0x00f6, 0x2079, 0x0100,
+ 0x080c, 0x76c0, 0x0150, 0x080c, 0x769d, 0x7828, 0x0118, 0x9084,
+ 0xe1ff, 0x0010, 0x9084, 0xffdf, 0x782a, 0x00fe, 0x080c, 0xaaf7,
0x2001, 0x19ea, 0x2004, 0x9086, 0x0005, 0x1120, 0x2011, 0x0000,
- 0x080c, 0xa40f, 0x2011, 0x0000, 0x080c, 0xa419, 0x080c, 0xaafc,
+ 0x080c, 0xa426, 0x2011, 0x0000, 0x080c, 0xa430, 0x080c, 0xab13,
0x012e, 0x00be, 0x0005, 0x0016, 0x0026, 0x0046, 0x00f6, 0x0126,
0x2091, 0x8000, 0x2079, 0x0100, 0x7904, 0x918c, 0xfffd, 0x7906,
- 0x2009, 0x00f7, 0x080c, 0x60fa, 0x7940, 0x918c, 0x0010, 0x7942,
- 0x7924, 0xd1b4, 0x0120, 0x2011, 0x0040, 0x080c, 0x2af5, 0xd19c,
- 0x0120, 0x2011, 0x0008, 0x080c, 0x2af5, 0x0006, 0x0036, 0x0156,
- 0x0000, 0x2001, 0x19a8, 0x2004, 0x9005, 0x1518, 0x080c, 0x2a89,
- 0x1148, 0x2001, 0x0001, 0x080c, 0x29ec, 0x2001, 0x0001, 0x080c,
- 0x29cf, 0x00b8, 0x080c, 0x2a91, 0x1138, 0x9006, 0x080c, 0x29ec,
- 0x9006, 0x080c, 0x29cf, 0x0068, 0x080c, 0x2a99, 0x1d50, 0x2001,
- 0x1999, 0x2004, 0xd0fc, 0x0108, 0x0020, 0x080c, 0x27e6, 0x0804,
- 0x0cc9, 0x2009, 0x19b1, 0x2104, 0x8000, 0x200a, 0x9084, 0x0001,
- 0x0120, 0x080c, 0x2b18, 0x080c, 0x2b4b, 0x20a9, 0x003a, 0x1d04,
- 0x0c1f, 0x080c, 0x8920, 0x1f04, 0x0c1f, 0x080c, 0x76b6, 0x0148,
- 0x080c, 0x76c8, 0x1118, 0x080c, 0x79b6, 0x0050, 0x080c, 0x76ad,
- 0x0dd0, 0x080c, 0x79b1, 0x080c, 0x79a7, 0x080c, 0x75d4, 0x0020,
- 0x2009, 0x00f8, 0x080c, 0x60fa, 0x7850, 0xc0e5, 0x7852, 0x080c,
- 0x76a5, 0x0120, 0x7843, 0x0090, 0x7843, 0x0010, 0x2021, 0xe678,
- 0x2019, 0xea60, 0x0d0c, 0x8920, 0x7820, 0xd09c, 0x15a0, 0x080c,
- 0x76a5, 0x0904, 0x0cab, 0x7824, 0xd0ac, 0x1904, 0x0cce, 0x080c,
- 0x76c8, 0x1548, 0x0046, 0x2021, 0x0320, 0x8421, 0x1df0, 0x004e,
- 0x2011, 0x1800, 0x080c, 0x2af5, 0x080c, 0x2aa1, 0x7824, 0x9084,
- 0x1800, 0x1168, 0x9484, 0x0fff, 0x1140, 0x2001, 0x1810, 0x2004,
- 0x9084, 0x9000, 0x0110, 0x080c, 0x0cf1, 0x8421, 0x1160, 0x1d04,
- 0x0c7b, 0x080c, 0x8920, 0x080c, 0x79b1, 0x080c, 0x79a7, 0x7003,
- 0x0001, 0x0804, 0x0cce, 0x8319, 0x1928, 0x2001, 0x1810, 0x2004,
- 0x9084, 0x9000, 0x0110, 0x080c, 0x0cf1, 0x1d04, 0x0c91, 0x080c,
- 0x8920, 0x2009, 0x199c, 0x2104, 0x9005, 0x0118, 0x8001, 0x200a,
- 0x1188, 0x200b, 0x000a, 0x2011, 0x0048, 0x080c, 0x2af5, 0x20a9,
- 0x0002, 0x080c, 0x2a82, 0x7924, 0x080c, 0x2aa1, 0xd19c, 0x0110,
- 0x080c, 0x29bd, 0x00f0, 0x080c, 0x76b6, 0x1140, 0x94a2, 0x03e8,
- 0x1128, 0x080c, 0x7679, 0x7003, 0x0001, 0x00c0, 0x2011, 0x1800,
- 0x080c, 0x2af5, 0x080c, 0x2aa1, 0x7824, 0x080c, 0x76bf, 0x0110,
- 0xd0ac, 0x1160, 0x9084, 0x1800, 0x0904, 0x0c83, 0x7003, 0x0001,
- 0x0028, 0x2001, 0x0001, 0x080c, 0x2647, 0x00a0, 0x7850, 0xc0e4,
- 0x7852, 0x2009, 0x180c, 0x210c, 0xd19c, 0x1120, 0x7904, 0x918d,
- 0x0002, 0x7906, 0x2011, 0x0048, 0x080c, 0x2af5, 0x7828, 0x9085,
- 0x0028, 0x782a, 0x2001, 0x19a8, 0x2003, 0x0000, 0x9006, 0x78f2,
- 0x015e, 0x003e, 0x000e, 0x012e, 0x00fe, 0x004e, 0x002e, 0x001e,
- 0x0005, 0x0006, 0x0016, 0x0026, 0x0036, 0x0046, 0x00b6, 0x00c6,
- 0x00d6, 0x00e6, 0x00f6, 0x0156, 0x0071, 0x0d0c, 0x8920, 0x015e,
- 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x00be, 0x004e, 0x003e, 0x002e,
- 0x001e, 0x000e, 0x0005, 0x00e6, 0x2071, 0x189e, 0x7004, 0x9086,
- 0x0001, 0x1110, 0x080c, 0x35b0, 0x00ee, 0x0005, 0x0005, 0x2a70,
- 0x2061, 0x19ac, 0x2063, 0x0003, 0x6007, 0x0003, 0x600b, 0x000f,
- 0x600f, 0x0137, 0x2001, 0x197d, 0x900e, 0x2102, 0x7196, 0x2001,
- 0x0100, 0x2004, 0x9082, 0x0002, 0x0218, 0x705f, 0xffff, 0x0008,
- 0x715e, 0x7067, 0xffff, 0x717e, 0x7182, 0x080c, 0xd084, 0x70ef,
- 0x00c0, 0x2061, 0x196d, 0x6003, 0x0909, 0x6106, 0x600b, 0x8800,
- 0x600f, 0x0200, 0x6013, 0x00ff, 0x6017, 0x001f, 0x611a, 0x601f,
- 0x07d0, 0x2061, 0x1975, 0x6003, 0x8000, 0x6106, 0x610a, 0x600f,
- 0x0200, 0x6013, 0x00ff, 0x6116, 0x601b, 0x0001, 0x611e, 0x2061,
- 0x198a, 0x6003, 0x514c, 0x6007, 0x4f47, 0x600b, 0x4943, 0x600f,
- 0x2020, 0x2001, 0x182c, 0x2102, 0x0005, 0x9016, 0x080c, 0x6789,
- 0x1178, 0xb804, 0x90c4, 0x00ff, 0x98c6, 0x0006, 0x0128, 0x90c4,
- 0xff00, 0x98c6, 0x0600, 0x1120, 0x9186, 0x0080, 0x0108, 0x8210,
- 0x8108, 0x9186, 0x0800, 0x1d50, 0x2208, 0x0005, 0x2091, 0x8000,
- 0x2079, 0x0000, 0x000e, 0x00f6, 0x0010, 0x2091, 0x8000, 0x0e04,
- 0x0d87, 0x0006, 0x0016, 0x2001, 0x8002, 0x0006, 0x2079, 0x0000,
- 0x000e, 0x7882, 0x7836, 0x001e, 0x798e, 0x000e, 0x788a, 0x000e,
- 0x7886, 0x3900, 0x789a, 0x00d6, 0x2069, 0x0300, 0x6818, 0x78ae,
- 0x681c, 0x78b2, 0x6808, 0x78be, 0x00de, 0x7833, 0x0012, 0x2091,
- 0x5000, 0x0156, 0x00d6, 0x0036, 0x0026, 0x2079, 0x0300, 0x2069,
- 0x1b2c, 0x7a08, 0x226a, 0x2069, 0x1b2d, 0x7a18, 0x226a, 0x8d68,
- 0x7a1c, 0x226a, 0x782c, 0x2019, 0x1b3a, 0x201a, 0x2019, 0x1b3d,
- 0x9016, 0x7808, 0xd09c, 0x0168, 0x7820, 0x201a, 0x8210, 0x8318,
- 0x9386, 0x1b56, 0x0108, 0x0ca8, 0x7808, 0xd09c, 0x0110, 0x2011,
- 0xdead, 0x2019, 0x1b3b, 0x782c, 0x201a, 0x8318, 0x221a, 0x7803,
- 0x0000, 0x2069, 0x1a82, 0x901e, 0x20a9, 0x0020, 0x7b26, 0x7a28,
- 0x226a, 0x8d68, 0x8318, 0x1f04, 0x0dde, 0x2069, 0x1aa2, 0x2019,
- 0x0050, 0x20a9, 0x0020, 0x7b26, 0x7a28, 0x226a, 0x8d68, 0x8318,
- 0x1f04, 0x0deb, 0x0491, 0x002e, 0x003e, 0x00de, 0x015e, 0x2079,
- 0x1800, 0x7803, 0x0005, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004,
- 0xd084, 0x0180, 0x2001, 0x1a26, 0x2004, 0x9005, 0x0128, 0x2001,
- 0x008b, 0x2004, 0xd0fc, 0x0dd8, 0x2001, 0x008a, 0x2003, 0x0002,
- 0x2003, 0x1001, 0x080c, 0x5835, 0x1170, 0x080c, 0x0f32, 0x0110,
- 0x080c, 0x0e85, 0x080c, 0x5835, 0x1130, 0x2071, 0x1800, 0x2011,
- 0x8000, 0x080c, 0x0f46, 0x0c70, 0x0005, 0x2001, 0x0382, 0x2004,
- 0x9084, 0x0007, 0x9086, 0x0001, 0x1120, 0x2001, 0x0015, 0x080c,
- 0xaad1, 0x2079, 0x0380, 0x2069, 0x1b0c, 0x7818, 0x6802, 0x781c,
- 0x6806, 0x7840, 0x680a, 0x7844, 0x680e, 0x782c, 0x6812, 0x2019,
- 0x1b17, 0x9016, 0x7808, 0xd09c, 0x0150, 0x7820, 0x201a, 0x8210,
- 0x8318, 0x8210, 0x9282, 0x0011, 0x0ea8, 0x2011, 0xdead, 0x6a2a,
- 0x7830, 0x681a, 0x7834, 0x681e, 0x7838, 0x6822, 0x783c, 0x6826,
- 0x7803, 0x0000, 0x2069, 0x1acc, 0x901e, 0x20a9, 0x0020, 0x7b26,
- 0x7828, 0x206a, 0x8d68, 0x8318, 0x1f04, 0x0e5f, 0x2069, 0x1aec,
- 0x2019, 0x00b0, 0x20a9, 0x0020, 0x7b26, 0x7828, 0x206a, 0x8d68,
- 0x8318, 0x1f04, 0x0e6c, 0x0005, 0x918c, 0x03ff, 0x2001, 0x0003,
- 0x2004, 0x9084, 0x0600, 0x1118, 0x918d, 0x6c00, 0x0010, 0x918d,
- 0x6400, 0x2001, 0x017f, 0x2102, 0x0005, 0x0026, 0x0126, 0x2011,
- 0x0080, 0x080c, 0x0f24, 0x20a9, 0x0900, 0x080c, 0x0f5a, 0x2011,
- 0x0040, 0x080c, 0x0f24, 0x20a9, 0x0900, 0x080c, 0x0f5a, 0x0c78,
- 0x0026, 0x080c, 0x0f32, 0x1188, 0x2011, 0x010e, 0x2214, 0x9294,
- 0x0007, 0x9296, 0x0007, 0x0118, 0x2011, 0x0947, 0x0010, 0x2011,
- 0x1b47, 0x080c, 0x0f46, 0x002e, 0x0005, 0x2011, 0x010e, 0x2214,
- 0x9294, 0x0007, 0x9296, 0x0007, 0x0118, 0x2011, 0xa880, 0x0010,
- 0x2011, 0x6840, 0xd0e4, 0x70f3, 0x0000, 0x1120, 0x70f3, 0x0fa0,
- 0x080c, 0x0f37, 0x002e, 0x0005, 0x0026, 0x080c, 0x0f32, 0x0148,
- 0xd0a4, 0x1138, 0x2011, 0xcdd5, 0x0010, 0x2011, 0x0080, 0x080c,
- 0x0f37, 0x002e, 0x0005, 0x0026, 0x70f3, 0x0000, 0x080c, 0x0f32,
- 0x1130, 0x2011, 0x8040, 0x080c, 0x0f46, 0x002e, 0x0005, 0x080c,
- 0x2a99, 0x1118, 0x2011, 0xcdc5, 0x0010, 0x2011, 0xcac2, 0x080c,
- 0x0f37, 0x002e, 0x0005, 0x00e6, 0x0016, 0x0006, 0x2071, 0x1800,
- 0xd0b4, 0x70ec, 0x71e8, 0x1118, 0xc0e4, 0xc1f4, 0x0050, 0x0006,
- 0x3b00, 0x9084, 0xff3e, 0x20d8, 0x000e, 0x70f3, 0x0000, 0xc0e5,
- 0xc1f5, 0x0099, 0x000e, 0x001e, 0x00ee, 0x0005, 0x00e6, 0x2071,
- 0x1800, 0xd0e4, 0x70ec, 0x1110, 0xc0dc, 0x0008, 0xc0dd, 0x0016,
- 0x71e8, 0x0019, 0x001e, 0x00ee, 0x0005, 0x70ee, 0x71ea, 0x7000,
- 0x9084, 0x0007, 0x000b, 0x0005, 0x0eea, 0x0ec4, 0x0ec4, 0x0e98,
- 0x0ed3, 0x0ec4, 0x0ec4, 0x0ed3, 0xc284, 0x0016, 0x3b08, 0x3a00,
- 0x9104, 0x918d, 0x00c1, 0x21d8, 0x9084, 0xff3e, 0x9205, 0x20d0,
- 0x001e, 0x0005, 0x2001, 0x183b, 0x2004, 0xd0dc, 0x0005, 0x9e86,
- 0x1800, 0x190c, 0x0d85, 0x70ec, 0xd0e4, 0x0108, 0xc2e5, 0x72ee,
- 0xd0e4, 0x1118, 0x9294, 0x00c1, 0x08f9, 0x0005, 0x9e86, 0x1800,
- 0x190c, 0x0d85, 0x70e8, 0xd0f4, 0x0108, 0xc2f5, 0x72ea, 0xd0f4,
- 0x1140, 0x9284, 0x8000, 0x8005, 0xc284, 0x9215, 0x9294, 0x00c1,
- 0x0861, 0x0005, 0x1d04, 0x0f5a, 0x2091, 0x6000, 0x1f04, 0x0f5a,
- 0x0005, 0x890e, 0x810e, 0x810f, 0x9194, 0x003f, 0x918c, 0xffc0,
- 0x0005, 0x0006, 0x2200, 0x914d, 0x894f, 0x894d, 0x894d, 0x000e,
- 0x0005, 0x01d6, 0x0146, 0x0036, 0x0096, 0x2061, 0x188d, 0x600b,
- 0x0000, 0x600f, 0x0000, 0x6003, 0x0000, 0x6007, 0x0000, 0x2009,
- 0xffc0, 0x2105, 0x0006, 0x2001, 0xaaaa, 0x200f, 0x2019, 0x5555,
- 0x9016, 0x2049, 0x0bff, 0xab02, 0xa001, 0xa001, 0xa800, 0x9306,
- 0x1138, 0x2105, 0x9306, 0x0120, 0x8210, 0x99c8, 0x0400, 0x0c98,
- 0x000e, 0x200f, 0x2001, 0x189d, 0x928a, 0x000e, 0x1638, 0x928a,
- 0x0006, 0x2011, 0x0006, 0x1210, 0x2011, 0x0000, 0x2202, 0x9006,
- 0x2008, 0x82ff, 0x01b0, 0x8200, 0x600a, 0x600f, 0xffff, 0x6003,
- 0x0002, 0x6007, 0x0000, 0x0026, 0x2019, 0x0010, 0x9280, 0x0001,
- 0x20e8, 0x21a0, 0x21a8, 0x4104, 0x8319, 0x1de0, 0x8211, 0x1da0,
- 0x002e, 0x009e, 0x003e, 0x014e, 0x01de, 0x0005, 0x2011, 0x000e,
- 0x08e8, 0x0016, 0x0026, 0x0096, 0x3348, 0x080c, 0x0f61, 0x2100,
- 0x9300, 0x2098, 0x22e0, 0x009e, 0x002e, 0x001e, 0x0036, 0x3518,
- 0x20a9, 0x0001, 0x4002, 0x8007, 0x4004, 0x8319, 0x1dd8, 0x003e,
- 0x0005, 0x20e9, 0x0001, 0x71b8, 0x81ff, 0x11c0, 0x9006, 0x2009,
- 0x0200, 0x20a9, 0x0002, 0x9298, 0x0018, 0x23a0, 0x4001, 0x2009,
- 0x0700, 0x20a9, 0x0002, 0x9298, 0x0008, 0x23a0, 0x4001, 0x707c,
- 0x8007, 0x7180, 0x810f, 0x20a9, 0x0002, 0x4001, 0x9298, 0x000c,
- 0x23a0, 0x900e, 0x080c, 0x0d65, 0x2001, 0x0000, 0x810f, 0x20a9,
- 0x0002, 0x4001, 0x0005, 0x89ff, 0x0140, 0xa804, 0xa807, 0x0000,
- 0x0006, 0x080c, 0x108b, 0x009e, 0x0cb0, 0x0005, 0x00e6, 0x2071,
- 0x1800, 0x080c, 0x1104, 0x090c, 0x0d85, 0x00ee, 0x0005, 0x0086,
- 0x00e6, 0x0006, 0x0026, 0x0036, 0x0126, 0x2091, 0x8000, 0x00c9,
- 0x2071, 0x1800, 0x73c0, 0x702c, 0x9016, 0x9045, 0x0158, 0x8210,
- 0x9906, 0x090c, 0x0d85, 0x2300, 0x9202, 0x0120, 0x1a0c, 0x0d85,
- 0xa000, 0x0c98, 0x012e, 0x003e, 0x002e, 0x000e, 0x00ee, 0x008e,
- 0x0005, 0x0086, 0x00e6, 0x0006, 0x0126, 0x2091, 0x8000, 0x2071,
- 0x1910, 0x7010, 0x9005, 0x0140, 0x7018, 0x9045, 0x0128, 0x9906,
- 0x090c, 0x0d85, 0xa000, 0x0cc8, 0x012e, 0x000e, 0x00ee, 0x008e,
- 0x0005, 0x00e6, 0x2071, 0x1800, 0x0126, 0x2091, 0x8000, 0x70c0,
- 0x8001, 0x0270, 0x70c2, 0x702c, 0x2048, 0x9085, 0x0001, 0xa800,
- 0x702e, 0xa803, 0x0000, 0xa807, 0x0000, 0x012e, 0x00ee, 0x0005,
- 0x904e, 0x0cd8, 0x00e6, 0x0126, 0x2091, 0x8000, 0x2071, 0x1800,
- 0x70c0, 0x90ca, 0x0020, 0x0268, 0x8001, 0x70c2, 0x702c, 0x2048,
- 0xa800, 0x702e, 0xa803, 0x0000, 0xa807, 0x0000, 0x012e, 0x00ee,
- 0x0005, 0x904e, 0x0cd8, 0x00e6, 0x0126, 0x2091, 0x8000, 0x0016,
- 0x890e, 0x810e, 0x810f, 0x9184, 0x003f, 0xa862, 0x9184, 0xffc0,
- 0xa85e, 0x001e, 0x0020, 0x00e6, 0x0126, 0x2091, 0x8000, 0x2071,
- 0x1800, 0x702c, 0xa802, 0x2900, 0x702e, 0x70c0, 0x8000, 0x70c2,
- 0x080c, 0x873a, 0x012e, 0x00ee, 0x0005, 0x2071, 0x1800, 0x9026,
- 0x2009, 0x0000, 0x2049, 0x0400, 0x2900, 0x702e, 0x8940, 0x2800,
- 0xa802, 0xa95e, 0xa863, 0x0001, 0x8420, 0x9886, 0x0440, 0x0120,
- 0x2848, 0x9188, 0x0040, 0x0c90, 0x2071, 0x188d, 0x7000, 0x9005,
- 0x11a0, 0x2001, 0x0558, 0xa802, 0x2048, 0x2009, 0x5600, 0x8940,
- 0x2800, 0xa802, 0xa95e, 0xa863, 0x0001, 0x8420, 0x9886, 0x0800,
- 0x0120, 0x2848, 0x9188, 0x0040, 0x0c90, 0x2071, 0x188d, 0x7104,
- 0x7200, 0x82ff, 0x01d0, 0x7308, 0x8318, 0x831f, 0x831b, 0x831b,
- 0x7312, 0x8319, 0x2001, 0x0800, 0xa802, 0x2048, 0x8900, 0xa802,
- 0x2040, 0xa95e, 0xaa62, 0x8420, 0x2300, 0x9906, 0x0130, 0x2848,
- 0x9188, 0x0040, 0x9291, 0x0000, 0x0c88, 0xa803, 0x0000, 0x2071,
- 0x1800, 0x74be, 0x74c2, 0x0005, 0x00e6, 0x0016, 0x9984, 0xfc00,
- 0x01e8, 0x908c, 0xf800, 0x1168, 0x9982, 0x0400, 0x02b8, 0x9982,
- 0x0440, 0x0278, 0x9982, 0x0558, 0x0288, 0x9982, 0x0800, 0x1270,
- 0x0040, 0x9982, 0x0800, 0x0250, 0x2071, 0x188d, 0x7010, 0x9902,
- 0x1228, 0x9085, 0x0001, 0x001e, 0x00ee, 0x0005, 0x9006, 0x0cd8,
- 0x00e6, 0x2071, 0x1a25, 0x7007, 0x0000, 0x9006, 0x701e, 0x7022,
- 0x7002, 0x2071, 0x0000, 0x7010, 0x9085, 0x8044, 0x7012, 0x2071,
- 0x0080, 0x9006, 0x702b, 0x0060, 0x20a9, 0x0040, 0x7022, 0x1f04,
- 0x113e, 0x702b, 0x0060, 0x702b, 0x0020, 0x20a9, 0x0040, 0x7022,
- 0x1f04, 0x1147, 0x702b, 0x0020, 0x00ee, 0x0005, 0x0126, 0x2091,
- 0x8000, 0x00e6, 0xa06f, 0x0000, 0x2071, 0x1a25, 0x701c, 0x9088,
- 0x1a2f, 0x280a, 0x8000, 0x9084, 0x003f, 0x701e, 0x7120, 0x9106,
- 0x090c, 0x0d85, 0x7004, 0x9005, 0x1128, 0x00f6, 0x2079, 0x0080,
- 0x00a9, 0x00fe, 0x00ee, 0x012e, 0x0005, 0x0126, 0x2091, 0x8000,
- 0x00e6, 0x2071, 0x1a25, 0x7004, 0x9005, 0x1128, 0x00f6, 0x2079,
- 0x0080, 0x0021, 0x00fe, 0x00ee, 0x012e, 0x0005, 0x7004, 0x9086,
- 0x0000, 0x1110, 0x7007, 0x0006, 0x7000, 0x0002, 0x1190, 0x1313,
- 0x118e, 0x118e, 0x1307, 0x1307, 0x1307, 0x1307, 0x080c, 0x0d85,
- 0x701c, 0x7120, 0x9106, 0x1148, 0x792c, 0x9184, 0x0001, 0x1120,
- 0xd1fc, 0x1110, 0x7007, 0x0000, 0x0005, 0x0096, 0x9180, 0x1a2f,
- 0x2004, 0x700a, 0x2048, 0x8108, 0x918c, 0x003f, 0x7122, 0x782b,
- 0x0026, 0xa88c, 0x7802, 0xa890, 0x7806, 0xa894, 0x780a, 0xa898,
- 0x780e, 0xa878, 0x700e, 0xa870, 0x7016, 0xa874, 0x701a, 0xa868,
- 0x009e, 0xd084, 0x0120, 0x7007, 0x0001, 0x0029, 0x0005, 0x7007,
- 0x0002, 0x00b1, 0x0005, 0x0016, 0x0026, 0x710c, 0x2011, 0x0040,
- 0x9182, 0x0040, 0x1210, 0x2110, 0x9006, 0x700e, 0x7212, 0x8203,
- 0x7812, 0x782b, 0x0020, 0x782b, 0x0041, 0x002e, 0x001e, 0x0005,
- 0x0016, 0x0026, 0x0136, 0x0146, 0x0156, 0x7014, 0x20e0, 0x7018,
- 0x2098, 0x20e9, 0x0000, 0x20a1, 0x0088, 0x782b, 0x0026, 0x710c,
- 0x2011, 0x0040, 0x9182, 0x0040, 0x1210, 0x2110, 0x9006, 0x700e,
- 0x22a8, 0x4006, 0x8203, 0x7812, 0x782b, 0x0020, 0x3300, 0x701a,
- 0x782b, 0x0001, 0x015e, 0x014e, 0x013e, 0x002e, 0x001e, 0x0005,
- 0x2009, 0x1a25, 0x2104, 0xc095, 0x200a, 0x080c, 0x116d, 0x0005,
- 0x0016, 0x00e6, 0x2071, 0x1a25, 0x00f6, 0x2079, 0x0080, 0x792c,
- 0xd1bc, 0x190c, 0x0d7e, 0x782b, 0x0002, 0xd1fc, 0x0120, 0x918c,
- 0x0700, 0x7004, 0x0023, 0x00fe, 0x00ee, 0x001e, 0x0005, 0x117e,
- 0x1226, 0x125a, 0x1332, 0x0d85, 0x134d, 0x0d85, 0x918c, 0x0700,
- 0x1550, 0x0136, 0x0146, 0x0156, 0x7014, 0x20e8, 0x7018, 0x20a0,
- 0x20e1, 0x0000, 0x2099, 0x0088, 0x782b, 0x0040, 0x7010, 0x20a8,
- 0x4005, 0x3400, 0x701a, 0x015e, 0x014e, 0x013e, 0x700c, 0x9005,
- 0x0578, 0x7800, 0x7802, 0x7804, 0x7806, 0x080c, 0x11c3, 0x0005,
- 0x7008, 0x0096, 0x2048, 0xa86f, 0x0100, 0x009e, 0x7007, 0x0000,
- 0x080c, 0x117e, 0x0005, 0x7008, 0x0096, 0x2048, 0xa86f, 0x0200,
- 0x009e, 0x0ca0, 0x918c, 0x0700, 0x1150, 0x700c, 0x9005, 0x0180,
- 0x7800, 0x7802, 0x7804, 0x7806, 0x080c, 0x11d8, 0x0005, 0x7008,
- 0x0096, 0x2048, 0xa86f, 0x0200, 0x009e, 0x7007, 0x0000, 0x0080,
- 0x0096, 0x7008, 0x2048, 0x7800, 0xa88e, 0x7804, 0xa892, 0x7808,
- 0xa896, 0x780c, 0xa89a, 0xa86f, 0x0100, 0x009e, 0x7007, 0x0000,
- 0x0096, 0x00d6, 0x7008, 0x2048, 0x2001, 0x18b9, 0x2004, 0x9906,
- 0x1128, 0xa89c, 0x080f, 0x00de, 0x009e, 0x00a0, 0x00de, 0x009e,
- 0x0096, 0x00d6, 0x7008, 0x2048, 0x0081, 0x0150, 0xa89c, 0x0086,
- 0x2940, 0x080f, 0x008e, 0x00de, 0x009e, 0x080c, 0x116d, 0x0005,
- 0x00de, 0x009e, 0x080c, 0x116d, 0x0005, 0xa8a8, 0xd08c, 0x0005,
- 0x0096, 0xa0a0, 0x904d, 0x090c, 0x0d85, 0xa06c, 0x908e, 0x0100,
- 0x0130, 0xa87b, 0x0030, 0xa883, 0x0000, 0xa897, 0x4002, 0x080c,
- 0x6f0d, 0xa09f, 0x0000, 0xa0a3, 0x0000, 0x2848, 0x080c, 0x108b,
- 0x009e, 0x0005, 0x00a6, 0xa0a0, 0x904d, 0x090c, 0x0d85, 0xa06c,
- 0x908e, 0x0100, 0x0128, 0xa87b, 0x0001, 0xa883, 0x0000, 0x00c0,
- 0xa80c, 0x2050, 0xb004, 0x9005, 0x0198, 0xa80e, 0x2050, 0x8006,
- 0x8006, 0x8007, 0x908c, 0x003f, 0x9084, 0xffc0, 0x9080, 0x0002,
- 0xa076, 0xa172, 0xb000, 0xa07a, 0x2810, 0x080c, 0x114e, 0x00e8,
- 0xa97c, 0xa894, 0x0016, 0x0006, 0x080c, 0x6f0d, 0x000e, 0x001e,
- 0xd1fc, 0x1138, 0xd1f4, 0x0128, 0x00c6, 0x2060, 0x080c, 0xaf2e,
- 0x00ce, 0x7008, 0x2048, 0xa89f, 0x0000, 0xa8a3, 0x0000, 0x080c,
- 0x108b, 0x7007, 0x0000, 0x080c, 0x116d, 0x00ae, 0x0005, 0x0126,
- 0x2091, 0x8000, 0x782b, 0x1001, 0x7007, 0x0005, 0x7000, 0xc094,
- 0x7002, 0x012e, 0x0005, 0x0096, 0x2001, 0x1930, 0x204c, 0xa87c,
- 0x7812, 0xa88c, 0x7802, 0xa890, 0x7806, 0xa894, 0x780a, 0xa898,
- 0x780e, 0x782b, 0x0020, 0x0126, 0x2091, 0x8000, 0x782b, 0x0041,
- 0x7007, 0x0003, 0x7000, 0xc084, 0x7002, 0x2900, 0x700a, 0x012e,
- 0x009e, 0x0005, 0x20e1, 0x0000, 0x2099, 0x0088, 0x782b, 0x0040,
- 0x0096, 0x2001, 0x1930, 0x204c, 0xaa7c, 0x009e, 0x080c, 0x8e26,
- 0x2009, 0x188c, 0x2104, 0x9084, 0xfffc, 0x200a, 0x080c, 0x8c88,
- 0x7007, 0x0000, 0x080c, 0x117e, 0x0005, 0x7007, 0x0000, 0x080c,
- 0x117e, 0x0005, 0x0126, 0x2091, 0x2200, 0x2079, 0x0300, 0x2071,
- 0x1a6f, 0x7003, 0x0000, 0x78bf, 0x00f6, 0x0041, 0x7807, 0x0007,
- 0x7803, 0x0000, 0x7803, 0x0001, 0x012e, 0x0005, 0x00c6, 0x7803,
- 0x0000, 0x2001, 0x0165, 0x2003, 0x4198, 0x7808, 0xd09c, 0x0120,
- 0x7820, 0x080c, 0x13b6, 0x0cc8, 0x2001, 0x1a70, 0x2003, 0x0000,
- 0x78ab, 0x0004, 0x78ac, 0xd0ac, 0x1de8, 0x78ab, 0x0002, 0x7807,
- 0x0007, 0x7827, 0x0030, 0x782b, 0x0400, 0x7827, 0x0031, 0x782b,
- 0x1a82, 0x78e3, 0xff00, 0x781f, 0xff00, 0x781b, 0xff00, 0x2001,
- 0x1a71, 0x2003, 0x0000, 0x2001, 0x0200, 0x2004, 0xd0dc, 0x0110,
- 0x781f, 0x0303, 0x2061, 0x1a82, 0x602f, 0x1ddc, 0x2001, 0x181a,
- 0x2004, 0x9082, 0x1ddc, 0x6032, 0x603b, 0x1ee2, 0x602b, 0x1ac2,
- 0x6007, 0x1aa2, 0x2061, 0x1aa2, 0x606f, 0x193e, 0x2001, 0x1929,
- 0x2004, 0x607a, 0x783f, 0x3489, 0x00ce, 0x0005, 0x9086, 0x000d,
- 0x11d0, 0x7808, 0xd09c, 0x01b8, 0x7820, 0x0026, 0x2010, 0x080c,
- 0xcc04, 0x0180, 0x2260, 0x6000, 0x9086, 0x0004, 0x1158, 0x0016,
- 0x6120, 0x9186, 0x0009, 0x0108, 0x0020, 0x2009, 0x004c, 0x080c,
- 0xafcc, 0x001e, 0x002e, 0x0005, 0x0126, 0x2091, 0x2200, 0x7908,
- 0x9184, 0x0070, 0x190c, 0x0d7e, 0xd19c, 0x05a0, 0x7820, 0x908c,
- 0xf000, 0x0540, 0x2060, 0x6020, 0x9086, 0x0003, 0x1550, 0x6000,
- 0x9086, 0x0004, 0x1530, 0x6114, 0x2148, 0xa876, 0xa87a, 0xa867,
- 0x0103, 0x080c, 0x6d2e, 0x00b6, 0x6010, 0x2058, 0xba3c, 0x8211,
- 0x0208, 0xba3e, 0xb8d0, 0x9005, 0x190c, 0x68b4, 0x00be, 0x6044,
- 0xd0fc, 0x190c, 0xab09, 0x080c, 0xaf57, 0x7808, 0xd09c, 0x19b0,
- 0x012e, 0x0005, 0x908a, 0x0024, 0x1a0c, 0x0d85, 0x002b, 0x012e,
- 0x0005, 0x04b0, 0x012e, 0x0005, 0x1438, 0x145e, 0x148e, 0x1493,
- 0x1497, 0x149c, 0x14c4, 0x14c8, 0x14d6, 0x14da, 0x1438, 0x15a7,
- 0x15ab, 0x161d, 0x1624, 0x1438, 0x1625, 0x1626, 0x1631, 0x1638,
- 0x1438, 0x1438, 0x1438, 0x1438, 0x1438, 0x1438, 0x1438, 0x149e,
- 0x1438, 0x1466, 0x148b, 0x1452, 0x1438, 0x1472, 0x143c, 0x143a,
- 0x080c, 0x0d85, 0x080c, 0x0d7e, 0x080c, 0x1643, 0x2009, 0x1a7e,
- 0x2104, 0x8000, 0x200a, 0x080c, 0x8159, 0x080c, 0x1b47, 0x0005,
- 0x6044, 0xd0fc, 0x190c, 0xab09, 0x2009, 0x0055, 0x080c, 0xafcc,
- 0x012e, 0x0005, 0x080c, 0x1643, 0x2060, 0x6044, 0xd0fc, 0x190c,
- 0xab09, 0x2009, 0x0055, 0x080c, 0xafcc, 0x0005, 0x2009, 0x0048,
- 0x080c, 0x1643, 0x2060, 0x080c, 0xafcc, 0x0005, 0x2009, 0x0054,
- 0x080c, 0x1643, 0x2060, 0x6044, 0xd0fc, 0x190c, 0xab09, 0x080c,
- 0xafcc, 0x0005, 0x080c, 0x1643, 0x2060, 0x0056, 0x0066, 0x080c,
- 0x1643, 0x2028, 0x080c, 0x1643, 0x2030, 0x0036, 0x0046, 0x2021,
- 0x0000, 0x2418, 0x2009, 0x0056, 0x080c, 0xafcc, 0x004e, 0x003e,
- 0x006e, 0x005e, 0x0005, 0x080c, 0x1643, 0x0005, 0x7004, 0xc085,
- 0xc0b5, 0x7006, 0x0005, 0x7004, 0xc085, 0x7006, 0x0005, 0x080c,
- 0x1643, 0x080c, 0x1740, 0x0005, 0x080c, 0x0d85, 0x080c, 0x1643,
- 0x2060, 0x6014, 0x0096, 0x2048, 0xa83b, 0xffff, 0x009e, 0x2009,
- 0x0048, 0x080c, 0xafcc, 0x2001, 0x015d, 0x2003, 0x0000, 0x2009,
- 0x03e8, 0x8109, 0x0160, 0x2001, 0x0201, 0x2004, 0x9005, 0x0dc8,
- 0x2001, 0x0218, 0x2004, 0xd0ec, 0x1110, 0x080c, 0x1648, 0x2001,
- 0x0307, 0x2003, 0x8000, 0x0005, 0x7004, 0xc095, 0x7006, 0x0005,
- 0x080c, 0x1643, 0x2060, 0x6014, 0x0096, 0x2048, 0xa83b, 0xffff,
- 0x009e, 0x2009, 0x0048, 0x080c, 0xafcc, 0x0005, 0x080c, 0x1643,
- 0x080c, 0x0d85, 0x080c, 0x1643, 0x080c, 0x1592, 0x7827, 0x0018,
- 0x79ac, 0xd1dc, 0x0904, 0x1543, 0x7827, 0x0015, 0x7828, 0x782b,
- 0x0000, 0x9065, 0x0140, 0x2001, 0x020d, 0x2003, 0x0050, 0x2003,
- 0x0020, 0x0804, 0x1549, 0x7004, 0x9005, 0x01c8, 0x1188, 0x78ab,
- 0x0004, 0x7827, 0x0018, 0x782b, 0x0000, 0xd1bc, 0x090c, 0x0d85,
- 0x2001, 0x020d, 0x2003, 0x0050, 0x2003, 0x0020, 0x0804, 0x1577,
- 0x78ab, 0x0004, 0x7803, 0x0001, 0x080c, 0x15ab, 0x0005, 0x7827,
- 0x0018, 0xa001, 0x7828, 0x7827, 0x0011, 0xa001, 0x7928, 0x9106,
- 0x0110, 0x79ac, 0x08e0, 0x00e6, 0x2071, 0x0200, 0x702c, 0xd0c4,
- 0x0140, 0x00ee, 0x080c, 0x1b47, 0x080c, 0x1366, 0x7803, 0x0001,
- 0x0005, 0x7037, 0x0001, 0xa001, 0x7150, 0x00ee, 0x918c, 0xff00,
- 0x9186, 0x0500, 0x0110, 0x79ac, 0x0810, 0x7004, 0xc09d, 0x7006,
- 0x78ab, 0x0004, 0x7803, 0x0001, 0x080c, 0x15ab, 0x2001, 0x020d,
- 0x2003, 0x0020, 0x0005, 0x7828, 0x782b, 0x0000, 0x9065, 0x090c,
- 0x0d85, 0x6014, 0x2048, 0x78ab, 0x0004, 0x918c, 0x0700, 0x01a8,
- 0x080c, 0x8159, 0x080c, 0x1b47, 0x080c, 0xcc16, 0x0158, 0xa9ac,
- 0xa936, 0xa9b0, 0xa93a, 0xa83f, 0xffff, 0xa843, 0xffff, 0xa880,
- 0xc0bd, 0xa882, 0x080c, 0xc802, 0x0005, 0x6020, 0x9086, 0x0009,
- 0x1128, 0x2009, 0x004c, 0x080c, 0xafcc, 0x0048, 0x6010, 0x00b6,
- 0x2058, 0xb800, 0x00be, 0xd0bc, 0x6024, 0x190c, 0xd019, 0x2029,
- 0x00c8, 0x8529, 0x0128, 0x2001, 0x0201, 0x2004, 0x9005, 0x0dc8,
- 0x7dbc, 0x080c, 0xeb55, 0xd5a4, 0x1118, 0x080c, 0x1648, 0x0005,
- 0x080c, 0x8159, 0x080c, 0x1b47, 0x0005, 0x781f, 0x0300, 0x7803,
- 0x0001, 0x0005, 0x0016, 0x0066, 0x0076, 0x00f6, 0x2079, 0x0300,
- 0x7908, 0x918c, 0x0007, 0x9186, 0x0003, 0x0120, 0x2001, 0x0016,
- 0x080c, 0x16b9, 0x00fe, 0x007e, 0x006e, 0x001e, 0x0005, 0x7004,
- 0xc09d, 0x7006, 0x0005, 0x7104, 0x9184, 0x0004, 0x190c, 0x0d85,
- 0xd184, 0x11b1, 0xd19c, 0x0180, 0xc19c, 0x7106, 0x0016, 0x080c,
- 0x1723, 0x001e, 0x0148, 0x2001, 0x020d, 0x2003, 0x0050, 0x2003,
- 0x0020, 0x080c, 0x1648, 0x0005, 0x81ff, 0x190c, 0x0d85, 0x0005,
- 0x2100, 0xc184, 0xc1b4, 0x7106, 0xd0b4, 0x0016, 0x00e6, 0x1904,
- 0x1612, 0x2071, 0x0200, 0x080c, 0x1710, 0x05e0, 0x080c, 0x1723,
- 0x05b0, 0x6014, 0x9005, 0x05b0, 0x0096, 0x2048, 0xa864, 0x009e,
- 0x9084, 0x00ff, 0x908e, 0x0029, 0x0160, 0x908e, 0x0048, 0x1550,
- 0x601c, 0xd084, 0x11e0, 0x00f6, 0x2c78, 0x080c, 0x17ad, 0x00fe,
- 0x00b0, 0x00f6, 0x2c78, 0x080c, 0x1936, 0x00fe, 0x2009, 0x01f4,
- 0x8109, 0x0168, 0x2001, 0x0201, 0x2004, 0x9005, 0x0dc8, 0x2001,
- 0x0218, 0x2004, 0xd0ec, 0x1118, 0x080c, 0x1648, 0x0040, 0x2001,
- 0x020d, 0x2003, 0x0020, 0x080c, 0x1366, 0x7803, 0x0001, 0x00ee,
- 0x001e, 0x0005, 0x080c, 0x1723, 0x0dd0, 0x2001, 0x020d, 0x2003,
- 0x0050, 0x2003, 0x0020, 0x0461, 0x0c90, 0x0429, 0x2060, 0x2009,
- 0x0053, 0x080c, 0xafcc, 0x0005, 0x0005, 0x0005, 0x00e1, 0x2008,
- 0x00d1, 0x0006, 0x7004, 0xc09d, 0x7006, 0x000e, 0x080c, 0x9177,
- 0x0005, 0x0089, 0x9005, 0x0118, 0x080c, 0x8d7a, 0x0cd0, 0x0005,
- 0x2001, 0x0036, 0x2009, 0x1820, 0x210c, 0x2011, 0x181f, 0x2214,
- 0x080c, 0x16b9, 0x0005, 0x7808, 0xd09c, 0x0de8, 0x7820, 0x0005,
- 0x080c, 0x1592, 0x00d6, 0x2069, 0x0200, 0x2009, 0x01f4, 0x8109,
- 0x0510, 0x6804, 0x9005, 0x0dd8, 0x2001, 0x015d, 0x2003, 0x0000,
- 0x79bc, 0xd1a4, 0x1528, 0x79b8, 0x918c, 0x0fff, 0x0180, 0x9182,
- 0x0841, 0x1268, 0x9188, 0x0007, 0x918c, 0x0ff8, 0x810c, 0x810c,
- 0x810c, 0x080c, 0x16ab, 0x6827, 0x0001, 0x8109, 0x1dd0, 0x04d9,
- 0x6827, 0x0002, 0x04c1, 0x6804, 0x9005, 0x1130, 0x682c, 0xd0e4,
- 0x1500, 0x6804, 0x9005, 0x0de8, 0x79b8, 0xd1ec, 0x1130, 0x08c0,
- 0x080c, 0x8159, 0x080c, 0x1b47, 0x0090, 0x7827, 0x0015, 0x782b,
- 0x0000, 0x7827, 0x0018, 0x782b, 0x0000, 0x2001, 0x020d, 0x2003,
- 0x0020, 0x2001, 0x0307, 0x2003, 0x0300, 0x7803, 0x0001, 0x00de,
- 0x0005, 0x682c, 0x9084, 0x5400, 0x9086, 0x5400, 0x0d30, 0x7827,
- 0x0015, 0x782b, 0x0000, 0x7803, 0x0001, 0x6800, 0x9085, 0x1800,
- 0x6802, 0x00de, 0x0005, 0x6824, 0x9084, 0x0003, 0x1de0, 0x0005,
- 0x2001, 0x0030, 0x2c08, 0x621c, 0x0021, 0x7830, 0x9086, 0x0041,
- 0x0005, 0x00f6, 0x00e6, 0x2079, 0x0300, 0x0006, 0x2071, 0x1a6f,
- 0x7008, 0x9005, 0x1110, 0x78e3, 0x0c0c, 0x8000, 0x700a, 0x0026,
- 0x2011, 0x0006, 0x7808, 0xd09c, 0x0150, 0x0016, 0x0026, 0x00c6,
- 0x080c, 0x13d4, 0x00ce, 0x002e, 0x001e, 0x8211, 0x1d98, 0x002e,
- 0x000e, 0x0006, 0x7832, 0x7936, 0x7a3a, 0x781b, 0x8080, 0x00b9,
- 0x1178, 0x2071, 0x1a6f, 0x7008, 0x9005, 0x0130, 0x8001, 0x0a0c,
- 0x0d85, 0x700a, 0x78e3, 0x0c00, 0x000e, 0x00ee, 0x00fe, 0x0005,
- 0x000e, 0x792c, 0x3900, 0x8000, 0x2004, 0x080c, 0x0d85, 0x2009,
- 0xff00, 0x8109, 0x0120, 0x7818, 0xd0bc, 0x1dd8, 0x0005, 0x9085,
- 0x0001, 0x0005, 0x7832, 0x7936, 0x7a3a, 0x781b, 0x8080, 0x0c79,
- 0x1108, 0x0005, 0x792c, 0x3900, 0x8000, 0x2004, 0x080c, 0x0d85,
- 0x7037, 0x0001, 0x7150, 0x7037, 0x0002, 0x7050, 0x2060, 0xd1bc,
- 0x1110, 0x7054, 0x2060, 0x918c, 0xff00, 0x9186, 0x0500, 0x0110,
- 0x9085, 0x0001, 0x0005, 0x0006, 0x0046, 0x00e6, 0x2071, 0x0200,
- 0x7037, 0x0002, 0x7058, 0x9084, 0xff00, 0x8007, 0x9086, 0x00bc,
- 0x1158, 0x2021, 0x1a7f, 0x2404, 0x8000, 0x0208, 0x2022, 0x080c,
- 0x8159, 0x080c, 0x1b47, 0x9006, 0x00ee, 0x004e, 0x000e, 0x0005,
- 0x0c11, 0x1108, 0x0005, 0x00e6, 0x0016, 0x2071, 0x0200, 0x0841,
- 0x6124, 0xd1dc, 0x01f8, 0x701c, 0xd08c, 0x0904, 0x17a2, 0x7017,
- 0x0000, 0x2001, 0x0264, 0x2004, 0xd0bc, 0x0904, 0x17a2, 0x2001,
- 0x0268, 0x00c6, 0x2064, 0x6104, 0x6038, 0x00ce, 0x918e, 0x0039,
- 0x1904, 0x17a2, 0x9c06, 0x15f0, 0x0126, 0x2091, 0x2600, 0x080c,
- 0x80b1, 0x012e, 0x7358, 0x745c, 0x6014, 0x905d, 0x0598, 0x2b48,
- 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x190c, 0xcff4,
- 0xab42, 0xac3e, 0x2001, 0x1869, 0x2004, 0xd0b4, 0x1170, 0x601c,
- 0xd0e4, 0x1158, 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc,
- 0x1120, 0xa83b, 0x7fff, 0xa837, 0xffff, 0x080c, 0x1f02, 0x1190,
- 0x080c, 0x1993, 0x2a00, 0xa816, 0x0130, 0x2800, 0xa80e, 0x2c05,
- 0xa80a, 0x2c00, 0xa812, 0x7037, 0x0020, 0x781f, 0x0300, 0x001e,
- 0x00ee, 0x0005, 0x7037, 0x0050, 0x7037, 0x0020, 0x001e, 0x00ee,
- 0x080c, 0x1648, 0x0005, 0x080c, 0x0d85, 0x2cf0, 0x0126, 0x2091,
- 0x2200, 0x0016, 0x00c6, 0x3e60, 0x6014, 0x2048, 0x2940, 0x903e,
- 0x2730, 0xa864, 0x2068, 0xa81a, 0x9d84, 0x000f, 0x9088, 0x1ee2,
- 0x2165, 0x0002, 0x17d9, 0x1847, 0x17d9, 0x17d9, 0x17dd, 0x1828,
- 0x17d9, 0x17fd, 0x17d2, 0x183e, 0x17d9, 0x17d9, 0x17e2, 0x1934,
- 0x1811, 0x1807, 0xa964, 0x918c, 0x00ff, 0x918e, 0x0048, 0x0904,
- 0x183e, 0x9085, 0x0001, 0x0804, 0x192a, 0xa87c, 0xd0ac, 0x0dc8,
- 0x0804, 0x184e, 0xa87c, 0xd0ac, 0x0da0, 0x0804, 0x18b9, 0xa898,
- 0x901d, 0x1108, 0xab9c, 0x9016, 0xaab2, 0xaa3e, 0xaa42, 0x3e00,
- 0x9080, 0x0008, 0x2004, 0x9080, 0x9347, 0x2005, 0x9005, 0x090c,
- 0x0d85, 0x2004, 0xa8ae, 0x0804, 0x1912, 0xa87c, 0xd0bc, 0x09c8,
- 0xa890, 0xa842, 0xa88c, 0xa83e, 0xa888, 0x0804, 0x184e, 0xa87c,
- 0xd0bc, 0x0978, 0xa890, 0xa842, 0xa88c, 0xa83e, 0xa888, 0x0804,
- 0x18b9, 0xa87c, 0xd0bc, 0x0928, 0xa890, 0xa842, 0xa88c, 0xa83e,
- 0xa804, 0x9045, 0x090c, 0x0d85, 0xa164, 0xa91a, 0x91ec, 0x000f,
- 0x9d80, 0x1ee2, 0x2065, 0xa888, 0xd19c, 0x1904, 0x18b9, 0x0430,
- 0xa87c, 0xd0ac, 0x0904, 0x17d9, 0xa804, 0x9045, 0x090c, 0x0d85,
- 0xa164, 0xa91a, 0x91ec, 0x000f, 0x9d80, 0x1ee2, 0x2065, 0x9006,
- 0xa842, 0xa83e, 0xd19c, 0x1904, 0x18b9, 0x0080, 0xa87c, 0xd0ac,
- 0x0904, 0x17d9, 0x9006, 0xa842, 0xa83e, 0x0804, 0x18b9, 0xa87c,
- 0xd0ac, 0x0904, 0x17d9, 0x9006, 0xa842, 0xa83e, 0x2c05, 0x908a,
- 0x0036, 0x1a0c, 0x0d85, 0x9082, 0x001b, 0x0002, 0x1871, 0x1871,
- 0x1873, 0x1871, 0x1871, 0x1871, 0x187d, 0x1871, 0x1871, 0x1871,
- 0x1887, 0x1871, 0x1871, 0x1871, 0x1891, 0x1871, 0x1871, 0x1871,
- 0x189b, 0x1871, 0x1871, 0x1871, 0x18a5, 0x1871, 0x1871, 0x1871,
- 0x18af, 0x080c, 0x0d85, 0xa574, 0xa478, 0x9d86, 0x0024, 0x0904,
- 0x17e7, 0xa37c, 0xa280, 0x0804, 0x1912, 0xa584, 0xa488, 0x9d86,
- 0x0024, 0x0904, 0x17e7, 0xa38c, 0xa290, 0x0804, 0x1912, 0xa594,
- 0xa498, 0x9d86, 0x0024, 0x0904, 0x17e7, 0xa39c, 0xa2a0, 0x0804,
- 0x1912, 0xa5a4, 0xa4a8, 0x9d86, 0x0024, 0x0904, 0x17e7, 0xa3ac,
- 0xa2b0, 0x0804, 0x1912, 0xa5b4, 0xa4b8, 0x9d86, 0x0024, 0x0904,
- 0x17e7, 0xa3bc, 0xa2c0, 0x0804, 0x1912, 0xa5c4, 0xa4c8, 0x9d86,
- 0x0024, 0x0904, 0x17e7, 0xa3cc, 0xa2d0, 0x0804, 0x1912, 0xa5d4,
- 0xa4d8, 0x9d86, 0x0024, 0x0904, 0x17e7, 0xa3dc, 0xa2e0, 0x0804,
- 0x1912, 0x2c05, 0x908a, 0x0034, 0x1a0c, 0x0d85, 0x9082, 0x001b,
- 0x0002, 0x18dc, 0x18da, 0x18da, 0x18da, 0x18da, 0x18da, 0x18e7,
- 0x18da, 0x18da, 0x18da, 0x18da, 0x18da, 0x18f2, 0x18da, 0x18da,
- 0x18da, 0x18da, 0x18da, 0x18fd, 0x18da, 0x18da, 0x18da, 0x18da,
- 0x18da, 0x1908, 0x080c, 0x0d85, 0xa56c, 0xa470, 0xa774, 0xa678,
- 0x9d86, 0x002c, 0x0904, 0x17e7, 0xa37c, 0xa280, 0x0458, 0xa584,
- 0xa488, 0xa78c, 0xa690, 0x9d86, 0x002c, 0x0904, 0x17e7, 0xa394,
- 0xa298, 0x0400, 0xa59c, 0xa4a0, 0xa7a4, 0xa6a8, 0x9d86, 0x002c,
- 0x0904, 0x17e7, 0xa3ac, 0xa2b0, 0x00a8, 0xa5b4, 0xa4b8, 0xa7bc,
- 0xa6c0, 0x9d86, 0x002c, 0x0904, 0x17e7, 0xa3c4, 0xa2c8, 0x0050,
- 0xa5cc, 0xa4d0, 0xa7d4, 0xa6d8, 0x9d86, 0x002c, 0x0904, 0x17e7,
- 0xa3dc, 0xa2e0, 0xab2e, 0xaa32, 0xad1e, 0xac22, 0xaf26, 0xae2a,
- 0xa988, 0x8c60, 0x2c1d, 0xa8ac, 0xaab0, 0xa836, 0xaa3a, 0x8109,
- 0xa916, 0x1160, 0x3e60, 0x601c, 0xc085, 0x601e, 0xa87c, 0xc0dd,
- 0xa87e, 0x9006, 0x00ce, 0x001e, 0x012e, 0x0005, 0x2800, 0xa80e,
- 0xab0a, 0x2c00, 0xa812, 0x0c70, 0x0804, 0x17d9, 0x2ff0, 0x0126,
- 0x2091, 0x2200, 0x0016, 0x00c6, 0x3e60, 0x6014, 0x2048, 0x2940,
- 0xa80e, 0x2061, 0x1edd, 0xa813, 0x1edd, 0x2c05, 0xa80a, 0xa964,
- 0xa91a, 0xa87c, 0xd0ac, 0x090c, 0x0d85, 0x9006, 0xa842, 0xa83e,
- 0x2c05, 0x908a, 0x0034, 0x1a0c, 0x0d85, 0xadcc, 0xacd0, 0xafd4,
- 0xaed8, 0xabdc, 0xaae0, 0xab2e, 0xaa32, 0xad1e, 0xac22, 0xaf26,
- 0xae2a, 0xa8ac, 0xaab0, 0xa836, 0xaa3a, 0xa988, 0xa864, 0x9084,
- 0x00ff, 0x9086, 0x0008, 0x1120, 0x8109, 0xa916, 0x0128, 0x0080,
- 0x918a, 0x0002, 0xa916, 0x1160, 0x3e60, 0x601c, 0xc085, 0x601e,
- 0xa87c, 0xc0dd, 0xa87e, 0x9006, 0x00ce, 0x001e, 0x012e, 0x0005,
- 0xa804, 0x9045, 0x090c, 0x0d85, 0xa80e, 0xa064, 0xa81a, 0x9084,
- 0x000f, 0x9080, 0x1ee2, 0x2015, 0x82ff, 0x090c, 0x0d85, 0xaa12,
- 0x2205, 0xa80a, 0x0c08, 0x903e, 0x2730, 0xa880, 0xd0fc, 0x1190,
- 0x2d00, 0x0002, 0x1abd, 0x19ea, 0x19ea, 0x1abd, 0x19ea, 0x1ab7,
- 0x1abd, 0x19ea, 0x1a5a, 0x1a5a, 0x1a5a, 0x1abd, 0x1a5a, 0x1abd,
- 0x1ab4, 0x1a5a, 0xc0fc, 0xa882, 0xab2c, 0xaa30, 0xad1c, 0xac20,
- 0xdd9c, 0x0904, 0x1abf, 0x2c05, 0x908a, 0x0034, 0x1a0c, 0x0d85,
- 0x9082, 0x001b, 0x0002, 0x19d6, 0x19d4, 0x19d4, 0x19d4, 0x19d4,
- 0x19d4, 0x19da, 0x19d4, 0x19d4, 0x19d4, 0x19d4, 0x19d4, 0x19de,
- 0x19d4, 0x19d4, 0x19d4, 0x19d4, 0x19d4, 0x19e2, 0x19d4, 0x19d4,
- 0x19d4, 0x19d4, 0x19d4, 0x19e6, 0x080c, 0x0d85, 0xa774, 0xa678,
- 0x0804, 0x1abf, 0xa78c, 0xa690, 0x0804, 0x1abf, 0xa7a4, 0xa6a8,
- 0x0804, 0x1abf, 0xa7bc, 0xa6c0, 0x0804, 0x1abf, 0xa7d4, 0xa6d8,
- 0x0804, 0x1abf, 0xa898, 0x901d, 0x1108, 0xab9c, 0x9016, 0x2c05,
- 0x908a, 0x0036, 0x1a0c, 0x0d85, 0x9082, 0x001b, 0x0002, 0x1a12,
- 0x1a12, 0x1a14, 0x1a12, 0x1a12, 0x1a12, 0x1a1e, 0x1a12, 0x1a12,
- 0x1a12, 0x1a28, 0x1a12, 0x1a12, 0x1a12, 0x1a32, 0x1a12, 0x1a12,
- 0x1a12, 0x1a3c, 0x1a12, 0x1a12, 0x1a12, 0x1a46, 0x1a12, 0x1a12,
- 0x1a12, 0x1a50, 0x080c, 0x0d85, 0xa574, 0xa478, 0x9d86, 0x0004,
- 0x0904, 0x1abf, 0xa37c, 0xa280, 0x0804, 0x1abf, 0xa584, 0xa488,
- 0x9d86, 0x0004, 0x0904, 0x1abf, 0xa38c, 0xa290, 0x0804, 0x1abf,
- 0xa594, 0xa498, 0x9d86, 0x0004, 0x0904, 0x1abf, 0xa39c, 0xa2a0,
- 0x0804, 0x1abf, 0xa5a4, 0xa4a8, 0x9d86, 0x0004, 0x0904, 0x1abf,
- 0xa3ac, 0xa2b0, 0x0804, 0x1abf, 0xa5b4, 0xa4b8, 0x9d86, 0x0004,
- 0x0904, 0x1abf, 0xa3bc, 0xa2c0, 0x0804, 0x1abf, 0xa5c4, 0xa4c8,
- 0x9d86, 0x0004, 0x0904, 0x1abf, 0xa3cc, 0xa2d0, 0x0804, 0x1abf,
- 0xa5d4, 0xa4d8, 0x9d86, 0x0004, 0x0904, 0x1abf, 0xa3dc, 0xa2e0,
- 0x0804, 0x1abf, 0xa898, 0x901d, 0x1108, 0xab9c, 0x9016, 0x2c05,
- 0x908a, 0x0034, 0x1a0c, 0x0d85, 0x9082, 0x001b, 0x0002, 0x1a82,
- 0x1a80, 0x1a80, 0x1a80, 0x1a80, 0x1a80, 0x1a8c, 0x1a80, 0x1a80,
- 0x1a80, 0x1a80, 0x1a80, 0x1a96, 0x1a80, 0x1a80, 0x1a80, 0x1a80,
- 0x1a80, 0x1aa0, 0x1a80, 0x1a80, 0x1a80, 0x1a80, 0x1a80, 0x1aaa,
- 0x080c, 0x0d85, 0xa56c, 0xa470, 0xa774, 0xa678, 0x9d86, 0x000c,
- 0x05b0, 0xa37c, 0xa280, 0x0498, 0xa584, 0xa488, 0xa78c, 0xa690,
- 0x9d86, 0x000c, 0x0560, 0xa394, 0xa298, 0x0448, 0xa59c, 0xa4a0,
- 0xa7a4, 0xa6a8, 0x9d86, 0x000c, 0x0510, 0xa3ac, 0xa2b0, 0x00f8,
- 0xa5b4, 0xa4b8, 0xa7bc, 0xa6c0, 0x9d86, 0x000c, 0x01c0, 0xa3c4,
- 0xa2c8, 0x00a8, 0xa5cc, 0xa4d0, 0xa7d4, 0xa6d8, 0x9d86, 0x000c,
- 0x0170, 0xa3dc, 0xa2e0, 0x0058, 0x9d86, 0x000e, 0x1130, 0x080c,
- 0x1eb8, 0x1904, 0x1993, 0x900e, 0x0050, 0x080c, 0x0d85, 0xab2e,
- 0xaa32, 0xad1e, 0xac22, 0xaf26, 0xae2a, 0x080c, 0x1eb8, 0x0005,
- 0x6014, 0x2048, 0x6118, 0x81ff, 0x0148, 0x810c, 0x810c, 0x810c,
- 0x81ff, 0x1118, 0xa887, 0x0001, 0x0008, 0xa986, 0x601b, 0x0002,
- 0xa874, 0x9084, 0x00ff, 0x9084, 0x0008, 0x0150, 0x00e9, 0x6000,
- 0x9086, 0x0004, 0x1120, 0x2009, 0x0048, 0x080c, 0xafcc, 0x0005,
- 0xa974, 0xd1dc, 0x1108, 0x0005, 0xa934, 0xa88c, 0x9106, 0x1158,
- 0xa938, 0xa890, 0x9106, 0x1138, 0x601c, 0xc084, 0x601e, 0x2009,
- 0x0048, 0x0804, 0xafcc, 0x0005, 0x0126, 0x00c6, 0x2091, 0x2200,
- 0x00ce, 0x7908, 0x918c, 0x0007, 0x9186, 0x0000, 0x05b0, 0x9186,
- 0x0003, 0x0598, 0x6020, 0x6023, 0x0000, 0x0006, 0x2031, 0x0008,
- 0x00c6, 0x781f, 0x0808, 0x7808, 0xd09c, 0x0120, 0x080c, 0x13d4,
- 0x8631, 0x1db8, 0x00ce, 0x781f, 0x0800, 0x2031, 0x0168, 0x00c6,
- 0x7808, 0xd09c, 0x190c, 0x13d4, 0x00ce, 0x2001, 0x0038, 0x080c,
- 0x1bcf, 0x7930, 0x9186, 0x0040, 0x0160, 0x9186, 0x0042, 0x190c,
- 0x0d85, 0x2001, 0x001e, 0x8001, 0x1df0, 0x8631, 0x1d40, 0x080c,
- 0x1bde, 0x000e, 0x6022, 0x012e, 0x0005, 0x080c, 0x1bcb, 0x7827,
- 0x0015, 0x7828, 0x9c06, 0x1db8, 0x782b, 0x0000, 0x0ca0, 0x00f6,
- 0x2079, 0x0300, 0x7803, 0x0000, 0x78ab, 0x0004, 0x00fe, 0x080c,
- 0x76a5, 0x1188, 0x2001, 0x0138, 0x2003, 0x0000, 0x2001, 0x0160,
- 0x2003, 0x0000, 0x2011, 0x012c, 0xa001, 0xa001, 0x8211, 0x1de0,
- 0x0059, 0x0804, 0x7747, 0x0479, 0x0039, 0x2001, 0x0160, 0x2502,
- 0x2001, 0x0138, 0x2202, 0x0005, 0x00e6, 0x2071, 0x0200, 0x080c,
- 0x2aad, 0x2009, 0x003c, 0x080c, 0x2241, 0x2001, 0x015d, 0x2003,
- 0x0000, 0x7000, 0x9084, 0x003c, 0x1de0, 0x080c, 0x873a, 0x70a0,
- 0x70a2, 0x7098, 0x709a, 0x709c, 0x709e, 0x2001, 0x020d, 0x2003,
- 0x0020, 0x00f6, 0x2079, 0x0300, 0x080c, 0x1366, 0x7803, 0x0001,
- 0x00fe, 0x00ee, 0x0005, 0x2001, 0x0138, 0x2014, 0x2003, 0x0000,
- 0x2001, 0x0160, 0x202c, 0x2003, 0x0000, 0x080c, 0x76a5, 0x1108,
- 0x0005, 0x2021, 0x0260, 0x2001, 0x0141, 0x201c, 0xd3dc, 0x1168,
- 0x2001, 0x0109, 0x201c, 0x939c, 0x0048, 0x1160, 0x2001, 0x0111,
- 0x201c, 0x83ff, 0x1110, 0x8421, 0x1d70, 0x2001, 0x015d, 0x2003,
- 0x0000, 0x0005, 0x0046, 0x2021, 0x0019, 0x2003, 0x0048, 0xa001,
- 0xa001, 0x201c, 0x939c, 0x0048, 0x0120, 0x8421, 0x1db0, 0x004e,
- 0x0c60, 0x004e, 0x0c40, 0x601c, 0xc084, 0x601e, 0x0005, 0x2c08,
- 0x621c, 0x080c, 0x16b9, 0x7930, 0x0005, 0x2c08, 0x621c, 0x080c,
- 0x1702, 0x7930, 0x0005, 0x8001, 0x1df0, 0x0005, 0x2031, 0x0064,
- 0x781c, 0x9084, 0x0007, 0x0170, 0x2001, 0x0038, 0x0c41, 0x9186,
- 0x0040, 0x0904, 0x1c3c, 0x2001, 0x001e, 0x0c69, 0x8631, 0x1d80,
- 0x080c, 0x0d85, 0x781f, 0x0202, 0x2001, 0x015d, 0x2003, 0x0000,
- 0x2001, 0x0dac, 0x0c01, 0x781c, 0xd084, 0x0110, 0x0861, 0x04e0,
- 0x2001, 0x0030, 0x0891, 0x9186, 0x0040, 0x0568, 0x781c, 0xd084,
- 0x1da8, 0x781f, 0x0101, 0x2001, 0x0014, 0x0869, 0x2001, 0x0037,
- 0x0821, 0x9186, 0x0040, 0x0140, 0x2001, 0x0030, 0x080c, 0x1bd5,
- 0x9186, 0x0040, 0x190c, 0x0d85, 0x00d6, 0x2069, 0x0200, 0x692c,
- 0xd1f4, 0x1170, 0xd1c4, 0x0160, 0xd19c, 0x0130, 0x6800, 0x9085,
- 0x1800, 0x6802, 0x00de, 0x0080, 0x6908, 0x9184, 0x0007, 0x1db0,
- 0x00de, 0x781f, 0x0100, 0x791c, 0x9184, 0x0007, 0x090c, 0x0d85,
- 0xa001, 0xa001, 0x781f, 0x0200, 0x0005, 0x0126, 0x2091, 0x2400,
- 0x2079, 0x0380, 0x2001, 0x19e9, 0x2070, 0x012e, 0x0005, 0x2cf0,
- 0x0126, 0x2091, 0x2400, 0x3e60, 0x6014, 0x2048, 0xa964, 0xa91a,
- 0x918c, 0x00ff, 0x9184, 0x000f, 0x0002, 0x1c71, 0x1c71, 0x1c71,
- 0x1c73, 0x1c71, 0x1c71, 0x1c71, 0x1c71, 0x1c65, 0x1c7b, 0x1c71,
- 0x1c77, 0x1c71, 0x1c71, 0x1c71, 0x1c71, 0x9086, 0x0008, 0x1148,
- 0xa87c, 0xd0b4, 0x0904, 0x1deb, 0x2011, 0x1edd, 0x2205, 0xab88,
- 0x00a8, 0x080c, 0x0d85, 0x9186, 0x0013, 0x0128, 0x0cd0, 0x9186,
- 0x001b, 0x0108, 0x0cb0, 0xa87c, 0xd0b4, 0x0904, 0x1deb, 0x9184,
- 0x000f, 0x9080, 0x1ee2, 0x2015, 0x2205, 0xab88, 0x2908, 0xa80a,
- 0xa90e, 0xaa12, 0xab16, 0x9006, 0xa842, 0xa83e, 0x012e, 0x0005,
- 0x2cf0, 0x0126, 0x2091, 0x2400, 0x3e60, 0x6014, 0x2048, 0xa88c,
- 0xa990, 0xaaac, 0xabb0, 0xaa36, 0xab3a, 0xa83e, 0xa942, 0xa846,
- 0xa94a, 0xa964, 0x918c, 0x00ff, 0x9186, 0x001e, 0x0198, 0x2940,
- 0xa064, 0xa81a, 0x90ec, 0x000f, 0x9d80, 0x1ee2, 0x2065, 0x2c05,
- 0x2808, 0x2c10, 0xab88, 0xa80a, 0xa90e, 0xaa12, 0xab16, 0x012e,
- 0x3e60, 0x0005, 0xa804, 0x2040, 0x0c58, 0x2cf0, 0x0126, 0x2091,
- 0x2400, 0x3e60, 0x6014, 0x2048, 0xa97c, 0x2950, 0xd1dc, 0x1904,
- 0x1db5, 0xc1dd, 0xa97e, 0x9006, 0xa842, 0xa83e, 0xa988, 0x8109,
- 0xa916, 0xa964, 0xa91a, 0x9184, 0x000f, 0x9088, 0x1ee2, 0x2145,
- 0x0002, 0x1ce9, 0x1cf7, 0x1ce9, 0x1ce9, 0x1ce9, 0x1ceb, 0x1ce9,
- 0x1ce9, 0x1d4c, 0x1d4c, 0x1ce9, 0x1ce9, 0x1ce9, 0x1d4a, 0x1ce9,
- 0x1ce9, 0x080c, 0x0d85, 0xa804, 0x2050, 0xb164, 0xa91a, 0x9184,
- 0x000f, 0x9080, 0x1ee2, 0x2045, 0xd19c, 0x1904, 0x1d4c, 0x9036,
- 0x2638, 0x2805, 0x908a, 0x0036, 0x1a0c, 0x0d85, 0x9082, 0x001b,
- 0x0002, 0x1d1c, 0x1d1c, 0x1d1e, 0x1d1c, 0x1d1c, 0x1d1c, 0x1d24,
- 0x1d1c, 0x1d1c, 0x1d1c, 0x1d2a, 0x1d1c, 0x1d1c, 0x1d1c, 0x1d30,
- 0x1d1c, 0x1d1c, 0x1d1c, 0x1d36, 0x1d1c, 0x1d1c, 0x1d1c, 0x1d3c,
- 0x1d1c, 0x1d1c, 0x1d1c, 0x1d42, 0x080c, 0x0d85, 0xb574, 0xb478,
- 0xb37c, 0xb280, 0x0804, 0x1d91, 0xb584, 0xb488, 0xb38c, 0xb290,
- 0x0804, 0x1d91, 0xb594, 0xb498, 0xb39c, 0xb2a0, 0x0804, 0x1d91,
- 0xb5a4, 0xb4a8, 0xb3ac, 0xb2b0, 0x0804, 0x1d91, 0xb5b4, 0xb4b8,
- 0xb3bc, 0xb2c0, 0x0804, 0x1d91, 0xb5c4, 0xb4c8, 0xb3cc, 0xb2d0,
- 0x0804, 0x1d91, 0xb5d4, 0xb4d8, 0xb3dc, 0xb2e0, 0x0804, 0x1d91,
- 0x0804, 0x1d91, 0x080c, 0x0d85, 0x2805, 0x908a, 0x0034, 0x1a0c,
- 0x0d85, 0x9082, 0x001b, 0x0002, 0x1d6f, 0x1d6d, 0x1d6d, 0x1d6d,
- 0x1d6d, 0x1d6d, 0x1d76, 0x1d6d, 0x1d6d, 0x1d6d, 0x1d6d, 0x1d6d,
- 0x1d7d, 0x1d6d, 0x1d6d, 0x1d6d, 0x1d6d, 0x1d6d, 0x1d84, 0x1d6d,
- 0x1d6d, 0x1d6d, 0x1d6d, 0x1d6d, 0x1d8b, 0x080c, 0x0d85, 0xb56c,
- 0xb470, 0xb774, 0xb678, 0xb37c, 0xb280, 0x00d8, 0xb584, 0xb488,
- 0xb78c, 0xb690, 0xb394, 0xb298, 0x00a0, 0xb59c, 0xb4a0, 0xb7a4,
- 0xb6a8, 0xb3ac, 0xb2b0, 0x0068, 0xb5b4, 0xb4b8, 0xb7bc, 0xb6c0,
- 0xb3c4, 0xb2c8, 0x0030, 0xb5cc, 0xb4d0, 0xb7d4, 0xb6d8, 0xb3dc,
- 0xb2e0, 0xab2e, 0xaa32, 0xad1e, 0xac22, 0xaf26, 0xae2a, 0xa988,
- 0x8109, 0xa916, 0x1118, 0x9006, 0x012e, 0x0005, 0x8840, 0x2805,
- 0x9005, 0x1168, 0xb004, 0x9005, 0x090c, 0x0d85, 0x2050, 0xb164,
- 0xa91a, 0x9184, 0x000f, 0x9080, 0x1ee2, 0x2045, 0x2805, 0x2810,
- 0x2a08, 0xa80a, 0xa90e, 0xaa12, 0x0c30, 0x3e60, 0x6344, 0xd3fc,
- 0x190c, 0x0d85, 0xa93c, 0xaa40, 0xa844, 0x9106, 0x1118, 0xa848,
- 0x9206, 0x0508, 0x2958, 0xab48, 0xac44, 0x2940, 0x080c, 0x1f02,
- 0x1998, 0x2850, 0x2c40, 0xab14, 0xa880, 0xd0fc, 0x1140, 0xa810,
- 0x2005, 0xa80a, 0x2a00, 0xa80e, 0x2009, 0x8015, 0x0070, 0x00c6,
- 0x3e60, 0x6044, 0xc0a4, 0x9085, 0x8005, 0x6046, 0x00ce, 0x8319,
- 0xab16, 0x1904, 0x1d9e, 0x2009, 0x8005, 0x3e60, 0x6044, 0x9105,
- 0x6046, 0x0804, 0x1d9b, 0x080c, 0x0d85, 0x00f6, 0x00e6, 0x0096,
- 0x00c6, 0x0026, 0x704c, 0x9c06, 0x190c, 0x0d85, 0x2079, 0x0090,
- 0x2001, 0x0105, 0x2003, 0x0010, 0x782b, 0x0004, 0x7057, 0x0000,
- 0x6014, 0x2048, 0x080c, 0xcc16, 0x0118, 0xa880, 0xc0bd, 0xa882,
- 0x6020, 0x9086, 0x0006, 0x1170, 0x2061, 0x0100, 0x62c8, 0x2001,
- 0x00fa, 0x8001, 0x1df0, 0x60c8, 0x9206, 0x1dc0, 0x60c4, 0xa89a,
- 0x60c8, 0xa896, 0x704c, 0x2060, 0x00c6, 0x080c, 0xc802, 0x080c,
- 0xaae0, 0x00ce, 0x704c, 0x9c06, 0x1150, 0x2009, 0x0040, 0x080c,
- 0x2241, 0x080c, 0xa585, 0x2011, 0x0000, 0x080c, 0xa419, 0x002e,
- 0x00ce, 0x009e, 0x00ee, 0x00fe, 0x0005, 0x00f6, 0x2079, 0x0090,
- 0x781c, 0x0006, 0x7818, 0x0006, 0x2079, 0x0100, 0x7a14, 0x9284,
- 0x1984, 0x9085, 0x0012, 0x7816, 0x2019, 0x1000, 0x8319, 0x090c,
- 0x0d85, 0x7820, 0xd0bc, 0x1dd0, 0x79c8, 0x000e, 0x9102, 0x001e,
- 0x0006, 0x0016, 0x79c4, 0x000e, 0x9103, 0x78c6, 0x000e, 0x78ca,
- 0x9284, 0x1984, 0x9085, 0x0012, 0x7816, 0x2079, 0x0090, 0x782b,
- 0x0008, 0x7057, 0x0000, 0x00fe, 0x0005, 0x00f6, 0x00e6, 0x2071,
- 0x19e9, 0x7054, 0x9086, 0x0000, 0x0904, 0x1eb3, 0x2079, 0x0090,
- 0x2009, 0x0207, 0x210c, 0xd194, 0x01b8, 0x2009, 0x020c, 0x210c,
- 0x9184, 0x0003, 0x0188, 0x080c, 0xeb9e, 0x2001, 0x0133, 0x2004,
- 0x9005, 0x090c, 0x0d85, 0x0016, 0x2009, 0x0040, 0x080c, 0x2241,
- 0x001e, 0x2001, 0x020c, 0x2102, 0x2009, 0x0206, 0x2104, 0x2009,
- 0x0203, 0x210c, 0x9106, 0x1120, 0x2009, 0x0040, 0x080c, 0x2241,
- 0x782c, 0xd0fc, 0x09a8, 0x080c, 0xaafc, 0x782c, 0xd0fc, 0x1de8,
- 0x080c, 0xaae0, 0x7054, 0x9086, 0x0000, 0x1950, 0x782b, 0x0004,
- 0x782c, 0xd0ac, 0x1de8, 0x2009, 0x0040, 0x080c, 0x2241, 0x782b,
- 0x0002, 0x7057, 0x0000, 0x00ee, 0x00fe, 0x0005, 0x080c, 0x0d85,
- 0x8c60, 0x2c05, 0x9005, 0x0110, 0x8a51, 0x0005, 0xa004, 0x9005,
- 0x0168, 0xa85a, 0x2040, 0xa064, 0x9084, 0x000f, 0x9080, 0x1ee2,
- 0x2065, 0x8cff, 0x090c, 0x0d85, 0x8a51, 0x0005, 0x2050, 0x0005,
- 0x0000, 0x001d, 0x0021, 0x0025, 0x0029, 0x002d, 0x0031, 0x0035,
- 0x0000, 0x001b, 0x0021, 0x0027, 0x002d, 0x0033, 0x0000, 0x0000,
- 0x0023, 0x0000, 0x0000, 0x1ed5, 0x1ed1, 0x1ed5, 0x1ed5, 0x1edf,
- 0x0000, 0x1ed5, 0x1edc, 0x1edc, 0x1ed9, 0x1edc, 0x1edc, 0x0000,
- 0x1edf, 0x1edc, 0x0000, 0x1ed7, 0x1ed7, 0x0000, 0x1ed7, 0x1edf,
- 0x0000, 0x1ed7, 0x1edd, 0x1edd, 0x1edd, 0x0000, 0x1edd, 0x0000,
- 0x1edf, 0x1edd, 0x00c6, 0x00d6, 0x0086, 0xab42, 0xac3e, 0xa888,
- 0x9055, 0x0904, 0x20e1, 0x2940, 0xa064, 0x90ec, 0x000f, 0x9084,
- 0x00ff, 0x9086, 0x0008, 0x1118, 0x2061, 0x1edd, 0x00d0, 0x9de0,
- 0x1ee2, 0x9d86, 0x0007, 0x0130, 0x9d86, 0x000e, 0x0118, 0x9d86,
- 0x000f, 0x1120, 0xa08c, 0x9422, 0xa090, 0x931b, 0x2c05, 0x9065,
- 0x1140, 0x0310, 0x0804, 0x20e1, 0xa004, 0x9045, 0x0904, 0x20e1,
- 0x08d8, 0x2c05, 0x9005, 0x0904, 0x1fc9, 0xdd9c, 0x1904, 0x1f85,
- 0x908a, 0x0036, 0x1a0c, 0x0d85, 0x9082, 0x001b, 0x0002, 0x1f5a,
- 0x1f5a, 0x1f5c, 0x1f5a, 0x1f5a, 0x1f5a, 0x1f62, 0x1f5a, 0x1f5a,
- 0x1f5a, 0x1f68, 0x1f5a, 0x1f5a, 0x1f5a, 0x1f6e, 0x1f5a, 0x1f5a,
- 0x1f5a, 0x1f74, 0x1f5a, 0x1f5a, 0x1f5a, 0x1f7a, 0x1f5a, 0x1f5a,
- 0x1f5a, 0x1f80, 0x080c, 0x0d85, 0xa07c, 0x9422, 0xa080, 0x931b,
- 0x0804, 0x1fbf, 0xa08c, 0x9422, 0xa090, 0x931b, 0x0804, 0x1fbf,
- 0xa09c, 0x9422, 0xa0a0, 0x931b, 0x0804, 0x1fbf, 0xa0ac, 0x9422,
- 0xa0b0, 0x931b, 0x0804, 0x1fbf, 0xa0bc, 0x9422, 0xa0c0, 0x931b,
- 0x0804, 0x1fbf, 0xa0cc, 0x9422, 0xa0d0, 0x931b, 0x0804, 0x1fbf,
- 0xa0dc, 0x9422, 0xa0e0, 0x931b, 0x04d0, 0x908a, 0x0034, 0x1a0c,
- 0x0d85, 0x9082, 0x001b, 0x0002, 0x1fa7, 0x1fa5, 0x1fa5, 0x1fa5,
- 0x1fa5, 0x1fa5, 0x1fac, 0x1fa5, 0x1fa5, 0x1fa5, 0x1fa5, 0x1fa5,
- 0x1fb1, 0x1fa5, 0x1fa5, 0x1fa5, 0x1fa5, 0x1fa5, 0x1fb6, 0x1fa5,
- 0x1fa5, 0x1fa5, 0x1fa5, 0x1fa5, 0x1fbb, 0x080c, 0x0d85, 0xa07c,
- 0x9422, 0xa080, 0x931b, 0x0098, 0xa094, 0x9422, 0xa098, 0x931b,
- 0x0070, 0xa0ac, 0x9422, 0xa0b0, 0x931b, 0x0048, 0xa0c4, 0x9422,
- 0xa0c8, 0x931b, 0x0020, 0xa0dc, 0x9422, 0xa0e0, 0x931b, 0x0630,
- 0x2300, 0x9405, 0x0160, 0x8a51, 0x0904, 0x20e1, 0x8c60, 0x0804,
- 0x1f31, 0xa004, 0x9045, 0x0904, 0x20e1, 0x0804, 0x1f0c, 0x8a51,
- 0x0904, 0x20e1, 0x8c60, 0x2c05, 0x9005, 0x1158, 0xa004, 0x9045,
- 0x0904, 0x20e1, 0xa064, 0x90ec, 0x000f, 0x9de0, 0x1ee2, 0x2c05,
- 0x2060, 0xa880, 0xc0fc, 0xa882, 0x0804, 0x20d6, 0x2c05, 0x8422,
- 0x8420, 0x831a, 0x9399, 0x0000, 0xac2e, 0xab32, 0xdd9c, 0x1904,
- 0x2073, 0x9082, 0x001b, 0x0002, 0x200f, 0x200f, 0x2011, 0x200f,
- 0x200f, 0x200f, 0x201f, 0x200f, 0x200f, 0x200f, 0x202d, 0x200f,
- 0x200f, 0x200f, 0x203b, 0x200f, 0x200f, 0x200f, 0x2049, 0x200f,
- 0x200f, 0x200f, 0x2057, 0x200f, 0x200f, 0x200f, 0x2065, 0x080c,
- 0x0d85, 0xa17c, 0x2400, 0x9122, 0xa180, 0x2300, 0x911b, 0x0a0c,
- 0x0d85, 0xa074, 0x9420, 0xa078, 0x9319, 0x0804, 0x20d1, 0xa18c,
- 0x2400, 0x9122, 0xa190, 0x2300, 0x911b, 0x0a0c, 0x0d85, 0xa084,
- 0x9420, 0xa088, 0x9319, 0x0804, 0x20d1, 0xa19c, 0x2400, 0x9122,
- 0xa1a0, 0x2300, 0x911b, 0x0a0c, 0x0d85, 0xa094, 0x9420, 0xa098,
- 0x9319, 0x0804, 0x20d1, 0xa1ac, 0x2400, 0x9122, 0xa1b0, 0x2300,
- 0x911b, 0x0a0c, 0x0d85, 0xa0a4, 0x9420, 0xa0a8, 0x9319, 0x0804,
- 0x20d1, 0xa1bc, 0x2400, 0x9122, 0xa1c0, 0x2300, 0x911b, 0x0a0c,
- 0x0d85, 0xa0b4, 0x9420, 0xa0b8, 0x9319, 0x0804, 0x20d1, 0xa1cc,
- 0x2400, 0x9122, 0xa1d0, 0x2300, 0x911b, 0x0a0c, 0x0d85, 0xa0c4,
- 0x9420, 0xa0c8, 0x9319, 0x0804, 0x20d1, 0xa1dc, 0x2400, 0x9122,
- 0xa1e0, 0x2300, 0x911b, 0x0a0c, 0x0d85, 0xa0d4, 0x9420, 0xa0d8,
- 0x9319, 0x0804, 0x20d1, 0x9082, 0x001b, 0x0002, 0x2091, 0x208f,
- 0x208f, 0x208f, 0x208f, 0x208f, 0x209e, 0x208f, 0x208f, 0x208f,
- 0x208f, 0x208f, 0x20ab, 0x208f, 0x208f, 0x208f, 0x208f, 0x208f,
- 0x20b8, 0x208f, 0x208f, 0x208f, 0x208f, 0x208f, 0x20c5, 0x080c,
- 0x0d85, 0xa17c, 0x2400, 0x9122, 0xa180, 0x2300, 0x911b, 0x0a0c,
- 0x0d85, 0xa06c, 0x9420, 0xa070, 0x9319, 0x0498, 0xa194, 0x2400,
- 0x9122, 0xa198, 0x2300, 0x911b, 0x0a0c, 0x0d85, 0xa084, 0x9420,
- 0xa088, 0x9319, 0x0430, 0xa1ac, 0x2400, 0x9122, 0xa1b0, 0x2300,
- 0x911b, 0x0a0c, 0x0d85, 0xa09c, 0x9420, 0xa0a0, 0x9319, 0x00c8,
- 0xa1c4, 0x2400, 0x9122, 0xa1c8, 0x2300, 0x911b, 0x0a0c, 0x0d85,
- 0xa0b4, 0x9420, 0xa0b8, 0x9319, 0x0060, 0xa1dc, 0x2400, 0x9122,
- 0xa1e0, 0x2300, 0x911b, 0x0a0c, 0x0d85, 0xa0cc, 0x9420, 0xa0d0,
- 0x9319, 0xac1e, 0xab22, 0xa880, 0xc0fd, 0xa882, 0x2800, 0xa85a,
- 0x2c00, 0xa812, 0x2a00, 0xa816, 0x000e, 0x000e, 0x000e, 0x9006,
- 0x0028, 0x008e, 0x00de, 0x00ce, 0x9085, 0x0001, 0x0005, 0x00c6,
- 0x610c, 0x0016, 0x9026, 0x2410, 0x6004, 0x9420, 0x9291, 0x0000,
- 0x2c04, 0x9210, 0x9ce0, 0x0002, 0x918a, 0x0002, 0x1da8, 0x9284,
- 0x000f, 0x9405, 0x001e, 0x00ce, 0x0005, 0x7803, 0x0003, 0x780f,
- 0x0000, 0x6004, 0x7812, 0x2c04, 0x7816, 0x9ce0, 0x0002, 0x918a,
- 0x0002, 0x1db8, 0x0005, 0x2001, 0x0005, 0x2004, 0xd0bc, 0x190c,
- 0x0d7e, 0xd094, 0x0110, 0x080c, 0x1208, 0x0005, 0x0126, 0x2091,
- 0x2600, 0x2079, 0x0200, 0x2071, 0x0260, 0x2069, 0x1800, 0x7817,
- 0x0000, 0x789b, 0x0814, 0x78a3, 0x0406, 0x789f, 0x0410, 0x2009,
- 0x013b, 0x200b, 0x0400, 0x781b, 0x0002, 0x783b, 0x001f, 0x7837,
- 0x0020, 0x7803, 0x1600, 0x012e, 0x0005, 0x2091, 0x2600, 0x781c,
- 0xd0a4, 0x190c, 0x223e, 0x7900, 0xd1dc, 0x1118, 0x9084, 0x0006,
- 0x001a, 0x9084, 0x000e, 0x0002, 0x215c, 0x2154, 0x80b1, 0x2154,
- 0x2156, 0x2156, 0x2156, 0x2156, 0x8097, 0x2154, 0x2158, 0x2154,
- 0x2156, 0x2154, 0x2156, 0x2154, 0x080c, 0x0d85, 0x0031, 0x0020,
- 0x080c, 0x8097, 0x080c, 0x80b1, 0x0005, 0x0006, 0x0016, 0x0026,
- 0x080c, 0xeb9e, 0x7930, 0x9184, 0x0003, 0x0510, 0x080c, 0xaae0,
- 0x2001, 0x19fc, 0x2004, 0x9005, 0x01a0, 0x2001, 0x0133, 0x2004,
- 0x9005, 0x090c, 0x0d85, 0x00c6, 0x2001, 0x19fc, 0x2064, 0x080c,
- 0xaafc, 0x080c, 0xc802, 0x2009, 0x0040, 0x080c, 0x2241, 0x00ce,
- 0x0408, 0x2009, 0x0040, 0x080c, 0x2241, 0x080c, 0xaafc, 0x00d0,
- 0x9184, 0x0014, 0x01a0, 0x6a00, 0x9286, 0x0003, 0x0160, 0x080c,
- 0x76a5, 0x1138, 0x080c, 0x79a7, 0x080c, 0x617e, 0x080c, 0x75d4,
- 0x0010, 0x080c, 0x6039, 0x080c, 0x814f, 0x0041, 0x0018, 0x9184,
- 0x9540, 0x1dc8, 0x002e, 0x001e, 0x000e, 0x0005, 0x00e6, 0x0036,
- 0x0046, 0x0056, 0x2071, 0x1a6f, 0x080c, 0x1b47, 0x005e, 0x004e,
- 0x003e, 0x00ee, 0x0005, 0x0126, 0x2091, 0x2e00, 0x2071, 0x1800,
- 0x7128, 0x2001, 0x1970, 0x2102, 0x2001, 0x1978, 0x2102, 0x2001,
- 0x013b, 0x2102, 0x2079, 0x0200, 0x2001, 0x0201, 0x789e, 0x78a3,
- 0x0200, 0x9198, 0x0007, 0x831c, 0x831c, 0x831c, 0x9398, 0x0005,
- 0x2320, 0x9182, 0x0204, 0x1230, 0x2011, 0x0008, 0x8423, 0x8423,
- 0x8423, 0x0488, 0x9182, 0x024c, 0x1240, 0x2011, 0x0007, 0x8403,
- 0x8003, 0x9400, 0x9400, 0x9420, 0x0430, 0x9182, 0x02bc, 0x1238,
- 0x2011, 0x0006, 0x8403, 0x8003, 0x9400, 0x9420, 0x00e0, 0x9182,
- 0x034c, 0x1230, 0x2011, 0x0005, 0x8403, 0x8003, 0x9420, 0x0098,
- 0x9182, 0x042c, 0x1228, 0x2011, 0x0004, 0x8423, 0x8423, 0x0058,
- 0x9182, 0x059c, 0x1228, 0x2011, 0x0003, 0x8403, 0x9420, 0x0018,
- 0x2011, 0x0002, 0x8423, 0x9482, 0x0228, 0x8002, 0x8020, 0x8301,
- 0x9402, 0x0110, 0x0208, 0x8321, 0x8217, 0x8203, 0x9405, 0x789a,
- 0x012e, 0x0005, 0x0006, 0x00d6, 0x2069, 0x0200, 0x6814, 0x9084,
- 0xffc0, 0x910d, 0x6916, 0x00de, 0x000e, 0x0005, 0x00d6, 0x2069,
- 0x0200, 0x9005, 0x6810, 0x0110, 0xc0a5, 0x0008, 0xc0a4, 0x6812,
- 0x00de, 0x0005, 0x0006, 0x00d6, 0x2069, 0x0200, 0x6810, 0x9084,
- 0xfff8, 0x910d, 0x6912, 0x00de, 0x000e, 0x0005, 0x7938, 0x080c,
- 0x0d7e, 0x00f6, 0x2079, 0x0200, 0x7902, 0xa001, 0xa001, 0xa001,
- 0xa001, 0xa001, 0xa001, 0x7902, 0xa001, 0xa001, 0xa001, 0xa001,
- 0xa001, 0xa001, 0x00fe, 0x0005, 0x0126, 0x2091, 0x2800, 0x2061,
- 0x0100, 0x2071, 0x1800, 0x2009, 0x0000, 0x080c, 0x2aa7, 0x080c,
- 0x29bd, 0x2001, 0x199e, 0x2003, 0x0700, 0x2001, 0x199f, 0x2003,
- 0x0700, 0x080c, 0x2b18, 0x9006, 0x080c, 0x29ec, 0x9006, 0x080c,
- 0x29cf, 0x20a9, 0x0012, 0x1d04, 0x2273, 0x2091, 0x6000, 0x1f04,
- 0x2273, 0x602f, 0x0100, 0x602f, 0x0000, 0x6050, 0x9085, 0x0400,
- 0x9084, 0xdfff, 0x6052, 0x6224, 0x080c, 0x2af5, 0x080c, 0x26db,
- 0x2009, 0x00ef, 0x6132, 0x6136, 0x080c, 0x26eb, 0x60e7, 0x0000,
- 0x61ea, 0x60e3, 0x0008, 0x604b, 0xf7f7, 0x6043, 0x0000, 0x602f,
- 0x0080, 0x602f, 0x0000, 0x6007, 0x349f, 0x00c6, 0x2061, 0x0140,
- 0x608b, 0x000b, 0x608f, 0x10b8, 0x6093, 0x0000, 0x6097, 0x0198,
- 0x00ce, 0x6004, 0x9085, 0x8000, 0x6006, 0x60bb, 0x0000, 0x20a9,
- 0x0018, 0x60bf, 0x0000, 0x1f04, 0x22b1, 0x60bb, 0x0000, 0x60bf,
- 0x0108, 0x60bf, 0x0012, 0x60bf, 0x0405, 0x60bf, 0x0014, 0x60bf,
- 0x0320, 0x60bf, 0x0018, 0x601b, 0x00f0, 0x601f, 0x001e, 0x600f,
- 0x006b, 0x602b, 0x402c, 0x012e, 0x0005, 0x00f6, 0x2079, 0x0140,
- 0x78c3, 0x0080, 0x78c3, 0x0083, 0x78c3, 0x0000, 0x00fe, 0x0005,
- 0x2001, 0x1835, 0x2003, 0x0000, 0x2001, 0x1834, 0x2003, 0x0001,
- 0x0005, 0x0126, 0x2091, 0x2800, 0x0006, 0x0016, 0x0026, 0x6124,
- 0x6028, 0x910c, 0x0066, 0x2031, 0x1837, 0x2634, 0x96b4, 0x0028,
- 0x006e, 0x1138, 0x6020, 0xd1bc, 0x0120, 0xd0bc, 0x1168, 0xd0b4,
- 0x1198, 0x9184, 0x5e2c, 0x1118, 0x9184, 0x0007, 0x00aa, 0x9195,
- 0x0004, 0x9284, 0x0007, 0x0082, 0x0016, 0x2001, 0x0387, 0x200c,
- 0xd1a4, 0x001e, 0x0d70, 0x0c98, 0x0016, 0x2001, 0x0387, 0x200c,
- 0xd1b4, 0x001e, 0x0d30, 0x0c58, 0x231f, 0x231c, 0x231c, 0x231c,
- 0x231e, 0x231c, 0x231c, 0x231c, 0x080c, 0x0d85, 0x0029, 0x002e,
- 0x001e, 0x000e, 0x012e, 0x0005, 0x00a6, 0x6124, 0x6028, 0xd09c,
- 0x0118, 0xd19c, 0x1904, 0x25a1, 0xd1f4, 0x190c, 0x0d7e, 0x080c,
- 0x76a5, 0x0904, 0x237c, 0x080c, 0xd33e, 0x1120, 0x7000, 0x9086,
- 0x0003, 0x0580, 0x6024, 0x9084, 0x1800, 0x0560, 0x080c, 0x76c8,
- 0x0118, 0x080c, 0x76b6, 0x1530, 0x2011, 0x0020, 0x080c, 0x2af5,
- 0x6043, 0x0000, 0x080c, 0xd33e, 0x0168, 0x080c, 0x76c8, 0x1150,
- 0x2001, 0x19a8, 0x2003, 0x0001, 0x6027, 0x1800, 0x080c, 0x7519,
- 0x0804, 0x25a4, 0x70a4, 0x9005, 0x1150, 0x70a7, 0x0001, 0x00d6,
- 0x2069, 0x0140, 0x080c, 0x76f9, 0x00de, 0x1904, 0x25a4, 0x080c,
- 0x79b1, 0x0428, 0x080c, 0x76c8, 0x1590, 0x6024, 0x9084, 0x1800,
- 0x1108, 0x0468, 0x080c, 0x79b1, 0x080c, 0x79a7, 0x080c, 0x617e,
- 0x080c, 0x75d4, 0x0804, 0x25a1, 0xd1ac, 0x1508, 0x6024, 0xd0dc,
- 0x1170, 0xd0e4, 0x1178, 0xd0d4, 0x1190, 0xd0cc, 0x0130, 0x7098,
- 0x9086, 0x0029, 0x1110, 0x080c, 0x7888, 0x0804, 0x25a1, 0x080c,
- 0x79ac, 0x0048, 0x2001, 0x197e, 0x2003, 0x0002, 0x0020, 0x080c,
- 0x77e3, 0x0804, 0x25a1, 0x080c, 0x792b, 0x0804, 0x25a1, 0x6220,
- 0xd1bc, 0x0138, 0xd2bc, 0x1904, 0x260c, 0xd2b4, 0x1904, 0x261e,
- 0x0000, 0xd1ac, 0x0904, 0x24ae, 0x0036, 0x6328, 0xc3bc, 0x632a,
- 0x003e, 0x080c, 0x76a5, 0x11d0, 0x2011, 0x0020, 0x080c, 0x2af5,
- 0x0006, 0x0026, 0x0036, 0x080c, 0x76bf, 0x1158, 0x080c, 0x79a7,
- 0x080c, 0x617e, 0x080c, 0x75d4, 0x003e, 0x002e, 0x000e, 0x00ae,
- 0x0005, 0x003e, 0x002e, 0x000e, 0x080c, 0x7679, 0x0016, 0x0046,
- 0x00c6, 0x644c, 0x9486, 0xf0f0, 0x1138, 0x2061, 0x0100, 0x644a,
- 0x6043, 0x0090, 0x6043, 0x0010, 0x74da, 0x948c, 0xff00, 0x7038,
- 0xd084, 0x0178, 0x9186, 0xf800, 0x1160, 0x7048, 0xd084, 0x1148,
- 0xc085, 0x704a, 0x0036, 0x2418, 0x2011, 0x8016, 0x080c, 0x4c2e,
- 0x003e, 0x080c, 0xd337, 0x1904, 0x2483, 0x9196, 0xff00, 0x05a8,
- 0x7060, 0x9084, 0x00ff, 0x810f, 0x81ff, 0x0110, 0x9116, 0x0568,
- 0x7130, 0xd184, 0x1550, 0x080c, 0x347d, 0x0128, 0xc18d, 0x7132,
- 0x080c, 0x6bcd, 0x1510, 0x6240, 0x9294, 0x0010, 0x0130, 0x6248,
- 0x9294, 0xff00, 0x9296, 0xff00, 0x01c0, 0x7030, 0xd08c, 0x0904,
- 0x2483, 0x7038, 0xd08c, 0x1140, 0x2001, 0x180c, 0x200c, 0xd1ac,
- 0x1904, 0x2483, 0xc1ad, 0x2102, 0x0036, 0x73d8, 0x2011, 0x8013,
- 0x080c, 0x4c2e, 0x003e, 0x0804, 0x2483, 0x7038, 0xd08c, 0x1140,
- 0x2001, 0x180c, 0x200c, 0xd1ac, 0x1904, 0x2483, 0xc1ad, 0x2102,
- 0x0036, 0x73d8, 0x2011, 0x8013, 0x080c, 0x4c2e, 0x003e, 0x7130,
- 0xc185, 0x7132, 0x2011, 0x1848, 0x220c, 0xd1a4, 0x01f0, 0x0016,
- 0x2009, 0x0001, 0x2011, 0x0100, 0x080c, 0x8ae5, 0x2019, 0x000e,
- 0x00c6, 0x2061, 0x0000, 0x080c, 0xe696, 0x00ce, 0x9484, 0x00ff,
- 0x9080, 0x3489, 0x200d, 0x918c, 0xff00, 0x810f, 0x2120, 0x9006,
- 0x2009, 0x000e, 0x080c, 0xe72a, 0x001e, 0x0016, 0x2009, 0x0002,
- 0x2019, 0x0004, 0x080c, 0x32d5, 0x001e, 0x00a8, 0x0156, 0x00b6,
- 0x20a9, 0x007f, 0x900e, 0x080c, 0x6789, 0x1140, 0x7030, 0xd084,
- 0x1118, 0xb800, 0xd0bc, 0x1110, 0x080c, 0x6198, 0x8108, 0x1f04,
- 0x2473, 0x00be, 0x015e, 0x00ce, 0x004e, 0x080c, 0xaae0, 0x080c,
- 0xad9e, 0x080c, 0xae67, 0x080c, 0xaafc, 0x60e3, 0x0000, 0x001e,
- 0x2001, 0x1800, 0x2014, 0x9296, 0x0004, 0x1170, 0xd19c, 0x11b0,
- 0x2011, 0x180c, 0x2214, 0xd29c, 0x1120, 0x6204, 0x9295, 0x0002,
- 0x6206, 0x6228, 0xc29d, 0x622a, 0x2003, 0x0001, 0x2001, 0x1826,
- 0x2003, 0x0000, 0x2011, 0x0020, 0x080c, 0x2af5, 0xd194, 0x0904,
- 0x25a1, 0x0016, 0x080c, 0xaae0, 0x6220, 0xd2b4, 0x0904, 0x253c,
- 0x080c, 0x88ec, 0x080c, 0xa08a, 0x2011, 0x0004, 0x080c, 0x2af5,
- 0x00f6, 0x2019, 0x19f5, 0x2304, 0x907d, 0x0904, 0x2509, 0x7804,
- 0x9086, 0x0032, 0x15f0, 0x00d6, 0x00c6, 0x00e6, 0x0096, 0x2069,
- 0x0140, 0x782c, 0x685e, 0x7808, 0x685a, 0x6043, 0x0002, 0x2001,
- 0x0003, 0x8001, 0x1df0, 0x6043, 0x0000, 0x2001, 0x003c, 0x8001,
- 0x1df0, 0x080c, 0x2acb, 0x2001, 0x001e, 0x8001, 0x0240, 0x20a9,
- 0x0009, 0x080c, 0x2a82, 0x6904, 0xd1dc, 0x1140, 0x0cb0, 0x2001,
- 0x0100, 0x080c, 0x2abb, 0x9006, 0x080c, 0x2abb, 0x080c, 0x97fe,
- 0x080c, 0xaafc, 0x7814, 0x2048, 0xa867, 0x0103, 0x2f60, 0x080c,
- 0xaf2e, 0x009e, 0x00ee, 0x00ce, 0x00de, 0x00fe, 0x001e, 0x00ae,
- 0x0005, 0x00fe, 0x00d6, 0x2069, 0x0140, 0x6804, 0x9084, 0x4000,
- 0x0110, 0x080c, 0x2acb, 0x00de, 0x00c6, 0x2061, 0x19e9, 0x6034,
- 0x080c, 0xd33e, 0x0120, 0x909a, 0x0003, 0x1258, 0x0018, 0x909a,
- 0x00c8, 0x1238, 0x8000, 0x6036, 0x00ce, 0x080c, 0xa062, 0x0804,
- 0x259e, 0x2061, 0x0100, 0x62c0, 0x080c, 0xaa11, 0x2019, 0x19f5,
- 0x2304, 0x9065, 0x0130, 0x6003, 0x0001, 0x2009, 0x0027, 0x080c,
- 0xafcc, 0x00ce, 0x0804, 0x259e, 0xd2bc, 0x0904, 0x2581, 0x080c,
- 0x88f9, 0x2011, 0x0004, 0x080c, 0x2af5, 0x00d6, 0x2069, 0x0140,
- 0x6804, 0x9084, 0x4000, 0x0110, 0x080c, 0x2acb, 0x00de, 0x00c6,
- 0x2061, 0x19e9, 0x6050, 0x080c, 0xd33e, 0x0120, 0x909a, 0x0003,
- 0x1668, 0x0018, 0x909a, 0x00c8, 0x1648, 0x8000, 0x6052, 0x604c,
- 0x00ce, 0x9005, 0x05d8, 0x2009, 0x07d0, 0x080c, 0x88f1, 0x9080,
- 0x0008, 0x2004, 0x9086, 0x0006, 0x1138, 0x2009, 0x1984, 0x2011,
- 0x0012, 0x080c, 0x2b04, 0x0450, 0x9080, 0x0008, 0x2004, 0x9086,
- 0x0009, 0x0d98, 0x2009, 0x1984, 0x2011, 0x0016, 0x080c, 0x2b04,
- 0x00e8, 0x2011, 0x0004, 0x080c, 0x2af5, 0x00c0, 0x0036, 0x2019,
- 0x0001, 0x080c, 0xa380, 0x003e, 0x2019, 0x19fc, 0x2304, 0x9065,
- 0x0160, 0x2009, 0x004f, 0x6020, 0x9086, 0x0009, 0x1110, 0x2009,
- 0x004f, 0x6003, 0x0003, 0x080c, 0xafcc, 0x00ce, 0x080c, 0xaafc,
- 0x001e, 0xd19c, 0x0904, 0x2605, 0x7038, 0xd0ac, 0x1558, 0x0016,
- 0x0156, 0x2011, 0x0008, 0x080c, 0x2af5, 0x080c, 0x2b18, 0x080c,
- 0x2b4b, 0x6050, 0xc0e5, 0x6052, 0x20a9, 0x0367, 0x1f04, 0x25d0,
- 0x1d04, 0x25b8, 0x080c, 0x8920, 0x6020, 0xd09c, 0x1db8, 0x00f6,
- 0x2079, 0x0100, 0x080c, 0x2a2e, 0x00fe, 0x1d80, 0x6050, 0xc0e4,
- 0x6052, 0x2011, 0x0008, 0x080c, 0x2af5, 0x015e, 0x001e, 0x04a8,
- 0x015e, 0x001e, 0x0016, 0x6028, 0xc09c, 0x602a, 0x080c, 0xaae0,
- 0x080c, 0xad9e, 0x080c, 0xae67, 0x080c, 0xaafc, 0x60e3, 0x0000,
- 0x080c, 0xeb7d, 0x080c, 0xeb98, 0x080c, 0x582a, 0xd0fc, 0x1138,
- 0x080c, 0xd337, 0x1120, 0x9085, 0x0001, 0x080c, 0x76e9, 0x9006,
- 0x080c, 0x2abb, 0x2009, 0x0002, 0x080c, 0x2aa7, 0x00e6, 0x2071,
- 0x1800, 0x7003, 0x0004, 0x080c, 0x0ed3, 0x00ee, 0x2011, 0x0008,
- 0x080c, 0x2af5, 0x080c, 0x0bc3, 0x001e, 0x918c, 0xffd0, 0x2110,
- 0x080c, 0x2af5, 0x00ae, 0x0005, 0x0016, 0x2001, 0x0387, 0x200c,
- 0xd1a4, 0x001e, 0x0904, 0x23a9, 0x0016, 0x2009, 0x2618, 0x00c0,
- 0x2001, 0x0387, 0x2003, 0x1000, 0x001e, 0x0c38, 0x0016, 0x2001,
- 0x0387, 0x200c, 0xd1b4, 0x001e, 0x0904, 0x23a9, 0x0016, 0x2009,
- 0x262a, 0x0030, 0x2001, 0x0387, 0x2003, 0x4000, 0x001e, 0x08a8,
- 0x6028, 0xc0bc, 0x602a, 0x2001, 0x0156, 0x2003, 0xbc91, 0x8000,
- 0x2003, 0xffff, 0x6043, 0x0001, 0x080c, 0x2aa1, 0x2011, 0x0080,
- 0x080c, 0x2af5, 0x6017, 0x0000, 0x6043, 0x0000, 0x0817, 0x0006,
- 0x0016, 0x0026, 0x0036, 0x00e6, 0x00f6, 0x0126, 0x2091, 0x8000,
- 0x2071, 0x1800, 0x71d0, 0x70d2, 0x9116, 0x0904, 0x269a, 0x81ff,
- 0x01a0, 0x2009, 0x0000, 0x080c, 0x2aa7, 0x2011, 0x8011, 0x2019,
- 0x010e, 0x231c, 0x939e, 0x0007, 0x1118, 0x2019, 0x0001, 0x0010,
- 0x2019, 0x0000, 0x080c, 0x4c2e, 0x0468, 0x2001, 0x19a9, 0x200c,
- 0x81ff, 0x1140, 0x2001, 0x0109, 0x2004, 0xd0b4, 0x0118, 0x2019,
- 0x0003, 0x0008, 0x2118, 0x2011, 0x8012, 0x080c, 0x4c2e, 0x080c,
- 0x0ed3, 0x080c, 0x582a, 0xd0fc, 0x11a8, 0x080c, 0xd337, 0x1190,
- 0x00c6, 0x080c, 0x2736, 0x080c, 0xaae0, 0x080c, 0xa2db, 0x080c,
- 0xaafc, 0x2061, 0x0100, 0x2019, 0x0028, 0x2009, 0x0002, 0x080c,
- 0x32d5, 0x00ce, 0x012e, 0x00fe, 0x00ee, 0x003e, 0x002e, 0x001e,
- 0x000e, 0x0005, 0x2028, 0x918c, 0x00ff, 0x2130, 0x9094, 0xff00,
- 0x11f0, 0x2011, 0x1837, 0x2214, 0xd2ac, 0x11c8, 0x81ff, 0x01e8,
- 0x2011, 0x181f, 0x2204, 0x9106, 0x1190, 0x2011, 0x1820, 0x2214,
- 0x9294, 0xff00, 0x9584, 0xff00, 0x9206, 0x1148, 0x2011, 0x1820,
- 0x2214, 0x9294, 0x00ff, 0x9584, 0x00ff, 0x9206, 0x1120, 0x2500,
- 0x080c, 0x83c2, 0x0048, 0x9584, 0x00ff, 0x9080, 0x3489, 0x200d,
- 0x918c, 0xff00, 0x810f, 0x9006, 0x0005, 0x9080, 0x3489, 0x200d,
- 0x918c, 0x00ff, 0x0005, 0x00d6, 0x2069, 0x0140, 0x2001, 0x1818,
- 0x2003, 0x00ef, 0x20a9, 0x0010, 0x9006, 0x6852, 0x6856, 0x1f04,
- 0x26e6, 0x00de, 0x0005, 0x0006, 0x00d6, 0x0026, 0x2069, 0x0140,
- 0x2001, 0x1818, 0x2102, 0x8114, 0x8214, 0x8214, 0x8214, 0x20a9,
- 0x0010, 0x6853, 0x0000, 0x9006, 0x82ff, 0x1128, 0x9184, 0x000f,
- 0x9080, 0xebac, 0x2005, 0x6856, 0x8211, 0x1f04, 0x26fb, 0x002e,
- 0x00de, 0x000e, 0x0005, 0x00c6, 0x2061, 0x1800, 0x6030, 0x0110,
- 0xc09d, 0x0008, 0xc09c, 0x6032, 0x00ce, 0x0005, 0x0156, 0x00d6,
- 0x0026, 0x0016, 0x0006, 0x2069, 0x0140, 0x6980, 0x9116, 0x0180,
- 0x9112, 0x1230, 0x8212, 0x8210, 0x22a8, 0x2001, 0x0402, 0x0018,
- 0x22a8, 0x2001, 0x0404, 0x680e, 0x1f04, 0x272b, 0x680f, 0x0000,
- 0x000e, 0x001e, 0x002e, 0x00de, 0x015e, 0x0005, 0x080c, 0x5826,
- 0xd0c4, 0x0150, 0xd0a4, 0x0140, 0x9006, 0x0046, 0x2020, 0x2009,
- 0x002e, 0x080c, 0xe72a, 0x004e, 0x0005, 0x00f6, 0x0016, 0x0026,
- 0x2079, 0x0140, 0x78c4, 0xd0dc, 0x0904, 0x27a2, 0x080c, 0x2a1e,
- 0x0660, 0x9084, 0x0700, 0x908e, 0x0600, 0x1120, 0x2011, 0x4000,
- 0x900e, 0x0458, 0x908e, 0x0500, 0x1120, 0x2011, 0x8000, 0x900e,
- 0x0420, 0x908e, 0x0400, 0x1120, 0x9016, 0x2009, 0x0001, 0x00e8,
- 0x908e, 0x0300, 0x1120, 0x9016, 0x2009, 0x0002, 0x00b0, 0x908e,
- 0x0200, 0x1120, 0x9016, 0x2009, 0x0004, 0x0078, 0x908e, 0x0100,
- 0x1548, 0x9016, 0x2009, 0x0008, 0x0040, 0x9084, 0x0700, 0x908e,
- 0x0300, 0x1500, 0x2011, 0x0030, 0x0058, 0x2300, 0x9080, 0x0020,
- 0x2018, 0x080c, 0x936c, 0x928c, 0xff00, 0x0110, 0x2011, 0x00ff,
- 0x2200, 0x8007, 0x9085, 0x004c, 0x78c2, 0x2009, 0x0138, 0x220a,
- 0x080c, 0x76a5, 0x1118, 0x2009, 0x196e, 0x220a, 0x002e, 0x001e,
- 0x00fe, 0x0005, 0x78c3, 0x0000, 0x0cc8, 0x0126, 0x2091, 0x2800,
- 0x0006, 0x0016, 0x0026, 0x2001, 0x0170, 0x200c, 0x8000, 0x2014,
- 0x9184, 0x0003, 0x0110, 0x080c, 0x0d7e, 0x002e, 0x001e, 0x000e,
- 0x012e, 0x0005, 0x2001, 0x0171, 0x2004, 0xd0dc, 0x0168, 0x2001,
- 0x0170, 0x200c, 0x918c, 0x00ff, 0x918e, 0x004c, 0x1128, 0x200c,
- 0x918c, 0xff00, 0x810f, 0x0005, 0x900e, 0x2001, 0x0227, 0x2004,
- 0x8007, 0x9084, 0x00ff, 0x8004, 0x9108, 0x2001, 0x0226, 0x2004,
- 0x8007, 0x9084, 0x00ff, 0x8004, 0x9108, 0x0005, 0x0018, 0x000c,
- 0x0018, 0x0020, 0x1000, 0x0800, 0x1000, 0x1800, 0x0156, 0x0006,
- 0x0016, 0x0026, 0x00e6, 0x2001, 0x1991, 0x2004, 0x908a, 0x0007,
- 0x1a0c, 0x0d85, 0x0033, 0x00ee, 0x002e, 0x001e, 0x000e, 0x015e,
- 0x0005, 0x2800, 0x281e, 0x2842, 0x2844, 0x286d, 0x286f, 0x2871,
- 0x2001, 0x0001, 0x080c, 0x2647, 0x080c, 0x2a6c, 0x2001, 0x1993,
- 0x2003, 0x0000, 0x7828, 0x9084, 0xe1d7, 0x782a, 0x9006, 0x20a9,
- 0x0009, 0x080c, 0x2a3a, 0x2001, 0x1991, 0x2003, 0x0006, 0x2009,
- 0x001e, 0x2011, 0x2872, 0x080c, 0x88fe, 0x0005, 0x2009, 0x1996,
- 0x200b, 0x0000, 0x2001, 0x199b, 0x2003, 0x0036, 0x2001, 0x199a,
- 0x2003, 0x002a, 0x2001, 0x1993, 0x2003, 0x0001, 0x9006, 0x080c,
- 0x29cf, 0x2001, 0xffff, 0x20a9, 0x0009, 0x080c, 0x2a3a, 0x2001,
- 0x1991, 0x2003, 0x0006, 0x2009, 0x001e, 0x2011, 0x2872, 0x080c,
- 0x88fe, 0x0005, 0x080c, 0x0d85, 0x2001, 0x199b, 0x2003, 0x0036,
- 0x2001, 0x1993, 0x2003, 0x0003, 0x7a38, 0x9294, 0x0005, 0x9296,
- 0x0004, 0x0110, 0x9006, 0x0010, 0x2001, 0x0001, 0x080c, 0x29cf,
- 0x2001, 0x1997, 0x2003, 0x0000, 0x2001, 0xffff, 0x20a9, 0x0009,
- 0x080c, 0x2a3a, 0x2001, 0x1991, 0x2003, 0x0006, 0x2009, 0x001e,
- 0x2011, 0x2872, 0x080c, 0x88fe, 0x0005, 0x080c, 0x0d85, 0x080c,
- 0x0d85, 0x0005, 0x0006, 0x0016, 0x0026, 0x00e6, 0x00f6, 0x0156,
- 0x0126, 0x2091, 0x8000, 0x2079, 0x0100, 0x2001, 0x1993, 0x2004,
- 0x908a, 0x0007, 0x1a0c, 0x0d85, 0x0043, 0x012e, 0x015e, 0x00fe,
- 0x00ee, 0x002e, 0x001e, 0x000e, 0x0005, 0x2894, 0x28b4, 0x28f4,
- 0x2924, 0x2948, 0x2958, 0x295a, 0x080c, 0x2a2e, 0x11b0, 0x7850,
- 0x9084, 0xefff, 0x7852, 0x2009, 0x1999, 0x2104, 0x7a38, 0x9294,
- 0x0005, 0x9296, 0x0004, 0x0110, 0xc08d, 0x0008, 0xc085, 0x200a,
- 0x2001, 0x1991, 0x2003, 0x0001, 0x0030, 0x080c, 0x297e, 0x2001,
- 0xffff, 0x080c, 0x280f, 0x0005, 0x080c, 0x295c, 0x05e0, 0x2009,
- 0x199a, 0x2104, 0x8001, 0x200a, 0x080c, 0x2a2e, 0x1178, 0x7850,
- 0x9084, 0xefff, 0x7852, 0x7a38, 0x9294, 0x0005, 0x9296, 0x0005,
- 0x0518, 0x2009, 0x1999, 0x2104, 0xc085, 0x200a, 0x2009, 0x1996,
- 0x2104, 0x8000, 0x200a, 0x9086, 0x0005, 0x0118, 0x080c, 0x2964,
- 0x00c0, 0x200b, 0x0000, 0x7a38, 0x9294, 0x0006, 0x9296, 0x0004,
- 0x0110, 0x9006, 0x0010, 0x2001, 0x0001, 0x080c, 0x29ec, 0x2001,
- 0x1993, 0x2003, 0x0002, 0x0028, 0x2001, 0x1991, 0x2003, 0x0003,
- 0x0010, 0x080c, 0x2831, 0x0005, 0x080c, 0x295c, 0x0560, 0x2009,
- 0x199a, 0x2104, 0x8001, 0x200a, 0x080c, 0x2a2e, 0x1168, 0x7850,
- 0x9084, 0xefff, 0x7852, 0x2001, 0x1991, 0x2003, 0x0003, 0x2001,
- 0x1992, 0x2003, 0x0000, 0x00b8, 0x2009, 0x199a, 0x2104, 0x9005,
- 0x1118, 0x080c, 0x29a1, 0x0010, 0x080c, 0x2971, 0x080c, 0x2964,
- 0x2009, 0x1996, 0x200b, 0x0000, 0x2001, 0x1993, 0x2003, 0x0001,
- 0x080c, 0x2831, 0x0000, 0x0005, 0x04b9, 0x0508, 0x080c, 0x2a2e,
- 0x11b8, 0x7850, 0x9084, 0xefff, 0x7852, 0x2009, 0x1997, 0x2104,
- 0x8000, 0x200a, 0x9086, 0x0007, 0x0108, 0x0078, 0x2001, 0x199c,
- 0x2003, 0x000a, 0x2009, 0x1999, 0x2104, 0xc0fd, 0x200a, 0x0038,
- 0x0419, 0x2001, 0x1993, 0x2003, 0x0004, 0x080c, 0x285c, 0x0005,
- 0x0099, 0x0168, 0x080c, 0x2a2e, 0x1138, 0x7850, 0x9084, 0xefff,
- 0x7852, 0x080c, 0x2848, 0x0018, 0x0079, 0x080c, 0x285c, 0x0005,
- 0x080c, 0x0d85, 0x080c, 0x0d85, 0x2009, 0x199b, 0x2104, 0x8001,
- 0x200a, 0x090c, 0x29bd, 0x0005, 0x7a38, 0x9294, 0x0005, 0x9296,
- 0x0005, 0x0110, 0x9006, 0x0010, 0x2001, 0x0001, 0x080c, 0x29ec,
- 0x0005, 0x7a38, 0x9294, 0x0006, 0x9296, 0x0006, 0x0110, 0x9006,
- 0x0010, 0x2001, 0x0001, 0x080c, 0x29cf, 0x0005, 0x2009, 0x1996,
- 0x2104, 0x8000, 0x200a, 0x9086, 0x0005, 0x0108, 0x0068, 0x200b,
- 0x0000, 0x7a38, 0x9294, 0x0006, 0x9296, 0x0006, 0x0110, 0x9006,
- 0x0010, 0x2001, 0x0001, 0x04d9, 0x7a38, 0x9294, 0x0005, 0x9296,
- 0x0005, 0x0110, 0x9006, 0x0010, 0x2001, 0x0001, 0x080c, 0x29ec,
- 0x0005, 0x0086, 0x2001, 0x1999, 0x2004, 0x9084, 0x7fff, 0x090c,
- 0x0d85, 0x2009, 0x1998, 0x2144, 0x8846, 0x280a, 0x9844, 0x0dd8,
- 0xd08c, 0x1120, 0xd084, 0x1120, 0x080c, 0x0d85, 0x9006, 0x0010,
- 0x2001, 0x0001, 0x00a1, 0x008e, 0x0005, 0x0006, 0x0156, 0x2001,
- 0x1991, 0x20a9, 0x0009, 0x2003, 0x0000, 0x8000, 0x1f04, 0x29c3,
- 0x2001, 0x1998, 0x2003, 0x8000, 0x015e, 0x000e, 0x0005, 0x00f6,
- 0x2079, 0x0100, 0x9085, 0x0000, 0x0158, 0x7838, 0x9084, 0xfff9,
- 0x9085, 0x0004, 0x783a, 0x2009, 0x199e, 0x210c, 0x795a, 0x0050,
- 0x7838, 0x9084, 0xfffb, 0x9085, 0x0006, 0x783a, 0x2009, 0x199f,
- 0x210c, 0x795a, 0x00fe, 0x0005, 0x00f6, 0x2079, 0x0100, 0x9085,
- 0x0000, 0x0158, 0x7838, 0x9084, 0xfffa, 0x9085, 0x0004, 0x783a,
- 0x7850, 0x9084, 0xfff0, 0x7852, 0x00f8, 0x7838, 0x9084, 0xfffb,
- 0x9085, 0x0005, 0x783a, 0x7850, 0x9084, 0xfff0, 0x0016, 0x2009,
- 0x017f, 0x210c, 0x918e, 0x0005, 0x0140, 0x2009, 0x0003, 0x210c,
- 0x918c, 0x0600, 0x918e, 0x0400, 0x0118, 0x9085, 0x000a, 0x0010,
- 0x9085, 0x0000, 0x001e, 0x7852, 0x00fe, 0x0005, 0x0006, 0x2001,
- 0x0100, 0x2004, 0x9082, 0x0007, 0x000e, 0x0005, 0x0006, 0x2001,
- 0x0100, 0x2004, 0x9082, 0x0009, 0x000e, 0x0005, 0x0156, 0x20a9,
- 0x0064, 0x7820, 0x080c, 0x2aa1, 0xd09c, 0x1110, 0x1f04, 0x2a31,
- 0x015e, 0x0005, 0x0126, 0x0016, 0x0006, 0x2091, 0x8000, 0x080c,
- 0x2b18, 0x080c, 0x2b4b, 0x000e, 0x2008, 0x9186, 0x0000, 0x1118,
- 0x783b, 0x0007, 0x0090, 0x9186, 0x0001, 0x1118, 0x783b, 0x0006,
- 0x0060, 0x9186, 0x0002, 0x1118, 0x783b, 0x0005, 0x0030, 0x9186,
- 0x0003, 0x1118, 0x783b, 0x0004, 0x0000, 0x0006, 0x1d04, 0x2a5e,
- 0x080c, 0x8920, 0x1f04, 0x2a5e, 0x7850, 0x9085, 0x1000, 0x7852,
- 0x000e, 0x001e, 0x012e, 0x0005, 0x080c, 0x2b4b, 0x0005, 0x0006,
- 0x0156, 0x00f6, 0x2079, 0x0100, 0x20a9, 0x000a, 0x7854, 0xd0ac,
- 0x1100, 0x7854, 0xd08c, 0x1110, 0x1f04, 0x2a79, 0x00fe, 0x015e,
- 0x000e, 0x0005, 0x1d04, 0x2a82, 0x080c, 0x8920, 0x1f04, 0x2a82,
- 0x0005, 0x0006, 0x2001, 0x199d, 0x2004, 0x9086, 0x0000, 0x000e,
- 0x0005, 0x0006, 0x2001, 0x199d, 0x2004, 0x9086, 0x0001, 0x000e,
- 0x0005, 0x0006, 0x2001, 0x199d, 0x2004, 0x9086, 0x0002, 0x000e,
- 0x0005, 0xa001, 0xa001, 0xa001, 0xa001, 0xa001, 0x0005, 0x0006,
- 0x2001, 0x19a9, 0x2102, 0x000e, 0x0005, 0x2009, 0x0171, 0x2104,
- 0xd0dc, 0x0140, 0x2009, 0x0170, 0x2104, 0x200b, 0x0080, 0xa001,
- 0xa001, 0x200a, 0x0005, 0x0016, 0x0026, 0x080c, 0x76bf, 0x0108,
- 0xc0bc, 0x2009, 0x0140, 0x2114, 0x9294, 0x0001, 0x9215, 0x220a,
- 0x002e, 0x001e, 0x0005, 0x0016, 0x0026, 0x2009, 0x0140, 0x2114,
- 0x9294, 0x0001, 0x9285, 0x1000, 0x200a, 0x220a, 0x002e, 0x001e,
- 0x0005, 0x0016, 0x0026, 0x2009, 0x0140, 0x2114, 0x9294, 0x0001,
- 0x9215, 0x220a, 0x002e, 0x001e, 0x0005, 0x0006, 0x0016, 0x2009,
- 0x0140, 0x2104, 0x1128, 0x080c, 0x76bf, 0x0110, 0xc0bc, 0x0008,
- 0xc0bd, 0x200a, 0x001e, 0x000e, 0x0005, 0x00f6, 0x2079, 0x0380,
- 0x7843, 0x0101, 0x7844, 0xd084, 0x1de8, 0x2001, 0x0109, 0x2202,
- 0x7843, 0x0100, 0x00fe, 0x0005, 0x00f6, 0x2079, 0x0380, 0x7843,
- 0x0202, 0x7844, 0xd08c, 0x1de8, 0x2079, 0x0100, 0x7814, 0x9104,
- 0x9205, 0x7a16, 0x2079, 0x0380, 0x7843, 0x0200, 0x00fe, 0x0005,
- 0x0016, 0x0026, 0x0036, 0x00c6, 0x2061, 0x0100, 0x6050, 0x9084,
- 0xfbff, 0x9085, 0x0040, 0x6052, 0x20a9, 0x0002, 0x080c, 0x2a82,
- 0x6050, 0x9085, 0x0400, 0x9084, 0xff9f, 0x6052, 0x20a9, 0x0005,
- 0x080c, 0x2a82, 0x6054, 0xd0bc, 0x090c, 0x0d85, 0x20a9, 0x0005,
- 0x080c, 0x2a82, 0x6054, 0xd0ac, 0x090c, 0x0d85, 0x2009, 0x19b0,
- 0x9084, 0x7e00, 0x8007, 0x8004, 0x8004, 0x200a, 0x00ce, 0x003e,
- 0x002e, 0x001e, 0x0005, 0x0006, 0x00c6, 0x2061, 0x0100, 0x6050,
- 0xc0cd, 0x6052, 0x00ce, 0x000e, 0x0005, 0x0016, 0x00c6, 0x00d6,
- 0x0006, 0x2061, 0x0100, 0x2069, 0x0140, 0x6030, 0x0006, 0x6048,
- 0x0006, 0x60e4, 0x0006, 0x60e8, 0x0006, 0x6050, 0x0006, 0x60ec,
- 0x0006, 0x600c, 0x0006, 0x6004, 0x0006, 0xc0fc, 0x6006, 0x2009,
- 0x0800, 0x2001, 0x0338, 0x2003, 0x0301, 0x8109, 0x090c, 0x0d85,
- 0x2001, 0x0338, 0x2004, 0xd084, 0x1dc0, 0x6028, 0x0006, 0x60e0,
- 0x0006, 0x6888, 0x0006, 0x688c, 0x0006, 0x6890, 0x0006, 0x080c,
- 0x76a5, 0x1110, 0x6884, 0x0006, 0x602f, 0x0100, 0x602f, 0x0000,
- 0xa001, 0xa001, 0xa001, 0xa001, 0x602f, 0x0040, 0x602f, 0x0000,
- 0x080c, 0x76a5, 0x1120, 0x6803, 0x0080, 0x000e, 0x6886, 0x6897,
- 0x4198, 0x000e, 0x6892, 0x000e, 0x688e, 0x000e, 0x688a, 0x000e,
- 0x60e2, 0x000e, 0x602a, 0x000e, 0x6006, 0x000e, 0x600e, 0x000e,
- 0x60ee, 0x000e, 0x6052, 0x000e, 0x60ea, 0x000e, 0x60e6, 0x000e,
- 0x604a, 0x000e, 0x6032, 0x6036, 0x2008, 0x080c, 0x26eb, 0x000e,
- 0x00de, 0x00ce, 0x001e, 0x0005, 0x0006, 0x0156, 0x6050, 0x9085,
- 0x0040, 0x6052, 0x6050, 0x9084, 0xfbcf, 0x6052, 0x080c, 0x2aa1,
- 0x9085, 0x2000, 0x6052, 0x20a9, 0x0012, 0x1d04, 0x2bd5, 0x080c,
- 0x8920, 0x1f04, 0x2bd5, 0x6050, 0x9085, 0x0400, 0x9084, 0xdfbf,
- 0x6052, 0x015e, 0x000e, 0x0005, 0x30e0, 0x30e0, 0x2ce4, 0x2ce4,
- 0x2cf0, 0x2cf0, 0x2cfc, 0x2cfc, 0x2d0a, 0x2d0a, 0x2d16, 0x2d16,
- 0x2d24, 0x2d24, 0x2d32, 0x2d32, 0x2d44, 0x2d44, 0x2d50, 0x2d50,
- 0x2d5e, 0x2d5e, 0x2d7c, 0x2d7c, 0x2d9c, 0x2d9c, 0x2d6c, 0x2d6c,
- 0x2d8c, 0x2d8c, 0x2daa, 0x2daa, 0x2d42, 0x2d42, 0x2d42, 0x2d42,
- 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42,
- 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42,
- 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42,
- 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2dbc, 0x2dbc, 0x2dc8, 0x2dc8,
- 0x2dd6, 0x2dd6, 0x2de4, 0x2de4, 0x2df4, 0x2df4, 0x2e02, 0x2e02,
- 0x2e12, 0x2e12, 0x2e22, 0x2e22, 0x2e34, 0x2e34, 0x2e42, 0x2e42,
- 0x2e52, 0x2e52, 0x2e74, 0x2e74, 0x2e98, 0x2e98, 0x2e62, 0x2e62,
- 0x2e86, 0x2e86, 0x2ea8, 0x2ea8, 0x2d42, 0x2d42, 0x2d42, 0x2d42,
- 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42,
- 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42,
- 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42,
- 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2ebc, 0x2ebc, 0x2ec8, 0x2ec8,
- 0x2ed6, 0x2ed6, 0x2ee4, 0x2ee4, 0x2ef4, 0x2ef4, 0x2f02, 0x2f02,
- 0x2f12, 0x2f12, 0x2f22, 0x2f22, 0x2f34, 0x2f34, 0x2f42, 0x2f42,
- 0x2f52, 0x2f52, 0x2f62, 0x2f62, 0x2f74, 0x2f74, 0x2f84, 0x2f84,
- 0x2f96, 0x2f96, 0x2fa8, 0x2fa8, 0x2d42, 0x2d42, 0x2d42, 0x2d42,
- 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42,
- 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42,
- 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42,
- 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2fbc, 0x2fbc, 0x2fca, 0x2fca,
- 0x2fda, 0x2fda, 0x2fea, 0x2fea, 0x2ffc, 0x2ffc, 0x300c, 0x300c,
- 0x301e, 0x301e, 0x3030, 0x3030, 0x3044, 0x3044, 0x3054, 0x3054,
- 0x3066, 0x3066, 0x3078, 0x3078, 0x308c, 0x308c, 0x309d, 0x309d,
- 0x30b0, 0x30b0, 0x30c3, 0x30c3, 0x2d42, 0x2d42, 0x2d42, 0x2d42,
- 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42,
- 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42,
- 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42,
- 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x0106, 0x0006, 0x0126, 0x01c6,
- 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x22e1, 0x0804, 0x30d8,
- 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156,
- 0x080c, 0x210b, 0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6,
- 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x210b, 0x080c, 0x22e1,
- 0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136,
- 0x0146, 0x0156, 0x080c, 0x2135, 0x0804, 0x30d8, 0x0106, 0x0006,
- 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x22e1,
- 0x080c, 0x2135, 0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6,
- 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x210b, 0x080c, 0x2135,
- 0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136,
- 0x0146, 0x0156, 0x080c, 0x210b, 0x080c, 0x22e1, 0x080c, 0x2135,
- 0x0804, 0x30d8, 0xa001, 0x0cf0, 0x0106, 0x0006, 0x0126, 0x01c6,
- 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x13d4, 0x0804, 0x30d8,
- 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156,
- 0x080c, 0x22e1, 0x080c, 0x13d4, 0x0804, 0x30d8, 0x0106, 0x0006,
- 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x210b,
- 0x080c, 0x13d4, 0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6,
- 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x22e1, 0x080c, 0x13d4,
- 0x080c, 0x2135, 0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6,
- 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x210b, 0x080c, 0x22e1,
- 0x080c, 0x13d4, 0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6,
- 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x210b, 0x080c, 0x13d4,
- 0x080c, 0x2135, 0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6,
- 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x13d4, 0x080c, 0x2135,
- 0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136,
- 0x0146, 0x0156, 0x080c, 0x210b, 0x080c, 0x22e1, 0x080c, 0x13d4,
- 0x080c, 0x2135, 0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6,
- 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x27a5, 0x0804, 0x30d8,
- 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156,
- 0x080c, 0x27a5, 0x080c, 0x22e1, 0x0804, 0x30d8, 0x0106, 0x0006,
- 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x27a5,
- 0x080c, 0x210b, 0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6,
- 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x27a5, 0x080c, 0x210b,
- 0x080c, 0x22e1, 0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6,
- 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x27a5, 0x080c, 0x2135,
- 0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136,
- 0x0146, 0x0156, 0x080c, 0x27a5, 0x080c, 0x22e1, 0x080c, 0x2135,
- 0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136,
- 0x0146, 0x0156, 0x080c, 0x27a5, 0x080c, 0x210b, 0x080c, 0x2135,
- 0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136,
- 0x0146, 0x0156, 0x080c, 0x27a5, 0x080c, 0x210b, 0x080c, 0x22e1,
- 0x080c, 0x2135, 0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6,
- 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x27a5, 0x080c, 0x13d4,
- 0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136,
- 0x0146, 0x0156, 0x080c, 0x27a5, 0x080c, 0x22e1, 0x080c, 0x13d4,
- 0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136,
- 0x0146, 0x0156, 0x080c, 0x27a5, 0x080c, 0x210b, 0x080c, 0x13d4,
- 0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136,
- 0x0146, 0x0156, 0x080c, 0x27a5, 0x080c, 0x22e1, 0x080c, 0x13d4,
- 0x080c, 0x2135, 0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6,
- 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x27a5, 0x080c, 0x210b,
- 0x080c, 0x22e1, 0x080c, 0x13d4, 0x0804, 0x30d8, 0x0106, 0x0006,
- 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x27a5,
- 0x080c, 0x210b, 0x080c, 0x13d4, 0x080c, 0x2135, 0x0804, 0x30d8,
- 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156,
- 0x080c, 0x27a5, 0x080c, 0x13d4, 0x080c, 0x2135, 0x0804, 0x30d8,
- 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156,
- 0x080c, 0x27a5, 0x080c, 0x210b, 0x080c, 0x22e1, 0x080c, 0x13d4,
- 0x080c, 0x2135, 0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6,
- 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0xab46, 0x0804, 0x30d8,
- 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156,
- 0x080c, 0xab46, 0x080c, 0x22e1, 0x0804, 0x30d8, 0x0106, 0x0006,
- 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x210b,
- 0x080c, 0xab46, 0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6,
- 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x210b, 0x080c, 0xab46,
- 0x080c, 0x22e1, 0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6,
- 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0xab46, 0x080c, 0x2135,
- 0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136,
- 0x0146, 0x0156, 0x080c, 0xab46, 0x080c, 0x22e1, 0x080c, 0x2135,
- 0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136,
- 0x0146, 0x0156, 0x080c, 0x210b, 0x080c, 0xab46, 0x080c, 0x2135,
- 0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136,
- 0x0146, 0x0156, 0x080c, 0x210b, 0x080c, 0xab46, 0x080c, 0x22e1,
- 0x080c, 0x2135, 0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6,
- 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0xab46, 0x080c, 0x13d4,
- 0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136,
- 0x0146, 0x0156, 0x080c, 0xab46, 0x080c, 0x22e1, 0x080c, 0x13d4,
- 0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136,
- 0x0146, 0x0156, 0x080c, 0x210b, 0x080c, 0xab46, 0x080c, 0x13d4,
- 0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136,
- 0x0146, 0x0156, 0x080c, 0x210b, 0x080c, 0xab46, 0x080c, 0x22e1,
- 0x080c, 0x13d4, 0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6,
- 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0xab46, 0x080c, 0x13d4,
- 0x080c, 0x2135, 0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6,
- 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0xab46, 0x080c, 0x22e1,
- 0x080c, 0x13d4, 0x080c, 0x2135, 0x0804, 0x30d8, 0x0106, 0x0006,
- 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x210b,
- 0x080c, 0xab46, 0x080c, 0x13d4, 0x080c, 0x2135, 0x0804, 0x30d8,
- 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156,
- 0x080c, 0x210b, 0x080c, 0xab46, 0x080c, 0x22e1, 0x080c, 0x13d4,
- 0x080c, 0x2135, 0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6,
- 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x27a5, 0x080c, 0xab46,
- 0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136,
- 0x0146, 0x0156, 0x080c, 0x27a5, 0x080c, 0xab46, 0x080c, 0x22e1,
- 0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136,
- 0x0146, 0x0156, 0x080c, 0x27a5, 0x080c, 0x210b, 0x080c, 0xab46,
- 0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136,
- 0x0146, 0x0156, 0x080c, 0x27a5, 0x080c, 0x210b, 0x080c, 0xab46,
- 0x080c, 0x22e1, 0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6,
- 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x27a5, 0x080c, 0xab46,
- 0x080c, 0x2135, 0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6,
- 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x27a5, 0x080c, 0xab46,
- 0x080c, 0x22e1, 0x080c, 0x2135, 0x0804, 0x30d8, 0x0106, 0x0006,
- 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x27a5,
- 0x080c, 0x210b, 0x080c, 0xab46, 0x080c, 0x2135, 0x0804, 0x30d8,
- 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156,
- 0x080c, 0x27a5, 0x080c, 0x210b, 0x080c, 0xab46, 0x080c, 0x22e1,
- 0x080c, 0x2135, 0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6,
- 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x27a5, 0x080c, 0xab46,
- 0x080c, 0x13d4, 0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6,
- 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x27a5, 0x080c, 0xab46,
- 0x080c, 0x22e1, 0x080c, 0x13d4, 0x0804, 0x30d8, 0x0106, 0x0006,
- 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x27a5,
- 0x080c, 0x210b, 0x080c, 0xab46, 0x080c, 0x13d4, 0x0804, 0x30d8,
- 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156,
- 0x080c, 0x27a5, 0x080c, 0x210b, 0x080c, 0xab46, 0x080c, 0x22e1,
- 0x080c, 0x13d4, 0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6,
- 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x27a5, 0x080c, 0xab46,
- 0x080c, 0x13d4, 0x080c, 0x2135, 0x04d8, 0x0106, 0x0006, 0x0126,
- 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x27a5, 0x080c,
- 0xab46, 0x080c, 0x22e1, 0x080c, 0x13d4, 0x080c, 0x2135, 0x0440,
- 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156,
- 0x080c, 0x27a5, 0x080c, 0x210b, 0x080c, 0x13d4, 0x080c, 0xab46,
- 0x080c, 0x2135, 0x00a8, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6,
- 0x0136, 0x0146, 0x0156, 0x080c, 0x27a5, 0x080c, 0x210b, 0x080c,
- 0xab46, 0x080c, 0x22e1, 0x080c, 0x13d4, 0x080c, 0x2135, 0x0000,
- 0x015e, 0x014e, 0x013e, 0x01de, 0x01ce, 0x012e, 0x000e, 0x010e,
- 0x000d, 0x00b6, 0x00c6, 0x0026, 0x0046, 0x9026, 0x080c, 0x6b93,
- 0x1904, 0x31f1, 0x72dc, 0x2001, 0x197d, 0x2004, 0x9005, 0x1110,
- 0xd29c, 0x0148, 0xd284, 0x1138, 0xd2bc, 0x1904, 0x31f1, 0x080c,
- 0x31f6, 0x0804, 0x31f1, 0xd2cc, 0x1904, 0x31f1, 0x080c, 0x76a5,
- 0x1120, 0x70af, 0xffff, 0x0804, 0x31f1, 0xd294, 0x0120, 0x70af,
- 0xffff, 0x0804, 0x31f1, 0x080c, 0x3478, 0x0160, 0x080c, 0xd33e,
- 0x0128, 0x2001, 0x1818, 0x203c, 0x0804, 0x317e, 0x70af, 0xffff,
- 0x0804, 0x31f1, 0x2001, 0x1818, 0x203c, 0x7294, 0xd284, 0x0904,
- 0x317e, 0xd28c, 0x1904, 0x317e, 0x0036, 0x73ac, 0x938e, 0xffff,
- 0x1110, 0x2019, 0x0001, 0x8314, 0x92e0, 0x1d80, 0x2c04, 0x938c,
- 0x0001, 0x0120, 0x9084, 0xff00, 0x8007, 0x0010, 0x9084, 0x00ff,
- 0x970e, 0x05d0, 0x908e, 0x0000, 0x05b8, 0x908e, 0x00ff, 0x1150,
- 0x7230, 0xd284, 0x15b0, 0x7294, 0xc28d, 0x7296, 0x70af, 0xffff,
- 0x003e, 0x04a0, 0x900e, 0x080c, 0x26a2, 0x080c, 0x671e, 0x1538,
- 0x9006, 0xb8bb, 0x0520, 0xb8ac, 0x9005, 0x0148, 0x00c6, 0x2060,
- 0x080c, 0x8d8f, 0x00ce, 0x090c, 0x9130, 0xb8af, 0x0000, 0x080c,
- 0x6bd5, 0x1168, 0x7030, 0xd08c, 0x0130, 0xb800, 0xd0bc, 0x0138,
- 0x080c, 0x6a7c, 0x0120, 0x080c, 0x320f, 0x0148, 0x0028, 0x080c,
- 0x335b, 0x080c, 0x323b, 0x0118, 0x8318, 0x0804, 0x312b, 0x73ae,
- 0x0010, 0x70af, 0xffff, 0x003e, 0x0804, 0x31f1, 0x9780, 0x3489,
- 0x203d, 0x97bc, 0xff00, 0x873f, 0x2041, 0x007e, 0x70ac, 0x9096,
- 0xffff, 0x1118, 0x900e, 0x28a8, 0x0050, 0x9812, 0x0220, 0x2008,
- 0x9802, 0x20a8, 0x0020, 0x70af, 0xffff, 0x0804, 0x31f1, 0x2700,
- 0x0156, 0x0016, 0x9106, 0x0904, 0x31e6, 0xc484, 0x080c, 0x6789,
- 0x0148, 0x080c, 0xd33e, 0x1904, 0x31e6, 0x080c, 0x671e, 0x1904,
- 0x31ee, 0x0008, 0xc485, 0xb8bb, 0x0520, 0xb8ac, 0x9005, 0x0148,
- 0x00c6, 0x2060, 0x080c, 0x8d8f, 0x00ce, 0x090c, 0x9130, 0xb8af,
- 0x0000, 0x080c, 0x6bd5, 0x1130, 0x7030, 0xd08c, 0x01f8, 0xb800,
- 0xd0bc, 0x11e0, 0x7294, 0xd28c, 0x0180, 0x080c, 0x6bd5, 0x9082,
- 0x0006, 0x02e0, 0xd484, 0x1118, 0x080c, 0x6743, 0x0028, 0x080c,
- 0x33ee, 0x01a0, 0x080c, 0x3419, 0x0088, 0x080c, 0x335b, 0x080c,
- 0xd33e, 0x1160, 0x080c, 0x323b, 0x0188, 0x0040, 0x080c, 0xd33e,
- 0x1118, 0x080c, 0x33ee, 0x0110, 0x0451, 0x0140, 0x001e, 0x8108,
- 0x015e, 0x1f04, 0x3197, 0x70af, 0xffff, 0x0018, 0x001e, 0x015e,
- 0x71ae, 0x004e, 0x002e, 0x00ce, 0x00be, 0x0005, 0x00c6, 0x0016,
- 0x70af, 0x0001, 0x2009, 0x007e, 0x080c, 0x671e, 0x1168, 0xb813,
- 0x00ff, 0xb817, 0xfffe, 0x080c, 0x335b, 0x04a9, 0x0128, 0x70dc,
- 0xc0bd, 0x70de, 0x080c, 0xd084, 0x001e, 0x00ce, 0x0005, 0x0016,
- 0x0076, 0x00d6, 0x00c6, 0x2001, 0x184c, 0x2004, 0x9084, 0x00ff,
- 0xb842, 0x080c, 0xaf9f, 0x01d0, 0x2b00, 0x6012, 0x080c, 0xd0b1,
- 0x6023, 0x0001, 0x9006, 0x080c, 0x66bb, 0x2001, 0x0000, 0x080c,
- 0x66cf, 0x0126, 0x2091, 0x8000, 0x70a8, 0x8000, 0x70aa, 0x012e,
- 0x2009, 0x0004, 0x080c, 0xafcc, 0x9085, 0x0001, 0x00ce, 0x00de,
- 0x007e, 0x001e, 0x0005, 0x0016, 0x0076, 0x00d6, 0x00c6, 0x2001,
- 0x184c, 0x2004, 0x9084, 0x00ff, 0xb842, 0x080c, 0xaf9f, 0x0548,
- 0x2b00, 0x6012, 0xb800, 0xc0c4, 0xb802, 0xb8a0, 0x9086, 0x007e,
- 0x0140, 0xb804, 0x9084, 0x00ff, 0x9086, 0x0006, 0x1110, 0x080c,
- 0x3310, 0x080c, 0xd0b1, 0x6023, 0x0001, 0x9006, 0x080c, 0x66bb,
- 0x2001, 0x0002, 0x080c, 0x66cf, 0x0126, 0x2091, 0x8000, 0x70a8,
- 0x8000, 0x70aa, 0x012e, 0x2009, 0x0002, 0x080c, 0xafcc, 0x9085,
- 0x0001, 0x00ce, 0x00de, 0x007e, 0x001e, 0x0005, 0x00b6, 0x00c6,
- 0x0026, 0x2009, 0x0080, 0x080c, 0x671e, 0x1140, 0xb813, 0x00ff,
- 0xb817, 0xfffc, 0x0039, 0x0110, 0x70e3, 0xffff, 0x002e, 0x00ce,
- 0x00be, 0x0005, 0x0016, 0x0076, 0x00d6, 0x00c6, 0x080c, 0xaed8,
- 0x01d0, 0x2b00, 0x6012, 0x080c, 0xd0b1, 0x6023, 0x0001, 0x9006,
- 0x080c, 0x66bb, 0x2001, 0x0002, 0x080c, 0x66cf, 0x0126, 0x2091,
- 0x8000, 0x70e4, 0x8000, 0x70e6, 0x012e, 0x2009, 0x0002, 0x080c,
- 0xafcc, 0x9085, 0x0001, 0x00ce, 0x00de, 0x007e, 0x001e, 0x0005,
- 0x00c6, 0x00d6, 0x0126, 0x2091, 0x8000, 0x2009, 0x007f, 0x080c,
- 0x671e, 0x11b8, 0xb813, 0x00ff, 0xb817, 0xfffd, 0xb8d7, 0x0004,
- 0x080c, 0xaed8, 0x0170, 0x2b00, 0x6012, 0x6316, 0x6023, 0x0001,
- 0x620a, 0x080c, 0xd0b1, 0x2009, 0x0022, 0x080c, 0xafcc, 0x9085,
- 0x0001, 0x012e, 0x00de, 0x00ce, 0x0005, 0x00e6, 0x00c6, 0x0066,
- 0x0036, 0x0026, 0x00b6, 0x21f0, 0x080c, 0xaae0, 0x0106, 0x080c,
- 0x95cc, 0x080c, 0x9538, 0x080c, 0xaa31, 0x080c, 0xbe95, 0x010e,
- 0x090c, 0xaafc, 0x3e08, 0x2130, 0x81ff, 0x0120, 0x20a9, 0x007e,
- 0x900e, 0x0018, 0x20a9, 0x007f, 0x900e, 0x0016, 0x080c, 0x6789,
- 0x1140, 0x9686, 0x0002, 0x1118, 0xb800, 0xd0bc, 0x1110, 0x080c,
- 0x6198, 0x001e, 0x8108, 0x1f04, 0x32f5, 0x9686, 0x0001, 0x190c,
- 0x344c, 0x00be, 0x002e, 0x003e, 0x006e, 0x00ce, 0x00ee, 0x0005,
- 0x00e6, 0x00c6, 0x0046, 0x0036, 0x0026, 0x0016, 0x00b6, 0x080c,
- 0xaae0, 0x0106, 0x6210, 0x2258, 0xbaa0, 0x0026, 0x2019, 0x0029,
- 0x080c, 0x95c1, 0x0076, 0x2039, 0x0000, 0x080c, 0x947e, 0x2c08,
- 0x080c, 0xe440, 0x007e, 0x001e, 0x010e, 0x090c, 0xaafc, 0xba10,
- 0xbb14, 0xbc84, 0x080c, 0x6198, 0xba12, 0xbb16, 0xbc86, 0x00be,
- 0x001e, 0x002e, 0x003e, 0x004e, 0x00ce, 0x00ee, 0x0005, 0x00e6,
- 0x0006, 0x00b6, 0x6010, 0x2058, 0xb8a0, 0x00be, 0x9086, 0x0080,
- 0x0150, 0x2071, 0x1800, 0x70a8, 0x9005, 0x0110, 0x8001, 0x70aa,
- 0x000e, 0x00ee, 0x0005, 0x2071, 0x1800, 0x70e4, 0x9005, 0x0dc0,
- 0x8001, 0x70e6, 0x0ca8, 0xb800, 0xc08c, 0xb802, 0x0005, 0x00f6,
- 0x00e6, 0x00c6, 0x00b6, 0x0046, 0x0036, 0x0026, 0x0016, 0x0156,
- 0x2178, 0x080c, 0xaae0, 0x0106, 0x81ff, 0x1118, 0x20a9, 0x0001,
- 0x0078, 0x080c, 0x5826, 0xd0c4, 0x0140, 0xd0a4, 0x0130, 0x9006,
- 0x2020, 0x2009, 0x002d, 0x080c, 0xe72a, 0x20a9, 0x0800, 0x9016,
- 0x0026, 0x928e, 0x007e, 0x0904, 0x33ca, 0x928e, 0x007f, 0x0904,
- 0x33ca, 0x928e, 0x0080, 0x05f0, 0x9288, 0x1000, 0x210c, 0x81ff,
- 0x05c8, 0x8fff, 0x1150, 0x2001, 0x198f, 0x0006, 0x2003, 0x0001,
- 0x080c, 0x33db, 0x000e, 0x2003, 0x0000, 0x00b6, 0x00c6, 0x2158,
- 0x2001, 0x0001, 0x080c, 0x6b9f, 0x00ce, 0x00be, 0x2019, 0x0029,
- 0x080c, 0x95c1, 0x0076, 0x2039, 0x0000, 0x080c, 0x947e, 0x00b6,
- 0x00c6, 0x0026, 0x2158, 0xba04, 0x9294, 0x00ff, 0x9286, 0x0006,
- 0x1118, 0xb807, 0x0404, 0x0028, 0x2001, 0x0004, 0x8007, 0x9215,
- 0xba06, 0x002e, 0x00ce, 0x00be, 0x0016, 0x2c08, 0x080c, 0xe440,
- 0x001e, 0x007e, 0x002e, 0x8210, 0x1f04, 0x3380, 0x010e, 0x090c,
- 0xaafc, 0x015e, 0x001e, 0x002e, 0x003e, 0x004e, 0x00be, 0x00ce,
- 0x00ee, 0x00fe, 0x0005, 0x0046, 0x0026, 0x0016, 0x080c, 0x5826,
- 0xd0c4, 0x0140, 0xd0a4, 0x0130, 0x9006, 0x2220, 0x2009, 0x0029,
- 0x080c, 0xe72a, 0x001e, 0x002e, 0x004e, 0x0005, 0x0016, 0x0026,
- 0x0036, 0x00c6, 0x7294, 0x82ff, 0x01e8, 0x080c, 0x6bcd, 0x11d0,
- 0x2100, 0x080c, 0x26d5, 0x81ff, 0x01b8, 0x2019, 0x0001, 0x8314,
- 0x92e0, 0x1d80, 0x2c04, 0xd384, 0x0120, 0x9084, 0xff00, 0x8007,
- 0x0010, 0x9084, 0x00ff, 0x9116, 0x0138, 0x9096, 0x00ff, 0x0110,
- 0x8318, 0x0c68, 0x9085, 0x0001, 0x00ce, 0x003e, 0x002e, 0x001e,
- 0x0005, 0x0016, 0x00c6, 0x0126, 0x2091, 0x8000, 0x080c, 0xaae0,
- 0x0106, 0x0036, 0x2019, 0x0029, 0x00c1, 0x003e, 0x010e, 0x090c,
- 0xaafc, 0x9180, 0x1000, 0x2004, 0x9065, 0x0158, 0x0016, 0x00c6,
- 0x2061, 0x1b3a, 0x001e, 0x6112, 0x080c, 0x3310, 0x001e, 0x080c,
- 0x6743, 0x012e, 0x00ce, 0x001e, 0x0005, 0x0016, 0x0026, 0x2110,
- 0x080c, 0xa5c6, 0x080c, 0xea92, 0x002e, 0x001e, 0x0005, 0x2001,
- 0x1837, 0x2004, 0xd0cc, 0x0005, 0x00c6, 0x00b6, 0x080c, 0x76a5,
- 0x1118, 0x20a9, 0x0800, 0x0010, 0x20a9, 0x0782, 0x080c, 0x76a5,
- 0x1110, 0x900e, 0x0010, 0x2009, 0x007e, 0x9180, 0x1000, 0x2004,
- 0x905d, 0x0130, 0x86ff, 0x0110, 0xb800, 0xd0bc, 0x090c, 0x6743,
- 0x8108, 0x1f04, 0x345d, 0x2061, 0x1800, 0x607f, 0x0000, 0x6080,
- 0x9084, 0x00ff, 0x6082, 0x60b3, 0x0000, 0x00be, 0x00ce, 0x0005,
- 0x2001, 0x1869, 0x2004, 0xd0bc, 0x0005, 0x2011, 0x1848, 0x2214,
- 0xd2ec, 0x0005, 0x0026, 0x2011, 0x1867, 0x2214, 0xd2dc, 0x002e,
- 0x0005, 0x7eef, 0x7de8, 0x7ce4, 0x80e2, 0x7be1, 0x80e0, 0x80dc,
- 0x80da, 0x7ad9, 0x80d6, 0x80d5, 0x80d4, 0x80d3, 0x80d2, 0x80d1,
- 0x79ce, 0x78cd, 0x80cc, 0x80cb, 0x80ca, 0x80c9, 0x80c7, 0x80c6,
- 0x77c5, 0x76c3, 0x80bc, 0x80ba, 0x75b9, 0x80b6, 0x74b5, 0x73b4,
- 0x72b3, 0x80b2, 0x80b1, 0x80ae, 0x71ad, 0x80ac, 0x70ab, 0x6faa,
- 0x6ea9, 0x80a7, 0x6da6, 0x6ca5, 0x6ba3, 0x6a9f, 0x699e, 0x689d,
- 0x809b, 0x8098, 0x6797, 0x6690, 0x658f, 0x6488, 0x6384, 0x6282,
- 0x8081, 0x8080, 0x617c, 0x607a, 0x8079, 0x5f76, 0x8075, 0x8074,
- 0x8073, 0x8072, 0x8071, 0x806e, 0x5e6d, 0x806c, 0x5d6b, 0x5c6a,
- 0x5b69, 0x8067, 0x5a66, 0x5965, 0x5863, 0x575c, 0x565a, 0x5559,
- 0x8056, 0x8055, 0x5454, 0x5353, 0x5252, 0x5151, 0x504e, 0x4f4d,
- 0x804c, 0x804b, 0x4e4a, 0x4d49, 0x8047, 0x4c46, 0x8045, 0x8043,
- 0x803c, 0x803a, 0x8039, 0x8036, 0x4b35, 0x8034, 0x4a33, 0x4932,
- 0x4831, 0x802e, 0x472d, 0x462c, 0x452b, 0x442a, 0x4329, 0x4227,
- 0x8026, 0x8025, 0x4123, 0x401f, 0x3f1e, 0x3e1d, 0x3d1b, 0x3c18,
- 0x8017, 0x8010, 0x3b0f, 0x3a08, 0x8004, 0x3902, 0x8001, 0x8000,
- 0x8000, 0x3800, 0x3700, 0x3600, 0x8000, 0x3500, 0x8000, 0x8000,
- 0x8000, 0x3400, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
- 0x3300, 0x3200, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
- 0x3100, 0x3000, 0x8000, 0x8000, 0x2f00, 0x8000, 0x2e00, 0x2d00,
- 0x2c00, 0x8000, 0x8000, 0x8000, 0x2b00, 0x8000, 0x2a00, 0x2900,
- 0x2800, 0x8000, 0x2700, 0x2600, 0x2500, 0x2400, 0x2300, 0x2200,
- 0x8000, 0x8000, 0x2100, 0x2000, 0x1f00, 0x1e00, 0x1d00, 0x1c00,
- 0x8000, 0x8000, 0x1b00, 0x1a00, 0x8000, 0x1900, 0x8000, 0x8000,
- 0x8000, 0x8000, 0x8000, 0x8000, 0x1800, 0x8000, 0x1700, 0x1600,
- 0x1500, 0x8000, 0x1400, 0x1300, 0x1200, 0x1100, 0x1000, 0x0f00,
- 0x8000, 0x8000, 0x0e00, 0x0d00, 0x0c00, 0x0b00, 0x0a00, 0x0900,
- 0x8000, 0x8000, 0x0800, 0x0700, 0x8000, 0x0600, 0x8000, 0x8000,
- 0x8000, 0x0500, 0x0400, 0x0300, 0x8000, 0x0200, 0x8000, 0x8000,
- 0x8000, 0x0100, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
- 0x0000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
+ 0x2009, 0x00f7, 0x080c, 0x60f4, 0x7940, 0x918c, 0x0010, 0x7942,
+ 0x7924, 0xd1b4, 0x0120, 0x2011, 0x0040, 0x080c, 0x2adc, 0xd19c,
+ 0x0120, 0x2011, 0x0008, 0x080c, 0x2adc, 0x0006, 0x0036, 0x0156,
+ 0x0000, 0x2001, 0x19a9, 0x2004, 0x9005, 0x1518, 0x080c, 0x2a70,
+ 0x1148, 0x2001, 0x0001, 0x080c, 0x29d7, 0x2001, 0x0001, 0x080c,
+ 0x29ba, 0x00b8, 0x080c, 0x2a78, 0x1138, 0x9006, 0x080c, 0x29d7,
+ 0x9006, 0x080c, 0x29ba, 0x0068, 0x080c, 0x2a80, 0x1d50, 0x2001,
+ 0x1999, 0x2004, 0xd0fc, 0x0108, 0x0020, 0x080c, 0x27e5, 0x0804,
+ 0x0cbd, 0x20a9, 0x003a, 0x1d04, 0x0c13, 0x080c, 0x8918, 0x1f04,
+ 0x0c13, 0x080c, 0x76ae, 0x0148, 0x080c, 0x76c0, 0x1118, 0x080c,
+ 0x79ae, 0x0050, 0x080c, 0x76a5, 0x0dd0, 0x080c, 0x79a9, 0x080c,
+ 0x799f, 0x080c, 0x75cc, 0x0020, 0x2009, 0x00f8, 0x080c, 0x60f4,
+ 0x7850, 0xc0e5, 0x7852, 0x080c, 0x769d, 0x0120, 0x7843, 0x0090,
+ 0x7843, 0x0010, 0x2021, 0xe678, 0x2019, 0xea60, 0x0d0c, 0x8918,
+ 0x7820, 0xd09c, 0x15a0, 0x080c, 0x769d, 0x0904, 0x0c9f, 0x7824,
+ 0xd0ac, 0x1904, 0x0cc2, 0x080c, 0x76c0, 0x1548, 0x0046, 0x2021,
+ 0x0320, 0x8421, 0x1df0, 0x004e, 0x2011, 0x1800, 0x080c, 0x2adc,
+ 0x080c, 0x2a88, 0x7824, 0x9084, 0x1800, 0x1168, 0x9484, 0x0fff,
+ 0x1140, 0x2001, 0x1810, 0x2004, 0x9084, 0x9000, 0x0110, 0x080c,
+ 0x0ce5, 0x8421, 0x1160, 0x1d04, 0x0c6f, 0x080c, 0x8918, 0x080c,
+ 0x79a9, 0x080c, 0x799f, 0x7003, 0x0001, 0x0804, 0x0cc2, 0x8319,
+ 0x1928, 0x2001, 0x1810, 0x2004, 0x9084, 0x9000, 0x0110, 0x080c,
+ 0x0ce5, 0x1d04, 0x0c85, 0x080c, 0x8918, 0x2009, 0x199c, 0x2104,
+ 0x9005, 0x0118, 0x8001, 0x200a, 0x1188, 0x200b, 0x000a, 0x2011,
+ 0x0048, 0x080c, 0x2adc, 0x20a9, 0x0002, 0x080c, 0x2a69, 0x7924,
+ 0x080c, 0x2a88, 0xd19c, 0x0110, 0x080c, 0x29a8, 0x00f0, 0x080c,
+ 0x76ae, 0x1140, 0x94a2, 0x03e8, 0x1128, 0x080c, 0x7671, 0x7003,
+ 0x0001, 0x00c0, 0x2011, 0x1800, 0x080c, 0x2adc, 0x080c, 0x2a88,
+ 0x7824, 0x080c, 0x76b7, 0x0110, 0xd0ac, 0x1160, 0x9084, 0x1800,
+ 0x0904, 0x0c77, 0x7003, 0x0001, 0x0028, 0x2001, 0x0001, 0x080c,
+ 0x2646, 0x00a0, 0x7850, 0xc0e4, 0x7852, 0x2009, 0x180c, 0x210c,
+ 0xd19c, 0x1120, 0x7904, 0x918d, 0x0002, 0x7906, 0x2011, 0x0048,
+ 0x080c, 0x2adc, 0x7828, 0x9085, 0x0028, 0x782a, 0x2001, 0x19a9,
+ 0x2003, 0x0000, 0x9006, 0x78f2, 0x015e, 0x003e, 0x000e, 0x012e,
+ 0x00fe, 0x004e, 0x002e, 0x001e, 0x0005, 0x0006, 0x0016, 0x0026,
+ 0x0036, 0x0046, 0x00b6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x0156,
+ 0x0071, 0x0d0c, 0x8918, 0x015e, 0x00fe, 0x00ee, 0x00de, 0x00ce,
+ 0x00be, 0x004e, 0x003e, 0x002e, 0x001e, 0x000e, 0x0005, 0x00e6,
+ 0x2071, 0x189e, 0x7004, 0x9086, 0x0001, 0x1110, 0x080c, 0x359b,
+ 0x00ee, 0x0005, 0x0005, 0x2a70, 0x2061, 0x19ad, 0x2063, 0x0003,
+ 0x6007, 0x0003, 0x600b, 0x0012, 0x600f, 0x0137, 0x2001, 0x197d,
+ 0x900e, 0x2102, 0x7196, 0x2001, 0x0100, 0x2004, 0x9082, 0x0002,
+ 0x0218, 0x705f, 0xffff, 0x0008, 0x715e, 0x7067, 0xffff, 0x717e,
+ 0x7182, 0x080c, 0xd0a1, 0x70ef, 0x00c0, 0x2061, 0x196d, 0x6003,
+ 0x0909, 0x6106, 0x600b, 0x8800, 0x600f, 0x0200, 0x6013, 0x00ff,
+ 0x6017, 0x001f, 0x611a, 0x601f, 0x07d0, 0x2061, 0x1975, 0x6003,
+ 0x8000, 0x6106, 0x610a, 0x600f, 0x0200, 0x6013, 0x00ff, 0x6116,
+ 0x601b, 0x0001, 0x611e, 0x2061, 0x198a, 0x6003, 0x514c, 0x6007,
+ 0x4f47, 0x600b, 0x4943, 0x600f, 0x2020, 0x2001, 0x182c, 0x2102,
+ 0x0005, 0x9016, 0x080c, 0x6783, 0x1178, 0xb804, 0x90c4, 0x00ff,
+ 0x98c6, 0x0006, 0x0128, 0x90c4, 0xff00, 0x98c6, 0x0600, 0x1120,
+ 0x9186, 0x0080, 0x0108, 0x8210, 0x8108, 0x9186, 0x0800, 0x1d50,
+ 0x2208, 0x0005, 0x2091, 0x8000, 0x2079, 0x0000, 0x000e, 0x00f6,
+ 0x0010, 0x2091, 0x8000, 0x0e04, 0x0d7b, 0x0006, 0x0016, 0x2001,
+ 0x8002, 0x0006, 0x2079, 0x0000, 0x000e, 0x7882, 0x7836, 0x001e,
+ 0x798e, 0x000e, 0x788a, 0x000e, 0x7886, 0x3900, 0x789a, 0x00d6,
+ 0x2069, 0x0300, 0x6818, 0x78ae, 0x681c, 0x78b2, 0x6808, 0x78be,
+ 0x00de, 0x7833, 0x0012, 0x2091, 0x5000, 0x0156, 0x00d6, 0x0036,
+ 0x0026, 0x2079, 0x0300, 0x2069, 0x1b2c, 0x7a08, 0x226a, 0x2069,
+ 0x1b2d, 0x7a18, 0x226a, 0x8d68, 0x7a1c, 0x226a, 0x782c, 0x2019,
+ 0x1b3a, 0x201a, 0x2019, 0x1b3d, 0x9016, 0x7808, 0xd09c, 0x0168,
+ 0x7820, 0x201a, 0x8210, 0x8318, 0x9386, 0x1b56, 0x0108, 0x0ca8,
+ 0x7808, 0xd09c, 0x0110, 0x2011, 0xdead, 0x2019, 0x1b3b, 0x782c,
+ 0x201a, 0x8318, 0x221a, 0x7803, 0x0000, 0x2069, 0x1a82, 0x901e,
+ 0x20a9, 0x0020, 0x7b26, 0x7a28, 0x226a, 0x8d68, 0x8318, 0x1f04,
+ 0x0dd2, 0x2069, 0x1aa2, 0x2019, 0x0050, 0x20a9, 0x0020, 0x7b26,
+ 0x7a28, 0x226a, 0x8d68, 0x8318, 0x1f04, 0x0ddf, 0x0491, 0x002e,
+ 0x003e, 0x00de, 0x015e, 0x2079, 0x1800, 0x7803, 0x0005, 0x2091,
+ 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x0180, 0x2001, 0x1a26,
+ 0x2004, 0x9005, 0x0128, 0x2001, 0x008b, 0x2004, 0xd0fc, 0x0dd8,
+ 0x2001, 0x008a, 0x2003, 0x0002, 0x2003, 0x1001, 0x080c, 0x582f,
+ 0x1170, 0x080c, 0x0f26, 0x0110, 0x080c, 0x0e79, 0x080c, 0x582f,
+ 0x1130, 0x2071, 0x1800, 0x2011, 0x8000, 0x080c, 0x0f3a, 0x0c70,
+ 0x0005, 0x2001, 0x0382, 0x2004, 0x9084, 0x0007, 0x9086, 0x0001,
+ 0x1120, 0x2001, 0x0015, 0x080c, 0xaae8, 0x2079, 0x0380, 0x2069,
+ 0x1b0c, 0x7818, 0x6802, 0x781c, 0x6806, 0x7840, 0x680a, 0x7844,
+ 0x680e, 0x782c, 0x6812, 0x2019, 0x1b17, 0x9016, 0x7808, 0xd09c,
+ 0x0150, 0x7820, 0x201a, 0x8210, 0x8318, 0x8210, 0x9282, 0x0011,
+ 0x0ea8, 0x2011, 0xdead, 0x6a2a, 0x7830, 0x681a, 0x7834, 0x681e,
+ 0x7838, 0x6822, 0x783c, 0x6826, 0x7803, 0x0000, 0x2069, 0x1acc,
+ 0x901e, 0x20a9, 0x0020, 0x7b26, 0x7828, 0x206a, 0x8d68, 0x8318,
+ 0x1f04, 0x0e53, 0x2069, 0x1aec, 0x2019, 0x00b0, 0x20a9, 0x0020,
+ 0x7b26, 0x7828, 0x206a, 0x8d68, 0x8318, 0x1f04, 0x0e60, 0x0005,
+ 0x918c, 0x03ff, 0x2001, 0x0003, 0x2004, 0x9084, 0x0600, 0x1118,
+ 0x918d, 0x6c00, 0x0010, 0x918d, 0x6400, 0x2001, 0x017f, 0x2102,
+ 0x0005, 0x0026, 0x0126, 0x2011, 0x0080, 0x080c, 0x0f18, 0x20a9,
+ 0x0900, 0x080c, 0x0f4e, 0x2011, 0x0040, 0x080c, 0x0f18, 0x20a9,
+ 0x0900, 0x080c, 0x0f4e, 0x0c78, 0x0026, 0x080c, 0x0f26, 0x1188,
+ 0x2011, 0x010e, 0x2214, 0x9294, 0x0007, 0x9296, 0x0007, 0x0118,
+ 0x2011, 0x0947, 0x0010, 0x2011, 0x1b47, 0x080c, 0x0f3a, 0x002e,
+ 0x0005, 0x2011, 0x010e, 0x2214, 0x9294, 0x0007, 0x9296, 0x0007,
+ 0x0118, 0x2011, 0xa880, 0x0010, 0x2011, 0x6840, 0xd0e4, 0x70f3,
+ 0x0000, 0x1120, 0x70f3, 0x0fa0, 0x080c, 0x0f2b, 0x002e, 0x0005,
+ 0x0026, 0x080c, 0x0f26, 0x0148, 0xd0a4, 0x1138, 0x2011, 0xcdd5,
+ 0x0010, 0x2011, 0x0080, 0x080c, 0x0f2b, 0x002e, 0x0005, 0x0026,
+ 0x70f3, 0x0000, 0x080c, 0x0f26, 0x1130, 0x2011, 0x8040, 0x080c,
+ 0x0f3a, 0x002e, 0x0005, 0x080c, 0x2a80, 0x1118, 0x2011, 0xcdc5,
+ 0x0010, 0x2011, 0xcac2, 0x080c, 0x0f2b, 0x002e, 0x0005, 0x00e6,
+ 0x0016, 0x0006, 0x2071, 0x1800, 0xd0b4, 0x70ec, 0x71e8, 0x1118,
+ 0xc0e4, 0xc1f4, 0x0050, 0x0006, 0x3b00, 0x9084, 0xff3e, 0x20d8,
+ 0x000e, 0x70f3, 0x0000, 0xc0e5, 0xc1f5, 0x0099, 0x000e, 0x001e,
+ 0x00ee, 0x0005, 0x00e6, 0x2071, 0x1800, 0xd0e4, 0x70ec, 0x1110,
+ 0xc0dc, 0x0008, 0xc0dd, 0x0016, 0x71e8, 0x0019, 0x001e, 0x00ee,
+ 0x0005, 0x70ee, 0x71ea, 0x7000, 0x9084, 0x0007, 0x000b, 0x0005,
+ 0x0ede, 0x0eb8, 0x0eb8, 0x0e8c, 0x0ec7, 0x0eb8, 0x0eb8, 0x0ec7,
+ 0xc284, 0x0016, 0x3b08, 0x3a00, 0x9104, 0x918d, 0x00c1, 0x21d8,
+ 0x9084, 0xff3e, 0x9205, 0x20d0, 0x001e, 0x0005, 0x2001, 0x183b,
+ 0x2004, 0xd0dc, 0x0005, 0x9e86, 0x1800, 0x190c, 0x0d79, 0x70ec,
+ 0xd0e4, 0x0108, 0xc2e5, 0x72ee, 0xd0e4, 0x1118, 0x9294, 0x00c1,
+ 0x08f9, 0x0005, 0x9e86, 0x1800, 0x190c, 0x0d79, 0x70e8, 0xd0f4,
+ 0x0108, 0xc2f5, 0x72ea, 0xd0f4, 0x1140, 0x9284, 0x8000, 0x8005,
+ 0xc284, 0x9215, 0x9294, 0x00c1, 0x0861, 0x0005, 0x1d04, 0x0f4e,
+ 0x2091, 0x6000, 0x1f04, 0x0f4e, 0x0005, 0x890e, 0x810e, 0x810f,
+ 0x9194, 0x003f, 0x918c, 0xffc0, 0x0005, 0x0006, 0x2200, 0x914d,
+ 0x894f, 0x894d, 0x894d, 0x000e, 0x0005, 0x01d6, 0x0146, 0x0036,
+ 0x0096, 0x2061, 0x188d, 0x600b, 0x0000, 0x600f, 0x0000, 0x6003,
+ 0x0000, 0x6007, 0x0000, 0x2009, 0xffc0, 0x2105, 0x0006, 0x2001,
+ 0xaaaa, 0x200f, 0x2019, 0x5555, 0x9016, 0x2049, 0x0bff, 0xab02,
+ 0xa001, 0xa001, 0xa800, 0x9306, 0x1138, 0x2105, 0x9306, 0x0120,
+ 0x8210, 0x99c8, 0x0400, 0x0c98, 0x000e, 0x200f, 0x2001, 0x189d,
+ 0x928a, 0x000e, 0x1638, 0x928a, 0x0006, 0x2011, 0x0006, 0x1210,
+ 0x2011, 0x0000, 0x2202, 0x9006, 0x2008, 0x82ff, 0x01b0, 0x8200,
+ 0x600a, 0x600f, 0xffff, 0x6003, 0x0002, 0x6007, 0x0000, 0x0026,
+ 0x2019, 0x0010, 0x9280, 0x0001, 0x20e8, 0x21a0, 0x21a8, 0x4104,
+ 0x8319, 0x1de0, 0x8211, 0x1da0, 0x002e, 0x009e, 0x003e, 0x014e,
+ 0x01de, 0x0005, 0x2011, 0x000e, 0x08e8, 0x0016, 0x0026, 0x0096,
+ 0x3348, 0x080c, 0x0f55, 0x2100, 0x9300, 0x2098, 0x22e0, 0x009e,
+ 0x002e, 0x001e, 0x0036, 0x3518, 0x20a9, 0x0001, 0x4002, 0x8007,
+ 0x4004, 0x8319, 0x1dd8, 0x003e, 0x0005, 0x20e9, 0x0001, 0x71b8,
+ 0x81ff, 0x11c0, 0x9006, 0x2009, 0x0200, 0x20a9, 0x0002, 0x9298,
+ 0x0018, 0x23a0, 0x4001, 0x2009, 0x0700, 0x20a9, 0x0002, 0x9298,
+ 0x0008, 0x23a0, 0x4001, 0x707c, 0x8007, 0x7180, 0x810f, 0x20a9,
+ 0x0002, 0x4001, 0x9298, 0x000c, 0x23a0, 0x900e, 0x080c, 0x0d59,
+ 0x2001, 0x0000, 0x810f, 0x20a9, 0x0002, 0x4001, 0x0005, 0x89ff,
+ 0x0140, 0xa804, 0xa807, 0x0000, 0x0006, 0x080c, 0x107f, 0x009e,
+ 0x0cb0, 0x0005, 0x00e6, 0x2071, 0x1800, 0x080c, 0x10f8, 0x090c,
+ 0x0d79, 0x00ee, 0x0005, 0x0086, 0x00e6, 0x0006, 0x0026, 0x0036,
+ 0x0126, 0x2091, 0x8000, 0x00c9, 0x2071, 0x1800, 0x73c0, 0x702c,
+ 0x9016, 0x9045, 0x0158, 0x8210, 0x9906, 0x090c, 0x0d79, 0x2300,
+ 0x9202, 0x0120, 0x1a0c, 0x0d79, 0xa000, 0x0c98, 0x012e, 0x003e,
+ 0x002e, 0x000e, 0x00ee, 0x008e, 0x0005, 0x0086, 0x00e6, 0x0006,
+ 0x0126, 0x2091, 0x8000, 0x2071, 0x1910, 0x7010, 0x9005, 0x0140,
+ 0x7018, 0x9045, 0x0128, 0x9906, 0x090c, 0x0d79, 0xa000, 0x0cc8,
+ 0x012e, 0x000e, 0x00ee, 0x008e, 0x0005, 0x00e6, 0x2071, 0x1800,
+ 0x0126, 0x2091, 0x8000, 0x70c0, 0x8001, 0x0270, 0x70c2, 0x702c,
+ 0x2048, 0x9085, 0x0001, 0xa800, 0x702e, 0xa803, 0x0000, 0xa807,
+ 0x0000, 0x012e, 0x00ee, 0x0005, 0x904e, 0x0cd8, 0x00e6, 0x0126,
+ 0x2091, 0x8000, 0x2071, 0x1800, 0x70c0, 0x90ca, 0x0020, 0x0268,
+ 0x8001, 0x70c2, 0x702c, 0x2048, 0xa800, 0x702e, 0xa803, 0x0000,
+ 0xa807, 0x0000, 0x012e, 0x00ee, 0x0005, 0x904e, 0x0cd8, 0x00e6,
+ 0x0126, 0x2091, 0x8000, 0x0016, 0x890e, 0x810e, 0x810f, 0x9184,
+ 0x003f, 0xa862, 0x9184, 0xffc0, 0xa85e, 0x001e, 0x0020, 0x00e6,
+ 0x0126, 0x2091, 0x8000, 0x2071, 0x1800, 0x702c, 0xa802, 0x2900,
+ 0x702e, 0x70c0, 0x8000, 0x70c2, 0x080c, 0x8732, 0x012e, 0x00ee,
+ 0x0005, 0x2071, 0x1800, 0x9026, 0x2009, 0x0000, 0x2049, 0x0400,
+ 0x2900, 0x702e, 0x8940, 0x2800, 0xa802, 0xa95e, 0xa863, 0x0001,
+ 0x8420, 0x9886, 0x0440, 0x0120, 0x2848, 0x9188, 0x0040, 0x0c90,
+ 0x2071, 0x188d, 0x7000, 0x9005, 0x11a0, 0x2001, 0x0558, 0xa802,
+ 0x2048, 0x2009, 0x5600, 0x8940, 0x2800, 0xa802, 0xa95e, 0xa863,
+ 0x0001, 0x8420, 0x9886, 0x0800, 0x0120, 0x2848, 0x9188, 0x0040,
+ 0x0c90, 0x2071, 0x188d, 0x7104, 0x7200, 0x82ff, 0x01d0, 0x7308,
+ 0x8318, 0x831f, 0x831b, 0x831b, 0x7312, 0x8319, 0x2001, 0x0800,
+ 0xa802, 0x2048, 0x8900, 0xa802, 0x2040, 0xa95e, 0xaa62, 0x8420,
+ 0x2300, 0x9906, 0x0130, 0x2848, 0x9188, 0x0040, 0x9291, 0x0000,
+ 0x0c88, 0xa803, 0x0000, 0x2071, 0x1800, 0x74be, 0x74c2, 0x0005,
+ 0x00e6, 0x0016, 0x9984, 0xfc00, 0x01e8, 0x908c, 0xf800, 0x1168,
+ 0x9982, 0x0400, 0x02b8, 0x9982, 0x0440, 0x0278, 0x9982, 0x0558,
+ 0x0288, 0x9982, 0x0800, 0x1270, 0x0040, 0x9982, 0x0800, 0x0250,
+ 0x2071, 0x188d, 0x7010, 0x9902, 0x1228, 0x9085, 0x0001, 0x001e,
+ 0x00ee, 0x0005, 0x9006, 0x0cd8, 0x00e6, 0x2071, 0x1a25, 0x7007,
+ 0x0000, 0x9006, 0x701e, 0x7022, 0x7002, 0x2071, 0x0000, 0x7010,
+ 0x9085, 0x8044, 0x7012, 0x2071, 0x0080, 0x9006, 0x702b, 0x0060,
+ 0x20a9, 0x0040, 0x7022, 0x1f04, 0x1132, 0x702b, 0x0060, 0x702b,
+ 0x0020, 0x20a9, 0x0040, 0x7022, 0x1f04, 0x113b, 0x702b, 0x0020,
+ 0x00ee, 0x0005, 0x0126, 0x2091, 0x8000, 0x00e6, 0xa06f, 0x0000,
+ 0x2071, 0x1a25, 0x701c, 0x9088, 0x1a2f, 0x280a, 0x8000, 0x9084,
+ 0x003f, 0x701e, 0x7120, 0x9106, 0x090c, 0x0d79, 0x7004, 0x9005,
+ 0x1128, 0x00f6, 0x2079, 0x0080, 0x00a9, 0x00fe, 0x00ee, 0x012e,
+ 0x0005, 0x0126, 0x2091, 0x8000, 0x00e6, 0x2071, 0x1a25, 0x7004,
+ 0x9005, 0x1128, 0x00f6, 0x2079, 0x0080, 0x0021, 0x00fe, 0x00ee,
+ 0x012e, 0x0005, 0x7004, 0x9086, 0x0000, 0x1110, 0x7007, 0x0006,
+ 0x7000, 0x0002, 0x1184, 0x1307, 0x1182, 0x1182, 0x12fb, 0x12fb,
+ 0x12fb, 0x12fb, 0x080c, 0x0d79, 0x701c, 0x7120, 0x9106, 0x1148,
+ 0x792c, 0x9184, 0x0001, 0x1120, 0xd1fc, 0x1110, 0x7007, 0x0000,
+ 0x0005, 0x0096, 0x9180, 0x1a2f, 0x2004, 0x700a, 0x2048, 0x8108,
+ 0x918c, 0x003f, 0x7122, 0x782b, 0x0026, 0xa88c, 0x7802, 0xa890,
+ 0x7806, 0xa894, 0x780a, 0xa898, 0x780e, 0xa878, 0x700e, 0xa870,
+ 0x7016, 0xa874, 0x701a, 0xa868, 0x009e, 0xd084, 0x0120, 0x7007,
+ 0x0001, 0x0029, 0x0005, 0x7007, 0x0002, 0x00b1, 0x0005, 0x0016,
+ 0x0026, 0x710c, 0x2011, 0x0040, 0x9182, 0x0040, 0x1210, 0x2110,
+ 0x9006, 0x700e, 0x7212, 0x8203, 0x7812, 0x782b, 0x0020, 0x782b,
+ 0x0041, 0x002e, 0x001e, 0x0005, 0x0016, 0x0026, 0x0136, 0x0146,
+ 0x0156, 0x7014, 0x20e0, 0x7018, 0x2098, 0x20e9, 0x0000, 0x20a1,
+ 0x0088, 0x782b, 0x0026, 0x710c, 0x2011, 0x0040, 0x9182, 0x0040,
+ 0x1210, 0x2110, 0x9006, 0x700e, 0x22a8, 0x4006, 0x8203, 0x7812,
+ 0x782b, 0x0020, 0x3300, 0x701a, 0x782b, 0x0001, 0x015e, 0x014e,
+ 0x013e, 0x002e, 0x001e, 0x0005, 0x2009, 0x1a25, 0x2104, 0xc095,
+ 0x200a, 0x080c, 0x1161, 0x0005, 0x0016, 0x00e6, 0x2071, 0x1a25,
+ 0x00f6, 0x2079, 0x0080, 0x792c, 0xd1bc, 0x190c, 0x0d72, 0x782b,
+ 0x0002, 0xd1fc, 0x0120, 0x918c, 0x0700, 0x7004, 0x0023, 0x00fe,
+ 0x00ee, 0x001e, 0x0005, 0x1172, 0x121a, 0x124e, 0x1326, 0x0d79,
+ 0x1341, 0x0d79, 0x918c, 0x0700, 0x1550, 0x0136, 0x0146, 0x0156,
+ 0x7014, 0x20e8, 0x7018, 0x20a0, 0x20e1, 0x0000, 0x2099, 0x0088,
+ 0x782b, 0x0040, 0x7010, 0x20a8, 0x4005, 0x3400, 0x701a, 0x015e,
+ 0x014e, 0x013e, 0x700c, 0x9005, 0x0578, 0x7800, 0x7802, 0x7804,
+ 0x7806, 0x080c, 0x11b7, 0x0005, 0x7008, 0x0096, 0x2048, 0xa86f,
+ 0x0100, 0x009e, 0x7007, 0x0000, 0x080c, 0x1172, 0x0005, 0x7008,
+ 0x0096, 0x2048, 0xa86f, 0x0200, 0x009e, 0x0ca0, 0x918c, 0x0700,
+ 0x1150, 0x700c, 0x9005, 0x0180, 0x7800, 0x7802, 0x7804, 0x7806,
+ 0x080c, 0x11cc, 0x0005, 0x7008, 0x0096, 0x2048, 0xa86f, 0x0200,
+ 0x009e, 0x7007, 0x0000, 0x0080, 0x0096, 0x7008, 0x2048, 0x7800,
+ 0xa88e, 0x7804, 0xa892, 0x7808, 0xa896, 0x780c, 0xa89a, 0xa86f,
+ 0x0100, 0x009e, 0x7007, 0x0000, 0x0096, 0x00d6, 0x7008, 0x2048,
+ 0x2001, 0x18b9, 0x2004, 0x9906, 0x1128, 0xa89c, 0x080f, 0x00de,
+ 0x009e, 0x00a0, 0x00de, 0x009e, 0x0096, 0x00d6, 0x7008, 0x2048,
+ 0x0081, 0x0150, 0xa89c, 0x0086, 0x2940, 0x080f, 0x008e, 0x00de,
+ 0x009e, 0x080c, 0x1161, 0x0005, 0x00de, 0x009e, 0x080c, 0x1161,
+ 0x0005, 0xa8a8, 0xd08c, 0x0005, 0x0096, 0xa0a0, 0x904d, 0x090c,
+ 0x0d79, 0xa06c, 0x908e, 0x0100, 0x0130, 0xa87b, 0x0030, 0xa883,
+ 0x0000, 0xa897, 0x4002, 0x080c, 0x6f05, 0xa09f, 0x0000, 0xa0a3,
+ 0x0000, 0x2848, 0x080c, 0x107f, 0x009e, 0x0005, 0x00a6, 0xa0a0,
+ 0x904d, 0x090c, 0x0d79, 0xa06c, 0x908e, 0x0100, 0x0128, 0xa87b,
+ 0x0001, 0xa883, 0x0000, 0x00c0, 0xa80c, 0x2050, 0xb004, 0x9005,
+ 0x0198, 0xa80e, 0x2050, 0x8006, 0x8006, 0x8007, 0x908c, 0x003f,
+ 0x9084, 0xffc0, 0x9080, 0x0002, 0xa076, 0xa172, 0xb000, 0xa07a,
+ 0x2810, 0x080c, 0x1142, 0x00e8, 0xa97c, 0xa894, 0x0016, 0x0006,
+ 0x080c, 0x6f05, 0x000e, 0x001e, 0xd1fc, 0x1138, 0xd1f4, 0x0128,
+ 0x00c6, 0x2060, 0x080c, 0xaf4e, 0x00ce, 0x7008, 0x2048, 0xa89f,
+ 0x0000, 0xa8a3, 0x0000, 0x080c, 0x107f, 0x7007, 0x0000, 0x080c,
+ 0x1161, 0x00ae, 0x0005, 0x0126, 0x2091, 0x8000, 0x782b, 0x1001,
+ 0x7007, 0x0005, 0x7000, 0xc094, 0x7002, 0x012e, 0x0005, 0x0096,
+ 0x2001, 0x1930, 0x204c, 0xa87c, 0x7812, 0xa88c, 0x7802, 0xa890,
+ 0x7806, 0xa894, 0x780a, 0xa898, 0x780e, 0x782b, 0x0020, 0x0126,
+ 0x2091, 0x8000, 0x782b, 0x0041, 0x7007, 0x0003, 0x7000, 0xc084,
+ 0x7002, 0x2900, 0x700a, 0x012e, 0x009e, 0x0005, 0x20e1, 0x0000,
+ 0x2099, 0x0088, 0x782b, 0x0040, 0x0096, 0x2001, 0x1930, 0x204c,
+ 0xaa7c, 0x009e, 0x080c, 0x8e1e, 0x2009, 0x188c, 0x2104, 0x9084,
+ 0xfffc, 0x200a, 0x080c, 0x8c80, 0x7007, 0x0000, 0x080c, 0x1172,
+ 0x0005, 0x7007, 0x0000, 0x080c, 0x1172, 0x0005, 0x0126, 0x2091,
+ 0x2200, 0x2079, 0x0300, 0x2071, 0x1a6f, 0x7003, 0x0000, 0x78bf,
+ 0x00f6, 0x0041, 0x7807, 0x0007, 0x7803, 0x0000, 0x7803, 0x0001,
+ 0x012e, 0x0005, 0x00c6, 0x7803, 0x0000, 0x2001, 0x0165, 0x2003,
+ 0x4198, 0x7808, 0xd09c, 0x0120, 0x7820, 0x080c, 0x13aa, 0x0cc8,
+ 0x2001, 0x1a70, 0x2003, 0x0000, 0x78ab, 0x0004, 0x78ac, 0xd0ac,
+ 0x1de8, 0x78ab, 0x0002, 0x7807, 0x0007, 0x7827, 0x0030, 0x782b,
+ 0x0400, 0x7827, 0x0031, 0x782b, 0x1a82, 0x78e3, 0xff00, 0x781f,
+ 0xff00, 0x781b, 0xff00, 0x2001, 0x1a71, 0x2003, 0x0000, 0x2001,
+ 0x0200, 0x2004, 0xd0dc, 0x0110, 0x781f, 0x0303, 0x2061, 0x1a82,
+ 0x602f, 0x1ddc, 0x2001, 0x181a, 0x2004, 0x9082, 0x1ddc, 0x6032,
+ 0x603b, 0x1ede, 0x602b, 0x1ac2, 0x6007, 0x1aa2, 0x2061, 0x1aa2,
+ 0x606f, 0x193e, 0x2001, 0x1929, 0x2004, 0x607a, 0x783f, 0x3474,
+ 0x00ce, 0x0005, 0x9086, 0x000d, 0x11d0, 0x7808, 0xd09c, 0x01b8,
+ 0x7820, 0x0026, 0x2010, 0x080c, 0xcc21, 0x0180, 0x2260, 0x6000,
+ 0x9086, 0x0004, 0x1158, 0x0016, 0x6120, 0x9186, 0x0009, 0x0108,
+ 0x0020, 0x2009, 0x004c, 0x080c, 0xafec, 0x001e, 0x002e, 0x0005,
+ 0x0126, 0x2091, 0x2200, 0x7908, 0x9184, 0x0070, 0x190c, 0x0d72,
+ 0xd19c, 0x05a0, 0x7820, 0x908c, 0xf000, 0x0540, 0x2060, 0x6020,
+ 0x9086, 0x0003, 0x1550, 0x6000, 0x9086, 0x0004, 0x1530, 0x6114,
+ 0x2148, 0xa876, 0xa87a, 0xa867, 0x0103, 0x080c, 0x6d26, 0x00b6,
+ 0x6010, 0x2058, 0xba3c, 0x8211, 0x0208, 0xba3e, 0xb8d0, 0x9005,
+ 0x190c, 0x68ae, 0x00be, 0x6044, 0xd0fc, 0x190c, 0xab20, 0x080c,
+ 0xaf77, 0x7808, 0xd09c, 0x19b0, 0x012e, 0x0005, 0x908a, 0x0024,
+ 0x1a0c, 0x0d79, 0x002b, 0x012e, 0x0005, 0x04b0, 0x012e, 0x0005,
+ 0x142c, 0x1452, 0x1482, 0x1487, 0x148b, 0x1490, 0x14b8, 0x14bc,
+ 0x14ca, 0x14ce, 0x142c, 0x159b, 0x159f, 0x1611, 0x1618, 0x142c,
+ 0x1619, 0x161a, 0x1625, 0x162c, 0x142c, 0x142c, 0x142c, 0x142c,
+ 0x142c, 0x142c, 0x142c, 0x1492, 0x142c, 0x145a, 0x147f, 0x1446,
+ 0x142c, 0x1466, 0x1430, 0x142e, 0x080c, 0x0d79, 0x080c, 0x0d72,
+ 0x080c, 0x1637, 0x2009, 0x1a7e, 0x2104, 0x8000, 0x200a, 0x080c,
+ 0x8151, 0x080c, 0x1b3b, 0x0005, 0x6044, 0xd0fc, 0x190c, 0xab20,
+ 0x2009, 0x0055, 0x080c, 0xafec, 0x012e, 0x0005, 0x080c, 0x1637,
+ 0x2060, 0x6044, 0xd0fc, 0x190c, 0xab20, 0x2009, 0x0055, 0x080c,
+ 0xafec, 0x0005, 0x2009, 0x0048, 0x080c, 0x1637, 0x2060, 0x080c,
+ 0xafec, 0x0005, 0x2009, 0x0054, 0x080c, 0x1637, 0x2060, 0x6044,
+ 0xd0fc, 0x190c, 0xab20, 0x080c, 0xafec, 0x0005, 0x080c, 0x1637,
+ 0x2060, 0x0056, 0x0066, 0x080c, 0x1637, 0x2028, 0x080c, 0x1637,
+ 0x2030, 0x0036, 0x0046, 0x2021, 0x0000, 0x2418, 0x2009, 0x0056,
+ 0x080c, 0xafec, 0x004e, 0x003e, 0x006e, 0x005e, 0x0005, 0x080c,
+ 0x1637, 0x0005, 0x7004, 0xc085, 0xc0b5, 0x7006, 0x0005, 0x7004,
+ 0xc085, 0x7006, 0x0005, 0x080c, 0x1637, 0x080c, 0x1734, 0x0005,
+ 0x080c, 0x0d79, 0x080c, 0x1637, 0x2060, 0x6014, 0x0096, 0x2048,
+ 0xa83b, 0xffff, 0x009e, 0x2009, 0x0048, 0x080c, 0xafec, 0x2001,
+ 0x015d, 0x2003, 0x0000, 0x2009, 0x03e8, 0x8109, 0x0160, 0x2001,
+ 0x0201, 0x2004, 0x9005, 0x0dc8, 0x2001, 0x0218, 0x2004, 0xd0ec,
+ 0x1110, 0x080c, 0x163c, 0x2001, 0x0307, 0x2003, 0x8000, 0x0005,
+ 0x7004, 0xc095, 0x7006, 0x0005, 0x080c, 0x1637, 0x2060, 0x6014,
+ 0x0096, 0x2048, 0xa83b, 0xffff, 0x009e, 0x2009, 0x0048, 0x080c,
+ 0xafec, 0x0005, 0x080c, 0x1637, 0x080c, 0x0d79, 0x080c, 0x1637,
+ 0x080c, 0x1586, 0x7827, 0x0018, 0x79ac, 0xd1dc, 0x0904, 0x1537,
+ 0x7827, 0x0015, 0x7828, 0x782b, 0x0000, 0x9065, 0x0140, 0x2001,
+ 0x020d, 0x2003, 0x0050, 0x2003, 0x0020, 0x0804, 0x153d, 0x7004,
+ 0x9005, 0x01c8, 0x1188, 0x78ab, 0x0004, 0x7827, 0x0018, 0x782b,
+ 0x0000, 0xd1bc, 0x090c, 0x0d79, 0x2001, 0x020d, 0x2003, 0x0050,
+ 0x2003, 0x0020, 0x0804, 0x156b, 0x78ab, 0x0004, 0x7803, 0x0001,
+ 0x080c, 0x159f, 0x0005, 0x7827, 0x0018, 0xa001, 0x7828, 0x7827,
+ 0x0011, 0xa001, 0x7928, 0x9106, 0x0110, 0x79ac, 0x08e0, 0x00e6,
+ 0x2071, 0x0200, 0x702c, 0xd0c4, 0x0140, 0x00ee, 0x080c, 0x1b3b,
+ 0x080c, 0x135a, 0x7803, 0x0001, 0x0005, 0x7037, 0x0001, 0xa001,
+ 0x7150, 0x00ee, 0x918c, 0xff00, 0x9186, 0x0500, 0x0110, 0x79ac,
+ 0x0810, 0x7004, 0xc09d, 0x7006, 0x78ab, 0x0004, 0x7803, 0x0001,
+ 0x080c, 0x159f, 0x2001, 0x020d, 0x2003, 0x0020, 0x0005, 0x7828,
+ 0x782b, 0x0000, 0x9065, 0x090c, 0x0d79, 0x6014, 0x2048, 0x78ab,
+ 0x0004, 0x918c, 0x0700, 0x01a8, 0x080c, 0x8151, 0x080c, 0x1b3b,
+ 0x080c, 0xcc33, 0x0158, 0xa9ac, 0xa936, 0xa9b0, 0xa93a, 0xa83f,
+ 0xffff, 0xa843, 0xffff, 0xa880, 0xc0bd, 0xa882, 0x080c, 0xc81b,
+ 0x0005, 0x6020, 0x9086, 0x0009, 0x1128, 0x2009, 0x004c, 0x080c,
+ 0xafec, 0x0048, 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc,
+ 0x6024, 0x190c, 0xd036, 0x2029, 0x00c8, 0x8529, 0x0128, 0x2001,
+ 0x0201, 0x2004, 0x9005, 0x0dc8, 0x7dbc, 0x080c, 0xebc0, 0xd5a4,
+ 0x1118, 0x080c, 0x163c, 0x0005, 0x080c, 0x8151, 0x080c, 0x1b3b,
+ 0x0005, 0x781f, 0x0300, 0x7803, 0x0001, 0x0005, 0x0016, 0x0066,
+ 0x0076, 0x00f6, 0x2079, 0x0300, 0x7908, 0x918c, 0x0007, 0x9186,
+ 0x0003, 0x0120, 0x2001, 0x0016, 0x080c, 0x16ad, 0x00fe, 0x007e,
+ 0x006e, 0x001e, 0x0005, 0x7004, 0xc09d, 0x7006, 0x0005, 0x7104,
+ 0x9184, 0x0004, 0x190c, 0x0d79, 0xd184, 0x11b1, 0xd19c, 0x0180,
+ 0xc19c, 0x7106, 0x0016, 0x080c, 0x1717, 0x001e, 0x0148, 0x2001,
+ 0x020d, 0x2003, 0x0050, 0x2003, 0x0020, 0x080c, 0x163c, 0x0005,
+ 0x81ff, 0x190c, 0x0d79, 0x0005, 0x2100, 0xc184, 0xc1b4, 0x7106,
+ 0xd0b4, 0x0016, 0x00e6, 0x1904, 0x1606, 0x2071, 0x0200, 0x080c,
+ 0x1704, 0x05e0, 0x080c, 0x1717, 0x05b0, 0x6014, 0x9005, 0x05b0,
+ 0x0096, 0x2048, 0xa864, 0x009e, 0x9084, 0x00ff, 0x908e, 0x0029,
+ 0x0160, 0x908e, 0x0048, 0x1550, 0x601c, 0xd084, 0x11e0, 0x00f6,
+ 0x2c78, 0x080c, 0x17a1, 0x00fe, 0x00b0, 0x00f6, 0x2c78, 0x080c,
+ 0x192a, 0x00fe, 0x2009, 0x01f4, 0x8109, 0x0168, 0x2001, 0x0201,
+ 0x2004, 0x9005, 0x0dc8, 0x2001, 0x0218, 0x2004, 0xd0ec, 0x1118,
+ 0x080c, 0x163c, 0x0040, 0x2001, 0x020d, 0x2003, 0x0020, 0x080c,
+ 0x135a, 0x7803, 0x0001, 0x00ee, 0x001e, 0x0005, 0x080c, 0x1717,
+ 0x0dd0, 0x2001, 0x020d, 0x2003, 0x0050, 0x2003, 0x0020, 0x0461,
+ 0x0c90, 0x0429, 0x2060, 0x2009, 0x0053, 0x080c, 0xafec, 0x0005,
+ 0x0005, 0x0005, 0x00e1, 0x2008, 0x00d1, 0x0006, 0x7004, 0xc09d,
+ 0x7006, 0x000e, 0x080c, 0x916f, 0x0005, 0x0089, 0x9005, 0x0118,
+ 0x080c, 0x8d72, 0x0cd0, 0x0005, 0x2001, 0x0036, 0x2009, 0x1820,
+ 0x210c, 0x2011, 0x181f, 0x2214, 0x080c, 0x16ad, 0x0005, 0x7808,
+ 0xd09c, 0x0de8, 0x7820, 0x0005, 0x080c, 0x1586, 0x00d6, 0x2069,
+ 0x0200, 0x2009, 0x01f4, 0x8109, 0x0510, 0x6804, 0x9005, 0x0dd8,
+ 0x2001, 0x015d, 0x2003, 0x0000, 0x79bc, 0xd1a4, 0x1528, 0x79b8,
+ 0x918c, 0x0fff, 0x0180, 0x9182, 0x0841, 0x1268, 0x9188, 0x0007,
+ 0x918c, 0x0ff8, 0x810c, 0x810c, 0x810c, 0x080c, 0x169f, 0x6827,
+ 0x0001, 0x8109, 0x1dd0, 0x04d9, 0x6827, 0x0002, 0x04c1, 0x6804,
+ 0x9005, 0x1130, 0x682c, 0xd0e4, 0x1500, 0x6804, 0x9005, 0x0de8,
+ 0x79b8, 0xd1ec, 0x1130, 0x08c0, 0x080c, 0x8151, 0x080c, 0x1b3b,
+ 0x0090, 0x7827, 0x0015, 0x782b, 0x0000, 0x7827, 0x0018, 0x782b,
+ 0x0000, 0x2001, 0x020d, 0x2003, 0x0020, 0x2001, 0x0307, 0x2003,
+ 0x0300, 0x7803, 0x0001, 0x00de, 0x0005, 0x682c, 0x9084, 0x5400,
+ 0x9086, 0x5400, 0x0d30, 0x7827, 0x0015, 0x782b, 0x0000, 0x7803,
+ 0x0001, 0x6800, 0x9085, 0x1800, 0x6802, 0x00de, 0x0005, 0x6824,
+ 0x9084, 0x0003, 0x1de0, 0x0005, 0x2001, 0x0030, 0x2c08, 0x621c,
+ 0x0021, 0x7830, 0x9086, 0x0041, 0x0005, 0x00f6, 0x00e6, 0x2079,
+ 0x0300, 0x0006, 0x2071, 0x1a6f, 0x7008, 0x9005, 0x1110, 0x78e3,
+ 0x0c0c, 0x8000, 0x700a, 0x0026, 0x2011, 0x0006, 0x7808, 0xd09c,
+ 0x0150, 0x0016, 0x0026, 0x00c6, 0x080c, 0x13c8, 0x00ce, 0x002e,
+ 0x001e, 0x8211, 0x1d98, 0x002e, 0x000e, 0x0006, 0x7832, 0x7936,
+ 0x7a3a, 0x781b, 0x8080, 0x00b9, 0x1178, 0x2071, 0x1a6f, 0x7008,
+ 0x9005, 0x0130, 0x8001, 0x0a0c, 0x0d79, 0x700a, 0x78e3, 0x0c00,
+ 0x000e, 0x00ee, 0x00fe, 0x0005, 0x000e, 0x792c, 0x3900, 0x8000,
+ 0x2004, 0x080c, 0x0d79, 0x2009, 0xff00, 0x8109, 0x0120, 0x7818,
+ 0xd0bc, 0x1dd8, 0x0005, 0x9085, 0x0001, 0x0005, 0x7832, 0x7936,
+ 0x7a3a, 0x781b, 0x8080, 0x0c79, 0x1108, 0x0005, 0x792c, 0x3900,
+ 0x8000, 0x2004, 0x080c, 0x0d79, 0x7037, 0x0001, 0x7150, 0x7037,
+ 0x0002, 0x7050, 0x2060, 0xd1bc, 0x1110, 0x7054, 0x2060, 0x918c,
+ 0xff00, 0x9186, 0x0500, 0x0110, 0x9085, 0x0001, 0x0005, 0x0006,
+ 0x0046, 0x00e6, 0x2071, 0x0200, 0x7037, 0x0002, 0x7058, 0x9084,
+ 0xff00, 0x8007, 0x9086, 0x00bc, 0x1158, 0x2021, 0x1a7f, 0x2404,
+ 0x8000, 0x0208, 0x2022, 0x080c, 0x8151, 0x080c, 0x1b3b, 0x9006,
+ 0x00ee, 0x004e, 0x000e, 0x0005, 0x0c11, 0x1108, 0x0005, 0x00e6,
+ 0x0016, 0x2071, 0x0200, 0x0841, 0x6124, 0xd1dc, 0x01f8, 0x701c,
+ 0xd08c, 0x0904, 0x1796, 0x7017, 0x0000, 0x2001, 0x0264, 0x2004,
+ 0xd0bc, 0x0904, 0x1796, 0x2001, 0x0268, 0x00c6, 0x2064, 0x6104,
+ 0x6038, 0x00ce, 0x918e, 0x0039, 0x1904, 0x1796, 0x9c06, 0x15f0,
+ 0x0126, 0x2091, 0x2600, 0x080c, 0x80a9, 0x012e, 0x7358, 0x745c,
+ 0x6014, 0x905d, 0x0598, 0x2b48, 0x6010, 0x00b6, 0x2058, 0xb800,
+ 0x00be, 0xd0bc, 0x190c, 0xd011, 0xab42, 0xac3e, 0x2001, 0x1869,
+ 0x2004, 0xd0b4, 0x1170, 0x601c, 0xd0e4, 0x1158, 0x6010, 0x00b6,
+ 0x2058, 0xb800, 0x00be, 0xd0bc, 0x1120, 0xa83b, 0x7fff, 0xa837,
+ 0xffff, 0x080c, 0x1efe, 0x1190, 0x080c, 0x1987, 0x2a00, 0xa816,
+ 0x0130, 0x2800, 0xa80e, 0x2c05, 0xa80a, 0x2c00, 0xa812, 0x7037,
+ 0x0020, 0x781f, 0x0300, 0x001e, 0x00ee, 0x0005, 0x7037, 0x0050,
+ 0x7037, 0x0020, 0x001e, 0x00ee, 0x080c, 0x163c, 0x0005, 0x080c,
+ 0x0d79, 0x2cf0, 0x0126, 0x2091, 0x2200, 0x0016, 0x00c6, 0x3e60,
+ 0x6014, 0x2048, 0x2940, 0x903e, 0x2730, 0xa864, 0x2068, 0xa81a,
+ 0x9d84, 0x000f, 0x9088, 0x1ede, 0x2165, 0x0002, 0x17cd, 0x183b,
+ 0x17cd, 0x17cd, 0x17d1, 0x181c, 0x17cd, 0x17f1, 0x17c6, 0x1832,
+ 0x17cd, 0x17cd, 0x17d6, 0x1928, 0x1805, 0x17fb, 0xa964, 0x918c,
+ 0x00ff, 0x918e, 0x0048, 0x0904, 0x1832, 0x9085, 0x0001, 0x0804,
+ 0x191e, 0xa87c, 0xd0ac, 0x0dc8, 0x0804, 0x1842, 0xa87c, 0xd0ac,
+ 0x0da0, 0x0804, 0x18ad, 0xa898, 0x901d, 0x1108, 0xab9c, 0x9016,
+ 0xaab2, 0xaa3e, 0xaa42, 0x3e00, 0x9080, 0x0008, 0x2004, 0x9080,
+ 0x933f, 0x2005, 0x9005, 0x090c, 0x0d79, 0x2004, 0xa8ae, 0x0804,
+ 0x1906, 0xa87c, 0xd0bc, 0x09c8, 0xa890, 0xa842, 0xa88c, 0xa83e,
+ 0xa888, 0x0804, 0x1842, 0xa87c, 0xd0bc, 0x0978, 0xa890, 0xa842,
+ 0xa88c, 0xa83e, 0xa888, 0x0804, 0x18ad, 0xa87c, 0xd0bc, 0x0928,
+ 0xa890, 0xa842, 0xa88c, 0xa83e, 0xa804, 0x9045, 0x090c, 0x0d79,
+ 0xa164, 0xa91a, 0x91ec, 0x000f, 0x9d80, 0x1ede, 0x2065, 0xa888,
+ 0xd19c, 0x1904, 0x18ad, 0x0430, 0xa87c, 0xd0ac, 0x0904, 0x17cd,
+ 0xa804, 0x9045, 0x090c, 0x0d79, 0xa164, 0xa91a, 0x91ec, 0x000f,
+ 0x9d80, 0x1ede, 0x2065, 0x9006, 0xa842, 0xa83e, 0xd19c, 0x1904,
+ 0x18ad, 0x0080, 0xa87c, 0xd0ac, 0x0904, 0x17cd, 0x9006, 0xa842,
+ 0xa83e, 0x0804, 0x18ad, 0xa87c, 0xd0ac, 0x0904, 0x17cd, 0x9006,
+ 0xa842, 0xa83e, 0x2c05, 0x908a, 0x0036, 0x1a0c, 0x0d79, 0x9082,
+ 0x001b, 0x0002, 0x1865, 0x1865, 0x1867, 0x1865, 0x1865, 0x1865,
+ 0x1871, 0x1865, 0x1865, 0x1865, 0x187b, 0x1865, 0x1865, 0x1865,
+ 0x1885, 0x1865, 0x1865, 0x1865, 0x188f, 0x1865, 0x1865, 0x1865,
+ 0x1899, 0x1865, 0x1865, 0x1865, 0x18a3, 0x080c, 0x0d79, 0xa574,
+ 0xa478, 0x9d86, 0x0024, 0x0904, 0x17db, 0xa37c, 0xa280, 0x0804,
+ 0x1906, 0xa584, 0xa488, 0x9d86, 0x0024, 0x0904, 0x17db, 0xa38c,
+ 0xa290, 0x0804, 0x1906, 0xa594, 0xa498, 0x9d86, 0x0024, 0x0904,
+ 0x17db, 0xa39c, 0xa2a0, 0x0804, 0x1906, 0xa5a4, 0xa4a8, 0x9d86,
+ 0x0024, 0x0904, 0x17db, 0xa3ac, 0xa2b0, 0x0804, 0x1906, 0xa5b4,
+ 0xa4b8, 0x9d86, 0x0024, 0x0904, 0x17db, 0xa3bc, 0xa2c0, 0x0804,
+ 0x1906, 0xa5c4, 0xa4c8, 0x9d86, 0x0024, 0x0904, 0x17db, 0xa3cc,
+ 0xa2d0, 0x0804, 0x1906, 0xa5d4, 0xa4d8, 0x9d86, 0x0024, 0x0904,
+ 0x17db, 0xa3dc, 0xa2e0, 0x0804, 0x1906, 0x2c05, 0x908a, 0x0034,
+ 0x1a0c, 0x0d79, 0x9082, 0x001b, 0x0002, 0x18d0, 0x18ce, 0x18ce,
+ 0x18ce, 0x18ce, 0x18ce, 0x18db, 0x18ce, 0x18ce, 0x18ce, 0x18ce,
+ 0x18ce, 0x18e6, 0x18ce, 0x18ce, 0x18ce, 0x18ce, 0x18ce, 0x18f1,
+ 0x18ce, 0x18ce, 0x18ce, 0x18ce, 0x18ce, 0x18fc, 0x080c, 0x0d79,
+ 0xa56c, 0xa470, 0xa774, 0xa678, 0x9d86, 0x002c, 0x0904, 0x17db,
+ 0xa37c, 0xa280, 0x0458, 0xa584, 0xa488, 0xa78c, 0xa690, 0x9d86,
+ 0x002c, 0x0904, 0x17db, 0xa394, 0xa298, 0x0400, 0xa59c, 0xa4a0,
+ 0xa7a4, 0xa6a8, 0x9d86, 0x002c, 0x0904, 0x17db, 0xa3ac, 0xa2b0,
+ 0x00a8, 0xa5b4, 0xa4b8, 0xa7bc, 0xa6c0, 0x9d86, 0x002c, 0x0904,
+ 0x17db, 0xa3c4, 0xa2c8, 0x0050, 0xa5cc, 0xa4d0, 0xa7d4, 0xa6d8,
+ 0x9d86, 0x002c, 0x0904, 0x17db, 0xa3dc, 0xa2e0, 0xab2e, 0xaa32,
+ 0xad1e, 0xac22, 0xaf26, 0xae2a, 0xa988, 0x8c60, 0x2c1d, 0xa8ac,
+ 0xaab0, 0xa836, 0xaa3a, 0x8109, 0xa916, 0x1160, 0x3e60, 0x601c,
+ 0xc085, 0x601e, 0xa87c, 0xc0dd, 0xa87e, 0x9006, 0x00ce, 0x001e,
+ 0x012e, 0x0005, 0x2800, 0xa80e, 0xab0a, 0x2c00, 0xa812, 0x0c70,
+ 0x0804, 0x17cd, 0x2ff0, 0x0126, 0x2091, 0x2200, 0x0016, 0x00c6,
+ 0x3e60, 0x6014, 0x2048, 0x2940, 0xa80e, 0x2061, 0x1ed9, 0xa813,
+ 0x1ed9, 0x2c05, 0xa80a, 0xa964, 0xa91a, 0xa87c, 0xd0ac, 0x090c,
+ 0x0d79, 0x9006, 0xa842, 0xa83e, 0x2c05, 0x908a, 0x0034, 0x1a0c,
+ 0x0d79, 0xadcc, 0xacd0, 0xafd4, 0xaed8, 0xabdc, 0xaae0, 0xab2e,
+ 0xaa32, 0xad1e, 0xac22, 0xaf26, 0xae2a, 0xa8ac, 0xaab0, 0xa836,
+ 0xaa3a, 0xa988, 0xa864, 0x9084, 0x00ff, 0x9086, 0x0008, 0x1120,
+ 0x8109, 0xa916, 0x0128, 0x0080, 0x918a, 0x0002, 0xa916, 0x1160,
+ 0x3e60, 0x601c, 0xc085, 0x601e, 0xa87c, 0xc0dd, 0xa87e, 0x9006,
+ 0x00ce, 0x001e, 0x012e, 0x0005, 0xa804, 0x9045, 0x090c, 0x0d79,
+ 0xa80e, 0xa064, 0xa81a, 0x9084, 0x000f, 0x9080, 0x1ede, 0x2015,
+ 0x82ff, 0x090c, 0x0d79, 0xaa12, 0x2205, 0xa80a, 0x0c08, 0x903e,
+ 0x2730, 0xa880, 0xd0fc, 0x1190, 0x2d00, 0x0002, 0x1ab1, 0x19de,
+ 0x19de, 0x1ab1, 0x19de, 0x1aab, 0x1ab1, 0x19de, 0x1a4e, 0x1a4e,
+ 0x1a4e, 0x1ab1, 0x1a4e, 0x1ab1, 0x1aa8, 0x1a4e, 0xc0fc, 0xa882,
+ 0xab2c, 0xaa30, 0xad1c, 0xac20, 0xdd9c, 0x0904, 0x1ab3, 0x2c05,
+ 0x908a, 0x0034, 0x1a0c, 0x0d79, 0x9082, 0x001b, 0x0002, 0x19ca,
+ 0x19c8, 0x19c8, 0x19c8, 0x19c8, 0x19c8, 0x19ce, 0x19c8, 0x19c8,
+ 0x19c8, 0x19c8, 0x19c8, 0x19d2, 0x19c8, 0x19c8, 0x19c8, 0x19c8,
+ 0x19c8, 0x19d6, 0x19c8, 0x19c8, 0x19c8, 0x19c8, 0x19c8, 0x19da,
+ 0x080c, 0x0d79, 0xa774, 0xa678, 0x0804, 0x1ab3, 0xa78c, 0xa690,
+ 0x0804, 0x1ab3, 0xa7a4, 0xa6a8, 0x0804, 0x1ab3, 0xa7bc, 0xa6c0,
+ 0x0804, 0x1ab3, 0xa7d4, 0xa6d8, 0x0804, 0x1ab3, 0xa898, 0x901d,
+ 0x1108, 0xab9c, 0x9016, 0x2c05, 0x908a, 0x0036, 0x1a0c, 0x0d79,
+ 0x9082, 0x001b, 0x0002, 0x1a06, 0x1a06, 0x1a08, 0x1a06, 0x1a06,
+ 0x1a06, 0x1a12, 0x1a06, 0x1a06, 0x1a06, 0x1a1c, 0x1a06, 0x1a06,
+ 0x1a06, 0x1a26, 0x1a06, 0x1a06, 0x1a06, 0x1a30, 0x1a06, 0x1a06,
+ 0x1a06, 0x1a3a, 0x1a06, 0x1a06, 0x1a06, 0x1a44, 0x080c, 0x0d79,
+ 0xa574, 0xa478, 0x9d86, 0x0004, 0x0904, 0x1ab3, 0xa37c, 0xa280,
+ 0x0804, 0x1ab3, 0xa584, 0xa488, 0x9d86, 0x0004, 0x0904, 0x1ab3,
+ 0xa38c, 0xa290, 0x0804, 0x1ab3, 0xa594, 0xa498, 0x9d86, 0x0004,
+ 0x0904, 0x1ab3, 0xa39c, 0xa2a0, 0x0804, 0x1ab3, 0xa5a4, 0xa4a8,
+ 0x9d86, 0x0004, 0x0904, 0x1ab3, 0xa3ac, 0xa2b0, 0x0804, 0x1ab3,
+ 0xa5b4, 0xa4b8, 0x9d86, 0x0004, 0x0904, 0x1ab3, 0xa3bc, 0xa2c0,
+ 0x0804, 0x1ab3, 0xa5c4, 0xa4c8, 0x9d86, 0x0004, 0x0904, 0x1ab3,
+ 0xa3cc, 0xa2d0, 0x0804, 0x1ab3, 0xa5d4, 0xa4d8, 0x9d86, 0x0004,
+ 0x0904, 0x1ab3, 0xa3dc, 0xa2e0, 0x0804, 0x1ab3, 0xa898, 0x901d,
+ 0x1108, 0xab9c, 0x9016, 0x2c05, 0x908a, 0x0034, 0x1a0c, 0x0d79,
+ 0x9082, 0x001b, 0x0002, 0x1a76, 0x1a74, 0x1a74, 0x1a74, 0x1a74,
+ 0x1a74, 0x1a80, 0x1a74, 0x1a74, 0x1a74, 0x1a74, 0x1a74, 0x1a8a,
+ 0x1a74, 0x1a74, 0x1a74, 0x1a74, 0x1a74, 0x1a94, 0x1a74, 0x1a74,
+ 0x1a74, 0x1a74, 0x1a74, 0x1a9e, 0x080c, 0x0d79, 0xa56c, 0xa470,
+ 0xa774, 0xa678, 0x9d86, 0x000c, 0x05b0, 0xa37c, 0xa280, 0x0498,
+ 0xa584, 0xa488, 0xa78c, 0xa690, 0x9d86, 0x000c, 0x0560, 0xa394,
+ 0xa298, 0x0448, 0xa59c, 0xa4a0, 0xa7a4, 0xa6a8, 0x9d86, 0x000c,
+ 0x0510, 0xa3ac, 0xa2b0, 0x00f8, 0xa5b4, 0xa4b8, 0xa7bc, 0xa6c0,
+ 0x9d86, 0x000c, 0x01c0, 0xa3c4, 0xa2c8, 0x00a8, 0xa5cc, 0xa4d0,
+ 0xa7d4, 0xa6d8, 0x9d86, 0x000c, 0x0170, 0xa3dc, 0xa2e0, 0x0058,
+ 0x9d86, 0x000e, 0x1130, 0x080c, 0x1eb4, 0x1904, 0x1987, 0x900e,
+ 0x0050, 0x080c, 0x0d79, 0xab2e, 0xaa32, 0xad1e, 0xac22, 0xaf26,
+ 0xae2a, 0x080c, 0x1eb4, 0x0005, 0x6014, 0x2048, 0x6118, 0x81ff,
+ 0x0148, 0x810c, 0x810c, 0x810c, 0x81ff, 0x1118, 0xa887, 0x0001,
+ 0x0008, 0xa986, 0x601b, 0x0002, 0xa874, 0x9084, 0x00ff, 0x9084,
+ 0x0008, 0x0150, 0x00e9, 0x6000, 0x9086, 0x0004, 0x1120, 0x2009,
+ 0x0048, 0x080c, 0xafec, 0x0005, 0xa974, 0xd1dc, 0x1108, 0x0005,
+ 0xa934, 0xa88c, 0x9106, 0x1158, 0xa938, 0xa890, 0x9106, 0x1138,
+ 0x601c, 0xc084, 0x601e, 0x2009, 0x0048, 0x0804, 0xafec, 0x0005,
+ 0x0126, 0x00c6, 0x2091, 0x2200, 0x00ce, 0x7908, 0x918c, 0x0007,
+ 0x9186, 0x0000, 0x05b0, 0x9186, 0x0003, 0x0598, 0x6020, 0x6023,
+ 0x0000, 0x0006, 0x2031, 0x0008, 0x00c6, 0x781f, 0x0808, 0x7808,
+ 0xd09c, 0x0120, 0x080c, 0x13c8, 0x8631, 0x1db8, 0x00ce, 0x781f,
+ 0x0800, 0x2031, 0x0168, 0x00c6, 0x7808, 0xd09c, 0x190c, 0x13c8,
+ 0x00ce, 0x2001, 0x0038, 0x080c, 0x1bcb, 0x7930, 0x9186, 0x0040,
+ 0x0160, 0x9186, 0x0042, 0x190c, 0x0d79, 0x2001, 0x001e, 0x8001,
+ 0x1df0, 0x8631, 0x1d40, 0x080c, 0x1bda, 0x000e, 0x6022, 0x012e,
+ 0x0005, 0x080c, 0x1bc7, 0x7827, 0x0015, 0x7828, 0x9c06, 0x1db8,
+ 0x782b, 0x0000, 0x0ca0, 0x00f6, 0x2079, 0x0300, 0x7803, 0x0000,
+ 0x78ab, 0x0004, 0x2001, 0xf000, 0x8001, 0x090c, 0x0d79, 0x7aac,
+ 0xd2ac, 0x1dd0, 0x00fe, 0x080c, 0x769d, 0x1188, 0x2001, 0x0138,
+ 0x2003, 0x0000, 0x2001, 0x0160, 0x2003, 0x0000, 0x2011, 0x012c,
+ 0xa001, 0xa001, 0x8211, 0x1de0, 0x0059, 0x0804, 0x773f, 0x0479,
+ 0x0039, 0x2001, 0x0160, 0x2502, 0x2001, 0x0138, 0x2202, 0x0005,
+ 0x00e6, 0x2071, 0x0200, 0x080c, 0x2a94, 0x2009, 0x003c, 0x080c,
+ 0x223d, 0x2001, 0x015d, 0x2003, 0x0000, 0x7000, 0x9084, 0x003c,
+ 0x1de0, 0x080c, 0x8732, 0x70a0, 0x70a2, 0x7098, 0x709a, 0x709c,
+ 0x709e, 0x2001, 0x020d, 0x2003, 0x0020, 0x00f6, 0x2079, 0x0300,
+ 0x080c, 0x135a, 0x7803, 0x0001, 0x00fe, 0x00ee, 0x0005, 0x2001,
+ 0x0138, 0x2014, 0x2003, 0x0000, 0x2001, 0x0160, 0x202c, 0x2003,
+ 0x0000, 0x080c, 0x769d, 0x1108, 0x0005, 0x2021, 0x0260, 0x2001,
+ 0x0141, 0x201c, 0xd3dc, 0x1168, 0x2001, 0x0109, 0x201c, 0x939c,
+ 0x0048, 0x1160, 0x2001, 0x0111, 0x201c, 0x83ff, 0x1110, 0x8421,
+ 0x1d70, 0x2001, 0x015d, 0x2003, 0x0000, 0x0005, 0x0046, 0x2021,
+ 0x0019, 0x2003, 0x0048, 0xa001, 0xa001, 0x201c, 0x939c, 0x0048,
+ 0x0120, 0x8421, 0x1db0, 0x004e, 0x0c60, 0x004e, 0x0c40, 0x601c,
+ 0xc084, 0x601e, 0x0005, 0x2c08, 0x621c, 0x080c, 0x16ad, 0x7930,
+ 0x0005, 0x2c08, 0x621c, 0x080c, 0x16f6, 0x7930, 0x0005, 0x8001,
+ 0x1df0, 0x0005, 0x2031, 0x0064, 0x781c, 0x9084, 0x0007, 0x0170,
+ 0x2001, 0x0038, 0x0c41, 0x9186, 0x0040, 0x0904, 0x1c38, 0x2001,
+ 0x001e, 0x0c69, 0x8631, 0x1d80, 0x080c, 0x0d79, 0x781f, 0x0202,
+ 0x2001, 0x015d, 0x2003, 0x0000, 0x2001, 0x0dac, 0x0c01, 0x781c,
+ 0xd084, 0x0110, 0x0861, 0x04e0, 0x2001, 0x0030, 0x0891, 0x9186,
+ 0x0040, 0x0568, 0x781c, 0xd084, 0x1da8, 0x781f, 0x0101, 0x2001,
+ 0x0014, 0x0869, 0x2001, 0x0037, 0x0821, 0x9186, 0x0040, 0x0140,
+ 0x2001, 0x0030, 0x080c, 0x1bd1, 0x9186, 0x0040, 0x190c, 0x0d79,
+ 0x00d6, 0x2069, 0x0200, 0x692c, 0xd1f4, 0x1170, 0xd1c4, 0x0160,
+ 0xd19c, 0x0130, 0x6800, 0x9085, 0x1800, 0x6802, 0x00de, 0x0080,
+ 0x6908, 0x9184, 0x0007, 0x1db0, 0x00de, 0x781f, 0x0100, 0x791c,
+ 0x9184, 0x0007, 0x090c, 0x0d79, 0xa001, 0xa001, 0x781f, 0x0200,
+ 0x0005, 0x0126, 0x2091, 0x2400, 0x2079, 0x0380, 0x2001, 0x19e9,
+ 0x2070, 0x012e, 0x0005, 0x2cf0, 0x0126, 0x2091, 0x2400, 0x3e60,
+ 0x6014, 0x2048, 0xa964, 0xa91a, 0x918c, 0x00ff, 0x9184, 0x000f,
+ 0x0002, 0x1c6d, 0x1c6d, 0x1c6d, 0x1c6f, 0x1c6d, 0x1c6d, 0x1c6d,
+ 0x1c6d, 0x1c61, 0x1c77, 0x1c6d, 0x1c73, 0x1c6d, 0x1c6d, 0x1c6d,
+ 0x1c6d, 0x9086, 0x0008, 0x1148, 0xa87c, 0xd0b4, 0x0904, 0x1de7,
+ 0x2011, 0x1ed9, 0x2205, 0xab88, 0x00a8, 0x080c, 0x0d79, 0x9186,
+ 0x0013, 0x0128, 0x0cd0, 0x9186, 0x001b, 0x0108, 0x0cb0, 0xa87c,
+ 0xd0b4, 0x0904, 0x1de7, 0x9184, 0x000f, 0x9080, 0x1ede, 0x2015,
+ 0x2205, 0xab88, 0x2908, 0xa80a, 0xa90e, 0xaa12, 0xab16, 0x9006,
+ 0xa842, 0xa83e, 0x012e, 0x0005, 0x2cf0, 0x0126, 0x2091, 0x2400,
+ 0x3e60, 0x6014, 0x2048, 0xa88c, 0xa990, 0xaaac, 0xabb0, 0xaa36,
+ 0xab3a, 0xa83e, 0xa942, 0xa846, 0xa94a, 0xa964, 0x918c, 0x00ff,
+ 0x9186, 0x001e, 0x0198, 0x2940, 0xa064, 0xa81a, 0x90ec, 0x000f,
+ 0x9d80, 0x1ede, 0x2065, 0x2c05, 0x2808, 0x2c10, 0xab88, 0xa80a,
+ 0xa90e, 0xaa12, 0xab16, 0x012e, 0x3e60, 0x0005, 0xa804, 0x2040,
+ 0x0c58, 0x2cf0, 0x0126, 0x2091, 0x2400, 0x3e60, 0x6014, 0x2048,
+ 0xa97c, 0x2950, 0xd1dc, 0x1904, 0x1db1, 0xc1dd, 0xa97e, 0x9006,
+ 0xa842, 0xa83e, 0xa988, 0x8109, 0xa916, 0xa964, 0xa91a, 0x9184,
+ 0x000f, 0x9088, 0x1ede, 0x2145, 0x0002, 0x1ce5, 0x1cf3, 0x1ce5,
+ 0x1ce5, 0x1ce5, 0x1ce7, 0x1ce5, 0x1ce5, 0x1d48, 0x1d48, 0x1ce5,
+ 0x1ce5, 0x1ce5, 0x1d46, 0x1ce5, 0x1ce5, 0x080c, 0x0d79, 0xa804,
+ 0x2050, 0xb164, 0xa91a, 0x9184, 0x000f, 0x9080, 0x1ede, 0x2045,
+ 0xd19c, 0x1904, 0x1d48, 0x9036, 0x2638, 0x2805, 0x908a, 0x0036,
+ 0x1a0c, 0x0d79, 0x9082, 0x001b, 0x0002, 0x1d18, 0x1d18, 0x1d1a,
+ 0x1d18, 0x1d18, 0x1d18, 0x1d20, 0x1d18, 0x1d18, 0x1d18, 0x1d26,
+ 0x1d18, 0x1d18, 0x1d18, 0x1d2c, 0x1d18, 0x1d18, 0x1d18, 0x1d32,
+ 0x1d18, 0x1d18, 0x1d18, 0x1d38, 0x1d18, 0x1d18, 0x1d18, 0x1d3e,
+ 0x080c, 0x0d79, 0xb574, 0xb478, 0xb37c, 0xb280, 0x0804, 0x1d8d,
+ 0xb584, 0xb488, 0xb38c, 0xb290, 0x0804, 0x1d8d, 0xb594, 0xb498,
+ 0xb39c, 0xb2a0, 0x0804, 0x1d8d, 0xb5a4, 0xb4a8, 0xb3ac, 0xb2b0,
+ 0x0804, 0x1d8d, 0xb5b4, 0xb4b8, 0xb3bc, 0xb2c0, 0x0804, 0x1d8d,
+ 0xb5c4, 0xb4c8, 0xb3cc, 0xb2d0, 0x0804, 0x1d8d, 0xb5d4, 0xb4d8,
+ 0xb3dc, 0xb2e0, 0x0804, 0x1d8d, 0x0804, 0x1d8d, 0x080c, 0x0d79,
+ 0x2805, 0x908a, 0x0034, 0x1a0c, 0x0d79, 0x9082, 0x001b, 0x0002,
+ 0x1d6b, 0x1d69, 0x1d69, 0x1d69, 0x1d69, 0x1d69, 0x1d72, 0x1d69,
+ 0x1d69, 0x1d69, 0x1d69, 0x1d69, 0x1d79, 0x1d69, 0x1d69, 0x1d69,
+ 0x1d69, 0x1d69, 0x1d80, 0x1d69, 0x1d69, 0x1d69, 0x1d69, 0x1d69,
+ 0x1d87, 0x080c, 0x0d79, 0xb56c, 0xb470, 0xb774, 0xb678, 0xb37c,
+ 0xb280, 0x00d8, 0xb584, 0xb488, 0xb78c, 0xb690, 0xb394, 0xb298,
+ 0x00a0, 0xb59c, 0xb4a0, 0xb7a4, 0xb6a8, 0xb3ac, 0xb2b0, 0x0068,
+ 0xb5b4, 0xb4b8, 0xb7bc, 0xb6c0, 0xb3c4, 0xb2c8, 0x0030, 0xb5cc,
+ 0xb4d0, 0xb7d4, 0xb6d8, 0xb3dc, 0xb2e0, 0xab2e, 0xaa32, 0xad1e,
+ 0xac22, 0xaf26, 0xae2a, 0xa988, 0x8109, 0xa916, 0x1118, 0x9006,
+ 0x012e, 0x0005, 0x8840, 0x2805, 0x9005, 0x1168, 0xb004, 0x9005,
+ 0x090c, 0x0d79, 0x2050, 0xb164, 0xa91a, 0x9184, 0x000f, 0x9080,
+ 0x1ede, 0x2045, 0x2805, 0x2810, 0x2a08, 0xa80a, 0xa90e, 0xaa12,
+ 0x0c30, 0x3e60, 0x6344, 0xd3fc, 0x190c, 0x0d79, 0xa93c, 0xaa40,
+ 0xa844, 0x9106, 0x1118, 0xa848, 0x9206, 0x0508, 0x2958, 0xab48,
+ 0xac44, 0x2940, 0x080c, 0x1efe, 0x1998, 0x2850, 0x2c40, 0xab14,
+ 0xa880, 0xd0fc, 0x1140, 0xa810, 0x2005, 0xa80a, 0x2a00, 0xa80e,
+ 0x2009, 0x8015, 0x0070, 0x00c6, 0x3e60, 0x6044, 0xc0a4, 0x9085,
+ 0x8005, 0x6046, 0x00ce, 0x8319, 0xab16, 0x1904, 0x1d9a, 0x2009,
+ 0x8005, 0x3e60, 0x6044, 0x9105, 0x6046, 0x0804, 0x1d97, 0x080c,
+ 0x0d79, 0x00f6, 0x00e6, 0x0096, 0x00c6, 0x0026, 0x704c, 0x9c06,
+ 0x190c, 0x0d79, 0x2079, 0x0090, 0x2001, 0x0105, 0x2003, 0x0010,
+ 0x782b, 0x0004, 0x7057, 0x0000, 0x6014, 0x2048, 0x080c, 0xcc33,
+ 0x0118, 0xa880, 0xc0bd, 0xa882, 0x6020, 0x9086, 0x0006, 0x1170,
+ 0x2061, 0x0100, 0x62c8, 0x2001, 0x00fa, 0x8001, 0x1df0, 0x60c8,
+ 0x9206, 0x1dc0, 0x60c4, 0xa89a, 0x60c8, 0xa896, 0x704c, 0x2060,
+ 0x00c6, 0x080c, 0xc81b, 0x080c, 0xaaf7, 0x00ce, 0x704c, 0x9c06,
+ 0x1150, 0x2009, 0x0040, 0x080c, 0x223d, 0x080c, 0xa59c, 0x2011,
+ 0x0000, 0x080c, 0xa430, 0x002e, 0x00ce, 0x009e, 0x00ee, 0x00fe,
+ 0x0005, 0x00f6, 0x2079, 0x0090, 0x781c, 0x0006, 0x7818, 0x0006,
+ 0x2079, 0x0100, 0x7a14, 0x9284, 0x1984, 0x9085, 0x0012, 0x7816,
+ 0x2019, 0x1000, 0x8319, 0x090c, 0x0d79, 0x7820, 0xd0bc, 0x1dd0,
+ 0x79c8, 0x000e, 0x9102, 0x001e, 0x0006, 0x0016, 0x79c4, 0x000e,
+ 0x9103, 0x78c6, 0x000e, 0x78ca, 0x9284, 0x1984, 0x9085, 0x0012,
+ 0x7816, 0x2079, 0x0090, 0x782b, 0x0008, 0x7057, 0x0000, 0x00fe,
+ 0x0005, 0x00f6, 0x00e6, 0x2071, 0x19e9, 0x7054, 0x9086, 0x0000,
+ 0x0904, 0x1eaf, 0x2079, 0x0090, 0x2009, 0x0207, 0x210c, 0xd194,
+ 0x01b8, 0x2009, 0x020c, 0x210c, 0x9184, 0x0003, 0x0188, 0x080c,
+ 0xec09, 0x2001, 0x0133, 0x2004, 0x9005, 0x090c, 0x0d79, 0x0016,
+ 0x2009, 0x0040, 0x080c, 0x223d, 0x001e, 0x2001, 0x020c, 0x2102,
+ 0x2009, 0x0206, 0x2104, 0x2009, 0x0203, 0x210c, 0x9106, 0x1120,
+ 0x2009, 0x0040, 0x080c, 0x223d, 0x782c, 0xd0fc, 0x09a8, 0x080c,
+ 0xab13, 0x782c, 0xd0fc, 0x1de8, 0x080c, 0xaaf7, 0x7054, 0x9086,
+ 0x0000, 0x1950, 0x782b, 0x0004, 0x782c, 0xd0ac, 0x1de8, 0x2009,
+ 0x0040, 0x080c, 0x223d, 0x782b, 0x0002, 0x7057, 0x0000, 0x00ee,
+ 0x00fe, 0x0005, 0x080c, 0x0d79, 0x8c60, 0x2c05, 0x9005, 0x0110,
+ 0x8a51, 0x0005, 0xa004, 0x9005, 0x0168, 0xa85a, 0x2040, 0xa064,
+ 0x9084, 0x000f, 0x9080, 0x1ede, 0x2065, 0x8cff, 0x090c, 0x0d79,
+ 0x8a51, 0x0005, 0x2050, 0x0005, 0x0000, 0x001d, 0x0021, 0x0025,
+ 0x0029, 0x002d, 0x0031, 0x0035, 0x0000, 0x001b, 0x0021, 0x0027,
+ 0x002d, 0x0033, 0x0000, 0x0000, 0x0023, 0x0000, 0x0000, 0x1ed1,
+ 0x1ecd, 0x1ed1, 0x1ed1, 0x1edb, 0x0000, 0x1ed1, 0x1ed8, 0x1ed8,
+ 0x1ed5, 0x1ed8, 0x1ed8, 0x0000, 0x1edb, 0x1ed8, 0x0000, 0x1ed3,
+ 0x1ed3, 0x0000, 0x1ed3, 0x1edb, 0x0000, 0x1ed3, 0x1ed9, 0x1ed9,
+ 0x1ed9, 0x0000, 0x1ed9, 0x0000, 0x1edb, 0x1ed9, 0x00c6, 0x00d6,
+ 0x0086, 0xab42, 0xac3e, 0xa888, 0x9055, 0x0904, 0x20dd, 0x2940,
+ 0xa064, 0x90ec, 0x000f, 0x9084, 0x00ff, 0x9086, 0x0008, 0x1118,
+ 0x2061, 0x1ed9, 0x00d0, 0x9de0, 0x1ede, 0x9d86, 0x0007, 0x0130,
+ 0x9d86, 0x000e, 0x0118, 0x9d86, 0x000f, 0x1120, 0xa08c, 0x9422,
+ 0xa090, 0x931b, 0x2c05, 0x9065, 0x1140, 0x0310, 0x0804, 0x20dd,
+ 0xa004, 0x9045, 0x0904, 0x20dd, 0x08d8, 0x2c05, 0x9005, 0x0904,
+ 0x1fc5, 0xdd9c, 0x1904, 0x1f81, 0x908a, 0x0036, 0x1a0c, 0x0d79,
+ 0x9082, 0x001b, 0x0002, 0x1f56, 0x1f56, 0x1f58, 0x1f56, 0x1f56,
+ 0x1f56, 0x1f5e, 0x1f56, 0x1f56, 0x1f56, 0x1f64, 0x1f56, 0x1f56,
+ 0x1f56, 0x1f6a, 0x1f56, 0x1f56, 0x1f56, 0x1f70, 0x1f56, 0x1f56,
+ 0x1f56, 0x1f76, 0x1f56, 0x1f56, 0x1f56, 0x1f7c, 0x080c, 0x0d79,
+ 0xa07c, 0x9422, 0xa080, 0x931b, 0x0804, 0x1fbb, 0xa08c, 0x9422,
+ 0xa090, 0x931b, 0x0804, 0x1fbb, 0xa09c, 0x9422, 0xa0a0, 0x931b,
+ 0x0804, 0x1fbb, 0xa0ac, 0x9422, 0xa0b0, 0x931b, 0x0804, 0x1fbb,
+ 0xa0bc, 0x9422, 0xa0c0, 0x931b, 0x0804, 0x1fbb, 0xa0cc, 0x9422,
+ 0xa0d0, 0x931b, 0x0804, 0x1fbb, 0xa0dc, 0x9422, 0xa0e0, 0x931b,
+ 0x04d0, 0x908a, 0x0034, 0x1a0c, 0x0d79, 0x9082, 0x001b, 0x0002,
+ 0x1fa3, 0x1fa1, 0x1fa1, 0x1fa1, 0x1fa1, 0x1fa1, 0x1fa8, 0x1fa1,
+ 0x1fa1, 0x1fa1, 0x1fa1, 0x1fa1, 0x1fad, 0x1fa1, 0x1fa1, 0x1fa1,
+ 0x1fa1, 0x1fa1, 0x1fb2, 0x1fa1, 0x1fa1, 0x1fa1, 0x1fa1, 0x1fa1,
+ 0x1fb7, 0x080c, 0x0d79, 0xa07c, 0x9422, 0xa080, 0x931b, 0x0098,
+ 0xa094, 0x9422, 0xa098, 0x931b, 0x0070, 0xa0ac, 0x9422, 0xa0b0,
+ 0x931b, 0x0048, 0xa0c4, 0x9422, 0xa0c8, 0x931b, 0x0020, 0xa0dc,
+ 0x9422, 0xa0e0, 0x931b, 0x0630, 0x2300, 0x9405, 0x0160, 0x8a51,
+ 0x0904, 0x20dd, 0x8c60, 0x0804, 0x1f2d, 0xa004, 0x9045, 0x0904,
+ 0x20dd, 0x0804, 0x1f08, 0x8a51, 0x0904, 0x20dd, 0x8c60, 0x2c05,
+ 0x9005, 0x1158, 0xa004, 0x9045, 0x0904, 0x20dd, 0xa064, 0x90ec,
+ 0x000f, 0x9de0, 0x1ede, 0x2c05, 0x2060, 0xa880, 0xc0fc, 0xa882,
+ 0x0804, 0x20d2, 0x2c05, 0x8422, 0x8420, 0x831a, 0x9399, 0x0000,
+ 0xac2e, 0xab32, 0xdd9c, 0x1904, 0x206f, 0x9082, 0x001b, 0x0002,
+ 0x200b, 0x200b, 0x200d, 0x200b, 0x200b, 0x200b, 0x201b, 0x200b,
+ 0x200b, 0x200b, 0x2029, 0x200b, 0x200b, 0x200b, 0x2037, 0x200b,
+ 0x200b, 0x200b, 0x2045, 0x200b, 0x200b, 0x200b, 0x2053, 0x200b,
+ 0x200b, 0x200b, 0x2061, 0x080c, 0x0d79, 0xa17c, 0x2400, 0x9122,
+ 0xa180, 0x2300, 0x911b, 0x0a0c, 0x0d79, 0xa074, 0x9420, 0xa078,
+ 0x9319, 0x0804, 0x20cd, 0xa18c, 0x2400, 0x9122, 0xa190, 0x2300,
+ 0x911b, 0x0a0c, 0x0d79, 0xa084, 0x9420, 0xa088, 0x9319, 0x0804,
+ 0x20cd, 0xa19c, 0x2400, 0x9122, 0xa1a0, 0x2300, 0x911b, 0x0a0c,
+ 0x0d79, 0xa094, 0x9420, 0xa098, 0x9319, 0x0804, 0x20cd, 0xa1ac,
+ 0x2400, 0x9122, 0xa1b0, 0x2300, 0x911b, 0x0a0c, 0x0d79, 0xa0a4,
+ 0x9420, 0xa0a8, 0x9319, 0x0804, 0x20cd, 0xa1bc, 0x2400, 0x9122,
+ 0xa1c0, 0x2300, 0x911b, 0x0a0c, 0x0d79, 0xa0b4, 0x9420, 0xa0b8,
+ 0x9319, 0x0804, 0x20cd, 0xa1cc, 0x2400, 0x9122, 0xa1d0, 0x2300,
+ 0x911b, 0x0a0c, 0x0d79, 0xa0c4, 0x9420, 0xa0c8, 0x9319, 0x0804,
+ 0x20cd, 0xa1dc, 0x2400, 0x9122, 0xa1e0, 0x2300, 0x911b, 0x0a0c,
+ 0x0d79, 0xa0d4, 0x9420, 0xa0d8, 0x9319, 0x0804, 0x20cd, 0x9082,
+ 0x001b, 0x0002, 0x208d, 0x208b, 0x208b, 0x208b, 0x208b, 0x208b,
+ 0x209a, 0x208b, 0x208b, 0x208b, 0x208b, 0x208b, 0x20a7, 0x208b,
+ 0x208b, 0x208b, 0x208b, 0x208b, 0x20b4, 0x208b, 0x208b, 0x208b,
+ 0x208b, 0x208b, 0x20c1, 0x080c, 0x0d79, 0xa17c, 0x2400, 0x9122,
+ 0xa180, 0x2300, 0x911b, 0x0a0c, 0x0d79, 0xa06c, 0x9420, 0xa070,
+ 0x9319, 0x0498, 0xa194, 0x2400, 0x9122, 0xa198, 0x2300, 0x911b,
+ 0x0a0c, 0x0d79, 0xa084, 0x9420, 0xa088, 0x9319, 0x0430, 0xa1ac,
+ 0x2400, 0x9122, 0xa1b0, 0x2300, 0x911b, 0x0a0c, 0x0d79, 0xa09c,
+ 0x9420, 0xa0a0, 0x9319, 0x00c8, 0xa1c4, 0x2400, 0x9122, 0xa1c8,
+ 0x2300, 0x911b, 0x0a0c, 0x0d79, 0xa0b4, 0x9420, 0xa0b8, 0x9319,
+ 0x0060, 0xa1dc, 0x2400, 0x9122, 0xa1e0, 0x2300, 0x911b, 0x0a0c,
+ 0x0d79, 0xa0cc, 0x9420, 0xa0d0, 0x9319, 0xac1e, 0xab22, 0xa880,
+ 0xc0fd, 0xa882, 0x2800, 0xa85a, 0x2c00, 0xa812, 0x2a00, 0xa816,
+ 0x000e, 0x000e, 0x000e, 0x9006, 0x0028, 0x008e, 0x00de, 0x00ce,
+ 0x9085, 0x0001, 0x0005, 0x00c6, 0x610c, 0x0016, 0x9026, 0x2410,
+ 0x6004, 0x9420, 0x9291, 0x0000, 0x2c04, 0x9210, 0x9ce0, 0x0002,
+ 0x918a, 0x0002, 0x1da8, 0x9284, 0x000f, 0x9405, 0x001e, 0x00ce,
+ 0x0005, 0x7803, 0x0003, 0x780f, 0x0000, 0x6004, 0x7812, 0x2c04,
+ 0x7816, 0x9ce0, 0x0002, 0x918a, 0x0002, 0x1db8, 0x0005, 0x2001,
+ 0x0005, 0x2004, 0xd0bc, 0x190c, 0x0d72, 0xd094, 0x0110, 0x080c,
+ 0x11fc, 0x0005, 0x0126, 0x2091, 0x2600, 0x2079, 0x0200, 0x2071,
+ 0x0260, 0x2069, 0x1800, 0x7817, 0x0000, 0x789b, 0x0814, 0x78a3,
+ 0x0406, 0x789f, 0x0410, 0x2009, 0x013b, 0x200b, 0x0400, 0x781b,
+ 0x0002, 0x783b, 0x001f, 0x7837, 0x0020, 0x7803, 0x1600, 0x012e,
+ 0x0005, 0x2091, 0x2600, 0x781c, 0xd0a4, 0x190c, 0x223a, 0x7900,
+ 0xd1dc, 0x1118, 0x9084, 0x0006, 0x001a, 0x9084, 0x000e, 0x0002,
+ 0x2158, 0x2150, 0x80a9, 0x2150, 0x2152, 0x2152, 0x2152, 0x2152,
+ 0x808f, 0x2150, 0x2154, 0x2150, 0x2152, 0x2150, 0x2152, 0x2150,
+ 0x080c, 0x0d79, 0x0031, 0x0020, 0x080c, 0x808f, 0x080c, 0x80a9,
+ 0x0005, 0x0006, 0x0016, 0x0026, 0x080c, 0xec09, 0x7930, 0x9184,
+ 0x0003, 0x0510, 0x080c, 0xaaf7, 0x2001, 0x19fc, 0x2004, 0x9005,
+ 0x01a0, 0x2001, 0x0133, 0x2004, 0x9005, 0x090c, 0x0d79, 0x00c6,
+ 0x2001, 0x19fc, 0x2064, 0x080c, 0xab13, 0x080c, 0xc81b, 0x2009,
+ 0x0040, 0x080c, 0x223d, 0x00ce, 0x0408, 0x2009, 0x0040, 0x080c,
+ 0x223d, 0x080c, 0xab13, 0x00d0, 0x9184, 0x0014, 0x01a0, 0x6a00,
+ 0x9286, 0x0003, 0x0160, 0x080c, 0x769d, 0x1138, 0x080c, 0x799f,
+ 0x080c, 0x6178, 0x080c, 0x75cc, 0x0010, 0x080c, 0x6033, 0x080c,
+ 0x8147, 0x0041, 0x0018, 0x9184, 0x9540, 0x1dc8, 0x002e, 0x001e,
+ 0x000e, 0x0005, 0x00e6, 0x0036, 0x0046, 0x0056, 0x2071, 0x1a6f,
+ 0x080c, 0x1b3b, 0x005e, 0x004e, 0x003e, 0x00ee, 0x0005, 0x0126,
+ 0x2091, 0x2e00, 0x2071, 0x1800, 0x7128, 0x2001, 0x1970, 0x2102,
+ 0x2001, 0x1978, 0x2102, 0x2001, 0x013b, 0x2102, 0x2079, 0x0200,
+ 0x2001, 0x0201, 0x789e, 0x78a3, 0x0200, 0x9198, 0x0007, 0x831c,
+ 0x831c, 0x831c, 0x9398, 0x0005, 0x2320, 0x9182, 0x0204, 0x1230,
+ 0x2011, 0x0008, 0x8423, 0x8423, 0x8423, 0x0488, 0x9182, 0x024c,
+ 0x1240, 0x2011, 0x0007, 0x8403, 0x8003, 0x9400, 0x9400, 0x9420,
+ 0x0430, 0x9182, 0x02bc, 0x1238, 0x2011, 0x0006, 0x8403, 0x8003,
+ 0x9400, 0x9420, 0x00e0, 0x9182, 0x034c, 0x1230, 0x2011, 0x0005,
+ 0x8403, 0x8003, 0x9420, 0x0098, 0x9182, 0x042c, 0x1228, 0x2011,
+ 0x0004, 0x8423, 0x8423, 0x0058, 0x9182, 0x059c, 0x1228, 0x2011,
+ 0x0003, 0x8403, 0x9420, 0x0018, 0x2011, 0x0002, 0x8423, 0x9482,
+ 0x0228, 0x8002, 0x8020, 0x8301, 0x9402, 0x0110, 0x0208, 0x8321,
+ 0x8217, 0x8203, 0x9405, 0x789a, 0x012e, 0x0005, 0x0006, 0x00d6,
+ 0x2069, 0x0200, 0x6814, 0x9084, 0xffc0, 0x910d, 0x6916, 0x00de,
+ 0x000e, 0x0005, 0x00d6, 0x2069, 0x0200, 0x9005, 0x6810, 0x0110,
+ 0xc0a5, 0x0008, 0xc0a4, 0x6812, 0x00de, 0x0005, 0x0006, 0x00d6,
+ 0x2069, 0x0200, 0x6810, 0x9084, 0xfff8, 0x910d, 0x6912, 0x00de,
+ 0x000e, 0x0005, 0x7938, 0x080c, 0x0d72, 0x00f6, 0x2079, 0x0200,
+ 0x7902, 0xa001, 0xa001, 0xa001, 0xa001, 0xa001, 0xa001, 0x7902,
+ 0xa001, 0xa001, 0xa001, 0xa001, 0xa001, 0xa001, 0x00fe, 0x0005,
+ 0x0126, 0x2091, 0x2800, 0x2061, 0x0100, 0x2071, 0x1800, 0x2009,
+ 0x0000, 0x080c, 0x2a8e, 0x080c, 0x29a8, 0x2001, 0x199e, 0x2003,
+ 0x0700, 0x2001, 0x199f, 0x2003, 0x0700, 0x080c, 0x2aff, 0x9006,
+ 0x080c, 0x29d7, 0x9006, 0x080c, 0x29ba, 0x20a9, 0x0012, 0x1d04,
+ 0x226f, 0x2091, 0x6000, 0x1f04, 0x226f, 0x602f, 0x0100, 0x602f,
+ 0x0000, 0x6050, 0x9085, 0x0400, 0x9084, 0xdfff, 0x6052, 0x6224,
+ 0x080c, 0x2adc, 0x080c, 0x26da, 0x2009, 0x00ef, 0x6132, 0x6136,
+ 0x080c, 0x26ea, 0x60e7, 0x0000, 0x61ea, 0x60e3, 0x0008, 0x604b,
+ 0xf7f7, 0x6043, 0x0000, 0x602f, 0x0080, 0x602f, 0x0000, 0x6007,
+ 0x349f, 0x00c6, 0x2061, 0x0140, 0x608b, 0x000b, 0x608f, 0x10b8,
+ 0x6093, 0x0000, 0x6097, 0x0198, 0x00ce, 0x6004, 0x9085, 0x8000,
+ 0x6006, 0x60bb, 0x0000, 0x20a9, 0x0018, 0x60bf, 0x0000, 0x1f04,
+ 0x22ad, 0x60bb, 0x0000, 0x60bf, 0x0108, 0x60bf, 0x0012, 0x60bf,
+ 0x0405, 0x60bf, 0x0014, 0x60bf, 0x0320, 0x60bf, 0x0018, 0x601b,
+ 0x00f0, 0x601f, 0x001e, 0x600f, 0x006b, 0x602b, 0x402c, 0x012e,
+ 0x0005, 0x00f6, 0x2079, 0x0140, 0x78c3, 0x0080, 0x78c3, 0x0083,
+ 0x78c3, 0x0000, 0x00fe, 0x0005, 0x2001, 0x1835, 0x2003, 0x0000,
+ 0x2001, 0x1834, 0x2003, 0x0001, 0x0005, 0x0126, 0x2091, 0x2800,
+ 0x0006, 0x0016, 0x0026, 0x6124, 0x6028, 0x910c, 0x0066, 0x2031,
+ 0x1837, 0x2634, 0x96b4, 0x0028, 0x006e, 0x1138, 0x6020, 0xd1bc,
+ 0x0120, 0xd0bc, 0x1168, 0xd0b4, 0x1198, 0x9184, 0x5e2c, 0x1118,
+ 0x9184, 0x0007, 0x00aa, 0x9195, 0x0004, 0x9284, 0x0007, 0x0082,
+ 0x0016, 0x2001, 0x0387, 0x200c, 0xd1a4, 0x001e, 0x0d70, 0x0c98,
+ 0x0016, 0x2001, 0x0387, 0x200c, 0xd1b4, 0x001e, 0x0d30, 0x0c58,
+ 0x231b, 0x2318, 0x2318, 0x2318, 0x231a, 0x2318, 0x2318, 0x2318,
+ 0x080c, 0x0d79, 0x0029, 0x002e, 0x001e, 0x000e, 0x012e, 0x0005,
+ 0x00a6, 0x6124, 0x6028, 0xd09c, 0x0118, 0xd19c, 0x1904, 0x25a0,
+ 0xd1f4, 0x190c, 0x0d72, 0x080c, 0x769d, 0x0904, 0x2378, 0x080c,
+ 0xd35d, 0x1120, 0x7000, 0x9086, 0x0003, 0x0580, 0x6024, 0x9084,
+ 0x1800, 0x0560, 0x080c, 0x76c0, 0x0118, 0x080c, 0x76ae, 0x1530,
+ 0x2011, 0x0020, 0x080c, 0x2adc, 0x6043, 0x0000, 0x080c, 0xd35d,
+ 0x0168, 0x080c, 0x76c0, 0x1150, 0x2001, 0x19a9, 0x2003, 0x0001,
+ 0x6027, 0x1800, 0x080c, 0x7511, 0x0804, 0x25a3, 0x70a4, 0x9005,
+ 0x1150, 0x70a7, 0x0001, 0x00d6, 0x2069, 0x0140, 0x080c, 0x76f1,
+ 0x00de, 0x1904, 0x25a3, 0x080c, 0x79a9, 0x0428, 0x080c, 0x76c0,
+ 0x1590, 0x6024, 0x9084, 0x1800, 0x1108, 0x0468, 0x080c, 0x79a9,
+ 0x080c, 0x799f, 0x080c, 0x6178, 0x080c, 0x75cc, 0x0804, 0x25a0,
+ 0xd1ac, 0x1508, 0x6024, 0xd0dc, 0x1170, 0xd0e4, 0x1178, 0xd0d4,
+ 0x1190, 0xd0cc, 0x0130, 0x7098, 0x9086, 0x0029, 0x1110, 0x080c,
+ 0x7880, 0x0804, 0x25a0, 0x080c, 0x79a4, 0x0048, 0x2001, 0x197e,
+ 0x2003, 0x0002, 0x0020, 0x080c, 0x77db, 0x0804, 0x25a0, 0x080c,
+ 0x7923, 0x0804, 0x25a0, 0x6220, 0xd1bc, 0x0138, 0xd2bc, 0x1904,
+ 0x260b, 0xd2b4, 0x1904, 0x261d, 0x0000, 0xd1ac, 0x0904, 0x24ad,
+ 0x0036, 0x6328, 0xc3bc, 0x632a, 0x003e, 0x080c, 0x769d, 0x11d0,
+ 0x2011, 0x0020, 0x080c, 0x2adc, 0x0006, 0x0026, 0x0036, 0x080c,
+ 0x76b7, 0x1158, 0x080c, 0x799f, 0x080c, 0x6178, 0x080c, 0x75cc,
+ 0x003e, 0x002e, 0x000e, 0x00ae, 0x0005, 0x003e, 0x002e, 0x000e,
+ 0x080c, 0x7671, 0x0016, 0x0046, 0x00c6, 0x644c, 0x9486, 0xf0f0,
+ 0x1138, 0x2061, 0x0100, 0x644a, 0x6043, 0x0090, 0x6043, 0x0010,
+ 0x74da, 0x948c, 0xff00, 0x7038, 0xd084, 0x0190, 0x080c, 0xd35d,
+ 0x1118, 0x9186, 0xf800, 0x1160, 0x7048, 0xd084, 0x1148, 0xc085,
+ 0x704a, 0x0036, 0x2418, 0x2011, 0x8016, 0x080c, 0x4c28, 0x003e,
+ 0x080c, 0xd356, 0x1904, 0x2482, 0x9196, 0xff00, 0x05a8, 0x7060,
+ 0x9084, 0x00ff, 0x810f, 0x81ff, 0x0110, 0x9116, 0x0568, 0x7130,
+ 0xd184, 0x1550, 0x080c, 0x3468, 0x0128, 0xc18d, 0x7132, 0x080c,
+ 0x6bc5, 0x1510, 0x6240, 0x9294, 0x0010, 0x0130, 0x6248, 0x9294,
+ 0xff00, 0x9296, 0xff00, 0x01c0, 0x7030, 0xd08c, 0x0904, 0x2482,
+ 0x7038, 0xd08c, 0x1140, 0x2001, 0x180c, 0x200c, 0xd1ac, 0x1904,
+ 0x2482, 0xc1ad, 0x2102, 0x0036, 0x73d8, 0x2011, 0x8013, 0x080c,
+ 0x4c28, 0x003e, 0x0804, 0x2482, 0x7038, 0xd08c, 0x1140, 0x2001,
+ 0x180c, 0x200c, 0xd1ac, 0x1904, 0x2482, 0xc1ad, 0x2102, 0x0036,
+ 0x73d8, 0x2011, 0x8013, 0x080c, 0x4c28, 0x003e, 0x7130, 0xc185,
+ 0x7132, 0x2011, 0x1848, 0x220c, 0xd1a4, 0x01f0, 0x0016, 0x2009,
+ 0x0001, 0x2011, 0x0100, 0x080c, 0x8add, 0x2019, 0x000e, 0x00c6,
+ 0x2061, 0x0000, 0x080c, 0xe701, 0x00ce, 0x9484, 0x00ff, 0x9080,
+ 0x3474, 0x200d, 0x918c, 0xff00, 0x810f, 0x2120, 0x9006, 0x2009,
+ 0x000e, 0x080c, 0xe795, 0x001e, 0x0016, 0x2009, 0x0002, 0x2019,
+ 0x0004, 0x080c, 0x32c0, 0x001e, 0x00a8, 0x0156, 0x00b6, 0x20a9,
+ 0x007f, 0x900e, 0x080c, 0x6783, 0x1140, 0x7030, 0xd084, 0x1118,
+ 0xb800, 0xd0bc, 0x1110, 0x080c, 0x6192, 0x8108, 0x1f04, 0x2472,
+ 0x00be, 0x015e, 0x00ce, 0x004e, 0x080c, 0xaaf7, 0x080c, 0xadbe,
+ 0x080c, 0xae87, 0x080c, 0xab13, 0x60e3, 0x0000, 0x001e, 0x2001,
+ 0x1800, 0x2014, 0x9296, 0x0004, 0x1170, 0xd19c, 0x11b0, 0x2011,
+ 0x180c, 0x2214, 0xd29c, 0x1120, 0x6204, 0x9295, 0x0002, 0x6206,
+ 0x6228, 0xc29d, 0x622a, 0x2003, 0x0001, 0x2001, 0x1826, 0x2003,
+ 0x0000, 0x2011, 0x0020, 0x080c, 0x2adc, 0xd194, 0x0904, 0x25a0,
+ 0x0016, 0x080c, 0xaaf7, 0x6220, 0xd2b4, 0x0904, 0x253b, 0x080c,
+ 0x88e4, 0x080c, 0xa09b, 0x2011, 0x0004, 0x080c, 0x2adc, 0x00f6,
+ 0x2019, 0x19f5, 0x2304, 0x907d, 0x0904, 0x2508, 0x7804, 0x9086,
+ 0x0032, 0x15f0, 0x00d6, 0x00c6, 0x00e6, 0x0096, 0x2069, 0x0140,
+ 0x782c, 0x685e, 0x7808, 0x685a, 0x6043, 0x0002, 0x2001, 0x0003,
+ 0x8001, 0x1df0, 0x6043, 0x0000, 0x2001, 0x003c, 0x8001, 0x1df0,
+ 0x080c, 0x2ab2, 0x2001, 0x001e, 0x8001, 0x0240, 0x20a9, 0x0009,
+ 0x080c, 0x2a69, 0x6904, 0xd1dc, 0x1140, 0x0cb0, 0x2001, 0x0100,
+ 0x080c, 0x2aa2, 0x9006, 0x080c, 0x2aa2, 0x080c, 0x97f6, 0x080c,
+ 0xab13, 0x7814, 0x2048, 0xa867, 0x0103, 0x2f60, 0x080c, 0xaf4e,
+ 0x009e, 0x00ee, 0x00ce, 0x00de, 0x00fe, 0x001e, 0x00ae, 0x0005,
+ 0x00fe, 0x00d6, 0x2069, 0x0140, 0x6804, 0x9084, 0x4000, 0x0110,
+ 0x080c, 0x2ab2, 0x00de, 0x00c6, 0x2061, 0x19e9, 0x6034, 0x080c,
+ 0xd35d, 0x0120, 0x909a, 0x0003, 0x1258, 0x0018, 0x909a, 0x00c8,
+ 0x1238, 0x8000, 0x6036, 0x00ce, 0x080c, 0xa073, 0x0804, 0x259d,
+ 0x2061, 0x0100, 0x62c0, 0x080c, 0xaa28, 0x2019, 0x19f5, 0x2304,
+ 0x9065, 0x0130, 0x6003, 0x0001, 0x2009, 0x0027, 0x080c, 0xafec,
+ 0x00ce, 0x0804, 0x259d, 0xd2bc, 0x0904, 0x2580, 0x080c, 0x88f1,
+ 0x2011, 0x0004, 0x080c, 0x2adc, 0x00d6, 0x2069, 0x0140, 0x6804,
+ 0x9084, 0x4000, 0x0110, 0x080c, 0x2ab2, 0x00de, 0x00c6, 0x2061,
+ 0x19e9, 0x6050, 0x080c, 0xd35d, 0x0120, 0x909a, 0x0003, 0x1668,
+ 0x0018, 0x909a, 0x00c8, 0x1648, 0x8000, 0x6052, 0x604c, 0x00ce,
+ 0x9005, 0x05d8, 0x2009, 0x07d0, 0x080c, 0x88e9, 0x9080, 0x0008,
+ 0x2004, 0x9086, 0x0006, 0x1138, 0x2009, 0x1984, 0x2011, 0x0012,
+ 0x080c, 0x2aeb, 0x0450, 0x9080, 0x0008, 0x2004, 0x9086, 0x0009,
+ 0x0d98, 0x2009, 0x1984, 0x2011, 0x0016, 0x080c, 0x2aeb, 0x00e8,
+ 0x2011, 0x0004, 0x080c, 0x2adc, 0x00c0, 0x0036, 0x2019, 0x0001,
+ 0x080c, 0xa391, 0x003e, 0x2019, 0x19fc, 0x2304, 0x9065, 0x0160,
+ 0x2009, 0x004f, 0x6020, 0x9086, 0x0009, 0x1110, 0x2009, 0x004f,
+ 0x6003, 0x0003, 0x080c, 0xafec, 0x00ce, 0x080c, 0xab13, 0x001e,
+ 0xd19c, 0x0904, 0x2604, 0x7038, 0xd0ac, 0x1558, 0x0016, 0x0156,
+ 0x2011, 0x0008, 0x080c, 0x2adc, 0x080c, 0x2aff, 0x080c, 0x2b32,
+ 0x6050, 0xc0e5, 0x6052, 0x20a9, 0x0367, 0x0f04, 0x25cf, 0x1d04,
+ 0x25b7, 0x080c, 0x8918, 0x6020, 0xd09c, 0x1db8, 0x00f6, 0x2079,
+ 0x0100, 0x080c, 0x2a19, 0x00fe, 0x1d80, 0x6050, 0xc0e4, 0x6052,
+ 0x2011, 0x0008, 0x080c, 0x2adc, 0x015e, 0x001e, 0x04a8, 0x015e,
+ 0x001e, 0x0016, 0x6028, 0xc09c, 0x602a, 0x080c, 0xaaf7, 0x080c,
+ 0xadbe, 0x080c, 0xae87, 0x080c, 0xab13, 0x60e3, 0x0000, 0x080c,
+ 0xebe8, 0x080c, 0xec03, 0x080c, 0x5824, 0xd0fc, 0x1138, 0x080c,
+ 0xd356, 0x1120, 0x9085, 0x0001, 0x080c, 0x76e1, 0x9006, 0x080c,
+ 0x2aa2, 0x2009, 0x0002, 0x080c, 0x2a8e, 0x00e6, 0x2071, 0x1800,
+ 0x7003, 0x0004, 0x080c, 0x0ec7, 0x00ee, 0x2011, 0x0008, 0x080c,
+ 0x2adc, 0x080c, 0x0bc3, 0x001e, 0x918c, 0xffd0, 0x2110, 0x080c,
+ 0x2adc, 0x00ae, 0x0005, 0x0016, 0x2001, 0x0387, 0x200c, 0xd1a4,
+ 0x001e, 0x0904, 0x23a5, 0x0016, 0x2009, 0x2617, 0x00c0, 0x2001,
+ 0x0387, 0x2003, 0x1000, 0x001e, 0x0c38, 0x0016, 0x2001, 0x0387,
+ 0x200c, 0xd1b4, 0x001e, 0x0904, 0x23a5, 0x0016, 0x2009, 0x2629,
+ 0x0030, 0x2001, 0x0387, 0x2003, 0x4000, 0x001e, 0x08a8, 0x6028,
+ 0xc0bc, 0x602a, 0x2001, 0x0156, 0x2003, 0xbc91, 0x8000, 0x2003,
+ 0xffff, 0x6043, 0x0001, 0x080c, 0x2a88, 0x2011, 0x0080, 0x080c,
+ 0x2adc, 0x6017, 0x0000, 0x6043, 0x0000, 0x0817, 0x0006, 0x0016,
+ 0x0026, 0x0036, 0x00e6, 0x00f6, 0x0126, 0x2091, 0x8000, 0x2071,
+ 0x1800, 0x71d0, 0x70d2, 0x9116, 0x0904, 0x2699, 0x81ff, 0x01a0,
+ 0x2009, 0x0000, 0x080c, 0x2a8e, 0x2011, 0x8011, 0x2019, 0x010e,
+ 0x231c, 0x939e, 0x0007, 0x1118, 0x2019, 0x0001, 0x0010, 0x2019,
+ 0x0000, 0x080c, 0x4c28, 0x0468, 0x2001, 0x19aa, 0x200c, 0x81ff,
+ 0x1140, 0x2001, 0x0109, 0x2004, 0xd0b4, 0x0118, 0x2019, 0x0003,
+ 0x0008, 0x2118, 0x2011, 0x8012, 0x080c, 0x4c28, 0x080c, 0x0ec7,
+ 0x080c, 0x5824, 0xd0fc, 0x11a8, 0x080c, 0xd356, 0x1190, 0x00c6,
+ 0x080c, 0x2735, 0x080c, 0xaaf7, 0x080c, 0xa2ec, 0x080c, 0xab13,
+ 0x2061, 0x0100, 0x2019, 0x0028, 0x2009, 0x0002, 0x080c, 0x32c0,
+ 0x00ce, 0x012e, 0x00fe, 0x00ee, 0x003e, 0x002e, 0x001e, 0x000e,
+ 0x0005, 0x2028, 0x918c, 0x00ff, 0x2130, 0x9094, 0xff00, 0x11f0,
+ 0x2011, 0x1837, 0x2214, 0xd2ac, 0x11c8, 0x81ff, 0x01e8, 0x2011,
+ 0x181f, 0x2204, 0x9106, 0x1190, 0x2011, 0x1820, 0x2214, 0x9294,
+ 0xff00, 0x9584, 0xff00, 0x9206, 0x1148, 0x2011, 0x1820, 0x2214,
+ 0x9294, 0x00ff, 0x9584, 0x00ff, 0x9206, 0x1120, 0x2500, 0x080c,
+ 0x83ba, 0x0048, 0x9584, 0x00ff, 0x9080, 0x3474, 0x200d, 0x918c,
+ 0xff00, 0x810f, 0x9006, 0x0005, 0x9080, 0x3474, 0x200d, 0x918c,
+ 0x00ff, 0x0005, 0x00d6, 0x2069, 0x0140, 0x2001, 0x1818, 0x2003,
+ 0x00ef, 0x20a9, 0x0010, 0x9006, 0x6852, 0x6856, 0x1f04, 0x26e5,
+ 0x00de, 0x0005, 0x0006, 0x00d6, 0x0026, 0x2069, 0x0140, 0x2001,
+ 0x1818, 0x2102, 0x8114, 0x8214, 0x8214, 0x8214, 0x20a9, 0x0010,
+ 0x6853, 0x0000, 0x9006, 0x82ff, 0x1128, 0x9184, 0x000f, 0x9080,
+ 0xec17, 0x2005, 0x6856, 0x8211, 0x1f04, 0x26fa, 0x002e, 0x00de,
+ 0x000e, 0x0005, 0x00c6, 0x2061, 0x1800, 0x6030, 0x0110, 0xc09d,
+ 0x0008, 0xc09c, 0x6032, 0x00ce, 0x0005, 0x0156, 0x00d6, 0x0026,
+ 0x0016, 0x0006, 0x2069, 0x0140, 0x6980, 0x9116, 0x0180, 0x9112,
+ 0x1230, 0x8212, 0x8210, 0x22a8, 0x2001, 0x0402, 0x0018, 0x22a8,
+ 0x2001, 0x0404, 0x680e, 0x1f04, 0x272a, 0x680f, 0x0000, 0x000e,
+ 0x001e, 0x002e, 0x00de, 0x015e, 0x0005, 0x080c, 0x5820, 0xd0c4,
+ 0x0150, 0xd0a4, 0x0140, 0x9006, 0x0046, 0x2020, 0x2009, 0x002e,
+ 0x080c, 0xe795, 0x004e, 0x0005, 0x00f6, 0x0016, 0x0026, 0x2079,
+ 0x0140, 0x78c4, 0xd0dc, 0x0904, 0x27a1, 0x080c, 0x2a09, 0x0660,
+ 0x9084, 0x0700, 0x908e, 0x0600, 0x1120, 0x2011, 0x4000, 0x900e,
+ 0x0458, 0x908e, 0x0500, 0x1120, 0x2011, 0x8000, 0x900e, 0x0420,
+ 0x908e, 0x0400, 0x1120, 0x9016, 0x2009, 0x0001, 0x00e8, 0x908e,
+ 0x0300, 0x1120, 0x9016, 0x2009, 0x0002, 0x00b0, 0x908e, 0x0200,
+ 0x1120, 0x9016, 0x2009, 0x0004, 0x0078, 0x908e, 0x0100, 0x1548,
+ 0x9016, 0x2009, 0x0008, 0x0040, 0x9084, 0x0700, 0x908e, 0x0300,
+ 0x1500, 0x2011, 0x0030, 0x0058, 0x2300, 0x9080, 0x0020, 0x2018,
+ 0x080c, 0x9364, 0x928c, 0xff00, 0x0110, 0x2011, 0x00ff, 0x2200,
+ 0x8007, 0x9085, 0x004c, 0x78c2, 0x2009, 0x0138, 0x220a, 0x080c,
+ 0x769d, 0x1118, 0x2009, 0x196e, 0x220a, 0x002e, 0x001e, 0x00fe,
+ 0x0005, 0x78c3, 0x0000, 0x0cc8, 0x0126, 0x2091, 0x2800, 0x0006,
+ 0x0016, 0x0026, 0x2001, 0x0170, 0x200c, 0x8000, 0x2014, 0x9184,
+ 0x0003, 0x0110, 0x080c, 0x0d72, 0x002e, 0x001e, 0x000e, 0x012e,
+ 0x0005, 0x2001, 0x0171, 0x2004, 0xd0dc, 0x0168, 0x2001, 0x0170,
+ 0x200c, 0x918c, 0x00ff, 0x918e, 0x004c, 0x1128, 0x200c, 0x918c,
+ 0xff00, 0x810f, 0x0005, 0x900e, 0x2001, 0x0227, 0x2004, 0x8007,
+ 0x9084, 0x00ff, 0x8004, 0x9108, 0x2001, 0x0226, 0x2004, 0x8007,
+ 0x9084, 0x00ff, 0x8004, 0x9108, 0x0005, 0x0018, 0x000c, 0x0018,
+ 0x0020, 0x1000, 0x0800, 0x1000, 0x1800, 0x0156, 0x0006, 0x0016,
+ 0x0026, 0x00e6, 0x2001, 0x1991, 0x2004, 0x908a, 0x0007, 0x1a0c,
+ 0x0d79, 0x0033, 0x00ee, 0x002e, 0x001e, 0x000e, 0x015e, 0x0005,
+ 0x27ff, 0x281d, 0x2841, 0x2843, 0x286c, 0x286e, 0x2870, 0x2001,
+ 0x0001, 0x080c, 0x2646, 0x080c, 0x2a53, 0x2001, 0x1993, 0x2003,
+ 0x0000, 0x7828, 0x9084, 0xe1d7, 0x782a, 0x9006, 0x20a9, 0x0009,
+ 0x080c, 0x2a25, 0x2001, 0x1991, 0x2003, 0x0006, 0x2009, 0x001e,
+ 0x2011, 0x2871, 0x080c, 0x88f6, 0x0005, 0x2009, 0x1996, 0x200b,
+ 0x0000, 0x2001, 0x199b, 0x2003, 0x0036, 0x2001, 0x199a, 0x2003,
+ 0x002a, 0x2001, 0x1993, 0x2003, 0x0001, 0x9006, 0x080c, 0x29ba,
+ 0x2001, 0xffff, 0x20a9, 0x0009, 0x080c, 0x2a25, 0x2001, 0x1991,
+ 0x2003, 0x0006, 0x2009, 0x001e, 0x2011, 0x2871, 0x080c, 0x88f6,
+ 0x0005, 0x080c, 0x0d79, 0x2001, 0x199b, 0x2003, 0x0036, 0x2001,
+ 0x1993, 0x2003, 0x0003, 0x7a38, 0x9294, 0x0005, 0x9296, 0x0004,
+ 0x0110, 0x9006, 0x0010, 0x2001, 0x0001, 0x080c, 0x29ba, 0x2001,
+ 0x1997, 0x2003, 0x0000, 0x2001, 0xffff, 0x20a9, 0x0009, 0x080c,
+ 0x2a25, 0x2001, 0x1991, 0x2003, 0x0006, 0x2009, 0x001e, 0x2011,
+ 0x2871, 0x080c, 0x88f6, 0x0005, 0x080c, 0x0d79, 0x080c, 0x0d79,
+ 0x0005, 0x0006, 0x0016, 0x0026, 0x00e6, 0x00f6, 0x0156, 0x0126,
+ 0x2091, 0x8000, 0x2079, 0x0100, 0x2001, 0x1993, 0x2004, 0x908a,
+ 0x0007, 0x1a0c, 0x0d79, 0x0043, 0x012e, 0x015e, 0x00fe, 0x00ee,
+ 0x002e, 0x001e, 0x000e, 0x0005, 0x2893, 0x28af, 0x28eb, 0x2917,
+ 0x2937, 0x2943, 0x2945, 0x080c, 0x2a19, 0x1190, 0x2009, 0x1999,
+ 0x2104, 0x7a38, 0x9294, 0x0005, 0x9296, 0x0004, 0x0110, 0xc08d,
+ 0x0008, 0xc085, 0x200a, 0x2001, 0x1991, 0x2003, 0x0001, 0x0030,
+ 0x080c, 0x2969, 0x2001, 0xffff, 0x080c, 0x280e, 0x0005, 0x080c,
+ 0x2947, 0x05c0, 0x2009, 0x199a, 0x2104, 0x8001, 0x200a, 0x080c,
+ 0x2a19, 0x1158, 0x7a38, 0x9294, 0x0005, 0x9296, 0x0005, 0x0518,
+ 0x2009, 0x1999, 0x2104, 0xc085, 0x200a, 0x2009, 0x1996, 0x2104,
+ 0x8000, 0x200a, 0x9086, 0x0005, 0x0118, 0x080c, 0x294f, 0x00c0,
+ 0x200b, 0x0000, 0x7a38, 0x9294, 0x0006, 0x9296, 0x0004, 0x0110,
+ 0x9006, 0x0010, 0x2001, 0x0001, 0x080c, 0x29d7, 0x2001, 0x1993,
+ 0x2003, 0x0002, 0x0028, 0x2001, 0x1991, 0x2003, 0x0003, 0x0010,
+ 0x080c, 0x2830, 0x0005, 0x080c, 0x2947, 0x0540, 0x2009, 0x199a,
+ 0x2104, 0x8001, 0x200a, 0x080c, 0x2a19, 0x1148, 0x2001, 0x1991,
+ 0x2003, 0x0003, 0x2001, 0x1992, 0x2003, 0x0000, 0x00b8, 0x2009,
+ 0x199a, 0x2104, 0x9005, 0x1118, 0x080c, 0x298c, 0x0010, 0x080c,
+ 0x295c, 0x080c, 0x294f, 0x2009, 0x1996, 0x200b, 0x0000, 0x2001,
+ 0x1993, 0x2003, 0x0001, 0x080c, 0x2830, 0x0000, 0x0005, 0x0479,
+ 0x01e8, 0x080c, 0x2a19, 0x1198, 0x2009, 0x1997, 0x2104, 0x8000,
+ 0x200a, 0x9086, 0x0007, 0x0108, 0x0078, 0x2001, 0x199c, 0x2003,
+ 0x000a, 0x2009, 0x1999, 0x2104, 0xc0fd, 0x200a, 0x0038, 0x00f9,
+ 0x2001, 0x1993, 0x2003, 0x0004, 0x080c, 0x285b, 0x0005, 0x0079,
+ 0x0148, 0x080c, 0x2a19, 0x1118, 0x080c, 0x2847, 0x0018, 0x0079,
+ 0x080c, 0x285b, 0x0005, 0x080c, 0x0d79, 0x080c, 0x0d79, 0x2009,
+ 0x199b, 0x2104, 0x8001, 0x200a, 0x090c, 0x29a8, 0x0005, 0x7a38,
+ 0x9294, 0x0005, 0x9296, 0x0005, 0x0110, 0x9006, 0x0010, 0x2001,
+ 0x0001, 0x080c, 0x29d7, 0x0005, 0x7a38, 0x9294, 0x0006, 0x9296,
+ 0x0006, 0x0110, 0x9006, 0x0010, 0x2001, 0x0001, 0x080c, 0x29ba,
+ 0x0005, 0x2009, 0x1996, 0x2104, 0x8000, 0x200a, 0x9086, 0x0005,
+ 0x0108, 0x0068, 0x200b, 0x0000, 0x7a38, 0x9294, 0x0006, 0x9296,
+ 0x0006, 0x0110, 0x9006, 0x0010, 0x2001, 0x0001, 0x04d9, 0x7a38,
+ 0x9294, 0x0005, 0x9296, 0x0005, 0x0110, 0x9006, 0x0010, 0x2001,
+ 0x0001, 0x080c, 0x29d7, 0x0005, 0x0086, 0x2001, 0x1999, 0x2004,
+ 0x9084, 0x7fff, 0x090c, 0x0d79, 0x2009, 0x1998, 0x2144, 0x8846,
+ 0x280a, 0x9844, 0x0dd8, 0xd08c, 0x1120, 0xd084, 0x1120, 0x080c,
+ 0x0d79, 0x9006, 0x0010, 0x2001, 0x0001, 0x00a1, 0x008e, 0x0005,
+ 0x0006, 0x0156, 0x2001, 0x1991, 0x20a9, 0x0009, 0x2003, 0x0000,
+ 0x8000, 0x1f04, 0x29ae, 0x2001, 0x1998, 0x2003, 0x8000, 0x015e,
+ 0x000e, 0x0005, 0x00f6, 0x2079, 0x0100, 0x9085, 0x0000, 0x0158,
+ 0x7838, 0x9084, 0xfff9, 0x9085, 0x0004, 0x783a, 0x2009, 0x199e,
+ 0x210c, 0x795a, 0x0050, 0x7838, 0x9084, 0xfffb, 0x9085, 0x0006,
+ 0x783a, 0x2009, 0x199f, 0x210c, 0x795a, 0x00fe, 0x0005, 0x00f6,
+ 0x2079, 0x0100, 0x9085, 0x0000, 0x0158, 0x7838, 0x9084, 0xfffa,
+ 0x9085, 0x0004, 0x783a, 0x7850, 0x9084, 0xfff0, 0x7852, 0x00f8,
+ 0x7838, 0x9084, 0xfffb, 0x9085, 0x0005, 0x783a, 0x7850, 0x9084,
+ 0xfff0, 0x0016, 0x2009, 0x017f, 0x210c, 0x918e, 0x0005, 0x0140,
+ 0x2009, 0x0003, 0x210c, 0x918c, 0x0600, 0x918e, 0x0400, 0x0118,
+ 0x9085, 0x000a, 0x0010, 0x9085, 0x0000, 0x001e, 0x7852, 0x00fe,
+ 0x0005, 0x0006, 0x2001, 0x0100, 0x2004, 0x9082, 0x0007, 0x000e,
+ 0x0005, 0x0006, 0x2001, 0x0100, 0x2004, 0x9082, 0x0009, 0x000e,
+ 0x0005, 0x0156, 0x20a9, 0x0064, 0x7820, 0x080c, 0x2a88, 0xd09c,
+ 0x1110, 0x1f04, 0x2a1c, 0x015e, 0x0005, 0x0126, 0x0016, 0x0006,
+ 0x2091, 0x8000, 0x000e, 0x2008, 0x9186, 0x0000, 0x1118, 0x783b,
+ 0x0007, 0x0090, 0x9186, 0x0001, 0x1118, 0x783b, 0x0006, 0x0060,
+ 0x9186, 0x0002, 0x1118, 0x783b, 0x0005, 0x0030, 0x9186, 0x0003,
+ 0x1118, 0x783b, 0x0004, 0x0000, 0x0006, 0x1d04, 0x2a45, 0x080c,
+ 0x8918, 0x1f04, 0x2a45, 0x7850, 0x9085, 0x1000, 0x7852, 0x000e,
+ 0x001e, 0x012e, 0x0005, 0x080c, 0x2b32, 0x0005, 0x0006, 0x0156,
+ 0x00f6, 0x2079, 0x0100, 0x20a9, 0x000a, 0x7854, 0xd0ac, 0x1100,
+ 0x7854, 0xd08c, 0x1110, 0x1f04, 0x2a60, 0x00fe, 0x015e, 0x000e,
+ 0x0005, 0x1d04, 0x2a69, 0x080c, 0x8918, 0x1f04, 0x2a69, 0x0005,
+ 0x0006, 0x2001, 0x199d, 0x2004, 0x9086, 0x0000, 0x000e, 0x0005,
+ 0x0006, 0x2001, 0x199d, 0x2004, 0x9086, 0x0001, 0x000e, 0x0005,
+ 0x0006, 0x2001, 0x199d, 0x2004, 0x9086, 0x0002, 0x000e, 0x0005,
+ 0xa001, 0xa001, 0xa001, 0xa001, 0xa001, 0x0005, 0x0006, 0x2001,
+ 0x19aa, 0x2102, 0x000e, 0x0005, 0x2009, 0x0171, 0x2104, 0xd0dc,
+ 0x0140, 0x2009, 0x0170, 0x2104, 0x200b, 0x0080, 0xa001, 0xa001,
+ 0x200a, 0x0005, 0x0016, 0x0026, 0x080c, 0x76b7, 0x0108, 0xc0bc,
+ 0x2009, 0x0140, 0x2114, 0x9294, 0x0001, 0x9215, 0x220a, 0x002e,
+ 0x001e, 0x0005, 0x0016, 0x0026, 0x2009, 0x0140, 0x2114, 0x9294,
+ 0x0001, 0x9285, 0x1000, 0x200a, 0x220a, 0x002e, 0x001e, 0x0005,
+ 0x0016, 0x0026, 0x2009, 0x0140, 0x2114, 0x9294, 0x0001, 0x9215,
+ 0x220a, 0x002e, 0x001e, 0x0005, 0x0006, 0x0016, 0x2009, 0x0140,
+ 0x2104, 0x1128, 0x080c, 0x76b7, 0x0110, 0xc0bc, 0x0008, 0xc0bd,
+ 0x200a, 0x001e, 0x000e, 0x0005, 0x00f6, 0x2079, 0x0380, 0x7843,
+ 0x0101, 0x7844, 0xd084, 0x1de8, 0x2001, 0x0109, 0x2202, 0x7843,
+ 0x0100, 0x00fe, 0x0005, 0x00f6, 0x2079, 0x0380, 0x7843, 0x0202,
+ 0x7844, 0xd08c, 0x1de8, 0x2079, 0x0100, 0x7814, 0x9104, 0x9205,
+ 0x7a16, 0x2079, 0x0380, 0x7843, 0x0200, 0x00fe, 0x0005, 0x0016,
+ 0x0026, 0x0036, 0x00c6, 0x2061, 0x0100, 0x6050, 0x9084, 0xfbff,
+ 0x9085, 0x0040, 0x6052, 0x20a9, 0x0002, 0x080c, 0x2a69, 0x6050,
+ 0x9085, 0x0400, 0x9084, 0xff9f, 0x6052, 0x20a9, 0x0005, 0x080c,
+ 0x2a69, 0x6054, 0xd0bc, 0x090c, 0x0d79, 0x20a9, 0x0005, 0x080c,
+ 0x2a69, 0x6054, 0xd0ac, 0x090c, 0x0d79, 0x2009, 0x19b1, 0x9084,
+ 0x7e00, 0x8007, 0x8004, 0x8004, 0x200a, 0x00ce, 0x003e, 0x002e,
+ 0x001e, 0x0005, 0x0006, 0x00c6, 0x2061, 0x0100, 0x6050, 0xc0cd,
+ 0x6052, 0x00ce, 0x000e, 0x0005, 0x0016, 0x00c6, 0x00d6, 0x0006,
+ 0x2061, 0x0100, 0x2069, 0x0140, 0x6030, 0x0006, 0x6048, 0x0006,
+ 0x60e4, 0x0006, 0x60e8, 0x0006, 0x6050, 0x0006, 0x60ec, 0x0006,
+ 0x600c, 0x0006, 0x6004, 0x0006, 0xc0fc, 0x6006, 0x2009, 0x0800,
+ 0x2001, 0x0338, 0x2003, 0x0301, 0x8109, 0x090c, 0x0d79, 0x2001,
+ 0x0338, 0x2004, 0xd084, 0x1dc0, 0x6028, 0x0006, 0x60e0, 0x0006,
+ 0x6888, 0x0006, 0x688c, 0x0006, 0x6890, 0x0006, 0x080c, 0x769d,
+ 0x1110, 0x6884, 0x0006, 0x602f, 0x0100, 0x602f, 0x0000, 0xa001,
+ 0xa001, 0xa001, 0xa001, 0x602f, 0x0040, 0x602f, 0x0000, 0x080c,
+ 0x769d, 0x1120, 0x6803, 0x0080, 0x000e, 0x6886, 0x6897, 0x4198,
+ 0x000e, 0x6892, 0x000e, 0x688e, 0x000e, 0x688a, 0x000e, 0x60e2,
+ 0x000e, 0x602a, 0x000e, 0x6006, 0x000e, 0x600e, 0x000e, 0x60ee,
+ 0x000e, 0x6052, 0x000e, 0x60ea, 0x000e, 0x60e6, 0x000e, 0x604a,
+ 0x000e, 0x6032, 0x6036, 0x2008, 0x080c, 0x26ea, 0x000e, 0x00de,
+ 0x00ce, 0x001e, 0x0005, 0x0006, 0x0156, 0x6050, 0x9085, 0x0040,
+ 0x6052, 0x6050, 0x9084, 0xfbcf, 0x6052, 0x080c, 0x2a88, 0x9085,
+ 0x2000, 0x6052, 0x20a9, 0x0012, 0x1d04, 0x2bbc, 0x080c, 0x8918,
+ 0x1f04, 0x2bbc, 0x6050, 0x9085, 0x0400, 0x9084, 0xdfbf, 0x6052,
+ 0x015e, 0x000e, 0x0005, 0x30c7, 0x30c7, 0x2ccb, 0x2ccb, 0x2cd7,
+ 0x2cd7, 0x2ce3, 0x2ce3, 0x2cf1, 0x2cf1, 0x2cfd, 0x2cfd, 0x2d0b,
+ 0x2d0b, 0x2d19, 0x2d19, 0x2d2b, 0x2d2b, 0x2d37, 0x2d37, 0x2d45,
+ 0x2d45, 0x2d63, 0x2d63, 0x2d83, 0x2d83, 0x2d53, 0x2d53, 0x2d73,
+ 0x2d73, 0x2d91, 0x2d91, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29,
+ 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29,
+ 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29,
+ 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29,
+ 0x2d29, 0x2d29, 0x2d29, 0x2da3, 0x2da3, 0x2daf, 0x2daf, 0x2dbd,
+ 0x2dbd, 0x2dcb, 0x2dcb, 0x2ddb, 0x2ddb, 0x2de9, 0x2de9, 0x2df9,
+ 0x2df9, 0x2e09, 0x2e09, 0x2e1b, 0x2e1b, 0x2e29, 0x2e29, 0x2e39,
+ 0x2e39, 0x2e5b, 0x2e5b, 0x2e7f, 0x2e7f, 0x2e49, 0x2e49, 0x2e6d,
+ 0x2e6d, 0x2e8f, 0x2e8f, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29,
+ 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29,
+ 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29,
+ 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29,
+ 0x2d29, 0x2d29, 0x2d29, 0x2ea3, 0x2ea3, 0x2eaf, 0x2eaf, 0x2ebd,
+ 0x2ebd, 0x2ecb, 0x2ecb, 0x2edb, 0x2edb, 0x2ee9, 0x2ee9, 0x2ef9,
+ 0x2ef9, 0x2f09, 0x2f09, 0x2f1b, 0x2f1b, 0x2f29, 0x2f29, 0x2f39,
+ 0x2f39, 0x2f49, 0x2f49, 0x2f5b, 0x2f5b, 0x2f6b, 0x2f6b, 0x2f7d,
+ 0x2f7d, 0x2f8f, 0x2f8f, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29,
+ 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29,
+ 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29,
+ 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29,
+ 0x2d29, 0x2d29, 0x2d29, 0x2fa3, 0x2fa3, 0x2fb1, 0x2fb1, 0x2fc1,
+ 0x2fc1, 0x2fd1, 0x2fd1, 0x2fe3, 0x2fe3, 0x2ff3, 0x2ff3, 0x3005,
+ 0x3005, 0x3017, 0x3017, 0x302b, 0x302b, 0x303b, 0x303b, 0x304d,
+ 0x304d, 0x305f, 0x305f, 0x3073, 0x3073, 0x3084, 0x3084, 0x3097,
+ 0x3097, 0x30aa, 0x30aa, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29,
+ 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29,
+ 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29,
+ 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29, 0x2d29,
+ 0x2d29, 0x2d29, 0x2d29, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6,
+ 0x0136, 0x0146, 0x0156, 0x080c, 0x22dd, 0x0804, 0x30bf, 0x0106,
+ 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c,
+ 0x2107, 0x0804, 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6,
+ 0x0136, 0x0146, 0x0156, 0x080c, 0x2107, 0x080c, 0x22dd, 0x0804,
+ 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146,
+ 0x0156, 0x080c, 0x2131, 0x0804, 0x30bf, 0x0106, 0x0006, 0x0126,
+ 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x22dd, 0x080c,
+ 0x2131, 0x0804, 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6,
+ 0x0136, 0x0146, 0x0156, 0x080c, 0x2107, 0x080c, 0x2131, 0x0804,
+ 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146,
+ 0x0156, 0x080c, 0x2107, 0x080c, 0x22dd, 0x080c, 0x2131, 0x0804,
+ 0x30bf, 0xa001, 0x0cf0, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6,
+ 0x0136, 0x0146, 0x0156, 0x080c, 0x13c8, 0x0804, 0x30bf, 0x0106,
+ 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c,
+ 0x22dd, 0x080c, 0x13c8, 0x0804, 0x30bf, 0x0106, 0x0006, 0x0126,
+ 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2107, 0x080c,
+ 0x13c8, 0x0804, 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6,
+ 0x0136, 0x0146, 0x0156, 0x080c, 0x22dd, 0x080c, 0x13c8, 0x080c,
+ 0x2131, 0x0804, 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6,
+ 0x0136, 0x0146, 0x0156, 0x080c, 0x2107, 0x080c, 0x22dd, 0x080c,
+ 0x13c8, 0x0804, 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6,
+ 0x0136, 0x0146, 0x0156, 0x080c, 0x2107, 0x080c, 0x13c8, 0x080c,
+ 0x2131, 0x0804, 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6,
+ 0x0136, 0x0146, 0x0156, 0x080c, 0x13c8, 0x080c, 0x2131, 0x0804,
+ 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146,
+ 0x0156, 0x080c, 0x2107, 0x080c, 0x22dd, 0x080c, 0x13c8, 0x080c,
+ 0x2131, 0x0804, 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6,
+ 0x0136, 0x0146, 0x0156, 0x080c, 0x27a4, 0x0804, 0x30bf, 0x0106,
+ 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c,
+ 0x27a4, 0x080c, 0x22dd, 0x0804, 0x30bf, 0x0106, 0x0006, 0x0126,
+ 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x27a4, 0x080c,
+ 0x2107, 0x0804, 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6,
+ 0x0136, 0x0146, 0x0156, 0x080c, 0x27a4, 0x080c, 0x2107, 0x080c,
+ 0x22dd, 0x0804, 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6,
+ 0x0136, 0x0146, 0x0156, 0x080c, 0x27a4, 0x080c, 0x2131, 0x0804,
+ 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146,
+ 0x0156, 0x080c, 0x27a4, 0x080c, 0x22dd, 0x080c, 0x2131, 0x0804,
+ 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146,
+ 0x0156, 0x080c, 0x27a4, 0x080c, 0x2107, 0x080c, 0x2131, 0x0804,
+ 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146,
+ 0x0156, 0x080c, 0x27a4, 0x080c, 0x2107, 0x080c, 0x22dd, 0x080c,
+ 0x2131, 0x0804, 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6,
+ 0x0136, 0x0146, 0x0156, 0x080c, 0x27a4, 0x080c, 0x13c8, 0x0804,
+ 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146,
+ 0x0156, 0x080c, 0x27a4, 0x080c, 0x22dd, 0x080c, 0x13c8, 0x0804,
+ 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146,
+ 0x0156, 0x080c, 0x27a4, 0x080c, 0x2107, 0x080c, 0x13c8, 0x0804,
+ 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146,
+ 0x0156, 0x080c, 0x27a4, 0x080c, 0x22dd, 0x080c, 0x13c8, 0x080c,
+ 0x2131, 0x0804, 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6,
+ 0x0136, 0x0146, 0x0156, 0x080c, 0x27a4, 0x080c, 0x2107, 0x080c,
+ 0x22dd, 0x080c, 0x13c8, 0x0804, 0x30bf, 0x0106, 0x0006, 0x0126,
+ 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x27a4, 0x080c,
+ 0x2107, 0x080c, 0x13c8, 0x080c, 0x2131, 0x0804, 0x30bf, 0x0106,
+ 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c,
+ 0x27a4, 0x080c, 0x13c8, 0x080c, 0x2131, 0x0804, 0x30bf, 0x0106,
+ 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c,
+ 0x27a4, 0x080c, 0x2107, 0x080c, 0x22dd, 0x080c, 0x13c8, 0x080c,
+ 0x2131, 0x0804, 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6,
+ 0x0136, 0x0146, 0x0156, 0x080c, 0xab5d, 0x0804, 0x30bf, 0x0106,
+ 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c,
+ 0xab5d, 0x080c, 0x22dd, 0x0804, 0x30bf, 0x0106, 0x0006, 0x0126,
+ 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2107, 0x080c,
+ 0xab5d, 0x0804, 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6,
+ 0x0136, 0x0146, 0x0156, 0x080c, 0x2107, 0x080c, 0xab5d, 0x080c,
+ 0x22dd, 0x0804, 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6,
+ 0x0136, 0x0146, 0x0156, 0x080c, 0xab5d, 0x080c, 0x2131, 0x0804,
+ 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146,
+ 0x0156, 0x080c, 0xab5d, 0x080c, 0x22dd, 0x080c, 0x2131, 0x0804,
+ 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146,
+ 0x0156, 0x080c, 0x2107, 0x080c, 0xab5d, 0x080c, 0x2131, 0x0804,
+ 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146,
+ 0x0156, 0x080c, 0x2107, 0x080c, 0xab5d, 0x080c, 0x22dd, 0x080c,
+ 0x2131, 0x0804, 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6,
+ 0x0136, 0x0146, 0x0156, 0x080c, 0xab5d, 0x080c, 0x13c8, 0x0804,
+ 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146,
+ 0x0156, 0x080c, 0xab5d, 0x080c, 0x22dd, 0x080c, 0x13c8, 0x0804,
+ 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146,
+ 0x0156, 0x080c, 0x2107, 0x080c, 0xab5d, 0x080c, 0x13c8, 0x0804,
+ 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146,
+ 0x0156, 0x080c, 0x2107, 0x080c, 0xab5d, 0x080c, 0x22dd, 0x080c,
+ 0x13c8, 0x0804, 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6,
+ 0x0136, 0x0146, 0x0156, 0x080c, 0xab5d, 0x080c, 0x13c8, 0x080c,
+ 0x2131, 0x0804, 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6,
+ 0x0136, 0x0146, 0x0156, 0x080c, 0xab5d, 0x080c, 0x22dd, 0x080c,
+ 0x13c8, 0x080c, 0x2131, 0x0804, 0x30bf, 0x0106, 0x0006, 0x0126,
+ 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2107, 0x080c,
+ 0xab5d, 0x080c, 0x13c8, 0x080c, 0x2131, 0x0804, 0x30bf, 0x0106,
+ 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c,
+ 0x2107, 0x080c, 0xab5d, 0x080c, 0x22dd, 0x080c, 0x13c8, 0x080c,
+ 0x2131, 0x0804, 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6,
+ 0x0136, 0x0146, 0x0156, 0x080c, 0x27a4, 0x080c, 0xab5d, 0x0804,
+ 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146,
+ 0x0156, 0x080c, 0x27a4, 0x080c, 0xab5d, 0x080c, 0x22dd, 0x0804,
+ 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146,
+ 0x0156, 0x080c, 0x27a4, 0x080c, 0x2107, 0x080c, 0xab5d, 0x0804,
+ 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146,
+ 0x0156, 0x080c, 0x27a4, 0x080c, 0x2107, 0x080c, 0xab5d, 0x080c,
+ 0x22dd, 0x0804, 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6,
+ 0x0136, 0x0146, 0x0156, 0x080c, 0x27a4, 0x080c, 0xab5d, 0x080c,
+ 0x2131, 0x0804, 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6,
+ 0x0136, 0x0146, 0x0156, 0x080c, 0x27a4, 0x080c, 0xab5d, 0x080c,
+ 0x22dd, 0x080c, 0x2131, 0x0804, 0x30bf, 0x0106, 0x0006, 0x0126,
+ 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x27a4, 0x080c,
+ 0x2107, 0x080c, 0xab5d, 0x080c, 0x2131, 0x0804, 0x30bf, 0x0106,
+ 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c,
+ 0x27a4, 0x080c, 0x2107, 0x080c, 0xab5d, 0x080c, 0x22dd, 0x080c,
+ 0x2131, 0x0804, 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6,
+ 0x0136, 0x0146, 0x0156, 0x080c, 0x27a4, 0x080c, 0xab5d, 0x080c,
+ 0x13c8, 0x0804, 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6,
+ 0x0136, 0x0146, 0x0156, 0x080c, 0x27a4, 0x080c, 0xab5d, 0x080c,
+ 0x22dd, 0x080c, 0x13c8, 0x0804, 0x30bf, 0x0106, 0x0006, 0x0126,
+ 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x27a4, 0x080c,
+ 0x2107, 0x080c, 0xab5d, 0x080c, 0x13c8, 0x0804, 0x30bf, 0x0106,
+ 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c,
+ 0x27a4, 0x080c, 0x2107, 0x080c, 0xab5d, 0x080c, 0x22dd, 0x080c,
+ 0x13c8, 0x0804, 0x30bf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6,
+ 0x0136, 0x0146, 0x0156, 0x080c, 0x27a4, 0x080c, 0xab5d, 0x080c,
+ 0x13c8, 0x080c, 0x2131, 0x04d8, 0x0106, 0x0006, 0x0126, 0x01c6,
+ 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x27a4, 0x080c, 0xab5d,
+ 0x080c, 0x22dd, 0x080c, 0x13c8, 0x080c, 0x2131, 0x0440, 0x0106,
+ 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c,
+ 0x27a4, 0x080c, 0x2107, 0x080c, 0x13c8, 0x080c, 0xab5d, 0x080c,
+ 0x2131, 0x00a8, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136,
+ 0x0146, 0x0156, 0x080c, 0x27a4, 0x080c, 0x2107, 0x080c, 0xab5d,
+ 0x080c, 0x22dd, 0x080c, 0x13c8, 0x080c, 0x2131, 0x0000, 0x015e,
+ 0x014e, 0x013e, 0x01de, 0x01ce, 0x012e, 0x000e, 0x010e, 0x000d,
+ 0x00b6, 0x00c6, 0x0026, 0x0046, 0x9026, 0x080c, 0x6b8b, 0x1904,
+ 0x31dc, 0x72dc, 0x2001, 0x197d, 0x2004, 0x9005, 0x1110, 0xd29c,
+ 0x0148, 0xd284, 0x1138, 0xd2bc, 0x1904, 0x31dc, 0x080c, 0x31e1,
+ 0x0804, 0x31dc, 0xd2cc, 0x1904, 0x31dc, 0x080c, 0x769d, 0x1120,
+ 0x70af, 0xffff, 0x0804, 0x31dc, 0xd294, 0x0120, 0x70af, 0xffff,
+ 0x0804, 0x31dc, 0x080c, 0x3463, 0x0160, 0x080c, 0xd35d, 0x0128,
+ 0x2001, 0x1818, 0x203c, 0x0804, 0x3165, 0x70af, 0xffff, 0x0804,
+ 0x31dc, 0x2001, 0x1818, 0x203c, 0x7294, 0xd284, 0x0904, 0x3165,
+ 0xd28c, 0x1904, 0x3165, 0x0036, 0x73ac, 0x938e, 0xffff, 0x1110,
+ 0x2019, 0x0001, 0x8314, 0x92e0, 0x1d80, 0x2c04, 0x938c, 0x0001,
+ 0x0120, 0x9084, 0xff00, 0x8007, 0x0010, 0x9084, 0x00ff, 0x970e,
+ 0x05d0, 0x908e, 0x0000, 0x05b8, 0x908e, 0x00ff, 0x1150, 0x7230,
+ 0xd284, 0x15b0, 0x7294, 0xc28d, 0x7296, 0x70af, 0xffff, 0x003e,
+ 0x04a0, 0x900e, 0x080c, 0x26a1, 0x080c, 0x6718, 0x1538, 0x9006,
+ 0xb8bb, 0x0520, 0xb8ac, 0x9005, 0x0148, 0x00c6, 0x2060, 0x080c,
+ 0x8d87, 0x00ce, 0x090c, 0x9128, 0xb8af, 0x0000, 0x080c, 0x6bcd,
+ 0x1168, 0x7030, 0xd08c, 0x0130, 0xb800, 0xd0bc, 0x0138, 0x080c,
+ 0x6a74, 0x0120, 0x080c, 0x31fa, 0x0148, 0x0028, 0x080c, 0x3346,
+ 0x080c, 0x3226, 0x0118, 0x8318, 0x0804, 0x3112, 0x73ae, 0x0010,
+ 0x70af, 0xffff, 0x003e, 0x0804, 0x31dc, 0x9780, 0x3474, 0x203d,
+ 0x97bc, 0xff00, 0x873f, 0x2041, 0x007e, 0x70ac, 0x9096, 0xffff,
+ 0x1118, 0x900e, 0x28a8, 0x0050, 0x9812, 0x0220, 0x2008, 0x9802,
+ 0x20a8, 0x0020, 0x70af, 0xffff, 0x0804, 0x31dc, 0x2700, 0x0156,
+ 0x0016, 0x9106, 0x0904, 0x31d1, 0xc484, 0x080c, 0x6783, 0x0168,
+ 0x080c, 0xd35d, 0x1904, 0x31d1, 0x080c, 0x3463, 0x1904, 0x31d1,
+ 0x080c, 0x6718, 0x1904, 0x31d9, 0x0008, 0xc485, 0xb8bb, 0x0520,
+ 0xb8ac, 0x9005, 0x0148, 0x00c6, 0x2060, 0x080c, 0x8d87, 0x00ce,
+ 0x090c, 0x9128, 0xb8af, 0x0000, 0x080c, 0x6bcd, 0x1130, 0x7030,
+ 0xd08c, 0x01f8, 0xb800, 0xd0bc, 0x11e0, 0x7294, 0xd28c, 0x0180,
+ 0x080c, 0x6bcd, 0x9082, 0x0006, 0x02e0, 0xd484, 0x1118, 0x080c,
+ 0x673d, 0x0028, 0x080c, 0x33d9, 0x01a0, 0x080c, 0x3404, 0x0088,
+ 0x080c, 0x3346, 0x080c, 0xd35d, 0x1160, 0x080c, 0x3226, 0x0188,
+ 0x0040, 0x080c, 0xd35d, 0x1118, 0x080c, 0x33d9, 0x0110, 0x0451,
+ 0x0140, 0x001e, 0x8108, 0x015e, 0x1f04, 0x317e, 0x70af, 0xffff,
+ 0x0018, 0x001e, 0x015e, 0x71ae, 0x004e, 0x002e, 0x00ce, 0x00be,
+ 0x0005, 0x00c6, 0x0016, 0x70af, 0x0001, 0x2009, 0x007e, 0x080c,
+ 0x6718, 0x1168, 0xb813, 0x00ff, 0xb817, 0xfffe, 0x080c, 0x3346,
+ 0x04a9, 0x0128, 0x70dc, 0xc0bd, 0x70de, 0x080c, 0xd0a1, 0x001e,
+ 0x00ce, 0x0005, 0x0016, 0x0076, 0x00d6, 0x00c6, 0x2001, 0x184c,
+ 0x2004, 0x9084, 0x00ff, 0xb842, 0x080c, 0xafbf, 0x01d0, 0x2b00,
+ 0x6012, 0x080c, 0xd0ce, 0x6023, 0x0001, 0x9006, 0x080c, 0x66b5,
+ 0x2001, 0x0000, 0x080c, 0x66c9, 0x0126, 0x2091, 0x8000, 0x70a8,
+ 0x8000, 0x70aa, 0x012e, 0x2009, 0x0004, 0x080c, 0xafec, 0x9085,
+ 0x0001, 0x00ce, 0x00de, 0x007e, 0x001e, 0x0005, 0x0016, 0x0076,
+ 0x00d6, 0x00c6, 0x2001, 0x184c, 0x2004, 0x9084, 0x00ff, 0xb842,
+ 0x080c, 0xafbf, 0x0548, 0x2b00, 0x6012, 0xb800, 0xc0c4, 0xb802,
+ 0xb8a0, 0x9086, 0x007e, 0x0140, 0xb804, 0x9084, 0x00ff, 0x9086,
+ 0x0006, 0x1110, 0x080c, 0x32fb, 0x080c, 0xd0ce, 0x6023, 0x0001,
+ 0x9006, 0x080c, 0x66b5, 0x2001, 0x0002, 0x080c, 0x66c9, 0x0126,
+ 0x2091, 0x8000, 0x70a8, 0x8000, 0x70aa, 0x012e, 0x2009, 0x0002,
+ 0x080c, 0xafec, 0x9085, 0x0001, 0x00ce, 0x00de, 0x007e, 0x001e,
+ 0x0005, 0x00b6, 0x00c6, 0x0026, 0x2009, 0x0080, 0x080c, 0x6718,
+ 0x1140, 0xb813, 0x00ff, 0xb817, 0xfffc, 0x0039, 0x0110, 0x70e3,
+ 0xffff, 0x002e, 0x00ce, 0x00be, 0x0005, 0x0016, 0x0076, 0x00d6,
+ 0x00c6, 0x080c, 0xaef8, 0x01d0, 0x2b00, 0x6012, 0x080c, 0xd0ce,
+ 0x6023, 0x0001, 0x9006, 0x080c, 0x66b5, 0x2001, 0x0002, 0x080c,
+ 0x66c9, 0x0126, 0x2091, 0x8000, 0x70e4, 0x8000, 0x70e6, 0x012e,
+ 0x2009, 0x0002, 0x080c, 0xafec, 0x9085, 0x0001, 0x00ce, 0x00de,
+ 0x007e, 0x001e, 0x0005, 0x00c6, 0x00d6, 0x0126, 0x2091, 0x8000,
+ 0x2009, 0x007f, 0x080c, 0x6718, 0x11b8, 0xb813, 0x00ff, 0xb817,
+ 0xfffd, 0xb8d7, 0x0004, 0x080c, 0xaef8, 0x0170, 0x2b00, 0x6012,
+ 0x6316, 0x6023, 0x0001, 0x620a, 0x080c, 0xd0ce, 0x2009, 0x0022,
+ 0x080c, 0xafec, 0x9085, 0x0001, 0x012e, 0x00de, 0x00ce, 0x0005,
+ 0x00e6, 0x00c6, 0x0066, 0x0036, 0x0026, 0x00b6, 0x21f0, 0x080c,
+ 0xaaf7, 0x0106, 0x080c, 0x95c4, 0x080c, 0x9530, 0x080c, 0xaa48,
+ 0x080c, 0xbeab, 0x010e, 0x090c, 0xab13, 0x3e08, 0x2130, 0x81ff,
+ 0x0120, 0x20a9, 0x007e, 0x900e, 0x0018, 0x20a9, 0x007f, 0x900e,
+ 0x0016, 0x080c, 0x6783, 0x1140, 0x9686, 0x0002, 0x1118, 0xb800,
+ 0xd0bc, 0x1110, 0x080c, 0x6192, 0x001e, 0x8108, 0x1f04, 0x32e0,
+ 0x9686, 0x0001, 0x190c, 0x3437, 0x00be, 0x002e, 0x003e, 0x006e,
+ 0x00ce, 0x00ee, 0x0005, 0x00e6, 0x00c6, 0x0046, 0x0036, 0x0026,
+ 0x0016, 0x00b6, 0x080c, 0xaaf7, 0x0106, 0x6210, 0x2258, 0xbaa0,
+ 0x0026, 0x2019, 0x0029, 0x080c, 0x95b9, 0x0076, 0x2039, 0x0000,
+ 0x080c, 0x9476, 0x2c08, 0x080c, 0xe465, 0x007e, 0x001e, 0x010e,
+ 0x090c, 0xab13, 0xba10, 0xbb14, 0xbc84, 0x080c, 0x6192, 0xba12,
+ 0xbb16, 0xbc86, 0x00be, 0x001e, 0x002e, 0x003e, 0x004e, 0x00ce,
+ 0x00ee, 0x0005, 0x00e6, 0x0006, 0x00b6, 0x6010, 0x2058, 0xb8a0,
+ 0x00be, 0x9086, 0x0080, 0x0150, 0x2071, 0x1800, 0x70a8, 0x9005,
+ 0x0110, 0x8001, 0x70aa, 0x000e, 0x00ee, 0x0005, 0x2071, 0x1800,
+ 0x70e4, 0x9005, 0x0dc0, 0x8001, 0x70e6, 0x0ca8, 0xb800, 0xc08c,
+ 0xb802, 0x0005, 0x00f6, 0x00e6, 0x00c6, 0x00b6, 0x0046, 0x0036,
+ 0x0026, 0x0016, 0x0156, 0x2178, 0x080c, 0xaaf7, 0x0106, 0x81ff,
+ 0x1118, 0x20a9, 0x0001, 0x0078, 0x080c, 0x5820, 0xd0c4, 0x0140,
+ 0xd0a4, 0x0130, 0x9006, 0x2020, 0x2009, 0x002d, 0x080c, 0xe795,
+ 0x20a9, 0x0800, 0x9016, 0x0026, 0x928e, 0x007e, 0x0904, 0x33b5,
+ 0x928e, 0x007f, 0x0904, 0x33b5, 0x928e, 0x0080, 0x05f0, 0x9288,
+ 0x1000, 0x210c, 0x81ff, 0x05c8, 0x8fff, 0x1150, 0x2001, 0x198f,
+ 0x0006, 0x2003, 0x0001, 0x080c, 0x33c6, 0x000e, 0x2003, 0x0000,
+ 0x00b6, 0x00c6, 0x2158, 0x2001, 0x0001, 0x080c, 0x6b97, 0x00ce,
+ 0x00be, 0x2019, 0x0029, 0x080c, 0x95b9, 0x0076, 0x2039, 0x0000,
+ 0x080c, 0x9476, 0x00b6, 0x00c6, 0x0026, 0x2158, 0xba04, 0x9294,
+ 0x00ff, 0x9286, 0x0006, 0x1118, 0xb807, 0x0404, 0x0028, 0x2001,
+ 0x0004, 0x8007, 0x9215, 0xba06, 0x002e, 0x00ce, 0x00be, 0x0016,
+ 0x2c08, 0x080c, 0xe465, 0x001e, 0x007e, 0x002e, 0x8210, 0x1f04,
+ 0x336b, 0x010e, 0x090c, 0xab13, 0x015e, 0x001e, 0x002e, 0x003e,
+ 0x004e, 0x00be, 0x00ce, 0x00ee, 0x00fe, 0x0005, 0x0046, 0x0026,
+ 0x0016, 0x080c, 0x5820, 0xd0c4, 0x0140, 0xd0a4, 0x0130, 0x9006,
+ 0x2220, 0x2009, 0x0029, 0x080c, 0xe795, 0x001e, 0x002e, 0x004e,
+ 0x0005, 0x0016, 0x0026, 0x0036, 0x00c6, 0x7294, 0x82ff, 0x01e8,
+ 0x080c, 0x6bc5, 0x11d0, 0x2100, 0x080c, 0x26d4, 0x81ff, 0x01b8,
+ 0x2019, 0x0001, 0x8314, 0x92e0, 0x1d80, 0x2c04, 0xd384, 0x0120,
+ 0x9084, 0xff00, 0x8007, 0x0010, 0x9084, 0x00ff, 0x9116, 0x0138,
+ 0x9096, 0x00ff, 0x0110, 0x8318, 0x0c68, 0x9085, 0x0001, 0x00ce,
+ 0x003e, 0x002e, 0x001e, 0x0005, 0x0016, 0x00c6, 0x0126, 0x2091,
+ 0x8000, 0x080c, 0xaaf7, 0x0106, 0x0036, 0x2019, 0x0029, 0x00c1,
+ 0x003e, 0x010e, 0x090c, 0xab13, 0x9180, 0x1000, 0x2004, 0x9065,
+ 0x0158, 0x0016, 0x00c6, 0x2061, 0x1b3a, 0x001e, 0x6112, 0x080c,
+ 0x32fb, 0x001e, 0x080c, 0x673d, 0x012e, 0x00ce, 0x001e, 0x0005,
+ 0x0016, 0x0026, 0x2110, 0x080c, 0xa5dd, 0x080c, 0xeafd, 0x002e,
+ 0x001e, 0x0005, 0x2001, 0x1837, 0x2004, 0xd0cc, 0x0005, 0x00c6,
+ 0x00b6, 0x080c, 0x769d, 0x1118, 0x20a9, 0x0800, 0x0010, 0x20a9,
+ 0x0782, 0x080c, 0x769d, 0x1110, 0x900e, 0x0010, 0x2009, 0x007e,
+ 0x9180, 0x1000, 0x2004, 0x905d, 0x0130, 0x86ff, 0x0110, 0xb800,
+ 0xd0bc, 0x090c, 0x673d, 0x8108, 0x1f04, 0x3448, 0x2061, 0x1800,
+ 0x607f, 0x0000, 0x6080, 0x9084, 0x00ff, 0x6082, 0x60b3, 0x0000,
+ 0x00be, 0x00ce, 0x0005, 0x2001, 0x1869, 0x2004, 0xd0bc, 0x0005,
+ 0x2011, 0x1848, 0x2214, 0xd2ec, 0x0005, 0x0026, 0x2011, 0x1867,
+ 0x2214, 0xd2dc, 0x002e, 0x0005, 0x7eef, 0x7de8, 0x7ce4, 0x80e2,
+ 0x7be1, 0x80e0, 0x80dc, 0x80da, 0x7ad9, 0x80d6, 0x80d5, 0x80d4,
+ 0x80d3, 0x80d2, 0x80d1, 0x79ce, 0x78cd, 0x80cc, 0x80cb, 0x80ca,
+ 0x80c9, 0x80c7, 0x80c6, 0x77c5, 0x76c3, 0x80bc, 0x80ba, 0x75b9,
+ 0x80b6, 0x74b5, 0x73b4, 0x72b3, 0x80b2, 0x80b1, 0x80ae, 0x71ad,
+ 0x80ac, 0x70ab, 0x6faa, 0x6ea9, 0x80a7, 0x6da6, 0x6ca5, 0x6ba3,
+ 0x6a9f, 0x699e, 0x689d, 0x809b, 0x8098, 0x6797, 0x6690, 0x658f,
+ 0x6488, 0x6384, 0x6282, 0x8081, 0x8080, 0x617c, 0x607a, 0x8079,
+ 0x5f76, 0x8075, 0x8074, 0x8073, 0x8072, 0x8071, 0x806e, 0x5e6d,
+ 0x806c, 0x5d6b, 0x5c6a, 0x5b69, 0x8067, 0x5a66, 0x5965, 0x5863,
+ 0x575c, 0x565a, 0x5559, 0x8056, 0x8055, 0x5454, 0x5353, 0x5252,
+ 0x5151, 0x504e, 0x4f4d, 0x804c, 0x804b, 0x4e4a, 0x4d49, 0x8047,
+ 0x4c46, 0x8045, 0x8043, 0x803c, 0x803a, 0x8039, 0x8036, 0x4b35,
+ 0x8034, 0x4a33, 0x4932, 0x4831, 0x802e, 0x472d, 0x462c, 0x452b,
+ 0x442a, 0x4329, 0x4227, 0x8026, 0x8025, 0x4123, 0x401f, 0x3f1e,
+ 0x3e1d, 0x3d1b, 0x3c18, 0x8017, 0x8010, 0x3b0f, 0x3a08, 0x8004,
+ 0x3902, 0x8001, 0x8000, 0x8000, 0x3800, 0x3700, 0x3600, 0x8000,
+ 0x3500, 0x8000, 0x8000, 0x8000, 0x3400, 0x8000, 0x8000, 0x8000,
+ 0x8000, 0x8000, 0x8000, 0x3300, 0x3200, 0x8000, 0x8000, 0x8000,
+ 0x8000, 0x8000, 0x8000, 0x3100, 0x3000, 0x8000, 0x8000, 0x2f00,
+ 0x8000, 0x2e00, 0x2d00, 0x2c00, 0x8000, 0x8000, 0x8000, 0x2b00,
+ 0x8000, 0x2a00, 0x2900, 0x2800, 0x8000, 0x2700, 0x2600, 0x2500,
+ 0x2400, 0x2300, 0x2200, 0x8000, 0x8000, 0x2100, 0x2000, 0x1f00,
+ 0x1e00, 0x1d00, 0x1c00, 0x8000, 0x8000, 0x1b00, 0x1a00, 0x8000,
+ 0x1900, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x1800,
+ 0x8000, 0x1700, 0x1600, 0x1500, 0x8000, 0x1400, 0x1300, 0x1200,
+ 0x1100, 0x1000, 0x0f00, 0x8000, 0x8000, 0x0e00, 0x0d00, 0x0c00,
+ 0x0b00, 0x0a00, 0x0900, 0x8000, 0x8000, 0x0800, 0x0700, 0x8000,
+ 0x0600, 0x8000, 0x8000, 0x8000, 0x0500, 0x0400, 0x0300, 0x8000,
+ 0x0200, 0x8000, 0x8000, 0x8000, 0x0100, 0x8000, 0x8000, 0x8000,
+ 0x8000, 0x8000, 0x8000, 0x0000, 0x8000, 0x8000, 0x8000, 0x8000,
0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
- 0x8000, 0x2071, 0x189e, 0x7003, 0x0002, 0x9006, 0x7016, 0x701a,
- 0x704a, 0x704e, 0x700e, 0x7042, 0x7046, 0x703b, 0x18ba, 0x703f,
- 0x18ba, 0x7007, 0x0001, 0x080c, 0x1072, 0x090c, 0x0d85, 0x2900,
- 0x706a, 0xa867, 0x0002, 0xa8ab, 0xdcb0, 0x080c, 0x1072, 0x090c,
- 0x0d85, 0x2900, 0x706e, 0xa867, 0x0002, 0xa8ab, 0xdcb0, 0x0005,
- 0x2071, 0x189e, 0x7004, 0x0002, 0x35b8, 0x35b9, 0x35cc, 0x35e0,
- 0x0005, 0x1004, 0x35c9, 0x0e04, 0x35c9, 0x2079, 0x0000, 0x0126,
- 0x2091, 0x8000, 0x700c, 0x9005, 0x1128, 0x700f, 0x0001, 0x012e,
- 0x0468, 0x0005, 0x012e, 0x0ce8, 0x2079, 0x0000, 0x2061, 0x18b8,
- 0x2c4c, 0xa86c, 0x908e, 0x0100, 0x0128, 0x9086, 0x0200, 0x0904,
- 0x36b4, 0x0005, 0x7018, 0x2048, 0x2061, 0x1800, 0x701c, 0x0807,
- 0x7014, 0x2048, 0xa864, 0x9094, 0x00ff, 0x9296, 0x0029, 0x1120,
- 0xaa78, 0xd2fc, 0x0128, 0x0005, 0x9086, 0x0103, 0x0108, 0x0005,
- 0x2079, 0x0000, 0x2061, 0x1800, 0x701c, 0x0807, 0x2061, 0x1800,
- 0x7880, 0x908a, 0x0040, 0x1210, 0x61d0, 0x0042, 0x2100, 0x908a,
- 0x003f, 0x1a04, 0x36b1, 0x61d0, 0x0804, 0x3646, 0x3688, 0x36c0,
- 0x36b1, 0x36cc, 0x36d6, 0x36dc, 0x36e0, 0x36f0, 0x36f4, 0x370a,
- 0x3710, 0x3716, 0x3721, 0x372c, 0x373b, 0x374a, 0x3758, 0x376f,
- 0x378a, 0x36b1, 0x3833, 0x3871, 0x3916, 0x3927, 0x394a, 0x36b1,
- 0x36b1, 0x36b1, 0x3982, 0x39a2, 0x39ab, 0x39d7, 0x39dd, 0x36b1,
- 0x3a23, 0x36b1, 0x36b1, 0x36b1, 0x36b1, 0x36b1, 0x3a2e, 0x3a37,
- 0x3a3f, 0x3a41, 0x36b1, 0x36b1, 0x36b1, 0x36b1, 0x36b1, 0x36b1,
- 0x3a71, 0x36b1, 0x36b1, 0x36b1, 0x36b1, 0x36b1, 0x3a8e, 0x3af2,
- 0x36b1, 0x36b1, 0x36b1, 0x36b1, 0x36b1, 0x36b1, 0x0002, 0x3b1c,
- 0x3b1f, 0x3b7e, 0x3b97, 0x3bc7, 0x3e6d, 0x36b1, 0x53db, 0x36b1,
- 0x36b1, 0x36b1, 0x36b1, 0x36b1, 0x36b1, 0x36b1, 0x36b1, 0x370a,
- 0x3710, 0x4365, 0x584a, 0x4383, 0x546a, 0x54bc, 0x55c7, 0x36b1,
- 0x5629, 0x5665, 0x5696, 0x57a6, 0x56c3, 0x5726, 0x36b1, 0x4387,
- 0x453c, 0x4552, 0x4577, 0x45dc, 0x4650, 0x4670, 0x46e7, 0x4743,
- 0x479f, 0x47a2, 0x47c7, 0x4839, 0x48a3, 0x48ab, 0x49e0, 0x4b58,
- 0x4b8c, 0x4df0, 0x36b1, 0x4e0e, 0x4eb4, 0x4f9d, 0x4ff7, 0x36b1,
- 0x50ae, 0x36b1, 0x511a, 0x5135, 0x48ab, 0x537b, 0x714c, 0x0000,
- 0x2021, 0x4000, 0x080c, 0x4c0a, 0x0126, 0x2091, 0x8000, 0x0e04,
- 0x3692, 0x0010, 0x012e, 0x0cc0, 0x7c36, 0x9486, 0x4000, 0x0118,
- 0x7833, 0x0011, 0x0010, 0x7833, 0x0010, 0x7c82, 0x7986, 0x7a8a,
- 0x7b8e, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c,
- 0x1200, 0x7007, 0x0001, 0x2091, 0x5000, 0x700f, 0x0000, 0x012e,
- 0x0005, 0x2021, 0x4001, 0x08b0, 0x2021, 0x4002, 0x0898, 0x2021,
- 0x4003, 0x0880, 0x2021, 0x4005, 0x0868, 0x2021, 0x4006, 0x0850,
- 0x2039, 0x0001, 0x902e, 0x2520, 0x7b88, 0x7a8c, 0x7884, 0x7990,
- 0x81ff, 0x0d98, 0x0804, 0x4c17, 0x2039, 0x0001, 0x902e, 0x2520,
- 0x7b88, 0x7a8c, 0x7884, 0x7990, 0x0804, 0x4c1a, 0x7984, 0x7888,
- 0x2114, 0x200a, 0x0804, 0x3688, 0x7984, 0x2114, 0x0804, 0x3688,
- 0x20e1, 0x0000, 0x2099, 0x0021, 0x20e9, 0x0000, 0x20a1, 0x0021,
- 0x20a9, 0x001f, 0x4003, 0x7984, 0x7a88, 0x7b8c, 0x0804, 0x3688,
- 0x7884, 0x2060, 0x0804, 0x373d, 0x2009, 0x0003, 0x2011, 0x0003,
- 0x2019, 0x000f, 0x789b, 0x0137, 0x7893, 0xffff, 0x2001, 0x188f,
- 0x2004, 0x9005, 0x0118, 0x7896, 0x0804, 0x3688, 0x7897, 0x0001,
- 0x0804, 0x3688, 0x2039, 0x0001, 0x7d98, 0x7c9c, 0x0804, 0x36c4,
- 0x2039, 0x0001, 0x7d98, 0x7c9c, 0x0804, 0x36d0, 0x79a0, 0x9182,
- 0x0040, 0x0210, 0x0804, 0x36bd, 0x2138, 0x7d98, 0x7c9c, 0x0804,
- 0x36c4, 0x79a0, 0x9182, 0x0040, 0x0210, 0x0804, 0x36bd, 0x2138,
- 0x7d98, 0x7c9c, 0x0804, 0x36d0, 0x79a0, 0x9182, 0x0040, 0x0210,
- 0x0804, 0x36bd, 0x21e8, 0x7984, 0x7888, 0x20a9, 0x0001, 0x21a0,
- 0x4004, 0x0804, 0x3688, 0x2061, 0x0800, 0xe10c, 0x9006, 0x2c15,
- 0x9200, 0x8c60, 0x8109, 0x1dd8, 0x2010, 0x9005, 0x0904, 0x3688,
- 0x0804, 0x36b7, 0x79a0, 0x9182, 0x0040, 0x0210, 0x0804, 0x36bd,
- 0x21e0, 0x20a9, 0x0001, 0x7984, 0x2198, 0x4012, 0x0804, 0x3688,
- 0x2069, 0x1847, 0x7884, 0x7990, 0x911a, 0x1a04, 0x36bd, 0x8019,
- 0x0904, 0x36bd, 0x684a, 0x6942, 0x788c, 0x6852, 0x7888, 0x6856,
- 0x9006, 0x685a, 0x685e, 0x080c, 0x79d8, 0x0804, 0x3688, 0x2069,
- 0x1847, 0x7884, 0x7994, 0x911a, 0x1a04, 0x36bd, 0x8019, 0x0904,
- 0x36bd, 0x684e, 0x6946, 0x788c, 0x6862, 0x7888, 0x6866, 0x9006,
- 0x686a, 0x686e, 0x0126, 0x2091, 0x8000, 0x080c, 0x6c6d, 0x012e,
- 0x0804, 0x3688, 0x902e, 0x2520, 0x81ff, 0x0120, 0x2009, 0x0001,
- 0x0804, 0x36ba, 0x7984, 0x7b88, 0x7a8c, 0x20a9, 0x0005, 0x20e9,
- 0x0001, 0x20a1, 0x18a6, 0x4101, 0x080c, 0x4bce, 0x1120, 0x2009,
- 0x0002, 0x0804, 0x36ba, 0x2009, 0x0020, 0xa85c, 0x9080, 0x0019,
- 0xaf60, 0x080c, 0x4c17, 0x701f, 0x37ae, 0x0005, 0xa864, 0x2008,
- 0x9084, 0x00ff, 0x9096, 0x0011, 0x0168, 0x9096, 0x0019, 0x0150,
- 0x9096, 0x0015, 0x0138, 0x9096, 0x0048, 0x0120, 0x9096, 0x0029,
- 0x1904, 0x36ba, 0x810f, 0x918c, 0x00ff, 0x0904, 0x36ba, 0x7112,
- 0x7010, 0x8001, 0x0560, 0x7012, 0x080c, 0x4bce, 0x1120, 0x2009,
- 0x0002, 0x0804, 0x36ba, 0x2009, 0x0020, 0x7068, 0x2040, 0xa28c,
- 0xa390, 0xa494, 0xa598, 0x9290, 0x0040, 0x9399, 0x0000, 0x94a1,
- 0x0000, 0x95a9, 0x0000, 0xa85c, 0x9080, 0x0019, 0xaf60, 0x080c,
- 0x4c17, 0x701f, 0x37ec, 0x0005, 0xa864, 0x9084, 0x00ff, 0x9096,
- 0x0002, 0x0120, 0x9096, 0x000a, 0x1904, 0x36ba, 0x0888, 0x7014,
- 0x2048, 0xa868, 0xc0fd, 0xa86a, 0xa864, 0x9084, 0x00ff, 0x9096,
- 0x0029, 0x1160, 0xc2fd, 0xaa7a, 0x080c, 0x62eb, 0x0150, 0x0126,
- 0x2091, 0x8000, 0xa87a, 0xa982, 0x012e, 0x0050, 0x080c, 0x661b,
- 0x1128, 0x7007, 0x0003, 0x701f, 0x3818, 0x0005, 0x080c, 0x7165,
- 0x0126, 0x2091, 0x8000, 0x20a9, 0x0005, 0x20e1, 0x0001, 0x2099,
- 0x18a6, 0x400a, 0x2100, 0x9210, 0x9399, 0x0000, 0x94a1, 0x0000,
- 0x95a9, 0x0000, 0xa85c, 0x9080, 0x0019, 0x2009, 0x0020, 0x012e,
- 0xaf60, 0x0804, 0x4c1a, 0x2091, 0x8000, 0x7837, 0x4000, 0x7833,
- 0x0010, 0x7883, 0x4000, 0x7887, 0x4953, 0x788b, 0x5020, 0x788f,
- 0x2020, 0x2009, 0x017f, 0x2104, 0x7892, 0x3f00, 0x7896, 0x2061,
- 0x0100, 0x6200, 0x2061, 0x0200, 0x603c, 0x8007, 0x9205, 0x789a,
- 0x2009, 0x04fd, 0x2104, 0x789e, 0x2091, 0x5000, 0x2091, 0x4080,
- 0x2001, 0x0089, 0x2004, 0xd084, 0x0180, 0x2001, 0x1a26, 0x2004,
- 0x9005, 0x0128, 0x2001, 0x008b, 0x2004, 0xd0fc, 0x0dd8, 0x2001,
- 0x008a, 0x2003, 0x0002, 0x2003, 0x1001, 0x2071, 0x0080, 0x0804,
- 0x0427, 0x81ff, 0x1904, 0x36ba, 0x7984, 0x080c, 0x6789, 0x1904,
- 0x36bd, 0x7e98, 0x9684, 0x3fff, 0x9082, 0x4000, 0x1a04, 0x36bd,
- 0x7c88, 0x7d8c, 0x080c, 0x69bf, 0x080c, 0x694c, 0x1518, 0x2061,
- 0x1ddc, 0x0126, 0x2091, 0x8000, 0x6000, 0x9086, 0x0000, 0x0148,
- 0x6014, 0x904d, 0x0130, 0xa86c, 0x9406, 0x1118, 0xa870, 0x9506,
- 0x0150, 0x012e, 0x9ce0, 0x001c, 0x2001, 0x181a, 0x2004, 0x9c02,
- 0x1a04, 0x36ba, 0x0c30, 0x080c, 0xc802, 0x012e, 0x0904, 0x36ba,
- 0x0804, 0x3688, 0x900e, 0x2001, 0x0005, 0x080c, 0x7165, 0x0126,
- 0x2091, 0x8000, 0x080c, 0xcf21, 0x080c, 0x6f19, 0x012e, 0x0804,
- 0x3688, 0x00a6, 0x2950, 0xb198, 0x080c, 0x6789, 0x1904, 0x3903,
- 0xb6a4, 0x9684, 0x3fff, 0x9082, 0x4000, 0x16e8, 0xb49c, 0xb5a0,
- 0x080c, 0x69bf, 0x080c, 0x694c, 0x1520, 0x2061, 0x1ddc, 0x0126,
- 0x2091, 0x8000, 0x6000, 0x9086, 0x0000, 0x0148, 0x6014, 0x904d,
- 0x0130, 0xa86c, 0x9406, 0x1118, 0xa870, 0x9506, 0x0158, 0x012e,
- 0x9ce0, 0x001c, 0x2001, 0x181a, 0x2004, 0x9c02, 0x2009, 0x000d,
- 0x12b0, 0x0c28, 0x080c, 0xc802, 0x012e, 0x2009, 0x0003, 0x0178,
- 0x00e0, 0x900e, 0x2001, 0x0005, 0x080c, 0x7165, 0x0126, 0x2091,
- 0x8000, 0x080c, 0xcf21, 0x080c, 0x6f0d, 0x012e, 0x0070, 0xb097,
- 0x4005, 0xb19a, 0x0010, 0xb097, 0x4006, 0x900e, 0x9085, 0x0001,
- 0x2001, 0x0030, 0x2a48, 0x00ae, 0x0005, 0xb097, 0x4000, 0x9006,
- 0x918d, 0x0001, 0x2008, 0x2a48, 0x00ae, 0x0005, 0x81ff, 0x1904,
- 0x36ba, 0x080c, 0x4be5, 0x0904, 0x36bd, 0x080c, 0x6850, 0x0904,
- 0x36ba, 0x080c, 0x69c5, 0x0904, 0x36ba, 0x0804, 0x4667, 0x81ff,
- 0x1904, 0x36ba, 0x080c, 0x4c01, 0x0904, 0x36bd, 0x080c, 0x6a53,
- 0x0904, 0x36ba, 0x2019, 0x0005, 0x79a8, 0x080c, 0x69e0, 0x0904,
- 0x36ba, 0x7888, 0x908a, 0x1000, 0x1a04, 0x36bd, 0x8003, 0x800b,
- 0x810b, 0x9108, 0x080c, 0x8842, 0x79a8, 0xd184, 0x1904, 0x3688,
- 0x0804, 0x4667, 0x0126, 0x2091, 0x8000, 0x81ff, 0x0118, 0x2009,
- 0x0001, 0x0450, 0x2029, 0x07ff, 0x645c, 0x2400, 0x9506, 0x01f8,
- 0x2508, 0x080c, 0x6789, 0x11d8, 0x080c, 0x6a53, 0x1128, 0x2009,
- 0x0002, 0x62c0, 0x2518, 0x00c0, 0x2019, 0x0004, 0x900e, 0x080c,
- 0x69e0, 0x1118, 0x2009, 0x0006, 0x0078, 0x7884, 0x908a, 0x1000,
- 0x1270, 0x8003, 0x800b, 0x810b, 0x9108, 0x080c, 0x8842, 0x8529,
- 0x1ae0, 0x012e, 0x0804, 0x3688, 0x012e, 0x0804, 0x36ba, 0x012e,
- 0x0804, 0x36bd, 0x080c, 0x4be5, 0x0904, 0x36bd, 0x080c, 0x6850,
- 0x0904, 0x36ba, 0x080c, 0xaae0, 0xbaa0, 0x2019, 0x0005, 0x00c6,
- 0x9066, 0x080c, 0x95c1, 0x0076, 0x903e, 0x080c, 0x947e, 0x900e,
- 0x080c, 0xe440, 0x007e, 0x00ce, 0x080c, 0xaafc, 0x080c, 0x69bf,
- 0x0804, 0x3688, 0x080c, 0x4be5, 0x0904, 0x36bd, 0x080c, 0x69bf,
- 0x2208, 0x0804, 0x3688, 0x0156, 0x00d6, 0x00e6, 0x00c6, 0x2069,
- 0x1910, 0x6810, 0x6914, 0x910a, 0x1208, 0x900e, 0x6816, 0x9016,
- 0x901e, 0x2071, 0x19e9, 0x7028, 0x9065, 0x0118, 0x8210, 0x600c,
- 0x0cd8, 0x2300, 0x9218, 0x00ce, 0x00ee, 0x00de, 0x015e, 0x0804,
- 0x3688, 0x00f6, 0x0016, 0x907d, 0x0138, 0x9006, 0x8000, 0x2f0c,
- 0x81ff, 0x0110, 0x2178, 0x0cd0, 0x001e, 0x00fe, 0x0005, 0x2069,
- 0x1910, 0x6910, 0x62bc, 0x0804, 0x3688, 0x81ff, 0x0120, 0x2009,
- 0x0001, 0x0804, 0x36ba, 0x0126, 0x2091, 0x8000, 0x080c, 0x583a,
- 0x0128, 0x2009, 0x0007, 0x012e, 0x0804, 0x36ba, 0x012e, 0x615c,
- 0x9190, 0x3489, 0x2215, 0x9294, 0x00ff, 0x637c, 0x83ff, 0x0108,
- 0x6280, 0x67dc, 0x97c4, 0x000a, 0x98c6, 0x000a, 0x1118, 0x2031,
- 0x0001, 0x00e8, 0x97c4, 0x0022, 0x98c6, 0x0022, 0x1118, 0x2031,
- 0x0003, 0x00a8, 0x97c4, 0x0012, 0x98c6, 0x0012, 0x1118, 0x2031,
- 0x0002, 0x0068, 0x080c, 0x76a5, 0x1118, 0x2031, 0x0004, 0x0038,
- 0xd79c, 0x0120, 0x2009, 0x0005, 0x0804, 0x36ba, 0x9036, 0x7e9a,
- 0x7f9e, 0x0804, 0x3688, 0x614c, 0x6250, 0x2019, 0x1987, 0x231c,
- 0x2001, 0x1988, 0x2004, 0x789a, 0x0804, 0x3688, 0x0126, 0x2091,
- 0x8000, 0x6138, 0x623c, 0x6340, 0x012e, 0x0804, 0x3688, 0x080c,
- 0x4c01, 0x0904, 0x36bd, 0xba44, 0xbb38, 0x0804, 0x3688, 0x080c,
- 0x0d85, 0x080c, 0x4c01, 0x2110, 0x0904, 0x36bd, 0xb804, 0x908c,
- 0x00ff, 0x918e, 0x0006, 0x0140, 0x9084, 0xff00, 0x9086, 0x0600,
- 0x2009, 0x0009, 0x1904, 0x36ba, 0x0126, 0x2091, 0x8000, 0x2019,
- 0x0005, 0x00c6, 0x9066, 0x080c, 0xaae0, 0x080c, 0xa5c6, 0x080c,
- 0x95c1, 0x0076, 0x903e, 0x080c, 0x947e, 0x900e, 0x080c, 0xe440,
- 0x007e, 0x00ce, 0x080c, 0xaafc, 0xb807, 0x0407, 0x012e, 0x0804,
- 0x3688, 0x614c, 0x6250, 0x7884, 0x604e, 0x7b88, 0x6352, 0x2069,
- 0x1847, 0x831f, 0x9305, 0x6816, 0x788c, 0x2069, 0x1987, 0x2d1c,
- 0x206a, 0x7e98, 0x9682, 0x0014, 0x1210, 0x2031, 0x07d0, 0x2069,
- 0x1988, 0x2d04, 0x266a, 0x789a, 0x0804, 0x3688, 0x0126, 0x2091,
- 0x8000, 0x6138, 0x7884, 0x603a, 0x910e, 0xd1b4, 0x190c, 0x0eeb,
- 0xd0c4, 0x01a8, 0x00d6, 0x78a8, 0x2009, 0x199e, 0x200a, 0x78ac,
- 0x2011, 0x199f, 0x2012, 0x2069, 0x0100, 0x6838, 0x9086, 0x0007,
- 0x1118, 0x2214, 0x6a5a, 0x0010, 0x210c, 0x695a, 0x00de, 0x2011,
- 0x0116, 0x220c, 0x7888, 0xd08c, 0x0118, 0x918d, 0x0040, 0x0010,
- 0x918c, 0xff7f, 0x2112, 0x7988, 0x613e, 0x6140, 0x788c, 0x6042,
- 0x910e, 0xd1e4, 0x190c, 0x0f06, 0x9084, 0x0020, 0x0130, 0x78b4,
- 0x6046, 0x9084, 0x0001, 0x090c, 0x4365, 0x6040, 0xd0cc, 0x0120,
- 0x78b0, 0x2011, 0x0114, 0x2012, 0x012e, 0x0804, 0x3688, 0x00f6,
- 0x2079, 0x1800, 0x7a38, 0xa898, 0x9084, 0xfebf, 0x9215, 0xa89c,
- 0x9084, 0xfebf, 0x8002, 0x9214, 0x7838, 0x9084, 0x0140, 0x9215,
- 0x7a3a, 0xa897, 0x4000, 0x900e, 0x9085, 0x0001, 0x2001, 0x0000,
- 0x00fe, 0x0005, 0x7898, 0x9005, 0x01a8, 0x7888, 0x9025, 0x0904,
- 0x36bd, 0x788c, 0x902d, 0x0904, 0x36bd, 0x900e, 0x080c, 0x6789,
- 0x1120, 0xba44, 0xbb38, 0xbc46, 0xbd3a, 0x9186, 0x07ff, 0x0190,
- 0x8108, 0x0ca0, 0x080c, 0x4c01, 0x0904, 0x36bd, 0x7888, 0x900d,
- 0x0904, 0x36bd, 0x788c, 0x9005, 0x0904, 0x36bd, 0xba44, 0xb946,
- 0xbb38, 0xb83a, 0x0804, 0x3688, 0x2011, 0xbc09, 0x0010, 0x2011,
- 0xbc05, 0x080c, 0x583a, 0x1904, 0x36ba, 0x00c6, 0x2061, 0x0100,
- 0x7984, 0x9186, 0x00ff, 0x1130, 0x2001, 0x1818, 0x2004, 0x9085,
- 0xff00, 0x0088, 0x9182, 0x007f, 0x16e0, 0x9188, 0x3489, 0x210d,
- 0x918c, 0x00ff, 0x2001, 0x1818, 0x2004, 0x0026, 0x9116, 0x002e,
- 0x0580, 0x810f, 0x9105, 0x0126, 0x2091, 0x8000, 0x0006, 0x080c,
- 0xaed8, 0x000e, 0x0510, 0x602e, 0x620a, 0x7984, 0x00b6, 0x080c,
- 0x6724, 0x2b08, 0x00be, 0x1500, 0x6112, 0x6023, 0x0001, 0x080c,
- 0x4bce, 0x01d0, 0x9006, 0xa866, 0x7007, 0x0003, 0xa832, 0xa868,
- 0xc0fd, 0xa86a, 0x701f, 0x3b77, 0x2900, 0x6016, 0x2009, 0x0032,
- 0x080c, 0xafcc, 0x012e, 0x00ce, 0x0005, 0x012e, 0x00ce, 0x0804,
- 0x36ba, 0x00ce, 0x0804, 0x36bd, 0x080c, 0xaf2e, 0x0cb0, 0xa830,
- 0x9086, 0x0100, 0x0904, 0x36ba, 0x0804, 0x3688, 0x2061, 0x1a74,
- 0x0126, 0x2091, 0x8000, 0x6000, 0xd084, 0x0170, 0x6104, 0x6208,
- 0x2061, 0x1800, 0x6354, 0x6074, 0x789a, 0x60c0, 0x789e, 0x60bc,
- 0x78aa, 0x012e, 0x0804, 0x3688, 0x900e, 0x2110, 0x0c88, 0x81ff,
- 0x1904, 0x36ba, 0x080c, 0x76a5, 0x0904, 0x36ba, 0x0126, 0x2091,
- 0x8000, 0x6254, 0x6074, 0x9202, 0x0248, 0x9085, 0x0001, 0x080c,
- 0x270b, 0x080c, 0x5a5d, 0x012e, 0x0804, 0x3688, 0x012e, 0x0804,
- 0x36bd, 0x0006, 0x0016, 0x00c6, 0x00e6, 0x2001, 0x19aa, 0x2070,
- 0x2061, 0x1847, 0x6008, 0x2072, 0x900e, 0x2011, 0x1400, 0x080c,
- 0x936c, 0x7206, 0x00ee, 0x00ce, 0x001e, 0x000e, 0x0005, 0x0126,
- 0x2091, 0x8000, 0x81ff, 0x0128, 0x012e, 0x2021, 0x400b, 0x0804,
- 0x368a, 0x7884, 0xd0fc, 0x0158, 0x2001, 0x002a, 0x2004, 0x9005,
- 0x0180, 0x9082, 0x00e1, 0x0298, 0x012e, 0x0804, 0x36bd, 0x2001,
- 0x002a, 0x2004, 0x9005, 0x0128, 0x2069, 0x1847, 0x6908, 0x9102,
- 0x1230, 0x012e, 0x0804, 0x36bd, 0x012e, 0x0804, 0x36ba, 0x080c,
- 0xae60, 0x0dd0, 0x7884, 0xd0fc, 0x0904, 0x3c46, 0x00c6, 0x080c,
- 0x4bce, 0x00ce, 0x0d88, 0xa867, 0x0000, 0x7884, 0xa80a, 0x7898,
- 0xa80e, 0x789c, 0xa812, 0x2001, 0x002e, 0x2004, 0xa81a, 0x2001,
- 0x002f, 0x2004, 0xa81e, 0x2001, 0x0030, 0x2004, 0xa822, 0x2001,
- 0x0031, 0x2004, 0xa826, 0x2001, 0x0034, 0x2004, 0xa82a, 0x2001,
- 0x0035, 0x2004, 0xa82e, 0x2001, 0x002a, 0x2004, 0x9080, 0x0003,
- 0x9084, 0x00fc, 0x8004, 0xa816, 0x080c, 0x3dd0, 0x0928, 0x7014,
- 0x2048, 0xad2c, 0xac28, 0xab1c, 0xaa18, 0xa930, 0xa808, 0xd0b4,
- 0x1120, 0x2029, 0x0000, 0x2021, 0x0000, 0x8906, 0x8006, 0x8007,
- 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, 0x001b, 0x080c, 0x4c17,
- 0x701f, 0x3d0d, 0x7023, 0x0001, 0x012e, 0x0005, 0x080c, 0xaae0,
- 0x0046, 0x0086, 0x0096, 0x00a6, 0x00b6, 0x00c6, 0x00d6, 0x00e6,
- 0x00f6, 0x080c, 0x3bb1, 0x2001, 0x19a0, 0x2003, 0x0000, 0x2021,
- 0x000a, 0x2061, 0x0100, 0x6104, 0x0016, 0x60bb, 0x0000, 0x60bf,
- 0x32e1, 0x60bf, 0x0012, 0x080c, 0x3e3f, 0x080c, 0x3dfe, 0x00f6,
- 0x00e6, 0x0086, 0x2940, 0x2071, 0x19e9, 0x2079, 0x0090, 0x00d6,
- 0x2069, 0x0000, 0x6884, 0xd0b4, 0x0140, 0x2001, 0x0035, 0x2004,
- 0x780e, 0x2001, 0x0034, 0x2004, 0x780a, 0x00de, 0x2011, 0x0001,
- 0x080c, 0x41a9, 0x008e, 0x00ee, 0x00fe, 0x080c, 0x40d6, 0x080c,
- 0x4003, 0x05b8, 0x2001, 0x020b, 0x2004, 0x9084, 0x0140, 0x1db8,
- 0x080c, 0x421d, 0x00f6, 0x2079, 0x0300, 0x78bc, 0x00fe, 0x908c,
- 0x0070, 0x1560, 0x2071, 0x0200, 0x7037, 0x0000, 0x7050, 0x9084,
- 0xff00, 0x9086, 0x3200, 0x1510, 0x7037, 0x0001, 0x7050, 0x9084,
- 0xff00, 0x9086, 0xe100, 0x11d0, 0x7037, 0x0000, 0x7054, 0x7037,
- 0x0000, 0x715c, 0x9106, 0x1190, 0x2001, 0x1820, 0x2004, 0x9106,
- 0x1168, 0x00c6, 0x2061, 0x0100, 0x6024, 0x9084, 0x1e00, 0x00ce,
- 0x0138, 0x080c, 0x400d, 0x080c, 0x3df9, 0x0058, 0x080c, 0x3df9,
- 0x080c, 0x4141, 0x080c, 0x40cc, 0x2001, 0x020b, 0x2004, 0xd0e4,
- 0x0dd8, 0x2001, 0x032a, 0x2003, 0x0004, 0x2061, 0x0100, 0x6027,
- 0x0002, 0x001e, 0x6106, 0x2011, 0x020d, 0x2013, 0x0020, 0x60bb,
- 0x0000, 0x60bf, 0x0108, 0x60bf, 0x0012, 0x2001, 0x0004, 0x200c,
- 0x918c, 0xfffd, 0x2102, 0x080c, 0x1352, 0x2009, 0x0028, 0x080c,
- 0x2241, 0x2001, 0x0227, 0x200c, 0x2102, 0x080c, 0xaafc, 0x00fe,
- 0x00ee, 0x00de, 0x00ce, 0x00be, 0x00ae, 0x009e, 0x008e, 0x004e,
- 0x2001, 0x19a0, 0x2004, 0x9005, 0x1118, 0x012e, 0x0804, 0x3688,
- 0x012e, 0x2021, 0x400c, 0x0804, 0x368a, 0x0016, 0x0026, 0x0036,
- 0x0046, 0x0056, 0x0076, 0x0086, 0x0096, 0x00d6, 0x0156, 0x7014,
- 0x2048, 0x7020, 0x20a8, 0x8000, 0x7022, 0xa804, 0x9005, 0x0904,
- 0x3d69, 0x2048, 0x1f04, 0x3d1d, 0x7068, 0x2040, 0xa28c, 0xa390,
- 0xa494, 0xa598, 0xa930, 0xa808, 0xd0b4, 0x1120, 0x2029, 0x0000,
- 0x2021, 0x0000, 0x0096, 0x7014, 0x2048, 0xa864, 0x009e, 0x9086,
- 0x0103, 0x0170, 0x8906, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084,
- 0xffc0, 0x9080, 0x001b, 0x080c, 0x4c17, 0x701f, 0x3d0d, 0x00b0,
+ 0x8000, 0x8000, 0x8000, 0x8000, 0x2071, 0x189e, 0x7003, 0x0002,
+ 0x9006, 0x7016, 0x701a, 0x704a, 0x704e, 0x700e, 0x7042, 0x7046,
+ 0x703b, 0x18ba, 0x703f, 0x18ba, 0x7007, 0x0001, 0x080c, 0x1066,
+ 0x090c, 0x0d79, 0x2900, 0x706a, 0xa867, 0x0002, 0xa8ab, 0xdcb0,
+ 0x080c, 0x1066, 0x090c, 0x0d79, 0x2900, 0x706e, 0xa867, 0x0002,
+ 0xa8ab, 0xdcb0, 0x0005, 0x2071, 0x189e, 0x7004, 0x0002, 0x35a3,
+ 0x35a4, 0x35b7, 0x35cb, 0x0005, 0x1004, 0x35b4, 0x0e04, 0x35b4,
+ 0x2079, 0x0000, 0x0126, 0x2091, 0x8000, 0x700c, 0x9005, 0x1128,
+ 0x700f, 0x0001, 0x012e, 0x0468, 0x0005, 0x012e, 0x0ce8, 0x2079,
+ 0x0000, 0x2061, 0x18b8, 0x2c4c, 0xa86c, 0x908e, 0x0100, 0x0128,
+ 0x9086, 0x0200, 0x0904, 0x369f, 0x0005, 0x7018, 0x2048, 0x2061,
+ 0x1800, 0x701c, 0x0807, 0x7014, 0x2048, 0xa864, 0x9094, 0x00ff,
+ 0x9296, 0x0029, 0x1120, 0xaa78, 0xd2fc, 0x0128, 0x0005, 0x9086,
+ 0x0103, 0x0108, 0x0005, 0x2079, 0x0000, 0x2061, 0x1800, 0x701c,
+ 0x0807, 0x2061, 0x1800, 0x7880, 0x908a, 0x0040, 0x1210, 0x61d0,
+ 0x0042, 0x2100, 0x908a, 0x003f, 0x1a04, 0x369c, 0x61d0, 0x0804,
+ 0x3631, 0x3673, 0x36ab, 0x369c, 0x36b7, 0x36c1, 0x36c7, 0x36cb,
+ 0x36db, 0x36df, 0x36f5, 0x36fb, 0x3701, 0x370c, 0x3717, 0x3726,
+ 0x3735, 0x3743, 0x375a, 0x3775, 0x369c, 0x381e, 0x385c, 0x3901,
+ 0x3912, 0x3935, 0x369c, 0x369c, 0x369c, 0x396d, 0x398d, 0x3996,
+ 0x39c2, 0x39c8, 0x369c, 0x3a0e, 0x369c, 0x369c, 0x369c, 0x369c,
+ 0x369c, 0x3a19, 0x3a22, 0x3a2a, 0x3a2c, 0x369c, 0x369c, 0x369c,
+ 0x369c, 0x369c, 0x369c, 0x3a5c, 0x369c, 0x369c, 0x369c, 0x369c,
+ 0x369c, 0x3a79, 0x3add, 0x369c, 0x369c, 0x369c, 0x369c, 0x369c,
+ 0x369c, 0x0002, 0x3b07, 0x3b0a, 0x3b69, 0x3b82, 0x3bb2, 0x3e58,
+ 0x369c, 0x53d5, 0x369c, 0x369c, 0x369c, 0x369c, 0x369c, 0x369c,
+ 0x369c, 0x369c, 0x36f5, 0x36fb, 0x435b, 0x5844, 0x4379, 0x5464,
+ 0x54b6, 0x55c1, 0x369c, 0x5623, 0x565f, 0x5690, 0x57a0, 0x56bd,
+ 0x5720, 0x369c, 0x437d, 0x4536, 0x454c, 0x4571, 0x45d6, 0x464a,
+ 0x466a, 0x46e1, 0x473d, 0x4799, 0x479c, 0x47c1, 0x4833, 0x489d,
+ 0x48a5, 0x49da, 0x4b52, 0x4b86, 0x4dea, 0x369c, 0x4e08, 0x4eae,
+ 0x4f97, 0x4ff1, 0x369c, 0x50a8, 0x369c, 0x5114, 0x512f, 0x48a5,
+ 0x5375, 0x714c, 0x0000, 0x2021, 0x4000, 0x080c, 0x4c04, 0x0126,
+ 0x2091, 0x8000, 0x0e04, 0x367d, 0x0010, 0x012e, 0x0cc0, 0x7c36,
+ 0x9486, 0x4000, 0x0118, 0x7833, 0x0011, 0x0010, 0x7833, 0x0010,
+ 0x7c82, 0x7986, 0x7a8a, 0x7b8e, 0x2091, 0x4080, 0x2001, 0x0089,
+ 0x2004, 0xd084, 0x190c, 0x11f4, 0x7007, 0x0001, 0x2091, 0x5000,
+ 0x700f, 0x0000, 0x012e, 0x0005, 0x2021, 0x4001, 0x08b0, 0x2021,
+ 0x4002, 0x0898, 0x2021, 0x4003, 0x0880, 0x2021, 0x4005, 0x0868,
+ 0x2021, 0x4006, 0x0850, 0x2039, 0x0001, 0x902e, 0x2520, 0x7b88,
+ 0x7a8c, 0x7884, 0x7990, 0x81ff, 0x0d98, 0x0804, 0x4c11, 0x2039,
+ 0x0001, 0x902e, 0x2520, 0x7b88, 0x7a8c, 0x7884, 0x7990, 0x0804,
+ 0x4c14, 0x7984, 0x7888, 0x2114, 0x200a, 0x0804, 0x3673, 0x7984,
+ 0x2114, 0x0804, 0x3673, 0x20e1, 0x0000, 0x2099, 0x0021, 0x20e9,
+ 0x0000, 0x20a1, 0x0021, 0x20a9, 0x001f, 0x4003, 0x7984, 0x7a88,
+ 0x7b8c, 0x0804, 0x3673, 0x7884, 0x2060, 0x0804, 0x3728, 0x2009,
+ 0x0003, 0x2011, 0x0003, 0x2019, 0x0012, 0x789b, 0x0137, 0x7893,
+ 0xffff, 0x2001, 0x188f, 0x2004, 0x9005, 0x0118, 0x7896, 0x0804,
+ 0x3673, 0x7897, 0x0001, 0x0804, 0x3673, 0x2039, 0x0001, 0x7d98,
+ 0x7c9c, 0x0804, 0x36af, 0x2039, 0x0001, 0x7d98, 0x7c9c, 0x0804,
+ 0x36bb, 0x79a0, 0x9182, 0x0040, 0x0210, 0x0804, 0x36a8, 0x2138,
+ 0x7d98, 0x7c9c, 0x0804, 0x36af, 0x79a0, 0x9182, 0x0040, 0x0210,
+ 0x0804, 0x36a8, 0x2138, 0x7d98, 0x7c9c, 0x0804, 0x36bb, 0x79a0,
+ 0x9182, 0x0040, 0x0210, 0x0804, 0x36a8, 0x21e8, 0x7984, 0x7888,
+ 0x20a9, 0x0001, 0x21a0, 0x4004, 0x0804, 0x3673, 0x2061, 0x0800,
+ 0xe10c, 0x9006, 0x2c15, 0x9200, 0x8c60, 0x8109, 0x1dd8, 0x2010,
+ 0x9005, 0x0904, 0x3673, 0x0804, 0x36a2, 0x79a0, 0x9182, 0x0040,
+ 0x0210, 0x0804, 0x36a8, 0x21e0, 0x20a9, 0x0001, 0x7984, 0x2198,
+ 0x4012, 0x0804, 0x3673, 0x2069, 0x1847, 0x7884, 0x7990, 0x911a,
+ 0x1a04, 0x36a8, 0x8019, 0x0904, 0x36a8, 0x684a, 0x6942, 0x788c,
+ 0x6852, 0x7888, 0x6856, 0x9006, 0x685a, 0x685e, 0x080c, 0x79d0,
+ 0x0804, 0x3673, 0x2069, 0x1847, 0x7884, 0x7994, 0x911a, 0x1a04,
+ 0x36a8, 0x8019, 0x0904, 0x36a8, 0x684e, 0x6946, 0x788c, 0x6862,
+ 0x7888, 0x6866, 0x9006, 0x686a, 0x686e, 0x0126, 0x2091, 0x8000,
+ 0x080c, 0x6c65, 0x012e, 0x0804, 0x3673, 0x902e, 0x2520, 0x81ff,
+ 0x0120, 0x2009, 0x0001, 0x0804, 0x36a5, 0x7984, 0x7b88, 0x7a8c,
+ 0x20a9, 0x0005, 0x20e9, 0x0001, 0x20a1, 0x18a6, 0x4101, 0x080c,
+ 0x4bc8, 0x1120, 0x2009, 0x0002, 0x0804, 0x36a5, 0x2009, 0x0020,
+ 0xa85c, 0x9080, 0x0019, 0xaf60, 0x080c, 0x4c11, 0x701f, 0x3799,
+ 0x0005, 0xa864, 0x2008, 0x9084, 0x00ff, 0x9096, 0x0011, 0x0168,
+ 0x9096, 0x0019, 0x0150, 0x9096, 0x0015, 0x0138, 0x9096, 0x0048,
+ 0x0120, 0x9096, 0x0029, 0x1904, 0x36a5, 0x810f, 0x918c, 0x00ff,
+ 0x0904, 0x36a5, 0x7112, 0x7010, 0x8001, 0x0560, 0x7012, 0x080c,
+ 0x4bc8, 0x1120, 0x2009, 0x0002, 0x0804, 0x36a5, 0x2009, 0x0020,
+ 0x7068, 0x2040, 0xa28c, 0xa390, 0xa494, 0xa598, 0x9290, 0x0040,
+ 0x9399, 0x0000, 0x94a1, 0x0000, 0x95a9, 0x0000, 0xa85c, 0x9080,
+ 0x0019, 0xaf60, 0x080c, 0x4c11, 0x701f, 0x37d7, 0x0005, 0xa864,
+ 0x9084, 0x00ff, 0x9096, 0x0002, 0x0120, 0x9096, 0x000a, 0x1904,
+ 0x36a5, 0x0888, 0x7014, 0x2048, 0xa868, 0xc0fd, 0xa86a, 0xa864,
+ 0x9084, 0x00ff, 0x9096, 0x0029, 0x1160, 0xc2fd, 0xaa7a, 0x080c,
+ 0x62e5, 0x0150, 0x0126, 0x2091, 0x8000, 0xa87a, 0xa982, 0x012e,
+ 0x0050, 0x080c, 0x6615, 0x1128, 0x7007, 0x0003, 0x701f, 0x3803,
+ 0x0005, 0x080c, 0x715d, 0x0126, 0x2091, 0x8000, 0x20a9, 0x0005,
+ 0x20e1, 0x0001, 0x2099, 0x18a6, 0x400a, 0x2100, 0x9210, 0x9399,
+ 0x0000, 0x94a1, 0x0000, 0x95a9, 0x0000, 0xa85c, 0x9080, 0x0019,
+ 0x2009, 0x0020, 0x012e, 0xaf60, 0x0804, 0x4c14, 0x2091, 0x8000,
+ 0x7837, 0x4000, 0x7833, 0x0010, 0x7883, 0x4000, 0x7887, 0x4953,
+ 0x788b, 0x5020, 0x788f, 0x2020, 0x2009, 0x017f, 0x2104, 0x7892,
+ 0x3f00, 0x7896, 0x2061, 0x0100, 0x6200, 0x2061, 0x0200, 0x603c,
+ 0x8007, 0x9205, 0x789a, 0x2009, 0x04fd, 0x2104, 0x789e, 0x2091,
+ 0x5000, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x0180,
+ 0x2001, 0x1a26, 0x2004, 0x9005, 0x0128, 0x2001, 0x008b, 0x2004,
+ 0xd0fc, 0x0dd8, 0x2001, 0x008a, 0x2003, 0x0002, 0x2003, 0x1001,
+ 0x2071, 0x0080, 0x0804, 0x0427, 0x81ff, 0x1904, 0x36a5, 0x7984,
+ 0x080c, 0x6783, 0x1904, 0x36a8, 0x7e98, 0x9684, 0x3fff, 0x9082,
+ 0x4000, 0x1a04, 0x36a8, 0x7c88, 0x7d8c, 0x080c, 0x69b7, 0x080c,
+ 0x6944, 0x1518, 0x2061, 0x1ddc, 0x0126, 0x2091, 0x8000, 0x6000,
+ 0x9086, 0x0000, 0x0148, 0x6014, 0x904d, 0x0130, 0xa86c, 0x9406,
+ 0x1118, 0xa870, 0x9506, 0x0150, 0x012e, 0x9ce0, 0x001c, 0x2001,
+ 0x181a, 0x2004, 0x9c02, 0x1a04, 0x36a5, 0x0c30, 0x080c, 0xc81b,
+ 0x012e, 0x0904, 0x36a5, 0x0804, 0x3673, 0x900e, 0x2001, 0x0005,
+ 0x080c, 0x715d, 0x0126, 0x2091, 0x8000, 0x080c, 0xcf3e, 0x080c,
+ 0x6f11, 0x012e, 0x0804, 0x3673, 0x00a6, 0x2950, 0xb198, 0x080c,
+ 0x6783, 0x1904, 0x38ee, 0xb6a4, 0x9684, 0x3fff, 0x9082, 0x4000,
+ 0x16e8, 0xb49c, 0xb5a0, 0x080c, 0x69b7, 0x080c, 0x6944, 0x1520,
+ 0x2061, 0x1ddc, 0x0126, 0x2091, 0x8000, 0x6000, 0x9086, 0x0000,
+ 0x0148, 0x6014, 0x904d, 0x0130, 0xa86c, 0x9406, 0x1118, 0xa870,
+ 0x9506, 0x0158, 0x012e, 0x9ce0, 0x001c, 0x2001, 0x181a, 0x2004,
+ 0x9c02, 0x2009, 0x000d, 0x12b0, 0x0c28, 0x080c, 0xc81b, 0x012e,
+ 0x2009, 0x0003, 0x0178, 0x00e0, 0x900e, 0x2001, 0x0005, 0x080c,
+ 0x715d, 0x0126, 0x2091, 0x8000, 0x080c, 0xcf3e, 0x080c, 0x6f05,
+ 0x012e, 0x0070, 0xb097, 0x4005, 0xb19a, 0x0010, 0xb097, 0x4006,
+ 0x900e, 0x9085, 0x0001, 0x2001, 0x0030, 0x2a48, 0x00ae, 0x0005,
+ 0xb097, 0x4000, 0x9006, 0x918d, 0x0001, 0x2008, 0x2a48, 0x00ae,
+ 0x0005, 0x81ff, 0x1904, 0x36a5, 0x080c, 0x4bdf, 0x0904, 0x36a8,
+ 0x080c, 0x684a, 0x0904, 0x36a5, 0x080c, 0x69bd, 0x0904, 0x36a5,
+ 0x0804, 0x4661, 0x81ff, 0x1904, 0x36a5, 0x080c, 0x4bfb, 0x0904,
+ 0x36a8, 0x080c, 0x6a4b, 0x0904, 0x36a5, 0x2019, 0x0005, 0x79a8,
+ 0x080c, 0x69d8, 0x0904, 0x36a5, 0x7888, 0x908a, 0x1000, 0x1a04,
+ 0x36a8, 0x8003, 0x800b, 0x810b, 0x9108, 0x080c, 0x883a, 0x79a8,
+ 0xd184, 0x1904, 0x3673, 0x0804, 0x4661, 0x0126, 0x2091, 0x8000,
+ 0x81ff, 0x0118, 0x2009, 0x0001, 0x0450, 0x2029, 0x07ff, 0x645c,
+ 0x2400, 0x9506, 0x01f8, 0x2508, 0x080c, 0x6783, 0x11d8, 0x080c,
+ 0x6a4b, 0x1128, 0x2009, 0x0002, 0x62c0, 0x2518, 0x00c0, 0x2019,
+ 0x0004, 0x900e, 0x080c, 0x69d8, 0x1118, 0x2009, 0x0006, 0x0078,
+ 0x7884, 0x908a, 0x1000, 0x1270, 0x8003, 0x800b, 0x810b, 0x9108,
+ 0x080c, 0x883a, 0x8529, 0x1ae0, 0x012e, 0x0804, 0x3673, 0x012e,
+ 0x0804, 0x36a5, 0x012e, 0x0804, 0x36a8, 0x080c, 0x4bdf, 0x0904,
+ 0x36a8, 0x080c, 0x684a, 0x0904, 0x36a5, 0x080c, 0xaaf7, 0xbaa0,
+ 0x2019, 0x0005, 0x00c6, 0x9066, 0x080c, 0x95b9, 0x0076, 0x903e,
+ 0x080c, 0x9476, 0x900e, 0x080c, 0xe465, 0x007e, 0x00ce, 0x080c,
+ 0xab13, 0x080c, 0x69b7, 0x0804, 0x3673, 0x080c, 0x4bdf, 0x0904,
+ 0x36a8, 0x080c, 0x69b7, 0x2208, 0x0804, 0x3673, 0x0156, 0x00d6,
+ 0x00e6, 0x00c6, 0x2069, 0x1910, 0x6810, 0x6914, 0x910a, 0x1208,
+ 0x900e, 0x6816, 0x9016, 0x901e, 0x2071, 0x19e9, 0x7028, 0x9065,
+ 0x0118, 0x8210, 0x600c, 0x0cd8, 0x2300, 0x9218, 0x00ce, 0x00ee,
+ 0x00de, 0x015e, 0x0804, 0x3673, 0x00f6, 0x0016, 0x907d, 0x0138,
+ 0x9006, 0x8000, 0x2f0c, 0x81ff, 0x0110, 0x2178, 0x0cd0, 0x001e,
+ 0x00fe, 0x0005, 0x2069, 0x1910, 0x6910, 0x62bc, 0x0804, 0x3673,
+ 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x36a5, 0x0126, 0x2091,
+ 0x8000, 0x080c, 0x5834, 0x0128, 0x2009, 0x0007, 0x012e, 0x0804,
+ 0x36a5, 0x012e, 0x615c, 0x9190, 0x3474, 0x2215, 0x9294, 0x00ff,
+ 0x637c, 0x83ff, 0x0108, 0x6280, 0x67dc, 0x97c4, 0x000a, 0x98c6,
+ 0x000a, 0x1118, 0x2031, 0x0001, 0x00e8, 0x97c4, 0x0022, 0x98c6,
+ 0x0022, 0x1118, 0x2031, 0x0003, 0x00a8, 0x97c4, 0x0012, 0x98c6,
+ 0x0012, 0x1118, 0x2031, 0x0002, 0x0068, 0x080c, 0x769d, 0x1118,
+ 0x2031, 0x0004, 0x0038, 0xd79c, 0x0120, 0x2009, 0x0005, 0x0804,
+ 0x36a5, 0x9036, 0x7e9a, 0x7f9e, 0x0804, 0x3673, 0x614c, 0x6250,
+ 0x2019, 0x1987, 0x231c, 0x2001, 0x1988, 0x2004, 0x789a, 0x0804,
+ 0x3673, 0x0126, 0x2091, 0x8000, 0x6138, 0x623c, 0x6340, 0x012e,
+ 0x0804, 0x3673, 0x080c, 0x4bfb, 0x0904, 0x36a8, 0xba44, 0xbb38,
+ 0x0804, 0x3673, 0x080c, 0x0d79, 0x080c, 0x4bfb, 0x2110, 0x0904,
+ 0x36a8, 0xb804, 0x908c, 0x00ff, 0x918e, 0x0006, 0x0140, 0x9084,
+ 0xff00, 0x9086, 0x0600, 0x2009, 0x0009, 0x1904, 0x36a5, 0x0126,
+ 0x2091, 0x8000, 0x2019, 0x0005, 0x00c6, 0x9066, 0x080c, 0xaaf7,
+ 0x080c, 0xa5dd, 0x080c, 0x95b9, 0x0076, 0x903e, 0x080c, 0x9476,
+ 0x900e, 0x080c, 0xe465, 0x007e, 0x00ce, 0x080c, 0xab13, 0xb807,
+ 0x0407, 0x012e, 0x0804, 0x3673, 0x614c, 0x6250, 0x7884, 0x604e,
+ 0x7b88, 0x6352, 0x2069, 0x1847, 0x831f, 0x9305, 0x6816, 0x788c,
+ 0x2069, 0x1987, 0x2d1c, 0x206a, 0x7e98, 0x9682, 0x0014, 0x1210,
+ 0x2031, 0x07d0, 0x2069, 0x1988, 0x2d04, 0x266a, 0x789a, 0x0804,
+ 0x3673, 0x0126, 0x2091, 0x8000, 0x6138, 0x7884, 0x603a, 0x910e,
+ 0xd1b4, 0x190c, 0x0edf, 0xd0c4, 0x01a8, 0x00d6, 0x78a8, 0x2009,
+ 0x199e, 0x200a, 0x78ac, 0x2011, 0x199f, 0x2012, 0x2069, 0x0100,
+ 0x6838, 0x9086, 0x0007, 0x1118, 0x2214, 0x6a5a, 0x0010, 0x210c,
+ 0x695a, 0x00de, 0x2011, 0x0116, 0x220c, 0x7888, 0xd08c, 0x0118,
+ 0x918d, 0x0040, 0x0010, 0x918c, 0xff7f, 0x2112, 0x7988, 0x613e,
+ 0x6140, 0x788c, 0x6042, 0x910e, 0xd1e4, 0x190c, 0x0efa, 0x9084,
+ 0x0020, 0x0130, 0x78b4, 0x6046, 0x9084, 0x0001, 0x090c, 0x435b,
+ 0x6040, 0xd0cc, 0x0120, 0x78b0, 0x2011, 0x0114, 0x2012, 0x012e,
+ 0x0804, 0x3673, 0x00f6, 0x2079, 0x1800, 0x7a38, 0xa898, 0x9084,
+ 0xfebf, 0x9215, 0xa89c, 0x9084, 0xfebf, 0x8002, 0x9214, 0x7838,
+ 0x9084, 0x0140, 0x9215, 0x7a3a, 0xa897, 0x4000, 0x900e, 0x9085,
+ 0x0001, 0x2001, 0x0000, 0x00fe, 0x0005, 0x7898, 0x9005, 0x01a8,
+ 0x7888, 0x9025, 0x0904, 0x36a8, 0x788c, 0x902d, 0x0904, 0x36a8,
+ 0x900e, 0x080c, 0x6783, 0x1120, 0xba44, 0xbb38, 0xbc46, 0xbd3a,
+ 0x9186, 0x07ff, 0x0190, 0x8108, 0x0ca0, 0x080c, 0x4bfb, 0x0904,
+ 0x36a8, 0x7888, 0x900d, 0x0904, 0x36a8, 0x788c, 0x9005, 0x0904,
+ 0x36a8, 0xba44, 0xb946, 0xbb38, 0xb83a, 0x0804, 0x3673, 0x2011,
+ 0xbc09, 0x0010, 0x2011, 0xbc05, 0x080c, 0x5834, 0x1904, 0x36a5,
+ 0x00c6, 0x2061, 0x0100, 0x7984, 0x9186, 0x00ff, 0x1130, 0x2001,
+ 0x1818, 0x2004, 0x9085, 0xff00, 0x0088, 0x9182, 0x007f, 0x16e0,
+ 0x9188, 0x3474, 0x210d, 0x918c, 0x00ff, 0x2001, 0x1818, 0x2004,
+ 0x0026, 0x9116, 0x002e, 0x0580, 0x810f, 0x9105, 0x0126, 0x2091,
+ 0x8000, 0x0006, 0x080c, 0xaef8, 0x000e, 0x0510, 0x602e, 0x620a,
+ 0x7984, 0x00b6, 0x080c, 0x671e, 0x2b08, 0x00be, 0x1500, 0x6112,
+ 0x6023, 0x0001, 0x080c, 0x4bc8, 0x01d0, 0x9006, 0xa866, 0x7007,
+ 0x0003, 0xa832, 0xa868, 0xc0fd, 0xa86a, 0x701f, 0x3b62, 0x2900,
+ 0x6016, 0x2009, 0x0032, 0x080c, 0xafec, 0x012e, 0x00ce, 0x0005,
+ 0x012e, 0x00ce, 0x0804, 0x36a5, 0x00ce, 0x0804, 0x36a8, 0x080c,
+ 0xaf4e, 0x0cb0, 0xa830, 0x9086, 0x0100, 0x0904, 0x36a5, 0x0804,
+ 0x3673, 0x2061, 0x1a74, 0x0126, 0x2091, 0x8000, 0x6000, 0xd084,
+ 0x0170, 0x6104, 0x6208, 0x2061, 0x1800, 0x6354, 0x6074, 0x789a,
+ 0x60c0, 0x789e, 0x60bc, 0x78aa, 0x012e, 0x0804, 0x3673, 0x900e,
+ 0x2110, 0x0c88, 0x81ff, 0x1904, 0x36a5, 0x080c, 0x769d, 0x0904,
+ 0x36a5, 0x0126, 0x2091, 0x8000, 0x6254, 0x6074, 0x9202, 0x0248,
+ 0x9085, 0x0001, 0x080c, 0x270a, 0x080c, 0x5a57, 0x012e, 0x0804,
+ 0x3673, 0x012e, 0x0804, 0x36a8, 0x0006, 0x0016, 0x00c6, 0x00e6,
+ 0x2001, 0x19ab, 0x2070, 0x2061, 0x1847, 0x6008, 0x2072, 0x900e,
+ 0x2011, 0x1400, 0x080c, 0x9364, 0x7206, 0x00ee, 0x00ce, 0x001e,
+ 0x000e, 0x0005, 0x0126, 0x2091, 0x8000, 0x81ff, 0x0128, 0x012e,
+ 0x2021, 0x400b, 0x0804, 0x3675, 0x7884, 0xd0fc, 0x0158, 0x2001,
+ 0x002a, 0x2004, 0x9005, 0x0180, 0x9082, 0x00e1, 0x0298, 0x012e,
+ 0x0804, 0x36a8, 0x2001, 0x002a, 0x2004, 0x9005, 0x0128, 0x2069,
+ 0x1847, 0x6908, 0x9102, 0x1230, 0x012e, 0x0804, 0x36a8, 0x012e,
+ 0x0804, 0x36a5, 0x080c, 0xae80, 0x0dd0, 0x7884, 0xd0fc, 0x0904,
+ 0x3c31, 0x00c6, 0x080c, 0x4bc8, 0x00ce, 0x0d88, 0xa867, 0x0000,
+ 0x7884, 0xa80a, 0x7898, 0xa80e, 0x789c, 0xa812, 0x2001, 0x002e,
+ 0x2004, 0xa81a, 0x2001, 0x002f, 0x2004, 0xa81e, 0x2001, 0x0030,
+ 0x2004, 0xa822, 0x2001, 0x0031, 0x2004, 0xa826, 0x2001, 0x0034,
+ 0x2004, 0xa82a, 0x2001, 0x0035, 0x2004, 0xa82e, 0x2001, 0x002a,
+ 0x2004, 0x9080, 0x0003, 0x9084, 0x00fc, 0x8004, 0xa816, 0x080c,
+ 0x3dbb, 0x0928, 0x7014, 0x2048, 0xad2c, 0xac28, 0xab1c, 0xaa18,
+ 0xa930, 0xa808, 0xd0b4, 0x1120, 0x2029, 0x0000, 0x2021, 0x0000,
0x8906, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080,
- 0x001b, 0x21a8, 0x27e0, 0x2098, 0x27e8, 0x20a0, 0x0006, 0x080c,
- 0x0fd6, 0x000e, 0x080c, 0x4c1a, 0x701f, 0x3d0d, 0x015e, 0x00de,
- 0x009e, 0x008e, 0x007e, 0x005e, 0x004e, 0x003e, 0x002e, 0x001e,
- 0x0005, 0x7014, 0x2048, 0xa864, 0x9086, 0x0103, 0x1118, 0x701f,
- 0x3dce, 0x0450, 0x7014, 0x2048, 0xa868, 0xc0fd, 0xa86a, 0x2009,
- 0x007f, 0x080c, 0x671e, 0x0110, 0x9006, 0x0030, 0xb813, 0x00ff,
- 0xb817, 0xfffd, 0x080c, 0xd104, 0x015e, 0x00de, 0x009e, 0x008e,
- 0x007e, 0x005e, 0x004e, 0x003e, 0x002e, 0x001e, 0x0904, 0x36ba,
+ 0x001b, 0x080c, 0x4c11, 0x701f, 0x3cf8, 0x7023, 0x0001, 0x012e,
+ 0x0005, 0x080c, 0xaaf7, 0x0046, 0x0086, 0x0096, 0x00a6, 0x00b6,
+ 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x080c, 0x3b9c, 0x2001, 0x19a1,
+ 0x2003, 0x0000, 0x2021, 0x000a, 0x2061, 0x0100, 0x6104, 0x0016,
+ 0x60bb, 0x0000, 0x60bf, 0x32e1, 0x60bf, 0x0012, 0x080c, 0x3e2a,
+ 0x080c, 0x3de9, 0x00f6, 0x00e6, 0x0086, 0x2940, 0x2071, 0x19e9,
+ 0x2079, 0x0090, 0x00d6, 0x2069, 0x0000, 0x6884, 0xd0b4, 0x0140,
+ 0x2001, 0x0035, 0x2004, 0x780e, 0x2001, 0x0034, 0x2004, 0x780a,
+ 0x00de, 0x2011, 0x0001, 0x080c, 0x419f, 0x008e, 0x00ee, 0x00fe,
+ 0x080c, 0x40c1, 0x080c, 0x3fee, 0x05b8, 0x2001, 0x020b, 0x2004,
+ 0x9084, 0x0140, 0x1db8, 0x080c, 0x4213, 0x00f6, 0x2079, 0x0300,
+ 0x78bc, 0x00fe, 0x908c, 0x0070, 0x1560, 0x2071, 0x0200, 0x7037,
+ 0x0000, 0x7050, 0x9084, 0xff00, 0x9086, 0x3200, 0x1510, 0x7037,
+ 0x0001, 0x7050, 0x9084, 0xff00, 0x9086, 0xe100, 0x11d0, 0x7037,
+ 0x0000, 0x7054, 0x7037, 0x0000, 0x715c, 0x9106, 0x1190, 0x2001,
+ 0x1820, 0x2004, 0x9106, 0x1168, 0x00c6, 0x2061, 0x0100, 0x6024,
+ 0x9084, 0x1e00, 0x00ce, 0x0138, 0x080c, 0x3ff8, 0x080c, 0x3de4,
+ 0x0058, 0x080c, 0x3de4, 0x080c, 0x4137, 0x080c, 0x40b7, 0x2001,
+ 0x020b, 0x2004, 0xd0e4, 0x0dd8, 0x2001, 0x032a, 0x2003, 0x0004,
+ 0x2061, 0x0100, 0x6027, 0x0002, 0x001e, 0x6106, 0x2011, 0x020d,
+ 0x2013, 0x0020, 0x60bb, 0x0000, 0x60bf, 0x0108, 0x60bf, 0x0012,
+ 0x2001, 0x0004, 0x200c, 0x918c, 0xfffd, 0x2102, 0x080c, 0x1346,
+ 0x2009, 0x0028, 0x080c, 0x223d, 0x2001, 0x0227, 0x200c, 0x2102,
+ 0x080c, 0xab13, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x00be, 0x00ae,
+ 0x009e, 0x008e, 0x004e, 0x2001, 0x19a1, 0x2004, 0x9005, 0x1118,
+ 0x012e, 0x0804, 0x3673, 0x012e, 0x2021, 0x400c, 0x0804, 0x3675,
0x0016, 0x0026, 0x0036, 0x0046, 0x0056, 0x0076, 0x0086, 0x0096,
- 0x00d6, 0x0156, 0x701f, 0x3da0, 0x7007, 0x0003, 0x0804, 0x3d5e,
- 0xa830, 0x9086, 0x0100, 0x2021, 0x400c, 0x0904, 0x368a, 0x0076,
- 0xad10, 0xac0c, 0xab24, 0xaa20, 0xa930, 0xa808, 0xd0b4, 0x1120,
- 0x2029, 0x0000, 0x2021, 0x0000, 0x8906, 0x8006, 0x8007, 0x90bc,
- 0x003f, 0x9084, 0xffc0, 0x9080, 0x001b, 0x21a8, 0x27e0, 0x2098,
- 0x27e8, 0x20a0, 0x0006, 0x080c, 0x0fd6, 0x000e, 0x080c, 0x4c1a,
- 0x007e, 0x701f, 0x3d0d, 0x7023, 0x0001, 0x0005, 0x0804, 0x3688,
- 0x0156, 0x00c6, 0xa814, 0x908a, 0x001e, 0x0218, 0xa833, 0x001e,
- 0x0010, 0xa832, 0x0078, 0x81ff, 0x0168, 0x0016, 0x080c, 0x4bce,
- 0x001e, 0x0130, 0xa800, 0x2040, 0xa008, 0xa80a, 0x2100, 0x0c58,
- 0x9006, 0x0010, 0x9085, 0x0001, 0x00ce, 0x015e, 0x0005, 0x0006,
- 0x00f6, 0x2079, 0x0000, 0x7880, 0x9086, 0x0044, 0x00fe, 0x000e,
- 0x0005, 0x2001, 0x19a0, 0x2003, 0x0001, 0x0005, 0x00f6, 0x00e6,
- 0x00c6, 0x2061, 0x0200, 0x2001, 0x19ab, 0x2004, 0x601a, 0x2061,
- 0x0100, 0x2001, 0x19aa, 0x2004, 0x60ce, 0x6104, 0xc1ac, 0x6106,
- 0x080c, 0x4bce, 0xa813, 0x0019, 0xa817, 0x0001, 0x2900, 0xa85a,
- 0x2001, 0x002e, 0x2004, 0xa866, 0x2001, 0x002f, 0x2004, 0xa86a,
- 0x2061, 0x0090, 0x2079, 0x0100, 0x2001, 0x19aa, 0x2004, 0x6036,
- 0x2009, 0x0040, 0x080c, 0x2241, 0x2001, 0x002a, 0x2004, 0x9084,
- 0xfff8, 0xa86e, 0x601a, 0xa873, 0x0000, 0x601f, 0x0000, 0x78ca,
- 0x9006, 0x600a, 0x600e, 0x00ce, 0x00ee, 0x00fe, 0x0005, 0x00e6,
- 0x080c, 0x4bce, 0x2940, 0xa013, 0x0019, 0xa017, 0x0001, 0x2800,
- 0xa05a, 0x2001, 0x0030, 0x2004, 0xa866, 0x2001, 0x0031, 0x2004,
- 0xa86a, 0x2001, 0x002a, 0x2004, 0x9084, 0xfff8, 0xa86e, 0xa873,
- 0x0000, 0x2001, 0x032a, 0x2003, 0x0004, 0x2001, 0x0300, 0x2003,
- 0x0000, 0x2001, 0x020d, 0x2003, 0x0000, 0x2001, 0x0004, 0x200c,
- 0x918d, 0x0002, 0x2102, 0x00ee, 0x0005, 0x0126, 0x2091, 0x8000,
- 0x81ff, 0x0148, 0x080c, 0x2a99, 0x1130, 0x9006, 0x080c, 0x29ec,
- 0x9006, 0x080c, 0x29cf, 0x7884, 0x9084, 0x0007, 0x0002, 0x3e8a,
- 0x3e8b, 0x3e8c, 0x3e87, 0x3e87, 0x3e87, 0x3e87, 0x3e87, 0x012e,
- 0x0804, 0x36bd, 0x0ce0, 0x0cd8, 0x080c, 0x76a5, 0x1128, 0x012e,
- 0x2009, 0x0016, 0x0804, 0x36ba, 0x81ff, 0x0128, 0x012e, 0x2021,
- 0x400b, 0x0804, 0x368a, 0x6000, 0x9086, 0x0003, 0x1db8, 0x2001,
- 0x0141, 0x2004, 0xd0dc, 0x0d90, 0x080c, 0xaae0, 0x0086, 0x0096,
- 0x00a6, 0x00b6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x080c, 0x3bb1,
- 0x2009, 0x0101, 0x210c, 0x0016, 0x7ec8, 0x7dcc, 0x9006, 0x2068,
- 0x2060, 0x2058, 0x080c, 0x42f8, 0x080c, 0x4248, 0x903e, 0x2720,
- 0x00f6, 0x00e6, 0x0086, 0x2940, 0x2071, 0x19e9, 0x2079, 0x0090,
- 0x00d6, 0x2069, 0x0000, 0x6884, 0xd0b4, 0x0120, 0x68d4, 0x780e,
- 0x68d0, 0x780a, 0x00de, 0x2011, 0x0001, 0x080c, 0x41a9, 0x080c,
- 0x2aa1, 0x080c, 0x2aa1, 0x080c, 0x2aa1, 0x080c, 0x2aa1, 0x080c,
- 0x41a9, 0x008e, 0x00ee, 0x00fe, 0x080c, 0x40d6, 0x2009, 0x9c40,
- 0x8109, 0x11b0, 0x080c, 0x400d, 0x2001, 0x0004, 0x200c, 0x918c,
- 0xfffd, 0x2102, 0x001e, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x00be,
- 0x00ae, 0x009e, 0x008e, 0x2009, 0x0017, 0x080c, 0x36ba, 0x0cf8,
- 0x2001, 0x020b, 0x2004, 0x9084, 0x0140, 0x1d10, 0x00f6, 0x2079,
- 0x0000, 0x7884, 0x00fe, 0xd0bc, 0x0178, 0x2001, 0x0201, 0x200c,
- 0x81ff, 0x0150, 0x080c, 0x40b4, 0x2d00, 0x9c05, 0x9b05, 0x0120,
- 0x080c, 0x400d, 0x0804, 0x3fb6, 0x080c, 0x421d, 0x080c, 0x4141,
- 0x080c, 0x4097, 0x080c, 0x40cc, 0x00f6, 0x2079, 0x0100, 0x7824,
- 0xd0ac, 0x0130, 0x8b58, 0x080c, 0x400d, 0x00fe, 0x0804, 0x3fb6,
- 0x00fe, 0x080c, 0x4003, 0x1150, 0x8d68, 0x2001, 0x0032, 0x2602,
- 0x2001, 0x0033, 0x2502, 0x080c, 0x400d, 0x0080, 0x87ff, 0x0138,
- 0x2001, 0x0201, 0x2004, 0x9005, 0x1908, 0x8739, 0x0038, 0x2001,
- 0x1a6f, 0x2004, 0x9086, 0x0000, 0x1904, 0x3f06, 0x2001, 0x032f,
- 0x2003, 0x00f6, 0x8631, 0x1208, 0x8529, 0x2500, 0x9605, 0x0904,
- 0x3fb6, 0x7884, 0xd0bc, 0x0128, 0x2d00, 0x9c05, 0x9b05, 0x1904,
- 0x3fb6, 0xa013, 0x0019, 0x2001, 0x032a, 0x2003, 0x0004, 0x7884,
- 0xd0ac, 0x1148, 0x2001, 0x1a6f, 0x2003, 0x0003, 0x2001, 0x032a,
- 0x2003, 0x0009, 0x0030, 0xa017, 0x0001, 0x78b4, 0x9005, 0x0108,
- 0xa016, 0x2800, 0xa05a, 0x2009, 0x0040, 0x080c, 0x2241, 0x2900,
- 0xa85a, 0xa813, 0x0019, 0x7884, 0xd0a4, 0x1180, 0xa817, 0x0000,
- 0x00c6, 0x20a9, 0x0004, 0x2061, 0x0090, 0x602b, 0x0008, 0x2001,
- 0x0203, 0x2004, 0x1f04, 0x3f8d, 0x00ce, 0x0030, 0xa817, 0x0001,
- 0x78b0, 0x9005, 0x0108, 0xa816, 0x00f6, 0x00c6, 0x2079, 0x0100,
- 0x2061, 0x0090, 0x7827, 0x0002, 0x2001, 0x002a, 0x2004, 0x9084,
- 0xfff8, 0x601a, 0x0006, 0x2001, 0x002b, 0x2004, 0x601e, 0x78c6,
- 0x000e, 0x78ca, 0x00ce, 0x00fe, 0x0804, 0x3ec0, 0x001e, 0x00c6,
- 0x2001, 0x032a, 0x2003, 0x0004, 0x2061, 0x0100, 0x6027, 0x0002,
- 0x6106, 0x2011, 0x020d, 0x2013, 0x0020, 0x2001, 0x0004, 0x200c,
- 0x918c, 0xfffd, 0x2102, 0x080c, 0x1352, 0x7884, 0x9084, 0x0003,
- 0x9086, 0x0002, 0x01b0, 0x2009, 0x0028, 0x080c, 0x2241, 0x2001,
- 0x0227, 0x200c, 0x2102, 0x6050, 0x9084, 0xb7ff, 0x080c, 0x2b4b,
- 0x6052, 0x602f, 0x0000, 0x604b, 0xf7f7, 0x6043, 0x0090, 0x6043,
- 0x0010, 0x080c, 0xaafc, 0x00ce, 0x2d08, 0x2c10, 0x2b18, 0x2b00,
- 0x9c05, 0x9d05, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x00be, 0x00ae,
- 0x009e, 0x008e, 0x1118, 0x012e, 0x0804, 0x3688, 0x012e, 0x2021,
- 0x400c, 0x0804, 0x368a, 0x9085, 0x0001, 0x1d04, 0x400c, 0x2091,
- 0x6000, 0x8420, 0x9486, 0x0064, 0x0005, 0x2001, 0x0105, 0x2003,
- 0x0010, 0x2001, 0x032a, 0x2003, 0x0004, 0x2001, 0x1a6f, 0x2003,
- 0x0000, 0x0071, 0x2009, 0x0048, 0x080c, 0x2241, 0x2001, 0x0227,
- 0x2024, 0x2402, 0x2001, 0x0109, 0x2003, 0x4000, 0x9026, 0x0005,
- 0x00f6, 0x00e6, 0x2071, 0x19e9, 0x7054, 0x9086, 0x0000, 0x0520,
- 0x2079, 0x0090, 0x2009, 0x0206, 0x2104, 0x2009, 0x0203, 0x210c,
- 0x9106, 0x1120, 0x2009, 0x0040, 0x080c, 0x2241, 0x782c, 0xd0fc,
- 0x0d88, 0x080c, 0x421d, 0x7054, 0x9086, 0x0000, 0x1d58, 0x782b,
- 0x0004, 0x782c, 0xd0ac, 0x1de8, 0x2009, 0x0040, 0x080c, 0x2241,
- 0x782b, 0x0002, 0x7057, 0x0000, 0x00ee, 0x00fe, 0x0005, 0x00f6,
- 0x2079, 0x0100, 0x2001, 0x1818, 0x200c, 0x7932, 0x7936, 0x080c,
- 0x26eb, 0x080c, 0x2b18, 0x080c, 0x2b4b, 0x784b, 0xf7f7, 0x7843,
- 0x0090, 0x7843, 0x0010, 0x7850, 0xc0e5, 0x7852, 0x2019, 0x61a8,
- 0x7820, 0xd09c, 0x0110, 0x8319, 0x1dd8, 0x7850, 0xc0e4, 0x7852,
- 0x2011, 0x0048, 0x080c, 0x2af5, 0x7843, 0x0040, 0x2019, 0x01f4,
- 0xa001, 0xa001, 0x8319, 0x1de0, 0x2001, 0x0100, 0x080c, 0x2abb,
- 0x2011, 0x0020, 0x080c, 0x2af5, 0x7843, 0x0000, 0x9006, 0x080c,
- 0x2abb, 0x2011, 0x0048, 0x080c, 0x2af5, 0x00fe, 0x0005, 0x7884,
- 0xd0ac, 0x11c8, 0x00f6, 0x00e6, 0x2071, 0x1a6f, 0x2079, 0x0320,
- 0x2001, 0x0201, 0x2004, 0x9005, 0x0160, 0x7000, 0x9086, 0x0000,
- 0x1140, 0x0051, 0xd0bc, 0x0108, 0x8738, 0x7003, 0x0003, 0x782b,
- 0x0019, 0x00ee, 0x00fe, 0x0005, 0x00f6, 0x2079, 0x0300, 0x78bc,
- 0x00fe, 0x908c, 0x0070, 0x0178, 0x2009, 0x0032, 0x260a, 0x2009,
- 0x0033, 0x250a, 0xd0b4, 0x0108, 0x8c60, 0xd0ac, 0x0108, 0x8d68,
- 0xd0a4, 0x0108, 0x8b58, 0x0005, 0x00f6, 0x2079, 0x0200, 0x781c,
- 0xd084, 0x0110, 0x7837, 0x0050, 0x00fe, 0x0005, 0x00e6, 0x2071,
- 0x0100, 0x2001, 0x19ab, 0x2004, 0x70e2, 0x080c, 0x3def, 0x1188,
- 0x2001, 0x1820, 0x2004, 0x2009, 0x181f, 0x210c, 0x918c, 0x00ff,
- 0x706e, 0x716a, 0x7066, 0x918d, 0x3200, 0x7162, 0x7073, 0xe109,
- 0x0080, 0x702c, 0x9085, 0x0002, 0x702e, 0x2009, 0x1818, 0x210c,
- 0x716e, 0x7063, 0x0100, 0x7166, 0x719e, 0x706b, 0x0000, 0x7073,
- 0x0809, 0x7077, 0x0008, 0x7078, 0x9080, 0x0100, 0x707a, 0x7080,
- 0x8000, 0x7082, 0x7087, 0xaaaa, 0x9006, 0x708a, 0x708e, 0x707e,
- 0x70d6, 0x70ab, 0x0036, 0x70af, 0x95d5, 0x7014, 0x9084, 0x1984,
- 0x9085, 0x0092, 0x7016, 0x080c, 0x421d, 0x00f6, 0x2071, 0x1a6f,
- 0x2079, 0x0320, 0x00d6, 0x2069, 0x0000, 0x6884, 0xd0b4, 0x0120,
- 0x689c, 0x780e, 0x6898, 0x780a, 0x00de, 0x2009, 0x03e8, 0x8109,
- 0x1df0, 0x792c, 0xd1fc, 0x0110, 0x782b, 0x0004, 0x2011, 0x0011,
- 0x080c, 0x41a9, 0x2011, 0x0001, 0x080c, 0x41a9, 0x00fe, 0x00ee,
- 0x0005, 0x00f6, 0x00e6, 0x2071, 0x1a6f, 0x2079, 0x0320, 0x792c,
- 0xd1fc, 0x0904, 0x41a6, 0x782b, 0x0002, 0x9026, 0xd19c, 0x1904,
- 0x41a2, 0x7000, 0x0002, 0x41a6, 0x4157, 0x4187, 0x41a2, 0xd1bc,
- 0x1170, 0xd1dc, 0x1190, 0x8001, 0x7002, 0x2011, 0x0001, 0x080c,
- 0x41a9, 0x0904, 0x41a6, 0x080c, 0x41a9, 0x0804, 0x41a6, 0x00f6,
- 0x2079, 0x0300, 0x78bf, 0x0000, 0x00fe, 0x7810, 0x7914, 0x782b,
- 0x0004, 0x7812, 0x7916, 0x2001, 0x0201, 0x200c, 0x81ff, 0x0de8,
- 0x080c, 0x40b4, 0x2009, 0x0001, 0x00f6, 0x2079, 0x0300, 0x78b8,
- 0x00fe, 0xd0ec, 0x0110, 0x2009, 0x0011, 0x792a, 0x00f8, 0x8001,
- 0x7002, 0x9184, 0x0880, 0x1140, 0x782c, 0xd0fc, 0x1904, 0x414b,
- 0x2011, 0x0001, 0x00b1, 0x0090, 0xa010, 0x9092, 0x0004, 0x9086,
- 0x0015, 0x1120, 0xa000, 0xa05a, 0x2011, 0x0031, 0xa212, 0xd1dc,
- 0x1960, 0x0828, 0x782b, 0x0004, 0x7003, 0x0000, 0x00ee, 0x00fe,
- 0x0005, 0xa014, 0x9005, 0x0550, 0x8001, 0x0036, 0x0096, 0xa016,
- 0xa058, 0x2048, 0xa010, 0x2009, 0x0031, 0x911a, 0x831c, 0x831c,
- 0x938a, 0x0007, 0x1a0c, 0x0d85, 0x9398, 0x41d7, 0x231d, 0x083f,
- 0x9080, 0x0004, 0x7a2a, 0x7100, 0x8108, 0x7102, 0x009e, 0x003e,
- 0x908a, 0x0035, 0x1140, 0x0096, 0xa058, 0x2048, 0xa804, 0xa05a,
- 0x2001, 0x0019, 0x009e, 0xa012, 0x9085, 0x0001, 0x0005, 0x4214,
- 0x420b, 0x4202, 0x41f9, 0x41f0, 0x41e7, 0x41de, 0xa964, 0x7902,
- 0xa968, 0x7906, 0xa96c, 0x7912, 0xa970, 0x7916, 0x0005, 0xa974,
- 0x7902, 0xa978, 0x7906, 0xa97c, 0x7912, 0xa980, 0x7916, 0x0005,
- 0xa984, 0x7902, 0xa988, 0x7906, 0xa98c, 0x7912, 0xa990, 0x7916,
- 0x0005, 0xa994, 0x7902, 0xa998, 0x7906, 0xa99c, 0x7912, 0xa9a0,
- 0x7916, 0x0005, 0xa9a4, 0x7902, 0xa9a8, 0x7906, 0xa9ac, 0x7912,
- 0xa9b0, 0x7916, 0x0005, 0xa9b4, 0x7902, 0xa9b8, 0x7906, 0xa9bc,
- 0x7912, 0xa9c0, 0x7916, 0x0005, 0xa9c4, 0x7902, 0xa9c8, 0x7906,
- 0xa9cc, 0x7912, 0xa9d0, 0x7916, 0x0005, 0x00f6, 0x00e6, 0x0086,
- 0x2071, 0x19e9, 0x2079, 0x0090, 0x792c, 0xd1fc, 0x01e8, 0x782b,
- 0x0002, 0x2940, 0x9026, 0x7054, 0x0002, 0x4244, 0x4230, 0x423b,
- 0x8001, 0x7056, 0xd19c, 0x1180, 0x2011, 0x0001, 0x080c, 0x41a9,
- 0x190c, 0x41a9, 0x0048, 0x8001, 0x7056, 0x782c, 0xd0fc, 0x1d38,
- 0x2011, 0x0001, 0x080c, 0x41a9, 0x008e, 0x00ee, 0x00fe, 0x0005,
- 0x00f6, 0x00e6, 0x00c6, 0x0086, 0x2061, 0x0200, 0x2001, 0x19ab,
- 0x2004, 0x601a, 0x2061, 0x0100, 0x2001, 0x19aa, 0x2004, 0x60ce,
- 0x6104, 0xc1ac, 0x6106, 0x2001, 0x002c, 0x2004, 0x9005, 0x0520,
- 0x2038, 0x2001, 0x002e, 0x2024, 0x2001, 0x002f, 0x201c, 0x080c,
- 0x4bce, 0xa813, 0x0019, 0xaf16, 0x2900, 0xa85a, 0x978a, 0x0007,
- 0x0220, 0x2138, 0x2009, 0x0007, 0x0010, 0x2708, 0x903e, 0x0096,
- 0xa858, 0x2048, 0xa85c, 0x9080, 0x0019, 0x009e, 0x080c, 0x42c0,
- 0x1d68, 0x2900, 0xa85a, 0x00d0, 0x080c, 0x4bce, 0xa813, 0x0019,
- 0xa817, 0x0001, 0x2900, 0xa85a, 0x2001, 0x002e, 0x2004, 0xa866,
- 0x2001, 0x002f, 0x2004, 0xa86a, 0x2001, 0x002a, 0x2004, 0x9084,
- 0xfff8, 0xa86e, 0x2001, 0x002b, 0x2004, 0xa872, 0x2061, 0x0090,
- 0x2079, 0x0100, 0x2001, 0x19aa, 0x2004, 0x6036, 0x2009, 0x0040,
- 0x080c, 0x2241, 0x2001, 0x002a, 0x2004, 0x9084, 0xfff8, 0x601a,
- 0x0006, 0x2001, 0x002b, 0x2004, 0x601e, 0x78c6, 0x000e, 0x78ca,
- 0x9006, 0x600a, 0x600e, 0x008e, 0x00ce, 0x00ee, 0x00fe, 0x0005,
- 0x00e6, 0x2071, 0x0080, 0xaa60, 0x22e8, 0x20a0, 0x20e1, 0x0000,
- 0x2099, 0x0088, 0x702b, 0x0026, 0x7402, 0x7306, 0x9006, 0x700a,
- 0x700e, 0x810b, 0x810b, 0x21a8, 0x810b, 0x7112, 0x702b, 0x0041,
- 0x702c, 0xd0fc, 0x0de8, 0x702b, 0x0002, 0x702b, 0x0040, 0x4005,
- 0x7400, 0x7304, 0x87ff, 0x0190, 0x0086, 0x0096, 0x2940, 0x0086,
- 0x080c, 0x4bce, 0x008e, 0xa058, 0x00a6, 0x2050, 0x2900, 0xb006,
- 0xa05a, 0x00ae, 0x009e, 0x008e, 0x9085, 0x0001, 0x00ee, 0x0005,
- 0x00e6, 0x2001, 0x002d, 0x2004, 0x9005, 0x0528, 0x2038, 0x2001,
- 0x0030, 0x2024, 0x2001, 0x0031, 0x201c, 0x080c, 0x4bce, 0x2940,
- 0xa813, 0x0019, 0xaf16, 0x2900, 0xa85a, 0x978a, 0x0007, 0x0220,
- 0x2138, 0x2009, 0x0007, 0x0010, 0x2708, 0x903e, 0x0096, 0xa858,
- 0x2048, 0xa85c, 0x9080, 0x0019, 0x009e, 0x080c, 0x42c0, 0x1d68,
- 0x2900, 0xa85a, 0x00d8, 0x080c, 0x4bce, 0x2940, 0xa013, 0x0019,
- 0xa017, 0x0001, 0x2800, 0xa05a, 0x2001, 0x0030, 0x2004, 0xa066,
- 0x2001, 0x0031, 0x2004, 0xa06a, 0x2001, 0x002a, 0x2004, 0x9084,
- 0xfff8, 0xa06e, 0x2001, 0x002b, 0x2004, 0xa072, 0x2001, 0x032a,
- 0x2003, 0x0004, 0x7884, 0xd0ac, 0x1180, 0x2001, 0x0101, 0x200c,
- 0x918d, 0x0200, 0x2102, 0xa017, 0x0000, 0x2001, 0x1a6f, 0x2003,
- 0x0003, 0x2001, 0x032a, 0x2003, 0x0009, 0x2001, 0x0300, 0x2003,
- 0x0000, 0x2001, 0x020d, 0x2003, 0x0000, 0x2001, 0x0004, 0x200c,
- 0x918d, 0x0002, 0x2102, 0x00ee, 0x0005, 0x0126, 0x2091, 0x8000,
- 0x20a9, 0x0007, 0x20a1, 0x1840, 0x20e9, 0x0001, 0x9006, 0x4004,
- 0x20a9, 0x0014, 0x20a1, 0xffec, 0x20e9, 0x0000, 0x9006, 0x4004,
- 0x2009, 0x013c, 0x200a, 0x012e, 0x7880, 0x9086, 0x0052, 0x0108,
- 0x0005, 0x0804, 0x3688, 0x7d98, 0x7c9c, 0x0804, 0x378c, 0x080c,
- 0x76a5, 0x190c, 0x6143, 0x6040, 0x9084, 0x0020, 0x09b1, 0x2069,
- 0x1847, 0x2d00, 0x2009, 0x0030, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98,
- 0x2039, 0x0001, 0x080c, 0x4c17, 0x701f, 0x439f, 0x0005, 0x080c,
- 0x5835, 0x1130, 0x3b00, 0x3a08, 0xc194, 0xc095, 0x20d8, 0x21d0,
- 0x2069, 0x1847, 0x6800, 0x9005, 0x0904, 0x36bd, 0x6804, 0xd0ac,
- 0x0118, 0xd0a4, 0x0904, 0x36bd, 0xd094, 0x00c6, 0x2061, 0x0100,
- 0x6104, 0x0138, 0x6200, 0x9292, 0x0005, 0x0218, 0x918c, 0xffdf,
- 0x0010, 0x918d, 0x0020, 0x6106, 0x00ce, 0xd08c, 0x00c6, 0x2061,
- 0x0100, 0x6104, 0x0118, 0x918d, 0x0010, 0x0010, 0x918c, 0xffef,
- 0x6106, 0x00ce, 0xd084, 0x0158, 0x6a28, 0x928a, 0x007f, 0x1a04,
- 0x36bd, 0x9288, 0x3489, 0x210d, 0x918c, 0x00ff, 0x6166, 0xd0dc,
- 0x0130, 0x6828, 0x908a, 0x007f, 0x1a04, 0x36bd, 0x605e, 0x6888,
- 0x9084, 0x0030, 0x8004, 0x8004, 0x8004, 0x8004, 0x0006, 0x2009,
- 0x19b3, 0x9080, 0x27de, 0x2005, 0x200a, 0x2008, 0x2001, 0x0018,
- 0x080c, 0xaad1, 0x2009, 0x0390, 0x200b, 0x0400, 0x000e, 0x2009,
- 0x19b4, 0x9080, 0x27e2, 0x2005, 0x200a, 0x6808, 0x908a, 0x0100,
- 0x0a04, 0x36bd, 0x908a, 0x0841, 0x1a04, 0x36bd, 0x9084, 0x0007,
- 0x1904, 0x36bd, 0x680c, 0x9005, 0x0904, 0x36bd, 0x6810, 0x9005,
- 0x0904, 0x36bd, 0x6848, 0x6940, 0x910a, 0x1a04, 0x36bd, 0x8001,
- 0x0904, 0x36bd, 0x684c, 0x6944, 0x910a, 0x1a04, 0x36bd, 0x8001,
- 0x0904, 0x36bd, 0x6814, 0x908c, 0x00ff, 0x614e, 0x8007, 0x9084,
- 0x00ff, 0x6052, 0x080c, 0x79d8, 0x080c, 0x6c0b, 0x080c, 0x6c6d,
- 0x6808, 0x602a, 0x080c, 0x21b3, 0x2009, 0x0170, 0x200b, 0x0080,
- 0xa001, 0xa001, 0x200b, 0x0000, 0x0036, 0x6b08, 0x080c, 0x2745,
- 0x003e, 0x6000, 0x9086, 0x0000, 0x1904, 0x452a, 0x6818, 0x691c,
- 0x6a20, 0x6b24, 0x8007, 0x810f, 0x8217, 0x831f, 0x6016, 0x611a,
- 0x621e, 0x6322, 0x6c04, 0xd4f4, 0x0148, 0x6830, 0x6934, 0x6a38,
- 0x6b3c, 0x8007, 0x810f, 0x8217, 0x831f, 0x0010, 0x9084, 0xf0ff,
- 0x6006, 0x610a, 0x620e, 0x6312, 0x8007, 0x810f, 0x8217, 0x831f,
- 0x20a9, 0x0004, 0x20a1, 0x19b5, 0x20e9, 0x0001, 0x4001, 0x20a9,
- 0x0004, 0x20a1, 0x19cf, 0x20e9, 0x0001, 0x4001, 0x080c, 0x89c7,
- 0x00c6, 0x900e, 0x20a9, 0x0001, 0x6b70, 0xd384, 0x01c8, 0x0020,
- 0x839d, 0x12b0, 0x3508, 0x8109, 0x080c, 0x7f9f, 0x6878, 0x6016,
- 0x6874, 0x2008, 0x9084, 0xff00, 0x8007, 0x600a, 0x9184, 0x00ff,
- 0x6006, 0x8108, 0x1118, 0x6003, 0x0003, 0x0010, 0x6003, 0x0001,
- 0x1f04, 0x4488, 0x00ce, 0x00c6, 0x2061, 0x199d, 0x6a88, 0x9284,
- 0xc000, 0x2010, 0x9286, 0x0000, 0x1158, 0x2063, 0x0000, 0x2001,
- 0x0001, 0x080c, 0x29ec, 0x2001, 0x0001, 0x080c, 0x29cf, 0x0088,
- 0x9286, 0x4000, 0x1148, 0x2063, 0x0001, 0x9006, 0x080c, 0x29ec,
- 0x9006, 0x080c, 0x29cf, 0x0028, 0x9286, 0x8000, 0x1d30, 0x2063,
- 0x0002, 0x00ce, 0x00e6, 0x2c70, 0x080c, 0x0ed3, 0x00ee, 0x6888,
- 0xd0ec, 0x0130, 0x2011, 0x0114, 0x2204, 0x9085, 0x0180, 0x2012,
- 0x6a80, 0x9284, 0x0030, 0x9086, 0x0030, 0x1128, 0x9294, 0xffcf,
- 0x9295, 0x0020, 0x6a82, 0x2001, 0x197d, 0x6a80, 0x9294, 0x0030,
- 0x928e, 0x0000, 0x0170, 0x928e, 0x0010, 0x0118, 0x928e, 0x0020,
- 0x0140, 0x2003, 0xaaaa, 0x080c, 0x27ba, 0x2001, 0x196e, 0x2102,
- 0x0008, 0x2102, 0x00c6, 0x2061, 0x0100, 0x602f, 0x0040, 0x602f,
- 0x0000, 0x00ce, 0x080c, 0x76a5, 0x0128, 0x080c, 0x510e, 0x0110,
- 0x080c, 0x270b, 0x60d4, 0x9005, 0x01c0, 0x6003, 0x0001, 0x2009,
- 0x4512, 0x00e0, 0x080c, 0x76a5, 0x1168, 0x2011, 0x7519, 0x080c,
- 0x8834, 0x2011, 0x750c, 0x080c, 0x8940, 0x080c, 0x79ac, 0x080c,
- 0x75d4, 0x0040, 0x080c, 0x6039, 0x0028, 0x6003, 0x0004, 0x2009,
- 0x452a, 0x0020, 0x080c, 0x6b37, 0x0804, 0x3688, 0x2001, 0x0170,
- 0x2004, 0x9084, 0x00ff, 0x9086, 0x004c, 0x1118, 0x2091, 0x31bd,
- 0x0817, 0x2091, 0x313d, 0x0817, 0x6000, 0x9086, 0x0000, 0x0904,
- 0x36ba, 0x2069, 0x1847, 0x7890, 0x6842, 0x7894, 0x6846, 0x2d00,
+ 0x00d6, 0x0156, 0x7014, 0x2048, 0x7020, 0x20a8, 0x8000, 0x7022,
+ 0xa804, 0x9005, 0x0904, 0x3d54, 0x2048, 0x1f04, 0x3d08, 0x7068,
+ 0x2040, 0xa28c, 0xa390, 0xa494, 0xa598, 0xa930, 0xa808, 0xd0b4,
+ 0x1120, 0x2029, 0x0000, 0x2021, 0x0000, 0x0096, 0x7014, 0x2048,
+ 0xa864, 0x009e, 0x9086, 0x0103, 0x0170, 0x8906, 0x8006, 0x8007,
+ 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, 0x001b, 0x080c, 0x4c11,
+ 0x701f, 0x3cf8, 0x00b0, 0x8906, 0x8006, 0x8007, 0x90bc, 0x003f,
+ 0x9084, 0xffc0, 0x9080, 0x001b, 0x21a8, 0x27e0, 0x2098, 0x27e8,
+ 0x20a0, 0x0006, 0x080c, 0x0fca, 0x000e, 0x080c, 0x4c14, 0x701f,
+ 0x3cf8, 0x015e, 0x00de, 0x009e, 0x008e, 0x007e, 0x005e, 0x004e,
+ 0x003e, 0x002e, 0x001e, 0x0005, 0x7014, 0x2048, 0xa864, 0x9086,
+ 0x0103, 0x1118, 0x701f, 0x3db9, 0x0450, 0x7014, 0x2048, 0xa868,
+ 0xc0fd, 0xa86a, 0x2009, 0x007f, 0x080c, 0x6718, 0x0110, 0x9006,
+ 0x0030, 0xb813, 0x00ff, 0xb817, 0xfffd, 0x080c, 0xd121, 0x015e,
+ 0x00de, 0x009e, 0x008e, 0x007e, 0x005e, 0x004e, 0x003e, 0x002e,
+ 0x001e, 0x0904, 0x36a5, 0x0016, 0x0026, 0x0036, 0x0046, 0x0056,
+ 0x0076, 0x0086, 0x0096, 0x00d6, 0x0156, 0x701f, 0x3d8b, 0x7007,
+ 0x0003, 0x0804, 0x3d49, 0xa830, 0x9086, 0x0100, 0x2021, 0x400c,
+ 0x0904, 0x3675, 0x0076, 0xad10, 0xac0c, 0xab24, 0xaa20, 0xa930,
+ 0xa808, 0xd0b4, 0x1120, 0x2029, 0x0000, 0x2021, 0x0000, 0x8906,
+ 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, 0x001b,
+ 0x21a8, 0x27e0, 0x2098, 0x27e8, 0x20a0, 0x0006, 0x080c, 0x0fca,
+ 0x000e, 0x080c, 0x4c14, 0x007e, 0x701f, 0x3cf8, 0x7023, 0x0001,
+ 0x0005, 0x0804, 0x3673, 0x0156, 0x00c6, 0xa814, 0x908a, 0x001e,
+ 0x0218, 0xa833, 0x001e, 0x0010, 0xa832, 0x0078, 0x81ff, 0x0168,
+ 0x0016, 0x080c, 0x4bc8, 0x001e, 0x0130, 0xa800, 0x2040, 0xa008,
+ 0xa80a, 0x2100, 0x0c58, 0x9006, 0x0010, 0x9085, 0x0001, 0x00ce,
+ 0x015e, 0x0005, 0x0006, 0x00f6, 0x2079, 0x0000, 0x7880, 0x9086,
+ 0x0044, 0x00fe, 0x000e, 0x0005, 0x2001, 0x19a1, 0x2003, 0x0001,
+ 0x0005, 0x00f6, 0x00e6, 0x00c6, 0x2061, 0x0200, 0x2001, 0x19ac,
+ 0x2004, 0x601a, 0x2061, 0x0100, 0x2001, 0x19ab, 0x2004, 0x60ce,
+ 0x6104, 0xc1ac, 0x6106, 0x080c, 0x4bc8, 0xa813, 0x0019, 0xa817,
+ 0x0001, 0x2900, 0xa85a, 0x2001, 0x002e, 0x2004, 0xa866, 0x2001,
+ 0x002f, 0x2004, 0xa86a, 0x2061, 0x0090, 0x2079, 0x0100, 0x2001,
+ 0x19ab, 0x2004, 0x6036, 0x2009, 0x0040, 0x080c, 0x223d, 0x2001,
+ 0x002a, 0x2004, 0x9084, 0xfff8, 0xa86e, 0x601a, 0xa873, 0x0000,
+ 0x601f, 0x0000, 0x78ca, 0x9006, 0x600a, 0x600e, 0x00ce, 0x00ee,
+ 0x00fe, 0x0005, 0x00e6, 0x080c, 0x4bc8, 0x2940, 0xa013, 0x0019,
+ 0xa017, 0x0001, 0x2800, 0xa05a, 0x2001, 0x0030, 0x2004, 0xa866,
+ 0x2001, 0x0031, 0x2004, 0xa86a, 0x2001, 0x002a, 0x2004, 0x9084,
+ 0xfff8, 0xa86e, 0xa873, 0x0000, 0x2001, 0x032a, 0x2003, 0x0004,
+ 0x2001, 0x0300, 0x2003, 0x0000, 0x2001, 0x020d, 0x2003, 0x0000,
+ 0x2001, 0x0004, 0x200c, 0x918d, 0x0002, 0x2102, 0x00ee, 0x0005,
+ 0x0126, 0x2091, 0x8000, 0x81ff, 0x0148, 0x080c, 0x2a80, 0x1130,
+ 0x9006, 0x080c, 0x29d7, 0x9006, 0x080c, 0x29ba, 0x2001, 0x19a0,
+ 0x2003, 0x0000, 0x7884, 0x9084, 0x0007, 0x0002, 0x3e79, 0x3e7a,
+ 0x3e7b, 0x3e76, 0x3e76, 0x3e76, 0x3e76, 0x3e76, 0x012e, 0x0804,
+ 0x36a8, 0x0ce0, 0x0cd8, 0x080c, 0x769d, 0x1128, 0x012e, 0x2009,
+ 0x0016, 0x0804, 0x36a5, 0x81ff, 0x0128, 0x012e, 0x2021, 0x400b,
+ 0x0804, 0x3675, 0x2001, 0x0141, 0x2004, 0xd0dc, 0x0db0, 0x080c,
+ 0xaaf7, 0x0086, 0x0096, 0x00a6, 0x00b6, 0x00c6, 0x00d6, 0x00e6,
+ 0x00f6, 0x080c, 0x3b9c, 0x2009, 0x0101, 0x210c, 0x0016, 0x7ec8,
+ 0x7dcc, 0x9006, 0x2068, 0x2060, 0x2058, 0x080c, 0x42ee, 0x080c,
+ 0x423e, 0x903e, 0x2720, 0x00f6, 0x00e6, 0x0086, 0x2940, 0x2071,
+ 0x19e9, 0x2079, 0x0090, 0x00d6, 0x2069, 0x0000, 0x6884, 0xd0b4,
+ 0x0120, 0x68d4, 0x780e, 0x68d0, 0x780a, 0x00de, 0x2011, 0x0001,
+ 0x080c, 0x419f, 0x080c, 0x2a88, 0x080c, 0x2a88, 0x080c, 0x2a88,
+ 0x080c, 0x2a88, 0x080c, 0x419f, 0x008e, 0x00ee, 0x00fe, 0x080c,
+ 0x40c1, 0x2009, 0x9c40, 0x8109, 0x11b0, 0x080c, 0x3ff8, 0x2001,
+ 0x0004, 0x200c, 0x918c, 0xfffd, 0x2102, 0x001e, 0x00fe, 0x00ee,
+ 0x00de, 0x00ce, 0x00be, 0x00ae, 0x009e, 0x008e, 0x2009, 0x0017,
+ 0x080c, 0x36a5, 0x0cf8, 0x2001, 0x020b, 0x2004, 0x9084, 0x0140,
+ 0x1d10, 0x00f6, 0x2079, 0x0000, 0x7884, 0x00fe, 0xd0bc, 0x0178,
+ 0x2001, 0x0201, 0x200c, 0x81ff, 0x0150, 0x080c, 0x409f, 0x2d00,
+ 0x9c05, 0x9b05, 0x0120, 0x080c, 0x3ff8, 0x0804, 0x3fa1, 0x080c,
+ 0x4213, 0x080c, 0x4137, 0x080c, 0x4082, 0x080c, 0x40b7, 0x00f6,
+ 0x2079, 0x0100, 0x7824, 0xd0ac, 0x0130, 0x8b58, 0x080c, 0x3ff8,
+ 0x00fe, 0x0804, 0x3fa1, 0x00fe, 0x080c, 0x3fee, 0x1150, 0x8d68,
+ 0x2001, 0x0032, 0x2602, 0x2001, 0x0033, 0x2502, 0x080c, 0x3ff8,
+ 0x0080, 0x87ff, 0x0138, 0x2001, 0x0201, 0x2004, 0x9005, 0x1908,
+ 0x8739, 0x0038, 0x2001, 0x1a6f, 0x2004, 0x9086, 0x0000, 0x1904,
+ 0x3ef1, 0x2001, 0x032f, 0x2003, 0x00f6, 0x8631, 0x1208, 0x8529,
+ 0x2500, 0x9605, 0x0904, 0x3fa1, 0x7884, 0xd0bc, 0x0128, 0x2d00,
+ 0x9c05, 0x9b05, 0x1904, 0x3fa1, 0xa013, 0x0019, 0x2001, 0x032a,
+ 0x2003, 0x0004, 0x7884, 0xd0ac, 0x1148, 0x2001, 0x1a6f, 0x2003,
+ 0x0003, 0x2001, 0x032a, 0x2003, 0x0009, 0x0030, 0xa017, 0x0001,
+ 0x78b4, 0x9005, 0x0108, 0xa016, 0x2800, 0xa05a, 0x2009, 0x0040,
+ 0x080c, 0x223d, 0x2900, 0xa85a, 0xa813, 0x0019, 0x7884, 0xd0a4,
+ 0x1180, 0xa817, 0x0000, 0x00c6, 0x20a9, 0x0004, 0x2061, 0x0090,
+ 0x602b, 0x0008, 0x2001, 0x0203, 0x2004, 0x1f04, 0x3f78, 0x00ce,
+ 0x0030, 0xa817, 0x0001, 0x78b0, 0x9005, 0x0108, 0xa816, 0x00f6,
+ 0x00c6, 0x2079, 0x0100, 0x2061, 0x0090, 0x7827, 0x0002, 0x2001,
+ 0x002a, 0x2004, 0x9084, 0xfff8, 0x601a, 0x0006, 0x2001, 0x002b,
+ 0x2004, 0x601e, 0x78c6, 0x000e, 0x78ca, 0x00ce, 0x00fe, 0x0804,
+ 0x3eab, 0x001e, 0x00c6, 0x2001, 0x032a, 0x2003, 0x0004, 0x2061,
+ 0x0100, 0x6027, 0x0002, 0x6106, 0x2011, 0x020d, 0x2013, 0x0020,
+ 0x2001, 0x0004, 0x200c, 0x918c, 0xfffd, 0x2102, 0x080c, 0x1346,
+ 0x7884, 0x9084, 0x0003, 0x9086, 0x0002, 0x01b0, 0x2009, 0x0028,
+ 0x080c, 0x223d, 0x2001, 0x0227, 0x200c, 0x2102, 0x6050, 0x9084,
+ 0xb7ff, 0x080c, 0x2b32, 0x6052, 0x602f, 0x0000, 0x604b, 0xf7f7,
+ 0x6043, 0x0090, 0x6043, 0x0010, 0x080c, 0xab13, 0x00ce, 0x2d08,
+ 0x2c10, 0x2b18, 0x2b00, 0x9c05, 0x9d05, 0x00fe, 0x00ee, 0x00de,
+ 0x00ce, 0x00be, 0x00ae, 0x009e, 0x008e, 0x1118, 0x012e, 0x0804,
+ 0x3673, 0x012e, 0x2021, 0x400c, 0x0804, 0x3675, 0x9085, 0x0001,
+ 0x1d04, 0x3ff7, 0x2091, 0x6000, 0x8420, 0x9486, 0x0064, 0x0005,
+ 0x2001, 0x0105, 0x2003, 0x0010, 0x2001, 0x032a, 0x2003, 0x0004,
+ 0x2001, 0x1a6f, 0x2003, 0x0000, 0x0071, 0x2009, 0x0048, 0x080c,
+ 0x223d, 0x2001, 0x0227, 0x2024, 0x2402, 0x2001, 0x0109, 0x2003,
+ 0x4000, 0x9026, 0x0005, 0x00f6, 0x00e6, 0x2071, 0x19e9, 0x7054,
+ 0x9086, 0x0000, 0x0520, 0x2079, 0x0090, 0x2009, 0x0206, 0x2104,
+ 0x2009, 0x0203, 0x210c, 0x9106, 0x1120, 0x2009, 0x0040, 0x080c,
+ 0x223d, 0x782c, 0xd0fc, 0x0d88, 0x080c, 0x4213, 0x7054, 0x9086,
+ 0x0000, 0x1d58, 0x782b, 0x0004, 0x782c, 0xd0ac, 0x1de8, 0x2009,
+ 0x0040, 0x080c, 0x223d, 0x782b, 0x0002, 0x7057, 0x0000, 0x00ee,
+ 0x00fe, 0x0005, 0x00f6, 0x2079, 0x0100, 0x2001, 0x1818, 0x200c,
+ 0x7932, 0x7936, 0x080c, 0x26ea, 0x080c, 0x2aff, 0x080c, 0x2b32,
+ 0x784b, 0xf7f7, 0x7843, 0x0090, 0x7843, 0x0010, 0x7850, 0xc0e5,
+ 0x7852, 0x2019, 0x61a8, 0x7820, 0xd09c, 0x0110, 0x8319, 0x1dd8,
+ 0x7850, 0xc0e4, 0x7852, 0x2011, 0x0048, 0x080c, 0x2adc, 0x7843,
+ 0x0040, 0x2019, 0x01f4, 0xa001, 0xa001, 0x8319, 0x1de0, 0x2001,
+ 0x0100, 0x080c, 0x2aa2, 0x2011, 0x0020, 0x080c, 0x2adc, 0x7843,
+ 0x0000, 0x9006, 0x080c, 0x2aa2, 0x2011, 0x0048, 0x080c, 0x2adc,
+ 0x00fe, 0x0005, 0x7884, 0xd0ac, 0x11c8, 0x00f6, 0x00e6, 0x2071,
+ 0x1a6f, 0x2079, 0x0320, 0x2001, 0x0201, 0x2004, 0x9005, 0x0160,
+ 0x7000, 0x9086, 0x0000, 0x1140, 0x0051, 0xd0bc, 0x0108, 0x8738,
+ 0x7003, 0x0003, 0x782b, 0x0019, 0x00ee, 0x00fe, 0x0005, 0x00f6,
+ 0x2079, 0x0300, 0x78bc, 0x00fe, 0x908c, 0x0070, 0x0178, 0x2009,
+ 0x0032, 0x260a, 0x2009, 0x0033, 0x250a, 0xd0b4, 0x0108, 0x8c60,
+ 0xd0ac, 0x0108, 0x8d68, 0xd0a4, 0x0108, 0x8b58, 0x0005, 0x00f6,
+ 0x2079, 0x0200, 0x781c, 0xd084, 0x0110, 0x7837, 0x0050, 0x00fe,
+ 0x0005, 0x00e6, 0x2071, 0x0100, 0x2001, 0x19ac, 0x2004, 0x70e2,
+ 0x080c, 0x3dda, 0x1188, 0x2001, 0x1820, 0x2004, 0x2009, 0x181f,
+ 0x210c, 0x918c, 0x00ff, 0x706e, 0x716a, 0x7066, 0x918d, 0x3200,
+ 0x7162, 0x7073, 0xe109, 0x0080, 0x702c, 0x9085, 0x0002, 0x702e,
+ 0x2009, 0x1818, 0x210c, 0x716e, 0x7063, 0x0100, 0x7166, 0x719e,
+ 0x706b, 0x0000, 0x7073, 0x0809, 0x7077, 0x0008, 0x7078, 0x9080,
+ 0x0100, 0x707a, 0x7080, 0x8000, 0x7082, 0x7087, 0xaaaa, 0x9006,
+ 0x708a, 0x708e, 0x707e, 0x70d6, 0x70ab, 0x0036, 0x70af, 0x95d5,
+ 0x7014, 0x9084, 0x1984, 0x9085, 0x0092, 0x7016, 0x080c, 0x4213,
+ 0x00f6, 0x2071, 0x1a6f, 0x2079, 0x0320, 0x00d6, 0x2069, 0x0000,
+ 0x6884, 0xd0b4, 0x0120, 0x689c, 0x780e, 0x6898, 0x780a, 0x00de,
+ 0x080c, 0x3dda, 0x0140, 0x2001, 0x19a0, 0x200c, 0x2003, 0x0001,
+ 0x918e, 0x0001, 0x0120, 0x2009, 0x03e8, 0x8109, 0x1df0, 0x792c,
+ 0xd1fc, 0x0110, 0x782b, 0x0004, 0x2011, 0x0011, 0x080c, 0x419f,
+ 0x2011, 0x0001, 0x080c, 0x419f, 0x00fe, 0x00ee, 0x0005, 0x00f6,
+ 0x00e6, 0x2071, 0x1a6f, 0x2079, 0x0320, 0x792c, 0xd1fc, 0x0904,
+ 0x419c, 0x782b, 0x0002, 0x9026, 0xd19c, 0x1904, 0x4198, 0x7000,
+ 0x0002, 0x419c, 0x414d, 0x417d, 0x4198, 0xd1bc, 0x1170, 0xd1dc,
+ 0x1190, 0x8001, 0x7002, 0x2011, 0x0001, 0x080c, 0x419f, 0x0904,
+ 0x419c, 0x080c, 0x419f, 0x0804, 0x419c, 0x00f6, 0x2079, 0x0300,
+ 0x78bf, 0x0000, 0x00fe, 0x7810, 0x7914, 0x782b, 0x0004, 0x7812,
+ 0x7916, 0x2001, 0x0201, 0x200c, 0x81ff, 0x0de8, 0x080c, 0x409f,
+ 0x2009, 0x0001, 0x00f6, 0x2079, 0x0300, 0x78b8, 0x00fe, 0xd0ec,
+ 0x0110, 0x2009, 0x0011, 0x792a, 0x00f8, 0x8001, 0x7002, 0x9184,
+ 0x0880, 0x1140, 0x782c, 0xd0fc, 0x1904, 0x4141, 0x2011, 0x0001,
+ 0x00b1, 0x0090, 0xa010, 0x9092, 0x0004, 0x9086, 0x0015, 0x1120,
+ 0xa000, 0xa05a, 0x2011, 0x0031, 0xa212, 0xd1dc, 0x1960, 0x0828,
+ 0x782b, 0x0004, 0x7003, 0x0000, 0x00ee, 0x00fe, 0x0005, 0xa014,
+ 0x9005, 0x0550, 0x8001, 0x0036, 0x0096, 0xa016, 0xa058, 0x2048,
+ 0xa010, 0x2009, 0x0031, 0x911a, 0x831c, 0x831c, 0x938a, 0x0007,
+ 0x1a0c, 0x0d79, 0x9398, 0x41cd, 0x231d, 0x083f, 0x9080, 0x0004,
+ 0x7a2a, 0x7100, 0x8108, 0x7102, 0x009e, 0x003e, 0x908a, 0x0035,
+ 0x1140, 0x0096, 0xa058, 0x2048, 0xa804, 0xa05a, 0x2001, 0x0019,
+ 0x009e, 0xa012, 0x9085, 0x0001, 0x0005, 0x420a, 0x4201, 0x41f8,
+ 0x41ef, 0x41e6, 0x41dd, 0x41d4, 0xa964, 0x7902, 0xa968, 0x7906,
+ 0xa96c, 0x7912, 0xa970, 0x7916, 0x0005, 0xa974, 0x7902, 0xa978,
+ 0x7906, 0xa97c, 0x7912, 0xa980, 0x7916, 0x0005, 0xa984, 0x7902,
+ 0xa988, 0x7906, 0xa98c, 0x7912, 0xa990, 0x7916, 0x0005, 0xa994,
+ 0x7902, 0xa998, 0x7906, 0xa99c, 0x7912, 0xa9a0, 0x7916, 0x0005,
+ 0xa9a4, 0x7902, 0xa9a8, 0x7906, 0xa9ac, 0x7912, 0xa9b0, 0x7916,
+ 0x0005, 0xa9b4, 0x7902, 0xa9b8, 0x7906, 0xa9bc, 0x7912, 0xa9c0,
+ 0x7916, 0x0005, 0xa9c4, 0x7902, 0xa9c8, 0x7906, 0xa9cc, 0x7912,
+ 0xa9d0, 0x7916, 0x0005, 0x00f6, 0x00e6, 0x0086, 0x2071, 0x19e9,
+ 0x2079, 0x0090, 0x792c, 0xd1fc, 0x01e8, 0x782b, 0x0002, 0x2940,
+ 0x9026, 0x7054, 0x0002, 0x423a, 0x4226, 0x4231, 0x8001, 0x7056,
+ 0xd19c, 0x1180, 0x2011, 0x0001, 0x080c, 0x419f, 0x190c, 0x419f,
+ 0x0048, 0x8001, 0x7056, 0x782c, 0xd0fc, 0x1d38, 0x2011, 0x0001,
+ 0x080c, 0x419f, 0x008e, 0x00ee, 0x00fe, 0x0005, 0x00f6, 0x00e6,
+ 0x00c6, 0x0086, 0x2061, 0x0200, 0x2001, 0x19ac, 0x2004, 0x601a,
+ 0x2061, 0x0100, 0x2001, 0x19ab, 0x2004, 0x60ce, 0x6104, 0xc1ac,
+ 0x6106, 0x2001, 0x002c, 0x2004, 0x9005, 0x0520, 0x2038, 0x2001,
+ 0x002e, 0x2024, 0x2001, 0x002f, 0x201c, 0x080c, 0x4bc8, 0xa813,
+ 0x0019, 0xaf16, 0x2900, 0xa85a, 0x978a, 0x0007, 0x0220, 0x2138,
+ 0x2009, 0x0007, 0x0010, 0x2708, 0x903e, 0x0096, 0xa858, 0x2048,
+ 0xa85c, 0x9080, 0x0019, 0x009e, 0x080c, 0x42b6, 0x1d68, 0x2900,
+ 0xa85a, 0x00d0, 0x080c, 0x4bc8, 0xa813, 0x0019, 0xa817, 0x0001,
+ 0x2900, 0xa85a, 0x2001, 0x002e, 0x2004, 0xa866, 0x2001, 0x002f,
+ 0x2004, 0xa86a, 0x2001, 0x002a, 0x2004, 0x9084, 0xfff8, 0xa86e,
+ 0x2001, 0x002b, 0x2004, 0xa872, 0x2061, 0x0090, 0x2079, 0x0100,
+ 0x2001, 0x19ab, 0x2004, 0x6036, 0x2009, 0x0040, 0x080c, 0x223d,
+ 0x2001, 0x002a, 0x2004, 0x9084, 0xfff8, 0x601a, 0x0006, 0x2001,
+ 0x002b, 0x2004, 0x601e, 0x78c6, 0x000e, 0x78ca, 0x9006, 0x600a,
+ 0x600e, 0x008e, 0x00ce, 0x00ee, 0x00fe, 0x0005, 0x00e6, 0x2071,
+ 0x0080, 0xaa60, 0x22e8, 0x20a0, 0x20e1, 0x0000, 0x2099, 0x0088,
+ 0x702b, 0x0026, 0x7402, 0x7306, 0x9006, 0x700a, 0x700e, 0x810b,
+ 0x810b, 0x21a8, 0x810b, 0x7112, 0x702b, 0x0041, 0x702c, 0xd0fc,
+ 0x0de8, 0x702b, 0x0002, 0x702b, 0x0040, 0x4005, 0x7400, 0x7304,
+ 0x87ff, 0x0190, 0x0086, 0x0096, 0x2940, 0x0086, 0x080c, 0x4bc8,
+ 0x008e, 0xa058, 0x00a6, 0x2050, 0x2900, 0xb006, 0xa05a, 0x00ae,
+ 0x009e, 0x008e, 0x9085, 0x0001, 0x00ee, 0x0005, 0x00e6, 0x2001,
+ 0x002d, 0x2004, 0x9005, 0x0528, 0x2038, 0x2001, 0x0030, 0x2024,
+ 0x2001, 0x0031, 0x201c, 0x080c, 0x4bc8, 0x2940, 0xa813, 0x0019,
+ 0xaf16, 0x2900, 0xa85a, 0x978a, 0x0007, 0x0220, 0x2138, 0x2009,
+ 0x0007, 0x0010, 0x2708, 0x903e, 0x0096, 0xa858, 0x2048, 0xa85c,
+ 0x9080, 0x0019, 0x009e, 0x080c, 0x42b6, 0x1d68, 0x2900, 0xa85a,
+ 0x00d8, 0x080c, 0x4bc8, 0x2940, 0xa013, 0x0019, 0xa017, 0x0001,
+ 0x2800, 0xa05a, 0x2001, 0x0030, 0x2004, 0xa066, 0x2001, 0x0031,
+ 0x2004, 0xa06a, 0x2001, 0x002a, 0x2004, 0x9084, 0xfff8, 0xa06e,
+ 0x2001, 0x002b, 0x2004, 0xa072, 0x2001, 0x032a, 0x2003, 0x0004,
+ 0x7884, 0xd0ac, 0x1180, 0x2001, 0x0101, 0x200c, 0x918d, 0x0200,
+ 0x2102, 0xa017, 0x0000, 0x2001, 0x1a6f, 0x2003, 0x0003, 0x2001,
+ 0x032a, 0x2003, 0x0009, 0x2001, 0x0300, 0x2003, 0x0000, 0x2001,
+ 0x020d, 0x2003, 0x0000, 0x2001, 0x0004, 0x200c, 0x918d, 0x0002,
+ 0x2102, 0x00ee, 0x0005, 0x0126, 0x2091, 0x8000, 0x20a9, 0x0007,
+ 0x20a1, 0x1840, 0x20e9, 0x0001, 0x9006, 0x4004, 0x20a9, 0x0014,
+ 0x20a1, 0xffec, 0x20e9, 0x0000, 0x9006, 0x4004, 0x2009, 0x013c,
+ 0x200a, 0x012e, 0x7880, 0x9086, 0x0052, 0x0108, 0x0005, 0x0804,
+ 0x3673, 0x7d98, 0x7c9c, 0x0804, 0x3777, 0x080c, 0x769d, 0x190c,
+ 0x613d, 0x6040, 0x9084, 0x0020, 0x09b1, 0x2069, 0x1847, 0x2d00,
0x2009, 0x0030, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0x2039, 0x0001,
- 0x0804, 0x4c1a, 0x9006, 0x080c, 0x270b, 0x81ff, 0x1904, 0x36ba,
- 0x080c, 0x76a5, 0x11b0, 0x080c, 0x79a7, 0x080c, 0x617e, 0x080c,
- 0x347d, 0x0118, 0x6130, 0xc18d, 0x6132, 0x080c, 0xd33e, 0x0130,
- 0x080c, 0x76c8, 0x1118, 0x080c, 0x7679, 0x0038, 0x080c, 0x75d4,
- 0x0020, 0x080c, 0x6143, 0x080c, 0x6039, 0x0804, 0x3688, 0x81ff,
- 0x1904, 0x36ba, 0x080c, 0x76a5, 0x1110, 0x0804, 0x36ba, 0x0126,
- 0x2091, 0x8000, 0x6194, 0x81ff, 0x0190, 0x704f, 0x0000, 0x2001,
- 0x1d80, 0x2009, 0x0040, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0x2039,
- 0x0001, 0x080c, 0x4c1a, 0x701f, 0x3686, 0x012e, 0x0005, 0x704f,
- 0x0001, 0x00d6, 0x2069, 0x1d80, 0x20a9, 0x0040, 0x20e9, 0x0001,
- 0x20a1, 0x1d80, 0x2019, 0xffff, 0x4304, 0x655c, 0x9588, 0x3489,
- 0x210d, 0x918c, 0x00ff, 0x216a, 0x900e, 0x2011, 0x0002, 0x2100,
- 0x9506, 0x01a8, 0x080c, 0x6789, 0x1190, 0xb814, 0x821c, 0x0238,
- 0x9398, 0x1d80, 0x9085, 0xff00, 0x8007, 0x201a, 0x0038, 0x9398,
- 0x1d80, 0x2324, 0x94a4, 0xff00, 0x9405, 0x201a, 0x8210, 0x8108,
- 0x9182, 0x0080, 0x1208, 0x0c18, 0x8201, 0x8007, 0x2d0c, 0x9105,
- 0x206a, 0x00de, 0x20a9, 0x0040, 0x20a1, 0x1d80, 0x2099, 0x1d80,
- 0x080c, 0x60ce, 0x0804, 0x4587, 0x080c, 0x4c01, 0x0904, 0x36bd,
- 0x080c, 0x4bce, 0x1120, 0x2009, 0x0002, 0x0804, 0x36ba, 0x080c,
- 0x5826, 0xd0b4, 0x0558, 0x7884, 0x908e, 0x007e, 0x0538, 0x908e,
- 0x007f, 0x0520, 0x908e, 0x0080, 0x0508, 0x080c, 0x3478, 0x1148,
- 0xb800, 0xd08c, 0x11d8, 0xb804, 0x9084, 0x00ff, 0x9086, 0x0006,
- 0x11a8, 0xa867, 0x0000, 0xa868, 0xc0fd, 0xa86a, 0x080c, 0xcde7,
- 0x1120, 0x2009, 0x0003, 0x0804, 0x36ba, 0x7007, 0x0003, 0x701f,
- 0x4612, 0x0005, 0x080c, 0x4c01, 0x0904, 0x36bd, 0x20a9, 0x002b,
- 0xb8c4, 0x20e0, 0xb8c8, 0x2098, 0xa860, 0x20e8, 0xa85c, 0x9080,
- 0x0002, 0x20a0, 0x4003, 0x20a9, 0x0008, 0x9080, 0x0006, 0x20a0,
- 0xb8c4, 0x20e0, 0xb8c8, 0x9080, 0x0006, 0x2098, 0x080c, 0x0fd6,
- 0x0070, 0x20a9, 0x0004, 0xa85c, 0x9080, 0x000a, 0x20a0, 0xb8c4,
- 0x20e0, 0xb8c8, 0x9080, 0x000a, 0x2098, 0x080c, 0x0fd6, 0x8906,
- 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, 0x0002,
- 0x2009, 0x002b, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0x0804, 0x4c1a,
- 0x81ff, 0x1904, 0x36ba, 0x080c, 0x4be5, 0x0904, 0x36bd, 0x080c,
- 0x69ce, 0x0904, 0x36ba, 0x0058, 0xa878, 0x9005, 0x0120, 0x2009,
- 0x0004, 0x0804, 0x36ba, 0xa974, 0xaa94, 0x0804, 0x3688, 0x080c,
- 0x582e, 0x0904, 0x3688, 0x701f, 0x465c, 0x7007, 0x0003, 0x0005,
- 0x81ff, 0x1904, 0x36ba, 0x7888, 0x908a, 0x1000, 0x1a04, 0x36bd,
- 0x080c, 0x4c01, 0x0904, 0x36bd, 0x080c, 0x6bd5, 0x0120, 0x080c,
- 0x6bdd, 0x1904, 0x36bd, 0x080c, 0x6a53, 0x0904, 0x36ba, 0x2019,
- 0x0004, 0x900e, 0x080c, 0x69e0, 0x0904, 0x36ba, 0x7984, 0x7a88,
- 0x04c9, 0x08a8, 0xa89c, 0x908a, 0x1000, 0x12f8, 0x080c, 0x4bff,
- 0x01e0, 0x080c, 0x6bd5, 0x0118, 0x080c, 0x6bdd, 0x11b0, 0x080c,
- 0x6a53, 0x2009, 0x0002, 0x0168, 0x2009, 0x0002, 0x2019, 0x0004,
- 0x080c, 0x69e0, 0x2009, 0x0003, 0x0120, 0xa998, 0xaa9c, 0x00d1,
- 0x0060, 0xa897, 0x4005, 0xa99a, 0x0010, 0xa897, 0x4006, 0x900e,
- 0x9085, 0x0001, 0x2001, 0x0030, 0x0005, 0xa897, 0x4000, 0x080c,
- 0x582e, 0x0110, 0x9006, 0x0018, 0x900e, 0x9085, 0x0001, 0x2001,
- 0x0000, 0x0005, 0x9186, 0x00ff, 0x0110, 0x0071, 0x0060, 0x2029,
- 0x007e, 0x2061, 0x1800, 0x645c, 0x2400, 0x9506, 0x0110, 0x2508,
- 0x0019, 0x8529, 0x1ec8, 0x0005, 0x080c, 0x6789, 0x1138, 0x2200,
- 0x8003, 0x800b, 0x810b, 0x9108, 0x080c, 0x8842, 0x0005, 0x81ff,
- 0x1904, 0x36ba, 0x798c, 0x2001, 0x1981, 0x918c, 0x8000, 0x2102,
- 0x080c, 0x4be5, 0x0904, 0x36bd, 0x080c, 0x6bd5, 0x0120, 0x080c,
- 0x6bdd, 0x1904, 0x36bd, 0x080c, 0x6850, 0x0904, 0x36ba, 0x080c,
- 0x69d7, 0x0904, 0x36ba, 0x2001, 0x1981, 0x2004, 0xd0fc, 0x1904,
- 0x3688, 0x0804, 0x4667, 0xa9a0, 0x2001, 0x1981, 0x918c, 0x8000,
- 0xc18d, 0x2102, 0x080c, 0x4bf2, 0x01a0, 0x080c, 0x6bd5, 0x0118,
- 0x080c, 0x6bdd, 0x1170, 0x080c, 0x6850, 0x2009, 0x0002, 0x0128,
- 0x080c, 0x69d7, 0x1170, 0x2009, 0x0003, 0xa897, 0x4005, 0xa99a,
- 0x0010, 0xa897, 0x4006, 0x900e, 0x9085, 0x0001, 0x2001, 0x0030,
- 0x0005, 0xa897, 0x4000, 0x2001, 0x1981, 0x2004, 0xd0fc, 0x1128,
- 0x080c, 0x582e, 0x0110, 0x9006, 0x0018, 0x900e, 0x9085, 0x0001,
- 0x2001, 0x0000, 0x0005, 0x81ff, 0x1904, 0x36ba, 0x798c, 0x2001,
- 0x1980, 0x918c, 0x8000, 0x2102, 0x080c, 0x4be5, 0x0904, 0x36bd,
- 0x080c, 0x6bd5, 0x0120, 0x080c, 0x6bdd, 0x1904, 0x36bd, 0x080c,
- 0x6850, 0x0904, 0x36ba, 0x080c, 0x69c5, 0x0904, 0x36ba, 0x2001,
- 0x1980, 0x2004, 0xd0fc, 0x1904, 0x3688, 0x0804, 0x4667, 0xa9a0,
- 0x2001, 0x1980, 0x918c, 0x8000, 0xc18d, 0x2102, 0x080c, 0x4bf2,
- 0x01a0, 0x080c, 0x6bd5, 0x0118, 0x080c, 0x6bdd, 0x1170, 0x080c,
- 0x6850, 0x2009, 0x0002, 0x0128, 0x080c, 0x69c5, 0x1170, 0x2009,
- 0x0003, 0xa897, 0x4005, 0xa99a, 0x0010, 0xa897, 0x4006, 0x900e,
- 0x9085, 0x0001, 0x2001, 0x0030, 0x0005, 0xa897, 0x4000, 0x2001,
- 0x1980, 0x2004, 0xd0fc, 0x1128, 0x080c, 0x582e, 0x0110, 0x9006,
- 0x0018, 0x900e, 0x9085, 0x0001, 0x2001, 0x0000, 0x0005, 0x6100,
- 0x0804, 0x3688, 0x080c, 0x4c01, 0x0904, 0x36bd, 0x080c, 0x583a,
- 0x1904, 0x36ba, 0x79a8, 0xd184, 0x1158, 0xb834, 0x8007, 0x789e,
- 0xb830, 0x8007, 0x789a, 0xbb2c, 0x831f, 0xba28, 0x8217, 0x0050,
- 0xb824, 0x8007, 0x789e, 0xb820, 0x8007, 0x789a, 0xbb1c, 0x831f,
- 0xba18, 0x8217, 0xb900, 0x918c, 0x0202, 0x0804, 0x3688, 0x78a8,
- 0x909c, 0x0003, 0xd0ac, 0x1150, 0xd0b4, 0x1140, 0x939a, 0x0003,
- 0x1a04, 0x36ba, 0x625c, 0x7884, 0x9206, 0x1548, 0x080c, 0x89b1,
- 0x2001, 0xffec, 0x2009, 0x000c, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98,
- 0x2039, 0x0000, 0x0006, 0x78a8, 0x9084, 0x0080, 0x1118, 0x000e,
- 0x0804, 0x4c1a, 0x000e, 0x2031, 0x0000, 0x2061, 0x18b8, 0x2c44,
- 0xa66a, 0xa17a, 0xa772, 0xa076, 0xa28e, 0xa392, 0xa496, 0xa59a,
- 0x080c, 0x114e, 0x7007, 0x0002, 0x701f, 0x481f, 0x0005, 0x81ff,
- 0x1904, 0x36ba, 0x080c, 0x4c01, 0x0904, 0x36bd, 0x080c, 0x6bd5,
- 0x1904, 0x36ba, 0x00c6, 0x080c, 0x4bce, 0x00ce, 0x0904, 0x36ba,
- 0xa867, 0x0000, 0xa868, 0xc0fd, 0xa86a, 0x7ea8, 0x080c, 0xcd8d,
- 0x0904, 0x36ba, 0x7007, 0x0003, 0x701f, 0x4823, 0x0005, 0x080c,
- 0x4365, 0x0804, 0x3688, 0xa830, 0x9086, 0x0100, 0x0904, 0x36ba,
- 0x8906, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080,
- 0x001b, 0x2009, 0x000c, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0x0804,
- 0x4c1a, 0x9006, 0x080c, 0x270b, 0x78a8, 0x9084, 0x00ff, 0x9086,
- 0x00ff, 0x0118, 0x81ff, 0x1904, 0x36ba, 0x080c, 0x76a5, 0x0110,
- 0x080c, 0x6143, 0x7888, 0x908a, 0x1000, 0x1a04, 0x36bd, 0x7984,
- 0x9186, 0x00ff, 0x0138, 0x9182, 0x007f, 0x1a04, 0x36bd, 0x2100,
- 0x080c, 0x26d5, 0x0026, 0x00c6, 0x0126, 0x2091, 0x8000, 0x2061,
- 0x1a05, 0x601b, 0x0000, 0x601f, 0x0000, 0x607b, 0x0000, 0x607f,
- 0x0000, 0x080c, 0x76a5, 0x1158, 0x080c, 0x79a7, 0x080c, 0x617e,
- 0x9085, 0x0001, 0x080c, 0x76e9, 0x080c, 0x75d4, 0x00f0, 0x080c,
- 0xaae0, 0x080c, 0xae67, 0x080c, 0xaafc, 0x2061, 0x0100, 0x2001,
- 0x1818, 0x2004, 0x9084, 0x00ff, 0x810f, 0x9105, 0x604a, 0x6043,
- 0x0090, 0x6043, 0x0010, 0x2009, 0x199a, 0x200b, 0x0000, 0x2009,
- 0x002d, 0x2011, 0x6069, 0x080c, 0x88fe, 0x7984, 0x080c, 0x76a5,
- 0x1110, 0x2009, 0x00ff, 0x7a88, 0x080c, 0x46ca, 0x012e, 0x00ce,
- 0x002e, 0x0804, 0x3688, 0x7984, 0x080c, 0x671e, 0x2b08, 0x1904,
- 0x36bd, 0x0804, 0x3688, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804,
- 0x36ba, 0x60dc, 0xd0ac, 0x1130, 0xd09c, 0x1120, 0x2009, 0x0005,
- 0x0804, 0x36ba, 0x080c, 0x4bce, 0x1120, 0x2009, 0x0002, 0x0804,
- 0x36ba, 0x7984, 0x81ff, 0x0904, 0x36bd, 0x9192, 0x0021, 0x1a04,
- 0x36bd, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0xa85c, 0x9080, 0x0019,
- 0x702a, 0xaf60, 0x7736, 0x080c, 0x4c17, 0x701f, 0x48de, 0x7880,
- 0x9086, 0x006e, 0x0110, 0x701f, 0x52c0, 0x0005, 0x2009, 0x0080,
- 0x080c, 0x6789, 0x1118, 0x080c, 0x6bd5, 0x0120, 0x2021, 0x400a,
- 0x0804, 0x368a, 0x00d6, 0x0096, 0xa964, 0xaa6c, 0xab70, 0xac74,
- 0xad78, 0xae7c, 0xa884, 0x90be, 0x0100, 0x0904, 0x4977, 0x90be,
- 0x0112, 0x0904, 0x4977, 0x90be, 0x0113, 0x0904, 0x4977, 0x90be,
- 0x0114, 0x0904, 0x4977, 0x90be, 0x0117, 0x0904, 0x4977, 0x90be,
- 0x011a, 0x0904, 0x4977, 0x90be, 0x011c, 0x0904, 0x4977, 0x90be,
- 0x0121, 0x0904, 0x495e, 0x90be, 0x0131, 0x0904, 0x495e, 0x90be,
- 0x0171, 0x0904, 0x4977, 0x90be, 0x0173, 0x0904, 0x4977, 0x90be,
- 0x01a1, 0x1128, 0xa894, 0x8007, 0xa896, 0x0804, 0x4982, 0x90be,
- 0x0212, 0x0904, 0x496b, 0x90be, 0x0213, 0x05e8, 0x90be, 0x0214,
- 0x0500, 0x90be, 0x0217, 0x0188, 0x90be, 0x021a, 0x1120, 0xa89c,
- 0x8007, 0xa89e, 0x04e0, 0x90be, 0x021f, 0x05c8, 0x90be, 0x0300,
- 0x05b0, 0x009e, 0x00de, 0x0804, 0x36bd, 0x7028, 0x9080, 0x0010,
- 0x2098, 0x20a0, 0x7034, 0x20e0, 0x20e8, 0x20a9, 0x0007, 0x080c,
- 0x49c0, 0x7028, 0x9080, 0x000e, 0x2098, 0x20a0, 0x7034, 0x20e0,
- 0x20e8, 0x20a9, 0x0001, 0x080c, 0x49c0, 0x00c8, 0x7028, 0x9080,
- 0x000c, 0x2098, 0x20a0, 0x7034, 0x20e0, 0x20e8, 0x20a9, 0x0001,
- 0x080c, 0x49cd, 0x00b8, 0x7028, 0x9080, 0x000e, 0x2098, 0x20a0,
- 0x7034, 0x20e0, 0x20e8, 0x20a9, 0x0001, 0x080c, 0x49cd, 0x7028,
- 0x9080, 0x000c, 0x2098, 0x20a0, 0x7034, 0x20e0, 0x20e8, 0x20a9,
- 0x0001, 0x04f1, 0x00c6, 0x080c, 0x4bce, 0x0550, 0xa868, 0xc0fd,
- 0xa86a, 0xa867, 0x0119, 0x9006, 0xa882, 0xa87f, 0x0020, 0xa88b,
- 0x0001, 0x810b, 0xa9ae, 0xa8b2, 0xaab6, 0xabba, 0xacbe, 0xadc2,
- 0xa9c6, 0xa8ca, 0x00ce, 0x009e, 0x00de, 0xa866, 0xa822, 0xa868,
- 0xc0fd, 0xa86a, 0xa804, 0x2048, 0x080c, 0xcda8, 0x1120, 0x2009,
- 0x0003, 0x0804, 0x36ba, 0x7007, 0x0003, 0x701f, 0x49b7, 0x0005,
- 0x00ce, 0x009e, 0x00de, 0x2009, 0x0002, 0x0804, 0x36ba, 0xa820,
- 0x9086, 0x8001, 0x1904, 0x3688, 0x2009, 0x0004, 0x0804, 0x36ba,
- 0x0016, 0x0026, 0x3510, 0x20a9, 0x0002, 0x4002, 0x4104, 0x4004,
- 0x8211, 0x1dc8, 0x002e, 0x001e, 0x0005, 0x0016, 0x0026, 0x0036,
- 0x0046, 0x3520, 0x20a9, 0x0004, 0x4002, 0x4304, 0x4204, 0x4104,
- 0x4004, 0x8421, 0x1db8, 0x004e, 0x003e, 0x002e, 0x001e, 0x0005,
- 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x36ba, 0x60dc, 0xd0ac,
- 0x1130, 0xd09c, 0x1120, 0x2009, 0x0005, 0x0804, 0x36ba, 0x7984,
- 0x78a8, 0x2040, 0x080c, 0xae60, 0x1120, 0x9182, 0x007f, 0x0a04,
- 0x36bd, 0x9186, 0x00ff, 0x0904, 0x36bd, 0x9182, 0x0800, 0x1a04,
- 0x36bd, 0x7a8c, 0x7b88, 0x607c, 0x9306, 0x1158, 0x6080, 0x924e,
- 0x0904, 0x36bd, 0x080c, 0xae60, 0x1120, 0x99cc, 0xff00, 0x0904,
- 0x36bd, 0x0126, 0x2091, 0x8000, 0x080c, 0x4ae1, 0x0904, 0x4a61,
- 0x0086, 0x90c6, 0x4000, 0x008e, 0x1538, 0x00c6, 0x0006, 0x0036,
- 0xb818, 0xbb1c, 0x9305, 0xbb20, 0x9305, 0xbb24, 0x9305, 0xbb28,
- 0x9305, 0xbb2c, 0x9305, 0xbb30, 0x9305, 0xbb34, 0x9305, 0x003e,
- 0x0570, 0xd88c, 0x1128, 0x080c, 0x6bd5, 0x0110, 0xc89d, 0x0438,
- 0x900e, 0x080c, 0x6a7c, 0x1108, 0xc185, 0xb800, 0xd0bc, 0x0108,
- 0xc18d, 0x000e, 0x00ce, 0x00b8, 0x90c6, 0x4007, 0x1110, 0x2408,
- 0x0090, 0x90c6, 0x4008, 0x1118, 0x2708, 0x2610, 0x0060, 0x90c6,
- 0x4009, 0x1108, 0x0040, 0x90c6, 0x4006, 0x1108, 0x0020, 0x2001,
- 0x4005, 0x2009, 0x000a, 0x2020, 0x012e, 0x0804, 0x368a, 0x000e,
- 0x00ce, 0x2b00, 0x7026, 0x0016, 0x00b6, 0x00c6, 0x00e6, 0x2c70,
- 0x080c, 0xaf9f, 0x0904, 0x4ab6, 0x2b00, 0x6012, 0x080c, 0xd0b1,
- 0x2e58, 0x00ee, 0x00e6, 0x00c6, 0x080c, 0x4bce, 0x00ce, 0x2b70,
- 0x1158, 0x080c, 0xaf2e, 0x00ee, 0x00ce, 0x00be, 0x001e, 0x012e,
- 0x2009, 0x0002, 0x0804, 0x36ba, 0x900e, 0xa966, 0xa96a, 0x2900,
- 0x6016, 0xa932, 0xa868, 0xc0fd, 0xd88c, 0x0108, 0xc0f5, 0xa86a,
- 0xd89c, 0x1110, 0x080c, 0x3310, 0x6023, 0x0001, 0x9006, 0x080c,
- 0x66bb, 0xd89c, 0x0138, 0x2001, 0x0004, 0x080c, 0x66cf, 0x2009,
- 0x0003, 0x0030, 0x2001, 0x0002, 0x080c, 0x66cf, 0x2009, 0x0002,
- 0x080c, 0xafcc, 0x78a8, 0xd094, 0x0138, 0x00ee, 0x7024, 0x00e6,
- 0x2058, 0xb8d4, 0xc08d, 0xb8d6, 0x9085, 0x0001, 0x00ee, 0x00ce,
- 0x00be, 0x001e, 0x012e, 0x1120, 0x2009, 0x0003, 0x0804, 0x36ba,
- 0x7007, 0x0003, 0x701f, 0x4ac5, 0x0005, 0xa830, 0x9086, 0x0100,
- 0x7024, 0x2058, 0x1138, 0x2009, 0x0004, 0xba04, 0x9294, 0x00ff,
- 0x0804, 0x5774, 0x900e, 0xa868, 0xd0f4, 0x1904, 0x3688, 0x080c,
- 0x6a7c, 0x1108, 0xc185, 0xb800, 0xd0bc, 0x0108, 0xc18d, 0x0804,
- 0x3688, 0x00e6, 0x00d6, 0x0096, 0x83ff, 0x0904, 0x4b30, 0x902e,
- 0x080c, 0xae60, 0x0130, 0x9026, 0x20a9, 0x0800, 0x2071, 0x1000,
- 0x0030, 0x2021, 0x007f, 0x20a9, 0x0781, 0x2071, 0x107f, 0x2e04,
- 0x9005, 0x11b8, 0x2100, 0x9406, 0x1904, 0x4b41, 0x2428, 0x94ce,
- 0x007f, 0x1120, 0x92ce, 0xfffd, 0x1558, 0x0030, 0x94ce, 0x0080,
- 0x1130, 0x92ce, 0xfffc, 0x1520, 0x93ce, 0x00ff, 0x1508, 0xc5fd,
- 0x0480, 0x2058, 0xbf10, 0x2700, 0x9306, 0x11e8, 0xbe14, 0x2600,
- 0x9206, 0x11c8, 0x2400, 0x9106, 0x1180, 0xd884, 0x0598, 0xd894,
- 0x1588, 0x080c, 0x6b75, 0x1570, 0x2001, 0x4000, 0x0460, 0x080c,
- 0x6bd5, 0x1540, 0x2001, 0x4000, 0x0430, 0x2001, 0x4007, 0x0418,
- 0x2001, 0x4006, 0x0400, 0x2400, 0x9106, 0x1158, 0xbe14, 0x87ff,
- 0x1128, 0x86ff, 0x0918, 0x080c, 0xae60, 0x1900, 0x2001, 0x4008,
- 0x0090, 0x8420, 0x8e70, 0x1f04, 0x4af7, 0x85ff, 0x1130, 0x2001,
- 0x4009, 0x0048, 0x2001, 0x0001, 0x0030, 0x080c, 0x671e, 0x1dd0,
- 0xbb12, 0xba16, 0x9006, 0x9005, 0x009e, 0x00de, 0x00ee, 0x0005,
- 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x36ba, 0x080c, 0x4bce,
- 0x1120, 0x2009, 0x0002, 0x0804, 0x36ba, 0xa867, 0x0000, 0xa868,
- 0xc0fd, 0xa86a, 0x7884, 0x9005, 0x0904, 0x36bd, 0x9096, 0x00ff,
- 0x0120, 0x9092, 0x0004, 0x1a04, 0x36bd, 0x2010, 0x2918, 0x080c,
- 0x32b0, 0x1120, 0x2009, 0x0003, 0x0804, 0x36ba, 0x7007, 0x0003,
- 0x701f, 0x4b83, 0x0005, 0xa830, 0x9086, 0x0100, 0x1904, 0x3688,
- 0x2009, 0x0004, 0x0804, 0x36ba, 0x7984, 0x080c, 0xae60, 0x1120,
- 0x9182, 0x007f, 0x0a04, 0x36bd, 0x9186, 0x00ff, 0x0904, 0x36bd,
- 0x9182, 0x0800, 0x1a04, 0x36bd, 0x2001, 0x9400, 0x080c, 0x57cf,
- 0x1904, 0x36ba, 0x0804, 0x3688, 0xa998, 0x080c, 0xae60, 0x1118,
- 0x9182, 0x007f, 0x0280, 0x9186, 0x00ff, 0x0168, 0x9182, 0x0800,
- 0x1250, 0x2001, 0x9400, 0x080c, 0x57cf, 0x11a8, 0x0060, 0xa897,
+ 0x080c, 0x4c11, 0x701f, 0x4395, 0x0005, 0x080c, 0x582f, 0x1130,
+ 0x3b00, 0x3a08, 0xc194, 0xc095, 0x20d8, 0x21d0, 0x2069, 0x1847,
+ 0x6800, 0x9005, 0x0904, 0x36a8, 0x6804, 0xd0ac, 0x0118, 0xd0a4,
+ 0x0904, 0x36a8, 0xd094, 0x00c6, 0x2061, 0x0100, 0x6104, 0x0138,
+ 0x6200, 0x9292, 0x0005, 0x0218, 0x918c, 0xffdf, 0x0010, 0x918d,
+ 0x0020, 0x6106, 0x00ce, 0xd08c, 0x00c6, 0x2061, 0x0100, 0x6104,
+ 0x0118, 0x918d, 0x0010, 0x0010, 0x918c, 0xffef, 0x6106, 0x00ce,
+ 0xd084, 0x0158, 0x6a28, 0x928a, 0x007f, 0x1a04, 0x36a8, 0x9288,
+ 0x3474, 0x210d, 0x918c, 0x00ff, 0x6166, 0xd0dc, 0x0130, 0x6828,
+ 0x908a, 0x007f, 0x1a04, 0x36a8, 0x605e, 0x6888, 0x9084, 0x0030,
+ 0x8004, 0x8004, 0x8004, 0x8004, 0x0006, 0x2009, 0x19b3, 0x9080,
+ 0x27dd, 0x2005, 0x200a, 0x2008, 0x2001, 0x0018, 0x080c, 0xaae8,
+ 0x2009, 0x0390, 0x200b, 0x0400, 0x000e, 0x2009, 0x19b4, 0x9080,
+ 0x27e1, 0x2005, 0x200a, 0x6808, 0x908a, 0x0100, 0x0a04, 0x36a8,
+ 0x908a, 0x0841, 0x1a04, 0x36a8, 0x9084, 0x0007, 0x1904, 0x36a8,
+ 0x680c, 0x9005, 0x0904, 0x36a8, 0x6810, 0x9005, 0x0904, 0x36a8,
+ 0x6848, 0x6940, 0x910a, 0x1a04, 0x36a8, 0x8001, 0x0904, 0x36a8,
+ 0x684c, 0x6944, 0x910a, 0x1a04, 0x36a8, 0x8001, 0x0904, 0x36a8,
+ 0x6814, 0x908c, 0x00ff, 0x614e, 0x8007, 0x9084, 0x00ff, 0x6052,
+ 0x080c, 0x79d0, 0x080c, 0x6c03, 0x080c, 0x6c65, 0x6808, 0x602a,
+ 0x080c, 0x21af, 0x2009, 0x0170, 0x200b, 0x0080, 0xa001, 0xa001,
+ 0x200b, 0x0000, 0x0036, 0x6b08, 0x080c, 0x2744, 0x003e, 0x6000,
+ 0x9086, 0x0000, 0x1904, 0x4524, 0x6818, 0x691c, 0x6a20, 0x6b24,
+ 0x8007, 0x810f, 0x8217, 0x831f, 0x6016, 0x611a, 0x621e, 0x6322,
+ 0x6c04, 0xd4f4, 0x0148, 0x6830, 0x6934, 0x6a38, 0x6b3c, 0x8007,
+ 0x810f, 0x8217, 0x831f, 0x0010, 0x9084, 0xf0ff, 0x6006, 0x610a,
+ 0x620e, 0x6312, 0x8007, 0x810f, 0x8217, 0x831f, 0x20a9, 0x0004,
+ 0x20a1, 0x19b5, 0x20e9, 0x0001, 0x4001, 0x20a9, 0x0004, 0x20a1,
+ 0x19cf, 0x20e9, 0x0001, 0x4001, 0x080c, 0x89bf, 0x00c6, 0x900e,
+ 0x20a9, 0x0001, 0x6b70, 0xd384, 0x01c8, 0x0020, 0x839d, 0x12b0,
+ 0x3508, 0x8109, 0x080c, 0x7f97, 0x6878, 0x6016, 0x6874, 0x2008,
+ 0x9084, 0xff00, 0x8007, 0x600a, 0x9184, 0x00ff, 0x6006, 0x8108,
+ 0x1118, 0x6003, 0x0003, 0x0010, 0x6003, 0x0001, 0x1f04, 0x447e,
+ 0x00ce, 0x00c6, 0x2061, 0x199d, 0x6a88, 0x9284, 0xc000, 0x2010,
+ 0x9286, 0x0000, 0x1158, 0x2063, 0x0000, 0x2001, 0x0001, 0x080c,
+ 0x29d7, 0x2001, 0x0001, 0x080c, 0x29ba, 0x0088, 0x9286, 0x4000,
+ 0x1148, 0x2063, 0x0001, 0x9006, 0x080c, 0x29d7, 0x9006, 0x080c,
+ 0x29ba, 0x0028, 0x9286, 0x8000, 0x1d30, 0x2063, 0x0002, 0x00ce,
+ 0x00e6, 0x2c70, 0x080c, 0x0ec7, 0x00ee, 0x080c, 0x2aff, 0x080c,
+ 0x2b32, 0x6888, 0xd0ec, 0x0130, 0x2011, 0x0114, 0x2204, 0x9085,
+ 0x0180, 0x2012, 0x6a80, 0x9284, 0x0030, 0x9086, 0x0030, 0x1128,
+ 0x9294, 0xffcf, 0x9295, 0x0020, 0x6a82, 0x2001, 0x197d, 0x6a80,
+ 0x9294, 0x0030, 0x928e, 0x0000, 0x0170, 0x928e, 0x0010, 0x0118,
+ 0x928e, 0x0020, 0x0140, 0x2003, 0xaaaa, 0x080c, 0x27b9, 0x2001,
+ 0x196e, 0x2102, 0x0008, 0x2102, 0x00c6, 0x2061, 0x0100, 0x602f,
+ 0x0040, 0x602f, 0x0000, 0x00ce, 0x080c, 0x769d, 0x0128, 0x080c,
+ 0x5108, 0x0110, 0x080c, 0x270a, 0x60d4, 0x9005, 0x01c0, 0x6003,
+ 0x0001, 0x2009, 0x450c, 0x00e0, 0x080c, 0x769d, 0x1168, 0x2011,
+ 0x7511, 0x080c, 0x882c, 0x2011, 0x7504, 0x080c, 0x8938, 0x080c,
+ 0x79a4, 0x080c, 0x75cc, 0x0040, 0x080c, 0x6033, 0x0028, 0x6003,
+ 0x0004, 0x2009, 0x4524, 0x0020, 0x080c, 0x6b2f, 0x0804, 0x3673,
+ 0x2001, 0x0170, 0x2004, 0x9084, 0x00ff, 0x9086, 0x004c, 0x1118,
+ 0x2091, 0x31bd, 0x0817, 0x2091, 0x313d, 0x0817, 0x6000, 0x9086,
+ 0x0000, 0x0904, 0x36a5, 0x2069, 0x1847, 0x7890, 0x6842, 0x7894,
+ 0x6846, 0x2d00, 0x2009, 0x0030, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98,
+ 0x2039, 0x0001, 0x0804, 0x4c14, 0x9006, 0x080c, 0x270a, 0x81ff,
+ 0x1904, 0x36a5, 0x080c, 0x769d, 0x11b0, 0x080c, 0x799f, 0x080c,
+ 0x6178, 0x080c, 0x3468, 0x0118, 0x6130, 0xc18d, 0x6132, 0x080c,
+ 0xd35d, 0x0130, 0x080c, 0x76c0, 0x1118, 0x080c, 0x7671, 0x0038,
+ 0x080c, 0x75cc, 0x0020, 0x080c, 0x613d, 0x080c, 0x6033, 0x0804,
+ 0x3673, 0x81ff, 0x1904, 0x36a5, 0x080c, 0x769d, 0x1110, 0x0804,
+ 0x36a5, 0x0126, 0x2091, 0x8000, 0x6194, 0x81ff, 0x0190, 0x704f,
+ 0x0000, 0x2001, 0x1d80, 0x2009, 0x0040, 0x7a8c, 0x7b88, 0x7c9c,
+ 0x7d98, 0x2039, 0x0001, 0x080c, 0x4c14, 0x701f, 0x3671, 0x012e,
+ 0x0005, 0x704f, 0x0001, 0x00d6, 0x2069, 0x1d80, 0x20a9, 0x0040,
+ 0x20e9, 0x0001, 0x20a1, 0x1d80, 0x2019, 0xffff, 0x4304, 0x655c,
+ 0x9588, 0x3474, 0x210d, 0x918c, 0x00ff, 0x216a, 0x900e, 0x2011,
+ 0x0002, 0x2100, 0x9506, 0x01a8, 0x080c, 0x6783, 0x1190, 0xb814,
+ 0x821c, 0x0238, 0x9398, 0x1d80, 0x9085, 0xff00, 0x8007, 0x201a,
+ 0x0038, 0x9398, 0x1d80, 0x2324, 0x94a4, 0xff00, 0x9405, 0x201a,
+ 0x8210, 0x8108, 0x9182, 0x0080, 0x1208, 0x0c18, 0x8201, 0x8007,
+ 0x2d0c, 0x9105, 0x206a, 0x00de, 0x20a9, 0x0040, 0x20a1, 0x1d80,
+ 0x2099, 0x1d80, 0x080c, 0x60c8, 0x0804, 0x4581, 0x080c, 0x4bfb,
+ 0x0904, 0x36a8, 0x080c, 0x4bc8, 0x1120, 0x2009, 0x0002, 0x0804,
+ 0x36a5, 0x080c, 0x5820, 0xd0b4, 0x0558, 0x7884, 0x908e, 0x007e,
+ 0x0538, 0x908e, 0x007f, 0x0520, 0x908e, 0x0080, 0x0508, 0x080c,
+ 0x3463, 0x1148, 0xb800, 0xd08c, 0x11d8, 0xb804, 0x9084, 0x00ff,
+ 0x9086, 0x0006, 0x11a8, 0xa867, 0x0000, 0xa868, 0xc0fd, 0xa86a,
+ 0x080c, 0xce04, 0x1120, 0x2009, 0x0003, 0x0804, 0x36a5, 0x7007,
+ 0x0003, 0x701f, 0x460c, 0x0005, 0x080c, 0x4bfb, 0x0904, 0x36a8,
+ 0x20a9, 0x002b, 0xb8c4, 0x20e0, 0xb8c8, 0x2098, 0xa860, 0x20e8,
+ 0xa85c, 0x9080, 0x0002, 0x20a0, 0x4003, 0x20a9, 0x0008, 0x9080,
+ 0x0006, 0x20a0, 0xb8c4, 0x20e0, 0xb8c8, 0x9080, 0x0006, 0x2098,
+ 0x080c, 0x0fca, 0x0070, 0x20a9, 0x0004, 0xa85c, 0x9080, 0x000a,
+ 0x20a0, 0xb8c4, 0x20e0, 0xb8c8, 0x9080, 0x000a, 0x2098, 0x080c,
+ 0x0fca, 0x8906, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0,
+ 0x9080, 0x0002, 0x2009, 0x002b, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98,
+ 0x0804, 0x4c14, 0x81ff, 0x1904, 0x36a5, 0x080c, 0x4bdf, 0x0904,
+ 0x36a8, 0x080c, 0x69c6, 0x0904, 0x36a5, 0x0058, 0xa878, 0x9005,
+ 0x0120, 0x2009, 0x0004, 0x0804, 0x36a5, 0xa974, 0xaa94, 0x0804,
+ 0x3673, 0x080c, 0x5828, 0x0904, 0x3673, 0x701f, 0x4656, 0x7007,
+ 0x0003, 0x0005, 0x81ff, 0x1904, 0x36a5, 0x7888, 0x908a, 0x1000,
+ 0x1a04, 0x36a8, 0x080c, 0x4bfb, 0x0904, 0x36a8, 0x080c, 0x6bcd,
+ 0x0120, 0x080c, 0x6bd5, 0x1904, 0x36a8, 0x080c, 0x6a4b, 0x0904,
+ 0x36a5, 0x2019, 0x0004, 0x900e, 0x080c, 0x69d8, 0x0904, 0x36a5,
+ 0x7984, 0x7a88, 0x04c9, 0x08a8, 0xa89c, 0x908a, 0x1000, 0x12f8,
+ 0x080c, 0x4bf9, 0x01e0, 0x080c, 0x6bcd, 0x0118, 0x080c, 0x6bd5,
+ 0x11b0, 0x080c, 0x6a4b, 0x2009, 0x0002, 0x0168, 0x2009, 0x0002,
+ 0x2019, 0x0004, 0x080c, 0x69d8, 0x2009, 0x0003, 0x0120, 0xa998,
+ 0xaa9c, 0x00d1, 0x0060, 0xa897, 0x4005, 0xa99a, 0x0010, 0xa897,
+ 0x4006, 0x900e, 0x9085, 0x0001, 0x2001, 0x0030, 0x0005, 0xa897,
+ 0x4000, 0x080c, 0x5828, 0x0110, 0x9006, 0x0018, 0x900e, 0x9085,
+ 0x0001, 0x2001, 0x0000, 0x0005, 0x9186, 0x00ff, 0x0110, 0x0071,
+ 0x0060, 0x2029, 0x007e, 0x2061, 0x1800, 0x645c, 0x2400, 0x9506,
+ 0x0110, 0x2508, 0x0019, 0x8529, 0x1ec8, 0x0005, 0x080c, 0x6783,
+ 0x1138, 0x2200, 0x8003, 0x800b, 0x810b, 0x9108, 0x080c, 0x883a,
+ 0x0005, 0x81ff, 0x1904, 0x36a5, 0x798c, 0x2001, 0x1981, 0x918c,
+ 0x8000, 0x2102, 0x080c, 0x4bdf, 0x0904, 0x36a8, 0x080c, 0x6bcd,
+ 0x0120, 0x080c, 0x6bd5, 0x1904, 0x36a8, 0x080c, 0x684a, 0x0904,
+ 0x36a5, 0x080c, 0x69cf, 0x0904, 0x36a5, 0x2001, 0x1981, 0x2004,
+ 0xd0fc, 0x1904, 0x3673, 0x0804, 0x4661, 0xa9a0, 0x2001, 0x1981,
+ 0x918c, 0x8000, 0xc18d, 0x2102, 0x080c, 0x4bec, 0x01a0, 0x080c,
+ 0x6bcd, 0x0118, 0x080c, 0x6bd5, 0x1170, 0x080c, 0x684a, 0x2009,
+ 0x0002, 0x0128, 0x080c, 0x69cf, 0x1170, 0x2009, 0x0003, 0xa897,
0x4005, 0xa99a, 0x0010, 0xa897, 0x4006, 0x900e, 0x9085, 0x0001,
- 0x2001, 0x0030, 0x0005, 0xa897, 0x4000, 0x900e, 0x9085, 0x0001,
- 0x2001, 0x0000, 0x0005, 0x2009, 0x000a, 0x0c48, 0x080c, 0x1059,
- 0x0198, 0x9006, 0xa802, 0x7014, 0x9005, 0x1120, 0x2900, 0x7016,
- 0x701a, 0x0040, 0x7018, 0xa802, 0x0086, 0x2040, 0x2900, 0xa006,
- 0x701a, 0x008e, 0x9085, 0x0001, 0x0005, 0x7984, 0x080c, 0x6789,
- 0x1130, 0x7e88, 0x9684, 0x3fff, 0x9082, 0x4000, 0x0208, 0x905e,
- 0x8bff, 0x0005, 0xa998, 0x080c, 0x6789, 0x1130, 0xae9c, 0x9684,
- 0x3fff, 0x9082, 0x4000, 0x0208, 0x905e, 0x8bff, 0x0005, 0xae98,
- 0x0008, 0x7e84, 0x2608, 0x080c, 0x6789, 0x1108, 0x0008, 0x905e,
- 0x8bff, 0x0005, 0x0016, 0x7114, 0x81ff, 0x0128, 0x2148, 0xa904,
- 0x080c, 0x108b, 0x0cc8, 0x7116, 0x711a, 0x001e, 0x0005, 0x2031,
- 0x0001, 0x0010, 0x2031, 0x0000, 0x2061, 0x18b8, 0x2c44, 0xa66a,
- 0xa17a, 0xa772, 0xa076, 0xa28e, 0xa392, 0xa496, 0xa59a, 0x080c,
- 0x114e, 0x7007, 0x0002, 0x701f, 0x3688, 0x0005, 0x00f6, 0x0126,
- 0x2091, 0x8000, 0x2079, 0x0000, 0x2001, 0x18b0, 0x2004, 0x9005,
- 0x1190, 0x0e04, 0x4c4b, 0x7a36, 0x7833, 0x0012, 0x7a82, 0x7b86,
- 0x7c8a, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c,
- 0x1200, 0x0804, 0x4cb1, 0x0016, 0x0086, 0x0096, 0x00c6, 0x00e6,
- 0x2071, 0x189e, 0x7044, 0x9005, 0x1540, 0x7148, 0x9182, 0x0010,
- 0x0288, 0x7038, 0x2060, 0x080c, 0x1059, 0x0904, 0x4ca9, 0xa84b,
- 0x0000, 0x2900, 0x7046, 0x2001, 0x0002, 0x9080, 0x1ee2, 0x2005,
- 0xa846, 0x0098, 0x7038, 0x90e0, 0x0004, 0x2001, 0x18ba, 0x9c82,
- 0x18fa, 0x0210, 0x2061, 0x18ba, 0x2c00, 0x703a, 0x7148, 0x81ff,
- 0x1108, 0x703e, 0x8108, 0x714a, 0x0460, 0x7148, 0x8108, 0x714a,
- 0x7044, 0x2040, 0xa144, 0x2105, 0x0016, 0x908a, 0x0036, 0x1a0c,
- 0x0d85, 0x2060, 0x001e, 0x8108, 0x2105, 0x9005, 0xa146, 0x1520,
- 0x080c, 0x1059, 0x1130, 0x8109, 0xa946, 0x7148, 0x8109, 0x714a,
- 0x00d8, 0x9006, 0xa806, 0xa84a, 0xa046, 0x2800, 0xa802, 0x2900,
- 0xa006, 0x7046, 0x2001, 0x0002, 0x9080, 0x1ee2, 0x2005, 0xa846,
- 0x0058, 0x2262, 0x6306, 0x640a, 0x00ee, 0x00ce, 0x009e, 0x008e,
- 0x001e, 0x012e, 0x00fe, 0x0005, 0x2c00, 0x9082, 0x001b, 0x0002,
- 0x4cd3, 0x4cd3, 0x4cd5, 0x4cd3, 0x4cd3, 0x4cd3, 0x4cd9, 0x4cd3,
- 0x4cd3, 0x4cd3, 0x4cdd, 0x4cd3, 0x4cd3, 0x4cd3, 0x4ce1, 0x4cd3,
- 0x4cd3, 0x4cd3, 0x4ce5, 0x4cd3, 0x4cd3, 0x4cd3, 0x4ce9, 0x4cd3,
- 0x4cd3, 0x4cd3, 0x4cee, 0x080c, 0x0d85, 0xa276, 0xa37a, 0xa47e,
- 0x0898, 0xa286, 0xa38a, 0xa48e, 0x0878, 0xa296, 0xa39a, 0xa49e,
- 0x0858, 0xa2a6, 0xa3aa, 0xa4ae, 0x0838, 0xa2b6, 0xa3ba, 0xa4be,
- 0x0818, 0xa2c6, 0xa3ca, 0xa4ce, 0x0804, 0x4cac, 0xa2d6, 0xa3da,
- 0xa4de, 0x0804, 0x4cac, 0x00e6, 0x2071, 0x189e, 0x7048, 0x9005,
- 0x0904, 0x4d85, 0x0126, 0x2091, 0x8000, 0x0e04, 0x4d84, 0x00f6,
- 0x2079, 0x0000, 0x00c6, 0x0096, 0x0086, 0x0076, 0x9006, 0x2038,
- 0x7040, 0x2048, 0x9005, 0x0500, 0xa948, 0x2105, 0x0016, 0x908a,
- 0x0036, 0x1a0c, 0x0d85, 0x2060, 0x001e, 0x8108, 0x2105, 0x9005,
- 0xa94a, 0x1904, 0x4d87, 0xa804, 0x9005, 0x090c, 0x0d85, 0x7042,
- 0x2938, 0x2040, 0xa003, 0x0000, 0x2001, 0x0002, 0x9080, 0x1ee2,
- 0x2005, 0xa04a, 0x0804, 0x4d87, 0x703c, 0x2060, 0x2c14, 0x6304,
- 0x6408, 0x650c, 0x2200, 0x7836, 0x7833, 0x0012, 0x7882, 0x2300,
- 0x7886, 0x2400, 0x788a, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004,
- 0xd084, 0x190c, 0x1200, 0x87ff, 0x0118, 0x2748, 0x080c, 0x108b,
- 0x7048, 0x8001, 0x704a, 0x9005, 0x1170, 0x7040, 0x2048, 0x9005,
- 0x0128, 0x080c, 0x108b, 0x9006, 0x7042, 0x7046, 0x703b, 0x18ba,
- 0x703f, 0x18ba, 0x0420, 0x7040, 0x9005, 0x1508, 0x7238, 0x2c00,
- 0x9206, 0x0148, 0x9c80, 0x0004, 0x90fa, 0x18fa, 0x0210, 0x2001,
- 0x18ba, 0x703e, 0x00a0, 0x9006, 0x703e, 0x703a, 0x7044, 0x9005,
- 0x090c, 0x0d85, 0x2048, 0xa800, 0x9005, 0x1de0, 0x2900, 0x7042,
- 0x2001, 0x0002, 0x9080, 0x1ee2, 0x2005, 0xa84a, 0x0000, 0x007e,
- 0x008e, 0x009e, 0x00ce, 0x00fe, 0x012e, 0x00ee, 0x0005, 0x2c00,
- 0x9082, 0x001b, 0x0002, 0x4da6, 0x4da6, 0x4da8, 0x4da6, 0x4da6,
- 0x4da6, 0x4dad, 0x4da6, 0x4da6, 0x4da6, 0x4db2, 0x4da6, 0x4da6,
- 0x4da6, 0x4db7, 0x4da6, 0x4da6, 0x4da6, 0x4dbc, 0x4da6, 0x4da6,
- 0x4da6, 0x4dc1, 0x4da6, 0x4da6, 0x4da6, 0x4dc6, 0x080c, 0x0d85,
- 0xaa74, 0xab78, 0xac7c, 0x0804, 0x4d32, 0xaa84, 0xab88, 0xac8c,
- 0x0804, 0x4d32, 0xaa94, 0xab98, 0xac9c, 0x0804, 0x4d32, 0xaaa4,
- 0xaba8, 0xacac, 0x0804, 0x4d32, 0xaab4, 0xabb8, 0xacbc, 0x0804,
- 0x4d32, 0xaac4, 0xabc8, 0xaccc, 0x0804, 0x4d32, 0xaad4, 0xabd8,
- 0xacdc, 0x0804, 0x4d32, 0x0016, 0x0026, 0x0036, 0x00b6, 0x00c6,
- 0x2009, 0x007e, 0x080c, 0x6789, 0x2019, 0x0001, 0xb85c, 0xd0ac,
- 0x0110, 0x2019, 0x0000, 0x2011, 0x801b, 0x080c, 0x4c2e, 0x00ce,
- 0x00be, 0x003e, 0x002e, 0x001e, 0x0005, 0x0026, 0x080c, 0x5826,
- 0xd0c4, 0x0120, 0x2011, 0x8014, 0x080c, 0x4c2e, 0x002e, 0x0005,
- 0x81ff, 0x1904, 0x36ba, 0x0126, 0x2091, 0x8000, 0x6030, 0xc08d,
- 0xc085, 0xc0ac, 0x6032, 0x080c, 0x76a5, 0x1158, 0x080c, 0x79a7,
- 0x080c, 0x617e, 0x9085, 0x0001, 0x080c, 0x76e9, 0x080c, 0x75d4,
- 0x0010, 0x080c, 0x6039, 0x012e, 0x0804, 0x3688, 0x81ff, 0x0120,
- 0x2009, 0x0001, 0x0804, 0x36ba, 0x080c, 0x583a, 0x0120, 0x2009,
- 0x0007, 0x0804, 0x36ba, 0x080c, 0x6bcd, 0x0120, 0x2009, 0x0008,
- 0x0804, 0x36ba, 0x7984, 0x080c, 0x671e, 0x1904, 0x36bd, 0x080c,
- 0x4c01, 0x0904, 0x36bd, 0x2b00, 0x7026, 0x080c, 0x6bd5, 0x7888,
- 0x1170, 0x9084, 0x0005, 0x1158, 0x900e, 0x080c, 0x6a7c, 0x1108,
- 0xc185, 0xb800, 0xd0bc, 0x0108, 0xc18d, 0x0804, 0x3688, 0x080c,
- 0x4bce, 0x0904, 0x36ba, 0x9006, 0xa866, 0xa832, 0xa868, 0xc0fd,
- 0xa86a, 0x080c, 0xce4f, 0x0904, 0x36ba, 0x7888, 0xd094, 0x0118,
- 0xb8d4, 0xc08d, 0xb8d6, 0x7007, 0x0003, 0x701f, 0x4ea1, 0x0005,
- 0x2061, 0x1800, 0x080c, 0x583a, 0x2009, 0x0007, 0x1560, 0x080c,
- 0x6bcd, 0x0118, 0x2009, 0x0008, 0x0430, 0xa998, 0x080c, 0x671e,
- 0x1530, 0x080c, 0x4bff, 0x0518, 0x080c, 0x6bd5, 0xa89c, 0x1168,
- 0x9084, 0x0005, 0x1150, 0x900e, 0x080c, 0x6a7c, 0x1108, 0xc185,
- 0xb800, 0xd0bc, 0x0108, 0xc18d, 0x00d0, 0xa868, 0xc0fc, 0xa86a,
- 0x080c, 0xce4f, 0x11e0, 0xa89c, 0xd094, 0x0118, 0xb8d4, 0xc08d,
- 0xb8d6, 0x2009, 0x0003, 0xa897, 0x4005, 0xa99a, 0x0010, 0xa897,
+ 0x2001, 0x0030, 0x0005, 0xa897, 0x4000, 0x2001, 0x1981, 0x2004,
+ 0xd0fc, 0x1128, 0x080c, 0x5828, 0x0110, 0x9006, 0x0018, 0x900e,
+ 0x9085, 0x0001, 0x2001, 0x0000, 0x0005, 0x81ff, 0x1904, 0x36a5,
+ 0x798c, 0x2001, 0x1980, 0x918c, 0x8000, 0x2102, 0x080c, 0x4bdf,
+ 0x0904, 0x36a8, 0x080c, 0x6bcd, 0x0120, 0x080c, 0x6bd5, 0x1904,
+ 0x36a8, 0x080c, 0x684a, 0x0904, 0x36a5, 0x080c, 0x69bd, 0x0904,
+ 0x36a5, 0x2001, 0x1980, 0x2004, 0xd0fc, 0x1904, 0x3673, 0x0804,
+ 0x4661, 0xa9a0, 0x2001, 0x1980, 0x918c, 0x8000, 0xc18d, 0x2102,
+ 0x080c, 0x4bec, 0x01a0, 0x080c, 0x6bcd, 0x0118, 0x080c, 0x6bd5,
+ 0x1170, 0x080c, 0x684a, 0x2009, 0x0002, 0x0128, 0x080c, 0x69bd,
+ 0x1170, 0x2009, 0x0003, 0xa897, 0x4005, 0xa99a, 0x0010, 0xa897,
0x4006, 0x900e, 0x9085, 0x0001, 0x2001, 0x0030, 0x0005, 0xa897,
- 0x4000, 0xa99a, 0x9006, 0x918d, 0x0001, 0x2008, 0x0005, 0x9006,
- 0x0005, 0xa830, 0x9086, 0x0100, 0x7024, 0x2058, 0x1110, 0x0804,
- 0x5774, 0x900e, 0x080c, 0x6a7c, 0x1108, 0xc185, 0xb800, 0xd0bc,
- 0x0108, 0xc18d, 0x0804, 0x3688, 0x080c, 0x583a, 0x0120, 0x2009,
- 0x0007, 0x0804, 0x36ba, 0x7f84, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98,
- 0x080c, 0x4bce, 0x1120, 0x2009, 0x0002, 0x0804, 0x36ba, 0x900e,
- 0x2130, 0x7126, 0x7132, 0xa860, 0x20e8, 0x7036, 0xa85c, 0x9080,
- 0x0005, 0x702a, 0x20a0, 0x080c, 0x6789, 0x1904, 0x4f4a, 0x080c,
- 0x6bd5, 0x0138, 0x080c, 0x6bdd, 0x0120, 0x080c, 0x6b75, 0x1904,
- 0x4f4a, 0xd794, 0x1110, 0xd784, 0x01a8, 0xb8c4, 0x20e0, 0xb8c8,
- 0x9080, 0x0006, 0x2098, 0x3400, 0xd794, 0x0198, 0x20a9, 0x0008,
- 0x4003, 0x2098, 0x20a0, 0x3d00, 0x20e0, 0x20a9, 0x0002, 0x080c,
- 0x49cd, 0x0080, 0xb8c4, 0x20e0, 0xb8c8, 0x9080, 0x000a, 0x2098,
- 0x3400, 0x20a9, 0x0004, 0x4003, 0x2098, 0x20a0, 0x3d00, 0x20e0,
- 0x080c, 0x49cd, 0x9186, 0x007e, 0x0170, 0x9186, 0x0080, 0x0158,
- 0x080c, 0x6bd5, 0x90c2, 0x0006, 0x1210, 0xc1fd, 0x0020, 0x080c,
- 0x6a7c, 0x1108, 0xc1fd, 0x4104, 0xc1fc, 0xd794, 0x0528, 0xb8c4,
- 0x20e0, 0xb8c8, 0x2060, 0x9c80, 0x0000, 0x2098, 0x20a9, 0x0002,
- 0x4003, 0x9c80, 0x0003, 0x2098, 0x20a9, 0x0001, 0x4005, 0x9c80,
- 0x0004, 0x2098, 0x3400, 0x20a9, 0x0002, 0x4003, 0x2098, 0x20a0,
- 0x3d00, 0x20e0, 0x080c, 0x49c0, 0x9c80, 0x0026, 0x2098, 0xb8c4,
- 0x20e0, 0x20a9, 0x0002, 0x4003, 0xd794, 0x0110, 0x96b0, 0x000b,
- 0x96b0, 0x0005, 0x8108, 0x080c, 0xae60, 0x0118, 0x9186, 0x0800,
- 0x0040, 0xd78c, 0x0120, 0x9186, 0x0800, 0x0170, 0x0018, 0x9186,
- 0x007e, 0x0150, 0xd794, 0x0118, 0x9686, 0x0020, 0x0010, 0x9686,
- 0x0028, 0x0150, 0x0804, 0x4ed3, 0x86ff, 0x1120, 0x7124, 0x810b,
- 0x0804, 0x3688, 0x7033, 0x0001, 0x7122, 0x7024, 0x9600, 0x7026,
- 0x772e, 0x2061, 0x18b8, 0x2c44, 0xa06b, 0x0000, 0xa67a, 0x7034,
- 0xa072, 0x7028, 0xa076, 0xa28e, 0xa392, 0xa496, 0xa59a, 0x080c,
- 0x114e, 0x7007, 0x0002, 0x701f, 0x4f86, 0x0005, 0x7030, 0x9005,
- 0x1180, 0x7120, 0x7028, 0x20a0, 0x772c, 0x9036, 0x7034, 0x20e8,
- 0x2061, 0x18b8, 0x2c44, 0xa28c, 0xa390, 0xa494, 0xa598, 0x0804,
- 0x4ed3, 0x7124, 0x810b, 0x0804, 0x3688, 0x2029, 0x007e, 0x7984,
- 0x7a88, 0x7b8c, 0x7c98, 0x9184, 0xff00, 0x8007, 0x90e2, 0x0020,
- 0x0a04, 0x36bd, 0x9502, 0x0a04, 0x36bd, 0x9184, 0x00ff, 0x90e2,
- 0x0020, 0x0a04, 0x36bd, 0x9502, 0x0a04, 0x36bd, 0x9284, 0xff00,
- 0x8007, 0x90e2, 0x0020, 0x0a04, 0x36bd, 0x9502, 0x0a04, 0x36bd,
- 0x9284, 0x00ff, 0x90e2, 0x0020, 0x0a04, 0x36bd, 0x9502, 0x0a04,
- 0x36bd, 0x9384, 0xff00, 0x8007, 0x90e2, 0x0020, 0x0a04, 0x36bd,
- 0x9502, 0x0a04, 0x36bd, 0x9384, 0x00ff, 0x90e2, 0x0020, 0x0a04,
- 0x36bd, 0x9502, 0x0a04, 0x36bd, 0x9484, 0xff00, 0x8007, 0x90e2,
- 0x0020, 0x0a04, 0x36bd, 0x9502, 0x0a04, 0x36bd, 0x9484, 0x00ff,
- 0x90e2, 0x0020, 0x0a04, 0x36bd, 0x9502, 0x0a04, 0x36bd, 0x2061,
- 0x198a, 0x6102, 0x6206, 0x630a, 0x640e, 0x0804, 0x3688, 0x080c,
- 0x4bce, 0x0904, 0x36ba, 0x2009, 0x0016, 0x7a8c, 0x7b88, 0x7c9c,
- 0x7d98, 0xa85c, 0x9080, 0x0019, 0xaf60, 0x080c, 0x4c17, 0x701f,
- 0x500a, 0x0005, 0x2001, 0x0138, 0x2003, 0x0000, 0x00e6, 0x2071,
- 0x0300, 0x701c, 0xd0a4, 0x1de8, 0x00ee, 0x20a9, 0x0016, 0x896e,
- 0x8d6e, 0x8d6f, 0x9d84, 0xffc0, 0x9080, 0x0019, 0x2098, 0x9d84,
- 0x003f, 0x20e0, 0x2069, 0x1877, 0x20e9, 0x0001, 0x2da0, 0x4003,
- 0x6800, 0x9005, 0x0904, 0x508b, 0x6804, 0x2008, 0x918c, 0xfff8,
- 0x1904, 0x508b, 0x680c, 0x9005, 0x0904, 0x508b, 0x9082, 0xff01,
- 0x1a04, 0x508b, 0x6810, 0x9082, 0x005c, 0x0a04, 0x508b, 0x6824,
- 0x2008, 0x9082, 0x0008, 0x0a04, 0x508b, 0x9182, 0x0400, 0x1a04,
- 0x508b, 0x0056, 0x2029, 0x0000, 0x080c, 0x8f15, 0x005e, 0x6944,
- 0x6820, 0x9102, 0x06c0, 0x6820, 0x9082, 0x0019, 0x16a0, 0x6828,
- 0x6944, 0x810c, 0x9102, 0x0678, 0x6840, 0x9082, 0x000f, 0x1658,
- 0x080c, 0x1072, 0x2900, 0x0904, 0x50a7, 0x684e, 0x00e6, 0x2071,
- 0x1932, 0x00b6, 0x2059, 0x0000, 0x080c, 0x8dd1, 0x00be, 0x00ee,
- 0x0568, 0x080c, 0x8b19, 0x080c, 0x8b68, 0x11e0, 0x6857, 0x0000,
- 0x00c6, 0x2061, 0x0100, 0x6104, 0x918d, 0x2000, 0x6106, 0x6b10,
- 0x2061, 0x1a6f, 0x630e, 0x00ce, 0x080c, 0x27ba, 0x2001, 0x0138,
- 0x2102, 0x0804, 0x3688, 0x080c, 0x27ba, 0x2001, 0x0138, 0x2102,
- 0x0804, 0x36bd, 0x080c, 0x8b61, 0x00e6, 0x2071, 0x1932, 0x080c,
- 0x8f95, 0x080c, 0x8fa4, 0x080c, 0x8db4, 0x00ee, 0x2001, 0x188a,
- 0x204c, 0x080c, 0x108b, 0x2001, 0x188a, 0x2003, 0x0000, 0x080c,
- 0x27ba, 0x2001, 0x0138, 0x2102, 0x0804, 0x36ba, 0x2001, 0x1926,
- 0x200c, 0x918e, 0x0000, 0x0904, 0x510c, 0x080c, 0x8daf, 0x0904,
- 0x510c, 0x2001, 0x0101, 0x200c, 0x918c, 0xdfff, 0x2102, 0x2001,
- 0x0138, 0x2003, 0x0000, 0x00e6, 0x2071, 0x0300, 0x701c, 0xd0a4,
- 0x1de8, 0x00ee, 0x080c, 0x8db4, 0x0126, 0x2091, 0x8000, 0x2001,
- 0x0035, 0x080c, 0x16b9, 0x012e, 0x00c6, 0x2061, 0x193e, 0x6004,
- 0x6100, 0x9106, 0x1de0, 0x00ce, 0x080c, 0x27ba, 0x2001, 0x0138,
- 0x2102, 0x00e6, 0x00f6, 0x2071, 0x1925, 0x080c, 0x8cee, 0x0120,
- 0x2f00, 0x080c, 0x8d7a, 0x0cc8, 0x00fe, 0x00ee, 0x0126, 0x2091,
- 0x8000, 0x2001, 0x188a, 0x200c, 0x81ff, 0x0138, 0x2148, 0x080c,
- 0x108b, 0x2001, 0x188a, 0x2003, 0x0000, 0x2001, 0x183e, 0x2003,
- 0x0020, 0x080c, 0x8b61, 0x00e6, 0x2071, 0x1932, 0x080c, 0x8f95,
- 0x080c, 0x8fa4, 0x00ee, 0x012e, 0x0804, 0x3688, 0x0006, 0x080c,
- 0x5826, 0xd0cc, 0x000e, 0x0005, 0x0006, 0x080c, 0x582a, 0xd0bc,
- 0x000e, 0x0005, 0x6174, 0x7a84, 0x6300, 0x82ff, 0x1118, 0x7986,
- 0x0804, 0x3688, 0x83ff, 0x1904, 0x36bd, 0x2001, 0xfff0, 0x9200,
- 0x1a04, 0x36bd, 0x2019, 0xffff, 0x6078, 0x9302, 0x9200, 0x0a04,
- 0x36bd, 0x7986, 0x6276, 0x0804, 0x3688, 0x080c, 0x583a, 0x1904,
- 0x36ba, 0x7c88, 0x7d84, 0x7e98, 0x7f8c, 0x080c, 0x4bce, 0x0904,
- 0x36ba, 0x900e, 0x901e, 0x7326, 0x7332, 0xa860, 0x20e8, 0x7036,
- 0xa85c, 0x9080, 0x0003, 0x702a, 0x20a0, 0x91d8, 0x1000, 0x2b5c,
- 0x8bff, 0x0178, 0x080c, 0x6bd5, 0x0118, 0x080c, 0x6bdd, 0x1148,
- 0x20a9, 0x0001, 0xb814, 0x4004, 0xb810, 0x4004, 0x4104, 0x9398,
- 0x0003, 0x8108, 0x9182, 0x0800, 0x0120, 0x9386, 0x003c, 0x0170,
- 0x0c20, 0x83ff, 0x1148, 0x7224, 0x900e, 0x2001, 0x0003, 0x080c,
- 0x936c, 0x2208, 0x0804, 0x3688, 0x7033, 0x0001, 0x7122, 0x7024,
- 0x9300, 0x7026, 0x2061, 0x18b8, 0x2c44, 0xa06b, 0x0000, 0xa37a,
- 0x7028, 0xa076, 0x7034, 0xa072, 0xa48e, 0xa592, 0xa696, 0xa79a,
- 0x080c, 0x114e, 0x7007, 0x0002, 0x701f, 0x518f, 0x0005, 0x7030,
- 0x9005, 0x1178, 0x7120, 0x7028, 0x20a0, 0x901e, 0x7034, 0x20e8,
- 0x2061, 0x18b8, 0x2c44, 0xa48c, 0xa590, 0xa694, 0xa798, 0x0804,
- 0x514d, 0x7224, 0x900e, 0x2001, 0x0003, 0x080c, 0x936c, 0x2208,
- 0x0804, 0x3688, 0x00f6, 0x00e6, 0x080c, 0x583a, 0x2009, 0x0007,
- 0x1904, 0x5222, 0x2071, 0x189e, 0x745c, 0x84ff, 0x2009, 0x000e,
- 0x1904, 0x5222, 0xac9c, 0xad98, 0xaea4, 0xafa0, 0x0096, 0x080c,
- 0x1072, 0x2009, 0x0002, 0x0904, 0x5222, 0x2900, 0x705e, 0x900e,
- 0x901e, 0x7356, 0x7362, 0xa860, 0x7066, 0xa85c, 0x9080, 0x0003,
- 0x705a, 0x20a0, 0x91d8, 0x1000, 0x2b5c, 0x8bff, 0x0178, 0x080c,
- 0x6bd5, 0x0118, 0x080c, 0x6bdd, 0x1148, 0xb814, 0x20a9, 0x0001,
- 0x4004, 0xb810, 0x4004, 0x4104, 0x9398, 0x0003, 0x8108, 0x9182,
- 0x0800, 0x0120, 0x9386, 0x003c, 0x01e8, 0x0c20, 0x83ff, 0x11c0,
- 0x7254, 0x900e, 0x2001, 0x0003, 0x080c, 0x936c, 0x2208, 0x009e,
- 0xa897, 0x4000, 0xa99a, 0x715c, 0x81ff, 0x090c, 0x0d85, 0x2148,
- 0x080c, 0x108b, 0x9006, 0x705e, 0x918d, 0x0001, 0x2008, 0x0418,
- 0x7063, 0x0001, 0x7152, 0x7054, 0x9300, 0x7056, 0x2061, 0x18b9,
- 0x2c44, 0xa37a, 0x7058, 0xa076, 0x7064, 0xa072, 0xa48e, 0xa592,
- 0xa696, 0xa79a, 0xa09f, 0x522e, 0x000e, 0xa0a2, 0x080c, 0x114e,
- 0x9006, 0x0048, 0x009e, 0xa897, 0x4005, 0xa99a, 0x900e, 0x9085,
- 0x0001, 0x2001, 0x0030, 0x00ee, 0x00fe, 0x0005, 0x00f6, 0xa0a0,
- 0x904d, 0x090c, 0x0d85, 0x00e6, 0x2071, 0x189e, 0xa06c, 0x908e,
- 0x0100, 0x0138, 0xa87b, 0x0030, 0xa883, 0x0000, 0xa897, 0x4002,
- 0x00d8, 0x7060, 0x9005, 0x1158, 0x7150, 0x7058, 0x20a0, 0x901e,
- 0x7064, 0x20e8, 0xa48c, 0xa590, 0xa694, 0xa798, 0x0428, 0xa87b,
- 0x0000, 0xa883, 0x0000, 0xa897, 0x4000, 0x7254, 0x900e, 0x2001,
- 0x0003, 0x080c, 0x936c, 0xaa9a, 0x715c, 0x81ff, 0x090c, 0x0d85,
- 0x2148, 0x080c, 0x108b, 0x705f, 0x0000, 0xa0a0, 0x2048, 0x0126,
- 0x2091, 0x8000, 0x080c, 0x6f19, 0x012e, 0xa09f, 0x0000, 0xa0a3,
- 0x0000, 0x00ee, 0x00fe, 0x0005, 0x91d8, 0x1000, 0x2b5c, 0x8bff,
- 0x0178, 0x080c, 0x6bd5, 0x0118, 0x080c, 0x6bdd, 0x1148, 0xb814,
+ 0x4000, 0x2001, 0x1980, 0x2004, 0xd0fc, 0x1128, 0x080c, 0x5828,
+ 0x0110, 0x9006, 0x0018, 0x900e, 0x9085, 0x0001, 0x2001, 0x0000,
+ 0x0005, 0x6100, 0x0804, 0x3673, 0x080c, 0x4bfb, 0x0904, 0x36a8,
+ 0x080c, 0x5834, 0x1904, 0x36a5, 0x79a8, 0xd184, 0x1158, 0xb834,
+ 0x8007, 0x789e, 0xb830, 0x8007, 0x789a, 0xbb2c, 0x831f, 0xba28,
+ 0x8217, 0x0050, 0xb824, 0x8007, 0x789e, 0xb820, 0x8007, 0x789a,
+ 0xbb1c, 0x831f, 0xba18, 0x8217, 0xb900, 0x918c, 0x0202, 0x0804,
+ 0x3673, 0x78a8, 0x909c, 0x0003, 0xd0ac, 0x1150, 0xd0b4, 0x1140,
+ 0x939a, 0x0003, 0x1a04, 0x36a5, 0x625c, 0x7884, 0x9206, 0x1548,
+ 0x080c, 0x89a9, 0x2001, 0xffec, 0x2009, 0x000c, 0x7a8c, 0x7b88,
+ 0x7c9c, 0x7d98, 0x2039, 0x0000, 0x0006, 0x78a8, 0x9084, 0x0080,
+ 0x1118, 0x000e, 0x0804, 0x4c14, 0x000e, 0x2031, 0x0000, 0x2061,
+ 0x18b8, 0x2c44, 0xa66a, 0xa17a, 0xa772, 0xa076, 0xa28e, 0xa392,
+ 0xa496, 0xa59a, 0x080c, 0x1142, 0x7007, 0x0002, 0x701f, 0x4819,
+ 0x0005, 0x81ff, 0x1904, 0x36a5, 0x080c, 0x4bfb, 0x0904, 0x36a8,
+ 0x080c, 0x6bcd, 0x1904, 0x36a5, 0x00c6, 0x080c, 0x4bc8, 0x00ce,
+ 0x0904, 0x36a5, 0xa867, 0x0000, 0xa868, 0xc0fd, 0xa86a, 0x7ea8,
+ 0x080c, 0xcdaa, 0x0904, 0x36a5, 0x7007, 0x0003, 0x701f, 0x481d,
+ 0x0005, 0x080c, 0x435b, 0x0804, 0x3673, 0xa830, 0x9086, 0x0100,
+ 0x0904, 0x36a5, 0x8906, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084,
+ 0xffc0, 0x9080, 0x001b, 0x2009, 0x000c, 0x7a8c, 0x7b88, 0x7c9c,
+ 0x7d98, 0x0804, 0x4c14, 0x9006, 0x080c, 0x270a, 0x78a8, 0x9084,
+ 0x00ff, 0x9086, 0x00ff, 0x0118, 0x81ff, 0x1904, 0x36a5, 0x080c,
+ 0x769d, 0x0110, 0x080c, 0x613d, 0x7888, 0x908a, 0x1000, 0x1a04,
+ 0x36a8, 0x7984, 0x9186, 0x00ff, 0x0138, 0x9182, 0x007f, 0x1a04,
+ 0x36a8, 0x2100, 0x080c, 0x26d4, 0x0026, 0x00c6, 0x0126, 0x2091,
+ 0x8000, 0x2061, 0x1a05, 0x601b, 0x0000, 0x601f, 0x0000, 0x607b,
+ 0x0000, 0x607f, 0x0000, 0x080c, 0x769d, 0x1158, 0x080c, 0x799f,
+ 0x080c, 0x6178, 0x9085, 0x0001, 0x080c, 0x76e1, 0x080c, 0x75cc,
+ 0x00f0, 0x080c, 0xaaf7, 0x080c, 0xae87, 0x080c, 0xab13, 0x2061,
+ 0x0100, 0x2001, 0x1818, 0x2004, 0x9084, 0x00ff, 0x810f, 0x9105,
+ 0x604a, 0x6043, 0x0090, 0x6043, 0x0010, 0x2009, 0x199a, 0x200b,
+ 0x0000, 0x2009, 0x002d, 0x2011, 0x6063, 0x080c, 0x88f6, 0x7984,
+ 0x080c, 0x769d, 0x1110, 0x2009, 0x00ff, 0x7a88, 0x080c, 0x46c4,
+ 0x012e, 0x00ce, 0x002e, 0x0804, 0x3673, 0x7984, 0x080c, 0x6718,
+ 0x2b08, 0x1904, 0x36a8, 0x0804, 0x3673, 0x81ff, 0x0120, 0x2009,
+ 0x0001, 0x0804, 0x36a5, 0x60dc, 0xd0ac, 0x1130, 0xd09c, 0x1120,
+ 0x2009, 0x0005, 0x0804, 0x36a5, 0x080c, 0x4bc8, 0x1120, 0x2009,
+ 0x0002, 0x0804, 0x36a5, 0x7984, 0x81ff, 0x0904, 0x36a8, 0x9192,
+ 0x0021, 0x1a04, 0x36a8, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0xa85c,
+ 0x9080, 0x0019, 0x702a, 0xaf60, 0x7736, 0x080c, 0x4c11, 0x701f,
+ 0x48d8, 0x7880, 0x9086, 0x006e, 0x0110, 0x701f, 0x52ba, 0x0005,
+ 0x2009, 0x0080, 0x080c, 0x6783, 0x1118, 0x080c, 0x6bcd, 0x0120,
+ 0x2021, 0x400a, 0x0804, 0x3675, 0x00d6, 0x0096, 0xa964, 0xaa6c,
+ 0xab70, 0xac74, 0xad78, 0xae7c, 0xa884, 0x90be, 0x0100, 0x0904,
+ 0x4971, 0x90be, 0x0112, 0x0904, 0x4971, 0x90be, 0x0113, 0x0904,
+ 0x4971, 0x90be, 0x0114, 0x0904, 0x4971, 0x90be, 0x0117, 0x0904,
+ 0x4971, 0x90be, 0x011a, 0x0904, 0x4971, 0x90be, 0x011c, 0x0904,
+ 0x4971, 0x90be, 0x0121, 0x0904, 0x4958, 0x90be, 0x0131, 0x0904,
+ 0x4958, 0x90be, 0x0171, 0x0904, 0x4971, 0x90be, 0x0173, 0x0904,
+ 0x4971, 0x90be, 0x01a1, 0x1128, 0xa894, 0x8007, 0xa896, 0x0804,
+ 0x497c, 0x90be, 0x0212, 0x0904, 0x4965, 0x90be, 0x0213, 0x05e8,
+ 0x90be, 0x0214, 0x0500, 0x90be, 0x0217, 0x0188, 0x90be, 0x021a,
+ 0x1120, 0xa89c, 0x8007, 0xa89e, 0x04e0, 0x90be, 0x021f, 0x05c8,
+ 0x90be, 0x0300, 0x05b0, 0x009e, 0x00de, 0x0804, 0x36a8, 0x7028,
+ 0x9080, 0x0010, 0x2098, 0x20a0, 0x7034, 0x20e0, 0x20e8, 0x20a9,
+ 0x0007, 0x080c, 0x49ba, 0x7028, 0x9080, 0x000e, 0x2098, 0x20a0,
+ 0x7034, 0x20e0, 0x20e8, 0x20a9, 0x0001, 0x080c, 0x49ba, 0x00c8,
+ 0x7028, 0x9080, 0x000c, 0x2098, 0x20a0, 0x7034, 0x20e0, 0x20e8,
+ 0x20a9, 0x0001, 0x080c, 0x49c7, 0x00b8, 0x7028, 0x9080, 0x000e,
+ 0x2098, 0x20a0, 0x7034, 0x20e0, 0x20e8, 0x20a9, 0x0001, 0x080c,
+ 0x49c7, 0x7028, 0x9080, 0x000c, 0x2098, 0x20a0, 0x7034, 0x20e0,
+ 0x20e8, 0x20a9, 0x0001, 0x04f1, 0x00c6, 0x080c, 0x4bc8, 0x0550,
+ 0xa868, 0xc0fd, 0xa86a, 0xa867, 0x0119, 0x9006, 0xa882, 0xa87f,
+ 0x0020, 0xa88b, 0x0001, 0x810b, 0xa9ae, 0xa8b2, 0xaab6, 0xabba,
+ 0xacbe, 0xadc2, 0xa9c6, 0xa8ca, 0x00ce, 0x009e, 0x00de, 0xa866,
+ 0xa822, 0xa868, 0xc0fd, 0xa86a, 0xa804, 0x2048, 0x080c, 0xcdc5,
+ 0x1120, 0x2009, 0x0003, 0x0804, 0x36a5, 0x7007, 0x0003, 0x701f,
+ 0x49b1, 0x0005, 0x00ce, 0x009e, 0x00de, 0x2009, 0x0002, 0x0804,
+ 0x36a5, 0xa820, 0x9086, 0x8001, 0x1904, 0x3673, 0x2009, 0x0004,
+ 0x0804, 0x36a5, 0x0016, 0x0026, 0x3510, 0x20a9, 0x0002, 0x4002,
+ 0x4104, 0x4004, 0x8211, 0x1dc8, 0x002e, 0x001e, 0x0005, 0x0016,
+ 0x0026, 0x0036, 0x0046, 0x3520, 0x20a9, 0x0004, 0x4002, 0x4304,
+ 0x4204, 0x4104, 0x4004, 0x8421, 0x1db8, 0x004e, 0x003e, 0x002e,
+ 0x001e, 0x0005, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x36a5,
+ 0x60dc, 0xd0ac, 0x1130, 0xd09c, 0x1120, 0x2009, 0x0005, 0x0804,
+ 0x36a5, 0x7984, 0x78a8, 0x2040, 0x080c, 0xae80, 0x1120, 0x9182,
+ 0x007f, 0x0a04, 0x36a8, 0x9186, 0x00ff, 0x0904, 0x36a8, 0x9182,
+ 0x0800, 0x1a04, 0x36a8, 0x7a8c, 0x7b88, 0x607c, 0x9306, 0x1158,
+ 0x6080, 0x924e, 0x0904, 0x36a8, 0x080c, 0xae80, 0x1120, 0x99cc,
+ 0xff00, 0x0904, 0x36a8, 0x0126, 0x2091, 0x8000, 0x080c, 0x4adb,
+ 0x0904, 0x4a5b, 0x0086, 0x90c6, 0x4000, 0x008e, 0x1538, 0x00c6,
+ 0x0006, 0x0036, 0xb818, 0xbb1c, 0x9305, 0xbb20, 0x9305, 0xbb24,
+ 0x9305, 0xbb28, 0x9305, 0xbb2c, 0x9305, 0xbb30, 0x9305, 0xbb34,
+ 0x9305, 0x003e, 0x0570, 0xd88c, 0x1128, 0x080c, 0x6bcd, 0x0110,
+ 0xc89d, 0x0438, 0x900e, 0x080c, 0x6a74, 0x1108, 0xc185, 0xb800,
+ 0xd0bc, 0x0108, 0xc18d, 0x000e, 0x00ce, 0x00b8, 0x90c6, 0x4007,
+ 0x1110, 0x2408, 0x0090, 0x90c6, 0x4008, 0x1118, 0x2708, 0x2610,
+ 0x0060, 0x90c6, 0x4009, 0x1108, 0x0040, 0x90c6, 0x4006, 0x1108,
+ 0x0020, 0x2001, 0x4005, 0x2009, 0x000a, 0x2020, 0x012e, 0x0804,
+ 0x3675, 0x000e, 0x00ce, 0x2b00, 0x7026, 0x0016, 0x00b6, 0x00c6,
+ 0x00e6, 0x2c70, 0x080c, 0xafbf, 0x0904, 0x4ab0, 0x2b00, 0x6012,
+ 0x080c, 0xd0ce, 0x2e58, 0x00ee, 0x00e6, 0x00c6, 0x080c, 0x4bc8,
+ 0x00ce, 0x2b70, 0x1158, 0x080c, 0xaf4e, 0x00ee, 0x00ce, 0x00be,
+ 0x001e, 0x012e, 0x2009, 0x0002, 0x0804, 0x36a5, 0x900e, 0xa966,
+ 0xa96a, 0x2900, 0x6016, 0xa932, 0xa868, 0xc0fd, 0xd88c, 0x0108,
+ 0xc0f5, 0xa86a, 0xd89c, 0x1110, 0x080c, 0x32fb, 0x6023, 0x0001,
+ 0x9006, 0x080c, 0x66b5, 0xd89c, 0x0138, 0x2001, 0x0004, 0x080c,
+ 0x66c9, 0x2009, 0x0003, 0x0030, 0x2001, 0x0002, 0x080c, 0x66c9,
+ 0x2009, 0x0002, 0x080c, 0xafec, 0x78a8, 0xd094, 0x0138, 0x00ee,
+ 0x7024, 0x00e6, 0x2058, 0xb8d4, 0xc08d, 0xb8d6, 0x9085, 0x0001,
+ 0x00ee, 0x00ce, 0x00be, 0x001e, 0x012e, 0x1120, 0x2009, 0x0003,
+ 0x0804, 0x36a5, 0x7007, 0x0003, 0x701f, 0x4abf, 0x0005, 0xa830,
+ 0x9086, 0x0100, 0x7024, 0x2058, 0x1138, 0x2009, 0x0004, 0xba04,
+ 0x9294, 0x00ff, 0x0804, 0x576e, 0x900e, 0xa868, 0xd0f4, 0x1904,
+ 0x3673, 0x080c, 0x6a74, 0x1108, 0xc185, 0xb800, 0xd0bc, 0x0108,
+ 0xc18d, 0x0804, 0x3673, 0x00e6, 0x00d6, 0x0096, 0x83ff, 0x0904,
+ 0x4b2a, 0x902e, 0x080c, 0xae80, 0x0130, 0x9026, 0x20a9, 0x0800,
+ 0x2071, 0x1000, 0x0030, 0x2021, 0x007f, 0x20a9, 0x0781, 0x2071,
+ 0x107f, 0x2e04, 0x9005, 0x11b8, 0x2100, 0x9406, 0x1904, 0x4b3b,
+ 0x2428, 0x94ce, 0x007f, 0x1120, 0x92ce, 0xfffd, 0x1558, 0x0030,
+ 0x94ce, 0x0080, 0x1130, 0x92ce, 0xfffc, 0x1520, 0x93ce, 0x00ff,
+ 0x1508, 0xc5fd, 0x0480, 0x2058, 0xbf10, 0x2700, 0x9306, 0x11e8,
+ 0xbe14, 0x2600, 0x9206, 0x11c8, 0x2400, 0x9106, 0x1180, 0xd884,
+ 0x0598, 0xd894, 0x1588, 0x080c, 0x6b6d, 0x1570, 0x2001, 0x4000,
+ 0x0460, 0x080c, 0x6bcd, 0x1540, 0x2001, 0x4000, 0x0430, 0x2001,
+ 0x4007, 0x0418, 0x2001, 0x4006, 0x0400, 0x2400, 0x9106, 0x1158,
+ 0xbe14, 0x87ff, 0x1128, 0x86ff, 0x0918, 0x080c, 0xae80, 0x1900,
+ 0x2001, 0x4008, 0x0090, 0x8420, 0x8e70, 0x1f04, 0x4af1, 0x85ff,
+ 0x1130, 0x2001, 0x4009, 0x0048, 0x2001, 0x0001, 0x0030, 0x080c,
+ 0x6718, 0x1dd0, 0xbb12, 0xba16, 0x9006, 0x9005, 0x009e, 0x00de,
+ 0x00ee, 0x0005, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x36a5,
+ 0x080c, 0x4bc8, 0x1120, 0x2009, 0x0002, 0x0804, 0x36a5, 0xa867,
+ 0x0000, 0xa868, 0xc0fd, 0xa86a, 0x7884, 0x9005, 0x0904, 0x36a8,
+ 0x9096, 0x00ff, 0x0120, 0x9092, 0x0004, 0x1a04, 0x36a8, 0x2010,
+ 0x2918, 0x080c, 0x329b, 0x1120, 0x2009, 0x0003, 0x0804, 0x36a5,
+ 0x7007, 0x0003, 0x701f, 0x4b7d, 0x0005, 0xa830, 0x9086, 0x0100,
+ 0x1904, 0x3673, 0x2009, 0x0004, 0x0804, 0x36a5, 0x7984, 0x080c,
+ 0xae80, 0x1120, 0x9182, 0x007f, 0x0a04, 0x36a8, 0x9186, 0x00ff,
+ 0x0904, 0x36a8, 0x9182, 0x0800, 0x1a04, 0x36a8, 0x2001, 0x9400,
+ 0x080c, 0x57c9, 0x1904, 0x36a5, 0x0804, 0x3673, 0xa998, 0x080c,
+ 0xae80, 0x1118, 0x9182, 0x007f, 0x0280, 0x9186, 0x00ff, 0x0168,
+ 0x9182, 0x0800, 0x1250, 0x2001, 0x9400, 0x080c, 0x57c9, 0x11a8,
+ 0x0060, 0xa897, 0x4005, 0xa99a, 0x0010, 0xa897, 0x4006, 0x900e,
+ 0x9085, 0x0001, 0x2001, 0x0030, 0x0005, 0xa897, 0x4000, 0x900e,
+ 0x9085, 0x0001, 0x2001, 0x0000, 0x0005, 0x2009, 0x000a, 0x0c48,
+ 0x080c, 0x104d, 0x0198, 0x9006, 0xa802, 0x7014, 0x9005, 0x1120,
+ 0x2900, 0x7016, 0x701a, 0x0040, 0x7018, 0xa802, 0x0086, 0x2040,
+ 0x2900, 0xa006, 0x701a, 0x008e, 0x9085, 0x0001, 0x0005, 0x7984,
+ 0x080c, 0x6783, 0x1130, 0x7e88, 0x9684, 0x3fff, 0x9082, 0x4000,
+ 0x0208, 0x905e, 0x8bff, 0x0005, 0xa998, 0x080c, 0x6783, 0x1130,
+ 0xae9c, 0x9684, 0x3fff, 0x9082, 0x4000, 0x0208, 0x905e, 0x8bff,
+ 0x0005, 0xae98, 0x0008, 0x7e84, 0x2608, 0x080c, 0x6783, 0x1108,
+ 0x0008, 0x905e, 0x8bff, 0x0005, 0x0016, 0x7114, 0x81ff, 0x0128,
+ 0x2148, 0xa904, 0x080c, 0x107f, 0x0cc8, 0x7116, 0x711a, 0x001e,
+ 0x0005, 0x2031, 0x0001, 0x0010, 0x2031, 0x0000, 0x2061, 0x18b8,
+ 0x2c44, 0xa66a, 0xa17a, 0xa772, 0xa076, 0xa28e, 0xa392, 0xa496,
+ 0xa59a, 0x080c, 0x1142, 0x7007, 0x0002, 0x701f, 0x3673, 0x0005,
+ 0x00f6, 0x0126, 0x2091, 0x8000, 0x2079, 0x0000, 0x2001, 0x18b0,
+ 0x2004, 0x9005, 0x1190, 0x0e04, 0x4c45, 0x7a36, 0x7833, 0x0012,
+ 0x7a82, 0x7b86, 0x7c8a, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004,
+ 0xd084, 0x190c, 0x11f4, 0x0804, 0x4cab, 0x0016, 0x0086, 0x0096,
+ 0x00c6, 0x00e6, 0x2071, 0x189e, 0x7044, 0x9005, 0x1540, 0x7148,
+ 0x9182, 0x0010, 0x0288, 0x7038, 0x2060, 0x080c, 0x104d, 0x0904,
+ 0x4ca3, 0xa84b, 0x0000, 0x2900, 0x7046, 0x2001, 0x0002, 0x9080,
+ 0x1ede, 0x2005, 0xa846, 0x0098, 0x7038, 0x90e0, 0x0004, 0x2001,
+ 0x18ba, 0x9c82, 0x18fa, 0x0210, 0x2061, 0x18ba, 0x2c00, 0x703a,
+ 0x7148, 0x81ff, 0x1108, 0x703e, 0x8108, 0x714a, 0x0460, 0x7148,
+ 0x8108, 0x714a, 0x7044, 0x2040, 0xa144, 0x2105, 0x0016, 0x908a,
+ 0x0036, 0x1a0c, 0x0d79, 0x2060, 0x001e, 0x8108, 0x2105, 0x9005,
+ 0xa146, 0x1520, 0x080c, 0x104d, 0x1130, 0x8109, 0xa946, 0x7148,
+ 0x8109, 0x714a, 0x00d8, 0x9006, 0xa806, 0xa84a, 0xa046, 0x2800,
+ 0xa802, 0x2900, 0xa006, 0x7046, 0x2001, 0x0002, 0x9080, 0x1ede,
+ 0x2005, 0xa846, 0x0058, 0x2262, 0x6306, 0x640a, 0x00ee, 0x00ce,
+ 0x009e, 0x008e, 0x001e, 0x012e, 0x00fe, 0x0005, 0x2c00, 0x9082,
+ 0x001b, 0x0002, 0x4ccd, 0x4ccd, 0x4ccf, 0x4ccd, 0x4ccd, 0x4ccd,
+ 0x4cd3, 0x4ccd, 0x4ccd, 0x4ccd, 0x4cd7, 0x4ccd, 0x4ccd, 0x4ccd,
+ 0x4cdb, 0x4ccd, 0x4ccd, 0x4ccd, 0x4cdf, 0x4ccd, 0x4ccd, 0x4ccd,
+ 0x4ce3, 0x4ccd, 0x4ccd, 0x4ccd, 0x4ce8, 0x080c, 0x0d79, 0xa276,
+ 0xa37a, 0xa47e, 0x0898, 0xa286, 0xa38a, 0xa48e, 0x0878, 0xa296,
+ 0xa39a, 0xa49e, 0x0858, 0xa2a6, 0xa3aa, 0xa4ae, 0x0838, 0xa2b6,
+ 0xa3ba, 0xa4be, 0x0818, 0xa2c6, 0xa3ca, 0xa4ce, 0x0804, 0x4ca6,
+ 0xa2d6, 0xa3da, 0xa4de, 0x0804, 0x4ca6, 0x00e6, 0x2071, 0x189e,
+ 0x7048, 0x9005, 0x0904, 0x4d7f, 0x0126, 0x2091, 0x8000, 0x0e04,
+ 0x4d7e, 0x00f6, 0x2079, 0x0000, 0x00c6, 0x0096, 0x0086, 0x0076,
+ 0x9006, 0x2038, 0x7040, 0x2048, 0x9005, 0x0500, 0xa948, 0x2105,
+ 0x0016, 0x908a, 0x0036, 0x1a0c, 0x0d79, 0x2060, 0x001e, 0x8108,
+ 0x2105, 0x9005, 0xa94a, 0x1904, 0x4d81, 0xa804, 0x9005, 0x090c,
+ 0x0d79, 0x7042, 0x2938, 0x2040, 0xa003, 0x0000, 0x2001, 0x0002,
+ 0x9080, 0x1ede, 0x2005, 0xa04a, 0x0804, 0x4d81, 0x703c, 0x2060,
+ 0x2c14, 0x6304, 0x6408, 0x650c, 0x2200, 0x7836, 0x7833, 0x0012,
+ 0x7882, 0x2300, 0x7886, 0x2400, 0x788a, 0x2091, 0x4080, 0x2001,
+ 0x0089, 0x2004, 0xd084, 0x190c, 0x11f4, 0x87ff, 0x0118, 0x2748,
+ 0x080c, 0x107f, 0x7048, 0x8001, 0x704a, 0x9005, 0x1170, 0x7040,
+ 0x2048, 0x9005, 0x0128, 0x080c, 0x107f, 0x9006, 0x7042, 0x7046,
+ 0x703b, 0x18ba, 0x703f, 0x18ba, 0x0420, 0x7040, 0x9005, 0x1508,
+ 0x7238, 0x2c00, 0x9206, 0x0148, 0x9c80, 0x0004, 0x90fa, 0x18fa,
+ 0x0210, 0x2001, 0x18ba, 0x703e, 0x00a0, 0x9006, 0x703e, 0x703a,
+ 0x7044, 0x9005, 0x090c, 0x0d79, 0x2048, 0xa800, 0x9005, 0x1de0,
+ 0x2900, 0x7042, 0x2001, 0x0002, 0x9080, 0x1ede, 0x2005, 0xa84a,
+ 0x0000, 0x007e, 0x008e, 0x009e, 0x00ce, 0x00fe, 0x012e, 0x00ee,
+ 0x0005, 0x2c00, 0x9082, 0x001b, 0x0002, 0x4da0, 0x4da0, 0x4da2,
+ 0x4da0, 0x4da0, 0x4da0, 0x4da7, 0x4da0, 0x4da0, 0x4da0, 0x4dac,
+ 0x4da0, 0x4da0, 0x4da0, 0x4db1, 0x4da0, 0x4da0, 0x4da0, 0x4db6,
+ 0x4da0, 0x4da0, 0x4da0, 0x4dbb, 0x4da0, 0x4da0, 0x4da0, 0x4dc0,
+ 0x080c, 0x0d79, 0xaa74, 0xab78, 0xac7c, 0x0804, 0x4d2c, 0xaa84,
+ 0xab88, 0xac8c, 0x0804, 0x4d2c, 0xaa94, 0xab98, 0xac9c, 0x0804,
+ 0x4d2c, 0xaaa4, 0xaba8, 0xacac, 0x0804, 0x4d2c, 0xaab4, 0xabb8,
+ 0xacbc, 0x0804, 0x4d2c, 0xaac4, 0xabc8, 0xaccc, 0x0804, 0x4d2c,
+ 0xaad4, 0xabd8, 0xacdc, 0x0804, 0x4d2c, 0x0016, 0x0026, 0x0036,
+ 0x00b6, 0x00c6, 0x2009, 0x007e, 0x080c, 0x6783, 0x2019, 0x0001,
+ 0xb85c, 0xd0ac, 0x0110, 0x2019, 0x0000, 0x2011, 0x801b, 0x080c,
+ 0x4c28, 0x00ce, 0x00be, 0x003e, 0x002e, 0x001e, 0x0005, 0x0026,
+ 0x080c, 0x5820, 0xd0c4, 0x0120, 0x2011, 0x8014, 0x080c, 0x4c28,
+ 0x002e, 0x0005, 0x81ff, 0x1904, 0x36a5, 0x0126, 0x2091, 0x8000,
+ 0x6030, 0xc08d, 0xc085, 0xc0ac, 0x6032, 0x080c, 0x769d, 0x1158,
+ 0x080c, 0x799f, 0x080c, 0x6178, 0x9085, 0x0001, 0x080c, 0x76e1,
+ 0x080c, 0x75cc, 0x0010, 0x080c, 0x6033, 0x012e, 0x0804, 0x3673,
+ 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x36a5, 0x080c, 0x5834,
+ 0x0120, 0x2009, 0x0007, 0x0804, 0x36a5, 0x080c, 0x6bc5, 0x0120,
+ 0x2009, 0x0008, 0x0804, 0x36a5, 0x7984, 0x080c, 0x6718, 0x1904,
+ 0x36a8, 0x080c, 0x4bfb, 0x0904, 0x36a8, 0x2b00, 0x7026, 0x080c,
+ 0x6bcd, 0x7888, 0x1170, 0x9084, 0x0005, 0x1158, 0x900e, 0x080c,
+ 0x6a74, 0x1108, 0xc185, 0xb800, 0xd0bc, 0x0108, 0xc18d, 0x0804,
+ 0x3673, 0x080c, 0x4bc8, 0x0904, 0x36a5, 0x9006, 0xa866, 0xa832,
+ 0xa868, 0xc0fd, 0xa86a, 0x080c, 0xce6c, 0x0904, 0x36a5, 0x7888,
+ 0xd094, 0x0118, 0xb8d4, 0xc08d, 0xb8d6, 0x7007, 0x0003, 0x701f,
+ 0x4e9b, 0x0005, 0x2061, 0x1800, 0x080c, 0x5834, 0x2009, 0x0007,
+ 0x1560, 0x080c, 0x6bc5, 0x0118, 0x2009, 0x0008, 0x0430, 0xa998,
+ 0x080c, 0x6718, 0x1530, 0x080c, 0x4bf9, 0x0518, 0x080c, 0x6bcd,
+ 0xa89c, 0x1168, 0x9084, 0x0005, 0x1150, 0x900e, 0x080c, 0x6a74,
+ 0x1108, 0xc185, 0xb800, 0xd0bc, 0x0108, 0xc18d, 0x00d0, 0xa868,
+ 0xc0fc, 0xa86a, 0x080c, 0xce6c, 0x11e0, 0xa89c, 0xd094, 0x0118,
+ 0xb8d4, 0xc08d, 0xb8d6, 0x2009, 0x0003, 0xa897, 0x4005, 0xa99a,
+ 0x0010, 0xa897, 0x4006, 0x900e, 0x9085, 0x0001, 0x2001, 0x0030,
+ 0x0005, 0xa897, 0x4000, 0xa99a, 0x9006, 0x918d, 0x0001, 0x2008,
+ 0x0005, 0x9006, 0x0005, 0xa830, 0x9086, 0x0100, 0x7024, 0x2058,
+ 0x1110, 0x0804, 0x576e, 0x900e, 0x080c, 0x6a74, 0x1108, 0xc185,
+ 0xb800, 0xd0bc, 0x0108, 0xc18d, 0x0804, 0x3673, 0x080c, 0x5834,
+ 0x0120, 0x2009, 0x0007, 0x0804, 0x36a5, 0x7f84, 0x7a8c, 0x7b88,
+ 0x7c9c, 0x7d98, 0x080c, 0x4bc8, 0x1120, 0x2009, 0x0002, 0x0804,
+ 0x36a5, 0x900e, 0x2130, 0x7126, 0x7132, 0xa860, 0x20e8, 0x7036,
+ 0xa85c, 0x9080, 0x0005, 0x702a, 0x20a0, 0x080c, 0x6783, 0x1904,
+ 0x4f44, 0x080c, 0x6bcd, 0x0138, 0x080c, 0x6bd5, 0x0120, 0x080c,
+ 0x6b6d, 0x1904, 0x4f44, 0xd794, 0x1110, 0xd784, 0x01a8, 0xb8c4,
+ 0x20e0, 0xb8c8, 0x9080, 0x0006, 0x2098, 0x3400, 0xd794, 0x0198,
+ 0x20a9, 0x0008, 0x4003, 0x2098, 0x20a0, 0x3d00, 0x20e0, 0x20a9,
+ 0x0002, 0x080c, 0x49c7, 0x0080, 0xb8c4, 0x20e0, 0xb8c8, 0x9080,
+ 0x000a, 0x2098, 0x3400, 0x20a9, 0x0004, 0x4003, 0x2098, 0x20a0,
+ 0x3d00, 0x20e0, 0x080c, 0x49c7, 0x9186, 0x007e, 0x0170, 0x9186,
+ 0x0080, 0x0158, 0x080c, 0x6bcd, 0x90c2, 0x0006, 0x1210, 0xc1fd,
+ 0x0020, 0x080c, 0x6a74, 0x1108, 0xc1fd, 0x4104, 0xc1fc, 0xd794,
+ 0x0528, 0xb8c4, 0x20e0, 0xb8c8, 0x2060, 0x9c80, 0x0000, 0x2098,
+ 0x20a9, 0x0002, 0x4003, 0x9c80, 0x0003, 0x2098, 0x20a9, 0x0001,
+ 0x4005, 0x9c80, 0x0004, 0x2098, 0x3400, 0x20a9, 0x0002, 0x4003,
+ 0x2098, 0x20a0, 0x3d00, 0x20e0, 0x080c, 0x49ba, 0x9c80, 0x0026,
+ 0x2098, 0xb8c4, 0x20e0, 0x20a9, 0x0002, 0x4003, 0xd794, 0x0110,
+ 0x96b0, 0x000b, 0x96b0, 0x0005, 0x8108, 0x080c, 0xae80, 0x0118,
+ 0x9186, 0x0800, 0x0040, 0xd78c, 0x0120, 0x9186, 0x0800, 0x0170,
+ 0x0018, 0x9186, 0x007e, 0x0150, 0xd794, 0x0118, 0x9686, 0x0020,
+ 0x0010, 0x9686, 0x0028, 0x0150, 0x0804, 0x4ecd, 0x86ff, 0x1120,
+ 0x7124, 0x810b, 0x0804, 0x3673, 0x7033, 0x0001, 0x7122, 0x7024,
+ 0x9600, 0x7026, 0x772e, 0x2061, 0x18b8, 0x2c44, 0xa06b, 0x0000,
+ 0xa67a, 0x7034, 0xa072, 0x7028, 0xa076, 0xa28e, 0xa392, 0xa496,
+ 0xa59a, 0x080c, 0x1142, 0x7007, 0x0002, 0x701f, 0x4f80, 0x0005,
+ 0x7030, 0x9005, 0x1180, 0x7120, 0x7028, 0x20a0, 0x772c, 0x9036,
+ 0x7034, 0x20e8, 0x2061, 0x18b8, 0x2c44, 0xa28c, 0xa390, 0xa494,
+ 0xa598, 0x0804, 0x4ecd, 0x7124, 0x810b, 0x0804, 0x3673, 0x2029,
+ 0x007e, 0x7984, 0x7a88, 0x7b8c, 0x7c98, 0x9184, 0xff00, 0x8007,
+ 0x90e2, 0x0020, 0x0a04, 0x36a8, 0x9502, 0x0a04, 0x36a8, 0x9184,
+ 0x00ff, 0x90e2, 0x0020, 0x0a04, 0x36a8, 0x9502, 0x0a04, 0x36a8,
+ 0x9284, 0xff00, 0x8007, 0x90e2, 0x0020, 0x0a04, 0x36a8, 0x9502,
+ 0x0a04, 0x36a8, 0x9284, 0x00ff, 0x90e2, 0x0020, 0x0a04, 0x36a8,
+ 0x9502, 0x0a04, 0x36a8, 0x9384, 0xff00, 0x8007, 0x90e2, 0x0020,
+ 0x0a04, 0x36a8, 0x9502, 0x0a04, 0x36a8, 0x9384, 0x00ff, 0x90e2,
+ 0x0020, 0x0a04, 0x36a8, 0x9502, 0x0a04, 0x36a8, 0x9484, 0xff00,
+ 0x8007, 0x90e2, 0x0020, 0x0a04, 0x36a8, 0x9502, 0x0a04, 0x36a8,
+ 0x9484, 0x00ff, 0x90e2, 0x0020, 0x0a04, 0x36a8, 0x9502, 0x0a04,
+ 0x36a8, 0x2061, 0x198a, 0x6102, 0x6206, 0x630a, 0x640e, 0x0804,
+ 0x3673, 0x080c, 0x4bc8, 0x0904, 0x36a5, 0x2009, 0x0016, 0x7a8c,
+ 0x7b88, 0x7c9c, 0x7d98, 0xa85c, 0x9080, 0x0019, 0xaf60, 0x080c,
+ 0x4c11, 0x701f, 0x5004, 0x0005, 0x2001, 0x0138, 0x2003, 0x0000,
+ 0x00e6, 0x2071, 0x0300, 0x701c, 0xd0a4, 0x1de8, 0x00ee, 0x20a9,
+ 0x0016, 0x896e, 0x8d6e, 0x8d6f, 0x9d84, 0xffc0, 0x9080, 0x0019,
+ 0x2098, 0x9d84, 0x003f, 0x20e0, 0x2069, 0x1877, 0x20e9, 0x0001,
+ 0x2da0, 0x4003, 0x6800, 0x9005, 0x0904, 0x5085, 0x6804, 0x2008,
+ 0x918c, 0xfff8, 0x1904, 0x5085, 0x680c, 0x9005, 0x0904, 0x5085,
+ 0x9082, 0xff01, 0x1a04, 0x5085, 0x6810, 0x9082, 0x005c, 0x0a04,
+ 0x5085, 0x6824, 0x2008, 0x9082, 0x0008, 0x0a04, 0x5085, 0x9182,
+ 0x0400, 0x1a04, 0x5085, 0x0056, 0x2029, 0x0000, 0x080c, 0x8f0d,
+ 0x005e, 0x6944, 0x6820, 0x9102, 0x06c0, 0x6820, 0x9082, 0x0019,
+ 0x16a0, 0x6828, 0x6944, 0x810c, 0x9102, 0x0678, 0x6840, 0x9082,
+ 0x000f, 0x1658, 0x080c, 0x1066, 0x2900, 0x0904, 0x50a1, 0x684e,
+ 0x00e6, 0x2071, 0x1932, 0x00b6, 0x2059, 0x0000, 0x080c, 0x8dc9,
+ 0x00be, 0x00ee, 0x0568, 0x080c, 0x8b11, 0x080c, 0x8b60, 0x11e0,
+ 0x6857, 0x0000, 0x00c6, 0x2061, 0x0100, 0x6104, 0x918d, 0x2000,
+ 0x6106, 0x6b10, 0x2061, 0x1a6f, 0x630e, 0x00ce, 0x080c, 0x27b9,
+ 0x2001, 0x0138, 0x2102, 0x0804, 0x3673, 0x080c, 0x27b9, 0x2001,
+ 0x0138, 0x2102, 0x0804, 0x36a8, 0x080c, 0x8b59, 0x00e6, 0x2071,
+ 0x1932, 0x080c, 0x8f8d, 0x080c, 0x8f9c, 0x080c, 0x8dac, 0x00ee,
+ 0x2001, 0x188a, 0x204c, 0x080c, 0x107f, 0x2001, 0x188a, 0x2003,
+ 0x0000, 0x080c, 0x27b9, 0x2001, 0x0138, 0x2102, 0x0804, 0x36a5,
+ 0x2001, 0x1926, 0x200c, 0x918e, 0x0000, 0x0904, 0x5106, 0x080c,
+ 0x8da7, 0x0904, 0x5106, 0x2001, 0x0101, 0x200c, 0x918c, 0xdfff,
+ 0x2102, 0x2001, 0x0138, 0x2003, 0x0000, 0x00e6, 0x2071, 0x0300,
+ 0x701c, 0xd0a4, 0x1de8, 0x00ee, 0x080c, 0x8dac, 0x0126, 0x2091,
+ 0x8000, 0x2001, 0x0035, 0x080c, 0x16ad, 0x012e, 0x00c6, 0x2061,
+ 0x193e, 0x6004, 0x6100, 0x9106, 0x1de0, 0x00ce, 0x080c, 0x27b9,
+ 0x2001, 0x0138, 0x2102, 0x00e6, 0x00f6, 0x2071, 0x1925, 0x080c,
+ 0x8ce6, 0x0120, 0x2f00, 0x080c, 0x8d72, 0x0cc8, 0x00fe, 0x00ee,
+ 0x0126, 0x2091, 0x8000, 0x2001, 0x188a, 0x200c, 0x81ff, 0x0138,
+ 0x2148, 0x080c, 0x107f, 0x2001, 0x188a, 0x2003, 0x0000, 0x2001,
+ 0x183e, 0x2003, 0x0020, 0x080c, 0x8b59, 0x00e6, 0x2071, 0x1932,
+ 0x080c, 0x8f8d, 0x080c, 0x8f9c, 0x00ee, 0x012e, 0x0804, 0x3673,
+ 0x0006, 0x080c, 0x5820, 0xd0cc, 0x000e, 0x0005, 0x0006, 0x080c,
+ 0x5824, 0xd0bc, 0x000e, 0x0005, 0x6174, 0x7a84, 0x6300, 0x82ff,
+ 0x1118, 0x7986, 0x0804, 0x3673, 0x83ff, 0x1904, 0x36a8, 0x2001,
+ 0xfff0, 0x9200, 0x1a04, 0x36a8, 0x2019, 0xffff, 0x6078, 0x9302,
+ 0x9200, 0x0a04, 0x36a8, 0x7986, 0x6276, 0x0804, 0x3673, 0x080c,
+ 0x5834, 0x1904, 0x36a5, 0x7c88, 0x7d84, 0x7e98, 0x7f8c, 0x080c,
+ 0x4bc8, 0x0904, 0x36a5, 0x900e, 0x901e, 0x7326, 0x7332, 0xa860,
+ 0x20e8, 0x7036, 0xa85c, 0x9080, 0x0003, 0x702a, 0x20a0, 0x91d8,
+ 0x1000, 0x2b5c, 0x8bff, 0x0178, 0x080c, 0x6bcd, 0x0118, 0x080c,
+ 0x6bd5, 0x1148, 0x20a9, 0x0001, 0xb814, 0x4004, 0xb810, 0x4004,
+ 0x4104, 0x9398, 0x0003, 0x8108, 0x9182, 0x0800, 0x0120, 0x9386,
+ 0x003c, 0x0170, 0x0c20, 0x83ff, 0x1148, 0x7224, 0x900e, 0x2001,
+ 0x0003, 0x080c, 0x9364, 0x2208, 0x0804, 0x3673, 0x7033, 0x0001,
+ 0x7122, 0x7024, 0x9300, 0x7026, 0x2061, 0x18b8, 0x2c44, 0xa06b,
+ 0x0000, 0xa37a, 0x7028, 0xa076, 0x7034, 0xa072, 0xa48e, 0xa592,
+ 0xa696, 0xa79a, 0x080c, 0x1142, 0x7007, 0x0002, 0x701f, 0x5189,
+ 0x0005, 0x7030, 0x9005, 0x1178, 0x7120, 0x7028, 0x20a0, 0x901e,
+ 0x7034, 0x20e8, 0x2061, 0x18b8, 0x2c44, 0xa48c, 0xa590, 0xa694,
+ 0xa798, 0x0804, 0x5147, 0x7224, 0x900e, 0x2001, 0x0003, 0x080c,
+ 0x9364, 0x2208, 0x0804, 0x3673, 0x00f6, 0x00e6, 0x080c, 0x5834,
+ 0x2009, 0x0007, 0x1904, 0x521c, 0x2071, 0x189e, 0x745c, 0x84ff,
+ 0x2009, 0x000e, 0x1904, 0x521c, 0xac9c, 0xad98, 0xaea4, 0xafa0,
+ 0x0096, 0x080c, 0x1066, 0x2009, 0x0002, 0x0904, 0x521c, 0x2900,
+ 0x705e, 0x900e, 0x901e, 0x7356, 0x7362, 0xa860, 0x7066, 0xa85c,
+ 0x9080, 0x0003, 0x705a, 0x20a0, 0x91d8, 0x1000, 0x2b5c, 0x8bff,
+ 0x0178, 0x080c, 0x6bcd, 0x0118, 0x080c, 0x6bd5, 0x1148, 0xb814,
0x20a9, 0x0001, 0x4004, 0xb810, 0x4004, 0x4104, 0x9398, 0x0003,
- 0x8108, 0x9182, 0x0800, 0x0120, 0x9386, 0x003c, 0x0518, 0x0c20,
- 0x83ff, 0x11f0, 0x7154, 0x810c, 0xa99a, 0xa897, 0x4000, 0x715c,
- 0x81ff, 0x090c, 0x0d85, 0x2148, 0x080c, 0x108b, 0x9006, 0x705e,
- 0x918d, 0x0001, 0x2008, 0xa0a0, 0x2048, 0x0126, 0x2091, 0x8000,
- 0x080c, 0x6f19, 0x012e, 0xa09f, 0x0000, 0xa0a3, 0x0000, 0x0070,
- 0x7063, 0x0001, 0x7152, 0x7054, 0x9300, 0x7056, 0xa37a, 0xa48e,
- 0xa592, 0xa696, 0xa79a, 0x080c, 0x114e, 0x9006, 0x00ee, 0x0005,
- 0x0096, 0xa88c, 0x90be, 0x7000, 0x0148, 0x90be, 0x7100, 0x0130,
- 0x90be, 0x7200, 0x0118, 0x009e, 0x0804, 0x36bd, 0xa884, 0xa988,
- 0x080c, 0x26a2, 0x1518, 0x080c, 0x671e, 0x1500, 0x7126, 0xbe12,
- 0xbd16, 0xae7c, 0x080c, 0x4bce, 0x01c8, 0x080c, 0x4bce, 0x01b0,
- 0x009e, 0xa867, 0x0000, 0xa868, 0xc0fd, 0xa86a, 0xa823, 0x0000,
- 0xa804, 0x2048, 0x080c, 0xcdc8, 0x1120, 0x2009, 0x0003, 0x0804,
- 0x36ba, 0x7007, 0x0003, 0x701f, 0x52fb, 0x0005, 0x009e, 0x2009,
- 0x0002, 0x0804, 0x36ba, 0x7124, 0x080c, 0x3419, 0xa820, 0x9086,
- 0x8001, 0x1120, 0x2009, 0x0004, 0x0804, 0x36ba, 0x2900, 0x7022,
- 0xa804, 0x0096, 0x2048, 0x8906, 0x8006, 0x8007, 0x90bc, 0x003f,
- 0x9084, 0xffc0, 0x009e, 0x9080, 0x0002, 0x0076, 0x0006, 0x2098,
- 0x20a0, 0x27e0, 0x27e8, 0x20a9, 0x002a, 0x080c, 0x0fd6, 0xaa6c,
- 0xab70, 0xac74, 0xad78, 0x2061, 0x18b8, 0x2c44, 0xa06b, 0x0000,
- 0xae64, 0xaf8c, 0x97c6, 0x7000, 0x0118, 0x97c6, 0x7100, 0x1148,
- 0x96c2, 0x0004, 0x0600, 0x2009, 0x0004, 0x000e, 0x007e, 0x0804,
- 0x4c1a, 0x97c6, 0x7200, 0x11b8, 0x96c2, 0x0054, 0x02a0, 0x000e,
- 0x007e, 0x2061, 0x18b8, 0x2c44, 0xa076, 0xa772, 0xa07b, 0x002a,
- 0xa28e, 0xa392, 0xa496, 0xa59a, 0x080c, 0x114e, 0x7007, 0x0002,
- 0x701f, 0x5357, 0x0005, 0x000e, 0x007e, 0x0804, 0x36bd, 0x7020,
- 0x2048, 0xa804, 0x2048, 0xa804, 0x2048, 0x8906, 0x8006, 0x8007,
- 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, 0x0002, 0x2098, 0x20a0,
- 0x27e0, 0x27e8, 0x20a9, 0x002a, 0x080c, 0x0fd6, 0x2100, 0x2238,
- 0x2061, 0x18b8, 0x2c44, 0xa28c, 0xa390, 0xa494, 0xa598, 0x2009,
- 0x002a, 0x0804, 0x4c1a, 0x81ff, 0x1904, 0x36ba, 0x798c, 0x2001,
- 0x197f, 0x918c, 0x8000, 0x2102, 0x080c, 0x4be5, 0x0904, 0x36bd,
- 0x080c, 0x6bd5, 0x0120, 0x080c, 0x6bdd, 0x1904, 0x36bd, 0x080c,
- 0x6850, 0x0904, 0x36ba, 0x0126, 0x2091, 0x8000, 0x080c, 0x69e9,
- 0x012e, 0x0904, 0x36ba, 0x2001, 0x197f, 0x2004, 0xd0fc, 0x1904,
- 0x3688, 0x0804, 0x4667, 0xa9a0, 0x2001, 0x197f, 0x918c, 0x8000,
- 0xc18d, 0x2102, 0x080c, 0x4bf2, 0x01a0, 0x080c, 0x6bd5, 0x0118,
- 0x080c, 0x6bdd, 0x1170, 0x080c, 0x6850, 0x2009, 0x0002, 0x0128,
- 0x080c, 0x69e9, 0x1170, 0x2009, 0x0003, 0xa897, 0x4005, 0xa99a,
+ 0x8108, 0x9182, 0x0800, 0x0120, 0x9386, 0x003c, 0x01e8, 0x0c20,
+ 0x83ff, 0x11c0, 0x7254, 0x900e, 0x2001, 0x0003, 0x080c, 0x9364,
+ 0x2208, 0x009e, 0xa897, 0x4000, 0xa99a, 0x715c, 0x81ff, 0x090c,
+ 0x0d79, 0x2148, 0x080c, 0x107f, 0x9006, 0x705e, 0x918d, 0x0001,
+ 0x2008, 0x0418, 0x7063, 0x0001, 0x7152, 0x7054, 0x9300, 0x7056,
+ 0x2061, 0x18b9, 0x2c44, 0xa37a, 0x7058, 0xa076, 0x7064, 0xa072,
+ 0xa48e, 0xa592, 0xa696, 0xa79a, 0xa09f, 0x5228, 0x000e, 0xa0a2,
+ 0x080c, 0x1142, 0x9006, 0x0048, 0x009e, 0xa897, 0x4005, 0xa99a,
+ 0x900e, 0x9085, 0x0001, 0x2001, 0x0030, 0x00ee, 0x00fe, 0x0005,
+ 0x00f6, 0xa0a0, 0x904d, 0x090c, 0x0d79, 0x00e6, 0x2071, 0x189e,
+ 0xa06c, 0x908e, 0x0100, 0x0138, 0xa87b, 0x0030, 0xa883, 0x0000,
+ 0xa897, 0x4002, 0x00d8, 0x7060, 0x9005, 0x1158, 0x7150, 0x7058,
+ 0x20a0, 0x901e, 0x7064, 0x20e8, 0xa48c, 0xa590, 0xa694, 0xa798,
+ 0x0428, 0xa87b, 0x0000, 0xa883, 0x0000, 0xa897, 0x4000, 0x7254,
+ 0x900e, 0x2001, 0x0003, 0x080c, 0x9364, 0xaa9a, 0x715c, 0x81ff,
+ 0x090c, 0x0d79, 0x2148, 0x080c, 0x107f, 0x705f, 0x0000, 0xa0a0,
+ 0x2048, 0x0126, 0x2091, 0x8000, 0x080c, 0x6f11, 0x012e, 0xa09f,
+ 0x0000, 0xa0a3, 0x0000, 0x00ee, 0x00fe, 0x0005, 0x91d8, 0x1000,
+ 0x2b5c, 0x8bff, 0x0178, 0x080c, 0x6bcd, 0x0118, 0x080c, 0x6bd5,
+ 0x1148, 0xb814, 0x20a9, 0x0001, 0x4004, 0xb810, 0x4004, 0x4104,
+ 0x9398, 0x0003, 0x8108, 0x9182, 0x0800, 0x0120, 0x9386, 0x003c,
+ 0x0518, 0x0c20, 0x83ff, 0x11f0, 0x7154, 0x810c, 0xa99a, 0xa897,
+ 0x4000, 0x715c, 0x81ff, 0x090c, 0x0d79, 0x2148, 0x080c, 0x107f,
+ 0x9006, 0x705e, 0x918d, 0x0001, 0x2008, 0xa0a0, 0x2048, 0x0126,
+ 0x2091, 0x8000, 0x080c, 0x6f11, 0x012e, 0xa09f, 0x0000, 0xa0a3,
+ 0x0000, 0x0070, 0x7063, 0x0001, 0x7152, 0x7054, 0x9300, 0x7056,
+ 0xa37a, 0xa48e, 0xa592, 0xa696, 0xa79a, 0x080c, 0x1142, 0x9006,
+ 0x00ee, 0x0005, 0x0096, 0xa88c, 0x90be, 0x7000, 0x0148, 0x90be,
+ 0x7100, 0x0130, 0x90be, 0x7200, 0x0118, 0x009e, 0x0804, 0x36a8,
+ 0xa884, 0xa988, 0x080c, 0x26a1, 0x1518, 0x080c, 0x6718, 0x1500,
+ 0x7126, 0xbe12, 0xbd16, 0xae7c, 0x080c, 0x4bc8, 0x01c8, 0x080c,
+ 0x4bc8, 0x01b0, 0x009e, 0xa867, 0x0000, 0xa868, 0xc0fd, 0xa86a,
+ 0xa823, 0x0000, 0xa804, 0x2048, 0x080c, 0xcde5, 0x1120, 0x2009,
+ 0x0003, 0x0804, 0x36a5, 0x7007, 0x0003, 0x701f, 0x52f5, 0x0005,
+ 0x009e, 0x2009, 0x0002, 0x0804, 0x36a5, 0x7124, 0x080c, 0x3404,
+ 0xa820, 0x9086, 0x8001, 0x1120, 0x2009, 0x0004, 0x0804, 0x36a5,
+ 0x2900, 0x7022, 0xa804, 0x0096, 0x2048, 0x8906, 0x8006, 0x8007,
+ 0x90bc, 0x003f, 0x9084, 0xffc0, 0x009e, 0x9080, 0x0002, 0x0076,
+ 0x0006, 0x2098, 0x20a0, 0x27e0, 0x27e8, 0x20a9, 0x002a, 0x080c,
+ 0x0fca, 0xaa6c, 0xab70, 0xac74, 0xad78, 0x2061, 0x18b8, 0x2c44,
+ 0xa06b, 0x0000, 0xae64, 0xaf8c, 0x97c6, 0x7000, 0x0118, 0x97c6,
+ 0x7100, 0x1148, 0x96c2, 0x0004, 0x0600, 0x2009, 0x0004, 0x000e,
+ 0x007e, 0x0804, 0x4c14, 0x97c6, 0x7200, 0x11b8, 0x96c2, 0x0054,
+ 0x02a0, 0x000e, 0x007e, 0x2061, 0x18b8, 0x2c44, 0xa076, 0xa772,
+ 0xa07b, 0x002a, 0xa28e, 0xa392, 0xa496, 0xa59a, 0x080c, 0x1142,
+ 0x7007, 0x0002, 0x701f, 0x5351, 0x0005, 0x000e, 0x007e, 0x0804,
+ 0x36a8, 0x7020, 0x2048, 0xa804, 0x2048, 0xa804, 0x2048, 0x8906,
+ 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, 0x0002,
+ 0x2098, 0x20a0, 0x27e0, 0x27e8, 0x20a9, 0x002a, 0x080c, 0x0fca,
+ 0x2100, 0x2238, 0x2061, 0x18b8, 0x2c44, 0xa28c, 0xa390, 0xa494,
+ 0xa598, 0x2009, 0x002a, 0x0804, 0x4c14, 0x81ff, 0x1904, 0x36a5,
+ 0x798c, 0x2001, 0x197f, 0x918c, 0x8000, 0x2102, 0x080c, 0x4bdf,
+ 0x0904, 0x36a8, 0x080c, 0x6bcd, 0x0120, 0x080c, 0x6bd5, 0x1904,
+ 0x36a8, 0x080c, 0x684a, 0x0904, 0x36a5, 0x0126, 0x2091, 0x8000,
+ 0x080c, 0x69e1, 0x012e, 0x0904, 0x36a5, 0x2001, 0x197f, 0x2004,
+ 0xd0fc, 0x1904, 0x3673, 0x0804, 0x4661, 0xa9a0, 0x2001, 0x197f,
+ 0x918c, 0x8000, 0xc18d, 0x2102, 0x080c, 0x4bec, 0x01a0, 0x080c,
+ 0x6bcd, 0x0118, 0x080c, 0x6bd5, 0x1170, 0x080c, 0x684a, 0x2009,
+ 0x0002, 0x0128, 0x080c, 0x69e1, 0x1170, 0x2009, 0x0003, 0xa897,
+ 0x4005, 0xa99a, 0x0010, 0xa897, 0x4006, 0x900e, 0x9085, 0x0001,
+ 0x2001, 0x0030, 0x0005, 0xa897, 0x4000, 0x2001, 0x197f, 0x2004,
+ 0xd0fc, 0x1128, 0x080c, 0x5828, 0x0110, 0x9006, 0x0018, 0x900e,
+ 0x9085, 0x0001, 0x2001, 0x0000, 0x0005, 0x78a8, 0xd08c, 0x1118,
+ 0xd084, 0x0904, 0x45d6, 0x080c, 0x4bfb, 0x0904, 0x36a8, 0x080c,
+ 0x4bc8, 0x1120, 0x2009, 0x0002, 0x0804, 0x36a5, 0x080c, 0x6bcd,
+ 0x0130, 0x908e, 0x0004, 0x0118, 0x908e, 0x0005, 0x15a0, 0x78a8,
+ 0xd08c, 0x0120, 0xb800, 0xc08c, 0xb802, 0x0028, 0x080c, 0x5820,
+ 0xd0b4, 0x0904, 0x4610, 0x7884, 0x908e, 0x007e, 0x0904, 0x4610,
+ 0x908e, 0x007f, 0x0904, 0x4610, 0x908e, 0x0080, 0x0904, 0x4610,
+ 0xb800, 0xd08c, 0x1904, 0x4610, 0xa867, 0x0000, 0xa868, 0xc0fd,
+ 0xa86a, 0x080c, 0xce04, 0x1120, 0x2009, 0x0003, 0x0804, 0x36a5,
+ 0x7007, 0x0003, 0x701f, 0x541d, 0x0005, 0x080c, 0x4bfb, 0x0904,
+ 0x36a8, 0x0804, 0x4610, 0x080c, 0x3463, 0x0108, 0x0005, 0x2009,
+ 0x1834, 0x210c, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x36a5,
+ 0x080c, 0x5834, 0x0120, 0x2009, 0x0007, 0x0804, 0x36a5, 0x080c,
+ 0x6bc5, 0x0120, 0x2009, 0x0008, 0x0804, 0x36a5, 0xb89c, 0xd0a4,
+ 0x1118, 0xd0ac, 0x1904, 0x4610, 0x9006, 0xa866, 0xa832, 0xa868,
+ 0xc0fd, 0xa86a, 0x080c, 0xce6c, 0x1120, 0x2009, 0x0003, 0x0804,
+ 0x36a5, 0x7007, 0x0003, 0x701f, 0x5456, 0x0005, 0xa830, 0x9086,
+ 0x0100, 0x1120, 0x2009, 0x0004, 0x0804, 0x576e, 0x080c, 0x4bfb,
+ 0x0904, 0x36a8, 0x0804, 0x53ef, 0x81ff, 0x2009, 0x0001, 0x1904,
+ 0x36a5, 0x080c, 0x5834, 0x2009, 0x0007, 0x1904, 0x36a5, 0x080c,
+ 0x6bc5, 0x0120, 0x2009, 0x0008, 0x0804, 0x36a5, 0x080c, 0x4bfb,
+ 0x0904, 0x36a8, 0x080c, 0x6bcd, 0x2009, 0x0009, 0x1904, 0x36a5,
+ 0x080c, 0x4bc8, 0x2009, 0x0002, 0x0904, 0x36a5, 0x9006, 0xa866,
+ 0xa832, 0xa868, 0xc0fd, 0xa86a, 0x7988, 0xa95a, 0x9194, 0xfd00,
+ 0x918c, 0x00ff, 0x9006, 0x82ff, 0x1128, 0xc0ed, 0xa952, 0x798c,
+ 0xa956, 0x0038, 0x928e, 0x0100, 0x1904, 0x36a8, 0xc0e5, 0xa952,
+ 0xa956, 0xa83e, 0x080c, 0xd0cf, 0x2009, 0x0003, 0x0904, 0x36a5,
+ 0x7007, 0x0003, 0x701f, 0x54ad, 0x0005, 0xa830, 0x9086, 0x0100,
+ 0x2009, 0x0004, 0x0904, 0x36a5, 0x0804, 0x3673, 0x7aa8, 0x9284,
+ 0xc000, 0x0148, 0xd2ec, 0x01a0, 0x080c, 0x5834, 0x1188, 0x2009,
+ 0x0014, 0x0804, 0x36a5, 0xd2dc, 0x1578, 0x81ff, 0x2009, 0x0001,
+ 0x1904, 0x36a5, 0x080c, 0x5834, 0x2009, 0x0007, 0x1904, 0x36a5,
+ 0xd2f4, 0x0138, 0x9284, 0x5000, 0xc0d5, 0x080c, 0x57fa, 0x0804,
+ 0x3673, 0xd2fc, 0x0160, 0x080c, 0x4bfb, 0x0904, 0x36a8, 0x7984,
+ 0x9284, 0x9000, 0xc0d5, 0x080c, 0x57c9, 0x0804, 0x3673, 0x080c,
+ 0x4bfb, 0x0904, 0x36a8, 0xb804, 0x9084, 0x00ff, 0x9086, 0x0006,
+ 0x2009, 0x0009, 0x1904, 0x559c, 0x080c, 0x4bc8, 0x2009, 0x0002,
+ 0x0904, 0x559c, 0xa85c, 0x9080, 0x001b, 0xaf60, 0x2009, 0x0008,
+ 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0x080c, 0x4c11, 0x701f, 0x5509,
+ 0x0005, 0xa86c, 0x9086, 0x0500, 0x1138, 0xa870, 0x9005, 0x1120,
+ 0xa874, 0x9084, 0xff00, 0x0110, 0x1904, 0x36a8, 0xa866, 0xa832,
+ 0xa868, 0xc0fd, 0xa86a, 0x080c, 0x4bfb, 0x1110, 0x0804, 0x36a8,
+ 0x2009, 0x0043, 0x080c, 0xd13b, 0x2009, 0x0003, 0x0904, 0x559c,
+ 0x7007, 0x0003, 0x701f, 0x552d, 0x0005, 0xa830, 0x9086, 0x0100,
+ 0x2009, 0x0004, 0x0904, 0x559c, 0x7984, 0x7aa8, 0x9284, 0x1000,
+ 0xc0d5, 0x080c, 0x57c9, 0x0804, 0x3673, 0x00c6, 0xaab0, 0x9284,
+ 0xc000, 0x0148, 0xd2ec, 0x0170, 0x080c, 0x5834, 0x1158, 0x2009,
+ 0x0014, 0x0804, 0x558b, 0x2061, 0x1800, 0x080c, 0x5834, 0x2009,
+ 0x0007, 0x15c8, 0xd2f4, 0x0130, 0x9284, 0x5000, 0xc0d5, 0x080c,
+ 0x57fa, 0x0058, 0xd2fc, 0x0180, 0x080c, 0x4bf9, 0x0590, 0xa998,
+ 0x9284, 0x9000, 0xc0d5, 0x080c, 0x57c9, 0xa87b, 0x0000, 0xa883,
+ 0x0000, 0xa897, 0x4000, 0x0438, 0x080c, 0x4bf9, 0x0510, 0x080c,
+ 0x6bcd, 0x2009, 0x0009, 0x11b8, 0xa8c4, 0x9086, 0x0500, 0x11c8,
+ 0xa8c8, 0x9005, 0x11b0, 0xa8cc, 0x9084, 0xff00, 0x1190, 0x080c,
+ 0x4bf9, 0x1108, 0x0070, 0x2009, 0x004b, 0x080c, 0xd13b, 0x2009,
+ 0x0003, 0x0108, 0x0078, 0x0431, 0x19c0, 0xa897, 0x4005, 0xa99a,
0x0010, 0xa897, 0x4006, 0x900e, 0x9085, 0x0001, 0x2001, 0x0030,
- 0x0005, 0xa897, 0x4000, 0x2001, 0x197f, 0x2004, 0xd0fc, 0x1128,
- 0x080c, 0x582e, 0x0110, 0x9006, 0x0018, 0x900e, 0x9085, 0x0001,
- 0x2001, 0x0000, 0x0005, 0x78a8, 0xd08c, 0x1118, 0xd084, 0x0904,
- 0x45dc, 0x080c, 0x4c01, 0x0904, 0x36bd, 0x080c, 0x4bce, 0x1120,
- 0x2009, 0x0002, 0x0804, 0x36ba, 0x080c, 0x6bd5, 0x0130, 0x908e,
- 0x0004, 0x0118, 0x908e, 0x0005, 0x15a0, 0x78a8, 0xd08c, 0x0120,
- 0xb800, 0xc08c, 0xb802, 0x0028, 0x080c, 0x5826, 0xd0b4, 0x0904,
- 0x4616, 0x7884, 0x908e, 0x007e, 0x0904, 0x4616, 0x908e, 0x007f,
- 0x0904, 0x4616, 0x908e, 0x0080, 0x0904, 0x4616, 0xb800, 0xd08c,
- 0x1904, 0x4616, 0xa867, 0x0000, 0xa868, 0xc0fd, 0xa86a, 0x080c,
- 0xcde7, 0x1120, 0x2009, 0x0003, 0x0804, 0x36ba, 0x7007, 0x0003,
- 0x701f, 0x5423, 0x0005, 0x080c, 0x4c01, 0x0904, 0x36bd, 0x0804,
- 0x4616, 0x080c, 0x3478, 0x0108, 0x0005, 0x2009, 0x1834, 0x210c,
- 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x36ba, 0x080c, 0x583a,
- 0x0120, 0x2009, 0x0007, 0x0804, 0x36ba, 0x080c, 0x6bcd, 0x0120,
- 0x2009, 0x0008, 0x0804, 0x36ba, 0xb89c, 0xd0a4, 0x1118, 0xd0ac,
- 0x1904, 0x4616, 0x9006, 0xa866, 0xa832, 0xa868, 0xc0fd, 0xa86a,
- 0x080c, 0xce4f, 0x1120, 0x2009, 0x0003, 0x0804, 0x36ba, 0x7007,
- 0x0003, 0x701f, 0x545c, 0x0005, 0xa830, 0x9086, 0x0100, 0x1120,
- 0x2009, 0x0004, 0x0804, 0x5774, 0x080c, 0x4c01, 0x0904, 0x36bd,
- 0x0804, 0x53f5, 0x81ff, 0x2009, 0x0001, 0x1904, 0x36ba, 0x080c,
- 0x583a, 0x2009, 0x0007, 0x1904, 0x36ba, 0x080c, 0x6bcd, 0x0120,
- 0x2009, 0x0008, 0x0804, 0x36ba, 0x080c, 0x4c01, 0x0904, 0x36bd,
- 0x080c, 0x6bd5, 0x2009, 0x0009, 0x1904, 0x36ba, 0x080c, 0x4bce,
- 0x2009, 0x0002, 0x0904, 0x36ba, 0x9006, 0xa866, 0xa832, 0xa868,
- 0xc0fd, 0xa86a, 0x7988, 0xa95a, 0x9194, 0xfd00, 0x918c, 0x00ff,
- 0x9006, 0x82ff, 0x1128, 0xc0ed, 0xa952, 0x798c, 0xa956, 0x0038,
- 0x928e, 0x0100, 0x1904, 0x36bd, 0xc0e5, 0xa952, 0xa956, 0xa83e,
- 0x080c, 0xd0b2, 0x2009, 0x0003, 0x0904, 0x36ba, 0x7007, 0x0003,
- 0x701f, 0x54b3, 0x0005, 0xa830, 0x9086, 0x0100, 0x2009, 0x0004,
- 0x0904, 0x36ba, 0x0804, 0x3688, 0x7aa8, 0x9284, 0xc000, 0x0148,
- 0xd2ec, 0x01a0, 0x080c, 0x583a, 0x1188, 0x2009, 0x0014, 0x0804,
- 0x36ba, 0xd2dc, 0x1578, 0x81ff, 0x2009, 0x0001, 0x1904, 0x36ba,
- 0x080c, 0x583a, 0x2009, 0x0007, 0x1904, 0x36ba, 0xd2f4, 0x0138,
- 0x9284, 0x5000, 0xc0d5, 0x080c, 0x5800, 0x0804, 0x3688, 0xd2fc,
- 0x0160, 0x080c, 0x4c01, 0x0904, 0x36bd, 0x7984, 0x9284, 0x9000,
- 0xc0d5, 0x080c, 0x57cf, 0x0804, 0x3688, 0x080c, 0x4c01, 0x0904,
- 0x36bd, 0xb804, 0x9084, 0x00ff, 0x9086, 0x0006, 0x2009, 0x0009,
- 0x1904, 0x55a2, 0x080c, 0x4bce, 0x2009, 0x0002, 0x0904, 0x55a2,
- 0xa85c, 0x9080, 0x001b, 0xaf60, 0x2009, 0x0008, 0x7a8c, 0x7b88,
- 0x7c9c, 0x7d98, 0x080c, 0x4c17, 0x701f, 0x550f, 0x0005, 0xa86c,
- 0x9086, 0x0500, 0x1138, 0xa870, 0x9005, 0x1120, 0xa874, 0x9084,
- 0xff00, 0x0110, 0x1904, 0x36bd, 0xa866, 0xa832, 0xa868, 0xc0fd,
- 0xa86a, 0x080c, 0x4c01, 0x1110, 0x0804, 0x36bd, 0x2009, 0x0043,
- 0x080c, 0xd11e, 0x2009, 0x0003, 0x0904, 0x55a2, 0x7007, 0x0003,
- 0x701f, 0x5533, 0x0005, 0xa830, 0x9086, 0x0100, 0x2009, 0x0004,
- 0x0904, 0x55a2, 0x7984, 0x7aa8, 0x9284, 0x1000, 0xc0d5, 0x080c,
- 0x57cf, 0x0804, 0x3688, 0x00c6, 0xaab0, 0x9284, 0xc000, 0x0148,
- 0xd2ec, 0x0170, 0x080c, 0x583a, 0x1158, 0x2009, 0x0014, 0x0804,
- 0x5591, 0x2061, 0x1800, 0x080c, 0x583a, 0x2009, 0x0007, 0x15c8,
- 0xd2f4, 0x0130, 0x9284, 0x5000, 0xc0d5, 0x080c, 0x5800, 0x0058,
- 0xd2fc, 0x0180, 0x080c, 0x4bff, 0x0590, 0xa998, 0x9284, 0x9000,
- 0xc0d5, 0x080c, 0x57cf, 0xa87b, 0x0000, 0xa883, 0x0000, 0xa897,
- 0x4000, 0x0438, 0x080c, 0x4bff, 0x0510, 0x080c, 0x6bd5, 0x2009,
- 0x0009, 0x11b8, 0xa8c4, 0x9086, 0x0500, 0x11c8, 0xa8c8, 0x9005,
- 0x11b0, 0xa8cc, 0x9084, 0xff00, 0x1190, 0x080c, 0x4bff, 0x1108,
- 0x0070, 0x2009, 0x004b, 0x080c, 0xd11e, 0x2009, 0x0003, 0x0108,
- 0x0078, 0x0431, 0x19c0, 0xa897, 0x4005, 0xa99a, 0x0010, 0xa897,
- 0x4006, 0x900e, 0x9085, 0x0001, 0x2001, 0x0030, 0x00ce, 0x0005,
- 0x9006, 0x0ce0, 0x7aa8, 0xd2dc, 0x0904, 0x36ba, 0x0016, 0x7984,
- 0x9284, 0x1000, 0xc0fd, 0x080c, 0x57cf, 0x001e, 0x1904, 0x36ba,
- 0x0804, 0x3688, 0x00f6, 0x2d78, 0xaab0, 0x0021, 0x00fe, 0x0005,
- 0xaab0, 0xc2d5, 0xd2dc, 0x0150, 0x0016, 0xa998, 0x9284, 0x1400,
- 0xc0fd, 0x080c, 0x57cf, 0x001e, 0x9085, 0x0001, 0x0005, 0x81ff,
- 0x0120, 0x2009, 0x0001, 0x0804, 0x36ba, 0x080c, 0x583a, 0x0120,
- 0x2009, 0x0007, 0x0804, 0x36ba, 0x7984, 0x7ea8, 0x96b4, 0x00ff,
- 0x080c, 0x6789, 0x1904, 0x36bd, 0x9186, 0x007f, 0x0138, 0x080c,
- 0x6bd5, 0x0120, 0x2009, 0x0009, 0x0804, 0x36ba, 0x080c, 0x4bce,
- 0x1120, 0x2009, 0x0002, 0x0804, 0x36ba, 0xa867, 0x0000, 0xa868,
- 0xc0fd, 0xa86a, 0x2001, 0x0100, 0x8007, 0xa80a, 0x080c, 0xce01,
- 0x1120, 0x2009, 0x0003, 0x0804, 0x36ba, 0x7007, 0x0003, 0x701f,
- 0x5602, 0x0005, 0xa808, 0x8007, 0x9086, 0x0100, 0x1120, 0x2009,
- 0x0004, 0x0804, 0x36ba, 0xa8e0, 0xa866, 0xa810, 0x8007, 0x9084,
- 0x00ff, 0x800c, 0xa814, 0x8007, 0x9084, 0x00ff, 0x8004, 0x9080,
- 0x0002, 0x9108, 0x8906, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084,
- 0xffc0, 0x9080, 0x0004, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0x0804,
- 0x4c1a, 0x080c, 0x4bce, 0x1120, 0x2009, 0x0002, 0x0804, 0x36ba,
- 0x7984, 0x9194, 0xff00, 0x918c, 0x00ff, 0x8217, 0x82ff, 0x1118,
- 0x7023, 0x19b5, 0x0040, 0x92c6, 0x0001, 0x1118, 0x7023, 0x19cf,
- 0x0010, 0x0804, 0x36bd, 0x2009, 0x001a, 0x7a8c, 0x7b88, 0x7c9c,
- 0x7d98, 0xa85c, 0x9080, 0x0019, 0xaf60, 0x080c, 0x4c17, 0x701f,
- 0x5652, 0x0005, 0x2001, 0x182e, 0x2003, 0x0001, 0xa85c, 0x9080,
- 0x0019, 0x2098, 0xa860, 0x20e0, 0x20a9, 0x001a, 0x7020, 0x20a0,
- 0x20e9, 0x0001, 0x4003, 0x0804, 0x3688, 0x080c, 0x4bce, 0x1120,
- 0x2009, 0x0002, 0x0804, 0x36ba, 0x7984, 0x9194, 0xff00, 0x918c,
- 0x00ff, 0x8217, 0x82ff, 0x1118, 0x2099, 0x19b5, 0x0040, 0x92c6,
- 0x0001, 0x1118, 0x2099, 0x19cf, 0x0010, 0x0804, 0x36bd, 0xa85c,
- 0x9080, 0x0019, 0x20a0, 0xa860, 0x20e8, 0x20a9, 0x001a, 0x20e1,
- 0x0001, 0x4003, 0x2009, 0x001a, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98,
- 0xa85c, 0x9080, 0x0019, 0xaf60, 0x0804, 0x4c1a, 0x7884, 0x908a,
- 0x1000, 0x1a04, 0x36bd, 0x0126, 0x2091, 0x8000, 0x8003, 0x800b,
- 0x810b, 0x9108, 0x00c6, 0x2061, 0x1a05, 0x614a, 0x00ce, 0x012e,
- 0x0804, 0x3688, 0x00c6, 0x080c, 0x76a5, 0x1160, 0x080c, 0x79a7,
- 0x080c, 0x617e, 0x9085, 0x0001, 0x080c, 0x76e9, 0x080c, 0x75d4,
- 0x080c, 0x0d85, 0x2061, 0x1800, 0x6030, 0xc09d, 0x6032, 0x080c,
- 0x6039, 0x00ce, 0x0005, 0x00c6, 0x2001, 0x1800, 0x2004, 0x908e,
- 0x0000, 0x0904, 0x36ba, 0x7884, 0x9005, 0x0188, 0x7888, 0x2061,
- 0x199d, 0x2c0c, 0x2062, 0x080c, 0x2a89, 0x01a0, 0x080c, 0x2a91,
- 0x0188, 0x080c, 0x2a99, 0x0170, 0x2162, 0x0804, 0x36bd, 0x2061,
- 0x0100, 0x6038, 0x9086, 0x0007, 0x1118, 0x2009, 0x0001, 0x0010,
- 0x2009, 0x0000, 0x7884, 0x9086, 0x0002, 0x15a8, 0x2061, 0x0100,
- 0x6028, 0xc09c, 0x602a, 0x080c, 0xaae0, 0x0026, 0x2011, 0x0003,
- 0x080c, 0xa40f, 0x2011, 0x0002, 0x080c, 0xa419, 0x002e, 0x080c,
- 0xa300, 0x0036, 0x901e, 0x080c, 0xa380, 0x003e, 0x080c, 0xaafc,
- 0x60e3, 0x0000, 0x080c, 0xeb7d, 0x080c, 0xeb98, 0x9085, 0x0001,
- 0x080c, 0x76e9, 0x9006, 0x080c, 0x2abb, 0x2001, 0x1800, 0x2003,
- 0x0004, 0x2001, 0x19a8, 0x2003, 0x0000, 0x0026, 0x2011, 0x0008,
- 0x080c, 0x2af5, 0x002e, 0x00ce, 0x0804, 0x3688, 0x81ff, 0x0120,
- 0x2009, 0x0001, 0x0804, 0x36ba, 0x080c, 0x583a, 0x0120, 0x2009,
- 0x0007, 0x0804, 0x36ba, 0x7984, 0x7ea8, 0x96b4, 0x00ff, 0x080c,
- 0x6789, 0x1904, 0x36bd, 0x9186, 0x007f, 0x0138, 0x080c, 0x6bd5,
- 0x0120, 0x2009, 0x0009, 0x0804, 0x36ba, 0x080c, 0x4bce, 0x1120,
- 0x2009, 0x0002, 0x0804, 0x36ba, 0xa867, 0x0000, 0xa868, 0xc0fd,
- 0xa86a, 0x080c, 0xce04, 0x1120, 0x2009, 0x0003, 0x0804, 0x36ba,
- 0x7007, 0x0003, 0x701f, 0x575d, 0x0005, 0xa830, 0x9086, 0x0100,
- 0x1120, 0x2009, 0x0004, 0x0804, 0x36ba, 0xa8e0, 0xa866, 0xa834,
- 0x8007, 0x800c, 0xa85c, 0x9080, 0x000c, 0x7a8c, 0x7b88, 0x7c9c,
- 0x7d98, 0xaf60, 0x0804, 0x4c1a, 0xa898, 0x9086, 0x000d, 0x1904,
- 0x36ba, 0x2021, 0x4005, 0x0126, 0x2091, 0x8000, 0x0e04, 0x5781,
- 0x0010, 0x012e, 0x0cc0, 0x7c36, 0x9486, 0x4000, 0x0118, 0x7833,
- 0x0011, 0x0010, 0x7833, 0x0010, 0x7883, 0x4005, 0xa998, 0x7986,
- 0xa9a4, 0x799a, 0xa9a8, 0x799e, 0x080c, 0x4c0a, 0x2091, 0x4080,
- 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x1200, 0x7007, 0x0001,
- 0x2091, 0x5000, 0x700f, 0x0000, 0x012e, 0x0005, 0x0126, 0x2091,
- 0x8000, 0x00c6, 0x2061, 0x1a05, 0x7984, 0x615a, 0x6156, 0x605f,
- 0x0000, 0x6053, 0x0009, 0x7898, 0x6072, 0x789c, 0x606e, 0x7888,
- 0x606a, 0x788c, 0x6066, 0x2001, 0x1a15, 0x2044, 0x2001, 0x1a1c,
- 0xa076, 0xa060, 0xa072, 0xa07b, 0x0001, 0xa07f, 0x0002, 0xa06b,
- 0x0000, 0xa09f, 0x0000, 0x00ce, 0x012e, 0x0804, 0x3688, 0x0126,
- 0x2091, 0x8000, 0x00b6, 0x00c6, 0x90e4, 0xc000, 0x0198, 0x0006,
- 0xd0d4, 0x0160, 0x0036, 0x2019, 0x0029, 0x080c, 0xaae0, 0x0106,
- 0x080c, 0x343d, 0x010e, 0x090c, 0xaafc, 0x003e, 0x080c, 0xcc63,
- 0x000e, 0x1198, 0xd0e4, 0x0160, 0x9180, 0x1000, 0x2004, 0x905d,
- 0x0160, 0x080c, 0x6198, 0x080c, 0xae60, 0x0110, 0xb817, 0x0000,
- 0x9006, 0x00ce, 0x00be, 0x012e, 0x0005, 0x9085, 0x0001, 0x0cc8,
- 0x0126, 0x2091, 0x8000, 0x0156, 0x2010, 0x900e, 0x20a9, 0x0800,
- 0x0016, 0x9180, 0x1000, 0x2004, 0x9005, 0x0188, 0x9186, 0x007e,
- 0x0170, 0x9186, 0x007f, 0x0158, 0x9186, 0x0080, 0x0140, 0x9186,
- 0x00ff, 0x0128, 0x0026, 0x2200, 0x080c, 0x57cf, 0x002e, 0x001e,
- 0x8108, 0x1f04, 0x5808, 0x015e, 0x012e, 0x0005, 0x2001, 0x1848,
- 0x2004, 0x0005, 0x2001, 0x1867, 0x2004, 0x0005, 0x0006, 0x2001,
- 0x1810, 0x2004, 0xd0d4, 0x000e, 0x0005, 0x2001, 0x180e, 0x2004,
- 0xd0b4, 0x0005, 0x2001, 0x1800, 0x2004, 0x9086, 0x0003, 0x0005,
- 0x0016, 0x00e6, 0x2071, 0x189e, 0x7108, 0x910d, 0x710a, 0x00ee,
- 0x001e, 0x0005, 0x79a4, 0x81ff, 0x0904, 0x36bd, 0x9182, 0x0081,
- 0x1a04, 0x36bd, 0x810c, 0x0016, 0x080c, 0x4bce, 0x0170, 0x080c,
- 0x0f61, 0x2100, 0x2238, 0x7d84, 0x7c88, 0x7b8c, 0x7a90, 0x001e,
- 0x080c, 0x4c17, 0x701f, 0x586a, 0x0005, 0x001e, 0x2009, 0x0002,
- 0x0804, 0x36ba, 0x2079, 0x0000, 0x7d94, 0x7c98, 0x7ba8, 0x7aac,
- 0x79a4, 0x810c, 0x2061, 0x18b8, 0x2c44, 0xa770, 0xa074, 0x2071,
- 0x189e, 0x080c, 0x4c1a, 0x701f, 0x587e, 0x0005, 0x2061, 0x18b8,
- 0x2c44, 0x0016, 0x0026, 0xa270, 0xa174, 0x080c, 0x0f69, 0x002e,
- 0x001e, 0x080c, 0x1016, 0x9006, 0xa802, 0xa806, 0x0804, 0x3688,
- 0x0126, 0x0156, 0x0136, 0x0146, 0x01c6, 0x01d6, 0x00c6, 0x00d6,
- 0x00e6, 0x00f6, 0x2061, 0x0100, 0x2069, 0x0200, 0x2071, 0x1800,
- 0x6044, 0xd0a4, 0x11e8, 0xd084, 0x0118, 0x080c, 0x5a39, 0x0068,
- 0xd08c, 0x0118, 0x080c, 0x5942, 0x0040, 0xd094, 0x0118, 0x080c,
- 0x5912, 0x0018, 0xd09c, 0x0108, 0x0099, 0x00fe, 0x00ee, 0x00de,
- 0x00ce, 0x01de, 0x01ce, 0x014e, 0x013e, 0x015e, 0x012e, 0x0005,
- 0x0016, 0x6128, 0xd19c, 0x1110, 0xc19d, 0x612a, 0x001e, 0x0c68,
- 0x0006, 0x7098, 0x9005, 0x000e, 0x0120, 0x709b, 0x0000, 0x7093,
- 0x0000, 0x624c, 0x9286, 0xf0f0, 0x1150, 0x6048, 0x9086, 0xf0f0,
- 0x0130, 0x624a, 0x6043, 0x0090, 0x6043, 0x0010, 0x0490, 0x9294,
- 0xff00, 0x9296, 0xf700, 0x0178, 0x7138, 0xd1a4, 0x1160, 0x6240,
- 0x9295, 0x0100, 0x6242, 0x9294, 0x0010, 0x0128, 0x2009, 0x00f7,
- 0x080c, 0x60fa, 0x00f0, 0x6040, 0x9084, 0x0010, 0x9085, 0x0140,
- 0x6042, 0x6043, 0x0000, 0x7087, 0x0000, 0x70a3, 0x0001, 0x70c7,
- 0x0000, 0x70df, 0x0000, 0x2009, 0x1d80, 0x200b, 0x0000, 0x7097,
- 0x0000, 0x708b, 0x000f, 0x2009, 0x000f, 0x2011, 0x5fdc, 0x080c,
- 0x88fe, 0x0005, 0x2001, 0x1869, 0x2004, 0xd08c, 0x0110, 0x705f,
- 0xffff, 0x7088, 0x9005, 0x1528, 0x2011, 0x5fdc, 0x080c, 0x8834,
- 0x6040, 0x9094, 0x0010, 0x9285, 0x0020, 0x6042, 0x20a9, 0x00c8,
- 0x6044, 0xd08c, 0x1168, 0x1f04, 0x5928, 0x6242, 0x709b, 0x0000,
- 0x6040, 0x9094, 0x0010, 0x9285, 0x0080, 0x6042, 0x6242, 0x0048,
- 0x6242, 0x709b, 0x0000, 0x708f, 0x0000, 0x9006, 0x080c, 0x6183,
- 0x0000, 0x0005, 0x708c, 0x908a, 0x0003, 0x1a0c, 0x0d85, 0x000b,
- 0x0005, 0x594c, 0x599d, 0x5a38, 0x00f6, 0x0016, 0x6900, 0x918c,
- 0x0800, 0x708f, 0x0001, 0x2001, 0x015d, 0x2003, 0x0000, 0x6803,
- 0x00fc, 0x20a9, 0x0004, 0x6800, 0x9084, 0x00fc, 0x0120, 0x1f04,
- 0x595b, 0x080c, 0x0d85, 0x68a0, 0x68a2, 0x689c, 0x689e, 0x6898,
- 0x689a, 0xa001, 0x918d, 0x1600, 0x6902, 0x001e, 0x6837, 0x0020,
- 0x080c, 0x615f, 0x2079, 0x1d00, 0x7833, 0x1101, 0x7837, 0x0000,
- 0x20e1, 0x0001, 0x2099, 0x1805, 0x20e9, 0x0001, 0x20a1, 0x1d0e,
- 0x20a9, 0x0004, 0x4003, 0x080c, 0xa8d5, 0x20e1, 0x0001, 0x2099,
- 0x1d00, 0x20e9, 0x0000, 0x20a1, 0x0240, 0x20a9, 0x0014, 0x4003,
- 0x60c3, 0x000c, 0x600f, 0x0000, 0x080c, 0x600d, 0x00fe, 0x9006,
- 0x7092, 0x6043, 0x0008, 0x6042, 0x0005, 0x00f6, 0x7090, 0x7093,
- 0x0000, 0x9025, 0x0904, 0x5a15, 0x6020, 0xd0b4, 0x1904, 0x5a13,
- 0x71a0, 0x81ff, 0x0904, 0x5a01, 0x9486, 0x000c, 0x1904, 0x5a0e,
- 0x9480, 0x0018, 0x8004, 0x20a8, 0x080c, 0x6158, 0x2011, 0x0260,
- 0x2019, 0x1d00, 0x220c, 0x2304, 0x9106, 0x11e8, 0x8210, 0x8318,
- 0x1f04, 0x59ba, 0x6043, 0x0004, 0x2061, 0x0140, 0x605b, 0xbc94,
- 0x605f, 0xf0f0, 0x2061, 0x0100, 0x6043, 0x0006, 0x708f, 0x0002,
- 0x709b, 0x0002, 0x2009, 0x07d0, 0x2011, 0x5fe3, 0x080c, 0x88fe,
- 0x080c, 0x615f, 0x04c0, 0x080c, 0x6158, 0x2079, 0x0260, 0x7930,
- 0x918e, 0x1101, 0x1558, 0x7834, 0x9005, 0x1540, 0x7900, 0x918c,
- 0x00ff, 0x1118, 0x7804, 0x9005, 0x0190, 0x080c, 0x6158, 0x2011,
- 0x026e, 0x2019, 0x1805, 0x20a9, 0x0004, 0x220c, 0x2304, 0x9102,
- 0x0230, 0x11a0, 0x8210, 0x8318, 0x1f04, 0x59f5, 0x0078, 0x70a3,
- 0x0000, 0x080c, 0x6158, 0x20e1, 0x0000, 0x2099, 0x0260, 0x20e9,
- 0x0001, 0x20a1, 0x1d00, 0x20a9, 0x0014, 0x4003, 0x6043, 0x0008,
- 0x6043, 0x0000, 0x0010, 0x00fe, 0x0005, 0x6040, 0x9085, 0x0100,
- 0x6042, 0x6020, 0xd0b4, 0x1db8, 0x080c, 0xa8d5, 0x20e1, 0x0001,
- 0x2099, 0x1d00, 0x20e9, 0x0000, 0x20a1, 0x0240, 0x20a9, 0x0014,
- 0x4003, 0x60c3, 0x000c, 0x2011, 0x19f6, 0x2013, 0x0000, 0x7093,
- 0x0000, 0x60a3, 0x0056, 0x60a7, 0x9575, 0x080c, 0xa07d, 0x08d8,
- 0x0005, 0x7098, 0x908a, 0x001d, 0x1a0c, 0x0d85, 0x000b, 0x0005,
- 0x5a6a, 0x5a7d, 0x5aa6, 0x5ac6, 0x5aec, 0x5b1b, 0x5b41, 0x5b79,
- 0x5b9f, 0x5bcd, 0x5c08, 0x5c40, 0x5c5e, 0x5c89, 0x5cab, 0x5cc6,
- 0x5cd0, 0x5d04, 0x5d2a, 0x5d59, 0x5d7f, 0x5db7, 0x5dfb, 0x5e38,
- 0x5e59, 0x5eb2, 0x5ed4, 0x5f02, 0x5f02, 0x00c6, 0x2061, 0x1800,
- 0x6003, 0x0007, 0x2061, 0x0100, 0x6004, 0x9084, 0xfff9, 0x6006,
- 0x00ce, 0x0005, 0x2061, 0x0140, 0x605b, 0xbc94, 0x605f, 0xf0f0,
- 0x2061, 0x0100, 0x6043, 0x0002, 0x709b, 0x0001, 0x2009, 0x07d0,
- 0x2011, 0x5fe3, 0x080c, 0x88fe, 0x0005, 0x00f6, 0x7090, 0x9086,
- 0x0014, 0x1510, 0x6042, 0x6020, 0xd0b4, 0x11f0, 0x080c, 0x6158,
- 0x2079, 0x0260, 0x7a30, 0x9296, 0x1102, 0x11a0, 0x7834, 0x9005,
- 0x1188, 0x7a38, 0xd2fc, 0x0128, 0x70c4, 0x9005, 0x1110, 0x70c7,
- 0x0001, 0x2011, 0x5fe3, 0x080c, 0x8834, 0x709b, 0x0010, 0x080c,
- 0x5cd0, 0x0010, 0x7093, 0x0000, 0x00fe, 0x0005, 0x00f6, 0x709b,
- 0x0003, 0x6043, 0x0004, 0x2011, 0x5fe3, 0x080c, 0x8834, 0x080c,
- 0x60dc, 0x2079, 0x0240, 0x7833, 0x1102, 0x7837, 0x0000, 0x20a9,
- 0x0008, 0x9f88, 0x000e, 0x200b, 0x0000, 0x8108, 0x1f04, 0x5abb,
- 0x60c3, 0x0014, 0x080c, 0x600d, 0x00fe, 0x0005, 0x00f6, 0x7090,
- 0x9005, 0x0500, 0x2011, 0x5fe3, 0x080c, 0x8834, 0x9086, 0x0014,
- 0x11b8, 0x080c, 0x6158, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1102,
+ 0x00ce, 0x0005, 0x9006, 0x0ce0, 0x7aa8, 0xd2dc, 0x0904, 0x36a5,
+ 0x0016, 0x7984, 0x9284, 0x1000, 0xc0fd, 0x080c, 0x57c9, 0x001e,
+ 0x1904, 0x36a5, 0x0804, 0x3673, 0x00f6, 0x2d78, 0xaab0, 0x0021,
+ 0x00fe, 0x0005, 0xaab0, 0xc2d5, 0xd2dc, 0x0150, 0x0016, 0xa998,
+ 0x9284, 0x1400, 0xc0fd, 0x080c, 0x57c9, 0x001e, 0x9085, 0x0001,
+ 0x0005, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x36a5, 0x080c,
+ 0x5834, 0x0120, 0x2009, 0x0007, 0x0804, 0x36a5, 0x7984, 0x7ea8,
+ 0x96b4, 0x00ff, 0x080c, 0x6783, 0x1904, 0x36a8, 0x9186, 0x007f,
+ 0x0138, 0x080c, 0x6bcd, 0x0120, 0x2009, 0x0009, 0x0804, 0x36a5,
+ 0x080c, 0x4bc8, 0x1120, 0x2009, 0x0002, 0x0804, 0x36a5, 0xa867,
+ 0x0000, 0xa868, 0xc0fd, 0xa86a, 0x2001, 0x0100, 0x8007, 0xa80a,
+ 0x080c, 0xce1e, 0x1120, 0x2009, 0x0003, 0x0804, 0x36a5, 0x7007,
+ 0x0003, 0x701f, 0x55fc, 0x0005, 0xa808, 0x8007, 0x9086, 0x0100,
+ 0x1120, 0x2009, 0x0004, 0x0804, 0x36a5, 0xa8e0, 0xa866, 0xa810,
+ 0x8007, 0x9084, 0x00ff, 0x800c, 0xa814, 0x8007, 0x9084, 0x00ff,
+ 0x8004, 0x9080, 0x0002, 0x9108, 0x8906, 0x8006, 0x8007, 0x90bc,
+ 0x003f, 0x9084, 0xffc0, 0x9080, 0x0004, 0x7a8c, 0x7b88, 0x7c9c,
+ 0x7d98, 0x0804, 0x4c14, 0x080c, 0x4bc8, 0x1120, 0x2009, 0x0002,
+ 0x0804, 0x36a5, 0x7984, 0x9194, 0xff00, 0x918c, 0x00ff, 0x8217,
+ 0x82ff, 0x1118, 0x7023, 0x19b5, 0x0040, 0x92c6, 0x0001, 0x1118,
+ 0x7023, 0x19cf, 0x0010, 0x0804, 0x36a8, 0x2009, 0x001a, 0x7a8c,
+ 0x7b88, 0x7c9c, 0x7d98, 0xa85c, 0x9080, 0x0019, 0xaf60, 0x080c,
+ 0x4c11, 0x701f, 0x564c, 0x0005, 0x2001, 0x182e, 0x2003, 0x0001,
+ 0xa85c, 0x9080, 0x0019, 0x2098, 0xa860, 0x20e0, 0x20a9, 0x001a,
+ 0x7020, 0x20a0, 0x20e9, 0x0001, 0x4003, 0x0804, 0x3673, 0x080c,
+ 0x4bc8, 0x1120, 0x2009, 0x0002, 0x0804, 0x36a5, 0x7984, 0x9194,
+ 0xff00, 0x918c, 0x00ff, 0x8217, 0x82ff, 0x1118, 0x2099, 0x19b5,
+ 0x0040, 0x92c6, 0x0001, 0x1118, 0x2099, 0x19cf, 0x0010, 0x0804,
+ 0x36a8, 0xa85c, 0x9080, 0x0019, 0x20a0, 0xa860, 0x20e8, 0x20a9,
+ 0x001a, 0x20e1, 0x0001, 0x4003, 0x2009, 0x001a, 0x7a8c, 0x7b88,
+ 0x7c9c, 0x7d98, 0xa85c, 0x9080, 0x0019, 0xaf60, 0x0804, 0x4c14,
+ 0x7884, 0x908a, 0x1000, 0x1a04, 0x36a8, 0x0126, 0x2091, 0x8000,
+ 0x8003, 0x800b, 0x810b, 0x9108, 0x00c6, 0x2061, 0x1a05, 0x614a,
+ 0x00ce, 0x012e, 0x0804, 0x3673, 0x00c6, 0x080c, 0x769d, 0x1160,
+ 0x080c, 0x799f, 0x080c, 0x6178, 0x9085, 0x0001, 0x080c, 0x76e1,
+ 0x080c, 0x75cc, 0x080c, 0x0d79, 0x2061, 0x1800, 0x6030, 0xc09d,
+ 0x6032, 0x080c, 0x6033, 0x00ce, 0x0005, 0x00c6, 0x2001, 0x1800,
+ 0x2004, 0x908e, 0x0000, 0x0904, 0x36a5, 0x7884, 0x9005, 0x0188,
+ 0x7888, 0x2061, 0x199d, 0x2c0c, 0x2062, 0x080c, 0x2a70, 0x01a0,
+ 0x080c, 0x2a78, 0x0188, 0x080c, 0x2a80, 0x0170, 0x2162, 0x0804,
+ 0x36a8, 0x2061, 0x0100, 0x6038, 0x9086, 0x0007, 0x1118, 0x2009,
+ 0x0001, 0x0010, 0x2009, 0x0000, 0x7884, 0x9086, 0x0002, 0x15a8,
+ 0x2061, 0x0100, 0x6028, 0xc09c, 0x602a, 0x080c, 0xaaf7, 0x0026,
+ 0x2011, 0x0003, 0x080c, 0xa426, 0x2011, 0x0002, 0x080c, 0xa430,
+ 0x002e, 0x080c, 0xa311, 0x0036, 0x901e, 0x080c, 0xa391, 0x003e,
+ 0x080c, 0xab13, 0x60e3, 0x0000, 0x080c, 0xebe8, 0x080c, 0xec03,
+ 0x9085, 0x0001, 0x080c, 0x76e1, 0x9006, 0x080c, 0x2aa2, 0x2001,
+ 0x1800, 0x2003, 0x0004, 0x2001, 0x19a9, 0x2003, 0x0000, 0x0026,
+ 0x2011, 0x0008, 0x080c, 0x2adc, 0x002e, 0x00ce, 0x0804, 0x3673,
+ 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x36a5, 0x080c, 0x5834,
+ 0x0120, 0x2009, 0x0007, 0x0804, 0x36a5, 0x7984, 0x7ea8, 0x96b4,
+ 0x00ff, 0x080c, 0x6783, 0x1904, 0x36a8, 0x9186, 0x007f, 0x0138,
+ 0x080c, 0x6bcd, 0x0120, 0x2009, 0x0009, 0x0804, 0x36a5, 0x080c,
+ 0x4bc8, 0x1120, 0x2009, 0x0002, 0x0804, 0x36a5, 0xa867, 0x0000,
+ 0xa868, 0xc0fd, 0xa86a, 0x080c, 0xce21, 0x1120, 0x2009, 0x0003,
+ 0x0804, 0x36a5, 0x7007, 0x0003, 0x701f, 0x5757, 0x0005, 0xa830,
+ 0x9086, 0x0100, 0x1120, 0x2009, 0x0004, 0x0804, 0x36a5, 0xa8e0,
+ 0xa866, 0xa834, 0x8007, 0x800c, 0xa85c, 0x9080, 0x000c, 0x7a8c,
+ 0x7b88, 0x7c9c, 0x7d98, 0xaf60, 0x0804, 0x4c14, 0xa898, 0x9086,
+ 0x000d, 0x1904, 0x36a5, 0x2021, 0x4005, 0x0126, 0x2091, 0x8000,
+ 0x0e04, 0x577b, 0x0010, 0x012e, 0x0cc0, 0x7c36, 0x9486, 0x4000,
+ 0x0118, 0x7833, 0x0011, 0x0010, 0x7833, 0x0010, 0x7883, 0x4005,
+ 0xa998, 0x7986, 0xa9a4, 0x799a, 0xa9a8, 0x799e, 0x080c, 0x4c04,
+ 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x11f4,
+ 0x7007, 0x0001, 0x2091, 0x5000, 0x700f, 0x0000, 0x012e, 0x0005,
+ 0x0126, 0x2091, 0x8000, 0x00c6, 0x2061, 0x1a05, 0x7984, 0x615a,
+ 0x6156, 0x605f, 0x0000, 0x6053, 0x0009, 0x7898, 0x6072, 0x789c,
+ 0x606e, 0x7888, 0x606a, 0x788c, 0x6066, 0x2001, 0x1a15, 0x2044,
+ 0x2001, 0x1a1c, 0xa076, 0xa060, 0xa072, 0xa07b, 0x0001, 0xa07f,
+ 0x0002, 0xa06b, 0x0000, 0xa09f, 0x0000, 0x00ce, 0x012e, 0x0804,
+ 0x3673, 0x0126, 0x2091, 0x8000, 0x00b6, 0x00c6, 0x90e4, 0xc000,
+ 0x0198, 0x0006, 0xd0d4, 0x0160, 0x0036, 0x2019, 0x0029, 0x080c,
+ 0xaaf7, 0x0106, 0x080c, 0x3428, 0x010e, 0x090c, 0xab13, 0x003e,
+ 0x080c, 0xcc80, 0x000e, 0x1198, 0xd0e4, 0x0160, 0x9180, 0x1000,
+ 0x2004, 0x905d, 0x0160, 0x080c, 0x6192, 0x080c, 0xae80, 0x0110,
+ 0xb817, 0x0000, 0x9006, 0x00ce, 0x00be, 0x012e, 0x0005, 0x9085,
+ 0x0001, 0x0cc8, 0x0126, 0x2091, 0x8000, 0x0156, 0x2010, 0x900e,
+ 0x20a9, 0x0800, 0x0016, 0x9180, 0x1000, 0x2004, 0x9005, 0x0188,
+ 0x9186, 0x007e, 0x0170, 0x9186, 0x007f, 0x0158, 0x9186, 0x0080,
+ 0x0140, 0x9186, 0x00ff, 0x0128, 0x0026, 0x2200, 0x080c, 0x57c9,
+ 0x002e, 0x001e, 0x8108, 0x1f04, 0x5802, 0x015e, 0x012e, 0x0005,
+ 0x2001, 0x1848, 0x2004, 0x0005, 0x2001, 0x1867, 0x2004, 0x0005,
+ 0x0006, 0x2001, 0x1810, 0x2004, 0xd0d4, 0x000e, 0x0005, 0x2001,
+ 0x180e, 0x2004, 0xd0b4, 0x0005, 0x2001, 0x1800, 0x2004, 0x9086,
+ 0x0003, 0x0005, 0x0016, 0x00e6, 0x2071, 0x189e, 0x7108, 0x910d,
+ 0x710a, 0x00ee, 0x001e, 0x0005, 0x79a4, 0x81ff, 0x0904, 0x36a8,
+ 0x9182, 0x0081, 0x1a04, 0x36a8, 0x810c, 0x0016, 0x080c, 0x4bc8,
+ 0x0170, 0x080c, 0x0f55, 0x2100, 0x2238, 0x7d84, 0x7c88, 0x7b8c,
+ 0x7a90, 0x001e, 0x080c, 0x4c11, 0x701f, 0x5864, 0x0005, 0x001e,
+ 0x2009, 0x0002, 0x0804, 0x36a5, 0x2079, 0x0000, 0x7d94, 0x7c98,
+ 0x7ba8, 0x7aac, 0x79a4, 0x810c, 0x2061, 0x18b8, 0x2c44, 0xa770,
+ 0xa074, 0x2071, 0x189e, 0x080c, 0x4c14, 0x701f, 0x5878, 0x0005,
+ 0x2061, 0x18b8, 0x2c44, 0x0016, 0x0026, 0xa270, 0xa174, 0x080c,
+ 0x0f5d, 0x002e, 0x001e, 0x080c, 0x100a, 0x9006, 0xa802, 0xa806,
+ 0x0804, 0x3673, 0x0126, 0x0156, 0x0136, 0x0146, 0x01c6, 0x01d6,
+ 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x2061, 0x0100, 0x2069, 0x0200,
+ 0x2071, 0x1800, 0x6044, 0xd0a4, 0x11e8, 0xd084, 0x0118, 0x080c,
+ 0x5a33, 0x0068, 0xd08c, 0x0118, 0x080c, 0x593c, 0x0040, 0xd094,
+ 0x0118, 0x080c, 0x590c, 0x0018, 0xd09c, 0x0108, 0x0099, 0x00fe,
+ 0x00ee, 0x00de, 0x00ce, 0x01de, 0x01ce, 0x014e, 0x013e, 0x015e,
+ 0x012e, 0x0005, 0x0016, 0x6128, 0xd19c, 0x1110, 0xc19d, 0x612a,
+ 0x001e, 0x0c68, 0x0006, 0x7098, 0x9005, 0x000e, 0x0120, 0x709b,
+ 0x0000, 0x7093, 0x0000, 0x624c, 0x9286, 0xf0f0, 0x1150, 0x6048,
+ 0x9086, 0xf0f0, 0x0130, 0x624a, 0x6043, 0x0090, 0x6043, 0x0010,
+ 0x0490, 0x9294, 0xff00, 0x9296, 0xf700, 0x0178, 0x7138, 0xd1a4,
+ 0x1160, 0x6240, 0x9295, 0x0100, 0x6242, 0x9294, 0x0010, 0x0128,
+ 0x2009, 0x00f7, 0x080c, 0x60f4, 0x00f0, 0x6040, 0x9084, 0x0010,
+ 0x9085, 0x0140, 0x6042, 0x6043, 0x0000, 0x7087, 0x0000, 0x70a3,
+ 0x0001, 0x70c7, 0x0000, 0x70df, 0x0000, 0x2009, 0x1d80, 0x200b,
+ 0x0000, 0x7097, 0x0000, 0x708b, 0x000f, 0x2009, 0x000f, 0x2011,
+ 0x5fd6, 0x080c, 0x88f6, 0x0005, 0x2001, 0x1869, 0x2004, 0xd08c,
+ 0x0110, 0x705f, 0xffff, 0x7088, 0x9005, 0x1528, 0x2011, 0x5fd6,
+ 0x080c, 0x882c, 0x6040, 0x9094, 0x0010, 0x9285, 0x0020, 0x6042,
+ 0x20a9, 0x00c8, 0x6044, 0xd08c, 0x1168, 0x1f04, 0x5922, 0x6242,
+ 0x709b, 0x0000, 0x6040, 0x9094, 0x0010, 0x9285, 0x0080, 0x6042,
+ 0x6242, 0x0048, 0x6242, 0x709b, 0x0000, 0x708f, 0x0000, 0x9006,
+ 0x080c, 0x617d, 0x0000, 0x0005, 0x708c, 0x908a, 0x0003, 0x1a0c,
+ 0x0d79, 0x000b, 0x0005, 0x5946, 0x5997, 0x5a32, 0x00f6, 0x0016,
+ 0x6900, 0x918c, 0x0800, 0x708f, 0x0001, 0x2001, 0x015d, 0x2003,
+ 0x0000, 0x6803, 0x00fc, 0x20a9, 0x0004, 0x6800, 0x9084, 0x00fc,
+ 0x0120, 0x1f04, 0x5955, 0x080c, 0x0d79, 0x68a0, 0x68a2, 0x689c,
+ 0x689e, 0x6898, 0x689a, 0xa001, 0x918d, 0x1600, 0x6902, 0x001e,
+ 0x6837, 0x0020, 0x080c, 0x6159, 0x2079, 0x1d00, 0x7833, 0x1101,
+ 0x7837, 0x0000, 0x20e1, 0x0001, 0x2099, 0x1805, 0x20e9, 0x0001,
+ 0x20a1, 0x1d0e, 0x20a9, 0x0004, 0x4003, 0x080c, 0xa8ec, 0x20e1,
+ 0x0001, 0x2099, 0x1d00, 0x20e9, 0x0000, 0x20a1, 0x0240, 0x20a9,
+ 0x0014, 0x4003, 0x60c3, 0x000c, 0x600f, 0x0000, 0x080c, 0x6007,
+ 0x00fe, 0x9006, 0x7092, 0x6043, 0x0008, 0x6042, 0x0005, 0x00f6,
+ 0x7090, 0x7093, 0x0000, 0x9025, 0x0904, 0x5a0f, 0x6020, 0xd0b4,
+ 0x1904, 0x5a0d, 0x71a0, 0x81ff, 0x0904, 0x59fb, 0x9486, 0x000c,
+ 0x1904, 0x5a08, 0x9480, 0x0018, 0x8004, 0x20a8, 0x080c, 0x6152,
+ 0x2011, 0x0260, 0x2019, 0x1d00, 0x220c, 0x2304, 0x9106, 0x11e8,
+ 0x8210, 0x8318, 0x1f04, 0x59b4, 0x6043, 0x0004, 0x2061, 0x0140,
+ 0x605b, 0xbc94, 0x605f, 0xf0f0, 0x2061, 0x0100, 0x6043, 0x0006,
+ 0x708f, 0x0002, 0x709b, 0x0002, 0x2009, 0x07d0, 0x2011, 0x5fdd,
+ 0x080c, 0x88f6, 0x080c, 0x6159, 0x04c0, 0x080c, 0x6152, 0x2079,
+ 0x0260, 0x7930, 0x918e, 0x1101, 0x1558, 0x7834, 0x9005, 0x1540,
+ 0x7900, 0x918c, 0x00ff, 0x1118, 0x7804, 0x9005, 0x0190, 0x080c,
+ 0x6152, 0x2011, 0x026e, 0x2019, 0x1805, 0x20a9, 0x0004, 0x220c,
+ 0x2304, 0x9102, 0x0230, 0x11a0, 0x8210, 0x8318, 0x1f04, 0x59ef,
+ 0x0078, 0x70a3, 0x0000, 0x080c, 0x6152, 0x20e1, 0x0000, 0x2099,
+ 0x0260, 0x20e9, 0x0001, 0x20a1, 0x1d00, 0x20a9, 0x0014, 0x4003,
+ 0x6043, 0x0008, 0x6043, 0x0000, 0x0010, 0x00fe, 0x0005, 0x6040,
+ 0x9085, 0x0100, 0x6042, 0x6020, 0xd0b4, 0x1db8, 0x080c, 0xa8ec,
+ 0x20e1, 0x0001, 0x2099, 0x1d00, 0x20e9, 0x0000, 0x20a1, 0x0240,
+ 0x20a9, 0x0014, 0x4003, 0x60c3, 0x000c, 0x2011, 0x19f6, 0x2013,
+ 0x0000, 0x7093, 0x0000, 0x60a3, 0x0056, 0x60a7, 0x9575, 0x080c,
+ 0xa08e, 0x08d8, 0x0005, 0x7098, 0x908a, 0x001d, 0x1a0c, 0x0d79,
+ 0x000b, 0x0005, 0x5a64, 0x5a77, 0x5aa0, 0x5ac0, 0x5ae6, 0x5b15,
+ 0x5b3b, 0x5b73, 0x5b99, 0x5bc7, 0x5c02, 0x5c3a, 0x5c58, 0x5c83,
+ 0x5ca5, 0x5cc0, 0x5cca, 0x5cfe, 0x5d24, 0x5d53, 0x5d79, 0x5db1,
+ 0x5df5, 0x5e32, 0x5e53, 0x5eac, 0x5ece, 0x5efc, 0x5efc, 0x00c6,
+ 0x2061, 0x1800, 0x6003, 0x0007, 0x2061, 0x0100, 0x6004, 0x9084,
+ 0xfff9, 0x6006, 0x00ce, 0x0005, 0x2061, 0x0140, 0x605b, 0xbc94,
+ 0x605f, 0xf0f0, 0x2061, 0x0100, 0x6043, 0x0002, 0x709b, 0x0001,
+ 0x2009, 0x07d0, 0x2011, 0x5fdd, 0x080c, 0x88f6, 0x0005, 0x00f6,
+ 0x7090, 0x9086, 0x0014, 0x1510, 0x6042, 0x6020, 0xd0b4, 0x11f0,
+ 0x080c, 0x6152, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1102, 0x11a0,
+ 0x7834, 0x9005, 0x1188, 0x7a38, 0xd2fc, 0x0128, 0x70c4, 0x9005,
+ 0x1110, 0x70c7, 0x0001, 0x2011, 0x5fdd, 0x080c, 0x882c, 0x709b,
+ 0x0010, 0x080c, 0x5cca, 0x0010, 0x7093, 0x0000, 0x00fe, 0x0005,
+ 0x00f6, 0x709b, 0x0003, 0x6043, 0x0004, 0x2011, 0x5fdd, 0x080c,
+ 0x882c, 0x080c, 0x60d6, 0x2079, 0x0240, 0x7833, 0x1102, 0x7837,
+ 0x0000, 0x20a9, 0x0008, 0x9f88, 0x000e, 0x200b, 0x0000, 0x8108,
+ 0x1f04, 0x5ab5, 0x60c3, 0x0014, 0x080c, 0x6007, 0x00fe, 0x0005,
+ 0x00f6, 0x7090, 0x9005, 0x0500, 0x2011, 0x5fdd, 0x080c, 0x882c,
+ 0x9086, 0x0014, 0x11b8, 0x080c, 0x6152, 0x2079, 0x0260, 0x7a30,
+ 0x9296, 0x1102, 0x1178, 0x7834, 0x9005, 0x1160, 0x7a38, 0xd2fc,
+ 0x0128, 0x70c4, 0x9005, 0x1110, 0x70c7, 0x0001, 0x709b, 0x0004,
+ 0x0029, 0x0010, 0x080c, 0x612e, 0x00fe, 0x0005, 0x00f6, 0x709b,
+ 0x0005, 0x080c, 0x60d6, 0x2079, 0x0240, 0x7833, 0x1103, 0x7837,
+ 0x0000, 0x080c, 0x6152, 0x080c, 0x6135, 0x1170, 0x7084, 0x9005,
+ 0x1158, 0x715c, 0x9186, 0xffff, 0x0138, 0x2011, 0x0008, 0x080c,
+ 0x5f8a, 0x0168, 0x080c, 0x610b, 0x20a9, 0x0008, 0x20e1, 0x0000,
+ 0x2099, 0x026e, 0x20e9, 0x0000, 0x20a1, 0x024e, 0x4003, 0x60c3,
+ 0x0014, 0x080c, 0x6007, 0x00fe, 0x0005, 0x00f6, 0x7090, 0x9005,
+ 0x0500, 0x2011, 0x5fdd, 0x080c, 0x882c, 0x9086, 0x0014, 0x11b8,
+ 0x080c, 0x6152, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1103, 0x1178,
+ 0x7834, 0x9005, 0x1160, 0x7a38, 0xd2fc, 0x0128, 0x70c4, 0x9005,
+ 0x1110, 0x70c7, 0x0001, 0x709b, 0x0006, 0x0029, 0x0010, 0x080c,
+ 0x612e, 0x00fe, 0x0005, 0x00f6, 0x709b, 0x0007, 0x080c, 0x60d6,
+ 0x2079, 0x0240, 0x7833, 0x1104, 0x7837, 0x0000, 0x080c, 0x6152,
+ 0x080c, 0x6135, 0x11b8, 0x7084, 0x9005, 0x11a0, 0x7164, 0x9186,
+ 0xffff, 0x0180, 0x9180, 0x3474, 0x200d, 0x918c, 0xff00, 0x810f,
+ 0x2011, 0x0008, 0x080c, 0x5f8a, 0x0180, 0x080c, 0x510e, 0x0110,
+ 0x080c, 0x270a, 0x20a9, 0x0008, 0x20e1, 0x0000, 0x2099, 0x026e,
+ 0x20e9, 0x0000, 0x20a1, 0x024e, 0x4003, 0x60c3, 0x0014, 0x080c,
+ 0x6007, 0x00fe, 0x0005, 0x00f6, 0x7090, 0x9005, 0x0500, 0x2011,
+ 0x5fdd, 0x080c, 0x882c, 0x9086, 0x0014, 0x11b8, 0x080c, 0x6152,
+ 0x2079, 0x0260, 0x7a30, 0x9296, 0x1104, 0x1178, 0x7834, 0x9005,
+ 0x1160, 0x7a38, 0xd2fc, 0x0128, 0x70c4, 0x9005, 0x1110, 0x70c7,
+ 0x0001, 0x709b, 0x0008, 0x0029, 0x0010, 0x080c, 0x612e, 0x00fe,
+ 0x0005, 0x00f6, 0x709b, 0x0009, 0x080c, 0x60d6, 0x2079, 0x0240,
+ 0x7833, 0x1105, 0x7837, 0x0100, 0x080c, 0x6135, 0x1150, 0x7084,
+ 0x9005, 0x1138, 0x080c, 0x5efd, 0x1188, 0x9085, 0x0001, 0x080c,
+ 0x270a, 0x20a9, 0x0008, 0x080c, 0x6152, 0x20e1, 0x0000, 0x2099,
+ 0x026e, 0x20e9, 0x0000, 0x20a1, 0x024e, 0x4003, 0x60c3, 0x0014,
+ 0x080c, 0x6007, 0x0010, 0x080c, 0x5a57, 0x00fe, 0x0005, 0x00f6,
+ 0x7090, 0x9005, 0x05a8, 0x2011, 0x5fdd, 0x080c, 0x882c, 0x9086,
+ 0x0014, 0x1560, 0x080c, 0x6152, 0x2079, 0x0260, 0x7a30, 0x9296,
+ 0x1105, 0x1520, 0x7834, 0x9084, 0x0100, 0x2011, 0x0100, 0x921e,
+ 0x1160, 0x7a38, 0xd2fc, 0x0128, 0x70c4, 0x9005, 0x1110, 0x70c7,
+ 0x0001, 0x709b, 0x000a, 0x00b1, 0x0098, 0x9005, 0x1178, 0x7a38,
+ 0xd2fc, 0x0128, 0x70c4, 0x9005, 0x1110, 0x70c7, 0x0001, 0x7097,
+ 0x0000, 0x709b, 0x000e, 0x080c, 0x5ca5, 0x0010, 0x080c, 0x612e,
+ 0x00fe, 0x0005, 0x00f6, 0x709b, 0x000b, 0x2011, 0x1d0e, 0x20e9,
+ 0x0001, 0x22a0, 0x20a9, 0x0040, 0x2019, 0xffff, 0x4304, 0x080c,
+ 0x60d6, 0x2079, 0x0240, 0x7833, 0x1106, 0x7837, 0x0000, 0x080c,
+ 0x6135, 0x0118, 0x2013, 0x0000, 0x0020, 0x7060, 0x9085, 0x0100,
+ 0x2012, 0x20a9, 0x0040, 0x2009, 0x024e, 0x2011, 0x1d0e, 0x220e,
+ 0x8210, 0x8108, 0x9186, 0x0260, 0x1128, 0x6810, 0x8000, 0x6812,
+ 0x2009, 0x0240, 0x1f04, 0x5c27, 0x60c3, 0x0084, 0x080c, 0x6007,
+ 0x00fe, 0x0005, 0x00f6, 0x7090, 0x9005, 0x01c0, 0x2011, 0x5fdd,
+ 0x080c, 0x882c, 0x9086, 0x0084, 0x1178, 0x080c, 0x6152, 0x2079,
+ 0x0260, 0x7a30, 0x9296, 0x1106, 0x1138, 0x7834, 0x9005, 0x1120,
+ 0x709b, 0x000c, 0x0029, 0x0010, 0x080c, 0x612e, 0x00fe, 0x0005,
+ 0x00f6, 0x709b, 0x000d, 0x080c, 0x60d6, 0x2079, 0x0240, 0x7833,
+ 0x1107, 0x7837, 0x0000, 0x080c, 0x6152, 0x20a9, 0x0040, 0x2011,
+ 0x026e, 0x2009, 0x024e, 0x220e, 0x8210, 0x8108, 0x9186, 0x0260,
+ 0x1150, 0x6810, 0x8000, 0x6812, 0x2009, 0x0240, 0x6814, 0x8000,
+ 0x6816, 0x2011, 0x0260, 0x1f04, 0x5c6b, 0x60c3, 0x0084, 0x080c,
+ 0x6007, 0x00fe, 0x0005, 0x00f6, 0x7090, 0x9005, 0x01e0, 0x2011,
+ 0x5fdd, 0x080c, 0x882c, 0x9086, 0x0084, 0x1198, 0x080c, 0x6152,
+ 0x2079, 0x0260, 0x7a30, 0x9296, 0x1107, 0x1158, 0x7834, 0x9005,
+ 0x1140, 0x7097, 0x0001, 0x080c, 0x60a8, 0x709b, 0x000e, 0x0029,
+ 0x0010, 0x080c, 0x612e, 0x00fe, 0x0005, 0x918d, 0x0001, 0x080c,
+ 0x617d, 0x709b, 0x000f, 0x7093, 0x0000, 0x2061, 0x0140, 0x605b,
+ 0xbc85, 0x605f, 0xb5b5, 0x2061, 0x0100, 0x6043, 0x0005, 0x6043,
+ 0x0004, 0x2009, 0x07d0, 0x2011, 0x5fdd, 0x080c, 0x8820, 0x0005,
+ 0x7090, 0x9005, 0x0130, 0x2011, 0x5fdd, 0x080c, 0x882c, 0x709b,
+ 0x0000, 0x0005, 0x709b, 0x0011, 0x080c, 0xa8ec, 0x080c, 0x6152,
+ 0x20e1, 0x0000, 0x2099, 0x0260, 0x20e9, 0x0000, 0x20a1, 0x0240,
+ 0x7490, 0x9480, 0x0018, 0x9080, 0x0007, 0x9084, 0x03f8, 0x8004,
+ 0x20a8, 0x4003, 0x080c, 0x6135, 0x11a0, 0x717c, 0x81ff, 0x0188,
+ 0x900e, 0x7080, 0x9084, 0x00ff, 0x0160, 0x080c, 0x26a1, 0x9186,
+ 0x007e, 0x0138, 0x9186, 0x0080, 0x0120, 0x2011, 0x0008, 0x080c,
+ 0x5f8a, 0x60c3, 0x0014, 0x080c, 0x6007, 0x0005, 0x00f6, 0x7090,
+ 0x9005, 0x0500, 0x2011, 0x5fdd, 0x080c, 0x882c, 0x9086, 0x0014,
+ 0x11b8, 0x080c, 0x6152, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1103,
0x1178, 0x7834, 0x9005, 0x1160, 0x7a38, 0xd2fc, 0x0128, 0x70c4,
- 0x9005, 0x1110, 0x70c7, 0x0001, 0x709b, 0x0004, 0x0029, 0x0010,
- 0x080c, 0x6134, 0x00fe, 0x0005, 0x00f6, 0x709b, 0x0005, 0x080c,
- 0x60dc, 0x2079, 0x0240, 0x7833, 0x1103, 0x7837, 0x0000, 0x080c,
- 0x6158, 0x080c, 0x613b, 0x1170, 0x7084, 0x9005, 0x1158, 0x715c,
- 0x9186, 0xffff, 0x0138, 0x2011, 0x0008, 0x080c, 0x5f90, 0x0168,
- 0x080c, 0x6111, 0x20a9, 0x0008, 0x20e1, 0x0000, 0x2099, 0x026e,
+ 0x9005, 0x1110, 0x70c7, 0x0001, 0x709b, 0x0012, 0x0029, 0x0010,
+ 0x7093, 0x0000, 0x00fe, 0x0005, 0x00f6, 0x709b, 0x0013, 0x080c,
+ 0x60e4, 0x2079, 0x0240, 0x7833, 0x1103, 0x7837, 0x0000, 0x080c,
+ 0x6152, 0x080c, 0x6135, 0x1170, 0x7084, 0x9005, 0x1158, 0x715c,
+ 0x9186, 0xffff, 0x0138, 0x2011, 0x0008, 0x080c, 0x5f8a, 0x0168,
+ 0x080c, 0x610b, 0x20a9, 0x0008, 0x20e1, 0x0000, 0x2099, 0x026e,
0x20e9, 0x0000, 0x20a1, 0x024e, 0x4003, 0x60c3, 0x0014, 0x080c,
- 0x600d, 0x00fe, 0x0005, 0x00f6, 0x7090, 0x9005, 0x0500, 0x2011,
- 0x5fe3, 0x080c, 0x8834, 0x9086, 0x0014, 0x11b8, 0x080c, 0x6158,
- 0x2079, 0x0260, 0x7a30, 0x9296, 0x1103, 0x1178, 0x7834, 0x9005,
+ 0x6007, 0x00fe, 0x0005, 0x00f6, 0x7090, 0x9005, 0x0500, 0x2011,
+ 0x5fdd, 0x080c, 0x882c, 0x9086, 0x0014, 0x11b8, 0x080c, 0x6152,
+ 0x2079, 0x0260, 0x7a30, 0x9296, 0x1104, 0x1178, 0x7834, 0x9005,
0x1160, 0x7a38, 0xd2fc, 0x0128, 0x70c4, 0x9005, 0x1110, 0x70c7,
- 0x0001, 0x709b, 0x0006, 0x0029, 0x0010, 0x080c, 0x6134, 0x00fe,
- 0x0005, 0x00f6, 0x709b, 0x0007, 0x080c, 0x60dc, 0x2079, 0x0240,
- 0x7833, 0x1104, 0x7837, 0x0000, 0x080c, 0x6158, 0x080c, 0x613b,
+ 0x0001, 0x709b, 0x0014, 0x0029, 0x0010, 0x7093, 0x0000, 0x00fe,
+ 0x0005, 0x00f6, 0x709b, 0x0015, 0x080c, 0x60e4, 0x2079, 0x0240,
+ 0x7833, 0x1104, 0x7837, 0x0000, 0x080c, 0x6152, 0x080c, 0x6135,
0x11b8, 0x7084, 0x9005, 0x11a0, 0x7164, 0x9186, 0xffff, 0x0180,
- 0x9180, 0x3489, 0x200d, 0x918c, 0xff00, 0x810f, 0x2011, 0x0008,
- 0x080c, 0x5f90, 0x0180, 0x080c, 0x5114, 0x0110, 0x080c, 0x270b,
+ 0x9180, 0x3474, 0x200d, 0x918c, 0xff00, 0x810f, 0x2011, 0x0008,
+ 0x080c, 0x5f8a, 0x0180, 0x080c, 0x510e, 0x0110, 0x080c, 0x270a,
0x20a9, 0x0008, 0x20e1, 0x0000, 0x2099, 0x026e, 0x20e9, 0x0000,
- 0x20a1, 0x024e, 0x4003, 0x60c3, 0x0014, 0x080c, 0x600d, 0x00fe,
- 0x0005, 0x00f6, 0x7090, 0x9005, 0x0500, 0x2011, 0x5fe3, 0x080c,
- 0x8834, 0x9086, 0x0014, 0x11b8, 0x080c, 0x6158, 0x2079, 0x0260,
- 0x7a30, 0x9296, 0x1104, 0x1178, 0x7834, 0x9005, 0x1160, 0x7a38,
- 0xd2fc, 0x0128, 0x70c4, 0x9005, 0x1110, 0x70c7, 0x0001, 0x709b,
- 0x0008, 0x0029, 0x0010, 0x080c, 0x6134, 0x00fe, 0x0005, 0x00f6,
- 0x709b, 0x0009, 0x080c, 0x60dc, 0x2079, 0x0240, 0x7833, 0x1105,
- 0x7837, 0x0100, 0x080c, 0x613b, 0x1150, 0x7084, 0x9005, 0x1138,
- 0x080c, 0x5f03, 0x1188, 0x9085, 0x0001, 0x080c, 0x270b, 0x20a9,
- 0x0008, 0x080c, 0x6158, 0x20e1, 0x0000, 0x2099, 0x026e, 0x20e9,
- 0x0000, 0x20a1, 0x024e, 0x4003, 0x60c3, 0x0014, 0x080c, 0x600d,
- 0x0010, 0x080c, 0x5a5d, 0x00fe, 0x0005, 0x00f6, 0x7090, 0x9005,
- 0x05a8, 0x2011, 0x5fe3, 0x080c, 0x8834, 0x9086, 0x0014, 0x1560,
- 0x080c, 0x6158, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1105, 0x1520,
- 0x7834, 0x9084, 0x0100, 0x2011, 0x0100, 0x921e, 0x1160, 0x7a38,
- 0xd2fc, 0x0128, 0x70c4, 0x9005, 0x1110, 0x70c7, 0x0001, 0x709b,
- 0x000a, 0x00b1, 0x0098, 0x9005, 0x1178, 0x7a38, 0xd2fc, 0x0128,
- 0x70c4, 0x9005, 0x1110, 0x70c7, 0x0001, 0x7097, 0x0000, 0x709b,
- 0x000e, 0x080c, 0x5cab, 0x0010, 0x080c, 0x6134, 0x00fe, 0x0005,
- 0x00f6, 0x709b, 0x000b, 0x2011, 0x1d0e, 0x20e9, 0x0001, 0x22a0,
- 0x20a9, 0x0040, 0x2019, 0xffff, 0x4304, 0x080c, 0x60dc, 0x2079,
- 0x0240, 0x7833, 0x1106, 0x7837, 0x0000, 0x080c, 0x613b, 0x0118,
- 0x2013, 0x0000, 0x0020, 0x7060, 0x9085, 0x0100, 0x2012, 0x20a9,
- 0x0040, 0x2009, 0x024e, 0x2011, 0x1d0e, 0x220e, 0x8210, 0x8108,
- 0x9186, 0x0260, 0x1128, 0x6810, 0x8000, 0x6812, 0x2009, 0x0240,
- 0x1f04, 0x5c2d, 0x60c3, 0x0084, 0x080c, 0x600d, 0x00fe, 0x0005,
- 0x00f6, 0x7090, 0x9005, 0x01c0, 0x2011, 0x5fe3, 0x080c, 0x8834,
- 0x9086, 0x0084, 0x1178, 0x080c, 0x6158, 0x2079, 0x0260, 0x7a30,
- 0x9296, 0x1106, 0x1138, 0x7834, 0x9005, 0x1120, 0x709b, 0x000c,
- 0x0029, 0x0010, 0x080c, 0x6134, 0x00fe, 0x0005, 0x00f6, 0x709b,
- 0x000d, 0x080c, 0x60dc, 0x2079, 0x0240, 0x7833, 0x1107, 0x7837,
- 0x0000, 0x080c, 0x6158, 0x20a9, 0x0040, 0x2011, 0x026e, 0x2009,
- 0x024e, 0x220e, 0x8210, 0x8108, 0x9186, 0x0260, 0x1150, 0x6810,
- 0x8000, 0x6812, 0x2009, 0x0240, 0x6814, 0x8000, 0x6816, 0x2011,
- 0x0260, 0x1f04, 0x5c71, 0x60c3, 0x0084, 0x080c, 0x600d, 0x00fe,
- 0x0005, 0x00f6, 0x7090, 0x9005, 0x01e0, 0x2011, 0x5fe3, 0x080c,
- 0x8834, 0x9086, 0x0084, 0x1198, 0x080c, 0x6158, 0x2079, 0x0260,
- 0x7a30, 0x9296, 0x1107, 0x1158, 0x7834, 0x9005, 0x1140, 0x7097,
- 0x0001, 0x080c, 0x60ae, 0x709b, 0x000e, 0x0029, 0x0010, 0x080c,
- 0x6134, 0x00fe, 0x0005, 0x918d, 0x0001, 0x080c, 0x6183, 0x709b,
- 0x000f, 0x7093, 0x0000, 0x2061, 0x0140, 0x605b, 0xbc85, 0x605f,
- 0xb5b5, 0x2061, 0x0100, 0x6043, 0x0005, 0x6043, 0x0004, 0x2009,
- 0x07d0, 0x2011, 0x5fe3, 0x080c, 0x8828, 0x0005, 0x7090, 0x9005,
- 0x0130, 0x2011, 0x5fe3, 0x080c, 0x8834, 0x709b, 0x0000, 0x0005,
- 0x709b, 0x0011, 0x080c, 0xa8d5, 0x080c, 0x6158, 0x20e1, 0x0000,
- 0x2099, 0x0260, 0x20e9, 0x0000, 0x20a1, 0x0240, 0x7490, 0x9480,
- 0x0018, 0x9080, 0x0007, 0x9084, 0x03f8, 0x8004, 0x20a8, 0x4003,
- 0x080c, 0x613b, 0x11a0, 0x717c, 0x81ff, 0x0188, 0x900e, 0x7080,
- 0x9084, 0x00ff, 0x0160, 0x080c, 0x26a2, 0x9186, 0x007e, 0x0138,
- 0x9186, 0x0080, 0x0120, 0x2011, 0x0008, 0x080c, 0x5f90, 0x60c3,
- 0x0014, 0x080c, 0x600d, 0x0005, 0x00f6, 0x7090, 0x9005, 0x0500,
- 0x2011, 0x5fe3, 0x080c, 0x8834, 0x9086, 0x0014, 0x11b8, 0x080c,
- 0x6158, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1103, 0x1178, 0x7834,
- 0x9005, 0x1160, 0x7a38, 0xd2fc, 0x0128, 0x70c4, 0x9005, 0x1110,
- 0x70c7, 0x0001, 0x709b, 0x0012, 0x0029, 0x0010, 0x7093, 0x0000,
- 0x00fe, 0x0005, 0x00f6, 0x709b, 0x0013, 0x080c, 0x60ea, 0x2079,
- 0x0240, 0x7833, 0x1103, 0x7837, 0x0000, 0x080c, 0x6158, 0x080c,
- 0x613b, 0x1170, 0x7084, 0x9005, 0x1158, 0x715c, 0x9186, 0xffff,
- 0x0138, 0x2011, 0x0008, 0x080c, 0x5f90, 0x0168, 0x080c, 0x6111,
- 0x20a9, 0x0008, 0x20e1, 0x0000, 0x2099, 0x026e, 0x20e9, 0x0000,
- 0x20a1, 0x024e, 0x4003, 0x60c3, 0x0014, 0x080c, 0x600d, 0x00fe,
- 0x0005, 0x00f6, 0x7090, 0x9005, 0x0500, 0x2011, 0x5fe3, 0x080c,
- 0x8834, 0x9086, 0x0014, 0x11b8, 0x080c, 0x6158, 0x2079, 0x0260,
- 0x7a30, 0x9296, 0x1104, 0x1178, 0x7834, 0x9005, 0x1160, 0x7a38,
- 0xd2fc, 0x0128, 0x70c4, 0x9005, 0x1110, 0x70c7, 0x0001, 0x709b,
- 0x0014, 0x0029, 0x0010, 0x7093, 0x0000, 0x00fe, 0x0005, 0x00f6,
- 0x709b, 0x0015, 0x080c, 0x60ea, 0x2079, 0x0240, 0x7833, 0x1104,
- 0x7837, 0x0000, 0x080c, 0x6158, 0x080c, 0x613b, 0x11b8, 0x7084,
- 0x9005, 0x11a0, 0x7164, 0x9186, 0xffff, 0x0180, 0x9180, 0x3489,
- 0x200d, 0x918c, 0xff00, 0x810f, 0x2011, 0x0008, 0x080c, 0x5f90,
- 0x0180, 0x080c, 0x5114, 0x0110, 0x080c, 0x270b, 0x20a9, 0x0008,
- 0x20e1, 0x0000, 0x2099, 0x026e, 0x20e9, 0x0000, 0x20a1, 0x024e,
- 0x4003, 0x60c3, 0x0014, 0x080c, 0x600d, 0x00fe, 0x0005, 0x00f6,
- 0x7090, 0x9005, 0x05f0, 0x2011, 0x5fe3, 0x080c, 0x8834, 0x9086,
- 0x0014, 0x15a8, 0x080c, 0x6158, 0x2079, 0x0260, 0x7a30, 0x9296,
- 0x1105, 0x1568, 0x7834, 0x9084, 0x0100, 0x2011, 0x0100, 0x921e,
- 0x1168, 0x9085, 0x0001, 0x080c, 0x6183, 0x7a38, 0xd2fc, 0x0128,
- 0x70c4, 0x9005, 0x1110, 0x70c7, 0x0001, 0x0080, 0x9005, 0x11b8,
- 0x7a38, 0xd2fc, 0x0128, 0x70c4, 0x9005, 0x1110, 0x70c7, 0x0001,
- 0x9085, 0x0001, 0x080c, 0x6183, 0x7097, 0x0000, 0x7a38, 0xd2f4,
- 0x0110, 0x70df, 0x0008, 0x709b, 0x0016, 0x0029, 0x0010, 0x7093,
- 0x0000, 0x00fe, 0x0005, 0x080c, 0xa8d5, 0x080c, 0x6158, 0x20e1,
- 0x0000, 0x2099, 0x0260, 0x20e9, 0x0000, 0x20a1, 0x0240, 0x20a9,
- 0x000e, 0x4003, 0x2011, 0x026d, 0x2204, 0x9084, 0x0100, 0x2011,
- 0x024d, 0x2012, 0x2011, 0x026e, 0x709b, 0x0017, 0x080c, 0x613b,
- 0x1150, 0x7084, 0x9005, 0x1138, 0x080c, 0x5f03, 0x1188, 0x9085,
- 0x0001, 0x080c, 0x270b, 0x20a9, 0x0008, 0x080c, 0x6158, 0x20e1,
- 0x0000, 0x2099, 0x026e, 0x20e9, 0x0000, 0x20a1, 0x024e, 0x4003,
- 0x60c3, 0x0014, 0x080c, 0x600d, 0x0010, 0x080c, 0x5a5d, 0x0005,
- 0x00f6, 0x7090, 0x9005, 0x01d8, 0x2011, 0x5fe3, 0x080c, 0x8834,
- 0x9086, 0x0084, 0x1190, 0x080c, 0x6158, 0x2079, 0x0260, 0x7a30,
- 0x9296, 0x1106, 0x1150, 0x7834, 0x9005, 0x1138, 0x9006, 0x080c,
- 0x6183, 0x709b, 0x0018, 0x0029, 0x0010, 0x7093, 0x0000, 0x00fe,
- 0x0005, 0x00f6, 0x709b, 0x0019, 0x080c, 0x60ea, 0x2079, 0x0240,
- 0x7833, 0x1106, 0x7837, 0x0000, 0x080c, 0x6158, 0x2009, 0x026e,
- 0x2039, 0x1d0e, 0x20a9, 0x0040, 0x213e, 0x8738, 0x8108, 0x9186,
- 0x0280, 0x1128, 0x6814, 0x8000, 0x6816, 0x2009, 0x0260, 0x1f04,
- 0x5e6c, 0x2039, 0x1d0e, 0x080c, 0x613b, 0x11e8, 0x2728, 0x2514,
- 0x8207, 0x9084, 0x00ff, 0x8000, 0x2018, 0x9294, 0x00ff, 0x8007,
- 0x9205, 0x202a, 0x7060, 0x2310, 0x8214, 0x92a0, 0x1d0e, 0x2414,
- 0x938c, 0x0001, 0x0118, 0x9294, 0xff00, 0x0018, 0x9294, 0x00ff,
- 0x8007, 0x9215, 0x2222, 0x20a9, 0x0040, 0x2009, 0x024e, 0x270e,
- 0x8738, 0x8108, 0x9186, 0x0260, 0x1128, 0x6810, 0x8000, 0x6812,
- 0x2009, 0x0240, 0x1f04, 0x5e9f, 0x60c3, 0x0084, 0x080c, 0x600d,
- 0x00fe, 0x0005, 0x00f6, 0x7090, 0x9005, 0x01e0, 0x2011, 0x5fe3,
- 0x080c, 0x8834, 0x9086, 0x0084, 0x1198, 0x080c, 0x6158, 0x2079,
- 0x0260, 0x7a30, 0x9296, 0x1107, 0x1158, 0x7834, 0x9005, 0x1140,
- 0x7097, 0x0001, 0x080c, 0x60ae, 0x709b, 0x001a, 0x0029, 0x0010,
- 0x7093, 0x0000, 0x00fe, 0x0005, 0x9085, 0x0001, 0x080c, 0x6183,
- 0x709b, 0x001b, 0x080c, 0xa8d5, 0x080c, 0x6158, 0x2011, 0x0260,
- 0x2009, 0x0240, 0x7490, 0x9480, 0x0018, 0x9080, 0x0007, 0x9084,
- 0x03f8, 0x8004, 0x20a8, 0x220e, 0x8210, 0x8108, 0x9186, 0x0260,
- 0x1150, 0x6810, 0x8000, 0x6812, 0x2009, 0x0240, 0x6814, 0x8000,
- 0x6816, 0x2011, 0x0260, 0x1f04, 0x5eeb, 0x60c3, 0x0084, 0x080c,
- 0x600d, 0x0005, 0x0005, 0x0086, 0x0096, 0x2029, 0x1848, 0x252c,
- 0x20a9, 0x0008, 0x2041, 0x1d0e, 0x20e9, 0x0001, 0x28a0, 0x080c,
- 0x6158, 0x20e1, 0x0000, 0x2099, 0x026e, 0x4003, 0x20a9, 0x0008,
- 0x2011, 0x0007, 0xd5d4, 0x0108, 0x9016, 0x2800, 0x9200, 0x200c,
- 0x91a6, 0xffff, 0x1148, 0xd5d4, 0x0110, 0x8210, 0x0008, 0x8211,
- 0x1f04, 0x5f1d, 0x0804, 0x5f8c, 0x82ff, 0x1160, 0xd5d4, 0x0120,
- 0x91a6, 0x3fff, 0x0d90, 0x0020, 0x91a6, 0x3fff, 0x0904, 0x5f8c,
- 0x918d, 0xc000, 0x20a9, 0x0010, 0x2019, 0x0001, 0xd5d4, 0x0110,
- 0x2019, 0x0010, 0x2120, 0xd5d4, 0x0110, 0x8423, 0x0008, 0x8424,
- 0x1240, 0xd5d4, 0x0110, 0x8319, 0x0008, 0x8318, 0x1f04, 0x5f43,
- 0x04d8, 0x23a8, 0x2021, 0x0001, 0x8426, 0x8425, 0x1f04, 0x5f55,
- 0x2328, 0x8529, 0x92be, 0x0007, 0x0158, 0x0006, 0x2039, 0x0007,
- 0x2200, 0x973a, 0x000e, 0x27a8, 0x95a8, 0x0010, 0x1f04, 0x5f64,
- 0x755e, 0x95c8, 0x3489, 0x292d, 0x95ac, 0x00ff, 0x7582, 0x6532,
- 0x6536, 0x0016, 0x2508, 0x080c, 0x26eb, 0x001e, 0x60e7, 0x0000,
- 0x65ea, 0x2018, 0x2304, 0x9405, 0x201a, 0x7087, 0x0001, 0x20e9,
- 0x0000, 0x20a1, 0x024e, 0x20e1, 0x0001, 0x2898, 0x20a9, 0x0008,
- 0x4003, 0x9085, 0x0001, 0x0008, 0x9006, 0x009e, 0x008e, 0x0005,
- 0x0156, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x22a8, 0x20e1, 0x0000,
- 0x2099, 0x026e, 0x20e9, 0x0000, 0x2011, 0x024e, 0x22a0, 0x4003,
- 0x014e, 0x013e, 0x01de, 0x01ce, 0x015e, 0x2118, 0x9026, 0x2001,
- 0x0007, 0x939a, 0x0010, 0x0218, 0x8420, 0x8001, 0x0cd0, 0x2118,
- 0x84ff, 0x0120, 0x939a, 0x0010, 0x8421, 0x1de0, 0x2021, 0x0001,
- 0x83ff, 0x0118, 0x8423, 0x8319, 0x1de8, 0x9238, 0x2029, 0x026e,
- 0x9528, 0x2504, 0x942c, 0x11b8, 0x9405, 0x203a, 0x715e, 0x91a0,
- 0x3489, 0x242d, 0x95ac, 0x00ff, 0x7582, 0x6532, 0x6536, 0x0016,
- 0x2508, 0x080c, 0x26eb, 0x001e, 0x60e7, 0x0000, 0x65ea, 0x7087,
- 0x0001, 0x9084, 0x0000, 0x0005, 0x00e6, 0x2071, 0x1800, 0x708b,
- 0x0000, 0x00ee, 0x0005, 0x00e6, 0x00f6, 0x2079, 0x0100, 0x2071,
- 0x0140, 0x080c, 0x609d, 0x080c, 0xa08a, 0x7004, 0x9084, 0x4000,
- 0x0110, 0x080c, 0x2acb, 0x0126, 0x2091, 0x8000, 0x2071, 0x1826,
- 0x2073, 0x0000, 0x7840, 0x0026, 0x0016, 0x2009, 0x00f7, 0x080c,
- 0x60fa, 0x001e, 0x9094, 0x0010, 0x9285, 0x0080, 0x7842, 0x7a42,
- 0x002e, 0x012e, 0x00fe, 0x00ee, 0x0005, 0x0126, 0x2091, 0x8000,
- 0x080c, 0x2a26, 0x0228, 0x2011, 0x0101, 0x2204, 0xc0c5, 0x2012,
- 0x2011, 0x19f6, 0x2013, 0x0000, 0x7093, 0x0000, 0x012e, 0x60a3,
- 0x0056, 0x60a7, 0x9575, 0x080c, 0xa07d, 0x6144, 0xd184, 0x0120,
- 0x7198, 0x918d, 0x2000, 0x0018, 0x718c, 0x918d, 0x1000, 0x2011,
- 0x199a, 0x2112, 0x2009, 0x07d0, 0x2011, 0x5fe3, 0x080c, 0x88fe,
- 0x0005, 0x0016, 0x0026, 0x00c6, 0x0126, 0x2091, 0x8000, 0x080c,
- 0xaae0, 0x080c, 0xae67, 0x080c, 0xaafc, 0x2009, 0x00f7, 0x080c,
- 0x60fa, 0x2061, 0x1a05, 0x900e, 0x611a, 0x611e, 0x617a, 0x617e,
- 0x2061, 0x1800, 0x6003, 0x0001, 0x2061, 0x0100, 0x6043, 0x0090,
- 0x6043, 0x0010, 0x2009, 0x199a, 0x200b, 0x0000, 0x2009, 0x002d,
- 0x2011, 0x6069, 0x080c, 0x8828, 0x012e, 0x00ce, 0x002e, 0x001e,
- 0x0005, 0x00e6, 0x0006, 0x0126, 0x2091, 0x8000, 0x0471, 0x2071,
- 0x0100, 0x080c, 0xa08a, 0x2071, 0x0140, 0x7004, 0x9084, 0x4000,
- 0x0110, 0x080c, 0x2acb, 0x080c, 0x76ad, 0x0188, 0x080c, 0x76c8,
- 0x1170, 0x080c, 0x79b1, 0x0016, 0x080c, 0x27ba, 0x2001, 0x196e,
- 0x2102, 0x001e, 0x080c, 0x79ac, 0x080c, 0x75d4, 0x0050, 0x2009,
- 0x0001, 0x080c, 0x2aa7, 0x2001, 0x0001, 0x080c, 0x2647, 0x080c,
- 0x6039, 0x012e, 0x000e, 0x00ee, 0x0005, 0x2001, 0x180e, 0x2004,
- 0xd0bc, 0x0158, 0x0026, 0x0036, 0x2011, 0x8017, 0x2001, 0x199a,
- 0x201c, 0x080c, 0x4c2e, 0x003e, 0x002e, 0x0005, 0x20a9, 0x0012,
- 0x20e9, 0x0001, 0x20a1, 0x1d80, 0x080c, 0x6158, 0x20e9, 0x0000,
- 0x2099, 0x026e, 0x0099, 0x20a9, 0x0020, 0x080c, 0x6152, 0x2099,
- 0x0260, 0x20a1, 0x1d92, 0x0051, 0x20a9, 0x000e, 0x080c, 0x6155,
- 0x2099, 0x0260, 0x20a1, 0x1db2, 0x0009, 0x0005, 0x0016, 0x0026,
- 0x3410, 0x3308, 0x2104, 0x8007, 0x2012, 0x8108, 0x8210, 0x1f04,
- 0x60d2, 0x002e, 0x001e, 0x0005, 0x080c, 0xa8d5, 0x20e1, 0x0001,
- 0x2099, 0x1d00, 0x20e9, 0x0000, 0x20a1, 0x0240, 0x20a9, 0x000c,
- 0x4003, 0x0005, 0x080c, 0xa8d5, 0x080c, 0x6158, 0x20e1, 0x0000,
- 0x2099, 0x0260, 0x20e9, 0x0000, 0x20a1, 0x0240, 0x20a9, 0x000c,
- 0x4003, 0x0005, 0x00c6, 0x0006, 0x2061, 0x0100, 0x810f, 0x2001,
- 0x1834, 0x2004, 0x9005, 0x1138, 0x2001, 0x1818, 0x2004, 0x9084,
- 0x00ff, 0x9105, 0x0010, 0x9185, 0x00f7, 0x604a, 0x000e, 0x00ce,
- 0x0005, 0x0016, 0x0046, 0x080c, 0x6bd1, 0x0158, 0x9006, 0x2020,
- 0x2009, 0x002a, 0x080c, 0xe72a, 0x2001, 0x180c, 0x200c, 0xc195,
- 0x2102, 0x2019, 0x002a, 0x900e, 0x080c, 0x32d5, 0x080c, 0xd33e,
- 0x0140, 0x0036, 0x2019, 0xffff, 0x2021, 0x0007, 0x080c, 0x4de5,
- 0x003e, 0x004e, 0x001e, 0x0005, 0x080c, 0x6039, 0x709b, 0x0000,
- 0x7093, 0x0000, 0x0005, 0x0006, 0x2001, 0x180c, 0x2004, 0xd09c,
- 0x0100, 0x000e, 0x0005, 0x0006, 0x0016, 0x0126, 0x2091, 0x8000,
- 0x2001, 0x0101, 0x200c, 0x918d, 0x0006, 0x2102, 0x012e, 0x001e,
- 0x000e, 0x0005, 0x2009, 0x0001, 0x0020, 0x2009, 0x0002, 0x0008,
- 0x900e, 0x6814, 0x9084, 0xffc0, 0x910d, 0x6916, 0x0005, 0x00f6,
- 0x0156, 0x0146, 0x01d6, 0x9006, 0x20a9, 0x0080, 0x20e9, 0x0001,
- 0x20a1, 0x1d00, 0x4004, 0x2079, 0x1d00, 0x7803, 0x2200, 0x7807,
- 0x00ef, 0x780f, 0x00ef, 0x7813, 0x0138, 0x7823, 0xffff, 0x7827,
- 0xffff, 0x01de, 0x014e, 0x015e, 0x00fe, 0x0005, 0x2001, 0x1800,
- 0x2003, 0x0001, 0x0005, 0x2001, 0x19a7, 0x0118, 0x2003, 0x0001,
- 0x0010, 0x2003, 0x0000, 0x0005, 0x0156, 0x20a9, 0x0800, 0x2009,
- 0x1000, 0x9006, 0x200a, 0x8108, 0x1f04, 0x6192, 0x015e, 0x0005,
- 0x00d6, 0x0036, 0x0156, 0x0136, 0x0146, 0x2069, 0x1847, 0x9006,
- 0xb802, 0xb8d6, 0xb807, 0x0707, 0xb80a, 0xb80e, 0xb812, 0x9198,
- 0x3489, 0x231d, 0x939c, 0x00ff, 0xbb16, 0x0016, 0x0026, 0xb886,
- 0x080c, 0xae60, 0x1120, 0x9192, 0x007e, 0x1208, 0xbb86, 0x20a9,
- 0x0004, 0xb8c4, 0x20e8, 0xb9c8, 0x9198, 0x0006, 0x9006, 0x23a0,
- 0x4004, 0x20a9, 0x0004, 0x9198, 0x000a, 0x23a0, 0x4004, 0x002e,
- 0x001e, 0xb83e, 0xb842, 0xb8ce, 0xb8d2, 0xb85e, 0xb862, 0xb866,
- 0xb86a, 0xb86f, 0x0100, 0xb872, 0xb876, 0xb87a, 0xb88a, 0xb88e,
- 0xb893, 0x0008, 0xb896, 0xb89a, 0xb89e, 0xb8be, 0xb9a2, 0x0096,
- 0xb8a4, 0x904d, 0x0110, 0x080c, 0x108b, 0xb8a7, 0x0000, 0x009e,
- 0x9006, 0xb84a, 0x6810, 0xb83a, 0x680c, 0xb846, 0xb8bb, 0x0520,
- 0xb8ac, 0x9005, 0x0198, 0x00c6, 0x2060, 0x9c82, 0x1ddc, 0x0a0c,
- 0x0d85, 0x2001, 0x181a, 0x2004, 0x9c02, 0x1a0c, 0x0d85, 0x080c,
- 0x8d8f, 0x00ce, 0x090c, 0x9130, 0xb8af, 0x0000, 0x6814, 0x9084,
- 0x00ff, 0xb842, 0x014e, 0x013e, 0x015e, 0x003e, 0x00de, 0x0005,
- 0x0126, 0x2091, 0x8000, 0xa974, 0xae78, 0x9684, 0x3fff, 0x9082,
- 0x4000, 0x1a04, 0x626e, 0x9182, 0x0800, 0x1a04, 0x6272, 0x2001,
- 0x180c, 0x2004, 0x9084, 0x0003, 0x1904, 0x6278, 0x9188, 0x1000,
- 0x2104, 0x905d, 0x0198, 0xb804, 0x9084, 0x00ff, 0x908e, 0x0006,
- 0x1188, 0xb8a4, 0x900d, 0x1904, 0x628a, 0x080c, 0x664a, 0x9006,
- 0x012e, 0x0005, 0x2001, 0x0005, 0x900e, 0x04b8, 0x2001, 0x0028,
- 0x900e, 0x0498, 0x9082, 0x0006, 0x1290, 0x080c, 0xae60, 0x1160,
- 0xb8a0, 0x9084, 0xff80, 0x1140, 0xb900, 0xd1fc, 0x0d10, 0x2001,
- 0x0029, 0x2009, 0x1000, 0x0408, 0x2001, 0x0028, 0x00a8, 0x2009,
- 0x180c, 0x210c, 0xd18c, 0x0118, 0x2001, 0x0004, 0x0068, 0xd184,
- 0x0118, 0x2001, 0x0004, 0x0040, 0x2001, 0x0029, 0xb900, 0xd1fc,
- 0x0118, 0x2009, 0x1000, 0x0048, 0x900e, 0x0038, 0x2001, 0x0029,
- 0x900e, 0x0018, 0x2001, 0x0029, 0x900e, 0x9005, 0x012e, 0x0005,
- 0x2001, 0x180c, 0x2004, 0xd084, 0x19d0, 0x9188, 0x1000, 0x2104,
- 0x9065, 0x09a8, 0x080c, 0x6bd5, 0x1990, 0xb800, 0xd0bc, 0x0978,
- 0x0804, 0x6231, 0x080c, 0x69f8, 0x0904, 0x623a, 0x0804, 0x6235,
- 0x00e6, 0x2071, 0x19e9, 0x7004, 0x9086, 0x0002, 0x1128, 0x7030,
- 0x9080, 0x0004, 0x2004, 0x9b06, 0x00ee, 0x0005, 0x00b6, 0x00e6,
- 0x0126, 0x2091, 0x8000, 0xa874, 0x908e, 0x00ff, 0x1120, 0x2001,
- 0x196c, 0x205c, 0x0060, 0xa974, 0x9182, 0x0800, 0x1690, 0x9188,
- 0x1000, 0x2104, 0x905d, 0x01d0, 0x080c, 0x6b75, 0x11d0, 0x080c,
- 0xaed8, 0x0570, 0x2b00, 0x6012, 0x2900, 0x6016, 0x6023, 0x0009,
- 0x602b, 0x0000, 0xa874, 0x908e, 0x00ff, 0x1110, 0x602b, 0x8000,
- 0x2009, 0x0043, 0x080c, 0xafcc, 0x9006, 0x00b0, 0x2001, 0x0028,
- 0x0090, 0x2009, 0x180c, 0x210c, 0xd18c, 0x0118, 0x2001, 0x0004,
- 0x0038, 0xd184, 0x0118, 0x2001, 0x0004, 0x0010, 0x2001, 0x0029,
- 0x0010, 0x2001, 0x0029, 0x9005, 0x012e, 0x00ee, 0x00be, 0x0005,
- 0x2001, 0x002c, 0x0cc0, 0x00b6, 0x00e6, 0x0126, 0x2091, 0x8000,
- 0xa974, 0x9182, 0x0800, 0x1a04, 0x6369, 0x9188, 0x1000, 0x2104,
- 0x905d, 0x0904, 0x6341, 0xb8a0, 0x9086, 0x007f, 0x0190, 0xa87c,
- 0xd0fc, 0x1178, 0x080c, 0x6bdd, 0x0160, 0xa994, 0x81ff, 0x0130,
- 0x908e, 0x0004, 0x0130, 0x908e, 0x0005, 0x0118, 0x080c, 0x6bd5,
- 0x1598, 0xa87c, 0xd0fc, 0x01e0, 0xa894, 0x9005, 0x01c8, 0x2060,
- 0x0026, 0x2010, 0x080c, 0xcc04, 0x002e, 0x1120, 0x2001, 0x0008,
- 0x0804, 0x636b, 0x6020, 0x9086, 0x000a, 0x0120, 0x2001, 0x0008,
- 0x0804, 0x636b, 0x601a, 0x6003, 0x0008, 0x2900, 0x6016, 0x0058,
- 0x080c, 0xaed8, 0x05e8, 0x2b00, 0x6012, 0x2900, 0x6016, 0x600b,
- 0xffff, 0x6023, 0x000a, 0x2009, 0x0003, 0x080c, 0xafcc, 0x9006,
- 0x0458, 0x2001, 0x0028, 0x0438, 0x9082, 0x0006, 0x1290, 0x080c,
- 0xae60, 0x1160, 0xb8a0, 0x9084, 0xff80, 0x1140, 0xb900, 0xd1fc,
- 0x0900, 0x2001, 0x0029, 0x2009, 0x1000, 0x00a8, 0x2001, 0x0028,
- 0x0090, 0x2009, 0x180c, 0x210c, 0xd18c, 0x0118, 0x2001, 0x0004,
- 0x0050, 0xd184, 0x0118, 0x2001, 0x0004, 0x0028, 0x2001, 0x0029,
- 0x0010, 0x2001, 0x0029, 0x9005, 0x012e, 0x00ee, 0x00be, 0x0005,
- 0x2001, 0x002c, 0x0cc0, 0x00f6, 0x00b6, 0x0126, 0x2091, 0x8000,
- 0xa8e0, 0x9005, 0x1550, 0xa8dc, 0x9082, 0x0101, 0x1630, 0xa8c8,
- 0x9005, 0x1518, 0xa8c4, 0x9082, 0x0101, 0x12f8, 0xa974, 0x2079,
- 0x1800, 0x9182, 0x0800, 0x12e8, 0x7830, 0x9084, 0x0003, 0x1130,
- 0xaa98, 0xab94, 0xa878, 0x9084, 0x0007, 0x00ea, 0x7930, 0xd18c,
- 0x0118, 0x2001, 0x0004, 0x0038, 0xd184, 0x0118, 0x2001, 0x0004,
- 0x0010, 0x2001, 0x0029, 0x900e, 0x0038, 0x2001, 0x002c, 0x900e,
- 0x0018, 0x2001, 0x0029, 0x900e, 0x9006, 0x0008, 0x9005, 0x012e,
- 0x00be, 0x00fe, 0x0005, 0x6400, 0x63bb, 0x63d2, 0x6400, 0x6400,
- 0x6400, 0x6400, 0x6400, 0x2100, 0x9082, 0x007e, 0x1278, 0x080c,
- 0x671e, 0x0148, 0x9046, 0xb810, 0x9306, 0x1904, 0x6408, 0xb814,
- 0x9206, 0x15f0, 0x0028, 0xbb12, 0xba16, 0x0010, 0x080c, 0x4ae1,
- 0x0150, 0x04b0, 0x080c, 0x6789, 0x1598, 0xb810, 0x9306, 0x1580,
- 0xb814, 0x9206, 0x1568, 0x080c, 0xaed8, 0x0530, 0x2b00, 0x6012,
- 0x080c, 0xd0b1, 0x2900, 0x6016, 0x600b, 0xffff, 0x6023, 0x000a,
- 0xa878, 0x9086, 0x0001, 0x1170, 0x080c, 0x3310, 0x9006, 0x080c,
- 0x66bb, 0x2001, 0x0002, 0x080c, 0x66cf, 0x2001, 0x0200, 0xb86e,
- 0xb893, 0x0002, 0x2009, 0x0003, 0x080c, 0xafcc, 0x9006, 0x0068,
- 0x2001, 0x0001, 0x900e, 0x0038, 0x2001, 0x002c, 0x900e, 0x0018,
- 0x2001, 0x0028, 0x900e, 0x9005, 0x0000, 0x012e, 0x00be, 0x00fe,
- 0x0005, 0x00b6, 0x00f6, 0x00e6, 0x0126, 0x2091, 0x8000, 0xa894,
- 0x90c6, 0x0015, 0x0904, 0x65f3, 0x90c6, 0x0056, 0x0904, 0x65f7,
- 0x90c6, 0x0066, 0x0904, 0x65fb, 0x90c6, 0x0067, 0x0904, 0x65ff,
- 0x90c6, 0x0068, 0x0904, 0x6603, 0x90c6, 0x0071, 0x0904, 0x6607,
- 0x90c6, 0x0074, 0x0904, 0x660b, 0x90c6, 0x007c, 0x0904, 0x660f,
- 0x90c6, 0x007e, 0x0904, 0x6613, 0x90c6, 0x0037, 0x0904, 0x6617,
- 0x9016, 0x2079, 0x1800, 0xa974, 0x9186, 0x00ff, 0x0904, 0x65ee,
- 0x9182, 0x0800, 0x1a04, 0x65ee, 0x080c, 0x6789, 0x1198, 0xb804,
- 0x9084, 0x00ff, 0x9082, 0x0006, 0x1268, 0xa894, 0x90c6, 0x006f,
- 0x0148, 0x080c, 0xae60, 0x1904, 0x65d7, 0xb8a0, 0x9084, 0xff80,
- 0x1904, 0x65d7, 0xa894, 0x90c6, 0x006f, 0x0158, 0x90c6, 0x005e,
- 0x0904, 0x6537, 0x90c6, 0x0064, 0x0904, 0x6560, 0x2008, 0x0804,
- 0x64f9, 0xa998, 0xa8b0, 0x2040, 0x080c, 0xae60, 0x1120, 0x9182,
- 0x007f, 0x0a04, 0x64f9, 0x9186, 0x00ff, 0x0904, 0x64f9, 0x9182,
- 0x0800, 0x1a04, 0x64f9, 0xaaa0, 0xab9c, 0x787c, 0x9306, 0x11a8,
- 0x7880, 0x0096, 0x924e, 0x1128, 0x2208, 0x2310, 0x009e, 0x0804,
- 0x64f9, 0x080c, 0xae60, 0x1140, 0x99cc, 0xff00, 0x009e, 0x1128,
- 0x2208, 0x2310, 0x0804, 0x64f9, 0x009e, 0x080c, 0x4ae1, 0x0904,
- 0x6503, 0x900e, 0x9016, 0x90c6, 0x4000, 0x15e0, 0x0006, 0x080c,
- 0x6a7c, 0x1108, 0xc185, 0xb800, 0xd0bc, 0x0108, 0xc18d, 0x20a9,
- 0x0004, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0031, 0x20a0, 0xb8c4,
- 0x20e0, 0xb8c8, 0x9080, 0x0006, 0x2098, 0x080c, 0x0fd6, 0x20a9,
- 0x0004, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0035, 0x20a0, 0xb8c4,
- 0x20e0, 0xb8c8, 0x9080, 0x000a, 0x2098, 0x080c, 0x0fd6, 0xa8c4,
- 0xabc8, 0x9305, 0xabcc, 0x9305, 0xabd0, 0x9305, 0xabd4, 0x9305,
- 0xabd8, 0x9305, 0xabdc, 0x9305, 0xabe0, 0x9305, 0x9005, 0x0510,
- 0x000e, 0x00c8, 0x90c6, 0x4007, 0x1110, 0x2408, 0x00a0, 0x90c6,
- 0x4008, 0x1118, 0x2708, 0x2610, 0x0070, 0x90c6, 0x4009, 0x1108,
- 0x0050, 0x90c6, 0x4006, 0x0138, 0x2001, 0x4005, 0x2009, 0x000a,
- 0x0010, 0x2001, 0x4006, 0xa896, 0xa99a, 0xaa9e, 0x2001, 0x0030,
- 0x900e, 0x0478, 0x000e, 0x080c, 0xaed8, 0x1130, 0x2001, 0x4005,
- 0x2009, 0x0003, 0x9016, 0x0c78, 0x2b00, 0x6012, 0x080c, 0xd0b1,
- 0x2900, 0x6016, 0x6023, 0x0001, 0xa868, 0xd88c, 0x0108, 0xc0f5,
- 0xa86a, 0x0126, 0x2091, 0x8000, 0x080c, 0x3310, 0x012e, 0x9006,
- 0x080c, 0x66bb, 0x2001, 0x0002, 0x080c, 0x66cf, 0x2009, 0x0002,
- 0x080c, 0xafcc, 0xa8b0, 0xd094, 0x0118, 0xb8d4, 0xc08d, 0xb8d6,
- 0x9006, 0x9005, 0x012e, 0x00ee, 0x00fe, 0x00be, 0x0005, 0x080c,
- 0x583a, 0x0118, 0x2009, 0x0007, 0x00f8, 0xa998, 0xaeb0, 0x080c,
- 0x6789, 0x1904, 0x64f4, 0x9186, 0x007f, 0x0130, 0x080c, 0x6bd5,
- 0x0118, 0x2009, 0x0009, 0x0080, 0x0096, 0x080c, 0x1059, 0x1120,
- 0x009e, 0x2009, 0x0002, 0x0040, 0x2900, 0x009e, 0xa806, 0x080c,
- 0xce04, 0x19b0, 0x2009, 0x0003, 0x2001, 0x4005, 0x0804, 0x64fb,
- 0xa998, 0xaeb0, 0x080c, 0x6789, 0x1904, 0x64f4, 0x0096, 0x080c,
- 0x1059, 0x1128, 0x009e, 0x2009, 0x0002, 0x0804, 0x65b4, 0x2900,
- 0x009e, 0xa806, 0x0096, 0x2048, 0x20a9, 0x002b, 0xb8c4, 0x20e0,
- 0xb8c8, 0x2098, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0002, 0x20a0,
- 0x4003, 0x20a9, 0x0008, 0x9080, 0x0006, 0x20a0, 0xbbc8, 0x9398,
- 0x0006, 0x2398, 0x080c, 0x0fd6, 0x009e, 0xa87b, 0x0000, 0xa883,
- 0x0000, 0xa897, 0x4000, 0xd684, 0x1168, 0x080c, 0x5826, 0xd0b4,
- 0x1118, 0xa89b, 0x000b, 0x00e0, 0xb800, 0xd08c, 0x0118, 0xa89b,
- 0x000c, 0x00b0, 0x080c, 0x6bd5, 0x0118, 0xa89b, 0x0009, 0x0080,
- 0x080c, 0x583a, 0x0118, 0xa89b, 0x0007, 0x0050, 0x080c, 0xcde7,
- 0x1904, 0x6530, 0x2009, 0x0003, 0x2001, 0x4005, 0x0804, 0x64fb,
- 0xa87b, 0x0030, 0xa897, 0x4005, 0xa804, 0x8006, 0x8006, 0x8007,
- 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, 0x0002, 0x2009, 0x002b,
- 0xaaa0, 0xab9c, 0xaca8, 0xada4, 0x2031, 0x0000, 0x2041, 0x12a8,
- 0x080c, 0xb456, 0x1904, 0x6530, 0x2009, 0x0002, 0x08e8, 0x2001,
- 0x0028, 0x900e, 0x0804, 0x6531, 0x2009, 0x180c, 0x210c, 0xd18c,
- 0x0118, 0x2001, 0x0004, 0x0038, 0xd184, 0x0118, 0x2001, 0x0004,
- 0x0010, 0x2001, 0x0029, 0x900e, 0x0804, 0x6531, 0x2001, 0x0029,
- 0x900e, 0x0804, 0x6531, 0x080c, 0x38b9, 0x0804, 0x6532, 0x080c,
- 0x5543, 0x0804, 0x6532, 0x080c, 0x4692, 0x0804, 0x6532, 0x080c,
- 0x470b, 0x0804, 0x6532, 0x080c, 0x4767, 0x0804, 0x6532, 0x080c,
- 0x4ba4, 0x0804, 0x6532, 0x080c, 0x4e58, 0x0804, 0x6532, 0x080c,
- 0x51aa, 0x0804, 0x6532, 0x080c, 0x53a3, 0x0804, 0x6532, 0x080c,
- 0x3ad7, 0x0804, 0x6532, 0x00b6, 0xa974, 0xae78, 0x9684, 0x3fff,
- 0x9082, 0x4000, 0x1608, 0x9182, 0x0800, 0x1258, 0x9188, 0x1000,
- 0x2104, 0x905d, 0x0130, 0x080c, 0x6bd5, 0x1138, 0x00d9, 0x9006,
- 0x00b0, 0x2001, 0x0028, 0x900e, 0x0090, 0x9082, 0x0006, 0x1240,
- 0xb900, 0xd1fc, 0x0d98, 0x2001, 0x0029, 0x2009, 0x1000, 0x0038,
+ 0x20a1, 0x024e, 0x4003, 0x60c3, 0x0014, 0x080c, 0x6007, 0x00fe,
+ 0x0005, 0x00f6, 0x7090, 0x9005, 0x05f0, 0x2011, 0x5fdd, 0x080c,
+ 0x882c, 0x9086, 0x0014, 0x15a8, 0x080c, 0x6152, 0x2079, 0x0260,
+ 0x7a30, 0x9296, 0x1105, 0x1568, 0x7834, 0x9084, 0x0100, 0x2011,
+ 0x0100, 0x921e, 0x1168, 0x9085, 0x0001, 0x080c, 0x617d, 0x7a38,
+ 0xd2fc, 0x0128, 0x70c4, 0x9005, 0x1110, 0x70c7, 0x0001, 0x0080,
+ 0x9005, 0x11b8, 0x7a38, 0xd2fc, 0x0128, 0x70c4, 0x9005, 0x1110,
+ 0x70c7, 0x0001, 0x9085, 0x0001, 0x080c, 0x617d, 0x7097, 0x0000,
+ 0x7a38, 0xd2f4, 0x0110, 0x70df, 0x0008, 0x709b, 0x0016, 0x0029,
+ 0x0010, 0x7093, 0x0000, 0x00fe, 0x0005, 0x080c, 0xa8ec, 0x080c,
+ 0x6152, 0x20e1, 0x0000, 0x2099, 0x0260, 0x20e9, 0x0000, 0x20a1,
+ 0x0240, 0x20a9, 0x000e, 0x4003, 0x2011, 0x026d, 0x2204, 0x9084,
+ 0x0100, 0x2011, 0x024d, 0x2012, 0x2011, 0x026e, 0x709b, 0x0017,
+ 0x080c, 0x6135, 0x1150, 0x7084, 0x9005, 0x1138, 0x080c, 0x5efd,
+ 0x1188, 0x9085, 0x0001, 0x080c, 0x270a, 0x20a9, 0x0008, 0x080c,
+ 0x6152, 0x20e1, 0x0000, 0x2099, 0x026e, 0x20e9, 0x0000, 0x20a1,
+ 0x024e, 0x4003, 0x60c3, 0x0014, 0x080c, 0x6007, 0x0010, 0x080c,
+ 0x5a57, 0x0005, 0x00f6, 0x7090, 0x9005, 0x01d8, 0x2011, 0x5fdd,
+ 0x080c, 0x882c, 0x9086, 0x0084, 0x1190, 0x080c, 0x6152, 0x2079,
+ 0x0260, 0x7a30, 0x9296, 0x1106, 0x1150, 0x7834, 0x9005, 0x1138,
+ 0x9006, 0x080c, 0x617d, 0x709b, 0x0018, 0x0029, 0x0010, 0x7093,
+ 0x0000, 0x00fe, 0x0005, 0x00f6, 0x709b, 0x0019, 0x080c, 0x60e4,
+ 0x2079, 0x0240, 0x7833, 0x1106, 0x7837, 0x0000, 0x080c, 0x6152,
+ 0x2009, 0x026e, 0x2039, 0x1d0e, 0x20a9, 0x0040, 0x213e, 0x8738,
+ 0x8108, 0x9186, 0x0280, 0x1128, 0x6814, 0x8000, 0x6816, 0x2009,
+ 0x0260, 0x1f04, 0x5e66, 0x2039, 0x1d0e, 0x080c, 0x6135, 0x11e8,
+ 0x2728, 0x2514, 0x8207, 0x9084, 0x00ff, 0x8000, 0x2018, 0x9294,
+ 0x00ff, 0x8007, 0x9205, 0x202a, 0x7060, 0x2310, 0x8214, 0x92a0,
+ 0x1d0e, 0x2414, 0x938c, 0x0001, 0x0118, 0x9294, 0xff00, 0x0018,
+ 0x9294, 0x00ff, 0x8007, 0x9215, 0x2222, 0x20a9, 0x0040, 0x2009,
+ 0x024e, 0x270e, 0x8738, 0x8108, 0x9186, 0x0260, 0x1128, 0x6810,
+ 0x8000, 0x6812, 0x2009, 0x0240, 0x1f04, 0x5e99, 0x60c3, 0x0084,
+ 0x080c, 0x6007, 0x00fe, 0x0005, 0x00f6, 0x7090, 0x9005, 0x01e0,
+ 0x2011, 0x5fdd, 0x080c, 0x882c, 0x9086, 0x0084, 0x1198, 0x080c,
+ 0x6152, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1107, 0x1158, 0x7834,
+ 0x9005, 0x1140, 0x7097, 0x0001, 0x080c, 0x60a8, 0x709b, 0x001a,
+ 0x0029, 0x0010, 0x7093, 0x0000, 0x00fe, 0x0005, 0x9085, 0x0001,
+ 0x080c, 0x617d, 0x709b, 0x001b, 0x080c, 0xa8ec, 0x080c, 0x6152,
+ 0x2011, 0x0260, 0x2009, 0x0240, 0x7490, 0x9480, 0x0018, 0x9080,
+ 0x0007, 0x9084, 0x03f8, 0x8004, 0x20a8, 0x220e, 0x8210, 0x8108,
+ 0x9186, 0x0260, 0x1150, 0x6810, 0x8000, 0x6812, 0x2009, 0x0240,
+ 0x6814, 0x8000, 0x6816, 0x2011, 0x0260, 0x1f04, 0x5ee5, 0x60c3,
+ 0x0084, 0x080c, 0x6007, 0x0005, 0x0005, 0x0086, 0x0096, 0x2029,
+ 0x1848, 0x252c, 0x20a9, 0x0008, 0x2041, 0x1d0e, 0x20e9, 0x0001,
+ 0x28a0, 0x080c, 0x6152, 0x20e1, 0x0000, 0x2099, 0x026e, 0x4003,
+ 0x20a9, 0x0008, 0x2011, 0x0007, 0xd5d4, 0x0108, 0x9016, 0x2800,
+ 0x9200, 0x200c, 0x91a6, 0xffff, 0x1148, 0xd5d4, 0x0110, 0x8210,
+ 0x0008, 0x8211, 0x1f04, 0x5f17, 0x0804, 0x5f86, 0x82ff, 0x1160,
+ 0xd5d4, 0x0120, 0x91a6, 0x3fff, 0x0d90, 0x0020, 0x91a6, 0x3fff,
+ 0x0904, 0x5f86, 0x918d, 0xc000, 0x20a9, 0x0010, 0x2019, 0x0001,
+ 0xd5d4, 0x0110, 0x2019, 0x0010, 0x2120, 0xd5d4, 0x0110, 0x8423,
+ 0x0008, 0x8424, 0x1240, 0xd5d4, 0x0110, 0x8319, 0x0008, 0x8318,
+ 0x1f04, 0x5f3d, 0x04d8, 0x23a8, 0x2021, 0x0001, 0x8426, 0x8425,
+ 0x1f04, 0x5f4f, 0x2328, 0x8529, 0x92be, 0x0007, 0x0158, 0x0006,
+ 0x2039, 0x0007, 0x2200, 0x973a, 0x000e, 0x27a8, 0x95a8, 0x0010,
+ 0x1f04, 0x5f5e, 0x755e, 0x95c8, 0x3474, 0x292d, 0x95ac, 0x00ff,
+ 0x7582, 0x6532, 0x6536, 0x0016, 0x2508, 0x080c, 0x26ea, 0x001e,
+ 0x60e7, 0x0000, 0x65ea, 0x2018, 0x2304, 0x9405, 0x201a, 0x7087,
+ 0x0001, 0x20e9, 0x0000, 0x20a1, 0x024e, 0x20e1, 0x0001, 0x2898,
+ 0x20a9, 0x0008, 0x4003, 0x9085, 0x0001, 0x0008, 0x9006, 0x009e,
+ 0x008e, 0x0005, 0x0156, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x22a8,
+ 0x20e1, 0x0000, 0x2099, 0x026e, 0x20e9, 0x0000, 0x2011, 0x024e,
+ 0x22a0, 0x4003, 0x014e, 0x013e, 0x01de, 0x01ce, 0x015e, 0x2118,
+ 0x9026, 0x2001, 0x0007, 0x939a, 0x0010, 0x0218, 0x8420, 0x8001,
+ 0x0cd0, 0x2118, 0x84ff, 0x0120, 0x939a, 0x0010, 0x8421, 0x1de0,
+ 0x2021, 0x0001, 0x83ff, 0x0118, 0x8423, 0x8319, 0x1de8, 0x9238,
+ 0x2029, 0x026e, 0x9528, 0x2504, 0x942c, 0x11b8, 0x9405, 0x203a,
+ 0x715e, 0x91a0, 0x3474, 0x242d, 0x95ac, 0x00ff, 0x7582, 0x6532,
+ 0x6536, 0x0016, 0x2508, 0x080c, 0x26ea, 0x001e, 0x60e7, 0x0000,
+ 0x65ea, 0x7087, 0x0001, 0x9084, 0x0000, 0x0005, 0x00e6, 0x2071,
+ 0x1800, 0x708b, 0x0000, 0x00ee, 0x0005, 0x00e6, 0x00f6, 0x2079,
+ 0x0100, 0x2071, 0x0140, 0x080c, 0x6097, 0x080c, 0xa09b, 0x7004,
+ 0x9084, 0x4000, 0x0110, 0x080c, 0x2ab2, 0x0126, 0x2091, 0x8000,
+ 0x2071, 0x1826, 0x2073, 0x0000, 0x7840, 0x0026, 0x0016, 0x2009,
+ 0x00f7, 0x080c, 0x60f4, 0x001e, 0x9094, 0x0010, 0x9285, 0x0080,
+ 0x7842, 0x7a42, 0x002e, 0x012e, 0x00fe, 0x00ee, 0x0005, 0x0126,
+ 0x2091, 0x8000, 0x080c, 0x2a11, 0x0228, 0x2011, 0x0101, 0x2204,
+ 0xc0c5, 0x2012, 0x2011, 0x19f6, 0x2013, 0x0000, 0x7093, 0x0000,
+ 0x012e, 0x60a3, 0x0056, 0x60a7, 0x9575, 0x080c, 0xa08e, 0x6144,
+ 0xd184, 0x0120, 0x7198, 0x918d, 0x2000, 0x0018, 0x718c, 0x918d,
+ 0x1000, 0x2011, 0x199a, 0x2112, 0x2009, 0x07d0, 0x2011, 0x5fdd,
+ 0x080c, 0x88f6, 0x0005, 0x0016, 0x0026, 0x00c6, 0x0126, 0x2091,
+ 0x8000, 0x080c, 0xaaf7, 0x080c, 0xae87, 0x080c, 0xab13, 0x2009,
+ 0x00f7, 0x080c, 0x60f4, 0x2061, 0x1a05, 0x900e, 0x611a, 0x611e,
+ 0x617a, 0x617e, 0x2061, 0x1800, 0x6003, 0x0001, 0x2061, 0x0100,
+ 0x6043, 0x0090, 0x6043, 0x0010, 0x2009, 0x199a, 0x200b, 0x0000,
+ 0x2009, 0x002d, 0x2011, 0x6063, 0x080c, 0x8820, 0x012e, 0x00ce,
+ 0x002e, 0x001e, 0x0005, 0x00e6, 0x0006, 0x0126, 0x2091, 0x8000,
+ 0x0471, 0x2071, 0x0100, 0x080c, 0xa09b, 0x2071, 0x0140, 0x7004,
+ 0x9084, 0x4000, 0x0110, 0x080c, 0x2ab2, 0x080c, 0x76a5, 0x0188,
+ 0x080c, 0x76c0, 0x1170, 0x080c, 0x79a9, 0x0016, 0x080c, 0x27b9,
+ 0x2001, 0x196e, 0x2102, 0x001e, 0x080c, 0x79a4, 0x080c, 0x75cc,
+ 0x0050, 0x2009, 0x0001, 0x080c, 0x2a8e, 0x2001, 0x0001, 0x080c,
+ 0x2646, 0x080c, 0x6033, 0x012e, 0x000e, 0x00ee, 0x0005, 0x2001,
+ 0x180e, 0x2004, 0xd0bc, 0x0158, 0x0026, 0x0036, 0x2011, 0x8017,
+ 0x2001, 0x199a, 0x201c, 0x080c, 0x4c28, 0x003e, 0x002e, 0x0005,
+ 0x20a9, 0x0012, 0x20e9, 0x0001, 0x20a1, 0x1d80, 0x080c, 0x6152,
+ 0x20e9, 0x0000, 0x2099, 0x026e, 0x0099, 0x20a9, 0x0020, 0x080c,
+ 0x614c, 0x2099, 0x0260, 0x20a1, 0x1d92, 0x0051, 0x20a9, 0x000e,
+ 0x080c, 0x614f, 0x2099, 0x0260, 0x20a1, 0x1db2, 0x0009, 0x0005,
+ 0x0016, 0x0026, 0x3410, 0x3308, 0x2104, 0x8007, 0x2012, 0x8108,
+ 0x8210, 0x1f04, 0x60cc, 0x002e, 0x001e, 0x0005, 0x080c, 0xa8ec,
+ 0x20e1, 0x0001, 0x2099, 0x1d00, 0x20e9, 0x0000, 0x20a1, 0x0240,
+ 0x20a9, 0x000c, 0x4003, 0x0005, 0x080c, 0xa8ec, 0x080c, 0x6152,
+ 0x20e1, 0x0000, 0x2099, 0x0260, 0x20e9, 0x0000, 0x20a1, 0x0240,
+ 0x20a9, 0x000c, 0x4003, 0x0005, 0x00c6, 0x0006, 0x2061, 0x0100,
+ 0x810f, 0x2001, 0x1834, 0x2004, 0x9005, 0x1138, 0x2001, 0x1818,
+ 0x2004, 0x9084, 0x00ff, 0x9105, 0x0010, 0x9185, 0x00f7, 0x604a,
+ 0x000e, 0x00ce, 0x0005, 0x0016, 0x0046, 0x080c, 0x6bc9, 0x0158,
+ 0x9006, 0x2020, 0x2009, 0x002a, 0x080c, 0xe795, 0x2001, 0x180c,
+ 0x200c, 0xc195, 0x2102, 0x2019, 0x002a, 0x900e, 0x080c, 0x32c0,
+ 0x080c, 0xd35d, 0x0140, 0x0036, 0x2019, 0xffff, 0x2021, 0x0007,
+ 0x080c, 0x4ddf, 0x003e, 0x004e, 0x001e, 0x0005, 0x080c, 0x6033,
+ 0x709b, 0x0000, 0x7093, 0x0000, 0x0005, 0x0006, 0x2001, 0x180c,
+ 0x2004, 0xd09c, 0x0100, 0x000e, 0x0005, 0x0006, 0x0016, 0x0126,
+ 0x2091, 0x8000, 0x2001, 0x0101, 0x200c, 0x918d, 0x0006, 0x2102,
+ 0x012e, 0x001e, 0x000e, 0x0005, 0x2009, 0x0001, 0x0020, 0x2009,
+ 0x0002, 0x0008, 0x900e, 0x6814, 0x9084, 0xffc0, 0x910d, 0x6916,
+ 0x0005, 0x00f6, 0x0156, 0x0146, 0x01d6, 0x9006, 0x20a9, 0x0080,
+ 0x20e9, 0x0001, 0x20a1, 0x1d00, 0x4004, 0x2079, 0x1d00, 0x7803,
+ 0x2200, 0x7807, 0x00ef, 0x780f, 0x00ef, 0x7813, 0x0138, 0x7823,
+ 0xffff, 0x7827, 0xffff, 0x01de, 0x014e, 0x015e, 0x00fe, 0x0005,
+ 0x2001, 0x1800, 0x2003, 0x0001, 0x0005, 0x2001, 0x19a8, 0x0118,
+ 0x2003, 0x0001, 0x0010, 0x2003, 0x0000, 0x0005, 0x0156, 0x20a9,
+ 0x0800, 0x2009, 0x1000, 0x9006, 0x200a, 0x8108, 0x1f04, 0x618c,
+ 0x015e, 0x0005, 0x00d6, 0x0036, 0x0156, 0x0136, 0x0146, 0x2069,
+ 0x1847, 0x9006, 0xb802, 0xb8d6, 0xb807, 0x0707, 0xb80a, 0xb80e,
+ 0xb812, 0x9198, 0x3474, 0x231d, 0x939c, 0x00ff, 0xbb16, 0x0016,
+ 0x0026, 0xb886, 0x080c, 0xae80, 0x1120, 0x9192, 0x007e, 0x1208,
+ 0xbb86, 0x20a9, 0x0004, 0xb8c4, 0x20e8, 0xb9c8, 0x9198, 0x0006,
+ 0x9006, 0x23a0, 0x4004, 0x20a9, 0x0004, 0x9198, 0x000a, 0x23a0,
+ 0x4004, 0x002e, 0x001e, 0xb83e, 0xb842, 0xb8ce, 0xb8d2, 0xb85e,
+ 0xb862, 0xb866, 0xb86a, 0xb86f, 0x0100, 0xb872, 0xb876, 0xb87a,
+ 0xb88a, 0xb88e, 0xb893, 0x0008, 0xb896, 0xb89a, 0xb89e, 0xb8be,
+ 0xb9a2, 0x0096, 0xb8a4, 0x904d, 0x0110, 0x080c, 0x107f, 0xb8a7,
+ 0x0000, 0x009e, 0x9006, 0xb84a, 0x6810, 0xb83a, 0x680c, 0xb846,
+ 0xb8bb, 0x0520, 0xb8ac, 0x9005, 0x0198, 0x00c6, 0x2060, 0x9c82,
+ 0x1ddc, 0x0a0c, 0x0d79, 0x2001, 0x181a, 0x2004, 0x9c02, 0x1a0c,
+ 0x0d79, 0x080c, 0x8d87, 0x00ce, 0x090c, 0x9128, 0xb8af, 0x0000,
+ 0x6814, 0x9084, 0x00ff, 0xb842, 0x014e, 0x013e, 0x015e, 0x003e,
+ 0x00de, 0x0005, 0x0126, 0x2091, 0x8000, 0xa974, 0xae78, 0x9684,
+ 0x3fff, 0x9082, 0x4000, 0x1a04, 0x6268, 0x9182, 0x0800, 0x1a04,
+ 0x626c, 0x2001, 0x180c, 0x2004, 0x9084, 0x0003, 0x1904, 0x6272,
+ 0x9188, 0x1000, 0x2104, 0x905d, 0x0198, 0xb804, 0x9084, 0x00ff,
+ 0x908e, 0x0006, 0x1188, 0xb8a4, 0x900d, 0x1904, 0x6284, 0x080c,
+ 0x6644, 0x9006, 0x012e, 0x0005, 0x2001, 0x0005, 0x900e, 0x04b8,
+ 0x2001, 0x0028, 0x900e, 0x0498, 0x9082, 0x0006, 0x1290, 0x080c,
+ 0xae80, 0x1160, 0xb8a0, 0x9084, 0xff80, 0x1140, 0xb900, 0xd1fc,
+ 0x0d10, 0x2001, 0x0029, 0x2009, 0x1000, 0x0408, 0x2001, 0x0028,
+ 0x00a8, 0x2009, 0x180c, 0x210c, 0xd18c, 0x0118, 0x2001, 0x0004,
+ 0x0068, 0xd184, 0x0118, 0x2001, 0x0004, 0x0040, 0x2001, 0x0029,
+ 0xb900, 0xd1fc, 0x0118, 0x2009, 0x1000, 0x0048, 0x900e, 0x0038,
0x2001, 0x0029, 0x900e, 0x0018, 0x2001, 0x0029, 0x900e, 0x9005,
- 0x00be, 0x0005, 0xa877, 0x0000, 0xb8d0, 0x9005, 0x1904, 0x66af,
- 0xb888, 0x9005, 0x1904, 0x66af, 0xb838, 0xb93c, 0x9102, 0x1a04,
- 0x66af, 0x2b10, 0x080c, 0xaf05, 0x0904, 0x66ab, 0x8108, 0xb93e,
- 0x6212, 0x2900, 0x6016, 0x6023, 0x0003, 0x600b, 0xffff, 0x6007,
- 0x0040, 0xa878, 0x605e, 0xa880, 0x6066, 0xa883, 0x0000, 0xa87c,
- 0xd0ac, 0x0588, 0xc0dd, 0xa87e, 0xa888, 0x8001, 0x1530, 0xa816,
- 0xa864, 0x9094, 0x00f7, 0x9296, 0x0011, 0x11f8, 0x9084, 0x00ff,
- 0xc0bd, 0x601e, 0xa8ac, 0xaab0, 0xa836, 0xaa3a, 0x2001, 0x000f,
- 0x8001, 0x1df0, 0x2001, 0x8004, 0x6003, 0x0004, 0x6046, 0x00f6,
- 0x2079, 0x0380, 0x7818, 0xd0bc, 0x1de8, 0x7833, 0x0010, 0x2c00,
- 0x7836, 0x781b, 0x8080, 0x00fe, 0x0005, 0x080c, 0x17ad, 0x601c,
- 0xc0bd, 0x601e, 0x0c38, 0xd0b4, 0x190c, 0x1cbd, 0x2001, 0x8004,
- 0x6003, 0x0002, 0x0c18, 0x81ff, 0x1110, 0xb88b, 0x0001, 0x2908,
- 0xb8cc, 0xb9ce, 0x9005, 0x1110, 0xb9d2, 0x0020, 0x0096, 0x2048,
- 0xa902, 0x009e, 0x0005, 0x00b6, 0x0126, 0x00c6, 0x0026, 0x2091,
- 0x8000, 0x6210, 0x2258, 0xba00, 0x9005, 0x0110, 0xc285, 0x0008,
- 0xc284, 0xba02, 0x002e, 0x00ce, 0x012e, 0x00be, 0x0005, 0x00b6,
- 0x0126, 0x00c6, 0x2091, 0x8000, 0x6210, 0x2258, 0xba04, 0x0006,
- 0x9086, 0x0006, 0x1170, 0xb89c, 0xd0ac, 0x0158, 0x080c, 0x6bd1,
- 0x0140, 0x9284, 0xff00, 0x8007, 0x9086, 0x0007, 0x1110, 0x2011,
- 0x0600, 0x000e, 0x9294, 0xff00, 0x9215, 0xba06, 0x0006, 0x9086,
- 0x0006, 0x1120, 0xba90, 0x82ff, 0x090c, 0x0d85, 0x000e, 0x00ce,
- 0x012e, 0x00be, 0x0005, 0x00b6, 0x0126, 0x00c6, 0x2091, 0x8000,
- 0x6210, 0x2258, 0xba04, 0x0006, 0x9086, 0x0006, 0x1168, 0xb89c,
- 0xd0a4, 0x0150, 0x080c, 0x6bcd, 0x1138, 0x9284, 0x00ff, 0x9086,
- 0x0007, 0x1110, 0x2011, 0x0006, 0x000e, 0x9294, 0x00ff, 0x8007,
- 0x9215, 0xba06, 0x00ce, 0x012e, 0x00be, 0x0005, 0x9182, 0x0800,
- 0x0218, 0x9085, 0x0001, 0x0005, 0x00d6, 0x0026, 0x9190, 0x1000,
- 0x2204, 0x905d, 0x1188, 0x0096, 0x080c, 0x1059, 0x2958, 0x009e,
- 0x0168, 0x2b00, 0x2012, 0xb85c, 0xb8ca, 0xb860, 0xb8c6, 0x9006,
- 0xb8a6, 0xb8ae, 0x080c, 0x6198, 0x9006, 0x0010, 0x9085, 0x0001,
- 0x002e, 0x00de, 0x0005, 0x00b6, 0x0096, 0x0126, 0x2091, 0x8000,
- 0x0026, 0x9182, 0x0800, 0x0218, 0x9085, 0x0001, 0x04a8, 0x00d6,
- 0x9190, 0x1000, 0x2204, 0x905d, 0x0568, 0x2013, 0x0000, 0xb8a4,
- 0x904d, 0x0110, 0x080c, 0x108b, 0x00d6, 0x00c6, 0xb8bc, 0x2060,
- 0x8cff, 0x0168, 0x600c, 0x0006, 0x6014, 0x2048, 0x080c, 0xcc16,
- 0x0110, 0x080c, 0x100b, 0x080c, 0xaf2e, 0x00ce, 0x0c88, 0x00ce,
- 0x00de, 0x00c6, 0xb8ac, 0x9065, 0x0128, 0x621c, 0xd2c4, 0x0110,
- 0x080c, 0x9130, 0x00ce, 0x2b48, 0xb8c8, 0xb85e, 0xb8c4, 0xb862,
- 0x080c, 0x109b, 0x00de, 0x9006, 0x002e, 0x012e, 0x009e, 0x00be,
- 0x0005, 0x0016, 0x9182, 0x0800, 0x0218, 0x9085, 0x0001, 0x0030,
- 0x9188, 0x1000, 0x2104, 0x905d, 0x0dc0, 0x9006, 0x001e, 0x0005,
- 0x00d6, 0x0156, 0x0136, 0x0146, 0x9006, 0xb80a, 0xb80e, 0xb800,
- 0xc08c, 0xb802, 0x080c, 0x76a5, 0x1510, 0xb8a0, 0x9086, 0x007e,
- 0x0120, 0x080c, 0xae60, 0x11d8, 0x0078, 0x7040, 0xd0e4, 0x01b8,
- 0x00c6, 0x2061, 0x1983, 0x7048, 0x2062, 0x704c, 0x6006, 0x7050,
- 0x600a, 0x7054, 0x600e, 0x00ce, 0x703c, 0x2069, 0x0140, 0x9005,
- 0x1110, 0x2001, 0x0001, 0x6886, 0x2069, 0x1800, 0x68b6, 0x7040,
- 0xb85e, 0x7048, 0xb862, 0x704c, 0xb866, 0x20e1, 0x0000, 0x2099,
- 0x0276, 0xb8c4, 0x20e8, 0xb8c8, 0x9088, 0x000a, 0x21a0, 0x20a9,
- 0x0004, 0x4003, 0x2099, 0x027a, 0x9088, 0x0006, 0x21a0, 0x20a9,
- 0x0004, 0x4003, 0x2069, 0x0200, 0x6817, 0x0001, 0x7040, 0xb86a,
- 0x7144, 0xb96e, 0x7048, 0xb872, 0x7050, 0xb876, 0x2069, 0x0200,
- 0x6817, 0x0000, 0xb8a0, 0x9086, 0x007e, 0x1110, 0x7144, 0xb96e,
- 0x9182, 0x0211, 0x1218, 0x2009, 0x0008, 0x0400, 0x9182, 0x0259,
- 0x1218, 0x2009, 0x0007, 0x00d0, 0x9182, 0x02c1, 0x1218, 0x2009,
- 0x0006, 0x00a0, 0x9182, 0x0349, 0x1218, 0x2009, 0x0005, 0x0070,
- 0x9182, 0x0421, 0x1218, 0x2009, 0x0004, 0x0040, 0x9182, 0x0581,
- 0x1218, 0x2009, 0x0003, 0x0010, 0x2009, 0x0002, 0xb992, 0x014e,
- 0x013e, 0x015e, 0x00de, 0x0005, 0x0016, 0x0026, 0x00e6, 0x2071,
- 0x0260, 0x7034, 0xb896, 0x703c, 0xb89a, 0x7054, 0xb89e, 0x0036,
- 0xbbd4, 0xc384, 0xba00, 0x2009, 0x1867, 0x210c, 0xd0bc, 0x0120,
- 0xd1ec, 0x0110, 0xc2ad, 0x0008, 0xc2ac, 0xd0c4, 0x0148, 0xd1e4,
- 0x0138, 0xc2bd, 0xd0cc, 0x0128, 0xd38c, 0x1108, 0xc385, 0x0008,
- 0xc2bc, 0xba02, 0xbbd6, 0x003e, 0x00ee, 0x002e, 0x001e, 0x0005,
- 0x0096, 0x0126, 0x2091, 0x8000, 0xb8a4, 0x904d, 0x0578, 0xa900,
- 0x81ff, 0x15c0, 0xaa04, 0x9282, 0x0010, 0x16c8, 0x0136, 0x0146,
- 0x01c6, 0x01d6, 0x8906, 0x8006, 0x8007, 0x908c, 0x003f, 0x21e0,
- 0x9084, 0xffc0, 0x9080, 0x0004, 0x2098, 0x2009, 0x0010, 0x20a9,
- 0x0001, 0x4002, 0x9086, 0xffff, 0x0120, 0x8109, 0x1dd0, 0x080c,
- 0x0d85, 0x3c00, 0x20e8, 0x3300, 0x8001, 0x20a0, 0x4604, 0x8210,
- 0xaa06, 0x01de, 0x01ce, 0x014e, 0x013e, 0x0060, 0x080c, 0x1059,
- 0x0170, 0x2900, 0xb8a6, 0xa803, 0x0000, 0x080c, 0x6a18, 0xa807,
- 0x0001, 0xae12, 0x9085, 0x0001, 0x012e, 0x009e, 0x0005, 0x9006,
- 0x0cd8, 0x0126, 0x2091, 0x8000, 0x0096, 0xb8a4, 0x904d, 0x0188,
- 0xa800, 0x9005, 0x1150, 0x080c, 0x6a27, 0x1158, 0xa804, 0x908a,
- 0x0002, 0x0218, 0x8001, 0xa806, 0x0020, 0x080c, 0x108b, 0xb8a7,
- 0x0000, 0x009e, 0x012e, 0x0005, 0x0096, 0x00c6, 0xb888, 0x9005,
- 0x1904, 0x690d, 0xb8d0, 0x904d, 0x0904, 0x690d, 0x080c, 0xaf05,
- 0x0904, 0x6909, 0x8210, 0xba3e, 0xa800, 0xb8d2, 0x9005, 0x1108,
- 0xb8ce, 0x2b00, 0x6012, 0x2900, 0x6016, 0x6023, 0x0003, 0x600b,
- 0xffff, 0x6007, 0x0040, 0xa878, 0x605e, 0xa880, 0x9084, 0x00ff,
- 0x6066, 0xa883, 0x0000, 0xa87c, 0xd0ac, 0x01c8, 0xc0dd, 0xa87e,
- 0xa888, 0x8001, 0x1568, 0xa816, 0xa864, 0x9094, 0x00f7, 0x9296,
- 0x0011, 0x1530, 0x9084, 0x00ff, 0xc0bd, 0x601e, 0xa8ac, 0xaab0,
- 0xa836, 0xaa3a, 0x2001, 0x8004, 0x6003, 0x0004, 0x0030, 0x080c,
- 0x1cbd, 0x2001, 0x8004, 0x6003, 0x0002, 0x6046, 0x2001, 0x0010,
- 0x2c08, 0x080c, 0xaad1, 0xb838, 0xba3c, 0x9202, 0x0a04, 0x68ba,
- 0x0020, 0x82ff, 0x1110, 0xb88b, 0x0001, 0x00ce, 0x009e, 0x0005,
- 0x080c, 0x17ad, 0x601c, 0xc0bd, 0x601e, 0x08e0, 0x00b6, 0x0096,
- 0x0016, 0x20a9, 0x0800, 0x900e, 0x0016, 0x080c, 0x6789, 0x1158,
+ 0x012e, 0x0005, 0x2001, 0x180c, 0x2004, 0xd084, 0x19d0, 0x9188,
+ 0x1000, 0x2104, 0x9065, 0x09a8, 0x080c, 0x6bcd, 0x1990, 0xb800,
+ 0xd0bc, 0x0978, 0x0804, 0x622b, 0x080c, 0x69f0, 0x0904, 0x6234,
+ 0x0804, 0x622f, 0x00e6, 0x2071, 0x19e9, 0x7004, 0x9086, 0x0002,
+ 0x1128, 0x7030, 0x9080, 0x0004, 0x2004, 0x9b06, 0x00ee, 0x0005,
+ 0x00b6, 0x00e6, 0x0126, 0x2091, 0x8000, 0xa874, 0x908e, 0x00ff,
+ 0x1120, 0x2001, 0x196c, 0x205c, 0x0060, 0xa974, 0x9182, 0x0800,
+ 0x1690, 0x9188, 0x1000, 0x2104, 0x905d, 0x01d0, 0x080c, 0x6b6d,
+ 0x11d0, 0x080c, 0xaef8, 0x0570, 0x2b00, 0x6012, 0x2900, 0x6016,
+ 0x6023, 0x0009, 0x602b, 0x0000, 0xa874, 0x908e, 0x00ff, 0x1110,
+ 0x602b, 0x8000, 0x2009, 0x0043, 0x080c, 0xafec, 0x9006, 0x00b0,
+ 0x2001, 0x0028, 0x0090, 0x2009, 0x180c, 0x210c, 0xd18c, 0x0118,
+ 0x2001, 0x0004, 0x0038, 0xd184, 0x0118, 0x2001, 0x0004, 0x0010,
+ 0x2001, 0x0029, 0x0010, 0x2001, 0x0029, 0x9005, 0x012e, 0x00ee,
+ 0x00be, 0x0005, 0x2001, 0x002c, 0x0cc0, 0x00b6, 0x00e6, 0x0126,
+ 0x2091, 0x8000, 0xa974, 0x9182, 0x0800, 0x1a04, 0x6363, 0x9188,
+ 0x1000, 0x2104, 0x905d, 0x0904, 0x633b, 0xb8a0, 0x9086, 0x007f,
+ 0x0190, 0xa87c, 0xd0fc, 0x1178, 0x080c, 0x6bd5, 0x0160, 0xa994,
+ 0x81ff, 0x0130, 0x908e, 0x0004, 0x0130, 0x908e, 0x0005, 0x0118,
+ 0x080c, 0x6bcd, 0x1598, 0xa87c, 0xd0fc, 0x01e0, 0xa894, 0x9005,
+ 0x01c8, 0x2060, 0x0026, 0x2010, 0x080c, 0xcc21, 0x002e, 0x1120,
+ 0x2001, 0x0008, 0x0804, 0x6365, 0x6020, 0x9086, 0x000a, 0x0120,
+ 0x2001, 0x0008, 0x0804, 0x6365, 0x601a, 0x6003, 0x0008, 0x2900,
+ 0x6016, 0x0058, 0x080c, 0xaef8, 0x05e8, 0x2b00, 0x6012, 0x2900,
+ 0x6016, 0x600b, 0xffff, 0x6023, 0x000a, 0x2009, 0x0003, 0x080c,
+ 0xafec, 0x9006, 0x0458, 0x2001, 0x0028, 0x0438, 0x9082, 0x0006,
+ 0x1290, 0x080c, 0xae80, 0x1160, 0xb8a0, 0x9084, 0xff80, 0x1140,
+ 0xb900, 0xd1fc, 0x0900, 0x2001, 0x0029, 0x2009, 0x1000, 0x00a8,
+ 0x2001, 0x0028, 0x0090, 0x2009, 0x180c, 0x210c, 0xd18c, 0x0118,
+ 0x2001, 0x0004, 0x0050, 0xd184, 0x0118, 0x2001, 0x0004, 0x0028,
+ 0x2001, 0x0029, 0x0010, 0x2001, 0x0029, 0x9005, 0x012e, 0x00ee,
+ 0x00be, 0x0005, 0x2001, 0x002c, 0x0cc0, 0x00f6, 0x00b6, 0x0126,
+ 0x2091, 0x8000, 0xa8e0, 0x9005, 0x1550, 0xa8dc, 0x9082, 0x0101,
+ 0x1630, 0xa8c8, 0x9005, 0x1518, 0xa8c4, 0x9082, 0x0101, 0x12f8,
+ 0xa974, 0x2079, 0x1800, 0x9182, 0x0800, 0x12e8, 0x7830, 0x9084,
+ 0x0003, 0x1130, 0xaa98, 0xab94, 0xa878, 0x9084, 0x0007, 0x00ea,
+ 0x7930, 0xd18c, 0x0118, 0x2001, 0x0004, 0x0038, 0xd184, 0x0118,
+ 0x2001, 0x0004, 0x0010, 0x2001, 0x0029, 0x900e, 0x0038, 0x2001,
+ 0x002c, 0x900e, 0x0018, 0x2001, 0x0029, 0x900e, 0x9006, 0x0008,
+ 0x9005, 0x012e, 0x00be, 0x00fe, 0x0005, 0x63fa, 0x63b5, 0x63cc,
+ 0x63fa, 0x63fa, 0x63fa, 0x63fa, 0x63fa, 0x2100, 0x9082, 0x007e,
+ 0x1278, 0x080c, 0x6718, 0x0148, 0x9046, 0xb810, 0x9306, 0x1904,
+ 0x6402, 0xb814, 0x9206, 0x15f0, 0x0028, 0xbb12, 0xba16, 0x0010,
+ 0x080c, 0x4adb, 0x0150, 0x04b0, 0x080c, 0x6783, 0x1598, 0xb810,
+ 0x9306, 0x1580, 0xb814, 0x9206, 0x1568, 0x080c, 0xaef8, 0x0530,
+ 0x2b00, 0x6012, 0x080c, 0xd0ce, 0x2900, 0x6016, 0x600b, 0xffff,
+ 0x6023, 0x000a, 0xa878, 0x9086, 0x0001, 0x1170, 0x080c, 0x32fb,
+ 0x9006, 0x080c, 0x66b5, 0x2001, 0x0002, 0x080c, 0x66c9, 0x2001,
+ 0x0200, 0xb86e, 0xb893, 0x0002, 0x2009, 0x0003, 0x080c, 0xafec,
+ 0x9006, 0x0068, 0x2001, 0x0001, 0x900e, 0x0038, 0x2001, 0x002c,
+ 0x900e, 0x0018, 0x2001, 0x0028, 0x900e, 0x9005, 0x0000, 0x012e,
+ 0x00be, 0x00fe, 0x0005, 0x00b6, 0x00f6, 0x00e6, 0x0126, 0x2091,
+ 0x8000, 0xa894, 0x90c6, 0x0015, 0x0904, 0x65ed, 0x90c6, 0x0056,
+ 0x0904, 0x65f1, 0x90c6, 0x0066, 0x0904, 0x65f5, 0x90c6, 0x0067,
+ 0x0904, 0x65f9, 0x90c6, 0x0068, 0x0904, 0x65fd, 0x90c6, 0x0071,
+ 0x0904, 0x6601, 0x90c6, 0x0074, 0x0904, 0x6605, 0x90c6, 0x007c,
+ 0x0904, 0x6609, 0x90c6, 0x007e, 0x0904, 0x660d, 0x90c6, 0x0037,
+ 0x0904, 0x6611, 0x9016, 0x2079, 0x1800, 0xa974, 0x9186, 0x00ff,
+ 0x0904, 0x65e8, 0x9182, 0x0800, 0x1a04, 0x65e8, 0x080c, 0x6783,
+ 0x1198, 0xb804, 0x9084, 0x00ff, 0x9082, 0x0006, 0x1268, 0xa894,
+ 0x90c6, 0x006f, 0x0148, 0x080c, 0xae80, 0x1904, 0x65d1, 0xb8a0,
+ 0x9084, 0xff80, 0x1904, 0x65d1, 0xa894, 0x90c6, 0x006f, 0x0158,
+ 0x90c6, 0x005e, 0x0904, 0x6531, 0x90c6, 0x0064, 0x0904, 0x655a,
+ 0x2008, 0x0804, 0x64f3, 0xa998, 0xa8b0, 0x2040, 0x080c, 0xae80,
+ 0x1120, 0x9182, 0x007f, 0x0a04, 0x64f3, 0x9186, 0x00ff, 0x0904,
+ 0x64f3, 0x9182, 0x0800, 0x1a04, 0x64f3, 0xaaa0, 0xab9c, 0x787c,
+ 0x9306, 0x11a8, 0x7880, 0x0096, 0x924e, 0x1128, 0x2208, 0x2310,
+ 0x009e, 0x0804, 0x64f3, 0x080c, 0xae80, 0x1140, 0x99cc, 0xff00,
+ 0x009e, 0x1128, 0x2208, 0x2310, 0x0804, 0x64f3, 0x009e, 0x080c,
+ 0x4adb, 0x0904, 0x64fd, 0x900e, 0x9016, 0x90c6, 0x4000, 0x15e0,
+ 0x0006, 0x080c, 0x6a74, 0x1108, 0xc185, 0xb800, 0xd0bc, 0x0108,
+ 0xc18d, 0x20a9, 0x0004, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0031,
+ 0x20a0, 0xb8c4, 0x20e0, 0xb8c8, 0x9080, 0x0006, 0x2098, 0x080c,
+ 0x0fca, 0x20a9, 0x0004, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0035,
+ 0x20a0, 0xb8c4, 0x20e0, 0xb8c8, 0x9080, 0x000a, 0x2098, 0x080c,
+ 0x0fca, 0xa8c4, 0xabc8, 0x9305, 0xabcc, 0x9305, 0xabd0, 0x9305,
+ 0xabd4, 0x9305, 0xabd8, 0x9305, 0xabdc, 0x9305, 0xabe0, 0x9305,
+ 0x9005, 0x0510, 0x000e, 0x00c8, 0x90c6, 0x4007, 0x1110, 0x2408,
+ 0x00a0, 0x90c6, 0x4008, 0x1118, 0x2708, 0x2610, 0x0070, 0x90c6,
+ 0x4009, 0x1108, 0x0050, 0x90c6, 0x4006, 0x0138, 0x2001, 0x4005,
+ 0x2009, 0x000a, 0x0010, 0x2001, 0x4006, 0xa896, 0xa99a, 0xaa9e,
+ 0x2001, 0x0030, 0x900e, 0x0478, 0x000e, 0x080c, 0xaef8, 0x1130,
+ 0x2001, 0x4005, 0x2009, 0x0003, 0x9016, 0x0c78, 0x2b00, 0x6012,
+ 0x080c, 0xd0ce, 0x2900, 0x6016, 0x6023, 0x0001, 0xa868, 0xd88c,
+ 0x0108, 0xc0f5, 0xa86a, 0x0126, 0x2091, 0x8000, 0x080c, 0x32fb,
+ 0x012e, 0x9006, 0x080c, 0x66b5, 0x2001, 0x0002, 0x080c, 0x66c9,
+ 0x2009, 0x0002, 0x080c, 0xafec, 0xa8b0, 0xd094, 0x0118, 0xb8d4,
+ 0xc08d, 0xb8d6, 0x9006, 0x9005, 0x012e, 0x00ee, 0x00fe, 0x00be,
+ 0x0005, 0x080c, 0x5834, 0x0118, 0x2009, 0x0007, 0x00f8, 0xa998,
+ 0xaeb0, 0x080c, 0x6783, 0x1904, 0x64ee, 0x9186, 0x007f, 0x0130,
+ 0x080c, 0x6bcd, 0x0118, 0x2009, 0x0009, 0x0080, 0x0096, 0x080c,
+ 0x104d, 0x1120, 0x009e, 0x2009, 0x0002, 0x0040, 0x2900, 0x009e,
+ 0xa806, 0x080c, 0xce21, 0x19b0, 0x2009, 0x0003, 0x2001, 0x4005,
+ 0x0804, 0x64f5, 0xa998, 0xaeb0, 0x080c, 0x6783, 0x1904, 0x64ee,
+ 0x0096, 0x080c, 0x104d, 0x1128, 0x009e, 0x2009, 0x0002, 0x0804,
+ 0x65ae, 0x2900, 0x009e, 0xa806, 0x0096, 0x2048, 0x20a9, 0x002b,
+ 0xb8c4, 0x20e0, 0xb8c8, 0x2098, 0xa860, 0x20e8, 0xa85c, 0x9080,
+ 0x0002, 0x20a0, 0x4003, 0x20a9, 0x0008, 0x9080, 0x0006, 0x20a0,
+ 0xbbc8, 0x9398, 0x0006, 0x2398, 0x080c, 0x0fca, 0x009e, 0xa87b,
+ 0x0000, 0xa883, 0x0000, 0xa897, 0x4000, 0xd684, 0x1168, 0x080c,
+ 0x5820, 0xd0b4, 0x1118, 0xa89b, 0x000b, 0x00e0, 0xb800, 0xd08c,
+ 0x0118, 0xa89b, 0x000c, 0x00b0, 0x080c, 0x6bcd, 0x0118, 0xa89b,
+ 0x0009, 0x0080, 0x080c, 0x5834, 0x0118, 0xa89b, 0x0007, 0x0050,
+ 0x080c, 0xce04, 0x1904, 0x652a, 0x2009, 0x0003, 0x2001, 0x4005,
+ 0x0804, 0x64f5, 0xa87b, 0x0030, 0xa897, 0x4005, 0xa804, 0x8006,
+ 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, 0x0002,
+ 0x2009, 0x002b, 0xaaa0, 0xab9c, 0xaca8, 0xada4, 0x2031, 0x0000,
+ 0x2041, 0x129c, 0x080c, 0xb473, 0x1904, 0x652a, 0x2009, 0x0002,
+ 0x08e8, 0x2001, 0x0028, 0x900e, 0x0804, 0x652b, 0x2009, 0x180c,
+ 0x210c, 0xd18c, 0x0118, 0x2001, 0x0004, 0x0038, 0xd184, 0x0118,
+ 0x2001, 0x0004, 0x0010, 0x2001, 0x0029, 0x900e, 0x0804, 0x652b,
+ 0x2001, 0x0029, 0x900e, 0x0804, 0x652b, 0x080c, 0x38a4, 0x0804,
+ 0x652c, 0x080c, 0x553d, 0x0804, 0x652c, 0x080c, 0x468c, 0x0804,
+ 0x652c, 0x080c, 0x4705, 0x0804, 0x652c, 0x080c, 0x4761, 0x0804,
+ 0x652c, 0x080c, 0x4b9e, 0x0804, 0x652c, 0x080c, 0x4e52, 0x0804,
+ 0x652c, 0x080c, 0x51a4, 0x0804, 0x652c, 0x080c, 0x539d, 0x0804,
+ 0x652c, 0x080c, 0x3ac2, 0x0804, 0x652c, 0x00b6, 0xa974, 0xae78,
+ 0x9684, 0x3fff, 0x9082, 0x4000, 0x1608, 0x9182, 0x0800, 0x1258,
+ 0x9188, 0x1000, 0x2104, 0x905d, 0x0130, 0x080c, 0x6bcd, 0x1138,
+ 0x00d9, 0x9006, 0x00b0, 0x2001, 0x0028, 0x900e, 0x0090, 0x9082,
+ 0x0006, 0x1240, 0xb900, 0xd1fc, 0x0d98, 0x2001, 0x0029, 0x2009,
+ 0x1000, 0x0038, 0x2001, 0x0029, 0x900e, 0x0018, 0x2001, 0x0029,
+ 0x900e, 0x9005, 0x00be, 0x0005, 0xa877, 0x0000, 0xb8d0, 0x9005,
+ 0x1904, 0x66a9, 0xb888, 0x9005, 0x1904, 0x66a9, 0xb838, 0xb93c,
+ 0x9102, 0x1a04, 0x66a9, 0x2b10, 0x080c, 0xaf25, 0x0904, 0x66a5,
+ 0x8108, 0xb93e, 0x6212, 0x2900, 0x6016, 0x6023, 0x0003, 0x600b,
+ 0xffff, 0x6007, 0x0040, 0xa878, 0x605e, 0xa880, 0x6066, 0xa883,
+ 0x0000, 0xa87c, 0xd0ac, 0x0588, 0xc0dd, 0xa87e, 0xa888, 0x8001,
+ 0x1530, 0xa816, 0xa864, 0x9094, 0x00f7, 0x9296, 0x0011, 0x11f8,
+ 0x9084, 0x00ff, 0xc0bd, 0x601e, 0xa8ac, 0xaab0, 0xa836, 0xaa3a,
+ 0x2001, 0x000f, 0x8001, 0x1df0, 0x2001, 0x8004, 0x6003, 0x0004,
+ 0x6046, 0x00f6, 0x2079, 0x0380, 0x7818, 0xd0bc, 0x1de8, 0x7833,
+ 0x0010, 0x2c00, 0x7836, 0x781b, 0x8080, 0x00fe, 0x0005, 0x080c,
+ 0x17a1, 0x601c, 0xc0bd, 0x601e, 0x0c38, 0xd0b4, 0x190c, 0x1cb9,
+ 0x2001, 0x8004, 0x6003, 0x0002, 0x0c18, 0x81ff, 0x1110, 0xb88b,
+ 0x0001, 0x2908, 0xb8cc, 0xb9ce, 0x9005, 0x1110, 0xb9d2, 0x0020,
+ 0x0096, 0x2048, 0xa902, 0x009e, 0x0005, 0x00b6, 0x0126, 0x00c6,
+ 0x0026, 0x2091, 0x8000, 0x6210, 0x2258, 0xba00, 0x9005, 0x0110,
+ 0xc285, 0x0008, 0xc284, 0xba02, 0x002e, 0x00ce, 0x012e, 0x00be,
+ 0x0005, 0x00b6, 0x0126, 0x00c6, 0x2091, 0x8000, 0x6210, 0x2258,
+ 0xba04, 0x0006, 0x9086, 0x0006, 0x1170, 0xb89c, 0xd0ac, 0x0158,
+ 0x080c, 0x6bc9, 0x0140, 0x9284, 0xff00, 0x8007, 0x9086, 0x0007,
+ 0x1110, 0x2011, 0x0600, 0x000e, 0x9294, 0xff00, 0x9215, 0xba06,
+ 0x0006, 0x9086, 0x0006, 0x1120, 0xba90, 0x82ff, 0x090c, 0x0d79,
+ 0x000e, 0x00ce, 0x012e, 0x00be, 0x0005, 0x00b6, 0x0126, 0x00c6,
+ 0x2091, 0x8000, 0x6210, 0x2258, 0xba04, 0x0006, 0x9086, 0x0006,
+ 0x1168, 0xb89c, 0xd0a4, 0x0150, 0x080c, 0x6bc5, 0x1138, 0x9284,
+ 0x00ff, 0x9086, 0x0007, 0x1110, 0x2011, 0x0006, 0x000e, 0x9294,
+ 0x00ff, 0x8007, 0x9215, 0xba06, 0x00ce, 0x012e, 0x00be, 0x0005,
+ 0x9182, 0x0800, 0x0218, 0x9085, 0x0001, 0x0005, 0x00d6, 0x0026,
+ 0x9190, 0x1000, 0x2204, 0x905d, 0x1188, 0x0096, 0x080c, 0x104d,
+ 0x2958, 0x009e, 0x0168, 0x2b00, 0x2012, 0xb85c, 0xb8ca, 0xb860,
+ 0xb8c6, 0x9006, 0xb8a6, 0xb8ae, 0x080c, 0x6192, 0x9006, 0x0010,
+ 0x9085, 0x0001, 0x002e, 0x00de, 0x0005, 0x00b6, 0x0096, 0x0126,
+ 0x2091, 0x8000, 0x0026, 0x9182, 0x0800, 0x0218, 0x9085, 0x0001,
+ 0x04a8, 0x00d6, 0x9190, 0x1000, 0x2204, 0x905d, 0x0568, 0x2013,
+ 0x0000, 0xb8a4, 0x904d, 0x0110, 0x080c, 0x107f, 0x00d6, 0x00c6,
+ 0xb8bc, 0x2060, 0x8cff, 0x0168, 0x600c, 0x0006, 0x6014, 0x2048,
+ 0x080c, 0xcc33, 0x0110, 0x080c, 0x0fff, 0x080c, 0xaf4e, 0x00ce,
+ 0x0c88, 0x00ce, 0x00de, 0x00c6, 0xb8ac, 0x9065, 0x0128, 0x621c,
+ 0xd2c4, 0x0110, 0x080c, 0x9128, 0x00ce, 0x2b48, 0xb8c8, 0xb85e,
+ 0xb8c4, 0xb862, 0x080c, 0x108f, 0x00de, 0x9006, 0x002e, 0x012e,
+ 0x009e, 0x00be, 0x0005, 0x0016, 0x9182, 0x0800, 0x0218, 0x9085,
+ 0x0001, 0x0030, 0x9188, 0x1000, 0x2104, 0x905d, 0x0dc0, 0x9006,
+ 0x001e, 0x0005, 0x00d6, 0x0156, 0x0136, 0x0146, 0x9006, 0xb80a,
+ 0xb80e, 0xb800, 0xc08c, 0xb802, 0x080c, 0x769d, 0x1510, 0xb8a0,
+ 0x9086, 0x007e, 0x0120, 0x080c, 0xae80, 0x11d8, 0x0078, 0x7040,
+ 0xd0e4, 0x01b8, 0x00c6, 0x2061, 0x1983, 0x7048, 0x2062, 0x704c,
+ 0x6006, 0x7050, 0x600a, 0x7054, 0x600e, 0x00ce, 0x703c, 0x2069,
+ 0x0140, 0x9005, 0x1110, 0x2001, 0x0001, 0x6886, 0x2069, 0x1800,
+ 0x68b6, 0x7040, 0xb85e, 0x7048, 0xb862, 0x704c, 0xb866, 0x20e1,
+ 0x0000, 0x2099, 0x0276, 0xb8c4, 0x20e8, 0xb8c8, 0x9088, 0x000a,
+ 0x21a0, 0x20a9, 0x0004, 0x4003, 0x2099, 0x027a, 0x9088, 0x0006,
+ 0x21a0, 0x20a9, 0x0004, 0x4003, 0x2069, 0x0200, 0x6817, 0x0001,
+ 0x7040, 0xb86a, 0x7144, 0xb96e, 0x7048, 0xb872, 0x7050, 0xb876,
+ 0x2069, 0x0200, 0x6817, 0x0000, 0xb8a0, 0x9086, 0x007e, 0x1110,
+ 0x7144, 0xb96e, 0x9182, 0x0211, 0x1218, 0x2009, 0x0008, 0x0400,
+ 0x9182, 0x0259, 0x1218, 0x2009, 0x0007, 0x00d0, 0x9182, 0x02c1,
+ 0x1218, 0x2009, 0x0006, 0x00a0, 0x9182, 0x0349, 0x1218, 0x2009,
+ 0x0005, 0x0070, 0x9182, 0x0421, 0x1218, 0x2009, 0x0004, 0x0040,
+ 0x9182, 0x0581, 0x1218, 0x2009, 0x0003, 0x0010, 0x2009, 0x0002,
+ 0xb992, 0x014e, 0x013e, 0x015e, 0x00de, 0x0005, 0x0016, 0x0026,
+ 0x00e6, 0x2071, 0x0260, 0x7034, 0xb896, 0x703c, 0xb89a, 0x7054,
+ 0xb89e, 0x0036, 0xbbd4, 0xc384, 0xba00, 0x2009, 0x1867, 0x210c,
+ 0xd0bc, 0x0120, 0xd1ec, 0x0110, 0xc2ad, 0x0008, 0xc2ac, 0xd0c4,
+ 0x0148, 0xd1e4, 0x0138, 0xc2bd, 0xd0cc, 0x0128, 0xd38c, 0x1108,
+ 0xc385, 0x0008, 0xc2bc, 0xba02, 0xbbd6, 0x003e, 0x00ee, 0x002e,
+ 0x001e, 0x0005, 0x0096, 0x0126, 0x2091, 0x8000, 0xb8a4, 0x904d,
+ 0x0578, 0xa900, 0x81ff, 0x15c0, 0xaa04, 0x9282, 0x0010, 0x16c8,
+ 0x0136, 0x0146, 0x01c6, 0x01d6, 0x8906, 0x8006, 0x8007, 0x908c,
+ 0x003f, 0x21e0, 0x9084, 0xffc0, 0x9080, 0x0004, 0x2098, 0x2009,
+ 0x0010, 0x20a9, 0x0001, 0x4002, 0x9086, 0xffff, 0x0120, 0x8109,
+ 0x1dd0, 0x080c, 0x0d79, 0x3c00, 0x20e8, 0x3300, 0x8001, 0x20a0,
+ 0x4604, 0x8210, 0xaa06, 0x01de, 0x01ce, 0x014e, 0x013e, 0x0060,
+ 0x080c, 0x104d, 0x0170, 0x2900, 0xb8a6, 0xa803, 0x0000, 0x080c,
+ 0x6a10, 0xa807, 0x0001, 0xae12, 0x9085, 0x0001, 0x012e, 0x009e,
+ 0x0005, 0x9006, 0x0cd8, 0x0126, 0x2091, 0x8000, 0x0096, 0xb8a4,
+ 0x904d, 0x0188, 0xa800, 0x9005, 0x1150, 0x080c, 0x6a1f, 0x1158,
+ 0xa804, 0x908a, 0x0002, 0x0218, 0x8001, 0xa806, 0x0020, 0x080c,
+ 0x107f, 0xb8a7, 0x0000, 0x009e, 0x012e, 0x0005, 0x0096, 0x00c6,
+ 0xb888, 0x9005, 0x1904, 0x6905, 0xb8d0, 0x904d, 0x0904, 0x6905,
+ 0x080c, 0xaf25, 0x0904, 0x6903, 0x8210, 0xba3e, 0xa800, 0xb8d2,
+ 0x9005, 0x1108, 0xb8ce, 0x2b00, 0x6012, 0x2900, 0x6016, 0x6023,
+ 0x0003, 0x600b, 0xffff, 0x6007, 0x0040, 0xa878, 0x605e, 0xa880,
+ 0x9084, 0x00ff, 0x6066, 0xa883, 0x0000, 0xa87c, 0xd0ac, 0x01c8,
+ 0xc0dd, 0xa87e, 0xa888, 0x8001, 0x1558, 0xa816, 0xa864, 0x9094,
+ 0x00f7, 0x9296, 0x0011, 0x1520, 0x9084, 0x00ff, 0xc0bd, 0x601e,
+ 0xa8ac, 0xaab0, 0xa836, 0xaa3a, 0x2001, 0x8004, 0x6003, 0x0004,
+ 0x0030, 0x080c, 0x1cb9, 0x2001, 0x8004, 0x6003, 0x0002, 0x6046,
+ 0x2001, 0x0010, 0x2c08, 0x080c, 0xaae8, 0xb838, 0xba3c, 0x9202,
+ 0x0a04, 0x68b4, 0x0010, 0xb88b, 0x0001, 0x00ce, 0x009e, 0x0005,
+ 0x080c, 0x17a1, 0x601c, 0xc0bd, 0x601e, 0x08f0, 0x00b6, 0x0096,
+ 0x0016, 0x20a9, 0x0800, 0x900e, 0x0016, 0x080c, 0x6783, 0x1158,
0xb8d0, 0x904d, 0x0140, 0x3e00, 0x9086, 0x0002, 0x1118, 0xb800,
- 0xd0bc, 0x1108, 0x0041, 0x001e, 0x8108, 0x1f04, 0x691c, 0x001e,
+ 0xd0bc, 0x1108, 0x0041, 0x001e, 0x8108, 0x1f04, 0x6914, 0x001e,
0x00be, 0x009e, 0x0005, 0x0096, 0x0016, 0xb8d0, 0x904d, 0x0188,
0xa800, 0xb8d2, 0x9005, 0x1108, 0xb8ce, 0x9006, 0xa802, 0xa867,
- 0x0103, 0xab7a, 0xa877, 0x0000, 0x080c, 0xcf1b, 0x080c, 0x6f19,
+ 0x0103, 0xab7a, 0xa877, 0x0000, 0x080c, 0xcf38, 0x080c, 0x6f11,
0x0c60, 0x001e, 0x009e, 0x0005, 0x0086, 0x9046, 0xb8d0, 0x904d,
0x01b0, 0xa86c, 0x9406, 0x1118, 0xa870, 0x9506, 0x0128, 0x2940,
0xa800, 0x904d, 0x0160, 0x0ca8, 0xa800, 0x88ff, 0x1128, 0xb8d2,
@@ -3172,18 +3159,18 @@ unsigned short risc_code01[] = {
0x7028, 0x9065, 0x01e8, 0x6014, 0x2068, 0x83ff, 0x0120, 0x605c,
0x9606, 0x0158, 0x0030, 0xa86c, 0x9406, 0x1118, 0xa870, 0x9506,
0x0120, 0x2c40, 0x600c, 0x2060, 0x0c60, 0x600c, 0x0006, 0x0066,
- 0x2830, 0x080c, 0xa20a, 0x006e, 0x000e, 0x83ff, 0x0508, 0x0c08,
+ 0x2830, 0x080c, 0xa21b, 0x006e, 0x000e, 0x83ff, 0x0508, 0x0c08,
0x9046, 0xb8d0, 0x904d, 0x01e0, 0x83ff, 0x0120, 0xa878, 0x9606,
0x0158, 0x0030, 0xa86c, 0x9406, 0x1118, 0xa870, 0x9506, 0x0120,
0x2940, 0xa800, 0x2048, 0x0c70, 0xb8d0, 0xaa00, 0x0026, 0x9906,
0x1110, 0xbad2, 0x0008, 0xa202, 0x000e, 0x83ff, 0x0108, 0x0c10,
0x002e, 0x008e, 0x00ce, 0x009e, 0x00ee, 0x012e, 0x0005, 0x9016,
- 0x0489, 0x1110, 0x2011, 0x0001, 0x0005, 0x080c, 0x6a7c, 0x0128,
- 0x080c, 0xccd7, 0x0010, 0x9085, 0x0001, 0x0005, 0x080c, 0x6a7c,
- 0x0128, 0x080c, 0xcc78, 0x0010, 0x9085, 0x0001, 0x0005, 0x080c,
- 0x6a7c, 0x0128, 0x080c, 0xccd4, 0x0010, 0x9085, 0x0001, 0x0005,
- 0x080c, 0x6a7c, 0x0128, 0x080c, 0xcc97, 0x0010, 0x9085, 0x0001,
- 0x0005, 0x080c, 0x6a7c, 0x0128, 0x080c, 0xcd1a, 0x0010, 0x9085,
+ 0x0489, 0x1110, 0x2011, 0x0001, 0x0005, 0x080c, 0x6a74, 0x0128,
+ 0x080c, 0xccf4, 0x0010, 0x9085, 0x0001, 0x0005, 0x080c, 0x6a74,
+ 0x0128, 0x080c, 0xcc95, 0x0010, 0x9085, 0x0001, 0x0005, 0x080c,
+ 0x6a74, 0x0128, 0x080c, 0xccf1, 0x0010, 0x9085, 0x0001, 0x0005,
+ 0x080c, 0x6a74, 0x0128, 0x080c, 0xccb4, 0x0010, 0x9085, 0x0001,
+ 0x0005, 0x080c, 0x6a74, 0x0128, 0x080c, 0xcd37, 0x0010, 0x9085,
0x0001, 0x0005, 0xb8a4, 0x900d, 0x1118, 0x9085, 0x0001, 0x0005,
0x0136, 0x01c6, 0xa800, 0x9005, 0x11b8, 0x890e, 0x810e, 0x810f,
0x9184, 0x003f, 0x20e0, 0x9184, 0xffc0, 0x9080, 0x0004, 0x2098,
@@ -3197,38 +3184,38 @@ unsigned short risc_code01[] = {
0x9085, 0x0001, 0x0068, 0x0146, 0x01d6, 0x3300, 0x8001, 0x20a0,
0x3c00, 0x20e8, 0x2001, 0xffff, 0x4004, 0x01de, 0x014e, 0x9006,
0x01ce, 0x013e, 0x0005, 0x0096, 0x0126, 0x2091, 0x8000, 0xb8a4,
- 0x904d, 0x1128, 0x080c, 0x1059, 0x0168, 0x2900, 0xb8a6, 0x080c,
- 0x6a18, 0xa803, 0x0001, 0xa807, 0x0000, 0x9085, 0x0001, 0x012e,
+ 0x904d, 0x1128, 0x080c, 0x104d, 0x0168, 0x2900, 0xb8a6, 0x080c,
+ 0x6a10, 0xa803, 0x0001, 0xa807, 0x0000, 0x9085, 0x0001, 0x012e,
0x009e, 0x0005, 0x9006, 0x0cd8, 0x0096, 0x0126, 0x2091, 0x8000,
- 0xb8a4, 0x904d, 0x0130, 0xb8a7, 0x0000, 0x080c, 0x108b, 0x9085,
+ 0xb8a4, 0x904d, 0x0130, 0xb8a7, 0x0000, 0x080c, 0x107f, 0x9085,
0x0001, 0x012e, 0x009e, 0x0005, 0xb89c, 0xd0a4, 0x0005, 0x00b6,
- 0x00f6, 0x080c, 0x76a5, 0x01b0, 0x71c4, 0x81ff, 0x1198, 0x71dc,
+ 0x00f6, 0x080c, 0x769d, 0x01b0, 0x71c4, 0x81ff, 0x1198, 0x71dc,
0xd19c, 0x0180, 0x2001, 0x007e, 0x9080, 0x1000, 0x2004, 0x905d,
0x0148, 0xb804, 0x9084, 0x00ff, 0x9086, 0x0006, 0x1118, 0xb800,
0xc0ed, 0xb802, 0x2079, 0x1847, 0x7804, 0xd0a4, 0x01d0, 0x0156,
- 0x20a9, 0x007f, 0x900e, 0x0016, 0x080c, 0x6789, 0x1168, 0xb804,
+ 0x20a9, 0x007f, 0x900e, 0x0016, 0x080c, 0x6783, 0x1168, 0xb804,
0x9084, 0xff00, 0x8007, 0x9096, 0x0004, 0x0118, 0x9086, 0x0006,
- 0x1118, 0xb800, 0xc0ed, 0xb802, 0x001e, 0x8108, 0x1f04, 0x6aa3,
- 0x015e, 0x080c, 0x6b93, 0x0120, 0x2001, 0x1986, 0x200c, 0x0038,
+ 0x1118, 0xb800, 0xc0ed, 0xb802, 0x001e, 0x8108, 0x1f04, 0x6a9b,
+ 0x015e, 0x080c, 0x6b8b, 0x0120, 0x2001, 0x1986, 0x200c, 0x0038,
0x2079, 0x1847, 0x7804, 0xd0a4, 0x0130, 0x2009, 0x07d0, 0x2011,
- 0x6ace, 0x080c, 0x88fe, 0x00fe, 0x00be, 0x0005, 0x00b6, 0x2011,
- 0x6ace, 0x080c, 0x8834, 0x080c, 0x6b93, 0x01d8, 0x2001, 0x107e,
- 0x2004, 0x2058, 0xb900, 0xc1ec, 0xb902, 0x080c, 0x6bd1, 0x0130,
- 0x2009, 0x07d0, 0x2011, 0x6ace, 0x080c, 0x88fe, 0x00e6, 0x2071,
- 0x1800, 0x9006, 0x707e, 0x7060, 0x7082, 0x080c, 0x30e1, 0x00ee,
+ 0x6ac6, 0x080c, 0x88f6, 0x00fe, 0x00be, 0x0005, 0x00b6, 0x2011,
+ 0x6ac6, 0x080c, 0x882c, 0x080c, 0x6b8b, 0x01d8, 0x2001, 0x107e,
+ 0x2004, 0x2058, 0xb900, 0xc1ec, 0xb902, 0x080c, 0x6bc9, 0x0130,
+ 0x2009, 0x07d0, 0x2011, 0x6ac6, 0x080c, 0x88f6, 0x00e6, 0x2071,
+ 0x1800, 0x9006, 0x707e, 0x7060, 0x7082, 0x080c, 0x30c8, 0x00ee,
0x04e0, 0x0156, 0x00c6, 0x20a9, 0x007f, 0x900e, 0x0016, 0x080c,
- 0x6789, 0x1568, 0xb800, 0xd0ec, 0x0550, 0xd0bc, 0x1540, 0x0046,
- 0xbaa0, 0x2220, 0x9006, 0x2009, 0x0029, 0x080c, 0xe72a, 0xb800,
- 0xc0e5, 0xc0ec, 0xb802, 0x080c, 0x6bcd, 0x2001, 0x0707, 0x1128,
- 0xb804, 0x9084, 0x00ff, 0x9085, 0x0700, 0xb806, 0x080c, 0xaae0,
- 0x2019, 0x0029, 0x080c, 0x95c1, 0x0076, 0x903e, 0x080c, 0x947e,
- 0x900e, 0x080c, 0xe440, 0x007e, 0x004e, 0x080c, 0xaafc, 0x001e,
- 0x8108, 0x1f04, 0x6af6, 0x00ce, 0x015e, 0x00be, 0x0005, 0x00b6,
+ 0x6783, 0x1568, 0xb800, 0xd0ec, 0x0550, 0xd0bc, 0x1540, 0x0046,
+ 0xbaa0, 0x2220, 0x9006, 0x2009, 0x0029, 0x080c, 0xe795, 0xb800,
+ 0xc0e5, 0xc0ec, 0xb802, 0x080c, 0x6bc5, 0x2001, 0x0707, 0x1128,
+ 0xb804, 0x9084, 0x00ff, 0x9085, 0x0700, 0xb806, 0x080c, 0xaaf7,
+ 0x2019, 0x0029, 0x080c, 0x95b9, 0x0076, 0x903e, 0x080c, 0x9476,
+ 0x900e, 0x080c, 0xe465, 0x007e, 0x004e, 0x080c, 0xab13, 0x001e,
+ 0x8108, 0x1f04, 0x6aee, 0x00ce, 0x015e, 0x00be, 0x0005, 0x00b6,
0x6010, 0x2058, 0xb800, 0xc0ec, 0xb802, 0x00be, 0x0005, 0x00b6,
- 0x00c6, 0x0096, 0x080c, 0x1072, 0x090c, 0x0d85, 0x2958, 0x009e,
+ 0x00c6, 0x0096, 0x080c, 0x1066, 0x090c, 0x0d79, 0x2958, 0x009e,
0x2001, 0x196c, 0x2b02, 0x8b07, 0x8006, 0x8006, 0x908c, 0x003f,
0xb9c6, 0x908c, 0xffc0, 0xb9ca, 0xb8af, 0x0000, 0x2009, 0x00ff,
- 0x080c, 0x6198, 0xb807, 0x0006, 0xb813, 0x00ff, 0xb817, 0xffff,
+ 0x080c, 0x6192, 0xb807, 0x0006, 0xb813, 0x00ff, 0xb817, 0xffff,
0xb86f, 0x0200, 0xb86c, 0xb893, 0x0002, 0xb8bb, 0x0520, 0xb8a3,
0x00ff, 0xb8af, 0x0000, 0x00ce, 0x00be, 0x0005, 0x7810, 0x00b6,
0x2058, 0xb800, 0x00be, 0xd0ac, 0x0005, 0x6010, 0x00b6, 0x905d,
@@ -3239,23 +3226,23 @@ unsigned short risc_code01[] = {
0x001e, 0x000e, 0x0005, 0x00b6, 0x00f6, 0x2001, 0x107e, 0x2004,
0x905d, 0x0110, 0xb800, 0xd0ec, 0x00fe, 0x00be, 0x0005, 0x0126,
0x0026, 0x2091, 0x8000, 0x0006, 0xbaa0, 0x9290, 0x1000, 0x2204,
- 0x9b06, 0x190c, 0x0d85, 0x000e, 0xba00, 0x9005, 0x0110, 0xc2fd,
+ 0x9b06, 0x190c, 0x0d79, 0x000e, 0xba00, 0x9005, 0x0110, 0xc2fd,
0x0008, 0xc2fc, 0xba02, 0x002e, 0x012e, 0x0005, 0x2011, 0x1837,
- 0x2204, 0xd0cc, 0x0138, 0x2001, 0x1984, 0x200c, 0x2011, 0x6bc3,
- 0x080c, 0x88fe, 0x0005, 0x2011, 0x6bc3, 0x080c, 0x8834, 0x2011,
- 0x1837, 0x2204, 0xc0cc, 0x2012, 0x0005, 0x080c, 0x5826, 0xd0ac,
- 0x0005, 0x080c, 0x5826, 0xd0a4, 0x0005, 0x0016, 0xb904, 0x9184,
+ 0x2204, 0xd0cc, 0x0138, 0x2001, 0x1984, 0x200c, 0x2011, 0x6bbb,
+ 0x080c, 0x88f6, 0x0005, 0x2011, 0x6bbb, 0x080c, 0x882c, 0x2011,
+ 0x1837, 0x2204, 0xc0cc, 0x2012, 0x0005, 0x080c, 0x5820, 0xd0ac,
+ 0x0005, 0x080c, 0x5820, 0xd0a4, 0x0005, 0x0016, 0xb904, 0x9184,
0x00ff, 0x908e, 0x0006, 0x001e, 0x0005, 0x0016, 0xb904, 0x9184,
0xff00, 0x8007, 0x908e, 0x0006, 0x001e, 0x0005, 0x00b6, 0x00f6,
- 0x080c, 0xd33e, 0x0158, 0x70dc, 0x9084, 0x0028, 0x0138, 0x2001,
+ 0x080c, 0xd35d, 0x0158, 0x70dc, 0x9084, 0x0028, 0x0138, 0x2001,
0x107f, 0x2004, 0x905d, 0x0110, 0xb8d4, 0xd094, 0x00fe, 0x00be,
0x0005, 0x2071, 0x1910, 0x7003, 0x0001, 0x7007, 0x0000, 0x9006,
0x7012, 0x7016, 0x701a, 0x701e, 0x700a, 0x7046, 0x2001, 0x1922,
0x2003, 0x0000, 0x0005, 0x0016, 0x00e6, 0x2071, 0x1949, 0x900e,
- 0x710a, 0x080c, 0x5826, 0xd0fc, 0x1140, 0x080c, 0x5826, 0x900e,
+ 0x710a, 0x080c, 0x5820, 0xd0fc, 0x1140, 0x080c, 0x5820, 0x900e,
0xd09c, 0x0108, 0x8108, 0x7102, 0x0430, 0x2001, 0x1867, 0x200c,
- 0x9184, 0x0007, 0x0002, 0x6c15, 0x6c15, 0x6c15, 0x6c15, 0x6c15,
- 0x6c2b, 0x6c40, 0x6c4e, 0x7003, 0x0003, 0x2009, 0x1868, 0x210c,
+ 0x9184, 0x0007, 0x0002, 0x6c0d, 0x6c0d, 0x6c0d, 0x6c0d, 0x6c0d,
+ 0x6c23, 0x6c38, 0x6c46, 0x7003, 0x0003, 0x2009, 0x1868, 0x210c,
0x9184, 0xff00, 0x908e, 0xff00, 0x0140, 0x8007, 0x9005, 0x1110,
0x2001, 0x0002, 0x8003, 0x7006, 0x0030, 0x7007, 0x0001, 0x0018,
0x7003, 0x0005, 0x0c50, 0x2071, 0x1910, 0x704f, 0x0000, 0x2071,
@@ -3266,66 +3253,66 @@ unsigned short risc_code01[] = {
0x000f, 0x0c90, 0x70f7, 0x0005, 0x08f0, 0x00e6, 0x2071, 0x0050,
0x684c, 0x9005, 0x1150, 0x00e6, 0x2071, 0x1910, 0x7028, 0xc085,
0x702a, 0x00ee, 0x9085, 0x0001, 0x0488, 0x6844, 0x9005, 0x0158,
- 0x080c, 0x7a19, 0x6a60, 0x9200, 0x7002, 0x6864, 0x9101, 0x7006,
+ 0x080c, 0x7a11, 0x6a60, 0x9200, 0x7002, 0x6864, 0x9101, 0x7006,
0x9006, 0x7012, 0x7016, 0x6860, 0x7002, 0x6864, 0x7006, 0x6868,
0x700a, 0x686c, 0x700e, 0x6844, 0x9005, 0x1110, 0x7012, 0x7016,
0x684c, 0x701a, 0x701c, 0x9085, 0x0040, 0x701e, 0x7037, 0x0019,
0x702b, 0x0001, 0x00e6, 0x2071, 0x1910, 0x7028, 0xc084, 0x702a,
0x7007, 0x0001, 0x700b, 0x0000, 0x00ee, 0x9006, 0x00ee, 0x0005,
- 0x00e6, 0x0026, 0x2071, 0x1949, 0x7000, 0x9015, 0x0904, 0x6f1e,
- 0x9286, 0x0003, 0x0904, 0x6db3, 0x9286, 0x0005, 0x0904, 0x6db3,
- 0x2071, 0x1877, 0xa87c, 0x9005, 0x0904, 0x6d0e, 0x7140, 0xa868,
- 0x9102, 0x0a04, 0x6f1e, 0xa878, 0xd084, 0x15d8, 0xa853, 0x0019,
+ 0x00e6, 0x0026, 0x2071, 0x1949, 0x7000, 0x9015, 0x0904, 0x6f16,
+ 0x9286, 0x0003, 0x0904, 0x6dab, 0x9286, 0x0005, 0x0904, 0x6dab,
+ 0x2071, 0x1877, 0xa87c, 0x9005, 0x0904, 0x6d06, 0x7140, 0xa868,
+ 0x9102, 0x0a04, 0x6f16, 0xa878, 0xd084, 0x15d8, 0xa853, 0x0019,
0x2001, 0x8023, 0xa84e, 0x2071, 0x1910, 0x701c, 0x9005, 0x1904,
- 0x70cd, 0x0e04, 0x713b, 0x2071, 0x0000, 0xa850, 0x7032, 0xa84c,
+ 0x70c5, 0x0e04, 0x7133, 0x2071, 0x0000, 0xa850, 0x7032, 0xa84c,
0x7082, 0xa870, 0x7086, 0xa86c, 0x708a, 0xa880, 0x708e, 0x7036,
0x0146, 0x01d6, 0x0136, 0x01c6, 0x0156, 0x20e9, 0x0000, 0x20a1,
0x002a, 0xa868, 0x20a8, 0xa860, 0x20e0, 0xa85c, 0x9080, 0x0021,
0x2098, 0x4003, 0x015e, 0x01ce, 0x013e, 0x01de, 0x014e, 0x2091,
- 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x1200, 0x0804,
- 0x6d96, 0xa853, 0x001b, 0x2001, 0x8027, 0x0820, 0x7004, 0xd08c,
- 0x1904, 0x6f1e, 0xa853, 0x001a, 0x2001, 0x8024, 0x0804, 0x6cd2,
- 0x00e6, 0x0026, 0x2071, 0x1949, 0x7000, 0x9015, 0x0904, 0x6f1e,
- 0x9286, 0x0003, 0x0904, 0x6db3, 0x9286, 0x0005, 0x0904, 0x6db3,
- 0xa84f, 0x8022, 0xa853, 0x0018, 0x0804, 0x6d7b, 0xa868, 0xd0fc,
+ 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x11f4, 0x0804,
+ 0x6d8e, 0xa853, 0x001b, 0x2001, 0x8027, 0x0820, 0x7004, 0xd08c,
+ 0x1904, 0x6f16, 0xa853, 0x001a, 0x2001, 0x8024, 0x0804, 0x6cca,
+ 0x00e6, 0x0026, 0x2071, 0x1949, 0x7000, 0x9015, 0x0904, 0x6f16,
+ 0x9286, 0x0003, 0x0904, 0x6dab, 0x9286, 0x0005, 0x0904, 0x6dab,
+ 0xa84f, 0x8022, 0xa853, 0x0018, 0x0804, 0x6d73, 0xa868, 0xd0fc,
0x1508, 0x00e6, 0x0026, 0x2001, 0x1949, 0x2004, 0x9015, 0x0904,
- 0x6f1e, 0xa978, 0xa874, 0x9105, 0x1904, 0x6f1e, 0x9286, 0x0003,
- 0x0904, 0x6db3, 0x9286, 0x0005, 0x0904, 0x6db3, 0xa87c, 0xd0bc,
- 0x1904, 0x6f1e, 0x2200, 0x0002, 0x6f1e, 0x6d77, 0x6db3, 0x6db3,
- 0x6f1e, 0x6db3, 0x0005, 0xa868, 0xd0fc, 0x1500, 0x00e6, 0x0026,
- 0x2009, 0x1949, 0x210c, 0x81ff, 0x0904, 0x6f1e, 0xa880, 0x9084,
- 0x00ff, 0x9086, 0x0001, 0x1904, 0x6f1e, 0x9186, 0x0003, 0x0904,
- 0x6db3, 0x9186, 0x0005, 0x0904, 0x6db3, 0xa87c, 0xd0cc, 0x0904,
- 0x6f1e, 0xa84f, 0x8021, 0xa853, 0x0017, 0x0028, 0x0005, 0xa84f,
+ 0x6f16, 0xa978, 0xa874, 0x9105, 0x1904, 0x6f16, 0x9286, 0x0003,
+ 0x0904, 0x6dab, 0x9286, 0x0005, 0x0904, 0x6dab, 0xa87c, 0xd0bc,
+ 0x1904, 0x6f16, 0x2200, 0x0002, 0x6f16, 0x6d6f, 0x6dab, 0x6dab,
+ 0x6f16, 0x6dab, 0x0005, 0xa868, 0xd0fc, 0x1500, 0x00e6, 0x0026,
+ 0x2009, 0x1949, 0x210c, 0x81ff, 0x0904, 0x6f16, 0xa880, 0x9084,
+ 0x00ff, 0x9086, 0x0001, 0x1904, 0x6f16, 0x9186, 0x0003, 0x0904,
+ 0x6dab, 0x9186, 0x0005, 0x0904, 0x6dab, 0xa87c, 0xd0cc, 0x0904,
+ 0x6f16, 0xa84f, 0x8021, 0xa853, 0x0017, 0x0028, 0x0005, 0xa84f,
0x8020, 0xa853, 0x0016, 0x2071, 0x1910, 0x701c, 0x9005, 0x1904,
- 0x70cd, 0x0e04, 0x713b, 0x2071, 0x0000, 0xa84c, 0x7082, 0xa850,
+ 0x70c5, 0x0e04, 0x7133, 0x2071, 0x0000, 0xa84c, 0x7082, 0xa850,
0x7032, 0xa86c, 0x7086, 0x7036, 0xa870, 0x708a, 0x2091, 0x4080,
- 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x1200, 0x2071, 0x1800,
+ 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x11f4, 0x2071, 0x1800,
0x2011, 0x0001, 0xa804, 0x900d, 0x702c, 0x1158, 0xa802, 0x2900,
- 0x702e, 0x70c0, 0x9200, 0x70c2, 0x080c, 0x873a, 0x002e, 0x00ee,
+ 0x702e, 0x70c0, 0x9200, 0x70c2, 0x080c, 0x8732, 0x002e, 0x00ee,
0x0005, 0x0096, 0x2148, 0xa904, 0xa802, 0x8210, 0x2900, 0x81ff,
0x1dc8, 0x009e, 0x0c58, 0xa84f, 0x0000, 0x00f6, 0x2079, 0x0050,
- 0x2071, 0x1910, 0xa803, 0x0000, 0x7010, 0x9005, 0x1904, 0x6ea4,
- 0x782c, 0x908c, 0x0780, 0x190c, 0x7289, 0x8004, 0x8004, 0x8004,
- 0x9084, 0x0003, 0x0002, 0x6dd1, 0x6ea4, 0x6df5, 0x6e41, 0x080c,
- 0x0d85, 0x2071, 0x1800, 0x2900, 0x7822, 0xa804, 0x900d, 0x1168,
+ 0x2071, 0x1910, 0xa803, 0x0000, 0x7010, 0x9005, 0x1904, 0x6e9c,
+ 0x782c, 0x908c, 0x0780, 0x190c, 0x7281, 0x8004, 0x8004, 0x8004,
+ 0x9084, 0x0003, 0x0002, 0x6dc9, 0x6e9c, 0x6ded, 0x6e39, 0x080c,
+ 0x0d79, 0x2071, 0x1800, 0x2900, 0x7822, 0xa804, 0x900d, 0x1168,
0x2071, 0x1a05, 0x7044, 0x9005, 0x1320, 0x2001, 0x194a, 0x2004,
0x7046, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x9016, 0x702c, 0x2148,
0xa904, 0xa802, 0x8210, 0x2900, 0x81ff, 0x1dc8, 0x702e, 0x70c0,
- 0x9200, 0x70c2, 0x080c, 0x873a, 0x0c18, 0x2071, 0x1800, 0x2900,
+ 0x9200, 0x70c2, 0x080c, 0x8732, 0x0c18, 0x2071, 0x1800, 0x2900,
0x7822, 0xa804, 0x900d, 0x15a0, 0x7824, 0x00e6, 0x2071, 0x0040,
0x712c, 0xd19c, 0x1170, 0x2009, 0x1830, 0x210c, 0x918a, 0x0020,
0x0240, 0x7022, 0x2001, 0x1dc0, 0x200c, 0x8108, 0x2102, 0x00ee,
0x0058, 0x00ee, 0x2048, 0x702c, 0xa802, 0x2900, 0x702e, 0x70c0,
- 0x8000, 0x70c2, 0x080c, 0x873a, 0x782c, 0x9094, 0x0780, 0x190c,
- 0x7289, 0xd0a4, 0x19c8, 0x2071, 0x1a05, 0x7044, 0x9005, 0x1320,
+ 0x8000, 0x70c2, 0x080c, 0x8732, 0x782c, 0x9094, 0x0780, 0x190c,
+ 0x7281, 0xd0a4, 0x19c8, 0x2071, 0x1a05, 0x7044, 0x9005, 0x1320,
0x2001, 0x194a, 0x2004, 0x7046, 0x00fe, 0x002e, 0x00ee, 0x0005,
0x9016, 0x702c, 0x2148, 0xa904, 0xa802, 0x8210, 0x2900, 0x81ff,
- 0x1dc8, 0x702e, 0x70c0, 0x9200, 0x70c2, 0x080c, 0x873a, 0x0804,
- 0x6dfc, 0x0096, 0x00e6, 0x7824, 0x2048, 0x2071, 0x1800, 0x702c,
- 0xa802, 0x2900, 0x702e, 0x70c0, 0x8000, 0x70c2, 0x080c, 0x873a,
- 0x782c, 0x9094, 0x0780, 0x190c, 0x7289, 0xd0a4, 0x1d60, 0x00ee,
- 0x782c, 0x9094, 0x0780, 0x190c, 0x7289, 0xd09c, 0x1198, 0x009e,
+ 0x1dc8, 0x702e, 0x70c0, 0x9200, 0x70c2, 0x080c, 0x8732, 0x0804,
+ 0x6df4, 0x0096, 0x00e6, 0x7824, 0x2048, 0x2071, 0x1800, 0x702c,
+ 0xa802, 0x2900, 0x702e, 0x70c0, 0x8000, 0x70c2, 0x080c, 0x8732,
+ 0x782c, 0x9094, 0x0780, 0x190c, 0x7281, 0xd0a4, 0x1d60, 0x00ee,
+ 0x782c, 0x9094, 0x0780, 0x190c, 0x7281, 0xd09c, 0x1198, 0x009e,
0x2900, 0x7822, 0xa804, 0x900d, 0x1550, 0x2071, 0x1a05, 0x7044,
0x9005, 0x1320, 0x2001, 0x194a, 0x2004, 0x7046, 0x00fe, 0x002e,
0x00ee, 0x0005, 0x009e, 0x2908, 0x7010, 0x8000, 0x7012, 0x7018,
@@ -3333,87 +3320,87 @@ unsigned short risc_code01[] = {
0x900d, 0x1168, 0x2071, 0x1a05, 0x7044, 0x9005, 0x1320, 0x2001,
0x194a, 0x2004, 0x7046, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x2071,
0x1800, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802, 0x8210, 0x2900,
- 0x81ff, 0x1dc8, 0x702e, 0x70c0, 0x9200, 0x70c2, 0x080c, 0x873a,
+ 0x81ff, 0x1dc8, 0x702e, 0x70c0, 0x9200, 0x70c2, 0x080c, 0x8732,
0x00fe, 0x002e, 0x00ee, 0x0005, 0x2908, 0x7010, 0x8000, 0x7012,
0x7018, 0x904d, 0x711a, 0x0110, 0xa902, 0x0008, 0x711e, 0x2148,
- 0xa804, 0x900d, 0x1904, 0x6ef8, 0x782c, 0x9094, 0x0780, 0x190c,
- 0x7289, 0xd09c, 0x1198, 0x701c, 0x904d, 0x0180, 0x7010, 0x8001,
+ 0xa804, 0x900d, 0x1904, 0x6ef0, 0x782c, 0x9094, 0x0780, 0x190c,
+ 0x7281, 0xd09c, 0x1198, 0x701c, 0x904d, 0x0180, 0x7010, 0x8001,
0x7012, 0x1108, 0x701a, 0xa800, 0x701e, 0x2900, 0x7822, 0x782c,
- 0x9094, 0x0780, 0x190c, 0x7289, 0xd09c, 0x0d68, 0x782c, 0x9094,
- 0x0780, 0x190c, 0x7289, 0xd0a4, 0x01b0, 0x00e6, 0x7824, 0x2048,
+ 0x9094, 0x0780, 0x190c, 0x7281, 0xd09c, 0x0d68, 0x782c, 0x9094,
+ 0x0780, 0x190c, 0x7281, 0xd0a4, 0x01b0, 0x00e6, 0x7824, 0x2048,
0x2071, 0x1800, 0x702c, 0xa802, 0x2900, 0x702e, 0x70c0, 0x8000,
- 0x70c2, 0x080c, 0x873a, 0x782c, 0x9094, 0x0780, 0x190c, 0x7289,
+ 0x70c2, 0x080c, 0x8732, 0x782c, 0x9094, 0x0780, 0x190c, 0x7281,
0xd0a4, 0x1d60, 0x00ee, 0x2071, 0x1a05, 0x7044, 0x9005, 0x1320,
0x2001, 0x194a, 0x2004, 0x7046, 0x00fe, 0x002e, 0x00ee, 0x0005,
0x00e6, 0x2071, 0x1800, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802,
0x8210, 0x2900, 0x81ff, 0x1dc8, 0x702e, 0x70c0, 0x9200, 0x70c2,
- 0x080c, 0x873a, 0x00ee, 0x0804, 0x6eb4, 0xa868, 0xd0fc, 0x15e0,
- 0x0096, 0xa804, 0xa807, 0x0000, 0x904d, 0x190c, 0x100b, 0x009e,
+ 0x080c, 0x8732, 0x00ee, 0x0804, 0x6eac, 0xa868, 0xd0fc, 0x15e0,
+ 0x0096, 0xa804, 0xa807, 0x0000, 0x904d, 0x190c, 0x0fff, 0x009e,
0x0018, 0xa868, 0xd0fc, 0x1580, 0x00e6, 0x0026, 0xa84f, 0x0000,
0x00f6, 0x2079, 0x0050, 0x2071, 0x1910, 0xa803, 0x0000, 0xa864,
0x9084, 0x00ff, 0x908e, 0x0016, 0x01a8, 0x7010, 0x9005, 0x1904,
- 0x7049, 0x782c, 0x908c, 0x0780, 0x190c, 0x7289, 0x8004, 0x8004,
- 0x8004, 0x9084, 0x0003, 0x0002, 0x6f4d, 0x7049, 0x6f68, 0x6fda,
- 0x080c, 0x0d85, 0x2009, 0x1949, 0x2104, 0x0002, 0x6f2d, 0x6f2d,
- 0x6f2d, 0x6dbc, 0x6f2d, 0x6dbc, 0x0005, 0x2071, 0x1800, 0x2900,
+ 0x7041, 0x782c, 0x908c, 0x0780, 0x190c, 0x7281, 0x8004, 0x8004,
+ 0x8004, 0x9084, 0x0003, 0x0002, 0x6f45, 0x7041, 0x6f60, 0x6fd2,
+ 0x080c, 0x0d79, 0x2009, 0x1949, 0x2104, 0x0002, 0x6f25, 0x6f25,
+ 0x6f25, 0x6db4, 0x6f25, 0x6db4, 0x0005, 0x2071, 0x1800, 0x2900,
0x7822, 0xa804, 0x900d, 0x1120, 0x00fe, 0x002e, 0x00ee, 0x0005,
0x9016, 0x702c, 0x2148, 0xa904, 0xa802, 0x8210, 0x2900, 0x81ff,
- 0x1dc8, 0x702e, 0x70c0, 0x9200, 0x70c2, 0x080c, 0x873a, 0x0c60,
- 0x2071, 0x1800, 0x2900, 0x7822, 0xa804, 0x900d, 0x1904, 0x6fc9,
+ 0x1dc8, 0x702e, 0x70c0, 0x9200, 0x70c2, 0x080c, 0x8732, 0x0c60,
+ 0x2071, 0x1800, 0x2900, 0x7822, 0xa804, 0x900d, 0x1904, 0x6fc1,
0x7830, 0xd0dc, 0x1120, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x7824,
0x00e6, 0x2071, 0x0040, 0x712c, 0xd19c, 0x1170, 0x2009, 0x1830,
0x210c, 0x918a, 0x0020, 0x0240, 0x7022, 0x2001, 0x1dc0, 0x200c,
0x8108, 0x2102, 0x00ee, 0x0058, 0x00ee, 0x2048, 0x702c, 0xa802,
- 0x2900, 0x702e, 0x70c0, 0x8000, 0x70c2, 0x080c, 0x873a, 0x782c,
- 0x9094, 0x0780, 0x190c, 0x7289, 0xd0a4, 0x19c8, 0x0e04, 0x6fc0,
+ 0x2900, 0x702e, 0x70c0, 0x8000, 0x70c2, 0x080c, 0x8732, 0x782c,
+ 0x9094, 0x0780, 0x190c, 0x7281, 0xd0a4, 0x19c8, 0x0e04, 0x6fb8,
0x7838, 0x7938, 0x910e, 0x1de0, 0x00d6, 0x2069, 0x0000, 0x6836,
0x6833, 0x0013, 0x00de, 0x2001, 0x1921, 0x200c, 0xc184, 0x2102,
- 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x1200,
+ 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x11f4,
0x2001, 0x1922, 0x2003, 0x0000, 0x00fe, 0x002e, 0x00ee, 0x0005,
0x2001, 0x1921, 0x200c, 0xc185, 0x2102, 0x00fe, 0x002e, 0x00ee,
0x0005, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802, 0x8210, 0x2900,
- 0x81ff, 0x1dc8, 0x702e, 0x70c0, 0x9200, 0x70c2, 0x080c, 0x873a,
- 0x0804, 0x6f77, 0x0096, 0x00e6, 0x7824, 0x2048, 0x2071, 0x1800,
+ 0x81ff, 0x1dc8, 0x702e, 0x70c0, 0x9200, 0x70c2, 0x080c, 0x8732,
+ 0x0804, 0x6f6f, 0x0096, 0x00e6, 0x7824, 0x2048, 0x2071, 0x1800,
0x702c, 0xa802, 0x2900, 0x702e, 0x70c0, 0x8000, 0x70c2, 0x080c,
- 0x873a, 0x782c, 0x9094, 0x0780, 0x190c, 0x7289, 0xd0a4, 0x1d60,
- 0x00ee, 0x0e04, 0x701c, 0x7838, 0x7938, 0x910e, 0x1de0, 0x00d6,
+ 0x8732, 0x782c, 0x9094, 0x0780, 0x190c, 0x7281, 0xd0a4, 0x1d60,
+ 0x00ee, 0x0e04, 0x7014, 0x7838, 0x7938, 0x910e, 0x1de0, 0x00d6,
0x2069, 0x0000, 0x6836, 0x6833, 0x0013, 0x00de, 0x7044, 0xc084,
0x7046, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c,
- 0x1200, 0x704b, 0x0000, 0x782c, 0x9094, 0x0780, 0x190c, 0x7289,
+ 0x11f4, 0x704b, 0x0000, 0x782c, 0x9094, 0x0780, 0x190c, 0x7281,
0xd09c, 0x1170, 0x009e, 0x2900, 0x7822, 0xa804, 0x900d, 0x11e0,
0x00fe, 0x002e, 0x00ee, 0x0005, 0x7044, 0xc085, 0x7046, 0x0c58,
0x009e, 0x2908, 0x7010, 0x8000, 0x7012, 0x7018, 0x904d, 0x711a,
0x0110, 0xa902, 0x0008, 0x711e, 0x2148, 0xa804, 0x900d, 0x1120,
0x00fe, 0x002e, 0x00ee, 0x0005, 0x2071, 0x1800, 0x9016, 0x702c,
0x2148, 0xa904, 0xa802, 0x8210, 0x2900, 0x81ff, 0x1dc8, 0x702e,
- 0x70c0, 0x9200, 0x70c2, 0x080c, 0x873a, 0x00fe, 0x002e, 0x00ee,
+ 0x70c0, 0x9200, 0x70c2, 0x080c, 0x8732, 0x00fe, 0x002e, 0x00ee,
0x0005, 0x2908, 0x7010, 0x8000, 0x7012, 0x7018, 0x904d, 0x711a,
0x0110, 0xa902, 0x0008, 0x711e, 0x2148, 0xa804, 0x900d, 0x1904,
- 0x70b8, 0x782c, 0x9094, 0x0780, 0x190c, 0x7289, 0xd09c, 0x11b0,
+ 0x70b0, 0x782c, 0x9094, 0x0780, 0x190c, 0x7281, 0xd09c, 0x11b0,
0x701c, 0x904d, 0x0198, 0xa84c, 0x9005, 0x1180, 0x7010, 0x8001,
0x7012, 0x1108, 0x701a, 0xa800, 0x701e, 0x2900, 0x7822, 0x782c,
- 0x9094, 0x0780, 0x190c, 0x7289, 0xd09c, 0x0d50, 0x782c, 0x9094,
- 0x0780, 0x190c, 0x7289, 0xd0a4, 0x05b8, 0x00e6, 0x7824, 0x2048,
+ 0x9094, 0x0780, 0x190c, 0x7281, 0xd09c, 0x0d50, 0x782c, 0x9094,
+ 0x0780, 0x190c, 0x7281, 0xd0a4, 0x05b8, 0x00e6, 0x7824, 0x2048,
0x2071, 0x1800, 0x702c, 0xa802, 0x2900, 0x702e, 0x70c0, 0x8000,
- 0x70c2, 0x080c, 0x873a, 0x782c, 0x9094, 0x0780, 0x190c, 0x7289,
- 0xd0a4, 0x1d60, 0x00ee, 0x0e04, 0x70b1, 0x7838, 0x7938, 0x910e,
+ 0x70c2, 0x080c, 0x8732, 0x782c, 0x9094, 0x0780, 0x190c, 0x7281,
+ 0xd0a4, 0x1d60, 0x00ee, 0x0e04, 0x70a9, 0x7838, 0x7938, 0x910e,
0x1de0, 0x00d6, 0x2069, 0x0000, 0x6836, 0x6833, 0x0013, 0x00de,
0x7044, 0xc084, 0x7046, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004,
- 0xd084, 0x190c, 0x1200, 0x704b, 0x0000, 0x00fe, 0x002e, 0x00ee,
+ 0xd084, 0x190c, 0x11f4, 0x704b, 0x0000, 0x00fe, 0x002e, 0x00ee,
0x0005, 0x7044, 0xc085, 0x7046, 0x00fe, 0x002e, 0x00ee, 0x0005,
0x00e6, 0x2071, 0x1800, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802,
0x8210, 0x2900, 0x81ff, 0x1dc8, 0x702e, 0x70c0, 0x9200, 0x70c2,
- 0x080c, 0x873a, 0x00ee, 0x0804, 0x7059, 0x2071, 0x1910, 0xa803,
+ 0x080c, 0x8732, 0x00ee, 0x0804, 0x7051, 0x2071, 0x1910, 0xa803,
0x0000, 0x2908, 0x7010, 0x8000, 0x7012, 0x7018, 0x904d, 0x711a,
0x0110, 0xa902, 0x0008, 0x711e, 0x2148, 0xa804, 0x900d, 0x1128,
- 0x1e04, 0x70f8, 0x002e, 0x00ee, 0x0005, 0x2071, 0x1800, 0x9016,
+ 0x1e04, 0x70f0, 0x002e, 0x00ee, 0x0005, 0x2071, 0x1800, 0x9016,
0x702c, 0x2148, 0xa904, 0xa802, 0x8210, 0x2900, 0x81ff, 0x1dc8,
- 0x702e, 0x70c0, 0x9200, 0x70c2, 0x080c, 0x873a, 0x0e04, 0x70e2,
+ 0x702e, 0x70c0, 0x9200, 0x70c2, 0x080c, 0x8732, 0x0e04, 0x70da,
0x2071, 0x1910, 0x701c, 0x2048, 0xa84c, 0x900d, 0x0d18, 0x2071,
0x0000, 0x7182, 0xa850, 0x7032, 0xa86c, 0x7086, 0x7036, 0xa870,
0x708a, 0xa850, 0x9082, 0x0019, 0x1278, 0x2091, 0x4080, 0x2001,
- 0x0089, 0x2004, 0xd084, 0x190c, 0x1200, 0x2071, 0x1910, 0x080c,
- 0x7275, 0x002e, 0x00ee, 0x0005, 0xa850, 0x9082, 0x001c, 0x1e68,
+ 0x0089, 0x2004, 0xd084, 0x190c, 0x11f4, 0x2071, 0x1910, 0x080c,
+ 0x726d, 0x002e, 0x00ee, 0x0005, 0xa850, 0x9082, 0x001c, 0x1e68,
0xa880, 0x708e, 0x7036, 0x0146, 0x01d6, 0x0136, 0x01c6, 0x0156,
0x20e9, 0x0000, 0x20a1, 0x002a, 0xa868, 0x20a8, 0xa860, 0x20e0,
0xa85c, 0x9080, 0x0021, 0x2098, 0x4003, 0x015e, 0x01ce, 0x013e,
@@ -3422,23 +3409,23 @@ unsigned short risc_code01[] = {
0x0008, 0x711e, 0x2148, 0xa804, 0x900d, 0x1118, 0x002e, 0x00ee,
0x0005, 0x2071, 0x1800, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802,
0x8210, 0x2900, 0x81ff, 0x1dc8, 0x702e, 0x70c0, 0x9200, 0x70c2,
- 0x080c, 0x873a, 0x002e, 0x00ee, 0x0005, 0x0006, 0xa87c, 0x0006,
+ 0x080c, 0x8732, 0x002e, 0x00ee, 0x0005, 0x0006, 0xa87c, 0x0006,
0xa867, 0x0103, 0x20a9, 0x001c, 0xa860, 0x20e8, 0xa85c, 0x9080,
0x001d, 0x20a0, 0x9006, 0x4004, 0x000e, 0x9084, 0x00ff, 0xa87e,
0x000e, 0xa87a, 0xa982, 0x0005, 0x2071, 0x1910, 0x7004, 0x0002,
- 0x7188, 0x7189, 0x7274, 0x7189, 0x7186, 0x7274, 0x080c, 0x0d85,
- 0x0005, 0x2001, 0x1949, 0x2004, 0x0002, 0x7193, 0x7193, 0x720d,
- 0x720e, 0x7193, 0x720e, 0x0126, 0x2091, 0x8000, 0x1e0c, 0x7294,
- 0x701c, 0x904d, 0x0508, 0xa84c, 0x9005, 0x0904, 0x71de, 0x0e04,
- 0x71bc, 0xa94c, 0x2071, 0x0000, 0x7182, 0xa850, 0x7032, 0xa86c,
+ 0x7180, 0x7181, 0x726c, 0x7181, 0x717e, 0x726c, 0x080c, 0x0d79,
+ 0x0005, 0x2001, 0x1949, 0x2004, 0x0002, 0x718b, 0x718b, 0x7205,
+ 0x7206, 0x718b, 0x7206, 0x0126, 0x2091, 0x8000, 0x1e0c, 0x728c,
+ 0x701c, 0x904d, 0x0508, 0xa84c, 0x9005, 0x0904, 0x71d6, 0x0e04,
+ 0x71b4, 0xa94c, 0x2071, 0x0000, 0x7182, 0xa850, 0x7032, 0xa86c,
0x7086, 0x7036, 0xa870, 0x708a, 0xa850, 0x9082, 0x0019, 0x1278,
- 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x1200,
- 0x2071, 0x1910, 0x080c, 0x7275, 0x012e, 0x0804, 0x720c, 0xa850,
+ 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x11f4,
+ 0x2071, 0x1910, 0x080c, 0x726d, 0x012e, 0x0804, 0x7204, 0xa850,
0x9082, 0x001c, 0x1e68, 0xa880, 0x708e, 0x7036, 0x0146, 0x01d6,
0x0136, 0x01c6, 0x0156, 0x20e9, 0x0000, 0x20a1, 0x002a, 0xa868,
0x20a8, 0xa860, 0x20e0, 0xa85c, 0x9080, 0x0021, 0x2098, 0x4003,
0x015e, 0x01ce, 0x013e, 0x01de, 0x014e, 0x0890, 0x2001, 0x005b,
- 0x2004, 0x9094, 0x0780, 0x190c, 0x7289, 0xd09c, 0x2071, 0x1910,
+ 0x2004, 0x9094, 0x0780, 0x190c, 0x7281, 0xd09c, 0x2071, 0x1910,
0x1510, 0x2071, 0x1910, 0x700f, 0x0001, 0xa964, 0x9184, 0x00ff,
0x9086, 0x0003, 0x1130, 0x810f, 0x918c, 0x00ff, 0x8101, 0x0108,
0x710e, 0x2900, 0x00d6, 0x2069, 0x0050, 0x6822, 0x00de, 0x2071,
@@ -3447,10 +3434,10 @@ unsigned short risc_code01[] = {
0x2069, 0x1a05, 0x6844, 0x9005, 0x0760, 0x0158, 0x9186, 0x0003,
0x0540, 0x2001, 0x1815, 0x2004, 0x2009, 0x1b74, 0x210c, 0x9102,
0x1500, 0x0126, 0x2091, 0x8000, 0x2069, 0x0050, 0x693c, 0x6838,
- 0x9106, 0x0190, 0x0e04, 0x7240, 0x2069, 0x0000, 0x6837, 0x8040,
+ 0x9106, 0x0190, 0x0e04, 0x7238, 0x2069, 0x0000, 0x6837, 0x8040,
0x6833, 0x0012, 0x6883, 0x8040, 0x2091, 0x4080, 0x2001, 0x0089,
- 0x2004, 0xd084, 0x190c, 0x1200, 0x2069, 0x1a05, 0x6847, 0xffff,
- 0x012e, 0x00de, 0x0126, 0x2091, 0x8000, 0x1e0c, 0x7304, 0x701c,
+ 0x2004, 0xd084, 0x190c, 0x11f4, 0x2069, 0x1a05, 0x6847, 0xffff,
+ 0x012e, 0x00de, 0x0126, 0x2091, 0x8000, 0x1e0c, 0x72fc, 0x701c,
0x904d, 0x0540, 0x2001, 0x005b, 0x2004, 0x9094, 0x0780, 0x15c9,
0xd09c, 0x1500, 0x2071, 0x1910, 0x700f, 0x0001, 0xa964, 0x9184,
0x00ff, 0x9086, 0x0003, 0x1130, 0x810f, 0x918c, 0x00ff, 0x8101,
@@ -3458,240 +3445,240 @@ unsigned short risc_code01[] = {
0x701c, 0x2048, 0x7010, 0x8001, 0x7012, 0xa800, 0x701e, 0x9005,
0x1108, 0x701a, 0x012e, 0x0005, 0x0005, 0x0126, 0x2091, 0x8000,
0x701c, 0x904d, 0x0160, 0x7010, 0x8001, 0x7012, 0xa800, 0x701e,
- 0x9005, 0x1108, 0x701a, 0x012e, 0x080c, 0x108b, 0x0005, 0x012e,
- 0x0005, 0x2091, 0x8000, 0x0e04, 0x728b, 0x0006, 0x0016, 0x2001,
- 0x8004, 0x0006, 0x0804, 0x0d8e, 0x0096, 0x00f6, 0x2079, 0x0050,
+ 0x9005, 0x1108, 0x701a, 0x012e, 0x080c, 0x107f, 0x0005, 0x012e,
+ 0x0005, 0x2091, 0x8000, 0x0e04, 0x7283, 0x0006, 0x0016, 0x2001,
+ 0x8004, 0x0006, 0x0804, 0x0d82, 0x0096, 0x00f6, 0x2079, 0x0050,
0x7044, 0xd084, 0x01d0, 0xc084, 0x7046, 0x7838, 0x7938, 0x910e,
0x1de0, 0x00d6, 0x2069, 0x0000, 0x6836, 0x6833, 0x0013, 0x00de,
- 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x1200,
+ 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x11f4,
0x704b, 0x0000, 0x00fe, 0x009e, 0x0005, 0x782c, 0x9094, 0x0780,
0x1981, 0xd0a4, 0x0db8, 0x7148, 0x704c, 0x8108, 0x714a, 0x9102,
0x0e88, 0x00e6, 0x2071, 0x1800, 0x7824, 0x00e6, 0x2071, 0x0040,
0x712c, 0xd19c, 0x1170, 0x2009, 0x1830, 0x210c, 0x918a, 0x0020,
0x0240, 0x7022, 0x2001, 0x1dc0, 0x200c, 0x8108, 0x2102, 0x00ee,
0x0058, 0x00ee, 0x2048, 0x702c, 0xa802, 0x2900, 0x702e, 0x70c0,
- 0x8000, 0x70c2, 0x080c, 0x873a, 0x782c, 0x9094, 0x0780, 0x190c,
- 0x7289, 0xd0a4, 0x19c8, 0x7838, 0x7938, 0x910e, 0x1de0, 0x00d6,
+ 0x8000, 0x70c2, 0x080c, 0x8732, 0x782c, 0x9094, 0x0780, 0x190c,
+ 0x7281, 0xd0a4, 0x19c8, 0x7838, 0x7938, 0x910e, 0x1de0, 0x00d6,
0x2069, 0x0000, 0x6836, 0x6833, 0x0013, 0x00de, 0x2091, 0x4080,
- 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x1200, 0x00ee, 0x704b,
+ 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x11f4, 0x00ee, 0x704b,
0x0000, 0x00fe, 0x009e, 0x0005, 0x00f6, 0x2079, 0x0050, 0x7044,
0xd084, 0x01b8, 0xc084, 0x7046, 0x7838, 0x7938, 0x910e, 0x1de0,
0x00d6, 0x2069, 0x0000, 0x6836, 0x6833, 0x0013, 0x00de, 0x2091,
- 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x1200, 0x00fe,
- 0x0005, 0x782c, 0x9094, 0x0780, 0x190c, 0x7289, 0xd0a4, 0x0db8,
+ 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x11f4, 0x00fe,
+ 0x0005, 0x782c, 0x9094, 0x0780, 0x190c, 0x7281, 0xd0a4, 0x0db8,
0x00e6, 0x2071, 0x1800, 0x7824, 0x2048, 0x702c, 0xa802, 0x2900,
- 0x702e, 0x70c0, 0x8000, 0x70c2, 0x080c, 0x873a, 0x782c, 0x9094,
- 0x0780, 0x190c, 0x7289, 0xd0a4, 0x1d70, 0x00d6, 0x2069, 0x0050,
+ 0x702e, 0x70c0, 0x8000, 0x70c2, 0x080c, 0x8732, 0x782c, 0x9094,
+ 0x0780, 0x190c, 0x7281, 0xd0a4, 0x1d70, 0x00d6, 0x2069, 0x0050,
0x693c, 0x2069, 0x1949, 0x6808, 0x690a, 0x2069, 0x1a05, 0x9102,
0x1118, 0x6844, 0x9005, 0x1320, 0x2001, 0x194a, 0x200c, 0x6946,
0x00de, 0x00ee, 0x00fe, 0x0005, 0x7098, 0x908a, 0x002a, 0x1a0c,
- 0x0d85, 0x9082, 0x001d, 0x003b, 0x0026, 0x2011, 0x1e00, 0x080c,
- 0x2af5, 0x002e, 0x0005, 0x7449, 0x73b6, 0x73d2, 0x73fc, 0x7438,
- 0x7478, 0x748a, 0x73d2, 0x7460, 0x7371, 0x739f, 0x7422, 0x7370,
+ 0x0d79, 0x9082, 0x001d, 0x003b, 0x0026, 0x2011, 0x1e00, 0x080c,
+ 0x2adc, 0x002e, 0x0005, 0x7441, 0x73ae, 0x73ca, 0x73f4, 0x7430,
+ 0x7470, 0x7482, 0x73ca, 0x7458, 0x7369, 0x7397, 0x741a, 0x7368,
0x0005, 0x00d6, 0x2069, 0x0200, 0x6804, 0x9005, 0x1180, 0x6808,
0x9005, 0x1518, 0x709b, 0x0029, 0x2069, 0x1990, 0x2d04, 0x7002,
- 0x080c, 0x77e3, 0x6028, 0x9085, 0x0600, 0x602a, 0x00b0, 0x709b,
+ 0x080c, 0x77db, 0x6028, 0x9085, 0x0600, 0x602a, 0x00b0, 0x709b,
0x0029, 0x2069, 0x1990, 0x2d04, 0x7002, 0x6028, 0x9085, 0x0600,
0x602a, 0x00e6, 0x0036, 0x0046, 0x0056, 0x2071, 0x1a6f, 0x080c,
- 0x1b47, 0x005e, 0x004e, 0x003e, 0x00ee, 0x00de, 0x0005, 0x00d6,
+ 0x1b3b, 0x005e, 0x004e, 0x003e, 0x00ee, 0x00de, 0x0005, 0x00d6,
0x2069, 0x0200, 0x6804, 0x9005, 0x1178, 0x6808, 0x9005, 0x1160,
- 0x709b, 0x0029, 0x2069, 0x1990, 0x2d04, 0x7002, 0x080c, 0x7888,
+ 0x709b, 0x0029, 0x2069, 0x1990, 0x2d04, 0x7002, 0x080c, 0x7880,
0x6028, 0x9085, 0x0600, 0x602a, 0x00de, 0x0005, 0x0006, 0x2001,
- 0x0090, 0x080c, 0x2abb, 0x000e, 0x6124, 0xd1e4, 0x1190, 0x080c,
- 0x74fb, 0xd1d4, 0x1160, 0xd1dc, 0x1138, 0xd1cc, 0x0150, 0x709b,
- 0x0020, 0x080c, 0x74fb, 0x0028, 0x709b, 0x001d, 0x0010, 0x709b,
- 0x001f, 0x0005, 0x2001, 0x0088, 0x080c, 0x2abb, 0x6124, 0xd1cc,
+ 0x0090, 0x080c, 0x2aa2, 0x000e, 0x6124, 0xd1e4, 0x1190, 0x080c,
+ 0x74f3, 0xd1d4, 0x1160, 0xd1dc, 0x1138, 0xd1cc, 0x0150, 0x709b,
+ 0x0020, 0x080c, 0x74f3, 0x0028, 0x709b, 0x001d, 0x0010, 0x709b,
+ 0x001f, 0x0005, 0x2001, 0x0088, 0x080c, 0x2aa2, 0x6124, 0xd1cc,
0x11e8, 0xd1dc, 0x11c0, 0xd1e4, 0x1198, 0x9184, 0x1e00, 0x11d8,
- 0x080c, 0x1b6c, 0x60e3, 0x0001, 0x600c, 0xc0b4, 0x600e, 0x080c,
- 0x76d1, 0x2001, 0x0080, 0x080c, 0x2abb, 0x709b, 0x0029, 0x0058,
+ 0x080c, 0x1b68, 0x60e3, 0x0001, 0x600c, 0xc0b4, 0x600e, 0x080c,
+ 0x76c9, 0x2001, 0x0080, 0x080c, 0x2aa2, 0x709b, 0x0029, 0x0058,
0x709b, 0x001e, 0x0040, 0x709b, 0x001d, 0x0028, 0x709b, 0x0020,
- 0x0010, 0x709b, 0x001f, 0x0005, 0x080c, 0x1b6c, 0x60e3, 0x0001,
- 0x600c, 0xc0b4, 0x600e, 0x080c, 0x76d1, 0x2001, 0x0080, 0x080c,
- 0x2abb, 0x6124, 0xd1d4, 0x1198, 0xd1dc, 0x1170, 0xd1e4, 0x1148,
+ 0x0010, 0x709b, 0x001f, 0x0005, 0x080c, 0x1b68, 0x60e3, 0x0001,
+ 0x600c, 0xc0b4, 0x600e, 0x080c, 0x76c9, 0x2001, 0x0080, 0x080c,
+ 0x2aa2, 0x6124, 0xd1d4, 0x1198, 0xd1dc, 0x1170, 0xd1e4, 0x1148,
0x9184, 0x1e00, 0x1118, 0x709b, 0x0029, 0x0058, 0x709b, 0x0028,
0x0040, 0x709b, 0x001e, 0x0028, 0x709b, 0x001d, 0x0010, 0x709b,
0x001f, 0x0005, 0x6124, 0xd1d4, 0x1180, 0xd1dc, 0x1158, 0xd1e4,
0x1130, 0x9184, 0x1e00, 0x1158, 0x709b, 0x0029, 0x0040, 0x709b,
0x001e, 0x0028, 0x709b, 0x001d, 0x0010, 0x709b, 0x001f, 0x0005,
- 0x2001, 0x00a0, 0x080c, 0x2abb, 0x6124, 0xd1dc, 0x1138, 0xd1e4,
- 0x0138, 0x080c, 0x1b6c, 0x709b, 0x001e, 0x0010, 0x709b, 0x001d,
- 0x0005, 0x080c, 0x7584, 0x6124, 0xd1dc, 0x1188, 0x080c, 0x74fb,
- 0x0016, 0x080c, 0x1b6c, 0x001e, 0xd1d4, 0x1128, 0xd1e4, 0x0138,
- 0x709b, 0x001e, 0x0020, 0x709b, 0x001f, 0x080c, 0x74fb, 0x0005,
- 0x0006, 0x2001, 0x00a0, 0x080c, 0x2abb, 0x000e, 0x6124, 0xd1d4,
+ 0x2001, 0x00a0, 0x080c, 0x2aa2, 0x6124, 0xd1dc, 0x1138, 0xd1e4,
+ 0x0138, 0x080c, 0x1b68, 0x709b, 0x001e, 0x0010, 0x709b, 0x001d,
+ 0x0005, 0x080c, 0x757c, 0x6124, 0xd1dc, 0x1188, 0x080c, 0x74f3,
+ 0x0016, 0x080c, 0x1b68, 0x001e, 0xd1d4, 0x1128, 0xd1e4, 0x0138,
+ 0x709b, 0x001e, 0x0020, 0x709b, 0x001f, 0x080c, 0x74f3, 0x0005,
+ 0x0006, 0x2001, 0x00a0, 0x080c, 0x2aa2, 0x000e, 0x6124, 0xd1d4,
0x1160, 0xd1cc, 0x1150, 0xd1dc, 0x1128, 0xd1e4, 0x0140, 0x709b,
0x001e, 0x0028, 0x709b, 0x001d, 0x0010, 0x709b, 0x0021, 0x0005,
- 0x080c, 0x7584, 0x6124, 0xd1d4, 0x1150, 0xd1dc, 0x1128, 0xd1e4,
+ 0x080c, 0x757c, 0x6124, 0xd1d4, 0x1150, 0xd1dc, 0x1128, 0xd1e4,
0x0140, 0x709b, 0x001e, 0x0028, 0x709b, 0x001d, 0x0010, 0x709b,
- 0x001f, 0x0005, 0x0006, 0x2001, 0x0090, 0x080c, 0x2abb, 0x000e,
+ 0x001f, 0x0005, 0x0006, 0x2001, 0x0090, 0x080c, 0x2aa2, 0x000e,
0x6124, 0xd1d4, 0x1178, 0xd1cc, 0x1150, 0xd1dc, 0x1128, 0xd1e4,
0x0158, 0x709b, 0x001e, 0x0040, 0x709b, 0x001d, 0x0028, 0x709b,
0x0020, 0x0010, 0x709b, 0x001f, 0x0005, 0x0016, 0x00c6, 0x00d6,
0x00e6, 0x0126, 0x2061, 0x0100, 0x2069, 0x0140, 0x2071, 0x1800,
- 0x2091, 0x8000, 0x080c, 0x76a5, 0x11f8, 0x2001, 0x180c, 0x200c,
+ 0x2091, 0x8000, 0x080c, 0x769d, 0x11f8, 0x2001, 0x180c, 0x200c,
0xd1b4, 0x01d0, 0xc1b4, 0x2102, 0x0026, 0x2011, 0x0200, 0x080c,
- 0x2af5, 0x002e, 0x080c, 0x2aa1, 0x6024, 0xd0cc, 0x0148, 0x2001,
- 0x00a0, 0x080c, 0x2abb, 0x080c, 0x79a7, 0x080c, 0x617e, 0x0428,
- 0x6028, 0xc0cd, 0x602a, 0x0408, 0x080c, 0x76bf, 0x0150, 0x080c,
- 0x76b6, 0x1138, 0x2001, 0x0001, 0x080c, 0x2647, 0x080c, 0x7679,
- 0x00a0, 0x080c, 0x7581, 0x0178, 0x2001, 0x0001, 0x080c, 0x2647,
+ 0x2adc, 0x002e, 0x080c, 0x2a88, 0x6024, 0xd0cc, 0x0148, 0x2001,
+ 0x00a0, 0x080c, 0x2aa2, 0x080c, 0x799f, 0x080c, 0x6178, 0x0428,
+ 0x6028, 0xc0cd, 0x602a, 0x0408, 0x080c, 0x76b7, 0x0150, 0x080c,
+ 0x76ae, 0x1138, 0x2001, 0x0001, 0x080c, 0x2646, 0x080c, 0x7671,
+ 0x00a0, 0x080c, 0x7579, 0x0178, 0x2001, 0x0001, 0x080c, 0x2646,
0x7098, 0x9086, 0x001e, 0x0120, 0x7098, 0x9086, 0x0022, 0x1118,
0x709b, 0x0025, 0x0010, 0x709b, 0x0021, 0x012e, 0x00ee, 0x00de,
- 0x00ce, 0x001e, 0x0005, 0x0026, 0x2011, 0x750c, 0x080c, 0x8940,
- 0x002e, 0x0016, 0x0026, 0x2009, 0x0064, 0x2011, 0x750c, 0x080c,
- 0x8937, 0x002e, 0x001e, 0x0005, 0x00e6, 0x00f6, 0x0016, 0x080c,
- 0xa08a, 0x2071, 0x1800, 0x080c, 0x74a5, 0x001e, 0x00fe, 0x00ee,
+ 0x00ce, 0x001e, 0x0005, 0x0026, 0x2011, 0x7504, 0x080c, 0x8938,
+ 0x002e, 0x0016, 0x0026, 0x2009, 0x0064, 0x2011, 0x7504, 0x080c,
+ 0x892f, 0x002e, 0x001e, 0x0005, 0x00e6, 0x00f6, 0x0016, 0x080c,
+ 0xa09b, 0x2071, 0x1800, 0x080c, 0x749d, 0x001e, 0x00fe, 0x00ee,
0x0005, 0x0016, 0x0026, 0x0036, 0x00c6, 0x00d6, 0x00e6, 0x00f6,
- 0x0126, 0x2071, 0x1800, 0x080c, 0xa08a, 0x2061, 0x0100, 0x2069,
- 0x0140, 0x2091, 0x8000, 0x6028, 0xc09c, 0x602a, 0x080c, 0xaae0,
- 0x2011, 0x0003, 0x080c, 0xa40f, 0x2011, 0x0002, 0x080c, 0xa419,
- 0x080c, 0xa300, 0x080c, 0x88ec, 0x0036, 0x901e, 0x080c, 0xa380,
- 0x003e, 0x080c, 0xaafc, 0x60e3, 0x0000, 0x080c, 0xeb7d, 0x080c,
- 0xeb98, 0x2009, 0x0004, 0x080c, 0x2aa7, 0x080c, 0x29bd, 0x2001,
- 0x1800, 0x2003, 0x0004, 0x2011, 0x0008, 0x080c, 0x2af5, 0x2011,
- 0x750c, 0x080c, 0x8940, 0x080c, 0x76bf, 0x0118, 0x9006, 0x080c,
- 0x2abb, 0x080c, 0x0bc3, 0x2001, 0x0001, 0x080c, 0x2647, 0x012e,
+ 0x0126, 0x2071, 0x1800, 0x080c, 0xa09b, 0x2061, 0x0100, 0x2069,
+ 0x0140, 0x2091, 0x8000, 0x6028, 0xc09c, 0x602a, 0x080c, 0xaaf7,
+ 0x2011, 0x0003, 0x080c, 0xa426, 0x2011, 0x0002, 0x080c, 0xa430,
+ 0x080c, 0xa311, 0x080c, 0x88e4, 0x0036, 0x901e, 0x080c, 0xa391,
+ 0x003e, 0x080c, 0xab13, 0x60e3, 0x0000, 0x080c, 0xebe8, 0x080c,
+ 0xec03, 0x2009, 0x0004, 0x080c, 0x2a8e, 0x080c, 0x29a8, 0x2001,
+ 0x1800, 0x2003, 0x0004, 0x2011, 0x0008, 0x080c, 0x2adc, 0x2011,
+ 0x7504, 0x080c, 0x8938, 0x080c, 0x76b7, 0x0118, 0x9006, 0x080c,
+ 0x2aa2, 0x080c, 0x0bc3, 0x2001, 0x0001, 0x080c, 0x2646, 0x012e,
0x00fe, 0x00ee, 0x00de, 0x00ce, 0x003e, 0x002e, 0x001e, 0x0005,
- 0x0026, 0x00e6, 0x2011, 0x7519, 0x2071, 0x1a05, 0x701c, 0x9206,
+ 0x0026, 0x00e6, 0x2011, 0x7511, 0x2071, 0x1a05, 0x701c, 0x9206,
0x1118, 0x7018, 0x9005, 0x0110, 0x9085, 0x0001, 0x00ee, 0x002e,
0x0005, 0x6020, 0xd09c, 0x0005, 0x6800, 0x9084, 0xfffe, 0x9086,
- 0x00c0, 0x01b8, 0x2001, 0x00c0, 0x080c, 0x2abb, 0x0156, 0x20a9,
- 0x002d, 0x1d04, 0x7591, 0x2091, 0x6000, 0x1f04, 0x7591, 0x015e,
+ 0x00c0, 0x01b8, 0x2001, 0x00c0, 0x080c, 0x2aa2, 0x0156, 0x20a9,
+ 0x002d, 0x1d04, 0x7589, 0x2091, 0x6000, 0x1f04, 0x7589, 0x015e,
0x00d6, 0x2069, 0x1800, 0x689c, 0x8001, 0x0220, 0x0118, 0x689e,
0x00de, 0x0005, 0x689f, 0x0014, 0x68ec, 0xd0dc, 0x0dc8, 0x6800,
- 0x9086, 0x0001, 0x1da8, 0x080c, 0x894c, 0x0c90, 0x00c6, 0x00d6,
+ 0x9086, 0x0001, 0x1da8, 0x080c, 0x8944, 0x0c90, 0x00c6, 0x00d6,
0x00e6, 0x2061, 0x0100, 0x2069, 0x0140, 0x2071, 0x1800, 0x080c,
- 0x79b6, 0x2001, 0x196e, 0x2003, 0x0000, 0x9006, 0x709a, 0x60e2,
- 0x6886, 0x080c, 0x2716, 0x9006, 0x080c, 0x2abb, 0x080c, 0x6039,
- 0x0026, 0x2011, 0xffff, 0x080c, 0x2af5, 0x002e, 0x602b, 0x182c,
+ 0x79ae, 0x2001, 0x196e, 0x2003, 0x0000, 0x9006, 0x709a, 0x60e2,
+ 0x6886, 0x080c, 0x2715, 0x9006, 0x080c, 0x2aa2, 0x080c, 0x6033,
+ 0x0026, 0x2011, 0xffff, 0x080c, 0x2adc, 0x002e, 0x602b, 0x182c,
0x00ee, 0x00de, 0x00ce, 0x0005, 0x00c6, 0x00d6, 0x00e6, 0x2061,
0x0100, 0x2069, 0x0140, 0x2071, 0x1800, 0x2001, 0x197e, 0x200c,
0x9186, 0x0000, 0x0158, 0x9186, 0x0001, 0x0158, 0x9186, 0x0002,
- 0x0158, 0x9186, 0x0003, 0x0158, 0x0804, 0x7669, 0x709b, 0x0022,
+ 0x0158, 0x9186, 0x0003, 0x0158, 0x0804, 0x7661, 0x709b, 0x0022,
0x0040, 0x709b, 0x0021, 0x0028, 0x709b, 0x0023, 0x0010, 0x709b,
0x0024, 0x60e3, 0x0000, 0x6887, 0x0001, 0x2001, 0x0001, 0x080c,
- 0x2716, 0x080c, 0xaae0, 0x0026, 0x080c, 0xad9e, 0x080c, 0xae67,
- 0x002e, 0x080c, 0xaafc, 0x7000, 0x908e, 0x0004, 0x0118, 0x602b,
+ 0x2715, 0x080c, 0xaaf7, 0x0026, 0x080c, 0xadbe, 0x080c, 0xae87,
+ 0x002e, 0x080c, 0xab13, 0x7000, 0x908e, 0x0004, 0x0118, 0x602b,
0x0028, 0x0010, 0x602b, 0x0020, 0x0156, 0x0126, 0x2091, 0x8000,
0x20a9, 0x0005, 0x6024, 0xd0ac, 0x0150, 0x012e, 0x015e, 0x080c,
- 0xd33e, 0x0118, 0x9006, 0x080c, 0x2ae5, 0x0804, 0x7675, 0x6800,
- 0x9084, 0x00a1, 0xc0bd, 0x6802, 0x080c, 0x2aa1, 0x6904, 0xd1d4,
- 0x1140, 0x2001, 0x0100, 0x080c, 0x2abb, 0x1f04, 0x761a, 0x080c,
- 0x76f9, 0x012e, 0x015e, 0x080c, 0x76b6, 0x0170, 0x6044, 0x9005,
- 0x0130, 0x080c, 0x76f9, 0x9006, 0x8001, 0x1df0, 0x0028, 0x6804,
- 0xd0d4, 0x1110, 0x080c, 0x76f9, 0x080c, 0xd33e, 0x0118, 0x9006,
- 0x080c, 0x2ae5, 0x0016, 0x0026, 0x7000, 0x908e, 0x0004, 0x0130,
- 0x2009, 0x00c8, 0x2011, 0x7519, 0x080c, 0x88fe, 0x002e, 0x001e,
- 0x080c, 0x8731, 0x7034, 0xc085, 0x7036, 0x2001, 0x197e, 0x2003,
- 0x0004, 0x080c, 0x7354, 0x080c, 0x76b6, 0x0138, 0x6804, 0xd0d4,
- 0x1120, 0xd0dc, 0x1100, 0x080c, 0x79ac, 0x00ee, 0x00de, 0x00ce,
+ 0xd35d, 0x0118, 0x9006, 0x080c, 0x2acc, 0x0804, 0x766d, 0x6800,
+ 0x9084, 0x00a1, 0xc0bd, 0x6802, 0x080c, 0x2a88, 0x6904, 0xd1d4,
+ 0x1140, 0x2001, 0x0100, 0x080c, 0x2aa2, 0x1f04, 0x7612, 0x080c,
+ 0x76f1, 0x012e, 0x015e, 0x080c, 0x76ae, 0x0170, 0x6044, 0x9005,
+ 0x0130, 0x080c, 0x76f1, 0x9006, 0x8001, 0x1df0, 0x0028, 0x6804,
+ 0xd0d4, 0x1110, 0x080c, 0x76f1, 0x080c, 0xd35d, 0x0118, 0x9006,
+ 0x080c, 0x2acc, 0x0016, 0x0026, 0x7000, 0x908e, 0x0004, 0x0130,
+ 0x2009, 0x00c8, 0x2011, 0x7511, 0x080c, 0x88f6, 0x002e, 0x001e,
+ 0x080c, 0x8729, 0x7034, 0xc085, 0x7036, 0x2001, 0x197e, 0x2003,
+ 0x0004, 0x080c, 0x734c, 0x080c, 0x76ae, 0x0138, 0x6804, 0xd0d4,
+ 0x1120, 0xd0dc, 0x1100, 0x080c, 0x79a4, 0x00ee, 0x00de, 0x00ce,
0x0005, 0x00c6, 0x00d6, 0x00e6, 0x2061, 0x0100, 0x2069, 0x0140,
- 0x2071, 0x1800, 0x080c, 0x8748, 0x080c, 0x873a, 0x080c, 0x79b6,
+ 0x2071, 0x1800, 0x080c, 0x8740, 0x080c, 0x8732, 0x080c, 0x79ae,
0x2001, 0x196e, 0x2003, 0x0000, 0x9006, 0x709a, 0x60e2, 0x6886,
- 0x080c, 0x2716, 0x9006, 0x080c, 0x2abb, 0x6043, 0x0090, 0x6043,
- 0x0010, 0x0026, 0x2011, 0xffff, 0x080c, 0x2af5, 0x002e, 0x602b,
+ 0x080c, 0x2715, 0x9006, 0x080c, 0x2aa2, 0x6043, 0x0090, 0x6043,
+ 0x0010, 0x0026, 0x2011, 0xffff, 0x080c, 0x2adc, 0x002e, 0x602b,
0x182c, 0x00ee, 0x00de, 0x00ce, 0x0005, 0x0006, 0x2001, 0x197d,
- 0x2004, 0x9086, 0xaaaa, 0x000e, 0x0005, 0x0006, 0x080c, 0x582a,
+ 0x2004, 0x9086, 0xaaaa, 0x000e, 0x0005, 0x0006, 0x080c, 0x5824,
0x9084, 0x0030, 0x9086, 0x0000, 0x000e, 0x0005, 0x0006, 0x080c,
- 0x582a, 0x9084, 0x0030, 0x9086, 0x0030, 0x000e, 0x0005, 0x0006,
- 0x080c, 0x582a, 0x9084, 0x0030, 0x9086, 0x0010, 0x000e, 0x0005,
- 0x0006, 0x080c, 0x582a, 0x9084, 0x0030, 0x9086, 0x0020, 0x000e,
+ 0x5824, 0x9084, 0x0030, 0x9086, 0x0030, 0x000e, 0x0005, 0x0006,
+ 0x080c, 0x5824, 0x9084, 0x0030, 0x9086, 0x0010, 0x000e, 0x0005,
+ 0x0006, 0x080c, 0x5824, 0x9084, 0x0030, 0x9086, 0x0020, 0x000e,
0x0005, 0x0036, 0x0016, 0x2001, 0x180c, 0x2004, 0x908c, 0x0013,
- 0x0168, 0x0020, 0x080c, 0x2736, 0x900e, 0x0010, 0x2009, 0x0002,
- 0x2019, 0x0028, 0x080c, 0x32d5, 0x9006, 0x0019, 0x001e, 0x003e,
- 0x0005, 0x00e6, 0x2071, 0x180c, 0x2e04, 0x0130, 0x080c, 0xd337,
+ 0x0168, 0x0020, 0x080c, 0x2735, 0x900e, 0x0010, 0x2009, 0x0002,
+ 0x2019, 0x0028, 0x080c, 0x32c0, 0x9006, 0x0019, 0x001e, 0x003e,
+ 0x0005, 0x00e6, 0x2071, 0x180c, 0x2e04, 0x0130, 0x080c, 0xd356,
0x1128, 0x9085, 0x0010, 0x0010, 0x9084, 0xffef, 0x2072, 0x00ee,
0x0005, 0x6050, 0x0006, 0x60ec, 0x0006, 0x600c, 0x0006, 0x6004,
- 0x0006, 0x6028, 0x0006, 0x080c, 0x2b18, 0x080c, 0x2b4b, 0x602f,
+ 0x0006, 0x6028, 0x0006, 0x080c, 0x2aff, 0x080c, 0x2b32, 0x602f,
0x0100, 0x602f, 0x0000, 0x602f, 0x0040, 0x602f, 0x0000, 0x20a9,
- 0x0002, 0x080c, 0x2a82, 0x0026, 0x2011, 0x0040, 0x080c, 0x2af5,
+ 0x0002, 0x080c, 0x2a69, 0x0026, 0x2011, 0x0040, 0x080c, 0x2adc,
0x002e, 0x000e, 0x602a, 0x000e, 0x6006, 0x000e, 0x600e, 0x000e,
0x60ee, 0x60e3, 0x0000, 0x6887, 0x0001, 0x2001, 0x0001, 0x080c,
- 0x2716, 0x2001, 0x00a0, 0x0006, 0x080c, 0xd33e, 0x000e, 0x0130,
- 0x080c, 0x2ad9, 0x9006, 0x080c, 0x2ae5, 0x0010, 0x080c, 0x2abb,
+ 0x2715, 0x2001, 0x00a0, 0x0006, 0x080c, 0xd35d, 0x000e, 0x0130,
+ 0x080c, 0x2ac0, 0x9006, 0x080c, 0x2acc, 0x0010, 0x080c, 0x2aa2,
0x000e, 0x6052, 0x6050, 0x0006, 0xc0e5, 0x6052, 0x00f6, 0x2079,
- 0x0100, 0x080c, 0x2a2e, 0x00fe, 0x000e, 0x6052, 0x0005, 0x0156,
+ 0x0100, 0x080c, 0x2a19, 0x00fe, 0x000e, 0x6052, 0x0005, 0x0156,
0x0016, 0x0026, 0x0036, 0x00c6, 0x00d6, 0x00e6, 0x2061, 0x0100,
- 0x2069, 0x0140, 0x2071, 0x1800, 0x080c, 0xab3e, 0x0158, 0x2001,
- 0x0386, 0x2004, 0xd0b4, 0x1130, 0x2001, 0x0016, 0x080c, 0xaad1,
- 0x0804, 0x77d5, 0x2001, 0x180c, 0x200c, 0xc1c4, 0x2102, 0x6028,
- 0x9084, 0xe1ff, 0x602a, 0x2011, 0x0200, 0x080c, 0x2af5, 0x2001,
- 0x0090, 0x080c, 0x2abb, 0x20a9, 0x0366, 0x6024, 0xd0cc, 0x1558,
- 0x1d04, 0x7775, 0x2091, 0x6000, 0x1f04, 0x7775, 0x080c, 0xaae0,
- 0x2011, 0x0003, 0x080c, 0xa40f, 0x2011, 0x0002, 0x080c, 0xa419,
- 0x080c, 0xa300, 0x901e, 0x080c, 0xa380, 0x2001, 0x0386, 0x2003,
- 0x7000, 0x080c, 0xaafc, 0x2001, 0x00a0, 0x080c, 0x2abb, 0x080c,
- 0x79a7, 0x080c, 0x617e, 0x080c, 0xd33e, 0x0110, 0x080c, 0x0cf1,
- 0x9085, 0x0001, 0x04c0, 0x080c, 0x1b6c, 0x60e3, 0x0000, 0x2001,
- 0x196e, 0x2004, 0x080c, 0x2716, 0x60e2, 0x2001, 0x0080, 0x080c,
- 0x2abb, 0x20a9, 0x0366, 0x2011, 0x1e00, 0x080c, 0x2af5, 0x2009,
- 0x1e00, 0x080c, 0x2aa1, 0x6024, 0x910c, 0x0140, 0x1d04, 0x77b3,
- 0x2091, 0x6000, 0x1f04, 0x77b3, 0x0804, 0x777e, 0x2001, 0x0386,
+ 0x2069, 0x0140, 0x2071, 0x1800, 0x080c, 0xab55, 0x0158, 0x2001,
+ 0x0386, 0x2004, 0xd0b4, 0x1130, 0x2001, 0x0016, 0x080c, 0xaae8,
+ 0x0804, 0x77cd, 0x2001, 0x180c, 0x200c, 0xc1c4, 0x2102, 0x6028,
+ 0x9084, 0xe1ff, 0x602a, 0x2011, 0x0200, 0x080c, 0x2adc, 0x2001,
+ 0x0090, 0x080c, 0x2aa2, 0x20a9, 0x0366, 0x6024, 0xd0cc, 0x1558,
+ 0x1d04, 0x776d, 0x2091, 0x6000, 0x1f04, 0x776d, 0x080c, 0xaaf7,
+ 0x2011, 0x0003, 0x080c, 0xa426, 0x2011, 0x0002, 0x080c, 0xa430,
+ 0x080c, 0xa311, 0x901e, 0x080c, 0xa391, 0x2001, 0x0386, 0x2003,
+ 0x7000, 0x080c, 0xab13, 0x2001, 0x00a0, 0x080c, 0x2aa2, 0x080c,
+ 0x799f, 0x080c, 0x6178, 0x080c, 0xd35d, 0x0110, 0x080c, 0x0ce5,
+ 0x9085, 0x0001, 0x04c0, 0x080c, 0x1b68, 0x60e3, 0x0000, 0x2001,
+ 0x196e, 0x2004, 0x080c, 0x2715, 0x60e2, 0x2001, 0x0080, 0x080c,
+ 0x2aa2, 0x20a9, 0x0366, 0x2011, 0x1e00, 0x080c, 0x2adc, 0x2009,
+ 0x1e00, 0x080c, 0x2a88, 0x6024, 0x910c, 0x0140, 0x1d04, 0x77ab,
+ 0x2091, 0x6000, 0x1f04, 0x77ab, 0x0804, 0x7776, 0x2001, 0x0386,
0x2003, 0x7000, 0x6028, 0x9085, 0x1e00, 0x602a, 0x70b4, 0x9005,
- 0x1118, 0x6887, 0x0001, 0x0008, 0x6886, 0x080c, 0xd33e, 0x0110,
- 0x080c, 0x0cf1, 0x9006, 0x00ee, 0x00de, 0x00ce, 0x003e, 0x002e,
+ 0x1118, 0x6887, 0x0001, 0x0008, 0x6886, 0x080c, 0xd35d, 0x0110,
+ 0x080c, 0x0ce5, 0x9006, 0x00ee, 0x00de, 0x00ce, 0x003e, 0x002e,
0x001e, 0x015e, 0x0005, 0x0156, 0x0016, 0x0026, 0x0036, 0x00c6,
0x00d6, 0x00e6, 0x2061, 0x0100, 0x2071, 0x1800, 0x7000, 0x9086,
0x0003, 0x1168, 0x2001, 0x020b, 0x2004, 0x9084, 0x5540, 0x9086,
0x5540, 0x1128, 0x2069, 0x1a7c, 0x2d04, 0x8000, 0x206a, 0x2069,
0x0140, 0x6020, 0x9084, 0x00c0, 0x0120, 0x6884, 0x9005, 0x1904,
- 0x784c, 0x2001, 0x0088, 0x080c, 0x2abb, 0x9006, 0x60e2, 0x6886,
- 0x080c, 0x2716, 0x2069, 0x0200, 0x6804, 0x9005, 0x1118, 0x6808,
+ 0x7844, 0x2001, 0x0088, 0x080c, 0x2aa2, 0x9006, 0x60e2, 0x6886,
+ 0x080c, 0x2715, 0x2069, 0x0200, 0x6804, 0x9005, 0x1118, 0x6808,
0x9005, 0x01d0, 0x6028, 0x9084, 0xfbff, 0x602a, 0x2011, 0x0400,
- 0x080c, 0x2af5, 0x2069, 0x1990, 0x7000, 0x206a, 0x709b, 0x0026,
- 0x7003, 0x0001, 0x20a9, 0x0002, 0x1d04, 0x782c, 0x2091, 0x6000,
- 0x1f04, 0x782c, 0x0804, 0x7880, 0x2069, 0x0140, 0x20a9, 0x0384,
- 0x2011, 0x1e00, 0x080c, 0x2af5, 0x2009, 0x1e00, 0x080c, 0x2aa1,
- 0x6024, 0x910c, 0x0528, 0x9084, 0x1a00, 0x1510, 0x1d04, 0x7838,
- 0x2091, 0x6000, 0x1f04, 0x7838, 0x080c, 0xaae0, 0x2011, 0x0003,
- 0x080c, 0xa40f, 0x2011, 0x0002, 0x080c, 0xa419, 0x080c, 0xa300,
- 0x901e, 0x080c, 0xa380, 0x080c, 0xaafc, 0x2001, 0x00a0, 0x080c,
- 0x2abb, 0x080c, 0x79a7, 0x080c, 0x617e, 0x9085, 0x0001, 0x00c0,
- 0x080c, 0x1b6c, 0x2001, 0x0080, 0x080c, 0x2abb, 0x2069, 0x0140,
+ 0x080c, 0x2adc, 0x2069, 0x1990, 0x7000, 0x206a, 0x709b, 0x0026,
+ 0x7003, 0x0001, 0x20a9, 0x0002, 0x1d04, 0x7824, 0x2091, 0x6000,
+ 0x1f04, 0x7824, 0x0804, 0x7878, 0x2069, 0x0140, 0x20a9, 0x0384,
+ 0x2011, 0x1e00, 0x080c, 0x2adc, 0x2009, 0x1e00, 0x080c, 0x2a88,
+ 0x6024, 0x910c, 0x0528, 0x9084, 0x1a00, 0x1510, 0x1d04, 0x7830,
+ 0x2091, 0x6000, 0x1f04, 0x7830, 0x080c, 0xaaf7, 0x2011, 0x0003,
+ 0x080c, 0xa426, 0x2011, 0x0002, 0x080c, 0xa430, 0x080c, 0xa311,
+ 0x901e, 0x080c, 0xa391, 0x080c, 0xab13, 0x2001, 0x00a0, 0x080c,
+ 0x2aa2, 0x080c, 0x799f, 0x080c, 0x6178, 0x9085, 0x0001, 0x00c0,
+ 0x080c, 0x1b68, 0x2001, 0x0080, 0x080c, 0x2aa2, 0x2069, 0x0140,
0x60e3, 0x0000, 0x70b4, 0x9005, 0x1118, 0x6887, 0x0001, 0x0008,
- 0x6886, 0x2001, 0x196e, 0x2004, 0x080c, 0x2716, 0x60e2, 0x9006,
+ 0x6886, 0x2001, 0x196e, 0x2004, 0x080c, 0x2715, 0x60e2, 0x9006,
0x00ee, 0x00de, 0x00ce, 0x003e, 0x002e, 0x001e, 0x015e, 0x0005,
0x0156, 0x0016, 0x0026, 0x0036, 0x00c6, 0x00d6, 0x00e6, 0x2061,
0x0100, 0x2071, 0x1800, 0x6020, 0x9084, 0x00c0, 0x01e8, 0x080c,
- 0xaae0, 0x2011, 0x0003, 0x080c, 0xa40f, 0x2011, 0x0002, 0x080c,
- 0xa419, 0x080c, 0xa300, 0x901e, 0x080c, 0xa380, 0x080c, 0xaafc,
- 0x2069, 0x0140, 0x2001, 0x00a0, 0x080c, 0x2abb, 0x080c, 0x79a7,
- 0x080c, 0x617e, 0x0804, 0x7923, 0x2001, 0x180c, 0x200c, 0xd1b4,
- 0x1160, 0xc1b5, 0x2102, 0x080c, 0x7501, 0x2069, 0x0140, 0x2001,
- 0x0080, 0x080c, 0x2abb, 0x60e3, 0x0000, 0x2069, 0x0200, 0x6804,
+ 0xaaf7, 0x2011, 0x0003, 0x080c, 0xa426, 0x2011, 0x0002, 0x080c,
+ 0xa430, 0x080c, 0xa311, 0x901e, 0x080c, 0xa391, 0x080c, 0xab13,
+ 0x2069, 0x0140, 0x2001, 0x00a0, 0x080c, 0x2aa2, 0x080c, 0x799f,
+ 0x080c, 0x6178, 0x0804, 0x791b, 0x2001, 0x180c, 0x200c, 0xd1b4,
+ 0x1160, 0xc1b5, 0x2102, 0x080c, 0x74f9, 0x2069, 0x0140, 0x2001,
+ 0x0080, 0x080c, 0x2aa2, 0x60e3, 0x0000, 0x2069, 0x0200, 0x6804,
0x9005, 0x1118, 0x6808, 0x9005, 0x0190, 0x6028, 0x9084, 0xfdff,
- 0x602a, 0x2011, 0x0200, 0x080c, 0x2af5, 0x2069, 0x1990, 0x7000,
- 0x206a, 0x709b, 0x0027, 0x7003, 0x0001, 0x0804, 0x7923, 0x2011,
- 0x1e00, 0x080c, 0x2af5, 0x2009, 0x1e00, 0x080c, 0x2aa1, 0x6024,
- 0x910c, 0x01c8, 0x9084, 0x1c00, 0x11b0, 0x1d04, 0x78df, 0x0006,
- 0x0016, 0x00c6, 0x00d6, 0x00e6, 0x080c, 0x8788, 0x00ee, 0x00de,
+ 0x602a, 0x2011, 0x0200, 0x080c, 0x2adc, 0x2069, 0x1990, 0x7000,
+ 0x206a, 0x709b, 0x0027, 0x7003, 0x0001, 0x0804, 0x791b, 0x2011,
+ 0x1e00, 0x080c, 0x2adc, 0x2009, 0x1e00, 0x080c, 0x2a88, 0x6024,
+ 0x910c, 0x01c8, 0x9084, 0x1c00, 0x11b0, 0x1d04, 0x78d7, 0x0006,
+ 0x0016, 0x00c6, 0x00d6, 0x00e6, 0x080c, 0x8780, 0x00ee, 0x00de,
0x00ce, 0x001e, 0x000e, 0x00e6, 0x2071, 0x1a05, 0x7078, 0x00ee,
- 0x9005, 0x19e8, 0x0400, 0x0026, 0x2011, 0x7519, 0x080c, 0x8834,
- 0x2011, 0x750c, 0x080c, 0x8940, 0x002e, 0x2069, 0x0140, 0x60e3,
+ 0x9005, 0x19e8, 0x0400, 0x0026, 0x2011, 0x7511, 0x080c, 0x882c,
+ 0x2011, 0x7504, 0x080c, 0x8938, 0x002e, 0x2069, 0x0140, 0x60e3,
0x0000, 0x70b4, 0x9005, 0x1118, 0x6887, 0x0001, 0x0008, 0x6886,
- 0x2001, 0x196e, 0x2004, 0x080c, 0x2716, 0x60e2, 0x2001, 0x180c,
+ 0x2001, 0x196e, 0x2004, 0x080c, 0x2715, 0x60e2, 0x2001, 0x180c,
0x200c, 0xc1b4, 0x2102, 0x00ee, 0x00de, 0x00ce, 0x003e, 0x002e,
0x001e, 0x015e, 0x0005, 0x0156, 0x0016, 0x0026, 0x0036, 0x0046,
- 0x00c6, 0x00e6, 0x2061, 0x0100, 0x2071, 0x1800, 0x080c, 0xd337,
- 0x1904, 0x7991, 0x7130, 0xd184, 0x1170, 0x080c, 0x347d, 0x0138,
+ 0x00c6, 0x00e6, 0x2061, 0x0100, 0x2071, 0x1800, 0x080c, 0xd356,
+ 0x1904, 0x7989, 0x7130, 0xd184, 0x1170, 0x080c, 0x3468, 0x0138,
0xc18d, 0x7132, 0x2011, 0x1848, 0x2214, 0xd2ac, 0x1120, 0x7030,
- 0xd08c, 0x0904, 0x7991, 0x2011, 0x1848, 0x220c, 0xd1a4, 0x0538,
- 0x0016, 0x2019, 0x000e, 0x080c, 0xe696, 0x0156, 0x00b6, 0x20a9,
+ 0xd08c, 0x0904, 0x7989, 0x2011, 0x1848, 0x220c, 0xd1a4, 0x0538,
+ 0x0016, 0x2019, 0x000e, 0x080c, 0xe701, 0x0156, 0x00b6, 0x20a9,
0x007f, 0x900e, 0x9186, 0x007e, 0x01a0, 0x9186, 0x0080, 0x0188,
- 0x080c, 0x6789, 0x1170, 0x2120, 0x9006, 0x0016, 0x2009, 0x000e,
- 0x080c, 0xe72a, 0x2009, 0x0001, 0x2011, 0x0100, 0x080c, 0x8ae5,
- 0x001e, 0x8108, 0x1f04, 0x795a, 0x00be, 0x015e, 0x001e, 0xd1ac,
- 0x1148, 0x0016, 0x2009, 0x0002, 0x2019, 0x0004, 0x080c, 0x32d5,
+ 0x080c, 0x6783, 0x1170, 0x2120, 0x9006, 0x0016, 0x2009, 0x000e,
+ 0x080c, 0xe795, 0x2009, 0x0001, 0x2011, 0x0100, 0x080c, 0x8add,
+ 0x001e, 0x8108, 0x1f04, 0x7952, 0x00be, 0x015e, 0x001e, 0xd1ac,
+ 0x1148, 0x0016, 0x2009, 0x0002, 0x2019, 0x0004, 0x080c, 0x32c0,
0x001e, 0x0078, 0x0156, 0x00b6, 0x20a9, 0x007f, 0x900e, 0x080c,
- 0x6789, 0x1110, 0x080c, 0x6198, 0x8108, 0x1f04, 0x7987, 0x00be,
- 0x015e, 0x080c, 0x1b6c, 0x080c, 0xaae0, 0x080c, 0xae67, 0x080c,
- 0xaafc, 0x60e3, 0x0000, 0x080c, 0x617e, 0x080c, 0x75d4, 0x00ee,
+ 0x6783, 0x1110, 0x080c, 0x6192, 0x8108, 0x1f04, 0x797f, 0x00be,
+ 0x015e, 0x080c, 0x1b68, 0x080c, 0xaaf7, 0x080c, 0xae87, 0x080c,
+ 0xab13, 0x60e3, 0x0000, 0x080c, 0x6178, 0x080c, 0x75cc, 0x00ee,
0x00ce, 0x004e, 0x003e, 0x002e, 0x001e, 0x015e, 0x0005, 0x2001,
0x197e, 0x2003, 0x0001, 0x0005, 0x2001, 0x197e, 0x2003, 0x0000,
0x0005, 0x2001, 0x197d, 0x2003, 0xaaaa, 0x0005, 0x2001, 0x197d,
0x2003, 0x0000, 0x0005, 0x2071, 0x18fa, 0x7003, 0x0000, 0x7007,
- 0x0000, 0x080c, 0x1072, 0x090c, 0x0d85, 0xa8ab, 0xdcb0, 0x2900,
- 0x704e, 0x080c, 0x1072, 0x090c, 0x0d85, 0xa8ab, 0xdcb0, 0x2900,
+ 0x0000, 0x080c, 0x1066, 0x090c, 0x0d79, 0xa8ab, 0xdcb0, 0x2900,
+ 0x704e, 0x080c, 0x1066, 0x090c, 0x0d79, 0xa8ab, 0xdcb0, 0x2900,
0x7052, 0xa867, 0x0000, 0xa86b, 0x0001, 0xa89f, 0x0000, 0x0005,
0x00e6, 0x2071, 0x0040, 0x6848, 0x9005, 0x1118, 0x9085, 0x0001,
0x04b0, 0x6840, 0x9005, 0x0150, 0x04a1, 0x6a50, 0x9200, 0x7002,
@@ -3700,78 +3687,78 @@ unsigned short risc_code01[] = {
0x1110, 0x7012, 0x7016, 0x6848, 0x701a, 0x701c, 0x9085, 0x0040,
0x701e, 0x2001, 0x0019, 0x7036, 0x702b, 0x0001, 0x2001, 0x0004,
0x200c, 0x918c, 0xfff7, 0x918d, 0x8000, 0x2102, 0x00d6, 0x2069,
- 0x18fa, 0x6807, 0x0001, 0x00de, 0x080c, 0x7fa4, 0x9006, 0x00ee,
+ 0x18fa, 0x6807, 0x0001, 0x00de, 0x080c, 0x7f9c, 0x9006, 0x00ee,
0x0005, 0x900e, 0x0156, 0x20a9, 0x0006, 0x8003, 0x818d, 0x1f04,
- 0x7a1d, 0x015e, 0x0005, 0x2079, 0x0040, 0x2071, 0x18fa, 0x7004,
- 0x0002, 0x7a33, 0x7a34, 0x7a80, 0x7adb, 0x7beb, 0x7a31, 0x7a31,
- 0x7c15, 0x080c, 0x0d85, 0x0005, 0x2079, 0x0040, 0x2001, 0x1dc0,
- 0x2003, 0x0000, 0x782c, 0x908c, 0x0780, 0x190c, 0x8086, 0xd0a4,
+ 0x7a15, 0x015e, 0x0005, 0x2079, 0x0040, 0x2071, 0x18fa, 0x7004,
+ 0x0002, 0x7a2b, 0x7a2c, 0x7a78, 0x7ad3, 0x7be3, 0x7a29, 0x7a29,
+ 0x7c0d, 0x080c, 0x0d79, 0x0005, 0x2079, 0x0040, 0x2001, 0x1dc0,
+ 0x2003, 0x0000, 0x782c, 0x908c, 0x0780, 0x190c, 0x807e, 0xd0a4,
0x0578, 0x2001, 0x1dc0, 0x2004, 0x9082, 0x0080, 0x1648, 0x1d04,
- 0x7a51, 0x2001, 0x1a08, 0x200c, 0x8109, 0x0510, 0x2091, 0x6000,
+ 0x7a49, 0x2001, 0x1a08, 0x200c, 0x8109, 0x0510, 0x2091, 0x6000,
0x2102, 0x7824, 0x2048, 0x9006, 0xa802, 0xa806, 0xa864, 0x9084,
0x00ff, 0x908a, 0x0040, 0x0610, 0x00c0, 0x2001, 0x1800, 0x200c,
- 0x9186, 0x0003, 0x1168, 0x7004, 0x0002, 0x7a70, 0x7a3a, 0x7a70,
- 0x7a6e, 0x7a70, 0x7a70, 0x7a70, 0x7a70, 0x7a70, 0x080c, 0x7adb,
- 0x782c, 0xd09c, 0x090c, 0x7fa4, 0x0005, 0x9082, 0x005a, 0x1218,
- 0x2100, 0x003b, 0x0c10, 0x080c, 0x7b11, 0x0c90, 0x00e3, 0x08e8,
- 0x0005, 0x7b11, 0x7b11, 0x7b11, 0x7b11, 0x7b11, 0x7b11, 0x7b11,
- 0x7b11, 0x7b33, 0x7b11, 0x7b11, 0x7b11, 0x7b11, 0x7b11, 0x7b11,
- 0x7b11, 0x7b11, 0x7b11, 0x7b11, 0x7b11, 0x7b11, 0x7b11, 0x7b11,
- 0x7b11, 0x7b11, 0x7b11, 0x7b11, 0x7b11, 0x7b1d, 0x7b11, 0x7d0b,
- 0x7b11, 0x7b11, 0x7b11, 0x7b33, 0x7b11, 0x7b1d, 0x7d4c, 0x7d8d,
- 0x7dd4, 0x7de8, 0x7b11, 0x7b11, 0x7b33, 0x7b1d, 0x7b47, 0x7b11,
- 0x7bbf, 0x7e93, 0x7eae, 0x7b11, 0x7b33, 0x7b11, 0x7b47, 0x7b11,
- 0x7b11, 0x7bb5, 0x7eae, 0x7b11, 0x7b11, 0x7b11, 0x7b11, 0x7b11,
- 0x7b11, 0x7b11, 0x7b11, 0x7b11, 0x7b5b, 0x7b11, 0x7b11, 0x7b11,
- 0x7b11, 0x7b11, 0x7b11, 0x7b11, 0x7b11, 0x7b11, 0x802a, 0x7b11,
- 0x7fd4, 0x7b11, 0x7fd4, 0x7b11, 0x7b70, 0x7b11, 0x7b11, 0x7b11,
- 0x7b11, 0x7b11, 0x7b11, 0x2079, 0x0040, 0x7004, 0x9086, 0x0003,
- 0x1198, 0x782c, 0x080c, 0x7fcd, 0xd0a4, 0x0170, 0x7824, 0x2048,
+ 0x9186, 0x0003, 0x1168, 0x7004, 0x0002, 0x7a68, 0x7a32, 0x7a68,
+ 0x7a66, 0x7a68, 0x7a68, 0x7a68, 0x7a68, 0x7a68, 0x080c, 0x7ad3,
+ 0x782c, 0xd09c, 0x090c, 0x7f9c, 0x0005, 0x9082, 0x005a, 0x1218,
+ 0x2100, 0x003b, 0x0c10, 0x080c, 0x7b09, 0x0c90, 0x00e3, 0x08e8,
+ 0x0005, 0x7b09, 0x7b09, 0x7b09, 0x7b09, 0x7b09, 0x7b09, 0x7b09,
+ 0x7b09, 0x7b2b, 0x7b09, 0x7b09, 0x7b09, 0x7b09, 0x7b09, 0x7b09,
+ 0x7b09, 0x7b09, 0x7b09, 0x7b09, 0x7b09, 0x7b09, 0x7b09, 0x7b09,
+ 0x7b09, 0x7b09, 0x7b09, 0x7b09, 0x7b09, 0x7b15, 0x7b09, 0x7d03,
+ 0x7b09, 0x7b09, 0x7b09, 0x7b2b, 0x7b09, 0x7b15, 0x7d44, 0x7d85,
+ 0x7dcc, 0x7de0, 0x7b09, 0x7b09, 0x7b2b, 0x7b15, 0x7b3f, 0x7b09,
+ 0x7bb7, 0x7e8b, 0x7ea6, 0x7b09, 0x7b2b, 0x7b09, 0x7b3f, 0x7b09,
+ 0x7b09, 0x7bad, 0x7ea6, 0x7b09, 0x7b09, 0x7b09, 0x7b09, 0x7b09,
+ 0x7b09, 0x7b09, 0x7b09, 0x7b09, 0x7b53, 0x7b09, 0x7b09, 0x7b09,
+ 0x7b09, 0x7b09, 0x7b09, 0x7b09, 0x7b09, 0x7b09, 0x8022, 0x7b09,
+ 0x7fcc, 0x7b09, 0x7fcc, 0x7b09, 0x7b68, 0x7b09, 0x7b09, 0x7b09,
+ 0x7b09, 0x7b09, 0x7b09, 0x2079, 0x0040, 0x7004, 0x9086, 0x0003,
+ 0x1198, 0x782c, 0x080c, 0x7fc5, 0xd0a4, 0x0170, 0x7824, 0x2048,
0x9006, 0xa802, 0xa806, 0xa864, 0x9084, 0x00ff, 0x908a, 0x001a,
- 0x1210, 0x002b, 0x0c50, 0x00e9, 0x080c, 0x7fa4, 0x0005, 0x7b11,
- 0x7b1d, 0x7cf7, 0x7b11, 0x7b1d, 0x7b11, 0x7b1d, 0x7b1d, 0x7b11,
- 0x7b1d, 0x7cf7, 0x7b1d, 0x7b1d, 0x7b1d, 0x7b1d, 0x7b1d, 0x7b11,
- 0x7b1d, 0x7cf7, 0x7b11, 0x7b11, 0x7b1d, 0x7b11, 0x7b11, 0x7b11,
- 0x7b1d, 0x00e6, 0x2071, 0x18fa, 0x2009, 0x0400, 0x0071, 0x00ee,
+ 0x1210, 0x002b, 0x0c50, 0x00e9, 0x080c, 0x7f9c, 0x0005, 0x7b09,
+ 0x7b15, 0x7cef, 0x7b09, 0x7b15, 0x7b09, 0x7b15, 0x7b15, 0x7b09,
+ 0x7b15, 0x7cef, 0x7b15, 0x7b15, 0x7b15, 0x7b15, 0x7b15, 0x7b09,
+ 0x7b15, 0x7cef, 0x7b09, 0x7b09, 0x7b15, 0x7b09, 0x7b09, 0x7b09,
+ 0x7b15, 0x00e6, 0x2071, 0x18fa, 0x2009, 0x0400, 0x0071, 0x00ee,
0x0005, 0x2009, 0x1000, 0x0049, 0x0005, 0x2009, 0x2000, 0x0029,
0x0005, 0x2009, 0x0800, 0x0009, 0x0005, 0x7007, 0x0001, 0xa868,
0x9084, 0x00ff, 0x9105, 0xa86a, 0x0126, 0x2091, 0x8000, 0x080c,
- 0x6f19, 0x012e, 0x0005, 0xa864, 0x8007, 0x9084, 0x00ff, 0x0d08,
- 0x8001, 0x1120, 0x7007, 0x0001, 0x0804, 0x7c94, 0x7007, 0x0003,
- 0x7012, 0x2900, 0x7016, 0x701a, 0x704b, 0x7c94, 0x0005, 0xa864,
+ 0x6f11, 0x012e, 0x0005, 0xa864, 0x8007, 0x9084, 0x00ff, 0x0d08,
+ 0x8001, 0x1120, 0x7007, 0x0001, 0x0804, 0x7c8c, 0x7007, 0x0003,
+ 0x7012, 0x2900, 0x7016, 0x701a, 0x704b, 0x7c8c, 0x0005, 0xa864,
0x8007, 0x9084, 0x00ff, 0x0968, 0x8001, 0x1120, 0x7007, 0x0001,
- 0x0804, 0x7caf, 0x7007, 0x0003, 0x7012, 0x2900, 0x7016, 0x701a,
- 0x704b, 0x7caf, 0x0005, 0xa864, 0x8007, 0x9084, 0x00ff, 0x0904,
- 0x7b19, 0x8001, 0x1120, 0x7007, 0x0001, 0x0804, 0x7ccb, 0x7007,
- 0x0003, 0x7012, 0x2900, 0x7016, 0x701a, 0x704b, 0x7ccb, 0x0005,
- 0xa864, 0x8007, 0x9084, 0x00ff, 0x9086, 0x0001, 0x1904, 0x7b19,
+ 0x0804, 0x7ca7, 0x7007, 0x0003, 0x7012, 0x2900, 0x7016, 0x701a,
+ 0x704b, 0x7ca7, 0x0005, 0xa864, 0x8007, 0x9084, 0x00ff, 0x0904,
+ 0x7b11, 0x8001, 0x1120, 0x7007, 0x0001, 0x0804, 0x7cc3, 0x7007,
+ 0x0003, 0x7012, 0x2900, 0x7016, 0x701a, 0x704b, 0x7cc3, 0x0005,
+ 0xa864, 0x8007, 0x9084, 0x00ff, 0x9086, 0x0001, 0x1904, 0x7b11,
0x7007, 0x0001, 0x2009, 0x1834, 0x210c, 0x81ff, 0x11a8, 0xa868,
- 0x9084, 0x00ff, 0xa86a, 0xa883, 0x0000, 0x080c, 0x6411, 0x1108,
+ 0x9084, 0x00ff, 0xa86a, 0xa883, 0x0000, 0x080c, 0x640b, 0x1108,
0x0005, 0x0126, 0x2091, 0x8000, 0xa867, 0x0139, 0xa87a, 0xa982,
- 0x080c, 0x6f19, 0x012e, 0x0ca0, 0xa994, 0x9186, 0x0071, 0x0d38,
+ 0x080c, 0x6f11, 0x012e, 0x0ca0, 0xa994, 0x9186, 0x0071, 0x0d38,
0x9186, 0x0064, 0x0d20, 0x9186, 0x007c, 0x0d08, 0x9186, 0x0028,
0x09f0, 0x9186, 0x0038, 0x09d8, 0x9186, 0x0078, 0x09c0, 0x9186,
0x005f, 0x09a8, 0x9186, 0x0056, 0x0990, 0xa897, 0x4005, 0xa89b,
0x0001, 0x2001, 0x0030, 0x900e, 0x08a0, 0xa87c, 0x9084, 0x00c0,
- 0x9086, 0x00c0, 0x1120, 0x7007, 0x0001, 0x0804, 0x7ec5, 0x2900,
+ 0x9086, 0x00c0, 0x1120, 0x7007, 0x0001, 0x0804, 0x7ebd, 0x2900,
0x7016, 0x701a, 0x20a9, 0x0004, 0xa860, 0x20e0, 0xa85c, 0x9080,
0x0030, 0x2098, 0x7050, 0x2040, 0xa060, 0x20e8, 0xa05c, 0x9080,
0x0023, 0x20a0, 0x4003, 0xa888, 0x7012, 0x9082, 0x0401, 0x1a04,
- 0x7b21, 0xaab4, 0x928a, 0x0002, 0x1a04, 0x7b21, 0x82ff, 0x1138,
- 0xa8b8, 0xa9bc, 0x9105, 0x0118, 0x2001, 0x7c52, 0x0018, 0x9280,
- 0x7c48, 0x2005, 0x7056, 0x7010, 0x9015, 0x0904, 0x7c33, 0x080c,
- 0x1072, 0x1118, 0x7007, 0x0004, 0x0005, 0x2900, 0x7022, 0x7054,
+ 0x7b19, 0xaab4, 0x928a, 0x0002, 0x1a04, 0x7b19, 0x82ff, 0x1138,
+ 0xa8b8, 0xa9bc, 0x9105, 0x0118, 0x2001, 0x7c4a, 0x0018, 0x9280,
+ 0x7c40, 0x2005, 0x7056, 0x7010, 0x9015, 0x0904, 0x7c2b, 0x080c,
+ 0x1066, 0x1118, 0x7007, 0x0004, 0x0005, 0x2900, 0x7022, 0x7054,
0x2060, 0xe000, 0xa866, 0x7050, 0x2040, 0xa95c, 0xe004, 0x9100,
0xa076, 0xa860, 0xa072, 0xe008, 0x920a, 0x1210, 0x900e, 0x2200,
0x7112, 0xe20c, 0x8003, 0x800b, 0x9296, 0x0004, 0x0108, 0x9108,
- 0xa17a, 0x810b, 0xa17e, 0x080c, 0x114e, 0xa06c, 0x908e, 0x0100,
+ 0xa17a, 0x810b, 0xa17e, 0x080c, 0x1142, 0xa06c, 0x908e, 0x0100,
0x0170, 0x9086, 0x0200, 0x0118, 0x7007, 0x0007, 0x0005, 0x7020,
- 0x2048, 0x080c, 0x108b, 0x7014, 0x2048, 0x0804, 0x7b21, 0x7020,
+ 0x2048, 0x080c, 0x107f, 0x7014, 0x2048, 0x0804, 0x7b19, 0x7020,
0x2048, 0x7018, 0xa802, 0xa807, 0x0000, 0x2908, 0x2048, 0xa906,
- 0x711a, 0x0804, 0x7beb, 0x7014, 0x2048, 0x7007, 0x0001, 0xa8b4,
+ 0x711a, 0x0804, 0x7be3, 0x7014, 0x2048, 0x7007, 0x0001, 0xa8b4,
0x9005, 0x1128, 0xa8b8, 0xa9bc, 0x9105, 0x0108, 0x00b9, 0xa864,
- 0x9084, 0x00ff, 0x9086, 0x001e, 0x0904, 0x7ec5, 0x0804, 0x7c94,
- 0x7c4a, 0x7c4e, 0x0002, 0x001d, 0x0007, 0x0004, 0x000a, 0x001b,
+ 0x9084, 0x00ff, 0x9086, 0x001e, 0x0904, 0x7ebd, 0x0804, 0x7c8c,
+ 0x7c42, 0x7c46, 0x0002, 0x001d, 0x0007, 0x0004, 0x000a, 0x001b,
0x0005, 0x0006, 0x000a, 0x001d, 0x0005, 0x0004, 0x0076, 0x0066,
0xafb8, 0xaebc, 0xa804, 0x2050, 0xb0c0, 0xb0e2, 0xb0bc, 0xb0de,
0xb0b8, 0xb0d2, 0xb0b4, 0xb0ce, 0xb6da, 0xb7d6, 0xb0b0, 0xb0ca,
@@ -3781,16 +3768,16 @@ unsigned short risc_code01[] = {
0xb084, 0xb086, 0xb692, 0xb78e, 0xb080, 0xb082, 0xb07c, 0xb07e,
0xb078, 0xb072, 0xb074, 0xb06e, 0xb67a, 0xb776, 0xb004, 0x9055,
0x1958, 0x006e, 0x007e, 0x0005, 0x2009, 0x1834, 0x210c, 0x81ff,
- 0x1178, 0x080c, 0x6210, 0x1108, 0x0005, 0x080c, 0x7165, 0x0126,
- 0x2091, 0x8000, 0x080c, 0xcf1b, 0x080c, 0x6f19, 0x012e, 0x0ca0,
- 0x080c, 0xd337, 0x1d70, 0x2001, 0x0028, 0x900e, 0x0c70, 0x2009,
+ 0x1178, 0x080c, 0x620a, 0x1108, 0x0005, 0x080c, 0x715d, 0x0126,
+ 0x2091, 0x8000, 0x080c, 0xcf38, 0x080c, 0x6f11, 0x012e, 0x0ca0,
+ 0x080c, 0xd356, 0x1d70, 0x2001, 0x0028, 0x900e, 0x0c70, 0x2009,
0x1834, 0x210c, 0x81ff, 0x1188, 0xa888, 0x9005, 0x0188, 0xa883,
- 0x0000, 0x080c, 0x629e, 0x1108, 0x0005, 0xa87a, 0x0126, 0x2091,
- 0x8000, 0x080c, 0x6f19, 0x012e, 0x0cb8, 0x2001, 0x0028, 0x0ca8,
+ 0x0000, 0x080c, 0x6298, 0x1108, 0x0005, 0xa87a, 0x0126, 0x2091,
+ 0x8000, 0x080c, 0x6f11, 0x012e, 0x0cb8, 0x2001, 0x0028, 0x0ca8,
0x2001, 0x0000, 0x0c90, 0x0419, 0x11d8, 0xa888, 0x9005, 0x01e0,
- 0xa883, 0x0000, 0xa87c, 0xd0f4, 0x0120, 0x080c, 0x6373, 0x1138,
- 0x0005, 0x9006, 0xa87a, 0x080c, 0x62eb, 0x1108, 0x0005, 0x0126,
- 0x2091, 0x8000, 0xa87a, 0xa982, 0x080c, 0x6f19, 0x012e, 0x0cb0,
+ 0xa883, 0x0000, 0xa87c, 0xd0f4, 0x0120, 0x080c, 0x636d, 0x1138,
+ 0x0005, 0x9006, 0xa87a, 0x080c, 0x62e5, 0x1108, 0x0005, 0x0126,
+ 0x2091, 0x8000, 0xa87a, 0xa982, 0x080c, 0x6f11, 0x012e, 0x0cb0,
0x2001, 0x0028, 0x900e, 0x0c98, 0x2001, 0x0000, 0x0c80, 0x00c6,
0x2061, 0x1800, 0x60d0, 0x9005, 0x0100, 0x00ce, 0x0005, 0x7018,
0xa802, 0x2908, 0x2048, 0xa906, 0x711a, 0x7010, 0x8001, 0x7012,
@@ -3798,222 +3785,222 @@ unsigned short risc_code01[] = {
0x7048, 0x080f, 0x0005, 0x00b6, 0x7007, 0x0001, 0xa974, 0xa878,
0x9084, 0x00ff, 0x9096, 0x0004, 0x0540, 0x20a9, 0x0001, 0x9096,
0x0001, 0x0190, 0x900e, 0x20a9, 0x0800, 0x9096, 0x0002, 0x0160,
- 0x9005, 0x11d8, 0xa974, 0x080c, 0x6789, 0x11b8, 0x0066, 0xae80,
- 0x080c, 0x6899, 0x006e, 0x0088, 0x0046, 0x2011, 0x180c, 0x2224,
- 0xc484, 0x2412, 0x004e, 0x00c6, 0x080c, 0x6789, 0x1110, 0x080c,
- 0x6a6c, 0x8108, 0x1f04, 0x7d34, 0x00ce, 0xa87c, 0xd084, 0x1120,
- 0x080c, 0x108b, 0x00be, 0x0005, 0x0126, 0x2091, 0x8000, 0x080c,
- 0x6f19, 0x012e, 0x00be, 0x0005, 0x0126, 0x2091, 0x8000, 0x7007,
- 0x0001, 0x080c, 0x6bd1, 0x0580, 0x2061, 0x1a74, 0x6100, 0xd184,
+ 0x9005, 0x11d8, 0xa974, 0x080c, 0x6783, 0x11b8, 0x0066, 0xae80,
+ 0x080c, 0x6893, 0x006e, 0x0088, 0x0046, 0x2011, 0x180c, 0x2224,
+ 0xc484, 0x2412, 0x004e, 0x00c6, 0x080c, 0x6783, 0x1110, 0x080c,
+ 0x6a64, 0x8108, 0x1f04, 0x7d2c, 0x00ce, 0xa87c, 0xd084, 0x1120,
+ 0x080c, 0x107f, 0x00be, 0x0005, 0x0126, 0x2091, 0x8000, 0x080c,
+ 0x6f11, 0x012e, 0x00be, 0x0005, 0x0126, 0x2091, 0x8000, 0x7007,
+ 0x0001, 0x080c, 0x6bc9, 0x0580, 0x2061, 0x1a74, 0x6100, 0xd184,
0x0178, 0xa888, 0x9084, 0x00ff, 0x1550, 0x6000, 0xd084, 0x0520,
0x6004, 0x9005, 0x1538, 0x6003, 0x0000, 0x600b, 0x0000, 0x00c8,
0x2011, 0x0001, 0xa890, 0x9005, 0x1110, 0x2001, 0x001e, 0x8000,
0x6016, 0xa888, 0x9084, 0x00ff, 0x0178, 0x6006, 0xa888, 0x8007,
0x9084, 0x00ff, 0x0148, 0x600a, 0xa888, 0x8000, 0x1108, 0xc28d,
- 0x6202, 0x012e, 0x0804, 0x7f8e, 0x012e, 0x0804, 0x7f88, 0x012e,
- 0x0804, 0x7f82, 0x012e, 0x0804, 0x7f85, 0x0126, 0x2091, 0x8000,
- 0x7007, 0x0001, 0x080c, 0x6bd1, 0x05e0, 0x2061, 0x1a74, 0x6000,
+ 0x6202, 0x012e, 0x0804, 0x7f86, 0x012e, 0x0804, 0x7f80, 0x012e,
+ 0x0804, 0x7f7a, 0x012e, 0x0804, 0x7f7d, 0x0126, 0x2091, 0x8000,
+ 0x7007, 0x0001, 0x080c, 0x6bc9, 0x05e0, 0x2061, 0x1a74, 0x6000,
0xd084, 0x05b8, 0x6204, 0x6308, 0xd08c, 0x1530, 0xac78, 0x9484,
0x0003, 0x0170, 0xa988, 0x918c, 0x00ff, 0x8001, 0x1120, 0x2100,
0x9210, 0x0620, 0x0028, 0x8001, 0x1508, 0x2100, 0x9212, 0x02f0,
0x9484, 0x000c, 0x0188, 0xa988, 0x810f, 0x918c, 0x00ff, 0x9082,
0x0004, 0x1120, 0x2100, 0x9318, 0x0288, 0x0030, 0x9082, 0x0004,
0x1168, 0x2100, 0x931a, 0x0250, 0xa890, 0x9005, 0x0110, 0x8000,
- 0x6016, 0x6206, 0x630a, 0x012e, 0x0804, 0x7f8e, 0x012e, 0x0804,
- 0x7f8b, 0x012e, 0x0804, 0x7f88, 0x0126, 0x2091, 0x8000, 0x7007,
+ 0x6016, 0x6206, 0x630a, 0x012e, 0x0804, 0x7f86, 0x012e, 0x0804,
+ 0x7f83, 0x012e, 0x0804, 0x7f80, 0x0126, 0x2091, 0x8000, 0x7007,
0x0001, 0x2061, 0x1a74, 0x6300, 0xd38c, 0x1120, 0x6308, 0x8318,
- 0x0220, 0x630a, 0x012e, 0x0804, 0x7f9c, 0x012e, 0x0804, 0x7f8b,
+ 0x0220, 0x630a, 0x012e, 0x0804, 0x7f94, 0x012e, 0x0804, 0x7f83,
0x00b6, 0x0126, 0x00c6, 0x2091, 0x8000, 0x7007, 0x0001, 0xa87c,
0xd0ac, 0x0148, 0x00c6, 0x2061, 0x1a74, 0x6000, 0x9084, 0xfcff,
0x6002, 0x00ce, 0x0440, 0xa888, 0x9005, 0x05d8, 0xa88c, 0x9065,
- 0x0598, 0x2001, 0x1834, 0x2004, 0x9005, 0x0118, 0x080c, 0xaf69,
+ 0x0598, 0x2001, 0x1834, 0x2004, 0x9005, 0x0118, 0x080c, 0xaf89,
0x0068, 0x6017, 0xf400, 0x6063, 0x0000, 0xa97c, 0xd1a4, 0x0110,
- 0xa980, 0x6162, 0x2009, 0x0041, 0x080c, 0xafcc, 0xa988, 0x918c,
+ 0xa980, 0x6162, 0x2009, 0x0041, 0x080c, 0xafec, 0xa988, 0x918c,
0xff00, 0x9186, 0x2000, 0x1138, 0x0026, 0x900e, 0x2011, 0xfdff,
- 0x080c, 0x8ae5, 0x002e, 0xa87c, 0xd0c4, 0x0148, 0x2061, 0x1a74,
+ 0x080c, 0x8add, 0x002e, 0xa87c, 0xd0c4, 0x0148, 0x2061, 0x1a74,
0x6000, 0xd08c, 0x1120, 0x6008, 0x8000, 0x0208, 0x600a, 0x00ce,
- 0x012e, 0x00be, 0x0804, 0x7f8e, 0x00ce, 0x012e, 0x00be, 0x0804,
- 0x7f88, 0xa984, 0x9186, 0x002e, 0x0d30, 0x9186, 0x002d, 0x0d18,
+ 0x012e, 0x00be, 0x0804, 0x7f86, 0x00ce, 0x012e, 0x00be, 0x0804,
+ 0x7f80, 0xa984, 0x9186, 0x002e, 0x0d30, 0x9186, 0x002d, 0x0d18,
0x9186, 0x0045, 0x0510, 0x9186, 0x002a, 0x1130, 0x2001, 0x180c,
0x200c, 0xc194, 0x2102, 0x08b8, 0x9186, 0x0020, 0x0158, 0x9186,
- 0x0029, 0x1d10, 0xa974, 0x080c, 0x6789, 0x1968, 0xb800, 0xc0e4,
+ 0x0029, 0x1d10, 0xa974, 0x080c, 0x6783, 0x1968, 0xb800, 0xc0e4,
0xb802, 0x0848, 0xa88c, 0x9065, 0x09b8, 0x6007, 0x0024, 0x2001,
- 0x1987, 0x2004, 0x601a, 0x0804, 0x7e23, 0xa88c, 0x9065, 0x0960,
+ 0x1987, 0x2004, 0x601a, 0x0804, 0x7e1b, 0xa88c, 0x9065, 0x0960,
0x00e6, 0xa890, 0x9075, 0x2001, 0x1834, 0x2004, 0x9005, 0x0150,
- 0x080c, 0xaf69, 0x8eff, 0x0118, 0x2e60, 0x080c, 0xaf69, 0x00ee,
- 0x0804, 0x7e23, 0x6024, 0xc0dc, 0xc0d5, 0x6026, 0x2e60, 0x6007,
+ 0x080c, 0xaf89, 0x8eff, 0x0118, 0x2e60, 0x080c, 0xaf89, 0x00ee,
+ 0x0804, 0x7e1b, 0x6024, 0xc0dc, 0xc0d5, 0x6026, 0x2e60, 0x6007,
0x003a, 0xa8a0, 0x9005, 0x0130, 0x6007, 0x003b, 0xa8a4, 0x602e,
- 0xa8a8, 0x6016, 0x6003, 0x0001, 0x2009, 0x8020, 0x080c, 0x9428,
- 0x00ee, 0x0804, 0x7e23, 0x2061, 0x1a74, 0x6000, 0xd084, 0x0190,
- 0xd08c, 0x1904, 0x7f9c, 0x0126, 0x2091, 0x8000, 0x6204, 0x8210,
- 0x0220, 0x6206, 0x012e, 0x0804, 0x7f9c, 0x012e, 0xa883, 0x0016,
- 0x0804, 0x7f95, 0xa883, 0x0007, 0x0804, 0x7f95, 0xa864, 0x8007,
+ 0xa8a8, 0x6016, 0x6003, 0x0001, 0x2009, 0x8020, 0x080c, 0x9420,
+ 0x00ee, 0x0804, 0x7e1b, 0x2061, 0x1a74, 0x6000, 0xd084, 0x0190,
+ 0xd08c, 0x1904, 0x7f94, 0x0126, 0x2091, 0x8000, 0x6204, 0x8210,
+ 0x0220, 0x6206, 0x012e, 0x0804, 0x7f94, 0x012e, 0xa883, 0x0016,
+ 0x0804, 0x7f8d, 0xa883, 0x0007, 0x0804, 0x7f8d, 0xa864, 0x8007,
0x9084, 0x00ff, 0x0130, 0x8001, 0x1138, 0x7007, 0x0001, 0x0069,
- 0x0005, 0x080c, 0x7b19, 0x0040, 0x7007, 0x0003, 0x7012, 0x2900,
- 0x7016, 0x701a, 0x704b, 0x7ec5, 0x0005, 0x00b6, 0x00e6, 0x0126,
+ 0x0005, 0x080c, 0x7b11, 0x0040, 0x7007, 0x0003, 0x7012, 0x2900,
+ 0x7016, 0x701a, 0x704b, 0x7ebd, 0x0005, 0x00b6, 0x00e6, 0x0126,
0x2091, 0x8000, 0x903e, 0x2061, 0x1800, 0x61d0, 0x81ff, 0x1904,
- 0x7f47, 0x6130, 0xd194, 0x1904, 0x7f71, 0xa878, 0x2070, 0x9e82,
- 0x1ddc, 0x0a04, 0x7f3b, 0x6068, 0x9e02, 0x1a04, 0x7f3b, 0x7120,
- 0x9186, 0x0006, 0x1904, 0x7f2d, 0x7010, 0x905d, 0x0904, 0x7f47,
- 0xb800, 0xd0e4, 0x1904, 0x7f6b, 0x2061, 0x1a74, 0x6100, 0x9184,
- 0x0301, 0x9086, 0x0001, 0x15a0, 0x7024, 0xd0dc, 0x1904, 0x7f74,
+ 0x7f3f, 0x6130, 0xd194, 0x1904, 0x7f69, 0xa878, 0x2070, 0x9e82,
+ 0x1ddc, 0x0a04, 0x7f33, 0x6068, 0x9e02, 0x1a04, 0x7f33, 0x7120,
+ 0x9186, 0x0006, 0x1904, 0x7f25, 0x7010, 0x905d, 0x0904, 0x7f3f,
+ 0xb800, 0xd0e4, 0x1904, 0x7f63, 0x2061, 0x1a74, 0x6100, 0x9184,
+ 0x0301, 0x9086, 0x0001, 0x15a0, 0x7024, 0xd0dc, 0x1904, 0x7f6c,
0xa883, 0x0000, 0xa803, 0x0000, 0x2908, 0x7014, 0x9005, 0x1198,
- 0x7116, 0xa87c, 0xd0f4, 0x1904, 0x7f77, 0x080c, 0x5826, 0xd09c,
- 0x1118, 0xa87c, 0xc0cc, 0xa87e, 0x2e60, 0x080c, 0x89d5, 0x012e,
+ 0x7116, 0xa87c, 0xd0f4, 0x1904, 0x7f6f, 0x080c, 0x5820, 0xd09c,
+ 0x1118, 0xa87c, 0xc0cc, 0xa87e, 0x2e60, 0x080c, 0x89cd, 0x012e,
0x00ee, 0x00be, 0x0005, 0x2048, 0xa800, 0x9005, 0x1de0, 0xa902,
- 0x2148, 0xa87c, 0xd0f4, 0x1904, 0x7f77, 0x012e, 0x00ee, 0x00be,
- 0x0005, 0x012e, 0x00ee, 0xa883, 0x0006, 0x00be, 0x0804, 0x7f95,
- 0xd184, 0x0db8, 0xd1c4, 0x1190, 0x00a0, 0xa974, 0x080c, 0x6789,
+ 0x2148, 0xa87c, 0xd0f4, 0x1904, 0x7f6f, 0x012e, 0x00ee, 0x00be,
+ 0x0005, 0x012e, 0x00ee, 0xa883, 0x0006, 0x00be, 0x0804, 0x7f8d,
+ 0xd184, 0x0db8, 0xd1c4, 0x1190, 0x00a0, 0xa974, 0x080c, 0x6783,
0x15d0, 0xb800, 0xd0e4, 0x15b8, 0x7120, 0x9186, 0x0007, 0x1118,
0xa883, 0x0002, 0x0490, 0xa883, 0x0008, 0x0478, 0xa883, 0x000e,
0x0460, 0xa883, 0x0017, 0x0448, 0xa883, 0x0035, 0x0430, 0x080c,
- 0x582a, 0xd0fc, 0x01e8, 0xa878, 0x2070, 0x9e82, 0x1ddc, 0x02c0,
+ 0x5824, 0xd0fc, 0x01e8, 0xa878, 0x2070, 0x9e82, 0x1ddc, 0x02c0,
0x6068, 0x9e02, 0x12a8, 0x7120, 0x9186, 0x0006, 0x1188, 0x7010,
0x905d, 0x0170, 0xb800, 0xd0bc, 0x0158, 0x2039, 0x0001, 0x7000,
- 0x9086, 0x0007, 0x1904, 0x7ed1, 0x7003, 0x0002, 0x0804, 0x7ed1,
+ 0x9086, 0x0007, 0x1904, 0x7ec9, 0x7003, 0x0002, 0x0804, 0x7ec9,
0xa883, 0x0028, 0x0010, 0xa883, 0x0029, 0x012e, 0x00ee, 0x00be,
0x0420, 0xa883, 0x002a, 0x0cc8, 0xa883, 0x0045, 0x0cb0, 0x2e60,
- 0x2019, 0x0002, 0x601b, 0x0014, 0x080c, 0xe27a, 0x012e, 0x00ee,
+ 0x2019, 0x0002, 0x601b, 0x0014, 0x080c, 0xe28e, 0x012e, 0x00ee,
0x00be, 0x0005, 0x2009, 0x003e, 0x0058, 0x2009, 0x0004, 0x0040,
0x2009, 0x0006, 0x0028, 0x2009, 0x0016, 0x0010, 0x2009, 0x0001,
0xa884, 0x9084, 0xff00, 0x9105, 0xa886, 0x0126, 0x2091, 0x8000,
- 0x080c, 0x6f19, 0x012e, 0x0005, 0x080c, 0x108b, 0x0005, 0x00d6,
- 0x080c, 0x89cc, 0x00de, 0x0005, 0x00d6, 0x00e6, 0x0126, 0x2091,
+ 0x080c, 0x6f11, 0x012e, 0x0005, 0x080c, 0x107f, 0x0005, 0x00d6,
+ 0x080c, 0x89c4, 0x00de, 0x0005, 0x00d6, 0x00e6, 0x0126, 0x2091,
0x8000, 0x2071, 0x0040, 0x702c, 0xd084, 0x01d8, 0x908c, 0x0780,
- 0x190c, 0x8086, 0xd09c, 0x11a8, 0x2071, 0x1800, 0x70c0, 0x90ea,
+ 0x190c, 0x807e, 0xd09c, 0x11a8, 0x2071, 0x1800, 0x70c0, 0x90ea,
0x0020, 0x0278, 0x8001, 0x70c2, 0x702c, 0x2048, 0xa800, 0x702e,
0x9006, 0xa802, 0xa806, 0x2071, 0x0040, 0x2900, 0x7022, 0x702c,
0x0c28, 0x012e, 0x00ee, 0x00de, 0x0005, 0x0006, 0x9084, 0x0780,
- 0x190c, 0x8086, 0x000e, 0x0005, 0xa898, 0x9084, 0x0003, 0x05a8,
- 0x080c, 0xaed8, 0x05d8, 0x2900, 0x6016, 0xa864, 0x9084, 0x00ff,
+ 0x190c, 0x807e, 0x000e, 0x0005, 0xa898, 0x9084, 0x0003, 0x05a8,
+ 0x080c, 0xaef8, 0x05d8, 0x2900, 0x6016, 0xa864, 0x9084, 0x00ff,
0x9086, 0x0035, 0x1138, 0x6028, 0xc0fd, 0x602a, 0x2001, 0x196c,
0x2004, 0x0098, 0xa8a0, 0x9084, 0x00ff, 0xa99c, 0x918c, 0xff00,
- 0x9105, 0xa99c, 0x918c, 0x00ff, 0x080c, 0x26a2, 0x1540, 0x00b6,
- 0x080c, 0x6789, 0x2b00, 0x00be, 0x1510, 0x6012, 0x6023, 0x0001,
+ 0x9105, 0xa99c, 0x918c, 0x00ff, 0x080c, 0x26a1, 0x1540, 0x00b6,
+ 0x080c, 0x6783, 0x2b00, 0x00be, 0x1510, 0x6012, 0x6023, 0x0001,
0x2009, 0x0040, 0xa864, 0x9084, 0x00ff, 0x9086, 0x0035, 0x0110,
- 0x2009, 0x0041, 0x080c, 0xafcc, 0x0005, 0xa87b, 0x0101, 0x0126,
- 0x2091, 0x8000, 0x080c, 0x6f19, 0x012e, 0x0005, 0xa87b, 0x002c,
- 0x0126, 0x2091, 0x8000, 0x080c, 0x6f19, 0x012e, 0x0005, 0xa87b,
- 0x0028, 0x0126, 0x2091, 0x8000, 0x080c, 0x6f19, 0x012e, 0x080c,
- 0xaf2e, 0x0005, 0x00d6, 0x00c6, 0x0036, 0x0026, 0x0016, 0x00b6,
- 0x7007, 0x0001, 0xaa74, 0x9282, 0x0004, 0x1a04, 0x8077, 0xa97c,
+ 0x2009, 0x0041, 0x080c, 0xafec, 0x0005, 0xa87b, 0x0101, 0x0126,
+ 0x2091, 0x8000, 0x080c, 0x6f11, 0x012e, 0x0005, 0xa87b, 0x002c,
+ 0x0126, 0x2091, 0x8000, 0x080c, 0x6f11, 0x012e, 0x0005, 0xa87b,
+ 0x0028, 0x0126, 0x2091, 0x8000, 0x080c, 0x6f11, 0x012e, 0x080c,
+ 0xaf4e, 0x0005, 0x00d6, 0x00c6, 0x0036, 0x0026, 0x0016, 0x00b6,
+ 0x7007, 0x0001, 0xaa74, 0x9282, 0x0004, 0x1a04, 0x806f, 0xa97c,
0x9188, 0x1000, 0x2104, 0x905d, 0xb804, 0xd284, 0x0140, 0x05e8,
0x8007, 0x9084, 0x00ff, 0x9084, 0x0006, 0x1108, 0x04b0, 0x2b10,
- 0x080c, 0xaed8, 0x1118, 0x080c, 0xaf9f, 0x05a8, 0x6212, 0xa874,
- 0x0002, 0x8055, 0x805a, 0x805d, 0x8063, 0x2019, 0x0002, 0x080c,
- 0xe696, 0x0060, 0x080c, 0xe621, 0x0048, 0x2019, 0x0002, 0xa980,
- 0x080c, 0xe640, 0x0018, 0xa980, 0x080c, 0xe621, 0x080c, 0xaf2e,
- 0xa887, 0x0000, 0x0126, 0x2091, 0x8000, 0x080c, 0x6f19, 0x012e,
+ 0x080c, 0xaef8, 0x1118, 0x080c, 0xafbf, 0x05a8, 0x6212, 0xa874,
+ 0x0002, 0x804d, 0x8052, 0x8055, 0x805b, 0x2019, 0x0002, 0x080c,
+ 0xe701, 0x0060, 0x080c, 0xe68c, 0x0048, 0x2019, 0x0002, 0xa980,
+ 0x080c, 0xe6ab, 0x0018, 0xa980, 0x080c, 0xe68c, 0x080c, 0xaf4e,
+ 0xa887, 0x0000, 0x0126, 0x2091, 0x8000, 0x080c, 0x6f11, 0x012e,
0x00be, 0x001e, 0x002e, 0x003e, 0x00ce, 0x00de, 0x0005, 0xa887,
0x0006, 0x0c80, 0xa887, 0x0002, 0x0c68, 0xa887, 0x0005, 0x0c50,
0xa887, 0x0004, 0x0c38, 0xa887, 0x0007, 0x0c20, 0x2091, 0x8000,
- 0x0e04, 0x8088, 0x0006, 0x0016, 0x2001, 0x8003, 0x0006, 0x0804,
- 0x0d8e, 0x2001, 0x1834, 0x2004, 0x9005, 0x0005, 0x0005, 0x00f6,
+ 0x0e04, 0x8080, 0x0006, 0x0016, 0x2001, 0x8003, 0x0006, 0x0804,
+ 0x0d82, 0x2001, 0x1834, 0x2004, 0x9005, 0x0005, 0x0005, 0x00f6,
0x2079, 0x0300, 0x2001, 0x0200, 0x200c, 0xc1e5, 0xc1dc, 0x2102,
- 0x2009, 0x0218, 0x210c, 0xd1ec, 0x1120, 0x080c, 0x1648, 0x00fe,
+ 0x2009, 0x0218, 0x210c, 0xd1ec, 0x1120, 0x080c, 0x163c, 0x00fe,
0x0005, 0x2001, 0x020d, 0x2003, 0x0020, 0x781f, 0x0300, 0x00fe,
- 0x0005, 0x781c, 0xd08c, 0x0904, 0x8109, 0x68c0, 0x90aa, 0x0005,
- 0x0a04, 0x8731, 0x7d44, 0x7c40, 0xd59c, 0x190c, 0x0d85, 0x9584,
+ 0x0005, 0x781c, 0xd08c, 0x0904, 0x8101, 0x68c0, 0x90aa, 0x0005,
+ 0x0a04, 0x8729, 0x7d44, 0x7c40, 0xd59c, 0x190c, 0x0d79, 0x9584,
0x00f6, 0x1508, 0x9484, 0x7000, 0x0138, 0x908a, 0x2000, 0x1258,
0x9584, 0x0700, 0x8007, 0x04f0, 0x7000, 0x9084, 0xff00, 0x9086,
0x8100, 0x0db0, 0x00b0, 0x9484, 0x0fff, 0x1130, 0x7000, 0x9084,
- 0xff00, 0x9086, 0x8100, 0x11c0, 0x080c, 0xeb55, 0x080c, 0x8618,
- 0x7817, 0x0140, 0x00a8, 0x9584, 0x0076, 0x1118, 0x080c, 0x8674,
- 0x19c8, 0xd5a4, 0x0148, 0x0046, 0x0056, 0x080c, 0x8159, 0x080c,
- 0x21a6, 0x005e, 0x004e, 0x0020, 0x080c, 0xeb55, 0x7817, 0x0140,
- 0x080c, 0x76a5, 0x0168, 0x2001, 0x0111, 0x2004, 0xd08c, 0x0140,
+ 0xff00, 0x9086, 0x8100, 0x11c0, 0x080c, 0xebc0, 0x080c, 0x8610,
+ 0x7817, 0x0140, 0x00a8, 0x9584, 0x0076, 0x1118, 0x080c, 0x866c,
+ 0x19c8, 0xd5a4, 0x0148, 0x0046, 0x0056, 0x080c, 0x8151, 0x080c,
+ 0x21a2, 0x005e, 0x004e, 0x0020, 0x080c, 0xebc0, 0x7817, 0x0140,
+ 0x080c, 0x769d, 0x0168, 0x2001, 0x0111, 0x2004, 0xd08c, 0x0140,
0x6893, 0x0000, 0x2001, 0x0110, 0x2003, 0x0008, 0x2003, 0x0000,
- 0x0489, 0x0005, 0x0002, 0x8116, 0x8426, 0x8113, 0x8113, 0x8113,
- 0x8113, 0x8113, 0x8113, 0x7817, 0x0140, 0x0005, 0x7000, 0x908c,
+ 0x0489, 0x0005, 0x0002, 0x810e, 0x841e, 0x810b, 0x810b, 0x810b,
+ 0x810b, 0x810b, 0x810b, 0x7817, 0x0140, 0x0005, 0x7000, 0x908c,
0xff00, 0x9194, 0xf000, 0x810f, 0x9484, 0x0fff, 0x6892, 0x9286,
- 0x2000, 0x1150, 0x6800, 0x9086, 0x0001, 0x1118, 0x080c, 0x5890,
- 0x0070, 0x080c, 0x8179, 0x0058, 0x9286, 0x3000, 0x1118, 0x080c,
- 0x8360, 0x0028, 0x9286, 0x8000, 0x1110, 0x080c, 0x8545, 0x7817,
+ 0x2000, 0x1150, 0x6800, 0x9086, 0x0001, 0x1118, 0x080c, 0x588a,
+ 0x0070, 0x080c, 0x8171, 0x0058, 0x9286, 0x3000, 0x1118, 0x080c,
+ 0x8358, 0x0028, 0x9286, 0x8000, 0x1110, 0x080c, 0x853d, 0x7817,
0x0140, 0x0005, 0x2001, 0x1810, 0x2004, 0xd08c, 0x0178, 0x2001,
0x1800, 0x2004, 0x9086, 0x0003, 0x1148, 0x0026, 0x0036, 0x2011,
- 0x8048, 0x2518, 0x080c, 0x4c2e, 0x003e, 0x002e, 0x0005, 0x0036,
+ 0x8048, 0x2518, 0x080c, 0x4c28, 0x003e, 0x002e, 0x0005, 0x0036,
0x0046, 0x0056, 0x00f6, 0x2079, 0x0200, 0x2019, 0xfffe, 0x7c30,
0x0050, 0x0036, 0x0046, 0x0056, 0x00f6, 0x2079, 0x0200, 0x7d44,
0x7c40, 0x2019, 0xffff, 0x2001, 0x1810, 0x2004, 0xd08c, 0x0160,
0x2001, 0x1800, 0x2004, 0x9086, 0x0003, 0x1130, 0x0026, 0x2011,
- 0x8048, 0x080c, 0x4c2e, 0x002e, 0x00fe, 0x005e, 0x004e, 0x003e,
+ 0x8048, 0x080c, 0x4c28, 0x002e, 0x00fe, 0x005e, 0x004e, 0x003e,
0x0005, 0x00b6, 0x00c6, 0x7010, 0x9084, 0xff00, 0x8007, 0x9096,
- 0x0001, 0x0120, 0x9096, 0x0023, 0x1904, 0x8331, 0x9186, 0x0023,
- 0x15c0, 0x080c, 0x85e3, 0x0904, 0x8331, 0x6120, 0x9186, 0x0001,
+ 0x0001, 0x0120, 0x9096, 0x0023, 0x1904, 0x8329, 0x9186, 0x0023,
+ 0x15c0, 0x080c, 0x85db, 0x0904, 0x8329, 0x6120, 0x9186, 0x0001,
0x0150, 0x9186, 0x0004, 0x0138, 0x9186, 0x0008, 0x0120, 0x9186,
- 0x000a, 0x1904, 0x8331, 0x7124, 0x610a, 0x7030, 0x908e, 0x0200,
- 0x1130, 0x2009, 0x0015, 0x080c, 0xafcc, 0x0804, 0x8331, 0x908e,
+ 0x000a, 0x1904, 0x8329, 0x7124, 0x610a, 0x7030, 0x908e, 0x0200,
+ 0x1130, 0x2009, 0x0015, 0x080c, 0xafec, 0x0804, 0x8329, 0x908e,
0x0214, 0x0118, 0x908e, 0x0210, 0x1130, 0x2009, 0x0015, 0x080c,
- 0xafcc, 0x0804, 0x8331, 0x908e, 0x0100, 0x1904, 0x8331, 0x7034,
- 0x9005, 0x1904, 0x8331, 0x2009, 0x0016, 0x080c, 0xafcc, 0x0804,
- 0x8331, 0x9186, 0x0022, 0x1904, 0x8331, 0x7030, 0x908e, 0x0300,
+ 0xafec, 0x0804, 0x8329, 0x908e, 0x0100, 0x1904, 0x8329, 0x7034,
+ 0x9005, 0x1904, 0x8329, 0x2009, 0x0016, 0x080c, 0xafec, 0x0804,
+ 0x8329, 0x9186, 0x0022, 0x1904, 0x8329, 0x7030, 0x908e, 0x0300,
0x1580, 0x68dc, 0xd0a4, 0x0528, 0xc0b5, 0x68de, 0x7100, 0x918c,
0x00ff, 0x697e, 0x7004, 0x6882, 0x00f6, 0x2079, 0x0100, 0x79e6,
- 0x78ea, 0x0006, 0x9084, 0x00ff, 0x0016, 0x2008, 0x080c, 0x26eb,
- 0x7932, 0x7936, 0x001e, 0x000e, 0x00fe, 0x080c, 0x26a2, 0x695e,
+ 0x78ea, 0x0006, 0x9084, 0x00ff, 0x0016, 0x2008, 0x080c, 0x26ea,
+ 0x7932, 0x7936, 0x001e, 0x000e, 0x00fe, 0x080c, 0x26a1, 0x695e,
0x703c, 0x00e6, 0x2071, 0x0140, 0x7086, 0x2071, 0x1800, 0x70b6,
- 0x00ee, 0x7034, 0x9005, 0x1904, 0x8331, 0x2009, 0x0017, 0x0804,
- 0x82e1, 0x908e, 0x0400, 0x1190, 0x7034, 0x9005, 0x1904, 0x8331,
- 0x080c, 0x76a5, 0x0120, 0x2009, 0x001d, 0x0804, 0x82e1, 0x68dc,
- 0xc0a5, 0x68de, 0x2009, 0x0030, 0x0804, 0x82e1, 0x908e, 0x0500,
- 0x1140, 0x7034, 0x9005, 0x1904, 0x8331, 0x2009, 0x0018, 0x0804,
- 0x82e1, 0x908e, 0x2010, 0x1120, 0x2009, 0x0019, 0x0804, 0x82e1,
- 0x908e, 0x2110, 0x1120, 0x2009, 0x001a, 0x0804, 0x82e1, 0x908e,
- 0x5200, 0x1140, 0x7034, 0x9005, 0x1904, 0x8331, 0x2009, 0x001b,
- 0x0804, 0x82e1, 0x908e, 0x5000, 0x1140, 0x7034, 0x9005, 0x1904,
- 0x8331, 0x2009, 0x001c, 0x0804, 0x82e1, 0x908e, 0x1300, 0x1120,
- 0x2009, 0x0034, 0x0804, 0x82e1, 0x908e, 0x1200, 0x1140, 0x7034,
- 0x9005, 0x1904, 0x8331, 0x2009, 0x0024, 0x0804, 0x82e1, 0x908c,
+ 0x00ee, 0x7034, 0x9005, 0x1904, 0x8329, 0x2009, 0x0017, 0x0804,
+ 0x82d9, 0x908e, 0x0400, 0x1190, 0x7034, 0x9005, 0x1904, 0x8329,
+ 0x080c, 0x769d, 0x0120, 0x2009, 0x001d, 0x0804, 0x82d9, 0x68dc,
+ 0xc0a5, 0x68de, 0x2009, 0x0030, 0x0804, 0x82d9, 0x908e, 0x0500,
+ 0x1140, 0x7034, 0x9005, 0x1904, 0x8329, 0x2009, 0x0018, 0x0804,
+ 0x82d9, 0x908e, 0x2010, 0x1120, 0x2009, 0x0019, 0x0804, 0x82d9,
+ 0x908e, 0x2110, 0x1120, 0x2009, 0x001a, 0x0804, 0x82d9, 0x908e,
+ 0x5200, 0x1140, 0x7034, 0x9005, 0x1904, 0x8329, 0x2009, 0x001b,
+ 0x0804, 0x82d9, 0x908e, 0x5000, 0x1140, 0x7034, 0x9005, 0x1904,
+ 0x8329, 0x2009, 0x001c, 0x0804, 0x82d9, 0x908e, 0x1300, 0x1120,
+ 0x2009, 0x0034, 0x0804, 0x82d9, 0x908e, 0x1200, 0x1140, 0x7034,
+ 0x9005, 0x1904, 0x8329, 0x2009, 0x0024, 0x0804, 0x82d9, 0x908c,
0xff00, 0x918e, 0x2400, 0x1170, 0x2009, 0x002d, 0x2001, 0x1810,
- 0x2004, 0xd09c, 0x0904, 0x82e1, 0x080c, 0xda84, 0x1904, 0x8331,
- 0x0804, 0x82df, 0x908c, 0xff00, 0x918e, 0x5300, 0x1120, 0x2009,
- 0x002a, 0x0804, 0x82e1, 0x908e, 0x0f00, 0x1120, 0x2009, 0x0020,
- 0x0804, 0x82e1, 0x908e, 0x6104, 0x1530, 0x2029, 0x0205, 0x2011,
+ 0x2004, 0xd09c, 0x0904, 0x82d9, 0x080c, 0xdaa3, 0x1904, 0x8329,
+ 0x0804, 0x82d7, 0x908c, 0xff00, 0x918e, 0x5300, 0x1120, 0x2009,
+ 0x002a, 0x0804, 0x82d9, 0x908e, 0x0f00, 0x1120, 0x2009, 0x0020,
+ 0x0804, 0x82d9, 0x908e, 0x6104, 0x1530, 0x2029, 0x0205, 0x2011,
0x026d, 0x8208, 0x2204, 0x9082, 0x0004, 0x8004, 0x8004, 0x20a8,
- 0x2011, 0x8015, 0x211c, 0x8108, 0x0046, 0x2124, 0x080c, 0x4c2e,
- 0x004e, 0x8108, 0x0f04, 0x8295, 0x9186, 0x0280, 0x1d88, 0x2504,
+ 0x2011, 0x8015, 0x211c, 0x8108, 0x0046, 0x2124, 0x080c, 0x4c28,
+ 0x004e, 0x8108, 0x0f04, 0x828d, 0x9186, 0x0280, 0x1d88, 0x2504,
0x8000, 0x202a, 0x2009, 0x0260, 0x0c58, 0x202b, 0x0000, 0x2009,
- 0x0023, 0x0804, 0x82e1, 0x908e, 0x6000, 0x1120, 0x2009, 0x003f,
- 0x0804, 0x82e1, 0x908e, 0x5400, 0x1138, 0x080c, 0x86e1, 0x1904,
- 0x8331, 0x2009, 0x0046, 0x04a8, 0x908e, 0x5500, 0x1148, 0x080c,
- 0x8709, 0x1118, 0x2009, 0x0041, 0x0460, 0x2009, 0x0042, 0x0448,
+ 0x0023, 0x0804, 0x82d9, 0x908e, 0x6000, 0x1120, 0x2009, 0x003f,
+ 0x0804, 0x82d9, 0x908e, 0x5400, 0x1138, 0x080c, 0x86d9, 0x1904,
+ 0x8329, 0x2009, 0x0046, 0x04a8, 0x908e, 0x5500, 0x1148, 0x080c,
+ 0x8701, 0x1118, 0x2009, 0x0041, 0x0460, 0x2009, 0x0042, 0x0448,
0x908e, 0x7800, 0x1118, 0x2009, 0x0045, 0x0418, 0x908e, 0x1000,
0x1118, 0x2009, 0x004e, 0x00e8, 0x908e, 0x6300, 0x1118, 0x2009,
0x004a, 0x00b8, 0x908c, 0xff00, 0x918e, 0x5600, 0x1118, 0x2009,
0x004f, 0x0078, 0x908c, 0xff00, 0x918e, 0x5700, 0x1118, 0x2009,
0x0050, 0x0038, 0x2009, 0x001d, 0x6838, 0xd0d4, 0x0110, 0x2009,
0x004c, 0x0016, 0x2011, 0x0263, 0x2204, 0x8211, 0x220c, 0x080c,
- 0x26a2, 0x1904, 0x8334, 0x080c, 0x671e, 0x1904, 0x8334, 0xbe12,
- 0xbd16, 0x001e, 0x0016, 0x080c, 0x76a5, 0x01c0, 0x68dc, 0xd08c,
+ 0x26a1, 0x1904, 0x832c, 0x080c, 0x6718, 0x1904, 0x832c, 0xbe12,
+ 0xbd16, 0x001e, 0x0016, 0x080c, 0x769d, 0x01c0, 0x68dc, 0xd08c,
0x1148, 0x7000, 0x9084, 0x00ff, 0x1188, 0x7004, 0x9084, 0xff00,
0x1168, 0x0040, 0x687c, 0x9606, 0x1148, 0x6880, 0x9506, 0x9084,
0xff00, 0x1120, 0x9584, 0x00ff, 0xb886, 0x0080, 0xb884, 0x9005,
0x1168, 0x9186, 0x0046, 0x1150, 0x687c, 0x9606, 0x1138, 0x6880,
- 0x9506, 0x9084, 0xff00, 0x1110, 0x001e, 0x0098, 0x080c, 0xaed8,
+ 0x9506, 0x9084, 0xff00, 0x1110, 0x001e, 0x0098, 0x080c, 0xaef8,
0x01a8, 0x2b08, 0x6112, 0x6023, 0x0004, 0x7120, 0x610a, 0x001e,
0x9186, 0x004c, 0x1110, 0x6023, 0x000a, 0x0016, 0x001e, 0x080c,
- 0xafcc, 0x00ce, 0x00be, 0x0005, 0x001e, 0x0cd8, 0x2001, 0x180e,
- 0x2004, 0xd0ec, 0x0120, 0x2011, 0x8049, 0x080c, 0x4c2e, 0x080c,
- 0xaf9f, 0x0d90, 0x2b08, 0x6112, 0x6023, 0x0004, 0x7120, 0x610a,
+ 0xafec, 0x00ce, 0x00be, 0x0005, 0x001e, 0x0cd8, 0x2001, 0x180e,
+ 0x2004, 0xd0ec, 0x0120, 0x2011, 0x8049, 0x080c, 0x4c28, 0x080c,
+ 0xafbf, 0x0d90, 0x2b08, 0x6112, 0x6023, 0x0004, 0x7120, 0x610a,
0x001e, 0x0016, 0x9186, 0x0017, 0x0118, 0x9186, 0x0030, 0x1128,
0x6007, 0x0009, 0x6017, 0x2900, 0x0020, 0x6007, 0x0051, 0x6017,
- 0x0000, 0x602f, 0x0009, 0x6003, 0x0001, 0x080c, 0x942f, 0x08a0,
- 0x080c, 0x8750, 0x1158, 0x080c, 0x3447, 0x1140, 0x7010, 0x9084,
+ 0x0000, 0x602f, 0x0009, 0x6003, 0x0001, 0x080c, 0x9427, 0x08a0,
+ 0x080c, 0x8748, 0x1158, 0x080c, 0x3432, 0x1140, 0x7010, 0x9084,
0xff00, 0x8007, 0x908e, 0x0008, 0x1108, 0x0009, 0x0005, 0x00b6,
0x00c6, 0x0046, 0x7000, 0x908c, 0xff00, 0x810f, 0x9186, 0x0033,
- 0x11e8, 0x080c, 0x85e3, 0x0904, 0x83be, 0x7124, 0x610a, 0x7030,
+ 0x11e8, 0x080c, 0x85db, 0x0904, 0x83b6, 0x7124, 0x610a, 0x7030,
0x908e, 0x0200, 0x1140, 0x7034, 0x9005, 0x15c0, 0x2009, 0x0015,
- 0x080c, 0xafcc, 0x0498, 0x908e, 0x0100, 0x1580, 0x7034, 0x9005,
- 0x1568, 0x2009, 0x0016, 0x080c, 0xafcc, 0x0440, 0x9186, 0x0032,
+ 0x080c, 0xafec, 0x0498, 0x908e, 0x0100, 0x1580, 0x7034, 0x9005,
+ 0x1568, 0x2009, 0x0016, 0x080c, 0xafec, 0x0440, 0x9186, 0x0032,
0x1528, 0x7030, 0x908e, 0x1400, 0x1508, 0x2009, 0x0038, 0x0016,
- 0x2011, 0x0263, 0x2204, 0x8211, 0x220c, 0x080c, 0x26a2, 0x11a8,
- 0x080c, 0x671e, 0x1190, 0xbe12, 0xbd16, 0x080c, 0xaed8, 0x0168,
- 0x2b08, 0x6112, 0x080c, 0xd0b1, 0x6023, 0x0004, 0x7120, 0x610a,
- 0x001e, 0x080c, 0xafcc, 0x0010, 0x00ce, 0x001e, 0x004e, 0x00ce,
+ 0x2011, 0x0263, 0x2204, 0x8211, 0x220c, 0x080c, 0x26a1, 0x11a8,
+ 0x080c, 0x6718, 0x1190, 0xbe12, 0xbd16, 0x080c, 0xaef8, 0x0168,
+ 0x2b08, 0x6112, 0x080c, 0xd0ce, 0x6023, 0x0004, 0x7120, 0x610a,
+ 0x001e, 0x080c, 0xafec, 0x0010, 0x00ce, 0x001e, 0x004e, 0x00ce,
0x00be, 0x0005, 0x00b6, 0x0046, 0x00e6, 0x00d6, 0x2028, 0x2130,
0x9696, 0x00ff, 0x11b8, 0x9592, 0xfffc, 0x02a0, 0x9596, 0xfffd,
- 0x1120, 0x2009, 0x007f, 0x0804, 0x8420, 0x9596, 0xfffe, 0x1120,
- 0x2009, 0x007e, 0x0804, 0x8420, 0x9596, 0xfffc, 0x1118, 0x2009,
+ 0x1120, 0x2009, 0x007f, 0x0804, 0x8418, 0x9596, 0xfffe, 0x1120,
+ 0x2009, 0x007e, 0x0804, 0x8418, 0x9596, 0xfffc, 0x1118, 0x2009,
0x0080, 0x04f0, 0x2011, 0x0000, 0x2019, 0x1837, 0x231c, 0xd3ac,
0x0130, 0x9026, 0x20a9, 0x0800, 0x2071, 0x1000, 0x0030, 0x2021,
0x0081, 0x20a9, 0x077f, 0x2071, 0x1081, 0x2e1c, 0x93dd, 0x0000,
@@ -4021,34 +4008,34 @@ unsigned short risc_code01[] = {
0x00a0, 0xbf10, 0x2600, 0x9706, 0xb814, 0x1120, 0x9546, 0x1110,
0x2408, 0x00b0, 0x9745, 0x1148, 0x94c6, 0x007e, 0x0130, 0x94c6,
0x007f, 0x0118, 0x94c6, 0x0080, 0x1d20, 0x8420, 0x8e70, 0x1f04,
- 0x83f5, 0x82ff, 0x1118, 0x9085, 0x0001, 0x0018, 0xc2fc, 0x2208,
+ 0x83ed, 0x82ff, 0x1118, 0x9085, 0x0001, 0x0018, 0xc2fc, 0x2208,
0x9006, 0x00de, 0x00ee, 0x004e, 0x00be, 0x0005, 0x2001, 0x1837,
0x200c, 0x9184, 0x0080, 0x0110, 0xd18c, 0x0138, 0x7000, 0x908c,
0xff00, 0x810f, 0x9184, 0x000f, 0x001a, 0x7817, 0x0140, 0x0005,
- 0x8448, 0x8448, 0x8448, 0x85f5, 0x8448, 0x844b, 0x8470, 0x84f9,
- 0x8448, 0x8448, 0x8448, 0x8448, 0x8448, 0x8448, 0x8448, 0x8448,
+ 0x8440, 0x8440, 0x8440, 0x85ed, 0x8440, 0x8443, 0x8468, 0x84f1,
+ 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440,
0x7817, 0x0140, 0x0005, 0x00b6, 0x7110, 0xd1bc, 0x01e8, 0x7120,
0x2160, 0x9c8c, 0x0003, 0x11c0, 0x9c8a, 0x1ddc, 0x02a8, 0x6868,
0x9c02, 0x1290, 0x7008, 0x9084, 0x00ff, 0x6110, 0x2158, 0xb910,
0x9106, 0x1150, 0x700c, 0xb914, 0x9106, 0x1130, 0x7124, 0x610a,
- 0x2009, 0x0046, 0x080c, 0xafcc, 0x7817, 0x0140, 0x00be, 0x0005,
- 0x00b6, 0x00c6, 0x9484, 0x0fff, 0x0904, 0x84d5, 0x7110, 0xd1bc,
- 0x1904, 0x84d5, 0x7108, 0x700c, 0x2028, 0x918c, 0x00ff, 0x2130,
- 0x9094, 0xff00, 0x15c8, 0x81ff, 0x15b8, 0x9080, 0x3489, 0x200d,
- 0x918c, 0xff00, 0x810f, 0x2001, 0x0080, 0x9106, 0x0904, 0x84d5,
- 0x9182, 0x0801, 0x1a04, 0x84d5, 0x9190, 0x1000, 0x2204, 0x905d,
+ 0x2009, 0x0046, 0x080c, 0xafec, 0x7817, 0x0140, 0x00be, 0x0005,
+ 0x00b6, 0x00c6, 0x9484, 0x0fff, 0x0904, 0x84cd, 0x7110, 0xd1bc,
+ 0x1904, 0x84cd, 0x7108, 0x700c, 0x2028, 0x918c, 0x00ff, 0x2130,
+ 0x9094, 0xff00, 0x15c8, 0x81ff, 0x15b8, 0x9080, 0x3474, 0x200d,
+ 0x918c, 0xff00, 0x810f, 0x2001, 0x0080, 0x9106, 0x0904, 0x84cd,
+ 0x9182, 0x0801, 0x1a04, 0x84cd, 0x9190, 0x1000, 0x2204, 0x905d,
0x05e0, 0xbe12, 0xbd16, 0xb800, 0xd0ec, 0x15b8, 0xba04, 0x9294,
- 0xff00, 0x9286, 0x0600, 0x1190, 0x080c, 0xaed8, 0x0598, 0x2b08,
+ 0xff00, 0x9286, 0x0600, 0x1190, 0x080c, 0xaef8, 0x0598, 0x2b08,
0x7028, 0x604e, 0x702c, 0x6052, 0x6112, 0x6023, 0x0006, 0x7120,
- 0x610a, 0x7130, 0x615e, 0x080c, 0xdd0b, 0x00f8, 0x080c, 0x6bd5,
- 0x1138, 0xb807, 0x0606, 0x0c40, 0x190c, 0x83c2, 0x11b0, 0x0880,
- 0x080c, 0xaed8, 0x2b08, 0x0188, 0x6112, 0x6023, 0x0004, 0x7120,
+ 0x610a, 0x7130, 0x615e, 0x080c, 0xdd1f, 0x00f8, 0x080c, 0x6bcd,
+ 0x1138, 0xb807, 0x0606, 0x0c40, 0x190c, 0x83ba, 0x11b0, 0x0880,
+ 0x080c, 0xaef8, 0x2b08, 0x0188, 0x6112, 0x6023, 0x0004, 0x7120,
0x610a, 0x9286, 0x0400, 0x1118, 0x6007, 0x0005, 0x0010, 0x6007,
- 0x0001, 0x6003, 0x0001, 0x080c, 0x942f, 0x7817, 0x0140, 0x00ce,
+ 0x0001, 0x6003, 0x0001, 0x080c, 0x9427, 0x7817, 0x0140, 0x00ce,
0x00be, 0x0005, 0x2001, 0x180e, 0x2004, 0xd0ec, 0x0120, 0x2011,
- 0x8049, 0x080c, 0x4c2e, 0x080c, 0xaf9f, 0x0d78, 0x2b08, 0x6112,
+ 0x8049, 0x080c, 0x4c28, 0x080c, 0xafbf, 0x0d78, 0x2b08, 0x6112,
0x6023, 0x0006, 0x7120, 0x610a, 0x7130, 0x615e, 0x6017, 0xf300,
- 0x6003, 0x0001, 0x6007, 0x0041, 0x2009, 0xa022, 0x080c, 0x9428,
+ 0x6003, 0x0001, 0x6007, 0x0041, 0x2009, 0xa022, 0x080c, 0x9420,
0x08e0, 0x00b6, 0x7110, 0xd1bc, 0x05d0, 0x7020, 0x2060, 0x9c84,
0x0003, 0x15a8, 0x9c82, 0x1ddc, 0x0690, 0x6868, 0x9c02, 0x1678,
0x9484, 0x0fff, 0x9082, 0x000c, 0x0650, 0x7008, 0x9084, 0x00ff,
@@ -4056,69 +4043,69 @@ unsigned short risc_code01[] = {
0x11f0, 0x7124, 0x610a, 0x601c, 0xd0fc, 0x11c8, 0x2001, 0x0271,
0x2004, 0x9005, 0x1180, 0x9484, 0x0fff, 0x9082, 0x000c, 0x0158,
0x0066, 0x2031, 0x0100, 0xa001, 0xa001, 0x8631, 0x1de0, 0x006e,
- 0x601c, 0xd0fc, 0x1120, 0x2009, 0x0045, 0x080c, 0xafcc, 0x7817,
+ 0x601c, 0xd0fc, 0x1120, 0x2009, 0x0045, 0x080c, 0xafec, 0x7817,
0x0140, 0x00be, 0x0005, 0x6120, 0x9186, 0x0002, 0x0128, 0x9186,
- 0x0005, 0x0110, 0x9085, 0x0001, 0x0005, 0x080c, 0x8750, 0x1180,
- 0x080c, 0x3447, 0x1168, 0x7010, 0x9084, 0xff00, 0x8007, 0x9086,
+ 0x0005, 0x0110, 0x9085, 0x0001, 0x0005, 0x080c, 0x8748, 0x1180,
+ 0x080c, 0x3432, 0x1168, 0x7010, 0x9084, 0xff00, 0x8007, 0x9086,
0x0000, 0x1130, 0x9184, 0x000f, 0x908a, 0x0006, 0x1208, 0x000b,
- 0x0005, 0x855f, 0x8560, 0x855f, 0x855f, 0x85c5, 0x85d4, 0x0005,
- 0x00b6, 0x700c, 0x7108, 0x080c, 0x26a2, 0x1904, 0x85c3, 0x080c,
- 0x671e, 0x1904, 0x85c3, 0xbe12, 0xbd16, 0x7110, 0xd1bc, 0x0540,
- 0x702c, 0xd084, 0x1120, 0xb800, 0xd0bc, 0x1904, 0x85c3, 0x080c,
- 0x6bd5, 0x0148, 0x9086, 0x0004, 0x0130, 0x080c, 0x6bdd, 0x0118,
- 0x9086, 0x0004, 0x1588, 0x00c6, 0x080c, 0x85e3, 0x00ce, 0x05d8,
- 0x080c, 0xaed8, 0x2b08, 0x05b8, 0x6112, 0x080c, 0xd0b1, 0x6023,
- 0x0002, 0x7120, 0x610a, 0x2009, 0x0088, 0x080c, 0xafcc, 0x0458,
- 0x080c, 0x6bd5, 0x0148, 0x9086, 0x0004, 0x0130, 0x080c, 0x6bdd,
- 0x0118, 0x9086, 0x0004, 0x1180, 0x080c, 0xaed8, 0x2b08, 0x01d8,
- 0x6112, 0x080c, 0xd0b1, 0x6023, 0x0005, 0x7120, 0x610a, 0x2009,
- 0x0088, 0x080c, 0xafcc, 0x0078, 0x080c, 0xaed8, 0x2b08, 0x0158,
- 0x6112, 0x080c, 0xd0b1, 0x6023, 0x0004, 0x7120, 0x610a, 0x2009,
- 0x0001, 0x080c, 0xafcc, 0x00be, 0x0005, 0x7110, 0xd1bc, 0x0158,
- 0x00d1, 0x0148, 0x080c, 0x853b, 0x1130, 0x7124, 0x610a, 0x2009,
- 0x0089, 0x080c, 0xafcc, 0x0005, 0x7110, 0xd1bc, 0x0158, 0x0059,
- 0x0148, 0x080c, 0x853b, 0x1130, 0x7124, 0x610a, 0x2009, 0x008a,
- 0x080c, 0xafcc, 0x0005, 0x7020, 0x2060, 0x9c84, 0x0003, 0x1158,
+ 0x0005, 0x8557, 0x8558, 0x8557, 0x8557, 0x85bd, 0x85cc, 0x0005,
+ 0x00b6, 0x700c, 0x7108, 0x080c, 0x26a1, 0x1904, 0x85bb, 0x080c,
+ 0x6718, 0x1904, 0x85bb, 0xbe12, 0xbd16, 0x7110, 0xd1bc, 0x0540,
+ 0x702c, 0xd084, 0x1120, 0xb800, 0xd0bc, 0x1904, 0x85bb, 0x080c,
+ 0x6bcd, 0x0148, 0x9086, 0x0004, 0x0130, 0x080c, 0x6bd5, 0x0118,
+ 0x9086, 0x0004, 0x1588, 0x00c6, 0x080c, 0x85db, 0x00ce, 0x05d8,
+ 0x080c, 0xaef8, 0x2b08, 0x05b8, 0x6112, 0x080c, 0xd0ce, 0x6023,
+ 0x0002, 0x7120, 0x610a, 0x2009, 0x0088, 0x080c, 0xafec, 0x0458,
+ 0x080c, 0x6bcd, 0x0148, 0x9086, 0x0004, 0x0130, 0x080c, 0x6bd5,
+ 0x0118, 0x9086, 0x0004, 0x1180, 0x080c, 0xaef8, 0x2b08, 0x01d8,
+ 0x6112, 0x080c, 0xd0ce, 0x6023, 0x0005, 0x7120, 0x610a, 0x2009,
+ 0x0088, 0x080c, 0xafec, 0x0078, 0x080c, 0xaef8, 0x2b08, 0x0158,
+ 0x6112, 0x080c, 0xd0ce, 0x6023, 0x0004, 0x7120, 0x610a, 0x2009,
+ 0x0001, 0x080c, 0xafec, 0x00be, 0x0005, 0x7110, 0xd1bc, 0x0158,
+ 0x00d1, 0x0148, 0x080c, 0x8533, 0x1130, 0x7124, 0x610a, 0x2009,
+ 0x0089, 0x080c, 0xafec, 0x0005, 0x7110, 0xd1bc, 0x0158, 0x0059,
+ 0x0148, 0x080c, 0x8533, 0x1130, 0x7124, 0x610a, 0x2009, 0x008a,
+ 0x080c, 0xafec, 0x0005, 0x7020, 0x2060, 0x9c84, 0x0003, 0x1158,
0x9c82, 0x1ddc, 0x0240, 0x2001, 0x181a, 0x2004, 0x9c02, 0x1218,
0x9085, 0x0001, 0x0005, 0x9006, 0x0ce8, 0x00b6, 0x7110, 0xd1bc,
0x11d8, 0x7024, 0x2060, 0x9c84, 0x0003, 0x11b0, 0x9c82, 0x1ddc,
0x0298, 0x6868, 0x9c02, 0x1280, 0x7008, 0x9084, 0x00ff, 0x6110,
0x2158, 0xb910, 0x9106, 0x1140, 0x700c, 0xb914, 0x9106, 0x1120,
- 0x2009, 0x0051, 0x080c, 0xafcc, 0x7817, 0x0140, 0x00be, 0x0005,
+ 0x2009, 0x0051, 0x080c, 0xafec, 0x7817, 0x0140, 0x00be, 0x0005,
0x2031, 0x0105, 0x0069, 0x0005, 0x2031, 0x0206, 0x0049, 0x0005,
0x2031, 0x0207, 0x0029, 0x0005, 0x2031, 0x0213, 0x0009, 0x0005,
0x00c6, 0x0096, 0x00f6, 0x7000, 0x9084, 0xf000, 0x9086, 0xc000,
- 0x05c0, 0x080c, 0xaed8, 0x05a8, 0x0066, 0x00c6, 0x0046, 0x2011,
- 0x0263, 0x2204, 0x8211, 0x220c, 0x080c, 0x26a2, 0x1590, 0x080c,
- 0x671e, 0x1578, 0xbe12, 0xbd16, 0x2b00, 0x004e, 0x00ce, 0x6012,
- 0x080c, 0xd0b1, 0x080c, 0x1059, 0x0500, 0x2900, 0x6062, 0x9006,
+ 0x05c0, 0x080c, 0xaef8, 0x05a8, 0x0066, 0x00c6, 0x0046, 0x2011,
+ 0x0263, 0x2204, 0x8211, 0x220c, 0x080c, 0x26a1, 0x1590, 0x080c,
+ 0x6718, 0x1578, 0xbe12, 0xbd16, 0x2b00, 0x004e, 0x00ce, 0x6012,
+ 0x080c, 0xd0ce, 0x080c, 0x104d, 0x0500, 0x2900, 0x6062, 0x9006,
0xa802, 0xa866, 0xac6a, 0xa85c, 0x90f8, 0x001b, 0x20a9, 0x000e,
0xa860, 0x20e8, 0x20e1, 0x0000, 0x2fa0, 0x2e98, 0x4003, 0x006e,
0x6616, 0x6007, 0x003e, 0x6023, 0x0001, 0x6003, 0x0001, 0x080c,
- 0x942f, 0x00fe, 0x009e, 0x00ce, 0x0005, 0x080c, 0xaf2e, 0x006e,
+ 0x9427, 0x00fe, 0x009e, 0x00ce, 0x0005, 0x080c, 0xaf4e, 0x006e,
0x0cc0, 0x004e, 0x00ce, 0x0cc8, 0x00c6, 0x7000, 0x908c, 0xff00,
- 0x9184, 0xf000, 0x810f, 0x9086, 0x2000, 0x1904, 0x86cb, 0x9186,
- 0x0022, 0x15f0, 0x2001, 0x0111, 0x2004, 0x9005, 0x1904, 0x86cd,
- 0x7030, 0x908e, 0x0400, 0x0904, 0x86cd, 0x908e, 0x6000, 0x05e8,
+ 0x9184, 0xf000, 0x810f, 0x9086, 0x2000, 0x1904, 0x86c3, 0x9186,
+ 0x0022, 0x15f0, 0x2001, 0x0111, 0x2004, 0x9005, 0x1904, 0x86c5,
+ 0x7030, 0x908e, 0x0400, 0x0904, 0x86c5, 0x908e, 0x6000, 0x05e8,
0x908e, 0x5400, 0x05d0, 0x908e, 0x0300, 0x11d8, 0x2009, 0x1837,
- 0x210c, 0xd18c, 0x1590, 0xd1a4, 0x1580, 0x080c, 0x6b93, 0x0588,
+ 0x210c, 0xd18c, 0x1590, 0xd1a4, 0x1580, 0x080c, 0x6b8b, 0x0588,
0x68b0, 0x9084, 0x00ff, 0x7100, 0x918c, 0x00ff, 0x9106, 0x1518,
0x6880, 0x69b0, 0x918c, 0xff00, 0x9105, 0x7104, 0x9106, 0x11d8,
0x00e0, 0x2009, 0x0103, 0x210c, 0xd1b4, 0x11a8, 0x908e, 0x5200,
0x09e8, 0x908e, 0x0500, 0x09d0, 0x908e, 0x5000, 0x09b8, 0x0058,
- 0x9186, 0x0023, 0x1140, 0x080c, 0x85e3, 0x0128, 0x6004, 0x9086,
+ 0x9186, 0x0023, 0x1140, 0x080c, 0x85db, 0x0128, 0x6004, 0x9086,
0x0002, 0x0118, 0x0000, 0x9006, 0x0010, 0x9085, 0x0001, 0x00ce,
0x0005, 0x7030, 0x908e, 0x0300, 0x0118, 0x908e, 0x5200, 0x1d98,
0x2001, 0x1837, 0x2004, 0x9084, 0x0009, 0x9086, 0x0008, 0x0d68,
0x0c50, 0x0156, 0x0046, 0x0016, 0x0036, 0x7038, 0x2020, 0x8427,
0x94a4, 0x0007, 0xd484, 0x0148, 0x20a9, 0x0004, 0x2019, 0x1805,
- 0x2011, 0x027a, 0x080c, 0xbf2a, 0x1178, 0xd48c, 0x0148, 0x20a9,
- 0x0004, 0x2019, 0x1801, 0x2011, 0x027e, 0x080c, 0xbf2a, 0x1120,
+ 0x2011, 0x027a, 0x080c, 0xbf40, 0x1178, 0xd48c, 0x0148, 0x20a9,
+ 0x0004, 0x2019, 0x1801, 0x2011, 0x027e, 0x080c, 0xbf40, 0x1120,
0xd494, 0x0110, 0x9085, 0x0001, 0x003e, 0x001e, 0x004e, 0x015e,
0x0005, 0x0156, 0x0046, 0x0016, 0x0036, 0x7038, 0x2020, 0x8427,
0x94a4, 0x0007, 0xd484, 0x0148, 0x20a9, 0x0004, 0x2019, 0x1805,
- 0x2011, 0x0272, 0x080c, 0xbf2a, 0x1178, 0xd48c, 0x0148, 0x20a9,
- 0x0004, 0x2019, 0x1801, 0x2011, 0x0276, 0x080c, 0xbf2a, 0x1120,
+ 0x2011, 0x0272, 0x080c, 0xbf40, 0x1178, 0xd48c, 0x0148, 0x20a9,
+ 0x0004, 0x2019, 0x1801, 0x2011, 0x0276, 0x080c, 0xbf40, 0x1120,
0xd494, 0x0110, 0x9085, 0x0001, 0x003e, 0x001e, 0x004e, 0x015e,
0x0005, 0x00f6, 0x2079, 0x0200, 0x7800, 0xc0e5, 0xc0cc, 0x7802,
0x00fe, 0x0005, 0x00f6, 0x2079, 0x1800, 0x7834, 0xd084, 0x1130,
@@ -4127,53 +4114,53 @@ unsigned short risc_code01[] = {
0x0016, 0x2001, 0x1837, 0x200c, 0x9184, 0x0080, 0x0118, 0xd18c,
0x0118, 0x9006, 0x001e, 0x0005, 0x9085, 0x0001, 0x0cd8, 0x2071,
0x1a05, 0x7003, 0x0003, 0x700f, 0x0361, 0x9006, 0x701a, 0x707a,
- 0x7012, 0x7017, 0x1ddc, 0x7007, 0x0000, 0x7026, 0x702b, 0xa0aa,
- 0x7032, 0x7037, 0xa127, 0x7047, 0xffff, 0x704a, 0x704f, 0x56aa,
- 0x7052, 0x7063, 0x8907, 0x080c, 0x1072, 0x090c, 0x0d85, 0x2900,
+ 0x7012, 0x7017, 0x1ddc, 0x7007, 0x0000, 0x7026, 0x702b, 0xa0bb,
+ 0x7032, 0x7037, 0xa138, 0x7047, 0xffff, 0x704a, 0x704f, 0x56a4,
+ 0x7052, 0x7063, 0x88ff, 0x080c, 0x1066, 0x090c, 0x0d79, 0x2900,
0x7042, 0xa867, 0x0003, 0xa86f, 0x0100, 0xa8ab, 0xdcb0, 0x0005,
- 0x2071, 0x1a05, 0x1d04, 0x8823, 0x2091, 0x6000, 0x700c, 0x8001,
- 0x700e, 0x1590, 0x2001, 0x013c, 0x2004, 0x9005, 0x190c, 0x89b1,
+ 0x2071, 0x1a05, 0x1d04, 0x881b, 0x2091, 0x6000, 0x700c, 0x8001,
+ 0x700e, 0x1590, 0x2001, 0x013c, 0x2004, 0x9005, 0x190c, 0x89a9,
0x2001, 0x1869, 0x2004, 0xd0c4, 0x0158, 0x3a00, 0xd08c, 0x1140,
- 0x20d1, 0x0000, 0x20d1, 0x0001, 0x20d1, 0x0000, 0x080c, 0x0d85,
+ 0x20d1, 0x0000, 0x20d1, 0x0001, 0x20d1, 0x0000, 0x080c, 0x0d79,
0x700f, 0x0361, 0x7007, 0x0001, 0x0126, 0x2091, 0x8000, 0x2069,
- 0x1800, 0x69ec, 0xd1e4, 0x1138, 0xd1dc, 0x1118, 0x080c, 0x8975,
- 0x0010, 0x080c, 0x894c, 0x7048, 0x900d, 0x0148, 0x8109, 0x714a,
+ 0x1800, 0x69ec, 0xd1e4, 0x1138, 0xd1dc, 0x1118, 0x080c, 0x896d,
+ 0x0010, 0x080c, 0x8944, 0x7048, 0x900d, 0x0148, 0x8109, 0x714a,
0x1130, 0x704c, 0x080f, 0x0018, 0x0126, 0x2091, 0x8000, 0x7024,
0x900d, 0x0188, 0x7020, 0x8001, 0x7022, 0x1168, 0x7023, 0x0009,
0x8109, 0x7126, 0x9186, 0x03e8, 0x1110, 0x7028, 0x080f, 0x81ff,
0x1110, 0x7028, 0x080f, 0x7030, 0x900d, 0x0180, 0x702c, 0x8001,
0x702e, 0x1160, 0x702f, 0x0009, 0x8109, 0x7132, 0x0128, 0x9184,
- 0x007f, 0x090c, 0xa1d5, 0x0010, 0x7034, 0x080f, 0x7044, 0x9005,
+ 0x007f, 0x090c, 0xa1e6, 0x0010, 0x7034, 0x080f, 0x7044, 0x9005,
0x0118, 0x0310, 0x8001, 0x7046, 0x7054, 0x900d, 0x0168, 0x7050,
0x8001, 0x7052, 0x1148, 0x7053, 0x0009, 0x8109, 0x7156, 0x1120,
0x7158, 0x7156, 0x7060, 0x080f, 0x7018, 0x900d, 0x01d8, 0x0016,
0x7078, 0x900d, 0x0158, 0x7074, 0x8001, 0x7076, 0x1138, 0x7077,
0x0009, 0x8109, 0x717a, 0x1110, 0x707c, 0x080f, 0x001e, 0x7008,
0x8001, 0x700a, 0x1138, 0x700b, 0x0009, 0x8109, 0x711a, 0x1110,
- 0x701c, 0x080f, 0x012e, 0x7004, 0x0002, 0x884b, 0x884c, 0x8876,
+ 0x701c, 0x080f, 0x012e, 0x7004, 0x0002, 0x8843, 0x8844, 0x886e,
0x00e6, 0x2071, 0x1a05, 0x7018, 0x9005, 0x1120, 0x711a, 0x721e,
0x700b, 0x0009, 0x00ee, 0x0005, 0x00e6, 0x0006, 0x2071, 0x1a05,
0x701c, 0x9206, 0x1120, 0x701a, 0x701e, 0x707a, 0x707e, 0x000e,
0x00ee, 0x0005, 0x00e6, 0x2071, 0x1a05, 0xb888, 0x9102, 0x0208,
0xb98a, 0x00ee, 0x0005, 0x0005, 0x00b6, 0x2031, 0x0010, 0x7110,
- 0x080c, 0x6789, 0x11a8, 0xb888, 0x8001, 0x0290, 0xb88a, 0x1180,
+ 0x080c, 0x6783, 0x11a8, 0xb888, 0x8001, 0x0290, 0xb88a, 0x1180,
0x0126, 0x2091, 0x8000, 0x0066, 0xb8d0, 0x9005, 0x0138, 0x0026,
- 0xba3c, 0x0016, 0x080c, 0x68b4, 0x001e, 0x002e, 0x006e, 0x012e,
+ 0xba3c, 0x0016, 0x080c, 0x68ae, 0x001e, 0x002e, 0x006e, 0x012e,
0x8108, 0x9182, 0x0800, 0x1220, 0x8631, 0x0128, 0x7112, 0x0c00,
0x900e, 0x7007, 0x0002, 0x7112, 0x00be, 0x0005, 0x2031, 0x0010,
0x7014, 0x2060, 0x0126, 0x2091, 0x8000, 0x6048, 0x9005, 0x0128,
- 0x8001, 0x604a, 0x1110, 0x080c, 0xcf32, 0x6018, 0x9005, 0x0904,
- 0x88ce, 0x00f6, 0x2079, 0x0300, 0x7918, 0xd1b4, 0x1904, 0x88e1,
+ 0x8001, 0x604a, 0x1110, 0x080c, 0xcf4f, 0x6018, 0x9005, 0x0904,
+ 0x88c6, 0x00f6, 0x2079, 0x0300, 0x7918, 0xd1b4, 0x1904, 0x88d9,
0x781b, 0x2020, 0xa001, 0x7918, 0xd1b4, 0x0120, 0x781b, 0x2000,
- 0x0804, 0x88e1, 0x8001, 0x601a, 0x0106, 0x781b, 0x2000, 0xa001,
+ 0x0804, 0x88d9, 0x8001, 0x601a, 0x0106, 0x781b, 0x2000, 0xa001,
0x7918, 0xd1ac, 0x1dd0, 0x010e, 0x00fe, 0x1540, 0x6120, 0x9186,
0x0003, 0x0148, 0x9186, 0x0006, 0x0130, 0x9186, 0x0009, 0x11e0,
- 0x611c, 0xd1c4, 0x1100, 0x080c, 0xcc16, 0x01b0, 0x6014, 0x2048,
+ 0x611c, 0xd1c4, 0x1100, 0x080c, 0xcc33, 0x01b0, 0x6014, 0x2048,
0xa884, 0x908a, 0x199a, 0x0280, 0x9082, 0x1999, 0xa886, 0x908a,
0x199a, 0x0210, 0x2001, 0x1999, 0x8003, 0x800b, 0x810b, 0x9108,
- 0x611a, 0x080c, 0xd36a, 0x0110, 0x080c, 0xc8f7, 0x012e, 0x9c88,
+ 0x611a, 0x080c, 0xd389, 0x0110, 0x080c, 0xc910, 0x012e, 0x9c88,
0x001c, 0x7116, 0x2001, 0x181a, 0x2004, 0x9102, 0x1228, 0x8631,
- 0x0138, 0x2160, 0x0804, 0x887a, 0x7017, 0x1ddc, 0x7007, 0x0000,
+ 0x0138, 0x2160, 0x0804, 0x8872, 0x7017, 0x1ddc, 0x7007, 0x0000,
0x0005, 0x00fe, 0x0c58, 0x00e6, 0x2071, 0x1a05, 0x7027, 0x07d0,
0x7023, 0x0009, 0x00ee, 0x0005, 0x2001, 0x1a0e, 0x2003, 0x0000,
0x0005, 0x00e6, 0x2071, 0x1a05, 0x7132, 0x702f, 0x0009, 0x00ee,
@@ -4181,9 +4168,9 @@ unsigned short risc_code01[] = {
0x1a05, 0x711a, 0x721e, 0x700b, 0x0009, 0x00ee, 0x0005, 0x0086,
0x0026, 0x705c, 0x8000, 0x705e, 0x2001, 0x1a15, 0x2044, 0xa06c,
0x9086, 0x0000, 0x0150, 0x7070, 0xa09a, 0x706c, 0xa096, 0x7068,
- 0xa092, 0x7064, 0xa08e, 0x080c, 0x114e, 0x002e, 0x008e, 0x0005,
+ 0xa092, 0x7064, 0xa08e, 0x080c, 0x1142, 0x002e, 0x008e, 0x0005,
0x0006, 0x0016, 0x0096, 0x00a6, 0x00b6, 0x00c6, 0x00d6, 0x00e6,
- 0x00f6, 0x0156, 0x080c, 0x8788, 0x015e, 0x00fe, 0x00ee, 0x00de,
+ 0x00f6, 0x0156, 0x080c, 0x8780, 0x015e, 0x00fe, 0x00ee, 0x00de,
0x00ce, 0x00be, 0x00ae, 0x009e, 0x001e, 0x000e, 0x0005, 0x00e6,
0x2071, 0x1a05, 0x717a, 0x727e, 0x7077, 0x0009, 0x00ee, 0x0005,
0x00e6, 0x0006, 0x2071, 0x1a05, 0x707c, 0x9206, 0x1110, 0x707a,
@@ -4192,14 +4179,14 @@ unsigned short risc_code01[] = {
0x8117, 0x9294, 0x00c1, 0x0088, 0x9184, 0x0007, 0x01a0, 0x8109,
0x9184, 0x0007, 0x0110, 0x69ee, 0x0070, 0x8107, 0x9084, 0x0007,
0x910d, 0x8107, 0x9106, 0x9094, 0x00c1, 0x9184, 0xff3e, 0x9205,
- 0x68ee, 0x080c, 0x0f24, 0x002e, 0x0005, 0x69e8, 0x9184, 0x003f,
+ 0x68ee, 0x080c, 0x0f18, 0x002e, 0x0005, 0x69e8, 0x9184, 0x003f,
0x05b8, 0x8109, 0x9184, 0x003f, 0x01a8, 0x6a54, 0x6874, 0x9202,
0x0220, 0xd1bc, 0x0168, 0xc1bc, 0x0018, 0xd1bc, 0x1148, 0xc1bd,
- 0x2110, 0x00e6, 0x2071, 0x1800, 0x080c, 0x0f46, 0x00ee, 0x0400,
+ 0x2110, 0x00e6, 0x2071, 0x1800, 0x080c, 0x0f3a, 0x00ee, 0x0400,
0x69ea, 0x00f0, 0x0026, 0x8107, 0x9094, 0x0007, 0x0128, 0x8001,
0x8007, 0x9085, 0x0007, 0x0050, 0x2010, 0x8004, 0x8004, 0x8004,
0x9084, 0x0007, 0x9205, 0x8007, 0x9085, 0x0028, 0x9086, 0x0040,
- 0x2010, 0x00e6, 0x2071, 0x1800, 0x080c, 0x0f46, 0x00ee, 0x002e,
+ 0x2010, 0x00e6, 0x2071, 0x1800, 0x080c, 0x0f3a, 0x00ee, 0x002e,
0x0005, 0x0016, 0x00c6, 0x2009, 0xfff4, 0x210d, 0x2061, 0x0100,
0x60f0, 0x9100, 0x60f3, 0x0000, 0x2009, 0xfff4, 0x200f, 0x1220,
0x8108, 0x2105, 0x8000, 0x200f, 0x00ce, 0x001e, 0x0005, 0x00c6,
@@ -4208,42 +4195,42 @@ unsigned short risc_code01[] = {
0x1638, 0x9005, 0x1150, 0x00c6, 0x2061, 0x1a74, 0x6014, 0x00ce,
0x9005, 0x1130, 0x2001, 0x001e, 0x0018, 0x908e, 0xffff, 0x01b0,
0x8003, 0x800b, 0x810b, 0x9108, 0x611a, 0xa87c, 0x908c, 0x00c0,
- 0x918e, 0x00c0, 0x0904, 0x8a8f, 0xd0b4, 0x1168, 0xd0bc, 0x1904,
- 0x8a68, 0x2009, 0x0006, 0x080c, 0x8abc, 0x0005, 0x900e, 0x0c60,
+ 0x918e, 0x00c0, 0x0904, 0x8a87, 0xd0b4, 0x1168, 0xd0bc, 0x1904,
+ 0x8a60, 0x2009, 0x0006, 0x080c, 0x8ab4, 0x0005, 0x900e, 0x0c60,
0x2001, 0x1999, 0x08b0, 0xd0fc, 0x05e0, 0x908c, 0x2023, 0x1568,
0x87ff, 0x1558, 0xa9a8, 0x81ff, 0x1540, 0x6124, 0x918c, 0x0500,
0x1520, 0x6100, 0x918e, 0x0007, 0x1500, 0x2009, 0x1869, 0x210c,
0xd184, 0x11d8, 0x6003, 0x0003, 0x6007, 0x0043, 0x6047, 0xb035,
- 0x080c, 0x1c90, 0xa87c, 0xc0dd, 0xa87e, 0x600f, 0x0000, 0x00f6,
+ 0x080c, 0x1c8c, 0xa87c, 0xc0dd, 0xa87e, 0x600f, 0x0000, 0x00f6,
0x2079, 0x0380, 0x7818, 0xd0bc, 0x1de8, 0x7833, 0x0013, 0x2c00,
0x7836, 0x781b, 0x8080, 0x00fe, 0x0005, 0x908c, 0x0003, 0x0120,
- 0x918e, 0x0003, 0x1904, 0x8ab6, 0x908c, 0x2020, 0x918e, 0x2020,
+ 0x918e, 0x0003, 0x1904, 0x8aae, 0x908c, 0x2020, 0x918e, 0x2020,
0x01a8, 0x6024, 0xd0d4, 0x11e8, 0x2009, 0x1869, 0x2104, 0xd084,
- 0x1138, 0x87ff, 0x1120, 0x2009, 0x0043, 0x0804, 0xafcc, 0x0005,
- 0x87ff, 0x1de8, 0x2009, 0x0042, 0x0804, 0xafcc, 0x6110, 0x00b6,
+ 0x1138, 0x87ff, 0x1120, 0x2009, 0x0043, 0x0804, 0xafec, 0x0005,
+ 0x87ff, 0x1de8, 0x2009, 0x0042, 0x0804, 0xafec, 0x6110, 0x00b6,
0x2158, 0xb900, 0x00be, 0xd1ac, 0x0d20, 0x6024, 0xc0cd, 0x6026,
0x0c00, 0xc0d4, 0x6026, 0xa890, 0x602e, 0xa88c, 0x6032, 0x08e0,
0xd0fc, 0x0160, 0x908c, 0x0003, 0x0120, 0x918e, 0x0003, 0x1904,
- 0x8ab6, 0x908c, 0x2020, 0x918e, 0x2020, 0x0170, 0x0076, 0x00f6,
- 0x2c78, 0x080c, 0x17ad, 0x00fe, 0x007e, 0x87ff, 0x1120, 0x2009,
- 0x0042, 0x080c, 0xafcc, 0x0005, 0x6110, 0x00b6, 0x2158, 0xb900,
+ 0x8aae, 0x908c, 0x2020, 0x918e, 0x2020, 0x0170, 0x0076, 0x00f6,
+ 0x2c78, 0x080c, 0x17a1, 0x00fe, 0x007e, 0x87ff, 0x1120, 0x2009,
+ 0x0042, 0x080c, 0xafec, 0x0005, 0x6110, 0x00b6, 0x2158, 0xb900,
0x00be, 0xd1ac, 0x0d58, 0x6124, 0xc1cd, 0x6126, 0x0c38, 0xd0fc,
0x0188, 0x908c, 0x2020, 0x918e, 0x2020, 0x01a8, 0x9084, 0x0003,
0x908e, 0x0002, 0x0148, 0x87ff, 0x1120, 0x2009, 0x0041, 0x080c,
- 0xafcc, 0x0005, 0x00b9, 0x0ce8, 0x87ff, 0x1dd8, 0x2009, 0x0043,
- 0x080c, 0xafcc, 0x0cb0, 0x6110, 0x00b6, 0x2158, 0xb900, 0x00be,
+ 0xafec, 0x0005, 0x00b9, 0x0ce8, 0x87ff, 0x1dd8, 0x2009, 0x0043,
+ 0x080c, 0xafec, 0x0cb0, 0x6110, 0x00b6, 0x2158, 0xb900, 0x00be,
0xd1ac, 0x0d20, 0x6124, 0xc1cd, 0x6126, 0x0c00, 0x2009, 0x0004,
- 0x0019, 0x0005, 0x2009, 0x0001, 0x0096, 0x080c, 0xcc16, 0x0518,
+ 0x0019, 0x0005, 0x2009, 0x0001, 0x0096, 0x080c, 0xcc33, 0x0518,
0x6014, 0x2048, 0xa982, 0xa800, 0x6016, 0x9186, 0x0001, 0x1188,
0xa97c, 0x918c, 0x8100, 0x918e, 0x8100, 0x1158, 0x00c6, 0x2061,
0x1a74, 0x6200, 0xd28c, 0x1120, 0x6204, 0x8210, 0x0208, 0x6206,
- 0x00ce, 0x080c, 0x6d53, 0x6014, 0x904d, 0x0076, 0x2039, 0x0000,
- 0x190c, 0x89d5, 0x007e, 0x009e, 0x0005, 0x0156, 0x00c6, 0x2061,
+ 0x00ce, 0x080c, 0x6d4b, 0x6014, 0x904d, 0x0076, 0x2039, 0x0000,
+ 0x190c, 0x89cd, 0x007e, 0x009e, 0x0005, 0x0156, 0x00c6, 0x2061,
0x1a74, 0x6000, 0x81ff, 0x0110, 0x9205, 0x0008, 0x9204, 0x6002,
0x00ce, 0x015e, 0x0005, 0x6800, 0xd08c, 0x1138, 0x6808, 0x9005,
0x0120, 0x8001, 0x680a, 0x9085, 0x0001, 0x0005, 0x2071, 0x1925,
0x7003, 0x0006, 0x7007, 0x0000, 0x700f, 0x0000, 0x7013, 0x0001,
- 0x080c, 0x1072, 0x090c, 0x0d85, 0xa867, 0x0006, 0xa86b, 0x0001,
+ 0x080c, 0x1066, 0x090c, 0x0d79, 0xa867, 0x0006, 0xa86b, 0x0001,
0xa8ab, 0xdcb0, 0xa89f, 0x0000, 0x2900, 0x702e, 0x7033, 0x0000,
0x0005, 0x0126, 0x2091, 0x8000, 0x0096, 0x00e6, 0x2071, 0x1925,
0x702c, 0x2048, 0x6a2c, 0x721e, 0x6b30, 0x7322, 0x6834, 0x7026,
@@ -4252,92 +4239,92 @@ unsigned short risc_code01[] = {
0x8001, 0x1de0, 0x2100, 0x9210, 0x1208, 0x8318, 0xaa8e, 0xab92,
0x7010, 0xd084, 0x0168, 0xc084, 0x7007, 0x0001, 0x700f, 0x0000,
0x0006, 0x2009, 0x1b74, 0x2104, 0x9082, 0x0007, 0x200a, 0x000e,
- 0xc095, 0x7012, 0x2008, 0x2001, 0x003b, 0x080c, 0x16b9, 0x9006,
+ 0xc095, 0x7012, 0x2008, 0x2001, 0x003b, 0x080c, 0x16ad, 0x9006,
0x2071, 0x193e, 0x7002, 0x7006, 0x702a, 0x00ee, 0x009e, 0x012e,
0x0005, 0x2009, 0x1b74, 0x2104, 0x9080, 0x0007, 0x200a, 0x0005,
0x00e6, 0x0126, 0x0156, 0x2091, 0x8000, 0x2071, 0x1800, 0x7154,
0x2001, 0x0008, 0x910a, 0x0638, 0x2001, 0x187d, 0x20ac, 0x9006,
- 0x9080, 0x0008, 0x1f04, 0x8b78, 0x71c0, 0x9102, 0x02e0, 0x2071,
- 0x1877, 0x20a9, 0x0007, 0x00c6, 0x080c, 0xaed8, 0x6023, 0x0009,
+ 0x9080, 0x0008, 0x1f04, 0x8b70, 0x71c0, 0x9102, 0x02e0, 0x2071,
+ 0x1877, 0x20a9, 0x0007, 0x00c6, 0x080c, 0xaef8, 0x6023, 0x0009,
0x6003, 0x0004, 0x601f, 0x0101, 0x0089, 0x0126, 0x2091, 0x8000,
- 0x080c, 0x8cf9, 0x012e, 0x1f04, 0x8b84, 0x9006, 0x00ce, 0x015e,
+ 0x080c, 0x8cf1, 0x012e, 0x1f04, 0x8b7c, 0x9006, 0x00ce, 0x015e,
0x012e, 0x00ee, 0x0005, 0x9085, 0x0001, 0x0cc8, 0x00e6, 0x00b6,
0x0096, 0x0086, 0x0056, 0x0046, 0x0026, 0x7118, 0x720c, 0x7620,
0x7004, 0xd084, 0x1128, 0x2021, 0x0024, 0x2029, 0x0002, 0x0020,
- 0x2021, 0x002c, 0x2029, 0x000a, 0x080c, 0x1059, 0x090c, 0x0d85,
+ 0x2021, 0x002c, 0x2029, 0x000a, 0x080c, 0x104d, 0x090c, 0x0d79,
0x2900, 0x6016, 0x2058, 0xac66, 0x9006, 0xa802, 0xa806, 0xa86a,
0xa87a, 0xa8aa, 0xa887, 0x0005, 0xa87f, 0x0020, 0x7008, 0xa89a,
0x7010, 0xa89e, 0xae8a, 0xa8af, 0xffff, 0xa8b3, 0x0000, 0x8109,
- 0x0160, 0x080c, 0x1059, 0x090c, 0x0d85, 0xad66, 0x2b00, 0xa802,
+ 0x0160, 0x080c, 0x104d, 0x090c, 0x0d79, 0xad66, 0x2b00, 0xa802,
0x2900, 0xb806, 0x2058, 0x8109, 0x1da0, 0x002e, 0x004e, 0x005e,
0x008e, 0x009e, 0x00be, 0x00ee, 0x0005, 0x2079, 0x0000, 0x2071,
- 0x1925, 0x7004, 0x004b, 0x700c, 0x0002, 0x8bf0, 0x8be9, 0x8be9,
- 0x0005, 0x8bfa, 0x8c50, 0x8c50, 0x8c50, 0x8c51, 0x8c62, 0x8c62,
+ 0x1925, 0x7004, 0x004b, 0x700c, 0x0002, 0x8be8, 0x8be1, 0x8be1,
+ 0x0005, 0x8bf2, 0x8c48, 0x8c48, 0x8c48, 0x8c49, 0x8c5a, 0x8c5a,
0x700c, 0x0cba, 0x0126, 0x2091, 0x8000, 0x78a0, 0x79a0, 0x9106,
- 0x1904, 0x8c42, 0x7814, 0xd0bc, 0x1904, 0x8c4b, 0x012e, 0x7018,
- 0x910a, 0x1128, 0x7030, 0x9005, 0x1904, 0x8c94, 0x0005, 0x1210,
+ 0x1904, 0x8c3a, 0x7814, 0xd0bc, 0x1904, 0x8c43, 0x012e, 0x7018,
+ 0x910a, 0x1128, 0x7030, 0x9005, 0x1904, 0x8c8c, 0x0005, 0x1210,
0x7114, 0x910a, 0x9192, 0x000a, 0x0210, 0x2009, 0x000a, 0x2001,
0x1888, 0x2014, 0x2001, 0x1937, 0x2004, 0x9100, 0x9202, 0x0e50,
- 0x080c, 0x8df1, 0x2200, 0x9102, 0x0208, 0x2208, 0x0096, 0x702c,
- 0x2048, 0xa873, 0x0001, 0xa976, 0x080c, 0x8efa, 0x2100, 0xa87e,
+ 0x080c, 0x8de9, 0x2200, 0x9102, 0x0208, 0x2208, 0x0096, 0x702c,
+ 0x2048, 0xa873, 0x0001, 0xa976, 0x080c, 0x8ef2, 0x2100, 0xa87e,
0xa86f, 0x0000, 0x009e, 0x0126, 0x2091, 0x8000, 0x2009, 0x1a25,
- 0x2104, 0xc085, 0x200a, 0x700f, 0x0002, 0x012e, 0x080c, 0x116d,
- 0x1de8, 0x0005, 0x78a0, 0x79a0, 0x9106, 0x0904, 0x8c02, 0x080c,
- 0x8dc9, 0x012e, 0x0005, 0x7810, 0xc0c5, 0x7812, 0x0804, 0x8c02,
- 0x0005, 0x700c, 0x0002, 0x8c56, 0x8c59, 0x8c58, 0x080c, 0x8bf8,
+ 0x2104, 0xc085, 0x200a, 0x700f, 0x0002, 0x012e, 0x080c, 0x1161,
+ 0x1de8, 0x0005, 0x78a0, 0x79a0, 0x9106, 0x0904, 0x8bfa, 0x080c,
+ 0x8dc1, 0x012e, 0x0005, 0x7810, 0xc0c5, 0x7812, 0x0804, 0x8bfa,
+ 0x0005, 0x700c, 0x0002, 0x8c4e, 0x8c51, 0x8c50, 0x080c, 0x8bf0,
0x0005, 0x8001, 0x700e, 0x0096, 0x702c, 0x2048, 0xa974, 0x009e,
0x0011, 0x0ca0, 0x0005, 0x0096, 0x702c, 0x2048, 0x7018, 0x9100,
0x7214, 0x921a, 0x1130, 0x701c, 0xa88e, 0x7020, 0xa892, 0x9006,
- 0x0068, 0x0006, 0x080c, 0x8efa, 0x2100, 0xaa8c, 0x9210, 0xaa8e,
+ 0x0068, 0x0006, 0x080c, 0x8ef2, 0x2100, 0xaa8c, 0x9210, 0xaa8e,
0x1220, 0xa890, 0x9081, 0x0000, 0xa892, 0x000e, 0x009e, 0x0126,
- 0x2091, 0x8000, 0x78a2, 0x701a, 0x080c, 0x8dc9, 0x012e, 0x0005,
- 0x00e6, 0x2071, 0x1925, 0x700c, 0x0002, 0x8c92, 0x8c92, 0x8c90,
+ 0x2091, 0x8000, 0x78a2, 0x701a, 0x080c, 0x8dc1, 0x012e, 0x0005,
+ 0x00e6, 0x2071, 0x1925, 0x700c, 0x0002, 0x8c8a, 0x8c8a, 0x8c88,
0x700f, 0x0001, 0x00ee, 0x0005, 0x0126, 0x2091, 0x8000, 0x7030,
0x9005, 0x0508, 0x2078, 0x7814, 0x2048, 0xae88, 0x00b6, 0x2059,
- 0x0000, 0x080c, 0x8d02, 0x00be, 0x01b0, 0x00e6, 0x2071, 0x193e,
- 0x080c, 0x8d49, 0x00ee, 0x0178, 0x0096, 0x080c, 0x1072, 0x2900,
+ 0x0000, 0x080c, 0x8cfa, 0x00be, 0x01b0, 0x00e6, 0x2071, 0x193e,
+ 0x080c, 0x8d41, 0x00ee, 0x0178, 0x0096, 0x080c, 0x1066, 0x2900,
0x009e, 0x0148, 0xa8aa, 0x04d1, 0x0041, 0x2001, 0x1948, 0x2003,
0x0000, 0x012e, 0x08c8, 0x012e, 0x0005, 0x00d6, 0x00c6, 0x0086,
0x00a6, 0x2940, 0x2650, 0x2600, 0x9005, 0x0180, 0xa864, 0x9084,
- 0x000f, 0x2068, 0x9d88, 0x1ee2, 0x2165, 0x0056, 0x2029, 0x0000,
- 0x080c, 0x8e7f, 0x080c, 0x1eb8, 0x1dd8, 0x005e, 0x00ae, 0x2001,
- 0x187f, 0x2004, 0xa88a, 0x00c6, 0x2f60, 0x080c, 0x17ad, 0x00ce,
+ 0x000f, 0x2068, 0x9d88, 0x1ede, 0x2165, 0x0056, 0x2029, 0x0000,
+ 0x080c, 0x8e77, 0x080c, 0x1eb4, 0x1dd8, 0x005e, 0x00ae, 0x2001,
+ 0x187f, 0x2004, 0xa88a, 0x00c6, 0x2f60, 0x080c, 0x17a1, 0x00ce,
0x781f, 0x0101, 0x7813, 0x0000, 0x0126, 0x2091, 0x8000, 0x080c,
- 0x8d58, 0x012e, 0x008e, 0x00ce, 0x00de, 0x0005, 0x7030, 0x9005,
+ 0x8d50, 0x012e, 0x008e, 0x00ce, 0x00de, 0x0005, 0x7030, 0x9005,
0x0138, 0x2078, 0x780c, 0x7032, 0x2001, 0x1948, 0x2003, 0x0001,
0x0005, 0x00e6, 0x2071, 0x1925, 0x7030, 0x600e, 0x2c00, 0x7032,
- 0x00ee, 0x0005, 0x00d6, 0x00c6, 0x0026, 0x9b80, 0x8fc8, 0x2005,
- 0x906d, 0x090c, 0x0d85, 0x9b80, 0x8fc0, 0x2005, 0x9065, 0x090c,
- 0x0d85, 0x6114, 0x2600, 0x9102, 0x0248, 0x6828, 0x9102, 0x02f0,
+ 0x00ee, 0x0005, 0x00d6, 0x00c6, 0x0026, 0x9b80, 0x8fc0, 0x2005,
+ 0x906d, 0x090c, 0x0d79, 0x9b80, 0x8fb8, 0x2005, 0x9065, 0x090c,
+ 0x0d79, 0x6114, 0x2600, 0x9102, 0x0248, 0x6828, 0x9102, 0x02f0,
0x9085, 0x0001, 0x002e, 0x00ce, 0x00de, 0x0005, 0x6804, 0xd094,
0x0148, 0x6854, 0xd084, 0x1178, 0xc085, 0x6856, 0x2011, 0x8026,
- 0x080c, 0x4c2e, 0x684c, 0x0096, 0x904d, 0x090c, 0x0d85, 0xa804,
+ 0x080c, 0x4c28, 0x684c, 0x0096, 0x904d, 0x090c, 0x0d79, 0xa804,
0x8000, 0xa806, 0x009e, 0x9006, 0x2030, 0x0c20, 0x6854, 0xd08c,
- 0x1d08, 0xc08d, 0x6856, 0x2011, 0x8025, 0x080c, 0x4c2e, 0x684c,
- 0x0096, 0x904d, 0x090c, 0x0d85, 0xa800, 0x8000, 0xa802, 0x009e,
+ 0x1d08, 0xc08d, 0x6856, 0x2011, 0x8025, 0x080c, 0x4c28, 0x684c,
+ 0x0096, 0x904d, 0x090c, 0x0d79, 0xa800, 0x8000, 0xa802, 0x009e,
0x0888, 0x7000, 0x2019, 0x0008, 0x8319, 0x7104, 0x9102, 0x1118,
0x2300, 0x9005, 0x0020, 0x0210, 0x9302, 0x0008, 0x8002, 0x0005,
- 0x00d6, 0x7814, 0x9005, 0x090c, 0x0d85, 0x781c, 0x9084, 0x0101,
- 0x9086, 0x0101, 0x190c, 0x0d85, 0x7827, 0x0000, 0x2069, 0x193e,
+ 0x00d6, 0x7814, 0x9005, 0x090c, 0x0d79, 0x781c, 0x9084, 0x0101,
+ 0x9086, 0x0101, 0x190c, 0x0d79, 0x7827, 0x0000, 0x2069, 0x193e,
0x6804, 0x9080, 0x1940, 0x2f08, 0x2102, 0x6904, 0x8108, 0x9182,
0x0008, 0x0208, 0x900e, 0x6906, 0x9180, 0x1940, 0x2003, 0x0000,
0x00de, 0x0005, 0x0096, 0x00c6, 0x2060, 0x6014, 0x2048, 0xa8a8,
- 0x0096, 0x2048, 0x9005, 0x190c, 0x108b, 0x009e, 0xa8ab, 0x0000,
- 0x080c, 0x100b, 0x080c, 0xaf2e, 0x00ce, 0x009e, 0x0005, 0x6020,
+ 0x0096, 0x2048, 0x9005, 0x190c, 0x107f, 0x009e, 0xa8ab, 0x0000,
+ 0x080c, 0x0fff, 0x080c, 0xaf4e, 0x00ce, 0x009e, 0x0005, 0x6020,
0x9086, 0x0009, 0x1128, 0x601c, 0xd0c4, 0x0110, 0x9006, 0x0005,
0x9085, 0x0001, 0x0005, 0x6000, 0x9086, 0x0000, 0x0178, 0x6010,
- 0x9005, 0x0150, 0x00b6, 0x2058, 0x080c, 0x90fd, 0x00be, 0x6013,
+ 0x9005, 0x0150, 0x00b6, 0x2058, 0x080c, 0x90f5, 0x00be, 0x6013,
0x0000, 0x601b, 0x0000, 0x0010, 0x2c00, 0x0861, 0x0005, 0x2009,
0x1929, 0x210c, 0xd194, 0x0005, 0x0126, 0x2091, 0x8000, 0x00e6,
0x2071, 0x1925, 0x7110, 0xc194, 0xd19c, 0x1118, 0xc185, 0x7007,
- 0x0000, 0x7112, 0x2001, 0x003b, 0x080c, 0x16b9, 0x00ee, 0x012e,
+ 0x0000, 0x7112, 0x2001, 0x003b, 0x080c, 0x16ad, 0x00ee, 0x012e,
0x0005, 0x7814, 0xd0bc, 0x1108, 0x0005, 0x7810, 0xc0c5, 0x7812,
0x0cc0, 0x0096, 0x00d6, 0x9006, 0x7006, 0x700e, 0x701a, 0x701e,
- 0x7022, 0x7016, 0x702a, 0x7026, 0x702f, 0x0000, 0x080c, 0x8f48,
- 0x0170, 0x080c, 0x8f7d, 0x0158, 0x2900, 0x7002, 0x700a, 0x701a,
+ 0x7022, 0x7016, 0x702a, 0x7026, 0x702f, 0x0000, 0x080c, 0x8f40,
+ 0x0170, 0x080c, 0x8f75, 0x0158, 0x2900, 0x7002, 0x700a, 0x701a,
0x7013, 0x0001, 0x701f, 0x000a, 0x00de, 0x009e, 0x0005, 0x900e,
0x0cd8, 0x00e6, 0x0096, 0x0086, 0x00d6, 0x00c6, 0x2071, 0x1932,
- 0x721c, 0x2100, 0x9202, 0x1618, 0x080c, 0x8f7d, 0x090c, 0x0d85,
+ 0x721c, 0x2100, 0x9202, 0x1618, 0x080c, 0x8f75, 0x090c, 0x0d79,
0x7018, 0x9005, 0x1160, 0x2900, 0x7002, 0x700a, 0x701a, 0x9006,
0x7006, 0x700e, 0xa806, 0xa802, 0x7012, 0x701e, 0x0038, 0x2040,
0xa806, 0x2900, 0xa002, 0x701a, 0xa803, 0x0000, 0x7010, 0x8000,
@@ -4345,92 +4332,92 @@ unsigned short risc_code01[] = {
0x00ce, 0x00de, 0x008e, 0x009e, 0x00ee, 0x0005, 0x0096, 0x0156,
0x0136, 0x0146, 0x00e6, 0x0126, 0x2091, 0x8000, 0x2071, 0x1932,
0x7300, 0x831f, 0x831e, 0x831e, 0x9384, 0x003f, 0x20e8, 0x939c,
- 0xffc0, 0x9398, 0x0003, 0x7104, 0x080c, 0x8efa, 0x810c, 0x2100,
+ 0xffc0, 0x9398, 0x0003, 0x7104, 0x080c, 0x8ef2, 0x810c, 0x2100,
0x9318, 0x8003, 0x2228, 0x2021, 0x0078, 0x9402, 0x9532, 0x0208,
0x2028, 0x2500, 0x8004, 0x20a8, 0x23a0, 0xa001, 0xa001, 0x4005,
- 0x2508, 0x080c, 0x8f03, 0x2130, 0x7014, 0x9600, 0x7016, 0x2600,
+ 0x2508, 0x080c, 0x8efb, 0x2130, 0x7014, 0x9600, 0x7016, 0x2600,
0x711c, 0x9102, 0x701e, 0x7004, 0x9600, 0x2008, 0x9082, 0x000a,
0x1190, 0x7000, 0x2048, 0xa800, 0x9005, 0x1148, 0x2009, 0x0001,
- 0x0026, 0x080c, 0x8df1, 0x002e, 0x7000, 0x2048, 0xa800, 0x7002,
- 0x7007, 0x0000, 0x0008, 0x7106, 0x2500, 0x9212, 0x1904, 0x8e30,
+ 0x0026, 0x080c, 0x8de9, 0x002e, 0x7000, 0x2048, 0xa800, 0x7002,
+ 0x7007, 0x0000, 0x0008, 0x7106, 0x2500, 0x9212, 0x1904, 0x8e28,
0x012e, 0x00ee, 0x014e, 0x013e, 0x015e, 0x009e, 0x0005, 0x0016,
- 0x0026, 0x00e6, 0x0126, 0x2091, 0x8000, 0x9580, 0x8fc0, 0x2005,
- 0x9075, 0x090c, 0x0d85, 0x080c, 0x8ed5, 0x012e, 0x9580, 0x8fbc,
- 0x2005, 0x9075, 0x090c, 0x0d85, 0x0156, 0x0136, 0x01c6, 0x0146,
+ 0x0026, 0x00e6, 0x0126, 0x2091, 0x8000, 0x9580, 0x8fb8, 0x2005,
+ 0x9075, 0x090c, 0x0d79, 0x080c, 0x8ecd, 0x012e, 0x9580, 0x8fb4,
+ 0x2005, 0x9075, 0x090c, 0x0d79, 0x0156, 0x0136, 0x01c6, 0x0146,
0x01d6, 0x831f, 0x831e, 0x831e, 0x9384, 0x003f, 0x20e0, 0x9384,
0xffc0, 0x9100, 0x2098, 0xa860, 0x20e8, 0xa95c, 0x2c05, 0x9100,
- 0x20a0, 0x20a9, 0x0002, 0x4003, 0x2e0c, 0x2d00, 0x0002, 0x8ebf,
- 0x8ebf, 0x8ec1, 0x8ebf, 0x8ec1, 0x8ebf, 0x8ebf, 0x8ebf, 0x8ebf,
- 0x8ebf, 0x8ec7, 0x8ebf, 0x8ec7, 0x8ebf, 0x8ebf, 0x8ebf, 0x080c,
- 0x0d85, 0x4104, 0x20a9, 0x0002, 0x4002, 0x4003, 0x0028, 0x20a9,
+ 0x20a0, 0x20a9, 0x0002, 0x4003, 0x2e0c, 0x2d00, 0x0002, 0x8eb7,
+ 0x8eb7, 0x8eb9, 0x8eb7, 0x8eb9, 0x8eb7, 0x8eb7, 0x8eb7, 0x8eb7,
+ 0x8eb7, 0x8ebf, 0x8eb7, 0x8ebf, 0x8eb7, 0x8eb7, 0x8eb7, 0x080c,
+ 0x0d79, 0x4104, 0x20a9, 0x0002, 0x4002, 0x4003, 0x0028, 0x20a9,
0x0002, 0x4003, 0x4104, 0x4003, 0x01de, 0x014e, 0x01ce, 0x013e,
0x015e, 0x00ee, 0x002e, 0x001e, 0x0005, 0x0096, 0x7014, 0x8001,
0x7016, 0x710c, 0x2110, 0x00f1, 0x810c, 0x9188, 0x0003, 0x7308,
0x8210, 0x9282, 0x000a, 0x1198, 0x7008, 0x2048, 0xa800, 0x9005,
- 0x0158, 0x0006, 0x080c, 0x8f8c, 0x009e, 0xa807, 0x0000, 0x2900,
+ 0x0158, 0x0006, 0x080c, 0x8f84, 0x009e, 0xa807, 0x0000, 0x2900,
0x700a, 0x7010, 0x8001, 0x7012, 0x700f, 0x0000, 0x0008, 0x720e,
0x009e, 0x0005, 0x0006, 0x810b, 0x810b, 0x2100, 0x810b, 0x9100,
0x2008, 0x000e, 0x0005, 0x0006, 0x0026, 0x2100, 0x9005, 0x0158,
0x9092, 0x000c, 0x0240, 0x900e, 0x8108, 0x9082, 0x000c, 0x1de0,
0x002e, 0x000e, 0x0005, 0x900e, 0x0cd8, 0x2d00, 0x90b8, 0x0008,
- 0x2031, 0x8f46, 0x901e, 0x6808, 0x9005, 0x0108, 0x8318, 0x690c,
+ 0x2031, 0x8f3e, 0x901e, 0x6808, 0x9005, 0x0108, 0x8318, 0x690c,
0x910a, 0x0248, 0x0140, 0x8318, 0x6810, 0x9112, 0x0220, 0x0118,
0x8318, 0x2208, 0x0cd0, 0x233a, 0x6804, 0xd084, 0x2300, 0x2021,
0x0001, 0x1150, 0x9082, 0x0003, 0x0967, 0x0a67, 0x8420, 0x9082,
0x0007, 0x0967, 0x0a67, 0x0cd0, 0x9082, 0x0002, 0x0967, 0x0a67,
0x8420, 0x9082, 0x0005, 0x0967, 0x0a67, 0x0cd0, 0x6c1a, 0x0005,
- 0x0096, 0x0046, 0x0126, 0x2091, 0x8000, 0x2b00, 0x9080, 0x8fc4,
- 0x2005, 0x9005, 0x090c, 0x0d85, 0x2004, 0x90a0, 0x000a, 0x080c,
- 0x1072, 0x01d0, 0x2900, 0x7026, 0xa803, 0x0000, 0xa807, 0x0000,
- 0x080c, 0x1072, 0x0188, 0x7024, 0xa802, 0xa807, 0x0000, 0x2900,
+ 0x0096, 0x0046, 0x0126, 0x2091, 0x8000, 0x2b00, 0x9080, 0x8fbc,
+ 0x2005, 0x9005, 0x090c, 0x0d79, 0x2004, 0x90a0, 0x000a, 0x080c,
+ 0x1066, 0x01d0, 0x2900, 0x7026, 0xa803, 0x0000, 0xa807, 0x0000,
+ 0x080c, 0x1066, 0x0188, 0x7024, 0xa802, 0xa807, 0x0000, 0x2900,
0x7026, 0x94a2, 0x000a, 0x0110, 0x0208, 0x0c90, 0x9085, 0x0001,
0x012e, 0x004e, 0x009e, 0x0005, 0x7024, 0x9005, 0x0dc8, 0x2048,
- 0xac00, 0x080c, 0x108b, 0x2400, 0x0cc0, 0x0126, 0x2091, 0x8000,
+ 0xac00, 0x080c, 0x107f, 0x2400, 0x0cc0, 0x0126, 0x2091, 0x8000,
0x7024, 0x2048, 0x9005, 0x0130, 0xa800, 0x7026, 0xa803, 0x0000,
0xa807, 0x0000, 0x012e, 0x0005, 0x0126, 0x2091, 0x8000, 0x7024,
0xa802, 0x2900, 0x7026, 0x012e, 0x0005, 0x0096, 0x9e80, 0x0009,
- 0x2004, 0x9005, 0x0138, 0x2048, 0xa800, 0x0006, 0x080c, 0x108b,
+ 0x2004, 0x9005, 0x0138, 0x2048, 0xa800, 0x0006, 0x080c, 0x107f,
0x000e, 0x0cb8, 0x009e, 0x0005, 0x0096, 0x7008, 0x9005, 0x0138,
- 0x2048, 0xa800, 0x0006, 0x080c, 0x108b, 0x000e, 0x0cb8, 0x9006,
+ 0x2048, 0xa800, 0x0006, 0x080c, 0x107f, 0x000e, 0x0cb8, 0x9006,
0x7002, 0x700a, 0x7006, 0x700e, 0x701a, 0x701e, 0x7022, 0x702a,
0x7026, 0x702e, 0x009e, 0x0005, 0x1a72, 0x0000, 0x0000, 0x0000,
0x1932, 0x0000, 0x0000, 0x0000, 0x1888, 0x0000, 0x0000, 0x0000,
0x1877, 0x0000, 0x0000, 0x0000, 0x00e6, 0x00c6, 0x00b6, 0x00a6,
- 0xa8a8, 0x2040, 0x2071, 0x1877, 0x080c, 0x90e8, 0xa067, 0x0023,
- 0x6010, 0x905d, 0x0904, 0x90bd, 0xb814, 0xa06e, 0xb910, 0xa172,
+ 0xa8a8, 0x2040, 0x2071, 0x1877, 0x080c, 0x90e0, 0xa067, 0x0023,
+ 0x6010, 0x905d, 0x0904, 0x90b5, 0xb814, 0xa06e, 0xb910, 0xa172,
0xb9a0, 0xa176, 0x2001, 0x0003, 0xa07e, 0xa834, 0xa082, 0xa07b,
0x0000, 0xa898, 0x9005, 0x0118, 0xa078, 0xc085, 0xa07a, 0x2858,
- 0x2031, 0x0018, 0xa068, 0x908a, 0x0019, 0x1a0c, 0x0d85, 0x2020,
+ 0x2031, 0x0018, 0xa068, 0x908a, 0x0019, 0x1a0c, 0x0d79, 0x2020,
0x2050, 0x2940, 0xa864, 0x90bc, 0x00ff, 0x908c, 0x000f, 0x91e0,
- 0x1ee2, 0x2c65, 0x9786, 0x0024, 0x2c05, 0x1590, 0x908a, 0x0036,
- 0x1a0c, 0x0d85, 0x9082, 0x001b, 0x0002, 0x9028, 0x9028, 0x902a,
- 0x9028, 0x9028, 0x9028, 0x902c, 0x9028, 0x9028, 0x9028, 0x902e,
- 0x9028, 0x9028, 0x9028, 0x9030, 0x9028, 0x9028, 0x9028, 0x9032,
- 0x9028, 0x9028, 0x9028, 0x9034, 0x9028, 0x9028, 0x9028, 0x9036,
- 0x080c, 0x0d85, 0xa180, 0x04b8, 0xa190, 0x04a8, 0xa1a0, 0x0498,
+ 0x1ede, 0x2c65, 0x9786, 0x0024, 0x2c05, 0x1590, 0x908a, 0x0036,
+ 0x1a0c, 0x0d79, 0x9082, 0x001b, 0x0002, 0x9020, 0x9020, 0x9022,
+ 0x9020, 0x9020, 0x9020, 0x9024, 0x9020, 0x9020, 0x9020, 0x9026,
+ 0x9020, 0x9020, 0x9020, 0x9028, 0x9020, 0x9020, 0x9020, 0x902a,
+ 0x9020, 0x9020, 0x9020, 0x902c, 0x9020, 0x9020, 0x9020, 0x902e,
+ 0x080c, 0x0d79, 0xa180, 0x04b8, 0xa190, 0x04a8, 0xa1a0, 0x0498,
0xa1b0, 0x0488, 0xa1c0, 0x0478, 0xa1d0, 0x0468, 0xa1e0, 0x0458,
- 0x908a, 0x0034, 0x1a0c, 0x0d85, 0x9082, 0x001b, 0x0002, 0x905a,
- 0x9058, 0x9058, 0x9058, 0x9058, 0x9058, 0x905c, 0x9058, 0x9058,
- 0x9058, 0x9058, 0x9058, 0x905e, 0x9058, 0x9058, 0x9058, 0x9058,
- 0x9058, 0x9060, 0x9058, 0x9058, 0x9058, 0x9058, 0x9058, 0x9062,
- 0x080c, 0x0d85, 0xa180, 0x0038, 0xa198, 0x0028, 0xa1b0, 0x0018,
- 0xa1c8, 0x0008, 0xa1e0, 0x2600, 0x0002, 0x907e, 0x9080, 0x9082,
- 0x9084, 0x9086, 0x9088, 0x908a, 0x908c, 0x908e, 0x9090, 0x9092,
- 0x9094, 0x9096, 0x9098, 0x909a, 0x909c, 0x909e, 0x90a0, 0x90a2,
- 0x90a4, 0x90a6, 0x90a8, 0x90aa, 0x90ac, 0x90ae, 0x080c, 0x0d85,
+ 0x908a, 0x0034, 0x1a0c, 0x0d79, 0x9082, 0x001b, 0x0002, 0x9052,
+ 0x9050, 0x9050, 0x9050, 0x9050, 0x9050, 0x9054, 0x9050, 0x9050,
+ 0x9050, 0x9050, 0x9050, 0x9056, 0x9050, 0x9050, 0x9050, 0x9050,
+ 0x9050, 0x9058, 0x9050, 0x9050, 0x9050, 0x9050, 0x9050, 0x905a,
+ 0x080c, 0x0d79, 0xa180, 0x0038, 0xa198, 0x0028, 0xa1b0, 0x0018,
+ 0xa1c8, 0x0008, 0xa1e0, 0x2600, 0x0002, 0x9076, 0x9078, 0x907a,
+ 0x907c, 0x907e, 0x9080, 0x9082, 0x9084, 0x9086, 0x9088, 0x908a,
+ 0x908c, 0x908e, 0x9090, 0x9092, 0x9094, 0x9096, 0x9098, 0x909a,
+ 0x909c, 0x909e, 0x90a0, 0x90a2, 0x90a4, 0x90a6, 0x080c, 0x0d79,
0xb9e2, 0x0468, 0xb9de, 0x0458, 0xb9da, 0x0448, 0xb9d6, 0x0438,
0xb9d2, 0x0428, 0xb9ce, 0x0418, 0xb9ca, 0x0408, 0xb9c6, 0x00f8,
0xb9c2, 0x00e8, 0xb9be, 0x00d8, 0xb9ba, 0x00c8, 0xb9b6, 0x00b8,
0xb9b2, 0x00a8, 0xb9ae, 0x0098, 0xb9aa, 0x0088, 0xb9a6, 0x0078,
0xb9a2, 0x0068, 0xb99e, 0x0058, 0xb99a, 0x0048, 0xb996, 0x0038,
0xb992, 0x0028, 0xb98e, 0x0018, 0xb98a, 0x0008, 0xb986, 0x8631,
- 0x8421, 0x0130, 0x080c, 0x1eb8, 0x090c, 0x0d85, 0x0804, 0x9002,
+ 0x8421, 0x0130, 0x080c, 0x1eb4, 0x090c, 0x0d79, 0x0804, 0x8ffa,
0x00ae, 0x00be, 0x00ce, 0x00ee, 0x0005, 0xa86c, 0xa06e, 0xa870,
- 0xa072, 0xa077, 0x00ff, 0x9006, 0x0804, 0x8fe4, 0x0006, 0x0016,
+ 0xa072, 0xa077, 0x00ff, 0x9006, 0x0804, 0x8fdc, 0x0006, 0x0016,
0x00b6, 0x6010, 0x2058, 0xb810, 0x9005, 0x01b0, 0x2001, 0x1926,
0x2004, 0x9005, 0x0188, 0x2001, 0x1800, 0x2004, 0x9086, 0x0003,
0x1158, 0x0036, 0x0046, 0xbba0, 0x2021, 0x0004, 0x2011, 0x8014,
- 0x080c, 0x4c2e, 0x004e, 0x003e, 0x00be, 0x001e, 0x000e, 0x0005,
+ 0x080c, 0x4c28, 0x004e, 0x003e, 0x00be, 0x001e, 0x000e, 0x0005,
0x9016, 0x710c, 0xa834, 0x910a, 0xa936, 0x7008, 0x9005, 0x0120,
0x8210, 0x910a, 0x0238, 0x0130, 0x7010, 0x8210, 0x910a, 0x0210,
0x0108, 0x0cd8, 0xaa8a, 0xa26a, 0x0005, 0x00f6, 0x00d6, 0x0036,
@@ -4438,90 +4425,90 @@ unsigned short risc_code01[] = {
0x0202, 0xa001, 0xa001, 0x7818, 0xd094, 0x1da0, 0xb8ac, 0x9005,
0x01b8, 0x2068, 0x2079, 0x0000, 0x2c08, 0x911e, 0x1118, 0x680c,
0xb8ae, 0x0060, 0x9106, 0x0140, 0x2d00, 0x2078, 0x680c, 0x9005,
- 0x090c, 0x0d85, 0x2068, 0x0cb0, 0x6b0c, 0x7b0e, 0x600f, 0x0000,
+ 0x090c, 0x0d79, 0x2068, 0x0cb0, 0x6b0c, 0x7b0e, 0x600f, 0x0000,
0x2079, 0x0300, 0x781b, 0x0200, 0x003e, 0x00de, 0x00fe, 0x0005,
0x00e6, 0x00d6, 0x0096, 0x00c6, 0x0036, 0x0126, 0x2091, 0x8000,
0x0156, 0x20a9, 0x01ff, 0x2071, 0x0300, 0x701b, 0x0200, 0x7018,
- 0xd094, 0x0110, 0x1f04, 0x913d, 0x701b, 0x0202, 0xa001, 0xa001,
+ 0xd094, 0x0110, 0x1f04, 0x9135, 0x701b, 0x0202, 0xa001, 0xa001,
0x7018, 0xd094, 0x1d90, 0xb8ac, 0x9005, 0x01e8, 0x2060, 0x600c,
0xb8ae, 0x6024, 0xc08d, 0x6026, 0x6003, 0x0004, 0x601b, 0x0000,
0x6013, 0x0000, 0x601f, 0x0101, 0x6014, 0x2048, 0xa88b, 0x0000,
- 0xa8a8, 0xa8ab, 0x0000, 0x904d, 0x090c, 0x0d85, 0x080c, 0x108b,
- 0x080c, 0x8cf9, 0x0c00, 0x2071, 0x0300, 0x701b, 0x0200, 0x015e,
+ 0xa8a8, 0xa8ab, 0x0000, 0x904d, 0x090c, 0x0d79, 0x080c, 0x107f,
+ 0x080c, 0x8cf1, 0x0c00, 0x2071, 0x0300, 0x701b, 0x0200, 0x015e,
0x012e, 0x003e, 0x00ce, 0x009e, 0x00de, 0x00ee, 0x0005, 0x00c6,
- 0x00b6, 0x0016, 0x0006, 0x0156, 0x080c, 0x26a2, 0x015e, 0x11b0,
- 0x080c, 0x671e, 0x190c, 0x0d85, 0x000e, 0x001e, 0xb912, 0xb816,
- 0x080c, 0xaed8, 0x0140, 0x2b00, 0x6012, 0x6023, 0x0001, 0x2009,
- 0x0001, 0x080c, 0xafcc, 0x00be, 0x00ce, 0x0005, 0x000e, 0x001e,
- 0x0cd0, 0x0066, 0x6000, 0x90b2, 0x0016, 0x1a0c, 0x0d85, 0x0013,
- 0x006e, 0x0005, 0x91b2, 0x91b2, 0x91b2, 0x91b4, 0x91fd, 0x91b2,
- 0x91b2, 0x91b2, 0x9264, 0x91b2, 0x929c, 0x91b2, 0x91b2, 0x91b2,
- 0x91b2, 0x91b2, 0x080c, 0x0d85, 0x9182, 0x0040, 0x0002, 0x91c7,
- 0x91c7, 0x91c7, 0x91c7, 0x91c7, 0x91c7, 0x91c7, 0x91c7, 0x91c7,
- 0x91c9, 0x91da, 0x91c7, 0x91c7, 0x91c7, 0x91c7, 0x91eb, 0x080c,
- 0x0d85, 0x0096, 0x6114, 0x2148, 0xa87b, 0x0000, 0x6010, 0x00b6,
- 0x2058, 0xb8bb, 0x0500, 0x00be, 0x080c, 0x6d18, 0x080c, 0xaf2e,
- 0x009e, 0x0005, 0x080c, 0x9859, 0x00d6, 0x6114, 0x080c, 0xcc16,
- 0x0130, 0x0096, 0x6114, 0x2148, 0x080c, 0x6f19, 0x009e, 0x00de,
- 0x080c, 0xaf2e, 0x0005, 0x080c, 0x9859, 0x080c, 0x3310, 0x6114,
- 0x0096, 0x2148, 0x080c, 0xcc16, 0x0120, 0xa87b, 0x0029, 0x080c,
- 0x6f19, 0x009e, 0x080c, 0xaf2e, 0x0005, 0x601b, 0x0000, 0x9182,
- 0x0040, 0x0096, 0x0002, 0x9218, 0x9218, 0x9218, 0x9218, 0x9218,
- 0x9218, 0x9218, 0x9218, 0x921a, 0x9218, 0x9218, 0x9218, 0x9260,
- 0x9218, 0x9218, 0x9218, 0x9218, 0x9218, 0x9218, 0x9221, 0x9218,
- 0x080c, 0x0d85, 0x6114, 0x2148, 0xa938, 0x918e, 0xffff, 0x0904,
- 0x9260, 0x6024, 0xd08c, 0x15c0, 0x00e6, 0x6114, 0x2148, 0x080c,
- 0x8fcc, 0x0096, 0xa8a8, 0x2048, 0x080c, 0x6cb0, 0x009e, 0xa8ab,
- 0x0000, 0x6010, 0x9005, 0x0128, 0x00b6, 0x2058, 0x080c, 0x90fd,
- 0x00be, 0xae88, 0x00b6, 0x2059, 0x0000, 0x080c, 0x8d02, 0x00be,
- 0x01e0, 0x2071, 0x193e, 0x080c, 0x8d49, 0x01b8, 0x9086, 0x0001,
+ 0x00b6, 0x0016, 0x0006, 0x0156, 0x080c, 0x26a1, 0x015e, 0x11b0,
+ 0x080c, 0x6718, 0x190c, 0x0d79, 0x000e, 0x001e, 0xb912, 0xb816,
+ 0x080c, 0xaef8, 0x0140, 0x2b00, 0x6012, 0x6023, 0x0001, 0x2009,
+ 0x0001, 0x080c, 0xafec, 0x00be, 0x00ce, 0x0005, 0x000e, 0x001e,
+ 0x0cd0, 0x0066, 0x6000, 0x90b2, 0x0010, 0x1a0c, 0x0d79, 0x0013,
+ 0x006e, 0x0005, 0x91aa, 0x91aa, 0x91aa, 0x91ac, 0x91f5, 0x91aa,
+ 0x91aa, 0x91aa, 0x925c, 0x91aa, 0x9294, 0x91aa, 0x91aa, 0x91aa,
+ 0x91aa, 0x91aa, 0x080c, 0x0d79, 0x9182, 0x0040, 0x0002, 0x91bf,
+ 0x91bf, 0x91bf, 0x91bf, 0x91bf, 0x91bf, 0x91bf, 0x91bf, 0x91bf,
+ 0x91c1, 0x91d2, 0x91bf, 0x91bf, 0x91bf, 0x91bf, 0x91e3, 0x080c,
+ 0x0d79, 0x0096, 0x6114, 0x2148, 0xa87b, 0x0000, 0x6010, 0x00b6,
+ 0x2058, 0xb8bb, 0x0500, 0x00be, 0x080c, 0x6d10, 0x080c, 0xaf4e,
+ 0x009e, 0x0005, 0x080c, 0x9851, 0x00d6, 0x6114, 0x080c, 0xcc33,
+ 0x0130, 0x0096, 0x6114, 0x2148, 0x080c, 0x6f11, 0x009e, 0x00de,
+ 0x080c, 0xaf4e, 0x0005, 0x080c, 0x9851, 0x080c, 0x32fb, 0x6114,
+ 0x0096, 0x2148, 0x080c, 0xcc33, 0x0120, 0xa87b, 0x0029, 0x080c,
+ 0x6f11, 0x009e, 0x080c, 0xaf4e, 0x0005, 0x601b, 0x0000, 0x9182,
+ 0x0040, 0x0096, 0x0002, 0x9210, 0x9210, 0x9210, 0x9210, 0x9210,
+ 0x9210, 0x9210, 0x9210, 0x9212, 0x9210, 0x9210, 0x9210, 0x9258,
+ 0x9210, 0x9210, 0x9210, 0x9210, 0x9210, 0x9210, 0x9219, 0x9210,
+ 0x080c, 0x0d79, 0x6114, 0x2148, 0xa938, 0x918e, 0xffff, 0x0904,
+ 0x9258, 0x6024, 0xd08c, 0x15c0, 0x00e6, 0x6114, 0x2148, 0x080c,
+ 0x8fc4, 0x0096, 0xa8a8, 0x2048, 0x080c, 0x6ca8, 0x009e, 0xa8ab,
+ 0x0000, 0x6010, 0x9005, 0x0128, 0x00b6, 0x2058, 0x080c, 0x90f5,
+ 0x00be, 0xae88, 0x00b6, 0x2059, 0x0000, 0x080c, 0x8cfa, 0x00be,
+ 0x01e0, 0x2071, 0x193e, 0x080c, 0x8d41, 0x01b8, 0x9086, 0x0001,
0x1128, 0x2001, 0x1948, 0x2004, 0x9005, 0x1178, 0x0096, 0x080c,
- 0x1059, 0x2900, 0x009e, 0x0148, 0xa8aa, 0x00f6, 0x2c78, 0x080c,
- 0x8cbd, 0x00fe, 0x00ee, 0x009e, 0x0005, 0x080c, 0x8cf9, 0x0cd0,
- 0x080c, 0x9318, 0x009e, 0x0005, 0x9182, 0x0040, 0x0096, 0x0002,
- 0x9278, 0x9278, 0x9278, 0x927a, 0x9278, 0x9278, 0x9278, 0x929a,
- 0x9278, 0x9278, 0x9278, 0x9278, 0x9278, 0x9278, 0x9278, 0x9278,
- 0x080c, 0x0d85, 0x6003, 0x0003, 0x6106, 0x6014, 0x2048, 0xa8ac,
+ 0x104d, 0x2900, 0x009e, 0x0148, 0xa8aa, 0x00f6, 0x2c78, 0x080c,
+ 0x8cb5, 0x00fe, 0x00ee, 0x009e, 0x0005, 0x080c, 0x8cf1, 0x0cd0,
+ 0x080c, 0x9310, 0x009e, 0x0005, 0x9182, 0x0040, 0x0096, 0x0002,
+ 0x9270, 0x9270, 0x9270, 0x9272, 0x9270, 0x9270, 0x9270, 0x9292,
+ 0x9270, 0x9270, 0x9270, 0x9270, 0x9270, 0x9270, 0x9270, 0x9270,
+ 0x080c, 0x0d79, 0x6003, 0x0003, 0x6106, 0x6014, 0x2048, 0xa8ac,
0xa836, 0xa8b0, 0xa83a, 0xa847, 0x0000, 0xa84b, 0x0000, 0xa884,
0x9092, 0x199a, 0x0210, 0x2001, 0x1999, 0x8003, 0x8013, 0x8213,
- 0x9210, 0x621a, 0x080c, 0x1c47, 0x2009, 0x8030, 0x080c, 0x946f,
- 0x009e, 0x0005, 0x080c, 0x0d85, 0x080c, 0x9859, 0x6114, 0x2148,
+ 0x9210, 0x621a, 0x080c, 0x1c43, 0x2009, 0x8030, 0x080c, 0x9467,
+ 0x009e, 0x0005, 0x080c, 0x0d79, 0x080c, 0x9851, 0x6114, 0x2148,
0xa87b, 0x0000, 0x6010, 0x00b6, 0x2058, 0xb8bb, 0x0500, 0x00be,
- 0x080c, 0x6f19, 0x080c, 0xaf2e, 0x009e, 0x0005, 0x080c, 0xaae0,
+ 0x080c, 0x6f11, 0x080c, 0xaf4e, 0x009e, 0x0005, 0x080c, 0xaaf7,
0x6144, 0xd1fc, 0x0120, 0xd1ac, 0x1110, 0x6003, 0x0003, 0x6000,
- 0x908a, 0x0016, 0x1a0c, 0x0d85, 0x0096, 0x0023, 0x009e, 0x080c,
- 0xaafc, 0x0005, 0x92d2, 0x92d2, 0x92d2, 0x92d4, 0x92e5, 0x92d2,
- 0x92d2, 0x92d2, 0x92d2, 0x92d2, 0x92d2, 0x92d2, 0x92d2, 0x92d2,
- 0x92d2, 0x92d2, 0x080c, 0x0d85, 0x080c, 0xacaf, 0x6114, 0x2148,
+ 0x908a, 0x0010, 0x1a0c, 0x0d79, 0x0096, 0x0023, 0x009e, 0x080c,
+ 0xab13, 0x0005, 0x92ca, 0x92ca, 0x92ca, 0x92cc, 0x92dd, 0x92ca,
+ 0x92ca, 0x92ca, 0x92ca, 0x92ca, 0x92ca, 0x92ca, 0x92ca, 0x92ca,
+ 0x92ca, 0x92ca, 0x080c, 0x0d79, 0x080c, 0xaccf, 0x6114, 0x2148,
0xa87b, 0x0006, 0x6010, 0x00b6, 0x2058, 0xb8bb, 0x0500, 0x00be,
- 0x080c, 0x6f19, 0x080c, 0xaf2e, 0x0005, 0x0491, 0x0005, 0x080c,
- 0xaae0, 0x6000, 0x6144, 0xd1fc, 0x0130, 0xd1ac, 0x1120, 0x6003,
- 0x0003, 0x2009, 0x0003, 0x908a, 0x0016, 0x1a0c, 0x0d85, 0x0096,
- 0x0033, 0x009e, 0x0106, 0x080c, 0xaafc, 0x010e, 0x0005, 0x930f,
- 0x930f, 0x930f, 0x9311, 0x9318, 0x930f, 0x930f, 0x930f, 0x930f,
- 0x930f, 0x930f, 0x930f, 0x930f, 0x930f, 0x930f, 0x930f, 0x080c,
- 0x0d85, 0x0036, 0x00e6, 0x080c, 0xacaf, 0x00ee, 0x003e, 0x0005,
+ 0x080c, 0x6f11, 0x080c, 0xaf4e, 0x0005, 0x0491, 0x0005, 0x080c,
+ 0xaaf7, 0x6000, 0x6144, 0xd1fc, 0x0130, 0xd1ac, 0x1120, 0x6003,
+ 0x0003, 0x2009, 0x0003, 0x908a, 0x0010, 0x1a0c, 0x0d79, 0x0096,
+ 0x0033, 0x009e, 0x0106, 0x080c, 0xab13, 0x010e, 0x0005, 0x9307,
+ 0x9307, 0x9307, 0x9309, 0x9310, 0x9307, 0x9307, 0x9307, 0x9307,
+ 0x9307, 0x9307, 0x9307, 0x9307, 0x9307, 0x9307, 0x9307, 0x080c,
+ 0x0d79, 0x0036, 0x00e6, 0x080c, 0xaccf, 0x00ee, 0x003e, 0x0005,
0x6024, 0xd08c, 0x11f0, 0x00f6, 0x00e6, 0x601b, 0x0000, 0x6014,
- 0x2048, 0x6010, 0x9005, 0x0128, 0x00b6, 0x2058, 0x080c, 0x90fd,
- 0x00be, 0x2071, 0x193e, 0x080c, 0x8d49, 0x0160, 0x2001, 0x187f,
- 0x2004, 0xa88a, 0x2031, 0x0000, 0x2c78, 0x080c, 0x8cbd, 0x00ee,
+ 0x2048, 0x6010, 0x9005, 0x0128, 0x00b6, 0x2058, 0x080c, 0x90f5,
+ 0x00be, 0x2071, 0x193e, 0x080c, 0x8d41, 0x0160, 0x2001, 0x187f,
+ 0x2004, 0xa88a, 0x2031, 0x0000, 0x2c78, 0x080c, 0x8cb5, 0x00ee,
0x00fe, 0x0005, 0x0096, 0xa88b, 0x0000, 0xa8a8, 0x2048, 0x080c,
- 0x108b, 0x009e, 0xa8ab, 0x0000, 0x080c, 0x8cf9, 0x0c80, 0x0000,
+ 0x107f, 0x009e, 0xa8ab, 0x0000, 0x080c, 0x8cf1, 0x0c80, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x187a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0126,
0x2091, 0x8000, 0x0036, 0x0046, 0x20a9, 0x0010, 0x9006, 0x8004,
- 0x8086, 0x818e, 0x1208, 0x9200, 0x1f04, 0x9360, 0x8086, 0x818e,
+ 0x8086, 0x818e, 0x1208, 0x9200, 0x1f04, 0x9358, 0x8086, 0x818e,
0x004e, 0x003e, 0x012e, 0x0005, 0x0126, 0x2091, 0x8000, 0x0076,
0x0156, 0x20a9, 0x0010, 0x9005, 0x01c8, 0x911a, 0x12b8, 0x8213,
- 0x818d, 0x0228, 0x911a, 0x1220, 0x1f04, 0x9377, 0x0028, 0x911a,
- 0x2308, 0x8210, 0x1f04, 0x9377, 0x0006, 0x3200, 0x9084, 0xefff,
+ 0x818d, 0x0228, 0x911a, 0x1220, 0x1f04, 0x936f, 0x0028, 0x911a,
+ 0x2308, 0x8210, 0x1f04, 0x936f, 0x0006, 0x3200, 0x9084, 0xefff,
0x2080, 0x000e, 0x015e, 0x007e, 0x012e, 0x0005, 0x0006, 0x3200,
0x9085, 0x1000, 0x0ca8, 0x0126, 0x2091, 0x2800, 0x2079, 0x19e9,
0x012e, 0x00d6, 0x2069, 0x19e9, 0x6803, 0x0005, 0x0156, 0x0146,
- 0x01d6, 0x20e9, 0x0000, 0x2069, 0x0200, 0x080c, 0xa8d5, 0x04c9,
- 0x080c, 0xa8c0, 0x04b1, 0x080c, 0xa8c3, 0x0499, 0x080c, 0xa8c6,
- 0x0481, 0x080c, 0xa8c9, 0x0469, 0x080c, 0xa8cc, 0x0451, 0x080c,
- 0xa8cf, 0x0439, 0x080c, 0xa8d2, 0x0421, 0x01de, 0x014e, 0x015e,
+ 0x01d6, 0x20e9, 0x0000, 0x2069, 0x0200, 0x080c, 0xa8ec, 0x04c9,
+ 0x080c, 0xa8d7, 0x04b1, 0x080c, 0xa8da, 0x0499, 0x080c, 0xa8dd,
+ 0x0481, 0x080c, 0xa8e0, 0x0469, 0x080c, 0xa8e3, 0x0451, 0x080c,
+ 0xa8e6, 0x0439, 0x080c, 0xa8e9, 0x0421, 0x01de, 0x014e, 0x015e,
0x6857, 0x0000, 0x00f6, 0x2079, 0x0380, 0x0419, 0x7807, 0x0003,
0x7803, 0x0000, 0x7803, 0x0001, 0x2069, 0x0004, 0x2d04, 0x9084,
0xfffe, 0x9085, 0x8000, 0x206a, 0x2069, 0x0100, 0x6828, 0x9084,
@@ -4530,842 +4517,847 @@ unsigned short risc_code01[] = {
0x0005, 0x00c6, 0x7803, 0x0000, 0x9006, 0x7827, 0x0030, 0x782b,
0x0400, 0x7827, 0x0031, 0x782b, 0x1af7, 0x781f, 0xff00, 0x781b,
0xff00, 0x2061, 0x1aec, 0x602f, 0x19e9, 0x6033, 0x1800, 0x6037,
- 0x1a05, 0x603b, 0x1ee2, 0x603f, 0x1ef2, 0x6042, 0x6047, 0x1ac2,
+ 0x1a05, 0x603b, 0x1ede, 0x603f, 0x1eee, 0x6042, 0x6047, 0x1ac2,
0x00ce, 0x0005, 0x2001, 0x0382, 0x2004, 0x9084, 0x0007, 0x9086,
0x0001, 0x01b0, 0x00c6, 0x6146, 0x600f, 0x0000, 0x2c08, 0x2061,
0x19e9, 0x602c, 0x8000, 0x602e, 0x601c, 0x9005, 0x0130, 0x9080,
0x0003, 0x2102, 0x611e, 0x00ce, 0x0005, 0x6122, 0x611e, 0x0cd8,
- 0x6146, 0x2c08, 0x2001, 0x0012, 0x080c, 0xaad1, 0x0005, 0x0016,
+ 0x6146, 0x2c08, 0x2001, 0x0012, 0x080c, 0xaae8, 0x0005, 0x0016,
0x2009, 0x8020, 0x6146, 0x2c08, 0x2001, 0x0382, 0x2004, 0x9084,
- 0x0007, 0x9086, 0x0001, 0x1128, 0x2001, 0x0019, 0x080c, 0xaad1,
+ 0x0007, 0x9086, 0x0001, 0x1128, 0x2001, 0x0019, 0x080c, 0xaae8,
0x0088, 0x00c6, 0x2061, 0x19e9, 0x602c, 0x8000, 0x602e, 0x600c,
0x9005, 0x0128, 0x9080, 0x0003, 0x2102, 0x610e, 0x0010, 0x6112,
0x610e, 0x00ce, 0x001e, 0x0005, 0x2001, 0x0382, 0x2004, 0x9084,
0x0007, 0x9086, 0x0001, 0x0198, 0x00c6, 0x6146, 0x600f, 0x0000,
0x2c08, 0x2061, 0x19e9, 0x6044, 0x9005, 0x0130, 0x9080, 0x0003,
0x2102, 0x6146, 0x00ce, 0x0005, 0x614a, 0x6146, 0x0cd8, 0x6146,
- 0x600f, 0x0000, 0x2c08, 0x2001, 0x0013, 0x080c, 0xaad1, 0x0005,
- 0x6044, 0xd0dc, 0x0110, 0x080c, 0xa56e, 0x0005, 0x00f6, 0x00e6,
+ 0x600f, 0x0000, 0x2c08, 0x2001, 0x0013, 0x080c, 0xaae8, 0x0005,
+ 0x6044, 0xd0dc, 0x0110, 0x080c, 0xa585, 0x0005, 0x00f6, 0x00e6,
0x00d6, 0x00c6, 0x00b6, 0x0096, 0x0076, 0x0066, 0x0056, 0x0036,
0x0026, 0x0016, 0x0006, 0x0126, 0x902e, 0x2071, 0x19e9, 0x7648,
- 0x2660, 0x2678, 0x2091, 0x8000, 0x8cff, 0x0904, 0x9502, 0x9c86,
- 0x1b56, 0x0904, 0x94fd, 0x6010, 0x2058, 0xb8a0, 0x9206, 0x1904,
- 0x94fd, 0x87ff, 0x0120, 0x605c, 0x9106, 0x1904, 0x94fd, 0x704c,
- 0x9c06, 0x1188, 0x0036, 0x2019, 0x0001, 0x080c, 0xa380, 0x703f,
- 0x0000, 0x9006, 0x704e, 0x706a, 0x7052, 0x706e, 0x080c, 0xadc0,
- 0x003e, 0x2029, 0x0001, 0x080c, 0x9478, 0x7048, 0x9c36, 0x1110,
+ 0x2660, 0x2678, 0x2091, 0x8000, 0x8cff, 0x0904, 0x94fa, 0x9c86,
+ 0x1b56, 0x0904, 0x94f5, 0x6010, 0x2058, 0xb8a0, 0x9206, 0x1904,
+ 0x94f5, 0x87ff, 0x0120, 0x605c, 0x9106, 0x1904, 0x94f5, 0x704c,
+ 0x9c06, 0x1188, 0x0036, 0x2019, 0x0001, 0x080c, 0xa391, 0x703f,
+ 0x0000, 0x9006, 0x704e, 0x706a, 0x7052, 0x706e, 0x080c, 0xade0,
+ 0x003e, 0x2029, 0x0001, 0x080c, 0x9470, 0x7048, 0x9c36, 0x1110,
0x660c, 0x764a, 0x7044, 0x9c36, 0x1140, 0x2c00, 0x9f36, 0x0118,
0x2f00, 0x7046, 0x0010, 0x7047, 0x0000, 0x660c, 0x0066, 0x2c00,
0x9f06, 0x0110, 0x7e0e, 0x0008, 0x2678, 0x600f, 0x0000, 0x080c,
- 0xcc16, 0x01f0, 0x6014, 0x2048, 0x6020, 0x9086, 0x0003, 0x1588,
- 0x6004, 0x9086, 0x0040, 0x090c, 0xa56e, 0xa867, 0x0103, 0xab7a,
- 0xa877, 0x0000, 0x0016, 0x0036, 0x0076, 0x080c, 0xcf1b, 0x080c,
- 0xea83, 0x080c, 0x6f19, 0x007e, 0x003e, 0x001e, 0x080c, 0xce07,
- 0x080c, 0xaf69, 0x00ce, 0x0804, 0x9494, 0x2c78, 0x600c, 0x2060,
- 0x0804, 0x9494, 0x012e, 0x000e, 0x001e, 0x002e, 0x003e, 0x005e,
+ 0xcc33, 0x01f0, 0x6014, 0x2048, 0x6020, 0x9086, 0x0003, 0x1588,
+ 0x6004, 0x9086, 0x0040, 0x090c, 0xa585, 0xa867, 0x0103, 0xab7a,
+ 0xa877, 0x0000, 0x0016, 0x0036, 0x0076, 0x080c, 0xcf38, 0x080c,
+ 0xeaee, 0x080c, 0x6f11, 0x007e, 0x003e, 0x001e, 0x080c, 0xce24,
+ 0x080c, 0xaf89, 0x00ce, 0x0804, 0x948c, 0x2c78, 0x600c, 0x2060,
+ 0x0804, 0x948c, 0x012e, 0x000e, 0x001e, 0x002e, 0x003e, 0x005e,
0x006e, 0x007e, 0x009e, 0x00be, 0x00ce, 0x00de, 0x00ee, 0x00fe,
0x0005, 0x6020, 0x9086, 0x0006, 0x1158, 0x0016, 0x0036, 0x0076,
- 0x080c, 0xea83, 0x080c, 0xe6cd, 0x007e, 0x003e, 0x001e, 0x08c0,
+ 0x080c, 0xeaee, 0x080c, 0xe738, 0x007e, 0x003e, 0x001e, 0x08c0,
0x6020, 0x9086, 0x0009, 0x1168, 0xa87b, 0x0006, 0x0016, 0x0036,
- 0x0076, 0x080c, 0x6f19, 0x080c, 0xaf2e, 0x007e, 0x003e, 0x001e,
- 0x0848, 0x6020, 0x9086, 0x000a, 0x0904, 0x94e7, 0x0804, 0x94e0,
+ 0x0076, 0x080c, 0x6f11, 0x080c, 0xaf4e, 0x007e, 0x003e, 0x001e,
+ 0x0848, 0x6020, 0x9086, 0x000a, 0x0904, 0x94df, 0x0804, 0x94d8,
0x0006, 0x0066, 0x0096, 0x00c6, 0x00d6, 0x00f6, 0x9036, 0x0126,
- 0x2091, 0x8000, 0x2079, 0x19e9, 0x7848, 0x9065, 0x0904, 0x95a1,
+ 0x2091, 0x8000, 0x2079, 0x19e9, 0x7848, 0x9065, 0x0904, 0x9599,
0x600c, 0x0006, 0x600f, 0x0000, 0x784c, 0x9c06, 0x11b0, 0x0036,
- 0x2019, 0x0001, 0x080c, 0xa380, 0x783f, 0x0000, 0x901e, 0x7b4e,
- 0x7b6a, 0x7b52, 0x7b6e, 0x080c, 0xadc0, 0x003e, 0x000e, 0x9005,
+ 0x2019, 0x0001, 0x080c, 0xa391, 0x783f, 0x0000, 0x901e, 0x7b4e,
+ 0x7b6a, 0x7b52, 0x7b6e, 0x080c, 0xade0, 0x003e, 0x000e, 0x9005,
0x1118, 0x600c, 0x600f, 0x0000, 0x0006, 0x9c86, 0x1b56, 0x05b0,
- 0x00e6, 0x2f70, 0x080c, 0x9478, 0x00ee, 0x080c, 0xcc16, 0x0548,
+ 0x00e6, 0x2f70, 0x080c, 0x9470, 0x00ee, 0x080c, 0xcc33, 0x0548,
0x6014, 0x2048, 0x6020, 0x9086, 0x0003, 0x15a8, 0x3e08, 0x918e,
0x0002, 0x1188, 0x6010, 0x9005, 0x0170, 0x00b6, 0x2058, 0xb800,
0x00be, 0xd0bc, 0x0140, 0x6048, 0x9005, 0x11c0, 0x2001, 0x1989,
- 0x2004, 0x604a, 0x0098, 0x6004, 0x9086, 0x0040, 0x090c, 0xa56e,
- 0xa867, 0x0103, 0xab7a, 0xa877, 0x0000, 0x080c, 0x6f0d, 0x080c,
- 0xce07, 0x6044, 0xc0fc, 0x6046, 0x080c, 0xaf69, 0x000e, 0x0804,
- 0x9545, 0x7e4a, 0x7e46, 0x012e, 0x00fe, 0x00de, 0x00ce, 0x009e,
+ 0x2004, 0x604a, 0x0098, 0x6004, 0x9086, 0x0040, 0x090c, 0xa585,
+ 0xa867, 0x0103, 0xab7a, 0xa877, 0x0000, 0x080c, 0x6f05, 0x080c,
+ 0xce24, 0x6044, 0xc0fc, 0x6046, 0x080c, 0xaf89, 0x000e, 0x0804,
+ 0x953d, 0x7e4a, 0x7e46, 0x012e, 0x00fe, 0x00de, 0x00ce, 0x009e,
0x006e, 0x000e, 0x0005, 0x6020, 0x9086, 0x0006, 0x1118, 0x080c,
- 0xe6cd, 0x0c38, 0x6020, 0x9086, 0x0009, 0x1130, 0xab7a, 0x080c,
- 0x6f19, 0x080c, 0xaf2e, 0x0c10, 0x6020, 0x9086, 0x000a, 0x0990,
- 0x0850, 0x0016, 0x0026, 0x0086, 0x9046, 0x00a9, 0x080c, 0x96b4,
+ 0xe738, 0x0c38, 0x6020, 0x9086, 0x0009, 0x1130, 0xab7a, 0x080c,
+ 0x6f11, 0x080c, 0xaf4e, 0x0c10, 0x6020, 0x9086, 0x000a, 0x0990,
+ 0x0850, 0x0016, 0x0026, 0x0086, 0x9046, 0x00a9, 0x080c, 0x96ac,
0x008e, 0x002e, 0x001e, 0x0005, 0x00f6, 0x0126, 0x2079, 0x19e9,
- 0x2091, 0x8000, 0x080c, 0x96fd, 0x080c, 0x9793, 0x080c, 0x6916,
+ 0x2091, 0x8000, 0x080c, 0x96f5, 0x080c, 0x978b, 0x080c, 0x690e,
0x012e, 0x00fe, 0x0005, 0x00b6, 0x0096, 0x00f6, 0x00e6, 0x00d6,
0x00c6, 0x0066, 0x0016, 0x0006, 0x0126, 0x2091, 0x8000, 0x2071,
- 0x19e9, 0x7620, 0x2660, 0x2678, 0x8cff, 0x0904, 0x9679, 0x6010,
- 0x2058, 0xb8a0, 0x9206, 0x1904, 0x9674, 0x88ff, 0x0120, 0x605c,
- 0x9106, 0x1904, 0x9674, 0x7030, 0x9c06, 0x1580, 0x2069, 0x0100,
- 0x6820, 0xd0a4, 0x0110, 0xd0cc, 0x1508, 0x080c, 0x88ec, 0x080c,
- 0xa08a, 0x68c3, 0x0000, 0x080c, 0xa56e, 0x7033, 0x0000, 0x0036,
+ 0x19e9, 0x7620, 0x2660, 0x2678, 0x8cff, 0x0904, 0x9671, 0x6010,
+ 0x2058, 0xb8a0, 0x9206, 0x1904, 0x966c, 0x88ff, 0x0120, 0x605c,
+ 0x9106, 0x1904, 0x966c, 0x7030, 0x9c06, 0x1580, 0x2069, 0x0100,
+ 0x6820, 0xd0a4, 0x0110, 0xd0cc, 0x1508, 0x080c, 0x88e4, 0x080c,
+ 0xa09b, 0x68c3, 0x0000, 0x080c, 0xa585, 0x7033, 0x0000, 0x0036,
0x2069, 0x0140, 0x6b04, 0x9384, 0x1000, 0x0138, 0x2001, 0x0100,
- 0x080c, 0x2abb, 0x9006, 0x080c, 0x2abb, 0x2069, 0x0100, 0x6824,
+ 0x080c, 0x2aa2, 0x9006, 0x080c, 0x2aa2, 0x2069, 0x0100, 0x6824,
0xd084, 0x0110, 0x6827, 0x0001, 0x003e, 0x0040, 0x7008, 0xc0ad,
- 0x700a, 0x6003, 0x0009, 0x630a, 0x0804, 0x9674, 0x7020, 0x9c36,
+ 0x700a, 0x6003, 0x0009, 0x630a, 0x0804, 0x966c, 0x7020, 0x9c36,
0x1110, 0x660c, 0x7622, 0x701c, 0x9c36, 0x1140, 0x2c00, 0x9f36,
0x0118, 0x2f00, 0x701e, 0x0010, 0x701f, 0x0000, 0x660c, 0x0066,
0x2c00, 0x9f06, 0x0110, 0x7e0e, 0x0008, 0x2678, 0x600f, 0x0000,
- 0x6044, 0xc0fc, 0x6046, 0x6014, 0x2048, 0x080c, 0xcc16, 0x01e8,
- 0x6020, 0x9086, 0x0003, 0x1580, 0x080c, 0xce2d, 0x1118, 0x080c,
- 0xb91f, 0x0098, 0xa867, 0x0103, 0xab7a, 0xa877, 0x0000, 0x0016,
- 0x0036, 0x0086, 0x080c, 0xcf1b, 0x080c, 0xea83, 0x080c, 0x6f19,
- 0x008e, 0x003e, 0x001e, 0x080c, 0xce07, 0x080c, 0xaf69, 0x080c,
- 0xa441, 0x00ce, 0x0804, 0x95ec, 0x2c78, 0x600c, 0x2060, 0x0804,
- 0x95ec, 0x012e, 0x000e, 0x001e, 0x006e, 0x00ce, 0x00de, 0x00ee,
+ 0x6044, 0xc0fc, 0x6046, 0x6014, 0x2048, 0x080c, 0xcc33, 0x01e8,
+ 0x6020, 0x9086, 0x0003, 0x1580, 0x080c, 0xce4a, 0x1118, 0x080c,
+ 0xb93c, 0x0098, 0xa867, 0x0103, 0xab7a, 0xa877, 0x0000, 0x0016,
+ 0x0036, 0x0086, 0x080c, 0xcf38, 0x080c, 0xeaee, 0x080c, 0x6f11,
+ 0x008e, 0x003e, 0x001e, 0x080c, 0xce24, 0x080c, 0xaf89, 0x080c,
+ 0xa458, 0x00ce, 0x0804, 0x95e4, 0x2c78, 0x600c, 0x2060, 0x0804,
+ 0x95e4, 0x012e, 0x000e, 0x001e, 0x006e, 0x00ce, 0x00de, 0x00ee,
0x00fe, 0x009e, 0x00be, 0x0005, 0x6020, 0x9086, 0x0006, 0x1158,
- 0x0016, 0x0036, 0x0086, 0x080c, 0xea83, 0x080c, 0xe6cd, 0x008e,
- 0x003e, 0x001e, 0x08d0, 0x080c, 0xb91f, 0x6020, 0x9086, 0x0002,
- 0x1160, 0x6004, 0x0006, 0x9086, 0x0085, 0x000e, 0x0904, 0x965a,
- 0x9086, 0x008b, 0x0904, 0x965a, 0x0840, 0x6020, 0x9086, 0x0005,
+ 0x0016, 0x0036, 0x0086, 0x080c, 0xeaee, 0x080c, 0xe738, 0x008e,
+ 0x003e, 0x001e, 0x08d0, 0x080c, 0xb93c, 0x6020, 0x9086, 0x0002,
+ 0x1160, 0x6004, 0x0006, 0x9086, 0x0085, 0x000e, 0x0904, 0x9652,
+ 0x9086, 0x008b, 0x0904, 0x9652, 0x0840, 0x6020, 0x9086, 0x0005,
0x1920, 0x6004, 0x0006, 0x9086, 0x0085, 0x000e, 0x09c8, 0x9086,
- 0x008b, 0x09b0, 0x0804, 0x966d, 0x0006, 0x00f6, 0x00e6, 0x0096,
+ 0x008b, 0x09b0, 0x0804, 0x9665, 0x0006, 0x00f6, 0x00e6, 0x0096,
0x00b6, 0x00c6, 0x0066, 0x0016, 0x0126, 0x2091, 0x8000, 0x9280,
0x1000, 0x2004, 0x905d, 0x2079, 0x19e9, 0x9036, 0x7828, 0x2060,
0x8cff, 0x0538, 0x6010, 0x9b06, 0x1500, 0x6043, 0xffff, 0x080c,
- 0xacfa, 0x01d8, 0x610c, 0x0016, 0x080c, 0xa20a, 0x6014, 0x2048,
+ 0xad1a, 0x01d8, 0x610c, 0x0016, 0x080c, 0xa21b, 0x6014, 0x2048,
0xa867, 0x0103, 0xab7a, 0xa877, 0x0000, 0x0016, 0x0036, 0x0086,
- 0x080c, 0xcf1b, 0x080c, 0xea83, 0x080c, 0x6f19, 0x008e, 0x003e,
- 0x001e, 0x080c, 0xaf69, 0x00ce, 0x08d8, 0x2c30, 0x600c, 0x2060,
- 0x08b8, 0x080c, 0x6933, 0x012e, 0x001e, 0x006e, 0x00ce, 0x00be,
+ 0x080c, 0xcf38, 0x080c, 0xeaee, 0x080c, 0x6f11, 0x008e, 0x003e,
+ 0x001e, 0x080c, 0xaf89, 0x00ce, 0x08d8, 0x2c30, 0x600c, 0x2060,
+ 0x08b8, 0x080c, 0x692b, 0x012e, 0x001e, 0x006e, 0x00ce, 0x00be,
0x009e, 0x00ee, 0x00fe, 0x000e, 0x0005, 0x0096, 0x0006, 0x0066,
- 0x00c6, 0x00d6, 0x9036, 0x7820, 0x9065, 0x0904, 0x9766, 0x600c,
+ 0x00c6, 0x00d6, 0x9036, 0x7820, 0x9065, 0x0904, 0x975e, 0x600c,
0x0006, 0x6044, 0xc0fc, 0x6046, 0x600f, 0x0000, 0x7830, 0x9c06,
0x1598, 0x2069, 0x0100, 0x6820, 0xd0a4, 0x0110, 0xd0cc, 0x1508,
- 0x080c, 0x88ec, 0x080c, 0xa08a, 0x68c3, 0x0000, 0x080c, 0xa56e,
+ 0x080c, 0x88e4, 0x080c, 0xa09b, 0x68c3, 0x0000, 0x080c, 0xa585,
0x7833, 0x0000, 0x0036, 0x2069, 0x0140, 0x6b04, 0x9384, 0x1000,
- 0x0138, 0x2001, 0x0100, 0x080c, 0x2abb, 0x9006, 0x080c, 0x2abb,
+ 0x0138, 0x2001, 0x0100, 0x080c, 0x2aa2, 0x9006, 0x080c, 0x2aa2,
0x2069, 0x0100, 0x6824, 0xd084, 0x0110, 0x6827, 0x0001, 0x003e,
- 0x0058, 0x080c, 0x6b6d, 0x1538, 0x6003, 0x0009, 0x630a, 0x7808,
- 0xc0ad, 0x780a, 0x2c30, 0x00f8, 0x6014, 0x2048, 0x080c, 0xcc14,
- 0x01b0, 0x6020, 0x9086, 0x0003, 0x1508, 0x080c, 0xce2d, 0x1118,
- 0x080c, 0xb91f, 0x0060, 0x080c, 0x6b6d, 0x1168, 0xa867, 0x0103,
- 0xab7a, 0xa877, 0x0000, 0x080c, 0x6f19, 0x080c, 0xce07, 0x080c,
- 0xaf69, 0x080c, 0xa441, 0x000e, 0x0804, 0x9704, 0x7e22, 0x7e1e,
+ 0x0058, 0x080c, 0x6b65, 0x1538, 0x6003, 0x0009, 0x630a, 0x7808,
+ 0xc0ad, 0x780a, 0x2c30, 0x00f8, 0x6014, 0x2048, 0x080c, 0xcc31,
+ 0x01b0, 0x6020, 0x9086, 0x0003, 0x1508, 0x080c, 0xce4a, 0x1118,
+ 0x080c, 0xb93c, 0x0060, 0x080c, 0x6b65, 0x1168, 0xa867, 0x0103,
+ 0xab7a, 0xa877, 0x0000, 0x080c, 0x6f11, 0x080c, 0xce24, 0x080c,
+ 0xaf89, 0x080c, 0xa458, 0x000e, 0x0804, 0x96fc, 0x7e22, 0x7e1e,
0x00de, 0x00ce, 0x006e, 0x000e, 0x009e, 0x0005, 0x6020, 0x9086,
- 0x0006, 0x1118, 0x080c, 0xe6cd, 0x0c50, 0x080c, 0xb91f, 0x6020,
+ 0x0006, 0x1118, 0x080c, 0xe738, 0x0c50, 0x080c, 0xb93c, 0x6020,
0x9086, 0x0002, 0x1150, 0x6004, 0x0006, 0x9086, 0x0085, 0x000e,
0x0990, 0x9086, 0x008b, 0x0978, 0x08d0, 0x6020, 0x9086, 0x0005,
0x19b0, 0x6004, 0x0006, 0x9086, 0x0085, 0x000e, 0x0d18, 0x9086,
0x008b, 0x0d00, 0x0860, 0x0006, 0x0096, 0x00b6, 0x00c6, 0x0066,
0x9036, 0x7828, 0x9065, 0x0510, 0x6010, 0x2058, 0x600c, 0x0006,
0x3e08, 0x918e, 0x0002, 0x1118, 0xb800, 0xd0bc, 0x11a8, 0x6043,
- 0xffff, 0x080c, 0xacfa, 0x0180, 0x610c, 0x080c, 0xa20a, 0x6014,
- 0x2048, 0xa867, 0x0103, 0xab7a, 0xa877, 0x0000, 0x080c, 0x6f19,
- 0x080c, 0xaf69, 0x000e, 0x08f0, 0x2c30, 0x0ce0, 0x006e, 0x00ce,
+ 0xffff, 0x080c, 0xad1a, 0x0180, 0x610c, 0x080c, 0xa21b, 0x6014,
+ 0x2048, 0xa867, 0x0103, 0xab7a, 0xa877, 0x0000, 0x080c, 0x6f11,
+ 0x080c, 0xaf89, 0x000e, 0x08f0, 0x2c30, 0x0ce0, 0x006e, 0x00ce,
0x00be, 0x009e, 0x000e, 0x0005, 0x00e6, 0x00d6, 0x0096, 0x0066,
- 0x080c, 0x6290, 0x11b0, 0x2071, 0x19e9, 0x7030, 0x9080, 0x0005,
+ 0x080c, 0x628a, 0x11b0, 0x2071, 0x19e9, 0x7030, 0x9080, 0x0005,
0x2004, 0x904d, 0x0170, 0xa878, 0x9606, 0x1158, 0x2071, 0x19e9,
0x7030, 0x9035, 0x0130, 0x9080, 0x0005, 0x2004, 0x9906, 0x1108,
0x0029, 0x006e, 0x009e, 0x00de, 0x00ee, 0x0005, 0x00c6, 0x2660,
- 0x6043, 0xffff, 0x080c, 0xacfa, 0x0178, 0x080c, 0xa20a, 0x6014,
- 0x2048, 0xa867, 0x0103, 0xab7a, 0xa877, 0x0000, 0x080c, 0xcf1b,
- 0x080c, 0x6f19, 0x080c, 0xaf69, 0x00ce, 0x0005, 0x00b6, 0x00e6,
- 0x00c6, 0x080c, 0xaae0, 0x0106, 0x2071, 0x0101, 0x2e04, 0xc0c4,
- 0x2072, 0x6044, 0xd0fc, 0x1138, 0x010e, 0x090c, 0xaafc, 0x00ce,
+ 0x6043, 0xffff, 0x080c, 0xad1a, 0x0178, 0x080c, 0xa21b, 0x6014,
+ 0x2048, 0xa867, 0x0103, 0xab7a, 0xa877, 0x0000, 0x080c, 0xcf38,
+ 0x080c, 0x6f11, 0x080c, 0xaf89, 0x00ce, 0x0005, 0x00b6, 0x00e6,
+ 0x00c6, 0x080c, 0xaaf7, 0x0106, 0x2071, 0x0101, 0x2e04, 0xc0c4,
+ 0x2072, 0x6044, 0xd0fc, 0x1138, 0x010e, 0x090c, 0xab13, 0x00ce,
0x00ee, 0x00be, 0x0005, 0x2071, 0x19e9, 0x7030, 0x9005, 0x0da0,
- 0x9c06, 0x190c, 0x0d85, 0x7036, 0x080c, 0x88ec, 0x7004, 0x9084,
- 0x0007, 0x0002, 0x982c, 0x982e, 0x9835, 0x983f, 0x984d, 0x982c,
- 0x983a, 0x982a, 0x080c, 0x0d85, 0x0428, 0x0005, 0x080c, 0xace5,
+ 0x9c06, 0x190c, 0x0d79, 0x7036, 0x080c, 0x88e4, 0x7004, 0x9084,
+ 0x0007, 0x0002, 0x9824, 0x9826, 0x982d, 0x9837, 0x9845, 0x9824,
+ 0x9832, 0x9822, 0x080c, 0x0d79, 0x0428, 0x0005, 0x080c, 0xad05,
0x7007, 0x0000, 0x7033, 0x0000, 0x00e8, 0x0066, 0x9036, 0x080c,
- 0xa20a, 0x006e, 0x7007, 0x0000, 0x7033, 0x0000, 0x0098, 0x080c,
- 0xacd0, 0x0140, 0x080c, 0xace5, 0x0128, 0x0066, 0x9036, 0x080c,
- 0xa20a, 0x006e, 0x7033, 0x0000, 0x0028, 0x080c, 0xacd0, 0x080c,
- 0xa56e, 0x0000, 0x010e, 0x090c, 0xaafc, 0x00ce, 0x00ee, 0x00be,
- 0x0005, 0x00d6, 0x00c6, 0x080c, 0xaae0, 0x0106, 0x6044, 0xd0fc,
- 0x1130, 0x010e, 0x090c, 0xaafc, 0x00ce, 0x00de, 0x0005, 0x2069,
- 0x19e9, 0x684c, 0x9005, 0x0da8, 0x9c06, 0x190c, 0x0d85, 0x6852,
- 0x00e6, 0x2d70, 0x080c, 0x9478, 0x00ee, 0x080c, 0x88f9, 0x0016,
- 0x2009, 0x0040, 0x080c, 0x2241, 0x001e, 0x683c, 0x9084, 0x0003,
- 0x0002, 0x9887, 0x9888, 0x98a7, 0x9885, 0x080c, 0x0d85, 0x0468,
+ 0xa21b, 0x006e, 0x7007, 0x0000, 0x7033, 0x0000, 0x0098, 0x080c,
+ 0xacf0, 0x0140, 0x080c, 0xad05, 0x0128, 0x0066, 0x9036, 0x080c,
+ 0xa21b, 0x006e, 0x7033, 0x0000, 0x0028, 0x080c, 0xacf0, 0x080c,
+ 0xa585, 0x0000, 0x010e, 0x090c, 0xab13, 0x00ce, 0x00ee, 0x00be,
+ 0x0005, 0x00d6, 0x00c6, 0x080c, 0xaaf7, 0x0106, 0x6044, 0xd0fc,
+ 0x1130, 0x010e, 0x090c, 0xab13, 0x00ce, 0x00de, 0x0005, 0x2069,
+ 0x19e9, 0x684c, 0x9005, 0x0da8, 0x9c06, 0x190c, 0x0d79, 0x6852,
+ 0x00e6, 0x2d70, 0x080c, 0x9470, 0x00ee, 0x080c, 0x88f1, 0x0016,
+ 0x2009, 0x0040, 0x080c, 0x223d, 0x001e, 0x683c, 0x9084, 0x0003,
+ 0x0002, 0x987f, 0x9880, 0x989f, 0x987d, 0x080c, 0x0d79, 0x0490,
0x6868, 0x9086, 0x0001, 0x0198, 0x600c, 0x9015, 0x0168, 0x6a4a,
- 0x600f, 0x0000, 0x6044, 0x9084, 0x7f7f, 0x6046, 0x9006, 0x7042,
- 0x684e, 0x683f, 0x0000, 0x00c8, 0x684a, 0x6846, 0x0c98, 0x686b,
- 0x0000, 0x6848, 0x9065, 0x0d70, 0x6003, 0x0002, 0x0c58, 0x9006,
- 0x686a, 0x6852, 0x686e, 0x600c, 0x9015, 0x0120, 0x6a4a, 0x600f,
- 0x0000, 0x0018, 0x684e, 0x684a, 0x6846, 0x080c, 0xadc0, 0x684f,
- 0x0000, 0x010e, 0x090c, 0xaafc, 0x00ce, 0x00de, 0x0005, 0x0005,
- 0x6020, 0x9084, 0x000f, 0x000b, 0x0005, 0x98d5, 0x98d8, 0x9d6a,
- 0x9e03, 0x98d8, 0x9d6a, 0x9e03, 0x98d5, 0x98d8, 0x98d5, 0x98d5,
- 0x98d5, 0x98d5, 0x98d5, 0x98d5, 0x98d5, 0x080c, 0x97fe, 0x0005,
- 0x00b6, 0x0156, 0x0136, 0x0146, 0x01c6, 0x01d6, 0x00c6, 0x00d6,
- 0x00e6, 0x00f6, 0x2069, 0x0200, 0x2071, 0x0240, 0x6004, 0x908a,
- 0x0053, 0x1a0c, 0x0d85, 0x6110, 0x2158, 0xb984, 0x2c78, 0x2061,
- 0x0100, 0x619a, 0x908a, 0x0040, 0x1a04, 0x9944, 0x005b, 0x00fe,
- 0x00ee, 0x00de, 0x00ce, 0x01de, 0x01ce, 0x014e, 0x013e, 0x015e,
- 0x00be, 0x0005, 0x9aed, 0x9b28, 0x9b51, 0x9bf9, 0x9c1b, 0x9c21,
- 0x9c2e, 0x9c36, 0x9c42, 0x9c48, 0x9c59, 0x9c48, 0x9cb1, 0x9c36,
- 0x9cbd, 0x9cc3, 0x9c42, 0x9cc3, 0x9ccf, 0x9942, 0x9942, 0x9942,
- 0x9942, 0x9942, 0x9942, 0x9942, 0x9942, 0x9942, 0x9942, 0x9942,
- 0xa22b, 0xa24e, 0xa25f, 0xa27f, 0xa2b1, 0x9c2e, 0x9942, 0x9c2e,
- 0x9c48, 0x9942, 0x9b51, 0x9bf9, 0x9942, 0xa66c, 0x9c48, 0x9942,
- 0xa688, 0x9c48, 0x9942, 0x9c42, 0x9ae7, 0x9965, 0x9942, 0xa6a4,
- 0xa711, 0xa7f5, 0x9942, 0xa802, 0x9c2b, 0xa82d, 0x9942, 0xa2bb,
- 0xa839, 0x9942, 0x080c, 0x0d85, 0x2100, 0x005b, 0x00fe, 0x00ee,
- 0x00de, 0x00ce, 0x01de, 0x01ce, 0x014e, 0x013e, 0x015e, 0x00be,
- 0x0005, 0xa8d9, 0xa98b, 0x9963, 0x999d, 0x9a49, 0x9a54, 0x9963,
- 0x9c2e, 0x9963, 0x9aae, 0x9aba, 0x99b8, 0x9963, 0x99d3, 0x9a07,
- 0xadd4, 0xae19, 0x9c48, 0x080c, 0x0d85, 0x00d6, 0x0096, 0x080c,
- 0x9ce2, 0x0026, 0x0036, 0x7814, 0x2048, 0xa958, 0xd1cc, 0x1138,
- 0x2009, 0x2414, 0x2011, 0x0018, 0x2019, 0x0018, 0x0030, 0x2009,
- 0x2410, 0x2011, 0x0014, 0x2019, 0x0014, 0x7102, 0x7206, 0x700b,
- 0x0800, 0xa83c, 0x700e, 0xa850, 0x7022, 0xa854, 0x7026, 0x63c2,
- 0x080c, 0xa05a, 0x003e, 0x002e, 0x009e, 0x00de, 0x0005, 0x7810,
- 0x00b6, 0x2058, 0xb8a0, 0x00be, 0x080c, 0xae60, 0x1118, 0x9084,
- 0xff80, 0x0110, 0x9085, 0x0001, 0x0005, 0x00d6, 0x0096, 0x080c,
- 0x9ce2, 0x7003, 0x0500, 0x7814, 0x2048, 0xa874, 0x700a, 0xa878,
- 0x700e, 0xa87c, 0x7012, 0xa880, 0x7016, 0xa884, 0x701a, 0xa888,
- 0x701e, 0x60c3, 0x0010, 0x080c, 0xa05a, 0x009e, 0x00de, 0x0005,
- 0x00d6, 0x0096, 0x080c, 0x9ce2, 0x7003, 0x0500, 0x7814, 0x2048,
- 0xa8cc, 0x700a, 0xa8d0, 0x700e, 0xa8d4, 0x7012, 0xa8d8, 0x7016,
- 0xa8dc, 0x701a, 0xa8e0, 0x701e, 0x60c3, 0x0010, 0x080c, 0xa05a,
- 0x009e, 0x00de, 0x0005, 0x00d6, 0x0096, 0x0126, 0x2091, 0x8000,
- 0x080c, 0x9ce2, 0x20e9, 0x0000, 0x2001, 0x19a4, 0x2003, 0x0000,
- 0x7814, 0x2048, 0xa814, 0x8003, 0x60c2, 0xa830, 0x20a8, 0xa860,
- 0x20e0, 0xa85c, 0x9080, 0x001b, 0x2098, 0x2001, 0x19a4, 0x0016,
- 0x200c, 0x2001, 0x0001, 0x080c, 0x2226, 0x080c, 0xd9e6, 0x9006,
- 0x080c, 0x2226, 0x001e, 0xa804, 0x9005, 0x0110, 0x2048, 0x0c28,
- 0x04d9, 0x080c, 0xa05a, 0x012e, 0x009e, 0x00de, 0x0005, 0x00d6,
- 0x0096, 0x0126, 0x2091, 0x8000, 0x080c, 0x9d2d, 0x20e9, 0x0000,
- 0x2001, 0x19a4, 0x2003, 0x0000, 0x7814, 0x2048, 0xa86f, 0x0200,
- 0xa873, 0x0000, 0xa814, 0x8003, 0x60c2, 0xa830, 0x20a8, 0xa860,
- 0x20e0, 0xa85c, 0x9080, 0x001b, 0x2098, 0x2001, 0x19a4, 0x0016,
- 0x200c, 0x080c, 0xd9e6, 0x001e, 0xa804, 0x9005, 0x0110, 0x2048,
- 0x0c60, 0x0051, 0x7814, 0x2048, 0x080c, 0x100b, 0x080c, 0xa05a,
- 0x012e, 0x009e, 0x00de, 0x0005, 0x60c0, 0x8004, 0x9084, 0x0003,
- 0x9005, 0x0130, 0x9082, 0x0004, 0x20a3, 0x0000, 0x8000, 0x1de0,
- 0x0005, 0x080c, 0x9ce2, 0x7003, 0x7800, 0x7808, 0x8007, 0x700a,
- 0x60c3, 0x0008, 0x0804, 0xa05a, 0x00d6, 0x00e6, 0x080c, 0x9d2d,
- 0x7814, 0x9084, 0xff00, 0x2073, 0x0200, 0x8e70, 0x8e70, 0x9096,
- 0xdf00, 0x0138, 0x9096, 0xe000, 0x0120, 0x2073, 0x0010, 0x8e70,
- 0x0030, 0x9095, 0x0010, 0x2272, 0x8e70, 0x2073, 0x0034, 0x8e70,
- 0x2069, 0x1805, 0x20a9, 0x0004, 0x2d76, 0x8d68, 0x8e70, 0x1f04,
- 0x9a74, 0x2069, 0x1801, 0x20a9, 0x0004, 0x2d76, 0x8d68, 0x8e70,
- 0x1f04, 0x9a7d, 0x9096, 0xdf00, 0x0130, 0x9096, 0xe000, 0x0118,
- 0x60c3, 0x0018, 0x00f0, 0x2069, 0x19b5, 0x9086, 0xdf00, 0x0110,
- 0x2069, 0x19cf, 0x20a9, 0x001a, 0x9e86, 0x0260, 0x1148, 0x00c6,
- 0x2061, 0x0200, 0x6010, 0x8000, 0x6012, 0x00ce, 0x2071, 0x0240,
- 0x2d04, 0x8007, 0x2072, 0x8d68, 0x8e70, 0x1f04, 0x9a94, 0x60c3,
- 0x004c, 0x080c, 0xa05a, 0x00ee, 0x00de, 0x0005, 0x080c, 0x9ce2,
- 0x7003, 0x6300, 0x7007, 0x0028, 0x7808, 0x700e, 0x60c3, 0x0008,
- 0x0804, 0xa05a, 0x00d6, 0x0026, 0x0016, 0x080c, 0x9d2d, 0x7003,
- 0x0200, 0x7814, 0x700e, 0x00e6, 0x9ef0, 0x0004, 0x2009, 0x0001,
- 0x2011, 0x000c, 0x2069, 0x1925, 0x6810, 0xd084, 0x1148, 0x2073,
- 0x0500, 0x8e70, 0x2073, 0x0000, 0x8e70, 0x8108, 0x9290, 0x0004,
- 0x2073, 0x0800, 0x8e70, 0x2073, 0x0000, 0x00ee, 0x7206, 0x710a,
- 0x62c2, 0x080c, 0xa05a, 0x001e, 0x002e, 0x00de, 0x0005, 0x2001,
- 0x1818, 0x2004, 0x609a, 0x0804, 0xa05a, 0x080c, 0x9ce2, 0x7003,
- 0x5200, 0x2069, 0x1847, 0x6804, 0xd084, 0x0130, 0x6828, 0x0016,
- 0x080c, 0x26d5, 0x710e, 0x001e, 0x20a9, 0x0004, 0x20e1, 0x0001,
- 0x2099, 0x1805, 0x20e9, 0x0000, 0x20a1, 0x0250, 0x4003, 0x20a9,
- 0x0004, 0x2099, 0x1801, 0x20a1, 0x0254, 0x4003, 0x080c, 0xae60,
- 0x1120, 0xb8a0, 0x9082, 0x007f, 0x0248, 0x2001, 0x181f, 0x2004,
- 0x7032, 0x2001, 0x1820, 0x2004, 0x7036, 0x0030, 0x2001, 0x1818,
- 0x2004, 0x9084, 0x00ff, 0x7036, 0x60c3, 0x001c, 0x0804, 0xa05a,
- 0x080c, 0x9ce2, 0x7003, 0x0500, 0x080c, 0xae60, 0x1120, 0xb8a0,
- 0x9082, 0x007f, 0x0248, 0x2001, 0x181f, 0x2004, 0x700a, 0x2001,
- 0x1820, 0x2004, 0x700e, 0x0030, 0x2001, 0x1818, 0x2004, 0x9084,
- 0x00ff, 0x700e, 0x20a9, 0x0004, 0x20e1, 0x0001, 0x2099, 0x1805,
- 0x20e9, 0x0000, 0x20a1, 0x0250, 0x4003, 0x60c3, 0x0010, 0x0804,
- 0xa05a, 0x080c, 0x9ce2, 0x9006, 0x080c, 0x6b9f, 0xb8a0, 0x9086,
- 0x007e, 0x1130, 0x7003, 0x0400, 0x620c, 0xc2b4, 0x620e, 0x0058,
- 0x7814, 0x0096, 0x904d, 0x0120, 0x9006, 0xa89a, 0xa8a6, 0xa8aa,
- 0x009e, 0x7003, 0x0300, 0xb8a0, 0x9086, 0x007e, 0x1904, 0x9bc0,
- 0x00d6, 0x2069, 0x196d, 0x2001, 0x1837, 0x2004, 0xd0a4, 0x0188,
- 0x6800, 0x700a, 0x6808, 0x9084, 0x2000, 0x7012, 0x080c, 0xae77,
- 0x680c, 0x7016, 0x701f, 0x2710, 0x6818, 0x7022, 0x681c, 0x7026,
- 0x0090, 0x6800, 0x700a, 0x6804, 0x700e, 0x6808, 0x080c, 0x76a5,
- 0x1118, 0x9084, 0x37ff, 0x0010, 0x9084, 0x3fff, 0x7012, 0x080c,
- 0xae77, 0x680c, 0x7016, 0x00de, 0x20a9, 0x0004, 0x20e1, 0x0001,
- 0x2099, 0x1805, 0x20e9, 0x0000, 0x20a1, 0x0256, 0x4003, 0x20a9,
- 0x0004, 0x2099, 0x1801, 0x20a1, 0x025a, 0x4003, 0x00d6, 0x080c,
- 0xa8c0, 0x2069, 0x1975, 0x2071, 0x024e, 0x6800, 0xc0dd, 0x7002,
- 0x080c, 0x582a, 0xd0e4, 0x0110, 0x680c, 0x700e, 0x00de, 0x04a8,
- 0x2001, 0x1837, 0x2004, 0xd0a4, 0x0170, 0x0016, 0x2001, 0x196e,
- 0x200c, 0x60e0, 0x9106, 0x0130, 0x2100, 0x60e3, 0x0000, 0x080c,
- 0x2716, 0x61e2, 0x001e, 0x20e1, 0x0001, 0x2099, 0x196d, 0x20e9,
- 0x0000, 0x20a1, 0x024e, 0x20a9, 0x0008, 0x4003, 0x20a9, 0x0004,
- 0x2099, 0x1805, 0x20a1, 0x0256, 0x4003, 0x20a9, 0x0004, 0x2099,
- 0x1801, 0x20a1, 0x025a, 0x4003, 0x080c, 0xa8c0, 0x20a1, 0x024e,
- 0x20a9, 0x0008, 0x2099, 0x1975, 0x4003, 0x60c3, 0x0074, 0x0804,
- 0xa05a, 0x080c, 0x9ce2, 0x7003, 0x2010, 0x7007, 0x0014, 0x700b,
- 0x0800, 0x700f, 0x2000, 0x9006, 0x00f6, 0x2079, 0x1847, 0x7904,
- 0x00fe, 0xd1ac, 0x1110, 0x9085, 0x0020, 0xd1a4, 0x0110, 0x9085,
- 0x0010, 0x9085, 0x0002, 0x00d6, 0x0804, 0x9c92, 0x7026, 0x60c3,
- 0x0014, 0x0804, 0xa05a, 0x080c, 0x9ce2, 0x7003, 0x5000, 0x0804,
- 0x9b6b, 0x080c, 0x9ce2, 0x7003, 0x2110, 0x7007, 0x0014, 0x60c3,
- 0x0014, 0x0804, 0xa05a, 0x080c, 0x9d24, 0x0010, 0x080c, 0x9d2d,
- 0x7003, 0x0200, 0x60c3, 0x0004, 0x0804, 0xa05a, 0x080c, 0x9d2d,
- 0x7003, 0x0100, 0x700b, 0x0003, 0x700f, 0x2a00, 0x60c3, 0x0008,
- 0x0804, 0xa05a, 0x080c, 0x9d2d, 0x7003, 0x0200, 0x0804, 0x9b6b,
- 0x080c, 0x9d2d, 0x7003, 0x0100, 0x782c, 0x9005, 0x0110, 0x700a,
- 0x0010, 0x700b, 0x0003, 0x7814, 0x700e, 0x60c3, 0x0008, 0x0804,
- 0xa05a, 0x00d6, 0x080c, 0x9d2d, 0x7003, 0x0210, 0x7007, 0x0014,
- 0x700b, 0x0800, 0xb894, 0x9086, 0x0014, 0x1198, 0xb99c, 0x9184,
- 0x0030, 0x0190, 0xb998, 0x9184, 0xc000, 0x1140, 0xd1ec, 0x0118,
- 0x700f, 0x2100, 0x0058, 0x700f, 0x0100, 0x0040, 0x700f, 0x0400,
- 0x0028, 0x700f, 0x0700, 0x0010, 0x700f, 0x0800, 0x00f6, 0x2079,
- 0x1847, 0x7904, 0x00fe, 0xd1ac, 0x1110, 0x9085, 0x0020, 0xd1a4,
- 0x0110, 0x9085, 0x0010, 0x2009, 0x1869, 0x210c, 0xd184, 0x1110,
- 0x9085, 0x0002, 0x0026, 0x2009, 0x1867, 0x210c, 0xd1e4, 0x0150,
- 0xc0c5, 0xbad4, 0xd28c, 0x1108, 0xc0cd, 0x9094, 0x0030, 0x9296,
- 0x0010, 0x0140, 0xd1ec, 0x0130, 0x9094, 0x0030, 0x9296, 0x0010,
- 0x0108, 0xc0bd, 0x002e, 0x7026, 0x60c3, 0x0014, 0x00de, 0x0804,
- 0xa05a, 0x080c, 0x9d2d, 0x7003, 0x0210, 0x7007, 0x0014, 0x700f,
- 0x0100, 0x60c3, 0x0014, 0x0804, 0xa05a, 0x080c, 0x9d2d, 0x7003,
- 0x0200, 0x0804, 0x9af1, 0x080c, 0x9d2d, 0x7003, 0x0100, 0x700b,
- 0x0003, 0x700f, 0x2a00, 0x60c3, 0x0008, 0x0804, 0xa05a, 0x080c,
- 0x9d2d, 0x7003, 0x0100, 0x700b, 0x000b, 0x60c3, 0x0008, 0x0804,
- 0xa05a, 0x0026, 0x00d6, 0x0036, 0x0046, 0x2019, 0x3200, 0x2021,
- 0x0800, 0x0040, 0x0026, 0x00d6, 0x0036, 0x0046, 0x2019, 0x2200,
- 0x2021, 0x0100, 0x080c, 0xa8d5, 0xb810, 0x9305, 0x7002, 0xb814,
- 0x7006, 0x2069, 0x1800, 0x687c, 0x700a, 0x6880, 0x700e, 0x9485,
- 0x0029, 0x7012, 0x004e, 0x003e, 0x00de, 0x080c, 0xa04e, 0x721a,
- 0x9f95, 0x0000, 0x7222, 0x7027, 0xffff, 0x2071, 0x024c, 0x002e,
- 0x0005, 0x0026, 0x080c, 0xa8d5, 0x7003, 0x02ff, 0x7007, 0xfffc,
- 0x00d6, 0x2069, 0x1800, 0x687c, 0x700a, 0x6880, 0x700e, 0x00de,
- 0x7013, 0x2029, 0x0c10, 0x7003, 0x0100, 0x7007, 0x0000, 0x700b,
- 0xfc02, 0x700f, 0x0000, 0x0005, 0x0026, 0x00d6, 0x0036, 0x0046,
- 0x2019, 0x3300, 0x2021, 0x0800, 0x0040, 0x0026, 0x00d6, 0x0036,
- 0x0046, 0x2019, 0x2300, 0x2021, 0x0100, 0x080c, 0xa8d5, 0xb810,
- 0x9305, 0x7002, 0xb814, 0x7006, 0x2069, 0x1800, 0xb810, 0x9005,
- 0x1140, 0xb814, 0x9005, 0x1128, 0x700b, 0x00ff, 0x700f, 0xfffe,
- 0x0020, 0x687c, 0x700a, 0x6880, 0x700e, 0x0000, 0x9485, 0x0098,
- 0x7012, 0x004e, 0x003e, 0x00de, 0x080c, 0xa04e, 0x721a, 0x7a08,
- 0x7222, 0x2f10, 0x7226, 0x2071, 0x024c, 0x002e, 0x0005, 0x080c,
- 0xa04e, 0x721a, 0x7a08, 0x7222, 0x7814, 0x7026, 0x2071, 0x024c,
- 0x002e, 0x0005, 0x00b6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x2069,
- 0x0200, 0x2071, 0x0240, 0x6004, 0x908a, 0x0085, 0x0a0c, 0x0d85,
- 0x908a, 0x0092, 0x1a0c, 0x0d85, 0x6110, 0x2158, 0xb984, 0x2c78,
- 0x2061, 0x0100, 0x619a, 0x9082, 0x0085, 0x0033, 0x00fe, 0x00ee,
- 0x00de, 0x00ce, 0x00be, 0x0005, 0x9d9b, 0x9daa, 0x9db5, 0x9d99,
- 0x9d99, 0x9d99, 0x9d9b, 0x9d99, 0x9d99, 0x9d99, 0x9d99, 0x9d99,
- 0x9d99, 0x080c, 0x0d85, 0x0411, 0x60c3, 0x0000, 0x0026, 0x080c,
- 0x2a26, 0x0228, 0x2011, 0x0101, 0x2204, 0xc0c5, 0x2012, 0x002e,
- 0x0804, 0xa05a, 0x0431, 0x7808, 0x700a, 0x7814, 0x700e, 0x7017,
- 0xffff, 0x60c3, 0x000c, 0x0804, 0xa05a, 0x04a1, 0x7003, 0x0003,
- 0x7007, 0x0300, 0x60c3, 0x0004, 0x0804, 0xa05a, 0x0026, 0x080c,
- 0xa8d5, 0xb810, 0x9085, 0x8100, 0x7002, 0xb814, 0x7006, 0x2069,
- 0x1800, 0x687c, 0x700a, 0x6880, 0x700e, 0x7013, 0x0009, 0x0804,
- 0x9cfd, 0x0026, 0x080c, 0xa8d5, 0xb810, 0x9085, 0x8400, 0x7002,
+ 0x600f, 0x0000, 0x6044, 0x9084, 0x7f7f, 0x6046, 0x9006, 0x6842,
+ 0x684e, 0x683f, 0x0000, 0x00f0, 0x684a, 0x6846, 0x0c98, 0x686b,
+ 0x0000, 0x6848, 0x9065, 0x0d70, 0x6003, 0x0002, 0x0c58, 0x6044,
+ 0x9084, 0x7f7f, 0x6046, 0x9006, 0x6842, 0x684e, 0x686a, 0x6852,
+ 0x686e, 0x600c, 0x9015, 0x0120, 0x6a4a, 0x600f, 0x0000, 0x0010,
+ 0x684a, 0x6846, 0x080c, 0xade0, 0x684f, 0x0000, 0x010e, 0x090c,
+ 0xab13, 0x00ce, 0x00de, 0x0005, 0x0005, 0x6020, 0x9084, 0x000f,
+ 0x000b, 0x0005, 0x98d2, 0x98d5, 0x9d7b, 0x9e14, 0x98d5, 0x9d7b,
+ 0x9e14, 0x98d2, 0x98d5, 0x98d2, 0x98d2, 0x98d2, 0x98d2, 0x98d2,
+ 0x98d2, 0x98d2, 0x080c, 0x97f6, 0x0005, 0x00b6, 0x0156, 0x0136,
+ 0x0146, 0x01c6, 0x01d6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x2069,
+ 0x0200, 0x2071, 0x0240, 0x6004, 0x908a, 0x0053, 0x1a0c, 0x0d79,
+ 0x6110, 0x2158, 0xb984, 0x2c78, 0x2061, 0x0100, 0x619a, 0x908a,
+ 0x0040, 0x1a04, 0x9941, 0x005b, 0x00fe, 0x00ee, 0x00de, 0x00ce,
+ 0x01de, 0x01ce, 0x014e, 0x013e, 0x015e, 0x00be, 0x0005, 0x9aea,
+ 0x9b25, 0x9b4e, 0x9c0a, 0x9c2c, 0x9c32, 0x9c3f, 0x9c47, 0x9c53,
+ 0x9c59, 0x9c6a, 0x9c59, 0x9cc2, 0x9c47, 0x9cce, 0x9cd4, 0x9c53,
+ 0x9cd4, 0x9ce0, 0x993f, 0x993f, 0x993f, 0x993f, 0x993f, 0x993f,
+ 0x993f, 0x993f, 0x993f, 0x993f, 0x993f, 0xa23c, 0xa25f, 0xa270,
+ 0xa290, 0xa2c2, 0x9c3f, 0x993f, 0x9c3f, 0x9c59, 0x993f, 0x9b4e,
+ 0x9c0a, 0x993f, 0xa683, 0x9c59, 0x993f, 0xa69f, 0x9c59, 0x993f,
+ 0x9c53, 0x9ae4, 0x9962, 0x993f, 0xa6bb, 0xa728, 0xa80c, 0x993f,
+ 0xa819, 0x9c3c, 0xa844, 0x993f, 0xa2cc, 0xa850, 0x993f, 0x080c,
+ 0x0d79, 0x2100, 0x005b, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x01de,
+ 0x01ce, 0x014e, 0x013e, 0x015e, 0x00be, 0x0005, 0xa8f0, 0xa9a2,
+ 0x9960, 0x999a, 0x9a46, 0x9a51, 0x9960, 0x9c3f, 0x9960, 0x9aab,
+ 0x9ab7, 0x99b5, 0x9960, 0x99d0, 0x9a04, 0xadf4, 0xae39, 0x9c59,
+ 0x080c, 0x0d79, 0x00d6, 0x0096, 0x080c, 0x9cf3, 0x0026, 0x0036,
+ 0x7814, 0x2048, 0xa958, 0xd1cc, 0x1138, 0x2009, 0x2414, 0x2011,
+ 0x0018, 0x2019, 0x0018, 0x0030, 0x2009, 0x2410, 0x2011, 0x0014,
+ 0x2019, 0x0014, 0x7102, 0x7206, 0x700b, 0x0800, 0xa83c, 0x700e,
+ 0xa850, 0x7022, 0xa854, 0x7026, 0x63c2, 0x080c, 0xa06b, 0x003e,
+ 0x002e, 0x009e, 0x00de, 0x0005, 0x7810, 0x00b6, 0x2058, 0xb8a0,
+ 0x00be, 0x080c, 0xae80, 0x1118, 0x9084, 0xff80, 0x0110, 0x9085,
+ 0x0001, 0x0005, 0x00d6, 0x0096, 0x080c, 0x9cf3, 0x7003, 0x0500,
+ 0x7814, 0x2048, 0xa874, 0x700a, 0xa878, 0x700e, 0xa87c, 0x7012,
+ 0xa880, 0x7016, 0xa884, 0x701a, 0xa888, 0x701e, 0x60c3, 0x0010,
+ 0x080c, 0xa06b, 0x009e, 0x00de, 0x0005, 0x00d6, 0x0096, 0x080c,
+ 0x9cf3, 0x7003, 0x0500, 0x7814, 0x2048, 0xa8cc, 0x700a, 0xa8d0,
+ 0x700e, 0xa8d4, 0x7012, 0xa8d8, 0x7016, 0xa8dc, 0x701a, 0xa8e0,
+ 0x701e, 0x60c3, 0x0010, 0x080c, 0xa06b, 0x009e, 0x00de, 0x0005,
+ 0x00d6, 0x0096, 0x0126, 0x2091, 0x8000, 0x080c, 0x9cf3, 0x20e9,
+ 0x0000, 0x2001, 0x19a5, 0x2003, 0x0000, 0x7814, 0x2048, 0xa814,
+ 0x8003, 0x60c2, 0xa830, 0x20a8, 0xa860, 0x20e0, 0xa85c, 0x9080,
+ 0x001b, 0x2098, 0x2001, 0x19a5, 0x0016, 0x200c, 0x2001, 0x0001,
+ 0x080c, 0x2222, 0x080c, 0xda05, 0x9006, 0x080c, 0x2222, 0x001e,
+ 0xa804, 0x9005, 0x0110, 0x2048, 0x0c28, 0x04d9, 0x080c, 0xa06b,
+ 0x012e, 0x009e, 0x00de, 0x0005, 0x00d6, 0x0096, 0x0126, 0x2091,
+ 0x8000, 0x080c, 0x9d3e, 0x20e9, 0x0000, 0x2001, 0x19a5, 0x2003,
+ 0x0000, 0x7814, 0x2048, 0xa86f, 0x0200, 0xa873, 0x0000, 0xa814,
+ 0x8003, 0x60c2, 0xa830, 0x20a8, 0xa860, 0x20e0, 0xa85c, 0x9080,
+ 0x001b, 0x2098, 0x2001, 0x19a5, 0x0016, 0x200c, 0x080c, 0xda05,
+ 0x001e, 0xa804, 0x9005, 0x0110, 0x2048, 0x0c60, 0x0051, 0x7814,
+ 0x2048, 0x080c, 0x0fff, 0x080c, 0xa06b, 0x012e, 0x009e, 0x00de,
+ 0x0005, 0x60c0, 0x8004, 0x9084, 0x0003, 0x9005, 0x0130, 0x9082,
+ 0x0004, 0x20a3, 0x0000, 0x8000, 0x1de0, 0x0005, 0x080c, 0x9cf3,
+ 0x7003, 0x7800, 0x7808, 0x8007, 0x700a, 0x60c3, 0x0008, 0x0804,
+ 0xa06b, 0x00d6, 0x00e6, 0x080c, 0x9d3e, 0x7814, 0x9084, 0xff00,
+ 0x2073, 0x0200, 0x8e70, 0x8e70, 0x9096, 0xdf00, 0x0138, 0x9096,
+ 0xe000, 0x0120, 0x2073, 0x0010, 0x8e70, 0x0030, 0x9095, 0x0010,
+ 0x2272, 0x8e70, 0x2073, 0x0034, 0x8e70, 0x2069, 0x1805, 0x20a9,
+ 0x0004, 0x2d76, 0x8d68, 0x8e70, 0x1f04, 0x9a71, 0x2069, 0x1801,
+ 0x20a9, 0x0004, 0x2d76, 0x8d68, 0x8e70, 0x1f04, 0x9a7a, 0x9096,
+ 0xdf00, 0x0130, 0x9096, 0xe000, 0x0118, 0x60c3, 0x0018, 0x00f0,
+ 0x2069, 0x19b5, 0x9086, 0xdf00, 0x0110, 0x2069, 0x19cf, 0x20a9,
+ 0x001a, 0x9e86, 0x0260, 0x1148, 0x00c6, 0x2061, 0x0200, 0x6010,
+ 0x8000, 0x6012, 0x00ce, 0x2071, 0x0240, 0x2d04, 0x8007, 0x2072,
+ 0x8d68, 0x8e70, 0x1f04, 0x9a91, 0x60c3, 0x004c, 0x080c, 0xa06b,
+ 0x00ee, 0x00de, 0x0005, 0x080c, 0x9cf3, 0x7003, 0x6300, 0x7007,
+ 0x0028, 0x7808, 0x700e, 0x60c3, 0x0008, 0x0804, 0xa06b, 0x00d6,
+ 0x0026, 0x0016, 0x080c, 0x9d3e, 0x7003, 0x0200, 0x7814, 0x700e,
+ 0x00e6, 0x9ef0, 0x0004, 0x2009, 0x0001, 0x2011, 0x000c, 0x2069,
+ 0x1925, 0x6810, 0xd084, 0x1148, 0x2073, 0x0500, 0x8e70, 0x2073,
+ 0x0000, 0x8e70, 0x8108, 0x9290, 0x0004, 0x2073, 0x0800, 0x8e70,
+ 0x2073, 0x0000, 0x00ee, 0x7206, 0x710a, 0x62c2, 0x080c, 0xa06b,
+ 0x001e, 0x002e, 0x00de, 0x0005, 0x2001, 0x1818, 0x2004, 0x609a,
+ 0x0804, 0xa06b, 0x080c, 0x9cf3, 0x7003, 0x5200, 0x2069, 0x1847,
+ 0x6804, 0xd084, 0x0130, 0x6828, 0x0016, 0x080c, 0x26d4, 0x710e,
+ 0x001e, 0x20a9, 0x0004, 0x20e1, 0x0001, 0x2099, 0x1805, 0x20e9,
+ 0x0000, 0x20a1, 0x0250, 0x4003, 0x20a9, 0x0004, 0x2099, 0x1801,
+ 0x20a1, 0x0254, 0x4003, 0x080c, 0xae80, 0x1120, 0xb8a0, 0x9082,
+ 0x007f, 0x0248, 0x2001, 0x181f, 0x2004, 0x7032, 0x2001, 0x1820,
+ 0x2004, 0x7036, 0x0030, 0x2001, 0x1818, 0x2004, 0x9084, 0x00ff,
+ 0x7036, 0x60c3, 0x001c, 0x0804, 0xa06b, 0x080c, 0x9cf3, 0x7003,
+ 0x0500, 0x080c, 0xae80, 0x1120, 0xb8a0, 0x9082, 0x007f, 0x0248,
+ 0x2001, 0x181f, 0x2004, 0x700a, 0x2001, 0x1820, 0x2004, 0x700e,
+ 0x0030, 0x2001, 0x1818, 0x2004, 0x9084, 0x00ff, 0x700e, 0x20a9,
+ 0x0004, 0x20e1, 0x0001, 0x2099, 0x1805, 0x20e9, 0x0000, 0x20a1,
+ 0x0250, 0x4003, 0x60c3, 0x0010, 0x0804, 0xa06b, 0x080c, 0x9cf3,
+ 0x9006, 0x080c, 0x6b97, 0xb8a0, 0x9086, 0x007e, 0x1170, 0x2011,
+ 0x0240, 0x2013, 0x22ff, 0x2011, 0x0241, 0x2013, 0xfffe, 0x7003,
+ 0x0400, 0x620c, 0xc2b4, 0x620e, 0x0058, 0x7814, 0x0096, 0x904d,
+ 0x0120, 0x9006, 0xa89a, 0xa8a6, 0xa8aa, 0x009e, 0x7003, 0x0300,
+ 0xb8a0, 0x9086, 0x007e, 0x1904, 0x9bd1, 0x00d6, 0x2069, 0x196d,
+ 0x2001, 0x1837, 0x2004, 0xd0a4, 0x0188, 0x6800, 0x700a, 0x6808,
+ 0x9084, 0x2000, 0x7012, 0x080c, 0xae97, 0x680c, 0x7016, 0x701f,
+ 0x2710, 0x6818, 0x7022, 0x681c, 0x7026, 0x00f0, 0x6800, 0x700a,
+ 0x6804, 0x700e, 0x00f6, 0x2079, 0x0100, 0x080c, 0x769d, 0x1128,
+ 0x78e3, 0x0000, 0x080c, 0x2715, 0x78e2, 0x00fe, 0x6808, 0x080c,
+ 0x769d, 0x1118, 0x9084, 0x37ff, 0x0010, 0x9084, 0x3fff, 0x7012,
+ 0x080c, 0xae97, 0x680c, 0x7016, 0x00de, 0x20a9, 0x0004, 0x20e1,
+ 0x0001, 0x2099, 0x1805, 0x20e9, 0x0000, 0x20a1, 0x0256, 0x4003,
+ 0x20a9, 0x0004, 0x2099, 0x1801, 0x20a1, 0x025a, 0x4003, 0x00d6,
+ 0x080c, 0xa8d7, 0x2069, 0x1975, 0x2071, 0x024e, 0x6800, 0xc0dd,
+ 0x7002, 0x080c, 0x5824, 0xd0e4, 0x0110, 0x680c, 0x700e, 0x00de,
+ 0x04a8, 0x2001, 0x1837, 0x2004, 0xd0a4, 0x0170, 0x0016, 0x2001,
+ 0x196e, 0x200c, 0x60e0, 0x9106, 0x0130, 0x2100, 0x60e3, 0x0000,
+ 0x080c, 0x2715, 0x61e2, 0x001e, 0x20e1, 0x0001, 0x2099, 0x196d,
+ 0x20e9, 0x0000, 0x20a1, 0x024e, 0x20a9, 0x0008, 0x4003, 0x20a9,
+ 0x0004, 0x2099, 0x1805, 0x20a1, 0x0256, 0x4003, 0x20a9, 0x0004,
+ 0x2099, 0x1801, 0x20a1, 0x025a, 0x4003, 0x080c, 0xa8d7, 0x20a1,
+ 0x024e, 0x20a9, 0x0008, 0x2099, 0x1975, 0x4003, 0x60c3, 0x0074,
+ 0x0804, 0xa06b, 0x080c, 0x9cf3, 0x7003, 0x2010, 0x7007, 0x0014,
+ 0x700b, 0x0800, 0x700f, 0x2000, 0x9006, 0x00f6, 0x2079, 0x1847,
+ 0x7904, 0x00fe, 0xd1ac, 0x1110, 0x9085, 0x0020, 0xd1a4, 0x0110,
+ 0x9085, 0x0010, 0x9085, 0x0002, 0x00d6, 0x0804, 0x9ca3, 0x7026,
+ 0x60c3, 0x0014, 0x0804, 0xa06b, 0x080c, 0x9cf3, 0x7003, 0x5000,
+ 0x0804, 0x9b70, 0x080c, 0x9cf3, 0x7003, 0x2110, 0x7007, 0x0014,
+ 0x60c3, 0x0014, 0x0804, 0xa06b, 0x080c, 0x9d35, 0x0010, 0x080c,
+ 0x9d3e, 0x7003, 0x0200, 0x60c3, 0x0004, 0x0804, 0xa06b, 0x080c,
+ 0x9d3e, 0x7003, 0x0100, 0x700b, 0x0003, 0x700f, 0x2a00, 0x60c3,
+ 0x0008, 0x0804, 0xa06b, 0x080c, 0x9d3e, 0x7003, 0x0200, 0x0804,
+ 0x9b70, 0x080c, 0x9d3e, 0x7003, 0x0100, 0x782c, 0x9005, 0x0110,
+ 0x700a, 0x0010, 0x700b, 0x0003, 0x7814, 0x700e, 0x60c3, 0x0008,
+ 0x0804, 0xa06b, 0x00d6, 0x080c, 0x9d3e, 0x7003, 0x0210, 0x7007,
+ 0x0014, 0x700b, 0x0800, 0xb894, 0x9086, 0x0014, 0x1198, 0xb99c,
+ 0x9184, 0x0030, 0x0190, 0xb998, 0x9184, 0xc000, 0x1140, 0xd1ec,
+ 0x0118, 0x700f, 0x2100, 0x0058, 0x700f, 0x0100, 0x0040, 0x700f,
+ 0x0400, 0x0028, 0x700f, 0x0700, 0x0010, 0x700f, 0x0800, 0x00f6,
+ 0x2079, 0x1847, 0x7904, 0x00fe, 0xd1ac, 0x1110, 0x9085, 0x0020,
+ 0xd1a4, 0x0110, 0x9085, 0x0010, 0x2009, 0x1869, 0x210c, 0xd184,
+ 0x1110, 0x9085, 0x0002, 0x0026, 0x2009, 0x1867, 0x210c, 0xd1e4,
+ 0x0150, 0xc0c5, 0xbad4, 0xd28c, 0x1108, 0xc0cd, 0x9094, 0x0030,
+ 0x9296, 0x0010, 0x0140, 0xd1ec, 0x0130, 0x9094, 0x0030, 0x9296,
+ 0x0010, 0x0108, 0xc0bd, 0x002e, 0x7026, 0x60c3, 0x0014, 0x00de,
+ 0x0804, 0xa06b, 0x080c, 0x9d3e, 0x7003, 0x0210, 0x7007, 0x0014,
+ 0x700f, 0x0100, 0x60c3, 0x0014, 0x0804, 0xa06b, 0x080c, 0x9d3e,
+ 0x7003, 0x0200, 0x0804, 0x9aee, 0x080c, 0x9d3e, 0x7003, 0x0100,
+ 0x700b, 0x0003, 0x700f, 0x2a00, 0x60c3, 0x0008, 0x0804, 0xa06b,
+ 0x080c, 0x9d3e, 0x7003, 0x0100, 0x700b, 0x000b, 0x60c3, 0x0008,
+ 0x0804, 0xa06b, 0x0026, 0x00d6, 0x0036, 0x0046, 0x2019, 0x3200,
+ 0x2021, 0x0800, 0x0040, 0x0026, 0x00d6, 0x0036, 0x0046, 0x2019,
+ 0x2200, 0x2021, 0x0100, 0x080c, 0xa8ec, 0xb810, 0x9305, 0x7002,
0xb814, 0x7006, 0x2069, 0x1800, 0x687c, 0x700a, 0x6880, 0x700e,
- 0x2001, 0x0099, 0x7a20, 0x9296, 0x0005, 0x0108, 0xc0bc, 0x7012,
- 0x0804, 0x9d5f, 0x0026, 0x080c, 0xa8d5, 0xb810, 0x9085, 0x8500,
+ 0x9485, 0x0029, 0x7012, 0x004e, 0x003e, 0x00de, 0x080c, 0xa05f,
+ 0x721a, 0x9f95, 0x0000, 0x7222, 0x7027, 0xffff, 0x2071, 0x024c,
+ 0x002e, 0x0005, 0x0026, 0x080c, 0xa8ec, 0x7003, 0x02ff, 0x7007,
+ 0xfffc, 0x00d6, 0x2069, 0x1800, 0x687c, 0x700a, 0x6880, 0x700e,
+ 0x00de, 0x7013, 0x2029, 0x0c10, 0x7003, 0x0100, 0x7007, 0x0000,
+ 0x700b, 0xfc02, 0x700f, 0x0000, 0x0005, 0x0026, 0x00d6, 0x0036,
+ 0x0046, 0x2019, 0x3300, 0x2021, 0x0800, 0x0040, 0x0026, 0x00d6,
+ 0x0036, 0x0046, 0x2019, 0x2300, 0x2021, 0x0100, 0x080c, 0xa8ec,
+ 0xb810, 0x9305, 0x7002, 0xb814, 0x7006, 0x2069, 0x1800, 0xb810,
+ 0x9005, 0x1140, 0xb814, 0x9005, 0x1128, 0x700b, 0x00ff, 0x700f,
+ 0xfffe, 0x0020, 0x687c, 0x700a, 0x6880, 0x700e, 0x0000, 0x9485,
+ 0x0098, 0x7012, 0x004e, 0x003e, 0x00de, 0x080c, 0xa05f, 0x721a,
+ 0x7a08, 0x7222, 0x2f10, 0x7226, 0x2071, 0x024c, 0x002e, 0x0005,
+ 0x080c, 0xa05f, 0x721a, 0x7a08, 0x7222, 0x7814, 0x7026, 0x2071,
+ 0x024c, 0x002e, 0x0005, 0x00b6, 0x00c6, 0x00d6, 0x00e6, 0x00f6,
+ 0x2069, 0x0200, 0x2071, 0x0240, 0x6004, 0x908a, 0x0085, 0x0a0c,
+ 0x0d79, 0x908a, 0x0092, 0x1a0c, 0x0d79, 0x6110, 0x2158, 0xb984,
+ 0x2c78, 0x2061, 0x0100, 0x619a, 0x9082, 0x0085, 0x0033, 0x00fe,
+ 0x00ee, 0x00de, 0x00ce, 0x00be, 0x0005, 0x9dac, 0x9dbb, 0x9dc6,
+ 0x9daa, 0x9daa, 0x9daa, 0x9dac, 0x9daa, 0x9daa, 0x9daa, 0x9daa,
+ 0x9daa, 0x9daa, 0x080c, 0x0d79, 0x0411, 0x60c3, 0x0000, 0x0026,
+ 0x080c, 0x2a11, 0x0228, 0x2011, 0x0101, 0x2204, 0xc0c5, 0x2012,
+ 0x002e, 0x0804, 0xa06b, 0x0431, 0x7808, 0x700a, 0x7814, 0x700e,
+ 0x7017, 0xffff, 0x60c3, 0x000c, 0x0804, 0xa06b, 0x04a1, 0x7003,
+ 0x0003, 0x7007, 0x0300, 0x60c3, 0x0004, 0x0804, 0xa06b, 0x0026,
+ 0x080c, 0xa8ec, 0xb810, 0x9085, 0x8100, 0x7002, 0xb814, 0x7006,
+ 0x2069, 0x1800, 0x687c, 0x700a, 0x6880, 0x700e, 0x7013, 0x0009,
+ 0x0804, 0x9d0e, 0x0026, 0x080c, 0xa8ec, 0xb810, 0x9085, 0x8400,
0x7002, 0xb814, 0x7006, 0x2069, 0x1800, 0x687c, 0x700a, 0x6880,
0x700e, 0x2001, 0x0099, 0x7a20, 0x9296, 0x0005, 0x0108, 0xc0bc,
- 0x7012, 0x0804, 0x9d5f, 0x00b6, 0x00c6, 0x00d6, 0x00e6, 0x00f6,
- 0x2c78, 0x2069, 0x0200, 0x2071, 0x0240, 0x7804, 0x908a, 0x0040,
- 0x0a0c, 0x0d85, 0x908a, 0x0057, 0x1a0c, 0x0d85, 0x7910, 0x2158,
- 0xb984, 0x2061, 0x0100, 0x619a, 0x9082, 0x0040, 0x0033, 0x00fe,
- 0x00ee, 0x00de, 0x00ce, 0x00be, 0x0005, 0x9e38, 0x9e38, 0x9e38,
- 0x9e69, 0x9e38, 0x9e38, 0x9e38, 0x9e38, 0x9e38, 0x9e38, 0x9e38,
- 0xa428, 0xa42d, 0xa432, 0xa437, 0x9e38, 0x9e38, 0x9e38, 0xa423,
- 0x080c, 0x0d85, 0x6813, 0x0008, 0xba8c, 0x8210, 0xb8d4, 0xd084,
- 0x0180, 0x2001, 0x1b73, 0x200c, 0x8108, 0x2102, 0x2001, 0x1b72,
- 0x201c, 0x1218, 0x8318, 0x2302, 0x0ea0, 0x7952, 0x712e, 0x7b4e,
- 0x732a, 0x9294, 0x00ff, 0xba8e, 0x8217, 0x721a, 0xba10, 0x9295,
- 0x0600, 0x7202, 0xba14, 0x7206, 0x2069, 0x1800, 0x6a7c, 0x720a,
- 0x6a80, 0x720e, 0x7013, 0x0829, 0x2f10, 0x7222, 0x7027, 0xffff,
- 0x0005, 0x0016, 0x7814, 0x9084, 0x0700, 0x8007, 0x0013, 0x001e,
- 0x0005, 0x9e79, 0x9e79, 0x9e7b, 0x9e79, 0x9e79, 0x9e79, 0x9e95,
- 0x9e79, 0x080c, 0x0d85, 0x7914, 0x918c, 0x08ff, 0x918d, 0xf600,
- 0x7916, 0x2009, 0x0003, 0x00b9, 0x2069, 0x1847, 0x6804, 0xd0bc,
- 0x0130, 0x682c, 0x9084, 0x00ff, 0x8007, 0x7032, 0x0010, 0x7033,
- 0x3f00, 0x60c3, 0x0001, 0x0804, 0xa05a, 0x2009, 0x0003, 0x0019,
- 0x7033, 0x7f00, 0x0cb0, 0x0016, 0x080c, 0xa8d5, 0x001e, 0xb810,
- 0x9085, 0x0100, 0x7002, 0xb814, 0x7006, 0x2069, 0x1800, 0x6a7c,
- 0x720a, 0x6a80, 0x720e, 0x7013, 0x0888, 0x918d, 0x0008, 0x7116,
- 0x080c, 0xa04e, 0x721a, 0x7a08, 0x7222, 0x2f10, 0x7226, 0x0005,
- 0x00b6, 0x00e6, 0x00d6, 0x00c6, 0x0066, 0x0056, 0x0046, 0x0036,
- 0x2061, 0x0100, 0x2071, 0x1800, 0x7160, 0x7810, 0x2058, 0x76dc,
- 0x96b4, 0x0028, 0x0110, 0x737c, 0x7480, 0x2500, 0x76dc, 0x96b4,
- 0x0028, 0x0140, 0x2001, 0x04ff, 0x6062, 0x6067, 0xffff, 0x636a,
- 0x646e, 0x0050, 0x2001, 0x00ff, 0x9085, 0x0400, 0x6062, 0x6067,
- 0xffff, 0x606b, 0x0000, 0x616e, 0xb8b8, 0x6073, 0x0530, 0x6077,
- 0x0008, 0xb88c, 0x8000, 0x9084, 0x00ff, 0xb88e, 0x8007, 0x9085,
- 0x0020, 0x607a, 0x607f, 0x0000, 0x2b00, 0x6082, 0x6087, 0xffff,
- 0x7814, 0x0096, 0x2048, 0xa848, 0x608a, 0xa844, 0x608e, 0xa838,
- 0x60c6, 0xa834, 0x60ca, 0x009e, 0xb86c, 0x60ce, 0x60ab, 0x0036,
- 0x60af, 0x95d5, 0x60d7, 0x0000, 0x2001, 0x1837, 0x2004, 0x9084,
- 0x0028, 0x0128, 0x609f, 0x0000, 0x2001, 0x0092, 0x0058, 0x6028,
- 0xc0bd, 0x602a, 0x609f, 0x00ff, 0x2011, 0xffff, 0x080c, 0x2af5,
- 0x2001, 0x00b2, 0x2010, 0x900e, 0x080c, 0x2b04, 0x2009, 0x07d0,
- 0x080c, 0x88f1, 0x003e, 0x004e, 0x005e, 0x006e, 0x00ce, 0x00de,
- 0x00ee, 0x00be, 0x0005, 0x00b6, 0x00e6, 0x00d6, 0x00c6, 0x0066,
- 0x0056, 0x0046, 0x0036, 0x2061, 0x0100, 0x2071, 0x1800, 0x7160,
- 0x7810, 0x2058, 0xb8a0, 0x2028, 0x76dc, 0xd6ac, 0x1168, 0x9582,
- 0x007e, 0x1250, 0x2500, 0x9094, 0xff80, 0x1130, 0x9080, 0x3489,
- 0x2015, 0x9294, 0x00ff, 0x0020, 0xb910, 0xba14, 0x737c, 0x7480,
- 0x70dc, 0xd0ac, 0x1130, 0x9582, 0x007e, 0x1218, 0x9584, 0xff80,
- 0x0138, 0x9185, 0x0400, 0x6062, 0x6266, 0x636a, 0x646e, 0x0030,
- 0x6063, 0x0400, 0x6266, 0x606b, 0x0000, 0x616e, 0xb8b8, 0x6072,
- 0x6077, 0x0000, 0xb864, 0xd0a4, 0x0110, 0x6077, 0x0008, 0xb88c,
- 0x8000, 0x9084, 0x00ff, 0xb88e, 0x8007, 0x9085, 0x0020, 0x607a,
- 0x607f, 0x0000, 0x2b00, 0x6082, 0x6087, 0xffff, 0x7814, 0x0096,
- 0x2048, 0xa848, 0x608a, 0xa844, 0x608e, 0xa838, 0x60c6, 0xa834,
- 0x60ca, 0x009e, 0xb86c, 0x60ce, 0x60ab, 0x0036, 0x60af, 0x95d5,
- 0x60d7, 0x0000, 0xba84, 0x629e, 0x00f6, 0x2079, 0x0140, 0x7803,
- 0x0000, 0x00fe, 0x900e, 0x2011, 0x0092, 0x080c, 0x2b04, 0x2009,
- 0x07d0, 0x080c, 0x88f1, 0x003e, 0x004e, 0x005e, 0x006e, 0x00ce,
- 0x00de, 0x00ee, 0x00be, 0x0005, 0x00b6, 0x0096, 0x00e6, 0x00d6,
- 0x00c6, 0x0056, 0x0046, 0x0036, 0x2061, 0x0100, 0x2071, 0x1800,
- 0x7810, 0x2058, 0xb8a0, 0x2028, 0xb910, 0xba14, 0x737c, 0x7480,
- 0x7820, 0x0002, 0x9fd9, 0x9fd9, 0x9fd9, 0x9fd9, 0x9fd9, 0x9fd9,
- 0x9fd9, 0x9fd9, 0x9fd9, 0x9fd9, 0x9fdb, 0x9fd9, 0x9fd9, 0x9fd9,
- 0x9fd9, 0x080c, 0x0d85, 0xb884, 0x609e, 0x7814, 0x2048, 0xa87c,
- 0xd0fc, 0x0558, 0xaf90, 0x9784, 0xff00, 0x9105, 0x6062, 0x873f,
- 0x9784, 0xff00, 0x0006, 0x7814, 0x2048, 0xa878, 0xc0fc, 0x9005,
- 0x000e, 0x1160, 0xaf94, 0x87ff, 0x0198, 0x2039, 0x0098, 0x9705,
- 0x6072, 0x7808, 0x6082, 0x2f00, 0x6086, 0x0038, 0x9185, 0x2200,
- 0x6062, 0x6073, 0x0129, 0x6077, 0x0000, 0xb884, 0x609e, 0x0050,
- 0x2039, 0x0029, 0x9705, 0x6072, 0x0cc0, 0x9185, 0x0200, 0x6062,
- 0x6073, 0x2029, 0xa87c, 0xd0fc, 0x0118, 0xaf94, 0x87ff, 0x1120,
- 0x2f00, 0x6082, 0x7808, 0x6086, 0x6266, 0x636a, 0x646e, 0x6077,
- 0x0000, 0xb88c, 0x8000, 0x9084, 0x00ff, 0xb88e, 0x8007, 0x607a,
- 0x607f, 0x0000, 0xa848, 0x608a, 0xa844, 0x608e, 0xa838, 0x60c6,
- 0xa834, 0x60ca, 0xb86c, 0x60ce, 0x60af, 0x95d5, 0x60d7, 0x0000,
- 0x080c, 0xa8b5, 0x2009, 0x07d0, 0x60c4, 0x9084, 0xfff0, 0x9005,
- 0x0110, 0x2009, 0x1b58, 0x080c, 0x88f1, 0x003e, 0x004e, 0x005e,
- 0x00ce, 0x00de, 0x00ee, 0x009e, 0x00be, 0x0005, 0x7a40, 0x9294,
- 0x00ff, 0x8217, 0x0005, 0x00d6, 0x2069, 0x19e9, 0x686b, 0x0001,
- 0x00de, 0x0005, 0x60a3, 0x0056, 0x60a7, 0x9575, 0x00f1, 0x080c,
- 0x88e3, 0x0005, 0x0016, 0x2001, 0x180c, 0x200c, 0x9184, 0x0600,
- 0x9086, 0x0600, 0x0128, 0x0089, 0x080c, 0x88e3, 0x001e, 0x0005,
- 0xc1e5, 0x2001, 0x180c, 0x2102, 0x2001, 0x19ea, 0x2003, 0x0000,
- 0x2001, 0x19f5, 0x2003, 0x0000, 0x0c88, 0x0006, 0x0016, 0x0026,
- 0x2009, 0x1804, 0x2011, 0x0009, 0x080c, 0x2b04, 0x002e, 0x001e,
- 0x000e, 0x0005, 0x0016, 0x00c6, 0x0006, 0x080c, 0xaae0, 0x0106,
- 0x2061, 0x0100, 0x61a4, 0x60a7, 0x95f5, 0x0016, 0x0026, 0x2009,
- 0x1804, 0x2011, 0x0008, 0x080c, 0x2b04, 0x002e, 0x001e, 0x010e,
- 0x090c, 0xaafc, 0x000e, 0xa001, 0xa001, 0xa001, 0x61a6, 0x00ce,
- 0x001e, 0x0005, 0x00c6, 0x00d6, 0x0016, 0x0026, 0x2061, 0x0100,
- 0x2069, 0x0140, 0x080c, 0x76a5, 0x1510, 0x2001, 0x1a0e, 0x2004,
- 0x9005, 0x1904, 0xa109, 0x080c, 0x7747, 0x11a8, 0x2069, 0x0380,
- 0x6843, 0x0101, 0x6844, 0xd084, 0x1de8, 0x2061, 0x0100, 0x6020,
- 0xd0b4, 0x1120, 0x6024, 0xd084, 0x090c, 0x0d85, 0x6843, 0x0100,
- 0x080c, 0x88e3, 0x04b0, 0x00c6, 0x2061, 0x19e9, 0x00f0, 0x6904,
- 0x9194, 0x4000, 0x0598, 0x080c, 0xa08a, 0x080c, 0x2acb, 0x00c6,
- 0x2061, 0x19e9, 0x6134, 0x9192, 0x0008, 0x1278, 0x8108, 0x6136,
- 0x080c, 0xaae0, 0x6130, 0x080c, 0xaafc, 0x00ce, 0x81ff, 0x01c8,
- 0x080c, 0x88e3, 0x080c, 0xa07d, 0x00a0, 0x080c, 0xaae0, 0x6130,
- 0x91e5, 0x0000, 0x0150, 0x080c, 0xeb92, 0x080c, 0x88ec, 0x6003,
- 0x0001, 0x2009, 0x0014, 0x080c, 0xafcc, 0x080c, 0xaafc, 0x00ce,
- 0x0000, 0x002e, 0x001e, 0x00de, 0x00ce, 0x0005, 0x2001, 0x1a0e,
- 0x2004, 0x9005, 0x1db0, 0x00c6, 0x2061, 0x19e9, 0x6134, 0x9192,
- 0x0003, 0x1ad8, 0x8108, 0x6136, 0x00ce, 0x080c, 0x88e3, 0x080c,
- 0x6039, 0x2009, 0x1846, 0x2114, 0x8210, 0x220a, 0x0c10, 0x0096,
- 0x00c6, 0x00d6, 0x00e6, 0x0016, 0x0026, 0x080c, 0x88f9, 0x080c,
- 0xaae0, 0x2001, 0x0387, 0x2003, 0x0202, 0x2071, 0x19e9, 0x714c,
- 0x81ff, 0x0904, 0xa1c3, 0x2061, 0x0100, 0x2069, 0x0140, 0x080c,
- 0x76a5, 0x1518, 0x0036, 0x2019, 0x0002, 0x080c, 0xa380, 0x003e,
- 0x080c, 0xeb92, 0x704c, 0x9065, 0x0180, 0x2009, 0x004a, 0x6220,
- 0x9296, 0x0009, 0x1130, 0x6114, 0x2148, 0xa87b, 0x0006, 0x2009,
- 0x004a, 0x6003, 0x0003, 0x080c, 0xafcc, 0x2001, 0x0386, 0x2003,
- 0x5040, 0x080c, 0x7747, 0x0804, 0xa1c3, 0x6904, 0xd1f4, 0x0904,
- 0xa1d0, 0x080c, 0x2acb, 0x00c6, 0x704c, 0x9065, 0x090c, 0x0d85,
- 0x6020, 0x00ce, 0x9086, 0x0006, 0x1520, 0x61c8, 0x60c4, 0x9105,
- 0x1500, 0x714c, 0x9188, 0x0011, 0x2104, 0xd0e4, 0x01d0, 0x6214,
- 0x9294, 0x1800, 0x1128, 0x6224, 0x9294, 0x0002, 0x15e0, 0x0010,
- 0xc0e4, 0x200a, 0x6014, 0x9084, 0xe7fd, 0x9085, 0x0010, 0x6016,
- 0x704c, 0x2060, 0x080c, 0x9859, 0x2009, 0x0049, 0x080c, 0xafcc,
- 0x0450, 0x080c, 0xeb92, 0x704c, 0x9065, 0x9086, 0x1b56, 0x1158,
- 0x080c, 0xad9e, 0x1500, 0x2061, 0x1b56, 0x6064, 0x8000, 0x6066,
- 0x080c, 0x6039, 0x00c0, 0x0036, 0x2019, 0x0001, 0x080c, 0xa380,
- 0x003e, 0x714c, 0x2160, 0x2009, 0x004a, 0x6220, 0x9296, 0x0009,
- 0x1130, 0x6114, 0x2148, 0xa87b, 0x0006, 0x2009, 0x004a, 0x6003,
- 0x0003, 0x080c, 0xafcc, 0x2001, 0x0387, 0x2003, 0x0200, 0x080c,
- 0xaafc, 0x002e, 0x001e, 0x00ee, 0x00de, 0x00ce, 0x009e, 0x0005,
- 0xd1ec, 0x1904, 0xa169, 0x0804, 0xa16b, 0x0026, 0x00e6, 0x2071,
- 0x19e9, 0x706c, 0xd084, 0x01e8, 0xc084, 0x706e, 0x714c, 0x81ff,
- 0x01c0, 0x2071, 0x0100, 0x9188, 0x0008, 0x2114, 0x928e, 0x0006,
- 0x1138, 0x2009, 0x1984, 0x2011, 0x0012, 0x080c, 0x2b04, 0x0048,
- 0x928e, 0x0009, 0x0db0, 0x2009, 0x1984, 0x2011, 0x0016, 0x080c,
- 0x2b04, 0x00ee, 0x002e, 0x0005, 0x9036, 0x2001, 0x19f3, 0x2004,
- 0x9005, 0x0128, 0x9c06, 0x0128, 0x2c30, 0x600c, 0x0cc8, 0x9085,
- 0x0001, 0x0005, 0x00f6, 0x2079, 0x19e9, 0x610c, 0x9006, 0x600e,
- 0x6044, 0xc0fc, 0x6046, 0x86ff, 0x1140, 0x7824, 0x9c06, 0x1118,
- 0x7826, 0x782a, 0x0050, 0x792a, 0x0040, 0x00c6, 0x2660, 0x610e,
- 0x00ce, 0x7824, 0x9c06, 0x1108, 0x7e26, 0x080c, 0xa441, 0x080c,
- 0xce07, 0x00fe, 0x0005, 0x080c, 0x9ce2, 0x7003, 0x1200, 0x7838,
- 0x7012, 0x783c, 0x7016, 0x00c6, 0x7820, 0x9086, 0x0004, 0x1148,
- 0x7810, 0x9005, 0x0130, 0x00b6, 0x2058, 0xb810, 0xb914, 0x00be,
- 0x0020, 0x2061, 0x1800, 0x607c, 0x6180, 0x9084, 0x00ff, 0x700a,
- 0x710e, 0x00ce, 0x60c3, 0x002c, 0x0804, 0xa05a, 0x080c, 0x9ce2,
- 0x7003, 0x0f00, 0x7808, 0xd09c, 0x0128, 0xb810, 0x9084, 0x00ff,
- 0x700a, 0xb814, 0x700e, 0x60c3, 0x0008, 0x0804, 0xa05a, 0x0156,
- 0x080c, 0x9d2d, 0x7003, 0x0200, 0x080c, 0x89b1, 0x20a9, 0x0006,
- 0x2011, 0xffec, 0x2019, 0xffed, 0x9ef0, 0x0002, 0x2305, 0x2072,
- 0x8e70, 0x2205, 0x2072, 0x8e70, 0x9398, 0x0002, 0x9290, 0x0002,
- 0x1f04, 0xa26e, 0x60c3, 0x001c, 0x015e, 0x0804, 0xa05a, 0x0016,
- 0x0026, 0x080c, 0x9d09, 0x080c, 0x9d1b, 0x9e80, 0x0004, 0x20e9,
- 0x0000, 0x20a0, 0x7814, 0x0096, 0x2048, 0xa800, 0x2048, 0xa860,
- 0x20e0, 0xa85c, 0x9080, 0x0021, 0x2098, 0x009e, 0x7808, 0x9088,
- 0x0002, 0x21a8, 0x9192, 0x0010, 0x1250, 0x4003, 0x9080, 0x0004,
- 0x8003, 0x60c2, 0x080c, 0xa05a, 0x002e, 0x001e, 0x0005, 0x20a9,
- 0x0010, 0x4003, 0x080c, 0xa8c0, 0x20a1, 0x0240, 0x22a8, 0x4003,
- 0x0c68, 0x080c, 0x9ce2, 0x7003, 0x6200, 0x7808, 0x700e, 0x60c3,
- 0x0008, 0x0804, 0xa05a, 0x0016, 0x0026, 0x080c, 0x9ce2, 0x20e9,
- 0x0000, 0x20a1, 0x024c, 0x7814, 0x0096, 0x2048, 0xa800, 0x2048,
- 0xa860, 0x20e0, 0xa85c, 0x9080, 0x0023, 0x2098, 0x009e, 0x7808,
- 0x9088, 0x0002, 0x21a8, 0x4003, 0x8003, 0x60c2, 0x080c, 0xa05a,
- 0x002e, 0x001e, 0x0005, 0x00e6, 0x00c6, 0x0006, 0x0126, 0x2091,
- 0x8000, 0x2071, 0x19e9, 0x7010, 0x2060, 0x8cff, 0x0188, 0x080c,
- 0xce2d, 0x1110, 0x080c, 0xb91f, 0x600c, 0x0006, 0x080c, 0xd0a9,
- 0x600f, 0x0000, 0x080c, 0xaf2e, 0x080c, 0xa441, 0x00ce, 0x0c68,
- 0x2c00, 0x7012, 0x700e, 0x012e, 0x000e, 0x00ce, 0x00ee, 0x0005,
- 0x0126, 0x0156, 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x0066, 0x0026,
- 0x0016, 0x0006, 0x2091, 0x8000, 0x2001, 0x180c, 0x200c, 0x918c,
- 0xe7ff, 0x2102, 0x2069, 0x0100, 0x2079, 0x0140, 0x2071, 0x19e9,
- 0x7030, 0x2060, 0x8cff, 0x0548, 0x080c, 0xa08a, 0x6ac0, 0x68c3,
- 0x0000, 0x080c, 0x88ec, 0x00c6, 0x2061, 0x0100, 0x080c, 0xaa11,
- 0x00ce, 0x20a9, 0x01f4, 0x04b1, 0x080c, 0x97fe, 0x6044, 0xd0ac,
- 0x1128, 0x2001, 0x1989, 0x2004, 0x604a, 0x0020, 0x2009, 0x0013,
- 0x080c, 0xafcc, 0x000e, 0x001e, 0x002e, 0x006e, 0x00ce, 0x00de,
- 0x00ee, 0x00fe, 0x015e, 0x012e, 0x0005, 0x2001, 0x1800, 0x2004,
- 0x9096, 0x0001, 0x0d78, 0x9096, 0x0004, 0x0d60, 0x080c, 0x88ec,
- 0x6814, 0x9084, 0x0001, 0x0110, 0x68a7, 0x95f5, 0x6817, 0x0008,
- 0x68c3, 0x0000, 0x2011, 0x5fe3, 0x080c, 0x8834, 0x20a9, 0x01f4,
- 0x0009, 0x08c0, 0x6824, 0xd094, 0x0140, 0x6827, 0x0004, 0x7804,
- 0x9084, 0x4000, 0x190c, 0x2acb, 0x0090, 0xd084, 0x0118, 0x6827,
- 0x0001, 0x0010, 0x1f04, 0xa362, 0x7804, 0x9084, 0x1000, 0x0138,
- 0x2001, 0x0100, 0x080c, 0x2abb, 0x9006, 0x080c, 0x2abb, 0x0005,
- 0x0126, 0x0156, 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x0066, 0x0026,
- 0x0016, 0x0006, 0x2091, 0x8000, 0x2001, 0x180c, 0x200c, 0x918c,
- 0xdbff, 0x2102, 0x2069, 0x0100, 0x2079, 0x0140, 0x2071, 0x0380,
- 0x701c, 0x0006, 0x701f, 0x0202, 0x2071, 0x19e9, 0x704c, 0x2060,
- 0x8cff, 0x0904, 0xa3fd, 0x080c, 0xad50, 0x0904, 0xa3fd, 0x9386,
- 0x0002, 0x1128, 0x6814, 0x9084, 0x0002, 0x0904, 0xa3fd, 0x68af,
- 0x95f5, 0x6817, 0x0010, 0x2009, 0x00fa, 0x8109, 0x1df0, 0x69c6,
- 0x68cb, 0x0008, 0x080c, 0x88f9, 0x080c, 0x1e65, 0x2001, 0x0032,
- 0x6920, 0xd1bc, 0x0130, 0x8001, 0x1dd8, 0x692c, 0x918d, 0x0008,
- 0x692e, 0x20a9, 0x03e8, 0x6824, 0xd094, 0x0140, 0x6827, 0x0004,
- 0x7804, 0x9084, 0x4000, 0x190c, 0x2acb, 0x0090, 0xd08c, 0x0118,
- 0x6827, 0x0002, 0x0010, 0x1f04, 0xa3cb, 0x7804, 0x9084, 0x1000,
- 0x0138, 0x2001, 0x0100, 0x080c, 0x2abb, 0x9006, 0x080c, 0x2abb,
- 0x6827, 0x4000, 0x6824, 0x83ff, 0x1180, 0x2009, 0x0049, 0x6020,
- 0x9086, 0x0009, 0x0150, 0x080c, 0x9859, 0x6044, 0xd0ac, 0x1118,
- 0x6003, 0x0002, 0x0010, 0x080c, 0xafcc, 0x000e, 0x2071, 0x0380,
- 0xd08c, 0x1110, 0x701f, 0x0200, 0x000e, 0x001e, 0x002e, 0x006e,
- 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x015e, 0x012e, 0x0005, 0x00d6,
- 0x0126, 0x2091, 0x8000, 0x2069, 0x19e9, 0x6a06, 0x012e, 0x00de,
- 0x0005, 0x00d6, 0x0126, 0x2091, 0x8000, 0x2069, 0x19e9, 0x6a3e,
- 0x012e, 0x00de, 0x0005, 0x080c, 0x9e3a, 0x7047, 0x1000, 0x0098,
- 0x080c, 0x9e3a, 0x7047, 0x4000, 0x0070, 0x080c, 0x9e3a, 0x7047,
- 0x2000, 0x0048, 0x080c, 0x9e3a, 0x7047, 0x0400, 0x0020, 0x080c,
- 0x9e3a, 0x7047, 0x0200, 0x785c, 0x7032, 0x60c3, 0x0020, 0x0804,
- 0xa05a, 0x00e6, 0x2071, 0x19e9, 0x702c, 0x9005, 0x0110, 0x8001,
- 0x702e, 0x00ee, 0x0005, 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x0076,
- 0x0066, 0x0006, 0x0126, 0x2091, 0x8000, 0x2071, 0x19e9, 0x7620,
- 0x2660, 0x2678, 0x2039, 0x0001, 0x87ff, 0x0904, 0xa4e6, 0x8cff,
- 0x0904, 0xa4e6, 0x6020, 0x9086, 0x0006, 0x1904, 0xa4e1, 0x88ff,
- 0x0138, 0x2800, 0x9c06, 0x1904, 0xa4e1, 0x2039, 0x0000, 0x0050,
- 0x6010, 0x9b06, 0x1904, 0xa4e1, 0x85ff, 0x0120, 0x605c, 0x9106,
- 0x1904, 0xa4e1, 0x7030, 0x9c06, 0x15b0, 0x2069, 0x0100, 0x68c0,
- 0x9005, 0x1160, 0x6824, 0xd084, 0x0148, 0x6827, 0x0001, 0x080c,
- 0x88ec, 0x080c, 0xa56e, 0x7033, 0x0000, 0x0428, 0x080c, 0x88ec,
- 0x6820, 0xd0b4, 0x0110, 0x68a7, 0x95f5, 0x6817, 0x0008, 0x68c3,
- 0x0000, 0x080c, 0xa56e, 0x7033, 0x0000, 0x0036, 0x2069, 0x0140,
- 0x6b04, 0x9384, 0x1000, 0x0138, 0x2001, 0x0100, 0x080c, 0x2abb,
- 0x9006, 0x080c, 0x2abb, 0x2069, 0x0100, 0x6824, 0xd084, 0x0110,
- 0x6827, 0x0001, 0x003e, 0x7020, 0x9c36, 0x1110, 0x660c, 0x7622,
- 0x701c, 0x9c36, 0x1140, 0x2c00, 0x9f36, 0x0118, 0x2f00, 0x701e,
- 0x0010, 0x701f, 0x0000, 0x660c, 0x0066, 0x2c00, 0x9f06, 0x0110,
- 0x7e0e, 0x0008, 0x2678, 0x89ff, 0x1168, 0x600f, 0x0000, 0x6014,
- 0x0096, 0x2048, 0x080c, 0xcc14, 0x0110, 0x080c, 0xe6cd, 0x009e,
- 0x080c, 0xaf69, 0x080c, 0xa441, 0x88ff, 0x1190, 0x00ce, 0x0804,
- 0xa45c, 0x2c78, 0x600c, 0x2060, 0x0804, 0xa45c, 0x9006, 0x012e,
- 0x000e, 0x006e, 0x007e, 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x0005,
- 0x601b, 0x0000, 0x00ce, 0x98c5, 0x0001, 0x0c88, 0x00f6, 0x00e6,
- 0x00d6, 0x0096, 0x00c6, 0x0066, 0x0026, 0x0006, 0x0126, 0x2091,
- 0x8000, 0x2071, 0x19e9, 0x7648, 0x2660, 0x2678, 0x8cff, 0x0904,
- 0xa55d, 0x6020, 0x9086, 0x0006, 0x1904, 0xa558, 0x87ff, 0x0128,
- 0x2700, 0x9c06, 0x1904, 0xa558, 0x0048, 0x6010, 0x9b06, 0x1904,
- 0xa558, 0x85ff, 0x0118, 0x605c, 0x9106, 0x15d0, 0x704c, 0x9c06,
- 0x1178, 0x0036, 0x2019, 0x0001, 0x080c, 0xa380, 0x703f, 0x0000,
- 0x9006, 0x704e, 0x706a, 0x7052, 0x706e, 0x080c, 0xadc0, 0x003e,
+ 0x7012, 0x0804, 0x9d70, 0x0026, 0x080c, 0xa8ec, 0xb810, 0x9085,
+ 0x8500, 0x7002, 0xb814, 0x7006, 0x2069, 0x1800, 0x687c, 0x700a,
+ 0x6880, 0x700e, 0x2001, 0x0099, 0x7a20, 0x9296, 0x0005, 0x0108,
+ 0xc0bc, 0x7012, 0x0804, 0x9d70, 0x00b6, 0x00c6, 0x00d6, 0x00e6,
+ 0x00f6, 0x2c78, 0x2069, 0x0200, 0x2071, 0x0240, 0x7804, 0x908a,
+ 0x0040, 0x0a0c, 0x0d79, 0x908a, 0x0057, 0x1a0c, 0x0d79, 0x7910,
+ 0x2158, 0xb984, 0x2061, 0x0100, 0x619a, 0x9082, 0x0040, 0x0033,
+ 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x00be, 0x0005, 0x9e49, 0x9e49,
+ 0x9e49, 0x9e7a, 0x9e49, 0x9e49, 0x9e49, 0x9e49, 0x9e49, 0x9e49,
+ 0x9e49, 0xa43f, 0xa444, 0xa449, 0xa44e, 0x9e49, 0x9e49, 0x9e49,
+ 0xa43a, 0x080c, 0x0d79, 0x6813, 0x0008, 0xba8c, 0x8210, 0xb8d4,
+ 0xd084, 0x0180, 0x2001, 0x1b73, 0x200c, 0x8108, 0x2102, 0x2001,
+ 0x1b72, 0x201c, 0x1218, 0x8318, 0x2302, 0x0ea0, 0x7952, 0x712e,
+ 0x7b4e, 0x732a, 0x9294, 0x00ff, 0xba8e, 0x8217, 0x721a, 0xba10,
+ 0x9295, 0x0600, 0x7202, 0xba14, 0x7206, 0x2069, 0x1800, 0x6a7c,
+ 0x720a, 0x6a80, 0x720e, 0x7013, 0x0829, 0x2f10, 0x7222, 0x7027,
+ 0xffff, 0x0005, 0x0016, 0x7814, 0x9084, 0x0700, 0x8007, 0x0013,
+ 0x001e, 0x0005, 0x9e8a, 0x9e8a, 0x9e8c, 0x9e8a, 0x9e8a, 0x9e8a,
+ 0x9ea6, 0x9e8a, 0x080c, 0x0d79, 0x7914, 0x918c, 0x08ff, 0x918d,
+ 0xf600, 0x7916, 0x2009, 0x0003, 0x00b9, 0x2069, 0x1847, 0x6804,
+ 0xd0bc, 0x0130, 0x682c, 0x9084, 0x00ff, 0x8007, 0x7032, 0x0010,
+ 0x7033, 0x3f00, 0x60c3, 0x0001, 0x0804, 0xa06b, 0x2009, 0x0003,
+ 0x0019, 0x7033, 0x7f00, 0x0cb0, 0x0016, 0x080c, 0xa8ec, 0x001e,
+ 0xb810, 0x9085, 0x0100, 0x7002, 0xb814, 0x7006, 0x2069, 0x1800,
+ 0x6a7c, 0x720a, 0x6a80, 0x720e, 0x7013, 0x0888, 0x918d, 0x0008,
+ 0x7116, 0x080c, 0xa05f, 0x721a, 0x7a08, 0x7222, 0x2f10, 0x7226,
+ 0x0005, 0x00b6, 0x00e6, 0x00d6, 0x00c6, 0x0066, 0x0056, 0x0046,
+ 0x0036, 0x2061, 0x0100, 0x2071, 0x1800, 0x7160, 0x7810, 0x2058,
+ 0x76dc, 0x96b4, 0x0028, 0x0110, 0x737c, 0x7480, 0x2500, 0x76dc,
+ 0x96b4, 0x0028, 0x0140, 0x2001, 0x04ff, 0x6062, 0x6067, 0xffff,
+ 0x636a, 0x646e, 0x0050, 0x2001, 0x00ff, 0x9085, 0x0400, 0x6062,
+ 0x6067, 0xffff, 0x606b, 0x0000, 0x616e, 0xb8b8, 0x6073, 0x0530,
+ 0x6077, 0x0008, 0xb88c, 0x8000, 0x9084, 0x00ff, 0xb88e, 0x8007,
+ 0x9085, 0x0020, 0x607a, 0x607f, 0x0000, 0x2b00, 0x6082, 0x6087,
+ 0xffff, 0x7814, 0x0096, 0x2048, 0xa848, 0x608a, 0xa844, 0x608e,
+ 0xa838, 0x60c6, 0xa834, 0x60ca, 0x009e, 0xb86c, 0x60ce, 0x60ab,
+ 0x0036, 0x60af, 0x95d5, 0x60d7, 0x0000, 0x2001, 0x1837, 0x2004,
+ 0x9084, 0x0028, 0x0128, 0x609f, 0x0000, 0x2001, 0x0092, 0x0058,
+ 0x6028, 0xc0bd, 0x602a, 0x609f, 0x00ff, 0x2011, 0xffff, 0x080c,
+ 0x2adc, 0x2001, 0x00b2, 0x2010, 0x900e, 0x080c, 0x2aeb, 0x2009,
+ 0x07d0, 0x080c, 0x88e9, 0x003e, 0x004e, 0x005e, 0x006e, 0x00ce,
+ 0x00de, 0x00ee, 0x00be, 0x0005, 0x00b6, 0x00e6, 0x00d6, 0x00c6,
+ 0x0066, 0x0056, 0x0046, 0x0036, 0x2061, 0x0100, 0x2071, 0x1800,
+ 0x7160, 0x7810, 0x2058, 0xb8a0, 0x2028, 0x76dc, 0xd6ac, 0x1168,
+ 0x9582, 0x007e, 0x1250, 0x2500, 0x9094, 0xff80, 0x1130, 0x9080,
+ 0x3474, 0x2015, 0x9294, 0x00ff, 0x0020, 0xb910, 0xba14, 0x737c,
+ 0x7480, 0x70dc, 0xd0ac, 0x1130, 0x9582, 0x007e, 0x1218, 0x9584,
+ 0xff80, 0x0138, 0x9185, 0x0400, 0x6062, 0x6266, 0x636a, 0x646e,
+ 0x0030, 0x6063, 0x0400, 0x6266, 0x606b, 0x0000, 0x616e, 0xb8b8,
+ 0x6072, 0x6077, 0x0000, 0xb864, 0xd0a4, 0x0110, 0x6077, 0x0008,
+ 0xb88c, 0x8000, 0x9084, 0x00ff, 0xb88e, 0x8007, 0x9085, 0x0020,
+ 0x607a, 0x607f, 0x0000, 0x2b00, 0x6082, 0x6087, 0xffff, 0x7814,
+ 0x0096, 0x2048, 0xa848, 0x608a, 0xa844, 0x608e, 0xa838, 0x60c6,
+ 0xa834, 0x60ca, 0x009e, 0xb86c, 0x60ce, 0x60ab, 0x0036, 0x60af,
+ 0x95d5, 0x60d7, 0x0000, 0xba84, 0x629e, 0x00f6, 0x2079, 0x0140,
+ 0x7803, 0x0000, 0x00fe, 0x900e, 0x2011, 0x0092, 0x080c, 0x2aeb,
+ 0x2009, 0x07d0, 0x080c, 0x88e9, 0x003e, 0x004e, 0x005e, 0x006e,
+ 0x00ce, 0x00de, 0x00ee, 0x00be, 0x0005, 0x00b6, 0x0096, 0x00e6,
+ 0x00d6, 0x00c6, 0x0056, 0x0046, 0x0036, 0x2061, 0x0100, 0x2071,
+ 0x1800, 0x7810, 0x2058, 0xb8a0, 0x2028, 0xb910, 0xba14, 0x737c,
+ 0x7480, 0x7820, 0x0002, 0x9fea, 0x9fea, 0x9fea, 0x9fea, 0x9fea,
+ 0x9fea, 0x9fea, 0x9fea, 0x9fea, 0x9fea, 0x9fec, 0x9fea, 0x9fea,
+ 0x9fea, 0x9fea, 0x080c, 0x0d79, 0xb884, 0x609e, 0x7814, 0x2048,
+ 0xa87c, 0xd0fc, 0x0558, 0xaf90, 0x9784, 0xff00, 0x9105, 0x6062,
+ 0x873f, 0x9784, 0xff00, 0x0006, 0x7814, 0x2048, 0xa878, 0xc0fc,
+ 0x9005, 0x000e, 0x1160, 0xaf94, 0x87ff, 0x0198, 0x2039, 0x0098,
+ 0x9705, 0x6072, 0x7808, 0x6082, 0x2f00, 0x6086, 0x0038, 0x9185,
+ 0x2200, 0x6062, 0x6073, 0x0129, 0x6077, 0x0000, 0xb884, 0x609e,
+ 0x0050, 0x2039, 0x0029, 0x9705, 0x6072, 0x0cc0, 0x9185, 0x0200,
+ 0x6062, 0x6073, 0x2029, 0xa87c, 0xd0fc, 0x0118, 0xaf94, 0x87ff,
+ 0x1120, 0x2f00, 0x6082, 0x7808, 0x6086, 0x6266, 0x636a, 0x646e,
+ 0x6077, 0x0000, 0xb88c, 0x8000, 0x9084, 0x00ff, 0xb88e, 0x8007,
+ 0x607a, 0x607f, 0x0000, 0xa848, 0x608a, 0xa844, 0x608e, 0xa838,
+ 0x60c6, 0xa834, 0x60ca, 0xb86c, 0x60ce, 0x60af, 0x95d5, 0x60d7,
+ 0x0000, 0x080c, 0xa8cc, 0x2009, 0x07d0, 0x60c4, 0x9084, 0xfff0,
+ 0x9005, 0x0110, 0x2009, 0x1b58, 0x080c, 0x88e9, 0x003e, 0x004e,
+ 0x005e, 0x00ce, 0x00de, 0x00ee, 0x009e, 0x00be, 0x0005, 0x7a40,
+ 0x9294, 0x00ff, 0x8217, 0x0005, 0x00d6, 0x2069, 0x19e9, 0x686b,
+ 0x0001, 0x00de, 0x0005, 0x60a3, 0x0056, 0x60a7, 0x9575, 0x00f1,
+ 0x080c, 0x88db, 0x0005, 0x0016, 0x2001, 0x180c, 0x200c, 0x9184,
+ 0x0600, 0x9086, 0x0600, 0x0128, 0x0089, 0x080c, 0x88db, 0x001e,
+ 0x0005, 0xc1e5, 0x2001, 0x180c, 0x2102, 0x2001, 0x19ea, 0x2003,
+ 0x0000, 0x2001, 0x19f5, 0x2003, 0x0000, 0x0c88, 0x0006, 0x0016,
+ 0x0026, 0x2009, 0x1804, 0x2011, 0x0009, 0x080c, 0x2aeb, 0x002e,
+ 0x001e, 0x000e, 0x0005, 0x0016, 0x00c6, 0x0006, 0x080c, 0xaaf7,
+ 0x0106, 0x2061, 0x0100, 0x61a4, 0x60a7, 0x95f5, 0x0016, 0x0026,
+ 0x2009, 0x1804, 0x2011, 0x0008, 0x080c, 0x2aeb, 0x002e, 0x001e,
+ 0x010e, 0x090c, 0xab13, 0x000e, 0xa001, 0xa001, 0xa001, 0x61a6,
+ 0x00ce, 0x001e, 0x0005, 0x00c6, 0x00d6, 0x0016, 0x0026, 0x2061,
+ 0x0100, 0x2069, 0x0140, 0x080c, 0x769d, 0x1510, 0x2001, 0x1a0e,
+ 0x2004, 0x9005, 0x1904, 0xa11a, 0x080c, 0x773f, 0x11a8, 0x2069,
+ 0x0380, 0x6843, 0x0101, 0x6844, 0xd084, 0x1de8, 0x2061, 0x0100,
+ 0x6020, 0xd0b4, 0x1120, 0x6024, 0xd084, 0x090c, 0x0d79, 0x6843,
+ 0x0100, 0x080c, 0x88db, 0x04b0, 0x00c6, 0x2061, 0x19e9, 0x00f0,
+ 0x6904, 0x9194, 0x4000, 0x0598, 0x080c, 0xa09b, 0x080c, 0x2ab2,
+ 0x00c6, 0x2061, 0x19e9, 0x6134, 0x9192, 0x0008, 0x1278, 0x8108,
+ 0x6136, 0x080c, 0xaaf7, 0x6130, 0x080c, 0xab13, 0x00ce, 0x81ff,
+ 0x01c8, 0x080c, 0x88db, 0x080c, 0xa08e, 0x00a0, 0x080c, 0xaaf7,
+ 0x6130, 0x91e5, 0x0000, 0x0150, 0x080c, 0xebfd, 0x080c, 0x88e4,
+ 0x6003, 0x0001, 0x2009, 0x0014, 0x080c, 0xafec, 0x080c, 0xab13,
+ 0x00ce, 0x0000, 0x002e, 0x001e, 0x00de, 0x00ce, 0x0005, 0x2001,
+ 0x1a0e, 0x2004, 0x9005, 0x1db0, 0x00c6, 0x2061, 0x19e9, 0x6134,
+ 0x9192, 0x0003, 0x1ad8, 0x8108, 0x6136, 0x00ce, 0x080c, 0x88db,
+ 0x080c, 0x6033, 0x2009, 0x1846, 0x2114, 0x8210, 0x220a, 0x0c10,
+ 0x0096, 0x00c6, 0x00d6, 0x00e6, 0x0016, 0x0026, 0x080c, 0x88f1,
+ 0x080c, 0xaaf7, 0x2001, 0x0387, 0x2003, 0x0202, 0x2071, 0x19e9,
+ 0x714c, 0x81ff, 0x0904, 0xa1d4, 0x2061, 0x0100, 0x2069, 0x0140,
+ 0x080c, 0x769d, 0x1518, 0x0036, 0x2019, 0x0002, 0x080c, 0xa391,
+ 0x003e, 0x080c, 0xebfd, 0x704c, 0x9065, 0x0180, 0x2009, 0x004a,
+ 0x6220, 0x9296, 0x0009, 0x1130, 0x6114, 0x2148, 0xa87b, 0x0006,
+ 0x2009, 0x004a, 0x6003, 0x0003, 0x080c, 0xafec, 0x2001, 0x0386,
+ 0x2003, 0x5040, 0x080c, 0x773f, 0x0804, 0xa1d4, 0x6904, 0xd1f4,
+ 0x0904, 0xa1e1, 0x080c, 0x2ab2, 0x00c6, 0x704c, 0x9065, 0x090c,
+ 0x0d79, 0x6020, 0x00ce, 0x9086, 0x0006, 0x1520, 0x61c8, 0x60c4,
+ 0x9105, 0x1500, 0x714c, 0x9188, 0x0011, 0x2104, 0xd0e4, 0x01d0,
+ 0x6214, 0x9294, 0x1800, 0x1128, 0x6224, 0x9294, 0x0002, 0x15e0,
+ 0x0010, 0xc0e4, 0x200a, 0x6014, 0x9084, 0xe7fd, 0x9085, 0x0010,
+ 0x6016, 0x704c, 0x2060, 0x080c, 0x9851, 0x2009, 0x0049, 0x080c,
+ 0xafec, 0x0450, 0x080c, 0xebfd, 0x704c, 0x9065, 0x9086, 0x1b56,
+ 0x1158, 0x080c, 0xadbe, 0x1500, 0x2061, 0x1b56, 0x6064, 0x8000,
+ 0x6066, 0x080c, 0x6033, 0x00c0, 0x0036, 0x2019, 0x0001, 0x080c,
+ 0xa391, 0x003e, 0x714c, 0x2160, 0x2009, 0x004a, 0x6220, 0x9296,
+ 0x0009, 0x1130, 0x6114, 0x2148, 0xa87b, 0x0006, 0x2009, 0x004a,
+ 0x6003, 0x0003, 0x080c, 0xafec, 0x2001, 0x0387, 0x2003, 0x0200,
+ 0x080c, 0xab13, 0x002e, 0x001e, 0x00ee, 0x00de, 0x00ce, 0x009e,
+ 0x0005, 0xd1ec, 0x1904, 0xa17a, 0x0804, 0xa17c, 0x0026, 0x00e6,
+ 0x2071, 0x19e9, 0x706c, 0xd084, 0x01e8, 0xc084, 0x706e, 0x714c,
+ 0x81ff, 0x01c0, 0x2071, 0x0100, 0x9188, 0x0008, 0x2114, 0x928e,
+ 0x0006, 0x1138, 0x2009, 0x1984, 0x2011, 0x0012, 0x080c, 0x2aeb,
+ 0x0048, 0x928e, 0x0009, 0x0db0, 0x2009, 0x1984, 0x2011, 0x0016,
+ 0x080c, 0x2aeb, 0x00ee, 0x002e, 0x0005, 0x9036, 0x2001, 0x19f3,
+ 0x2004, 0x9005, 0x0128, 0x9c06, 0x0128, 0x2c30, 0x600c, 0x0cc8,
+ 0x9085, 0x0001, 0x0005, 0x00f6, 0x2079, 0x19e9, 0x610c, 0x9006,
+ 0x600e, 0x6044, 0xc0fc, 0x6046, 0x86ff, 0x1140, 0x7824, 0x9c06,
+ 0x1118, 0x7826, 0x782a, 0x0050, 0x792a, 0x0040, 0x00c6, 0x2660,
+ 0x610e, 0x00ce, 0x7824, 0x9c06, 0x1108, 0x7e26, 0x080c, 0xa458,
+ 0x080c, 0xce24, 0x00fe, 0x0005, 0x080c, 0x9cf3, 0x7003, 0x1200,
+ 0x7838, 0x7012, 0x783c, 0x7016, 0x00c6, 0x7820, 0x9086, 0x0004,
+ 0x1148, 0x7810, 0x9005, 0x0130, 0x00b6, 0x2058, 0xb810, 0xb914,
+ 0x00be, 0x0020, 0x2061, 0x1800, 0x607c, 0x6180, 0x9084, 0x00ff,
+ 0x700a, 0x710e, 0x00ce, 0x60c3, 0x002c, 0x0804, 0xa06b, 0x080c,
+ 0x9cf3, 0x7003, 0x0f00, 0x7808, 0xd09c, 0x0128, 0xb810, 0x9084,
+ 0x00ff, 0x700a, 0xb814, 0x700e, 0x60c3, 0x0008, 0x0804, 0xa06b,
+ 0x0156, 0x080c, 0x9d3e, 0x7003, 0x0200, 0x080c, 0x89a9, 0x20a9,
+ 0x0006, 0x2011, 0xffec, 0x2019, 0xffed, 0x9ef0, 0x0002, 0x2305,
+ 0x2072, 0x8e70, 0x2205, 0x2072, 0x8e70, 0x9398, 0x0002, 0x9290,
+ 0x0002, 0x1f04, 0xa27f, 0x60c3, 0x001c, 0x015e, 0x0804, 0xa06b,
+ 0x0016, 0x0026, 0x080c, 0x9d1a, 0x080c, 0x9d2c, 0x9e80, 0x0004,
+ 0x20e9, 0x0000, 0x20a0, 0x7814, 0x0096, 0x2048, 0xa800, 0x2048,
+ 0xa860, 0x20e0, 0xa85c, 0x9080, 0x0021, 0x2098, 0x009e, 0x7808,
+ 0x9088, 0x0002, 0x21a8, 0x9192, 0x0010, 0x1250, 0x4003, 0x9080,
+ 0x0004, 0x8003, 0x60c2, 0x080c, 0xa06b, 0x002e, 0x001e, 0x0005,
+ 0x20a9, 0x0010, 0x4003, 0x080c, 0xa8d7, 0x20a1, 0x0240, 0x22a8,
+ 0x4003, 0x0c68, 0x080c, 0x9cf3, 0x7003, 0x6200, 0x7808, 0x700e,
+ 0x60c3, 0x0008, 0x0804, 0xa06b, 0x0016, 0x0026, 0x080c, 0x9cf3,
+ 0x20e9, 0x0000, 0x20a1, 0x024c, 0x7814, 0x0096, 0x2048, 0xa800,
+ 0x2048, 0xa860, 0x20e0, 0xa85c, 0x9080, 0x0023, 0x2098, 0x009e,
+ 0x7808, 0x9088, 0x0002, 0x21a8, 0x4003, 0x8003, 0x60c2, 0x080c,
+ 0xa06b, 0x002e, 0x001e, 0x0005, 0x00e6, 0x00c6, 0x0006, 0x0126,
+ 0x2091, 0x8000, 0x2071, 0x19e9, 0x7010, 0x2060, 0x8cff, 0x0188,
+ 0x080c, 0xce4a, 0x1110, 0x080c, 0xb93c, 0x600c, 0x0006, 0x080c,
+ 0xd0c6, 0x600f, 0x0000, 0x080c, 0xaf4e, 0x080c, 0xa458, 0x00ce,
+ 0x0c68, 0x2c00, 0x7012, 0x700e, 0x012e, 0x000e, 0x00ce, 0x00ee,
+ 0x0005, 0x0126, 0x0156, 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x0066,
+ 0x0026, 0x0016, 0x0006, 0x2091, 0x8000, 0x2001, 0x180c, 0x200c,
+ 0x918c, 0xe7ff, 0x2102, 0x2069, 0x0100, 0x2079, 0x0140, 0x2071,
+ 0x19e9, 0x7030, 0x2060, 0x8cff, 0x0548, 0x080c, 0xa09b, 0x6ac0,
+ 0x68c3, 0x0000, 0x080c, 0x88e4, 0x00c6, 0x2061, 0x0100, 0x080c,
+ 0xaa28, 0x00ce, 0x20a9, 0x01f4, 0x04b1, 0x080c, 0x97f6, 0x6044,
+ 0xd0ac, 0x1128, 0x2001, 0x1989, 0x2004, 0x604a, 0x0020, 0x2009,
+ 0x0013, 0x080c, 0xafec, 0x000e, 0x001e, 0x002e, 0x006e, 0x00ce,
+ 0x00de, 0x00ee, 0x00fe, 0x015e, 0x012e, 0x0005, 0x2001, 0x1800,
+ 0x2004, 0x9096, 0x0001, 0x0d78, 0x9096, 0x0004, 0x0d60, 0x080c,
+ 0x88e4, 0x6814, 0x9084, 0x0001, 0x0110, 0x68a7, 0x95f5, 0x6817,
+ 0x0008, 0x68c3, 0x0000, 0x2011, 0x5fdd, 0x080c, 0x882c, 0x20a9,
+ 0x01f4, 0x0009, 0x08c0, 0x6824, 0xd094, 0x0140, 0x6827, 0x0004,
+ 0x7804, 0x9084, 0x4000, 0x190c, 0x2ab2, 0x0090, 0xd084, 0x0118,
+ 0x6827, 0x0001, 0x0010, 0x1f04, 0xa373, 0x7804, 0x9084, 0x1000,
+ 0x0138, 0x2001, 0x0100, 0x080c, 0x2aa2, 0x9006, 0x080c, 0x2aa2,
+ 0x0005, 0x0126, 0x0156, 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x0066,
+ 0x0026, 0x0016, 0x0006, 0x2091, 0x8000, 0x2001, 0x180c, 0x200c,
+ 0x918c, 0xdbff, 0x2102, 0x2069, 0x0100, 0x2079, 0x0140, 0x2071,
+ 0x0380, 0x701c, 0x0006, 0x701f, 0x0202, 0x2071, 0x19e9, 0x704c,
+ 0x2060, 0x8cff, 0x0904, 0xa414, 0x080c, 0xad70, 0x0904, 0xa414,
+ 0x9386, 0x0002, 0x1128, 0x6814, 0x9084, 0x0002, 0x0904, 0xa414,
+ 0x68af, 0x95f5, 0x6817, 0x0010, 0x2009, 0x00fa, 0x8109, 0x1df0,
+ 0x69c6, 0x68cb, 0x0008, 0x080c, 0x88f1, 0x080c, 0x1e61, 0x2001,
+ 0x0032, 0x6920, 0xd1bc, 0x0130, 0x8001, 0x1dd8, 0x692c, 0x918d,
+ 0x0008, 0x692e, 0x0016, 0x2009, 0x0040, 0x080c, 0x223d, 0x001e,
+ 0x20a9, 0x03e8, 0x6824, 0xd094, 0x0140, 0x6827, 0x0004, 0x7804,
+ 0x9084, 0x4000, 0x190c, 0x2ab2, 0x0090, 0xd08c, 0x0118, 0x6827,
+ 0x0002, 0x0010, 0x1f04, 0xa3e2, 0x7804, 0x9084, 0x1000, 0x0138,
+ 0x2001, 0x0100, 0x080c, 0x2aa2, 0x9006, 0x080c, 0x2aa2, 0x6827,
+ 0x4000, 0x6824, 0x83ff, 0x1180, 0x2009, 0x0049, 0x6020, 0x9086,
+ 0x0009, 0x0150, 0x080c, 0x9851, 0x6044, 0xd0ac, 0x1118, 0x6003,
+ 0x0002, 0x0010, 0x080c, 0xafec, 0x000e, 0x2071, 0x0380, 0xd08c,
+ 0x1110, 0x701f, 0x0200, 0x000e, 0x001e, 0x002e, 0x006e, 0x00ce,
+ 0x00de, 0x00ee, 0x00fe, 0x015e, 0x012e, 0x0005, 0x00d6, 0x0126,
+ 0x2091, 0x8000, 0x2069, 0x19e9, 0x6a06, 0x012e, 0x00de, 0x0005,
+ 0x00d6, 0x0126, 0x2091, 0x8000, 0x2069, 0x19e9, 0x6a3e, 0x012e,
+ 0x00de, 0x0005, 0x080c, 0x9e4b, 0x7047, 0x1000, 0x0098, 0x080c,
+ 0x9e4b, 0x7047, 0x4000, 0x0070, 0x080c, 0x9e4b, 0x7047, 0x2000,
+ 0x0048, 0x080c, 0x9e4b, 0x7047, 0x0400, 0x0020, 0x080c, 0x9e4b,
+ 0x7047, 0x0200, 0x785c, 0x7032, 0x60c3, 0x0020, 0x0804, 0xa06b,
+ 0x00e6, 0x2071, 0x19e9, 0x702c, 0x9005, 0x0110, 0x8001, 0x702e,
+ 0x00ee, 0x0005, 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x0076, 0x0066,
+ 0x0006, 0x0126, 0x2091, 0x8000, 0x2071, 0x19e9, 0x7620, 0x2660,
+ 0x2678, 0x2039, 0x0001, 0x87ff, 0x0904, 0xa4fd, 0x8cff, 0x0904,
+ 0xa4fd, 0x6020, 0x9086, 0x0006, 0x1904, 0xa4f8, 0x88ff, 0x0138,
+ 0x2800, 0x9c06, 0x1904, 0xa4f8, 0x2039, 0x0000, 0x0050, 0x6010,
+ 0x9b06, 0x1904, 0xa4f8, 0x85ff, 0x0120, 0x605c, 0x9106, 0x1904,
+ 0xa4f8, 0x7030, 0x9c06, 0x15b0, 0x2069, 0x0100, 0x68c0, 0x9005,
+ 0x1160, 0x6824, 0xd084, 0x0148, 0x6827, 0x0001, 0x080c, 0x88e4,
+ 0x080c, 0xa585, 0x7033, 0x0000, 0x0428, 0x080c, 0x88e4, 0x6820,
+ 0xd0b4, 0x0110, 0x68a7, 0x95f5, 0x6817, 0x0008, 0x68c3, 0x0000,
+ 0x080c, 0xa585, 0x7033, 0x0000, 0x0036, 0x2069, 0x0140, 0x6b04,
+ 0x9384, 0x1000, 0x0138, 0x2001, 0x0100, 0x080c, 0x2aa2, 0x9006,
+ 0x080c, 0x2aa2, 0x2069, 0x0100, 0x6824, 0xd084, 0x0110, 0x6827,
+ 0x0001, 0x003e, 0x7020, 0x9c36, 0x1110, 0x660c, 0x7622, 0x701c,
+ 0x9c36, 0x1140, 0x2c00, 0x9f36, 0x0118, 0x2f00, 0x701e, 0x0010,
+ 0x701f, 0x0000, 0x660c, 0x0066, 0x2c00, 0x9f06, 0x0110, 0x7e0e,
+ 0x0008, 0x2678, 0x89ff, 0x1168, 0x600f, 0x0000, 0x6014, 0x0096,
+ 0x2048, 0x080c, 0xcc31, 0x0110, 0x080c, 0xe738, 0x009e, 0x080c,
+ 0xaf89, 0x080c, 0xa458, 0x88ff, 0x1190, 0x00ce, 0x0804, 0xa473,
+ 0x2c78, 0x600c, 0x2060, 0x0804, 0xa473, 0x9006, 0x012e, 0x000e,
+ 0x006e, 0x007e, 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x0005, 0x601b,
+ 0x0000, 0x00ce, 0x98c5, 0x0001, 0x0c88, 0x00f6, 0x00e6, 0x00d6,
+ 0x0096, 0x00c6, 0x0066, 0x0026, 0x0006, 0x0126, 0x2091, 0x8000,
+ 0x2071, 0x19e9, 0x7648, 0x2660, 0x2678, 0x8cff, 0x0904, 0xa574,
+ 0x6020, 0x9086, 0x0006, 0x1904, 0xa56f, 0x87ff, 0x0128, 0x2700,
+ 0x9c06, 0x1904, 0xa56f, 0x0048, 0x6010, 0x9b06, 0x1904, 0xa56f,
+ 0x85ff, 0x0118, 0x605c, 0x9106, 0x15d0, 0x704c, 0x9c06, 0x1178,
+ 0x0036, 0x2019, 0x0001, 0x080c, 0xa391, 0x703f, 0x0000, 0x9006,
+ 0x704e, 0x706a, 0x7052, 0x706e, 0x080c, 0xade0, 0x003e, 0x7048,
+ 0x9c36, 0x1110, 0x660c, 0x764a, 0x7044, 0x9c36, 0x1140, 0x2c00,
+ 0x9f36, 0x0118, 0x2f00, 0x7046, 0x0010, 0x7047, 0x0000, 0x660c,
+ 0x0066, 0x2c00, 0x9f06, 0x0110, 0x7e0e, 0x0008, 0x2678, 0x600f,
+ 0x0000, 0x6014, 0x2048, 0x080c, 0xcc31, 0x0110, 0x080c, 0xe738,
+ 0x080c, 0xaf89, 0x87ff, 0x1198, 0x00ce, 0x0804, 0xa51d, 0x2c78,
+ 0x600c, 0x2060, 0x0804, 0xa51d, 0x9006, 0x012e, 0x000e, 0x002e,
+ 0x006e, 0x00ce, 0x009e, 0x00de, 0x00ee, 0x00fe, 0x0005, 0x601b,
+ 0x0000, 0x00ce, 0x97bd, 0x0001, 0x0c80, 0x00e6, 0x2071, 0x19e9,
+ 0x9006, 0x7032, 0x700a, 0x7004, 0x9086, 0x0003, 0x0158, 0x2001,
+ 0x1800, 0x2004, 0x9086, 0x0002, 0x1118, 0x7007, 0x0005, 0x0010,
+ 0x7007, 0x0000, 0x00ee, 0x0005, 0x00f6, 0x00e6, 0x00c6, 0x0066,
+ 0x0026, 0x0006, 0x0126, 0x2091, 0x8000, 0x2071, 0x19e9, 0x2c10,
+ 0x7648, 0x2660, 0x2678, 0x8cff, 0x0540, 0x2200, 0x9c06, 0x1508,
0x7048, 0x9c36, 0x1110, 0x660c, 0x764a, 0x7044, 0x9c36, 0x1140,
0x2c00, 0x9f36, 0x0118, 0x2f00, 0x7046, 0x0010, 0x7047, 0x0000,
- 0x660c, 0x0066, 0x2c00, 0x9f06, 0x0110, 0x7e0e, 0x0008, 0x2678,
- 0x600f, 0x0000, 0x6014, 0x2048, 0x080c, 0xcc14, 0x0110, 0x080c,
- 0xe6cd, 0x080c, 0xaf69, 0x87ff, 0x1198, 0x00ce, 0x0804, 0xa506,
- 0x2c78, 0x600c, 0x2060, 0x0804, 0xa506, 0x9006, 0x012e, 0x000e,
- 0x002e, 0x006e, 0x00ce, 0x009e, 0x00de, 0x00ee, 0x00fe, 0x0005,
- 0x601b, 0x0000, 0x00ce, 0x97bd, 0x0001, 0x0c80, 0x00e6, 0x2071,
- 0x19e9, 0x9006, 0x7032, 0x700a, 0x7004, 0x9086, 0x0003, 0x0158,
- 0x2001, 0x1800, 0x2004, 0x9086, 0x0002, 0x1118, 0x7007, 0x0005,
- 0x0010, 0x7007, 0x0000, 0x00ee, 0x0005, 0x00f6, 0x00e6, 0x00c6,
- 0x0066, 0x0026, 0x0006, 0x0126, 0x2091, 0x8000, 0x2071, 0x19e9,
- 0x2c10, 0x7648, 0x2660, 0x2678, 0x8cff, 0x0540, 0x2200, 0x9c06,
- 0x1508, 0x7048, 0x9c36, 0x1110, 0x660c, 0x764a, 0x7044, 0x9c36,
- 0x1140, 0x2c00, 0x9f36, 0x0118, 0x2f00, 0x7046, 0x0010, 0x7047,
- 0x0000, 0x660c, 0x2c00, 0x9f06, 0x0110, 0x7e0e, 0x0008, 0x2678,
- 0x600f, 0x0000, 0x6004, 0x9086, 0x0040, 0x090c, 0x97fe, 0x9085,
- 0x0001, 0x0020, 0x2c78, 0x600c, 0x2060, 0x08b0, 0x012e, 0x000e,
- 0x002e, 0x006e, 0x00ce, 0x00ee, 0x00fe, 0x0005, 0x0096, 0x00f6,
- 0x00e6, 0x00d6, 0x00c6, 0x0066, 0x0026, 0x0006, 0x0126, 0x2091,
- 0x8000, 0x2071, 0x19e9, 0x7610, 0x2660, 0x2678, 0x8cff, 0x0904,
- 0xa65b, 0x6010, 0x00b6, 0x2058, 0xb8a0, 0x00be, 0x9206, 0x1904,
- 0xa656, 0x7030, 0x9c06, 0x1520, 0x2069, 0x0100, 0x68c0, 0x9005,
- 0x0904, 0xa62d, 0x080c, 0xa08a, 0x68c3, 0x0000, 0x080c, 0xa56e,
- 0x7033, 0x0000, 0x0036, 0x2069, 0x0140, 0x6b04, 0x9384, 0x1000,
- 0x0138, 0x2001, 0x0100, 0x080c, 0x2abb, 0x9006, 0x080c, 0x2abb,
- 0x2069, 0x0100, 0x6824, 0xd084, 0x0110, 0x6827, 0x0001, 0x003e,
- 0x7010, 0x9c36, 0x1110, 0x660c, 0x7612, 0x700c, 0x9c36, 0x1140,
- 0x2c00, 0x9f36, 0x0118, 0x2f00, 0x700e, 0x0010, 0x700f, 0x0000,
- 0x660c, 0x0066, 0x2c00, 0x9f06, 0x0110, 0x7e0e, 0x0008, 0x2678,
- 0x600f, 0x0000, 0x080c, 0xce1c, 0x1180, 0x080c, 0x333f, 0x080c,
- 0xce2d, 0x1518, 0x080c, 0xb91f, 0x0400, 0x080c, 0xa56e, 0x6824,
- 0xd084, 0x09b0, 0x6827, 0x0001, 0x0898, 0x080c, 0xce2d, 0x1118,
- 0x080c, 0xb91f, 0x0090, 0x6014, 0x2048, 0x080c, 0xcc14, 0x0168,
- 0x6020, 0x9086, 0x0003, 0x1508, 0xa867, 0x0103, 0xab7a, 0xa877,
- 0x0000, 0x080c, 0x6f0d, 0x080c, 0xce07, 0x080c, 0xd0a9, 0x080c,
- 0xaf69, 0x080c, 0xa441, 0x00ce, 0x0804, 0xa5d6, 0x2c78, 0x600c,
- 0x2060, 0x0804, 0xa5d6, 0x012e, 0x000e, 0x002e, 0x006e, 0x00ce,
- 0x00de, 0x00ee, 0x00fe, 0x009e, 0x0005, 0x6020, 0x9086, 0x0006,
- 0x1d20, 0x080c, 0xe6cd, 0x0c08, 0x00d6, 0x080c, 0x9d2d, 0x7003,
- 0x0200, 0x7007, 0x0014, 0x60c3, 0x0014, 0x20e1, 0x0001, 0x2099,
- 0x198a, 0x20e9, 0x0000, 0x20a1, 0x0250, 0x20a9, 0x0004, 0x4003,
- 0x7023, 0x0004, 0x7027, 0x7878, 0x080c, 0xa05a, 0x00de, 0x0005,
- 0x080c, 0x9d2d, 0x700b, 0x0800, 0x7814, 0x9084, 0xff00, 0x700e,
- 0x7814, 0x9084, 0x00ff, 0x7022, 0x782c, 0x7026, 0x7860, 0x9084,
- 0x00ff, 0x9085, 0x0200, 0x7002, 0x7860, 0x9084, 0xff00, 0x8007,
- 0x7006, 0x60c2, 0x0804, 0xa05a, 0x00b6, 0x00d6, 0x0016, 0x00d6,
- 0x2f68, 0x2009, 0x0035, 0x080c, 0xd2b6, 0x00de, 0x1904, 0xa709,
- 0x080c, 0x9ce2, 0x7003, 0x1300, 0x782c, 0x080c, 0xa818, 0x2068,
- 0x6820, 0x9086, 0x0003, 0x0560, 0x7810, 0x2058, 0xbaa0, 0x080c,
- 0xae60, 0x11d8, 0x9286, 0x007e, 0x1128, 0x700b, 0x00ff, 0x700f,
- 0xfffe, 0x0498, 0x9286, 0x007f, 0x1128, 0x700b, 0x00ff, 0x700f,
- 0xfffd, 0x0458, 0x9284, 0xff80, 0x0180, 0x9286, 0x0080, 0x1128,
- 0x700b, 0x00ff, 0x700f, 0xfffc, 0x0400, 0x92d8, 0x1000, 0x2b5c,
- 0xb810, 0x700a, 0xb814, 0x700e, 0x00c0, 0xb884, 0x700e, 0x00a8,
- 0x080c, 0xae60, 0x1130, 0x7810, 0x2058, 0xb8a0, 0x9082, 0x007e,
- 0x0250, 0x00d6, 0x2069, 0x181f, 0x2d04, 0x700a, 0x8d68, 0x2d04,
- 0x700e, 0x00de, 0x0010, 0x6034, 0x700e, 0x7838, 0x7012, 0x783c,
- 0x7016, 0x60c3, 0x000c, 0x001e, 0x00de, 0x080c, 0xa05a, 0x00be,
- 0x0005, 0x781b, 0x0001, 0x7803, 0x0006, 0x001e, 0x00de, 0x00be,
- 0x0005, 0x792c, 0x9180, 0x0008, 0x200c, 0x9186, 0x0006, 0x01c0,
- 0x9186, 0x0003, 0x0904, 0xa788, 0x9186, 0x0005, 0x0904, 0xa770,
- 0x9186, 0x0004, 0x05f0, 0x9186, 0x0008, 0x0904, 0xa779, 0x7807,
- 0x0037, 0x782f, 0x0003, 0x7817, 0x1700, 0x080c, 0xa7f5, 0x0005,
- 0x080c, 0xa7b6, 0x00d6, 0x0026, 0x792c, 0x2168, 0x2009, 0x4000,
- 0x6800, 0x6a44, 0xd2fc, 0x11f8, 0x0002, 0xa750, 0xa75b, 0xa752,
- 0xa75b, 0xa757, 0xa750, 0xa750, 0xa75b, 0xa75b, 0xa75b, 0xa75b,
- 0xa750, 0xa750, 0xa750, 0xa750, 0xa750, 0xa75b, 0xa750, 0xa75b,
- 0x080c, 0x0d85, 0x6824, 0xd0e4, 0x0110, 0xd0cc, 0x0110, 0x900e,
- 0x0010, 0x2009, 0x2000, 0x682c, 0x7022, 0x6830, 0x7026, 0x0804,
- 0xa7af, 0x080c, 0xa7b6, 0x00d6, 0x0026, 0x792c, 0x2168, 0x2009,
- 0x4000, 0x6a00, 0x9286, 0x0002, 0x1108, 0x900e, 0x0804, 0xa7af,
- 0x080c, 0xa7b6, 0x00d6, 0x0026, 0x792c, 0x2168, 0x2009, 0x4000,
- 0x04b0, 0x04e1, 0x00d6, 0x0026, 0x792c, 0x2168, 0x2009, 0x4000,
- 0x9286, 0x0005, 0x0118, 0x9286, 0x0002, 0x1108, 0x900e, 0x0438,
- 0x0469, 0x00d6, 0x0026, 0x792c, 0x2168, 0x6814, 0x6924, 0xc185,
- 0x6926, 0x0096, 0x2048, 0xa9ac, 0xa834, 0x9112, 0xa9b0, 0xa838,
- 0x009e, 0x9103, 0x7022, 0x7226, 0x792c, 0x9180, 0x0011, 0x2004,
- 0xd0fc, 0x1148, 0x9180, 0x0000, 0x2004, 0x908e, 0x0002, 0x0130,
- 0x908e, 0x0004, 0x0118, 0x2009, 0x4000, 0x0008, 0x900e, 0x712a,
- 0x60c3, 0x0018, 0x002e, 0x00de, 0x0804, 0xa05a, 0x00b6, 0x0036,
- 0x0046, 0x0056, 0x0066, 0x080c, 0x9d2d, 0x9006, 0x7003, 0x0200,
- 0x7938, 0x710a, 0x793c, 0x710e, 0x7810, 0x2058, 0xb8a0, 0x080c,
- 0xae60, 0x1118, 0x9092, 0x007e, 0x0268, 0x00d6, 0x2069, 0x181f,
- 0x2d2c, 0x8d68, 0x2d34, 0x90d8, 0x1000, 0x2b5c, 0xbb10, 0xbc14,
- 0x00de, 0x0028, 0x901e, 0xbc84, 0x2029, 0x0000, 0x6634, 0x782c,
- 0x9080, 0x0008, 0x2004, 0x9086, 0x0003, 0x1128, 0x7512, 0x7616,
- 0x731a, 0x741e, 0x0020, 0x7312, 0x7416, 0x751a, 0x761e, 0x006e,
- 0x005e, 0x004e, 0x003e, 0x00be, 0x0005, 0x080c, 0x9d2d, 0x7003,
- 0x0100, 0x782c, 0x700a, 0x7814, 0x700e, 0x700e, 0x60c3, 0x0008,
- 0x0804, 0xa05a, 0x080c, 0x9cd9, 0x7003, 0x1400, 0x7838, 0x700a,
- 0x0079, 0x783c, 0x700e, 0x782c, 0x7012, 0x7830, 0x7016, 0x7834,
- 0x9084, 0x00ff, 0x8007, 0x701a, 0x60c3, 0x0010, 0x0804, 0xa05a,
- 0x00e6, 0x2071, 0x0240, 0x0006, 0x00f6, 0x2078, 0x7810, 0x00b6,
- 0x2058, 0xb8d4, 0xd084, 0x0120, 0x784c, 0x702a, 0x7850, 0x702e,
- 0x00be, 0x00fe, 0x000e, 0x00ee, 0x0005, 0x080c, 0x9d24, 0x7003,
- 0x0100, 0x782c, 0x700a, 0x7814, 0x700e, 0x60c3, 0x0008, 0x0804,
- 0xa05a, 0x00a9, 0x7914, 0x712a, 0x60c3, 0x0000, 0x60a7, 0x9575,
- 0x0026, 0x080c, 0x2a26, 0x0228, 0x2011, 0x0101, 0x2204, 0xc0c5,
- 0x2012, 0x002e, 0x080c, 0xa07d, 0x080c, 0x88e3, 0x0005, 0x0036,
- 0x0096, 0x00d6, 0x00e6, 0x7860, 0x2048, 0xaa7c, 0x9296, 0x00c0,
- 0x9294, 0x00fd, 0xaa7e, 0xaa80, 0x9294, 0x0300, 0xaa82, 0xa96c,
- 0x9194, 0x00ff, 0xab74, 0x9384, 0x00ff, 0x908d, 0xc200, 0xa96e,
- 0x9384, 0xff00, 0x9215, 0xaa76, 0xa870, 0xaa78, 0xa87a, 0xaa72,
- 0x00d6, 0x2069, 0x0200, 0x080c, 0xa8d5, 0x00de, 0x20e9, 0x0000,
- 0x20a1, 0x0240, 0x20a9, 0x000a, 0xa860, 0x20e0, 0xa85c, 0x9080,
- 0x001b, 0x2098, 0x4003, 0x60a3, 0x0035, 0xaa68, 0x9294, 0x7000,
- 0x9286, 0x3000, 0x0110, 0x60a3, 0x0037, 0x00ee, 0x00de, 0x009e,
- 0x003e, 0x0005, 0x900e, 0x7814, 0x0096, 0x2048, 0xa87c, 0xd0fc,
- 0x01c0, 0x9084, 0x0003, 0x11a8, 0x2001, 0x180c, 0x2004, 0xd0bc,
- 0x0180, 0x7824, 0xd0cc, 0x1168, 0xd0c4, 0x1158, 0xa8a8, 0x9005,
- 0x1140, 0x2001, 0x180c, 0x200c, 0xc1d5, 0x2102, 0x2009, 0x19b4,
- 0x210c, 0x009e, 0x918d, 0x0092, 0x0010, 0x2009, 0x0096, 0x60ab,
- 0x0036, 0x0026, 0x2110, 0x900e, 0x080c, 0x2b04, 0x002e, 0x0005,
- 0x2009, 0x0009, 0x00a0, 0x2009, 0x000a, 0x0088, 0x2009, 0x000b,
- 0x0070, 0x2009, 0x000c, 0x0058, 0x2009, 0x000d, 0x0040, 0x2009,
- 0x000e, 0x0028, 0x2009, 0x000f, 0x0010, 0x2009, 0x0008, 0x6912,
- 0x0005, 0x080c, 0x9ce2, 0x0016, 0x0026, 0x0096, 0x00d6, 0x7814,
- 0x2048, 0x7013, 0x0138, 0x2001, 0x1837, 0x2004, 0x9084, 0x0028,
- 0x1138, 0x2001, 0x197d, 0x2004, 0x9086, 0xaaaa, 0x1904, 0xa97a,
- 0x7003, 0x5400, 0x00c6, 0x2061, 0x1800, 0x607c, 0x9084, 0x00ff,
- 0xa998, 0x810f, 0x918c, 0xff00, 0x9105, 0x700a, 0x6080, 0x700e,
- 0xa998, 0x918c, 0xff00, 0x7112, 0x20a9, 0x0004, 0x2009, 0x1805,
- 0x2e10, 0x9290, 0x0006, 0x2104, 0x2012, 0x8108, 0x8210, 0x1f04,
- 0xa90b, 0x20a9, 0x0004, 0x2009, 0x1801, 0x2104, 0x2012, 0x8108,
- 0x8210, 0x1f04, 0xa915, 0xa860, 0x20e0, 0xa85c, 0x9080, 0x0029,
- 0x2098, 0x2009, 0x0006, 0x20a9, 0x0001, 0x4002, 0x8007, 0x2012,
- 0x8210, 0x8109, 0x1dc0, 0x00d6, 0x2069, 0x0200, 0x080c, 0xa8c0,
- 0x00de, 0x2071, 0x0240, 0x2011, 0x0240, 0x2009, 0x0002, 0x20a9,
- 0x0001, 0x4002, 0x8007, 0x2012, 0x8210, 0x8109, 0x1dc0, 0x2009,
- 0x0008, 0x20a9, 0x0001, 0x4002, 0x8007, 0x2012, 0x8210, 0x8109,
- 0x1dc0, 0xa85c, 0x9080, 0x0031, 0x2098, 0x2009, 0x0008, 0x20a9,
- 0x0001, 0x4002, 0x8007, 0x2012, 0x8210, 0x8109, 0x1dc0, 0x00ce,
- 0x60c3, 0x004c, 0x60a3, 0x0056, 0x60a7, 0x9575, 0x2001, 0x1837,
- 0x2004, 0x9084, 0x0028, 0x1168, 0x080c, 0x76a5, 0x0150, 0x6028,
- 0xc0bd, 0x602a, 0x2009, 0x1804, 0x2011, 0x0029, 0x080c, 0x2b04,
- 0x0010, 0x080c, 0xa05a, 0x080c, 0x88e3, 0x00de, 0x009e, 0x002e,
- 0x001e, 0x0005, 0x00e6, 0x2071, 0x0240, 0x2001, 0x2200, 0x9085,
- 0x00ff, 0x7002, 0x7007, 0xffff, 0x2071, 0x0100, 0x709b, 0x00ff,
- 0x00ee, 0x0804, 0xa8f0, 0x080c, 0x9ce2, 0x0016, 0x0026, 0x0096,
- 0x00d6, 0x7814, 0x2048, 0x7013, 0x0138, 0x7003, 0x5500, 0x00c6,
- 0xa89c, 0x9084, 0x00ff, 0xa998, 0x810f, 0x918c, 0xff00, 0x9105,
- 0x700a, 0xa99c, 0x918c, 0xff00, 0xa8a0, 0x9084, 0x00ff, 0x9105,
- 0x700e, 0xa998, 0x918c, 0xff00, 0x2061, 0x1800, 0x607c, 0x9084,
- 0x00ff, 0x910d, 0x7112, 0x6180, 0x7116, 0x2009, 0x0008, 0xa860,
- 0x20e0, 0xa85c, 0x9080, 0x0029, 0x2098, 0x2e10, 0x9290, 0x0006,
+ 0x660c, 0x2c00, 0x9f06, 0x0110, 0x7e0e, 0x0008, 0x2678, 0x600f,
+ 0x0000, 0x6004, 0x9086, 0x0040, 0x090c, 0x97f6, 0x9085, 0x0001,
+ 0x0020, 0x2c78, 0x600c, 0x2060, 0x08b0, 0x012e, 0x000e, 0x002e,
+ 0x006e, 0x00ce, 0x00ee, 0x00fe, 0x0005, 0x0096, 0x00f6, 0x00e6,
+ 0x00d6, 0x00c6, 0x0066, 0x0026, 0x0006, 0x0126, 0x2091, 0x8000,
+ 0x2071, 0x19e9, 0x7610, 0x2660, 0x2678, 0x8cff, 0x0904, 0xa672,
+ 0x6010, 0x00b6, 0x2058, 0xb8a0, 0x00be, 0x9206, 0x1904, 0xa66d,
+ 0x7030, 0x9c06, 0x1520, 0x2069, 0x0100, 0x68c0, 0x9005, 0x0904,
+ 0xa644, 0x080c, 0xa09b, 0x68c3, 0x0000, 0x080c, 0xa585, 0x7033,
+ 0x0000, 0x0036, 0x2069, 0x0140, 0x6b04, 0x9384, 0x1000, 0x0138,
+ 0x2001, 0x0100, 0x080c, 0x2aa2, 0x9006, 0x080c, 0x2aa2, 0x2069,
+ 0x0100, 0x6824, 0xd084, 0x0110, 0x6827, 0x0001, 0x003e, 0x7010,
+ 0x9c36, 0x1110, 0x660c, 0x7612, 0x700c, 0x9c36, 0x1140, 0x2c00,
+ 0x9f36, 0x0118, 0x2f00, 0x700e, 0x0010, 0x700f, 0x0000, 0x660c,
+ 0x0066, 0x2c00, 0x9f06, 0x0110, 0x7e0e, 0x0008, 0x2678, 0x600f,
+ 0x0000, 0x080c, 0xce39, 0x1180, 0x080c, 0x332a, 0x080c, 0xce4a,
+ 0x1518, 0x080c, 0xb93c, 0x0400, 0x080c, 0xa585, 0x6824, 0xd084,
+ 0x09b0, 0x6827, 0x0001, 0x0898, 0x080c, 0xce4a, 0x1118, 0x080c,
+ 0xb93c, 0x0090, 0x6014, 0x2048, 0x080c, 0xcc31, 0x0168, 0x6020,
+ 0x9086, 0x0003, 0x1508, 0xa867, 0x0103, 0xab7a, 0xa877, 0x0000,
+ 0x080c, 0x6f05, 0x080c, 0xce24, 0x080c, 0xd0c6, 0x080c, 0xaf89,
+ 0x080c, 0xa458, 0x00ce, 0x0804, 0xa5ed, 0x2c78, 0x600c, 0x2060,
+ 0x0804, 0xa5ed, 0x012e, 0x000e, 0x002e, 0x006e, 0x00ce, 0x00de,
+ 0x00ee, 0x00fe, 0x009e, 0x0005, 0x6020, 0x9086, 0x0006, 0x1d20,
+ 0x080c, 0xe738, 0x0c08, 0x00d6, 0x080c, 0x9d3e, 0x7003, 0x0200,
+ 0x7007, 0x0014, 0x60c3, 0x0014, 0x20e1, 0x0001, 0x2099, 0x198a,
+ 0x20e9, 0x0000, 0x20a1, 0x0250, 0x20a9, 0x0004, 0x4003, 0x7023,
+ 0x0004, 0x7027, 0x7878, 0x080c, 0xa06b, 0x00de, 0x0005, 0x080c,
+ 0x9d3e, 0x700b, 0x0800, 0x7814, 0x9084, 0xff00, 0x700e, 0x7814,
+ 0x9084, 0x00ff, 0x7022, 0x782c, 0x7026, 0x7860, 0x9084, 0x00ff,
+ 0x9085, 0x0200, 0x7002, 0x7860, 0x9084, 0xff00, 0x8007, 0x7006,
+ 0x60c2, 0x0804, 0xa06b, 0x00b6, 0x00d6, 0x0016, 0x00d6, 0x2f68,
+ 0x2009, 0x0035, 0x080c, 0xd2d3, 0x00de, 0x1904, 0xa720, 0x080c,
+ 0x9cf3, 0x7003, 0x1300, 0x782c, 0x080c, 0xa82f, 0x2068, 0x6820,
+ 0x9086, 0x0003, 0x0560, 0x7810, 0x2058, 0xbaa0, 0x080c, 0xae80,
+ 0x11d8, 0x9286, 0x007e, 0x1128, 0x700b, 0x00ff, 0x700f, 0xfffe,
+ 0x0498, 0x9286, 0x007f, 0x1128, 0x700b, 0x00ff, 0x700f, 0xfffd,
+ 0x0458, 0x9284, 0xff80, 0x0180, 0x9286, 0x0080, 0x1128, 0x700b,
+ 0x00ff, 0x700f, 0xfffc, 0x0400, 0x92d8, 0x1000, 0x2b5c, 0xb810,
+ 0x700a, 0xb814, 0x700e, 0x00c0, 0xb884, 0x700e, 0x00a8, 0x080c,
+ 0xae80, 0x1130, 0x7810, 0x2058, 0xb8a0, 0x9082, 0x007e, 0x0250,
+ 0x00d6, 0x2069, 0x181f, 0x2d04, 0x700a, 0x8d68, 0x2d04, 0x700e,
+ 0x00de, 0x0010, 0x6034, 0x700e, 0x7838, 0x7012, 0x783c, 0x7016,
+ 0x60c3, 0x000c, 0x001e, 0x00de, 0x080c, 0xa06b, 0x00be, 0x0005,
+ 0x781b, 0x0001, 0x7803, 0x0006, 0x001e, 0x00de, 0x00be, 0x0005,
+ 0x792c, 0x9180, 0x0008, 0x200c, 0x9186, 0x0006, 0x01c0, 0x9186,
+ 0x0003, 0x0904, 0xa79f, 0x9186, 0x0005, 0x0904, 0xa787, 0x9186,
+ 0x0004, 0x05f0, 0x9186, 0x0008, 0x0904, 0xa790, 0x7807, 0x0037,
+ 0x782f, 0x0003, 0x7817, 0x1700, 0x080c, 0xa80c, 0x0005, 0x080c,
+ 0xa7cd, 0x00d6, 0x0026, 0x792c, 0x2168, 0x2009, 0x4000, 0x6800,
+ 0x6a44, 0xd2fc, 0x11f8, 0x0002, 0xa767, 0xa772, 0xa769, 0xa772,
+ 0xa76e, 0xa767, 0xa767, 0xa772, 0xa772, 0xa772, 0xa772, 0xa767,
+ 0xa767, 0xa767, 0xa767, 0xa767, 0xa772, 0xa767, 0xa772, 0x080c,
+ 0x0d79, 0x6824, 0xd0e4, 0x0110, 0xd0cc, 0x0110, 0x900e, 0x0010,
+ 0x2009, 0x2000, 0x682c, 0x7022, 0x6830, 0x7026, 0x0804, 0xa7c6,
+ 0x080c, 0xa7cd, 0x00d6, 0x0026, 0x792c, 0x2168, 0x2009, 0x4000,
+ 0x6a00, 0x9286, 0x0002, 0x1108, 0x900e, 0x0804, 0xa7c6, 0x080c,
+ 0xa7cd, 0x00d6, 0x0026, 0x792c, 0x2168, 0x2009, 0x4000, 0x04b0,
+ 0x04e1, 0x00d6, 0x0026, 0x792c, 0x2168, 0x2009, 0x4000, 0x9286,
+ 0x0005, 0x0118, 0x9286, 0x0002, 0x1108, 0x900e, 0x0438, 0x0469,
+ 0x00d6, 0x0026, 0x792c, 0x2168, 0x6814, 0x6924, 0xc185, 0x6926,
+ 0x0096, 0x2048, 0xa9ac, 0xa834, 0x9112, 0xa9b0, 0xa838, 0x009e,
+ 0x9103, 0x7022, 0x7226, 0x792c, 0x9180, 0x0011, 0x2004, 0xd0fc,
+ 0x1148, 0x9180, 0x0000, 0x2004, 0x908e, 0x0002, 0x0130, 0x908e,
+ 0x0004, 0x0118, 0x2009, 0x4000, 0x0008, 0x900e, 0x712a, 0x60c3,
+ 0x0018, 0x002e, 0x00de, 0x0804, 0xa06b, 0x00b6, 0x0036, 0x0046,
+ 0x0056, 0x0066, 0x080c, 0x9d3e, 0x9006, 0x7003, 0x0200, 0x7938,
+ 0x710a, 0x793c, 0x710e, 0x7810, 0x2058, 0xb8a0, 0x080c, 0xae80,
+ 0x1118, 0x9092, 0x007e, 0x0268, 0x00d6, 0x2069, 0x181f, 0x2d2c,
+ 0x8d68, 0x2d34, 0x90d8, 0x1000, 0x2b5c, 0xbb10, 0xbc14, 0x00de,
+ 0x0028, 0x901e, 0xbc84, 0x2029, 0x0000, 0x6634, 0x782c, 0x9080,
+ 0x0008, 0x2004, 0x9086, 0x0003, 0x1128, 0x7512, 0x7616, 0x731a,
+ 0x741e, 0x0020, 0x7312, 0x7416, 0x751a, 0x761e, 0x006e, 0x005e,
+ 0x004e, 0x003e, 0x00be, 0x0005, 0x080c, 0x9d3e, 0x7003, 0x0100,
+ 0x782c, 0x700a, 0x7814, 0x700e, 0x700e, 0x60c3, 0x0008, 0x0804,
+ 0xa06b, 0x080c, 0x9cea, 0x7003, 0x1400, 0x7838, 0x700a, 0x0079,
+ 0x783c, 0x700e, 0x782c, 0x7012, 0x7830, 0x7016, 0x7834, 0x9084,
+ 0x00ff, 0x8007, 0x701a, 0x60c3, 0x0010, 0x0804, 0xa06b, 0x00e6,
+ 0x2071, 0x0240, 0x0006, 0x00f6, 0x2078, 0x7810, 0x00b6, 0x2058,
+ 0xb8d4, 0xd084, 0x0120, 0x784c, 0x702a, 0x7850, 0x702e, 0x00be,
+ 0x00fe, 0x000e, 0x00ee, 0x0005, 0x080c, 0x9d35, 0x7003, 0x0100,
+ 0x782c, 0x700a, 0x7814, 0x700e, 0x60c3, 0x0008, 0x0804, 0xa06b,
+ 0x00a9, 0x7914, 0x712a, 0x60c3, 0x0000, 0x60a7, 0x9575, 0x0026,
+ 0x080c, 0x2a11, 0x0228, 0x2011, 0x0101, 0x2204, 0xc0c5, 0x2012,
+ 0x002e, 0x080c, 0xa08e, 0x080c, 0x88db, 0x0005, 0x0036, 0x0096,
+ 0x00d6, 0x00e6, 0x7860, 0x2048, 0xaa7c, 0x9296, 0x00c0, 0x9294,
+ 0x00fd, 0xaa7e, 0xaa80, 0x9294, 0x0300, 0xaa82, 0xa96c, 0x9194,
+ 0x00ff, 0xab74, 0x9384, 0x00ff, 0x908d, 0xc200, 0xa96e, 0x9384,
+ 0xff00, 0x9215, 0xaa76, 0xa870, 0xaa78, 0xa87a, 0xaa72, 0x00d6,
+ 0x2069, 0x0200, 0x080c, 0xa8ec, 0x00de, 0x20e9, 0x0000, 0x20a1,
+ 0x0240, 0x20a9, 0x000a, 0xa860, 0x20e0, 0xa85c, 0x9080, 0x001b,
+ 0x2098, 0x4003, 0x60a3, 0x0035, 0xaa68, 0x9294, 0x7000, 0x9286,
+ 0x3000, 0x0110, 0x60a3, 0x0037, 0x00ee, 0x00de, 0x009e, 0x003e,
+ 0x0005, 0x900e, 0x7814, 0x0096, 0x2048, 0xa87c, 0xd0fc, 0x01c0,
+ 0x9084, 0x0003, 0x11a8, 0x2001, 0x180c, 0x2004, 0xd0bc, 0x0180,
+ 0x7824, 0xd0cc, 0x1168, 0xd0c4, 0x1158, 0xa8a8, 0x9005, 0x1140,
+ 0x2001, 0x180c, 0x200c, 0xc1d5, 0x2102, 0x2009, 0x19b4, 0x210c,
+ 0x009e, 0x918d, 0x0092, 0x0010, 0x2009, 0x0096, 0x60ab, 0x0036,
+ 0x0026, 0x2110, 0x900e, 0x080c, 0x2aeb, 0x002e, 0x0005, 0x2009,
+ 0x0009, 0x00a0, 0x2009, 0x000a, 0x0088, 0x2009, 0x000b, 0x0070,
+ 0x2009, 0x000c, 0x0058, 0x2009, 0x000d, 0x0040, 0x2009, 0x000e,
+ 0x0028, 0x2009, 0x000f, 0x0010, 0x2009, 0x0008, 0x6912, 0x0005,
+ 0x080c, 0x9cf3, 0x0016, 0x0026, 0x0096, 0x00d6, 0x7814, 0x2048,
+ 0x7013, 0x0138, 0x2001, 0x1837, 0x2004, 0x9084, 0x0028, 0x1138,
+ 0x2001, 0x197d, 0x2004, 0x9086, 0xaaaa, 0x1904, 0xa991, 0x7003,
+ 0x5400, 0x00c6, 0x2061, 0x1800, 0x607c, 0x9084, 0x00ff, 0xa998,
+ 0x810f, 0x918c, 0xff00, 0x9105, 0x700a, 0x6080, 0x700e, 0xa998,
+ 0x918c, 0xff00, 0x7112, 0x20a9, 0x0004, 0x2009, 0x1805, 0x2e10,
+ 0x9290, 0x0006, 0x2104, 0x2012, 0x8108, 0x8210, 0x1f04, 0xa922,
+ 0x20a9, 0x0004, 0x2009, 0x1801, 0x2104, 0x2012, 0x8108, 0x8210,
+ 0x1f04, 0xa92c, 0xa860, 0x20e0, 0xa85c, 0x9080, 0x0029, 0x2098,
+ 0x2009, 0x0006, 0x20a9, 0x0001, 0x4002, 0x8007, 0x2012, 0x8210,
+ 0x8109, 0x1dc0, 0x00d6, 0x2069, 0x0200, 0x080c, 0xa8d7, 0x00de,
+ 0x2071, 0x0240, 0x2011, 0x0240, 0x2009, 0x0002, 0x20a9, 0x0001,
+ 0x4002, 0x8007, 0x2012, 0x8210, 0x8109, 0x1dc0, 0x2009, 0x0008,
0x20a9, 0x0001, 0x4002, 0x8007, 0x2012, 0x8210, 0x8109, 0x1dc0,
- 0x20a9, 0x0004, 0x2009, 0x1805, 0x2104, 0x2012, 0x8108, 0x8210,
- 0x1f04, 0xa9cc, 0x20a9, 0x0002, 0x2009, 0x1801, 0x2104, 0x2012,
- 0x8108, 0x8210, 0x1f04, 0xa9d6, 0x00d6, 0x0016, 0x2069, 0x0200,
- 0x080c, 0xa8c0, 0x001e, 0x00de, 0x2071, 0x0240, 0x20a9, 0x0002,
- 0x2009, 0x1803, 0x2011, 0x0240, 0x2104, 0x2012, 0x8108, 0x8210,
- 0x1f04, 0xa9ec, 0x2009, 0x0008, 0x4002, 0x8007, 0x2012, 0x8210,
- 0x8109, 0x1dd0, 0x9006, 0x20a9, 0x0008, 0x2012, 0x8210, 0x1f04,
- 0xa9fd, 0x00ce, 0x60c3, 0x004c, 0x60a3, 0x0056, 0x60a7, 0x9575,
- 0x080c, 0xa05a, 0x080c, 0x88e3, 0x00de, 0x009e, 0x002e, 0x001e,
- 0x0005, 0x00d6, 0x9290, 0x0018, 0x8214, 0x20e9, 0x0000, 0x2069,
- 0x0200, 0x6813, 0x0000, 0x22a8, 0x9284, 0x00e0, 0x0128, 0x20a9,
- 0x0020, 0x9292, 0x0020, 0x0008, 0x9016, 0x20a1, 0x0240, 0x9006,
- 0x4004, 0x82ff, 0x0120, 0x6810, 0x8000, 0x6812, 0x0c60, 0x00de,
- 0x0005, 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x00a6, 0x0096, 0x0066,
- 0x0126, 0x2091, 0x8000, 0x2071, 0x19e9, 0x7610, 0x2660, 0x2678,
- 0x8cff, 0x0904, 0xaabd, 0x7030, 0x9c06, 0x1520, 0x2069, 0x0100,
- 0x68c0, 0x9005, 0x0904, 0xaa8f, 0x080c, 0xa08a, 0x68c3, 0x0000,
- 0x080c, 0xa56e, 0x7033, 0x0000, 0x0036, 0x2069, 0x0140, 0x6b04,
- 0x9384, 0x1000, 0x0138, 0x2001, 0x0100, 0x080c, 0x2abb, 0x9006,
- 0x080c, 0x2abb, 0x2069, 0x0100, 0x6824, 0xd084, 0x0110, 0x6827,
- 0x0001, 0x003e, 0x7010, 0x9c36, 0x1110, 0x660c, 0x7612, 0x700c,
- 0x9c36, 0x1140, 0x2c00, 0x9f36, 0x0118, 0x2f00, 0x700e, 0x0010,
- 0x700f, 0x0000, 0x660c, 0x0066, 0x2c00, 0x9f06, 0x0110, 0x7e0e,
- 0x0008, 0x2678, 0x600f, 0x0000, 0x080c, 0xce1c, 0x1180, 0x080c,
- 0x333f, 0x080c, 0xce2d, 0x1518, 0x080c, 0xb91f, 0x0400, 0x080c,
- 0xa56e, 0x6824, 0xd084, 0x09b0, 0x6827, 0x0001, 0x0898, 0x080c,
- 0xce2d, 0x1118, 0x080c, 0xb91f, 0x0090, 0x6014, 0x2048, 0x080c,
- 0xcc14, 0x0168, 0x6020, 0x9086, 0x0003, 0x1520, 0xa867, 0x0103,
- 0xab7a, 0xa877, 0x0000, 0x080c, 0x6f19, 0x080c, 0xce07, 0x080c,
- 0xd0a9, 0x080c, 0xaf69, 0x080c, 0xa441, 0x00ce, 0x0804, 0xaa40,
- 0x2c78, 0x600c, 0x2060, 0x0804, 0xaa40, 0x7013, 0x0000, 0x700f,
- 0x0000, 0x012e, 0x006e, 0x009e, 0x00ae, 0x00ce, 0x00de, 0x00ee,
- 0x00fe, 0x0005, 0x6020, 0x9086, 0x0006, 0x1d08, 0x080c, 0xe6cd,
- 0x08f0, 0x00f6, 0x0036, 0x2079, 0x0380, 0x7b18, 0xd3bc, 0x1de8,
- 0x7832, 0x7936, 0x7a3a, 0x781b, 0x8080, 0x003e, 0x00fe, 0x0005,
- 0x0016, 0x2001, 0x0382, 0x2004, 0x9084, 0x0007, 0x9086, 0x0001,
- 0x1188, 0x2001, 0x0015, 0x0c29, 0x2009, 0x1000, 0x2001, 0x0382,
- 0x2004, 0x9084, 0x0007, 0x9086, 0x0003, 0x0120, 0x8109, 0x1db0,
- 0x080c, 0x0d85, 0x001e, 0x0005, 0x2001, 0x0382, 0x2004, 0x9084,
- 0x0007, 0x9086, 0x0003, 0x1120, 0x2001, 0x0380, 0x2003, 0x0001,
- 0x0005, 0x0156, 0x0016, 0x0026, 0x00e6, 0x900e, 0x2071, 0x19e9,
- 0x0469, 0x0106, 0x0190, 0x7004, 0x9086, 0x0003, 0x0148, 0x20a9,
- 0x1000, 0x6044, 0xd0fc, 0x01d8, 0x1f04, 0xab19, 0x080c, 0x0d85,
- 0x080c, 0xaae0, 0x6044, 0xd0fc, 0x0190, 0x7030, 0x9c06, 0x1148,
- 0x080c, 0x97fe, 0x6044, 0xd0dc, 0x0150, 0xc0dc, 0x6046, 0x700a,
- 0x7042, 0x704c, 0x9c06, 0x190c, 0x0d85, 0x080c, 0x9859, 0x010e,
- 0x1919, 0x00ee, 0x002e, 0x001e, 0x015e, 0x0005, 0x2001, 0x0382,
- 0x2004, 0x9084, 0x0007, 0x9086, 0x0003, 0x0005, 0x0126, 0x2091,
- 0x2400, 0x7808, 0xd0a4, 0x190c, 0x0d7e, 0xd09c, 0x0128, 0x7820,
- 0x908c, 0xf000, 0x11b8, 0x0012, 0x012e, 0x0005, 0xab66, 0xaba4,
- 0xabce, 0xac05, 0xac15, 0xac26, 0xac35, 0xac43, 0xac70, 0xac74,
- 0xab66, 0xab66, 0xac77, 0xac93, 0xab66, 0xab66, 0x080c, 0x0d85,
- 0x012e, 0x0005, 0x2060, 0x6044, 0xd0bc, 0x0140, 0xc0bc, 0x6046,
- 0x6000, 0x908a, 0x0016, 0x1a0c, 0x0d85, 0x0012, 0x012e, 0x0005,
- 0xab8b, 0xab8d, 0xab8b, 0xab93, 0xab8b, 0xab8b, 0xab8b, 0xab8b,
- 0xab8b, 0xab8d, 0xab8b, 0xab8d, 0xab8b, 0xab8d, 0xab8b, 0xab8b,
- 0xab8b, 0xab8d, 0xab8b, 0x080c, 0x0d85, 0x2009, 0x0013, 0x080c,
- 0xafcc, 0x012e, 0x0005, 0x6014, 0x2048, 0xa87c, 0xd0dc, 0x0130,
- 0x080c, 0x8aba, 0x080c, 0xaf2e, 0x012e, 0x0005, 0x2009, 0x0049,
- 0x080c, 0xafcc, 0x012e, 0x0005, 0x080c, 0xaae0, 0x2001, 0x1a0e,
- 0x2003, 0x0000, 0x7030, 0x9065, 0x090c, 0x0d85, 0x7034, 0x9092,
- 0xc350, 0x1258, 0x8000, 0x7036, 0x7004, 0x9086, 0x0003, 0x0110,
- 0x7007, 0x0000, 0x781f, 0x0808, 0x0058, 0x080c, 0xae8c, 0x0140,
- 0x080c, 0xeb92, 0x6003, 0x0001, 0x2009, 0x0014, 0x080c, 0xafcc,
- 0x781f, 0x0100, 0x080c, 0xaafc, 0x012e, 0x0005, 0x080c, 0xaae0,
- 0x714c, 0x81ff, 0x1128, 0x2011, 0x1a11, 0x2013, 0x0000, 0x0438,
- 0x2061, 0x0100, 0x7150, 0x9192, 0x7530, 0x12f0, 0x8108, 0x7152,
- 0x714c, 0x9188, 0x0008, 0x210c, 0x918e, 0x0006, 0x1138, 0x6014,
- 0x9084, 0x1984, 0x9085, 0x0012, 0x6016, 0x0088, 0x714c, 0x9188,
- 0x0008, 0x210c, 0x918e, 0x0009, 0x0d90, 0x6014, 0x9084, 0x1984,
- 0x9085, 0x0016, 0x6016, 0x0018, 0x706c, 0xc085, 0x706e, 0x781f,
- 0x0200, 0x080c, 0xaafc, 0x012e, 0x0005, 0x080c, 0xaae0, 0x714c,
- 0x2160, 0x6003, 0x0003, 0x2009, 0x004a, 0x080c, 0xafcc, 0x781f,
- 0x0200, 0x080c, 0xaafc, 0x012e, 0x0005, 0x7808, 0xd09c, 0x0de8,
- 0x7820, 0x2060, 0x6003, 0x0003, 0x080c, 0xaae0, 0x080c, 0x1ded,
- 0x781f, 0x0400, 0x080c, 0xaafc, 0x012e, 0x0005, 0x7808, 0xd09c,
- 0x0de8, 0x7820, 0x2060, 0x080c, 0xaae0, 0x080c, 0x1e35, 0x781f,
- 0x0400, 0x080c, 0xaafc, 0x012e, 0x0005, 0x7030, 0x9065, 0x0148,
- 0x6044, 0xc0bc, 0x6046, 0x7104, 0x9186, 0x0003, 0x0110, 0x080c,
- 0x98c0, 0x012e, 0x0005, 0x00f6, 0x703c, 0x9086, 0x0002, 0x0528,
- 0x704c, 0x907d, 0x0510, 0x7844, 0xc0bc, 0x7846, 0x7820, 0x9086,
- 0x0009, 0x0118, 0x080c, 0x9fb4, 0x00c0, 0x7828, 0xd0fc, 0x1118,
- 0x080c, 0x9f33, 0x0090, 0x2001, 0x1837, 0x2004, 0x9084, 0x0028,
- 0x1130, 0x2001, 0x197d, 0x2004, 0x9086, 0xaaaa, 0x1120, 0x2001,
- 0x0387, 0x2003, 0x1000, 0x080c, 0x9eb8, 0x00fe, 0x012e, 0x0005,
- 0x080c, 0x7747, 0x012e, 0x0005, 0x080c, 0x0d85, 0x0005, 0x2009,
- 0x1b67, 0x2104, 0xd0bc, 0x01a8, 0xc0bc, 0x200a, 0x2009, 0x010b,
- 0x2104, 0x9085, 0x0002, 0x200a, 0x2009, 0x0101, 0x2104, 0xc0ac,
- 0x200a, 0x2009, 0x0105, 0x2104, 0x9084, 0x1984, 0x9085, 0x8092,
- 0x200a, 0x012e, 0x0005, 0x2009, 0x010b, 0x2104, 0xd08c, 0x01a8,
+ 0xa85c, 0x9080, 0x0031, 0x2098, 0x2009, 0x0008, 0x20a9, 0x0001,
+ 0x4002, 0x8007, 0x2012, 0x8210, 0x8109, 0x1dc0, 0x00ce, 0x60c3,
+ 0x004c, 0x60a3, 0x0056, 0x60a7, 0x9575, 0x2001, 0x1837, 0x2004,
+ 0x9084, 0x0028, 0x1168, 0x080c, 0x769d, 0x0150, 0x6028, 0xc0bd,
+ 0x602a, 0x2009, 0x1804, 0x2011, 0x0029, 0x080c, 0x2aeb, 0x0010,
+ 0x080c, 0xa06b, 0x080c, 0x88db, 0x00de, 0x009e, 0x002e, 0x001e,
+ 0x0005, 0x00e6, 0x2071, 0x0240, 0x2001, 0x2200, 0x9085, 0x00ff,
+ 0x7002, 0x7007, 0xffff, 0x2071, 0x0100, 0x709b, 0x00ff, 0x00ee,
+ 0x0804, 0xa907, 0x080c, 0x9cf3, 0x0016, 0x0026, 0x0096, 0x00d6,
+ 0x7814, 0x2048, 0x7013, 0x0138, 0x7003, 0x5500, 0x00c6, 0xa89c,
+ 0x9084, 0x00ff, 0xa998, 0x810f, 0x918c, 0xff00, 0x9105, 0x700a,
+ 0xa99c, 0x918c, 0xff00, 0xa8a0, 0x9084, 0x00ff, 0x9105, 0x700e,
+ 0xa998, 0x918c, 0xff00, 0x2061, 0x1800, 0x607c, 0x9084, 0x00ff,
+ 0x910d, 0x7112, 0x6180, 0x7116, 0x2009, 0x0008, 0xa860, 0x20e0,
+ 0xa85c, 0x9080, 0x0029, 0x2098, 0x2e10, 0x9290, 0x0006, 0x20a9,
+ 0x0001, 0x4002, 0x8007, 0x2012, 0x8210, 0x8109, 0x1dc0, 0x20a9,
+ 0x0004, 0x2009, 0x1805, 0x2104, 0x2012, 0x8108, 0x8210, 0x1f04,
+ 0xa9e3, 0x20a9, 0x0002, 0x2009, 0x1801, 0x2104, 0x2012, 0x8108,
+ 0x8210, 0x1f04, 0xa9ed, 0x00d6, 0x0016, 0x2069, 0x0200, 0x080c,
+ 0xa8d7, 0x001e, 0x00de, 0x2071, 0x0240, 0x20a9, 0x0002, 0x2009,
+ 0x1803, 0x2011, 0x0240, 0x2104, 0x2012, 0x8108, 0x8210, 0x1f04,
+ 0xaa03, 0x2009, 0x0008, 0x4002, 0x8007, 0x2012, 0x8210, 0x8109,
+ 0x1dd0, 0x9006, 0x20a9, 0x0008, 0x2012, 0x8210, 0x1f04, 0xaa14,
+ 0x00ce, 0x60c3, 0x004c, 0x60a3, 0x0056, 0x60a7, 0x9575, 0x080c,
+ 0xa06b, 0x080c, 0x88db, 0x00de, 0x009e, 0x002e, 0x001e, 0x0005,
+ 0x00d6, 0x9290, 0x0018, 0x8214, 0x20e9, 0x0000, 0x2069, 0x0200,
+ 0x6813, 0x0000, 0x22a8, 0x9284, 0x00e0, 0x0128, 0x20a9, 0x0020,
+ 0x9292, 0x0020, 0x0008, 0x9016, 0x20a1, 0x0240, 0x9006, 0x4004,
+ 0x82ff, 0x0120, 0x6810, 0x8000, 0x6812, 0x0c60, 0x00de, 0x0005,
+ 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x00a6, 0x0096, 0x0066, 0x0126,
+ 0x2091, 0x8000, 0x2071, 0x19e9, 0x7610, 0x2660, 0x2678, 0x8cff,
+ 0x0904, 0xaad4, 0x7030, 0x9c06, 0x1520, 0x2069, 0x0100, 0x68c0,
+ 0x9005, 0x0904, 0xaaa6, 0x080c, 0xa09b, 0x68c3, 0x0000, 0x080c,
+ 0xa585, 0x7033, 0x0000, 0x0036, 0x2069, 0x0140, 0x6b04, 0x9384,
+ 0x1000, 0x0138, 0x2001, 0x0100, 0x080c, 0x2aa2, 0x9006, 0x080c,
+ 0x2aa2, 0x2069, 0x0100, 0x6824, 0xd084, 0x0110, 0x6827, 0x0001,
+ 0x003e, 0x7010, 0x9c36, 0x1110, 0x660c, 0x7612, 0x700c, 0x9c36,
+ 0x1140, 0x2c00, 0x9f36, 0x0118, 0x2f00, 0x700e, 0x0010, 0x700f,
+ 0x0000, 0x660c, 0x0066, 0x2c00, 0x9f06, 0x0110, 0x7e0e, 0x0008,
+ 0x2678, 0x600f, 0x0000, 0x080c, 0xce39, 0x1180, 0x080c, 0x332a,
+ 0x080c, 0xce4a, 0x1518, 0x080c, 0xb93c, 0x0400, 0x080c, 0xa585,
+ 0x6824, 0xd084, 0x09b0, 0x6827, 0x0001, 0x0898, 0x080c, 0xce4a,
+ 0x1118, 0x080c, 0xb93c, 0x0090, 0x6014, 0x2048, 0x080c, 0xcc31,
+ 0x0168, 0x6020, 0x9086, 0x0003, 0x1520, 0xa867, 0x0103, 0xab7a,
+ 0xa877, 0x0000, 0x080c, 0x6f11, 0x080c, 0xce24, 0x080c, 0xd0c6,
+ 0x080c, 0xaf89, 0x080c, 0xa458, 0x00ce, 0x0804, 0xaa57, 0x2c78,
+ 0x600c, 0x2060, 0x0804, 0xaa57, 0x7013, 0x0000, 0x700f, 0x0000,
+ 0x012e, 0x006e, 0x009e, 0x00ae, 0x00ce, 0x00de, 0x00ee, 0x00fe,
+ 0x0005, 0x6020, 0x9086, 0x0006, 0x1d08, 0x080c, 0xe738, 0x08f0,
+ 0x00f6, 0x0036, 0x2079, 0x0380, 0x7b18, 0xd3bc, 0x1de8, 0x7832,
+ 0x7936, 0x7a3a, 0x781b, 0x8080, 0x003e, 0x00fe, 0x0005, 0x0016,
+ 0x2001, 0x0382, 0x2004, 0x9084, 0x0007, 0x9086, 0x0001, 0x1188,
+ 0x2001, 0x0015, 0x0c29, 0x2009, 0x1000, 0x2001, 0x0382, 0x2004,
+ 0x9084, 0x0007, 0x9086, 0x0003, 0x0120, 0x8109, 0x1db0, 0x080c,
+ 0x0d79, 0x001e, 0x0005, 0x2001, 0x0382, 0x2004, 0x9084, 0x0007,
+ 0x9086, 0x0003, 0x1120, 0x2001, 0x0380, 0x2003, 0x0001, 0x0005,
+ 0x0156, 0x0016, 0x0026, 0x00e6, 0x900e, 0x2071, 0x19e9, 0x0469,
+ 0x0106, 0x0190, 0x7004, 0x9086, 0x0003, 0x0148, 0x20a9, 0x1000,
+ 0x6044, 0xd0fc, 0x01d8, 0x1f04, 0xab30, 0x080c, 0x0d79, 0x080c,
+ 0xaaf7, 0x6044, 0xd0fc, 0x0190, 0x7030, 0x9c06, 0x1148, 0x080c,
+ 0x97f6, 0x6044, 0xd0dc, 0x0150, 0xc0dc, 0x6046, 0x700a, 0x7042,
+ 0x704c, 0x9c06, 0x190c, 0x0d79, 0x080c, 0x9851, 0x010e, 0x1919,
+ 0x00ee, 0x002e, 0x001e, 0x015e, 0x0005, 0x2001, 0x0382, 0x2004,
+ 0x9084, 0x0007, 0x9086, 0x0003, 0x0005, 0x0126, 0x2091, 0x2400,
+ 0x7808, 0xd0a4, 0x190c, 0x0d72, 0xd09c, 0x0128, 0x7820, 0x908c,
+ 0xf000, 0x11b8, 0x0012, 0x012e, 0x0005, 0xab7d, 0xabbb, 0xabe5,
+ 0xac23, 0xac33, 0xac44, 0xac53, 0xac61, 0xac8e, 0xac92, 0xab7d,
+ 0xab7d, 0xac95, 0xacb1, 0xab7d, 0xab7d, 0x080c, 0x0d79, 0x012e,
+ 0x0005, 0x2060, 0x6044, 0xd0bc, 0x0140, 0xc0bc, 0x6046, 0x6000,
+ 0x908a, 0x0010, 0x1a0c, 0x0d79, 0x0012, 0x012e, 0x0005, 0xaba2,
+ 0xaba4, 0xaba2, 0xabaa, 0xaba2, 0xaba2, 0xaba2, 0xaba2, 0xaba2,
+ 0xaba4, 0xaba2, 0xaba4, 0xaba2, 0xaba4, 0xaba2, 0xaba2, 0xaba2,
+ 0xaba4, 0xaba2, 0x080c, 0x0d79, 0x2009, 0x0013, 0x080c, 0xafec,
+ 0x012e, 0x0005, 0x6014, 0x2048, 0xa87c, 0xd0dc, 0x0130, 0x080c,
+ 0x8ab2, 0x080c, 0xaf4e, 0x012e, 0x0005, 0x2009, 0x0049, 0x080c,
+ 0xafec, 0x012e, 0x0005, 0x080c, 0xaaf7, 0x2001, 0x1a0e, 0x2003,
+ 0x0000, 0x7030, 0x9065, 0x090c, 0x0d79, 0x7034, 0x9092, 0xc350,
+ 0x1258, 0x8000, 0x7036, 0x7004, 0x9086, 0x0003, 0x0110, 0x7007,
+ 0x0000, 0x781f, 0x0808, 0x0058, 0x080c, 0xaeac, 0x0140, 0x080c,
+ 0xebfd, 0x6003, 0x0001, 0x2009, 0x0014, 0x080c, 0xafec, 0x781f,
+ 0x0100, 0x080c, 0xab13, 0x012e, 0x0005, 0x080c, 0xaaf7, 0x714c,
+ 0x81ff, 0x1128, 0x2011, 0x1a11, 0x2013, 0x0000, 0x0470, 0x2061,
+ 0x0100, 0x7150, 0x9192, 0x7530, 0x1628, 0x8108, 0x7152, 0x714c,
+ 0x9186, 0x1b56, 0x0120, 0x2001, 0x0391, 0x2003, 0x0400, 0x9188,
+ 0x0008, 0x210c, 0x918e, 0x0006, 0x1138, 0x6014, 0x9084, 0x1984,
+ 0x9085, 0x0012, 0x6016, 0x0088, 0x714c, 0x9188, 0x0008, 0x210c,
+ 0x918e, 0x0009, 0x0d90, 0x6014, 0x9084, 0x1984, 0x9085, 0x0016,
+ 0x6016, 0x0018, 0x706c, 0xc085, 0x706e, 0x781f, 0x0200, 0x080c,
+ 0xab13, 0x012e, 0x0005, 0x080c, 0xaaf7, 0x714c, 0x2160, 0x6003,
+ 0x0003, 0x2009, 0x004a, 0x080c, 0xafec, 0x781f, 0x0200, 0x080c,
+ 0xab13, 0x012e, 0x0005, 0x7808, 0xd09c, 0x0de8, 0x7820, 0x2060,
+ 0x6003, 0x0003, 0x080c, 0xaaf7, 0x080c, 0x1de9, 0x781f, 0x0400,
+ 0x080c, 0xab13, 0x012e, 0x0005, 0x7808, 0xd09c, 0x0de8, 0x7820,
+ 0x2060, 0x080c, 0xaaf7, 0x080c, 0x1e31, 0x781f, 0x0400, 0x080c,
+ 0xab13, 0x012e, 0x0005, 0x7030, 0x9065, 0x0148, 0x6044, 0xc0bc,
+ 0x6046, 0x7104, 0x9186, 0x0003, 0x0110, 0x080c, 0x98bd, 0x012e,
+ 0x0005, 0x00f6, 0x703c, 0x9086, 0x0002, 0x0528, 0x704c, 0x907d,
+ 0x0510, 0x7844, 0xc0bc, 0x7846, 0x7820, 0x9086, 0x0009, 0x0118,
+ 0x080c, 0x9fc5, 0x00c0, 0x7828, 0xd0fc, 0x1118, 0x080c, 0x9f44,
+ 0x0090, 0x2001, 0x1837, 0x2004, 0x9084, 0x0028, 0x1130, 0x2001,
+ 0x197d, 0x2004, 0x9086, 0xaaaa, 0x1120, 0x2001, 0x0387, 0x2003,
+ 0x1000, 0x080c, 0x9ec9, 0x00fe, 0x012e, 0x0005, 0x080c, 0x773f,
+ 0x012e, 0x0005, 0x080c, 0x0d79, 0x0005, 0x2009, 0x1b67, 0x2104,
+ 0xd0bc, 0x01a8, 0xc0bc, 0x200a, 0x2009, 0x010b, 0x2104, 0x9085,
+ 0x0002, 0x200a, 0x2009, 0x0101, 0x2104, 0xc0ac, 0x200a, 0x2009,
+ 0x0105, 0x2104, 0x9084, 0x1984, 0x9085, 0x8092, 0x200a, 0x012e,
+ 0x0005, 0x080c, 0x88f1, 0x2009, 0x010b, 0x2104, 0xd08c, 0x01a8,
0xc08c, 0x200a, 0x2001, 0x1848, 0x2004, 0xd094, 0x1130, 0x2009,
0x0101, 0x2104, 0x9085, 0x0020, 0x200a, 0x2009, 0x1b67, 0x200b,
- 0x0000, 0x2001, 0x001b, 0x080c, 0xaad1, 0x012e, 0x0005, 0x00e6,
+ 0x0000, 0x2001, 0x001b, 0x080c, 0xaae8, 0x012e, 0x0005, 0x00e6,
0x2071, 0x19e9, 0x6044, 0xc0bc, 0x6046, 0xd0fc, 0x01b8, 0x704c,
- 0x9c06, 0x1190, 0x2019, 0x0001, 0x080c, 0xa380, 0x704f, 0x0000,
+ 0x9c06, 0x1190, 0x2019, 0x0001, 0x080c, 0xa391, 0x704f, 0x0000,
0x2001, 0x0109, 0x2004, 0xd08c, 0x1138, 0x2001, 0x0108, 0x2004,
- 0xd0bc, 0x1110, 0x703f, 0x0000, 0x080c, 0xa585, 0x00ee, 0x0005,
- 0x0026, 0x7010, 0x9c06, 0x1178, 0x080c, 0xa441, 0x6044, 0xc0fc,
+ 0xd0bc, 0x1110, 0x703f, 0x0000, 0x080c, 0xa59c, 0x00ee, 0x0005,
+ 0x0026, 0x7010, 0x9c06, 0x1178, 0x080c, 0xa458, 0x6044, 0xc0fc,
0x6046, 0x600c, 0x9015, 0x0120, 0x7212, 0x600f, 0x0000, 0x0010,
0x7212, 0x720e, 0x9006, 0x002e, 0x0005, 0x0026, 0x7020, 0x9c06,
- 0x1178, 0x080c, 0xa441, 0x6044, 0xc0fc, 0x6046, 0x600c, 0x9015,
+ 0x1178, 0x080c, 0xa458, 0x6044, 0xc0fc, 0x6046, 0x600c, 0x9015,
0x0120, 0x7222, 0x600f, 0x0000, 0x0010, 0x7222, 0x721e, 0x9006,
0x002e, 0x0005, 0x00d6, 0x0036, 0x7830, 0x9c06, 0x1558, 0x2069,
- 0x0100, 0x68c0, 0x9005, 0x01f8, 0x080c, 0x88ec, 0x080c, 0xa08a,
- 0x68c3, 0x0000, 0x080c, 0xa56e, 0x2069, 0x0140, 0x6b04, 0x9384,
- 0x1000, 0x0138, 0x2001, 0x0100, 0x080c, 0x2abb, 0x9006, 0x080c,
- 0x2abb, 0x2069, 0x0100, 0x6824, 0xd084, 0x0110, 0x6827, 0x0001,
+ 0x0100, 0x68c0, 0x9005, 0x01f8, 0x080c, 0x88e4, 0x080c, 0xa09b,
+ 0x68c3, 0x0000, 0x080c, 0xa585, 0x2069, 0x0140, 0x6b04, 0x9384,
+ 0x1000, 0x0138, 0x2001, 0x0100, 0x080c, 0x2aa2, 0x9006, 0x080c,
+ 0x2aa2, 0x2069, 0x0100, 0x6824, 0xd084, 0x0110, 0x6827, 0x0001,
0x9085, 0x0001, 0x0038, 0x7808, 0xc0ad, 0x780a, 0x6003, 0x0009,
0x630a, 0x9006, 0x003e, 0x00de, 0x0005, 0x0016, 0x0026, 0x0036,
0x6100, 0x2019, 0x0100, 0x2001, 0x0382, 0x2004, 0xd09c, 0x0190,
- 0x00c6, 0x0126, 0x2091, 0x2800, 0x0016, 0x0036, 0x080c, 0xab46,
+ 0x00c6, 0x0126, 0x2091, 0x2800, 0x0016, 0x0036, 0x080c, 0xab5d,
0x003e, 0x001e, 0x012e, 0x00ce, 0x6200, 0x2200, 0x9106, 0x0d58,
0x2200, 0x0010, 0x8319, 0x1d38, 0x003e, 0x002e, 0x001e, 0x0005,
- 0x00e6, 0x00d6, 0x00c6, 0x080c, 0xaae0, 0x0106, 0x2071, 0x19e9,
+ 0x00e6, 0x00d6, 0x00c6, 0x080c, 0xaaf7, 0x0106, 0x2071, 0x19e9,
0x2069, 0x0100, 0x704c, 0x2060, 0x9086, 0x1b56, 0x15b8, 0x6814,
0xd08c, 0x0188, 0x6817, 0x0010, 0x2009, 0x0019, 0x8109, 0x1df0,
0x2001, 0x0032, 0x6920, 0xd1bc, 0x0130, 0x8001, 0x1dd8, 0x692c,
0x918d, 0x0008, 0x692e, 0x6824, 0xd08c, 0x0110, 0x6827, 0x0002,
0x68d0, 0x9005, 0x0118, 0x9082, 0x0005, 0x0238, 0x6060, 0x8000,
- 0x6062, 0x2001, 0x0391, 0x2003, 0x0400, 0x080c, 0x9859, 0x682c,
+ 0x6062, 0x2001, 0x0391, 0x2003, 0x0400, 0x080c, 0x9851, 0x682c,
0x9084, 0xfffd, 0x682e, 0x2001, 0x1848, 0x2004, 0xd094, 0x1120,
0x6804, 0x9085, 0x0020, 0x6806, 0x2069, 0x0000, 0x010e, 0x090c,
- 0xaafc, 0x8dff, 0x00ce, 0x00de, 0x00ee, 0x0005, 0x00e6, 0x00d6,
- 0x00c6, 0x080c, 0xaae0, 0x0106, 0x2071, 0x19e9, 0x2069, 0x0100,
- 0x080c, 0xad50, 0x68d0, 0x9005, 0x0158, 0x9082, 0x0005, 0x1240,
- 0x080c, 0x2b55, 0x2001, 0x0391, 0x2003, 0x0400, 0x2069, 0x0000,
- 0x010e, 0x090c, 0xaafc, 0x8dff, 0x00ce, 0x00de, 0x00ee, 0x0005,
+ 0xab13, 0x8dff, 0x00ce, 0x00de, 0x00ee, 0x0005, 0x00e6, 0x00d6,
+ 0x00c6, 0x080c, 0xaaf7, 0x0106, 0x2071, 0x19e9, 0x2069, 0x0100,
+ 0x080c, 0xad70, 0x68d0, 0x9005, 0x0158, 0x9082, 0x0005, 0x1240,
+ 0x080c, 0x2b3c, 0x2001, 0x0391, 0x2003, 0x0400, 0x2069, 0x0000,
+ 0x010e, 0x090c, 0xab13, 0x8dff, 0x00ce, 0x00de, 0x00ee, 0x0005,
0x0016, 0x2001, 0x0134, 0x2004, 0x9005, 0x0140, 0x9082, 0x0005,
0x1228, 0x2001, 0x0391, 0x2003, 0x0404, 0x0020, 0x2001, 0x0391,
- 0x2003, 0x0400, 0x001e, 0x0005, 0x00d6, 0x0156, 0x080c, 0x9d2d,
+ 0x2003, 0x0400, 0x001e, 0x0005, 0x00d6, 0x0156, 0x080c, 0x9d3e,
0x7a14, 0x82ff, 0x0138, 0x7003, 0x0100, 0x700b, 0x0003, 0x60c3,
0x0008, 0x0490, 0x7003, 0x0200, 0x7007, 0x0000, 0x2069, 0x1800,
0x901e, 0x6800, 0x9086, 0x0004, 0x1110, 0xc38d, 0x0060, 0x080c,
- 0x76a5, 0x1110, 0xc3ad, 0x0008, 0xc3a5, 0x6adc, 0xd29c, 0x1110,
- 0xd2ac, 0x0108, 0xc39d, 0x730e, 0x080c, 0x89b1, 0x20a9, 0x0006,
+ 0x769d, 0x1110, 0xc3ad, 0x0008, 0xc3a5, 0x6adc, 0xd29c, 0x1110,
+ 0xd2ac, 0x0108, 0xc39d, 0x730e, 0x080c, 0x89a9, 0x20a9, 0x0006,
0x2011, 0xffec, 0x2019, 0xffed, 0x2071, 0x0250, 0x2305, 0x2072,
0x8e70, 0x2205, 0x2072, 0x8e70, 0x9398, 0x0002, 0x9290, 0x0002,
- 0x1f04, 0xae06, 0x60c3, 0x0020, 0x080c, 0xa05a, 0x015e, 0x00de,
- 0x0005, 0x0156, 0x080c, 0x9d2d, 0x7a14, 0x82ff, 0x0168, 0x9286,
+ 0x1f04, 0xae26, 0x60c3, 0x0020, 0x080c, 0xa06b, 0x015e, 0x00de,
+ 0x0005, 0x0156, 0x080c, 0x9d3e, 0x7a14, 0x82ff, 0x0168, 0x9286,
0xffff, 0x0118, 0x9282, 0x000e, 0x1238, 0x7003, 0x0100, 0x700b,
0x0003, 0x60c3, 0x0008, 0x0488, 0x7003, 0x0200, 0x7007, 0x001c,
0x700f, 0x0001, 0x2011, 0x19bf, 0x2204, 0x8007, 0x701a, 0x8210,
@@ -5373,12 +5365,12 @@ unsigned short risc_code01[] = {
0x0248, 0x2001, 0x181f, 0x2004, 0x7022, 0x2001, 0x1820, 0x2004,
0x7026, 0x0030, 0x2001, 0x1818, 0x2004, 0x9084, 0x00ff, 0x7026,
0x20a9, 0x0004, 0x20e1, 0x0001, 0x2099, 0x1805, 0x20e9, 0x0000,
- 0x20a1, 0x0256, 0x4003, 0x60c3, 0x001c, 0x015e, 0x0804, 0xa05a,
+ 0x20a1, 0x0256, 0x4003, 0x60c3, 0x001c, 0x015e, 0x0804, 0xa06b,
0x0006, 0x2001, 0x1837, 0x2004, 0xd0ac, 0x000e, 0x0005, 0x2011,
- 0x0003, 0x080c, 0xa40f, 0x2011, 0x0002, 0x080c, 0xa419, 0x080c,
- 0xa300, 0x0036, 0x901e, 0x080c, 0xa380, 0x003e, 0x0005, 0x080c,
- 0x3482, 0x0188, 0x0016, 0x00b6, 0x00c6, 0x7010, 0x9085, 0x0020,
- 0x7012, 0x2009, 0x007e, 0x080c, 0x6789, 0xb85c, 0xc0ac, 0xb85e,
+ 0x0003, 0x080c, 0xa426, 0x2011, 0x0002, 0x080c, 0xa430, 0x080c,
+ 0xa311, 0x0036, 0x901e, 0x080c, 0xa391, 0x003e, 0x0005, 0x080c,
+ 0x346d, 0x0188, 0x0016, 0x00b6, 0x00c6, 0x7010, 0x9085, 0x0020,
+ 0x7012, 0x2009, 0x007e, 0x080c, 0x6783, 0xb85c, 0xc0ac, 0xb85e,
0x00ce, 0x00be, 0x001e, 0x0005, 0x00d6, 0x00f6, 0x7104, 0x9186,
0x0004, 0x1120, 0x7410, 0x9e90, 0x0004, 0x0068, 0x9186, 0x0001,
0x1120, 0x7420, 0x9e90, 0x0008, 0x0030, 0x9186, 0x0002, 0x1508,
@@ -5400,7 +5392,7 @@ unsigned short risc_code01[] = {
0x2061, 0x1ddc, 0x0c98, 0x6003, 0x0008, 0x8529, 0x7556, 0x9ca8,
0x001c, 0x7068, 0x9502, 0x1228, 0x755a, 0x9085, 0x0001, 0x00ee,
0x0005, 0x705b, 0x1ddc, 0x0cc8, 0x9006, 0x0cc8, 0x9c82, 0x1ddc,
- 0x0a0c, 0x0d85, 0x2001, 0x181a, 0x2004, 0x9c02, 0x1a0c, 0x0d85,
+ 0x0a0c, 0x0d79, 0x2001, 0x181a, 0x2004, 0x9c02, 0x1a0c, 0x0d79,
0x9006, 0x6006, 0x600a, 0x600e, 0x6016, 0x601a, 0x6012, 0x6023,
0x0000, 0x6003, 0x0000, 0x601e, 0x605e, 0x6062, 0x6026, 0x602a,
0x602e, 0x6032, 0x6036, 0x603a, 0x603e, 0x604a, 0x602a, 0x6046,
@@ -5408,1941 +5400,1950 @@ unsigned short risc_code01[] = {
0x600e, 0x6016, 0x601a, 0x6012, 0x6022, 0x6002, 0x601e, 0x605e,
0x6062, 0x604a, 0x6046, 0x2061, 0x1800, 0x6054, 0x8000, 0x6056,
0x0005, 0x0006, 0x6000, 0x9086, 0x0000, 0x01d8, 0x601c, 0xd084,
- 0x190c, 0x1afc, 0x6023, 0x0007, 0x2001, 0x1987, 0x2004, 0x0006,
- 0x9082, 0x0051, 0x000e, 0x0208, 0x8004, 0x601a, 0x080c, 0xe985,
+ 0x190c, 0x1af0, 0x6023, 0x0007, 0x2001, 0x1987, 0x2004, 0x0006,
+ 0x9082, 0x0051, 0x000e, 0x0208, 0x8004, 0x601a, 0x080c, 0xe9f0,
0x604b, 0x0000, 0x6044, 0xd0fc, 0x1131, 0x9006, 0x6046, 0x6016,
- 0x6012, 0x000e, 0x0005, 0x080c, 0xaae0, 0x0106, 0x2001, 0x19fc,
- 0x2004, 0x9c06, 0x1130, 0x0036, 0x2019, 0x0001, 0x080c, 0xa380,
- 0x003e, 0x080c, 0xa585, 0x010e, 0x090c, 0xaafc, 0x0005, 0x00e6,
+ 0x6012, 0x000e, 0x0005, 0x080c, 0xaaf7, 0x0106, 0x2001, 0x19fc,
+ 0x2004, 0x9c06, 0x1130, 0x0036, 0x2019, 0x0001, 0x080c, 0xa391,
+ 0x003e, 0x080c, 0xa59c, 0x010e, 0x090c, 0xab13, 0x0005, 0x00e6,
0x0126, 0x2071, 0x1800, 0x2091, 0x8000, 0x7554, 0x9582, 0x0001,
0x0608, 0x7058, 0x2060, 0x6000, 0x9086, 0x0000, 0x0148, 0x9ce0,
0x001c, 0x7068, 0x9c02, 0x1208, 0x0cb0, 0x2061, 0x1ddc, 0x0c98,
0x6003, 0x0008, 0x8529, 0x7556, 0x9ca8, 0x001c, 0x7068, 0x9502,
0x1230, 0x755a, 0x9085, 0x0001, 0x012e, 0x00ee, 0x0005, 0x705b,
0x1ddc, 0x0cc0, 0x9006, 0x0cc0, 0x6020, 0x9084, 0x000f, 0x0002,
- 0xafe0, 0xafea, 0xb005, 0xb020, 0xd391, 0xd3ae, 0xd3c9, 0xafe0,
- 0xafea, 0x9199, 0xb03c, 0xafe0, 0xafe0, 0xafe0, 0xafe0, 0xafe0,
- 0x9186, 0x0013, 0x1130, 0x6044, 0xd0fc, 0x0110, 0x080c, 0x97fe,
- 0x0005, 0x0005, 0x0066, 0x6000, 0x90b2, 0x0016, 0x1a0c, 0x0d85,
- 0x0013, 0x006e, 0x0005, 0xb003, 0xb77f, 0xb966, 0xb003, 0xb9fc,
- 0xb305, 0xb003, 0xb003, 0xb701, 0xbf76, 0xb003, 0xb003, 0xb003,
- 0xb003, 0xb003, 0xb003, 0x080c, 0x0d85, 0x0066, 0x6000, 0x90b2,
- 0x0016, 0x1a0c, 0x0d85, 0x0013, 0x006e, 0x0005, 0xb01e, 0xc58e,
- 0xb01e, 0xb01e, 0xb01e, 0xb01e, 0xb01e, 0xb01e, 0xc525, 0xc711,
- 0xb01e, 0xc5cb, 0xc64f, 0xc5cb, 0xc64f, 0xb01e, 0x080c, 0x0d85,
- 0x6000, 0x9082, 0x0016, 0x1a0c, 0x0d85, 0x6000, 0x0002, 0xb03a,
- 0xbfc0, 0xc05a, 0xc1da, 0xc249, 0xb03a, 0xb03a, 0xb03a, 0xbf8f,
- 0xc4a6, 0xc4a9, 0xb03a, 0xb03a, 0xb03a, 0xb03a, 0xc4d9, 0xb03a,
- 0xb03a, 0xb03a, 0x080c, 0x0d85, 0x0066, 0x6000, 0x90b2, 0x0016,
- 0x1a0c, 0x0d85, 0x0013, 0x006e, 0x0005, 0xb055, 0xb055, 0xb093,
- 0xb132, 0xb1b2, 0xb055, 0xb055, 0xb055, 0xb057, 0xb055, 0xb055,
- 0xb055, 0xb055, 0xb055, 0xb055, 0xb055, 0x080c, 0x0d85, 0x9186,
- 0x004c, 0x0560, 0x9186, 0x0003, 0x190c, 0x0d85, 0x0096, 0x601c,
- 0xc0ed, 0x601e, 0x6003, 0x0003, 0x6106, 0x6014, 0x2048, 0xa87c,
- 0x9084, 0xa000, 0xc0b5, 0xa87e, 0xa8ac, 0xa836, 0xa8b0, 0xa83a,
- 0x9006, 0xa846, 0xa84a, 0xa884, 0x9092, 0x199a, 0x0210, 0x2001,
- 0x1999, 0x8003, 0x8013, 0x8213, 0x9210, 0x621a, 0x009e, 0x080c,
- 0x1c47, 0x2009, 0x8030, 0x080c, 0x946f, 0x0005, 0x6010, 0x00b6,
- 0x2058, 0xbca0, 0x00be, 0x2c00, 0x080c, 0xb1d4, 0x080c, 0xd356,
- 0x6003, 0x0007, 0x0005, 0x00d6, 0x0096, 0x00f6, 0x2079, 0x1800,
- 0x7a90, 0x6014, 0x2048, 0xa87c, 0xd0ec, 0x1110, 0x9290, 0x0018,
- 0xac78, 0xc4fc, 0x0046, 0xa8e0, 0x9005, 0x1140, 0xa8dc, 0x921a,
- 0x0140, 0x0220, 0xa87b, 0x0007, 0x2010, 0x0028, 0xa87b, 0x0015,
- 0x0010, 0xa87b, 0x0000, 0x8214, 0xa883, 0x0000, 0xaa02, 0x0006,
- 0x0016, 0x0026, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x2400, 0x9005,
- 0x1108, 0x009a, 0x2100, 0x9086, 0x0015, 0x1118, 0x2001, 0x0001,
- 0x0038, 0x2100, 0x9086, 0x0016, 0x0118, 0x2001, 0x0001, 0x002a,
- 0x94a4, 0x0007, 0x8423, 0x9405, 0x0002, 0xb0fa, 0xb0fa, 0xb0f5,
- 0xb0f8, 0xb0fa, 0xb0f2, 0xb0e5, 0xb0e5, 0xb0e5, 0xb0e5, 0xb0e5,
- 0xb0e5, 0xb0e5, 0xb0e5, 0xb0e5, 0xb0e5, 0x00fe, 0x00ee, 0x00de,
- 0x00ce, 0x002e, 0x001e, 0x000e, 0x004e, 0x00fe, 0x009e, 0x00de,
- 0x080c, 0x0d85, 0x080c, 0xbbc9, 0x0028, 0x080c, 0xbcb0, 0x0010,
- 0x080c, 0xbda6, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x002e, 0x001e,
- 0x2c00, 0xa896, 0x000e, 0x080c, 0xb292, 0x0530, 0xa804, 0xa80e,
- 0x00a6, 0x2050, 0xb100, 0x00ae, 0x8006, 0x8006, 0x8007, 0x90bc,
- 0x003f, 0x9084, 0xffc0, 0x9080, 0x0002, 0xaacc, 0xabd0, 0xacd4,
- 0xadd8, 0x2031, 0x0000, 0x2041, 0x12c2, 0x080c, 0xb456, 0x0160,
- 0x000e, 0x9005, 0x0120, 0x00fe, 0x009e, 0x00de, 0x0005, 0x00fe,
- 0x009e, 0x00de, 0x0804, 0xaf2e, 0x2001, 0x002c, 0x900e, 0x080c,
- 0xb2f8, 0x0c70, 0x91b6, 0x0015, 0x0170, 0x91b6, 0x0016, 0x0158,
- 0x91b2, 0x0047, 0x0a0c, 0x0d85, 0x91b2, 0x0050, 0x1a0c, 0x0d85,
- 0x9182, 0x0047, 0x0042, 0x080c, 0xad2d, 0x0120, 0x9086, 0x0002,
- 0x0904, 0xb093, 0x0005, 0xb154, 0xb154, 0xb156, 0xb188, 0xb154,
- 0xb154, 0xb154, 0xb154, 0xb19b, 0x080c, 0x0d85, 0x00d6, 0x0016,
- 0x0096, 0x6003, 0x0004, 0x6114, 0x2148, 0xa87c, 0xd0fc, 0x01c0,
- 0xa878, 0xc0fc, 0x9005, 0x1158, 0xa894, 0x9005, 0x0140, 0x2001,
- 0x0000, 0x900e, 0x080c, 0xb2f8, 0x080c, 0xaf2e, 0x00a8, 0x6003,
- 0x0002, 0xa8a4, 0xa9a8, 0x9105, 0x1178, 0xa8ae, 0xa8b2, 0x0c78,
- 0xa87f, 0x0020, 0xa88c, 0xa88a, 0xa8a4, 0xa8ae, 0xa8a8, 0xa8b2,
- 0xa8c7, 0x0000, 0xa8cb, 0x0000, 0x009e, 0x001e, 0x00de, 0x0005,
- 0x080c, 0x9859, 0x00d6, 0x0096, 0x6114, 0x2148, 0x080c, 0xcc16,
- 0x0120, 0xa87b, 0x0006, 0x080c, 0x6f19, 0x009e, 0x00de, 0x080c,
- 0xaf2e, 0x0804, 0x98bf, 0x080c, 0x9859, 0x080c, 0x3310, 0x080c,
- 0xd353, 0x00d6, 0x0096, 0x6114, 0x2148, 0x080c, 0xcc16, 0x0120,
- 0xa87b, 0x0029, 0x080c, 0x6f19, 0x009e, 0x00de, 0x080c, 0xaf2e,
- 0x0804, 0x98bf, 0x9182, 0x0047, 0x0002, 0xb1c2, 0xb1c4, 0xb1c2,
- 0xb1c2, 0xb1c2, 0xb1c2, 0xb1c2, 0xb1c2, 0xb1c2, 0xb1c2, 0xb1c2,
- 0xb1c2, 0xb1c4, 0x080c, 0x0d85, 0x00d6, 0x0096, 0x601f, 0x0000,
- 0x6114, 0x2148, 0xa87b, 0x0000, 0xa883, 0x0000, 0x080c, 0x6f19,
- 0x009e, 0x00de, 0x0804, 0xaf2e, 0x0026, 0x0036, 0x0056, 0x0066,
- 0x0096, 0x00a6, 0x00f6, 0x0006, 0x080c, 0x1059, 0x000e, 0x090c,
- 0x0d85, 0xa960, 0x21e8, 0xa95c, 0x9188, 0x0019, 0x21a0, 0x900e,
- 0x20a9, 0x0020, 0x4104, 0xa87a, 0x2079, 0x1800, 0x7990, 0x9188,
- 0x0018, 0x918c, 0x0fff, 0xa972, 0xac76, 0x2950, 0x00a6, 0x2001,
- 0x0205, 0x2003, 0x0000, 0x901e, 0x2029, 0x0001, 0x9182, 0x0034,
- 0x1228, 0x2011, 0x001f, 0x080c, 0xc794, 0x04c0, 0x2130, 0x2009,
- 0x0034, 0x2011, 0x001f, 0x080c, 0xc794, 0x96b2, 0x0034, 0xb004,
- 0x904d, 0x0110, 0x080c, 0x100b, 0x080c, 0x1059, 0x01d0, 0x8528,
- 0xa867, 0x0110, 0xa86b, 0x0000, 0x2920, 0xb406, 0x968a, 0x003d,
- 0x1230, 0x2608, 0x2011, 0x001b, 0x080c, 0xc794, 0x00b8, 0x96b2,
- 0x003c, 0x2009, 0x003c, 0x2950, 0x2011, 0x001b, 0x080c, 0xc794,
- 0x0c18, 0x2001, 0x0205, 0x2003, 0x0000, 0x00ae, 0x852f, 0x95ad,
- 0x0050, 0xb566, 0xb070, 0xc0fd, 0xb072, 0x0048, 0x2001, 0x0205,
- 0x2003, 0x0000, 0x00ae, 0x852f, 0x95ad, 0x0050, 0xb566, 0x2a48,
- 0xa804, 0xa807, 0x0000, 0x0006, 0x080c, 0x6f19, 0x000e, 0x2048,
- 0x9005, 0x1db0, 0x00fe, 0x00ae, 0x009e, 0x006e, 0x005e, 0x003e,
- 0x002e, 0x0005, 0x00d6, 0x00f6, 0x0096, 0x0006, 0x080c, 0x1059,
- 0x000e, 0x090c, 0x0d85, 0xa960, 0x21e8, 0xa95c, 0x9188, 0x0019,
- 0x21a0, 0x900e, 0x20a9, 0x0020, 0x4104, 0xaa66, 0xa87a, 0x2079,
- 0x1800, 0x7990, 0x810c, 0x9188, 0x000c, 0x9182, 0x001a, 0x0210,
- 0x2009, 0x001a, 0x21a8, 0x810b, 0xa972, 0xac76, 0x2e98, 0xa85c,
- 0x9080, 0x001f, 0x20a0, 0x2001, 0x0205, 0x200c, 0x918d, 0x0080,
- 0x2102, 0x4003, 0x2003, 0x0000, 0x080c, 0x6f19, 0x009e, 0x00fe,
- 0x00de, 0x0005, 0x0016, 0x00d6, 0x00f6, 0x0096, 0x0016, 0x2001,
- 0x0205, 0x200c, 0x918d, 0x0080, 0x2102, 0x001e, 0x2079, 0x0200,
- 0x2e98, 0xa87c, 0xd0ec, 0x0118, 0x9e80, 0x000c, 0x2098, 0x2021,
- 0x003e, 0x901e, 0x9282, 0x0020, 0x0218, 0x2011, 0x0020, 0x2018,
- 0x9486, 0x003e, 0x1170, 0x0096, 0x080c, 0x1059, 0x2900, 0x009e,
- 0x05c0, 0xa806, 0x2048, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0002,
- 0x20a0, 0x3300, 0x908e, 0x0260, 0x0140, 0x2009, 0x0280, 0x9102,
- 0x920a, 0x0218, 0x2010, 0x2100, 0x9318, 0x2200, 0x9402, 0x1228,
- 0x2400, 0x9202, 0x2410, 0x9318, 0x9006, 0x2020, 0x22a8, 0xa800,
- 0x9200, 0xa802, 0x20e1, 0x0000, 0x4003, 0x83ff, 0x0180, 0x3300,
- 0x9086, 0x0280, 0x1130, 0x7814, 0x8000, 0x9085, 0x0080, 0x7816,
- 0x2e98, 0x2310, 0x84ff, 0x0904, 0xb2a7, 0x0804, 0xb2a9, 0x9085,
- 0x0001, 0x7817, 0x0000, 0x009e, 0x00fe, 0x00de, 0x001e, 0x0005,
- 0x00d6, 0x0036, 0x0096, 0x6314, 0x2348, 0xa87a, 0xa982, 0x080c,
- 0x6f0d, 0x009e, 0x003e, 0x00de, 0x0005, 0x91b6, 0x0015, 0x1118,
- 0x080c, 0xaf2e, 0x0030, 0x91b6, 0x0016, 0x190c, 0x0d85, 0x080c,
- 0xaf2e, 0x0005, 0x20a9, 0x000e, 0x20e1, 0x0000, 0x2e98, 0x6014,
- 0x0096, 0x2048, 0xa860, 0x20e8, 0xa85c, 0x20a0, 0x009e, 0x4003,
- 0x9196, 0x0016, 0x01f0, 0x0136, 0x9080, 0x001b, 0x20a0, 0x2011,
- 0x0006, 0x20a9, 0x0001, 0x3418, 0x8318, 0x23a0, 0x4003, 0x3318,
- 0x8318, 0x2398, 0x8211, 0x1db8, 0x2011, 0x0006, 0x013e, 0x20a0,
- 0x3318, 0x8318, 0x2398, 0x4003, 0x3418, 0x8318, 0x23a0, 0x8211,
- 0x1db8, 0x0096, 0x080c, 0xcc16, 0x0130, 0x6014, 0x2048, 0xa807,
- 0x0000, 0xa867, 0x0103, 0x009e, 0x0804, 0xaf2e, 0x0096, 0x00d6,
- 0x0036, 0x7330, 0x9386, 0x0200, 0x11a8, 0x6010, 0x00b6, 0x2058,
- 0xb8d7, 0x0000, 0x00be, 0x6014, 0x9005, 0x0130, 0x2048, 0xa807,
- 0x0000, 0xa867, 0x0103, 0xab32, 0x080c, 0xaf2e, 0x003e, 0x00de,
- 0x009e, 0x0005, 0x0011, 0x1d48, 0x0cc8, 0x0006, 0x0016, 0x080c,
- 0xd33e, 0x0188, 0x6014, 0x9005, 0x1170, 0x600b, 0x0003, 0x601b,
- 0x0000, 0x604b, 0x0000, 0x2009, 0x0022, 0x080c, 0xb757, 0x9006,
- 0x001e, 0x000e, 0x0005, 0x9085, 0x0001, 0x0cd0, 0x0096, 0x0016,
- 0x20a9, 0x0014, 0x9e80, 0x000c, 0x20e1, 0x0000, 0x2098, 0x6014,
- 0x2048, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0002, 0x20a0, 0x4003,
- 0x2001, 0x0205, 0x2003, 0x0001, 0x2099, 0x0260, 0x20a9, 0x0016,
- 0x4003, 0x20a9, 0x000a, 0xa804, 0x2048, 0xa860, 0x20e8, 0xa85c,
- 0x9080, 0x0002, 0x20a0, 0x4003, 0x2001, 0x0205, 0x2003, 0x0002,
- 0x2099, 0x0260, 0x20a9, 0x0020, 0x4003, 0x2003, 0x0000, 0x6014,
- 0x2048, 0xa800, 0x2048, 0xa867, 0x0103, 0x080c, 0xaf2e, 0x001e,
- 0x009e, 0x0005, 0x0096, 0x0016, 0x900e, 0x7030, 0x9086, 0x0100,
- 0x0140, 0x7038, 0x9084, 0x00ff, 0x800c, 0x703c, 0x9084, 0x00ff,
- 0x8004, 0x9080, 0x0004, 0x9108, 0x810b, 0x2011, 0x0002, 0x2019,
- 0x000c, 0x6014, 0x2048, 0x080c, 0xc794, 0x080c, 0xcc16, 0x0140,
- 0x6014, 0x2048, 0xa807, 0x0000, 0xa864, 0xa8e2, 0xa867, 0x0103,
- 0x080c, 0xaf2e, 0x001e, 0x009e, 0x0005, 0x0016, 0x2009, 0x0000,
- 0x7030, 0x9086, 0x0200, 0x0110, 0x2009, 0x0001, 0x0096, 0x6014,
- 0x904d, 0x090c, 0x0d85, 0xa97a, 0x080c, 0x6f19, 0x009e, 0x080c,
- 0xaf2e, 0x001e, 0x0005, 0x0016, 0x0096, 0x7030, 0x9086, 0x0100,
- 0x1118, 0x2009, 0x0004, 0x0010, 0x7034, 0x800c, 0x810b, 0x2011,
- 0x000c, 0x2019, 0x000c, 0x6014, 0x2048, 0xa804, 0x0096, 0x9005,
- 0x0108, 0x2048, 0x080c, 0xc794, 0x009e, 0x080c, 0xcc16, 0x0148,
- 0xa804, 0x9005, 0x1158, 0xa807, 0x0000, 0xa864, 0xa8e2, 0xa867,
- 0x0103, 0x080c, 0xaf2e, 0x009e, 0x001e, 0x0005, 0x0086, 0x2040,
- 0xa030, 0x8007, 0x9086, 0x0100, 0x1118, 0x080c, 0xb91f, 0x00e0,
- 0xa034, 0x8007, 0x800c, 0x8806, 0x8006, 0x8007, 0x90bc, 0x003f,
- 0x9084, 0xffc0, 0x9080, 0x000c, 0xa87b, 0x0000, 0xa883, 0x0000,
- 0xa897, 0x4000, 0xaaa0, 0xab9c, 0xaca8, 0xada4, 0x2031, 0x0000,
- 0x2041, 0x12a8, 0x0019, 0x0d08, 0x008e, 0x0898, 0x0096, 0x0006,
- 0x080c, 0x1059, 0x000e, 0x01b0, 0xa8ab, 0x0dcb, 0xa876, 0x000e,
- 0xa8a2, 0x0006, 0xae6a, 0x2800, 0xa89e, 0xa97a, 0xaf72, 0xaa8e,
- 0xab92, 0xac96, 0xad9a, 0x0086, 0x2940, 0x080c, 0x114e, 0x008e,
- 0x9085, 0x0001, 0x009e, 0x0005, 0x00e6, 0x00d6, 0x0026, 0x7008,
- 0x9084, 0x00ff, 0x6210, 0x00b6, 0x2258, 0xba10, 0x00be, 0x9206,
- 0x1520, 0x700c, 0x6210, 0x00b6, 0x2258, 0xba14, 0x00be, 0x9206,
- 0x11e0, 0x604b, 0x0000, 0x2c68, 0x0016, 0x2009, 0x0035, 0x080c,
- 0xd2b6, 0x001e, 0x1158, 0x622c, 0x2268, 0x2071, 0x026c, 0x6b20,
- 0x9386, 0x0003, 0x0130, 0x9386, 0x0006, 0x0128, 0x080c, 0xaf2e,
- 0x0020, 0x0039, 0x0010, 0x080c, 0xb58c, 0x002e, 0x00de, 0x00ee,
- 0x0005, 0x0096, 0x6814, 0x2048, 0x9186, 0x0015, 0x0904, 0xb56b,
- 0x918e, 0x0016, 0x1904, 0xb58a, 0x700c, 0x908c, 0xff00, 0x9186,
- 0x1700, 0x0120, 0x9186, 0x0300, 0x1904, 0xb545, 0x89ff, 0x1138,
- 0x6800, 0x9086, 0x000f, 0x0904, 0xb527, 0x0804, 0xb588, 0x6808,
- 0x9086, 0xffff, 0x1904, 0xb56d, 0xa87c, 0x9084, 0x0060, 0x9086,
- 0x0020, 0x1150, 0xa8ac, 0xa934, 0x9106, 0x1904, 0xb56d, 0xa8b0,
- 0xa938, 0x9106, 0x1904, 0xb56d, 0x6824, 0xd084, 0x1904, 0xb56d,
- 0xd0b4, 0x0158, 0x0016, 0x2001, 0x1987, 0x200c, 0x6018, 0x9102,
- 0x9082, 0x0005, 0x001e, 0x1a04, 0xb56d, 0x080c, 0xce07, 0x6810,
- 0x0096, 0x2048, 0xa9a0, 0x009e, 0x685c, 0xa87a, 0xa976, 0x6864,
- 0xa882, 0xa87c, 0xc0dc, 0xc0f4, 0xc0d4, 0xa87e, 0x0026, 0x900e,
- 0x6a18, 0x2001, 0x000a, 0x080c, 0x936c, 0xa884, 0x920a, 0x0208,
- 0x8011, 0xaa86, 0x82ff, 0x002e, 0x1138, 0x00c6, 0x2d60, 0x080c,
- 0xc91f, 0x00ce, 0x0804, 0xb588, 0x00c6, 0xa868, 0xd0fc, 0x1118,
- 0x080c, 0x6210, 0x0010, 0x080c, 0x661b, 0x00ce, 0x1904, 0xb56d,
- 0x00c6, 0x2d60, 0x080c, 0xaf2e, 0x00ce, 0x0804, 0xb588, 0x00c6,
- 0x080c, 0xaf9f, 0x0198, 0x6017, 0x0000, 0x6810, 0x6012, 0x080c,
- 0xd0b1, 0x6023, 0x0003, 0x6904, 0x00c6, 0x2d60, 0x080c, 0xaf2e,
- 0x00ce, 0x080c, 0xafcc, 0x00ce, 0x0804, 0xb588, 0x2001, 0x1989,
- 0x2004, 0x684a, 0x00ce, 0x0804, 0xb588, 0x7008, 0x9086, 0x000b,
- 0x11c8, 0x6010, 0x00b6, 0x2058, 0xb900, 0xc1bc, 0xb902, 0x00be,
- 0x00c6, 0x2d60, 0xa87b, 0x0003, 0x080c, 0xd2f8, 0x6007, 0x0085,
- 0x6003, 0x000b, 0x6023, 0x0002, 0x2009, 0x8020, 0x080c, 0x9428,
- 0x00ce, 0x0430, 0x700c, 0x9086, 0x2a00, 0x1138, 0x2001, 0x1989,
- 0x2004, 0x684a, 0x00e8, 0x04c1, 0x00e8, 0x89ff, 0x090c, 0x0d85,
- 0x00c6, 0x00d6, 0x2d60, 0xa867, 0x0103, 0xa87b, 0x0003, 0x080c,
- 0x6d2e, 0x080c, 0xce07, 0x080c, 0xaf69, 0x0026, 0x6010, 0x00b6,
- 0x2058, 0xba3c, 0x080c, 0x68b4, 0x00be, 0x002e, 0x00de, 0x00ce,
- 0x080c, 0xaf2e, 0x009e, 0x0005, 0x9186, 0x0015, 0x1128, 0x2001,
- 0x1989, 0x2004, 0x684a, 0x0068, 0x918e, 0x0016, 0x1160, 0x00c6,
- 0x2d00, 0x2060, 0x080c, 0xe985, 0x080c, 0x8aba, 0x080c, 0xaf2e,
- 0x00ce, 0x080c, 0xaf2e, 0x0005, 0x0026, 0x0036, 0x0046, 0x7228,
- 0xacb0, 0xabac, 0xd2f4, 0x0130, 0x2001, 0x1989, 0x2004, 0x684a,
- 0x0804, 0xb606, 0x00c6, 0x2d60, 0x080c, 0xc7f5, 0x00ce, 0x6804,
- 0x9086, 0x0050, 0x1168, 0x00c6, 0x2d00, 0x2060, 0x6003, 0x0001,
- 0x6007, 0x0050, 0x2009, 0x8023, 0x080c, 0x9428, 0x00ce, 0x04f0,
- 0x6800, 0x9086, 0x000f, 0x01a8, 0x89ff, 0x090c, 0x0d85, 0x6800,
- 0x9086, 0x0004, 0x1190, 0xa87c, 0xd0ac, 0x0178, 0xa843, 0x0fff,
- 0xa83f, 0x0fff, 0xa880, 0xc0fc, 0xa882, 0x2001, 0x0001, 0x6832,
- 0x0400, 0x2001, 0x0007, 0x6832, 0x00e0, 0xa87c, 0xd0b4, 0x1150,
- 0xd0ac, 0x0db8, 0x6824, 0xd0f4, 0x1d48, 0xa838, 0xa934, 0x9105,
- 0x0d80, 0x0c20, 0xd2ec, 0x1d68, 0x7024, 0x9306, 0x1118, 0x7020,
- 0x9406, 0x0d38, 0x7020, 0x683e, 0x7024, 0x683a, 0x2001, 0x0005,
- 0x6832, 0x080c, 0xcf9b, 0x080c, 0x98bf, 0x0010, 0x080c, 0xaf2e,
- 0x004e, 0x003e, 0x002e, 0x0005, 0x00e6, 0x00d6, 0x0026, 0x7008,
- 0x9084, 0x00ff, 0x6210, 0x00b6, 0x2258, 0xba10, 0x00be, 0x9206,
- 0x1904, 0xb671, 0x700c, 0x6210, 0x00b6, 0x2258, 0xba14, 0x00be,
- 0x9206, 0x1904, 0xb671, 0x6038, 0x2068, 0x6824, 0xc0dc, 0x6826,
- 0x6a20, 0x9286, 0x0007, 0x0904, 0xb671, 0x9286, 0x0002, 0x0904,
- 0xb671, 0x9286, 0x0000, 0x05e8, 0x6808, 0x633c, 0x9306, 0x15c8,
- 0x2071, 0x026c, 0x9186, 0x0015, 0x0570, 0x918e, 0x0016, 0x1100,
- 0x00c6, 0x6038, 0x2060, 0x6104, 0x9186, 0x004b, 0x01c0, 0x9186,
- 0x004c, 0x01a8, 0x9186, 0x004d, 0x0190, 0x9186, 0x004e, 0x0178,
- 0x9186, 0x0052, 0x0160, 0x6014, 0x0096, 0x2048, 0x080c, 0xcc16,
- 0x090c, 0x0d85, 0xa87b, 0x0003, 0x009e, 0x080c, 0xd2f8, 0x6007,
- 0x0085, 0x6003, 0x000b, 0x6023, 0x0002, 0x2009, 0x8020, 0x080c,
- 0x9428, 0x00ce, 0x0030, 0x6038, 0x2070, 0x2001, 0x1989, 0x2004,
- 0x704a, 0x080c, 0xaf2e, 0x002e, 0x00de, 0x00ee, 0x0005, 0x00b6,
- 0x0096, 0x00f6, 0x6014, 0x2048, 0x6010, 0x2058, 0x91b6, 0x0015,
- 0x0130, 0xba08, 0xbb0c, 0xbc00, 0xc48c, 0xbc02, 0x0460, 0x0096,
- 0x0156, 0x0036, 0x0026, 0x2b48, 0x9e90, 0x0010, 0x2019, 0x000a,
- 0x20a9, 0x0004, 0x080c, 0xbf3e, 0x002e, 0x003e, 0x015e, 0x009e,
- 0x1904, 0xb6e0, 0x0096, 0x0156, 0x0036, 0x0026, 0x2b48, 0x9e90,
- 0x0014, 0x2019, 0x0006, 0x20a9, 0x0004, 0x080c, 0xbf3e, 0x002e,
- 0x003e, 0x015e, 0x009e, 0x15a0, 0x7238, 0xba0a, 0x733c, 0xbb0e,
- 0xbc00, 0xc48d, 0xbc02, 0xa804, 0x9005, 0x1128, 0x00fe, 0x009e,
- 0x00be, 0x0804, 0xb341, 0x0096, 0x2048, 0xaa12, 0xab16, 0xac0a,
- 0x009e, 0x8006, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0,
- 0x9080, 0x0002, 0x2009, 0x002b, 0xaaa0, 0xab9c, 0xaca8, 0xada4,
- 0x2031, 0x0000, 0x2041, 0x12a8, 0x080c, 0xb456, 0x0130, 0x00fe,
- 0x009e, 0x080c, 0xaf2e, 0x00be, 0x0005, 0x080c, 0xb91f, 0x0cb8,
- 0x2b78, 0x00f6, 0x080c, 0x3310, 0x080c, 0xd353, 0x00fe, 0x00c6,
- 0x080c, 0xaed8, 0x2f00, 0x6012, 0x6017, 0x0000, 0x6023, 0x0001,
- 0x6007, 0x0001, 0x6003, 0x0001, 0x2001, 0x0007, 0x080c, 0x66cf,
- 0x080c, 0x66fb, 0x080c, 0x942f, 0x080c, 0x98bf, 0x00ce, 0x0804,
- 0xb6b3, 0x2100, 0x91b2, 0x0053, 0x1a0c, 0x0d85, 0x91b2, 0x0040,
- 0x1a04, 0xb769, 0x0002, 0xb757, 0xb757, 0xb74d, 0xb757, 0xb757,
- 0xb757, 0xb74b, 0xb74b, 0xb74b, 0xb74b, 0xb74b, 0xb74b, 0xb74b,
- 0xb74b, 0xb74b, 0xb74b, 0xb74b, 0xb74b, 0xb74b, 0xb74b, 0xb74b,
- 0xb74b, 0xb74b, 0xb74b, 0xb74b, 0xb74b, 0xb74b, 0xb74b, 0xb74b,
- 0xb74b, 0xb74b, 0xb757, 0xb74b, 0xb757, 0xb757, 0xb74b, 0xb74b,
- 0xb74b, 0xb74b, 0xb74b, 0xb74d, 0xb74b, 0xb74b, 0xb74b, 0xb74b,
- 0xb74b, 0xb74b, 0xb74b, 0xb74b, 0xb74b, 0xb757, 0xb757, 0xb74b,
- 0xb74b, 0xb74b, 0xb74b, 0xb74b, 0xb74b, 0xb74b, 0xb74b, 0xb74b,
- 0xb757, 0xb74b, 0xb74b, 0x080c, 0x0d85, 0x0066, 0x00b6, 0x6610,
- 0x2658, 0xb8d4, 0xc08c, 0xb8d6, 0x00be, 0x006e, 0x0000, 0x6003,
- 0x0001, 0x6106, 0x9186, 0x0032, 0x0118, 0x080c, 0x942f, 0x0010,
- 0x080c, 0x9428, 0x0126, 0x2091, 0x8000, 0x080c, 0x98bf, 0x012e,
- 0x0005, 0x2600, 0x0002, 0xb757, 0xb757, 0xb77d, 0xb757, 0xb757,
- 0xb77d, 0xb77d, 0xb77d, 0xb77d, 0xb757, 0xb77d, 0xb757, 0xb77d,
- 0xb757, 0xb77d, 0xb77d, 0xb77d, 0xb77d, 0x080c, 0x0d85, 0x6004,
- 0x90b2, 0x0053, 0x1a0c, 0x0d85, 0x91b6, 0x0013, 0x0904, 0xb854,
- 0x91b6, 0x0027, 0x1904, 0xb800, 0x080c, 0x97fe, 0x6004, 0x080c,
- 0xce1c, 0x01b0, 0x080c, 0xce2d, 0x01a8, 0x908e, 0x0021, 0x0904,
- 0xb7fd, 0x908e, 0x0022, 0x1130, 0x080c, 0xb36d, 0x0904, 0xb7f9,
- 0x0804, 0xb7fa, 0x908e, 0x003d, 0x0904, 0xb7fd, 0x0804, 0xb7f3,
- 0x080c, 0x333f, 0x2001, 0x0007, 0x080c, 0x66cf, 0x6010, 0x00b6,
- 0x2058, 0xb9a0, 0x00be, 0x080c, 0xb91f, 0x9186, 0x007e, 0x1148,
- 0x2001, 0x1837, 0x2014, 0xc285, 0x080c, 0x76a5, 0x1108, 0xc2ad,
- 0x2202, 0x080c, 0xaae0, 0x0036, 0x0026, 0x2019, 0x0028, 0x2110,
- 0x080c, 0xea92, 0x002e, 0x003e, 0x0016, 0x0026, 0x0036, 0x2110,
- 0x2019, 0x0028, 0x080c, 0x95c1, 0x0076, 0x903e, 0x080c, 0x947e,
- 0x6010, 0x00b6, 0x905d, 0x0100, 0x00be, 0x2c08, 0x080c, 0xe440,
- 0x007e, 0x003e, 0x002e, 0x001e, 0x080c, 0xaafc, 0x080c, 0xd353,
- 0x0016, 0x080c, 0xd0a9, 0x080c, 0xaf2e, 0x001e, 0x080c, 0x3419,
- 0x080c, 0x98bf, 0x0030, 0x080c, 0xd0a9, 0x080c, 0xaf2e, 0x080c,
- 0x98bf, 0x0005, 0x080c, 0xb91f, 0x0cb0, 0x080c, 0xb95b, 0x0c98,
- 0x9186, 0x0015, 0x0118, 0x9186, 0x0016, 0x1140, 0x080c, 0xad2d,
- 0x0d80, 0x9086, 0x0002, 0x0904, 0xb966, 0x0c58, 0x9186, 0x0014,
- 0x1d40, 0x080c, 0x97fe, 0x6004, 0x908e, 0x0022, 0x1118, 0x080c,
- 0xb36d, 0x09f8, 0x080c, 0x3310, 0x080c, 0xd353, 0x080c, 0xce1c,
- 0x1190, 0x080c, 0x333f, 0x6010, 0x00b6, 0x2058, 0xb9a0, 0x00be,
- 0x080c, 0xb91f, 0x9186, 0x007e, 0x1128, 0x2001, 0x1837, 0x200c,
- 0xc185, 0x2102, 0x0800, 0x080c, 0xce2d, 0x1120, 0x080c, 0xb91f,
- 0x0804, 0xb7f3, 0x6004, 0x908e, 0x0032, 0x1160, 0x00e6, 0x00f6,
- 0x2071, 0x189e, 0x2079, 0x0000, 0x080c, 0x36ba, 0x00fe, 0x00ee,
- 0x0804, 0xb7f3, 0x6004, 0x908e, 0x0021, 0x0d40, 0x908e, 0x0022,
- 0x090c, 0xb91f, 0x0804, 0xb7f3, 0x90b2, 0x0040, 0x1a04, 0xb8ff,
- 0x2008, 0x0002, 0xb89c, 0xb89d, 0xb8a0, 0xb8a3, 0xb8a6, 0xb8b3,
- 0xb89a, 0xb89a, 0xb89a, 0xb89a, 0xb89a, 0xb89a, 0xb89a, 0xb89a,
- 0xb89a, 0xb89a, 0xb89a, 0xb89a, 0xb89a, 0xb89a, 0xb89a, 0xb89a,
- 0xb89a, 0xb89a, 0xb89a, 0xb89a, 0xb89a, 0xb89a, 0xb89a, 0xb89a,
- 0xb8b6, 0xb8c1, 0xb89a, 0xb8c2, 0xb8c1, 0xb89a, 0xb89a, 0xb89a,
- 0xb89a, 0xb89a, 0xb8c1, 0xb8c1, 0xb89a, 0xb89a, 0xb89a, 0xb89a,
- 0xb89a, 0xb89a, 0xb89a, 0xb89a, 0xb8ea, 0xb8c1, 0xb89a, 0xb8bd,
- 0xb89a, 0xb89a, 0xb89a, 0xb8be, 0xb89a, 0xb89a, 0xb89a, 0xb8c1,
- 0xb8e5, 0xb89a, 0x080c, 0x0d85, 0x0420, 0x2001, 0x000b, 0x0448,
- 0x2001, 0x0003, 0x0430, 0x2001, 0x0005, 0x0418, 0x6010, 0x00b6,
- 0x2058, 0xb804, 0x00be, 0x9084, 0x00ff, 0x9086, 0x0000, 0x11d8,
- 0x2001, 0x0001, 0x00b0, 0x2001, 0x0009, 0x0098, 0x6003, 0x0005,
- 0x080c, 0xd356, 0x080c, 0x98bf, 0x0058, 0x0018, 0x0010, 0x080c,
- 0x66cf, 0x04b8, 0x080c, 0xd356, 0x6003, 0x0004, 0x080c, 0x98bf,
- 0x0005, 0x080c, 0x66cf, 0x6003, 0x0002, 0x0036, 0x2019, 0x1852,
- 0x2304, 0x9084, 0xff00, 0x1120, 0x2001, 0x1987, 0x201c, 0x0040,
- 0x8007, 0x909a, 0x0004, 0x0ec0, 0x8003, 0x801b, 0x831b, 0x9318,
- 0x631a, 0x003e, 0x080c, 0x98bf, 0x0c18, 0x080c, 0xd0a9, 0x080c,
- 0xaf2e, 0x08f0, 0x00e6, 0x00f6, 0x2071, 0x189e, 0x2079, 0x0000,
- 0x080c, 0x36ba, 0x00fe, 0x00ee, 0x080c, 0x97fe, 0x080c, 0xaf2e,
- 0x0878, 0x6003, 0x0002, 0x080c, 0xd356, 0x0804, 0x98bf, 0x2600,
- 0x2008, 0x0002, 0xb916, 0xb8f9, 0xb914, 0xb8f9, 0xb8f9, 0xb914,
- 0xb914, 0xb914, 0xb914, 0xb8f9, 0xb914, 0xb8f9, 0xb914, 0xb8f9,
- 0xb914, 0xb914, 0xb914, 0xb914, 0x080c, 0x0d85, 0x0096, 0x6014,
- 0x2048, 0x080c, 0x6f19, 0x009e, 0x080c, 0xaf2e, 0x0005, 0x00e6,
- 0x0096, 0x0026, 0x0016, 0x080c, 0xcc16, 0x0568, 0x6014, 0x2048,
- 0xa864, 0x9086, 0x0139, 0x11a8, 0xa894, 0x9086, 0x0056, 0x1148,
- 0x080c, 0x55b2, 0x0130, 0x2001, 0x0000, 0x900e, 0x2011, 0x4000,
- 0x0028, 0x2001, 0x0030, 0x900e, 0x2011, 0x4005, 0x080c, 0xd21a,
- 0x0090, 0xa868, 0xd0fc, 0x0178, 0xa807, 0x0000, 0x0016, 0x6004,
- 0x908e, 0x0021, 0x0168, 0x908e, 0x003d, 0x0150, 0x001e, 0xa867,
- 0x0103, 0xa833, 0x0100, 0x001e, 0x002e, 0x009e, 0x00ee, 0x0005,
- 0x001e, 0x0009, 0x0cc0, 0x0096, 0x6014, 0x2048, 0xa800, 0x2048,
- 0xa867, 0x0103, 0xa823, 0x8001, 0x009e, 0x0005, 0x00b6, 0x6610,
- 0x2658, 0xb804, 0x9084, 0x00ff, 0x90b2, 0x000c, 0x1a0c, 0x0d85,
- 0x6604, 0x96b6, 0x004d, 0x1120, 0x080c, 0xd139, 0x0804, 0xb9eb,
- 0x6604, 0x96b6, 0x0043, 0x1120, 0x080c, 0xd182, 0x0804, 0xb9eb,
- 0x6604, 0x96b6, 0x004b, 0x1120, 0x080c, 0xd1ae, 0x0804, 0xb9eb,
- 0x6604, 0x96b6, 0x0033, 0x1120, 0x080c, 0xd0cb, 0x0804, 0xb9eb,
- 0x6604, 0x96b6, 0x0028, 0x1120, 0x080c, 0xce6b, 0x0804, 0xb9eb,
- 0x6604, 0x96b6, 0x0029, 0x1120, 0x080c, 0xceac, 0x0804, 0xb9eb,
- 0x6604, 0x96b6, 0x001f, 0x1120, 0x080c, 0xb312, 0x0804, 0xb9eb,
- 0x6604, 0x96b6, 0x0000, 0x1118, 0x080c, 0xb677, 0x04e0, 0x6604,
- 0x96b6, 0x0022, 0x1118, 0x080c, 0xb34e, 0x04a8, 0x6604, 0x96b6,
- 0x0035, 0x1118, 0x080c, 0xb474, 0x0470, 0x6604, 0x96b6, 0x0039,
- 0x1118, 0x080c, 0xb60c, 0x0438, 0x6604, 0x96b6, 0x003d, 0x1118,
- 0x080c, 0xb386, 0x0400, 0x6604, 0x96b6, 0x0044, 0x1118, 0x080c,
- 0xb3c2, 0x00c8, 0x6604, 0x96b6, 0x0049, 0x1118, 0x080c, 0xb403,
- 0x0090, 0x6604, 0x96b6, 0x0041, 0x1118, 0x080c, 0xb3ed, 0x0058,
- 0x91b6, 0x0015, 0x1110, 0x0063, 0x0030, 0x91b6, 0x0016, 0x1128,
- 0x00be, 0x0804, 0xbc55, 0x00be, 0x0005, 0x080c, 0xafe9, 0x0cd8,
- 0xba08, 0xba16, 0xba08, 0xba5d, 0xba08, 0xbbc9, 0xbc62, 0xba08,
- 0xba08, 0xbc2b, 0xba08, 0xbc41, 0x0096, 0x601f, 0x0000, 0x6014,
- 0x2048, 0xa800, 0x2048, 0xa867, 0x0103, 0x009e, 0x0804, 0xaf2e,
- 0xa001, 0xa001, 0x0005, 0x6604, 0x96b6, 0x0004, 0x1130, 0x2001,
- 0x0001, 0x080c, 0x66bb, 0x0804, 0xaf2e, 0x0005, 0x00e6, 0x2071,
- 0x1800, 0x7090, 0x9086, 0x0074, 0x1540, 0x080c, 0xe411, 0x11b0,
- 0x6010, 0x00b6, 0x2058, 0x7030, 0xd08c, 0x0128, 0xb800, 0xd0bc,
- 0x0110, 0xc0c5, 0xb802, 0x00f9, 0x00be, 0x2001, 0x0006, 0x080c,
- 0x66cf, 0x080c, 0x333f, 0x080c, 0xaf2e, 0x0098, 0x2001, 0x000a,
- 0x080c, 0x66cf, 0x080c, 0x333f, 0x6003, 0x0001, 0x6007, 0x0001,
- 0x080c, 0x942f, 0x080c, 0x98bf, 0x0020, 0x2001, 0x0001, 0x080c,
- 0xbb99, 0x00ee, 0x0005, 0x00d6, 0xb800, 0xd084, 0x0160, 0x9006,
- 0x080c, 0x66bb, 0x2069, 0x1847, 0x6804, 0xd0a4, 0x0120, 0x2001,
- 0x0006, 0x080c, 0x66fb, 0x00de, 0x0005, 0x00b6, 0x0096, 0x00d6,
- 0x2011, 0x1824, 0x2204, 0x9086, 0x0074, 0x1904, 0xbb6e, 0x6010,
- 0x2058, 0xbaa0, 0x9286, 0x007e, 0x1120, 0x080c, 0xbdb1, 0x0804,
- 0xbacf, 0x080c, 0xbda6, 0x6010, 0x2058, 0xbaa0, 0x9286, 0x0080,
- 0x1510, 0x6014, 0x9005, 0x01a8, 0x2048, 0xa864, 0x9084, 0x00ff,
- 0x9086, 0x0039, 0x1140, 0x2001, 0x0000, 0x900e, 0x2011, 0x4000,
- 0x080c, 0xd21a, 0x0030, 0xa807, 0x0000, 0xa867, 0x0103, 0xa833,
- 0x0200, 0x2001, 0x0006, 0x080c, 0x66cf, 0x080c, 0x333f, 0x080c,
- 0xaf2e, 0x0804, 0xbb73, 0x080c, 0xbb81, 0x6014, 0x9005, 0x0190,
- 0x2048, 0xa868, 0xd0f4, 0x01e8, 0xa864, 0x9084, 0x00ff, 0x9086,
- 0x0039, 0x1d08, 0x2001, 0x0000, 0x900e, 0x2011, 0x4000, 0x080c,
- 0xd21a, 0x08f8, 0x080c, 0xbb77, 0x0160, 0x9006, 0x080c, 0x66bb,
- 0x2001, 0x0004, 0x080c, 0x66fb, 0x2001, 0x0007, 0x080c, 0x66cf,
- 0x08a0, 0x2001, 0x0004, 0x080c, 0x66cf, 0x6003, 0x0001, 0x6007,
- 0x0003, 0x080c, 0x942f, 0x080c, 0x98bf, 0x0804, 0xbb73, 0xb85c,
- 0xd0e4, 0x01d8, 0x080c, 0xd043, 0x080c, 0x76a5, 0x0118, 0xd0dc,
- 0x1904, 0xba91, 0x2011, 0x1837, 0x2204, 0xc0ad, 0x2012, 0x2001,
- 0x196e, 0x2004, 0x00f6, 0x2079, 0x0100, 0x78e3, 0x0000, 0x080c,
- 0x2716, 0x78e2, 0x00fe, 0x0804, 0xba91, 0x080c, 0xd084, 0x2011,
- 0x1837, 0x2204, 0xc0a5, 0x2012, 0x0006, 0x080c, 0xe5a2, 0x000e,
- 0x1904, 0xba91, 0xc0b5, 0x2012, 0x2001, 0x0006, 0x080c, 0x66cf,
- 0x9006, 0x080c, 0x66bb, 0x00c6, 0x2001, 0x180f, 0x2004, 0xd09c,
- 0x0520, 0x00f6, 0x2079, 0x0100, 0x00e6, 0x2071, 0x1800, 0x700c,
- 0x9084, 0x00ff, 0x78e6, 0x707e, 0x7010, 0x78ea, 0x7082, 0x908c,
- 0x00ff, 0x00ee, 0x780c, 0xc0b5, 0x780e, 0x00fe, 0x080c, 0x26eb,
- 0x00f6, 0x2100, 0x900e, 0x080c, 0x26a2, 0x795e, 0x00fe, 0x9186,
- 0x0081, 0x01f0, 0x2009, 0x0081, 0x00e0, 0x2009, 0x00ef, 0x00f6,
- 0x2079, 0x0100, 0x79ea, 0x78e7, 0x0000, 0x7932, 0x7936, 0x780c,
- 0xc0b5, 0x780e, 0x00fe, 0x080c, 0x26eb, 0x00f6, 0x2079, 0x1800,
- 0x7982, 0x2100, 0x900e, 0x797e, 0x080c, 0x26a2, 0x795e, 0x00fe,
- 0x8108, 0x080c, 0x671e, 0x2b00, 0x00ce, 0x1904, 0xba91, 0x6012,
- 0x2009, 0x180f, 0x210c, 0xd19c, 0x0150, 0x2009, 0x027c, 0x210c,
- 0x918c, 0x00ff, 0xb912, 0x2009, 0x027d, 0x210c, 0xb916, 0x2001,
- 0x0002, 0x080c, 0x66cf, 0x6023, 0x0001, 0x6003, 0x0001, 0x6007,
- 0x0002, 0x080c, 0x942f, 0x080c, 0x98bf, 0x0028, 0x080c, 0xb91f,
- 0x2001, 0x0001, 0x0431, 0x00de, 0x009e, 0x00be, 0x0005, 0x2001,
- 0x1810, 0x2004, 0xd0a4, 0x0120, 0x2001, 0x1848, 0x2004, 0xd0ac,
- 0x0005, 0x00e6, 0x080c, 0xeaeb, 0x0190, 0x2071, 0x0260, 0x7108,
- 0x720c, 0x918c, 0x00ff, 0x1118, 0x9284, 0xff00, 0x0140, 0x6010,
- 0x2058, 0xb8a0, 0x9084, 0xff80, 0x1110, 0xb912, 0xba16, 0x00ee,
- 0x0005, 0x2030, 0x9005, 0x0158, 0x2001, 0x0007, 0x080c, 0x66cf,
- 0x080c, 0x583a, 0x1120, 0x2001, 0x0007, 0x080c, 0x66fb, 0x2600,
- 0x9005, 0x11b0, 0x6014, 0x0096, 0x2048, 0xa868, 0x009e, 0xd0fc,
- 0x1178, 0x0036, 0x0046, 0x6010, 0x00b6, 0x2058, 0xbba0, 0x00be,
- 0x2021, 0x0004, 0x2011, 0x8014, 0x080c, 0x4c2e, 0x004e, 0x003e,
- 0x080c, 0x333f, 0x6020, 0x9086, 0x000a, 0x1108, 0x0005, 0x0804,
- 0xaf2e, 0x00b6, 0x00e6, 0x0026, 0x0016, 0x2071, 0x1800, 0x7090,
- 0x9086, 0x0014, 0x1904, 0xbc21, 0x080c, 0x583a, 0x1170, 0x6014,
- 0x9005, 0x1158, 0x0036, 0x0046, 0x6010, 0x2058, 0xbba0, 0x2021,
- 0x0006, 0x080c, 0x4de5, 0x004e, 0x003e, 0x00d6, 0x6010, 0x2058,
- 0x080c, 0x6824, 0x080c, 0xba4b, 0x00de, 0x080c, 0xbe77, 0x1588,
- 0x6010, 0x2058, 0xb890, 0x9005, 0x0560, 0x2001, 0x0006, 0x080c,
- 0x66cf, 0x0096, 0x6014, 0x904d, 0x01d0, 0xa864, 0x9084, 0x00ff,
- 0x9086, 0x0039, 0x1140, 0x2001, 0x0000, 0x900e, 0x2011, 0x4000,
- 0x080c, 0xd21a, 0x0060, 0xa864, 0x9084, 0x00ff, 0x9086, 0x0029,
- 0x0130, 0xa807, 0x0000, 0xa867, 0x0103, 0xa833, 0x0200, 0x009e,
- 0x080c, 0x333f, 0x6020, 0x9086, 0x000a, 0x0140, 0x080c, 0xaf2e,
- 0x0028, 0x080c, 0xb91f, 0x9006, 0x080c, 0xbb99, 0x001e, 0x002e,
- 0x00ee, 0x00be, 0x0005, 0x2011, 0x1824, 0x2204, 0x9086, 0x0014,
- 0x1160, 0x2001, 0x0002, 0x080c, 0x66cf, 0x6003, 0x0001, 0x6007,
- 0x0001, 0x080c, 0x942f, 0x0804, 0x98bf, 0x2001, 0x0001, 0x0804,
- 0xbb99, 0x2030, 0x2011, 0x1824, 0x2204, 0x9086, 0x0004, 0x1148,
- 0x96b6, 0x000b, 0x1120, 0x2001, 0x0007, 0x080c, 0x66cf, 0x0804,
- 0xaf2e, 0x2001, 0x0001, 0x0804, 0xbb99, 0x0002, 0xba08, 0xbc6d,
- 0xba08, 0xbcb0, 0xba08, 0xbd5d, 0xbc62, 0xba0b, 0xba08, 0xbd71,
- 0xba08, 0xbd83, 0x6604, 0x9686, 0x0003, 0x0904, 0xbbc9, 0x96b6,
- 0x001e, 0x1110, 0x080c, 0xaf2e, 0x0005, 0x00b6, 0x00d6, 0x00c6,
- 0x080c, 0xbd95, 0x11a0, 0x9006, 0x080c, 0x66bb, 0x080c, 0x3310,
- 0x080c, 0xd353, 0x2001, 0x0002, 0x080c, 0x66cf, 0x6003, 0x0001,
- 0x6007, 0x0002, 0x080c, 0x942f, 0x080c, 0x98bf, 0x0428, 0x2009,
- 0x026e, 0x2104, 0x9086, 0x0009, 0x1160, 0x6010, 0x2058, 0xb840,
- 0x9084, 0x00ff, 0x9005, 0x0180, 0x8001, 0xb842, 0x601b, 0x000a,
- 0x0098, 0x2009, 0x026f, 0x2104, 0x9084, 0xff00, 0x908e, 0x1900,
- 0x0158, 0x908e, 0x1e00, 0x0990, 0x080c, 0x3310, 0x080c, 0xd353,
- 0x2001, 0x0001, 0x080c, 0xbb99, 0x00ce, 0x00de, 0x00be, 0x0005,
- 0x0096, 0x00b6, 0x0026, 0x9016, 0x080c, 0xbda3, 0x00d6, 0x2069,
- 0x197d, 0x2d04, 0x9005, 0x0168, 0x6010, 0x2058, 0xb8a0, 0x9086,
- 0x007e, 0x1138, 0x2069, 0x1820, 0x2d04, 0x8000, 0x206a, 0x00de,
- 0x0010, 0x00de, 0x0088, 0x9006, 0x080c, 0x66bb, 0x2001, 0x0002,
- 0x080c, 0x66cf, 0x6003, 0x0001, 0x6007, 0x0002, 0x080c, 0x942f,
- 0x080c, 0x98bf, 0x0804, 0xbd2d, 0x080c, 0xcc16, 0x01b0, 0x6014,
- 0x2048, 0xa864, 0x2010, 0x9086, 0x0139, 0x1138, 0x6007, 0x0016,
- 0x2001, 0x0002, 0x080c, 0xd277, 0x00b0, 0x6014, 0x2048, 0xa864,
- 0xd0fc, 0x0118, 0x2001, 0x0001, 0x0ca8, 0x2001, 0x180e, 0x2004,
- 0xd0dc, 0x0148, 0x6010, 0x2058, 0xb840, 0x9084, 0x00ff, 0x9005,
- 0x1110, 0x9006, 0x0c38, 0x080c, 0xb91f, 0x2009, 0x026e, 0x2134,
- 0x96b4, 0x00ff, 0x9686, 0x0005, 0x0520, 0x9686, 0x000b, 0x01c8,
- 0x2009, 0x026f, 0x2104, 0x9084, 0xff00, 0x1118, 0x9686, 0x0009,
- 0x01c0, 0x9086, 0x1900, 0x1168, 0x9686, 0x0009, 0x0190, 0x2001,
- 0x0004, 0x080c, 0x66cf, 0x2001, 0x0028, 0x601a, 0x6007, 0x0052,
- 0x0020, 0x2001, 0x0001, 0x080c, 0xbb99, 0x002e, 0x00be, 0x009e,
- 0x0005, 0x9286, 0x0139, 0x0160, 0x6014, 0x2048, 0x080c, 0xcc16,
- 0x0140, 0xa864, 0x9086, 0x0139, 0x0118, 0xa868, 0xd0fc, 0x0108,
- 0x0c40, 0x6010, 0x2058, 0xb840, 0x9084, 0x00ff, 0x9005, 0x0138,
- 0x8001, 0xb842, 0x601b, 0x000a, 0x6007, 0x0016, 0x08f0, 0xb8a0,
- 0x9086, 0x007e, 0x1138, 0x00e6, 0x2071, 0x1800, 0x080c, 0x6111,
- 0x00ee, 0x0010, 0x080c, 0x3310, 0x0860, 0x2001, 0x0004, 0x080c,
- 0x66cf, 0x080c, 0xbda3, 0x1140, 0x6003, 0x0001, 0x6007, 0x0003,
- 0x080c, 0x942f, 0x0804, 0x98bf, 0x080c, 0xb91f, 0x9006, 0x0804,
- 0xbb99, 0x0489, 0x1160, 0x2001, 0x0008, 0x080c, 0x66cf, 0x6003,
- 0x0001, 0x6007, 0x0005, 0x080c, 0x942f, 0x0804, 0x98bf, 0x2001,
- 0x0001, 0x0804, 0xbb99, 0x00f9, 0x1160, 0x2001, 0x000a, 0x080c,
- 0x66cf, 0x6003, 0x0001, 0x6007, 0x0001, 0x080c, 0x942f, 0x0804,
- 0x98bf, 0x2001, 0x0001, 0x0804, 0xbb99, 0x2009, 0x026e, 0x2104,
- 0x9086, 0x0003, 0x1138, 0x2009, 0x026f, 0x2104, 0x9084, 0xff00,
- 0x9086, 0x2a00, 0x0005, 0x9085, 0x0001, 0x0005, 0x00b6, 0x00c6,
- 0x0016, 0x6110, 0x2158, 0x080c, 0x6798, 0x001e, 0x00ce, 0x00be,
- 0x0005, 0x00b6, 0x00f6, 0x00e6, 0x00d6, 0x0036, 0x0016, 0x6010,
- 0x2058, 0x2009, 0x1837, 0x2104, 0x9085, 0x0003, 0x200a, 0x080c,
- 0xbe49, 0x0560, 0x2009, 0x1837, 0x2104, 0xc0cd, 0x200a, 0x080c,
- 0x6bd1, 0x0158, 0x9006, 0x2020, 0x2009, 0x002a, 0x080c, 0xe72a,
- 0x2001, 0x180c, 0x200c, 0xc195, 0x2102, 0x2019, 0x002a, 0x2009,
- 0x0001, 0x080c, 0x32d5, 0x00e6, 0x2071, 0x1800, 0x080c, 0x30e1,
- 0x00ee, 0x00c6, 0x0156, 0x20a9, 0x0781, 0x2009, 0x007f, 0x080c,
- 0x3419, 0x8108, 0x1f04, 0xbde7, 0x015e, 0x00ce, 0x080c, 0xbda6,
- 0x2071, 0x0260, 0x2079, 0x0200, 0x7817, 0x0001, 0x2001, 0x1837,
- 0x200c, 0xc1c5, 0x7018, 0xd0fc, 0x0110, 0xd0dc, 0x0118, 0x7038,
- 0xd0dc, 0x1108, 0xc1c4, 0x7817, 0x0000, 0x2001, 0x1837, 0x2102,
- 0x2079, 0x0100, 0x2e04, 0x9084, 0x00ff, 0x2069, 0x181f, 0x206a,
- 0x78e6, 0x0006, 0x8e70, 0x2e04, 0x2069, 0x1820, 0x206a, 0x78ea,
- 0x7832, 0x7836, 0x2010, 0x9084, 0xff00, 0x001e, 0x9105, 0x2009,
- 0x182c, 0x200a, 0x2200, 0x9084, 0x00ff, 0x2008, 0x080c, 0x26eb,
- 0x080c, 0x76a5, 0x0170, 0x2071, 0x0260, 0x2069, 0x1983, 0x7048,
- 0x206a, 0x704c, 0x6806, 0x7050, 0x680a, 0x7054, 0x680e, 0x080c,
- 0xd043, 0x0040, 0x2001, 0x0006, 0x080c, 0x66cf, 0x080c, 0x333f,
- 0x080c, 0xaf2e, 0x001e, 0x003e, 0x00de, 0x00ee, 0x00fe, 0x00be,
- 0x0005, 0x0096, 0x0026, 0x0036, 0x00e6, 0x0156, 0x2019, 0x182c,
- 0x231c, 0x83ff, 0x01f0, 0x2071, 0x0260, 0x7200, 0x9294, 0x00ff,
- 0x7004, 0x9084, 0xff00, 0x9205, 0x9306, 0x1198, 0x2011, 0x0276,
- 0x20a9, 0x0004, 0x2b48, 0x2019, 0x000a, 0x080c, 0xbf3e, 0x1148,
- 0x2011, 0x027a, 0x20a9, 0x0004, 0x2019, 0x0006, 0x080c, 0xbf3e,
- 0x1100, 0x015e, 0x00ee, 0x003e, 0x002e, 0x009e, 0x0005, 0x00e6,
- 0x2071, 0x0260, 0x7034, 0x9086, 0x0014, 0x11a8, 0x7038, 0x9086,
- 0x0800, 0x1188, 0x703c, 0xd0ec, 0x0160, 0x9084, 0x0f00, 0x9086,
- 0x0100, 0x1138, 0x7054, 0xd0a4, 0x1110, 0xd0ac, 0x0110, 0x9006,
- 0x0010, 0x9085, 0x0001, 0x00ee, 0x0005, 0x00e6, 0x0096, 0x00c6,
- 0x0076, 0x0056, 0x0046, 0x0026, 0x0006, 0x0126, 0x2091, 0x8000,
- 0x2029, 0x19f5, 0x252c, 0x2021, 0x19fc, 0x2424, 0x2061, 0x1ddc,
- 0x2071, 0x1800, 0x7254, 0x7074, 0x9202, 0x1a04, 0xbf0a, 0x080c,
- 0x8d8f, 0x0904, 0xbf03, 0x080c, 0xe75b, 0x0904, 0xbf03, 0x6720,
- 0x9786, 0x0007, 0x0904, 0xbf03, 0x2500, 0x9c06, 0x0904, 0xbf03,
- 0x2400, 0x9c06, 0x0904, 0xbf03, 0x3e08, 0x9186, 0x0002, 0x1148,
- 0x6010, 0x9005, 0x0130, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc,
- 0x1590, 0x00c6, 0x6043, 0xffff, 0x6000, 0x9086, 0x0004, 0x1110,
- 0x080c, 0x1afc, 0x9786, 0x000a, 0x0148, 0x080c, 0xce2d, 0x1130,
- 0x00ce, 0x080c, 0xb91f, 0x080c, 0xaf69, 0x00e8, 0x6014, 0x2048,
- 0x080c, 0xcc16, 0x01a8, 0x9786, 0x0003, 0x1530, 0xa867, 0x0103,
- 0xa87c, 0xd0cc, 0x0130, 0x0096, 0xa878, 0x2048, 0x080c, 0x100b,
- 0x009e, 0xab7a, 0xa877, 0x0000, 0x080c, 0x6f0d, 0x080c, 0xce07,
- 0x080c, 0xaf69, 0x00ce, 0x9ce0, 0x001c, 0x7068, 0x9c02, 0x1210,
- 0x0804, 0xbeaa, 0x012e, 0x000e, 0x002e, 0x004e, 0x005e, 0x007e,
- 0x00ce, 0x009e, 0x00ee, 0x0005, 0x9786, 0x0006, 0x1118, 0x080c,
- 0xe6cd, 0x0c30, 0x9786, 0x0009, 0x1148, 0x6000, 0x9086, 0x0004,
- 0x0d08, 0x2009, 0x004c, 0x080c, 0xafcc, 0x08e0, 0x9786, 0x000a,
- 0x0980, 0x0820, 0x220c, 0x2304, 0x9106, 0x1130, 0x8210, 0x8318,
- 0x1f04, 0xbf2a, 0x9006, 0x0005, 0x2304, 0x9102, 0x0218, 0x2001,
- 0x0001, 0x0008, 0x9006, 0x918d, 0x0001, 0x0005, 0x0136, 0x01c6,
- 0x0016, 0x8906, 0x8006, 0x8007, 0x908c, 0x003f, 0x21e0, 0x9084,
- 0xffc0, 0x9300, 0x2098, 0x3518, 0x20a9, 0x0001, 0x220c, 0x4002,
- 0x910e, 0x1140, 0x8210, 0x8319, 0x1dc8, 0x9006, 0x001e, 0x01ce,
- 0x013e, 0x0005, 0x220c, 0x9102, 0x0218, 0x2001, 0x0001, 0x0010,
- 0x2001, 0x0000, 0x918d, 0x0001, 0x001e, 0x01ce, 0x013e, 0x0005,
- 0x220c, 0x810f, 0x2304, 0x9106, 0x1130, 0x8210, 0x8318, 0x1f04,
- 0xbf68, 0x9006, 0x0005, 0x918d, 0x0001, 0x0005, 0x6004, 0x908a,
- 0x0053, 0x1a0c, 0x0d85, 0x080c, 0xce1c, 0x0120, 0x080c, 0xce2d,
- 0x0158, 0x0028, 0x080c, 0x333f, 0x080c, 0xce2d, 0x0128, 0x080c,
- 0x97fe, 0x080c, 0xaf2e, 0x0005, 0x080c, 0xb91f, 0x0cc0, 0x9182,
- 0x0057, 0x1220, 0x9182, 0x0040, 0x0208, 0x000a, 0x0005, 0xbfae,
- 0xbfae, 0xbfae, 0xbfae, 0xbfae, 0xbfae, 0xbfae, 0xbfae, 0xbfae,
- 0xbfae, 0xbfae, 0xbfb0, 0xbfb0, 0xbfb0, 0xbfb0, 0xbfae, 0xbfae,
- 0xbfae, 0xbfb0, 0xbfae, 0xbfae, 0xbfae, 0xbfae, 0x080c, 0x0d85,
- 0x600b, 0xffff, 0x6003, 0x000f, 0x6106, 0x0126, 0x2091, 0x8000,
- 0x080c, 0xd356, 0x2009, 0x8000, 0x080c, 0x9428, 0x012e, 0x0005,
- 0x9186, 0x0013, 0x1128, 0x6004, 0x9082, 0x0040, 0x0804, 0xc038,
- 0x9186, 0x0027, 0x1520, 0x080c, 0x97fe, 0x080c, 0x3310, 0x080c,
- 0xd353, 0x0096, 0x6114, 0x2148, 0x080c, 0xcc16, 0x0198, 0x080c,
- 0xce2d, 0x1118, 0x080c, 0xb91f, 0x0068, 0xa867, 0x0103, 0xa87b,
- 0x0029, 0xa877, 0x0000, 0xa97c, 0xc1c5, 0xa97e, 0x080c, 0x6f19,
- 0x080c, 0xce07, 0x009e, 0x080c, 0xaf2e, 0x0804, 0x98bf, 0x9186,
- 0x0014, 0x1120, 0x6004, 0x9082, 0x0040, 0x0030, 0x9186, 0x0053,
- 0x0110, 0x080c, 0x0d85, 0x0005, 0x0002, 0xc016, 0xc014, 0xc014,
- 0xc014, 0xc014, 0xc014, 0xc014, 0xc014, 0xc014, 0xc014, 0xc014,
- 0xc02f, 0xc02f, 0xc02f, 0xc02f, 0xc014, 0xc02f, 0xc014, 0xc02f,
- 0xc014, 0xc014, 0xc014, 0xc014, 0x080c, 0x0d85, 0x080c, 0x97fe,
- 0x0096, 0x6114, 0x2148, 0x080c, 0xcc16, 0x0168, 0xa867, 0x0103,
- 0xa87b, 0x0006, 0xa877, 0x0000, 0xa880, 0xc0ec, 0xa882, 0x080c,
- 0x6f19, 0x080c, 0xce07, 0x009e, 0x080c, 0xaf2e, 0x0005, 0x080c,
- 0x97fe, 0x080c, 0xce2d, 0x090c, 0xb91f, 0x080c, 0xaf2e, 0x0005,
- 0x0002, 0xc052, 0xc050, 0xc050, 0xc050, 0xc050, 0xc050, 0xc050,
- 0xc050, 0xc050, 0xc050, 0xc050, 0xc054, 0xc054, 0xc054, 0xc054,
- 0xc050, 0xc056, 0xc050, 0xc054, 0xc050, 0xc050, 0xc050, 0xc050,
- 0x080c, 0x0d85, 0x080c, 0x0d85, 0x080c, 0x0d85, 0x080c, 0xaf2e,
- 0x0804, 0x98bf, 0x9182, 0x0057, 0x1220, 0x9182, 0x0040, 0x0208,
- 0x000a, 0x0005, 0xc079, 0xc079, 0xc079, 0xc079, 0xc079, 0xc0b2,
- 0xc1a1, 0xc079, 0xc1ad, 0xc079, 0xc079, 0xc079, 0xc079, 0xc079,
- 0xc079, 0xc079, 0xc079, 0xc079, 0xc079, 0xc1ad, 0xc07b, 0xc079,
- 0xc1ab, 0x080c, 0x0d85, 0x00b6, 0x0096, 0x6114, 0x2148, 0x6010,
- 0x2058, 0xb800, 0xd0bc, 0x1508, 0xa87b, 0x0000, 0xa867, 0x0103,
- 0xa877, 0x0000, 0xa87c, 0xd0ac, 0x0128, 0xa834, 0xa938, 0x9115,
- 0x190c, 0xc232, 0x080c, 0x6d2e, 0x6210, 0x2258, 0xba3c, 0x82ff,
- 0x0110, 0x8211, 0xba3e, 0xb8d0, 0x9005, 0x0110, 0x080c, 0x68b4,
- 0x080c, 0xaf2e, 0x009e, 0x00be, 0x0005, 0xa87c, 0xd0ac, 0x09e0,
- 0xa838, 0xa934, 0x9105, 0x09c0, 0xa880, 0xd0bc, 0x19a8, 0x080c,
- 0xcf62, 0x0c80, 0x00b6, 0x0096, 0x6114, 0x2148, 0x601c, 0xd0fc,
- 0x1110, 0x7644, 0x0008, 0x9036, 0x96b4, 0x0fff, 0x86ff, 0x1590,
- 0x6010, 0x2058, 0xb800, 0xd0bc, 0x1904, 0xc190, 0xa87b, 0x0000,
- 0xa867, 0x0103, 0xae76, 0xa87c, 0xd0ac, 0x0128, 0xa834, 0xa938,
- 0x9115, 0x190c, 0xc232, 0x080c, 0x6d2e, 0x6210, 0x2258, 0xba3c,
- 0x82ff, 0x0110, 0x8211, 0xba3e, 0xb8d0, 0x9005, 0x0110, 0x080c,
- 0x68b4, 0x601c, 0xd0fc, 0x1148, 0x7044, 0xd0e4, 0x1904, 0xc174,
- 0x080c, 0xaf2e, 0x009e, 0x00be, 0x0005, 0x2009, 0x0211, 0x210c,
- 0x080c, 0x0d85, 0x968c, 0x0c00, 0x0150, 0x6010, 0x2058, 0xb800,
- 0xd0bc, 0x1904, 0xc178, 0x7348, 0xab92, 0x734c, 0xab8e, 0x968c,
- 0x00ff, 0x9186, 0x0002, 0x0508, 0x9186, 0x0028, 0x1118, 0xa87b,
- 0x001c, 0x00e8, 0xd6dc, 0x01a0, 0xa87b, 0x0015, 0xa87c, 0xd0ac,
- 0x0170, 0xa938, 0xaa34, 0x2100, 0x9205, 0x0148, 0x7048, 0x9106,
- 0x1118, 0x704c, 0x9206, 0x0118, 0xa992, 0xaa8e, 0xc6dc, 0x0038,
- 0xd6d4, 0x0118, 0xa87b, 0x0007, 0x0010, 0xa87b, 0x0000, 0xa867,
- 0x0103, 0xae76, 0x901e, 0xd6c4, 0x01d8, 0x9686, 0x0100, 0x1130,
- 0x7064, 0x9005, 0x1118, 0xc6c4, 0x0804, 0xc0be, 0x735c, 0xab86,
- 0x83ff, 0x0170, 0x938a, 0x0009, 0x0210, 0x2019, 0x0008, 0x0036,
- 0x2308, 0x2019, 0x0018, 0x2011, 0x0025, 0x080c, 0xc794, 0x003e,
- 0xd6cc, 0x0904, 0xc0d3, 0x7154, 0xa98a, 0x81ff, 0x0904, 0xc0d3,
- 0x9192, 0x0021, 0x1278, 0x8304, 0x9098, 0x0018, 0x2011, 0x0029,
- 0x080c, 0xc794, 0x2011, 0x0205, 0x2013, 0x0000, 0x080c, 0xd2e3,
- 0x0804, 0xc0d3, 0xa868, 0xd0fc, 0x0120, 0x2009, 0x0020, 0xa98a,
- 0x0c50, 0x00a6, 0x2950, 0x080c, 0xc733, 0x00ae, 0x080c, 0xd2e3,
- 0x080c, 0xc784, 0x0804, 0xc0d5, 0x080c, 0xcf25, 0x0804, 0xc0ea,
- 0xa87c, 0xd0ac, 0x0904, 0xc0fb, 0xa880, 0xd0bc, 0x1904, 0xc0fb,
- 0x7348, 0xa838, 0x9306, 0x11c8, 0x734c, 0xa834, 0x931e, 0x0904,
- 0xc0fb, 0xd6d4, 0x0190, 0xab38, 0x9305, 0x0904, 0xc0fb, 0x0068,
- 0xa87c, 0xd0ac, 0x0904, 0xc0c6, 0xa838, 0xa934, 0x9105, 0x0904,
- 0xc0c6, 0xa880, 0xd0bc, 0x1904, 0xc0c6, 0x080c, 0xcf62, 0x0804,
- 0xc0ea, 0x00f6, 0x2079, 0x026c, 0x7c04, 0x7b00, 0x7e0c, 0x7d08,
- 0x00fe, 0x0021, 0x0005, 0x0011, 0x0005, 0x0005, 0x0096, 0x6003,
- 0x0002, 0x6007, 0x0043, 0x6014, 0x2048, 0xa87c, 0xd0ac, 0x0128,
- 0x009e, 0x0005, 0x2130, 0x2228, 0x0058, 0x2400, 0xa9ac, 0x910a,
- 0x2300, 0xaab0, 0x9213, 0x2600, 0x9102, 0x2500, 0x9203, 0x0e90,
- 0xac46, 0xab4a, 0xae36, 0xad3a, 0x6044, 0xd0fc, 0x190c, 0xab09,
- 0x604b, 0x0000, 0x080c, 0x1cbd, 0x1118, 0x6144, 0x080c, 0x9454,
- 0x009e, 0x0005, 0x9182, 0x0057, 0x1220, 0x9182, 0x0040, 0x0208,
- 0x000a, 0x0005, 0xc1f9, 0xc1f9, 0xc1f9, 0xc1f9, 0xc1f9, 0xc1f9,
- 0xc1f9, 0xc1f9, 0xc1f9, 0xc1f9, 0xc1fb, 0xc1f9, 0xc1f9, 0xc1f9,
- 0xc1f9, 0xc20c, 0xc1f9, 0xc1f9, 0xc1f9, 0xc1f9, 0xc230, 0xc1f9,
- 0xc1f9, 0x080c, 0x0d85, 0x6004, 0x9086, 0x0040, 0x1110, 0x080c,
- 0x97fe, 0x2019, 0x0001, 0x080c, 0xa380, 0x6003, 0x0002, 0x080c,
- 0xd35b, 0x080c, 0x9859, 0x0005, 0x6004, 0x9086, 0x0040, 0x1110,
- 0x080c, 0x97fe, 0x2019, 0x0001, 0x080c, 0xa380, 0x080c, 0x9859,
- 0x080c, 0x3310, 0x080c, 0xd353, 0x0096, 0x6114, 0x2148, 0x080c,
- 0xcc16, 0x0150, 0xa867, 0x0103, 0xa87b, 0x0029, 0xa877, 0x0000,
- 0x080c, 0x6f19, 0x080c, 0xce07, 0x009e, 0x080c, 0xaf2e, 0x0005,
- 0x080c, 0x0d85, 0xa87b, 0x0015, 0xd1fc, 0x0180, 0xa87b, 0x0007,
- 0x8002, 0x8000, 0x810a, 0x9189, 0x0000, 0x0006, 0x0016, 0x2009,
- 0x1a7d, 0x2104, 0x8000, 0x200a, 0x001e, 0x000e, 0xa992, 0xa88e,
- 0x0005, 0x9182, 0x0057, 0x1220, 0x9182, 0x0040, 0x0208, 0x000a,
- 0x0005, 0xc268, 0xc268, 0xc268, 0xc268, 0xc268, 0xc26a, 0xc268,
- 0xc268, 0xc327, 0xc268, 0xc268, 0xc268, 0xc268, 0xc268, 0xc268,
- 0xc268, 0xc268, 0xc268, 0xc268, 0xc467, 0xc268, 0xc471, 0xc268,
- 0x080c, 0x0d85, 0x601c, 0xd0bc, 0x0178, 0xd084, 0x0168, 0xd0f4,
- 0x0120, 0xc084, 0x601e, 0x0804, 0xc05a, 0x6114, 0x0096, 0x2148,
- 0xa87c, 0xc0e5, 0xa87e, 0x009e, 0x0076, 0x00a6, 0x00e6, 0x0096,
- 0x2071, 0x0260, 0x6114, 0x2150, 0x601c, 0xd0fc, 0x1110, 0x7644,
- 0x0008, 0x9036, 0xb676, 0x96b4, 0x0fff, 0xb77c, 0xc7e5, 0xb77e,
- 0x6210, 0x00b6, 0x2258, 0xba3c, 0x82ff, 0x0110, 0x8211, 0xba3e,
- 0x00be, 0x86ff, 0x0904, 0xc320, 0x9694, 0xff00, 0x9284, 0x0c00,
- 0x0120, 0x7048, 0xb092, 0x704c, 0xb08e, 0x9284, 0x0300, 0x0904,
- 0xc320, 0x9686, 0x0100, 0x1130, 0x7064, 0x9005, 0x1118, 0xc6c4,
- 0xb676, 0x0c38, 0x080c, 0x1059, 0x090c, 0x0d85, 0x2900, 0xb07a,
- 0xb77c, 0x97bd, 0x0200, 0xb77e, 0xa867, 0x0103, 0xb068, 0xa86a,
- 0xb06c, 0xa86e, 0xb070, 0xa872, 0x7044, 0x9084, 0xf000, 0x9635,
- 0xae76, 0x968c, 0x0c00, 0x0120, 0x7348, 0xab92, 0x734c, 0xab8e,
- 0x968c, 0x00ff, 0x9186, 0x0002, 0x0180, 0x9186, 0x0028, 0x1118,
- 0xa87b, 0x001c, 0x0060, 0xd6dc, 0x0118, 0xa87b, 0x0015, 0x0038,
- 0xd6d4, 0x0118, 0xa87b, 0x0007, 0x0010, 0xa87b, 0x0000, 0xaf7e,
- 0xb080, 0xa882, 0xb084, 0xa886, 0x901e, 0xd6c4, 0x0190, 0x735c,
- 0xab86, 0x83ff, 0x0170, 0x938a, 0x0009, 0x0210, 0x2019, 0x0008,
- 0x0036, 0x2308, 0x2019, 0x0018, 0x2011, 0x0025, 0x080c, 0xc794,
- 0x003e, 0xd6cc, 0x01e8, 0x7154, 0xa98a, 0x81ff, 0x01c8, 0x9192,
- 0x0021, 0x1260, 0x8304, 0x9098, 0x0018, 0x2011, 0x0029, 0x080c,
- 0xc794, 0x2011, 0x0205, 0x2013, 0x0000, 0x0050, 0xb068, 0xd0fc,
- 0x0120, 0x2009, 0x0020, 0xa98a, 0x0c68, 0x2950, 0x080c, 0xc733,
- 0x080c, 0x1ac8, 0x009e, 0x00ee, 0x00ae, 0x007e, 0x0005, 0x2001,
- 0x1989, 0x2004, 0x604a, 0x0096, 0x6114, 0x2148, 0xa83c, 0xa940,
- 0x9105, 0x1118, 0xa87c, 0xc0dc, 0xa87e, 0x6003, 0x0002, 0x080c,
- 0xd364, 0x0904, 0xc462, 0x604b, 0x0000, 0x6010, 0x00b6, 0x2058,
- 0xb800, 0x00be, 0xd0bc, 0x1500, 0xd1cc, 0x0904, 0xc426, 0xa978,
- 0xa868, 0xd0fc, 0x0904, 0xc3e7, 0x0016, 0xa87c, 0x0006, 0xa880,
- 0x0006, 0x00a6, 0x2150, 0xb174, 0x9184, 0x00ff, 0x90b6, 0x0002,
- 0x0904, 0xc3b4, 0x9086, 0x0028, 0x1904, 0xc3a0, 0xa87b, 0x001c,
- 0xb07b, 0x001c, 0x0804, 0xc3bc, 0x6024, 0xd0f4, 0x11d0, 0xa838,
- 0xaa34, 0x9205, 0x09c8, 0xa838, 0xaa90, 0x9206, 0x1120, 0xa88c,
- 0xaa34, 0x9206, 0x0988, 0x6024, 0xd0d4, 0x1148, 0xa9ac, 0xa834,
- 0x9102, 0x603a, 0xa9b0, 0xa838, 0x9103, 0x603e, 0x6024, 0xc0f5,
- 0x6026, 0x6010, 0x00b6, 0x2058, 0xb83c, 0x8000, 0xb83e, 0x00be,
- 0x601c, 0xc0fc, 0x601e, 0x9006, 0xa876, 0xa892, 0xa88e, 0xa87c,
- 0xc0e4, 0xa87e, 0xd0cc, 0x0140, 0xc0cc, 0xa87e, 0x0096, 0xa878,
- 0x2048, 0x080c, 0x100b, 0x009e, 0x080c, 0xcf62, 0x0804, 0xc462,
- 0xd1dc, 0x0158, 0xa87b, 0x0015, 0xb07b, 0x0015, 0x080c, 0xd203,
- 0x0118, 0xb174, 0xc1dc, 0xb176, 0x0078, 0xd1d4, 0x0128, 0xa87b,
- 0x0007, 0xb07b, 0x0007, 0x0040, 0xa87c, 0xd0ac, 0x0128, 0xa834,
- 0xa938, 0x9115, 0x190c, 0xc232, 0xa87c, 0xb07e, 0xa890, 0xb092,
- 0xa88c, 0xb08e, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0019, 0x20a0,
- 0x20a9, 0x0020, 0x8a06, 0x8006, 0x8007, 0x9094, 0x003f, 0x22e0,
- 0x9084, 0xffc0, 0x9080, 0x0019, 0x2098, 0x4003, 0x00ae, 0x000e,
- 0xa882, 0x000e, 0xc0cc, 0xa87e, 0x080c, 0xd2e3, 0x001e, 0xa874,
- 0x0006, 0x2148, 0x080c, 0x100b, 0x001e, 0x0804, 0xc453, 0x0016,
- 0x00a6, 0x2150, 0xb174, 0x9184, 0x00ff, 0x90b6, 0x0002, 0x01e0,
- 0x9086, 0x0028, 0x1128, 0xa87b, 0x001c, 0xb07b, 0x001c, 0x00e0,
- 0xd1dc, 0x0158, 0xa87b, 0x0015, 0xb07b, 0x0015, 0x080c, 0xd203,
- 0x0118, 0xb174, 0xc1dc, 0xb176, 0x0078, 0xd1d4, 0x0128, 0xa87b,
- 0x0007, 0xb07b, 0x0007, 0x0040, 0xa87c, 0xd0ac, 0x0128, 0xa834,
- 0xa938, 0x9115, 0x190c, 0xc232, 0xa890, 0xb092, 0xa88c, 0xb08e,
- 0xa87c, 0xb07e, 0x00ae, 0x080c, 0x100b, 0x009e, 0x080c, 0xd2e3,
- 0xa974, 0x0016, 0x080c, 0xc784, 0x001e, 0x0468, 0xa867, 0x0103,
- 0xa974, 0x9184, 0x00ff, 0x90b6, 0x0002, 0x01b0, 0x9086, 0x0028,
- 0x1118, 0xa87b, 0x001c, 0x00d0, 0xd1dc, 0x0148, 0xa87b, 0x0015,
- 0x080c, 0xd203, 0x0118, 0xa974, 0xc1dc, 0xa976, 0x0078, 0xd1d4,
- 0x0118, 0xa87b, 0x0007, 0x0050, 0xa87b, 0x0000, 0xa87c, 0xd0ac,
- 0x0128, 0xa834, 0xa938, 0x9115, 0x190c, 0xc232, 0xa974, 0x0016,
- 0x080c, 0x6d2e, 0x001e, 0x6010, 0x00b6, 0x2058, 0xba3c, 0xb8d0,
- 0x0016, 0x9005, 0x190c, 0x68b4, 0x001e, 0x00be, 0xd1e4, 0x1120,
- 0x080c, 0xaf2e, 0x009e, 0x0005, 0x080c, 0xcf25, 0x0cd8, 0x6114,
- 0x0096, 0x2148, 0xa97c, 0x080c, 0xd364, 0x190c, 0x1ae8, 0x009e,
- 0x0005, 0x0096, 0x6114, 0x2148, 0xa83c, 0xa940, 0x9105, 0x01e8,
- 0xa877, 0x0000, 0xa87b, 0x0000, 0xa867, 0x0103, 0x00b6, 0x6010,
- 0x2058, 0xa834, 0xa938, 0x9115, 0x11a0, 0x080c, 0x6d2e, 0xba3c,
- 0x8211, 0x0208, 0xba3e, 0xb8d0, 0x9005, 0x0110, 0x080c, 0x68b4,
- 0x080c, 0xaf2e, 0x00be, 0x009e, 0x0005, 0xa87c, 0xc0dc, 0xa87e,
- 0x08f8, 0xb800, 0xd0bc, 0x1120, 0xa834, 0x080c, 0xc232, 0x0c28,
- 0xa880, 0xd0bc, 0x1dc8, 0x080c, 0xcf62, 0x0c60, 0x080c, 0x97fe,
- 0x0010, 0x080c, 0x9859, 0x601c, 0xd084, 0x0110, 0x080c, 0x1afc,
- 0x080c, 0xcc16, 0x01f0, 0x0096, 0x6114, 0x2148, 0x080c, 0xce2d,
- 0x1118, 0x080c, 0xb91f, 0x00a0, 0xa867, 0x0103, 0x2009, 0x180c,
- 0x210c, 0xd18c, 0x1198, 0xd184, 0x1170, 0x6108, 0xa97a, 0x918e,
- 0x0029, 0x1110, 0x080c, 0xea83, 0xa877, 0x0000, 0x080c, 0x6f19,
- 0x009e, 0x0804, 0xaf69, 0xa87b, 0x0004, 0x0cb0, 0xa87b, 0x0004,
- 0x0c98, 0x9182, 0x0057, 0x1220, 0x9182, 0x0040, 0x0208, 0x000a,
- 0x0005, 0xc4f8, 0xc4f8, 0xc4f8, 0xc4f8, 0xc4f8, 0xc4fa, 0xc4f8,
- 0xc4f8, 0xc4f8, 0xc4f8, 0xc4f8, 0xc4f8, 0xc4f8, 0xc4f8, 0xc4f8,
- 0xc4f8, 0xc4f8, 0xc4f8, 0xc4f8, 0xc4f8, 0xc51e, 0xc4f8, 0xc4f8,
- 0x080c, 0x0d85, 0x080c, 0x582e, 0x01f8, 0x6014, 0x7144, 0x918c,
- 0x0fff, 0x9016, 0xd1c4, 0x0118, 0x7264, 0x9294, 0x00ff, 0x0096,
- 0x904d, 0x0188, 0xa87b, 0x0000, 0xa864, 0x9086, 0x0139, 0x0128,
- 0xa867, 0x0103, 0xa976, 0xaa96, 0x0030, 0xa897, 0x4000, 0xa99a,
- 0xaa9e, 0x080c, 0x6f19, 0x009e, 0x0804, 0xaf2e, 0x080c, 0x582e,
- 0x0dd8, 0x6014, 0x900e, 0x9016, 0x0c10, 0x9182, 0x0085, 0x0002,
- 0xc537, 0xc535, 0xc535, 0xc543, 0xc535, 0xc535, 0xc535, 0xc535,
- 0xc535, 0xc535, 0xc535, 0xc535, 0xc535, 0x080c, 0x0d85, 0x6003,
- 0x0001, 0x6106, 0x0126, 0x2091, 0x8000, 0x2009, 0x8020, 0x080c,
- 0x9428, 0x012e, 0x0005, 0x0026, 0x0056, 0x00d6, 0x00e6, 0x2071,
- 0x0260, 0x7224, 0x6216, 0x7220, 0x080c, 0xcc04, 0x01f8, 0x2268,
- 0x6800, 0x9086, 0x0000, 0x01d0, 0x6010, 0x6d10, 0x952e, 0x11b0,
- 0x00c6, 0x2d60, 0x00d6, 0x080c, 0xc7f5, 0x00de, 0x00ce, 0x0158,
- 0x702c, 0xd084, 0x1118, 0x080c, 0xc7bf, 0x0010, 0x6803, 0x0002,
- 0x6007, 0x0086, 0x0028, 0x080c, 0xc7e1, 0x0d90, 0x6007, 0x0087,
- 0x6003, 0x0001, 0x2009, 0x8020, 0x080c, 0x9428, 0x7220, 0x080c,
- 0xcc04, 0x0178, 0x6810, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc,
- 0x0140, 0x6824, 0xd0ec, 0x0128, 0x00c6, 0x2d60, 0x080c, 0xcf62,
- 0x00ce, 0x00ee, 0x00de, 0x005e, 0x002e, 0x0005, 0x9186, 0x0013,
- 0x1160, 0x6004, 0x908a, 0x0085, 0x0a0c, 0x0d85, 0x908a, 0x0092,
- 0x1a0c, 0x0d85, 0x9082, 0x0085, 0x00e2, 0x9186, 0x0027, 0x0120,
- 0x9186, 0x0014, 0x190c, 0x0d85, 0x080c, 0x97fe, 0x0096, 0x6014,
- 0x2048, 0x080c, 0xcc16, 0x0140, 0xa867, 0x0103, 0xa877, 0x0000,
- 0xa87b, 0x0029, 0x080c, 0x6f19, 0x009e, 0x080c, 0xaf69, 0x0804,
- 0x98bf, 0xc5c6, 0xc5c8, 0xc5c8, 0xc5c6, 0xc5c6, 0xc5c6, 0xc5c6,
- 0xc5c6, 0xc5c6, 0xc5c6, 0xc5c6, 0xc5c6, 0xc5c6, 0x080c, 0x0d85,
- 0x080c, 0xaf69, 0x0005, 0x9186, 0x0013, 0x1130, 0x6004, 0x9082,
- 0x0085, 0x2008, 0x0804, 0xc617, 0x9186, 0x0027, 0x1558, 0x080c,
- 0x97fe, 0x080c, 0x3310, 0x080c, 0xd353, 0x0096, 0x6014, 0x2048,
- 0x080c, 0xcc16, 0x0150, 0xa867, 0x0103, 0xa877, 0x0000, 0xa87b,
- 0x0029, 0x080c, 0x6f19, 0x080c, 0xce07, 0x009e, 0x080c, 0xaf2e,
- 0x0005, 0x9186, 0x0089, 0x0118, 0x9186, 0x008a, 0x1140, 0x080c,
- 0xad2d, 0x0128, 0x9086, 0x000c, 0x0904, 0xc64f, 0x0000, 0x080c,
- 0xafe9, 0x0c70, 0x9186, 0x0014, 0x1d60, 0x080c, 0x97fe, 0x0096,
- 0x6014, 0x2048, 0x080c, 0xcc16, 0x0d00, 0xa867, 0x0103, 0xa877,
- 0x0000, 0xa87b, 0x0006, 0xa880, 0xc0ec, 0xa882, 0x0890, 0x0002,
- 0xc627, 0xc625, 0xc625, 0xc625, 0xc625, 0xc625, 0xc63b, 0xc625,
- 0xc625, 0xc625, 0xc625, 0xc625, 0xc625, 0x080c, 0x0d85, 0x6034,
- 0x908c, 0xff00, 0x810f, 0x9186, 0x0039, 0x0118, 0x9186, 0x0035,
- 0x1118, 0x2001, 0x1987, 0x0010, 0x2001, 0x1988, 0x2004, 0x601a,
- 0x6003, 0x000c, 0x0005, 0x6034, 0x908c, 0xff00, 0x810f, 0x9186,
- 0x0039, 0x0118, 0x9186, 0x0035, 0x1118, 0x2001, 0x1987, 0x0010,
- 0x2001, 0x1988, 0x2004, 0x601a, 0x6003, 0x000e, 0x0005, 0x9182,
- 0x0092, 0x1220, 0x9182, 0x0085, 0x0208, 0x0012, 0x0804, 0xafe9,
- 0xc665, 0xc665, 0xc665, 0xc665, 0xc667, 0xc6b4, 0xc665, 0xc665,
- 0xc665, 0xc665, 0xc665, 0xc665, 0xc665, 0x080c, 0x0d85, 0x0096,
- 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x0168, 0x6034,
- 0x908c, 0xff00, 0x810f, 0x9186, 0x0039, 0x0118, 0x9186, 0x0035,
- 0x1118, 0x009e, 0x0804, 0xc6c8, 0x080c, 0xcc16, 0x1118, 0x080c,
- 0xce07, 0x0068, 0x6014, 0x2048, 0x080c, 0xd36a, 0x1110, 0x080c,
- 0xce07, 0xa867, 0x0103, 0x080c, 0xd31e, 0x080c, 0x6f19, 0x00d6,
- 0x2c68, 0x080c, 0xaed8, 0x01d0, 0x6003, 0x0001, 0x6007, 0x001e,
- 0x600b, 0xffff, 0x2009, 0x026e, 0x210c, 0x613a, 0x2009, 0x026f,
- 0x210c, 0x613e, 0x6910, 0x6112, 0x080c, 0xd0b1, 0x695c, 0x615e,
- 0x6023, 0x0001, 0x2009, 0x8020, 0x080c, 0x9428, 0x2d60, 0x00de,
- 0x080c, 0xaf2e, 0x009e, 0x0005, 0x6010, 0x00b6, 0x2058, 0xb800,
- 0x00be, 0xd0bc, 0x05a0, 0x6034, 0x908c, 0xff00, 0x810f, 0x9186,
- 0x0035, 0x0130, 0x9186, 0x001e, 0x0118, 0x9186, 0x0039, 0x1538,
- 0x00d6, 0x2c68, 0x080c, 0xd2b6, 0x11f0, 0x080c, 0xaed8, 0x01d8,
- 0x6106, 0x6003, 0x0001, 0x6023, 0x0001, 0x6910, 0x6112, 0x692c,
- 0x612e, 0x6930, 0x6132, 0x6934, 0x918c, 0x00ff, 0x6136, 0x6938,
- 0x613a, 0x693c, 0x613e, 0x695c, 0x615e, 0x080c, 0xd0b1, 0x2009,
- 0x8020, 0x080c, 0x9428, 0x2d60, 0x00de, 0x0804, 0xaf2e, 0x0096,
- 0x6014, 0x2048, 0x080c, 0xcc16, 0x01c8, 0xa867, 0x0103, 0xa880,
- 0xd0b4, 0x0128, 0xc0ec, 0xa882, 0xa87b, 0x0006, 0x0048, 0xd0bc,
- 0x0118, 0xa87b, 0x0002, 0x0020, 0xa87b, 0x0005, 0x080c, 0xcf21,
- 0xa877, 0x0000, 0x080c, 0x6f19, 0x080c, 0xce07, 0x009e, 0x0804,
- 0xaf2e, 0x0016, 0x0096, 0x6014, 0x2048, 0x080c, 0xcc16, 0x0140,
- 0xa867, 0x0103, 0xa87b, 0x0028, 0xa877, 0x0000, 0x080c, 0x6f19,
- 0x009e, 0x001e, 0x9186, 0x0013, 0x0158, 0x9186, 0x0014, 0x0130,
- 0x9186, 0x0027, 0x0118, 0x080c, 0xafe9, 0x0020, 0x080c, 0x97fe,
- 0x080c, 0xaf69, 0x0005, 0x0056, 0x0066, 0x0096, 0x00a6, 0x2029,
- 0x0001, 0x9182, 0x0101, 0x1208, 0x0010, 0x2009, 0x0100, 0x2130,
- 0x8304, 0x9098, 0x0018, 0x2009, 0x0020, 0x2011, 0x0029, 0x080c,
- 0xc794, 0x96b2, 0x0020, 0xb004, 0x904d, 0x0110, 0x080c, 0x100b,
- 0x080c, 0x1059, 0x0520, 0x8528, 0xa867, 0x0110, 0xa86b, 0x0000,
- 0x2920, 0xb406, 0x968a, 0x003d, 0x1228, 0x2608, 0x2011, 0x001b,
- 0x0499, 0x00a8, 0x96b2, 0x003c, 0x2009, 0x003c, 0x2950, 0x2011,
- 0x001b, 0x0451, 0x0c28, 0x2001, 0x0205, 0x2003, 0x0000, 0x00ae,
- 0x852f, 0x95ad, 0x0003, 0xb566, 0x95ac, 0x0000, 0x0048, 0x2001,
- 0x0205, 0x2003, 0x0000, 0x00ae, 0x852f, 0x95ad, 0x0003, 0xb566,
- 0x009e, 0x006e, 0x005e, 0x0005, 0x00a6, 0x89ff, 0x0158, 0xa804,
- 0x9055, 0x0130, 0xa807, 0x0000, 0x080c, 0x6f19, 0x2a48, 0x0cb8,
- 0x080c, 0x6f19, 0x00ae, 0x0005, 0x00f6, 0x2079, 0x0200, 0x7814,
- 0x9085, 0x0080, 0x7816, 0xd184, 0x0108, 0x8108, 0x810c, 0x20a9,
- 0x0001, 0xa860, 0x20e8, 0xa85c, 0x9200, 0x20a0, 0x20e1, 0x0000,
- 0x2300, 0x9e00, 0x2098, 0x4003, 0x8318, 0x9386, 0x0020, 0x1148,
- 0x2018, 0x2300, 0x9e00, 0x2098, 0x7814, 0x8000, 0x9085, 0x0080,
- 0x7816, 0x8109, 0x1d80, 0x7817, 0x0000, 0x00fe, 0x0005, 0x6920,
- 0x9186, 0x0003, 0x0118, 0x9186, 0x0002, 0x11d0, 0x00c6, 0x00d6,
- 0x00e6, 0x2d60, 0x0096, 0x6014, 0x2048, 0x080c, 0xcc16, 0x0150,
- 0x2001, 0x0006, 0xa980, 0xc1d5, 0x080c, 0x7165, 0x080c, 0x6f0d,
- 0x080c, 0xce07, 0x009e, 0x080c, 0xaf69, 0x00ee, 0x00de, 0x00ce,
- 0x0005, 0x00c6, 0x702c, 0xd084, 0x1170, 0x6008, 0x2060, 0x6020,
- 0x9086, 0x0002, 0x1140, 0x6104, 0x9186, 0x0085, 0x0118, 0x9186,
- 0x008b, 0x1108, 0x9006, 0x00ce, 0x0005, 0x0066, 0x0126, 0x2091,
- 0x8000, 0x2031, 0x0001, 0x6020, 0x9084, 0x000f, 0x0083, 0x012e,
- 0x006e, 0x0005, 0x0126, 0x2091, 0x8000, 0x0066, 0x2031, 0x0000,
- 0x6020, 0x9084, 0x000f, 0x001b, 0x006e, 0x012e, 0x0005, 0xc847,
- 0xc847, 0xc842, 0xc86b, 0xc81f, 0xc842, 0xc821, 0xc842, 0xc81f,
- 0x92e7, 0xc842, 0xc842, 0xc842, 0xc81f, 0xc81f, 0xc81f, 0x080c,
- 0x0d85, 0x6010, 0x9080, 0x0000, 0x2004, 0xd0bc, 0x190c, 0xc86b,
- 0x0036, 0x6014, 0x0096, 0x2048, 0xa880, 0x009e, 0xd0cc, 0x0118,
- 0x2019, 0x000c, 0x0038, 0xd094, 0x0118, 0x2019, 0x000d, 0x0010,
- 0x2019, 0x0010, 0x080c, 0xe27a, 0x6023, 0x0006, 0x6003, 0x0007,
- 0x003e, 0x0005, 0x9006, 0x0005, 0x9085, 0x0001, 0x0005, 0x0096,
- 0x86ff, 0x11e8, 0x6014, 0x2048, 0x080c, 0xcc16, 0x01d0, 0x6043,
- 0xffff, 0xa864, 0x9086, 0x0139, 0x1128, 0xa87b, 0x0005, 0xa883,
- 0x0000, 0x0028, 0x900e, 0x2001, 0x0005, 0x080c, 0x7165, 0x080c,
- 0xcf21, 0x080c, 0x6f0d, 0x080c, 0xaf69, 0x9085, 0x0001, 0x009e,
- 0x0005, 0x9006, 0x0ce0, 0x080c, 0xaae0, 0x080c, 0xd378, 0x6000,
- 0x908a, 0x0016, 0x1a0c, 0x0d85, 0x002b, 0x0106, 0x080c, 0xaafc,
- 0x010e, 0x0005, 0xc88a, 0xc8ba, 0xc88c, 0xc8e1, 0xc8b5, 0xc88a,
- 0xc842, 0xc847, 0xc847, 0xc842, 0xc842, 0xc842, 0xc842, 0xc842,
- 0xc842, 0xc842, 0x080c, 0x0d85, 0x86ff, 0x1520, 0x6020, 0x9086,
- 0x0006, 0x0500, 0x0096, 0x6014, 0x2048, 0x080c, 0xcc16, 0x0168,
- 0xa87c, 0xd0cc, 0x0140, 0x0096, 0xc0cc, 0xa87e, 0xa878, 0x2048,
- 0x080c, 0x100b, 0x009e, 0x080c, 0xcf21, 0x009e, 0x080c, 0xd2f8,
- 0x6007, 0x0085, 0x6003, 0x000b, 0x6023, 0x0002, 0x2009, 0x8020,
- 0x080c, 0x940a, 0x9085, 0x0001, 0x0005, 0x0066, 0x080c, 0x1afc,
- 0x006e, 0x0890, 0x00e6, 0x2071, 0x19e9, 0x7030, 0x9c06, 0x1120,
- 0x080c, 0xa300, 0x00ee, 0x0840, 0x6020, 0x9084, 0x000f, 0x9086,
- 0x0006, 0x1150, 0x0086, 0x0096, 0x2049, 0x0001, 0x2c40, 0x080c,
- 0xa44b, 0x009e, 0x008e, 0x0040, 0x0066, 0x080c, 0xa1fc, 0x190c,
- 0x0d85, 0x080c, 0xa20a, 0x006e, 0x00ee, 0x1904, 0xc88c, 0x0804,
- 0xc842, 0x0036, 0x00e6, 0x2071, 0x19e9, 0x704c, 0x9c06, 0x1138,
- 0x901e, 0x080c, 0xa380, 0x00ee, 0x003e, 0x0804, 0xc88c, 0x080c,
- 0xa585, 0x00ee, 0x003e, 0x1904, 0xc88c, 0x0804, 0xc842, 0x00c6,
- 0x0066, 0x6020, 0x9084, 0x000f, 0x001b, 0x006e, 0x00ce, 0x0005,
- 0xc917, 0xc9e6, 0xcb50, 0xc91f, 0xaf69, 0xc917, 0xe26c, 0xd360,
- 0xc9e6, 0x92ae, 0xcbdc, 0xc910, 0xc910, 0xc910, 0xc910, 0xc910,
- 0x080c, 0x0d85, 0x080c, 0xce2d, 0x1110, 0x080c, 0xb91f, 0x0005,
- 0x080c, 0x97fe, 0x0804, 0xaf2e, 0x601b, 0x0001, 0x0005, 0x080c,
- 0xcc16, 0x0130, 0x6014, 0x0096, 0x2048, 0x2c00, 0xa896, 0x009e,
- 0x080c, 0xaae0, 0x080c, 0xd378, 0x6000, 0x908a, 0x0016, 0x1a0c,
- 0x0d85, 0x0013, 0x0804, 0xaafc, 0xc944, 0xc946, 0xc970, 0xc984,
- 0xc9b1, 0xc944, 0xc917, 0xc917, 0xc917, 0xc98b, 0xc98b, 0xc944,
- 0xc944, 0xc944, 0xc944, 0xc995, 0x080c, 0x0d85, 0x00e6, 0x6014,
- 0x0096, 0x2048, 0xa880, 0xc0b5, 0xa882, 0x009e, 0x2071, 0x19e9,
- 0x7030, 0x9c06, 0x01d0, 0x0066, 0x080c, 0xa1fc, 0x190c, 0x0d85,
- 0x080c, 0xa20a, 0x006e, 0x080c, 0xd2f8, 0x6007, 0x0085, 0x6003,
- 0x000b, 0x6023, 0x0002, 0x2001, 0x1988, 0x2004, 0x601a, 0x2009,
- 0x8020, 0x080c, 0x940a, 0x00ee, 0x0005, 0x601b, 0x0001, 0x0cd8,
- 0x0096, 0x6014, 0x2048, 0xa880, 0xc0b5, 0xa882, 0x009e, 0x080c,
- 0xd2f8, 0x6007, 0x0085, 0x6003, 0x000b, 0x6023, 0x0002, 0x2009,
- 0x8020, 0x080c, 0x940a, 0x0005, 0x080c, 0xaae0, 0x080c, 0xacaf,
- 0x080c, 0xaafc, 0x0c28, 0x0096, 0x601b, 0x0001, 0x6014, 0x2048,
- 0xa880, 0xc0b5, 0xa882, 0x009e, 0x0005, 0x080c, 0x582e, 0x01b8,
- 0x6014, 0x0096, 0x904d, 0x0190, 0xa864, 0xa867, 0x0103, 0xa87b,
- 0x0006, 0x9086, 0x0139, 0x1150, 0xa867, 0x0139, 0xa87b, 0x0030,
- 0xa897, 0x4005, 0xa89b, 0x0004, 0x080c, 0x6f19, 0x009e, 0x0804,
- 0xaf2e, 0x6014, 0x0096, 0x904d, 0x0560, 0xa97c, 0xd1e4, 0x1158,
- 0x611c, 0xd1fc, 0x0530, 0x6110, 0x00b6, 0x2158, 0xb93c, 0x8109,
- 0x0208, 0xb93e, 0x00be, 0x080c, 0xaafc, 0x2001, 0x180f, 0x2004,
- 0xd0c4, 0x0110, 0x009e, 0x0005, 0xa884, 0x009e, 0x8003, 0x800b,
- 0x810b, 0x9108, 0x611a, 0x2001, 0x0037, 0x2c08, 0x080c, 0x16b9,
- 0x6000, 0x9086, 0x0004, 0x1120, 0x2009, 0x0048, 0x080c, 0xafcc,
- 0x0005, 0x009e, 0x080c, 0x1afc, 0x0804, 0xc970, 0x6000, 0x908a,
- 0x0016, 0x1a0c, 0x0d85, 0x000b, 0x0005, 0xc9fd, 0xc91c, 0xc9ff,
- 0xc9fd, 0xc9ff, 0xc9ff, 0xc918, 0xc9fd, 0xc912, 0xc912, 0xc9fd,
- 0xc9fd, 0xc9fd, 0xc9fd, 0xc9fd, 0xc9fd, 0x080c, 0x0d85, 0x6010,
+ 0xb000, 0xb00a, 0xb025, 0xb040, 0xd3b0, 0xd3cd, 0xd3e8, 0xb000,
+ 0xb00a, 0x9191, 0xb059, 0xb000, 0xb000, 0xb000, 0xb000, 0xb000,
+ 0x9186, 0x0013, 0x1130, 0x6044, 0xd0fc, 0x0110, 0x080c, 0x97f6,
+ 0x0005, 0x0005, 0x0066, 0x6000, 0x90b2, 0x0010, 0x1a0c, 0x0d79,
+ 0x0013, 0x006e, 0x0005, 0xb023, 0xb79c, 0xb983, 0xb023, 0xba19,
+ 0xb322, 0xb023, 0xb023, 0xb71e, 0xbf8c, 0xb023, 0xb023, 0xb023,
+ 0xb023, 0xb023, 0xb023, 0x080c, 0x0d79, 0x0066, 0x6000, 0x90b2,
+ 0x0010, 0x1a0c, 0x0d79, 0x0013, 0x006e, 0x0005, 0xb03e, 0xc5a7,
+ 0xb03e, 0xb03e, 0xb03e, 0xb03e, 0xb03e, 0xb03e, 0xc53e, 0xc72a,
+ 0xb03e, 0xc5e4, 0xc668, 0xc5e4, 0xc668, 0xb03e, 0x080c, 0x0d79,
+ 0x6000, 0x9082, 0x0010, 0x1a0c, 0x0d79, 0x6000, 0x0002, 0xb057,
+ 0xbfd6, 0xc070, 0xc1f3, 0xc262, 0xb057, 0xb057, 0xb057, 0xbfa5,
+ 0xc4bf, 0xc4c2, 0xb057, 0xb057, 0xb057, 0xb057, 0xc4f2, 0x080c,
+ 0x0d79, 0x0066, 0x6000, 0x90b2, 0x0010, 0x1a0c, 0x0d79, 0x0013,
+ 0x006e, 0x0005, 0xb072, 0xb072, 0xb0b0, 0xb14f, 0xb1cf, 0xb072,
+ 0xb072, 0xb072, 0xb074, 0xb072, 0xb072, 0xb072, 0xb072, 0xb072,
+ 0xb072, 0xb072, 0x080c, 0x0d79, 0x9186, 0x004c, 0x0560, 0x9186,
+ 0x0003, 0x190c, 0x0d79, 0x0096, 0x601c, 0xc0ed, 0x601e, 0x6003,
+ 0x0003, 0x6106, 0x6014, 0x2048, 0xa87c, 0x9084, 0xa000, 0xc0b5,
+ 0xa87e, 0xa8ac, 0xa836, 0xa8b0, 0xa83a, 0x9006, 0xa846, 0xa84a,
+ 0xa884, 0x9092, 0x199a, 0x0210, 0x2001, 0x1999, 0x8003, 0x8013,
+ 0x8213, 0x9210, 0x621a, 0x009e, 0x080c, 0x1c43, 0x2009, 0x8030,
+ 0x080c, 0x9467, 0x0005, 0x6010, 0x00b6, 0x2058, 0xbca0, 0x00be,
+ 0x2c00, 0x080c, 0xb1f1, 0x080c, 0xd375, 0x6003, 0x0007, 0x0005,
+ 0x00d6, 0x0096, 0x00f6, 0x2079, 0x1800, 0x7a90, 0x6014, 0x2048,
+ 0xa87c, 0xd0ec, 0x1110, 0x9290, 0x0018, 0xac78, 0xc4fc, 0x0046,
+ 0xa8e0, 0x9005, 0x1140, 0xa8dc, 0x921a, 0x0140, 0x0220, 0xa87b,
+ 0x0007, 0x2010, 0x0028, 0xa87b, 0x0015, 0x0010, 0xa87b, 0x0000,
+ 0x8214, 0xa883, 0x0000, 0xaa02, 0x0006, 0x0016, 0x0026, 0x00c6,
+ 0x00d6, 0x00e6, 0x00f6, 0x2400, 0x9005, 0x1108, 0x009a, 0x2100,
+ 0x9086, 0x0015, 0x1118, 0x2001, 0x0001, 0x0038, 0x2100, 0x9086,
+ 0x0016, 0x0118, 0x2001, 0x0001, 0x002a, 0x94a4, 0x0007, 0x8423,
+ 0x9405, 0x0002, 0xb117, 0xb117, 0xb112, 0xb115, 0xb117, 0xb10f,
+ 0xb102, 0xb102, 0xb102, 0xb102, 0xb102, 0xb102, 0xb102, 0xb102,
+ 0xb102, 0xb102, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x002e, 0x001e,
+ 0x000e, 0x004e, 0x00fe, 0x009e, 0x00de, 0x080c, 0x0d79, 0x080c,
+ 0xbbda, 0x0028, 0x080c, 0xbcc1, 0x0010, 0x080c, 0xbdb7, 0x00fe,
+ 0x00ee, 0x00de, 0x00ce, 0x002e, 0x001e, 0x2c00, 0xa896, 0x000e,
+ 0x080c, 0xb2af, 0x0530, 0xa804, 0xa80e, 0x00a6, 0x2050, 0xb100,
+ 0x00ae, 0x8006, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0,
+ 0x9080, 0x0002, 0xaacc, 0xabd0, 0xacd4, 0xadd8, 0x2031, 0x0000,
+ 0x2041, 0x12b6, 0x080c, 0xb473, 0x0160, 0x000e, 0x9005, 0x0120,
+ 0x00fe, 0x009e, 0x00de, 0x0005, 0x00fe, 0x009e, 0x00de, 0x0804,
+ 0xaf4e, 0x2001, 0x002c, 0x900e, 0x080c, 0xb315, 0x0c70, 0x91b6,
+ 0x0015, 0x0170, 0x91b6, 0x0016, 0x0158, 0x91b2, 0x0047, 0x0a0c,
+ 0x0d79, 0x91b2, 0x0050, 0x1a0c, 0x0d79, 0x9182, 0x0047, 0x0042,
+ 0x080c, 0xad4d, 0x0120, 0x9086, 0x0002, 0x0904, 0xb0b0, 0x0005,
+ 0xb171, 0xb171, 0xb173, 0xb1a5, 0xb171, 0xb171, 0xb171, 0xb171,
+ 0xb1b8, 0x080c, 0x0d79, 0x00d6, 0x0016, 0x0096, 0x6003, 0x0004,
+ 0x6114, 0x2148, 0xa87c, 0xd0fc, 0x01c0, 0xa878, 0xc0fc, 0x9005,
+ 0x1158, 0xa894, 0x9005, 0x0140, 0x2001, 0x0000, 0x900e, 0x080c,
+ 0xb315, 0x080c, 0xaf4e, 0x00a8, 0x6003, 0x0002, 0xa8a4, 0xa9a8,
+ 0x9105, 0x1178, 0xa8ae, 0xa8b2, 0x0c78, 0xa87f, 0x0020, 0xa88c,
+ 0xa88a, 0xa8a4, 0xa8ae, 0xa8a8, 0xa8b2, 0xa8c7, 0x0000, 0xa8cb,
+ 0x0000, 0x009e, 0x001e, 0x00de, 0x0005, 0x080c, 0x9851, 0x00d6,
+ 0x0096, 0x6114, 0x2148, 0x080c, 0xcc33, 0x0120, 0xa87b, 0x0006,
+ 0x080c, 0x6f11, 0x009e, 0x00de, 0x080c, 0xaf4e, 0x0804, 0x98bc,
+ 0x080c, 0x9851, 0x080c, 0x32fb, 0x080c, 0xd372, 0x00d6, 0x0096,
+ 0x6114, 0x2148, 0x080c, 0xcc33, 0x0120, 0xa87b, 0x0029, 0x080c,
+ 0x6f11, 0x009e, 0x00de, 0x080c, 0xaf4e, 0x0804, 0x98bc, 0x9182,
+ 0x0047, 0x0002, 0xb1df, 0xb1e1, 0xb1df, 0xb1df, 0xb1df, 0xb1df,
+ 0xb1df, 0xb1df, 0xb1df, 0xb1df, 0xb1df, 0xb1df, 0xb1e1, 0x080c,
+ 0x0d79, 0x00d6, 0x0096, 0x601f, 0x0000, 0x6114, 0x2148, 0xa87b,
+ 0x0000, 0xa883, 0x0000, 0x080c, 0x6f11, 0x009e, 0x00de, 0x0804,
+ 0xaf4e, 0x0026, 0x0036, 0x0056, 0x0066, 0x0096, 0x00a6, 0x00f6,
+ 0x0006, 0x080c, 0x104d, 0x000e, 0x090c, 0x0d79, 0xa960, 0x21e8,
+ 0xa95c, 0x9188, 0x0019, 0x21a0, 0x900e, 0x20a9, 0x0020, 0x4104,
+ 0xa87a, 0x2079, 0x1800, 0x7990, 0x9188, 0x0018, 0x918c, 0x0fff,
+ 0xa972, 0xac76, 0x2950, 0x00a6, 0x2001, 0x0205, 0x2003, 0x0000,
+ 0x901e, 0x2029, 0x0001, 0x9182, 0x0035, 0x1228, 0x2011, 0x001f,
+ 0x080c, 0xc7ad, 0x04c0, 0x2130, 0x2009, 0x0034, 0x2011, 0x001f,
+ 0x080c, 0xc7ad, 0x96b2, 0x0034, 0xb004, 0x904d, 0x0110, 0x080c,
+ 0x0fff, 0x080c, 0x104d, 0x01d0, 0x8528, 0xa867, 0x0110, 0xa86b,
+ 0x0000, 0x2920, 0xb406, 0x968a, 0x003d, 0x1230, 0x2608, 0x2011,
+ 0x001b, 0x080c, 0xc7ad, 0x00b8, 0x96b2, 0x003c, 0x2009, 0x003c,
+ 0x2950, 0x2011, 0x001b, 0x080c, 0xc7ad, 0x0c18, 0x2001, 0x0205,
+ 0x2003, 0x0000, 0x00ae, 0x852f, 0x95ad, 0x0050, 0xb566, 0xb070,
+ 0xc0fd, 0xb072, 0x0048, 0x2001, 0x0205, 0x2003, 0x0000, 0x00ae,
+ 0x852f, 0x95ad, 0x0050, 0xb566, 0x2a48, 0xa804, 0xa807, 0x0000,
+ 0x0006, 0x080c, 0x6f11, 0x000e, 0x2048, 0x9005, 0x1db0, 0x00fe,
+ 0x00ae, 0x009e, 0x006e, 0x005e, 0x003e, 0x002e, 0x0005, 0x00d6,
+ 0x00f6, 0x0096, 0x0006, 0x080c, 0x104d, 0x000e, 0x090c, 0x0d79,
+ 0xa960, 0x21e8, 0xa95c, 0x9188, 0x0019, 0x21a0, 0x900e, 0x20a9,
+ 0x0020, 0x4104, 0xaa66, 0xa87a, 0x2079, 0x1800, 0x7990, 0x810c,
+ 0x9188, 0x000c, 0x9182, 0x001a, 0x0210, 0x2009, 0x001a, 0x21a8,
+ 0x810b, 0xa972, 0xac76, 0x2e98, 0xa85c, 0x9080, 0x001f, 0x20a0,
+ 0x2001, 0x0205, 0x200c, 0x918d, 0x0080, 0x2102, 0x4003, 0x2003,
+ 0x0000, 0x080c, 0x6f11, 0x009e, 0x00fe, 0x00de, 0x0005, 0x0016,
+ 0x00d6, 0x00f6, 0x0096, 0x0016, 0x2001, 0x0205, 0x200c, 0x918d,
+ 0x0080, 0x2102, 0x001e, 0x2079, 0x0200, 0x2e98, 0xa87c, 0xd0ec,
+ 0x0118, 0x9e80, 0x000c, 0x2098, 0x2021, 0x003e, 0x901e, 0x9282,
+ 0x0020, 0x0218, 0x2011, 0x0020, 0x2018, 0x9486, 0x003e, 0x1170,
+ 0x0096, 0x080c, 0x104d, 0x2900, 0x009e, 0x05c0, 0xa806, 0x2048,
+ 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0002, 0x20a0, 0x3300, 0x908e,
+ 0x0260, 0x0140, 0x2009, 0x0280, 0x9102, 0x920a, 0x0218, 0x2010,
+ 0x2100, 0x9318, 0x2200, 0x9402, 0x1228, 0x2400, 0x9202, 0x2410,
+ 0x9318, 0x9006, 0x2020, 0x22a8, 0xa800, 0x9200, 0xa802, 0x20e1,
+ 0x0000, 0x4003, 0x83ff, 0x0180, 0x3300, 0x9086, 0x0280, 0x1130,
+ 0x7814, 0x8000, 0x9085, 0x0080, 0x7816, 0x2e98, 0x2310, 0x84ff,
+ 0x0904, 0xb2c4, 0x0804, 0xb2c6, 0x9085, 0x0001, 0x7817, 0x0000,
+ 0x009e, 0x00fe, 0x00de, 0x001e, 0x0005, 0x00d6, 0x0036, 0x0096,
+ 0x6314, 0x2348, 0xa87a, 0xa982, 0x080c, 0x6f05, 0x009e, 0x003e,
+ 0x00de, 0x0005, 0x91b6, 0x0015, 0x1118, 0x080c, 0xaf4e, 0x0030,
+ 0x91b6, 0x0016, 0x190c, 0x0d79, 0x080c, 0xaf4e, 0x0005, 0x20a9,
+ 0x000e, 0x20e1, 0x0000, 0x2e98, 0x6014, 0x0096, 0x2048, 0xa860,
+ 0x20e8, 0xa85c, 0x20a0, 0x009e, 0x4003, 0x9196, 0x0016, 0x01f0,
+ 0x0136, 0x9080, 0x001b, 0x20a0, 0x2011, 0x0006, 0x20a9, 0x0001,
+ 0x3418, 0x8318, 0x23a0, 0x4003, 0x3318, 0x8318, 0x2398, 0x8211,
+ 0x1db8, 0x2011, 0x0006, 0x013e, 0x20a0, 0x3318, 0x8318, 0x2398,
+ 0x4003, 0x3418, 0x8318, 0x23a0, 0x8211, 0x1db8, 0x0096, 0x080c,
+ 0xcc33, 0x0130, 0x6014, 0x2048, 0xa807, 0x0000, 0xa867, 0x0103,
+ 0x009e, 0x0804, 0xaf4e, 0x0096, 0x00d6, 0x0036, 0x7330, 0x9386,
+ 0x0200, 0x11a8, 0x6010, 0x00b6, 0x2058, 0xb8d7, 0x0000, 0x00be,
+ 0x6014, 0x9005, 0x0130, 0x2048, 0xa807, 0x0000, 0xa867, 0x0103,
+ 0xab32, 0x080c, 0xaf4e, 0x003e, 0x00de, 0x009e, 0x0005, 0x0011,
+ 0x1d48, 0x0cc8, 0x0006, 0x0016, 0x080c, 0xd35d, 0x0188, 0x6014,
+ 0x9005, 0x1170, 0x600b, 0x0003, 0x601b, 0x0000, 0x604b, 0x0000,
+ 0x2009, 0x0022, 0x080c, 0xb774, 0x9006, 0x001e, 0x000e, 0x0005,
+ 0x9085, 0x0001, 0x0cd0, 0x0096, 0x0016, 0x20a9, 0x0014, 0x9e80,
+ 0x000c, 0x20e1, 0x0000, 0x2098, 0x6014, 0x2048, 0xa860, 0x20e8,
+ 0xa85c, 0x9080, 0x0002, 0x20a0, 0x4003, 0x2001, 0x0205, 0x2003,
+ 0x0001, 0x2099, 0x0260, 0x20a9, 0x0016, 0x4003, 0x20a9, 0x000a,
+ 0xa804, 0x2048, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0002, 0x20a0,
+ 0x4003, 0x2001, 0x0205, 0x2003, 0x0002, 0x2099, 0x0260, 0x20a9,
+ 0x0020, 0x4003, 0x2003, 0x0000, 0x6014, 0x2048, 0xa800, 0x2048,
+ 0xa867, 0x0103, 0x080c, 0xaf4e, 0x001e, 0x009e, 0x0005, 0x0096,
+ 0x0016, 0x900e, 0x7030, 0x9086, 0x0100, 0x0140, 0x7038, 0x9084,
+ 0x00ff, 0x800c, 0x703c, 0x9084, 0x00ff, 0x8004, 0x9080, 0x0004,
+ 0x9108, 0x810b, 0x2011, 0x0002, 0x2019, 0x000c, 0x6014, 0x2048,
+ 0x080c, 0xc7ad, 0x080c, 0xcc33, 0x0140, 0x6014, 0x2048, 0xa807,
+ 0x0000, 0xa864, 0xa8e2, 0xa867, 0x0103, 0x080c, 0xaf4e, 0x001e,
+ 0x009e, 0x0005, 0x0016, 0x2009, 0x0000, 0x7030, 0x9086, 0x0200,
+ 0x0110, 0x2009, 0x0001, 0x0096, 0x6014, 0x904d, 0x090c, 0x0d79,
+ 0xa97a, 0x080c, 0x6f11, 0x009e, 0x080c, 0xaf4e, 0x001e, 0x0005,
+ 0x0016, 0x0096, 0x7030, 0x9086, 0x0100, 0x1118, 0x2009, 0x0004,
+ 0x0010, 0x7034, 0x800c, 0x810b, 0x2011, 0x000c, 0x2019, 0x000c,
+ 0x6014, 0x2048, 0xa804, 0x0096, 0x9005, 0x0108, 0x2048, 0x080c,
+ 0xc7ad, 0x009e, 0x080c, 0xcc33, 0x0148, 0xa804, 0x9005, 0x1158,
+ 0xa807, 0x0000, 0xa864, 0xa8e2, 0xa867, 0x0103, 0x080c, 0xaf4e,
+ 0x009e, 0x001e, 0x0005, 0x0086, 0x2040, 0xa030, 0x8007, 0x9086,
+ 0x0100, 0x1118, 0x080c, 0xb93c, 0x00e0, 0xa034, 0x8007, 0x800c,
+ 0x8806, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080,
+ 0x000c, 0xa87b, 0x0000, 0xa883, 0x0000, 0xa897, 0x4000, 0xaaa0,
+ 0xab9c, 0xaca8, 0xada4, 0x2031, 0x0000, 0x2041, 0x129c, 0x0019,
+ 0x0d08, 0x008e, 0x0898, 0x0096, 0x0006, 0x080c, 0x104d, 0x000e,
+ 0x01b0, 0xa8ab, 0x0dcb, 0xa876, 0x000e, 0xa8a2, 0x0006, 0xae6a,
+ 0x2800, 0xa89e, 0xa97a, 0xaf72, 0xaa8e, 0xab92, 0xac96, 0xad9a,
+ 0x0086, 0x2940, 0x080c, 0x1142, 0x008e, 0x9085, 0x0001, 0x009e,
+ 0x0005, 0x00e6, 0x00d6, 0x0026, 0x7008, 0x9084, 0x00ff, 0x6210,
+ 0x00b6, 0x2258, 0xba10, 0x00be, 0x9206, 0x1520, 0x700c, 0x6210,
+ 0x00b6, 0x2258, 0xba14, 0x00be, 0x9206, 0x11e0, 0x604b, 0x0000,
+ 0x2c68, 0x0016, 0x2009, 0x0035, 0x080c, 0xd2d3, 0x001e, 0x1158,
+ 0x622c, 0x2268, 0x2071, 0x026c, 0x6b20, 0x9386, 0x0003, 0x0130,
+ 0x9386, 0x0006, 0x0128, 0x080c, 0xaf4e, 0x0020, 0x0039, 0x0010,
+ 0x080c, 0xb5a9, 0x002e, 0x00de, 0x00ee, 0x0005, 0x0096, 0x6814,
+ 0x2048, 0x9186, 0x0015, 0x0904, 0xb588, 0x918e, 0x0016, 0x1904,
+ 0xb5a7, 0x700c, 0x908c, 0xff00, 0x9186, 0x1700, 0x0120, 0x9186,
+ 0x0300, 0x1904, 0xb562, 0x89ff, 0x1138, 0x6800, 0x9086, 0x000f,
+ 0x0904, 0xb544, 0x0804, 0xb5a5, 0x6808, 0x9086, 0xffff, 0x1904,
+ 0xb58a, 0xa87c, 0x9084, 0x0060, 0x9086, 0x0020, 0x1150, 0xa8ac,
+ 0xa934, 0x9106, 0x1904, 0xb58a, 0xa8b0, 0xa938, 0x9106, 0x1904,
+ 0xb58a, 0x6824, 0xd084, 0x1904, 0xb58a, 0xd0b4, 0x0158, 0x0016,
+ 0x2001, 0x1987, 0x200c, 0x6018, 0x9102, 0x9082, 0x0005, 0x001e,
+ 0x1a04, 0xb58a, 0x080c, 0xce24, 0x6810, 0x0096, 0x2048, 0xa9a0,
+ 0x009e, 0x685c, 0xa87a, 0xa976, 0x6864, 0xa882, 0xa87c, 0xc0dc,
+ 0xc0f4, 0xc0d4, 0xa87e, 0x0026, 0x900e, 0x6a18, 0x2001, 0x000a,
+ 0x080c, 0x9364, 0xa884, 0x920a, 0x0208, 0x8011, 0xaa86, 0x82ff,
+ 0x002e, 0x1138, 0x00c6, 0x2d60, 0x080c, 0xc938, 0x00ce, 0x0804,
+ 0xb5a5, 0x00c6, 0xa868, 0xd0fc, 0x1118, 0x080c, 0x620a, 0x0010,
+ 0x080c, 0x6615, 0x00ce, 0x1904, 0xb58a, 0x00c6, 0x2d60, 0x080c,
+ 0xaf4e, 0x00ce, 0x0804, 0xb5a5, 0x00c6, 0x080c, 0xafbf, 0x0198,
+ 0x6017, 0x0000, 0x6810, 0x6012, 0x080c, 0xd0ce, 0x6023, 0x0003,
+ 0x6904, 0x00c6, 0x2d60, 0x080c, 0xaf4e, 0x00ce, 0x080c, 0xafec,
+ 0x00ce, 0x0804, 0xb5a5, 0x2001, 0x1989, 0x2004, 0x684a, 0x00ce,
+ 0x0804, 0xb5a5, 0x7008, 0x9086, 0x000b, 0x11c8, 0x6010, 0x00b6,
+ 0x2058, 0xb900, 0xc1bc, 0xb902, 0x00be, 0x00c6, 0x2d60, 0xa87b,
+ 0x0003, 0x080c, 0xd317, 0x6007, 0x0085, 0x6003, 0x000b, 0x6023,
+ 0x0002, 0x2009, 0x8020, 0x080c, 0x9420, 0x00ce, 0x0430, 0x700c,
+ 0x9086, 0x2a00, 0x1138, 0x2001, 0x1989, 0x2004, 0x684a, 0x00e8,
+ 0x04c1, 0x00e8, 0x89ff, 0x090c, 0x0d79, 0x00c6, 0x00d6, 0x2d60,
+ 0xa867, 0x0103, 0xa87b, 0x0003, 0x080c, 0x6d26, 0x080c, 0xce24,
+ 0x080c, 0xaf89, 0x0026, 0x6010, 0x00b6, 0x2058, 0xba3c, 0x080c,
+ 0x68ae, 0x00be, 0x002e, 0x00de, 0x00ce, 0x080c, 0xaf4e, 0x009e,
+ 0x0005, 0x9186, 0x0015, 0x1128, 0x2001, 0x1989, 0x2004, 0x684a,
+ 0x0068, 0x918e, 0x0016, 0x1160, 0x00c6, 0x2d00, 0x2060, 0x080c,
+ 0xe9f0, 0x080c, 0x8ab2, 0x080c, 0xaf4e, 0x00ce, 0x080c, 0xaf4e,
+ 0x0005, 0x0026, 0x0036, 0x0046, 0x7228, 0xacb0, 0xabac, 0xd2f4,
+ 0x0130, 0x2001, 0x1989, 0x2004, 0x684a, 0x0804, 0xb623, 0x00c6,
+ 0x2d60, 0x080c, 0xc80e, 0x00ce, 0x6804, 0x9086, 0x0050, 0x1168,
+ 0x00c6, 0x2d00, 0x2060, 0x6003, 0x0001, 0x6007, 0x0050, 0x2009,
+ 0x8023, 0x080c, 0x9420, 0x00ce, 0x04f0, 0x6800, 0x9086, 0x000f,
+ 0x01a8, 0x89ff, 0x090c, 0x0d79, 0x6800, 0x9086, 0x0004, 0x1190,
+ 0xa87c, 0xd0ac, 0x0178, 0xa843, 0x0fff, 0xa83f, 0x0fff, 0xa880,
+ 0xc0fc, 0xa882, 0x2001, 0x0001, 0x6832, 0x0400, 0x2001, 0x0007,
+ 0x6832, 0x00e0, 0xa87c, 0xd0b4, 0x1150, 0xd0ac, 0x0db8, 0x6824,
+ 0xd0f4, 0x1d48, 0xa838, 0xa934, 0x9105, 0x0d80, 0x0c20, 0xd2ec,
+ 0x1d68, 0x7024, 0x9306, 0x1118, 0x7020, 0x9406, 0x0d38, 0x7020,
+ 0x683e, 0x7024, 0x683a, 0x2001, 0x0005, 0x6832, 0x080c, 0xcfb8,
+ 0x080c, 0x98bc, 0x0010, 0x080c, 0xaf4e, 0x004e, 0x003e, 0x002e,
+ 0x0005, 0x00e6, 0x00d6, 0x0026, 0x7008, 0x9084, 0x00ff, 0x6210,
+ 0x00b6, 0x2258, 0xba10, 0x00be, 0x9206, 0x1904, 0xb68e, 0x700c,
+ 0x6210, 0x00b6, 0x2258, 0xba14, 0x00be, 0x9206, 0x1904, 0xb68e,
+ 0x6038, 0x2068, 0x6824, 0xc0dc, 0x6826, 0x6a20, 0x9286, 0x0007,
+ 0x0904, 0xb68e, 0x9286, 0x0002, 0x0904, 0xb68e, 0x9286, 0x0000,
+ 0x05e8, 0x6808, 0x633c, 0x9306, 0x15c8, 0x2071, 0x026c, 0x9186,
+ 0x0015, 0x0570, 0x918e, 0x0016, 0x1100, 0x00c6, 0x6038, 0x2060,
+ 0x6104, 0x9186, 0x004b, 0x01c0, 0x9186, 0x004c, 0x01a8, 0x9186,
+ 0x004d, 0x0190, 0x9186, 0x004e, 0x0178, 0x9186, 0x0052, 0x0160,
+ 0x6014, 0x0096, 0x2048, 0x080c, 0xcc33, 0x090c, 0x0d79, 0xa87b,
+ 0x0003, 0x009e, 0x080c, 0xd317, 0x6007, 0x0085, 0x6003, 0x000b,
+ 0x6023, 0x0002, 0x2009, 0x8020, 0x080c, 0x9420, 0x00ce, 0x0030,
+ 0x6038, 0x2070, 0x2001, 0x1989, 0x2004, 0x704a, 0x080c, 0xaf4e,
+ 0x002e, 0x00de, 0x00ee, 0x0005, 0x00b6, 0x0096, 0x00f6, 0x6014,
+ 0x2048, 0x6010, 0x2058, 0x91b6, 0x0015, 0x0130, 0xba08, 0xbb0c,
+ 0xbc00, 0xc48c, 0xbc02, 0x0460, 0x0096, 0x0156, 0x0036, 0x0026,
+ 0x2b48, 0x9e90, 0x0010, 0x2019, 0x000a, 0x20a9, 0x0004, 0x080c,
+ 0xbf54, 0x002e, 0x003e, 0x015e, 0x009e, 0x1904, 0xb6fd, 0x0096,
+ 0x0156, 0x0036, 0x0026, 0x2b48, 0x9e90, 0x0014, 0x2019, 0x0006,
+ 0x20a9, 0x0004, 0x080c, 0xbf54, 0x002e, 0x003e, 0x015e, 0x009e,
+ 0x15a0, 0x7238, 0xba0a, 0x733c, 0xbb0e, 0xbc00, 0xc48d, 0xbc02,
+ 0xa804, 0x9005, 0x1128, 0x00fe, 0x009e, 0x00be, 0x0804, 0xb35e,
+ 0x0096, 0x2048, 0xaa12, 0xab16, 0xac0a, 0x009e, 0x8006, 0x8006,
+ 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, 0x0002, 0x2009,
+ 0x002b, 0xaaa0, 0xab9c, 0xaca8, 0xada4, 0x2031, 0x0000, 0x2041,
+ 0x129c, 0x080c, 0xb473, 0x0130, 0x00fe, 0x009e, 0x080c, 0xaf4e,
+ 0x00be, 0x0005, 0x080c, 0xb93c, 0x0cb8, 0x2b78, 0x00f6, 0x080c,
+ 0x32fb, 0x080c, 0xd372, 0x00fe, 0x00c6, 0x080c, 0xaef8, 0x2f00,
+ 0x6012, 0x6017, 0x0000, 0x6023, 0x0001, 0x6007, 0x0001, 0x6003,
+ 0x0001, 0x2001, 0x0007, 0x080c, 0x66c9, 0x080c, 0x66f5, 0x080c,
+ 0x9427, 0x080c, 0x98bc, 0x00ce, 0x0804, 0xb6d0, 0x2100, 0x91b2,
+ 0x0053, 0x1a0c, 0x0d79, 0x91b2, 0x0040, 0x1a04, 0xb786, 0x0002,
+ 0xb774, 0xb774, 0xb76a, 0xb774, 0xb774, 0xb774, 0xb768, 0xb768,
+ 0xb768, 0xb768, 0xb768, 0xb768, 0xb768, 0xb768, 0xb768, 0xb768,
+ 0xb768, 0xb768, 0xb768, 0xb768, 0xb768, 0xb768, 0xb768, 0xb768,
+ 0xb768, 0xb768, 0xb768, 0xb768, 0xb768, 0xb768, 0xb768, 0xb774,
+ 0xb768, 0xb774, 0xb774, 0xb768, 0xb768, 0xb768, 0xb768, 0xb768,
+ 0xb76a, 0xb768, 0xb768, 0xb768, 0xb768, 0xb768, 0xb768, 0xb768,
+ 0xb768, 0xb768, 0xb774, 0xb774, 0xb768, 0xb768, 0xb768, 0xb768,
+ 0xb768, 0xb768, 0xb768, 0xb768, 0xb768, 0xb774, 0xb768, 0xb768,
+ 0x080c, 0x0d79, 0x0066, 0x00b6, 0x6610, 0x2658, 0xb8d4, 0xc08c,
+ 0xb8d6, 0x00be, 0x006e, 0x0000, 0x6003, 0x0001, 0x6106, 0x9186,
+ 0x0032, 0x0118, 0x080c, 0x9427, 0x0010, 0x080c, 0x9420, 0x0126,
+ 0x2091, 0x8000, 0x080c, 0x98bc, 0x012e, 0x0005, 0x2600, 0x0002,
+ 0xb774, 0xb774, 0xb79a, 0xb774, 0xb774, 0xb79a, 0xb79a, 0xb79a,
+ 0xb79a, 0xb774, 0xb79a, 0xb774, 0xb79a, 0xb774, 0xb79a, 0xb79a,
+ 0xb79a, 0xb79a, 0x080c, 0x0d79, 0x6004, 0x90b2, 0x0053, 0x1a0c,
+ 0x0d79, 0x91b6, 0x0013, 0x0904, 0xb871, 0x91b6, 0x0027, 0x1904,
+ 0xb81d, 0x080c, 0x97f6, 0x6004, 0x080c, 0xce39, 0x01b0, 0x080c,
+ 0xce4a, 0x01a8, 0x908e, 0x0021, 0x0904, 0xb81a, 0x908e, 0x0022,
+ 0x1130, 0x080c, 0xb38a, 0x0904, 0xb816, 0x0804, 0xb817, 0x908e,
+ 0x003d, 0x0904, 0xb81a, 0x0804, 0xb810, 0x080c, 0x332a, 0x2001,
+ 0x0007, 0x080c, 0x66c9, 0x6010, 0x00b6, 0x2058, 0xb9a0, 0x00be,
+ 0x080c, 0xb93c, 0x9186, 0x007e, 0x1148, 0x2001, 0x1837, 0x2014,
+ 0xc285, 0x080c, 0x769d, 0x1108, 0xc2ad, 0x2202, 0x080c, 0xaaf7,
+ 0x0036, 0x0026, 0x2019, 0x0028, 0x2110, 0x080c, 0xeafd, 0x002e,
+ 0x003e, 0x0016, 0x0026, 0x0036, 0x2110, 0x2019, 0x0028, 0x080c,
+ 0x95b9, 0x0076, 0x903e, 0x080c, 0x9476, 0x6010, 0x00b6, 0x905d,
+ 0x0100, 0x00be, 0x2c08, 0x080c, 0xe465, 0x007e, 0x003e, 0x002e,
+ 0x001e, 0x080c, 0xab13, 0x080c, 0xd372, 0x0016, 0x080c, 0xd0c6,
+ 0x080c, 0xaf4e, 0x001e, 0x080c, 0x3404, 0x080c, 0x98bc, 0x0030,
+ 0x080c, 0xd0c6, 0x080c, 0xaf4e, 0x080c, 0x98bc, 0x0005, 0x080c,
+ 0xb93c, 0x0cb0, 0x080c, 0xb978, 0x0c98, 0x9186, 0x0015, 0x0118,
+ 0x9186, 0x0016, 0x1140, 0x080c, 0xad4d, 0x0d80, 0x9086, 0x0002,
+ 0x0904, 0xb983, 0x0c58, 0x9186, 0x0014, 0x1d40, 0x080c, 0x97f6,
+ 0x6004, 0x908e, 0x0022, 0x1118, 0x080c, 0xb38a, 0x09f8, 0x080c,
+ 0x32fb, 0x080c, 0xd372, 0x080c, 0xce39, 0x1190, 0x080c, 0x332a,
+ 0x6010, 0x00b6, 0x2058, 0xb9a0, 0x00be, 0x080c, 0xb93c, 0x9186,
+ 0x007e, 0x1128, 0x2001, 0x1837, 0x200c, 0xc185, 0x2102, 0x0800,
+ 0x080c, 0xce4a, 0x1120, 0x080c, 0xb93c, 0x0804, 0xb810, 0x6004,
+ 0x908e, 0x0032, 0x1160, 0x00e6, 0x00f6, 0x2071, 0x189e, 0x2079,
+ 0x0000, 0x080c, 0x36a5, 0x00fe, 0x00ee, 0x0804, 0xb810, 0x6004,
+ 0x908e, 0x0021, 0x0d40, 0x908e, 0x0022, 0x090c, 0xb93c, 0x0804,
+ 0xb810, 0x90b2, 0x0040, 0x1a04, 0xb91c, 0x2008, 0x0002, 0xb8b9,
+ 0xb8ba, 0xb8bd, 0xb8c0, 0xb8c3, 0xb8d0, 0xb8b7, 0xb8b7, 0xb8b7,
+ 0xb8b7, 0xb8b7, 0xb8b7, 0xb8b7, 0xb8b7, 0xb8b7, 0xb8b7, 0xb8b7,
+ 0xb8b7, 0xb8b7, 0xb8b7, 0xb8b7, 0xb8b7, 0xb8b7, 0xb8b7, 0xb8b7,
+ 0xb8b7, 0xb8b7, 0xb8b7, 0xb8b7, 0xb8b7, 0xb8d3, 0xb8de, 0xb8b7,
+ 0xb8df, 0xb8de, 0xb8b7, 0xb8b7, 0xb8b7, 0xb8b7, 0xb8b7, 0xb8de,
+ 0xb8de, 0xb8b7, 0xb8b7, 0xb8b7, 0xb8b7, 0xb8b7, 0xb8b7, 0xb8b7,
+ 0xb8b7, 0xb907, 0xb8de, 0xb8b7, 0xb8da, 0xb8b7, 0xb8b7, 0xb8b7,
+ 0xb8db, 0xb8b7, 0xb8b7, 0xb8b7, 0xb8de, 0xb902, 0xb8b7, 0x080c,
+ 0x0d79, 0x0420, 0x2001, 0x000b, 0x0448, 0x2001, 0x0003, 0x0430,
+ 0x2001, 0x0005, 0x0418, 0x6010, 0x00b6, 0x2058, 0xb804, 0x00be,
+ 0x9084, 0x00ff, 0x9086, 0x0000, 0x11d8, 0x2001, 0x0001, 0x00b0,
+ 0x2001, 0x0009, 0x0098, 0x6003, 0x0005, 0x080c, 0xd375, 0x080c,
+ 0x98bc, 0x0058, 0x0018, 0x0010, 0x080c, 0x66c9, 0x04b8, 0x080c,
+ 0xd375, 0x6003, 0x0004, 0x080c, 0x98bc, 0x0005, 0x080c, 0x66c9,
+ 0x6003, 0x0002, 0x0036, 0x2019, 0x1852, 0x2304, 0x9084, 0xff00,
+ 0x1120, 0x2001, 0x1987, 0x201c, 0x0040, 0x8007, 0x909a, 0x0004,
+ 0x0ec0, 0x8003, 0x801b, 0x831b, 0x9318, 0x631a, 0x003e, 0x080c,
+ 0x98bc, 0x0c18, 0x080c, 0xd0c6, 0x080c, 0xaf4e, 0x08f0, 0x00e6,
+ 0x00f6, 0x2071, 0x189e, 0x2079, 0x0000, 0x080c, 0x36a5, 0x00fe,
+ 0x00ee, 0x080c, 0x97f6, 0x080c, 0xaf4e, 0x0878, 0x6003, 0x0002,
+ 0x080c, 0xd375, 0x0804, 0x98bc, 0x2600, 0x2008, 0x0002, 0xb933,
+ 0xb916, 0xb931, 0xb916, 0xb916, 0xb931, 0xb931, 0xb931, 0xb931,
+ 0xb916, 0xb931, 0xb916, 0xb931, 0xb916, 0xb931, 0xb931, 0xb931,
+ 0xb931, 0x080c, 0x0d79, 0x0096, 0x6014, 0x2048, 0x080c, 0x6f11,
+ 0x009e, 0x080c, 0xaf4e, 0x0005, 0x00e6, 0x0096, 0x0026, 0x0016,
+ 0x080c, 0xcc33, 0x0568, 0x6014, 0x2048, 0xa864, 0x9086, 0x0139,
+ 0x11a8, 0xa894, 0x9086, 0x0056, 0x1148, 0x080c, 0x55ac, 0x0130,
+ 0x2001, 0x0000, 0x900e, 0x2011, 0x4000, 0x0028, 0x2001, 0x0030,
+ 0x900e, 0x2011, 0x4005, 0x080c, 0xd237, 0x0090, 0xa868, 0xd0fc,
+ 0x0178, 0xa807, 0x0000, 0x0016, 0x6004, 0x908e, 0x0021, 0x0168,
+ 0x908e, 0x003d, 0x0150, 0x001e, 0xa867, 0x0103, 0xa833, 0x0100,
+ 0x001e, 0x002e, 0x009e, 0x00ee, 0x0005, 0x001e, 0x0009, 0x0cc0,
+ 0x0096, 0x6014, 0x2048, 0xa800, 0x2048, 0xa867, 0x0103, 0xa823,
+ 0x8001, 0x009e, 0x0005, 0x00b6, 0x6610, 0x2658, 0xb804, 0x9084,
+ 0x00ff, 0x90b2, 0x000c, 0x1a0c, 0x0d79, 0x6604, 0x96b6, 0x004d,
+ 0x1120, 0x080c, 0xd156, 0x0804, 0xba08, 0x6604, 0x96b6, 0x0043,
+ 0x1120, 0x080c, 0xd19f, 0x0804, 0xba08, 0x6604, 0x96b6, 0x004b,
+ 0x1120, 0x080c, 0xd1cb, 0x0804, 0xba08, 0x6604, 0x96b6, 0x0033,
+ 0x1120, 0x080c, 0xd0e8, 0x0804, 0xba08, 0x6604, 0x96b6, 0x0028,
+ 0x1120, 0x080c, 0xce88, 0x0804, 0xba08, 0x6604, 0x96b6, 0x0029,
+ 0x1120, 0x080c, 0xcec9, 0x0804, 0xba08, 0x6604, 0x96b6, 0x001f,
+ 0x1120, 0x080c, 0xb32f, 0x0804, 0xba08, 0x6604, 0x96b6, 0x0000,
+ 0x1118, 0x080c, 0xb694, 0x04e0, 0x6604, 0x96b6, 0x0022, 0x1118,
+ 0x080c, 0xb36b, 0x04a8, 0x6604, 0x96b6, 0x0035, 0x1118, 0x080c,
+ 0xb491, 0x0470, 0x6604, 0x96b6, 0x0039, 0x1118, 0x080c, 0xb629,
+ 0x0438, 0x6604, 0x96b6, 0x003d, 0x1118, 0x080c, 0xb3a3, 0x0400,
+ 0x6604, 0x96b6, 0x0044, 0x1118, 0x080c, 0xb3df, 0x00c8, 0x6604,
+ 0x96b6, 0x0049, 0x1118, 0x080c, 0xb420, 0x0090, 0x6604, 0x96b6,
+ 0x0041, 0x1118, 0x080c, 0xb40a, 0x0058, 0x91b6, 0x0015, 0x1110,
+ 0x0063, 0x0030, 0x91b6, 0x0016, 0x1128, 0x00be, 0x0804, 0xbc66,
+ 0x00be, 0x0005, 0x080c, 0xb009, 0x0cd8, 0xba25, 0xba33, 0xba25,
+ 0xba7a, 0xba25, 0xbbda, 0xbc73, 0xba25, 0xba25, 0xbc3c, 0xba25,
+ 0xbc52, 0x0096, 0x601f, 0x0000, 0x6014, 0x2048, 0xa800, 0x2048,
+ 0xa867, 0x0103, 0x009e, 0x0804, 0xaf4e, 0xa001, 0xa001, 0x0005,
+ 0x6604, 0x96b6, 0x0004, 0x1130, 0x2001, 0x0001, 0x080c, 0x66b5,
+ 0x0804, 0xaf4e, 0x0005, 0x00e6, 0x2071, 0x1800, 0x7090, 0x9086,
+ 0x0074, 0x1540, 0x080c, 0xe436, 0x11b0, 0x6010, 0x00b6, 0x2058,
+ 0x7030, 0xd08c, 0x0128, 0xb800, 0xd0bc, 0x0110, 0xc0c5, 0xb802,
+ 0x00f9, 0x00be, 0x2001, 0x0006, 0x080c, 0x66c9, 0x080c, 0x332a,
+ 0x080c, 0xaf4e, 0x0098, 0x2001, 0x000a, 0x080c, 0x66c9, 0x080c,
+ 0x332a, 0x6003, 0x0001, 0x6007, 0x0001, 0x080c, 0x9427, 0x080c,
+ 0x98bc, 0x0020, 0x2001, 0x0001, 0x080c, 0xbbaa, 0x00ee, 0x0005,
+ 0x00d6, 0xb800, 0xd084, 0x0160, 0x9006, 0x080c, 0x66b5, 0x2069,
+ 0x1847, 0x6804, 0xd0a4, 0x0120, 0x2001, 0x0006, 0x080c, 0x66f5,
+ 0x00de, 0x0005, 0x00b6, 0x0096, 0x00d6, 0x2011, 0x1824, 0x2204,
+ 0x9086, 0x0074, 0x1904, 0xbb7f, 0x6010, 0x2058, 0xbaa0, 0x9286,
+ 0x007e, 0x1120, 0x080c, 0xbdc2, 0x0804, 0xbaec, 0x080c, 0xbdb7,
+ 0x6010, 0x2058, 0xbaa0, 0x9286, 0x0080, 0x1510, 0x6014, 0x9005,
+ 0x01a8, 0x2048, 0xa864, 0x9084, 0x00ff, 0x9086, 0x0039, 0x1140,
+ 0x2001, 0x0000, 0x900e, 0x2011, 0x4000, 0x080c, 0xd237, 0x0030,
+ 0xa807, 0x0000, 0xa867, 0x0103, 0xa833, 0x0200, 0x2001, 0x0006,
+ 0x080c, 0x66c9, 0x080c, 0x332a, 0x080c, 0xaf4e, 0x0804, 0xbb84,
+ 0x080c, 0xbb92, 0x6014, 0x9005, 0x0190, 0x2048, 0xa868, 0xd0f4,
+ 0x01e8, 0xa864, 0x9084, 0x00ff, 0x9086, 0x0039, 0x1d08, 0x2001,
+ 0x0000, 0x900e, 0x2011, 0x4000, 0x080c, 0xd237, 0x08f8, 0x080c,
+ 0xbb88, 0x0160, 0x9006, 0x080c, 0x66b5, 0x2001, 0x0004, 0x080c,
+ 0x66f5, 0x2001, 0x0007, 0x080c, 0x66c9, 0x08a0, 0x2001, 0x0004,
+ 0x080c, 0x66c9, 0x6003, 0x0001, 0x6007, 0x0003, 0x080c, 0x9427,
+ 0x080c, 0x98bc, 0x0804, 0xbb84, 0xb85c, 0xd0e4, 0x0178, 0x080c,
+ 0xd060, 0x080c, 0x769d, 0x0118, 0xd0dc, 0x1904, 0xbaae, 0x2011,
+ 0x1837, 0x2204, 0xc0ad, 0x2012, 0x0804, 0xbaae, 0x080c, 0xd0a1,
+ 0x2011, 0x1837, 0x2204, 0xc0a5, 0x2012, 0x0006, 0x080c, 0xe60d,
+ 0x000e, 0x1904, 0xbaae, 0xc0b5, 0x2012, 0x2001, 0x0006, 0x080c,
+ 0x66c9, 0x9006, 0x080c, 0x66b5, 0x00c6, 0x2001, 0x180f, 0x2004,
+ 0xd09c, 0x0520, 0x00f6, 0x2079, 0x0100, 0x00e6, 0x2071, 0x1800,
+ 0x700c, 0x9084, 0x00ff, 0x78e6, 0x707e, 0x7010, 0x78ea, 0x7082,
+ 0x908c, 0x00ff, 0x00ee, 0x780c, 0xc0b5, 0x780e, 0x00fe, 0x080c,
+ 0x26ea, 0x00f6, 0x2100, 0x900e, 0x080c, 0x26a1, 0x795e, 0x00fe,
+ 0x9186, 0x0081, 0x01f0, 0x2009, 0x0081, 0x00e0, 0x2009, 0x00ef,
+ 0x00f6, 0x2079, 0x0100, 0x79ea, 0x78e7, 0x0000, 0x7932, 0x7936,
+ 0x780c, 0xc0b5, 0x780e, 0x00fe, 0x080c, 0x26ea, 0x00f6, 0x2079,
+ 0x1800, 0x7982, 0x2100, 0x900e, 0x797e, 0x080c, 0x26a1, 0x795e,
+ 0x00fe, 0x8108, 0x080c, 0x6718, 0x2b00, 0x00ce, 0x1904, 0xbaae,
+ 0x6012, 0x2009, 0x180f, 0x210c, 0xd19c, 0x0150, 0x2009, 0x027c,
+ 0x210c, 0x918c, 0x00ff, 0xb912, 0x2009, 0x027d, 0x210c, 0xb916,
+ 0x2001, 0x0002, 0x080c, 0x66c9, 0x6023, 0x0001, 0x6003, 0x0001,
+ 0x6007, 0x0002, 0x080c, 0x9427, 0x080c, 0x98bc, 0x0028, 0x080c,
+ 0xb93c, 0x2001, 0x0001, 0x0431, 0x00de, 0x009e, 0x00be, 0x0005,
+ 0x2001, 0x1810, 0x2004, 0xd0a4, 0x0120, 0x2001, 0x1848, 0x2004,
+ 0xd0ac, 0x0005, 0x00e6, 0x080c, 0xeb56, 0x0190, 0x2071, 0x0260,
+ 0x7108, 0x720c, 0x918c, 0x00ff, 0x1118, 0x9284, 0xff00, 0x0140,
+ 0x6010, 0x2058, 0xb8a0, 0x9084, 0xff80, 0x1110, 0xb912, 0xba16,
+ 0x00ee, 0x0005, 0x2030, 0x9005, 0x0158, 0x2001, 0x0007, 0x080c,
+ 0x66c9, 0x080c, 0x5834, 0x1120, 0x2001, 0x0007, 0x080c, 0x66f5,
+ 0x2600, 0x9005, 0x11b0, 0x6014, 0x0096, 0x2048, 0xa868, 0x009e,
+ 0xd0fc, 0x1178, 0x0036, 0x0046, 0x6010, 0x00b6, 0x2058, 0xbba0,
+ 0x00be, 0x2021, 0x0004, 0x2011, 0x8014, 0x080c, 0x4c28, 0x004e,
+ 0x003e, 0x080c, 0x332a, 0x6020, 0x9086, 0x000a, 0x1108, 0x0005,
+ 0x0804, 0xaf4e, 0x00b6, 0x00e6, 0x0026, 0x0016, 0x2071, 0x1800,
+ 0x7090, 0x9086, 0x0014, 0x1904, 0xbc32, 0x080c, 0x5834, 0x1170,
+ 0x6014, 0x9005, 0x1158, 0x0036, 0x0046, 0x6010, 0x2058, 0xbba0,
+ 0x2021, 0x0006, 0x080c, 0x4ddf, 0x004e, 0x003e, 0x00d6, 0x6010,
+ 0x2058, 0x080c, 0x681e, 0x080c, 0xba68, 0x00de, 0x080c, 0xbe8d,
+ 0x1588, 0x6010, 0x2058, 0xb890, 0x9005, 0x0560, 0x2001, 0x0006,
+ 0x080c, 0x66c9, 0x0096, 0x6014, 0x904d, 0x01d0, 0xa864, 0x9084,
+ 0x00ff, 0x9086, 0x0039, 0x1140, 0x2001, 0x0000, 0x900e, 0x2011,
+ 0x4000, 0x080c, 0xd237, 0x0060, 0xa864, 0x9084, 0x00ff, 0x9086,
+ 0x0029, 0x0130, 0xa807, 0x0000, 0xa867, 0x0103, 0xa833, 0x0200,
+ 0x009e, 0x080c, 0x332a, 0x6020, 0x9086, 0x000a, 0x0140, 0x080c,
+ 0xaf4e, 0x0028, 0x080c, 0xb93c, 0x9006, 0x080c, 0xbbaa, 0x001e,
+ 0x002e, 0x00ee, 0x00be, 0x0005, 0x2011, 0x1824, 0x2204, 0x9086,
+ 0x0014, 0x1160, 0x2001, 0x0002, 0x080c, 0x66c9, 0x6003, 0x0001,
+ 0x6007, 0x0001, 0x080c, 0x9427, 0x0804, 0x98bc, 0x2001, 0x0001,
+ 0x0804, 0xbbaa, 0x2030, 0x2011, 0x1824, 0x2204, 0x9086, 0x0004,
+ 0x1148, 0x96b6, 0x000b, 0x1120, 0x2001, 0x0007, 0x080c, 0x66c9,
+ 0x0804, 0xaf4e, 0x2001, 0x0001, 0x0804, 0xbbaa, 0x0002, 0xba25,
+ 0xbc7e, 0xba25, 0xbcc1, 0xba25, 0xbd6e, 0xbc73, 0xba28, 0xba25,
+ 0xbd82, 0xba25, 0xbd94, 0x6604, 0x9686, 0x0003, 0x0904, 0xbbda,
+ 0x96b6, 0x001e, 0x1110, 0x080c, 0xaf4e, 0x0005, 0x00b6, 0x00d6,
+ 0x00c6, 0x080c, 0xbda6, 0x11a0, 0x9006, 0x080c, 0x66b5, 0x080c,
+ 0x32fb, 0x080c, 0xd372, 0x2001, 0x0002, 0x080c, 0x66c9, 0x6003,
+ 0x0001, 0x6007, 0x0002, 0x080c, 0x9427, 0x080c, 0x98bc, 0x0428,
+ 0x2009, 0x026e, 0x2104, 0x9086, 0x0009, 0x1160, 0x6010, 0x2058,
+ 0xb840, 0x9084, 0x00ff, 0x9005, 0x0180, 0x8001, 0xb842, 0x601b,
+ 0x000a, 0x0098, 0x2009, 0x026f, 0x2104, 0x9084, 0xff00, 0x908e,
+ 0x1900, 0x0158, 0x908e, 0x1e00, 0x0990, 0x080c, 0x32fb, 0x080c,
+ 0xd372, 0x2001, 0x0001, 0x080c, 0xbbaa, 0x00ce, 0x00de, 0x00be,
+ 0x0005, 0x0096, 0x00b6, 0x0026, 0x9016, 0x080c, 0xbdb4, 0x00d6,
+ 0x2069, 0x197d, 0x2d04, 0x9005, 0x0168, 0x6010, 0x2058, 0xb8a0,
+ 0x9086, 0x007e, 0x1138, 0x2069, 0x1820, 0x2d04, 0x8000, 0x206a,
+ 0x00de, 0x0010, 0x00de, 0x0088, 0x9006, 0x080c, 0x66b5, 0x2001,
+ 0x0002, 0x080c, 0x66c9, 0x6003, 0x0001, 0x6007, 0x0002, 0x080c,
+ 0x9427, 0x080c, 0x98bc, 0x0804, 0xbd3e, 0x080c, 0xcc33, 0x01b0,
+ 0x6014, 0x2048, 0xa864, 0x2010, 0x9086, 0x0139, 0x1138, 0x6007,
+ 0x0016, 0x2001, 0x0002, 0x080c, 0xd294, 0x00b0, 0x6014, 0x2048,
+ 0xa864, 0xd0fc, 0x0118, 0x2001, 0x0001, 0x0ca8, 0x2001, 0x180e,
+ 0x2004, 0xd0dc, 0x0148, 0x6010, 0x2058, 0xb840, 0x9084, 0x00ff,
+ 0x9005, 0x1110, 0x9006, 0x0c38, 0x080c, 0xb93c, 0x2009, 0x026e,
+ 0x2134, 0x96b4, 0x00ff, 0x9686, 0x0005, 0x0520, 0x9686, 0x000b,
+ 0x01c8, 0x2009, 0x026f, 0x2104, 0x9084, 0xff00, 0x1118, 0x9686,
+ 0x0009, 0x01c0, 0x9086, 0x1900, 0x1168, 0x9686, 0x0009, 0x0190,
+ 0x2001, 0x0004, 0x080c, 0x66c9, 0x2001, 0x0028, 0x601a, 0x6007,
+ 0x0052, 0x0020, 0x2001, 0x0001, 0x080c, 0xbbaa, 0x002e, 0x00be,
+ 0x009e, 0x0005, 0x9286, 0x0139, 0x0160, 0x6014, 0x2048, 0x080c,
+ 0xcc33, 0x0140, 0xa864, 0x9086, 0x0139, 0x0118, 0xa868, 0xd0fc,
+ 0x0108, 0x0c40, 0x6010, 0x2058, 0xb840, 0x9084, 0x00ff, 0x9005,
+ 0x0138, 0x8001, 0xb842, 0x601b, 0x000a, 0x6007, 0x0016, 0x08f0,
+ 0xb8a0, 0x9086, 0x007e, 0x1138, 0x00e6, 0x2071, 0x1800, 0x080c,
+ 0x610b, 0x00ee, 0x0010, 0x080c, 0x32fb, 0x0860, 0x2001, 0x0004,
+ 0x080c, 0x66c9, 0x080c, 0xbdb4, 0x1140, 0x6003, 0x0001, 0x6007,
+ 0x0003, 0x080c, 0x9427, 0x0804, 0x98bc, 0x080c, 0xb93c, 0x9006,
+ 0x0804, 0xbbaa, 0x0489, 0x1160, 0x2001, 0x0008, 0x080c, 0x66c9,
+ 0x6003, 0x0001, 0x6007, 0x0005, 0x080c, 0x9427, 0x0804, 0x98bc,
+ 0x2001, 0x0001, 0x0804, 0xbbaa, 0x00f9, 0x1160, 0x2001, 0x000a,
+ 0x080c, 0x66c9, 0x6003, 0x0001, 0x6007, 0x0001, 0x080c, 0x9427,
+ 0x0804, 0x98bc, 0x2001, 0x0001, 0x0804, 0xbbaa, 0x2009, 0x026e,
+ 0x2104, 0x9086, 0x0003, 0x1138, 0x2009, 0x026f, 0x2104, 0x9084,
+ 0xff00, 0x9086, 0x2a00, 0x0005, 0x9085, 0x0001, 0x0005, 0x00b6,
+ 0x00c6, 0x0016, 0x6110, 0x2158, 0x080c, 0x6792, 0x001e, 0x00ce,
+ 0x00be, 0x0005, 0x00b6, 0x00f6, 0x00e6, 0x00d6, 0x0036, 0x0016,
+ 0x6010, 0x2058, 0x2009, 0x1837, 0x2104, 0x9085, 0x0003, 0x200a,
+ 0x080c, 0xbe5f, 0x0560, 0x2009, 0x1837, 0x2104, 0xc0cd, 0x200a,
+ 0x080c, 0x6bc9, 0x0158, 0x9006, 0x2020, 0x2009, 0x002a, 0x080c,
+ 0xe795, 0x2001, 0x180c, 0x200c, 0xc195, 0x2102, 0x2019, 0x002a,
+ 0x2009, 0x0001, 0x080c, 0x32c0, 0x00e6, 0x2071, 0x1800, 0x080c,
+ 0x30c8, 0x00ee, 0x00c6, 0x0156, 0x20a9, 0x0781, 0x2009, 0x007f,
+ 0x080c, 0x3404, 0x8108, 0x1f04, 0xbdf8, 0x015e, 0x00ce, 0x080c,
+ 0xbdb7, 0x2071, 0x0260, 0x2079, 0x0200, 0x7817, 0x0001, 0x2001,
+ 0x1837, 0x200c, 0xc1c5, 0x7018, 0xd0fc, 0x0110, 0xd0dc, 0x0118,
+ 0x7038, 0xd0dc, 0x1108, 0xc1c4, 0x7817, 0x0000, 0x2001, 0x1837,
+ 0x2102, 0x9184, 0x0050, 0x9086, 0x0050, 0x05d0, 0x2079, 0x0100,
+ 0x2e04, 0x9084, 0x00ff, 0x2069, 0x181f, 0x206a, 0x78e6, 0x0006,
+ 0x8e70, 0x2e04, 0x2069, 0x1820, 0x206a, 0x78ea, 0x7832, 0x7836,
+ 0x2010, 0x9084, 0xff00, 0x001e, 0x9105, 0x2009, 0x182c, 0x200a,
+ 0x2200, 0x9084, 0x00ff, 0x2008, 0x080c, 0x26ea, 0x080c, 0x769d,
+ 0x0170, 0x2071, 0x0260, 0x2069, 0x1983, 0x7048, 0x206a, 0x704c,
+ 0x6806, 0x7050, 0x680a, 0x7054, 0x680e, 0x080c, 0xd060, 0x0040,
+ 0x2001, 0x0006, 0x080c, 0x66c9, 0x080c, 0x332a, 0x080c, 0xaf4e,
+ 0x001e, 0x003e, 0x00de, 0x00ee, 0x00fe, 0x00be, 0x0005, 0x0096,
+ 0x0026, 0x0036, 0x00e6, 0x0156, 0x2019, 0x182c, 0x231c, 0x83ff,
+ 0x01f0, 0x2071, 0x0260, 0x7200, 0x9294, 0x00ff, 0x7004, 0x9084,
+ 0xff00, 0x9205, 0x9306, 0x1198, 0x2011, 0x0276, 0x20a9, 0x0004,
+ 0x2b48, 0x2019, 0x000a, 0x080c, 0xbf54, 0x1148, 0x2011, 0x027a,
+ 0x20a9, 0x0004, 0x2019, 0x0006, 0x080c, 0xbf54, 0x1100, 0x015e,
+ 0x00ee, 0x003e, 0x002e, 0x009e, 0x0005, 0x00e6, 0x2071, 0x0260,
+ 0x7034, 0x9086, 0x0014, 0x11a8, 0x7038, 0x9086, 0x0800, 0x1188,
+ 0x703c, 0xd0ec, 0x0160, 0x9084, 0x0f00, 0x9086, 0x0100, 0x1138,
+ 0x7054, 0xd0a4, 0x1110, 0xd0ac, 0x0110, 0x9006, 0x0010, 0x9085,
+ 0x0001, 0x00ee, 0x0005, 0x00e6, 0x0096, 0x00c6, 0x0076, 0x0056,
+ 0x0046, 0x0026, 0x0006, 0x0126, 0x2091, 0x8000, 0x2029, 0x19f5,
+ 0x252c, 0x2021, 0x19fc, 0x2424, 0x2061, 0x1ddc, 0x2071, 0x1800,
+ 0x7254, 0x7074, 0x9202, 0x1a04, 0xbf20, 0x080c, 0x8d87, 0x0904,
+ 0xbf19, 0x080c, 0xe7c6, 0x0904, 0xbf19, 0x6720, 0x9786, 0x0007,
+ 0x0904, 0xbf19, 0x2500, 0x9c06, 0x0904, 0xbf19, 0x2400, 0x9c06,
+ 0x0904, 0xbf19, 0x3e08, 0x9186, 0x0002, 0x1148, 0x6010, 0x9005,
+ 0x0130, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x1590, 0x00c6,
+ 0x6043, 0xffff, 0x6000, 0x9086, 0x0004, 0x1110, 0x080c, 0x1af0,
+ 0x9786, 0x000a, 0x0148, 0x080c, 0xce4a, 0x1130, 0x00ce, 0x080c,
+ 0xb93c, 0x080c, 0xaf89, 0x00e8, 0x6014, 0x2048, 0x080c, 0xcc33,
+ 0x01a8, 0x9786, 0x0003, 0x1530, 0xa867, 0x0103, 0xa87c, 0xd0cc,
+ 0x0130, 0x0096, 0xa878, 0x2048, 0x080c, 0x0fff, 0x009e, 0xab7a,
+ 0xa877, 0x0000, 0x080c, 0x6f05, 0x080c, 0xce24, 0x080c, 0xaf89,
+ 0x00ce, 0x9ce0, 0x001c, 0x7068, 0x9c02, 0x1210, 0x0804, 0xbec0,
+ 0x012e, 0x000e, 0x002e, 0x004e, 0x005e, 0x007e, 0x00ce, 0x009e,
+ 0x00ee, 0x0005, 0x9786, 0x0006, 0x1118, 0x080c, 0xe738, 0x0c30,
+ 0x9786, 0x0009, 0x1148, 0x6000, 0x9086, 0x0004, 0x0d08, 0x2009,
+ 0x004c, 0x080c, 0xafec, 0x08e0, 0x9786, 0x000a, 0x0980, 0x0820,
+ 0x220c, 0x2304, 0x9106, 0x1130, 0x8210, 0x8318, 0x1f04, 0xbf40,
+ 0x9006, 0x0005, 0x2304, 0x9102, 0x0218, 0x2001, 0x0001, 0x0008,
+ 0x9006, 0x918d, 0x0001, 0x0005, 0x0136, 0x01c6, 0x0016, 0x8906,
+ 0x8006, 0x8007, 0x908c, 0x003f, 0x21e0, 0x9084, 0xffc0, 0x9300,
+ 0x2098, 0x3518, 0x20a9, 0x0001, 0x220c, 0x4002, 0x910e, 0x1140,
+ 0x8210, 0x8319, 0x1dc8, 0x9006, 0x001e, 0x01ce, 0x013e, 0x0005,
+ 0x220c, 0x9102, 0x0218, 0x2001, 0x0001, 0x0010, 0x2001, 0x0000,
+ 0x918d, 0x0001, 0x001e, 0x01ce, 0x013e, 0x0005, 0x220c, 0x810f,
+ 0x2304, 0x9106, 0x1130, 0x8210, 0x8318, 0x1f04, 0xbf7e, 0x9006,
+ 0x0005, 0x918d, 0x0001, 0x0005, 0x6004, 0x908a, 0x0053, 0x1a0c,
+ 0x0d79, 0x080c, 0xce39, 0x0120, 0x080c, 0xce4a, 0x0158, 0x0028,
+ 0x080c, 0x332a, 0x080c, 0xce4a, 0x0128, 0x080c, 0x97f6, 0x080c,
+ 0xaf4e, 0x0005, 0x080c, 0xb93c, 0x0cc0, 0x9182, 0x0057, 0x1220,
+ 0x9182, 0x0040, 0x0208, 0x000a, 0x0005, 0xbfc4, 0xbfc4, 0xbfc4,
+ 0xbfc4, 0xbfc4, 0xbfc4, 0xbfc4, 0xbfc4, 0xbfc4, 0xbfc4, 0xbfc4,
+ 0xbfc6, 0xbfc6, 0xbfc6, 0xbfc6, 0xbfc4, 0xbfc4, 0xbfc4, 0xbfc6,
+ 0xbfc4, 0xbfc4, 0xbfc4, 0xbfc4, 0x080c, 0x0d79, 0x600b, 0xffff,
+ 0x6003, 0x000f, 0x6106, 0x0126, 0x2091, 0x8000, 0x080c, 0xd375,
+ 0x2009, 0x8000, 0x080c, 0x9420, 0x012e, 0x0005, 0x9186, 0x0013,
+ 0x1128, 0x6004, 0x9082, 0x0040, 0x0804, 0xc04e, 0x9186, 0x0027,
+ 0x1520, 0x080c, 0x97f6, 0x080c, 0x32fb, 0x080c, 0xd372, 0x0096,
+ 0x6114, 0x2148, 0x080c, 0xcc33, 0x0198, 0x080c, 0xce4a, 0x1118,
+ 0x080c, 0xb93c, 0x0068, 0xa867, 0x0103, 0xa87b, 0x0029, 0xa877,
+ 0x0000, 0xa97c, 0xc1c5, 0xa97e, 0x080c, 0x6f11, 0x080c, 0xce24,
+ 0x009e, 0x080c, 0xaf4e, 0x0804, 0x98bc, 0x9186, 0x0014, 0x1120,
+ 0x6004, 0x9082, 0x0040, 0x0030, 0x9186, 0x0053, 0x0110, 0x080c,
+ 0x0d79, 0x0005, 0x0002, 0xc02c, 0xc02a, 0xc02a, 0xc02a, 0xc02a,
+ 0xc02a, 0xc02a, 0xc02a, 0xc02a, 0xc02a, 0xc02a, 0xc045, 0xc045,
+ 0xc045, 0xc045, 0xc02a, 0xc045, 0xc02a, 0xc045, 0xc02a, 0xc02a,
+ 0xc02a, 0xc02a, 0x080c, 0x0d79, 0x080c, 0x97f6, 0x0096, 0x6114,
+ 0x2148, 0x080c, 0xcc33, 0x0168, 0xa867, 0x0103, 0xa87b, 0x0006,
+ 0xa877, 0x0000, 0xa880, 0xc0ec, 0xa882, 0x080c, 0x6f11, 0x080c,
+ 0xce24, 0x009e, 0x080c, 0xaf4e, 0x0005, 0x080c, 0x97f6, 0x080c,
+ 0xce4a, 0x090c, 0xb93c, 0x080c, 0xaf4e, 0x0005, 0x0002, 0xc068,
+ 0xc066, 0xc066, 0xc066, 0xc066, 0xc066, 0xc066, 0xc066, 0xc066,
+ 0xc066, 0xc066, 0xc06a, 0xc06a, 0xc06a, 0xc06a, 0xc066, 0xc06c,
+ 0xc066, 0xc06a, 0xc066, 0xc066, 0xc066, 0xc066, 0x080c, 0x0d79,
+ 0x080c, 0x0d79, 0x080c, 0x0d79, 0x080c, 0xaf4e, 0x0804, 0x98bc,
+ 0x9182, 0x0057, 0x1220, 0x9182, 0x0040, 0x0208, 0x000a, 0x0005,
+ 0xc08f, 0xc08f, 0xc08f, 0xc08f, 0xc08f, 0xc0c8, 0xc1ba, 0xc08f,
+ 0xc1c6, 0xc08f, 0xc08f, 0xc08f, 0xc08f, 0xc08f, 0xc08f, 0xc08f,
+ 0xc08f, 0xc08f, 0xc08f, 0xc1c6, 0xc091, 0xc08f, 0xc1c4, 0x080c,
+ 0x0d79, 0x00b6, 0x0096, 0x6114, 0x2148, 0x6010, 0x2058, 0xb800,
+ 0xd0bc, 0x1508, 0xa87b, 0x0000, 0xa867, 0x0103, 0xa877, 0x0000,
+ 0xa87c, 0xd0ac, 0x0128, 0xa834, 0xa938, 0x9115, 0x190c, 0xc24b,
+ 0x080c, 0x6d26, 0x6210, 0x2258, 0xba3c, 0x82ff, 0x0110, 0x8211,
+ 0xba3e, 0xb8d0, 0x9005, 0x0110, 0x080c, 0x68ae, 0x080c, 0xaf4e,
+ 0x009e, 0x00be, 0x0005, 0xa87c, 0xd0ac, 0x09e0, 0xa838, 0xa934,
+ 0x9105, 0x09c0, 0xa880, 0xd0bc, 0x19a8, 0x080c, 0xcf7f, 0x0c80,
+ 0x00b6, 0x0096, 0x6114, 0x2148, 0x601c, 0xd0fc, 0x1110, 0x7644,
+ 0x0008, 0x9036, 0x96b4, 0x0fff, 0x86ff, 0x1590, 0x6010, 0x2058,
+ 0xb800, 0xd0bc, 0x1904, 0xc1a9, 0xa87b, 0x0000, 0xa867, 0x0103,
+ 0xae76, 0xa87c, 0xd0ac, 0x0128, 0xa834, 0xa938, 0x9115, 0x190c,
+ 0xc24b, 0x080c, 0x6d26, 0x6210, 0x2258, 0xba3c, 0x82ff, 0x0110,
+ 0x8211, 0xba3e, 0xb8d0, 0x9005, 0x0110, 0x080c, 0x68ae, 0x601c,
+ 0xd0fc, 0x1148, 0x7044, 0xd0e4, 0x1904, 0xc18a, 0x080c, 0xaf4e,
+ 0x009e, 0x00be, 0x0005, 0x2009, 0x0211, 0x210c, 0x080c, 0x0d79,
+ 0x968c, 0x0c00, 0x0150, 0x6010, 0x2058, 0xb800, 0xd0bc, 0x1904,
+ 0xc18e, 0x7348, 0xab92, 0x734c, 0xab8e, 0x968c, 0x00ff, 0x9186,
+ 0x0002, 0x0508, 0x9186, 0x0028, 0x1118, 0xa87b, 0x001c, 0x00e8,
+ 0xd6dc, 0x01a0, 0xa87b, 0x0015, 0xa87c, 0xd0ac, 0x0170, 0xa938,
+ 0xaa34, 0x2100, 0x9205, 0x0148, 0x7048, 0x9106, 0x1118, 0x704c,
+ 0x9206, 0x0118, 0xa992, 0xaa8e, 0xc6dc, 0x0038, 0xd6d4, 0x0118,
+ 0xa87b, 0x0007, 0x0010, 0xa87b, 0x0000, 0xa867, 0x0103, 0xae76,
+ 0x901e, 0xd6c4, 0x01d8, 0x9686, 0x0100, 0x1130, 0x7064, 0x9005,
+ 0x1118, 0xc6c4, 0x0804, 0xc0d4, 0x735c, 0xab86, 0x83ff, 0x0170,
+ 0x938a, 0x0009, 0x0210, 0x2019, 0x0008, 0x0036, 0x2308, 0x2019,
+ 0x0018, 0x2011, 0x0025, 0x080c, 0xc7ad, 0x003e, 0xd6cc, 0x0904,
+ 0xc0e9, 0x7154, 0xa98a, 0x81ff, 0x0904, 0xc0e9, 0x9192, 0x0021,
+ 0x1278, 0x8304, 0x9098, 0x0018, 0x2011, 0x0029, 0x080c, 0xc7ad,
+ 0x2011, 0x0205, 0x2013, 0x0000, 0x080c, 0xd300, 0x0804, 0xc0e9,
+ 0xa868, 0xd0fc, 0x0120, 0x2009, 0x0020, 0xa98a, 0x0c50, 0x00a6,
+ 0x2950, 0x080c, 0xc74c, 0x00ae, 0x080c, 0xd300, 0x080c, 0xc79d,
+ 0x0804, 0xc0eb, 0x080c, 0xcf42, 0x0804, 0xc100, 0xa87c, 0xd0ac,
+ 0x0904, 0xc111, 0xa880, 0xd0bc, 0x1904, 0xc111, 0x9684, 0x0400,
+ 0x0130, 0xa838, 0xab34, 0x9305, 0x0904, 0xc111, 0x00b8, 0x7348,
+ 0xa838, 0x9306, 0x1198, 0x734c, 0xa834, 0x931e, 0x0904, 0xc111,
+ 0x0068, 0xa87c, 0xd0ac, 0x0904, 0xc0dc, 0xa838, 0xa934, 0x9105,
+ 0x0904, 0xc0dc, 0xa880, 0xd0bc, 0x1904, 0xc0dc, 0x080c, 0xcf7f,
+ 0x0804, 0xc100, 0x00f6, 0x2079, 0x026c, 0x7c04, 0x7b00, 0x7e0c,
+ 0x7d08, 0x00fe, 0x0021, 0x0005, 0x0011, 0x0005, 0x0005, 0x0096,
+ 0x6003, 0x0002, 0x6007, 0x0043, 0x6014, 0x2048, 0xa87c, 0xd0ac,
+ 0x0128, 0x009e, 0x0005, 0x2130, 0x2228, 0x0058, 0x2400, 0xa9ac,
+ 0x910a, 0x2300, 0xaab0, 0x9213, 0x2600, 0x9102, 0x2500, 0x9203,
+ 0x0e90, 0xac46, 0xab4a, 0xae36, 0xad3a, 0x6044, 0xd0fc, 0x190c,
+ 0xab20, 0x604b, 0x0000, 0x080c, 0x1cb9, 0x1118, 0x6144, 0x080c,
+ 0x944c, 0x009e, 0x0005, 0x9182, 0x0057, 0x1220, 0x9182, 0x0040,
+ 0x0208, 0x000a, 0x0005, 0xc212, 0xc212, 0xc212, 0xc212, 0xc212,
+ 0xc212, 0xc212, 0xc212, 0xc212, 0xc212, 0xc214, 0xc212, 0xc212,
+ 0xc212, 0xc212, 0xc225, 0xc212, 0xc212, 0xc212, 0xc212, 0xc249,
+ 0xc212, 0xc212, 0x080c, 0x0d79, 0x6004, 0x9086, 0x0040, 0x1110,
+ 0x080c, 0x97f6, 0x2019, 0x0001, 0x080c, 0xa391, 0x6003, 0x0002,
+ 0x080c, 0xd37a, 0x080c, 0x9851, 0x0005, 0x6004, 0x9086, 0x0040,
+ 0x1110, 0x080c, 0x97f6, 0x2019, 0x0001, 0x080c, 0xa391, 0x080c,
+ 0x9851, 0x080c, 0x32fb, 0x080c, 0xd372, 0x0096, 0x6114, 0x2148,
+ 0x080c, 0xcc33, 0x0150, 0xa867, 0x0103, 0xa87b, 0x0029, 0xa877,
+ 0x0000, 0x080c, 0x6f11, 0x080c, 0xce24, 0x009e, 0x080c, 0xaf4e,
+ 0x0005, 0x080c, 0x0d79, 0xa87b, 0x0015, 0xd1fc, 0x0180, 0xa87b,
+ 0x0007, 0x8002, 0x8000, 0x810a, 0x9189, 0x0000, 0x0006, 0x0016,
+ 0x2009, 0x1a7d, 0x2104, 0x8000, 0x200a, 0x001e, 0x000e, 0xa992,
+ 0xa88e, 0x0005, 0x9182, 0x0057, 0x1220, 0x9182, 0x0040, 0x0208,
+ 0x000a, 0x0005, 0xc281, 0xc281, 0xc281, 0xc281, 0xc281, 0xc283,
+ 0xc281, 0xc281, 0xc340, 0xc281, 0xc281, 0xc281, 0xc281, 0xc281,
+ 0xc281, 0xc281, 0xc281, 0xc281, 0xc281, 0xc480, 0xc281, 0xc48a,
+ 0xc281, 0x080c, 0x0d79, 0x601c, 0xd0bc, 0x0178, 0xd084, 0x0168,
+ 0xd0f4, 0x0120, 0xc084, 0x601e, 0x0804, 0xc070, 0x6114, 0x0096,
+ 0x2148, 0xa87c, 0xc0e5, 0xa87e, 0x009e, 0x0076, 0x00a6, 0x00e6,
+ 0x0096, 0x2071, 0x0260, 0x6114, 0x2150, 0x601c, 0xd0fc, 0x1110,
+ 0x7644, 0x0008, 0x9036, 0xb676, 0x96b4, 0x0fff, 0xb77c, 0xc7e5,
+ 0xb77e, 0x6210, 0x00b6, 0x2258, 0xba3c, 0x82ff, 0x0110, 0x8211,
+ 0xba3e, 0x00be, 0x86ff, 0x0904, 0xc339, 0x9694, 0xff00, 0x9284,
+ 0x0c00, 0x0120, 0x7048, 0xb092, 0x704c, 0xb08e, 0x9284, 0x0300,
+ 0x0904, 0xc339, 0x9686, 0x0100, 0x1130, 0x7064, 0x9005, 0x1118,
+ 0xc6c4, 0xb676, 0x0c38, 0x080c, 0x104d, 0x090c, 0x0d79, 0x2900,
+ 0xb07a, 0xb77c, 0x97bd, 0x0200, 0xb77e, 0xa867, 0x0103, 0xb068,
+ 0xa86a, 0xb06c, 0xa86e, 0xb070, 0xa872, 0x7044, 0x9084, 0xf000,
+ 0x9635, 0xae76, 0x968c, 0x0c00, 0x0120, 0x7348, 0xab92, 0x734c,
+ 0xab8e, 0x968c, 0x00ff, 0x9186, 0x0002, 0x0180, 0x9186, 0x0028,
+ 0x1118, 0xa87b, 0x001c, 0x0060, 0xd6dc, 0x0118, 0xa87b, 0x0015,
+ 0x0038, 0xd6d4, 0x0118, 0xa87b, 0x0007, 0x0010, 0xa87b, 0x0000,
+ 0xaf7e, 0xb080, 0xa882, 0xb084, 0xa886, 0x901e, 0xd6c4, 0x0190,
+ 0x735c, 0xab86, 0x83ff, 0x0170, 0x938a, 0x0009, 0x0210, 0x2019,
+ 0x0008, 0x0036, 0x2308, 0x2019, 0x0018, 0x2011, 0x0025, 0x080c,
+ 0xc7ad, 0x003e, 0xd6cc, 0x01e8, 0x7154, 0xa98a, 0x81ff, 0x01c8,
+ 0x9192, 0x0021, 0x1260, 0x8304, 0x9098, 0x0018, 0x2011, 0x0029,
+ 0x080c, 0xc7ad, 0x2011, 0x0205, 0x2013, 0x0000, 0x0050, 0xb068,
+ 0xd0fc, 0x0120, 0x2009, 0x0020, 0xa98a, 0x0c68, 0x2950, 0x080c,
+ 0xc74c, 0x080c, 0x1abc, 0x009e, 0x00ee, 0x00ae, 0x007e, 0x0005,
+ 0x2001, 0x1989, 0x2004, 0x604a, 0x0096, 0x6114, 0x2148, 0xa83c,
+ 0xa940, 0x9105, 0x1118, 0xa87c, 0xc0dc, 0xa87e, 0x6003, 0x0002,
+ 0x080c, 0xd383, 0x0904, 0xc47b, 0x604b, 0x0000, 0x6010, 0x00b6,
+ 0x2058, 0xb800, 0x00be, 0xd0bc, 0x1500, 0xd1cc, 0x0904, 0xc43f,
+ 0xa978, 0xa868, 0xd0fc, 0x0904, 0xc400, 0x0016, 0xa87c, 0x0006,
+ 0xa880, 0x0006, 0x00a6, 0x2150, 0xb174, 0x9184, 0x00ff, 0x90b6,
+ 0x0002, 0x0904, 0xc3cd, 0x9086, 0x0028, 0x1904, 0xc3b9, 0xa87b,
+ 0x001c, 0xb07b, 0x001c, 0x0804, 0xc3d5, 0x6024, 0xd0f4, 0x11d0,
+ 0xa838, 0xaa34, 0x9205, 0x09c8, 0xa838, 0xaa90, 0x9206, 0x1120,
+ 0xa88c, 0xaa34, 0x9206, 0x0988, 0x6024, 0xd0d4, 0x1148, 0xa9ac,
+ 0xa834, 0x9102, 0x603a, 0xa9b0, 0xa838, 0x9103, 0x603e, 0x6024,
+ 0xc0f5, 0x6026, 0x6010, 0x00b6, 0x2058, 0xb83c, 0x8000, 0xb83e,
+ 0x00be, 0x601c, 0xc0fc, 0x601e, 0x9006, 0xa876, 0xa892, 0xa88e,
+ 0xa87c, 0xc0e4, 0xa87e, 0xd0cc, 0x0140, 0xc0cc, 0xa87e, 0x0096,
+ 0xa878, 0x2048, 0x080c, 0x0fff, 0x009e, 0x080c, 0xcf7f, 0x0804,
+ 0xc47b, 0xd1dc, 0x0158, 0xa87b, 0x0015, 0xb07b, 0x0015, 0x080c,
+ 0xd220, 0x0118, 0xb174, 0xc1dc, 0xb176, 0x0078, 0xd1d4, 0x0128,
+ 0xa87b, 0x0007, 0xb07b, 0x0007, 0x0040, 0xa87c, 0xd0ac, 0x0128,
+ 0xa834, 0xa938, 0x9115, 0x190c, 0xc24b, 0xa87c, 0xb07e, 0xa890,
+ 0xb092, 0xa88c, 0xb08e, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0019,
+ 0x20a0, 0x20a9, 0x0020, 0x8a06, 0x8006, 0x8007, 0x9094, 0x003f,
+ 0x22e0, 0x9084, 0xffc0, 0x9080, 0x0019, 0x2098, 0x4003, 0x00ae,
+ 0x000e, 0xa882, 0x000e, 0xc0cc, 0xa87e, 0x080c, 0xd300, 0x001e,
+ 0xa874, 0x0006, 0x2148, 0x080c, 0x0fff, 0x001e, 0x0804, 0xc46c,
+ 0x0016, 0x00a6, 0x2150, 0xb174, 0x9184, 0x00ff, 0x90b6, 0x0002,
+ 0x01e0, 0x9086, 0x0028, 0x1128, 0xa87b, 0x001c, 0xb07b, 0x001c,
+ 0x00e0, 0xd1dc, 0x0158, 0xa87b, 0x0015, 0xb07b, 0x0015, 0x080c,
+ 0xd220, 0x0118, 0xb174, 0xc1dc, 0xb176, 0x0078, 0xd1d4, 0x0128,
+ 0xa87b, 0x0007, 0xb07b, 0x0007, 0x0040, 0xa87c, 0xd0ac, 0x0128,
+ 0xa834, 0xa938, 0x9115, 0x190c, 0xc24b, 0xa890, 0xb092, 0xa88c,
+ 0xb08e, 0xa87c, 0xb07e, 0x00ae, 0x080c, 0x0fff, 0x009e, 0x080c,
+ 0xd300, 0xa974, 0x0016, 0x080c, 0xc79d, 0x001e, 0x0468, 0xa867,
+ 0x0103, 0xa974, 0x9184, 0x00ff, 0x90b6, 0x0002, 0x01b0, 0x9086,
+ 0x0028, 0x1118, 0xa87b, 0x001c, 0x00d0, 0xd1dc, 0x0148, 0xa87b,
+ 0x0015, 0x080c, 0xd220, 0x0118, 0xa974, 0xc1dc, 0xa976, 0x0078,
+ 0xd1d4, 0x0118, 0xa87b, 0x0007, 0x0050, 0xa87b, 0x0000, 0xa87c,
+ 0xd0ac, 0x0128, 0xa834, 0xa938, 0x9115, 0x190c, 0xc24b, 0xa974,
+ 0x0016, 0x080c, 0x6d26, 0x001e, 0x6010, 0x00b6, 0x2058, 0xba3c,
+ 0xb8d0, 0x0016, 0x9005, 0x190c, 0x68ae, 0x001e, 0x00be, 0xd1e4,
+ 0x1120, 0x080c, 0xaf4e, 0x009e, 0x0005, 0x080c, 0xcf42, 0x0cd8,
+ 0x6114, 0x0096, 0x2148, 0xa97c, 0x080c, 0xd383, 0x190c, 0x1adc,
+ 0x009e, 0x0005, 0x0096, 0x6114, 0x2148, 0xa83c, 0xa940, 0x9105,
+ 0x01e8, 0xa877, 0x0000, 0xa87b, 0x0000, 0xa867, 0x0103, 0x00b6,
+ 0x6010, 0x2058, 0xa834, 0xa938, 0x9115, 0x11a0, 0x080c, 0x6d26,
+ 0xba3c, 0x8211, 0x0208, 0xba3e, 0xb8d0, 0x9005, 0x0110, 0x080c,
+ 0x68ae, 0x080c, 0xaf4e, 0x00be, 0x009e, 0x0005, 0xa87c, 0xc0dc,
+ 0xa87e, 0x08f8, 0xb800, 0xd0bc, 0x1120, 0xa834, 0x080c, 0xc24b,
+ 0x0c28, 0xa880, 0xd0bc, 0x1dc8, 0x080c, 0xcf7f, 0x0c60, 0x080c,
+ 0x97f6, 0x0010, 0x080c, 0x9851, 0x601c, 0xd084, 0x0110, 0x080c,
+ 0x1af0, 0x080c, 0xcc33, 0x01f0, 0x0096, 0x6114, 0x2148, 0x080c,
+ 0xce4a, 0x1118, 0x080c, 0xb93c, 0x00a0, 0xa867, 0x0103, 0x2009,
+ 0x180c, 0x210c, 0xd18c, 0x1198, 0xd184, 0x1170, 0x6108, 0xa97a,
+ 0x918e, 0x0029, 0x1110, 0x080c, 0xeaee, 0xa877, 0x0000, 0x080c,
+ 0x6f11, 0x009e, 0x0804, 0xaf89, 0xa87b, 0x0004, 0x0cb0, 0xa87b,
+ 0x0004, 0x0c98, 0x9182, 0x0057, 0x1220, 0x9182, 0x0040, 0x0208,
+ 0x000a, 0x0005, 0xc511, 0xc511, 0xc511, 0xc511, 0xc511, 0xc513,
+ 0xc511, 0xc511, 0xc511, 0xc511, 0xc511, 0xc511, 0xc511, 0xc511,
+ 0xc511, 0xc511, 0xc511, 0xc511, 0xc511, 0xc511, 0xc537, 0xc511,
+ 0xc511, 0x080c, 0x0d79, 0x080c, 0x5828, 0x01f8, 0x6014, 0x7144,
+ 0x918c, 0x0fff, 0x9016, 0xd1c4, 0x0118, 0x7264, 0x9294, 0x00ff,
+ 0x0096, 0x904d, 0x0188, 0xa87b, 0x0000, 0xa864, 0x9086, 0x0139,
+ 0x0128, 0xa867, 0x0103, 0xa976, 0xaa96, 0x0030, 0xa897, 0x4000,
+ 0xa99a, 0xaa9e, 0x080c, 0x6f11, 0x009e, 0x0804, 0xaf4e, 0x080c,
+ 0x5828, 0x0dd8, 0x6014, 0x900e, 0x9016, 0x0c10, 0x9182, 0x0085,
+ 0x0002, 0xc550, 0xc54e, 0xc54e, 0xc55c, 0xc54e, 0xc54e, 0xc54e,
+ 0xc54e, 0xc54e, 0xc54e, 0xc54e, 0xc54e, 0xc54e, 0x080c, 0x0d79,
+ 0x6003, 0x0001, 0x6106, 0x0126, 0x2091, 0x8000, 0x2009, 0x8020,
+ 0x080c, 0x9420, 0x012e, 0x0005, 0x0026, 0x0056, 0x00d6, 0x00e6,
+ 0x2071, 0x0260, 0x7224, 0x6216, 0x7220, 0x080c, 0xcc21, 0x01f8,
+ 0x2268, 0x6800, 0x9086, 0x0000, 0x01d0, 0x6010, 0x6d10, 0x952e,
+ 0x11b0, 0x00c6, 0x2d60, 0x00d6, 0x080c, 0xc80e, 0x00de, 0x00ce,
+ 0x0158, 0x702c, 0xd084, 0x1118, 0x080c, 0xc7d8, 0x0010, 0x6803,
+ 0x0002, 0x6007, 0x0086, 0x0028, 0x080c, 0xc7fa, 0x0d90, 0x6007,
+ 0x0087, 0x6003, 0x0001, 0x2009, 0x8020, 0x080c, 0x9420, 0x7220,
+ 0x080c, 0xcc21, 0x0178, 0x6810, 0x00b6, 0x2058, 0xb800, 0x00be,
+ 0xd0bc, 0x0140, 0x6824, 0xd0ec, 0x0128, 0x00c6, 0x2d60, 0x080c,
+ 0xcf7f, 0x00ce, 0x00ee, 0x00de, 0x005e, 0x002e, 0x0005, 0x9186,
+ 0x0013, 0x1160, 0x6004, 0x908a, 0x0085, 0x0a0c, 0x0d79, 0x908a,
+ 0x0092, 0x1a0c, 0x0d79, 0x9082, 0x0085, 0x00e2, 0x9186, 0x0027,
+ 0x0120, 0x9186, 0x0014, 0x190c, 0x0d79, 0x080c, 0x97f6, 0x0096,
+ 0x6014, 0x2048, 0x080c, 0xcc33, 0x0140, 0xa867, 0x0103, 0xa877,
+ 0x0000, 0xa87b, 0x0029, 0x080c, 0x6f11, 0x009e, 0x080c, 0xaf89,
+ 0x0804, 0x98bc, 0xc5df, 0xc5e1, 0xc5e1, 0xc5df, 0xc5df, 0xc5df,
+ 0xc5df, 0xc5df, 0xc5df, 0xc5df, 0xc5df, 0xc5df, 0xc5df, 0x080c,
+ 0x0d79, 0x080c, 0xaf89, 0x0005, 0x9186, 0x0013, 0x1130, 0x6004,
+ 0x9082, 0x0085, 0x2008, 0x0804, 0xc630, 0x9186, 0x0027, 0x1558,
+ 0x080c, 0x97f6, 0x080c, 0x32fb, 0x080c, 0xd372, 0x0096, 0x6014,
+ 0x2048, 0x080c, 0xcc33, 0x0150, 0xa867, 0x0103, 0xa877, 0x0000,
+ 0xa87b, 0x0029, 0x080c, 0x6f11, 0x080c, 0xce24, 0x009e, 0x080c,
+ 0xaf4e, 0x0005, 0x9186, 0x0089, 0x0118, 0x9186, 0x008a, 0x1140,
+ 0x080c, 0xad4d, 0x0128, 0x9086, 0x000c, 0x0904, 0xc668, 0x0000,
+ 0x080c, 0xb009, 0x0c70, 0x9186, 0x0014, 0x1d60, 0x080c, 0x97f6,
+ 0x0096, 0x6014, 0x2048, 0x080c, 0xcc33, 0x0d00, 0xa867, 0x0103,
+ 0xa877, 0x0000, 0xa87b, 0x0006, 0xa880, 0xc0ec, 0xa882, 0x0890,
+ 0x0002, 0xc640, 0xc63e, 0xc63e, 0xc63e, 0xc63e, 0xc63e, 0xc654,
+ 0xc63e, 0xc63e, 0xc63e, 0xc63e, 0xc63e, 0xc63e, 0x080c, 0x0d79,
+ 0x6034, 0x908c, 0xff00, 0x810f, 0x9186, 0x0039, 0x0118, 0x9186,
+ 0x0035, 0x1118, 0x2001, 0x1987, 0x0010, 0x2001, 0x1988, 0x2004,
+ 0x601a, 0x6003, 0x000c, 0x0005, 0x6034, 0x908c, 0xff00, 0x810f,
+ 0x9186, 0x0039, 0x0118, 0x9186, 0x0035, 0x1118, 0x2001, 0x1987,
+ 0x0010, 0x2001, 0x1988, 0x2004, 0x601a, 0x6003, 0x000e, 0x0005,
+ 0x9182, 0x0092, 0x1220, 0x9182, 0x0085, 0x0208, 0x0012, 0x0804,
+ 0xb009, 0xc67e, 0xc67e, 0xc67e, 0xc67e, 0xc680, 0xc6cd, 0xc67e,
+ 0xc67e, 0xc67e, 0xc67e, 0xc67e, 0xc67e, 0xc67e, 0x080c, 0x0d79,
+ 0x0096, 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x0168,
+ 0x6034, 0x908c, 0xff00, 0x810f, 0x9186, 0x0039, 0x0118, 0x9186,
+ 0x0035, 0x1118, 0x009e, 0x0804, 0xc6e1, 0x080c, 0xcc33, 0x1118,
+ 0x080c, 0xce24, 0x0068, 0x6014, 0x2048, 0x080c, 0xd389, 0x1110,
+ 0x080c, 0xce24, 0xa867, 0x0103, 0x080c, 0xd33d, 0x080c, 0x6f11,
+ 0x00d6, 0x2c68, 0x080c, 0xaef8, 0x01d0, 0x6003, 0x0001, 0x6007,
+ 0x001e, 0x600b, 0xffff, 0x2009, 0x026e, 0x210c, 0x613a, 0x2009,
+ 0x026f, 0x210c, 0x613e, 0x6910, 0x6112, 0x080c, 0xd0ce, 0x695c,
+ 0x615e, 0x6023, 0x0001, 0x2009, 0x8020, 0x080c, 0x9420, 0x2d60,
+ 0x00de, 0x080c, 0xaf4e, 0x009e, 0x0005, 0x6010, 0x00b6, 0x2058,
+ 0xb800, 0x00be, 0xd0bc, 0x05a0, 0x6034, 0x908c, 0xff00, 0x810f,
+ 0x9186, 0x0035, 0x0130, 0x9186, 0x001e, 0x0118, 0x9186, 0x0039,
+ 0x1538, 0x00d6, 0x2c68, 0x080c, 0xd2d3, 0x11f0, 0x080c, 0xaef8,
+ 0x01d8, 0x6106, 0x6003, 0x0001, 0x6023, 0x0001, 0x6910, 0x6112,
+ 0x692c, 0x612e, 0x6930, 0x6132, 0x6934, 0x918c, 0x00ff, 0x6136,
+ 0x6938, 0x613a, 0x693c, 0x613e, 0x695c, 0x615e, 0x080c, 0xd0ce,
+ 0x2009, 0x8020, 0x080c, 0x9420, 0x2d60, 0x00de, 0x0804, 0xaf4e,
+ 0x0096, 0x6014, 0x2048, 0x080c, 0xcc33, 0x01c8, 0xa867, 0x0103,
+ 0xa880, 0xd0b4, 0x0128, 0xc0ec, 0xa882, 0xa87b, 0x0006, 0x0048,
+ 0xd0bc, 0x0118, 0xa87b, 0x0002, 0x0020, 0xa87b, 0x0005, 0x080c,
+ 0xcf3e, 0xa877, 0x0000, 0x080c, 0x6f11, 0x080c, 0xce24, 0x009e,
+ 0x0804, 0xaf4e, 0x0016, 0x0096, 0x6014, 0x2048, 0x080c, 0xcc33,
+ 0x0140, 0xa867, 0x0103, 0xa87b, 0x0028, 0xa877, 0x0000, 0x080c,
+ 0x6f11, 0x009e, 0x001e, 0x9186, 0x0013, 0x0158, 0x9186, 0x0014,
+ 0x0130, 0x9186, 0x0027, 0x0118, 0x080c, 0xb009, 0x0020, 0x080c,
+ 0x97f6, 0x080c, 0xaf89, 0x0005, 0x0056, 0x0066, 0x0096, 0x00a6,
+ 0x2029, 0x0001, 0x9182, 0x0101, 0x1208, 0x0010, 0x2009, 0x0100,
+ 0x2130, 0x8304, 0x9098, 0x0018, 0x2009, 0x0020, 0x2011, 0x0029,
+ 0x080c, 0xc7ad, 0x96b2, 0x0020, 0xb004, 0x904d, 0x0110, 0x080c,
+ 0x0fff, 0x080c, 0x104d, 0x0520, 0x8528, 0xa867, 0x0110, 0xa86b,
+ 0x0000, 0x2920, 0xb406, 0x968a, 0x003d, 0x1228, 0x2608, 0x2011,
+ 0x001b, 0x0499, 0x00a8, 0x96b2, 0x003c, 0x2009, 0x003c, 0x2950,
+ 0x2011, 0x001b, 0x0451, 0x0c28, 0x2001, 0x0205, 0x2003, 0x0000,
+ 0x00ae, 0x852f, 0x95ad, 0x0003, 0xb566, 0x95ac, 0x0000, 0x0048,
+ 0x2001, 0x0205, 0x2003, 0x0000, 0x00ae, 0x852f, 0x95ad, 0x0003,
+ 0xb566, 0x009e, 0x006e, 0x005e, 0x0005, 0x00a6, 0x89ff, 0x0158,
+ 0xa804, 0x9055, 0x0130, 0xa807, 0x0000, 0x080c, 0x6f11, 0x2a48,
+ 0x0cb8, 0x080c, 0x6f11, 0x00ae, 0x0005, 0x00f6, 0x2079, 0x0200,
+ 0x7814, 0x9085, 0x0080, 0x7816, 0xd184, 0x0108, 0x8108, 0x810c,
+ 0x20a9, 0x0001, 0xa860, 0x20e8, 0xa85c, 0x9200, 0x20a0, 0x20e1,
+ 0x0000, 0x2300, 0x9e00, 0x2098, 0x4003, 0x8318, 0x9386, 0x0020,
+ 0x1148, 0x2018, 0x2300, 0x9e00, 0x2098, 0x7814, 0x8000, 0x9085,
+ 0x0080, 0x7816, 0x8109, 0x1d80, 0x7817, 0x0000, 0x00fe, 0x0005,
+ 0x6920, 0x9186, 0x0003, 0x0118, 0x9186, 0x0002, 0x11d0, 0x00c6,
+ 0x00d6, 0x00e6, 0x2d60, 0x0096, 0x6014, 0x2048, 0x080c, 0xcc33,
+ 0x0150, 0x2001, 0x0006, 0xa980, 0xc1d5, 0x080c, 0x715d, 0x080c,
+ 0x6f05, 0x080c, 0xce24, 0x009e, 0x080c, 0xaf89, 0x00ee, 0x00de,
+ 0x00ce, 0x0005, 0x00c6, 0x702c, 0xd084, 0x1170, 0x6008, 0x2060,
+ 0x6020, 0x9086, 0x0002, 0x1140, 0x6104, 0x9186, 0x0085, 0x0118,
+ 0x9186, 0x008b, 0x1108, 0x9006, 0x00ce, 0x0005, 0x0066, 0x0126,
+ 0x2091, 0x8000, 0x2031, 0x0001, 0x6020, 0x9084, 0x000f, 0x0083,
+ 0x012e, 0x006e, 0x0005, 0x0126, 0x2091, 0x8000, 0x0066, 0x2031,
+ 0x0000, 0x6020, 0x9084, 0x000f, 0x001b, 0x006e, 0x012e, 0x0005,
+ 0xc860, 0xc860, 0xc85b, 0xc884, 0xc838, 0xc85b, 0xc83a, 0xc85b,
+ 0xc85b, 0x92df, 0xc85b, 0xc85b, 0xc85b, 0xc838, 0xc838, 0xc838,
+ 0x080c, 0x0d79, 0x6010, 0x9080, 0x0000, 0x2004, 0xd0bc, 0x190c,
+ 0xc884, 0x0036, 0x6014, 0x0096, 0x2048, 0xa880, 0x009e, 0xd0cc,
+ 0x0118, 0x2019, 0x000c, 0x0038, 0xd094, 0x0118, 0x2019, 0x000d,
+ 0x0010, 0x2019, 0x0010, 0x080c, 0xe28e, 0x6023, 0x0006, 0x6003,
+ 0x0007, 0x003e, 0x0005, 0x9006, 0x0005, 0x9085, 0x0001, 0x0005,
+ 0x0096, 0x86ff, 0x11e8, 0x6014, 0x2048, 0x080c, 0xcc33, 0x01d0,
+ 0x6043, 0xffff, 0xa864, 0x9086, 0x0139, 0x1128, 0xa87b, 0x0005,
+ 0xa883, 0x0000, 0x0028, 0x900e, 0x2001, 0x0005, 0x080c, 0x715d,
+ 0x080c, 0xcf3e, 0x080c, 0x6f05, 0x080c, 0xaf89, 0x9085, 0x0001,
+ 0x009e, 0x0005, 0x9006, 0x0ce0, 0x080c, 0xaaf7, 0x080c, 0xd397,
+ 0x6000, 0x908a, 0x0010, 0x1a0c, 0x0d79, 0x002b, 0x0106, 0x080c,
+ 0xab13, 0x010e, 0x0005, 0xc8a3, 0xc8d3, 0xc8a5, 0xc8fa, 0xc8ce,
+ 0xc8a3, 0xc85b, 0xc860, 0xc860, 0xc85b, 0xc85b, 0xc85b, 0xc85b,
+ 0xc85b, 0xc85b, 0xc85b, 0x080c, 0x0d79, 0x86ff, 0x1520, 0x6020,
+ 0x9086, 0x0006, 0x0500, 0x0096, 0x6014, 0x2048, 0x080c, 0xcc33,
+ 0x0168, 0xa87c, 0xd0cc, 0x0140, 0x0096, 0xc0cc, 0xa87e, 0xa878,
+ 0x2048, 0x080c, 0x0fff, 0x009e, 0x080c, 0xcf3e, 0x009e, 0x080c,
+ 0xd317, 0x6007, 0x0085, 0x6003, 0x000b, 0x6023, 0x0002, 0x2009,
+ 0x8020, 0x080c, 0x9402, 0x9085, 0x0001, 0x0005, 0x0066, 0x080c,
+ 0x1af0, 0x006e, 0x0890, 0x00e6, 0x2071, 0x19e9, 0x7030, 0x9c06,
+ 0x1120, 0x080c, 0xa311, 0x00ee, 0x0840, 0x6020, 0x9084, 0x000f,
+ 0x9086, 0x0006, 0x1150, 0x0086, 0x0096, 0x2049, 0x0001, 0x2c40,
+ 0x080c, 0xa462, 0x009e, 0x008e, 0x0040, 0x0066, 0x080c, 0xa20d,
+ 0x190c, 0x0d79, 0x080c, 0xa21b, 0x006e, 0x00ee, 0x1904, 0xc8a5,
+ 0x0804, 0xc85b, 0x0036, 0x00e6, 0x2071, 0x19e9, 0x704c, 0x9c06,
+ 0x1138, 0x901e, 0x080c, 0xa391, 0x00ee, 0x003e, 0x0804, 0xc8a5,
+ 0x080c, 0xa59c, 0x00ee, 0x003e, 0x1904, 0xc8a5, 0x0804, 0xc85b,
+ 0x00c6, 0x0066, 0x6020, 0x9084, 0x000f, 0x001b, 0x006e, 0x00ce,
+ 0x0005, 0xc930, 0xc9fe, 0xcb68, 0xc938, 0xaf89, 0xc930, 0xe280,
+ 0xd37f, 0xc9fe, 0x92a6, 0xcbf4, 0xc929, 0xc929, 0xc929, 0xc929,
+ 0xc929, 0x080c, 0x0d79, 0x080c, 0xce4a, 0x1110, 0x080c, 0xb93c,
+ 0x0005, 0x080c, 0x97f6, 0x0804, 0xaf4e, 0x601b, 0x0001, 0x0005,
+ 0x080c, 0xcc33, 0x0130, 0x6014, 0x0096, 0x2048, 0x2c00, 0xa896,
+ 0x009e, 0x080c, 0xaaf7, 0x080c, 0xd397, 0x6000, 0x908a, 0x0010,
+ 0x1a0c, 0x0d79, 0x0013, 0x0804, 0xab13, 0xc95d, 0xc95f, 0xc989,
+ 0xc99d, 0xc9ca, 0xc95d, 0xc930, 0xc930, 0xc930, 0xc9a4, 0xc9a4,
+ 0xc95d, 0xc95d, 0xc95d, 0xc95d, 0xc9ae, 0x080c, 0x0d79, 0x00e6,
+ 0x6014, 0x0096, 0x2048, 0xa880, 0xc0b5, 0xa882, 0x009e, 0x2071,
+ 0x19e9, 0x7030, 0x9c06, 0x01d0, 0x0066, 0x080c, 0xa20d, 0x190c,
+ 0x0d79, 0x080c, 0xa21b, 0x006e, 0x080c, 0xd317, 0x6007, 0x0085,
+ 0x6003, 0x000b, 0x6023, 0x0002, 0x2001, 0x1988, 0x2004, 0x601a,
+ 0x2009, 0x8020, 0x080c, 0x9402, 0x00ee, 0x0005, 0x601b, 0x0001,
+ 0x0cd8, 0x0096, 0x6014, 0x2048, 0xa880, 0xc0b5, 0xa882, 0x009e,
+ 0x080c, 0xd317, 0x6007, 0x0085, 0x6003, 0x000b, 0x6023, 0x0002,
+ 0x2009, 0x8020, 0x080c, 0x9402, 0x0005, 0x080c, 0xaaf7, 0x080c,
+ 0xaccf, 0x080c, 0xab13, 0x0c28, 0x0096, 0x601b, 0x0001, 0x6014,
+ 0x2048, 0xa880, 0xc0b5, 0xa882, 0x009e, 0x0005, 0x080c, 0x5828,
+ 0x01b8, 0x6014, 0x0096, 0x904d, 0x0190, 0xa864, 0xa867, 0x0103,
+ 0xa87b, 0x0006, 0x9086, 0x0139, 0x1150, 0xa867, 0x0139, 0xa87b,
+ 0x0030, 0xa897, 0x4005, 0xa89b, 0x0004, 0x080c, 0x6f11, 0x009e,
+ 0x0804, 0xaf4e, 0x6014, 0x0096, 0x904d, 0x0558, 0xa97c, 0xd1e4,
+ 0x1158, 0x611c, 0xd1fc, 0x0528, 0x6110, 0x00b6, 0x2158, 0xb93c,
+ 0x8109, 0x0208, 0xb93e, 0x00be, 0x080c, 0xab13, 0x2001, 0x180f,
+ 0x2004, 0xd0c4, 0x0110, 0x009e, 0x0005, 0xa884, 0x009e, 0x8003,
+ 0x800b, 0x810b, 0x9108, 0x611a, 0x00c6, 0x080c, 0x21a2, 0x00ce,
+ 0x6000, 0x9086, 0x0004, 0x1120, 0x2009, 0x0048, 0x080c, 0xafec,
+ 0x0005, 0x009e, 0x080c, 0x1af0, 0x0804, 0xc989, 0x6000, 0x908a,
+ 0x0010, 0x1a0c, 0x0d79, 0x000b, 0x0005, 0xca15, 0xc935, 0xca17,
+ 0xca15, 0xca17, 0xca17, 0xc931, 0xca15, 0xc92b, 0xc92b, 0xca15,
+ 0xca15, 0xca15, 0xca15, 0xca15, 0xca15, 0x080c, 0x0d79, 0x6010,
0x00b6, 0x2058, 0xb804, 0x9084, 0x00ff, 0x00be, 0x908a, 0x000c,
- 0x1a0c, 0x0d85, 0x00b6, 0x0013, 0x00be, 0x0005, 0xca1a, 0xcae7,
- 0xca1c, 0xca5c, 0xca1c, 0xca5c, 0xca1c, 0xca2a, 0xca1a, 0xca5c,
- 0xca1a, 0xca4b, 0x080c, 0x0d85, 0x6004, 0x908e, 0x0016, 0x05c0,
+ 0x1a0c, 0x0d79, 0x00b6, 0x0013, 0x00be, 0x0005, 0xca32, 0xcaff,
+ 0xca34, 0xca74, 0xca34, 0xca74, 0xca34, 0xca42, 0xca32, 0xca74,
+ 0xca32, 0xca63, 0x080c, 0x0d79, 0x6004, 0x908e, 0x0016, 0x05c0,
0x908e, 0x0004, 0x05a8, 0x908e, 0x0002, 0x0590, 0x908e, 0x0052,
- 0x0904, 0xcae3, 0x6004, 0x080c, 0xce2d, 0x0904, 0xcb00, 0x908e,
- 0x0004, 0x1110, 0x080c, 0x333f, 0x908e, 0x0021, 0x0904, 0xcb04,
- 0x908e, 0x0022, 0x0904, 0xcb4b, 0x908e, 0x003d, 0x0904, 0xcb04,
- 0x908e, 0x0039, 0x0904, 0xcb08, 0x908e, 0x0035, 0x0904, 0xcb08,
+ 0x0904, 0xcafb, 0x6004, 0x080c, 0xce4a, 0x0904, 0xcb18, 0x908e,
+ 0x0004, 0x1110, 0x080c, 0x332a, 0x908e, 0x0021, 0x0904, 0xcb1c,
+ 0x908e, 0x0022, 0x0904, 0xcb63, 0x908e, 0x003d, 0x0904, 0xcb1c,
+ 0x908e, 0x0039, 0x0904, 0xcb20, 0x908e, 0x0035, 0x0904, 0xcb20,
0x908e, 0x001e, 0x0178, 0x908e, 0x0001, 0x1140, 0x6010, 0x2058,
- 0xb804, 0x9084, 0x00ff, 0x9086, 0x0006, 0x0110, 0x080c, 0x3310,
- 0x080c, 0xb91f, 0x0804, 0xaf69, 0x00c6, 0x00d6, 0x6104, 0x9186,
- 0x0016, 0x0904, 0xcad4, 0x9186, 0x0002, 0x1904, 0xcaa9, 0x2001,
- 0x1837, 0x2004, 0xd08c, 0x11c8, 0x080c, 0x76a5, 0x11b0, 0x080c,
- 0xd33e, 0x0138, 0x080c, 0x76c8, 0x1120, 0x080c, 0x75ae, 0x0804,
- 0xcb34, 0x2001, 0x197e, 0x2003, 0x0001, 0x2001, 0x1800, 0x2003,
- 0x0001, 0x080c, 0x75d4, 0x0804, 0xcb34, 0x6010, 0x2058, 0x2001,
- 0x1837, 0x2004, 0xd0ac, 0x1904, 0xcb34, 0xb8a0, 0x9084, 0xff80,
- 0x1904, 0xcb34, 0xb840, 0x9084, 0x00ff, 0x9005, 0x0190, 0x8001,
+ 0xb804, 0x9084, 0x00ff, 0x9086, 0x0006, 0x0110, 0x080c, 0x32fb,
+ 0x080c, 0xb93c, 0x0804, 0xaf89, 0x00c6, 0x00d6, 0x6104, 0x9186,
+ 0x0016, 0x0904, 0xcaec, 0x9186, 0x0002, 0x1904, 0xcac1, 0x2001,
+ 0x1837, 0x2004, 0xd08c, 0x11c8, 0x080c, 0x769d, 0x11b0, 0x080c,
+ 0xd35d, 0x0138, 0x080c, 0x76c0, 0x1120, 0x080c, 0x75a6, 0x0804,
+ 0xcb4c, 0x2001, 0x197e, 0x2003, 0x0001, 0x2001, 0x1800, 0x2003,
+ 0x0001, 0x080c, 0x75cc, 0x0804, 0xcb4c, 0x6010, 0x2058, 0x2001,
+ 0x1837, 0x2004, 0xd0ac, 0x1904, 0xcb4c, 0xb8a0, 0x9084, 0xff80,
+ 0x1904, 0xcb4c, 0xb840, 0x9084, 0x00ff, 0x9005, 0x0190, 0x8001,
0xb842, 0x6017, 0x0000, 0x6023, 0x0007, 0x601b, 0x0398, 0x604b,
- 0x0000, 0x080c, 0xaed8, 0x0128, 0x2b00, 0x6012, 0x6023, 0x0001,
+ 0x0000, 0x080c, 0xaef8, 0x0128, 0x2b00, 0x6012, 0x6023, 0x0001,
0x0458, 0x00de, 0x00ce, 0x6004, 0x908e, 0x0002, 0x11a0, 0x6010,
0x2058, 0xb8a0, 0x9086, 0x007e, 0x1170, 0x2009, 0x1837, 0x2104,
- 0xc085, 0x200a, 0x00e6, 0x2071, 0x1800, 0x080c, 0x6111, 0x00ee,
- 0x080c, 0xb91f, 0x0030, 0x080c, 0xb91f, 0x080c, 0x3310, 0x080c,
- 0xd353, 0x00e6, 0x0126, 0x2091, 0x8000, 0x080c, 0x333f, 0x012e,
- 0x00ee, 0x080c, 0xaf69, 0x0005, 0x2001, 0x0002, 0x080c, 0x66cf,
- 0x6003, 0x0001, 0x6007, 0x0002, 0x080c, 0x942f, 0x080c, 0x98bf,
- 0x00de, 0x00ce, 0x0c80, 0x080c, 0x333f, 0x0804, 0xca58, 0x00c6,
+ 0xc085, 0x200a, 0x00e6, 0x2071, 0x1800, 0x080c, 0x610b, 0x00ee,
+ 0x080c, 0xb93c, 0x0030, 0x080c, 0xb93c, 0x080c, 0x32fb, 0x080c,
+ 0xd372, 0x00e6, 0x0126, 0x2091, 0x8000, 0x080c, 0x332a, 0x012e,
+ 0x00ee, 0x080c, 0xaf89, 0x0005, 0x2001, 0x0002, 0x080c, 0x66c9,
+ 0x6003, 0x0001, 0x6007, 0x0002, 0x080c, 0x9427, 0x080c, 0x98bc,
+ 0x00de, 0x00ce, 0x0c80, 0x080c, 0x332a, 0x0804, 0xca70, 0x00c6,
0x00d6, 0x6104, 0x9186, 0x0016, 0x0d38, 0x6010, 0x2058, 0xb840,
- 0x9084, 0x00ff, 0x9005, 0x0904, 0xcaa9, 0x8001, 0xb842, 0x6003,
- 0x0001, 0x080c, 0x942f, 0x080c, 0x98bf, 0x00de, 0x00ce, 0x0898,
- 0x080c, 0xb91f, 0x0804, 0xca5a, 0x080c, 0xb95b, 0x0804, 0xca5a,
- 0x00d6, 0x2c68, 0x6104, 0x080c, 0xd2b6, 0x00de, 0x0118, 0x080c,
- 0xaf2e, 0x0408, 0x6004, 0x8007, 0x6134, 0x918c, 0x00ff, 0x9105,
+ 0x9084, 0x00ff, 0x9005, 0x0904, 0xcac1, 0x8001, 0xb842, 0x6003,
+ 0x0001, 0x080c, 0x9427, 0x080c, 0x98bc, 0x00de, 0x00ce, 0x0898,
+ 0x080c, 0xb93c, 0x0804, 0xca72, 0x080c, 0xb978, 0x0804, 0xca72,
+ 0x00d6, 0x2c68, 0x6104, 0x080c, 0xd2d3, 0x00de, 0x0118, 0x080c,
+ 0xaf4e, 0x0408, 0x6004, 0x8007, 0x6134, 0x918c, 0x00ff, 0x9105,
0x6036, 0x6007, 0x0085, 0x6003, 0x000b, 0x6023, 0x0002, 0x603c,
0x600a, 0x2001, 0x1988, 0x2004, 0x601a, 0x602c, 0x2c08, 0x2060,
0x6024, 0xd0b4, 0x0108, 0xc085, 0xc0b5, 0x6026, 0x2160, 0x2009,
- 0x8020, 0x080c, 0x9428, 0x0005, 0x00de, 0x00ce, 0x080c, 0xb91f,
- 0x080c, 0x3310, 0x00e6, 0x0126, 0x2091, 0x8000, 0x080c, 0x333f,
+ 0x8020, 0x080c, 0x9420, 0x0005, 0x00de, 0x00ce, 0x080c, 0xb93c,
+ 0x080c, 0x32fb, 0x00e6, 0x0126, 0x2091, 0x8000, 0x080c, 0x332a,
0x6017, 0x0000, 0x6023, 0x0007, 0x601b, 0x0398, 0x604b, 0x0000,
- 0x012e, 0x00ee, 0x0005, 0x080c, 0xb36d, 0x1904, 0xcb00, 0x0005,
- 0x6000, 0x908a, 0x0016, 0x1a0c, 0x0d85, 0x0096, 0x00d6, 0x001b,
- 0x00de, 0x009e, 0x0005, 0xcb6b, 0xcb6b, 0xcb6b, 0xcb6b, 0xcb6b,
- 0xcb6b, 0xcb6b, 0xcb6b, 0xcb6b, 0xc917, 0xcb6b, 0xc91c, 0xcb6d,
- 0xc91c, 0xcb87, 0xcb6b, 0x080c, 0x0d85, 0x6004, 0x9086, 0x008b,
+ 0x012e, 0x00ee, 0x0005, 0x080c, 0xb38a, 0x1904, 0xcb18, 0x0005,
+ 0x6000, 0x908a, 0x0010, 0x1a0c, 0x0d79, 0x0096, 0x00d6, 0x001b,
+ 0x00de, 0x009e, 0x0005, 0xcb83, 0xcb83, 0xcb83, 0xcb83, 0xcb83,
+ 0xcb83, 0xcb83, 0xcb83, 0xcb83, 0xc930, 0xcb83, 0xc935, 0xcb85,
+ 0xc935, 0xcb9f, 0xcb83, 0x080c, 0x0d79, 0x6004, 0x9086, 0x008b,
0x01b0, 0x6034, 0x908c, 0xff00, 0x810f, 0x9186, 0x0035, 0x1130,
0x602c, 0x9080, 0x0009, 0x200c, 0xc185, 0x2102, 0x6007, 0x008b,
- 0x6003, 0x000d, 0x2009, 0x8020, 0x080c, 0x9428, 0x0005, 0x080c,
- 0xd332, 0x0118, 0x080c, 0xd345, 0x0010, 0x080c, 0xd353, 0x080c,
- 0xce07, 0x080c, 0xcc16, 0x0570, 0x080c, 0x3310, 0x080c, 0xcc16,
+ 0x6003, 0x000d, 0x2009, 0x8020, 0x080c, 0x9420, 0x0005, 0x080c,
+ 0xd351, 0x0118, 0x080c, 0xd364, 0x0010, 0x080c, 0xd372, 0x080c,
+ 0xce24, 0x080c, 0xcc33, 0x0570, 0x080c, 0x32fb, 0x080c, 0xcc33,
0x0168, 0x6014, 0x2048, 0xa867, 0x0103, 0xa87b, 0x0006, 0xa877,
- 0x0000, 0xa880, 0xc0ed, 0xa882, 0x080c, 0x6f19, 0x2c68, 0x080c,
- 0xaed8, 0x0150, 0x6810, 0x6012, 0x080c, 0xd0b1, 0x00c6, 0x2d60,
- 0x080c, 0xaf69, 0x00ce, 0x0008, 0x2d60, 0x6017, 0x0000, 0x6023,
- 0x0001, 0x6007, 0x0001, 0x6003, 0x0001, 0x080c, 0x942f, 0x080c,
- 0x98bf, 0x00c8, 0x080c, 0xd332, 0x0138, 0x6034, 0x9086, 0x4000,
- 0x1118, 0x080c, 0x3310, 0x08d0, 0x6034, 0x908c, 0xff00, 0x810f,
- 0x9186, 0x0039, 0x0118, 0x9186, 0x0035, 0x1118, 0x080c, 0x3310,
- 0x0868, 0x080c, 0xaf69, 0x0005, 0x6000, 0x908a, 0x0016, 0x1a0c,
- 0x0d85, 0x0002, 0xcbf2, 0xcbf2, 0xcbf4, 0xcbf4, 0xcbf4, 0xcbf2,
- 0xcbf2, 0xaf69, 0xcbf2, 0xcbf2, 0xcbf2, 0xcbf2, 0xcbf2, 0xcbf2,
- 0xcbf2, 0xcbf2, 0x080c, 0x0d85, 0x080c, 0xaae0, 0x080c, 0xacaf,
- 0x080c, 0xaafc, 0x6114, 0x0096, 0x2148, 0xa87b, 0x0006, 0x080c,
- 0x6f19, 0x009e, 0x0804, 0xaf2e, 0x9284, 0x0003, 0x1158, 0x9282,
- 0x1ddc, 0x0240, 0x2001, 0x181a, 0x2004, 0x9202, 0x1218, 0x9085,
- 0x0001, 0x0005, 0x9006, 0x0ce8, 0x0096, 0x0028, 0x0096, 0x0006,
- 0x6014, 0x2048, 0x000e, 0x0006, 0x9984, 0xf000, 0x9086, 0xf000,
- 0x0110, 0x080c, 0x1104, 0x000e, 0x009e, 0x0005, 0x00e6, 0x00c6,
- 0x0036, 0x0006, 0x0126, 0x2091, 0x8000, 0x2061, 0x1ddc, 0x2071,
- 0x1800, 0x7354, 0x7074, 0x9302, 0x1640, 0x6020, 0x9206, 0x11f8,
- 0x080c, 0xd33e, 0x0180, 0x9286, 0x0001, 0x1168, 0x6004, 0x9086,
- 0x0004, 0x1148, 0x080c, 0x3310, 0x080c, 0xd353, 0x00c6, 0x080c,
- 0xaf69, 0x00ce, 0x0060, 0x080c, 0xd023, 0x0148, 0x080c, 0xce2d,
- 0x1110, 0x080c, 0xb91f, 0x00c6, 0x080c, 0xaf2e, 0x00ce, 0x9ce0,
- 0x001c, 0x7068, 0x9c02, 0x1208, 0x08a0, 0x012e, 0x000e, 0x003e,
- 0x00ce, 0x00ee, 0x0005, 0x00e6, 0x00c6, 0x0016, 0x9188, 0x1000,
- 0x210c, 0x81ff, 0x0128, 0x2061, 0x1b3a, 0x6112, 0x080c, 0x3310,
- 0x9006, 0x0010, 0x9085, 0x0001, 0x001e, 0x00ce, 0x00ee, 0x0005,
- 0x00c6, 0x0126, 0x2091, 0x8000, 0x080c, 0xaed8, 0x01b0, 0x665e,
- 0x2b00, 0x6012, 0x080c, 0x582e, 0x0118, 0x080c, 0xcd49, 0x0168,
- 0x080c, 0xd0b1, 0x6023, 0x0003, 0x2009, 0x004b, 0x080c, 0xafcc,
- 0x9085, 0x0001, 0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd8, 0x00c6,
- 0x0126, 0x2091, 0x8000, 0xbaa0, 0x080c, 0xaf9f, 0x0580, 0x605f,
- 0x0000, 0x2b00, 0x6012, 0x080c, 0xd0b1, 0x6023, 0x0003, 0x0016,
- 0x080c, 0xaae0, 0x080c, 0x95c1, 0x0076, 0x903e, 0x080c, 0x947e,
- 0x2c08, 0x080c, 0xe440, 0x007e, 0x080c, 0xaafc, 0x001e, 0xd184,
- 0x0128, 0x080c, 0xaf2e, 0x9085, 0x0001, 0x0070, 0x080c, 0x582e,
- 0x0128, 0xd18c, 0x1170, 0x080c, 0xcd49, 0x0148, 0x2009, 0x004c,
- 0x080c, 0xafcc, 0x9085, 0x0001, 0x012e, 0x00ce, 0x0005, 0x9006,
- 0x0cd8, 0x2900, 0x6016, 0x0c90, 0x2009, 0x004d, 0x0010, 0x2009,
- 0x004e, 0x00f6, 0x00c6, 0x0046, 0x0016, 0x080c, 0xaed8, 0x2c78,
- 0x05a0, 0x7e5e, 0x2b00, 0x7812, 0x7823, 0x0003, 0x0016, 0x2021,
- 0x0005, 0x080c, 0xcd5b, 0x001e, 0x9186, 0x004d, 0x0118, 0x9186,
- 0x004e, 0x0148, 0x2001, 0x1981, 0x200c, 0xd1fc, 0x0168, 0x2f60,
- 0x080c, 0xaf2e, 0x00d0, 0x2001, 0x1980, 0x200c, 0xd1fc, 0x0120,
- 0x2f60, 0x080c, 0xaf2e, 0x0088, 0x2f60, 0x080c, 0x582e, 0x0138,
- 0xd18c, 0x1118, 0x04f1, 0x0148, 0x0010, 0x2900, 0x7816, 0x001e,
- 0x0016, 0x080c, 0xafcc, 0x9085, 0x0001, 0x001e, 0x004e, 0x00ce,
- 0x00fe, 0x0005, 0x00f6, 0x00c6, 0x0046, 0x080c, 0xaed8, 0x2c78,
- 0x0508, 0x7e5e, 0x2b00, 0x7812, 0x7823, 0x0003, 0x0096, 0x2021,
- 0x0004, 0x0489, 0x009e, 0x2001, 0x197f, 0x200c, 0xd1fc, 0x0120,
- 0x2f60, 0x080c, 0xaf2e, 0x0060, 0x2f60, 0x080c, 0x582e, 0x0120,
- 0xd18c, 0x1160, 0x0071, 0x0130, 0x2009, 0x0052, 0x080c, 0xafcc,
- 0x9085, 0x0001, 0x004e, 0x00ce, 0x00fe, 0x0005, 0x2900, 0x7816,
- 0x0c98, 0x00c6, 0x080c, 0x4bce, 0x00ce, 0x1120, 0x080c, 0xaf2e,
- 0x9006, 0x0005, 0xa867, 0x0000, 0xa86b, 0x8000, 0x2900, 0x6016,
- 0x9085, 0x0001, 0x0005, 0x0096, 0x0076, 0x0126, 0x2091, 0x8000,
- 0x080c, 0xaae0, 0x080c, 0x696b, 0x0158, 0x2001, 0xcd62, 0x0006,
- 0x900e, 0x2400, 0x080c, 0x7165, 0x080c, 0x6f19, 0x000e, 0x0807,
- 0x2418, 0x080c, 0x97c4, 0xbaa0, 0x0086, 0x2041, 0x0001, 0x2039,
- 0x0001, 0x2608, 0x080c, 0x95db, 0x008e, 0x080c, 0x947e, 0x2f08,
- 0x2648, 0x080c, 0xe440, 0xb93c, 0x81ff, 0x090c, 0x96b4, 0x080c,
- 0xaafc, 0x012e, 0x007e, 0x009e, 0x0005, 0x00c6, 0x0126, 0x2091,
- 0x8000, 0x080c, 0xaed8, 0x0190, 0x660a, 0x2b08, 0x6112, 0x080c,
- 0xd0b1, 0x6023, 0x0001, 0x2900, 0x6016, 0x2009, 0x001f, 0x080c,
- 0xafcc, 0x9085, 0x0001, 0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd8,
- 0x00c6, 0x0126, 0x2091, 0x8000, 0x080c, 0xaf9f, 0x01b8, 0x660a,
- 0x2b08, 0x6112, 0x080c, 0xd0b1, 0x6023, 0x0008, 0x2900, 0x6016,
- 0x00f6, 0x2c78, 0x080c, 0x17ad, 0x00fe, 0x2009, 0x0021, 0x080c,
- 0xafcc, 0x9085, 0x0001, 0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd8,
- 0x2009, 0x003d, 0x00c6, 0x0126, 0x0016, 0x2091, 0x8000, 0x080c,
- 0xaed8, 0x0198, 0x660a, 0x2b08, 0x6112, 0x080c, 0xd0b1, 0x6023,
- 0x0001, 0x2900, 0x6016, 0x001e, 0x0016, 0x080c, 0xafcc, 0x9085,
- 0x0001, 0x001e, 0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd0, 0x00c6,
- 0x0126, 0x2091, 0x8000, 0x080c, 0xaf9f, 0x0188, 0x2b08, 0x6112,
- 0x080c, 0xd0b1, 0x6023, 0x0001, 0x2900, 0x6016, 0x2009, 0x0000,
- 0x080c, 0xafcc, 0x9085, 0x0001, 0x012e, 0x00ce, 0x0005, 0x9006,
- 0x0cd8, 0x2009, 0x0044, 0x0830, 0x2009, 0x0049, 0x0818, 0x0026,
- 0x00b6, 0x6210, 0x2258, 0xba3c, 0x82ff, 0x0118, 0x8211, 0xba3e,
- 0x1140, 0xb8d0, 0x9005, 0x0128, 0xb888, 0x9005, 0x1110, 0xb88b,
- 0x0001, 0x00be, 0x002e, 0x0005, 0x0006, 0x0016, 0x6004, 0x908e,
- 0x0002, 0x0140, 0x908e, 0x0003, 0x0128, 0x908e, 0x0004, 0x0110,
- 0x9085, 0x0001, 0x001e, 0x000e, 0x0005, 0x0006, 0x0086, 0x0096,
- 0x6020, 0x9086, 0x0004, 0x01a8, 0x6014, 0x904d, 0x080c, 0xcc16,
- 0x0180, 0xa864, 0x9086, 0x0139, 0x0170, 0x6020, 0x90c6, 0x0003,
- 0x0140, 0x90c6, 0x0002, 0x0128, 0xa868, 0xd0fc, 0x0110, 0x9006,
- 0x0010, 0x9085, 0x0001, 0x009e, 0x008e, 0x000e, 0x0005, 0x00c6,
- 0x0126, 0x2091, 0x8000, 0x080c, 0xaf9f, 0x0198, 0x2b08, 0x6112,
- 0x080c, 0xd0b1, 0x6023, 0x0001, 0x2900, 0x6016, 0x080c, 0x3310,
- 0x2009, 0x0028, 0x080c, 0xafcc, 0x9085, 0x0001, 0x012e, 0x00ce,
- 0x0005, 0x9006, 0x0cd8, 0x9186, 0x0015, 0x11a8, 0x2011, 0x1824,
- 0x2204, 0x9086, 0x0074, 0x1178, 0x00b6, 0x080c, 0xbb81, 0x00be,
- 0x080c, 0xbda6, 0x6003, 0x0001, 0x6007, 0x0029, 0x080c, 0x942f,
- 0x080c, 0x98bf, 0x0078, 0x6014, 0x0096, 0x2048, 0xa868, 0x009e,
- 0xd0fc, 0x0148, 0x2001, 0x0001, 0x080c, 0xd277, 0x080c, 0xb91f,
- 0x080c, 0xaf2e, 0x0005, 0x0096, 0x6014, 0x904d, 0x090c, 0x0d85,
- 0xa87b, 0x0030, 0xa883, 0x0000, 0xa897, 0x4005, 0xa89b, 0x0004,
- 0xa867, 0x0139, 0x0126, 0x2091, 0x8000, 0x080c, 0x6f19, 0x012e,
- 0x009e, 0x080c, 0xaf2e, 0x0c30, 0x0096, 0x9186, 0x0016, 0x1128,
- 0x2001, 0x0004, 0x080c, 0x66cf, 0x00e8, 0x9186, 0x0015, 0x1510,
- 0x2011, 0x1824, 0x2204, 0x9086, 0x0014, 0x11e0, 0x6010, 0x00b6,
- 0x2058, 0x080c, 0x6824, 0x00be, 0x080c, 0xbe77, 0x1198, 0x6010,
- 0x00b6, 0x2058, 0xb890, 0x00be, 0x9005, 0x0160, 0x2001, 0x0006,
- 0x080c, 0x66cf, 0x6014, 0x2048, 0xa868, 0xd0fc, 0x0170, 0x080c,
- 0xb341, 0x0048, 0x6014, 0x2048, 0xa868, 0xd0fc, 0x0528, 0x080c,
- 0xb91f, 0x080c, 0xaf2e, 0x009e, 0x0005, 0x6014, 0x6310, 0x2358,
- 0x904d, 0x090c, 0x0d85, 0xa87b, 0x0000, 0xa883, 0x0000, 0xa897,
- 0x4000, 0x900e, 0x080c, 0x6a7c, 0x1108, 0xc185, 0xb800, 0xd0bc,
- 0x0108, 0xc18d, 0xa99a, 0x0126, 0x2091, 0x8000, 0x080c, 0x6f19,
- 0x012e, 0x080c, 0xaf2e, 0x08f8, 0x6014, 0x904d, 0x090c, 0x0d85,
- 0xa87b, 0x0030, 0xa883, 0x0000, 0xa897, 0x4005, 0xa89b, 0x0004,
- 0xa867, 0x0139, 0x0126, 0x2091, 0x8000, 0x080c, 0x6f19, 0x012e,
- 0x080c, 0xaf2e, 0x0840, 0xa878, 0x9086, 0x0005, 0x1108, 0x0009,
- 0x0005, 0xa880, 0xc0ad, 0xa882, 0x0005, 0x604b, 0x0000, 0x6017,
- 0x0000, 0x6003, 0x0001, 0x6007, 0x0050, 0x2009, 0x8023, 0x080c,
- 0x9428, 0x0005, 0x00c6, 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be,
- 0xd0bc, 0x0130, 0x0066, 0x6020, 0x9084, 0x000f, 0x001b, 0x006e,
- 0x00ce, 0x0005, 0xc917, 0xcf54, 0xcf54, 0xcf57, 0xe779, 0xe794,
- 0xe797, 0xc917, 0xc917, 0xc917, 0xc917, 0xc917, 0xc917, 0xc917,
- 0xc917, 0xc917, 0x080c, 0x0d85, 0xa001, 0xa001, 0x0005, 0x0096,
- 0x6014, 0x904d, 0x0118, 0xa87c, 0xd0e4, 0x1110, 0x009e, 0x0010,
- 0x009e, 0x0005, 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc,
- 0x0550, 0x2001, 0x1834, 0x2004, 0x9005, 0x1540, 0x00f6, 0x2c78,
- 0x080c, 0xaed8, 0x0508, 0x7810, 0x6012, 0x080c, 0xd0b1, 0x7820,
- 0x9086, 0x0003, 0x0128, 0x7808, 0x603a, 0x2f00, 0x603e, 0x0020,
- 0x7808, 0x603e, 0x2f00, 0x603a, 0x602e, 0x6023, 0x0001, 0x6007,
- 0x0035, 0x6003, 0x0001, 0x795c, 0x615e, 0x2009, 0x8020, 0x080c,
- 0x9428, 0x2f60, 0x00fe, 0x0005, 0x2f60, 0x00fe, 0x2001, 0x1989,
- 0x2004, 0x604a, 0x0005, 0x0016, 0x0096, 0x6814, 0x2048, 0x681c,
- 0xd0fc, 0xc0fc, 0x681e, 0xa87c, 0x1108, 0xd0e4, 0x0180, 0xc0e4,
- 0xa87e, 0xa877, 0x0000, 0xa893, 0x0000, 0xa88f, 0x0000, 0xd0cc,
- 0x0130, 0xc0cc, 0xa87e, 0xa878, 0x2048, 0x080c, 0x100b, 0x6830,
- 0x6036, 0x908e, 0x0001, 0x0148, 0x6803, 0x0002, 0x9086, 0x0005,
- 0x0170, 0x9006, 0x602e, 0x6032, 0x00d0, 0x681c, 0xc085, 0x681e,
- 0x6803, 0x0004, 0x6824, 0xc0f4, 0x9085, 0x0c00, 0x6826, 0x6814,
- 0x2048, 0xa8ac, 0x6938, 0x9102, 0xa8b0, 0x693c, 0x9103, 0x1e48,
- 0x683c, 0x602e, 0x6838, 0x9084, 0xfffc, 0x683a, 0x6032, 0x2d00,
- 0x603a, 0x6808, 0x603e, 0x6910, 0x6112, 0x695c, 0x615e, 0x6023,
- 0x0001, 0x6007, 0x0039, 0x6003, 0x0001, 0x2009, 0x8020, 0x080c,
- 0x9428, 0x009e, 0x001e, 0x0005, 0x6024, 0xd0d4, 0x0510, 0xd0f4,
- 0x11f8, 0x6038, 0x940a, 0x603c, 0x9303, 0x0230, 0x9105, 0x0120,
- 0x6024, 0xc0d4, 0xc0f5, 0x0098, 0x643a, 0x633e, 0xac3e, 0xab42,
- 0x0046, 0x0036, 0x2400, 0xacac, 0x9402, 0xa836, 0x2300, 0xabb0,
- 0x9303, 0xa83a, 0x003e, 0x004e, 0x6024, 0xc0d4, 0x0000, 0x6026,
- 0x0005, 0xd0f4, 0x1138, 0xa83c, 0x603a, 0xa840, 0x603e, 0x6024,
- 0xc0f5, 0x6026, 0x0005, 0x0006, 0x0016, 0x6004, 0x908e, 0x0034,
- 0x01b8, 0x908e, 0x0035, 0x01a0, 0x908e, 0x0036, 0x0188, 0x908e,
- 0x0037, 0x0170, 0x908e, 0x0038, 0x0158, 0x908e, 0x0039, 0x0140,
- 0x908e, 0x003a, 0x0128, 0x908e, 0x003b, 0x0110, 0x9085, 0x0001,
- 0x001e, 0x000e, 0x0005, 0x0006, 0x0016, 0x0026, 0x0036, 0x00e6,
- 0x2001, 0x1983, 0x200c, 0x8000, 0x2014, 0x2001, 0x0032, 0x080c,
- 0x936c, 0x2001, 0x1987, 0x82ff, 0x1110, 0x2011, 0x0014, 0x2202,
- 0x2001, 0x1985, 0x200c, 0x8000, 0x2014, 0x2071, 0x196d, 0x711a,
- 0x721e, 0x2001, 0x0064, 0x080c, 0x936c, 0x2001, 0x1988, 0x82ff,
- 0x1110, 0x2011, 0x0014, 0x2202, 0x2001, 0x1989, 0x9288, 0x000a,
- 0x2102, 0x2001, 0x0017, 0x080c, 0xaad1, 0x2001, 0x1a91, 0x2102,
- 0x2001, 0x0032, 0x080c, 0x16b9, 0x080c, 0x6bb6, 0x00ee, 0x003e,
- 0x002e, 0x001e, 0x000e, 0x0005, 0x0006, 0x0016, 0x00e6, 0x2001,
- 0x1987, 0x2003, 0x0028, 0x2001, 0x1988, 0x2003, 0x0014, 0x2071,
- 0x196d, 0x701b, 0x0000, 0x701f, 0x07d0, 0x2001, 0x1989, 0x2009,
- 0x001e, 0x2102, 0x2001, 0x0017, 0x080c, 0xaad1, 0x2001, 0x1a91,
- 0x2102, 0x2001, 0x0032, 0x080c, 0x16b9, 0x00ee, 0x001e, 0x000e,
- 0x0005, 0x0096, 0x6060, 0x904d, 0x0110, 0x080c, 0x108b, 0x009e,
- 0x0005, 0x0005, 0x00c6, 0x0126, 0x2091, 0x8000, 0x080c, 0xaed8,
- 0x0180, 0x2b08, 0x6112, 0x0ca9, 0x6023, 0x0001, 0x2900, 0x6016,
- 0x2009, 0x0033, 0x080c, 0xafcc, 0x9085, 0x0001, 0x012e, 0x00ce,
- 0x0005, 0x9006, 0x0cd8, 0x0096, 0x00e6, 0x00f6, 0x2071, 0x1800,
- 0x9186, 0x0015, 0x1520, 0x7090, 0x9086, 0x0018, 0x0120, 0x7090,
- 0x9086, 0x0014, 0x11e0, 0x6014, 0x2048, 0xaa3c, 0xd2e4, 0x1160,
- 0x2c78, 0x080c, 0x998f, 0x01d8, 0x707c, 0xaa50, 0x9206, 0x1160,
- 0x7080, 0xaa54, 0x9206, 0x1140, 0x6210, 0x00b6, 0x2258, 0xbaa0,
- 0x00be, 0x900e, 0x080c, 0x335f, 0x080c, 0xb341, 0x0020, 0x080c,
- 0xb91f, 0x080c, 0xaf2e, 0x00fe, 0x00ee, 0x009e, 0x0005, 0x7060,
- 0xaa54, 0x9206, 0x0d48, 0x0c80, 0x00c6, 0x0126, 0x2091, 0x8000,
- 0x080c, 0xaed8, 0x0188, 0x2b08, 0x6112, 0x080c, 0xd0b1, 0x6023,
- 0x0001, 0x2900, 0x6016, 0x2009, 0x004d, 0x080c, 0xafcc, 0x9085,
- 0x0001, 0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd8, 0x00c6, 0x0126,
- 0x2091, 0x8000, 0x0016, 0x080c, 0xaed8, 0x0180, 0x2b08, 0x6112,
- 0x080c, 0xd0b1, 0x6023, 0x0001, 0x2900, 0x6016, 0x001e, 0x080c,
- 0xafcc, 0x9085, 0x0001, 0x012e, 0x00ce, 0x0005, 0x001e, 0x9006,
- 0x0cd0, 0x0016, 0x0026, 0x0036, 0x0046, 0x0056, 0x0066, 0x0096,
- 0x00e6, 0x00f6, 0x2071, 0x1800, 0x9186, 0x0015, 0x1568, 0x7190,
- 0x6014, 0x2048, 0xa814, 0x8003, 0x9106, 0x1530, 0x20e1, 0x0000,
- 0x2001, 0x19a1, 0x2003, 0x0000, 0x6014, 0x2048, 0xa830, 0x20a8,
- 0x8906, 0x8006, 0x8007, 0x9094, 0x003f, 0x22e8, 0x9084, 0xffc0,
- 0x9080, 0x001b, 0x20a0, 0x2001, 0x19a1, 0x0016, 0x200c, 0x080c,
- 0xd998, 0x001e, 0xa804, 0x9005, 0x0110, 0x2048, 0x0c38, 0x6014,
- 0x2048, 0xa867, 0x0103, 0x0010, 0x080c, 0xb91f, 0x080c, 0xaf2e,
- 0x00fe, 0x00ee, 0x009e, 0x006e, 0x005e, 0x004e, 0x003e, 0x002e,
- 0x001e, 0x0005, 0x0096, 0x00e6, 0x00f6, 0x2071, 0x1800, 0x9186,
- 0x0015, 0x11b8, 0x7090, 0x9086, 0x0004, 0x1198, 0x6014, 0x2048,
- 0x2c78, 0x080c, 0x998f, 0x01a8, 0x707c, 0xaa74, 0x9206, 0x1130,
- 0x7080, 0xaa78, 0x9206, 0x1110, 0x080c, 0x3310, 0x080c, 0xb341,
- 0x0020, 0x080c, 0xb91f, 0x080c, 0xaf2e, 0x00fe, 0x00ee, 0x009e,
- 0x0005, 0x7060, 0xaa78, 0x9206, 0x0d78, 0x0c80, 0x0096, 0x00e6,
- 0x00f6, 0x2071, 0x1800, 0x9186, 0x0015, 0x1550, 0x7090, 0x9086,
- 0x0004, 0x1530, 0x6014, 0x2048, 0x2c78, 0x080c, 0x998f, 0x05f0,
- 0x707c, 0xaacc, 0x9206, 0x1180, 0x7080, 0xaad0, 0x9206, 0x1160,
- 0x080c, 0x3310, 0x0016, 0xa998, 0xaab0, 0x9284, 0x1000, 0xc0fd,
- 0x080c, 0x57cf, 0x001e, 0x0010, 0x080c, 0x55b2, 0x080c, 0xcc16,
- 0x0508, 0xa87b, 0x0000, 0xa883, 0x0000, 0xa897, 0x4000, 0x0080,
- 0x080c, 0xcc16, 0x01b8, 0x6014, 0x2048, 0x080c, 0x55b2, 0x1d70,
- 0xa87b, 0x0030, 0xa883, 0x0000, 0xa897, 0x4005, 0xa89b, 0x0004,
- 0x0126, 0x2091, 0x8000, 0xa867, 0x0139, 0x080c, 0x6f19, 0x012e,
- 0x080c, 0xaf2e, 0x00fe, 0x00ee, 0x009e, 0x0005, 0x7060, 0xaad0,
- 0x9206, 0x0930, 0x0888, 0x0016, 0x0026, 0xa87c, 0xd0ac, 0x0178,
- 0xa938, 0xaa34, 0x2100, 0x9205, 0x0150, 0xa890, 0x9106, 0x1118,
- 0xa88c, 0x9206, 0x0120, 0xa992, 0xaa8e, 0x9085, 0x0001, 0x002e,
- 0x001e, 0x0005, 0x00b6, 0x00d6, 0x0036, 0x080c, 0xcc16, 0x0904,
- 0xd273, 0x0096, 0x6314, 0x2348, 0xa87a, 0xa982, 0x929e, 0x4000,
- 0x1580, 0x6310, 0x00c6, 0x2358, 0x2009, 0x0000, 0xa868, 0xd0f4,
- 0x1140, 0x080c, 0x6a7c, 0x1108, 0xc185, 0xb800, 0xd0bc, 0x0108,
- 0xc18d, 0xaa96, 0xa99a, 0x20a9, 0x0004, 0xa860, 0x20e8, 0xa85c,
- 0x9080, 0x0031, 0x20a0, 0xb8c4, 0x20e0, 0xb8c8, 0x9080, 0x0006,
- 0x2098, 0x080c, 0x0fd6, 0x20a9, 0x0004, 0xa85c, 0x9080, 0x0035,
- 0x20a0, 0xb8c8, 0x9080, 0x000a, 0x2098, 0x080c, 0x0fd6, 0x00ce,
- 0x0090, 0xaa96, 0x3918, 0x9398, 0x0007, 0x231c, 0x6004, 0x9086,
- 0x0016, 0x0110, 0xa89b, 0x0004, 0xaba2, 0x6310, 0x2358, 0xb804,
- 0x9084, 0x00ff, 0xa89e, 0xa868, 0xc0f4, 0xa86a, 0x080c, 0x6f0d,
- 0x6017, 0x0000, 0x009e, 0x003e, 0x00de, 0x00be, 0x0005, 0x0026,
- 0x0036, 0x0046, 0x00b6, 0x0096, 0x00f6, 0x6214, 0x2248, 0x6210,
- 0x2258, 0x2079, 0x0260, 0x9096, 0x0000, 0x11a0, 0xb814, 0x9084,
- 0x00ff, 0x900e, 0x080c, 0x26a2, 0x2118, 0x831f, 0x939c, 0xff00,
- 0x7838, 0x9084, 0x00ff, 0x931d, 0x7c3c, 0x2011, 0x8018, 0x080c,
- 0x4c2e, 0x00a8, 0x9096, 0x0001, 0x1148, 0x89ff, 0x0180, 0xa89b,
- 0x000d, 0x7838, 0xa8a6, 0x783c, 0xa8aa, 0x0048, 0x9096, 0x0002,
- 0x1130, 0xa89b, 0x000d, 0x7838, 0xa8a6, 0x783c, 0xa8aa, 0x00fe,
- 0x009e, 0x00be, 0x004e, 0x003e, 0x002e, 0x0005, 0x00c6, 0x0026,
- 0x0016, 0x9186, 0x0035, 0x0110, 0x6a38, 0x0008, 0x6a2c, 0x080c,
- 0xcc04, 0x01f0, 0x2260, 0x6120, 0x9186, 0x0003, 0x0118, 0x9186,
- 0x0006, 0x1190, 0x6838, 0x9206, 0x0140, 0x683c, 0x9206, 0x1160,
- 0x6108, 0x6838, 0x9106, 0x1140, 0x0020, 0x6008, 0x693c, 0x9106,
- 0x1118, 0x6010, 0x6910, 0x9106, 0x001e, 0x002e, 0x00ce, 0x0005,
- 0x9085, 0x0001, 0x0cc8, 0xa974, 0xd1cc, 0x0188, 0x918c, 0x00ff,
- 0x918e, 0x0002, 0x1160, 0xa9a8, 0x918c, 0x0f00, 0x810f, 0x918e,
- 0x0001, 0x1128, 0xa834, 0xa938, 0x9115, 0x190c, 0xc232, 0x0005,
- 0x0036, 0x2019, 0x0001, 0x0010, 0x0036, 0x901e, 0x0499, 0x01e0,
- 0x080c, 0xcc16, 0x01c8, 0x080c, 0xce07, 0x6037, 0x4000, 0x6014,
- 0x6017, 0x0000, 0x0096, 0x2048, 0xa87c, 0x080c, 0xce2d, 0x1118,
- 0x080c, 0xb91f, 0x0040, 0xa867, 0x0103, 0xa877, 0x0000, 0x83ff,
- 0x1129, 0x080c, 0x6f19, 0x009e, 0x003e, 0x0005, 0xa880, 0xd0b4,
- 0x0128, 0xa87b, 0x0006, 0xc0ec, 0xa882, 0x0048, 0xd0bc, 0x0118,
- 0xa87b, 0x0002, 0x0020, 0xa87b, 0x0005, 0x080c, 0xcf21, 0xa877,
- 0x0000, 0x0005, 0x2001, 0x1810, 0x2004, 0xd0ec, 0x0005, 0x0006,
- 0x2001, 0x1810, 0x2004, 0xd0f4, 0x000e, 0x0005, 0x0006, 0x2001,
- 0x1810, 0x2004, 0xd0e4, 0x000e, 0x0005, 0x0036, 0x0046, 0x6010,
- 0x00b6, 0x2058, 0xbba0, 0x00be, 0x2021, 0x0007, 0x080c, 0x4de5,
- 0x004e, 0x003e, 0x0005, 0x0c51, 0x1d81, 0x0005, 0x2001, 0x1987,
- 0x2004, 0x601a, 0x0005, 0x2001, 0x1989, 0x2004, 0x604a, 0x0005,
- 0x080c, 0xaf2e, 0x0804, 0x98bf, 0x611c, 0xd1fc, 0xa97c, 0x1108,
- 0xd1e4, 0x0005, 0x601c, 0xd0fc, 0xa87c, 0x1108, 0xd0e4, 0x0005,
- 0x601c, 0xd0fc, 0xc0fc, 0x601e, 0xa87c, 0x1108, 0xd0e4, 0x0005,
- 0x6044, 0xd0fc, 0x1138, 0xd0bc, 0x0198, 0xc0bc, 0x6046, 0x6003,
- 0x0002, 0x0070, 0xd0ac, 0x1160, 0xd0dc, 0x1128, 0x908c, 0x000f,
- 0x9186, 0x0005, 0x1118, 0x6003, 0x0003, 0x0010, 0x6003, 0x0001,
- 0x0005, 0x00b6, 0x0066, 0x6000, 0x90b2, 0x0016, 0x1a0c, 0x0d85,
- 0x001b, 0x006e, 0x00be, 0x0005, 0xd3ac, 0xdaf5, 0xdc64, 0xd3ac,
- 0xd3ac, 0xd3ac, 0xd3ac, 0xd3ac, 0xd3e3, 0xdce8, 0xd3ac, 0xd3ac,
- 0xd3ac, 0xd3ac, 0xd3ac, 0xd3ac, 0x080c, 0x0d85, 0x0066, 0x6000,
- 0x90b2, 0x0016, 0x1a0c, 0x0d85, 0x0013, 0x006e, 0x0005, 0xd3c7,
- 0xe209, 0xd3c7, 0xd3c7, 0xd3c7, 0xd3c7, 0xd3c7, 0xd3c7, 0xe1b8,
- 0xe25b, 0xd3c7, 0xe8b4, 0xe8e8, 0xe8b4, 0xe8e8, 0xd3c7, 0x080c,
- 0x0d85, 0x6000, 0x9082, 0x0016, 0x1a0c, 0x0d85, 0x6000, 0x000a,
- 0x0005, 0xd3e1, 0xdec5, 0xdf90, 0xdfb3, 0xe02f, 0xd3e1, 0xe12a,
- 0xe0b7, 0xdcf2, 0xe190, 0xe1a5, 0xd3e1, 0xd3e1, 0xd3e1, 0xd3e1,
- 0xd3e1, 0x080c, 0x0d85, 0x91b2, 0x0053, 0x1a0c, 0x0d85, 0x2100,
- 0x91b2, 0x0040, 0x1a04, 0xd867, 0x0002, 0xd42d, 0xd635, 0xd42d,
- 0xd42d, 0xd42d, 0xd63e, 0xd42d, 0xd42d, 0xd42d, 0xd42d, 0xd42d,
- 0xd42d, 0xd42d, 0xd42d, 0xd42d, 0xd42d, 0xd42d, 0xd42d, 0xd42d,
- 0xd42d, 0xd42d, 0xd42d, 0xd42d, 0xd42f, 0xd496, 0xd4a5, 0xd509,
- 0xd534, 0xd5ad, 0xd620, 0xd42d, 0xd42d, 0xd641, 0xd42d, 0xd42d,
- 0xd656, 0xd663, 0xd42d, 0xd42d, 0xd42d, 0xd42d, 0xd42d, 0xd709,
- 0xd42d, 0xd42d, 0xd71d, 0xd42d, 0xd42d, 0xd6d8, 0xd42d, 0xd42d,
- 0xd42d, 0xd735, 0xd42d, 0xd42d, 0xd42d, 0xd7b2, 0xd42d, 0xd42d,
- 0xd42d, 0xd42d, 0xd42d, 0xd42d, 0xd82f, 0x080c, 0x0d85, 0x080c,
- 0x6b93, 0x1150, 0x2001, 0x1837, 0x2004, 0xd0cc, 0x1128, 0x9084,
- 0x0009, 0x9086, 0x0008, 0x1140, 0x6007, 0x0009, 0x602f, 0x0009,
- 0x6017, 0x0000, 0x0804, 0xd62e, 0x080c, 0x6b2f, 0x00e6, 0x00c6,
- 0x0036, 0x0026, 0x0016, 0x6210, 0x2258, 0xbaa0, 0x0026, 0x2019,
- 0x0029, 0x080c, 0xaae0, 0x080c, 0x95c1, 0x0076, 0x903e, 0x080c,
- 0x947e, 0x2c08, 0x080c, 0xe440, 0x007e, 0x001e, 0x080c, 0xaafc,
- 0x001e, 0x002e, 0x003e, 0x00ce, 0x00ee, 0x6610, 0x2658, 0x080c,
- 0x6798, 0xbe04, 0x9684, 0x00ff, 0x9082, 0x0006, 0x1268, 0x0016,
- 0x0026, 0x6210, 0x00b6, 0x2258, 0xbaa0, 0x00be, 0x2c08, 0x080c,
- 0xeb13, 0x002e, 0x001e, 0x1178, 0x080c, 0xe36e, 0x1904, 0xd501,
- 0x080c, 0xe30a, 0x1120, 0x6007, 0x0008, 0x0804, 0xd62e, 0x6007,
- 0x0009, 0x0804, 0xd62e, 0x080c, 0xe5a2, 0x0128, 0x080c, 0xe36e,
- 0x0d78, 0x0804, 0xd501, 0x6017, 0x1900, 0x0c88, 0x080c, 0x3447,
- 0x1904, 0xd864, 0x6106, 0x080c, 0xe2bb, 0x6007, 0x0006, 0x0804,
- 0xd62e, 0x6007, 0x0007, 0x0804, 0xd62e, 0x080c, 0xe924, 0x1904,
- 0xd864, 0x080c, 0x3447, 0x1904, 0xd864, 0x00d6, 0x6610, 0x2658,
- 0xbe04, 0x9684, 0x00ff, 0x9082, 0x0006, 0x1220, 0x2001, 0x0001,
- 0x080c, 0x66bb, 0x96b4, 0xff00, 0x8637, 0x9686, 0x0006, 0x0188,
- 0x9686, 0x0004, 0x0170, 0xbe04, 0x96b4, 0x00ff, 0x9686, 0x0006,
- 0x0140, 0x9686, 0x0004, 0x0128, 0x9686, 0x0005, 0x0110, 0x00de,
- 0x0480, 0x00e6, 0x2071, 0x0260, 0x7034, 0x9084, 0x0003, 0x1140,
- 0x7034, 0x9082, 0x0014, 0x0220, 0x7030, 0x9084, 0x0003, 0x0130,
- 0x00ee, 0x6017, 0x0000, 0x602f, 0x0007, 0x00b0, 0x00ee, 0x080c,
- 0xe3d6, 0x1190, 0x9686, 0x0006, 0x1140, 0x0026, 0x6210, 0x2258,
- 0xbaa0, 0x900e, 0x080c, 0x335f, 0x002e, 0x080c, 0x6824, 0x6007,
- 0x000a, 0x00de, 0x0804, 0xd62e, 0x6007, 0x000b, 0x00de, 0x0804,
- 0xd62e, 0x080c, 0x3310, 0x080c, 0xd353, 0x6007, 0x0001, 0x0804,
- 0xd62e, 0x080c, 0xe924, 0x1904, 0xd864, 0x080c, 0x3447, 0x1904,
- 0xd864, 0x2071, 0x0260, 0x7034, 0x90b4, 0x0003, 0x1948, 0x90b2,
- 0x0014, 0x0a30, 0x7030, 0x9084, 0x0003, 0x1910, 0x6610, 0x2658,
- 0xbe04, 0x9686, 0x0707, 0x09e8, 0x0026, 0x6210, 0x2258, 0xbaa0,
- 0x900e, 0x080c, 0x335f, 0x002e, 0x6007, 0x000c, 0x2001, 0x0001,
- 0x080c, 0xeaf2, 0x0804, 0xd62e, 0x080c, 0x6b93, 0x1140, 0x2001,
+ 0x0000, 0xa880, 0xc0ed, 0xa882, 0x080c, 0x6f11, 0x2c68, 0x080c,
+ 0xaef8, 0x0150, 0x6810, 0x6012, 0x080c, 0xd0ce, 0x00c6, 0x2d60,
+ 0x080c, 0xaf89, 0x00ce, 0x0008, 0x2d60, 0x6017, 0x0000, 0x6023,
+ 0x0001, 0x6007, 0x0001, 0x6003, 0x0001, 0x080c, 0x9427, 0x080c,
+ 0x98bc, 0x00c8, 0x080c, 0xd351, 0x0138, 0x6034, 0x9086, 0x4000,
+ 0x1118, 0x080c, 0x32fb, 0x08d0, 0x6034, 0x908c, 0xff00, 0x810f,
+ 0x9186, 0x0039, 0x0118, 0x9186, 0x0035, 0x1118, 0x080c, 0x32fb,
+ 0x0868, 0x080c, 0xaf89, 0x0005, 0x6000, 0x908a, 0x0010, 0x1a0c,
+ 0x0d79, 0x0002, 0xcc0a, 0xcc0a, 0xcc12, 0xcc0c, 0xcc1c, 0xcc0a,
+ 0xcc0a, 0xaf89, 0xcc0a, 0xcc0a, 0xcc0a, 0xcc0a, 0xcc0a, 0xcc0a,
+ 0xcc0a, 0xcc0a, 0x080c, 0x0d79, 0x080c, 0xaaf7, 0x080c, 0xaccf,
+ 0x080c, 0xab13, 0x6114, 0x0096, 0x2148, 0xa87b, 0x0006, 0x080c,
+ 0x6f11, 0x009e, 0x0804, 0xaf4e, 0x601c, 0xd084, 0x190c, 0x1af0,
+ 0x0c88, 0x9284, 0x0003, 0x1158, 0x9282, 0x1ddc, 0x0240, 0x2001,
+ 0x181a, 0x2004, 0x9202, 0x1218, 0x9085, 0x0001, 0x0005, 0x9006,
+ 0x0ce8, 0x0096, 0x0028, 0x0096, 0x0006, 0x6014, 0x2048, 0x000e,
+ 0x0006, 0x9984, 0xf000, 0x9086, 0xf000, 0x0110, 0x080c, 0x10f8,
+ 0x000e, 0x009e, 0x0005, 0x00e6, 0x00c6, 0x0036, 0x0006, 0x0126,
+ 0x2091, 0x8000, 0x2061, 0x1ddc, 0x2071, 0x1800, 0x7354, 0x7074,
+ 0x9302, 0x1640, 0x6020, 0x9206, 0x11f8, 0x080c, 0xd35d, 0x0180,
+ 0x9286, 0x0001, 0x1168, 0x6004, 0x9086, 0x0004, 0x1148, 0x080c,
+ 0x32fb, 0x080c, 0xd372, 0x00c6, 0x080c, 0xaf89, 0x00ce, 0x0060,
+ 0x080c, 0xd040, 0x0148, 0x080c, 0xce4a, 0x1110, 0x080c, 0xb93c,
+ 0x00c6, 0x080c, 0xaf4e, 0x00ce, 0x9ce0, 0x001c, 0x7068, 0x9c02,
+ 0x1208, 0x08a0, 0x012e, 0x000e, 0x003e, 0x00ce, 0x00ee, 0x0005,
+ 0x00e6, 0x00c6, 0x0016, 0x9188, 0x1000, 0x210c, 0x81ff, 0x0128,
+ 0x2061, 0x1b3a, 0x6112, 0x080c, 0x32fb, 0x9006, 0x0010, 0x9085,
+ 0x0001, 0x001e, 0x00ce, 0x00ee, 0x0005, 0x00c6, 0x0126, 0x2091,
+ 0x8000, 0x080c, 0xaef8, 0x01b0, 0x665e, 0x2b00, 0x6012, 0x080c,
+ 0x5828, 0x0118, 0x080c, 0xcd66, 0x0168, 0x080c, 0xd0ce, 0x6023,
+ 0x0003, 0x2009, 0x004b, 0x080c, 0xafec, 0x9085, 0x0001, 0x012e,
+ 0x00ce, 0x0005, 0x9006, 0x0cd8, 0x00c6, 0x0126, 0x2091, 0x8000,
+ 0xbaa0, 0x080c, 0xafbf, 0x0580, 0x605f, 0x0000, 0x2b00, 0x6012,
+ 0x080c, 0xd0ce, 0x6023, 0x0003, 0x0016, 0x080c, 0xaaf7, 0x080c,
+ 0x95b9, 0x0076, 0x903e, 0x080c, 0x9476, 0x2c08, 0x080c, 0xe465,
+ 0x007e, 0x080c, 0xab13, 0x001e, 0xd184, 0x0128, 0x080c, 0xaf4e,
+ 0x9085, 0x0001, 0x0070, 0x080c, 0x5828, 0x0128, 0xd18c, 0x1170,
+ 0x080c, 0xcd66, 0x0148, 0x2009, 0x004c, 0x080c, 0xafec, 0x9085,
+ 0x0001, 0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd8, 0x2900, 0x6016,
+ 0x0c90, 0x2009, 0x004d, 0x0010, 0x2009, 0x004e, 0x00f6, 0x00c6,
+ 0x0046, 0x0016, 0x080c, 0xaef8, 0x2c78, 0x05a0, 0x7e5e, 0x2b00,
+ 0x7812, 0x7823, 0x0003, 0x0016, 0x2021, 0x0005, 0x080c, 0xcd78,
+ 0x001e, 0x9186, 0x004d, 0x0118, 0x9186, 0x004e, 0x0148, 0x2001,
+ 0x1981, 0x200c, 0xd1fc, 0x0168, 0x2f60, 0x080c, 0xaf4e, 0x00d0,
+ 0x2001, 0x1980, 0x200c, 0xd1fc, 0x0120, 0x2f60, 0x080c, 0xaf4e,
+ 0x0088, 0x2f60, 0x080c, 0x5828, 0x0138, 0xd18c, 0x1118, 0x04f1,
+ 0x0148, 0x0010, 0x2900, 0x7816, 0x001e, 0x0016, 0x080c, 0xafec,
+ 0x9085, 0x0001, 0x001e, 0x004e, 0x00ce, 0x00fe, 0x0005, 0x00f6,
+ 0x00c6, 0x0046, 0x080c, 0xaef8, 0x2c78, 0x0508, 0x7e5e, 0x2b00,
+ 0x7812, 0x7823, 0x0003, 0x0096, 0x2021, 0x0004, 0x0489, 0x009e,
+ 0x2001, 0x197f, 0x200c, 0xd1fc, 0x0120, 0x2f60, 0x080c, 0xaf4e,
+ 0x0060, 0x2f60, 0x080c, 0x5828, 0x0120, 0xd18c, 0x1160, 0x0071,
+ 0x0130, 0x2009, 0x0052, 0x080c, 0xafec, 0x9085, 0x0001, 0x004e,
+ 0x00ce, 0x00fe, 0x0005, 0x2900, 0x7816, 0x0c98, 0x00c6, 0x080c,
+ 0x4bc8, 0x00ce, 0x1120, 0x080c, 0xaf4e, 0x9006, 0x0005, 0xa867,
+ 0x0000, 0xa86b, 0x8000, 0x2900, 0x6016, 0x9085, 0x0001, 0x0005,
+ 0x0096, 0x0076, 0x0126, 0x2091, 0x8000, 0x080c, 0xaaf7, 0x080c,
+ 0x6963, 0x0158, 0x2001, 0xcd7f, 0x0006, 0x900e, 0x2400, 0x080c,
+ 0x715d, 0x080c, 0x6f11, 0x000e, 0x0807, 0x2418, 0x080c, 0x97bc,
+ 0xbaa0, 0x0086, 0x2041, 0x0001, 0x2039, 0x0001, 0x2608, 0x080c,
+ 0x95d3, 0x008e, 0x080c, 0x9476, 0x2f08, 0x2648, 0x080c, 0xe465,
+ 0xb93c, 0x81ff, 0x090c, 0x96ac, 0x080c, 0xab13, 0x012e, 0x007e,
+ 0x009e, 0x0005, 0x00c6, 0x0126, 0x2091, 0x8000, 0x080c, 0xaef8,
+ 0x0190, 0x660a, 0x2b08, 0x6112, 0x080c, 0xd0ce, 0x6023, 0x0001,
+ 0x2900, 0x6016, 0x2009, 0x001f, 0x080c, 0xafec, 0x9085, 0x0001,
+ 0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd8, 0x00c6, 0x0126, 0x2091,
+ 0x8000, 0x080c, 0xafbf, 0x01b8, 0x660a, 0x2b08, 0x6112, 0x080c,
+ 0xd0ce, 0x6023, 0x0008, 0x2900, 0x6016, 0x00f6, 0x2c78, 0x080c,
+ 0x17a1, 0x00fe, 0x2009, 0x0021, 0x080c, 0xafec, 0x9085, 0x0001,
+ 0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd8, 0x2009, 0x003d, 0x00c6,
+ 0x0126, 0x0016, 0x2091, 0x8000, 0x080c, 0xaef8, 0x0198, 0x660a,
+ 0x2b08, 0x6112, 0x080c, 0xd0ce, 0x6023, 0x0001, 0x2900, 0x6016,
+ 0x001e, 0x0016, 0x080c, 0xafec, 0x9085, 0x0001, 0x001e, 0x012e,
+ 0x00ce, 0x0005, 0x9006, 0x0cd0, 0x00c6, 0x0126, 0x2091, 0x8000,
+ 0x080c, 0xafbf, 0x0188, 0x2b08, 0x6112, 0x080c, 0xd0ce, 0x6023,
+ 0x0001, 0x2900, 0x6016, 0x2009, 0x0000, 0x080c, 0xafec, 0x9085,
+ 0x0001, 0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd8, 0x2009, 0x0044,
+ 0x0830, 0x2009, 0x0049, 0x0818, 0x0026, 0x00b6, 0x6210, 0x2258,
+ 0xba3c, 0x82ff, 0x0118, 0x8211, 0xba3e, 0x1140, 0xb8d0, 0x9005,
+ 0x0128, 0xb888, 0x9005, 0x1110, 0xb88b, 0x0001, 0x00be, 0x002e,
+ 0x0005, 0x0006, 0x0016, 0x6004, 0x908e, 0x0002, 0x0140, 0x908e,
+ 0x0003, 0x0128, 0x908e, 0x0004, 0x0110, 0x9085, 0x0001, 0x001e,
+ 0x000e, 0x0005, 0x0006, 0x0086, 0x0096, 0x6020, 0x9086, 0x0004,
+ 0x01a8, 0x6014, 0x904d, 0x080c, 0xcc33, 0x0180, 0xa864, 0x9086,
+ 0x0139, 0x0170, 0x6020, 0x90c6, 0x0003, 0x0140, 0x90c6, 0x0002,
+ 0x0128, 0xa868, 0xd0fc, 0x0110, 0x9006, 0x0010, 0x9085, 0x0001,
+ 0x009e, 0x008e, 0x000e, 0x0005, 0x00c6, 0x0126, 0x2091, 0x8000,
+ 0x080c, 0xafbf, 0x0198, 0x2b08, 0x6112, 0x080c, 0xd0ce, 0x6023,
+ 0x0001, 0x2900, 0x6016, 0x080c, 0x32fb, 0x2009, 0x0028, 0x080c,
+ 0xafec, 0x9085, 0x0001, 0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd8,
+ 0x9186, 0x0015, 0x11a8, 0x2011, 0x1824, 0x2204, 0x9086, 0x0074,
+ 0x1178, 0x00b6, 0x080c, 0xbb92, 0x00be, 0x080c, 0xbdb7, 0x6003,
+ 0x0001, 0x6007, 0x0029, 0x080c, 0x9427, 0x080c, 0x98bc, 0x0078,
+ 0x6014, 0x0096, 0x2048, 0xa868, 0x009e, 0xd0fc, 0x0148, 0x2001,
+ 0x0001, 0x080c, 0xd294, 0x080c, 0xb93c, 0x080c, 0xaf4e, 0x0005,
+ 0x0096, 0x6014, 0x904d, 0x090c, 0x0d79, 0xa87b, 0x0030, 0xa883,
+ 0x0000, 0xa897, 0x4005, 0xa89b, 0x0004, 0xa867, 0x0139, 0x0126,
+ 0x2091, 0x8000, 0x080c, 0x6f11, 0x012e, 0x009e, 0x080c, 0xaf4e,
+ 0x0c30, 0x0096, 0x9186, 0x0016, 0x1128, 0x2001, 0x0004, 0x080c,
+ 0x66c9, 0x00e8, 0x9186, 0x0015, 0x1510, 0x2011, 0x1824, 0x2204,
+ 0x9086, 0x0014, 0x11e0, 0x6010, 0x00b6, 0x2058, 0x080c, 0x681e,
+ 0x00be, 0x080c, 0xbe8d, 0x1198, 0x6010, 0x00b6, 0x2058, 0xb890,
+ 0x00be, 0x9005, 0x0160, 0x2001, 0x0006, 0x080c, 0x66c9, 0x6014,
+ 0x2048, 0xa868, 0xd0fc, 0x0170, 0x080c, 0xb35e, 0x0048, 0x6014,
+ 0x2048, 0xa868, 0xd0fc, 0x0528, 0x080c, 0xb93c, 0x080c, 0xaf4e,
+ 0x009e, 0x0005, 0x6014, 0x6310, 0x2358, 0x904d, 0x090c, 0x0d79,
+ 0xa87b, 0x0000, 0xa883, 0x0000, 0xa897, 0x4000, 0x900e, 0x080c,
+ 0x6a74, 0x1108, 0xc185, 0xb800, 0xd0bc, 0x0108, 0xc18d, 0xa99a,
+ 0x0126, 0x2091, 0x8000, 0x080c, 0x6f11, 0x012e, 0x080c, 0xaf4e,
+ 0x08f8, 0x6014, 0x904d, 0x090c, 0x0d79, 0xa87b, 0x0030, 0xa883,
+ 0x0000, 0xa897, 0x4005, 0xa89b, 0x0004, 0xa867, 0x0139, 0x0126,
+ 0x2091, 0x8000, 0x080c, 0x6f11, 0x012e, 0x080c, 0xaf4e, 0x0840,
+ 0xa878, 0x9086, 0x0005, 0x1108, 0x0009, 0x0005, 0xa880, 0xc0ad,
+ 0xa882, 0x0005, 0x604b, 0x0000, 0x6017, 0x0000, 0x6003, 0x0001,
+ 0x6007, 0x0050, 0x2009, 0x8023, 0x080c, 0x9420, 0x0005, 0x00c6,
+ 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x0130, 0x0066,
+ 0x6020, 0x9084, 0x000f, 0x001b, 0x006e, 0x00ce, 0x0005, 0xc930,
+ 0xcf71, 0xcf71, 0xcf74, 0xe7e4, 0xe7ff, 0xe802, 0xc930, 0xc930,
+ 0xc930, 0xc930, 0xc930, 0xc930, 0xc930, 0xc930, 0xc930, 0x080c,
+ 0x0d79, 0xa001, 0xa001, 0x0005, 0x0096, 0x6014, 0x904d, 0x0118,
+ 0xa87c, 0xd0e4, 0x1110, 0x009e, 0x0010, 0x009e, 0x0005, 0x6010,
+ 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x0550, 0x2001, 0x1834,
+ 0x2004, 0x9005, 0x1540, 0x00f6, 0x2c78, 0x080c, 0xaef8, 0x0508,
+ 0x7810, 0x6012, 0x080c, 0xd0ce, 0x7820, 0x9086, 0x0003, 0x0128,
+ 0x7808, 0x603a, 0x2f00, 0x603e, 0x0020, 0x7808, 0x603e, 0x2f00,
+ 0x603a, 0x602e, 0x6023, 0x0001, 0x6007, 0x0035, 0x6003, 0x0001,
+ 0x795c, 0x615e, 0x2009, 0x8020, 0x080c, 0x9420, 0x2f60, 0x00fe,
+ 0x0005, 0x2f60, 0x00fe, 0x2001, 0x1989, 0x2004, 0x604a, 0x0005,
+ 0x0016, 0x0096, 0x6814, 0x2048, 0x681c, 0xd0fc, 0xc0fc, 0x681e,
+ 0xa87c, 0x1108, 0xd0e4, 0x0180, 0xc0e4, 0xa87e, 0xa877, 0x0000,
+ 0xa893, 0x0000, 0xa88f, 0x0000, 0xd0cc, 0x0130, 0xc0cc, 0xa87e,
+ 0xa878, 0x2048, 0x080c, 0x0fff, 0x6830, 0x6036, 0x908e, 0x0001,
+ 0x0148, 0x6803, 0x0002, 0x9086, 0x0005, 0x0170, 0x9006, 0x602e,
+ 0x6032, 0x00d0, 0x681c, 0xc085, 0x681e, 0x6803, 0x0004, 0x6824,
+ 0xc0f4, 0x9085, 0x0c00, 0x6826, 0x6814, 0x2048, 0xa8ac, 0x6938,
+ 0x9102, 0xa8b0, 0x693c, 0x9103, 0x1e48, 0x683c, 0x602e, 0x6838,
+ 0x9084, 0xfffc, 0x683a, 0x6032, 0x2d00, 0x603a, 0x6808, 0x603e,
+ 0x6910, 0x6112, 0x695c, 0x615e, 0x6023, 0x0001, 0x6007, 0x0039,
+ 0x6003, 0x0001, 0x2009, 0x8020, 0x080c, 0x9420, 0x009e, 0x001e,
+ 0x0005, 0x6024, 0xd0d4, 0x0510, 0xd0f4, 0x11f8, 0x6038, 0x940a,
+ 0x603c, 0x9303, 0x0230, 0x9105, 0x0120, 0x6024, 0xc0d4, 0xc0f5,
+ 0x0098, 0x643a, 0x633e, 0xac3e, 0xab42, 0x0046, 0x0036, 0x2400,
+ 0xacac, 0x9402, 0xa836, 0x2300, 0xabb0, 0x9303, 0xa83a, 0x003e,
+ 0x004e, 0x6024, 0xc0d4, 0x0000, 0x6026, 0x0005, 0xd0f4, 0x1138,
+ 0xa83c, 0x603a, 0xa840, 0x603e, 0x6024, 0xc0f5, 0x6026, 0x0005,
+ 0x0006, 0x0016, 0x6004, 0x908e, 0x0034, 0x01b8, 0x908e, 0x0035,
+ 0x01a0, 0x908e, 0x0036, 0x0188, 0x908e, 0x0037, 0x0170, 0x908e,
+ 0x0038, 0x0158, 0x908e, 0x0039, 0x0140, 0x908e, 0x003a, 0x0128,
+ 0x908e, 0x003b, 0x0110, 0x9085, 0x0001, 0x001e, 0x000e, 0x0005,
+ 0x0006, 0x0016, 0x0026, 0x0036, 0x00e6, 0x2001, 0x1983, 0x200c,
+ 0x8000, 0x2014, 0x2001, 0x0032, 0x080c, 0x9364, 0x2001, 0x1987,
+ 0x82ff, 0x1110, 0x2011, 0x0014, 0x2202, 0x2001, 0x1985, 0x200c,
+ 0x8000, 0x2014, 0x2071, 0x196d, 0x711a, 0x721e, 0x2001, 0x0064,
+ 0x080c, 0x9364, 0x2001, 0x1988, 0x82ff, 0x1110, 0x2011, 0x0014,
+ 0x2202, 0x2001, 0x1989, 0x9288, 0x000a, 0x2102, 0x2001, 0x0017,
+ 0x080c, 0xaae8, 0x2001, 0x1a91, 0x2102, 0x2001, 0x0032, 0x080c,
+ 0x16ad, 0x080c, 0x6bae, 0x00ee, 0x003e, 0x002e, 0x001e, 0x000e,
+ 0x0005, 0x0006, 0x0016, 0x00e6, 0x2001, 0x1987, 0x2003, 0x0028,
+ 0x2001, 0x1988, 0x2003, 0x0014, 0x2071, 0x196d, 0x701b, 0x0000,
+ 0x701f, 0x07d0, 0x2001, 0x1989, 0x2009, 0x001e, 0x2102, 0x2001,
+ 0x0017, 0x080c, 0xaae8, 0x2001, 0x1a91, 0x2102, 0x2001, 0x0032,
+ 0x080c, 0x16ad, 0x00ee, 0x001e, 0x000e, 0x0005, 0x0096, 0x6060,
+ 0x904d, 0x0110, 0x080c, 0x107f, 0x009e, 0x0005, 0x0005, 0x00c6,
+ 0x0126, 0x2091, 0x8000, 0x080c, 0xaef8, 0x0180, 0x2b08, 0x6112,
+ 0x0ca9, 0x6023, 0x0001, 0x2900, 0x6016, 0x2009, 0x0033, 0x080c,
+ 0xafec, 0x9085, 0x0001, 0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd8,
+ 0x0096, 0x00e6, 0x00f6, 0x2071, 0x1800, 0x9186, 0x0015, 0x1520,
+ 0x7090, 0x9086, 0x0018, 0x0120, 0x7090, 0x9086, 0x0014, 0x11e0,
+ 0x6014, 0x2048, 0xaa3c, 0xd2e4, 0x1160, 0x2c78, 0x080c, 0x998c,
+ 0x01d8, 0x707c, 0xaa50, 0x9206, 0x1160, 0x7080, 0xaa54, 0x9206,
+ 0x1140, 0x6210, 0x00b6, 0x2258, 0xbaa0, 0x00be, 0x900e, 0x080c,
+ 0x334a, 0x080c, 0xb35e, 0x0020, 0x080c, 0xb93c, 0x080c, 0xaf4e,
+ 0x00fe, 0x00ee, 0x009e, 0x0005, 0x7060, 0xaa54, 0x9206, 0x0d48,
+ 0x0c80, 0x00c6, 0x0126, 0x2091, 0x8000, 0x080c, 0xaef8, 0x0188,
+ 0x2b08, 0x6112, 0x080c, 0xd0ce, 0x6023, 0x0001, 0x2900, 0x6016,
+ 0x2009, 0x004d, 0x080c, 0xafec, 0x9085, 0x0001, 0x012e, 0x00ce,
+ 0x0005, 0x9006, 0x0cd8, 0x00c6, 0x0126, 0x2091, 0x8000, 0x0016,
+ 0x080c, 0xaef8, 0x0180, 0x2b08, 0x6112, 0x080c, 0xd0ce, 0x6023,
+ 0x0001, 0x2900, 0x6016, 0x001e, 0x080c, 0xafec, 0x9085, 0x0001,
+ 0x012e, 0x00ce, 0x0005, 0x001e, 0x9006, 0x0cd0, 0x0016, 0x0026,
+ 0x0036, 0x0046, 0x0056, 0x0066, 0x0096, 0x00e6, 0x00f6, 0x2071,
+ 0x1800, 0x9186, 0x0015, 0x1568, 0x7190, 0x6014, 0x2048, 0xa814,
+ 0x8003, 0x9106, 0x1530, 0x20e1, 0x0000, 0x2001, 0x19a2, 0x2003,
+ 0x0000, 0x6014, 0x2048, 0xa830, 0x20a8, 0x8906, 0x8006, 0x8007,
+ 0x9094, 0x003f, 0x22e8, 0x9084, 0xffc0, 0x9080, 0x001b, 0x20a0,
+ 0x2001, 0x19a2, 0x0016, 0x200c, 0x080c, 0xd9b7, 0x001e, 0xa804,
+ 0x9005, 0x0110, 0x2048, 0x0c38, 0x6014, 0x2048, 0xa867, 0x0103,
+ 0x0010, 0x080c, 0xb93c, 0x080c, 0xaf4e, 0x00fe, 0x00ee, 0x009e,
+ 0x006e, 0x005e, 0x004e, 0x003e, 0x002e, 0x001e, 0x0005, 0x0096,
+ 0x00e6, 0x00f6, 0x2071, 0x1800, 0x9186, 0x0015, 0x11b8, 0x7090,
+ 0x9086, 0x0004, 0x1198, 0x6014, 0x2048, 0x2c78, 0x080c, 0x998c,
+ 0x01a8, 0x707c, 0xaa74, 0x9206, 0x1130, 0x7080, 0xaa78, 0x9206,
+ 0x1110, 0x080c, 0x32fb, 0x080c, 0xb35e, 0x0020, 0x080c, 0xb93c,
+ 0x080c, 0xaf4e, 0x00fe, 0x00ee, 0x009e, 0x0005, 0x7060, 0xaa78,
+ 0x9206, 0x0d78, 0x0c80, 0x0096, 0x00e6, 0x00f6, 0x2071, 0x1800,
+ 0x9186, 0x0015, 0x1550, 0x7090, 0x9086, 0x0004, 0x1530, 0x6014,
+ 0x2048, 0x2c78, 0x080c, 0x998c, 0x05f0, 0x707c, 0xaacc, 0x9206,
+ 0x1180, 0x7080, 0xaad0, 0x9206, 0x1160, 0x080c, 0x32fb, 0x0016,
+ 0xa998, 0xaab0, 0x9284, 0x1000, 0xc0fd, 0x080c, 0x57c9, 0x001e,
+ 0x0010, 0x080c, 0x55ac, 0x080c, 0xcc33, 0x0508, 0xa87b, 0x0000,
+ 0xa883, 0x0000, 0xa897, 0x4000, 0x0080, 0x080c, 0xcc33, 0x01b8,
+ 0x6014, 0x2048, 0x080c, 0x55ac, 0x1d70, 0xa87b, 0x0030, 0xa883,
+ 0x0000, 0xa897, 0x4005, 0xa89b, 0x0004, 0x0126, 0x2091, 0x8000,
+ 0xa867, 0x0139, 0x080c, 0x6f11, 0x012e, 0x080c, 0xaf4e, 0x00fe,
+ 0x00ee, 0x009e, 0x0005, 0x7060, 0xaad0, 0x9206, 0x0930, 0x0888,
+ 0x0016, 0x0026, 0xa87c, 0xd0ac, 0x0178, 0xa938, 0xaa34, 0x2100,
+ 0x9205, 0x0150, 0xa890, 0x9106, 0x1118, 0xa88c, 0x9206, 0x0120,
+ 0xa992, 0xaa8e, 0x9085, 0x0001, 0x002e, 0x001e, 0x0005, 0x00b6,
+ 0x00d6, 0x0036, 0x080c, 0xcc33, 0x0904, 0xd290, 0x0096, 0x6314,
+ 0x2348, 0xa87a, 0xa982, 0x929e, 0x4000, 0x1580, 0x6310, 0x00c6,
+ 0x2358, 0x2009, 0x0000, 0xa868, 0xd0f4, 0x1140, 0x080c, 0x6a74,
+ 0x1108, 0xc185, 0xb800, 0xd0bc, 0x0108, 0xc18d, 0xaa96, 0xa99a,
+ 0x20a9, 0x0004, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0031, 0x20a0,
+ 0xb8c4, 0x20e0, 0xb8c8, 0x9080, 0x0006, 0x2098, 0x080c, 0x0fca,
+ 0x20a9, 0x0004, 0xa85c, 0x9080, 0x0035, 0x20a0, 0xb8c8, 0x9080,
+ 0x000a, 0x2098, 0x080c, 0x0fca, 0x00ce, 0x0090, 0xaa96, 0x3918,
+ 0x9398, 0x0007, 0x231c, 0x6004, 0x9086, 0x0016, 0x0110, 0xa89b,
+ 0x0004, 0xaba2, 0x6310, 0x2358, 0xb804, 0x9084, 0x00ff, 0xa89e,
+ 0xa868, 0xc0f4, 0xa86a, 0x080c, 0x6f05, 0x6017, 0x0000, 0x009e,
+ 0x003e, 0x00de, 0x00be, 0x0005, 0x0026, 0x0036, 0x0046, 0x00b6,
+ 0x0096, 0x00f6, 0x6214, 0x2248, 0x6210, 0x2258, 0x2079, 0x0260,
+ 0x9096, 0x0000, 0x11a0, 0xb814, 0x9084, 0x00ff, 0x900e, 0x080c,
+ 0x26a1, 0x2118, 0x831f, 0x939c, 0xff00, 0x7838, 0x9084, 0x00ff,
+ 0x931d, 0x7c3c, 0x2011, 0x8018, 0x080c, 0x4c28, 0x00a8, 0x9096,
+ 0x0001, 0x1148, 0x89ff, 0x0180, 0xa89b, 0x000d, 0x7838, 0xa8a6,
+ 0x783c, 0xa8aa, 0x0048, 0x9096, 0x0002, 0x1130, 0xa89b, 0x000d,
+ 0x7838, 0xa8a6, 0x783c, 0xa8aa, 0x00fe, 0x009e, 0x00be, 0x004e,
+ 0x003e, 0x002e, 0x0005, 0x00c6, 0x0026, 0x0016, 0x9186, 0x0035,
+ 0x0110, 0x6a38, 0x0008, 0x6a2c, 0x080c, 0xcc21, 0x01f0, 0x2260,
+ 0x6120, 0x9186, 0x0003, 0x0118, 0x9186, 0x0006, 0x1190, 0x6838,
+ 0x9206, 0x0140, 0x683c, 0x9206, 0x1160, 0x6108, 0x6838, 0x9106,
+ 0x1140, 0x0020, 0x6008, 0x693c, 0x9106, 0x1118, 0x6010, 0x6910,
+ 0x9106, 0x001e, 0x002e, 0x00ce, 0x0005, 0x9085, 0x0001, 0x0cc8,
+ 0xa974, 0xd1cc, 0x0198, 0x918c, 0x00ff, 0x918e, 0x0002, 0x1170,
+ 0xa9a8, 0x918c, 0x000f, 0x918e, 0x0001, 0x1140, 0xa87c, 0xd0ac,
+ 0x0128, 0xa834, 0xa938, 0x9115, 0x190c, 0xc24b, 0x0005, 0x0036,
+ 0x2019, 0x0001, 0x0010, 0x0036, 0x901e, 0x0499, 0x01e0, 0x080c,
+ 0xcc33, 0x01c8, 0x080c, 0xce24, 0x6037, 0x4000, 0x6014, 0x6017,
+ 0x0000, 0x0096, 0x2048, 0xa87c, 0x080c, 0xce4a, 0x1118, 0x080c,
+ 0xb93c, 0x0040, 0xa867, 0x0103, 0xa877, 0x0000, 0x83ff, 0x1129,
+ 0x080c, 0x6f11, 0x009e, 0x003e, 0x0005, 0xa880, 0xd0b4, 0x0128,
+ 0xa87b, 0x0006, 0xc0ec, 0xa882, 0x0048, 0xd0bc, 0x0118, 0xa87b,
+ 0x0002, 0x0020, 0xa87b, 0x0005, 0x080c, 0xcf3e, 0xa877, 0x0000,
+ 0x0005, 0x2001, 0x1810, 0x2004, 0xd0ec, 0x0005, 0x0006, 0x2001,
+ 0x1810, 0x2004, 0xd0f4, 0x000e, 0x0005, 0x0006, 0x2001, 0x1810,
+ 0x2004, 0xd0e4, 0x000e, 0x0005, 0x0036, 0x0046, 0x6010, 0x00b6,
+ 0x2058, 0xbba0, 0x00be, 0x2021, 0x0007, 0x080c, 0x4ddf, 0x004e,
+ 0x003e, 0x0005, 0x0c51, 0x1d81, 0x0005, 0x2001, 0x1987, 0x2004,
+ 0x601a, 0x0005, 0x2001, 0x1989, 0x2004, 0x604a, 0x0005, 0x080c,
+ 0xaf4e, 0x0804, 0x98bc, 0x611c, 0xd1fc, 0xa97c, 0x1108, 0xd1e4,
+ 0x0005, 0x601c, 0xd0fc, 0xa87c, 0x1108, 0xd0e4, 0x0005, 0x601c,
+ 0xd0fc, 0xc0fc, 0x601e, 0xa87c, 0x1108, 0xd0e4, 0x0005, 0x6044,
+ 0xd0fc, 0x1138, 0xd0bc, 0x0198, 0xc0bc, 0x6046, 0x6003, 0x0002,
+ 0x0070, 0xd0ac, 0x1160, 0xd0dc, 0x1128, 0x908c, 0x000f, 0x9186,
+ 0x0005, 0x1118, 0x6003, 0x0003, 0x0010, 0x6003, 0x0001, 0x0005,
+ 0x00b6, 0x0066, 0x6000, 0x90b2, 0x0010, 0x1a0c, 0x0d79, 0x001b,
+ 0x006e, 0x00be, 0x0005, 0xd3cb, 0xdb14, 0xdc78, 0xd3cb, 0xd3cb,
+ 0xd3cb, 0xd3cb, 0xd3cb, 0xd402, 0xdcfc, 0xd3cb, 0xd3cb, 0xd3cb,
+ 0xd3cb, 0xd3cb, 0xd3cb, 0x080c, 0x0d79, 0x0066, 0x6000, 0x90b2,
+ 0x0010, 0x1a0c, 0x0d79, 0x0013, 0x006e, 0x0005, 0xd3e6, 0xe21d,
+ 0xd3e6, 0xd3e6, 0xd3e6, 0xd3e6, 0xd3e6, 0xd3e6, 0xe1cc, 0xe26f,
+ 0xd3e6, 0xe91f, 0xe953, 0xe91f, 0xe953, 0xd3e6, 0x080c, 0x0d79,
+ 0x6000, 0x9082, 0x0010, 0x1a0c, 0x0d79, 0x6000, 0x000a, 0x0005,
+ 0xd400, 0xded9, 0xdfa4, 0xdfc7, 0xe043, 0xd400, 0xe13e, 0xe0cb,
+ 0xdd06, 0xe1a4, 0xe1b9, 0xd400, 0xd400, 0xd400, 0xd400, 0xd400,
+ 0x080c, 0x0d79, 0x91b2, 0x0053, 0x1a0c, 0x0d79, 0x2100, 0x91b2,
+ 0x0040, 0x1a04, 0xd886, 0x0002, 0xd44c, 0xd654, 0xd44c, 0xd44c,
+ 0xd44c, 0xd65d, 0xd44c, 0xd44c, 0xd44c, 0xd44c, 0xd44c, 0xd44c,
+ 0xd44c, 0xd44c, 0xd44c, 0xd44c, 0xd44c, 0xd44c, 0xd44c, 0xd44c,
+ 0xd44c, 0xd44c, 0xd44c, 0xd44e, 0xd4b5, 0xd4c4, 0xd528, 0xd553,
+ 0xd5cc, 0xd63f, 0xd44c, 0xd44c, 0xd660, 0xd44c, 0xd44c, 0xd675,
+ 0xd682, 0xd44c, 0xd44c, 0xd44c, 0xd44c, 0xd44c, 0xd728, 0xd44c,
+ 0xd44c, 0xd73c, 0xd44c, 0xd44c, 0xd6f7, 0xd44c, 0xd44c, 0xd44c,
+ 0xd754, 0xd44c, 0xd44c, 0xd44c, 0xd7d1, 0xd44c, 0xd44c, 0xd44c,
+ 0xd44c, 0xd44c, 0xd44c, 0xd84e, 0x080c, 0x0d79, 0x080c, 0x6b8b,
+ 0x1150, 0x2001, 0x1837, 0x2004, 0xd0cc, 0x1128, 0x9084, 0x0009,
+ 0x9086, 0x0008, 0x1140, 0x6007, 0x0009, 0x602f, 0x0009, 0x6017,
+ 0x0000, 0x0804, 0xd64d, 0x080c, 0x6b27, 0x00e6, 0x00c6, 0x0036,
+ 0x0026, 0x0016, 0x6210, 0x2258, 0xbaa0, 0x0026, 0x2019, 0x0029,
+ 0x080c, 0xaaf7, 0x080c, 0x95b9, 0x0076, 0x903e, 0x080c, 0x9476,
+ 0x2c08, 0x080c, 0xe465, 0x007e, 0x001e, 0x080c, 0xab13, 0x001e,
+ 0x002e, 0x003e, 0x00ce, 0x00ee, 0x6610, 0x2658, 0x080c, 0x6792,
+ 0xbe04, 0x9684, 0x00ff, 0x9082, 0x0006, 0x1268, 0x0016, 0x0026,
+ 0x6210, 0x00b6, 0x2258, 0xbaa0, 0x00be, 0x2c08, 0x080c, 0xeb7e,
+ 0x002e, 0x001e, 0x1178, 0x080c, 0xe393, 0x1904, 0xd520, 0x080c,
+ 0xe32f, 0x1120, 0x6007, 0x0008, 0x0804, 0xd64d, 0x6007, 0x0009,
+ 0x0804, 0xd64d, 0x080c, 0xe60d, 0x0128, 0x080c, 0xe393, 0x0d78,
+ 0x0804, 0xd520, 0x6017, 0x1900, 0x0c88, 0x080c, 0x3432, 0x1904,
+ 0xd883, 0x6106, 0x080c, 0xe2cf, 0x6007, 0x0006, 0x0804, 0xd64d,
+ 0x6007, 0x0007, 0x0804, 0xd64d, 0x080c, 0xe98f, 0x1904, 0xd883,
+ 0x080c, 0x3432, 0x1904, 0xd883, 0x00d6, 0x6610, 0x2658, 0xbe04,
+ 0x9684, 0x00ff, 0x9082, 0x0006, 0x1220, 0x2001, 0x0001, 0x080c,
+ 0x66b5, 0x96b4, 0xff00, 0x8637, 0x9686, 0x0006, 0x0188, 0x9686,
+ 0x0004, 0x0170, 0xbe04, 0x96b4, 0x00ff, 0x9686, 0x0006, 0x0140,
+ 0x9686, 0x0004, 0x0128, 0x9686, 0x0005, 0x0110, 0x00de, 0x0480,
+ 0x00e6, 0x2071, 0x0260, 0x7034, 0x9084, 0x0003, 0x1140, 0x7034,
+ 0x9082, 0x0014, 0x0220, 0x7030, 0x9084, 0x0003, 0x0130, 0x00ee,
+ 0x6017, 0x0000, 0x602f, 0x0007, 0x00b0, 0x00ee, 0x080c, 0xe3fb,
+ 0x1190, 0x9686, 0x0006, 0x1140, 0x0026, 0x6210, 0x2258, 0xbaa0,
+ 0x900e, 0x080c, 0x334a, 0x002e, 0x080c, 0x681e, 0x6007, 0x000a,
+ 0x00de, 0x0804, 0xd64d, 0x6007, 0x000b, 0x00de, 0x0804, 0xd64d,
+ 0x080c, 0x32fb, 0x080c, 0xd372, 0x6007, 0x0001, 0x0804, 0xd64d,
+ 0x080c, 0xe98f, 0x1904, 0xd883, 0x080c, 0x3432, 0x1904, 0xd883,
+ 0x2071, 0x0260, 0x7034, 0x90b4, 0x0003, 0x1948, 0x90b2, 0x0014,
+ 0x0a30, 0x7030, 0x9084, 0x0003, 0x1910, 0x6610, 0x2658, 0xbe04,
+ 0x9686, 0x0707, 0x09e8, 0x0026, 0x6210, 0x2258, 0xbaa0, 0x900e,
+ 0x080c, 0x334a, 0x002e, 0x6007, 0x000c, 0x2001, 0x0001, 0x080c,
+ 0xeb5d, 0x0804, 0xd64d, 0x080c, 0x6b8b, 0x1140, 0x2001, 0x1837,
+ 0x2004, 0x9084, 0x0009, 0x9086, 0x0008, 0x1110, 0x0804, 0xd45b,
+ 0x080c, 0x6b27, 0x6610, 0x2658, 0xbe04, 0x9684, 0x00ff, 0x9082,
+ 0x0006, 0x06c8, 0x1138, 0x0026, 0x2001, 0x0006, 0x080c, 0x66f5,
+ 0x002e, 0x0050, 0x96b4, 0xff00, 0x8637, 0x9686, 0x0004, 0x0120,
+ 0x9686, 0x0006, 0x1904, 0xd520, 0x080c, 0xe408, 0x1120, 0x6007,
+ 0x000e, 0x0804, 0xd64d, 0x0046, 0x6410, 0x2458, 0xbca0, 0x0046,
+ 0x080c, 0x32fb, 0x080c, 0xd372, 0x004e, 0x0016, 0x9006, 0x2009,
+ 0x1848, 0x210c, 0xd1a4, 0x0148, 0x2009, 0x0029, 0x080c, 0xe795,
+ 0x6010, 0x2058, 0xb800, 0xc0e5, 0xb802, 0x001e, 0x004e, 0x6007,
+ 0x0001, 0x0804, 0xd64d, 0x2001, 0x0001, 0x080c, 0x66b5, 0x0156,
+ 0x0016, 0x0026, 0x0036, 0x20a9, 0x0004, 0x2019, 0x1805, 0x2011,
+ 0x0270, 0x080c, 0xbf40, 0x003e, 0x002e, 0x001e, 0x015e, 0x9005,
+ 0x0168, 0x96b4, 0xff00, 0x8637, 0x9682, 0x0004, 0x0a04, 0xd520,
+ 0x9682, 0x0007, 0x0a04, 0xd57c, 0x0804, 0xd520, 0x6017, 0x1900,
+ 0x6007, 0x0009, 0x0804, 0xd64d, 0x080c, 0x6b8b, 0x1140, 0x2001,
0x1837, 0x2004, 0x9084, 0x0009, 0x9086, 0x0008, 0x1110, 0x0804,
- 0xd43c, 0x080c, 0x6b2f, 0x6610, 0x2658, 0xbe04, 0x9684, 0x00ff,
- 0x9082, 0x0006, 0x06c8, 0x1138, 0x0026, 0x2001, 0x0006, 0x080c,
- 0x66fb, 0x002e, 0x0050, 0x96b4, 0xff00, 0x8637, 0x9686, 0x0004,
- 0x0120, 0x9686, 0x0006, 0x1904, 0xd501, 0x080c, 0xe3e3, 0x1120,
- 0x6007, 0x000e, 0x0804, 0xd62e, 0x0046, 0x6410, 0x2458, 0xbca0,
- 0x0046, 0x080c, 0x3310, 0x080c, 0xd353, 0x004e, 0x0016, 0x9006,
- 0x2009, 0x1848, 0x210c, 0xd1a4, 0x0148, 0x2009, 0x0029, 0x080c,
- 0xe72a, 0x6010, 0x2058, 0xb800, 0xc0e5, 0xb802, 0x001e, 0x004e,
- 0x6007, 0x0001, 0x0804, 0xd62e, 0x2001, 0x0001, 0x080c, 0x66bb,
- 0x0156, 0x0016, 0x0026, 0x0036, 0x20a9, 0x0004, 0x2019, 0x1805,
- 0x2011, 0x0270, 0x080c, 0xbf2a, 0x003e, 0x002e, 0x001e, 0x015e,
- 0x9005, 0x0168, 0x96b4, 0xff00, 0x8637, 0x9682, 0x0004, 0x0a04,
- 0xd501, 0x9682, 0x0007, 0x0a04, 0xd55d, 0x0804, 0xd501, 0x6017,
- 0x1900, 0x6007, 0x0009, 0x0804, 0xd62e, 0x080c, 0x6b93, 0x1140,
- 0x2001, 0x1837, 0x2004, 0x9084, 0x0009, 0x9086, 0x0008, 0x1110,
- 0x0804, 0xd43c, 0x080c, 0x6b2f, 0x6610, 0x2658, 0xbe04, 0x9684,
- 0x00ff, 0x0006, 0x0016, 0x908e, 0x0001, 0x0118, 0x908e, 0x0000,
- 0x1118, 0x001e, 0x000e, 0x0080, 0x001e, 0x000e, 0x9082, 0x0006,
- 0x06a0, 0x0150, 0x96b4, 0xff00, 0x8637, 0x9686, 0x0004, 0x0120,
- 0x9686, 0x0006, 0x1904, 0xd501, 0x080c, 0xe411, 0x1138, 0x080c,
- 0xe30a, 0x1120, 0x6007, 0x0010, 0x0804, 0xd62e, 0x0046, 0x6410,
- 0x2458, 0xbca0, 0x0046, 0x080c, 0x3310, 0x080c, 0xd353, 0x004e,
- 0x0016, 0x9006, 0x2009, 0x1848, 0x210c, 0xd1a4, 0x0148, 0x2009,
- 0x0029, 0x080c, 0xe72a, 0x6010, 0x2058, 0xb800, 0xc0e5, 0xb802,
- 0x001e, 0x004e, 0x6007, 0x0001, 0x0448, 0x080c, 0xe5a2, 0x0198,
- 0x0016, 0x968c, 0x00ff, 0x9186, 0x0002, 0x0160, 0x9186, 0x0003,
- 0x0148, 0x001e, 0x96b4, 0xff00, 0x8637, 0x9686, 0x0006, 0x0920,
- 0x0804, 0xd501, 0x001e, 0x6017, 0x1900, 0x6007, 0x0009, 0x0070,
- 0x080c, 0x3447, 0x1904, 0xd864, 0x080c, 0xe924, 0x1904, 0xd864,
- 0x080c, 0xda35, 0x1904, 0xd501, 0x6007, 0x0012, 0x6003, 0x0001,
- 0x080c, 0x942f, 0x080c, 0x98bf, 0x0005, 0x6007, 0x0001, 0x6003,
- 0x0001, 0x080c, 0x942f, 0x080c, 0x98bf, 0x0cb0, 0x6007, 0x0005,
- 0x0c68, 0x080c, 0xe924, 0x1904, 0xd864, 0x080c, 0x3447, 0x1904,
- 0xd864, 0x080c, 0xda35, 0x1904, 0xd501, 0x6007, 0x0020, 0x6003,
- 0x0001, 0x080c, 0x942f, 0x080c, 0x98bf, 0x0005, 0x080c, 0x3447,
- 0x1904, 0xd864, 0x6007, 0x0023, 0x6003, 0x0001, 0x080c, 0x942f,
- 0x080c, 0x98bf, 0x0005, 0x080c, 0xe924, 0x1904, 0xd864, 0x080c,
- 0x3447, 0x1904, 0xd864, 0x080c, 0xda35, 0x1904, 0xd501, 0x0016,
- 0x0026, 0x00e6, 0x2071, 0x0260, 0x2c08, 0x2011, 0x1820, 0x2214,
- 0x703c, 0x9206, 0x11e0, 0x2011, 0x181f, 0x2214, 0x7038, 0x9084,
- 0x00ff, 0x9206, 0x11a0, 0x7240, 0x080c, 0xcc04, 0x0570, 0x2260,
- 0x6008, 0x9086, 0xffff, 0x0120, 0x7244, 0x6008, 0x9206, 0x1528,
- 0x6020, 0x9086, 0x0007, 0x1508, 0x080c, 0xaf2e, 0x04a0, 0x7244,
- 0x9286, 0xffff, 0x0180, 0x2c08, 0x080c, 0xcc04, 0x01b0, 0x2260,
- 0x7240, 0x6008, 0x9206, 0x1188, 0x6010, 0x9190, 0x0004, 0x2214,
- 0x9206, 0x01b8, 0x0050, 0x7240, 0x2c08, 0x9006, 0x080c, 0xe6f4,
- 0x1180, 0x7244, 0x9286, 0xffff, 0x01b0, 0x2160, 0x6007, 0x0026,
- 0x6017, 0x1700, 0x7214, 0x9296, 0xffff, 0x1180, 0x6007, 0x0025,
- 0x0068, 0x6020, 0x9086, 0x0007, 0x1d80, 0x6004, 0x9086, 0x0024,
- 0x1110, 0x080c, 0xaf2e, 0x2160, 0x6007, 0x0025, 0x6003, 0x0001,
- 0x080c, 0x942f, 0x080c, 0x98bf, 0x00ee, 0x002e, 0x001e, 0x0005,
- 0x2001, 0x0001, 0x080c, 0x66bb, 0x0156, 0x0016, 0x0026, 0x0036,
- 0x20a9, 0x0004, 0x2019, 0x1805, 0x2011, 0x0276, 0x080c, 0xbf2a,
- 0x003e, 0x002e, 0x001e, 0x015e, 0x0120, 0x6007, 0x0031, 0x0804,
- 0xd62e, 0x080c, 0xbb99, 0x080c, 0x76a5, 0x1190, 0x0006, 0x0026,
- 0x0036, 0x080c, 0x76bf, 0x1138, 0x080c, 0x79a7, 0x080c, 0x617e,
- 0x080c, 0x75d4, 0x0010, 0x080c, 0x7679, 0x003e, 0x002e, 0x000e,
- 0x0005, 0x080c, 0x3447, 0x1904, 0xd864, 0x080c, 0xda35, 0x1904,
- 0xd501, 0x6106, 0x080c, 0xda51, 0x1120, 0x6007, 0x002b, 0x0804,
- 0xd62e, 0x6007, 0x002c, 0x0804, 0xd62e, 0x080c, 0xe924, 0x1904,
- 0xd864, 0x080c, 0x3447, 0x1904, 0xd864, 0x080c, 0xda35, 0x1904,
- 0xd501, 0x6106, 0x080c, 0xda56, 0x1120, 0x6007, 0x002e, 0x0804,
- 0xd62e, 0x6007, 0x002f, 0x0804, 0xd62e, 0x080c, 0x3447, 0x1904,
- 0xd864, 0x00e6, 0x00d6, 0x00c6, 0x6010, 0x2058, 0xb904, 0x9184,
- 0x00ff, 0x9086, 0x0006, 0x0158, 0x9184, 0xff00, 0x8007, 0x9086,
- 0x0006, 0x0128, 0x00ce, 0x00de, 0x00ee, 0x0804, 0xd635, 0x080c,
- 0x582a, 0xd0e4, 0x0904, 0xd7af, 0x2071, 0x026c, 0x7010, 0x603a,
- 0x7014, 0x603e, 0x7108, 0x720c, 0x080c, 0x6bd1, 0x0140, 0x6010,
- 0x2058, 0xb810, 0x9106, 0x1118, 0xb814, 0x9206, 0x0510, 0x080c,
- 0x6bcd, 0x15b8, 0x2069, 0x1800, 0x6880, 0x9206, 0x1590, 0x687c,
- 0x9106, 0x1578, 0x7210, 0x080c, 0xcc04, 0x0590, 0x080c, 0xd922,
- 0x0578, 0x080c, 0xe7a6, 0x0560, 0x622e, 0x6007, 0x0036, 0x6003,
- 0x0001, 0x2009, 0x8020, 0x080c, 0x9428, 0x00ce, 0x00de, 0x00ee,
- 0x0005, 0x7214, 0x9286, 0xffff, 0x0150, 0x080c, 0xcc04, 0x01c0,
- 0x9280, 0x0002, 0x2004, 0x7110, 0x9106, 0x1190, 0x08e0, 0x7210,
- 0x2c08, 0x9085, 0x0001, 0x080c, 0xe6f4, 0x2c10, 0x2160, 0x0140,
- 0x0890, 0x6007, 0x0037, 0x602f, 0x0009, 0x6017, 0x1500, 0x08b8,
- 0x6007, 0x0037, 0x602f, 0x0003, 0x6017, 0x1700, 0x0880, 0x6007,
- 0x0012, 0x0868, 0x080c, 0x3447, 0x1904, 0xd864, 0x6010, 0x2058,
- 0xb804, 0x9084, 0xff00, 0x8007, 0x9086, 0x0006, 0x1904, 0xd635,
- 0x00e6, 0x00d6, 0x00c6, 0x080c, 0x582a, 0xd0e4, 0x0904, 0xd827,
- 0x2069, 0x1800, 0x2071, 0x026c, 0x7008, 0x603a, 0x720c, 0x623e,
- 0x9286, 0xffff, 0x1150, 0x7208, 0x00c6, 0x2c08, 0x9085, 0x0001,
- 0x080c, 0xe6f4, 0x2c10, 0x00ce, 0x05e8, 0x080c, 0xcc04, 0x05d0,
- 0x7108, 0x9280, 0x0002, 0x2004, 0x9106, 0x15a0, 0x00c6, 0x0026,
- 0x2260, 0x080c, 0xc7f5, 0x002e, 0x00ce, 0x7118, 0x918c, 0xff00,
- 0x810f, 0x9186, 0x0001, 0x0178, 0x9186, 0x0005, 0x0118, 0x9186,
- 0x0007, 0x1198, 0x9280, 0x0005, 0x2004, 0x9005, 0x0170, 0x080c,
- 0xd922, 0x0904, 0xd7a8, 0x0056, 0x7510, 0x7614, 0x080c, 0xe7bf,
- 0x005e, 0x00ce, 0x00de, 0x00ee, 0x0005, 0x6007, 0x003b, 0x602f,
- 0x0009, 0x6017, 0x2a00, 0x6003, 0x0001, 0x2009, 0x8020, 0x080c,
- 0x9428, 0x0c78, 0x6007, 0x003b, 0x602f, 0x0003, 0x6017, 0x0300,
- 0x6003, 0x0001, 0x2009, 0x8020, 0x080c, 0x9428, 0x0c10, 0x6007,
- 0x003b, 0x602f, 0x000b, 0x6017, 0x0000, 0x0804, 0xd77f, 0x00e6,
- 0x0026, 0x080c, 0x6b93, 0x0550, 0x080c, 0x6b2f, 0x080c, 0xe995,
- 0x1518, 0x2071, 0x1800, 0x70dc, 0x9085, 0x0003, 0x70de, 0x00f6,
- 0x2079, 0x0100, 0x72b0, 0x9284, 0x00ff, 0x707e, 0x78e6, 0x9284,
- 0xff00, 0x7280, 0x9205, 0x7082, 0x78ea, 0x00fe, 0x70e7, 0x0000,
- 0x080c, 0x6bd1, 0x0120, 0x2011, 0x1a0b, 0x2013, 0x07d0, 0xd0ac,
- 0x1128, 0x080c, 0x30e1, 0x0010, 0x080c, 0xe9c9, 0x002e, 0x00ee,
- 0x080c, 0xaf2e, 0x0804, 0xd634, 0x080c, 0xaf2e, 0x0005, 0x2600,
- 0x0002, 0xd87b, 0xd8a9, 0xd8ba, 0xd87b, 0xd87b, 0xd87d, 0xd8cb,
- 0xd87b, 0xd87b, 0xd87b, 0xd897, 0xd87b, 0xd87b, 0xd87b, 0xd8d6,
- 0xd8ec, 0xd91d, 0xd87b, 0x080c, 0x0d85, 0x080c, 0xe924, 0x1d20,
- 0x080c, 0x3447, 0x1d08, 0x7038, 0x6016, 0x6007, 0x0045, 0x6003,
- 0x0001, 0x080c, 0x942f, 0x0005, 0x080c, 0x3310, 0x080c, 0xd353,
- 0x6007, 0x0001, 0x6003, 0x0001, 0x080c, 0x942f, 0x0005, 0x080c,
- 0xe924, 0x1950, 0x080c, 0x3447, 0x1938, 0x080c, 0xda35, 0x1d60,
- 0x703c, 0x6016, 0x6007, 0x004a, 0x6003, 0x0001, 0x080c, 0x942f,
- 0x0005, 0x080c, 0x3447, 0x1904, 0xd864, 0x2009, 0x0041, 0x080c,
- 0xe9d2, 0x6007, 0x0047, 0x6003, 0x0001, 0x080c, 0x942f, 0x080c,
- 0x98bf, 0x0005, 0x080c, 0x3447, 0x1904, 0xd864, 0x2009, 0x0042,
- 0x080c, 0xe9d2, 0x6007, 0x0047, 0x6003, 0x0001, 0x080c, 0x942f,
- 0x080c, 0x98bf, 0x0005, 0x080c, 0x3447, 0x1904, 0xd864, 0x2009,
- 0x0046, 0x080c, 0xe9d2, 0x080c, 0xaf2e, 0x0005, 0x2001, 0x1824,
- 0x2004, 0x9082, 0x00e1, 0x1268, 0x080c, 0xd93f, 0x0904, 0xd864,
- 0x6007, 0x004e, 0x6003, 0x0001, 0x080c, 0x942f, 0x080c, 0x98bf,
- 0x0005, 0x6007, 0x0012, 0x0cb0, 0x6007, 0x004f, 0x6017, 0x0000,
- 0x7134, 0x918c, 0x00ff, 0x81ff, 0x0508, 0x9186, 0x0001, 0x1160,
- 0x7140, 0x2001, 0x19bf, 0x2004, 0x9106, 0x11b0, 0x7144, 0x2001,
- 0x19c0, 0x2004, 0x9106, 0x0190, 0x9186, 0x0002, 0x1168, 0x2011,
- 0x0276, 0x20a9, 0x0004, 0x6010, 0x0096, 0x2048, 0x2019, 0x000a,
- 0x080c, 0xbf3e, 0x009e, 0x0110, 0x6017, 0x0001, 0x6003, 0x0001,
- 0x080c, 0x942f, 0x080c, 0x98bf, 0x0005, 0x6007, 0x0050, 0x703c,
- 0x6016, 0x0ca0, 0x0016, 0x00e6, 0x2071, 0x0260, 0x00b6, 0x00c6,
- 0x2260, 0x6010, 0x2058, 0xb8d4, 0xd084, 0x0150, 0x7128, 0x604c,
- 0x9106, 0x1120, 0x712c, 0x6050, 0x9106, 0x0110, 0x9006, 0x0010,
- 0x9085, 0x0001, 0x00ce, 0x00be, 0x00ee, 0x001e, 0x0005, 0x0016,
- 0x0096, 0x0086, 0x00e6, 0x01c6, 0x01d6, 0x0126, 0x2091, 0x8000,
- 0x2071, 0x1800, 0x20e1, 0x0000, 0x2001, 0x19a1, 0x2003, 0x0000,
- 0x080c, 0x1072, 0x05a0, 0x2900, 0x6016, 0x7090, 0x8004, 0xa816,
- 0x908a, 0x001e, 0x02d0, 0xa833, 0x001e, 0x20a9, 0x001e, 0xa860,
- 0x20e8, 0xa85c, 0x9080, 0x001b, 0x20a0, 0x2001, 0x19a1, 0x0016,
- 0x200c, 0x0471, 0x001e, 0x81ff, 0x01b8, 0x2940, 0x080c, 0x1072,
- 0x01b0, 0x2900, 0xa006, 0x2100, 0x0c18, 0xa832, 0x20a8, 0xa860,
- 0x20e8, 0xa85c, 0x9080, 0x001b, 0x20a0, 0x2001, 0x19a1, 0x0016,
- 0x200c, 0x00b1, 0x001e, 0x0000, 0x9085, 0x0001, 0x0048, 0x2071,
- 0x1800, 0x7093, 0x0000, 0x6014, 0x2048, 0x080c, 0x100b, 0x9006,
- 0x012e, 0x01de, 0x01ce, 0x00ee, 0x008e, 0x009e, 0x001e, 0x0005,
- 0x0006, 0x0016, 0x0026, 0x0036, 0x00c6, 0x918c, 0xffff, 0x11b0,
- 0x080c, 0x221a, 0x2099, 0x026c, 0x2001, 0x0014, 0x3518, 0x9312,
- 0x0108, 0x1218, 0x23a8, 0x4003, 0x0400, 0x20a8, 0x4003, 0x22a8,
- 0x8108, 0x080c, 0x221a, 0x2099, 0x0260, 0x0ca8, 0x080c, 0x221a,
- 0x2061, 0x19a1, 0x6004, 0x2098, 0x6008, 0x3518, 0x9312, 0x0108,
- 0x1218, 0x23a8, 0x4003, 0x0048, 0x20a8, 0x4003, 0x22a8, 0x8108,
- 0x080c, 0x221a, 0x2099, 0x0260, 0x0ca8, 0x2061, 0x19a1, 0x2019,
- 0x0280, 0x3300, 0x931e, 0x0110, 0x6006, 0x0020, 0x2001, 0x0260,
- 0x6006, 0x8108, 0x2162, 0x9292, 0x0021, 0x9296, 0xffff, 0x620a,
- 0x00ce, 0x003e, 0x002e, 0x001e, 0x000e, 0x0005, 0x0006, 0x0016,
- 0x0026, 0x0036, 0x00c6, 0x81ff, 0x11b8, 0x080c, 0x2232, 0x20a1,
- 0x024c, 0x2001, 0x0014, 0x3518, 0x9312, 0x1218, 0x23a8, 0x4003,
- 0x0418, 0x20a8, 0x4003, 0x82ff, 0x01f8, 0x22a8, 0x8108, 0x080c,
- 0x2232, 0x20a1, 0x0240, 0x0c98, 0x080c, 0x2232, 0x2061, 0x19a4,
- 0x6004, 0x20a0, 0x6008, 0x3518, 0x9312, 0x1218, 0x23a8, 0x4003,
- 0x0058, 0x20a8, 0x4003, 0x82ff, 0x0138, 0x22a8, 0x8108, 0x080c,
- 0x2232, 0x20a1, 0x0240, 0x0c98, 0x2061, 0x19a4, 0x2019, 0x0260,
- 0x3400, 0x931e, 0x0110, 0x6006, 0x0020, 0x2001, 0x0240, 0x6006,
+ 0xd45b, 0x080c, 0x6b27, 0x6610, 0x2658, 0xbe04, 0x9684, 0x00ff,
+ 0x0006, 0x0016, 0x908e, 0x0001, 0x0118, 0x908e, 0x0000, 0x1118,
+ 0x001e, 0x000e, 0x0080, 0x001e, 0x000e, 0x9082, 0x0006, 0x06a0,
+ 0x0150, 0x96b4, 0xff00, 0x8637, 0x9686, 0x0004, 0x0120, 0x9686,
+ 0x0006, 0x1904, 0xd520, 0x080c, 0xe436, 0x1138, 0x080c, 0xe32f,
+ 0x1120, 0x6007, 0x0010, 0x0804, 0xd64d, 0x0046, 0x6410, 0x2458,
+ 0xbca0, 0x0046, 0x080c, 0x32fb, 0x080c, 0xd372, 0x004e, 0x0016,
+ 0x9006, 0x2009, 0x1848, 0x210c, 0xd1a4, 0x0148, 0x2009, 0x0029,
+ 0x080c, 0xe795, 0x6010, 0x2058, 0xb800, 0xc0e5, 0xb802, 0x001e,
+ 0x004e, 0x6007, 0x0001, 0x0448, 0x080c, 0xe60d, 0x0198, 0x0016,
+ 0x968c, 0x00ff, 0x9186, 0x0002, 0x0160, 0x9186, 0x0003, 0x0148,
+ 0x001e, 0x96b4, 0xff00, 0x8637, 0x9686, 0x0006, 0x0920, 0x0804,
+ 0xd520, 0x001e, 0x6017, 0x1900, 0x6007, 0x0009, 0x0070, 0x080c,
+ 0x3432, 0x1904, 0xd883, 0x080c, 0xe98f, 0x1904, 0xd883, 0x080c,
+ 0xda54, 0x1904, 0xd520, 0x6007, 0x0012, 0x6003, 0x0001, 0x080c,
+ 0x9427, 0x080c, 0x98bc, 0x0005, 0x6007, 0x0001, 0x6003, 0x0001,
+ 0x080c, 0x9427, 0x080c, 0x98bc, 0x0cb0, 0x6007, 0x0005, 0x0c68,
+ 0x080c, 0xe98f, 0x1904, 0xd883, 0x080c, 0x3432, 0x1904, 0xd883,
+ 0x080c, 0xda54, 0x1904, 0xd520, 0x6007, 0x0020, 0x6003, 0x0001,
+ 0x080c, 0x9427, 0x080c, 0x98bc, 0x0005, 0x080c, 0x3432, 0x1904,
+ 0xd883, 0x6007, 0x0023, 0x6003, 0x0001, 0x080c, 0x9427, 0x080c,
+ 0x98bc, 0x0005, 0x080c, 0xe98f, 0x1904, 0xd883, 0x080c, 0x3432,
+ 0x1904, 0xd883, 0x080c, 0xda54, 0x1904, 0xd520, 0x0016, 0x0026,
+ 0x00e6, 0x2071, 0x0260, 0x2c08, 0x2011, 0x1820, 0x2214, 0x703c,
+ 0x9206, 0x11e0, 0x2011, 0x181f, 0x2214, 0x7038, 0x9084, 0x00ff,
+ 0x9206, 0x11a0, 0x7240, 0x080c, 0xcc21, 0x0570, 0x2260, 0x6008,
+ 0x9086, 0xffff, 0x0120, 0x7244, 0x6008, 0x9206, 0x1528, 0x6020,
+ 0x9086, 0x0007, 0x1508, 0x080c, 0xaf4e, 0x04a0, 0x7244, 0x9286,
+ 0xffff, 0x0180, 0x2c08, 0x080c, 0xcc21, 0x01b0, 0x2260, 0x7240,
+ 0x6008, 0x9206, 0x1188, 0x6010, 0x9190, 0x0004, 0x2214, 0x9206,
+ 0x01b8, 0x0050, 0x7240, 0x2c08, 0x9006, 0x080c, 0xe75f, 0x1180,
+ 0x7244, 0x9286, 0xffff, 0x01b0, 0x2160, 0x6007, 0x0026, 0x6017,
+ 0x1700, 0x7214, 0x9296, 0xffff, 0x1180, 0x6007, 0x0025, 0x0068,
+ 0x6020, 0x9086, 0x0007, 0x1d80, 0x6004, 0x9086, 0x0024, 0x1110,
+ 0x080c, 0xaf4e, 0x2160, 0x6007, 0x0025, 0x6003, 0x0001, 0x080c,
+ 0x9427, 0x080c, 0x98bc, 0x00ee, 0x002e, 0x001e, 0x0005, 0x2001,
+ 0x0001, 0x080c, 0x66b5, 0x0156, 0x0016, 0x0026, 0x0036, 0x20a9,
+ 0x0004, 0x2019, 0x1805, 0x2011, 0x0276, 0x080c, 0xbf40, 0x003e,
+ 0x002e, 0x001e, 0x015e, 0x0120, 0x6007, 0x0031, 0x0804, 0xd64d,
+ 0x080c, 0xbbaa, 0x080c, 0x769d, 0x1190, 0x0006, 0x0026, 0x0036,
+ 0x080c, 0x76b7, 0x1138, 0x080c, 0x799f, 0x080c, 0x6178, 0x080c,
+ 0x75cc, 0x0010, 0x080c, 0x7671, 0x003e, 0x002e, 0x000e, 0x0005,
+ 0x080c, 0x3432, 0x1904, 0xd883, 0x080c, 0xda54, 0x1904, 0xd520,
+ 0x6106, 0x080c, 0xda70, 0x1120, 0x6007, 0x002b, 0x0804, 0xd64d,
+ 0x6007, 0x002c, 0x0804, 0xd64d, 0x080c, 0xe98f, 0x1904, 0xd883,
+ 0x080c, 0x3432, 0x1904, 0xd883, 0x080c, 0xda54, 0x1904, 0xd520,
+ 0x6106, 0x080c, 0xda75, 0x1120, 0x6007, 0x002e, 0x0804, 0xd64d,
+ 0x6007, 0x002f, 0x0804, 0xd64d, 0x080c, 0x3432, 0x1904, 0xd883,
+ 0x00e6, 0x00d6, 0x00c6, 0x6010, 0x2058, 0xb904, 0x9184, 0x00ff,
+ 0x9086, 0x0006, 0x0158, 0x9184, 0xff00, 0x8007, 0x9086, 0x0006,
+ 0x0128, 0x00ce, 0x00de, 0x00ee, 0x0804, 0xd654, 0x080c, 0x5824,
+ 0xd0e4, 0x0904, 0xd7ce, 0x2071, 0x026c, 0x7010, 0x603a, 0x7014,
+ 0x603e, 0x7108, 0x720c, 0x080c, 0x6bc9, 0x0140, 0x6010, 0x2058,
+ 0xb810, 0x9106, 0x1118, 0xb814, 0x9206, 0x0510, 0x080c, 0x6bc5,
+ 0x15b8, 0x2069, 0x1800, 0x6880, 0x9206, 0x1590, 0x687c, 0x9106,
+ 0x1578, 0x7210, 0x080c, 0xcc21, 0x0590, 0x080c, 0xd941, 0x0578,
+ 0x080c, 0xe811, 0x0560, 0x622e, 0x6007, 0x0036, 0x6003, 0x0001,
+ 0x2009, 0x8020, 0x080c, 0x9420, 0x00ce, 0x00de, 0x00ee, 0x0005,
+ 0x7214, 0x9286, 0xffff, 0x0150, 0x080c, 0xcc21, 0x01c0, 0x9280,
+ 0x0002, 0x2004, 0x7110, 0x9106, 0x1190, 0x08e0, 0x7210, 0x2c08,
+ 0x9085, 0x0001, 0x080c, 0xe75f, 0x2c10, 0x2160, 0x0140, 0x0890,
+ 0x6007, 0x0037, 0x602f, 0x0009, 0x6017, 0x1500, 0x08b8, 0x6007,
+ 0x0037, 0x602f, 0x0003, 0x6017, 0x1700, 0x0880, 0x6007, 0x0012,
+ 0x0868, 0x080c, 0x3432, 0x1904, 0xd883, 0x6010, 0x2058, 0xb804,
+ 0x9084, 0xff00, 0x8007, 0x9086, 0x0006, 0x1904, 0xd654, 0x00e6,
+ 0x00d6, 0x00c6, 0x080c, 0x5824, 0xd0e4, 0x0904, 0xd846, 0x2069,
+ 0x1800, 0x2071, 0x026c, 0x7008, 0x603a, 0x720c, 0x623e, 0x9286,
+ 0xffff, 0x1150, 0x7208, 0x00c6, 0x2c08, 0x9085, 0x0001, 0x080c,
+ 0xe75f, 0x2c10, 0x00ce, 0x05e8, 0x080c, 0xcc21, 0x05d0, 0x7108,
+ 0x9280, 0x0002, 0x2004, 0x9106, 0x15a0, 0x00c6, 0x0026, 0x2260,
+ 0x080c, 0xc80e, 0x002e, 0x00ce, 0x7118, 0x918c, 0xff00, 0x810f,
+ 0x9186, 0x0001, 0x0178, 0x9186, 0x0005, 0x0118, 0x9186, 0x0007,
+ 0x1198, 0x9280, 0x0005, 0x2004, 0x9005, 0x0170, 0x080c, 0xd941,
+ 0x0904, 0xd7c7, 0x0056, 0x7510, 0x7614, 0x080c, 0xe82a, 0x005e,
+ 0x00ce, 0x00de, 0x00ee, 0x0005, 0x6007, 0x003b, 0x602f, 0x0009,
+ 0x6017, 0x2a00, 0x6003, 0x0001, 0x2009, 0x8020, 0x080c, 0x9420,
+ 0x0c78, 0x6007, 0x003b, 0x602f, 0x0003, 0x6017, 0x0300, 0x6003,
+ 0x0001, 0x2009, 0x8020, 0x080c, 0x9420, 0x0c10, 0x6007, 0x003b,
+ 0x602f, 0x000b, 0x6017, 0x0000, 0x0804, 0xd79e, 0x00e6, 0x0026,
+ 0x080c, 0x6b8b, 0x0550, 0x080c, 0x6b27, 0x080c, 0xea00, 0x1518,
+ 0x2071, 0x1800, 0x70dc, 0x9085, 0x0003, 0x70de, 0x00f6, 0x2079,
+ 0x0100, 0x72b0, 0x9284, 0x00ff, 0x707e, 0x78e6, 0x9284, 0xff00,
+ 0x7280, 0x9205, 0x7082, 0x78ea, 0x00fe, 0x70e7, 0x0000, 0x080c,
+ 0x6bc9, 0x0120, 0x2011, 0x1a0b, 0x2013, 0x07d0, 0xd0ac, 0x1128,
+ 0x080c, 0x30c8, 0x0010, 0x080c, 0xea34, 0x002e, 0x00ee, 0x080c,
+ 0xaf4e, 0x0804, 0xd653, 0x080c, 0xaf4e, 0x0005, 0x2600, 0x0002,
+ 0xd89a, 0xd8c8, 0xd8d9, 0xd89a, 0xd89a, 0xd89c, 0xd8ea, 0xd89a,
+ 0xd89a, 0xd89a, 0xd8b6, 0xd89a, 0xd89a, 0xd89a, 0xd8f5, 0xd90b,
+ 0xd93c, 0xd89a, 0x080c, 0x0d79, 0x080c, 0xe98f, 0x1d20, 0x080c,
+ 0x3432, 0x1d08, 0x7038, 0x6016, 0x6007, 0x0045, 0x6003, 0x0001,
+ 0x080c, 0x9427, 0x0005, 0x080c, 0x32fb, 0x080c, 0xd372, 0x6007,
+ 0x0001, 0x6003, 0x0001, 0x080c, 0x9427, 0x0005, 0x080c, 0xe98f,
+ 0x1950, 0x080c, 0x3432, 0x1938, 0x080c, 0xda54, 0x1d60, 0x703c,
+ 0x6016, 0x6007, 0x004a, 0x6003, 0x0001, 0x080c, 0x9427, 0x0005,
+ 0x080c, 0x3432, 0x1904, 0xd883, 0x2009, 0x0041, 0x080c, 0xea3d,
+ 0x6007, 0x0047, 0x6003, 0x0001, 0x080c, 0x9427, 0x080c, 0x98bc,
+ 0x0005, 0x080c, 0x3432, 0x1904, 0xd883, 0x2009, 0x0042, 0x080c,
+ 0xea3d, 0x6007, 0x0047, 0x6003, 0x0001, 0x080c, 0x9427, 0x080c,
+ 0x98bc, 0x0005, 0x080c, 0x3432, 0x1904, 0xd883, 0x2009, 0x0046,
+ 0x080c, 0xea3d, 0x080c, 0xaf4e, 0x0005, 0x2001, 0x1824, 0x2004,
+ 0x9082, 0x00e1, 0x1268, 0x080c, 0xd95e, 0x0904, 0xd883, 0x6007,
+ 0x004e, 0x6003, 0x0001, 0x080c, 0x9427, 0x080c, 0x98bc, 0x0005,
+ 0x6007, 0x0012, 0x0cb0, 0x6007, 0x004f, 0x6017, 0x0000, 0x7134,
+ 0x918c, 0x00ff, 0x81ff, 0x0508, 0x9186, 0x0001, 0x1160, 0x7140,
+ 0x2001, 0x19bf, 0x2004, 0x9106, 0x11b0, 0x7144, 0x2001, 0x19c0,
+ 0x2004, 0x9106, 0x0190, 0x9186, 0x0002, 0x1168, 0x2011, 0x0276,
+ 0x20a9, 0x0004, 0x6010, 0x0096, 0x2048, 0x2019, 0x000a, 0x080c,
+ 0xbf54, 0x009e, 0x0110, 0x6017, 0x0001, 0x6003, 0x0001, 0x080c,
+ 0x9427, 0x080c, 0x98bc, 0x0005, 0x6007, 0x0050, 0x703c, 0x6016,
+ 0x0ca0, 0x0016, 0x00e6, 0x2071, 0x0260, 0x00b6, 0x00c6, 0x2260,
+ 0x6010, 0x2058, 0xb8d4, 0xd084, 0x0150, 0x7128, 0x604c, 0x9106,
+ 0x1120, 0x712c, 0x6050, 0x9106, 0x0110, 0x9006, 0x0010, 0x9085,
+ 0x0001, 0x00ce, 0x00be, 0x00ee, 0x001e, 0x0005, 0x0016, 0x0096,
+ 0x0086, 0x00e6, 0x01c6, 0x01d6, 0x0126, 0x2091, 0x8000, 0x2071,
+ 0x1800, 0x20e1, 0x0000, 0x2001, 0x19a2, 0x2003, 0x0000, 0x080c,
+ 0x1066, 0x05a0, 0x2900, 0x6016, 0x7090, 0x8004, 0xa816, 0x908a,
+ 0x001e, 0x02d0, 0xa833, 0x001e, 0x20a9, 0x001e, 0xa860, 0x20e8,
+ 0xa85c, 0x9080, 0x001b, 0x20a0, 0x2001, 0x19a2, 0x0016, 0x200c,
+ 0x0471, 0x001e, 0x81ff, 0x01b8, 0x2940, 0x080c, 0x1066, 0x01b0,
+ 0x2900, 0xa006, 0x2100, 0x0c18, 0xa832, 0x20a8, 0xa860, 0x20e8,
+ 0xa85c, 0x9080, 0x001b, 0x20a0, 0x2001, 0x19a2, 0x0016, 0x200c,
+ 0x00b1, 0x001e, 0x0000, 0x9085, 0x0001, 0x0048, 0x2071, 0x1800,
+ 0x7093, 0x0000, 0x6014, 0x2048, 0x080c, 0x0fff, 0x9006, 0x012e,
+ 0x01de, 0x01ce, 0x00ee, 0x008e, 0x009e, 0x001e, 0x0005, 0x0006,
+ 0x0016, 0x0026, 0x0036, 0x00c6, 0x918c, 0xffff, 0x11b0, 0x080c,
+ 0x2216, 0x2099, 0x026c, 0x2001, 0x0014, 0x3518, 0x9312, 0x0108,
+ 0x1218, 0x23a8, 0x4003, 0x0400, 0x20a8, 0x4003, 0x22a8, 0x8108,
+ 0x080c, 0x2216, 0x2099, 0x0260, 0x0ca8, 0x080c, 0x2216, 0x2061,
+ 0x19a2, 0x6004, 0x2098, 0x6008, 0x3518, 0x9312, 0x0108, 0x1218,
+ 0x23a8, 0x4003, 0x0048, 0x20a8, 0x4003, 0x22a8, 0x8108, 0x080c,
+ 0x2216, 0x2099, 0x0260, 0x0ca8, 0x2061, 0x19a2, 0x2019, 0x0280,
+ 0x3300, 0x931e, 0x0110, 0x6006, 0x0020, 0x2001, 0x0260, 0x6006,
0x8108, 0x2162, 0x9292, 0x0021, 0x9296, 0xffff, 0x620a, 0x00ce,
- 0x003e, 0x002e, 0x001e, 0x000e, 0x0005, 0x00b6, 0x0066, 0x6610,
- 0x2658, 0xbe04, 0x96b4, 0xff00, 0x8637, 0x9686, 0x0006, 0x0170,
- 0x9686, 0x0004, 0x0158, 0xbe04, 0x96b4, 0x00ff, 0x9686, 0x0006,
- 0x0128, 0x9686, 0x0004, 0x0110, 0x9085, 0x0001, 0x006e, 0x00be,
- 0x0005, 0x00d6, 0x080c, 0xdacb, 0x00de, 0x0005, 0x00d6, 0x080c,
- 0xdad8, 0x1520, 0x680c, 0x908c, 0xff00, 0x6820, 0x9084, 0x00ff,
- 0x9115, 0x6216, 0x6824, 0x602e, 0xd1e4, 0x0130, 0x9006, 0x080c,
- 0xeaf2, 0x2009, 0x0001, 0x0078, 0xd1ec, 0x0180, 0x6920, 0x918c,
- 0x00ff, 0x6824, 0x080c, 0x26a2, 0x1148, 0x2001, 0x0001, 0x080c,
- 0xeaf2, 0x2110, 0x900e, 0x080c, 0x335f, 0x0018, 0x9085, 0x0001,
- 0x0008, 0x9006, 0x00de, 0x0005, 0x00b6, 0x00c6, 0x080c, 0xaf9f,
- 0x0598, 0x0016, 0x0026, 0x00c6, 0x2011, 0x0263, 0x2204, 0x8211,
- 0x220c, 0x080c, 0x26a2, 0x1568, 0x080c, 0x671e, 0x1550, 0xbe12,
- 0xbd16, 0x00ce, 0x002e, 0x001e, 0x2b00, 0x6012, 0x080c, 0xe924,
- 0x11c8, 0x080c, 0x3447, 0x11b0, 0x080c, 0xda35, 0x0500, 0x2001,
- 0x0007, 0x080c, 0x66cf, 0x2001, 0x0007, 0x080c, 0x66fb, 0x6017,
- 0x0000, 0x6023, 0x0001, 0x6007, 0x0001, 0x6003, 0x0001, 0x080c,
- 0x942f, 0x0010, 0x080c, 0xaf2e, 0x9085, 0x0001, 0x00ce, 0x00be,
- 0x0005, 0x080c, 0xaf2e, 0x00ce, 0x002e, 0x001e, 0x0ca8, 0x080c,
- 0xaf2e, 0x9006, 0x0c98, 0x2069, 0x026d, 0x6800, 0x9082, 0x0010,
- 0x1228, 0x6017, 0x0000, 0x9085, 0x0001, 0x0008, 0x9006, 0x0005,
- 0x6017, 0x0000, 0x2069, 0x026c, 0x6808, 0x9084, 0xff00, 0x9086,
- 0x0800, 0x1190, 0x6904, 0x9186, 0x0018, 0x0118, 0x9186, 0x0014,
- 0x1158, 0x810f, 0x6800, 0x9084, 0x00ff, 0x910d, 0x6162, 0x908e,
- 0x0014, 0x0110, 0x908e, 0x0010, 0x0005, 0x6004, 0x90b2, 0x0053,
- 0x1a0c, 0x0d85, 0x91b6, 0x0013, 0x1130, 0x2008, 0x91b2, 0x0040,
- 0x1a04, 0xdc38, 0x0402, 0x91b6, 0x0027, 0x0190, 0x9186, 0x0015,
- 0x0118, 0x9186, 0x0016, 0x1140, 0x080c, 0xad2d, 0x0120, 0x9086,
- 0x0002, 0x0904, 0xb966, 0x0005, 0x91b6, 0x0014, 0x190c, 0x0d85,
- 0x2001, 0x0007, 0x080c, 0x66fb, 0x080c, 0x97fe, 0x080c, 0xaf69,
- 0x080c, 0x98bf, 0x0005, 0xdb63, 0xdb65, 0xdb63, 0xdb63, 0xdb63,
- 0xdb65, 0xdb72, 0xdc35, 0xdbc2, 0xdc35, 0xdbe6, 0xdc35, 0xdb72,
- 0xdc35, 0xdc2d, 0xdc35, 0xdc2d, 0xdc35, 0xdc35, 0xdb63, 0xdb63,
- 0xdb63, 0xdb63, 0xdb63, 0xdb63, 0xdb63, 0xdb63, 0xdb63, 0xdb63,
- 0xdb63, 0xdb65, 0xdb63, 0xdc35, 0xdb63, 0xdb63, 0xdc35, 0xdb63,
- 0xdc32, 0xdc35, 0xdb63, 0xdb63, 0xdb63, 0xdb63, 0xdc35, 0xdc35,
- 0xdb63, 0xdc35, 0xdc35, 0xdb63, 0xdb6d, 0xdb63, 0xdb63, 0xdb63,
- 0xdb63, 0xdc31, 0xdc35, 0xdb63, 0xdb63, 0xdc35, 0xdc35, 0xdb63,
- 0xdb63, 0xdb63, 0xdb63, 0x080c, 0x0d85, 0x080c, 0xd356, 0x6003,
- 0x0002, 0x080c, 0x98bf, 0x0804, 0xdc37, 0x9006, 0x080c, 0x66bb,
- 0x0804, 0xdc35, 0x080c, 0x6bcd, 0x1904, 0xdc35, 0x9006, 0x080c,
- 0x66bb, 0x6010, 0x2058, 0xb810, 0x9086, 0x00ff, 0x1140, 0x00f6,
- 0x2079, 0x1800, 0x78a8, 0x8000, 0x78aa, 0x00fe, 0x0428, 0x6010,
- 0x2058, 0xb884, 0x9005, 0x1178, 0x080c, 0xd33e, 0x1904, 0xdc35,
- 0x0036, 0x0046, 0xbba0, 0x2021, 0x0007, 0x080c, 0x4de5, 0x004e,
- 0x003e, 0x0804, 0xdc35, 0x080c, 0x3478, 0x1904, 0xdc35, 0x2001,
- 0x1800, 0x2004, 0x9086, 0x0002, 0x1138, 0x00f6, 0x2079, 0x1800,
- 0x78a8, 0x8000, 0x78aa, 0x00fe, 0x2001, 0x0002, 0x080c, 0x66cf,
- 0x6023, 0x0001, 0x6003, 0x0001, 0x6007, 0x0002, 0x080c, 0x942f,
- 0x080c, 0x98bf, 0x6110, 0x2158, 0x2009, 0x0001, 0x080c, 0x8842,
- 0x0804, 0xdc37, 0x6610, 0x2658, 0xbe04, 0x96b4, 0xff00, 0x8637,
- 0x9686, 0x0006, 0x0148, 0x9686, 0x0004, 0x0130, 0x080c, 0x90c6,
- 0x2001, 0x0004, 0x080c, 0x66fb, 0x080c, 0xeb41, 0x0904, 0xdc35,
- 0x2001, 0x0004, 0x080c, 0x66cf, 0x6023, 0x0001, 0x6003, 0x0001,
- 0x6007, 0x0003, 0x080c, 0x942f, 0x0804, 0xdc37, 0x2001, 0x1800,
- 0x2004, 0x9086, 0x0003, 0x1158, 0x0036, 0x0046, 0x6010, 0x2058,
- 0xbba0, 0x2021, 0x0006, 0x080c, 0x4de5, 0x004e, 0x003e, 0x2001,
- 0x0006, 0x080c, 0xdc51, 0x6610, 0x2658, 0xbe04, 0x0066, 0x96b4,
- 0xff00, 0x8637, 0x9686, 0x0006, 0x006e, 0x0168, 0x2001, 0x0006,
- 0x080c, 0x66fb, 0x9284, 0x00ff, 0x908e, 0x0007, 0x1120, 0x2001,
- 0x0006, 0x080c, 0x66cf, 0x080c, 0x6bcd, 0x11f8, 0x2001, 0x1837,
- 0x2004, 0xd0a4, 0x01d0, 0xbe04, 0x96b4, 0x00ff, 0x9686, 0x0006,
- 0x01a0, 0x00f6, 0x2079, 0x1800, 0x78a8, 0x8000, 0x78aa, 0x00fe,
- 0x0804, 0xdbac, 0x2001, 0x0004, 0x0030, 0x2001, 0x0006, 0x0409,
- 0x0020, 0x0018, 0x0010, 0x080c, 0x66fb, 0x080c, 0xaf2e, 0x0005,
- 0x2600, 0x0002, 0xdc4c, 0xdc4c, 0xdc4c, 0xdc4c, 0xdc4c, 0xdc4e,
- 0xdc4c, 0xdc4e, 0xdc4c, 0xdc4c, 0xdc4e, 0xdc4c, 0xdc4c, 0xdc4c,
- 0xdc4e, 0xdc4e, 0xdc4e, 0xdc4e, 0x080c, 0x0d85, 0x080c, 0xaf2e,
- 0x0005, 0x0016, 0x00b6, 0x00d6, 0x6110, 0x2158, 0xb900, 0xd184,
- 0x0138, 0x080c, 0x66cf, 0x9006, 0x080c, 0x66bb, 0x080c, 0x333f,
- 0x00de, 0x00be, 0x001e, 0x0005, 0x6610, 0x2658, 0xb804, 0x9084,
- 0xff00, 0x8007, 0x90b2, 0x000c, 0x1a0c, 0x0d85, 0x91b6, 0x0015,
- 0x1110, 0x003b, 0x0028, 0x91b6, 0x0016, 0x190c, 0x0d85, 0x006b,
- 0x0005, 0xba08, 0xba08, 0xba08, 0xba08, 0xdce6, 0xba08, 0xdcd0,
- 0xdc91, 0xba08, 0xba08, 0xba08, 0xba08, 0xba08, 0xba08, 0xba08,
- 0xba08, 0xdce6, 0xba08, 0xdcd0, 0xdcd7, 0xba08, 0xba08, 0xba08,
- 0xba08, 0x00f6, 0x080c, 0x6bcd, 0x11d8, 0x080c, 0xd33e, 0x11c0,
- 0x6010, 0x905d, 0x01a8, 0xb884, 0x9005, 0x0190, 0x9006, 0x080c,
- 0x66bb, 0x2001, 0x0002, 0x080c, 0x66cf, 0x6023, 0x0001, 0x6003,
- 0x0001, 0x6007, 0x0002, 0x080c, 0x942f, 0x080c, 0x98bf, 0x00f0,
- 0x2011, 0x0263, 0x2204, 0x8211, 0x220c, 0x080c, 0x26a2, 0x11b0,
- 0x080c, 0x6789, 0x0118, 0x080c, 0xaf2e, 0x0080, 0xb810, 0x0006,
- 0xb814, 0x0006, 0xb884, 0x0006, 0x080c, 0x6198, 0x000e, 0xb886,
- 0x000e, 0xb816, 0x000e, 0xb812, 0x080c, 0xaf2e, 0x00fe, 0x0005,
- 0x6604, 0x96b6, 0x001e, 0x1110, 0x080c, 0xaf2e, 0x0005, 0x080c,
- 0xbda3, 0x1148, 0x6003, 0x0001, 0x6007, 0x0001, 0x080c, 0x942f,
- 0x080c, 0x98bf, 0x0010, 0x080c, 0xaf2e, 0x0005, 0x0804, 0xaf2e,
- 0x6004, 0x908a, 0x0053, 0x1a0c, 0x0d85, 0x080c, 0x97fe, 0x080c,
- 0xaf69, 0x0005, 0x9182, 0x0040, 0x0002, 0xdd09, 0xdd09, 0xdd09,
- 0xdd09, 0xdd0b, 0xdd09, 0xdd09, 0xdd09, 0xdd09, 0xdd09, 0xdd09,
- 0xdd09, 0xdd09, 0xdd09, 0xdd09, 0xdd09, 0xdd09, 0xdd09, 0xdd09,
- 0xdd09, 0x080c, 0x0d85, 0x0096, 0x00b6, 0x00d6, 0x00e6, 0x00f6,
- 0x0046, 0x0026, 0x6210, 0x2258, 0xb8bc, 0x9005, 0x11b0, 0x6007,
- 0x0044, 0x2071, 0x0260, 0x7444, 0x94a4, 0xff00, 0x0904, 0xdd72,
- 0x080c, 0xeae6, 0x1170, 0x9486, 0x2000, 0x1158, 0x2009, 0x0001,
- 0x2011, 0x0200, 0x080c, 0x8ae5, 0x0020, 0x9026, 0x080c, 0xe969,
- 0x0c30, 0x080c, 0x1059, 0x090c, 0x0d85, 0x6003, 0x0007, 0xa867,
- 0x010d, 0x9006, 0xa802, 0xa86a, 0xac8a, 0x2c00, 0xa88e, 0x6008,
- 0xa8e2, 0x6010, 0x2058, 0xb8a0, 0x7130, 0xa97a, 0x0016, 0xa876,
- 0xa87f, 0x0000, 0xa883, 0x0000, 0xa887, 0x0036, 0x080c, 0x6f19,
- 0x001e, 0x080c, 0xeae6, 0x1904, 0xddd2, 0x9486, 0x2000, 0x1130,
- 0x2019, 0x0017, 0x080c, 0xe696, 0x0804, 0xddd2, 0x9486, 0x0200,
- 0x1120, 0x080c, 0xe621, 0x0804, 0xddd2, 0x9486, 0x0400, 0x0120,
- 0x9486, 0x1000, 0x1904, 0xddd2, 0x2019, 0x0002, 0x080c, 0xe640,
- 0x0804, 0xddd2, 0x2069, 0x1a74, 0x6a00, 0xd284, 0x0904, 0xde3c,
- 0x9284, 0x0300, 0x1904, 0xde35, 0x6804, 0x9005, 0x0904, 0xde1d,
- 0x2d78, 0x6003, 0x0007, 0x080c, 0x1072, 0x0904, 0xddde, 0x7800,
- 0xd08c, 0x1118, 0x7804, 0x8001, 0x7806, 0x6017, 0x0000, 0x2001,
- 0x180f, 0x2004, 0xd084, 0x1904, 0xde40, 0x9006, 0xa802, 0xa867,
- 0x0116, 0xa86a, 0x6008, 0xa8e2, 0x2c00, 0xa87a, 0x6010, 0x2058,
- 0xb8a0, 0x7130, 0xa9b6, 0xa876, 0xb928, 0xa9ba, 0xb92c, 0xa9be,
- 0xb930, 0xa9c2, 0xb934, 0xa9c6, 0xa883, 0x003d, 0x7044, 0x9084,
- 0x0003, 0x9080, 0xddda, 0x2005, 0xa87e, 0x20a9, 0x000a, 0x2001,
- 0x0270, 0xaa5c, 0x9290, 0x0021, 0x2009, 0x0205, 0x200b, 0x0080,
- 0x20e1, 0x0000, 0xab60, 0x23e8, 0x2098, 0x22a0, 0x4003, 0x200b,
- 0x0000, 0x2001, 0x027a, 0x200c, 0xa9b2, 0x8000, 0x200c, 0xa9ae,
- 0x080c, 0x6f1c, 0x002e, 0x004e, 0x00fe, 0x00ee, 0x00de, 0x00be,
- 0x009e, 0x0005, 0x0000, 0x0080, 0x0040, 0x0000, 0x2001, 0x1810,
- 0x2004, 0xd084, 0x0120, 0x080c, 0x1059, 0x1904, 0xdd87, 0x6017,
- 0xf100, 0x6003, 0x0001, 0x6007, 0x0041, 0x2009, 0xa022, 0x080c,
- 0x9428, 0x0c00, 0x2069, 0x0260, 0x6848, 0x9084, 0xff00, 0x9086,
- 0x1200, 0x1198, 0x686c, 0x9084, 0x00ff, 0x0016, 0x6114, 0x918c,
- 0xf700, 0x910d, 0x6116, 0x001e, 0x6003, 0x0001, 0x6007, 0x0043,
- 0x2009, 0xa025, 0x080c, 0x9428, 0x0828, 0x6868, 0x602e, 0x686c,
- 0x6032, 0x6017, 0xf200, 0x6003, 0x0001, 0x6007, 0x0041, 0x2009,
- 0xa022, 0x080c, 0x9428, 0x0804, 0xddd2, 0x2001, 0x180e, 0x2004,
- 0xd0ec, 0x0120, 0x2011, 0x8049, 0x080c, 0x4c2e, 0x6017, 0xf300,
- 0x0010, 0x6017, 0xf100, 0x6003, 0x0001, 0x6007, 0x0041, 0x2009,
- 0xa022, 0x080c, 0x9428, 0x0804, 0xddd2, 0x6017, 0xf500, 0x0c98,
- 0x6017, 0xf600, 0x0804, 0xddf2, 0x6017, 0xf200, 0x0804, 0xddf2,
- 0xa867, 0x0146, 0xa86b, 0x0000, 0x6008, 0xa886, 0x2c00, 0xa87a,
- 0x7044, 0x9084, 0x0003, 0x9080, 0xddda, 0x2005, 0xa87e, 0x2928,
- 0x6010, 0x2058, 0xb8a0, 0xa876, 0xb828, 0xa88a, 0xb82c, 0xa88e,
- 0xb830, 0xa892, 0xb834, 0xa896, 0xa883, 0x003d, 0x2009, 0x0205,
- 0x2104, 0x9085, 0x0080, 0x200a, 0x20e1, 0x0000, 0x2011, 0x0210,
- 0x2214, 0x9294, 0x0fff, 0xaaa2, 0x9282, 0x0111, 0x1a0c, 0x0d85,
- 0x8210, 0x821c, 0x2001, 0x026c, 0x2098, 0xa860, 0x20e8, 0xa85c,
- 0x9080, 0x0029, 0x20a0, 0x2011, 0xdebc, 0x2041, 0x0001, 0x223d,
- 0x9784, 0x00ff, 0x9322, 0x1208, 0x2300, 0x20a8, 0x4003, 0x931a,
- 0x0530, 0x8210, 0xd7fc, 0x1130, 0x8d68, 0x2d0a, 0x2001, 0x0260,
- 0x2098, 0x0c68, 0x2950, 0x080c, 0x1072, 0x0170, 0x2900, 0xb002,
- 0xa867, 0x0147, 0xa86b, 0x0000, 0xa860, 0x20e8, 0xa85c, 0x9080,
- 0x001b, 0x20a0, 0x8840, 0x08d8, 0x2548, 0xa800, 0x902d, 0x0118,
- 0x080c, 0x108b, 0x0cc8, 0x080c, 0x108b, 0x0804, 0xddde, 0x2548,
- 0x8847, 0x9885, 0x0046, 0xa866, 0x2009, 0x0205, 0x200b, 0x0000,
- 0x080c, 0xe6cd, 0x0804, 0xddd2, 0x8010, 0x0004, 0x801a, 0x0006,
- 0x8018, 0x0008, 0x8016, 0x000a, 0x8014, 0x9186, 0x0013, 0x1160,
- 0x6004, 0x908a, 0x0057, 0x1a0c, 0x0d85, 0x9082, 0x0040, 0x0a0c,
- 0x0d85, 0x2008, 0x0804, 0xdf48, 0x9186, 0x0051, 0x0108, 0x0040,
- 0x080c, 0xad2d, 0x01e8, 0x9086, 0x0002, 0x0904, 0xdf90, 0x00c0,
- 0x9186, 0x0027, 0x0180, 0x9186, 0x0048, 0x0128, 0x9186, 0x0014,
- 0x0150, 0x190c, 0x0d85, 0x080c, 0xad2d, 0x0150, 0x9086, 0x0004,
- 0x0904, 0xe02f, 0x0028, 0x6004, 0x9082, 0x0040, 0x2008, 0x001a,
- 0x080c, 0xafe9, 0x0005, 0xdf0f, 0xdf11, 0xdf11, 0xdf38, 0xdf0f,
- 0xdf0f, 0xdf0f, 0xdf0f, 0xdf0f, 0xdf0f, 0xdf0f, 0xdf0f, 0xdf0f,
- 0xdf0f, 0xdf0f, 0xdf0f, 0xdf0f, 0xdf0f, 0xdf0f, 0xdf0f, 0x080c,
- 0x0d85, 0x080c, 0x97fe, 0x080c, 0x98bf, 0x0036, 0x0096, 0x6014,
- 0x904d, 0x01d8, 0x080c, 0xcc16, 0x01c0, 0x6003, 0x0002, 0x6010,
- 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x1178, 0x2019, 0x0004,
- 0x080c, 0xe6cd, 0x6017, 0x0000, 0x6018, 0x9005, 0x1120, 0x2001,
- 0x1988, 0x2004, 0x601a, 0x6003, 0x0007, 0x009e, 0x003e, 0x0005,
- 0x0096, 0x080c, 0x97fe, 0x080c, 0x98bf, 0x080c, 0xcc16, 0x0120,
- 0x6014, 0x2048, 0x080c, 0x108b, 0x080c, 0xaf69, 0x009e, 0x0005,
- 0x0002, 0xdf5d, 0xdf72, 0xdf5f, 0xdf87, 0xdf5d, 0xdf5d, 0xdf5d,
- 0xdf5d, 0xdf5d, 0xdf5d, 0xdf5d, 0xdf5d, 0xdf5d, 0xdf5d, 0xdf5d,
- 0xdf5d, 0xdf5d, 0xdf5d, 0xdf5d, 0xdf5d, 0x080c, 0x0d85, 0x0096,
- 0x6014, 0x2048, 0xa87c, 0xd0b4, 0x0138, 0x6003, 0x0007, 0x2009,
- 0x0043, 0x080c, 0xafcc, 0x0010, 0x6003, 0x0004, 0x080c, 0x98bf,
- 0x009e, 0x0005, 0x080c, 0xcc16, 0x0138, 0x6114, 0x0096, 0x2148,
- 0xa97c, 0x009e, 0xd1ec, 0x1138, 0x080c, 0x8aba, 0x080c, 0xaf2e,
- 0x080c, 0x98bf, 0x0005, 0x080c, 0xe92d, 0x0db0, 0x0cc8, 0x6003,
- 0x0001, 0x6007, 0x0041, 0x2009, 0xa022, 0x080c, 0x9428, 0x0005,
- 0x9182, 0x0040, 0x0002, 0xdfa7, 0xdfa9, 0xdfa7, 0xdfa7, 0xdfa7,
- 0xdfa7, 0xdfa7, 0xdfa7, 0xdfa7, 0xdfa7, 0xdfa7, 0xdfa7, 0xdfa7,
- 0xdfa7, 0xdfa7, 0xdfa7, 0xdfa7, 0xdfaa, 0xdfa7, 0xdfa7, 0x080c,
- 0x0d85, 0x0005, 0x00d6, 0x080c, 0x8aba, 0x00de, 0x080c, 0xe985,
- 0x080c, 0xaf2e, 0x0005, 0x9182, 0x0040, 0x0002, 0xdfca, 0xdfca,
- 0xdfca, 0xdfca, 0xdfca, 0xdfca, 0xdfca, 0xdfca, 0xdfca, 0xdfcc,
- 0xdff7, 0xdfca, 0xdfca, 0xdfca, 0xdfca, 0xdff7, 0xdfca, 0xdfca,
- 0xdfca, 0xdfca, 0x080c, 0x0d85, 0x6014, 0x0096, 0x2048, 0xa87c,
- 0xd0fc, 0x0168, 0x908c, 0x0003, 0x918e, 0x0002, 0x0180, 0x6144,
- 0xd1e4, 0x1168, 0x2009, 0x0041, 0x009e, 0x0804, 0xe0b7, 0x6003,
- 0x0007, 0x601b, 0x0000, 0x080c, 0x8aba, 0x009e, 0x0005, 0x6014,
- 0x2048, 0xa97c, 0xd1ec, 0x1130, 0x080c, 0x8aba, 0x080c, 0xaf2e,
- 0x009e, 0x0005, 0x080c, 0xe92d, 0x0db8, 0x009e, 0x0005, 0x2001,
- 0x180c, 0x200c, 0xc1d4, 0x2102, 0x0036, 0x080c, 0x9859, 0x080c,
- 0x98bf, 0x6014, 0x0096, 0x2048, 0x6010, 0x00b6, 0x2058, 0xb800,
- 0x00be, 0xd0bc, 0x0188, 0xa87c, 0x9084, 0x0003, 0x9086, 0x0002,
- 0x0140, 0xa8ac, 0x6330, 0x931a, 0x6332, 0xa8b0, 0x632c, 0x931b,
- 0x632e, 0x6003, 0x0002, 0x0080, 0x2019, 0x0004, 0x080c, 0xe6cd,
- 0x6018, 0x9005, 0x1128, 0x2001, 0x1988, 0x2004, 0x8003, 0x601a,
- 0x6017, 0x0000, 0x6003, 0x0007, 0x009e, 0x003e, 0x0005, 0x9182,
- 0x0040, 0x0002, 0xe046, 0xe046, 0xe046, 0xe046, 0xe046, 0xe046,
- 0xe046, 0xe046, 0xe048, 0xe046, 0xe046, 0xe046, 0xe046, 0xe046,
- 0xe046, 0xe046, 0xe046, 0xe046, 0xe046, 0xe093, 0x080c, 0x0d85,
- 0x6014, 0x0096, 0x2048, 0xa834, 0xaa38, 0x6110, 0x00b6, 0x2158,
- 0xb900, 0x00be, 0xd1bc, 0x1190, 0x920d, 0x1518, 0xa87c, 0xd0fc,
- 0x0128, 0x2009, 0x0041, 0x009e, 0x0804, 0xe0b7, 0x6003, 0x0007,
- 0x601b, 0x0000, 0x080c, 0x8aba, 0x009e, 0x0005, 0x6124, 0xd1f4,
- 0x1d58, 0x0006, 0x0046, 0xacac, 0x9422, 0xa9b0, 0x2200, 0x910b,
- 0x6030, 0x9420, 0x6432, 0x602c, 0x9109, 0x612e, 0x004e, 0x000e,
- 0x08d8, 0x6110, 0x00b6, 0x2158, 0xb900, 0x00be, 0xd1bc, 0x1178,
- 0x2009, 0x180e, 0x210c, 0xd19c, 0x0118, 0x6003, 0x0007, 0x0010,
- 0x6003, 0x0006, 0x00e9, 0x080c, 0x8abc, 0x009e, 0x0005, 0x6003,
- 0x0002, 0x009e, 0x0005, 0x6024, 0xd0f4, 0x0128, 0x080c, 0x16b0,
- 0x1904, 0xe048, 0x0005, 0x6014, 0x0096, 0x2048, 0xa834, 0xa938,
- 0x009e, 0x9105, 0x1120, 0x080c, 0x16b0, 0x1904, 0xe048, 0x0005,
- 0xd2fc, 0x0140, 0x8002, 0x8000, 0x8212, 0x9291, 0x0000, 0x2009,
- 0x0009, 0x0010, 0x2009, 0x0015, 0xaa9a, 0xa896, 0x0005, 0x9182,
- 0x0040, 0x0208, 0x0062, 0x9186, 0x0013, 0x0120, 0x9186, 0x0014,
- 0x190c, 0x0d85, 0x6024, 0xd0dc, 0x090c, 0x0d85, 0x0005, 0xe0db,
- 0xe0e7, 0xe0f3, 0xe0ff, 0xe0db, 0xe0db, 0xe0db, 0xe0db, 0xe0e2,
- 0xe0dd, 0xe0dd, 0xe0db, 0xe0db, 0xe0db, 0xe0db, 0xe0dd, 0xe0db,
- 0xe0dd, 0xe0db, 0xe0e2, 0x080c, 0x0d85, 0x6024, 0xd0dc, 0x090c,
- 0x0d85, 0x0005, 0x6014, 0x9005, 0x190c, 0x0d85, 0x0005, 0x6003,
- 0x0001, 0x6106, 0x0126, 0x2091, 0x8000, 0x2009, 0xa022, 0x080c,
- 0x940a, 0x012e, 0x0005, 0x6003, 0x0004, 0x6106, 0x0126, 0x2091,
- 0x8000, 0x2009, 0xa001, 0x080c, 0x9428, 0x012e, 0x0005, 0x6003,
- 0x0003, 0x6106, 0x080c, 0x1c90, 0x0126, 0x2091, 0x8000, 0x6014,
- 0x0096, 0x2048, 0xa87c, 0xd0fc, 0x0188, 0x9084, 0x0003, 0x9086,
- 0x0002, 0x01a0, 0x6024, 0xd0cc, 0x1148, 0xd0c4, 0x1138, 0xa8a8,
- 0x9005, 0x1120, 0x6144, 0x918d, 0xb035, 0x0018, 0x6144, 0x918d,
- 0xa035, 0x009e, 0x080c, 0x946f, 0x012e, 0x0005, 0x6144, 0x918d,
- 0xa032, 0x0cb8, 0x0126, 0x2091, 0x8000, 0x0036, 0x0096, 0x9182,
- 0x0040, 0x0023, 0x009e, 0x003e, 0x012e, 0x0005, 0xe14a, 0xe14c,
- 0xe161, 0xe17b, 0xe14a, 0xe14a, 0xe14a, 0xe14a, 0xe14a, 0xe14a,
- 0xe14a, 0xe14a, 0xe14a, 0xe14a, 0xe14a, 0xe14a, 0xe14a, 0xe14a,
- 0xe14a, 0xe14a, 0x080c, 0x0d85, 0x6014, 0x2048, 0xa87c, 0xd0fc,
- 0x0510, 0x909c, 0x0003, 0x939e, 0x0003, 0x01e8, 0x6003, 0x0001,
- 0x6106, 0x0126, 0x2091, 0x8000, 0x2009, 0xa022, 0x080c, 0x9428,
- 0x0470, 0x6014, 0x2048, 0xa87c, 0xd0fc, 0x0168, 0x909c, 0x0003,
- 0x939e, 0x0003, 0x0140, 0x6003, 0x0001, 0x6106, 0x2009, 0xa001,
- 0x080c, 0x9428, 0x00e0, 0x901e, 0x6316, 0x631a, 0x2019, 0x0004,
- 0x080c, 0xe6cd, 0x00a0, 0x6014, 0x2048, 0xa87c, 0xd0fc, 0x0d98,
- 0x909c, 0x0003, 0x939e, 0x0003, 0x0d70, 0x6003, 0x0003, 0x6106,
- 0x080c, 0x1c90, 0x6144, 0x918d, 0xa035, 0x080c, 0x946f, 0x0005,
- 0x080c, 0x97fe, 0x6114, 0x81ff, 0x0158, 0x0096, 0x2148, 0x080c,
- 0xea83, 0x0036, 0x2019, 0x0029, 0x080c, 0xe6cd, 0x003e, 0x009e,
- 0x080c, 0xaf69, 0x080c, 0x98bf, 0x0005, 0x080c, 0x9859, 0x6114,
- 0x81ff, 0x0158, 0x0096, 0x2148, 0x080c, 0xea83, 0x0036, 0x2019,
- 0x0029, 0x080c, 0xe6cd, 0x003e, 0x009e, 0x080c, 0xaf69, 0x0005,
- 0x9182, 0x0085, 0x0002, 0xe1ca, 0xe1c8, 0xe1c8, 0xe1d6, 0xe1c8,
- 0xe1c8, 0xe1c8, 0xe1c8, 0xe1c8, 0xe1c8, 0xe1c8, 0xe1c8, 0xe1c8,
- 0x080c, 0x0d85, 0x6003, 0x000b, 0x6106, 0x0126, 0x2091, 0x8000,
- 0x2009, 0x8020, 0x080c, 0x9428, 0x012e, 0x0005, 0x0026, 0x00e6,
- 0x080c, 0xe924, 0x0118, 0x080c, 0xaf2e, 0x0440, 0x2071, 0x0260,
- 0x7224, 0x6216, 0x2001, 0x180e, 0x2004, 0xd0e4, 0x0150, 0x6010,
- 0x00b6, 0x2058, 0xbca0, 0x00be, 0x2c00, 0x2011, 0x014e, 0x080c,
- 0xb25a, 0x7220, 0x080c, 0xe558, 0x0118, 0x6007, 0x0086, 0x0040,
- 0x6007, 0x0087, 0x7224, 0x9296, 0xffff, 0x1110, 0x6007, 0x0086,
- 0x6003, 0x0001, 0x2009, 0x8020, 0x080c, 0x9428, 0x00ee, 0x002e,
- 0x0005, 0x9186, 0x0013, 0x1160, 0x6004, 0x908a, 0x0085, 0x0a0c,
- 0x0d85, 0x908a, 0x0092, 0x1a0c, 0x0d85, 0x9082, 0x0085, 0x00a2,
- 0x9186, 0x0027, 0x0130, 0x9186, 0x0014, 0x0118, 0x080c, 0xafe9,
- 0x0050, 0x2001, 0x0007, 0x080c, 0x66fb, 0x080c, 0x97fe, 0x080c,
- 0xaf69, 0x080c, 0x98bf, 0x0005, 0xe239, 0xe23b, 0xe23b, 0xe239,
- 0xe239, 0xe239, 0xe239, 0xe239, 0xe239, 0xe239, 0xe239, 0xe239,
- 0xe239, 0x080c, 0x0d85, 0x080c, 0xaf69, 0x080c, 0x98bf, 0x0005,
- 0x9182, 0x0085, 0x0a0c, 0x0d85, 0x9182, 0x0092, 0x1a0c, 0x0d85,
- 0x9182, 0x0085, 0x0002, 0xe258, 0xe258, 0xe258, 0xe25a, 0xe258,
- 0xe258, 0xe258, 0xe258, 0xe258, 0xe258, 0xe258, 0xe258, 0xe258,
- 0x080c, 0x0d85, 0x0005, 0x9186, 0x0013, 0x0148, 0x9186, 0x0014,
- 0x0130, 0x9186, 0x0027, 0x0118, 0x080c, 0xafe9, 0x0020, 0x080c,
- 0x97fe, 0x080c, 0xaf69, 0x0005, 0x0036, 0x080c, 0xe985, 0x604b,
- 0x0000, 0x2019, 0x000b, 0x0031, 0x6023, 0x0006, 0x6003, 0x0007,
- 0x003e, 0x0005, 0x0126, 0x0036, 0x2091, 0x8000, 0x080c, 0xaae0,
- 0x0106, 0x0086, 0x2c40, 0x0096, 0x904e, 0x080c, 0xa44b, 0x009e,
- 0x008e, 0x1558, 0x0076, 0x2c38, 0x080c, 0xa4f6, 0x007e, 0x1528,
- 0x6000, 0x9086, 0x0000, 0x0508, 0x6020, 0x9086, 0x0007, 0x01e8,
- 0x0096, 0x601c, 0xd084, 0x0140, 0x080c, 0xe985, 0x080c, 0xd356,
- 0x080c, 0x1afc, 0x6023, 0x0007, 0x6014, 0x2048, 0x080c, 0xcc16,
- 0x0110, 0x080c, 0xe6cd, 0x009e, 0x9006, 0x6046, 0x6016, 0x080c,
- 0xe985, 0x6023, 0x0007, 0x080c, 0xd356, 0x010e, 0x090c, 0xaafc,
- 0x003e, 0x012e, 0x0005, 0x00f6, 0x00c6, 0x00b6, 0x0036, 0x0156,
- 0x2079, 0x0260, 0x7938, 0x783c, 0x080c, 0x26a2, 0x15e8, 0x0016,
- 0x00c6, 0x080c, 0x6789, 0x15b0, 0x001e, 0x00c6, 0x2160, 0x080c,
- 0xd353, 0x00ce, 0x002e, 0x0026, 0x0016, 0x080c, 0xaae0, 0x2019,
- 0x0029, 0x080c, 0xa5c6, 0x080c, 0x95c1, 0x0076, 0x903e, 0x080c,
- 0x947e, 0x007e, 0x001e, 0x0076, 0x903e, 0x080c, 0xe440, 0x007e,
- 0x080c, 0xaafc, 0x0026, 0xba04, 0x9294, 0xff00, 0x8217, 0x9286,
- 0x0006, 0x0118, 0x9286, 0x0004, 0x1118, 0xbaa0, 0x080c, 0x33db,
- 0x002e, 0xbc84, 0x001e, 0x080c, 0x6198, 0xbe12, 0xbd16, 0xbc86,
- 0x9006, 0x0010, 0x00ce, 0x001e, 0x015e, 0x003e, 0x00be, 0x00ce,
- 0x00fe, 0x0005, 0x00c6, 0x00d6, 0x00b6, 0x0016, 0x2009, 0x1824,
- 0x2104, 0x9086, 0x0074, 0x1904, 0xe363, 0x2069, 0x0260, 0x6944,
- 0x9182, 0x0100, 0x06e0, 0x6940, 0x9184, 0x8000, 0x0904, 0xe360,
- 0x2001, 0x197d, 0x2004, 0x9005, 0x1140, 0x6010, 0x2058, 0xb884,
- 0x9005, 0x0118, 0x9184, 0x0800, 0x0598, 0x6948, 0x918a, 0x0001,
- 0x0648, 0x080c, 0xeaeb, 0x0118, 0x6978, 0xd1fc, 0x11b8, 0x2009,
- 0x0205, 0x200b, 0x0001, 0x693c, 0x81ff, 0x1198, 0x6944, 0x9182,
- 0x0100, 0x02a8, 0x6940, 0x81ff, 0x1178, 0x6948, 0x918a, 0x0001,
- 0x0288, 0x6950, 0x918a, 0x0001, 0x0298, 0x00d0, 0x6017, 0x0100,
- 0x00a0, 0x6017, 0x0300, 0x0088, 0x6017, 0x0500, 0x0070, 0x6017,
- 0x0700, 0x0058, 0x6017, 0x0900, 0x0040, 0x6017, 0x0b00, 0x0028,
- 0x6017, 0x0f00, 0x0010, 0x6017, 0x2d00, 0x9085, 0x0001, 0x0008,
- 0x9006, 0x001e, 0x00be, 0x00de, 0x00ce, 0x0005, 0x00c6, 0x00b6,
- 0x0026, 0x0036, 0x0156, 0x6210, 0x2258, 0xbb04, 0x9394, 0x00ff,
- 0x9286, 0x0006, 0x0180, 0x9286, 0x0004, 0x0168, 0x9394, 0xff00,
- 0x8217, 0x9286, 0x0006, 0x0138, 0x9286, 0x0004, 0x0120, 0x080c,
- 0x6798, 0x0804, 0xe3cf, 0x2011, 0x0276, 0x20a9, 0x0004, 0x0096,
- 0x2b48, 0x2019, 0x000a, 0x080c, 0xbf3e, 0x009e, 0x15c8, 0x2011,
- 0x027a, 0x20a9, 0x0004, 0x0096, 0x2b48, 0x2019, 0x0006, 0x080c,
- 0xbf3e, 0x009e, 0x1568, 0x0046, 0x0016, 0xbaa0, 0x2220, 0x9006,
- 0x2009, 0x1848, 0x210c, 0xd1a4, 0x0138, 0x2009, 0x0029, 0x080c,
- 0xe72a, 0xb800, 0xc0e5, 0xb802, 0x080c, 0xaae0, 0x2019, 0x0029,
- 0x080c, 0x95c1, 0x0076, 0x2039, 0x0000, 0x080c, 0x947e, 0x2c08,
- 0x080c, 0xe440, 0x007e, 0x080c, 0xaafc, 0x2001, 0x0007, 0x080c,
- 0x66fb, 0x2001, 0x0007, 0x080c, 0x66cf, 0x001e, 0x004e, 0x9006,
- 0x015e, 0x003e, 0x002e, 0x00be, 0x00ce, 0x0005, 0x00d6, 0x2069,
- 0x026e, 0x6800, 0x9086, 0x0800, 0x0118, 0x6017, 0x0000, 0x0008,
- 0x9006, 0x00de, 0x0005, 0x00b6, 0x00f6, 0x0016, 0x0026, 0x0036,
- 0x0156, 0x2079, 0x026c, 0x7930, 0x7834, 0x080c, 0x26a2, 0x11d0,
- 0x080c, 0x6789, 0x11b8, 0x2011, 0x0270, 0x20a9, 0x0004, 0x0096,
- 0x2b48, 0x2019, 0x000a, 0x080c, 0xbf3e, 0x009e, 0x1158, 0x2011,
- 0x0274, 0x20a9, 0x0004, 0x0096, 0x2b48, 0x2019, 0x0006, 0x080c,
- 0xbf3e, 0x009e, 0x015e, 0x003e, 0x002e, 0x001e, 0x00fe, 0x00be,
- 0x0005, 0x00b6, 0x0006, 0x0016, 0x0026, 0x0036, 0x0156, 0x2011,
- 0x0263, 0x2204, 0x8211, 0x220c, 0x080c, 0x26a2, 0x11d0, 0x080c,
- 0x6789, 0x11b8, 0x2011, 0x0276, 0x20a9, 0x0004, 0x0096, 0x2b48,
- 0x2019, 0x000a, 0x080c, 0xbf3e, 0x009e, 0x1158, 0x2011, 0x027a,
- 0x20a9, 0x0004, 0x0096, 0x2b48, 0x2019, 0x0006, 0x080c, 0xbf3e,
- 0x009e, 0x015e, 0x003e, 0x002e, 0x001e, 0x000e, 0x00be, 0x0005,
- 0x00e6, 0x00c6, 0x0086, 0x0076, 0x0066, 0x0056, 0x0046, 0x0026,
- 0x0126, 0x2091, 0x8000, 0x080c, 0xab3e, 0x0106, 0x190c, 0xaae0,
- 0x2740, 0x2029, 0x19f5, 0x252c, 0x2021, 0x19fc, 0x2424, 0x2061,
- 0x1ddc, 0x2071, 0x1800, 0x7654, 0x7074, 0x81ff, 0x0150, 0x0006,
- 0x9186, 0x1b3a, 0x000e, 0x0128, 0x8001, 0x9602, 0x1a04, 0xe4e6,
- 0x0018, 0x9606, 0x0904, 0xe4e6, 0x080c, 0x8d8f, 0x0904, 0xe4dd,
- 0x2100, 0x9c06, 0x0904, 0xe4dd, 0x6720, 0x9786, 0x0007, 0x0904,
- 0xe4dd, 0x080c, 0xe76b, 0x1904, 0xe4dd, 0x080c, 0xeb09, 0x0904,
- 0xe4dd, 0x080c, 0xe75b, 0x0904, 0xe4dd, 0x6720, 0x9786, 0x0001,
- 0x1148, 0x080c, 0x3478, 0x0904, 0xe528, 0x6004, 0x9086, 0x0000,
- 0x1904, 0xe528, 0x9786, 0x0004, 0x0904, 0xe528, 0x2500, 0x9c06,
- 0x0904, 0xe4dd, 0x2400, 0x9c06, 0x0904, 0xe4dd, 0x88ff, 0x0118,
- 0x605c, 0x9906, 0x15d0, 0x0096, 0x6043, 0xffff, 0x6000, 0x9086,
- 0x0004, 0x1120, 0x0016, 0x080c, 0x1afc, 0x001e, 0x9786, 0x000a,
- 0x0148, 0x080c, 0xce2d, 0x1130, 0x080c, 0xb91f, 0x009e, 0x080c,
- 0xaf69, 0x0418, 0x6014, 0x2048, 0x080c, 0xcc16, 0x01d8, 0x9786,
- 0x0003, 0x1588, 0xa867, 0x0103, 0xa87c, 0xd0cc, 0x0130, 0x0096,
- 0xa878, 0x2048, 0x080c, 0x100b, 0x009e, 0xab7a, 0xa877, 0x0000,
- 0x080c, 0xea83, 0x0016, 0x080c, 0xcf1b, 0x080c, 0x6f0d, 0x001e,
- 0x080c, 0xce07, 0x009e, 0x080c, 0xaf69, 0x9ce0, 0x001c, 0x2001,
- 0x181a, 0x2004, 0x9c02, 0x1210, 0x0804, 0xe459, 0x010e, 0x190c,
- 0xaafc, 0x012e, 0x002e, 0x004e, 0x005e, 0x006e, 0x007e, 0x008e,
- 0x00ce, 0x00ee, 0x0005, 0x9786, 0x0006, 0x1150, 0x9386, 0x0005,
- 0x0128, 0x080c, 0xea83, 0x080c, 0xe6cd, 0x08e0, 0x009e, 0x08e8,
- 0x9786, 0x0009, 0x11f8, 0x6000, 0x9086, 0x0004, 0x01c0, 0x6000,
- 0x9086, 0x0003, 0x11a0, 0x080c, 0x9859, 0x0096, 0x6114, 0x2148,
- 0x080c, 0xcc16, 0x0118, 0x6010, 0x080c, 0x6f19, 0x009e, 0x00c6,
- 0x080c, 0xaf2e, 0x00ce, 0x0036, 0x080c, 0x98bf, 0x003e, 0x009e,
- 0x0804, 0xe4dd, 0x9786, 0x000a, 0x0904, 0xe4cd, 0x0804, 0xe4c2,
- 0x81ff, 0x0904, 0xe4dd, 0x9180, 0x0001, 0x2004, 0x9086, 0x0018,
- 0x0138, 0x9180, 0x0001, 0x2004, 0x9086, 0x002d, 0x1904, 0xe4dd,
- 0x6000, 0x9086, 0x0002, 0x1904, 0xe4dd, 0x080c, 0xce1c, 0x0138,
- 0x080c, 0xce2d, 0x1904, 0xe4dd, 0x080c, 0xb91f, 0x0038, 0x080c,
- 0x333f, 0x080c, 0xce2d, 0x1110, 0x080c, 0xb91f, 0x080c, 0xaf69,
- 0x0804, 0xe4dd, 0xa864, 0x9084, 0x00ff, 0x9086, 0x0039, 0x0005,
- 0x00c6, 0x00e6, 0x0016, 0x2c08, 0x2170, 0x9006, 0x080c, 0xe6f4,
- 0x001e, 0x0120, 0x6020, 0x9084, 0x000f, 0x001b, 0x00ee, 0x00ce,
- 0x0005, 0xe577, 0xe577, 0xe577, 0xe577, 0xe577, 0xe577, 0xe579,
- 0xe577, 0xe577, 0xe577, 0xe577, 0xaf69, 0xaf69, 0xe577, 0x9006,
- 0x0005, 0x0036, 0x0046, 0x0016, 0x7010, 0x00b6, 0x2058, 0xbca0,
- 0x00be, 0x2c00, 0x2009, 0x0020, 0x080c, 0xe72a, 0x001e, 0x004e,
- 0x2019, 0x0002, 0x080c, 0xe27a, 0x003e, 0x9085, 0x0001, 0x0005,
- 0x0096, 0x080c, 0xcc16, 0x0140, 0x6014, 0x904d, 0x080c, 0xc802,
- 0x687b, 0x0005, 0x080c, 0x6f19, 0x009e, 0x080c, 0xaf69, 0x9085,
- 0x0001, 0x0005, 0x2001, 0x0001, 0x080c, 0x66bb, 0x0156, 0x0016,
- 0x0026, 0x0036, 0x20a9, 0x0004, 0x2019, 0x1805, 0x2011, 0x0276,
- 0x080c, 0xbf2a, 0x003e, 0x002e, 0x001e, 0x015e, 0x9005, 0x0005,
- 0x00f6, 0x00e6, 0x00c6, 0x0086, 0x0076, 0x0066, 0x00b6, 0x0126,
- 0x2091, 0x8000, 0x2740, 0x2061, 0x1ddc, 0x2079, 0x0001, 0x8fff,
- 0x0904, 0xe614, 0x2071, 0x1800, 0x7654, 0x7074, 0x8001, 0x9602,
- 0x1a04, 0xe614, 0x88ff, 0x0120, 0x2800, 0x9c06, 0x15a0, 0x2078,
- 0x080c, 0xe75b, 0x0580, 0x2400, 0x9c06, 0x0568, 0x6720, 0x9786,
- 0x0006, 0x1548, 0x9786, 0x0007, 0x0530, 0x88ff, 0x1150, 0xd58c,
- 0x1118, 0x6010, 0x9b06, 0x11f8, 0xd584, 0x0118, 0x605c, 0x9106,
- 0x11d0, 0x0096, 0x601c, 0xd084, 0x0140, 0x080c, 0xe985, 0x080c,
- 0xd356, 0x080c, 0x1afc, 0x6023, 0x0007, 0x6014, 0x2048, 0x080c,
- 0xcc16, 0x0120, 0x0046, 0x080c, 0xe6cd, 0x004e, 0x009e, 0x080c,
- 0xaf69, 0x88ff, 0x1198, 0x9ce0, 0x001c, 0x2001, 0x181a, 0x2004,
- 0x9c02, 0x1210, 0x0804, 0xe5c7, 0x9006, 0x012e, 0x00be, 0x006e,
- 0x007e, 0x008e, 0x00ce, 0x00ee, 0x00fe, 0x0005, 0x98c5, 0x0001,
- 0x0ca0, 0x080c, 0xaae0, 0x00b6, 0x0076, 0x0056, 0x0086, 0x9046,
- 0x2029, 0x0001, 0x2c20, 0x2019, 0x0002, 0x6210, 0x2258, 0x0096,
- 0x904e, 0x080c, 0xa44b, 0x009e, 0x008e, 0x903e, 0x080c, 0xa4f6,
- 0x080c, 0xe5b8, 0x005e, 0x007e, 0x00be, 0x080c, 0xaafc, 0x0005,
- 0x080c, 0xaae0, 0x00b6, 0x0046, 0x0056, 0x0076, 0x00c6, 0x0156,
- 0x2c20, 0x2128, 0x20a9, 0x007f, 0x900e, 0x0016, 0x0036, 0x080c,
- 0x6789, 0x1180, 0x0056, 0x0086, 0x9046, 0x2508, 0x2029, 0x0001,
- 0x0096, 0x904e, 0x080c, 0xa44b, 0x009e, 0x008e, 0x903e, 0x080c,
- 0xa4f6, 0x005e, 0x003e, 0x001e, 0x8108, 0x1f04, 0xe64d, 0x0036,
- 0x2508, 0x2029, 0x0003, 0x080c, 0xe5b8, 0x003e, 0x015e, 0x00ce,
- 0x007e, 0x005e, 0x004e, 0x00be, 0x080c, 0xaafc, 0x0005, 0x080c,
- 0xaae0, 0x00b6, 0x0076, 0x0056, 0x6210, 0x2258, 0x0086, 0x9046,
- 0x2029, 0x0001, 0x2019, 0x0048, 0x0096, 0x904e, 0x080c, 0xa44b,
- 0x009e, 0x008e, 0x903e, 0x080c, 0xa4f6, 0x2c20, 0x080c, 0xe5b8,
- 0x005e, 0x007e, 0x00be, 0x080c, 0xaafc, 0x0005, 0x080c, 0xaae0,
- 0x00b6, 0x0046, 0x0056, 0x0076, 0x00c6, 0x0156, 0x2c20, 0x20a9,
- 0x0800, 0x900e, 0x0016, 0x0036, 0x080c, 0x6789, 0x1190, 0x0086,
- 0x9046, 0x2828, 0x0046, 0x2021, 0x0001, 0x080c, 0xe969, 0x004e,
- 0x0096, 0x904e, 0x080c, 0xa44b, 0x009e, 0x008e, 0x903e, 0x080c,
- 0xa4f6, 0x003e, 0x001e, 0x8108, 0x1f04, 0xe6a2, 0x0036, 0x2029,
- 0x0002, 0x080c, 0xe5b8, 0x003e, 0x015e, 0x00ce, 0x007e, 0x005e,
- 0x004e, 0x00be, 0x080c, 0xaafc, 0x0005, 0x0016, 0x00f6, 0x080c,
- 0xcc14, 0x0198, 0xa864, 0x9084, 0x00ff, 0x9086, 0x0046, 0x0180,
- 0xa800, 0x907d, 0x0138, 0xa803, 0x0000, 0xab82, 0x080c, 0x6f19,
- 0x2f48, 0x0cb0, 0xab82, 0x080c, 0x6f19, 0x00fe, 0x001e, 0x0005,
- 0xa800, 0x907d, 0x0130, 0xa803, 0x0000, 0x080c, 0x6f19, 0x2f48,
- 0x0cb8, 0x080c, 0x6f19, 0x0c88, 0x00e6, 0x0046, 0x0036, 0x2061,
- 0x1ddc, 0x9005, 0x1138, 0x2071, 0x1800, 0x7454, 0x7074, 0x8001,
- 0x9402, 0x12f8, 0x2100, 0x9c06, 0x0188, 0x6000, 0x9086, 0x0000,
- 0x0168, 0x6008, 0x9206, 0x1150, 0x6320, 0x9386, 0x0009, 0x01b0,
- 0x6010, 0x91a0, 0x0004, 0x2424, 0x9406, 0x0140, 0x9ce0, 0x001c,
- 0x2001, 0x181a, 0x2004, 0x9c02, 0x1220, 0x0c20, 0x9085, 0x0001,
- 0x0008, 0x9006, 0x003e, 0x004e, 0x00ee, 0x0005, 0x631c, 0xd3c4,
- 0x1d68, 0x0c30, 0x0096, 0x0006, 0x080c, 0x1059, 0x000e, 0x090c,
- 0x0d85, 0xaae2, 0xa867, 0x010d, 0xa88e, 0x0026, 0x2010, 0x080c,
- 0xcc04, 0x2001, 0x0000, 0x0120, 0x2200, 0x9080, 0x0017, 0x2004,
- 0x002e, 0xa87a, 0x9186, 0x0020, 0x0110, 0xa8e3, 0xffff, 0xa986,
- 0xac76, 0xa87f, 0x0000, 0x2001, 0x198f, 0x2004, 0xa882, 0x9006,
- 0xa802, 0xa86a, 0xa88a, 0x0126, 0x2091, 0x8000, 0x080c, 0x6f19,
- 0x012e, 0x009e, 0x0005, 0x6700, 0x9786, 0x0000, 0x0158, 0x9786,
- 0x0001, 0x0140, 0x9786, 0x000a, 0x0128, 0x9786, 0x0009, 0x0110,
- 0x9085, 0x0001, 0x0005, 0x00e6, 0x6010, 0x9075, 0x0138, 0x00b6,
- 0x2058, 0xb8a0, 0x00be, 0x9206, 0x00ee, 0x0005, 0x9085, 0x0001,
- 0x0cd8, 0x0016, 0x6004, 0x908e, 0x001e, 0x11a0, 0x8007, 0x6134,
- 0x918c, 0x00ff, 0x9105, 0x6036, 0x6007, 0x0085, 0x6003, 0x000b,
- 0x6023, 0x0005, 0x2001, 0x1988, 0x2004, 0x601a, 0x2009, 0x8020,
- 0x080c, 0x9428, 0x001e, 0x0005, 0xa001, 0xa001, 0x0005, 0x6024,
- 0xd0e4, 0x0158, 0xd0cc, 0x0118, 0x080c, 0xcf62, 0x0030, 0x080c,
- 0xe985, 0x080c, 0x8aba, 0x080c, 0xaf2e, 0x0005, 0x9280, 0x0008,
- 0x2004, 0x9084, 0x000f, 0x0002, 0xe7ba, 0xe7ba, 0xe7ba, 0xe7bc,
- 0xe7ba, 0xe7bc, 0xe7bc, 0xe7ba, 0xe7bc, 0xe7ba, 0xe7ba, 0xe7ba,
- 0xe7ba, 0xe7ba, 0x9006, 0x0005, 0x9085, 0x0001, 0x0005, 0x9280,
- 0x0008, 0x2004, 0x9084, 0x000f, 0x0002, 0xe7d3, 0xe7d3, 0xe7d3,
- 0xe7d3, 0xe7d3, 0xe7d3, 0xe7e0, 0xe7d3, 0xe7d3, 0xe7d3, 0xe7d3,
- 0xe7d3, 0xe7d3, 0xe7d3, 0x6007, 0x003b, 0x602f, 0x0009, 0x6017,
- 0x2a00, 0x6003, 0x0001, 0x2009, 0x8020, 0x080c, 0x9428, 0x0005,
- 0x0096, 0x00c6, 0x2260, 0x080c, 0xe985, 0x604b, 0x0000, 0x6024,
- 0xc0f4, 0xc0e4, 0x6026, 0x603b, 0x0000, 0x00ce, 0x00d6, 0x2268,
- 0x9186, 0x0007, 0x1904, 0xe839, 0x6814, 0x9005, 0x0138, 0x2048,
- 0xa87c, 0xd0fc, 0x1118, 0x00de, 0x009e, 0x08a8, 0x6007, 0x003a,
- 0x6003, 0x0001, 0x2009, 0x8020, 0x080c, 0x9428, 0x00c6, 0x2d60,
- 0x6100, 0x9186, 0x0002, 0x1904, 0xe8b0, 0x6014, 0x9005, 0x1138,
- 0x6000, 0x9086, 0x0007, 0x190c, 0x0d85, 0x0804, 0xe8b0, 0x2048,
- 0x080c, 0xcc16, 0x1130, 0x0028, 0x2048, 0xa800, 0x9005, 0x1de0,
- 0x2900, 0x2048, 0xa87c, 0x9084, 0x0003, 0x9086, 0x0002, 0x1168,
- 0xa87c, 0xc0dc, 0xc0f4, 0xa87e, 0xa880, 0xc0fc, 0xa882, 0x2009,
- 0x0043, 0x080c, 0xe0b7, 0x0804, 0xe8b0, 0x2009, 0x0041, 0x0804,
- 0xe8aa, 0x9186, 0x0005, 0x15a0, 0x6814, 0x2048, 0xa87c, 0xd0bc,
- 0x1120, 0x00de, 0x009e, 0x0804, 0xe7d3, 0xd0b4, 0x0128, 0xd0fc,
- 0x090c, 0x0d85, 0x0804, 0xe7f4, 0x6007, 0x003a, 0x6003, 0x0001,
- 0x2009, 0x8020, 0x080c, 0x9428, 0x00c6, 0x2d60, 0x6100, 0x9186,
- 0x0002, 0x0120, 0x9186, 0x0004, 0x1904, 0xe8b0, 0x6814, 0x2048,
- 0xa97c, 0xc1f4, 0xc1dc, 0xa97e, 0xa980, 0xc1fc, 0xc1bc, 0xa982,
- 0x00f6, 0x2c78, 0x080c, 0x17ad, 0x00fe, 0x2009, 0x0042, 0x04d0,
- 0x0036, 0x080c, 0x1059, 0x090c, 0x0d85, 0xa867, 0x010d, 0x9006,
- 0xa802, 0xa86a, 0xa88a, 0x2d18, 0xab8e, 0xa887, 0x0045, 0x2c00,
- 0xa892, 0x6038, 0xa8a2, 0x2360, 0x6024, 0xc0dd, 0x6026, 0x6010,
- 0x00b6, 0x2058, 0xb8a0, 0x00be, 0x2004, 0x635c, 0xab7a, 0xa876,
- 0x9006, 0xa87e, 0xa882, 0xad9a, 0xae96, 0xa89f, 0x0001, 0x080c,
- 0x6f19, 0x2019, 0x0045, 0x6008, 0x2068, 0x080c, 0xe27a, 0x2d00,
- 0x600a, 0x6023, 0x0006, 0x6003, 0x0007, 0x901e, 0x631a, 0x634a,
- 0x003e, 0x0038, 0x604b, 0x0000, 0x6003, 0x0007, 0x080c, 0xe0b7,
- 0x00ce, 0x00de, 0x009e, 0x0005, 0x9186, 0x0013, 0x1128, 0x6004,
- 0x9082, 0x0085, 0x2008, 0x00c2, 0x9186, 0x0027, 0x1178, 0x080c,
- 0x97fe, 0x0036, 0x0096, 0x6014, 0x2048, 0x2019, 0x0004, 0x080c,
- 0xe6cd, 0x009e, 0x003e, 0x080c, 0x98bf, 0x0005, 0x9186, 0x0014,
- 0x0d70, 0x080c, 0xafe9, 0x0005, 0xe8e3, 0xe8e1, 0xe8e1, 0xe8e1,
- 0xe8e1, 0xe8e1, 0xe8e3, 0xe8e1, 0xe8e1, 0xe8e1, 0xe8e1, 0xe8e1,
- 0xe8e1, 0x080c, 0x0d85, 0x6003, 0x000c, 0x080c, 0x98bf, 0x0005,
- 0x9182, 0x0092, 0x1220, 0x9182, 0x0085, 0x0208, 0x001a, 0x080c,
- 0xafe9, 0x0005, 0xe8ff, 0xe8ff, 0xe8ff, 0xe8ff, 0xe901, 0xe921,
- 0xe8ff, 0xe8ff, 0xe8ff, 0xe8ff, 0xe8ff, 0xe8ff, 0xe8ff, 0x080c,
- 0x0d85, 0x00d6, 0x2c68, 0x080c, 0xaed8, 0x01b0, 0x6003, 0x0001,
- 0x6007, 0x001e, 0x2009, 0x026e, 0x210c, 0x613a, 0x2009, 0x026f,
- 0x210c, 0x613e, 0x600b, 0xffff, 0x6910, 0x6112, 0x6023, 0x0004,
- 0x2009, 0x8020, 0x080c, 0x9428, 0x2d60, 0x080c, 0xaf2e, 0x00de,
- 0x0005, 0x080c, 0xaf2e, 0x0005, 0x00e6, 0x6010, 0x00b6, 0x2058,
- 0xb800, 0x00be, 0xd0ec, 0x00ee, 0x0005, 0x2009, 0x1867, 0x210c,
- 0xd1ec, 0x05b0, 0x6003, 0x0002, 0x6024, 0xc0e5, 0x6026, 0xd0cc,
- 0x0150, 0x2001, 0x1989, 0x2004, 0x604a, 0x2009, 0x1867, 0x210c,
- 0xd1f4, 0x1520, 0x00a0, 0x2009, 0x1867, 0x210c, 0xd1f4, 0x0128,
- 0x6024, 0xc0e4, 0x6026, 0x9006, 0x00d8, 0x2001, 0x1989, 0x200c,
- 0x2001, 0x1987, 0x2004, 0x9100, 0x9080, 0x000a, 0x604a, 0x6010,
- 0x00b6, 0x2058, 0xb8bc, 0x00be, 0x0008, 0x2104, 0x9005, 0x0118,
- 0x9088, 0x0003, 0x0cd0, 0x2c0a, 0x600f, 0x0000, 0x9085, 0x0001,
- 0x0005, 0x0016, 0x00c6, 0x00e6, 0x615c, 0xb8bc, 0x2060, 0x8cff,
- 0x0180, 0x84ff, 0x1118, 0x605c, 0x9106, 0x1138, 0x600c, 0x2072,
- 0x080c, 0x8aba, 0x080c, 0xaf2e, 0x0010, 0x9cf0, 0x0003, 0x2e64,
- 0x0c70, 0x00ee, 0x00ce, 0x001e, 0x0005, 0x00d6, 0x00b6, 0x6010,
- 0x2058, 0xb8bc, 0x906d, 0x0130, 0x9c06, 0x0110, 0x680c, 0x0cd0,
- 0x600c, 0x680e, 0x00be, 0x00de, 0x0005, 0x0026, 0x0036, 0x0156,
- 0x2011, 0x182c, 0x2204, 0x9084, 0x00ff, 0x2019, 0x026e, 0x2334,
- 0x96b4, 0x00ff, 0x9636, 0x1508, 0x8318, 0x2334, 0x2204, 0x9084,
- 0xff00, 0x9636, 0x11d0, 0x2011, 0x0270, 0x20a9, 0x0004, 0x6010,
- 0x0096, 0x2048, 0x2019, 0x000a, 0x080c, 0xbf3e, 0x009e, 0x1168,
- 0x2011, 0x0274, 0x20a9, 0x0004, 0x6010, 0x0096, 0x2048, 0x2019,
- 0x0006, 0x080c, 0xbf3e, 0x009e, 0x1100, 0x015e, 0x003e, 0x002e,
- 0x0005, 0x00e6, 0x2071, 0x1800, 0x080c, 0x6111, 0x080c, 0x30e1,
- 0x00ee, 0x0005, 0x0096, 0x0026, 0x080c, 0x1059, 0x090c, 0x0d85,
- 0xa85c, 0x9080, 0x001a, 0x20a0, 0x20a9, 0x000c, 0xa860, 0x20e8,
- 0x9006, 0x4004, 0x9186, 0x0046, 0x1118, 0xa867, 0x0136, 0x0038,
- 0xa867, 0x0138, 0x9186, 0x0041, 0x0110, 0xa87b, 0x0001, 0x7038,
- 0x9084, 0xff00, 0x7240, 0x9294, 0xff00, 0x8007, 0x9215, 0xaa9a,
- 0x9186, 0x0046, 0x1168, 0x7038, 0x9084, 0x00ff, 0x723c, 0x9294,
- 0xff00, 0x9215, 0xaa9e, 0x723c, 0x9294, 0x00ff, 0xaaa2, 0x0060,
- 0x7040, 0x9084, 0x00ff, 0x7244, 0x9294, 0xff00, 0x9215, 0xaa9e,
- 0x7244, 0x9294, 0x00ff, 0xaaa2, 0x9186, 0x0046, 0x1118, 0x9e90,
- 0x0012, 0x0010, 0x9e90, 0x001a, 0x2204, 0x8007, 0xa8a6, 0x8210,
- 0x2204, 0x8007, 0xa8aa, 0x8210, 0x2204, 0x8007, 0xa8ae, 0x8210,
- 0x2204, 0x8007, 0xa8b2, 0x8210, 0x9186, 0x0046, 0x11b8, 0x9e90,
- 0x0016, 0x2204, 0x8007, 0xa8b6, 0x8210, 0x2204, 0x8007, 0xa8ba,
- 0x8210, 0x2204, 0x8007, 0xa8be, 0x8210, 0x2204, 0x8007, 0xa8c2,
- 0x8210, 0x2011, 0x0205, 0x2013, 0x0001, 0x00b0, 0x9e90, 0x001e,
- 0x2204, 0x8007, 0xa8b6, 0x8210, 0x2204, 0x8007, 0xa8ba, 0x2011,
- 0x0205, 0x2013, 0x0001, 0x2011, 0x0260, 0x2204, 0x8007, 0xa8be,
- 0x8210, 0x2204, 0x8007, 0xa8c2, 0x9186, 0x0046, 0x1118, 0x2011,
- 0x0262, 0x0010, 0x2011, 0x026a, 0x0146, 0x01d6, 0x0036, 0x20a9,
- 0x0001, 0x2019, 0x0008, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0031,
- 0x20a0, 0x2204, 0x8007, 0x4004, 0x8210, 0x8319, 0x1dd0, 0x003e,
- 0x01ce, 0x013e, 0x2011, 0x0205, 0x2013, 0x0000, 0x002e, 0x080c,
- 0x6f19, 0x009e, 0x0005, 0x00e6, 0x6010, 0x00b6, 0x2058, 0xb800,
- 0x00be, 0xd0fc, 0x0108, 0x0011, 0x00ee, 0x0005, 0xa880, 0xc0e5,
- 0xa882, 0x0005, 0x00e6, 0x00d6, 0x00c6, 0x0076, 0x0066, 0x0056,
- 0x0046, 0x0026, 0x0016, 0x0126, 0x2091, 0x8000, 0x2029, 0x19f5,
+ 0x003e, 0x002e, 0x001e, 0x000e, 0x0005, 0x0006, 0x0016, 0x0026,
+ 0x0036, 0x00c6, 0x81ff, 0x11b8, 0x080c, 0x222e, 0x20a1, 0x024c,
+ 0x2001, 0x0014, 0x3518, 0x9312, 0x1218, 0x23a8, 0x4003, 0x0418,
+ 0x20a8, 0x4003, 0x82ff, 0x01f8, 0x22a8, 0x8108, 0x080c, 0x222e,
+ 0x20a1, 0x0240, 0x0c98, 0x080c, 0x222e, 0x2061, 0x19a5, 0x6004,
+ 0x20a0, 0x6008, 0x3518, 0x9312, 0x1218, 0x23a8, 0x4003, 0x0058,
+ 0x20a8, 0x4003, 0x82ff, 0x0138, 0x22a8, 0x8108, 0x080c, 0x222e,
+ 0x20a1, 0x0240, 0x0c98, 0x2061, 0x19a5, 0x2019, 0x0260, 0x3400,
+ 0x931e, 0x0110, 0x6006, 0x0020, 0x2001, 0x0240, 0x6006, 0x8108,
+ 0x2162, 0x9292, 0x0021, 0x9296, 0xffff, 0x620a, 0x00ce, 0x003e,
+ 0x002e, 0x001e, 0x000e, 0x0005, 0x00b6, 0x0066, 0x6610, 0x2658,
+ 0xbe04, 0x96b4, 0xff00, 0x8637, 0x9686, 0x0006, 0x0170, 0x9686,
+ 0x0004, 0x0158, 0xbe04, 0x96b4, 0x00ff, 0x9686, 0x0006, 0x0128,
+ 0x9686, 0x0004, 0x0110, 0x9085, 0x0001, 0x006e, 0x00be, 0x0005,
+ 0x00d6, 0x080c, 0xdaea, 0x00de, 0x0005, 0x00d6, 0x080c, 0xdaf7,
+ 0x1520, 0x680c, 0x908c, 0xff00, 0x6820, 0x9084, 0x00ff, 0x9115,
+ 0x6216, 0x6824, 0x602e, 0xd1e4, 0x0130, 0x9006, 0x080c, 0xeb5d,
+ 0x2009, 0x0001, 0x0078, 0xd1ec, 0x0180, 0x6920, 0x918c, 0x00ff,
+ 0x6824, 0x080c, 0x26a1, 0x1148, 0x2001, 0x0001, 0x080c, 0xeb5d,
+ 0x2110, 0x900e, 0x080c, 0x334a, 0x0018, 0x9085, 0x0001, 0x0008,
+ 0x9006, 0x00de, 0x0005, 0x00b6, 0x00c6, 0x080c, 0xafbf, 0x0598,
+ 0x0016, 0x0026, 0x00c6, 0x2011, 0x0263, 0x2204, 0x8211, 0x220c,
+ 0x080c, 0x26a1, 0x1568, 0x080c, 0x6718, 0x1550, 0xbe12, 0xbd16,
+ 0x00ce, 0x002e, 0x001e, 0x2b00, 0x6012, 0x080c, 0xe98f, 0x11c8,
+ 0x080c, 0x3432, 0x11b0, 0x080c, 0xda54, 0x0500, 0x2001, 0x0007,
+ 0x080c, 0x66c9, 0x2001, 0x0007, 0x080c, 0x66f5, 0x6017, 0x0000,
+ 0x6023, 0x0001, 0x6007, 0x0001, 0x6003, 0x0001, 0x080c, 0x9427,
+ 0x0010, 0x080c, 0xaf4e, 0x9085, 0x0001, 0x00ce, 0x00be, 0x0005,
+ 0x080c, 0xaf4e, 0x00ce, 0x002e, 0x001e, 0x0ca8, 0x080c, 0xaf4e,
+ 0x9006, 0x0c98, 0x2069, 0x026d, 0x6800, 0x9082, 0x0010, 0x1228,
+ 0x6017, 0x0000, 0x9085, 0x0001, 0x0008, 0x9006, 0x0005, 0x6017,
+ 0x0000, 0x2069, 0x026c, 0x6808, 0x9084, 0xff00, 0x9086, 0x0800,
+ 0x1190, 0x6904, 0x9186, 0x0018, 0x0118, 0x9186, 0x0014, 0x1158,
+ 0x810f, 0x6800, 0x9084, 0x00ff, 0x910d, 0x6162, 0x908e, 0x0014,
+ 0x0110, 0x908e, 0x0010, 0x0005, 0x6004, 0x90b2, 0x0053, 0x1a0c,
+ 0x0d79, 0x91b6, 0x0013, 0x1130, 0x2008, 0x91b2, 0x0040, 0x1a04,
+ 0xdc4c, 0x0402, 0x91b6, 0x0027, 0x0190, 0x9186, 0x0015, 0x0118,
+ 0x9186, 0x0016, 0x1140, 0x080c, 0xad4d, 0x0120, 0x9086, 0x0002,
+ 0x0904, 0xb983, 0x0005, 0x91b6, 0x0014, 0x190c, 0x0d79, 0x2001,
+ 0x0007, 0x080c, 0x66f5, 0x080c, 0x97f6, 0x080c, 0xaf89, 0x080c,
+ 0x98bc, 0x0005, 0xdb82, 0xdb84, 0xdb82, 0xdb82, 0xdb82, 0xdb84,
+ 0xdb91, 0xdc49, 0xdbd3, 0xdc49, 0xdbf7, 0xdc49, 0xdb91, 0xdc49,
+ 0xdc41, 0xdc49, 0xdc41, 0xdc49, 0xdc49, 0xdb82, 0xdb82, 0xdb82,
+ 0xdb82, 0xdb82, 0xdb82, 0xdb82, 0xdb82, 0xdb82, 0xdb82, 0xdb82,
+ 0xdb84, 0xdb82, 0xdc49, 0xdb82, 0xdb82, 0xdc49, 0xdb82, 0xdc46,
+ 0xdc49, 0xdb82, 0xdb82, 0xdb82, 0xdb82, 0xdc49, 0xdc49, 0xdb82,
+ 0xdc49, 0xdc49, 0xdb82, 0xdb8c, 0xdb82, 0xdb82, 0xdb82, 0xdb82,
+ 0xdc45, 0xdc49, 0xdb82, 0xdb82, 0xdc49, 0xdc49, 0xdb82, 0xdb82,
+ 0xdb82, 0xdb82, 0x080c, 0x0d79, 0x080c, 0xd375, 0x6003, 0x0002,
+ 0x080c, 0x98bc, 0x0804, 0xdc4b, 0x9006, 0x080c, 0x66b5, 0x0804,
+ 0xdc49, 0x080c, 0x6bc5, 0x1904, 0xdc49, 0x9006, 0x080c, 0x66b5,
+ 0x6010, 0x2058, 0xb810, 0x9086, 0x00ff, 0x1140, 0x00f6, 0x2079,
+ 0x1800, 0x78a8, 0x8000, 0x78aa, 0x00fe, 0x00b8, 0x6010, 0x2058,
+ 0xb884, 0x9005, 0x0904, 0xdc49, 0x080c, 0x3463, 0x1904, 0xdc49,
+ 0x2001, 0x1800, 0x2004, 0x9086, 0x0002, 0x1138, 0x00f6, 0x2079,
+ 0x1800, 0x78a8, 0x8000, 0x78aa, 0x00fe, 0x2001, 0x0002, 0x080c,
+ 0x66c9, 0x6023, 0x0001, 0x6003, 0x0001, 0x6007, 0x0002, 0x080c,
+ 0x9427, 0x080c, 0x98bc, 0x6110, 0x2158, 0x2009, 0x0001, 0x080c,
+ 0x883a, 0x0804, 0xdc4b, 0x6610, 0x2658, 0xbe04, 0x96b4, 0xff00,
+ 0x8637, 0x9686, 0x0006, 0x0148, 0x9686, 0x0004, 0x0130, 0x080c,
+ 0x90be, 0x2001, 0x0004, 0x080c, 0x66f5, 0x080c, 0xebac, 0x0904,
+ 0xdc49, 0x2001, 0x0004, 0x080c, 0x66c9, 0x6023, 0x0001, 0x6003,
+ 0x0001, 0x6007, 0x0003, 0x080c, 0x9427, 0x0804, 0xdc4b, 0x2001,
+ 0x1800, 0x2004, 0x9086, 0x0003, 0x1158, 0x0036, 0x0046, 0x6010,
+ 0x2058, 0xbba0, 0x2021, 0x0006, 0x080c, 0x4ddf, 0x004e, 0x003e,
+ 0x2001, 0x0006, 0x080c, 0xdc65, 0x6610, 0x2658, 0xbe04, 0x0066,
+ 0x96b4, 0xff00, 0x8637, 0x9686, 0x0006, 0x006e, 0x0180, 0x2001,
+ 0x0006, 0x080c, 0x66f5, 0x9284, 0x00ff, 0x908e, 0x0007, 0x0118,
+ 0x908e, 0x0004, 0x1120, 0x2001, 0x0006, 0x080c, 0x66c9, 0x080c,
+ 0x6bc5, 0x11f8, 0x2001, 0x1837, 0x2004, 0xd0a4, 0x01d0, 0xbe04,
+ 0x96b4, 0x00ff, 0x9686, 0x0006, 0x01a0, 0x00f6, 0x2079, 0x1800,
+ 0x78a8, 0x8000, 0x78aa, 0x00fe, 0x0804, 0xdbbd, 0x2001, 0x0004,
+ 0x0030, 0x2001, 0x0006, 0x0409, 0x0020, 0x0018, 0x0010, 0x080c,
+ 0x66f5, 0x080c, 0xaf4e, 0x0005, 0x2600, 0x0002, 0xdc60, 0xdc60,
+ 0xdc60, 0xdc60, 0xdc60, 0xdc62, 0xdc60, 0xdc62, 0xdc60, 0xdc60,
+ 0xdc62, 0xdc60, 0xdc60, 0xdc60, 0xdc62, 0xdc62, 0xdc62, 0xdc62,
+ 0x080c, 0x0d79, 0x080c, 0xaf4e, 0x0005, 0x0016, 0x00b6, 0x00d6,
+ 0x6110, 0x2158, 0xb900, 0xd184, 0x0138, 0x080c, 0x66c9, 0x9006,
+ 0x080c, 0x66b5, 0x080c, 0x332a, 0x00de, 0x00be, 0x001e, 0x0005,
+ 0x6610, 0x2658, 0xb804, 0x9084, 0xff00, 0x8007, 0x90b2, 0x000c,
+ 0x1a0c, 0x0d79, 0x91b6, 0x0015, 0x1110, 0x003b, 0x0028, 0x91b6,
+ 0x0016, 0x190c, 0x0d79, 0x006b, 0x0005, 0xba25, 0xba25, 0xba25,
+ 0xba25, 0xdcfa, 0xba25, 0xdce4, 0xdca5, 0xba25, 0xba25, 0xba25,
+ 0xba25, 0xba25, 0xba25, 0xba25, 0xba25, 0xdcfa, 0xba25, 0xdce4,
+ 0xdceb, 0xba25, 0xba25, 0xba25, 0xba25, 0x00f6, 0x080c, 0x6bc5,
+ 0x11d8, 0x080c, 0xd35d, 0x11c0, 0x6010, 0x905d, 0x01a8, 0xb884,
+ 0x9005, 0x0190, 0x9006, 0x080c, 0x66b5, 0x2001, 0x0002, 0x080c,
+ 0x66c9, 0x6023, 0x0001, 0x6003, 0x0001, 0x6007, 0x0002, 0x080c,
+ 0x9427, 0x080c, 0x98bc, 0x00f0, 0x2011, 0x0263, 0x2204, 0x8211,
+ 0x220c, 0x080c, 0x26a1, 0x11b0, 0x080c, 0x6783, 0x0118, 0x080c,
+ 0xaf4e, 0x0080, 0xb810, 0x0006, 0xb814, 0x0006, 0xb884, 0x0006,
+ 0x080c, 0x6192, 0x000e, 0xb886, 0x000e, 0xb816, 0x000e, 0xb812,
+ 0x080c, 0xaf4e, 0x00fe, 0x0005, 0x6604, 0x96b6, 0x001e, 0x1110,
+ 0x080c, 0xaf4e, 0x0005, 0x080c, 0xbdb4, 0x1148, 0x6003, 0x0001,
+ 0x6007, 0x0001, 0x080c, 0x9427, 0x080c, 0x98bc, 0x0010, 0x080c,
+ 0xaf4e, 0x0005, 0x0804, 0xaf4e, 0x6004, 0x908a, 0x0053, 0x1a0c,
+ 0x0d79, 0x080c, 0x97f6, 0x080c, 0xaf89, 0x0005, 0x9182, 0x0040,
+ 0x0002, 0xdd1d, 0xdd1d, 0xdd1d, 0xdd1d, 0xdd1f, 0xdd1d, 0xdd1d,
+ 0xdd1d, 0xdd1d, 0xdd1d, 0xdd1d, 0xdd1d, 0xdd1d, 0xdd1d, 0xdd1d,
+ 0xdd1d, 0xdd1d, 0xdd1d, 0xdd1d, 0xdd1d, 0x080c, 0x0d79, 0x0096,
+ 0x00b6, 0x00d6, 0x00e6, 0x00f6, 0x0046, 0x0026, 0x6210, 0x2258,
+ 0xb8bc, 0x9005, 0x11b0, 0x6007, 0x0044, 0x2071, 0x0260, 0x7444,
+ 0x94a4, 0xff00, 0x0904, 0xdd86, 0x080c, 0xeb51, 0x1170, 0x9486,
+ 0x2000, 0x1158, 0x2009, 0x0001, 0x2011, 0x0200, 0x080c, 0x8add,
+ 0x0020, 0x9026, 0x080c, 0xe9d4, 0x0c30, 0x080c, 0x104d, 0x090c,
+ 0x0d79, 0x6003, 0x0007, 0xa867, 0x010d, 0x9006, 0xa802, 0xa86a,
+ 0xac8a, 0x2c00, 0xa88e, 0x6008, 0xa8e2, 0x6010, 0x2058, 0xb8a0,
+ 0x7130, 0xa97a, 0x0016, 0xa876, 0xa87f, 0x0000, 0xa883, 0x0000,
+ 0xa887, 0x0036, 0x080c, 0x6f11, 0x001e, 0x080c, 0xeb51, 0x1904,
+ 0xdde6, 0x9486, 0x2000, 0x1130, 0x2019, 0x0017, 0x080c, 0xe701,
+ 0x0804, 0xdde6, 0x9486, 0x0200, 0x1120, 0x080c, 0xe68c, 0x0804,
+ 0xdde6, 0x9486, 0x0400, 0x0120, 0x9486, 0x1000, 0x1904, 0xdde6,
+ 0x2019, 0x0002, 0x080c, 0xe6ab, 0x0804, 0xdde6, 0x2069, 0x1a74,
+ 0x6a00, 0xd284, 0x0904, 0xde50, 0x9284, 0x0300, 0x1904, 0xde49,
+ 0x6804, 0x9005, 0x0904, 0xde31, 0x2d78, 0x6003, 0x0007, 0x080c,
+ 0x1066, 0x0904, 0xddf2, 0x7800, 0xd08c, 0x1118, 0x7804, 0x8001,
+ 0x7806, 0x6017, 0x0000, 0x2001, 0x180f, 0x2004, 0xd084, 0x1904,
+ 0xde54, 0x9006, 0xa802, 0xa867, 0x0116, 0xa86a, 0x6008, 0xa8e2,
+ 0x2c00, 0xa87a, 0x6010, 0x2058, 0xb8a0, 0x7130, 0xa9b6, 0xa876,
+ 0xb928, 0xa9ba, 0xb92c, 0xa9be, 0xb930, 0xa9c2, 0xb934, 0xa9c6,
+ 0xa883, 0x003d, 0x7044, 0x9084, 0x0003, 0x9080, 0xddee, 0x2005,
+ 0xa87e, 0x20a9, 0x000a, 0x2001, 0x0270, 0xaa5c, 0x9290, 0x0021,
+ 0x2009, 0x0205, 0x200b, 0x0080, 0x20e1, 0x0000, 0xab60, 0x23e8,
+ 0x2098, 0x22a0, 0x4003, 0x200b, 0x0000, 0x2001, 0x027a, 0x200c,
+ 0xa9b2, 0x8000, 0x200c, 0xa9ae, 0x080c, 0x6f14, 0x002e, 0x004e,
+ 0x00fe, 0x00ee, 0x00de, 0x00be, 0x009e, 0x0005, 0x0000, 0x0080,
+ 0x0040, 0x0000, 0x2001, 0x1810, 0x2004, 0xd084, 0x0120, 0x080c,
+ 0x104d, 0x1904, 0xdd9b, 0x6017, 0xf100, 0x6003, 0x0001, 0x6007,
+ 0x0041, 0x2009, 0xa022, 0x080c, 0x9420, 0x0c00, 0x2069, 0x0260,
+ 0x6848, 0x9084, 0xff00, 0x9086, 0x1200, 0x1198, 0x686c, 0x9084,
+ 0x00ff, 0x0016, 0x6114, 0x918c, 0xf700, 0x910d, 0x6116, 0x001e,
+ 0x6003, 0x0001, 0x6007, 0x0043, 0x2009, 0xa025, 0x080c, 0x9420,
+ 0x0828, 0x6868, 0x602e, 0x686c, 0x6032, 0x6017, 0xf200, 0x6003,
+ 0x0001, 0x6007, 0x0041, 0x2009, 0xa022, 0x080c, 0x9420, 0x0804,
+ 0xdde6, 0x2001, 0x180e, 0x2004, 0xd0ec, 0x0120, 0x2011, 0x8049,
+ 0x080c, 0x4c28, 0x6017, 0xf300, 0x0010, 0x6017, 0xf100, 0x6003,
+ 0x0001, 0x6007, 0x0041, 0x2009, 0xa022, 0x080c, 0x9420, 0x0804,
+ 0xdde6, 0x6017, 0xf500, 0x0c98, 0x6017, 0xf600, 0x0804, 0xde06,
+ 0x6017, 0xf200, 0x0804, 0xde06, 0xa867, 0x0146, 0xa86b, 0x0000,
+ 0x6008, 0xa886, 0x2c00, 0xa87a, 0x7044, 0x9084, 0x0003, 0x9080,
+ 0xddee, 0x2005, 0xa87e, 0x2928, 0x6010, 0x2058, 0xb8a0, 0xa876,
+ 0xb828, 0xa88a, 0xb82c, 0xa88e, 0xb830, 0xa892, 0xb834, 0xa896,
+ 0xa883, 0x003d, 0x2009, 0x0205, 0x2104, 0x9085, 0x0080, 0x200a,
+ 0x20e1, 0x0000, 0x2011, 0x0210, 0x2214, 0x9294, 0x0fff, 0xaaa2,
+ 0x9282, 0x0111, 0x1a0c, 0x0d79, 0x8210, 0x821c, 0x2001, 0x026c,
+ 0x2098, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0029, 0x20a0, 0x2011,
+ 0xded0, 0x2041, 0x0001, 0x223d, 0x9784, 0x00ff, 0x9322, 0x1208,
+ 0x2300, 0x20a8, 0x4003, 0x931a, 0x0530, 0x8210, 0xd7fc, 0x1130,
+ 0x8d68, 0x2d0a, 0x2001, 0x0260, 0x2098, 0x0c68, 0x2950, 0x080c,
+ 0x1066, 0x0170, 0x2900, 0xb002, 0xa867, 0x0147, 0xa86b, 0x0000,
+ 0xa860, 0x20e8, 0xa85c, 0x9080, 0x001b, 0x20a0, 0x8840, 0x08d8,
+ 0x2548, 0xa800, 0x902d, 0x0118, 0x080c, 0x107f, 0x0cc8, 0x080c,
+ 0x107f, 0x0804, 0xddf2, 0x2548, 0x8847, 0x9885, 0x0046, 0xa866,
+ 0x2009, 0x0205, 0x200b, 0x0000, 0x080c, 0xe738, 0x0804, 0xdde6,
+ 0x8010, 0x0004, 0x801a, 0x0006, 0x8018, 0x0008, 0x8016, 0x000a,
+ 0x8014, 0x9186, 0x0013, 0x1160, 0x6004, 0x908a, 0x0057, 0x1a0c,
+ 0x0d79, 0x9082, 0x0040, 0x0a0c, 0x0d79, 0x2008, 0x0804, 0xdf5c,
+ 0x9186, 0x0051, 0x0108, 0x0040, 0x080c, 0xad4d, 0x01e8, 0x9086,
+ 0x0002, 0x0904, 0xdfa4, 0x00c0, 0x9186, 0x0027, 0x0180, 0x9186,
+ 0x0048, 0x0128, 0x9186, 0x0014, 0x0150, 0x190c, 0x0d79, 0x080c,
+ 0xad4d, 0x0150, 0x9086, 0x0004, 0x0904, 0xe043, 0x0028, 0x6004,
+ 0x9082, 0x0040, 0x2008, 0x001a, 0x080c, 0xb009, 0x0005, 0xdf23,
+ 0xdf25, 0xdf25, 0xdf4c, 0xdf23, 0xdf23, 0xdf23, 0xdf23, 0xdf23,
+ 0xdf23, 0xdf23, 0xdf23, 0xdf23, 0xdf23, 0xdf23, 0xdf23, 0xdf23,
+ 0xdf23, 0xdf23, 0xdf23, 0x080c, 0x0d79, 0x080c, 0x97f6, 0x080c,
+ 0x98bc, 0x0036, 0x0096, 0x6014, 0x904d, 0x01d8, 0x080c, 0xcc33,
+ 0x01c0, 0x6003, 0x0002, 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be,
+ 0xd0bc, 0x1178, 0x2019, 0x0004, 0x080c, 0xe738, 0x6017, 0x0000,
+ 0x6018, 0x9005, 0x1120, 0x2001, 0x1988, 0x2004, 0x601a, 0x6003,
+ 0x0007, 0x009e, 0x003e, 0x0005, 0x0096, 0x080c, 0x97f6, 0x080c,
+ 0x98bc, 0x080c, 0xcc33, 0x0120, 0x6014, 0x2048, 0x080c, 0x107f,
+ 0x080c, 0xaf89, 0x009e, 0x0005, 0x0002, 0xdf71, 0xdf86, 0xdf73,
+ 0xdf9b, 0xdf71, 0xdf71, 0xdf71, 0xdf71, 0xdf71, 0xdf71, 0xdf71,
+ 0xdf71, 0xdf71, 0xdf71, 0xdf71, 0xdf71, 0xdf71, 0xdf71, 0xdf71,
+ 0xdf71, 0x080c, 0x0d79, 0x0096, 0x6014, 0x2048, 0xa87c, 0xd0b4,
+ 0x0138, 0x6003, 0x0007, 0x2009, 0x0043, 0x080c, 0xafec, 0x0010,
+ 0x6003, 0x0004, 0x080c, 0x98bc, 0x009e, 0x0005, 0x080c, 0xcc33,
+ 0x0138, 0x6114, 0x0096, 0x2148, 0xa97c, 0x009e, 0xd1ec, 0x1138,
+ 0x080c, 0x8ab2, 0x080c, 0xaf4e, 0x080c, 0x98bc, 0x0005, 0x080c,
+ 0xe998, 0x0db0, 0x0cc8, 0x6003, 0x0001, 0x6007, 0x0041, 0x2009,
+ 0xa022, 0x080c, 0x9420, 0x0005, 0x9182, 0x0040, 0x0002, 0xdfbb,
+ 0xdfbd, 0xdfbb, 0xdfbb, 0xdfbb, 0xdfbb, 0xdfbb, 0xdfbb, 0xdfbb,
+ 0xdfbb, 0xdfbb, 0xdfbb, 0xdfbb, 0xdfbb, 0xdfbb, 0xdfbb, 0xdfbb,
+ 0xdfbe, 0xdfbb, 0xdfbb, 0x080c, 0x0d79, 0x0005, 0x00d6, 0x080c,
+ 0x8ab2, 0x00de, 0x080c, 0xe9f0, 0x080c, 0xaf4e, 0x0005, 0x9182,
+ 0x0040, 0x0002, 0xdfde, 0xdfde, 0xdfde, 0xdfde, 0xdfde, 0xdfde,
+ 0xdfde, 0xdfde, 0xdfde, 0xdfe0, 0xe00b, 0xdfde, 0xdfde, 0xdfde,
+ 0xdfde, 0xe00b, 0xdfde, 0xdfde, 0xdfde, 0xdfde, 0x080c, 0x0d79,
+ 0x6014, 0x0096, 0x2048, 0xa87c, 0xd0fc, 0x0168, 0x908c, 0x0003,
+ 0x918e, 0x0002, 0x0180, 0x6144, 0xd1e4, 0x1168, 0x2009, 0x0041,
+ 0x009e, 0x0804, 0xe0cb, 0x6003, 0x0007, 0x601b, 0x0000, 0x080c,
+ 0x8ab2, 0x009e, 0x0005, 0x6014, 0x2048, 0xa97c, 0xd1ec, 0x1130,
+ 0x080c, 0x8ab2, 0x080c, 0xaf4e, 0x009e, 0x0005, 0x080c, 0xe998,
+ 0x0db8, 0x009e, 0x0005, 0x2001, 0x180c, 0x200c, 0xc1d4, 0x2102,
+ 0x0036, 0x080c, 0x9851, 0x080c, 0x98bc, 0x6014, 0x0096, 0x2048,
+ 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x0188, 0xa87c,
+ 0x9084, 0x0003, 0x9086, 0x0002, 0x0140, 0xa8ac, 0x6330, 0x931a,
+ 0x6332, 0xa8b0, 0x632c, 0x931b, 0x632e, 0x6003, 0x0002, 0x0080,
+ 0x2019, 0x0004, 0x080c, 0xe738, 0x6018, 0x9005, 0x1128, 0x2001,
+ 0x1988, 0x2004, 0x8003, 0x601a, 0x6017, 0x0000, 0x6003, 0x0007,
+ 0x009e, 0x003e, 0x0005, 0x9182, 0x0040, 0x0002, 0xe05a, 0xe05a,
+ 0xe05a, 0xe05a, 0xe05a, 0xe05a, 0xe05a, 0xe05a, 0xe05c, 0xe05a,
+ 0xe05a, 0xe05a, 0xe05a, 0xe05a, 0xe05a, 0xe05a, 0xe05a, 0xe05a,
+ 0xe05a, 0xe0a7, 0x080c, 0x0d79, 0x6014, 0x0096, 0x2048, 0xa834,
+ 0xaa38, 0x6110, 0x00b6, 0x2158, 0xb900, 0x00be, 0xd1bc, 0x1190,
+ 0x920d, 0x1518, 0xa87c, 0xd0fc, 0x0128, 0x2009, 0x0041, 0x009e,
+ 0x0804, 0xe0cb, 0x6003, 0x0007, 0x601b, 0x0000, 0x080c, 0x8ab2,
+ 0x009e, 0x0005, 0x6124, 0xd1f4, 0x1d58, 0x0006, 0x0046, 0xacac,
+ 0x9422, 0xa9b0, 0x2200, 0x910b, 0x6030, 0x9420, 0x6432, 0x602c,
+ 0x9109, 0x612e, 0x004e, 0x000e, 0x08d8, 0x6110, 0x00b6, 0x2158,
+ 0xb900, 0x00be, 0xd1bc, 0x1178, 0x2009, 0x180e, 0x210c, 0xd19c,
+ 0x0118, 0x6003, 0x0007, 0x0010, 0x6003, 0x0006, 0x00e9, 0x080c,
+ 0x8ab4, 0x009e, 0x0005, 0x6003, 0x0002, 0x009e, 0x0005, 0x6024,
+ 0xd0f4, 0x0128, 0x080c, 0x16a4, 0x1904, 0xe05c, 0x0005, 0x6014,
+ 0x0096, 0x2048, 0xa834, 0xa938, 0x009e, 0x9105, 0x1120, 0x080c,
+ 0x16a4, 0x1904, 0xe05c, 0x0005, 0xd2fc, 0x0140, 0x8002, 0x8000,
+ 0x8212, 0x9291, 0x0000, 0x2009, 0x0009, 0x0010, 0x2009, 0x0015,
+ 0xaa9a, 0xa896, 0x0005, 0x9182, 0x0040, 0x0208, 0x0062, 0x9186,
+ 0x0013, 0x0120, 0x9186, 0x0014, 0x190c, 0x0d79, 0x6024, 0xd0dc,
+ 0x090c, 0x0d79, 0x0005, 0xe0ef, 0xe0fb, 0xe107, 0xe113, 0xe0ef,
+ 0xe0ef, 0xe0ef, 0xe0ef, 0xe0f6, 0xe0f1, 0xe0f1, 0xe0ef, 0xe0ef,
+ 0xe0ef, 0xe0ef, 0xe0f1, 0xe0ef, 0xe0f1, 0xe0ef, 0xe0f6, 0x080c,
+ 0x0d79, 0x6024, 0xd0dc, 0x090c, 0x0d79, 0x0005, 0x6014, 0x9005,
+ 0x190c, 0x0d79, 0x0005, 0x6003, 0x0001, 0x6106, 0x0126, 0x2091,
+ 0x8000, 0x2009, 0xa022, 0x080c, 0x9402, 0x012e, 0x0005, 0x6003,
+ 0x0004, 0x6106, 0x0126, 0x2091, 0x8000, 0x2009, 0xa001, 0x080c,
+ 0x9420, 0x012e, 0x0005, 0x6003, 0x0003, 0x6106, 0x080c, 0x1c8c,
+ 0x0126, 0x2091, 0x8000, 0x6014, 0x0096, 0x2048, 0xa87c, 0xd0fc,
+ 0x0188, 0x9084, 0x0003, 0x9086, 0x0002, 0x01a0, 0x6024, 0xd0cc,
+ 0x1148, 0xd0c4, 0x1138, 0xa8a8, 0x9005, 0x1120, 0x6144, 0x918d,
+ 0xb035, 0x0018, 0x6144, 0x918d, 0xa035, 0x009e, 0x080c, 0x9467,
+ 0x012e, 0x0005, 0x6144, 0x918d, 0xa032, 0x0cb8, 0x0126, 0x2091,
+ 0x8000, 0x0036, 0x0096, 0x9182, 0x0040, 0x0023, 0x009e, 0x003e,
+ 0x012e, 0x0005, 0xe15e, 0xe160, 0xe175, 0xe18f, 0xe15e, 0xe15e,
+ 0xe15e, 0xe15e, 0xe15e, 0xe15e, 0xe15e, 0xe15e, 0xe15e, 0xe15e,
+ 0xe15e, 0xe15e, 0xe15e, 0xe15e, 0xe15e, 0xe15e, 0x080c, 0x0d79,
+ 0x6014, 0x2048, 0xa87c, 0xd0fc, 0x0510, 0x909c, 0x0003, 0x939e,
+ 0x0003, 0x01e8, 0x6003, 0x0001, 0x6106, 0x0126, 0x2091, 0x8000,
+ 0x2009, 0xa022, 0x080c, 0x9420, 0x0470, 0x6014, 0x2048, 0xa87c,
+ 0xd0fc, 0x0168, 0x909c, 0x0003, 0x939e, 0x0003, 0x0140, 0x6003,
+ 0x0001, 0x6106, 0x2009, 0xa001, 0x080c, 0x9420, 0x00e0, 0x901e,
+ 0x6316, 0x631a, 0x2019, 0x0004, 0x080c, 0xe738, 0x00a0, 0x6014,
+ 0x2048, 0xa87c, 0xd0fc, 0x0d98, 0x909c, 0x0003, 0x939e, 0x0003,
+ 0x0d70, 0x6003, 0x0003, 0x6106, 0x080c, 0x1c8c, 0x6144, 0x918d,
+ 0xa035, 0x080c, 0x9467, 0x0005, 0x080c, 0x97f6, 0x6114, 0x81ff,
+ 0x0158, 0x0096, 0x2148, 0x080c, 0xeaee, 0x0036, 0x2019, 0x0029,
+ 0x080c, 0xe738, 0x003e, 0x009e, 0x080c, 0xaf89, 0x080c, 0x98bc,
+ 0x0005, 0x080c, 0x9851, 0x6114, 0x81ff, 0x0158, 0x0096, 0x2148,
+ 0x080c, 0xeaee, 0x0036, 0x2019, 0x0029, 0x080c, 0xe738, 0x003e,
+ 0x009e, 0x080c, 0xaf89, 0x0005, 0x9182, 0x0085, 0x0002, 0xe1de,
+ 0xe1dc, 0xe1dc, 0xe1ea, 0xe1dc, 0xe1dc, 0xe1dc, 0xe1dc, 0xe1dc,
+ 0xe1dc, 0xe1dc, 0xe1dc, 0xe1dc, 0x080c, 0x0d79, 0x6003, 0x000b,
+ 0x6106, 0x0126, 0x2091, 0x8000, 0x2009, 0x8020, 0x080c, 0x9420,
+ 0x012e, 0x0005, 0x0026, 0x00e6, 0x080c, 0xe98f, 0x0118, 0x080c,
+ 0xaf4e, 0x0440, 0x2071, 0x0260, 0x7224, 0x6216, 0x2001, 0x180e,
+ 0x2004, 0xd0e4, 0x0150, 0x6010, 0x00b6, 0x2058, 0xbca0, 0x00be,
+ 0x2c00, 0x2011, 0x014e, 0x080c, 0xb277, 0x7220, 0x080c, 0xe57d,
+ 0x0118, 0x6007, 0x0086, 0x0040, 0x6007, 0x0087, 0x7224, 0x9296,
+ 0xffff, 0x1110, 0x6007, 0x0086, 0x6003, 0x0001, 0x2009, 0x8020,
+ 0x080c, 0x9420, 0x00ee, 0x002e, 0x0005, 0x9186, 0x0013, 0x1160,
+ 0x6004, 0x908a, 0x0085, 0x0a0c, 0x0d79, 0x908a, 0x0092, 0x1a0c,
+ 0x0d79, 0x9082, 0x0085, 0x00a2, 0x9186, 0x0027, 0x0130, 0x9186,
+ 0x0014, 0x0118, 0x080c, 0xb009, 0x0050, 0x2001, 0x0007, 0x080c,
+ 0x66f5, 0x080c, 0x97f6, 0x080c, 0xaf89, 0x080c, 0x98bc, 0x0005,
+ 0xe24d, 0xe24f, 0xe24f, 0xe24d, 0xe24d, 0xe24d, 0xe24d, 0xe24d,
+ 0xe24d, 0xe24d, 0xe24d, 0xe24d, 0xe24d, 0x080c, 0x0d79, 0x080c,
+ 0xaf89, 0x080c, 0x98bc, 0x0005, 0x9182, 0x0085, 0x0a0c, 0x0d79,
+ 0x9182, 0x0092, 0x1a0c, 0x0d79, 0x9182, 0x0085, 0x0002, 0xe26c,
+ 0xe26c, 0xe26c, 0xe26e, 0xe26c, 0xe26c, 0xe26c, 0xe26c, 0xe26c,
+ 0xe26c, 0xe26c, 0xe26c, 0xe26c, 0x080c, 0x0d79, 0x0005, 0x9186,
+ 0x0013, 0x0148, 0x9186, 0x0014, 0x0130, 0x9186, 0x0027, 0x0118,
+ 0x080c, 0xb009, 0x0020, 0x080c, 0x97f6, 0x080c, 0xaf89, 0x0005,
+ 0x0036, 0x080c, 0xe9f0, 0x604b, 0x0000, 0x2019, 0x000b, 0x0031,
+ 0x6023, 0x0006, 0x6003, 0x0007, 0x003e, 0x0005, 0x0126, 0x0036,
+ 0x2091, 0x8000, 0x080c, 0xaaf7, 0x0106, 0x0086, 0x2c40, 0x0096,
+ 0x904e, 0x080c, 0xa462, 0x009e, 0x008e, 0x1558, 0x0076, 0x2c38,
+ 0x080c, 0xa50d, 0x007e, 0x1528, 0x6000, 0x9086, 0x0000, 0x0508,
+ 0x6020, 0x9086, 0x0007, 0x01e8, 0x0096, 0x601c, 0xd084, 0x0140,
+ 0x080c, 0xe9f0, 0x080c, 0xd375, 0x080c, 0x1af0, 0x6023, 0x0007,
+ 0x6014, 0x2048, 0x080c, 0xcc33, 0x0110, 0x080c, 0xe738, 0x009e,
+ 0x9006, 0x6046, 0x6016, 0x080c, 0xe9f0, 0x6023, 0x0007, 0x080c,
+ 0xd375, 0x010e, 0x090c, 0xab13, 0x003e, 0x012e, 0x0005, 0x00f6,
+ 0x00c6, 0x00b6, 0x0036, 0x0156, 0x2079, 0x0260, 0x7938, 0x783c,
+ 0x080c, 0x26a1, 0x1904, 0xe329, 0x0016, 0x00c6, 0x080c, 0x6783,
+ 0x1904, 0xe327, 0x001e, 0x00c6, 0x080c, 0xd35d, 0x1130, 0xb884,
+ 0x9005, 0x0118, 0x080c, 0x3463, 0x0148, 0x2b10, 0x2160, 0x6010,
+ 0x0006, 0x6212, 0x080c, 0xd364, 0x000e, 0x6012, 0x00ce, 0x002e,
+ 0x0026, 0x0016, 0x080c, 0xaaf7, 0x2019, 0x0029, 0x080c, 0xa5dd,
+ 0x080c, 0x95b9, 0x0076, 0x903e, 0x080c, 0x9476, 0x007e, 0x001e,
+ 0x0076, 0x903e, 0x080c, 0xe465, 0x007e, 0x080c, 0xab13, 0x0026,
+ 0xba04, 0x9294, 0xff00, 0x8217, 0x9286, 0x0006, 0x0118, 0x9286,
+ 0x0004, 0x1118, 0xbaa0, 0x080c, 0x33c6, 0x002e, 0xbc84, 0x001e,
+ 0x080c, 0x6192, 0xbe12, 0xbd16, 0xbc86, 0x9006, 0x0010, 0x00ce,
+ 0x001e, 0x015e, 0x003e, 0x00be, 0x00ce, 0x00fe, 0x0005, 0x00c6,
+ 0x00d6, 0x00b6, 0x0016, 0x2009, 0x1824, 0x2104, 0x9086, 0x0074,
+ 0x1904, 0xe388, 0x2069, 0x0260, 0x6944, 0x9182, 0x0100, 0x06e0,
+ 0x6940, 0x9184, 0x8000, 0x0904, 0xe385, 0x2001, 0x197d, 0x2004,
+ 0x9005, 0x1140, 0x6010, 0x2058, 0xb884, 0x9005, 0x0118, 0x9184,
+ 0x0800, 0x0598, 0x6948, 0x918a, 0x0001, 0x0648, 0x080c, 0xeb56,
+ 0x0118, 0x6978, 0xd1fc, 0x11b8, 0x2009, 0x0205, 0x200b, 0x0001,
+ 0x693c, 0x81ff, 0x1198, 0x6944, 0x9182, 0x0100, 0x02a8, 0x6940,
+ 0x81ff, 0x1178, 0x6948, 0x918a, 0x0001, 0x0288, 0x6950, 0x918a,
+ 0x0001, 0x0298, 0x00d0, 0x6017, 0x0100, 0x00a0, 0x6017, 0x0300,
+ 0x0088, 0x6017, 0x0500, 0x0070, 0x6017, 0x0700, 0x0058, 0x6017,
+ 0x0900, 0x0040, 0x6017, 0x0b00, 0x0028, 0x6017, 0x0f00, 0x0010,
+ 0x6017, 0x2d00, 0x9085, 0x0001, 0x0008, 0x9006, 0x001e, 0x00be,
+ 0x00de, 0x00ce, 0x0005, 0x00c6, 0x00b6, 0x0026, 0x0036, 0x0156,
+ 0x6210, 0x2258, 0xbb04, 0x9394, 0x00ff, 0x9286, 0x0006, 0x0180,
+ 0x9286, 0x0004, 0x0168, 0x9394, 0xff00, 0x8217, 0x9286, 0x0006,
+ 0x0138, 0x9286, 0x0004, 0x0120, 0x080c, 0x6792, 0x0804, 0xe3f4,
+ 0x2011, 0x0276, 0x20a9, 0x0004, 0x0096, 0x2b48, 0x2019, 0x000a,
+ 0x080c, 0xbf54, 0x009e, 0x15c8, 0x2011, 0x027a, 0x20a9, 0x0004,
+ 0x0096, 0x2b48, 0x2019, 0x0006, 0x080c, 0xbf54, 0x009e, 0x1568,
+ 0x0046, 0x0016, 0xbaa0, 0x2220, 0x9006, 0x2009, 0x1848, 0x210c,
+ 0xd1a4, 0x0138, 0x2009, 0x0029, 0x080c, 0xe795, 0xb800, 0xc0e5,
+ 0xb802, 0x080c, 0xaaf7, 0x2019, 0x0029, 0x080c, 0x95b9, 0x0076,
+ 0x2039, 0x0000, 0x080c, 0x9476, 0x2c08, 0x080c, 0xe465, 0x007e,
+ 0x080c, 0xab13, 0x2001, 0x0007, 0x080c, 0x66f5, 0x2001, 0x0007,
+ 0x080c, 0x66c9, 0x001e, 0x004e, 0x9006, 0x015e, 0x003e, 0x002e,
+ 0x00be, 0x00ce, 0x0005, 0x00d6, 0x2069, 0x026e, 0x6800, 0x9086,
+ 0x0800, 0x0118, 0x6017, 0x0000, 0x0008, 0x9006, 0x00de, 0x0005,
+ 0x00b6, 0x00f6, 0x0016, 0x0026, 0x0036, 0x0156, 0x2079, 0x026c,
+ 0x7930, 0x7834, 0x080c, 0x26a1, 0x11d0, 0x080c, 0x6783, 0x11b8,
+ 0x2011, 0x0270, 0x20a9, 0x0004, 0x0096, 0x2b48, 0x2019, 0x000a,
+ 0x080c, 0xbf54, 0x009e, 0x1158, 0x2011, 0x0274, 0x20a9, 0x0004,
+ 0x0096, 0x2b48, 0x2019, 0x0006, 0x080c, 0xbf54, 0x009e, 0x015e,
+ 0x003e, 0x002e, 0x001e, 0x00fe, 0x00be, 0x0005, 0x00b6, 0x0006,
+ 0x0016, 0x0026, 0x0036, 0x0156, 0x2011, 0x0263, 0x2204, 0x8211,
+ 0x220c, 0x080c, 0x26a1, 0x11d0, 0x080c, 0x6783, 0x11b8, 0x2011,
+ 0x0276, 0x20a9, 0x0004, 0x0096, 0x2b48, 0x2019, 0x000a, 0x080c,
+ 0xbf54, 0x009e, 0x1158, 0x2011, 0x027a, 0x20a9, 0x0004, 0x0096,
+ 0x2b48, 0x2019, 0x0006, 0x080c, 0xbf54, 0x009e, 0x015e, 0x003e,
+ 0x002e, 0x001e, 0x000e, 0x00be, 0x0005, 0x00e6, 0x00c6, 0x0086,
+ 0x0076, 0x0066, 0x0056, 0x0046, 0x0026, 0x0126, 0x2091, 0x8000,
+ 0x080c, 0xab55, 0x0106, 0x190c, 0xaaf7, 0x2740, 0x2029, 0x19f5,
0x252c, 0x2021, 0x19fc, 0x2424, 0x2061, 0x1ddc, 0x2071, 0x1800,
- 0x7654, 0x7074, 0x9606, 0x0578, 0x6720, 0x9786, 0x0001, 0x0118,
- 0x9786, 0x0008, 0x1500, 0x2500, 0x9c06, 0x01e8, 0x2400, 0x9c06,
- 0x01d0, 0x080c, 0xe75b, 0x01b8, 0x080c, 0xe76b, 0x11a0, 0x6000,
- 0x9086, 0x0004, 0x1120, 0x0016, 0x080c, 0x1afc, 0x001e, 0x080c,
- 0xce1c, 0x1110, 0x080c, 0x333f, 0x080c, 0xce2d, 0x1110, 0x080c,
- 0xb91f, 0x080c, 0xaf69, 0x9ce0, 0x001c, 0x2001, 0x181a, 0x2004,
- 0x9c02, 0x1208, 0x0858, 0x012e, 0x001e, 0x002e, 0x004e, 0x005e,
- 0x006e, 0x007e, 0x00ce, 0x00de, 0x00ee, 0x0005, 0x2001, 0x1810,
- 0x2004, 0xd0dc, 0x0005, 0x0006, 0x2001, 0x1837, 0x2004, 0xd09c,
- 0x000e, 0x0005, 0x0006, 0x0036, 0x0046, 0x080c, 0xd33e, 0x0168,
- 0x2019, 0xffff, 0x9005, 0x0128, 0x6010, 0x00b6, 0x2058, 0xbba0,
- 0x00be, 0x2021, 0x0004, 0x080c, 0x4de5, 0x004e, 0x003e, 0x000e,
- 0x0005, 0x6004, 0x9086, 0x0001, 0x1128, 0x080c, 0xa5c6, 0x080c,
- 0xaf69, 0x9006, 0x0005, 0x00e6, 0x00c6, 0x00b6, 0x0046, 0x2061,
- 0x1ddc, 0x2071, 0x1800, 0x7454, 0x7074, 0x8001, 0x9402, 0x12d8,
- 0x2100, 0x9c06, 0x0168, 0x6000, 0x9086, 0x0000, 0x0148, 0x6010,
- 0x2058, 0xb8a0, 0x9206, 0x1120, 0x6004, 0x9086, 0x0002, 0x0140,
- 0x9ce0, 0x001c, 0x2001, 0x181a, 0x2004, 0x9c02, 0x1220, 0x0c40,
- 0x9085, 0x0001, 0x0008, 0x9006, 0x004e, 0x00be, 0x00ce, 0x00ee,
- 0x0005, 0x2001, 0x1810, 0x2004, 0xd0a4, 0x0160, 0x2001, 0x1837,
- 0x2004, 0xd0a4, 0x0138, 0x2001, 0x1848, 0x2004, 0xd0a4, 0x1118,
- 0x9085, 0x0001, 0x0005, 0x9006, 0x0ce8, 0x0126, 0x0006, 0x00e6,
- 0x0016, 0x2091, 0x8000, 0x2071, 0x1840, 0xd5a4, 0x0118, 0x7004,
- 0x8000, 0x7006, 0xd5b4, 0x0118, 0x7000, 0x8000, 0x7002, 0xd5ac,
- 0x0178, 0x2500, 0x9084, 0x0007, 0x908e, 0x0003, 0x0148, 0x908e,
- 0x0004, 0x0130, 0x908e, 0x0005, 0x0118, 0x2071, 0xfff6, 0x0089,
- 0x001e, 0x00ee, 0x000e, 0x012e, 0x0005, 0x0126, 0x0006, 0x00e6,
- 0x2091, 0x8000, 0x2071, 0xffee, 0x0021, 0x00ee, 0x000e, 0x012e,
- 0x0005, 0x2e05, 0x8000, 0x2077, 0x1220, 0x8e70, 0x2e05, 0x8000,
- 0x2077, 0x0005, 0x00e6, 0x2071, 0xffec, 0x0c99, 0x00ee, 0x0005,
- 0x00e6, 0x2071, 0xfff0, 0x0c69, 0x00ee, 0x0005, 0x0126, 0x0006,
- 0x00e6, 0x2091, 0x8000, 0x2071, 0x1840, 0x7014, 0x8000, 0x7016,
- 0x00ee, 0x000e, 0x012e, 0x0005, 0x0001, 0x0002, 0x0004, 0x0008,
- 0x0010, 0x0020, 0x0040, 0x0080, 0x0100, 0x0200, 0x0400, 0x0800,
- 0x1000, 0x2000, 0x4000, 0x8000, 0x77f3
+ 0x7654, 0x7074, 0x81ff, 0x0150, 0x0006, 0x9186, 0x1b3a, 0x000e,
+ 0x0128, 0x8001, 0x9602, 0x1a04, 0xe50b, 0x0018, 0x9606, 0x0904,
+ 0xe50b, 0x080c, 0x8d87, 0x0904, 0xe502, 0x2100, 0x9c06, 0x0904,
+ 0xe502, 0x6720, 0x9786, 0x0007, 0x0904, 0xe502, 0x080c, 0xe7d6,
+ 0x1904, 0xe502, 0x080c, 0xeb74, 0x0904, 0xe502, 0x080c, 0xe7c6,
+ 0x0904, 0xe502, 0x6720, 0x9786, 0x0001, 0x1148, 0x080c, 0x3463,
+ 0x0904, 0xe54d, 0x6004, 0x9086, 0x0000, 0x1904, 0xe54d, 0x9786,
+ 0x0004, 0x0904, 0xe54d, 0x2500, 0x9c06, 0x0904, 0xe502, 0x2400,
+ 0x9c06, 0x0904, 0xe502, 0x88ff, 0x0118, 0x605c, 0x9906, 0x15d0,
+ 0x0096, 0x6043, 0xffff, 0x6000, 0x9086, 0x0004, 0x1120, 0x0016,
+ 0x080c, 0x1af0, 0x001e, 0x9786, 0x000a, 0x0148, 0x080c, 0xce4a,
+ 0x1130, 0x080c, 0xb93c, 0x009e, 0x080c, 0xaf89, 0x0418, 0x6014,
+ 0x2048, 0x080c, 0xcc33, 0x01d8, 0x9786, 0x0003, 0x1588, 0xa867,
+ 0x0103, 0xa87c, 0xd0cc, 0x0130, 0x0096, 0xa878, 0x2048, 0x080c,
+ 0x0fff, 0x009e, 0xab7a, 0xa877, 0x0000, 0x080c, 0xeaee, 0x0016,
+ 0x080c, 0xcf38, 0x080c, 0x6f05, 0x001e, 0x080c, 0xce24, 0x009e,
+ 0x080c, 0xaf89, 0x9ce0, 0x001c, 0x2001, 0x181a, 0x2004, 0x9c02,
+ 0x1210, 0x0804, 0xe47e, 0x010e, 0x190c, 0xab13, 0x012e, 0x002e,
+ 0x004e, 0x005e, 0x006e, 0x007e, 0x008e, 0x00ce, 0x00ee, 0x0005,
+ 0x9786, 0x0006, 0x1150, 0x9386, 0x0005, 0x0128, 0x080c, 0xeaee,
+ 0x080c, 0xe738, 0x08e0, 0x009e, 0x08e8, 0x9786, 0x0009, 0x11f8,
+ 0x6000, 0x9086, 0x0004, 0x01c0, 0x6000, 0x9086, 0x0003, 0x11a0,
+ 0x080c, 0x9851, 0x0096, 0x6114, 0x2148, 0x080c, 0xcc33, 0x0118,
+ 0x6010, 0x080c, 0x6f11, 0x009e, 0x00c6, 0x080c, 0xaf4e, 0x00ce,
+ 0x0036, 0x080c, 0x98bc, 0x003e, 0x009e, 0x0804, 0xe502, 0x9786,
+ 0x000a, 0x0904, 0xe4f2, 0x0804, 0xe4e7, 0x81ff, 0x0904, 0xe502,
+ 0x9180, 0x0001, 0x2004, 0x9086, 0x0018, 0x0138, 0x9180, 0x0001,
+ 0x2004, 0x9086, 0x002d, 0x1904, 0xe502, 0x6000, 0x9086, 0x0002,
+ 0x1904, 0xe502, 0x080c, 0xce39, 0x0138, 0x080c, 0xce4a, 0x1904,
+ 0xe502, 0x080c, 0xb93c, 0x0038, 0x080c, 0x332a, 0x080c, 0xce4a,
+ 0x1110, 0x080c, 0xb93c, 0x080c, 0xaf89, 0x0804, 0xe502, 0xa864,
+ 0x9084, 0x00ff, 0x9086, 0x0039, 0x0005, 0x00c6, 0x00e6, 0x0016,
+ 0x2c08, 0x2170, 0x9006, 0x080c, 0xe75f, 0x001e, 0x0120, 0x6020,
+ 0x9084, 0x000f, 0x001b, 0x00ee, 0x00ce, 0x0005, 0xe59c, 0xe59c,
+ 0xe59c, 0xe59c, 0xe59c, 0xe59c, 0xe59e, 0xe59c, 0xe59c, 0xe59c,
+ 0xe5c7, 0xaf89, 0xaf89, 0xe59c, 0x9006, 0x0005, 0x0036, 0x0046,
+ 0x0016, 0x7010, 0x00b6, 0x2058, 0xbca0, 0x00be, 0x2c00, 0x2009,
+ 0x0020, 0x080c, 0xe795, 0x001e, 0x004e, 0x2019, 0x0002, 0x080c,
+ 0xe28e, 0x003e, 0x9085, 0x0001, 0x0005, 0x0096, 0x080c, 0xcc33,
+ 0x0140, 0x6014, 0x904d, 0x080c, 0xc81b, 0x687b, 0x0005, 0x080c,
+ 0x6f11, 0x009e, 0x080c, 0xaf89, 0x9085, 0x0001, 0x0005, 0x0019,
+ 0x9085, 0x0001, 0x0005, 0x6000, 0x908a, 0x0010, 0x1a0c, 0x0d79,
+ 0x000b, 0x0005, 0xe5e2, 0xe5e2, 0xe5f9, 0xe5e9, 0xe608, 0xe5e2,
+ 0xe5e2, 0xe5e4, 0xe5e2, 0xe5e2, 0xe5e2, 0xe5e2, 0xe5e2, 0xe5e2,
+ 0xe5e2, 0xe5e2, 0x080c, 0x0d79, 0x080c, 0xaf89, 0x9085, 0x0001,
+ 0x0005, 0x0036, 0x00e6, 0x2071, 0x19e9, 0x704c, 0x9c06, 0x1128,
+ 0x2019, 0x0001, 0x080c, 0xa391, 0x0010, 0x080c, 0xa59c, 0x00ee,
+ 0x003e, 0x0096, 0x00d6, 0x6014, 0x2048, 0xa87b, 0x0005, 0x080c,
+ 0x6f11, 0x080c, 0xaf89, 0x00de, 0x009e, 0x9085, 0x0001, 0x0005,
+ 0x601c, 0xd084, 0x190c, 0x1af0, 0x0c60, 0x2001, 0x0001, 0x080c,
+ 0x66b5, 0x0156, 0x0016, 0x0026, 0x0036, 0x20a9, 0x0004, 0x2019,
+ 0x1805, 0x2011, 0x0276, 0x080c, 0xbf40, 0x003e, 0x002e, 0x001e,
+ 0x015e, 0x9005, 0x0005, 0x00f6, 0x00e6, 0x00c6, 0x0086, 0x0076,
+ 0x0066, 0x00b6, 0x0126, 0x2091, 0x8000, 0x2740, 0x2061, 0x1ddc,
+ 0x2079, 0x0001, 0x8fff, 0x0904, 0xe67f, 0x2071, 0x1800, 0x7654,
+ 0x7074, 0x8001, 0x9602, 0x1a04, 0xe67f, 0x88ff, 0x0120, 0x2800,
+ 0x9c06, 0x15a0, 0x2078, 0x080c, 0xe7c6, 0x0580, 0x2400, 0x9c06,
+ 0x0568, 0x6720, 0x9786, 0x0006, 0x1548, 0x9786, 0x0007, 0x0530,
+ 0x88ff, 0x1150, 0xd58c, 0x1118, 0x6010, 0x9b06, 0x11f8, 0xd584,
+ 0x0118, 0x605c, 0x9106, 0x11d0, 0x0096, 0x601c, 0xd084, 0x0140,
+ 0x080c, 0xe9f0, 0x080c, 0xd375, 0x080c, 0x1af0, 0x6023, 0x0007,
+ 0x6014, 0x2048, 0x080c, 0xcc33, 0x0120, 0x0046, 0x080c, 0xe738,
+ 0x004e, 0x009e, 0x080c, 0xaf89, 0x88ff, 0x1198, 0x9ce0, 0x001c,
+ 0x2001, 0x181a, 0x2004, 0x9c02, 0x1210, 0x0804, 0xe632, 0x9006,
+ 0x012e, 0x00be, 0x006e, 0x007e, 0x008e, 0x00ce, 0x00ee, 0x00fe,
+ 0x0005, 0x98c5, 0x0001, 0x0ca0, 0x080c, 0xaaf7, 0x00b6, 0x0076,
+ 0x0056, 0x0086, 0x9046, 0x2029, 0x0001, 0x2c20, 0x2019, 0x0002,
+ 0x6210, 0x2258, 0x0096, 0x904e, 0x080c, 0xa462, 0x009e, 0x008e,
+ 0x903e, 0x080c, 0xa50d, 0x080c, 0xe623, 0x005e, 0x007e, 0x00be,
+ 0x080c, 0xab13, 0x0005, 0x080c, 0xaaf7, 0x00b6, 0x0046, 0x0056,
+ 0x0076, 0x00c6, 0x0156, 0x2c20, 0x2128, 0x20a9, 0x007f, 0x900e,
+ 0x0016, 0x0036, 0x080c, 0x6783, 0x1180, 0x0056, 0x0086, 0x9046,
+ 0x2508, 0x2029, 0x0001, 0x0096, 0x904e, 0x080c, 0xa462, 0x009e,
+ 0x008e, 0x903e, 0x080c, 0xa50d, 0x005e, 0x003e, 0x001e, 0x8108,
+ 0x1f04, 0xe6b8, 0x0036, 0x2508, 0x2029, 0x0003, 0x080c, 0xe623,
+ 0x003e, 0x015e, 0x00ce, 0x007e, 0x005e, 0x004e, 0x00be, 0x080c,
+ 0xab13, 0x0005, 0x080c, 0xaaf7, 0x00b6, 0x0076, 0x0056, 0x6210,
+ 0x2258, 0x0086, 0x9046, 0x2029, 0x0001, 0x2019, 0x0048, 0x0096,
+ 0x904e, 0x080c, 0xa462, 0x009e, 0x008e, 0x903e, 0x080c, 0xa50d,
+ 0x2c20, 0x080c, 0xe623, 0x005e, 0x007e, 0x00be, 0x080c, 0xab13,
+ 0x0005, 0x080c, 0xaaf7, 0x00b6, 0x0046, 0x0056, 0x0076, 0x00c6,
+ 0x0156, 0x2c20, 0x20a9, 0x0800, 0x900e, 0x0016, 0x0036, 0x080c,
+ 0x6783, 0x1190, 0x0086, 0x9046, 0x2828, 0x0046, 0x2021, 0x0001,
+ 0x080c, 0xe9d4, 0x004e, 0x0096, 0x904e, 0x080c, 0xa462, 0x009e,
+ 0x008e, 0x903e, 0x080c, 0xa50d, 0x003e, 0x001e, 0x8108, 0x1f04,
+ 0xe70d, 0x0036, 0x2029, 0x0002, 0x080c, 0xe623, 0x003e, 0x015e,
+ 0x00ce, 0x007e, 0x005e, 0x004e, 0x00be, 0x080c, 0xab13, 0x0005,
+ 0x0016, 0x00f6, 0x080c, 0xcc31, 0x0198, 0xa864, 0x9084, 0x00ff,
+ 0x9086, 0x0046, 0x0180, 0xa800, 0x907d, 0x0138, 0xa803, 0x0000,
+ 0xab82, 0x080c, 0x6f11, 0x2f48, 0x0cb0, 0xab82, 0x080c, 0x6f11,
+ 0x00fe, 0x001e, 0x0005, 0xa800, 0x907d, 0x0130, 0xa803, 0x0000,
+ 0x080c, 0x6f11, 0x2f48, 0x0cb8, 0x080c, 0x6f11, 0x0c88, 0x00e6,
+ 0x0046, 0x0036, 0x2061, 0x1ddc, 0x9005, 0x1138, 0x2071, 0x1800,
+ 0x7454, 0x7074, 0x8001, 0x9402, 0x12f8, 0x2100, 0x9c06, 0x0188,
+ 0x6000, 0x9086, 0x0000, 0x0168, 0x6008, 0x9206, 0x1150, 0x6320,
+ 0x9386, 0x0009, 0x01b0, 0x6010, 0x91a0, 0x0004, 0x2424, 0x9406,
+ 0x0140, 0x9ce0, 0x001c, 0x2001, 0x181a, 0x2004, 0x9c02, 0x1220,
+ 0x0c20, 0x9085, 0x0001, 0x0008, 0x9006, 0x003e, 0x004e, 0x00ee,
+ 0x0005, 0x631c, 0xd3c4, 0x1d68, 0x0c30, 0x0096, 0x0006, 0x080c,
+ 0x104d, 0x000e, 0x090c, 0x0d79, 0xaae2, 0xa867, 0x010d, 0xa88e,
+ 0x0026, 0x2010, 0x080c, 0xcc21, 0x2001, 0x0000, 0x0120, 0x2200,
+ 0x9080, 0x0017, 0x2004, 0x002e, 0xa87a, 0x9186, 0x0020, 0x0110,
+ 0xa8e3, 0xffff, 0xa986, 0xac76, 0xa87f, 0x0000, 0x2001, 0x198f,
+ 0x2004, 0xa882, 0x9006, 0xa802, 0xa86a, 0xa88a, 0x0126, 0x2091,
+ 0x8000, 0x080c, 0x6f11, 0x012e, 0x009e, 0x0005, 0x6700, 0x9786,
+ 0x0000, 0x0158, 0x9786, 0x0001, 0x0140, 0x9786, 0x000a, 0x0128,
+ 0x9786, 0x0009, 0x0110, 0x9085, 0x0001, 0x0005, 0x00e6, 0x6010,
+ 0x9075, 0x0138, 0x00b6, 0x2058, 0xb8a0, 0x00be, 0x9206, 0x00ee,
+ 0x0005, 0x9085, 0x0001, 0x0cd8, 0x0016, 0x6004, 0x908e, 0x001e,
+ 0x11a0, 0x8007, 0x6134, 0x918c, 0x00ff, 0x9105, 0x6036, 0x6007,
+ 0x0085, 0x6003, 0x000b, 0x6023, 0x0005, 0x2001, 0x1988, 0x2004,
+ 0x601a, 0x2009, 0x8020, 0x080c, 0x9420, 0x001e, 0x0005, 0xa001,
+ 0xa001, 0x0005, 0x6024, 0xd0e4, 0x0158, 0xd0cc, 0x0118, 0x080c,
+ 0xcf7f, 0x0030, 0x080c, 0xe9f0, 0x080c, 0x8ab2, 0x080c, 0xaf4e,
+ 0x0005, 0x9280, 0x0008, 0x2004, 0x9084, 0x000f, 0x0002, 0xe825,
+ 0xe825, 0xe825, 0xe827, 0xe825, 0xe827, 0xe827, 0xe825, 0xe827,
+ 0xe825, 0xe825, 0xe825, 0xe825, 0xe825, 0x9006, 0x0005, 0x9085,
+ 0x0001, 0x0005, 0x9280, 0x0008, 0x2004, 0x9084, 0x000f, 0x0002,
+ 0xe83e, 0xe83e, 0xe83e, 0xe83e, 0xe83e, 0xe83e, 0xe84b, 0xe83e,
+ 0xe83e, 0xe83e, 0xe83e, 0xe83e, 0xe83e, 0xe83e, 0x6007, 0x003b,
+ 0x602f, 0x0009, 0x6017, 0x2a00, 0x6003, 0x0001, 0x2009, 0x8020,
+ 0x080c, 0x9420, 0x0005, 0x0096, 0x00c6, 0x2260, 0x080c, 0xe9f0,
+ 0x604b, 0x0000, 0x6024, 0xc0f4, 0xc0e4, 0x6026, 0x603b, 0x0000,
+ 0x00ce, 0x00d6, 0x2268, 0x9186, 0x0007, 0x1904, 0xe8a4, 0x6814,
+ 0x9005, 0x0138, 0x2048, 0xa87c, 0xd0fc, 0x1118, 0x00de, 0x009e,
+ 0x08a8, 0x6007, 0x003a, 0x6003, 0x0001, 0x2009, 0x8020, 0x080c,
+ 0x9420, 0x00c6, 0x2d60, 0x6100, 0x9186, 0x0002, 0x1904, 0xe91b,
+ 0x6014, 0x9005, 0x1138, 0x6000, 0x9086, 0x0007, 0x190c, 0x0d79,
+ 0x0804, 0xe91b, 0x2048, 0x080c, 0xcc33, 0x1130, 0x0028, 0x2048,
+ 0xa800, 0x9005, 0x1de0, 0x2900, 0x2048, 0xa87c, 0x9084, 0x0003,
+ 0x9086, 0x0002, 0x1168, 0xa87c, 0xc0dc, 0xc0f4, 0xa87e, 0xa880,
+ 0xc0fc, 0xa882, 0x2009, 0x0043, 0x080c, 0xe0cb, 0x0804, 0xe91b,
+ 0x2009, 0x0041, 0x0804, 0xe915, 0x9186, 0x0005, 0x15a0, 0x6814,
+ 0x2048, 0xa87c, 0xd0bc, 0x1120, 0x00de, 0x009e, 0x0804, 0xe83e,
+ 0xd0b4, 0x0128, 0xd0fc, 0x090c, 0x0d79, 0x0804, 0xe85f, 0x6007,
+ 0x003a, 0x6003, 0x0001, 0x2009, 0x8020, 0x080c, 0x9420, 0x00c6,
+ 0x2d60, 0x6100, 0x9186, 0x0002, 0x0120, 0x9186, 0x0004, 0x1904,
+ 0xe91b, 0x6814, 0x2048, 0xa97c, 0xc1f4, 0xc1dc, 0xa97e, 0xa980,
+ 0xc1fc, 0xc1bc, 0xa982, 0x00f6, 0x2c78, 0x080c, 0x17a1, 0x00fe,
+ 0x2009, 0x0042, 0x04d0, 0x0036, 0x080c, 0x104d, 0x090c, 0x0d79,
+ 0xa867, 0x010d, 0x9006, 0xa802, 0xa86a, 0xa88a, 0x2d18, 0xab8e,
+ 0xa887, 0x0045, 0x2c00, 0xa892, 0x6038, 0xa8a2, 0x2360, 0x6024,
+ 0xc0dd, 0x6026, 0x6010, 0x00b6, 0x2058, 0xb8a0, 0x00be, 0x2004,
+ 0x635c, 0xab7a, 0xa876, 0x9006, 0xa87e, 0xa882, 0xad9a, 0xae96,
+ 0xa89f, 0x0001, 0x080c, 0x6f11, 0x2019, 0x0045, 0x6008, 0x2068,
+ 0x080c, 0xe28e, 0x2d00, 0x600a, 0x6023, 0x0006, 0x6003, 0x0007,
+ 0x901e, 0x631a, 0x634a, 0x003e, 0x0038, 0x604b, 0x0000, 0x6003,
+ 0x0007, 0x080c, 0xe0cb, 0x00ce, 0x00de, 0x009e, 0x0005, 0x9186,
+ 0x0013, 0x1128, 0x6004, 0x9082, 0x0085, 0x2008, 0x00c2, 0x9186,
+ 0x0027, 0x1178, 0x080c, 0x97f6, 0x0036, 0x0096, 0x6014, 0x2048,
+ 0x2019, 0x0004, 0x080c, 0xe738, 0x009e, 0x003e, 0x080c, 0x98bc,
+ 0x0005, 0x9186, 0x0014, 0x0d70, 0x080c, 0xb009, 0x0005, 0xe94e,
+ 0xe94c, 0xe94c, 0xe94c, 0xe94c, 0xe94c, 0xe94e, 0xe94c, 0xe94c,
+ 0xe94c, 0xe94c, 0xe94c, 0xe94c, 0x080c, 0x0d79, 0x6003, 0x000c,
+ 0x080c, 0x98bc, 0x0005, 0x9182, 0x0092, 0x1220, 0x9182, 0x0085,
+ 0x0208, 0x001a, 0x080c, 0xb009, 0x0005, 0xe96a, 0xe96a, 0xe96a,
+ 0xe96a, 0xe96c, 0xe98c, 0xe96a, 0xe96a, 0xe96a, 0xe96a, 0xe96a,
+ 0xe96a, 0xe96a, 0x080c, 0x0d79, 0x00d6, 0x2c68, 0x080c, 0xaef8,
+ 0x01b0, 0x6003, 0x0001, 0x6007, 0x001e, 0x2009, 0x026e, 0x210c,
+ 0x613a, 0x2009, 0x026f, 0x210c, 0x613e, 0x600b, 0xffff, 0x6910,
+ 0x6112, 0x6023, 0x0004, 0x2009, 0x8020, 0x080c, 0x9420, 0x2d60,
+ 0x080c, 0xaf4e, 0x00de, 0x0005, 0x080c, 0xaf4e, 0x0005, 0x00e6,
+ 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0ec, 0x00ee, 0x0005,
+ 0x2009, 0x1867, 0x210c, 0xd1ec, 0x05b0, 0x6003, 0x0002, 0x6024,
+ 0xc0e5, 0x6026, 0xd0cc, 0x0150, 0x2001, 0x1989, 0x2004, 0x604a,
+ 0x2009, 0x1867, 0x210c, 0xd1f4, 0x1520, 0x00a0, 0x2009, 0x1867,
+ 0x210c, 0xd1f4, 0x0128, 0x6024, 0xc0e4, 0x6026, 0x9006, 0x00d8,
+ 0x2001, 0x1989, 0x200c, 0x2001, 0x1987, 0x2004, 0x9100, 0x9080,
+ 0x000a, 0x604a, 0x6010, 0x00b6, 0x2058, 0xb8bc, 0x00be, 0x0008,
+ 0x2104, 0x9005, 0x0118, 0x9088, 0x0003, 0x0cd0, 0x2c0a, 0x600f,
+ 0x0000, 0x9085, 0x0001, 0x0005, 0x0016, 0x00c6, 0x00e6, 0x615c,
+ 0xb8bc, 0x2060, 0x8cff, 0x0180, 0x84ff, 0x1118, 0x605c, 0x9106,
+ 0x1138, 0x600c, 0x2072, 0x080c, 0x8ab2, 0x080c, 0xaf4e, 0x0010,
+ 0x9cf0, 0x0003, 0x2e64, 0x0c70, 0x00ee, 0x00ce, 0x001e, 0x0005,
+ 0x00d6, 0x00b6, 0x6010, 0x2058, 0xb8bc, 0x906d, 0x0130, 0x9c06,
+ 0x0110, 0x680c, 0x0cd0, 0x600c, 0x680e, 0x00be, 0x00de, 0x0005,
+ 0x0026, 0x0036, 0x0156, 0x2011, 0x182c, 0x2204, 0x9084, 0x00ff,
+ 0x2019, 0x026e, 0x2334, 0x96b4, 0x00ff, 0x9636, 0x1508, 0x8318,
+ 0x2334, 0x2204, 0x9084, 0xff00, 0x9636, 0x11d0, 0x2011, 0x0270,
+ 0x20a9, 0x0004, 0x6010, 0x0096, 0x2048, 0x2019, 0x000a, 0x080c,
+ 0xbf54, 0x009e, 0x1168, 0x2011, 0x0274, 0x20a9, 0x0004, 0x6010,
+ 0x0096, 0x2048, 0x2019, 0x0006, 0x080c, 0xbf54, 0x009e, 0x1100,
+ 0x015e, 0x003e, 0x002e, 0x0005, 0x00e6, 0x2071, 0x1800, 0x080c,
+ 0x610b, 0x080c, 0x30c8, 0x00ee, 0x0005, 0x0096, 0x0026, 0x080c,
+ 0x104d, 0x090c, 0x0d79, 0xa85c, 0x9080, 0x001a, 0x20a0, 0x20a9,
+ 0x000c, 0xa860, 0x20e8, 0x9006, 0x4004, 0x9186, 0x0046, 0x1118,
+ 0xa867, 0x0136, 0x0038, 0xa867, 0x0138, 0x9186, 0x0041, 0x0110,
+ 0xa87b, 0x0001, 0x7038, 0x9084, 0xff00, 0x7240, 0x9294, 0xff00,
+ 0x8007, 0x9215, 0xaa9a, 0x9186, 0x0046, 0x1168, 0x7038, 0x9084,
+ 0x00ff, 0x723c, 0x9294, 0xff00, 0x9215, 0xaa9e, 0x723c, 0x9294,
+ 0x00ff, 0xaaa2, 0x0060, 0x7040, 0x9084, 0x00ff, 0x7244, 0x9294,
+ 0xff00, 0x9215, 0xaa9e, 0x7244, 0x9294, 0x00ff, 0xaaa2, 0x9186,
+ 0x0046, 0x1118, 0x9e90, 0x0012, 0x0010, 0x9e90, 0x001a, 0x2204,
+ 0x8007, 0xa8a6, 0x8210, 0x2204, 0x8007, 0xa8aa, 0x8210, 0x2204,
+ 0x8007, 0xa8ae, 0x8210, 0x2204, 0x8007, 0xa8b2, 0x8210, 0x9186,
+ 0x0046, 0x11b8, 0x9e90, 0x0016, 0x2204, 0x8007, 0xa8b6, 0x8210,
+ 0x2204, 0x8007, 0xa8ba, 0x8210, 0x2204, 0x8007, 0xa8be, 0x8210,
+ 0x2204, 0x8007, 0xa8c2, 0x8210, 0x2011, 0x0205, 0x2013, 0x0001,
+ 0x00b0, 0x9e90, 0x001e, 0x2204, 0x8007, 0xa8b6, 0x8210, 0x2204,
+ 0x8007, 0xa8ba, 0x2011, 0x0205, 0x2013, 0x0001, 0x2011, 0x0260,
+ 0x2204, 0x8007, 0xa8be, 0x8210, 0x2204, 0x8007, 0xa8c2, 0x9186,
+ 0x0046, 0x1118, 0x2011, 0x0262, 0x0010, 0x2011, 0x026a, 0x0146,
+ 0x01d6, 0x0036, 0x20a9, 0x0001, 0x2019, 0x0008, 0xa860, 0x20e8,
+ 0xa85c, 0x9080, 0x0031, 0x20a0, 0x2204, 0x8007, 0x4004, 0x8210,
+ 0x8319, 0x1dd0, 0x003e, 0x01ce, 0x013e, 0x2011, 0x0205, 0x2013,
+ 0x0000, 0x002e, 0x080c, 0x6f11, 0x009e, 0x0005, 0x00e6, 0x6010,
+ 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0fc, 0x0108, 0x0011, 0x00ee,
+ 0x0005, 0xa880, 0xc0e5, 0xa882, 0x0005, 0x00e6, 0x00d6, 0x00c6,
+ 0x0076, 0x0066, 0x0056, 0x0046, 0x0026, 0x0016, 0x0126, 0x2091,
+ 0x8000, 0x2029, 0x19f5, 0x252c, 0x2021, 0x19fc, 0x2424, 0x2061,
+ 0x1ddc, 0x2071, 0x1800, 0x7654, 0x7074, 0x9606, 0x0578, 0x6720,
+ 0x9786, 0x0001, 0x0118, 0x9786, 0x0008, 0x1500, 0x2500, 0x9c06,
+ 0x01e8, 0x2400, 0x9c06, 0x01d0, 0x080c, 0xe7c6, 0x01b8, 0x080c,
+ 0xe7d6, 0x11a0, 0x6000, 0x9086, 0x0004, 0x1120, 0x0016, 0x080c,
+ 0x1af0, 0x001e, 0x080c, 0xce39, 0x1110, 0x080c, 0x332a, 0x080c,
+ 0xce4a, 0x1110, 0x080c, 0xb93c, 0x080c, 0xaf89, 0x9ce0, 0x001c,
+ 0x2001, 0x181a, 0x2004, 0x9c02, 0x1208, 0x0858, 0x012e, 0x001e,
+ 0x002e, 0x004e, 0x005e, 0x006e, 0x007e, 0x00ce, 0x00de, 0x00ee,
+ 0x0005, 0x2001, 0x1810, 0x2004, 0xd0dc, 0x0005, 0x0006, 0x2001,
+ 0x1837, 0x2004, 0xd09c, 0x000e, 0x0005, 0x0006, 0x0036, 0x0046,
+ 0x080c, 0xd35d, 0x0168, 0x2019, 0xffff, 0x9005, 0x0128, 0x6010,
+ 0x00b6, 0x2058, 0xbba0, 0x00be, 0x2021, 0x0004, 0x080c, 0x4ddf,
+ 0x004e, 0x003e, 0x000e, 0x0005, 0x6004, 0x9086, 0x0001, 0x1128,
+ 0x080c, 0xa5dd, 0x080c, 0xaf89, 0x9006, 0x0005, 0x00e6, 0x00c6,
+ 0x00b6, 0x0046, 0x2061, 0x1ddc, 0x2071, 0x1800, 0x7454, 0x7074,
+ 0x8001, 0x9402, 0x12d8, 0x2100, 0x9c06, 0x0168, 0x6000, 0x9086,
+ 0x0000, 0x0148, 0x6010, 0x2058, 0xb8a0, 0x9206, 0x1120, 0x6004,
+ 0x9086, 0x0002, 0x0140, 0x9ce0, 0x001c, 0x2001, 0x181a, 0x2004,
+ 0x9c02, 0x1220, 0x0c40, 0x9085, 0x0001, 0x0008, 0x9006, 0x004e,
+ 0x00be, 0x00ce, 0x00ee, 0x0005, 0x2001, 0x1810, 0x2004, 0xd0a4,
+ 0x0160, 0x2001, 0x1837, 0x2004, 0xd0a4, 0x0138, 0x2001, 0x1848,
+ 0x2004, 0xd0a4, 0x1118, 0x9085, 0x0001, 0x0005, 0x9006, 0x0ce8,
+ 0x0126, 0x0006, 0x00e6, 0x0016, 0x2091, 0x8000, 0x2071, 0x1840,
+ 0xd5a4, 0x0118, 0x7004, 0x8000, 0x7006, 0xd5b4, 0x0118, 0x7000,
+ 0x8000, 0x7002, 0xd5ac, 0x0178, 0x2500, 0x9084, 0x0007, 0x908e,
+ 0x0003, 0x0148, 0x908e, 0x0004, 0x0130, 0x908e, 0x0005, 0x0118,
+ 0x2071, 0xfff6, 0x0089, 0x001e, 0x00ee, 0x000e, 0x012e, 0x0005,
+ 0x0126, 0x0006, 0x00e6, 0x2091, 0x8000, 0x2071, 0xffee, 0x0021,
+ 0x00ee, 0x000e, 0x012e, 0x0005, 0x2e05, 0x8000, 0x2077, 0x1220,
+ 0x8e70, 0x2e05, 0x8000, 0x2077, 0x0005, 0x00e6, 0x2071, 0xffec,
+ 0x0c99, 0x00ee, 0x0005, 0x00e6, 0x2071, 0xfff0, 0x0c69, 0x00ee,
+ 0x0005, 0x0126, 0x0006, 0x00e6, 0x2091, 0x8000, 0x2071, 0x1840,
+ 0x7014, 0x8000, 0x7016, 0x00ee, 0x000e, 0x012e, 0x0005, 0x0001,
+ 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080, 0x0100,
+ 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000, 0x8000, 0x7163
};
#ifdef UNIQUE_FW_NAME
-unsigned short fw2322ipx_length01 = 0xe3bd;
+unsigned short fw2322ipx_length01 = 0xe428;
#else
-unsigned short risc_code_length01 = 0xe3bd;
+unsigned short risc_code_length01 = 0xe428;
#endif
/*
@@ -7351,32 +7352,32 @@ unsigned short risc_code_length01 = 0xe3bd;
unsigned long rseqipx_code_addr01 = 0x0001c000 ;
unsigned short rseqipx_code01[] = {
-0x000b, 0x0003, 0x0000, 0x0a20, 0x0001, 0xc000, 0x0008, 0x8064,
+0x000b, 0x0003, 0x0000, 0x0a4a, 0x0001, 0xc000, 0x0008, 0x8064,
0x0000, 0x0010, 0x0000, 0x8066, 0x0008, 0x0101, 0x0003, 0xc007,
0x0008, 0x80e0, 0x0008, 0xff00, 0x0000, 0x80e2, 0x0008, 0xff00,
0x0008, 0x0162, 0x0000, 0x8066, 0x0008, 0xa101, 0x000b, 0xc00f,
0x0008, 0x0d02, 0x0000, 0x8060, 0x0000, 0x0400, 0x000b, 0x60c6,
- 0x0008, 0x80e0, 0x0000, 0x0100, 0x000b, 0x5819, 0x0003, 0x7af3,
- 0x000b, 0x522c, 0x000b, 0xc813, 0x0009, 0xbac0, 0x0000, 0x008a,
+ 0x0008, 0x80e0, 0x0000, 0x0100, 0x000b, 0x5819, 0x0003, 0x7b08,
+ 0x0003, 0x5241, 0x000b, 0xc813, 0x0009, 0xbac0, 0x0000, 0x008a,
0x0003, 0x8813, 0x000a, 0x7042, 0x0003, 0x8813, 0x0000, 0x15fc,
0x000b, 0xb013, 0x0009, 0xc4c0, 0x0000, 0x7000, 0x0001, 0xffa0,
- 0x0000, 0x2000, 0x000b, 0x93b8, 0x0008, 0x808c, 0x0000, 0x0001,
+ 0x0000, 0x2000, 0x0003, 0x93cd, 0x0008, 0x808c, 0x0000, 0x0001,
0x0007, 0x0000, 0x0007, 0x0000, 0x0000, 0x40d4, 0x000a, 0x4047,
0x0008, 0x808c, 0x0000, 0x0002, 0x0007, 0x0000, 0x000b, 0x0832,
0x0000, 0x4022, 0x0003, 0x0038, 0x0008, 0x4122, 0x0009, 0xeac0,
- 0x0008, 0xff00, 0x0009, 0xffe0, 0x0008, 0x0500, 0x000b, 0x0bdf,
- 0x0002, 0x4447, 0x0003, 0x8bdc, 0x0008, 0x0bfe, 0x0001, 0x11a0,
- 0x0003, 0x13be, 0x0001, 0x0ca0, 0x0003, 0x13be, 0x0001, 0x9180,
+ 0x0008, 0xff00, 0x0009, 0xffe0, 0x0008, 0x0500, 0x000b, 0x0bf4,
+ 0x0002, 0x4447, 0x0003, 0x8bf1, 0x0008, 0x0bfe, 0x0001, 0x11a0,
+ 0x000b, 0x13d3, 0x0001, 0x0ca0, 0x000b, 0x13d3, 0x0001, 0x9180,
0x0000, 0x0004, 0x0000, 0x8060, 0x0000, 0x0400, 0x0008, 0x7f62,
0x0000, 0x8066, 0x0008, 0x0009, 0x0003, 0xc046, 0x0008, 0x808c,
0x0008, 0x0000, 0x0008, 0x0060, 0x0008, 0x8062, 0x0000, 0x0004,
0x0000, 0x8066, 0x0000, 0x0411, 0x000b, 0xc04e, 0x0000, 0x03fe,
- 0x0001, 0x43e0, 0x000b, 0x8bbb, 0x0009, 0xc2c0, 0x0008, 0x00ff,
- 0x0001, 0x02e0, 0x000b, 0x8bbb, 0x0001, 0x9180, 0x0008, 0x0005,
+ 0x0001, 0x43e0, 0x0003, 0x8bd0, 0x0009, 0xc2c0, 0x0008, 0x00ff,
+ 0x0001, 0x02e0, 0x0003, 0x8bd0, 0x0001, 0x9180, 0x0008, 0x0005,
0x0000, 0x8060, 0x0000, 0x0400, 0x0008, 0x7f62, 0x0000, 0x8066,
- 0x0000, 0x0019, 0x0003, 0xc05d, 0x0002, 0x0240, 0x0003, 0x0bb8,
- 0x0008, 0x00fc, 0x000b, 0x33bb, 0x000a, 0x0244, 0x0003, 0x086f,
- 0x000c, 0x0205, 0x0001, 0x9180, 0x0000, 0x0007, 0x0008, 0x7f62,
+ 0x0000, 0x0019, 0x0003, 0xc05d, 0x0002, 0x0240, 0x000b, 0x0bcd,
+ 0x0008, 0x00fc, 0x0003, 0x33d0, 0x000a, 0x0244, 0x0003, 0x086f,
+ 0x0004, 0x021a, 0x0001, 0x9180, 0x0000, 0x0007, 0x0008, 0x7f62,
0x0000, 0x8060, 0x0000, 0x0400, 0x0002, 0x0234, 0x0008, 0x7f04,
0x0000, 0x8066, 0x0000, 0x040a, 0x0003, 0xc06e, 0x000a, 0x0248,
0x000b, 0x0879, 0x0001, 0x9180, 0x0008, 0x0006, 0x0008, 0x7f62,
@@ -7385,7 +7386,7 @@ unsigned short rseqipx_code01[] = {
0x0002, 0x3a44, 0x0003, 0x8813, 0x0008, 0x808c, 0x0000, 0x0002,
0x0008, 0x1760, 0x0008, 0x8062, 0x0008, 0x000f, 0x0000, 0x8066,
0x0008, 0x0011, 0x0003, 0xc085, 0x0008, 0x01fe, 0x0009, 0x42e0,
- 0x0003, 0x8bab, 0x0000, 0x00fe, 0x0001, 0x43e0, 0x0003, 0x8bab,
+ 0x000b, 0x8bc0, 0x0000, 0x00fe, 0x0001, 0x43e0, 0x000b, 0x8bc0,
0x0000, 0x1734, 0x0000, 0x1530, 0x0008, 0x1632, 0x0008, 0x0d2a,
0x0001, 0x9880, 0x0008, 0x0012, 0x0000, 0x8060, 0x0000, 0x0400,
0x0008, 0x7f62, 0x0000, 0x8066, 0x0008, 0x1e0a, 0x0003, 0xc097,
@@ -7401,291 +7402,297 @@ unsigned short rseqipx_code01[] = {
0x0000, 0x064a, 0x000a, 0x1948, 0x0003, 0x08c0, 0x0008, 0x0d4a,
0x0003, 0x58c0, 0x0008, 0x8054, 0x0000, 0x0001, 0x0000, 0x8074,
0x0008, 0x2020, 0x000f, 0x4000, 0x0002, 0x7043, 0x0003, 0x8816,
- 0x0002, 0x7040, 0x000b, 0x8934, 0x0000, 0x4820, 0x0008, 0x0bfe,
- 0x0009, 0x10a0, 0x000b, 0x112b, 0x0001, 0x0ca0, 0x000b, 0x112b,
+ 0x0002, 0x7040, 0x000b, 0x8949, 0x0000, 0x4820, 0x0008, 0x0bfe,
+ 0x0009, 0x10a0, 0x0003, 0x1140, 0x0001, 0x0ca0, 0x0003, 0x1140,
0x0000, 0x8060, 0x0000, 0x0400, 0x0009, 0x9080, 0x0000, 0x0008,
0x0008, 0x7f62, 0x0000, 0x8066, 0x0008, 0x0009, 0x000b, 0xc0d7,
- 0x0001, 0x80e0, 0x0008, 0x0003, 0x0003, 0x892b, 0x0000, 0x49b4,
- 0x0002, 0x4b4e, 0x0003, 0x893c, 0x0008, 0x808a, 0x0000, 0x0004,
- 0x0000, 0x18fe, 0x0001, 0x10e0, 0x0003, 0x88e5, 0x0002, 0x192f,
- 0x0008, 0x7f32, 0x0008, 0x15fe, 0x0001, 0x10e0, 0x0003, 0x88ea,
- 0x0002, 0x162f, 0x0008, 0x7f2c, 0x0000, 0x8060, 0x0000, 0x0400,
- 0x0009, 0x9080, 0x0000, 0x0007, 0x0008, 0x7f62, 0x0000, 0x8066,
- 0x0008, 0x0009, 0x0003, 0xc0f1, 0x000a, 0x004f, 0x0003, 0x8922,
- 0x000a, 0x0040, 0x000b, 0x090c, 0x0002, 0x004e, 0x000b, 0x090c,
- 0x0002, 0x0030, 0x0002, 0x7f2f, 0x0000, 0x7f00, 0x0000, 0x8066,
- 0x0008, 0x000a, 0x0003, 0xc0fd, 0x0008, 0x1010, 0x0004, 0x01ec,
- 0x000b, 0xb105, 0x0004, 0x0372, 0x0004, 0x01d6, 0x0003, 0x7816,
- 0x0003, 0x0013, 0x0000, 0x0806, 0x0008, 0x8010, 0x0000, 0x001f,
- 0x0004, 0x0372, 0x0000, 0x0310, 0x0004, 0x0372, 0x0003, 0x0103,
- 0x000a, 0x002f, 0x0000, 0x7f00, 0x0000, 0x8066, 0x0008, 0x000a,
- 0x000b, 0xc110, 0x000c, 0x01af, 0x000a, 0x0040, 0x0003, 0x0925,
- 0x0004, 0x021c, 0x0000, 0x8000, 0x0000, 0x0002, 0x0000, 0x8060,
- 0x0000, 0x0400, 0x0009, 0x9080, 0x0008, 0x0006, 0x0008, 0x7f62,
- 0x0000, 0x8066, 0x0008, 0x000a, 0x0003, 0xc11e, 0x0000, 0x8072,
- 0x0000, 0x4000, 0x0003, 0x0103, 0x0008, 0x8010, 0x0008, 0x001e,
- 0x0003, 0x0127, 0x0008, 0x8010, 0x0008, 0x001d, 0x0004, 0x0372,
- 0x0008, 0x1010, 0x0004, 0x0372, 0x0003, 0x0016, 0x0002, 0x4b4e,
- 0x0003, 0x0931, 0x0008, 0x808a, 0x0000, 0x0004, 0x000b, 0x6131,
- 0x000f, 0x8000, 0x0008, 0x808a, 0x0000, 0x0004, 0x0003, 0x0016,
- 0x0008, 0x808a, 0x0000, 0x0004, 0x0007, 0x0000, 0x0007, 0x0000,
- 0x0008, 0x80e0, 0x0008, 0x0202, 0x000b, 0x6134, 0x000b, 0x0014,
- 0x0000, 0x8060, 0x0000, 0x0400, 0x0009, 0x9080, 0x0008, 0x0011,
- 0x0008, 0x7f62, 0x0000, 0x8066, 0x0008, 0x0009, 0x000b, 0xc143,
- 0x000a, 0x004f, 0x0003, 0x89a0, 0x0000, 0x8060, 0x0000, 0x0400,
- 0x0009, 0x9080, 0x0008, 0x0005, 0x0008, 0x7f62, 0x0000, 0x8066,
- 0x0008, 0x0009, 0x0003, 0xc14d, 0x0008, 0x0060, 0x0008, 0x8062,
- 0x0000, 0x001f, 0x0000, 0x8066, 0x0000, 0x0209, 0x0003, 0xc153,
- 0x000a, 0x014b, 0x000b, 0x09a0, 0x0008, 0x8062, 0x0008, 0x000f,
- 0x0000, 0x8066, 0x0000, 0x0211, 0x0003, 0xc15a, 0x0008, 0x01fe,
- 0x0001, 0x02d0, 0x0003, 0x89a0, 0x000c, 0x01b8, 0x000b, 0x09a0,
- 0x0008, 0x03a0, 0x0008, 0x8004, 0x0000, 0x0002, 0x0000, 0x8006,
- 0x0000, 0x0043, 0x0008, 0x4908, 0x0008, 0x808a, 0x0000, 0x0004,
- 0x0000, 0x8060, 0x0000, 0x0400, 0x0009, 0x9080, 0x0008, 0x0000,
- 0x0008, 0x7f62, 0x0000, 0x8066, 0x0008, 0x041a, 0x0003, 0xc16f,
- 0x0003, 0xe170, 0x0008, 0x4908, 0x0008, 0x480a, 0x0008, 0x808a,
- 0x0000, 0x0004, 0x0008, 0x0060, 0x0008, 0x8062, 0x0008, 0x002b,
- 0x0000, 0x8066, 0x0000, 0x0411, 0x000b, 0xc17a, 0x0008, 0x04fe,
- 0x0009, 0x02a0, 0x0003, 0x9181, 0x0002, 0x0500, 0x0003, 0x099d,
- 0x0003, 0x0182, 0x0000, 0x05fe, 0x0001, 0x03a0, 0x0003, 0x119d,
- 0x0000, 0x0d0c, 0x0008, 0x0d0e, 0x0008, 0x0d10, 0x0000, 0x0d12,
- 0x0008, 0x0060, 0x0008, 0x8062, 0x0000, 0x000d, 0x0000, 0x8066,
- 0x0008, 0x0832, 0x0003, 0xc18d, 0x0000, 0x800a, 0x0000, 0x8005,
- 0x0000, 0x8060, 0x0000, 0x0400, 0x0009, 0x9080, 0x0008, 0x0011,
- 0x0008, 0x7f62, 0x0000, 0x8066, 0x0008, 0x0a12, 0x000b, 0xc197,
- 0x0008, 0x5006, 0x0008, 0x100e, 0x000c, 0x01c3, 0x0003, 0x7816,
- 0x0003, 0x0013, 0x0008, 0x0208, 0x0008, 0x030a, 0x0003, 0x0184,
- 0x000c, 0x01af, 0x0008, 0x808a, 0x0000, 0x0004, 0x0008, 0x8010,
- 0x0008, 0x0021, 0x0004, 0x0372, 0x0008, 0x1010, 0x0004, 0x0372,
- 0x0000, 0x4810, 0x0004, 0x0372, 0x0008, 0x4910, 0x0004, 0x0372,
- 0x0008, 0x808a, 0x0000, 0x0004, 0x0003, 0x0016, 0x0000, 0x8060,
- 0x0000, 0x0400, 0x0009, 0x9080, 0x0000, 0x0002, 0x0008, 0x7f62,
- 0x0000, 0x8066, 0x0008, 0xb40a, 0x000b, 0xc1b6, 0x000f, 0x4000,
- 0x0000, 0x8060, 0x0000, 0x0400, 0x0000, 0x0a62, 0x0000, 0x8066,
- 0x0000, 0x0411, 0x0003, 0xc1bd, 0x0002, 0x0210, 0x0001, 0xffc0,
- 0x0000, 0x0007, 0x0009, 0x03e0, 0x000f, 0x4000, 0x0000, 0x8060,
- 0x0000, 0x0400, 0x0001, 0x8380, 0x0000, 0x0002, 0x0009, 0x0a80,
- 0x0008, 0x7f62, 0x0000, 0x8066, 0x0000, 0x0e0a, 0x000b, 0xc1cb,
- 0x0002, 0x0300, 0x0001, 0xffc0, 0x0000, 0x0007, 0x0000, 0x7f06,
- 0x0002, 0x0a00, 0x0008, 0x7f62, 0x0000, 0x8066, 0x0008, 0x060a,
- 0x0003, 0xc1d4, 0x000f, 0x4000, 0x0000, 0x0da0, 0x0008, 0x0da2,
- 0x0008, 0x0da4, 0x0009, 0x8880, 0x0000, 0x0001, 0x0008, 0x7f62,
- 0x0000, 0x8060, 0x0000, 0x0400, 0x0000, 0x8066, 0x0008, 0xa012,
- 0x0000, 0x0da6, 0x0008, 0x0da8, 0x0000, 0x0daa, 0x0000, 0x0dac,
- 0x0003, 0xc1e4, 0x0009, 0x8880, 0x0008, 0x0009, 0x0008, 0x7f62,
- 0x0000, 0x8066, 0x0008, 0xa03a, 0x000b, 0xc1ea, 0x000f, 0x4000,
- 0x0009, 0x8880, 0x0008, 0x0005, 0x0000, 0x8060, 0x0000, 0x0400,
- 0x0008, 0x7f62, 0x0000, 0x8066, 0x0008, 0x0009, 0x0003, 0xc1f3,
- 0x0008, 0x0060, 0x0008, 0x8062, 0x0000, 0x000d, 0x0000, 0x8066,
- 0x0008, 0x0021, 0x0003, 0xc1f9, 0x0000, 0x00fe, 0x0001, 0x01d0,
- 0x000b, 0x8a02, 0x0008, 0x02fe, 0x0009, 0x03d0, 0x0003, 0x0a02,
- 0x0000, 0x0d06, 0x000f, 0x4000, 0x0000, 0x8006, 0x0000, 0x0001,
- 0x000f, 0x4000, 0x0008, 0x0060, 0x0008, 0x8062, 0x0008, 0x002b,
- 0x0000, 0x8066, 0x0008, 0xa041, 0x0003, 0xc20a, 0x0002, 0x0243,
- 0x0003, 0x8a11, 0x0000, 0x54ac, 0x0000, 0x55ae, 0x0008, 0x0da8,
- 0x0000, 0x0daa, 0x0000, 0x50b0, 0x0000, 0x51b2, 0x0000, 0x0db4,
- 0x0008, 0x0db6, 0x0008, 0x0060, 0x0008, 0x8062, 0x0000, 0x0007,
- 0x0000, 0x8066, 0x0008, 0xa452, 0x000b, 0xc21a, 0x000f, 0x4000,
- 0x000a, 0x3945, 0x000b, 0x8a26, 0x0000, 0x8072, 0x0008, 0x4040,
- 0x0007, 0x0000, 0x000a, 0x3945, 0x0003, 0x8a24, 0x000f, 0x4000,
- 0x0000, 0x8072, 0x0000, 0x4000, 0x0007, 0x0000, 0x0007, 0x0000,
- 0x0007, 0x0000, 0x000a, 0x3945, 0x000b, 0x0a1e, 0x000b, 0x0226,
- 0x000a, 0x3a40, 0x0003, 0x8819, 0x0001, 0xabd0, 0x0008, 0x0000,
- 0x0000, 0x7f24, 0x0003, 0x5a31, 0x0008, 0x8054, 0x0000, 0x0002,
- 0x0002, 0x1242, 0x000b, 0x0a77, 0x000a, 0x3a45, 0x000b, 0x0a66,
- 0x000a, 0x1e10, 0x0000, 0x7f3c, 0x000b, 0x0a63, 0x0002, 0x1d00,
- 0x0000, 0x7f3a, 0x0000, 0x0d60, 0x0008, 0x7f62, 0x0000, 0x8066,
- 0x0008, 0x0009, 0x0003, 0xc241, 0x0008, 0x00fc, 0x000b, 0xb260,
- 0x0000, 0x1c60, 0x0008, 0x8062, 0x0000, 0x0001, 0x0000, 0x8066,
- 0x0008, 0x0009, 0x000b, 0xc249, 0x0008, 0x00fc, 0x0003, 0x3394,
- 0x0000, 0x0038, 0x0008, 0x0060, 0x0008, 0x8062, 0x0000, 0x0019,
- 0x0000, 0x8066, 0x0008, 0x0009, 0x000b, 0xc252, 0x0009, 0x80c0,
- 0x0008, 0x00ff, 0x0008, 0x7f3e, 0x0000, 0x0d60, 0x0008, 0x0efe,
- 0x0001, 0x1f80, 0x0008, 0x7f62, 0x0000, 0x8066, 0x0008, 0x0009,
- 0x0003, 0xc25c, 0x0008, 0x003a, 0x0000, 0x1dfe, 0x000b, 0x023d,
- 0x0008, 0x0036, 0x0004, 0x00aa, 0x0003, 0x0277, 0x0000, 0x8074,
- 0x0000, 0x2000, 0x0003, 0x0277, 0x0002, 0x3a44, 0x000b, 0x0bc1,
- 0x0000, 0x8074, 0x0000, 0x1000, 0x0001, 0xadd0, 0x0008, 0x0000,
- 0x0008, 0x7f0e, 0x000b, 0xb391, 0x0001, 0xa7d0, 0x0008, 0x0000,
- 0x0000, 0x7f00, 0x0009, 0xa6d0, 0x0008, 0x0000, 0x0009, 0x00d0,
- 0x0003, 0x8a87, 0x0000, 0x8074, 0x0008, 0x4040, 0x000b, 0x5a77,
- 0x000b, 0x522c, 0x000a, 0x3a46, 0x0003, 0x8a87, 0x0002, 0x3a47,
- 0x000b, 0x0a82, 0x0008, 0x8054, 0x0000, 0x0004, 0x0000, 0x8074,
- 0x0000, 0x8000, 0x0003, 0x02e7, 0x0009, 0x92c0, 0x0000, 0x0fc8,
- 0x000b, 0x0813, 0x000a, 0x1246, 0x000b, 0x8b8b, 0x0000, 0x1a60,
- 0x0008, 0x8062, 0x0000, 0x0002, 0x0000, 0x8066, 0x0000, 0x367a,
- 0x000b, 0xc28c, 0x0009, 0x92c0, 0x0008, 0x0780, 0x000b, 0x8ba5,
- 0x0002, 0x124b, 0x000b, 0x0a95, 0x0002, 0x2e4d, 0x0002, 0x2e4d,
- 0x000b, 0x0b91, 0x000a, 0x3a46, 0x0003, 0x8aa5, 0x0003, 0x5a97,
- 0x0008, 0x8054, 0x0000, 0x0004, 0x000a, 0x1243, 0x0003, 0x0ae5,
- 0x0008, 0x8010, 0x0000, 0x000d, 0x0004, 0x0372, 0x000a, 0x1948,
- 0x0003, 0x0aa2, 0x000c, 0x0367, 0x0000, 0x1810, 0x0004, 0x0372,
- 0x000b, 0x02e5, 0x000a, 0x1948, 0x000b, 0x0aa9, 0x000a, 0x1243,
- 0x000b, 0x0b94, 0x000a, 0x194d, 0x0003, 0x0aad, 0x000a, 0x1243,
- 0x000b, 0x0b9b, 0x0003, 0x5aad, 0x0008, 0x8054, 0x0000, 0x0004,
- 0x000a, 0x192e, 0x0008, 0x7f32, 0x000a, 0x1947, 0x0003, 0x0adf,
- 0x0002, 0x194f, 0x000b, 0x0abd, 0x000c, 0x0367, 0x0000, 0x1810,
- 0x0004, 0x01ec, 0x000b, 0xb2d8, 0x0004, 0x0372, 0x0004, 0x01d6,
- 0x000b, 0x02e5, 0x0000, 0x1a60, 0x0008, 0x8062, 0x0000, 0x001f,
- 0x0000, 0x8066, 0x0008, 0x0009, 0x000b, 0xc2c2, 0x000a, 0x004c,
- 0x000b, 0x8adf, 0x0000, 0x8060, 0x0000, 0x0400, 0x0001, 0x9880,
- 0x0000, 0x0007, 0x0008, 0x7f62, 0x0000, 0x8066, 0x0000, 0x320a,
- 0x0003, 0xc2cc, 0x0000, 0x8060, 0x0000, 0x0400, 0x0001, 0x9880,
- 0x0008, 0x0012, 0x0008, 0x7f62, 0x0000, 0x8066, 0x0008, 0x1e0a,
- 0x0003, 0xc2d4, 0x0000, 0x1826, 0x0000, 0x1928, 0x000b, 0x02e5,
- 0x0000, 0x0806, 0x0008, 0x8010, 0x0000, 0x001f, 0x0004, 0x0372,
- 0x0000, 0x0310, 0x0004, 0x0372, 0x000b, 0x02e5, 0x000c, 0x0367,
- 0x0008, 0x8010, 0x0000, 0x0001, 0x0004, 0x0372, 0x0000, 0x1810,
- 0x0004, 0x0372, 0x0000, 0x8074, 0x0008, 0xf000, 0x0000, 0x0d30,
- 0x0002, 0x3a42, 0x0003, 0x8aed, 0x0000, 0x15fc, 0x0003, 0xb07e,
- 0x0003, 0x0013, 0x0000, 0x8074, 0x0000, 0x0501, 0x0008, 0x8010,
- 0x0008, 0x000c, 0x0004, 0x0372, 0x0003, 0x0013, 0x0009, 0xbbe0,
- 0x0008, 0x0030, 0x000b, 0x8b09, 0x0000, 0x18fe, 0x0009, 0x3ce0,
- 0x0003, 0x0b06, 0x0008, 0x15fe, 0x0009, 0x3ce0, 0x0003, 0x0b06,
- 0x0008, 0x13fe, 0x0009, 0x3ce0, 0x0003, 0x8b02, 0x0004, 0x0360,
- 0x0008, 0x0d26, 0x000b, 0x0303, 0x000c, 0x0362, 0x0008, 0x8076,
- 0x0000, 0x0040, 0x0003, 0x035d, 0x0008, 0x8076, 0x0008, 0x0041,
- 0x0003, 0x035d, 0x0009, 0xbbe0, 0x0000, 0x0032, 0x0003, 0x8b0e,
- 0x0008, 0x3c1e, 0x0003, 0x035d, 0x0009, 0xbbe0, 0x0000, 0x003b,
- 0x0003, 0x8b13, 0x0000, 0x3cdc, 0x0003, 0x035d, 0x0009, 0xbbe0,
- 0x0008, 0x0035, 0x0003, 0x8b19, 0x0000, 0x8072, 0x0000, 0x8000,
- 0x000b, 0x04ce, 0x0009, 0xbbe0, 0x0008, 0x0036, 0x000b, 0x0bf1,
- 0x0009, 0xbbe0, 0x0000, 0x0037, 0x0003, 0x8b3e, 0x0000, 0x18fe,
- 0x0009, 0x3ce0, 0x000b, 0x8b06, 0x0008, 0x8076, 0x0000, 0x0040,
- 0x0000, 0x1a60, 0x0008, 0x8062, 0x0000, 0x000d, 0x0009, 0xa6d0,
- 0x0008, 0x0000, 0x0008, 0x7f04, 0x0001, 0xa7d0, 0x0008, 0x0000,
- 0x0000, 0x7f06, 0x0001, 0xa8d0, 0x0008, 0x0000, 0x0008, 0x7f08,
- 0x0009, 0xa9d0, 0x0008, 0x0000, 0x0000, 0x7f0a, 0x0000, 0x8066,
- 0x0000, 0x0422, 0x000b, 0xc335, 0x000c, 0x0367, 0x0008, 0x8054,
- 0x0000, 0x0004, 0x0000, 0x8074, 0x0008, 0xf000, 0x0000, 0x8072,
- 0x0000, 0x8000, 0x0003, 0x02e7, 0x0009, 0xbbe0, 0x0000, 0x0038,
- 0x000b, 0x8b50, 0x0000, 0x18fe, 0x0009, 0x3ce0, 0x0003, 0x0b4d,
- 0x0008, 0x15fe, 0x0009, 0x3ce0, 0x0003, 0x8afc, 0x000c, 0x0362,
- 0x0008, 0x8076, 0x0000, 0x0040, 0x0000, 0x8072, 0x0000, 0x8000,
- 0x000b, 0x03b8, 0x0008, 0x8076, 0x0008, 0x0042, 0x0003, 0x035d,
- 0x0009, 0xbbe0, 0x0000, 0x0016, 0x0003, 0x8b5d, 0x0000, 0x8074,
- 0x0008, 0x0808, 0x0002, 0x3a44, 0x000b, 0x8818, 0x0000, 0x8074,
- 0x0000, 0x0800, 0x0000, 0x8072, 0x0000, 0x8000, 0x000f, 0x8000,
- 0x0003, 0x0013, 0x0000, 0x8072, 0x0000, 0x8000, 0x0003, 0x0013,
- 0x0002, 0x1430, 0x000b, 0x0363, 0x000a, 0x3d30, 0x0000, 0x7f00,
- 0x0001, 0xbc80, 0x0000, 0x0007, 0x0003, 0x036b, 0x000a, 0x1930,
- 0x0000, 0x7f00, 0x0001, 0x9880, 0x0000, 0x0007, 0x0000, 0x8060,
- 0x0000, 0x0400, 0x0008, 0x7f62, 0x0000, 0x8066, 0x0008, 0x000a,
- 0x0003, 0xc370, 0x000f, 0x4000, 0x000b, 0x2375, 0x0008, 0x0870,
- 0x000f, 0x4000, 0x0002, 0x7040, 0x0003, 0x0b72, 0x000b, 0xe37f,
- 0x0008, 0x808a, 0x0000, 0x0004, 0x0007, 0x0000, 0x0007, 0x0000,
- 0x0008, 0x80e0, 0x0008, 0x0202, 0x000b, 0x6378, 0x0008, 0x80e0,
- 0x0000, 0x0100, 0x000b, 0x0372, 0x0009, 0xbac0, 0x0008, 0x0090,
- 0x0003, 0x0b88, 0x0000, 0x8074, 0x0000, 0x0706, 0x0003, 0x038a,
- 0x0000, 0x8074, 0x0000, 0x0703, 0x000f, 0x4000, 0x0008, 0x8010,
- 0x0000, 0x0023, 0x000b, 0x03c6, 0x0008, 0x8010, 0x0000, 0x0008,
- 0x000b, 0x03c6, 0x0008, 0x8010, 0x0008, 0x0022, 0x000b, 0x03c6,
- 0x000c, 0x0367, 0x0008, 0x8010, 0x0000, 0x0007, 0x0004, 0x0372,
- 0x0000, 0x1810, 0x0004, 0x0372, 0x0003, 0x03d0, 0x000c, 0x0367,
- 0x0008, 0x8010, 0x0008, 0x001b, 0x0004, 0x0372, 0x0000, 0x1810,
- 0x0004, 0x0372, 0x0000, 0x8074, 0x0000, 0xf080, 0x0000, 0x0d30,
- 0x0003, 0x0013, 0x0008, 0x8010, 0x0008, 0x0009, 0x000b, 0x03c6,
- 0x0008, 0x8010, 0x0008, 0x0005, 0x000b, 0x03c6, 0x000a, 0x1648,
- 0x0003, 0x888c, 0x0008, 0x808c, 0x0000, 0x0001, 0x0007, 0x0000,
- 0x0008, 0x8010, 0x0000, 0x0004, 0x000a, 0x4143, 0x000b, 0x088c,
- 0x0002, 0x3a44, 0x0003, 0x8813, 0x0008, 0x0d2a, 0x000b, 0x03c6,
- 0x0008, 0x8010, 0x0008, 0x0003, 0x0003, 0x03c8, 0x0008, 0x8010,
- 0x0000, 0x000b, 0x0003, 0x03c8, 0x0008, 0x8010, 0x0000, 0x0002,
- 0x0003, 0x03c8, 0x0002, 0x3a47, 0x0003, 0x8a77, 0x0008, 0x8010,
- 0x0008, 0x0006, 0x0003, 0x03c8, 0x0000, 0x8074, 0x0008, 0xf000,
- 0x0004, 0x0372, 0x0004, 0x0382, 0x000a, 0x3a40, 0x000b, 0x0813,
- 0x0008, 0x8010, 0x0008, 0x000c, 0x0004, 0x0372, 0x0003, 0x0013,
- 0x0000, 0x8074, 0x0000, 0xf080, 0x0000, 0x0d30, 0x0002, 0x2e4d,
- 0x0002, 0x2e4d, 0x000b, 0x0bd9, 0x0008, 0x8054, 0x0000, 0x0019,
- 0x0003, 0x0013, 0x0008, 0x8054, 0x0008, 0x0009, 0x0003, 0x0013,
- 0x0002, 0x3a44, 0x0003, 0x8813, 0x000b, 0x03bb, 0x0008, 0x808c,
- 0x0008, 0x0000, 0x0002, 0x4447, 0x000b, 0x0c05, 0x0001, 0xc0c0,
- 0x0008, 0x00ff, 0x0009, 0xffe0, 0x0008, 0x00ff, 0x0003, 0x8bdc,
- 0x0001, 0xc1e0, 0x0008, 0xffff, 0x0003, 0x8bdc, 0x0008, 0x8010,
- 0x0000, 0x0013, 0x0004, 0x0372, 0x0000, 0x8074, 0x0008, 0x0202,
- 0x0003, 0x0013, 0x000a, 0x3a40, 0x000b, 0x8c02, 0x0000, 0x8074,
- 0x0000, 0x0200, 0x0000, 0x3d00, 0x0000, 0x3cfe, 0x0000, 0x8072,
- 0x0000, 0x8000, 0x0001, 0x43e0, 0x0003, 0x8c00, 0x0000, 0x42fe,
- 0x0001, 0xffc0, 0x0008, 0x00ff, 0x0009, 0x00e0, 0x000b, 0x0bdc,
- 0x0008, 0x0d08, 0x0003, 0x0455, 0x0000, 0x8072, 0x0000, 0x8000,
- 0x0003, 0x0013, 0x000c, 0x04d7, 0x0008, 0x808c, 0x0000, 0x0001,
- 0x0000, 0x04fc, 0x000b, 0x34ba, 0x0000, 0x0460, 0x0008, 0x8062,
- 0x0000, 0x0001, 0x0000, 0x8066, 0x0008, 0x0009, 0x0003, 0xc40f,
- 0x0000, 0x0004, 0x0009, 0x80c0, 0x0008, 0x00ff, 0x0000, 0x7f00,
- 0x0001, 0x80e0, 0x0000, 0x0004, 0x0003, 0x0c29, 0x0001, 0x80e0,
- 0x0008, 0x0005, 0x0003, 0x0c29, 0x0001, 0x80e0, 0x0008, 0x0006,
- 0x0003, 0x0c29, 0x0001, 0x82c0, 0x0008, 0xff00, 0x0008, 0x7f04,
- 0x0009, 0x82e0, 0x0008, 0x0600, 0x0003, 0x0c29, 0x0009, 0x82e0,
- 0x0008, 0x0500, 0x0003, 0x0c29, 0x0009, 0x82e0, 0x0000, 0x0400,
- 0x000b, 0x8cba, 0x0009, 0xc4c0, 0x0000, 0x7000, 0x0009, 0xffe0,
- 0x0000, 0x1000, 0x000b, 0x0c55, 0x0004, 0x04c8, 0x0002, 0x3941,
- 0x0003, 0x0c34, 0x0000, 0x8072, 0x0000, 0x0400, 0x0003, 0x0013,
- 0x0000, 0x0460, 0x0008, 0x80fe, 0x0008, 0x002b, 0x0008, 0x7f62,
- 0x0000, 0x8066, 0x0008, 0x2209, 0x0003, 0xc43a, 0x0008, 0x11fc,
- 0x0003, 0x3450, 0x0001, 0x9180, 0x0000, 0x0002, 0x0000, 0x8060,
- 0x0000, 0x0400, 0x0008, 0x7f62, 0x0000, 0x8066, 0x0008, 0x0609,
- 0x0003, 0xc444, 0x0000, 0x42fe, 0x0001, 0xffc0, 0x0008, 0xff00,
- 0x0009, 0x03e0, 0x0003, 0x8c4d, 0x0000, 0x8072, 0x0000, 0x0400,
- 0x000b, 0x0056, 0x0001, 0x9180, 0x0008, 0x0003, 0x000b, 0x0437,
- 0x0000, 0x8072, 0x0000, 0x0400, 0x0008, 0x8010, 0x0000, 0x0010,
- 0x000b, 0x04ad, 0x0004, 0x04c8, 0x0002, 0x3941, 0x0003, 0x0c5b,
- 0x0000, 0x8072, 0x0000, 0x0400, 0x0003, 0x0013, 0x0004, 0x0492,
- 0x0008, 0x11fc, 0x000b, 0xb463, 0x0000, 0x8072, 0x0000, 0x0400,
- 0x0008, 0x8010, 0x0000, 0x000e, 0x000b, 0x04ad, 0x0000, 0x8060,
- 0x0000, 0x0400, 0x0000, 0x04fc, 0x000b, 0xb478, 0x0008, 0x808c,
- 0x0008, 0x0000, 0x0001, 0x9180, 0x0008, 0x0005, 0x0008, 0x7f62,
- 0x0000, 0x8066, 0x0008, 0x0009, 0x000b, 0xc46e, 0x0008, 0x0060,
- 0x0008, 0x8062, 0x0008, 0x001b, 0x0008, 0x4304, 0x0008, 0x4206,
- 0x0000, 0x8066, 0x0000, 0x0412, 0x000b, 0xc476, 0x000b, 0x048f,
- 0x0008, 0x808c, 0x0000, 0x0001, 0x0000, 0x0460, 0x0008, 0x8062,
- 0x0008, 0x002b, 0x0000, 0x8066, 0x0008, 0x0609, 0x000b, 0xc47f,
- 0x0000, 0x8066, 0x0008, 0x220a, 0x0003, 0xc482, 0x0000, 0x42fe,
- 0x0001, 0xffc0, 0x0008, 0xff00, 0x0008, 0x7f04, 0x0000, 0x8060,
- 0x0000, 0x0400, 0x0001, 0x9180, 0x0000, 0x0002, 0x0008, 0x7f62,
- 0x0000, 0x8066, 0x0008, 0x041a, 0x0003, 0xc48e, 0x0000, 0x8072,
- 0x0000, 0x0400, 0x000b, 0x0056, 0x0000, 0x8060, 0x0000, 0x0400,
- 0x0008, 0x6b62, 0x0000, 0x8066, 0x0000, 0x0411, 0x000b, 0xc497,
- 0x0008, 0x02fe, 0x0009, 0x03e0, 0x000b, 0x8c9d, 0x0000, 0x0d22,
- 0x000f, 0x4000, 0x0009, 0x8280, 0x0000, 0x0002, 0x0001, 0x6b80,
- 0x0008, 0x7f62, 0x0000, 0x8066, 0x0008, 0x2209, 0x0003, 0xc4a3,
- 0x000a, 0x0200, 0x0001, 0xffc0, 0x0000, 0x0007, 0x0000, 0x7f06,
- 0x0008, 0x6b62, 0x0000, 0x8066, 0x0008, 0x060a, 0x000b, 0xc4ab,
- 0x000f, 0x4000, 0x0002, 0x3a44, 0x0003, 0x8813, 0x000a, 0x2f44,
- 0x000a, 0x2f44, 0x000b, 0x8bbb, 0x0008, 0x808a, 0x0008, 0x0003,
- 0x0000, 0x8074, 0x0000, 0xf080, 0x0003, 0x5cb6, 0x0008, 0x8054,
- 0x0000, 0x0019, 0x0003, 0x0013, 0x0002, 0x3a44, 0x0003, 0x8813,
- 0x0008, 0x808c, 0x0008, 0x0000, 0x0008, 0x8010, 0x0008, 0x0011,
- 0x0004, 0x0372, 0x0000, 0x42fe, 0x0001, 0xffc0, 0x0008, 0x00ff,
- 0x0008, 0x7f10, 0x0004, 0x0372, 0x0008, 0x4310, 0x0003, 0x03c8,
- 0x0002, 0x3941, 0x0003, 0x0ccb, 0x000f, 0x4000, 0x0000, 0x8072,
- 0x0008, 0x0404, 0x000f, 0x4000, 0x0008, 0x8010, 0x0008, 0x0012,
- 0x0004, 0x0372, 0x0004, 0x0492, 0x0000, 0x1110, 0x0004, 0x0372,
- 0x0008, 0x11fc, 0x000b, 0xb4d1, 0x0003, 0x0013, 0x0009, 0xc2c0,
- 0x0008, 0x00ff, 0x0000, 0x7f00, 0x0001, 0xc3c0, 0x0008, 0xff00,
- 0x0009, 0x00d0, 0x000b, 0x0cfc, 0x0000, 0x0d0a, 0x0001, 0x8580,
- 0x0000, 0x1000, 0x0008, 0x7f62, 0x0000, 0x8060, 0x0000, 0x0400,
- 0x0000, 0x8066, 0x0000, 0x0809, 0x000b, 0xc4e6, 0x0000, 0x04fc,
- 0x0003, 0x34f5, 0x0000, 0x0460, 0x0008, 0x8062, 0x0000, 0x0004,
- 0x0000, 0x8066, 0x0000, 0x0211, 0x0003, 0xc4ee, 0x0008, 0x01fe,
- 0x0009, 0x00e0, 0x0003, 0x8cf5, 0x0008, 0x02fe, 0x0001, 0x43e0,
- 0x0003, 0x0cfb, 0x0002, 0x0500, 0x0000, 0x7f0a, 0x0009, 0xffe0,
- 0x0000, 0x0800, 0x000b, 0x8cdf, 0x0008, 0x0d08, 0x000f, 0x4000,
- 0x0008, 0x43fe, 0x0001, 0x3e80, 0x0000, 0x0d60, 0x0008, 0x7f62,
- 0x0000, 0x8066, 0x0000, 0x0809, 0x0003, 0xc502, 0x0000, 0x8060,
- 0x0000, 0x0400, 0x0001, 0x84c0, 0x0008, 0xff00, 0x0002, 0x7f70,
- 0x0009, 0xff80, 0x0000, 0x1000, 0x0008, 0x7f62, 0x0000, 0x8066,
- 0x0000, 0x0809, 0x0003, 0xc50d, 0x000f, 0x4000, 0xe5cd, 0x01ac
+ 0x0001, 0x80e0, 0x0008, 0x0003, 0x000b, 0x8940, 0x0000, 0x8060,
+ 0x0000, 0x0400, 0x0009, 0x9080, 0x0000, 0x0004, 0x0008, 0x7f62,
+ 0x0000, 0x8066, 0x0008, 0x0009, 0x000b, 0xc0e2, 0x0008, 0x0060,
+ 0x0008, 0x8062, 0x0000, 0x0004, 0x0000, 0x8066, 0x0000, 0x0411,
+ 0x000b, 0xc0e8, 0x0008, 0x4afe, 0x0009, 0x03e0, 0x000b, 0x8940,
+ 0x0009, 0xcbc0, 0x0008, 0x00ff, 0x0001, 0x02e0, 0x000b, 0x8940,
+ 0x0000, 0x49b4, 0x0002, 0x4b4e, 0x000b, 0x8951, 0x0008, 0x808a,
+ 0x0000, 0x0004, 0x0000, 0x18fe, 0x0001, 0x10e0, 0x000b, 0x88fa,
+ 0x0002, 0x192f, 0x0008, 0x7f32, 0x0008, 0x15fe, 0x0001, 0x10e0,
+ 0x000b, 0x88ff, 0x0002, 0x162f, 0x0008, 0x7f2c, 0x0000, 0x8060,
+ 0x0000, 0x0400, 0x0009, 0x9080, 0x0000, 0x0007, 0x0008, 0x7f62,
+ 0x0000, 0x8066, 0x0008, 0x0009, 0x0003, 0xc106, 0x000a, 0x004f,
+ 0x000b, 0x8937, 0x000a, 0x0040, 0x000b, 0x0921, 0x0002, 0x004e,
+ 0x000b, 0x0921, 0x0002, 0x0030, 0x0002, 0x7f2f, 0x0000, 0x7f00,
+ 0x0000, 0x8066, 0x0008, 0x000a, 0x0003, 0xc112, 0x0008, 0x1010,
+ 0x0004, 0x0201, 0x0003, 0xb11a, 0x0004, 0x0387, 0x000c, 0x01eb,
+ 0x0003, 0x7816, 0x0003, 0x0013, 0x0000, 0x0806, 0x0008, 0x8010,
+ 0x0000, 0x001f, 0x0004, 0x0387, 0x0000, 0x0310, 0x0004, 0x0387,
+ 0x0003, 0x0118, 0x000a, 0x002f, 0x0000, 0x7f00, 0x0000, 0x8066,
+ 0x0008, 0x000a, 0x000b, 0xc125, 0x0004, 0x01c4, 0x000a, 0x0040,
+ 0x000b, 0x093a, 0x0004, 0x0231, 0x0000, 0x8000, 0x0000, 0x0002,
+ 0x0000, 0x8060, 0x0000, 0x0400, 0x0009, 0x9080, 0x0008, 0x0006,
+ 0x0008, 0x7f62, 0x0000, 0x8066, 0x0008, 0x000a, 0x0003, 0xc133,
+ 0x0000, 0x8072, 0x0000, 0x4000, 0x0003, 0x0118, 0x0008, 0x8010,
+ 0x0008, 0x001e, 0x0003, 0x013c, 0x0008, 0x8010, 0x0008, 0x001d,
+ 0x0004, 0x0387, 0x0008, 0x1010, 0x0004, 0x0387, 0x0003, 0x0016,
+ 0x0002, 0x4b4e, 0x0003, 0x0946, 0x0008, 0x808a, 0x0000, 0x0004,
+ 0x000b, 0x6146, 0x000f, 0x8000, 0x0008, 0x808a, 0x0000, 0x0004,
+ 0x0003, 0x0016, 0x0008, 0x808a, 0x0000, 0x0004, 0x0007, 0x0000,
+ 0x0007, 0x0000, 0x0008, 0x80e0, 0x0008, 0x0202, 0x000b, 0x6149,
+ 0x000b, 0x0014, 0x0000, 0x8060, 0x0000, 0x0400, 0x0009, 0x9080,
+ 0x0008, 0x0011, 0x0008, 0x7f62, 0x0000, 0x8066, 0x0008, 0x0009,
+ 0x000b, 0xc158, 0x000a, 0x004f, 0x000b, 0x89b5, 0x0000, 0x8060,
+ 0x0000, 0x0400, 0x0009, 0x9080, 0x0008, 0x0005, 0x0008, 0x7f62,
+ 0x0000, 0x8066, 0x0008, 0x0009, 0x000b, 0xc162, 0x0008, 0x0060,
+ 0x0008, 0x8062, 0x0000, 0x001f, 0x0000, 0x8066, 0x0000, 0x0209,
+ 0x000b, 0xc168, 0x000a, 0x014b, 0x0003, 0x09b5, 0x0008, 0x8062,
+ 0x0008, 0x000f, 0x0000, 0x8066, 0x0000, 0x0211, 0x0003, 0xc16f,
+ 0x0008, 0x01fe, 0x0001, 0x02d0, 0x000b, 0x89b5, 0x0004, 0x01cd,
+ 0x0003, 0x09b5, 0x0008, 0x03a0, 0x0008, 0x8004, 0x0000, 0x0002,
+ 0x0000, 0x8006, 0x0000, 0x0043, 0x0008, 0x4908, 0x0008, 0x808a,
+ 0x0000, 0x0004, 0x0000, 0x8060, 0x0000, 0x0400, 0x0009, 0x9080,
+ 0x0008, 0x0000, 0x0008, 0x7f62, 0x0000, 0x8066, 0x0008, 0x041a,
+ 0x0003, 0xc184, 0x0003, 0xe185, 0x0008, 0x4908, 0x0008, 0x480a,
+ 0x0008, 0x808a, 0x0000, 0x0004, 0x0008, 0x0060, 0x0008, 0x8062,
+ 0x0008, 0x002b, 0x0000, 0x8066, 0x0000, 0x0411, 0x000b, 0xc18f,
+ 0x0008, 0x04fe, 0x0009, 0x02a0, 0x0003, 0x9196, 0x0002, 0x0500,
+ 0x000b, 0x09b2, 0x000b, 0x0197, 0x0000, 0x05fe, 0x0001, 0x03a0,
+ 0x000b, 0x11b2, 0x0000, 0x0d0c, 0x0008, 0x0d0e, 0x0008, 0x0d10,
+ 0x0000, 0x0d12, 0x0008, 0x0060, 0x0008, 0x8062, 0x0000, 0x000d,
+ 0x0000, 0x8066, 0x0008, 0x0832, 0x000b, 0xc1a2, 0x0000, 0x800a,
+ 0x0000, 0x8005, 0x0000, 0x8060, 0x0000, 0x0400, 0x0009, 0x9080,
+ 0x0008, 0x0011, 0x0008, 0x7f62, 0x0000, 0x8066, 0x0008, 0x0a12,
+ 0x0003, 0xc1ac, 0x0008, 0x5006, 0x0008, 0x100e, 0x000c, 0x01d8,
+ 0x0003, 0x7816, 0x0003, 0x0013, 0x0008, 0x0208, 0x0008, 0x030a,
+ 0x0003, 0x0199, 0x0004, 0x01c4, 0x0008, 0x808a, 0x0000, 0x0004,
+ 0x0008, 0x8010, 0x0008, 0x0021, 0x0004, 0x0387, 0x0008, 0x1010,
+ 0x0004, 0x0387, 0x0000, 0x4810, 0x0004, 0x0387, 0x0008, 0x4910,
+ 0x0004, 0x0387, 0x0008, 0x808a, 0x0000, 0x0004, 0x0003, 0x0016,
+ 0x0000, 0x8060, 0x0000, 0x0400, 0x0009, 0x9080, 0x0000, 0x0002,
+ 0x0008, 0x7f62, 0x0000, 0x8066, 0x0008, 0xb40a, 0x000b, 0xc1cb,
+ 0x000f, 0x4000, 0x0000, 0x8060, 0x0000, 0x0400, 0x0000, 0x0a62,
+ 0x0000, 0x8066, 0x0000, 0x0411, 0x0003, 0xc1d2, 0x0002, 0x0210,
+ 0x0001, 0xffc0, 0x0000, 0x0007, 0x0009, 0x03e0, 0x000f, 0x4000,
+ 0x0000, 0x8060, 0x0000, 0x0400, 0x0001, 0x8380, 0x0000, 0x0002,
+ 0x0009, 0x0a80, 0x0008, 0x7f62, 0x0000, 0x8066, 0x0000, 0x0e0a,
+ 0x000b, 0xc1e0, 0x0002, 0x0300, 0x0001, 0xffc0, 0x0000, 0x0007,
+ 0x0000, 0x7f06, 0x0002, 0x0a00, 0x0008, 0x7f62, 0x0000, 0x8066,
+ 0x0008, 0x060a, 0x000b, 0xc1e9, 0x000f, 0x4000, 0x0000, 0x0da0,
+ 0x0008, 0x0da2, 0x0008, 0x0da4, 0x0009, 0x8880, 0x0000, 0x0001,
+ 0x0008, 0x7f62, 0x0000, 0x8060, 0x0000, 0x0400, 0x0000, 0x8066,
+ 0x0008, 0xa012, 0x0000, 0x0da6, 0x0008, 0x0da8, 0x0000, 0x0daa,
+ 0x0000, 0x0dac, 0x0003, 0xc1f9, 0x0009, 0x8880, 0x0008, 0x0009,
+ 0x0008, 0x7f62, 0x0000, 0x8066, 0x0008, 0xa03a, 0x0003, 0xc1ff,
+ 0x000f, 0x4000, 0x0009, 0x8880, 0x0008, 0x0005, 0x0000, 0x8060,
+ 0x0000, 0x0400, 0x0008, 0x7f62, 0x0000, 0x8066, 0x0008, 0x0009,
+ 0x000b, 0xc208, 0x0008, 0x0060, 0x0008, 0x8062, 0x0000, 0x000d,
+ 0x0000, 0x8066, 0x0008, 0x0021, 0x000b, 0xc20e, 0x0000, 0x00fe,
+ 0x0001, 0x01d0, 0x0003, 0x8a17, 0x0008, 0x02fe, 0x0009, 0x03d0,
+ 0x000b, 0x0a17, 0x0000, 0x0d06, 0x000f, 0x4000, 0x0000, 0x8006,
+ 0x0000, 0x0001, 0x000f, 0x4000, 0x0008, 0x0060, 0x0008, 0x8062,
+ 0x0008, 0x002b, 0x0000, 0x8066, 0x0008, 0xa041, 0x000b, 0xc21f,
+ 0x0002, 0x0243, 0x000b, 0x8a26, 0x0000, 0x54ac, 0x0000, 0x55ae,
+ 0x0008, 0x0da8, 0x0000, 0x0daa, 0x0000, 0x50b0, 0x0000, 0x51b2,
+ 0x0000, 0x0db4, 0x0008, 0x0db6, 0x0008, 0x0060, 0x0008, 0x8062,
+ 0x0000, 0x0007, 0x0000, 0x8066, 0x0008, 0xa452, 0x000b, 0xc22f,
+ 0x000f, 0x4000, 0x000a, 0x3945, 0x000b, 0x8a3b, 0x0000, 0x8072,
+ 0x0008, 0x4040, 0x0007, 0x0000, 0x000a, 0x3945, 0x0003, 0x8a39,
+ 0x000f, 0x4000, 0x0000, 0x8072, 0x0000, 0x4000, 0x0007, 0x0000,
+ 0x0007, 0x0000, 0x0007, 0x0000, 0x000a, 0x3945, 0x000b, 0x0a33,
+ 0x000b, 0x023b, 0x000a, 0x3a40, 0x0003, 0x8819, 0x0001, 0xabd0,
+ 0x0008, 0x0000, 0x0000, 0x7f24, 0x0003, 0x5a46, 0x0008, 0x8054,
+ 0x0000, 0x0002, 0x0002, 0x1242, 0x0003, 0x0a8c, 0x000a, 0x3a45,
+ 0x000b, 0x0a7b, 0x000a, 0x1e10, 0x0000, 0x7f3c, 0x000b, 0x0a78,
+ 0x0002, 0x1d00, 0x0000, 0x7f3a, 0x0000, 0x0d60, 0x0008, 0x7f62,
+ 0x0000, 0x8066, 0x0008, 0x0009, 0x0003, 0xc256, 0x0008, 0x00fc,
+ 0x0003, 0xb275, 0x0000, 0x1c60, 0x0008, 0x8062, 0x0000, 0x0001,
+ 0x0000, 0x8066, 0x0008, 0x0009, 0x000b, 0xc25e, 0x0008, 0x00fc,
+ 0x000b, 0x33a9, 0x0000, 0x0038, 0x0008, 0x0060, 0x0008, 0x8062,
+ 0x0000, 0x0019, 0x0000, 0x8066, 0x0008, 0x0009, 0x000b, 0xc267,
+ 0x0009, 0x80c0, 0x0008, 0x00ff, 0x0008, 0x7f3e, 0x0000, 0x0d60,
+ 0x0008, 0x0efe, 0x0001, 0x1f80, 0x0008, 0x7f62, 0x0000, 0x8066,
+ 0x0008, 0x0009, 0x0003, 0xc271, 0x0008, 0x003a, 0x0000, 0x1dfe,
+ 0x000b, 0x0252, 0x0008, 0x0036, 0x0004, 0x00aa, 0x000b, 0x028c,
+ 0x0000, 0x8074, 0x0000, 0x2000, 0x000b, 0x028c, 0x0002, 0x3a44,
+ 0x000b, 0x0bd6, 0x0000, 0x8074, 0x0000, 0x1000, 0x0001, 0xadd0,
+ 0x0008, 0x0000, 0x0008, 0x7f0e, 0x0003, 0xb3a6, 0x0001, 0xa7d0,
+ 0x0008, 0x0000, 0x0000, 0x7f00, 0x0009, 0xa6d0, 0x0008, 0x0000,
+ 0x0009, 0x00d0, 0x0003, 0x8a9c, 0x0000, 0x8074, 0x0008, 0x4040,
+ 0x0003, 0x5a8c, 0x0003, 0x5241, 0x000a, 0x3a46, 0x0003, 0x8a9c,
+ 0x0002, 0x3a47, 0x0003, 0x0a97, 0x0008, 0x8054, 0x0000, 0x0004,
+ 0x0000, 0x8074, 0x0000, 0x8000, 0x0003, 0x02fc, 0x0009, 0x92c0,
+ 0x0000, 0x0fc8, 0x000b, 0x0813, 0x000a, 0x1246, 0x000b, 0x8ba0,
+ 0x0000, 0x1a60, 0x0008, 0x8062, 0x0000, 0x0002, 0x0000, 0x8066,
+ 0x0000, 0x367a, 0x000b, 0xc2a1, 0x0009, 0x92c0, 0x0008, 0x0780,
+ 0x0003, 0x8bba, 0x0002, 0x124b, 0x000b, 0x0aaa, 0x0002, 0x2e4d,
+ 0x0002, 0x2e4d, 0x0003, 0x0ba6, 0x000a, 0x3a46, 0x000b, 0x8aba,
+ 0x000b, 0x5aac, 0x0008, 0x8054, 0x0000, 0x0004, 0x000a, 0x1243,
+ 0x000b, 0x0afa, 0x0008, 0x8010, 0x0000, 0x000d, 0x0004, 0x0387,
+ 0x000a, 0x1948, 0x000b, 0x0ab7, 0x000c, 0x037c, 0x0000, 0x1810,
+ 0x0004, 0x0387, 0x0003, 0x02fa, 0x000a, 0x1948, 0x000b, 0x0abe,
+ 0x000a, 0x1243, 0x0003, 0x0ba9, 0x000a, 0x194d, 0x0003, 0x0ac2,
+ 0x000a, 0x1243, 0x000b, 0x0bb0, 0x0003, 0x5ac2, 0x0008, 0x8054,
+ 0x0000, 0x0004, 0x000a, 0x192e, 0x0008, 0x7f32, 0x000a, 0x1947,
+ 0x0003, 0x0af4, 0x0002, 0x194f, 0x000b, 0x0ad2, 0x000c, 0x037c,
+ 0x0000, 0x1810, 0x0004, 0x0201, 0x000b, 0xb2ed, 0x0004, 0x0387,
+ 0x000c, 0x01eb, 0x0003, 0x02fa, 0x0000, 0x1a60, 0x0008, 0x8062,
+ 0x0000, 0x001f, 0x0000, 0x8066, 0x0008, 0x0009, 0x0003, 0xc2d7,
+ 0x000a, 0x004c, 0x000b, 0x8af4, 0x0000, 0x8060, 0x0000, 0x0400,
+ 0x0001, 0x9880, 0x0000, 0x0007, 0x0008, 0x7f62, 0x0000, 0x8066,
+ 0x0000, 0x320a, 0x0003, 0xc2e1, 0x0000, 0x8060, 0x0000, 0x0400,
+ 0x0001, 0x9880, 0x0008, 0x0012, 0x0008, 0x7f62, 0x0000, 0x8066,
+ 0x0008, 0x1e0a, 0x000b, 0xc2e9, 0x0000, 0x1826, 0x0000, 0x1928,
+ 0x0003, 0x02fa, 0x0000, 0x0806, 0x0008, 0x8010, 0x0000, 0x001f,
+ 0x0004, 0x0387, 0x0000, 0x0310, 0x0004, 0x0387, 0x0003, 0x02fa,
+ 0x000c, 0x037c, 0x0008, 0x8010, 0x0000, 0x0001, 0x0004, 0x0387,
+ 0x0000, 0x1810, 0x0004, 0x0387, 0x0000, 0x8074, 0x0008, 0xf000,
+ 0x0000, 0x0d30, 0x0002, 0x3a42, 0x0003, 0x8b02, 0x0000, 0x15fc,
+ 0x0003, 0xb07e, 0x0003, 0x0013, 0x0000, 0x8074, 0x0000, 0x0501,
+ 0x0008, 0x8010, 0x0008, 0x000c, 0x0004, 0x0387, 0x0003, 0x0013,
+ 0x0009, 0xbbe0, 0x0008, 0x0030, 0x000b, 0x8b1e, 0x0000, 0x18fe,
+ 0x0009, 0x3ce0, 0x0003, 0x0b1b, 0x0008, 0x15fe, 0x0009, 0x3ce0,
+ 0x0003, 0x0b1b, 0x0008, 0x13fe, 0x0009, 0x3ce0, 0x000b, 0x8b17,
+ 0x000c, 0x0375, 0x0008, 0x0d26, 0x000b, 0x0318, 0x0004, 0x0377,
+ 0x0008, 0x8076, 0x0000, 0x0040, 0x000b, 0x0372, 0x0008, 0x8076,
+ 0x0008, 0x0041, 0x000b, 0x0372, 0x0009, 0xbbe0, 0x0000, 0x0032,
+ 0x0003, 0x8b23, 0x0008, 0x3c1e, 0x000b, 0x0372, 0x0009, 0xbbe0,
+ 0x0000, 0x003b, 0x000b, 0x8b28, 0x0000, 0x3cdc, 0x000b, 0x0372,
+ 0x0009, 0xbbe0, 0x0008, 0x0035, 0x000b, 0x8b2e, 0x0000, 0x8072,
+ 0x0000, 0x8000, 0x000b, 0x04e3, 0x0009, 0xbbe0, 0x0008, 0x0036,
+ 0x000b, 0x0c06, 0x0009, 0xbbe0, 0x0000, 0x0037, 0x000b, 0x8b53,
+ 0x0000, 0x18fe, 0x0009, 0x3ce0, 0x000b, 0x8b1b, 0x0008, 0x8076,
+ 0x0000, 0x0040, 0x0000, 0x1a60, 0x0008, 0x8062, 0x0000, 0x000d,
+ 0x0009, 0xa6d0, 0x0008, 0x0000, 0x0008, 0x7f04, 0x0001, 0xa7d0,
+ 0x0008, 0x0000, 0x0000, 0x7f06, 0x0001, 0xa8d0, 0x0008, 0x0000,
+ 0x0008, 0x7f08, 0x0009, 0xa9d0, 0x0008, 0x0000, 0x0000, 0x7f0a,
+ 0x0000, 0x8066, 0x0000, 0x0422, 0x0003, 0xc34a, 0x000c, 0x037c,
+ 0x0008, 0x8054, 0x0000, 0x0004, 0x0000, 0x8074, 0x0008, 0xf000,
+ 0x0000, 0x8072, 0x0000, 0x8000, 0x0003, 0x02fc, 0x0009, 0xbbe0,
+ 0x0000, 0x0038, 0x000b, 0x8b65, 0x0000, 0x18fe, 0x0009, 0x3ce0,
+ 0x000b, 0x0b62, 0x0008, 0x15fe, 0x0009, 0x3ce0, 0x000b, 0x8b11,
+ 0x0004, 0x0377, 0x0008, 0x8076, 0x0000, 0x0040, 0x0000, 0x8072,
+ 0x0000, 0x8000, 0x0003, 0x03cd, 0x0008, 0x8076, 0x0008, 0x0042,
+ 0x000b, 0x0372, 0x0009, 0xbbe0, 0x0000, 0x0016, 0x000b, 0x8b72,
+ 0x0000, 0x8074, 0x0008, 0x0808, 0x0002, 0x3a44, 0x000b, 0x8818,
+ 0x0000, 0x8074, 0x0000, 0x0800, 0x0000, 0x8072, 0x0000, 0x8000,
+ 0x000f, 0x8000, 0x0003, 0x0013, 0x0000, 0x8072, 0x0000, 0x8000,
+ 0x0003, 0x0013, 0x0002, 0x1430, 0x000b, 0x0378, 0x000a, 0x3d30,
+ 0x0000, 0x7f00, 0x0001, 0xbc80, 0x0000, 0x0007, 0x0003, 0x0380,
+ 0x000a, 0x1930, 0x0000, 0x7f00, 0x0001, 0x9880, 0x0000, 0x0007,
+ 0x0000, 0x8060, 0x0000, 0x0400, 0x0008, 0x7f62, 0x0000, 0x8066,
+ 0x0008, 0x000a, 0x0003, 0xc385, 0x000f, 0x4000, 0x000b, 0x238a,
+ 0x0008, 0x0870, 0x000f, 0x4000, 0x0002, 0x7040, 0x0003, 0x0b87,
+ 0x000b, 0xe394, 0x0008, 0x808a, 0x0000, 0x0004, 0x0007, 0x0000,
+ 0x0007, 0x0000, 0x0008, 0x80e0, 0x0008, 0x0202, 0x000b, 0x638d,
+ 0x0008, 0x80e0, 0x0000, 0x0100, 0x000b, 0x0387, 0x0009, 0xbac0,
+ 0x0008, 0x0090, 0x000b, 0x0b9d, 0x0000, 0x8074, 0x0000, 0x0706,
+ 0x000b, 0x039f, 0x0000, 0x8074, 0x0000, 0x0703, 0x000f, 0x4000,
+ 0x0008, 0x8010, 0x0000, 0x0023, 0x000b, 0x03db, 0x0008, 0x8010,
+ 0x0000, 0x0008, 0x000b, 0x03db, 0x0008, 0x8010, 0x0008, 0x0022,
+ 0x000b, 0x03db, 0x000c, 0x037c, 0x0008, 0x8010, 0x0000, 0x0007,
+ 0x0004, 0x0387, 0x0000, 0x1810, 0x0004, 0x0387, 0x0003, 0x03e5,
+ 0x000c, 0x037c, 0x0008, 0x8010, 0x0008, 0x001b, 0x0004, 0x0387,
+ 0x0000, 0x1810, 0x0004, 0x0387, 0x0000, 0x8074, 0x0000, 0xf080,
+ 0x0000, 0x0d30, 0x0003, 0x0013, 0x0008, 0x8010, 0x0008, 0x0009,
+ 0x000b, 0x03db, 0x0008, 0x8010, 0x0008, 0x0005, 0x000b, 0x03db,
+ 0x000a, 0x1648, 0x0003, 0x888c, 0x0008, 0x808c, 0x0000, 0x0001,
+ 0x0007, 0x0000, 0x0008, 0x8010, 0x0000, 0x0004, 0x000a, 0x4143,
+ 0x000b, 0x088c, 0x0002, 0x3a44, 0x0003, 0x8813, 0x0008, 0x0d2a,
+ 0x000b, 0x03db, 0x0008, 0x8010, 0x0008, 0x0003, 0x000b, 0x03dd,
+ 0x0008, 0x8010, 0x0000, 0x000b, 0x000b, 0x03dd, 0x0008, 0x8010,
+ 0x0000, 0x0002, 0x000b, 0x03dd, 0x0002, 0x3a47, 0x000b, 0x8a8c,
+ 0x0008, 0x8010, 0x0008, 0x0006, 0x000b, 0x03dd, 0x0000, 0x8074,
+ 0x0008, 0xf000, 0x0004, 0x0387, 0x000c, 0x0397, 0x000a, 0x3a40,
+ 0x000b, 0x0813, 0x0008, 0x8010, 0x0008, 0x000c, 0x0004, 0x0387,
+ 0x0003, 0x0013, 0x0000, 0x8074, 0x0000, 0xf080, 0x0000, 0x0d30,
+ 0x0002, 0x2e4d, 0x0002, 0x2e4d, 0x0003, 0x0bee, 0x0008, 0x8054,
+ 0x0000, 0x0019, 0x0003, 0x0013, 0x0008, 0x8054, 0x0008, 0x0009,
+ 0x0003, 0x0013, 0x0002, 0x3a44, 0x0003, 0x8813, 0x0003, 0x03d0,
+ 0x0008, 0x808c, 0x0008, 0x0000, 0x0002, 0x4447, 0x0003, 0x0c1a,
+ 0x0001, 0xc0c0, 0x0008, 0x00ff, 0x0009, 0xffe0, 0x0008, 0x00ff,
+ 0x0003, 0x8bf1, 0x0001, 0xc1e0, 0x0008, 0xffff, 0x0003, 0x8bf1,
+ 0x0008, 0x8010, 0x0000, 0x0013, 0x0004, 0x0387, 0x0000, 0x8074,
+ 0x0008, 0x0202, 0x0003, 0x0013, 0x000a, 0x3a40, 0x0003, 0x8c17,
+ 0x0000, 0x8074, 0x0000, 0x0200, 0x0000, 0x3d00, 0x0000, 0x3cfe,
+ 0x0000, 0x8072, 0x0000, 0x8000, 0x0001, 0x43e0, 0x000b, 0x8c15,
+ 0x0000, 0x42fe, 0x0001, 0xffc0, 0x0008, 0x00ff, 0x0009, 0x00e0,
+ 0x000b, 0x0bf1, 0x0008, 0x0d08, 0x0003, 0x046a, 0x0000, 0x8072,
+ 0x0000, 0x8000, 0x0003, 0x0013, 0x0004, 0x04ec, 0x0008, 0x808c,
+ 0x0000, 0x0001, 0x0000, 0x04fc, 0x0003, 0x34cf, 0x0000, 0x0460,
+ 0x0008, 0x8062, 0x0000, 0x0001, 0x0000, 0x8066, 0x0008, 0x0009,
+ 0x0003, 0xc424, 0x0000, 0x0004, 0x0009, 0x80c0, 0x0008, 0x00ff,
+ 0x0000, 0x7f00, 0x0001, 0x80e0, 0x0000, 0x0004, 0x0003, 0x0c3e,
+ 0x0001, 0x80e0, 0x0008, 0x0005, 0x0003, 0x0c3e, 0x0001, 0x80e0,
+ 0x0008, 0x0006, 0x0003, 0x0c3e, 0x0001, 0x82c0, 0x0008, 0xff00,
+ 0x0008, 0x7f04, 0x0009, 0x82e0, 0x0008, 0x0600, 0x0003, 0x0c3e,
+ 0x0009, 0x82e0, 0x0008, 0x0500, 0x0003, 0x0c3e, 0x0009, 0x82e0,
+ 0x0000, 0x0400, 0x0003, 0x8ccf, 0x0009, 0xc4c0, 0x0000, 0x7000,
+ 0x0009, 0xffe0, 0x0000, 0x1000, 0x000b, 0x0c6a, 0x000c, 0x04dd,
+ 0x0002, 0x3941, 0x0003, 0x0c49, 0x0000, 0x8072, 0x0000, 0x0400,
+ 0x0003, 0x0013, 0x0000, 0x0460, 0x0008, 0x80fe, 0x0008, 0x002b,
+ 0x0008, 0x7f62, 0x0000, 0x8066, 0x0008, 0x2209, 0x000b, 0xc44f,
+ 0x0008, 0x11fc, 0x0003, 0x3465, 0x0001, 0x9180, 0x0000, 0x0002,
+ 0x0000, 0x8060, 0x0000, 0x0400, 0x0008, 0x7f62, 0x0000, 0x8066,
+ 0x0008, 0x0609, 0x0003, 0xc459, 0x0000, 0x42fe, 0x0001, 0xffc0,
+ 0x0008, 0xff00, 0x0009, 0x03e0, 0x000b, 0x8c62, 0x0000, 0x8072,
+ 0x0000, 0x0400, 0x000b, 0x0056, 0x0001, 0x9180, 0x0008, 0x0003,
+ 0x000b, 0x044c, 0x0000, 0x8072, 0x0000, 0x0400, 0x0008, 0x8010,
+ 0x0000, 0x0010, 0x000b, 0x04c2, 0x000c, 0x04dd, 0x0002, 0x3941,
+ 0x0003, 0x0c70, 0x0000, 0x8072, 0x0000, 0x0400, 0x0003, 0x0013,
+ 0x0004, 0x04a7, 0x0008, 0x11fc, 0x000b, 0xb478, 0x0000, 0x8072,
+ 0x0000, 0x0400, 0x0008, 0x8010, 0x0000, 0x000e, 0x000b, 0x04c2,
+ 0x0000, 0x8060, 0x0000, 0x0400, 0x0000, 0x04fc, 0x000b, 0xb48d,
+ 0x0008, 0x808c, 0x0008, 0x0000, 0x0001, 0x9180, 0x0008, 0x0005,
+ 0x0008, 0x7f62, 0x0000, 0x8066, 0x0008, 0x0009, 0x000b, 0xc483,
+ 0x0008, 0x0060, 0x0008, 0x8062, 0x0008, 0x001b, 0x0008, 0x4304,
+ 0x0008, 0x4206, 0x0000, 0x8066, 0x0000, 0x0412, 0x0003, 0xc48b,
+ 0x000b, 0x04a4, 0x0008, 0x808c, 0x0000, 0x0001, 0x0000, 0x0460,
+ 0x0008, 0x8062, 0x0008, 0x002b, 0x0000, 0x8066, 0x0008, 0x0609,
+ 0x000b, 0xc494, 0x0000, 0x8066, 0x0008, 0x220a, 0x000b, 0xc497,
+ 0x0000, 0x42fe, 0x0001, 0xffc0, 0x0008, 0xff00, 0x0008, 0x7f04,
+ 0x0000, 0x8060, 0x0000, 0x0400, 0x0001, 0x9180, 0x0000, 0x0002,
+ 0x0008, 0x7f62, 0x0000, 0x8066, 0x0008, 0x041a, 0x0003, 0xc4a3,
+ 0x0000, 0x8072, 0x0000, 0x0400, 0x000b, 0x0056, 0x0000, 0x8060,
+ 0x0000, 0x0400, 0x0008, 0x6b62, 0x0000, 0x8066, 0x0000, 0x0411,
+ 0x0003, 0xc4ac, 0x0008, 0x02fe, 0x0009, 0x03e0, 0x0003, 0x8cb2,
+ 0x0000, 0x0d22, 0x000f, 0x4000, 0x0009, 0x8280, 0x0000, 0x0002,
+ 0x0001, 0x6b80, 0x0008, 0x7f62, 0x0000, 0x8066, 0x0008, 0x2209,
+ 0x0003, 0xc4b8, 0x000a, 0x0200, 0x0001, 0xffc0, 0x0000, 0x0007,
+ 0x0000, 0x7f06, 0x0008, 0x6b62, 0x0000, 0x8066, 0x0008, 0x060a,
+ 0x0003, 0xc4c0, 0x000f, 0x4000, 0x0002, 0x3a44, 0x0003, 0x8813,
+ 0x000a, 0x2f44, 0x000a, 0x2f44, 0x0003, 0x8bd0, 0x0008, 0x808a,
+ 0x0008, 0x0003, 0x0000, 0x8074, 0x0000, 0xf080, 0x0003, 0x5ccb,
+ 0x0008, 0x8054, 0x0000, 0x0019, 0x0003, 0x0013, 0x0002, 0x3a44,
+ 0x0003, 0x8813, 0x0008, 0x808c, 0x0008, 0x0000, 0x0008, 0x8010,
+ 0x0008, 0x0011, 0x0004, 0x0387, 0x0000, 0x42fe, 0x0001, 0xffc0,
+ 0x0008, 0x00ff, 0x0008, 0x7f10, 0x0004, 0x0387, 0x0008, 0x4310,
+ 0x000b, 0x03dd, 0x0002, 0x3941, 0x0003, 0x0ce0, 0x000f, 0x4000,
+ 0x0000, 0x8072, 0x0008, 0x0404, 0x000f, 0x4000, 0x0008, 0x8010,
+ 0x0008, 0x0012, 0x0004, 0x0387, 0x0004, 0x04a7, 0x0000, 0x1110,
+ 0x0004, 0x0387, 0x0008, 0x11fc, 0x0003, 0xb4e6, 0x0003, 0x0013,
+ 0x0009, 0xc2c0, 0x0008, 0x00ff, 0x0000, 0x7f00, 0x0001, 0xc3c0,
+ 0x0008, 0xff00, 0x0009, 0x00d0, 0x0003, 0x0d11, 0x0000, 0x0d0a,
+ 0x0001, 0x8580, 0x0000, 0x1000, 0x0008, 0x7f62, 0x0000, 0x8060,
+ 0x0000, 0x0400, 0x0000, 0x8066, 0x0000, 0x0809, 0x000b, 0xc4fb,
+ 0x0000, 0x04fc, 0x000b, 0x350a, 0x0000, 0x0460, 0x0008, 0x8062,
+ 0x0000, 0x0004, 0x0000, 0x8066, 0x0000, 0x0211, 0x000b, 0xc503,
+ 0x0008, 0x01fe, 0x0009, 0x00e0, 0x000b, 0x8d0a, 0x0008, 0x02fe,
+ 0x0001, 0x43e0, 0x000b, 0x0d10, 0x0002, 0x0500, 0x0000, 0x7f0a,
+ 0x0009, 0xffe0, 0x0000, 0x0800, 0x000b, 0x8cf4, 0x0008, 0x0d08,
+ 0x000f, 0x4000, 0x0008, 0x43fe, 0x0001, 0x3e80, 0x0000, 0x0d60,
+ 0x0008, 0x7f62, 0x0000, 0x8066, 0x0000, 0x0809, 0x000b, 0xc517,
+ 0x0000, 0x8060, 0x0000, 0x0400, 0x0001, 0x84c0, 0x0008, 0xff00,
+ 0x0002, 0x7f70, 0x0009, 0xff80, 0x0000, 0x1000, 0x0008, 0x7f62,
+ 0x0000, 0x8066, 0x0000, 0x0809, 0x000b, 0xc522, 0x000f, 0x4000,
+ 0xe4ae, 0x1eb8
};
-unsigned short rseqipx_code_length01 = 0x0a20;
+unsigned short rseqipx_code_length01 = 0x0a4a;
/*
*
*/
unsigned long xseqipx_code_addr01 = 0x0001e000 ;
unsigned short xseqipx_code01[] = {
-0x0013, 0x0003, 0x0000, 0x1246, 0x0001, 0xe000, 0x0005, 0x0032,
+0x0013, 0x0003, 0x0000, 0x1252, 0x0001, 0xe000, 0x0005, 0x0032,
0x0000, 0x0010, 0x0015, 0x0033, 0x0010, 0xbb39, 0x000b, 0x8007,
- 0x0004, 0x0110, 0x0014, 0x0122, 0x0010, 0xc000, 0x0000, 0xc001,
+ 0x0004, 0x0113, 0x0004, 0x0125, 0x0010, 0xc000, 0x0000, 0xc001,
0x0000, 0xc0b0, 0x0010, 0xc0b1, 0x0010, 0xc0b2, 0x0000, 0xc0b3,
0x0010, 0xc0b4, 0x0000, 0xc0b5, 0x0000, 0xc0b6, 0x0010, 0xc0b7,
0x0010, 0xc0b8, 0x0000, 0xc0b9, 0x0000, 0xc0ba, 0x0000, 0xc0c2,
@@ -7695,578 +7702,580 @@ unsigned short xseqipx_code01[] = {
0x0010, 0xc0cf, 0x0015, 0x0039, 0x0010, 0xff00, 0x0015, 0x003a,
0x0010, 0xff00, 0x0005, 0x00d0, 0x0010, 0xff00, 0x0015, 0x00d1,
0x0010, 0xff00, 0x0012, 0x3a40, 0x000b, 0x1031, 0x0002, 0x7940,
- 0x001b, 0x1134, 0x0002, 0x3a42, 0x001b, 0x1035, 0x0003, 0xb035,
- 0x0013, 0xa1df, 0x0002, 0x3a41, 0x001b, 0x1039, 0x0012, 0x7941,
- 0x001b, 0x1314, 0x0013, 0xe054, 0x0001, 0x0fe8, 0x0000, 0x0001,
+ 0x001b, 0x1137, 0x0002, 0x3a42, 0x001b, 0x1035, 0x0003, 0xb035,
+ 0x0003, 0xa1e2, 0x0002, 0x3a41, 0x001b, 0x1039, 0x0012, 0x7941,
+ 0x001b, 0x1317, 0x0013, 0xe054, 0x0001, 0x0fe8, 0x0000, 0x0001,
0x0013, 0x1054, 0x0000, 0x0cfe, 0x0013, 0x6047, 0x0002, 0x3a44,
- 0x001b, 0x1047, 0x0011, 0x02e8, 0x0010, 0x0000, 0x0013, 0x13c7,
- 0x0011, 0x02e8, 0x0010, 0x0005, 0x0013, 0x1459, 0x0012, 0x3a46,
+ 0x001b, 0x1047, 0x0011, 0x02e8, 0x0010, 0x0000, 0x0013, 0x13cd,
+ 0x0011, 0x02e8, 0x0010, 0x0005, 0x0013, 0x145f, 0x0012, 0x3a46,
0x000b, 0x1054, 0x0011, 0x02e8, 0x0010, 0x0000, 0x0013, 0x104f,
0x0011, 0x02e8, 0x0010, 0x0005, 0x000b, 0x1054, 0x0000, 0x12fe,
- 0x0003, 0x6054, 0x0001, 0x0fe8, 0x0010, 0x0000, 0x0013, 0x168f,
+ 0x0003, 0x6054, 0x0001, 0x0fe8, 0x0010, 0x0000, 0x0003, 0x1695,
0x0015, 0x0030, 0x0000, 0x0400, 0x0010, 0xc131, 0x0015, 0x0033,
0x0010, 0xb211, 0x001b, 0x8059, 0x0010, 0xb2ff, 0x0001, 0xb3e0,
- 0x000c, 0x10d2, 0x000b, 0xf02d, 0x0011, 0x3be8, 0x0000, 0x0010,
+ 0x001c, 0x10d5, 0x000b, 0xf02d, 0x0011, 0x3be8, 0x0000, 0x0010,
0x001b, 0x1071, 0x0000, 0x0afe, 0x000b, 0x6065, 0x0000, 0x3c0b,
0x0003, 0x006d, 0x0015, 0x0030, 0x0000, 0x0400, 0x0001, 0x0a88,
0x0010, 0x0003, 0x0000, 0xff31, 0x0015, 0x0033, 0x0010, 0x3c0a,
0x001b, 0x806c, 0x0010, 0x3c0a, 0x0002, 0x0c00, 0x0010, 0xff0c,
- 0x0013, 0x00cf, 0x0011, 0x3be8, 0x0010, 0x0012, 0x001b, 0x1084,
+ 0x0013, 0x00d2, 0x0011, 0x3be8, 0x0010, 0x0012, 0x001b, 0x1084,
0x0010, 0x08fe, 0x000b, 0x6078, 0x0010, 0x3c09, 0x0003, 0x0080,
0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x0888, 0x0010, 0x0003,
0x0000, 0xff31, 0x0015, 0x0033, 0x0010, 0x3c0a, 0x000b, 0x807f,
- 0x0000, 0x3c08, 0x0002, 0x0c00, 0x0010, 0xff0c, 0x0013, 0x00cf,
+ 0x0000, 0x3c08, 0x0002, 0x0c00, 0x0010, 0xff0c, 0x0013, 0x00d2,
0x0011, 0x3be8, 0x0000, 0x0013, 0x000b, 0x108a, 0x0000, 0x3cb0,
- 0x0004, 0x00e2, 0x0013, 0x00cf, 0x0011, 0x3be8, 0x0000, 0x0019,
+ 0x0014, 0x00e5, 0x0013, 0x00d2, 0x0011, 0x3be8, 0x0000, 0x0019,
0x000b, 0x109d, 0x0010, 0x04fe, 0x001b, 0x6091, 0x0010, 0x3c05,
0x0013, 0x0099, 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x0488,
0x0010, 0x0003, 0x0000, 0xff31, 0x0015, 0x0033, 0x0010, 0x3c0a,
0x000b, 0x8098, 0x0000, 0x3c04, 0x0002, 0x0c00, 0x0010, 0xff0c,
- 0x0013, 0x00cf, 0x0011, 0x3be8, 0x0010, 0x001b, 0x001b, 0x10a3,
- 0x0015, 0x000f, 0x0010, 0x0000, 0x0013, 0x00cf, 0x0011, 0x3be8,
- 0x0000, 0x0015, 0x001b, 0x10af, 0x0004, 0x0119, 0x0014, 0x012b,
- 0x0015, 0x0039, 0x0000, 0x8000, 0x0017, 0x8000, 0x0004, 0x0110,
- 0x0014, 0x0122, 0x0014, 0x00fb, 0x0013, 0x002d, 0x0011, 0x3be8,
- 0x0000, 0x0016, 0x000b, 0x10c1, 0x0001, 0x0fe8, 0x0010, 0x0000,
- 0x0003, 0x10bb, 0x0001, 0x0fe8, 0x0000, 0x0002, 0x0003, 0x10bb,
- 0x0015, 0x0039, 0x0010, 0x1010, 0x0013, 0x00cf, 0x0015, 0x0039,
- 0x0000, 0x5040, 0x0015, 0x00b8, 0x0000, 0x0008, 0x0014, 0x091f,
- 0x0013, 0x00cf, 0x0011, 0x3be8, 0x0010, 0x0017, 0x001b, 0x10c6,
- 0x0010, 0x3cc3, 0x0013, 0x00cf, 0x0011, 0x3be8, 0x0010, 0x0018,
- 0x000b, 0x10cb, 0x0000, 0x3cc2, 0x0013, 0x00cf, 0x0005, 0x00ce,
- 0x0000, 0x0001, 0x0000, 0x3bcf, 0x0014, 0x08e1, 0x0015, 0x0039,
- 0x0000, 0x8000, 0x0013, 0x002d, 0x0001, 0xb288, 0x0000, 0x0002,
- 0x0001, 0xc180, 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb009,
- 0x001b, 0x80d8, 0x0002, 0xb200, 0x0011, 0xffc8, 0x0000, 0x0007,
- 0x0010, 0xffb2, 0x0010, 0xc131, 0x0015, 0x0033, 0x0010, 0xb20a,
- 0x0001, 0xb0d0, 0x001b, 0x80e1, 0x0015, 0x0030, 0x0000, 0x0400,
- 0x0011, 0xb088, 0x0000, 0x0010, 0x0000, 0xff31, 0x0015, 0x0033,
- 0x0010, 0xb109, 0x000b, 0x80e9, 0x0001, 0xb1e8, 0x0010, 0xffff,
- 0x0003, 0x10fa, 0x0000, 0x11fe, 0x001b, 0x60f1, 0x0000, 0xb012,
- 0x0013, 0x00f9, 0x0015, 0x0030, 0x0000, 0x0400, 0x0001, 0x1188,
- 0x0010, 0x0003, 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb00a,
- 0x000b, 0x80f8, 0x0000, 0xb011, 0x0017, 0x4000, 0x0015, 0x0030,
- 0x0000, 0x0400, 0x0011, 0xbc88, 0x0000, 0x001f, 0x0000, 0xff31,
- 0x0015, 0x0033, 0x0000, 0xc411, 0x001b, 0x8102, 0x0011, 0xbc88,
- 0x0010, 0x0018, 0x0000, 0xff31, 0x0015, 0x0033, 0x0010, 0xc609,
- 0x001b, 0x8108, 0x0011, 0xbc88, 0x0000, 0x0037, 0x0000, 0xff31,
- 0x0015, 0x0033, 0x0000, 0xc709, 0x001b, 0x810e, 0x0017, 0x4000,
+ 0x0013, 0x00d2, 0x0011, 0x3be8, 0x0010, 0x001b, 0x001b, 0x10a6,
+ 0x0010, 0xc014, 0x0000, 0xc013, 0x0000, 0xc010, 0x0015, 0x000f,
+ 0x0010, 0x0000, 0x0013, 0x00d2, 0x0011, 0x3be8, 0x0000, 0x0015,
+ 0x001b, 0x10b2, 0x0004, 0x011c, 0x0014, 0x012e, 0x0015, 0x0039,
+ 0x0000, 0x8000, 0x0017, 0x8000, 0x0004, 0x0113, 0x0004, 0x0125,
+ 0x0014, 0x00fe, 0x0013, 0x002d, 0x0011, 0x3be8, 0x0000, 0x0016,
+ 0x000b, 0x10c4, 0x0001, 0x0fe8, 0x0010, 0x0000, 0x0003, 0x10be,
+ 0x0001, 0x0fe8, 0x0000, 0x0002, 0x0003, 0x10be, 0x0015, 0x0039,
+ 0x0010, 0x1010, 0x0013, 0x00d2, 0x0015, 0x0039, 0x0000, 0x5040,
+ 0x0015, 0x00b8, 0x0000, 0x0008, 0x0014, 0x0925, 0x0013, 0x00d2,
+ 0x0011, 0x3be8, 0x0010, 0x0017, 0x001b, 0x10c9, 0x0010, 0x3cc3,
+ 0x0013, 0x00d2, 0x0011, 0x3be8, 0x0010, 0x0018, 0x000b, 0x10ce,
+ 0x0000, 0x3cc2, 0x0013, 0x00d2, 0x0005, 0x00ce, 0x0000, 0x0001,
+ 0x0000, 0x3bcf, 0x0014, 0x08e7, 0x0015, 0x0039, 0x0000, 0x8000,
+ 0x0013, 0x002d, 0x0001, 0xb288, 0x0000, 0x0002, 0x0001, 0xc180,
+ 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb009, 0x001b, 0x80db,
+ 0x0002, 0xb200, 0x0011, 0xffc8, 0x0000, 0x0007, 0x0010, 0xffb2,
+ 0x0010, 0xc131, 0x0015, 0x0033, 0x0010, 0xb20a, 0x0001, 0xb0d0,
+ 0x001b, 0x80e4, 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0xb088,
+ 0x0000, 0x0010, 0x0000, 0xff31, 0x0015, 0x0033, 0x0010, 0xb109,
+ 0x000b, 0x80ec, 0x0001, 0xb1e8, 0x0010, 0xffff, 0x0013, 0x10fd,
+ 0x0000, 0x11fe, 0x001b, 0x60f4, 0x0000, 0xb012, 0x0013, 0x00fc,
+ 0x0015, 0x0030, 0x0000, 0x0400, 0x0001, 0x1188, 0x0010, 0x0003,
+ 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb00a, 0x000b, 0x80fb,
+ 0x0000, 0xb011, 0x0017, 0x4000, 0x0015, 0x0030, 0x0000, 0x0400,
+ 0x0011, 0xbc88, 0x0000, 0x001f, 0x0000, 0xff31, 0x0015, 0x0033,
+ 0x0000, 0xc411, 0x000b, 0x8105, 0x0011, 0xbc88, 0x0010, 0x0018,
+ 0x0000, 0xff31, 0x0015, 0x0033, 0x0010, 0xc609, 0x001b, 0x810b,
+ 0x0011, 0xbc88, 0x0000, 0x0037, 0x0000, 0xff31, 0x0015, 0x0033,
+ 0x0000, 0xc709, 0x000b, 0x8111, 0x0017, 0x4000, 0x0015, 0x0030,
+ 0x0000, 0x0400, 0x0001, 0xbb88, 0x0000, 0x0001, 0x0000, 0xff31,
+ 0x0015, 0x0033, 0x0000, 0x0269, 0x001b, 0x811a, 0x0017, 0x4000,
0x0015, 0x0030, 0x0000, 0x0400, 0x0001, 0xbb88, 0x0000, 0x0001,
- 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0x0269, 0x000b, 0x8117,
+ 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0x026a, 0x001b, 0x8123,
0x0017, 0x4000, 0x0015, 0x0030, 0x0000, 0x0400, 0x0001, 0xbb88,
- 0x0000, 0x0001, 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0x026a,
- 0x001b, 0x8120, 0x0017, 0x4000, 0x0015, 0x0030, 0x0000, 0x0400,
+ 0x0010, 0x000f, 0x0000, 0xff31, 0x0015, 0x0033, 0x0010, 0x0f59,
+ 0x001b, 0x812c, 0x0017, 0x4000, 0x0015, 0x0030, 0x0000, 0x0400,
0x0001, 0xbb88, 0x0010, 0x000f, 0x0000, 0xff31, 0x0015, 0x0033,
- 0x0010, 0x0f59, 0x001b, 0x8129, 0x0017, 0x4000, 0x0015, 0x0030,
- 0x0000, 0x0400, 0x0001, 0xbb88, 0x0010, 0x000f, 0x0000, 0xff31,
- 0x0015, 0x0033, 0x0010, 0x0f5a, 0x001b, 0x8132, 0x0017, 0x4000,
- 0x0000, 0xd0ff, 0x0012, 0xff40, 0x000b, 0x1031, 0x0015, 0x00d1,
- 0x0010, 0x0101, 0x0003, 0x9139, 0x0005, 0x0079, 0x0000, 0x0001,
- 0x0003, 0x913c, 0x0015, 0x00d1, 0x0000, 0x0100, 0x0011, 0x02e8,
- 0x0000, 0x0002, 0x0003, 0x1164, 0x0011, 0x02e8, 0x0000, 0x0001,
- 0x0003, 0x117c, 0x0011, 0x02e8, 0x0000, 0x0004, 0x0013, 0x119a,
- 0x0011, 0x02e8, 0x0010, 0x0003, 0x0003, 0x11cb, 0x0005, 0x0002,
- 0x0010, 0x0000, 0x0000, 0xc00e, 0x0000, 0xc00d, 0x0010, 0xc003,
- 0x0015, 0x0030, 0x0000, 0x0400, 0x0001, 0xbd88, 0x0010, 0x0009,
- 0x0000, 0xff31, 0x0015, 0x0033, 0x0010, 0xc00a, 0x001b, 0x8157,
- 0x0000, 0xff31, 0x0015, 0x0033, 0x0010, 0xc00a, 0x001b, 0x815b,
- 0x0012, 0x3a45, 0x0013, 0x1163, 0x0015, 0x003a, 0x0000, 0x2000,
- 0x0015, 0x003a, 0x0010, 0x1010, 0x0014, 0x090b, 0x0003, 0x004f,
- 0x0012, 0x7849, 0x0003, 0x11d9, 0x0010, 0x0dfe, 0x0003, 0x614d,
- 0x0012, 0x0c10, 0x0010, 0xff0c, 0x0015, 0x0030, 0x0000, 0x0400,
- 0x0011, 0x0d88, 0x0010, 0x0003, 0x0000, 0xff31, 0x0015, 0x0033,
- 0x0000, 0xb309, 0x000b, 0x8171, 0x0010, 0xb3fe, 0x0013, 0x6179,
- 0x0010, 0xb30b, 0x0015, 0x0033, 0x0010, 0xc00a, 0x000b, 0x8177,
- 0x0013, 0x01ce, 0x0000, 0xc00b, 0x0010, 0xc00a, 0x0013, 0x01ce,
- 0x0000, 0x78b0, 0x0012, 0xb044, 0x0003, 0x11d9, 0x0002, 0xb049,
- 0x0003, 0x11d9, 0x0010, 0x71ff, 0x0012, 0xff38, 0x0010, 0xff71,
- 0x0010, 0x0dfe, 0x0003, 0x614b, 0x0012, 0x0c10, 0x0010, 0xff0c,
- 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x0d88, 0x0010, 0x0003,
- 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb309, 0x001b, 0x818f,
- 0x0010, 0xb3fe, 0x0013, 0x6197, 0x0000, 0xb309, 0x0015, 0x0033,
- 0x0010, 0xc00a, 0x000b, 0x8195, 0x0013, 0x01ce, 0x0010, 0xc009,
- 0x0000, 0xc008, 0x0013, 0x01ce, 0x0000, 0x78b0, 0x0012, 0xb044,
- 0x0003, 0x11d9, 0x0002, 0xb049, 0x0003, 0x11d9, 0x0010, 0x71ff,
- 0x0012, 0xff38, 0x0010, 0xff71, 0x0010, 0x0dfe, 0x0003, 0x614b,
- 0x0012, 0x0c10, 0x0010, 0xff0c, 0x0015, 0x0030, 0x0000, 0x0400,
- 0x0011, 0x0d88, 0x0010, 0x0003, 0x0000, 0xff31, 0x0015, 0x0033,
- 0x0000, 0xb309, 0x001b, 0x81ad, 0x0010, 0xb3fe, 0x0013, 0x61b5,
- 0x0000, 0xb305, 0x0015, 0x0033, 0x0010, 0xc00a, 0x001b, 0x81b3,
- 0x0003, 0x01b7, 0x0010, 0xc005, 0x0000, 0xc004, 0x0002, 0x033f,
- 0x0002, 0xff27, 0x0000, 0x0db8, 0x0014, 0x03bc, 0x0000, 0x0db8,
- 0x0014, 0x091f, 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0xbc88,
- 0x0010, 0x0000, 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb309,
- 0x001b, 0x81c4, 0x0011, 0xb3e8, 0x0000, 0x0002, 0x000b, 0x114b,
- 0x0005, 0x0002, 0x0010, 0x0005, 0x0003, 0x014d, 0x0012, 0x7849,
- 0x0003, 0x11d9, 0x0003, 0x014d, 0x0000, 0x0db8, 0x0012, 0x0345,
- 0x000b, 0x11d4, 0x0002, 0x033f, 0x0014, 0x03bc, 0x0003, 0x014b,
- 0x0002, 0x033f, 0x0002, 0xff27, 0x0014, 0x03bc, 0x0014, 0x091f,
- 0x0003, 0x014b, 0x0015, 0x00b8, 0x0000, 0x0001, 0x0015, 0x003a,
- 0x0010, 0x0101, 0x0014, 0x091f, 0x0003, 0x015c, 0x0001, 0x2bd8,
- 0x0010, 0x0000, 0x0000, 0xffba, 0x0013, 0xb1e2, 0x0005, 0x002a,
- 0x0000, 0x0002, 0x0001, 0xbac8, 0x0000, 0x0700, 0x000b, 0x12cf,
- 0x0011, 0x15e8, 0x0000, 0x0002, 0x0003, 0x1245, 0x0011, 0x15e8,
- 0x0000, 0x0001, 0x0003, 0x11f1, 0x0005, 0x0015, 0x0010, 0x0000,
- 0x0003, 0x0228, 0x0005, 0x0015, 0x0010, 0x0000, 0x0002, 0xba43,
- 0x0003, 0x1229, 0x0013, 0xb1f5, 0x0005, 0x002a, 0x0000, 0x0004,
- 0x0012, 0xba42, 0x0003, 0x122f, 0x0012, 0x104b, 0x000b, 0x1228,
- 0x0000, 0x1a30, 0x0005, 0x0031, 0x0000, 0x0002, 0x0015, 0x0033,
- 0x0000, 0x1b2a, 0x001b, 0x8201, 0x0011, 0x20d8, 0x0010, 0x0000,
- 0x0000, 0xffb0, 0x0001, 0x21d8, 0x0010, 0x0000, 0x0010, 0xffb1,
- 0x0001, 0x22d8, 0x0010, 0x0000, 0x0010, 0xffb2, 0x0011, 0x23d8,
- 0x0010, 0x0000, 0x0000, 0xffb3, 0x0001, 0x24d8, 0x0010, 0x0000,
- 0x0010, 0xffb4, 0x0011, 0x25d8, 0x0010, 0x0000, 0x0000, 0xffb5,
- 0x0001, 0x28d8, 0x0010, 0x0000, 0x0010, 0xffb8, 0x0011, 0x29d8,
- 0x0010, 0x0000, 0x0000, 0xffb9, 0x0000, 0x1a30, 0x0005, 0x0031,
- 0x0000, 0x0007, 0x0015, 0x0033, 0x0010, 0xb032, 0x001b, 0x821f,
- 0x0000, 0x1a30, 0x0005, 0x0031, 0x0010, 0x000f, 0x0015, 0x0033,
- 0x0010, 0xb812, 0x001b, 0x8225, 0x0005, 0x0015, 0x0010, 0x0000,
- 0x0013, 0x0035, 0x0000, 0x1efe, 0x0013, 0x623d, 0x0014, 0x0274,
- 0x0000, 0x1efe, 0x000c, 0x6274, 0x0003, 0x0228, 0x0000, 0x1a30,
- 0x0005, 0x0031, 0x0000, 0x0020, 0x0015, 0x0033, 0x0000, 0xb009,
- 0x001b, 0x8234, 0x0002, 0xb02f, 0x0000, 0xffb0, 0x0005, 0x0031,
- 0x0000, 0x0020, 0x0015, 0x0033, 0x0000, 0xb00a, 0x001b, 0x823b,
- 0x0003, 0x01fc, 0x0015, 0x00b8, 0x0010, 0x0005, 0x0014, 0x091f,
- 0x0000, 0x13b8, 0x0015, 0x003a, 0x0010, 0x0404, 0x0014, 0x091f,
- 0x0003, 0x0228, 0x0005, 0x0015, 0x0000, 0x0001, 0x0012, 0xba42,
- 0x0013, 0x1253, 0x0003, 0xb249, 0x0001, 0x2bd8, 0x0010, 0x0000,
- 0x0012, 0xff4f, 0x001b, 0x11df, 0x0002, 0xba43, 0x001b, 0x122f,
- 0x0000, 0x1efe, 0x000c, 0x6274, 0x0003, 0x0228, 0x0001, 0x28d8,
- 0x0010, 0x0000, 0x0010, 0xffb8, 0x0011, 0x29d8, 0x0010, 0x0000,
- 0x0000, 0xffb9, 0x0004, 0x02e5, 0x0002, 0x3a42, 0x000b, 0x1228,
- 0x0000, 0x1c30, 0x0015, 0x00ff, 0x0000, 0x0002, 0x0002, 0x1f43,
- 0x001b, 0x1264, 0x0001, 0xff88, 0x0000, 0x0002, 0x0003, 0x0266,
- 0x0001, 0xff88, 0x0000, 0x0004, 0x0000, 0xff31, 0x0015, 0x0033,
- 0x0000, 0xb011, 0x000b, 0x8269, 0x0000, 0xb0ff, 0x0011, 0x16a0,
- 0x0000, 0xff16, 0x001b, 0x2270, 0x0002, 0xb100, 0x0003, 0x0271,
- 0x0010, 0xb1ff, 0x0001, 0x17a0, 0x0010, 0xff17, 0x0013, 0x022f,
- 0x0000, 0x16ff, 0x0001, 0x18a0, 0x0010, 0xff00, 0x000b, 0x227b,
- 0x0002, 0x1700, 0x0003, 0x12ce, 0x0013, 0x027c, 0x0010, 0x17ff,
- 0x0011, 0x19a0, 0x0003, 0x22ce, 0x0011, 0x00d0, 0x0003, 0x12ce,
- 0x0000, 0x1c30, 0x0000, 0x1b31, 0x0015, 0x0033, 0x0000, 0xb131,
- 0x000b, 0x8284, 0x0003, 0xb285, 0x0000, 0xb120, 0x0010, 0xb221,
- 0x0002, 0x1f43, 0x001b, 0x1291, 0x0010, 0xc022, 0x0000, 0xc023,
- 0x0000, 0xb324, 0x0000, 0xb425, 0x0010, 0xb3b5, 0x0000, 0xb4b6,
- 0x0003, 0x0295, 0x0000, 0xb322, 0x0000, 0xb423, 0x0000, 0xb524,
- 0x0010, 0xb625, 0x0013, 0xb295, 0x0005, 0x002a, 0x0000, 0x0001,
- 0x0012, 0x1500, 0x0000, 0xff15, 0x0000, 0x16ff, 0x0001, 0xb580,
- 0x0000, 0xff16, 0x000b, 0x22a0, 0x0002, 0x1700, 0x0013, 0x02a1,
- 0x0010, 0x17ff, 0x0001, 0xb680, 0x0010, 0xff17, 0x0012, 0x1e10,
- 0x0010, 0xff1e, 0x0013, 0x62ce, 0x0002, 0x1d00, 0x0010, 0xff1d,
- 0x0010, 0xc030, 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb009,
- 0x000b, 0x82ac, 0x0010, 0xb0fe, 0x000b, 0x62cd, 0x0000, 0x1c30,
- 0x0005, 0x0031, 0x0000, 0x0001, 0x0015, 0x0033, 0x0000, 0xb009,
- 0x000b, 0x82b4, 0x0010, 0xb0fe, 0x000b, 0x62ba, 0x0005, 0x00ce,
- 0x0010, 0x0005, 0x0003, 0x08e1, 0x0010, 0xb01c, 0x0000, 0x1c30,
- 0x0005, 0x0031, 0x0000, 0x0019, 0x0015, 0x0033, 0x0000, 0xb009,
- 0x000b, 0x82c0, 0x0001, 0xb0c8, 0x0010, 0x00ff, 0x0000, 0xff1f,
- 0x0010, 0xc030, 0x0011, 0xbe80, 0x0000, 0xff31, 0x0015, 0x0033,
- 0x0000, 0xb009, 0x000b, 0x82c9, 0x0000, 0xb01d, 0x0010, 0x1dff,
- 0x0013, 0x02a8, 0x0000, 0xb01b, 0x0017, 0x4000, 0x0002, 0x3a41,
- 0x0013, 0x12d7, 0x0013, 0xb2d1, 0x0005, 0x002a, 0x0000, 0x0004,
- 0x0005, 0x0015, 0x0010, 0x0000, 0x0003, 0x0228, 0x0000, 0x1a30,
+ 0x0010, 0x0f5a, 0x000b, 0x8135, 0x0017, 0x4000, 0x0000, 0xd0ff,
+ 0x0012, 0xff40, 0x000b, 0x1031, 0x0015, 0x00d1, 0x0010, 0x0101,
+ 0x0003, 0x913c, 0x0005, 0x0079, 0x0000, 0x0001, 0x0003, 0x913f,
+ 0x0015, 0x00d1, 0x0000, 0x0100, 0x0011, 0x02e8, 0x0000, 0x0002,
+ 0x0003, 0x1167, 0x0011, 0x02e8, 0x0000, 0x0001, 0x0003, 0x117f,
+ 0x0011, 0x02e8, 0x0000, 0x0004, 0x0003, 0x119d, 0x0011, 0x02e8,
+ 0x0010, 0x0003, 0x0003, 0x11ce, 0x0005, 0x0002, 0x0010, 0x0000,
+ 0x0000, 0xc00e, 0x0000, 0xc00d, 0x0010, 0xc003, 0x0015, 0x0030,
+ 0x0000, 0x0400, 0x0001, 0xbd88, 0x0010, 0x0009, 0x0000, 0xff31,
+ 0x0015, 0x0033, 0x0010, 0xc00a, 0x000b, 0x815a, 0x0000, 0xff31,
+ 0x0015, 0x0033, 0x0010, 0xc00a, 0x001b, 0x815e, 0x0012, 0x3a45,
+ 0x0013, 0x1166, 0x0015, 0x003a, 0x0000, 0x2000, 0x0015, 0x003a,
+ 0x0010, 0x1010, 0x0004, 0x0911, 0x0003, 0x004f, 0x0012, 0x7849,
+ 0x0003, 0x11dc, 0x0010, 0x0dfe, 0x0003, 0x6150, 0x0012, 0x0c10,
+ 0x0010, 0xff0c, 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x0d88,
+ 0x0010, 0x0003, 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb309,
+ 0x000b, 0x8174, 0x0010, 0xb3fe, 0x0013, 0x617c, 0x0010, 0xb30b,
+ 0x0015, 0x0033, 0x0010, 0xc00a, 0x001b, 0x817a, 0x0003, 0x01d1,
+ 0x0000, 0xc00b, 0x0010, 0xc00a, 0x0003, 0x01d1, 0x0000, 0x78b0,
+ 0x0012, 0xb044, 0x0003, 0x11dc, 0x0002, 0xb049, 0x0003, 0x11dc,
+ 0x0010, 0x71ff, 0x0012, 0xff38, 0x0010, 0xff71, 0x0010, 0x0dfe,
+ 0x0003, 0x614e, 0x0012, 0x0c10, 0x0010, 0xff0c, 0x0015, 0x0030,
+ 0x0000, 0x0400, 0x0011, 0x0d88, 0x0010, 0x0003, 0x0000, 0xff31,
+ 0x0015, 0x0033, 0x0000, 0xb309, 0x001b, 0x8192, 0x0010, 0xb3fe,
+ 0x0003, 0x619a, 0x0000, 0xb309, 0x0015, 0x0033, 0x0010, 0xc00a,
+ 0x001b, 0x8198, 0x0003, 0x01d1, 0x0010, 0xc009, 0x0000, 0xc008,
+ 0x0003, 0x01d1, 0x0000, 0x78b0, 0x0012, 0xb044, 0x0003, 0x11dc,
+ 0x0002, 0xb049, 0x0003, 0x11dc, 0x0010, 0x71ff, 0x0012, 0xff38,
+ 0x0010, 0xff71, 0x0010, 0x0dfe, 0x0003, 0x614e, 0x0012, 0x0c10,
+ 0x0010, 0xff0c, 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x0d88,
+ 0x0010, 0x0003, 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb309,
+ 0x001b, 0x81b0, 0x0010, 0xb3fe, 0x0003, 0x61b8, 0x0000, 0xb305,
+ 0x0015, 0x0033, 0x0010, 0xc00a, 0x001b, 0x81b6, 0x0013, 0x01ba,
+ 0x0010, 0xc005, 0x0000, 0xc004, 0x0002, 0x033f, 0x0002, 0xff27,
+ 0x0000, 0x0db8, 0x0014, 0x03c2, 0x0000, 0x0db8, 0x0014, 0x0925,
+ 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0xbc88, 0x0010, 0x0000,
+ 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb309, 0x001b, 0x81c7,
+ 0x0011, 0xb3e8, 0x0000, 0x0002, 0x000b, 0x114e, 0x0005, 0x0002,
+ 0x0010, 0x0005, 0x0003, 0x0150, 0x0012, 0x7849, 0x0003, 0x11dc,
+ 0x0003, 0x0150, 0x0000, 0x0db8, 0x0012, 0x0345, 0x000b, 0x11d7,
+ 0x0002, 0x033f, 0x0014, 0x03c2, 0x0003, 0x014e, 0x0002, 0x033f,
+ 0x0002, 0xff27, 0x0014, 0x03c2, 0x0014, 0x0925, 0x0003, 0x014e,
+ 0x0015, 0x00b8, 0x0000, 0x0001, 0x0015, 0x003a, 0x0010, 0x0101,
+ 0x0014, 0x0925, 0x0003, 0x015f, 0x0001, 0x2bd8, 0x0010, 0x0000,
+ 0x0000, 0xffba, 0x0003, 0xb1e5, 0x0005, 0x002a, 0x0000, 0x0002,
+ 0x0001, 0xbac8, 0x0000, 0x0700, 0x000b, 0x12d2, 0x0011, 0x15e8,
+ 0x0000, 0x0002, 0x0013, 0x1248, 0x0011, 0x15e8, 0x0000, 0x0001,
+ 0x0003, 0x11f4, 0x0005, 0x0015, 0x0010, 0x0000, 0x0003, 0x022b,
+ 0x0005, 0x0015, 0x0010, 0x0000, 0x0002, 0xba43, 0x0003, 0x122c,
+ 0x0003, 0xb1f8, 0x0005, 0x002a, 0x0000, 0x0004, 0x0012, 0xba42,
+ 0x0003, 0x1232, 0x0012, 0x104b, 0x000b, 0x122b, 0x0000, 0x1a30,
0x0005, 0x0031, 0x0000, 0x0002, 0x0015, 0x0033, 0x0000, 0x1b2a,
- 0x001b, 0x82dc, 0x0015, 0x00b8, 0x0000, 0x0004, 0x0014, 0x091f,
- 0x0000, 0x13b8, 0x0015, 0x003a, 0x0010, 0x0404, 0x0014, 0x091f,
- 0x0013, 0x0039, 0x0002, 0x1e00, 0x0010, 0xff1e, 0x0012, 0x1d10,
- 0x0010, 0xff1d, 0x0010, 0xc030, 0x0000, 0xff31, 0x0015, 0x0033,
- 0x0000, 0xb009, 0x000b, 0x82ed, 0x0010, 0xb0fe, 0x000b, 0x6312,
- 0x0000, 0x1cff, 0x0001, 0x1ae0, 0x0013, 0x12fc, 0x0000, 0x1c30,
- 0x0005, 0x0031, 0x0010, 0x0000, 0x0015, 0x0033, 0x0000, 0xb009,
- 0x001b, 0x82f8, 0x0010, 0xb0fe, 0x001b, 0x62fc, 0x0000, 0x1aff,
- 0x0000, 0xff1c, 0x0000, 0x1c30, 0x0005, 0x0031, 0x0000, 0x0019,
- 0x0015, 0x0033, 0x0000, 0xb009, 0x000b, 0x8302, 0x0001, 0xb0c8,
- 0x0010, 0x000f, 0x0000, 0xff1f, 0x0001, 0xbf80, 0x0010, 0xff1d,
+ 0x001b, 0x8204, 0x0011, 0x20d8, 0x0010, 0x0000, 0x0000, 0xffb0,
+ 0x0001, 0x21d8, 0x0010, 0x0000, 0x0010, 0xffb1, 0x0001, 0x22d8,
+ 0x0010, 0x0000, 0x0010, 0xffb2, 0x0011, 0x23d8, 0x0010, 0x0000,
+ 0x0000, 0xffb3, 0x0001, 0x24d8, 0x0010, 0x0000, 0x0010, 0xffb4,
+ 0x0011, 0x25d8, 0x0010, 0x0000, 0x0000, 0xffb5, 0x0001, 0x28d8,
+ 0x0010, 0x0000, 0x0010, 0xffb8, 0x0011, 0x29d8, 0x0010, 0x0000,
+ 0x0000, 0xffb9, 0x0000, 0x1a30, 0x0005, 0x0031, 0x0000, 0x0007,
+ 0x0015, 0x0033, 0x0010, 0xb032, 0x000b, 0x8222, 0x0000, 0x1a30,
+ 0x0005, 0x0031, 0x0010, 0x000f, 0x0015, 0x0033, 0x0010, 0xb812,
+ 0x000b, 0x8228, 0x0005, 0x0015, 0x0010, 0x0000, 0x0013, 0x0035,
+ 0x0000, 0x1efe, 0x0013, 0x6240, 0x0014, 0x0277, 0x0000, 0x1efe,
+ 0x000c, 0x6277, 0x0003, 0x022b, 0x0000, 0x1a30, 0x0005, 0x0031,
+ 0x0000, 0x0020, 0x0015, 0x0033, 0x0000, 0xb009, 0x001b, 0x8237,
+ 0x0002, 0xb02f, 0x0000, 0xffb0, 0x0005, 0x0031, 0x0000, 0x0020,
+ 0x0015, 0x0033, 0x0000, 0xb00a, 0x001b, 0x823e, 0x0003, 0x01ff,
+ 0x0015, 0x00b8, 0x0010, 0x0005, 0x0014, 0x0925, 0x0000, 0x13b8,
+ 0x0015, 0x003a, 0x0010, 0x0404, 0x0014, 0x0925, 0x0003, 0x022b,
+ 0x0005, 0x0015, 0x0000, 0x0001, 0x0012, 0xba42, 0x0013, 0x1256,
+ 0x0003, 0xb24c, 0x0001, 0x2bd8, 0x0010, 0x0000, 0x0012, 0xff4f,
+ 0x000b, 0x11e2, 0x0002, 0xba43, 0x001b, 0x1232, 0x0000, 0x1efe,
+ 0x000c, 0x6277, 0x0003, 0x022b, 0x0001, 0x28d8, 0x0010, 0x0000,
+ 0x0010, 0xffb8, 0x0011, 0x29d8, 0x0010, 0x0000, 0x0000, 0xffb9,
+ 0x0014, 0x02e8, 0x0002, 0x3a42, 0x000b, 0x122b, 0x0000, 0x1c30,
+ 0x0015, 0x00ff, 0x0000, 0x0002, 0x0002, 0x1f43, 0x001b, 0x1267,
+ 0x0001, 0xff88, 0x0000, 0x0002, 0x0003, 0x0269, 0x0001, 0xff88,
+ 0x0000, 0x0004, 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb011,
+ 0x000b, 0x826c, 0x0000, 0xb0ff, 0x0011, 0x16a0, 0x0000, 0xff16,
+ 0x001b, 0x2273, 0x0002, 0xb100, 0x0003, 0x0274, 0x0010, 0xb1ff,
+ 0x0001, 0x17a0, 0x0010, 0xff17, 0x0013, 0x0232, 0x0000, 0x16ff,
+ 0x0001, 0x18a0, 0x0010, 0xff00, 0x000b, 0x227e, 0x0002, 0x1700,
+ 0x0013, 0x12d1, 0x0013, 0x027f, 0x0010, 0x17ff, 0x0011, 0x19a0,
+ 0x0013, 0x22d1, 0x0011, 0x00d0, 0x0013, 0x12d1, 0x0000, 0x1c30,
+ 0x0000, 0x1b31, 0x0015, 0x0033, 0x0000, 0xb131, 0x000b, 0x8287,
+ 0x0013, 0xb288, 0x0000, 0xb120, 0x0010, 0xb221, 0x0002, 0x1f43,
+ 0x001b, 0x1294, 0x0010, 0xc022, 0x0000, 0xc023, 0x0000, 0xb324,
+ 0x0000, 0xb425, 0x0010, 0xb3b5, 0x0000, 0xb4b6, 0x0013, 0x0298,
+ 0x0000, 0xb322, 0x0000, 0xb423, 0x0000, 0xb524, 0x0010, 0xb625,
+ 0x0003, 0xb298, 0x0005, 0x002a, 0x0000, 0x0001, 0x0012, 0x1500,
+ 0x0000, 0xff15, 0x0000, 0x16ff, 0x0001, 0xb580, 0x0000, 0xff16,
+ 0x000b, 0x22a3, 0x0002, 0x1700, 0x0013, 0x02a4, 0x0010, 0x17ff,
+ 0x0001, 0xb680, 0x0010, 0xff17, 0x0012, 0x1e10, 0x0010, 0xff1e,
+ 0x0003, 0x62d1, 0x0002, 0x1d00, 0x0010, 0xff1d, 0x0010, 0xc030,
+ 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb009, 0x000b, 0x82af,
+ 0x0010, 0xb0fe, 0x000b, 0x62d0, 0x0000, 0x1c30, 0x0005, 0x0031,
+ 0x0000, 0x0001, 0x0015, 0x0033, 0x0000, 0xb009, 0x000b, 0x82b7,
+ 0x0010, 0xb0fe, 0x001b, 0x62bd, 0x0005, 0x00ce, 0x0010, 0x0005,
+ 0x0003, 0x08e7, 0x0010, 0xb01c, 0x0000, 0x1c30, 0x0005, 0x0031,
+ 0x0000, 0x0019, 0x0015, 0x0033, 0x0000, 0xb009, 0x000b, 0x82c3,
+ 0x0001, 0xb0c8, 0x0010, 0x00ff, 0x0000, 0xff1f, 0x0010, 0xc030,
+ 0x0011, 0xbe80, 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb009,
+ 0x000b, 0x82cc, 0x0000, 0xb01d, 0x0010, 0x1dff, 0x0013, 0x02ab,
+ 0x0000, 0xb01b, 0x0017, 0x4000, 0x0002, 0x3a41, 0x0003, 0x12da,
+ 0x0013, 0xb2d4, 0x0005, 0x002a, 0x0000, 0x0004, 0x0005, 0x0015,
+ 0x0010, 0x0000, 0x0003, 0x022b, 0x0000, 0x1a30, 0x0005, 0x0031,
+ 0x0000, 0x0002, 0x0015, 0x0033, 0x0000, 0x1b2a, 0x001b, 0x82df,
+ 0x0015, 0x00b8, 0x0000, 0x0004, 0x0014, 0x0925, 0x0000, 0x13b8,
+ 0x0015, 0x003a, 0x0010, 0x0404, 0x0014, 0x0925, 0x0013, 0x0039,
+ 0x0002, 0x1e00, 0x0010, 0xff1e, 0x0012, 0x1d10, 0x0010, 0xff1d,
0x0010, 0xc030, 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb009,
- 0x001b, 0x830c, 0x0010, 0xb0fe, 0x000b, 0x6312, 0x0005, 0x00ce,
- 0x0010, 0x0006, 0x0003, 0x08e1, 0x0000, 0xb01b, 0x0017, 0x4000,
- 0x0010, 0x79b0, 0x0000, 0xd0ff, 0x0012, 0xff40, 0x001b, 0x1039,
- 0x0015, 0x00d1, 0x0010, 0x0101, 0x0003, 0x931a, 0x0005, 0x0079,
- 0x0000, 0x0002, 0x0013, 0x931d, 0x0015, 0x00d1, 0x0000, 0x0100,
- 0x0010, 0x13fe, 0x0003, 0x636b, 0x0012, 0xb04e, 0x000b, 0x1394,
- 0x0000, 0x78b0, 0x0002, 0xb045, 0x0003, 0x139a, 0x0012, 0x784a,
- 0x0003, 0x139a, 0x0000, 0x75ff, 0x0011, 0xffc8, 0x0010, 0x1800,
- 0x001b, 0x139a, 0x0001, 0x0fe8, 0x0000, 0x0001, 0x001b, 0x1339,
- 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x1388, 0x0000, 0x000e,
- 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0x8f0a, 0x000b, 0x8337,
- 0x0013, 0x03a0, 0x0001, 0x0fe8, 0x0000, 0x0002, 0x001b, 0x1344,
- 0x0015, 0x0030, 0x0000, 0x0400, 0x0005, 0x0031, 0x0000, 0x001a,
- 0x0015, 0x0033, 0x0010, 0xc00a, 0x001b, 0x8342, 0x0013, 0x03a0,
- 0x0001, 0x0fe8, 0x0010, 0x0000, 0x0003, 0x134b, 0x0005, 0x00ce,
- 0x0000, 0x0007, 0x0010, 0x0fcf, 0x0003, 0x08db, 0x0002, 0xd142,
- 0x0013, 0x1361, 0x0015, 0x00d1, 0x0000, 0x0400, 0x0005, 0x0031,
- 0x0011, 0x1b6e, 0x0015, 0x0033, 0x0010, 0xb409, 0x001b, 0x8353,
- 0x0002, 0xb400, 0x0010, 0xffb4, 0x0005, 0x0031, 0x0011, 0x1b6e,
- 0x0015, 0x0033, 0x0010, 0xb40a, 0x001b, 0x835a, 0x0012, 0xd042,
- 0x0013, 0x136b, 0x0015, 0x00b8, 0x0000, 0x000d, 0x0014, 0x091f,
- 0x0003, 0x0054, 0x0000, 0x13b8, 0x0002, 0x1045, 0x0003, 0x1369,
- 0x0012, 0x103f, 0x0002, 0xff27, 0x0014, 0x03bc, 0x0014, 0x091f,
- 0x0003, 0x036b, 0x0012, 0x103f, 0x0014, 0x03bc, 0x0015, 0x000f,
- 0x0010, 0x0000, 0x0002, 0x3944, 0x0003, 0x1374, 0x0015, 0x0039,
- 0x0000, 0x5040, 0x0015, 0x00b8, 0x0000, 0x0008, 0x0014, 0x091f,
- 0x0015, 0x0030, 0x0000, 0x0400, 0x0001, 0xbd88, 0x0010, 0x000c,
- 0x0000, 0xff31, 0x0015, 0x0033, 0x0010, 0xc00a, 0x001b, 0x837b,
- 0x0000, 0xff31, 0x0015, 0x0033, 0x0010, 0xc00a, 0x000b, 0x837f,
- 0x0010, 0xc014, 0x0000, 0xc013, 0x0000, 0xc010, 0x0000, 0xa4ff,
- 0x0003, 0x638c, 0x0011, 0xffa8, 0x0010, 0x0005, 0x000b, 0x238c,
- 0x0015, 0x00d1, 0x0010, 0x0404, 0x0015, 0x003a, 0x0000, 0x8000,
- 0x0002, 0x3a47, 0x0003, 0x1393, 0x0015, 0x003a, 0x0000, 0x8000,
- 0x0015, 0x003a, 0x0010, 0x4040, 0x0004, 0x08e6, 0x0013, 0x0039,
- 0x0015, 0x00b8, 0x0010, 0x0003, 0x0015, 0x003a, 0x0010, 0x0202,
- 0x0014, 0x091f, 0x0003, 0x0383, 0x0015, 0x00b8, 0x0000, 0x0002,
- 0x0015, 0x003a, 0x0010, 0x0202, 0x0014, 0x091f, 0x0003, 0x0383,
- 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x1388, 0x0010, 0x0003,
- 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb009, 0x000b, 0x83a7,
+ 0x000b, 0x82f0, 0x0010, 0xb0fe, 0x001b, 0x6315, 0x0000, 0x1cff,
+ 0x0001, 0x1ae0, 0x0013, 0x12ff, 0x0000, 0x1c30, 0x0005, 0x0031,
+ 0x0010, 0x0000, 0x0015, 0x0033, 0x0000, 0xb009, 0x001b, 0x82fb,
+ 0x0010, 0xb0fe, 0x001b, 0x62ff, 0x0000, 0x1aff, 0x0000, 0xff1c,
+ 0x0000, 0x1c30, 0x0005, 0x0031, 0x0000, 0x0019, 0x0015, 0x0033,
+ 0x0000, 0xb009, 0x001b, 0x8305, 0x0001, 0xb0c8, 0x0010, 0x000f,
+ 0x0000, 0xff1f, 0x0001, 0xbf80, 0x0010, 0xff1d, 0x0010, 0xc030,
+ 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb009, 0x001b, 0x830f,
+ 0x0010, 0xb0fe, 0x001b, 0x6315, 0x0005, 0x00ce, 0x0010, 0x0006,
+ 0x0003, 0x08e7, 0x0000, 0xb01b, 0x0017, 0x4000, 0x0010, 0x79b0,
+ 0x0000, 0xd0ff, 0x0012, 0xff40, 0x001b, 0x1039, 0x0015, 0x00d1,
+ 0x0010, 0x0101, 0x0013, 0x931d, 0x0005, 0x0079, 0x0000, 0x0002,
+ 0x0003, 0x9320, 0x0015, 0x00d1, 0x0000, 0x0100, 0x0010, 0x13fe,
+ 0x0013, 0x6371, 0x0012, 0xb04e, 0x001b, 0x139a, 0x0000, 0x78b0,
+ 0x0002, 0xb045, 0x0003, 0x13a0, 0x0012, 0x784a, 0x0003, 0x13a0,
+ 0x0000, 0x75ff, 0x0011, 0xffc8, 0x0010, 0x1800, 0x001b, 0x13a0,
+ 0x0001, 0x0fe8, 0x0000, 0x0001, 0x001b, 0x133c, 0x0015, 0x0030,
+ 0x0000, 0x0400, 0x0011, 0x1388, 0x0000, 0x000e, 0x0000, 0xff31,
+ 0x0015, 0x0033, 0x0000, 0x8f0a, 0x001b, 0x833a, 0x0013, 0x03a6,
+ 0x0001, 0x0fe8, 0x0000, 0x0002, 0x001b, 0x1347, 0x0015, 0x0030,
+ 0x0000, 0x0400, 0x0005, 0x0031, 0x0000, 0x001a, 0x0015, 0x0033,
+ 0x0010, 0xc00a, 0x000b, 0x8345, 0x0013, 0x03a6, 0x0001, 0x0fe8,
+ 0x0010, 0x0000, 0x0003, 0x134e, 0x0005, 0x00ce, 0x0000, 0x0007,
+ 0x0010, 0x0fcf, 0x0003, 0x08e1, 0x0002, 0xd142, 0x0013, 0x1367,
+ 0x0015, 0x00d1, 0x0000, 0x0400, 0x0011, 0x13e8, 0x0001, 0x1b56,
+ 0x000b, 0x1367, 0x0005, 0x0031, 0x0011, 0x1b6e, 0x0015, 0x0033,
+ 0x0010, 0xb409, 0x001b, 0x8359, 0x0002, 0xb400, 0x0010, 0xffb4,
+ 0x0005, 0x0031, 0x0011, 0x1b6e, 0x0015, 0x0033, 0x0010, 0xb40a,
+ 0x001b, 0x8360, 0x0012, 0xd042, 0x0003, 0x1371, 0x0015, 0x00b8,
+ 0x0000, 0x000d, 0x0014, 0x0925, 0x0003, 0x0054, 0x0000, 0x13b8,
+ 0x0002, 0x1045, 0x0003, 0x136f, 0x0012, 0x103f, 0x0002, 0xff27,
+ 0x0014, 0x03c2, 0x0014, 0x0925, 0x0013, 0x0371, 0x0012, 0x103f,
+ 0x0014, 0x03c2, 0x0015, 0x000f, 0x0010, 0x0000, 0x0002, 0x3944,
+ 0x0013, 0x137a, 0x0015, 0x0039, 0x0000, 0x5040, 0x0015, 0x00b8,
+ 0x0000, 0x0008, 0x0014, 0x0925, 0x0015, 0x0030, 0x0000, 0x0400,
+ 0x0001, 0xbd88, 0x0010, 0x000c, 0x0000, 0xff31, 0x0015, 0x0033,
+ 0x0010, 0xc00a, 0x001b, 0x8381, 0x0000, 0xff31, 0x0015, 0x0033,
+ 0x0010, 0xc00a, 0x000b, 0x8385, 0x0010, 0xc014, 0x0000, 0xc013,
+ 0x0000, 0xc010, 0x0000, 0xa4ff, 0x0003, 0x6392, 0x0011, 0xffa8,
+ 0x0010, 0x0005, 0x000b, 0x2392, 0x0015, 0x00d1, 0x0010, 0x0404,
+ 0x0015, 0x003a, 0x0000, 0x8000, 0x0002, 0x3a47, 0x0003, 0x1399,
+ 0x0015, 0x003a, 0x0000, 0x8000, 0x0015, 0x003a, 0x0010, 0x4040,
+ 0x0004, 0x08ec, 0x0013, 0x0039, 0x0015, 0x00b8, 0x0010, 0x0003,
+ 0x0015, 0x003a, 0x0010, 0x0202, 0x0014, 0x0925, 0x0003, 0x0389,
+ 0x0015, 0x00b8, 0x0000, 0x0002, 0x0015, 0x003a, 0x0010, 0x0202,
+ 0x0014, 0x0925, 0x0003, 0x0389, 0x0015, 0x0030, 0x0000, 0x0400,
0x0011, 0x1388, 0x0010, 0x0003, 0x0000, 0xff31, 0x0015, 0x0033,
- 0x0010, 0xc00a, 0x000b, 0x83ad, 0x0010, 0xb0fe, 0x0013, 0x63b2,
- 0x0000, 0xb012, 0x0013, 0x03b4, 0x0010, 0xc012, 0x0010, 0xc011,
- 0x0012, 0x104b, 0x0003, 0x134b, 0x0002, 0x103b, 0x0010, 0xff03,
- 0x0005, 0x0002, 0x0010, 0x0000, 0x0000, 0xc00d, 0x0013, 0x034b,
- 0x0000, 0xffb0, 0x0010, 0xc3b1, 0x0015, 0x0030, 0x0000, 0x0400,
- 0x0001, 0xb888, 0x0010, 0x0011, 0x0000, 0xff31, 0x0015, 0x0033,
- 0x0000, 0xb012, 0x001b, 0x83c5, 0x0017, 0x4000, 0x0002, 0xd142,
- 0x001b, 0x147f, 0x0012, 0x3a43, 0x0003, 0x13d8, 0x0015, 0x003a,
- 0x0000, 0x0800, 0x0010, 0x0db0, 0x0013, 0x63d8, 0x0000, 0x0bff,
- 0x0001, 0xb0e0, 0x0003, 0x1401, 0x0010, 0x09ff, 0x0001, 0xb0e0,
- 0x0013, 0x13e5, 0x0010, 0x05ff, 0x0001, 0xb0e0, 0x0013, 0x13dc,
- 0x0000, 0xc00e, 0x0000, 0x05fe, 0x0013, 0x63e2, 0x0000, 0x050d,
- 0x0005, 0x0002, 0x0000, 0x0004, 0x0014, 0x0466, 0x0002, 0x3a47,
- 0x000b, 0x1465, 0x0013, 0x03fc, 0x0000, 0x09fe, 0x0003, 0x63fe,
- 0x0000, 0x090d, 0x0005, 0x0002, 0x0000, 0x0001, 0x0004, 0x0494,
- 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x0d88, 0x0000, 0x0004,
- 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xba09, 0x000b, 0x83ef,
- 0x0011, 0x03c8, 0x0010, 0x000f, 0x0000, 0xffb6, 0x0011, 0xb6e8,
- 0x0000, 0x0001, 0x0003, 0x1539, 0x0011, 0xb6e8, 0x0000, 0x0002,
- 0x0013, 0x155b, 0x0011, 0xb6e8, 0x0010, 0x0003, 0x0003, 0x164d,
- 0x0004, 0x08e6, 0x0003, 0x0465, 0x0010, 0x0bfe, 0x0003, 0x6465,
- 0x0010, 0x0b0d, 0x0005, 0x0002, 0x0000, 0x0002, 0x0004, 0x0494,
- 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x0d88, 0x0000, 0x0004,
- 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xba09, 0x001b, 0x840b,
- 0x0000, 0xb930, 0x0005, 0x0031, 0x0010, 0x0021, 0x0015, 0x0033,
- 0x0000, 0xb009, 0x000b, 0x8411, 0x0001, 0xb0a8, 0x0000, 0x199a,
- 0x0013, 0x2417, 0x0005, 0x00b0, 0x0000, 0x1999, 0x0012, 0xb050,
- 0x0000, 0xffb0, 0x0002, 0xff50, 0x0002, 0xff50, 0x0001, 0xb080,
- 0x0000, 0xffb0, 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x0d88,
- 0x0010, 0x0006, 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb00a,
- 0x000b, 0x8424, 0x0000, 0xb930, 0x0005, 0x0031, 0x0000, 0x0019,
- 0x0015, 0x0033, 0x0000, 0xb009, 0x001b, 0x842a, 0x0001, 0xb0c8,
- 0x0010, 0x00ff, 0x0001, 0xffe8, 0x0010, 0x0048, 0x000b, 0x14a3,
- 0x0005, 0x0002, 0x0010, 0x0006, 0x0012, 0x0c10, 0x0010, 0xff0c,
- 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x0d88, 0x0010, 0x0003,
- 0x0000, 0xff31, 0x0015, 0x0033, 0x0010, 0xb109, 0x001b, 0x843b,
- 0x0000, 0xb10b, 0x001b, 0x643f, 0x0010, 0xb10a, 0x0015, 0x0033,
- 0x0010, 0xc00a, 0x000b, 0x8441, 0x0002, 0x032b, 0x0010, 0xff03,
+ 0x0000, 0xb009, 0x000b, 0x83ad, 0x0011, 0x1388, 0x0010, 0x0003,
+ 0x0000, 0xff31, 0x0015, 0x0033, 0x0010, 0xc00a, 0x000b, 0x83b3,
+ 0x0010, 0xb0fe, 0x0013, 0x63b8, 0x0000, 0xb012, 0x0003, 0x03ba,
+ 0x0010, 0xc012, 0x0010, 0xc011, 0x0012, 0x104b, 0x0003, 0x134e,
+ 0x0002, 0x103b, 0x0010, 0xff03, 0x0005, 0x0002, 0x0010, 0x0000,
+ 0x0000, 0xc00d, 0x0013, 0x034e, 0x0000, 0xffb0, 0x0010, 0xc3b1,
+ 0x0015, 0x0030, 0x0000, 0x0400, 0x0001, 0xb888, 0x0010, 0x0011,
+ 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb012, 0x000b, 0x83cb,
+ 0x0017, 0x4000, 0x0002, 0xd142, 0x001b, 0x1485, 0x0012, 0x3a43,
+ 0x0003, 0x13de, 0x0015, 0x003a, 0x0000, 0x0800, 0x0010, 0x0db0,
+ 0x0013, 0x63de, 0x0000, 0x0bff, 0x0001, 0xb0e0, 0x0003, 0x1407,
+ 0x0010, 0x09ff, 0x0001, 0xb0e0, 0x0003, 0x13eb, 0x0010, 0x05ff,
+ 0x0001, 0xb0e0, 0x0003, 0x13e2, 0x0000, 0xc00e, 0x0000, 0x05fe,
+ 0x0013, 0x63e8, 0x0000, 0x050d, 0x0005, 0x0002, 0x0000, 0x0004,
+ 0x0014, 0x046c, 0x0002, 0x3a47, 0x001b, 0x146b, 0x0013, 0x0402,
+ 0x0000, 0x09fe, 0x0013, 0x6404, 0x0000, 0x090d, 0x0005, 0x0002,
+ 0x0000, 0x0001, 0x0014, 0x049a, 0x0015, 0x0030, 0x0000, 0x0400,
+ 0x0011, 0x0d88, 0x0000, 0x0004, 0x0000, 0xff31, 0x0015, 0x0033,
+ 0x0000, 0xba09, 0x001b, 0x83f5, 0x0011, 0x03c8, 0x0010, 0x000f,
+ 0x0000, 0xffb6, 0x0011, 0xb6e8, 0x0000, 0x0001, 0x0003, 0x153f,
+ 0x0011, 0xb6e8, 0x0000, 0x0002, 0x0013, 0x1561, 0x0011, 0xb6e8,
+ 0x0010, 0x0003, 0x0003, 0x1653, 0x0004, 0x08ec, 0x0013, 0x046b,
+ 0x0010, 0x0bfe, 0x0013, 0x646b, 0x0010, 0x0b0d, 0x0005, 0x0002,
+ 0x0000, 0x0002, 0x0014, 0x049a, 0x0015, 0x0030, 0x0000, 0x0400,
+ 0x0011, 0x0d88, 0x0000, 0x0004, 0x0000, 0xff31, 0x0015, 0x0033,
+ 0x0000, 0xba09, 0x000b, 0x8411, 0x0000, 0xb930, 0x0005, 0x0031,
+ 0x0010, 0x0021, 0x0015, 0x0033, 0x0000, 0xb009, 0x000b, 0x8417,
+ 0x0001, 0xb0a8, 0x0000, 0x199a, 0x0013, 0x241d, 0x0005, 0x00b0,
+ 0x0000, 0x1999, 0x0012, 0xb050, 0x0000, 0xffb0, 0x0002, 0xff50,
+ 0x0002, 0xff50, 0x0001, 0xb080, 0x0000, 0xffb0, 0x0015, 0x0030,
+ 0x0000, 0x0400, 0x0011, 0x0d88, 0x0010, 0x0006, 0x0000, 0xff31,
+ 0x0015, 0x0033, 0x0000, 0xb00a, 0x001b, 0x842a, 0x0000, 0xb930,
+ 0x0005, 0x0031, 0x0000, 0x0019, 0x0015, 0x0033, 0x0000, 0xb009,
+ 0x000b, 0x8430, 0x0001, 0xb0c8, 0x0010, 0x00ff, 0x0001, 0xffe8,
+ 0x0010, 0x0048, 0x000b, 0x14a9, 0x0005, 0x0002, 0x0010, 0x0006,
+ 0x0012, 0x0c10, 0x0010, 0xff0c, 0x0015, 0x0030, 0x0000, 0x0400,
+ 0x0011, 0x0d88, 0x0010, 0x0003, 0x0000, 0xff31, 0x0015, 0x0033,
+ 0x0010, 0xb109, 0x000b, 0x8441, 0x0000, 0xb10b, 0x000b, 0x6445,
+ 0x0010, 0xb10a, 0x0015, 0x0033, 0x0010, 0xc00a, 0x000b, 0x8447,
+ 0x0002, 0x032b, 0x0010, 0xff03, 0x0011, 0x0d88, 0x0010, 0x0011,
+ 0x0000, 0xff31, 0x0015, 0x0033, 0x0010, 0x030a, 0x001b, 0x844f,
+ 0x0000, 0x11fe, 0x000b, 0x6454, 0x0000, 0x0d12, 0x0013, 0x045d,
+ 0x0015, 0x0030, 0x0000, 0x0400, 0x0001, 0x1188, 0x0010, 0x0003,
+ 0x0000, 0xff31, 0x0010, 0x0db0, 0x0015, 0x0033, 0x0000, 0xb00a,
+ 0x000b, 0x845c, 0x0000, 0x0d11, 0x0013, 0x046b, 0x0002, 0xd142,
+ 0x0003, 0x1462, 0x0013, 0x0485, 0x0000, 0x05fe, 0x0013, 0x646b,
+ 0x0005, 0x0002, 0x0000, 0x0004, 0x0000, 0x050d, 0x0014, 0x046c,
+ 0x0002, 0x3a47, 0x001b, 0x146b, 0x0004, 0x08ec, 0x0013, 0x0047,
+ 0x0001, 0xc7c8, 0x0010, 0x0028, 0x000b, 0x1484, 0x0015, 0x0030,
+ 0x0000, 0x0400, 0x0011, 0x0d88, 0x0010, 0x000a, 0x0000, 0xff31,
+ 0x0015, 0x0033, 0x0000, 0xb009, 0x001b, 0x8476, 0x0002, 0xb04f,
+ 0x0013, 0x1484, 0x0001, 0x0fe8, 0x0010, 0x0000, 0x0013, 0x1482,
+ 0x0001, 0x0fe8, 0x0000, 0x0002, 0x0013, 0x1482, 0x0015, 0x003a,
+ 0x0010, 0x8080, 0x0003, 0x0484, 0x0015, 0x003a, 0x0010, 0x4040,
+ 0x0017, 0x4000, 0x0000, 0x12fe, 0x001b, 0x604f, 0x0015, 0x0012,
+ 0x0001, 0x1b56, 0x0015, 0x0011, 0x0001, 0x1b56, 0x0001, 0x1288,
+ 0x0010, 0x0003, 0x0000, 0xff31, 0x0015, 0x0033, 0x0010, 0xc00a,
+ 0x000b, 0x8490, 0x0005, 0x00b0, 0x0000, 0x8000, 0x0001, 0x1288,
+ 0x0010, 0x0011, 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb00a,
+ 0x001b, 0x8498, 0x0003, 0x004f, 0x0015, 0x0030, 0x0000, 0x0400,
0x0011, 0x0d88, 0x0010, 0x0011, 0x0000, 0xff31, 0x0015, 0x0033,
- 0x0010, 0x030a, 0x001b, 0x8449, 0x0000, 0x11fe, 0x001b, 0x644e,
- 0x0000, 0x0d12, 0x0013, 0x0457, 0x0015, 0x0030, 0x0000, 0x0400,
- 0x0001, 0x1188, 0x0010, 0x0003, 0x0000, 0xff31, 0x0010, 0x0db0,
- 0x0015, 0x0033, 0x0000, 0xb00a, 0x000b, 0x8456, 0x0000, 0x0d11,
- 0x0003, 0x0465, 0x0002, 0xd142, 0x0013, 0x145c, 0x0013, 0x047f,
- 0x0000, 0x05fe, 0x0003, 0x6465, 0x0005, 0x0002, 0x0000, 0x0004,
- 0x0000, 0x050d, 0x0014, 0x0466, 0x0002, 0x3a47, 0x000b, 0x1465,
- 0x0004, 0x08e6, 0x0013, 0x0047, 0x0001, 0xc7c8, 0x0010, 0x0028,
- 0x000b, 0x147e, 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x0d88,
- 0x0010, 0x000a, 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb009,
- 0x001b, 0x8470, 0x0002, 0xb04f, 0x0013, 0x147e, 0x0001, 0x0fe8,
- 0x0010, 0x0000, 0x0003, 0x147c, 0x0001, 0x0fe8, 0x0000, 0x0002,
- 0x0003, 0x147c, 0x0015, 0x003a, 0x0010, 0x8080, 0x0003, 0x047e,
- 0x0015, 0x003a, 0x0010, 0x4040, 0x0017, 0x4000, 0x0000, 0x12fe,
- 0x001b, 0x604f, 0x0015, 0x0012, 0x0001, 0x1b56, 0x0015, 0x0011,
- 0x0001, 0x1b56, 0x0001, 0x1288, 0x0010, 0x0003, 0x0000, 0xff31,
- 0x0015, 0x0033, 0x0010, 0xc00a, 0x001b, 0x848a, 0x0005, 0x00b0,
- 0x0000, 0x8000, 0x0001, 0x1288, 0x0010, 0x0011, 0x0000, 0xff31,
- 0x0015, 0x0033, 0x0000, 0xb00a, 0x001b, 0x8492, 0x0003, 0x004f,
- 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x0d88, 0x0010, 0x0011,
- 0x0000, 0xff31, 0x0015, 0x0033, 0x0010, 0x0309, 0x001b, 0x849b,
- 0x0011, 0x0d88, 0x0010, 0x0005, 0x0000, 0xff31, 0x0015, 0x0033,
- 0x0000, 0xb909, 0x001b, 0x84a1, 0x0017, 0x4000, 0x0005, 0x00b6,
- 0x0010, 0x0600, 0x0004, 0x067d, 0x0014, 0x0515, 0x0000, 0xb05a,
- 0x0000, 0xb15b, 0x0005, 0x0054, 0x0010, 0x0829, 0x0010, 0x0d58,
- 0x0015, 0x0059, 0x0010, 0xffff, 0x0000, 0xb930, 0x0005, 0x0031,
- 0x0010, 0x001e, 0x0015, 0x0033, 0x0000, 0xb009, 0x001b, 0x84b3,
- 0x0000, 0xb05c, 0x0005, 0x0031, 0x0000, 0x001f, 0x0015, 0x0033,
- 0x0000, 0xb009, 0x001b, 0x84b9, 0x0001, 0xb0c8, 0x0010, 0x000f,
- 0x000b, 0x14c0, 0x0015, 0x00ff, 0x0010, 0x0005, 0x0013, 0x04c8,
- 0x0002, 0xb040, 0x0013, 0x14c5, 0x0015, 0x00ff, 0x0000, 0x0004,
- 0x0013, 0x04c8, 0x0001, 0xb0c8, 0x0010, 0x0006, 0x0002, 0xff60,
- 0x0010, 0xffb2, 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x0d88,
- 0x0000, 0x0019, 0x0000, 0xff31, 0x0015, 0x0033, 0x0010, 0xb109,
- 0x001b, 0x84d0, 0x0012, 0xb170, 0x0011, 0xffc8, 0x0010, 0xff00,
- 0x0011, 0xb2d0, 0x0010, 0xff60, 0x0002, 0xb045, 0x0013, 0x14db,
- 0x0015, 0x00b2, 0x0000, 0x0002, 0x0013, 0x04e5, 0x0002, 0xb046,
- 0x0003, 0x14e0, 0x0015, 0x00b2, 0x0000, 0x0001, 0x0013, 0x04e5,
- 0x0015, 0x00b2, 0x0010, 0x0000, 0x0000, 0xc0b0, 0x0010, 0xc0b1,
- 0x0003, 0x04eb, 0x0000, 0xb930, 0x0005, 0x0031, 0x0010, 0x002b,
- 0x0015, 0x0033, 0x0000, 0xb011, 0x001b, 0x84ea, 0x0010, 0xb16a,
- 0x0010, 0xb06b, 0x0000, 0xb261, 0x0015, 0x0044, 0x0010, 0x0018,
- 0x0000, 0xb930, 0x0005, 0x0031, 0x0000, 0x0023, 0x0015, 0x0033,
- 0x0000, 0x6241, 0x000b, 0x84f5, 0x0003, 0x94f6, 0x0015, 0x00a0,
- 0x0000, 0x0020, 0x0012, 0xd041, 0x000b, 0x14f9, 0x0015, 0x00d1,
- 0x0010, 0x0202, 0x0013, 0x94fd, 0x0000, 0x75ff, 0x0011, 0xffc8,
- 0x0000, 0x1804, 0x0001, 0xffd8, 0x0010, 0x0009, 0x0013, 0x9503,
- 0x0000, 0xff75, 0x0013, 0x9505, 0x0015, 0x00d1, 0x0000, 0x0200,
- 0x0015, 0x0030, 0x0000, 0x0400, 0x0001, 0xbd88, 0x0000, 0x0008,
- 0x0000, 0xff31, 0x0015, 0x00b1, 0x0010, 0x07d0, 0x0005, 0x00b0,
- 0x0010, 0x0009, 0x0015, 0x0033, 0x0000, 0xb012, 0x000b, 0x8513,
- 0x0003, 0x0465, 0x0000, 0xba30, 0x0005, 0x0031, 0x0010, 0x0035,
- 0x0015, 0x0033, 0x0000, 0xb009, 0x000b, 0x851a, 0x0002, 0xb040,
- 0x0003, 0x1536, 0x0015, 0x0030, 0x0000, 0x0400, 0x0005, 0x0031,
- 0x0001, 0x1b72, 0x0015, 0x0033, 0x0000, 0xb011, 0x000b, 0x8523,
- 0x0002, 0xb100, 0x0010, 0xffb1, 0x000b, 0x252a, 0x0012, 0xb000,
- 0x0000, 0xffb0, 0x0003, 0x2524, 0x0015, 0x0033, 0x0000, 0xb012,
- 0x000b, 0x852c, 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x0d88,
- 0x0000, 0x0013, 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb012,
- 0x000b, 0x8534, 0x0003, 0x0538, 0x0010, 0xc0b1, 0x0000, 0xc0b0,
- 0x0017, 0x4000, 0x0005, 0x00b6, 0x0010, 0x0500, 0x0004, 0x067d,
- 0x0005, 0x0054, 0x0010, 0x0889, 0x0015, 0x0030, 0x0000, 0x0400,
- 0x0011, 0x0d88, 0x0000, 0x0002, 0x0000, 0xff31, 0x0015, 0x0033,
- 0x0000, 0xb009, 0x000b, 0x8545, 0x0010, 0xb058, 0x0000, 0x0d59,
- 0x0000, 0xb930, 0x0005, 0x0031, 0x0000, 0x0023, 0x0015, 0x0033,
- 0x0000, 0xb011, 0x001b, 0x854d, 0x0010, 0xb15c, 0x0010, 0xb05d,
+ 0x0010, 0x0309, 0x001b, 0x84a1, 0x0011, 0x0d88, 0x0010, 0x0005,
+ 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb909, 0x001b, 0x84a7,
+ 0x0017, 0x4000, 0x0005, 0x00b6, 0x0010, 0x0600, 0x0014, 0x0683,
+ 0x0004, 0x051b, 0x0000, 0xb05a, 0x0000, 0xb15b, 0x0005, 0x0054,
+ 0x0010, 0x0829, 0x0010, 0x0d58, 0x0015, 0x0059, 0x0010, 0xffff,
+ 0x0000, 0xb930, 0x0005, 0x0031, 0x0010, 0x001e, 0x0015, 0x0033,
+ 0x0000, 0xb009, 0x001b, 0x84b9, 0x0000, 0xb05c, 0x0005, 0x0031,
+ 0x0000, 0x001f, 0x0015, 0x0033, 0x0000, 0xb009, 0x001b, 0x84bf,
+ 0x0001, 0xb0c8, 0x0010, 0x000f, 0x000b, 0x14c6, 0x0015, 0x00ff,
+ 0x0010, 0x0005, 0x0013, 0x04ce, 0x0002, 0xb040, 0x0003, 0x14cb,
+ 0x0015, 0x00ff, 0x0000, 0x0004, 0x0013, 0x04ce, 0x0001, 0xb0c8,
+ 0x0010, 0x0006, 0x0002, 0xff60, 0x0010, 0xffb2, 0x0015, 0x0030,
+ 0x0000, 0x0400, 0x0011, 0x0d88, 0x0000, 0x0019, 0x0000, 0xff31,
+ 0x0015, 0x0033, 0x0010, 0xb109, 0x001b, 0x84d6, 0x0012, 0xb170,
+ 0x0011, 0xffc8, 0x0010, 0xff00, 0x0011, 0xb2d0, 0x0010, 0xff60,
+ 0x0002, 0xb045, 0x0013, 0x14e1, 0x0015, 0x00b2, 0x0000, 0x0002,
+ 0x0003, 0x04eb, 0x0002, 0xb046, 0x0003, 0x14e6, 0x0015, 0x00b2,
+ 0x0000, 0x0001, 0x0003, 0x04eb, 0x0015, 0x00b2, 0x0010, 0x0000,
+ 0x0000, 0xc0b0, 0x0010, 0xc0b1, 0x0013, 0x04f1, 0x0000, 0xb930,
0x0005, 0x0031, 0x0010, 0x002b, 0x0015, 0x0033, 0x0000, 0xb011,
- 0x000b, 0x8554, 0x0000, 0xb15e, 0x0000, 0xb05f, 0x0003, 0x9557,
- 0x0015, 0x00a0, 0x0010, 0x000c, 0x0003, 0x0662, 0x0005, 0x00b6,
- 0x0000, 0x0700, 0x0004, 0x067d, 0x0015, 0x0030, 0x0000, 0x0400,
- 0x0011, 0x0d88, 0x0010, 0x0009, 0x0000, 0xff31, 0x0015, 0x0033,
- 0x0010, 0xb709, 0x001b, 0x8565, 0x0012, 0xb749, 0x0013, 0x156b,
- 0x0005, 0x0054, 0x0010, 0x0889, 0x0003, 0x056d, 0x0005, 0x0054,
- 0x0010, 0x0898, 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x0d88,
- 0x0000, 0x0002, 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb009,
- 0x001b, 0x8574, 0x0010, 0xb058, 0x0000, 0x0d59, 0x0001, 0xb9c8,
- 0x0010, 0xf000, 0x0001, 0xffe8, 0x0010, 0xf000, 0x000b, 0x159d,
- 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x0d88, 0x0010, 0x0005,
- 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb009, 0x000b, 0x8583,
- 0x0001, 0xb0c8, 0x0000, 0xf700, 0x0000, 0xffb0, 0x0011, 0xb0e8,
- 0x0000, 0xf100, 0x0003, 0x15e4, 0x0011, 0xb0e8, 0x0000, 0xf200,
- 0x0013, 0x15e9, 0x0011, 0xb0e8, 0x0010, 0xf300, 0x0013, 0x160e,
- 0x0011, 0xb0e8, 0x0000, 0xf400, 0x0013, 0x1613, 0x0011, 0xb0e8,
- 0x0010, 0xf500, 0x0003, 0x15e4, 0x0011, 0xb0e8, 0x0010, 0xf600,
- 0x0013, 0x1625, 0x0005, 0x00ce, 0x0010, 0x0009, 0x0000, 0xb0cf,
- 0x0003, 0x08db, 0x0000, 0xb930, 0x0005, 0x0031, 0x0000, 0x0025,
- 0x0015, 0x0033, 0x0000, 0xb039, 0x000b, 0x85a2, 0x0012, 0xb749,
- 0x0013, 0x15a7, 0x0002, 0xb52c, 0x0000, 0xffb5, 0x0000, 0xb162,
- 0x0000, 0xb063, 0x0005, 0x0031, 0x0000, 0x001f, 0x0015, 0x0033,
- 0x0000, 0xb309, 0x000b, 0x85ad, 0x0001, 0xb3c8, 0x0010, 0x0003,
- 0x0013, 0x15b5, 0x0010, 0xffb2, 0x0001, 0xffe8, 0x0010, 0x0003,
- 0x001b, 0x15b7, 0x0000, 0xc2b7, 0x0013, 0x0641, 0x0001, 0xb2e8,
- 0x0000, 0x0001, 0x0003, 0x15be, 0x0005, 0x00ce, 0x0010, 0x000a,
- 0x0010, 0xb2cf, 0x0003, 0x08db, 0x0010, 0xb465, 0x0010, 0xb667,
- 0x0015, 0x00b7, 0x0010, 0x0018, 0x0001, 0xb5c8, 0x0010, 0x0300,
- 0x0013, 0x15e3, 0x0012, 0xb548, 0x0003, 0x15ca, 0x0000, 0xb6ff,
- 0x0011, 0xb780, 0x0010, 0xffb7, 0x0002, 0xb549, 0x0003, 0x15cf,
- 0x0010, 0xb4ff, 0x0011, 0xb780, 0x0010, 0xffb7, 0x0015, 0x0044,
- 0x0010, 0x0018, 0x0005, 0x0031, 0x0000, 0x002c, 0x0015, 0x0033,
- 0x0000, 0x6841, 0x000b, 0x85d5, 0x0015, 0x0044, 0x0000, 0x0019,
- 0x0005, 0x0031, 0x0000, 0x0034, 0x0015, 0x0033, 0x0000, 0x5029,
- 0x000b, 0x85dc, 0x0015, 0x0044, 0x0000, 0x0008, 0x0011, 0xb7c8,
- 0x0010, 0x0003, 0x0013, 0x15e3, 0x0010, 0xff55, 0x0013, 0x0641,
- 0x0005, 0x00b5, 0x0000, 0x0008, 0x0015, 0x00b7, 0x0010, 0x0018,
- 0x0013, 0x0641, 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x0d88,
- 0x0000, 0x000b, 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb011,
- 0x001b, 0x85f0, 0x0010, 0xb1ff, 0x0001, 0xb0d0, 0x0003, 0x15f9,
- 0x0005, 0x00b5, 0x0010, 0x0b02, 0x0010, 0xb062, 0x0010, 0xb163,
- 0x0003, 0x05fb, 0x0005, 0x00b5, 0x0000, 0x0302, 0x0015, 0x0065,
- 0x0010, 0x0012, 0x0005, 0x0067, 0x0000, 0x0008, 0x0015, 0x006c,
- 0x0000, 0x7000, 0x0005, 0x006d, 0x0010, 0x0500, 0x0015, 0x006f,
- 0x0010, 0x000a, 0x0015, 0x0044, 0x0000, 0x0001, 0x0005, 0x0052,
- 0x0000, 0x2500, 0x0015, 0x0044, 0x0000, 0x0008, 0x0015, 0x00b7,
- 0x0000, 0x0032, 0x0013, 0x0641, 0x0005, 0x00b5, 0x0010, 0x0028,
- 0x0015, 0x00b7, 0x0010, 0x0018, 0x0013, 0x0641, 0x0005, 0x00b5,
- 0x0000, 0x0100, 0x0005, 0x0067, 0x0000, 0x0008, 0x0015, 0x0030,
- 0x0000, 0x0400, 0x0011, 0x0d88, 0x0010, 0x0018, 0x0000, 0xff31,
- 0x0015, 0x0033, 0x0000, 0xb009, 0x001b, 0x861e, 0x0001, 0xb0c8,
- 0x0010, 0x00ff, 0x0010, 0xff69, 0x0015, 0x00b7, 0x0000, 0x0020,
- 0x0013, 0x0641, 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x0d88,
- 0x0010, 0x0005, 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb609,
- 0x000b, 0x862c, 0x0001, 0xb6c8, 0x0010, 0xff00, 0x0000, 0xffb0,
- 0x0015, 0x0033, 0x0000, 0xb00a, 0x000b, 0x8632, 0x0001, 0xb6c8,
- 0x0010, 0x00ff, 0x0012, 0xff10, 0x000b, 0x163b, 0x0000, 0xffb5,
- 0x0015, 0x00b7, 0x0010, 0x0018, 0x0013, 0x0641, 0x0010, 0xff63,
- 0x0005, 0x00b5, 0x0000, 0x0800, 0x0015, 0x00b7, 0x0010, 0x0018,
- 0x0013, 0x0641, 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x0d88,
- 0x0010, 0x0009, 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb009,
- 0x001b, 0x8648, 0x0010, 0xb561, 0x0003, 0x964a, 0x0010, 0xb7a0,
- 0x0003, 0x0662, 0x0005, 0x00b6, 0x0010, 0x0300, 0x0004, 0x067d,
- 0x0005, 0x0054, 0x0010, 0x0819, 0x0010, 0x0d58, 0x0015, 0x0030,
+ 0x000b, 0x84f0, 0x0010, 0xb16a, 0x0010, 0xb06b, 0x0000, 0xb261,
+ 0x0015, 0x0044, 0x0010, 0x0018, 0x0000, 0xb930, 0x0005, 0x0031,
+ 0x0000, 0x0023, 0x0015, 0x0033, 0x0000, 0x6241, 0x001b, 0x84fb,
+ 0x0003, 0x94fc, 0x0015, 0x00a0, 0x0000, 0x0020, 0x0012, 0xd041,
+ 0x000b, 0x14ff, 0x0015, 0x00d1, 0x0010, 0x0202, 0x0013, 0x9503,
+ 0x0000, 0x75ff, 0x0011, 0xffc8, 0x0000, 0x1804, 0x0001, 0xffd8,
+ 0x0010, 0x0009, 0x0013, 0x9509, 0x0000, 0xff75, 0x0003, 0x950b,
+ 0x0015, 0x00d1, 0x0000, 0x0200, 0x0015, 0x0030, 0x0000, 0x0400,
+ 0x0001, 0xbd88, 0x0000, 0x0008, 0x0000, 0xff31, 0x0015, 0x00b1,
+ 0x0010, 0x07d0, 0x0005, 0x00b0, 0x0010, 0x0009, 0x0015, 0x0033,
+ 0x0000, 0xb012, 0x000b, 0x8519, 0x0013, 0x046b, 0x0000, 0xba30,
+ 0x0005, 0x0031, 0x0010, 0x0035, 0x0015, 0x0033, 0x0000, 0xb009,
+ 0x000b, 0x8520, 0x0002, 0xb040, 0x0003, 0x153c, 0x0015, 0x0030,
+ 0x0000, 0x0400, 0x0005, 0x0031, 0x0001, 0x1b72, 0x0015, 0x0033,
+ 0x0000, 0xb011, 0x000b, 0x8529, 0x0002, 0xb100, 0x0010, 0xffb1,
+ 0x001b, 0x2530, 0x0012, 0xb000, 0x0000, 0xffb0, 0x0013, 0x252a,
+ 0x0015, 0x0033, 0x0000, 0xb012, 0x000b, 0x8532, 0x0015, 0x0030,
+ 0x0000, 0x0400, 0x0011, 0x0d88, 0x0000, 0x0013, 0x0000, 0xff31,
+ 0x0015, 0x0033, 0x0000, 0xb012, 0x001b, 0x853a, 0x0003, 0x053e,
+ 0x0010, 0xc0b1, 0x0000, 0xc0b0, 0x0017, 0x4000, 0x0005, 0x00b6,
+ 0x0010, 0x0500, 0x0014, 0x0683, 0x0005, 0x0054, 0x0010, 0x0889,
+ 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x0d88, 0x0000, 0x0002,
+ 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb009, 0x001b, 0x854b,
+ 0x0010, 0xb058, 0x0000, 0x0d59, 0x0000, 0xb930, 0x0005, 0x0031,
+ 0x0000, 0x0023, 0x0015, 0x0033, 0x0000, 0xb011, 0x001b, 0x8553,
+ 0x0010, 0xb15c, 0x0010, 0xb05d, 0x0005, 0x0031, 0x0010, 0x002b,
+ 0x0015, 0x0033, 0x0000, 0xb011, 0x001b, 0x855a, 0x0000, 0xb15e,
+ 0x0000, 0xb05f, 0x0003, 0x955d, 0x0015, 0x00a0, 0x0010, 0x000c,
+ 0x0003, 0x0668, 0x0005, 0x00b6, 0x0000, 0x0700, 0x0014, 0x0683,
+ 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x0d88, 0x0010, 0x0009,
+ 0x0000, 0xff31, 0x0015, 0x0033, 0x0010, 0xb709, 0x000b, 0x856b,
+ 0x0012, 0xb749, 0x0003, 0x1571, 0x0005, 0x0054, 0x0010, 0x0889,
+ 0x0003, 0x0573, 0x0005, 0x0054, 0x0010, 0x0898, 0x0015, 0x0030,
0x0000, 0x0400, 0x0011, 0x0d88, 0x0000, 0x0002, 0x0000, 0xff31,
- 0x0015, 0x0033, 0x0000, 0xb009, 0x001b, 0x865a, 0x0000, 0xb059,
- 0x0013, 0x965c, 0x0010, 0xc0a0, 0x0010, 0x71ff, 0x0002, 0xff28,
- 0x0010, 0xff71, 0x0003, 0x0662, 0x0012, 0xd041, 0x000b, 0x1662,
- 0x0015, 0x00d1, 0x0010, 0x0202, 0x0000, 0x75ff, 0x0011, 0xffc8,
- 0x0000, 0x1804, 0x0001, 0xffd8, 0x0010, 0x0009, 0x0003, 0x966b,
- 0x0000, 0xff75, 0x0003, 0x966d, 0x0015, 0x00d1, 0x0000, 0x0200,
- 0x0015, 0x0030, 0x0000, 0x0400, 0x0001, 0xbd88, 0x0000, 0x0008,
- 0x0000, 0xff31, 0x0005, 0x00b0, 0x0010, 0x0009, 0x0015, 0x00b1,
- 0x0010, 0x07d0, 0x0015, 0x0033, 0x0000, 0xb012, 0x001b, 0x867b,
- 0x0003, 0x0465, 0x0015, 0x0044, 0x0000, 0x0008, 0x0005, 0x0098,
- 0x0010, 0x0056, 0x0015, 0x0099, 0x0000, 0x9575, 0x0004, 0x08a2,
- 0x0000, 0xb096, 0x0012, 0xb270, 0x0010, 0xff56, 0x0004, 0x08c4,
- 0x0010, 0xb052, 0x0010, 0xb153, 0x0000, 0xb6ff, 0x0011, 0xb2d0,
- 0x0010, 0xff50, 0x0010, 0xb351, 0x0017, 0x4000, 0x0001, 0x12e8,
- 0x0001, 0x1b56, 0x0013, 0x183f, 0x0015, 0x00d1, 0x0000, 0x0400,
- 0x0015, 0x0030, 0x0000, 0x0400, 0x0001, 0x1288, 0x0010, 0x0011,
- 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0x1009, 0x000b, 0x869b,
- 0x0015, 0x000f, 0x0000, 0x0001, 0x0010, 0xc014, 0x0000, 0x1213,
- 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x1388, 0x0000, 0x0004,
- 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xba09, 0x000b, 0x86a7,
- 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x1388, 0x0010, 0x0005,
- 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0x1a09, 0x001b, 0x86af,
- 0x0012, 0x104b, 0x001b, 0x16b8, 0x0000, 0x1a30, 0x0005, 0x0031,
- 0x0000, 0x000b, 0x0015, 0x0033, 0x0000, 0x1621, 0x001b, 0x86b7,
- 0x0010, 0x15fe, 0x000b, 0x66d7, 0x0014, 0x06fe, 0x0002, 0x3a42,
- 0x000b, 0x16fd, 0x0001, 0x10c8, 0x0010, 0x000f, 0x000b, 0x1760,
- 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x1388, 0x0000, 0x0008,
- 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb009, 0x000b, 0x86c7,
- 0x0011, 0xb0e8, 0x0010, 0x0009, 0x0013, 0x16ce, 0x0011, 0xb0e8,
- 0x0000, 0x0001, 0x001b, 0x16fc, 0x0011, 0x1388, 0x0010, 0x000a,
- 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb009, 0x000b, 0x86d3,
- 0x0002, 0xb04f, 0x001b, 0x16f3, 0x0013, 0x06fc, 0x0015, 0x0030,
- 0x0000, 0x0400, 0x0011, 0x1388, 0x0010, 0x0003, 0x0000, 0xff31,
- 0x0015, 0x0033, 0x0000, 0xb009, 0x001b, 0x86de, 0x0015, 0x0033,
- 0x0010, 0xc00a, 0x001b, 0x86e1, 0x0010, 0xb0fe, 0x0003, 0x66e6,
- 0x0000, 0xb012, 0x0013, 0x06e8, 0x0010, 0xc012, 0x0010, 0xc011,
- 0x0015, 0x000f, 0x0010, 0x0000, 0x0002, 0x3944, 0x0013, 0x16f1,
- 0x0015, 0x0039, 0x0000, 0x5040, 0x0015, 0x00b8, 0x0000, 0x0008,
- 0x0014, 0x091f, 0x0000, 0xc013, 0x0003, 0x06fd, 0x0010, 0x02fe,
- 0x0003, 0x66f8, 0x0015, 0x003a, 0x0010, 0x2020, 0x0003, 0x06fd,
- 0x0015, 0x003a, 0x0000, 0x2000, 0x0015, 0x003a, 0x0010, 0x1010,
- 0x0014, 0x090b, 0x0003, 0x0054, 0x0013, 0xb6fe, 0x0005, 0x002a,
- 0x0000, 0x0004, 0x0000, 0xba30, 0x0005, 0x0031, 0x0010, 0x001b,
- 0x0015, 0x0033, 0x0000, 0xb009, 0x000b, 0x8706, 0x0000, 0xc02c,
- 0x0000, 0xb02d, 0x0012, 0x104b, 0x0013, 0x1721, 0x0000, 0x1a30,
- 0x0005, 0x0031, 0x0000, 0x0023, 0x0015, 0x0033, 0x0000, 0xb129,
- 0x001b, 0x8710, 0x0000, 0xb120, 0x0010, 0xb221, 0x0000, 0xb322,
- 0x0000, 0xb423, 0x0000, 0xb524, 0x0000, 0xc025, 0x0010, 0xb526,
- 0x0010, 0xc027, 0x0010, 0xb516, 0x0010, 0xc017, 0x0000, 0xb518,
- 0x0000, 0xc019, 0x0010, 0xc028, 0x0000, 0xc029, 0x0010, 0xc01e,
- 0x0013, 0x0757, 0x0012, 0x1044, 0x0003, 0x1751, 0x0002, 0x1034,
- 0x0000, 0xff10, 0x0000, 0x1a30, 0x0005, 0x0031, 0x0000, 0x0002,
- 0x0015, 0x0033, 0x0000, 0x1b29, 0x001b, 0x872a, 0x0000, 0x1c30,
- 0x0000, 0x1b31, 0x0015, 0x0033, 0x0000, 0xb131, 0x001b, 0x872f,
- 0x0002, 0x1f43, 0x000b, 0x1736, 0x0010, 0xb3b5, 0x0000, 0xb4b6,
- 0x0000, 0xc0b3, 0x0010, 0xc0b4, 0x0000, 0xb120, 0x0010, 0xb221,
- 0x0000, 0xb322, 0x0000, 0xb423, 0x0000, 0xb524, 0x0010, 0xb625,
- 0x0010, 0xb516, 0x0000, 0xb617, 0x0000, 0x1826, 0x0000, 0x1927,
- 0x0000, 0x1a30, 0x0005, 0x0031, 0x0010, 0x000f, 0x0015, 0x0033,
- 0x0000, 0xb011, 0x001b, 0x8745, 0x0000, 0xb028, 0x0000, 0xb129,
- 0x0012, 0x1e10, 0x0010, 0xff1e, 0x0013, 0x6757, 0x0002, 0x1d00,
- 0x0010, 0xff1d, 0x0004, 0x02a8, 0x0002, 0x3a42, 0x0003, 0x1757,
- 0x0003, 0x075f, 0x0000, 0x1a30, 0x0005, 0x0031, 0x0000, 0x0002,
- 0x0015, 0x0033, 0x0000, 0x1b79, 0x000b, 0x8756, 0x0003, 0xb757,
- 0x0005, 0x002a, 0x0000, 0x0001, 0x0005, 0x0015, 0x0000, 0x0001,
- 0x0000, 0x1efe, 0x0003, 0x675f, 0x0003, 0x0274, 0x0017, 0x4000,
- 0x0000, 0xba30, 0x0005, 0x0031, 0x0010, 0x001b, 0x0015, 0x0033,
- 0x0010, 0xb051, 0x000b, 0x8765, 0x0000, 0xb0a3, 0x0010, 0xb697,
- 0x0010, 0xb946, 0x0015, 0x00a5, 0x0000, 0x0010, 0x0015, 0x0030,
- 0x0000, 0x0400, 0x0011, 0x1388, 0x0000, 0x0002, 0x0000, 0xff31,
- 0x0015, 0x0033, 0x0000, 0xb509, 0x000b, 0x8772, 0x0004, 0x08c4,
- 0x0004, 0x08b3, 0x0012, 0xb470, 0x0010, 0xffb4, 0x0010, 0xb48e,
- 0x0010, 0xb08a, 0x0010, 0xb18b, 0x0012, 0x104d, 0x0013, 0x177d,
- 0x0003, 0x07aa, 0x0012, 0x104b, 0x0013, 0x1790, 0x0005, 0x008c,
- 0x0010, 0x0829, 0x0010, 0xc08d, 0x0001, 0xb2d8, 0x0010, 0x0600,
+ 0x0015, 0x0033, 0x0000, 0xb009, 0x000b, 0x857a, 0x0010, 0xb058,
+ 0x0000, 0x0d59, 0x0001, 0xb9c8, 0x0010, 0xf000, 0x0001, 0xffe8,
+ 0x0010, 0xf000, 0x001b, 0x15a3, 0x0015, 0x0030, 0x0000, 0x0400,
+ 0x0011, 0x0d88, 0x0010, 0x0005, 0x0000, 0xff31, 0x0015, 0x0033,
+ 0x0000, 0xb009, 0x000b, 0x8589, 0x0001, 0xb0c8, 0x0000, 0xf700,
+ 0x0000, 0xffb0, 0x0011, 0xb0e8, 0x0000, 0xf100, 0x0013, 0x15ea,
+ 0x0011, 0xb0e8, 0x0000, 0xf200, 0x0013, 0x15ef, 0x0011, 0xb0e8,
+ 0x0010, 0xf300, 0x0003, 0x1614, 0x0011, 0xb0e8, 0x0000, 0xf400,
+ 0x0013, 0x1619, 0x0011, 0xb0e8, 0x0010, 0xf500, 0x0013, 0x15ea,
+ 0x0011, 0xb0e8, 0x0010, 0xf600, 0x0003, 0x162b, 0x0005, 0x00ce,
+ 0x0010, 0x0009, 0x0000, 0xb0cf, 0x0003, 0x08e1, 0x0000, 0xb930,
+ 0x0005, 0x0031, 0x0000, 0x0025, 0x0015, 0x0033, 0x0000, 0xb039,
+ 0x000b, 0x85a8, 0x0012, 0xb749, 0x0013, 0x15ad, 0x0002, 0xb52c,
+ 0x0000, 0xffb5, 0x0000, 0xb162, 0x0000, 0xb063, 0x0005, 0x0031,
+ 0x0000, 0x001f, 0x0015, 0x0033, 0x0000, 0xb309, 0x000b, 0x85b3,
+ 0x0001, 0xb3c8, 0x0010, 0x0003, 0x0003, 0x15bb, 0x0010, 0xffb2,
+ 0x0001, 0xffe8, 0x0010, 0x0003, 0x001b, 0x15bd, 0x0000, 0xc2b7,
+ 0x0013, 0x0647, 0x0001, 0xb2e8, 0x0000, 0x0001, 0x0013, 0x15c4,
+ 0x0005, 0x00ce, 0x0010, 0x000a, 0x0010, 0xb2cf, 0x0003, 0x08e1,
+ 0x0010, 0xb465, 0x0010, 0xb667, 0x0015, 0x00b7, 0x0010, 0x0018,
+ 0x0001, 0xb5c8, 0x0010, 0x0300, 0x0013, 0x15e9, 0x0012, 0xb548,
+ 0x0013, 0x15d0, 0x0000, 0xb6ff, 0x0011, 0xb780, 0x0010, 0xffb7,
+ 0x0002, 0xb549, 0x0013, 0x15d5, 0x0010, 0xb4ff, 0x0011, 0xb780,
+ 0x0010, 0xffb7, 0x0015, 0x0044, 0x0010, 0x0018, 0x0005, 0x0031,
+ 0x0000, 0x002c, 0x0015, 0x0033, 0x0000, 0x6841, 0x001b, 0x85db,
+ 0x0015, 0x0044, 0x0000, 0x0019, 0x0005, 0x0031, 0x0000, 0x0034,
+ 0x0015, 0x0033, 0x0000, 0x5029, 0x001b, 0x85e2, 0x0015, 0x0044,
+ 0x0000, 0x0008, 0x0011, 0xb7c8, 0x0010, 0x0003, 0x0013, 0x15e9,
+ 0x0010, 0xff55, 0x0013, 0x0647, 0x0005, 0x00b5, 0x0000, 0x0008,
+ 0x0015, 0x00b7, 0x0010, 0x0018, 0x0013, 0x0647, 0x0015, 0x0030,
+ 0x0000, 0x0400, 0x0011, 0x0d88, 0x0000, 0x000b, 0x0000, 0xff31,
+ 0x0015, 0x0033, 0x0000, 0xb011, 0x001b, 0x85f6, 0x0010, 0xb1ff,
+ 0x0001, 0xb0d0, 0x0003, 0x15ff, 0x0005, 0x00b5, 0x0010, 0x0b02,
+ 0x0010, 0xb062, 0x0010, 0xb163, 0x0003, 0x0601, 0x0005, 0x00b5,
+ 0x0000, 0x0302, 0x0015, 0x0065, 0x0010, 0x0012, 0x0005, 0x0067,
+ 0x0000, 0x0008, 0x0015, 0x006c, 0x0000, 0x7000, 0x0005, 0x006d,
+ 0x0010, 0x0500, 0x0015, 0x006f, 0x0010, 0x000a, 0x0015, 0x0044,
+ 0x0000, 0x0001, 0x0005, 0x0052, 0x0000, 0x2500, 0x0015, 0x0044,
+ 0x0000, 0x0008, 0x0015, 0x00b7, 0x0000, 0x0032, 0x0013, 0x0647,
+ 0x0005, 0x00b5, 0x0010, 0x0028, 0x0015, 0x00b7, 0x0010, 0x0018,
+ 0x0013, 0x0647, 0x0005, 0x00b5, 0x0000, 0x0100, 0x0005, 0x0067,
+ 0x0000, 0x0008, 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x0d88,
+ 0x0010, 0x0018, 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb009,
+ 0x001b, 0x8624, 0x0001, 0xb0c8, 0x0010, 0x00ff, 0x0010, 0xff69,
+ 0x0015, 0x00b7, 0x0000, 0x0020, 0x0013, 0x0647, 0x0015, 0x0030,
+ 0x0000, 0x0400, 0x0011, 0x0d88, 0x0010, 0x0005, 0x0000, 0xff31,
+ 0x0015, 0x0033, 0x0000, 0xb609, 0x000b, 0x8632, 0x0001, 0xb6c8,
+ 0x0010, 0xff00, 0x0000, 0xffb0, 0x0015, 0x0033, 0x0000, 0xb00a,
+ 0x000b, 0x8638, 0x0001, 0xb6c8, 0x0010, 0x00ff, 0x0012, 0xff10,
+ 0x001b, 0x1641, 0x0000, 0xffb5, 0x0015, 0x00b7, 0x0010, 0x0018,
+ 0x0013, 0x0647, 0x0010, 0xff63, 0x0005, 0x00b5, 0x0000, 0x0800,
+ 0x0015, 0x00b7, 0x0010, 0x0018, 0x0013, 0x0647, 0x0015, 0x0030,
+ 0x0000, 0x0400, 0x0011, 0x0d88, 0x0010, 0x0009, 0x0000, 0xff31,
+ 0x0015, 0x0033, 0x0000, 0xb009, 0x001b, 0x864e, 0x0010, 0xb561,
+ 0x0013, 0x9650, 0x0010, 0xb7a0, 0x0003, 0x0668, 0x0005, 0x00b6,
+ 0x0010, 0x0300, 0x0014, 0x0683, 0x0005, 0x0054, 0x0010, 0x0819,
+ 0x0010, 0x0d58, 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x0d88,
+ 0x0000, 0x0002, 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb009,
+ 0x001b, 0x8660, 0x0000, 0xb059, 0x0003, 0x9662, 0x0010, 0xc0a0,
+ 0x0010, 0x71ff, 0x0002, 0xff28, 0x0010, 0xff71, 0x0003, 0x0668,
+ 0x0012, 0xd041, 0x000b, 0x1668, 0x0015, 0x00d1, 0x0010, 0x0202,
+ 0x0000, 0x75ff, 0x0011, 0xffc8, 0x0000, 0x1804, 0x0001, 0xffd8,
+ 0x0010, 0x0009, 0x0013, 0x9671, 0x0000, 0xff75, 0x0003, 0x9673,
+ 0x0015, 0x00d1, 0x0000, 0x0200, 0x0015, 0x0030, 0x0000, 0x0400,
+ 0x0001, 0xbd88, 0x0000, 0x0008, 0x0000, 0xff31, 0x0005, 0x00b0,
+ 0x0010, 0x0009, 0x0015, 0x00b1, 0x0010, 0x07d0, 0x0015, 0x0033,
+ 0x0000, 0xb012, 0x001b, 0x8681, 0x0013, 0x046b, 0x0015, 0x0044,
+ 0x0000, 0x0008, 0x0005, 0x0098, 0x0010, 0x0056, 0x0015, 0x0099,
+ 0x0000, 0x9575, 0x0004, 0x08a8, 0x0000, 0xb096, 0x0012, 0xb270,
+ 0x0010, 0xff56, 0x0014, 0x08ca, 0x0010, 0xb052, 0x0010, 0xb153,
+ 0x0000, 0xb6ff, 0x0011, 0xb2d0, 0x0010, 0xff50, 0x0010, 0xb351,
+ 0x0017, 0x4000, 0x0001, 0x12e8, 0x0001, 0x1b56, 0x0003, 0x1845,
+ 0x0015, 0x00d1, 0x0000, 0x0400, 0x0015, 0x0030, 0x0000, 0x0400,
+ 0x0001, 0x1288, 0x0010, 0x0011, 0x0000, 0xff31, 0x0015, 0x0033,
+ 0x0000, 0x1009, 0x000b, 0x86a1, 0x0015, 0x000f, 0x0000, 0x0001,
+ 0x0010, 0xc014, 0x0000, 0x1213, 0x0015, 0x0030, 0x0000, 0x0400,
+ 0x0011, 0x1388, 0x0000, 0x0004, 0x0000, 0xff31, 0x0015, 0x0033,
+ 0x0000, 0xba09, 0x000b, 0x86ad, 0x0015, 0x0030, 0x0000, 0x0400,
+ 0x0011, 0x1388, 0x0010, 0x0005, 0x0000, 0xff31, 0x0015, 0x0033,
+ 0x0000, 0x1a09, 0x000b, 0x86b5, 0x0012, 0x104b, 0x001b, 0x16be,
+ 0x0000, 0x1a30, 0x0005, 0x0031, 0x0000, 0x000b, 0x0015, 0x0033,
+ 0x0000, 0x1621, 0x001b, 0x86bd, 0x0010, 0x15fe, 0x000b, 0x66dd,
+ 0x0004, 0x0704, 0x0002, 0x3a42, 0x000b, 0x1703, 0x0001, 0x10c8,
+ 0x0010, 0x000f, 0x000b, 0x1766, 0x0015, 0x0030, 0x0000, 0x0400,
+ 0x0011, 0x1388, 0x0000, 0x0008, 0x0000, 0xff31, 0x0015, 0x0033,
+ 0x0000, 0xb009, 0x000b, 0x86cd, 0x0011, 0xb0e8, 0x0010, 0x0009,
+ 0x0003, 0x16d4, 0x0011, 0xb0e8, 0x0000, 0x0001, 0x001b, 0x1702,
+ 0x0011, 0x1388, 0x0010, 0x000a, 0x0000, 0xff31, 0x0015, 0x0033,
+ 0x0000, 0xb009, 0x000b, 0x86d9, 0x0002, 0xb04f, 0x001b, 0x16f9,
+ 0x0013, 0x0702, 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x1388,
+ 0x0010, 0x0003, 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb009,
+ 0x001b, 0x86e4, 0x0015, 0x0033, 0x0010, 0xc00a, 0x001b, 0x86e7,
+ 0x0010, 0xb0fe, 0x0003, 0x66ec, 0x0000, 0xb012, 0x0013, 0x06ee,
+ 0x0010, 0xc012, 0x0010, 0xc011, 0x0015, 0x000f, 0x0010, 0x0000,
+ 0x0002, 0x3944, 0x0013, 0x16f7, 0x0015, 0x0039, 0x0000, 0x5040,
+ 0x0015, 0x00b8, 0x0000, 0x0008, 0x0014, 0x0925, 0x0000, 0xc013,
+ 0x0003, 0x0703, 0x0010, 0x02fe, 0x0003, 0x66fe, 0x0015, 0x003a,
+ 0x0010, 0x2020, 0x0003, 0x0703, 0x0015, 0x003a, 0x0000, 0x2000,
+ 0x0015, 0x003a, 0x0010, 0x1010, 0x0004, 0x0911, 0x0003, 0x0054,
+ 0x0003, 0xb704, 0x0005, 0x002a, 0x0000, 0x0004, 0x0000, 0xba30,
+ 0x0005, 0x0031, 0x0010, 0x001b, 0x0015, 0x0033, 0x0000, 0xb009,
+ 0x000b, 0x870c, 0x0000, 0xc02c, 0x0000, 0xb02d, 0x0012, 0x104b,
+ 0x0013, 0x1727, 0x0000, 0x1a30, 0x0005, 0x0031, 0x0000, 0x0023,
+ 0x0015, 0x0033, 0x0000, 0xb129, 0x001b, 0x8716, 0x0000, 0xb120,
+ 0x0010, 0xb221, 0x0000, 0xb322, 0x0000, 0xb423, 0x0000, 0xb524,
+ 0x0000, 0xc025, 0x0010, 0xb526, 0x0010, 0xc027, 0x0010, 0xb516,
+ 0x0010, 0xc017, 0x0000, 0xb518, 0x0000, 0xc019, 0x0010, 0xc028,
+ 0x0000, 0xc029, 0x0010, 0xc01e, 0x0013, 0x075d, 0x0012, 0x1044,
+ 0x0003, 0x1757, 0x0002, 0x1034, 0x0000, 0xff10, 0x0000, 0x1a30,
+ 0x0005, 0x0031, 0x0000, 0x0002, 0x0015, 0x0033, 0x0000, 0x1b29,
+ 0x000b, 0x8730, 0x0000, 0x1c30, 0x0000, 0x1b31, 0x0015, 0x0033,
+ 0x0000, 0xb131, 0x000b, 0x8735, 0x0002, 0x1f43, 0x000b, 0x173c,
+ 0x0010, 0xb3b5, 0x0000, 0xb4b6, 0x0000, 0xc0b3, 0x0010, 0xc0b4,
+ 0x0000, 0xb120, 0x0010, 0xb221, 0x0000, 0xb322, 0x0000, 0xb423,
+ 0x0000, 0xb524, 0x0010, 0xb625, 0x0010, 0xb516, 0x0000, 0xb617,
+ 0x0000, 0x1826, 0x0000, 0x1927, 0x0000, 0x1a30, 0x0005, 0x0031,
+ 0x0010, 0x000f, 0x0015, 0x0033, 0x0000, 0xb011, 0x000b, 0x874b,
+ 0x0000, 0xb028, 0x0000, 0xb129, 0x0012, 0x1e10, 0x0010, 0xff1e,
+ 0x0013, 0x675d, 0x0002, 0x1d00, 0x0010, 0xff1d, 0x0004, 0x02ab,
+ 0x0002, 0x3a42, 0x0003, 0x175d, 0x0003, 0x0765, 0x0000, 0x1a30,
+ 0x0005, 0x0031, 0x0000, 0x0002, 0x0015, 0x0033, 0x0000, 0x1b79,
+ 0x000b, 0x875c, 0x0003, 0xb75d, 0x0005, 0x002a, 0x0000, 0x0001,
+ 0x0005, 0x0015, 0x0000, 0x0001, 0x0000, 0x1efe, 0x0003, 0x6765,
+ 0x0003, 0x0277, 0x0017, 0x4000, 0x0000, 0xba30, 0x0005, 0x0031,
+ 0x0010, 0x001b, 0x0015, 0x0033, 0x0010, 0xb051, 0x001b, 0x876b,
+ 0x0000, 0xb0a3, 0x0010, 0xb697, 0x0010, 0xb946, 0x0015, 0x00a5,
+ 0x0000, 0x0010, 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x1388,
+ 0x0000, 0x0002, 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb509,
+ 0x000b, 0x8778, 0x0014, 0x08ca, 0x0004, 0x08b9, 0x0012, 0xb470,
+ 0x0010, 0xffb4, 0x0010, 0xb48e, 0x0010, 0xb08a, 0x0010, 0xb18b,
+ 0x0012, 0x104d, 0x0003, 0x1783, 0x0013, 0x07b0, 0x0012, 0x104b,
+ 0x0013, 0x1796, 0x0005, 0x008c, 0x0010, 0x0829, 0x0010, 0xc08d,
+ 0x0001, 0xb2d8, 0x0010, 0x0600, 0x0010, 0xff88, 0x0010, 0xb389,
+ 0x0000, 0x1390, 0x0010, 0xb591, 0x0000, 0xc08f, 0x0010, 0x1ab9,
+ 0x0004, 0x051b, 0x0013, 0x9791, 0x0010, 0xb092, 0x0010, 0xb193,
+ 0x0013, 0x9794, 0x0013, 0x07ab, 0x0005, 0x008c, 0x0000, 0x0809,
+ 0x0015, 0x008d, 0x0000, 0x0008, 0x0001, 0xb2d8, 0x0000, 0x0100,
0x0010, 0xff88, 0x0010, 0xb389, 0x0000, 0x1390, 0x0010, 0xb591,
- 0x0000, 0xc08f, 0x0010, 0x1ab9, 0x0014, 0x0515, 0x0003, 0x978b,
- 0x0010, 0xb092, 0x0010, 0xb193, 0x0003, 0x978e, 0x0003, 0x07a5,
- 0x0005, 0x008c, 0x0000, 0x0809, 0x0015, 0x008d, 0x0000, 0x0008,
- 0x0001, 0xb2d8, 0x0000, 0x0100, 0x0010, 0xff88, 0x0010, 0xb389,
- 0x0000, 0x1390, 0x0010, 0xb591, 0x0000, 0xc08f, 0x0000, 0x1a30,
- 0x0005, 0x0031, 0x0010, 0x000f, 0x0015, 0x0033, 0x0000, 0xb011,
- 0x000b, 0x87a0, 0x0013, 0x97a1, 0x0000, 0xb192, 0x0000, 0xb093,
- 0x0013, 0x97a4, 0x0010, 0x19a1, 0x0000, 0x18a2, 0x0015, 0x00b1,
- 0x0010, 0x0096, 0x0003, 0x081b, 0x0000, 0xb590, 0x0010, 0x1391,
- 0x0001, 0x10c8, 0x0010, 0x000f, 0x0001, 0xffe8, 0x0010, 0x0005,
- 0x0013, 0x17d1, 0x0001, 0xb2d8, 0x0000, 0x0700, 0x0010, 0xff88,
- 0x0010, 0xb389, 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x1388,
- 0x0010, 0x0009, 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb009,
- 0x001b, 0x87bc, 0x0002, 0xb049, 0x0003, 0x17c4, 0x0005, 0x008c,
- 0x0010, 0x0889, 0x0015, 0x00b1, 0x0010, 0x0096, 0x0013, 0x07c8,
- 0x0005, 0x008c, 0x0010, 0x0898, 0x0015, 0x00b1, 0x0000, 0x0092,
- 0x0010, 0xc08d, 0x0000, 0xc08f, 0x0003, 0x97ca, 0x0000, 0xc092,
- 0x0010, 0xc093, 0x0013, 0x97cd, 0x0010, 0x19a1, 0x0000, 0x18a2,
- 0x0003, 0x081b, 0x0001, 0xb2d8, 0x0000, 0x0100, 0x0010, 0xff88,
- 0x0010, 0xb389, 0x0005, 0x008c, 0x0010, 0x0880, 0x0015, 0x008d,
- 0x0000, 0x0008, 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x1388,
- 0x0000, 0x000e, 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb009,
- 0x001b, 0x87e0, 0x0010, 0xb08f, 0x0000, 0xb590, 0x0010, 0x1391,
- 0x0000, 0x1a30, 0x0005, 0x0031, 0x0000, 0x000d, 0x0015, 0x0033,
- 0x0000, 0xb021, 0x001b, 0x87e9, 0x0013, 0x97ea, 0x0010, 0xb392,
- 0x0010, 0xb293, 0x0003, 0x97ed, 0x0000, 0xb1a1, 0x0010, 0xb0a2,
- 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x1388, 0x0000, 0x000b,
- 0x0000, 0xff31, 0x0015, 0x0033, 0x0010, 0xb211, 0x001b, 0x87f7,
- 0x0000, 0xb3ff, 0x0001, 0xb080, 0x0000, 0xffb3, 0x001b, 0x27fe,
- 0x0002, 0xb200, 0x0003, 0x07ff, 0x0010, 0xb2ff, 0x0011, 0xb180,
- 0x0010, 0xffb2, 0x0011, 0x1388, 0x0000, 0x000b, 0x0000, 0xff31,
- 0x0015, 0x0033, 0x0010, 0xb212, 0x000b, 0x8806, 0x0015, 0x00b1,
- 0x0000, 0x0092, 0x0002, 0x104c, 0x0003, 0x1819, 0x0011, 0xc2e8,
- 0x0010, 0x000c, 0x000b, 0x1811, 0x0015, 0x00ff, 0x0000, 0x0800,
- 0x0013, 0x0819, 0x0011, 0xc2e8, 0x0000, 0x0020, 0x000b, 0x1817,
- 0x0015, 0x00ff, 0x0010, 0x1800, 0x0013, 0x0819, 0x0015, 0x00ff,
- 0x0000, 0x1000, 0x0011, 0xb1d0, 0x0010, 0xffb1, 0x0015, 0x009a,
- 0x0010, 0x0036, 0x0005, 0x009b, 0x0000, 0x95d5, 0x0012, 0xd041,
- 0x001b, 0x181f, 0x0015, 0x00d1, 0x0010, 0x0202, 0x0013, 0x9823,
- 0x0012, 0x104e, 0x0013, 0x1828, 0x0012, 0xb12f, 0x0010, 0xffb1,
- 0x0000, 0xb175, 0x0013, 0x9829, 0x0015, 0x00d1, 0x0000, 0x0200,
- 0x0001, 0x19c8, 0x0010, 0xfff0, 0x001b, 0x1832, 0x0015, 0x00b1,
- 0x0010, 0x07d0, 0x0013, 0x0834, 0x0015, 0x00b1, 0x0000, 0x1b58,
- 0x0005, 0x00b0, 0x0010, 0x0009, 0x0015, 0x0030, 0x0000, 0x0400,
+ 0x0000, 0xc08f, 0x0000, 0x1a30, 0x0005, 0x0031, 0x0010, 0x000f,
+ 0x0015, 0x0033, 0x0000, 0xb011, 0x000b, 0x87a6, 0x0013, 0x97a7,
+ 0x0000, 0xb192, 0x0000, 0xb093, 0x0003, 0x97aa, 0x0010, 0x19a1,
+ 0x0000, 0x18a2, 0x0015, 0x00b1, 0x0010, 0x0096, 0x0003, 0x0821,
+ 0x0000, 0xb590, 0x0010, 0x1391, 0x0001, 0x10c8, 0x0010, 0x000f,
+ 0x0001, 0xffe8, 0x0010, 0x0005, 0x0013, 0x17d7, 0x0001, 0xb2d8,
+ 0x0000, 0x0700, 0x0010, 0xff88, 0x0010, 0xb389, 0x0015, 0x0030,
+ 0x0000, 0x0400, 0x0011, 0x1388, 0x0010, 0x0009, 0x0000, 0xff31,
+ 0x0015, 0x0033, 0x0000, 0xb009, 0x001b, 0x87c2, 0x0002, 0xb049,
+ 0x0013, 0x17ca, 0x0005, 0x008c, 0x0010, 0x0889, 0x0015, 0x00b1,
+ 0x0010, 0x0096, 0x0013, 0x07ce, 0x0005, 0x008c, 0x0010, 0x0898,
+ 0x0015, 0x00b1, 0x0000, 0x0092, 0x0010, 0xc08d, 0x0000, 0xc08f,
+ 0x0013, 0x97d0, 0x0000, 0xc092, 0x0010, 0xc093, 0x0013, 0x97d3,
+ 0x0010, 0x19a1, 0x0000, 0x18a2, 0x0003, 0x0821, 0x0001, 0xb2d8,
+ 0x0000, 0x0100, 0x0010, 0xff88, 0x0010, 0xb389, 0x0005, 0x008c,
+ 0x0010, 0x0880, 0x0015, 0x008d, 0x0000, 0x0008, 0x0015, 0x0030,
+ 0x0000, 0x0400, 0x0011, 0x1388, 0x0000, 0x000e, 0x0000, 0xff31,
+ 0x0015, 0x0033, 0x0000, 0xb009, 0x001b, 0x87e6, 0x0010, 0xb08f,
+ 0x0000, 0xb590, 0x0010, 0x1391, 0x0000, 0x1a30, 0x0005, 0x0031,
+ 0x0000, 0x000d, 0x0015, 0x0033, 0x0000, 0xb021, 0x001b, 0x87ef,
+ 0x0003, 0x97f0, 0x0010, 0xb392, 0x0010, 0xb293, 0x0003, 0x97f3,
+ 0x0000, 0xb1a1, 0x0010, 0xb0a2, 0x0015, 0x0030, 0x0000, 0x0400,
+ 0x0011, 0x1388, 0x0000, 0x000b, 0x0000, 0xff31, 0x0015, 0x0033,
+ 0x0010, 0xb211, 0x001b, 0x87fd, 0x0000, 0xb3ff, 0x0001, 0xb080,
+ 0x0000, 0xffb3, 0x001b, 0x2804, 0x0002, 0xb200, 0x0003, 0x0805,
+ 0x0010, 0xb2ff, 0x0011, 0xb180, 0x0010, 0xffb2, 0x0011, 0x1388,
+ 0x0000, 0x000b, 0x0000, 0xff31, 0x0015, 0x0033, 0x0010, 0xb212,
+ 0x000b, 0x880c, 0x0015, 0x00b1, 0x0000, 0x0092, 0x0002, 0x104c,
+ 0x0003, 0x181f, 0x0011, 0xc2e8, 0x0010, 0x000c, 0x000b, 0x1817,
+ 0x0015, 0x00ff, 0x0000, 0x0800, 0x0013, 0x081f, 0x0011, 0xc2e8,
+ 0x0000, 0x0020, 0x000b, 0x181d, 0x0015, 0x00ff, 0x0010, 0x1800,
+ 0x0013, 0x081f, 0x0015, 0x00ff, 0x0000, 0x1000, 0x0011, 0xb1d0,
+ 0x0010, 0xffb1, 0x0015, 0x009a, 0x0010, 0x0036, 0x0005, 0x009b,
+ 0x0000, 0x95d5, 0x0012, 0xd041, 0x001b, 0x1825, 0x0015, 0x00d1,
+ 0x0010, 0x0202, 0x0013, 0x9829, 0x0012, 0x104e, 0x0013, 0x182e,
+ 0x0012, 0xb12f, 0x0010, 0xffb1, 0x0000, 0xb175, 0x0013, 0x982f,
+ 0x0015, 0x00d1, 0x0000, 0x0200, 0x0001, 0x19c8, 0x0010, 0xfff0,
+ 0x001b, 0x1838, 0x0015, 0x00b1, 0x0010, 0x07d0, 0x0003, 0x083a,
+ 0x0015, 0x00b1, 0x0000, 0x1b58, 0x0005, 0x00b0, 0x0010, 0x0009,
+ 0x0015, 0x0030, 0x0000, 0x0400, 0x0001, 0xbd88, 0x0000, 0x000b,
+ 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb012, 0x001b, 0x8843,
+ 0x0003, 0x0703, 0x0015, 0x0030, 0x0000, 0x0400, 0x0000, 0xa4ff,
+ 0x0003, 0x6893, 0x0011, 0xffa8, 0x0010, 0x0005, 0x000b, 0x2893,
+ 0x0005, 0x0031, 0x0011, 0x1b6d, 0x0015, 0x0033, 0x0010, 0xb211,
+ 0x000b, 0x8850, 0x0002, 0xb200, 0x0010, 0xffb2, 0x0005, 0x0031,
+ 0x0011, 0x1b6d, 0x0015, 0x0033, 0x0010, 0xb20a, 0x001b, 0x8857,
+ 0x0015, 0x000f, 0x0000, 0x0001, 0x0000, 0x1213, 0x0005, 0x0010,
+ 0x0000, 0x8000, 0x0015, 0x00a3, 0x0000, 0x0200, 0x0000, 0xc697,
+ 0x0005, 0x0046, 0x0000, 0x0002, 0x0015, 0x00a5, 0x0000, 0x0010,
+ 0x0011, 0xc4d8, 0x0000, 0x3200, 0x0010, 0xff88, 0x0000, 0xc589,
+ 0x0010, 0xc48a, 0x0010, 0xc58b, 0x0010, 0xc08e, 0x0005, 0x008c,
+ 0x0010, 0xe109, 0x0010, 0xc08d, 0x0015, 0x0090, 0x0001, 0x1b56,
+ 0x0005, 0x0091, 0x0010, 0xffff, 0x0000, 0xb292, 0x0000, 0xb393,
+ 0x0015, 0x009a, 0x0010, 0x0056, 0x0005, 0x009b, 0x0010, 0x95f5,
+ 0x0012, 0xd042, 0x0003, 0x1886, 0x0005, 0x00b0, 0x0010, 0x8080,
+ 0x0011, 0x1388, 0x0010, 0x0011, 0x0000, 0xff31, 0x0015, 0x0033,
+ 0x0000, 0xb00a, 0x000b, 0x8881, 0x0015, 0x00b8, 0x0010, 0x000c,
+ 0x0014, 0x0925, 0x0003, 0x0888, 0x0005, 0x0075, 0x0010, 0x8092,
+ 0x0015, 0x00b1, 0x0010, 0x07d0, 0x0005, 0x00b0, 0x0010, 0x0009,
0x0001, 0xbd88, 0x0000, 0x000b, 0x0000, 0xff31, 0x0015, 0x0033,
- 0x0000, 0xb012, 0x001b, 0x883d, 0x0003, 0x06fd, 0x0015, 0x0030,
- 0x0000, 0x0400, 0x0000, 0xa4ff, 0x0003, 0x688d, 0x0011, 0xffa8,
- 0x0010, 0x0005, 0x000b, 0x288d, 0x0005, 0x0031, 0x0011, 0x1b6d,
- 0x0015, 0x0033, 0x0010, 0xb211, 0x001b, 0x884a, 0x0002, 0xb200,
- 0x0010, 0xffb2, 0x0005, 0x0031, 0x0011, 0x1b6d, 0x0015, 0x0033,
- 0x0010, 0xb20a, 0x001b, 0x8851, 0x0015, 0x000f, 0x0000, 0x0001,
- 0x0000, 0x1213, 0x0005, 0x0010, 0x0000, 0x8000, 0x0015, 0x00a3,
- 0x0000, 0x0200, 0x0000, 0xc697, 0x0005, 0x0046, 0x0000, 0x0002,
- 0x0015, 0x00a5, 0x0000, 0x0010, 0x0011, 0xc4d8, 0x0000, 0x3200,
- 0x0010, 0xff88, 0x0000, 0xc589, 0x0010, 0xc48a, 0x0010, 0xc58b,
- 0x0010, 0xc08e, 0x0005, 0x008c, 0x0010, 0xe109, 0x0010, 0xc08d,
- 0x0015, 0x0090, 0x0001, 0x1b56, 0x0005, 0x0091, 0x0010, 0xffff,
- 0x0000, 0xb292, 0x0000, 0xb393, 0x0015, 0x009a, 0x0010, 0x0056,
- 0x0005, 0x009b, 0x0010, 0x95f5, 0x0012, 0xd042, 0x0003, 0x1880,
- 0x0005, 0x00b0, 0x0010, 0x8080, 0x0011, 0x1388, 0x0010, 0x0011,
- 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb00a, 0x000b, 0x887b,
- 0x0015, 0x00b8, 0x0010, 0x000c, 0x0014, 0x091f, 0x0003, 0x0882,
- 0x0005, 0x0075, 0x0010, 0x8092, 0x0015, 0x00b1, 0x0010, 0x07d0,
- 0x0005, 0x00b0, 0x0010, 0x0009, 0x0001, 0xbd88, 0x0000, 0x000b,
- 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb012, 0x000b, 0x888b,
- 0x0003, 0x06fd, 0x0015, 0x00d1, 0x0000, 0x0400, 0x0001, 0x1288,
- 0x0010, 0x0003, 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb009,
- 0x001b, 0x8894, 0x0001, 0x1288, 0x0010, 0x0003, 0x0000, 0xff31,
- 0x0015, 0x0033, 0x0010, 0xc00a, 0x000b, 0x889a, 0x0010, 0xb0fe,
- 0x0003, 0x689f, 0x0000, 0xb012, 0x0003, 0x06fd, 0x0010, 0xc012,
- 0x0010, 0xc011, 0x0003, 0x06fd, 0x0000, 0xba30, 0x0005, 0x0031,
- 0x0010, 0x0021, 0x0015, 0x0033, 0x0010, 0xb019, 0x001b, 0x88a7,
- 0x0002, 0xb200, 0x0011, 0xffc8, 0x0010, 0x00ff, 0x0010, 0xffb2,
- 0x0010, 0xb2b7, 0x0005, 0x0031, 0x0000, 0x0023, 0x0015, 0x0033,
- 0x0010, 0xb20a, 0x000b, 0x88b1, 0x0017, 0x4000, 0x0000, 0xba30,
- 0x0005, 0x0031, 0x0000, 0x0023, 0x0015, 0x0033, 0x0010, 0xb409,
- 0x000b, 0x88b8, 0x0002, 0xb400, 0x0011, 0xffc8, 0x0010, 0x00ff,
- 0x0010, 0xffb4, 0x0010, 0xb4b7, 0x0005, 0x0031, 0x0000, 0x0023,
- 0x0015, 0x0033, 0x0010, 0xb40a, 0x001b, 0x88c2, 0x0017, 0x4000,
- 0x0000, 0xba30, 0x0001, 0xc7c8, 0x0000, 0x0020, 0x001b, 0x18d0,
- 0x0005, 0x0031, 0x0010, 0x0028, 0x0015, 0x0033, 0x0010, 0xb209,
- 0x000b, 0x88cc, 0x0011, 0xb2c8, 0x0000, 0xff80, 0x0003, 0x18d3,
- 0x0010, 0xc4b0, 0x0010, 0xc5b1, 0x0013, 0x08d5, 0x0010, 0xc6b1,
- 0x0000, 0xc0b0, 0x0005, 0x0031, 0x0000, 0x0004, 0x0015, 0x0033,
- 0x0010, 0xb211, 0x001b, 0x88d9, 0x0017, 0x4000, 0x0015, 0x00b8,
- 0x0010, 0x0009, 0x0015, 0x003a, 0x0010, 0x0707, 0x0014, 0x091f,
- 0x0013, 0x002d, 0x0015, 0x00b8, 0x0010, 0x0009, 0x0015, 0x003a,
- 0x0010, 0x0707, 0x0003, 0x091f, 0x0004, 0x0119, 0x0015, 0x0030,
- 0x0000, 0x0400, 0x0011, 0x0d88, 0x0000, 0x0004, 0x0000, 0xff31,
- 0x0015, 0x0033, 0x0000, 0xba09, 0x000b, 0x88ee, 0x0004, 0x08a2,
- 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x0d88, 0x0000, 0x0010,
- 0x0000, 0xff31, 0x0015, 0x0033, 0x0010, 0xb20a, 0x001b, 0x88f7,
- 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x0d88, 0x0010, 0x0011,
- 0x0000, 0xff31, 0x0015, 0x0033, 0x0010, 0x0309, 0x000b, 0x88ff,
- 0x0002, 0x0327, 0x0010, 0xffb2, 0x0011, 0x0d88, 0x0010, 0x0011,
- 0x0000, 0xff31, 0x0015, 0x0033, 0x0010, 0xb20a, 0x000b, 0x8907,
- 0x0015, 0x00b8, 0x0010, 0x0006, 0x0003, 0x091f, 0x0014, 0x012b,
- 0x0004, 0x08a2, 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x1388,
- 0x0000, 0x0010, 0x0000, 0xff31, 0x0015, 0x0033, 0x0010, 0xb20a,
- 0x001b, 0x8914, 0x0012, 0x1027, 0x0010, 0xffb2, 0x0011, 0x1388,
- 0x0010, 0x0011, 0x0000, 0xff31, 0x0015, 0x0033, 0x0010, 0xb20a,
- 0x000b, 0x891c, 0x0015, 0x00b8, 0x0000, 0x0007, 0x0013, 0x491f,
- 0x0000, 0xb838, 0x0017, 0x4000, 0x9aec, 0x3b6c
+ 0x0000, 0xb012, 0x001b, 0x8891, 0x0003, 0x0703, 0x0015, 0x00d1,
+ 0x0000, 0x0400, 0x0001, 0x1288, 0x0010, 0x0003, 0x0000, 0xff31,
+ 0x0015, 0x0033, 0x0000, 0xb009, 0x000b, 0x889a, 0x0001, 0x1288,
+ 0x0010, 0x0003, 0x0000, 0xff31, 0x0015, 0x0033, 0x0010, 0xc00a,
+ 0x000b, 0x88a0, 0x0010, 0xb0fe, 0x0003, 0x68a5, 0x0000, 0xb012,
+ 0x0003, 0x0703, 0x0010, 0xc012, 0x0010, 0xc011, 0x0003, 0x0703,
+ 0x0000, 0xba30, 0x0005, 0x0031, 0x0010, 0x0021, 0x0015, 0x0033,
+ 0x0010, 0xb019, 0x001b, 0x88ad, 0x0002, 0xb200, 0x0011, 0xffc8,
+ 0x0010, 0x00ff, 0x0010, 0xffb2, 0x0010, 0xb2b7, 0x0005, 0x0031,
+ 0x0000, 0x0023, 0x0015, 0x0033, 0x0010, 0xb20a, 0x000b, 0x88b7,
+ 0x0017, 0x4000, 0x0000, 0xba30, 0x0005, 0x0031, 0x0000, 0x0023,
+ 0x0015, 0x0033, 0x0010, 0xb409, 0x000b, 0x88be, 0x0002, 0xb400,
+ 0x0011, 0xffc8, 0x0010, 0x00ff, 0x0010, 0xffb4, 0x0010, 0xb4b7,
+ 0x0005, 0x0031, 0x0000, 0x0023, 0x0015, 0x0033, 0x0010, 0xb40a,
+ 0x001b, 0x88c8, 0x0017, 0x4000, 0x0000, 0xba30, 0x0001, 0xc7c8,
+ 0x0000, 0x0020, 0x001b, 0x18d6, 0x0005, 0x0031, 0x0010, 0x0028,
+ 0x0015, 0x0033, 0x0010, 0xb209, 0x000b, 0x88d2, 0x0011, 0xb2c8,
+ 0x0000, 0xff80, 0x0003, 0x18d9, 0x0010, 0xc4b0, 0x0010, 0xc5b1,
+ 0x0003, 0x08db, 0x0010, 0xc6b1, 0x0000, 0xc0b0, 0x0005, 0x0031,
+ 0x0000, 0x0004, 0x0015, 0x0033, 0x0010, 0xb211, 0x001b, 0x88df,
+ 0x0017, 0x4000, 0x0015, 0x00b8, 0x0010, 0x0009, 0x0015, 0x003a,
+ 0x0010, 0x0707, 0x0014, 0x0925, 0x0013, 0x002d, 0x0015, 0x00b8,
+ 0x0010, 0x0009, 0x0015, 0x003a, 0x0010, 0x0707, 0x0003, 0x0925,
+ 0x0004, 0x011c, 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x0d88,
+ 0x0000, 0x0004, 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xba09,
+ 0x001b, 0x88f4, 0x0004, 0x08a8, 0x0015, 0x0030, 0x0000, 0x0400,
+ 0x0011, 0x0d88, 0x0000, 0x0010, 0x0000, 0xff31, 0x0015, 0x0033,
+ 0x0010, 0xb20a, 0x001b, 0x88fd, 0x0015, 0x0030, 0x0000, 0x0400,
+ 0x0011, 0x0d88, 0x0010, 0x0011, 0x0000, 0xff31, 0x0015, 0x0033,
+ 0x0010, 0x0309, 0x001b, 0x8905, 0x0002, 0x0327, 0x0010, 0xffb2,
+ 0x0011, 0x0d88, 0x0010, 0x0011, 0x0000, 0xff31, 0x0015, 0x0033,
+ 0x0010, 0xb20a, 0x000b, 0x890d, 0x0015, 0x00b8, 0x0010, 0x0006,
+ 0x0003, 0x0925, 0x0014, 0x012e, 0x0004, 0x08a8, 0x0015, 0x0030,
+ 0x0000, 0x0400, 0x0011, 0x1388, 0x0000, 0x0010, 0x0000, 0xff31,
+ 0x0015, 0x0033, 0x0010, 0xb20a, 0x000b, 0x891a, 0x0012, 0x1027,
+ 0x0010, 0xffb2, 0x0011, 0x1388, 0x0010, 0x0011, 0x0000, 0xff31,
+ 0x0015, 0x0033, 0x0010, 0xb20a, 0x001b, 0x8922, 0x0015, 0x00b8,
+ 0x0000, 0x0007, 0x0013, 0x4925, 0x0000, 0xb838, 0x0017, 0x4000,
+ 0x9a6c, 0xaf33
};
-unsigned short xseqipx_code_length01 = 0x1246;
+unsigned short xseqipx_code_length01 = 0x1252;
diff --git a/drivers/scsi/qla2xxx/ql6312.c b/drivers/scsi/qla2xxx/ql6312.c
index e75882dd4cf6..de55397f6f4c 100644
--- a/drivers/scsi/qla2xxx/ql6312.c
+++ b/drivers/scsi/qla2xxx/ql6312.c
@@ -1,10 +1,9 @@
/*
- * QLogic ISP6312 device driver for Linux 2.6.x
- * Copyright (C) 2003-2005 QLogic Corporation (www.qlogic.com)
+ * QLogic Fibre Channel HBA Driver
+ * Copyright (c) 2003-2005 QLogic Corporation
*
- * Released under GPL v2.
+ * See LICENSE.qla2xxx for copyright and licensing details.
*/
-
#include <linux/init.h>
#include <linux/module.h>
#include <linux/pci.h>
diff --git a/drivers/scsi/qla2xxx/ql6312_fw.c b/drivers/scsi/qla2xxx/ql6312_fw.c
index 357980942d73..5bb837052ef1 100644
--- a/drivers/scsi/qla2xxx/ql6312_fw.c
+++ b/drivers/scsi/qla2xxx/ql6312_fw.c
@@ -1,24 +1,12 @@
-/******************************************************************************
- * QLOGIC LINUX SOFTWARE
- *
- * QLogic ISP2x00 device driver for Linux 2.6.x
- * Copyright (C) 2005 QLogic Corporation
- * (www.qlogic.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, 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.
+/*
+ * QLogic Fibre Channel HBA Driver
+ * Copyright (c) 2003-2005 QLogic Corporation
*
- ******************************************************************************/
+ * See LICENSE.qla2xxx for copyright and licensing details.
+ */
/*
- * Firmware Version 3.03.15 (10:00 May 26, 2005)
+ * Firmware Version 3.03.18 (12:07 Sep 20, 2005)
*/
#ifdef UNIQUE_FW_NAME
@@ -28,15 +16,15 @@ unsigned short risc_code_version = 3*1024+3;
#endif
#ifdef UNIQUE_FW_NAME
-unsigned char fw2300flx_version_str[] = {3, 3,15};
+unsigned char fw2300flx_version_str[] = {3, 3,18};
#else
-unsigned char firmware_version[] = {3, 3,15};
+unsigned char firmware_version[] = {3, 3,18};
#endif
#ifdef UNIQUE_FW_NAME
-#define fw2300flx_VERSION_STRING "3.03.15"
+#define fw2300flx_VERSION_STRING "3.03.18"
#else
-#define FW_VERSION_STRING "3.03.15"
+#define FW_VERSION_STRING "3.03.18"
#endif
#ifdef UNIQUE_FW_NAME
@@ -50,12 +38,12 @@ unsigned short fw2300flx_code01[] = {
#else
unsigned short risc_code01[] = {
#endif
- 0x0470, 0x0000, 0x0000, 0xdb56, 0x0000, 0x0003, 0x0003, 0x000f,
+ 0x0470, 0x0000, 0x0000, 0xdbb7, 0x0000, 0x0003, 0x0003, 0x0012,
0x0317, 0x2043, 0x4f50, 0x5952, 0x4947, 0x4854, 0x2032, 0x3030,
0x3120, 0x514c, 0x4f47, 0x4943, 0x2043, 0x4f52, 0x504f, 0x5241,
0x5449, 0x4f4e, 0x2049, 0x5350, 0x3233, 0x3030, 0x2046, 0x6972,
0x6d77, 0x6172, 0x6520, 0x2056, 0x6572, 0x7369, 0x6f6e, 0x2030,
- 0x332e, 0x3033, 0x2e31, 0x3520, 0x2020, 0x2020, 0x2400, 0x20a9,
+ 0x332e, 0x3033, 0x2e31, 0x3820, 0x2020, 0x2020, 0x2400, 0x20a9,
0x000f, 0x2001, 0x0000, 0x400f, 0x2091, 0x2200, 0x20a9, 0x000f,
0x2001, 0x0000, 0x400f, 0x2091, 0x2400, 0x20a9, 0x000f, 0x2001,
0x0000, 0x400f, 0x2091, 0x2600, 0x20a9, 0x000f, 0x2001, 0x0000,
@@ -64,8 +52,8 @@ unsigned short risc_code01[] = {
0x2c00, 0x20a9, 0x000f, 0x2001, 0x0000, 0x400f, 0x2091, 0x2e00,
0x20a9, 0x000f, 0x2001, 0x0000, 0x400f, 0x2091, 0x2000, 0x2001,
0x0000, 0x20c1, 0x0004, 0x20c9, 0x1bff, 0x2059, 0x0000, 0x2b78,
- 0x7883, 0x0004, 0x2089, 0x2c1f, 0x2051, 0x1800, 0x2a70, 0x20e1,
- 0x0001, 0x20e9, 0x0001, 0x2009, 0x0000, 0x080c, 0x0e87, 0x2029,
+ 0x7883, 0x0004, 0x2089, 0x2c06, 0x2051, 0x1800, 0x2a70, 0x20e1,
+ 0x0001, 0x20e9, 0x0001, 0x2009, 0x0000, 0x080c, 0x0e7b, 0x2029,
0x2480, 0x2031, 0xffff, 0x2039, 0x2450, 0x2021, 0x0050, 0x20e9,
0x0001, 0x20a1, 0x0000, 0x20a9, 0x0800, 0x900e, 0x4104, 0x20e9,
0x0001, 0x20a1, 0x1000, 0x900e, 0x2001, 0x0cc0, 0x9084, 0x0fff,
@@ -77,7002 +65,7014 @@ unsigned short risc_code01[] = {
0x8001, 0x9102, 0x0120, 0x0218, 0x20a8, 0x900e, 0x4104, 0x2009,
0x1800, 0x810d, 0x810d, 0x810d, 0x810d, 0x810d, 0x918c, 0x001f,
0x2001, 0x0001, 0x9112, 0x20e9, 0x0001, 0x20a1, 0x0800, 0x900e,
- 0x20a9, 0x0800, 0x4104, 0x8211, 0x1dd8, 0x080c, 0x0f5b, 0x080c,
- 0x5e3e, 0x080c, 0x9f6b, 0x080c, 0x1112, 0x080c, 0x130a, 0x080c,
- 0x1a79, 0x080c, 0x0d94, 0x080c, 0x1097, 0x080c, 0x3309, 0x080c,
- 0x748f, 0x080c, 0x6785, 0x080c, 0x8195, 0x080c, 0x22b7, 0x080c,
- 0x84a6, 0x080c, 0x7b19, 0x080c, 0x20e3, 0x080c, 0x2217, 0x080c,
- 0x22ac, 0x2091, 0x3009, 0x7883, 0x0000, 0x1004, 0x091d, 0x7880,
+ 0x20a9, 0x0800, 0x4104, 0x8211, 0x1dd8, 0x080c, 0x0f4f, 0x080c,
+ 0x5e3d, 0x080c, 0x9f80, 0x080c, 0x1106, 0x080c, 0x12fe, 0x080c,
+ 0x1a75, 0x080c, 0x0d88, 0x080c, 0x108b, 0x080c, 0x32f3, 0x080c,
+ 0x748e, 0x080c, 0x6784, 0x080c, 0x8194, 0x080c, 0x22b3, 0x080c,
+ 0x84a5, 0x080c, 0x7b18, 0x080c, 0x20df, 0x080c, 0x2213, 0x080c,
+ 0x22a8, 0x2091, 0x3009, 0x7883, 0x0000, 0x1004, 0x091d, 0x7880,
0x9086, 0x0002, 0x1190, 0x7883, 0x4000, 0x7837, 0x4000, 0x7833,
0x0010, 0x0e04, 0x0911, 0x2091, 0x5000, 0x2091, 0x4080, 0x2001,
- 0x0089, 0x2004, 0xd084, 0x190c, 0x11f2, 0x2071, 0x1800, 0x7003,
+ 0x0089, 0x2004, 0xd084, 0x190c, 0x11e6, 0x2071, 0x1800, 0x7003,
0x0000, 0x2071, 0x1800, 0x7000, 0x908e, 0x0003, 0x1168, 0x080c,
- 0x4add, 0x080c, 0x3330, 0x080c, 0x74f7, 0x080c, 0x6c83, 0x080c,
- 0x81be, 0x080c, 0x2b2c, 0x0c68, 0x000b, 0x0c88, 0x0940, 0x0941,
- 0x0ad8, 0x093e, 0x0b8f, 0x0d93, 0x0d93, 0x0d93, 0x080c, 0x0e02,
+ 0x4adc, 0x080c, 0x331a, 0x080c, 0x74f6, 0x080c, 0x6c82, 0x080c,
+ 0x81bd, 0x080c, 0x2b13, 0x0c68, 0x000b, 0x0c88, 0x0940, 0x0941,
+ 0x0ad8, 0x093e, 0x0b8f, 0x0d87, 0x0d87, 0x0d87, 0x080c, 0x0df6,
0x0005, 0x0126, 0x00f6, 0x2091, 0x8000, 0x7000, 0x9086, 0x0001,
- 0x1904, 0x0aab, 0x080c, 0x0ec9, 0x080c, 0x717f, 0x0150, 0x080c,
- 0x71a2, 0x15a0, 0x2079, 0x0100, 0x7828, 0x9085, 0x1800, 0x782a,
- 0x0468, 0x080c, 0x709f, 0x7000, 0x9086, 0x0001, 0x1904, 0x0aab,
- 0x7094, 0x9086, 0x0029, 0x1904, 0x0aab, 0x080c, 0x817e, 0x080c,
- 0x8170, 0x2001, 0x0161, 0x2003, 0x0001, 0x2079, 0x0100, 0x7827,
- 0xffff, 0x7a28, 0x9295, 0x5e2f, 0x7a2a, 0x2011, 0x6fee, 0x080c,
- 0x825a, 0x2011, 0x6fe1, 0x080c, 0x832e, 0x2011, 0x5c99, 0x080c,
- 0x825a, 0x2011, 0x8030, 0x901e, 0x7392, 0x04d0, 0x080c, 0x5546,
- 0x2079, 0x0100, 0x7844, 0x9005, 0x1904, 0x0aab, 0x2011, 0x5c99,
- 0x080c, 0x825a, 0x2011, 0x6fee, 0x080c, 0x825a, 0x2011, 0x6fe1,
- 0x080c, 0x832e, 0x2001, 0x0265, 0x2001, 0x0205, 0x2003, 0x0000,
- 0x7840, 0x9084, 0xfffb, 0x7842, 0x2001, 0x1980, 0x2004, 0x9005,
- 0x1140, 0x00c6, 0x2061, 0x0100, 0x080c, 0x5de6, 0x00ce, 0x0804,
- 0x0aab, 0x780f, 0x006b, 0x7a28, 0x080c, 0x7187, 0x0118, 0x9295,
+ 0x1904, 0x0aab, 0x080c, 0x0ebd, 0x080c, 0x717e, 0x0150, 0x080c,
+ 0x71a1, 0x15a0, 0x2079, 0x0100, 0x7828, 0x9085, 0x1800, 0x782a,
+ 0x0468, 0x080c, 0x709e, 0x7000, 0x9086, 0x0001, 0x1904, 0x0aab,
+ 0x7094, 0x9086, 0x0029, 0x1904, 0x0aab, 0x080c, 0x817d, 0x080c,
+ 0x816f, 0x2001, 0x0161, 0x2003, 0x0001, 0x2079, 0x0100, 0x7827,
+ 0xffff, 0x7a28, 0x9295, 0x5e2f, 0x7a2a, 0x2011, 0x6fed, 0x080c,
+ 0x8259, 0x2011, 0x6fe0, 0x080c, 0x832d, 0x2011, 0x5c98, 0x080c,
+ 0x8259, 0x2011, 0x8030, 0x901e, 0x7392, 0x04d0, 0x080c, 0x5545,
+ 0x2079, 0x0100, 0x7844, 0x9005, 0x1904, 0x0aab, 0x2011, 0x5c98,
+ 0x080c, 0x8259, 0x2011, 0x6fed, 0x080c, 0x8259, 0x2011, 0x6fe0,
+ 0x080c, 0x832d, 0x2001, 0x0265, 0x2001, 0x0205, 0x2003, 0x0000,
+ 0x7840, 0x9084, 0xfffb, 0x7842, 0x2001, 0x1981, 0x2004, 0x9005,
+ 0x1140, 0x00c6, 0x2061, 0x0100, 0x080c, 0x5de5, 0x00ce, 0x0804,
+ 0x0aab, 0x780f, 0x006b, 0x7a28, 0x080c, 0x7186, 0x0118, 0x9295,
0x5e2f, 0x0010, 0x9295, 0x402f, 0x7a2a, 0x2011, 0x8010, 0x73d4,
- 0x2001, 0x1981, 0x2003, 0x0001, 0x080c, 0x2989, 0x080c, 0x4a18,
+ 0x2001, 0x1982, 0x2003, 0x0001, 0x080c, 0x2974, 0x080c, 0x4a17,
0x7244, 0xc284, 0x7246, 0x2001, 0x180c, 0x200c, 0xc1ac, 0xc1cc,
- 0x2102, 0x080c, 0x9803, 0x2011, 0x0004, 0x080c, 0xbd4b, 0x080c,
- 0x65c7, 0x080c, 0x717f, 0x1120, 0x080c, 0x29f6, 0x02e0, 0x0400,
- 0x080c, 0x5ded, 0x0140, 0x7093, 0x0001, 0x70cf, 0x0000, 0x080c,
- 0x5713, 0x0804, 0x0aab, 0x080c, 0x54dc, 0xd094, 0x0188, 0x2011,
- 0x180c, 0x2204, 0xc0cd, 0x2012, 0x080c, 0x54e0, 0xd0d4, 0x1118,
- 0x080c, 0x29f6, 0x1270, 0x2011, 0x180c, 0x2204, 0xc0bc, 0x0088,
- 0x080c, 0x54e0, 0xd0d4, 0x1db8, 0x2011, 0x180c, 0x2204, 0xc0bd,
- 0x0040, 0x2011, 0x180c, 0x2204, 0xc0bd, 0x2012, 0x080c, 0x66c2,
- 0x0008, 0x2012, 0x080c, 0x6688, 0x0120, 0x7a0c, 0xc2b4, 0x7a0e,
- 0x00a8, 0x707b, 0x0000, 0x080c, 0x717f, 0x1130, 0x70ac, 0x9005,
- 0x1168, 0x080c, 0xc18e, 0x0050, 0x080c, 0xc18e, 0x70d8, 0xd09c,
- 0x1128, 0x70ac, 0x9005, 0x0110, 0x080c, 0x5dc3, 0x70e3, 0x0000,
- 0x70df, 0x0000, 0x70a3, 0x0000, 0x080c, 0x29fe, 0x0228, 0x2011,
- 0x0101, 0x2204, 0xc0c4, 0x2012, 0x72d8, 0x080c, 0x717f, 0x1178,
+ 0x2102, 0x080c, 0x9818, 0x2011, 0x0004, 0x080c, 0xbd5e, 0x080c,
+ 0x65c6, 0x080c, 0x717e, 0x1120, 0x080c, 0x29e1, 0x02e0, 0x0400,
+ 0x080c, 0x5dec, 0x0140, 0x7093, 0x0001, 0x70cf, 0x0000, 0x080c,
+ 0x5712, 0x0804, 0x0aab, 0x080c, 0x54db, 0xd094, 0x0188, 0x2011,
+ 0x180c, 0x2204, 0xc0cd, 0x2012, 0x080c, 0x54df, 0xd0d4, 0x1118,
+ 0x080c, 0x29e1, 0x1270, 0x2011, 0x180c, 0x2204, 0xc0bc, 0x0088,
+ 0x080c, 0x54df, 0xd0d4, 0x1db8, 0x2011, 0x180c, 0x2204, 0xc0bd,
+ 0x0040, 0x2011, 0x180c, 0x2204, 0xc0bd, 0x2012, 0x080c, 0x66c1,
+ 0x0008, 0x2012, 0x080c, 0x6687, 0x0120, 0x7a0c, 0xc2b4, 0x7a0e,
+ 0x00a8, 0x707b, 0x0000, 0x080c, 0x717e, 0x1130, 0x70ac, 0x9005,
+ 0x1168, 0x080c, 0xc1a1, 0x0050, 0x080c, 0xc1a1, 0x70d8, 0xd09c,
+ 0x1128, 0x70ac, 0x9005, 0x0110, 0x080c, 0x5dc2, 0x70e3, 0x0000,
+ 0x70df, 0x0000, 0x70a3, 0x0000, 0x080c, 0x29e9, 0x0228, 0x2011,
+ 0x0101, 0x2204, 0xc0c4, 0x2012, 0x72d8, 0x080c, 0x717e, 0x1178,
0x9016, 0x0016, 0x2009, 0x0002, 0x2019, 0x1947, 0x211a, 0x001e,
0x705b, 0xffff, 0x705f, 0x00ef, 0x707f, 0x0000, 0x0020, 0x2019,
0x1947, 0x201b, 0x0000, 0x2079, 0x185b, 0x7804, 0xd0ac, 0x0108,
- 0xc295, 0x72da, 0x080c, 0x717f, 0x0118, 0x9296, 0x0004, 0x0548,
- 0x2011, 0x0001, 0x080c, 0xbd4b, 0x70a7, 0x0000, 0x70ab, 0xffff,
+ 0xc295, 0x72da, 0x080c, 0x717e, 0x0118, 0x9296, 0x0004, 0x0548,
+ 0x2011, 0x0001, 0x080c, 0xbd5e, 0x70a7, 0x0000, 0x70ab, 0xffff,
0x7003, 0x0002, 0x2079, 0x0100, 0x7827, 0x0003, 0x7828, 0x9085,
- 0x0003, 0x782a, 0x00fe, 0x080c, 0x2e8c, 0x2011, 0x0005, 0x080c,
- 0x990e, 0x080c, 0x8b90, 0x080c, 0x717f, 0x0148, 0x00c6, 0x2061,
+ 0x0003, 0x782a, 0x00fe, 0x080c, 0x2e73, 0x2011, 0x0005, 0x080c,
+ 0x9923, 0x080c, 0x8b8f, 0x080c, 0x717e, 0x0148, 0x00c6, 0x2061,
0x0100, 0x0016, 0x2009, 0x0002, 0x61e2, 0x001e, 0x00ce, 0x012e,
0x0420, 0x70a7, 0x0000, 0x70ab, 0xffff, 0x7003, 0x0002, 0x00f6,
0x2079, 0x0100, 0x7827, 0x0003, 0x7828, 0x9085, 0x0003, 0x782a,
- 0x00fe, 0x2011, 0x0005, 0x080c, 0x990e, 0x080c, 0x8b90, 0x080c,
- 0x717f, 0x0148, 0x00c6, 0x2061, 0x0100, 0x0016, 0x2009, 0x0002,
+ 0x00fe, 0x2011, 0x0005, 0x080c, 0x9923, 0x080c, 0x8b8f, 0x080c,
+ 0x717e, 0x0148, 0x00c6, 0x2061, 0x0100, 0x0016, 0x2009, 0x0002,
0x61e2, 0x001e, 0x00ce, 0x00fe, 0x012e, 0x0005, 0x00c6, 0x00b6,
- 0x080c, 0x717f, 0x1118, 0x20a9, 0x0800, 0x0010, 0x20a9, 0x0782,
- 0x080c, 0x717f, 0x1110, 0x900e, 0x0010, 0x2009, 0x007e, 0x86ff,
+ 0x080c, 0x717e, 0x1118, 0x20a9, 0x0800, 0x0010, 0x20a9, 0x0782,
+ 0x080c, 0x717e, 0x1110, 0x900e, 0x0010, 0x2009, 0x007e, 0x86ff,
0x0138, 0x9180, 0x1000, 0x2004, 0x905d, 0x0110, 0xb800, 0xd0bc,
- 0x090c, 0x31a6, 0x8108, 0x1f04, 0x0abf, 0x707b, 0x0000, 0x707c,
+ 0x090c, 0x3190, 0x8108, 0x1f04, 0x0abf, 0x707b, 0x0000, 0x707c,
0x9084, 0x00ff, 0x707e, 0x70af, 0x0000, 0x00be, 0x00ce, 0x0005,
0x00b6, 0x0126, 0x2091, 0x8000, 0x7000, 0x9086, 0x0002, 0x1904,
- 0x0b8c, 0x70a8, 0x9086, 0xffff, 0x0130, 0x080c, 0x2e8c, 0x080c,
- 0x8b90, 0x0804, 0x0b8c, 0x70d8, 0xd0ac, 0x1110, 0xd09c, 0x0540,
+ 0x0b8c, 0x70a8, 0x9086, 0xffff, 0x0130, 0x080c, 0x2e73, 0x080c,
+ 0x8b8f, 0x0804, 0x0b8c, 0x70d8, 0xd0ac, 0x1110, 0xd09c, 0x0540,
0xd084, 0x0530, 0x0006, 0x2001, 0x0103, 0x2003, 0x002b, 0x000e,
- 0xd08c, 0x01f0, 0x70dc, 0x9086, 0xffff, 0x01b0, 0x080c, 0x3017,
- 0x080c, 0x8b90, 0x70d8, 0xd094, 0x1904, 0x0b8c, 0x2011, 0x0001,
- 0x080c, 0xc444, 0x0110, 0x2011, 0x0003, 0x901e, 0x080c, 0x3051,
- 0x080c, 0x8b90, 0x0804, 0x0b8c, 0x70e0, 0x9005, 0x1904, 0x0b8c,
+ 0xd08c, 0x01f0, 0x70dc, 0x9086, 0xffff, 0x01b0, 0x080c, 0x3001,
+ 0x080c, 0x8b8f, 0x70d8, 0xd094, 0x1904, 0x0b8c, 0x2011, 0x0001,
+ 0x080c, 0xc459, 0x0110, 0x2011, 0x0003, 0x901e, 0x080c, 0x303b,
+ 0x080c, 0x8b8f, 0x0804, 0x0b8c, 0x70e0, 0x9005, 0x1904, 0x0b8c,
0x70a4, 0x9005, 0x1904, 0x0b8c, 0x70d8, 0xd0a4, 0x0118, 0xd0b4,
- 0x0904, 0x0b8c, 0x080c, 0x6688, 0x1904, 0x0b8c, 0x080c, 0x66db,
- 0x1904, 0x0b8c, 0x080c, 0x66c2, 0x01c0, 0x0156, 0x00c6, 0x20a9,
- 0x007f, 0x900e, 0x0016, 0x080c, 0x63a4, 0x1118, 0xb800, 0xd0ec,
+ 0x0904, 0x0b8c, 0x080c, 0x6687, 0x1904, 0x0b8c, 0x080c, 0x66da,
+ 0x1904, 0x0b8c, 0x080c, 0x66c1, 0x01c0, 0x0156, 0x00c6, 0x20a9,
+ 0x007f, 0x900e, 0x0016, 0x080c, 0x63a3, 0x1118, 0xb800, 0xd0ec,
0x1138, 0x001e, 0x8108, 0x1f04, 0x0b32, 0x00ce, 0x015e, 0x0028,
0x001e, 0x00ce, 0x015e, 0x0804, 0x0b8c, 0x0006, 0x2001, 0x0103,
- 0x2003, 0x006b, 0x000e, 0x2011, 0x198e, 0x080c, 0x0fcb, 0x2011,
- 0x19a8, 0x080c, 0x0fcb, 0x7030, 0xc08c, 0x7032, 0x7003, 0x0003,
- 0x70ab, 0xffff, 0x080c, 0x0eab, 0x9006, 0x080c, 0x2617, 0x0036,
- 0x0046, 0x2019, 0xffff, 0x2021, 0x0006, 0x080c, 0x4bb5, 0x004e,
- 0x003e, 0x00f6, 0x2079, 0x0100, 0x080c, 0x71a2, 0x0150, 0x080c,
- 0x717f, 0x7828, 0x0118, 0x9084, 0xe1ff, 0x0010, 0x9084, 0xffdf,
+ 0x2003, 0x006b, 0x000e, 0x2011, 0x198e, 0x080c, 0x0fbf, 0x2011,
+ 0x19a8, 0x080c, 0x0fbf, 0x7030, 0xc08c, 0x7032, 0x7003, 0x0003,
+ 0x70ab, 0xffff, 0x080c, 0x0e9f, 0x9006, 0x080c, 0x2616, 0x0036,
+ 0x0046, 0x2019, 0xffff, 0x2021, 0x0006, 0x080c, 0x4bb4, 0x004e,
+ 0x003e, 0x00f6, 0x2079, 0x0100, 0x080c, 0x71a1, 0x0150, 0x080c,
+ 0x717e, 0x7828, 0x0118, 0x9084, 0xe1ff, 0x0010, 0x9084, 0xffdf,
0x782a, 0x00fe, 0x2001, 0x19c3, 0x2004, 0x9086, 0x0005, 0x1120,
- 0x2011, 0x0000, 0x080c, 0x990e, 0x2011, 0x0000, 0x080c, 0x9918,
- 0x080c, 0x8b90, 0x080c, 0x8c6d, 0x012e, 0x00be, 0x0005, 0x0016,
+ 0x2011, 0x0000, 0x080c, 0x9923, 0x2011, 0x0000, 0x080c, 0x992d,
+ 0x080c, 0x8b8f, 0x080c, 0x8c6c, 0x012e, 0x00be, 0x0005, 0x0016,
0x0046, 0x00f6, 0x0126, 0x2091, 0x8000, 0x2079, 0x0100, 0x7904,
- 0x918c, 0xfffd, 0x7906, 0x2009, 0x00f7, 0x080c, 0x5dac, 0x7940,
+ 0x918c, 0xfffd, 0x7906, 0x2009, 0x00f7, 0x080c, 0x5dab, 0x7940,
0x918c, 0x0010, 0x7942, 0x7924, 0xd1b4, 0x0110, 0x7827, 0x0040,
0xd19c, 0x0110, 0x7827, 0x0008, 0x0006, 0x0036, 0x0156, 0x2001,
0x0100, 0x2004, 0x9086, 0x000a, 0x1904, 0x0c23, 0x7954, 0xd1ac,
- 0x1904, 0x0c23, 0x2001, 0x1981, 0x2004, 0x9005, 0x1518, 0x080c,
- 0x2a98, 0x1148, 0x2001, 0x0001, 0x080c, 0x29b8, 0x2001, 0x0001,
- 0x080c, 0x299b, 0x00b8, 0x080c, 0x2aa0, 0x1138, 0x9006, 0x080c,
- 0x29b8, 0x9006, 0x080c, 0x299b, 0x0068, 0x080c, 0x2aa8, 0x1d50,
- 0x2001, 0x1972, 0x2004, 0xd0fc, 0x0108, 0x0020, 0x080c, 0x27b2,
- 0x0804, 0x0d3b, 0x080c, 0x7190, 0x0148, 0x080c, 0x71a2, 0x1118,
- 0x080c, 0x748a, 0x0050, 0x080c, 0x7187, 0x0dd0, 0x080c, 0x7485,
- 0x080c, 0x747b, 0x080c, 0x709f, 0x0058, 0x080c, 0x717f, 0x0140,
- 0x2009, 0x00f8, 0x080c, 0x5dac, 0x7843, 0x0090, 0x7843, 0x0010,
- 0x20a9, 0x09c4, 0x7820, 0xd09c, 0x1138, 0x080c, 0x717f, 0x0138,
- 0x7824, 0xd0ac, 0x1904, 0x0d40, 0x1f04, 0x0c02, 0x0070, 0x7824,
- 0x080c, 0x7199, 0x0118, 0xd0ac, 0x1904, 0x0d40, 0x9084, 0x1800,
- 0x0d98, 0x7003, 0x0001, 0x0804, 0x0d40, 0x2001, 0x0001, 0x080c,
- 0x2617, 0x0804, 0x0d62, 0x2001, 0x1981, 0x2004, 0x9005, 0x1518,
- 0x080c, 0x2a98, 0x1148, 0x2001, 0x0001, 0x080c, 0x29b8, 0x2001,
- 0x0001, 0x080c, 0x299b, 0x00b8, 0x080c, 0x2aa0, 0x1138, 0x9006,
- 0x080c, 0x29b8, 0x9006, 0x080c, 0x299b, 0x0068, 0x080c, 0x2aa8,
+ 0x1904, 0x0c23, 0x2001, 0x1982, 0x2004, 0x9005, 0x1518, 0x080c,
+ 0x2a7f, 0x1148, 0x2001, 0x0001, 0x080c, 0x29a3, 0x2001, 0x0001,
+ 0x080c, 0x2986, 0x00b8, 0x080c, 0x2a87, 0x1138, 0x9006, 0x080c,
+ 0x29a3, 0x9006, 0x080c, 0x2986, 0x0068, 0x080c, 0x2a8f, 0x1d50,
+ 0x2001, 0x1972, 0x2004, 0xd0fc, 0x0108, 0x0020, 0x080c, 0x27b1,
+ 0x0804, 0x0d2f, 0x080c, 0x718f, 0x0148, 0x080c, 0x71a1, 0x1118,
+ 0x080c, 0x7489, 0x0050, 0x080c, 0x7186, 0x0dd0, 0x080c, 0x7484,
+ 0x080c, 0x747a, 0x080c, 0x709e, 0x0058, 0x080c, 0x717e, 0x0140,
+ 0x2009, 0x00f8, 0x080c, 0x5dab, 0x7843, 0x0090, 0x7843, 0x0010,
+ 0x20a9, 0x09c4, 0x7820, 0xd09c, 0x1138, 0x080c, 0x717e, 0x0138,
+ 0x7824, 0xd0ac, 0x1904, 0x0d34, 0x1f04, 0x0c02, 0x0070, 0x7824,
+ 0x080c, 0x7198, 0x0118, 0xd0ac, 0x1904, 0x0d34, 0x9084, 0x1800,
+ 0x0d98, 0x7003, 0x0001, 0x0804, 0x0d34, 0x2001, 0x0001, 0x080c,
+ 0x2616, 0x0804, 0x0d56, 0x2001, 0x1982, 0x2004, 0x9005, 0x1518,
+ 0x080c, 0x2a7f, 0x1148, 0x2001, 0x0001, 0x080c, 0x29a3, 0x2001,
+ 0x0001, 0x080c, 0x2986, 0x00b8, 0x080c, 0x2a87, 0x1138, 0x9006,
+ 0x080c, 0x29a3, 0x9006, 0x080c, 0x2986, 0x0068, 0x080c, 0x2a8f,
0x1d50, 0x2001, 0x1972, 0x2004, 0xd0fc, 0x0108, 0x0020, 0x080c,
- 0x27b2, 0x0804, 0x0d3b, 0x2001, 0x0100, 0x2004, 0x9086, 0x000a,
+ 0x27b1, 0x0804, 0x0d2f, 0x2001, 0x0100, 0x2004, 0x9086, 0x000a,
0x01f8, 0x7850, 0x9085, 0x0040, 0x7852, 0x7938, 0x7850, 0x9084,
- 0xfbcf, 0x7852, 0x080c, 0x2ab0, 0x9085, 0x2000, 0x7852, 0x793a,
- 0x20a9, 0x0046, 0x1d04, 0x0c62, 0x080c, 0x830e, 0x1f04, 0x0c62,
- 0x7850, 0x9085, 0x0400, 0x9084, 0xdfbf, 0x7852, 0x793a, 0x00a0,
- 0x2009, 0x198a, 0x2104, 0x8000, 0x200a, 0x9084, 0x0001, 0x0120,
- 0x080c, 0x2bc2, 0x080c, 0x2bf5, 0x20a9, 0x003a, 0x1d04, 0x0c7e,
- 0x080c, 0x830e, 0x1f04, 0x0c7e, 0x080c, 0x7190, 0x0148, 0x080c,
- 0x71a2, 0x1118, 0x080c, 0x748a, 0x0050, 0x080c, 0x7187, 0x0dd0,
- 0x080c, 0x7485, 0x080c, 0x747b, 0x080c, 0x709f, 0x0020, 0x2009,
- 0x00f8, 0x080c, 0x5dac, 0x2001, 0x0100, 0x2004, 0x9086, 0x000a,
- 0x0168, 0x20a9, 0x0028, 0xa001, 0x1f04, 0x0ca3, 0x7850, 0x9085,
- 0x1400, 0x7852, 0x080c, 0x717f, 0x0158, 0x0030, 0x7850, 0xc0e5,
- 0x7852, 0x080c, 0x717f, 0x0120, 0x7843, 0x0090, 0x7843, 0x0010,
- 0x2021, 0xe678, 0x2019, 0xea60, 0x0d0c, 0x830e, 0x7820, 0xd09c,
- 0x1590, 0x080c, 0x717f, 0x0904, 0x0d1f, 0x7824, 0xd0ac, 0x1904,
- 0x0d40, 0x080c, 0x71a2, 0x1538, 0x0046, 0x2021, 0x0320, 0x8421,
- 0x1df0, 0x004e, 0x7827, 0x1800, 0x080c, 0x2ab0, 0x7824, 0x9084,
- 0x1800, 0x1168, 0x9484, 0x0fff, 0x1140, 0x2001, 0x1810, 0x2004,
- 0x9084, 0x9000, 0x0110, 0x080c, 0x0d70, 0x8421, 0x1160, 0x1d04,
- 0x0ceb, 0x080c, 0x830e, 0x080c, 0x7485, 0x080c, 0x747b, 0x7003,
- 0x0001, 0x0804, 0x0d40, 0x8319, 0x1938, 0x2001, 0x0100, 0x2004,
- 0x9086, 0x000a, 0x1140, 0x2001, 0x1810, 0x2004, 0x9084, 0x9000,
- 0x0110, 0x080c, 0x0d70, 0x1d04, 0x0d07, 0x080c, 0x830e, 0x2009,
- 0x1975, 0x2104, 0x9005, 0x0118, 0x8001, 0x200a, 0x1178, 0x200b,
- 0x000a, 0x7827, 0x0048, 0x20a9, 0x0002, 0x080c, 0x2a91, 0x7924,
- 0x080c, 0x2ab0, 0xd19c, 0x0110, 0x080c, 0x2989, 0x00e0, 0x080c,
- 0x7190, 0x1140, 0x94a2, 0x03e8, 0x1128, 0x080c, 0x7157, 0x7003,
- 0x0001, 0x00b0, 0x7827, 0x1800, 0x080c, 0x2ab0, 0x7824, 0x080c,
- 0x7199, 0x0110, 0xd0ac, 0x1160, 0x9084, 0x1800, 0x0904, 0x0cf3,
- 0x7003, 0x0001, 0x0028, 0x2001, 0x0001, 0x080c, 0x2617, 0x00c0,
- 0x2001, 0x0100, 0x2004, 0x9086, 0x000a, 0x1118, 0x7850, 0xc0e4,
- 0x7852, 0x2009, 0x180c, 0x210c, 0xd19c, 0x1120, 0x7904, 0x918d,
- 0x0002, 0x7906, 0x7827, 0x0048, 0x7828, 0x9085, 0x0028, 0x782a,
- 0x2001, 0x0100, 0x2004, 0x9086, 0x000a, 0x0120, 0x7850, 0x9085,
- 0x0400, 0x7852, 0x2001, 0x1981, 0x2003, 0x0000, 0x9006, 0x78f2,
- 0x015e, 0x003e, 0x000e, 0x012e, 0x00fe, 0x004e, 0x001e, 0x0005,
- 0x0006, 0x0016, 0x0036, 0x0046, 0x00b6, 0x00c6, 0x00d6, 0x00e6,
- 0x00f6, 0x0156, 0x0069, 0x0d0c, 0x830e, 0x015e, 0x00fe, 0x00ee,
- 0x00de, 0x00ce, 0x00be, 0x004e, 0x003e, 0x001e, 0x000e, 0x0005,
- 0x00e6, 0x2071, 0x189c, 0x7004, 0x9086, 0x0001, 0x1110, 0x080c,
- 0x3330, 0x00ee, 0x0005, 0x0005, 0x2a70, 0x2061, 0x1985, 0x2063,
- 0x0003, 0x6007, 0x0003, 0x600b, 0x000f, 0x600f, 0x0317, 0x2001,
- 0x1956, 0x900e, 0x2102, 0x7192, 0x2001, 0x0100, 0x2004, 0x9082,
- 0x0002, 0x0218, 0x705b, 0xffff, 0x0008, 0x715a, 0x7063, 0xffff,
- 0x717a, 0x717e, 0x080c, 0xc18e, 0x70e7, 0x00c0, 0x2061, 0x1946,
- 0x6003, 0x0909, 0x6106, 0x600b, 0x8800, 0x600f, 0x0200, 0x6013,
- 0x00ff, 0x6017, 0x000f, 0x611a, 0x601f, 0x07d0, 0x2061, 0x194e,
- 0x6003, 0x8000, 0x6106, 0x610a, 0x600f, 0x0200, 0x6013, 0x00ff,
- 0x6116, 0x601b, 0x0001, 0x611e, 0x2061, 0x1963, 0x6003, 0x514c,
- 0x6007, 0x4f47, 0x600b, 0x4943, 0x600f, 0x2020, 0x2001, 0x182b,
- 0x2102, 0x0005, 0x9016, 0x080c, 0x63a4, 0x1178, 0xb804, 0x90c4,
- 0x00ff, 0x98c6, 0x0006, 0x0128, 0x90c4, 0xff00, 0x98c6, 0x0600,
- 0x1120, 0x9186, 0x0080, 0x0108, 0x8210, 0x8108, 0x9186, 0x0800,
- 0x1d50, 0x2208, 0x0005, 0x2091, 0x8000, 0x2079, 0x0000, 0x000e,
- 0x00f6, 0x0010, 0x2091, 0x8000, 0x0e04, 0x0e04, 0x0006, 0x0016,
- 0x2001, 0x8002, 0x0006, 0x2079, 0x0000, 0x000e, 0x7882, 0x7836,
- 0x001e, 0x798e, 0x000e, 0x788a, 0x000e, 0x7886, 0x3900, 0x789a,
- 0x00d6, 0x2069, 0x0300, 0x6818, 0x78ae, 0x681c, 0x78b2, 0x6808,
- 0x78be, 0x00de, 0x7833, 0x0012, 0x2091, 0x5000, 0x0156, 0x00d6,
- 0x0036, 0x0026, 0x2079, 0x0300, 0x2069, 0x1a7a, 0x7a08, 0x226a,
- 0x2069, 0x1a7b, 0x7a18, 0x226a, 0x8d68, 0x7a1c, 0x226a, 0x782c,
- 0x2019, 0x1a88, 0x201a, 0x2019, 0x1a8b, 0x9016, 0x7808, 0xd09c,
- 0x0168, 0x7820, 0x201a, 0x8210, 0x8318, 0x9386, 0x1aa0, 0x0108,
- 0x0ca8, 0x7808, 0xd09c, 0x0110, 0x2011, 0xdead, 0x2019, 0x1a89,
- 0x782c, 0x201a, 0x8318, 0x221a, 0x7803, 0x0000, 0x2069, 0x1a5a,
- 0x901e, 0x20a9, 0x0020, 0x7b26, 0x7a28, 0x226a, 0x8d68, 0x8318,
- 0x1f04, 0x0e5b, 0x002e, 0x003e, 0x00de, 0x015e, 0x2079, 0x1800,
- 0x7803, 0x0005, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084,
- 0x0180, 0x2001, 0x19f6, 0x2004, 0x9005, 0x0128, 0x2001, 0x008b,
- 0x2004, 0xd0fc, 0x0dd8, 0x2001, 0x008a, 0x2003, 0x0002, 0x2003,
- 0x1001, 0x080c, 0x54eb, 0x1108, 0x0099, 0x0cd8, 0x0005, 0x918c,
- 0x03ff, 0x2001, 0x0003, 0x2004, 0x9084, 0x0600, 0x1118, 0x918d,
- 0x6c00, 0x0010, 0x918d, 0x6400, 0x2001, 0x017f, 0x2102, 0x0005,
- 0x0026, 0x0126, 0x2011, 0x0080, 0x080c, 0x0f23, 0x20a9, 0x0900,
- 0x080c, 0x0f44, 0x2011, 0x0040, 0x080c, 0x0f23, 0x20a9, 0x0900,
- 0x080c, 0x0f44, 0x0c78, 0x0026, 0x080c, 0x0f30, 0x1118, 0x2011,
- 0x0040, 0x0098, 0x2011, 0x010e, 0x2214, 0x9294, 0x0007, 0x9296,
- 0x0007, 0x0118, 0x2011, 0xa880, 0x0010, 0x2011, 0x6840, 0xd0e4,
- 0x70eb, 0x0000, 0x1120, 0x70eb, 0x0fa0, 0x080c, 0x0f35, 0x002e,
- 0x0005, 0x0026, 0x080c, 0x0f30, 0x0128, 0xd0a4, 0x1138, 0x2011,
- 0xcdd5, 0x0010, 0x2011, 0x0080, 0x080c, 0x0f35, 0x002e, 0x0005,
- 0x0026, 0x70eb, 0x0000, 0x080c, 0x0f30, 0x1148, 0x080c, 0x2aa8,
- 0x1118, 0x2011, 0x8484, 0x0058, 0x2011, 0x8282, 0x0040, 0x080c,
- 0x2aa8, 0x1118, 0x2011, 0xcdc5, 0x0010, 0x2011, 0xcac2, 0x080c,
- 0x0f35, 0x002e, 0x0005, 0x00e6, 0x0006, 0x2071, 0x1800, 0xd0b4,
- 0x70e4, 0x1110, 0xc0e4, 0x0048, 0x0006, 0x3b00, 0x9084, 0xff3f,
- 0x20d8, 0x000e, 0x70eb, 0x0000, 0xc0e5, 0x0079, 0x000e, 0x00ee,
- 0x0005, 0x00e6, 0x2071, 0x1800, 0xd0e4, 0x70e4, 0x1110, 0xc0dc,
- 0x0008, 0xc0dd, 0x0011, 0x00ee, 0x0005, 0x70e6, 0x7000, 0x9084,
- 0x0007, 0x000b, 0x0005, 0x0ef2, 0x0ec9, 0x0ec9, 0x0eab, 0x0ed8,
- 0x0ec9, 0x0ec9, 0x0ed8, 0x0016, 0x3b08, 0x3a00, 0x9104, 0x918d,
- 0x00c0, 0x21d8, 0x9084, 0xff3f, 0x9205, 0x20d0, 0x001e, 0x0005,
- 0x2001, 0x1839, 0x2004, 0xd0dc, 0x0005, 0x9e86, 0x1800, 0x190c,
- 0x0e02, 0x70e4, 0xd0e4, 0x0108, 0xc2e5, 0x72e6, 0xd0e4, 0x1118,
- 0x9294, 0x00c0, 0x0c01, 0x0005, 0x1d04, 0x0f44, 0x2091, 0x6000,
- 0x1f04, 0x0f44, 0x0005, 0x890e, 0x810e, 0x810f, 0x9194, 0x003f,
- 0x918c, 0xffc0, 0x0005, 0x0006, 0x2200, 0x914d, 0x894f, 0x894d,
- 0x894d, 0x000e, 0x0005, 0x01d6, 0x0146, 0x0036, 0x0096, 0x2061,
- 0x188b, 0x600b, 0x0000, 0x600f, 0x0000, 0x6003, 0x0000, 0x6007,
- 0x0000, 0x2009, 0xffc0, 0x2105, 0x0006, 0x2001, 0xaaaa, 0x200f,
- 0x2019, 0x5555, 0x9016, 0x2049, 0x0bff, 0xab02, 0xa001, 0xa001,
- 0xa800, 0x9306, 0x1138, 0x2105, 0x9306, 0x0120, 0x8210, 0x99c8,
- 0x0400, 0x0c98, 0x000e, 0x200f, 0x2001, 0x189b, 0x928a, 0x000e,
- 0x1638, 0x928a, 0x0006, 0x2011, 0x0006, 0x1210, 0x2011, 0x0000,
- 0x2202, 0x9006, 0x2008, 0x82ff, 0x01b0, 0x8200, 0x600a, 0x600f,
- 0xffff, 0x6003, 0x0002, 0x6007, 0x0000, 0x0026, 0x2019, 0x0010,
- 0x9280, 0x0001, 0x20e8, 0x21a0, 0x21a8, 0x4104, 0x8319, 0x1de0,
- 0x8211, 0x1da0, 0x002e, 0x009e, 0x003e, 0x014e, 0x01de, 0x0005,
- 0x2011, 0x000e, 0x08e8, 0x0016, 0x0026, 0x0096, 0x3348, 0x080c,
- 0x0f4b, 0x2100, 0x9300, 0x2098, 0x22e0, 0x009e, 0x002e, 0x001e,
- 0x0036, 0x3518, 0x20a9, 0x0001, 0x4002, 0x8007, 0x4004, 0x8319,
- 0x1dd8, 0x003e, 0x0005, 0x20e9, 0x0001, 0x71b4, 0x81ff, 0x11c0,
- 0x9006, 0x2009, 0x0200, 0x20a9, 0x0002, 0x9298, 0x0018, 0x23a0,
- 0x4001, 0x2009, 0x0700, 0x20a9, 0x0002, 0x9298, 0x0008, 0x23a0,
- 0x4001, 0x7078, 0x8007, 0x717c, 0x810f, 0x20a9, 0x0002, 0x4001,
- 0x9298, 0x000c, 0x23a0, 0x900e, 0x080c, 0x0de2, 0x2001, 0x0000,
- 0x810f, 0x20a9, 0x0002, 0x4001, 0x0005, 0x89ff, 0x0140, 0xa804,
- 0xa807, 0x0000, 0x0006, 0x080c, 0x1075, 0x009e, 0x0cb0, 0x0005,
- 0x00e6, 0x2071, 0x1800, 0x080c, 0x10ee, 0x090c, 0x0e02, 0x00ee,
- 0x0005, 0x0086, 0x00e6, 0x0006, 0x0026, 0x0036, 0x0126, 0x2091,
- 0x8000, 0x00c9, 0x2071, 0x1800, 0x73bc, 0x702c, 0x9016, 0x9045,
- 0x0158, 0x8210, 0x9906, 0x090c, 0x0e02, 0x2300, 0x9202, 0x0120,
- 0x1a0c, 0x0e02, 0xa000, 0x0c98, 0x012e, 0x003e, 0x002e, 0x000e,
- 0x00ee, 0x008e, 0x0005, 0x0086, 0x00e6, 0x0006, 0x0126, 0x2091,
- 0x8000, 0x2071, 0x190e, 0x7010, 0x9005, 0x0140, 0x7018, 0x9045,
- 0x0128, 0x9906, 0x090c, 0x0e02, 0xa000, 0x0cc8, 0x012e, 0x000e,
- 0x00ee, 0x008e, 0x0005, 0x00e6, 0x2071, 0x1800, 0x0126, 0x2091,
- 0x8000, 0x70bc, 0x8001, 0x0270, 0x70be, 0x702c, 0x2048, 0x9085,
- 0x0001, 0xa800, 0x702e, 0xa803, 0x0000, 0xa807, 0x0000, 0x012e,
- 0x00ee, 0x0005, 0x904e, 0x0cd8, 0x00e6, 0x0126, 0x2091, 0x8000,
- 0x2071, 0x1800, 0x70bc, 0x90ca, 0x0040, 0x0268, 0x8001, 0x70be,
- 0x702c, 0x2048, 0xa800, 0x702e, 0xa803, 0x0000, 0xa807, 0x0000,
- 0x012e, 0x00ee, 0x0005, 0x904e, 0x0cd8, 0x00e6, 0x0126, 0x2091,
- 0x8000, 0x0016, 0x890e, 0x810e, 0x810f, 0x9184, 0x003f, 0xa862,
- 0x9184, 0xffc0, 0xa85e, 0x001e, 0x0020, 0x00e6, 0x0126, 0x2091,
- 0x8000, 0x2071, 0x1800, 0x702c, 0xa802, 0x2900, 0x702e, 0x70bc,
- 0x8000, 0x70be, 0x080c, 0x8170, 0x012e, 0x00ee, 0x0005, 0x2071,
- 0x1800, 0x9026, 0x2009, 0x0000, 0x2049, 0x0400, 0x2900, 0x702e,
- 0x8940, 0x2800, 0xa802, 0xa95e, 0xa863, 0x0001, 0x8420, 0x9886,
- 0x0440, 0x0120, 0x2848, 0x9188, 0x0040, 0x0c90, 0x2071, 0x188b,
- 0x7000, 0x9005, 0x11a0, 0x2001, 0x0492, 0xa802, 0x2048, 0x2009,
- 0x2480, 0x8940, 0x2800, 0xa802, 0xa95e, 0xa863, 0x0001, 0x8420,
- 0x9886, 0x0800, 0x0120, 0x2848, 0x9188, 0x0040, 0x0c90, 0x2071,
- 0x188b, 0x7104, 0x7200, 0x82ff, 0x01d0, 0x7308, 0x8318, 0x831f,
- 0x831b, 0x831b, 0x7312, 0x8319, 0x2001, 0x0800, 0xa802, 0x2048,
- 0x8900, 0xa802, 0x2040, 0xa95e, 0xaa62, 0x8420, 0x2300, 0x9906,
- 0x0130, 0x2848, 0x9188, 0x0040, 0x9291, 0x0000, 0x0c88, 0xa803,
- 0x0000, 0x2071, 0x1800, 0x74ba, 0x74be, 0x0005, 0x00e6, 0x0016,
- 0x9984, 0xfc00, 0x01e8, 0x908c, 0xf800, 0x1168, 0x9982, 0x0400,
- 0x02b8, 0x9982, 0x0440, 0x0278, 0x9982, 0x0492, 0x0288, 0x9982,
- 0x0800, 0x1270, 0x0040, 0x9982, 0x0800, 0x0250, 0x2071, 0x188b,
- 0x7010, 0x9902, 0x1228, 0x9085, 0x0001, 0x001e, 0x00ee, 0x0005,
- 0x9006, 0x0cd8, 0x00e6, 0x2071, 0x19f5, 0x7007, 0x0000, 0x9006,
- 0x701e, 0x7022, 0x7002, 0x2071, 0x0000, 0x7010, 0x9085, 0x8044,
- 0x7012, 0x2071, 0x0080, 0x9006, 0x0006, 0x2001, 0x0100, 0x2004,
- 0x9086, 0x000a, 0x000e, 0x1158, 0x702b, 0x0060, 0x20a9, 0x0040,
- 0x7022, 0x1f04, 0x1130, 0x702b, 0x0060, 0x702b, 0x0020, 0x20a9,
- 0x0040, 0x7022, 0x1f04, 0x1139, 0x702b, 0x0020, 0x00ee, 0x0005,
- 0x0126, 0x2091, 0x8000, 0x00e6, 0xa06f, 0x0000, 0x2071, 0x19f5,
- 0x701c, 0x9088, 0x19ff, 0x280a, 0x8000, 0x9084, 0x003f, 0x701e,
- 0x7120, 0x9106, 0x090c, 0x0e02, 0x7004, 0x9005, 0x1128, 0x00f6,
- 0x2079, 0x0080, 0x00a9, 0x00fe, 0x00ee, 0x012e, 0x0005, 0x0126,
- 0x2091, 0x8000, 0x00e6, 0x2071, 0x19f5, 0x7004, 0x9005, 0x1128,
- 0x00f6, 0x2079, 0x0080, 0x0021, 0x00fe, 0x00ee, 0x012e, 0x0005,
- 0x7004, 0x9086, 0x0000, 0x1110, 0x7007, 0x0006, 0x7000, 0x0002,
- 0x1182, 0x1180, 0x1180, 0x1180, 0x12f9, 0x12f9, 0x12f9, 0x12f9,
- 0x080c, 0x0e02, 0x701c, 0x7120, 0x9106, 0x1148, 0x792c, 0x9184,
- 0x0001, 0x1120, 0xd1fc, 0x1110, 0x7007, 0x0000, 0x0005, 0x0096,
- 0x9180, 0x19ff, 0x2004, 0x700a, 0x2048, 0x8108, 0x918c, 0x003f,
- 0x7122, 0x782b, 0x0026, 0xa88c, 0x7802, 0xa890, 0x7806, 0xa894,
- 0x780a, 0xa898, 0x780e, 0xa878, 0x700e, 0xa870, 0x7016, 0xa874,
- 0x701a, 0xa868, 0x009e, 0xd084, 0x0120, 0x7007, 0x0001, 0x0029,
- 0x0005, 0x7007, 0x0002, 0x00b1, 0x0005, 0x0016, 0x0026, 0x710c,
- 0x2011, 0x0040, 0x9182, 0x0040, 0x1210, 0x2110, 0x9006, 0x700e,
- 0x7212, 0x8203, 0x7812, 0x782b, 0x0020, 0x782b, 0x0041, 0x002e,
- 0x001e, 0x0005, 0x0016, 0x0026, 0x0136, 0x0146, 0x0156, 0x7014,
- 0x20e0, 0x7018, 0x2098, 0x20e9, 0x0000, 0x20a1, 0x0088, 0x782b,
- 0x0026, 0x710c, 0x2011, 0x0040, 0x9182, 0x0040, 0x1210, 0x2110,
- 0x9006, 0x700e, 0x22a8, 0x4006, 0x8203, 0x7812, 0x782b, 0x0020,
- 0x3300, 0x701a, 0x782b, 0x0001, 0x015e, 0x014e, 0x013e, 0x002e,
- 0x001e, 0x0005, 0x2009, 0x19f5, 0x2104, 0xc095, 0x200a, 0x080c,
- 0x115f, 0x0005, 0x0016, 0x00e6, 0x2071, 0x19f5, 0x00f6, 0x2079,
- 0x0080, 0x792c, 0xd1bc, 0x190c, 0x0dfb, 0x782b, 0x0002, 0xd1fc,
- 0x0120, 0x918c, 0x0700, 0x7004, 0x0023, 0x00fe, 0x00ee, 0x001e,
- 0x0005, 0x1170, 0x1218, 0x124c, 0x0e02, 0x0e02, 0x1305, 0x0e02,
- 0x918c, 0x0700, 0x1550, 0x0136, 0x0146, 0x0156, 0x7014, 0x20e8,
- 0x7018, 0x20a0, 0x20e1, 0x0000, 0x2099, 0x0088, 0x782b, 0x0040,
- 0x7010, 0x20a8, 0x4005, 0x3400, 0x701a, 0x015e, 0x014e, 0x013e,
- 0x700c, 0x9005, 0x0578, 0x7800, 0x7802, 0x7804, 0x7806, 0x080c,
- 0x11b5, 0x0005, 0x7008, 0x0096, 0x2048, 0xa86f, 0x0100, 0x009e,
- 0x7007, 0x0000, 0x080c, 0x1170, 0x0005, 0x7008, 0x0096, 0x2048,
- 0xa86f, 0x0200, 0x009e, 0x0ca0, 0x918c, 0x0700, 0x1150, 0x700c,
- 0x9005, 0x0180, 0x7800, 0x7802, 0x7804, 0x7806, 0x080c, 0x11ca,
- 0x0005, 0x7008, 0x0096, 0x2048, 0xa86f, 0x0200, 0x009e, 0x7007,
- 0x0000, 0x0080, 0x0096, 0x7008, 0x2048, 0x7800, 0xa88e, 0x7804,
- 0xa892, 0x7808, 0xa896, 0x780c, 0xa89a, 0xa86f, 0x0100, 0x009e,
- 0x7007, 0x0000, 0x0096, 0x00d6, 0x7008, 0x2048, 0x2001, 0x18b7,
- 0x2004, 0x9906, 0x1128, 0xa89c, 0x080f, 0x00de, 0x009e, 0x00a0,
- 0x00de, 0x009e, 0x0096, 0x00d6, 0x7008, 0x2048, 0x0081, 0x0150,
- 0xa89c, 0x0086, 0x2940, 0x080f, 0x008e, 0x00de, 0x009e, 0x080c,
- 0x115f, 0x0005, 0x00de, 0x009e, 0x080c, 0x115f, 0x0005, 0xa8a8,
- 0xd08c, 0x0005, 0x0096, 0xa0a0, 0x904d, 0x090c, 0x0e02, 0xa06c,
- 0x908e, 0x0100, 0x0130, 0xa87b, 0x0030, 0xa883, 0x0000, 0xa897,
- 0x4002, 0x080c, 0x6a16, 0xa09f, 0x0000, 0xa0a3, 0x0000, 0x2848,
- 0x080c, 0x1075, 0x009e, 0x0005, 0x00a6, 0xa0a0, 0x904d, 0x090c,
- 0x0e02, 0xa06c, 0x908e, 0x0100, 0x0128, 0xa87b, 0x0001, 0xa883,
- 0x0000, 0x00c0, 0xa80c, 0x2050, 0xb004, 0x9005, 0x0198, 0xa80e,
- 0x2050, 0x8006, 0x8006, 0x8007, 0x908c, 0x003f, 0x9084, 0xffc0,
- 0x9080, 0x0002, 0xa076, 0xa172, 0xb000, 0xa07a, 0x2810, 0x080c,
- 0x1140, 0x00e8, 0xa97c, 0xa894, 0x0016, 0x0006, 0x080c, 0x6a16,
- 0x000e, 0x001e, 0xd1fc, 0x1138, 0xd1f4, 0x0128, 0x00c6, 0x2060,
- 0x080c, 0x9fd5, 0x00ce, 0x7008, 0x2048, 0xa89f, 0x0000, 0xa8a3,
- 0x0000, 0x080c, 0x1075, 0x7007, 0x0000, 0x080c, 0x115f, 0x00ae,
- 0x0005, 0x0126, 0x2091, 0x8000, 0x782b, 0x1001, 0x7007, 0x0005,
- 0x7000, 0xc094, 0x7002, 0x012e, 0x0005, 0x7007, 0x0000, 0x080c,
- 0x1170, 0x0005, 0x0126, 0x2091, 0x2200, 0x2079, 0x0300, 0x2071,
- 0x1a3f, 0x7003, 0x0000, 0x78bf, 0x00f6, 0x0419, 0x7803, 0x0003,
- 0x780f, 0x0000, 0x2001, 0x0100, 0x2004, 0x9086, 0x000a, 0x0128,
- 0x20a9, 0x01e8, 0x2061, 0xdba9, 0x0020, 0x20a9, 0x01e8, 0x2061,
- 0xdf77, 0x2c0d, 0x7912, 0xe104, 0x9ce0, 0x0002, 0x7916, 0x1f04,
- 0x1329, 0x7807, 0x0007, 0x7803, 0x0000, 0x7803, 0x0001, 0x012e,
- 0x0005, 0x00c6, 0x7803, 0x0000, 0x7808, 0xd09c, 0x0110, 0x7820,
- 0x0cd8, 0x2001, 0x1a40, 0x2003, 0x0000, 0x78ab, 0x0004, 0x78ac,
- 0xd0ac, 0x1de8, 0x78ab, 0x0002, 0x7807, 0x0007, 0x7827, 0x0030,
- 0x782b, 0x0400, 0x7827, 0x0031, 0x782b, 0x1a5a, 0x781f, 0xff00,
- 0x781b, 0xff00, 0x2001, 0x0200, 0x2004, 0xd0dc, 0x0110, 0x781f,
- 0x0303, 0x2061, 0x1a5a, 0x602f, 0x1cd0, 0x2001, 0x1819, 0x2004,
- 0x9082, 0x1cd0, 0x6032, 0x603b, 0x1ec2, 0x783f, 0x3209, 0x00ce,
- 0x0005, 0x0126, 0x2091, 0x2200, 0x7908, 0x9184, 0x0070, 0x190c,
- 0x0dfb, 0xd19c, 0x0158, 0x7820, 0x908c, 0xf000, 0x15e8, 0x908a,
- 0x0024, 0x1a0c, 0x0e02, 0x0023, 0x012e, 0x0005, 0x012e, 0x0005,
- 0x13ac, 0x13ac, 0x13c3, 0x13c8, 0x13cc, 0x13d1, 0x13f9, 0x13fd,
- 0x140b, 0x140f, 0x13ac, 0x149b, 0x149f, 0x150f, 0x13ac, 0x13ac,
- 0x13ac, 0x13ac, 0x13ac, 0x13ac, 0x13ac, 0x13ac, 0x13ac, 0x13ac,
- 0x13ac, 0x13ac, 0x13ac, 0x13d3, 0x13ac, 0x13ac, 0x13ac, 0x13ac,
- 0x13ac, 0x13ac, 0x13b0, 0x13ae, 0x080c, 0x0e02, 0x080c, 0x0dfb,
- 0x080c, 0x1516, 0x2009, 0x1a56, 0x2104, 0x8000, 0x200a, 0x080c,
- 0x7bed, 0x080c, 0x1983, 0x0005, 0x2009, 0x0048, 0x2060, 0x080c,
- 0xa053, 0x012e, 0x0005, 0x7004, 0xc085, 0xc0b5, 0x7006, 0x0005,
- 0x7004, 0xc085, 0x7006, 0x0005, 0x080c, 0x1516, 0x080c, 0x15f0,
- 0x0005, 0x080c, 0x0e02, 0x080c, 0x1516, 0x2060, 0x6014, 0x0096,
- 0x2048, 0xa83b, 0xffff, 0x009e, 0x2009, 0x0048, 0x080c, 0xa053,
- 0x2001, 0x015d, 0x2003, 0x0000, 0x2009, 0x03e8, 0x8109, 0x0160,
- 0x2001, 0x0201, 0x2004, 0x9005, 0x0dc8, 0x2001, 0x0218, 0x2004,
- 0xd0ec, 0x1110, 0x080c, 0x151b, 0x2001, 0x0307, 0x2003, 0x8000,
- 0x0005, 0x7004, 0xc095, 0x7006, 0x0005, 0x080c, 0x1516, 0x2060,
- 0x6014, 0x0096, 0x2048, 0xa83b, 0xffff, 0x009e, 0x2009, 0x0048,
- 0x080c, 0xa053, 0x0005, 0x080c, 0x1516, 0x080c, 0x0e02, 0x080c,
- 0x1516, 0x080c, 0x1486, 0x7827, 0x0018, 0x79ac, 0xd1dc, 0x0540,
- 0x7827, 0x0015, 0x7828, 0x782b, 0x0000, 0x9065, 0x0138, 0x2001,
- 0x020d, 0x2003, 0x0050, 0x2003, 0x0020, 0x0400, 0x7004, 0x9005,
- 0x1180, 0x78ab, 0x0004, 0x7827, 0x0018, 0x782b, 0x0000, 0xd1bc,
- 0x090c, 0x0e02, 0x2001, 0x020d, 0x2003, 0x0050, 0x2003, 0x0020,
- 0x0490, 0x78ab, 0x0004, 0x7803, 0x0001, 0x080c, 0x149f, 0x0005,
- 0x7828, 0x782b, 0x0000, 0x9065, 0x090c, 0x0e02, 0x6014, 0x2048,
- 0x78ab, 0x0004, 0x918c, 0x0700, 0x01a8, 0x080c, 0x7bed, 0x080c,
- 0x1983, 0x080c, 0xbd3b, 0x0158, 0xa9ac, 0xa936, 0xa9b0, 0xa93a,
- 0xa83f, 0xffff, 0xa843, 0xffff, 0xa880, 0xc0bd, 0xa882, 0x080c,
- 0xb974, 0x0005, 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc,
- 0x6024, 0x190c, 0xc127, 0x2029, 0x00c8, 0x8529, 0x0128, 0x2001,
- 0x0201, 0x2004, 0x9005, 0x0dc8, 0x7dbc, 0x080c, 0xdb52, 0xd5a4,
- 0x1118, 0x080c, 0x151b, 0x0005, 0x080c, 0x7bed, 0x080c, 0x1983,
- 0x0005, 0x781f, 0x0300, 0x7803, 0x0001, 0x0005, 0x0016, 0x0066,
- 0x0076, 0x00f6, 0x2079, 0x0300, 0x7908, 0x918c, 0x0007, 0x9186,
- 0x0003, 0x0120, 0x2001, 0x0016, 0x080c, 0x158c, 0x00fe, 0x007e,
- 0x006e, 0x001e, 0x0005, 0x7004, 0xc09d, 0x7006, 0x0005, 0x7104,
- 0x9184, 0x0004, 0x190c, 0x0e02, 0xd184, 0x11b1, 0xd19c, 0x0180,
- 0xc19c, 0x7106, 0x0016, 0x080c, 0x15d3, 0x001e, 0x0148, 0x2001,
- 0x020d, 0x2003, 0x0050, 0x2003, 0x0020, 0x080c, 0x151b, 0x0005,
- 0x81ff, 0x190c, 0x0e02, 0x0005, 0x2100, 0xc184, 0xc1b4, 0x7106,
- 0xd0b4, 0x0016, 0x00e6, 0x1904, 0x1504, 0x2071, 0x0200, 0x080c,
- 0x15c7, 0x080c, 0x15d3, 0x05a8, 0x6014, 0x9005, 0x05a8, 0x0096,
- 0x2048, 0xa864, 0x009e, 0x9084, 0x00ff, 0x908e, 0x0029, 0x0160,
- 0x908e, 0x0048, 0x1548, 0x601c, 0xd084, 0x11d8, 0x00f6, 0x2c78,
- 0x080c, 0x165d, 0x00fe, 0x00a8, 0x00f6, 0x2c78, 0x080c, 0x17a7,
- 0x00fe, 0x2009, 0x01f4, 0x8109, 0x0160, 0x2001, 0x0201, 0x2004,
- 0x9005, 0x0dc8, 0x2001, 0x0218, 0x2004, 0xd0ec, 0x1110, 0x0419,
- 0x0040, 0x2001, 0x020d, 0x2003, 0x0020, 0x080c, 0x1339, 0x7803,
- 0x0001, 0x00ee, 0x001e, 0x0005, 0x080c, 0x15d3, 0x0dd0, 0x2001,
- 0x020d, 0x2003, 0x0050, 0x2003, 0x0020, 0x0069, 0x0c90, 0x0031,
- 0x2060, 0x2009, 0x0053, 0x080c, 0xa053, 0x0005, 0x7808, 0xd09c,
- 0x0de8, 0x7820, 0x0005, 0x080c, 0x1486, 0x00d6, 0x2069, 0x0200,
- 0x2009, 0x01f4, 0x8109, 0x0510, 0x6804, 0x9005, 0x0dd8, 0x2001,
- 0x015d, 0x2003, 0x0000, 0x79bc, 0xd1a4, 0x1528, 0x79b8, 0x918c,
- 0x0fff, 0x0180, 0x9182, 0x0841, 0x1268, 0x9188, 0x0007, 0x918c,
- 0x0ff8, 0x810c, 0x810c, 0x810c, 0x080c, 0x157e, 0x6827, 0x0001,
- 0x8109, 0x1dd0, 0x04d9, 0x6827, 0x0002, 0x04c1, 0x6804, 0x9005,
- 0x1130, 0x682c, 0xd0e4, 0x1500, 0x6804, 0x9005, 0x0de8, 0x79b8,
- 0xd1ec, 0x1130, 0x08c0, 0x080c, 0x7bed, 0x080c, 0x1983, 0x0090,
- 0x7827, 0x0015, 0x782b, 0x0000, 0x7827, 0x0018, 0x782b, 0x0000,
- 0x2001, 0x020d, 0x2003, 0x0020, 0x2001, 0x0307, 0x2003, 0x0300,
- 0x7803, 0x0001, 0x00de, 0x0005, 0x682c, 0x9084, 0x5400, 0x9086,
- 0x5400, 0x0d30, 0x7827, 0x0015, 0x782b, 0x0000, 0x7803, 0x0001,
- 0x6800, 0x9085, 0x1800, 0x6802, 0x00de, 0x0005, 0x6824, 0x9084,
- 0x0003, 0x1de0, 0x0005, 0x2001, 0x0030, 0x2c08, 0x621c, 0x0021,
- 0x7830, 0x9086, 0x0041, 0x0005, 0x00f6, 0x2079, 0x0300, 0x0006,
- 0x7808, 0xd09c, 0x0140, 0x0016, 0x0026, 0x00c6, 0x080c, 0x1371,
- 0x00ce, 0x002e, 0x001e, 0x000e, 0x0006, 0x7832, 0x7936, 0x7a3a,
- 0x781b, 0x8080, 0x0059, 0x1118, 0x000e, 0x00fe, 0x0005, 0x000e,
- 0x792c, 0x3900, 0x8000, 0x2004, 0x080c, 0x0e02, 0x2009, 0xff00,
- 0x8109, 0x0120, 0x7818, 0xd0bc, 0x1dd8, 0x0005, 0x9085, 0x0001,
- 0x0005, 0x7832, 0x7936, 0x7a3a, 0x781b, 0x8080, 0x0c79, 0x1108,
- 0x0005, 0x792c, 0x3900, 0x8000, 0x2004, 0x080c, 0x0e02, 0x7037,
- 0x0001, 0x7150, 0x7037, 0x0002, 0x7050, 0x2060, 0xd1bc, 0x1110,
- 0x7054, 0x2060, 0x0005, 0x0006, 0x0046, 0x00e6, 0x2071, 0x0200,
- 0x7037, 0x0002, 0x7058, 0x9084, 0xff00, 0x8007, 0x9086, 0x00bc,
- 0x1158, 0x2021, 0x1a57, 0x2404, 0x8000, 0x0208, 0x2022, 0x080c,
- 0x7bed, 0x080c, 0x1983, 0x9006, 0x00ee, 0x004e, 0x000e, 0x0005,
- 0x0c11, 0x1108, 0x0005, 0x00e6, 0x0016, 0x2071, 0x0200, 0x0879,
- 0x6124, 0xd1dc, 0x01f8, 0x701c, 0xd08c, 0x0904, 0x1652, 0x7017,
- 0x0000, 0x2001, 0x0264, 0x2004, 0xd0bc, 0x0904, 0x1652, 0x2001,
- 0x0268, 0x00c6, 0x2064, 0x6104, 0x6038, 0x00ce, 0x918e, 0x0039,
- 0x1904, 0x1652, 0x9c06, 0x15f0, 0x0126, 0x2091, 0x2600, 0x080c,
- 0x7b34, 0x012e, 0x7358, 0x745c, 0x6014, 0x905d, 0x0598, 0x2b48,
- 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x190c, 0xc102,
- 0xab42, 0xac3e, 0x2001, 0x187d, 0x2004, 0xd0b4, 0x1170, 0x601c,
- 0xd0e4, 0x1158, 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc,
- 0x1120, 0xa83b, 0x7fff, 0xa837, 0xffff, 0x080c, 0x1ee2, 0x1190,
- 0x080c, 0x1804, 0x2a00, 0xa816, 0x0130, 0x2800, 0xa80e, 0x2c05,
- 0xa80a, 0x2c00, 0xa812, 0x7037, 0x0020, 0x781f, 0x0300, 0x001e,
- 0x00ee, 0x0005, 0x7037, 0x0050, 0x7037, 0x0020, 0x001e, 0x00ee,
- 0x080c, 0x151b, 0x0005, 0x080c, 0x0e02, 0x0016, 0x2009, 0x00a0,
- 0x8109, 0xa001, 0xa001, 0xa001, 0x1dd8, 0x001e, 0x2ff0, 0x0126,
- 0x2091, 0x2200, 0x0016, 0x00c6, 0x3e60, 0x6014, 0x2048, 0x2940,
- 0x903e, 0x2730, 0xa864, 0x2068, 0xa81a, 0x9d84, 0x000f, 0x9088,
- 0x1ec2, 0x2165, 0x0002, 0x1692, 0x16df, 0x1692, 0x1692, 0x1692,
- 0x16c1, 0x1692, 0x1696, 0x168b, 0x16d6, 0x1692, 0x1692, 0x1692,
- 0x179c, 0x16aa, 0x16a0, 0xa964, 0x918c, 0x00ff, 0x918e, 0x0048,
- 0x0904, 0x16d6, 0x9085, 0x0001, 0x0804, 0x1792, 0xa87c, 0xd0bc,
- 0x0dc8, 0xa890, 0xa842, 0xa88c, 0xa83e, 0xa888, 0x0804, 0x16e6,
- 0xa87c, 0xd0bc, 0x0d78, 0xa890, 0xa842, 0xa88c, 0xa83e, 0xa888,
- 0x0804, 0x1735, 0xa87c, 0xd0bc, 0x0d28, 0xa890, 0xa842, 0xa88c,
- 0xa83e, 0xa804, 0x9045, 0x090c, 0x0e02, 0xa164, 0xa91a, 0x91ec,
- 0x000f, 0x9d80, 0x1ec2, 0x2065, 0xa888, 0xd19c, 0x1904, 0x1735,
- 0x0428, 0xa87c, 0xd0ac, 0x0970, 0xa804, 0x9045, 0x090c, 0x0e02,
- 0xa164, 0xa91a, 0x91ec, 0x000f, 0x9d80, 0x1ec2, 0x2065, 0x9006,
- 0xa842, 0xa83e, 0xd19c, 0x1904, 0x1735, 0x0080, 0xa87c, 0xd0ac,
- 0x0904, 0x1692, 0x9006, 0xa842, 0xa83e, 0x0804, 0x1735, 0xa87c,
- 0xd0ac, 0x0904, 0x1692, 0x9006, 0xa842, 0xa83e, 0x2c05, 0x908a,
- 0x0036, 0x1a0c, 0x0e02, 0x9082, 0x001b, 0x0002, 0x1709, 0x1709,
- 0x170b, 0x1709, 0x1709, 0x1709, 0x1711, 0x1709, 0x1709, 0x1709,
- 0x1717, 0x1709, 0x1709, 0x1709, 0x171d, 0x1709, 0x1709, 0x1709,
- 0x1723, 0x1709, 0x1709, 0x1709, 0x1729, 0x1709, 0x1709, 0x1709,
- 0x172f, 0x080c, 0x0e02, 0xa574, 0xa478, 0xa37c, 0xa280, 0x0804,
- 0x177a, 0xa584, 0xa488, 0xa38c, 0xa290, 0x0804, 0x177a, 0xa594,
- 0xa498, 0xa39c, 0xa2a0, 0x0804, 0x177a, 0xa5a4, 0xa4a8, 0xa3ac,
- 0xa2b0, 0x0804, 0x177a, 0xa5b4, 0xa4b8, 0xa3bc, 0xa2c0, 0x0804,
- 0x177a, 0xa5c4, 0xa4c8, 0xa3cc, 0xa2d0, 0x0804, 0x177a, 0xa5d4,
- 0xa4d8, 0xa3dc, 0xa2e0, 0x0804, 0x177a, 0x2c05, 0x908a, 0x0034,
- 0x1a0c, 0x0e02, 0x9082, 0x001b, 0x0002, 0x1758, 0x1756, 0x1756,
- 0x1756, 0x1756, 0x1756, 0x175f, 0x1756, 0x1756, 0x1756, 0x1756,
- 0x1756, 0x1766, 0x1756, 0x1756, 0x1756, 0x1756, 0x1756, 0x176d,
- 0x1756, 0x1756, 0x1756, 0x1756, 0x1756, 0x1774, 0x080c, 0x0e02,
- 0xa56c, 0xa470, 0xa774, 0xa678, 0xa37c, 0xa280, 0x00d8, 0xa584,
- 0xa488, 0xa78c, 0xa690, 0xa394, 0xa298, 0x00a0, 0xa59c, 0xa4a0,
- 0xa7a4, 0xa6a8, 0xa3ac, 0xa2b0, 0x0068, 0xa5b4, 0xa4b8, 0xa7bc,
- 0xa6c0, 0xa3c4, 0xa2c8, 0x0030, 0xa5cc, 0xa4d0, 0xa7d4, 0xa6d8,
- 0xa3dc, 0xa2e0, 0xab2e, 0xaa32, 0xad1e, 0xac22, 0xaf26, 0xae2a,
- 0xa988, 0x8c60, 0x2c1d, 0xa8ac, 0xaab0, 0xa836, 0xaa3a, 0x8109,
- 0xa916, 0x1160, 0x3e60, 0x601c, 0xc085, 0x601e, 0xa87c, 0xc0dd,
- 0xa87e, 0x9006, 0x00ce, 0x001e, 0x012e, 0x0005, 0x2800, 0xa80e,
- 0xab0a, 0x2c00, 0xa812, 0x0c70, 0x0804, 0x1692, 0x0016, 0x2009,
- 0x00a0, 0x8109, 0xa001, 0xa001, 0xa001, 0x1dd8, 0x001e, 0x2ff0,
- 0x0126, 0x2091, 0x2200, 0x0016, 0x00c6, 0x3e60, 0x6014, 0x2048,
- 0x2940, 0xa80e, 0x2061, 0x1ebd, 0xa813, 0x1ebd, 0x2c05, 0xa80a,
- 0xa964, 0xa91a, 0xa87c, 0xd0ac, 0x090c, 0x0e02, 0x9006, 0xa842,
- 0xa83e, 0x2c05, 0x908a, 0x0034, 0x1a0c, 0x0e02, 0xadcc, 0xacd0,
- 0xafd4, 0xaed8, 0xabdc, 0xaae0, 0xab2e, 0xaa32, 0xad1e, 0xac22,
- 0xaf26, 0xae2a, 0xa8ac, 0xaab0, 0xa836, 0xaa3a, 0xa988, 0xa864,
- 0x9084, 0x00ff, 0x9086, 0x0008, 0x1120, 0x8109, 0xa916, 0x0128,
- 0x0080, 0x918a, 0x0002, 0xa916, 0x1160, 0x3e60, 0x601c, 0xc085,
- 0x601e, 0xa87c, 0xc0dd, 0xa87e, 0x9006, 0x00ce, 0x001e, 0x012e,
- 0x0005, 0xa804, 0x9045, 0x090c, 0x0e02, 0xa80e, 0xa064, 0xa81a,
- 0x9084, 0x000f, 0x9080, 0x1ec2, 0x2015, 0x82ff, 0x090c, 0x0e02,
- 0xaa12, 0x2205, 0xa80a, 0x0c08, 0x903e, 0x2730, 0xa880, 0xd0fc,
- 0x1190, 0x2d00, 0x0002, 0x18f9, 0x185b, 0x185b, 0x18f9, 0x18f9,
- 0x18f3, 0x18f9, 0x185b, 0x18aa, 0x18aa, 0x18aa, 0x18f9, 0x18f9,
- 0x18f9, 0x18f0, 0x18aa, 0xc0fc, 0xa882, 0xab2c, 0xaa30, 0xad1c,
- 0xac20, 0xdd9c, 0x0904, 0x18fb, 0x2c05, 0x908a, 0x0034, 0x1a0c,
- 0x0e02, 0x9082, 0x001b, 0x0002, 0x1847, 0x1845, 0x1845, 0x1845,
- 0x1845, 0x1845, 0x184b, 0x1845, 0x1845, 0x1845, 0x1845, 0x1845,
- 0x184f, 0x1845, 0x1845, 0x1845, 0x1845, 0x1845, 0x1853, 0x1845,
- 0x1845, 0x1845, 0x1845, 0x1845, 0x1857, 0x080c, 0x0e02, 0xa774,
- 0xa678, 0x0804, 0x18fb, 0xa78c, 0xa690, 0x0804, 0x18fb, 0xa7a4,
- 0xa6a8, 0x0804, 0x18fb, 0xa7bc, 0xa6c0, 0x0804, 0x18fb, 0xa7d4,
- 0xa6d8, 0x0804, 0x18fb, 0x2c05, 0x908a, 0x0036, 0x1a0c, 0x0e02,
- 0x9082, 0x001b, 0x0002, 0x187e, 0x187e, 0x1880, 0x187e, 0x187e,
- 0x187e, 0x1886, 0x187e, 0x187e, 0x187e, 0x188c, 0x187e, 0x187e,
- 0x187e, 0x1892, 0x187e, 0x187e, 0x187e, 0x1898, 0x187e, 0x187e,
- 0x187e, 0x189e, 0x187e, 0x187e, 0x187e, 0x18a4, 0x080c, 0x0e02,
- 0xa574, 0xa478, 0xa37c, 0xa280, 0x0804, 0x18fb, 0xa584, 0xa488,
- 0xa38c, 0xa290, 0x0804, 0x18fb, 0xa594, 0xa498, 0xa39c, 0xa2a0,
- 0x0804, 0x18fb, 0xa5a4, 0xa4a8, 0xa3ac, 0xa2b0, 0x0804, 0x18fb,
- 0xa5b4, 0xa4b8, 0xa3bc, 0xa2c0, 0x0804, 0x18fb, 0xa5c4, 0xa4c8,
- 0xa3cc, 0xa2d0, 0x0804, 0x18fb, 0xa5d4, 0xa4d8, 0xa3dc, 0xa2e0,
- 0x0804, 0x18fb, 0x2c05, 0x908a, 0x0034, 0x1a0c, 0x0e02, 0x9082,
- 0x001b, 0x0002, 0x18cd, 0x18cb, 0x18cb, 0x18cb, 0x18cb, 0x18cb,
- 0x18d4, 0x18cb, 0x18cb, 0x18cb, 0x18cb, 0x18cb, 0x18db, 0x18cb,
- 0x18cb, 0x18cb, 0x18cb, 0x18cb, 0x18e2, 0x18cb, 0x18cb, 0x18cb,
- 0x18cb, 0x18cb, 0x18e9, 0x080c, 0x0e02, 0xa56c, 0xa470, 0xa774,
- 0xa678, 0xa37c, 0xa280, 0x0438, 0xa584, 0xa488, 0xa78c, 0xa690,
- 0xa394, 0xa298, 0x0400, 0xa59c, 0xa4a0, 0xa7a4, 0xa6a8, 0xa3ac,
- 0xa2b0, 0x00c8, 0xa5b4, 0xa4b8, 0xa7bc, 0xa6c0, 0xa3c4, 0xa2c8,
- 0x0090, 0xa5cc, 0xa4d0, 0xa7d4, 0xa6d8, 0xa3dc, 0xa2e0, 0x0058,
- 0x9d86, 0x000e, 0x1130, 0x080c, 0x1e80, 0x1904, 0x1804, 0x900e,
- 0x0050, 0x080c, 0x0e02, 0xab2e, 0xaa32, 0xad1e, 0xac22, 0xaf26,
- 0xae2a, 0x080c, 0x1e80, 0x0005, 0x6014, 0x2048, 0x6118, 0x81ff,
- 0x0148, 0x810c, 0x810c, 0x810c, 0x81ff, 0x1118, 0xa887, 0x0001,
- 0x0008, 0xa986, 0x601b, 0x0002, 0xa874, 0x9084, 0x00ff, 0x9084,
- 0x0008, 0x0150, 0x00e9, 0x6000, 0x9086, 0x0004, 0x1120, 0x2009,
- 0x0048, 0x080c, 0xa053, 0x0005, 0xa974, 0xd1dc, 0x1108, 0x0005,
- 0xa934, 0xa88c, 0x9106, 0x1158, 0xa938, 0xa890, 0x9106, 0x1138,
- 0x601c, 0xc084, 0x601e, 0x2009, 0x0048, 0x0804, 0xa053, 0x0005,
- 0x0126, 0x00c6, 0x2091, 0x2200, 0x00ce, 0x7908, 0x918c, 0x0007,
- 0x9186, 0x0000, 0x05b0, 0x9186, 0x0003, 0x0598, 0x6020, 0x6023,
- 0x0000, 0x0006, 0x2031, 0x0008, 0x00c6, 0x781f, 0x0808, 0x7808,
- 0xd09c, 0x0120, 0x080c, 0x1371, 0x8631, 0x1db8, 0x00ce, 0x781f,
- 0x0800, 0x2031, 0x0168, 0x00c6, 0x7808, 0xd09c, 0x190c, 0x1371,
- 0x00ce, 0x2001, 0x0038, 0x080c, 0x1a0b, 0x7930, 0x9186, 0x0040,
- 0x0160, 0x9186, 0x0042, 0x190c, 0x0e02, 0x2001, 0x001e, 0x8001,
- 0x1df0, 0x8631, 0x1d40, 0x080c, 0x1a1a, 0x000e, 0x6022, 0x012e,
- 0x0005, 0x080c, 0x1a07, 0x7827, 0x0015, 0x7828, 0x9c06, 0x1db8,
- 0x782b, 0x0000, 0x0ca0, 0x00f6, 0x2079, 0x0300, 0x7803, 0x0000,
- 0x78ab, 0x0004, 0x00fe, 0x080c, 0x717f, 0x1188, 0x2001, 0x0138,
- 0x2003, 0x0000, 0x2001, 0x0160, 0x2003, 0x0000, 0x2011, 0x012c,
- 0xa001, 0xa001, 0x8211, 0x1de0, 0x0059, 0x0804, 0x7247, 0x0479,
- 0x0039, 0x2001, 0x0160, 0x2502, 0x2001, 0x0138, 0x2202, 0x0005,
- 0x00e6, 0x2071, 0x0200, 0x080c, 0x2abc, 0x2009, 0x003c, 0x080c,
- 0x2204, 0x2001, 0x015d, 0x2003, 0x0000, 0x7000, 0x9084, 0x003c,
- 0x1de0, 0x080c, 0x8170, 0x70a0, 0x70a2, 0x7098, 0x709a, 0x709c,
- 0x709e, 0x2001, 0x020d, 0x2003, 0x0020, 0x00f6, 0x2079, 0x0300,
- 0x080c, 0x1339, 0x7803, 0x0001, 0x00fe, 0x00ee, 0x0005, 0x2001,
- 0x0138, 0x2014, 0x2003, 0x0000, 0x2001, 0x0160, 0x202c, 0x2003,
- 0x0000, 0x080c, 0x717f, 0x1108, 0x0005, 0x2021, 0x0260, 0x2001,
- 0x0141, 0x201c, 0xd3dc, 0x1168, 0x2001, 0x0109, 0x201c, 0x939c,
- 0x0048, 0x1160, 0x2001, 0x0111, 0x201c, 0x83ff, 0x1110, 0x8421,
- 0x1d70, 0x2001, 0x015d, 0x2003, 0x0000, 0x0005, 0x0046, 0x2021,
- 0x0019, 0x2003, 0x0048, 0xa001, 0xa001, 0x201c, 0x939c, 0x0048,
- 0x0120, 0x8421, 0x1db0, 0x004e, 0x0c60, 0x004e, 0x0c40, 0x601c,
- 0xc084, 0x601e, 0x0005, 0x2c08, 0x621c, 0x080c, 0x158c, 0x7930,
- 0x0005, 0x2c08, 0x621c, 0x080c, 0x15b9, 0x7930, 0x0005, 0x8001,
- 0x1df0, 0x0005, 0x2031, 0x0064, 0x781c, 0x9084, 0x0007, 0x0170,
- 0x2001, 0x0038, 0x0c41, 0x9186, 0x0040, 0x0904, 0x1a78, 0x2001,
- 0x001e, 0x0c69, 0x8631, 0x1d80, 0x080c, 0x0e02, 0x781f, 0x0202,
- 0x2001, 0x015d, 0x2003, 0x0000, 0x2001, 0x0dac, 0x0c01, 0x781c,
- 0xd084, 0x0110, 0x0861, 0x04e0, 0x2001, 0x0030, 0x0891, 0x9186,
- 0x0040, 0x0568, 0x781c, 0xd084, 0x1da8, 0x781f, 0x0101, 0x2001,
- 0x0014, 0x0869, 0x2001, 0x0037, 0x0821, 0x9186, 0x0040, 0x0140,
- 0x2001, 0x0030, 0x080c, 0x1a11, 0x9186, 0x0040, 0x190c, 0x0e02,
- 0x00d6, 0x2069, 0x0200, 0x692c, 0xd1f4, 0x1170, 0xd1c4, 0x0160,
- 0xd19c, 0x0130, 0x6800, 0x9085, 0x1800, 0x6802, 0x00de, 0x0080,
- 0x6908, 0x9184, 0x0007, 0x1db0, 0x00de, 0x781f, 0x0100, 0x791c,
- 0x9184, 0x0007, 0x090c, 0x0e02, 0xa001, 0xa001, 0x781f, 0x0200,
- 0x0005, 0x0126, 0x2091, 0x2400, 0x2071, 0x1a42, 0x2079, 0x0090,
- 0x012e, 0x0005, 0x9280, 0x0005, 0x2004, 0x2048, 0xa97c, 0xd1dc,
- 0x1904, 0x1b0d, 0xa964, 0x9184, 0x0007, 0x0002, 0x1a96, 0x1af8,
- 0x1aad, 0x1aad, 0x1aad, 0x1ae0, 0x1ac0, 0x1aaf, 0x918c, 0x00ff,
- 0x9186, 0x0008, 0x1170, 0xa87c, 0xd0b4, 0x0904, 0x1cc3, 0x9006,
- 0xa842, 0xa83e, 0xa988, 0x2900, 0xa85a, 0xa813, 0x1ebd, 0x0804,
- 0x1b09, 0x9186, 0x0048, 0x0904, 0x1af8, 0x080c, 0x0e02, 0xa87c,
- 0xd0b4, 0x0904, 0x1cc3, 0xa890, 0xa842, 0xa83a, 0xa88c, 0xa83e,
- 0xa836, 0xa8ac, 0xa846, 0xa8b0, 0xa84a, 0xa988, 0x0804, 0x1b00,
- 0xa864, 0x9084, 0x00ff, 0x9086, 0x001e, 0x1d38, 0xa87c, 0xd0b4,
- 0x0904, 0x1cc3, 0xa890, 0xa842, 0xa83a, 0xa88c, 0xa83e, 0xa836,
- 0xa8ac, 0xa846, 0xa8b0, 0xa84a, 0xa804, 0xa85a, 0x2040, 0xa064,
- 0x9084, 0x000f, 0x9080, 0x1ec2, 0x2005, 0xa812, 0xa988, 0x0448,
- 0x918c, 0x00ff, 0x9186, 0x0015, 0x1540, 0xa87c, 0xd0b4, 0x0904,
- 0x1cc3, 0xa804, 0xa85a, 0x2040, 0xa064, 0x9084, 0x000f, 0x9080,
- 0x1ec2, 0x2005, 0xa812, 0xa988, 0x9006, 0xa842, 0xa83e, 0x0088,
- 0xa87c, 0xd0b4, 0x0904, 0x1cc3, 0xa988, 0x9006, 0xa842, 0xa83e,
- 0x2900, 0xa85a, 0xa864, 0x9084, 0x000f, 0x9080, 0x1ec2, 0x2005,
- 0xa812, 0xa916, 0xa87c, 0xc0dd, 0xa87e, 0x0005, 0x00f6, 0x2079,
- 0x0090, 0x782c, 0xd0fc, 0x190c, 0x1d04, 0x00e6, 0x2071, 0x1a42,
- 0x7000, 0x9005, 0x1904, 0x1b65, 0x7206, 0x9280, 0x0005, 0x204c,
- 0x9280, 0x0004, 0x2004, 0x782b, 0x0004, 0x00f6, 0x2079, 0x0200,
- 0x7803, 0x0040, 0x00fe, 0x00b6, 0x2058, 0xb86c, 0x7836, 0xb890,
- 0x00be, 0x00f6, 0x2079, 0x0200, 0x7803, 0x0040, 0xa001, 0xa001,
- 0xa001, 0xa001, 0xa001, 0xa001, 0x781a, 0x78d7, 0x0000, 0x00fe,
- 0xa814, 0x2050, 0xa858, 0x2040, 0xa810, 0x2060, 0xa064, 0x90ec,
- 0x000f, 0xa944, 0x791a, 0x7116, 0xa848, 0x781e, 0x701a, 0x9006,
- 0x700e, 0x7012, 0x7004, 0xa940, 0xa838, 0x9106, 0x1188, 0xa93c,
- 0xa834, 0x9106, 0x1168, 0x8aff, 0x01a8, 0x0126, 0x2091, 0x8000,
- 0x00a1, 0x0108, 0x0091, 0x012e, 0x9006, 0x00ee, 0x00fe, 0x0005,
- 0x0036, 0x0046, 0xab38, 0xac34, 0x080c, 0x1ee2, 0x004e, 0x003e,
- 0x0d50, 0x0c98, 0x9085, 0x0001, 0x0c80, 0x0076, 0x0066, 0x0056,
- 0x0046, 0x0036, 0x0026, 0x8aff, 0x0904, 0x1cbc, 0x700c, 0x7214,
- 0x923a, 0x7010, 0x7218, 0x9203, 0x0a04, 0x1cbb, 0x9705, 0x0904,
- 0x1cbb, 0x903e, 0x2730, 0xa880, 0xd0fc, 0x1190, 0x2d00, 0x0002,
- 0x1c9f, 0x1be0, 0x1be0, 0x1c9f, 0x1c9f, 0x1c7d, 0x1c9f, 0x1be0,
- 0x1c83, 0x1c2f, 0x1c2f, 0x1c9f, 0x1c9f, 0x1c9f, 0x1c77, 0x1c2f,
- 0xc0fc, 0xa882, 0xab2c, 0xaa30, 0xad1c, 0xac20, 0xdd9c, 0x0904,
- 0x1ca1, 0x2c05, 0x908a, 0x0034, 0x1a0c, 0x0e02, 0x9082, 0x001b,
- 0x0002, 0x1bcc, 0x1bca, 0x1bca, 0x1bca, 0x1bca, 0x1bca, 0x1bd0,
- 0x1bca, 0x1bca, 0x1bca, 0x1bca, 0x1bca, 0x1bd4, 0x1bca, 0x1bca,
- 0x1bca, 0x1bca, 0x1bca, 0x1bd8, 0x1bca, 0x1bca, 0x1bca, 0x1bca,
- 0x1bca, 0x1bdc, 0x080c, 0x0e02, 0xa774, 0xa678, 0x0804, 0x1ca1,
- 0xa78c, 0xa690, 0x0804, 0x1ca1, 0xa7a4, 0xa6a8, 0x0804, 0x1ca1,
- 0xa7bc, 0xa6c0, 0x0804, 0x1ca1, 0xa7d4, 0xa6d8, 0x0804, 0x1ca1,
- 0x2c05, 0x908a, 0x0036, 0x1a0c, 0x0e02, 0x9082, 0x001b, 0x0002,
- 0x1c03, 0x1c03, 0x1c05, 0x1c03, 0x1c03, 0x1c03, 0x1c0b, 0x1c03,
- 0x1c03, 0x1c03, 0x1c11, 0x1c03, 0x1c03, 0x1c03, 0x1c17, 0x1c03,
- 0x1c03, 0x1c03, 0x1c1d, 0x1c03, 0x1c03, 0x1c03, 0x1c23, 0x1c03,
- 0x1c03, 0x1c03, 0x1c29, 0x080c, 0x0e02, 0xa574, 0xa478, 0xa37c,
- 0xa280, 0x0804, 0x1ca1, 0xa584, 0xa488, 0xa38c, 0xa290, 0x0804,
- 0x1ca1, 0xa594, 0xa498, 0xa39c, 0xa2a0, 0x0804, 0x1ca1, 0xa5a4,
- 0xa4a8, 0xa3ac, 0xa2b0, 0x0804, 0x1ca1, 0xa5b4, 0xa4b8, 0xa3bc,
- 0xa2c0, 0x0804, 0x1ca1, 0xa5c4, 0xa4c8, 0xa3cc, 0xa2d0, 0x0804,
- 0x1ca1, 0xa5d4, 0xa4d8, 0xa3dc, 0xa2e0, 0x0804, 0x1ca1, 0x2c05,
- 0x908a, 0x0034, 0x1a0c, 0x0e02, 0x9082, 0x001b, 0x0002, 0x1c52,
- 0x1c50, 0x1c50, 0x1c50, 0x1c50, 0x1c50, 0x1c5a, 0x1c50, 0x1c50,
- 0x1c50, 0x1c50, 0x1c50, 0x1c62, 0x1c50, 0x1c50, 0x1c50, 0x1c50,
- 0x1c50, 0x1c69, 0x1c50, 0x1c50, 0x1c50, 0x1c50, 0x1c50, 0x1c70,
- 0x080c, 0x0e02, 0xa56c, 0xa470, 0xa774, 0xa678, 0xa37c, 0xa280,
- 0x0804, 0x1ca1, 0xa584, 0xa488, 0xa78c, 0xa690, 0xa394, 0xa298,
- 0x0804, 0x1ca1, 0xa59c, 0xa4a0, 0xa7a4, 0xa6a8, 0xa3ac, 0xa2b0,
- 0x04c0, 0xa5b4, 0xa4b8, 0xa7bc, 0xa6c0, 0xa3c4, 0xa2c8, 0x0488,
- 0xa5cc, 0xa4d0, 0xa7d4, 0xa6d8, 0xa3dc, 0xa2e0, 0x0450, 0xa864,
- 0x9084, 0x00ff, 0x9086, 0x001e, 0x1510, 0x080c, 0x1e80, 0x1904,
- 0x1b7b, 0x900e, 0x04c8, 0xab64, 0x939c, 0x00ff, 0x9386, 0x0048,
- 0x1180, 0x00c6, 0x7004, 0x2060, 0x6004, 0x9086, 0x0043, 0x00ce,
- 0x0904, 0x1c2f, 0xab9c, 0x9016, 0xad8c, 0xac90, 0xaf94, 0xae98,
- 0x0040, 0x9386, 0x0008, 0x0904, 0x1c2f, 0x080c, 0x0e02, 0x080c,
- 0x0e02, 0x7b12, 0x7a16, 0x7d02, 0x7c06, 0x7f0a, 0x7e0e, 0x782b,
- 0x0001, 0x7000, 0x8000, 0x7002, 0xa83c, 0x9300, 0xa83e, 0xa840,
- 0x9201, 0xa842, 0x700c, 0x9300, 0x700e, 0x7010, 0x9201, 0x7012,
- 0x080c, 0x1e80, 0x0008, 0x9006, 0x002e, 0x003e, 0x004e, 0x005e,
- 0x006e, 0x007e, 0x0005, 0x080c, 0x0e02, 0x0026, 0x2001, 0x0105,
- 0x2003, 0x0010, 0x782b, 0x0004, 0x7003, 0x0000, 0x7004, 0x2060,
- 0x6014, 0x2048, 0x080c, 0xbd3b, 0x0118, 0xa880, 0xc0bd, 0xa882,
- 0x6020, 0x9086, 0x0006, 0x1180, 0x2061, 0x0100, 0x62c8, 0x2001,
- 0x00fa, 0x8001, 0x1df0, 0x60c8, 0x9206, 0x1dc0, 0x60c4, 0xa89a,
- 0x60c8, 0xa896, 0x7004, 0x2060, 0x00c6, 0x080c, 0xb974, 0x00ce,
- 0x2001, 0x19d1, 0x2004, 0x9c06, 0x1160, 0x2009, 0x0040, 0x080c,
- 0x2204, 0x080c, 0x9a7a, 0x2011, 0x0000, 0x080c, 0x9918, 0x080c,
- 0x8c6d, 0x002e, 0x0804, 0x1e32, 0x0126, 0x2091, 0x2400, 0xa858,
- 0x2040, 0x792c, 0x782b, 0x0002, 0x9184, 0x0700, 0x1904, 0x1cc5,
- 0x7000, 0x0002, 0x1e32, 0x1d16, 0x1d83, 0x1e30, 0x8001, 0x7002,
- 0xd19c, 0x1150, 0x8aff, 0x05b0, 0x080c, 0x1b75, 0x0904, 0x1e32,
- 0x080c, 0x1b75, 0x0804, 0x1e32, 0x782b, 0x0004, 0xd194, 0x0148,
- 0xa880, 0xc0fc, 0xa882, 0x8aff, 0x11d8, 0xa87c, 0xc0f5, 0xa87e,
- 0x00b8, 0x0026, 0x0036, 0xab3c, 0xaa40, 0x7810, 0xa82e, 0x931a,
- 0x7814, 0xa832, 0x9213, 0x7800, 0xa81e, 0x7804, 0xa822, 0xab3e,
- 0xaa42, 0x003e, 0x002e, 0x080c, 0x1e98, 0xa880, 0xc0fd, 0xa882,
- 0x2a00, 0xa816, 0x2800, 0xa85a, 0x2c00, 0xa812, 0x7003, 0x0000,
- 0x0804, 0x1e32, 0x00f6, 0x0026, 0x781c, 0x0006, 0x7818, 0x0006,
- 0x2079, 0x0100, 0x7a14, 0x9284, 0x1984, 0x9085, 0x0012, 0x7816,
- 0x0036, 0x2019, 0x1000, 0x8319, 0x090c, 0x0e02, 0x7820, 0xd0bc,
- 0x1dd0, 0x003e, 0x79c8, 0x000e, 0x9102, 0x001e, 0x0006, 0x0016,
- 0x79c4, 0x000e, 0x9103, 0x78c6, 0x000e, 0x78ca, 0x9284, 0x1984,
- 0x9085, 0x0012, 0x7816, 0x002e, 0x00fe, 0x782b, 0x0008, 0x7003,
- 0x0000, 0x0804, 0x1e32, 0x8001, 0x7002, 0xd194, 0x0170, 0x782c,
- 0xd0fc, 0x1904, 0x1d09, 0xd19c, 0x1904, 0x1e2e, 0x8aff, 0x0904,
- 0x1e32, 0x080c, 0x1b75, 0x0804, 0x1e32, 0x0026, 0x0036, 0xab3c,
- 0xaa40, 0x080c, 0x1e98, 0xdd9c, 0x1904, 0x1ded, 0x2c05, 0x908a,
- 0x0036, 0x1a0c, 0x0e02, 0x9082, 0x001b, 0x0002, 0x1dc1, 0x1dc1,
- 0x1dc3, 0x1dc1, 0x1dc1, 0x1dc1, 0x1dc9, 0x1dc1, 0x1dc1, 0x1dc1,
- 0x1dcf, 0x1dc1, 0x1dc1, 0x1dc1, 0x1dd5, 0x1dc1, 0x1dc1, 0x1dc1,
- 0x1ddb, 0x1dc1, 0x1dc1, 0x1dc1, 0x1de1, 0x1dc1, 0x1dc1, 0x1dc1,
- 0x1de7, 0x080c, 0x0e02, 0xa07c, 0x931a, 0xa080, 0x9213, 0x0804,
- 0x1d35, 0xa08c, 0x931a, 0xa090, 0x9213, 0x0804, 0x1d35, 0xa09c,
- 0x931a, 0xa0a0, 0x9213, 0x0804, 0x1d35, 0xa0ac, 0x931a, 0xa0b0,
- 0x9213, 0x0804, 0x1d35, 0xa0bc, 0x931a, 0xa0c0, 0x9213, 0x0804,
- 0x1d35, 0xa0cc, 0x931a, 0xa0d0, 0x9213, 0x0804, 0x1d35, 0xa0dc,
- 0x931a, 0xa0e0, 0x9213, 0x0804, 0x1d35, 0x2c05, 0x908a, 0x0034,
- 0x1a0c, 0x0e02, 0x9082, 0x001b, 0x0002, 0x1e10, 0x1e0e, 0x1e0e,
- 0x1e0e, 0x1e0e, 0x1e0e, 0x1e16, 0x1e0e, 0x1e0e, 0x1e0e, 0x1e0e,
- 0x1e0e, 0x1e1c, 0x1e0e, 0x1e0e, 0x1e0e, 0x1e0e, 0x1e0e, 0x1e22,
- 0x1e0e, 0x1e0e, 0x1e0e, 0x1e0e, 0x1e0e, 0x1e28, 0x080c, 0x0e02,
- 0xa07c, 0x931a, 0xa080, 0x9213, 0x0804, 0x1d35, 0xa094, 0x931a,
- 0xa098, 0x9213, 0x0804, 0x1d35, 0xa0ac, 0x931a, 0xa0b0, 0x9213,
- 0x0804, 0x1d35, 0xa0c4, 0x931a, 0xa0c8, 0x9213, 0x0804, 0x1d35,
- 0xa0dc, 0x931a, 0xa0e0, 0x9213, 0x0804, 0x1d35, 0x0804, 0x1d31,
- 0x080c, 0x0e02, 0x012e, 0x0005, 0x00f6, 0x00e6, 0x2071, 0x1a42,
- 0x7000, 0x9086, 0x0000, 0x0904, 0x1e7d, 0x2079, 0x0090, 0x2009,
- 0x0207, 0x210c, 0xd194, 0x01b8, 0x2009, 0x020c, 0x210c, 0x9184,
- 0x0003, 0x0188, 0x080c, 0xdb9b, 0x2001, 0x0133, 0x2004, 0x9005,
- 0x090c, 0x0e02, 0x0016, 0x2009, 0x0040, 0x080c, 0x2204, 0x001e,
- 0x2001, 0x020c, 0x2102, 0x2009, 0x0206, 0x2104, 0x2009, 0x0203,
- 0x210c, 0x9106, 0x1120, 0x2009, 0x0040, 0x080c, 0x2204, 0x782c,
- 0xd0fc, 0x09a8, 0x080c, 0x1d04, 0x7000, 0x9086, 0x0000, 0x1978,
- 0x782b, 0x0004, 0x782c, 0xd0ac, 0x1de8, 0x2009, 0x0040, 0x080c,
- 0x2204, 0x782b, 0x0002, 0x7003, 0x0000, 0x00ee, 0x00fe, 0x0005,
- 0x8c60, 0x2c05, 0x9005, 0x0110, 0x8a51, 0x0005, 0xa004, 0x9005,
- 0x0168, 0xa85a, 0x2040, 0xa064, 0x9084, 0x000f, 0x9080, 0x1ec2,
- 0x2065, 0x8cff, 0x090c, 0x0e02, 0x8a51, 0x0005, 0x2050, 0x0005,
- 0x8a50, 0x8c61, 0x2c05, 0x9005, 0x1190, 0x2800, 0x9906, 0x0120,
- 0xa000, 0x9005, 0x1108, 0x2900, 0x2040, 0xa85a, 0xa064, 0x9084,
- 0x000f, 0x9080, 0x1ed2, 0x2065, 0x8cff, 0x090c, 0x0e02, 0x0005,
- 0x0000, 0x001d, 0x0021, 0x0025, 0x0029, 0x002d, 0x0031, 0x0035,
- 0x0000, 0x001b, 0x0021, 0x0027, 0x002d, 0x0033, 0x0000, 0x0000,
- 0x0023, 0x0000, 0x0000, 0x1eb5, 0x1eb1, 0x0000, 0x0000, 0x1ebf,
- 0x0000, 0x1eb5, 0x1ebc, 0x1ebc, 0x1eb9, 0x0000, 0x0000, 0x0000,
- 0x1ebf, 0x1ebc, 0x0000, 0x1eb7, 0x1eb7, 0x0000, 0x0000, 0x1ebf,
- 0x0000, 0x1eb7, 0x1ebd, 0x1ebd, 0x1ebd, 0x0000, 0x0000, 0x0000,
- 0x1ebf, 0x1ebd, 0x00c6, 0x00d6, 0x0086, 0xab42, 0xac3e, 0xa888,
- 0x9055, 0x0904, 0x20c1, 0x2940, 0xa064, 0x90ec, 0x000f, 0x9084,
- 0x00ff, 0x9086, 0x0008, 0x1118, 0x2061, 0x1ebd, 0x00d0, 0x9de0,
- 0x1ec2, 0x9d86, 0x0007, 0x0130, 0x9d86, 0x000e, 0x0118, 0x9d86,
- 0x000f, 0x1120, 0xa08c, 0x9422, 0xa090, 0x931b, 0x2c05, 0x9065,
- 0x1140, 0x0310, 0x0804, 0x20c1, 0xa004, 0x9045, 0x0904, 0x20c1,
- 0x08d8, 0x2c05, 0x9005, 0x0904, 0x1fa9, 0xdd9c, 0x1904, 0x1f65,
- 0x908a, 0x0036, 0x1a0c, 0x0e02, 0x9082, 0x001b, 0x0002, 0x1f3a,
- 0x1f3a, 0x1f3c, 0x1f3a, 0x1f3a, 0x1f3a, 0x1f42, 0x1f3a, 0x1f3a,
- 0x1f3a, 0x1f48, 0x1f3a, 0x1f3a, 0x1f3a, 0x1f4e, 0x1f3a, 0x1f3a,
- 0x1f3a, 0x1f54, 0x1f3a, 0x1f3a, 0x1f3a, 0x1f5a, 0x1f3a, 0x1f3a,
- 0x1f3a, 0x1f60, 0x080c, 0x0e02, 0xa07c, 0x9422, 0xa080, 0x931b,
- 0x0804, 0x1f9f, 0xa08c, 0x9422, 0xa090, 0x931b, 0x0804, 0x1f9f,
- 0xa09c, 0x9422, 0xa0a0, 0x931b, 0x0804, 0x1f9f, 0xa0ac, 0x9422,
- 0xa0b0, 0x931b, 0x0804, 0x1f9f, 0xa0bc, 0x9422, 0xa0c0, 0x931b,
- 0x0804, 0x1f9f, 0xa0cc, 0x9422, 0xa0d0, 0x931b, 0x0804, 0x1f9f,
- 0xa0dc, 0x9422, 0xa0e0, 0x931b, 0x04d0, 0x908a, 0x0034, 0x1a0c,
- 0x0e02, 0x9082, 0x001b, 0x0002, 0x1f87, 0x1f85, 0x1f85, 0x1f85,
- 0x1f85, 0x1f85, 0x1f8c, 0x1f85, 0x1f85, 0x1f85, 0x1f85, 0x1f85,
- 0x1f91, 0x1f85, 0x1f85, 0x1f85, 0x1f85, 0x1f85, 0x1f96, 0x1f85,
- 0x1f85, 0x1f85, 0x1f85, 0x1f85, 0x1f9b, 0x080c, 0x0e02, 0xa07c,
- 0x9422, 0xa080, 0x931b, 0x0098, 0xa094, 0x9422, 0xa098, 0x931b,
- 0x0070, 0xa0ac, 0x9422, 0xa0b0, 0x931b, 0x0048, 0xa0c4, 0x9422,
- 0xa0c8, 0x931b, 0x0020, 0xa0dc, 0x9422, 0xa0e0, 0x931b, 0x0630,
- 0x2300, 0x9405, 0x0160, 0x8a51, 0x0904, 0x20c1, 0x8c60, 0x0804,
- 0x1f11, 0xa004, 0x9045, 0x0904, 0x20c1, 0x0804, 0x1eec, 0x8a51,
- 0x0904, 0x20c1, 0x8c60, 0x2c05, 0x9005, 0x1158, 0xa004, 0x9045,
- 0x0904, 0x20c1, 0xa064, 0x90ec, 0x000f, 0x9de0, 0x1ec2, 0x2c05,
- 0x2060, 0xa880, 0xc0fc, 0xa882, 0x0804, 0x20b6, 0x2c05, 0x8422,
- 0x8420, 0x831a, 0x9399, 0x0000, 0xac2e, 0xab32, 0xdd9c, 0x1904,
- 0x2053, 0x9082, 0x001b, 0x0002, 0x1fef, 0x1fef, 0x1ff1, 0x1fef,
- 0x1fef, 0x1fef, 0x1fff, 0x1fef, 0x1fef, 0x1fef, 0x200d, 0x1fef,
- 0x1fef, 0x1fef, 0x201b, 0x1fef, 0x1fef, 0x1fef, 0x2029, 0x1fef,
- 0x1fef, 0x1fef, 0x2037, 0x1fef, 0x1fef, 0x1fef, 0x2045, 0x080c,
- 0x0e02, 0xa17c, 0x2400, 0x9122, 0xa180, 0x2300, 0x911b, 0x0a0c,
- 0x0e02, 0xa074, 0x9420, 0xa078, 0x9319, 0x0804, 0x20b1, 0xa18c,
- 0x2400, 0x9122, 0xa190, 0x2300, 0x911b, 0x0a0c, 0x0e02, 0xa084,
- 0x9420, 0xa088, 0x9319, 0x0804, 0x20b1, 0xa19c, 0x2400, 0x9122,
- 0xa1a0, 0x2300, 0x911b, 0x0a0c, 0x0e02, 0xa094, 0x9420, 0xa098,
- 0x9319, 0x0804, 0x20b1, 0xa1ac, 0x2400, 0x9122, 0xa1b0, 0x2300,
- 0x911b, 0x0a0c, 0x0e02, 0xa0a4, 0x9420, 0xa0a8, 0x9319, 0x0804,
- 0x20b1, 0xa1bc, 0x2400, 0x9122, 0xa1c0, 0x2300, 0x911b, 0x0a0c,
- 0x0e02, 0xa0b4, 0x9420, 0xa0b8, 0x9319, 0x0804, 0x20b1, 0xa1cc,
- 0x2400, 0x9122, 0xa1d0, 0x2300, 0x911b, 0x0a0c, 0x0e02, 0xa0c4,
- 0x9420, 0xa0c8, 0x9319, 0x0804, 0x20b1, 0xa1dc, 0x2400, 0x9122,
- 0xa1e0, 0x2300, 0x911b, 0x0a0c, 0x0e02, 0xa0d4, 0x9420, 0xa0d8,
- 0x9319, 0x0804, 0x20b1, 0x9082, 0x001b, 0x0002, 0x2071, 0x206f,
- 0x206f, 0x206f, 0x206f, 0x206f, 0x207e, 0x206f, 0x206f, 0x206f,
- 0x206f, 0x206f, 0x208b, 0x206f, 0x206f, 0x206f, 0x206f, 0x206f,
- 0x2098, 0x206f, 0x206f, 0x206f, 0x206f, 0x206f, 0x20a5, 0x080c,
- 0x0e02, 0xa17c, 0x2400, 0x9122, 0xa180, 0x2300, 0x911b, 0x0a0c,
- 0x0e02, 0xa06c, 0x9420, 0xa070, 0x9319, 0x0498, 0xa194, 0x2400,
- 0x9122, 0xa198, 0x2300, 0x911b, 0x0a0c, 0x0e02, 0xa084, 0x9420,
- 0xa088, 0x9319, 0x0430, 0xa1ac, 0x2400, 0x9122, 0xa1b0, 0x2300,
- 0x911b, 0x0a0c, 0x0e02, 0xa09c, 0x9420, 0xa0a0, 0x9319, 0x00c8,
- 0xa1c4, 0x2400, 0x9122, 0xa1c8, 0x2300, 0x911b, 0x0a0c, 0x0e02,
- 0xa0b4, 0x9420, 0xa0b8, 0x9319, 0x0060, 0xa1dc, 0x2400, 0x9122,
- 0xa1e0, 0x2300, 0x911b, 0x0a0c, 0x0e02, 0xa0cc, 0x9420, 0xa0d0,
- 0x9319, 0xac1e, 0xab22, 0xa880, 0xc0fd, 0xa882, 0x2800, 0xa85a,
- 0x2c00, 0xa812, 0x2a00, 0xa816, 0x000e, 0x000e, 0x000e, 0x9006,
- 0x0028, 0x008e, 0x00de, 0x00ce, 0x9085, 0x0001, 0x0005, 0x2001,
- 0x0005, 0x2004, 0xd0bc, 0x190c, 0x0dfb, 0x9084, 0x0007, 0x0002,
- 0x20e2, 0x1d04, 0x20e2, 0x20d8, 0x20db, 0x20de, 0x20db, 0x20de,
- 0x080c, 0x1d04, 0x0005, 0x080c, 0x11fa, 0x0005, 0x080c, 0x1d04,
- 0x080c, 0x11fa, 0x0005, 0x0126, 0x2091, 0x2600, 0x2079, 0x0200,
- 0x2071, 0x0260, 0x2069, 0x1800, 0x7817, 0x0000, 0x789b, 0x0814,
- 0x78a3, 0x0406, 0x789f, 0x0410, 0x2009, 0x013b, 0x200b, 0x0400,
- 0x781b, 0x0002, 0x783b, 0x001f, 0x7837, 0x0020, 0x7803, 0x1600,
- 0x012e, 0x0005, 0x2091, 0x2600, 0x781c, 0xd0a4, 0x190c, 0x2201,
- 0x7900, 0xd1dc, 0x1118, 0x9084, 0x0006, 0x001a, 0x9084, 0x000e,
- 0x0002, 0x2129, 0x2121, 0x7b34, 0x2121, 0x2123, 0x2123, 0x2123,
- 0x2123, 0x7b1a, 0x2121, 0x2125, 0x2121, 0x2123, 0x2121, 0x2123,
- 0x2121, 0x080c, 0x0e02, 0x0031, 0x0020, 0x080c, 0x7b1a, 0x080c,
- 0x7b34, 0x0005, 0x0006, 0x0016, 0x0026, 0x080c, 0xdb9b, 0x7930,
- 0x9184, 0x0003, 0x01c0, 0x2001, 0x19d1, 0x2004, 0x9005, 0x0170,
- 0x2001, 0x0133, 0x2004, 0x9005, 0x090c, 0x0e02, 0x00c6, 0x2001,
- 0x19d1, 0x2064, 0x080c, 0xb974, 0x00ce, 0x00f8, 0x2009, 0x0040,
- 0x080c, 0x2204, 0x00d0, 0x9184, 0x0014, 0x01a0, 0x6a00, 0x9286,
- 0x0003, 0x0160, 0x080c, 0x717f, 0x1138, 0x080c, 0x747b, 0x080c,
- 0x5e30, 0x080c, 0x709f, 0x0010, 0x080c, 0x5cef, 0x080c, 0x7be3,
- 0x0041, 0x0018, 0x9184, 0x9540, 0x1dc8, 0x002e, 0x001e, 0x000e,
- 0x0005, 0x00e6, 0x0036, 0x0046, 0x0056, 0x2071, 0x1a3f, 0x080c,
- 0x1983, 0x005e, 0x004e, 0x003e, 0x00ee, 0x0005, 0x0126, 0x2091,
- 0x2e00, 0x2071, 0x1800, 0x7128, 0x2001, 0x1949, 0x2102, 0x2001,
- 0x1951, 0x2102, 0x2001, 0x013b, 0x2102, 0x2079, 0x0200, 0x2001,
- 0x0201, 0x789e, 0x78a3, 0x0200, 0x9198, 0x0007, 0x831c, 0x831c,
- 0x831c, 0x9398, 0x0005, 0x2320, 0x9182, 0x0204, 0x1230, 0x2011,
- 0x0008, 0x8423, 0x8423, 0x8423, 0x0488, 0x9182, 0x024c, 0x1240,
- 0x2011, 0x0007, 0x8403, 0x8003, 0x9400, 0x9400, 0x9420, 0x0430,
- 0x9182, 0x02bc, 0x1238, 0x2011, 0x0006, 0x8403, 0x8003, 0x9400,
- 0x9420, 0x00e0, 0x9182, 0x034c, 0x1230, 0x2011, 0x0005, 0x8403,
- 0x8003, 0x9420, 0x0098, 0x9182, 0x042c, 0x1228, 0x2011, 0x0004,
- 0x8423, 0x8423, 0x0058, 0x9182, 0x059c, 0x1228, 0x2011, 0x0003,
- 0x8403, 0x9420, 0x0018, 0x2011, 0x0002, 0x8423, 0x9482, 0x0228,
- 0x8002, 0x8020, 0x8301, 0x9402, 0x0110, 0x0208, 0x8321, 0x8217,
- 0x8203, 0x9405, 0x789a, 0x012e, 0x0005, 0x0006, 0x00d6, 0x2069,
- 0x0200, 0x6814, 0x9084, 0xffc0, 0x910d, 0x6916, 0x00de, 0x000e,
- 0x0005, 0x00d6, 0x2069, 0x0200, 0x9005, 0x6810, 0x0110, 0xc0a5,
- 0x0008, 0xc0a4, 0x6812, 0x00de, 0x0005, 0x0006, 0x00d6, 0x2069,
- 0x0200, 0x6810, 0x9084, 0xfff8, 0x910d, 0x6912, 0x00de, 0x000e,
- 0x0005, 0x7938, 0x080c, 0x0dfb, 0x00f6, 0x2079, 0x0200, 0x7902,
- 0xa001, 0xa001, 0xa001, 0xa001, 0xa001, 0xa001, 0x7902, 0xa001,
- 0xa001, 0xa001, 0xa001, 0xa001, 0xa001, 0x00fe, 0x0005, 0x0126,
- 0x2091, 0x2800, 0x2061, 0x0100, 0x2071, 0x1800, 0x2009, 0x0000,
- 0x080c, 0x2ab6, 0x080c, 0x2989, 0x2001, 0x0100, 0x2004, 0x9086,
- 0x000a, 0x0558, 0x6054, 0x8004, 0x8004, 0x8004, 0x8004, 0x9084,
- 0x000c, 0x6150, 0x918c, 0xfff3, 0x9105, 0x6052, 0x6050, 0x9084,
- 0xb17f, 0x9085, 0x2000, 0x6052, 0x2009, 0x1977, 0x2011, 0x1978,
- 0x6358, 0x939c, 0x38f0, 0x2320, 0x080c, 0x29f6, 0x1238, 0x939d,
- 0x4003, 0x94a5, 0x8603, 0x230a, 0x2412, 0x0030, 0x939d, 0x0203,
- 0x94a5, 0x8603, 0x230a, 0x2412, 0x0050, 0x2001, 0x1977, 0x2003,
- 0x0700, 0x2001, 0x1978, 0x2003, 0x0700, 0x080c, 0x2bc2, 0x9006,
- 0x080c, 0x29b8, 0x9006, 0x080c, 0x299b, 0x20a9, 0x0012, 0x1d04,
- 0x2267, 0x2091, 0x6000, 0x1f04, 0x2267, 0x602f, 0x0100, 0x602f,
- 0x0000, 0x6050, 0x9085, 0x0400, 0x9084, 0xdfff, 0x6052, 0x6024,
- 0x6026, 0x080c, 0x26a7, 0x2009, 0x00ef, 0x6132, 0x6136, 0x080c,
- 0x26b7, 0x60e7, 0x0000, 0x61ea, 0x60e3, 0x0002, 0x604b, 0xf7f7,
- 0x6043, 0x0000, 0x602f, 0x0080, 0x602f, 0x0000, 0x6007, 0x149f,
- 0x60bb, 0x0000, 0x20a9, 0x0018, 0x60bf, 0x0000, 0x1f04, 0x2294,
- 0x60bb, 0x0000, 0x60bf, 0x0108, 0x60bf, 0x0012, 0x60bf, 0x0320,
- 0x60bf, 0x0018, 0x601b, 0x00f0, 0x601f, 0x001e, 0x600f, 0x006b,
- 0x602b, 0x402f, 0x012e, 0x0005, 0x00f6, 0x2079, 0x0140, 0x78c3,
- 0x0080, 0x78c3, 0x0083, 0x78c3, 0x0000, 0x00fe, 0x0005, 0x2001,
- 0x1834, 0x2003, 0x0000, 0x2001, 0x1833, 0x2003, 0x0001, 0x0005,
- 0x0126, 0x2091, 0x2800, 0x0006, 0x0016, 0x0026, 0x6124, 0x9184,
- 0x5e2c, 0x1118, 0x9184, 0x0007, 0x002a, 0x9195, 0x0004, 0x9284,
- 0x0007, 0x0002, 0x22f4, 0x22da, 0x22dd, 0x22e0, 0x22e5, 0x22e7,
- 0x22eb, 0x22ef, 0x080c, 0x84e3, 0x00b8, 0x080c, 0x85b2, 0x00a0,
- 0x080c, 0x85b2, 0x080c, 0x84e3, 0x0078, 0x0099, 0x0068, 0x080c,
- 0x84e3, 0x0079, 0x0048, 0x080c, 0x85b2, 0x0059, 0x0028, 0x080c,
- 0x85b2, 0x080c, 0x84e3, 0x0029, 0x002e, 0x001e, 0x000e, 0x012e,
- 0x0005, 0x00a6, 0x6124, 0x6028, 0xd09c, 0x0118, 0xd19c, 0x1904,
- 0x2548, 0xd1f4, 0x190c, 0x0dfb, 0x080c, 0x717f, 0x0904, 0x234f,
- 0x080c, 0xc444, 0x1120, 0x7000, 0x9086, 0x0003, 0x0570, 0x6024,
- 0x9084, 0x1800, 0x0550, 0x080c, 0x71a2, 0x0118, 0x080c, 0x7190,
- 0x1520, 0x6027, 0x0020, 0x6043, 0x0000, 0x080c, 0xc444, 0x0168,
- 0x080c, 0x71a2, 0x1150, 0x2001, 0x1981, 0x2003, 0x0001, 0x6027,
- 0x1800, 0x080c, 0x6fee, 0x0804, 0x254b, 0x70a0, 0x9005, 0x1150,
- 0x70a3, 0x0001, 0x00d6, 0x2069, 0x0140, 0x080c, 0x71d3, 0x00de,
- 0x1904, 0x254b, 0x080c, 0x7485, 0x0428, 0x080c, 0x71a2, 0x1590,
- 0x6024, 0x9084, 0x1800, 0x1108, 0x0468, 0x080c, 0x7485, 0x080c,
- 0x747b, 0x080c, 0x5e30, 0x080c, 0x709f, 0x0804, 0x2548, 0xd1ac,
- 0x1508, 0x6024, 0xd0dc, 0x1170, 0xd0e4, 0x1178, 0xd0d4, 0x1190,
- 0xd0cc, 0x0130, 0x7094, 0x9086, 0x0029, 0x1110, 0x080c, 0x736a,
- 0x0804, 0x2548, 0x080c, 0x7480, 0x0048, 0x2001, 0x1957, 0x2003,
- 0x0002, 0x0020, 0x080c, 0x72ce, 0x0804, 0x2548, 0x080c, 0x7404,
- 0x0804, 0x2548, 0xd1ac, 0x0904, 0x2469, 0x080c, 0x717f, 0x11c0,
- 0x6027, 0x0020, 0x0006, 0x0026, 0x0036, 0x080c, 0x7199, 0x1158,
- 0x080c, 0x747b, 0x080c, 0x5e30, 0x080c, 0x709f, 0x003e, 0x002e,
- 0x000e, 0x00ae, 0x0005, 0x003e, 0x002e, 0x000e, 0x080c, 0x7157,
- 0x0016, 0x0046, 0x00c6, 0x644c, 0x9486, 0xf0f0, 0x1138, 0x2061,
- 0x0100, 0x644a, 0x6043, 0x0090, 0x6043, 0x0010, 0x74d6, 0x948c,
- 0xff00, 0x7038, 0xd084, 0x0178, 0x9186, 0xf800, 0x1160, 0x7044,
- 0xd084, 0x1148, 0xc085, 0x7046, 0x0036, 0x2418, 0x2011, 0x8016,
- 0x080c, 0x4a18, 0x003e, 0x080c, 0xc43d, 0x1904, 0x2446, 0x9196,
- 0xff00, 0x05a8, 0x705c, 0x9084, 0x00ff, 0x810f, 0x81ff, 0x0110,
- 0x9116, 0x0568, 0x7130, 0xd184, 0x1550, 0x080c, 0x3204, 0x0128,
- 0xc18d, 0x7132, 0x080c, 0x66c2, 0x1510, 0x6240, 0x9294, 0x0010,
- 0x0130, 0x6248, 0x9294, 0xff00, 0x9296, 0xff00, 0x01c0, 0x7030,
- 0xd08c, 0x0904, 0x2446, 0x7038, 0xd08c, 0x1140, 0x2001, 0x180c,
- 0x200c, 0xd1ac, 0x1904, 0x2446, 0xc1ad, 0x2102, 0x0036, 0x73d4,
- 0x2011, 0x8013, 0x080c, 0x4a18, 0x003e, 0x0804, 0x2446, 0x7038,
- 0xd08c, 0x1140, 0x2001, 0x180c, 0x200c, 0xd1ac, 0x1904, 0x2446,
- 0xc1ad, 0x2102, 0x0036, 0x73d4, 0x2011, 0x8013, 0x080c, 0x4a18,
- 0x003e, 0x7130, 0xc185, 0x7132, 0x2011, 0x185c, 0x220c, 0x00f0,
- 0x0016, 0x2009, 0x0001, 0x2011, 0x0100, 0x080c, 0x8451, 0x2019,
- 0x000e, 0x00c6, 0x2061, 0x0000, 0x080c, 0xd74e, 0x00ce, 0x9484,
- 0x00ff, 0x9080, 0x3209, 0x200d, 0x918c, 0xff00, 0x810f, 0x2120,
- 0x9006, 0x2009, 0x000e, 0x080c, 0xd7d6, 0x001e, 0xd1ac, 0x1148,
- 0x0016, 0x2009, 0x0002, 0x2019, 0x0004, 0x080c, 0x3076, 0x001e,
- 0x00a8, 0x0156, 0x00b6, 0x20a9, 0x007f, 0x900e, 0x080c, 0x63a4,
- 0x1140, 0x7030, 0xd084, 0x1118, 0xb800, 0xd0bc, 0x1110, 0x080c,
- 0x5e4a, 0x8108, 0x1f04, 0x2436, 0x00be, 0x015e, 0x00ce, 0x004e,
- 0x080c, 0x9f5b, 0x60e3, 0x0000, 0x001e, 0x2001, 0x1800, 0x2014,
- 0x9296, 0x0004, 0x1170, 0xd19c, 0x11a0, 0x2011, 0x180c, 0x2214,
- 0xd29c, 0x1120, 0x6204, 0x9295, 0x0002, 0x6206, 0x6228, 0xc29d,
- 0x622a, 0x2003, 0x0001, 0x2001, 0x1825, 0x2003, 0x0000, 0x6027,
- 0x0020, 0xd194, 0x0904, 0x2548, 0x0016, 0x6220, 0xd2b4, 0x0904,
- 0x24f1, 0x080c, 0x82da, 0x080c, 0x9605, 0x6027, 0x0004, 0x00f6,
- 0x2019, 0x19cb, 0x2304, 0x907d, 0x0904, 0x24c0, 0x7804, 0x9086,
- 0x0032, 0x15f0, 0x00d6, 0x00c6, 0x00e6, 0x0096, 0x2069, 0x0140,
- 0x782c, 0x685e, 0x7808, 0x685a, 0x6043, 0x0002, 0x2001, 0x0003,
- 0x8001, 0x1df0, 0x6043, 0x0000, 0x2001, 0x003c, 0x8001, 0x1df0,
- 0x080c, 0x2b98, 0x2001, 0x001e, 0x8001, 0x0240, 0x20a9, 0x0009,
- 0x080c, 0x2a91, 0x6904, 0xd1dc, 0x1140, 0x0cb0, 0x2001, 0x0100,
- 0x080c, 0x2b88, 0x9006, 0x080c, 0x2b88, 0x080c, 0x8a84, 0x080c,
- 0x8b90, 0x7814, 0x2048, 0xa867, 0x0103, 0x2f60, 0x080c, 0x9fd5,
- 0x009e, 0x00ee, 0x00ce, 0x00de, 0x00fe, 0x001e, 0x00ae, 0x0005,
- 0x00fe, 0x00d6, 0x2069, 0x0140, 0x6804, 0x9084, 0x4000, 0x0110,
- 0x080c, 0x2b98, 0x00de, 0x00c6, 0x2061, 0x19c2, 0x6028, 0x080c,
- 0xc444, 0x0120, 0x909a, 0x0003, 0x1258, 0x0018, 0x909a, 0x00c8,
- 0x1238, 0x8000, 0x602a, 0x00ce, 0x080c, 0x95e1, 0x0804, 0x2547,
- 0x2061, 0x0100, 0x62c0, 0x080c, 0x9de1, 0x2019, 0x19cb, 0x2304,
- 0x9065, 0x0120, 0x2009, 0x0027, 0x080c, 0xa053, 0x00ce, 0x0804,
- 0x2547, 0xd2bc, 0x0904, 0x2534, 0x080c, 0x82e7, 0x6014, 0x9084,
- 0x1984, 0x9085, 0x0010, 0x6016, 0x6027, 0x0004, 0x00d6, 0x2069,
- 0x0140, 0x6804, 0x9084, 0x4000, 0x0110, 0x080c, 0x2b98, 0x00de,
- 0x00c6, 0x2061, 0x19c2, 0x6044, 0x080c, 0xc444, 0x0120, 0x909a,
- 0x0003, 0x1628, 0x0018, 0x909a, 0x00c8, 0x1608, 0x8000, 0x6046,
- 0x603c, 0x00ce, 0x9005, 0x0558, 0x2009, 0x07d0, 0x080c, 0x82df,
- 0x9080, 0x0008, 0x2004, 0x9086, 0x0006, 0x1138, 0x6114, 0x918c,
- 0x1984, 0x918d, 0x0012, 0x6116, 0x00d0, 0x6114, 0x918c, 0x1984,
- 0x918d, 0x0016, 0x6116, 0x0098, 0x6027, 0x0004, 0x0080, 0x0036,
- 0x2019, 0x0001, 0x080c, 0x989c, 0x003e, 0x2019, 0x19d1, 0x2304,
- 0x9065, 0x0120, 0x2009, 0x004f, 0x080c, 0xa053, 0x00ce, 0x001e,
- 0xd19c, 0x0904, 0x2612, 0x7038, 0xd0ac, 0x1904, 0x25e7, 0x0016,
- 0x0156, 0x6027, 0x0008, 0x2001, 0x0100, 0x2004, 0x9086, 0x000a,
- 0x0904, 0x25c4, 0x6050, 0x9085, 0x0040, 0x6052, 0x6050, 0x9084,
- 0xfbcf, 0x6052, 0x080c, 0x2ab0, 0x9085, 0x2000, 0x6052, 0x20a9,
- 0x0012, 0x1d04, 0x2569, 0x080c, 0x830e, 0x1f04, 0x2569, 0x6050,
- 0x9085, 0x0400, 0x9084, 0xdfbf, 0x6052, 0x20a9, 0x0028, 0xa001,
- 0x1f04, 0x2577, 0x6150, 0x9185, 0x1400, 0x6052, 0x20a9, 0x0366,
- 0x1d04, 0x2580, 0x080c, 0x830e, 0x6020, 0xd09c, 0x1138, 0x015e,
- 0x6152, 0x001e, 0x6027, 0x0008, 0x0804, 0x2612, 0x080c, 0x2a78,
- 0x1f04, 0x2580, 0x015e, 0x6152, 0x001e, 0x6027, 0x0008, 0x0016,
- 0x6028, 0xc09c, 0x602a, 0x080c, 0x9f5b, 0x60e3, 0x0000, 0x080c,
- 0xdb7a, 0x080c, 0xdb95, 0x080c, 0x54e0, 0xd0fc, 0x1138, 0x080c,
- 0xc43d, 0x1120, 0x9085, 0x0001, 0x080c, 0x71c3, 0x9006, 0x080c,
- 0x2b88, 0x2009, 0x0002, 0x080c, 0x2ab6, 0x00e6, 0x2071, 0x1800,
- 0x7003, 0x0004, 0x080c, 0x0ed8, 0x00ee, 0x6027, 0x0008, 0x080c,
- 0x0b8f, 0x001e, 0x0804, 0x2612, 0x080c, 0x2bc2, 0x080c, 0x2bf5,
- 0x6050, 0xc0e5, 0x6052, 0x20a9, 0x0367, 0x1f04, 0x25e5, 0x1d04,
- 0x25cf, 0x080c, 0x830e, 0x6020, 0xd09c, 0x1db8, 0x00f6, 0x2079,
- 0x0100, 0x080c, 0x2a06, 0x00fe, 0x1d80, 0x6050, 0xc0e4, 0x6052,
- 0x6027, 0x0008, 0x015e, 0x001e, 0x0468, 0x015e, 0x001e, 0x0016,
- 0x6028, 0xc09c, 0x602a, 0x080c, 0x9f5b, 0x60e3, 0x0000, 0x080c,
- 0xdb7a, 0x080c, 0xdb95, 0x080c, 0x54e0, 0xd0fc, 0x1138, 0x080c,
- 0xc43d, 0x1120, 0x9085, 0x0001, 0x080c, 0x71c3, 0x9006, 0x080c,
- 0x2b88, 0x2009, 0x0002, 0x080c, 0x2ab6, 0x00e6, 0x2071, 0x1800,
- 0x7003, 0x0004, 0x080c, 0x0ed8, 0x00ee, 0x6027, 0x0008, 0x080c,
- 0x0b8f, 0x001e, 0x918c, 0xffd0, 0x6126, 0x00ae, 0x0005, 0x0006,
- 0x0016, 0x0026, 0x0036, 0x00e6, 0x00f6, 0x0126, 0x2091, 0x8000,
- 0x2071, 0x1800, 0x71cc, 0x70ce, 0x9116, 0x0904, 0x2666, 0x81ff,
- 0x01a0, 0x2009, 0x0000, 0x080c, 0x2ab6, 0x2011, 0x8011, 0x2019,
- 0x010e, 0x231c, 0x939e, 0x0007, 0x1118, 0x2019, 0x0001, 0x0010,
- 0x2019, 0x0000, 0x080c, 0x4a18, 0x0448, 0x2001, 0x1982, 0x200c,
- 0x81ff, 0x1140, 0x2001, 0x0109, 0x2004, 0xd0b4, 0x0118, 0x2019,
- 0x0003, 0x0008, 0x2118, 0x2011, 0x8012, 0x080c, 0x4a18, 0x080c,
- 0x0ed8, 0x080c, 0x54e0, 0xd0fc, 0x1188, 0x080c, 0xc43d, 0x1170,
- 0x00c6, 0x080c, 0x2702, 0x080c, 0x9803, 0x2061, 0x0100, 0x2019,
- 0x0028, 0x2009, 0x0002, 0x080c, 0x3076, 0x00ce, 0x012e, 0x00fe,
- 0x00ee, 0x003e, 0x002e, 0x001e, 0x000e, 0x0005, 0x2028, 0x918c,
- 0x00ff, 0x2130, 0x9094, 0xff00, 0x11f0, 0x2011, 0x1836, 0x2214,
- 0xd2ac, 0x11c8, 0x81ff, 0x01e8, 0x2011, 0x181e, 0x2204, 0x9106,
- 0x1190, 0x2011, 0x181f, 0x2214, 0x9294, 0xff00, 0x9584, 0xff00,
- 0x9206, 0x1148, 0x2011, 0x181f, 0x2214, 0x9294, 0x00ff, 0x9584,
- 0x00ff, 0x9206, 0x1120, 0x2500, 0x080c, 0x7e40, 0x0048, 0x9584,
- 0x00ff, 0x9080, 0x3209, 0x200d, 0x918c, 0xff00, 0x810f, 0x9006,
- 0x0005, 0x9080, 0x3209, 0x200d, 0x918c, 0x00ff, 0x0005, 0x00d6,
- 0x2069, 0x0140, 0x2001, 0x1817, 0x2003, 0x00ef, 0x20a9, 0x0010,
- 0x9006, 0x6852, 0x6856, 0x1f04, 0x26b2, 0x00de, 0x0005, 0x0006,
- 0x00d6, 0x0026, 0x2069, 0x0140, 0x2001, 0x1817, 0x2102, 0x8114,
- 0x8214, 0x8214, 0x8214, 0x20a9, 0x0010, 0x6853, 0x0000, 0x9006,
- 0x82ff, 0x1128, 0x9184, 0x000f, 0x9080, 0xe345, 0x2005, 0x6856,
- 0x8211, 0x1f04, 0x26c7, 0x002e, 0x00de, 0x000e, 0x0005, 0x00c6,
- 0x2061, 0x1800, 0x6030, 0x0110, 0xc09d, 0x0008, 0xc09c, 0x6032,
- 0x00ce, 0x0005, 0x0156, 0x00d6, 0x0026, 0x0016, 0x0006, 0x2069,
- 0x0140, 0x6980, 0x9116, 0x0180, 0x9112, 0x1230, 0x8212, 0x8210,
- 0x22a8, 0x2001, 0x0402, 0x0018, 0x22a8, 0x2001, 0x0404, 0x680e,
- 0x1f04, 0x26f7, 0x680f, 0x0000, 0x000e, 0x001e, 0x002e, 0x00de,
- 0x015e, 0x0005, 0x080c, 0x54dc, 0xd0c4, 0x0150, 0xd0a4, 0x0140,
- 0x9006, 0x0046, 0x2020, 0x2009, 0x002e, 0x080c, 0xd7d6, 0x004e,
- 0x0005, 0x00f6, 0x0016, 0x0026, 0x2079, 0x0140, 0x78c4, 0xd0dc,
- 0x0904, 0x276e, 0x080c, 0x29f6, 0x0660, 0x9084, 0x0700, 0x908e,
- 0x0600, 0x1120, 0x2011, 0x4000, 0x900e, 0x0458, 0x908e, 0x0500,
- 0x1120, 0x2011, 0x8000, 0x900e, 0x0420, 0x908e, 0x0400, 0x1120,
- 0x9016, 0x2009, 0x0001, 0x00e8, 0x908e, 0x0300, 0x1120, 0x9016,
- 0x2009, 0x0002, 0x00b0, 0x908e, 0x0200, 0x1120, 0x9016, 0x2009,
- 0x0004, 0x0078, 0x908e, 0x0100, 0x1548, 0x9016, 0x2009, 0x0008,
- 0x0040, 0x9084, 0x0700, 0x908e, 0x0300, 0x1500, 0x2011, 0x0030,
- 0x0058, 0x2300, 0x9080, 0x0020, 0x2018, 0x080c, 0x847f, 0x928c,
- 0xff00, 0x0110, 0x2011, 0x00ff, 0x2200, 0x8007, 0x9085, 0x004c,
- 0x78c2, 0x2009, 0x0138, 0x220a, 0x080c, 0x717f, 0x1118, 0x2009,
- 0x1947, 0x220a, 0x002e, 0x001e, 0x00fe, 0x0005, 0x78c3, 0x0000,
- 0x0cc8, 0x0126, 0x2091, 0x2800, 0x0006, 0x0016, 0x0026, 0x2001,
- 0x0170, 0x200c, 0x8000, 0x2014, 0x9184, 0x0003, 0x0110, 0x080c,
- 0x0dfb, 0x002e, 0x001e, 0x000e, 0x012e, 0x0005, 0x2001, 0x0171,
- 0x2004, 0xd0dc, 0x0168, 0x2001, 0x0170, 0x200c, 0x918c, 0x00ff,
- 0x918e, 0x004c, 0x1128, 0x200c, 0x918c, 0xff00, 0x810f, 0x0005,
- 0x900e, 0x2001, 0x0227, 0x2004, 0x8007, 0x9084, 0x00ff, 0x8004,
- 0x9108, 0x2001, 0x0226, 0x2004, 0x8007, 0x9084, 0x00ff, 0x8004,
- 0x9108, 0x0005, 0x0018, 0x000c, 0x0018, 0x0020, 0x1000, 0x0800,
- 0x1000, 0x1800, 0x0156, 0x0006, 0x0016, 0x0026, 0x00e6, 0x2001,
- 0x196a, 0x2004, 0x908a, 0x0007, 0x1a0c, 0x0e02, 0x0033, 0x00ee,
- 0x002e, 0x001e, 0x000e, 0x015e, 0x0005, 0x27cc, 0x27ea, 0x280e,
- 0x2810, 0x2839, 0x283b, 0x283d, 0x2001, 0x0001, 0x080c, 0x2617,
- 0x080c, 0x2a6a, 0x2001, 0x196c, 0x2003, 0x0000, 0x7828, 0x9084,
- 0xe1d7, 0x782a, 0x9006, 0x20a9, 0x0009, 0x080c, 0x2a12, 0x2001,
- 0x196a, 0x2003, 0x0006, 0x2009, 0x001e, 0x2011, 0x283e, 0x080c,
- 0x82ec, 0x0005, 0x2009, 0x196f, 0x200b, 0x0000, 0x2001, 0x1974,
- 0x2003, 0x0036, 0x2001, 0x1973, 0x2003, 0x002a, 0x2001, 0x196c,
- 0x2003, 0x0001, 0x9006, 0x080c, 0x299b, 0x2001, 0xffff, 0x20a9,
- 0x0009, 0x080c, 0x2a12, 0x2001, 0x196a, 0x2003, 0x0006, 0x2009,
- 0x001e, 0x2011, 0x283e, 0x080c, 0x82ec, 0x0005, 0x080c, 0x0e02,
- 0x2001, 0x1974, 0x2003, 0x0036, 0x2001, 0x196c, 0x2003, 0x0003,
- 0x7a38, 0x9294, 0x0005, 0x9296, 0x0004, 0x0110, 0x9006, 0x0010,
- 0x2001, 0x0001, 0x080c, 0x299b, 0x2001, 0x1970, 0x2003, 0x0000,
- 0x2001, 0xffff, 0x20a9, 0x0009, 0x080c, 0x2a12, 0x2001, 0x196a,
- 0x2003, 0x0006, 0x2009, 0x001e, 0x2011, 0x283e, 0x080c, 0x82ec,
- 0x0005, 0x080c, 0x0e02, 0x080c, 0x0e02, 0x0005, 0x0006, 0x0016,
- 0x0026, 0x00e6, 0x00f6, 0x0156, 0x0126, 0x2091, 0x8000, 0x2079,
- 0x0100, 0x2001, 0x196c, 0x2004, 0x908a, 0x0007, 0x1a0c, 0x0e02,
- 0x0043, 0x012e, 0x015e, 0x00fe, 0x00ee, 0x002e, 0x001e, 0x000e,
- 0x0005, 0x2860, 0x2880, 0x28c0, 0x28f0, 0x2914, 0x2924, 0x2926,
- 0x080c, 0x2a06, 0x11b0, 0x7850, 0x9084, 0xefff, 0x7852, 0x2009,
- 0x1972, 0x2104, 0x7a38, 0x9294, 0x0005, 0x9296, 0x0004, 0x0110,
- 0xc08d, 0x0008, 0xc085, 0x200a, 0x2001, 0x196a, 0x2003, 0x0001,
- 0x0030, 0x080c, 0x294a, 0x2001, 0xffff, 0x080c, 0x27db, 0x0005,
- 0x080c, 0x2928, 0x05e0, 0x2009, 0x1973, 0x2104, 0x8001, 0x200a,
- 0x080c, 0x2a06, 0x1178, 0x7850, 0x9084, 0xefff, 0x7852, 0x7a38,
- 0x9294, 0x0005, 0x9296, 0x0005, 0x0518, 0x2009, 0x1972, 0x2104,
- 0xc085, 0x200a, 0x2009, 0x196f, 0x2104, 0x8000, 0x200a, 0x9086,
- 0x0005, 0x0118, 0x080c, 0x2930, 0x00c0, 0x200b, 0x0000, 0x7a38,
- 0x9294, 0x0006, 0x9296, 0x0004, 0x0110, 0x9006, 0x0010, 0x2001,
- 0x0001, 0x080c, 0x29b8, 0x2001, 0x196c, 0x2003, 0x0002, 0x0028,
- 0x2001, 0x196a, 0x2003, 0x0003, 0x0010, 0x080c, 0x27fd, 0x0005,
- 0x080c, 0x2928, 0x0560, 0x2009, 0x1973, 0x2104, 0x8001, 0x200a,
- 0x080c, 0x2a06, 0x1168, 0x7850, 0x9084, 0xefff, 0x7852, 0x2001,
- 0x196a, 0x2003, 0x0003, 0x2001, 0x196b, 0x2003, 0x0000, 0x00b8,
- 0x2009, 0x1973, 0x2104, 0x9005, 0x1118, 0x080c, 0x296d, 0x0010,
- 0x080c, 0x293d, 0x080c, 0x2930, 0x2009, 0x196f, 0x200b, 0x0000,
- 0x2001, 0x196c, 0x2003, 0x0001, 0x080c, 0x27fd, 0x0000, 0x0005,
- 0x04b9, 0x0508, 0x080c, 0x2a06, 0x11b8, 0x7850, 0x9084, 0xefff,
- 0x7852, 0x2009, 0x1970, 0x2104, 0x8000, 0x200a, 0x9086, 0x0007,
- 0x0108, 0x0078, 0x2001, 0x1975, 0x2003, 0x000a, 0x2009, 0x1972,
- 0x2104, 0xc0fd, 0x200a, 0x0038, 0x0419, 0x2001, 0x196c, 0x2003,
- 0x0004, 0x080c, 0x2828, 0x0005, 0x0099, 0x0168, 0x080c, 0x2a06,
- 0x1138, 0x7850, 0x9084, 0xefff, 0x7852, 0x080c, 0x2814, 0x0018,
- 0x0079, 0x080c, 0x2828, 0x0005, 0x080c, 0x0e02, 0x080c, 0x0e02,
- 0x2009, 0x1974, 0x2104, 0x8001, 0x200a, 0x090c, 0x2989, 0x0005,
- 0x7a38, 0x9294, 0x0005, 0x9296, 0x0005, 0x0110, 0x9006, 0x0010,
- 0x2001, 0x0001, 0x080c, 0x29b8, 0x0005, 0x7a38, 0x9294, 0x0006,
- 0x9296, 0x0006, 0x0110, 0x9006, 0x0010, 0x2001, 0x0001, 0x080c,
- 0x299b, 0x0005, 0x2009, 0x196f, 0x2104, 0x8000, 0x200a, 0x9086,
- 0x0005, 0x0108, 0x0068, 0x200b, 0x0000, 0x7a38, 0x9294, 0x0006,
- 0x9296, 0x0006, 0x0110, 0x9006, 0x0010, 0x2001, 0x0001, 0x04d9,
- 0x7a38, 0x9294, 0x0005, 0x9296, 0x0005, 0x0110, 0x9006, 0x0010,
- 0x2001, 0x0001, 0x080c, 0x29b8, 0x0005, 0x0086, 0x2001, 0x1972,
- 0x2004, 0x9084, 0x7fff, 0x090c, 0x0e02, 0x2009, 0x1971, 0x2144,
- 0x8846, 0x280a, 0x9844, 0x0dd8, 0xd08c, 0x1120, 0xd084, 0x1120,
- 0x080c, 0x0e02, 0x9006, 0x0010, 0x2001, 0x0001, 0x00a1, 0x008e,
- 0x0005, 0x0006, 0x0156, 0x2001, 0x196a, 0x20a9, 0x0009, 0x2003,
- 0x0000, 0x8000, 0x1f04, 0x298f, 0x2001, 0x1971, 0x2003, 0x8000,
- 0x015e, 0x000e, 0x0005, 0x00f6, 0x2079, 0x0100, 0x9085, 0x0000,
- 0x0158, 0x7838, 0x9084, 0xfff9, 0x9085, 0x0004, 0x783a, 0x2009,
- 0x1977, 0x210c, 0x795a, 0x0050, 0x7838, 0x9084, 0xfffb, 0x9085,
- 0x0006, 0x783a, 0x2009, 0x1978, 0x210c, 0x795a, 0x00fe, 0x0005,
- 0x00f6, 0x2079, 0x0100, 0x9085, 0x0000, 0x0188, 0x7838, 0x9084,
- 0xfffa, 0x9085, 0x0004, 0x783a, 0x2001, 0x0100, 0x2004, 0x9086,
- 0x000a, 0x1120, 0x7850, 0x9084, 0xfff0, 0x7852, 0x0428, 0x7838,
- 0x9084, 0xfffb, 0x9085, 0x0005, 0x783a, 0x2001, 0x0100, 0x2004,
- 0x9086, 0x000a, 0x11c8, 0x7850, 0x9084, 0xfff0, 0x0016, 0x2009,
- 0x017f, 0x210c, 0x918e, 0x0005, 0x0140, 0x2009, 0x0003, 0x210c,
- 0x918c, 0x0600, 0x918e, 0x0400, 0x0118, 0x9085, 0x000a, 0x0010,
- 0x9085, 0x0000, 0x001e, 0x7852, 0x00fe, 0x0005, 0x0006, 0x2001,
- 0x0100, 0x2004, 0x9082, 0x0007, 0x000e, 0x0005, 0x0006, 0x2001,
- 0x0100, 0x2004, 0x9082, 0x0009, 0x000e, 0x0005, 0x0156, 0x20a9,
- 0x0064, 0x7820, 0x080c, 0x2ab0, 0xd09c, 0x1110, 0x1f04, 0x2a09,
- 0x015e, 0x0005, 0x0126, 0x0016, 0x0006, 0x2091, 0x8000, 0x2001,
- 0x0100, 0x2004, 0x9086, 0x000a, 0x0170, 0x7850, 0x9085, 0x0040,
- 0x7852, 0x7850, 0x9084, 0xfbcf, 0x7852, 0x080c, 0x2ab0, 0x9085,
- 0x2000, 0x7852, 0x0020, 0x080c, 0x2bc2, 0x080c, 0x2bf5, 0x000e,
- 0x2008, 0x9186, 0x0000, 0x1118, 0x783b, 0x0007, 0x0090, 0x9186,
- 0x0001, 0x1118, 0x783b, 0x0006, 0x0060, 0x9186, 0x0002, 0x1118,
- 0x783b, 0x0005, 0x0030, 0x9186, 0x0003, 0x1118, 0x783b, 0x0004,
- 0x0000, 0x0006, 0x1d04, 0x2a4a, 0x080c, 0x830e, 0x1f04, 0x2a4a,
- 0x2001, 0x0100, 0x2004, 0x9086, 0x000a, 0x0160, 0x7850, 0x9085,
- 0x0400, 0x9084, 0xdfbf, 0x7852, 0x080c, 0x2ab0, 0x9085, 0x1000,
- 0x7852, 0x0020, 0x7850, 0x9085, 0x1000, 0x7852, 0x000e, 0x001e,
- 0x012e, 0x0005, 0x2001, 0x0100, 0x2004, 0x9086, 0x000a, 0x0128,
- 0x7850, 0x9084, 0xffcf, 0x7852, 0x0010, 0x080c, 0x2bf5, 0x0005,
- 0x0006, 0x0156, 0x00f6, 0x2079, 0x0100, 0x20a9, 0x000a, 0x7854,
- 0xd0ac, 0x1130, 0x7820, 0xd0e4, 0x1140, 0x1f04, 0x2a82, 0x0028,
- 0x7854, 0xd08c, 0x1110, 0x1f04, 0x2a88, 0x00fe, 0x015e, 0x000e,
- 0x0005, 0x1d04, 0x2a91, 0x080c, 0x830e, 0x1f04, 0x2a91, 0x0005,
- 0x0006, 0x2001, 0x1976, 0x2004, 0x9086, 0x0000, 0x000e, 0x0005,
- 0x0006, 0x2001, 0x1976, 0x2004, 0x9086, 0x0001, 0x000e, 0x0005,
- 0x0006, 0x2001, 0x1976, 0x2004, 0x9086, 0x0002, 0x000e, 0x0005,
- 0xa001, 0xa001, 0xa001, 0xa001, 0xa001, 0x0005, 0x0006, 0x2001,
- 0x1982, 0x2102, 0x000e, 0x0005, 0x2009, 0x0171, 0x2104, 0xd0dc,
- 0x0140, 0x2009, 0x0170, 0x2104, 0x200b, 0x0080, 0xa001, 0xa001,
- 0x200a, 0x0005, 0x0036, 0x0046, 0x2001, 0x0141, 0x200c, 0x918c,
- 0xff00, 0x9186, 0x2100, 0x0140, 0x9186, 0x2000, 0x0170, 0x9186,
- 0x0100, 0x1904, 0x2b29, 0x0048, 0x0016, 0x2009, 0x1a58, 0x2104,
- 0x8000, 0x0208, 0x200a, 0x001e, 0x04f0, 0x2009, 0x00a2, 0x080c,
- 0x0e87, 0x2019, 0x0160, 0x2324, 0x2011, 0x0003, 0x2009, 0x0169,
- 0x2104, 0x9084, 0x0007, 0x210c, 0x918c, 0x0007, 0x910e, 0x1db0,
- 0x9086, 0x0003, 0x1548, 0x2304, 0x0066, 0x0076, 0x2031, 0x0002,
- 0x233c, 0x973e, 0x0148, 0x8631, 0x1dd8, 0x2031, 0x1a59, 0x263c,
- 0x8738, 0x0208, 0x2732, 0x2304, 0x007e, 0x006e, 0x9402, 0x02a0,
- 0x19d0, 0x8211, 0x19d8, 0x84ff, 0x0170, 0x2001, 0x0141, 0x200c,
- 0x918c, 0xff00, 0x9186, 0x0100, 0x0130, 0x2009, 0x180c, 0x2104,
- 0xc0dd, 0x200a, 0x0008, 0x0421, 0x2001, 0x195b, 0x200c, 0x080c,
- 0x0e87, 0x004e, 0x003e, 0x0005, 0x2001, 0x180c, 0x2004, 0xd0dc,
- 0x01b0, 0x2001, 0x0160, 0x2004, 0x9005, 0x0140, 0x2001, 0x0141,
- 0x2004, 0x9084, 0xff00, 0x9086, 0x0100, 0x1148, 0x0126, 0x2091,
- 0x8000, 0x0016, 0x0026, 0x0021, 0x002e, 0x001e, 0x012e, 0x0005,
- 0x00c6, 0x2061, 0x0100, 0x6014, 0x0006, 0x2001, 0x0161, 0x2003,
- 0x0000, 0x6017, 0x0018, 0xa001, 0xa001, 0x602f, 0x0008, 0x6104,
- 0x918e, 0x0010, 0x6106, 0x918e, 0x0010, 0x6106, 0x6017, 0x0040,
- 0x04b9, 0x001e, 0x9184, 0x0003, 0x01e0, 0x0036, 0x0016, 0x2019,
- 0x0141, 0x6124, 0x918c, 0x0028, 0x1120, 0x2304, 0x9084, 0x2800,
- 0x0dc0, 0x001e, 0x919c, 0xffe4, 0x9184, 0x0001, 0x0118, 0x9385,
- 0x0009, 0x6016, 0x9184, 0x0002, 0x0118, 0x9385, 0x0012, 0x6016,
- 0x003e, 0x2001, 0x180c, 0x200c, 0xc1dc, 0x2102, 0x00ce, 0x0005,
- 0x0016, 0x0026, 0x080c, 0x7199, 0x0108, 0xc0bc, 0x2009, 0x0140,
- 0x2114, 0x9294, 0x0001, 0x9215, 0x220a, 0x002e, 0x001e, 0x0005,
- 0x0016, 0x0026, 0x2009, 0x0140, 0x2114, 0x9294, 0x0001, 0x9285,
- 0x1000, 0x200a, 0x220a, 0x002e, 0x001e, 0x0005, 0x0016, 0x0026,
- 0x2009, 0x0140, 0x2114, 0x9294, 0x0001, 0x9215, 0x220a, 0x002e,
- 0x001e, 0x0005, 0x0006, 0x0016, 0x2009, 0x0140, 0x2104, 0x1128,
- 0x080c, 0x7199, 0x0110, 0xc0bc, 0x0008, 0xc0bd, 0x200a, 0x001e,
- 0x000e, 0x0005, 0x0016, 0x0026, 0x0036, 0x00c6, 0x2061, 0x0100,
- 0x6050, 0x9084, 0xfbff, 0x9085, 0x0040, 0x6052, 0x20a9, 0x0002,
- 0x080c, 0x2a91, 0x6050, 0x9085, 0x0400, 0x9084, 0xff9f, 0x6052,
- 0x20a9, 0x0005, 0x080c, 0x2a91, 0x6054, 0xd0bc, 0x090c, 0x0e02,
- 0x20a9, 0x0005, 0x080c, 0x2a91, 0x6054, 0xd0ac, 0x090c, 0x0e02,
- 0x2009, 0x1989, 0x9084, 0x7e00, 0x8007, 0x8004, 0x8004, 0x200a,
- 0x00ce, 0x003e, 0x002e, 0x001e, 0x0005, 0x0006, 0x00c6, 0x2061,
- 0x0100, 0x6050, 0xc0cd, 0x6052, 0x00ce, 0x000e, 0x0005, 0x0006,
- 0x0156, 0x6050, 0x9085, 0x0040, 0x6052, 0x6050, 0x9084, 0xfbcf,
- 0x6052, 0x080c, 0x2ab0, 0x9085, 0x2000, 0x6052, 0x20a9, 0x0012,
- 0x1d04, 0x2c10, 0x080c, 0x830e, 0x1f04, 0x2c10, 0x6050, 0x9085,
- 0x0400, 0x9084, 0xdfbf, 0x6052, 0x015e, 0x000e, 0x0005, 0x2e8b,
- 0x2e8b, 0x2caf, 0x2caf, 0x2cbb, 0x2cbb, 0x2cc7, 0x2cc7, 0x2cd5,
- 0x2cd5, 0x2ce1, 0x2ce1, 0x2cef, 0x2cef, 0x2cfd, 0x2cfd, 0x2d0f,
- 0x2d0f, 0x2d1b, 0x2d1b, 0x2d29, 0x2d29, 0x2d47, 0x2d47, 0x2d67,
- 0x2d67, 0x2d37, 0x2d37, 0x2d57, 0x2d57, 0x2d75, 0x2d75, 0x2d0d,
- 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d,
- 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d,
- 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d,
- 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d87,
- 0x2d87, 0x2d93, 0x2d93, 0x2da1, 0x2da1, 0x2daf, 0x2daf, 0x2dbf,
- 0x2dbf, 0x2dcd, 0x2dcd, 0x2ddd, 0x2ddd, 0x2ded, 0x2ded, 0x2dff,
- 0x2dff, 0x2e0d, 0x2e0d, 0x2e1d, 0x2e1d, 0x2e3f, 0x2e3f, 0x2e61,
- 0x2e61, 0x2e2d, 0x2e2d, 0x2e50, 0x2e50, 0x2e70, 0x2e70, 0x2d0d,
- 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d,
- 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d,
- 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d,
- 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d,
- 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d,
- 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x0106,
- 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c,
- 0x22c0, 0x0804, 0x2e83, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6,
- 0x0136, 0x0146, 0x0156, 0x080c, 0x20c7, 0x0804, 0x2e83, 0x0106,
- 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c,
- 0x20c7, 0x080c, 0x22c0, 0x0804, 0x2e83, 0x0106, 0x0006, 0x0126,
- 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2102, 0x0804,
- 0x2e83, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146,
- 0x0156, 0x080c, 0x22c0, 0x080c, 0x2102, 0x0804, 0x2e83, 0x0106,
- 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c,
- 0x20c7, 0x080c, 0x2102, 0x0804, 0x2e83, 0x0106, 0x0006, 0x0126,
- 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x20c7, 0x080c,
- 0x22c0, 0x080c, 0x2102, 0x0804, 0x2e83, 0xa001, 0x0cf0, 0x0106,
- 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c,
- 0x1371, 0x0804, 0x2e83, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6,
- 0x0136, 0x0146, 0x0156, 0x080c, 0x22c0, 0x080c, 0x1371, 0x0804,
- 0x2e83, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146,
- 0x0156, 0x080c, 0x20c7, 0x080c, 0x1371, 0x0804, 0x2e83, 0x0106,
- 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c,
- 0x22c0, 0x080c, 0x1371, 0x080c, 0x2102, 0x0804, 0x2e83, 0x0106,
- 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c,
- 0x20c7, 0x080c, 0x22c0, 0x080c, 0x1371, 0x0804, 0x2e83, 0x0106,
- 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c,
- 0x20c7, 0x080c, 0x1371, 0x080c, 0x2102, 0x0804, 0x2e83, 0x0106,
- 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c,
- 0x1371, 0x080c, 0x2102, 0x0804, 0x2e83, 0x0106, 0x0006, 0x0126,
- 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x20c7, 0x080c,
- 0x22c0, 0x080c, 0x1371, 0x080c, 0x2102, 0x0804, 0x2e83, 0x0106,
- 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c,
- 0x2771, 0x0804, 0x2e83, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6,
- 0x0136, 0x0146, 0x0156, 0x080c, 0x2771, 0x080c, 0x22c0, 0x0804,
- 0x2e83, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146,
- 0x0156, 0x080c, 0x2771, 0x080c, 0x20c7, 0x0804, 0x2e83, 0x0106,
- 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c,
- 0x2771, 0x080c, 0x20c7, 0x080c, 0x22c0, 0x0804, 0x2e83, 0x0106,
- 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c,
- 0x2771, 0x080c, 0x2102, 0x0804, 0x2e83, 0x0106, 0x0006, 0x0126,
- 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2771, 0x080c,
- 0x22c0, 0x080c, 0x2102, 0x0804, 0x2e83, 0x0106, 0x0006, 0x0126,
- 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2771, 0x080c,
- 0x20c7, 0x080c, 0x2102, 0x0804, 0x2e83, 0x0106, 0x0006, 0x0126,
- 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2771, 0x080c,
- 0x20c7, 0x080c, 0x22c0, 0x080c, 0x2102, 0x0804, 0x2e83, 0x0106,
- 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c,
- 0x2771, 0x080c, 0x1371, 0x0804, 0x2e83, 0x0106, 0x0006, 0x0126,
- 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2771, 0x080c,
- 0x22c0, 0x080c, 0x1371, 0x0804, 0x2e83, 0x0106, 0x0006, 0x0126,
- 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2771, 0x080c,
- 0x20c7, 0x080c, 0x1371, 0x0804, 0x2e83, 0x0106, 0x0006, 0x0126,
- 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2771, 0x080c,
- 0x22c0, 0x080c, 0x1371, 0x080c, 0x2102, 0x0804, 0x2e83, 0x0106,
- 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c,
- 0x2771, 0x080c, 0x20c7, 0x080c, 0x22c0, 0x080c, 0x1371, 0x0498,
+ 0xfbcf, 0x7852, 0x080c, 0x2a97, 0x9085, 0x2000, 0x7852, 0x793a,
+ 0x20a9, 0x0046, 0x1d04, 0x0c62, 0x080c, 0x830d, 0x1f04, 0x0c62,
+ 0x7850, 0x9085, 0x0400, 0x9084, 0xdfbf, 0x7852, 0x793a, 0x0040,
+ 0x20a9, 0x003a, 0x1d04, 0x0c72, 0x080c, 0x830d, 0x1f04, 0x0c72,
+ 0x080c, 0x718f, 0x0148, 0x080c, 0x71a1, 0x1118, 0x080c, 0x7489,
+ 0x0050, 0x080c, 0x7186, 0x0dd0, 0x080c, 0x7484, 0x080c, 0x747a,
+ 0x080c, 0x709e, 0x0020, 0x2009, 0x00f8, 0x080c, 0x5dab, 0x2001,
+ 0x0100, 0x2004, 0x9086, 0x000a, 0x0168, 0x20a9, 0x0028, 0xa001,
+ 0x1f04, 0x0c97, 0x7850, 0x9085, 0x1400, 0x7852, 0x080c, 0x717e,
+ 0x0158, 0x0030, 0x7850, 0xc0e5, 0x7852, 0x080c, 0x717e, 0x0120,
+ 0x7843, 0x0090, 0x7843, 0x0010, 0x2021, 0xe678, 0x2019, 0xea60,
+ 0x0d0c, 0x830d, 0x7820, 0xd09c, 0x1590, 0x080c, 0x717e, 0x0904,
+ 0x0d13, 0x7824, 0xd0ac, 0x1904, 0x0d34, 0x080c, 0x71a1, 0x1538,
+ 0x0046, 0x2021, 0x0320, 0x8421, 0x1df0, 0x004e, 0x7827, 0x1800,
+ 0x080c, 0x2a97, 0x7824, 0x9084, 0x1800, 0x1168, 0x9484, 0x0fff,
+ 0x1140, 0x2001, 0x1810, 0x2004, 0x9084, 0x9000, 0x0110, 0x080c,
+ 0x0d64, 0x8421, 0x1160, 0x1d04, 0x0cdf, 0x080c, 0x830d, 0x080c,
+ 0x7484, 0x080c, 0x747a, 0x7003, 0x0001, 0x0804, 0x0d34, 0x8319,
+ 0x1938, 0x2001, 0x0100, 0x2004, 0x9086, 0x000a, 0x1140, 0x2001,
+ 0x1810, 0x2004, 0x9084, 0x9000, 0x0110, 0x080c, 0x0d64, 0x1d04,
+ 0x0cfb, 0x080c, 0x830d, 0x2009, 0x1975, 0x2104, 0x9005, 0x0118,
+ 0x8001, 0x200a, 0x1178, 0x200b, 0x000a, 0x7827, 0x0048, 0x20a9,
+ 0x0002, 0x080c, 0x2a78, 0x7924, 0x080c, 0x2a97, 0xd19c, 0x0110,
+ 0x080c, 0x2974, 0x00e0, 0x080c, 0x718f, 0x1140, 0x94a2, 0x03e8,
+ 0x1128, 0x080c, 0x7156, 0x7003, 0x0001, 0x00b0, 0x7827, 0x1800,
+ 0x080c, 0x2a97, 0x7824, 0x080c, 0x7198, 0x0110, 0xd0ac, 0x1160,
+ 0x9084, 0x1800, 0x0904, 0x0ce7, 0x7003, 0x0001, 0x0028, 0x2001,
+ 0x0001, 0x080c, 0x2616, 0x00c0, 0x2001, 0x0100, 0x2004, 0x9086,
+ 0x000a, 0x1118, 0x7850, 0xc0e4, 0x7852, 0x2009, 0x180c, 0x210c,
+ 0xd19c, 0x1120, 0x7904, 0x918d, 0x0002, 0x7906, 0x7827, 0x0048,
+ 0x7828, 0x9085, 0x0028, 0x782a, 0x2001, 0x0100, 0x2004, 0x9086,
+ 0x000a, 0x0120, 0x7850, 0x9085, 0x0400, 0x7852, 0x2001, 0x1982,
+ 0x2003, 0x0000, 0x9006, 0x78f2, 0x015e, 0x003e, 0x000e, 0x012e,
+ 0x00fe, 0x004e, 0x001e, 0x0005, 0x0006, 0x0016, 0x0036, 0x0046,
+ 0x00b6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x0156, 0x0069, 0x0d0c,
+ 0x830d, 0x015e, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x00be, 0x004e,
+ 0x003e, 0x001e, 0x000e, 0x0005, 0x00e6, 0x2071, 0x189c, 0x7004,
+ 0x9086, 0x0001, 0x1110, 0x080c, 0x331a, 0x00ee, 0x0005, 0x0005,
+ 0x2a70, 0x2061, 0x1986, 0x2063, 0x0003, 0x6007, 0x0003, 0x600b,
+ 0x0012, 0x600f, 0x0317, 0x2001, 0x1956, 0x900e, 0x2102, 0x7192,
+ 0x2001, 0x0100, 0x2004, 0x9082, 0x0002, 0x0218, 0x705b, 0xffff,
+ 0x0008, 0x715a, 0x7063, 0xffff, 0x717a, 0x717e, 0x080c, 0xc1a1,
+ 0x70e7, 0x00c0, 0x2061, 0x1946, 0x6003, 0x0909, 0x6106, 0x600b,
+ 0x8800, 0x600f, 0x0200, 0x6013, 0x00ff, 0x6017, 0x000f, 0x611a,
+ 0x601f, 0x07d0, 0x2061, 0x194e, 0x6003, 0x8000, 0x6106, 0x610a,
+ 0x600f, 0x0200, 0x6013, 0x00ff, 0x6116, 0x601b, 0x0001, 0x611e,
+ 0x2061, 0x1963, 0x6003, 0x514c, 0x6007, 0x4f47, 0x600b, 0x4943,
+ 0x600f, 0x2020, 0x2001, 0x182b, 0x2102, 0x0005, 0x9016, 0x080c,
+ 0x63a3, 0x1178, 0xb804, 0x90c4, 0x00ff, 0x98c6, 0x0006, 0x0128,
+ 0x90c4, 0xff00, 0x98c6, 0x0600, 0x1120, 0x9186, 0x0080, 0x0108,
+ 0x8210, 0x8108, 0x9186, 0x0800, 0x1d50, 0x2208, 0x0005, 0x2091,
+ 0x8000, 0x2079, 0x0000, 0x000e, 0x00f6, 0x0010, 0x2091, 0x8000,
+ 0x0e04, 0x0df8, 0x0006, 0x0016, 0x2001, 0x8002, 0x0006, 0x2079,
+ 0x0000, 0x000e, 0x7882, 0x7836, 0x001e, 0x798e, 0x000e, 0x788a,
+ 0x000e, 0x7886, 0x3900, 0x789a, 0x00d6, 0x2069, 0x0300, 0x6818,
+ 0x78ae, 0x681c, 0x78b2, 0x6808, 0x78be, 0x00de, 0x7833, 0x0012,
+ 0x2091, 0x5000, 0x0156, 0x00d6, 0x0036, 0x0026, 0x2079, 0x0300,
+ 0x2069, 0x1a7a, 0x7a08, 0x226a, 0x2069, 0x1a7b, 0x7a18, 0x226a,
+ 0x8d68, 0x7a1c, 0x226a, 0x782c, 0x2019, 0x1a88, 0x201a, 0x2019,
+ 0x1a8b, 0x9016, 0x7808, 0xd09c, 0x0168, 0x7820, 0x201a, 0x8210,
+ 0x8318, 0x9386, 0x1aa0, 0x0108, 0x0ca8, 0x7808, 0xd09c, 0x0110,
+ 0x2011, 0xdead, 0x2019, 0x1a89, 0x782c, 0x201a, 0x8318, 0x221a,
+ 0x7803, 0x0000, 0x2069, 0x1a5a, 0x901e, 0x20a9, 0x0020, 0x7b26,
+ 0x7a28, 0x226a, 0x8d68, 0x8318, 0x1f04, 0x0e4f, 0x002e, 0x003e,
+ 0x00de, 0x015e, 0x2079, 0x1800, 0x7803, 0x0005, 0x2091, 0x4080,
+ 0x2001, 0x0089, 0x2004, 0xd084, 0x0180, 0x2001, 0x19f6, 0x2004,
+ 0x9005, 0x0128, 0x2001, 0x008b, 0x2004, 0xd0fc, 0x0dd8, 0x2001,
+ 0x008a, 0x2003, 0x0002, 0x2003, 0x1001, 0x080c, 0x54ea, 0x1108,
+ 0x0099, 0x0cd8, 0x0005, 0x918c, 0x03ff, 0x2001, 0x0003, 0x2004,
+ 0x9084, 0x0600, 0x1118, 0x918d, 0x6c00, 0x0010, 0x918d, 0x6400,
+ 0x2001, 0x017f, 0x2102, 0x0005, 0x0026, 0x0126, 0x2011, 0x0080,
+ 0x080c, 0x0f17, 0x20a9, 0x0900, 0x080c, 0x0f38, 0x2011, 0x0040,
+ 0x080c, 0x0f17, 0x20a9, 0x0900, 0x080c, 0x0f38, 0x0c78, 0x0026,
+ 0x080c, 0x0f24, 0x1118, 0x2011, 0x0040, 0x0098, 0x2011, 0x010e,
+ 0x2214, 0x9294, 0x0007, 0x9296, 0x0007, 0x0118, 0x2011, 0xa880,
+ 0x0010, 0x2011, 0x6840, 0xd0e4, 0x70eb, 0x0000, 0x1120, 0x70eb,
+ 0x0fa0, 0x080c, 0x0f29, 0x002e, 0x0005, 0x0026, 0x080c, 0x0f24,
+ 0x0128, 0xd0a4, 0x1138, 0x2011, 0xcdd5, 0x0010, 0x2011, 0x0080,
+ 0x080c, 0x0f29, 0x002e, 0x0005, 0x0026, 0x70eb, 0x0000, 0x080c,
+ 0x0f24, 0x1148, 0x080c, 0x2a8f, 0x1118, 0x2011, 0x8484, 0x0058,
+ 0x2011, 0x8282, 0x0040, 0x080c, 0x2a8f, 0x1118, 0x2011, 0xcdc5,
+ 0x0010, 0x2011, 0xcac2, 0x080c, 0x0f29, 0x002e, 0x0005, 0x00e6,
+ 0x0006, 0x2071, 0x1800, 0xd0b4, 0x70e4, 0x1110, 0xc0e4, 0x0048,
+ 0x0006, 0x3b00, 0x9084, 0xff3f, 0x20d8, 0x000e, 0x70eb, 0x0000,
+ 0xc0e5, 0x0079, 0x000e, 0x00ee, 0x0005, 0x00e6, 0x2071, 0x1800,
+ 0xd0e4, 0x70e4, 0x1110, 0xc0dc, 0x0008, 0xc0dd, 0x0011, 0x00ee,
+ 0x0005, 0x70e6, 0x7000, 0x9084, 0x0007, 0x000b, 0x0005, 0x0ee6,
+ 0x0ebd, 0x0ebd, 0x0e9f, 0x0ecc, 0x0ebd, 0x0ebd, 0x0ecc, 0x0016,
+ 0x3b08, 0x3a00, 0x9104, 0x918d, 0x00c0, 0x21d8, 0x9084, 0xff3f,
+ 0x9205, 0x20d0, 0x001e, 0x0005, 0x2001, 0x1839, 0x2004, 0xd0dc,
+ 0x0005, 0x9e86, 0x1800, 0x190c, 0x0df6, 0x70e4, 0xd0e4, 0x0108,
+ 0xc2e5, 0x72e6, 0xd0e4, 0x1118, 0x9294, 0x00c0, 0x0c01, 0x0005,
+ 0x1d04, 0x0f38, 0x2091, 0x6000, 0x1f04, 0x0f38, 0x0005, 0x890e,
+ 0x810e, 0x810f, 0x9194, 0x003f, 0x918c, 0xffc0, 0x0005, 0x0006,
+ 0x2200, 0x914d, 0x894f, 0x894d, 0x894d, 0x000e, 0x0005, 0x01d6,
+ 0x0146, 0x0036, 0x0096, 0x2061, 0x188b, 0x600b, 0x0000, 0x600f,
+ 0x0000, 0x6003, 0x0000, 0x6007, 0x0000, 0x2009, 0xffc0, 0x2105,
+ 0x0006, 0x2001, 0xaaaa, 0x200f, 0x2019, 0x5555, 0x9016, 0x2049,
+ 0x0bff, 0xab02, 0xa001, 0xa001, 0xa800, 0x9306, 0x1138, 0x2105,
+ 0x9306, 0x0120, 0x8210, 0x99c8, 0x0400, 0x0c98, 0x000e, 0x200f,
+ 0x2001, 0x189b, 0x928a, 0x000e, 0x1638, 0x928a, 0x0006, 0x2011,
+ 0x0006, 0x1210, 0x2011, 0x0000, 0x2202, 0x9006, 0x2008, 0x82ff,
+ 0x01b0, 0x8200, 0x600a, 0x600f, 0xffff, 0x6003, 0x0002, 0x6007,
+ 0x0000, 0x0026, 0x2019, 0x0010, 0x9280, 0x0001, 0x20e8, 0x21a0,
+ 0x21a8, 0x4104, 0x8319, 0x1de0, 0x8211, 0x1da0, 0x002e, 0x009e,
+ 0x003e, 0x014e, 0x01de, 0x0005, 0x2011, 0x000e, 0x08e8, 0x0016,
+ 0x0026, 0x0096, 0x3348, 0x080c, 0x0f3f, 0x2100, 0x9300, 0x2098,
+ 0x22e0, 0x009e, 0x002e, 0x001e, 0x0036, 0x3518, 0x20a9, 0x0001,
+ 0x4002, 0x8007, 0x4004, 0x8319, 0x1dd8, 0x003e, 0x0005, 0x20e9,
+ 0x0001, 0x71b4, 0x81ff, 0x11c0, 0x9006, 0x2009, 0x0200, 0x20a9,
+ 0x0002, 0x9298, 0x0018, 0x23a0, 0x4001, 0x2009, 0x0700, 0x20a9,
+ 0x0002, 0x9298, 0x0008, 0x23a0, 0x4001, 0x7078, 0x8007, 0x717c,
+ 0x810f, 0x20a9, 0x0002, 0x4001, 0x9298, 0x000c, 0x23a0, 0x900e,
+ 0x080c, 0x0dd6, 0x2001, 0x0000, 0x810f, 0x20a9, 0x0002, 0x4001,
+ 0x0005, 0x89ff, 0x0140, 0xa804, 0xa807, 0x0000, 0x0006, 0x080c,
+ 0x1069, 0x009e, 0x0cb0, 0x0005, 0x00e6, 0x2071, 0x1800, 0x080c,
+ 0x10e2, 0x090c, 0x0df6, 0x00ee, 0x0005, 0x0086, 0x00e6, 0x0006,
+ 0x0026, 0x0036, 0x0126, 0x2091, 0x8000, 0x00c9, 0x2071, 0x1800,
+ 0x73bc, 0x702c, 0x9016, 0x9045, 0x0158, 0x8210, 0x9906, 0x090c,
+ 0x0df6, 0x2300, 0x9202, 0x0120, 0x1a0c, 0x0df6, 0xa000, 0x0c98,
+ 0x012e, 0x003e, 0x002e, 0x000e, 0x00ee, 0x008e, 0x0005, 0x0086,
+ 0x00e6, 0x0006, 0x0126, 0x2091, 0x8000, 0x2071, 0x190e, 0x7010,
+ 0x9005, 0x0140, 0x7018, 0x9045, 0x0128, 0x9906, 0x090c, 0x0df6,
+ 0xa000, 0x0cc8, 0x012e, 0x000e, 0x00ee, 0x008e, 0x0005, 0x00e6,
+ 0x2071, 0x1800, 0x0126, 0x2091, 0x8000, 0x70bc, 0x8001, 0x0270,
+ 0x70be, 0x702c, 0x2048, 0x9085, 0x0001, 0xa800, 0x702e, 0xa803,
+ 0x0000, 0xa807, 0x0000, 0x012e, 0x00ee, 0x0005, 0x904e, 0x0cd8,
+ 0x00e6, 0x0126, 0x2091, 0x8000, 0x2071, 0x1800, 0x70bc, 0x90ca,
+ 0x0040, 0x0268, 0x8001, 0x70be, 0x702c, 0x2048, 0xa800, 0x702e,
+ 0xa803, 0x0000, 0xa807, 0x0000, 0x012e, 0x00ee, 0x0005, 0x904e,
+ 0x0cd8, 0x00e6, 0x0126, 0x2091, 0x8000, 0x0016, 0x890e, 0x810e,
+ 0x810f, 0x9184, 0x003f, 0xa862, 0x9184, 0xffc0, 0xa85e, 0x001e,
+ 0x0020, 0x00e6, 0x0126, 0x2091, 0x8000, 0x2071, 0x1800, 0x702c,
+ 0xa802, 0x2900, 0x702e, 0x70bc, 0x8000, 0x70be, 0x080c, 0x816f,
+ 0x012e, 0x00ee, 0x0005, 0x2071, 0x1800, 0x9026, 0x2009, 0x0000,
+ 0x2049, 0x0400, 0x2900, 0x702e, 0x8940, 0x2800, 0xa802, 0xa95e,
+ 0xa863, 0x0001, 0x8420, 0x9886, 0x0440, 0x0120, 0x2848, 0x9188,
+ 0x0040, 0x0c90, 0x2071, 0x188b, 0x7000, 0x9005, 0x11a0, 0x2001,
+ 0x0492, 0xa802, 0x2048, 0x2009, 0x2480, 0x8940, 0x2800, 0xa802,
+ 0xa95e, 0xa863, 0x0001, 0x8420, 0x9886, 0x0800, 0x0120, 0x2848,
+ 0x9188, 0x0040, 0x0c90, 0x2071, 0x188b, 0x7104, 0x7200, 0x82ff,
+ 0x01d0, 0x7308, 0x8318, 0x831f, 0x831b, 0x831b, 0x7312, 0x8319,
+ 0x2001, 0x0800, 0xa802, 0x2048, 0x8900, 0xa802, 0x2040, 0xa95e,
+ 0xaa62, 0x8420, 0x2300, 0x9906, 0x0130, 0x2848, 0x9188, 0x0040,
+ 0x9291, 0x0000, 0x0c88, 0xa803, 0x0000, 0x2071, 0x1800, 0x74ba,
+ 0x74be, 0x0005, 0x00e6, 0x0016, 0x9984, 0xfc00, 0x01e8, 0x908c,
+ 0xf800, 0x1168, 0x9982, 0x0400, 0x02b8, 0x9982, 0x0440, 0x0278,
+ 0x9982, 0x0492, 0x0288, 0x9982, 0x0800, 0x1270, 0x0040, 0x9982,
+ 0x0800, 0x0250, 0x2071, 0x188b, 0x7010, 0x9902, 0x1228, 0x9085,
+ 0x0001, 0x001e, 0x00ee, 0x0005, 0x9006, 0x0cd8, 0x00e6, 0x2071,
+ 0x19f5, 0x7007, 0x0000, 0x9006, 0x701e, 0x7022, 0x7002, 0x2071,
+ 0x0000, 0x7010, 0x9085, 0x8044, 0x7012, 0x2071, 0x0080, 0x9006,
+ 0x0006, 0x2001, 0x0100, 0x2004, 0x9086, 0x000a, 0x000e, 0x1158,
+ 0x702b, 0x0060, 0x20a9, 0x0040, 0x7022, 0x1f04, 0x1124, 0x702b,
+ 0x0060, 0x702b, 0x0020, 0x20a9, 0x0040, 0x7022, 0x1f04, 0x112d,
+ 0x702b, 0x0020, 0x00ee, 0x0005, 0x0126, 0x2091, 0x8000, 0x00e6,
+ 0xa06f, 0x0000, 0x2071, 0x19f5, 0x701c, 0x9088, 0x19ff, 0x280a,
+ 0x8000, 0x9084, 0x003f, 0x701e, 0x7120, 0x9106, 0x090c, 0x0df6,
+ 0x7004, 0x9005, 0x1128, 0x00f6, 0x2079, 0x0080, 0x00a9, 0x00fe,
+ 0x00ee, 0x012e, 0x0005, 0x0126, 0x2091, 0x8000, 0x00e6, 0x2071,
+ 0x19f5, 0x7004, 0x9005, 0x1128, 0x00f6, 0x2079, 0x0080, 0x0021,
+ 0x00fe, 0x00ee, 0x012e, 0x0005, 0x7004, 0x9086, 0x0000, 0x1110,
+ 0x7007, 0x0006, 0x7000, 0x0002, 0x1176, 0x1174, 0x1174, 0x1174,
+ 0x12ed, 0x12ed, 0x12ed, 0x12ed, 0x080c, 0x0df6, 0x701c, 0x7120,
+ 0x9106, 0x1148, 0x792c, 0x9184, 0x0001, 0x1120, 0xd1fc, 0x1110,
+ 0x7007, 0x0000, 0x0005, 0x0096, 0x9180, 0x19ff, 0x2004, 0x700a,
+ 0x2048, 0x8108, 0x918c, 0x003f, 0x7122, 0x782b, 0x0026, 0xa88c,
+ 0x7802, 0xa890, 0x7806, 0xa894, 0x780a, 0xa898, 0x780e, 0xa878,
+ 0x700e, 0xa870, 0x7016, 0xa874, 0x701a, 0xa868, 0x009e, 0xd084,
+ 0x0120, 0x7007, 0x0001, 0x0029, 0x0005, 0x7007, 0x0002, 0x00b1,
+ 0x0005, 0x0016, 0x0026, 0x710c, 0x2011, 0x0040, 0x9182, 0x0040,
+ 0x1210, 0x2110, 0x9006, 0x700e, 0x7212, 0x8203, 0x7812, 0x782b,
+ 0x0020, 0x782b, 0x0041, 0x002e, 0x001e, 0x0005, 0x0016, 0x0026,
+ 0x0136, 0x0146, 0x0156, 0x7014, 0x20e0, 0x7018, 0x2098, 0x20e9,
+ 0x0000, 0x20a1, 0x0088, 0x782b, 0x0026, 0x710c, 0x2011, 0x0040,
+ 0x9182, 0x0040, 0x1210, 0x2110, 0x9006, 0x700e, 0x22a8, 0x4006,
+ 0x8203, 0x7812, 0x782b, 0x0020, 0x3300, 0x701a, 0x782b, 0x0001,
+ 0x015e, 0x014e, 0x013e, 0x002e, 0x001e, 0x0005, 0x2009, 0x19f5,
+ 0x2104, 0xc095, 0x200a, 0x080c, 0x1153, 0x0005, 0x0016, 0x00e6,
+ 0x2071, 0x19f5, 0x00f6, 0x2079, 0x0080, 0x792c, 0xd1bc, 0x190c,
+ 0x0def, 0x782b, 0x0002, 0xd1fc, 0x0120, 0x918c, 0x0700, 0x7004,
+ 0x0023, 0x00fe, 0x00ee, 0x001e, 0x0005, 0x1164, 0x120c, 0x1240,
+ 0x0df6, 0x0df6, 0x12f9, 0x0df6, 0x918c, 0x0700, 0x1550, 0x0136,
+ 0x0146, 0x0156, 0x7014, 0x20e8, 0x7018, 0x20a0, 0x20e1, 0x0000,
+ 0x2099, 0x0088, 0x782b, 0x0040, 0x7010, 0x20a8, 0x4005, 0x3400,
+ 0x701a, 0x015e, 0x014e, 0x013e, 0x700c, 0x9005, 0x0578, 0x7800,
+ 0x7802, 0x7804, 0x7806, 0x080c, 0x11a9, 0x0005, 0x7008, 0x0096,
+ 0x2048, 0xa86f, 0x0100, 0x009e, 0x7007, 0x0000, 0x080c, 0x1164,
+ 0x0005, 0x7008, 0x0096, 0x2048, 0xa86f, 0x0200, 0x009e, 0x0ca0,
+ 0x918c, 0x0700, 0x1150, 0x700c, 0x9005, 0x0180, 0x7800, 0x7802,
+ 0x7804, 0x7806, 0x080c, 0x11be, 0x0005, 0x7008, 0x0096, 0x2048,
+ 0xa86f, 0x0200, 0x009e, 0x7007, 0x0000, 0x0080, 0x0096, 0x7008,
+ 0x2048, 0x7800, 0xa88e, 0x7804, 0xa892, 0x7808, 0xa896, 0x780c,
+ 0xa89a, 0xa86f, 0x0100, 0x009e, 0x7007, 0x0000, 0x0096, 0x00d6,
+ 0x7008, 0x2048, 0x2001, 0x18b7, 0x2004, 0x9906, 0x1128, 0xa89c,
+ 0x080f, 0x00de, 0x009e, 0x00a0, 0x00de, 0x009e, 0x0096, 0x00d6,
+ 0x7008, 0x2048, 0x0081, 0x0150, 0xa89c, 0x0086, 0x2940, 0x080f,
+ 0x008e, 0x00de, 0x009e, 0x080c, 0x1153, 0x0005, 0x00de, 0x009e,
+ 0x080c, 0x1153, 0x0005, 0xa8a8, 0xd08c, 0x0005, 0x0096, 0xa0a0,
+ 0x904d, 0x090c, 0x0df6, 0xa06c, 0x908e, 0x0100, 0x0130, 0xa87b,
+ 0x0030, 0xa883, 0x0000, 0xa897, 0x4002, 0x080c, 0x6a15, 0xa09f,
+ 0x0000, 0xa0a3, 0x0000, 0x2848, 0x080c, 0x1069, 0x009e, 0x0005,
+ 0x00a6, 0xa0a0, 0x904d, 0x090c, 0x0df6, 0xa06c, 0x908e, 0x0100,
+ 0x0128, 0xa87b, 0x0001, 0xa883, 0x0000, 0x00c0, 0xa80c, 0x2050,
+ 0xb004, 0x9005, 0x0198, 0xa80e, 0x2050, 0x8006, 0x8006, 0x8007,
+ 0x908c, 0x003f, 0x9084, 0xffc0, 0x9080, 0x0002, 0xa076, 0xa172,
+ 0xb000, 0xa07a, 0x2810, 0x080c, 0x1134, 0x00e8, 0xa97c, 0xa894,
+ 0x0016, 0x0006, 0x080c, 0x6a15, 0x000e, 0x001e, 0xd1fc, 0x1138,
+ 0xd1f4, 0x0128, 0x00c6, 0x2060, 0x080c, 0x9fea, 0x00ce, 0x7008,
+ 0x2048, 0xa89f, 0x0000, 0xa8a3, 0x0000, 0x080c, 0x1069, 0x7007,
+ 0x0000, 0x080c, 0x1153, 0x00ae, 0x0005, 0x0126, 0x2091, 0x8000,
+ 0x782b, 0x1001, 0x7007, 0x0005, 0x7000, 0xc094, 0x7002, 0x012e,
+ 0x0005, 0x7007, 0x0000, 0x080c, 0x1164, 0x0005, 0x0126, 0x2091,
+ 0x2200, 0x2079, 0x0300, 0x2071, 0x1a3f, 0x7003, 0x0000, 0x78bf,
+ 0x00f6, 0x0419, 0x7803, 0x0003, 0x780f, 0x0000, 0x2001, 0x0100,
+ 0x2004, 0x9086, 0x000a, 0x0128, 0x20a9, 0x01e8, 0x2061, 0xdc0a,
+ 0x0020, 0x20a9, 0x01e8, 0x2061, 0xdfd8, 0x2c0d, 0x7912, 0xe104,
+ 0x9ce0, 0x0002, 0x7916, 0x1f04, 0x131d, 0x7807, 0x0007, 0x7803,
+ 0x0000, 0x7803, 0x0001, 0x012e, 0x0005, 0x00c6, 0x7803, 0x0000,
+ 0x7808, 0xd09c, 0x0110, 0x7820, 0x0cd8, 0x2001, 0x1a40, 0x2003,
+ 0x0000, 0x78ab, 0x0004, 0x78ac, 0xd0ac, 0x1de8, 0x78ab, 0x0002,
+ 0x7807, 0x0007, 0x7827, 0x0030, 0x782b, 0x0400, 0x7827, 0x0031,
+ 0x782b, 0x1a5a, 0x781f, 0xff00, 0x781b, 0xff00, 0x2001, 0x0200,
+ 0x2004, 0xd0dc, 0x0110, 0x781f, 0x0303, 0x2061, 0x1a5a, 0x602f,
+ 0x1cd0, 0x2001, 0x1819, 0x2004, 0x9082, 0x1cd0, 0x6032, 0x603b,
+ 0x1ebe, 0x783f, 0x31f3, 0x00ce, 0x0005, 0x0126, 0x2091, 0x2200,
+ 0x7908, 0x9184, 0x0070, 0x190c, 0x0def, 0xd19c, 0x0158, 0x7820,
+ 0x908c, 0xf000, 0x15e8, 0x908a, 0x0024, 0x1a0c, 0x0df6, 0x0023,
+ 0x012e, 0x0005, 0x012e, 0x0005, 0x13a0, 0x13a0, 0x13b7, 0x13bc,
+ 0x13c0, 0x13c5, 0x13ed, 0x13f1, 0x13ff, 0x1403, 0x13a0, 0x148f,
+ 0x1493, 0x1503, 0x13a0, 0x13a0, 0x13a0, 0x13a0, 0x13a0, 0x13a0,
+ 0x13a0, 0x13a0, 0x13a0, 0x13a0, 0x13a0, 0x13a0, 0x13a0, 0x13c7,
+ 0x13a0, 0x13a0, 0x13a0, 0x13a0, 0x13a0, 0x13a0, 0x13a4, 0x13a2,
+ 0x080c, 0x0df6, 0x080c, 0x0def, 0x080c, 0x150a, 0x2009, 0x1a56,
+ 0x2104, 0x8000, 0x200a, 0x080c, 0x7bec, 0x080c, 0x1977, 0x0005,
+ 0x2009, 0x0048, 0x2060, 0x080c, 0xa068, 0x012e, 0x0005, 0x7004,
+ 0xc085, 0xc0b5, 0x7006, 0x0005, 0x7004, 0xc085, 0x7006, 0x0005,
+ 0x080c, 0x150a, 0x080c, 0x15e4, 0x0005, 0x080c, 0x0df6, 0x080c,
+ 0x150a, 0x2060, 0x6014, 0x0096, 0x2048, 0xa83b, 0xffff, 0x009e,
+ 0x2009, 0x0048, 0x080c, 0xa068, 0x2001, 0x015d, 0x2003, 0x0000,
+ 0x2009, 0x03e8, 0x8109, 0x0160, 0x2001, 0x0201, 0x2004, 0x9005,
+ 0x0dc8, 0x2001, 0x0218, 0x2004, 0xd0ec, 0x1110, 0x080c, 0x150f,
+ 0x2001, 0x0307, 0x2003, 0x8000, 0x0005, 0x7004, 0xc095, 0x7006,
+ 0x0005, 0x080c, 0x150a, 0x2060, 0x6014, 0x0096, 0x2048, 0xa83b,
+ 0xffff, 0x009e, 0x2009, 0x0048, 0x080c, 0xa068, 0x0005, 0x080c,
+ 0x150a, 0x080c, 0x0df6, 0x080c, 0x150a, 0x080c, 0x147a, 0x7827,
+ 0x0018, 0x79ac, 0xd1dc, 0x0540, 0x7827, 0x0015, 0x7828, 0x782b,
+ 0x0000, 0x9065, 0x0138, 0x2001, 0x020d, 0x2003, 0x0050, 0x2003,
+ 0x0020, 0x0400, 0x7004, 0x9005, 0x1180, 0x78ab, 0x0004, 0x7827,
+ 0x0018, 0x782b, 0x0000, 0xd1bc, 0x090c, 0x0df6, 0x2001, 0x020d,
+ 0x2003, 0x0050, 0x2003, 0x0020, 0x0490, 0x78ab, 0x0004, 0x7803,
+ 0x0001, 0x080c, 0x1493, 0x0005, 0x7828, 0x782b, 0x0000, 0x9065,
+ 0x090c, 0x0df6, 0x6014, 0x2048, 0x78ab, 0x0004, 0x918c, 0x0700,
+ 0x01a8, 0x080c, 0x7bec, 0x080c, 0x1977, 0x080c, 0xbd4e, 0x0158,
+ 0xa9ac, 0xa936, 0xa9b0, 0xa93a, 0xa83f, 0xffff, 0xa843, 0xffff,
+ 0xa880, 0xc0bd, 0xa882, 0x080c, 0xb983, 0x0005, 0x6010, 0x00b6,
+ 0x2058, 0xb800, 0x00be, 0xd0bc, 0x6024, 0x190c, 0xc13a, 0x2029,
+ 0x00c8, 0x8529, 0x0128, 0x2001, 0x0201, 0x2004, 0x9005, 0x0dc8,
+ 0x7dbc, 0x080c, 0xdbb3, 0xd5a4, 0x1118, 0x080c, 0x150f, 0x0005,
+ 0x080c, 0x7bec, 0x080c, 0x1977, 0x0005, 0x781f, 0x0300, 0x7803,
+ 0x0001, 0x0005, 0x0016, 0x0066, 0x0076, 0x00f6, 0x2079, 0x0300,
+ 0x7908, 0x918c, 0x0007, 0x9186, 0x0003, 0x0120, 0x2001, 0x0016,
+ 0x080c, 0x1580, 0x00fe, 0x007e, 0x006e, 0x001e, 0x0005, 0x7004,
+ 0xc09d, 0x7006, 0x0005, 0x7104, 0x9184, 0x0004, 0x190c, 0x0df6,
+ 0xd184, 0x11b1, 0xd19c, 0x0180, 0xc19c, 0x7106, 0x0016, 0x080c,
+ 0x15c7, 0x001e, 0x0148, 0x2001, 0x020d, 0x2003, 0x0050, 0x2003,
+ 0x0020, 0x080c, 0x150f, 0x0005, 0x81ff, 0x190c, 0x0df6, 0x0005,
+ 0x2100, 0xc184, 0xc1b4, 0x7106, 0xd0b4, 0x0016, 0x00e6, 0x1904,
+ 0x14f8, 0x2071, 0x0200, 0x080c, 0x15bb, 0x080c, 0x15c7, 0x05a8,
+ 0x6014, 0x9005, 0x05a8, 0x0096, 0x2048, 0xa864, 0x009e, 0x9084,
+ 0x00ff, 0x908e, 0x0029, 0x0160, 0x908e, 0x0048, 0x1548, 0x601c,
+ 0xd084, 0x11d8, 0x00f6, 0x2c78, 0x080c, 0x1651, 0x00fe, 0x00a8,
+ 0x00f6, 0x2c78, 0x080c, 0x179b, 0x00fe, 0x2009, 0x01f4, 0x8109,
+ 0x0160, 0x2001, 0x0201, 0x2004, 0x9005, 0x0dc8, 0x2001, 0x0218,
+ 0x2004, 0xd0ec, 0x1110, 0x0419, 0x0040, 0x2001, 0x020d, 0x2003,
+ 0x0020, 0x080c, 0x132d, 0x7803, 0x0001, 0x00ee, 0x001e, 0x0005,
+ 0x080c, 0x15c7, 0x0dd0, 0x2001, 0x020d, 0x2003, 0x0050, 0x2003,
+ 0x0020, 0x0069, 0x0c90, 0x0031, 0x2060, 0x2009, 0x0053, 0x080c,
+ 0xa068, 0x0005, 0x7808, 0xd09c, 0x0de8, 0x7820, 0x0005, 0x080c,
+ 0x147a, 0x00d6, 0x2069, 0x0200, 0x2009, 0x01f4, 0x8109, 0x0510,
+ 0x6804, 0x9005, 0x0dd8, 0x2001, 0x015d, 0x2003, 0x0000, 0x79bc,
+ 0xd1a4, 0x1528, 0x79b8, 0x918c, 0x0fff, 0x0180, 0x9182, 0x0841,
+ 0x1268, 0x9188, 0x0007, 0x918c, 0x0ff8, 0x810c, 0x810c, 0x810c,
+ 0x080c, 0x1572, 0x6827, 0x0001, 0x8109, 0x1dd0, 0x04d9, 0x6827,
+ 0x0002, 0x04c1, 0x6804, 0x9005, 0x1130, 0x682c, 0xd0e4, 0x1500,
+ 0x6804, 0x9005, 0x0de8, 0x79b8, 0xd1ec, 0x1130, 0x08c0, 0x080c,
+ 0x7bec, 0x080c, 0x1977, 0x0090, 0x7827, 0x0015, 0x782b, 0x0000,
+ 0x7827, 0x0018, 0x782b, 0x0000, 0x2001, 0x020d, 0x2003, 0x0020,
+ 0x2001, 0x0307, 0x2003, 0x0300, 0x7803, 0x0001, 0x00de, 0x0005,
+ 0x682c, 0x9084, 0x5400, 0x9086, 0x5400, 0x0d30, 0x7827, 0x0015,
+ 0x782b, 0x0000, 0x7803, 0x0001, 0x6800, 0x9085, 0x1800, 0x6802,
+ 0x00de, 0x0005, 0x6824, 0x9084, 0x0003, 0x1de0, 0x0005, 0x2001,
+ 0x0030, 0x2c08, 0x621c, 0x0021, 0x7830, 0x9086, 0x0041, 0x0005,
+ 0x00f6, 0x2079, 0x0300, 0x0006, 0x7808, 0xd09c, 0x0140, 0x0016,
+ 0x0026, 0x00c6, 0x080c, 0x1365, 0x00ce, 0x002e, 0x001e, 0x000e,
+ 0x0006, 0x7832, 0x7936, 0x7a3a, 0x781b, 0x8080, 0x0059, 0x1118,
+ 0x000e, 0x00fe, 0x0005, 0x000e, 0x792c, 0x3900, 0x8000, 0x2004,
+ 0x080c, 0x0df6, 0x2009, 0xff00, 0x8109, 0x0120, 0x7818, 0xd0bc,
+ 0x1dd8, 0x0005, 0x9085, 0x0001, 0x0005, 0x7832, 0x7936, 0x7a3a,
+ 0x781b, 0x8080, 0x0c79, 0x1108, 0x0005, 0x792c, 0x3900, 0x8000,
+ 0x2004, 0x080c, 0x0df6, 0x7037, 0x0001, 0x7150, 0x7037, 0x0002,
+ 0x7050, 0x2060, 0xd1bc, 0x1110, 0x7054, 0x2060, 0x0005, 0x0006,
+ 0x0046, 0x00e6, 0x2071, 0x0200, 0x7037, 0x0002, 0x7058, 0x9084,
+ 0xff00, 0x8007, 0x9086, 0x00bc, 0x1158, 0x2021, 0x1a57, 0x2404,
+ 0x8000, 0x0208, 0x2022, 0x080c, 0x7bec, 0x080c, 0x1977, 0x9006,
+ 0x00ee, 0x004e, 0x000e, 0x0005, 0x0c11, 0x1108, 0x0005, 0x00e6,
+ 0x0016, 0x2071, 0x0200, 0x0879, 0x6124, 0xd1dc, 0x01f8, 0x701c,
+ 0xd08c, 0x0904, 0x1646, 0x7017, 0x0000, 0x2001, 0x0264, 0x2004,
+ 0xd0bc, 0x0904, 0x1646, 0x2001, 0x0268, 0x00c6, 0x2064, 0x6104,
+ 0x6038, 0x00ce, 0x918e, 0x0039, 0x1904, 0x1646, 0x9c06, 0x15f0,
+ 0x0126, 0x2091, 0x2600, 0x080c, 0x7b33, 0x012e, 0x7358, 0x745c,
+ 0x6014, 0x905d, 0x0598, 0x2b48, 0x6010, 0x00b6, 0x2058, 0xb800,
+ 0x00be, 0xd0bc, 0x190c, 0xc115, 0xab42, 0xac3e, 0x2001, 0x187d,
+ 0x2004, 0xd0b4, 0x1170, 0x601c, 0xd0e4, 0x1158, 0x6010, 0x00b6,
+ 0x2058, 0xb800, 0x00be, 0xd0bc, 0x1120, 0xa83b, 0x7fff, 0xa837,
+ 0xffff, 0x080c, 0x1ede, 0x1190, 0x080c, 0x17f8, 0x2a00, 0xa816,
+ 0x0130, 0x2800, 0xa80e, 0x2c05, 0xa80a, 0x2c00, 0xa812, 0x7037,
+ 0x0020, 0x781f, 0x0300, 0x001e, 0x00ee, 0x0005, 0x7037, 0x0050,
+ 0x7037, 0x0020, 0x001e, 0x00ee, 0x080c, 0x150f, 0x0005, 0x080c,
+ 0x0df6, 0x0016, 0x2009, 0x00a0, 0x8109, 0xa001, 0xa001, 0xa001,
+ 0x1dd8, 0x001e, 0x2ff0, 0x0126, 0x2091, 0x2200, 0x0016, 0x00c6,
+ 0x3e60, 0x6014, 0x2048, 0x2940, 0x903e, 0x2730, 0xa864, 0x2068,
+ 0xa81a, 0x9d84, 0x000f, 0x9088, 0x1ebe, 0x2165, 0x0002, 0x1686,
+ 0x16d3, 0x1686, 0x1686, 0x1686, 0x16b5, 0x1686, 0x168a, 0x167f,
+ 0x16ca, 0x1686, 0x1686, 0x1686, 0x1790, 0x169e, 0x1694, 0xa964,
+ 0x918c, 0x00ff, 0x918e, 0x0048, 0x0904, 0x16ca, 0x9085, 0x0001,
+ 0x0804, 0x1786, 0xa87c, 0xd0bc, 0x0dc8, 0xa890, 0xa842, 0xa88c,
+ 0xa83e, 0xa888, 0x0804, 0x16da, 0xa87c, 0xd0bc, 0x0d78, 0xa890,
+ 0xa842, 0xa88c, 0xa83e, 0xa888, 0x0804, 0x1729, 0xa87c, 0xd0bc,
+ 0x0d28, 0xa890, 0xa842, 0xa88c, 0xa83e, 0xa804, 0x9045, 0x090c,
+ 0x0df6, 0xa164, 0xa91a, 0x91ec, 0x000f, 0x9d80, 0x1ebe, 0x2065,
+ 0xa888, 0xd19c, 0x1904, 0x1729, 0x0428, 0xa87c, 0xd0ac, 0x0970,
+ 0xa804, 0x9045, 0x090c, 0x0df6, 0xa164, 0xa91a, 0x91ec, 0x000f,
+ 0x9d80, 0x1ebe, 0x2065, 0x9006, 0xa842, 0xa83e, 0xd19c, 0x1904,
+ 0x1729, 0x0080, 0xa87c, 0xd0ac, 0x0904, 0x1686, 0x9006, 0xa842,
+ 0xa83e, 0x0804, 0x1729, 0xa87c, 0xd0ac, 0x0904, 0x1686, 0x9006,
+ 0xa842, 0xa83e, 0x2c05, 0x908a, 0x0036, 0x1a0c, 0x0df6, 0x9082,
+ 0x001b, 0x0002, 0x16fd, 0x16fd, 0x16ff, 0x16fd, 0x16fd, 0x16fd,
+ 0x1705, 0x16fd, 0x16fd, 0x16fd, 0x170b, 0x16fd, 0x16fd, 0x16fd,
+ 0x1711, 0x16fd, 0x16fd, 0x16fd, 0x1717, 0x16fd, 0x16fd, 0x16fd,
+ 0x171d, 0x16fd, 0x16fd, 0x16fd, 0x1723, 0x080c, 0x0df6, 0xa574,
+ 0xa478, 0xa37c, 0xa280, 0x0804, 0x176e, 0xa584, 0xa488, 0xa38c,
+ 0xa290, 0x0804, 0x176e, 0xa594, 0xa498, 0xa39c, 0xa2a0, 0x0804,
+ 0x176e, 0xa5a4, 0xa4a8, 0xa3ac, 0xa2b0, 0x0804, 0x176e, 0xa5b4,
+ 0xa4b8, 0xa3bc, 0xa2c0, 0x0804, 0x176e, 0xa5c4, 0xa4c8, 0xa3cc,
+ 0xa2d0, 0x0804, 0x176e, 0xa5d4, 0xa4d8, 0xa3dc, 0xa2e0, 0x0804,
+ 0x176e, 0x2c05, 0x908a, 0x0034, 0x1a0c, 0x0df6, 0x9082, 0x001b,
+ 0x0002, 0x174c, 0x174a, 0x174a, 0x174a, 0x174a, 0x174a, 0x1753,
+ 0x174a, 0x174a, 0x174a, 0x174a, 0x174a, 0x175a, 0x174a, 0x174a,
+ 0x174a, 0x174a, 0x174a, 0x1761, 0x174a, 0x174a, 0x174a, 0x174a,
+ 0x174a, 0x1768, 0x080c, 0x0df6, 0xa56c, 0xa470, 0xa774, 0xa678,
+ 0xa37c, 0xa280, 0x00d8, 0xa584, 0xa488, 0xa78c, 0xa690, 0xa394,
+ 0xa298, 0x00a0, 0xa59c, 0xa4a0, 0xa7a4, 0xa6a8, 0xa3ac, 0xa2b0,
+ 0x0068, 0xa5b4, 0xa4b8, 0xa7bc, 0xa6c0, 0xa3c4, 0xa2c8, 0x0030,
+ 0xa5cc, 0xa4d0, 0xa7d4, 0xa6d8, 0xa3dc, 0xa2e0, 0xab2e, 0xaa32,
+ 0xad1e, 0xac22, 0xaf26, 0xae2a, 0xa988, 0x8c60, 0x2c1d, 0xa8ac,
+ 0xaab0, 0xa836, 0xaa3a, 0x8109, 0xa916, 0x1160, 0x3e60, 0x601c,
+ 0xc085, 0x601e, 0xa87c, 0xc0dd, 0xa87e, 0x9006, 0x00ce, 0x001e,
+ 0x012e, 0x0005, 0x2800, 0xa80e, 0xab0a, 0x2c00, 0xa812, 0x0c70,
+ 0x0804, 0x1686, 0x0016, 0x2009, 0x00a0, 0x8109, 0xa001, 0xa001,
+ 0xa001, 0x1dd8, 0x001e, 0x2ff0, 0x0126, 0x2091, 0x2200, 0x0016,
+ 0x00c6, 0x3e60, 0x6014, 0x2048, 0x2940, 0xa80e, 0x2061, 0x1eb9,
+ 0xa813, 0x1eb9, 0x2c05, 0xa80a, 0xa964, 0xa91a, 0xa87c, 0xd0ac,
+ 0x090c, 0x0df6, 0x9006, 0xa842, 0xa83e, 0x2c05, 0x908a, 0x0034,
+ 0x1a0c, 0x0df6, 0xadcc, 0xacd0, 0xafd4, 0xaed8, 0xabdc, 0xaae0,
+ 0xab2e, 0xaa32, 0xad1e, 0xac22, 0xaf26, 0xae2a, 0xa8ac, 0xaab0,
+ 0xa836, 0xaa3a, 0xa988, 0xa864, 0x9084, 0x00ff, 0x9086, 0x0008,
+ 0x1120, 0x8109, 0xa916, 0x0128, 0x0080, 0x918a, 0x0002, 0xa916,
+ 0x1160, 0x3e60, 0x601c, 0xc085, 0x601e, 0xa87c, 0xc0dd, 0xa87e,
+ 0x9006, 0x00ce, 0x001e, 0x012e, 0x0005, 0xa804, 0x9045, 0x090c,
+ 0x0df6, 0xa80e, 0xa064, 0xa81a, 0x9084, 0x000f, 0x9080, 0x1ebe,
+ 0x2015, 0x82ff, 0x090c, 0x0df6, 0xaa12, 0x2205, 0xa80a, 0x0c08,
+ 0x903e, 0x2730, 0xa880, 0xd0fc, 0x1190, 0x2d00, 0x0002, 0x18ed,
+ 0x184f, 0x184f, 0x18ed, 0x18ed, 0x18e7, 0x18ed, 0x184f, 0x189e,
+ 0x189e, 0x189e, 0x18ed, 0x18ed, 0x18ed, 0x18e4, 0x189e, 0xc0fc,
+ 0xa882, 0xab2c, 0xaa30, 0xad1c, 0xac20, 0xdd9c, 0x0904, 0x18ef,
+ 0x2c05, 0x908a, 0x0034, 0x1a0c, 0x0df6, 0x9082, 0x001b, 0x0002,
+ 0x183b, 0x1839, 0x1839, 0x1839, 0x1839, 0x1839, 0x183f, 0x1839,
+ 0x1839, 0x1839, 0x1839, 0x1839, 0x1843, 0x1839, 0x1839, 0x1839,
+ 0x1839, 0x1839, 0x1847, 0x1839, 0x1839, 0x1839, 0x1839, 0x1839,
+ 0x184b, 0x080c, 0x0df6, 0xa774, 0xa678, 0x0804, 0x18ef, 0xa78c,
+ 0xa690, 0x0804, 0x18ef, 0xa7a4, 0xa6a8, 0x0804, 0x18ef, 0xa7bc,
+ 0xa6c0, 0x0804, 0x18ef, 0xa7d4, 0xa6d8, 0x0804, 0x18ef, 0x2c05,
+ 0x908a, 0x0036, 0x1a0c, 0x0df6, 0x9082, 0x001b, 0x0002, 0x1872,
+ 0x1872, 0x1874, 0x1872, 0x1872, 0x1872, 0x187a, 0x1872, 0x1872,
+ 0x1872, 0x1880, 0x1872, 0x1872, 0x1872, 0x1886, 0x1872, 0x1872,
+ 0x1872, 0x188c, 0x1872, 0x1872, 0x1872, 0x1892, 0x1872, 0x1872,
+ 0x1872, 0x1898, 0x080c, 0x0df6, 0xa574, 0xa478, 0xa37c, 0xa280,
+ 0x0804, 0x18ef, 0xa584, 0xa488, 0xa38c, 0xa290, 0x0804, 0x18ef,
+ 0xa594, 0xa498, 0xa39c, 0xa2a0, 0x0804, 0x18ef, 0xa5a4, 0xa4a8,
+ 0xa3ac, 0xa2b0, 0x0804, 0x18ef, 0xa5b4, 0xa4b8, 0xa3bc, 0xa2c0,
+ 0x0804, 0x18ef, 0xa5c4, 0xa4c8, 0xa3cc, 0xa2d0, 0x0804, 0x18ef,
+ 0xa5d4, 0xa4d8, 0xa3dc, 0xa2e0, 0x0804, 0x18ef, 0x2c05, 0x908a,
+ 0x0034, 0x1a0c, 0x0df6, 0x9082, 0x001b, 0x0002, 0x18c1, 0x18bf,
+ 0x18bf, 0x18bf, 0x18bf, 0x18bf, 0x18c8, 0x18bf, 0x18bf, 0x18bf,
+ 0x18bf, 0x18bf, 0x18cf, 0x18bf, 0x18bf, 0x18bf, 0x18bf, 0x18bf,
+ 0x18d6, 0x18bf, 0x18bf, 0x18bf, 0x18bf, 0x18bf, 0x18dd, 0x080c,
+ 0x0df6, 0xa56c, 0xa470, 0xa774, 0xa678, 0xa37c, 0xa280, 0x0438,
+ 0xa584, 0xa488, 0xa78c, 0xa690, 0xa394, 0xa298, 0x0400, 0xa59c,
+ 0xa4a0, 0xa7a4, 0xa6a8, 0xa3ac, 0xa2b0, 0x00c8, 0xa5b4, 0xa4b8,
+ 0xa7bc, 0xa6c0, 0xa3c4, 0xa2c8, 0x0090, 0xa5cc, 0xa4d0, 0xa7d4,
+ 0xa6d8, 0xa3dc, 0xa2e0, 0x0058, 0x9d86, 0x000e, 0x1130, 0x080c,
+ 0x1e7c, 0x1904, 0x17f8, 0x900e, 0x0050, 0x080c, 0x0df6, 0xab2e,
+ 0xaa32, 0xad1e, 0xac22, 0xaf26, 0xae2a, 0x080c, 0x1e7c, 0x0005,
+ 0x6014, 0x2048, 0x6118, 0x81ff, 0x0148, 0x810c, 0x810c, 0x810c,
+ 0x81ff, 0x1118, 0xa887, 0x0001, 0x0008, 0xa986, 0x601b, 0x0002,
+ 0xa874, 0x9084, 0x00ff, 0x9084, 0x0008, 0x0150, 0x00e9, 0x6000,
+ 0x9086, 0x0004, 0x1120, 0x2009, 0x0048, 0x080c, 0xa068, 0x0005,
+ 0xa974, 0xd1dc, 0x1108, 0x0005, 0xa934, 0xa88c, 0x9106, 0x1158,
+ 0xa938, 0xa890, 0x9106, 0x1138, 0x601c, 0xc084, 0x601e, 0x2009,
+ 0x0048, 0x0804, 0xa068, 0x0005, 0x0126, 0x00c6, 0x2091, 0x2200,
+ 0x00ce, 0x7908, 0x918c, 0x0007, 0x9186, 0x0000, 0x05b0, 0x9186,
+ 0x0003, 0x0598, 0x6020, 0x6023, 0x0000, 0x0006, 0x2031, 0x0008,
+ 0x00c6, 0x781f, 0x0808, 0x7808, 0xd09c, 0x0120, 0x080c, 0x1365,
+ 0x8631, 0x1db8, 0x00ce, 0x781f, 0x0800, 0x2031, 0x0168, 0x00c6,
+ 0x7808, 0xd09c, 0x190c, 0x1365, 0x00ce, 0x2001, 0x0038, 0x080c,
+ 0x1a07, 0x7930, 0x9186, 0x0040, 0x0160, 0x9186, 0x0042, 0x190c,
+ 0x0df6, 0x2001, 0x001e, 0x8001, 0x1df0, 0x8631, 0x1d40, 0x080c,
+ 0x1a16, 0x000e, 0x6022, 0x012e, 0x0005, 0x080c, 0x1a03, 0x7827,
+ 0x0015, 0x7828, 0x9c06, 0x1db8, 0x782b, 0x0000, 0x0ca0, 0x00f6,
+ 0x2079, 0x0300, 0x7803, 0x0000, 0x78ab, 0x0004, 0x2001, 0xf000,
+ 0x8001, 0x090c, 0x0df6, 0x7aac, 0xd2ac, 0x1dd0, 0x00fe, 0x080c,
+ 0x717e, 0x1188, 0x2001, 0x0138, 0x2003, 0x0000, 0x2001, 0x0160,
+ 0x2003, 0x0000, 0x2011, 0x012c, 0xa001, 0xa001, 0x8211, 0x1de0,
+ 0x0059, 0x0804, 0x7246, 0x0479, 0x0039, 0x2001, 0x0160, 0x2502,
+ 0x2001, 0x0138, 0x2202, 0x0005, 0x00e6, 0x2071, 0x0200, 0x080c,
+ 0x2aa3, 0x2009, 0x003c, 0x080c, 0x2200, 0x2001, 0x015d, 0x2003,
+ 0x0000, 0x7000, 0x9084, 0x003c, 0x1de0, 0x080c, 0x816f, 0x70a0,
+ 0x70a2, 0x7098, 0x709a, 0x709c, 0x709e, 0x2001, 0x020d, 0x2003,
+ 0x0020, 0x00f6, 0x2079, 0x0300, 0x080c, 0x132d, 0x7803, 0x0001,
+ 0x00fe, 0x00ee, 0x0005, 0x2001, 0x0138, 0x2014, 0x2003, 0x0000,
+ 0x2001, 0x0160, 0x202c, 0x2003, 0x0000, 0x080c, 0x717e, 0x1108,
+ 0x0005, 0x2021, 0x0260, 0x2001, 0x0141, 0x201c, 0xd3dc, 0x1168,
+ 0x2001, 0x0109, 0x201c, 0x939c, 0x0048, 0x1160, 0x2001, 0x0111,
+ 0x201c, 0x83ff, 0x1110, 0x8421, 0x1d70, 0x2001, 0x015d, 0x2003,
+ 0x0000, 0x0005, 0x0046, 0x2021, 0x0019, 0x2003, 0x0048, 0xa001,
+ 0xa001, 0x201c, 0x939c, 0x0048, 0x0120, 0x8421, 0x1db0, 0x004e,
+ 0x0c60, 0x004e, 0x0c40, 0x601c, 0xc084, 0x601e, 0x0005, 0x2c08,
+ 0x621c, 0x080c, 0x1580, 0x7930, 0x0005, 0x2c08, 0x621c, 0x080c,
+ 0x15ad, 0x7930, 0x0005, 0x8001, 0x1df0, 0x0005, 0x2031, 0x0064,
+ 0x781c, 0x9084, 0x0007, 0x0170, 0x2001, 0x0038, 0x0c41, 0x9186,
+ 0x0040, 0x0904, 0x1a74, 0x2001, 0x001e, 0x0c69, 0x8631, 0x1d80,
+ 0x080c, 0x0df6, 0x781f, 0x0202, 0x2001, 0x015d, 0x2003, 0x0000,
+ 0x2001, 0x0dac, 0x0c01, 0x781c, 0xd084, 0x0110, 0x0861, 0x04e0,
+ 0x2001, 0x0030, 0x0891, 0x9186, 0x0040, 0x0568, 0x781c, 0xd084,
+ 0x1da8, 0x781f, 0x0101, 0x2001, 0x0014, 0x0869, 0x2001, 0x0037,
+ 0x0821, 0x9186, 0x0040, 0x0140, 0x2001, 0x0030, 0x080c, 0x1a0d,
+ 0x9186, 0x0040, 0x190c, 0x0df6, 0x00d6, 0x2069, 0x0200, 0x692c,
+ 0xd1f4, 0x1170, 0xd1c4, 0x0160, 0xd19c, 0x0130, 0x6800, 0x9085,
+ 0x1800, 0x6802, 0x00de, 0x0080, 0x6908, 0x9184, 0x0007, 0x1db0,
+ 0x00de, 0x781f, 0x0100, 0x791c, 0x9184, 0x0007, 0x090c, 0x0df6,
+ 0xa001, 0xa001, 0x781f, 0x0200, 0x0005, 0x0126, 0x2091, 0x2400,
+ 0x2071, 0x1a42, 0x2079, 0x0090, 0x012e, 0x0005, 0x9280, 0x0005,
+ 0x2004, 0x2048, 0xa97c, 0xd1dc, 0x1904, 0x1b09, 0xa964, 0x9184,
+ 0x0007, 0x0002, 0x1a92, 0x1af4, 0x1aa9, 0x1aa9, 0x1aa9, 0x1adc,
+ 0x1abc, 0x1aab, 0x918c, 0x00ff, 0x9186, 0x0008, 0x1170, 0xa87c,
+ 0xd0b4, 0x0904, 0x1cbf, 0x9006, 0xa842, 0xa83e, 0xa988, 0x2900,
+ 0xa85a, 0xa813, 0x1eb9, 0x0804, 0x1b05, 0x9186, 0x0048, 0x0904,
+ 0x1af4, 0x080c, 0x0df6, 0xa87c, 0xd0b4, 0x0904, 0x1cbf, 0xa890,
+ 0xa842, 0xa83a, 0xa88c, 0xa83e, 0xa836, 0xa8ac, 0xa846, 0xa8b0,
+ 0xa84a, 0xa988, 0x0804, 0x1afc, 0xa864, 0x9084, 0x00ff, 0x9086,
+ 0x001e, 0x1d38, 0xa87c, 0xd0b4, 0x0904, 0x1cbf, 0xa890, 0xa842,
+ 0xa83a, 0xa88c, 0xa83e, 0xa836, 0xa8ac, 0xa846, 0xa8b0, 0xa84a,
+ 0xa804, 0xa85a, 0x2040, 0xa064, 0x9084, 0x000f, 0x9080, 0x1ebe,
+ 0x2005, 0xa812, 0xa988, 0x0448, 0x918c, 0x00ff, 0x9186, 0x0015,
+ 0x1540, 0xa87c, 0xd0b4, 0x0904, 0x1cbf, 0xa804, 0xa85a, 0x2040,
+ 0xa064, 0x9084, 0x000f, 0x9080, 0x1ebe, 0x2005, 0xa812, 0xa988,
+ 0x9006, 0xa842, 0xa83e, 0x0088, 0xa87c, 0xd0b4, 0x0904, 0x1cbf,
+ 0xa988, 0x9006, 0xa842, 0xa83e, 0x2900, 0xa85a, 0xa864, 0x9084,
+ 0x000f, 0x9080, 0x1ebe, 0x2005, 0xa812, 0xa916, 0xa87c, 0xc0dd,
+ 0xa87e, 0x0005, 0x00f6, 0x2079, 0x0090, 0x782c, 0xd0fc, 0x190c,
+ 0x1d00, 0x00e6, 0x2071, 0x1a42, 0x7000, 0x9005, 0x1904, 0x1b61,
+ 0x7206, 0x9280, 0x0005, 0x204c, 0x9280, 0x0004, 0x2004, 0x782b,
+ 0x0004, 0x00f6, 0x2079, 0x0200, 0x7803, 0x0040, 0x00fe, 0x00b6,
+ 0x2058, 0xb86c, 0x7836, 0xb890, 0x00be, 0x00f6, 0x2079, 0x0200,
+ 0x7803, 0x0040, 0xa001, 0xa001, 0xa001, 0xa001, 0xa001, 0xa001,
+ 0x781a, 0x78d7, 0x0000, 0x00fe, 0xa814, 0x2050, 0xa858, 0x2040,
+ 0xa810, 0x2060, 0xa064, 0x90ec, 0x000f, 0xa944, 0x791a, 0x7116,
+ 0xa848, 0x781e, 0x701a, 0x9006, 0x700e, 0x7012, 0x7004, 0xa940,
+ 0xa838, 0x9106, 0x1188, 0xa93c, 0xa834, 0x9106, 0x1168, 0x8aff,
+ 0x01a8, 0x0126, 0x2091, 0x8000, 0x00a1, 0x0108, 0x0091, 0x012e,
+ 0x9006, 0x00ee, 0x00fe, 0x0005, 0x0036, 0x0046, 0xab38, 0xac34,
+ 0x080c, 0x1ede, 0x004e, 0x003e, 0x0d50, 0x0c98, 0x9085, 0x0001,
+ 0x0c80, 0x0076, 0x0066, 0x0056, 0x0046, 0x0036, 0x0026, 0x8aff,
+ 0x0904, 0x1cb8, 0x700c, 0x7214, 0x923a, 0x7010, 0x7218, 0x9203,
+ 0x0a04, 0x1cb7, 0x9705, 0x0904, 0x1cb7, 0x903e, 0x2730, 0xa880,
+ 0xd0fc, 0x1190, 0x2d00, 0x0002, 0x1c9b, 0x1bdc, 0x1bdc, 0x1c9b,
+ 0x1c9b, 0x1c79, 0x1c9b, 0x1bdc, 0x1c7f, 0x1c2b, 0x1c2b, 0x1c9b,
+ 0x1c9b, 0x1c9b, 0x1c73, 0x1c2b, 0xc0fc, 0xa882, 0xab2c, 0xaa30,
+ 0xad1c, 0xac20, 0xdd9c, 0x0904, 0x1c9d, 0x2c05, 0x908a, 0x0034,
+ 0x1a0c, 0x0df6, 0x9082, 0x001b, 0x0002, 0x1bc8, 0x1bc6, 0x1bc6,
+ 0x1bc6, 0x1bc6, 0x1bc6, 0x1bcc, 0x1bc6, 0x1bc6, 0x1bc6, 0x1bc6,
+ 0x1bc6, 0x1bd0, 0x1bc6, 0x1bc6, 0x1bc6, 0x1bc6, 0x1bc6, 0x1bd4,
+ 0x1bc6, 0x1bc6, 0x1bc6, 0x1bc6, 0x1bc6, 0x1bd8, 0x080c, 0x0df6,
+ 0xa774, 0xa678, 0x0804, 0x1c9d, 0xa78c, 0xa690, 0x0804, 0x1c9d,
+ 0xa7a4, 0xa6a8, 0x0804, 0x1c9d, 0xa7bc, 0xa6c0, 0x0804, 0x1c9d,
+ 0xa7d4, 0xa6d8, 0x0804, 0x1c9d, 0x2c05, 0x908a, 0x0036, 0x1a0c,
+ 0x0df6, 0x9082, 0x001b, 0x0002, 0x1bff, 0x1bff, 0x1c01, 0x1bff,
+ 0x1bff, 0x1bff, 0x1c07, 0x1bff, 0x1bff, 0x1bff, 0x1c0d, 0x1bff,
+ 0x1bff, 0x1bff, 0x1c13, 0x1bff, 0x1bff, 0x1bff, 0x1c19, 0x1bff,
+ 0x1bff, 0x1bff, 0x1c1f, 0x1bff, 0x1bff, 0x1bff, 0x1c25, 0x080c,
+ 0x0df6, 0xa574, 0xa478, 0xa37c, 0xa280, 0x0804, 0x1c9d, 0xa584,
+ 0xa488, 0xa38c, 0xa290, 0x0804, 0x1c9d, 0xa594, 0xa498, 0xa39c,
+ 0xa2a0, 0x0804, 0x1c9d, 0xa5a4, 0xa4a8, 0xa3ac, 0xa2b0, 0x0804,
+ 0x1c9d, 0xa5b4, 0xa4b8, 0xa3bc, 0xa2c0, 0x0804, 0x1c9d, 0xa5c4,
+ 0xa4c8, 0xa3cc, 0xa2d0, 0x0804, 0x1c9d, 0xa5d4, 0xa4d8, 0xa3dc,
+ 0xa2e0, 0x0804, 0x1c9d, 0x2c05, 0x908a, 0x0034, 0x1a0c, 0x0df6,
+ 0x9082, 0x001b, 0x0002, 0x1c4e, 0x1c4c, 0x1c4c, 0x1c4c, 0x1c4c,
+ 0x1c4c, 0x1c56, 0x1c4c, 0x1c4c, 0x1c4c, 0x1c4c, 0x1c4c, 0x1c5e,
+ 0x1c4c, 0x1c4c, 0x1c4c, 0x1c4c, 0x1c4c, 0x1c65, 0x1c4c, 0x1c4c,
+ 0x1c4c, 0x1c4c, 0x1c4c, 0x1c6c, 0x080c, 0x0df6, 0xa56c, 0xa470,
+ 0xa774, 0xa678, 0xa37c, 0xa280, 0x0804, 0x1c9d, 0xa584, 0xa488,
+ 0xa78c, 0xa690, 0xa394, 0xa298, 0x0804, 0x1c9d, 0xa59c, 0xa4a0,
+ 0xa7a4, 0xa6a8, 0xa3ac, 0xa2b0, 0x04c0, 0xa5b4, 0xa4b8, 0xa7bc,
+ 0xa6c0, 0xa3c4, 0xa2c8, 0x0488, 0xa5cc, 0xa4d0, 0xa7d4, 0xa6d8,
+ 0xa3dc, 0xa2e0, 0x0450, 0xa864, 0x9084, 0x00ff, 0x9086, 0x001e,
+ 0x1510, 0x080c, 0x1e7c, 0x1904, 0x1b77, 0x900e, 0x04c8, 0xab64,
+ 0x939c, 0x00ff, 0x9386, 0x0048, 0x1180, 0x00c6, 0x7004, 0x2060,
+ 0x6004, 0x9086, 0x0043, 0x00ce, 0x0904, 0x1c2b, 0xab9c, 0x9016,
+ 0xad8c, 0xac90, 0xaf94, 0xae98, 0x0040, 0x9386, 0x0008, 0x0904,
+ 0x1c2b, 0x080c, 0x0df6, 0x080c, 0x0df6, 0x7b12, 0x7a16, 0x7d02,
+ 0x7c06, 0x7f0a, 0x7e0e, 0x782b, 0x0001, 0x7000, 0x8000, 0x7002,
+ 0xa83c, 0x9300, 0xa83e, 0xa840, 0x9201, 0xa842, 0x700c, 0x9300,
+ 0x700e, 0x7010, 0x9201, 0x7012, 0x080c, 0x1e7c, 0x0008, 0x9006,
+ 0x002e, 0x003e, 0x004e, 0x005e, 0x006e, 0x007e, 0x0005, 0x080c,
+ 0x0df6, 0x0026, 0x2001, 0x0105, 0x2003, 0x0010, 0x782b, 0x0004,
+ 0x7003, 0x0000, 0x7004, 0x2060, 0x6014, 0x2048, 0x080c, 0xbd4e,
+ 0x0118, 0xa880, 0xc0bd, 0xa882, 0x6020, 0x9086, 0x0006, 0x1180,
+ 0x2061, 0x0100, 0x62c8, 0x2001, 0x00fa, 0x8001, 0x1df0, 0x60c8,
+ 0x9206, 0x1dc0, 0x60c4, 0xa89a, 0x60c8, 0xa896, 0x7004, 0x2060,
+ 0x00c6, 0x080c, 0xb983, 0x00ce, 0x2001, 0x19d1, 0x2004, 0x9c06,
+ 0x1160, 0x2009, 0x0040, 0x080c, 0x2200, 0x080c, 0x9a8f, 0x2011,
+ 0x0000, 0x080c, 0x992d, 0x080c, 0x8c6c, 0x002e, 0x0804, 0x1e2e,
+ 0x0126, 0x2091, 0x2400, 0xa858, 0x2040, 0x792c, 0x782b, 0x0002,
+ 0x9184, 0x0700, 0x1904, 0x1cc1, 0x7000, 0x0002, 0x1e2e, 0x1d12,
+ 0x1d7f, 0x1e2c, 0x8001, 0x7002, 0xd19c, 0x1150, 0x8aff, 0x05b0,
+ 0x080c, 0x1b71, 0x0904, 0x1e2e, 0x080c, 0x1b71, 0x0804, 0x1e2e,
+ 0x782b, 0x0004, 0xd194, 0x0148, 0xa880, 0xc0fc, 0xa882, 0x8aff,
+ 0x11d8, 0xa87c, 0xc0f5, 0xa87e, 0x00b8, 0x0026, 0x0036, 0xab3c,
+ 0xaa40, 0x7810, 0xa82e, 0x931a, 0x7814, 0xa832, 0x9213, 0x7800,
+ 0xa81e, 0x7804, 0xa822, 0xab3e, 0xaa42, 0x003e, 0x002e, 0x080c,
+ 0x1e94, 0xa880, 0xc0fd, 0xa882, 0x2a00, 0xa816, 0x2800, 0xa85a,
+ 0x2c00, 0xa812, 0x7003, 0x0000, 0x0804, 0x1e2e, 0x00f6, 0x0026,
+ 0x781c, 0x0006, 0x7818, 0x0006, 0x2079, 0x0100, 0x7a14, 0x9284,
+ 0x1984, 0x9085, 0x0012, 0x7816, 0x0036, 0x2019, 0x1000, 0x8319,
+ 0x090c, 0x0df6, 0x7820, 0xd0bc, 0x1dd0, 0x003e, 0x79c8, 0x000e,
+ 0x9102, 0x001e, 0x0006, 0x0016, 0x79c4, 0x000e, 0x9103, 0x78c6,
+ 0x000e, 0x78ca, 0x9284, 0x1984, 0x9085, 0x0012, 0x7816, 0x002e,
+ 0x00fe, 0x782b, 0x0008, 0x7003, 0x0000, 0x0804, 0x1e2e, 0x8001,
+ 0x7002, 0xd194, 0x0170, 0x782c, 0xd0fc, 0x1904, 0x1d05, 0xd19c,
+ 0x1904, 0x1e2a, 0x8aff, 0x0904, 0x1e2e, 0x080c, 0x1b71, 0x0804,
+ 0x1e2e, 0x0026, 0x0036, 0xab3c, 0xaa40, 0x080c, 0x1e94, 0xdd9c,
+ 0x1904, 0x1de9, 0x2c05, 0x908a, 0x0036, 0x1a0c, 0x0df6, 0x9082,
+ 0x001b, 0x0002, 0x1dbd, 0x1dbd, 0x1dbf, 0x1dbd, 0x1dbd, 0x1dbd,
+ 0x1dc5, 0x1dbd, 0x1dbd, 0x1dbd, 0x1dcb, 0x1dbd, 0x1dbd, 0x1dbd,
+ 0x1dd1, 0x1dbd, 0x1dbd, 0x1dbd, 0x1dd7, 0x1dbd, 0x1dbd, 0x1dbd,
+ 0x1ddd, 0x1dbd, 0x1dbd, 0x1dbd, 0x1de3, 0x080c, 0x0df6, 0xa07c,
+ 0x931a, 0xa080, 0x9213, 0x0804, 0x1d31, 0xa08c, 0x931a, 0xa090,
+ 0x9213, 0x0804, 0x1d31, 0xa09c, 0x931a, 0xa0a0, 0x9213, 0x0804,
+ 0x1d31, 0xa0ac, 0x931a, 0xa0b0, 0x9213, 0x0804, 0x1d31, 0xa0bc,
+ 0x931a, 0xa0c0, 0x9213, 0x0804, 0x1d31, 0xa0cc, 0x931a, 0xa0d0,
+ 0x9213, 0x0804, 0x1d31, 0xa0dc, 0x931a, 0xa0e0, 0x9213, 0x0804,
+ 0x1d31, 0x2c05, 0x908a, 0x0034, 0x1a0c, 0x0df6, 0x9082, 0x001b,
+ 0x0002, 0x1e0c, 0x1e0a, 0x1e0a, 0x1e0a, 0x1e0a, 0x1e0a, 0x1e12,
+ 0x1e0a, 0x1e0a, 0x1e0a, 0x1e0a, 0x1e0a, 0x1e18, 0x1e0a, 0x1e0a,
+ 0x1e0a, 0x1e0a, 0x1e0a, 0x1e1e, 0x1e0a, 0x1e0a, 0x1e0a, 0x1e0a,
+ 0x1e0a, 0x1e24, 0x080c, 0x0df6, 0xa07c, 0x931a, 0xa080, 0x9213,
+ 0x0804, 0x1d31, 0xa094, 0x931a, 0xa098, 0x9213, 0x0804, 0x1d31,
+ 0xa0ac, 0x931a, 0xa0b0, 0x9213, 0x0804, 0x1d31, 0xa0c4, 0x931a,
+ 0xa0c8, 0x9213, 0x0804, 0x1d31, 0xa0dc, 0x931a, 0xa0e0, 0x9213,
+ 0x0804, 0x1d31, 0x0804, 0x1d2d, 0x080c, 0x0df6, 0x012e, 0x0005,
+ 0x00f6, 0x00e6, 0x2071, 0x1a42, 0x7000, 0x9086, 0x0000, 0x0904,
+ 0x1e79, 0x2079, 0x0090, 0x2009, 0x0207, 0x210c, 0xd194, 0x01b8,
+ 0x2009, 0x020c, 0x210c, 0x9184, 0x0003, 0x0188, 0x080c, 0xdbfc,
+ 0x2001, 0x0133, 0x2004, 0x9005, 0x090c, 0x0df6, 0x0016, 0x2009,
+ 0x0040, 0x080c, 0x2200, 0x001e, 0x2001, 0x020c, 0x2102, 0x2009,
+ 0x0206, 0x2104, 0x2009, 0x0203, 0x210c, 0x9106, 0x1120, 0x2009,
+ 0x0040, 0x080c, 0x2200, 0x782c, 0xd0fc, 0x09a8, 0x080c, 0x1d00,
+ 0x7000, 0x9086, 0x0000, 0x1978, 0x782b, 0x0004, 0x782c, 0xd0ac,
+ 0x1de8, 0x2009, 0x0040, 0x080c, 0x2200, 0x782b, 0x0002, 0x7003,
+ 0x0000, 0x00ee, 0x00fe, 0x0005, 0x8c60, 0x2c05, 0x9005, 0x0110,
+ 0x8a51, 0x0005, 0xa004, 0x9005, 0x0168, 0xa85a, 0x2040, 0xa064,
+ 0x9084, 0x000f, 0x9080, 0x1ebe, 0x2065, 0x8cff, 0x090c, 0x0df6,
+ 0x8a51, 0x0005, 0x2050, 0x0005, 0x8a50, 0x8c61, 0x2c05, 0x9005,
+ 0x1190, 0x2800, 0x9906, 0x0120, 0xa000, 0x9005, 0x1108, 0x2900,
+ 0x2040, 0xa85a, 0xa064, 0x9084, 0x000f, 0x9080, 0x1ece, 0x2065,
+ 0x8cff, 0x090c, 0x0df6, 0x0005, 0x0000, 0x001d, 0x0021, 0x0025,
+ 0x0029, 0x002d, 0x0031, 0x0035, 0x0000, 0x001b, 0x0021, 0x0027,
+ 0x002d, 0x0033, 0x0000, 0x0000, 0x0023, 0x0000, 0x0000, 0x1eb1,
+ 0x1ead, 0x0000, 0x0000, 0x1ebb, 0x0000, 0x1eb1, 0x1eb8, 0x1eb8,
+ 0x1eb5, 0x0000, 0x0000, 0x0000, 0x1ebb, 0x1eb8, 0x0000, 0x1eb3,
+ 0x1eb3, 0x0000, 0x0000, 0x1ebb, 0x0000, 0x1eb3, 0x1eb9, 0x1eb9,
+ 0x1eb9, 0x0000, 0x0000, 0x0000, 0x1ebb, 0x1eb9, 0x00c6, 0x00d6,
+ 0x0086, 0xab42, 0xac3e, 0xa888, 0x9055, 0x0904, 0x20bd, 0x2940,
+ 0xa064, 0x90ec, 0x000f, 0x9084, 0x00ff, 0x9086, 0x0008, 0x1118,
+ 0x2061, 0x1eb9, 0x00d0, 0x9de0, 0x1ebe, 0x9d86, 0x0007, 0x0130,
+ 0x9d86, 0x000e, 0x0118, 0x9d86, 0x000f, 0x1120, 0xa08c, 0x9422,
+ 0xa090, 0x931b, 0x2c05, 0x9065, 0x1140, 0x0310, 0x0804, 0x20bd,
+ 0xa004, 0x9045, 0x0904, 0x20bd, 0x08d8, 0x2c05, 0x9005, 0x0904,
+ 0x1fa5, 0xdd9c, 0x1904, 0x1f61, 0x908a, 0x0036, 0x1a0c, 0x0df6,
+ 0x9082, 0x001b, 0x0002, 0x1f36, 0x1f36, 0x1f38, 0x1f36, 0x1f36,
+ 0x1f36, 0x1f3e, 0x1f36, 0x1f36, 0x1f36, 0x1f44, 0x1f36, 0x1f36,
+ 0x1f36, 0x1f4a, 0x1f36, 0x1f36, 0x1f36, 0x1f50, 0x1f36, 0x1f36,
+ 0x1f36, 0x1f56, 0x1f36, 0x1f36, 0x1f36, 0x1f5c, 0x080c, 0x0df6,
+ 0xa07c, 0x9422, 0xa080, 0x931b, 0x0804, 0x1f9b, 0xa08c, 0x9422,
+ 0xa090, 0x931b, 0x0804, 0x1f9b, 0xa09c, 0x9422, 0xa0a0, 0x931b,
+ 0x0804, 0x1f9b, 0xa0ac, 0x9422, 0xa0b0, 0x931b, 0x0804, 0x1f9b,
+ 0xa0bc, 0x9422, 0xa0c0, 0x931b, 0x0804, 0x1f9b, 0xa0cc, 0x9422,
+ 0xa0d0, 0x931b, 0x0804, 0x1f9b, 0xa0dc, 0x9422, 0xa0e0, 0x931b,
+ 0x04d0, 0x908a, 0x0034, 0x1a0c, 0x0df6, 0x9082, 0x001b, 0x0002,
+ 0x1f83, 0x1f81, 0x1f81, 0x1f81, 0x1f81, 0x1f81, 0x1f88, 0x1f81,
+ 0x1f81, 0x1f81, 0x1f81, 0x1f81, 0x1f8d, 0x1f81, 0x1f81, 0x1f81,
+ 0x1f81, 0x1f81, 0x1f92, 0x1f81, 0x1f81, 0x1f81, 0x1f81, 0x1f81,
+ 0x1f97, 0x080c, 0x0df6, 0xa07c, 0x9422, 0xa080, 0x931b, 0x0098,
+ 0xa094, 0x9422, 0xa098, 0x931b, 0x0070, 0xa0ac, 0x9422, 0xa0b0,
+ 0x931b, 0x0048, 0xa0c4, 0x9422, 0xa0c8, 0x931b, 0x0020, 0xa0dc,
+ 0x9422, 0xa0e0, 0x931b, 0x0630, 0x2300, 0x9405, 0x0160, 0x8a51,
+ 0x0904, 0x20bd, 0x8c60, 0x0804, 0x1f0d, 0xa004, 0x9045, 0x0904,
+ 0x20bd, 0x0804, 0x1ee8, 0x8a51, 0x0904, 0x20bd, 0x8c60, 0x2c05,
+ 0x9005, 0x1158, 0xa004, 0x9045, 0x0904, 0x20bd, 0xa064, 0x90ec,
+ 0x000f, 0x9de0, 0x1ebe, 0x2c05, 0x2060, 0xa880, 0xc0fc, 0xa882,
+ 0x0804, 0x20b2, 0x2c05, 0x8422, 0x8420, 0x831a, 0x9399, 0x0000,
+ 0xac2e, 0xab32, 0xdd9c, 0x1904, 0x204f, 0x9082, 0x001b, 0x0002,
+ 0x1feb, 0x1feb, 0x1fed, 0x1feb, 0x1feb, 0x1feb, 0x1ffb, 0x1feb,
+ 0x1feb, 0x1feb, 0x2009, 0x1feb, 0x1feb, 0x1feb, 0x2017, 0x1feb,
+ 0x1feb, 0x1feb, 0x2025, 0x1feb, 0x1feb, 0x1feb, 0x2033, 0x1feb,
+ 0x1feb, 0x1feb, 0x2041, 0x080c, 0x0df6, 0xa17c, 0x2400, 0x9122,
+ 0xa180, 0x2300, 0x911b, 0x0a0c, 0x0df6, 0xa074, 0x9420, 0xa078,
+ 0x9319, 0x0804, 0x20ad, 0xa18c, 0x2400, 0x9122, 0xa190, 0x2300,
+ 0x911b, 0x0a0c, 0x0df6, 0xa084, 0x9420, 0xa088, 0x9319, 0x0804,
+ 0x20ad, 0xa19c, 0x2400, 0x9122, 0xa1a0, 0x2300, 0x911b, 0x0a0c,
+ 0x0df6, 0xa094, 0x9420, 0xa098, 0x9319, 0x0804, 0x20ad, 0xa1ac,
+ 0x2400, 0x9122, 0xa1b0, 0x2300, 0x911b, 0x0a0c, 0x0df6, 0xa0a4,
+ 0x9420, 0xa0a8, 0x9319, 0x0804, 0x20ad, 0xa1bc, 0x2400, 0x9122,
+ 0xa1c0, 0x2300, 0x911b, 0x0a0c, 0x0df6, 0xa0b4, 0x9420, 0xa0b8,
+ 0x9319, 0x0804, 0x20ad, 0xa1cc, 0x2400, 0x9122, 0xa1d0, 0x2300,
+ 0x911b, 0x0a0c, 0x0df6, 0xa0c4, 0x9420, 0xa0c8, 0x9319, 0x0804,
+ 0x20ad, 0xa1dc, 0x2400, 0x9122, 0xa1e0, 0x2300, 0x911b, 0x0a0c,
+ 0x0df6, 0xa0d4, 0x9420, 0xa0d8, 0x9319, 0x0804, 0x20ad, 0x9082,
+ 0x001b, 0x0002, 0x206d, 0x206b, 0x206b, 0x206b, 0x206b, 0x206b,
+ 0x207a, 0x206b, 0x206b, 0x206b, 0x206b, 0x206b, 0x2087, 0x206b,
+ 0x206b, 0x206b, 0x206b, 0x206b, 0x2094, 0x206b, 0x206b, 0x206b,
+ 0x206b, 0x206b, 0x20a1, 0x080c, 0x0df6, 0xa17c, 0x2400, 0x9122,
+ 0xa180, 0x2300, 0x911b, 0x0a0c, 0x0df6, 0xa06c, 0x9420, 0xa070,
+ 0x9319, 0x0498, 0xa194, 0x2400, 0x9122, 0xa198, 0x2300, 0x911b,
+ 0x0a0c, 0x0df6, 0xa084, 0x9420, 0xa088, 0x9319, 0x0430, 0xa1ac,
+ 0x2400, 0x9122, 0xa1b0, 0x2300, 0x911b, 0x0a0c, 0x0df6, 0xa09c,
+ 0x9420, 0xa0a0, 0x9319, 0x00c8, 0xa1c4, 0x2400, 0x9122, 0xa1c8,
+ 0x2300, 0x911b, 0x0a0c, 0x0df6, 0xa0b4, 0x9420, 0xa0b8, 0x9319,
+ 0x0060, 0xa1dc, 0x2400, 0x9122, 0xa1e0, 0x2300, 0x911b, 0x0a0c,
+ 0x0df6, 0xa0cc, 0x9420, 0xa0d0, 0x9319, 0xac1e, 0xab22, 0xa880,
+ 0xc0fd, 0xa882, 0x2800, 0xa85a, 0x2c00, 0xa812, 0x2a00, 0xa816,
+ 0x000e, 0x000e, 0x000e, 0x9006, 0x0028, 0x008e, 0x00de, 0x00ce,
+ 0x9085, 0x0001, 0x0005, 0x2001, 0x0005, 0x2004, 0xd0bc, 0x190c,
+ 0x0def, 0x9084, 0x0007, 0x0002, 0x20de, 0x1d00, 0x20de, 0x20d4,
+ 0x20d7, 0x20da, 0x20d7, 0x20da, 0x080c, 0x1d00, 0x0005, 0x080c,
+ 0x11ee, 0x0005, 0x080c, 0x1d00, 0x080c, 0x11ee, 0x0005, 0x0126,
+ 0x2091, 0x2600, 0x2079, 0x0200, 0x2071, 0x0260, 0x2069, 0x1800,
+ 0x7817, 0x0000, 0x789b, 0x0814, 0x78a3, 0x0406, 0x789f, 0x0410,
+ 0x2009, 0x013b, 0x200b, 0x0400, 0x781b, 0x0002, 0x783b, 0x001f,
+ 0x7837, 0x0020, 0x7803, 0x1600, 0x012e, 0x0005, 0x2091, 0x2600,
+ 0x781c, 0xd0a4, 0x190c, 0x21fd, 0x7900, 0xd1dc, 0x1118, 0x9084,
+ 0x0006, 0x001a, 0x9084, 0x000e, 0x0002, 0x2125, 0x211d, 0x7b33,
+ 0x211d, 0x211f, 0x211f, 0x211f, 0x211f, 0x7b19, 0x211d, 0x2121,
+ 0x211d, 0x211f, 0x211d, 0x211f, 0x211d, 0x080c, 0x0df6, 0x0031,
+ 0x0020, 0x080c, 0x7b19, 0x080c, 0x7b33, 0x0005, 0x0006, 0x0016,
+ 0x0026, 0x080c, 0xdbfc, 0x7930, 0x9184, 0x0003, 0x01c0, 0x2001,
+ 0x19d1, 0x2004, 0x9005, 0x0170, 0x2001, 0x0133, 0x2004, 0x9005,
+ 0x090c, 0x0df6, 0x00c6, 0x2001, 0x19d1, 0x2064, 0x080c, 0xb983,
+ 0x00ce, 0x00f8, 0x2009, 0x0040, 0x080c, 0x2200, 0x00d0, 0x9184,
+ 0x0014, 0x01a0, 0x6a00, 0x9286, 0x0003, 0x0160, 0x080c, 0x717e,
+ 0x1138, 0x080c, 0x747a, 0x080c, 0x5e2f, 0x080c, 0x709e, 0x0010,
+ 0x080c, 0x5cee, 0x080c, 0x7be2, 0x0041, 0x0018, 0x9184, 0x9540,
+ 0x1dc8, 0x002e, 0x001e, 0x000e, 0x0005, 0x00e6, 0x0036, 0x0046,
+ 0x0056, 0x2071, 0x1a3f, 0x080c, 0x1977, 0x005e, 0x004e, 0x003e,
+ 0x00ee, 0x0005, 0x0126, 0x2091, 0x2e00, 0x2071, 0x1800, 0x7128,
+ 0x2001, 0x1949, 0x2102, 0x2001, 0x1951, 0x2102, 0x2001, 0x013b,
+ 0x2102, 0x2079, 0x0200, 0x2001, 0x0201, 0x789e, 0x78a3, 0x0200,
+ 0x9198, 0x0007, 0x831c, 0x831c, 0x831c, 0x9398, 0x0005, 0x2320,
+ 0x9182, 0x0204, 0x1230, 0x2011, 0x0008, 0x8423, 0x8423, 0x8423,
+ 0x0488, 0x9182, 0x024c, 0x1240, 0x2011, 0x0007, 0x8403, 0x8003,
+ 0x9400, 0x9400, 0x9420, 0x0430, 0x9182, 0x02bc, 0x1238, 0x2011,
+ 0x0006, 0x8403, 0x8003, 0x9400, 0x9420, 0x00e0, 0x9182, 0x034c,
+ 0x1230, 0x2011, 0x0005, 0x8403, 0x8003, 0x9420, 0x0098, 0x9182,
+ 0x042c, 0x1228, 0x2011, 0x0004, 0x8423, 0x8423, 0x0058, 0x9182,
+ 0x059c, 0x1228, 0x2011, 0x0003, 0x8403, 0x9420, 0x0018, 0x2011,
+ 0x0002, 0x8423, 0x9482, 0x0228, 0x8002, 0x8020, 0x8301, 0x9402,
+ 0x0110, 0x0208, 0x8321, 0x8217, 0x8203, 0x9405, 0x789a, 0x012e,
+ 0x0005, 0x0006, 0x00d6, 0x2069, 0x0200, 0x6814, 0x9084, 0xffc0,
+ 0x910d, 0x6916, 0x00de, 0x000e, 0x0005, 0x00d6, 0x2069, 0x0200,
+ 0x9005, 0x6810, 0x0110, 0xc0a5, 0x0008, 0xc0a4, 0x6812, 0x00de,
+ 0x0005, 0x0006, 0x00d6, 0x2069, 0x0200, 0x6810, 0x9084, 0xfff8,
+ 0x910d, 0x6912, 0x00de, 0x000e, 0x0005, 0x7938, 0x080c, 0x0def,
+ 0x00f6, 0x2079, 0x0200, 0x7902, 0xa001, 0xa001, 0xa001, 0xa001,
+ 0xa001, 0xa001, 0x7902, 0xa001, 0xa001, 0xa001, 0xa001, 0xa001,
+ 0xa001, 0x00fe, 0x0005, 0x0126, 0x2091, 0x2800, 0x2061, 0x0100,
+ 0x2071, 0x1800, 0x2009, 0x0000, 0x080c, 0x2a9d, 0x080c, 0x2974,
+ 0x2001, 0x0100, 0x2004, 0x9086, 0x000a, 0x0558, 0x6054, 0x8004,
+ 0x8004, 0x8004, 0x8004, 0x9084, 0x000c, 0x6150, 0x918c, 0xfff3,
+ 0x9105, 0x6052, 0x6050, 0x9084, 0xb17f, 0x9085, 0x2000, 0x6052,
+ 0x2009, 0x1977, 0x2011, 0x1978, 0x6358, 0x939c, 0x38f0, 0x2320,
+ 0x080c, 0x29e1, 0x1238, 0x939d, 0x4003, 0x94a5, 0x8603, 0x230a,
+ 0x2412, 0x0030, 0x939d, 0x0203, 0x94a5, 0x8603, 0x230a, 0x2412,
+ 0x0050, 0x2001, 0x1977, 0x2003, 0x0700, 0x2001, 0x1978, 0x2003,
+ 0x0700, 0x080c, 0x2ba9, 0x9006, 0x080c, 0x29a3, 0x9006, 0x080c,
+ 0x2986, 0x20a9, 0x0012, 0x1d04, 0x2263, 0x2091, 0x6000, 0x1f04,
+ 0x2263, 0x602f, 0x0100, 0x602f, 0x0000, 0x6050, 0x9085, 0x0400,
+ 0x9084, 0xdfff, 0x6052, 0x6024, 0x6026, 0x080c, 0x26a6, 0x2009,
+ 0x00ef, 0x6132, 0x6136, 0x080c, 0x26b6, 0x60e7, 0x0000, 0x61ea,
+ 0x60e3, 0x0002, 0x604b, 0xf7f7, 0x6043, 0x0000, 0x602f, 0x0080,
+ 0x602f, 0x0000, 0x6007, 0x149f, 0x60bb, 0x0000, 0x20a9, 0x0018,
+ 0x60bf, 0x0000, 0x1f04, 0x2290, 0x60bb, 0x0000, 0x60bf, 0x0108,
+ 0x60bf, 0x0012, 0x60bf, 0x0320, 0x60bf, 0x0018, 0x601b, 0x00f0,
+ 0x601f, 0x001e, 0x600f, 0x006b, 0x602b, 0x402f, 0x012e, 0x0005,
+ 0x00f6, 0x2079, 0x0140, 0x78c3, 0x0080, 0x78c3, 0x0083, 0x78c3,
+ 0x0000, 0x00fe, 0x0005, 0x2001, 0x1834, 0x2003, 0x0000, 0x2001,
+ 0x1833, 0x2003, 0x0001, 0x0005, 0x0126, 0x2091, 0x2800, 0x0006,
+ 0x0016, 0x0026, 0x6124, 0x9184, 0x5e2c, 0x1118, 0x9184, 0x0007,
+ 0x002a, 0x9195, 0x0004, 0x9284, 0x0007, 0x0002, 0x22f0, 0x22d6,
+ 0x22d9, 0x22dc, 0x22e1, 0x22e3, 0x22e7, 0x22eb, 0x080c, 0x84e2,
+ 0x00b8, 0x080c, 0x85b1, 0x00a0, 0x080c, 0x85b1, 0x080c, 0x84e2,
+ 0x0078, 0x0099, 0x0068, 0x080c, 0x84e2, 0x0079, 0x0048, 0x080c,
+ 0x85b1, 0x0059, 0x0028, 0x080c, 0x85b1, 0x080c, 0x84e2, 0x0029,
+ 0x002e, 0x001e, 0x000e, 0x012e, 0x0005, 0x00a6, 0x6124, 0x6028,
+ 0xd09c, 0x0118, 0xd19c, 0x1904, 0x2547, 0xd1f4, 0x190c, 0x0def,
+ 0x080c, 0x717e, 0x0904, 0x234b, 0x080c, 0xc459, 0x1120, 0x7000,
+ 0x9086, 0x0003, 0x0570, 0x6024, 0x9084, 0x1800, 0x0550, 0x080c,
+ 0x71a1, 0x0118, 0x080c, 0x718f, 0x1520, 0x6027, 0x0020, 0x6043,
+ 0x0000, 0x080c, 0xc459, 0x0168, 0x080c, 0x71a1, 0x1150, 0x2001,
+ 0x1982, 0x2003, 0x0001, 0x6027, 0x1800, 0x080c, 0x6fed, 0x0804,
+ 0x254a, 0x70a0, 0x9005, 0x1150, 0x70a3, 0x0001, 0x00d6, 0x2069,
+ 0x0140, 0x080c, 0x71d2, 0x00de, 0x1904, 0x254a, 0x080c, 0x7484,
+ 0x0428, 0x080c, 0x71a1, 0x1590, 0x6024, 0x9084, 0x1800, 0x1108,
+ 0x0468, 0x080c, 0x7484, 0x080c, 0x747a, 0x080c, 0x5e2f, 0x080c,
+ 0x709e, 0x0804, 0x2547, 0xd1ac, 0x1508, 0x6024, 0xd0dc, 0x1170,
+ 0xd0e4, 0x1178, 0xd0d4, 0x1190, 0xd0cc, 0x0130, 0x7094, 0x9086,
+ 0x0029, 0x1110, 0x080c, 0x7369, 0x0804, 0x2547, 0x080c, 0x747f,
+ 0x0048, 0x2001, 0x1957, 0x2003, 0x0002, 0x0020, 0x080c, 0x72cd,
+ 0x0804, 0x2547, 0x080c, 0x7403, 0x0804, 0x2547, 0xd1ac, 0x0904,
+ 0x2468, 0x080c, 0x717e, 0x11c0, 0x6027, 0x0020, 0x0006, 0x0026,
+ 0x0036, 0x080c, 0x7198, 0x1158, 0x080c, 0x747a, 0x080c, 0x5e2f,
+ 0x080c, 0x709e, 0x003e, 0x002e, 0x000e, 0x00ae, 0x0005, 0x003e,
+ 0x002e, 0x000e, 0x080c, 0x7156, 0x0016, 0x0046, 0x00c6, 0x644c,
+ 0x9486, 0xf0f0, 0x1138, 0x2061, 0x0100, 0x644a, 0x6043, 0x0090,
+ 0x6043, 0x0010, 0x74d6, 0x948c, 0xff00, 0x7038, 0xd084, 0x0190,
+ 0x080c, 0xc459, 0x1118, 0x9186, 0xf800, 0x1160, 0x7044, 0xd084,
+ 0x1148, 0xc085, 0x7046, 0x0036, 0x2418, 0x2011, 0x8016, 0x080c,
+ 0x4a17, 0x003e, 0x080c, 0xc452, 0x1904, 0x2445, 0x9196, 0xff00,
+ 0x05a8, 0x705c, 0x9084, 0x00ff, 0x810f, 0x81ff, 0x0110, 0x9116,
+ 0x0568, 0x7130, 0xd184, 0x1550, 0x080c, 0x31ee, 0x0128, 0xc18d,
+ 0x7132, 0x080c, 0x66c1, 0x1510, 0x6240, 0x9294, 0x0010, 0x0130,
+ 0x6248, 0x9294, 0xff00, 0x9296, 0xff00, 0x01c0, 0x7030, 0xd08c,
+ 0x0904, 0x2445, 0x7038, 0xd08c, 0x1140, 0x2001, 0x180c, 0x200c,
+ 0xd1ac, 0x1904, 0x2445, 0xc1ad, 0x2102, 0x0036, 0x73d4, 0x2011,
+ 0x8013, 0x080c, 0x4a17, 0x003e, 0x0804, 0x2445, 0x7038, 0xd08c,
+ 0x1140, 0x2001, 0x180c, 0x200c, 0xd1ac, 0x1904, 0x2445, 0xc1ad,
+ 0x2102, 0x0036, 0x73d4, 0x2011, 0x8013, 0x080c, 0x4a17, 0x003e,
+ 0x7130, 0xc185, 0x7132, 0x2011, 0x185c, 0x220c, 0x00f0, 0x0016,
+ 0x2009, 0x0001, 0x2011, 0x0100, 0x080c, 0x8450, 0x2019, 0x000e,
+ 0x00c6, 0x2061, 0x0000, 0x080c, 0xd7af, 0x00ce, 0x9484, 0x00ff,
+ 0x9080, 0x31f3, 0x200d, 0x918c, 0xff00, 0x810f, 0x2120, 0x9006,
+ 0x2009, 0x000e, 0x080c, 0xd837, 0x001e, 0xd1ac, 0x1148, 0x0016,
+ 0x2009, 0x0002, 0x2019, 0x0004, 0x080c, 0x3060, 0x001e, 0x00a8,
+ 0x0156, 0x00b6, 0x20a9, 0x007f, 0x900e, 0x080c, 0x63a3, 0x1140,
+ 0x7030, 0xd084, 0x1118, 0xb800, 0xd0bc, 0x1110, 0x080c, 0x5e49,
+ 0x8108, 0x1f04, 0x2435, 0x00be, 0x015e, 0x00ce, 0x004e, 0x080c,
+ 0x9f70, 0x60e3, 0x0000, 0x001e, 0x2001, 0x1800, 0x2014, 0x9296,
+ 0x0004, 0x1170, 0xd19c, 0x11a0, 0x2011, 0x180c, 0x2214, 0xd29c,
+ 0x1120, 0x6204, 0x9295, 0x0002, 0x6206, 0x6228, 0xc29d, 0x622a,
+ 0x2003, 0x0001, 0x2001, 0x1825, 0x2003, 0x0000, 0x6027, 0x0020,
+ 0xd194, 0x0904, 0x2547, 0x0016, 0x6220, 0xd2b4, 0x0904, 0x24f0,
+ 0x080c, 0x82d9, 0x080c, 0x961a, 0x6027, 0x0004, 0x00f6, 0x2019,
+ 0x19cb, 0x2304, 0x907d, 0x0904, 0x24bf, 0x7804, 0x9086, 0x0032,
+ 0x15f0, 0x00d6, 0x00c6, 0x00e6, 0x0096, 0x2069, 0x0140, 0x782c,
+ 0x685e, 0x7808, 0x685a, 0x6043, 0x0002, 0x2001, 0x0003, 0x8001,
+ 0x1df0, 0x6043, 0x0000, 0x2001, 0x003c, 0x8001, 0x1df0, 0x080c,
+ 0x2b7f, 0x2001, 0x001e, 0x8001, 0x0240, 0x20a9, 0x0009, 0x080c,
+ 0x2a78, 0x6904, 0xd1dc, 0x1140, 0x0cb0, 0x2001, 0x0100, 0x080c,
+ 0x2b6f, 0x9006, 0x080c, 0x2b6f, 0x080c, 0x8a83, 0x080c, 0x8b8f,
+ 0x7814, 0x2048, 0xa867, 0x0103, 0x2f60, 0x080c, 0x9fea, 0x009e,
+ 0x00ee, 0x00ce, 0x00de, 0x00fe, 0x001e, 0x00ae, 0x0005, 0x00fe,
+ 0x00d6, 0x2069, 0x0140, 0x6804, 0x9084, 0x4000, 0x0110, 0x080c,
+ 0x2b7f, 0x00de, 0x00c6, 0x2061, 0x19c2, 0x6028, 0x080c, 0xc459,
+ 0x0120, 0x909a, 0x0003, 0x1258, 0x0018, 0x909a, 0x00c8, 0x1238,
+ 0x8000, 0x602a, 0x00ce, 0x080c, 0x95f6, 0x0804, 0x2546, 0x2061,
+ 0x0100, 0x62c0, 0x080c, 0x9df6, 0x2019, 0x19cb, 0x2304, 0x9065,
+ 0x0120, 0x2009, 0x0027, 0x080c, 0xa068, 0x00ce, 0x0804, 0x2546,
+ 0xd2bc, 0x0904, 0x2533, 0x080c, 0x82e6, 0x6014, 0x9084, 0x1984,
+ 0x9085, 0x0010, 0x6016, 0x6027, 0x0004, 0x00d6, 0x2069, 0x0140,
+ 0x6804, 0x9084, 0x4000, 0x0110, 0x080c, 0x2b7f, 0x00de, 0x00c6,
+ 0x2061, 0x19c2, 0x6044, 0x080c, 0xc459, 0x0120, 0x909a, 0x0003,
+ 0x1628, 0x0018, 0x909a, 0x00c8, 0x1608, 0x8000, 0x6046, 0x603c,
+ 0x00ce, 0x9005, 0x0558, 0x2009, 0x07d0, 0x080c, 0x82de, 0x9080,
+ 0x0008, 0x2004, 0x9086, 0x0006, 0x1138, 0x6114, 0x918c, 0x1984,
+ 0x918d, 0x0012, 0x6116, 0x00d0, 0x6114, 0x918c, 0x1984, 0x918d,
+ 0x0016, 0x6116, 0x0098, 0x6027, 0x0004, 0x0080, 0x0036, 0x2019,
+ 0x0001, 0x080c, 0x98b1, 0x003e, 0x2019, 0x19d1, 0x2304, 0x9065,
+ 0x0120, 0x2009, 0x004f, 0x080c, 0xa068, 0x00ce, 0x001e, 0xd19c,
+ 0x0904, 0x2611, 0x7038, 0xd0ac, 0x1904, 0x25e6, 0x0016, 0x0156,
+ 0x6027, 0x0008, 0x2001, 0x0100, 0x2004, 0x9086, 0x000a, 0x0904,
+ 0x25c3, 0x6050, 0x9085, 0x0040, 0x6052, 0x6050, 0x9084, 0xfbcf,
+ 0x6052, 0x080c, 0x2a97, 0x9085, 0x2000, 0x6052, 0x20a9, 0x0012,
+ 0x1d04, 0x2568, 0x080c, 0x830d, 0x1f04, 0x2568, 0x6050, 0x9085,
+ 0x0400, 0x9084, 0xdfbf, 0x6052, 0x20a9, 0x0028, 0xa001, 0x1f04,
+ 0x2576, 0x6150, 0x9185, 0x1400, 0x6052, 0x20a9, 0x0366, 0x1d04,
+ 0x257f, 0x080c, 0x830d, 0x6020, 0xd09c, 0x1138, 0x015e, 0x6152,
+ 0x001e, 0x6027, 0x0008, 0x0804, 0x2611, 0x080c, 0x2a5f, 0x1f04,
+ 0x257f, 0x015e, 0x6152, 0x001e, 0x6027, 0x0008, 0x0016, 0x6028,
+ 0xc09c, 0x602a, 0x080c, 0x9f70, 0x60e3, 0x0000, 0x080c, 0xdbdb,
+ 0x080c, 0xdbf6, 0x080c, 0x54df, 0xd0fc, 0x1138, 0x080c, 0xc452,
+ 0x1120, 0x9085, 0x0001, 0x080c, 0x71c2, 0x9006, 0x080c, 0x2b6f,
+ 0x2009, 0x0002, 0x080c, 0x2a9d, 0x00e6, 0x2071, 0x1800, 0x7003,
+ 0x0004, 0x080c, 0x0ecc, 0x00ee, 0x6027, 0x0008, 0x080c, 0x0b8f,
+ 0x001e, 0x0804, 0x2611, 0x080c, 0x2ba9, 0x080c, 0x2bdc, 0x6050,
+ 0xc0e5, 0x6052, 0x20a9, 0x0367, 0x0f04, 0x25e4, 0x1d04, 0x25ce,
+ 0x080c, 0x830d, 0x6020, 0xd09c, 0x1db8, 0x00f6, 0x2079, 0x0100,
+ 0x080c, 0x29f1, 0x00fe, 0x1d80, 0x6050, 0xc0e4, 0x6052, 0x6027,
+ 0x0008, 0x015e, 0x001e, 0x0468, 0x015e, 0x001e, 0x0016, 0x6028,
+ 0xc09c, 0x602a, 0x080c, 0x9f70, 0x60e3, 0x0000, 0x080c, 0xdbdb,
+ 0x080c, 0xdbf6, 0x080c, 0x54df, 0xd0fc, 0x1138, 0x080c, 0xc452,
+ 0x1120, 0x9085, 0x0001, 0x080c, 0x71c2, 0x9006, 0x080c, 0x2b6f,
+ 0x2009, 0x0002, 0x080c, 0x2a9d, 0x00e6, 0x2071, 0x1800, 0x7003,
+ 0x0004, 0x080c, 0x0ecc, 0x00ee, 0x6027, 0x0008, 0x080c, 0x0b8f,
+ 0x001e, 0x918c, 0xffd0, 0x6126, 0x00ae, 0x0005, 0x0006, 0x0016,
+ 0x0026, 0x0036, 0x00e6, 0x00f6, 0x0126, 0x2091, 0x8000, 0x2071,
+ 0x1800, 0x71cc, 0x70ce, 0x9116, 0x0904, 0x2665, 0x81ff, 0x01a0,
+ 0x2009, 0x0000, 0x080c, 0x2a9d, 0x2011, 0x8011, 0x2019, 0x010e,
+ 0x231c, 0x939e, 0x0007, 0x1118, 0x2019, 0x0001, 0x0010, 0x2019,
+ 0x0000, 0x080c, 0x4a17, 0x0448, 0x2001, 0x1983, 0x200c, 0x81ff,
+ 0x1140, 0x2001, 0x0109, 0x2004, 0xd0b4, 0x0118, 0x2019, 0x0003,
+ 0x0008, 0x2118, 0x2011, 0x8012, 0x080c, 0x4a17, 0x080c, 0x0ecc,
+ 0x080c, 0x54df, 0xd0fc, 0x1188, 0x080c, 0xc452, 0x1170, 0x00c6,
+ 0x080c, 0x2701, 0x080c, 0x9818, 0x2061, 0x0100, 0x2019, 0x0028,
+ 0x2009, 0x0002, 0x080c, 0x3060, 0x00ce, 0x012e, 0x00fe, 0x00ee,
+ 0x003e, 0x002e, 0x001e, 0x000e, 0x0005, 0x2028, 0x918c, 0x00ff,
+ 0x2130, 0x9094, 0xff00, 0x11f0, 0x2011, 0x1836, 0x2214, 0xd2ac,
+ 0x11c8, 0x81ff, 0x01e8, 0x2011, 0x181e, 0x2204, 0x9106, 0x1190,
+ 0x2011, 0x181f, 0x2214, 0x9294, 0xff00, 0x9584, 0xff00, 0x9206,
+ 0x1148, 0x2011, 0x181f, 0x2214, 0x9294, 0x00ff, 0x9584, 0x00ff,
+ 0x9206, 0x1120, 0x2500, 0x080c, 0x7e3f, 0x0048, 0x9584, 0x00ff,
+ 0x9080, 0x31f3, 0x200d, 0x918c, 0xff00, 0x810f, 0x9006, 0x0005,
+ 0x9080, 0x31f3, 0x200d, 0x918c, 0x00ff, 0x0005, 0x00d6, 0x2069,
+ 0x0140, 0x2001, 0x1817, 0x2003, 0x00ef, 0x20a9, 0x0010, 0x9006,
+ 0x6852, 0x6856, 0x1f04, 0x26b1, 0x00de, 0x0005, 0x0006, 0x00d6,
+ 0x0026, 0x2069, 0x0140, 0x2001, 0x1817, 0x2102, 0x8114, 0x8214,
+ 0x8214, 0x8214, 0x20a9, 0x0010, 0x6853, 0x0000, 0x9006, 0x82ff,
+ 0x1128, 0x9184, 0x000f, 0x9080, 0xe3a6, 0x2005, 0x6856, 0x8211,
+ 0x1f04, 0x26c6, 0x002e, 0x00de, 0x000e, 0x0005, 0x00c6, 0x2061,
+ 0x1800, 0x6030, 0x0110, 0xc09d, 0x0008, 0xc09c, 0x6032, 0x00ce,
+ 0x0005, 0x0156, 0x00d6, 0x0026, 0x0016, 0x0006, 0x2069, 0x0140,
+ 0x6980, 0x9116, 0x0180, 0x9112, 0x1230, 0x8212, 0x8210, 0x22a8,
+ 0x2001, 0x0402, 0x0018, 0x22a8, 0x2001, 0x0404, 0x680e, 0x1f04,
+ 0x26f6, 0x680f, 0x0000, 0x000e, 0x001e, 0x002e, 0x00de, 0x015e,
+ 0x0005, 0x080c, 0x54db, 0xd0c4, 0x0150, 0xd0a4, 0x0140, 0x9006,
+ 0x0046, 0x2020, 0x2009, 0x002e, 0x080c, 0xd837, 0x004e, 0x0005,
+ 0x00f6, 0x0016, 0x0026, 0x2079, 0x0140, 0x78c4, 0xd0dc, 0x0904,
+ 0x276d, 0x080c, 0x29e1, 0x0660, 0x9084, 0x0700, 0x908e, 0x0600,
+ 0x1120, 0x2011, 0x4000, 0x900e, 0x0458, 0x908e, 0x0500, 0x1120,
+ 0x2011, 0x8000, 0x900e, 0x0420, 0x908e, 0x0400, 0x1120, 0x9016,
+ 0x2009, 0x0001, 0x00e8, 0x908e, 0x0300, 0x1120, 0x9016, 0x2009,
+ 0x0002, 0x00b0, 0x908e, 0x0200, 0x1120, 0x9016, 0x2009, 0x0004,
+ 0x0078, 0x908e, 0x0100, 0x1548, 0x9016, 0x2009, 0x0008, 0x0040,
+ 0x9084, 0x0700, 0x908e, 0x0300, 0x1500, 0x2011, 0x0030, 0x0058,
+ 0x2300, 0x9080, 0x0020, 0x2018, 0x080c, 0x847e, 0x928c, 0xff00,
+ 0x0110, 0x2011, 0x00ff, 0x2200, 0x8007, 0x9085, 0x004c, 0x78c2,
+ 0x2009, 0x0138, 0x220a, 0x080c, 0x717e, 0x1118, 0x2009, 0x1947,
+ 0x220a, 0x002e, 0x001e, 0x00fe, 0x0005, 0x78c3, 0x0000, 0x0cc8,
+ 0x0126, 0x2091, 0x2800, 0x0006, 0x0016, 0x0026, 0x2001, 0x0170,
+ 0x200c, 0x8000, 0x2014, 0x9184, 0x0003, 0x0110, 0x080c, 0x0def,
+ 0x002e, 0x001e, 0x000e, 0x012e, 0x0005, 0x2001, 0x0171, 0x2004,
+ 0xd0dc, 0x0168, 0x2001, 0x0170, 0x200c, 0x918c, 0x00ff, 0x918e,
+ 0x004c, 0x1128, 0x200c, 0x918c, 0xff00, 0x810f, 0x0005, 0x900e,
+ 0x2001, 0x0227, 0x2004, 0x8007, 0x9084, 0x00ff, 0x8004, 0x9108,
+ 0x2001, 0x0226, 0x2004, 0x8007, 0x9084, 0x00ff, 0x8004, 0x9108,
+ 0x0005, 0x0018, 0x000c, 0x0018, 0x0020, 0x1000, 0x0800, 0x1000,
+ 0x1800, 0x0156, 0x0006, 0x0016, 0x0026, 0x00e6, 0x2001, 0x196a,
+ 0x2004, 0x908a, 0x0007, 0x1a0c, 0x0df6, 0x0033, 0x00ee, 0x002e,
+ 0x001e, 0x000e, 0x015e, 0x0005, 0x27cb, 0x27e9, 0x280d, 0x280f,
+ 0x2838, 0x283a, 0x283c, 0x2001, 0x0001, 0x080c, 0x2616, 0x080c,
+ 0x2a51, 0x2001, 0x196c, 0x2003, 0x0000, 0x7828, 0x9084, 0xe1d7,
+ 0x782a, 0x9006, 0x20a9, 0x0009, 0x080c, 0x29fd, 0x2001, 0x196a,
+ 0x2003, 0x0006, 0x2009, 0x001e, 0x2011, 0x283d, 0x080c, 0x82eb,
+ 0x0005, 0x2009, 0x196f, 0x200b, 0x0000, 0x2001, 0x1974, 0x2003,
+ 0x0036, 0x2001, 0x1973, 0x2003, 0x002a, 0x2001, 0x196c, 0x2003,
+ 0x0001, 0x9006, 0x080c, 0x2986, 0x2001, 0xffff, 0x20a9, 0x0009,
+ 0x080c, 0x29fd, 0x2001, 0x196a, 0x2003, 0x0006, 0x2009, 0x001e,
+ 0x2011, 0x283d, 0x080c, 0x82eb, 0x0005, 0x080c, 0x0df6, 0x2001,
+ 0x1974, 0x2003, 0x0036, 0x2001, 0x196c, 0x2003, 0x0003, 0x7a38,
+ 0x9294, 0x0005, 0x9296, 0x0004, 0x0110, 0x9006, 0x0010, 0x2001,
+ 0x0001, 0x080c, 0x2986, 0x2001, 0x1970, 0x2003, 0x0000, 0x2001,
+ 0xffff, 0x20a9, 0x0009, 0x080c, 0x29fd, 0x2001, 0x196a, 0x2003,
+ 0x0006, 0x2009, 0x001e, 0x2011, 0x283d, 0x080c, 0x82eb, 0x0005,
+ 0x080c, 0x0df6, 0x080c, 0x0df6, 0x0005, 0x0006, 0x0016, 0x0026,
+ 0x00e6, 0x00f6, 0x0156, 0x0126, 0x2091, 0x8000, 0x2079, 0x0100,
+ 0x2001, 0x196c, 0x2004, 0x908a, 0x0007, 0x1a0c, 0x0df6, 0x0043,
+ 0x012e, 0x015e, 0x00fe, 0x00ee, 0x002e, 0x001e, 0x000e, 0x0005,
+ 0x285f, 0x287b, 0x28b7, 0x28e3, 0x2903, 0x290f, 0x2911, 0x080c,
+ 0x29f1, 0x1190, 0x2009, 0x1972, 0x2104, 0x7a38, 0x9294, 0x0005,
+ 0x9296, 0x0004, 0x0110, 0xc08d, 0x0008, 0xc085, 0x200a, 0x2001,
+ 0x196a, 0x2003, 0x0001, 0x0030, 0x080c, 0x2935, 0x2001, 0xffff,
+ 0x080c, 0x27da, 0x0005, 0x080c, 0x2913, 0x05c0, 0x2009, 0x1973,
+ 0x2104, 0x8001, 0x200a, 0x080c, 0x29f1, 0x1158, 0x7a38, 0x9294,
+ 0x0005, 0x9296, 0x0005, 0x0518, 0x2009, 0x1972, 0x2104, 0xc085,
+ 0x200a, 0x2009, 0x196f, 0x2104, 0x8000, 0x200a, 0x9086, 0x0005,
+ 0x0118, 0x080c, 0x291b, 0x00c0, 0x200b, 0x0000, 0x7a38, 0x9294,
+ 0x0006, 0x9296, 0x0004, 0x0110, 0x9006, 0x0010, 0x2001, 0x0001,
+ 0x080c, 0x29a3, 0x2001, 0x196c, 0x2003, 0x0002, 0x0028, 0x2001,
+ 0x196a, 0x2003, 0x0003, 0x0010, 0x080c, 0x27fc, 0x0005, 0x080c,
+ 0x2913, 0x0540, 0x2009, 0x1973, 0x2104, 0x8001, 0x200a, 0x080c,
+ 0x29f1, 0x1148, 0x2001, 0x196a, 0x2003, 0x0003, 0x2001, 0x196b,
+ 0x2003, 0x0000, 0x00b8, 0x2009, 0x1973, 0x2104, 0x9005, 0x1118,
+ 0x080c, 0x2958, 0x0010, 0x080c, 0x2928, 0x080c, 0x291b, 0x2009,
+ 0x196f, 0x200b, 0x0000, 0x2001, 0x196c, 0x2003, 0x0001, 0x080c,
+ 0x27fc, 0x0000, 0x0005, 0x0479, 0x01e8, 0x080c, 0x29f1, 0x1198,
+ 0x2009, 0x1970, 0x2104, 0x8000, 0x200a, 0x9086, 0x0007, 0x0108,
+ 0x0078, 0x2001, 0x1975, 0x2003, 0x000a, 0x2009, 0x1972, 0x2104,
+ 0xc0fd, 0x200a, 0x0038, 0x00f9, 0x2001, 0x196c, 0x2003, 0x0004,
+ 0x080c, 0x2827, 0x0005, 0x0079, 0x0148, 0x080c, 0x29f1, 0x1118,
+ 0x080c, 0x2813, 0x0018, 0x0079, 0x080c, 0x2827, 0x0005, 0x080c,
+ 0x0df6, 0x080c, 0x0df6, 0x2009, 0x1974, 0x2104, 0x8001, 0x200a,
+ 0x090c, 0x2974, 0x0005, 0x7a38, 0x9294, 0x0005, 0x9296, 0x0005,
+ 0x0110, 0x9006, 0x0010, 0x2001, 0x0001, 0x080c, 0x29a3, 0x0005,
+ 0x7a38, 0x9294, 0x0006, 0x9296, 0x0006, 0x0110, 0x9006, 0x0010,
+ 0x2001, 0x0001, 0x080c, 0x2986, 0x0005, 0x2009, 0x196f, 0x2104,
+ 0x8000, 0x200a, 0x9086, 0x0005, 0x0108, 0x0068, 0x200b, 0x0000,
+ 0x7a38, 0x9294, 0x0006, 0x9296, 0x0006, 0x0110, 0x9006, 0x0010,
+ 0x2001, 0x0001, 0x04d9, 0x7a38, 0x9294, 0x0005, 0x9296, 0x0005,
+ 0x0110, 0x9006, 0x0010, 0x2001, 0x0001, 0x080c, 0x29a3, 0x0005,
+ 0x0086, 0x2001, 0x1972, 0x2004, 0x9084, 0x7fff, 0x090c, 0x0df6,
+ 0x2009, 0x1971, 0x2144, 0x8846, 0x280a, 0x9844, 0x0dd8, 0xd08c,
+ 0x1120, 0xd084, 0x1120, 0x080c, 0x0df6, 0x9006, 0x0010, 0x2001,
+ 0x0001, 0x00a1, 0x008e, 0x0005, 0x0006, 0x0156, 0x2001, 0x196a,
+ 0x20a9, 0x0009, 0x2003, 0x0000, 0x8000, 0x1f04, 0x297a, 0x2001,
+ 0x1971, 0x2003, 0x8000, 0x015e, 0x000e, 0x0005, 0x00f6, 0x2079,
+ 0x0100, 0x9085, 0x0000, 0x0158, 0x7838, 0x9084, 0xfff9, 0x9085,
+ 0x0004, 0x783a, 0x2009, 0x1977, 0x210c, 0x795a, 0x0050, 0x7838,
+ 0x9084, 0xfffb, 0x9085, 0x0006, 0x783a, 0x2009, 0x1978, 0x210c,
+ 0x795a, 0x00fe, 0x0005, 0x00f6, 0x2079, 0x0100, 0x9085, 0x0000,
+ 0x0188, 0x7838, 0x9084, 0xfffa, 0x9085, 0x0004, 0x783a, 0x2001,
+ 0x0100, 0x2004, 0x9086, 0x000a, 0x1120, 0x7850, 0x9084, 0xfff0,
+ 0x7852, 0x0428, 0x7838, 0x9084, 0xfffb, 0x9085, 0x0005, 0x783a,
+ 0x2001, 0x0100, 0x2004, 0x9086, 0x000a, 0x11c8, 0x7850, 0x9084,
+ 0xfff0, 0x0016, 0x2009, 0x017f, 0x210c, 0x918e, 0x0005, 0x0140,
+ 0x2009, 0x0003, 0x210c, 0x918c, 0x0600, 0x918e, 0x0400, 0x0118,
+ 0x9085, 0x000a, 0x0010, 0x9085, 0x0000, 0x001e, 0x7852, 0x00fe,
+ 0x0005, 0x0006, 0x2001, 0x0100, 0x2004, 0x9082, 0x0007, 0x000e,
+ 0x0005, 0x0006, 0x2001, 0x0100, 0x2004, 0x9082, 0x0009, 0x000e,
+ 0x0005, 0x0156, 0x20a9, 0x0064, 0x7820, 0x080c, 0x2a97, 0xd09c,
+ 0x1110, 0x1f04, 0x29f4, 0x015e, 0x0005, 0x0126, 0x0016, 0x0006,
+ 0x2091, 0x8000, 0x2001, 0x0100, 0x2004, 0x9086, 0x000a, 0x0170,
+ 0x7850, 0x9085, 0x0040, 0x7852, 0x7850, 0x9084, 0xfbcf, 0x7852,
+ 0x080c, 0x2a97, 0x9085, 0x2000, 0x7852, 0x0000, 0x000e, 0x2008,
+ 0x9186, 0x0000, 0x1118, 0x783b, 0x0007, 0x0090, 0x9186, 0x0001,
+ 0x1118, 0x783b, 0x0006, 0x0060, 0x9186, 0x0002, 0x1118, 0x783b,
+ 0x0005, 0x0030, 0x9186, 0x0003, 0x1118, 0x783b, 0x0004, 0x0000,
+ 0x0006, 0x1d04, 0x2a31, 0x080c, 0x830d, 0x1f04, 0x2a31, 0x2001,
+ 0x0100, 0x2004, 0x9086, 0x000a, 0x0160, 0x7850, 0x9085, 0x0400,
+ 0x9084, 0xdfbf, 0x7852, 0x080c, 0x2a97, 0x9085, 0x1000, 0x7852,
+ 0x0020, 0x7850, 0x9085, 0x1000, 0x7852, 0x000e, 0x001e, 0x012e,
+ 0x0005, 0x2001, 0x0100, 0x2004, 0x9086, 0x000a, 0x0128, 0x7850,
+ 0x9084, 0xffcf, 0x7852, 0x0010, 0x080c, 0x2bdc, 0x0005, 0x0006,
+ 0x0156, 0x00f6, 0x2079, 0x0100, 0x20a9, 0x000a, 0x7854, 0xd0ac,
+ 0x1130, 0x7820, 0xd0e4, 0x1140, 0x1f04, 0x2a69, 0x0028, 0x7854,
+ 0xd08c, 0x1110, 0x1f04, 0x2a6f, 0x00fe, 0x015e, 0x000e, 0x0005,
+ 0x1d04, 0x2a78, 0x080c, 0x830d, 0x1f04, 0x2a78, 0x0005, 0x0006,
+ 0x2001, 0x1976, 0x2004, 0x9086, 0x0000, 0x000e, 0x0005, 0x0006,
+ 0x2001, 0x1976, 0x2004, 0x9086, 0x0001, 0x000e, 0x0005, 0x0006,
+ 0x2001, 0x1976, 0x2004, 0x9086, 0x0002, 0x000e, 0x0005, 0xa001,
+ 0xa001, 0xa001, 0xa001, 0xa001, 0x0005, 0x0006, 0x2001, 0x1983,
+ 0x2102, 0x000e, 0x0005, 0x2009, 0x0171, 0x2104, 0xd0dc, 0x0140,
+ 0x2009, 0x0170, 0x2104, 0x200b, 0x0080, 0xa001, 0xa001, 0x200a,
+ 0x0005, 0x0036, 0x0046, 0x2001, 0x0141, 0x200c, 0x918c, 0xff00,
+ 0x9186, 0x2100, 0x0140, 0x9186, 0x2000, 0x0170, 0x9186, 0x0100,
+ 0x1904, 0x2b10, 0x0048, 0x0016, 0x2009, 0x1a58, 0x2104, 0x8000,
+ 0x0208, 0x200a, 0x001e, 0x04f0, 0x2009, 0x00a2, 0x080c, 0x0e7b,
+ 0x2019, 0x0160, 0x2324, 0x2011, 0x0003, 0x2009, 0x0169, 0x2104,
+ 0x9084, 0x0007, 0x210c, 0x918c, 0x0007, 0x910e, 0x1db0, 0x9086,
+ 0x0003, 0x1548, 0x2304, 0x0066, 0x0076, 0x2031, 0x0002, 0x233c,
+ 0x973e, 0x0148, 0x8631, 0x1dd8, 0x2031, 0x1a59, 0x263c, 0x8738,
+ 0x0208, 0x2732, 0x2304, 0x007e, 0x006e, 0x9402, 0x02a0, 0x19d0,
+ 0x8211, 0x19d8, 0x84ff, 0x0170, 0x2001, 0x0141, 0x200c, 0x918c,
+ 0xff00, 0x9186, 0x0100, 0x0130, 0x2009, 0x180c, 0x2104, 0xc0dd,
+ 0x200a, 0x0008, 0x0421, 0x2001, 0x195b, 0x200c, 0x080c, 0x0e7b,
+ 0x004e, 0x003e, 0x0005, 0x2001, 0x180c, 0x2004, 0xd0dc, 0x01b0,
+ 0x2001, 0x0160, 0x2004, 0x9005, 0x0140, 0x2001, 0x0141, 0x2004,
+ 0x9084, 0xff00, 0x9086, 0x0100, 0x1148, 0x0126, 0x2091, 0x8000,
+ 0x0016, 0x0026, 0x0021, 0x002e, 0x001e, 0x012e, 0x0005, 0x00c6,
+ 0x2061, 0x0100, 0x6014, 0x0006, 0x2001, 0x0161, 0x2003, 0x0000,
+ 0x6017, 0x0018, 0xa001, 0xa001, 0x602f, 0x0008, 0x6104, 0x918e,
+ 0x0010, 0x6106, 0x918e, 0x0010, 0x6106, 0x6017, 0x0040, 0x04b9,
+ 0x001e, 0x9184, 0x0003, 0x01e0, 0x0036, 0x0016, 0x2019, 0x0141,
+ 0x6124, 0x918c, 0x0028, 0x1120, 0x2304, 0x9084, 0x2800, 0x0dc0,
+ 0x001e, 0x919c, 0xffe4, 0x9184, 0x0001, 0x0118, 0x9385, 0x0009,
+ 0x6016, 0x9184, 0x0002, 0x0118, 0x9385, 0x0012, 0x6016, 0x003e,
+ 0x2001, 0x180c, 0x200c, 0xc1dc, 0x2102, 0x00ce, 0x0005, 0x0016,
+ 0x0026, 0x080c, 0x7198, 0x0108, 0xc0bc, 0x2009, 0x0140, 0x2114,
+ 0x9294, 0x0001, 0x9215, 0x220a, 0x002e, 0x001e, 0x0005, 0x0016,
+ 0x0026, 0x2009, 0x0140, 0x2114, 0x9294, 0x0001, 0x9285, 0x1000,
+ 0x200a, 0x220a, 0x002e, 0x001e, 0x0005, 0x0016, 0x0026, 0x2009,
+ 0x0140, 0x2114, 0x9294, 0x0001, 0x9215, 0x220a, 0x002e, 0x001e,
+ 0x0005, 0x0006, 0x0016, 0x2009, 0x0140, 0x2104, 0x1128, 0x080c,
+ 0x7198, 0x0110, 0xc0bc, 0x0008, 0xc0bd, 0x200a, 0x001e, 0x000e,
+ 0x0005, 0x0016, 0x0026, 0x0036, 0x00c6, 0x2061, 0x0100, 0x6050,
+ 0x9084, 0xfbff, 0x9085, 0x0040, 0x6052, 0x20a9, 0x0002, 0x080c,
+ 0x2a78, 0x6050, 0x9085, 0x0400, 0x9084, 0xff9f, 0x6052, 0x20a9,
+ 0x0005, 0x080c, 0x2a78, 0x6054, 0xd0bc, 0x090c, 0x0df6, 0x20a9,
+ 0x0005, 0x080c, 0x2a78, 0x6054, 0xd0ac, 0x090c, 0x0df6, 0x2009,
+ 0x198a, 0x9084, 0x7e00, 0x8007, 0x8004, 0x8004, 0x200a, 0x00ce,
+ 0x003e, 0x002e, 0x001e, 0x0005, 0x0006, 0x00c6, 0x2061, 0x0100,
+ 0x6050, 0xc0cd, 0x6052, 0x00ce, 0x000e, 0x0005, 0x0006, 0x0156,
+ 0x6050, 0x9085, 0x0040, 0x6052, 0x6050, 0x9084, 0xfbcf, 0x6052,
+ 0x080c, 0x2a97, 0x9085, 0x2000, 0x6052, 0x20a9, 0x0012, 0x1d04,
+ 0x2bf7, 0x080c, 0x830d, 0x1f04, 0x2bf7, 0x6050, 0x9085, 0x0400,
+ 0x9084, 0xdfbf, 0x6052, 0x015e, 0x000e, 0x0005, 0x2e72, 0x2e72,
+ 0x2c96, 0x2c96, 0x2ca2, 0x2ca2, 0x2cae, 0x2cae, 0x2cbc, 0x2cbc,
+ 0x2cc8, 0x2cc8, 0x2cd6, 0x2cd6, 0x2ce4, 0x2ce4, 0x2cf6, 0x2cf6,
+ 0x2d02, 0x2d02, 0x2d10, 0x2d10, 0x2d2e, 0x2d2e, 0x2d4e, 0x2d4e,
+ 0x2d1e, 0x2d1e, 0x2d3e, 0x2d3e, 0x2d5c, 0x2d5c, 0x2cf4, 0x2cf4,
+ 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4,
+ 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4,
+ 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4,
+ 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, 0x2d6e, 0x2d6e,
+ 0x2d7a, 0x2d7a, 0x2d88, 0x2d88, 0x2d96, 0x2d96, 0x2da6, 0x2da6,
+ 0x2db4, 0x2db4, 0x2dc4, 0x2dc4, 0x2dd4, 0x2dd4, 0x2de6, 0x2de6,
+ 0x2df4, 0x2df4, 0x2e04, 0x2e04, 0x2e26, 0x2e26, 0x2e48, 0x2e48,
+ 0x2e14, 0x2e14, 0x2e37, 0x2e37, 0x2e57, 0x2e57, 0x2cf4, 0x2cf4,
+ 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4,
+ 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4,
+ 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4,
+ 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4,
+ 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4,
+ 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, 0x2cf4, 0x0106, 0x0006,
+ 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x22bc,
+ 0x0804, 0x2e6a, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136,
+ 0x0146, 0x0156, 0x080c, 0x20c3, 0x0804, 0x2e6a, 0x0106, 0x0006,
+ 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x20c3,
+ 0x080c, 0x22bc, 0x0804, 0x2e6a, 0x0106, 0x0006, 0x0126, 0x01c6,
+ 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x20fe, 0x0804, 0x2e6a,
0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156,
- 0x080c, 0x2771, 0x080c, 0x20c7, 0x080c, 0x1371, 0x080c, 0x2102,
- 0x0410, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146,
- 0x0156, 0x080c, 0x2771, 0x080c, 0x1371, 0x080c, 0x2102, 0x0098,
+ 0x080c, 0x22bc, 0x080c, 0x20fe, 0x0804, 0x2e6a, 0x0106, 0x0006,
+ 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x20c3,
+ 0x080c, 0x20fe, 0x0804, 0x2e6a, 0x0106, 0x0006, 0x0126, 0x01c6,
+ 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x20c3, 0x080c, 0x22bc,
+ 0x080c, 0x20fe, 0x0804, 0x2e6a, 0xa001, 0x0cf0, 0x0106, 0x0006,
+ 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x1365,
+ 0x0804, 0x2e6a, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136,
+ 0x0146, 0x0156, 0x080c, 0x22bc, 0x080c, 0x1365, 0x0804, 0x2e6a,
0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156,
- 0x080c, 0x2771, 0x080c, 0x20c7, 0x080c, 0x22c0, 0x080c, 0x1371,
- 0x080c, 0x2102, 0x0000, 0x015e, 0x014e, 0x013e, 0x01de, 0x01ce,
- 0x012e, 0x000e, 0x010e, 0x000d, 0x00b6, 0x00c6, 0x0026, 0x0046,
- 0x9026, 0x080c, 0x6688, 0x1904, 0x2f92, 0x72d8, 0x2001, 0x1956,
- 0x2004, 0x9005, 0x1110, 0xd29c, 0x0148, 0xd284, 0x1138, 0xd2bc,
- 0x1904, 0x2f92, 0x080c, 0x2f97, 0x0804, 0x2f92, 0xd2cc, 0x1904,
- 0x2f92, 0x080c, 0x717f, 0x1120, 0x70ab, 0xffff, 0x0804, 0x2f92,
- 0xd294, 0x0120, 0x70ab, 0xffff, 0x0804, 0x2f92, 0x080c, 0x31ff,
- 0x0160, 0x080c, 0xc444, 0x0128, 0x2001, 0x1817, 0x203c, 0x0804,
- 0x2f24, 0x70ab, 0xffff, 0x0804, 0x2f92, 0x2001, 0x1817, 0x203c,
- 0x7290, 0xd284, 0x0904, 0x2f24, 0xd28c, 0x1904, 0x2f24, 0x0036,
- 0x73a8, 0x938e, 0xffff, 0x1110, 0x2019, 0x0001, 0x8314, 0x92e0,
- 0x1c80, 0x2c04, 0x938c, 0x0001, 0x0120, 0x9084, 0xff00, 0x8007,
- 0x0010, 0x9084, 0x00ff, 0x970e, 0x05a8, 0x908e, 0x0000, 0x0590,
- 0x908e, 0x00ff, 0x1150, 0x7230, 0xd284, 0x1588, 0x7290, 0xc28d,
- 0x7292, 0x70ab, 0xffff, 0x003e, 0x0478, 0x0026, 0x2011, 0x0010,
- 0x080c, 0x66ee, 0x002e, 0x0118, 0x70ab, 0xffff, 0x0410, 0x900e,
- 0x080c, 0x266e, 0x080c, 0x6344, 0x11c0, 0x080c, 0x66ca, 0x1168,
- 0x7030, 0xd08c, 0x0130, 0xb800, 0xd0bc, 0x0138, 0x080c, 0x65c4,
- 0x0120, 0x080c, 0x2fb0, 0x0148, 0x0028, 0x080c, 0x30f0, 0x080c,
- 0x2fdc, 0x0118, 0x8318, 0x0804, 0x2ed6, 0x73aa, 0x0010, 0x70ab,
- 0xffff, 0x003e, 0x0804, 0x2f92, 0x9780, 0x3209, 0x203d, 0x97bc,
- 0xff00, 0x873f, 0x2041, 0x007e, 0x70a8, 0x9096, 0xffff, 0x1118,
- 0x900e, 0x28a8, 0x0050, 0x9812, 0x0220, 0x2008, 0x9802, 0x20a8,
- 0x0020, 0x70ab, 0xffff, 0x0804, 0x2f92, 0x2700, 0x0156, 0x0016,
- 0x9106, 0x0904, 0x2f87, 0x0026, 0x2011, 0x0010, 0x080c, 0x66ee,
- 0x002e, 0x0120, 0x2009, 0xffff, 0x0804, 0x2f8f, 0xc484, 0x080c,
- 0x63a4, 0x0138, 0x080c, 0xc444, 0x1590, 0x080c, 0x6344, 0x15b8,
- 0x0008, 0xc485, 0x080c, 0x66ca, 0x1130, 0x7030, 0xd08c, 0x01f8,
- 0xb800, 0xd0bc, 0x11e0, 0x7290, 0xd28c, 0x0180, 0x080c, 0x66ca,
- 0x9082, 0x0006, 0x02e0, 0xd484, 0x1118, 0x080c, 0x6368, 0x0028,
- 0x080c, 0x317b, 0x01a0, 0x080c, 0x31a6, 0x0088, 0x080c, 0x30f0,
- 0x080c, 0xc444, 0x1160, 0x080c, 0x2fdc, 0x0188, 0x0040, 0x080c,
- 0xc444, 0x1118, 0x080c, 0x317b, 0x0110, 0x0451, 0x0140, 0x001e,
- 0x8108, 0x015e, 0x1f04, 0x2f3d, 0x70ab, 0xffff, 0x0018, 0x001e,
- 0x015e, 0x71aa, 0x004e, 0x002e, 0x00ce, 0x00be, 0x0005, 0x00c6,
- 0x0016, 0x70ab, 0x0001, 0x2009, 0x007e, 0x080c, 0x6344, 0x1168,
- 0xb813, 0x00ff, 0xb817, 0xfffe, 0x080c, 0x30f0, 0x04a9, 0x0128,
- 0x70d8, 0xc0bd, 0x70da, 0x080c, 0xc18e, 0x001e, 0x00ce, 0x0005,
- 0x0016, 0x0076, 0x00d6, 0x00c6, 0x2001, 0x1860, 0x2004, 0x9084,
- 0x00ff, 0xb842, 0x080c, 0xa026, 0x01d0, 0x2b00, 0x6012, 0x080c,
- 0xc1b7, 0x6023, 0x0001, 0x9006, 0x080c, 0x62e1, 0x2001, 0x0000,
- 0x080c, 0x62f5, 0x0126, 0x2091, 0x8000, 0x70a4, 0x8000, 0x70a6,
- 0x012e, 0x2009, 0x0004, 0x080c, 0xa053, 0x9085, 0x0001, 0x00ce,
- 0x00de, 0x007e, 0x001e, 0x0005, 0x0016, 0x0076, 0x00d6, 0x00c6,
- 0x2001, 0x1860, 0x2004, 0x9084, 0x00ff, 0xb842, 0x080c, 0xa026,
- 0x0548, 0x2b00, 0x6012, 0xb800, 0xc0c4, 0xb802, 0xb8a0, 0x9086,
- 0x007e, 0x0140, 0xb804, 0x9084, 0x00ff, 0x9086, 0x0006, 0x1110,
- 0x080c, 0x30ab, 0x080c, 0xc1b7, 0x6023, 0x0001, 0x9006, 0x080c,
- 0x62e1, 0x2001, 0x0002, 0x080c, 0x62f5, 0x0126, 0x2091, 0x8000,
- 0x70a4, 0x8000, 0x70a6, 0x012e, 0x2009, 0x0002, 0x080c, 0xa053,
- 0x9085, 0x0001, 0x00ce, 0x00de, 0x007e, 0x001e, 0x0005, 0x00b6,
- 0x00c6, 0x0026, 0x2009, 0x0080, 0x080c, 0x6344, 0x1140, 0xb813,
- 0x00ff, 0xb817, 0xfffc, 0x0039, 0x0110, 0x70df, 0xffff, 0x002e,
- 0x00ce, 0x00be, 0x0005, 0x0016, 0x0076, 0x00d6, 0x00c6, 0x080c,
- 0x9f7f, 0x01d0, 0x2b00, 0x6012, 0x080c, 0xc1b7, 0x6023, 0x0001,
- 0x9006, 0x080c, 0x62e1, 0x2001, 0x0002, 0x080c, 0x62f5, 0x0126,
- 0x2091, 0x8000, 0x70e0, 0x8000, 0x70e2, 0x012e, 0x2009, 0x0002,
- 0x080c, 0xa053, 0x9085, 0x0001, 0x00ce, 0x00de, 0x007e, 0x001e,
- 0x0005, 0x00c6, 0x00d6, 0x0126, 0x2091, 0x8000, 0x2009, 0x007f,
- 0x080c, 0x6344, 0x11b8, 0xb813, 0x00ff, 0xb817, 0xfffd, 0xb8bf,
- 0x0004, 0x080c, 0x9f7f, 0x0170, 0x2b00, 0x6012, 0x6316, 0x6023,
- 0x0001, 0x620a, 0x080c, 0xc1b7, 0x2009, 0x0022, 0x080c, 0xa053,
- 0x9085, 0x0001, 0x012e, 0x00de, 0x00ce, 0x0005, 0x00e6, 0x00c6,
- 0x0066, 0x0036, 0x0026, 0x00b6, 0x21f0, 0x080c, 0x878e, 0x080c,
- 0x8718, 0x080c, 0x9e28, 0x080c, 0xaf75, 0x3e08, 0x2130, 0x81ff,
- 0x0120, 0x20a9, 0x007e, 0x900e, 0x0018, 0x20a9, 0x007f, 0x900e,
- 0x0016, 0x080c, 0x63a4, 0x1140, 0x9686, 0x0002, 0x1118, 0xb800,
- 0xd0bc, 0x1110, 0x080c, 0x5e4a, 0x001e, 0x8108, 0x1f04, 0x3090,
- 0x9686, 0x0001, 0x190c, 0x31d3, 0x00be, 0x002e, 0x003e, 0x006e,
- 0x00ce, 0x00ee, 0x0005, 0x00e6, 0x00c6, 0x0046, 0x0036, 0x0026,
- 0x0016, 0x00b6, 0x6210, 0x2258, 0xbaa0, 0x0026, 0x2019, 0x0029,
- 0x080c, 0x8783, 0x0076, 0x2039, 0x0000, 0x080c, 0x8671, 0x2c08,
- 0x080c, 0xd53b, 0x007e, 0x001e, 0xba10, 0xbb14, 0xbcb0, 0x080c,
- 0x5e4a, 0xba12, 0xbb16, 0xbcb2, 0x00be, 0x001e, 0x002e, 0x003e,
- 0x004e, 0x00ce, 0x00ee, 0x0005, 0x00e6, 0x0006, 0x00b6, 0x6010,
- 0x2058, 0xb8a0, 0x00be, 0x9086, 0x0080, 0x0150, 0x2071, 0x1800,
- 0x70a4, 0x9005, 0x0110, 0x8001, 0x70a6, 0x000e, 0x00ee, 0x0005,
- 0x2071, 0x1800, 0x70e0, 0x9005, 0x0dc0, 0x8001, 0x70e2, 0x0ca8,
- 0xb800, 0xc08c, 0xb802, 0x0005, 0x00f6, 0x00e6, 0x00c6, 0x00b6,
- 0x0046, 0x0036, 0x0026, 0x0016, 0x0156, 0x2178, 0x81ff, 0x1118,
- 0x20a9, 0x0001, 0x0070, 0x080c, 0x54dc, 0xd0c4, 0x0138, 0x0030,
- 0x9006, 0x2020, 0x2009, 0x002d, 0x080c, 0xd7d6, 0x20a9, 0x0800,
- 0x9016, 0x0026, 0x928e, 0x007e, 0x0904, 0x315a, 0x928e, 0x007f,
- 0x0904, 0x315a, 0x928e, 0x0080, 0x05e8, 0x9288, 0x1000, 0x210c,
- 0x81ff, 0x05c0, 0x8fff, 0x1148, 0x2001, 0x1968, 0x0006, 0x2003,
- 0x0001, 0x04f1, 0x000e, 0x2003, 0x0000, 0x00b6, 0x00c6, 0x2158,
- 0x2001, 0x0001, 0x080c, 0x6694, 0x00ce, 0x00be, 0x2019, 0x0029,
- 0x080c, 0x8783, 0x0076, 0x2039, 0x0000, 0x080c, 0x8671, 0x00b6,
- 0x00c6, 0x0026, 0x2158, 0xba04, 0x9294, 0x00ff, 0x9286, 0x0006,
- 0x1118, 0xb807, 0x0404, 0x0028, 0x2001, 0x0004, 0x8007, 0x9215,
- 0xba06, 0x002e, 0x00ce, 0x00be, 0x0016, 0x2c08, 0x080c, 0xd53b,
- 0x001e, 0x007e, 0x002e, 0x8210, 0x1f04, 0x3111, 0x015e, 0x001e,
- 0x002e, 0x003e, 0x004e, 0x00be, 0x00ce, 0x00ee, 0x00fe, 0x0005,
- 0x0046, 0x0026, 0x0016, 0x080c, 0x54dc, 0xd0c4, 0x0140, 0xd0a4,
- 0x0130, 0x9006, 0x2220, 0x2009, 0x0029, 0x080c, 0xd7d6, 0x001e,
- 0x002e, 0x004e, 0x0005, 0x0016, 0x0026, 0x0036, 0x00c6, 0x7290,
- 0x82ff, 0x01e8, 0x080c, 0x66c2, 0x11d0, 0x2100, 0x080c, 0x26a1,
- 0x81ff, 0x01b8, 0x2019, 0x0001, 0x8314, 0x92e0, 0x1c80, 0x2c04,
- 0xd384, 0x0120, 0x9084, 0xff00, 0x8007, 0x0010, 0x9084, 0x00ff,
- 0x9116, 0x0138, 0x9096, 0x00ff, 0x0110, 0x8318, 0x0c68, 0x9085,
- 0x0001, 0x00ce, 0x003e, 0x002e, 0x001e, 0x0005, 0x0016, 0x00c6,
- 0x0126, 0x2091, 0x8000, 0x0036, 0x2019, 0x0029, 0x00a9, 0x003e,
- 0x9180, 0x1000, 0x2004, 0x9065, 0x0158, 0x0016, 0x00c6, 0x2061,
- 0x1a88, 0x001e, 0x6112, 0x080c, 0x30ab, 0x001e, 0x080c, 0x6368,
- 0x012e, 0x00ce, 0x001e, 0x0005, 0x0016, 0x0026, 0x2110, 0x080c,
- 0x9abb, 0x080c, 0xda8f, 0x002e, 0x001e, 0x0005, 0x2001, 0x1836,
- 0x2004, 0xd0cc, 0x0005, 0x00c6, 0x00b6, 0x080c, 0x717f, 0x1118,
- 0x20a9, 0x0800, 0x0010, 0x20a9, 0x0782, 0x080c, 0x717f, 0x1110,
- 0x900e, 0x0010, 0x2009, 0x007e, 0x9180, 0x1000, 0x2004, 0x905d,
- 0x0130, 0x86ff, 0x0110, 0xb800, 0xd0bc, 0x090c, 0x6368, 0x8108,
- 0x1f04, 0x31e4, 0x2061, 0x1800, 0x607b, 0x0000, 0x607c, 0x9084,
- 0x00ff, 0x607e, 0x60af, 0x0000, 0x00be, 0x00ce, 0x0005, 0x2001,
- 0x187d, 0x2004, 0xd0bc, 0x0005, 0x2011, 0x185c, 0x2214, 0xd2ec,
- 0x0005, 0x7eef, 0x7de8, 0x7ce4, 0x80e2, 0x7be1, 0x80e0, 0x80dc,
- 0x80da, 0x7ad9, 0x80d6, 0x80d5, 0x80d4, 0x80d3, 0x80d2, 0x80d1,
- 0x79ce, 0x78cd, 0x80cc, 0x80cb, 0x80ca, 0x80c9, 0x80c7, 0x80c6,
- 0x77c5, 0x76c3, 0x80bc, 0x80ba, 0x75b9, 0x80b6, 0x74b5, 0x73b4,
- 0x72b3, 0x80b2, 0x80b1, 0x80ae, 0x71ad, 0x80ac, 0x70ab, 0x6faa,
- 0x6ea9, 0x80a7, 0x6da6, 0x6ca5, 0x6ba3, 0x6a9f, 0x699e, 0x689d,
- 0x809b, 0x8098, 0x6797, 0x6690, 0x658f, 0x6488, 0x6384, 0x6282,
- 0x8081, 0x8080, 0x617c, 0x607a, 0x8079, 0x5f76, 0x8075, 0x8074,
- 0x8073, 0x8072, 0x8071, 0x806e, 0x5e6d, 0x806c, 0x5d6b, 0x5c6a,
- 0x5b69, 0x8067, 0x5a66, 0x5965, 0x5863, 0x575c, 0x565a, 0x5559,
- 0x8056, 0x8055, 0x5454, 0x5353, 0x5252, 0x5151, 0x504e, 0x4f4d,
- 0x804c, 0x804b, 0x4e4a, 0x4d49, 0x8047, 0x4c46, 0x8045, 0x8043,
- 0x803c, 0x803a, 0x8039, 0x8036, 0x4b35, 0x8034, 0x4a33, 0x4932,
- 0x4831, 0x802e, 0x472d, 0x462c, 0x452b, 0x442a, 0x4329, 0x4227,
- 0x8026, 0x8025, 0x4123, 0x401f, 0x3f1e, 0x3e1d, 0x3d1b, 0x3c18,
- 0x8017, 0x8010, 0x3b0f, 0x3a08, 0x8004, 0x3902, 0x8001, 0x8000,
- 0x8000, 0x3800, 0x3700, 0x3600, 0x8000, 0x3500, 0x8000, 0x8000,
- 0x8000, 0x3400, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
- 0x3300, 0x3200, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
- 0x3100, 0x3000, 0x8000, 0x8000, 0x2f00, 0x8000, 0x2e00, 0x2d00,
- 0x2c00, 0x8000, 0x8000, 0x8000, 0x2b00, 0x8000, 0x2a00, 0x2900,
- 0x2800, 0x8000, 0x2700, 0x2600, 0x2500, 0x2400, 0x2300, 0x2200,
- 0x8000, 0x8000, 0x2100, 0x2000, 0x1f00, 0x1e00, 0x1d00, 0x1c00,
- 0x8000, 0x8000, 0x1b00, 0x1a00, 0x8000, 0x1900, 0x8000, 0x8000,
- 0x8000, 0x8000, 0x8000, 0x8000, 0x1800, 0x8000, 0x1700, 0x1600,
- 0x1500, 0x8000, 0x1400, 0x1300, 0x1200, 0x1100, 0x1000, 0x0f00,
- 0x8000, 0x8000, 0x0e00, 0x0d00, 0x0c00, 0x0b00, 0x0a00, 0x0900,
- 0x8000, 0x8000, 0x0800, 0x0700, 0x8000, 0x0600, 0x8000, 0x8000,
- 0x8000, 0x0500, 0x0400, 0x0300, 0x8000, 0x0200, 0x8000, 0x8000,
- 0x8000, 0x0100, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
- 0x0000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
+ 0x080c, 0x20c3, 0x080c, 0x1365, 0x0804, 0x2e6a, 0x0106, 0x0006,
+ 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x22bc,
+ 0x080c, 0x1365, 0x080c, 0x20fe, 0x0804, 0x2e6a, 0x0106, 0x0006,
+ 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x20c3,
+ 0x080c, 0x22bc, 0x080c, 0x1365, 0x0804, 0x2e6a, 0x0106, 0x0006,
+ 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x20c3,
+ 0x080c, 0x1365, 0x080c, 0x20fe, 0x0804, 0x2e6a, 0x0106, 0x0006,
+ 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x1365,
+ 0x080c, 0x20fe, 0x0804, 0x2e6a, 0x0106, 0x0006, 0x0126, 0x01c6,
+ 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x20c3, 0x080c, 0x22bc,
+ 0x080c, 0x1365, 0x080c, 0x20fe, 0x0804, 0x2e6a, 0x0106, 0x0006,
+ 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2770,
+ 0x0804, 0x2e6a, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136,
+ 0x0146, 0x0156, 0x080c, 0x2770, 0x080c, 0x22bc, 0x0804, 0x2e6a,
+ 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156,
+ 0x080c, 0x2770, 0x080c, 0x20c3, 0x0804, 0x2e6a, 0x0106, 0x0006,
+ 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2770,
+ 0x080c, 0x20c3, 0x080c, 0x22bc, 0x0804, 0x2e6a, 0x0106, 0x0006,
+ 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2770,
+ 0x080c, 0x20fe, 0x0804, 0x2e6a, 0x0106, 0x0006, 0x0126, 0x01c6,
+ 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2770, 0x080c, 0x22bc,
+ 0x080c, 0x20fe, 0x0804, 0x2e6a, 0x0106, 0x0006, 0x0126, 0x01c6,
+ 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2770, 0x080c, 0x20c3,
+ 0x080c, 0x20fe, 0x0804, 0x2e6a, 0x0106, 0x0006, 0x0126, 0x01c6,
+ 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2770, 0x080c, 0x20c3,
+ 0x080c, 0x22bc, 0x080c, 0x20fe, 0x0804, 0x2e6a, 0x0106, 0x0006,
+ 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2770,
+ 0x080c, 0x1365, 0x0804, 0x2e6a, 0x0106, 0x0006, 0x0126, 0x01c6,
+ 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2770, 0x080c, 0x22bc,
+ 0x080c, 0x1365, 0x0804, 0x2e6a, 0x0106, 0x0006, 0x0126, 0x01c6,
+ 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2770, 0x080c, 0x20c3,
+ 0x080c, 0x1365, 0x0804, 0x2e6a, 0x0106, 0x0006, 0x0126, 0x01c6,
+ 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2770, 0x080c, 0x22bc,
+ 0x080c, 0x1365, 0x080c, 0x20fe, 0x0804, 0x2e6a, 0x0106, 0x0006,
+ 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2770,
+ 0x080c, 0x20c3, 0x080c, 0x22bc, 0x080c, 0x1365, 0x0498, 0x0106,
+ 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c,
+ 0x2770, 0x080c, 0x20c3, 0x080c, 0x1365, 0x080c, 0x20fe, 0x0410,
+ 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156,
+ 0x080c, 0x2770, 0x080c, 0x1365, 0x080c, 0x20fe, 0x0098, 0x0106,
+ 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c,
+ 0x2770, 0x080c, 0x20c3, 0x080c, 0x22bc, 0x080c, 0x1365, 0x080c,
+ 0x20fe, 0x0000, 0x015e, 0x014e, 0x013e, 0x01de, 0x01ce, 0x012e,
+ 0x000e, 0x010e, 0x000d, 0x00b6, 0x00c6, 0x0026, 0x0046, 0x9026,
+ 0x080c, 0x6687, 0x1904, 0x2f7c, 0x72d8, 0x2001, 0x1956, 0x2004,
+ 0x9005, 0x1110, 0xd29c, 0x0148, 0xd284, 0x1138, 0xd2bc, 0x1904,
+ 0x2f7c, 0x080c, 0x2f81, 0x0804, 0x2f7c, 0xd2cc, 0x1904, 0x2f7c,
+ 0x080c, 0x717e, 0x1120, 0x70ab, 0xffff, 0x0804, 0x2f7c, 0xd294,
+ 0x0120, 0x70ab, 0xffff, 0x0804, 0x2f7c, 0x080c, 0x31e9, 0x0160,
+ 0x080c, 0xc459, 0x0128, 0x2001, 0x1817, 0x203c, 0x0804, 0x2f0b,
+ 0x70ab, 0xffff, 0x0804, 0x2f7c, 0x2001, 0x1817, 0x203c, 0x7290,
+ 0xd284, 0x0904, 0x2f0b, 0xd28c, 0x1904, 0x2f0b, 0x0036, 0x73a8,
+ 0x938e, 0xffff, 0x1110, 0x2019, 0x0001, 0x8314, 0x92e0, 0x1c80,
+ 0x2c04, 0x938c, 0x0001, 0x0120, 0x9084, 0xff00, 0x8007, 0x0010,
+ 0x9084, 0x00ff, 0x970e, 0x05a8, 0x908e, 0x0000, 0x0590, 0x908e,
+ 0x00ff, 0x1150, 0x7230, 0xd284, 0x1588, 0x7290, 0xc28d, 0x7292,
+ 0x70ab, 0xffff, 0x003e, 0x0478, 0x0026, 0x2011, 0x0010, 0x080c,
+ 0x66ed, 0x002e, 0x0118, 0x70ab, 0xffff, 0x0410, 0x900e, 0x080c,
+ 0x266d, 0x080c, 0x6343, 0x11c0, 0x080c, 0x66c9, 0x1168, 0x7030,
+ 0xd08c, 0x0130, 0xb800, 0xd0bc, 0x0138, 0x080c, 0x65c3, 0x0120,
+ 0x080c, 0x2f9a, 0x0148, 0x0028, 0x080c, 0x30da, 0x080c, 0x2fc6,
+ 0x0118, 0x8318, 0x0804, 0x2ebd, 0x73aa, 0x0010, 0x70ab, 0xffff,
+ 0x003e, 0x0804, 0x2f7c, 0x9780, 0x31f3, 0x203d, 0x97bc, 0xff00,
+ 0x873f, 0x2041, 0x007e, 0x70a8, 0x9096, 0xffff, 0x1118, 0x900e,
+ 0x28a8, 0x0050, 0x9812, 0x0220, 0x2008, 0x9802, 0x20a8, 0x0020,
+ 0x70ab, 0xffff, 0x0804, 0x2f7c, 0x2700, 0x0156, 0x0016, 0x9106,
+ 0x0904, 0x2f71, 0x0026, 0x2011, 0x0010, 0x080c, 0x66ed, 0x002e,
+ 0x0120, 0x2009, 0xffff, 0x0804, 0x2f79, 0xc484, 0x080c, 0x63a3,
+ 0x0150, 0x080c, 0xc459, 0x15a8, 0x080c, 0x31e9, 0x1590, 0x080c,
+ 0x6343, 0x15b8, 0x0008, 0xc485, 0x080c, 0x66c9, 0x1130, 0x7030,
+ 0xd08c, 0x01f8, 0xb800, 0xd0bc, 0x11e0, 0x7290, 0xd28c, 0x0180,
+ 0x080c, 0x66c9, 0x9082, 0x0006, 0x02e0, 0xd484, 0x1118, 0x080c,
+ 0x6367, 0x0028, 0x080c, 0x3165, 0x01a0, 0x080c, 0x3190, 0x0088,
+ 0x080c, 0x30da, 0x080c, 0xc459, 0x1160, 0x080c, 0x2fc6, 0x0188,
+ 0x0040, 0x080c, 0xc459, 0x1118, 0x080c, 0x3165, 0x0110, 0x0451,
+ 0x0140, 0x001e, 0x8108, 0x015e, 0x1f04, 0x2f24, 0x70ab, 0xffff,
+ 0x0018, 0x001e, 0x015e, 0x71aa, 0x004e, 0x002e, 0x00ce, 0x00be,
+ 0x0005, 0x00c6, 0x0016, 0x70ab, 0x0001, 0x2009, 0x007e, 0x080c,
+ 0x6343, 0x1168, 0xb813, 0x00ff, 0xb817, 0xfffe, 0x080c, 0x30da,
+ 0x04a9, 0x0128, 0x70d8, 0xc0bd, 0x70da, 0x080c, 0xc1a1, 0x001e,
+ 0x00ce, 0x0005, 0x0016, 0x0076, 0x00d6, 0x00c6, 0x2001, 0x1860,
+ 0x2004, 0x9084, 0x00ff, 0xb842, 0x080c, 0xa03b, 0x01d0, 0x2b00,
+ 0x6012, 0x080c, 0xc1ca, 0x6023, 0x0001, 0x9006, 0x080c, 0x62e0,
+ 0x2001, 0x0000, 0x080c, 0x62f4, 0x0126, 0x2091, 0x8000, 0x70a4,
+ 0x8000, 0x70a6, 0x012e, 0x2009, 0x0004, 0x080c, 0xa068, 0x9085,
+ 0x0001, 0x00ce, 0x00de, 0x007e, 0x001e, 0x0005, 0x0016, 0x0076,
+ 0x00d6, 0x00c6, 0x2001, 0x1860, 0x2004, 0x9084, 0x00ff, 0xb842,
+ 0x080c, 0xa03b, 0x0548, 0x2b00, 0x6012, 0xb800, 0xc0c4, 0xb802,
+ 0xb8a0, 0x9086, 0x007e, 0x0140, 0xb804, 0x9084, 0x00ff, 0x9086,
+ 0x0006, 0x1110, 0x080c, 0x3095, 0x080c, 0xc1ca, 0x6023, 0x0001,
+ 0x9006, 0x080c, 0x62e0, 0x2001, 0x0002, 0x080c, 0x62f4, 0x0126,
+ 0x2091, 0x8000, 0x70a4, 0x8000, 0x70a6, 0x012e, 0x2009, 0x0002,
+ 0x080c, 0xa068, 0x9085, 0x0001, 0x00ce, 0x00de, 0x007e, 0x001e,
+ 0x0005, 0x00b6, 0x00c6, 0x0026, 0x2009, 0x0080, 0x080c, 0x6343,
+ 0x1140, 0xb813, 0x00ff, 0xb817, 0xfffc, 0x0039, 0x0110, 0x70df,
+ 0xffff, 0x002e, 0x00ce, 0x00be, 0x0005, 0x0016, 0x0076, 0x00d6,
+ 0x00c6, 0x080c, 0x9f94, 0x01d0, 0x2b00, 0x6012, 0x080c, 0xc1ca,
+ 0x6023, 0x0001, 0x9006, 0x080c, 0x62e0, 0x2001, 0x0002, 0x080c,
+ 0x62f4, 0x0126, 0x2091, 0x8000, 0x70e0, 0x8000, 0x70e2, 0x012e,
+ 0x2009, 0x0002, 0x080c, 0xa068, 0x9085, 0x0001, 0x00ce, 0x00de,
+ 0x007e, 0x001e, 0x0005, 0x00c6, 0x00d6, 0x0126, 0x2091, 0x8000,
+ 0x2009, 0x007f, 0x080c, 0x6343, 0x11b8, 0xb813, 0x00ff, 0xb817,
+ 0xfffd, 0xb8bf, 0x0004, 0x080c, 0x9f94, 0x0170, 0x2b00, 0x6012,
+ 0x6316, 0x6023, 0x0001, 0x620a, 0x080c, 0xc1ca, 0x2009, 0x0022,
+ 0x080c, 0xa068, 0x9085, 0x0001, 0x012e, 0x00de, 0x00ce, 0x0005,
+ 0x00e6, 0x00c6, 0x0066, 0x0036, 0x0026, 0x00b6, 0x21f0, 0x080c,
+ 0x878d, 0x080c, 0x8717, 0x080c, 0x9e3d, 0x080c, 0xaf81, 0x3e08,
+ 0x2130, 0x81ff, 0x0120, 0x20a9, 0x007e, 0x900e, 0x0018, 0x20a9,
+ 0x007f, 0x900e, 0x0016, 0x080c, 0x63a3, 0x1140, 0x9686, 0x0002,
+ 0x1118, 0xb800, 0xd0bc, 0x1110, 0x080c, 0x5e49, 0x001e, 0x8108,
+ 0x1f04, 0x307a, 0x9686, 0x0001, 0x190c, 0x31bd, 0x00be, 0x002e,
+ 0x003e, 0x006e, 0x00ce, 0x00ee, 0x0005, 0x00e6, 0x00c6, 0x0046,
+ 0x0036, 0x0026, 0x0016, 0x00b6, 0x6210, 0x2258, 0xbaa0, 0x0026,
+ 0x2019, 0x0029, 0x080c, 0x8782, 0x0076, 0x2039, 0x0000, 0x080c,
+ 0x8670, 0x2c08, 0x080c, 0xd556, 0x007e, 0x001e, 0xba10, 0xbb14,
+ 0xbcb0, 0x080c, 0x5e49, 0xba12, 0xbb16, 0xbcb2, 0x00be, 0x001e,
+ 0x002e, 0x003e, 0x004e, 0x00ce, 0x00ee, 0x0005, 0x00e6, 0x0006,
+ 0x00b6, 0x6010, 0x2058, 0xb8a0, 0x00be, 0x9086, 0x0080, 0x0150,
+ 0x2071, 0x1800, 0x70a4, 0x9005, 0x0110, 0x8001, 0x70a6, 0x000e,
+ 0x00ee, 0x0005, 0x2071, 0x1800, 0x70e0, 0x9005, 0x0dc0, 0x8001,
+ 0x70e2, 0x0ca8, 0xb800, 0xc08c, 0xb802, 0x0005, 0x00f6, 0x00e6,
+ 0x00c6, 0x00b6, 0x0046, 0x0036, 0x0026, 0x0016, 0x0156, 0x2178,
+ 0x81ff, 0x1118, 0x20a9, 0x0001, 0x0070, 0x080c, 0x54db, 0xd0c4,
+ 0x0138, 0x0030, 0x9006, 0x2020, 0x2009, 0x002d, 0x080c, 0xd837,
+ 0x20a9, 0x0800, 0x9016, 0x0026, 0x928e, 0x007e, 0x0904, 0x3144,
+ 0x928e, 0x007f, 0x0904, 0x3144, 0x928e, 0x0080, 0x05e8, 0x9288,
+ 0x1000, 0x210c, 0x81ff, 0x05c0, 0x8fff, 0x1148, 0x2001, 0x1968,
+ 0x0006, 0x2003, 0x0001, 0x04f1, 0x000e, 0x2003, 0x0000, 0x00b6,
+ 0x00c6, 0x2158, 0x2001, 0x0001, 0x080c, 0x6693, 0x00ce, 0x00be,
+ 0x2019, 0x0029, 0x080c, 0x8782, 0x0076, 0x2039, 0x0000, 0x080c,
+ 0x8670, 0x00b6, 0x00c6, 0x0026, 0x2158, 0xba04, 0x9294, 0x00ff,
+ 0x9286, 0x0006, 0x1118, 0xb807, 0x0404, 0x0028, 0x2001, 0x0004,
+ 0x8007, 0x9215, 0xba06, 0x002e, 0x00ce, 0x00be, 0x0016, 0x2c08,
+ 0x080c, 0xd556, 0x001e, 0x007e, 0x002e, 0x8210, 0x1f04, 0x30fb,
+ 0x015e, 0x001e, 0x002e, 0x003e, 0x004e, 0x00be, 0x00ce, 0x00ee,
+ 0x00fe, 0x0005, 0x0046, 0x0026, 0x0016, 0x080c, 0x54db, 0xd0c4,
+ 0x0140, 0xd0a4, 0x0130, 0x9006, 0x2220, 0x2009, 0x0029, 0x080c,
+ 0xd837, 0x001e, 0x002e, 0x004e, 0x0005, 0x0016, 0x0026, 0x0036,
+ 0x00c6, 0x7290, 0x82ff, 0x01e8, 0x080c, 0x66c1, 0x11d0, 0x2100,
+ 0x080c, 0x26a0, 0x81ff, 0x01b8, 0x2019, 0x0001, 0x8314, 0x92e0,
+ 0x1c80, 0x2c04, 0xd384, 0x0120, 0x9084, 0xff00, 0x8007, 0x0010,
+ 0x9084, 0x00ff, 0x9116, 0x0138, 0x9096, 0x00ff, 0x0110, 0x8318,
+ 0x0c68, 0x9085, 0x0001, 0x00ce, 0x003e, 0x002e, 0x001e, 0x0005,
+ 0x0016, 0x00c6, 0x0126, 0x2091, 0x8000, 0x0036, 0x2019, 0x0029,
+ 0x00a9, 0x003e, 0x9180, 0x1000, 0x2004, 0x9065, 0x0158, 0x0016,
+ 0x00c6, 0x2061, 0x1a88, 0x001e, 0x6112, 0x080c, 0x3095, 0x001e,
+ 0x080c, 0x6367, 0x012e, 0x00ce, 0x001e, 0x0005, 0x0016, 0x0026,
+ 0x2110, 0x080c, 0x9ad0, 0x080c, 0xdaf0, 0x002e, 0x001e, 0x0005,
+ 0x2001, 0x1836, 0x2004, 0xd0cc, 0x0005, 0x00c6, 0x00b6, 0x080c,
+ 0x717e, 0x1118, 0x20a9, 0x0800, 0x0010, 0x20a9, 0x0782, 0x080c,
+ 0x717e, 0x1110, 0x900e, 0x0010, 0x2009, 0x007e, 0x9180, 0x1000,
+ 0x2004, 0x905d, 0x0130, 0x86ff, 0x0110, 0xb800, 0xd0bc, 0x090c,
+ 0x6367, 0x8108, 0x1f04, 0x31ce, 0x2061, 0x1800, 0x607b, 0x0000,
+ 0x607c, 0x9084, 0x00ff, 0x607e, 0x60af, 0x0000, 0x00be, 0x00ce,
+ 0x0005, 0x2001, 0x187d, 0x2004, 0xd0bc, 0x0005, 0x2011, 0x185c,
+ 0x2214, 0xd2ec, 0x0005, 0x7eef, 0x7de8, 0x7ce4, 0x80e2, 0x7be1,
+ 0x80e0, 0x80dc, 0x80da, 0x7ad9, 0x80d6, 0x80d5, 0x80d4, 0x80d3,
+ 0x80d2, 0x80d1, 0x79ce, 0x78cd, 0x80cc, 0x80cb, 0x80ca, 0x80c9,
+ 0x80c7, 0x80c6, 0x77c5, 0x76c3, 0x80bc, 0x80ba, 0x75b9, 0x80b6,
+ 0x74b5, 0x73b4, 0x72b3, 0x80b2, 0x80b1, 0x80ae, 0x71ad, 0x80ac,
+ 0x70ab, 0x6faa, 0x6ea9, 0x80a7, 0x6da6, 0x6ca5, 0x6ba3, 0x6a9f,
+ 0x699e, 0x689d, 0x809b, 0x8098, 0x6797, 0x6690, 0x658f, 0x6488,
+ 0x6384, 0x6282, 0x8081, 0x8080, 0x617c, 0x607a, 0x8079, 0x5f76,
+ 0x8075, 0x8074, 0x8073, 0x8072, 0x8071, 0x806e, 0x5e6d, 0x806c,
+ 0x5d6b, 0x5c6a, 0x5b69, 0x8067, 0x5a66, 0x5965, 0x5863, 0x575c,
+ 0x565a, 0x5559, 0x8056, 0x8055, 0x5454, 0x5353, 0x5252, 0x5151,
+ 0x504e, 0x4f4d, 0x804c, 0x804b, 0x4e4a, 0x4d49, 0x8047, 0x4c46,
+ 0x8045, 0x8043, 0x803c, 0x803a, 0x8039, 0x8036, 0x4b35, 0x8034,
+ 0x4a33, 0x4932, 0x4831, 0x802e, 0x472d, 0x462c, 0x452b, 0x442a,
+ 0x4329, 0x4227, 0x8026, 0x8025, 0x4123, 0x401f, 0x3f1e, 0x3e1d,
+ 0x3d1b, 0x3c18, 0x8017, 0x8010, 0x3b0f, 0x3a08, 0x8004, 0x3902,
+ 0x8001, 0x8000, 0x8000, 0x3800, 0x3700, 0x3600, 0x8000, 0x3500,
+ 0x8000, 0x8000, 0x8000, 0x3400, 0x8000, 0x8000, 0x8000, 0x8000,
+ 0x8000, 0x8000, 0x3300, 0x3200, 0x8000, 0x8000, 0x8000, 0x8000,
+ 0x8000, 0x8000, 0x3100, 0x3000, 0x8000, 0x8000, 0x2f00, 0x8000,
+ 0x2e00, 0x2d00, 0x2c00, 0x8000, 0x8000, 0x8000, 0x2b00, 0x8000,
+ 0x2a00, 0x2900, 0x2800, 0x8000, 0x2700, 0x2600, 0x2500, 0x2400,
+ 0x2300, 0x2200, 0x8000, 0x8000, 0x2100, 0x2000, 0x1f00, 0x1e00,
+ 0x1d00, 0x1c00, 0x8000, 0x8000, 0x1b00, 0x1a00, 0x8000, 0x1900,
+ 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x1800, 0x8000,
+ 0x1700, 0x1600, 0x1500, 0x8000, 0x1400, 0x1300, 0x1200, 0x1100,
+ 0x1000, 0x0f00, 0x8000, 0x8000, 0x0e00, 0x0d00, 0x0c00, 0x0b00,
+ 0x0a00, 0x0900, 0x8000, 0x8000, 0x0800, 0x0700, 0x8000, 0x0600,
+ 0x8000, 0x8000, 0x8000, 0x0500, 0x0400, 0x0300, 0x8000, 0x0200,
+ 0x8000, 0x8000, 0x8000, 0x0100, 0x8000, 0x8000, 0x8000, 0x8000,
+ 0x8000, 0x8000, 0x0000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
- 0x8000, 0x2071, 0x189c, 0x7003, 0x0002, 0x9006, 0x7016, 0x701a,
- 0x704a, 0x704e, 0x700e, 0x7042, 0x7046, 0x703b, 0x18b8, 0x703f,
- 0x18b8, 0x7007, 0x0001, 0x080c, 0x105c, 0x090c, 0x0e02, 0x2900,
- 0x706a, 0xa867, 0x0002, 0xa8ab, 0xdcb0, 0x080c, 0x105c, 0x090c,
- 0x0e02, 0x2900, 0x706e, 0xa867, 0x0002, 0xa8ab, 0xdcb0, 0x0005,
- 0x2071, 0x189c, 0x7004, 0x0002, 0x3338, 0x3339, 0x334c, 0x3360,
- 0x0005, 0x1004, 0x3349, 0x0e04, 0x3349, 0x2079, 0x0000, 0x0126,
- 0x2091, 0x8000, 0x700c, 0x9005, 0x1128, 0x700f, 0x0001, 0x012e,
- 0x0468, 0x0005, 0x012e, 0x0ce8, 0x2079, 0x0000, 0x2061, 0x18b6,
- 0x2c4c, 0xa86c, 0x908e, 0x0100, 0x0128, 0x9086, 0x0200, 0x0904,
- 0x3434, 0x0005, 0x7018, 0x2048, 0x2061, 0x1800, 0x701c, 0x0807,
- 0x7014, 0x2048, 0xa864, 0x9094, 0x00ff, 0x9296, 0x0029, 0x1120,
- 0xaa78, 0xd2fc, 0x0128, 0x0005, 0x9086, 0x0103, 0x0108, 0x0005,
- 0x2079, 0x0000, 0x2061, 0x1800, 0x701c, 0x0807, 0x2061, 0x1800,
- 0x7880, 0x908a, 0x0040, 0x1210, 0x61cc, 0x0042, 0x2100, 0x908a,
- 0x003f, 0x1a04, 0x3431, 0x61cc, 0x0804, 0x33c6, 0x3408, 0x3440,
- 0x3431, 0x344c, 0x3456, 0x345c, 0x3460, 0x3470, 0x3474, 0x348a,
- 0x3490, 0x3496, 0x34a1, 0x34ac, 0x34bb, 0x34ca, 0x34d8, 0x34ef,
- 0x350a, 0x3431, 0x35b3, 0x35f1, 0x3697, 0x36a8, 0x36cb, 0x3431,
- 0x3431, 0x3431, 0x3703, 0x371f, 0x3728, 0x3757, 0x375d, 0x3431,
- 0x37a3, 0x3431, 0x3431, 0x3431, 0x3431, 0x3431, 0x37ae, 0x37b7,
- 0x37bf, 0x37c1, 0x3431, 0x3431, 0x3431, 0x3431, 0x3431, 0x3431,
- 0x37ed, 0x3431, 0x3431, 0x3431, 0x3431, 0x3431, 0x380a, 0x387e,
- 0x3431, 0x3431, 0x3431, 0x3431, 0x3431, 0x3431, 0x0002, 0x38a8,
- 0x38ab, 0x390a, 0x3923, 0x3953, 0x3bf5, 0x3431, 0x509f, 0x3431,
- 0x3431, 0x3431, 0x3431, 0x3431, 0x3431, 0x3431, 0x3431, 0x348a,
- 0x3490, 0x4178, 0x5500, 0x418e, 0x512e, 0x5180, 0x528b, 0x3431,
- 0x52ed, 0x5329, 0x535a, 0x5462, 0x5387, 0x53e2, 0x3431, 0x4192,
- 0x4337, 0x434d, 0x4372, 0x43d7, 0x444b, 0x446b, 0x44e2, 0x453e,
- 0x459a, 0x459d, 0x45c2, 0x4637, 0x469d, 0x46a5, 0x47da, 0x4942,
- 0x4976, 0x4bc0, 0x3431, 0x4bde, 0x4c9b, 0x4d78, 0x3431, 0x3431,
- 0x3431, 0x3431, 0x4dde, 0x4df9, 0x46a5, 0x503f, 0x714c, 0x0000,
- 0x2021, 0x4000, 0x080c, 0x49f4, 0x0126, 0x2091, 0x8000, 0x0e04,
- 0x3412, 0x0010, 0x012e, 0x0cc0, 0x7c36, 0x9486, 0x4000, 0x0118,
- 0x7833, 0x0011, 0x0010, 0x7833, 0x0010, 0x7c82, 0x7986, 0x7a8a,
- 0x7b8e, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c,
- 0x11f2, 0x7007, 0x0001, 0x2091, 0x5000, 0x700f, 0x0000, 0x012e,
- 0x0005, 0x2021, 0x4001, 0x08b0, 0x2021, 0x4002, 0x0898, 0x2021,
- 0x4003, 0x0880, 0x2021, 0x4005, 0x0868, 0x2021, 0x4006, 0x0850,
- 0x2039, 0x0001, 0x902e, 0x2520, 0x7b88, 0x7a8c, 0x7884, 0x7990,
- 0x81ff, 0x0d98, 0x0804, 0x4a01, 0x2039, 0x0001, 0x902e, 0x2520,
- 0x7b88, 0x7a8c, 0x7884, 0x7990, 0x0804, 0x4a04, 0x7984, 0x7888,
- 0x2114, 0x200a, 0x0804, 0x3408, 0x7984, 0x2114, 0x0804, 0x3408,
- 0x20e1, 0x0000, 0x2099, 0x0021, 0x20e9, 0x0000, 0x20a1, 0x0021,
- 0x20a9, 0x001f, 0x4003, 0x7984, 0x7a88, 0x7b8c, 0x0804, 0x3408,
- 0x7884, 0x2060, 0x0804, 0x34bd, 0x2009, 0x0003, 0x2011, 0x0003,
- 0x2019, 0x000f, 0x789b, 0x0317, 0x7893, 0xffff, 0x2001, 0x188d,
- 0x2004, 0x9005, 0x0118, 0x7896, 0x0804, 0x3408, 0x7897, 0x0001,
- 0x0804, 0x3408, 0x2039, 0x0001, 0x7d98, 0x7c9c, 0x0804, 0x3444,
- 0x2039, 0x0001, 0x7d98, 0x7c9c, 0x0804, 0x3450, 0x79a0, 0x9182,
- 0x0040, 0x0210, 0x0804, 0x343d, 0x2138, 0x7d98, 0x7c9c, 0x0804,
- 0x3444, 0x79a0, 0x9182, 0x0040, 0x0210, 0x0804, 0x343d, 0x2138,
- 0x7d98, 0x7c9c, 0x0804, 0x3450, 0x79a0, 0x9182, 0x0040, 0x0210,
- 0x0804, 0x343d, 0x21e8, 0x7984, 0x7888, 0x20a9, 0x0001, 0x21a0,
- 0x4004, 0x0804, 0x3408, 0x2061, 0x0800, 0xe10c, 0x9006, 0x2c15,
- 0x9200, 0x8c60, 0x8109, 0x1dd8, 0x2010, 0x9005, 0x0904, 0x3408,
- 0x0804, 0x3437, 0x79a0, 0x9182, 0x0040, 0x0210, 0x0804, 0x343d,
- 0x21e0, 0x20a9, 0x0001, 0x7984, 0x2198, 0x4012, 0x0804, 0x3408,
- 0x2069, 0x185b, 0x7884, 0x7990, 0x911a, 0x1a04, 0x343d, 0x8019,
- 0x0904, 0x343d, 0x684a, 0x6942, 0x788c, 0x6852, 0x7888, 0x6856,
- 0x9006, 0x685a, 0x685e, 0x080c, 0x74ac, 0x0804, 0x3408, 0x2069,
- 0x185b, 0x7884, 0x7994, 0x911a, 0x1a04, 0x343d, 0x8019, 0x0904,
- 0x343d, 0x684e, 0x6946, 0x788c, 0x6862, 0x7888, 0x6866, 0x9006,
- 0x686a, 0x686e, 0x0126, 0x2091, 0x8000, 0x080c, 0x67fa, 0x012e,
- 0x0804, 0x3408, 0x902e, 0x2520, 0x81ff, 0x0120, 0x2009, 0x0001,
- 0x0804, 0x343a, 0x7984, 0x7b88, 0x7a8c, 0x20a9, 0x0005, 0x20e9,
- 0x0001, 0x20a1, 0x18a4, 0x4101, 0x080c, 0x49b8, 0x1120, 0x2009,
- 0x0002, 0x0804, 0x343a, 0x2009, 0x0020, 0xa85c, 0x9080, 0x0019,
- 0xaf60, 0x080c, 0x4a01, 0x701f, 0x352e, 0x0005, 0xa864, 0x2008,
- 0x9084, 0x00ff, 0x9096, 0x0011, 0x0168, 0x9096, 0x0019, 0x0150,
- 0x9096, 0x0015, 0x0138, 0x9096, 0x0048, 0x0120, 0x9096, 0x0029,
- 0x1904, 0x343a, 0x810f, 0x918c, 0x00ff, 0x0904, 0x343a, 0x7112,
- 0x7010, 0x8001, 0x0560, 0x7012, 0x080c, 0x49b8, 0x1120, 0x2009,
- 0x0002, 0x0804, 0x343a, 0x2009, 0x0020, 0x7068, 0x2040, 0xa28c,
- 0xa390, 0xa494, 0xa598, 0x9290, 0x0040, 0x9399, 0x0000, 0x94a1,
- 0x0000, 0x95a9, 0x0000, 0xa85c, 0x9080, 0x0019, 0xaf60, 0x080c,
- 0x4a01, 0x701f, 0x356c, 0x0005, 0xa864, 0x9084, 0x00ff, 0x9096,
- 0x0002, 0x0120, 0x9096, 0x000a, 0x1904, 0x343a, 0x0888, 0x7014,
- 0x2048, 0xa868, 0xc0fd, 0xa86a, 0xa864, 0x9084, 0x00ff, 0x9096,
- 0x0029, 0x1160, 0xc2fd, 0xaa7a, 0x080c, 0x5f3c, 0x0150, 0x0126,
- 0x2091, 0x8000, 0xa87a, 0xa982, 0x012e, 0x0050, 0x080c, 0x625a,
- 0x1128, 0x7007, 0x0003, 0x701f, 0x3598, 0x0005, 0x080c, 0x6c6c,
- 0x0126, 0x2091, 0x8000, 0x20a9, 0x0005, 0x20e1, 0x0001, 0x2099,
- 0x18a4, 0x400a, 0x2100, 0x9210, 0x9399, 0x0000, 0x94a1, 0x0000,
- 0x95a9, 0x0000, 0xa85c, 0x9080, 0x0019, 0x2009, 0x0020, 0x012e,
- 0xaf60, 0x0804, 0x4a04, 0x2091, 0x8000, 0x7837, 0x4000, 0x7833,
- 0x0010, 0x7883, 0x4000, 0x7887, 0x4953, 0x788b, 0x5020, 0x788f,
- 0x2020, 0x2009, 0x017f, 0x2104, 0x7892, 0x3f00, 0x7896, 0x2061,
- 0x0100, 0x6200, 0x2061, 0x0200, 0x603c, 0x8007, 0x9205, 0x789a,
- 0x2009, 0x04fd, 0x2104, 0x789e, 0x2091, 0x5000, 0x2091, 0x4080,
- 0x2001, 0x0089, 0x2004, 0xd084, 0x0180, 0x2001, 0x19f6, 0x2004,
- 0x9005, 0x0128, 0x2001, 0x008b, 0x2004, 0xd0fc, 0x0dd8, 0x2001,
- 0x008a, 0x2003, 0x0002, 0x2003, 0x1001, 0x2071, 0x0080, 0x0804,
- 0x0427, 0x81ff, 0x1904, 0x343a, 0x7984, 0x080c, 0x63a4, 0x1904,
- 0x343d, 0x7e98, 0x9684, 0x3fff, 0x9082, 0x4000, 0x1a04, 0x343d,
- 0x7c88, 0x7d8c, 0x080c, 0x6507, 0x080c, 0x64d6, 0x0000, 0x1518,
+ 0x8000, 0x8000, 0x8000, 0x2071, 0x189c, 0x7003, 0x0002, 0x9006,
+ 0x7016, 0x701a, 0x704a, 0x704e, 0x700e, 0x7042, 0x7046, 0x703b,
+ 0x18b8, 0x703f, 0x18b8, 0x7007, 0x0001, 0x080c, 0x1050, 0x090c,
+ 0x0df6, 0x2900, 0x706a, 0xa867, 0x0002, 0xa8ab, 0xdcb0, 0x080c,
+ 0x1050, 0x090c, 0x0df6, 0x2900, 0x706e, 0xa867, 0x0002, 0xa8ab,
+ 0xdcb0, 0x0005, 0x2071, 0x189c, 0x7004, 0x0002, 0x3322, 0x3323,
+ 0x3336, 0x334a, 0x0005, 0x1004, 0x3333, 0x0e04, 0x3333, 0x2079,
+ 0x0000, 0x0126, 0x2091, 0x8000, 0x700c, 0x9005, 0x1128, 0x700f,
+ 0x0001, 0x012e, 0x0468, 0x0005, 0x012e, 0x0ce8, 0x2079, 0x0000,
+ 0x2061, 0x18b6, 0x2c4c, 0xa86c, 0x908e, 0x0100, 0x0128, 0x9086,
+ 0x0200, 0x0904, 0x341e, 0x0005, 0x7018, 0x2048, 0x2061, 0x1800,
+ 0x701c, 0x0807, 0x7014, 0x2048, 0xa864, 0x9094, 0x00ff, 0x9296,
+ 0x0029, 0x1120, 0xaa78, 0xd2fc, 0x0128, 0x0005, 0x9086, 0x0103,
+ 0x0108, 0x0005, 0x2079, 0x0000, 0x2061, 0x1800, 0x701c, 0x0807,
+ 0x2061, 0x1800, 0x7880, 0x908a, 0x0040, 0x1210, 0x61cc, 0x0042,
+ 0x2100, 0x908a, 0x003f, 0x1a04, 0x341b, 0x61cc, 0x0804, 0x33b0,
+ 0x33f2, 0x342a, 0x341b, 0x3436, 0x3440, 0x3446, 0x344a, 0x345a,
+ 0x345e, 0x3474, 0x347a, 0x3480, 0x348b, 0x3496, 0x34a5, 0x34b4,
+ 0x34c2, 0x34d9, 0x34f4, 0x341b, 0x359d, 0x35db, 0x3681, 0x3692,
+ 0x36b5, 0x341b, 0x341b, 0x341b, 0x36ed, 0x3709, 0x3712, 0x3741,
+ 0x3747, 0x341b, 0x378d, 0x341b, 0x341b, 0x341b, 0x341b, 0x341b,
+ 0x3798, 0x37a1, 0x37a9, 0x37ab, 0x341b, 0x341b, 0x341b, 0x341b,
+ 0x341b, 0x341b, 0x37d7, 0x341b, 0x341b, 0x341b, 0x341b, 0x341b,
+ 0x37f4, 0x3868, 0x341b, 0x341b, 0x341b, 0x341b, 0x341b, 0x341b,
+ 0x0002, 0x3892, 0x3895, 0x38f4, 0x390d, 0x393d, 0x3bdf, 0x341b,
+ 0x509e, 0x341b, 0x341b, 0x341b, 0x341b, 0x341b, 0x341b, 0x341b,
+ 0x341b, 0x3474, 0x347a, 0x416d, 0x54ff, 0x4183, 0x512d, 0x517f,
+ 0x528a, 0x341b, 0x52ec, 0x5328, 0x5359, 0x5461, 0x5386, 0x53e1,
+ 0x341b, 0x4187, 0x4336, 0x434c, 0x4371, 0x43d6, 0x444a, 0x446a,
+ 0x44e1, 0x453d, 0x4599, 0x459c, 0x45c1, 0x4636, 0x469c, 0x46a4,
+ 0x47d9, 0x4941, 0x4975, 0x4bbf, 0x341b, 0x4bdd, 0x4c9a, 0x4d77,
+ 0x341b, 0x341b, 0x341b, 0x341b, 0x4ddd, 0x4df8, 0x46a4, 0x503e,
+ 0x714c, 0x0000, 0x2021, 0x4000, 0x080c, 0x49f3, 0x0126, 0x2091,
+ 0x8000, 0x0e04, 0x33fc, 0x0010, 0x012e, 0x0cc0, 0x7c36, 0x9486,
+ 0x4000, 0x0118, 0x7833, 0x0011, 0x0010, 0x7833, 0x0010, 0x7c82,
+ 0x7986, 0x7a8a, 0x7b8e, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004,
+ 0xd084, 0x190c, 0x11e6, 0x7007, 0x0001, 0x2091, 0x5000, 0x700f,
+ 0x0000, 0x012e, 0x0005, 0x2021, 0x4001, 0x08b0, 0x2021, 0x4002,
+ 0x0898, 0x2021, 0x4003, 0x0880, 0x2021, 0x4005, 0x0868, 0x2021,
+ 0x4006, 0x0850, 0x2039, 0x0001, 0x902e, 0x2520, 0x7b88, 0x7a8c,
+ 0x7884, 0x7990, 0x81ff, 0x0d98, 0x0804, 0x4a00, 0x2039, 0x0001,
+ 0x902e, 0x2520, 0x7b88, 0x7a8c, 0x7884, 0x7990, 0x0804, 0x4a03,
+ 0x7984, 0x7888, 0x2114, 0x200a, 0x0804, 0x33f2, 0x7984, 0x2114,
+ 0x0804, 0x33f2, 0x20e1, 0x0000, 0x2099, 0x0021, 0x20e9, 0x0000,
+ 0x20a1, 0x0021, 0x20a9, 0x001f, 0x4003, 0x7984, 0x7a88, 0x7b8c,
+ 0x0804, 0x33f2, 0x7884, 0x2060, 0x0804, 0x34a7, 0x2009, 0x0003,
+ 0x2011, 0x0003, 0x2019, 0x0012, 0x789b, 0x0317, 0x7893, 0xffff,
+ 0x2001, 0x188d, 0x2004, 0x9005, 0x0118, 0x7896, 0x0804, 0x33f2,
+ 0x7897, 0x0001, 0x0804, 0x33f2, 0x2039, 0x0001, 0x7d98, 0x7c9c,
+ 0x0804, 0x342e, 0x2039, 0x0001, 0x7d98, 0x7c9c, 0x0804, 0x343a,
+ 0x79a0, 0x9182, 0x0040, 0x0210, 0x0804, 0x3427, 0x2138, 0x7d98,
+ 0x7c9c, 0x0804, 0x342e, 0x79a0, 0x9182, 0x0040, 0x0210, 0x0804,
+ 0x3427, 0x2138, 0x7d98, 0x7c9c, 0x0804, 0x343a, 0x79a0, 0x9182,
+ 0x0040, 0x0210, 0x0804, 0x3427, 0x21e8, 0x7984, 0x7888, 0x20a9,
+ 0x0001, 0x21a0, 0x4004, 0x0804, 0x33f2, 0x2061, 0x0800, 0xe10c,
+ 0x9006, 0x2c15, 0x9200, 0x8c60, 0x8109, 0x1dd8, 0x2010, 0x9005,
+ 0x0904, 0x33f2, 0x0804, 0x3421, 0x79a0, 0x9182, 0x0040, 0x0210,
+ 0x0804, 0x3427, 0x21e0, 0x20a9, 0x0001, 0x7984, 0x2198, 0x4012,
+ 0x0804, 0x33f2, 0x2069, 0x185b, 0x7884, 0x7990, 0x911a, 0x1a04,
+ 0x3427, 0x8019, 0x0904, 0x3427, 0x684a, 0x6942, 0x788c, 0x6852,
+ 0x7888, 0x6856, 0x9006, 0x685a, 0x685e, 0x080c, 0x74ab, 0x0804,
+ 0x33f2, 0x2069, 0x185b, 0x7884, 0x7994, 0x911a, 0x1a04, 0x3427,
+ 0x8019, 0x0904, 0x3427, 0x684e, 0x6946, 0x788c, 0x6862, 0x7888,
+ 0x6866, 0x9006, 0x686a, 0x686e, 0x0126, 0x2091, 0x8000, 0x080c,
+ 0x67f9, 0x012e, 0x0804, 0x33f2, 0x902e, 0x2520, 0x81ff, 0x0120,
+ 0x2009, 0x0001, 0x0804, 0x3424, 0x7984, 0x7b88, 0x7a8c, 0x20a9,
+ 0x0005, 0x20e9, 0x0001, 0x20a1, 0x18a4, 0x4101, 0x080c, 0x49b7,
+ 0x1120, 0x2009, 0x0002, 0x0804, 0x3424, 0x2009, 0x0020, 0xa85c,
+ 0x9080, 0x0019, 0xaf60, 0x080c, 0x4a00, 0x701f, 0x3518, 0x0005,
+ 0xa864, 0x2008, 0x9084, 0x00ff, 0x9096, 0x0011, 0x0168, 0x9096,
+ 0x0019, 0x0150, 0x9096, 0x0015, 0x0138, 0x9096, 0x0048, 0x0120,
+ 0x9096, 0x0029, 0x1904, 0x3424, 0x810f, 0x918c, 0x00ff, 0x0904,
+ 0x3424, 0x7112, 0x7010, 0x8001, 0x0560, 0x7012, 0x080c, 0x49b7,
+ 0x1120, 0x2009, 0x0002, 0x0804, 0x3424, 0x2009, 0x0020, 0x7068,
+ 0x2040, 0xa28c, 0xa390, 0xa494, 0xa598, 0x9290, 0x0040, 0x9399,
+ 0x0000, 0x94a1, 0x0000, 0x95a9, 0x0000, 0xa85c, 0x9080, 0x0019,
+ 0xaf60, 0x080c, 0x4a00, 0x701f, 0x3556, 0x0005, 0xa864, 0x9084,
+ 0x00ff, 0x9096, 0x0002, 0x0120, 0x9096, 0x000a, 0x1904, 0x3424,
+ 0x0888, 0x7014, 0x2048, 0xa868, 0xc0fd, 0xa86a, 0xa864, 0x9084,
+ 0x00ff, 0x9096, 0x0029, 0x1160, 0xc2fd, 0xaa7a, 0x080c, 0x5f3b,
+ 0x0150, 0x0126, 0x2091, 0x8000, 0xa87a, 0xa982, 0x012e, 0x0050,
+ 0x080c, 0x6259, 0x1128, 0x7007, 0x0003, 0x701f, 0x3582, 0x0005,
+ 0x080c, 0x6c6b, 0x0126, 0x2091, 0x8000, 0x20a9, 0x0005, 0x20e1,
+ 0x0001, 0x2099, 0x18a4, 0x400a, 0x2100, 0x9210, 0x9399, 0x0000,
+ 0x94a1, 0x0000, 0x95a9, 0x0000, 0xa85c, 0x9080, 0x0019, 0x2009,
+ 0x0020, 0x012e, 0xaf60, 0x0804, 0x4a03, 0x2091, 0x8000, 0x7837,
+ 0x4000, 0x7833, 0x0010, 0x7883, 0x4000, 0x7887, 0x4953, 0x788b,
+ 0x5020, 0x788f, 0x2020, 0x2009, 0x017f, 0x2104, 0x7892, 0x3f00,
+ 0x7896, 0x2061, 0x0100, 0x6200, 0x2061, 0x0200, 0x603c, 0x8007,
+ 0x9205, 0x789a, 0x2009, 0x04fd, 0x2104, 0x789e, 0x2091, 0x5000,
+ 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x0180, 0x2001,
+ 0x19f6, 0x2004, 0x9005, 0x0128, 0x2001, 0x008b, 0x2004, 0xd0fc,
+ 0x0dd8, 0x2001, 0x008a, 0x2003, 0x0002, 0x2003, 0x1001, 0x2071,
+ 0x0080, 0x0804, 0x0427, 0x81ff, 0x1904, 0x3424, 0x7984, 0x080c,
+ 0x63a3, 0x1904, 0x3427, 0x7e98, 0x9684, 0x3fff, 0x9082, 0x4000,
+ 0x1a04, 0x3427, 0x7c88, 0x7d8c, 0x080c, 0x6506, 0x080c, 0x64d5,
+ 0x0000, 0x1518, 0x2061, 0x1cd0, 0x0126, 0x2091, 0x8000, 0x6000,
+ 0x9086, 0x0000, 0x0148, 0x6014, 0x904d, 0x0130, 0xa86c, 0x9406,
+ 0x1118, 0xa870, 0x9506, 0x0150, 0x012e, 0x9ce0, 0x0018, 0x2001,
+ 0x1819, 0x2004, 0x9c02, 0x1a04, 0x3424, 0x0c30, 0x080c, 0xb983,
+ 0x012e, 0x0904, 0x3424, 0x0804, 0x33f2, 0x900e, 0x2001, 0x0005,
+ 0x080c, 0x6c6b, 0x0126, 0x2091, 0x8000, 0x080c, 0xc04a, 0x080c,
+ 0x6a22, 0x012e, 0x0804, 0x33f2, 0x00a6, 0x2950, 0xb198, 0x080c,
+ 0x63a3, 0x1904, 0x366e, 0xb6a4, 0x9684, 0x3fff, 0x9082, 0x4000,
+ 0x16e8, 0xb49c, 0xb5a0, 0x080c, 0x6506, 0x080c, 0x64d5, 0x1520,
0x2061, 0x1cd0, 0x0126, 0x2091, 0x8000, 0x6000, 0x9086, 0x0000,
0x0148, 0x6014, 0x904d, 0x0130, 0xa86c, 0x9406, 0x1118, 0xa870,
- 0x9506, 0x0150, 0x012e, 0x9ce0, 0x0018, 0x2001, 0x1819, 0x2004,
- 0x9c02, 0x1a04, 0x343a, 0x0c30, 0x080c, 0xb974, 0x012e, 0x0904,
- 0x343a, 0x0804, 0x3408, 0x900e, 0x2001, 0x0005, 0x080c, 0x6c6c,
- 0x0126, 0x2091, 0x8000, 0x080c, 0xc037, 0x080c, 0x6a23, 0x012e,
- 0x0804, 0x3408, 0x00a6, 0x2950, 0xb198, 0x080c, 0x63a4, 0x1904,
- 0x3684, 0xb6a4, 0x9684, 0x3fff, 0x9082, 0x4000, 0x16e8, 0xb49c,
- 0xb5a0, 0x080c, 0x6507, 0x080c, 0x64d6, 0x1520, 0x2061, 0x1cd0,
- 0x0126, 0x2091, 0x8000, 0x6000, 0x9086, 0x0000, 0x0148, 0x6014,
- 0x904d, 0x0130, 0xa86c, 0x9406, 0x1118, 0xa870, 0x9506, 0x0158,
- 0x012e, 0x9ce0, 0x0018, 0x2001, 0x1819, 0x2004, 0x9c02, 0x2009,
- 0x000d, 0x12b0, 0x0c28, 0x080c, 0xb974, 0x012e, 0x2009, 0x0003,
- 0x0178, 0x00e0, 0x900e, 0x2001, 0x0005, 0x080c, 0x6c6c, 0x0126,
- 0x2091, 0x8000, 0x080c, 0xc037, 0x080c, 0x6a16, 0x012e, 0x0070,
- 0xb097, 0x4005, 0xb19a, 0x0010, 0xb097, 0x4006, 0x900e, 0x9085,
- 0x0001, 0x2001, 0x0030, 0x2a48, 0x00ae, 0x0005, 0xb097, 0x4000,
- 0x9006, 0x918d, 0x0001, 0x2008, 0x2a48, 0x00ae, 0x0005, 0x81ff,
- 0x1904, 0x343a, 0x080c, 0x49cf, 0x0904, 0x343d, 0x080c, 0x646b,
- 0x0904, 0x343a, 0x080c, 0x650d, 0x0904, 0x343a, 0x0804, 0x4462,
- 0x81ff, 0x1904, 0x343a, 0x080c, 0x49eb, 0x0904, 0x343d, 0x080c,
- 0x659b, 0x0904, 0x343a, 0x2019, 0x0005, 0x79a8, 0x080c, 0x6528,
- 0x0904, 0x343a, 0x7888, 0x908a, 0x1000, 0x1a04, 0x343d, 0x8003,
- 0x800b, 0x810b, 0x9108, 0x080c, 0x8268, 0x79a8, 0xd184, 0x1904,
- 0x3408, 0x0804, 0x4462, 0x0126, 0x2091, 0x8000, 0x81ff, 0x0118,
- 0x2009, 0x0001, 0x0450, 0x2029, 0x07ff, 0x6458, 0x2400, 0x9506,
- 0x01f8, 0x2508, 0x080c, 0x63a4, 0x11d8, 0x080c, 0x659b, 0x1128,
- 0x2009, 0x0002, 0x62bc, 0x2518, 0x00c0, 0x2019, 0x0004, 0x900e,
- 0x080c, 0x6528, 0x1118, 0x2009, 0x0006, 0x0078, 0x7884, 0x908a,
- 0x1000, 0x1270, 0x8003, 0x800b, 0x810b, 0x9108, 0x080c, 0x8268,
- 0x8529, 0x1ae0, 0x012e, 0x0804, 0x3408, 0x012e, 0x0804, 0x343a,
- 0x012e, 0x0804, 0x343d, 0x080c, 0x49cf, 0x0904, 0x343d, 0x080c,
- 0x646b, 0x0904, 0x343a, 0xbaa0, 0x2019, 0x0005, 0x00c6, 0x9066,
- 0x080c, 0x8783, 0x0076, 0x903e, 0x080c, 0x8671, 0x900e, 0x080c,
- 0xd53b, 0x007e, 0x00ce, 0x080c, 0x6507, 0x0804, 0x3408, 0x080c,
- 0x49cf, 0x0904, 0x343d, 0x080c, 0x6507, 0x2208, 0x0804, 0x3408,
- 0x0156, 0x00d6, 0x00e6, 0x2069, 0x190e, 0x6810, 0x6914, 0x910a,
- 0x1208, 0x900e, 0x6816, 0x9016, 0x901e, 0x20a9, 0x007e, 0x2069,
- 0x1000, 0x2d04, 0x905d, 0x0118, 0xb84c, 0x0059, 0x9210, 0x8d68,
- 0x1f04, 0x3739, 0x2300, 0x9218, 0x00ee, 0x00de, 0x015e, 0x0804,
- 0x3408, 0x00f6, 0x0016, 0x907d, 0x0138, 0x9006, 0x8000, 0x2f0c,
- 0x81ff, 0x0110, 0x2178, 0x0cd0, 0x001e, 0x00fe, 0x0005, 0x2069,
- 0x190e, 0x6910, 0x62b8, 0x0804, 0x3408, 0x81ff, 0x0120, 0x2009,
- 0x0001, 0x0804, 0x343a, 0x0126, 0x2091, 0x8000, 0x080c, 0x54f0,
- 0x0128, 0x2009, 0x0007, 0x012e, 0x0804, 0x343a, 0x012e, 0x6158,
- 0x9190, 0x3209, 0x2215, 0x9294, 0x00ff, 0x6378, 0x83ff, 0x0108,
- 0x627c, 0x67d8, 0x97c4, 0x000a, 0x98c6, 0x000a, 0x1118, 0x2031,
- 0x0001, 0x00e8, 0x97c4, 0x0022, 0x98c6, 0x0022, 0x1118, 0x2031,
- 0x0003, 0x00a8, 0x97c4, 0x0012, 0x98c6, 0x0012, 0x1118, 0x2031,
- 0x0002, 0x0068, 0x080c, 0x717f, 0x1118, 0x2031, 0x0004, 0x0038,
- 0xd79c, 0x0120, 0x2009, 0x0005, 0x0804, 0x343a, 0x9036, 0x7e9a,
- 0x7f9e, 0x0804, 0x3408, 0x6148, 0x624c, 0x2019, 0x1960, 0x231c,
- 0x2001, 0x1961, 0x2004, 0x789a, 0x0804, 0x3408, 0x0126, 0x2091,
- 0x8000, 0x6138, 0x623c, 0x6340, 0x012e, 0x0804, 0x3408, 0x080c,
- 0x49eb, 0x0904, 0x343d, 0xba44, 0xbb38, 0x0804, 0x3408, 0x080c,
- 0x0e02, 0x080c, 0x49eb, 0x2110, 0x0904, 0x343d, 0xb804, 0x908c,
- 0x00ff, 0x918e, 0x0006, 0x0140, 0x9084, 0xff00, 0x9086, 0x0600,
- 0x2009, 0x0009, 0x1904, 0x343a, 0x0126, 0x2091, 0x8000, 0x2019,
- 0x0005, 0x00c6, 0x9066, 0x080c, 0x9abb, 0x080c, 0x8783, 0x0076,
- 0x903e, 0x080c, 0x8671, 0x900e, 0x080c, 0xd53b, 0x007e, 0x00ce,
- 0xb807, 0x0407, 0x012e, 0x0804, 0x3408, 0x6148, 0x624c, 0x7884,
- 0x604a, 0x7b88, 0x634e, 0x2069, 0x185b, 0x831f, 0x9305, 0x6816,
- 0x788c, 0x2069, 0x1960, 0x2d1c, 0x206a, 0x7e98, 0x9682, 0x0014,
- 0x1210, 0x2031, 0x07d0, 0x2069, 0x1961, 0x2d04, 0x266a, 0x789a,
- 0x0804, 0x3408, 0x0126, 0x2091, 0x8000, 0x6138, 0x7884, 0x603a,
- 0x910e, 0xd1b4, 0x190c, 0x0ef3, 0xd0c4, 0x01a8, 0x00d6, 0x78a8,
- 0x2009, 0x1977, 0x200a, 0x78ac, 0x2011, 0x1978, 0x2012, 0x2069,
- 0x0100, 0x6838, 0x9086, 0x0007, 0x1118, 0x2214, 0x6a5a, 0x0010,
- 0x210c, 0x695a, 0x00de, 0x2001, 0x0100, 0x2004, 0x9086, 0x000a,
- 0x0168, 0x2011, 0x0114, 0x220c, 0x7888, 0xd08c, 0x0118, 0x918d,
- 0x0080, 0x0010, 0x918c, 0xff7f, 0x2112, 0x0060, 0x2011, 0x0116,
- 0x220c, 0x7888, 0xd08c, 0x0118, 0x918d, 0x0040, 0x0010, 0x918c,
- 0xff7f, 0x2112, 0x603c, 0x7988, 0x613e, 0x6140, 0x910d, 0x788c,
- 0x6042, 0x7a88, 0x9294, 0x1000, 0x9205, 0x910e, 0xd1e4, 0x190c,
- 0x0f09, 0x6040, 0xd0cc, 0x0120, 0x78b0, 0x2011, 0x0114, 0x2012,
- 0x012e, 0x0804, 0x3408, 0x00f6, 0x2079, 0x1800, 0x7a38, 0xa898,
- 0x9084, 0xfebf, 0x9215, 0xa89c, 0x9084, 0xfebf, 0x8002, 0x9214,
- 0x7838, 0x9084, 0x0140, 0x9215, 0x7a3a, 0xa897, 0x4000, 0x900e,
- 0x9085, 0x0001, 0x2001, 0x0000, 0x00fe, 0x0005, 0x7898, 0x9005,
- 0x01a8, 0x7888, 0x9025, 0x0904, 0x343d, 0x788c, 0x902d, 0x0904,
- 0x343d, 0x900e, 0x080c, 0x63a4, 0x1120, 0xba44, 0xbb38, 0xbc46,
- 0xbd3a, 0x9186, 0x07ff, 0x0190, 0x8108, 0x0ca0, 0x080c, 0x49eb,
- 0x0904, 0x343d, 0x7888, 0x900d, 0x0904, 0x343d, 0x788c, 0x9005,
- 0x0904, 0x343d, 0xba44, 0xb946, 0xbb38, 0xb83a, 0x0804, 0x3408,
- 0x2011, 0xbc09, 0x0010, 0x2011, 0xbc05, 0x080c, 0x54f0, 0x1904,
- 0x343a, 0x00c6, 0x2061, 0x0100, 0x7984, 0x9186, 0x00ff, 0x1130,
- 0x2001, 0x1817, 0x2004, 0x9085, 0xff00, 0x0088, 0x9182, 0x007f,
- 0x16e0, 0x9188, 0x3209, 0x210d, 0x918c, 0x00ff, 0x2001, 0x1817,
- 0x2004, 0x0026, 0x9116, 0x002e, 0x0580, 0x810f, 0x9105, 0x0126,
- 0x2091, 0x8000, 0x0006, 0x080c, 0x9f7f, 0x000e, 0x0510, 0x602e,
- 0x620a, 0x7984, 0x00b6, 0x080c, 0x634a, 0x2b08, 0x00be, 0x1500,
- 0x6112, 0x6023, 0x0001, 0x080c, 0x49b8, 0x01d0, 0x9006, 0xa866,
- 0x7007, 0x0003, 0xa832, 0xa868, 0xc0fd, 0xa86a, 0x701f, 0x3903,
- 0x2900, 0x6016, 0x2009, 0x0032, 0x080c, 0xa053, 0x012e, 0x00ce,
- 0x0005, 0x012e, 0x00ce, 0x0804, 0x343a, 0x00ce, 0x0804, 0x343d,
- 0x080c, 0x9fd5, 0x0cb0, 0xa830, 0x9086, 0x0100, 0x0904, 0x343a,
- 0x0804, 0x3408, 0x2061, 0x1a4c, 0x0126, 0x2091, 0x8000, 0x6000,
- 0xd084, 0x0170, 0x6104, 0x6208, 0x2061, 0x1800, 0x6350, 0x6070,
- 0x789a, 0x60bc, 0x789e, 0x60b8, 0x78aa, 0x012e, 0x0804, 0x3408,
- 0x900e, 0x2110, 0x0c88, 0x81ff, 0x1904, 0x343a, 0x080c, 0x717f,
- 0x0904, 0x343a, 0x0126, 0x2091, 0x8000, 0x6250, 0x6070, 0x9202,
- 0x0248, 0x9085, 0x0001, 0x080c, 0x26d7, 0x080c, 0x5713, 0x012e,
- 0x0804, 0x3408, 0x012e, 0x0804, 0x343d, 0x0006, 0x0016, 0x00c6,
- 0x00e6, 0x2001, 0x1983, 0x2070, 0x2061, 0x185b, 0x6008, 0x2072,
- 0x900e, 0x2011, 0x1400, 0x080c, 0x847f, 0x7206, 0x00ee, 0x00ce,
- 0x001e, 0x000e, 0x0005, 0x0126, 0x2091, 0x8000, 0x81ff, 0x0128,
- 0x012e, 0x2021, 0x400b, 0x0804, 0x340a, 0x7884, 0xd0fc, 0x0158,
- 0x2001, 0x002a, 0x2004, 0x9005, 0x0180, 0x9082, 0x00e1, 0x0298,
- 0x012e, 0x0804, 0x343d, 0x2001, 0x002a, 0x2004, 0x9005, 0x0128,
- 0x2069, 0x185b, 0x6908, 0x9102, 0x1230, 0x012e, 0x0804, 0x343d,
- 0x012e, 0x0804, 0x343a, 0x080c, 0x9f54, 0x0dd0, 0x7884, 0xd0fc,
- 0x0904, 0x39d2, 0x00c6, 0x080c, 0x49b8, 0x00ce, 0x0d88, 0xa867,
- 0x0000, 0x7884, 0xa80a, 0x7898, 0xa80e, 0x789c, 0xa812, 0x2001,
- 0x002e, 0x2004, 0xa81a, 0x2001, 0x002f, 0x2004, 0xa81e, 0x2001,
- 0x0030, 0x2004, 0xa822, 0x2001, 0x0031, 0x2004, 0xa826, 0x2001,
- 0x0034, 0x2004, 0xa82a, 0x2001, 0x0035, 0x2004, 0xa82e, 0x2001,
- 0x002a, 0x2004, 0x9080, 0x0003, 0x9084, 0x00fc, 0x8004, 0xa816,
- 0x080c, 0x3b58, 0x0928, 0x7014, 0x2048, 0xad2c, 0xac28, 0xab1c,
- 0xaa18, 0xa930, 0xa808, 0xd0b4, 0x1120, 0x2029, 0x0000, 0x2021,
- 0x0000, 0x8906, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0,
- 0x9080, 0x001b, 0x080c, 0x4a01, 0x701f, 0x3a95, 0x7023, 0x0001,
- 0x012e, 0x0005, 0x0046, 0x0086, 0x0096, 0x00a6, 0x00b6, 0x00c6,
- 0x00d6, 0x00e6, 0x00f6, 0x080c, 0x393d, 0x2001, 0x1979, 0x2003,
- 0x0000, 0x2021, 0x000a, 0x2061, 0x0100, 0x6104, 0x0016, 0x60bb,
- 0x0000, 0x60bf, 0x32e1, 0x60bf, 0x0012, 0x080c, 0x3bc7, 0x080c,
- 0x3b86, 0x00f6, 0x00e6, 0x0086, 0x2940, 0x2071, 0x1a42, 0x2079,
- 0x0090, 0x00d6, 0x2069, 0x0000, 0x6884, 0xd0b4, 0x0140, 0x2001,
- 0x0035, 0x2004, 0x780e, 0x2001, 0x0034, 0x2004, 0x780a, 0x00de,
- 0x2011, 0x0001, 0x080c, 0x3fbc, 0x008e, 0x00ee, 0x00fe, 0x080c,
- 0x3ee9, 0x080c, 0x3dae, 0x05b8, 0x2001, 0x020b, 0x2004, 0x9084,
- 0x0140, 0x1db8, 0x080c, 0x4030, 0x00f6, 0x2079, 0x0300, 0x78bc,
- 0x00fe, 0x908c, 0x0070, 0x1560, 0x2071, 0x0200, 0x7037, 0x0000,
- 0x7050, 0x9084, 0xff00, 0x9086, 0x3200, 0x1510, 0x7037, 0x0001,
- 0x7050, 0x9084, 0xff00, 0x9086, 0xe100, 0x11d0, 0x7037, 0x0000,
- 0x7054, 0x7037, 0x0000, 0x715c, 0x9106, 0x1190, 0x2001, 0x181f,
- 0x2004, 0x9106, 0x1168, 0x00c6, 0x2061, 0x0100, 0x6024, 0x9084,
- 0x1e00, 0x00ce, 0x0138, 0x080c, 0x3db8, 0x080c, 0x3b81, 0x0058,
- 0x080c, 0x3b81, 0x080c, 0x3f54, 0x080c, 0x3edf, 0x2001, 0x020b,
- 0x2004, 0xd0e4, 0x0dd8, 0x2001, 0x032a, 0x2003, 0x0004, 0x2061,
- 0x0100, 0x6027, 0x0002, 0x001e, 0x6106, 0x2011, 0x020d, 0x2013,
- 0x0020, 0x60bb, 0x0000, 0x60bf, 0x0108, 0x60bf, 0x0012, 0x2001,
- 0x0004, 0x200c, 0x918c, 0xfffd, 0x2102, 0x080c, 0x130a, 0x2009,
- 0x0028, 0x080c, 0x2204, 0x2001, 0x0227, 0x200c, 0x2102, 0x00fe,
- 0x00ee, 0x00de, 0x00ce, 0x00be, 0x00ae, 0x009e, 0x008e, 0x004e,
- 0x2001, 0x1979, 0x2004, 0x9005, 0x1118, 0x012e, 0x0804, 0x3408,
- 0x012e, 0x2021, 0x400c, 0x0804, 0x340a, 0x0016, 0x0026, 0x0036,
- 0x0046, 0x0056, 0x0076, 0x0086, 0x0096, 0x00d6, 0x0156, 0x7014,
- 0x2048, 0x7020, 0x20a8, 0x8000, 0x7022, 0xa804, 0x9005, 0x0904,
- 0x3af1, 0x2048, 0x1f04, 0x3aa5, 0x7068, 0x2040, 0xa28c, 0xa390,
- 0xa494, 0xa598, 0xa930, 0xa808, 0xd0b4, 0x1120, 0x2029, 0x0000,
- 0x2021, 0x0000, 0x0096, 0x7014, 0x2048, 0xa864, 0x009e, 0x9086,
- 0x0103, 0x0170, 0x8906, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084,
- 0xffc0, 0x9080, 0x001b, 0x080c, 0x4a01, 0x701f, 0x3a95, 0x00b0,
- 0x8906, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080,
- 0x001b, 0x21a8, 0x27e0, 0x2098, 0x27e8, 0x20a0, 0x0006, 0x080c,
- 0x0fc0, 0x000e, 0x080c, 0x4a04, 0x701f, 0x3a95, 0x015e, 0x00de,
+ 0x9506, 0x0158, 0x012e, 0x9ce0, 0x0018, 0x2001, 0x1819, 0x2004,
+ 0x9c02, 0x2009, 0x000d, 0x12b0, 0x0c28, 0x080c, 0xb983, 0x012e,
+ 0x2009, 0x0003, 0x0178, 0x00e0, 0x900e, 0x2001, 0x0005, 0x080c,
+ 0x6c6b, 0x0126, 0x2091, 0x8000, 0x080c, 0xc04a, 0x080c, 0x6a15,
+ 0x012e, 0x0070, 0xb097, 0x4005, 0xb19a, 0x0010, 0xb097, 0x4006,
+ 0x900e, 0x9085, 0x0001, 0x2001, 0x0030, 0x2a48, 0x00ae, 0x0005,
+ 0xb097, 0x4000, 0x9006, 0x918d, 0x0001, 0x2008, 0x2a48, 0x00ae,
+ 0x0005, 0x81ff, 0x1904, 0x3424, 0x080c, 0x49ce, 0x0904, 0x3427,
+ 0x080c, 0x646a, 0x0904, 0x3424, 0x080c, 0x650c, 0x0904, 0x3424,
+ 0x0804, 0x4461, 0x81ff, 0x1904, 0x3424, 0x080c, 0x49ea, 0x0904,
+ 0x3427, 0x080c, 0x659a, 0x0904, 0x3424, 0x2019, 0x0005, 0x79a8,
+ 0x080c, 0x6527, 0x0904, 0x3424, 0x7888, 0x908a, 0x1000, 0x1a04,
+ 0x3427, 0x8003, 0x800b, 0x810b, 0x9108, 0x080c, 0x8267, 0x79a8,
+ 0xd184, 0x1904, 0x33f2, 0x0804, 0x4461, 0x0126, 0x2091, 0x8000,
+ 0x81ff, 0x0118, 0x2009, 0x0001, 0x0450, 0x2029, 0x07ff, 0x6458,
+ 0x2400, 0x9506, 0x01f8, 0x2508, 0x080c, 0x63a3, 0x11d8, 0x080c,
+ 0x659a, 0x1128, 0x2009, 0x0002, 0x62bc, 0x2518, 0x00c0, 0x2019,
+ 0x0004, 0x900e, 0x080c, 0x6527, 0x1118, 0x2009, 0x0006, 0x0078,
+ 0x7884, 0x908a, 0x1000, 0x1270, 0x8003, 0x800b, 0x810b, 0x9108,
+ 0x080c, 0x8267, 0x8529, 0x1ae0, 0x012e, 0x0804, 0x33f2, 0x012e,
+ 0x0804, 0x3424, 0x012e, 0x0804, 0x3427, 0x080c, 0x49ce, 0x0904,
+ 0x3427, 0x080c, 0x646a, 0x0904, 0x3424, 0xbaa0, 0x2019, 0x0005,
+ 0x00c6, 0x9066, 0x080c, 0x8782, 0x0076, 0x903e, 0x080c, 0x8670,
+ 0x900e, 0x080c, 0xd556, 0x007e, 0x00ce, 0x080c, 0x6506, 0x0804,
+ 0x33f2, 0x080c, 0x49ce, 0x0904, 0x3427, 0x080c, 0x6506, 0x2208,
+ 0x0804, 0x33f2, 0x0156, 0x00d6, 0x00e6, 0x2069, 0x190e, 0x6810,
+ 0x6914, 0x910a, 0x1208, 0x900e, 0x6816, 0x9016, 0x901e, 0x20a9,
+ 0x007e, 0x2069, 0x1000, 0x2d04, 0x905d, 0x0118, 0xb84c, 0x0059,
+ 0x9210, 0x8d68, 0x1f04, 0x3723, 0x2300, 0x9218, 0x00ee, 0x00de,
+ 0x015e, 0x0804, 0x33f2, 0x00f6, 0x0016, 0x907d, 0x0138, 0x9006,
+ 0x8000, 0x2f0c, 0x81ff, 0x0110, 0x2178, 0x0cd0, 0x001e, 0x00fe,
+ 0x0005, 0x2069, 0x190e, 0x6910, 0x62b8, 0x0804, 0x33f2, 0x81ff,
+ 0x0120, 0x2009, 0x0001, 0x0804, 0x3424, 0x0126, 0x2091, 0x8000,
+ 0x080c, 0x54ef, 0x0128, 0x2009, 0x0007, 0x012e, 0x0804, 0x3424,
+ 0x012e, 0x6158, 0x9190, 0x31f3, 0x2215, 0x9294, 0x00ff, 0x6378,
+ 0x83ff, 0x0108, 0x627c, 0x67d8, 0x97c4, 0x000a, 0x98c6, 0x000a,
+ 0x1118, 0x2031, 0x0001, 0x00e8, 0x97c4, 0x0022, 0x98c6, 0x0022,
+ 0x1118, 0x2031, 0x0003, 0x00a8, 0x97c4, 0x0012, 0x98c6, 0x0012,
+ 0x1118, 0x2031, 0x0002, 0x0068, 0x080c, 0x717e, 0x1118, 0x2031,
+ 0x0004, 0x0038, 0xd79c, 0x0120, 0x2009, 0x0005, 0x0804, 0x3424,
+ 0x9036, 0x7e9a, 0x7f9e, 0x0804, 0x33f2, 0x6148, 0x624c, 0x2019,
+ 0x1960, 0x231c, 0x2001, 0x1961, 0x2004, 0x789a, 0x0804, 0x33f2,
+ 0x0126, 0x2091, 0x8000, 0x6138, 0x623c, 0x6340, 0x012e, 0x0804,
+ 0x33f2, 0x080c, 0x49ea, 0x0904, 0x3427, 0xba44, 0xbb38, 0x0804,
+ 0x33f2, 0x080c, 0x0df6, 0x080c, 0x49ea, 0x2110, 0x0904, 0x3427,
+ 0xb804, 0x908c, 0x00ff, 0x918e, 0x0006, 0x0140, 0x9084, 0xff00,
+ 0x9086, 0x0600, 0x2009, 0x0009, 0x1904, 0x3424, 0x0126, 0x2091,
+ 0x8000, 0x2019, 0x0005, 0x00c6, 0x9066, 0x080c, 0x9ad0, 0x080c,
+ 0x8782, 0x0076, 0x903e, 0x080c, 0x8670, 0x900e, 0x080c, 0xd556,
+ 0x007e, 0x00ce, 0xb807, 0x0407, 0x012e, 0x0804, 0x33f2, 0x6148,
+ 0x624c, 0x7884, 0x604a, 0x7b88, 0x634e, 0x2069, 0x185b, 0x831f,
+ 0x9305, 0x6816, 0x788c, 0x2069, 0x1960, 0x2d1c, 0x206a, 0x7e98,
+ 0x9682, 0x0014, 0x1210, 0x2031, 0x07d0, 0x2069, 0x1961, 0x2d04,
+ 0x266a, 0x789a, 0x0804, 0x33f2, 0x0126, 0x2091, 0x8000, 0x6138,
+ 0x7884, 0x603a, 0x910e, 0xd1b4, 0x190c, 0x0ee7, 0xd0c4, 0x01a8,
+ 0x00d6, 0x78a8, 0x2009, 0x1977, 0x200a, 0x78ac, 0x2011, 0x1978,
+ 0x2012, 0x2069, 0x0100, 0x6838, 0x9086, 0x0007, 0x1118, 0x2214,
+ 0x6a5a, 0x0010, 0x210c, 0x695a, 0x00de, 0x2001, 0x0100, 0x2004,
+ 0x9086, 0x000a, 0x0168, 0x2011, 0x0114, 0x220c, 0x7888, 0xd08c,
+ 0x0118, 0x918d, 0x0080, 0x0010, 0x918c, 0xff7f, 0x2112, 0x0060,
+ 0x2011, 0x0116, 0x220c, 0x7888, 0xd08c, 0x0118, 0x918d, 0x0040,
+ 0x0010, 0x918c, 0xff7f, 0x2112, 0x603c, 0x7988, 0x613e, 0x6140,
+ 0x910d, 0x788c, 0x6042, 0x7a88, 0x9294, 0x1000, 0x9205, 0x910e,
+ 0xd1e4, 0x190c, 0x0efd, 0x6040, 0xd0cc, 0x0120, 0x78b0, 0x2011,
+ 0x0114, 0x2012, 0x012e, 0x0804, 0x33f2, 0x00f6, 0x2079, 0x1800,
+ 0x7a38, 0xa898, 0x9084, 0xfebf, 0x9215, 0xa89c, 0x9084, 0xfebf,
+ 0x8002, 0x9214, 0x7838, 0x9084, 0x0140, 0x9215, 0x7a3a, 0xa897,
+ 0x4000, 0x900e, 0x9085, 0x0001, 0x2001, 0x0000, 0x00fe, 0x0005,
+ 0x7898, 0x9005, 0x01a8, 0x7888, 0x9025, 0x0904, 0x3427, 0x788c,
+ 0x902d, 0x0904, 0x3427, 0x900e, 0x080c, 0x63a3, 0x1120, 0xba44,
+ 0xbb38, 0xbc46, 0xbd3a, 0x9186, 0x07ff, 0x0190, 0x8108, 0x0ca0,
+ 0x080c, 0x49ea, 0x0904, 0x3427, 0x7888, 0x900d, 0x0904, 0x3427,
+ 0x788c, 0x9005, 0x0904, 0x3427, 0xba44, 0xb946, 0xbb38, 0xb83a,
+ 0x0804, 0x33f2, 0x2011, 0xbc09, 0x0010, 0x2011, 0xbc05, 0x080c,
+ 0x54ef, 0x1904, 0x3424, 0x00c6, 0x2061, 0x0100, 0x7984, 0x9186,
+ 0x00ff, 0x1130, 0x2001, 0x1817, 0x2004, 0x9085, 0xff00, 0x0088,
+ 0x9182, 0x007f, 0x16e0, 0x9188, 0x31f3, 0x210d, 0x918c, 0x00ff,
+ 0x2001, 0x1817, 0x2004, 0x0026, 0x9116, 0x002e, 0x0580, 0x810f,
+ 0x9105, 0x0126, 0x2091, 0x8000, 0x0006, 0x080c, 0x9f94, 0x000e,
+ 0x0510, 0x602e, 0x620a, 0x7984, 0x00b6, 0x080c, 0x6349, 0x2b08,
+ 0x00be, 0x1500, 0x6112, 0x6023, 0x0001, 0x080c, 0x49b7, 0x01d0,
+ 0x9006, 0xa866, 0x7007, 0x0003, 0xa832, 0xa868, 0xc0fd, 0xa86a,
+ 0x701f, 0x38ed, 0x2900, 0x6016, 0x2009, 0x0032, 0x080c, 0xa068,
+ 0x012e, 0x00ce, 0x0005, 0x012e, 0x00ce, 0x0804, 0x3424, 0x00ce,
+ 0x0804, 0x3427, 0x080c, 0x9fea, 0x0cb0, 0xa830, 0x9086, 0x0100,
+ 0x0904, 0x3424, 0x0804, 0x33f2, 0x2061, 0x1a4c, 0x0126, 0x2091,
+ 0x8000, 0x6000, 0xd084, 0x0170, 0x6104, 0x6208, 0x2061, 0x1800,
+ 0x6350, 0x6070, 0x789a, 0x60bc, 0x789e, 0x60b8, 0x78aa, 0x012e,
+ 0x0804, 0x33f2, 0x900e, 0x2110, 0x0c88, 0x81ff, 0x1904, 0x3424,
+ 0x080c, 0x717e, 0x0904, 0x3424, 0x0126, 0x2091, 0x8000, 0x6250,
+ 0x6070, 0x9202, 0x0248, 0x9085, 0x0001, 0x080c, 0x26d6, 0x080c,
+ 0x5712, 0x012e, 0x0804, 0x33f2, 0x012e, 0x0804, 0x3427, 0x0006,
+ 0x0016, 0x00c6, 0x00e6, 0x2001, 0x1984, 0x2070, 0x2061, 0x185b,
+ 0x6008, 0x2072, 0x900e, 0x2011, 0x1400, 0x080c, 0x847e, 0x7206,
+ 0x00ee, 0x00ce, 0x001e, 0x000e, 0x0005, 0x0126, 0x2091, 0x8000,
+ 0x81ff, 0x0128, 0x012e, 0x2021, 0x400b, 0x0804, 0x33f4, 0x7884,
+ 0xd0fc, 0x0158, 0x2001, 0x002a, 0x2004, 0x9005, 0x0180, 0x9082,
+ 0x00e1, 0x0298, 0x012e, 0x0804, 0x3427, 0x2001, 0x002a, 0x2004,
+ 0x9005, 0x0128, 0x2069, 0x185b, 0x6908, 0x9102, 0x1230, 0x012e,
+ 0x0804, 0x3427, 0x012e, 0x0804, 0x3424, 0x080c, 0x9f69, 0x0dd0,
+ 0x7884, 0xd0fc, 0x0904, 0x39bc, 0x00c6, 0x080c, 0x49b7, 0x00ce,
+ 0x0d88, 0xa867, 0x0000, 0x7884, 0xa80a, 0x7898, 0xa80e, 0x789c,
+ 0xa812, 0x2001, 0x002e, 0x2004, 0xa81a, 0x2001, 0x002f, 0x2004,
+ 0xa81e, 0x2001, 0x0030, 0x2004, 0xa822, 0x2001, 0x0031, 0x2004,
+ 0xa826, 0x2001, 0x0034, 0x2004, 0xa82a, 0x2001, 0x0035, 0x2004,
+ 0xa82e, 0x2001, 0x002a, 0x2004, 0x9080, 0x0003, 0x9084, 0x00fc,
+ 0x8004, 0xa816, 0x080c, 0x3b42, 0x0928, 0x7014, 0x2048, 0xad2c,
+ 0xac28, 0xab1c, 0xaa18, 0xa930, 0xa808, 0xd0b4, 0x1120, 0x2029,
+ 0x0000, 0x2021, 0x0000, 0x8906, 0x8006, 0x8007, 0x90bc, 0x003f,
+ 0x9084, 0xffc0, 0x9080, 0x001b, 0x080c, 0x4a00, 0x701f, 0x3a7f,
+ 0x7023, 0x0001, 0x012e, 0x0005, 0x0046, 0x0086, 0x0096, 0x00a6,
+ 0x00b6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x080c, 0x3927, 0x2001,
+ 0x197a, 0x2003, 0x0000, 0x2021, 0x000a, 0x2061, 0x0100, 0x6104,
+ 0x0016, 0x60bb, 0x0000, 0x60bf, 0x32e1, 0x60bf, 0x0012, 0x080c,
+ 0x3bb1, 0x080c, 0x3b70, 0x00f6, 0x00e6, 0x0086, 0x2940, 0x2071,
+ 0x1a42, 0x2079, 0x0090, 0x00d6, 0x2069, 0x0000, 0x6884, 0xd0b4,
+ 0x0140, 0x2001, 0x0035, 0x2004, 0x780e, 0x2001, 0x0034, 0x2004,
+ 0x780a, 0x00de, 0x2011, 0x0001, 0x080c, 0x3fb1, 0x008e, 0x00ee,
+ 0x00fe, 0x080c, 0x3ed3, 0x080c, 0x3d98, 0x05b8, 0x2001, 0x020b,
+ 0x2004, 0x9084, 0x0140, 0x1db8, 0x080c, 0x4025, 0x00f6, 0x2079,
+ 0x0300, 0x78bc, 0x00fe, 0x908c, 0x0070, 0x1560, 0x2071, 0x0200,
+ 0x7037, 0x0000, 0x7050, 0x9084, 0xff00, 0x9086, 0x3200, 0x1510,
+ 0x7037, 0x0001, 0x7050, 0x9084, 0xff00, 0x9086, 0xe100, 0x11d0,
+ 0x7037, 0x0000, 0x7054, 0x7037, 0x0000, 0x715c, 0x9106, 0x1190,
+ 0x2001, 0x181f, 0x2004, 0x9106, 0x1168, 0x00c6, 0x2061, 0x0100,
+ 0x6024, 0x9084, 0x1e00, 0x00ce, 0x0138, 0x080c, 0x3da2, 0x080c,
+ 0x3b6b, 0x0058, 0x080c, 0x3b6b, 0x080c, 0x3f49, 0x080c, 0x3ec9,
+ 0x2001, 0x020b, 0x2004, 0xd0e4, 0x0dd8, 0x2001, 0x032a, 0x2003,
+ 0x0004, 0x2061, 0x0100, 0x6027, 0x0002, 0x001e, 0x6106, 0x2011,
+ 0x020d, 0x2013, 0x0020, 0x60bb, 0x0000, 0x60bf, 0x0108, 0x60bf,
+ 0x0012, 0x2001, 0x0004, 0x200c, 0x918c, 0xfffd, 0x2102, 0x080c,
+ 0x12fe, 0x2009, 0x0028, 0x080c, 0x2200, 0x2001, 0x0227, 0x200c,
+ 0x2102, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x00be, 0x00ae, 0x009e,
+ 0x008e, 0x004e, 0x2001, 0x197a, 0x2004, 0x9005, 0x1118, 0x012e,
+ 0x0804, 0x33f2, 0x012e, 0x2021, 0x400c, 0x0804, 0x33f4, 0x0016,
+ 0x0026, 0x0036, 0x0046, 0x0056, 0x0076, 0x0086, 0x0096, 0x00d6,
+ 0x0156, 0x7014, 0x2048, 0x7020, 0x20a8, 0x8000, 0x7022, 0xa804,
+ 0x9005, 0x0904, 0x3adb, 0x2048, 0x1f04, 0x3a8f, 0x7068, 0x2040,
+ 0xa28c, 0xa390, 0xa494, 0xa598, 0xa930, 0xa808, 0xd0b4, 0x1120,
+ 0x2029, 0x0000, 0x2021, 0x0000, 0x0096, 0x7014, 0x2048, 0xa864,
+ 0x009e, 0x9086, 0x0103, 0x0170, 0x8906, 0x8006, 0x8007, 0x90bc,
+ 0x003f, 0x9084, 0xffc0, 0x9080, 0x001b, 0x080c, 0x4a00, 0x701f,
+ 0x3a7f, 0x00b0, 0x8906, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084,
+ 0xffc0, 0x9080, 0x001b, 0x21a8, 0x27e0, 0x2098, 0x27e8, 0x20a0,
+ 0x0006, 0x080c, 0x0fb4, 0x000e, 0x080c, 0x4a03, 0x701f, 0x3a7f,
+ 0x015e, 0x00de, 0x009e, 0x008e, 0x007e, 0x005e, 0x004e, 0x003e,
+ 0x002e, 0x001e, 0x0005, 0x7014, 0x2048, 0xa864, 0x9086, 0x0103,
+ 0x1118, 0x701f, 0x3b40, 0x0450, 0x7014, 0x2048, 0xa868, 0xc0fd,
+ 0xa86a, 0x2009, 0x007f, 0x080c, 0x6343, 0x0110, 0x9006, 0x0030,
+ 0xb813, 0x00ff, 0xb817, 0xfffd, 0x080c, 0xc21d, 0x015e, 0x00de,
0x009e, 0x008e, 0x007e, 0x005e, 0x004e, 0x003e, 0x002e, 0x001e,
- 0x0005, 0x7014, 0x2048, 0xa864, 0x9086, 0x0103, 0x1118, 0x701f,
- 0x3b56, 0x0450, 0x7014, 0x2048, 0xa868, 0xc0fd, 0xa86a, 0x2009,
- 0x007f, 0x080c, 0x6344, 0x0110, 0x9006, 0x0030, 0xb813, 0x00ff,
- 0xb817, 0xfffd, 0x080c, 0xc20a, 0x015e, 0x00de, 0x009e, 0x008e,
- 0x007e, 0x005e, 0x004e, 0x003e, 0x002e, 0x001e, 0x0904, 0x343a,
- 0x0016, 0x0026, 0x0036, 0x0046, 0x0056, 0x0076, 0x0086, 0x0096,
- 0x00d6, 0x0156, 0x701f, 0x3b28, 0x7007, 0x0003, 0x0804, 0x3ae6,
- 0xa830, 0x9086, 0x0100, 0x2021, 0x400c, 0x0904, 0x340a, 0x0076,
- 0xad10, 0xac0c, 0xab24, 0xaa20, 0xa930, 0xa808, 0xd0b4, 0x1120,
- 0x2029, 0x0000, 0x2021, 0x0000, 0x8906, 0x8006, 0x8007, 0x90bc,
- 0x003f, 0x9084, 0xffc0, 0x9080, 0x001b, 0x21a8, 0x27e0, 0x2098,
- 0x27e8, 0x20a0, 0x0006, 0x080c, 0x0fc0, 0x000e, 0x080c, 0x4a04,
- 0x007e, 0x701f, 0x3a95, 0x7023, 0x0001, 0x0005, 0x0804, 0x3408,
- 0x0156, 0x00c6, 0xa814, 0x908a, 0x001e, 0x0218, 0xa833, 0x001e,
- 0x0010, 0xa832, 0x0078, 0x81ff, 0x0168, 0x0016, 0x080c, 0x49b8,
- 0x001e, 0x0130, 0xa800, 0x2040, 0xa008, 0xa80a, 0x2100, 0x0c58,
- 0x9006, 0x0010, 0x9085, 0x0001, 0x00ce, 0x015e, 0x0005, 0x0006,
- 0x00f6, 0x2079, 0x0000, 0x7880, 0x9086, 0x0044, 0x00fe, 0x000e,
- 0x0005, 0x2001, 0x1979, 0x2003, 0x0001, 0x0005, 0x00f6, 0x00e6,
- 0x00c6, 0x2061, 0x0200, 0x2001, 0x1984, 0x2004, 0x601a, 0x2061,
- 0x0100, 0x2001, 0x1983, 0x2004, 0x60ce, 0x6104, 0xc1ac, 0x6106,
- 0x080c, 0x49b8, 0xa813, 0x0019, 0xa817, 0x0001, 0x2900, 0xa85a,
- 0x2001, 0x002e, 0x2004, 0xa866, 0x2001, 0x002f, 0x2004, 0xa86a,
- 0x2061, 0x0090, 0x2079, 0x0100, 0x2001, 0x1983, 0x2004, 0x6036,
- 0x2009, 0x0040, 0x080c, 0x2204, 0x2001, 0x002a, 0x2004, 0x9084,
- 0xfff8, 0xa86e, 0x601a, 0xa873, 0x0000, 0x601f, 0x0000, 0x78ca,
- 0x9006, 0x600a, 0x600e, 0x00ce, 0x00ee, 0x00fe, 0x0005, 0x00e6,
- 0x080c, 0x49b8, 0x2940, 0xa013, 0x0019, 0xa017, 0x0001, 0x2800,
- 0xa05a, 0x2001, 0x0030, 0x2004, 0xa866, 0x2001, 0x0031, 0x2004,
- 0xa86a, 0x2001, 0x002a, 0x2004, 0x9084, 0xfff8, 0xa86e, 0xa873,
- 0x0000, 0x2001, 0x032a, 0x2003, 0x0004, 0x2001, 0x0300, 0x2003,
+ 0x0904, 0x3424, 0x0016, 0x0026, 0x0036, 0x0046, 0x0056, 0x0076,
+ 0x0086, 0x0096, 0x00d6, 0x0156, 0x701f, 0x3b12, 0x7007, 0x0003,
+ 0x0804, 0x3ad0, 0xa830, 0x9086, 0x0100, 0x2021, 0x400c, 0x0904,
+ 0x33f4, 0x0076, 0xad10, 0xac0c, 0xab24, 0xaa20, 0xa930, 0xa808,
+ 0xd0b4, 0x1120, 0x2029, 0x0000, 0x2021, 0x0000, 0x8906, 0x8006,
+ 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, 0x001b, 0x21a8,
+ 0x27e0, 0x2098, 0x27e8, 0x20a0, 0x0006, 0x080c, 0x0fb4, 0x000e,
+ 0x080c, 0x4a03, 0x007e, 0x701f, 0x3a7f, 0x7023, 0x0001, 0x0005,
+ 0x0804, 0x33f2, 0x0156, 0x00c6, 0xa814, 0x908a, 0x001e, 0x0218,
+ 0xa833, 0x001e, 0x0010, 0xa832, 0x0078, 0x81ff, 0x0168, 0x0016,
+ 0x080c, 0x49b7, 0x001e, 0x0130, 0xa800, 0x2040, 0xa008, 0xa80a,
+ 0x2100, 0x0c58, 0x9006, 0x0010, 0x9085, 0x0001, 0x00ce, 0x015e,
+ 0x0005, 0x0006, 0x00f6, 0x2079, 0x0000, 0x7880, 0x9086, 0x0044,
+ 0x00fe, 0x000e, 0x0005, 0x2001, 0x197a, 0x2003, 0x0001, 0x0005,
+ 0x00f6, 0x00e6, 0x00c6, 0x2061, 0x0200, 0x2001, 0x1985, 0x2004,
+ 0x601a, 0x2061, 0x0100, 0x2001, 0x1984, 0x2004, 0x60ce, 0x6104,
+ 0xc1ac, 0x6106, 0x080c, 0x49b7, 0xa813, 0x0019, 0xa817, 0x0001,
+ 0x2900, 0xa85a, 0x2001, 0x002e, 0x2004, 0xa866, 0x2001, 0x002f,
+ 0x2004, 0xa86a, 0x2061, 0x0090, 0x2079, 0x0100, 0x2001, 0x1984,
+ 0x2004, 0x6036, 0x2009, 0x0040, 0x080c, 0x2200, 0x2001, 0x002a,
+ 0x2004, 0x9084, 0xfff8, 0xa86e, 0x601a, 0xa873, 0x0000, 0x601f,
+ 0x0000, 0x78ca, 0x9006, 0x600a, 0x600e, 0x00ce, 0x00ee, 0x00fe,
+ 0x0005, 0x00e6, 0x080c, 0x49b7, 0x2940, 0xa013, 0x0019, 0xa017,
+ 0x0001, 0x2800, 0xa05a, 0x2001, 0x0030, 0x2004, 0xa866, 0x2001,
+ 0x0031, 0x2004, 0xa86a, 0x2001, 0x002a, 0x2004, 0x9084, 0xfff8,
+ 0xa86e, 0xa873, 0x0000, 0x2001, 0x032a, 0x2003, 0x0004, 0x2001,
+ 0x0300, 0x2003, 0x0000, 0x2001, 0x020d, 0x2003, 0x0000, 0x2001,
+ 0x0004, 0x200c, 0x918d, 0x0002, 0x2102, 0x00ee, 0x0005, 0x0126,
+ 0x2091, 0x8000, 0x81ff, 0x0148, 0x080c, 0x2a8f, 0x1130, 0x9006,
+ 0x080c, 0x29a3, 0x9006, 0x080c, 0x2986, 0x2001, 0x1979, 0x2003,
+ 0x0000, 0x7884, 0x9084, 0x0007, 0x0002, 0x3c00, 0x3c0f, 0x3c1e,
+ 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x012e, 0x0804, 0x3427,
+ 0x2001, 0x0100, 0x2004, 0x9086, 0x000a, 0x0db8, 0x2009, 0x0114,
+ 0x2104, 0x9085, 0x0800, 0x200a, 0x080c, 0x3dec, 0x00f0, 0x2001,
+ 0x0100, 0x2004, 0x9086, 0x000a, 0x0d40, 0x2009, 0x0114, 0x2104,
+ 0x9085, 0x4000, 0x200a, 0x080c, 0x3dec, 0x0078, 0x080c, 0x717e,
+ 0x1128, 0x012e, 0x2009, 0x0016, 0x0804, 0x3424, 0x81ff, 0x0128,
+ 0x012e, 0x2021, 0x400b, 0x0804, 0x33f4, 0x2001, 0x0141, 0x2004,
+ 0xd0dc, 0x0db0, 0x0086, 0x0096, 0x00a6, 0x00b6, 0x00c6, 0x00d6,
+ 0x00e6, 0x00f6, 0x080c, 0x3927, 0x2009, 0x0101, 0x210c, 0x0016,
+ 0x7ec8, 0x7dcc, 0x9006, 0x2068, 0x2060, 0x2058, 0x080c, 0x4100,
+ 0x080c, 0x4050, 0x903e, 0x2720, 0x00f6, 0x00e6, 0x0086, 0x2940,
+ 0x2071, 0x1a42, 0x2079, 0x0090, 0x00d6, 0x2069, 0x0000, 0x6884,
+ 0xd0b4, 0x0120, 0x68d4, 0x780e, 0x68d0, 0x780a, 0x00de, 0x2011,
+ 0x0001, 0x080c, 0x3fb1, 0x080c, 0x2a97, 0x080c, 0x2a97, 0x080c,
+ 0x2a97, 0x080c, 0x2a97, 0x080c, 0x3fb1, 0x008e, 0x00ee, 0x00fe,
+ 0x080c, 0x3ed3, 0x2009, 0x9c40, 0x8109, 0x11b0, 0x080c, 0x3da2,
+ 0x2001, 0x0004, 0x200c, 0x918c, 0xfffd, 0x2102, 0x001e, 0x00fe,
+ 0x00ee, 0x00de, 0x00ce, 0x00be, 0x00ae, 0x009e, 0x008e, 0x2009,
+ 0x0017, 0x080c, 0x3424, 0x0cf8, 0x2001, 0x020b, 0x2004, 0x9084,
+ 0x0140, 0x1d10, 0x00f6, 0x2079, 0x0000, 0x7884, 0x00fe, 0xd0bc,
+ 0x0178, 0x2001, 0x0201, 0x200c, 0x81ff, 0x0150, 0x080c, 0x3eb1,
+ 0x2d00, 0x9c05, 0x9b05, 0x0120, 0x080c, 0x3da2, 0x0804, 0x3d42,
+ 0x080c, 0x4025, 0x080c, 0x3f49, 0x080c, 0x3e94, 0x080c, 0x3ec9,
+ 0x00f6, 0x2079, 0x0100, 0x7824, 0xd0ac, 0x0130, 0x8b58, 0x080c,
+ 0x3da2, 0x00fe, 0x0804, 0x3d42, 0x00fe, 0x080c, 0x3d98, 0x1150,
+ 0x8d68, 0x2001, 0x0032, 0x2602, 0x2001, 0x0033, 0x2502, 0x080c,
+ 0x3da2, 0x0080, 0x87ff, 0x0138, 0x2001, 0x0201, 0x2004, 0x9005,
+ 0x1908, 0x8739, 0x0038, 0x2001, 0x1a3f, 0x2004, 0x9086, 0x0000,
+ 0x1904, 0x3c92, 0x2001, 0x032f, 0x2003, 0x00f6, 0x8631, 0x1208,
+ 0x8529, 0x2500, 0x9605, 0x0904, 0x3d42, 0x7884, 0xd0bc, 0x0128,
+ 0x2d00, 0x9c05, 0x9b05, 0x1904, 0x3d42, 0xa013, 0x0019, 0x2001,
+ 0x032a, 0x2003, 0x0004, 0x7884, 0xd0ac, 0x1148, 0x2001, 0x1a3f,
+ 0x2003, 0x0003, 0x2001, 0x032a, 0x2003, 0x0009, 0x0030, 0xa017,
+ 0x0001, 0x78b4, 0x9005, 0x0108, 0xa016, 0x2800, 0xa05a, 0x2009,
+ 0x0040, 0x080c, 0x2200, 0x2900, 0xa85a, 0xa813, 0x0019, 0x7884,
+ 0xd0a4, 0x1180, 0xa817, 0x0000, 0x00c6, 0x20a9, 0x0004, 0x2061,
+ 0x0090, 0x602b, 0x0008, 0x2001, 0x0203, 0x2004, 0x1f04, 0x3d19,
+ 0x00ce, 0x0030, 0xa817, 0x0001, 0x78b0, 0x9005, 0x0108, 0xa816,
+ 0x00f6, 0x00c6, 0x2079, 0x0100, 0x2061, 0x0090, 0x7827, 0x0002,
+ 0x2001, 0x002a, 0x2004, 0x9084, 0xfff8, 0x601a, 0x0006, 0x2001,
+ 0x002b, 0x2004, 0x601e, 0x78c6, 0x000e, 0x78ca, 0x00ce, 0x00fe,
+ 0x0804, 0x3c4c, 0x001e, 0x00c6, 0x2001, 0x032a, 0x2003, 0x0004,
+ 0x2061, 0x0100, 0x6027, 0x0002, 0x6106, 0x2011, 0x020d, 0x2013,
+ 0x0020, 0x2001, 0x0004, 0x200c, 0x918c, 0xfffd, 0x2102, 0x080c,
+ 0x12fe, 0x7884, 0x9084, 0x0003, 0x9086, 0x0002, 0x0508, 0x2009,
+ 0x0028, 0x080c, 0x2200, 0x2001, 0x0227, 0x200c, 0x2102, 0x6050,
+ 0x0006, 0x2001, 0x0100, 0x2004, 0x9086, 0x000a, 0x000e, 0x0118,
+ 0x9084, 0xb7ef, 0x0020, 0x9084, 0xb7ff, 0x080c, 0x2bdc, 0x6052,
+ 0x602f, 0x0000, 0x604b, 0xf7f7, 0x6043, 0x0090, 0x6043, 0x0010,
+ 0x00ce, 0x2d08, 0x2c10, 0x2b18, 0x2b00, 0x9c05, 0x9d05, 0x00fe,
+ 0x00ee, 0x00de, 0x00ce, 0x00be, 0x00ae, 0x009e, 0x008e, 0x1118,
+ 0x012e, 0x0804, 0x33f2, 0x012e, 0x2021, 0x400c, 0x0804, 0x33f4,
+ 0x9085, 0x0001, 0x1d04, 0x3da1, 0x2091, 0x6000, 0x8420, 0x9486,
+ 0x0064, 0x0005, 0x2001, 0x0105, 0x2003, 0x0010, 0x2001, 0x032a,
+ 0x2003, 0x0004, 0x2001, 0x1a3f, 0x2003, 0x0000, 0x0071, 0x2009,
+ 0x0048, 0x080c, 0x2200, 0x2001, 0x0227, 0x2024, 0x2402, 0x2001,
+ 0x0109, 0x2003, 0x4000, 0x9026, 0x0005, 0x00f6, 0x00e6, 0x2071,
+ 0x1a42, 0x7000, 0x9086, 0x0000, 0x0520, 0x2079, 0x0090, 0x2009,
+ 0x0206, 0x2104, 0x2009, 0x0203, 0x210c, 0x9106, 0x1120, 0x2009,
+ 0x0040, 0x080c, 0x2200, 0x782c, 0xd0fc, 0x0d88, 0x080c, 0x4025,
+ 0x7000, 0x9086, 0x0000, 0x1d58, 0x782b, 0x0004, 0x782c, 0xd0ac,
+ 0x1de8, 0x2009, 0x0040, 0x080c, 0x2200, 0x782b, 0x0002, 0x7003,
+ 0x0000, 0x00ee, 0x00fe, 0x0005, 0x2001, 0x0100, 0x2004, 0x9086,
+ 0x000a, 0x15d0, 0x00f6, 0x2079, 0x0100, 0x2001, 0x1817, 0x200c,
+ 0x7932, 0x7936, 0x080c, 0x26b6, 0x080c, 0x2ba9, 0x080c, 0x2bdc,
+ 0x784b, 0xf7f7, 0x7843, 0x0090, 0x7843, 0x0010, 0x7850, 0xc0e5,
+ 0x7852, 0x2019, 0x61a8, 0x7820, 0xd09c, 0x0110, 0x8319, 0x1dd8,
+ 0x7850, 0xc0e4, 0x7852, 0x7827, 0x0048, 0x7843, 0x0040, 0x2019,
+ 0x01f4, 0xa001, 0xa001, 0x8319, 0x1de0, 0x2001, 0x0100, 0x080c,
+ 0x2b6f, 0x7827, 0x0020, 0x7843, 0x0000, 0x9006, 0x080c, 0x2b6f,
+ 0x7827, 0x0048, 0x00fe, 0x0005, 0x00f6, 0x2079, 0x0100, 0x2001,
+ 0x1817, 0x200c, 0x7932, 0x7936, 0x080c, 0x26b6, 0x7850, 0x9084,
+ 0xfbff, 0x9085, 0x0030, 0x7852, 0x2019, 0x01f4, 0x8319, 0x1df0,
+ 0x9084, 0xffcf, 0x9085, 0x2000, 0x7852, 0x20a9, 0x0046, 0x1d04,
+ 0x3e47, 0x2091, 0x6000, 0x1f04, 0x3e47, 0x7850, 0x9085, 0x0400,
+ 0x9084, 0xdfff, 0x7852, 0x2001, 0x0021, 0x2004, 0x9084, 0x0003,
+ 0x9086, 0x0001, 0x1120, 0x7850, 0x9084, 0xdfff, 0x7852, 0x784b,
+ 0xf7f7, 0x7843, 0x0090, 0x7843, 0x0010, 0x20a9, 0x0028, 0xa001,
+ 0x1f04, 0x3e67, 0x7850, 0x9085, 0x1400, 0x7852, 0x2019, 0x61a8,
+ 0x7854, 0xa001, 0xa001, 0xd08c, 0x1110, 0x8319, 0x1dc8, 0x7827,
+ 0x0048, 0x7850, 0x9085, 0x0400, 0x7852, 0x7843, 0x0040, 0x2019,
+ 0x01f4, 0xa001, 0xa001, 0x8319, 0x1de0, 0x2001, 0x0100, 0x080c,
+ 0x2b6f, 0x7827, 0x0020, 0x7843, 0x0000, 0x9006, 0x080c, 0x2b6f,
+ 0x7827, 0x0048, 0x00fe, 0x0005, 0x7884, 0xd0ac, 0x11c8, 0x00f6,
+ 0x00e6, 0x2071, 0x1a3f, 0x2079, 0x0320, 0x2001, 0x0201, 0x2004,
+ 0x9005, 0x0160, 0x7000, 0x9086, 0x0000, 0x1140, 0x0051, 0xd0bc,
+ 0x0108, 0x8738, 0x7003, 0x0003, 0x782b, 0x0019, 0x00ee, 0x00fe,
+ 0x0005, 0x00f6, 0x2079, 0x0300, 0x78bc, 0x00fe, 0x908c, 0x0070,
+ 0x0178, 0x2009, 0x0032, 0x260a, 0x2009, 0x0033, 0x250a, 0xd0b4,
+ 0x0108, 0x8c60, 0xd0ac, 0x0108, 0x8d68, 0xd0a4, 0x0108, 0x8b58,
+ 0x0005, 0x00f6, 0x2079, 0x0200, 0x781c, 0xd084, 0x0110, 0x7837,
+ 0x0050, 0x00fe, 0x0005, 0x00e6, 0x2071, 0x0100, 0x2001, 0x1985,
+ 0x2004, 0x70e2, 0x080c, 0x3b61, 0x1188, 0x2001, 0x181f, 0x2004,
+ 0x2009, 0x181e, 0x210c, 0x918c, 0x00ff, 0x706e, 0x716a, 0x7066,
+ 0x918d, 0x3200, 0x7162, 0x7073, 0xe109, 0x0080, 0x702c, 0x9085,
+ 0x0002, 0x702e, 0x2009, 0x1817, 0x210c, 0x716e, 0x7063, 0x0100,
+ 0x7166, 0x719e, 0x706b, 0x0000, 0x7073, 0x0809, 0x7077, 0x0008,
+ 0x7078, 0x9080, 0x0100, 0x707a, 0x7080, 0x8000, 0x7082, 0x7087,
+ 0xaaaa, 0x9006, 0x708a, 0x708e, 0x707e, 0x70d6, 0x70ab, 0x0036,
+ 0x70af, 0x95d5, 0x7014, 0x9084, 0x1984, 0x9085, 0x0092, 0x7016,
+ 0x080c, 0x4025, 0x00f6, 0x2071, 0x1a3f, 0x2079, 0x0320, 0x00d6,
+ 0x2069, 0x0000, 0x6884, 0xd0b4, 0x0120, 0x689c, 0x780e, 0x6898,
+ 0x780a, 0x00de, 0x080c, 0x3b61, 0x0140, 0x2001, 0x1979, 0x200c,
+ 0x2003, 0x0001, 0x918e, 0x0001, 0x0120, 0x2009, 0x03e8, 0x8109,
+ 0x1df0, 0x792c, 0xd1fc, 0x0110, 0x782b, 0x0004, 0x2011, 0x0011,
+ 0x080c, 0x3fb1, 0x2011, 0x0001, 0x080c, 0x3fb1, 0x00fe, 0x00ee,
+ 0x0005, 0x00f6, 0x00e6, 0x2071, 0x1a3f, 0x2079, 0x0320, 0x792c,
+ 0xd1fc, 0x0904, 0x3fae, 0x782b, 0x0002, 0x9026, 0xd19c, 0x1904,
+ 0x3faa, 0x7000, 0x0002, 0x3fae, 0x3f5f, 0x3f8f, 0x3faa, 0xd1bc,
+ 0x1170, 0xd1dc, 0x1190, 0x8001, 0x7002, 0x2011, 0x0001, 0x080c,
+ 0x3fb1, 0x0904, 0x3fae, 0x080c, 0x3fb1, 0x0804, 0x3fae, 0x00f6,
+ 0x2079, 0x0300, 0x78bf, 0x0000, 0x00fe, 0x7810, 0x7914, 0x782b,
+ 0x0004, 0x7812, 0x7916, 0x2001, 0x0201, 0x200c, 0x81ff, 0x0de8,
+ 0x080c, 0x3eb1, 0x2009, 0x0001, 0x00f6, 0x2079, 0x0300, 0x78b8,
+ 0x00fe, 0xd0ec, 0x0110, 0x2009, 0x0011, 0x792a, 0x00f8, 0x8001,
+ 0x7002, 0x9184, 0x0880, 0x1140, 0x782c, 0xd0fc, 0x1904, 0x3f53,
+ 0x2011, 0x0001, 0x00b1, 0x0090, 0xa010, 0x9092, 0x0004, 0x9086,
+ 0x0015, 0x1120, 0xa000, 0xa05a, 0x2011, 0x0031, 0xa212, 0xd1dc,
+ 0x1960, 0x0828, 0x782b, 0x0004, 0x7003, 0x0000, 0x00ee, 0x00fe,
+ 0x0005, 0xa014, 0x9005, 0x0550, 0x8001, 0x0036, 0x0096, 0xa016,
+ 0xa058, 0x2048, 0xa010, 0x2009, 0x0031, 0x911a, 0x831c, 0x831c,
+ 0x938a, 0x0007, 0x1a0c, 0x0df6, 0x9398, 0x3fdf, 0x231d, 0x083f,
+ 0x9080, 0x0004, 0x7a2a, 0x7100, 0x8108, 0x7102, 0x009e, 0x003e,
+ 0x908a, 0x0035, 0x1140, 0x0096, 0xa058, 0x2048, 0xa804, 0xa05a,
+ 0x2001, 0x0019, 0x009e, 0xa012, 0x9085, 0x0001, 0x0005, 0x401c,
+ 0x4013, 0x400a, 0x4001, 0x3ff8, 0x3fef, 0x3fe6, 0xa964, 0x7902,
+ 0xa968, 0x7906, 0xa96c, 0x7912, 0xa970, 0x7916, 0x0005, 0xa974,
+ 0x7902, 0xa978, 0x7906, 0xa97c, 0x7912, 0xa980, 0x7916, 0x0005,
+ 0xa984, 0x7902, 0xa988, 0x7906, 0xa98c, 0x7912, 0xa990, 0x7916,
+ 0x0005, 0xa994, 0x7902, 0xa998, 0x7906, 0xa99c, 0x7912, 0xa9a0,
+ 0x7916, 0x0005, 0xa9a4, 0x7902, 0xa9a8, 0x7906, 0xa9ac, 0x7912,
+ 0xa9b0, 0x7916, 0x0005, 0xa9b4, 0x7902, 0xa9b8, 0x7906, 0xa9bc,
+ 0x7912, 0xa9c0, 0x7916, 0x0005, 0xa9c4, 0x7902, 0xa9c8, 0x7906,
+ 0xa9cc, 0x7912, 0xa9d0, 0x7916, 0x0005, 0x00f6, 0x00e6, 0x0086,
+ 0x2071, 0x1a42, 0x2079, 0x0090, 0x792c, 0xd1fc, 0x01e8, 0x782b,
+ 0x0002, 0x2940, 0x9026, 0x7000, 0x0002, 0x404c, 0x4038, 0x4043,
+ 0x8001, 0x7002, 0xd19c, 0x1180, 0x2011, 0x0001, 0x080c, 0x3fb1,
+ 0x190c, 0x3fb1, 0x0048, 0x8001, 0x7002, 0x782c, 0xd0fc, 0x1d38,
+ 0x2011, 0x0001, 0x080c, 0x3fb1, 0x008e, 0x00ee, 0x00fe, 0x0005,
+ 0x00f6, 0x00e6, 0x00c6, 0x0086, 0x2061, 0x0200, 0x2001, 0x1985,
+ 0x2004, 0x601a, 0x2061, 0x0100, 0x2001, 0x1984, 0x2004, 0x60ce,
+ 0x6104, 0xc1ac, 0x6106, 0x2001, 0x002c, 0x2004, 0x9005, 0x0520,
+ 0x2038, 0x2001, 0x002e, 0x2024, 0x2001, 0x002f, 0x201c, 0x080c,
+ 0x49b7, 0xa813, 0x0019, 0xaf16, 0x2900, 0xa85a, 0x978a, 0x0007,
+ 0x0220, 0x2138, 0x2009, 0x0007, 0x0010, 0x2708, 0x903e, 0x0096,
+ 0xa858, 0x2048, 0xa85c, 0x9080, 0x0019, 0x009e, 0x080c, 0x40c8,
+ 0x1d68, 0x2900, 0xa85a, 0x00d0, 0x080c, 0x49b7, 0xa813, 0x0019,
+ 0xa817, 0x0001, 0x2900, 0xa85a, 0x2001, 0x002e, 0x2004, 0xa866,
+ 0x2001, 0x002f, 0x2004, 0xa86a, 0x2001, 0x002a, 0x2004, 0x9084,
+ 0xfff8, 0xa86e, 0x2001, 0x002b, 0x2004, 0xa872, 0x2061, 0x0090,
+ 0x2079, 0x0100, 0x2001, 0x1984, 0x2004, 0x6036, 0x2009, 0x0040,
+ 0x080c, 0x2200, 0x2001, 0x002a, 0x2004, 0x9084, 0xfff8, 0x601a,
+ 0x0006, 0x2001, 0x002b, 0x2004, 0x601e, 0x78c6, 0x000e, 0x78ca,
+ 0x9006, 0x600a, 0x600e, 0x008e, 0x00ce, 0x00ee, 0x00fe, 0x0005,
+ 0x00e6, 0x2071, 0x0080, 0xaa60, 0x22e8, 0x20a0, 0x20e1, 0x0000,
+ 0x2099, 0x0088, 0x702b, 0x0026, 0x7402, 0x7306, 0x9006, 0x700a,
+ 0x700e, 0x810b, 0x810b, 0x21a8, 0x810b, 0x7112, 0x702b, 0x0041,
+ 0x702c, 0xd0fc, 0x0de8, 0x702b, 0x0002, 0x702b, 0x0040, 0x4005,
+ 0x7400, 0x7304, 0x87ff, 0x0190, 0x0086, 0x0096, 0x2940, 0x0086,
+ 0x080c, 0x49b7, 0x008e, 0xa058, 0x00a6, 0x2050, 0x2900, 0xb006,
+ 0xa05a, 0x00ae, 0x009e, 0x008e, 0x9085, 0x0001, 0x00ee, 0x0005,
+ 0x00e6, 0x2001, 0x002d, 0x2004, 0x9005, 0x0528, 0x2038, 0x2001,
+ 0x0030, 0x2024, 0x2001, 0x0031, 0x201c, 0x080c, 0x49b7, 0x2940,
+ 0xa813, 0x0019, 0xaf16, 0x2900, 0xa85a, 0x978a, 0x0007, 0x0220,
+ 0x2138, 0x2009, 0x0007, 0x0010, 0x2708, 0x903e, 0x0096, 0xa858,
+ 0x2048, 0xa85c, 0x9080, 0x0019, 0x009e, 0x080c, 0x40c8, 0x1d68,
+ 0x2900, 0xa85a, 0x00d8, 0x080c, 0x49b7, 0x2940, 0xa013, 0x0019,
+ 0xa017, 0x0001, 0x2800, 0xa05a, 0x2001, 0x0030, 0x2004, 0xa066,
+ 0x2001, 0x0031, 0x2004, 0xa06a, 0x2001, 0x002a, 0x2004, 0x9084,
+ 0xfff8, 0xa06e, 0x2001, 0x002b, 0x2004, 0xa072, 0x2001, 0x032a,
+ 0x2003, 0x0004, 0x7884, 0xd0ac, 0x1180, 0x2001, 0x0101, 0x200c,
+ 0x918d, 0x0200, 0x2102, 0xa017, 0x0000, 0x2001, 0x1a3f, 0x2003,
+ 0x0003, 0x2001, 0x032a, 0x2003, 0x0009, 0x2001, 0x0300, 0x2003,
0x0000, 0x2001, 0x020d, 0x2003, 0x0000, 0x2001, 0x0004, 0x200c,
0x918d, 0x0002, 0x2102, 0x00ee, 0x0005, 0x0126, 0x2091, 0x8000,
- 0x81ff, 0x0148, 0x080c, 0x2aa8, 0x1130, 0x9006, 0x080c, 0x29b8,
- 0x9006, 0x080c, 0x299b, 0x7884, 0x9084, 0x0007, 0x0002, 0x3c12,
- 0x3c21, 0x3c30, 0x3c0f, 0x3c0f, 0x3c0f, 0x3c0f, 0x3c0f, 0x012e,
- 0x0804, 0x343d, 0x2001, 0x0100, 0x2004, 0x9086, 0x000a, 0x0db8,
- 0x2009, 0x0114, 0x2104, 0x9085, 0x0800, 0x200a, 0x080c, 0x3e02,
- 0x00f0, 0x2001, 0x0100, 0x2004, 0x9086, 0x000a, 0x0d40, 0x2009,
- 0x0114, 0x2104, 0x9085, 0x4000, 0x200a, 0x080c, 0x3e02, 0x0078,
- 0x080c, 0x717f, 0x1128, 0x012e, 0x2009, 0x0016, 0x0804, 0x343a,
- 0x81ff, 0x0128, 0x012e, 0x2021, 0x400b, 0x0804, 0x340a, 0x6000,
- 0x9086, 0x0003, 0x1db8, 0x2001, 0x0141, 0x2004, 0xd0dc, 0x0d90,
- 0x0086, 0x0096, 0x00a6, 0x00b6, 0x00c6, 0x00d6, 0x00e6, 0x00f6,
- 0x080c, 0x393d, 0x2009, 0x0101, 0x210c, 0x0016, 0x7ec8, 0x7dcc,
- 0x9006, 0x2068, 0x2060, 0x2058, 0x080c, 0x410b, 0x080c, 0x405b,
- 0x903e, 0x2720, 0x00f6, 0x00e6, 0x0086, 0x2940, 0x2071, 0x1a42,
- 0x2079, 0x0090, 0x00d6, 0x2069, 0x0000, 0x6884, 0xd0b4, 0x0120,
- 0x68d4, 0x780e, 0x68d0, 0x780a, 0x00de, 0x2011, 0x0001, 0x080c,
- 0x3fbc, 0x080c, 0x2ab0, 0x080c, 0x2ab0, 0x080c, 0x2ab0, 0x080c,
- 0x2ab0, 0x080c, 0x3fbc, 0x008e, 0x00ee, 0x00fe, 0x080c, 0x3ee9,
- 0x2009, 0x9c40, 0x8109, 0x11b0, 0x080c, 0x3db8, 0x2001, 0x0004,
- 0x200c, 0x918c, 0xfffd, 0x2102, 0x001e, 0x00fe, 0x00ee, 0x00de,
- 0x00ce, 0x00be, 0x00ae, 0x009e, 0x008e, 0x2009, 0x0017, 0x080c,
- 0x343a, 0x0cf8, 0x2001, 0x020b, 0x2004, 0x9084, 0x0140, 0x1d10,
- 0x00f6, 0x2079, 0x0000, 0x7884, 0x00fe, 0xd0bc, 0x0178, 0x2001,
- 0x0201, 0x200c, 0x81ff, 0x0150, 0x080c, 0x3ec7, 0x2d00, 0x9c05,
- 0x9b05, 0x0120, 0x080c, 0x3db8, 0x0804, 0x3d58, 0x080c, 0x4030,
- 0x080c, 0x3f54, 0x080c, 0x3eaa, 0x080c, 0x3edf, 0x00f6, 0x2079,
- 0x0100, 0x7824, 0xd0ac, 0x0130, 0x8b58, 0x080c, 0x3db8, 0x00fe,
- 0x0804, 0x3d58, 0x00fe, 0x080c, 0x3dae, 0x1150, 0x8d68, 0x2001,
- 0x0032, 0x2602, 0x2001, 0x0033, 0x2502, 0x080c, 0x3db8, 0x0080,
- 0x87ff, 0x0138, 0x2001, 0x0201, 0x2004, 0x9005, 0x1908, 0x8739,
- 0x0038, 0x2001, 0x1a3f, 0x2004, 0x9086, 0x0000, 0x1904, 0x3ca8,
- 0x2001, 0x032f, 0x2003, 0x00f6, 0x8631, 0x1208, 0x8529, 0x2500,
- 0x9605, 0x0904, 0x3d58, 0x7884, 0xd0bc, 0x0128, 0x2d00, 0x9c05,
- 0x9b05, 0x1904, 0x3d58, 0xa013, 0x0019, 0x2001, 0x032a, 0x2003,
- 0x0004, 0x7884, 0xd0ac, 0x1148, 0x2001, 0x1a3f, 0x2003, 0x0003,
- 0x2001, 0x032a, 0x2003, 0x0009, 0x0030, 0xa017, 0x0001, 0x78b4,
- 0x9005, 0x0108, 0xa016, 0x2800, 0xa05a, 0x2009, 0x0040, 0x080c,
- 0x2204, 0x2900, 0xa85a, 0xa813, 0x0019, 0x7884, 0xd0a4, 0x1180,
- 0xa817, 0x0000, 0x00c6, 0x20a9, 0x0004, 0x2061, 0x0090, 0x602b,
- 0x0008, 0x2001, 0x0203, 0x2004, 0x1f04, 0x3d2f, 0x00ce, 0x0030,
- 0xa817, 0x0001, 0x78b0, 0x9005, 0x0108, 0xa816, 0x00f6, 0x00c6,
- 0x2079, 0x0100, 0x2061, 0x0090, 0x7827, 0x0002, 0x2001, 0x002a,
- 0x2004, 0x9084, 0xfff8, 0x601a, 0x0006, 0x2001, 0x002b, 0x2004,
- 0x601e, 0x78c6, 0x000e, 0x78ca, 0x00ce, 0x00fe, 0x0804, 0x3c62,
- 0x001e, 0x00c6, 0x2001, 0x032a, 0x2003, 0x0004, 0x2061, 0x0100,
- 0x6027, 0x0002, 0x6106, 0x2011, 0x020d, 0x2013, 0x0020, 0x2001,
- 0x0004, 0x200c, 0x918c, 0xfffd, 0x2102, 0x080c, 0x130a, 0x7884,
- 0x9084, 0x0003, 0x9086, 0x0002, 0x0508, 0x2009, 0x0028, 0x080c,
- 0x2204, 0x2001, 0x0227, 0x200c, 0x2102, 0x6050, 0x0006, 0x2001,
- 0x0100, 0x2004, 0x9086, 0x000a, 0x000e, 0x0118, 0x9084, 0xb7ef,
- 0x0020, 0x9084, 0xb7ff, 0x080c, 0x2bf5, 0x6052, 0x602f, 0x0000,
- 0x604b, 0xf7f7, 0x6043, 0x0090, 0x6043, 0x0010, 0x00ce, 0x2d08,
- 0x2c10, 0x2b18, 0x2b00, 0x9c05, 0x9d05, 0x00fe, 0x00ee, 0x00de,
- 0x00ce, 0x00be, 0x00ae, 0x009e, 0x008e, 0x1118, 0x012e, 0x0804,
- 0x3408, 0x012e, 0x2021, 0x400c, 0x0804, 0x340a, 0x9085, 0x0001,
- 0x1d04, 0x3db7, 0x2091, 0x6000, 0x8420, 0x9486, 0x0064, 0x0005,
- 0x2001, 0x0105, 0x2003, 0x0010, 0x2001, 0x032a, 0x2003, 0x0004,
- 0x2001, 0x1a3f, 0x2003, 0x0000, 0x0071, 0x2009, 0x0048, 0x080c,
- 0x2204, 0x2001, 0x0227, 0x2024, 0x2402, 0x2001, 0x0109, 0x2003,
- 0x4000, 0x9026, 0x0005, 0x00f6, 0x00e6, 0x2071, 0x1a42, 0x7000,
- 0x9086, 0x0000, 0x0520, 0x2079, 0x0090, 0x2009, 0x0206, 0x2104,
- 0x2009, 0x0203, 0x210c, 0x9106, 0x1120, 0x2009, 0x0040, 0x080c,
- 0x2204, 0x782c, 0xd0fc, 0x0d88, 0x080c, 0x4030, 0x7000, 0x9086,
- 0x0000, 0x1d58, 0x782b, 0x0004, 0x782c, 0xd0ac, 0x1de8, 0x2009,
- 0x0040, 0x080c, 0x2204, 0x782b, 0x0002, 0x7003, 0x0000, 0x00ee,
- 0x00fe, 0x0005, 0x2001, 0x0100, 0x2004, 0x9086, 0x000a, 0x15d0,
- 0x00f6, 0x2079, 0x0100, 0x2001, 0x1817, 0x200c, 0x7932, 0x7936,
- 0x080c, 0x26b7, 0x080c, 0x2bc2, 0x080c, 0x2bf5, 0x784b, 0xf7f7,
- 0x7843, 0x0090, 0x7843, 0x0010, 0x7850, 0xc0e5, 0x7852, 0x2019,
- 0x61a8, 0x7820, 0xd09c, 0x0110, 0x8319, 0x1dd8, 0x7850, 0xc0e4,
- 0x7852, 0x7827, 0x0048, 0x7843, 0x0040, 0x2019, 0x01f4, 0xa001,
- 0xa001, 0x8319, 0x1de0, 0x2001, 0x0100, 0x080c, 0x2b88, 0x7827,
- 0x0020, 0x7843, 0x0000, 0x9006, 0x080c, 0x2b88, 0x7827, 0x0048,
- 0x00fe, 0x0005, 0x00f6, 0x2079, 0x0100, 0x2001, 0x1817, 0x200c,
- 0x7932, 0x7936, 0x080c, 0x26b7, 0x7850, 0x9084, 0xfbff, 0x9085,
- 0x0030, 0x7852, 0x2019, 0x01f4, 0x8319, 0x1df0, 0x9084, 0xffcf,
- 0x9085, 0x2000, 0x7852, 0x20a9, 0x0046, 0x1d04, 0x3e5d, 0x2091,
- 0x6000, 0x1f04, 0x3e5d, 0x7850, 0x9085, 0x0400, 0x9084, 0xdfff,
- 0x7852, 0x2001, 0x0021, 0x2004, 0x9084, 0x0003, 0x9086, 0x0001,
- 0x1120, 0x7850, 0x9084, 0xdfff, 0x7852, 0x784b, 0xf7f7, 0x7843,
- 0x0090, 0x7843, 0x0010, 0x20a9, 0x0028, 0xa001, 0x1f04, 0x3e7d,
- 0x7850, 0x9085, 0x1400, 0x7852, 0x2019, 0x61a8, 0x7854, 0xa001,
- 0xa001, 0xd08c, 0x1110, 0x8319, 0x1dc8, 0x7827, 0x0048, 0x7850,
- 0x9085, 0x0400, 0x7852, 0x7843, 0x0040, 0x2019, 0x01f4, 0xa001,
- 0xa001, 0x8319, 0x1de0, 0x2001, 0x0100, 0x080c, 0x2b88, 0x7827,
- 0x0020, 0x7843, 0x0000, 0x9006, 0x080c, 0x2b88, 0x7827, 0x0048,
- 0x00fe, 0x0005, 0x7884, 0xd0ac, 0x11c8, 0x00f6, 0x00e6, 0x2071,
- 0x1a3f, 0x2079, 0x0320, 0x2001, 0x0201, 0x2004, 0x9005, 0x0160,
- 0x7000, 0x9086, 0x0000, 0x1140, 0x0051, 0xd0bc, 0x0108, 0x8738,
- 0x7003, 0x0003, 0x782b, 0x0019, 0x00ee, 0x00fe, 0x0005, 0x00f6,
- 0x2079, 0x0300, 0x78bc, 0x00fe, 0x908c, 0x0070, 0x0178, 0x2009,
- 0x0032, 0x260a, 0x2009, 0x0033, 0x250a, 0xd0b4, 0x0108, 0x8c60,
- 0xd0ac, 0x0108, 0x8d68, 0xd0a4, 0x0108, 0x8b58, 0x0005, 0x00f6,
- 0x2079, 0x0200, 0x781c, 0xd084, 0x0110, 0x7837, 0x0050, 0x00fe,
- 0x0005, 0x00e6, 0x2071, 0x0100, 0x2001, 0x1984, 0x2004, 0x70e2,
- 0x080c, 0x3b77, 0x1188, 0x2001, 0x181f, 0x2004, 0x2009, 0x181e,
- 0x210c, 0x918c, 0x00ff, 0x706e, 0x716a, 0x7066, 0x918d, 0x3200,
- 0x7162, 0x7073, 0xe109, 0x0080, 0x702c, 0x9085, 0x0002, 0x702e,
- 0x2009, 0x1817, 0x210c, 0x716e, 0x7063, 0x0100, 0x7166, 0x719e,
- 0x706b, 0x0000, 0x7073, 0x0809, 0x7077, 0x0008, 0x7078, 0x9080,
- 0x0100, 0x707a, 0x7080, 0x8000, 0x7082, 0x7087, 0xaaaa, 0x9006,
- 0x708a, 0x708e, 0x707e, 0x70d6, 0x70ab, 0x0036, 0x70af, 0x95d5,
- 0x7014, 0x9084, 0x1984, 0x9085, 0x0092, 0x7016, 0x080c, 0x4030,
- 0x00f6, 0x2071, 0x1a3f, 0x2079, 0x0320, 0x00d6, 0x2069, 0x0000,
- 0x6884, 0xd0b4, 0x0120, 0x689c, 0x780e, 0x6898, 0x780a, 0x00de,
- 0x2009, 0x03e8, 0x8109, 0x1df0, 0x792c, 0xd1fc, 0x0110, 0x782b,
- 0x0004, 0x2011, 0x0011, 0x080c, 0x3fbc, 0x2011, 0x0001, 0x080c,
- 0x3fbc, 0x00fe, 0x00ee, 0x0005, 0x00f6, 0x00e6, 0x2071, 0x1a3f,
- 0x2079, 0x0320, 0x792c, 0xd1fc, 0x0904, 0x3fb9, 0x782b, 0x0002,
- 0x9026, 0xd19c, 0x1904, 0x3fb5, 0x7000, 0x0002, 0x3fb9, 0x3f6a,
- 0x3f9a, 0x3fb5, 0xd1bc, 0x1170, 0xd1dc, 0x1190, 0x8001, 0x7002,
- 0x2011, 0x0001, 0x080c, 0x3fbc, 0x0904, 0x3fb9, 0x080c, 0x3fbc,
- 0x0804, 0x3fb9, 0x00f6, 0x2079, 0x0300, 0x78bf, 0x0000, 0x00fe,
- 0x7810, 0x7914, 0x782b, 0x0004, 0x7812, 0x7916, 0x2001, 0x0201,
- 0x200c, 0x81ff, 0x0de8, 0x080c, 0x3ec7, 0x2009, 0x0001, 0x00f6,
- 0x2079, 0x0300, 0x78b8, 0x00fe, 0xd0ec, 0x0110, 0x2009, 0x0011,
- 0x792a, 0x00f8, 0x8001, 0x7002, 0x9184, 0x0880, 0x1140, 0x782c,
- 0xd0fc, 0x1904, 0x3f5e, 0x2011, 0x0001, 0x00b1, 0x0090, 0xa010,
- 0x9092, 0x0004, 0x9086, 0x0015, 0x1120, 0xa000, 0xa05a, 0x2011,
- 0x0031, 0xa212, 0xd1dc, 0x1960, 0x0828, 0x782b, 0x0004, 0x7003,
- 0x0000, 0x00ee, 0x00fe, 0x0005, 0xa014, 0x9005, 0x0550, 0x8001,
- 0x0036, 0x0096, 0xa016, 0xa058, 0x2048, 0xa010, 0x2009, 0x0031,
- 0x911a, 0x831c, 0x831c, 0x938a, 0x0007, 0x1a0c, 0x0e02, 0x9398,
- 0x3fea, 0x231d, 0x083f, 0x9080, 0x0004, 0x7a2a, 0x7100, 0x8108,
- 0x7102, 0x009e, 0x003e, 0x908a, 0x0035, 0x1140, 0x0096, 0xa058,
- 0x2048, 0xa804, 0xa05a, 0x2001, 0x0019, 0x009e, 0xa012, 0x9085,
- 0x0001, 0x0005, 0x4027, 0x401e, 0x4015, 0x400c, 0x4003, 0x3ffa,
- 0x3ff1, 0xa964, 0x7902, 0xa968, 0x7906, 0xa96c, 0x7912, 0xa970,
- 0x7916, 0x0005, 0xa974, 0x7902, 0xa978, 0x7906, 0xa97c, 0x7912,
- 0xa980, 0x7916, 0x0005, 0xa984, 0x7902, 0xa988, 0x7906, 0xa98c,
- 0x7912, 0xa990, 0x7916, 0x0005, 0xa994, 0x7902, 0xa998, 0x7906,
- 0xa99c, 0x7912, 0xa9a0, 0x7916, 0x0005, 0xa9a4, 0x7902, 0xa9a8,
- 0x7906, 0xa9ac, 0x7912, 0xa9b0, 0x7916, 0x0005, 0xa9b4, 0x7902,
- 0xa9b8, 0x7906, 0xa9bc, 0x7912, 0xa9c0, 0x7916, 0x0005, 0xa9c4,
- 0x7902, 0xa9c8, 0x7906, 0xa9cc, 0x7912, 0xa9d0, 0x7916, 0x0005,
- 0x00f6, 0x00e6, 0x0086, 0x2071, 0x1a42, 0x2079, 0x0090, 0x792c,
- 0xd1fc, 0x01e8, 0x782b, 0x0002, 0x2940, 0x9026, 0x7000, 0x0002,
- 0x4057, 0x4043, 0x404e, 0x8001, 0x7002, 0xd19c, 0x1180, 0x2011,
- 0x0001, 0x080c, 0x3fbc, 0x190c, 0x3fbc, 0x0048, 0x8001, 0x7002,
- 0x782c, 0xd0fc, 0x1d38, 0x2011, 0x0001, 0x080c, 0x3fbc, 0x008e,
- 0x00ee, 0x00fe, 0x0005, 0x00f6, 0x00e6, 0x00c6, 0x0086, 0x2061,
- 0x0200, 0x2001, 0x1984, 0x2004, 0x601a, 0x2061, 0x0100, 0x2001,
- 0x1983, 0x2004, 0x60ce, 0x6104, 0xc1ac, 0x6106, 0x2001, 0x002c,
- 0x2004, 0x9005, 0x0520, 0x2038, 0x2001, 0x002e, 0x2024, 0x2001,
- 0x002f, 0x201c, 0x080c, 0x49b8, 0xa813, 0x0019, 0xaf16, 0x2900,
- 0xa85a, 0x978a, 0x0007, 0x0220, 0x2138, 0x2009, 0x0007, 0x0010,
- 0x2708, 0x903e, 0x0096, 0xa858, 0x2048, 0xa85c, 0x9080, 0x0019,
- 0x009e, 0x080c, 0x40d3, 0x1d68, 0x2900, 0xa85a, 0x00d0, 0x080c,
- 0x49b8, 0xa813, 0x0019, 0xa817, 0x0001, 0x2900, 0xa85a, 0x2001,
- 0x002e, 0x2004, 0xa866, 0x2001, 0x002f, 0x2004, 0xa86a, 0x2001,
- 0x002a, 0x2004, 0x9084, 0xfff8, 0xa86e, 0x2001, 0x002b, 0x2004,
- 0xa872, 0x2061, 0x0090, 0x2079, 0x0100, 0x2001, 0x1983, 0x2004,
- 0x6036, 0x2009, 0x0040, 0x080c, 0x2204, 0x2001, 0x002a, 0x2004,
- 0x9084, 0xfff8, 0x601a, 0x0006, 0x2001, 0x002b, 0x2004, 0x601e,
- 0x78c6, 0x000e, 0x78ca, 0x9006, 0x600a, 0x600e, 0x008e, 0x00ce,
- 0x00ee, 0x00fe, 0x0005, 0x00e6, 0x2071, 0x0080, 0xaa60, 0x22e8,
- 0x20a0, 0x20e1, 0x0000, 0x2099, 0x0088, 0x702b, 0x0026, 0x7402,
- 0x7306, 0x9006, 0x700a, 0x700e, 0x810b, 0x810b, 0x21a8, 0x810b,
- 0x7112, 0x702b, 0x0041, 0x702c, 0xd0fc, 0x0de8, 0x702b, 0x0002,
- 0x702b, 0x0040, 0x4005, 0x7400, 0x7304, 0x87ff, 0x0190, 0x0086,
- 0x0096, 0x2940, 0x0086, 0x080c, 0x49b8, 0x008e, 0xa058, 0x00a6,
- 0x2050, 0x2900, 0xb006, 0xa05a, 0x00ae, 0x009e, 0x008e, 0x9085,
- 0x0001, 0x00ee, 0x0005, 0x00e6, 0x2001, 0x002d, 0x2004, 0x9005,
- 0x0528, 0x2038, 0x2001, 0x0030, 0x2024, 0x2001, 0x0031, 0x201c,
- 0x080c, 0x49b8, 0x2940, 0xa813, 0x0019, 0xaf16, 0x2900, 0xa85a,
- 0x978a, 0x0007, 0x0220, 0x2138, 0x2009, 0x0007, 0x0010, 0x2708,
- 0x903e, 0x0096, 0xa858, 0x2048, 0xa85c, 0x9080, 0x0019, 0x009e,
- 0x080c, 0x40d3, 0x1d68, 0x2900, 0xa85a, 0x00d8, 0x080c, 0x49b8,
- 0x2940, 0xa013, 0x0019, 0xa017, 0x0001, 0x2800, 0xa05a, 0x2001,
- 0x0030, 0x2004, 0xa066, 0x2001, 0x0031, 0x2004, 0xa06a, 0x2001,
- 0x002a, 0x2004, 0x9084, 0xfff8, 0xa06e, 0x2001, 0x002b, 0x2004,
- 0xa072, 0x2001, 0x032a, 0x2003, 0x0004, 0x7884, 0xd0ac, 0x1180,
- 0x2001, 0x0101, 0x200c, 0x918d, 0x0200, 0x2102, 0xa017, 0x0000,
- 0x2001, 0x1a3f, 0x2003, 0x0003, 0x2001, 0x032a, 0x2003, 0x0009,
- 0x2001, 0x0300, 0x2003, 0x0000, 0x2001, 0x020d, 0x2003, 0x0000,
- 0x2001, 0x0004, 0x200c, 0x918d, 0x0002, 0x2102, 0x00ee, 0x0005,
- 0x0126, 0x2091, 0x8000, 0x20a9, 0x001b, 0x20a1, 0x1840, 0x20e9,
- 0x0001, 0x9006, 0x4004, 0x2009, 0x013c, 0x200a, 0x012e, 0x7880,
- 0x9086, 0x0052, 0x0108, 0x0005, 0x0804, 0x3408, 0x7d98, 0x7c9c,
- 0x0804, 0x350c, 0x080c, 0x717f, 0x190c, 0x5df5, 0x2069, 0x185b,
- 0x2d00, 0x2009, 0x0030, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0x2039,
- 0x0001, 0x080c, 0x4a01, 0x701f, 0x41a6, 0x0005, 0x080c, 0x54eb,
- 0x1130, 0x3b00, 0x3a08, 0xc194, 0xc095, 0x20d8, 0x21d0, 0x2069,
- 0x185b, 0x6800, 0x9005, 0x0904, 0x343d, 0x6804, 0xd094, 0x00c6,
- 0x2061, 0x0100, 0x6104, 0x0138, 0x6200, 0x9292, 0x0005, 0x0218,
- 0x918c, 0xffdf, 0x0010, 0x918d, 0x0020, 0x6106, 0x00ce, 0xd08c,
- 0x00c6, 0x2061, 0x0100, 0x6104, 0x0118, 0x918d, 0x0010, 0x0010,
- 0x918c, 0xffef, 0x6106, 0x00ce, 0xd084, 0x0158, 0x6a28, 0x928a,
- 0x007f, 0x1a04, 0x343d, 0x9288, 0x3209, 0x210d, 0x918c, 0x00ff,
- 0x6162, 0xd0dc, 0x0130, 0x6828, 0x908a, 0x007f, 0x1a04, 0x343d,
- 0x605a, 0x6888, 0x9084, 0x0030, 0x8004, 0x8004, 0x8004, 0x8004,
- 0x0006, 0x2009, 0x198c, 0x9080, 0x27aa, 0x2005, 0x200a, 0x000e,
- 0x2009, 0x198d, 0x9080, 0x27ae, 0x2005, 0x200a, 0x6808, 0x908a,
- 0x0100, 0x0a04, 0x343d, 0x908a, 0x0841, 0x1a04, 0x343d, 0x9084,
- 0x0007, 0x1904, 0x343d, 0x680c, 0x9005, 0x0904, 0x343d, 0x6810,
- 0x9005, 0x0904, 0x343d, 0x6848, 0x6940, 0x910a, 0x1a04, 0x343d,
- 0x8001, 0x0904, 0x343d, 0x684c, 0x6944, 0x910a, 0x1a04, 0x343d,
- 0x8001, 0x0904, 0x343d, 0x2009, 0x195b, 0x200b, 0x0000, 0x2001,
- 0x187d, 0x2004, 0xd0c4, 0x0140, 0x7884, 0x200a, 0x2008, 0x080c,
- 0x0e87, 0x3b00, 0xc085, 0x20d8, 0x6814, 0x908c, 0x00ff, 0x614a,
- 0x8007, 0x9084, 0x00ff, 0x604e, 0x080c, 0x74ac, 0x080c, 0x6797,
- 0x080c, 0x67fa, 0x6808, 0x602a, 0x080c, 0x2176, 0x2009, 0x0170,
- 0x200b, 0x0080, 0xa001, 0xa001, 0x200b, 0x0000, 0x0036, 0x6b08,
- 0x080c, 0x2711, 0x003e, 0x6000, 0x9086, 0x0000, 0x1904, 0x4327,
- 0x6818, 0x691c, 0x6a20, 0x6b24, 0x8007, 0x810f, 0x8217, 0x831f,
- 0x6016, 0x611a, 0x621e, 0x6322, 0x6c04, 0xd4f4, 0x0148, 0x6830,
- 0x6934, 0x6a38, 0x6b3c, 0x8007, 0x810f, 0x8217, 0x831f, 0x0010,
- 0x9084, 0xf0ff, 0x6006, 0x610a, 0x620e, 0x6312, 0x8007, 0x810f,
- 0x8217, 0x831f, 0x20a9, 0x0004, 0x20a1, 0x198e, 0x20e9, 0x0001,
- 0x4001, 0x20a9, 0x0004, 0x20a1, 0x19a8, 0x20e9, 0x0001, 0x4001,
- 0x080c, 0x8363, 0x00c6, 0x900e, 0x20a9, 0x0001, 0x6b70, 0xd384,
- 0x01c8, 0x0020, 0x839d, 0x12b0, 0x3508, 0x8109, 0x080c, 0x7a78,
- 0x6878, 0x6016, 0x6874, 0x2008, 0x9084, 0xff00, 0x8007, 0x600a,
- 0x9184, 0x00ff, 0x6006, 0x8108, 0x1118, 0x6003, 0x0003, 0x0010,
- 0x6003, 0x0001, 0x1f04, 0x4292, 0x00ce, 0x00c6, 0x2061, 0x1976,
- 0x2063, 0x0001, 0x9006, 0x080c, 0x29b8, 0x9006, 0x080c, 0x299b,
- 0x0000, 0x00ce, 0x00e6, 0x2c70, 0x080c, 0x0ed8, 0x00ee, 0x6888,
- 0xd0ec, 0x0198, 0x2001, 0x0100, 0x2004, 0x9086, 0x000a, 0x0138,
- 0x2011, 0x0114, 0x2204, 0x9085, 0x0100, 0x2012, 0x0030, 0x2011,
- 0x0114, 0x2204, 0x9085, 0x0180, 0x2012, 0x6a80, 0x9284, 0x0030,
- 0x9086, 0x0030, 0x1128, 0x9294, 0xffcf, 0x9295, 0x0020, 0x6a82,
- 0x2001, 0x1956, 0x6a80, 0x9294, 0x0030, 0x928e, 0x0000, 0x0170,
- 0x928e, 0x0010, 0x0118, 0x928e, 0x0020, 0x0140, 0x2003, 0xaaaa,
- 0x080c, 0x2786, 0x2001, 0x1947, 0x2102, 0x0008, 0x2102, 0x00c6,
- 0x2061, 0x0100, 0x602f, 0x0040, 0x602f, 0x0000, 0x00ce, 0x080c,
- 0x717f, 0x0128, 0x080c, 0x4dd2, 0x0110, 0x080c, 0x26d7, 0x60d0,
- 0x9005, 0x01c0, 0x6003, 0x0001, 0x2009, 0x430f, 0x00d0, 0x080c,
- 0x717f, 0x1168, 0x2011, 0x6fee, 0x080c, 0x825a, 0x2011, 0x6fe1,
- 0x080c, 0x832e, 0x080c, 0x7480, 0x080c, 0x709f, 0x0040, 0x080c,
- 0x5cef, 0x0028, 0x6003, 0x0004, 0x2009, 0x4327, 0x0010, 0x0804,
- 0x3408, 0x2001, 0x0170, 0x2004, 0x9084, 0x00ff, 0x9086, 0x004c,
- 0x1118, 0x2091, 0x30bd, 0x0817, 0x2091, 0x303d, 0x0817, 0x6000,
- 0x9086, 0x0000, 0x0904, 0x343a, 0x2069, 0x185b, 0x7890, 0x6842,
- 0x7894, 0x6846, 0x2d00, 0x2009, 0x0030, 0x7a8c, 0x7b88, 0x7c9c,
- 0x7d98, 0x2039, 0x0001, 0x0804, 0x4a04, 0x9006, 0x080c, 0x26d7,
- 0x81ff, 0x1904, 0x343a, 0x080c, 0x717f, 0x11b0, 0x080c, 0x747b,
- 0x080c, 0x5e30, 0x080c, 0x3204, 0x0118, 0x6130, 0xc18d, 0x6132,
- 0x080c, 0xc444, 0x0130, 0x080c, 0x71a2, 0x1118, 0x080c, 0x7157,
- 0x0038, 0x080c, 0x709f, 0x0020, 0x080c, 0x5df5, 0x080c, 0x5cef,
- 0x0804, 0x3408, 0x81ff, 0x1904, 0x343a, 0x080c, 0x717f, 0x1110,
- 0x0804, 0x343a, 0x0126, 0x2091, 0x8000, 0x6190, 0x81ff, 0x0190,
- 0x704f, 0x0000, 0x2001, 0x1c80, 0x2009, 0x0040, 0x7a8c, 0x7b88,
- 0x7c9c, 0x7d98, 0x2039, 0x0001, 0x080c, 0x4a04, 0x701f, 0x3406,
- 0x012e, 0x0005, 0x704f, 0x0001, 0x00d6, 0x2069, 0x1c80, 0x20a9,
- 0x0040, 0x20e9, 0x0001, 0x20a1, 0x1c80, 0x2019, 0xffff, 0x4304,
- 0x6558, 0x9588, 0x3209, 0x210d, 0x918c, 0x00ff, 0x216a, 0x900e,
- 0x2011, 0x0002, 0x2100, 0x9506, 0x01a8, 0x080c, 0x63a4, 0x1190,
- 0xb814, 0x821c, 0x0238, 0x9398, 0x1c80, 0x9085, 0xff00, 0x8007,
- 0x201a, 0x0038, 0x9398, 0x1c80, 0x2324, 0x94a4, 0xff00, 0x9405,
- 0x201a, 0x8210, 0x8108, 0x9182, 0x0080, 0x1208, 0x0c18, 0x8201,
- 0x8007, 0x2d0c, 0x9105, 0x206a, 0x00de, 0x20a9, 0x0040, 0x20a1,
- 0x1c80, 0x2099, 0x1c80, 0x080c, 0x5d80, 0x0804, 0x4382, 0x080c,
- 0x49eb, 0x0904, 0x343d, 0x080c, 0x49b8, 0x1120, 0x2009, 0x0002,
- 0x0804, 0x343a, 0x080c, 0x54dc, 0xd0b4, 0x0558, 0x7884, 0x908e,
- 0x007e, 0x0538, 0x908e, 0x007f, 0x0520, 0x908e, 0x0080, 0x0508,
- 0x080c, 0x31ff, 0x1148, 0xb800, 0xd08c, 0x11d8, 0xb804, 0x9084,
- 0x00ff, 0x9086, 0x0006, 0x11a8, 0xa867, 0x0000, 0xa868, 0xc0fd,
- 0xa86a, 0x080c, 0xbf06, 0x1120, 0x2009, 0x0003, 0x0804, 0x343a,
- 0x7007, 0x0003, 0x701f, 0x440d, 0x0005, 0x080c, 0x49eb, 0x0904,
- 0x343d, 0x20a9, 0x002b, 0xb8b4, 0x20e0, 0xb8b8, 0x2098, 0xa860,
- 0x20e8, 0xa85c, 0x9080, 0x0002, 0x20a0, 0x4003, 0x20a9, 0x0008,
- 0x9080, 0x0006, 0x20a0, 0xb8b4, 0x20e0, 0xb8b8, 0x9080, 0x0006,
- 0x2098, 0x080c, 0x0fc0, 0x0070, 0x20a9, 0x0004, 0xa85c, 0x9080,
- 0x000a, 0x20a0, 0xb8b4, 0x20e0, 0xb8b8, 0x9080, 0x000a, 0x2098,
- 0x080c, 0x0fc0, 0x8906, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084,
- 0xffc0, 0x9080, 0x0002, 0x2009, 0x002b, 0x7a8c, 0x7b88, 0x7c9c,
- 0x7d98, 0x0804, 0x4a04, 0x81ff, 0x1904, 0x343a, 0x080c, 0x49cf,
- 0x0904, 0x343d, 0x080c, 0x6516, 0x0904, 0x343a, 0x0058, 0xa878,
- 0x9005, 0x0120, 0x2009, 0x0004, 0x0804, 0x343a, 0xa974, 0xaa94,
- 0x0804, 0x3408, 0x080c, 0x54e4, 0x0904, 0x3408, 0x701f, 0x4457,
- 0x7007, 0x0003, 0x0005, 0x81ff, 0x1904, 0x343a, 0x7888, 0x908a,
- 0x1000, 0x1a04, 0x343d, 0x080c, 0x49eb, 0x0904, 0x343d, 0x080c,
- 0x66ca, 0x0120, 0x080c, 0x66d2, 0x1904, 0x343d, 0x080c, 0x659b,
- 0x0904, 0x343a, 0x2019, 0x0004, 0x900e, 0x080c, 0x6528, 0x0904,
- 0x343a, 0x7984, 0x7a88, 0x04c9, 0x08a8, 0xa89c, 0x908a, 0x1000,
- 0x12f8, 0x080c, 0x49e9, 0x01e0, 0x080c, 0x66ca, 0x0118, 0x080c,
- 0x66d2, 0x11b0, 0x080c, 0x659b, 0x2009, 0x0002, 0x0168, 0x2009,
- 0x0002, 0x2019, 0x0004, 0x080c, 0x6528, 0x2009, 0x0003, 0x0120,
- 0xa998, 0xaa9c, 0x00d1, 0x0060, 0xa897, 0x4005, 0xa99a, 0x0010,
- 0xa897, 0x4006, 0x900e, 0x9085, 0x0001, 0x2001, 0x0030, 0x0005,
- 0xa897, 0x4000, 0x080c, 0x54e4, 0x0110, 0x9006, 0x0018, 0x900e,
- 0x9085, 0x0001, 0x2001, 0x0000, 0x0005, 0x9186, 0x00ff, 0x0110,
- 0x0071, 0x0060, 0x2029, 0x007e, 0x2061, 0x1800, 0x6458, 0x2400,
- 0x9506, 0x0110, 0x2508, 0x0019, 0x8529, 0x1ec8, 0x0005, 0x080c,
- 0x63a4, 0x1138, 0x2200, 0x8003, 0x800b, 0x810b, 0x9108, 0x080c,
- 0x8268, 0x0005, 0x81ff, 0x1904, 0x343a, 0x798c, 0x2001, 0x195a,
- 0x918c, 0x8000, 0x2102, 0x080c, 0x49cf, 0x0904, 0x343d, 0x080c,
- 0x66ca, 0x0120, 0x080c, 0x66d2, 0x1904, 0x343d, 0x080c, 0x646b,
- 0x0904, 0x343a, 0x080c, 0x651f, 0x0904, 0x343a, 0x2001, 0x195a,
- 0x2004, 0xd0fc, 0x1904, 0x3408, 0x0804, 0x4462, 0xa9a0, 0x2001,
- 0x195a, 0x918c, 0x8000, 0xc18d, 0x2102, 0x080c, 0x49dc, 0x01a0,
- 0x080c, 0x66ca, 0x0118, 0x080c, 0x66d2, 0x1170, 0x080c, 0x646b,
- 0x2009, 0x0002, 0x0128, 0x080c, 0x651f, 0x1170, 0x2009, 0x0003,
- 0xa897, 0x4005, 0xa99a, 0x0010, 0xa897, 0x4006, 0x900e, 0x9085,
- 0x0001, 0x2001, 0x0030, 0x0005, 0xa897, 0x4000, 0x2001, 0x195a,
- 0x2004, 0xd0fc, 0x1128, 0x080c, 0x54e4, 0x0110, 0x9006, 0x0018,
- 0x900e, 0x9085, 0x0001, 0x2001, 0x0000, 0x0005, 0x81ff, 0x1904,
- 0x343a, 0x798c, 0x2001, 0x1959, 0x918c, 0x8000, 0x2102, 0x080c,
- 0x49cf, 0x0904, 0x343d, 0x080c, 0x66ca, 0x0120, 0x080c, 0x66d2,
- 0x1904, 0x343d, 0x080c, 0x646b, 0x0904, 0x343a, 0x080c, 0x650d,
- 0x0904, 0x343a, 0x2001, 0x1959, 0x2004, 0xd0fc, 0x1904, 0x3408,
- 0x0804, 0x4462, 0xa9a0, 0x2001, 0x1959, 0x918c, 0x8000, 0xc18d,
- 0x2102, 0x080c, 0x49dc, 0x01a0, 0x080c, 0x66ca, 0x0118, 0x080c,
- 0x66d2, 0x1170, 0x080c, 0x646b, 0x2009, 0x0002, 0x0128, 0x080c,
- 0x650d, 0x1170, 0x2009, 0x0003, 0xa897, 0x4005, 0xa99a, 0x0010,
- 0xa897, 0x4006, 0x900e, 0x9085, 0x0001, 0x2001, 0x0030, 0x0005,
- 0xa897, 0x4000, 0x2001, 0x1959, 0x2004, 0xd0fc, 0x1128, 0x080c,
- 0x54e4, 0x0110, 0x9006, 0x0018, 0x900e, 0x9085, 0x0001, 0x2001,
- 0x0000, 0x0005, 0x6100, 0x0804, 0x3408, 0x080c, 0x49eb, 0x0904,
- 0x343d, 0x080c, 0x54f0, 0x1904, 0x343a, 0x79a8, 0xd184, 0x1158,
- 0xb834, 0x8007, 0x789e, 0xb830, 0x8007, 0x789a, 0xbb2c, 0x831f,
- 0xba28, 0x8217, 0x0050, 0xb824, 0x8007, 0x789e, 0xb820, 0x8007,
- 0x789a, 0xbb1c, 0x831f, 0xba18, 0x8217, 0xb900, 0x918c, 0x0202,
- 0x0804, 0x3408, 0x78a8, 0x909c, 0x0003, 0xd0ac, 0x1150, 0xd0b4,
- 0x1140, 0x939a, 0x0003, 0x1a04, 0x343a, 0x6258, 0x7884, 0x9206,
- 0x1560, 0x2031, 0x1848, 0x2009, 0x013c, 0x2136, 0x2001, 0x1840,
- 0x2009, 0x000c, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0x2039, 0x0001,
- 0x0006, 0x78a8, 0x9084, 0x0080, 0x1118, 0x000e, 0x0804, 0x4a04,
- 0x000e, 0x2031, 0x0000, 0x2061, 0x18b6, 0x2c44, 0xa66a, 0xa17a,
- 0xa772, 0xa076, 0xa28e, 0xa392, 0xa496, 0xa59a, 0x080c, 0x1140,
- 0x7007, 0x0002, 0x701f, 0x461d, 0x0005, 0x81ff, 0x1904, 0x343a,
- 0x080c, 0x49eb, 0x0904, 0x343d, 0x080c, 0x66ca, 0x1904, 0x343a,
- 0x00c6, 0x080c, 0x49b8, 0x00ce, 0x0904, 0x343a, 0xa867, 0x0000,
- 0xa868, 0xc0fd, 0xa86a, 0x7ea8, 0x080c, 0xbeac, 0x0904, 0x343a,
- 0x7007, 0x0003, 0x701f, 0x4621, 0x0005, 0x080c, 0x4178, 0x0804,
- 0x3408, 0xa830, 0x9086, 0x0100, 0x0904, 0x343a, 0x8906, 0x8006,
- 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, 0x001b, 0x2009,
- 0x000c, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0x0804, 0x4a04, 0x9006,
- 0x080c, 0x26d7, 0x78a8, 0x9084, 0x00ff, 0x9086, 0x00ff, 0x0118,
- 0x81ff, 0x1904, 0x343a, 0x080c, 0x717f, 0x0110, 0x080c, 0x5df5,
- 0x7888, 0x908a, 0x1000, 0x1a04, 0x343d, 0x7984, 0x9186, 0x00ff,
- 0x0138, 0x9182, 0x007f, 0x1a04, 0x343d, 0x2100, 0x080c, 0x26a1,
- 0x0026, 0x00c6, 0x0126, 0x2091, 0x8000, 0x2061, 0x19d5, 0x601b,
- 0x0000, 0x601f, 0x0000, 0x607b, 0x0000, 0x607f, 0x0000, 0x080c,
- 0x717f, 0x1158, 0x080c, 0x747b, 0x080c, 0x5e30, 0x9085, 0x0001,
- 0x080c, 0x71c3, 0x080c, 0x709f, 0x00d0, 0x080c, 0x9f5b, 0x2061,
- 0x0100, 0x2001, 0x1817, 0x2004, 0x9084, 0x00ff, 0x810f, 0x9105,
- 0x604a, 0x6043, 0x0090, 0x6043, 0x0010, 0x2009, 0x1973, 0x200b,
- 0x0000, 0x2009, 0x002d, 0x2011, 0x5d1b, 0x080c, 0x82ec, 0x7984,
- 0x080c, 0x717f, 0x1110, 0x2009, 0x00ff, 0x7a88, 0x080c, 0x44c5,
- 0x012e, 0x00ce, 0x002e, 0x0804, 0x3408, 0x7984, 0x080c, 0x6344,
- 0x2b08, 0x1904, 0x343d, 0x0804, 0x3408, 0x81ff, 0x0120, 0x2009,
- 0x0001, 0x0804, 0x343a, 0x60d8, 0xd0ac, 0x1130, 0xd09c, 0x1120,
- 0x2009, 0x0005, 0x0804, 0x343a, 0x080c, 0x49b8, 0x1120, 0x2009,
- 0x0002, 0x0804, 0x343a, 0x7984, 0x81ff, 0x0904, 0x343d, 0x9192,
- 0x0021, 0x1a04, 0x343d, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0xa85c,
- 0x9080, 0x0019, 0x702a, 0xaf60, 0x7736, 0x080c, 0x4a01, 0x701f,
- 0x46d8, 0x7880, 0x9086, 0x006e, 0x0110, 0x701f, 0x4f84, 0x0005,
- 0x2009, 0x0080, 0x080c, 0x63a4, 0x1118, 0x080c, 0x66ca, 0x0120,
- 0x2021, 0x400a, 0x0804, 0x340a, 0x00d6, 0x0096, 0xa964, 0xaa6c,
- 0xab70, 0xac74, 0xad78, 0xae7c, 0xa884, 0x90be, 0x0100, 0x0904,
- 0x4771, 0x90be, 0x0112, 0x0904, 0x4771, 0x90be, 0x0113, 0x0904,
- 0x4771, 0x90be, 0x0114, 0x0904, 0x4771, 0x90be, 0x0117, 0x0904,
- 0x4771, 0x90be, 0x011a, 0x0904, 0x4771, 0x90be, 0x011c, 0x0904,
- 0x4771, 0x90be, 0x0121, 0x0904, 0x4758, 0x90be, 0x0131, 0x0904,
- 0x4758, 0x90be, 0x0171, 0x0904, 0x4771, 0x90be, 0x0173, 0x0904,
- 0x4771, 0x90be, 0x01a1, 0x1128, 0xa894, 0x8007, 0xa896, 0x0804,
- 0x477c, 0x90be, 0x0212, 0x0904, 0x4765, 0x90be, 0x0213, 0x05e8,
- 0x90be, 0x0214, 0x0500, 0x90be, 0x0217, 0x0188, 0x90be, 0x021a,
- 0x1120, 0xa89c, 0x8007, 0xa89e, 0x04e0, 0x90be, 0x021f, 0x05c8,
- 0x90be, 0x0300, 0x05b0, 0x009e, 0x00de, 0x0804, 0x343d, 0x7028,
- 0x9080, 0x0010, 0x2098, 0x20a0, 0x7034, 0x20e0, 0x20e8, 0x20a9,
- 0x0007, 0x080c, 0x47ba, 0x7028, 0x9080, 0x000e, 0x2098, 0x20a0,
- 0x7034, 0x20e0, 0x20e8, 0x20a9, 0x0001, 0x080c, 0x47ba, 0x00c8,
+ 0x20a9, 0x001b, 0x20a1, 0x1840, 0x20e9, 0x0001, 0x9006, 0x4004,
+ 0x2009, 0x013c, 0x200a, 0x012e, 0x7880, 0x9086, 0x0052, 0x0108,
+ 0x0005, 0x0804, 0x33f2, 0x7d98, 0x7c9c, 0x0804, 0x34f6, 0x080c,
+ 0x717e, 0x190c, 0x5df4, 0x2069, 0x185b, 0x2d00, 0x2009, 0x0030,
+ 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0x2039, 0x0001, 0x080c, 0x4a00,
+ 0x701f, 0x419b, 0x0005, 0x080c, 0x54ea, 0x1130, 0x3b00, 0x3a08,
+ 0xc194, 0xc095, 0x20d8, 0x21d0, 0x2069, 0x185b, 0x6800, 0x9005,
+ 0x0904, 0x3427, 0x6804, 0xd094, 0x00c6, 0x2061, 0x0100, 0x6104,
+ 0x0138, 0x6200, 0x9292, 0x0005, 0x0218, 0x918c, 0xffdf, 0x0010,
+ 0x918d, 0x0020, 0x6106, 0x00ce, 0xd08c, 0x00c6, 0x2061, 0x0100,
+ 0x6104, 0x0118, 0x918d, 0x0010, 0x0010, 0x918c, 0xffef, 0x6106,
+ 0x00ce, 0xd084, 0x0158, 0x6a28, 0x928a, 0x007f, 0x1a04, 0x3427,
+ 0x9288, 0x31f3, 0x210d, 0x918c, 0x00ff, 0x6162, 0xd0dc, 0x0130,
+ 0x6828, 0x908a, 0x007f, 0x1a04, 0x3427, 0x605a, 0x6888, 0x9084,
+ 0x0030, 0x8004, 0x8004, 0x8004, 0x8004, 0x0006, 0x2009, 0x198c,
+ 0x9080, 0x27a9, 0x2005, 0x200a, 0x000e, 0x2009, 0x198d, 0x9080,
+ 0x27ad, 0x2005, 0x200a, 0x6808, 0x908a, 0x0100, 0x0a04, 0x3427,
+ 0x908a, 0x0841, 0x1a04, 0x3427, 0x9084, 0x0007, 0x1904, 0x3427,
+ 0x680c, 0x9005, 0x0904, 0x3427, 0x6810, 0x9005, 0x0904, 0x3427,
+ 0x6848, 0x6940, 0x910a, 0x1a04, 0x3427, 0x8001, 0x0904, 0x3427,
+ 0x684c, 0x6944, 0x910a, 0x1a04, 0x3427, 0x8001, 0x0904, 0x3427,
+ 0x2009, 0x195b, 0x200b, 0x0000, 0x2001, 0x187d, 0x2004, 0xd0c4,
+ 0x0140, 0x7884, 0x200a, 0x2008, 0x080c, 0x0e7b, 0x3b00, 0xc085,
+ 0x20d8, 0x6814, 0x908c, 0x00ff, 0x614a, 0x8007, 0x9084, 0x00ff,
+ 0x604e, 0x080c, 0x74ab, 0x080c, 0x6796, 0x080c, 0x67f9, 0x6808,
+ 0x602a, 0x080c, 0x2172, 0x2009, 0x0170, 0x200b, 0x0080, 0xa001,
+ 0xa001, 0x200b, 0x0000, 0x0036, 0x6b08, 0x080c, 0x2710, 0x003e,
+ 0x6000, 0x9086, 0x0000, 0x1904, 0x4326, 0x6818, 0x691c, 0x6a20,
+ 0x6b24, 0x8007, 0x810f, 0x8217, 0x831f, 0x6016, 0x611a, 0x621e,
+ 0x6322, 0x6c04, 0xd4f4, 0x0148, 0x6830, 0x6934, 0x6a38, 0x6b3c,
+ 0x8007, 0x810f, 0x8217, 0x831f, 0x0010, 0x9084, 0xf0ff, 0x6006,
+ 0x610a, 0x620e, 0x6312, 0x8007, 0x810f, 0x8217, 0x831f, 0x20a9,
+ 0x0004, 0x20a1, 0x198e, 0x20e9, 0x0001, 0x4001, 0x20a9, 0x0004,
+ 0x20a1, 0x19a8, 0x20e9, 0x0001, 0x4001, 0x080c, 0x8362, 0x00c6,
+ 0x900e, 0x20a9, 0x0001, 0x6b70, 0xd384, 0x01c8, 0x0020, 0x839d,
+ 0x12b0, 0x3508, 0x8109, 0x080c, 0x7a77, 0x6878, 0x6016, 0x6874,
+ 0x2008, 0x9084, 0xff00, 0x8007, 0x600a, 0x9184, 0x00ff, 0x6006,
+ 0x8108, 0x1118, 0x6003, 0x0003, 0x0010, 0x6003, 0x0001, 0x1f04,
+ 0x4287, 0x00ce, 0x00c6, 0x2061, 0x1976, 0x2063, 0x0001, 0x9006,
+ 0x080c, 0x29a3, 0x9006, 0x080c, 0x2986, 0x0000, 0x00ce, 0x00e6,
+ 0x2c70, 0x080c, 0x0ecc, 0x00ee, 0x2001, 0x0100, 0x2004, 0x9086,
+ 0x000a, 0x1120, 0x080c, 0x2ba9, 0x080c, 0x2bdc, 0x6888, 0xd0ec,
+ 0x0198, 0x2001, 0x0100, 0x2004, 0x9086, 0x000a, 0x0138, 0x2011,
+ 0x0114, 0x2204, 0x9085, 0x0100, 0x2012, 0x0030, 0x2011, 0x0114,
+ 0x2204, 0x9085, 0x0180, 0x2012, 0x6a80, 0x9284, 0x0030, 0x9086,
+ 0x0030, 0x1128, 0x9294, 0xffcf, 0x9295, 0x0020, 0x6a82, 0x2001,
+ 0x1956, 0x6a80, 0x9294, 0x0030, 0x928e, 0x0000, 0x0170, 0x928e,
+ 0x0010, 0x0118, 0x928e, 0x0020, 0x0140, 0x2003, 0xaaaa, 0x080c,
+ 0x2785, 0x2001, 0x1947, 0x2102, 0x0008, 0x2102, 0x00c6, 0x2061,
+ 0x0100, 0x602f, 0x0040, 0x602f, 0x0000, 0x00ce, 0x080c, 0x717e,
+ 0x0128, 0x080c, 0x4dd1, 0x0110, 0x080c, 0x26d6, 0x60d0, 0x9005,
+ 0x01c0, 0x6003, 0x0001, 0x2009, 0x430e, 0x00d0, 0x080c, 0x717e,
+ 0x1168, 0x2011, 0x6fed, 0x080c, 0x8259, 0x2011, 0x6fe0, 0x080c,
+ 0x832d, 0x080c, 0x747f, 0x080c, 0x709e, 0x0040, 0x080c, 0x5cee,
+ 0x0028, 0x6003, 0x0004, 0x2009, 0x4326, 0x0010, 0x0804, 0x33f2,
+ 0x2001, 0x0170, 0x2004, 0x9084, 0x00ff, 0x9086, 0x004c, 0x1118,
+ 0x2091, 0x30bd, 0x0817, 0x2091, 0x303d, 0x0817, 0x6000, 0x9086,
+ 0x0000, 0x0904, 0x3424, 0x2069, 0x185b, 0x7890, 0x6842, 0x7894,
+ 0x6846, 0x2d00, 0x2009, 0x0030, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98,
+ 0x2039, 0x0001, 0x0804, 0x4a03, 0x9006, 0x080c, 0x26d6, 0x81ff,
+ 0x1904, 0x3424, 0x080c, 0x717e, 0x11b0, 0x080c, 0x747a, 0x080c,
+ 0x5e2f, 0x080c, 0x31ee, 0x0118, 0x6130, 0xc18d, 0x6132, 0x080c,
+ 0xc459, 0x0130, 0x080c, 0x71a1, 0x1118, 0x080c, 0x7156, 0x0038,
+ 0x080c, 0x709e, 0x0020, 0x080c, 0x5df4, 0x080c, 0x5cee, 0x0804,
+ 0x33f2, 0x81ff, 0x1904, 0x3424, 0x080c, 0x717e, 0x1110, 0x0804,
+ 0x3424, 0x0126, 0x2091, 0x8000, 0x6190, 0x81ff, 0x0190, 0x704f,
+ 0x0000, 0x2001, 0x1c80, 0x2009, 0x0040, 0x7a8c, 0x7b88, 0x7c9c,
+ 0x7d98, 0x2039, 0x0001, 0x080c, 0x4a03, 0x701f, 0x33f0, 0x012e,
+ 0x0005, 0x704f, 0x0001, 0x00d6, 0x2069, 0x1c80, 0x20a9, 0x0040,
+ 0x20e9, 0x0001, 0x20a1, 0x1c80, 0x2019, 0xffff, 0x4304, 0x6558,
+ 0x9588, 0x31f3, 0x210d, 0x918c, 0x00ff, 0x216a, 0x900e, 0x2011,
+ 0x0002, 0x2100, 0x9506, 0x01a8, 0x080c, 0x63a3, 0x1190, 0xb814,
+ 0x821c, 0x0238, 0x9398, 0x1c80, 0x9085, 0xff00, 0x8007, 0x201a,
+ 0x0038, 0x9398, 0x1c80, 0x2324, 0x94a4, 0xff00, 0x9405, 0x201a,
+ 0x8210, 0x8108, 0x9182, 0x0080, 0x1208, 0x0c18, 0x8201, 0x8007,
+ 0x2d0c, 0x9105, 0x206a, 0x00de, 0x20a9, 0x0040, 0x20a1, 0x1c80,
+ 0x2099, 0x1c80, 0x080c, 0x5d7f, 0x0804, 0x4381, 0x080c, 0x49ea,
+ 0x0904, 0x3427, 0x080c, 0x49b7, 0x1120, 0x2009, 0x0002, 0x0804,
+ 0x3424, 0x080c, 0x54db, 0xd0b4, 0x0558, 0x7884, 0x908e, 0x007e,
+ 0x0538, 0x908e, 0x007f, 0x0520, 0x908e, 0x0080, 0x0508, 0x080c,
+ 0x31e9, 0x1148, 0xb800, 0xd08c, 0x11d8, 0xb804, 0x9084, 0x00ff,
+ 0x9086, 0x0006, 0x11a8, 0xa867, 0x0000, 0xa868, 0xc0fd, 0xa86a,
+ 0x080c, 0xbf19, 0x1120, 0x2009, 0x0003, 0x0804, 0x3424, 0x7007,
+ 0x0003, 0x701f, 0x440c, 0x0005, 0x080c, 0x49ea, 0x0904, 0x3427,
+ 0x20a9, 0x002b, 0xb8b4, 0x20e0, 0xb8b8, 0x2098, 0xa860, 0x20e8,
+ 0xa85c, 0x9080, 0x0002, 0x20a0, 0x4003, 0x20a9, 0x0008, 0x9080,
+ 0x0006, 0x20a0, 0xb8b4, 0x20e0, 0xb8b8, 0x9080, 0x0006, 0x2098,
+ 0x080c, 0x0fb4, 0x0070, 0x20a9, 0x0004, 0xa85c, 0x9080, 0x000a,
+ 0x20a0, 0xb8b4, 0x20e0, 0xb8b8, 0x9080, 0x000a, 0x2098, 0x080c,
+ 0x0fb4, 0x8906, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0,
+ 0x9080, 0x0002, 0x2009, 0x002b, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98,
+ 0x0804, 0x4a03, 0x81ff, 0x1904, 0x3424, 0x080c, 0x49ce, 0x0904,
+ 0x3427, 0x080c, 0x6515, 0x0904, 0x3424, 0x0058, 0xa878, 0x9005,
+ 0x0120, 0x2009, 0x0004, 0x0804, 0x3424, 0xa974, 0xaa94, 0x0804,
+ 0x33f2, 0x080c, 0x54e3, 0x0904, 0x33f2, 0x701f, 0x4456, 0x7007,
+ 0x0003, 0x0005, 0x81ff, 0x1904, 0x3424, 0x7888, 0x908a, 0x1000,
+ 0x1a04, 0x3427, 0x080c, 0x49ea, 0x0904, 0x3427, 0x080c, 0x66c9,
+ 0x0120, 0x080c, 0x66d1, 0x1904, 0x3427, 0x080c, 0x659a, 0x0904,
+ 0x3424, 0x2019, 0x0004, 0x900e, 0x080c, 0x6527, 0x0904, 0x3424,
+ 0x7984, 0x7a88, 0x04c9, 0x08a8, 0xa89c, 0x908a, 0x1000, 0x12f8,
+ 0x080c, 0x49e8, 0x01e0, 0x080c, 0x66c9, 0x0118, 0x080c, 0x66d1,
+ 0x11b0, 0x080c, 0x659a, 0x2009, 0x0002, 0x0168, 0x2009, 0x0002,
+ 0x2019, 0x0004, 0x080c, 0x6527, 0x2009, 0x0003, 0x0120, 0xa998,
+ 0xaa9c, 0x00d1, 0x0060, 0xa897, 0x4005, 0xa99a, 0x0010, 0xa897,
+ 0x4006, 0x900e, 0x9085, 0x0001, 0x2001, 0x0030, 0x0005, 0xa897,
+ 0x4000, 0x080c, 0x54e3, 0x0110, 0x9006, 0x0018, 0x900e, 0x9085,
+ 0x0001, 0x2001, 0x0000, 0x0005, 0x9186, 0x00ff, 0x0110, 0x0071,
+ 0x0060, 0x2029, 0x007e, 0x2061, 0x1800, 0x6458, 0x2400, 0x9506,
+ 0x0110, 0x2508, 0x0019, 0x8529, 0x1ec8, 0x0005, 0x080c, 0x63a3,
+ 0x1138, 0x2200, 0x8003, 0x800b, 0x810b, 0x9108, 0x080c, 0x8267,
+ 0x0005, 0x81ff, 0x1904, 0x3424, 0x798c, 0x2001, 0x195a, 0x918c,
+ 0x8000, 0x2102, 0x080c, 0x49ce, 0x0904, 0x3427, 0x080c, 0x66c9,
+ 0x0120, 0x080c, 0x66d1, 0x1904, 0x3427, 0x080c, 0x646a, 0x0904,
+ 0x3424, 0x080c, 0x651e, 0x0904, 0x3424, 0x2001, 0x195a, 0x2004,
+ 0xd0fc, 0x1904, 0x33f2, 0x0804, 0x4461, 0xa9a0, 0x2001, 0x195a,
+ 0x918c, 0x8000, 0xc18d, 0x2102, 0x080c, 0x49db, 0x01a0, 0x080c,
+ 0x66c9, 0x0118, 0x080c, 0x66d1, 0x1170, 0x080c, 0x646a, 0x2009,
+ 0x0002, 0x0128, 0x080c, 0x651e, 0x1170, 0x2009, 0x0003, 0xa897,
+ 0x4005, 0xa99a, 0x0010, 0xa897, 0x4006, 0x900e, 0x9085, 0x0001,
+ 0x2001, 0x0030, 0x0005, 0xa897, 0x4000, 0x2001, 0x195a, 0x2004,
+ 0xd0fc, 0x1128, 0x080c, 0x54e3, 0x0110, 0x9006, 0x0018, 0x900e,
+ 0x9085, 0x0001, 0x2001, 0x0000, 0x0005, 0x81ff, 0x1904, 0x3424,
+ 0x798c, 0x2001, 0x1959, 0x918c, 0x8000, 0x2102, 0x080c, 0x49ce,
+ 0x0904, 0x3427, 0x080c, 0x66c9, 0x0120, 0x080c, 0x66d1, 0x1904,
+ 0x3427, 0x080c, 0x646a, 0x0904, 0x3424, 0x080c, 0x650c, 0x0904,
+ 0x3424, 0x2001, 0x1959, 0x2004, 0xd0fc, 0x1904, 0x33f2, 0x0804,
+ 0x4461, 0xa9a0, 0x2001, 0x1959, 0x918c, 0x8000, 0xc18d, 0x2102,
+ 0x080c, 0x49db, 0x01a0, 0x080c, 0x66c9, 0x0118, 0x080c, 0x66d1,
+ 0x1170, 0x080c, 0x646a, 0x2009, 0x0002, 0x0128, 0x080c, 0x650c,
+ 0x1170, 0x2009, 0x0003, 0xa897, 0x4005, 0xa99a, 0x0010, 0xa897,
+ 0x4006, 0x900e, 0x9085, 0x0001, 0x2001, 0x0030, 0x0005, 0xa897,
+ 0x4000, 0x2001, 0x1959, 0x2004, 0xd0fc, 0x1128, 0x080c, 0x54e3,
+ 0x0110, 0x9006, 0x0018, 0x900e, 0x9085, 0x0001, 0x2001, 0x0000,
+ 0x0005, 0x6100, 0x0804, 0x33f2, 0x080c, 0x49ea, 0x0904, 0x3427,
+ 0x080c, 0x54ef, 0x1904, 0x3424, 0x79a8, 0xd184, 0x1158, 0xb834,
+ 0x8007, 0x789e, 0xb830, 0x8007, 0x789a, 0xbb2c, 0x831f, 0xba28,
+ 0x8217, 0x0050, 0xb824, 0x8007, 0x789e, 0xb820, 0x8007, 0x789a,
+ 0xbb1c, 0x831f, 0xba18, 0x8217, 0xb900, 0x918c, 0x0202, 0x0804,
+ 0x33f2, 0x78a8, 0x909c, 0x0003, 0xd0ac, 0x1150, 0xd0b4, 0x1140,
+ 0x939a, 0x0003, 0x1a04, 0x3424, 0x6258, 0x7884, 0x9206, 0x1560,
+ 0x2031, 0x1848, 0x2009, 0x013c, 0x2136, 0x2001, 0x1840, 0x2009,
+ 0x000c, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0x2039, 0x0001, 0x0006,
+ 0x78a8, 0x9084, 0x0080, 0x1118, 0x000e, 0x0804, 0x4a03, 0x000e,
+ 0x2031, 0x0000, 0x2061, 0x18b6, 0x2c44, 0xa66a, 0xa17a, 0xa772,
+ 0xa076, 0xa28e, 0xa392, 0xa496, 0xa59a, 0x080c, 0x1134, 0x7007,
+ 0x0002, 0x701f, 0x461c, 0x0005, 0x81ff, 0x1904, 0x3424, 0x080c,
+ 0x49ea, 0x0904, 0x3427, 0x080c, 0x66c9, 0x1904, 0x3424, 0x00c6,
+ 0x080c, 0x49b7, 0x00ce, 0x0904, 0x3424, 0xa867, 0x0000, 0xa868,
+ 0xc0fd, 0xa86a, 0x7ea8, 0x080c, 0xbebf, 0x0904, 0x3424, 0x7007,
+ 0x0003, 0x701f, 0x4620, 0x0005, 0x080c, 0x416d, 0x0804, 0x33f2,
+ 0xa830, 0x9086, 0x0100, 0x0904, 0x3424, 0x8906, 0x8006, 0x8007,
+ 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, 0x001b, 0x2009, 0x000c,
+ 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0x0804, 0x4a03, 0x9006, 0x080c,
+ 0x26d6, 0x78a8, 0x9084, 0x00ff, 0x9086, 0x00ff, 0x0118, 0x81ff,
+ 0x1904, 0x3424, 0x080c, 0x717e, 0x0110, 0x080c, 0x5df4, 0x7888,
+ 0x908a, 0x1000, 0x1a04, 0x3427, 0x7984, 0x9186, 0x00ff, 0x0138,
+ 0x9182, 0x007f, 0x1a04, 0x3427, 0x2100, 0x080c, 0x26a0, 0x0026,
+ 0x00c6, 0x0126, 0x2091, 0x8000, 0x2061, 0x19d5, 0x601b, 0x0000,
+ 0x601f, 0x0000, 0x607b, 0x0000, 0x607f, 0x0000, 0x080c, 0x717e,
+ 0x1158, 0x080c, 0x747a, 0x080c, 0x5e2f, 0x9085, 0x0001, 0x080c,
+ 0x71c2, 0x080c, 0x709e, 0x00d0, 0x080c, 0x9f70, 0x2061, 0x0100,
+ 0x2001, 0x1817, 0x2004, 0x9084, 0x00ff, 0x810f, 0x9105, 0x604a,
+ 0x6043, 0x0090, 0x6043, 0x0010, 0x2009, 0x1973, 0x200b, 0x0000,
+ 0x2009, 0x002d, 0x2011, 0x5d1a, 0x080c, 0x82eb, 0x7984, 0x080c,
+ 0x717e, 0x1110, 0x2009, 0x00ff, 0x7a88, 0x080c, 0x44c4, 0x012e,
+ 0x00ce, 0x002e, 0x0804, 0x33f2, 0x7984, 0x080c, 0x6343, 0x2b08,
+ 0x1904, 0x3427, 0x0804, 0x33f2, 0x81ff, 0x0120, 0x2009, 0x0001,
+ 0x0804, 0x3424, 0x60d8, 0xd0ac, 0x1130, 0xd09c, 0x1120, 0x2009,
+ 0x0005, 0x0804, 0x3424, 0x080c, 0x49b7, 0x1120, 0x2009, 0x0002,
+ 0x0804, 0x3424, 0x7984, 0x81ff, 0x0904, 0x3427, 0x9192, 0x0021,
+ 0x1a04, 0x3427, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0xa85c, 0x9080,
+ 0x0019, 0x702a, 0xaf60, 0x7736, 0x080c, 0x4a00, 0x701f, 0x46d7,
+ 0x7880, 0x9086, 0x006e, 0x0110, 0x701f, 0x4f83, 0x0005, 0x2009,
+ 0x0080, 0x080c, 0x63a3, 0x1118, 0x080c, 0x66c9, 0x0120, 0x2021,
+ 0x400a, 0x0804, 0x33f4, 0x00d6, 0x0096, 0xa964, 0xaa6c, 0xab70,
+ 0xac74, 0xad78, 0xae7c, 0xa884, 0x90be, 0x0100, 0x0904, 0x4770,
+ 0x90be, 0x0112, 0x0904, 0x4770, 0x90be, 0x0113, 0x0904, 0x4770,
+ 0x90be, 0x0114, 0x0904, 0x4770, 0x90be, 0x0117, 0x0904, 0x4770,
+ 0x90be, 0x011a, 0x0904, 0x4770, 0x90be, 0x011c, 0x0904, 0x4770,
+ 0x90be, 0x0121, 0x0904, 0x4757, 0x90be, 0x0131, 0x0904, 0x4757,
+ 0x90be, 0x0171, 0x0904, 0x4770, 0x90be, 0x0173, 0x0904, 0x4770,
+ 0x90be, 0x01a1, 0x1128, 0xa894, 0x8007, 0xa896, 0x0804, 0x477b,
+ 0x90be, 0x0212, 0x0904, 0x4764, 0x90be, 0x0213, 0x05e8, 0x90be,
+ 0x0214, 0x0500, 0x90be, 0x0217, 0x0188, 0x90be, 0x021a, 0x1120,
+ 0xa89c, 0x8007, 0xa89e, 0x04e0, 0x90be, 0x021f, 0x05c8, 0x90be,
+ 0x0300, 0x05b0, 0x009e, 0x00de, 0x0804, 0x3427, 0x7028, 0x9080,
+ 0x0010, 0x2098, 0x20a0, 0x7034, 0x20e0, 0x20e8, 0x20a9, 0x0007,
+ 0x080c, 0x47b9, 0x7028, 0x9080, 0x000e, 0x2098, 0x20a0, 0x7034,
+ 0x20e0, 0x20e8, 0x20a9, 0x0001, 0x080c, 0x47b9, 0x00c8, 0x7028,
+ 0x9080, 0x000c, 0x2098, 0x20a0, 0x7034, 0x20e0, 0x20e8, 0x20a9,
+ 0x0001, 0x080c, 0x47c6, 0x00b8, 0x7028, 0x9080, 0x000e, 0x2098,
+ 0x20a0, 0x7034, 0x20e0, 0x20e8, 0x20a9, 0x0001, 0x080c, 0x47c6,
0x7028, 0x9080, 0x000c, 0x2098, 0x20a0, 0x7034, 0x20e0, 0x20e8,
- 0x20a9, 0x0001, 0x080c, 0x47c7, 0x00b8, 0x7028, 0x9080, 0x000e,
- 0x2098, 0x20a0, 0x7034, 0x20e0, 0x20e8, 0x20a9, 0x0001, 0x080c,
- 0x47c7, 0x7028, 0x9080, 0x000c, 0x2098, 0x20a0, 0x7034, 0x20e0,
- 0x20e8, 0x20a9, 0x0001, 0x04f1, 0x00c6, 0x080c, 0x49b8, 0x0550,
- 0xa868, 0xc0fd, 0xa86a, 0xa867, 0x0119, 0x9006, 0xa882, 0xa87f,
- 0x0020, 0xa88b, 0x0001, 0x810b, 0xa9ae, 0xa8b2, 0xaab6, 0xabba,
- 0xacbe, 0xadc2, 0xa9c6, 0xa8ca, 0x00ce, 0x009e, 0x00de, 0xa866,
- 0xa822, 0xa868, 0xc0fd, 0xa86a, 0xa804, 0x2048, 0x080c, 0xbec7,
- 0x1120, 0x2009, 0x0003, 0x0804, 0x343a, 0x7007, 0x0003, 0x701f,
- 0x47b1, 0x0005, 0x00ce, 0x009e, 0x00de, 0x2009, 0x0002, 0x0804,
- 0x343a, 0xa820, 0x9086, 0x8001, 0x1904, 0x3408, 0x2009, 0x0004,
- 0x0804, 0x343a, 0x0016, 0x0026, 0x3510, 0x20a9, 0x0002, 0x4002,
- 0x4104, 0x4004, 0x8211, 0x1dc8, 0x002e, 0x001e, 0x0005, 0x0016,
- 0x0026, 0x0036, 0x0046, 0x3520, 0x20a9, 0x0004, 0x4002, 0x4304,
- 0x4204, 0x4104, 0x4004, 0x8421, 0x1db8, 0x004e, 0x003e, 0x002e,
- 0x001e, 0x0005, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x343a,
- 0x60d8, 0xd0ac, 0x1160, 0xd09c, 0x0120, 0x2009, 0x0016, 0x0804,
- 0x343a, 0xd09c, 0x1120, 0x2009, 0x0005, 0x0804, 0x343a, 0x7984,
- 0x78a8, 0x2040, 0x080c, 0x9f54, 0x1120, 0x9182, 0x007f, 0x0a04,
- 0x343d, 0x9186, 0x00ff, 0x0904, 0x343d, 0x9182, 0x0800, 0x1a04,
- 0x343d, 0x7a8c, 0x7b88, 0x6078, 0x9306, 0x1158, 0x607c, 0x924e,
- 0x0904, 0x343d, 0x080c, 0x9f54, 0x1120, 0x99cc, 0xff00, 0x0904,
- 0x343d, 0x0126, 0x2091, 0x8000, 0x9386, 0x00ff, 0x0178, 0x0026,
- 0x2011, 0x8008, 0x080c, 0x66ee, 0x002e, 0x0140, 0x918d, 0x8000,
- 0x080c, 0x6738, 0x1118, 0x2001, 0x4009, 0x0458, 0x080c, 0x48d2,
- 0x0560, 0x90c6, 0x4000, 0x1170, 0x00c6, 0x0006, 0x900e, 0x080c,
- 0x65c4, 0x1108, 0xc185, 0xb800, 0xd0bc, 0x0108, 0xc18d, 0x000e,
- 0x00ce, 0x00b8, 0x90c6, 0x4007, 0x1110, 0x2408, 0x0090, 0x90c6,
- 0x4008, 0x1118, 0x2708, 0x2610, 0x0060, 0x90c6, 0x4009, 0x1108,
- 0x0040, 0x90c6, 0x4006, 0x1108, 0x0020, 0x2001, 0x4005, 0x2009,
- 0x000a, 0x2020, 0x012e, 0x0804, 0x340a, 0x2b00, 0x7026, 0x0016,
- 0x00b6, 0x00c6, 0x00e6, 0x2c70, 0x080c, 0xa026, 0x0904, 0x489f,
- 0x2b00, 0x6012, 0x080c, 0xc1b7, 0x2e58, 0x00ee, 0x00e6, 0x00c6,
- 0x080c, 0x49b8, 0x00ce, 0x2b70, 0x1158, 0x080c, 0x9fd5, 0x00ee,
- 0x00ce, 0x00be, 0x001e, 0x012e, 0x2009, 0x0002, 0x0804, 0x343a,
- 0x900e, 0xa966, 0xa96a, 0x2900, 0x6016, 0xa932, 0xa868, 0xc0fd,
- 0xd88c, 0x0108, 0xc0f5, 0xa86a, 0x080c, 0x30ab, 0x6023, 0x0001,
- 0x9006, 0x080c, 0x62e1, 0x2001, 0x0002, 0x080c, 0x62f5, 0x2009,
- 0x0002, 0x080c, 0xa053, 0x78a8, 0xd094, 0x0138, 0x00ee, 0x7024,
- 0x00e6, 0x2058, 0xb8bc, 0xc08d, 0xb8be, 0x9085, 0x0001, 0x00ee,
- 0x00ce, 0x00be, 0x001e, 0x012e, 0x1120, 0x2009, 0x0003, 0x0804,
- 0x343a, 0x7007, 0x0003, 0x701f, 0x48ae, 0x0005, 0xa830, 0x2008,
- 0x918e, 0xdead, 0x1120, 0x2021, 0x4009, 0x0804, 0x340a, 0x9086,
- 0x0100, 0x7024, 0x2058, 0x1138, 0x2009, 0x0004, 0xba04, 0x9294,
- 0x00ff, 0x0804, 0x5430, 0x900e, 0xa868, 0xd0f4, 0x1904, 0x3408,
- 0x080c, 0x65c4, 0x1108, 0xc185, 0xb800, 0xd0bc, 0x0108, 0xc18d,
- 0x0804, 0x3408, 0x00e6, 0x00d6, 0x0096, 0x83ff, 0x0904, 0x491a,
- 0x902e, 0x080c, 0x9f54, 0x0130, 0x9026, 0x20a9, 0x0800, 0x2071,
- 0x1000, 0x0030, 0x2021, 0x007f, 0x20a9, 0x0781, 0x2071, 0x107f,
- 0x2e04, 0x9005, 0x11b0, 0x2100, 0x9406, 0x15e8, 0x2428, 0x94ce,
- 0x007f, 0x1120, 0x92ce, 0xfffd, 0x1528, 0x0030, 0x94ce, 0x0080,
- 0x1130, 0x92ce, 0xfffc, 0x11f0, 0x93ce, 0x00ff, 0x11d8, 0xc5fd,
- 0x0450, 0x2058, 0xbf10, 0x2700, 0x9306, 0x11b8, 0xbe14, 0x2600,
- 0x9206, 0x1198, 0x2400, 0x9106, 0x1150, 0xd884, 0x0568, 0xd894,
- 0x1558, 0x080c, 0x66ca, 0x1540, 0x2001, 0x4000, 0x0430, 0x2001,
- 0x4007, 0x0418, 0x2001, 0x4006, 0x0400, 0x2400, 0x9106, 0x1158,
- 0xbe14, 0x87ff, 0x1128, 0x86ff, 0x0948, 0x080c, 0x9f54, 0x1930,
- 0x2001, 0x4008, 0x0090, 0x8420, 0x8e70, 0x1f04, 0x48e8, 0x85ff,
- 0x1130, 0x2001, 0x4009, 0x0048, 0x2001, 0x0001, 0x0030, 0x080c,
- 0x6344, 0x1dd0, 0xbb12, 0xba16, 0x9006, 0x9005, 0x009e, 0x00de,
- 0x00ee, 0x0005, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x343a,
- 0x080c, 0x49b8, 0x1120, 0x2009, 0x0002, 0x0804, 0x343a, 0xa867,
- 0x0000, 0xa868, 0xc0fd, 0xa86a, 0x7884, 0x9005, 0x0904, 0x343d,
- 0x9096, 0x00ff, 0x0120, 0x9092, 0x0004, 0x1a04, 0x343d, 0x2010,
- 0x2918, 0x080c, 0x3051, 0x1120, 0x2009, 0x0003, 0x0804, 0x343a,
- 0x7007, 0x0003, 0x701f, 0x496d, 0x0005, 0xa830, 0x9086, 0x0100,
- 0x1904, 0x3408, 0x2009, 0x0004, 0x0804, 0x343a, 0x7984, 0x080c,
- 0x9f54, 0x1120, 0x9182, 0x007f, 0x0a04, 0x343d, 0x9186, 0x00ff,
- 0x0904, 0x343d, 0x9182, 0x0800, 0x1a04, 0x343d, 0x2001, 0x9400,
- 0x080c, 0x548b, 0x1904, 0x343a, 0x0804, 0x3408, 0xa998, 0x080c,
- 0x9f54, 0x1118, 0x9182, 0x007f, 0x0280, 0x9186, 0x00ff, 0x0168,
- 0x9182, 0x0800, 0x1250, 0x2001, 0x9400, 0x080c, 0x548b, 0x11a8,
- 0x0060, 0xa897, 0x4005, 0xa99a, 0x0010, 0xa897, 0x4006, 0x900e,
- 0x9085, 0x0001, 0x2001, 0x0030, 0x0005, 0xa897, 0x4000, 0x900e,
- 0x9085, 0x0001, 0x2001, 0x0000, 0x0005, 0x2009, 0x000a, 0x0c48,
- 0x080c, 0x1043, 0x0198, 0x9006, 0xa802, 0x7014, 0x9005, 0x1120,
- 0x2900, 0x7016, 0x701a, 0x0040, 0x7018, 0xa802, 0x0086, 0x2040,
- 0x2900, 0xa006, 0x701a, 0x008e, 0x9085, 0x0001, 0x0005, 0x7984,
- 0x080c, 0x63a4, 0x1130, 0x7e88, 0x9684, 0x3fff, 0x9082, 0x4000,
- 0x0208, 0x905e, 0x8bff, 0x0005, 0xa998, 0x080c, 0x63a4, 0x1130,
- 0xae9c, 0x9684, 0x3fff, 0x9082, 0x4000, 0x0208, 0x905e, 0x8bff,
- 0x0005, 0xae98, 0x0008, 0x7e84, 0x2608, 0x080c, 0x63a4, 0x1108,
- 0x0008, 0x905e, 0x8bff, 0x0005, 0x0016, 0x7114, 0x81ff, 0x0128,
- 0x2148, 0xa904, 0x080c, 0x1075, 0x0cc8, 0x7116, 0x711a, 0x001e,
- 0x0005, 0x2031, 0x0001, 0x0010, 0x2031, 0x0000, 0x2061, 0x18b6,
- 0x2c44, 0xa66a, 0xa17a, 0xa772, 0xa076, 0xa28e, 0xa392, 0xa496,
- 0xa59a, 0x080c, 0x1140, 0x7007, 0x0002, 0x701f, 0x3408, 0x0005,
- 0x00f6, 0x0126, 0x2091, 0x8000, 0x2079, 0x0000, 0x2001, 0x18ae,
- 0x2004, 0x9005, 0x1190, 0x0e04, 0x4a35, 0x7a36, 0x7833, 0x0012,
- 0x7a82, 0x7b86, 0x7c8a, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004,
- 0xd084, 0x190c, 0x11f2, 0x0804, 0x4a9b, 0x0016, 0x0086, 0x0096,
- 0x00c6, 0x00e6, 0x2071, 0x189c, 0x7044, 0x9005, 0x1540, 0x7148,
- 0x9182, 0x0010, 0x0288, 0x7038, 0x2060, 0x080c, 0x1043, 0x0904,
- 0x4a93, 0xa84b, 0x0000, 0x2900, 0x7046, 0x2001, 0x0002, 0x9080,
- 0x1ec2, 0x2005, 0xa846, 0x0098, 0x7038, 0x90e0, 0x0004, 0x2001,
- 0x18b8, 0x9c82, 0x18f8, 0x0210, 0x2061, 0x18b8, 0x2c00, 0x703a,
- 0x7148, 0x81ff, 0x1108, 0x703e, 0x8108, 0x714a, 0x0460, 0x7148,
- 0x8108, 0x714a, 0x7044, 0x2040, 0xa144, 0x2105, 0x0016, 0x908a,
- 0x0036, 0x1a0c, 0x0e02, 0x2060, 0x001e, 0x8108, 0x2105, 0x9005,
- 0xa146, 0x1520, 0x080c, 0x1043, 0x1130, 0x8109, 0xa946, 0x7148,
- 0x8109, 0x714a, 0x00d8, 0x9006, 0xa806, 0xa84a, 0xa046, 0x2800,
- 0xa802, 0x2900, 0xa006, 0x7046, 0x2001, 0x0002, 0x9080, 0x1ec2,
- 0x2005, 0xa846, 0x0058, 0x2262, 0x6306, 0x640a, 0x00ee, 0x00ce,
- 0x009e, 0x008e, 0x001e, 0x012e, 0x00fe, 0x0005, 0x2c00, 0x9082,
- 0x001b, 0x0002, 0x4abd, 0x4abd, 0x4abf, 0x4abd, 0x4abd, 0x4abd,
- 0x4ac3, 0x4abd, 0x4abd, 0x4abd, 0x4ac7, 0x4abd, 0x4abd, 0x4abd,
- 0x4acb, 0x4abd, 0x4abd, 0x4abd, 0x4acf, 0x4abd, 0x4abd, 0x4abd,
- 0x4ad3, 0x4abd, 0x4abd, 0x4abd, 0x4ad8, 0x080c, 0x0e02, 0xa276,
- 0xa37a, 0xa47e, 0x0898, 0xa286, 0xa38a, 0xa48e, 0x0878, 0xa296,
- 0xa39a, 0xa49e, 0x0858, 0xa2a6, 0xa3aa, 0xa4ae, 0x0838, 0xa2b6,
- 0xa3ba, 0xa4be, 0x0818, 0xa2c6, 0xa3ca, 0xa4ce, 0x0804, 0x4a96,
- 0xa2d6, 0xa3da, 0xa4de, 0x0804, 0x4a96, 0x00e6, 0x2071, 0x189c,
- 0x7048, 0x9005, 0x0904, 0x4b6f, 0x0126, 0x2091, 0x8000, 0x0e04,
- 0x4b6e, 0x00f6, 0x2079, 0x0000, 0x00c6, 0x0096, 0x0086, 0x0076,
- 0x9006, 0x2038, 0x7040, 0x2048, 0x9005, 0x0500, 0xa948, 0x2105,
- 0x0016, 0x908a, 0x0036, 0x1a0c, 0x0e02, 0x2060, 0x001e, 0x8108,
- 0x2105, 0x9005, 0xa94a, 0x1904, 0x4b71, 0xa804, 0x9005, 0x090c,
- 0x0e02, 0x7042, 0x2938, 0x2040, 0xa003, 0x0000, 0x2001, 0x0002,
- 0x9080, 0x1ec2, 0x2005, 0xa04a, 0x0804, 0x4b71, 0x703c, 0x2060,
- 0x2c14, 0x6304, 0x6408, 0x650c, 0x2200, 0x7836, 0x7833, 0x0012,
- 0x7882, 0x2300, 0x7886, 0x2400, 0x788a, 0x2091, 0x4080, 0x2001,
- 0x0089, 0x2004, 0xd084, 0x190c, 0x11f2, 0x87ff, 0x0118, 0x2748,
- 0x080c, 0x1075, 0x7048, 0x8001, 0x704a, 0x9005, 0x1170, 0x7040,
- 0x2048, 0x9005, 0x0128, 0x080c, 0x1075, 0x9006, 0x7042, 0x7046,
- 0x703b, 0x18b8, 0x703f, 0x18b8, 0x0420, 0x7040, 0x9005, 0x1508,
- 0x7238, 0x2c00, 0x9206, 0x0148, 0x9c80, 0x0004, 0x90fa, 0x18f8,
- 0x0210, 0x2001, 0x18b8, 0x703e, 0x00a0, 0x9006, 0x703e, 0x703a,
- 0x7044, 0x9005, 0x090c, 0x0e02, 0x2048, 0xa800, 0x9005, 0x1de0,
- 0x2900, 0x7042, 0x2001, 0x0002, 0x9080, 0x1ec2, 0x2005, 0xa84a,
- 0x0000, 0x007e, 0x008e, 0x009e, 0x00ce, 0x00fe, 0x012e, 0x00ee,
- 0x0005, 0x2c00, 0x9082, 0x001b, 0x0002, 0x4b90, 0x4b90, 0x4b92,
- 0x4b90, 0x4b90, 0x4b90, 0x4b97, 0x4b90, 0x4b90, 0x4b90, 0x4b9c,
- 0x4b90, 0x4b90, 0x4b90, 0x4ba1, 0x4b90, 0x4b90, 0x4b90, 0x4ba6,
- 0x4b90, 0x4b90, 0x4b90, 0x4bab, 0x4b90, 0x4b90, 0x4b90, 0x4bb0,
- 0x080c, 0x0e02, 0xaa74, 0xab78, 0xac7c, 0x0804, 0x4b1c, 0xaa84,
- 0xab88, 0xac8c, 0x0804, 0x4b1c, 0xaa94, 0xab98, 0xac9c, 0x0804,
- 0x4b1c, 0xaaa4, 0xaba8, 0xacac, 0x0804, 0x4b1c, 0xaab4, 0xabb8,
- 0xacbc, 0x0804, 0x4b1c, 0xaac4, 0xabc8, 0xaccc, 0x0804, 0x4b1c,
- 0xaad4, 0xabd8, 0xacdc, 0x0804, 0x4b1c, 0x0026, 0x080c, 0x54dc,
- 0xd0c4, 0x0120, 0x2011, 0x8014, 0x080c, 0x4a18, 0x002e, 0x0005,
- 0x81ff, 0x1904, 0x343a, 0x0126, 0x2091, 0x8000, 0x6030, 0xc08d,
- 0xc085, 0xc0ac, 0x6032, 0x080c, 0x717f, 0x1158, 0x080c, 0x747b,
- 0x080c, 0x5e30, 0x9085, 0x0001, 0x080c, 0x71c3, 0x080c, 0x709f,
- 0x0010, 0x080c, 0x5cef, 0x012e, 0x0804, 0x3408, 0x81ff, 0x0120,
- 0x2009, 0x0001, 0x0804, 0x343a, 0x080c, 0x54f0, 0x0120, 0x2009,
- 0x0007, 0x0804, 0x343a, 0x080c, 0x66c2, 0x0120, 0x2009, 0x0008,
- 0x0804, 0x343a, 0x0026, 0x2011, 0x0010, 0x080c, 0x66ee, 0x002e,
- 0x0140, 0x7984, 0x080c, 0x6738, 0x1120, 0x2009, 0x4009, 0x0804,
- 0x343a, 0x7984, 0x080c, 0x6344, 0x1904, 0x343d, 0x080c, 0x49eb,
- 0x0904, 0x343d, 0x2b00, 0x7026, 0x080c, 0x66ca, 0x7888, 0x1170,
- 0x9084, 0x0005, 0x1158, 0x900e, 0x080c, 0x65c4, 0x1108, 0xc185,
- 0xb800, 0xd0bc, 0x0108, 0xc18d, 0x0804, 0x3408, 0x080c, 0x49b8,
- 0x0904, 0x343a, 0x9006, 0xa866, 0xa832, 0xa868, 0xc0fd, 0xa86a,
- 0x080c, 0xbf65, 0x0904, 0x343a, 0x7888, 0xd094, 0x0118, 0xb8bc,
- 0xc08d, 0xb8be, 0x7007, 0x0003, 0x701f, 0x4c80, 0x0005, 0x2061,
- 0x1800, 0x080c, 0x54f0, 0x2009, 0x0007, 0x1560, 0x080c, 0x66c2,
- 0x0118, 0x2009, 0x0008, 0x0430, 0xa998, 0x080c, 0x6344, 0x1530,
- 0x080c, 0x49e9, 0x0518, 0x080c, 0x66ca, 0xa89c, 0x1168, 0x9084,
- 0x0005, 0x1150, 0x900e, 0x080c, 0x65c4, 0x1108, 0xc185, 0xb800,
- 0xd0bc, 0x0108, 0xc18d, 0x00d0, 0xa868, 0xc0fc, 0xa86a, 0x080c,
- 0xbf65, 0x11e0, 0xa89c, 0xd094, 0x0118, 0xb8bc, 0xc08d, 0xb8be,
- 0x2009, 0x0003, 0xa897, 0x4005, 0xa99a, 0x0010, 0xa897, 0x4006,
- 0x900e, 0x9085, 0x0001, 0x2001, 0x0030, 0x0005, 0xa897, 0x4000,
- 0xa99a, 0x9006, 0x918d, 0x0001, 0x2008, 0x0005, 0x9006, 0x0005,
- 0xa830, 0x2008, 0x918e, 0xdead, 0x1120, 0x2021, 0x4009, 0x0804,
- 0x340a, 0x9086, 0x0100, 0x7024, 0x2058, 0x1110, 0x0804, 0x5430,
- 0x900e, 0x080c, 0x65c4, 0x1108, 0xc185, 0xb800, 0xd0bc, 0x0108,
- 0xc18d, 0x0804, 0x3408, 0x080c, 0x54f0, 0x0120, 0x2009, 0x0007,
- 0x0804, 0x343a, 0x7f84, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0x080c,
- 0x49b8, 0x1120, 0x2009, 0x0002, 0x0804, 0x343a, 0x900e, 0x2130,
- 0x7126, 0x7132, 0xa860, 0x20e8, 0x7036, 0xa85c, 0x9080, 0x0005,
- 0x702a, 0x20a0, 0x080c, 0x63a4, 0x1904, 0x4d25, 0x080c, 0x66ca,
- 0x0120, 0x080c, 0x66d2, 0x1904, 0x4d25, 0x080c, 0x66c2, 0x1130,
- 0x080c, 0x65c4, 0x1118, 0xd79c, 0x0904, 0x4d25, 0xd794, 0x1110,
- 0xd784, 0x01a8, 0xb8b4, 0x20e0, 0xb8b8, 0x9080, 0x0006, 0x2098,
- 0x3400, 0xd794, 0x0198, 0x20a9, 0x0008, 0x4003, 0x2098, 0x20a0,
- 0x3d00, 0x20e0, 0x20a9, 0x0002, 0x080c, 0x47c7, 0x0080, 0xb8b4,
- 0x20e0, 0xb8b8, 0x9080, 0x000a, 0x2098, 0x3400, 0x20a9, 0x0004,
- 0x4003, 0x2098, 0x20a0, 0x3d00, 0x20e0, 0x080c, 0x47c7, 0x4104,
- 0xd794, 0x0528, 0xb8b4, 0x20e0, 0xb8b8, 0x2060, 0x9c80, 0x0000,
- 0x2098, 0x20a9, 0x0002, 0x4003, 0x9c80, 0x0003, 0x2098, 0x20a9,
- 0x0001, 0x4005, 0x9c80, 0x0004, 0x2098, 0x3400, 0x20a9, 0x0002,
- 0x4003, 0x2098, 0x20a0, 0x3d00, 0x20e0, 0x080c, 0x47ba, 0x9c80,
- 0x0026, 0x2098, 0xb8b4, 0x20e0, 0x20a9, 0x0002, 0x4003, 0xd794,
- 0x0110, 0x96b0, 0x000b, 0x96b0, 0x0005, 0x8108, 0x080c, 0x9f54,
- 0x0118, 0x9186, 0x0800, 0x0040, 0xd78c, 0x0120, 0x9186, 0x0800,
- 0x0170, 0x0018, 0x9186, 0x007e, 0x0150, 0xd794, 0x0118, 0x9686,
- 0x0020, 0x0010, 0x9686, 0x0028, 0x0150, 0x0804, 0x4cba, 0x86ff,
- 0x1120, 0x7124, 0x810b, 0x0804, 0x3408, 0x7033, 0x0001, 0x7122,
- 0x7024, 0x9600, 0x7026, 0x772e, 0x2061, 0x18b6, 0x2c44, 0xa06b,
- 0x0000, 0xa67a, 0x7034, 0xa072, 0x7028, 0xa076, 0xa28e, 0xa392,
- 0xa496, 0xa59a, 0x080c, 0x1140, 0x7007, 0x0002, 0x701f, 0x4d61,
- 0x0005, 0x7030, 0x9005, 0x1180, 0x7120, 0x7028, 0x20a0, 0x772c,
- 0x9036, 0x7034, 0x20e8, 0x2061, 0x18b6, 0x2c44, 0xa28c, 0xa390,
- 0xa494, 0xa598, 0x0804, 0x4cba, 0x7124, 0x810b, 0x0804, 0x3408,
- 0x2029, 0x007e, 0x7984, 0x7a88, 0x7b8c, 0x7c98, 0x9184, 0xff00,
- 0x8007, 0x90e2, 0x0020, 0x0a04, 0x343d, 0x9502, 0x0a04, 0x343d,
- 0x9184, 0x00ff, 0x90e2, 0x0020, 0x0a04, 0x343d, 0x9502, 0x0a04,
- 0x343d, 0x9284, 0xff00, 0x8007, 0x90e2, 0x0020, 0x0a04, 0x343d,
- 0x9502, 0x0a04, 0x343d, 0x9284, 0x00ff, 0x90e2, 0x0020, 0x0a04,
- 0x343d, 0x9502, 0x0a04, 0x343d, 0x9384, 0xff00, 0x8007, 0x90e2,
- 0x0020, 0x0a04, 0x343d, 0x9502, 0x0a04, 0x343d, 0x9384, 0x00ff,
- 0x90e2, 0x0020, 0x0a04, 0x343d, 0x9502, 0x0a04, 0x343d, 0x9484,
- 0xff00, 0x8007, 0x90e2, 0x0020, 0x0a04, 0x343d, 0x9502, 0x0a04,
- 0x343d, 0x9484, 0x00ff, 0x90e2, 0x0020, 0x0a04, 0x343d, 0x9502,
- 0x0a04, 0x343d, 0x2061, 0x1963, 0x6102, 0x6206, 0x630a, 0x640e,
- 0x0804, 0x3408, 0x0006, 0x080c, 0x54dc, 0xd0cc, 0x000e, 0x0005,
- 0x0006, 0x080c, 0x54e0, 0xd0bc, 0x000e, 0x0005, 0x6170, 0x7a84,
- 0x6300, 0x82ff, 0x1118, 0x7986, 0x0804, 0x3408, 0x83ff, 0x1904,
- 0x343d, 0x2001, 0xfff0, 0x9200, 0x1a04, 0x343d, 0x2019, 0xffff,
- 0x6074, 0x9302, 0x9200, 0x0a04, 0x343d, 0x7986, 0x6272, 0x0804,
- 0x3408, 0x080c, 0x54f0, 0x1904, 0x343a, 0x7c88, 0x7d84, 0x7e98,
- 0x7f8c, 0x080c, 0x49b8, 0x0904, 0x343a, 0x900e, 0x901e, 0x7326,
- 0x7332, 0xa860, 0x20e8, 0x7036, 0xa85c, 0x9080, 0x0003, 0x702a,
- 0x20a0, 0x91d8, 0x1000, 0x2b5c, 0x8bff, 0x0178, 0x080c, 0x66ca,
- 0x0118, 0x080c, 0x66d2, 0x1148, 0x20a9, 0x0001, 0xb814, 0x4004,
- 0xb810, 0x4004, 0x4104, 0x9398, 0x0003, 0x8108, 0x9182, 0x0800,
- 0x0120, 0x9386, 0x003c, 0x0170, 0x0c20, 0x83ff, 0x1148, 0x7224,
- 0x900e, 0x2001, 0x0003, 0x080c, 0x847f, 0x2208, 0x0804, 0x3408,
- 0x7033, 0x0001, 0x7122, 0x7024, 0x9300, 0x7026, 0x2061, 0x18b6,
- 0x2c44, 0xa06b, 0x0000, 0xa37a, 0x7028, 0xa076, 0x7034, 0xa072,
- 0xa48e, 0xa592, 0xa696, 0xa79a, 0x080c, 0x1140, 0x7007, 0x0002,
- 0x701f, 0x4e53, 0x0005, 0x7030, 0x9005, 0x1178, 0x7120, 0x7028,
- 0x20a0, 0x901e, 0x7034, 0x20e8, 0x2061, 0x18b6, 0x2c44, 0xa48c,
- 0xa590, 0xa694, 0xa798, 0x0804, 0x4e11, 0x7224, 0x900e, 0x2001,
- 0x0003, 0x080c, 0x847f, 0x2208, 0x0804, 0x3408, 0x00f6, 0x00e6,
- 0x080c, 0x54f0, 0x2009, 0x0007, 0x1904, 0x4ee6, 0x2071, 0x189c,
- 0x745c, 0x84ff, 0x2009, 0x000e, 0x1904, 0x4ee6, 0xac9c, 0xad98,
- 0xaea4, 0xafa0, 0x0096, 0x080c, 0x105c, 0x2009, 0x0002, 0x0904,
- 0x4ee6, 0x2900, 0x705e, 0x900e, 0x901e, 0x7356, 0x7362, 0xa860,
- 0x7066, 0xa85c, 0x9080, 0x0003, 0x705a, 0x20a0, 0x91d8, 0x1000,
- 0x2b5c, 0x8bff, 0x0178, 0x080c, 0x66ca, 0x0118, 0x080c, 0x66d2,
- 0x1148, 0xb814, 0x20a9, 0x0001, 0x4004, 0xb810, 0x4004, 0x4104,
- 0x9398, 0x0003, 0x8108, 0x9182, 0x0800, 0x0120, 0x9386, 0x003c,
- 0x01e8, 0x0c20, 0x83ff, 0x11c0, 0x7254, 0x900e, 0x2001, 0x0003,
- 0x080c, 0x847f, 0x2208, 0x009e, 0xa897, 0x4000, 0xa99a, 0x715c,
- 0x81ff, 0x090c, 0x0e02, 0x2148, 0x080c, 0x1075, 0x9006, 0x705e,
- 0x918d, 0x0001, 0x2008, 0x0418, 0x7063, 0x0001, 0x7152, 0x7054,
- 0x9300, 0x7056, 0x2061, 0x18b7, 0x2c44, 0xa37a, 0x7058, 0xa076,
- 0x7064, 0xa072, 0xa48e, 0xa592, 0xa696, 0xa79a, 0xa09f, 0x4ef2,
- 0x000e, 0xa0a2, 0x080c, 0x1140, 0x9006, 0x0048, 0x009e, 0xa897,
- 0x4005, 0xa99a, 0x900e, 0x9085, 0x0001, 0x2001, 0x0030, 0x00ee,
- 0x00fe, 0x0005, 0x00f6, 0xa0a0, 0x904d, 0x090c, 0x0e02, 0x00e6,
- 0x2071, 0x189c, 0xa06c, 0x908e, 0x0100, 0x0138, 0xa87b, 0x0030,
- 0xa883, 0x0000, 0xa897, 0x4002, 0x00d8, 0x7060, 0x9005, 0x1158,
- 0x7150, 0x7058, 0x20a0, 0x901e, 0x7064, 0x20e8, 0xa48c, 0xa590,
- 0xa694, 0xa798, 0x0428, 0xa87b, 0x0000, 0xa883, 0x0000, 0xa897,
- 0x4000, 0x7254, 0x900e, 0x2001, 0x0003, 0x080c, 0x847f, 0xaa9a,
- 0x715c, 0x81ff, 0x090c, 0x0e02, 0x2148, 0x080c, 0x1075, 0x705f,
- 0x0000, 0xa0a0, 0x2048, 0x0126, 0x2091, 0x8000, 0x080c, 0x6a23,
- 0x012e, 0xa09f, 0x0000, 0xa0a3, 0x0000, 0x00ee, 0x00fe, 0x0005,
- 0x91d8, 0x1000, 0x2b5c, 0x8bff, 0x0178, 0x080c, 0x66ca, 0x0118,
- 0x080c, 0x66d2, 0x1148, 0xb814, 0x20a9, 0x0001, 0x4004, 0xb810,
- 0x4004, 0x4104, 0x9398, 0x0003, 0x8108, 0x9182, 0x0800, 0x0120,
- 0x9386, 0x003c, 0x0518, 0x0c20, 0x83ff, 0x11f0, 0x7154, 0x810c,
- 0xa99a, 0xa897, 0x4000, 0x715c, 0x81ff, 0x090c, 0x0e02, 0x2148,
- 0x080c, 0x1075, 0x9006, 0x705e, 0x918d, 0x0001, 0x2008, 0xa0a0,
- 0x2048, 0x0126, 0x2091, 0x8000, 0x080c, 0x6a23, 0x012e, 0xa09f,
- 0x0000, 0xa0a3, 0x0000, 0x0070, 0x7063, 0x0001, 0x7152, 0x7054,
- 0x9300, 0x7056, 0xa37a, 0xa48e, 0xa592, 0xa696, 0xa79a, 0x080c,
- 0x1140, 0x9006, 0x00ee, 0x0005, 0x0096, 0xa88c, 0x90be, 0x7000,
- 0x0148, 0x90be, 0x7100, 0x0130, 0x90be, 0x7200, 0x0118, 0x009e,
- 0x0804, 0x343d, 0xa884, 0xa988, 0x080c, 0x266e, 0x1518, 0x080c,
- 0x6344, 0x1500, 0x7126, 0xbe12, 0xbd16, 0xae7c, 0x080c, 0x49b8,
- 0x01c8, 0x080c, 0x49b8, 0x01b0, 0x009e, 0xa867, 0x0000, 0xa868,
- 0xc0fd, 0xa86a, 0xa823, 0x0000, 0xa804, 0x2048, 0x080c, 0xbee7,
- 0x1120, 0x2009, 0x0003, 0x0804, 0x343a, 0x7007, 0x0003, 0x701f,
- 0x4fbf, 0x0005, 0x009e, 0x2009, 0x0002, 0x0804, 0x343a, 0x7124,
- 0x080c, 0x31a6, 0xa820, 0x9086, 0x8001, 0x1120, 0x2009, 0x0004,
- 0x0804, 0x343a, 0x2900, 0x7022, 0xa804, 0x0096, 0x2048, 0x8906,
- 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x009e, 0x9080,
- 0x0002, 0x0076, 0x0006, 0x2098, 0x20a0, 0x27e0, 0x27e8, 0x20a9,
- 0x002a, 0x080c, 0x0fc0, 0xaa6c, 0xab70, 0xac74, 0xad78, 0x2061,
- 0x18b6, 0x2c44, 0xa06b, 0x0000, 0xae64, 0xaf8c, 0x97c6, 0x7000,
- 0x0118, 0x97c6, 0x7100, 0x1148, 0x96c2, 0x0004, 0x0600, 0x2009,
- 0x0004, 0x000e, 0x007e, 0x0804, 0x4a04, 0x97c6, 0x7200, 0x11b8,
- 0x96c2, 0x0054, 0x02a0, 0x000e, 0x007e, 0x2061, 0x18b6, 0x2c44,
- 0xa076, 0xa772, 0xa07b, 0x002a, 0xa28e, 0xa392, 0xa496, 0xa59a,
- 0x080c, 0x1140, 0x7007, 0x0002, 0x701f, 0x501b, 0x0005, 0x000e,
- 0x007e, 0x0804, 0x343d, 0x7020, 0x2048, 0xa804, 0x2048, 0xa804,
- 0x2048, 0x8906, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0,
- 0x9080, 0x0002, 0x2098, 0x20a0, 0x27e0, 0x27e8, 0x20a9, 0x002a,
- 0x080c, 0x0fc0, 0x2100, 0x2238, 0x2061, 0x18b6, 0x2c44, 0xa28c,
- 0xa390, 0xa494, 0xa598, 0x2009, 0x002a, 0x0804, 0x4a04, 0x81ff,
- 0x1904, 0x343a, 0x798c, 0x2001, 0x1958, 0x918c, 0x8000, 0x2102,
- 0x080c, 0x49cf, 0x0904, 0x343d, 0x080c, 0x66ca, 0x0120, 0x080c,
- 0x66d2, 0x1904, 0x343d, 0x080c, 0x646b, 0x0904, 0x343a, 0x0126,
- 0x2091, 0x8000, 0x080c, 0x6531, 0x012e, 0x0904, 0x343a, 0x2001,
- 0x1958, 0x2004, 0xd0fc, 0x1904, 0x3408, 0x0804, 0x4462, 0xa9a0,
- 0x2001, 0x1958, 0x918c, 0x8000, 0xc18d, 0x2102, 0x080c, 0x49dc,
- 0x01a0, 0x080c, 0x66ca, 0x0118, 0x080c, 0x66d2, 0x1170, 0x080c,
- 0x646b, 0x2009, 0x0002, 0x0128, 0x080c, 0x6531, 0x1170, 0x2009,
+ 0x20a9, 0x0001, 0x04f1, 0x00c6, 0x080c, 0x49b7, 0x0550, 0xa868,
+ 0xc0fd, 0xa86a, 0xa867, 0x0119, 0x9006, 0xa882, 0xa87f, 0x0020,
+ 0xa88b, 0x0001, 0x810b, 0xa9ae, 0xa8b2, 0xaab6, 0xabba, 0xacbe,
+ 0xadc2, 0xa9c6, 0xa8ca, 0x00ce, 0x009e, 0x00de, 0xa866, 0xa822,
+ 0xa868, 0xc0fd, 0xa86a, 0xa804, 0x2048, 0x080c, 0xbeda, 0x1120,
+ 0x2009, 0x0003, 0x0804, 0x3424, 0x7007, 0x0003, 0x701f, 0x47b0,
+ 0x0005, 0x00ce, 0x009e, 0x00de, 0x2009, 0x0002, 0x0804, 0x3424,
+ 0xa820, 0x9086, 0x8001, 0x1904, 0x33f2, 0x2009, 0x0004, 0x0804,
+ 0x3424, 0x0016, 0x0026, 0x3510, 0x20a9, 0x0002, 0x4002, 0x4104,
+ 0x4004, 0x8211, 0x1dc8, 0x002e, 0x001e, 0x0005, 0x0016, 0x0026,
+ 0x0036, 0x0046, 0x3520, 0x20a9, 0x0004, 0x4002, 0x4304, 0x4204,
+ 0x4104, 0x4004, 0x8421, 0x1db8, 0x004e, 0x003e, 0x002e, 0x001e,
+ 0x0005, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x3424, 0x60d8,
+ 0xd0ac, 0x1160, 0xd09c, 0x0120, 0x2009, 0x0016, 0x0804, 0x3424,
+ 0xd09c, 0x1120, 0x2009, 0x0005, 0x0804, 0x3424, 0x7984, 0x78a8,
+ 0x2040, 0x080c, 0x9f69, 0x1120, 0x9182, 0x007f, 0x0a04, 0x3427,
+ 0x9186, 0x00ff, 0x0904, 0x3427, 0x9182, 0x0800, 0x1a04, 0x3427,
+ 0x7a8c, 0x7b88, 0x6078, 0x9306, 0x1158, 0x607c, 0x924e, 0x0904,
+ 0x3427, 0x080c, 0x9f69, 0x1120, 0x99cc, 0xff00, 0x0904, 0x3427,
+ 0x0126, 0x2091, 0x8000, 0x9386, 0x00ff, 0x0178, 0x0026, 0x2011,
+ 0x8008, 0x080c, 0x66ed, 0x002e, 0x0140, 0x918d, 0x8000, 0x080c,
+ 0x6737, 0x1118, 0x2001, 0x4009, 0x0458, 0x080c, 0x48d1, 0x0560,
+ 0x90c6, 0x4000, 0x1170, 0x00c6, 0x0006, 0x900e, 0x080c, 0x65c3,
+ 0x1108, 0xc185, 0xb800, 0xd0bc, 0x0108, 0xc18d, 0x000e, 0x00ce,
+ 0x00b8, 0x90c6, 0x4007, 0x1110, 0x2408, 0x0090, 0x90c6, 0x4008,
+ 0x1118, 0x2708, 0x2610, 0x0060, 0x90c6, 0x4009, 0x1108, 0x0040,
+ 0x90c6, 0x4006, 0x1108, 0x0020, 0x2001, 0x4005, 0x2009, 0x000a,
+ 0x2020, 0x012e, 0x0804, 0x33f4, 0x2b00, 0x7026, 0x0016, 0x00b6,
+ 0x00c6, 0x00e6, 0x2c70, 0x080c, 0xa03b, 0x0904, 0x489e, 0x2b00,
+ 0x6012, 0x080c, 0xc1ca, 0x2e58, 0x00ee, 0x00e6, 0x00c6, 0x080c,
+ 0x49b7, 0x00ce, 0x2b70, 0x1158, 0x080c, 0x9fea, 0x00ee, 0x00ce,
+ 0x00be, 0x001e, 0x012e, 0x2009, 0x0002, 0x0804, 0x3424, 0x900e,
+ 0xa966, 0xa96a, 0x2900, 0x6016, 0xa932, 0xa868, 0xc0fd, 0xd88c,
+ 0x0108, 0xc0f5, 0xa86a, 0x080c, 0x3095, 0x6023, 0x0001, 0x9006,
+ 0x080c, 0x62e0, 0x2001, 0x0002, 0x080c, 0x62f4, 0x2009, 0x0002,
+ 0x080c, 0xa068, 0x78a8, 0xd094, 0x0138, 0x00ee, 0x7024, 0x00e6,
+ 0x2058, 0xb8bc, 0xc08d, 0xb8be, 0x9085, 0x0001, 0x00ee, 0x00ce,
+ 0x00be, 0x001e, 0x012e, 0x1120, 0x2009, 0x0003, 0x0804, 0x3424,
+ 0x7007, 0x0003, 0x701f, 0x48ad, 0x0005, 0xa830, 0x2008, 0x918e,
+ 0xdead, 0x1120, 0x2021, 0x4009, 0x0804, 0x33f4, 0x9086, 0x0100,
+ 0x7024, 0x2058, 0x1138, 0x2009, 0x0004, 0xba04, 0x9294, 0x00ff,
+ 0x0804, 0x542f, 0x900e, 0xa868, 0xd0f4, 0x1904, 0x33f2, 0x080c,
+ 0x65c3, 0x1108, 0xc185, 0xb800, 0xd0bc, 0x0108, 0xc18d, 0x0804,
+ 0x33f2, 0x00e6, 0x00d6, 0x0096, 0x83ff, 0x0904, 0x4919, 0x902e,
+ 0x080c, 0x9f69, 0x0130, 0x9026, 0x20a9, 0x0800, 0x2071, 0x1000,
+ 0x0030, 0x2021, 0x007f, 0x20a9, 0x0781, 0x2071, 0x107f, 0x2e04,
+ 0x9005, 0x11b0, 0x2100, 0x9406, 0x15e8, 0x2428, 0x94ce, 0x007f,
+ 0x1120, 0x92ce, 0xfffd, 0x1528, 0x0030, 0x94ce, 0x0080, 0x1130,
+ 0x92ce, 0xfffc, 0x11f0, 0x93ce, 0x00ff, 0x11d8, 0xc5fd, 0x0450,
+ 0x2058, 0xbf10, 0x2700, 0x9306, 0x11b8, 0xbe14, 0x2600, 0x9206,
+ 0x1198, 0x2400, 0x9106, 0x1150, 0xd884, 0x0568, 0xd894, 0x1558,
+ 0x080c, 0x66c9, 0x1540, 0x2001, 0x4000, 0x0430, 0x2001, 0x4007,
+ 0x0418, 0x2001, 0x4006, 0x0400, 0x2400, 0x9106, 0x1158, 0xbe14,
+ 0x87ff, 0x1128, 0x86ff, 0x0948, 0x080c, 0x9f69, 0x1930, 0x2001,
+ 0x4008, 0x0090, 0x8420, 0x8e70, 0x1f04, 0x48e7, 0x85ff, 0x1130,
+ 0x2001, 0x4009, 0x0048, 0x2001, 0x0001, 0x0030, 0x080c, 0x6343,
+ 0x1dd0, 0xbb12, 0xba16, 0x9006, 0x9005, 0x009e, 0x00de, 0x00ee,
+ 0x0005, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x3424, 0x080c,
+ 0x49b7, 0x1120, 0x2009, 0x0002, 0x0804, 0x3424, 0xa867, 0x0000,
+ 0xa868, 0xc0fd, 0xa86a, 0x7884, 0x9005, 0x0904, 0x3427, 0x9096,
+ 0x00ff, 0x0120, 0x9092, 0x0004, 0x1a04, 0x3427, 0x2010, 0x2918,
+ 0x080c, 0x303b, 0x1120, 0x2009, 0x0003, 0x0804, 0x3424, 0x7007,
+ 0x0003, 0x701f, 0x496c, 0x0005, 0xa830, 0x9086, 0x0100, 0x1904,
+ 0x33f2, 0x2009, 0x0004, 0x0804, 0x3424, 0x7984, 0x080c, 0x9f69,
+ 0x1120, 0x9182, 0x007f, 0x0a04, 0x3427, 0x9186, 0x00ff, 0x0904,
+ 0x3427, 0x9182, 0x0800, 0x1a04, 0x3427, 0x2001, 0x9400, 0x080c,
+ 0x548a, 0x1904, 0x3424, 0x0804, 0x33f2, 0xa998, 0x080c, 0x9f69,
+ 0x1118, 0x9182, 0x007f, 0x0280, 0x9186, 0x00ff, 0x0168, 0x9182,
+ 0x0800, 0x1250, 0x2001, 0x9400, 0x080c, 0x548a, 0x11a8, 0x0060,
+ 0xa897, 0x4005, 0xa99a, 0x0010, 0xa897, 0x4006, 0x900e, 0x9085,
+ 0x0001, 0x2001, 0x0030, 0x0005, 0xa897, 0x4000, 0x900e, 0x9085,
+ 0x0001, 0x2001, 0x0000, 0x0005, 0x2009, 0x000a, 0x0c48, 0x080c,
+ 0x1037, 0x0198, 0x9006, 0xa802, 0x7014, 0x9005, 0x1120, 0x2900,
+ 0x7016, 0x701a, 0x0040, 0x7018, 0xa802, 0x0086, 0x2040, 0x2900,
+ 0xa006, 0x701a, 0x008e, 0x9085, 0x0001, 0x0005, 0x7984, 0x080c,
+ 0x63a3, 0x1130, 0x7e88, 0x9684, 0x3fff, 0x9082, 0x4000, 0x0208,
+ 0x905e, 0x8bff, 0x0005, 0xa998, 0x080c, 0x63a3, 0x1130, 0xae9c,
+ 0x9684, 0x3fff, 0x9082, 0x4000, 0x0208, 0x905e, 0x8bff, 0x0005,
+ 0xae98, 0x0008, 0x7e84, 0x2608, 0x080c, 0x63a3, 0x1108, 0x0008,
+ 0x905e, 0x8bff, 0x0005, 0x0016, 0x7114, 0x81ff, 0x0128, 0x2148,
+ 0xa904, 0x080c, 0x1069, 0x0cc8, 0x7116, 0x711a, 0x001e, 0x0005,
+ 0x2031, 0x0001, 0x0010, 0x2031, 0x0000, 0x2061, 0x18b6, 0x2c44,
+ 0xa66a, 0xa17a, 0xa772, 0xa076, 0xa28e, 0xa392, 0xa496, 0xa59a,
+ 0x080c, 0x1134, 0x7007, 0x0002, 0x701f, 0x33f2, 0x0005, 0x00f6,
+ 0x0126, 0x2091, 0x8000, 0x2079, 0x0000, 0x2001, 0x18ae, 0x2004,
+ 0x9005, 0x1190, 0x0e04, 0x4a34, 0x7a36, 0x7833, 0x0012, 0x7a82,
+ 0x7b86, 0x7c8a, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084,
+ 0x190c, 0x11e6, 0x0804, 0x4a9a, 0x0016, 0x0086, 0x0096, 0x00c6,
+ 0x00e6, 0x2071, 0x189c, 0x7044, 0x9005, 0x1540, 0x7148, 0x9182,
+ 0x0010, 0x0288, 0x7038, 0x2060, 0x080c, 0x1037, 0x0904, 0x4a92,
+ 0xa84b, 0x0000, 0x2900, 0x7046, 0x2001, 0x0002, 0x9080, 0x1ebe,
+ 0x2005, 0xa846, 0x0098, 0x7038, 0x90e0, 0x0004, 0x2001, 0x18b8,
+ 0x9c82, 0x18f8, 0x0210, 0x2061, 0x18b8, 0x2c00, 0x703a, 0x7148,
+ 0x81ff, 0x1108, 0x703e, 0x8108, 0x714a, 0x0460, 0x7148, 0x8108,
+ 0x714a, 0x7044, 0x2040, 0xa144, 0x2105, 0x0016, 0x908a, 0x0036,
+ 0x1a0c, 0x0df6, 0x2060, 0x001e, 0x8108, 0x2105, 0x9005, 0xa146,
+ 0x1520, 0x080c, 0x1037, 0x1130, 0x8109, 0xa946, 0x7148, 0x8109,
+ 0x714a, 0x00d8, 0x9006, 0xa806, 0xa84a, 0xa046, 0x2800, 0xa802,
+ 0x2900, 0xa006, 0x7046, 0x2001, 0x0002, 0x9080, 0x1ebe, 0x2005,
+ 0xa846, 0x0058, 0x2262, 0x6306, 0x640a, 0x00ee, 0x00ce, 0x009e,
+ 0x008e, 0x001e, 0x012e, 0x00fe, 0x0005, 0x2c00, 0x9082, 0x001b,
+ 0x0002, 0x4abc, 0x4abc, 0x4abe, 0x4abc, 0x4abc, 0x4abc, 0x4ac2,
+ 0x4abc, 0x4abc, 0x4abc, 0x4ac6, 0x4abc, 0x4abc, 0x4abc, 0x4aca,
+ 0x4abc, 0x4abc, 0x4abc, 0x4ace, 0x4abc, 0x4abc, 0x4abc, 0x4ad2,
+ 0x4abc, 0x4abc, 0x4abc, 0x4ad7, 0x080c, 0x0df6, 0xa276, 0xa37a,
+ 0xa47e, 0x0898, 0xa286, 0xa38a, 0xa48e, 0x0878, 0xa296, 0xa39a,
+ 0xa49e, 0x0858, 0xa2a6, 0xa3aa, 0xa4ae, 0x0838, 0xa2b6, 0xa3ba,
+ 0xa4be, 0x0818, 0xa2c6, 0xa3ca, 0xa4ce, 0x0804, 0x4a95, 0xa2d6,
+ 0xa3da, 0xa4de, 0x0804, 0x4a95, 0x00e6, 0x2071, 0x189c, 0x7048,
+ 0x9005, 0x0904, 0x4b6e, 0x0126, 0x2091, 0x8000, 0x0e04, 0x4b6d,
+ 0x00f6, 0x2079, 0x0000, 0x00c6, 0x0096, 0x0086, 0x0076, 0x9006,
+ 0x2038, 0x7040, 0x2048, 0x9005, 0x0500, 0xa948, 0x2105, 0x0016,
+ 0x908a, 0x0036, 0x1a0c, 0x0df6, 0x2060, 0x001e, 0x8108, 0x2105,
+ 0x9005, 0xa94a, 0x1904, 0x4b70, 0xa804, 0x9005, 0x090c, 0x0df6,
+ 0x7042, 0x2938, 0x2040, 0xa003, 0x0000, 0x2001, 0x0002, 0x9080,
+ 0x1ebe, 0x2005, 0xa04a, 0x0804, 0x4b70, 0x703c, 0x2060, 0x2c14,
+ 0x6304, 0x6408, 0x650c, 0x2200, 0x7836, 0x7833, 0x0012, 0x7882,
+ 0x2300, 0x7886, 0x2400, 0x788a, 0x2091, 0x4080, 0x2001, 0x0089,
+ 0x2004, 0xd084, 0x190c, 0x11e6, 0x87ff, 0x0118, 0x2748, 0x080c,
+ 0x1069, 0x7048, 0x8001, 0x704a, 0x9005, 0x1170, 0x7040, 0x2048,
+ 0x9005, 0x0128, 0x080c, 0x1069, 0x9006, 0x7042, 0x7046, 0x703b,
+ 0x18b8, 0x703f, 0x18b8, 0x0420, 0x7040, 0x9005, 0x1508, 0x7238,
+ 0x2c00, 0x9206, 0x0148, 0x9c80, 0x0004, 0x90fa, 0x18f8, 0x0210,
+ 0x2001, 0x18b8, 0x703e, 0x00a0, 0x9006, 0x703e, 0x703a, 0x7044,
+ 0x9005, 0x090c, 0x0df6, 0x2048, 0xa800, 0x9005, 0x1de0, 0x2900,
+ 0x7042, 0x2001, 0x0002, 0x9080, 0x1ebe, 0x2005, 0xa84a, 0x0000,
+ 0x007e, 0x008e, 0x009e, 0x00ce, 0x00fe, 0x012e, 0x00ee, 0x0005,
+ 0x2c00, 0x9082, 0x001b, 0x0002, 0x4b8f, 0x4b8f, 0x4b91, 0x4b8f,
+ 0x4b8f, 0x4b8f, 0x4b96, 0x4b8f, 0x4b8f, 0x4b8f, 0x4b9b, 0x4b8f,
+ 0x4b8f, 0x4b8f, 0x4ba0, 0x4b8f, 0x4b8f, 0x4b8f, 0x4ba5, 0x4b8f,
+ 0x4b8f, 0x4b8f, 0x4baa, 0x4b8f, 0x4b8f, 0x4b8f, 0x4baf, 0x080c,
+ 0x0df6, 0xaa74, 0xab78, 0xac7c, 0x0804, 0x4b1b, 0xaa84, 0xab88,
+ 0xac8c, 0x0804, 0x4b1b, 0xaa94, 0xab98, 0xac9c, 0x0804, 0x4b1b,
+ 0xaaa4, 0xaba8, 0xacac, 0x0804, 0x4b1b, 0xaab4, 0xabb8, 0xacbc,
+ 0x0804, 0x4b1b, 0xaac4, 0xabc8, 0xaccc, 0x0804, 0x4b1b, 0xaad4,
+ 0xabd8, 0xacdc, 0x0804, 0x4b1b, 0x0026, 0x080c, 0x54db, 0xd0c4,
+ 0x0120, 0x2011, 0x8014, 0x080c, 0x4a17, 0x002e, 0x0005, 0x81ff,
+ 0x1904, 0x3424, 0x0126, 0x2091, 0x8000, 0x6030, 0xc08d, 0xc085,
+ 0xc0ac, 0x6032, 0x080c, 0x717e, 0x1158, 0x080c, 0x747a, 0x080c,
+ 0x5e2f, 0x9085, 0x0001, 0x080c, 0x71c2, 0x080c, 0x709e, 0x0010,
+ 0x080c, 0x5cee, 0x012e, 0x0804, 0x33f2, 0x81ff, 0x0120, 0x2009,
+ 0x0001, 0x0804, 0x3424, 0x080c, 0x54ef, 0x0120, 0x2009, 0x0007,
+ 0x0804, 0x3424, 0x080c, 0x66c1, 0x0120, 0x2009, 0x0008, 0x0804,
+ 0x3424, 0x0026, 0x2011, 0x0010, 0x080c, 0x66ed, 0x002e, 0x0140,
+ 0x7984, 0x080c, 0x6737, 0x1120, 0x2009, 0x4009, 0x0804, 0x3424,
+ 0x7984, 0x080c, 0x6343, 0x1904, 0x3427, 0x080c, 0x49ea, 0x0904,
+ 0x3427, 0x2b00, 0x7026, 0x080c, 0x66c9, 0x7888, 0x1170, 0x9084,
+ 0x0005, 0x1158, 0x900e, 0x080c, 0x65c3, 0x1108, 0xc185, 0xb800,
+ 0xd0bc, 0x0108, 0xc18d, 0x0804, 0x33f2, 0x080c, 0x49b7, 0x0904,
+ 0x3424, 0x9006, 0xa866, 0xa832, 0xa868, 0xc0fd, 0xa86a, 0x080c,
+ 0xbf78, 0x0904, 0x3424, 0x7888, 0xd094, 0x0118, 0xb8bc, 0xc08d,
+ 0xb8be, 0x7007, 0x0003, 0x701f, 0x4c7f, 0x0005, 0x2061, 0x1800,
+ 0x080c, 0x54ef, 0x2009, 0x0007, 0x1560, 0x080c, 0x66c1, 0x0118,
+ 0x2009, 0x0008, 0x0430, 0xa998, 0x080c, 0x6343, 0x1530, 0x080c,
+ 0x49e8, 0x0518, 0x080c, 0x66c9, 0xa89c, 0x1168, 0x9084, 0x0005,
+ 0x1150, 0x900e, 0x080c, 0x65c3, 0x1108, 0xc185, 0xb800, 0xd0bc,
+ 0x0108, 0xc18d, 0x00d0, 0xa868, 0xc0fc, 0xa86a, 0x080c, 0xbf78,
+ 0x11e0, 0xa89c, 0xd094, 0x0118, 0xb8bc, 0xc08d, 0xb8be, 0x2009,
0x0003, 0xa897, 0x4005, 0xa99a, 0x0010, 0xa897, 0x4006, 0x900e,
- 0x9085, 0x0001, 0x2001, 0x0030, 0x0005, 0xa897, 0x4000, 0x2001,
- 0x1958, 0x2004, 0xd0fc, 0x1128, 0x080c, 0x54e4, 0x0110, 0x9006,
- 0x0018, 0x900e, 0x9085, 0x0001, 0x2001, 0x0000, 0x0005, 0x78a8,
- 0xd08c, 0x1118, 0xd084, 0x0904, 0x43d7, 0x080c, 0x49eb, 0x0904,
- 0x343d, 0x080c, 0x49b8, 0x1120, 0x2009, 0x0002, 0x0804, 0x343a,
- 0x080c, 0x66ca, 0x0130, 0x908e, 0x0004, 0x0118, 0x908e, 0x0005,
- 0x15a0, 0x78a8, 0xd08c, 0x0120, 0xb800, 0xc08c, 0xb802, 0x0028,
- 0x080c, 0x54dc, 0xd0b4, 0x0904, 0x4411, 0x7884, 0x908e, 0x007e,
- 0x0904, 0x4411, 0x908e, 0x007f, 0x0904, 0x4411, 0x908e, 0x0080,
- 0x0904, 0x4411, 0xb800, 0xd08c, 0x1904, 0x4411, 0xa867, 0x0000,
- 0xa868, 0xc0fd, 0xa86a, 0x080c, 0xbf06, 0x1120, 0x2009, 0x0003,
- 0x0804, 0x343a, 0x7007, 0x0003, 0x701f, 0x50e7, 0x0005, 0x080c,
- 0x49eb, 0x0904, 0x343d, 0x0804, 0x4411, 0x080c, 0x31ff, 0x0108,
- 0x0005, 0x2009, 0x1833, 0x210c, 0x81ff, 0x0120, 0x2009, 0x0001,
- 0x0804, 0x343a, 0x080c, 0x54f0, 0x0120, 0x2009, 0x0007, 0x0804,
- 0x343a, 0x080c, 0x66c2, 0x0120, 0x2009, 0x0008, 0x0804, 0x343a,
- 0xb89c, 0xd0a4, 0x1118, 0xd0ac, 0x1904, 0x4411, 0x9006, 0xa866,
- 0xa832, 0xa868, 0xc0fd, 0xa86a, 0x080c, 0xbf65, 0x1120, 0x2009,
- 0x0003, 0x0804, 0x343a, 0x7007, 0x0003, 0x701f, 0x5120, 0x0005,
- 0xa830, 0x9086, 0x0100, 0x1120, 0x2009, 0x0004, 0x0804, 0x5430,
- 0x080c, 0x49eb, 0x0904, 0x343d, 0x0804, 0x50b9, 0x81ff, 0x2009,
- 0x0001, 0x1904, 0x343a, 0x080c, 0x54f0, 0x2009, 0x0007, 0x1904,
- 0x343a, 0x080c, 0x66c2, 0x0120, 0x2009, 0x0008, 0x0804, 0x343a,
- 0x080c, 0x49eb, 0x0904, 0x343d, 0x080c, 0x66ca, 0x2009, 0x0009,
- 0x1904, 0x343a, 0x080c, 0x49b8, 0x2009, 0x0002, 0x0904, 0x343a,
- 0x9006, 0xa866, 0xa832, 0xa868, 0xc0fd, 0xa86a, 0x7988, 0xa95a,
- 0x9194, 0xfd00, 0x918c, 0x00ff, 0x9006, 0x82ff, 0x1128, 0xc0ed,
- 0xa952, 0x798c, 0xa956, 0x0038, 0x928e, 0x0100, 0x1904, 0x343d,
- 0xc0e5, 0xa952, 0xa956, 0xa83e, 0x080c, 0xc1b8, 0x2009, 0x0003,
- 0x0904, 0x343a, 0x7007, 0x0003, 0x701f, 0x5177, 0x0005, 0xa830,
- 0x9086, 0x0100, 0x2009, 0x0004, 0x0904, 0x343a, 0x0804, 0x3408,
- 0x7aa8, 0x9284, 0xc000, 0x0148, 0xd2ec, 0x01a0, 0x080c, 0x54f0,
- 0x1188, 0x2009, 0x0014, 0x0804, 0x343a, 0xd2dc, 0x1578, 0x81ff,
- 0x2009, 0x0001, 0x1904, 0x343a, 0x080c, 0x54f0, 0x2009, 0x0007,
- 0x1904, 0x343a, 0xd2f4, 0x0138, 0x9284, 0x5000, 0xc0d5, 0x080c,
- 0x54b6, 0x0804, 0x3408, 0xd2fc, 0x0160, 0x080c, 0x49eb, 0x0904,
- 0x343d, 0x7984, 0x9284, 0x9000, 0xc0d5, 0x080c, 0x548b, 0x0804,
- 0x3408, 0x080c, 0x49eb, 0x0904, 0x343d, 0xb804, 0x9084, 0x00ff,
- 0x9086, 0x0006, 0x2009, 0x0009, 0x1904, 0x5266, 0x080c, 0x49b8,
- 0x2009, 0x0002, 0x0904, 0x5266, 0xa85c, 0x9080, 0x001b, 0xaf60,
- 0x2009, 0x0008, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0x080c, 0x4a01,
- 0x701f, 0x51d3, 0x0005, 0xa86c, 0x9086, 0x0500, 0x1138, 0xa870,
- 0x9005, 0x1120, 0xa874, 0x9084, 0xff00, 0x0110, 0x1904, 0x343d,
- 0xa866, 0xa832, 0xa868, 0xc0fd, 0xa86a, 0x080c, 0x49eb, 0x1110,
- 0x0804, 0x343d, 0x2009, 0x0043, 0x080c, 0xc224, 0x2009, 0x0003,
- 0x0904, 0x5266, 0x7007, 0x0003, 0x701f, 0x51f7, 0x0005, 0xa830,
- 0x9086, 0x0100, 0x2009, 0x0004, 0x0904, 0x5266, 0x7984, 0x7aa8,
- 0x9284, 0x1000, 0xc0d5, 0x080c, 0x548b, 0x0804, 0x3408, 0x00c6,
- 0xaab0, 0x9284, 0xc000, 0x0148, 0xd2ec, 0x0170, 0x080c, 0x54f0,
- 0x1158, 0x2009, 0x0014, 0x0804, 0x5255, 0x2061, 0x1800, 0x080c,
- 0x54f0, 0x2009, 0x0007, 0x15c8, 0xd2f4, 0x0130, 0x9284, 0x5000,
- 0xc0d5, 0x080c, 0x54b6, 0x0058, 0xd2fc, 0x0180, 0x080c, 0x49e9,
- 0x0590, 0xa998, 0x9284, 0x9000, 0xc0d5, 0x080c, 0x548b, 0xa87b,
- 0x0000, 0xa883, 0x0000, 0xa897, 0x4000, 0x0438, 0x080c, 0x49e9,
- 0x0510, 0x080c, 0x66ca, 0x2009, 0x0009, 0x11b8, 0xa8c4, 0x9086,
- 0x0500, 0x11c8, 0xa8c8, 0x9005, 0x11b0, 0xa8cc, 0x9084, 0xff00,
- 0x1190, 0x080c, 0x49e9, 0x1108, 0x0070, 0x2009, 0x004b, 0x080c,
- 0xc224, 0x2009, 0x0003, 0x0108, 0x0078, 0x0431, 0x19c0, 0xa897,
- 0x4005, 0xa99a, 0x0010, 0xa897, 0x4006, 0x900e, 0x9085, 0x0001,
- 0x2001, 0x0030, 0x00ce, 0x0005, 0x9006, 0x0ce0, 0x7aa8, 0xd2dc,
- 0x0904, 0x343a, 0x0016, 0x7984, 0x9284, 0x1000, 0xc0fd, 0x080c,
- 0x548b, 0x001e, 0x1904, 0x343a, 0x0804, 0x3408, 0x00f6, 0x2d78,
- 0xaab0, 0x0021, 0x00fe, 0x0005, 0xaab0, 0xc2d5, 0xd2dc, 0x0150,
- 0x0016, 0xa998, 0x9284, 0x1400, 0xc0fd, 0x080c, 0x548b, 0x001e,
- 0x9085, 0x0001, 0x0005, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804,
- 0x343a, 0x080c, 0x54f0, 0x0120, 0x2009, 0x0007, 0x0804, 0x343a,
- 0x7984, 0x7ea8, 0x96b4, 0x00ff, 0x080c, 0x63a4, 0x1904, 0x343d,
- 0x9186, 0x007f, 0x0138, 0x080c, 0x66ca, 0x0120, 0x2009, 0x0009,
- 0x0804, 0x343a, 0x080c, 0x49b8, 0x1120, 0x2009, 0x0002, 0x0804,
- 0x343a, 0xa867, 0x0000, 0xa868, 0xc0fd, 0xa86a, 0x2001, 0x0100,
- 0x8007, 0xa80a, 0x080c, 0xbf20, 0x1120, 0x2009, 0x0003, 0x0804,
- 0x343a, 0x7007, 0x0003, 0x701f, 0x52c6, 0x0005, 0xa808, 0x8007,
- 0x9086, 0x0100, 0x1120, 0x2009, 0x0004, 0x0804, 0x343a, 0xa8e0,
- 0xa866, 0xa810, 0x8007, 0x9084, 0x00ff, 0x800c, 0xa814, 0x8007,
- 0x9084, 0x00ff, 0x8004, 0x9080, 0x0002, 0x9108, 0x8906, 0x8006,
- 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, 0x0004, 0x7a8c,
- 0x7b88, 0x7c9c, 0x7d98, 0x0804, 0x4a04, 0x080c, 0x49b8, 0x1120,
- 0x2009, 0x0002, 0x0804, 0x343a, 0x7984, 0x9194, 0xff00, 0x918c,
- 0x00ff, 0x8217, 0x82ff, 0x1118, 0x7023, 0x198e, 0x0040, 0x92c6,
- 0x0001, 0x1118, 0x7023, 0x19a8, 0x0010, 0x0804, 0x343d, 0x2009,
- 0x001a, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0xa85c, 0x9080, 0x0019,
- 0xaf60, 0x080c, 0x4a01, 0x701f, 0x5316, 0x0005, 0x2001, 0x182d,
- 0x2003, 0x0001, 0xa85c, 0x9080, 0x0019, 0x2098, 0xa860, 0x20e0,
- 0x20a9, 0x001a, 0x7020, 0x20a0, 0x20e9, 0x0001, 0x4003, 0x0804,
- 0x3408, 0x080c, 0x49b8, 0x1120, 0x2009, 0x0002, 0x0804, 0x343a,
- 0x7984, 0x9194, 0xff00, 0x918c, 0x00ff, 0x8217, 0x82ff, 0x1118,
- 0x2099, 0x198e, 0x0040, 0x92c6, 0x0001, 0x1118, 0x2099, 0x19a8,
- 0x0010, 0x0804, 0x343d, 0xa85c, 0x9080, 0x0019, 0x20a0, 0xa860,
- 0x20e8, 0x20a9, 0x001a, 0x20e1, 0x0001, 0x4003, 0x2009, 0x001a,
+ 0x9085, 0x0001, 0x2001, 0x0030, 0x0005, 0xa897, 0x4000, 0xa99a,
+ 0x9006, 0x918d, 0x0001, 0x2008, 0x0005, 0x9006, 0x0005, 0xa830,
+ 0x2008, 0x918e, 0xdead, 0x1120, 0x2021, 0x4009, 0x0804, 0x33f4,
+ 0x9086, 0x0100, 0x7024, 0x2058, 0x1110, 0x0804, 0x542f, 0x900e,
+ 0x080c, 0x65c3, 0x1108, 0xc185, 0xb800, 0xd0bc, 0x0108, 0xc18d,
+ 0x0804, 0x33f2, 0x080c, 0x54ef, 0x0120, 0x2009, 0x0007, 0x0804,
+ 0x3424, 0x7f84, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0x080c, 0x49b7,
+ 0x1120, 0x2009, 0x0002, 0x0804, 0x3424, 0x900e, 0x2130, 0x7126,
+ 0x7132, 0xa860, 0x20e8, 0x7036, 0xa85c, 0x9080, 0x0005, 0x702a,
+ 0x20a0, 0x080c, 0x63a3, 0x1904, 0x4d24, 0x080c, 0x66c9, 0x0120,
+ 0x080c, 0x66d1, 0x1904, 0x4d24, 0x080c, 0x66c1, 0x1130, 0x080c,
+ 0x65c3, 0x1118, 0xd79c, 0x0904, 0x4d24, 0xd794, 0x1110, 0xd784,
+ 0x01a8, 0xb8b4, 0x20e0, 0xb8b8, 0x9080, 0x0006, 0x2098, 0x3400,
+ 0xd794, 0x0198, 0x20a9, 0x0008, 0x4003, 0x2098, 0x20a0, 0x3d00,
+ 0x20e0, 0x20a9, 0x0002, 0x080c, 0x47c6, 0x0080, 0xb8b4, 0x20e0,
+ 0xb8b8, 0x9080, 0x000a, 0x2098, 0x3400, 0x20a9, 0x0004, 0x4003,
+ 0x2098, 0x20a0, 0x3d00, 0x20e0, 0x080c, 0x47c6, 0x4104, 0xd794,
+ 0x0528, 0xb8b4, 0x20e0, 0xb8b8, 0x2060, 0x9c80, 0x0000, 0x2098,
+ 0x20a9, 0x0002, 0x4003, 0x9c80, 0x0003, 0x2098, 0x20a9, 0x0001,
+ 0x4005, 0x9c80, 0x0004, 0x2098, 0x3400, 0x20a9, 0x0002, 0x4003,
+ 0x2098, 0x20a0, 0x3d00, 0x20e0, 0x080c, 0x47b9, 0x9c80, 0x0026,
+ 0x2098, 0xb8b4, 0x20e0, 0x20a9, 0x0002, 0x4003, 0xd794, 0x0110,
+ 0x96b0, 0x000b, 0x96b0, 0x0005, 0x8108, 0x080c, 0x9f69, 0x0118,
+ 0x9186, 0x0800, 0x0040, 0xd78c, 0x0120, 0x9186, 0x0800, 0x0170,
+ 0x0018, 0x9186, 0x007e, 0x0150, 0xd794, 0x0118, 0x9686, 0x0020,
+ 0x0010, 0x9686, 0x0028, 0x0150, 0x0804, 0x4cb9, 0x86ff, 0x1120,
+ 0x7124, 0x810b, 0x0804, 0x33f2, 0x7033, 0x0001, 0x7122, 0x7024,
+ 0x9600, 0x7026, 0x772e, 0x2061, 0x18b6, 0x2c44, 0xa06b, 0x0000,
+ 0xa67a, 0x7034, 0xa072, 0x7028, 0xa076, 0xa28e, 0xa392, 0xa496,
+ 0xa59a, 0x080c, 0x1134, 0x7007, 0x0002, 0x701f, 0x4d60, 0x0005,
+ 0x7030, 0x9005, 0x1180, 0x7120, 0x7028, 0x20a0, 0x772c, 0x9036,
+ 0x7034, 0x20e8, 0x2061, 0x18b6, 0x2c44, 0xa28c, 0xa390, 0xa494,
+ 0xa598, 0x0804, 0x4cb9, 0x7124, 0x810b, 0x0804, 0x33f2, 0x2029,
+ 0x007e, 0x7984, 0x7a88, 0x7b8c, 0x7c98, 0x9184, 0xff00, 0x8007,
+ 0x90e2, 0x0020, 0x0a04, 0x3427, 0x9502, 0x0a04, 0x3427, 0x9184,
+ 0x00ff, 0x90e2, 0x0020, 0x0a04, 0x3427, 0x9502, 0x0a04, 0x3427,
+ 0x9284, 0xff00, 0x8007, 0x90e2, 0x0020, 0x0a04, 0x3427, 0x9502,
+ 0x0a04, 0x3427, 0x9284, 0x00ff, 0x90e2, 0x0020, 0x0a04, 0x3427,
+ 0x9502, 0x0a04, 0x3427, 0x9384, 0xff00, 0x8007, 0x90e2, 0x0020,
+ 0x0a04, 0x3427, 0x9502, 0x0a04, 0x3427, 0x9384, 0x00ff, 0x90e2,
+ 0x0020, 0x0a04, 0x3427, 0x9502, 0x0a04, 0x3427, 0x9484, 0xff00,
+ 0x8007, 0x90e2, 0x0020, 0x0a04, 0x3427, 0x9502, 0x0a04, 0x3427,
+ 0x9484, 0x00ff, 0x90e2, 0x0020, 0x0a04, 0x3427, 0x9502, 0x0a04,
+ 0x3427, 0x2061, 0x1963, 0x6102, 0x6206, 0x630a, 0x640e, 0x0804,
+ 0x33f2, 0x0006, 0x080c, 0x54db, 0xd0cc, 0x000e, 0x0005, 0x0006,
+ 0x080c, 0x54df, 0xd0bc, 0x000e, 0x0005, 0x6170, 0x7a84, 0x6300,
+ 0x82ff, 0x1118, 0x7986, 0x0804, 0x33f2, 0x83ff, 0x1904, 0x3427,
+ 0x2001, 0xfff0, 0x9200, 0x1a04, 0x3427, 0x2019, 0xffff, 0x6074,
+ 0x9302, 0x9200, 0x0a04, 0x3427, 0x7986, 0x6272, 0x0804, 0x33f2,
+ 0x080c, 0x54ef, 0x1904, 0x3424, 0x7c88, 0x7d84, 0x7e98, 0x7f8c,
+ 0x080c, 0x49b7, 0x0904, 0x3424, 0x900e, 0x901e, 0x7326, 0x7332,
+ 0xa860, 0x20e8, 0x7036, 0xa85c, 0x9080, 0x0003, 0x702a, 0x20a0,
+ 0x91d8, 0x1000, 0x2b5c, 0x8bff, 0x0178, 0x080c, 0x66c9, 0x0118,
+ 0x080c, 0x66d1, 0x1148, 0x20a9, 0x0001, 0xb814, 0x4004, 0xb810,
+ 0x4004, 0x4104, 0x9398, 0x0003, 0x8108, 0x9182, 0x0800, 0x0120,
+ 0x9386, 0x003c, 0x0170, 0x0c20, 0x83ff, 0x1148, 0x7224, 0x900e,
+ 0x2001, 0x0003, 0x080c, 0x847e, 0x2208, 0x0804, 0x33f2, 0x7033,
+ 0x0001, 0x7122, 0x7024, 0x9300, 0x7026, 0x2061, 0x18b6, 0x2c44,
+ 0xa06b, 0x0000, 0xa37a, 0x7028, 0xa076, 0x7034, 0xa072, 0xa48e,
+ 0xa592, 0xa696, 0xa79a, 0x080c, 0x1134, 0x7007, 0x0002, 0x701f,
+ 0x4e52, 0x0005, 0x7030, 0x9005, 0x1178, 0x7120, 0x7028, 0x20a0,
+ 0x901e, 0x7034, 0x20e8, 0x2061, 0x18b6, 0x2c44, 0xa48c, 0xa590,
+ 0xa694, 0xa798, 0x0804, 0x4e10, 0x7224, 0x900e, 0x2001, 0x0003,
+ 0x080c, 0x847e, 0x2208, 0x0804, 0x33f2, 0x00f6, 0x00e6, 0x080c,
+ 0x54ef, 0x2009, 0x0007, 0x1904, 0x4ee5, 0x2071, 0x189c, 0x745c,
+ 0x84ff, 0x2009, 0x000e, 0x1904, 0x4ee5, 0xac9c, 0xad98, 0xaea4,
+ 0xafa0, 0x0096, 0x080c, 0x1050, 0x2009, 0x0002, 0x0904, 0x4ee5,
+ 0x2900, 0x705e, 0x900e, 0x901e, 0x7356, 0x7362, 0xa860, 0x7066,
+ 0xa85c, 0x9080, 0x0003, 0x705a, 0x20a0, 0x91d8, 0x1000, 0x2b5c,
+ 0x8bff, 0x0178, 0x080c, 0x66c9, 0x0118, 0x080c, 0x66d1, 0x1148,
+ 0xb814, 0x20a9, 0x0001, 0x4004, 0xb810, 0x4004, 0x4104, 0x9398,
+ 0x0003, 0x8108, 0x9182, 0x0800, 0x0120, 0x9386, 0x003c, 0x01e8,
+ 0x0c20, 0x83ff, 0x11c0, 0x7254, 0x900e, 0x2001, 0x0003, 0x080c,
+ 0x847e, 0x2208, 0x009e, 0xa897, 0x4000, 0xa99a, 0x715c, 0x81ff,
+ 0x090c, 0x0df6, 0x2148, 0x080c, 0x1069, 0x9006, 0x705e, 0x918d,
+ 0x0001, 0x2008, 0x0418, 0x7063, 0x0001, 0x7152, 0x7054, 0x9300,
+ 0x7056, 0x2061, 0x18b7, 0x2c44, 0xa37a, 0x7058, 0xa076, 0x7064,
+ 0xa072, 0xa48e, 0xa592, 0xa696, 0xa79a, 0xa09f, 0x4ef1, 0x000e,
+ 0xa0a2, 0x080c, 0x1134, 0x9006, 0x0048, 0x009e, 0xa897, 0x4005,
+ 0xa99a, 0x900e, 0x9085, 0x0001, 0x2001, 0x0030, 0x00ee, 0x00fe,
+ 0x0005, 0x00f6, 0xa0a0, 0x904d, 0x090c, 0x0df6, 0x00e6, 0x2071,
+ 0x189c, 0xa06c, 0x908e, 0x0100, 0x0138, 0xa87b, 0x0030, 0xa883,
+ 0x0000, 0xa897, 0x4002, 0x00d8, 0x7060, 0x9005, 0x1158, 0x7150,
+ 0x7058, 0x20a0, 0x901e, 0x7064, 0x20e8, 0xa48c, 0xa590, 0xa694,
+ 0xa798, 0x0428, 0xa87b, 0x0000, 0xa883, 0x0000, 0xa897, 0x4000,
+ 0x7254, 0x900e, 0x2001, 0x0003, 0x080c, 0x847e, 0xaa9a, 0x715c,
+ 0x81ff, 0x090c, 0x0df6, 0x2148, 0x080c, 0x1069, 0x705f, 0x0000,
+ 0xa0a0, 0x2048, 0x0126, 0x2091, 0x8000, 0x080c, 0x6a22, 0x012e,
+ 0xa09f, 0x0000, 0xa0a3, 0x0000, 0x00ee, 0x00fe, 0x0005, 0x91d8,
+ 0x1000, 0x2b5c, 0x8bff, 0x0178, 0x080c, 0x66c9, 0x0118, 0x080c,
+ 0x66d1, 0x1148, 0xb814, 0x20a9, 0x0001, 0x4004, 0xb810, 0x4004,
+ 0x4104, 0x9398, 0x0003, 0x8108, 0x9182, 0x0800, 0x0120, 0x9386,
+ 0x003c, 0x0518, 0x0c20, 0x83ff, 0x11f0, 0x7154, 0x810c, 0xa99a,
+ 0xa897, 0x4000, 0x715c, 0x81ff, 0x090c, 0x0df6, 0x2148, 0x080c,
+ 0x1069, 0x9006, 0x705e, 0x918d, 0x0001, 0x2008, 0xa0a0, 0x2048,
+ 0x0126, 0x2091, 0x8000, 0x080c, 0x6a22, 0x012e, 0xa09f, 0x0000,
+ 0xa0a3, 0x0000, 0x0070, 0x7063, 0x0001, 0x7152, 0x7054, 0x9300,
+ 0x7056, 0xa37a, 0xa48e, 0xa592, 0xa696, 0xa79a, 0x080c, 0x1134,
+ 0x9006, 0x00ee, 0x0005, 0x0096, 0xa88c, 0x90be, 0x7000, 0x0148,
+ 0x90be, 0x7100, 0x0130, 0x90be, 0x7200, 0x0118, 0x009e, 0x0804,
+ 0x3427, 0xa884, 0xa988, 0x080c, 0x266d, 0x1518, 0x080c, 0x6343,
+ 0x1500, 0x7126, 0xbe12, 0xbd16, 0xae7c, 0x080c, 0x49b7, 0x01c8,
+ 0x080c, 0x49b7, 0x01b0, 0x009e, 0xa867, 0x0000, 0xa868, 0xc0fd,
+ 0xa86a, 0xa823, 0x0000, 0xa804, 0x2048, 0x080c, 0xbefa, 0x1120,
+ 0x2009, 0x0003, 0x0804, 0x3424, 0x7007, 0x0003, 0x701f, 0x4fbe,
+ 0x0005, 0x009e, 0x2009, 0x0002, 0x0804, 0x3424, 0x7124, 0x080c,
+ 0x3190, 0xa820, 0x9086, 0x8001, 0x1120, 0x2009, 0x0004, 0x0804,
+ 0x3424, 0x2900, 0x7022, 0xa804, 0x0096, 0x2048, 0x8906, 0x8006,
+ 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x009e, 0x9080, 0x0002,
+ 0x0076, 0x0006, 0x2098, 0x20a0, 0x27e0, 0x27e8, 0x20a9, 0x002a,
+ 0x080c, 0x0fb4, 0xaa6c, 0xab70, 0xac74, 0xad78, 0x2061, 0x18b6,
+ 0x2c44, 0xa06b, 0x0000, 0xae64, 0xaf8c, 0x97c6, 0x7000, 0x0118,
+ 0x97c6, 0x7100, 0x1148, 0x96c2, 0x0004, 0x0600, 0x2009, 0x0004,
+ 0x000e, 0x007e, 0x0804, 0x4a03, 0x97c6, 0x7200, 0x11b8, 0x96c2,
+ 0x0054, 0x02a0, 0x000e, 0x007e, 0x2061, 0x18b6, 0x2c44, 0xa076,
+ 0xa772, 0xa07b, 0x002a, 0xa28e, 0xa392, 0xa496, 0xa59a, 0x080c,
+ 0x1134, 0x7007, 0x0002, 0x701f, 0x501a, 0x0005, 0x000e, 0x007e,
+ 0x0804, 0x3427, 0x7020, 0x2048, 0xa804, 0x2048, 0xa804, 0x2048,
+ 0x8906, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080,
+ 0x0002, 0x2098, 0x20a0, 0x27e0, 0x27e8, 0x20a9, 0x002a, 0x080c,
+ 0x0fb4, 0x2100, 0x2238, 0x2061, 0x18b6, 0x2c44, 0xa28c, 0xa390,
+ 0xa494, 0xa598, 0x2009, 0x002a, 0x0804, 0x4a03, 0x81ff, 0x1904,
+ 0x3424, 0x798c, 0x2001, 0x1958, 0x918c, 0x8000, 0x2102, 0x080c,
+ 0x49ce, 0x0904, 0x3427, 0x080c, 0x66c9, 0x0120, 0x080c, 0x66d1,
+ 0x1904, 0x3427, 0x080c, 0x646a, 0x0904, 0x3424, 0x0126, 0x2091,
+ 0x8000, 0x080c, 0x6530, 0x012e, 0x0904, 0x3424, 0x2001, 0x1958,
+ 0x2004, 0xd0fc, 0x1904, 0x33f2, 0x0804, 0x4461, 0xa9a0, 0x2001,
+ 0x1958, 0x918c, 0x8000, 0xc18d, 0x2102, 0x080c, 0x49db, 0x01a0,
+ 0x080c, 0x66c9, 0x0118, 0x080c, 0x66d1, 0x1170, 0x080c, 0x646a,
+ 0x2009, 0x0002, 0x0128, 0x080c, 0x6530, 0x1170, 0x2009, 0x0003,
+ 0xa897, 0x4005, 0xa99a, 0x0010, 0xa897, 0x4006, 0x900e, 0x9085,
+ 0x0001, 0x2001, 0x0030, 0x0005, 0xa897, 0x4000, 0x2001, 0x1958,
+ 0x2004, 0xd0fc, 0x1128, 0x080c, 0x54e3, 0x0110, 0x9006, 0x0018,
+ 0x900e, 0x9085, 0x0001, 0x2001, 0x0000, 0x0005, 0x78a8, 0xd08c,
+ 0x1118, 0xd084, 0x0904, 0x43d6, 0x080c, 0x49ea, 0x0904, 0x3427,
+ 0x080c, 0x49b7, 0x1120, 0x2009, 0x0002, 0x0804, 0x3424, 0x080c,
+ 0x66c9, 0x0130, 0x908e, 0x0004, 0x0118, 0x908e, 0x0005, 0x15a0,
+ 0x78a8, 0xd08c, 0x0120, 0xb800, 0xc08c, 0xb802, 0x0028, 0x080c,
+ 0x54db, 0xd0b4, 0x0904, 0x4410, 0x7884, 0x908e, 0x007e, 0x0904,
+ 0x4410, 0x908e, 0x007f, 0x0904, 0x4410, 0x908e, 0x0080, 0x0904,
+ 0x4410, 0xb800, 0xd08c, 0x1904, 0x4410, 0xa867, 0x0000, 0xa868,
+ 0xc0fd, 0xa86a, 0x080c, 0xbf19, 0x1120, 0x2009, 0x0003, 0x0804,
+ 0x3424, 0x7007, 0x0003, 0x701f, 0x50e6, 0x0005, 0x080c, 0x49ea,
+ 0x0904, 0x3427, 0x0804, 0x4410, 0x080c, 0x31e9, 0x0108, 0x0005,
+ 0x2009, 0x1833, 0x210c, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804,
+ 0x3424, 0x080c, 0x54ef, 0x0120, 0x2009, 0x0007, 0x0804, 0x3424,
+ 0x080c, 0x66c1, 0x0120, 0x2009, 0x0008, 0x0804, 0x3424, 0xb89c,
+ 0xd0a4, 0x1118, 0xd0ac, 0x1904, 0x4410, 0x9006, 0xa866, 0xa832,
+ 0xa868, 0xc0fd, 0xa86a, 0x080c, 0xbf78, 0x1120, 0x2009, 0x0003,
+ 0x0804, 0x3424, 0x7007, 0x0003, 0x701f, 0x511f, 0x0005, 0xa830,
+ 0x9086, 0x0100, 0x1120, 0x2009, 0x0004, 0x0804, 0x542f, 0x080c,
+ 0x49ea, 0x0904, 0x3427, 0x0804, 0x50b8, 0x81ff, 0x2009, 0x0001,
+ 0x1904, 0x3424, 0x080c, 0x54ef, 0x2009, 0x0007, 0x1904, 0x3424,
+ 0x080c, 0x66c1, 0x0120, 0x2009, 0x0008, 0x0804, 0x3424, 0x080c,
+ 0x49ea, 0x0904, 0x3427, 0x080c, 0x66c9, 0x2009, 0x0009, 0x1904,
+ 0x3424, 0x080c, 0x49b7, 0x2009, 0x0002, 0x0904, 0x3424, 0x9006,
+ 0xa866, 0xa832, 0xa868, 0xc0fd, 0xa86a, 0x7988, 0xa95a, 0x9194,
+ 0xfd00, 0x918c, 0x00ff, 0x9006, 0x82ff, 0x1128, 0xc0ed, 0xa952,
+ 0x798c, 0xa956, 0x0038, 0x928e, 0x0100, 0x1904, 0x3427, 0xc0e5,
+ 0xa952, 0xa956, 0xa83e, 0x080c, 0xc1cb, 0x2009, 0x0003, 0x0904,
+ 0x3424, 0x7007, 0x0003, 0x701f, 0x5176, 0x0005, 0xa830, 0x9086,
+ 0x0100, 0x2009, 0x0004, 0x0904, 0x3424, 0x0804, 0x33f2, 0x7aa8,
+ 0x9284, 0xc000, 0x0148, 0xd2ec, 0x01a0, 0x080c, 0x54ef, 0x1188,
+ 0x2009, 0x0014, 0x0804, 0x3424, 0xd2dc, 0x1578, 0x81ff, 0x2009,
+ 0x0001, 0x1904, 0x3424, 0x080c, 0x54ef, 0x2009, 0x0007, 0x1904,
+ 0x3424, 0xd2f4, 0x0138, 0x9284, 0x5000, 0xc0d5, 0x080c, 0x54b5,
+ 0x0804, 0x33f2, 0xd2fc, 0x0160, 0x080c, 0x49ea, 0x0904, 0x3427,
+ 0x7984, 0x9284, 0x9000, 0xc0d5, 0x080c, 0x548a, 0x0804, 0x33f2,
+ 0x080c, 0x49ea, 0x0904, 0x3427, 0xb804, 0x9084, 0x00ff, 0x9086,
+ 0x0006, 0x2009, 0x0009, 0x1904, 0x5265, 0x080c, 0x49b7, 0x2009,
+ 0x0002, 0x0904, 0x5265, 0xa85c, 0x9080, 0x001b, 0xaf60, 0x2009,
+ 0x0008, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0x080c, 0x4a00, 0x701f,
+ 0x51d2, 0x0005, 0xa86c, 0x9086, 0x0500, 0x1138, 0xa870, 0x9005,
+ 0x1120, 0xa874, 0x9084, 0xff00, 0x0110, 0x1904, 0x3427, 0xa866,
+ 0xa832, 0xa868, 0xc0fd, 0xa86a, 0x080c, 0x49ea, 0x1110, 0x0804,
+ 0x3427, 0x2009, 0x0043, 0x080c, 0xc237, 0x2009, 0x0003, 0x0904,
+ 0x5265, 0x7007, 0x0003, 0x701f, 0x51f6, 0x0005, 0xa830, 0x9086,
+ 0x0100, 0x2009, 0x0004, 0x0904, 0x5265, 0x7984, 0x7aa8, 0x9284,
+ 0x1000, 0xc0d5, 0x080c, 0x548a, 0x0804, 0x33f2, 0x00c6, 0xaab0,
+ 0x9284, 0xc000, 0x0148, 0xd2ec, 0x0170, 0x080c, 0x54ef, 0x1158,
+ 0x2009, 0x0014, 0x0804, 0x5254, 0x2061, 0x1800, 0x080c, 0x54ef,
+ 0x2009, 0x0007, 0x15c8, 0xd2f4, 0x0130, 0x9284, 0x5000, 0xc0d5,
+ 0x080c, 0x54b5, 0x0058, 0xd2fc, 0x0180, 0x080c, 0x49e8, 0x0590,
+ 0xa998, 0x9284, 0x9000, 0xc0d5, 0x080c, 0x548a, 0xa87b, 0x0000,
+ 0xa883, 0x0000, 0xa897, 0x4000, 0x0438, 0x080c, 0x49e8, 0x0510,
+ 0x080c, 0x66c9, 0x2009, 0x0009, 0x11b8, 0xa8c4, 0x9086, 0x0500,
+ 0x11c8, 0xa8c8, 0x9005, 0x11b0, 0xa8cc, 0x9084, 0xff00, 0x1190,
+ 0x080c, 0x49e8, 0x1108, 0x0070, 0x2009, 0x004b, 0x080c, 0xc237,
+ 0x2009, 0x0003, 0x0108, 0x0078, 0x0431, 0x19c0, 0xa897, 0x4005,
+ 0xa99a, 0x0010, 0xa897, 0x4006, 0x900e, 0x9085, 0x0001, 0x2001,
+ 0x0030, 0x00ce, 0x0005, 0x9006, 0x0ce0, 0x7aa8, 0xd2dc, 0x0904,
+ 0x3424, 0x0016, 0x7984, 0x9284, 0x1000, 0xc0fd, 0x080c, 0x548a,
+ 0x001e, 0x1904, 0x3424, 0x0804, 0x33f2, 0x00f6, 0x2d78, 0xaab0,
+ 0x0021, 0x00fe, 0x0005, 0xaab0, 0xc2d5, 0xd2dc, 0x0150, 0x0016,
+ 0xa998, 0x9284, 0x1400, 0xc0fd, 0x080c, 0x548a, 0x001e, 0x9085,
+ 0x0001, 0x0005, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x3424,
+ 0x080c, 0x54ef, 0x0120, 0x2009, 0x0007, 0x0804, 0x3424, 0x7984,
+ 0x7ea8, 0x96b4, 0x00ff, 0x080c, 0x63a3, 0x1904, 0x3427, 0x9186,
+ 0x007f, 0x0138, 0x080c, 0x66c9, 0x0120, 0x2009, 0x0009, 0x0804,
+ 0x3424, 0x080c, 0x49b7, 0x1120, 0x2009, 0x0002, 0x0804, 0x3424,
+ 0xa867, 0x0000, 0xa868, 0xc0fd, 0xa86a, 0x2001, 0x0100, 0x8007,
+ 0xa80a, 0x080c, 0xbf33, 0x1120, 0x2009, 0x0003, 0x0804, 0x3424,
+ 0x7007, 0x0003, 0x701f, 0x52c5, 0x0005, 0xa808, 0x8007, 0x9086,
+ 0x0100, 0x1120, 0x2009, 0x0004, 0x0804, 0x3424, 0xa8e0, 0xa866,
+ 0xa810, 0x8007, 0x9084, 0x00ff, 0x800c, 0xa814, 0x8007, 0x9084,
+ 0x00ff, 0x8004, 0x9080, 0x0002, 0x9108, 0x8906, 0x8006, 0x8007,
+ 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, 0x0004, 0x7a8c, 0x7b88,
+ 0x7c9c, 0x7d98, 0x0804, 0x4a03, 0x080c, 0x49b7, 0x1120, 0x2009,
+ 0x0002, 0x0804, 0x3424, 0x7984, 0x9194, 0xff00, 0x918c, 0x00ff,
+ 0x8217, 0x82ff, 0x1118, 0x7023, 0x198e, 0x0040, 0x92c6, 0x0001,
+ 0x1118, 0x7023, 0x19a8, 0x0010, 0x0804, 0x3427, 0x2009, 0x001a,
0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0xa85c, 0x9080, 0x0019, 0xaf60,
- 0x0804, 0x4a04, 0x7884, 0x908a, 0x1000, 0x1a04, 0x343d, 0x0126,
- 0x2091, 0x8000, 0x8003, 0x800b, 0x810b, 0x9108, 0x00c6, 0x2061,
- 0x19d5, 0x614a, 0x00ce, 0x012e, 0x0804, 0x3408, 0x00c6, 0x080c,
- 0x717f, 0x1160, 0x080c, 0x747b, 0x080c, 0x5e30, 0x9085, 0x0001,
- 0x080c, 0x71c3, 0x080c, 0x709f, 0x080c, 0x0e02, 0x2061, 0x1800,
- 0x6030, 0xc09d, 0x6032, 0x080c, 0x5cef, 0x00ce, 0x0005, 0x00c6,
- 0x2001, 0x1800, 0x2004, 0x908e, 0x0000, 0x0904, 0x343a, 0x7884,
- 0x9005, 0x0188, 0x7888, 0x2061, 0x1976, 0x2c0c, 0x2062, 0x080c,
- 0x2a98, 0x01a0, 0x080c, 0x2aa0, 0x0188, 0x080c, 0x2aa8, 0x0170,
- 0x2162, 0x0804, 0x343d, 0x2061, 0x0100, 0x6038, 0x9086, 0x0007,
- 0x1118, 0x2009, 0x0001, 0x0010, 0x2009, 0x0000, 0x7884, 0x9086,
- 0x0002, 0x1568, 0x2061, 0x0100, 0x6028, 0xc09c, 0x602a, 0x0026,
- 0x2011, 0x0003, 0x080c, 0x990e, 0x2011, 0x0002, 0x080c, 0x9918,
- 0x002e, 0x080c, 0x9826, 0x0036, 0x901e, 0x080c, 0x989c, 0x003e,
- 0x60e3, 0x0000, 0x080c, 0xdb7a, 0x080c, 0xdb95, 0x9085, 0x0001,
- 0x080c, 0x71c3, 0x9006, 0x080c, 0x2b88, 0x2001, 0x1800, 0x2003,
- 0x0004, 0x2001, 0x1981, 0x2003, 0x0000, 0x6027, 0x0008, 0x00ce,
- 0x0804, 0x3408, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x343a,
- 0x080c, 0x54f0, 0x0120, 0x2009, 0x0007, 0x0804, 0x343a, 0x7984,
- 0x7ea8, 0x96b4, 0x00ff, 0x080c, 0x63a4, 0x1904, 0x343d, 0x9186,
- 0x007f, 0x0138, 0x080c, 0x66ca, 0x0120, 0x2009, 0x0009, 0x0804,
- 0x343a, 0x080c, 0x49b8, 0x1120, 0x2009, 0x0002, 0x0804, 0x343a,
- 0xa867, 0x0000, 0xa868, 0xc0fd, 0xa86a, 0x080c, 0xbf23, 0x1120,
- 0x2009, 0x0003, 0x0804, 0x343a, 0x7007, 0x0003, 0x701f, 0x5419,
- 0x0005, 0xa830, 0x9086, 0x0100, 0x1120, 0x2009, 0x0004, 0x0804,
- 0x343a, 0xa8e0, 0xa866, 0xa834, 0x8007, 0x800c, 0xa85c, 0x9080,
- 0x000c, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0xaf60, 0x0804, 0x4a04,
- 0xa898, 0x9086, 0x000d, 0x1904, 0x343a, 0x2021, 0x4005, 0x0126,
- 0x2091, 0x8000, 0x0e04, 0x543d, 0x0010, 0x012e, 0x0cc0, 0x7c36,
- 0x9486, 0x4000, 0x0118, 0x7833, 0x0011, 0x0010, 0x7833, 0x0010,
- 0x7883, 0x4005, 0xa998, 0x7986, 0xa9a4, 0x799a, 0xa9a8, 0x799e,
- 0x080c, 0x49f4, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084,
- 0x190c, 0x11f2, 0x7007, 0x0001, 0x2091, 0x5000, 0x700f, 0x0000,
- 0x012e, 0x0005, 0x0126, 0x2091, 0x8000, 0x00c6, 0x2061, 0x19d5,
- 0x7984, 0x615a, 0x6156, 0x605f, 0x0000, 0x6053, 0x0009, 0x7898,
- 0x6072, 0x789c, 0x606e, 0x7888, 0x606a, 0x788c, 0x6066, 0x2001,
- 0x19e5, 0x2044, 0x2001, 0x19ec, 0xa076, 0xa060, 0xa072, 0xa07b,
- 0x0001, 0xa07f, 0x0002, 0xa06b, 0x0000, 0xa09f, 0x0000, 0x00ce,
- 0x012e, 0x0804, 0x3408, 0x0126, 0x2091, 0x8000, 0x00b6, 0x00c6,
- 0x90e4, 0xc000, 0x0168, 0x0006, 0xd0d4, 0x0130, 0x0036, 0x2019,
- 0x0029, 0x080c, 0x31c4, 0x003e, 0x080c, 0xbd88, 0x000e, 0x1198,
- 0xd0e4, 0x0160, 0x9180, 0x1000, 0x2004, 0x905d, 0x0160, 0x080c,
- 0x5e4a, 0x080c, 0x9f54, 0x0110, 0xb817, 0x0000, 0x9006, 0x00ce,
- 0x00be, 0x012e, 0x0005, 0x9085, 0x0001, 0x0cc8, 0x0126, 0x2091,
- 0x8000, 0x0156, 0x2010, 0x900e, 0x20a9, 0x0800, 0x0016, 0x9180,
- 0x1000, 0x2004, 0x9005, 0x0188, 0x9186, 0x007e, 0x0170, 0x9186,
- 0x007f, 0x0158, 0x9186, 0x0080, 0x0140, 0x9186, 0x00ff, 0x0128,
- 0x0026, 0x2200, 0x080c, 0x548b, 0x002e, 0x001e, 0x8108, 0x1f04,
- 0x54be, 0x015e, 0x012e, 0x0005, 0x2001, 0x185c, 0x2004, 0x0005,
- 0x2001, 0x187b, 0x2004, 0x0005, 0x0006, 0x2001, 0x1810, 0x2004,
- 0xd0d4, 0x000e, 0x0005, 0x2001, 0x180e, 0x2004, 0xd0b4, 0x0005,
- 0x2001, 0x1800, 0x2004, 0x9086, 0x0003, 0x0005, 0x0016, 0x00e6,
- 0x2071, 0x189c, 0x7108, 0x910d, 0x710a, 0x00ee, 0x001e, 0x0005,
- 0x79a4, 0x81ff, 0x0904, 0x343d, 0x9182, 0x0081, 0x1a04, 0x343d,
- 0x810c, 0x0016, 0x080c, 0x49b8, 0x0170, 0x080c, 0x0f4b, 0x2100,
- 0x2238, 0x7d84, 0x7c88, 0x7b8c, 0x7a90, 0x001e, 0x080c, 0x4a01,
- 0x701f, 0x5520, 0x0005, 0x001e, 0x2009, 0x0002, 0x0804, 0x343a,
- 0x2079, 0x0000, 0x7d94, 0x7c98, 0x7ba8, 0x7aac, 0x79a4, 0x810c,
- 0x2061, 0x18b6, 0x2c44, 0xa770, 0xa074, 0x2071, 0x189c, 0x080c,
- 0x4a04, 0x701f, 0x5534, 0x0005, 0x2061, 0x18b6, 0x2c44, 0x0016,
- 0x0026, 0xa270, 0xa174, 0x080c, 0x0f53, 0x002e, 0x001e, 0x080c,
- 0x1000, 0x9006, 0xa802, 0xa806, 0x0804, 0x3408, 0x0126, 0x0156,
- 0x0136, 0x0146, 0x01c6, 0x01d6, 0x00c6, 0x00d6, 0x00e6, 0x00f6,
- 0x2061, 0x0100, 0x2069, 0x0200, 0x2071, 0x1800, 0x6044, 0xd0a4,
- 0x11e8, 0xd084, 0x0118, 0x080c, 0x56ef, 0x0068, 0xd08c, 0x0118,
- 0x080c, 0x55f8, 0x0040, 0xd094, 0x0118, 0x080c, 0x55c8, 0x0018,
- 0xd09c, 0x0108, 0x0099, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x01de,
- 0x01ce, 0x014e, 0x013e, 0x015e, 0x012e, 0x0005, 0x0016, 0x6128,
- 0xd19c, 0x1110, 0xc19d, 0x612a, 0x001e, 0x0c68, 0x0006, 0x7094,
- 0x9005, 0x000e, 0x0120, 0x7097, 0x0000, 0x708f, 0x0000, 0x624c,
- 0x9286, 0xf0f0, 0x1150, 0x6048, 0x9086, 0xf0f0, 0x0130, 0x624a,
- 0x6043, 0x0090, 0x6043, 0x0010, 0x0490, 0x9294, 0xff00, 0x9296,
- 0xf700, 0x0178, 0x7138, 0xd1a4, 0x1160, 0x6240, 0x9295, 0x0100,
- 0x6242, 0x9294, 0x0010, 0x0128, 0x2009, 0x00f7, 0x080c, 0x5dac,
- 0x00f0, 0x6040, 0x9084, 0x0010, 0x9085, 0x0140, 0x6042, 0x6043,
- 0x0000, 0x7083, 0x0000, 0x709f, 0x0001, 0x70c3, 0x0000, 0x70db,
- 0x0000, 0x2009, 0x1c80, 0x200b, 0x0000, 0x7093, 0x0000, 0x7087,
- 0x000f, 0x2009, 0x000f, 0x2011, 0x5c92, 0x080c, 0x82ec, 0x0005,
- 0x2001, 0x187d, 0x2004, 0xd08c, 0x0110, 0x705b, 0xffff, 0x7084,
- 0x9005, 0x1528, 0x2011, 0x5c92, 0x080c, 0x825a, 0x6040, 0x9094,
- 0x0010, 0x9285, 0x0020, 0x6042, 0x20a9, 0x00c8, 0x6044, 0xd08c,
- 0x1168, 0x1f04, 0x55de, 0x6242, 0x7097, 0x0000, 0x6040, 0x9094,
- 0x0010, 0x9285, 0x0080, 0x6042, 0x6242, 0x0048, 0x6242, 0x7097,
- 0x0000, 0x708b, 0x0000, 0x9006, 0x080c, 0x5e35, 0x0000, 0x0005,
- 0x7088, 0x908a, 0x0003, 0x1a0c, 0x0e02, 0x000b, 0x0005, 0x5602,
- 0x5653, 0x56ee, 0x00f6, 0x0016, 0x6900, 0x918c, 0x0800, 0x708b,
- 0x0001, 0x2001, 0x015d, 0x2003, 0x0000, 0x6803, 0x00fc, 0x20a9,
- 0x0004, 0x6800, 0x9084, 0x00fc, 0x0120, 0x1f04, 0x5611, 0x080c,
- 0x0e02, 0x68a0, 0x68a2, 0x689c, 0x689e, 0x6898, 0x689a, 0xa001,
- 0x918d, 0x1600, 0x6902, 0x001e, 0x6837, 0x0020, 0x080c, 0x5e11,
- 0x2079, 0x1c00, 0x7833, 0x1101, 0x7837, 0x0000, 0x20e1, 0x0001,
- 0x2099, 0x1805, 0x20e9, 0x0001, 0x20a1, 0x1c0e, 0x20a9, 0x0004,
- 0x4003, 0x080c, 0x9ddd, 0x20e1, 0x0001, 0x2099, 0x1c00, 0x20e9,
+ 0x080c, 0x4a00, 0x701f, 0x5315, 0x0005, 0x2001, 0x182d, 0x2003,
+ 0x0001, 0xa85c, 0x9080, 0x0019, 0x2098, 0xa860, 0x20e0, 0x20a9,
+ 0x001a, 0x7020, 0x20a0, 0x20e9, 0x0001, 0x4003, 0x0804, 0x33f2,
+ 0x080c, 0x49b7, 0x1120, 0x2009, 0x0002, 0x0804, 0x3424, 0x7984,
+ 0x9194, 0xff00, 0x918c, 0x00ff, 0x8217, 0x82ff, 0x1118, 0x2099,
+ 0x198e, 0x0040, 0x92c6, 0x0001, 0x1118, 0x2099, 0x19a8, 0x0010,
+ 0x0804, 0x3427, 0xa85c, 0x9080, 0x0019, 0x20a0, 0xa860, 0x20e8,
+ 0x20a9, 0x001a, 0x20e1, 0x0001, 0x4003, 0x2009, 0x001a, 0x7a8c,
+ 0x7b88, 0x7c9c, 0x7d98, 0xa85c, 0x9080, 0x0019, 0xaf60, 0x0804,
+ 0x4a03, 0x7884, 0x908a, 0x1000, 0x1a04, 0x3427, 0x0126, 0x2091,
+ 0x8000, 0x8003, 0x800b, 0x810b, 0x9108, 0x00c6, 0x2061, 0x19d5,
+ 0x614a, 0x00ce, 0x012e, 0x0804, 0x33f2, 0x00c6, 0x080c, 0x717e,
+ 0x1160, 0x080c, 0x747a, 0x080c, 0x5e2f, 0x9085, 0x0001, 0x080c,
+ 0x71c2, 0x080c, 0x709e, 0x080c, 0x0df6, 0x2061, 0x1800, 0x6030,
+ 0xc09d, 0x6032, 0x080c, 0x5cee, 0x00ce, 0x0005, 0x00c6, 0x2001,
+ 0x1800, 0x2004, 0x908e, 0x0000, 0x0904, 0x3424, 0x7884, 0x9005,
+ 0x0188, 0x7888, 0x2061, 0x1976, 0x2c0c, 0x2062, 0x080c, 0x2a7f,
+ 0x01a0, 0x080c, 0x2a87, 0x0188, 0x080c, 0x2a8f, 0x0170, 0x2162,
+ 0x0804, 0x3427, 0x2061, 0x0100, 0x6038, 0x9086, 0x0007, 0x1118,
+ 0x2009, 0x0001, 0x0010, 0x2009, 0x0000, 0x7884, 0x9086, 0x0002,
+ 0x1568, 0x2061, 0x0100, 0x6028, 0xc09c, 0x602a, 0x0026, 0x2011,
+ 0x0003, 0x080c, 0x9923, 0x2011, 0x0002, 0x080c, 0x992d, 0x002e,
+ 0x080c, 0x983b, 0x0036, 0x901e, 0x080c, 0x98b1, 0x003e, 0x60e3,
+ 0x0000, 0x080c, 0xdbdb, 0x080c, 0xdbf6, 0x9085, 0x0001, 0x080c,
+ 0x71c2, 0x9006, 0x080c, 0x2b6f, 0x2001, 0x1800, 0x2003, 0x0004,
+ 0x2001, 0x1982, 0x2003, 0x0000, 0x6027, 0x0008, 0x00ce, 0x0804,
+ 0x33f2, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x3424, 0x080c,
+ 0x54ef, 0x0120, 0x2009, 0x0007, 0x0804, 0x3424, 0x7984, 0x7ea8,
+ 0x96b4, 0x00ff, 0x080c, 0x63a3, 0x1904, 0x3427, 0x9186, 0x007f,
+ 0x0138, 0x080c, 0x66c9, 0x0120, 0x2009, 0x0009, 0x0804, 0x3424,
+ 0x080c, 0x49b7, 0x1120, 0x2009, 0x0002, 0x0804, 0x3424, 0xa867,
+ 0x0000, 0xa868, 0xc0fd, 0xa86a, 0x080c, 0xbf36, 0x1120, 0x2009,
+ 0x0003, 0x0804, 0x3424, 0x7007, 0x0003, 0x701f, 0x5418, 0x0005,
+ 0xa830, 0x9086, 0x0100, 0x1120, 0x2009, 0x0004, 0x0804, 0x3424,
+ 0xa8e0, 0xa866, 0xa834, 0x8007, 0x800c, 0xa85c, 0x9080, 0x000c,
+ 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0xaf60, 0x0804, 0x4a03, 0xa898,
+ 0x9086, 0x000d, 0x1904, 0x3424, 0x2021, 0x4005, 0x0126, 0x2091,
+ 0x8000, 0x0e04, 0x543c, 0x0010, 0x012e, 0x0cc0, 0x7c36, 0x9486,
+ 0x4000, 0x0118, 0x7833, 0x0011, 0x0010, 0x7833, 0x0010, 0x7883,
+ 0x4005, 0xa998, 0x7986, 0xa9a4, 0x799a, 0xa9a8, 0x799e, 0x080c,
+ 0x49f3, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c,
+ 0x11e6, 0x7007, 0x0001, 0x2091, 0x5000, 0x700f, 0x0000, 0x012e,
+ 0x0005, 0x0126, 0x2091, 0x8000, 0x00c6, 0x2061, 0x19d5, 0x7984,
+ 0x615a, 0x6156, 0x605f, 0x0000, 0x6053, 0x0009, 0x7898, 0x6072,
+ 0x789c, 0x606e, 0x7888, 0x606a, 0x788c, 0x6066, 0x2001, 0x19e5,
+ 0x2044, 0x2001, 0x19ec, 0xa076, 0xa060, 0xa072, 0xa07b, 0x0001,
+ 0xa07f, 0x0002, 0xa06b, 0x0000, 0xa09f, 0x0000, 0x00ce, 0x012e,
+ 0x0804, 0x33f2, 0x0126, 0x2091, 0x8000, 0x00b6, 0x00c6, 0x90e4,
+ 0xc000, 0x0168, 0x0006, 0xd0d4, 0x0130, 0x0036, 0x2019, 0x0029,
+ 0x080c, 0x31ae, 0x003e, 0x080c, 0xbd9b, 0x000e, 0x1198, 0xd0e4,
+ 0x0160, 0x9180, 0x1000, 0x2004, 0x905d, 0x0160, 0x080c, 0x5e49,
+ 0x080c, 0x9f69, 0x0110, 0xb817, 0x0000, 0x9006, 0x00ce, 0x00be,
+ 0x012e, 0x0005, 0x9085, 0x0001, 0x0cc8, 0x0126, 0x2091, 0x8000,
+ 0x0156, 0x2010, 0x900e, 0x20a9, 0x0800, 0x0016, 0x9180, 0x1000,
+ 0x2004, 0x9005, 0x0188, 0x9186, 0x007e, 0x0170, 0x9186, 0x007f,
+ 0x0158, 0x9186, 0x0080, 0x0140, 0x9186, 0x00ff, 0x0128, 0x0026,
+ 0x2200, 0x080c, 0x548a, 0x002e, 0x001e, 0x8108, 0x1f04, 0x54bd,
+ 0x015e, 0x012e, 0x0005, 0x2001, 0x185c, 0x2004, 0x0005, 0x2001,
+ 0x187b, 0x2004, 0x0005, 0x0006, 0x2001, 0x1810, 0x2004, 0xd0d4,
+ 0x000e, 0x0005, 0x2001, 0x180e, 0x2004, 0xd0b4, 0x0005, 0x2001,
+ 0x1800, 0x2004, 0x9086, 0x0003, 0x0005, 0x0016, 0x00e6, 0x2071,
+ 0x189c, 0x7108, 0x910d, 0x710a, 0x00ee, 0x001e, 0x0005, 0x79a4,
+ 0x81ff, 0x0904, 0x3427, 0x9182, 0x0081, 0x1a04, 0x3427, 0x810c,
+ 0x0016, 0x080c, 0x49b7, 0x0170, 0x080c, 0x0f3f, 0x2100, 0x2238,
+ 0x7d84, 0x7c88, 0x7b8c, 0x7a90, 0x001e, 0x080c, 0x4a00, 0x701f,
+ 0x551f, 0x0005, 0x001e, 0x2009, 0x0002, 0x0804, 0x3424, 0x2079,
+ 0x0000, 0x7d94, 0x7c98, 0x7ba8, 0x7aac, 0x79a4, 0x810c, 0x2061,
+ 0x18b6, 0x2c44, 0xa770, 0xa074, 0x2071, 0x189c, 0x080c, 0x4a03,
+ 0x701f, 0x5533, 0x0005, 0x2061, 0x18b6, 0x2c44, 0x0016, 0x0026,
+ 0xa270, 0xa174, 0x080c, 0x0f47, 0x002e, 0x001e, 0x080c, 0x0ff4,
+ 0x9006, 0xa802, 0xa806, 0x0804, 0x33f2, 0x0126, 0x0156, 0x0136,
+ 0x0146, 0x01c6, 0x01d6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x2061,
+ 0x0100, 0x2069, 0x0200, 0x2071, 0x1800, 0x6044, 0xd0a4, 0x11e8,
+ 0xd084, 0x0118, 0x080c, 0x56ee, 0x0068, 0xd08c, 0x0118, 0x080c,
+ 0x55f7, 0x0040, 0xd094, 0x0118, 0x080c, 0x55c7, 0x0018, 0xd09c,
+ 0x0108, 0x0099, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x01de, 0x01ce,
+ 0x014e, 0x013e, 0x015e, 0x012e, 0x0005, 0x0016, 0x6128, 0xd19c,
+ 0x1110, 0xc19d, 0x612a, 0x001e, 0x0c68, 0x0006, 0x7094, 0x9005,
+ 0x000e, 0x0120, 0x7097, 0x0000, 0x708f, 0x0000, 0x624c, 0x9286,
+ 0xf0f0, 0x1150, 0x6048, 0x9086, 0xf0f0, 0x0130, 0x624a, 0x6043,
+ 0x0090, 0x6043, 0x0010, 0x0490, 0x9294, 0xff00, 0x9296, 0xf700,
+ 0x0178, 0x7138, 0xd1a4, 0x1160, 0x6240, 0x9295, 0x0100, 0x6242,
+ 0x9294, 0x0010, 0x0128, 0x2009, 0x00f7, 0x080c, 0x5dab, 0x00f0,
+ 0x6040, 0x9084, 0x0010, 0x9085, 0x0140, 0x6042, 0x6043, 0x0000,
+ 0x7083, 0x0000, 0x709f, 0x0001, 0x70c3, 0x0000, 0x70db, 0x0000,
+ 0x2009, 0x1c80, 0x200b, 0x0000, 0x7093, 0x0000, 0x7087, 0x000f,
+ 0x2009, 0x000f, 0x2011, 0x5c91, 0x080c, 0x82eb, 0x0005, 0x2001,
+ 0x187d, 0x2004, 0xd08c, 0x0110, 0x705b, 0xffff, 0x7084, 0x9005,
+ 0x1528, 0x2011, 0x5c91, 0x080c, 0x8259, 0x6040, 0x9094, 0x0010,
+ 0x9285, 0x0020, 0x6042, 0x20a9, 0x00c8, 0x6044, 0xd08c, 0x1168,
+ 0x1f04, 0x55dd, 0x6242, 0x7097, 0x0000, 0x6040, 0x9094, 0x0010,
+ 0x9285, 0x0080, 0x6042, 0x6242, 0x0048, 0x6242, 0x7097, 0x0000,
+ 0x708b, 0x0000, 0x9006, 0x080c, 0x5e34, 0x0000, 0x0005, 0x7088,
+ 0x908a, 0x0003, 0x1a0c, 0x0df6, 0x000b, 0x0005, 0x5601, 0x5652,
+ 0x56ed, 0x00f6, 0x0016, 0x6900, 0x918c, 0x0800, 0x708b, 0x0001,
+ 0x2001, 0x015d, 0x2003, 0x0000, 0x6803, 0x00fc, 0x20a9, 0x0004,
+ 0x6800, 0x9084, 0x00fc, 0x0120, 0x1f04, 0x5610, 0x080c, 0x0df6,
+ 0x68a0, 0x68a2, 0x689c, 0x689e, 0x6898, 0x689a, 0xa001, 0x918d,
+ 0x1600, 0x6902, 0x001e, 0x6837, 0x0020, 0x080c, 0x5e10, 0x2079,
+ 0x1c00, 0x7833, 0x1101, 0x7837, 0x0000, 0x20e1, 0x0001, 0x2099,
+ 0x1805, 0x20e9, 0x0001, 0x20a1, 0x1c0e, 0x20a9, 0x0004, 0x4003,
+ 0x080c, 0x9df2, 0x20e1, 0x0001, 0x2099, 0x1c00, 0x20e9, 0x0000,
+ 0x20a1, 0x0240, 0x20a9, 0x0014, 0x4003, 0x60c3, 0x000c, 0x600f,
+ 0x0000, 0x080c, 0x5cc2, 0x00fe, 0x9006, 0x708e, 0x6043, 0x0008,
+ 0x6042, 0x0005, 0x00f6, 0x708c, 0x708f, 0x0000, 0x9025, 0x0904,
+ 0x56ca, 0x6020, 0xd0b4, 0x1904, 0x56c8, 0x719c, 0x81ff, 0x0904,
+ 0x56b6, 0x9486, 0x000c, 0x1904, 0x56c3, 0x9480, 0x0018, 0x8004,
+ 0x20a8, 0x080c, 0x5e09, 0x2011, 0x0260, 0x2019, 0x1c00, 0x220c,
+ 0x2304, 0x9106, 0x11e8, 0x8210, 0x8318, 0x1f04, 0x566f, 0x6043,
+ 0x0004, 0x2061, 0x0140, 0x605b, 0xbc94, 0x605f, 0xf0f0, 0x2061,
+ 0x0100, 0x6043, 0x0006, 0x708b, 0x0002, 0x7097, 0x0002, 0x2009,
+ 0x07d0, 0x2011, 0x5c98, 0x080c, 0x82eb, 0x080c, 0x5e10, 0x04c0,
+ 0x080c, 0x5e09, 0x2079, 0x0260, 0x7930, 0x918e, 0x1101, 0x1558,
+ 0x7834, 0x9005, 0x1540, 0x7900, 0x918c, 0x00ff, 0x1118, 0x7804,
+ 0x9005, 0x0190, 0x080c, 0x5e09, 0x2011, 0x026e, 0x2019, 0x1805,
+ 0x20a9, 0x0004, 0x220c, 0x2304, 0x9102, 0x0230, 0x11a0, 0x8210,
+ 0x8318, 0x1f04, 0x56aa, 0x0078, 0x709f, 0x0000, 0x080c, 0x5e09,
+ 0x20e1, 0x0000, 0x2099, 0x0260, 0x20e9, 0x0001, 0x20a1, 0x1c00,
+ 0x20a9, 0x0014, 0x4003, 0x6043, 0x0008, 0x6043, 0x0000, 0x0010,
+ 0x00fe, 0x0005, 0x6040, 0x9085, 0x0100, 0x6042, 0x6020, 0xd0b4,
+ 0x1db8, 0x080c, 0x9df2, 0x20e1, 0x0001, 0x2099, 0x1c00, 0x20e9,
0x0000, 0x20a1, 0x0240, 0x20a9, 0x0014, 0x4003, 0x60c3, 0x000c,
- 0x600f, 0x0000, 0x080c, 0x5cc3, 0x00fe, 0x9006, 0x708e, 0x6043,
- 0x0008, 0x6042, 0x0005, 0x00f6, 0x708c, 0x708f, 0x0000, 0x9025,
- 0x0904, 0x56cb, 0x6020, 0xd0b4, 0x1904, 0x56c9, 0x719c, 0x81ff,
- 0x0904, 0x56b7, 0x9486, 0x000c, 0x1904, 0x56c4, 0x9480, 0x0018,
- 0x8004, 0x20a8, 0x080c, 0x5e0a, 0x2011, 0x0260, 0x2019, 0x1c00,
- 0x220c, 0x2304, 0x9106, 0x11e8, 0x8210, 0x8318, 0x1f04, 0x5670,
- 0x6043, 0x0004, 0x2061, 0x0140, 0x605b, 0xbc94, 0x605f, 0xf0f0,
- 0x2061, 0x0100, 0x6043, 0x0006, 0x708b, 0x0002, 0x7097, 0x0002,
- 0x2009, 0x07d0, 0x2011, 0x5c99, 0x080c, 0x82ec, 0x080c, 0x5e11,
- 0x04c0, 0x080c, 0x5e0a, 0x2079, 0x0260, 0x7930, 0x918e, 0x1101,
- 0x1558, 0x7834, 0x9005, 0x1540, 0x7900, 0x918c, 0x00ff, 0x1118,
- 0x7804, 0x9005, 0x0190, 0x080c, 0x5e0a, 0x2011, 0x026e, 0x2019,
- 0x1805, 0x20a9, 0x0004, 0x220c, 0x2304, 0x9102, 0x0230, 0x11a0,
- 0x8210, 0x8318, 0x1f04, 0x56ab, 0x0078, 0x709f, 0x0000, 0x080c,
- 0x5e0a, 0x20e1, 0x0000, 0x2099, 0x0260, 0x20e9, 0x0001, 0x20a1,
- 0x1c00, 0x20a9, 0x0014, 0x4003, 0x6043, 0x0008, 0x6043, 0x0000,
- 0x0010, 0x00fe, 0x0005, 0x6040, 0x9085, 0x0100, 0x6042, 0x6020,
- 0xd0b4, 0x1db8, 0x080c, 0x9ddd, 0x20e1, 0x0001, 0x2099, 0x1c00,
- 0x20e9, 0x0000, 0x20a1, 0x0240, 0x20a9, 0x0014, 0x4003, 0x60c3,
- 0x000c, 0x2011, 0x19cc, 0x2013, 0x0000, 0x708f, 0x0000, 0x60a3,
- 0x0056, 0x60a7, 0x9575, 0x080c, 0x95fc, 0x08d8, 0x0005, 0x7094,
- 0x908a, 0x001d, 0x1a0c, 0x0e02, 0x000b, 0x0005, 0x5720, 0x5733,
- 0x575c, 0x577c, 0x57a2, 0x57d1, 0x57f7, 0x582f, 0x5855, 0x5883,
- 0x58be, 0x58f6, 0x5914, 0x593f, 0x5961, 0x597c, 0x5986, 0x59ba,
- 0x59e0, 0x5a0f, 0x5a35, 0x5a6d, 0x5ab1, 0x5aee, 0x5b0f, 0x5b68,
- 0x5b8a, 0x5bb8, 0x5bb8, 0x00c6, 0x2061, 0x1800, 0x6003, 0x0007,
- 0x2061, 0x0100, 0x6004, 0x9084, 0xfff9, 0x6006, 0x00ce, 0x0005,
- 0x2061, 0x0140, 0x605b, 0xbc94, 0x605f, 0xf0f0, 0x2061, 0x0100,
- 0x6043, 0x0002, 0x7097, 0x0001, 0x2009, 0x07d0, 0x2011, 0x5c99,
- 0x080c, 0x82ec, 0x0005, 0x00f6, 0x708c, 0x9086, 0x0014, 0x1510,
- 0x6042, 0x6020, 0xd0b4, 0x11f0, 0x080c, 0x5e0a, 0x2079, 0x0260,
- 0x7a30, 0x9296, 0x1102, 0x11a0, 0x7834, 0x9005, 0x1188, 0x7a38,
- 0xd2fc, 0x0128, 0x70c0, 0x9005, 0x1110, 0x70c3, 0x0001, 0x2011,
- 0x5c99, 0x080c, 0x825a, 0x7097, 0x0010, 0x080c, 0x5986, 0x0010,
- 0x708f, 0x0000, 0x00fe, 0x0005, 0x00f6, 0x7097, 0x0003, 0x6043,
- 0x0004, 0x2011, 0x5c99, 0x080c, 0x825a, 0x080c, 0x5d8e, 0x2079,
- 0x0240, 0x7833, 0x1102, 0x7837, 0x0000, 0x20a9, 0x0008, 0x9f88,
- 0x000e, 0x200b, 0x0000, 0x8108, 0x1f04, 0x5771, 0x60c3, 0x0014,
- 0x080c, 0x5cc3, 0x00fe, 0x0005, 0x00f6, 0x708c, 0x9005, 0x0500,
- 0x2011, 0x5c99, 0x080c, 0x825a, 0x9086, 0x0014, 0x11b8, 0x080c,
- 0x5e0a, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1102, 0x1178, 0x7834,
- 0x9005, 0x1160, 0x7a38, 0xd2fc, 0x0128, 0x70c0, 0x9005, 0x1110,
- 0x70c3, 0x0001, 0x7097, 0x0004, 0x0029, 0x0010, 0x080c, 0x5de6,
- 0x00fe, 0x0005, 0x00f6, 0x7097, 0x0005, 0x080c, 0x5d8e, 0x2079,
- 0x0240, 0x7833, 0x1103, 0x7837, 0x0000, 0x080c, 0x5e0a, 0x080c,
- 0x5ded, 0x1170, 0x7080, 0x9005, 0x1158, 0x7158, 0x9186, 0xffff,
- 0x0138, 0x2011, 0x0008, 0x080c, 0x5c46, 0x0168, 0x080c, 0x5dc3,
- 0x20a9, 0x0008, 0x20e1, 0x0000, 0x2099, 0x026e, 0x20e9, 0x0000,
- 0x20a1, 0x024e, 0x4003, 0x60c3, 0x0014, 0x080c, 0x5cc3, 0x00fe,
- 0x0005, 0x00f6, 0x708c, 0x9005, 0x0500, 0x2011, 0x5c99, 0x080c,
- 0x825a, 0x9086, 0x0014, 0x11b8, 0x080c, 0x5e0a, 0x2079, 0x0260,
+ 0x2011, 0x19cc, 0x2013, 0x0000, 0x708f, 0x0000, 0x60a3, 0x0056,
+ 0x60a7, 0x9575, 0x080c, 0x9611, 0x08d8, 0x0005, 0x7094, 0x908a,
+ 0x001d, 0x1a0c, 0x0df6, 0x000b, 0x0005, 0x571f, 0x5732, 0x575b,
+ 0x577b, 0x57a1, 0x57d0, 0x57f6, 0x582e, 0x5854, 0x5882, 0x58bd,
+ 0x58f5, 0x5913, 0x593e, 0x5960, 0x597b, 0x5985, 0x59b9, 0x59df,
+ 0x5a0e, 0x5a34, 0x5a6c, 0x5ab0, 0x5aed, 0x5b0e, 0x5b67, 0x5b89,
+ 0x5bb7, 0x5bb7, 0x00c6, 0x2061, 0x1800, 0x6003, 0x0007, 0x2061,
+ 0x0100, 0x6004, 0x9084, 0xfff9, 0x6006, 0x00ce, 0x0005, 0x2061,
+ 0x0140, 0x605b, 0xbc94, 0x605f, 0xf0f0, 0x2061, 0x0100, 0x6043,
+ 0x0002, 0x7097, 0x0001, 0x2009, 0x07d0, 0x2011, 0x5c98, 0x080c,
+ 0x82eb, 0x0005, 0x00f6, 0x708c, 0x9086, 0x0014, 0x1510, 0x6042,
+ 0x6020, 0xd0b4, 0x11f0, 0x080c, 0x5e09, 0x2079, 0x0260, 0x7a30,
+ 0x9296, 0x1102, 0x11a0, 0x7834, 0x9005, 0x1188, 0x7a38, 0xd2fc,
+ 0x0128, 0x70c0, 0x9005, 0x1110, 0x70c3, 0x0001, 0x2011, 0x5c98,
+ 0x080c, 0x8259, 0x7097, 0x0010, 0x080c, 0x5985, 0x0010, 0x708f,
+ 0x0000, 0x00fe, 0x0005, 0x00f6, 0x7097, 0x0003, 0x6043, 0x0004,
+ 0x2011, 0x5c98, 0x080c, 0x8259, 0x080c, 0x5d8d, 0x2079, 0x0240,
+ 0x7833, 0x1102, 0x7837, 0x0000, 0x20a9, 0x0008, 0x9f88, 0x000e,
+ 0x200b, 0x0000, 0x8108, 0x1f04, 0x5770, 0x60c3, 0x0014, 0x080c,
+ 0x5cc2, 0x00fe, 0x0005, 0x00f6, 0x708c, 0x9005, 0x0500, 0x2011,
+ 0x5c98, 0x080c, 0x8259, 0x9086, 0x0014, 0x11b8, 0x080c, 0x5e09,
+ 0x2079, 0x0260, 0x7a30, 0x9296, 0x1102, 0x1178, 0x7834, 0x9005,
+ 0x1160, 0x7a38, 0xd2fc, 0x0128, 0x70c0, 0x9005, 0x1110, 0x70c3,
+ 0x0001, 0x7097, 0x0004, 0x0029, 0x0010, 0x080c, 0x5de5, 0x00fe,
+ 0x0005, 0x00f6, 0x7097, 0x0005, 0x080c, 0x5d8d, 0x2079, 0x0240,
+ 0x7833, 0x1103, 0x7837, 0x0000, 0x080c, 0x5e09, 0x080c, 0x5dec,
+ 0x1170, 0x7080, 0x9005, 0x1158, 0x7158, 0x9186, 0xffff, 0x0138,
+ 0x2011, 0x0008, 0x080c, 0x5c45, 0x0168, 0x080c, 0x5dc2, 0x20a9,
+ 0x0008, 0x20e1, 0x0000, 0x2099, 0x026e, 0x20e9, 0x0000, 0x20a1,
+ 0x024e, 0x4003, 0x60c3, 0x0014, 0x080c, 0x5cc2, 0x00fe, 0x0005,
+ 0x00f6, 0x708c, 0x9005, 0x0500, 0x2011, 0x5c98, 0x080c, 0x8259,
+ 0x9086, 0x0014, 0x11b8, 0x080c, 0x5e09, 0x2079, 0x0260, 0x7a30,
+ 0x9296, 0x1103, 0x1178, 0x7834, 0x9005, 0x1160, 0x7a38, 0xd2fc,
+ 0x0128, 0x70c0, 0x9005, 0x1110, 0x70c3, 0x0001, 0x7097, 0x0006,
+ 0x0029, 0x0010, 0x080c, 0x5de5, 0x00fe, 0x0005, 0x00f6, 0x7097,
+ 0x0007, 0x080c, 0x5d8d, 0x2079, 0x0240, 0x7833, 0x1104, 0x7837,
+ 0x0000, 0x080c, 0x5e09, 0x080c, 0x5dec, 0x11b8, 0x7080, 0x9005,
+ 0x11a0, 0x7160, 0x9186, 0xffff, 0x0180, 0x9180, 0x31f3, 0x200d,
+ 0x918c, 0xff00, 0x810f, 0x2011, 0x0008, 0x080c, 0x5c45, 0x0180,
+ 0x080c, 0x4dd7, 0x0110, 0x080c, 0x26d6, 0x20a9, 0x0008, 0x20e1,
+ 0x0000, 0x2099, 0x026e, 0x20e9, 0x0000, 0x20a1, 0x024e, 0x4003,
+ 0x60c3, 0x0014, 0x080c, 0x5cc2, 0x00fe, 0x0005, 0x00f6, 0x708c,
+ 0x9005, 0x0500, 0x2011, 0x5c98, 0x080c, 0x8259, 0x9086, 0x0014,
+ 0x11b8, 0x080c, 0x5e09, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1104,
+ 0x1178, 0x7834, 0x9005, 0x1160, 0x7a38, 0xd2fc, 0x0128, 0x70c0,
+ 0x9005, 0x1110, 0x70c3, 0x0001, 0x7097, 0x0008, 0x0029, 0x0010,
+ 0x080c, 0x5de5, 0x00fe, 0x0005, 0x00f6, 0x7097, 0x0009, 0x080c,
+ 0x5d8d, 0x2079, 0x0240, 0x7833, 0x1105, 0x7837, 0x0100, 0x080c,
+ 0x5dec, 0x1150, 0x7080, 0x9005, 0x1138, 0x080c, 0x5bb8, 0x1188,
+ 0x9085, 0x0001, 0x080c, 0x26d6, 0x20a9, 0x0008, 0x080c, 0x5e09,
+ 0x20e1, 0x0000, 0x2099, 0x026e, 0x20e9, 0x0000, 0x20a1, 0x024e,
+ 0x4003, 0x60c3, 0x0014, 0x080c, 0x5cc2, 0x0010, 0x080c, 0x5712,
+ 0x00fe, 0x0005, 0x00f6, 0x708c, 0x9005, 0x05a8, 0x2011, 0x5c98,
+ 0x080c, 0x8259, 0x9086, 0x0014, 0x1560, 0x080c, 0x5e09, 0x2079,
+ 0x0260, 0x7a30, 0x9296, 0x1105, 0x1520, 0x7834, 0x9084, 0x0100,
+ 0x2011, 0x0100, 0x921e, 0x1160, 0x7a38, 0xd2fc, 0x0128, 0x70c0,
+ 0x9005, 0x1110, 0x70c3, 0x0001, 0x7097, 0x000a, 0x00b1, 0x0098,
+ 0x9005, 0x1178, 0x7a38, 0xd2fc, 0x0128, 0x70c0, 0x9005, 0x1110,
+ 0x70c3, 0x0001, 0x7093, 0x0000, 0x7097, 0x000e, 0x080c, 0x5960,
+ 0x0010, 0x080c, 0x5de5, 0x00fe, 0x0005, 0x00f6, 0x7097, 0x000b,
+ 0x2011, 0x1c0e, 0x20e9, 0x0001, 0x22a0, 0x20a9, 0x0040, 0x2019,
+ 0xffff, 0x4304, 0x080c, 0x5d8d, 0x2079, 0x0240, 0x7833, 0x1106,
+ 0x7837, 0x0000, 0x080c, 0x5dec, 0x0118, 0x2013, 0x0000, 0x0020,
+ 0x705c, 0x9085, 0x0100, 0x2012, 0x20a9, 0x0040, 0x2009, 0x024e,
+ 0x2011, 0x1c0e, 0x220e, 0x8210, 0x8108, 0x9186, 0x0260, 0x1128,
+ 0x6810, 0x8000, 0x6812, 0x2009, 0x0240, 0x1f04, 0x58e2, 0x60c3,
+ 0x0084, 0x080c, 0x5cc2, 0x00fe, 0x0005, 0x00f6, 0x708c, 0x9005,
+ 0x01c0, 0x2011, 0x5c98, 0x080c, 0x8259, 0x9086, 0x0084, 0x1178,
+ 0x080c, 0x5e09, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1106, 0x1138,
+ 0x7834, 0x9005, 0x1120, 0x7097, 0x000c, 0x0029, 0x0010, 0x080c,
+ 0x5de5, 0x00fe, 0x0005, 0x00f6, 0x7097, 0x000d, 0x080c, 0x5d8d,
+ 0x2079, 0x0240, 0x7833, 0x1107, 0x7837, 0x0000, 0x080c, 0x5e09,
+ 0x20a9, 0x0040, 0x2011, 0x026e, 0x2009, 0x024e, 0x220e, 0x8210,
+ 0x8108, 0x9186, 0x0260, 0x1150, 0x6810, 0x8000, 0x6812, 0x2009,
+ 0x0240, 0x6814, 0x8000, 0x6816, 0x2011, 0x0260, 0x1f04, 0x5926,
+ 0x60c3, 0x0084, 0x080c, 0x5cc2, 0x00fe, 0x0005, 0x00f6, 0x708c,
+ 0x9005, 0x01e0, 0x2011, 0x5c98, 0x080c, 0x8259, 0x9086, 0x0084,
+ 0x1198, 0x080c, 0x5e09, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1107,
+ 0x1158, 0x7834, 0x9005, 0x1140, 0x7093, 0x0001, 0x080c, 0x5d5f,
+ 0x7097, 0x000e, 0x0029, 0x0010, 0x080c, 0x5de5, 0x00fe, 0x0005,
+ 0x918d, 0x0001, 0x080c, 0x5e34, 0x7097, 0x000f, 0x708f, 0x0000,
+ 0x2061, 0x0140, 0x605b, 0xbc85, 0x605f, 0xb5b5, 0x2061, 0x0100,
+ 0x6043, 0x0005, 0x6043, 0x0004, 0x2009, 0x07d0, 0x2011, 0x5c98,
+ 0x080c, 0x824d, 0x0005, 0x708c, 0x9005, 0x0130, 0x2011, 0x5c98,
+ 0x080c, 0x8259, 0x7097, 0x0000, 0x0005, 0x7097, 0x0011, 0x080c,
+ 0x9df2, 0x080c, 0x5e09, 0x20e1, 0x0000, 0x2099, 0x0260, 0x20e9,
+ 0x0000, 0x20a1, 0x0240, 0x748c, 0x9480, 0x0018, 0x9080, 0x0007,
+ 0x9084, 0x03f8, 0x8004, 0x20a8, 0x4003, 0x080c, 0x5dec, 0x11a0,
+ 0x7178, 0x81ff, 0x0188, 0x900e, 0x707c, 0x9084, 0x00ff, 0x0160,
+ 0x080c, 0x266d, 0x9186, 0x007e, 0x0138, 0x9186, 0x0080, 0x0120,
+ 0x2011, 0x0008, 0x080c, 0x5c45, 0x60c3, 0x0014, 0x080c, 0x5cc2,
+ 0x0005, 0x00f6, 0x708c, 0x9005, 0x0500, 0x2011, 0x5c98, 0x080c,
+ 0x8259, 0x9086, 0x0014, 0x11b8, 0x080c, 0x5e09, 0x2079, 0x0260,
0x7a30, 0x9296, 0x1103, 0x1178, 0x7834, 0x9005, 0x1160, 0x7a38,
0xd2fc, 0x0128, 0x70c0, 0x9005, 0x1110, 0x70c3, 0x0001, 0x7097,
- 0x0006, 0x0029, 0x0010, 0x080c, 0x5de6, 0x00fe, 0x0005, 0x00f6,
- 0x7097, 0x0007, 0x080c, 0x5d8e, 0x2079, 0x0240, 0x7833, 0x1104,
- 0x7837, 0x0000, 0x080c, 0x5e0a, 0x080c, 0x5ded, 0x11b8, 0x7080,
- 0x9005, 0x11a0, 0x7160, 0x9186, 0xffff, 0x0180, 0x9180, 0x3209,
- 0x200d, 0x918c, 0xff00, 0x810f, 0x2011, 0x0008, 0x080c, 0x5c46,
- 0x0180, 0x080c, 0x4dd8, 0x0110, 0x080c, 0x26d7, 0x20a9, 0x0008,
- 0x20e1, 0x0000, 0x2099, 0x026e, 0x20e9, 0x0000, 0x20a1, 0x024e,
- 0x4003, 0x60c3, 0x0014, 0x080c, 0x5cc3, 0x00fe, 0x0005, 0x00f6,
- 0x708c, 0x9005, 0x0500, 0x2011, 0x5c99, 0x080c, 0x825a, 0x9086,
- 0x0014, 0x11b8, 0x080c, 0x5e0a, 0x2079, 0x0260, 0x7a30, 0x9296,
- 0x1104, 0x1178, 0x7834, 0x9005, 0x1160, 0x7a38, 0xd2fc, 0x0128,
- 0x70c0, 0x9005, 0x1110, 0x70c3, 0x0001, 0x7097, 0x0008, 0x0029,
- 0x0010, 0x080c, 0x5de6, 0x00fe, 0x0005, 0x00f6, 0x7097, 0x0009,
- 0x080c, 0x5d8e, 0x2079, 0x0240, 0x7833, 0x1105, 0x7837, 0x0100,
- 0x080c, 0x5ded, 0x1150, 0x7080, 0x9005, 0x1138, 0x080c, 0x5bb9,
- 0x1188, 0x9085, 0x0001, 0x080c, 0x26d7, 0x20a9, 0x0008, 0x080c,
- 0x5e0a, 0x20e1, 0x0000, 0x2099, 0x026e, 0x20e9, 0x0000, 0x20a1,
- 0x024e, 0x4003, 0x60c3, 0x0014, 0x080c, 0x5cc3, 0x0010, 0x080c,
- 0x5713, 0x00fe, 0x0005, 0x00f6, 0x708c, 0x9005, 0x05a8, 0x2011,
- 0x5c99, 0x080c, 0x825a, 0x9086, 0x0014, 0x1560, 0x080c, 0x5e0a,
- 0x2079, 0x0260, 0x7a30, 0x9296, 0x1105, 0x1520, 0x7834, 0x9084,
- 0x0100, 0x2011, 0x0100, 0x921e, 0x1160, 0x7a38, 0xd2fc, 0x0128,
- 0x70c0, 0x9005, 0x1110, 0x70c3, 0x0001, 0x7097, 0x000a, 0x00b1,
- 0x0098, 0x9005, 0x1178, 0x7a38, 0xd2fc, 0x0128, 0x70c0, 0x9005,
- 0x1110, 0x70c3, 0x0001, 0x7093, 0x0000, 0x7097, 0x000e, 0x080c,
- 0x5961, 0x0010, 0x080c, 0x5de6, 0x00fe, 0x0005, 0x00f6, 0x7097,
- 0x000b, 0x2011, 0x1c0e, 0x20e9, 0x0001, 0x22a0, 0x20a9, 0x0040,
- 0x2019, 0xffff, 0x4304, 0x080c, 0x5d8e, 0x2079, 0x0240, 0x7833,
- 0x1106, 0x7837, 0x0000, 0x080c, 0x5ded, 0x0118, 0x2013, 0x0000,
- 0x0020, 0x705c, 0x9085, 0x0100, 0x2012, 0x20a9, 0x0040, 0x2009,
- 0x024e, 0x2011, 0x1c0e, 0x220e, 0x8210, 0x8108, 0x9186, 0x0260,
- 0x1128, 0x6810, 0x8000, 0x6812, 0x2009, 0x0240, 0x1f04, 0x58e3,
- 0x60c3, 0x0084, 0x080c, 0x5cc3, 0x00fe, 0x0005, 0x00f6, 0x708c,
- 0x9005, 0x01c0, 0x2011, 0x5c99, 0x080c, 0x825a, 0x9086, 0x0084,
- 0x1178, 0x080c, 0x5e0a, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1106,
- 0x1138, 0x7834, 0x9005, 0x1120, 0x7097, 0x000c, 0x0029, 0x0010,
- 0x080c, 0x5de6, 0x00fe, 0x0005, 0x00f6, 0x7097, 0x000d, 0x080c,
- 0x5d8e, 0x2079, 0x0240, 0x7833, 0x1107, 0x7837, 0x0000, 0x080c,
- 0x5e0a, 0x20a9, 0x0040, 0x2011, 0x026e, 0x2009, 0x024e, 0x220e,
- 0x8210, 0x8108, 0x9186, 0x0260, 0x1150, 0x6810, 0x8000, 0x6812,
- 0x2009, 0x0240, 0x6814, 0x8000, 0x6816, 0x2011, 0x0260, 0x1f04,
- 0x5927, 0x60c3, 0x0084, 0x080c, 0x5cc3, 0x00fe, 0x0005, 0x00f6,
- 0x708c, 0x9005, 0x01e0, 0x2011, 0x5c99, 0x080c, 0x825a, 0x9086,
- 0x0084, 0x1198, 0x080c, 0x5e0a, 0x2079, 0x0260, 0x7a30, 0x9296,
- 0x1107, 0x1158, 0x7834, 0x9005, 0x1140, 0x7093, 0x0001, 0x080c,
- 0x5d60, 0x7097, 0x000e, 0x0029, 0x0010, 0x080c, 0x5de6, 0x00fe,
- 0x0005, 0x918d, 0x0001, 0x080c, 0x5e35, 0x7097, 0x000f, 0x708f,
- 0x0000, 0x2061, 0x0140, 0x605b, 0xbc85, 0x605f, 0xb5b5, 0x2061,
- 0x0100, 0x6043, 0x0005, 0x6043, 0x0004, 0x2009, 0x07d0, 0x2011,
- 0x5c99, 0x080c, 0x824e, 0x0005, 0x708c, 0x9005, 0x0130, 0x2011,
- 0x5c99, 0x080c, 0x825a, 0x7097, 0x0000, 0x0005, 0x7097, 0x0011,
- 0x080c, 0x9ddd, 0x080c, 0x5e0a, 0x20e1, 0x0000, 0x2099, 0x0260,
- 0x20e9, 0x0000, 0x20a1, 0x0240, 0x748c, 0x9480, 0x0018, 0x9080,
- 0x0007, 0x9084, 0x03f8, 0x8004, 0x20a8, 0x4003, 0x080c, 0x5ded,
- 0x11a0, 0x7178, 0x81ff, 0x0188, 0x900e, 0x707c, 0x9084, 0x00ff,
- 0x0160, 0x080c, 0x266e, 0x9186, 0x007e, 0x0138, 0x9186, 0x0080,
- 0x0120, 0x2011, 0x0008, 0x080c, 0x5c46, 0x60c3, 0x0014, 0x080c,
- 0x5cc3, 0x0005, 0x00f6, 0x708c, 0x9005, 0x0500, 0x2011, 0x5c99,
- 0x080c, 0x825a, 0x9086, 0x0014, 0x11b8, 0x080c, 0x5e0a, 0x2079,
- 0x0260, 0x7a30, 0x9296, 0x1103, 0x1178, 0x7834, 0x9005, 0x1160,
- 0x7a38, 0xd2fc, 0x0128, 0x70c0, 0x9005, 0x1110, 0x70c3, 0x0001,
- 0x7097, 0x0012, 0x0029, 0x0010, 0x708f, 0x0000, 0x00fe, 0x0005,
- 0x00f6, 0x7097, 0x0013, 0x080c, 0x5d9c, 0x2079, 0x0240, 0x7833,
- 0x1103, 0x7837, 0x0000, 0x080c, 0x5e0a, 0x080c, 0x5ded, 0x1170,
- 0x7080, 0x9005, 0x1158, 0x7158, 0x9186, 0xffff, 0x0138, 0x2011,
- 0x0008, 0x080c, 0x5c46, 0x0168, 0x080c, 0x5dc3, 0x20a9, 0x0008,
- 0x20e1, 0x0000, 0x2099, 0x026e, 0x20e9, 0x0000, 0x20a1, 0x024e,
- 0x4003, 0x60c3, 0x0014, 0x080c, 0x5cc3, 0x00fe, 0x0005, 0x00f6,
- 0x708c, 0x9005, 0x0500, 0x2011, 0x5c99, 0x080c, 0x825a, 0x9086,
- 0x0014, 0x11b8, 0x080c, 0x5e0a, 0x2079, 0x0260, 0x7a30, 0x9296,
- 0x1104, 0x1178, 0x7834, 0x9005, 0x1160, 0x7a38, 0xd2fc, 0x0128,
- 0x70c0, 0x9005, 0x1110, 0x70c3, 0x0001, 0x7097, 0x0014, 0x0029,
- 0x0010, 0x708f, 0x0000, 0x00fe, 0x0005, 0x00f6, 0x7097, 0x0015,
- 0x080c, 0x5d9c, 0x2079, 0x0240, 0x7833, 0x1104, 0x7837, 0x0000,
- 0x080c, 0x5e0a, 0x080c, 0x5ded, 0x11b8, 0x7080, 0x9005, 0x11a0,
- 0x7160, 0x9186, 0xffff, 0x0180, 0x9180, 0x3209, 0x200d, 0x918c,
- 0xff00, 0x810f, 0x2011, 0x0008, 0x080c, 0x5c46, 0x0180, 0x080c,
- 0x4dd8, 0x0110, 0x080c, 0x26d7, 0x20a9, 0x0008, 0x20e1, 0x0000,
- 0x2099, 0x026e, 0x20e9, 0x0000, 0x20a1, 0x024e, 0x4003, 0x60c3,
- 0x0014, 0x080c, 0x5cc3, 0x00fe, 0x0005, 0x00f6, 0x708c, 0x9005,
- 0x05f0, 0x2011, 0x5c99, 0x080c, 0x825a, 0x9086, 0x0014, 0x15a8,
- 0x080c, 0x5e0a, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1105, 0x1568,
- 0x7834, 0x9084, 0x0100, 0x2011, 0x0100, 0x921e, 0x1168, 0x9085,
- 0x0001, 0x080c, 0x5e35, 0x7a38, 0xd2fc, 0x0128, 0x70c0, 0x9005,
- 0x1110, 0x70c3, 0x0001, 0x0080, 0x9005, 0x11b8, 0x7a38, 0xd2fc,
- 0x0128, 0x70c0, 0x9005, 0x1110, 0x70c3, 0x0001, 0x9085, 0x0001,
- 0x080c, 0x5e35, 0x7093, 0x0000, 0x7a38, 0xd2f4, 0x0110, 0x70db,
- 0x0008, 0x7097, 0x0016, 0x0029, 0x0010, 0x708f, 0x0000, 0x00fe,
- 0x0005, 0x080c, 0x9ddd, 0x080c, 0x5e0a, 0x20e1, 0x0000, 0x2099,
- 0x0260, 0x20e9, 0x0000, 0x20a1, 0x0240, 0x20a9, 0x000e, 0x4003,
- 0x2011, 0x026d, 0x2204, 0x9084, 0x0100, 0x2011, 0x024d, 0x2012,
- 0x2011, 0x026e, 0x7097, 0x0017, 0x080c, 0x5ded, 0x1150, 0x7080,
- 0x9005, 0x1138, 0x080c, 0x5bb9, 0x1188, 0x9085, 0x0001, 0x080c,
- 0x26d7, 0x20a9, 0x0008, 0x080c, 0x5e0a, 0x20e1, 0x0000, 0x2099,
+ 0x0012, 0x0029, 0x0010, 0x708f, 0x0000, 0x00fe, 0x0005, 0x00f6,
+ 0x7097, 0x0013, 0x080c, 0x5d9b, 0x2079, 0x0240, 0x7833, 0x1103,
+ 0x7837, 0x0000, 0x080c, 0x5e09, 0x080c, 0x5dec, 0x1170, 0x7080,
+ 0x9005, 0x1158, 0x7158, 0x9186, 0xffff, 0x0138, 0x2011, 0x0008,
+ 0x080c, 0x5c45, 0x0168, 0x080c, 0x5dc2, 0x20a9, 0x0008, 0x20e1,
+ 0x0000, 0x2099, 0x026e, 0x20e9, 0x0000, 0x20a1, 0x024e, 0x4003,
+ 0x60c3, 0x0014, 0x080c, 0x5cc2, 0x00fe, 0x0005, 0x00f6, 0x708c,
+ 0x9005, 0x0500, 0x2011, 0x5c98, 0x080c, 0x8259, 0x9086, 0x0014,
+ 0x11b8, 0x080c, 0x5e09, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1104,
+ 0x1178, 0x7834, 0x9005, 0x1160, 0x7a38, 0xd2fc, 0x0128, 0x70c0,
+ 0x9005, 0x1110, 0x70c3, 0x0001, 0x7097, 0x0014, 0x0029, 0x0010,
+ 0x708f, 0x0000, 0x00fe, 0x0005, 0x00f6, 0x7097, 0x0015, 0x080c,
+ 0x5d9b, 0x2079, 0x0240, 0x7833, 0x1104, 0x7837, 0x0000, 0x080c,
+ 0x5e09, 0x080c, 0x5dec, 0x11b8, 0x7080, 0x9005, 0x11a0, 0x7160,
+ 0x9186, 0xffff, 0x0180, 0x9180, 0x31f3, 0x200d, 0x918c, 0xff00,
+ 0x810f, 0x2011, 0x0008, 0x080c, 0x5c45, 0x0180, 0x080c, 0x4dd7,
+ 0x0110, 0x080c, 0x26d6, 0x20a9, 0x0008, 0x20e1, 0x0000, 0x2099,
0x026e, 0x20e9, 0x0000, 0x20a1, 0x024e, 0x4003, 0x60c3, 0x0014,
- 0x080c, 0x5cc3, 0x0010, 0x080c, 0x5713, 0x0005, 0x00f6, 0x708c,
- 0x9005, 0x01d8, 0x2011, 0x5c99, 0x080c, 0x825a, 0x9086, 0x0084,
- 0x1190, 0x080c, 0x5e0a, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1106,
- 0x1150, 0x7834, 0x9005, 0x1138, 0x9006, 0x080c, 0x5e35, 0x7097,
- 0x0018, 0x0029, 0x0010, 0x708f, 0x0000, 0x00fe, 0x0005, 0x00f6,
- 0x7097, 0x0019, 0x080c, 0x5d9c, 0x2079, 0x0240, 0x7833, 0x1106,
- 0x7837, 0x0000, 0x080c, 0x5e0a, 0x2009, 0x026e, 0x2039, 0x1c0e,
- 0x20a9, 0x0040, 0x213e, 0x8738, 0x8108, 0x9186, 0x0280, 0x1128,
- 0x6814, 0x8000, 0x6816, 0x2009, 0x0260, 0x1f04, 0x5b22, 0x2039,
- 0x1c0e, 0x080c, 0x5ded, 0x11e8, 0x2728, 0x2514, 0x8207, 0x9084,
- 0x00ff, 0x8000, 0x2018, 0x9294, 0x00ff, 0x8007, 0x9205, 0x202a,
- 0x705c, 0x2310, 0x8214, 0x92a0, 0x1c0e, 0x2414, 0x938c, 0x0001,
- 0x0118, 0x9294, 0xff00, 0x0018, 0x9294, 0x00ff, 0x8007, 0x9215,
- 0x2222, 0x20a9, 0x0040, 0x2009, 0x024e, 0x270e, 0x8738, 0x8108,
- 0x9186, 0x0260, 0x1128, 0x6810, 0x8000, 0x6812, 0x2009, 0x0240,
- 0x1f04, 0x5b55, 0x60c3, 0x0084, 0x080c, 0x5cc3, 0x00fe, 0x0005,
- 0x00f6, 0x708c, 0x9005, 0x01e0, 0x2011, 0x5c99, 0x080c, 0x825a,
- 0x9086, 0x0084, 0x1198, 0x080c, 0x5e0a, 0x2079, 0x0260, 0x7a30,
- 0x9296, 0x1107, 0x1158, 0x7834, 0x9005, 0x1140, 0x7093, 0x0001,
- 0x080c, 0x5d60, 0x7097, 0x001a, 0x0029, 0x0010, 0x708f, 0x0000,
- 0x00fe, 0x0005, 0x9085, 0x0001, 0x080c, 0x5e35, 0x7097, 0x001b,
- 0x080c, 0x9ddd, 0x080c, 0x5e0a, 0x2011, 0x0260, 0x2009, 0x0240,
- 0x748c, 0x9480, 0x0018, 0x9080, 0x0007, 0x9084, 0x03f8, 0x8004,
- 0x20a8, 0x220e, 0x8210, 0x8108, 0x9186, 0x0260, 0x1150, 0x6810,
- 0x8000, 0x6812, 0x2009, 0x0240, 0x6814, 0x8000, 0x6816, 0x2011,
- 0x0260, 0x1f04, 0x5ba1, 0x60c3, 0x0084, 0x080c, 0x5cc3, 0x0005,
- 0x0005, 0x0086, 0x0096, 0x2029, 0x185c, 0x252c, 0x20a9, 0x0008,
- 0x2041, 0x1c0e, 0x20e9, 0x0001, 0x28a0, 0x080c, 0x5e0a, 0x20e1,
- 0x0000, 0x2099, 0x026e, 0x4003, 0x20a9, 0x0008, 0x2011, 0x0007,
- 0xd5d4, 0x0108, 0x9016, 0x2800, 0x9200, 0x200c, 0x91a6, 0xffff,
- 0x1148, 0xd5d4, 0x0110, 0x8210, 0x0008, 0x8211, 0x1f04, 0x5bd3,
- 0x0804, 0x5c42, 0x82ff, 0x1160, 0xd5d4, 0x0120, 0x91a6, 0x3fff,
- 0x0d90, 0x0020, 0x91a6, 0x3fff, 0x0904, 0x5c42, 0x918d, 0xc000,
- 0x20a9, 0x0010, 0x2019, 0x0001, 0xd5d4, 0x0110, 0x2019, 0x0010,
- 0x2120, 0xd5d4, 0x0110, 0x8423, 0x0008, 0x8424, 0x1240, 0xd5d4,
- 0x0110, 0x8319, 0x0008, 0x8318, 0x1f04, 0x5bf9, 0x04d8, 0x23a8,
- 0x2021, 0x0001, 0x8426, 0x8425, 0x1f04, 0x5c0b, 0x2328, 0x8529,
- 0x92be, 0x0007, 0x0158, 0x0006, 0x2039, 0x0007, 0x2200, 0x973a,
- 0x000e, 0x27a8, 0x95a8, 0x0010, 0x1f04, 0x5c1a, 0x755a, 0x95c8,
- 0x3209, 0x292d, 0x95ac, 0x00ff, 0x757e, 0x6532, 0x6536, 0x0016,
- 0x2508, 0x080c, 0x26b7, 0x001e, 0x60e7, 0x0000, 0x65ea, 0x2018,
- 0x2304, 0x9405, 0x201a, 0x7083, 0x0001, 0x20e9, 0x0000, 0x20a1,
- 0x024e, 0x20e1, 0x0001, 0x2898, 0x20a9, 0x0008, 0x4003, 0x9085,
- 0x0001, 0x0008, 0x9006, 0x009e, 0x008e, 0x0005, 0x0156, 0x01c6,
- 0x01d6, 0x0136, 0x0146, 0x22a8, 0x20e1, 0x0000, 0x2099, 0x026e,
- 0x20e9, 0x0000, 0x2011, 0x024e, 0x22a0, 0x4003, 0x014e, 0x013e,
- 0x01de, 0x01ce, 0x015e, 0x2118, 0x9026, 0x2001, 0x0007, 0x939a,
- 0x0010, 0x0218, 0x8420, 0x8001, 0x0cd0, 0x2118, 0x84ff, 0x0120,
- 0x939a, 0x0010, 0x8421, 0x1de0, 0x2021, 0x0001, 0x83ff, 0x0118,
- 0x8423, 0x8319, 0x1de8, 0x9238, 0x2029, 0x026e, 0x9528, 0x2504,
- 0x942c, 0x11b8, 0x9405, 0x203a, 0x715a, 0x91a0, 0x3209, 0x242d,
- 0x95ac, 0x00ff, 0x757e, 0x6532, 0x6536, 0x0016, 0x2508, 0x080c,
- 0x26b7, 0x001e, 0x60e7, 0x0000, 0x65ea, 0x7083, 0x0001, 0x9084,
- 0x0000, 0x0005, 0x00e6, 0x2071, 0x1800, 0x7087, 0x0000, 0x00ee,
- 0x0005, 0x00e6, 0x00f6, 0x2079, 0x0100, 0x2071, 0x0140, 0x080c,
- 0x5d4f, 0x080c, 0x9605, 0x7004, 0x9084, 0x4000, 0x0110, 0x080c,
- 0x2b98, 0x0126, 0x2091, 0x8000, 0x2071, 0x1825, 0x2073, 0x0000,
- 0x7840, 0x0026, 0x0016, 0x2009, 0x00f7, 0x080c, 0x5dac, 0x001e,
- 0x9094, 0x0010, 0x9285, 0x0080, 0x7842, 0x7a42, 0x002e, 0x012e,
- 0x00fe, 0x00ee, 0x0005, 0x0126, 0x2091, 0x8000, 0x080c, 0x29fe,
- 0x0228, 0x2011, 0x0101, 0x2204, 0xc0c5, 0x2012, 0x2011, 0x19cc,
- 0x2013, 0x0000, 0x708f, 0x0000, 0x012e, 0x60a3, 0x0056, 0x60a7,
- 0x9575, 0x080c, 0x95fc, 0x6144, 0xd184, 0x0120, 0x7194, 0x918d,
- 0x2000, 0x0018, 0x7188, 0x918d, 0x1000, 0x2011, 0x1973, 0x2112,
- 0x2009, 0x07d0, 0x2011, 0x5c99, 0x080c, 0x82ec, 0x0005, 0x0016,
- 0x0026, 0x00c6, 0x0126, 0x2091, 0x8000, 0x080c, 0x9f5b, 0x2009,
- 0x00f7, 0x080c, 0x5dac, 0x2061, 0x19d5, 0x900e, 0x611a, 0x611e,
- 0x617a, 0x617e, 0x2061, 0x1800, 0x6003, 0x0001, 0x2061, 0x0100,
- 0x6043, 0x0090, 0x6043, 0x0010, 0x2009, 0x1973, 0x200b, 0x0000,
- 0x2009, 0x002d, 0x2011, 0x5d1b, 0x080c, 0x824e, 0x012e, 0x00ce,
- 0x002e, 0x001e, 0x0005, 0x00e6, 0x0006, 0x0126, 0x2091, 0x8000,
- 0x0471, 0x2071, 0x0100, 0x080c, 0x9605, 0x2071, 0x0140, 0x7004,
- 0x9084, 0x4000, 0x0110, 0x080c, 0x2b98, 0x080c, 0x7187, 0x0188,
- 0x080c, 0x71a2, 0x1170, 0x080c, 0x7485, 0x0016, 0x080c, 0x2786,
- 0x2001, 0x1947, 0x2102, 0x001e, 0x080c, 0x7480, 0x080c, 0x709f,
- 0x0050, 0x2009, 0x0001, 0x080c, 0x2ab6, 0x2001, 0x0001, 0x080c,
- 0x2617, 0x080c, 0x5cef, 0x012e, 0x000e, 0x00ee, 0x0005, 0x2001,
- 0x180e, 0x2004, 0xd0bc, 0x0158, 0x0026, 0x0036, 0x2011, 0x8017,
- 0x2001, 0x1973, 0x201c, 0x080c, 0x4a18, 0x003e, 0x002e, 0x0005,
- 0x20a9, 0x0012, 0x20e9, 0x0001, 0x20a1, 0x1c80, 0x080c, 0x5e0a,
- 0x20e9, 0x0000, 0x2099, 0x026e, 0x0099, 0x20a9, 0x0020, 0x080c,
- 0x5e04, 0x2099, 0x0260, 0x20a1, 0x1c92, 0x0051, 0x20a9, 0x000e,
- 0x080c, 0x5e07, 0x2099, 0x0260, 0x20a1, 0x1cb2, 0x0009, 0x0005,
- 0x0016, 0x0026, 0x3410, 0x3308, 0x2104, 0x8007, 0x2012, 0x8108,
- 0x8210, 0x1f04, 0x5d84, 0x002e, 0x001e, 0x0005, 0x080c, 0x9ddd,
- 0x20e1, 0x0001, 0x2099, 0x1c00, 0x20e9, 0x0000, 0x20a1, 0x0240,
- 0x20a9, 0x000c, 0x4003, 0x0005, 0x080c, 0x9ddd, 0x080c, 0x5e0a,
- 0x20e1, 0x0000, 0x2099, 0x0260, 0x20e9, 0x0000, 0x20a1, 0x0240,
- 0x20a9, 0x000c, 0x4003, 0x0005, 0x00c6, 0x0006, 0x2061, 0x0100,
- 0x810f, 0x2001, 0x1833, 0x2004, 0x9005, 0x1138, 0x2001, 0x1817,
- 0x2004, 0x9084, 0x00ff, 0x9105, 0x0010, 0x9185, 0x00f7, 0x604a,
- 0x000e, 0x00ce, 0x0005, 0x0016, 0x0046, 0x080c, 0x66c6, 0x0158,
- 0x9006, 0x2020, 0x2009, 0x002a, 0x080c, 0xd7d6, 0x2001, 0x180c,
- 0x200c, 0xc195, 0x2102, 0x2019, 0x002a, 0x900e, 0x080c, 0x3076,
- 0x080c, 0xc444, 0x0140, 0x0036, 0x2019, 0xffff, 0x2021, 0x0007,
- 0x080c, 0x4bb5, 0x003e, 0x004e, 0x001e, 0x0005, 0x080c, 0x5cef,
- 0x7097, 0x0000, 0x708f, 0x0000, 0x0005, 0x0006, 0x2001, 0x180c,
- 0x2004, 0xd09c, 0x0100, 0x000e, 0x0005, 0x0006, 0x0016, 0x0126,
- 0x2091, 0x8000, 0x2001, 0x0101, 0x200c, 0x918d, 0x0006, 0x2102,
- 0x012e, 0x001e, 0x000e, 0x0005, 0x2009, 0x0001, 0x0020, 0x2009,
- 0x0002, 0x0008, 0x900e, 0x6814, 0x9084, 0xffc0, 0x910d, 0x6916,
- 0x0005, 0x00f6, 0x0156, 0x0146, 0x01d6, 0x9006, 0x20a9, 0x0080,
- 0x20e9, 0x0001, 0x20a1, 0x1c00, 0x4004, 0x2079, 0x1c00, 0x7803,
- 0x2200, 0x7807, 0x00ef, 0x780f, 0x00ef, 0x7813, 0x0138, 0x7823,
- 0xffff, 0x7827, 0xffff, 0x01de, 0x014e, 0x015e, 0x00fe, 0x0005,
- 0x2001, 0x1800, 0x2003, 0x0001, 0x0005, 0x2001, 0x1980, 0x0118,
- 0x2003, 0x0001, 0x0010, 0x2003, 0x0000, 0x0005, 0x0156, 0x20a9,
- 0x0800, 0x2009, 0x1000, 0x9006, 0x200a, 0x8108, 0x1f04, 0x5e44,
- 0x015e, 0x0005, 0x00d6, 0x0036, 0x0156, 0x0136, 0x0146, 0x2069,
- 0x185b, 0x9006, 0xb802, 0xb8be, 0xb807, 0x0707, 0xb80a, 0xb80e,
- 0xb812, 0x9198, 0x3209, 0x231d, 0x939c, 0x00ff, 0xbb16, 0x0016,
- 0x0026, 0xb8b2, 0x080c, 0x9f54, 0x1120, 0x9192, 0x007e, 0x1208,
- 0xbbb2, 0x20a9, 0x0004, 0xb8b4, 0x20e8, 0xb9b8, 0x9198, 0x0006,
- 0x9006, 0x23a0, 0x4004, 0x20a9, 0x0004, 0x9198, 0x000a, 0x23a0,
- 0x4004, 0x002e, 0x001e, 0xb83e, 0xb842, 0xb84e, 0xb852, 0xb856,
- 0xb85a, 0xb85e, 0xb862, 0xb866, 0xb86a, 0xb86f, 0x0100, 0xb872,
- 0xb876, 0xb87a, 0xb88a, 0xb88e, 0xb893, 0x0008, 0xb896, 0xb89a,
- 0xb89e, 0xb8ae, 0xb9a2, 0x0096, 0xb8a4, 0x904d, 0x0110, 0x080c,
- 0x1075, 0xb8a7, 0x0000, 0x009e, 0x9006, 0xb84a, 0x6810, 0xb83a,
- 0x680c, 0xb846, 0x6814, 0x9084, 0x00ff, 0xb842, 0x014e, 0x013e,
- 0x015e, 0x003e, 0x00de, 0x0005, 0x0126, 0x2091, 0x8000, 0xa974,
- 0xae78, 0x9684, 0x3fff, 0x9082, 0x4000, 0x1a04, 0x5f1a, 0x9182,
- 0x0800, 0x1a04, 0x5f1e, 0x2001, 0x180c, 0x2004, 0x9084, 0x0003,
- 0x1904, 0x5f24, 0x9188, 0x1000, 0x2104, 0x905d, 0x0518, 0xb804,
- 0x9084, 0x00ff, 0x908e, 0x0006, 0x1508, 0xb8a4, 0x900d, 0x1904,
- 0x5f36, 0xb850, 0x900d, 0x1148, 0xa802, 0x2900, 0xb852, 0xb84e,
- 0x080c, 0x8616, 0x9006, 0x012e, 0x0005, 0x00a6, 0x2150, 0x2900,
- 0xb002, 0xa803, 0x0000, 0x00ae, 0xb852, 0x0c90, 0x2001, 0x0005,
- 0x900e, 0x04b8, 0x2001, 0x0028, 0x900e, 0x0498, 0x9082, 0x0006,
- 0x1290, 0x080c, 0x9f54, 0x1160, 0xb8a0, 0x9084, 0xff80, 0x1140,
- 0xb900, 0xd1fc, 0x0990, 0x2001, 0x0029, 0x2009, 0x1000, 0x0408,
- 0x2001, 0x0028, 0x00a8, 0x2009, 0x180c, 0x210c, 0xd18c, 0x0118,
- 0x2001, 0x0004, 0x0068, 0xd184, 0x0118, 0x2001, 0x0004, 0x0040,
- 0x2001, 0x0029, 0xb900, 0xd1fc, 0x0118, 0x2009, 0x1000, 0x0048,
- 0x900e, 0x0038, 0x2001, 0x0029, 0x900e, 0x0018, 0x2001, 0x0029,
- 0x900e, 0x9005, 0x012e, 0x0005, 0x2001, 0x180c, 0x2004, 0xd084,
- 0x19d0, 0x9188, 0x1000, 0x2104, 0x905d, 0x09a8, 0x080c, 0x66ca,
- 0x1990, 0xb800, 0xd0bc, 0x0978, 0x0804, 0x5ecd, 0x080c, 0x6540,
- 0x0904, 0x5ee6, 0x0804, 0x5ed1, 0x00b6, 0x00e6, 0x0126, 0x2091,
- 0x8000, 0xa974, 0x9182, 0x0800, 0x1a04, 0x5fba, 0x9188, 0x1000,
- 0x2104, 0x905d, 0x0904, 0x5f92, 0xb8a0, 0x9086, 0x007f, 0x0190,
- 0xa87c, 0xd0fc, 0x1178, 0x080c, 0x66d2, 0x0160, 0xa994, 0x81ff,
- 0x0130, 0x908e, 0x0004, 0x0130, 0x908e, 0x0005, 0x0118, 0x080c,
- 0x66ca, 0x1598, 0xa87c, 0xd0fc, 0x01e0, 0xa894, 0x9005, 0x01c8,
- 0x2060, 0x0026, 0x2010, 0x080c, 0xbd29, 0x002e, 0x1120, 0x2001,
- 0x0008, 0x0804, 0x5fbc, 0x6020, 0x9086, 0x000a, 0x0120, 0x2001,
- 0x0008, 0x0804, 0x5fbc, 0x601a, 0x6003, 0x0008, 0x2900, 0x6016,
- 0x0058, 0x080c, 0x9f7f, 0x05e8, 0x2b00, 0x6012, 0x2900, 0x6016,
- 0x600b, 0xffff, 0x6023, 0x000a, 0x2009, 0x0003, 0x080c, 0xa053,
- 0x9006, 0x0458, 0x2001, 0x0028, 0x0438, 0x9082, 0x0006, 0x1290,
- 0x080c, 0x9f54, 0x1160, 0xb8a0, 0x9084, 0xff80, 0x1140, 0xb900,
- 0xd1fc, 0x0900, 0x2001, 0x0029, 0x2009, 0x1000, 0x00a8, 0x2001,
- 0x0028, 0x0090, 0x2009, 0x180c, 0x210c, 0xd18c, 0x0118, 0x2001,
- 0x0004, 0x0050, 0xd184, 0x0118, 0x2001, 0x0004, 0x0028, 0x2001,
- 0x0029, 0x0010, 0x2001, 0x0029, 0x9005, 0x012e, 0x00ee, 0x00be,
- 0x0005, 0x2001, 0x002c, 0x0cc0, 0x00f6, 0x00b6, 0x0126, 0x2091,
- 0x8000, 0xa8e0, 0x9005, 0x1550, 0xa8dc, 0x9082, 0x0101, 0x1630,
- 0xa8c8, 0x9005, 0x1518, 0xa8c4, 0x9082, 0x0101, 0x12f8, 0xa974,
- 0x2079, 0x1800, 0x9182, 0x0800, 0x12e8, 0x7830, 0x9084, 0x0003,
- 0x1130, 0xaa98, 0xab94, 0xa878, 0x9084, 0x0007, 0x00ea, 0x7930,
- 0xd18c, 0x0118, 0x2001, 0x0004, 0x0038, 0xd184, 0x0118, 0x2001,
- 0x0004, 0x0010, 0x2001, 0x0029, 0x900e, 0x0038, 0x2001, 0x002c,
- 0x900e, 0x0018, 0x2001, 0x0029, 0x900e, 0x9006, 0x0008, 0x9005,
- 0x012e, 0x00be, 0x00fe, 0x0005, 0x6051, 0x600c, 0x6023, 0x6051,
- 0x6051, 0x6051, 0x6051, 0x6051, 0x2100, 0x9082, 0x007e, 0x1278,
- 0x080c, 0x6344, 0x0148, 0x9046, 0xb810, 0x9306, 0x1904, 0x6059,
- 0xb814, 0x9206, 0x15f0, 0x0028, 0xbb12, 0xba16, 0x0010, 0x080c,
- 0x48d2, 0x0150, 0x04b0, 0x080c, 0x63a4, 0x1598, 0xb810, 0x9306,
- 0x1580, 0xb814, 0x9206, 0x1568, 0x080c, 0x9f7f, 0x0530, 0x2b00,
- 0x6012, 0x080c, 0xc1b7, 0x2900, 0x6016, 0x600b, 0xffff, 0x6023,
- 0x000a, 0xa878, 0x9086, 0x0001, 0x1170, 0x080c, 0x30ab, 0x9006,
- 0x080c, 0x62e1, 0x2001, 0x0002, 0x080c, 0x62f5, 0x2001, 0x0200,
- 0xb86e, 0xb893, 0x0002, 0x2009, 0x0003, 0x080c, 0xa053, 0x9006,
- 0x0068, 0x2001, 0x0001, 0x900e, 0x0038, 0x2001, 0x002c, 0x900e,
- 0x0018, 0x2001, 0x0028, 0x900e, 0x9005, 0x0000, 0x012e, 0x00be,
- 0x00fe, 0x0005, 0x00b6, 0x00f6, 0x00e6, 0x0126, 0x2091, 0x8000,
- 0xa894, 0x90c6, 0x0015, 0x0904, 0x6232, 0x90c6, 0x0056, 0x0904,
- 0x6236, 0x90c6, 0x0066, 0x0904, 0x623a, 0x90c6, 0x0067, 0x0904,
- 0x623e, 0x90c6, 0x0068, 0x0904, 0x6242, 0x90c6, 0x0071, 0x0904,
- 0x6246, 0x90c6, 0x0074, 0x0904, 0x624a, 0x90c6, 0x007c, 0x0904,
- 0x624e, 0x90c6, 0x007e, 0x0904, 0x6252, 0x90c6, 0x0037, 0x0904,
- 0x6256, 0x9016, 0x2079, 0x1800, 0xa974, 0x9186, 0x00ff, 0x0904,
- 0x622d, 0x9182, 0x0800, 0x1a04, 0x622d, 0x080c, 0x63a4, 0x1198,
- 0xb804, 0x9084, 0x00ff, 0x9082, 0x0006, 0x1268, 0xa894, 0x90c6,
- 0x006f, 0x0148, 0x080c, 0x9f54, 0x1904, 0x6216, 0xb8a0, 0x9084,
- 0xff80, 0x1904, 0x6216, 0xa894, 0x90c6, 0x006f, 0x0158, 0x90c6,
- 0x005e, 0x0904, 0x6176, 0x90c6, 0x0064, 0x0904, 0x619f, 0x2008,
- 0x0804, 0x6139, 0xa998, 0xa8b0, 0x2040, 0x080c, 0x9f54, 0x1120,
- 0x9182, 0x007f, 0x0a04, 0x6139, 0x9186, 0x00ff, 0x0904, 0x6139,
- 0x9182, 0x0800, 0x1a04, 0x6139, 0xaaa0, 0xab9c, 0x7878, 0x9306,
- 0x11a8, 0x787c, 0x0096, 0x924e, 0x1128, 0x2208, 0x2310, 0x009e,
- 0x0804, 0x6139, 0x080c, 0x9f54, 0x1140, 0x99cc, 0xff00, 0x009e,
- 0x1128, 0x2208, 0x2310, 0x0804, 0x6139, 0x009e, 0x080c, 0x48d2,
- 0x0904, 0x6142, 0x900e, 0x9016, 0x90c6, 0x4000, 0x1558, 0x0006,
- 0x080c, 0x65c4, 0x1108, 0xc185, 0xb800, 0xd0bc, 0x0108, 0xc18d,
- 0x20a9, 0x0004, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0031, 0x20a0,
- 0xb8b4, 0x20e0, 0xb8b8, 0x9080, 0x0006, 0x2098, 0x080c, 0x0fc0,
- 0x20a9, 0x0004, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0035, 0x20a0,
- 0xb8b4, 0x20e0, 0xb8b8, 0x9080, 0x000a, 0x2098, 0x080c, 0x0fc0,
- 0x000e, 0x00c8, 0x90c6, 0x4007, 0x1110, 0x2408, 0x00a0, 0x90c6,
- 0x4008, 0x1118, 0x2708, 0x2610, 0x0070, 0x90c6, 0x4009, 0x1108,
- 0x0050, 0x90c6, 0x4006, 0x0138, 0x2001, 0x4005, 0x2009, 0x000a,
- 0x0010, 0x2001, 0x4006, 0xa896, 0xa99a, 0xaa9e, 0x2001, 0x0030,
- 0x900e, 0x0470, 0x080c, 0x9f7f, 0x1130, 0x2001, 0x4005, 0x2009,
- 0x0003, 0x9016, 0x0c80, 0x2b00, 0x6012, 0x080c, 0xc1b7, 0x2900,
- 0x6016, 0x6023, 0x0001, 0xa868, 0xd88c, 0x0108, 0xc0f5, 0xa86a,
- 0x0126, 0x2091, 0x8000, 0x080c, 0x30ab, 0x012e, 0x9006, 0x080c,
- 0x62e1, 0x2001, 0x0002, 0x080c, 0x62f5, 0x2009, 0x0002, 0x080c,
- 0xa053, 0xa8b0, 0xd094, 0x0118, 0xb8bc, 0xc08d, 0xb8be, 0x9006,
- 0x9005, 0x012e, 0x00ee, 0x00fe, 0x00be, 0x0005, 0x080c, 0x54f0,
- 0x0118, 0x2009, 0x0007, 0x00f8, 0xa998, 0xaeb0, 0x080c, 0x63a4,
- 0x1904, 0x6134, 0x9186, 0x007f, 0x0130, 0x080c, 0x66ca, 0x0118,
- 0x2009, 0x0009, 0x0080, 0x0096, 0x080c, 0x1043, 0x1120, 0x009e,
- 0x2009, 0x0002, 0x0040, 0x2900, 0x009e, 0xa806, 0x080c, 0xbf23,
- 0x19b0, 0x2009, 0x0003, 0x2001, 0x4005, 0x0804, 0x613b, 0xa998,
- 0xaeb0, 0x080c, 0x63a4, 0x1904, 0x6134, 0x0096, 0x080c, 0x1043,
- 0x1128, 0x009e, 0x2009, 0x0002, 0x0804, 0x61f3, 0x2900, 0x009e,
- 0xa806, 0x0096, 0x2048, 0x20a9, 0x002b, 0xb8b4, 0x20e0, 0xb8b8,
- 0x2098, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0002, 0x20a0, 0x4003,
- 0x20a9, 0x0008, 0x9080, 0x0006, 0x20a0, 0xbbb8, 0x9398, 0x0006,
- 0x2398, 0x080c, 0x0fc0, 0x009e, 0xa87b, 0x0000, 0xa883, 0x0000,
- 0xa897, 0x4000, 0xd684, 0x1168, 0x080c, 0x54dc, 0xd0b4, 0x1118,
- 0xa89b, 0x000b, 0x00e0, 0xb800, 0xd08c, 0x0118, 0xa89b, 0x000c,
- 0x00b0, 0x080c, 0x66ca, 0x0118, 0xa89b, 0x0009, 0x0080, 0x080c,
- 0x54f0, 0x0118, 0xa89b, 0x0007, 0x0050, 0x080c, 0xbf06, 0x1904,
- 0x616f, 0x2009, 0x0003, 0x2001, 0x4005, 0x0804, 0x613b, 0xa87b,
- 0x0030, 0xa897, 0x4005, 0xa804, 0x8006, 0x8006, 0x8007, 0x90bc,
- 0x003f, 0x9084, 0xffc0, 0x9080, 0x0002, 0x2009, 0x002b, 0xaaa0,
- 0xab9c, 0xaca8, 0xada4, 0x2031, 0x0000, 0x2041, 0x129a, 0x080c,
- 0xa4df, 0x1904, 0x616f, 0x2009, 0x0002, 0x08e8, 0x2001, 0x0028,
- 0x900e, 0x0804, 0x6170, 0x2009, 0x180c, 0x210c, 0xd18c, 0x0118,
- 0x2001, 0x0004, 0x0038, 0xd184, 0x0118, 0x2001, 0x0004, 0x0010,
- 0x2001, 0x0029, 0x900e, 0x0804, 0x6170, 0x2001, 0x0029, 0x900e,
- 0x0804, 0x6170, 0x080c, 0x363a, 0x0804, 0x6171, 0x080c, 0x5207,
- 0x0804, 0x6171, 0x080c, 0x448d, 0x0804, 0x6171, 0x080c, 0x4506,
- 0x0804, 0x6171, 0x080c, 0x4562, 0x0804, 0x6171, 0x080c, 0x498e,
- 0x0804, 0x6171, 0x080c, 0x4c37, 0x0804, 0x6171, 0x080c, 0x4e6e,
- 0x0804, 0x6171, 0x080c, 0x5067, 0x0804, 0x6171, 0x080c, 0x3863,
- 0x0804, 0x6171, 0x00b6, 0xa974, 0xae78, 0x9684, 0x3fff, 0x9082,
- 0x4000, 0x1618, 0x9182, 0x0800, 0x1268, 0x9188, 0x1000, 0x2104,
- 0x905d, 0x0140, 0x080c, 0x66ca, 0x1148, 0x00e9, 0x080c, 0x64cf,
- 0x9006, 0x00b0, 0x2001, 0x0028, 0x900e, 0x0090, 0x9082, 0x0006,
- 0x1240, 0xb900, 0xd1fc, 0x0d88, 0x2001, 0x0029, 0x2009, 0x1000,
+ 0x080c, 0x5cc2, 0x00fe, 0x0005, 0x00f6, 0x708c, 0x9005, 0x05f0,
+ 0x2011, 0x5c98, 0x080c, 0x8259, 0x9086, 0x0014, 0x15a8, 0x080c,
+ 0x5e09, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1105, 0x1568, 0x7834,
+ 0x9084, 0x0100, 0x2011, 0x0100, 0x921e, 0x1168, 0x9085, 0x0001,
+ 0x080c, 0x5e34, 0x7a38, 0xd2fc, 0x0128, 0x70c0, 0x9005, 0x1110,
+ 0x70c3, 0x0001, 0x0080, 0x9005, 0x11b8, 0x7a38, 0xd2fc, 0x0128,
+ 0x70c0, 0x9005, 0x1110, 0x70c3, 0x0001, 0x9085, 0x0001, 0x080c,
+ 0x5e34, 0x7093, 0x0000, 0x7a38, 0xd2f4, 0x0110, 0x70db, 0x0008,
+ 0x7097, 0x0016, 0x0029, 0x0010, 0x708f, 0x0000, 0x00fe, 0x0005,
+ 0x080c, 0x9df2, 0x080c, 0x5e09, 0x20e1, 0x0000, 0x2099, 0x0260,
+ 0x20e9, 0x0000, 0x20a1, 0x0240, 0x20a9, 0x000e, 0x4003, 0x2011,
+ 0x026d, 0x2204, 0x9084, 0x0100, 0x2011, 0x024d, 0x2012, 0x2011,
+ 0x026e, 0x7097, 0x0017, 0x080c, 0x5dec, 0x1150, 0x7080, 0x9005,
+ 0x1138, 0x080c, 0x5bb8, 0x1188, 0x9085, 0x0001, 0x080c, 0x26d6,
+ 0x20a9, 0x0008, 0x080c, 0x5e09, 0x20e1, 0x0000, 0x2099, 0x026e,
+ 0x20e9, 0x0000, 0x20a1, 0x024e, 0x4003, 0x60c3, 0x0014, 0x080c,
+ 0x5cc2, 0x0010, 0x080c, 0x5712, 0x0005, 0x00f6, 0x708c, 0x9005,
+ 0x01d8, 0x2011, 0x5c98, 0x080c, 0x8259, 0x9086, 0x0084, 0x1190,
+ 0x080c, 0x5e09, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1106, 0x1150,
+ 0x7834, 0x9005, 0x1138, 0x9006, 0x080c, 0x5e34, 0x7097, 0x0018,
+ 0x0029, 0x0010, 0x708f, 0x0000, 0x00fe, 0x0005, 0x00f6, 0x7097,
+ 0x0019, 0x080c, 0x5d9b, 0x2079, 0x0240, 0x7833, 0x1106, 0x7837,
+ 0x0000, 0x080c, 0x5e09, 0x2009, 0x026e, 0x2039, 0x1c0e, 0x20a9,
+ 0x0040, 0x213e, 0x8738, 0x8108, 0x9186, 0x0280, 0x1128, 0x6814,
+ 0x8000, 0x6816, 0x2009, 0x0260, 0x1f04, 0x5b21, 0x2039, 0x1c0e,
+ 0x080c, 0x5dec, 0x11e8, 0x2728, 0x2514, 0x8207, 0x9084, 0x00ff,
+ 0x8000, 0x2018, 0x9294, 0x00ff, 0x8007, 0x9205, 0x202a, 0x705c,
+ 0x2310, 0x8214, 0x92a0, 0x1c0e, 0x2414, 0x938c, 0x0001, 0x0118,
+ 0x9294, 0xff00, 0x0018, 0x9294, 0x00ff, 0x8007, 0x9215, 0x2222,
+ 0x20a9, 0x0040, 0x2009, 0x024e, 0x270e, 0x8738, 0x8108, 0x9186,
+ 0x0260, 0x1128, 0x6810, 0x8000, 0x6812, 0x2009, 0x0240, 0x1f04,
+ 0x5b54, 0x60c3, 0x0084, 0x080c, 0x5cc2, 0x00fe, 0x0005, 0x00f6,
+ 0x708c, 0x9005, 0x01e0, 0x2011, 0x5c98, 0x080c, 0x8259, 0x9086,
+ 0x0084, 0x1198, 0x080c, 0x5e09, 0x2079, 0x0260, 0x7a30, 0x9296,
+ 0x1107, 0x1158, 0x7834, 0x9005, 0x1140, 0x7093, 0x0001, 0x080c,
+ 0x5d5f, 0x7097, 0x001a, 0x0029, 0x0010, 0x708f, 0x0000, 0x00fe,
+ 0x0005, 0x9085, 0x0001, 0x080c, 0x5e34, 0x7097, 0x001b, 0x080c,
+ 0x9df2, 0x080c, 0x5e09, 0x2011, 0x0260, 0x2009, 0x0240, 0x748c,
+ 0x9480, 0x0018, 0x9080, 0x0007, 0x9084, 0x03f8, 0x8004, 0x20a8,
+ 0x220e, 0x8210, 0x8108, 0x9186, 0x0260, 0x1150, 0x6810, 0x8000,
+ 0x6812, 0x2009, 0x0240, 0x6814, 0x8000, 0x6816, 0x2011, 0x0260,
+ 0x1f04, 0x5ba0, 0x60c3, 0x0084, 0x080c, 0x5cc2, 0x0005, 0x0005,
+ 0x0086, 0x0096, 0x2029, 0x185c, 0x252c, 0x20a9, 0x0008, 0x2041,
+ 0x1c0e, 0x20e9, 0x0001, 0x28a0, 0x080c, 0x5e09, 0x20e1, 0x0000,
+ 0x2099, 0x026e, 0x4003, 0x20a9, 0x0008, 0x2011, 0x0007, 0xd5d4,
+ 0x0108, 0x9016, 0x2800, 0x9200, 0x200c, 0x91a6, 0xffff, 0x1148,
+ 0xd5d4, 0x0110, 0x8210, 0x0008, 0x8211, 0x1f04, 0x5bd2, 0x0804,
+ 0x5c41, 0x82ff, 0x1160, 0xd5d4, 0x0120, 0x91a6, 0x3fff, 0x0d90,
+ 0x0020, 0x91a6, 0x3fff, 0x0904, 0x5c41, 0x918d, 0xc000, 0x20a9,
+ 0x0010, 0x2019, 0x0001, 0xd5d4, 0x0110, 0x2019, 0x0010, 0x2120,
+ 0xd5d4, 0x0110, 0x8423, 0x0008, 0x8424, 0x1240, 0xd5d4, 0x0110,
+ 0x8319, 0x0008, 0x8318, 0x1f04, 0x5bf8, 0x04d8, 0x23a8, 0x2021,
+ 0x0001, 0x8426, 0x8425, 0x1f04, 0x5c0a, 0x2328, 0x8529, 0x92be,
+ 0x0007, 0x0158, 0x0006, 0x2039, 0x0007, 0x2200, 0x973a, 0x000e,
+ 0x27a8, 0x95a8, 0x0010, 0x1f04, 0x5c19, 0x755a, 0x95c8, 0x31f3,
+ 0x292d, 0x95ac, 0x00ff, 0x757e, 0x6532, 0x6536, 0x0016, 0x2508,
+ 0x080c, 0x26b6, 0x001e, 0x60e7, 0x0000, 0x65ea, 0x2018, 0x2304,
+ 0x9405, 0x201a, 0x7083, 0x0001, 0x20e9, 0x0000, 0x20a1, 0x024e,
+ 0x20e1, 0x0001, 0x2898, 0x20a9, 0x0008, 0x4003, 0x9085, 0x0001,
+ 0x0008, 0x9006, 0x009e, 0x008e, 0x0005, 0x0156, 0x01c6, 0x01d6,
+ 0x0136, 0x0146, 0x22a8, 0x20e1, 0x0000, 0x2099, 0x026e, 0x20e9,
+ 0x0000, 0x2011, 0x024e, 0x22a0, 0x4003, 0x014e, 0x013e, 0x01de,
+ 0x01ce, 0x015e, 0x2118, 0x9026, 0x2001, 0x0007, 0x939a, 0x0010,
+ 0x0218, 0x8420, 0x8001, 0x0cd0, 0x2118, 0x84ff, 0x0120, 0x939a,
+ 0x0010, 0x8421, 0x1de0, 0x2021, 0x0001, 0x83ff, 0x0118, 0x8423,
+ 0x8319, 0x1de8, 0x9238, 0x2029, 0x026e, 0x9528, 0x2504, 0x942c,
+ 0x11b8, 0x9405, 0x203a, 0x715a, 0x91a0, 0x31f3, 0x242d, 0x95ac,
+ 0x00ff, 0x757e, 0x6532, 0x6536, 0x0016, 0x2508, 0x080c, 0x26b6,
+ 0x001e, 0x60e7, 0x0000, 0x65ea, 0x7083, 0x0001, 0x9084, 0x0000,
+ 0x0005, 0x00e6, 0x2071, 0x1800, 0x7087, 0x0000, 0x00ee, 0x0005,
+ 0x00e6, 0x00f6, 0x2079, 0x0100, 0x2071, 0x0140, 0x080c, 0x5d4e,
+ 0x080c, 0x961a, 0x7004, 0x9084, 0x4000, 0x0110, 0x080c, 0x2b7f,
+ 0x0126, 0x2091, 0x8000, 0x2071, 0x1825, 0x2073, 0x0000, 0x7840,
+ 0x0026, 0x0016, 0x2009, 0x00f7, 0x080c, 0x5dab, 0x001e, 0x9094,
+ 0x0010, 0x9285, 0x0080, 0x7842, 0x7a42, 0x002e, 0x012e, 0x00fe,
+ 0x00ee, 0x0005, 0x0126, 0x2091, 0x8000, 0x080c, 0x29e9, 0x0228,
+ 0x2011, 0x0101, 0x2204, 0xc0c5, 0x2012, 0x2011, 0x19cc, 0x2013,
+ 0x0000, 0x708f, 0x0000, 0x012e, 0x60a3, 0x0056, 0x60a7, 0x9575,
+ 0x080c, 0x9611, 0x6144, 0xd184, 0x0120, 0x7194, 0x918d, 0x2000,
+ 0x0018, 0x7188, 0x918d, 0x1000, 0x2011, 0x1973, 0x2112, 0x2009,
+ 0x07d0, 0x2011, 0x5c98, 0x080c, 0x82eb, 0x0005, 0x0016, 0x0026,
+ 0x00c6, 0x0126, 0x2091, 0x8000, 0x080c, 0x9f70, 0x2009, 0x00f7,
+ 0x080c, 0x5dab, 0x2061, 0x19d5, 0x900e, 0x611a, 0x611e, 0x617a,
+ 0x617e, 0x2061, 0x1800, 0x6003, 0x0001, 0x2061, 0x0100, 0x6043,
+ 0x0090, 0x6043, 0x0010, 0x2009, 0x1973, 0x200b, 0x0000, 0x2009,
+ 0x002d, 0x2011, 0x5d1a, 0x080c, 0x824d, 0x012e, 0x00ce, 0x002e,
+ 0x001e, 0x0005, 0x00e6, 0x0006, 0x0126, 0x2091, 0x8000, 0x0471,
+ 0x2071, 0x0100, 0x080c, 0x961a, 0x2071, 0x0140, 0x7004, 0x9084,
+ 0x4000, 0x0110, 0x080c, 0x2b7f, 0x080c, 0x7186, 0x0188, 0x080c,
+ 0x71a1, 0x1170, 0x080c, 0x7484, 0x0016, 0x080c, 0x2785, 0x2001,
+ 0x1947, 0x2102, 0x001e, 0x080c, 0x747f, 0x080c, 0x709e, 0x0050,
+ 0x2009, 0x0001, 0x080c, 0x2a9d, 0x2001, 0x0001, 0x080c, 0x2616,
+ 0x080c, 0x5cee, 0x012e, 0x000e, 0x00ee, 0x0005, 0x2001, 0x180e,
+ 0x2004, 0xd0bc, 0x0158, 0x0026, 0x0036, 0x2011, 0x8017, 0x2001,
+ 0x1973, 0x201c, 0x080c, 0x4a17, 0x003e, 0x002e, 0x0005, 0x20a9,
+ 0x0012, 0x20e9, 0x0001, 0x20a1, 0x1c80, 0x080c, 0x5e09, 0x20e9,
+ 0x0000, 0x2099, 0x026e, 0x0099, 0x20a9, 0x0020, 0x080c, 0x5e03,
+ 0x2099, 0x0260, 0x20a1, 0x1c92, 0x0051, 0x20a9, 0x000e, 0x080c,
+ 0x5e06, 0x2099, 0x0260, 0x20a1, 0x1cb2, 0x0009, 0x0005, 0x0016,
+ 0x0026, 0x3410, 0x3308, 0x2104, 0x8007, 0x2012, 0x8108, 0x8210,
+ 0x1f04, 0x5d83, 0x002e, 0x001e, 0x0005, 0x080c, 0x9df2, 0x20e1,
+ 0x0001, 0x2099, 0x1c00, 0x20e9, 0x0000, 0x20a1, 0x0240, 0x20a9,
+ 0x000c, 0x4003, 0x0005, 0x080c, 0x9df2, 0x080c, 0x5e09, 0x20e1,
+ 0x0000, 0x2099, 0x0260, 0x20e9, 0x0000, 0x20a1, 0x0240, 0x20a9,
+ 0x000c, 0x4003, 0x0005, 0x00c6, 0x0006, 0x2061, 0x0100, 0x810f,
+ 0x2001, 0x1833, 0x2004, 0x9005, 0x1138, 0x2001, 0x1817, 0x2004,
+ 0x9084, 0x00ff, 0x9105, 0x0010, 0x9185, 0x00f7, 0x604a, 0x000e,
+ 0x00ce, 0x0005, 0x0016, 0x0046, 0x080c, 0x66c5, 0x0158, 0x9006,
+ 0x2020, 0x2009, 0x002a, 0x080c, 0xd837, 0x2001, 0x180c, 0x200c,
+ 0xc195, 0x2102, 0x2019, 0x002a, 0x900e, 0x080c, 0x3060, 0x080c,
+ 0xc459, 0x0140, 0x0036, 0x2019, 0xffff, 0x2021, 0x0007, 0x080c,
+ 0x4bb4, 0x003e, 0x004e, 0x001e, 0x0005, 0x080c, 0x5cee, 0x7097,
+ 0x0000, 0x708f, 0x0000, 0x0005, 0x0006, 0x2001, 0x180c, 0x2004,
+ 0xd09c, 0x0100, 0x000e, 0x0005, 0x0006, 0x0016, 0x0126, 0x2091,
+ 0x8000, 0x2001, 0x0101, 0x200c, 0x918d, 0x0006, 0x2102, 0x012e,
+ 0x001e, 0x000e, 0x0005, 0x2009, 0x0001, 0x0020, 0x2009, 0x0002,
+ 0x0008, 0x900e, 0x6814, 0x9084, 0xffc0, 0x910d, 0x6916, 0x0005,
+ 0x00f6, 0x0156, 0x0146, 0x01d6, 0x9006, 0x20a9, 0x0080, 0x20e9,
+ 0x0001, 0x20a1, 0x1c00, 0x4004, 0x2079, 0x1c00, 0x7803, 0x2200,
+ 0x7807, 0x00ef, 0x780f, 0x00ef, 0x7813, 0x0138, 0x7823, 0xffff,
+ 0x7827, 0xffff, 0x01de, 0x014e, 0x015e, 0x00fe, 0x0005, 0x2001,
+ 0x1800, 0x2003, 0x0001, 0x0005, 0x2001, 0x1981, 0x0118, 0x2003,
+ 0x0001, 0x0010, 0x2003, 0x0000, 0x0005, 0x0156, 0x20a9, 0x0800,
+ 0x2009, 0x1000, 0x9006, 0x200a, 0x8108, 0x1f04, 0x5e43, 0x015e,
+ 0x0005, 0x00d6, 0x0036, 0x0156, 0x0136, 0x0146, 0x2069, 0x185b,
+ 0x9006, 0xb802, 0xb8be, 0xb807, 0x0707, 0xb80a, 0xb80e, 0xb812,
+ 0x9198, 0x31f3, 0x231d, 0x939c, 0x00ff, 0xbb16, 0x0016, 0x0026,
+ 0xb8b2, 0x080c, 0x9f69, 0x1120, 0x9192, 0x007e, 0x1208, 0xbbb2,
+ 0x20a9, 0x0004, 0xb8b4, 0x20e8, 0xb9b8, 0x9198, 0x0006, 0x9006,
+ 0x23a0, 0x4004, 0x20a9, 0x0004, 0x9198, 0x000a, 0x23a0, 0x4004,
+ 0x002e, 0x001e, 0xb83e, 0xb842, 0xb84e, 0xb852, 0xb856, 0xb85a,
+ 0xb85e, 0xb862, 0xb866, 0xb86a, 0xb86f, 0x0100, 0xb872, 0xb876,
+ 0xb87a, 0xb88a, 0xb88e, 0xb893, 0x0008, 0xb896, 0xb89a, 0xb89e,
+ 0xb8ae, 0xb9a2, 0x0096, 0xb8a4, 0x904d, 0x0110, 0x080c, 0x1069,
+ 0xb8a7, 0x0000, 0x009e, 0x9006, 0xb84a, 0x6810, 0xb83a, 0x680c,
+ 0xb846, 0x6814, 0x9084, 0x00ff, 0xb842, 0x014e, 0x013e, 0x015e,
+ 0x003e, 0x00de, 0x0005, 0x0126, 0x2091, 0x8000, 0xa974, 0xae78,
+ 0x9684, 0x3fff, 0x9082, 0x4000, 0x1a04, 0x5f19, 0x9182, 0x0800,
+ 0x1a04, 0x5f1d, 0x2001, 0x180c, 0x2004, 0x9084, 0x0003, 0x1904,
+ 0x5f23, 0x9188, 0x1000, 0x2104, 0x905d, 0x0518, 0xb804, 0x9084,
+ 0x00ff, 0x908e, 0x0006, 0x1508, 0xb8a4, 0x900d, 0x1904, 0x5f35,
+ 0xb850, 0x900d, 0x1148, 0xa802, 0x2900, 0xb852, 0xb84e, 0x080c,
+ 0x8615, 0x9006, 0x012e, 0x0005, 0x00a6, 0x2150, 0x2900, 0xb002,
+ 0xa803, 0x0000, 0x00ae, 0xb852, 0x0c90, 0x2001, 0x0005, 0x900e,
+ 0x04b8, 0x2001, 0x0028, 0x900e, 0x0498, 0x9082, 0x0006, 0x1290,
+ 0x080c, 0x9f69, 0x1160, 0xb8a0, 0x9084, 0xff80, 0x1140, 0xb900,
+ 0xd1fc, 0x0990, 0x2001, 0x0029, 0x2009, 0x1000, 0x0408, 0x2001,
+ 0x0028, 0x00a8, 0x2009, 0x180c, 0x210c, 0xd18c, 0x0118, 0x2001,
+ 0x0004, 0x0068, 0xd184, 0x0118, 0x2001, 0x0004, 0x0040, 0x2001,
+ 0x0029, 0xb900, 0xd1fc, 0x0118, 0x2009, 0x1000, 0x0048, 0x900e,
0x0038, 0x2001, 0x0029, 0x900e, 0x0018, 0x2001, 0x0029, 0x900e,
- 0x9005, 0x00be, 0x0005, 0x0126, 0x2091, 0x8000, 0xb850, 0x900d,
- 0x0150, 0x2900, 0x0096, 0x2148, 0xa802, 0x009e, 0xa803, 0x0000,
- 0xb852, 0x012e, 0x0005, 0x2900, 0xb852, 0xb84e, 0xa803, 0x0000,
- 0x0cc0, 0x0126, 0x2091, 0x8000, 0xb84c, 0x9005, 0x0170, 0x00e6,
- 0x2071, 0x19c2, 0x7004, 0x9086, 0x0002, 0x0168, 0x00ee, 0xb84c,
- 0xa802, 0x2900, 0xb84e, 0x012e, 0x0005, 0x2900, 0xb852, 0xb84e,
- 0xa803, 0x0000, 0x0cc0, 0x701c, 0x9b06, 0x1d80, 0xb84c, 0x00a6,
- 0x2050, 0xb000, 0xa802, 0x2900, 0xb002, 0x00ae, 0x00ee, 0x012e,
- 0x0005, 0x0126, 0x2091, 0x8000, 0xb84c, 0x904d, 0x0130, 0xa800,
- 0x9005, 0x1108, 0xb852, 0xb84e, 0x9905, 0x012e, 0x0005, 0xb84c,
- 0x904d, 0x0130, 0xa800, 0x9005, 0x1108, 0xb852, 0xb84e, 0x9905,
- 0x0005, 0x00b6, 0x0126, 0x00c6, 0x0026, 0x2091, 0x8000, 0x6210,
- 0x2258, 0xba00, 0x9005, 0x0110, 0xc285, 0x0008, 0xc284, 0xba02,
- 0x002e, 0x00ce, 0x012e, 0x00be, 0x0005, 0x00b6, 0x0126, 0x00c6,
- 0x2091, 0x8000, 0x6210, 0x2258, 0xba04, 0x0006, 0x9086, 0x0006,
- 0x1170, 0xb89c, 0xd0ac, 0x0158, 0x080c, 0x66c6, 0x0140, 0x9284,
- 0xff00, 0x8007, 0x9086, 0x0007, 0x1110, 0x2011, 0x0600, 0x000e,
- 0x9294, 0xff00, 0x9215, 0xba06, 0x0006, 0x9086, 0x0006, 0x1120,
- 0xba90, 0x82ff, 0x090c, 0x0e02, 0x000e, 0x00ce, 0x012e, 0x00be,
- 0x0005, 0x00b6, 0x0126, 0x00c6, 0x2091, 0x8000, 0x6210, 0x2258,
- 0xba04, 0x0006, 0x9086, 0x0006, 0x1168, 0xb89c, 0xd0a4, 0x0150,
- 0x080c, 0x66c2, 0x1138, 0x9284, 0x00ff, 0x9086, 0x0007, 0x1110,
- 0x2011, 0x0006, 0x000e, 0x9294, 0x00ff, 0x8007, 0x9215, 0xba06,
- 0x00ce, 0x012e, 0x00be, 0x0005, 0x9182, 0x0800, 0x0218, 0x9085,
- 0x0001, 0x0005, 0x00d6, 0x0026, 0x9190, 0x1000, 0x2204, 0x905d,
- 0x1180, 0x0096, 0x080c, 0x1043, 0x2958, 0x009e, 0x0160, 0x2b00,
- 0x2012, 0xb85c, 0xb8ba, 0xb860, 0xb8b6, 0x9006, 0xb8a6, 0x080c,
- 0x5e4a, 0x9006, 0x0010, 0x9085, 0x0001, 0x002e, 0x00de, 0x0005,
- 0x00b6, 0x0096, 0x0126, 0x2091, 0x8000, 0x0026, 0x9182, 0x0800,
- 0x0218, 0x9085, 0x0001, 0x0458, 0x00d6, 0x9190, 0x1000, 0x2204,
- 0x905d, 0x0518, 0x2013, 0x0000, 0xb8a4, 0x904d, 0x0110, 0x080c,
- 0x1075, 0x00d6, 0x00c6, 0xb8ac, 0x2060, 0x8cff, 0x0168, 0x600c,
- 0x0006, 0x6014, 0x2048, 0x080c, 0xbd3b, 0x0110, 0x080c, 0x0ff5,
- 0x080c, 0x9fd5, 0x00ce, 0x0c88, 0x00ce, 0x00de, 0x2b48, 0xb8b8,
- 0xb85e, 0xb8b4, 0xb862, 0x080c, 0x1085, 0x00de, 0x9006, 0x002e,
- 0x012e, 0x009e, 0x00be, 0x0005, 0x0016, 0x9182, 0x0800, 0x0218,
- 0x9085, 0x0001, 0x0030, 0x9188, 0x1000, 0x2104, 0x905d, 0x0dc0,
- 0x9006, 0x001e, 0x0005, 0x00d6, 0x0156, 0x0136, 0x0146, 0x9006,
- 0xb80a, 0xb80e, 0xb800, 0xc08c, 0xb802, 0x080c, 0x717f, 0x1510,
- 0xb8a0, 0x9086, 0x007e, 0x0120, 0x080c, 0x9f54, 0x11d8, 0x0078,
- 0x7040, 0xd0e4, 0x01b8, 0x00c6, 0x2061, 0x195c, 0x7048, 0x2062,
- 0x704c, 0x6006, 0x7050, 0x600a, 0x7054, 0x600e, 0x00ce, 0x703c,
- 0x2069, 0x0140, 0x9005, 0x1110, 0x2001, 0x0001, 0x6886, 0x2069,
- 0x1800, 0x68b2, 0x7040, 0xb85e, 0x7048, 0xb862, 0x704c, 0xb866,
- 0x20e1, 0x0000, 0x2099, 0x0276, 0xb8b4, 0x20e8, 0xb8b8, 0x9088,
- 0x000a, 0x21a0, 0x20a9, 0x0004, 0x4003, 0x2099, 0x027a, 0x9088,
- 0x0006, 0x21a0, 0x20a9, 0x0004, 0x4003, 0x2069, 0x0200, 0x6817,
- 0x0001, 0x7040, 0xb86a, 0x7144, 0xb96e, 0x7048, 0xb872, 0x7050,
- 0xb876, 0x2069, 0x0200, 0x6817, 0x0000, 0xb8a0, 0x9086, 0x007e,
- 0x1110, 0x7144, 0xb96e, 0x9182, 0x0211, 0x1218, 0x2009, 0x0008,
- 0x0400, 0x9182, 0x0259, 0x1218, 0x2009, 0x0007, 0x00d0, 0x9182,
- 0x02c1, 0x1218, 0x2009, 0x0006, 0x00a0, 0x9182, 0x0349, 0x1218,
- 0x2009, 0x0005, 0x0070, 0x9182, 0x0421, 0x1218, 0x2009, 0x0004,
- 0x0040, 0x9182, 0x0581, 0x1218, 0x2009, 0x0003, 0x0010, 0x2009,
- 0x0002, 0xb992, 0x014e, 0x013e, 0x015e, 0x00de, 0x0005, 0x0016,
- 0x0026, 0x00e6, 0x2071, 0x0260, 0x7034, 0xb896, 0x703c, 0xb89a,
- 0x7054, 0xb89e, 0x0036, 0xbbbc, 0xc384, 0xba00, 0x2009, 0x187b,
- 0x210c, 0xd0bc, 0x0120, 0xd1ec, 0x0110, 0xc2ad, 0x0008, 0xc2ac,
- 0xd0c4, 0x0148, 0xd1e4, 0x0138, 0xc2bd, 0xd0cc, 0x0128, 0xd38c,
- 0x1108, 0xc385, 0x0008, 0xc2bc, 0xba02, 0xbbbe, 0x003e, 0x00ee,
- 0x002e, 0x001e, 0x0005, 0x0096, 0x0126, 0x2091, 0x8000, 0xb8a4,
- 0x904d, 0x0578, 0xa900, 0x81ff, 0x15c0, 0xaa04, 0x9282, 0x0010,
- 0x16c8, 0x0136, 0x0146, 0x01c6, 0x01d6, 0x8906, 0x8006, 0x8007,
- 0x908c, 0x003f, 0x21e0, 0x9084, 0xffc0, 0x9080, 0x0004, 0x2098,
- 0x2009, 0x0010, 0x20a9, 0x0001, 0x4002, 0x9086, 0xffff, 0x0120,
- 0x8109, 0x1dd0, 0x080c, 0x0e02, 0x3c00, 0x20e8, 0x3300, 0x8001,
- 0x20a0, 0x4604, 0x8210, 0xaa06, 0x01de, 0x01ce, 0x014e, 0x013e,
- 0x0060, 0x080c, 0x1043, 0x0170, 0x2900, 0xb8a6, 0xa803, 0x0000,
- 0x080c, 0x6560, 0xa807, 0x0001, 0xae12, 0x9085, 0x0001, 0x012e,
- 0x009e, 0x0005, 0x9006, 0x0cd8, 0x0126, 0x2091, 0x8000, 0x0096,
- 0xb8a4, 0x904d, 0x0188, 0xa800, 0x9005, 0x1150, 0x080c, 0x656f,
- 0x1158, 0xa804, 0x908a, 0x0002, 0x0218, 0x8001, 0xa806, 0x0020,
- 0x080c, 0x1075, 0xb8a7, 0x0000, 0x009e, 0x012e, 0x0005, 0x0126,
- 0x2091, 0x8000, 0x080c, 0x8616, 0x012e, 0x0005, 0x901e, 0x0010,
- 0x2019, 0x0001, 0x900e, 0x0126, 0x2091, 0x8000, 0xb84c, 0x2048,
- 0xb800, 0xd0dc, 0x1170, 0x89ff, 0x0500, 0x83ff, 0x0120, 0xa878,
- 0x9606, 0x0158, 0x0030, 0xa86c, 0x9406, 0x1118, 0xa870, 0x9506,
- 0x0120, 0x2908, 0xa800, 0x2048, 0x0c70, 0x080c, 0x9940, 0xaa00,
- 0xb84c, 0x9906, 0x1110, 0xba4e, 0x0020, 0x00a6, 0x2150, 0xb202,
- 0x00ae, 0x82ff, 0x1110, 0xb952, 0x89ff, 0x012e, 0x0005, 0x9016,
- 0x0489, 0x1110, 0x2011, 0x0001, 0x0005, 0x080c, 0x65c4, 0x0128,
- 0x080c, 0xbdf8, 0x0010, 0x9085, 0x0001, 0x0005, 0x080c, 0x65c4,
- 0x0128, 0x080c, 0xbd9d, 0x0010, 0x9085, 0x0001, 0x0005, 0x080c,
- 0x65c4, 0x0128, 0x080c, 0xbdf5, 0x0010, 0x9085, 0x0001, 0x0005,
- 0x080c, 0x65c4, 0x0128, 0x080c, 0xbdbc, 0x0010, 0x9085, 0x0001,
- 0x0005, 0x080c, 0x65c4, 0x0128, 0x080c, 0xbe3b, 0x0010, 0x9085,
- 0x0001, 0x0005, 0xb8a4, 0x900d, 0x1118, 0x9085, 0x0001, 0x0005,
- 0x0136, 0x01c6, 0xa800, 0x9005, 0x11b8, 0x890e, 0x810e, 0x810f,
- 0x9184, 0x003f, 0x20e0, 0x9184, 0xffc0, 0x9080, 0x0004, 0x2098,
- 0x20a9, 0x0001, 0x2009, 0x0010, 0x4002, 0x9606, 0x0128, 0x8109,
- 0x1dd8, 0x9085, 0x0001, 0x0008, 0x9006, 0x01ce, 0x013e, 0x0005,
- 0x0146, 0x01d6, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0004, 0x20a0,
- 0x20a9, 0x0010, 0x2009, 0xffff, 0x4104, 0x01de, 0x014e, 0x0136,
+ 0x9005, 0x012e, 0x0005, 0x2001, 0x180c, 0x2004, 0xd084, 0x19d0,
+ 0x9188, 0x1000, 0x2104, 0x905d, 0x09a8, 0x080c, 0x66c9, 0x1990,
+ 0xb800, 0xd0bc, 0x0978, 0x0804, 0x5ecc, 0x080c, 0x653f, 0x0904,
+ 0x5ee5, 0x0804, 0x5ed0, 0x00b6, 0x00e6, 0x0126, 0x2091, 0x8000,
+ 0xa974, 0x9182, 0x0800, 0x1a04, 0x5fb9, 0x9188, 0x1000, 0x2104,
+ 0x905d, 0x0904, 0x5f91, 0xb8a0, 0x9086, 0x007f, 0x0190, 0xa87c,
+ 0xd0fc, 0x1178, 0x080c, 0x66d1, 0x0160, 0xa994, 0x81ff, 0x0130,
+ 0x908e, 0x0004, 0x0130, 0x908e, 0x0005, 0x0118, 0x080c, 0x66c9,
+ 0x1598, 0xa87c, 0xd0fc, 0x01e0, 0xa894, 0x9005, 0x01c8, 0x2060,
+ 0x0026, 0x2010, 0x080c, 0xbd3c, 0x002e, 0x1120, 0x2001, 0x0008,
+ 0x0804, 0x5fbb, 0x6020, 0x9086, 0x000a, 0x0120, 0x2001, 0x0008,
+ 0x0804, 0x5fbb, 0x601a, 0x6003, 0x0008, 0x2900, 0x6016, 0x0058,
+ 0x080c, 0x9f94, 0x05e8, 0x2b00, 0x6012, 0x2900, 0x6016, 0x600b,
+ 0xffff, 0x6023, 0x000a, 0x2009, 0x0003, 0x080c, 0xa068, 0x9006,
+ 0x0458, 0x2001, 0x0028, 0x0438, 0x9082, 0x0006, 0x1290, 0x080c,
+ 0x9f69, 0x1160, 0xb8a0, 0x9084, 0xff80, 0x1140, 0xb900, 0xd1fc,
+ 0x0900, 0x2001, 0x0029, 0x2009, 0x1000, 0x00a8, 0x2001, 0x0028,
+ 0x0090, 0x2009, 0x180c, 0x210c, 0xd18c, 0x0118, 0x2001, 0x0004,
+ 0x0050, 0xd184, 0x0118, 0x2001, 0x0004, 0x0028, 0x2001, 0x0029,
+ 0x0010, 0x2001, 0x0029, 0x9005, 0x012e, 0x00ee, 0x00be, 0x0005,
+ 0x2001, 0x002c, 0x0cc0, 0x00f6, 0x00b6, 0x0126, 0x2091, 0x8000,
+ 0xa8e0, 0x9005, 0x1550, 0xa8dc, 0x9082, 0x0101, 0x1630, 0xa8c8,
+ 0x9005, 0x1518, 0xa8c4, 0x9082, 0x0101, 0x12f8, 0xa974, 0x2079,
+ 0x1800, 0x9182, 0x0800, 0x12e8, 0x7830, 0x9084, 0x0003, 0x1130,
+ 0xaa98, 0xab94, 0xa878, 0x9084, 0x0007, 0x00ea, 0x7930, 0xd18c,
+ 0x0118, 0x2001, 0x0004, 0x0038, 0xd184, 0x0118, 0x2001, 0x0004,
+ 0x0010, 0x2001, 0x0029, 0x900e, 0x0038, 0x2001, 0x002c, 0x900e,
+ 0x0018, 0x2001, 0x0029, 0x900e, 0x9006, 0x0008, 0x9005, 0x012e,
+ 0x00be, 0x00fe, 0x0005, 0x6050, 0x600b, 0x6022, 0x6050, 0x6050,
+ 0x6050, 0x6050, 0x6050, 0x2100, 0x9082, 0x007e, 0x1278, 0x080c,
+ 0x6343, 0x0148, 0x9046, 0xb810, 0x9306, 0x1904, 0x6058, 0xb814,
+ 0x9206, 0x15f0, 0x0028, 0xbb12, 0xba16, 0x0010, 0x080c, 0x48d1,
+ 0x0150, 0x04b0, 0x080c, 0x63a3, 0x1598, 0xb810, 0x9306, 0x1580,
+ 0xb814, 0x9206, 0x1568, 0x080c, 0x9f94, 0x0530, 0x2b00, 0x6012,
+ 0x080c, 0xc1ca, 0x2900, 0x6016, 0x600b, 0xffff, 0x6023, 0x000a,
+ 0xa878, 0x9086, 0x0001, 0x1170, 0x080c, 0x3095, 0x9006, 0x080c,
+ 0x62e0, 0x2001, 0x0002, 0x080c, 0x62f4, 0x2001, 0x0200, 0xb86e,
+ 0xb893, 0x0002, 0x2009, 0x0003, 0x080c, 0xa068, 0x9006, 0x0068,
+ 0x2001, 0x0001, 0x900e, 0x0038, 0x2001, 0x002c, 0x900e, 0x0018,
+ 0x2001, 0x0028, 0x900e, 0x9005, 0x0000, 0x012e, 0x00be, 0x00fe,
+ 0x0005, 0x00b6, 0x00f6, 0x00e6, 0x0126, 0x2091, 0x8000, 0xa894,
+ 0x90c6, 0x0015, 0x0904, 0x6231, 0x90c6, 0x0056, 0x0904, 0x6235,
+ 0x90c6, 0x0066, 0x0904, 0x6239, 0x90c6, 0x0067, 0x0904, 0x623d,
+ 0x90c6, 0x0068, 0x0904, 0x6241, 0x90c6, 0x0071, 0x0904, 0x6245,
+ 0x90c6, 0x0074, 0x0904, 0x6249, 0x90c6, 0x007c, 0x0904, 0x624d,
+ 0x90c6, 0x007e, 0x0904, 0x6251, 0x90c6, 0x0037, 0x0904, 0x6255,
+ 0x9016, 0x2079, 0x1800, 0xa974, 0x9186, 0x00ff, 0x0904, 0x622c,
+ 0x9182, 0x0800, 0x1a04, 0x622c, 0x080c, 0x63a3, 0x1198, 0xb804,
+ 0x9084, 0x00ff, 0x9082, 0x0006, 0x1268, 0xa894, 0x90c6, 0x006f,
+ 0x0148, 0x080c, 0x9f69, 0x1904, 0x6215, 0xb8a0, 0x9084, 0xff80,
+ 0x1904, 0x6215, 0xa894, 0x90c6, 0x006f, 0x0158, 0x90c6, 0x005e,
+ 0x0904, 0x6175, 0x90c6, 0x0064, 0x0904, 0x619e, 0x2008, 0x0804,
+ 0x6138, 0xa998, 0xa8b0, 0x2040, 0x080c, 0x9f69, 0x1120, 0x9182,
+ 0x007f, 0x0a04, 0x6138, 0x9186, 0x00ff, 0x0904, 0x6138, 0x9182,
+ 0x0800, 0x1a04, 0x6138, 0xaaa0, 0xab9c, 0x7878, 0x9306, 0x11a8,
+ 0x787c, 0x0096, 0x924e, 0x1128, 0x2208, 0x2310, 0x009e, 0x0804,
+ 0x6138, 0x080c, 0x9f69, 0x1140, 0x99cc, 0xff00, 0x009e, 0x1128,
+ 0x2208, 0x2310, 0x0804, 0x6138, 0x009e, 0x080c, 0x48d1, 0x0904,
+ 0x6141, 0x900e, 0x9016, 0x90c6, 0x4000, 0x1558, 0x0006, 0x080c,
+ 0x65c3, 0x1108, 0xc185, 0xb800, 0xd0bc, 0x0108, 0xc18d, 0x20a9,
+ 0x0004, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0031, 0x20a0, 0xb8b4,
+ 0x20e0, 0xb8b8, 0x9080, 0x0006, 0x2098, 0x080c, 0x0fb4, 0x20a9,
+ 0x0004, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0035, 0x20a0, 0xb8b4,
+ 0x20e0, 0xb8b8, 0x9080, 0x000a, 0x2098, 0x080c, 0x0fb4, 0x000e,
+ 0x00c8, 0x90c6, 0x4007, 0x1110, 0x2408, 0x00a0, 0x90c6, 0x4008,
+ 0x1118, 0x2708, 0x2610, 0x0070, 0x90c6, 0x4009, 0x1108, 0x0050,
+ 0x90c6, 0x4006, 0x0138, 0x2001, 0x4005, 0x2009, 0x000a, 0x0010,
+ 0x2001, 0x4006, 0xa896, 0xa99a, 0xaa9e, 0x2001, 0x0030, 0x900e,
+ 0x0470, 0x080c, 0x9f94, 0x1130, 0x2001, 0x4005, 0x2009, 0x0003,
+ 0x9016, 0x0c80, 0x2b00, 0x6012, 0x080c, 0xc1ca, 0x2900, 0x6016,
+ 0x6023, 0x0001, 0xa868, 0xd88c, 0x0108, 0xc0f5, 0xa86a, 0x0126,
+ 0x2091, 0x8000, 0x080c, 0x3095, 0x012e, 0x9006, 0x080c, 0x62e0,
+ 0x2001, 0x0002, 0x080c, 0x62f4, 0x2009, 0x0002, 0x080c, 0xa068,
+ 0xa8b0, 0xd094, 0x0118, 0xb8bc, 0xc08d, 0xb8be, 0x9006, 0x9005,
+ 0x012e, 0x00ee, 0x00fe, 0x00be, 0x0005, 0x080c, 0x54ef, 0x0118,
+ 0x2009, 0x0007, 0x00f8, 0xa998, 0xaeb0, 0x080c, 0x63a3, 0x1904,
+ 0x6133, 0x9186, 0x007f, 0x0130, 0x080c, 0x66c9, 0x0118, 0x2009,
+ 0x0009, 0x0080, 0x0096, 0x080c, 0x1037, 0x1120, 0x009e, 0x2009,
+ 0x0002, 0x0040, 0x2900, 0x009e, 0xa806, 0x080c, 0xbf36, 0x19b0,
+ 0x2009, 0x0003, 0x2001, 0x4005, 0x0804, 0x613a, 0xa998, 0xaeb0,
+ 0x080c, 0x63a3, 0x1904, 0x6133, 0x0096, 0x080c, 0x1037, 0x1128,
+ 0x009e, 0x2009, 0x0002, 0x0804, 0x61f2, 0x2900, 0x009e, 0xa806,
+ 0x0096, 0x2048, 0x20a9, 0x002b, 0xb8b4, 0x20e0, 0xb8b8, 0x2098,
+ 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0002, 0x20a0, 0x4003, 0x20a9,
+ 0x0008, 0x9080, 0x0006, 0x20a0, 0xbbb8, 0x9398, 0x0006, 0x2398,
+ 0x080c, 0x0fb4, 0x009e, 0xa87b, 0x0000, 0xa883, 0x0000, 0xa897,
+ 0x4000, 0xd684, 0x1168, 0x080c, 0x54db, 0xd0b4, 0x1118, 0xa89b,
+ 0x000b, 0x00e0, 0xb800, 0xd08c, 0x0118, 0xa89b, 0x000c, 0x00b0,
+ 0x080c, 0x66c9, 0x0118, 0xa89b, 0x0009, 0x0080, 0x080c, 0x54ef,
+ 0x0118, 0xa89b, 0x0007, 0x0050, 0x080c, 0xbf19, 0x1904, 0x616e,
+ 0x2009, 0x0003, 0x2001, 0x4005, 0x0804, 0x613a, 0xa87b, 0x0030,
+ 0xa897, 0x4005, 0xa804, 0x8006, 0x8006, 0x8007, 0x90bc, 0x003f,
+ 0x9084, 0xffc0, 0x9080, 0x0002, 0x2009, 0x002b, 0xaaa0, 0xab9c,
+ 0xaca8, 0xada4, 0x2031, 0x0000, 0x2041, 0x128e, 0x080c, 0xa4f1,
+ 0x1904, 0x616e, 0x2009, 0x0002, 0x08e8, 0x2001, 0x0028, 0x900e,
+ 0x0804, 0x616f, 0x2009, 0x180c, 0x210c, 0xd18c, 0x0118, 0x2001,
+ 0x0004, 0x0038, 0xd184, 0x0118, 0x2001, 0x0004, 0x0010, 0x2001,
+ 0x0029, 0x900e, 0x0804, 0x616f, 0x2001, 0x0029, 0x900e, 0x0804,
+ 0x616f, 0x080c, 0x3624, 0x0804, 0x6170, 0x080c, 0x5206, 0x0804,
+ 0x6170, 0x080c, 0x448c, 0x0804, 0x6170, 0x080c, 0x4505, 0x0804,
+ 0x6170, 0x080c, 0x4561, 0x0804, 0x6170, 0x080c, 0x498d, 0x0804,
+ 0x6170, 0x080c, 0x4c36, 0x0804, 0x6170, 0x080c, 0x4e6d, 0x0804,
+ 0x6170, 0x080c, 0x5066, 0x0804, 0x6170, 0x080c, 0x384d, 0x0804,
+ 0x6170, 0x00b6, 0xa974, 0xae78, 0x9684, 0x3fff, 0x9082, 0x4000,
+ 0x1618, 0x9182, 0x0800, 0x1268, 0x9188, 0x1000, 0x2104, 0x905d,
+ 0x0140, 0x080c, 0x66c9, 0x1148, 0x00e9, 0x080c, 0x64ce, 0x9006,
+ 0x00b0, 0x2001, 0x0028, 0x900e, 0x0090, 0x9082, 0x0006, 0x1240,
+ 0xb900, 0xd1fc, 0x0d88, 0x2001, 0x0029, 0x2009, 0x1000, 0x0038,
+ 0x2001, 0x0029, 0x900e, 0x0018, 0x2001, 0x0029, 0x900e, 0x9005,
+ 0x00be, 0x0005, 0x0126, 0x2091, 0x8000, 0xb850, 0x900d, 0x0150,
+ 0x2900, 0x0096, 0x2148, 0xa802, 0x009e, 0xa803, 0x0000, 0xb852,
+ 0x012e, 0x0005, 0x2900, 0xb852, 0xb84e, 0xa803, 0x0000, 0x0cc0,
+ 0x0126, 0x2091, 0x8000, 0xb84c, 0x9005, 0x0170, 0x00e6, 0x2071,
+ 0x19c2, 0x7004, 0x9086, 0x0002, 0x0168, 0x00ee, 0xb84c, 0xa802,
+ 0x2900, 0xb84e, 0x012e, 0x0005, 0x2900, 0xb852, 0xb84e, 0xa803,
+ 0x0000, 0x0cc0, 0x701c, 0x9b06, 0x1d80, 0xb84c, 0x00a6, 0x2050,
+ 0xb000, 0xa802, 0x2900, 0xb002, 0x00ae, 0x00ee, 0x012e, 0x0005,
+ 0x0126, 0x2091, 0x8000, 0xb84c, 0x904d, 0x0130, 0xa800, 0x9005,
+ 0x1108, 0xb852, 0xb84e, 0x9905, 0x012e, 0x0005, 0xb84c, 0x904d,
+ 0x0130, 0xa800, 0x9005, 0x1108, 0xb852, 0xb84e, 0x9905, 0x0005,
+ 0x00b6, 0x0126, 0x00c6, 0x0026, 0x2091, 0x8000, 0x6210, 0x2258,
+ 0xba00, 0x9005, 0x0110, 0xc285, 0x0008, 0xc284, 0xba02, 0x002e,
+ 0x00ce, 0x012e, 0x00be, 0x0005, 0x00b6, 0x0126, 0x00c6, 0x2091,
+ 0x8000, 0x6210, 0x2258, 0xba04, 0x0006, 0x9086, 0x0006, 0x1170,
+ 0xb89c, 0xd0ac, 0x0158, 0x080c, 0x66c5, 0x0140, 0x9284, 0xff00,
+ 0x8007, 0x9086, 0x0007, 0x1110, 0x2011, 0x0600, 0x000e, 0x9294,
+ 0xff00, 0x9215, 0xba06, 0x0006, 0x9086, 0x0006, 0x1120, 0xba90,
+ 0x82ff, 0x090c, 0x0df6, 0x000e, 0x00ce, 0x012e, 0x00be, 0x0005,
+ 0x00b6, 0x0126, 0x00c6, 0x2091, 0x8000, 0x6210, 0x2258, 0xba04,
+ 0x0006, 0x9086, 0x0006, 0x1168, 0xb89c, 0xd0a4, 0x0150, 0x080c,
+ 0x66c1, 0x1138, 0x9284, 0x00ff, 0x9086, 0x0007, 0x1110, 0x2011,
+ 0x0006, 0x000e, 0x9294, 0x00ff, 0x8007, 0x9215, 0xba06, 0x00ce,
+ 0x012e, 0x00be, 0x0005, 0x9182, 0x0800, 0x0218, 0x9085, 0x0001,
+ 0x0005, 0x00d6, 0x0026, 0x9190, 0x1000, 0x2204, 0x905d, 0x1180,
+ 0x0096, 0x080c, 0x1037, 0x2958, 0x009e, 0x0160, 0x2b00, 0x2012,
+ 0xb85c, 0xb8ba, 0xb860, 0xb8b6, 0x9006, 0xb8a6, 0x080c, 0x5e49,
+ 0x9006, 0x0010, 0x9085, 0x0001, 0x002e, 0x00de, 0x0005, 0x00b6,
+ 0x0096, 0x0126, 0x2091, 0x8000, 0x0026, 0x9182, 0x0800, 0x0218,
+ 0x9085, 0x0001, 0x0458, 0x00d6, 0x9190, 0x1000, 0x2204, 0x905d,
+ 0x0518, 0x2013, 0x0000, 0xb8a4, 0x904d, 0x0110, 0x080c, 0x1069,
+ 0x00d6, 0x00c6, 0xb8ac, 0x2060, 0x8cff, 0x0168, 0x600c, 0x0006,
+ 0x6014, 0x2048, 0x080c, 0xbd4e, 0x0110, 0x080c, 0x0fe9, 0x080c,
+ 0x9fea, 0x00ce, 0x0c88, 0x00ce, 0x00de, 0x2b48, 0xb8b8, 0xb85e,
+ 0xb8b4, 0xb862, 0x080c, 0x1079, 0x00de, 0x9006, 0x002e, 0x012e,
+ 0x009e, 0x00be, 0x0005, 0x0016, 0x9182, 0x0800, 0x0218, 0x9085,
+ 0x0001, 0x0030, 0x9188, 0x1000, 0x2104, 0x905d, 0x0dc0, 0x9006,
+ 0x001e, 0x0005, 0x00d6, 0x0156, 0x0136, 0x0146, 0x9006, 0xb80a,
+ 0xb80e, 0xb800, 0xc08c, 0xb802, 0x080c, 0x717e, 0x1510, 0xb8a0,
+ 0x9086, 0x007e, 0x0120, 0x080c, 0x9f69, 0x11d8, 0x0078, 0x7040,
+ 0xd0e4, 0x01b8, 0x00c6, 0x2061, 0x195c, 0x7048, 0x2062, 0x704c,
+ 0x6006, 0x7050, 0x600a, 0x7054, 0x600e, 0x00ce, 0x703c, 0x2069,
+ 0x0140, 0x9005, 0x1110, 0x2001, 0x0001, 0x6886, 0x2069, 0x1800,
+ 0x68b2, 0x7040, 0xb85e, 0x7048, 0xb862, 0x704c, 0xb866, 0x20e1,
+ 0x0000, 0x2099, 0x0276, 0xb8b4, 0x20e8, 0xb8b8, 0x9088, 0x000a,
+ 0x21a0, 0x20a9, 0x0004, 0x4003, 0x2099, 0x027a, 0x9088, 0x0006,
+ 0x21a0, 0x20a9, 0x0004, 0x4003, 0x2069, 0x0200, 0x6817, 0x0001,
+ 0x7040, 0xb86a, 0x7144, 0xb96e, 0x7048, 0xb872, 0x7050, 0xb876,
+ 0x2069, 0x0200, 0x6817, 0x0000, 0xb8a0, 0x9086, 0x007e, 0x1110,
+ 0x7144, 0xb96e, 0x9182, 0x0211, 0x1218, 0x2009, 0x0008, 0x0400,
+ 0x9182, 0x0259, 0x1218, 0x2009, 0x0007, 0x00d0, 0x9182, 0x02c1,
+ 0x1218, 0x2009, 0x0006, 0x00a0, 0x9182, 0x0349, 0x1218, 0x2009,
+ 0x0005, 0x0070, 0x9182, 0x0421, 0x1218, 0x2009, 0x0004, 0x0040,
+ 0x9182, 0x0581, 0x1218, 0x2009, 0x0003, 0x0010, 0x2009, 0x0002,
+ 0xb992, 0x014e, 0x013e, 0x015e, 0x00de, 0x0005, 0x0016, 0x0026,
+ 0x00e6, 0x2071, 0x0260, 0x7034, 0xb896, 0x703c, 0xb89a, 0x7054,
+ 0xb89e, 0x0036, 0xbbbc, 0xc384, 0xba00, 0x2009, 0x187b, 0x210c,
+ 0xd0bc, 0x0120, 0xd1ec, 0x0110, 0xc2ad, 0x0008, 0xc2ac, 0xd0c4,
+ 0x0148, 0xd1e4, 0x0138, 0xc2bd, 0xd0cc, 0x0128, 0xd38c, 0x1108,
+ 0xc385, 0x0008, 0xc2bc, 0xba02, 0xbbbe, 0x003e, 0x00ee, 0x002e,
+ 0x001e, 0x0005, 0x0096, 0x0126, 0x2091, 0x8000, 0xb8a4, 0x904d,
+ 0x0578, 0xa900, 0x81ff, 0x15c0, 0xaa04, 0x9282, 0x0010, 0x16c8,
+ 0x0136, 0x0146, 0x01c6, 0x01d6, 0x8906, 0x8006, 0x8007, 0x908c,
+ 0x003f, 0x21e0, 0x9084, 0xffc0, 0x9080, 0x0004, 0x2098, 0x2009,
+ 0x0010, 0x20a9, 0x0001, 0x4002, 0x9086, 0xffff, 0x0120, 0x8109,
+ 0x1dd0, 0x080c, 0x0df6, 0x3c00, 0x20e8, 0x3300, 0x8001, 0x20a0,
+ 0x4604, 0x8210, 0xaa06, 0x01de, 0x01ce, 0x014e, 0x013e, 0x0060,
+ 0x080c, 0x1037, 0x0170, 0x2900, 0xb8a6, 0xa803, 0x0000, 0x080c,
+ 0x655f, 0xa807, 0x0001, 0xae12, 0x9085, 0x0001, 0x012e, 0x009e,
+ 0x0005, 0x9006, 0x0cd8, 0x0126, 0x2091, 0x8000, 0x0096, 0xb8a4,
+ 0x904d, 0x0188, 0xa800, 0x9005, 0x1150, 0x080c, 0x656e, 0x1158,
+ 0xa804, 0x908a, 0x0002, 0x0218, 0x8001, 0xa806, 0x0020, 0x080c,
+ 0x1069, 0xb8a7, 0x0000, 0x009e, 0x012e, 0x0005, 0x0126, 0x2091,
+ 0x8000, 0x080c, 0x8615, 0x012e, 0x0005, 0x901e, 0x0010, 0x2019,
+ 0x0001, 0x900e, 0x0126, 0x2091, 0x8000, 0xb84c, 0x2048, 0xb800,
+ 0xd0dc, 0x1170, 0x89ff, 0x0500, 0x83ff, 0x0120, 0xa878, 0x9606,
+ 0x0158, 0x0030, 0xa86c, 0x9406, 0x1118, 0xa870, 0x9506, 0x0120,
+ 0x2908, 0xa800, 0x2048, 0x0c70, 0x080c, 0x9955, 0xaa00, 0xb84c,
+ 0x9906, 0x1110, 0xba4e, 0x0020, 0x00a6, 0x2150, 0xb202, 0x00ae,
+ 0x82ff, 0x1110, 0xb952, 0x89ff, 0x012e, 0x0005, 0x9016, 0x0489,
+ 0x1110, 0x2011, 0x0001, 0x0005, 0x080c, 0x65c3, 0x0128, 0x080c,
+ 0xbe0b, 0x0010, 0x9085, 0x0001, 0x0005, 0x080c, 0x65c3, 0x0128,
+ 0x080c, 0xbdb0, 0x0010, 0x9085, 0x0001, 0x0005, 0x080c, 0x65c3,
+ 0x0128, 0x080c, 0xbe08, 0x0010, 0x9085, 0x0001, 0x0005, 0x080c,
+ 0x65c3, 0x0128, 0x080c, 0xbdcf, 0x0010, 0x9085, 0x0001, 0x0005,
+ 0x080c, 0x65c3, 0x0128, 0x080c, 0xbe4e, 0x0010, 0x9085, 0x0001,
+ 0x0005, 0xb8a4, 0x900d, 0x1118, 0x9085, 0x0001, 0x0005, 0x0136,
0x01c6, 0xa800, 0x9005, 0x11b8, 0x890e, 0x810e, 0x810f, 0x9184,
0x003f, 0x20e0, 0x9184, 0xffc0, 0x9080, 0x0004, 0x2098, 0x20a9,
0x0001, 0x2009, 0x0010, 0x4002, 0x9606, 0x0128, 0x8109, 0x1dd8,
- 0x9085, 0x0001, 0x0068, 0x0146, 0x01d6, 0x3300, 0x8001, 0x20a0,
- 0x3c00, 0x20e8, 0x2001, 0xffff, 0x4004, 0x01de, 0x014e, 0x9006,
- 0x01ce, 0x013e, 0x0005, 0x0096, 0x0126, 0x2091, 0x8000, 0xb8a4,
- 0x904d, 0x1128, 0x080c, 0x1043, 0x0168, 0x2900, 0xb8a6, 0x080c,
- 0x6560, 0xa803, 0x0001, 0xa807, 0x0000, 0x9085, 0x0001, 0x012e,
- 0x009e, 0x0005, 0x9006, 0x0cd8, 0x0096, 0x0126, 0x2091, 0x8000,
- 0xb8a4, 0x904d, 0x0130, 0xb8a7, 0x0000, 0x080c, 0x1075, 0x9085,
- 0x0001, 0x012e, 0x009e, 0x0005, 0xb89c, 0xd0a4, 0x0005, 0x00b6,
- 0x00f6, 0x080c, 0x717f, 0x01b0, 0x71c0, 0x81ff, 0x1198, 0x71d8,
- 0xd19c, 0x0180, 0x2001, 0x007e, 0x9080, 0x1000, 0x2004, 0x905d,
- 0x0148, 0xb804, 0x9084, 0x00ff, 0x9086, 0x0006, 0x1118, 0xb800,
- 0xc0ed, 0xb802, 0x2079, 0x185b, 0x7804, 0x00d0, 0x0156, 0x20a9,
- 0x007f, 0x900e, 0x0016, 0x080c, 0x63a4, 0x1168, 0xb804, 0x9084,
- 0xff00, 0x8007, 0x9096, 0x0004, 0x0118, 0x9086, 0x0006, 0x1118,
- 0xb800, 0xc0ed, 0xb802, 0x001e, 0x8108, 0x1f04, 0x65ea, 0x015e,
- 0x080c, 0x6688, 0x0120, 0x2001, 0x195f, 0x200c, 0x0030, 0x2079,
- 0x185b, 0x7804, 0x0030, 0x2009, 0x07d0, 0x2011, 0x6614, 0x080c,
- 0x82ec, 0x00fe, 0x00be, 0x0005, 0x00b6, 0x2011, 0x6614, 0x080c,
- 0x825a, 0x080c, 0x6688, 0x01d8, 0x2001, 0x107e, 0x2004, 0x2058,
- 0xb900, 0xc1ec, 0xb902, 0x080c, 0x66c6, 0x0130, 0x2009, 0x07d0,
- 0x2011, 0x6614, 0x080c, 0x82ec, 0x00e6, 0x2071, 0x1800, 0x9006,
- 0x707a, 0x705c, 0x707e, 0x080c, 0x2e8c, 0x00ee, 0x04c0, 0x0156,
- 0x00c6, 0x20a9, 0x007f, 0x900e, 0x0016, 0x080c, 0x63a4, 0x1548,
- 0xb800, 0xd0ec, 0x0530, 0xd0bc, 0x1520, 0x0046, 0xbaa0, 0x2220,
- 0x9006, 0x2009, 0x0029, 0x080c, 0xd7d6, 0xb800, 0xc0e5, 0xc0ec,
- 0xb802, 0x080c, 0x66c2, 0x2001, 0x0707, 0x1128, 0xb804, 0x9084,
- 0x00ff, 0x9085, 0x0700, 0xb806, 0x2019, 0x0029, 0x080c, 0x8783,
- 0x0076, 0x903e, 0x080c, 0x8671, 0x900e, 0x080c, 0xd53b, 0x007e,
- 0x004e, 0x001e, 0x8108, 0x1f04, 0x663c, 0x00ce, 0x015e, 0x00be,
- 0x0005, 0x00b6, 0x6010, 0x2058, 0xb800, 0xc0ec, 0xb802, 0x00be,
- 0x0005, 0x7810, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0ac, 0x0005,
- 0x6010, 0x00b6, 0x905d, 0x0108, 0xb800, 0x00be, 0xd0bc, 0x0005,
- 0x00b6, 0x00f6, 0x2001, 0x107e, 0x2004, 0x905d, 0x0110, 0xb800,
- 0xd0ec, 0x00fe, 0x00be, 0x0005, 0x0126, 0x0026, 0x2091, 0x8000,
- 0x0006, 0xbaa0, 0x9290, 0x1000, 0x2204, 0x9b06, 0x190c, 0x0e02,
- 0x000e, 0xba00, 0x9005, 0x0110, 0xc2fd, 0x0008, 0xc2fc, 0xba02,
- 0x002e, 0x012e, 0x0005, 0x2011, 0x1836, 0x2204, 0xd0cc, 0x0138,
- 0x2001, 0x195d, 0x200c, 0x2011, 0x66b8, 0x080c, 0x82ec, 0x0005,
- 0x2011, 0x66b8, 0x080c, 0x825a, 0x2011, 0x1836, 0x2204, 0xc0cc,
- 0x2012, 0x0005, 0x080c, 0x54dc, 0xd0ac, 0x0005, 0x080c, 0x54dc,
- 0xd0a4, 0x0005, 0x0016, 0xb904, 0x9184, 0x00ff, 0x908e, 0x0006,
- 0x001e, 0x0005, 0x0016, 0xb904, 0x9184, 0xff00, 0x8007, 0x908e,
- 0x0006, 0x001e, 0x0005, 0x00b6, 0x00f6, 0x080c, 0xc444, 0x0158,
- 0x70d8, 0x9084, 0x0028, 0x0138, 0x2001, 0x107f, 0x2004, 0x905d,
- 0x0110, 0xb8bc, 0xd094, 0x00fe, 0x00be, 0x0005, 0x0006, 0x0016,
- 0x0036, 0x0046, 0x0076, 0x00b6, 0x2001, 0x1817, 0x203c, 0x9780,
- 0x3209, 0x203d, 0x97bc, 0xff00, 0x873f, 0x9006, 0x2018, 0x2008,
- 0x9284, 0x8000, 0x0110, 0x2019, 0x0001, 0x9294, 0x7fff, 0x2100,
- 0x9706, 0x0190, 0x91a0, 0x1000, 0x2404, 0x905d, 0x0168, 0xb804,
- 0x9084, 0x00ff, 0x9086, 0x0006, 0x1138, 0x83ff, 0x0118, 0xb89c,
- 0xd0a4, 0x0110, 0x8211, 0x0158, 0x8108, 0x83ff, 0x0120, 0x9182,
- 0x0800, 0x0e28, 0x0068, 0x9182, 0x007e, 0x0e08, 0x0048, 0x00be,
- 0x007e, 0x004e, 0x003e, 0x001e, 0x9085, 0x0001, 0x000e, 0x0005,
- 0x00be, 0x007e, 0x004e, 0x003e, 0x001e, 0x9006, 0x000e, 0x0005,
- 0x0046, 0x0056, 0x0076, 0x00b6, 0x2100, 0x9084, 0x7fff, 0x9080,
- 0x1000, 0x2004, 0x905d, 0x0130, 0xb804, 0x9084, 0x00ff, 0x9086,
- 0x0006, 0x0550, 0x9184, 0x8000, 0x0580, 0x2001, 0x1817, 0x203c,
- 0x9780, 0x3209, 0x203d, 0x97bc, 0xff00, 0x873f, 0x9006, 0x2020,
- 0x2400, 0x9706, 0x01a0, 0x94a8, 0x1000, 0x2504, 0x905d, 0x0178,
- 0xb804, 0x9084, 0x00ff, 0x9086, 0x0006, 0x1148, 0xb89c, 0xd0a4,
- 0x0130, 0xb814, 0x9206, 0x1118, 0xb810, 0x9306, 0x0128, 0x8420,
- 0x9482, 0x0800, 0x0e28, 0x0048, 0x918c, 0x7fff, 0x00be, 0x007e,
- 0x005e, 0x004e, 0x9085, 0x0001, 0x0005, 0x918c, 0x7fff, 0x00be,
- 0x007e, 0x005e, 0x004e, 0x9006, 0x0005, 0x2071, 0x190e, 0x7003,
- 0x0001, 0x7007, 0x0000, 0x9006, 0x7012, 0x7016, 0x701a, 0x701e,
- 0x700a, 0x7046, 0x2001, 0x1920, 0x2003, 0x0000, 0x0005, 0x0016,
- 0x00e6, 0x2071, 0x1923, 0x900e, 0x710a, 0x080c, 0x54dc, 0xd0fc,
- 0x1140, 0x080c, 0x54dc, 0x900e, 0xd09c, 0x0108, 0x8108, 0x7102,
- 0x0438, 0x2001, 0x187b, 0x200c, 0x9184, 0x0007, 0x9006, 0x0002,
- 0x67a1, 0x67a1, 0x67a1, 0x67a1, 0x67a1, 0x67b8, 0x67cd, 0x67db,
- 0x7003, 0x0003, 0x2009, 0x187c, 0x210c, 0x9184, 0xff00, 0x908e,
- 0xff00, 0x0140, 0x8007, 0x9005, 0x1110, 0x2001, 0x0002, 0x8003,
- 0x7006, 0x0030, 0x7007, 0x0001, 0x0018, 0x7003, 0x0005, 0x0c50,
- 0x2071, 0x190e, 0x704f, 0x0000, 0x2071, 0x1800, 0x70ef, 0x0001,
- 0x00ee, 0x001e, 0x0005, 0x7003, 0x0000, 0x2071, 0x190e, 0x2009,
- 0x187c, 0x210c, 0x9184, 0x7f00, 0x8007, 0x908c, 0x000f, 0x0160,
- 0x714e, 0x8004, 0x8004, 0x8004, 0x8004, 0x2071, 0x1800, 0x908c,
- 0x0007, 0x0128, 0x70ee, 0x0c20, 0x704f, 0x000f, 0x0c90, 0x70ef,
- 0x0005, 0x08f0, 0x00e6, 0x2071, 0x0050, 0x684c, 0x9005, 0x1150,
- 0x00e6, 0x2071, 0x190e, 0x7028, 0xc085, 0x702a, 0x00ee, 0x9085,
- 0x0001, 0x0488, 0x6844, 0x9005, 0x0158, 0x080c, 0x74ed, 0x6a60,
- 0x9200, 0x7002, 0x6864, 0x9101, 0x7006, 0x9006, 0x7012, 0x7016,
- 0x6860, 0x7002, 0x6864, 0x7006, 0x6868, 0x700a, 0x686c, 0x700e,
- 0x6844, 0x9005, 0x1110, 0x7012, 0x7016, 0x684c, 0x701a, 0x701c,
- 0x9085, 0x0040, 0x701e, 0x7037, 0x0019, 0x702b, 0x0001, 0x00e6,
- 0x2071, 0x190e, 0x7028, 0xc084, 0x702a, 0x7007, 0x0001, 0x700b,
- 0x0000, 0x00ee, 0x9006, 0x00ee, 0x0005, 0xa868, 0xd0fc, 0x1508,
- 0x00e6, 0x0026, 0x2001, 0x1923, 0x2004, 0x9015, 0x0904, 0x6a29,
- 0xa978, 0xa874, 0x9105, 0x1904, 0x6a29, 0x9286, 0x0003, 0x0904,
- 0x68c2, 0x9286, 0x0005, 0x0904, 0x68c2, 0xa87c, 0xd0bc, 0x1904,
- 0x6a29, 0x2200, 0x0002, 0x6a29, 0x6886, 0x68c2, 0x68c2, 0x6a29,
- 0x68c2, 0x0005, 0xa868, 0xd0fc, 0x1500, 0x00e6, 0x0026, 0x2009,
- 0x1923, 0x210c, 0x81ff, 0x0904, 0x6a29, 0xa880, 0x9084, 0x00ff,
- 0x9086, 0x0001, 0x1904, 0x6a29, 0x9186, 0x0003, 0x0904, 0x68c2,
- 0x9186, 0x0005, 0x0904, 0x68c2, 0xa87c, 0xd0cc, 0x0904, 0x6a29,
- 0xa84f, 0x8021, 0xa853, 0x0017, 0x0028, 0x0005, 0xa84f, 0x8020,
- 0xa853, 0x0016, 0x2071, 0x190e, 0x701c, 0x9005, 0x1904, 0x6bf7,
- 0x0e04, 0x6c42, 0x2071, 0x0000, 0xa84c, 0x7082, 0xa850, 0x7032,
- 0xa86c, 0x7086, 0x7036, 0xa870, 0x708a, 0x2091, 0x4080, 0x2001,
- 0x0089, 0x2004, 0xd084, 0x190c, 0x11f2, 0x2071, 0x1800, 0x2011,
- 0x0001, 0xa804, 0x900d, 0x702c, 0x1158, 0xa802, 0x2900, 0x702e,
- 0x70bc, 0x9200, 0x70be, 0x080c, 0x8170, 0x002e, 0x00ee, 0x0005,
- 0x0096, 0x2148, 0xa904, 0xa802, 0x8210, 0x2900, 0x81ff, 0x1dc8,
- 0x009e, 0x0c58, 0xa84f, 0x0000, 0x00f6, 0x2079, 0x0050, 0x2071,
- 0x190e, 0xa803, 0x0000, 0x7010, 0x9005, 0x1904, 0x69ad, 0x782c,
- 0x908c, 0x0780, 0x190c, 0x6d6b, 0x8004, 0x8004, 0x8004, 0x9084,
- 0x0003, 0x0002, 0x68e0, 0x69ad, 0x6904, 0x694a, 0x080c, 0x0e02,
- 0x2071, 0x1800, 0x2900, 0x7822, 0xa804, 0x900d, 0x1168, 0x2071,
- 0x19d5, 0x7044, 0x9005, 0x1320, 0x2001, 0x1924, 0x2004, 0x7046,
- 0x00fe, 0x002e, 0x00ee, 0x0005, 0x9016, 0x702c, 0x2148, 0xa904,
- 0xa802, 0x8210, 0x2900, 0x81ff, 0x1dc8, 0x702e, 0x70bc, 0x9200,
- 0x70be, 0x080c, 0x8170, 0x0c18, 0x2071, 0x1800, 0x2900, 0x7822,
- 0xa804, 0x900d, 0x1578, 0x7824, 0x00e6, 0x2071, 0x0040, 0x712c,
- 0xd19c, 0x1148, 0x2009, 0x182f, 0x210c, 0x918a, 0x0040, 0x0218,
- 0x7022, 0x00ee, 0x0058, 0x00ee, 0x2048, 0x702c, 0xa802, 0x2900,
- 0x702e, 0x70bc, 0x8000, 0x70be, 0x080c, 0x8170, 0x782c, 0x9094,
- 0x0780, 0x190c, 0x6d6b, 0xd0a4, 0x19f0, 0x2071, 0x19d5, 0x7044,
- 0x9005, 0x1320, 0x2001, 0x1924, 0x2004, 0x7046, 0x00fe, 0x002e,
- 0x00ee, 0x0005, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802, 0x8210,
- 0x2900, 0x81ff, 0x1dc8, 0x702e, 0x70bc, 0x9200, 0x70be, 0x080c,
- 0x8170, 0x0808, 0x0096, 0x00e6, 0x7824, 0x2048, 0x2071, 0x1800,
- 0x702c, 0xa802, 0x2900, 0x702e, 0x70bc, 0x8000, 0x70be, 0x080c,
- 0x8170, 0x782c, 0x9094, 0x0780, 0x190c, 0x6d6b, 0xd0a4, 0x1d60,
- 0x00ee, 0x782c, 0x9094, 0x0780, 0x190c, 0x6d6b, 0xd09c, 0x1198,
- 0x009e, 0x2900, 0x7822, 0xa804, 0x900d, 0x1550, 0x2071, 0x19d5,
+ 0x9085, 0x0001, 0x0008, 0x9006, 0x01ce, 0x013e, 0x0005, 0x0146,
+ 0x01d6, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0004, 0x20a0, 0x20a9,
+ 0x0010, 0x2009, 0xffff, 0x4104, 0x01de, 0x014e, 0x0136, 0x01c6,
+ 0xa800, 0x9005, 0x11b8, 0x890e, 0x810e, 0x810f, 0x9184, 0x003f,
+ 0x20e0, 0x9184, 0xffc0, 0x9080, 0x0004, 0x2098, 0x20a9, 0x0001,
+ 0x2009, 0x0010, 0x4002, 0x9606, 0x0128, 0x8109, 0x1dd8, 0x9085,
+ 0x0001, 0x0068, 0x0146, 0x01d6, 0x3300, 0x8001, 0x20a0, 0x3c00,
+ 0x20e8, 0x2001, 0xffff, 0x4004, 0x01de, 0x014e, 0x9006, 0x01ce,
+ 0x013e, 0x0005, 0x0096, 0x0126, 0x2091, 0x8000, 0xb8a4, 0x904d,
+ 0x1128, 0x080c, 0x1037, 0x0168, 0x2900, 0xb8a6, 0x080c, 0x655f,
+ 0xa803, 0x0001, 0xa807, 0x0000, 0x9085, 0x0001, 0x012e, 0x009e,
+ 0x0005, 0x9006, 0x0cd8, 0x0096, 0x0126, 0x2091, 0x8000, 0xb8a4,
+ 0x904d, 0x0130, 0xb8a7, 0x0000, 0x080c, 0x1069, 0x9085, 0x0001,
+ 0x012e, 0x009e, 0x0005, 0xb89c, 0xd0a4, 0x0005, 0x00b6, 0x00f6,
+ 0x080c, 0x717e, 0x01b0, 0x71c0, 0x81ff, 0x1198, 0x71d8, 0xd19c,
+ 0x0180, 0x2001, 0x007e, 0x9080, 0x1000, 0x2004, 0x905d, 0x0148,
+ 0xb804, 0x9084, 0x00ff, 0x9086, 0x0006, 0x1118, 0xb800, 0xc0ed,
+ 0xb802, 0x2079, 0x185b, 0x7804, 0x00d0, 0x0156, 0x20a9, 0x007f,
+ 0x900e, 0x0016, 0x080c, 0x63a3, 0x1168, 0xb804, 0x9084, 0xff00,
+ 0x8007, 0x9096, 0x0004, 0x0118, 0x9086, 0x0006, 0x1118, 0xb800,
+ 0xc0ed, 0xb802, 0x001e, 0x8108, 0x1f04, 0x65e9, 0x015e, 0x080c,
+ 0x6687, 0x0120, 0x2001, 0x195f, 0x200c, 0x0030, 0x2079, 0x185b,
+ 0x7804, 0x0030, 0x2009, 0x07d0, 0x2011, 0x6613, 0x080c, 0x82eb,
+ 0x00fe, 0x00be, 0x0005, 0x00b6, 0x2011, 0x6613, 0x080c, 0x8259,
+ 0x080c, 0x6687, 0x01d8, 0x2001, 0x107e, 0x2004, 0x2058, 0xb900,
+ 0xc1ec, 0xb902, 0x080c, 0x66c5, 0x0130, 0x2009, 0x07d0, 0x2011,
+ 0x6613, 0x080c, 0x82eb, 0x00e6, 0x2071, 0x1800, 0x9006, 0x707a,
+ 0x705c, 0x707e, 0x080c, 0x2e73, 0x00ee, 0x04c0, 0x0156, 0x00c6,
+ 0x20a9, 0x007f, 0x900e, 0x0016, 0x080c, 0x63a3, 0x1548, 0xb800,
+ 0xd0ec, 0x0530, 0xd0bc, 0x1520, 0x0046, 0xbaa0, 0x2220, 0x9006,
+ 0x2009, 0x0029, 0x080c, 0xd837, 0xb800, 0xc0e5, 0xc0ec, 0xb802,
+ 0x080c, 0x66c1, 0x2001, 0x0707, 0x1128, 0xb804, 0x9084, 0x00ff,
+ 0x9085, 0x0700, 0xb806, 0x2019, 0x0029, 0x080c, 0x8782, 0x0076,
+ 0x903e, 0x080c, 0x8670, 0x900e, 0x080c, 0xd556, 0x007e, 0x004e,
+ 0x001e, 0x8108, 0x1f04, 0x663b, 0x00ce, 0x015e, 0x00be, 0x0005,
+ 0x00b6, 0x6010, 0x2058, 0xb800, 0xc0ec, 0xb802, 0x00be, 0x0005,
+ 0x7810, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0ac, 0x0005, 0x6010,
+ 0x00b6, 0x905d, 0x0108, 0xb800, 0x00be, 0xd0bc, 0x0005, 0x00b6,
+ 0x00f6, 0x2001, 0x107e, 0x2004, 0x905d, 0x0110, 0xb800, 0xd0ec,
+ 0x00fe, 0x00be, 0x0005, 0x0126, 0x0026, 0x2091, 0x8000, 0x0006,
+ 0xbaa0, 0x9290, 0x1000, 0x2204, 0x9b06, 0x190c, 0x0df6, 0x000e,
+ 0xba00, 0x9005, 0x0110, 0xc2fd, 0x0008, 0xc2fc, 0xba02, 0x002e,
+ 0x012e, 0x0005, 0x2011, 0x1836, 0x2204, 0xd0cc, 0x0138, 0x2001,
+ 0x195d, 0x200c, 0x2011, 0x66b7, 0x080c, 0x82eb, 0x0005, 0x2011,
+ 0x66b7, 0x080c, 0x8259, 0x2011, 0x1836, 0x2204, 0xc0cc, 0x2012,
+ 0x0005, 0x080c, 0x54db, 0xd0ac, 0x0005, 0x080c, 0x54db, 0xd0a4,
+ 0x0005, 0x0016, 0xb904, 0x9184, 0x00ff, 0x908e, 0x0006, 0x001e,
+ 0x0005, 0x0016, 0xb904, 0x9184, 0xff00, 0x8007, 0x908e, 0x0006,
+ 0x001e, 0x0005, 0x00b6, 0x00f6, 0x080c, 0xc459, 0x0158, 0x70d8,
+ 0x9084, 0x0028, 0x0138, 0x2001, 0x107f, 0x2004, 0x905d, 0x0110,
+ 0xb8bc, 0xd094, 0x00fe, 0x00be, 0x0005, 0x0006, 0x0016, 0x0036,
+ 0x0046, 0x0076, 0x00b6, 0x2001, 0x1817, 0x203c, 0x9780, 0x31f3,
+ 0x203d, 0x97bc, 0xff00, 0x873f, 0x9006, 0x2018, 0x2008, 0x9284,
+ 0x8000, 0x0110, 0x2019, 0x0001, 0x9294, 0x7fff, 0x2100, 0x9706,
+ 0x0190, 0x91a0, 0x1000, 0x2404, 0x905d, 0x0168, 0xb804, 0x9084,
+ 0x00ff, 0x9086, 0x0006, 0x1138, 0x83ff, 0x0118, 0xb89c, 0xd0a4,
+ 0x0110, 0x8211, 0x0158, 0x8108, 0x83ff, 0x0120, 0x9182, 0x0800,
+ 0x0e28, 0x0068, 0x9182, 0x007e, 0x0e08, 0x0048, 0x00be, 0x007e,
+ 0x004e, 0x003e, 0x001e, 0x9085, 0x0001, 0x000e, 0x0005, 0x00be,
+ 0x007e, 0x004e, 0x003e, 0x001e, 0x9006, 0x000e, 0x0005, 0x0046,
+ 0x0056, 0x0076, 0x00b6, 0x2100, 0x9084, 0x7fff, 0x9080, 0x1000,
+ 0x2004, 0x905d, 0x0130, 0xb804, 0x9084, 0x00ff, 0x9086, 0x0006,
+ 0x0550, 0x9184, 0x8000, 0x0580, 0x2001, 0x1817, 0x203c, 0x9780,
+ 0x31f3, 0x203d, 0x97bc, 0xff00, 0x873f, 0x9006, 0x2020, 0x2400,
+ 0x9706, 0x01a0, 0x94a8, 0x1000, 0x2504, 0x905d, 0x0178, 0xb804,
+ 0x9084, 0x00ff, 0x9086, 0x0006, 0x1148, 0xb89c, 0xd0a4, 0x0130,
+ 0xb814, 0x9206, 0x1118, 0xb810, 0x9306, 0x0128, 0x8420, 0x9482,
+ 0x0800, 0x0e28, 0x0048, 0x918c, 0x7fff, 0x00be, 0x007e, 0x005e,
+ 0x004e, 0x9085, 0x0001, 0x0005, 0x918c, 0x7fff, 0x00be, 0x007e,
+ 0x005e, 0x004e, 0x9006, 0x0005, 0x2071, 0x190e, 0x7003, 0x0001,
+ 0x7007, 0x0000, 0x9006, 0x7012, 0x7016, 0x701a, 0x701e, 0x700a,
+ 0x7046, 0x2001, 0x1920, 0x2003, 0x0000, 0x0005, 0x0016, 0x00e6,
+ 0x2071, 0x1923, 0x900e, 0x710a, 0x080c, 0x54db, 0xd0fc, 0x1140,
+ 0x080c, 0x54db, 0x900e, 0xd09c, 0x0108, 0x8108, 0x7102, 0x0438,
+ 0x2001, 0x187b, 0x200c, 0x9184, 0x0007, 0x9006, 0x0002, 0x67a0,
+ 0x67a0, 0x67a0, 0x67a0, 0x67a0, 0x67b7, 0x67cc, 0x67da, 0x7003,
+ 0x0003, 0x2009, 0x187c, 0x210c, 0x9184, 0xff00, 0x908e, 0xff00,
+ 0x0140, 0x8007, 0x9005, 0x1110, 0x2001, 0x0002, 0x8003, 0x7006,
+ 0x0030, 0x7007, 0x0001, 0x0018, 0x7003, 0x0005, 0x0c50, 0x2071,
+ 0x190e, 0x704f, 0x0000, 0x2071, 0x1800, 0x70ef, 0x0001, 0x00ee,
+ 0x001e, 0x0005, 0x7003, 0x0000, 0x2071, 0x190e, 0x2009, 0x187c,
+ 0x210c, 0x9184, 0x7f00, 0x8007, 0x908c, 0x000f, 0x0160, 0x714e,
+ 0x8004, 0x8004, 0x8004, 0x8004, 0x2071, 0x1800, 0x908c, 0x0007,
+ 0x0128, 0x70ee, 0x0c20, 0x704f, 0x000f, 0x0c90, 0x70ef, 0x0005,
+ 0x08f0, 0x00e6, 0x2071, 0x0050, 0x684c, 0x9005, 0x1150, 0x00e6,
+ 0x2071, 0x190e, 0x7028, 0xc085, 0x702a, 0x00ee, 0x9085, 0x0001,
+ 0x0488, 0x6844, 0x9005, 0x0158, 0x080c, 0x74ec, 0x6a60, 0x9200,
+ 0x7002, 0x6864, 0x9101, 0x7006, 0x9006, 0x7012, 0x7016, 0x6860,
+ 0x7002, 0x6864, 0x7006, 0x6868, 0x700a, 0x686c, 0x700e, 0x6844,
+ 0x9005, 0x1110, 0x7012, 0x7016, 0x684c, 0x701a, 0x701c, 0x9085,
+ 0x0040, 0x701e, 0x7037, 0x0019, 0x702b, 0x0001, 0x00e6, 0x2071,
+ 0x190e, 0x7028, 0xc084, 0x702a, 0x7007, 0x0001, 0x700b, 0x0000,
+ 0x00ee, 0x9006, 0x00ee, 0x0005, 0xa868, 0xd0fc, 0x1508, 0x00e6,
+ 0x0026, 0x2001, 0x1923, 0x2004, 0x9015, 0x0904, 0x6a28, 0xa978,
+ 0xa874, 0x9105, 0x1904, 0x6a28, 0x9286, 0x0003, 0x0904, 0x68c1,
+ 0x9286, 0x0005, 0x0904, 0x68c1, 0xa87c, 0xd0bc, 0x1904, 0x6a28,
+ 0x2200, 0x0002, 0x6a28, 0x6885, 0x68c1, 0x68c1, 0x6a28, 0x68c1,
+ 0x0005, 0xa868, 0xd0fc, 0x1500, 0x00e6, 0x0026, 0x2009, 0x1923,
+ 0x210c, 0x81ff, 0x0904, 0x6a28, 0xa880, 0x9084, 0x00ff, 0x9086,
+ 0x0001, 0x1904, 0x6a28, 0x9186, 0x0003, 0x0904, 0x68c1, 0x9186,
+ 0x0005, 0x0904, 0x68c1, 0xa87c, 0xd0cc, 0x0904, 0x6a28, 0xa84f,
+ 0x8021, 0xa853, 0x0017, 0x0028, 0x0005, 0xa84f, 0x8020, 0xa853,
+ 0x0016, 0x2071, 0x190e, 0x701c, 0x9005, 0x1904, 0x6bf6, 0x0e04,
+ 0x6c41, 0x2071, 0x0000, 0xa84c, 0x7082, 0xa850, 0x7032, 0xa86c,
+ 0x7086, 0x7036, 0xa870, 0x708a, 0x2091, 0x4080, 0x2001, 0x0089,
+ 0x2004, 0xd084, 0x190c, 0x11e6, 0x2071, 0x1800, 0x2011, 0x0001,
+ 0xa804, 0x900d, 0x702c, 0x1158, 0xa802, 0x2900, 0x702e, 0x70bc,
+ 0x9200, 0x70be, 0x080c, 0x816f, 0x002e, 0x00ee, 0x0005, 0x0096,
+ 0x2148, 0xa904, 0xa802, 0x8210, 0x2900, 0x81ff, 0x1dc8, 0x009e,
+ 0x0c58, 0xa84f, 0x0000, 0x00f6, 0x2079, 0x0050, 0x2071, 0x190e,
+ 0xa803, 0x0000, 0x7010, 0x9005, 0x1904, 0x69ac, 0x782c, 0x908c,
+ 0x0780, 0x190c, 0x6d6a, 0x8004, 0x8004, 0x8004, 0x9084, 0x0003,
+ 0x0002, 0x68df, 0x69ac, 0x6903, 0x6949, 0x080c, 0x0df6, 0x2071,
+ 0x1800, 0x2900, 0x7822, 0xa804, 0x900d, 0x1168, 0x2071, 0x19d5,
0x7044, 0x9005, 0x1320, 0x2001, 0x1924, 0x2004, 0x7046, 0x00fe,
- 0x002e, 0x00ee, 0x0005, 0x009e, 0x2908, 0x7010, 0x8000, 0x7012,
+ 0x002e, 0x00ee, 0x0005, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802,
+ 0x8210, 0x2900, 0x81ff, 0x1dc8, 0x702e, 0x70bc, 0x9200, 0x70be,
+ 0x080c, 0x816f, 0x0c18, 0x2071, 0x1800, 0x2900, 0x7822, 0xa804,
+ 0x900d, 0x1578, 0x7824, 0x00e6, 0x2071, 0x0040, 0x712c, 0xd19c,
+ 0x1148, 0x2009, 0x182f, 0x210c, 0x918a, 0x0040, 0x0218, 0x7022,
+ 0x00ee, 0x0058, 0x00ee, 0x2048, 0x702c, 0xa802, 0x2900, 0x702e,
+ 0x70bc, 0x8000, 0x70be, 0x080c, 0x816f, 0x782c, 0x9094, 0x0780,
+ 0x190c, 0x6d6a, 0xd0a4, 0x19f0, 0x2071, 0x19d5, 0x7044, 0x9005,
+ 0x1320, 0x2001, 0x1924, 0x2004, 0x7046, 0x00fe, 0x002e, 0x00ee,
+ 0x0005, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802, 0x8210, 0x2900,
+ 0x81ff, 0x1dc8, 0x702e, 0x70bc, 0x9200, 0x70be, 0x080c, 0x816f,
+ 0x0808, 0x0096, 0x00e6, 0x7824, 0x2048, 0x2071, 0x1800, 0x702c,
+ 0xa802, 0x2900, 0x702e, 0x70bc, 0x8000, 0x70be, 0x080c, 0x816f,
+ 0x782c, 0x9094, 0x0780, 0x190c, 0x6d6a, 0xd0a4, 0x1d60, 0x00ee,
+ 0x782c, 0x9094, 0x0780, 0x190c, 0x6d6a, 0xd09c, 0x1198, 0x009e,
+ 0x2900, 0x7822, 0xa804, 0x900d, 0x1550, 0x2071, 0x19d5, 0x7044,
+ 0x9005, 0x1320, 0x2001, 0x1924, 0x2004, 0x7046, 0x00fe, 0x002e,
+ 0x00ee, 0x0005, 0x009e, 0x2908, 0x7010, 0x8000, 0x7012, 0x7018,
+ 0x904d, 0x711a, 0x0110, 0xa902, 0x0008, 0x711e, 0x2148, 0xa804,
+ 0x900d, 0x1168, 0x2071, 0x19d5, 0x7044, 0x9005, 0x1320, 0x2001,
+ 0x1924, 0x2004, 0x7046, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x2071,
+ 0x1800, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802, 0x8210, 0x2900,
+ 0x81ff, 0x1dc8, 0x702e, 0x70bc, 0x9200, 0x70be, 0x080c, 0x816f,
+ 0x00fe, 0x002e, 0x00ee, 0x0005, 0x2908, 0x7010, 0x8000, 0x7012,
0x7018, 0x904d, 0x711a, 0x0110, 0xa902, 0x0008, 0x711e, 0x2148,
- 0xa804, 0x900d, 0x1168, 0x2071, 0x19d5, 0x7044, 0x9005, 0x1320,
+ 0xa804, 0x900d, 0x1904, 0x6a00, 0x782c, 0x9094, 0x0780, 0x190c,
+ 0x6d6a, 0xd09c, 0x1198, 0x701c, 0x904d, 0x0180, 0x7010, 0x8001,
+ 0x7012, 0x1108, 0x701a, 0xa800, 0x701e, 0x2900, 0x7822, 0x782c,
+ 0x9094, 0x0780, 0x190c, 0x6d6a, 0xd09c, 0x0d68, 0x782c, 0x9094,
+ 0x0780, 0x190c, 0x6d6a, 0xd0a4, 0x01b0, 0x00e6, 0x7824, 0x2048,
+ 0x2071, 0x1800, 0x702c, 0xa802, 0x2900, 0x702e, 0x70bc, 0x8000,
+ 0x70be, 0x080c, 0x816f, 0x782c, 0x9094, 0x0780, 0x190c, 0x6d6a,
+ 0xd0a4, 0x1d60, 0x00ee, 0x2071, 0x19d5, 0x7044, 0x9005, 0x1320,
0x2001, 0x1924, 0x2004, 0x7046, 0x00fe, 0x002e, 0x00ee, 0x0005,
- 0x2071, 0x1800, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802, 0x8210,
+ 0x00e6, 0x2071, 0x1800, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802,
+ 0x8210, 0x2900, 0x81ff, 0x1dc8, 0x702e, 0x70bc, 0x9200, 0x70be,
+ 0x080c, 0x816f, 0x00ee, 0x0804, 0x69bc, 0xa868, 0xd0fc, 0x1904,
+ 0x6a76, 0x0096, 0xa804, 0xa807, 0x0000, 0x904d, 0x190c, 0x0fe9,
+ 0x009e, 0x0020, 0xa868, 0xd0fc, 0x1904, 0x6a76, 0x00e6, 0x0026,
+ 0xa84f, 0x0000, 0x00f6, 0x2079, 0x0050, 0x2071, 0x1800, 0x70e8,
+ 0x8001, 0x0558, 0x1a04, 0x6a73, 0x2071, 0x190e, 0xa803, 0x0000,
+ 0xa864, 0x9084, 0x00ff, 0x908e, 0x0016, 0x01a8, 0x7010, 0x9005,
+ 0x1904, 0x6b72, 0x782c, 0x908c, 0x0780, 0x190c, 0x6d6a, 0x8004,
+ 0x8004, 0x8004, 0x9084, 0x0003, 0x0002, 0x6a77, 0x6b72, 0x6a92,
+ 0x6b03, 0x080c, 0x0df6, 0x2009, 0x1923, 0x2104, 0x0002, 0x6a3e,
+ 0x6a3e, 0x6a3e, 0x68ca, 0x6a3e, 0x68ca, 0x70eb, 0x0fa0, 0x71e4,
+ 0x8107, 0x9106, 0x9094, 0x00c0, 0x9184, 0xff3f, 0x9205, 0x70e6,
+ 0x3b08, 0x3a00, 0x9104, 0x918d, 0x00c0, 0x21d8, 0x9084, 0xff3f,
+ 0x9205, 0x20d0, 0x0808, 0x70ea, 0x0804, 0x6a34, 0x0005, 0x2071,
+ 0x1800, 0x2900, 0x7822, 0xa804, 0x900d, 0x1120, 0x00fe, 0x002e,
+ 0x00ee, 0x0005, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802, 0x8210,
0x2900, 0x81ff, 0x1dc8, 0x702e, 0x70bc, 0x9200, 0x70be, 0x080c,
- 0x8170, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x2908, 0x7010, 0x8000,
- 0x7012, 0x7018, 0x904d, 0x711a, 0x0110, 0xa902, 0x0008, 0x711e,
- 0x2148, 0xa804, 0x900d, 0x1904, 0x6a01, 0x782c, 0x9094, 0x0780,
- 0x190c, 0x6d6b, 0xd09c, 0x1198, 0x701c, 0x904d, 0x0180, 0x7010,
+ 0x816f, 0x0c60, 0x2071, 0x1800, 0x2900, 0x7822, 0xa804, 0x900d,
+ 0x1904, 0x6af2, 0x7830, 0x8007, 0x908c, 0x001f, 0x70ec, 0x9102,
+ 0x1220, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x7824, 0x00e6, 0x2071,
+ 0x0040, 0x712c, 0xd19c, 0x1148, 0x2009, 0x182f, 0x210c, 0x918a,
+ 0x0040, 0x0218, 0x7022, 0x00ee, 0x0058, 0x00ee, 0x2048, 0x702c,
+ 0xa802, 0x2900, 0x702e, 0x70bc, 0x8000, 0x70be, 0x080c, 0x816f,
+ 0x782c, 0x9094, 0x0780, 0x190c, 0x6d6a, 0xd0a4, 0x19f0, 0x0e04,
+ 0x6ae9, 0x7838, 0x7938, 0x910e, 0x1de0, 0x00d6, 0x2069, 0x0000,
+ 0x6836, 0x6833, 0x0013, 0x00de, 0x2001, 0x191f, 0x200c, 0xc184,
+ 0x2102, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c,
+ 0x11e6, 0x2001, 0x1920, 0x2003, 0x0000, 0x00fe, 0x002e, 0x00ee,
+ 0x0005, 0x2001, 0x191f, 0x200c, 0xc185, 0x2102, 0x00fe, 0x002e,
+ 0x00ee, 0x0005, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802, 0x8210,
+ 0x2900, 0x81ff, 0x1dc8, 0x702e, 0x70bc, 0x9200, 0x70be, 0x080c,
+ 0x816f, 0x0804, 0x6aa5, 0x0096, 0x00e6, 0x7824, 0x2048, 0x2071,
+ 0x1800, 0x702c, 0xa802, 0x2900, 0x702e, 0x70bc, 0x8000, 0x70be,
+ 0x080c, 0x816f, 0x782c, 0x9094, 0x0780, 0x190c, 0x6d6a, 0xd0a4,
+ 0x1d60, 0x00ee, 0x0e04, 0x6b45, 0x7838, 0x7938, 0x910e, 0x1de0,
+ 0x00d6, 0x2069, 0x0000, 0x6836, 0x6833, 0x0013, 0x00de, 0x7044,
+ 0xc084, 0x7046, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084,
+ 0x190c, 0x11e6, 0x704b, 0x0000, 0x782c, 0x9094, 0x0780, 0x190c,
+ 0x6d6a, 0xd09c, 0x1170, 0x009e, 0x2900, 0x7822, 0xa804, 0x900d,
+ 0x11e0, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x7044, 0xc085, 0x7046,
+ 0x0c58, 0x009e, 0x2908, 0x7010, 0x8000, 0x7012, 0x7018, 0x904d,
+ 0x711a, 0x0110, 0xa902, 0x0008, 0x711e, 0x2148, 0xa804, 0x900d,
+ 0x1120, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x2071, 0x1800, 0x9016,
+ 0x702c, 0x2148, 0xa904, 0xa802, 0x8210, 0x2900, 0x81ff, 0x1dc8,
+ 0x702e, 0x70bc, 0x9200, 0x70be, 0x080c, 0x816f, 0x00fe, 0x002e,
+ 0x00ee, 0x0005, 0x2908, 0x7010, 0x8000, 0x7012, 0x7018, 0x904d,
+ 0x711a, 0x0110, 0xa902, 0x0008, 0x711e, 0x2148, 0xa804, 0x900d,
+ 0x1904, 0x6be1, 0x782c, 0x9094, 0x0780, 0x190c, 0x6d6a, 0xd09c,
+ 0x11b0, 0x701c, 0x904d, 0x0198, 0xa84c, 0x9005, 0x1180, 0x7010,
0x8001, 0x7012, 0x1108, 0x701a, 0xa800, 0x701e, 0x2900, 0x7822,
- 0x782c, 0x9094, 0x0780, 0x190c, 0x6d6b, 0xd09c, 0x0d68, 0x782c,
- 0x9094, 0x0780, 0x190c, 0x6d6b, 0xd0a4, 0x01b0, 0x00e6, 0x7824,
+ 0x782c, 0x9094, 0x0780, 0x190c, 0x6d6a, 0xd09c, 0x0d50, 0x782c,
+ 0x9094, 0x0780, 0x190c, 0x6d6a, 0xd0a4, 0x05b8, 0x00e6, 0x7824,
0x2048, 0x2071, 0x1800, 0x702c, 0xa802, 0x2900, 0x702e, 0x70bc,
- 0x8000, 0x70be, 0x080c, 0x8170, 0x782c, 0x9094, 0x0780, 0x190c,
- 0x6d6b, 0xd0a4, 0x1d60, 0x00ee, 0x2071, 0x19d5, 0x7044, 0x9005,
- 0x1320, 0x2001, 0x1924, 0x2004, 0x7046, 0x00fe, 0x002e, 0x00ee,
+ 0x8000, 0x70be, 0x080c, 0x816f, 0x782c, 0x9094, 0x0780, 0x190c,
+ 0x6d6a, 0xd0a4, 0x1d60, 0x00ee, 0x0e04, 0x6bda, 0x7838, 0x7938,
+ 0x910e, 0x1de0, 0x00d6, 0x2069, 0x0000, 0x6836, 0x6833, 0x0013,
+ 0x00de, 0x7044, 0xc084, 0x7046, 0x2091, 0x4080, 0x2001, 0x0089,
+ 0x2004, 0xd084, 0x190c, 0x11e6, 0x704b, 0x0000, 0x00fe, 0x002e,
+ 0x00ee, 0x0005, 0x7044, 0xc085, 0x7046, 0x00fe, 0x002e, 0x00ee,
0x0005, 0x00e6, 0x2071, 0x1800, 0x9016, 0x702c, 0x2148, 0xa904,
0xa802, 0x8210, 0x2900, 0x81ff, 0x1dc8, 0x702e, 0x70bc, 0x9200,
- 0x70be, 0x080c, 0x8170, 0x00ee, 0x0804, 0x69bd, 0xa868, 0xd0fc,
- 0x1904, 0x6a77, 0x0096, 0xa804, 0xa807, 0x0000, 0x904d, 0x190c,
- 0x0ff5, 0x009e, 0x0020, 0xa868, 0xd0fc, 0x1904, 0x6a77, 0x00e6,
- 0x0026, 0xa84f, 0x0000, 0x00f6, 0x2079, 0x0050, 0x2071, 0x1800,
- 0x70e8, 0x8001, 0x0558, 0x1a04, 0x6a74, 0x2071, 0x190e, 0xa803,
- 0x0000, 0xa864, 0x9084, 0x00ff, 0x908e, 0x0016, 0x01a8, 0x7010,
- 0x9005, 0x1904, 0x6b73, 0x782c, 0x908c, 0x0780, 0x190c, 0x6d6b,
- 0x8004, 0x8004, 0x8004, 0x9084, 0x0003, 0x0002, 0x6a78, 0x6b73,
- 0x6a93, 0x6b04, 0x080c, 0x0e02, 0x2009, 0x1923, 0x2104, 0x0002,
- 0x6a3f, 0x6a3f, 0x6a3f, 0x68cb, 0x6a3f, 0x68cb, 0x70eb, 0x0fa0,
- 0x71e4, 0x8107, 0x9106, 0x9094, 0x00c0, 0x9184, 0xff3f, 0x9205,
- 0x70e6, 0x3b08, 0x3a00, 0x9104, 0x918d, 0x00c0, 0x21d8, 0x9084,
- 0xff3f, 0x9205, 0x20d0, 0x0808, 0x70ea, 0x0804, 0x6a35, 0x0005,
- 0x2071, 0x1800, 0x2900, 0x7822, 0xa804, 0x900d, 0x1120, 0x00fe,
- 0x002e, 0x00ee, 0x0005, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802,
- 0x8210, 0x2900, 0x81ff, 0x1dc8, 0x702e, 0x70bc, 0x9200, 0x70be,
- 0x080c, 0x8170, 0x0c60, 0x2071, 0x1800, 0x2900, 0x7822, 0xa804,
- 0x900d, 0x1904, 0x6af3, 0x7830, 0x8007, 0x908c, 0x001f, 0x70ec,
- 0x9102, 0x1220, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x7824, 0x00e6,
- 0x2071, 0x0040, 0x712c, 0xd19c, 0x1148, 0x2009, 0x182f, 0x210c,
- 0x918a, 0x0040, 0x0218, 0x7022, 0x00ee, 0x0058, 0x00ee, 0x2048,
- 0x702c, 0xa802, 0x2900, 0x702e, 0x70bc, 0x8000, 0x70be, 0x080c,
- 0x8170, 0x782c, 0x9094, 0x0780, 0x190c, 0x6d6b, 0xd0a4, 0x19f0,
- 0x0e04, 0x6aea, 0x7838, 0x7938, 0x910e, 0x1de0, 0x00d6, 0x2069,
- 0x0000, 0x6836, 0x6833, 0x0013, 0x00de, 0x2001, 0x191f, 0x200c,
- 0xc184, 0x2102, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084,
- 0x190c, 0x11f2, 0x2001, 0x1920, 0x2003, 0x0000, 0x00fe, 0x002e,
- 0x00ee, 0x0005, 0x2001, 0x191f, 0x200c, 0xc185, 0x2102, 0x00fe,
- 0x002e, 0x00ee, 0x0005, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802,
- 0x8210, 0x2900, 0x81ff, 0x1dc8, 0x702e, 0x70bc, 0x9200, 0x70be,
- 0x080c, 0x8170, 0x0804, 0x6aa6, 0x0096, 0x00e6, 0x7824, 0x2048,
- 0x2071, 0x1800, 0x702c, 0xa802, 0x2900, 0x702e, 0x70bc, 0x8000,
- 0x70be, 0x080c, 0x8170, 0x782c, 0x9094, 0x0780, 0x190c, 0x6d6b,
- 0xd0a4, 0x1d60, 0x00ee, 0x0e04, 0x6b46, 0x7838, 0x7938, 0x910e,
- 0x1de0, 0x00d6, 0x2069, 0x0000, 0x6836, 0x6833, 0x0013, 0x00de,
- 0x7044, 0xc084, 0x7046, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004,
- 0xd084, 0x190c, 0x11f2, 0x704b, 0x0000, 0x782c, 0x9094, 0x0780,
- 0x190c, 0x6d6b, 0xd09c, 0x1170, 0x009e, 0x2900, 0x7822, 0xa804,
- 0x900d, 0x11e0, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x7044, 0xc085,
- 0x7046, 0x0c58, 0x009e, 0x2908, 0x7010, 0x8000, 0x7012, 0x7018,
- 0x904d, 0x711a, 0x0110, 0xa902, 0x0008, 0x711e, 0x2148, 0xa804,
- 0x900d, 0x1120, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x2071, 0x1800,
+ 0x70be, 0x080c, 0x816f, 0x00ee, 0x0804, 0x6b82, 0x2071, 0x190e,
+ 0xa803, 0x0000, 0x2908, 0x7010, 0x8000, 0x7012, 0x7018, 0x904d,
+ 0x711a, 0x0110, 0xa902, 0x0008, 0x711e, 0x2148, 0xa804, 0x900d,
+ 0x1128, 0x1e04, 0x6c21, 0x002e, 0x00ee, 0x0005, 0x2071, 0x1800,
0x9016, 0x702c, 0x2148, 0xa904, 0xa802, 0x8210, 0x2900, 0x81ff,
- 0x1dc8, 0x702e, 0x70bc, 0x9200, 0x70be, 0x080c, 0x8170, 0x00fe,
- 0x002e, 0x00ee, 0x0005, 0x2908, 0x7010, 0x8000, 0x7012, 0x7018,
- 0x904d, 0x711a, 0x0110, 0xa902, 0x0008, 0x711e, 0x2148, 0xa804,
- 0x900d, 0x1904, 0x6be2, 0x782c, 0x9094, 0x0780, 0x190c, 0x6d6b,
- 0xd09c, 0x11b0, 0x701c, 0x904d, 0x0198, 0xa84c, 0x9005, 0x1180,
- 0x7010, 0x8001, 0x7012, 0x1108, 0x701a, 0xa800, 0x701e, 0x2900,
- 0x7822, 0x782c, 0x9094, 0x0780, 0x190c, 0x6d6b, 0xd09c, 0x0d50,
- 0x782c, 0x9094, 0x0780, 0x190c, 0x6d6b, 0xd0a4, 0x05b8, 0x00e6,
- 0x7824, 0x2048, 0x2071, 0x1800, 0x702c, 0xa802, 0x2900, 0x702e,
- 0x70bc, 0x8000, 0x70be, 0x080c, 0x8170, 0x782c, 0x9094, 0x0780,
- 0x190c, 0x6d6b, 0xd0a4, 0x1d60, 0x00ee, 0x0e04, 0x6bdb, 0x7838,
- 0x7938, 0x910e, 0x1de0, 0x00d6, 0x2069, 0x0000, 0x6836, 0x6833,
- 0x0013, 0x00de, 0x7044, 0xc084, 0x7046, 0x2091, 0x4080, 0x2001,
- 0x0089, 0x2004, 0xd084, 0x190c, 0x11f2, 0x704b, 0x0000, 0x00fe,
- 0x002e, 0x00ee, 0x0005, 0x7044, 0xc085, 0x7046, 0x00fe, 0x002e,
- 0x00ee, 0x0005, 0x00e6, 0x2071, 0x1800, 0x9016, 0x702c, 0x2148,
- 0xa904, 0xa802, 0x8210, 0x2900, 0x81ff, 0x1dc8, 0x702e, 0x70bc,
- 0x9200, 0x70be, 0x080c, 0x8170, 0x00ee, 0x0804, 0x6b83, 0x2071,
- 0x190e, 0xa803, 0x0000, 0x2908, 0x7010, 0x8000, 0x7012, 0x7018,
- 0x904d, 0x711a, 0x0110, 0xa902, 0x0008, 0x711e, 0x2148, 0xa804,
- 0x900d, 0x1128, 0x1e04, 0x6c22, 0x002e, 0x00ee, 0x0005, 0x2071,
- 0x1800, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802, 0x8210, 0x2900,
- 0x81ff, 0x1dc8, 0x702e, 0x70bc, 0x9200, 0x70be, 0x080c, 0x8170,
- 0x0e04, 0x6c0c, 0x2071, 0x190e, 0x701c, 0x2048, 0xa84c, 0x900d,
- 0x0d18, 0x2071, 0x0000, 0x7182, 0xa850, 0x7032, 0xa86c, 0x7086,
- 0x7036, 0xa870, 0x708a, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004,
- 0xd084, 0x190c, 0x11f2, 0x2071, 0x190e, 0x080c, 0x6d57, 0x002e,
- 0x00ee, 0x0005, 0x2071, 0x190e, 0xa803, 0x0000, 0x2908, 0x7010,
- 0x8000, 0x7012, 0x7018, 0x904d, 0x711a, 0x0110, 0xa902, 0x0008,
- 0x711e, 0x2148, 0xa804, 0x900d, 0x1118, 0x002e, 0x00ee, 0x0005,
- 0x2071, 0x1800, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802, 0x8210,
- 0x2900, 0x81ff, 0x1dc8, 0x702e, 0x70bc, 0x9200, 0x70be, 0x080c,
- 0x8170, 0x002e, 0x00ee, 0x0005, 0x0006, 0xa87c, 0x0006, 0xa867,
- 0x0103, 0x20a9, 0x001c, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x001d,
- 0x20a0, 0x9006, 0x4004, 0x000e, 0x9084, 0x00ff, 0xa87e, 0x000e,
- 0xa87a, 0xa982, 0x0005, 0x2071, 0x190e, 0x7004, 0x0002, 0x6c8f,
- 0x6c90, 0x6d56, 0x6c90, 0x6c8d, 0x6d56, 0x080c, 0x0e02, 0x0005,
- 0x2001, 0x1923, 0x2004, 0x0002, 0x6c9a, 0x6c9a, 0x6cef, 0x6cf0,
- 0x6c9a, 0x6cf0, 0x0126, 0x2091, 0x8000, 0x1e0c, 0x6d76, 0x701c,
- 0x904d, 0x01e0, 0xa84c, 0x9005, 0x01d8, 0x0e04, 0x6cbe, 0xa94c,
+ 0x1dc8, 0x702e, 0x70bc, 0x9200, 0x70be, 0x080c, 0x816f, 0x0e04,
+ 0x6c0b, 0x2071, 0x190e, 0x701c, 0x2048, 0xa84c, 0x900d, 0x0d18,
0x2071, 0x0000, 0x7182, 0xa850, 0x7032, 0xa86c, 0x7086, 0x7036,
0xa870, 0x708a, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084,
- 0x190c, 0x11f2, 0x2071, 0x190e, 0x080c, 0x6d57, 0x012e, 0x0470,
- 0x2001, 0x005b, 0x2004, 0x9094, 0x0780, 0x190c, 0x6d6b, 0xd09c,
- 0x2071, 0x190e, 0x1510, 0x2071, 0x190e, 0x700f, 0x0001, 0xa964,
+ 0x190c, 0x11e6, 0x2071, 0x190e, 0x080c, 0x6d56, 0x002e, 0x00ee,
+ 0x0005, 0x2071, 0x190e, 0xa803, 0x0000, 0x2908, 0x7010, 0x8000,
+ 0x7012, 0x7018, 0x904d, 0x711a, 0x0110, 0xa902, 0x0008, 0x711e,
+ 0x2148, 0xa804, 0x900d, 0x1118, 0x002e, 0x00ee, 0x0005, 0x2071,
+ 0x1800, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802, 0x8210, 0x2900,
+ 0x81ff, 0x1dc8, 0x702e, 0x70bc, 0x9200, 0x70be, 0x080c, 0x816f,
+ 0x002e, 0x00ee, 0x0005, 0x0006, 0xa87c, 0x0006, 0xa867, 0x0103,
+ 0x20a9, 0x001c, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x001d, 0x20a0,
+ 0x9006, 0x4004, 0x000e, 0x9084, 0x00ff, 0xa87e, 0x000e, 0xa87a,
+ 0xa982, 0x0005, 0x2071, 0x190e, 0x7004, 0x0002, 0x6c8e, 0x6c8f,
+ 0x6d55, 0x6c8f, 0x6c8c, 0x6d55, 0x080c, 0x0df6, 0x0005, 0x2001,
+ 0x1923, 0x2004, 0x0002, 0x6c99, 0x6c99, 0x6cee, 0x6cef, 0x6c99,
+ 0x6cef, 0x0126, 0x2091, 0x8000, 0x1e0c, 0x6d75, 0x701c, 0x904d,
+ 0x01e0, 0xa84c, 0x9005, 0x01d8, 0x0e04, 0x6cbd, 0xa94c, 0x2071,
+ 0x0000, 0x7182, 0xa850, 0x7032, 0xa86c, 0x7086, 0x7036, 0xa870,
+ 0x708a, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c,
+ 0x11e6, 0x2071, 0x190e, 0x080c, 0x6d56, 0x012e, 0x0470, 0x2001,
+ 0x005b, 0x2004, 0x9094, 0x0780, 0x190c, 0x6d6a, 0xd09c, 0x2071,
+ 0x190e, 0x1510, 0x2071, 0x190e, 0x700f, 0x0001, 0xa964, 0x9184,
+ 0x00ff, 0x9086, 0x0003, 0x1130, 0x810f, 0x918c, 0x00ff, 0x8101,
+ 0x0108, 0x710e, 0x2900, 0x00d6, 0x2069, 0x0050, 0x6822, 0x00de,
+ 0x2071, 0x190e, 0x701c, 0x2048, 0x7010, 0x8001, 0x7012, 0xa800,
+ 0x701e, 0x9005, 0x1108, 0x701a, 0x012e, 0x0005, 0x0005, 0x00d6,
+ 0x2008, 0x2069, 0x19d5, 0x6844, 0x9005, 0x0760, 0x0158, 0x9186,
+ 0x0003, 0x0540, 0x2001, 0x1814, 0x2004, 0x2009, 0x1aa2, 0x210c,
+ 0x9102, 0x1500, 0x0126, 0x2091, 0x8000, 0x2069, 0x0050, 0x693c,
+ 0x6838, 0x9106, 0x0190, 0x0e04, 0x6d21, 0x2069, 0x0000, 0x6837,
+ 0x8040, 0x6833, 0x0012, 0x6883, 0x8040, 0x2091, 0x4080, 0x2001,
+ 0x0089, 0x2004, 0xd084, 0x190c, 0x11e6, 0x2069, 0x19d5, 0x6847,
+ 0xffff, 0x012e, 0x00de, 0x0126, 0x2091, 0x8000, 0x1e0c, 0x6de0,
+ 0x701c, 0x904d, 0x0540, 0x2001, 0x005b, 0x2004, 0x9094, 0x0780,
+ 0x15c9, 0xd09c, 0x1500, 0x2071, 0x190e, 0x700f, 0x0001, 0xa964,
0x9184, 0x00ff, 0x9086, 0x0003, 0x1130, 0x810f, 0x918c, 0x00ff,
0x8101, 0x0108, 0x710e, 0x2900, 0x00d6, 0x2069, 0x0050, 0x6822,
- 0x00de, 0x2071, 0x190e, 0x701c, 0x2048, 0x7010, 0x8001, 0x7012,
- 0xa800, 0x701e, 0x9005, 0x1108, 0x701a, 0x012e, 0x0005, 0x0005,
- 0x00d6, 0x2008, 0x2069, 0x19d5, 0x6844, 0x9005, 0x0760, 0x0158,
- 0x9186, 0x0003, 0x0540, 0x2001, 0x1814, 0x2004, 0x2009, 0x1aa2,
- 0x210c, 0x9102, 0x1500, 0x0126, 0x2091, 0x8000, 0x2069, 0x0050,
- 0x693c, 0x6838, 0x9106, 0x0190, 0x0e04, 0x6d22, 0x2069, 0x0000,
- 0x6837, 0x8040, 0x6833, 0x0012, 0x6883, 0x8040, 0x2091, 0x4080,
- 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x11f2, 0x2069, 0x19d5,
- 0x6847, 0xffff, 0x012e, 0x00de, 0x0126, 0x2091, 0x8000, 0x1e0c,
- 0x6de1, 0x701c, 0x904d, 0x0540, 0x2001, 0x005b, 0x2004, 0x9094,
- 0x0780, 0x15c9, 0xd09c, 0x1500, 0x2071, 0x190e, 0x700f, 0x0001,
- 0xa964, 0x9184, 0x00ff, 0x9086, 0x0003, 0x1130, 0x810f, 0x918c,
- 0x00ff, 0x8101, 0x0108, 0x710e, 0x2900, 0x00d6, 0x2069, 0x0050,
- 0x6822, 0x00de, 0x701c, 0x2048, 0x7010, 0x8001, 0x7012, 0xa800,
- 0x701e, 0x9005, 0x1108, 0x701a, 0x012e, 0x0005, 0x0005, 0x0126,
- 0x2091, 0x8000, 0x701c, 0x904d, 0x0160, 0x7010, 0x8001, 0x7012,
- 0xa800, 0x701e, 0x9005, 0x1108, 0x701a, 0x012e, 0x080c, 0x1075,
- 0x0005, 0x012e, 0x0005, 0x2091, 0x8000, 0x0e04, 0x6d6d, 0x0006,
- 0x0016, 0x2001, 0x8004, 0x0006, 0x0804, 0x0e0b, 0x0096, 0x00f6,
- 0x2079, 0x0050, 0x7044, 0xd084, 0x01d0, 0xc084, 0x7046, 0x7838,
+ 0x00de, 0x701c, 0x2048, 0x7010, 0x8001, 0x7012, 0xa800, 0x701e,
+ 0x9005, 0x1108, 0x701a, 0x012e, 0x0005, 0x0005, 0x0126, 0x2091,
+ 0x8000, 0x701c, 0x904d, 0x0160, 0x7010, 0x8001, 0x7012, 0xa800,
+ 0x701e, 0x9005, 0x1108, 0x701a, 0x012e, 0x080c, 0x1069, 0x0005,
+ 0x012e, 0x0005, 0x2091, 0x8000, 0x0e04, 0x6d6c, 0x0006, 0x0016,
+ 0x2001, 0x8004, 0x0006, 0x0804, 0x0dff, 0x0096, 0x00f6, 0x2079,
+ 0x0050, 0x7044, 0xd084, 0x01d0, 0xc084, 0x7046, 0x7838, 0x7938,
+ 0x910e, 0x1de0, 0x00d6, 0x2069, 0x0000, 0x6836, 0x6833, 0x0013,
+ 0x00de, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c,
+ 0x11e6, 0x704b, 0x0000, 0x00fe, 0x009e, 0x0005, 0x782c, 0x9094,
+ 0x0780, 0x1981, 0xd0a4, 0x0db8, 0x7148, 0x704c, 0x8108, 0x714a,
+ 0x9102, 0x0e88, 0x00e6, 0x2071, 0x1800, 0x7824, 0x00e6, 0x2071,
+ 0x0040, 0x712c, 0xd19c, 0x1148, 0x2009, 0x182f, 0x210c, 0x918a,
+ 0x0040, 0x0218, 0x7022, 0x00ee, 0x0058, 0x00ee, 0x2048, 0x702c,
+ 0xa802, 0x2900, 0x702e, 0x70bc, 0x8000, 0x70be, 0x080c, 0x816f,
+ 0x782c, 0x9094, 0x0780, 0x190c, 0x6d6a, 0xd0a4, 0x19f0, 0x7838,
0x7938, 0x910e, 0x1de0, 0x00d6, 0x2069, 0x0000, 0x6836, 0x6833,
0x0013, 0x00de, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084,
- 0x190c, 0x11f2, 0x704b, 0x0000, 0x00fe, 0x009e, 0x0005, 0x782c,
- 0x9094, 0x0780, 0x1981, 0xd0a4, 0x0db8, 0x7148, 0x704c, 0x8108,
- 0x714a, 0x9102, 0x0e88, 0x00e6, 0x2071, 0x1800, 0x7824, 0x00e6,
- 0x2071, 0x0040, 0x712c, 0xd19c, 0x1148, 0x2009, 0x182f, 0x210c,
- 0x918a, 0x0040, 0x0218, 0x7022, 0x00ee, 0x0058, 0x00ee, 0x2048,
- 0x702c, 0xa802, 0x2900, 0x702e, 0x70bc, 0x8000, 0x70be, 0x080c,
- 0x8170, 0x782c, 0x9094, 0x0780, 0x190c, 0x6d6b, 0xd0a4, 0x19f0,
+ 0x190c, 0x11e6, 0x00ee, 0x704b, 0x0000, 0x00fe, 0x009e, 0x0005,
+ 0x00f6, 0x2079, 0x0050, 0x7044, 0xd084, 0x01b8, 0xc084, 0x7046,
0x7838, 0x7938, 0x910e, 0x1de0, 0x00d6, 0x2069, 0x0000, 0x6836,
0x6833, 0x0013, 0x00de, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004,
- 0xd084, 0x190c, 0x11f2, 0x00ee, 0x704b, 0x0000, 0x00fe, 0x009e,
- 0x0005, 0x00f6, 0x2079, 0x0050, 0x7044, 0xd084, 0x01b8, 0xc084,
- 0x7046, 0x7838, 0x7938, 0x910e, 0x1de0, 0x00d6, 0x2069, 0x0000,
- 0x6836, 0x6833, 0x0013, 0x00de, 0x2091, 0x4080, 0x2001, 0x0089,
- 0x2004, 0xd084, 0x190c, 0x11f2, 0x00fe, 0x0005, 0x782c, 0x9094,
- 0x0780, 0x190c, 0x6d6b, 0xd0a4, 0x0db8, 0x00e6, 0x2071, 0x1800,
- 0x7824, 0x2048, 0x702c, 0xa802, 0x2900, 0x702e, 0x70bc, 0x8000,
- 0x70be, 0x080c, 0x8170, 0x782c, 0x9094, 0x0780, 0x190c, 0x6d6b,
- 0xd0a4, 0x1d70, 0x00d6, 0x2069, 0x0050, 0x693c, 0x2069, 0x1923,
- 0x6808, 0x690a, 0x2069, 0x19d5, 0x9102, 0x1118, 0x6844, 0x9005,
- 0x1320, 0x2001, 0x1924, 0x200c, 0x6946, 0x00de, 0x00ee, 0x00fe,
- 0x0005, 0x7094, 0x908a, 0x002a, 0x1a0c, 0x0e02, 0x9082, 0x001d,
- 0x001b, 0x6027, 0x1e00, 0x0005, 0x6f22, 0x6e8f, 0x6eab, 0x6ed5,
- 0x6f11, 0x6f51, 0x6f63, 0x6eab, 0x6f39, 0x6e4a, 0x6e78, 0x6efb,
- 0x6e49, 0x0005, 0x00d6, 0x2069, 0x0200, 0x6804, 0x9005, 0x1180,
- 0x6808, 0x9005, 0x1518, 0x7097, 0x0029, 0x2069, 0x1969, 0x2d04,
- 0x7002, 0x080c, 0x72ce, 0x6028, 0x9085, 0x0600, 0x602a, 0x00b0,
- 0x7097, 0x0029, 0x2069, 0x1969, 0x2d04, 0x7002, 0x6028, 0x9085,
- 0x0600, 0x602a, 0x00e6, 0x0036, 0x0046, 0x0056, 0x2071, 0x1a3f,
- 0x080c, 0x1983, 0x005e, 0x004e, 0x003e, 0x00ee, 0x00de, 0x0005,
- 0x00d6, 0x2069, 0x0200, 0x6804, 0x9005, 0x1178, 0x6808, 0x9005,
- 0x1160, 0x7097, 0x0029, 0x2069, 0x1969, 0x2d04, 0x7002, 0x080c,
- 0x736a, 0x6028, 0x9085, 0x0600, 0x602a, 0x00de, 0x0005, 0x0006,
- 0x2001, 0x0090, 0x080c, 0x2b88, 0x000e, 0x6124, 0xd1e4, 0x1190,
- 0x080c, 0x6fd0, 0xd1d4, 0x1160, 0xd1dc, 0x1138, 0xd1cc, 0x0150,
- 0x7097, 0x0020, 0x080c, 0x6fd0, 0x0028, 0x7097, 0x001d, 0x0010,
- 0x7097, 0x001f, 0x0005, 0x2001, 0x0088, 0x080c, 0x2b88, 0x6124,
- 0xd1cc, 0x11e8, 0xd1dc, 0x11c0, 0xd1e4, 0x1198, 0x9184, 0x1e00,
- 0x11d8, 0x080c, 0x19a8, 0x60e3, 0x0001, 0x600c, 0xc0b4, 0x600e,
- 0x080c, 0x71ab, 0x2001, 0x0080, 0x080c, 0x2b88, 0x7097, 0x0029,
- 0x0058, 0x7097, 0x001e, 0x0040, 0x7097, 0x001d, 0x0028, 0x7097,
- 0x0020, 0x0010, 0x7097, 0x001f, 0x0005, 0x080c, 0x19a8, 0x60e3,
- 0x0001, 0x600c, 0xc0b4, 0x600e, 0x080c, 0x71ab, 0x2001, 0x0080,
- 0x080c, 0x2b88, 0x6124, 0xd1d4, 0x1198, 0xd1dc, 0x1170, 0xd1e4,
- 0x1148, 0x9184, 0x1e00, 0x1118, 0x7097, 0x0029, 0x0058, 0x7097,
- 0x0028, 0x0040, 0x7097, 0x001e, 0x0028, 0x7097, 0x001d, 0x0010,
- 0x7097, 0x001f, 0x0005, 0x6124, 0xd1d4, 0x1180, 0xd1dc, 0x1158,
- 0xd1e4, 0x1130, 0x9184, 0x1e00, 0x1158, 0x7097, 0x0029, 0x0040,
- 0x7097, 0x001e, 0x0028, 0x7097, 0x001d, 0x0010, 0x7097, 0x001f,
- 0x0005, 0x2001, 0x00a0, 0x080c, 0x2b88, 0x6124, 0xd1dc, 0x1138,
- 0xd1e4, 0x0138, 0x080c, 0x19a8, 0x7097, 0x001e, 0x0010, 0x7097,
- 0x001d, 0x0005, 0x080c, 0x7053, 0x6124, 0xd1dc, 0x1188, 0x080c,
- 0x6fd0, 0x0016, 0x080c, 0x19a8, 0x001e, 0xd1d4, 0x1128, 0xd1e4,
- 0x0138, 0x7097, 0x001e, 0x0020, 0x7097, 0x001f, 0x080c, 0x6fd0,
- 0x0005, 0x0006, 0x2001, 0x00a0, 0x080c, 0x2b88, 0x000e, 0x6124,
- 0xd1d4, 0x1160, 0xd1cc, 0x1150, 0xd1dc, 0x1128, 0xd1e4, 0x0140,
- 0x7097, 0x001e, 0x0028, 0x7097, 0x001d, 0x0010, 0x7097, 0x0021,
- 0x0005, 0x080c, 0x7053, 0x6124, 0xd1d4, 0x1150, 0xd1dc, 0x1128,
- 0xd1e4, 0x0140, 0x7097, 0x001e, 0x0028, 0x7097, 0x001d, 0x0010,
- 0x7097, 0x001f, 0x0005, 0x0006, 0x2001, 0x0090, 0x080c, 0x2b88,
- 0x000e, 0x6124, 0xd1d4, 0x1178, 0xd1cc, 0x1150, 0xd1dc, 0x1128,
- 0xd1e4, 0x0158, 0x7097, 0x001e, 0x0040, 0x7097, 0x001d, 0x0028,
- 0x7097, 0x0020, 0x0010, 0x7097, 0x001f, 0x0005, 0x0016, 0x00c6,
- 0x00d6, 0x00e6, 0x0126, 0x2061, 0x0100, 0x2069, 0x0140, 0x2071,
- 0x1800, 0x2091, 0x8000, 0x080c, 0x717f, 0x11d8, 0x2001, 0x180c,
- 0x200c, 0xd1b4, 0x01b0, 0xc1b4, 0x2102, 0x6027, 0x0200, 0x080c,
- 0x2ab0, 0x6024, 0xd0cc, 0x0148, 0x2001, 0x00a0, 0x080c, 0x2b88,
- 0x080c, 0x747b, 0x080c, 0x5e30, 0x0428, 0x6028, 0xc0cd, 0x602a,
- 0x0408, 0x080c, 0x7199, 0x0150, 0x080c, 0x7190, 0x1138, 0x2001,
- 0x0001, 0x080c, 0x2617, 0x080c, 0x7157, 0x00a0, 0x080c, 0x7050,
- 0x0178, 0x2001, 0x0001, 0x080c, 0x2617, 0x7094, 0x9086, 0x001e,
- 0x0120, 0x7094, 0x9086, 0x0022, 0x1118, 0x7097, 0x0025, 0x0010,
- 0x7097, 0x0021, 0x012e, 0x00ee, 0x00de, 0x00ce, 0x001e, 0x0005,
- 0x0026, 0x2011, 0x6fe1, 0x080c, 0x832e, 0x002e, 0x0016, 0x0026,
- 0x2009, 0x0064, 0x2011, 0x6fe1, 0x080c, 0x8325, 0x002e, 0x001e,
- 0x0005, 0x00e6, 0x00f6, 0x0016, 0x080c, 0x9605, 0x2071, 0x1800,
- 0x080c, 0x6f7e, 0x001e, 0x00fe, 0x00ee, 0x0005, 0x0016, 0x0026,
- 0x0036, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x0126, 0x2071, 0x1800,
- 0x080c, 0x9605, 0x2061, 0x0100, 0x2069, 0x0140, 0x2091, 0x8000,
- 0x6028, 0xc09c, 0x602a, 0x2011, 0x0003, 0x080c, 0x990e, 0x2011,
- 0x0002, 0x080c, 0x9918, 0x080c, 0x9826, 0x080c, 0x82da, 0x0036,
- 0x901e, 0x080c, 0x989c, 0x003e, 0x60e3, 0x0000, 0x080c, 0xdb7a,
- 0x080c, 0xdb95, 0x2009, 0x0004, 0x080c, 0x2ab6, 0x080c, 0x2989,
- 0x2001, 0x1800, 0x2003, 0x0004, 0x6027, 0x0008, 0x2011, 0x6fe1,
- 0x080c, 0x832e, 0x080c, 0x7199, 0x0118, 0x9006, 0x080c, 0x2b88,
- 0x080c, 0x0b8f, 0x2001, 0x0001, 0x080c, 0x2617, 0x012e, 0x00fe,
- 0x00ee, 0x00de, 0x00ce, 0x003e, 0x002e, 0x001e, 0x0005, 0x0026,
- 0x00e6, 0x2011, 0x6fee, 0x2071, 0x19d5, 0x701c, 0x9206, 0x1118,
- 0x7018, 0x9005, 0x0110, 0x9085, 0x0001, 0x00ee, 0x002e, 0x0005,
- 0x6020, 0xd09c, 0x0005, 0x6800, 0x9084, 0xfffe, 0x9086, 0x00c0,
- 0x01b8, 0x2001, 0x00c0, 0x080c, 0x2b88, 0x0156, 0x20a9, 0x002d,
- 0x1d04, 0x7060, 0x2091, 0x6000, 0x1f04, 0x7060, 0x015e, 0x00d6,
- 0x2069, 0x1800, 0x6898, 0x8001, 0x0220, 0x0118, 0x689a, 0x00de,
- 0x0005, 0x689b, 0x0014, 0x68e4, 0xd0dc, 0x0dc8, 0x6800, 0x9086,
- 0x0001, 0x1da8, 0x080c, 0x833a, 0x0c90, 0x00c6, 0x00d6, 0x00e6,
- 0x2061, 0x0100, 0x2069, 0x0140, 0x2071, 0x1800, 0x080c, 0x748a,
- 0x2001, 0x1947, 0x2003, 0x0000, 0x9006, 0x7096, 0x60e2, 0x6886,
- 0x080c, 0x26e2, 0x9006, 0x080c, 0x2b88, 0x080c, 0x5cef, 0x6027,
- 0xffff, 0x602b, 0x182f, 0x00ee, 0x00de, 0x00ce, 0x0005, 0x00c6,
- 0x00d6, 0x00e6, 0x2061, 0x0100, 0x2069, 0x0140, 0x2071, 0x1800,
- 0x2001, 0x1957, 0x200c, 0x9186, 0x0000, 0x0158, 0x9186, 0x0001,
- 0x0158, 0x9186, 0x0002, 0x0158, 0x9186, 0x0003, 0x0158, 0x0804,
- 0x7147, 0x7097, 0x0022, 0x0040, 0x7097, 0x0021, 0x0028, 0x7097,
- 0x0023, 0x0010, 0x7097, 0x0024, 0x60e3, 0x0000, 0x6887, 0x0001,
- 0x2001, 0x0001, 0x080c, 0x26e2, 0x0026, 0x080c, 0x9f5b, 0x002e,
- 0x7000, 0x908e, 0x0004, 0x0118, 0x602b, 0x0028, 0x0010, 0x602b,
- 0x0020, 0x0156, 0x0126, 0x2091, 0x8000, 0x20a9, 0x0005, 0x6024,
- 0xd0ac, 0x0150, 0x012e, 0x015e, 0x080c, 0xc444, 0x0118, 0x9006,
- 0x080c, 0x2bb2, 0x0804, 0x7153, 0x6800, 0x9084, 0x00a1, 0xc0bd,
- 0x6802, 0x080c, 0x2ab0, 0x6904, 0xd1d4, 0x1140, 0x2001, 0x0100,
- 0x080c, 0x2b88, 0x1f04, 0x70df, 0x080c, 0x71d3, 0x012e, 0x015e,
- 0x080c, 0x7190, 0x0538, 0x6044, 0x9005, 0x01f8, 0x2001, 0x0100,
- 0x2004, 0x9086, 0x000a, 0x0158, 0x2011, 0x0114, 0x2204, 0x9085,
- 0x0100, 0x2012, 0x6050, 0x0006, 0x9085, 0x0020, 0x6052, 0x080c,
- 0x71d3, 0x9006, 0x8001, 0x1df0, 0x2001, 0x0100, 0x2004, 0x9086,
- 0x000a, 0x0140, 0x000e, 0x6052, 0x0028, 0x6804, 0xd0d4, 0x1110,
- 0x080c, 0x71d3, 0x080c, 0xc444, 0x0118, 0x9006, 0x080c, 0x2bb2,
- 0x0016, 0x0026, 0x7000, 0x908e, 0x0004, 0x0130, 0x2009, 0x00c8,
- 0x2011, 0x6fee, 0x080c, 0x82ec, 0x002e, 0x001e, 0x080c, 0x8167,
- 0x7034, 0xc085, 0x7036, 0x2001, 0x1957, 0x2003, 0x0004, 0x080c,
- 0x6e31, 0x080c, 0x7190, 0x0138, 0x6804, 0xd0d4, 0x1120, 0xd0dc,
- 0x1100, 0x080c, 0x7480, 0x00ee, 0x00de, 0x00ce, 0x0005, 0x00c6,
- 0x00d6, 0x00e6, 0x2061, 0x0100, 0x2069, 0x0140, 0x2071, 0x1800,
- 0x080c, 0x817e, 0x080c, 0x8170, 0x080c, 0x748a, 0x2001, 0x1947,
- 0x2003, 0x0000, 0x9006, 0x7096, 0x60e2, 0x6886, 0x080c, 0x26e2,
- 0x9006, 0x080c, 0x2b88, 0x6043, 0x0090, 0x6043, 0x0010, 0x6027,
- 0xffff, 0x602b, 0x182f, 0x00ee, 0x00de, 0x00ce, 0x0005, 0x0006,
- 0x2001, 0x1956, 0x2004, 0x9086, 0xaaaa, 0x000e, 0x0005, 0x0006,
- 0x080c, 0x54e0, 0x9084, 0x0030, 0x9086, 0x0000, 0x000e, 0x0005,
- 0x0006, 0x080c, 0x54e0, 0x9084, 0x0030, 0x9086, 0x0030, 0x000e,
- 0x0005, 0x0006, 0x080c, 0x54e0, 0x9084, 0x0030, 0x9086, 0x0010,
- 0x000e, 0x0005, 0x0006, 0x080c, 0x54e0, 0x9084, 0x0030, 0x9086,
- 0x0020, 0x000e, 0x0005, 0x0036, 0x0016, 0x2001, 0x180c, 0x2004,
- 0x908c, 0x0013, 0x0168, 0x0020, 0x080c, 0x2702, 0x900e, 0x0010,
- 0x2009, 0x0002, 0x2019, 0x0028, 0x080c, 0x3076, 0x9006, 0x0019,
- 0x001e, 0x003e, 0x0005, 0x00e6, 0x2071, 0x180c, 0x2e04, 0x0130,
- 0x080c, 0xc43d, 0x1128, 0x9085, 0x0010, 0x0010, 0x9084, 0xffef,
- 0x2072, 0x00ee, 0x0005, 0x6050, 0x0006, 0x60ec, 0x0006, 0x600c,
- 0x0006, 0x6004, 0x0006, 0x6028, 0x0006, 0x2001, 0x0100, 0x2004,
- 0x9086, 0x000a, 0x0510, 0x0016, 0x6138, 0x6050, 0x9084, 0xfbff,
- 0x9085, 0x2000, 0x6052, 0x613a, 0x20a9, 0x0012, 0x1d04, 0x71ee,
- 0x2091, 0x6000, 0x1f04, 0x71ee, 0x602f, 0x0100, 0x602f, 0x0000,
- 0x6050, 0x9085, 0x0400, 0x9084, 0xdfff, 0x6052, 0x613a, 0x001e,
- 0x602f, 0x0040, 0x602f, 0x0000, 0x00a0, 0x080c, 0x2bc2, 0x080c,
- 0x2bf5, 0x602f, 0x0100, 0x602f, 0x0000, 0x602f, 0x0040, 0x602f,
- 0x0000, 0x20a9, 0x0002, 0x080c, 0x2a91, 0x0026, 0x6027, 0x0040,
- 0x002e, 0x000e, 0x602a, 0x000e, 0x6006, 0x000e, 0x600e, 0x000e,
- 0x60ee, 0x60e3, 0x0000, 0x6887, 0x0001, 0x2001, 0x0001, 0x080c,
- 0x26e2, 0x2001, 0x00a0, 0x0006, 0x080c, 0xc444, 0x000e, 0x0130,
- 0x080c, 0x2ba6, 0x9006, 0x080c, 0x2bb2, 0x0010, 0x080c, 0x2b88,
- 0x000e, 0x6052, 0x6050, 0x0006, 0xc0e5, 0x6052, 0x00f6, 0x2079,
- 0x0100, 0x080c, 0x2a06, 0x00fe, 0x000e, 0x6052, 0x0005, 0x0156,
- 0x0016, 0x0026, 0x0036, 0x00c6, 0x00d6, 0x00e6, 0x2061, 0x0100,
- 0x2069, 0x0140, 0x2071, 0x1800, 0x6020, 0x9084, 0x0080, 0x0138,
- 0x2001, 0x180c, 0x200c, 0xc1c5, 0x2102, 0x0804, 0x72c0, 0x2001,
- 0x180c, 0x200c, 0xc1c4, 0x2102, 0x6028, 0x9084, 0xe1ff, 0x602a,
- 0x6027, 0x0200, 0x2001, 0x0090, 0x080c, 0x2b88, 0x20a9, 0x0366,
- 0x6024, 0xd0cc, 0x1518, 0x1d04, 0x7270, 0x2091, 0x6000, 0x1f04,
- 0x7270, 0x2011, 0x0003, 0x080c, 0x990e, 0x2011, 0x0002, 0x080c,
- 0x9918, 0x080c, 0x9826, 0x901e, 0x080c, 0x989c, 0x2001, 0x00a0,
- 0x080c, 0x2b88, 0x080c, 0x747b, 0x080c, 0x5e30, 0x080c, 0xc444,
- 0x0110, 0x080c, 0x0d70, 0x9085, 0x0001, 0x0480, 0x080c, 0x19a8,
- 0x60e3, 0x0000, 0x2001, 0x0002, 0x080c, 0x26e2, 0x60e2, 0x2001,
- 0x0080, 0x080c, 0x2b88, 0x20a9, 0x0366, 0x6027, 0x1e00, 0x2009,
- 0x1e00, 0x080c, 0x2ab0, 0x6024, 0x910c, 0x0138, 0x1d04, 0x72a5,
- 0x2091, 0x6000, 0x1f04, 0x72a5, 0x0820, 0x6028, 0x9085, 0x1e00,
- 0x602a, 0x70b0, 0x9005, 0x1118, 0x6887, 0x0001, 0x0008, 0x6886,
- 0x080c, 0xc444, 0x0110, 0x080c, 0x0d70, 0x9006, 0x00ee, 0x00de,
- 0x00ce, 0x003e, 0x002e, 0x001e, 0x015e, 0x0005, 0x0156, 0x0016,
- 0x0026, 0x0036, 0x00c6, 0x00d6, 0x00e6, 0x2061, 0x0100, 0x2071,
- 0x1800, 0x7000, 0x9086, 0x0003, 0x1168, 0x2001, 0x020b, 0x2004,
- 0x9084, 0x5540, 0x9086, 0x5540, 0x1128, 0x2069, 0x1a54, 0x2d04,
- 0x8000, 0x206a, 0x2069, 0x0140, 0x6020, 0x9084, 0x00c0, 0x0120,
- 0x6884, 0x9005, 0x1904, 0x7333, 0x2001, 0x0088, 0x080c, 0x2b88,
- 0x9006, 0x60e2, 0x6886, 0x080c, 0x26e2, 0x2069, 0x0200, 0x6804,
- 0x9005, 0x1118, 0x6808, 0x9005, 0x01c0, 0x6028, 0x9084, 0xfbff,
- 0x602a, 0x6027, 0x0400, 0x2069, 0x1969, 0x7000, 0x206a, 0x7097,
- 0x0026, 0x7003, 0x0001, 0x20a9, 0x0002, 0x1d04, 0x7315, 0x2091,
- 0x6000, 0x1f04, 0x7315, 0x0804, 0x7362, 0x2069, 0x0140, 0x20a9,
- 0x0384, 0x6027, 0x1e00, 0x2009, 0x1e00, 0x080c, 0x2ab0, 0x6024,
- 0x910c, 0x0508, 0x9084, 0x1a00, 0x11f0, 0x1d04, 0x7321, 0x2091,
- 0x6000, 0x1f04, 0x7321, 0x2011, 0x0003, 0x080c, 0x990e, 0x2011,
- 0x0002, 0x080c, 0x9918, 0x080c, 0x9826, 0x901e, 0x080c, 0x989c,
- 0x2001, 0x00a0, 0x080c, 0x2b88, 0x080c, 0x747b, 0x080c, 0x5e30,
- 0x9085, 0x0001, 0x00b8, 0x080c, 0x19a8, 0x2001, 0x0080, 0x080c,
- 0x2b88, 0x2069, 0x0140, 0x60e3, 0x0000, 0x70b0, 0x9005, 0x1118,
- 0x6887, 0x0001, 0x0008, 0x6886, 0x2001, 0x0002, 0x080c, 0x26e2,
- 0x60e2, 0x9006, 0x00ee, 0x00de, 0x00ce, 0x003e, 0x002e, 0x001e,
- 0x015e, 0x0005, 0x0156, 0x0016, 0x0026, 0x0036, 0x00c6, 0x00d6,
- 0x00e6, 0x2061, 0x0100, 0x2071, 0x1800, 0x6020, 0x9084, 0x00c0,
- 0x01c8, 0x2011, 0x0003, 0x080c, 0x990e, 0x2011, 0x0002, 0x080c,
- 0x9918, 0x080c, 0x9826, 0x901e, 0x080c, 0x989c, 0x2069, 0x0140,
- 0x2001, 0x00a0, 0x080c, 0x2b88, 0x080c, 0x747b, 0x080c, 0x5e30,
- 0x0804, 0x73fc, 0x2001, 0x180c, 0x200c, 0xd1b4, 0x1160, 0xc1b5,
- 0x2102, 0x080c, 0x6fd6, 0x2069, 0x0140, 0x2001, 0x0080, 0x080c,
- 0x2b88, 0x60e3, 0x0000, 0x2069, 0x0200, 0x6804, 0x9005, 0x1118,
- 0x6808, 0x9005, 0x0180, 0x6028, 0x9084, 0xfdff, 0x602a, 0x6027,
- 0x0200, 0x2069, 0x1969, 0x7000, 0x206a, 0x7097, 0x0027, 0x7003,
- 0x0001, 0x0804, 0x73fc, 0x6027, 0x1e00, 0x2009, 0x1e00, 0x080c,
- 0x2ab0, 0x6024, 0x910c, 0x01c8, 0x9084, 0x1c00, 0x11b0, 0x1d04,
- 0x73bb, 0x0006, 0x0016, 0x00c6, 0x00d6, 0x00e6, 0x080c, 0x81be,
- 0x00ee, 0x00de, 0x00ce, 0x001e, 0x000e, 0x00e6, 0x2071, 0x19d5,
- 0x7078, 0x00ee, 0x9005, 0x19f8, 0x00f8, 0x0026, 0x2011, 0x6fee,
- 0x080c, 0x825a, 0x2011, 0x6fe1, 0x080c, 0x832e, 0x002e, 0x2069,
- 0x0140, 0x60e3, 0x0000, 0x70b0, 0x9005, 0x1118, 0x6887, 0x0001,
- 0x0008, 0x6886, 0x2001, 0x0002, 0x080c, 0x26e2, 0x60e2, 0x2001,
- 0x180c, 0x200c, 0xc1b4, 0x2102, 0x00ee, 0x00de, 0x00ce, 0x003e,
- 0x002e, 0x001e, 0x015e, 0x0005, 0x0156, 0x0016, 0x0026, 0x0036,
- 0x0046, 0x00c6, 0x00e6, 0x2061, 0x0100, 0x2071, 0x1800, 0x080c,
- 0xc43d, 0x1904, 0x7469, 0x7130, 0xd184, 0x1170, 0x080c, 0x3204,
- 0x0138, 0xc18d, 0x7132, 0x2011, 0x185c, 0x2214, 0xd2ac, 0x1120,
- 0x7030, 0xd08c, 0x0904, 0x7469, 0x2011, 0x185c, 0x220c, 0x0438,
- 0x0016, 0x2019, 0x000e, 0x080c, 0xd74e, 0x0156, 0x00b6, 0x20a9,
- 0x007f, 0x900e, 0x9186, 0x007e, 0x01a0, 0x9186, 0x0080, 0x0188,
- 0x080c, 0x63a4, 0x1170, 0x2120, 0x9006, 0x0016, 0x2009, 0x000e,
- 0x080c, 0xd7d6, 0x2009, 0x0001, 0x2011, 0x0100, 0x080c, 0x8451,
- 0x001e, 0x8108, 0x1f04, 0x7432, 0x00be, 0x015e, 0x001e, 0xd1ac,
- 0x1148, 0x0016, 0x2009, 0x0002, 0x2019, 0x0004, 0x080c, 0x3076,
- 0x001e, 0x0078, 0x0156, 0x00b6, 0x20a9, 0x007f, 0x900e, 0x080c,
- 0x63a4, 0x1110, 0x080c, 0x5e4a, 0x8108, 0x1f04, 0x745f, 0x00be,
- 0x015e, 0x080c, 0x19a8, 0x080c, 0x9f5b, 0x60e3, 0x0000, 0x080c,
- 0x5e30, 0x080c, 0x709f, 0x00ee, 0x00ce, 0x004e, 0x003e, 0x002e,
- 0x001e, 0x015e, 0x0005, 0x2001, 0x1957, 0x2003, 0x0001, 0x0005,
- 0x2001, 0x1957, 0x2003, 0x0000, 0x0005, 0x2001, 0x1956, 0x2003,
- 0xaaaa, 0x0005, 0x2001, 0x1956, 0x2003, 0x0000, 0x0005, 0x2071,
- 0x18f8, 0x7003, 0x0000, 0x7007, 0x0000, 0x080c, 0x105c, 0x090c,
- 0x0e02, 0xa8ab, 0xdcb0, 0x2900, 0x704e, 0x080c, 0x105c, 0x090c,
- 0x0e02, 0xa8ab, 0xdcb0, 0x2900, 0x7052, 0xa867, 0x0000, 0xa86b,
- 0x0001, 0xa89f, 0x0000, 0x0005, 0x00e6, 0x2071, 0x0040, 0x6848,
- 0x9005, 0x1118, 0x9085, 0x0001, 0x04b0, 0x6840, 0x9005, 0x0150,
- 0x04a1, 0x6a50, 0x9200, 0x7002, 0x6854, 0x9101, 0x7006, 0x9006,
- 0x7012, 0x7016, 0x6850, 0x7002, 0x6854, 0x7006, 0x6858, 0x700a,
- 0x685c, 0x700e, 0x6840, 0x9005, 0x1110, 0x7012, 0x7016, 0x6848,
- 0x701a, 0x701c, 0x9085, 0x0040, 0x701e, 0x2001, 0x0019, 0x7036,
- 0x702b, 0x0001, 0x2001, 0x0004, 0x200c, 0x918c, 0xfff7, 0x918d,
- 0x8000, 0x2102, 0x00d6, 0x2069, 0x18f8, 0x6807, 0x0001, 0x00de,
- 0x080c, 0x7a7d, 0x9006, 0x00ee, 0x0005, 0x900e, 0x0156, 0x20a9,
- 0x0006, 0x8003, 0x818d, 0x1f04, 0x74f1, 0x015e, 0x0005, 0x2079,
- 0x0040, 0x2071, 0x18f8, 0x7004, 0x0002, 0x7507, 0x7508, 0x7540,
- 0x759b, 0x76e0, 0x7505, 0x7505, 0x770a, 0x080c, 0x0e02, 0x0005,
- 0x2079, 0x0040, 0x782c, 0x908c, 0x0780, 0x190c, 0x7b09, 0xd0a4,
- 0x01f8, 0x7824, 0x2048, 0x9006, 0xa802, 0xa806, 0xa864, 0x9084,
- 0x00ff, 0x908a, 0x0040, 0x0610, 0x00c0, 0x2001, 0x1800, 0x200c,
- 0x9186, 0x0003, 0x1168, 0x7004, 0x0002, 0x7530, 0x750a, 0x7530,
- 0x752e, 0x7530, 0x7530, 0x7530, 0x7530, 0x7530, 0x080c, 0x759b,
- 0x782c, 0xd09c, 0x090c, 0x7a7d, 0x0005, 0x9082, 0x005a, 0x1218,
- 0x2100, 0x003b, 0x0c10, 0x080c, 0x75d1, 0x0c90, 0x00e3, 0x08e8,
- 0x0005, 0x75d1, 0x75d1, 0x75d1, 0x75d1, 0x75d1, 0x75d1, 0x75d1,
- 0x75d1, 0x75f3, 0x75d1, 0x75d1, 0x75d1, 0x75d1, 0x75d1, 0x75d1,
- 0x75d1, 0x75d1, 0x75d1, 0x75d1, 0x75d1, 0x75d1, 0x75d1, 0x75d1,
- 0x75d1, 0x75d1, 0x75d1, 0x75d1, 0x75d1, 0x75dd, 0x75d1, 0x77e4,
- 0x75d1, 0x75d1, 0x75d1, 0x75f3, 0x75d1, 0x75dd, 0x7825, 0x7866,
- 0x78ad, 0x78c1, 0x75d1, 0x75d1, 0x75f3, 0x75dd, 0x75d1, 0x75d1,
- 0x76b4, 0x796c, 0x7987, 0x75d1, 0x75f3, 0x75d1, 0x75d1, 0x75d1,
- 0x75d1, 0x76aa, 0x7987, 0x75d1, 0x75d1, 0x75d1, 0x75d1, 0x75d1,
- 0x75d1, 0x75d1, 0x75d1, 0x75d1, 0x7607, 0x75d1, 0x75d1, 0x75d1,
- 0x75d1, 0x75d1, 0x75d1, 0x75d1, 0x75d1, 0x75d1, 0x7aad, 0x75d1,
- 0x75d1, 0x75d1, 0x75d1, 0x75d1, 0x761b, 0x75d1, 0x75d1, 0x75d1,
- 0x75d1, 0x75d1, 0x75d1, 0x2079, 0x0040, 0x7004, 0x9086, 0x0003,
- 0x1198, 0x782c, 0x080c, 0x7aa6, 0xd0a4, 0x0170, 0x7824, 0x2048,
- 0x9006, 0xa802, 0xa806, 0xa864, 0x9084, 0x00ff, 0x908a, 0x001a,
- 0x1210, 0x002b, 0x0c50, 0x00e9, 0x080c, 0x7a7d, 0x0005, 0x75d1,
- 0x75dd, 0x77d0, 0x75d1, 0x75dd, 0x75d1, 0x75dd, 0x75dd, 0x75d1,
- 0x75dd, 0x77d0, 0x75dd, 0x75dd, 0x75dd, 0x75dd, 0x75dd, 0x75d1,
- 0x75dd, 0x77d0, 0x75d1, 0x75d1, 0x75dd, 0x75d1, 0x75d1, 0x75d1,
- 0x75dd, 0x00e6, 0x2071, 0x18f8, 0x2009, 0x0400, 0x0071, 0x00ee,
- 0x0005, 0x2009, 0x1000, 0x0049, 0x0005, 0x2009, 0x2000, 0x0029,
- 0x0005, 0x2009, 0x0800, 0x0009, 0x0005, 0x7007, 0x0001, 0xa868,
- 0x9084, 0x00ff, 0x9105, 0xa86a, 0x0126, 0x2091, 0x8000, 0x080c,
- 0x6a23, 0x012e, 0x0005, 0xa864, 0x8007, 0x9084, 0x00ff, 0x0d08,
- 0x8001, 0x1120, 0x7007, 0x0001, 0x0804, 0x7789, 0x7007, 0x0003,
- 0x7012, 0x2900, 0x7016, 0x701a, 0x704b, 0x7789, 0x0005, 0xa864,
- 0x8007, 0x9084, 0x00ff, 0x0968, 0x8001, 0x1120, 0x7007, 0x0001,
- 0x0804, 0x77a4, 0x7007, 0x0003, 0x7012, 0x2900, 0x7016, 0x701a,
- 0x704b, 0x77a4, 0x0005, 0xa864, 0x8007, 0x9084, 0x00ff, 0x9086,
- 0x0001, 0x1904, 0x75d9, 0x7007, 0x0001, 0x2009, 0x1833, 0x210c,
- 0x81ff, 0x1904, 0x7681, 0xa99c, 0x9186, 0x00ff, 0x05e8, 0xa994,
- 0x9186, 0x006f, 0x0188, 0x9186, 0x0074, 0x15b0, 0x0026, 0x2011,
- 0x0010, 0x080c, 0x66ee, 0x002e, 0x0578, 0x0016, 0xa998, 0x080c,
- 0x6738, 0x001e, 0x1548, 0x0400, 0x080c, 0x717f, 0x0140, 0xa897,
- 0x4005, 0xa89b, 0x0016, 0x2001, 0x0030, 0x900e, 0x0438, 0x0026,
- 0x2011, 0x8008, 0x080c, 0x66ee, 0x002e, 0x01b0, 0x0016, 0x0026,
- 0x0036, 0xa998, 0xaaa0, 0xab9c, 0x918d, 0x8000, 0x080c, 0x6738,
- 0x003e, 0x002e, 0x001e, 0x1140, 0xa897, 0x4005, 0xa89b, 0x4009,
- 0x2001, 0x0030, 0x900e, 0x0050, 0xa868, 0x9084, 0x00ff, 0xa86a,
- 0xa883, 0x0000, 0x080c, 0x6062, 0x1108, 0x0005, 0x0126, 0x2091,
- 0x8000, 0xa867, 0x0139, 0xa87a, 0xa982, 0x080c, 0x6a23, 0x012e,
- 0x0ca0, 0xa994, 0x9186, 0x0071, 0x0904, 0x762b, 0x9186, 0x0064,
- 0x0904, 0x762b, 0x9186, 0x007c, 0x0904, 0x762b, 0x9186, 0x0028,
- 0x0904, 0x762b, 0x9186, 0x0038, 0x0904, 0x762b, 0x9186, 0x0078,
- 0x0904, 0x762b, 0x9186, 0x005f, 0x0904, 0x762b, 0x9186, 0x0056,
- 0x0904, 0x762b, 0xa897, 0x4005, 0xa89b, 0x0001, 0x2001, 0x0030,
- 0x900e, 0x0860, 0xa87c, 0x9084, 0x00c0, 0x9086, 0x00c0, 0x1120,
- 0x7007, 0x0001, 0x0804, 0x799e, 0x2900, 0x7016, 0x701a, 0x20a9,
- 0x0004, 0xa860, 0x20e0, 0xa85c, 0x9080, 0x0030, 0x2098, 0x7050,
- 0x2040, 0xa060, 0x20e8, 0xa05c, 0x9080, 0x0023, 0x20a0, 0x4003,
- 0xa888, 0x7012, 0x9082, 0x0401, 0x1a04, 0x75e1, 0xaab4, 0x928a,
- 0x0002, 0x1a04, 0x75e1, 0x82ff, 0x1138, 0xa8b8, 0xa9bc, 0x9105,
- 0x0118, 0x2001, 0x7747, 0x0018, 0x9280, 0x773d, 0x2005, 0x7056,
- 0x7010, 0x9015, 0x0904, 0x7728, 0x080c, 0x105c, 0x1118, 0x7007,
- 0x0004, 0x0005, 0x2900, 0x7022, 0x7054, 0x2060, 0xe000, 0xa866,
- 0x7050, 0x2040, 0xa95c, 0xe004, 0x9100, 0xa076, 0xa860, 0xa072,
- 0xe008, 0x920a, 0x1210, 0x900e, 0x2200, 0x7112, 0xe20c, 0x8003,
- 0x800b, 0x9296, 0x0004, 0x0108, 0x9108, 0xa17a, 0x810b, 0xa17e,
- 0x080c, 0x1140, 0xa06c, 0x908e, 0x0100, 0x0170, 0x9086, 0x0200,
- 0x0118, 0x7007, 0x0007, 0x0005, 0x7020, 0x2048, 0x080c, 0x1075,
- 0x7014, 0x2048, 0x0804, 0x75e1, 0x7020, 0x2048, 0x7018, 0xa802,
- 0xa807, 0x0000, 0x2908, 0x2048, 0xa906, 0x711a, 0x0804, 0x76e0,
- 0x7014, 0x2048, 0x7007, 0x0001, 0xa8b4, 0x9005, 0x1128, 0xa8b8,
- 0xa9bc, 0x9105, 0x0108, 0x00b9, 0xa864, 0x9084, 0x00ff, 0x9086,
- 0x001e, 0x0904, 0x799e, 0x0804, 0x7789, 0x773f, 0x7743, 0x0002,
- 0x001d, 0x0007, 0x0004, 0x000a, 0x001b, 0x0005, 0x0006, 0x000a,
- 0x001d, 0x0005, 0x0004, 0x0076, 0x0066, 0xafb8, 0xaebc, 0xa804,
- 0x2050, 0xb0c0, 0xb0e2, 0xb0bc, 0xb0de, 0xb0b8, 0xb0d2, 0xb0b4,
- 0xb0ce, 0xb6da, 0xb7d6, 0xb0b0, 0xb0ca, 0xb0ac, 0xb0c6, 0xb0a8,
- 0xb0ba, 0xb0a4, 0xb0b6, 0xb6c2, 0xb7be, 0xb0a0, 0xb0b2, 0xb09c,
- 0xb0ae, 0xb098, 0xb0a2, 0xb094, 0xb09e, 0xb6aa, 0xb7a6, 0xb090,
- 0xb09a, 0xb08c, 0xb096, 0xb088, 0xb08a, 0xb084, 0xb086, 0xb692,
- 0xb78e, 0xb080, 0xb082, 0xb07c, 0xb07e, 0xb078, 0xb072, 0xb074,
- 0xb06e, 0xb67a, 0xb776, 0xb004, 0x9055, 0x1958, 0x006e, 0x007e,
- 0x0005, 0x2009, 0x1833, 0x210c, 0x81ff, 0x1178, 0x080c, 0x5eac,
- 0x1108, 0x0005, 0x080c, 0x6c6c, 0x0126, 0x2091, 0x8000, 0x080c,
- 0xc031, 0x080c, 0x6a23, 0x012e, 0x0ca0, 0x080c, 0xc43d, 0x1d70,
- 0x2001, 0x0028, 0x900e, 0x0c70, 0x0419, 0x11d8, 0xa888, 0x9005,
- 0x01e0, 0xa883, 0x0000, 0xa87c, 0xd0f4, 0x0120, 0x080c, 0x5fc4,
- 0x1138, 0x0005, 0x9006, 0xa87a, 0x080c, 0x5f3c, 0x1108, 0x0005,
- 0x0126, 0x2091, 0x8000, 0xa87a, 0xa982, 0x080c, 0x6a23, 0x012e,
- 0x0cb0, 0x2001, 0x0028, 0x900e, 0x0c98, 0x2001, 0x0000, 0x0c80,
- 0x00c6, 0x2061, 0x1800, 0x60cc, 0x9005, 0x0100, 0x00ce, 0x0005,
- 0x7018, 0xa802, 0x2908, 0x2048, 0xa906, 0x711a, 0x7010, 0x8001,
- 0x7012, 0x0118, 0x7007, 0x0003, 0x0030, 0x7014, 0x2048, 0x7007,
- 0x0001, 0x7048, 0x080f, 0x0005, 0x00b6, 0x7007, 0x0001, 0xa974,
- 0xa878, 0x9084, 0x00ff, 0x9096, 0x0004, 0x0540, 0x20a9, 0x0001,
- 0x9096, 0x0001, 0x0190, 0x900e, 0x20a9, 0x0800, 0x9096, 0x0002,
- 0x0160, 0x9005, 0x11d8, 0xa974, 0x080c, 0x63a4, 0x11b8, 0x0066,
- 0xae80, 0x080c, 0x64b4, 0x006e, 0x0088, 0x0046, 0x2011, 0x180c,
- 0x2224, 0xc484, 0x2412, 0x004e, 0x00c6, 0x080c, 0x63a4, 0x1110,
- 0x080c, 0x65b4, 0x8108, 0x1f04, 0x780d, 0x00ce, 0xa87c, 0xd084,
- 0x1120, 0x080c, 0x1075, 0x00be, 0x0005, 0x0126, 0x2091, 0x8000,
- 0x080c, 0x6a23, 0x012e, 0x00be, 0x0005, 0x0126, 0x2091, 0x8000,
- 0x7007, 0x0001, 0x080c, 0x66c6, 0x0580, 0x2061, 0x1a4c, 0x6100,
- 0xd184, 0x0178, 0xa888, 0x9084, 0x00ff, 0x1550, 0x6000, 0xd084,
- 0x0520, 0x6004, 0x9005, 0x1538, 0x6003, 0x0000, 0x600b, 0x0000,
- 0x00c8, 0x2011, 0x0001, 0xa890, 0x9005, 0x1110, 0x2001, 0x001e,
- 0x8000, 0x6016, 0xa888, 0x9084, 0x00ff, 0x0178, 0x6006, 0xa888,
- 0x8007, 0x9084, 0x00ff, 0x0148, 0x600a, 0xa888, 0x8000, 0x1108,
- 0xc28d, 0x6202, 0x012e, 0x0804, 0x7a67, 0x012e, 0x0804, 0x7a61,
- 0x012e, 0x0804, 0x7a5b, 0x012e, 0x0804, 0x7a5e, 0x0126, 0x2091,
- 0x8000, 0x7007, 0x0001, 0x080c, 0x66c6, 0x05e0, 0x2061, 0x1a4c,
- 0x6000, 0xd084, 0x05b8, 0x6204, 0x6308, 0xd08c, 0x1530, 0xac78,
- 0x9484, 0x0003, 0x0170, 0xa988, 0x918c, 0x00ff, 0x8001, 0x1120,
- 0x2100, 0x9210, 0x0620, 0x0028, 0x8001, 0x1508, 0x2100, 0x9212,
- 0x02f0, 0x9484, 0x000c, 0x0188, 0xa988, 0x810f, 0x918c, 0x00ff,
- 0x9082, 0x0004, 0x1120, 0x2100, 0x9318, 0x0288, 0x0030, 0x9082,
- 0x0004, 0x1168, 0x2100, 0x931a, 0x0250, 0xa890, 0x9005, 0x0110,
- 0x8000, 0x6016, 0x6206, 0x630a, 0x012e, 0x0804, 0x7a67, 0x012e,
- 0x0804, 0x7a64, 0x012e, 0x0804, 0x7a61, 0x0126, 0x2091, 0x8000,
- 0x7007, 0x0001, 0x2061, 0x1a4c, 0x6300, 0xd38c, 0x1120, 0x6308,
- 0x8318, 0x0220, 0x630a, 0x012e, 0x0804, 0x7a75, 0x012e, 0x0804,
- 0x7a64, 0x00b6, 0x0126, 0x00c6, 0x2091, 0x8000, 0x7007, 0x0001,
- 0xa87c, 0xd0ac, 0x0148, 0x00c6, 0x2061, 0x1a4c, 0x6000, 0x9084,
- 0xfcff, 0x6002, 0x00ce, 0x0440, 0xa888, 0x9005, 0x05d8, 0xa88c,
- 0x9065, 0x0598, 0x2001, 0x1833, 0x2004, 0x9005, 0x0118, 0x080c,
- 0xa007, 0x0068, 0x6017, 0xf400, 0x605b, 0x0000, 0xa97c, 0xd1a4,
- 0x0110, 0xa980, 0x615a, 0x2009, 0x0041, 0x080c, 0xa053, 0xa988,
- 0x918c, 0xff00, 0x9186, 0x2000, 0x1138, 0x0026, 0x900e, 0x2011,
- 0xfdff, 0x080c, 0x8451, 0x002e, 0xa87c, 0xd0c4, 0x0148, 0x2061,
- 0x1a4c, 0x6000, 0xd08c, 0x1120, 0x6008, 0x8000, 0x0208, 0x600a,
- 0x00ce, 0x012e, 0x00be, 0x0804, 0x7a67, 0x00ce, 0x012e, 0x00be,
- 0x0804, 0x7a61, 0xa984, 0x9186, 0x002e, 0x0d30, 0x9186, 0x002d,
- 0x0d18, 0x9186, 0x0045, 0x0510, 0x9186, 0x002a, 0x1130, 0x2001,
- 0x180c, 0x200c, 0xc194, 0x2102, 0x08b8, 0x9186, 0x0020, 0x0158,
- 0x9186, 0x0029, 0x1d10, 0xa974, 0x080c, 0x63a4, 0x1968, 0xb800,
- 0xc0e4, 0xb802, 0x0848, 0xa88c, 0x9065, 0x09b8, 0x6007, 0x0024,
- 0x2001, 0x1960, 0x2004, 0x601a, 0x0804, 0x78fc, 0xa88c, 0x9065,
- 0x0960, 0x00e6, 0xa890, 0x9075, 0x2001, 0x1833, 0x2004, 0x9005,
- 0x0150, 0x080c, 0xa007, 0x8eff, 0x0118, 0x2e60, 0x080c, 0xa007,
- 0x00ee, 0x0804, 0x78fc, 0x6024, 0xc0dc, 0xc0d5, 0x6026, 0x2e60,
- 0x6007, 0x003a, 0xa8a0, 0x9005, 0x0130, 0x6007, 0x003b, 0xa8a4,
- 0x602e, 0xa8a8, 0x6016, 0x6003, 0x0001, 0x080c, 0x85f9, 0x080c,
- 0x8b90, 0x00ee, 0x0804, 0x78fc, 0x2061, 0x1a4c, 0x6000, 0xd084,
- 0x0190, 0xd08c, 0x1904, 0x7a75, 0x0126, 0x2091, 0x8000, 0x6204,
- 0x8210, 0x0220, 0x6206, 0x012e, 0x0804, 0x7a75, 0x012e, 0xa883,
- 0x0016, 0x0804, 0x7a6e, 0xa883, 0x0007, 0x0804, 0x7a6e, 0xa864,
- 0x8007, 0x9084, 0x00ff, 0x0130, 0x8001, 0x1138, 0x7007, 0x0001,
- 0x0069, 0x0005, 0x080c, 0x75d9, 0x0040, 0x7007, 0x0003, 0x7012,
- 0x2900, 0x7016, 0x701a, 0x704b, 0x799e, 0x0005, 0x00b6, 0x00e6,
- 0x0126, 0x2091, 0x8000, 0x903e, 0x2061, 0x1800, 0x61cc, 0x81ff,
- 0x1904, 0x7a20, 0x6130, 0xd194, 0x1904, 0x7a4a, 0xa878, 0x2070,
- 0x9e82, 0x1cd0, 0x0a04, 0x7a14, 0x6064, 0x9e02, 0x1a04, 0x7a14,
- 0x7120, 0x9186, 0x0006, 0x1904, 0x7a06, 0x7010, 0x905d, 0x0904,
- 0x7a20, 0xb800, 0xd0e4, 0x1904, 0x7a44, 0x2061, 0x1a4c, 0x6100,
- 0x9184, 0x0301, 0x9086, 0x0001, 0x15a0, 0x7024, 0xd0dc, 0x1904,
- 0x7a4d, 0xa883, 0x0000, 0xa803, 0x0000, 0x2908, 0x7014, 0x9005,
- 0x1198, 0x7116, 0xa87c, 0xd0f4, 0x1904, 0x7a50, 0x080c, 0x54dc,
- 0xd09c, 0x1118, 0xa87c, 0xc0cc, 0xa87e, 0x2e60, 0x080c, 0x8371,
- 0x012e, 0x00ee, 0x00be, 0x0005, 0x2048, 0xa800, 0x9005, 0x1de0,
- 0xa902, 0x2148, 0xa87c, 0xd0f4, 0x1904, 0x7a50, 0x012e, 0x00ee,
- 0x00be, 0x0005, 0x012e, 0x00ee, 0xa883, 0x0006, 0x00be, 0x0804,
- 0x7a6e, 0xd184, 0x0db8, 0xd1c4, 0x1190, 0x00a0, 0xa974, 0x080c,
- 0x63a4, 0x15d0, 0xb800, 0xd0e4, 0x15b8, 0x7120, 0x9186, 0x0007,
- 0x1118, 0xa883, 0x0002, 0x0490, 0xa883, 0x0008, 0x0478, 0xa883,
- 0x000e, 0x0460, 0xa883, 0x0017, 0x0448, 0xa883, 0x0035, 0x0430,
- 0x080c, 0x54e0, 0xd0fc, 0x01e8, 0xa878, 0x2070, 0x9e82, 0x1cd0,
- 0x02c0, 0x6064, 0x9e02, 0x12a8, 0x7120, 0x9186, 0x0006, 0x1188,
- 0x7010, 0x905d, 0x0170, 0xb800, 0xd0bc, 0x0158, 0x2039, 0x0001,
- 0x7000, 0x9086, 0x0007, 0x1904, 0x79aa, 0x7003, 0x0002, 0x0804,
- 0x79aa, 0xa883, 0x0028, 0x0010, 0xa883, 0x0029, 0x012e, 0x00ee,
- 0x00be, 0x0420, 0xa883, 0x002a, 0x0cc8, 0xa883, 0x0045, 0x0cb0,
- 0x2e60, 0x2019, 0x0002, 0x601b, 0x0014, 0x080c, 0xd385, 0x012e,
- 0x00ee, 0x00be, 0x0005, 0x2009, 0x003e, 0x0058, 0x2009, 0x0004,
- 0x0040, 0x2009, 0x0006, 0x0028, 0x2009, 0x0016, 0x0010, 0x2009,
- 0x0001, 0xa884, 0x9084, 0xff00, 0x9105, 0xa886, 0x0126, 0x2091,
- 0x8000, 0x080c, 0x6a23, 0x012e, 0x0005, 0x080c, 0x1075, 0x0005,
- 0x00d6, 0x080c, 0x8368, 0x00de, 0x0005, 0x00d6, 0x00e6, 0x0126,
- 0x2091, 0x8000, 0x2071, 0x0040, 0x702c, 0xd084, 0x01d8, 0x908c,
- 0x0780, 0x190c, 0x7b09, 0xd09c, 0x11a8, 0x2071, 0x1800, 0x70bc,
- 0x90ea, 0x0040, 0x0278, 0x8001, 0x70be, 0x702c, 0x2048, 0xa800,
- 0x702e, 0x9006, 0xa802, 0xa806, 0x2071, 0x0040, 0x2900, 0x7022,
- 0x702c, 0x0c28, 0x012e, 0x00ee, 0x00de, 0x0005, 0x0006, 0x9084,
- 0x0780, 0x190c, 0x7b09, 0x000e, 0x0005, 0x00d6, 0x00c6, 0x0036,
- 0x0026, 0x0016, 0x00b6, 0x7007, 0x0001, 0xaa74, 0x9282, 0x0004,
- 0x1a04, 0x7afa, 0xa97c, 0x9188, 0x1000, 0x2104, 0x905d, 0xb804,
- 0xd284, 0x0140, 0x05e8, 0x8007, 0x9084, 0x00ff, 0x9084, 0x0006,
- 0x1108, 0x04b0, 0x2b10, 0x080c, 0x9f7f, 0x1118, 0x080c, 0xa026,
- 0x05a8, 0x6212, 0xa874, 0x0002, 0x7ad8, 0x7add, 0x7ae0, 0x7ae6,
- 0x2019, 0x0002, 0x080c, 0xd74e, 0x0060, 0x080c, 0xd6e5, 0x0048,
- 0x2019, 0x0002, 0xa980, 0x080c, 0xd700, 0x0018, 0xa980, 0x080c,
- 0xd6e5, 0x080c, 0x9fd5, 0xa887, 0x0000, 0x0126, 0x2091, 0x8000,
- 0x080c, 0x6a23, 0x012e, 0x00be, 0x001e, 0x002e, 0x003e, 0x00ce,
- 0x00de, 0x0005, 0xa887, 0x0006, 0x0c80, 0xa887, 0x0002, 0x0c68,
- 0xa887, 0x0005, 0x0c50, 0xa887, 0x0004, 0x0c38, 0xa887, 0x0007,
- 0x0c20, 0x2091, 0x8000, 0x0e04, 0x7b0b, 0x0006, 0x0016, 0x2001,
- 0x8003, 0x0006, 0x0804, 0x0e0b, 0x2001, 0x1833, 0x2004, 0x9005,
- 0x0005, 0x0005, 0x00f6, 0x2079, 0x0300, 0x2001, 0x0200, 0x200c,
- 0xc1e5, 0xc1dc, 0x2102, 0x2009, 0x0218, 0x210c, 0xd1ec, 0x1120,
- 0x080c, 0x151b, 0x00fe, 0x0005, 0x2001, 0x020d, 0x2003, 0x0020,
- 0x781f, 0x0300, 0x00fe, 0x0005, 0x781c, 0xd08c, 0x0904, 0x7b8b,
- 0x68bc, 0x90aa, 0x0005, 0x0a04, 0x8167, 0x7d44, 0x7c40, 0x9584,
- 0x00f6, 0x1510, 0x9484, 0x7000, 0x0140, 0x908a, 0x2000, 0x1260,
- 0x9584, 0x0700, 0x8007, 0x0804, 0x7b92, 0x7000, 0x9084, 0xff00,
- 0x9086, 0x8100, 0x0da8, 0x00b0, 0x9484, 0x0fff, 0x1130, 0x7000,
- 0x9084, 0xff00, 0x9086, 0x8100, 0x11c0, 0x080c, 0xdb52, 0x080c,
- 0x809c, 0x7817, 0x0140, 0x00a8, 0x9584, 0x0076, 0x1118, 0x080c,
- 0x80fa, 0x19c0, 0xd5a4, 0x0148, 0x0046, 0x0056, 0x080c, 0x7bed,
- 0x080c, 0x2169, 0x005e, 0x004e, 0x0020, 0x080c, 0xdb52, 0x7817,
- 0x0140, 0x080c, 0x717f, 0x0168, 0x2001, 0x0111, 0x2004, 0xd08c,
- 0x0140, 0x688f, 0x0000, 0x2001, 0x0110, 0x2003, 0x0008, 0x2003,
- 0x0000, 0x080c, 0x7bce, 0x2001, 0x19cb, 0x2004, 0x9005, 0x090c,
- 0x8b90, 0x0005, 0x0002, 0x7ba4, 0x7ea4, 0x7b9b, 0x7b9b, 0x7b9b,
- 0x7b9b, 0x7b9b, 0x7b9b, 0x7817, 0x0140, 0x2001, 0x19cb, 0x2004,
- 0x9005, 0x090c, 0x8b90, 0x0005, 0x7000, 0x908c, 0xff00, 0x9194,
- 0xf000, 0x810f, 0x9484, 0x0fff, 0x688e, 0x9286, 0x2000, 0x1150,
- 0x6800, 0x9086, 0x0001, 0x1118, 0x080c, 0x5546, 0x0070, 0x080c,
- 0x7c0d, 0x0058, 0x9286, 0x3000, 0x1118, 0x080c, 0x7ddc, 0x0028,
- 0x9286, 0x8000, 0x1110, 0x080c, 0x7fc3, 0x7817, 0x0140, 0x2001,
- 0x19cb, 0x2004, 0x9005, 0x090c, 0x8b90, 0x0005, 0x2001, 0x1810,
- 0x2004, 0xd08c, 0x0178, 0x2001, 0x1800, 0x2004, 0x9086, 0x0003,
- 0x1148, 0x0026, 0x0036, 0x2011, 0x8048, 0x2518, 0x080c, 0x4a18,
- 0x003e, 0x002e, 0x0005, 0x0036, 0x0046, 0x0056, 0x00f6, 0x2079,
- 0x0200, 0x2019, 0xfffe, 0x7c30, 0x0050, 0x0036, 0x0046, 0x0056,
- 0x00f6, 0x2079, 0x0200, 0x7d44, 0x7c40, 0x2019, 0xffff, 0x2001,
- 0x1810, 0x2004, 0xd08c, 0x0160, 0x2001, 0x1800, 0x2004, 0x9086,
- 0x0003, 0x1130, 0x0026, 0x2011, 0x8048, 0x080c, 0x4a18, 0x002e,
- 0x00fe, 0x005e, 0x004e, 0x003e, 0x0005, 0x00b6, 0x00c6, 0x7010,
- 0x9084, 0xff00, 0x8007, 0x9096, 0x0001, 0x0120, 0x9096, 0x0023,
- 0x1904, 0x7dad, 0x9186, 0x0023, 0x15c0, 0x080c, 0x8061, 0x0904,
- 0x7dad, 0x6120, 0x9186, 0x0001, 0x0150, 0x9186, 0x0004, 0x0138,
- 0x9186, 0x0008, 0x0120, 0x9186, 0x000a, 0x1904, 0x7dad, 0x7124,
- 0x610a, 0x7030, 0x908e, 0x0200, 0x1130, 0x2009, 0x0015, 0x080c,
- 0xa053, 0x0804, 0x7dad, 0x908e, 0x0214, 0x0118, 0x908e, 0x0210,
- 0x1130, 0x2009, 0x0015, 0x080c, 0xa053, 0x0804, 0x7dad, 0x908e,
- 0x0100, 0x1904, 0x7dad, 0x7034, 0x9005, 0x1904, 0x7dad, 0x2009,
- 0x0016, 0x080c, 0xa053, 0x0804, 0x7dad, 0x9186, 0x0022, 0x1904,
- 0x7dad, 0x7030, 0x908e, 0x0300, 0x1580, 0x68d8, 0xd0a4, 0x0528,
- 0xc0b5, 0x68da, 0x7100, 0x918c, 0x00ff, 0x697a, 0x7004, 0x687e,
- 0x00f6, 0x2079, 0x0100, 0x79e6, 0x78ea, 0x0006, 0x9084, 0x00ff,
- 0x0016, 0x2008, 0x080c, 0x26b7, 0x7932, 0x7936, 0x001e, 0x000e,
- 0x00fe, 0x080c, 0x266e, 0x695a, 0x703c, 0x00e6, 0x2071, 0x0140,
- 0x7086, 0x2071, 0x1800, 0x70b2, 0x00ee, 0x7034, 0x9005, 0x1904,
- 0x7dad, 0x2009, 0x0017, 0x0804, 0x7d5d, 0x908e, 0x0400, 0x1190,
- 0x7034, 0x9005, 0x1904, 0x7dad, 0x080c, 0x717f, 0x0120, 0x2009,
- 0x001d, 0x0804, 0x7d5d, 0x68d8, 0xc0a5, 0x68da, 0x2009, 0x0030,
- 0x0804, 0x7d5d, 0x908e, 0x0500, 0x1140, 0x7034, 0x9005, 0x1904,
- 0x7dad, 0x2009, 0x0018, 0x0804, 0x7d5d, 0x908e, 0x2010, 0x1120,
- 0x2009, 0x0019, 0x0804, 0x7d5d, 0x908e, 0x2110, 0x1120, 0x2009,
- 0x001a, 0x0804, 0x7d5d, 0x908e, 0x5200, 0x1140, 0x7034, 0x9005,
- 0x1904, 0x7dad, 0x2009, 0x001b, 0x0804, 0x7d5d, 0x908e, 0x5000,
- 0x1140, 0x7034, 0x9005, 0x1904, 0x7dad, 0x2009, 0x001c, 0x0804,
- 0x7d5d, 0x908e, 0x1300, 0x1120, 0x2009, 0x0034, 0x0804, 0x7d5d,
- 0x908e, 0x1200, 0x1140, 0x7034, 0x9005, 0x1904, 0x7dad, 0x2009,
- 0x0024, 0x0804, 0x7d5d, 0x908c, 0xff00, 0x918e, 0x2400, 0x1170,
- 0x2009, 0x002d, 0x2001, 0x1810, 0x2004, 0xd09c, 0x0904, 0x7d5d,
- 0x080c, 0xcb4c, 0x1904, 0x7dad, 0x0804, 0x7d5b, 0x908c, 0xff00,
- 0x918e, 0x5300, 0x1120, 0x2009, 0x002a, 0x0804, 0x7d5d, 0x908e,
- 0x0f00, 0x1120, 0x2009, 0x0020, 0x0804, 0x7d5d, 0x908e, 0x6104,
- 0x1528, 0x2029, 0x0205, 0x2011, 0x026d, 0x8208, 0x2204, 0x9082,
- 0x0004, 0x8004, 0x8004, 0x20a8, 0x2011, 0x8015, 0x211c, 0x8108,
- 0x0046, 0x2124, 0x080c, 0x4a18, 0x004e, 0x8108, 0x0f04, 0x7d29,
- 0x9186, 0x0280, 0x1d88, 0x2504, 0x8000, 0x202a, 0x2009, 0x0260,
- 0x0c58, 0x202b, 0x0000, 0x2009, 0x0023, 0x0478, 0x908e, 0x6000,
- 0x1118, 0x2009, 0x003f, 0x0448, 0x908e, 0x7800, 0x1118, 0x2009,
- 0x0045, 0x0418, 0x908e, 0x1000, 0x1118, 0x2009, 0x004e, 0x00e8,
- 0x908e, 0x6300, 0x1118, 0x2009, 0x004a, 0x00b8, 0x908c, 0xff00,
- 0x918e, 0x5600, 0x1118, 0x2009, 0x004f, 0x0078, 0x908c, 0xff00,
- 0x918e, 0x5700, 0x1118, 0x2009, 0x0050, 0x0038, 0x2009, 0x001d,
- 0x6838, 0xd0d4, 0x0110, 0x2009, 0x004c, 0x0016, 0x2011, 0x0263,
- 0x2204, 0x8211, 0x220c, 0x080c, 0x266e, 0x1904, 0x7db0, 0x080c,
- 0x6344, 0x1904, 0x7db0, 0xbe12, 0xbd16, 0x001e, 0x0016, 0x080c,
- 0x717f, 0x01c0, 0x68d8, 0xd08c, 0x1148, 0x7000, 0x9084, 0x00ff,
- 0x1188, 0x7004, 0x9084, 0xff00, 0x1168, 0x0040, 0x6878, 0x9606,
- 0x1148, 0x687c, 0x9506, 0x9084, 0xff00, 0x1120, 0x9584, 0x00ff,
- 0xb8b2, 0x0080, 0xb8b0, 0x9005, 0x1168, 0x9186, 0x0046, 0x1150,
- 0x6878, 0x9606, 0x1138, 0x687c, 0x9506, 0x9084, 0xff00, 0x1110,
- 0x001e, 0x0098, 0x080c, 0x9f7f, 0x01a8, 0x2b08, 0x6112, 0x6023,
- 0x0004, 0x7120, 0x610a, 0x001e, 0x9186, 0x004c, 0x1110, 0x6023,
- 0x000a, 0x0016, 0x001e, 0x080c, 0xa053, 0x00ce, 0x00be, 0x0005,
- 0x001e, 0x0cd8, 0x2001, 0x180e, 0x2004, 0xd0ec, 0x0120, 0x2011,
- 0x8049, 0x080c, 0x4a18, 0x080c, 0xa026, 0x0d90, 0x2b08, 0x6112,
- 0x6023, 0x0004, 0x7120, 0x610a, 0x001e, 0x0016, 0x9186, 0x0017,
- 0x0118, 0x9186, 0x0030, 0x1128, 0x6007, 0x0009, 0x6017, 0x2900,
- 0x0020, 0x6007, 0x0051, 0x6017, 0x0000, 0x602f, 0x0009, 0x6003,
- 0x0001, 0x080c, 0x8641, 0x08a0, 0x080c, 0x8186, 0x1158, 0x080c,
- 0x31ce, 0x1140, 0x7010, 0x9084, 0xff00, 0x8007, 0x908e, 0x0008,
- 0x1108, 0x0009, 0x0005, 0x00b6, 0x00c6, 0x0046, 0x7000, 0x908c,
- 0xff00, 0x810f, 0x9186, 0x0033, 0x11e8, 0x080c, 0x8061, 0x0904,
- 0x7e3c, 0x7124, 0x610a, 0x7030, 0x908e, 0x0200, 0x1140, 0x7034,
- 0x9005, 0x15d0, 0x2009, 0x0015, 0x080c, 0xa053, 0x04a8, 0x908e,
- 0x0100, 0x1590, 0x7034, 0x9005, 0x1578, 0x2009, 0x0016, 0x080c,
- 0xa053, 0x0450, 0x9186, 0x0032, 0x1538, 0x7030, 0x908e, 0x1400,
- 0x1518, 0x2009, 0x0038, 0x0016, 0x2011, 0x0263, 0x2204, 0x8211,
- 0x220c, 0x080c, 0x266e, 0x11b8, 0x080c, 0x6344, 0x11a0, 0xbe12,
- 0xbd16, 0x080c, 0x9f7f, 0x0178, 0x2b08, 0x6112, 0x080c, 0xc1b7,
- 0x6023, 0x0004, 0x7120, 0x610a, 0x001e, 0x080c, 0xa053, 0x080c,
- 0x8b90, 0x0010, 0x00ce, 0x001e, 0x004e, 0x00ce, 0x00be, 0x0005,
- 0x00b6, 0x0046, 0x00e6, 0x00d6, 0x2028, 0x2130, 0x9696, 0x00ff,
- 0x11b8, 0x9592, 0xfffc, 0x02a0, 0x9596, 0xfffd, 0x1120, 0x2009,
- 0x007f, 0x0804, 0x7e9e, 0x9596, 0xfffe, 0x1120, 0x2009, 0x007e,
- 0x0804, 0x7e9e, 0x9596, 0xfffc, 0x1118, 0x2009, 0x0080, 0x04f0,
- 0x2011, 0x0000, 0x2019, 0x1836, 0x231c, 0xd3ac, 0x0130, 0x9026,
- 0x20a9, 0x0800, 0x2071, 0x1000, 0x0030, 0x2021, 0x0081, 0x20a9,
- 0x077f, 0x2071, 0x1081, 0x2e1c, 0x93dd, 0x0000, 0x1140, 0x82ff,
- 0x11d0, 0x9496, 0x00ff, 0x01b8, 0x2410, 0xc2fd, 0x00a0, 0xbf10,
- 0x2600, 0x9706, 0xb814, 0x1120, 0x9546, 0x1110, 0x2408, 0x00b0,
- 0x9745, 0x1148, 0x94c6, 0x007e, 0x0130, 0x94c6, 0x007f, 0x0118,
- 0x94c6, 0x0080, 0x1d20, 0x8420, 0x8e70, 0x1f04, 0x7e73, 0x82ff,
- 0x1118, 0x9085, 0x0001, 0x0018, 0xc2fc, 0x2208, 0x9006, 0x00de,
- 0x00ee, 0x004e, 0x00be, 0x0005, 0x2001, 0x1836, 0x200c, 0x9184,
- 0x0080, 0x0110, 0xd18c, 0x0138, 0x7000, 0x908c, 0xff00, 0x810f,
- 0x9184, 0x000f, 0x004a, 0x7817, 0x0140, 0x2001, 0x19cb, 0x2004,
- 0x9005, 0x090c, 0x8b90, 0x0005, 0x7ecc, 0x7ecc, 0x7ecc, 0x8073,
- 0x7ecc, 0x7ed5, 0x7f00, 0x7f8e, 0x7ecc, 0x7ecc, 0x7ecc, 0x7ecc,
- 0x7ecc, 0x7ecc, 0x7ecc, 0x7ecc, 0x7817, 0x0140, 0x2001, 0x19cb,
- 0x2004, 0x9005, 0x090c, 0x8b90, 0x0005, 0x00b6, 0x7110, 0xd1bc,
- 0x01e8, 0x7120, 0x2160, 0x9c8c, 0x0007, 0x11c0, 0x9c8a, 0x1cd0,
+ 0xd084, 0x190c, 0x11e6, 0x00fe, 0x0005, 0x782c, 0x9094, 0x0780,
+ 0x190c, 0x6d6a, 0xd0a4, 0x0db8, 0x00e6, 0x2071, 0x1800, 0x7824,
+ 0x2048, 0x702c, 0xa802, 0x2900, 0x702e, 0x70bc, 0x8000, 0x70be,
+ 0x080c, 0x816f, 0x782c, 0x9094, 0x0780, 0x190c, 0x6d6a, 0xd0a4,
+ 0x1d70, 0x00d6, 0x2069, 0x0050, 0x693c, 0x2069, 0x1923, 0x6808,
+ 0x690a, 0x2069, 0x19d5, 0x9102, 0x1118, 0x6844, 0x9005, 0x1320,
+ 0x2001, 0x1924, 0x200c, 0x6946, 0x00de, 0x00ee, 0x00fe, 0x0005,
+ 0x7094, 0x908a, 0x002a, 0x1a0c, 0x0df6, 0x9082, 0x001d, 0x001b,
+ 0x6027, 0x1e00, 0x0005, 0x6f21, 0x6e8e, 0x6eaa, 0x6ed4, 0x6f10,
+ 0x6f50, 0x6f62, 0x6eaa, 0x6f38, 0x6e49, 0x6e77, 0x6efa, 0x6e48,
+ 0x0005, 0x00d6, 0x2069, 0x0200, 0x6804, 0x9005, 0x1180, 0x6808,
+ 0x9005, 0x1518, 0x7097, 0x0029, 0x2069, 0x1969, 0x2d04, 0x7002,
+ 0x080c, 0x72cd, 0x6028, 0x9085, 0x0600, 0x602a, 0x00b0, 0x7097,
+ 0x0029, 0x2069, 0x1969, 0x2d04, 0x7002, 0x6028, 0x9085, 0x0600,
+ 0x602a, 0x00e6, 0x0036, 0x0046, 0x0056, 0x2071, 0x1a3f, 0x080c,
+ 0x1977, 0x005e, 0x004e, 0x003e, 0x00ee, 0x00de, 0x0005, 0x00d6,
+ 0x2069, 0x0200, 0x6804, 0x9005, 0x1178, 0x6808, 0x9005, 0x1160,
+ 0x7097, 0x0029, 0x2069, 0x1969, 0x2d04, 0x7002, 0x080c, 0x7369,
+ 0x6028, 0x9085, 0x0600, 0x602a, 0x00de, 0x0005, 0x0006, 0x2001,
+ 0x0090, 0x080c, 0x2b6f, 0x000e, 0x6124, 0xd1e4, 0x1190, 0x080c,
+ 0x6fcf, 0xd1d4, 0x1160, 0xd1dc, 0x1138, 0xd1cc, 0x0150, 0x7097,
+ 0x0020, 0x080c, 0x6fcf, 0x0028, 0x7097, 0x001d, 0x0010, 0x7097,
+ 0x001f, 0x0005, 0x2001, 0x0088, 0x080c, 0x2b6f, 0x6124, 0xd1cc,
+ 0x11e8, 0xd1dc, 0x11c0, 0xd1e4, 0x1198, 0x9184, 0x1e00, 0x11d8,
+ 0x080c, 0x19a4, 0x60e3, 0x0001, 0x600c, 0xc0b4, 0x600e, 0x080c,
+ 0x71aa, 0x2001, 0x0080, 0x080c, 0x2b6f, 0x7097, 0x0029, 0x0058,
+ 0x7097, 0x001e, 0x0040, 0x7097, 0x001d, 0x0028, 0x7097, 0x0020,
+ 0x0010, 0x7097, 0x001f, 0x0005, 0x080c, 0x19a4, 0x60e3, 0x0001,
+ 0x600c, 0xc0b4, 0x600e, 0x080c, 0x71aa, 0x2001, 0x0080, 0x080c,
+ 0x2b6f, 0x6124, 0xd1d4, 0x1198, 0xd1dc, 0x1170, 0xd1e4, 0x1148,
+ 0x9184, 0x1e00, 0x1118, 0x7097, 0x0029, 0x0058, 0x7097, 0x0028,
+ 0x0040, 0x7097, 0x001e, 0x0028, 0x7097, 0x001d, 0x0010, 0x7097,
+ 0x001f, 0x0005, 0x6124, 0xd1d4, 0x1180, 0xd1dc, 0x1158, 0xd1e4,
+ 0x1130, 0x9184, 0x1e00, 0x1158, 0x7097, 0x0029, 0x0040, 0x7097,
+ 0x001e, 0x0028, 0x7097, 0x001d, 0x0010, 0x7097, 0x001f, 0x0005,
+ 0x2001, 0x00a0, 0x080c, 0x2b6f, 0x6124, 0xd1dc, 0x1138, 0xd1e4,
+ 0x0138, 0x080c, 0x19a4, 0x7097, 0x001e, 0x0010, 0x7097, 0x001d,
+ 0x0005, 0x080c, 0x7052, 0x6124, 0xd1dc, 0x1188, 0x080c, 0x6fcf,
+ 0x0016, 0x080c, 0x19a4, 0x001e, 0xd1d4, 0x1128, 0xd1e4, 0x0138,
+ 0x7097, 0x001e, 0x0020, 0x7097, 0x001f, 0x080c, 0x6fcf, 0x0005,
+ 0x0006, 0x2001, 0x00a0, 0x080c, 0x2b6f, 0x000e, 0x6124, 0xd1d4,
+ 0x1160, 0xd1cc, 0x1150, 0xd1dc, 0x1128, 0xd1e4, 0x0140, 0x7097,
+ 0x001e, 0x0028, 0x7097, 0x001d, 0x0010, 0x7097, 0x0021, 0x0005,
+ 0x080c, 0x7052, 0x6124, 0xd1d4, 0x1150, 0xd1dc, 0x1128, 0xd1e4,
+ 0x0140, 0x7097, 0x001e, 0x0028, 0x7097, 0x001d, 0x0010, 0x7097,
+ 0x001f, 0x0005, 0x0006, 0x2001, 0x0090, 0x080c, 0x2b6f, 0x000e,
+ 0x6124, 0xd1d4, 0x1178, 0xd1cc, 0x1150, 0xd1dc, 0x1128, 0xd1e4,
+ 0x0158, 0x7097, 0x001e, 0x0040, 0x7097, 0x001d, 0x0028, 0x7097,
+ 0x0020, 0x0010, 0x7097, 0x001f, 0x0005, 0x0016, 0x00c6, 0x00d6,
+ 0x00e6, 0x0126, 0x2061, 0x0100, 0x2069, 0x0140, 0x2071, 0x1800,
+ 0x2091, 0x8000, 0x080c, 0x717e, 0x11d8, 0x2001, 0x180c, 0x200c,
+ 0xd1b4, 0x01b0, 0xc1b4, 0x2102, 0x6027, 0x0200, 0x080c, 0x2a97,
+ 0x6024, 0xd0cc, 0x0148, 0x2001, 0x00a0, 0x080c, 0x2b6f, 0x080c,
+ 0x747a, 0x080c, 0x5e2f, 0x0428, 0x6028, 0xc0cd, 0x602a, 0x0408,
+ 0x080c, 0x7198, 0x0150, 0x080c, 0x718f, 0x1138, 0x2001, 0x0001,
+ 0x080c, 0x2616, 0x080c, 0x7156, 0x00a0, 0x080c, 0x704f, 0x0178,
+ 0x2001, 0x0001, 0x080c, 0x2616, 0x7094, 0x9086, 0x001e, 0x0120,
+ 0x7094, 0x9086, 0x0022, 0x1118, 0x7097, 0x0025, 0x0010, 0x7097,
+ 0x0021, 0x012e, 0x00ee, 0x00de, 0x00ce, 0x001e, 0x0005, 0x0026,
+ 0x2011, 0x6fe0, 0x080c, 0x832d, 0x002e, 0x0016, 0x0026, 0x2009,
+ 0x0064, 0x2011, 0x6fe0, 0x080c, 0x8324, 0x002e, 0x001e, 0x0005,
+ 0x00e6, 0x00f6, 0x0016, 0x080c, 0x961a, 0x2071, 0x1800, 0x080c,
+ 0x6f7d, 0x001e, 0x00fe, 0x00ee, 0x0005, 0x0016, 0x0026, 0x0036,
+ 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x0126, 0x2071, 0x1800, 0x080c,
+ 0x961a, 0x2061, 0x0100, 0x2069, 0x0140, 0x2091, 0x8000, 0x6028,
+ 0xc09c, 0x602a, 0x2011, 0x0003, 0x080c, 0x9923, 0x2011, 0x0002,
+ 0x080c, 0x992d, 0x080c, 0x983b, 0x080c, 0x82d9, 0x0036, 0x901e,
+ 0x080c, 0x98b1, 0x003e, 0x60e3, 0x0000, 0x080c, 0xdbdb, 0x080c,
+ 0xdbf6, 0x2009, 0x0004, 0x080c, 0x2a9d, 0x080c, 0x2974, 0x2001,
+ 0x1800, 0x2003, 0x0004, 0x6027, 0x0008, 0x2011, 0x6fe0, 0x080c,
+ 0x832d, 0x080c, 0x7198, 0x0118, 0x9006, 0x080c, 0x2b6f, 0x080c,
+ 0x0b8f, 0x2001, 0x0001, 0x080c, 0x2616, 0x012e, 0x00fe, 0x00ee,
+ 0x00de, 0x00ce, 0x003e, 0x002e, 0x001e, 0x0005, 0x0026, 0x00e6,
+ 0x2011, 0x6fed, 0x2071, 0x19d5, 0x701c, 0x9206, 0x1118, 0x7018,
+ 0x9005, 0x0110, 0x9085, 0x0001, 0x00ee, 0x002e, 0x0005, 0x6020,
+ 0xd09c, 0x0005, 0x6800, 0x9084, 0xfffe, 0x9086, 0x00c0, 0x01b8,
+ 0x2001, 0x00c0, 0x080c, 0x2b6f, 0x0156, 0x20a9, 0x002d, 0x1d04,
+ 0x705f, 0x2091, 0x6000, 0x1f04, 0x705f, 0x015e, 0x00d6, 0x2069,
+ 0x1800, 0x6898, 0x8001, 0x0220, 0x0118, 0x689a, 0x00de, 0x0005,
+ 0x689b, 0x0014, 0x68e4, 0xd0dc, 0x0dc8, 0x6800, 0x9086, 0x0001,
+ 0x1da8, 0x080c, 0x8339, 0x0c90, 0x00c6, 0x00d6, 0x00e6, 0x2061,
+ 0x0100, 0x2069, 0x0140, 0x2071, 0x1800, 0x080c, 0x7489, 0x2001,
+ 0x1947, 0x2003, 0x0000, 0x9006, 0x7096, 0x60e2, 0x6886, 0x080c,
+ 0x26e1, 0x9006, 0x080c, 0x2b6f, 0x080c, 0x5cee, 0x6027, 0xffff,
+ 0x602b, 0x182f, 0x00ee, 0x00de, 0x00ce, 0x0005, 0x00c6, 0x00d6,
+ 0x00e6, 0x2061, 0x0100, 0x2069, 0x0140, 0x2071, 0x1800, 0x2001,
+ 0x1957, 0x200c, 0x9186, 0x0000, 0x0158, 0x9186, 0x0001, 0x0158,
+ 0x9186, 0x0002, 0x0158, 0x9186, 0x0003, 0x0158, 0x0804, 0x7146,
+ 0x7097, 0x0022, 0x0040, 0x7097, 0x0021, 0x0028, 0x7097, 0x0023,
+ 0x0010, 0x7097, 0x0024, 0x60e3, 0x0000, 0x6887, 0x0001, 0x2001,
+ 0x0001, 0x080c, 0x26e1, 0x0026, 0x080c, 0x9f70, 0x002e, 0x7000,
+ 0x908e, 0x0004, 0x0118, 0x602b, 0x0028, 0x0010, 0x602b, 0x0020,
+ 0x0156, 0x0126, 0x2091, 0x8000, 0x20a9, 0x0005, 0x6024, 0xd0ac,
+ 0x0150, 0x012e, 0x015e, 0x080c, 0xc459, 0x0118, 0x9006, 0x080c,
+ 0x2b99, 0x0804, 0x7152, 0x6800, 0x9084, 0x00a1, 0xc0bd, 0x6802,
+ 0x080c, 0x2a97, 0x6904, 0xd1d4, 0x1140, 0x2001, 0x0100, 0x080c,
+ 0x2b6f, 0x1f04, 0x70de, 0x080c, 0x71d2, 0x012e, 0x015e, 0x080c,
+ 0x718f, 0x0538, 0x6044, 0x9005, 0x01f8, 0x2001, 0x0100, 0x2004,
+ 0x9086, 0x000a, 0x0158, 0x2011, 0x0114, 0x2204, 0x9085, 0x0100,
+ 0x2012, 0x6050, 0x0006, 0x9085, 0x0020, 0x6052, 0x080c, 0x71d2,
+ 0x9006, 0x8001, 0x1df0, 0x2001, 0x0100, 0x2004, 0x9086, 0x000a,
+ 0x0140, 0x000e, 0x6052, 0x0028, 0x6804, 0xd0d4, 0x1110, 0x080c,
+ 0x71d2, 0x080c, 0xc459, 0x0118, 0x9006, 0x080c, 0x2b99, 0x0016,
+ 0x0026, 0x7000, 0x908e, 0x0004, 0x0130, 0x2009, 0x00c8, 0x2011,
+ 0x6fed, 0x080c, 0x82eb, 0x002e, 0x001e, 0x080c, 0x8166, 0x7034,
+ 0xc085, 0x7036, 0x2001, 0x1957, 0x2003, 0x0004, 0x080c, 0x6e30,
+ 0x080c, 0x718f, 0x0138, 0x6804, 0xd0d4, 0x1120, 0xd0dc, 0x1100,
+ 0x080c, 0x747f, 0x00ee, 0x00de, 0x00ce, 0x0005, 0x00c6, 0x00d6,
+ 0x00e6, 0x2061, 0x0100, 0x2069, 0x0140, 0x2071, 0x1800, 0x080c,
+ 0x817d, 0x080c, 0x816f, 0x080c, 0x7489, 0x2001, 0x1947, 0x2003,
+ 0x0000, 0x9006, 0x7096, 0x60e2, 0x6886, 0x080c, 0x26e1, 0x9006,
+ 0x080c, 0x2b6f, 0x6043, 0x0090, 0x6043, 0x0010, 0x6027, 0xffff,
+ 0x602b, 0x182f, 0x00ee, 0x00de, 0x00ce, 0x0005, 0x0006, 0x2001,
+ 0x1956, 0x2004, 0x9086, 0xaaaa, 0x000e, 0x0005, 0x0006, 0x080c,
+ 0x54df, 0x9084, 0x0030, 0x9086, 0x0000, 0x000e, 0x0005, 0x0006,
+ 0x080c, 0x54df, 0x9084, 0x0030, 0x9086, 0x0030, 0x000e, 0x0005,
+ 0x0006, 0x080c, 0x54df, 0x9084, 0x0030, 0x9086, 0x0010, 0x000e,
+ 0x0005, 0x0006, 0x080c, 0x54df, 0x9084, 0x0030, 0x9086, 0x0020,
+ 0x000e, 0x0005, 0x0036, 0x0016, 0x2001, 0x180c, 0x2004, 0x908c,
+ 0x0013, 0x0168, 0x0020, 0x080c, 0x2701, 0x900e, 0x0010, 0x2009,
+ 0x0002, 0x2019, 0x0028, 0x080c, 0x3060, 0x9006, 0x0019, 0x001e,
+ 0x003e, 0x0005, 0x00e6, 0x2071, 0x180c, 0x2e04, 0x0130, 0x080c,
+ 0xc452, 0x1128, 0x9085, 0x0010, 0x0010, 0x9084, 0xffef, 0x2072,
+ 0x00ee, 0x0005, 0x6050, 0x0006, 0x60ec, 0x0006, 0x600c, 0x0006,
+ 0x6004, 0x0006, 0x6028, 0x0006, 0x2001, 0x0100, 0x2004, 0x9086,
+ 0x000a, 0x0510, 0x0016, 0x6138, 0x6050, 0x9084, 0xfbff, 0x9085,
+ 0x2000, 0x6052, 0x613a, 0x20a9, 0x0012, 0x1d04, 0x71ed, 0x2091,
+ 0x6000, 0x1f04, 0x71ed, 0x602f, 0x0100, 0x602f, 0x0000, 0x6050,
+ 0x9085, 0x0400, 0x9084, 0xdfff, 0x6052, 0x613a, 0x001e, 0x602f,
+ 0x0040, 0x602f, 0x0000, 0x00a0, 0x080c, 0x2ba9, 0x080c, 0x2bdc,
+ 0x602f, 0x0100, 0x602f, 0x0000, 0x602f, 0x0040, 0x602f, 0x0000,
+ 0x20a9, 0x0002, 0x080c, 0x2a78, 0x0026, 0x6027, 0x0040, 0x002e,
+ 0x000e, 0x602a, 0x000e, 0x6006, 0x000e, 0x600e, 0x000e, 0x60ee,
+ 0x60e3, 0x0000, 0x6887, 0x0001, 0x2001, 0x0001, 0x080c, 0x26e1,
+ 0x2001, 0x00a0, 0x0006, 0x080c, 0xc459, 0x000e, 0x0130, 0x080c,
+ 0x2b8d, 0x9006, 0x080c, 0x2b99, 0x0010, 0x080c, 0x2b6f, 0x000e,
+ 0x6052, 0x6050, 0x0006, 0xc0e5, 0x6052, 0x00f6, 0x2079, 0x0100,
+ 0x080c, 0x29f1, 0x00fe, 0x000e, 0x6052, 0x0005, 0x0156, 0x0016,
+ 0x0026, 0x0036, 0x00c6, 0x00d6, 0x00e6, 0x2061, 0x0100, 0x2069,
+ 0x0140, 0x2071, 0x1800, 0x6020, 0x9084, 0x0080, 0x0138, 0x2001,
+ 0x180c, 0x200c, 0xc1c5, 0x2102, 0x0804, 0x72bf, 0x2001, 0x180c,
+ 0x200c, 0xc1c4, 0x2102, 0x6028, 0x9084, 0xe1ff, 0x602a, 0x6027,
+ 0x0200, 0x2001, 0x0090, 0x080c, 0x2b6f, 0x20a9, 0x0366, 0x6024,
+ 0xd0cc, 0x1518, 0x1d04, 0x726f, 0x2091, 0x6000, 0x1f04, 0x726f,
+ 0x2011, 0x0003, 0x080c, 0x9923, 0x2011, 0x0002, 0x080c, 0x992d,
+ 0x080c, 0x983b, 0x901e, 0x080c, 0x98b1, 0x2001, 0x00a0, 0x080c,
+ 0x2b6f, 0x080c, 0x747a, 0x080c, 0x5e2f, 0x080c, 0xc459, 0x0110,
+ 0x080c, 0x0d64, 0x9085, 0x0001, 0x0480, 0x080c, 0x19a4, 0x60e3,
+ 0x0000, 0x2001, 0x0002, 0x080c, 0x26e1, 0x60e2, 0x2001, 0x0080,
+ 0x080c, 0x2b6f, 0x20a9, 0x0366, 0x6027, 0x1e00, 0x2009, 0x1e00,
+ 0x080c, 0x2a97, 0x6024, 0x910c, 0x0138, 0x1d04, 0x72a4, 0x2091,
+ 0x6000, 0x1f04, 0x72a4, 0x0820, 0x6028, 0x9085, 0x1e00, 0x602a,
+ 0x70b0, 0x9005, 0x1118, 0x6887, 0x0001, 0x0008, 0x6886, 0x080c,
+ 0xc459, 0x0110, 0x080c, 0x0d64, 0x9006, 0x00ee, 0x00de, 0x00ce,
+ 0x003e, 0x002e, 0x001e, 0x015e, 0x0005, 0x0156, 0x0016, 0x0026,
+ 0x0036, 0x00c6, 0x00d6, 0x00e6, 0x2061, 0x0100, 0x2071, 0x1800,
+ 0x7000, 0x9086, 0x0003, 0x1168, 0x2001, 0x020b, 0x2004, 0x9084,
+ 0x5540, 0x9086, 0x5540, 0x1128, 0x2069, 0x1a54, 0x2d04, 0x8000,
+ 0x206a, 0x2069, 0x0140, 0x6020, 0x9084, 0x00c0, 0x0120, 0x6884,
+ 0x9005, 0x1904, 0x7332, 0x2001, 0x0088, 0x080c, 0x2b6f, 0x9006,
+ 0x60e2, 0x6886, 0x080c, 0x26e1, 0x2069, 0x0200, 0x6804, 0x9005,
+ 0x1118, 0x6808, 0x9005, 0x01c0, 0x6028, 0x9084, 0xfbff, 0x602a,
+ 0x6027, 0x0400, 0x2069, 0x1969, 0x7000, 0x206a, 0x7097, 0x0026,
+ 0x7003, 0x0001, 0x20a9, 0x0002, 0x1d04, 0x7314, 0x2091, 0x6000,
+ 0x1f04, 0x7314, 0x0804, 0x7361, 0x2069, 0x0140, 0x20a9, 0x0384,
+ 0x6027, 0x1e00, 0x2009, 0x1e00, 0x080c, 0x2a97, 0x6024, 0x910c,
+ 0x0508, 0x9084, 0x1a00, 0x11f0, 0x1d04, 0x7320, 0x2091, 0x6000,
+ 0x1f04, 0x7320, 0x2011, 0x0003, 0x080c, 0x9923, 0x2011, 0x0002,
+ 0x080c, 0x992d, 0x080c, 0x983b, 0x901e, 0x080c, 0x98b1, 0x2001,
+ 0x00a0, 0x080c, 0x2b6f, 0x080c, 0x747a, 0x080c, 0x5e2f, 0x9085,
+ 0x0001, 0x00b8, 0x080c, 0x19a4, 0x2001, 0x0080, 0x080c, 0x2b6f,
+ 0x2069, 0x0140, 0x60e3, 0x0000, 0x70b0, 0x9005, 0x1118, 0x6887,
+ 0x0001, 0x0008, 0x6886, 0x2001, 0x0002, 0x080c, 0x26e1, 0x60e2,
+ 0x9006, 0x00ee, 0x00de, 0x00ce, 0x003e, 0x002e, 0x001e, 0x015e,
+ 0x0005, 0x0156, 0x0016, 0x0026, 0x0036, 0x00c6, 0x00d6, 0x00e6,
+ 0x2061, 0x0100, 0x2071, 0x1800, 0x6020, 0x9084, 0x00c0, 0x01c8,
+ 0x2011, 0x0003, 0x080c, 0x9923, 0x2011, 0x0002, 0x080c, 0x992d,
+ 0x080c, 0x983b, 0x901e, 0x080c, 0x98b1, 0x2069, 0x0140, 0x2001,
+ 0x00a0, 0x080c, 0x2b6f, 0x080c, 0x747a, 0x080c, 0x5e2f, 0x0804,
+ 0x73fb, 0x2001, 0x180c, 0x200c, 0xd1b4, 0x1160, 0xc1b5, 0x2102,
+ 0x080c, 0x6fd5, 0x2069, 0x0140, 0x2001, 0x0080, 0x080c, 0x2b6f,
+ 0x60e3, 0x0000, 0x2069, 0x0200, 0x6804, 0x9005, 0x1118, 0x6808,
+ 0x9005, 0x0180, 0x6028, 0x9084, 0xfdff, 0x602a, 0x6027, 0x0200,
+ 0x2069, 0x1969, 0x7000, 0x206a, 0x7097, 0x0027, 0x7003, 0x0001,
+ 0x0804, 0x73fb, 0x6027, 0x1e00, 0x2009, 0x1e00, 0x080c, 0x2a97,
+ 0x6024, 0x910c, 0x01c8, 0x9084, 0x1c00, 0x11b0, 0x1d04, 0x73ba,
+ 0x0006, 0x0016, 0x00c6, 0x00d6, 0x00e6, 0x080c, 0x81bd, 0x00ee,
+ 0x00de, 0x00ce, 0x001e, 0x000e, 0x00e6, 0x2071, 0x19d5, 0x7078,
+ 0x00ee, 0x9005, 0x19f8, 0x00f8, 0x0026, 0x2011, 0x6fed, 0x080c,
+ 0x8259, 0x2011, 0x6fe0, 0x080c, 0x832d, 0x002e, 0x2069, 0x0140,
+ 0x60e3, 0x0000, 0x70b0, 0x9005, 0x1118, 0x6887, 0x0001, 0x0008,
+ 0x6886, 0x2001, 0x0002, 0x080c, 0x26e1, 0x60e2, 0x2001, 0x180c,
+ 0x200c, 0xc1b4, 0x2102, 0x00ee, 0x00de, 0x00ce, 0x003e, 0x002e,
+ 0x001e, 0x015e, 0x0005, 0x0156, 0x0016, 0x0026, 0x0036, 0x0046,
+ 0x00c6, 0x00e6, 0x2061, 0x0100, 0x2071, 0x1800, 0x080c, 0xc452,
+ 0x1904, 0x7468, 0x7130, 0xd184, 0x1170, 0x080c, 0x31ee, 0x0138,
+ 0xc18d, 0x7132, 0x2011, 0x185c, 0x2214, 0xd2ac, 0x1120, 0x7030,
+ 0xd08c, 0x0904, 0x7468, 0x2011, 0x185c, 0x220c, 0x0438, 0x0016,
+ 0x2019, 0x000e, 0x080c, 0xd7af, 0x0156, 0x00b6, 0x20a9, 0x007f,
+ 0x900e, 0x9186, 0x007e, 0x01a0, 0x9186, 0x0080, 0x0188, 0x080c,
+ 0x63a3, 0x1170, 0x2120, 0x9006, 0x0016, 0x2009, 0x000e, 0x080c,
+ 0xd837, 0x2009, 0x0001, 0x2011, 0x0100, 0x080c, 0x8450, 0x001e,
+ 0x8108, 0x1f04, 0x7431, 0x00be, 0x015e, 0x001e, 0xd1ac, 0x1148,
+ 0x0016, 0x2009, 0x0002, 0x2019, 0x0004, 0x080c, 0x3060, 0x001e,
+ 0x0078, 0x0156, 0x00b6, 0x20a9, 0x007f, 0x900e, 0x080c, 0x63a3,
+ 0x1110, 0x080c, 0x5e49, 0x8108, 0x1f04, 0x745e, 0x00be, 0x015e,
+ 0x080c, 0x19a4, 0x080c, 0x9f70, 0x60e3, 0x0000, 0x080c, 0x5e2f,
+ 0x080c, 0x709e, 0x00ee, 0x00ce, 0x004e, 0x003e, 0x002e, 0x001e,
+ 0x015e, 0x0005, 0x2001, 0x1957, 0x2003, 0x0001, 0x0005, 0x2001,
+ 0x1957, 0x2003, 0x0000, 0x0005, 0x2001, 0x1956, 0x2003, 0xaaaa,
+ 0x0005, 0x2001, 0x1956, 0x2003, 0x0000, 0x0005, 0x2071, 0x18f8,
+ 0x7003, 0x0000, 0x7007, 0x0000, 0x080c, 0x1050, 0x090c, 0x0df6,
+ 0xa8ab, 0xdcb0, 0x2900, 0x704e, 0x080c, 0x1050, 0x090c, 0x0df6,
+ 0xa8ab, 0xdcb0, 0x2900, 0x7052, 0xa867, 0x0000, 0xa86b, 0x0001,
+ 0xa89f, 0x0000, 0x0005, 0x00e6, 0x2071, 0x0040, 0x6848, 0x9005,
+ 0x1118, 0x9085, 0x0001, 0x04b0, 0x6840, 0x9005, 0x0150, 0x04a1,
+ 0x6a50, 0x9200, 0x7002, 0x6854, 0x9101, 0x7006, 0x9006, 0x7012,
+ 0x7016, 0x6850, 0x7002, 0x6854, 0x7006, 0x6858, 0x700a, 0x685c,
+ 0x700e, 0x6840, 0x9005, 0x1110, 0x7012, 0x7016, 0x6848, 0x701a,
+ 0x701c, 0x9085, 0x0040, 0x701e, 0x2001, 0x0019, 0x7036, 0x702b,
+ 0x0001, 0x2001, 0x0004, 0x200c, 0x918c, 0xfff7, 0x918d, 0x8000,
+ 0x2102, 0x00d6, 0x2069, 0x18f8, 0x6807, 0x0001, 0x00de, 0x080c,
+ 0x7a7c, 0x9006, 0x00ee, 0x0005, 0x900e, 0x0156, 0x20a9, 0x0006,
+ 0x8003, 0x818d, 0x1f04, 0x74f0, 0x015e, 0x0005, 0x2079, 0x0040,
+ 0x2071, 0x18f8, 0x7004, 0x0002, 0x7506, 0x7507, 0x753f, 0x759a,
+ 0x76df, 0x7504, 0x7504, 0x7709, 0x080c, 0x0df6, 0x0005, 0x2079,
+ 0x0040, 0x782c, 0x908c, 0x0780, 0x190c, 0x7b08, 0xd0a4, 0x01f8,
+ 0x7824, 0x2048, 0x9006, 0xa802, 0xa806, 0xa864, 0x9084, 0x00ff,
+ 0x908a, 0x0040, 0x0610, 0x00c0, 0x2001, 0x1800, 0x200c, 0x9186,
+ 0x0003, 0x1168, 0x7004, 0x0002, 0x752f, 0x7509, 0x752f, 0x752d,
+ 0x752f, 0x752f, 0x752f, 0x752f, 0x752f, 0x080c, 0x759a, 0x782c,
+ 0xd09c, 0x090c, 0x7a7c, 0x0005, 0x9082, 0x005a, 0x1218, 0x2100,
+ 0x003b, 0x0c10, 0x080c, 0x75d0, 0x0c90, 0x00e3, 0x08e8, 0x0005,
+ 0x75d0, 0x75d0, 0x75d0, 0x75d0, 0x75d0, 0x75d0, 0x75d0, 0x75d0,
+ 0x75f2, 0x75d0, 0x75d0, 0x75d0, 0x75d0, 0x75d0, 0x75d0, 0x75d0,
+ 0x75d0, 0x75d0, 0x75d0, 0x75d0, 0x75d0, 0x75d0, 0x75d0, 0x75d0,
+ 0x75d0, 0x75d0, 0x75d0, 0x75d0, 0x75dc, 0x75d0, 0x77e3, 0x75d0,
+ 0x75d0, 0x75d0, 0x75f2, 0x75d0, 0x75dc, 0x7824, 0x7865, 0x78ac,
+ 0x78c0, 0x75d0, 0x75d0, 0x75f2, 0x75dc, 0x75d0, 0x75d0, 0x76b3,
+ 0x796b, 0x7986, 0x75d0, 0x75f2, 0x75d0, 0x75d0, 0x75d0, 0x75d0,
+ 0x76a9, 0x7986, 0x75d0, 0x75d0, 0x75d0, 0x75d0, 0x75d0, 0x75d0,
+ 0x75d0, 0x75d0, 0x75d0, 0x7606, 0x75d0, 0x75d0, 0x75d0, 0x75d0,
+ 0x75d0, 0x75d0, 0x75d0, 0x75d0, 0x75d0, 0x7aac, 0x75d0, 0x75d0,
+ 0x75d0, 0x75d0, 0x75d0, 0x761a, 0x75d0, 0x75d0, 0x75d0, 0x75d0,
+ 0x75d0, 0x75d0, 0x2079, 0x0040, 0x7004, 0x9086, 0x0003, 0x1198,
+ 0x782c, 0x080c, 0x7aa5, 0xd0a4, 0x0170, 0x7824, 0x2048, 0x9006,
+ 0xa802, 0xa806, 0xa864, 0x9084, 0x00ff, 0x908a, 0x001a, 0x1210,
+ 0x002b, 0x0c50, 0x00e9, 0x080c, 0x7a7c, 0x0005, 0x75d0, 0x75dc,
+ 0x77cf, 0x75d0, 0x75dc, 0x75d0, 0x75dc, 0x75dc, 0x75d0, 0x75dc,
+ 0x77cf, 0x75dc, 0x75dc, 0x75dc, 0x75dc, 0x75dc, 0x75d0, 0x75dc,
+ 0x77cf, 0x75d0, 0x75d0, 0x75dc, 0x75d0, 0x75d0, 0x75d0, 0x75dc,
+ 0x00e6, 0x2071, 0x18f8, 0x2009, 0x0400, 0x0071, 0x00ee, 0x0005,
+ 0x2009, 0x1000, 0x0049, 0x0005, 0x2009, 0x2000, 0x0029, 0x0005,
+ 0x2009, 0x0800, 0x0009, 0x0005, 0x7007, 0x0001, 0xa868, 0x9084,
+ 0x00ff, 0x9105, 0xa86a, 0x0126, 0x2091, 0x8000, 0x080c, 0x6a22,
+ 0x012e, 0x0005, 0xa864, 0x8007, 0x9084, 0x00ff, 0x0d08, 0x8001,
+ 0x1120, 0x7007, 0x0001, 0x0804, 0x7788, 0x7007, 0x0003, 0x7012,
+ 0x2900, 0x7016, 0x701a, 0x704b, 0x7788, 0x0005, 0xa864, 0x8007,
+ 0x9084, 0x00ff, 0x0968, 0x8001, 0x1120, 0x7007, 0x0001, 0x0804,
+ 0x77a3, 0x7007, 0x0003, 0x7012, 0x2900, 0x7016, 0x701a, 0x704b,
+ 0x77a3, 0x0005, 0xa864, 0x8007, 0x9084, 0x00ff, 0x9086, 0x0001,
+ 0x1904, 0x75d8, 0x7007, 0x0001, 0x2009, 0x1833, 0x210c, 0x81ff,
+ 0x1904, 0x7680, 0xa99c, 0x9186, 0x00ff, 0x05e8, 0xa994, 0x9186,
+ 0x006f, 0x0188, 0x9186, 0x0074, 0x15b0, 0x0026, 0x2011, 0x0010,
+ 0x080c, 0x66ed, 0x002e, 0x0578, 0x0016, 0xa998, 0x080c, 0x6737,
+ 0x001e, 0x1548, 0x0400, 0x080c, 0x717e, 0x0140, 0xa897, 0x4005,
+ 0xa89b, 0x0016, 0x2001, 0x0030, 0x900e, 0x0438, 0x0026, 0x2011,
+ 0x8008, 0x080c, 0x66ed, 0x002e, 0x01b0, 0x0016, 0x0026, 0x0036,
+ 0xa998, 0xaaa0, 0xab9c, 0x918d, 0x8000, 0x080c, 0x6737, 0x003e,
+ 0x002e, 0x001e, 0x1140, 0xa897, 0x4005, 0xa89b, 0x4009, 0x2001,
+ 0x0030, 0x900e, 0x0050, 0xa868, 0x9084, 0x00ff, 0xa86a, 0xa883,
+ 0x0000, 0x080c, 0x6061, 0x1108, 0x0005, 0x0126, 0x2091, 0x8000,
+ 0xa867, 0x0139, 0xa87a, 0xa982, 0x080c, 0x6a22, 0x012e, 0x0ca0,
+ 0xa994, 0x9186, 0x0071, 0x0904, 0x762a, 0x9186, 0x0064, 0x0904,
+ 0x762a, 0x9186, 0x007c, 0x0904, 0x762a, 0x9186, 0x0028, 0x0904,
+ 0x762a, 0x9186, 0x0038, 0x0904, 0x762a, 0x9186, 0x0078, 0x0904,
+ 0x762a, 0x9186, 0x005f, 0x0904, 0x762a, 0x9186, 0x0056, 0x0904,
+ 0x762a, 0xa897, 0x4005, 0xa89b, 0x0001, 0x2001, 0x0030, 0x900e,
+ 0x0860, 0xa87c, 0x9084, 0x00c0, 0x9086, 0x00c0, 0x1120, 0x7007,
+ 0x0001, 0x0804, 0x799d, 0x2900, 0x7016, 0x701a, 0x20a9, 0x0004,
+ 0xa860, 0x20e0, 0xa85c, 0x9080, 0x0030, 0x2098, 0x7050, 0x2040,
+ 0xa060, 0x20e8, 0xa05c, 0x9080, 0x0023, 0x20a0, 0x4003, 0xa888,
+ 0x7012, 0x9082, 0x0401, 0x1a04, 0x75e0, 0xaab4, 0x928a, 0x0002,
+ 0x1a04, 0x75e0, 0x82ff, 0x1138, 0xa8b8, 0xa9bc, 0x9105, 0x0118,
+ 0x2001, 0x7746, 0x0018, 0x9280, 0x773c, 0x2005, 0x7056, 0x7010,
+ 0x9015, 0x0904, 0x7727, 0x080c, 0x1050, 0x1118, 0x7007, 0x0004,
+ 0x0005, 0x2900, 0x7022, 0x7054, 0x2060, 0xe000, 0xa866, 0x7050,
+ 0x2040, 0xa95c, 0xe004, 0x9100, 0xa076, 0xa860, 0xa072, 0xe008,
+ 0x920a, 0x1210, 0x900e, 0x2200, 0x7112, 0xe20c, 0x8003, 0x800b,
+ 0x9296, 0x0004, 0x0108, 0x9108, 0xa17a, 0x810b, 0xa17e, 0x080c,
+ 0x1134, 0xa06c, 0x908e, 0x0100, 0x0170, 0x9086, 0x0200, 0x0118,
+ 0x7007, 0x0007, 0x0005, 0x7020, 0x2048, 0x080c, 0x1069, 0x7014,
+ 0x2048, 0x0804, 0x75e0, 0x7020, 0x2048, 0x7018, 0xa802, 0xa807,
+ 0x0000, 0x2908, 0x2048, 0xa906, 0x711a, 0x0804, 0x76df, 0x7014,
+ 0x2048, 0x7007, 0x0001, 0xa8b4, 0x9005, 0x1128, 0xa8b8, 0xa9bc,
+ 0x9105, 0x0108, 0x00b9, 0xa864, 0x9084, 0x00ff, 0x9086, 0x001e,
+ 0x0904, 0x799d, 0x0804, 0x7788, 0x773e, 0x7742, 0x0002, 0x001d,
+ 0x0007, 0x0004, 0x000a, 0x001b, 0x0005, 0x0006, 0x000a, 0x001d,
+ 0x0005, 0x0004, 0x0076, 0x0066, 0xafb8, 0xaebc, 0xa804, 0x2050,
+ 0xb0c0, 0xb0e2, 0xb0bc, 0xb0de, 0xb0b8, 0xb0d2, 0xb0b4, 0xb0ce,
+ 0xb6da, 0xb7d6, 0xb0b0, 0xb0ca, 0xb0ac, 0xb0c6, 0xb0a8, 0xb0ba,
+ 0xb0a4, 0xb0b6, 0xb6c2, 0xb7be, 0xb0a0, 0xb0b2, 0xb09c, 0xb0ae,
+ 0xb098, 0xb0a2, 0xb094, 0xb09e, 0xb6aa, 0xb7a6, 0xb090, 0xb09a,
+ 0xb08c, 0xb096, 0xb088, 0xb08a, 0xb084, 0xb086, 0xb692, 0xb78e,
+ 0xb080, 0xb082, 0xb07c, 0xb07e, 0xb078, 0xb072, 0xb074, 0xb06e,
+ 0xb67a, 0xb776, 0xb004, 0x9055, 0x1958, 0x006e, 0x007e, 0x0005,
+ 0x2009, 0x1833, 0x210c, 0x81ff, 0x1178, 0x080c, 0x5eab, 0x1108,
+ 0x0005, 0x080c, 0x6c6b, 0x0126, 0x2091, 0x8000, 0x080c, 0xc044,
+ 0x080c, 0x6a22, 0x012e, 0x0ca0, 0x080c, 0xc452, 0x1d70, 0x2001,
+ 0x0028, 0x900e, 0x0c70, 0x0419, 0x11d8, 0xa888, 0x9005, 0x01e0,
+ 0xa883, 0x0000, 0xa87c, 0xd0f4, 0x0120, 0x080c, 0x5fc3, 0x1138,
+ 0x0005, 0x9006, 0xa87a, 0x080c, 0x5f3b, 0x1108, 0x0005, 0x0126,
+ 0x2091, 0x8000, 0xa87a, 0xa982, 0x080c, 0x6a22, 0x012e, 0x0cb0,
+ 0x2001, 0x0028, 0x900e, 0x0c98, 0x2001, 0x0000, 0x0c80, 0x00c6,
+ 0x2061, 0x1800, 0x60cc, 0x9005, 0x0100, 0x00ce, 0x0005, 0x7018,
+ 0xa802, 0x2908, 0x2048, 0xa906, 0x711a, 0x7010, 0x8001, 0x7012,
+ 0x0118, 0x7007, 0x0003, 0x0030, 0x7014, 0x2048, 0x7007, 0x0001,
+ 0x7048, 0x080f, 0x0005, 0x00b6, 0x7007, 0x0001, 0xa974, 0xa878,
+ 0x9084, 0x00ff, 0x9096, 0x0004, 0x0540, 0x20a9, 0x0001, 0x9096,
+ 0x0001, 0x0190, 0x900e, 0x20a9, 0x0800, 0x9096, 0x0002, 0x0160,
+ 0x9005, 0x11d8, 0xa974, 0x080c, 0x63a3, 0x11b8, 0x0066, 0xae80,
+ 0x080c, 0x64b3, 0x006e, 0x0088, 0x0046, 0x2011, 0x180c, 0x2224,
+ 0xc484, 0x2412, 0x004e, 0x00c6, 0x080c, 0x63a3, 0x1110, 0x080c,
+ 0x65b3, 0x8108, 0x1f04, 0x780c, 0x00ce, 0xa87c, 0xd084, 0x1120,
+ 0x080c, 0x1069, 0x00be, 0x0005, 0x0126, 0x2091, 0x8000, 0x080c,
+ 0x6a22, 0x012e, 0x00be, 0x0005, 0x0126, 0x2091, 0x8000, 0x7007,
+ 0x0001, 0x080c, 0x66c5, 0x0580, 0x2061, 0x1a4c, 0x6100, 0xd184,
+ 0x0178, 0xa888, 0x9084, 0x00ff, 0x1550, 0x6000, 0xd084, 0x0520,
+ 0x6004, 0x9005, 0x1538, 0x6003, 0x0000, 0x600b, 0x0000, 0x00c8,
+ 0x2011, 0x0001, 0xa890, 0x9005, 0x1110, 0x2001, 0x001e, 0x8000,
+ 0x6016, 0xa888, 0x9084, 0x00ff, 0x0178, 0x6006, 0xa888, 0x8007,
+ 0x9084, 0x00ff, 0x0148, 0x600a, 0xa888, 0x8000, 0x1108, 0xc28d,
+ 0x6202, 0x012e, 0x0804, 0x7a66, 0x012e, 0x0804, 0x7a60, 0x012e,
+ 0x0804, 0x7a5a, 0x012e, 0x0804, 0x7a5d, 0x0126, 0x2091, 0x8000,
+ 0x7007, 0x0001, 0x080c, 0x66c5, 0x05e0, 0x2061, 0x1a4c, 0x6000,
+ 0xd084, 0x05b8, 0x6204, 0x6308, 0xd08c, 0x1530, 0xac78, 0x9484,
+ 0x0003, 0x0170, 0xa988, 0x918c, 0x00ff, 0x8001, 0x1120, 0x2100,
+ 0x9210, 0x0620, 0x0028, 0x8001, 0x1508, 0x2100, 0x9212, 0x02f0,
+ 0x9484, 0x000c, 0x0188, 0xa988, 0x810f, 0x918c, 0x00ff, 0x9082,
+ 0x0004, 0x1120, 0x2100, 0x9318, 0x0288, 0x0030, 0x9082, 0x0004,
+ 0x1168, 0x2100, 0x931a, 0x0250, 0xa890, 0x9005, 0x0110, 0x8000,
+ 0x6016, 0x6206, 0x630a, 0x012e, 0x0804, 0x7a66, 0x012e, 0x0804,
+ 0x7a63, 0x012e, 0x0804, 0x7a60, 0x0126, 0x2091, 0x8000, 0x7007,
+ 0x0001, 0x2061, 0x1a4c, 0x6300, 0xd38c, 0x1120, 0x6308, 0x8318,
+ 0x0220, 0x630a, 0x012e, 0x0804, 0x7a74, 0x012e, 0x0804, 0x7a63,
+ 0x00b6, 0x0126, 0x00c6, 0x2091, 0x8000, 0x7007, 0x0001, 0xa87c,
+ 0xd0ac, 0x0148, 0x00c6, 0x2061, 0x1a4c, 0x6000, 0x9084, 0xfcff,
+ 0x6002, 0x00ce, 0x0440, 0xa888, 0x9005, 0x05d8, 0xa88c, 0x9065,
+ 0x0598, 0x2001, 0x1833, 0x2004, 0x9005, 0x0118, 0x080c, 0xa01c,
+ 0x0068, 0x6017, 0xf400, 0x605b, 0x0000, 0xa97c, 0xd1a4, 0x0110,
+ 0xa980, 0x615a, 0x2009, 0x0041, 0x080c, 0xa068, 0xa988, 0x918c,
+ 0xff00, 0x9186, 0x2000, 0x1138, 0x0026, 0x900e, 0x2011, 0xfdff,
+ 0x080c, 0x8450, 0x002e, 0xa87c, 0xd0c4, 0x0148, 0x2061, 0x1a4c,
+ 0x6000, 0xd08c, 0x1120, 0x6008, 0x8000, 0x0208, 0x600a, 0x00ce,
+ 0x012e, 0x00be, 0x0804, 0x7a66, 0x00ce, 0x012e, 0x00be, 0x0804,
+ 0x7a60, 0xa984, 0x9186, 0x002e, 0x0d30, 0x9186, 0x002d, 0x0d18,
+ 0x9186, 0x0045, 0x0510, 0x9186, 0x002a, 0x1130, 0x2001, 0x180c,
+ 0x200c, 0xc194, 0x2102, 0x08b8, 0x9186, 0x0020, 0x0158, 0x9186,
+ 0x0029, 0x1d10, 0xa974, 0x080c, 0x63a3, 0x1968, 0xb800, 0xc0e4,
+ 0xb802, 0x0848, 0xa88c, 0x9065, 0x09b8, 0x6007, 0x0024, 0x2001,
+ 0x1960, 0x2004, 0x601a, 0x0804, 0x78fb, 0xa88c, 0x9065, 0x0960,
+ 0x00e6, 0xa890, 0x9075, 0x2001, 0x1833, 0x2004, 0x9005, 0x0150,
+ 0x080c, 0xa01c, 0x8eff, 0x0118, 0x2e60, 0x080c, 0xa01c, 0x00ee,
+ 0x0804, 0x78fb, 0x6024, 0xc0dc, 0xc0d5, 0x6026, 0x2e60, 0x6007,
+ 0x003a, 0xa8a0, 0x9005, 0x0130, 0x6007, 0x003b, 0xa8a4, 0x602e,
+ 0xa8a8, 0x6016, 0x6003, 0x0001, 0x080c, 0x85f8, 0x080c, 0x8b8f,
+ 0x00ee, 0x0804, 0x78fb, 0x2061, 0x1a4c, 0x6000, 0xd084, 0x0190,
+ 0xd08c, 0x1904, 0x7a74, 0x0126, 0x2091, 0x8000, 0x6204, 0x8210,
+ 0x0220, 0x6206, 0x012e, 0x0804, 0x7a74, 0x012e, 0xa883, 0x0016,
+ 0x0804, 0x7a6d, 0xa883, 0x0007, 0x0804, 0x7a6d, 0xa864, 0x8007,
+ 0x9084, 0x00ff, 0x0130, 0x8001, 0x1138, 0x7007, 0x0001, 0x0069,
+ 0x0005, 0x080c, 0x75d8, 0x0040, 0x7007, 0x0003, 0x7012, 0x2900,
+ 0x7016, 0x701a, 0x704b, 0x799d, 0x0005, 0x00b6, 0x00e6, 0x0126,
+ 0x2091, 0x8000, 0x903e, 0x2061, 0x1800, 0x61cc, 0x81ff, 0x1904,
+ 0x7a1f, 0x6130, 0xd194, 0x1904, 0x7a49, 0xa878, 0x2070, 0x9e82,
+ 0x1cd0, 0x0a04, 0x7a13, 0x6064, 0x9e02, 0x1a04, 0x7a13, 0x7120,
+ 0x9186, 0x0006, 0x1904, 0x7a05, 0x7010, 0x905d, 0x0904, 0x7a1f,
+ 0xb800, 0xd0e4, 0x1904, 0x7a43, 0x2061, 0x1a4c, 0x6100, 0x9184,
+ 0x0301, 0x9086, 0x0001, 0x15a0, 0x7024, 0xd0dc, 0x1904, 0x7a4c,
+ 0xa883, 0x0000, 0xa803, 0x0000, 0x2908, 0x7014, 0x9005, 0x1198,
+ 0x7116, 0xa87c, 0xd0f4, 0x1904, 0x7a4f, 0x080c, 0x54db, 0xd09c,
+ 0x1118, 0xa87c, 0xc0cc, 0xa87e, 0x2e60, 0x080c, 0x8370, 0x012e,
+ 0x00ee, 0x00be, 0x0005, 0x2048, 0xa800, 0x9005, 0x1de0, 0xa902,
+ 0x2148, 0xa87c, 0xd0f4, 0x1904, 0x7a4f, 0x012e, 0x00ee, 0x00be,
+ 0x0005, 0x012e, 0x00ee, 0xa883, 0x0006, 0x00be, 0x0804, 0x7a6d,
+ 0xd184, 0x0db8, 0xd1c4, 0x1190, 0x00a0, 0xa974, 0x080c, 0x63a3,
+ 0x15d0, 0xb800, 0xd0e4, 0x15b8, 0x7120, 0x9186, 0x0007, 0x1118,
+ 0xa883, 0x0002, 0x0490, 0xa883, 0x0008, 0x0478, 0xa883, 0x000e,
+ 0x0460, 0xa883, 0x0017, 0x0448, 0xa883, 0x0035, 0x0430, 0x080c,
+ 0x54df, 0xd0fc, 0x01e8, 0xa878, 0x2070, 0x9e82, 0x1cd0, 0x02c0,
+ 0x6064, 0x9e02, 0x12a8, 0x7120, 0x9186, 0x0006, 0x1188, 0x7010,
+ 0x905d, 0x0170, 0xb800, 0xd0bc, 0x0158, 0x2039, 0x0001, 0x7000,
+ 0x9086, 0x0007, 0x1904, 0x79a9, 0x7003, 0x0002, 0x0804, 0x79a9,
+ 0xa883, 0x0028, 0x0010, 0xa883, 0x0029, 0x012e, 0x00ee, 0x00be,
+ 0x0420, 0xa883, 0x002a, 0x0cc8, 0xa883, 0x0045, 0x0cb0, 0x2e60,
+ 0x2019, 0x0002, 0x601b, 0x0014, 0x080c, 0xd38f, 0x012e, 0x00ee,
+ 0x00be, 0x0005, 0x2009, 0x003e, 0x0058, 0x2009, 0x0004, 0x0040,
+ 0x2009, 0x0006, 0x0028, 0x2009, 0x0016, 0x0010, 0x2009, 0x0001,
+ 0xa884, 0x9084, 0xff00, 0x9105, 0xa886, 0x0126, 0x2091, 0x8000,
+ 0x080c, 0x6a22, 0x012e, 0x0005, 0x080c, 0x1069, 0x0005, 0x00d6,
+ 0x080c, 0x8367, 0x00de, 0x0005, 0x00d6, 0x00e6, 0x0126, 0x2091,
+ 0x8000, 0x2071, 0x0040, 0x702c, 0xd084, 0x01d8, 0x908c, 0x0780,
+ 0x190c, 0x7b08, 0xd09c, 0x11a8, 0x2071, 0x1800, 0x70bc, 0x90ea,
+ 0x0040, 0x0278, 0x8001, 0x70be, 0x702c, 0x2048, 0xa800, 0x702e,
+ 0x9006, 0xa802, 0xa806, 0x2071, 0x0040, 0x2900, 0x7022, 0x702c,
+ 0x0c28, 0x012e, 0x00ee, 0x00de, 0x0005, 0x0006, 0x9084, 0x0780,
+ 0x190c, 0x7b08, 0x000e, 0x0005, 0x00d6, 0x00c6, 0x0036, 0x0026,
+ 0x0016, 0x00b6, 0x7007, 0x0001, 0xaa74, 0x9282, 0x0004, 0x1a04,
+ 0x7af9, 0xa97c, 0x9188, 0x1000, 0x2104, 0x905d, 0xb804, 0xd284,
+ 0x0140, 0x05e8, 0x8007, 0x9084, 0x00ff, 0x9084, 0x0006, 0x1108,
+ 0x04b0, 0x2b10, 0x080c, 0x9f94, 0x1118, 0x080c, 0xa03b, 0x05a8,
+ 0x6212, 0xa874, 0x0002, 0x7ad7, 0x7adc, 0x7adf, 0x7ae5, 0x2019,
+ 0x0002, 0x080c, 0xd7af, 0x0060, 0x080c, 0xd746, 0x0048, 0x2019,
+ 0x0002, 0xa980, 0x080c, 0xd761, 0x0018, 0xa980, 0x080c, 0xd746,
+ 0x080c, 0x9fea, 0xa887, 0x0000, 0x0126, 0x2091, 0x8000, 0x080c,
+ 0x6a22, 0x012e, 0x00be, 0x001e, 0x002e, 0x003e, 0x00ce, 0x00de,
+ 0x0005, 0xa887, 0x0006, 0x0c80, 0xa887, 0x0002, 0x0c68, 0xa887,
+ 0x0005, 0x0c50, 0xa887, 0x0004, 0x0c38, 0xa887, 0x0007, 0x0c20,
+ 0x2091, 0x8000, 0x0e04, 0x7b0a, 0x0006, 0x0016, 0x2001, 0x8003,
+ 0x0006, 0x0804, 0x0dff, 0x2001, 0x1833, 0x2004, 0x9005, 0x0005,
+ 0x0005, 0x00f6, 0x2079, 0x0300, 0x2001, 0x0200, 0x200c, 0xc1e5,
+ 0xc1dc, 0x2102, 0x2009, 0x0218, 0x210c, 0xd1ec, 0x1120, 0x080c,
+ 0x150f, 0x00fe, 0x0005, 0x2001, 0x020d, 0x2003, 0x0020, 0x781f,
+ 0x0300, 0x00fe, 0x0005, 0x781c, 0xd08c, 0x0904, 0x7b8a, 0x68bc,
+ 0x90aa, 0x0005, 0x0a04, 0x8166, 0x7d44, 0x7c40, 0x9584, 0x00f6,
+ 0x1510, 0x9484, 0x7000, 0x0140, 0x908a, 0x2000, 0x1260, 0x9584,
+ 0x0700, 0x8007, 0x0804, 0x7b91, 0x7000, 0x9084, 0xff00, 0x9086,
+ 0x8100, 0x0da8, 0x00b0, 0x9484, 0x0fff, 0x1130, 0x7000, 0x9084,
+ 0xff00, 0x9086, 0x8100, 0x11c0, 0x080c, 0xdbb3, 0x080c, 0x809b,
+ 0x7817, 0x0140, 0x00a8, 0x9584, 0x0076, 0x1118, 0x080c, 0x80f9,
+ 0x19c0, 0xd5a4, 0x0148, 0x0046, 0x0056, 0x080c, 0x7bec, 0x080c,
+ 0x2165, 0x005e, 0x004e, 0x0020, 0x080c, 0xdbb3, 0x7817, 0x0140,
+ 0x080c, 0x717e, 0x0168, 0x2001, 0x0111, 0x2004, 0xd08c, 0x0140,
+ 0x688f, 0x0000, 0x2001, 0x0110, 0x2003, 0x0008, 0x2003, 0x0000,
+ 0x080c, 0x7bcd, 0x2001, 0x19cb, 0x2004, 0x9005, 0x090c, 0x8b8f,
+ 0x0005, 0x0002, 0x7ba3, 0x7ea3, 0x7b9a, 0x7b9a, 0x7b9a, 0x7b9a,
+ 0x7b9a, 0x7b9a, 0x7817, 0x0140, 0x2001, 0x19cb, 0x2004, 0x9005,
+ 0x090c, 0x8b8f, 0x0005, 0x7000, 0x908c, 0xff00, 0x9194, 0xf000,
+ 0x810f, 0x9484, 0x0fff, 0x688e, 0x9286, 0x2000, 0x1150, 0x6800,
+ 0x9086, 0x0001, 0x1118, 0x080c, 0x5545, 0x0070, 0x080c, 0x7c0c,
+ 0x0058, 0x9286, 0x3000, 0x1118, 0x080c, 0x7ddb, 0x0028, 0x9286,
+ 0x8000, 0x1110, 0x080c, 0x7fc2, 0x7817, 0x0140, 0x2001, 0x19cb,
+ 0x2004, 0x9005, 0x090c, 0x8b8f, 0x0005, 0x2001, 0x1810, 0x2004,
+ 0xd08c, 0x0178, 0x2001, 0x1800, 0x2004, 0x9086, 0x0003, 0x1148,
+ 0x0026, 0x0036, 0x2011, 0x8048, 0x2518, 0x080c, 0x4a17, 0x003e,
+ 0x002e, 0x0005, 0x0036, 0x0046, 0x0056, 0x00f6, 0x2079, 0x0200,
+ 0x2019, 0xfffe, 0x7c30, 0x0050, 0x0036, 0x0046, 0x0056, 0x00f6,
+ 0x2079, 0x0200, 0x7d44, 0x7c40, 0x2019, 0xffff, 0x2001, 0x1810,
+ 0x2004, 0xd08c, 0x0160, 0x2001, 0x1800, 0x2004, 0x9086, 0x0003,
+ 0x1130, 0x0026, 0x2011, 0x8048, 0x080c, 0x4a17, 0x002e, 0x00fe,
+ 0x005e, 0x004e, 0x003e, 0x0005, 0x00b6, 0x00c6, 0x7010, 0x9084,
+ 0xff00, 0x8007, 0x9096, 0x0001, 0x0120, 0x9096, 0x0023, 0x1904,
+ 0x7dac, 0x9186, 0x0023, 0x15c0, 0x080c, 0x8060, 0x0904, 0x7dac,
+ 0x6120, 0x9186, 0x0001, 0x0150, 0x9186, 0x0004, 0x0138, 0x9186,
+ 0x0008, 0x0120, 0x9186, 0x000a, 0x1904, 0x7dac, 0x7124, 0x610a,
+ 0x7030, 0x908e, 0x0200, 0x1130, 0x2009, 0x0015, 0x080c, 0xa068,
+ 0x0804, 0x7dac, 0x908e, 0x0214, 0x0118, 0x908e, 0x0210, 0x1130,
+ 0x2009, 0x0015, 0x080c, 0xa068, 0x0804, 0x7dac, 0x908e, 0x0100,
+ 0x1904, 0x7dac, 0x7034, 0x9005, 0x1904, 0x7dac, 0x2009, 0x0016,
+ 0x080c, 0xa068, 0x0804, 0x7dac, 0x9186, 0x0022, 0x1904, 0x7dac,
+ 0x7030, 0x908e, 0x0300, 0x1580, 0x68d8, 0xd0a4, 0x0528, 0xc0b5,
+ 0x68da, 0x7100, 0x918c, 0x00ff, 0x697a, 0x7004, 0x687e, 0x00f6,
+ 0x2079, 0x0100, 0x79e6, 0x78ea, 0x0006, 0x9084, 0x00ff, 0x0016,
+ 0x2008, 0x080c, 0x26b6, 0x7932, 0x7936, 0x001e, 0x000e, 0x00fe,
+ 0x080c, 0x266d, 0x695a, 0x703c, 0x00e6, 0x2071, 0x0140, 0x7086,
+ 0x2071, 0x1800, 0x70b2, 0x00ee, 0x7034, 0x9005, 0x1904, 0x7dac,
+ 0x2009, 0x0017, 0x0804, 0x7d5c, 0x908e, 0x0400, 0x1190, 0x7034,
+ 0x9005, 0x1904, 0x7dac, 0x080c, 0x717e, 0x0120, 0x2009, 0x001d,
+ 0x0804, 0x7d5c, 0x68d8, 0xc0a5, 0x68da, 0x2009, 0x0030, 0x0804,
+ 0x7d5c, 0x908e, 0x0500, 0x1140, 0x7034, 0x9005, 0x1904, 0x7dac,
+ 0x2009, 0x0018, 0x0804, 0x7d5c, 0x908e, 0x2010, 0x1120, 0x2009,
+ 0x0019, 0x0804, 0x7d5c, 0x908e, 0x2110, 0x1120, 0x2009, 0x001a,
+ 0x0804, 0x7d5c, 0x908e, 0x5200, 0x1140, 0x7034, 0x9005, 0x1904,
+ 0x7dac, 0x2009, 0x001b, 0x0804, 0x7d5c, 0x908e, 0x5000, 0x1140,
+ 0x7034, 0x9005, 0x1904, 0x7dac, 0x2009, 0x001c, 0x0804, 0x7d5c,
+ 0x908e, 0x1300, 0x1120, 0x2009, 0x0034, 0x0804, 0x7d5c, 0x908e,
+ 0x1200, 0x1140, 0x7034, 0x9005, 0x1904, 0x7dac, 0x2009, 0x0024,
+ 0x0804, 0x7d5c, 0x908c, 0xff00, 0x918e, 0x2400, 0x1170, 0x2009,
+ 0x002d, 0x2001, 0x1810, 0x2004, 0xd09c, 0x0904, 0x7d5c, 0x080c,
+ 0xcb61, 0x1904, 0x7dac, 0x0804, 0x7d5a, 0x908c, 0xff00, 0x918e,
+ 0x5300, 0x1120, 0x2009, 0x002a, 0x0804, 0x7d5c, 0x908e, 0x0f00,
+ 0x1120, 0x2009, 0x0020, 0x0804, 0x7d5c, 0x908e, 0x6104, 0x1528,
+ 0x2029, 0x0205, 0x2011, 0x026d, 0x8208, 0x2204, 0x9082, 0x0004,
+ 0x8004, 0x8004, 0x20a8, 0x2011, 0x8015, 0x211c, 0x8108, 0x0046,
+ 0x2124, 0x080c, 0x4a17, 0x004e, 0x8108, 0x0f04, 0x7d28, 0x9186,
+ 0x0280, 0x1d88, 0x2504, 0x8000, 0x202a, 0x2009, 0x0260, 0x0c58,
+ 0x202b, 0x0000, 0x2009, 0x0023, 0x0478, 0x908e, 0x6000, 0x1118,
+ 0x2009, 0x003f, 0x0448, 0x908e, 0x7800, 0x1118, 0x2009, 0x0045,
+ 0x0418, 0x908e, 0x1000, 0x1118, 0x2009, 0x004e, 0x00e8, 0x908e,
+ 0x6300, 0x1118, 0x2009, 0x004a, 0x00b8, 0x908c, 0xff00, 0x918e,
+ 0x5600, 0x1118, 0x2009, 0x004f, 0x0078, 0x908c, 0xff00, 0x918e,
+ 0x5700, 0x1118, 0x2009, 0x0050, 0x0038, 0x2009, 0x001d, 0x6838,
+ 0xd0d4, 0x0110, 0x2009, 0x004c, 0x0016, 0x2011, 0x0263, 0x2204,
+ 0x8211, 0x220c, 0x080c, 0x266d, 0x1904, 0x7daf, 0x080c, 0x6343,
+ 0x1904, 0x7daf, 0xbe12, 0xbd16, 0x001e, 0x0016, 0x080c, 0x717e,
+ 0x01c0, 0x68d8, 0xd08c, 0x1148, 0x7000, 0x9084, 0x00ff, 0x1188,
+ 0x7004, 0x9084, 0xff00, 0x1168, 0x0040, 0x6878, 0x9606, 0x1148,
+ 0x687c, 0x9506, 0x9084, 0xff00, 0x1120, 0x9584, 0x00ff, 0xb8b2,
+ 0x0080, 0xb8b0, 0x9005, 0x1168, 0x9186, 0x0046, 0x1150, 0x6878,
+ 0x9606, 0x1138, 0x687c, 0x9506, 0x9084, 0xff00, 0x1110, 0x001e,
+ 0x0098, 0x080c, 0x9f94, 0x01a8, 0x2b08, 0x6112, 0x6023, 0x0004,
+ 0x7120, 0x610a, 0x001e, 0x9186, 0x004c, 0x1110, 0x6023, 0x000a,
+ 0x0016, 0x001e, 0x080c, 0xa068, 0x00ce, 0x00be, 0x0005, 0x001e,
+ 0x0cd8, 0x2001, 0x180e, 0x2004, 0xd0ec, 0x0120, 0x2011, 0x8049,
+ 0x080c, 0x4a17, 0x080c, 0xa03b, 0x0d90, 0x2b08, 0x6112, 0x6023,
+ 0x0004, 0x7120, 0x610a, 0x001e, 0x0016, 0x9186, 0x0017, 0x0118,
+ 0x9186, 0x0030, 0x1128, 0x6007, 0x0009, 0x6017, 0x2900, 0x0020,
+ 0x6007, 0x0051, 0x6017, 0x0000, 0x602f, 0x0009, 0x6003, 0x0001,
+ 0x080c, 0x8640, 0x08a0, 0x080c, 0x8185, 0x1158, 0x080c, 0x31b8,
+ 0x1140, 0x7010, 0x9084, 0xff00, 0x8007, 0x908e, 0x0008, 0x1108,
+ 0x0009, 0x0005, 0x00b6, 0x00c6, 0x0046, 0x7000, 0x908c, 0xff00,
+ 0x810f, 0x9186, 0x0033, 0x11e8, 0x080c, 0x8060, 0x0904, 0x7e3b,
+ 0x7124, 0x610a, 0x7030, 0x908e, 0x0200, 0x1140, 0x7034, 0x9005,
+ 0x15d0, 0x2009, 0x0015, 0x080c, 0xa068, 0x04a8, 0x908e, 0x0100,
+ 0x1590, 0x7034, 0x9005, 0x1578, 0x2009, 0x0016, 0x080c, 0xa068,
+ 0x0450, 0x9186, 0x0032, 0x1538, 0x7030, 0x908e, 0x1400, 0x1518,
+ 0x2009, 0x0038, 0x0016, 0x2011, 0x0263, 0x2204, 0x8211, 0x220c,
+ 0x080c, 0x266d, 0x11b8, 0x080c, 0x6343, 0x11a0, 0xbe12, 0xbd16,
+ 0x080c, 0x9f94, 0x0178, 0x2b08, 0x6112, 0x080c, 0xc1ca, 0x6023,
+ 0x0004, 0x7120, 0x610a, 0x001e, 0x080c, 0xa068, 0x080c, 0x8b8f,
+ 0x0010, 0x00ce, 0x001e, 0x004e, 0x00ce, 0x00be, 0x0005, 0x00b6,
+ 0x0046, 0x00e6, 0x00d6, 0x2028, 0x2130, 0x9696, 0x00ff, 0x11b8,
+ 0x9592, 0xfffc, 0x02a0, 0x9596, 0xfffd, 0x1120, 0x2009, 0x007f,
+ 0x0804, 0x7e9d, 0x9596, 0xfffe, 0x1120, 0x2009, 0x007e, 0x0804,
+ 0x7e9d, 0x9596, 0xfffc, 0x1118, 0x2009, 0x0080, 0x04f0, 0x2011,
+ 0x0000, 0x2019, 0x1836, 0x231c, 0xd3ac, 0x0130, 0x9026, 0x20a9,
+ 0x0800, 0x2071, 0x1000, 0x0030, 0x2021, 0x0081, 0x20a9, 0x077f,
+ 0x2071, 0x1081, 0x2e1c, 0x93dd, 0x0000, 0x1140, 0x82ff, 0x11d0,
+ 0x9496, 0x00ff, 0x01b8, 0x2410, 0xc2fd, 0x00a0, 0xbf10, 0x2600,
+ 0x9706, 0xb814, 0x1120, 0x9546, 0x1110, 0x2408, 0x00b0, 0x9745,
+ 0x1148, 0x94c6, 0x007e, 0x0130, 0x94c6, 0x007f, 0x0118, 0x94c6,
+ 0x0080, 0x1d20, 0x8420, 0x8e70, 0x1f04, 0x7e72, 0x82ff, 0x1118,
+ 0x9085, 0x0001, 0x0018, 0xc2fc, 0x2208, 0x9006, 0x00de, 0x00ee,
+ 0x004e, 0x00be, 0x0005, 0x2001, 0x1836, 0x200c, 0x9184, 0x0080,
+ 0x0110, 0xd18c, 0x0138, 0x7000, 0x908c, 0xff00, 0x810f, 0x9184,
+ 0x000f, 0x004a, 0x7817, 0x0140, 0x2001, 0x19cb, 0x2004, 0x9005,
+ 0x090c, 0x8b8f, 0x0005, 0x7ecb, 0x7ecb, 0x7ecb, 0x8072, 0x7ecb,
+ 0x7ed4, 0x7eff, 0x7f8d, 0x7ecb, 0x7ecb, 0x7ecb, 0x7ecb, 0x7ecb,
+ 0x7ecb, 0x7ecb, 0x7ecb, 0x7817, 0x0140, 0x2001, 0x19cb, 0x2004,
+ 0x9005, 0x090c, 0x8b8f, 0x0005, 0x00b6, 0x7110, 0xd1bc, 0x01e8,
+ 0x7120, 0x2160, 0x9c8c, 0x0007, 0x11c0, 0x9c8a, 0x1cd0, 0x02a8,
+ 0x6864, 0x9c02, 0x1290, 0x7008, 0x9084, 0x00ff, 0x6110, 0x2158,
+ 0xb910, 0x9106, 0x1150, 0x700c, 0xb914, 0x9106, 0x1130, 0x7124,
+ 0x610a, 0x2009, 0x0046, 0x080c, 0xa068, 0x7817, 0x0140, 0x2001,
+ 0x19cb, 0x2004, 0x9005, 0x090c, 0x8b8f, 0x00be, 0x0005, 0x00b6,
+ 0x00c6, 0x9484, 0x0fff, 0x0904, 0x7f63, 0x7110, 0xd1bc, 0x1904,
+ 0x7f63, 0x7108, 0x700c, 0x2028, 0x918c, 0x00ff, 0x2130, 0x9094,
+ 0xff00, 0x15b0, 0x81ff, 0x15a0, 0x9080, 0x31f3, 0x200d, 0x918c,
+ 0xff00, 0x810f, 0x2001, 0x0080, 0x9106, 0x0904, 0x7f63, 0x080c,
+ 0x6343, 0x1904, 0x7f63, 0xbe12, 0xbd16, 0xb800, 0xd0ec, 0x15d8,
+ 0xba04, 0x9294, 0xff00, 0x9286, 0x0600, 0x11a0, 0x080c, 0x9f94,
+ 0x05e8, 0x2b08, 0x7028, 0x6046, 0x702c, 0x604a, 0x6112, 0x6023,
+ 0x0006, 0x7120, 0x610a, 0x7130, 0x6156, 0x2009, 0x0044, 0x080c,
+ 0xcdd7, 0x0408, 0x080c, 0x66c9, 0x1138, 0xb807, 0x0606, 0x0c30,
+ 0x190c, 0x7e3f, 0x11c0, 0x0898, 0x080c, 0x9f94, 0x2b08, 0x0198,
+ 0x6112, 0x6023, 0x0004, 0x7120, 0x610a, 0x9286, 0x0400, 0x1118,
+ 0x6007, 0x0005, 0x0010, 0x6007, 0x0001, 0x6003, 0x0001, 0x080c,
+ 0x8640, 0x080c, 0x8b8f, 0x7817, 0x0140, 0x2001, 0x19cb, 0x2004,
+ 0x9005, 0x090c, 0x8b8f, 0x00ce, 0x00be, 0x0005, 0x2001, 0x180e,
+ 0x2004, 0xd0ec, 0x0120, 0x2011, 0x8049, 0x080c, 0x4a17, 0x080c,
+ 0xa03b, 0x0d48, 0x2b08, 0x6112, 0x6023, 0x0006, 0x7120, 0x610a,
+ 0x7130, 0x6156, 0x6017, 0xf300, 0x6003, 0x0001, 0x6007, 0x0041,
+ 0x080c, 0x85f8, 0x080c, 0x8b8f, 0x08b0, 0x00b6, 0x7110, 0xd1bc,
+ 0x01e8, 0x7020, 0x2060, 0x9c84, 0x0007, 0x11c0, 0x9c82, 0x1cd0,
0x02a8, 0x6864, 0x9c02, 0x1290, 0x7008, 0x9084, 0x00ff, 0x6110,
0x2158, 0xb910, 0x9106, 0x1150, 0x700c, 0xb914, 0x9106, 0x1130,
- 0x7124, 0x610a, 0x2009, 0x0046, 0x080c, 0xa053, 0x7817, 0x0140,
- 0x2001, 0x19cb, 0x2004, 0x9005, 0x090c, 0x8b90, 0x00be, 0x0005,
- 0x00b6, 0x00c6, 0x9484, 0x0fff, 0x0904, 0x7f64, 0x7110, 0xd1bc,
- 0x1904, 0x7f64, 0x7108, 0x700c, 0x2028, 0x918c, 0x00ff, 0x2130,
- 0x9094, 0xff00, 0x15b0, 0x81ff, 0x15a0, 0x9080, 0x3209, 0x200d,
- 0x918c, 0xff00, 0x810f, 0x2001, 0x0080, 0x9106, 0x0904, 0x7f64,
- 0x080c, 0x6344, 0x1904, 0x7f64, 0xbe12, 0xbd16, 0xb800, 0xd0ec,
- 0x15d8, 0xba04, 0x9294, 0xff00, 0x9286, 0x0600, 0x11a0, 0x080c,
- 0x9f7f, 0x05e8, 0x2b08, 0x7028, 0x6046, 0x702c, 0x604a, 0x6112,
- 0x6023, 0x0006, 0x7120, 0x610a, 0x7130, 0x6156, 0x2009, 0x0044,
- 0x080c, 0xcdcd, 0x0408, 0x080c, 0x66ca, 0x1138, 0xb807, 0x0606,
- 0x0c30, 0x190c, 0x7e40, 0x11c0, 0x0898, 0x080c, 0x9f7f, 0x2b08,
- 0x0198, 0x6112, 0x6023, 0x0004, 0x7120, 0x610a, 0x9286, 0x0400,
- 0x1118, 0x6007, 0x0005, 0x0010, 0x6007, 0x0001, 0x6003, 0x0001,
- 0x080c, 0x8641, 0x080c, 0x8b90, 0x7817, 0x0140, 0x2001, 0x19cb,
- 0x2004, 0x9005, 0x090c, 0x8b90, 0x00ce, 0x00be, 0x0005, 0x2001,
- 0x180e, 0x2004, 0xd0ec, 0x0120, 0x2011, 0x8049, 0x080c, 0x4a18,
- 0x080c, 0xa026, 0x0d48, 0x2b08, 0x6112, 0x6023, 0x0006, 0x7120,
- 0x610a, 0x7130, 0x6156, 0x6017, 0xf300, 0x6003, 0x0001, 0x6007,
- 0x0041, 0x080c, 0x85f9, 0x080c, 0x8b90, 0x08b0, 0x00b6, 0x7110,
- 0xd1bc, 0x01e8, 0x7020, 0x2060, 0x9c84, 0x0007, 0x11c0, 0x9c82,
- 0x1cd0, 0x02a8, 0x6864, 0x9c02, 0x1290, 0x7008, 0x9084, 0x00ff,
- 0x6110, 0x2158, 0xb910, 0x9106, 0x1150, 0x700c, 0xb914, 0x9106,
- 0x1130, 0x7124, 0x610a, 0x2009, 0x0045, 0x080c, 0xa053, 0x7817,
- 0x0140, 0x2001, 0x19cb, 0x2004, 0x9005, 0x090c, 0x8b90, 0x00be,
- 0x0005, 0x6120, 0x9186, 0x0002, 0x0128, 0x9186, 0x0005, 0x0110,
- 0x9085, 0x0001, 0x0005, 0x080c, 0x8186, 0x1180, 0x080c, 0x31ce,
- 0x1168, 0x7010, 0x9084, 0xff00, 0x8007, 0x9086, 0x0000, 0x1130,
- 0x9184, 0x000f, 0x908a, 0x0006, 0x1208, 0x000b, 0x0005, 0x7fdd,
- 0x7fde, 0x7fdd, 0x7fdd, 0x8043, 0x8052, 0x0005, 0x00b6, 0x700c,
- 0x7108, 0x080c, 0x266e, 0x1904, 0x8041, 0x080c, 0x6344, 0x1904,
- 0x8041, 0xbe12, 0xbd16, 0x7110, 0xd1bc, 0x0540, 0x702c, 0xd084,
- 0x1120, 0xb800, 0xd0bc, 0x1904, 0x8041, 0x080c, 0x66ca, 0x0148,
- 0x9086, 0x0004, 0x0130, 0x080c, 0x66d2, 0x0118, 0x9086, 0x0004,
- 0x1588, 0x00c6, 0x080c, 0x8061, 0x00ce, 0x05d8, 0x080c, 0x9f7f,
- 0x2b08, 0x05b8, 0x6112, 0x080c, 0xc1b7, 0x6023, 0x0002, 0x7120,
- 0x610a, 0x2009, 0x0088, 0x080c, 0xa053, 0x0458, 0x080c, 0x66ca,
- 0x0148, 0x9086, 0x0004, 0x0130, 0x080c, 0x66d2, 0x0118, 0x9086,
- 0x0004, 0x1180, 0x080c, 0x9f7f, 0x2b08, 0x01d8, 0x6112, 0x080c,
- 0xc1b7, 0x6023, 0x0005, 0x7120, 0x610a, 0x2009, 0x0088, 0x080c,
- 0xa053, 0x0078, 0x080c, 0x9f7f, 0x2b08, 0x0158, 0x6112, 0x080c,
- 0xc1b7, 0x6023, 0x0004, 0x7120, 0x610a, 0x2009, 0x0001, 0x080c,
- 0xa053, 0x00be, 0x0005, 0x7110, 0xd1bc, 0x0158, 0x00d1, 0x0148,
- 0x080c, 0x7fb9, 0x1130, 0x7124, 0x610a, 0x2009, 0x0089, 0x080c,
- 0xa053, 0x0005, 0x7110, 0xd1bc, 0x0158, 0x0059, 0x0148, 0x080c,
- 0x7fb9, 0x1130, 0x7124, 0x610a, 0x2009, 0x008a, 0x080c, 0xa053,
- 0x0005, 0x7020, 0x2060, 0x9c84, 0x0007, 0x1158, 0x9c82, 0x1cd0,
- 0x0240, 0x2001, 0x1819, 0x2004, 0x9c02, 0x1218, 0x9085, 0x0001,
- 0x0005, 0x9006, 0x0ce8, 0x00b6, 0x7110, 0xd1bc, 0x11d8, 0x7024,
- 0x2060, 0x9c84, 0x0007, 0x11b0, 0x9c82, 0x1cd0, 0x0298, 0x6864,
- 0x9c02, 0x1280, 0x7008, 0x9084, 0x00ff, 0x6110, 0x2158, 0xb910,
- 0x9106, 0x1140, 0x700c, 0xb914, 0x9106, 0x1120, 0x2009, 0x0051,
- 0x080c, 0xa053, 0x7817, 0x0140, 0x2001, 0x19cb, 0x2004, 0x9005,
- 0x090c, 0x8b90, 0x00be, 0x0005, 0x2031, 0x0105, 0x0069, 0x0005,
- 0x2031, 0x0206, 0x0049, 0x0005, 0x2031, 0x0207, 0x0029, 0x0005,
- 0x2031, 0x0213, 0x0009, 0x0005, 0x00c6, 0x0096, 0x00f6, 0x7000,
- 0x9084, 0xf000, 0x9086, 0xc000, 0x05d0, 0x080c, 0x9f7f, 0x05b8,
- 0x0066, 0x00c6, 0x0046, 0x2011, 0x0263, 0x2204, 0x8211, 0x220c,
- 0x080c, 0x266e, 0x15a0, 0x080c, 0x6344, 0x1588, 0xbe12, 0xbd16,
- 0x2b00, 0x004e, 0x00ce, 0x6012, 0x080c, 0xc1b7, 0x080c, 0x1043,
- 0x0510, 0x2900, 0x605a, 0x9006, 0xa802, 0xa866, 0xac6a, 0xa85c,
- 0x90f8, 0x001b, 0x20a9, 0x000e, 0xa860, 0x20e8, 0x20e1, 0x0000,
- 0x2fa0, 0x2e98, 0x4003, 0x006e, 0x6616, 0x6007, 0x003e, 0x6023,
- 0x0001, 0x6003, 0x0001, 0x080c, 0x8641, 0x080c, 0x8b90, 0x00fe,
- 0x009e, 0x00ce, 0x0005, 0x080c, 0x9fd5, 0x006e, 0x0cc0, 0x004e,
- 0x00ce, 0x0cc8, 0x00c6, 0x7000, 0x908c, 0xff00, 0x9184, 0xf000,
- 0x810f, 0x9086, 0x2000, 0x1904, 0x8151, 0x9186, 0x0022, 0x15f0,
- 0x2001, 0x0111, 0x2004, 0x9005, 0x1904, 0x8153, 0x7030, 0x908e,
- 0x0400, 0x0904, 0x8153, 0x908e, 0x6000, 0x05e8, 0x908e, 0x5400,
- 0x05d0, 0x908e, 0x0300, 0x11d8, 0x2009, 0x1836, 0x210c, 0xd18c,
- 0x1590, 0xd1a4, 0x1580, 0x080c, 0x6688, 0x0588, 0x68ac, 0x9084,
- 0x00ff, 0x7100, 0x918c, 0x00ff, 0x9106, 0x1518, 0x687c, 0x69ac,
- 0x918c, 0xff00, 0x9105, 0x7104, 0x9106, 0x11d8, 0x00e0, 0x2009,
- 0x0103, 0x210c, 0xd1b4, 0x11a8, 0x908e, 0x5200, 0x09e8, 0x908e,
- 0x0500, 0x09d0, 0x908e, 0x5000, 0x09b8, 0x0058, 0x9186, 0x0023,
- 0x1140, 0x080c, 0x8061, 0x0128, 0x6004, 0x9086, 0x0002, 0x0118,
- 0x0000, 0x9006, 0x0010, 0x9085, 0x0001, 0x00ce, 0x0005, 0x7030,
- 0x908e, 0x0300, 0x0118, 0x908e, 0x5200, 0x1d98, 0x2001, 0x1836,
- 0x2004, 0x9084, 0x0009, 0x9086, 0x0008, 0x0d68, 0x0c50, 0x00f6,
- 0x2079, 0x0200, 0x7800, 0xc0e5, 0xc0cc, 0x7802, 0x00fe, 0x0005,
- 0x00f6, 0x2079, 0x1800, 0x7834, 0xd084, 0x1130, 0x2079, 0x0200,
- 0x7800, 0x9085, 0x1200, 0x7802, 0x00fe, 0x0005, 0x00e6, 0x2071,
- 0x1800, 0x7034, 0xc084, 0x7036, 0x00ee, 0x0005, 0x0016, 0x2001,
- 0x1836, 0x200c, 0x9184, 0x0080, 0x0118, 0xd18c, 0x0118, 0x9006,
- 0x001e, 0x0005, 0x9085, 0x0001, 0x0cd8, 0x2071, 0x19d5, 0x7003,
- 0x0003, 0x700f, 0x0361, 0x9006, 0x701a, 0x707a, 0x7012, 0x7017,
- 0x1cd0, 0x7007, 0x0000, 0x7026, 0x702b, 0x961b, 0x7032, 0x7037,
- 0x9683, 0x7047, 0xffff, 0x704a, 0x704f, 0x536e, 0x7052, 0x7063,
- 0x82f5, 0x080c, 0x105c, 0x090c, 0x0e02, 0x2900, 0x7042, 0xa867,
- 0x0003, 0xa86f, 0x0100, 0xa8ab, 0xdcb0, 0x0005, 0x2071, 0x19d5,
- 0x1d04, 0x8249, 0x2091, 0x6000, 0x700c, 0x8001, 0x700e, 0x1510,
- 0x2001, 0x187d, 0x2004, 0xd0c4, 0x0158, 0x3a00, 0xd08c, 0x1140,
- 0x20d1, 0x0000, 0x20d1, 0x0001, 0x20d1, 0x0000, 0x080c, 0x0e02,
- 0x700f, 0x0361, 0x7007, 0x0001, 0x0126, 0x2091, 0x8000, 0x080c,
- 0x833a, 0x7048, 0x900d, 0x0148, 0x8109, 0x714a, 0x1130, 0x704c,
- 0x080f, 0x0018, 0x0126, 0x2091, 0x8000, 0x7024, 0x900d, 0x0188,
- 0x7020, 0x8001, 0x7022, 0x1168, 0x7023, 0x0009, 0x8109, 0x7126,
- 0x9186, 0x03e8, 0x1110, 0x7028, 0x080f, 0x81ff, 0x1110, 0x7028,
- 0x080f, 0x7030, 0x900d, 0x0180, 0x702c, 0x8001, 0x702e, 0x1160,
- 0x702f, 0x0009, 0x8109, 0x7132, 0x0128, 0x9184, 0x007f, 0x090c,
- 0x9701, 0x0010, 0x7034, 0x080f, 0x7044, 0x9005, 0x0118, 0x0310,
- 0x8001, 0x7046, 0x7054, 0x900d, 0x0168, 0x7050, 0x8001, 0x7052,
- 0x1148, 0x7053, 0x0009, 0x8109, 0x7156, 0x1120, 0x7158, 0x7156,
- 0x7060, 0x080f, 0x7018, 0x900d, 0x01d8, 0x0016, 0x7078, 0x900d,
- 0x0158, 0x7074, 0x8001, 0x7076, 0x1138, 0x7077, 0x0009, 0x8109,
- 0x717a, 0x1110, 0x707c, 0x080f, 0x001e, 0x7008, 0x8001, 0x700a,
- 0x1138, 0x700b, 0x0009, 0x8109, 0x711a, 0x1110, 0x701c, 0x080f,
- 0x012e, 0x7004, 0x0002, 0x8271, 0x8272, 0x828e, 0x00e6, 0x2071,
- 0x19d5, 0x7018, 0x9005, 0x1120, 0x711a, 0x721e, 0x700b, 0x0009,
- 0x00ee, 0x0005, 0x00e6, 0x0006, 0x2071, 0x19d5, 0x701c, 0x9206,
- 0x1120, 0x701a, 0x701e, 0x707a, 0x707e, 0x000e, 0x00ee, 0x0005,
- 0x00e6, 0x2071, 0x19d5, 0xb888, 0x9102, 0x0208, 0xb98a, 0x00ee,
- 0x0005, 0x0005, 0x00b6, 0x7110, 0x080c, 0x63a4, 0x1168, 0xb888,
- 0x8001, 0x0250, 0xb88a, 0x1140, 0x0126, 0x2091, 0x8000, 0x0016,
- 0x080c, 0x8b90, 0x001e, 0x012e, 0x8108, 0x9182, 0x0800, 0x0218,
- 0x900e, 0x7007, 0x0002, 0x7112, 0x00be, 0x0005, 0x7014, 0x2060,
- 0x0126, 0x2091, 0x8000, 0x6040, 0x9005, 0x0128, 0x8001, 0x6042,
- 0x1110, 0x080c, 0xc048, 0x6018, 0x9005, 0x0528, 0x8001, 0x601a,
- 0x1510, 0x6120, 0x9186, 0x0003, 0x0118, 0x9186, 0x0006, 0x11c8,
- 0x080c, 0xbd3b, 0x01b0, 0x6014, 0x2048, 0xa884, 0x908a, 0x199a,
- 0x0280, 0x9082, 0x1999, 0xa886, 0x908a, 0x199a, 0x0210, 0x2001,
- 0x1999, 0x8003, 0x800b, 0x810b, 0x9108, 0x611a, 0xa87c, 0xd0e4,
- 0x0110, 0x080c, 0xba41, 0x012e, 0x9c88, 0x0018, 0x7116, 0x2001,
- 0x1819, 0x2004, 0x9102, 0x0220, 0x7017, 0x1cd0, 0x7007, 0x0000,
- 0x0005, 0x00e6, 0x2071, 0x19d5, 0x7027, 0x07d0, 0x7023, 0x0009,
- 0x00ee, 0x0005, 0x2001, 0x19de, 0x2003, 0x0000, 0x0005, 0x00e6,
- 0x2071, 0x19d5, 0x7132, 0x702f, 0x0009, 0x00ee, 0x0005, 0x2011,
- 0x19e1, 0x2013, 0x0000, 0x0005, 0x00e6, 0x2071, 0x19d5, 0x711a,
- 0x721e, 0x700b, 0x0009, 0x00ee, 0x0005, 0x0086, 0x0026, 0x705c,
- 0x8000, 0x705e, 0x2001, 0x19e5, 0x2044, 0xa06c, 0x9086, 0x0000,
- 0x0150, 0x7070, 0xa09a, 0x706c, 0xa096, 0x7068, 0xa092, 0x7064,
- 0xa08e, 0x080c, 0x1140, 0x002e, 0x008e, 0x0005, 0x0006, 0x0016,
- 0x0096, 0x00a6, 0x00b6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x0156,
- 0x080c, 0x81be, 0x015e, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x00be,
- 0x00ae, 0x009e, 0x001e, 0x000e, 0x0005, 0x00e6, 0x2071, 0x19d5,
- 0x717a, 0x727e, 0x7077, 0x0009, 0x00ee, 0x0005, 0x00e6, 0x0006,
- 0x2071, 0x19d5, 0x707c, 0x9206, 0x1110, 0x707a, 0x707e, 0x000e,
- 0x00ee, 0x0005, 0x2069, 0x1800, 0x69e4, 0xd1e4, 0x1518, 0x0026,
- 0xd1ec, 0x0140, 0x6a50, 0x6870, 0x9202, 0x0288, 0x8117, 0x9294,
- 0x00c0, 0x0088, 0x9184, 0x0007, 0x01a0, 0x8109, 0x9184, 0x0007,
- 0x0110, 0x69e6, 0x0070, 0x8107, 0x9084, 0x0007, 0x910d, 0x8107,
- 0x9106, 0x9094, 0x00c0, 0x9184, 0xff3f, 0x9205, 0x68e6, 0x080c,
- 0x0f23, 0x002e, 0x0005, 0x00c6, 0x2061, 0x1a4c, 0x00ce, 0x0005,
- 0x9184, 0x000f, 0x8003, 0x8003, 0x8003, 0x9080, 0x1a4c, 0x2060,
- 0x0005, 0xa884, 0x908a, 0x199a, 0x1638, 0x9005, 0x1150, 0x00c6,
- 0x2061, 0x1a4c, 0x6014, 0x00ce, 0x9005, 0x1130, 0x2001, 0x001e,
- 0x0018, 0x908e, 0xffff, 0x01b0, 0x8003, 0x800b, 0x810b, 0x9108,
- 0x611a, 0xa87c, 0x908c, 0x00c0, 0x918e, 0x00c0, 0x0904, 0x83fb,
- 0xd0b4, 0x1168, 0xd0bc, 0x1904, 0x83d4, 0x2009, 0x0006, 0x080c,
- 0x8428, 0x0005, 0x900e, 0x0c60, 0x2001, 0x1999, 0x08b0, 0xd0fc,
- 0x0160, 0x908c, 0x0003, 0x0120, 0x918e, 0x0003, 0x1904, 0x8422,
- 0x908c, 0x2020, 0x918e, 0x2020, 0x01a8, 0x6024, 0xd0d4, 0x11e8,
- 0x2009, 0x187d, 0x2104, 0xd084, 0x1138, 0x87ff, 0x1120, 0x2009,
- 0x0043, 0x0804, 0xa053, 0x0005, 0x87ff, 0x1de8, 0x2009, 0x0042,
- 0x0804, 0xa053, 0x6110, 0x00b6, 0x2158, 0xb900, 0x00be, 0xd1ac,
- 0x0d20, 0x6024, 0xc0cd, 0x6026, 0x0c00, 0xc0d4, 0x6026, 0xa890,
- 0x602e, 0xa88c, 0x6032, 0x08e0, 0xd0fc, 0x0160, 0x908c, 0x0003,
- 0x0120, 0x918e, 0x0003, 0x1904, 0x8422, 0x908c, 0x2020, 0x918e,
- 0x2020, 0x0170, 0x0076, 0x00f6, 0x2c78, 0x080c, 0x165d, 0x00fe,
- 0x007e, 0x87ff, 0x1120, 0x2009, 0x0042, 0x080c, 0xa053, 0x0005,
- 0x6110, 0x00b6, 0x2158, 0xb900, 0x00be, 0xd1ac, 0x0d58, 0x6124,
- 0xc1cd, 0x6126, 0x0c38, 0xd0fc, 0x0188, 0x908c, 0x2020, 0x918e,
- 0x2020, 0x01a8, 0x9084, 0x0003, 0x908e, 0x0002, 0x0148, 0x87ff,
- 0x1120, 0x2009, 0x0041, 0x080c, 0xa053, 0x0005, 0x00b9, 0x0ce8,
- 0x87ff, 0x1dd8, 0x2009, 0x0043, 0x080c, 0xa053, 0x0cb0, 0x6110,
- 0x00b6, 0x2158, 0xb900, 0x00be, 0xd1ac, 0x0d20, 0x6124, 0xc1cd,
- 0x6126, 0x0c00, 0x2009, 0x0004, 0x0019, 0x0005, 0x2009, 0x0001,
- 0x0096, 0x080c, 0xbd3b, 0x0518, 0x6014, 0x2048, 0xa982, 0xa800,
- 0x6016, 0x9186, 0x0001, 0x1188, 0xa97c, 0x918c, 0x8100, 0x918e,
- 0x8100, 0x1158, 0x00c6, 0x2061, 0x1a4c, 0x6200, 0xd28c, 0x1120,
- 0x6204, 0x8210, 0x0208, 0x6206, 0x00ce, 0x080c, 0x6862, 0x6014,
- 0x904d, 0x0076, 0x2039, 0x0000, 0x190c, 0x8371, 0x007e, 0x009e,
- 0x0005, 0x0156, 0x00c6, 0x2061, 0x1a4c, 0x6000, 0x81ff, 0x0110,
- 0x9205, 0x0008, 0x9204, 0x6002, 0x00ce, 0x015e, 0x0005, 0x6800,
- 0xd08c, 0x1138, 0x6808, 0x9005, 0x0120, 0x8001, 0x680a, 0x9085,
- 0x0001, 0x0005, 0x0126, 0x2091, 0x8000, 0x0036, 0x0046, 0x20a9,
- 0x0010, 0x9006, 0x8004, 0x8086, 0x818e, 0x1208, 0x9200, 0x1f04,
- 0x8473, 0x8086, 0x818e, 0x004e, 0x003e, 0x012e, 0x0005, 0x0126,
- 0x2091, 0x8000, 0x0076, 0x0156, 0x20a9, 0x0010, 0x9005, 0x01c8,
- 0x911a, 0x12b8, 0x8213, 0x818d, 0x0228, 0x911a, 0x1220, 0x1f04,
- 0x848a, 0x0028, 0x911a, 0x2308, 0x8210, 0x1f04, 0x848a, 0x0006,
- 0x3200, 0x9084, 0xefff, 0x2080, 0x000e, 0x015e, 0x007e, 0x012e,
- 0x0005, 0x0006, 0x3200, 0x9085, 0x1000, 0x0ca8, 0x0126, 0x2091,
- 0x2800, 0x2079, 0x19c2, 0x012e, 0x00d6, 0x2069, 0x19c2, 0x6803,
- 0x0005, 0x0156, 0x0146, 0x01d6, 0x20e9, 0x0000, 0x2069, 0x0200,
- 0x080c, 0x9ddd, 0x0401, 0x080c, 0x9dc8, 0x00e9, 0x080c, 0x9dcb,
- 0x00d1, 0x080c, 0x9dce, 0x00b9, 0x080c, 0x9dd1, 0x00a1, 0x080c,
- 0x9dd4, 0x0089, 0x080c, 0x9dd7, 0x0071, 0x080c, 0x9dda, 0x0059,
- 0x01de, 0x014e, 0x015e, 0x2069, 0x0004, 0x2d04, 0x9085, 0x8001,
- 0x206a, 0x00de, 0x0005, 0x20a9, 0x0020, 0x20a1, 0x0240, 0x2001,
- 0x0000, 0x4004, 0x0005, 0x00c6, 0x6027, 0x0001, 0x7804, 0x9084,
- 0x0007, 0x0002, 0x84f4, 0x8518, 0x8559, 0x84fa, 0x8518, 0x84f4,
- 0x84f2, 0x84f2, 0x080c, 0x0e02, 0x080c, 0x82da, 0x080c, 0x8b90,
- 0x00ce, 0x0005, 0x62c0, 0x82ff, 0x1110, 0x00ce, 0x0005, 0x2011,
- 0x5c99, 0x080c, 0x825a, 0x7828, 0x9092, 0x00c8, 0x1228, 0x8000,
- 0x782a, 0x080c, 0x5cd9, 0x0c88, 0x62c0, 0x080c, 0x9de1, 0x080c,
- 0x5c99, 0x7807, 0x0003, 0x7827, 0x0000, 0x782b, 0x0000, 0x0c28,
- 0x080c, 0x82da, 0x6220, 0xd2a4, 0x0170, 0xd2cc, 0x0160, 0x782b,
- 0x0000, 0x7824, 0x9065, 0x090c, 0x0e02, 0x2009, 0x0013, 0x080c,
- 0xa053, 0x00ce, 0x0005, 0x00c6, 0x7824, 0x9065, 0x090c, 0x0e02,
- 0x7828, 0x9092, 0xc350, 0x12c0, 0x8000, 0x782a, 0x00ce, 0x080c,
- 0x29fe, 0x0278, 0x00c6, 0x7924, 0x2160, 0x6010, 0x906d, 0x090c,
- 0x0e02, 0x7807, 0x0000, 0x7827, 0x0000, 0x00ce, 0x080c, 0x8b90,
- 0x0c00, 0x080c, 0x95e1, 0x08e8, 0x2011, 0x0130, 0x2214, 0x080c,
- 0x9de1, 0x080c, 0xdb8f, 0x2009, 0x0014, 0x080c, 0xa053, 0x00ce,
- 0x0880, 0x2001, 0x19de, 0x2003, 0x0000, 0x62c0, 0x82ff, 0x1160,
- 0x782b, 0x0000, 0x7824, 0x9065, 0x090c, 0x0e02, 0x2009, 0x0013,
- 0x080c, 0xa0a5, 0x00ce, 0x0005, 0x00b6, 0x00c6, 0x00d6, 0x7824,
- 0x9005, 0x090c, 0x0e02, 0x7828, 0x9092, 0xc350, 0x1648, 0x8000,
- 0x782a, 0x00de, 0x00ce, 0x00be, 0x080c, 0x29fe, 0x02f0, 0x00b6,
- 0x00c6, 0x00d6, 0x781c, 0x905d, 0x090c, 0x0e02, 0xb800, 0xc0dc,
- 0xb802, 0x7924, 0x2160, 0x080c, 0x9fd5, 0xb93c, 0x81ff, 0x090c,
- 0x0e02, 0x8109, 0xb93e, 0x7807, 0x0000, 0x7827, 0x0000, 0x00de,
- 0x00ce, 0x00be, 0x080c, 0x8b90, 0x0868, 0x080c, 0x95e1, 0x0850,
- 0x2011, 0x0130, 0x2214, 0x080c, 0x9de1, 0x080c, 0xdb8f, 0x7824,
- 0x9065, 0x2009, 0x0014, 0x080c, 0xa053, 0x00de, 0x00ce, 0x00be,
- 0x0804, 0x856a, 0x00c6, 0x2001, 0x009b, 0x2004, 0xd0fc, 0x190c,
- 0x1d04, 0x6024, 0x6027, 0x0002, 0xd0f4, 0x1580, 0x62c8, 0x60c4,
- 0x9205, 0x1170, 0x783c, 0x9065, 0x0130, 0x2009, 0x0049, 0x080c,
- 0xa053, 0x00ce, 0x0005, 0x2011, 0x19e1, 0x2013, 0x0000, 0x0cc8,
- 0x793c, 0x81ff, 0x0dc0, 0x7944, 0x9192, 0x7530, 0x12f0, 0x8108,
- 0x7946, 0x793c, 0x9188, 0x0008, 0x210c, 0x918e, 0x0006, 0x1138,
- 0x6014, 0x9084, 0x1984, 0x9085, 0x0012, 0x6016, 0x0c10, 0x6014,
- 0x9084, 0x1984, 0x9085, 0x0016, 0x6016, 0x08d8, 0x793c, 0x2160,
- 0x2009, 0x004a, 0x080c, 0xa053, 0x08a0, 0x7848, 0xc085, 0x784a,
- 0x0880, 0x0006, 0x0016, 0x00c6, 0x0126, 0x2091, 0x8000, 0x600f,
- 0x0000, 0x2c08, 0x2061, 0x19c2, 0x6020, 0x8000, 0x6022, 0x6010,
- 0x9005, 0x0148, 0x9080, 0x0003, 0x2102, 0x6112, 0x012e, 0x00ce,
- 0x001e, 0x000e, 0x0005, 0x6116, 0x6112, 0x0cc0, 0x00d6, 0x2069,
- 0x19c2, 0xb800, 0xd0d4, 0x0168, 0x6820, 0x8000, 0x6822, 0x9086,
- 0x0001, 0x1110, 0x2b00, 0x681e, 0x00de, 0x0804, 0x8b90, 0x00de,
- 0x0005, 0xc0d5, 0xb802, 0x6818, 0x9005, 0x0168, 0xb856, 0xb85b,
- 0x0000, 0x0086, 0x0006, 0x2b00, 0x681a, 0x008e, 0xa05a, 0x008e,
- 0x2069, 0x19c2, 0x0c08, 0xb856, 0xb85a, 0x2b00, 0x681a, 0x681e,
- 0x08d8, 0x0006, 0x0016, 0x00c6, 0x0126, 0x2091, 0x8000, 0x600f,
- 0x0000, 0x2c08, 0x2061, 0x19c2, 0x6020, 0x8000, 0x6022, 0x6008,
- 0x9005, 0x0148, 0x9080, 0x0003, 0x2102, 0x610a, 0x012e, 0x00ce,
- 0x001e, 0x000e, 0x0005, 0x610e, 0x610a, 0x0cc0, 0x00c6, 0x600f,
- 0x0000, 0x2c08, 0x2061, 0x19c2, 0x6034, 0x9005, 0x0130, 0x9080,
- 0x0003, 0x2102, 0x6136, 0x00ce, 0x0005, 0x613a, 0x6136, 0x00ce,
- 0x0005, 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x00b6, 0x0096, 0x0076,
- 0x0066, 0x0056, 0x0036, 0x0026, 0x0016, 0x0006, 0x0126, 0x902e,
- 0x2071, 0x19c2, 0x7638, 0x2660, 0x2678, 0x2091, 0x8000, 0x8cff,
- 0x0904, 0x86ed, 0x6010, 0x2058, 0xb8a0, 0x9206, 0x1904, 0x86e8,
- 0x87ff, 0x0120, 0x6054, 0x9106, 0x1904, 0x86e8, 0x703c, 0x9c06,
- 0x1178, 0x0036, 0x2019, 0x0001, 0x080c, 0x989c, 0x7033, 0x0000,
- 0x9006, 0x703e, 0x7042, 0x7046, 0x704a, 0x003e, 0x2029, 0x0001,
- 0x7038, 0x9c36, 0x1110, 0x660c, 0x763a, 0x7034, 0x9c36, 0x1140,
- 0x2c00, 0x9f36, 0x0118, 0x2f00, 0x7036, 0x0010, 0x7037, 0x0000,
- 0x660c, 0x0066, 0x2c00, 0x9f06, 0x0110, 0x7e0e, 0x0008, 0x2678,
- 0x600f, 0x0000, 0x080c, 0xbd3b, 0x01f0, 0x6014, 0x2048, 0x6020,
- 0x9086, 0x0003, 0x15b8, 0x6004, 0x9086, 0x0040, 0x090c, 0x9a6a,
- 0xa867, 0x0103, 0xab7a, 0xa877, 0x0000, 0x0016, 0x0036, 0x0076,
- 0x080c, 0xc031, 0x080c, 0xda80, 0x080c, 0x6a23, 0x007e, 0x003e,
- 0x001e, 0x080c, 0xbf26, 0x080c, 0xa007, 0x00ce, 0x0804, 0x8687,
- 0x2c78, 0x600c, 0x2060, 0x0804, 0x8687, 0x85ff, 0x0120, 0x0036,
- 0x080c, 0x8c6d, 0x003e, 0x012e, 0x000e, 0x001e, 0x002e, 0x003e,
- 0x005e, 0x006e, 0x007e, 0x009e, 0x00be, 0x00ce, 0x00de, 0x00ee,
- 0x00fe, 0x0005, 0x6020, 0x9086, 0x0006, 0x1158, 0x0016, 0x0036,
- 0x0076, 0x080c, 0xda80, 0x080c, 0xd781, 0x007e, 0x003e, 0x001e,
- 0x0890, 0x6020, 0x9086, 0x000a, 0x0904, 0x86d2, 0x0804, 0x86cb,
- 0x0006, 0x0066, 0x0096, 0x00c6, 0x00d6, 0x00f6, 0x9036, 0x0126,
- 0x2091, 0x8000, 0x2079, 0x19c2, 0x7838, 0x9065, 0x0904, 0x876d,
- 0x600c, 0x0006, 0x600f, 0x0000, 0x783c, 0x9c06, 0x1168, 0x0036,
- 0x2019, 0x0001, 0x080c, 0x989c, 0x7833, 0x0000, 0x901e, 0x7b3e,
- 0x7b42, 0x7b46, 0x7b4a, 0x003e, 0x080c, 0xbd3b, 0x0548, 0x6014,
- 0x2048, 0x6020, 0x9086, 0x0003, 0x1590, 0x3e08, 0x918e, 0x0002,
- 0x1188, 0x6010, 0x9005, 0x0170, 0x00b6, 0x2058, 0xb800, 0x00be,
- 0xd0bc, 0x0140, 0x6040, 0x9005, 0x11a8, 0x2001, 0x1962, 0x2004,
- 0x6042, 0x0080, 0x6004, 0x9086, 0x0040, 0x090c, 0x9a6a, 0xa867,
- 0x0103, 0xab7a, 0xa877, 0x0000, 0x080c, 0x6a16, 0x080c, 0xbf26,
- 0x080c, 0xa007, 0x000e, 0x0804, 0x8725, 0x7e3a, 0x7e36, 0x012e,
- 0x00fe, 0x00de, 0x00ce, 0x009e, 0x006e, 0x000e, 0x0005, 0x6020,
- 0x9086, 0x0006, 0x1118, 0x080c, 0xd781, 0x0c50, 0x6020, 0x9086,
- 0x000a, 0x09f8, 0x08b8, 0x0016, 0x0026, 0x0086, 0x9046, 0x0099,
- 0x080c, 0x886e, 0x008e, 0x002e, 0x001e, 0x0005, 0x00f6, 0x0126,
- 0x2079, 0x19c2, 0x2091, 0x8000, 0x080c, 0x8905, 0x080c, 0x8995,
- 0x012e, 0x00fe, 0x0005, 0x00b6, 0x0096, 0x00f6, 0x00e6, 0x00d6,
- 0x00c6, 0x0066, 0x0016, 0x0006, 0x0126, 0x2091, 0x8000, 0x2071,
- 0x19c2, 0x7614, 0x2660, 0x2678, 0x8cff, 0x0904, 0x8833, 0x6010,
- 0x2058, 0xb8a0, 0x9206, 0x1904, 0x882e, 0x88ff, 0x0120, 0x6054,
- 0x9106, 0x1904, 0x882e, 0x7024, 0x9c06, 0x1568, 0x2069, 0x0100,
- 0x6820, 0xd0a4, 0x0110, 0xd0cc, 0x1508, 0x080c, 0x82da, 0x080c,
- 0x9605, 0x68c3, 0x0000, 0x080c, 0x9a6a, 0x7027, 0x0000, 0x0036,
- 0x2069, 0x0140, 0x6b04, 0x9384, 0x1000, 0x0138, 0x2001, 0x0100,
- 0x080c, 0x2b88, 0x9006, 0x080c, 0x2b88, 0x2069, 0x0100, 0x6824,
- 0xd084, 0x0110, 0x6827, 0x0001, 0x003e, 0x0028, 0x6003, 0x0009,
- 0x630a, 0x0804, 0x882e, 0x7014, 0x9c36, 0x1110, 0x660c, 0x7616,
- 0x7010, 0x9c36, 0x1140, 0x2c00, 0x9f36, 0x0118, 0x2f00, 0x7012,
- 0x0010, 0x7013, 0x0000, 0x660c, 0x0066, 0x2c00, 0x9f06, 0x0110,
- 0x7e0e, 0x0008, 0x2678, 0x600f, 0x0000, 0x6014, 0x2048, 0x080c,
- 0xbd3b, 0x01e8, 0x6020, 0x9086, 0x0003, 0x1580, 0x080c, 0xbf43,
- 0x1118, 0x080c, 0xa995, 0x0098, 0xa867, 0x0103, 0xab7a, 0xa877,
- 0x0000, 0x0016, 0x0036, 0x0086, 0x080c, 0xc031, 0x080c, 0xda80,
- 0x080c, 0x6a23, 0x008e, 0x003e, 0x001e, 0x080c, 0xbf26, 0x080c,
- 0xa007, 0x080c, 0x9940, 0x00ce, 0x0804, 0x87ac, 0x2c78, 0x600c,
- 0x2060, 0x0804, 0x87ac, 0x012e, 0x000e, 0x001e, 0x006e, 0x00ce,
- 0x00de, 0x00ee, 0x00fe, 0x009e, 0x00be, 0x0005, 0x6020, 0x9086,
- 0x0006, 0x1158, 0x0016, 0x0036, 0x0086, 0x080c, 0xda80, 0x080c,
- 0xd781, 0x008e, 0x003e, 0x001e, 0x08d0, 0x080c, 0xa995, 0x6020,
- 0x9086, 0x0002, 0x1160, 0x6004, 0x0006, 0x9086, 0x0085, 0x000e,
- 0x0904, 0x8814, 0x9086, 0x008b, 0x0904, 0x8814, 0x0840, 0x6020,
- 0x9086, 0x0005, 0x1920, 0x6004, 0x0006, 0x9086, 0x0085, 0x000e,
- 0x09c8, 0x9086, 0x008b, 0x09b0, 0x0804, 0x8827, 0x00b6, 0x00a6,
- 0x0096, 0x00c6, 0x0006, 0x0126, 0x2091, 0x8000, 0x9280, 0x1000,
- 0x2004, 0x905d, 0x0904, 0x88fe, 0x00f6, 0x00e6, 0x00d6, 0x0066,
- 0x2071, 0x19c2, 0xbe54, 0x7018, 0x9b06, 0x1108, 0x761a, 0x701c,
- 0x9b06, 0x1130, 0x86ff, 0x1118, 0x7018, 0x701e, 0x0008, 0x761e,
- 0xb858, 0x904d, 0x0108, 0xae56, 0x96d5, 0x0000, 0x0110, 0x2900,
- 0xb05a, 0xb857, 0x0000, 0xb85b, 0x0000, 0xb800, 0xc0d4, 0xc0dc,
- 0xb802, 0x080c, 0x62d7, 0x0904, 0x88fa, 0x7624, 0x86ff, 0x0904,
- 0x88e9, 0x9680, 0x0005, 0x2004, 0x9906, 0x15d8, 0x00d6, 0x2069,
- 0x0100, 0x68c0, 0x9005, 0x0560, 0x080c, 0x82da, 0x080c, 0x9605,
- 0x68c3, 0x0000, 0x080c, 0x9a6a, 0x7027, 0x0000, 0x0036, 0x2069,
+ 0x7124, 0x610a, 0x2009, 0x0045, 0x080c, 0xa068, 0x7817, 0x0140,
+ 0x2001, 0x19cb, 0x2004, 0x9005, 0x090c, 0x8b8f, 0x00be, 0x0005,
+ 0x6120, 0x9186, 0x0002, 0x0128, 0x9186, 0x0005, 0x0110, 0x9085,
+ 0x0001, 0x0005, 0x080c, 0x8185, 0x1180, 0x080c, 0x31b8, 0x1168,
+ 0x7010, 0x9084, 0xff00, 0x8007, 0x9086, 0x0000, 0x1130, 0x9184,
+ 0x000f, 0x908a, 0x0006, 0x1208, 0x000b, 0x0005, 0x7fdc, 0x7fdd,
+ 0x7fdc, 0x7fdc, 0x8042, 0x8051, 0x0005, 0x00b6, 0x700c, 0x7108,
+ 0x080c, 0x266d, 0x1904, 0x8040, 0x080c, 0x6343, 0x1904, 0x8040,
+ 0xbe12, 0xbd16, 0x7110, 0xd1bc, 0x0540, 0x702c, 0xd084, 0x1120,
+ 0xb800, 0xd0bc, 0x1904, 0x8040, 0x080c, 0x66c9, 0x0148, 0x9086,
+ 0x0004, 0x0130, 0x080c, 0x66d1, 0x0118, 0x9086, 0x0004, 0x1588,
+ 0x00c6, 0x080c, 0x8060, 0x00ce, 0x05d8, 0x080c, 0x9f94, 0x2b08,
+ 0x05b8, 0x6112, 0x080c, 0xc1ca, 0x6023, 0x0002, 0x7120, 0x610a,
+ 0x2009, 0x0088, 0x080c, 0xa068, 0x0458, 0x080c, 0x66c9, 0x0148,
+ 0x9086, 0x0004, 0x0130, 0x080c, 0x66d1, 0x0118, 0x9086, 0x0004,
+ 0x1180, 0x080c, 0x9f94, 0x2b08, 0x01d8, 0x6112, 0x080c, 0xc1ca,
+ 0x6023, 0x0005, 0x7120, 0x610a, 0x2009, 0x0088, 0x080c, 0xa068,
+ 0x0078, 0x080c, 0x9f94, 0x2b08, 0x0158, 0x6112, 0x080c, 0xc1ca,
+ 0x6023, 0x0004, 0x7120, 0x610a, 0x2009, 0x0001, 0x080c, 0xa068,
+ 0x00be, 0x0005, 0x7110, 0xd1bc, 0x0158, 0x00d1, 0x0148, 0x080c,
+ 0x7fb8, 0x1130, 0x7124, 0x610a, 0x2009, 0x0089, 0x080c, 0xa068,
+ 0x0005, 0x7110, 0xd1bc, 0x0158, 0x0059, 0x0148, 0x080c, 0x7fb8,
+ 0x1130, 0x7124, 0x610a, 0x2009, 0x008a, 0x080c, 0xa068, 0x0005,
+ 0x7020, 0x2060, 0x9c84, 0x0007, 0x1158, 0x9c82, 0x1cd0, 0x0240,
+ 0x2001, 0x1819, 0x2004, 0x9c02, 0x1218, 0x9085, 0x0001, 0x0005,
+ 0x9006, 0x0ce8, 0x00b6, 0x7110, 0xd1bc, 0x11d8, 0x7024, 0x2060,
+ 0x9c84, 0x0007, 0x11b0, 0x9c82, 0x1cd0, 0x0298, 0x6864, 0x9c02,
+ 0x1280, 0x7008, 0x9084, 0x00ff, 0x6110, 0x2158, 0xb910, 0x9106,
+ 0x1140, 0x700c, 0xb914, 0x9106, 0x1120, 0x2009, 0x0051, 0x080c,
+ 0xa068, 0x7817, 0x0140, 0x2001, 0x19cb, 0x2004, 0x9005, 0x090c,
+ 0x8b8f, 0x00be, 0x0005, 0x2031, 0x0105, 0x0069, 0x0005, 0x2031,
+ 0x0206, 0x0049, 0x0005, 0x2031, 0x0207, 0x0029, 0x0005, 0x2031,
+ 0x0213, 0x0009, 0x0005, 0x00c6, 0x0096, 0x00f6, 0x7000, 0x9084,
+ 0xf000, 0x9086, 0xc000, 0x05d0, 0x080c, 0x9f94, 0x05b8, 0x0066,
+ 0x00c6, 0x0046, 0x2011, 0x0263, 0x2204, 0x8211, 0x220c, 0x080c,
+ 0x266d, 0x15a0, 0x080c, 0x6343, 0x1588, 0xbe12, 0xbd16, 0x2b00,
+ 0x004e, 0x00ce, 0x6012, 0x080c, 0xc1ca, 0x080c, 0x1037, 0x0510,
+ 0x2900, 0x605a, 0x9006, 0xa802, 0xa866, 0xac6a, 0xa85c, 0x90f8,
+ 0x001b, 0x20a9, 0x000e, 0xa860, 0x20e8, 0x20e1, 0x0000, 0x2fa0,
+ 0x2e98, 0x4003, 0x006e, 0x6616, 0x6007, 0x003e, 0x6023, 0x0001,
+ 0x6003, 0x0001, 0x080c, 0x8640, 0x080c, 0x8b8f, 0x00fe, 0x009e,
+ 0x00ce, 0x0005, 0x080c, 0x9fea, 0x006e, 0x0cc0, 0x004e, 0x00ce,
+ 0x0cc8, 0x00c6, 0x7000, 0x908c, 0xff00, 0x9184, 0xf000, 0x810f,
+ 0x9086, 0x2000, 0x1904, 0x8150, 0x9186, 0x0022, 0x15f0, 0x2001,
+ 0x0111, 0x2004, 0x9005, 0x1904, 0x8152, 0x7030, 0x908e, 0x0400,
+ 0x0904, 0x8152, 0x908e, 0x6000, 0x05e8, 0x908e, 0x5400, 0x05d0,
+ 0x908e, 0x0300, 0x11d8, 0x2009, 0x1836, 0x210c, 0xd18c, 0x1590,
+ 0xd1a4, 0x1580, 0x080c, 0x6687, 0x0588, 0x68ac, 0x9084, 0x00ff,
+ 0x7100, 0x918c, 0x00ff, 0x9106, 0x1518, 0x687c, 0x69ac, 0x918c,
+ 0xff00, 0x9105, 0x7104, 0x9106, 0x11d8, 0x00e0, 0x2009, 0x0103,
+ 0x210c, 0xd1b4, 0x11a8, 0x908e, 0x5200, 0x09e8, 0x908e, 0x0500,
+ 0x09d0, 0x908e, 0x5000, 0x09b8, 0x0058, 0x9186, 0x0023, 0x1140,
+ 0x080c, 0x8060, 0x0128, 0x6004, 0x9086, 0x0002, 0x0118, 0x0000,
+ 0x9006, 0x0010, 0x9085, 0x0001, 0x00ce, 0x0005, 0x7030, 0x908e,
+ 0x0300, 0x0118, 0x908e, 0x5200, 0x1d98, 0x2001, 0x1836, 0x2004,
+ 0x9084, 0x0009, 0x9086, 0x0008, 0x0d68, 0x0c50, 0x00f6, 0x2079,
+ 0x0200, 0x7800, 0xc0e5, 0xc0cc, 0x7802, 0x00fe, 0x0005, 0x00f6,
+ 0x2079, 0x1800, 0x7834, 0xd084, 0x1130, 0x2079, 0x0200, 0x7800,
+ 0x9085, 0x1200, 0x7802, 0x00fe, 0x0005, 0x00e6, 0x2071, 0x1800,
+ 0x7034, 0xc084, 0x7036, 0x00ee, 0x0005, 0x0016, 0x2001, 0x1836,
+ 0x200c, 0x9184, 0x0080, 0x0118, 0xd18c, 0x0118, 0x9006, 0x001e,
+ 0x0005, 0x9085, 0x0001, 0x0cd8, 0x2071, 0x19d5, 0x7003, 0x0003,
+ 0x700f, 0x0361, 0x9006, 0x701a, 0x707a, 0x7012, 0x7017, 0x1cd0,
+ 0x7007, 0x0000, 0x7026, 0x702b, 0x9630, 0x7032, 0x7037, 0x9698,
+ 0x7047, 0xffff, 0x704a, 0x704f, 0x536d, 0x7052, 0x7063, 0x82f4,
+ 0x080c, 0x1050, 0x090c, 0x0df6, 0x2900, 0x7042, 0xa867, 0x0003,
+ 0xa86f, 0x0100, 0xa8ab, 0xdcb0, 0x0005, 0x2071, 0x19d5, 0x1d04,
+ 0x8248, 0x2091, 0x6000, 0x700c, 0x8001, 0x700e, 0x1510, 0x2001,
+ 0x187d, 0x2004, 0xd0c4, 0x0158, 0x3a00, 0xd08c, 0x1140, 0x20d1,
+ 0x0000, 0x20d1, 0x0001, 0x20d1, 0x0000, 0x080c, 0x0df6, 0x700f,
+ 0x0361, 0x7007, 0x0001, 0x0126, 0x2091, 0x8000, 0x080c, 0x8339,
+ 0x7048, 0x900d, 0x0148, 0x8109, 0x714a, 0x1130, 0x704c, 0x080f,
+ 0x0018, 0x0126, 0x2091, 0x8000, 0x7024, 0x900d, 0x0188, 0x7020,
+ 0x8001, 0x7022, 0x1168, 0x7023, 0x0009, 0x8109, 0x7126, 0x9186,
+ 0x03e8, 0x1110, 0x7028, 0x080f, 0x81ff, 0x1110, 0x7028, 0x080f,
+ 0x7030, 0x900d, 0x0180, 0x702c, 0x8001, 0x702e, 0x1160, 0x702f,
+ 0x0009, 0x8109, 0x7132, 0x0128, 0x9184, 0x007f, 0x090c, 0x9716,
+ 0x0010, 0x7034, 0x080f, 0x7044, 0x9005, 0x0118, 0x0310, 0x8001,
+ 0x7046, 0x7054, 0x900d, 0x0168, 0x7050, 0x8001, 0x7052, 0x1148,
+ 0x7053, 0x0009, 0x8109, 0x7156, 0x1120, 0x7158, 0x7156, 0x7060,
+ 0x080f, 0x7018, 0x900d, 0x01d8, 0x0016, 0x7078, 0x900d, 0x0158,
+ 0x7074, 0x8001, 0x7076, 0x1138, 0x7077, 0x0009, 0x8109, 0x717a,
+ 0x1110, 0x707c, 0x080f, 0x001e, 0x7008, 0x8001, 0x700a, 0x1138,
+ 0x700b, 0x0009, 0x8109, 0x711a, 0x1110, 0x701c, 0x080f, 0x012e,
+ 0x7004, 0x0002, 0x8270, 0x8271, 0x828d, 0x00e6, 0x2071, 0x19d5,
+ 0x7018, 0x9005, 0x1120, 0x711a, 0x721e, 0x700b, 0x0009, 0x00ee,
+ 0x0005, 0x00e6, 0x0006, 0x2071, 0x19d5, 0x701c, 0x9206, 0x1120,
+ 0x701a, 0x701e, 0x707a, 0x707e, 0x000e, 0x00ee, 0x0005, 0x00e6,
+ 0x2071, 0x19d5, 0xb888, 0x9102, 0x0208, 0xb98a, 0x00ee, 0x0005,
+ 0x0005, 0x00b6, 0x7110, 0x080c, 0x63a3, 0x1168, 0xb888, 0x8001,
+ 0x0250, 0xb88a, 0x1140, 0x0126, 0x2091, 0x8000, 0x0016, 0x080c,
+ 0x8b8f, 0x001e, 0x012e, 0x8108, 0x9182, 0x0800, 0x0218, 0x900e,
+ 0x7007, 0x0002, 0x7112, 0x00be, 0x0005, 0x7014, 0x2060, 0x0126,
+ 0x2091, 0x8000, 0x6040, 0x9005, 0x0128, 0x8001, 0x6042, 0x1110,
+ 0x080c, 0xc05b, 0x6018, 0x9005, 0x0528, 0x8001, 0x601a, 0x1510,
+ 0x6120, 0x9186, 0x0003, 0x0118, 0x9186, 0x0006, 0x11c8, 0x080c,
+ 0xbd4e, 0x01b0, 0x6014, 0x2048, 0xa884, 0x908a, 0x199a, 0x0280,
+ 0x9082, 0x1999, 0xa886, 0x908a, 0x199a, 0x0210, 0x2001, 0x1999,
+ 0x8003, 0x800b, 0x810b, 0x9108, 0x611a, 0xa87c, 0xd0e4, 0x0110,
+ 0x080c, 0xba50, 0x012e, 0x9c88, 0x0018, 0x7116, 0x2001, 0x1819,
+ 0x2004, 0x9102, 0x0220, 0x7017, 0x1cd0, 0x7007, 0x0000, 0x0005,
+ 0x00e6, 0x2071, 0x19d5, 0x7027, 0x07d0, 0x7023, 0x0009, 0x00ee,
+ 0x0005, 0x2001, 0x19de, 0x2003, 0x0000, 0x0005, 0x00e6, 0x2071,
+ 0x19d5, 0x7132, 0x702f, 0x0009, 0x00ee, 0x0005, 0x2011, 0x19e1,
+ 0x2013, 0x0000, 0x0005, 0x00e6, 0x2071, 0x19d5, 0x711a, 0x721e,
+ 0x700b, 0x0009, 0x00ee, 0x0005, 0x0086, 0x0026, 0x705c, 0x8000,
+ 0x705e, 0x2001, 0x19e5, 0x2044, 0xa06c, 0x9086, 0x0000, 0x0150,
+ 0x7070, 0xa09a, 0x706c, 0xa096, 0x7068, 0xa092, 0x7064, 0xa08e,
+ 0x080c, 0x1134, 0x002e, 0x008e, 0x0005, 0x0006, 0x0016, 0x0096,
+ 0x00a6, 0x00b6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x0156, 0x080c,
+ 0x81bd, 0x015e, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x00be, 0x00ae,
+ 0x009e, 0x001e, 0x000e, 0x0005, 0x00e6, 0x2071, 0x19d5, 0x717a,
+ 0x727e, 0x7077, 0x0009, 0x00ee, 0x0005, 0x00e6, 0x0006, 0x2071,
+ 0x19d5, 0x707c, 0x9206, 0x1110, 0x707a, 0x707e, 0x000e, 0x00ee,
+ 0x0005, 0x2069, 0x1800, 0x69e4, 0xd1e4, 0x1518, 0x0026, 0xd1ec,
+ 0x0140, 0x6a50, 0x6870, 0x9202, 0x0288, 0x8117, 0x9294, 0x00c0,
+ 0x0088, 0x9184, 0x0007, 0x01a0, 0x8109, 0x9184, 0x0007, 0x0110,
+ 0x69e6, 0x0070, 0x8107, 0x9084, 0x0007, 0x910d, 0x8107, 0x9106,
+ 0x9094, 0x00c0, 0x9184, 0xff3f, 0x9205, 0x68e6, 0x080c, 0x0f17,
+ 0x002e, 0x0005, 0x00c6, 0x2061, 0x1a4c, 0x00ce, 0x0005, 0x9184,
+ 0x000f, 0x8003, 0x8003, 0x8003, 0x9080, 0x1a4c, 0x2060, 0x0005,
+ 0xa884, 0x908a, 0x199a, 0x1638, 0x9005, 0x1150, 0x00c6, 0x2061,
+ 0x1a4c, 0x6014, 0x00ce, 0x9005, 0x1130, 0x2001, 0x001e, 0x0018,
+ 0x908e, 0xffff, 0x01b0, 0x8003, 0x800b, 0x810b, 0x9108, 0x611a,
+ 0xa87c, 0x908c, 0x00c0, 0x918e, 0x00c0, 0x0904, 0x83fa, 0xd0b4,
+ 0x1168, 0xd0bc, 0x1904, 0x83d3, 0x2009, 0x0006, 0x080c, 0x8427,
+ 0x0005, 0x900e, 0x0c60, 0x2001, 0x1999, 0x08b0, 0xd0fc, 0x0160,
+ 0x908c, 0x0003, 0x0120, 0x918e, 0x0003, 0x1904, 0x8421, 0x908c,
+ 0x2020, 0x918e, 0x2020, 0x01a8, 0x6024, 0xd0d4, 0x11e8, 0x2009,
+ 0x187d, 0x2104, 0xd084, 0x1138, 0x87ff, 0x1120, 0x2009, 0x0043,
+ 0x0804, 0xa068, 0x0005, 0x87ff, 0x1de8, 0x2009, 0x0042, 0x0804,
+ 0xa068, 0x6110, 0x00b6, 0x2158, 0xb900, 0x00be, 0xd1ac, 0x0d20,
+ 0x6024, 0xc0cd, 0x6026, 0x0c00, 0xc0d4, 0x6026, 0xa890, 0x602e,
+ 0xa88c, 0x6032, 0x08e0, 0xd0fc, 0x0160, 0x908c, 0x0003, 0x0120,
+ 0x918e, 0x0003, 0x1904, 0x8421, 0x908c, 0x2020, 0x918e, 0x2020,
+ 0x0170, 0x0076, 0x00f6, 0x2c78, 0x080c, 0x1651, 0x00fe, 0x007e,
+ 0x87ff, 0x1120, 0x2009, 0x0042, 0x080c, 0xa068, 0x0005, 0x6110,
+ 0x00b6, 0x2158, 0xb900, 0x00be, 0xd1ac, 0x0d58, 0x6124, 0xc1cd,
+ 0x6126, 0x0c38, 0xd0fc, 0x0188, 0x908c, 0x2020, 0x918e, 0x2020,
+ 0x01a8, 0x9084, 0x0003, 0x908e, 0x0002, 0x0148, 0x87ff, 0x1120,
+ 0x2009, 0x0041, 0x080c, 0xa068, 0x0005, 0x00b9, 0x0ce8, 0x87ff,
+ 0x1dd8, 0x2009, 0x0043, 0x080c, 0xa068, 0x0cb0, 0x6110, 0x00b6,
+ 0x2158, 0xb900, 0x00be, 0xd1ac, 0x0d20, 0x6124, 0xc1cd, 0x6126,
+ 0x0c00, 0x2009, 0x0004, 0x0019, 0x0005, 0x2009, 0x0001, 0x0096,
+ 0x080c, 0xbd4e, 0x0518, 0x6014, 0x2048, 0xa982, 0xa800, 0x6016,
+ 0x9186, 0x0001, 0x1188, 0xa97c, 0x918c, 0x8100, 0x918e, 0x8100,
+ 0x1158, 0x00c6, 0x2061, 0x1a4c, 0x6200, 0xd28c, 0x1120, 0x6204,
+ 0x8210, 0x0208, 0x6206, 0x00ce, 0x080c, 0x6861, 0x6014, 0x904d,
+ 0x0076, 0x2039, 0x0000, 0x190c, 0x8370, 0x007e, 0x009e, 0x0005,
+ 0x0156, 0x00c6, 0x2061, 0x1a4c, 0x6000, 0x81ff, 0x0110, 0x9205,
+ 0x0008, 0x9204, 0x6002, 0x00ce, 0x015e, 0x0005, 0x6800, 0xd08c,
+ 0x1138, 0x6808, 0x9005, 0x0120, 0x8001, 0x680a, 0x9085, 0x0001,
+ 0x0005, 0x0126, 0x2091, 0x8000, 0x0036, 0x0046, 0x20a9, 0x0010,
+ 0x9006, 0x8004, 0x8086, 0x818e, 0x1208, 0x9200, 0x1f04, 0x8472,
+ 0x8086, 0x818e, 0x004e, 0x003e, 0x012e, 0x0005, 0x0126, 0x2091,
+ 0x8000, 0x0076, 0x0156, 0x20a9, 0x0010, 0x9005, 0x01c8, 0x911a,
+ 0x12b8, 0x8213, 0x818d, 0x0228, 0x911a, 0x1220, 0x1f04, 0x8489,
+ 0x0028, 0x911a, 0x2308, 0x8210, 0x1f04, 0x8489, 0x0006, 0x3200,
+ 0x9084, 0xefff, 0x2080, 0x000e, 0x015e, 0x007e, 0x012e, 0x0005,
+ 0x0006, 0x3200, 0x9085, 0x1000, 0x0ca8, 0x0126, 0x2091, 0x2800,
+ 0x2079, 0x19c2, 0x012e, 0x00d6, 0x2069, 0x19c2, 0x6803, 0x0005,
+ 0x0156, 0x0146, 0x01d6, 0x20e9, 0x0000, 0x2069, 0x0200, 0x080c,
+ 0x9df2, 0x0401, 0x080c, 0x9ddd, 0x00e9, 0x080c, 0x9de0, 0x00d1,
+ 0x080c, 0x9de3, 0x00b9, 0x080c, 0x9de6, 0x00a1, 0x080c, 0x9de9,
+ 0x0089, 0x080c, 0x9dec, 0x0071, 0x080c, 0x9def, 0x0059, 0x01de,
+ 0x014e, 0x015e, 0x2069, 0x0004, 0x2d04, 0x9085, 0x8001, 0x206a,
+ 0x00de, 0x0005, 0x20a9, 0x0020, 0x20a1, 0x0240, 0x2001, 0x0000,
+ 0x4004, 0x0005, 0x00c6, 0x6027, 0x0001, 0x7804, 0x9084, 0x0007,
+ 0x0002, 0x84f3, 0x8517, 0x8558, 0x84f9, 0x8517, 0x84f3, 0x84f1,
+ 0x84f1, 0x080c, 0x0df6, 0x080c, 0x82d9, 0x080c, 0x8b8f, 0x00ce,
+ 0x0005, 0x62c0, 0x82ff, 0x1110, 0x00ce, 0x0005, 0x2011, 0x5c98,
+ 0x080c, 0x8259, 0x7828, 0x9092, 0x00c8, 0x1228, 0x8000, 0x782a,
+ 0x080c, 0x5cd8, 0x0c88, 0x62c0, 0x080c, 0x9df6, 0x080c, 0x5c98,
+ 0x7807, 0x0003, 0x7827, 0x0000, 0x782b, 0x0000, 0x0c28, 0x080c,
+ 0x82d9, 0x6220, 0xd2a4, 0x0170, 0xd2cc, 0x0160, 0x782b, 0x0000,
+ 0x7824, 0x9065, 0x090c, 0x0df6, 0x2009, 0x0013, 0x080c, 0xa068,
+ 0x00ce, 0x0005, 0x00c6, 0x7824, 0x9065, 0x090c, 0x0df6, 0x7828,
+ 0x9092, 0xc350, 0x12c0, 0x8000, 0x782a, 0x00ce, 0x080c, 0x29e9,
+ 0x0278, 0x00c6, 0x7924, 0x2160, 0x6010, 0x906d, 0x090c, 0x0df6,
+ 0x7807, 0x0000, 0x7827, 0x0000, 0x00ce, 0x080c, 0x8b8f, 0x0c00,
+ 0x080c, 0x95f6, 0x08e8, 0x2011, 0x0130, 0x2214, 0x080c, 0x9df6,
+ 0x080c, 0xdbf0, 0x2009, 0x0014, 0x080c, 0xa068, 0x00ce, 0x0880,
+ 0x2001, 0x19de, 0x2003, 0x0000, 0x62c0, 0x82ff, 0x1160, 0x782b,
+ 0x0000, 0x7824, 0x9065, 0x090c, 0x0df6, 0x2009, 0x0013, 0x080c,
+ 0xa0ba, 0x00ce, 0x0005, 0x00b6, 0x00c6, 0x00d6, 0x7824, 0x9005,
+ 0x090c, 0x0df6, 0x7828, 0x9092, 0xc350, 0x1648, 0x8000, 0x782a,
+ 0x00de, 0x00ce, 0x00be, 0x080c, 0x29e9, 0x02f0, 0x00b6, 0x00c6,
+ 0x00d6, 0x781c, 0x905d, 0x090c, 0x0df6, 0xb800, 0xc0dc, 0xb802,
+ 0x7924, 0x2160, 0x080c, 0x9fea, 0xb93c, 0x81ff, 0x090c, 0x0df6,
+ 0x8109, 0xb93e, 0x7807, 0x0000, 0x7827, 0x0000, 0x00de, 0x00ce,
+ 0x00be, 0x080c, 0x8b8f, 0x0868, 0x080c, 0x95f6, 0x0850, 0x2011,
+ 0x0130, 0x2214, 0x080c, 0x9df6, 0x080c, 0xdbf0, 0x7824, 0x9065,
+ 0x2009, 0x0014, 0x080c, 0xa068, 0x00de, 0x00ce, 0x00be, 0x0804,
+ 0x8569, 0x00c6, 0x2001, 0x009b, 0x2004, 0xd0fc, 0x190c, 0x1d00,
+ 0x6024, 0x6027, 0x0002, 0xd0f4, 0x1580, 0x62c8, 0x60c4, 0x9205,
+ 0x1170, 0x783c, 0x9065, 0x0130, 0x2009, 0x0049, 0x080c, 0xa068,
+ 0x00ce, 0x0005, 0x2011, 0x19e1, 0x2013, 0x0000, 0x0cc8, 0x793c,
+ 0x81ff, 0x0dc0, 0x7944, 0x9192, 0x7530, 0x12f0, 0x8108, 0x7946,
+ 0x793c, 0x9188, 0x0008, 0x210c, 0x918e, 0x0006, 0x1138, 0x6014,
+ 0x9084, 0x1984, 0x9085, 0x0012, 0x6016, 0x0c10, 0x6014, 0x9084,
+ 0x1984, 0x9085, 0x0016, 0x6016, 0x08d8, 0x793c, 0x2160, 0x2009,
+ 0x004a, 0x080c, 0xa068, 0x08a0, 0x7848, 0xc085, 0x784a, 0x0880,
+ 0x0006, 0x0016, 0x00c6, 0x0126, 0x2091, 0x8000, 0x600f, 0x0000,
+ 0x2c08, 0x2061, 0x19c2, 0x6020, 0x8000, 0x6022, 0x6010, 0x9005,
+ 0x0148, 0x9080, 0x0003, 0x2102, 0x6112, 0x012e, 0x00ce, 0x001e,
+ 0x000e, 0x0005, 0x6116, 0x6112, 0x0cc0, 0x00d6, 0x2069, 0x19c2,
+ 0xb800, 0xd0d4, 0x0168, 0x6820, 0x8000, 0x6822, 0x9086, 0x0001,
+ 0x1110, 0x2b00, 0x681e, 0x00de, 0x0804, 0x8b8f, 0x00de, 0x0005,
+ 0xc0d5, 0xb802, 0x6818, 0x9005, 0x0168, 0xb856, 0xb85b, 0x0000,
+ 0x0086, 0x0006, 0x2b00, 0x681a, 0x008e, 0xa05a, 0x008e, 0x2069,
+ 0x19c2, 0x0c08, 0xb856, 0xb85a, 0x2b00, 0x681a, 0x681e, 0x08d8,
+ 0x0006, 0x0016, 0x00c6, 0x0126, 0x2091, 0x8000, 0x600f, 0x0000,
+ 0x2c08, 0x2061, 0x19c2, 0x6020, 0x8000, 0x6022, 0x6008, 0x9005,
+ 0x0148, 0x9080, 0x0003, 0x2102, 0x610a, 0x012e, 0x00ce, 0x001e,
+ 0x000e, 0x0005, 0x610e, 0x610a, 0x0cc0, 0x00c6, 0x600f, 0x0000,
+ 0x2c08, 0x2061, 0x19c2, 0x6034, 0x9005, 0x0130, 0x9080, 0x0003,
+ 0x2102, 0x6136, 0x00ce, 0x0005, 0x613a, 0x6136, 0x00ce, 0x0005,
+ 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x00b6, 0x0096, 0x0076, 0x0066,
+ 0x0056, 0x0036, 0x0026, 0x0016, 0x0006, 0x0126, 0x902e, 0x2071,
+ 0x19c2, 0x7638, 0x2660, 0x2678, 0x2091, 0x8000, 0x8cff, 0x0904,
+ 0x86ec, 0x6010, 0x2058, 0xb8a0, 0x9206, 0x1904, 0x86e7, 0x87ff,
+ 0x0120, 0x6054, 0x9106, 0x1904, 0x86e7, 0x703c, 0x9c06, 0x1178,
+ 0x0036, 0x2019, 0x0001, 0x080c, 0x98b1, 0x7033, 0x0000, 0x9006,
+ 0x703e, 0x7042, 0x7046, 0x704a, 0x003e, 0x2029, 0x0001, 0x7038,
+ 0x9c36, 0x1110, 0x660c, 0x763a, 0x7034, 0x9c36, 0x1140, 0x2c00,
+ 0x9f36, 0x0118, 0x2f00, 0x7036, 0x0010, 0x7037, 0x0000, 0x660c,
+ 0x0066, 0x2c00, 0x9f06, 0x0110, 0x7e0e, 0x0008, 0x2678, 0x600f,
+ 0x0000, 0x080c, 0xbd4e, 0x01f0, 0x6014, 0x2048, 0x6020, 0x9086,
+ 0x0003, 0x15b8, 0x6004, 0x9086, 0x0040, 0x090c, 0x9a7f, 0xa867,
+ 0x0103, 0xab7a, 0xa877, 0x0000, 0x0016, 0x0036, 0x0076, 0x080c,
+ 0xc044, 0x080c, 0xdae1, 0x080c, 0x6a22, 0x007e, 0x003e, 0x001e,
+ 0x080c, 0xbf39, 0x080c, 0xa01c, 0x00ce, 0x0804, 0x8686, 0x2c78,
+ 0x600c, 0x2060, 0x0804, 0x8686, 0x85ff, 0x0120, 0x0036, 0x080c,
+ 0x8c6c, 0x003e, 0x012e, 0x000e, 0x001e, 0x002e, 0x003e, 0x005e,
+ 0x006e, 0x007e, 0x009e, 0x00be, 0x00ce, 0x00de, 0x00ee, 0x00fe,
+ 0x0005, 0x6020, 0x9086, 0x0006, 0x1158, 0x0016, 0x0036, 0x0076,
+ 0x080c, 0xdae1, 0x080c, 0xd7e2, 0x007e, 0x003e, 0x001e, 0x0890,
+ 0x6020, 0x9086, 0x000a, 0x0904, 0x86d1, 0x0804, 0x86ca, 0x0006,
+ 0x0066, 0x0096, 0x00c6, 0x00d6, 0x00f6, 0x9036, 0x0126, 0x2091,
+ 0x8000, 0x2079, 0x19c2, 0x7838, 0x9065, 0x0904, 0x876c, 0x600c,
+ 0x0006, 0x600f, 0x0000, 0x783c, 0x9c06, 0x1168, 0x0036, 0x2019,
+ 0x0001, 0x080c, 0x98b1, 0x7833, 0x0000, 0x901e, 0x7b3e, 0x7b42,
+ 0x7b46, 0x7b4a, 0x003e, 0x080c, 0xbd4e, 0x0548, 0x6014, 0x2048,
+ 0x6020, 0x9086, 0x0003, 0x1590, 0x3e08, 0x918e, 0x0002, 0x1188,
+ 0x6010, 0x9005, 0x0170, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc,
+ 0x0140, 0x6040, 0x9005, 0x11a8, 0x2001, 0x1962, 0x2004, 0x6042,
+ 0x0080, 0x6004, 0x9086, 0x0040, 0x090c, 0x9a7f, 0xa867, 0x0103,
+ 0xab7a, 0xa877, 0x0000, 0x080c, 0x6a15, 0x080c, 0xbf39, 0x080c,
+ 0xa01c, 0x000e, 0x0804, 0x8724, 0x7e3a, 0x7e36, 0x012e, 0x00fe,
+ 0x00de, 0x00ce, 0x009e, 0x006e, 0x000e, 0x0005, 0x6020, 0x9086,
+ 0x0006, 0x1118, 0x080c, 0xd7e2, 0x0c50, 0x6020, 0x9086, 0x000a,
+ 0x09f8, 0x08b8, 0x0016, 0x0026, 0x0086, 0x9046, 0x0099, 0x080c,
+ 0x886d, 0x008e, 0x002e, 0x001e, 0x0005, 0x00f6, 0x0126, 0x2079,
+ 0x19c2, 0x2091, 0x8000, 0x080c, 0x8904, 0x080c, 0x8994, 0x012e,
+ 0x00fe, 0x0005, 0x00b6, 0x0096, 0x00f6, 0x00e6, 0x00d6, 0x00c6,
+ 0x0066, 0x0016, 0x0006, 0x0126, 0x2091, 0x8000, 0x2071, 0x19c2,
+ 0x7614, 0x2660, 0x2678, 0x8cff, 0x0904, 0x8832, 0x6010, 0x2058,
+ 0xb8a0, 0x9206, 0x1904, 0x882d, 0x88ff, 0x0120, 0x6054, 0x9106,
+ 0x1904, 0x882d, 0x7024, 0x9c06, 0x1568, 0x2069, 0x0100, 0x6820,
+ 0xd0a4, 0x0110, 0xd0cc, 0x1508, 0x080c, 0x82d9, 0x080c, 0x961a,
+ 0x68c3, 0x0000, 0x080c, 0x9a7f, 0x7027, 0x0000, 0x0036, 0x2069,
0x0140, 0x6b04, 0x9384, 0x1000, 0x0138, 0x2001, 0x0100, 0x080c,
- 0x2b88, 0x9006, 0x080c, 0x2b88, 0x2069, 0x0100, 0x6824, 0xd084,
- 0x0110, 0x6827, 0x0001, 0x003e, 0x00de, 0x00c6, 0xb83c, 0x9005,
- 0x0110, 0x8001, 0xb83e, 0x2660, 0x080c, 0xa007, 0x00ce, 0x0048,
- 0x00de, 0x00c6, 0x2660, 0x6003, 0x0009, 0x630a, 0x00ce, 0x0804,
- 0x88a1, 0x89ff, 0x0158, 0xa867, 0x0103, 0xab7a, 0xa877, 0x0000,
- 0x080c, 0xc031, 0x080c, 0xda80, 0x080c, 0x6a23, 0x080c, 0x9940,
- 0x0804, 0x88a1, 0x006e, 0x00de, 0x00ee, 0x00fe, 0x012e, 0x000e,
- 0x00ce, 0x009e, 0x00ae, 0x00be, 0x0005, 0x0096, 0x0006, 0x0066,
- 0x00c6, 0x00d6, 0x9036, 0x7814, 0x9065, 0x0904, 0x8968, 0x600c,
- 0x0006, 0x600f, 0x0000, 0x7824, 0x9c06, 0x1580, 0x2069, 0x0100,
- 0x6820, 0xd0a4, 0x0110, 0xd0cc, 0x1508, 0x080c, 0x82da, 0x080c,
- 0x9605, 0x68c3, 0x0000, 0x080c, 0x9a6a, 0x7827, 0x0000, 0x0036,
- 0x2069, 0x0140, 0x6b04, 0x9384, 0x1000, 0x0138, 0x2001, 0x0100,
- 0x080c, 0x2b88, 0x9006, 0x080c, 0x2b88, 0x2069, 0x0100, 0x6824,
- 0xd084, 0x0110, 0x6827, 0x0001, 0x003e, 0x0040, 0x080c, 0x6680,
- 0x1520, 0x6003, 0x0009, 0x630a, 0x2c30, 0x00f8, 0x6014, 0x2048,
- 0x080c, 0xbd39, 0x01b0, 0x6020, 0x9086, 0x0003, 0x1508, 0x080c,
- 0xbf43, 0x1118, 0x080c, 0xa995, 0x0060, 0x080c, 0x6680, 0x1168,
- 0xa867, 0x0103, 0xab7a, 0xa877, 0x0000, 0x080c, 0x6a23, 0x080c,
- 0xbf26, 0x080c, 0xa007, 0x080c, 0x9940, 0x000e, 0x0804, 0x890c,
- 0x7e16, 0x7e12, 0x00de, 0x00ce, 0x006e, 0x000e, 0x009e, 0x0005,
- 0x6020, 0x9086, 0x0006, 0x1118, 0x080c, 0xd781, 0x0c50, 0x080c,
- 0xa995, 0x6020, 0x9086, 0x0002, 0x1150, 0x6004, 0x0006, 0x9086,
- 0x0085, 0x000e, 0x0990, 0x9086, 0x008b, 0x0978, 0x08d0, 0x6020,
- 0x9086, 0x0005, 0x19b0, 0x6004, 0x0006, 0x9086, 0x0085, 0x000e,
- 0x0d18, 0x9086, 0x008b, 0x0d00, 0x0860, 0x0006, 0x0066, 0x0096,
- 0x00b6, 0x00c6, 0x00d6, 0x7818, 0x905d, 0x0904, 0x8a15, 0xb854,
- 0x0006, 0x9006, 0xb856, 0xb85a, 0xb800, 0xc0d4, 0xc0dc, 0xb802,
- 0x080c, 0x62d7, 0x0904, 0x8a12, 0x7e24, 0x86ff, 0x0904, 0x8a05,
- 0x9680, 0x0005, 0x2004, 0x9906, 0x1904, 0x8a05, 0x00d6, 0x2069,
- 0x0100, 0x68c0, 0x9005, 0x0904, 0x89fc, 0x080c, 0x82da, 0x080c,
- 0x9605, 0x68c3, 0x0000, 0x080c, 0x9a6a, 0x7827, 0x0000, 0x0036,
- 0x2069, 0x0140, 0x6b04, 0x9384, 0x1000, 0x0138, 0x2001, 0x0100,
- 0x080c, 0x2b88, 0x9006, 0x080c, 0x2b88, 0x2069, 0x0100, 0x6824,
- 0xd084, 0x0110, 0x6827, 0x0001, 0x003e, 0x00de, 0x00c6, 0x3e08,
- 0x918e, 0x0002, 0x1168, 0xb800, 0xd0bc, 0x0150, 0x9680, 0x0010,
- 0x200c, 0x81ff, 0x1518, 0x2009, 0x1962, 0x210c, 0x2102, 0x00f0,
- 0xb83c, 0x9005, 0x0110, 0x8001, 0xb83e, 0x2660, 0x600f, 0x0000,
- 0x080c, 0xa007, 0x00ce, 0x0048, 0x00de, 0x00c6, 0x2660, 0x6003,
- 0x0009, 0x630a, 0x00ce, 0x0804, 0x89a8, 0x89ff, 0x0138, 0xa867,
- 0x0103, 0xab7a, 0xa877, 0x0000, 0x080c, 0x6a23, 0x080c, 0x9940,
- 0x0804, 0x89a8, 0x000e, 0x0804, 0x899c, 0x781e, 0x781a, 0x00de,
- 0x00ce, 0x00be, 0x009e, 0x006e, 0x000e, 0x0005, 0x00e6, 0x00d6,
- 0x0096, 0x0066, 0xb800, 0xd0dc, 0x01a0, 0xb84c, 0x904d, 0x0188,
- 0xa878, 0x9606, 0x1170, 0x2071, 0x19c2, 0x7024, 0x9035, 0x0148,
- 0x9080, 0x0005, 0x2004, 0x9906, 0x1120, 0xb800, 0xc0dc, 0xb802,
- 0x0029, 0x006e, 0x009e, 0x00de, 0x00ee, 0x0005, 0x00f6, 0x2079,
- 0x0100, 0x78c0, 0x9005, 0x1138, 0x00c6, 0x2660, 0x6003, 0x0009,
- 0x630a, 0x00ce, 0x04b8, 0x080c, 0x9605, 0x78c3, 0x0000, 0x080c,
- 0x9a6a, 0x7027, 0x0000, 0x0036, 0x2079, 0x0140, 0x7b04, 0x9384,
- 0x1000, 0x0138, 0x2001, 0x0100, 0x080c, 0x2b88, 0x9006, 0x080c,
- 0x2b88, 0x2079, 0x0100, 0x7824, 0xd084, 0x0110, 0x7827, 0x0001,
- 0x080c, 0x9a6a, 0x003e, 0x080c, 0x62d7, 0x00c6, 0xb83c, 0x9005,
- 0x0110, 0x8001, 0xb83e, 0x2660, 0x080c, 0x9fd5, 0x00ce, 0xa867,
- 0x0103, 0xab7a, 0xa877, 0x0000, 0x080c, 0xc031, 0x080c, 0x6a23,
- 0x080c, 0x9940, 0x00fe, 0x0005, 0x00b6, 0x00e6, 0x00c6, 0x2011,
- 0x0101, 0x2204, 0xc0c4, 0x2012, 0x2001, 0x180c, 0x2014, 0xc2e4,
- 0x2202, 0x2071, 0x19c2, 0x7004, 0x9084, 0x0007, 0x0002, 0x8aa1,
- 0x8aa5, 0x8ac3, 0x8aec, 0x8b2a, 0x8aa1, 0x8abc, 0x8a9f, 0x080c,
- 0x0e02, 0x00ce, 0x00ee, 0x00be, 0x0005, 0x7024, 0x9065, 0x0148,
- 0x7020, 0x8001, 0x7022, 0x600c, 0x9015, 0x0158, 0x7216, 0x600f,
- 0x0000, 0x7007, 0x0000, 0x7027, 0x0000, 0x00ce, 0x00ee, 0x00be,
- 0x0005, 0x7216, 0x7212, 0x0ca8, 0x7007, 0x0000, 0x7027, 0x0000,
- 0x7020, 0x9005, 0x0070, 0x6010, 0x2058, 0x080c, 0x62d7, 0xb800,
- 0xc0dc, 0xb802, 0x7007, 0x0000, 0x7027, 0x0000, 0x7020, 0x8001,
- 0x7022, 0x1148, 0x2001, 0x180c, 0x2014, 0xd2ec, 0x1180, 0x00ce,
- 0x00ee, 0x00be, 0x0005, 0xb854, 0x9015, 0x0120, 0x721e, 0x080c,
- 0x8b90, 0x0ca8, 0x7218, 0x721e, 0x080c, 0x8b90, 0x0c80, 0xc2ec,
- 0x2202, 0x080c, 0x8c6d, 0x0c58, 0x7024, 0x9065, 0x05b8, 0x700c,
- 0x9c06, 0x1160, 0x080c, 0x9940, 0x600c, 0x9015, 0x0120, 0x720e,
- 0x600f, 0x0000, 0x0448, 0x720e, 0x720a, 0x0430, 0x7014, 0x9c06,
- 0x1160, 0x080c, 0x9940, 0x600c, 0x9015, 0x0120, 0x7216, 0x600f,
- 0x0000, 0x00d0, 0x7216, 0x7212, 0x00b8, 0x6020, 0x9086, 0x0003,
- 0x1198, 0x6010, 0x2058, 0x080c, 0x62d7, 0xb800, 0xc0dc, 0xb802,
- 0x080c, 0x9940, 0x701c, 0x9065, 0x0138, 0xb854, 0x9015, 0x0110,
- 0x721e, 0x0010, 0x7218, 0x721e, 0x7027, 0x0000, 0x00ce, 0x00ee,
- 0x00be, 0x0005, 0x7024, 0x9065, 0x0140, 0x080c, 0x9940, 0x600c,
- 0x9015, 0x0158, 0x720e, 0x600f, 0x0000, 0x080c, 0x9a6a, 0x7027,
- 0x0000, 0x00ce, 0x00ee, 0x00be, 0x0005, 0x720e, 0x720a, 0x0ca8,
- 0x00d6, 0x2069, 0x19c2, 0x6830, 0x9084, 0x0003, 0x0002, 0x8b4d,
- 0x8b4f, 0x8b73, 0x8b4b, 0x080c, 0x0e02, 0x00de, 0x0005, 0x00c6,
- 0x6840, 0x9086, 0x0001, 0x01b8, 0x683c, 0x9065, 0x0130, 0x600c,
- 0x9015, 0x0170, 0x6a3a, 0x600f, 0x0000, 0x6833, 0x0000, 0x683f,
- 0x0000, 0x2011, 0x19e1, 0x2013, 0x0000, 0x00ce, 0x00de, 0x0005,
- 0x683a, 0x6836, 0x0c90, 0x6843, 0x0000, 0x6838, 0x9065, 0x0d68,
- 0x6003, 0x0003, 0x0c50, 0x00c6, 0x9006, 0x6842, 0x6846, 0x684a,
- 0x683c, 0x9065, 0x0160, 0x600c, 0x9015, 0x0130, 0x6a3a, 0x600f,
- 0x0000, 0x683f, 0x0000, 0x0018, 0x683e, 0x683a, 0x6836, 0x00ce,
- 0x00de, 0x0005, 0x2001, 0x180c, 0x200c, 0xc1e5, 0x2102, 0x0005,
- 0x2001, 0x180c, 0x200c, 0xd1ec, 0x0120, 0xc1ec, 0x2102, 0x080c,
- 0x8c6d, 0x2001, 0x19ce, 0x2004, 0x9086, 0x0001, 0x0d58, 0x00d6,
- 0x2069, 0x19c2, 0x6804, 0x9084, 0x0007, 0x0002, 0x8bb0, 0x8c55,
- 0x8c55, 0x8c55, 0x8c55, 0x8c57, 0x8c55, 0x8bae, 0x080c, 0x0e02,
- 0x6820, 0x9005, 0x1110, 0x00de, 0x0005, 0x00c6, 0x680c, 0x9065,
- 0x0150, 0x6807, 0x0004, 0x6826, 0x682b, 0x0000, 0x080c, 0x8cc4,
- 0x00ce, 0x00de, 0x0005, 0x6814, 0x9065, 0x0150, 0x6807, 0x0001,
- 0x6826, 0x682b, 0x0000, 0x080c, 0x8cc4, 0x00ce, 0x00de, 0x0005,
- 0x00b6, 0x00e6, 0x6a1c, 0x92dd, 0x0000, 0x0904, 0x8c3f, 0xb84c,
- 0x900d, 0x0118, 0xb888, 0x9005, 0x01a0, 0xb854, 0x905d, 0x0120,
- 0x920e, 0x0904, 0x8c3f, 0x0028, 0x6818, 0x920e, 0x0904, 0x8c3f,
- 0x2058, 0xb84c, 0x900d, 0x0d88, 0xb888, 0x9005, 0x1d70, 0x2b00,
- 0x681e, 0xbb3c, 0xb838, 0x9302, 0x1e40, 0x080c, 0x9fac, 0x0904,
- 0x8c3f, 0x8318, 0xbb3e, 0x6116, 0x2b10, 0x6212, 0x0096, 0x2148,
- 0xa880, 0x9084, 0x00ff, 0x605e, 0xa883, 0x0000, 0xa884, 0x009e,
- 0x908a, 0x199a, 0x0210, 0x2001, 0x1999, 0x8003, 0x801b, 0x831b,
- 0x9318, 0x631a, 0x6114, 0x0096, 0x2148, 0xa964, 0x009e, 0x918c,
- 0x00ff, 0x918e, 0x0048, 0x0538, 0x00f6, 0x2c78, 0x2061, 0x0100,
- 0xbab0, 0x629a, 0x2069, 0x0200, 0x2071, 0x0240, 0x080c, 0x922a,
- 0x2069, 0x19c2, 0xbb00, 0xc3dd, 0xbb02, 0x6807, 0x0002, 0x2f18,
- 0x6b26, 0x682b, 0x0000, 0x7823, 0x0003, 0x7803, 0x0001, 0x7807,
- 0x0040, 0x00fe, 0x00ee, 0x00be, 0x00ce, 0x00de, 0x0005, 0x00ee,
- 0x00be, 0x00ce, 0x0cd0, 0x6807, 0x0006, 0x2c18, 0x6b26, 0x6820,
- 0x8001, 0x6822, 0x682b, 0x0000, 0x080c, 0x62d7, 0x080c, 0x9e01,
- 0x00ee, 0x00be, 0x00ce, 0x00de, 0x0005, 0x00de, 0x0005, 0x00c6,
- 0x680c, 0x9065, 0x0138, 0x6807, 0x0004, 0x6826, 0x682b, 0x0000,
- 0x080c, 0x8cc4, 0x00ce, 0x00de, 0x0005, 0x2001, 0x180c, 0x2014,
- 0xc2ed, 0x2202, 0x00de, 0x00fe, 0x0005, 0x00f6, 0x00d6, 0x2069,
- 0x19c2, 0x6830, 0x9086, 0x0000, 0x1548, 0x2001, 0x180c, 0x2014,
- 0xd2e4, 0x0130, 0xc2e4, 0x2202, 0x080c, 0x8b9f, 0x2069, 0x19c2,
- 0x2001, 0x180c, 0x200c, 0xd1c4, 0x11e0, 0x6838, 0x907d, 0x01b0,
- 0x6a04, 0x9296, 0x0000, 0x1568, 0x6833, 0x0001, 0x683e, 0x6847,
- 0x0000, 0x684b, 0x0000, 0x0126, 0x00f6, 0x2091, 0x2400, 0x002e,
- 0x080c, 0x1b0e, 0x1158, 0x012e, 0x080c, 0x9462, 0x00de, 0x00fe,
- 0x0005, 0xc1c4, 0x2102, 0x080c, 0x7247, 0x08f8, 0x012e, 0x6843,
- 0x0000, 0x7803, 0x0002, 0x780c, 0x9015, 0x0140, 0x6a3a, 0x780f,
- 0x0000, 0x6833, 0x0000, 0x683f, 0x0000, 0x0c40, 0x683a, 0x6836,
- 0x0cc0, 0x6a04, 0x9296, 0x0006, 0x1904, 0x8c65, 0x6a30, 0x9296,
- 0x0000, 0x0950, 0x0804, 0x8c65, 0x6020, 0x9084, 0x000f, 0x000b,
- 0x0005, 0x8cd8, 0x8cdd, 0x915a, 0x91f3, 0x8cdd, 0x915a, 0x91f3,
- 0x8cd8, 0x8cdd, 0x8cd8, 0x8cd8, 0x8cd8, 0x8cd8, 0x8cd8, 0x8cd8,
- 0x080c, 0x8a84, 0x080c, 0x8b90, 0x0005, 0x00b6, 0x0156, 0x0136,
- 0x0146, 0x01c6, 0x01d6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x2069,
- 0x0200, 0x2071, 0x0240, 0x6004, 0x908a, 0x0053, 0x1a0c, 0x0e02,
- 0x6110, 0x2158, 0xb9b0, 0x2c78, 0x2061, 0x0100, 0x619a, 0x908a,
- 0x0040, 0x1a04, 0x8d49, 0x005b, 0x00fe, 0x00ee, 0x00de, 0x00ce,
- 0x01de, 0x01ce, 0x014e, 0x013e, 0x015e, 0x00be, 0x0005, 0x8ee4,
- 0x8f1f, 0x8f48, 0x8feb, 0x900c, 0x9012, 0x901f, 0x9027, 0x9033,
- 0x9039, 0x904a, 0x9039, 0x90a1, 0x9027, 0x90ad, 0x90b3, 0x9033,
- 0x90b3, 0x90bf, 0x8d47, 0x8d47, 0x8d47, 0x8d47, 0x8d47, 0x8d47,
- 0x8d47, 0x8d47, 0x8d47, 0x8d47, 0x8d47, 0x9753, 0x9776, 0x9787,
- 0x97a7, 0x97d9, 0x901f, 0x8d47, 0x901f, 0x9039, 0x8d47, 0x8f48,
- 0x8feb, 0x8d47, 0x9b61, 0x9039, 0x8d47, 0x9b7d, 0x9039, 0x8d47,
- 0x9033, 0x8ede, 0x8d6a, 0x8d47, 0x9b99, 0x9c06, 0x9ce1, 0x8d47,
- 0x9cee, 0x901c, 0x9d19, 0x8d47, 0x97e3, 0x9d46, 0x8d47, 0x080c,
- 0x0e02, 0x2100, 0x005b, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x01de,
- 0x01ce, 0x014e, 0x013e, 0x015e, 0x00be, 0x0005, 0x8d68, 0x8d68,
- 0x8d68, 0x8da2, 0x8e4e, 0x8e59, 0x8d68, 0x8d68, 0x8d68, 0x8eb3,
- 0x8ebf, 0x8dbd, 0x8d68, 0x8dd8, 0x8e0c, 0x9ec8, 0x9f0d, 0x9039,
- 0x080c, 0x0e02, 0x00d6, 0x0096, 0x080c, 0x90d2, 0x0026, 0x0036,
- 0x7814, 0x2048, 0xa958, 0xd1cc, 0x1138, 0x2009, 0x2414, 0x2011,
- 0x0018, 0x2019, 0x0018, 0x0030, 0x2009, 0x2410, 0x2011, 0x0014,
- 0x2019, 0x0014, 0x7102, 0x7206, 0x700b, 0x0800, 0xa83c, 0x700e,
- 0xa850, 0x7022, 0xa854, 0x7026, 0x63c2, 0x080c, 0x95d9, 0x003e,
- 0x002e, 0x009e, 0x00de, 0x0005, 0x7810, 0x00b6, 0x2058, 0xb8a0,
- 0x00be, 0x080c, 0x9f54, 0x1118, 0x9084, 0xff80, 0x0110, 0x9085,
- 0x0001, 0x0005, 0x00d6, 0x0096, 0x080c, 0x90d2, 0x7003, 0x0500,
- 0x7814, 0x2048, 0xa874, 0x700a, 0xa878, 0x700e, 0xa87c, 0x7012,
- 0xa880, 0x7016, 0xa884, 0x701a, 0xa888, 0x701e, 0x60c3, 0x0010,
- 0x080c, 0x95d9, 0x009e, 0x00de, 0x0005, 0x00d6, 0x0096, 0x080c,
- 0x90d2, 0x7003, 0x0500, 0x7814, 0x2048, 0xa8cc, 0x700a, 0xa8d0,
- 0x700e, 0xa8d4, 0x7012, 0xa8d8, 0x7016, 0xa8dc, 0x701a, 0xa8e0,
- 0x701e, 0x60c3, 0x0010, 0x080c, 0x95d9, 0x009e, 0x00de, 0x0005,
- 0x00d6, 0x0096, 0x0126, 0x2091, 0x8000, 0x080c, 0x90d2, 0x20e9,
- 0x0000, 0x2001, 0x197d, 0x2003, 0x0000, 0x7814, 0x2048, 0xa814,
- 0x8003, 0x60c2, 0xa830, 0x20a8, 0xa860, 0x20e0, 0xa85c, 0x9080,
- 0x001b, 0x2098, 0x2001, 0x197d, 0x0016, 0x200c, 0x2001, 0x0001,
- 0x080c, 0x21e9, 0x080c, 0xcaae, 0x9006, 0x080c, 0x21e9, 0x001e,
- 0xa804, 0x9005, 0x0110, 0x2048, 0x0c28, 0x04d9, 0x080c, 0x95d9,
- 0x012e, 0x009e, 0x00de, 0x0005, 0x00d6, 0x0096, 0x0126, 0x2091,
- 0x8000, 0x080c, 0x911d, 0x20e9, 0x0000, 0x2001, 0x197d, 0x2003,
- 0x0000, 0x7814, 0x2048, 0xa86f, 0x0200, 0xa873, 0x0000, 0xa814,
- 0x8003, 0x60c2, 0xa830, 0x20a8, 0xa860, 0x20e0, 0xa85c, 0x9080,
- 0x001b, 0x2098, 0x2001, 0x197d, 0x0016, 0x200c, 0x080c, 0xcaae,
- 0x001e, 0xa804, 0x9005, 0x0110, 0x2048, 0x0c60, 0x0051, 0x7814,
- 0x2048, 0x080c, 0x0ff5, 0x080c, 0x95d9, 0x012e, 0x009e, 0x00de,
- 0x0005, 0x60c0, 0x8004, 0x9084, 0x0003, 0x9005, 0x0130, 0x9082,
- 0x0004, 0x20a3, 0x0000, 0x8000, 0x1de0, 0x0005, 0x080c, 0x90d2,
- 0x7003, 0x7800, 0x7808, 0x8007, 0x700a, 0x60c3, 0x0008, 0x0804,
- 0x95d9, 0x00d6, 0x00e6, 0x080c, 0x911d, 0x7814, 0x9084, 0xff00,
- 0x2073, 0x0200, 0x8e70, 0x8e70, 0x9096, 0xdf00, 0x0138, 0x9096,
- 0xe000, 0x0120, 0x2073, 0x0010, 0x8e70, 0x0030, 0x9095, 0x0010,
- 0x2272, 0x8e70, 0x2073, 0x0034, 0x8e70, 0x2069, 0x1805, 0x20a9,
- 0x0004, 0x2d76, 0x8d68, 0x8e70, 0x1f04, 0x8e79, 0x2069, 0x1801,
- 0x20a9, 0x0004, 0x2d76, 0x8d68, 0x8e70, 0x1f04, 0x8e82, 0x9096,
- 0xdf00, 0x0130, 0x9096, 0xe000, 0x0118, 0x60c3, 0x0018, 0x00f0,
- 0x2069, 0x198e, 0x9086, 0xdf00, 0x0110, 0x2069, 0x19a8, 0x20a9,
- 0x001a, 0x9e86, 0x0260, 0x1148, 0x00c6, 0x2061, 0x0200, 0x6010,
- 0x8000, 0x6012, 0x00ce, 0x2071, 0x0240, 0x2d04, 0x8007, 0x2072,
- 0x8d68, 0x8e70, 0x1f04, 0x8e99, 0x60c3, 0x004c, 0x080c, 0x95d9,
- 0x00ee, 0x00de, 0x0005, 0x080c, 0x90d2, 0x7003, 0x6300, 0x7007,
- 0x0028, 0x7808, 0x700e, 0x60c3, 0x0008, 0x0804, 0x95d9, 0x00d6,
- 0x0026, 0x0016, 0x080c, 0x911d, 0x7003, 0x0200, 0x7814, 0x700e,
- 0x00e6, 0x9ef0, 0x0004, 0x2009, 0x0001, 0x2011, 0x000c, 0x2073,
- 0x0800, 0x8e70, 0x2073, 0x0000, 0x00ee, 0x7206, 0x710a, 0x62c2,
- 0x080c, 0x95d9, 0x001e, 0x002e, 0x00de, 0x0005, 0x2001, 0x1817,
- 0x2004, 0x609a, 0x0804, 0x95d9, 0x080c, 0x90d2, 0x7003, 0x5200,
- 0x2069, 0x185b, 0x6804, 0xd084, 0x0130, 0x6828, 0x0016, 0x080c,
- 0x26a1, 0x710e, 0x001e, 0x20a9, 0x0004, 0x20e1, 0x0001, 0x2099,
- 0x1805, 0x20e9, 0x0000, 0x20a1, 0x0250, 0x4003, 0x20a9, 0x0004,
- 0x2099, 0x1801, 0x20a1, 0x0254, 0x4003, 0x080c, 0x9f54, 0x1120,
- 0xb8a0, 0x9082, 0x007f, 0x0248, 0x2001, 0x181e, 0x2004, 0x7032,
- 0x2001, 0x181f, 0x2004, 0x7036, 0x0030, 0x2001, 0x1817, 0x2004,
- 0x9084, 0x00ff, 0x7036, 0x60c3, 0x001c, 0x0804, 0x95d9, 0x080c,
- 0x90d2, 0x7003, 0x0500, 0x080c, 0x9f54, 0x1120, 0xb8a0, 0x9082,
- 0x007f, 0x0248, 0x2001, 0x181e, 0x2004, 0x700a, 0x2001, 0x181f,
- 0x2004, 0x700e, 0x0030, 0x2001, 0x1817, 0x2004, 0x9084, 0x00ff,
- 0x700e, 0x20a9, 0x0004, 0x20e1, 0x0001, 0x2099, 0x1805, 0x20e9,
- 0x0000, 0x20a1, 0x0250, 0x4003, 0x60c3, 0x0010, 0x0804, 0x95d9,
- 0x080c, 0x90d2, 0x9006, 0x080c, 0x6694, 0xb8a0, 0x9086, 0x007e,
- 0x1130, 0x7003, 0x0400, 0x620c, 0xc2b4, 0x620e, 0x0058, 0x7814,
- 0x0096, 0x904d, 0x0120, 0x9006, 0xa89a, 0xa8a6, 0xa8aa, 0x009e,
- 0x7003, 0x0300, 0xb8a0, 0x9086, 0x007e, 0x1904, 0x8fb3, 0x00d6,
- 0x2069, 0x1946, 0x2001, 0x1836, 0x2004, 0xd0a4, 0x0178, 0x6800,
- 0x700a, 0x6808, 0x9084, 0x2000, 0x7012, 0x680c, 0x7016, 0x701f,
- 0x2710, 0x6818, 0x7022, 0x681c, 0x7026, 0x0080, 0x6800, 0x700a,
- 0x6804, 0x700e, 0x6808, 0x080c, 0x717f, 0x1118, 0x9084, 0x37ff,
- 0x0010, 0x9084, 0x3fff, 0x7012, 0x680c, 0x7016, 0x00de, 0x20a9,
- 0x0004, 0x20e1, 0x0001, 0x2099, 0x1805, 0x20e9, 0x0000, 0x20a1,
- 0x0256, 0x4003, 0x20a9, 0x0004, 0x2099, 0x1801, 0x20a1, 0x025a,
- 0x4003, 0x00d6, 0x080c, 0x9dc8, 0x2069, 0x194e, 0x2071, 0x024e,
- 0x6800, 0xc0dd, 0x7002, 0x080c, 0x54e0, 0xd0e4, 0x0110, 0x680c,
- 0x700e, 0x00de, 0x04a0, 0x2001, 0x1836, 0x2004, 0xd0a4, 0x0168,
- 0x0016, 0x2009, 0x0002, 0x60e0, 0x9106, 0x0130, 0x2100, 0x60e3,
- 0x0000, 0x080c, 0x26e2, 0x61e2, 0x001e, 0x20e1, 0x0001, 0x2099,
- 0x1946, 0x20e9, 0x0000, 0x20a1, 0x024e, 0x20a9, 0x0008, 0x4003,
- 0x20a9, 0x0004, 0x2099, 0x1805, 0x20a1, 0x0256, 0x4003, 0x20a9,
- 0x0004, 0x2099, 0x1801, 0x20a1, 0x025a, 0x4003, 0x080c, 0x9dc8,
- 0x20a1, 0x024e, 0x20a9, 0x0008, 0x2099, 0x194e, 0x4003, 0x60c3,
- 0x0074, 0x0804, 0x95d9, 0x080c, 0x90d2, 0x7003, 0x2010, 0x7007,
- 0x0014, 0x700b, 0x0800, 0x700f, 0x2000, 0x9006, 0x00f6, 0x2079,
- 0x185b, 0x7904, 0x00fe, 0xd1ac, 0x1110, 0x9085, 0x0020, 0x0010,
- 0x9085, 0x0010, 0x9085, 0x0002, 0x00d6, 0x0804, 0x9082, 0x7026,
- 0x60c3, 0x0014, 0x0804, 0x95d9, 0x080c, 0x90d2, 0x7003, 0x5000,
- 0x0804, 0x8f62, 0x080c, 0x90d2, 0x7003, 0x2110, 0x7007, 0x0014,
- 0x60c3, 0x0014, 0x0804, 0x95d9, 0x080c, 0x9114, 0x0010, 0x080c,
- 0x911d, 0x7003, 0x0200, 0x60c3, 0x0004, 0x0804, 0x95d9, 0x080c,
- 0x911d, 0x7003, 0x0100, 0x700b, 0x0003, 0x700f, 0x2a00, 0x60c3,
- 0x0008, 0x0804, 0x95d9, 0x080c, 0x911d, 0x7003, 0x0200, 0x0804,
- 0x8f62, 0x080c, 0x911d, 0x7003, 0x0100, 0x782c, 0x9005, 0x0110,
- 0x700a, 0x0010, 0x700b, 0x0003, 0x7814, 0x700e, 0x60c3, 0x0008,
- 0x0804, 0x95d9, 0x00d6, 0x080c, 0x911d, 0x7003, 0x0210, 0x7007,
- 0x0014, 0x700b, 0x0800, 0xb894, 0x9086, 0x0014, 0x1198, 0xb99c,
- 0x9184, 0x0030, 0x0190, 0xb998, 0x9184, 0xc000, 0x1140, 0xd1ec,
- 0x0118, 0x700f, 0x2100, 0x0058, 0x700f, 0x0100, 0x0040, 0x700f,
- 0x0400, 0x0028, 0x700f, 0x0700, 0x0010, 0x700f, 0x0800, 0x00f6,
- 0x2079, 0x185b, 0x7904, 0x00fe, 0xd1ac, 0x1110, 0x9085, 0x0020,
- 0x0010, 0x9085, 0x0010, 0x2009, 0x187d, 0x210c, 0xd184, 0x1110,
- 0x9085, 0x0002, 0x0026, 0x2009, 0x187b, 0x210c, 0xd1e4, 0x0150,
- 0xc0c5, 0xbabc, 0xd28c, 0x1108, 0xc0cd, 0x9094, 0x0030, 0x9296,
- 0x0010, 0x0140, 0xd1ec, 0x0130, 0x9094, 0x0030, 0x9296, 0x0010,
- 0x0108, 0xc0bd, 0x002e, 0x7026, 0x60c3, 0x0014, 0x00de, 0x0804,
- 0x95d9, 0x080c, 0x911d, 0x7003, 0x0210, 0x7007, 0x0014, 0x700f,
- 0x0100, 0x60c3, 0x0014, 0x0804, 0x95d9, 0x080c, 0x911d, 0x7003,
- 0x0200, 0x0804, 0x8ee8, 0x080c, 0x911d, 0x7003, 0x0100, 0x700b,
- 0x0003, 0x700f, 0x2a00, 0x60c3, 0x0008, 0x0804, 0x95d9, 0x080c,
- 0x911d, 0x7003, 0x0100, 0x700b, 0x000b, 0x60c3, 0x0008, 0x0804,
- 0x95d9, 0x0026, 0x00d6, 0x0036, 0x0046, 0x2019, 0x3200, 0x2021,
- 0x0800, 0x0040, 0x0026, 0x00d6, 0x0036, 0x0046, 0x2019, 0x2200,
- 0x2021, 0x0100, 0x080c, 0x9ddd, 0xb810, 0x9305, 0x7002, 0xb814,
- 0x7006, 0x2069, 0x1800, 0x6878, 0x700a, 0x687c, 0x700e, 0x9485,
- 0x0029, 0x7012, 0x004e, 0x003e, 0x00de, 0x080c, 0x95c7, 0x721a,
- 0x9f95, 0x0000, 0x7222, 0x7027, 0xffff, 0x2071, 0x024c, 0x002e,
- 0x0005, 0x0026, 0x080c, 0x9ddd, 0x7003, 0x02ff, 0x7007, 0xfffc,
- 0x00d6, 0x2069, 0x1800, 0x6878, 0x700a, 0x687c, 0x700e, 0x00de,
- 0x7013, 0x2029, 0x0c10, 0x7003, 0x0100, 0x7007, 0x0000, 0x700b,
- 0xfc02, 0x700f, 0x0000, 0x0005, 0x0026, 0x00d6, 0x0036, 0x0046,
- 0x2019, 0x3300, 0x2021, 0x0800, 0x0040, 0x0026, 0x00d6, 0x0036,
- 0x0046, 0x2019, 0x2300, 0x2021, 0x0100, 0x080c, 0x9ddd, 0xb810,
- 0x9305, 0x7002, 0xb814, 0x7006, 0x2069, 0x1800, 0xb810, 0x9005,
- 0x1140, 0xb814, 0x9005, 0x1128, 0x700b, 0x00ff, 0x700f, 0xfffe,
- 0x0020, 0x6878, 0x700a, 0x687c, 0x700e, 0x0000, 0x9485, 0x0098,
- 0x7012, 0x004e, 0x003e, 0x00de, 0x080c, 0x95c7, 0x721a, 0x7a08,
- 0x7222, 0x2f10, 0x7226, 0x2071, 0x024c, 0x002e, 0x0005, 0x080c,
- 0x95c7, 0x721a, 0x7a08, 0x7222, 0x7814, 0x7026, 0x2071, 0x024c,
- 0x002e, 0x0005, 0x00b6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x2069,
- 0x0200, 0x2071, 0x0240, 0x6004, 0x908a, 0x0085, 0x0a0c, 0x0e02,
- 0x908a, 0x0092, 0x1a0c, 0x0e02, 0x6110, 0x2158, 0xb9b0, 0x2c78,
- 0x2061, 0x0100, 0x619a, 0x9082, 0x0085, 0x0033, 0x00fe, 0x00ee,
- 0x00de, 0x00ce, 0x00be, 0x0005, 0x918b, 0x919a, 0x91a5, 0x9189,
- 0x9189, 0x9189, 0x918b, 0x9189, 0x9189, 0x9189, 0x9189, 0x9189,
- 0x9189, 0x080c, 0x0e02, 0x0411, 0x60c3, 0x0000, 0x0026, 0x080c,
- 0x29fe, 0x0228, 0x2011, 0x0101, 0x2204, 0xc0c5, 0x2012, 0x002e,
- 0x0804, 0x95d9, 0x0431, 0x7808, 0x700a, 0x7814, 0x700e, 0x7017,
- 0xffff, 0x60c3, 0x000c, 0x0804, 0x95d9, 0x04a1, 0x7003, 0x0003,
- 0x7007, 0x0300, 0x60c3, 0x0004, 0x0804, 0x95d9, 0x0026, 0x080c,
- 0x9ddd, 0xb810, 0x9085, 0x8100, 0x7002, 0xb814, 0x7006, 0x2069,
- 0x1800, 0x6878, 0x700a, 0x687c, 0x700e, 0x7013, 0x0009, 0x0804,
- 0x90ed, 0x0026, 0x080c, 0x9ddd, 0xb810, 0x9085, 0x8400, 0x7002,
- 0xb814, 0x7006, 0x2069, 0x1800, 0x6878, 0x700a, 0x687c, 0x700e,
- 0x2001, 0x0099, 0x7a20, 0x9296, 0x0005, 0x0108, 0xc0bc, 0x7012,
- 0x0804, 0x914f, 0x0026, 0x080c, 0x9ddd, 0xb810, 0x9085, 0x8500,
- 0x7002, 0xb814, 0x7006, 0x2069, 0x1800, 0x6878, 0x700a, 0x687c,
- 0x700e, 0x2001, 0x0099, 0x7a20, 0x9296, 0x0005, 0x0108, 0xc0bc,
- 0x7012, 0x0804, 0x914f, 0x00b6, 0x00c6, 0x00d6, 0x00e6, 0x00f6,
- 0x2c78, 0x2069, 0x0200, 0x2071, 0x0240, 0x7804, 0x908a, 0x0040,
- 0x0a0c, 0x0e02, 0x908a, 0x0054, 0x1a0c, 0x0e02, 0x7910, 0x2158,
- 0xb9b0, 0x2061, 0x0100, 0x619a, 0x9082, 0x0040, 0x0033, 0x00fe,
- 0x00ee, 0x00de, 0x00ce, 0x00be, 0x0005, 0x922a, 0x92f1, 0x92c4,
- 0x9413, 0x9228, 0x9228, 0x9228, 0x9228, 0x9228, 0x9228, 0x9228,
- 0x9927, 0x992c, 0x9931, 0x9936, 0x9228, 0x9d25, 0x9228, 0x9922,
- 0x080c, 0x0e02, 0x0096, 0x780b, 0xffff, 0x080c, 0x9295, 0x7914,
- 0x2148, 0xa978, 0x7956, 0xae64, 0x96b4, 0x00ff, 0x9686, 0x0008,
- 0x1148, 0xa8b4, 0x7032, 0xa8b8, 0x7036, 0xa8bc, 0x703a, 0xa8c0,
- 0x703e, 0x0008, 0x7132, 0xa97c, 0x9184, 0x000f, 0x1118, 0x2001,
- 0x0005, 0x0040, 0xd184, 0x0118, 0x2001, 0x0004, 0x0018, 0x9084,
- 0x0006, 0x8004, 0x2010, 0x785c, 0x9084, 0x00ff, 0x8007, 0x9205,
- 0x7042, 0xd1ac, 0x0158, 0x7047, 0x0002, 0x9686, 0x0008, 0x1118,
- 0x080c, 0x179e, 0x0010, 0x080c, 0x165d, 0x0050, 0xd1b4, 0x0118,
- 0x7047, 0x0001, 0x0028, 0x7047, 0x0000, 0x9016, 0x2230, 0x0010,
- 0xaab0, 0xaeac, 0x726a, 0x766e, 0x20a9, 0x0008, 0x20e9, 0x0000,
- 0xa860, 0x20e0, 0xa85c, 0x9080, 0x0023, 0x2098, 0x20a1, 0x0252,
- 0x2069, 0x0200, 0x6813, 0x0018, 0x4003, 0x6813, 0x0008, 0x60c3,
- 0x0020, 0x6017, 0x0009, 0x2001, 0x19de, 0x2003, 0x07d0, 0x2001,
- 0x19dd, 0x2003, 0x0009, 0x009e, 0x0005, 0x6813, 0x0008, 0xba8c,
- 0x8210, 0xb8bc, 0xd084, 0x0180, 0x2001, 0x1aa1, 0x200c, 0x8108,
- 0x2102, 0x2001, 0x1aa0, 0x201c, 0x1218, 0x8318, 0x2302, 0x0ea0,
- 0x794a, 0x712e, 0x7b46, 0x732a, 0x9294, 0x00ff, 0xba8e, 0x8217,
- 0x721a, 0xba10, 0x9295, 0x0600, 0x7202, 0xba14, 0x7206, 0x2069,
- 0x1800, 0x6a78, 0x720a, 0x6a7c, 0x720e, 0x7013, 0x0829, 0x2f10,
- 0x7222, 0x7027, 0xffff, 0x0005, 0x00d6, 0x0096, 0x0081, 0x7814,
- 0x2048, 0xa890, 0x7002, 0xa88c, 0x7006, 0xa8b0, 0x700a, 0xa8ac,
- 0x700e, 0x60c3, 0x000c, 0x009e, 0x00de, 0x0804, 0x95d9, 0x6813,
- 0x0008, 0xb810, 0x9085, 0x0500, 0x7002, 0xb814, 0x7006, 0x2069,
- 0x1800, 0x6878, 0x700a, 0x687c, 0x700e, 0x7013, 0x0889, 0x080c,
- 0x95c7, 0x721a, 0x7a08, 0x7222, 0x2f10, 0x7226, 0x2071, 0x024c,
- 0x0005, 0x00d6, 0x0096, 0x080c, 0x93f1, 0x7814, 0x2048, 0x080c,
- 0xbd39, 0x1130, 0x7814, 0x9084, 0x0700, 0x8007, 0x0033, 0x0010,
- 0x9006, 0x001b, 0x009e, 0x00de, 0x0005, 0x930f, 0x9378, 0x9388,
- 0x93ae, 0x93ba, 0x93cb, 0x93d3, 0x930d, 0x080c, 0x0e02, 0x0016,
- 0x0036, 0xa97c, 0x918c, 0x0003, 0x0118, 0x9186, 0x0003, 0x1198,
- 0xaba8, 0x7824, 0xd0cc, 0x1168, 0x7316, 0xa898, 0x701a, 0xa894,
- 0x701e, 0x003e, 0x001e, 0x2001, 0x198c, 0x2004, 0x60c2, 0x0804,
- 0x95d9, 0xc3e5, 0x0c88, 0x9186, 0x0001, 0x190c, 0x0e02, 0xaba8,
- 0x7824, 0xd0cc, 0x1904, 0x9375, 0x7316, 0xa898, 0x701a, 0xa894,
- 0x701e, 0xa8a4, 0x7026, 0xa8ac, 0x702e, 0x2009, 0x0018, 0x9384,
- 0x0300, 0x0570, 0xd3c4, 0x0110, 0xa8ac, 0x9108, 0xd3cc, 0x0110,
- 0xa8a4, 0x9108, 0x6810, 0x9085, 0x0010, 0x6812, 0x2011, 0x0258,
- 0x20e9, 0x0000, 0x22a0, 0x0156, 0x20a9, 0x0008, 0xa860, 0x20e0,
- 0xa85c, 0x9080, 0x002c, 0x2098, 0x4003, 0x6810, 0x8000, 0x6812,
- 0x2011, 0x0240, 0x22a0, 0x20a9, 0x0005, 0x4003, 0x6810, 0xc0a4,
- 0x6812, 0x015e, 0x9184, 0x0003, 0x0118, 0x2019, 0x0245, 0x201a,
- 0x61c2, 0x003e, 0x001e, 0x0804, 0x95d9, 0xc3e5, 0x0804, 0x9334,
- 0x2011, 0x0008, 0x2001, 0x180f, 0x2004, 0xd0a4, 0x0110, 0x2011,
- 0x0028, 0x7824, 0xd0cc, 0x1110, 0x7216, 0x0470, 0x0ce8, 0xc2e5,
- 0x2011, 0x0302, 0x0016, 0x782c, 0x701a, 0x7930, 0x711e, 0x9105,
- 0x0108, 0xc2dd, 0x001e, 0x7824, 0xd0cc, 0x0108, 0xc2e5, 0x7216,
- 0x7027, 0x0012, 0x702f, 0x0008, 0x7043, 0x7000, 0x7047, 0x0500,
- 0x704f, 0x000a, 0x2069, 0x0200, 0x6813, 0x0009, 0x2071, 0x0240,
- 0x700b, 0x2500, 0x60c3, 0x0032, 0x0804, 0x95d9, 0x2011, 0x0028,
- 0x7824, 0xd0cc, 0x1128, 0x7216, 0x60c3, 0x0018, 0x0804, 0x95d9,
- 0x0cd0, 0xc2e5, 0x2011, 0x0100, 0x7824, 0xd0cc, 0x0108, 0xc2e5,
- 0x7216, 0x702f, 0x0008, 0x7858, 0x9084, 0x00ff, 0x7036, 0x60c3,
- 0x0020, 0x0804, 0x95d9, 0x2011, 0x0008, 0x7824, 0xd0cc, 0x0108,
- 0xc2e5, 0x7216, 0x0c08, 0x0036, 0x7b14, 0x9384, 0xff00, 0x7816,
- 0x9384, 0x00ff, 0x8001, 0x1138, 0x7824, 0xd0cc, 0x0108, 0xc2e5,
- 0x7216, 0x003e, 0x0888, 0x0046, 0x2021, 0x0800, 0x0006, 0x7824,
- 0xd0cc, 0x000e, 0x0108, 0xc4e5, 0x7416, 0x004e, 0x701e, 0x003e,
- 0x0818, 0x00d6, 0x6813, 0x0008, 0xb810, 0x9085, 0x0700, 0x7002,
- 0xb814, 0x7006, 0x2069, 0x1800, 0x6878, 0x700a, 0x687c, 0x700e,
- 0x7824, 0xd0cc, 0x1168, 0x7013, 0x0898, 0x080c, 0x95c7, 0x721a,
- 0x7a08, 0x7222, 0x2f10, 0x7226, 0x2071, 0x024c, 0x00de, 0x0005,
- 0x7013, 0x0889, 0x0c90, 0x0016, 0x7814, 0x9084, 0x0700, 0x8007,
- 0x0013, 0x001e, 0x0005, 0x9423, 0x9423, 0x9425, 0x9423, 0x9423,
- 0x9423, 0x943f, 0x9423, 0x080c, 0x0e02, 0x7914, 0x918c, 0x08ff,
- 0x918d, 0xf600, 0x7916, 0x2009, 0x0003, 0x00b9, 0x2069, 0x185b,
- 0x6804, 0xd0bc, 0x0130, 0x682c, 0x9084, 0x00ff, 0x8007, 0x7032,
- 0x0010, 0x7033, 0x3f00, 0x60c3, 0x0001, 0x0804, 0x95d9, 0x2009,
- 0x0003, 0x0019, 0x7033, 0x7f00, 0x0cb0, 0x0016, 0x080c, 0x9ddd,
- 0x001e, 0xb810, 0x9085, 0x0100, 0x7002, 0xb814, 0x7006, 0x2069,
- 0x1800, 0x6a78, 0x720a, 0x6a7c, 0x720e, 0x7013, 0x0888, 0x918d,
- 0x0008, 0x7116, 0x080c, 0x95c7, 0x721a, 0x7a08, 0x7222, 0x2f10,
- 0x7226, 0x0005, 0x00b6, 0x0096, 0x00e6, 0x00d6, 0x00c6, 0x0056,
- 0x0046, 0x0036, 0x2061, 0x0100, 0x2071, 0x1800, 0x7810, 0x2058,
- 0xb8a0, 0x2028, 0xb910, 0xba14, 0x7378, 0x747c, 0x7820, 0x90be,
- 0x0006, 0x0904, 0x9536, 0x90be, 0x000a, 0x1904, 0x94f2, 0xb8b0,
- 0x609e, 0x7814, 0x2048, 0xa87c, 0xd0fc, 0x0558, 0xaf90, 0x9784,
- 0xff00, 0x9105, 0x6062, 0x873f, 0x9784, 0xff00, 0x0006, 0x7814,
- 0x2048, 0xa878, 0xc0fc, 0x9005, 0x000e, 0x1160, 0xaf94, 0x87ff,
- 0x0198, 0x2039, 0x0098, 0x9705, 0x6072, 0x7808, 0x6082, 0x2f00,
- 0x6086, 0x0038, 0x9185, 0x2200, 0x6062, 0x6073, 0x0129, 0x6077,
- 0x0000, 0xb8b0, 0x609e, 0x0050, 0x2039, 0x0029, 0x9705, 0x6072,
- 0x0cc0, 0x9185, 0x0200, 0x6062, 0x6073, 0x2029, 0xa87c, 0xd0fc,
- 0x0118, 0xaf94, 0x87ff, 0x1120, 0x2f00, 0x6082, 0x7808, 0x6086,
- 0x6266, 0x636a, 0x646e, 0x6077, 0x0000, 0xb88c, 0x8000, 0x9084,
- 0x00ff, 0xb88e, 0x8007, 0x607a, 0x607f, 0x0000, 0xa838, 0x608a,
- 0xa834, 0x608e, 0xa848, 0x60c6, 0xa844, 0x60ca, 0xb86c, 0x60ce,
- 0x60af, 0x95d5, 0x60d7, 0x0000, 0x080c, 0x9dc2, 0x2009, 0x07d0,
- 0x60c4, 0x9084, 0xfff0, 0x9005, 0x0110, 0x2009, 0x1b58, 0x080c,
- 0x82df, 0x003e, 0x004e, 0x005e, 0x00ce, 0x00de, 0x00ee, 0x009e,
- 0x00be, 0x0005, 0x7804, 0x9086, 0x0040, 0x0904, 0x9572, 0x9185,
- 0x0100, 0x6062, 0x6266, 0x636a, 0x646e, 0x6073, 0x0809, 0x6077,
- 0x0008, 0x60af, 0x95d5, 0x60d7, 0x0000, 0xb88c, 0x8000, 0x9084,
- 0x00ff, 0xb88e, 0x8007, 0x607a, 0x607f, 0x0000, 0x2f00, 0x6082,
- 0x7808, 0x6086, 0x7814, 0x2048, 0xa838, 0x608a, 0xa834, 0x608e,
- 0xa848, 0x60c6, 0xa844, 0x60ca, 0xb86c, 0x60ce, 0xbab0, 0x629e,
- 0x080c, 0x9dc2, 0x2009, 0x07d0, 0x60c4, 0x9084, 0xfff0, 0x9005,
- 0x0110, 0x2009, 0x1b58, 0x080c, 0x82df, 0x003e, 0x004e, 0x005e,
- 0x00ce, 0x00de, 0x00ee, 0x009e, 0x00be, 0x0005, 0x7814, 0x2048,
- 0xa87c, 0x9084, 0x0003, 0x9086, 0x0002, 0x0904, 0x958e, 0x9185,
- 0x0100, 0x6062, 0x6266, 0x636a, 0x646e, 0x6073, 0x0880, 0x6077,
- 0x0008, 0xb88c, 0x8000, 0x9084, 0x00ff, 0xb88e, 0x8007, 0x607a,
- 0x7838, 0x607e, 0x2f00, 0x6086, 0x7808, 0x6082, 0xa890, 0x608a,
- 0xa88c, 0x608e, 0xa8b0, 0x60c6, 0xa8ac, 0x60ca, 0xa8ac, 0x7930,
- 0x9108, 0x7932, 0xa8b0, 0x792c, 0x9109, 0x792e, 0xb86c, 0x60ce,
- 0x60af, 0x95d5, 0x60d7, 0x0000, 0xbab0, 0x629e, 0x080c, 0x9d9f,
- 0x0804, 0x9522, 0xb8bc, 0xd084, 0x0148, 0xb88c, 0x7814, 0x2048,
- 0xb88c, 0x784a, 0xa836, 0x2900, 0xa83a, 0xb046, 0x9185, 0x0600,
- 0x6062, 0x6266, 0x636a, 0x646e, 0x6073, 0x0829, 0x6077, 0x0000,
- 0x60af, 0x9575, 0x60d7, 0x0000, 0x0804, 0x9505, 0x9185, 0x0700,
- 0x6062, 0x6266, 0x636a, 0x646e, 0x7824, 0xd0cc, 0x7826, 0x0118,
- 0x6073, 0x0889, 0x0010, 0x6073, 0x0898, 0x6077, 0x0000, 0xb88c,
- 0x8000, 0x9084, 0x00ff, 0xb88e, 0x8007, 0x607a, 0x607f, 0x0000,
- 0x2f00, 0x6086, 0x7808, 0x6082, 0xa838, 0x608a, 0xa834, 0x608e,
- 0xa848, 0x60c6, 0xa844, 0x60ca, 0xb86c, 0x60ce, 0x60af, 0x95d5,
- 0x60d7, 0x0000, 0xbab0, 0x629e, 0x7824, 0xd0cc, 0x0120, 0x080c,
- 0x9dc2, 0x0804, 0x9522, 0x080c, 0x9d9f, 0x0804, 0x9522, 0x7a10,
- 0x00b6, 0x2258, 0xba8c, 0x8210, 0x9294, 0x00ff, 0xba8e, 0x00be,
- 0x8217, 0x0005, 0x00d6, 0x2069, 0x19c2, 0x6843, 0x0001, 0x00de,
- 0x0005, 0x60a3, 0x0056, 0x60a7, 0x9575, 0x00f1, 0x080c, 0x82d1,
- 0x0005, 0x0016, 0x2001, 0x180c, 0x200c, 0x9184, 0x0600, 0x9086,
- 0x0600, 0x0128, 0x0089, 0x080c, 0x82d1, 0x001e, 0x0005, 0xc1e5,
- 0x2001, 0x180c, 0x2102, 0x2001, 0x19c3, 0x2003, 0x0000, 0x2001,
- 0x19cb, 0x2003, 0x0000, 0x0c88, 0x0006, 0x6014, 0x9084, 0x1804,
- 0x9085, 0x0009, 0x6016, 0x000e, 0x0005, 0x0016, 0x00c6, 0x0006,
- 0x2061, 0x0100, 0x61a4, 0x60a7, 0x95f5, 0x6014, 0x9084, 0x1804,
- 0x9085, 0x0008, 0x6016, 0x000e, 0xa001, 0xa001, 0xa001, 0x61a6,
- 0x00ce, 0x001e, 0x0005, 0x00c6, 0x00d6, 0x0016, 0x0026, 0x2061,
- 0x0100, 0x2069, 0x0140, 0x080c, 0x717f, 0x11c0, 0x2001, 0x19de,
- 0x2004, 0x9005, 0x15d0, 0x080c, 0x7247, 0x1160, 0x2061, 0x0100,
- 0x6020, 0xd0b4, 0x1120, 0x6024, 0xd084, 0x090c, 0x0e02, 0x080c,
- 0x82d1, 0x0458, 0x00c6, 0x2061, 0x19c2, 0x00c8, 0x6904, 0x9194,
- 0x4000, 0x0540, 0x0811, 0x080c, 0x2b98, 0x00c6, 0x2061, 0x19c2,
- 0x6128, 0x9192, 0x0008, 0x1258, 0x8108, 0x612a, 0x6124, 0x00ce,
- 0x81ff, 0x0198, 0x080c, 0x82d1, 0x080c, 0x95fc, 0x0070, 0x6124,
- 0x91e5, 0x0000, 0x0140, 0x080c, 0xdb8f, 0x080c, 0x82da, 0x2009,
- 0x0014, 0x080c, 0xa053, 0x00ce, 0x0000, 0x002e, 0x001e, 0x00de,
- 0x00ce, 0x0005, 0x2001, 0x19de, 0x2004, 0x9005, 0x1db0, 0x00c6,
- 0x2061, 0x19c2, 0x6128, 0x9192, 0x0003, 0x1e08, 0x8108, 0x612a,
- 0x00ce, 0x080c, 0x82d1, 0x080c, 0x5cef, 0x2009, 0x185a, 0x2114,
- 0x8210, 0x220a, 0x0c10, 0x0096, 0x00c6, 0x00d6, 0x00e6, 0x0016,
- 0x0026, 0x080c, 0x82e7, 0x2071, 0x19c2, 0x713c, 0x81ff, 0x0904,
- 0x96f5, 0x2061, 0x0100, 0x2069, 0x0140, 0x080c, 0x717f, 0x1190,
- 0x0036, 0x2019, 0x0002, 0x080c, 0x989c, 0x003e, 0x713c, 0x2160,
- 0x080c, 0xdb8f, 0x2009, 0x004a, 0x080c, 0xa053, 0x080c, 0x7247,
- 0x0804, 0x96f5, 0x6904, 0xd1f4, 0x0904, 0x96fc, 0x080c, 0x2b98,
- 0x00c6, 0x703c, 0x9065, 0x090c, 0x0e02, 0x6020, 0x00ce, 0x9086,
- 0x0006, 0x1568, 0x61c8, 0x60c4, 0x9105, 0x1548, 0x2009, 0x180c,
- 0x2104, 0xd0d4, 0x0520, 0x6214, 0x9294, 0x1800, 0x1128, 0x6224,
- 0x9294, 0x0002, 0x1550, 0x0070, 0xc0d4, 0x200a, 0x0006, 0x2001,
- 0x0100, 0x2004, 0x9086, 0x000a, 0x000e, 0x0120, 0xd0cc, 0x0110,
- 0x080c, 0x2aca, 0x6014, 0x9084, 0xe7fd, 0x9085, 0x0010, 0x6016,
- 0x703c, 0x2060, 0x2009, 0x0049, 0x080c, 0xa053, 0x0070, 0x0036,
- 0x2019, 0x0001, 0x080c, 0x989c, 0x003e, 0x713c, 0x2160, 0x080c,
- 0xdb8f, 0x2009, 0x004a, 0x080c, 0xa053, 0x002e, 0x001e, 0x00ee,
- 0x00de, 0x00ce, 0x009e, 0x0005, 0xd1ec, 0x1904, 0x96ae, 0x0804,
- 0x96b0, 0x0026, 0x00e6, 0x2071, 0x19c2, 0x7048, 0xd084, 0x01c0,
- 0x713c, 0x81ff, 0x01a8, 0x2071, 0x0100, 0x9188, 0x0008, 0x2114,
- 0x928e, 0x0006, 0x1138, 0x7014, 0x9084, 0x1984, 0x9085, 0x0012,
- 0x7016, 0x0030, 0x7014, 0x9084, 0x1984, 0x9085, 0x0016, 0x7016,
- 0x00ee, 0x002e, 0x0005, 0x00b6, 0x00e6, 0x00d6, 0x00c6, 0x0066,
- 0x0056, 0x0046, 0x0006, 0x0126, 0x2091, 0x8000, 0x6010, 0x2058,
- 0xbca0, 0x2071, 0x19c2, 0x7018, 0x2058, 0x8bff, 0x0190, 0xb8a0,
- 0x9406, 0x0118, 0xb854, 0x2058, 0x0cc0, 0x6014, 0x0096, 0x2048,
- 0xac6c, 0xad70, 0xae78, 0x009e, 0x080c, 0x64d6, 0x0110, 0x9085,
- 0x0001, 0x012e, 0x000e, 0x004e, 0x005e, 0x006e, 0x00ce, 0x00de,
- 0x00ee, 0x00be, 0x0005, 0x080c, 0x90d2, 0x7003, 0x1200, 0x7838,
- 0x7012, 0x783c, 0x7016, 0x00c6, 0x7820, 0x9086, 0x0004, 0x1148,
- 0x7810, 0x9005, 0x0130, 0x00b6, 0x2058, 0xb810, 0xb914, 0x00be,
- 0x0020, 0x2061, 0x1800, 0x6078, 0x617c, 0x9084, 0x00ff, 0x700a,
- 0x710e, 0x00ce, 0x60c3, 0x002c, 0x0804, 0x95d9, 0x080c, 0x90d2,
- 0x7003, 0x0f00, 0x7808, 0xd09c, 0x0128, 0xb810, 0x9084, 0x00ff,
- 0x700a, 0xb814, 0x700e, 0x60c3, 0x0008, 0x0804, 0x95d9, 0x0156,
- 0x080c, 0x911d, 0x7003, 0x0200, 0x2011, 0x1848, 0x63f0, 0x2312,
- 0x20a9, 0x0006, 0x2011, 0x1840, 0x2019, 0x1841, 0x9ef0, 0x0002,
- 0x2376, 0x8e70, 0x2276, 0x8e70, 0x9398, 0x0002, 0x9290, 0x0002,
- 0x1f04, 0x9798, 0x60c3, 0x001c, 0x015e, 0x0804, 0x95d9, 0x0016,
- 0x0026, 0x080c, 0x90f9, 0x080c, 0x910b, 0x9e80, 0x0004, 0x20e9,
- 0x0000, 0x20a0, 0x7814, 0x0096, 0x2048, 0xa800, 0x2048, 0xa860,
- 0x20e0, 0xa85c, 0x9080, 0x0021, 0x2098, 0x009e, 0x7808, 0x9088,
- 0x0002, 0x21a8, 0x9192, 0x0010, 0x1250, 0x4003, 0x9080, 0x0004,
- 0x8003, 0x60c2, 0x080c, 0x95d9, 0x002e, 0x001e, 0x0005, 0x20a9,
- 0x0010, 0x4003, 0x080c, 0x9dc8, 0x20a1, 0x0240, 0x22a8, 0x4003,
- 0x0c68, 0x080c, 0x90d2, 0x7003, 0x6200, 0x7808, 0x700e, 0x60c3,
- 0x0008, 0x0804, 0x95d9, 0x0016, 0x0026, 0x080c, 0x90d2, 0x20e9,
- 0x0000, 0x20a1, 0x024c, 0x7814, 0x0096, 0x2048, 0xa800, 0x2048,
- 0xa860, 0x20e0, 0xa85c, 0x9080, 0x0023, 0x2098, 0x009e, 0x7808,
- 0x9088, 0x0002, 0x21a8, 0x4003, 0x8003, 0x60c2, 0x080c, 0x95d9,
- 0x002e, 0x001e, 0x0005, 0x00e6, 0x00c6, 0x0006, 0x0126, 0x2091,
- 0x8000, 0x2071, 0x19c2, 0x700c, 0x2060, 0x8cff, 0x0178, 0x080c,
- 0xbf43, 0x1110, 0x080c, 0xa995, 0x600c, 0x0006, 0x080c, 0xc1af,
- 0x080c, 0x9fd5, 0x080c, 0x9940, 0x00ce, 0x0c78, 0x2c00, 0x700e,
- 0x700a, 0x012e, 0x000e, 0x00ce, 0x00ee, 0x0005, 0x0126, 0x0156,
- 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x0066, 0x0026, 0x0016, 0x0006,
- 0x2091, 0x8000, 0x2001, 0x180c, 0x200c, 0x918c, 0xe7ff, 0x2102,
- 0x2069, 0x0100, 0x2079, 0x0140, 0x2071, 0x19c2, 0x7024, 0x2060,
- 0x8cff, 0x01f8, 0x080c, 0x9605, 0x6ac0, 0x68c3, 0x0000, 0x080c,
- 0x82da, 0x00c6, 0x2061, 0x0100, 0x080c, 0x9de1, 0x00ce, 0x20a9,
- 0x01f4, 0x0461, 0x2009, 0x0013, 0x080c, 0xa053, 0x000e, 0x001e,
- 0x002e, 0x006e, 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x015e, 0x012e,
- 0x0005, 0x2001, 0x1800, 0x2004, 0x9096, 0x0001, 0x0d78, 0x9096,
- 0x0004, 0x0d60, 0x080c, 0x82da, 0x6814, 0x9084, 0x0001, 0x0110,
- 0x68a7, 0x95f5, 0x6817, 0x0008, 0x68c3, 0x0000, 0x2011, 0x5c99,
- 0x080c, 0x825a, 0x20a9, 0x01f4, 0x0009, 0x08c0, 0x6824, 0xd094,
- 0x0140, 0x6827, 0x0004, 0x7804, 0x9084, 0x4000, 0x190c, 0x2b98,
- 0x0090, 0xd084, 0x0118, 0x6827, 0x0001, 0x0010, 0x1f04, 0x987e,
- 0x7804, 0x9084, 0x1000, 0x0138, 0x2001, 0x0100, 0x080c, 0x2b88,
- 0x9006, 0x080c, 0x2b88, 0x0005, 0x0126, 0x0156, 0x00f6, 0x00e6,
- 0x00d6, 0x00c6, 0x0066, 0x0026, 0x0016, 0x0006, 0x2091, 0x8000,
- 0x2001, 0x180c, 0x200c, 0x918c, 0xdbff, 0x2102, 0x2069, 0x0100,
- 0x2079, 0x0140, 0x2071, 0x19c2, 0x703c, 0x2060, 0x8cff, 0x0904,
- 0x9903, 0x9386, 0x0002, 0x1128, 0x6814, 0x9084, 0x0002, 0x0904,
- 0x9903, 0x68af, 0x95f5, 0x6817, 0x0010, 0x2009, 0x00fa, 0x8109,
- 0x1df0, 0x69c6, 0x68cb, 0x0008, 0x080c, 0x82e7, 0x080c, 0x1e34,
- 0x2001, 0x0032, 0x6920, 0xd1bc, 0x0130, 0x8001, 0x1dd8, 0x692c,
- 0x918d, 0x0008, 0x692e, 0x20a9, 0x03e8, 0x6824, 0xd094, 0x0140,
- 0x6827, 0x0004, 0x7804, 0x9084, 0x4000, 0x190c, 0x2b98, 0x0090,
- 0xd08c, 0x0118, 0x6827, 0x0002, 0x0010, 0x1f04, 0x98dd, 0x7804,
- 0x9084, 0x1000, 0x0138, 0x2001, 0x0100, 0x080c, 0x2b88, 0x9006,
- 0x080c, 0x2b88, 0x6827, 0x4000, 0x6824, 0x83ff, 0x1120, 0x2009,
- 0x0049, 0x080c, 0xa053, 0x000e, 0x001e, 0x002e, 0x006e, 0x00ce,
- 0x00de, 0x00ee, 0x00fe, 0x015e, 0x012e, 0x0005, 0x00d6, 0x0126,
- 0x2091, 0x8000, 0x2069, 0x19c2, 0x6a06, 0x012e, 0x00de, 0x0005,
- 0x00d6, 0x0126, 0x2091, 0x8000, 0x2069, 0x19c2, 0x6a32, 0x012e,
- 0x00de, 0x0005, 0x080c, 0x9295, 0x7047, 0x1000, 0x0098, 0x080c,
- 0x9295, 0x7047, 0x4000, 0x0070, 0x080c, 0x9295, 0x7047, 0x2000,
- 0x0048, 0x080c, 0x9295, 0x7047, 0x0400, 0x0020, 0x080c, 0x9295,
- 0x7047, 0x0200, 0x7854, 0x7032, 0x60c3, 0x0020, 0x0804, 0x95d9,
- 0x00e6, 0x2071, 0x19c2, 0x7020, 0x9005, 0x0110, 0x8001, 0x7022,
- 0x00ee, 0x0005, 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x0076, 0x0066,
- 0x0006, 0x0126, 0x2091, 0x8000, 0x2071, 0x19c2, 0x7614, 0x2660,
- 0x2678, 0x2039, 0x0001, 0x87ff, 0x0904, 0x99e5, 0x8cff, 0x0904,
- 0x99e5, 0x6020, 0x9086, 0x0006, 0x1904, 0x99e0, 0x88ff, 0x0138,
- 0x2800, 0x9c06, 0x1904, 0x99e0, 0x2039, 0x0000, 0x0050, 0x6010,
- 0x9b06, 0x1904, 0x99e0, 0x85ff, 0x0120, 0x6054, 0x9106, 0x1904,
- 0x99e0, 0x7024, 0x9c06, 0x15b0, 0x2069, 0x0100, 0x68c0, 0x9005,
- 0x1160, 0x6824, 0xd084, 0x0148, 0x6827, 0x0001, 0x080c, 0x82da,
- 0x080c, 0x9a6a, 0x7027, 0x0000, 0x0428, 0x080c, 0x82da, 0x6820,
- 0xd0b4, 0x0110, 0x68a7, 0x95f5, 0x6817, 0x0008, 0x68c3, 0x0000,
- 0x080c, 0x9a6a, 0x7027, 0x0000, 0x0036, 0x2069, 0x0140, 0x6b04,
- 0x9384, 0x1000, 0x0138, 0x2001, 0x0100, 0x080c, 0x2b88, 0x9006,
- 0x080c, 0x2b88, 0x2069, 0x0100, 0x6824, 0xd084, 0x0110, 0x6827,
- 0x0001, 0x003e, 0x7014, 0x9c36, 0x1110, 0x660c, 0x7616, 0x7010,
+ 0x2b6f, 0x9006, 0x080c, 0x2b6f, 0x2069, 0x0100, 0x6824, 0xd084,
+ 0x0110, 0x6827, 0x0001, 0x003e, 0x0028, 0x6003, 0x0009, 0x630a,
+ 0x0804, 0x882d, 0x7014, 0x9c36, 0x1110, 0x660c, 0x7616, 0x7010,
0x9c36, 0x1140, 0x2c00, 0x9f36, 0x0118, 0x2f00, 0x7012, 0x0010,
0x7013, 0x0000, 0x660c, 0x0066, 0x2c00, 0x9f06, 0x0110, 0x7e0e,
- 0x0008, 0x2678, 0x89ff, 0x1168, 0x600f, 0x0000, 0x6014, 0x0096,
- 0x2048, 0x080c, 0xbd39, 0x0110, 0x080c, 0xd781, 0x009e, 0x080c,
- 0xa007, 0x080c, 0x9940, 0x88ff, 0x1190, 0x00ce, 0x0804, 0x995b,
- 0x2c78, 0x600c, 0x2060, 0x0804, 0x995b, 0x9006, 0x012e, 0x000e,
- 0x006e, 0x007e, 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x0005, 0x601b,
- 0x0000, 0x00ce, 0x98c5, 0x0001, 0x0c88, 0x00f6, 0x00e6, 0x00d6,
- 0x0096, 0x00c6, 0x0066, 0x0026, 0x0006, 0x0126, 0x2091, 0x8000,
- 0x2071, 0x19c2, 0x7638, 0x2660, 0x2678, 0x8cff, 0x0904, 0x9a59,
- 0x6020, 0x9086, 0x0006, 0x1904, 0x9a54, 0x87ff, 0x0128, 0x2700,
- 0x9c06, 0x1904, 0x9a54, 0x0040, 0x6010, 0x9b06, 0x15e8, 0x85ff,
- 0x0118, 0x6054, 0x9106, 0x15c0, 0x703c, 0x9c06, 0x1168, 0x0036,
- 0x2019, 0x0001, 0x080c, 0x989c, 0x7033, 0x0000, 0x9006, 0x703e,
- 0x7042, 0x7046, 0x704a, 0x003e, 0x7038, 0x9c36, 0x1110, 0x660c,
- 0x763a, 0x7034, 0x9c36, 0x1140, 0x2c00, 0x9f36, 0x0118, 0x2f00,
- 0x7036, 0x0010, 0x7037, 0x0000, 0x660c, 0x0066, 0x2c00, 0x9f06,
- 0x0110, 0x7e0e, 0x0008, 0x2678, 0x600f, 0x0000, 0x6014, 0x2048,
- 0x080c, 0xbd39, 0x0110, 0x080c, 0xd781, 0x080c, 0xa007, 0x87ff,
- 0x1198, 0x00ce, 0x0804, 0x9a05, 0x2c78, 0x600c, 0x2060, 0x0804,
- 0x9a05, 0x9006, 0x012e, 0x000e, 0x002e, 0x006e, 0x00ce, 0x009e,
- 0x00de, 0x00ee, 0x00fe, 0x0005, 0x601b, 0x0000, 0x00ce, 0x97bd,
- 0x0001, 0x0c80, 0x00e6, 0x2071, 0x19c2, 0x2001, 0x1800, 0x2004,
- 0x9086, 0x0002, 0x1118, 0x7007, 0x0005, 0x0010, 0x7007, 0x0000,
- 0x00ee, 0x0005, 0x00f6, 0x00e6, 0x00c6, 0x0066, 0x0026, 0x0006,
- 0x0126, 0x2091, 0x8000, 0x2071, 0x19c2, 0x2c10, 0x7638, 0x2660,
- 0x2678, 0x8cff, 0x0540, 0x2200, 0x9c06, 0x1508, 0x7038, 0x9c36,
- 0x1110, 0x660c, 0x763a, 0x7034, 0x9c36, 0x1140, 0x2c00, 0x9f36,
- 0x0118, 0x2f00, 0x7036, 0x0010, 0x7037, 0x0000, 0x660c, 0x2c00,
- 0x9f06, 0x0110, 0x7e0e, 0x0008, 0x2678, 0x600f, 0x0000, 0x6004,
- 0x9086, 0x0040, 0x090c, 0x8a84, 0x9085, 0x0001, 0x0020, 0x2c78,
- 0x600c, 0x2060, 0x08b0, 0x012e, 0x000e, 0x002e, 0x006e, 0x00ce,
- 0x00ee, 0x00fe, 0x0005, 0x0096, 0x00f6, 0x00e6, 0x00d6, 0x00c6,
- 0x0066, 0x0026, 0x0006, 0x0126, 0x2091, 0x8000, 0x2071, 0x19c2,
- 0x760c, 0x2660, 0x2678, 0x8cff, 0x0904, 0x9b50, 0x6010, 0x00b6,
- 0x2058, 0xb8a0, 0x00be, 0x9206, 0x1904, 0x9b4b, 0x7024, 0x9c06,
- 0x1520, 0x2069, 0x0100, 0x68c0, 0x9005, 0x0904, 0x9b22, 0x080c,
- 0x9605, 0x68c3, 0x0000, 0x080c, 0x9a6a, 0x7027, 0x0000, 0x0036,
- 0x2069, 0x0140, 0x6b04, 0x9384, 0x1000, 0x0138, 0x2001, 0x0100,
- 0x080c, 0x2b88, 0x9006, 0x080c, 0x2b88, 0x2069, 0x0100, 0x6824,
- 0xd084, 0x0110, 0x6827, 0x0001, 0x003e, 0x700c, 0x9c36, 0x1110,
- 0x660c, 0x760e, 0x7008, 0x9c36, 0x1140, 0x2c00, 0x9f36, 0x0118,
- 0x2f00, 0x700a, 0x0010, 0x700b, 0x0000, 0x660c, 0x0066, 0x2c00,
- 0x9f06, 0x0110, 0x7e0e, 0x0008, 0x2678, 0x600f, 0x0000, 0x080c,
- 0xbf32, 0x1180, 0x080c, 0x30d4, 0x080c, 0xbf43, 0x1518, 0x080c,
- 0xa995, 0x0400, 0x080c, 0x9a6a, 0x6824, 0xd084, 0x09b0, 0x6827,
- 0x0001, 0x0898, 0x080c, 0xbf43, 0x1118, 0x080c, 0xa995, 0x0090,
- 0x6014, 0x2048, 0x080c, 0xbd39, 0x0168, 0x6020, 0x9086, 0x0003,
- 0x1508, 0xa867, 0x0103, 0xab7a, 0xa877, 0x0000, 0x080c, 0x6a16,
- 0x080c, 0xbf26, 0x080c, 0xc1af, 0x080c, 0xa007, 0x080c, 0x9940,
- 0x00ce, 0x0804, 0x9acb, 0x2c78, 0x600c, 0x2060, 0x0804, 0x9acb,
- 0x012e, 0x000e, 0x002e, 0x006e, 0x00ce, 0x00de, 0x00ee, 0x00fe,
- 0x009e, 0x0005, 0x6020, 0x9086, 0x0006, 0x1d20, 0x080c, 0xd781,
- 0x0c08, 0x00d6, 0x080c, 0x911d, 0x7003, 0x0200, 0x7007, 0x0014,
- 0x60c3, 0x0014, 0x20e1, 0x0001, 0x2099, 0x1963, 0x20e9, 0x0000,
- 0x20a1, 0x0250, 0x20a9, 0x0004, 0x4003, 0x7023, 0x0004, 0x7027,
- 0x7878, 0x080c, 0x95d9, 0x00de, 0x0005, 0x080c, 0x911d, 0x700b,
- 0x0800, 0x7814, 0x9084, 0xff00, 0x700e, 0x7814, 0x9084, 0x00ff,
- 0x7022, 0x782c, 0x7026, 0x7858, 0x9084, 0x00ff, 0x9085, 0x0200,
- 0x7002, 0x7858, 0x9084, 0xff00, 0x8007, 0x7006, 0x60c2, 0x0804,
- 0x95d9, 0x00b6, 0x00d6, 0x0016, 0x00d6, 0x2f68, 0x2009, 0x0035,
- 0x080c, 0xc3bc, 0x00de, 0x1904, 0x9bfe, 0x080c, 0x90d2, 0x7003,
- 0x1300, 0x782c, 0x080c, 0x9d04, 0x2068, 0x6820, 0x9086, 0x0003,
- 0x0560, 0x7810, 0x2058, 0xbaa0, 0x080c, 0x9f54, 0x11d8, 0x9286,
- 0x007e, 0x1128, 0x700b, 0x00ff, 0x700f, 0xfffe, 0x0498, 0x9286,
- 0x007f, 0x1128, 0x700b, 0x00ff, 0x700f, 0xfffd, 0x0458, 0x9284,
- 0xff80, 0x0180, 0x9286, 0x0080, 0x1128, 0x700b, 0x00ff, 0x700f,
- 0xfffc, 0x0400, 0x92d8, 0x1000, 0x2b5c, 0xb810, 0x700a, 0xb814,
- 0x700e, 0x00c0, 0x6098, 0x700e, 0x00a8, 0x080c, 0x9f54, 0x1130,
- 0x7810, 0x2058, 0xb8a0, 0x9082, 0x007e, 0x0250, 0x00d6, 0x2069,
- 0x181e, 0x2d04, 0x700a, 0x8d68, 0x2d04, 0x700e, 0x00de, 0x0010,
- 0x6034, 0x700e, 0x7838, 0x7012, 0x783c, 0x7016, 0x60c3, 0x000c,
- 0x001e, 0x00de, 0x080c, 0x95d9, 0x00be, 0x0005, 0x781b, 0x0001,
- 0x7803, 0x0006, 0x001e, 0x00de, 0x00be, 0x0005, 0x792c, 0x9180,
- 0x0008, 0x200c, 0x9186, 0x0006, 0x01c0, 0x9186, 0x0003, 0x0904,
- 0x9c79, 0x9186, 0x0005, 0x0904, 0x9c61, 0x9186, 0x0004, 0x05d8,
- 0x9186, 0x0008, 0x0904, 0x9c6a, 0x7807, 0x0037, 0x782f, 0x0003,
- 0x7817, 0x1700, 0x080c, 0x9ce1, 0x0005, 0x080c, 0x9ca2, 0x00d6,
- 0x0026, 0x792c, 0x2168, 0x2009, 0x4000, 0x6800, 0x0002, 0x9c42,
- 0x9c4d, 0x9c44, 0x9c4d, 0x9c49, 0x9c42, 0x9c42, 0x9c4d, 0x9c4d,
- 0x9c4d, 0x9c4d, 0x9c42, 0x9c42, 0x9c42, 0x9c42, 0x9c42, 0x9c4d,
- 0x9c42, 0x9c4d, 0x080c, 0x0e02, 0x6824, 0xd0e4, 0x0110, 0xd0cc,
- 0x0110, 0x900e, 0x0010, 0x2009, 0x2000, 0x682c, 0x7022, 0x6830,
- 0x7026, 0x0804, 0x9c9b, 0x080c, 0x9ca2, 0x00d6, 0x0026, 0x792c,
- 0x2168, 0x2009, 0x4000, 0x6a00, 0x9286, 0x0002, 0x1108, 0x900e,
- 0x04d0, 0x080c, 0x9ca2, 0x00d6, 0x0026, 0x792c, 0x2168, 0x2009,
- 0x4000, 0x0488, 0x04b9, 0x00d6, 0x0026, 0x792c, 0x2168, 0x2009,
- 0x4000, 0x9286, 0x0005, 0x0118, 0x9286, 0x0002, 0x1108, 0x900e,
- 0x0410, 0x0441, 0x00d6, 0x0026, 0x792c, 0x2168, 0x6814, 0x6924,
- 0xc185, 0x6926, 0x0096, 0x2048, 0xa9ac, 0xa834, 0x9112, 0xa9b0,
- 0xa838, 0x009e, 0x9103, 0x7022, 0x7226, 0x792c, 0x9180, 0x0000,
- 0x2004, 0x908e, 0x0002, 0x0130, 0x908e, 0x0004, 0x0118, 0x2009,
- 0x4000, 0x0008, 0x900e, 0x712a, 0x60c3, 0x0018, 0x002e, 0x00de,
- 0x0804, 0x95d9, 0x00b6, 0x0036, 0x0046, 0x0056, 0x0066, 0x080c,
- 0x911d, 0x9006, 0x7003, 0x0200, 0x7938, 0x710a, 0x793c, 0x710e,
- 0x7810, 0x2058, 0xb8a0, 0x080c, 0x9f54, 0x1118, 0x9092, 0x007e,
- 0x0268, 0x00d6, 0x2069, 0x181e, 0x2d2c, 0x8d68, 0x2d34, 0x90d8,
- 0x1000, 0x2b5c, 0xbb10, 0xbc14, 0x00de, 0x0028, 0x901e, 0x6498,
- 0x2029, 0x0000, 0x6634, 0x782c, 0x9080, 0x0008, 0x2004, 0x9086,
- 0x0003, 0x1128, 0x7512, 0x7616, 0x731a, 0x741e, 0x0020, 0x7312,
- 0x7416, 0x751a, 0x761e, 0x006e, 0x005e, 0x004e, 0x003e, 0x00be,
- 0x0005, 0x080c, 0x911d, 0x7003, 0x0100, 0x782c, 0x700a, 0x7814,
- 0x700e, 0x700e, 0x60c3, 0x0008, 0x0804, 0x95d9, 0x080c, 0x90c9,
- 0x7003, 0x1400, 0x7838, 0x700a, 0x0079, 0x783c, 0x700e, 0x782c,
- 0x7012, 0x7830, 0x7016, 0x7834, 0x9084, 0x00ff, 0x8007, 0x701a,
- 0x60c3, 0x0010, 0x0804, 0x95d9, 0x00e6, 0x2071, 0x0240, 0x0006,
- 0x00f6, 0x2078, 0x7810, 0x00b6, 0x2058, 0xb8bc, 0xd084, 0x0120,
- 0x7844, 0x702a, 0x7848, 0x702e, 0x00be, 0x00fe, 0x000e, 0x00ee,
- 0x0005, 0x080c, 0x9114, 0x7003, 0x0100, 0x782c, 0x700a, 0x7814,
- 0x700e, 0x60c3, 0x0008, 0x0804, 0x95d9, 0x0021, 0x60c3, 0x0000,
- 0x0804, 0x95d9, 0x00d6, 0x080c, 0x9ddd, 0xb810, 0x9085, 0x0300,
- 0x7002, 0xb814, 0x7006, 0x2069, 0x1800, 0x6878, 0x700a, 0x687c,
- 0x700e, 0x7013, 0x0819, 0x080c, 0x95c7, 0x721a, 0x2f10, 0x7222,
- 0x7a08, 0x7226, 0x2071, 0x024c, 0x00de, 0x0005, 0x00a9, 0x7914,
- 0x712a, 0x60c3, 0x0000, 0x60a7, 0x9575, 0x0026, 0x080c, 0x29fe,
- 0x0228, 0x2011, 0x0101, 0x2204, 0xc0c5, 0x2012, 0x002e, 0x080c,
- 0x95fc, 0x080c, 0x82d1, 0x0005, 0x0036, 0x0096, 0x00d6, 0x00e6,
- 0x7858, 0x2048, 0xaa7c, 0x9296, 0x00c0, 0x9294, 0x00fd, 0xaa7e,
- 0xaa80, 0x9294, 0x0300, 0xaa82, 0xa96c, 0x9194, 0x00ff, 0xab74,
- 0x9384, 0x00ff, 0x908d, 0xc200, 0xa96e, 0x9384, 0xff00, 0x9215,
- 0xaa76, 0xa870, 0xaa78, 0xa87a, 0xaa72, 0x00d6, 0x2069, 0x0200,
- 0x080c, 0x9ddd, 0x00de, 0x20e9, 0x0000, 0x20a1, 0x0240, 0x20a9,
- 0x000a, 0xa860, 0x20e0, 0xa85c, 0x9080, 0x001b, 0x2098, 0x4003,
- 0x60a3, 0x0035, 0xaa68, 0x9294, 0x7000, 0x9286, 0x3000, 0x0110,
- 0x60a3, 0x0037, 0x00ee, 0x00de, 0x009e, 0x003e, 0x0005, 0x900e,
- 0x7814, 0x0096, 0x2048, 0xa87c, 0xd0fc, 0x01c0, 0x9084, 0x0003,
- 0x11a8, 0x2001, 0x180c, 0x2004, 0xd0bc, 0x0180, 0x7824, 0xd0cc,
- 0x1168, 0xd0c4, 0x1158, 0xa8a8, 0x9005, 0x1140, 0x2001, 0x180c,
- 0x200c, 0xc1d5, 0x2102, 0x2009, 0x198d, 0x210c, 0x009e, 0x918d,
- 0x0092, 0x0010, 0x2009, 0x0096, 0x60ab, 0x0036, 0x6116, 0x0005,
- 0x2009, 0x0009, 0x00a0, 0x2009, 0x000a, 0x0088, 0x2009, 0x000b,
- 0x0070, 0x2009, 0x000c, 0x0058, 0x2009, 0x000d, 0x0040, 0x2009,
- 0x000e, 0x0028, 0x2009, 0x000f, 0x0010, 0x2009, 0x0008, 0x6912,
- 0x0005, 0x00d6, 0x9290, 0x0018, 0x8214, 0x20e9, 0x0000, 0x2069,
- 0x0200, 0x6813, 0x0000, 0x22a8, 0x9284, 0x00e0, 0x0128, 0x20a9,
- 0x0020, 0x9292, 0x0020, 0x0008, 0x9016, 0x20a1, 0x0240, 0x9006,
- 0x4004, 0x82ff, 0x0120, 0x6810, 0x8000, 0x6812, 0x0c60, 0x00de,
- 0x0005, 0x00d6, 0x0096, 0x6014, 0x2048, 0xa878, 0x6056, 0x9006,
- 0xa836, 0xa83a, 0xa99c, 0xa946, 0xa84a, 0x6023, 0x0003, 0x6007,
- 0x0040, 0x6003, 0x0003, 0x600b, 0xffff, 0xa817, 0x0001, 0xa842,
- 0xa83e, 0x2900, 0xa85a, 0xa813, 0x1ec0, 0x080c, 0x865e, 0x0126,
- 0x2091, 0x8000, 0x080c, 0x8c6d, 0x012e, 0x009e, 0x00de, 0x0005,
- 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x00a6, 0x0096, 0x0066, 0x0126,
- 0x2091, 0x8000, 0x2071, 0x19c2, 0x760c, 0x2660, 0x2678, 0x8cff,
- 0x0904, 0x9eb4, 0x7024, 0x9c06, 0x1520, 0x2069, 0x0100, 0x68c0,
- 0x9005, 0x0904, 0x9e86, 0x080c, 0x9605, 0x68c3, 0x0000, 0x080c,
- 0x9a6a, 0x7027, 0x0000, 0x0036, 0x2069, 0x0140, 0x6b04, 0x9384,
- 0x1000, 0x0138, 0x2001, 0x0100, 0x080c, 0x2b88, 0x9006, 0x080c,
- 0x2b88, 0x2069, 0x0100, 0x6824, 0xd084, 0x0110, 0x6827, 0x0001,
- 0x003e, 0x700c, 0x9c36, 0x1110, 0x660c, 0x760e, 0x7008, 0x9c36,
- 0x1140, 0x2c00, 0x9f36, 0x0118, 0x2f00, 0x700a, 0x0010, 0x700b,
+ 0x0008, 0x2678, 0x600f, 0x0000, 0x6014, 0x2048, 0x080c, 0xbd4e,
+ 0x01e8, 0x6020, 0x9086, 0x0003, 0x1580, 0x080c, 0xbf56, 0x1118,
+ 0x080c, 0xa9a7, 0x0098, 0xa867, 0x0103, 0xab7a, 0xa877, 0x0000,
+ 0x0016, 0x0036, 0x0086, 0x080c, 0xc044, 0x080c, 0xdae1, 0x080c,
+ 0x6a22, 0x008e, 0x003e, 0x001e, 0x080c, 0xbf39, 0x080c, 0xa01c,
+ 0x080c, 0x9955, 0x00ce, 0x0804, 0x87ab, 0x2c78, 0x600c, 0x2060,
+ 0x0804, 0x87ab, 0x012e, 0x000e, 0x001e, 0x006e, 0x00ce, 0x00de,
+ 0x00ee, 0x00fe, 0x009e, 0x00be, 0x0005, 0x6020, 0x9086, 0x0006,
+ 0x1158, 0x0016, 0x0036, 0x0086, 0x080c, 0xdae1, 0x080c, 0xd7e2,
+ 0x008e, 0x003e, 0x001e, 0x08d0, 0x080c, 0xa9a7, 0x6020, 0x9086,
+ 0x0002, 0x1160, 0x6004, 0x0006, 0x9086, 0x0085, 0x000e, 0x0904,
+ 0x8813, 0x9086, 0x008b, 0x0904, 0x8813, 0x0840, 0x6020, 0x9086,
+ 0x0005, 0x1920, 0x6004, 0x0006, 0x9086, 0x0085, 0x000e, 0x09c8,
+ 0x9086, 0x008b, 0x09b0, 0x0804, 0x8826, 0x00b6, 0x00a6, 0x0096,
+ 0x00c6, 0x0006, 0x0126, 0x2091, 0x8000, 0x9280, 0x1000, 0x2004,
+ 0x905d, 0x0904, 0x88fd, 0x00f6, 0x00e6, 0x00d6, 0x0066, 0x2071,
+ 0x19c2, 0xbe54, 0x7018, 0x9b06, 0x1108, 0x761a, 0x701c, 0x9b06,
+ 0x1130, 0x86ff, 0x1118, 0x7018, 0x701e, 0x0008, 0x761e, 0xb858,
+ 0x904d, 0x0108, 0xae56, 0x96d5, 0x0000, 0x0110, 0x2900, 0xb05a,
+ 0xb857, 0x0000, 0xb85b, 0x0000, 0xb800, 0xc0d4, 0xc0dc, 0xb802,
+ 0x080c, 0x62d6, 0x0904, 0x88f9, 0x7624, 0x86ff, 0x0904, 0x88e8,
+ 0x9680, 0x0005, 0x2004, 0x9906, 0x15d8, 0x00d6, 0x2069, 0x0100,
+ 0x68c0, 0x9005, 0x0560, 0x080c, 0x82d9, 0x080c, 0x961a, 0x68c3,
+ 0x0000, 0x080c, 0x9a7f, 0x7027, 0x0000, 0x0036, 0x2069, 0x0140,
+ 0x6b04, 0x9384, 0x1000, 0x0138, 0x2001, 0x0100, 0x080c, 0x2b6f,
+ 0x9006, 0x080c, 0x2b6f, 0x2069, 0x0100, 0x6824, 0xd084, 0x0110,
+ 0x6827, 0x0001, 0x003e, 0x00de, 0x00c6, 0xb83c, 0x9005, 0x0110,
+ 0x8001, 0xb83e, 0x2660, 0x080c, 0xa01c, 0x00ce, 0x0048, 0x00de,
+ 0x00c6, 0x2660, 0x6003, 0x0009, 0x630a, 0x00ce, 0x0804, 0x88a0,
+ 0x89ff, 0x0158, 0xa867, 0x0103, 0xab7a, 0xa877, 0x0000, 0x080c,
+ 0xc044, 0x080c, 0xdae1, 0x080c, 0x6a22, 0x080c, 0x9955, 0x0804,
+ 0x88a0, 0x006e, 0x00de, 0x00ee, 0x00fe, 0x012e, 0x000e, 0x00ce,
+ 0x009e, 0x00ae, 0x00be, 0x0005, 0x0096, 0x0006, 0x0066, 0x00c6,
+ 0x00d6, 0x9036, 0x7814, 0x9065, 0x0904, 0x8967, 0x600c, 0x0006,
+ 0x600f, 0x0000, 0x7824, 0x9c06, 0x1580, 0x2069, 0x0100, 0x6820,
+ 0xd0a4, 0x0110, 0xd0cc, 0x1508, 0x080c, 0x82d9, 0x080c, 0x961a,
+ 0x68c3, 0x0000, 0x080c, 0x9a7f, 0x7827, 0x0000, 0x0036, 0x2069,
+ 0x0140, 0x6b04, 0x9384, 0x1000, 0x0138, 0x2001, 0x0100, 0x080c,
+ 0x2b6f, 0x9006, 0x080c, 0x2b6f, 0x2069, 0x0100, 0x6824, 0xd084,
+ 0x0110, 0x6827, 0x0001, 0x003e, 0x0040, 0x080c, 0x667f, 0x1520,
+ 0x6003, 0x0009, 0x630a, 0x2c30, 0x00f8, 0x6014, 0x2048, 0x080c,
+ 0xbd4c, 0x01b0, 0x6020, 0x9086, 0x0003, 0x1508, 0x080c, 0xbf56,
+ 0x1118, 0x080c, 0xa9a7, 0x0060, 0x080c, 0x667f, 0x1168, 0xa867,
+ 0x0103, 0xab7a, 0xa877, 0x0000, 0x080c, 0x6a22, 0x080c, 0xbf39,
+ 0x080c, 0xa01c, 0x080c, 0x9955, 0x000e, 0x0804, 0x890b, 0x7e16,
+ 0x7e12, 0x00de, 0x00ce, 0x006e, 0x000e, 0x009e, 0x0005, 0x6020,
+ 0x9086, 0x0006, 0x1118, 0x080c, 0xd7e2, 0x0c50, 0x080c, 0xa9a7,
+ 0x6020, 0x9086, 0x0002, 0x1150, 0x6004, 0x0006, 0x9086, 0x0085,
+ 0x000e, 0x0990, 0x9086, 0x008b, 0x0978, 0x08d0, 0x6020, 0x9086,
+ 0x0005, 0x19b0, 0x6004, 0x0006, 0x9086, 0x0085, 0x000e, 0x0d18,
+ 0x9086, 0x008b, 0x0d00, 0x0860, 0x0006, 0x0066, 0x0096, 0x00b6,
+ 0x00c6, 0x00d6, 0x7818, 0x905d, 0x0904, 0x8a14, 0xb854, 0x0006,
+ 0x9006, 0xb856, 0xb85a, 0xb800, 0xc0d4, 0xc0dc, 0xb802, 0x080c,
+ 0x62d6, 0x0904, 0x8a11, 0x7e24, 0x86ff, 0x0904, 0x8a04, 0x9680,
+ 0x0005, 0x2004, 0x9906, 0x1904, 0x8a04, 0x00d6, 0x2069, 0x0100,
+ 0x68c0, 0x9005, 0x0904, 0x89fb, 0x080c, 0x82d9, 0x080c, 0x961a,
+ 0x68c3, 0x0000, 0x080c, 0x9a7f, 0x7827, 0x0000, 0x0036, 0x2069,
+ 0x0140, 0x6b04, 0x9384, 0x1000, 0x0138, 0x2001, 0x0100, 0x080c,
+ 0x2b6f, 0x9006, 0x080c, 0x2b6f, 0x2069, 0x0100, 0x6824, 0xd084,
+ 0x0110, 0x6827, 0x0001, 0x003e, 0x00de, 0x00c6, 0x3e08, 0x918e,
+ 0x0002, 0x1168, 0xb800, 0xd0bc, 0x0150, 0x9680, 0x0010, 0x200c,
+ 0x81ff, 0x1518, 0x2009, 0x1962, 0x210c, 0x2102, 0x00f0, 0xb83c,
+ 0x9005, 0x0110, 0x8001, 0xb83e, 0x2660, 0x600f, 0x0000, 0x080c,
+ 0xa01c, 0x00ce, 0x0048, 0x00de, 0x00c6, 0x2660, 0x6003, 0x0009,
+ 0x630a, 0x00ce, 0x0804, 0x89a7, 0x89ff, 0x0138, 0xa867, 0x0103,
+ 0xab7a, 0xa877, 0x0000, 0x080c, 0x6a22, 0x080c, 0x9955, 0x0804,
+ 0x89a7, 0x000e, 0x0804, 0x899b, 0x781e, 0x781a, 0x00de, 0x00ce,
+ 0x00be, 0x009e, 0x006e, 0x000e, 0x0005, 0x00e6, 0x00d6, 0x0096,
+ 0x0066, 0xb800, 0xd0dc, 0x01a0, 0xb84c, 0x904d, 0x0188, 0xa878,
+ 0x9606, 0x1170, 0x2071, 0x19c2, 0x7024, 0x9035, 0x0148, 0x9080,
+ 0x0005, 0x2004, 0x9906, 0x1120, 0xb800, 0xc0dc, 0xb802, 0x0029,
+ 0x006e, 0x009e, 0x00de, 0x00ee, 0x0005, 0x00f6, 0x2079, 0x0100,
+ 0x78c0, 0x9005, 0x1138, 0x00c6, 0x2660, 0x6003, 0x0009, 0x630a,
+ 0x00ce, 0x04b8, 0x080c, 0x961a, 0x78c3, 0x0000, 0x080c, 0x9a7f,
+ 0x7027, 0x0000, 0x0036, 0x2079, 0x0140, 0x7b04, 0x9384, 0x1000,
+ 0x0138, 0x2001, 0x0100, 0x080c, 0x2b6f, 0x9006, 0x080c, 0x2b6f,
+ 0x2079, 0x0100, 0x7824, 0xd084, 0x0110, 0x7827, 0x0001, 0x080c,
+ 0x9a7f, 0x003e, 0x080c, 0x62d6, 0x00c6, 0xb83c, 0x9005, 0x0110,
+ 0x8001, 0xb83e, 0x2660, 0x080c, 0x9fea, 0x00ce, 0xa867, 0x0103,
+ 0xab7a, 0xa877, 0x0000, 0x080c, 0xc044, 0x080c, 0x6a22, 0x080c,
+ 0x9955, 0x00fe, 0x0005, 0x00b6, 0x00e6, 0x00c6, 0x2011, 0x0101,
+ 0x2204, 0xc0c4, 0x2012, 0x2001, 0x180c, 0x2014, 0xc2e4, 0x2202,
+ 0x2071, 0x19c2, 0x7004, 0x9084, 0x0007, 0x0002, 0x8aa0, 0x8aa4,
+ 0x8ac2, 0x8aeb, 0x8b29, 0x8aa0, 0x8abb, 0x8a9e, 0x080c, 0x0df6,
+ 0x00ce, 0x00ee, 0x00be, 0x0005, 0x7024, 0x9065, 0x0148, 0x7020,
+ 0x8001, 0x7022, 0x600c, 0x9015, 0x0158, 0x7216, 0x600f, 0x0000,
+ 0x7007, 0x0000, 0x7027, 0x0000, 0x00ce, 0x00ee, 0x00be, 0x0005,
+ 0x7216, 0x7212, 0x0ca8, 0x7007, 0x0000, 0x7027, 0x0000, 0x7020,
+ 0x9005, 0x0070, 0x6010, 0x2058, 0x080c, 0x62d6, 0xb800, 0xc0dc,
+ 0xb802, 0x7007, 0x0000, 0x7027, 0x0000, 0x7020, 0x8001, 0x7022,
+ 0x1148, 0x2001, 0x180c, 0x2014, 0xd2ec, 0x1180, 0x00ce, 0x00ee,
+ 0x00be, 0x0005, 0xb854, 0x9015, 0x0120, 0x721e, 0x080c, 0x8b8f,
+ 0x0ca8, 0x7218, 0x721e, 0x080c, 0x8b8f, 0x0c80, 0xc2ec, 0x2202,
+ 0x080c, 0x8c6c, 0x0c58, 0x7024, 0x9065, 0x05b8, 0x700c, 0x9c06,
+ 0x1160, 0x080c, 0x9955, 0x600c, 0x9015, 0x0120, 0x720e, 0x600f,
+ 0x0000, 0x0448, 0x720e, 0x720a, 0x0430, 0x7014, 0x9c06, 0x1160,
+ 0x080c, 0x9955, 0x600c, 0x9015, 0x0120, 0x7216, 0x600f, 0x0000,
+ 0x00d0, 0x7216, 0x7212, 0x00b8, 0x6020, 0x9086, 0x0003, 0x1198,
+ 0x6010, 0x2058, 0x080c, 0x62d6, 0xb800, 0xc0dc, 0xb802, 0x080c,
+ 0x9955, 0x701c, 0x9065, 0x0138, 0xb854, 0x9015, 0x0110, 0x721e,
+ 0x0010, 0x7218, 0x721e, 0x7027, 0x0000, 0x00ce, 0x00ee, 0x00be,
+ 0x0005, 0x7024, 0x9065, 0x0140, 0x080c, 0x9955, 0x600c, 0x9015,
+ 0x0158, 0x720e, 0x600f, 0x0000, 0x080c, 0x9a7f, 0x7027, 0x0000,
+ 0x00ce, 0x00ee, 0x00be, 0x0005, 0x720e, 0x720a, 0x0ca8, 0x00d6,
+ 0x2069, 0x19c2, 0x6830, 0x9084, 0x0003, 0x0002, 0x8b4c, 0x8b4e,
+ 0x8b72, 0x8b4a, 0x080c, 0x0df6, 0x00de, 0x0005, 0x00c6, 0x6840,
+ 0x9086, 0x0001, 0x01b8, 0x683c, 0x9065, 0x0130, 0x600c, 0x9015,
+ 0x0170, 0x6a3a, 0x600f, 0x0000, 0x6833, 0x0000, 0x683f, 0x0000,
+ 0x2011, 0x19e1, 0x2013, 0x0000, 0x00ce, 0x00de, 0x0005, 0x683a,
+ 0x6836, 0x0c90, 0x6843, 0x0000, 0x6838, 0x9065, 0x0d68, 0x6003,
+ 0x0003, 0x0c50, 0x00c6, 0x9006, 0x6842, 0x6846, 0x684a, 0x683c,
+ 0x9065, 0x0160, 0x600c, 0x9015, 0x0130, 0x6a3a, 0x600f, 0x0000,
+ 0x683f, 0x0000, 0x0018, 0x683e, 0x683a, 0x6836, 0x00ce, 0x00de,
+ 0x0005, 0x2001, 0x180c, 0x200c, 0xc1e5, 0x2102, 0x0005, 0x2001,
+ 0x180c, 0x200c, 0xd1ec, 0x0120, 0xc1ec, 0x2102, 0x080c, 0x8c6c,
+ 0x2001, 0x19ce, 0x2004, 0x9086, 0x0001, 0x0d58, 0x00d6, 0x2069,
+ 0x19c2, 0x6804, 0x9084, 0x0007, 0x0002, 0x8baf, 0x8c54, 0x8c54,
+ 0x8c54, 0x8c54, 0x8c56, 0x8c54, 0x8bad, 0x080c, 0x0df6, 0x6820,
+ 0x9005, 0x1110, 0x00de, 0x0005, 0x00c6, 0x680c, 0x9065, 0x0150,
+ 0x6807, 0x0004, 0x6826, 0x682b, 0x0000, 0x080c, 0x8cc3, 0x00ce,
+ 0x00de, 0x0005, 0x6814, 0x9065, 0x0150, 0x6807, 0x0001, 0x6826,
+ 0x682b, 0x0000, 0x080c, 0x8cc3, 0x00ce, 0x00de, 0x0005, 0x00b6,
+ 0x00e6, 0x6a1c, 0x92dd, 0x0000, 0x0904, 0x8c3e, 0xb84c, 0x900d,
+ 0x0118, 0xb888, 0x9005, 0x01a0, 0xb854, 0x905d, 0x0120, 0x920e,
+ 0x0904, 0x8c3e, 0x0028, 0x6818, 0x920e, 0x0904, 0x8c3e, 0x2058,
+ 0xb84c, 0x900d, 0x0d88, 0xb888, 0x9005, 0x1d70, 0x2b00, 0x681e,
+ 0xbb3c, 0xb838, 0x9302, 0x1e40, 0x080c, 0x9fc1, 0x0904, 0x8c3e,
+ 0x8318, 0xbb3e, 0x6116, 0x2b10, 0x6212, 0x0096, 0x2148, 0xa880,
+ 0x9084, 0x00ff, 0x605e, 0xa883, 0x0000, 0xa884, 0x009e, 0x908a,
+ 0x199a, 0x0210, 0x2001, 0x1999, 0x8003, 0x801b, 0x831b, 0x9318,
+ 0x631a, 0x6114, 0x0096, 0x2148, 0xa964, 0x009e, 0x918c, 0x00ff,
+ 0x918e, 0x0048, 0x0538, 0x00f6, 0x2c78, 0x2061, 0x0100, 0xbab0,
+ 0x629a, 0x2069, 0x0200, 0x2071, 0x0240, 0x080c, 0x923f, 0x2069,
+ 0x19c2, 0xbb00, 0xc3dd, 0xbb02, 0x6807, 0x0002, 0x2f18, 0x6b26,
+ 0x682b, 0x0000, 0x7823, 0x0003, 0x7803, 0x0001, 0x7807, 0x0040,
+ 0x00fe, 0x00ee, 0x00be, 0x00ce, 0x00de, 0x0005, 0x00ee, 0x00be,
+ 0x00ce, 0x0cd0, 0x6807, 0x0006, 0x2c18, 0x6b26, 0x6820, 0x8001,
+ 0x6822, 0x682b, 0x0000, 0x080c, 0x62d6, 0x080c, 0x9e16, 0x00ee,
+ 0x00be, 0x00ce, 0x00de, 0x0005, 0x00de, 0x0005, 0x00c6, 0x680c,
+ 0x9065, 0x0138, 0x6807, 0x0004, 0x6826, 0x682b, 0x0000, 0x080c,
+ 0x8cc3, 0x00ce, 0x00de, 0x0005, 0x2001, 0x180c, 0x2014, 0xc2ed,
+ 0x2202, 0x00de, 0x00fe, 0x0005, 0x00f6, 0x00d6, 0x2069, 0x19c2,
+ 0x6830, 0x9086, 0x0000, 0x1548, 0x2001, 0x180c, 0x2014, 0xd2e4,
+ 0x0130, 0xc2e4, 0x2202, 0x080c, 0x8b9e, 0x2069, 0x19c2, 0x2001,
+ 0x180c, 0x200c, 0xd1c4, 0x11e0, 0x6838, 0x907d, 0x01b0, 0x6a04,
+ 0x9296, 0x0000, 0x1568, 0x6833, 0x0001, 0x683e, 0x6847, 0x0000,
+ 0x684b, 0x0000, 0x0126, 0x00f6, 0x2091, 0x2400, 0x002e, 0x080c,
+ 0x1b0a, 0x1158, 0x012e, 0x080c, 0x9477, 0x00de, 0x00fe, 0x0005,
+ 0xc1c4, 0x2102, 0x080c, 0x7246, 0x08f8, 0x012e, 0x6843, 0x0000,
+ 0x7803, 0x0002, 0x780c, 0x9015, 0x0140, 0x6a3a, 0x780f, 0x0000,
+ 0x6833, 0x0000, 0x683f, 0x0000, 0x0c40, 0x683a, 0x6836, 0x0cc0,
+ 0x6a04, 0x9296, 0x0006, 0x1904, 0x8c64, 0x6a30, 0x9296, 0x0000,
+ 0x0950, 0x0804, 0x8c64, 0x6020, 0x9084, 0x000f, 0x000b, 0x0005,
+ 0x8cd7, 0x8cdc, 0x916f, 0x9208, 0x8cdc, 0x916f, 0x9208, 0x8cd7,
+ 0x8cdc, 0x8cd7, 0x8cd7, 0x8cd7, 0x8cd7, 0x8cd7, 0x8cd7, 0x080c,
+ 0x8a83, 0x080c, 0x8b8f, 0x0005, 0x00b6, 0x0156, 0x0136, 0x0146,
+ 0x01c6, 0x01d6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x2069, 0x0200,
+ 0x2071, 0x0240, 0x6004, 0x908a, 0x0053, 0x1a0c, 0x0df6, 0x6110,
+ 0x2158, 0xb9b0, 0x2c78, 0x2061, 0x0100, 0x619a, 0x908a, 0x0040,
+ 0x1a04, 0x8d48, 0x005b, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x01de,
+ 0x01ce, 0x014e, 0x013e, 0x015e, 0x00be, 0x0005, 0x8ee3, 0x8f1e,
+ 0x8f47, 0x9000, 0x9021, 0x9027, 0x9034, 0x903c, 0x9048, 0x904e,
+ 0x905f, 0x904e, 0x90b6, 0x903c, 0x90c2, 0x90c8, 0x9048, 0x90c8,
+ 0x90d4, 0x8d46, 0x8d46, 0x8d46, 0x8d46, 0x8d46, 0x8d46, 0x8d46,
+ 0x8d46, 0x8d46, 0x8d46, 0x8d46, 0x9768, 0x978b, 0x979c, 0x97bc,
+ 0x97ee, 0x9034, 0x8d46, 0x9034, 0x904e, 0x8d46, 0x8f47, 0x9000,
+ 0x8d46, 0x9b76, 0x904e, 0x8d46, 0x9b92, 0x904e, 0x8d46, 0x9048,
+ 0x8edd, 0x8d69, 0x8d46, 0x9bae, 0x9c1b, 0x9cf6, 0x8d46, 0x9d03,
+ 0x9031, 0x9d2e, 0x8d46, 0x97f8, 0x9d5b, 0x8d46, 0x080c, 0x0df6,
+ 0x2100, 0x005b, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x01de, 0x01ce,
+ 0x014e, 0x013e, 0x015e, 0x00be, 0x0005, 0x8d67, 0x8d67, 0x8d67,
+ 0x8da1, 0x8e4d, 0x8e58, 0x8d67, 0x8d67, 0x8d67, 0x8eb2, 0x8ebe,
+ 0x8dbc, 0x8d67, 0x8dd7, 0x8e0b, 0x9edd, 0x9f22, 0x904e, 0x080c,
+ 0x0df6, 0x00d6, 0x0096, 0x080c, 0x90e7, 0x0026, 0x0036, 0x7814,
+ 0x2048, 0xa958, 0xd1cc, 0x1138, 0x2009, 0x2414, 0x2011, 0x0018,
+ 0x2019, 0x0018, 0x0030, 0x2009, 0x2410, 0x2011, 0x0014, 0x2019,
+ 0x0014, 0x7102, 0x7206, 0x700b, 0x0800, 0xa83c, 0x700e, 0xa850,
+ 0x7022, 0xa854, 0x7026, 0x63c2, 0x080c, 0x95ee, 0x003e, 0x002e,
+ 0x009e, 0x00de, 0x0005, 0x7810, 0x00b6, 0x2058, 0xb8a0, 0x00be,
+ 0x080c, 0x9f69, 0x1118, 0x9084, 0xff80, 0x0110, 0x9085, 0x0001,
+ 0x0005, 0x00d6, 0x0096, 0x080c, 0x90e7, 0x7003, 0x0500, 0x7814,
+ 0x2048, 0xa874, 0x700a, 0xa878, 0x700e, 0xa87c, 0x7012, 0xa880,
+ 0x7016, 0xa884, 0x701a, 0xa888, 0x701e, 0x60c3, 0x0010, 0x080c,
+ 0x95ee, 0x009e, 0x00de, 0x0005, 0x00d6, 0x0096, 0x080c, 0x90e7,
+ 0x7003, 0x0500, 0x7814, 0x2048, 0xa8cc, 0x700a, 0xa8d0, 0x700e,
+ 0xa8d4, 0x7012, 0xa8d8, 0x7016, 0xa8dc, 0x701a, 0xa8e0, 0x701e,
+ 0x60c3, 0x0010, 0x080c, 0x95ee, 0x009e, 0x00de, 0x0005, 0x00d6,
+ 0x0096, 0x0126, 0x2091, 0x8000, 0x080c, 0x90e7, 0x20e9, 0x0000,
+ 0x2001, 0x197e, 0x2003, 0x0000, 0x7814, 0x2048, 0xa814, 0x8003,
+ 0x60c2, 0xa830, 0x20a8, 0xa860, 0x20e0, 0xa85c, 0x9080, 0x001b,
+ 0x2098, 0x2001, 0x197e, 0x0016, 0x200c, 0x2001, 0x0001, 0x080c,
+ 0x21e5, 0x080c, 0xcac3, 0x9006, 0x080c, 0x21e5, 0x001e, 0xa804,
+ 0x9005, 0x0110, 0x2048, 0x0c28, 0x04d9, 0x080c, 0x95ee, 0x012e,
+ 0x009e, 0x00de, 0x0005, 0x00d6, 0x0096, 0x0126, 0x2091, 0x8000,
+ 0x080c, 0x9132, 0x20e9, 0x0000, 0x2001, 0x197e, 0x2003, 0x0000,
+ 0x7814, 0x2048, 0xa86f, 0x0200, 0xa873, 0x0000, 0xa814, 0x8003,
+ 0x60c2, 0xa830, 0x20a8, 0xa860, 0x20e0, 0xa85c, 0x9080, 0x001b,
+ 0x2098, 0x2001, 0x197e, 0x0016, 0x200c, 0x080c, 0xcac3, 0x001e,
+ 0xa804, 0x9005, 0x0110, 0x2048, 0x0c60, 0x0051, 0x7814, 0x2048,
+ 0x080c, 0x0fe9, 0x080c, 0x95ee, 0x012e, 0x009e, 0x00de, 0x0005,
+ 0x60c0, 0x8004, 0x9084, 0x0003, 0x9005, 0x0130, 0x9082, 0x0004,
+ 0x20a3, 0x0000, 0x8000, 0x1de0, 0x0005, 0x080c, 0x90e7, 0x7003,
+ 0x7800, 0x7808, 0x8007, 0x700a, 0x60c3, 0x0008, 0x0804, 0x95ee,
+ 0x00d6, 0x00e6, 0x080c, 0x9132, 0x7814, 0x9084, 0xff00, 0x2073,
+ 0x0200, 0x8e70, 0x8e70, 0x9096, 0xdf00, 0x0138, 0x9096, 0xe000,
+ 0x0120, 0x2073, 0x0010, 0x8e70, 0x0030, 0x9095, 0x0010, 0x2272,
+ 0x8e70, 0x2073, 0x0034, 0x8e70, 0x2069, 0x1805, 0x20a9, 0x0004,
+ 0x2d76, 0x8d68, 0x8e70, 0x1f04, 0x8e78, 0x2069, 0x1801, 0x20a9,
+ 0x0004, 0x2d76, 0x8d68, 0x8e70, 0x1f04, 0x8e81, 0x9096, 0xdf00,
+ 0x0130, 0x9096, 0xe000, 0x0118, 0x60c3, 0x0018, 0x00f0, 0x2069,
+ 0x198e, 0x9086, 0xdf00, 0x0110, 0x2069, 0x19a8, 0x20a9, 0x001a,
+ 0x9e86, 0x0260, 0x1148, 0x00c6, 0x2061, 0x0200, 0x6010, 0x8000,
+ 0x6012, 0x00ce, 0x2071, 0x0240, 0x2d04, 0x8007, 0x2072, 0x8d68,
+ 0x8e70, 0x1f04, 0x8e98, 0x60c3, 0x004c, 0x080c, 0x95ee, 0x00ee,
+ 0x00de, 0x0005, 0x080c, 0x90e7, 0x7003, 0x6300, 0x7007, 0x0028,
+ 0x7808, 0x700e, 0x60c3, 0x0008, 0x0804, 0x95ee, 0x00d6, 0x0026,
+ 0x0016, 0x080c, 0x9132, 0x7003, 0x0200, 0x7814, 0x700e, 0x00e6,
+ 0x9ef0, 0x0004, 0x2009, 0x0001, 0x2011, 0x000c, 0x2073, 0x0800,
+ 0x8e70, 0x2073, 0x0000, 0x00ee, 0x7206, 0x710a, 0x62c2, 0x080c,
+ 0x95ee, 0x001e, 0x002e, 0x00de, 0x0005, 0x2001, 0x1817, 0x2004,
+ 0x609a, 0x0804, 0x95ee, 0x080c, 0x90e7, 0x7003, 0x5200, 0x2069,
+ 0x185b, 0x6804, 0xd084, 0x0130, 0x6828, 0x0016, 0x080c, 0x26a0,
+ 0x710e, 0x001e, 0x20a9, 0x0004, 0x20e1, 0x0001, 0x2099, 0x1805,
+ 0x20e9, 0x0000, 0x20a1, 0x0250, 0x4003, 0x20a9, 0x0004, 0x2099,
+ 0x1801, 0x20a1, 0x0254, 0x4003, 0x080c, 0x9f69, 0x1120, 0xb8a0,
+ 0x9082, 0x007f, 0x0248, 0x2001, 0x181e, 0x2004, 0x7032, 0x2001,
+ 0x181f, 0x2004, 0x7036, 0x0030, 0x2001, 0x1817, 0x2004, 0x9084,
+ 0x00ff, 0x7036, 0x60c3, 0x001c, 0x0804, 0x95ee, 0x080c, 0x90e7,
+ 0x7003, 0x0500, 0x080c, 0x9f69, 0x1120, 0xb8a0, 0x9082, 0x007f,
+ 0x0248, 0x2001, 0x181e, 0x2004, 0x700a, 0x2001, 0x181f, 0x2004,
+ 0x700e, 0x0030, 0x2001, 0x1817, 0x2004, 0x9084, 0x00ff, 0x700e,
+ 0x20a9, 0x0004, 0x20e1, 0x0001, 0x2099, 0x1805, 0x20e9, 0x0000,
+ 0x20a1, 0x0250, 0x4003, 0x60c3, 0x0010, 0x0804, 0x95ee, 0x080c,
+ 0x90e7, 0x9006, 0x080c, 0x6693, 0xb8a0, 0x9086, 0x007e, 0x1170,
+ 0x2011, 0x0240, 0x2013, 0x22ff, 0x2011, 0x0241, 0x2013, 0xfffe,
+ 0x7003, 0x0400, 0x620c, 0xc2b4, 0x620e, 0x0058, 0x7814, 0x0096,
+ 0x904d, 0x0120, 0x9006, 0xa89a, 0xa8a6, 0xa8aa, 0x009e, 0x7003,
+ 0x0300, 0xb8a0, 0x9086, 0x007e, 0x1904, 0x8fc8, 0x00d6, 0x2069,
+ 0x1946, 0x2001, 0x1836, 0x2004, 0xd0a4, 0x0178, 0x6800, 0x700a,
+ 0x6808, 0x9084, 0x2000, 0x7012, 0x680c, 0x7016, 0x701f, 0x2710,
+ 0x6818, 0x7022, 0x681c, 0x7026, 0x00f0, 0x6800, 0x700a, 0x6804,
+ 0x700e, 0x2001, 0x0002, 0x00f6, 0x2079, 0x0100, 0x080c, 0x717e,
+ 0x1128, 0x78e3, 0x0000, 0x080c, 0x26e1, 0x78e2, 0x00fe, 0x6808,
+ 0x080c, 0x717e, 0x1118, 0x9084, 0x37ff, 0x0010, 0x9084, 0x3fff,
+ 0x7012, 0x680c, 0x7016, 0x00de, 0x20a9, 0x0004, 0x20e1, 0x0001,
+ 0x2099, 0x1805, 0x20e9, 0x0000, 0x20a1, 0x0256, 0x4003, 0x20a9,
+ 0x0004, 0x2099, 0x1801, 0x20a1, 0x025a, 0x4003, 0x00d6, 0x080c,
+ 0x9ddd, 0x2069, 0x194e, 0x2071, 0x024e, 0x6800, 0xc0dd, 0x7002,
+ 0x080c, 0x54df, 0xd0e4, 0x0110, 0x680c, 0x700e, 0x00de, 0x04a0,
+ 0x2001, 0x1836, 0x2004, 0xd0a4, 0x0168, 0x0016, 0x2009, 0x0002,
+ 0x60e0, 0x9106, 0x0130, 0x2100, 0x60e3, 0x0000, 0x080c, 0x26e1,
+ 0x61e2, 0x001e, 0x20e1, 0x0001, 0x2099, 0x1946, 0x20e9, 0x0000,
+ 0x20a1, 0x024e, 0x20a9, 0x0008, 0x4003, 0x20a9, 0x0004, 0x2099,
+ 0x1805, 0x20a1, 0x0256, 0x4003, 0x20a9, 0x0004, 0x2099, 0x1801,
+ 0x20a1, 0x025a, 0x4003, 0x080c, 0x9ddd, 0x20a1, 0x024e, 0x20a9,
+ 0x0008, 0x2099, 0x194e, 0x4003, 0x60c3, 0x0074, 0x0804, 0x95ee,
+ 0x080c, 0x90e7, 0x7003, 0x2010, 0x7007, 0x0014, 0x700b, 0x0800,
+ 0x700f, 0x2000, 0x9006, 0x00f6, 0x2079, 0x185b, 0x7904, 0x00fe,
+ 0xd1ac, 0x1110, 0x9085, 0x0020, 0x0010, 0x9085, 0x0010, 0x9085,
+ 0x0002, 0x00d6, 0x0804, 0x9097, 0x7026, 0x60c3, 0x0014, 0x0804,
+ 0x95ee, 0x080c, 0x90e7, 0x7003, 0x5000, 0x0804, 0x8f69, 0x080c,
+ 0x90e7, 0x7003, 0x2110, 0x7007, 0x0014, 0x60c3, 0x0014, 0x0804,
+ 0x95ee, 0x080c, 0x9129, 0x0010, 0x080c, 0x9132, 0x7003, 0x0200,
+ 0x60c3, 0x0004, 0x0804, 0x95ee, 0x080c, 0x9132, 0x7003, 0x0100,
+ 0x700b, 0x0003, 0x700f, 0x2a00, 0x60c3, 0x0008, 0x0804, 0x95ee,
+ 0x080c, 0x9132, 0x7003, 0x0200, 0x0804, 0x8f69, 0x080c, 0x9132,
+ 0x7003, 0x0100, 0x782c, 0x9005, 0x0110, 0x700a, 0x0010, 0x700b,
+ 0x0003, 0x7814, 0x700e, 0x60c3, 0x0008, 0x0804, 0x95ee, 0x00d6,
+ 0x080c, 0x9132, 0x7003, 0x0210, 0x7007, 0x0014, 0x700b, 0x0800,
+ 0xb894, 0x9086, 0x0014, 0x1198, 0xb99c, 0x9184, 0x0030, 0x0190,
+ 0xb998, 0x9184, 0xc000, 0x1140, 0xd1ec, 0x0118, 0x700f, 0x2100,
+ 0x0058, 0x700f, 0x0100, 0x0040, 0x700f, 0x0400, 0x0028, 0x700f,
+ 0x0700, 0x0010, 0x700f, 0x0800, 0x00f6, 0x2079, 0x185b, 0x7904,
+ 0x00fe, 0xd1ac, 0x1110, 0x9085, 0x0020, 0x0010, 0x9085, 0x0010,
+ 0x2009, 0x187d, 0x210c, 0xd184, 0x1110, 0x9085, 0x0002, 0x0026,
+ 0x2009, 0x187b, 0x210c, 0xd1e4, 0x0150, 0xc0c5, 0xbabc, 0xd28c,
+ 0x1108, 0xc0cd, 0x9094, 0x0030, 0x9296, 0x0010, 0x0140, 0xd1ec,
+ 0x0130, 0x9094, 0x0030, 0x9296, 0x0010, 0x0108, 0xc0bd, 0x002e,
+ 0x7026, 0x60c3, 0x0014, 0x00de, 0x0804, 0x95ee, 0x080c, 0x9132,
+ 0x7003, 0x0210, 0x7007, 0x0014, 0x700f, 0x0100, 0x60c3, 0x0014,
+ 0x0804, 0x95ee, 0x080c, 0x9132, 0x7003, 0x0200, 0x0804, 0x8ee7,
+ 0x080c, 0x9132, 0x7003, 0x0100, 0x700b, 0x0003, 0x700f, 0x2a00,
+ 0x60c3, 0x0008, 0x0804, 0x95ee, 0x080c, 0x9132, 0x7003, 0x0100,
+ 0x700b, 0x000b, 0x60c3, 0x0008, 0x0804, 0x95ee, 0x0026, 0x00d6,
+ 0x0036, 0x0046, 0x2019, 0x3200, 0x2021, 0x0800, 0x0040, 0x0026,
+ 0x00d6, 0x0036, 0x0046, 0x2019, 0x2200, 0x2021, 0x0100, 0x080c,
+ 0x9df2, 0xb810, 0x9305, 0x7002, 0xb814, 0x7006, 0x2069, 0x1800,
+ 0x6878, 0x700a, 0x687c, 0x700e, 0x9485, 0x0029, 0x7012, 0x004e,
+ 0x003e, 0x00de, 0x080c, 0x95dc, 0x721a, 0x9f95, 0x0000, 0x7222,
+ 0x7027, 0xffff, 0x2071, 0x024c, 0x002e, 0x0005, 0x0026, 0x080c,
+ 0x9df2, 0x7003, 0x02ff, 0x7007, 0xfffc, 0x00d6, 0x2069, 0x1800,
+ 0x6878, 0x700a, 0x687c, 0x700e, 0x00de, 0x7013, 0x2029, 0x0c10,
+ 0x7003, 0x0100, 0x7007, 0x0000, 0x700b, 0xfc02, 0x700f, 0x0000,
+ 0x0005, 0x0026, 0x00d6, 0x0036, 0x0046, 0x2019, 0x3300, 0x2021,
+ 0x0800, 0x0040, 0x0026, 0x00d6, 0x0036, 0x0046, 0x2019, 0x2300,
+ 0x2021, 0x0100, 0x080c, 0x9df2, 0xb810, 0x9305, 0x7002, 0xb814,
+ 0x7006, 0x2069, 0x1800, 0xb810, 0x9005, 0x1140, 0xb814, 0x9005,
+ 0x1128, 0x700b, 0x00ff, 0x700f, 0xfffe, 0x0020, 0x6878, 0x700a,
+ 0x687c, 0x700e, 0x0000, 0x9485, 0x0098, 0x7012, 0x004e, 0x003e,
+ 0x00de, 0x080c, 0x95dc, 0x721a, 0x7a08, 0x7222, 0x2f10, 0x7226,
+ 0x2071, 0x024c, 0x002e, 0x0005, 0x080c, 0x95dc, 0x721a, 0x7a08,
+ 0x7222, 0x7814, 0x7026, 0x2071, 0x024c, 0x002e, 0x0005, 0x00b6,
+ 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x2069, 0x0200, 0x2071, 0x0240,
+ 0x6004, 0x908a, 0x0085, 0x0a0c, 0x0df6, 0x908a, 0x0092, 0x1a0c,
+ 0x0df6, 0x6110, 0x2158, 0xb9b0, 0x2c78, 0x2061, 0x0100, 0x619a,
+ 0x9082, 0x0085, 0x0033, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x00be,
+ 0x0005, 0x91a0, 0x91af, 0x91ba, 0x919e, 0x919e, 0x919e, 0x91a0,
+ 0x919e, 0x919e, 0x919e, 0x919e, 0x919e, 0x919e, 0x080c, 0x0df6,
+ 0x0411, 0x60c3, 0x0000, 0x0026, 0x080c, 0x29e9, 0x0228, 0x2011,
+ 0x0101, 0x2204, 0xc0c5, 0x2012, 0x002e, 0x0804, 0x95ee, 0x0431,
+ 0x7808, 0x700a, 0x7814, 0x700e, 0x7017, 0xffff, 0x60c3, 0x000c,
+ 0x0804, 0x95ee, 0x04a1, 0x7003, 0x0003, 0x7007, 0x0300, 0x60c3,
+ 0x0004, 0x0804, 0x95ee, 0x0026, 0x080c, 0x9df2, 0xb810, 0x9085,
+ 0x8100, 0x7002, 0xb814, 0x7006, 0x2069, 0x1800, 0x6878, 0x700a,
+ 0x687c, 0x700e, 0x7013, 0x0009, 0x0804, 0x9102, 0x0026, 0x080c,
+ 0x9df2, 0xb810, 0x9085, 0x8400, 0x7002, 0xb814, 0x7006, 0x2069,
+ 0x1800, 0x6878, 0x700a, 0x687c, 0x700e, 0x2001, 0x0099, 0x7a20,
+ 0x9296, 0x0005, 0x0108, 0xc0bc, 0x7012, 0x0804, 0x9164, 0x0026,
+ 0x080c, 0x9df2, 0xb810, 0x9085, 0x8500, 0x7002, 0xb814, 0x7006,
+ 0x2069, 0x1800, 0x6878, 0x700a, 0x687c, 0x700e, 0x2001, 0x0099,
+ 0x7a20, 0x9296, 0x0005, 0x0108, 0xc0bc, 0x7012, 0x0804, 0x9164,
+ 0x00b6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x2c78, 0x2069, 0x0200,
+ 0x2071, 0x0240, 0x7804, 0x908a, 0x0040, 0x0a0c, 0x0df6, 0x908a,
+ 0x0054, 0x1a0c, 0x0df6, 0x7910, 0x2158, 0xb9b0, 0x2061, 0x0100,
+ 0x619a, 0x9082, 0x0040, 0x0033, 0x00fe, 0x00ee, 0x00de, 0x00ce,
+ 0x00be, 0x0005, 0x923f, 0x9306, 0x92d9, 0x9428, 0x923d, 0x923d,
+ 0x923d, 0x923d, 0x923d, 0x923d, 0x923d, 0x993c, 0x9941, 0x9946,
+ 0x994b, 0x923d, 0x9d3a, 0x923d, 0x9937, 0x080c, 0x0df6, 0x0096,
+ 0x780b, 0xffff, 0x080c, 0x92aa, 0x7914, 0x2148, 0xa978, 0x7956,
+ 0xae64, 0x96b4, 0x00ff, 0x9686, 0x0008, 0x1148, 0xa8b4, 0x7032,
+ 0xa8b8, 0x7036, 0xa8bc, 0x703a, 0xa8c0, 0x703e, 0x0008, 0x7132,
+ 0xa97c, 0x9184, 0x000f, 0x1118, 0x2001, 0x0005, 0x0040, 0xd184,
+ 0x0118, 0x2001, 0x0004, 0x0018, 0x9084, 0x0006, 0x8004, 0x2010,
+ 0x785c, 0x9084, 0x00ff, 0x8007, 0x9205, 0x7042, 0xd1ac, 0x0158,
+ 0x7047, 0x0002, 0x9686, 0x0008, 0x1118, 0x080c, 0x1792, 0x0010,
+ 0x080c, 0x1651, 0x0050, 0xd1b4, 0x0118, 0x7047, 0x0001, 0x0028,
+ 0x7047, 0x0000, 0x9016, 0x2230, 0x0010, 0xaab0, 0xaeac, 0x726a,
+ 0x766e, 0x20a9, 0x0008, 0x20e9, 0x0000, 0xa860, 0x20e0, 0xa85c,
+ 0x9080, 0x0023, 0x2098, 0x20a1, 0x0252, 0x2069, 0x0200, 0x6813,
+ 0x0018, 0x4003, 0x6813, 0x0008, 0x60c3, 0x0020, 0x6017, 0x0009,
+ 0x2001, 0x19de, 0x2003, 0x07d0, 0x2001, 0x19dd, 0x2003, 0x0009,
+ 0x009e, 0x0005, 0x6813, 0x0008, 0xba8c, 0x8210, 0xb8bc, 0xd084,
+ 0x0180, 0x2001, 0x1aa1, 0x200c, 0x8108, 0x2102, 0x2001, 0x1aa0,
+ 0x201c, 0x1218, 0x8318, 0x2302, 0x0ea0, 0x794a, 0x712e, 0x7b46,
+ 0x732a, 0x9294, 0x00ff, 0xba8e, 0x8217, 0x721a, 0xba10, 0x9295,
+ 0x0600, 0x7202, 0xba14, 0x7206, 0x2069, 0x1800, 0x6a78, 0x720a,
+ 0x6a7c, 0x720e, 0x7013, 0x0829, 0x2f10, 0x7222, 0x7027, 0xffff,
+ 0x0005, 0x00d6, 0x0096, 0x0081, 0x7814, 0x2048, 0xa890, 0x7002,
+ 0xa88c, 0x7006, 0xa8b0, 0x700a, 0xa8ac, 0x700e, 0x60c3, 0x000c,
+ 0x009e, 0x00de, 0x0804, 0x95ee, 0x6813, 0x0008, 0xb810, 0x9085,
+ 0x0500, 0x7002, 0xb814, 0x7006, 0x2069, 0x1800, 0x6878, 0x700a,
+ 0x687c, 0x700e, 0x7013, 0x0889, 0x080c, 0x95dc, 0x721a, 0x7a08,
+ 0x7222, 0x2f10, 0x7226, 0x2071, 0x024c, 0x0005, 0x00d6, 0x0096,
+ 0x080c, 0x9406, 0x7814, 0x2048, 0x080c, 0xbd4c, 0x1130, 0x7814,
+ 0x9084, 0x0700, 0x8007, 0x0033, 0x0010, 0x9006, 0x001b, 0x009e,
+ 0x00de, 0x0005, 0x9324, 0x938d, 0x939d, 0x93c3, 0x93cf, 0x93e0,
+ 0x93e8, 0x9322, 0x080c, 0x0df6, 0x0016, 0x0036, 0xa97c, 0x918c,
+ 0x0003, 0x0118, 0x9186, 0x0003, 0x1198, 0xaba8, 0x7824, 0xd0cc,
+ 0x1168, 0x7316, 0xa898, 0x701a, 0xa894, 0x701e, 0x003e, 0x001e,
+ 0x2001, 0x198c, 0x2004, 0x60c2, 0x0804, 0x95ee, 0xc3e5, 0x0c88,
+ 0x9186, 0x0001, 0x190c, 0x0df6, 0xaba8, 0x7824, 0xd0cc, 0x1904,
+ 0x938a, 0x7316, 0xa898, 0x701a, 0xa894, 0x701e, 0xa8a4, 0x7026,
+ 0xa8ac, 0x702e, 0x2009, 0x0018, 0x9384, 0x0300, 0x0570, 0xd3c4,
+ 0x0110, 0xa8ac, 0x9108, 0xd3cc, 0x0110, 0xa8a4, 0x9108, 0x6810,
+ 0x9085, 0x0010, 0x6812, 0x2011, 0x0258, 0x20e9, 0x0000, 0x22a0,
+ 0x0156, 0x20a9, 0x0008, 0xa860, 0x20e0, 0xa85c, 0x9080, 0x002c,
+ 0x2098, 0x4003, 0x6810, 0x8000, 0x6812, 0x2011, 0x0240, 0x22a0,
+ 0x20a9, 0x0005, 0x4003, 0x6810, 0xc0a4, 0x6812, 0x015e, 0x9184,
+ 0x0003, 0x0118, 0x2019, 0x0245, 0x201a, 0x61c2, 0x003e, 0x001e,
+ 0x0804, 0x95ee, 0xc3e5, 0x0804, 0x9349, 0x2011, 0x0008, 0x2001,
+ 0x180f, 0x2004, 0xd0a4, 0x0110, 0x2011, 0x0028, 0x7824, 0xd0cc,
+ 0x1110, 0x7216, 0x0470, 0x0ce8, 0xc2e5, 0x2011, 0x0302, 0x0016,
+ 0x782c, 0x701a, 0x7930, 0x711e, 0x9105, 0x0108, 0xc2dd, 0x001e,
+ 0x7824, 0xd0cc, 0x0108, 0xc2e5, 0x7216, 0x7027, 0x0012, 0x702f,
+ 0x0008, 0x7043, 0x7000, 0x7047, 0x0500, 0x704f, 0x000a, 0x2069,
+ 0x0200, 0x6813, 0x0009, 0x2071, 0x0240, 0x700b, 0x2500, 0x60c3,
+ 0x0032, 0x0804, 0x95ee, 0x2011, 0x0028, 0x7824, 0xd0cc, 0x1128,
+ 0x7216, 0x60c3, 0x0018, 0x0804, 0x95ee, 0x0cd0, 0xc2e5, 0x2011,
+ 0x0100, 0x7824, 0xd0cc, 0x0108, 0xc2e5, 0x7216, 0x702f, 0x0008,
+ 0x7858, 0x9084, 0x00ff, 0x7036, 0x60c3, 0x0020, 0x0804, 0x95ee,
+ 0x2011, 0x0008, 0x7824, 0xd0cc, 0x0108, 0xc2e5, 0x7216, 0x0c08,
+ 0x0036, 0x7b14, 0x9384, 0xff00, 0x7816, 0x9384, 0x00ff, 0x8001,
+ 0x1138, 0x7824, 0xd0cc, 0x0108, 0xc2e5, 0x7216, 0x003e, 0x0888,
+ 0x0046, 0x2021, 0x0800, 0x0006, 0x7824, 0xd0cc, 0x000e, 0x0108,
+ 0xc4e5, 0x7416, 0x004e, 0x701e, 0x003e, 0x0818, 0x00d6, 0x6813,
+ 0x0008, 0xb810, 0x9085, 0x0700, 0x7002, 0xb814, 0x7006, 0x2069,
+ 0x1800, 0x6878, 0x700a, 0x687c, 0x700e, 0x7824, 0xd0cc, 0x1168,
+ 0x7013, 0x0898, 0x080c, 0x95dc, 0x721a, 0x7a08, 0x7222, 0x2f10,
+ 0x7226, 0x2071, 0x024c, 0x00de, 0x0005, 0x7013, 0x0889, 0x0c90,
+ 0x0016, 0x7814, 0x9084, 0x0700, 0x8007, 0x0013, 0x001e, 0x0005,
+ 0x9438, 0x9438, 0x943a, 0x9438, 0x9438, 0x9438, 0x9454, 0x9438,
+ 0x080c, 0x0df6, 0x7914, 0x918c, 0x08ff, 0x918d, 0xf600, 0x7916,
+ 0x2009, 0x0003, 0x00b9, 0x2069, 0x185b, 0x6804, 0xd0bc, 0x0130,
+ 0x682c, 0x9084, 0x00ff, 0x8007, 0x7032, 0x0010, 0x7033, 0x3f00,
+ 0x60c3, 0x0001, 0x0804, 0x95ee, 0x2009, 0x0003, 0x0019, 0x7033,
+ 0x7f00, 0x0cb0, 0x0016, 0x080c, 0x9df2, 0x001e, 0xb810, 0x9085,
+ 0x0100, 0x7002, 0xb814, 0x7006, 0x2069, 0x1800, 0x6a78, 0x720a,
+ 0x6a7c, 0x720e, 0x7013, 0x0888, 0x918d, 0x0008, 0x7116, 0x080c,
+ 0x95dc, 0x721a, 0x7a08, 0x7222, 0x2f10, 0x7226, 0x0005, 0x00b6,
+ 0x0096, 0x00e6, 0x00d6, 0x00c6, 0x0056, 0x0046, 0x0036, 0x2061,
+ 0x0100, 0x2071, 0x1800, 0x7810, 0x2058, 0xb8a0, 0x2028, 0xb910,
+ 0xba14, 0x7378, 0x747c, 0x7820, 0x90be, 0x0006, 0x0904, 0x954b,
+ 0x90be, 0x000a, 0x1904, 0x9507, 0xb8b0, 0x609e, 0x7814, 0x2048,
+ 0xa87c, 0xd0fc, 0x0558, 0xaf90, 0x9784, 0xff00, 0x9105, 0x6062,
+ 0x873f, 0x9784, 0xff00, 0x0006, 0x7814, 0x2048, 0xa878, 0xc0fc,
+ 0x9005, 0x000e, 0x1160, 0xaf94, 0x87ff, 0x0198, 0x2039, 0x0098,
+ 0x9705, 0x6072, 0x7808, 0x6082, 0x2f00, 0x6086, 0x0038, 0x9185,
+ 0x2200, 0x6062, 0x6073, 0x0129, 0x6077, 0x0000, 0xb8b0, 0x609e,
+ 0x0050, 0x2039, 0x0029, 0x9705, 0x6072, 0x0cc0, 0x9185, 0x0200,
+ 0x6062, 0x6073, 0x2029, 0xa87c, 0xd0fc, 0x0118, 0xaf94, 0x87ff,
+ 0x1120, 0x2f00, 0x6082, 0x7808, 0x6086, 0x6266, 0x636a, 0x646e,
+ 0x6077, 0x0000, 0xb88c, 0x8000, 0x9084, 0x00ff, 0xb88e, 0x8007,
+ 0x607a, 0x607f, 0x0000, 0xa838, 0x608a, 0xa834, 0x608e, 0xa848,
+ 0x60c6, 0xa844, 0x60ca, 0xb86c, 0x60ce, 0x60af, 0x95d5, 0x60d7,
+ 0x0000, 0x080c, 0x9dd7, 0x2009, 0x07d0, 0x60c4, 0x9084, 0xfff0,
+ 0x9005, 0x0110, 0x2009, 0x1b58, 0x080c, 0x82de, 0x003e, 0x004e,
+ 0x005e, 0x00ce, 0x00de, 0x00ee, 0x009e, 0x00be, 0x0005, 0x7804,
+ 0x9086, 0x0040, 0x0904, 0x9587, 0x9185, 0x0100, 0x6062, 0x6266,
+ 0x636a, 0x646e, 0x6073, 0x0809, 0x6077, 0x0008, 0x60af, 0x95d5,
+ 0x60d7, 0x0000, 0xb88c, 0x8000, 0x9084, 0x00ff, 0xb88e, 0x8007,
+ 0x607a, 0x607f, 0x0000, 0x2f00, 0x6082, 0x7808, 0x6086, 0x7814,
+ 0x2048, 0xa838, 0x608a, 0xa834, 0x608e, 0xa848, 0x60c6, 0xa844,
+ 0x60ca, 0xb86c, 0x60ce, 0xbab0, 0x629e, 0x080c, 0x9dd7, 0x2009,
+ 0x07d0, 0x60c4, 0x9084, 0xfff0, 0x9005, 0x0110, 0x2009, 0x1b58,
+ 0x080c, 0x82de, 0x003e, 0x004e, 0x005e, 0x00ce, 0x00de, 0x00ee,
+ 0x009e, 0x00be, 0x0005, 0x7814, 0x2048, 0xa87c, 0x9084, 0x0003,
+ 0x9086, 0x0002, 0x0904, 0x95a3, 0x9185, 0x0100, 0x6062, 0x6266,
+ 0x636a, 0x646e, 0x6073, 0x0880, 0x6077, 0x0008, 0xb88c, 0x8000,
+ 0x9084, 0x00ff, 0xb88e, 0x8007, 0x607a, 0x7838, 0x607e, 0x2f00,
+ 0x6086, 0x7808, 0x6082, 0xa890, 0x608a, 0xa88c, 0x608e, 0xa8b0,
+ 0x60c6, 0xa8ac, 0x60ca, 0xa8ac, 0x7930, 0x9108, 0x7932, 0xa8b0,
+ 0x792c, 0x9109, 0x792e, 0xb86c, 0x60ce, 0x60af, 0x95d5, 0x60d7,
+ 0x0000, 0xbab0, 0x629e, 0x080c, 0x9db4, 0x0804, 0x9537, 0xb8bc,
+ 0xd084, 0x0148, 0xb88c, 0x7814, 0x2048, 0xb88c, 0x784a, 0xa836,
+ 0x2900, 0xa83a, 0xb046, 0x9185, 0x0600, 0x6062, 0x6266, 0x636a,
+ 0x646e, 0x6073, 0x0829, 0x6077, 0x0000, 0x60af, 0x9575, 0x60d7,
+ 0x0000, 0x0804, 0x951a, 0x9185, 0x0700, 0x6062, 0x6266, 0x636a,
+ 0x646e, 0x7824, 0xd0cc, 0x7826, 0x0118, 0x6073, 0x0889, 0x0010,
+ 0x6073, 0x0898, 0x6077, 0x0000, 0xb88c, 0x8000, 0x9084, 0x00ff,
+ 0xb88e, 0x8007, 0x607a, 0x607f, 0x0000, 0x2f00, 0x6086, 0x7808,
+ 0x6082, 0xa838, 0x608a, 0xa834, 0x608e, 0xa848, 0x60c6, 0xa844,
+ 0x60ca, 0xb86c, 0x60ce, 0x60af, 0x95d5, 0x60d7, 0x0000, 0xbab0,
+ 0x629e, 0x7824, 0xd0cc, 0x0120, 0x080c, 0x9dd7, 0x0804, 0x9537,
+ 0x080c, 0x9db4, 0x0804, 0x9537, 0x7a10, 0x00b6, 0x2258, 0xba8c,
+ 0x8210, 0x9294, 0x00ff, 0xba8e, 0x00be, 0x8217, 0x0005, 0x00d6,
+ 0x2069, 0x19c2, 0x6843, 0x0001, 0x00de, 0x0005, 0x60a3, 0x0056,
+ 0x60a7, 0x9575, 0x00f1, 0x080c, 0x82d0, 0x0005, 0x0016, 0x2001,
+ 0x180c, 0x200c, 0x9184, 0x0600, 0x9086, 0x0600, 0x0128, 0x0089,
+ 0x080c, 0x82d0, 0x001e, 0x0005, 0xc1e5, 0x2001, 0x180c, 0x2102,
+ 0x2001, 0x19c3, 0x2003, 0x0000, 0x2001, 0x19cb, 0x2003, 0x0000,
+ 0x0c88, 0x0006, 0x6014, 0x9084, 0x1804, 0x9085, 0x0009, 0x6016,
+ 0x000e, 0x0005, 0x0016, 0x00c6, 0x0006, 0x2061, 0x0100, 0x61a4,
+ 0x60a7, 0x95f5, 0x6014, 0x9084, 0x1804, 0x9085, 0x0008, 0x6016,
+ 0x000e, 0xa001, 0xa001, 0xa001, 0x61a6, 0x00ce, 0x001e, 0x0005,
+ 0x00c6, 0x00d6, 0x0016, 0x0026, 0x2061, 0x0100, 0x2069, 0x0140,
+ 0x080c, 0x717e, 0x11c0, 0x2001, 0x19de, 0x2004, 0x9005, 0x15d0,
+ 0x080c, 0x7246, 0x1160, 0x2061, 0x0100, 0x6020, 0xd0b4, 0x1120,
+ 0x6024, 0xd084, 0x090c, 0x0df6, 0x080c, 0x82d0, 0x0458, 0x00c6,
+ 0x2061, 0x19c2, 0x00c8, 0x6904, 0x9194, 0x4000, 0x0540, 0x0811,
+ 0x080c, 0x2b7f, 0x00c6, 0x2061, 0x19c2, 0x6128, 0x9192, 0x0008,
+ 0x1258, 0x8108, 0x612a, 0x6124, 0x00ce, 0x81ff, 0x0198, 0x080c,
+ 0x82d0, 0x080c, 0x9611, 0x0070, 0x6124, 0x91e5, 0x0000, 0x0140,
+ 0x080c, 0xdbf0, 0x080c, 0x82d9, 0x2009, 0x0014, 0x080c, 0xa068,
+ 0x00ce, 0x0000, 0x002e, 0x001e, 0x00de, 0x00ce, 0x0005, 0x2001,
+ 0x19de, 0x2004, 0x9005, 0x1db0, 0x00c6, 0x2061, 0x19c2, 0x6128,
+ 0x9192, 0x0003, 0x1e08, 0x8108, 0x612a, 0x00ce, 0x080c, 0x82d0,
+ 0x080c, 0x5cee, 0x2009, 0x185a, 0x2114, 0x8210, 0x220a, 0x0c10,
+ 0x0096, 0x00c6, 0x00d6, 0x00e6, 0x0016, 0x0026, 0x080c, 0x82e6,
+ 0x2071, 0x19c2, 0x713c, 0x81ff, 0x0904, 0x970a, 0x2061, 0x0100,
+ 0x2069, 0x0140, 0x080c, 0x717e, 0x1190, 0x0036, 0x2019, 0x0002,
+ 0x080c, 0x98b1, 0x003e, 0x713c, 0x2160, 0x080c, 0xdbf0, 0x2009,
+ 0x004a, 0x080c, 0xa068, 0x080c, 0x7246, 0x0804, 0x970a, 0x6904,
+ 0xd1f4, 0x0904, 0x9711, 0x080c, 0x2b7f, 0x00c6, 0x703c, 0x9065,
+ 0x090c, 0x0df6, 0x6020, 0x00ce, 0x9086, 0x0006, 0x1568, 0x61c8,
+ 0x60c4, 0x9105, 0x1548, 0x2009, 0x180c, 0x2104, 0xd0d4, 0x0520,
+ 0x6214, 0x9294, 0x1800, 0x1128, 0x6224, 0x9294, 0x0002, 0x1550,
+ 0x0070, 0xc0d4, 0x200a, 0x0006, 0x2001, 0x0100, 0x2004, 0x9086,
+ 0x000a, 0x000e, 0x0120, 0xd0cc, 0x0110, 0x080c, 0x2ab1, 0x6014,
+ 0x9084, 0xe7fd, 0x9085, 0x0010, 0x6016, 0x703c, 0x2060, 0x2009,
+ 0x0049, 0x080c, 0xa068, 0x0070, 0x0036, 0x2019, 0x0001, 0x080c,
+ 0x98b1, 0x003e, 0x713c, 0x2160, 0x080c, 0xdbf0, 0x2009, 0x004a,
+ 0x080c, 0xa068, 0x002e, 0x001e, 0x00ee, 0x00de, 0x00ce, 0x009e,
+ 0x0005, 0xd1ec, 0x1904, 0x96c3, 0x0804, 0x96c5, 0x0026, 0x00e6,
+ 0x2071, 0x19c2, 0x7048, 0xd084, 0x01c0, 0x713c, 0x81ff, 0x01a8,
+ 0x2071, 0x0100, 0x9188, 0x0008, 0x2114, 0x928e, 0x0006, 0x1138,
+ 0x7014, 0x9084, 0x1984, 0x9085, 0x0012, 0x7016, 0x0030, 0x7014,
+ 0x9084, 0x1984, 0x9085, 0x0016, 0x7016, 0x00ee, 0x002e, 0x0005,
+ 0x00b6, 0x00e6, 0x00d6, 0x00c6, 0x0066, 0x0056, 0x0046, 0x0006,
+ 0x0126, 0x2091, 0x8000, 0x6010, 0x2058, 0xbca0, 0x2071, 0x19c2,
+ 0x7018, 0x2058, 0x8bff, 0x0190, 0xb8a0, 0x9406, 0x0118, 0xb854,
+ 0x2058, 0x0cc0, 0x6014, 0x0096, 0x2048, 0xac6c, 0xad70, 0xae78,
+ 0x009e, 0x080c, 0x64d5, 0x0110, 0x9085, 0x0001, 0x012e, 0x000e,
+ 0x004e, 0x005e, 0x006e, 0x00ce, 0x00de, 0x00ee, 0x00be, 0x0005,
+ 0x080c, 0x90e7, 0x7003, 0x1200, 0x7838, 0x7012, 0x783c, 0x7016,
+ 0x00c6, 0x7820, 0x9086, 0x0004, 0x1148, 0x7810, 0x9005, 0x0130,
+ 0x00b6, 0x2058, 0xb810, 0xb914, 0x00be, 0x0020, 0x2061, 0x1800,
+ 0x6078, 0x617c, 0x9084, 0x00ff, 0x700a, 0x710e, 0x00ce, 0x60c3,
+ 0x002c, 0x0804, 0x95ee, 0x080c, 0x90e7, 0x7003, 0x0f00, 0x7808,
+ 0xd09c, 0x0128, 0xb810, 0x9084, 0x00ff, 0x700a, 0xb814, 0x700e,
+ 0x60c3, 0x0008, 0x0804, 0x95ee, 0x0156, 0x080c, 0x9132, 0x7003,
+ 0x0200, 0x2011, 0x1848, 0x63f0, 0x2312, 0x20a9, 0x0006, 0x2011,
+ 0x1840, 0x2019, 0x1841, 0x9ef0, 0x0002, 0x2376, 0x8e70, 0x2276,
+ 0x8e70, 0x9398, 0x0002, 0x9290, 0x0002, 0x1f04, 0x97ad, 0x60c3,
+ 0x001c, 0x015e, 0x0804, 0x95ee, 0x0016, 0x0026, 0x080c, 0x910e,
+ 0x080c, 0x9120, 0x9e80, 0x0004, 0x20e9, 0x0000, 0x20a0, 0x7814,
+ 0x0096, 0x2048, 0xa800, 0x2048, 0xa860, 0x20e0, 0xa85c, 0x9080,
+ 0x0021, 0x2098, 0x009e, 0x7808, 0x9088, 0x0002, 0x21a8, 0x9192,
+ 0x0010, 0x1250, 0x4003, 0x9080, 0x0004, 0x8003, 0x60c2, 0x080c,
+ 0x95ee, 0x002e, 0x001e, 0x0005, 0x20a9, 0x0010, 0x4003, 0x080c,
+ 0x9ddd, 0x20a1, 0x0240, 0x22a8, 0x4003, 0x0c68, 0x080c, 0x90e7,
+ 0x7003, 0x6200, 0x7808, 0x700e, 0x60c3, 0x0008, 0x0804, 0x95ee,
+ 0x0016, 0x0026, 0x080c, 0x90e7, 0x20e9, 0x0000, 0x20a1, 0x024c,
+ 0x7814, 0x0096, 0x2048, 0xa800, 0x2048, 0xa860, 0x20e0, 0xa85c,
+ 0x9080, 0x0023, 0x2098, 0x009e, 0x7808, 0x9088, 0x0002, 0x21a8,
+ 0x4003, 0x8003, 0x60c2, 0x080c, 0x95ee, 0x002e, 0x001e, 0x0005,
+ 0x00e6, 0x00c6, 0x0006, 0x0126, 0x2091, 0x8000, 0x2071, 0x19c2,
+ 0x700c, 0x2060, 0x8cff, 0x0178, 0x080c, 0xbf56, 0x1110, 0x080c,
+ 0xa9a7, 0x600c, 0x0006, 0x080c, 0xc1c2, 0x080c, 0x9fea, 0x080c,
+ 0x9955, 0x00ce, 0x0c78, 0x2c00, 0x700e, 0x700a, 0x012e, 0x000e,
+ 0x00ce, 0x00ee, 0x0005, 0x0126, 0x0156, 0x00f6, 0x00e6, 0x00d6,
+ 0x00c6, 0x0066, 0x0026, 0x0016, 0x0006, 0x2091, 0x8000, 0x2001,
+ 0x180c, 0x200c, 0x918c, 0xe7ff, 0x2102, 0x2069, 0x0100, 0x2079,
+ 0x0140, 0x2071, 0x19c2, 0x7024, 0x2060, 0x8cff, 0x01f8, 0x080c,
+ 0x961a, 0x6ac0, 0x68c3, 0x0000, 0x080c, 0x82d9, 0x00c6, 0x2061,
+ 0x0100, 0x080c, 0x9df6, 0x00ce, 0x20a9, 0x01f4, 0x0461, 0x2009,
+ 0x0013, 0x080c, 0xa068, 0x000e, 0x001e, 0x002e, 0x006e, 0x00ce,
+ 0x00de, 0x00ee, 0x00fe, 0x015e, 0x012e, 0x0005, 0x2001, 0x1800,
+ 0x2004, 0x9096, 0x0001, 0x0d78, 0x9096, 0x0004, 0x0d60, 0x080c,
+ 0x82d9, 0x6814, 0x9084, 0x0001, 0x0110, 0x68a7, 0x95f5, 0x6817,
+ 0x0008, 0x68c3, 0x0000, 0x2011, 0x5c98, 0x080c, 0x8259, 0x20a9,
+ 0x01f4, 0x0009, 0x08c0, 0x6824, 0xd094, 0x0140, 0x6827, 0x0004,
+ 0x7804, 0x9084, 0x4000, 0x190c, 0x2b7f, 0x0090, 0xd084, 0x0118,
+ 0x6827, 0x0001, 0x0010, 0x1f04, 0x9893, 0x7804, 0x9084, 0x1000,
+ 0x0138, 0x2001, 0x0100, 0x080c, 0x2b6f, 0x9006, 0x080c, 0x2b6f,
+ 0x0005, 0x0126, 0x0156, 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x0066,
+ 0x0026, 0x0016, 0x0006, 0x2091, 0x8000, 0x2001, 0x180c, 0x200c,
+ 0x918c, 0xdbff, 0x2102, 0x2069, 0x0100, 0x2079, 0x0140, 0x2071,
+ 0x19c2, 0x703c, 0x2060, 0x8cff, 0x0904, 0x9918, 0x9386, 0x0002,
+ 0x1128, 0x6814, 0x9084, 0x0002, 0x0904, 0x9918, 0x68af, 0x95f5,
+ 0x6817, 0x0010, 0x2009, 0x00fa, 0x8109, 0x1df0, 0x69c6, 0x68cb,
+ 0x0008, 0x080c, 0x82e6, 0x080c, 0x1e30, 0x2001, 0x0032, 0x6920,
+ 0xd1bc, 0x0130, 0x8001, 0x1dd8, 0x692c, 0x918d, 0x0008, 0x692e,
+ 0x20a9, 0x03e8, 0x6824, 0xd094, 0x0140, 0x6827, 0x0004, 0x7804,
+ 0x9084, 0x4000, 0x190c, 0x2b7f, 0x0090, 0xd08c, 0x0118, 0x6827,
+ 0x0002, 0x0010, 0x1f04, 0x98f2, 0x7804, 0x9084, 0x1000, 0x0138,
+ 0x2001, 0x0100, 0x080c, 0x2b6f, 0x9006, 0x080c, 0x2b6f, 0x6827,
+ 0x4000, 0x6824, 0x83ff, 0x1120, 0x2009, 0x0049, 0x080c, 0xa068,
+ 0x000e, 0x001e, 0x002e, 0x006e, 0x00ce, 0x00de, 0x00ee, 0x00fe,
+ 0x015e, 0x012e, 0x0005, 0x00d6, 0x0126, 0x2091, 0x8000, 0x2069,
+ 0x19c2, 0x6a06, 0x012e, 0x00de, 0x0005, 0x00d6, 0x0126, 0x2091,
+ 0x8000, 0x2069, 0x19c2, 0x6a32, 0x012e, 0x00de, 0x0005, 0x080c,
+ 0x92aa, 0x7047, 0x1000, 0x0098, 0x080c, 0x92aa, 0x7047, 0x4000,
+ 0x0070, 0x080c, 0x92aa, 0x7047, 0x2000, 0x0048, 0x080c, 0x92aa,
+ 0x7047, 0x0400, 0x0020, 0x080c, 0x92aa, 0x7047, 0x0200, 0x7854,
+ 0x7032, 0x60c3, 0x0020, 0x0804, 0x95ee, 0x00e6, 0x2071, 0x19c2,
+ 0x7020, 0x9005, 0x0110, 0x8001, 0x7022, 0x00ee, 0x0005, 0x00f6,
+ 0x00e6, 0x00d6, 0x00c6, 0x0076, 0x0066, 0x0006, 0x0126, 0x2091,
+ 0x8000, 0x2071, 0x19c2, 0x7614, 0x2660, 0x2678, 0x2039, 0x0001,
+ 0x87ff, 0x0904, 0x99fa, 0x8cff, 0x0904, 0x99fa, 0x6020, 0x9086,
+ 0x0006, 0x1904, 0x99f5, 0x88ff, 0x0138, 0x2800, 0x9c06, 0x1904,
+ 0x99f5, 0x2039, 0x0000, 0x0050, 0x6010, 0x9b06, 0x1904, 0x99f5,
+ 0x85ff, 0x0120, 0x6054, 0x9106, 0x1904, 0x99f5, 0x7024, 0x9c06,
+ 0x15b0, 0x2069, 0x0100, 0x68c0, 0x9005, 0x1160, 0x6824, 0xd084,
+ 0x0148, 0x6827, 0x0001, 0x080c, 0x82d9, 0x080c, 0x9a7f, 0x7027,
+ 0x0000, 0x0428, 0x080c, 0x82d9, 0x6820, 0xd0b4, 0x0110, 0x68a7,
+ 0x95f5, 0x6817, 0x0008, 0x68c3, 0x0000, 0x080c, 0x9a7f, 0x7027,
+ 0x0000, 0x0036, 0x2069, 0x0140, 0x6b04, 0x9384, 0x1000, 0x0138,
+ 0x2001, 0x0100, 0x080c, 0x2b6f, 0x9006, 0x080c, 0x2b6f, 0x2069,
+ 0x0100, 0x6824, 0xd084, 0x0110, 0x6827, 0x0001, 0x003e, 0x7014,
+ 0x9c36, 0x1110, 0x660c, 0x7616, 0x7010, 0x9c36, 0x1140, 0x2c00,
+ 0x9f36, 0x0118, 0x2f00, 0x7012, 0x0010, 0x7013, 0x0000, 0x660c,
+ 0x0066, 0x2c00, 0x9f06, 0x0110, 0x7e0e, 0x0008, 0x2678, 0x89ff,
+ 0x1168, 0x600f, 0x0000, 0x6014, 0x0096, 0x2048, 0x080c, 0xbd4c,
+ 0x0110, 0x080c, 0xd7e2, 0x009e, 0x080c, 0xa01c, 0x080c, 0x9955,
+ 0x88ff, 0x1190, 0x00ce, 0x0804, 0x9970, 0x2c78, 0x600c, 0x2060,
+ 0x0804, 0x9970, 0x9006, 0x012e, 0x000e, 0x006e, 0x007e, 0x00ce,
+ 0x00de, 0x00ee, 0x00fe, 0x0005, 0x601b, 0x0000, 0x00ce, 0x98c5,
+ 0x0001, 0x0c88, 0x00f6, 0x00e6, 0x00d6, 0x0096, 0x00c6, 0x0066,
+ 0x0026, 0x0006, 0x0126, 0x2091, 0x8000, 0x2071, 0x19c2, 0x7638,
+ 0x2660, 0x2678, 0x8cff, 0x0904, 0x9a6e, 0x6020, 0x9086, 0x0006,
+ 0x1904, 0x9a69, 0x87ff, 0x0128, 0x2700, 0x9c06, 0x1904, 0x9a69,
+ 0x0040, 0x6010, 0x9b06, 0x15e8, 0x85ff, 0x0118, 0x6054, 0x9106,
+ 0x15c0, 0x703c, 0x9c06, 0x1168, 0x0036, 0x2019, 0x0001, 0x080c,
+ 0x98b1, 0x7033, 0x0000, 0x9006, 0x703e, 0x7042, 0x7046, 0x704a,
+ 0x003e, 0x7038, 0x9c36, 0x1110, 0x660c, 0x763a, 0x7034, 0x9c36,
+ 0x1140, 0x2c00, 0x9f36, 0x0118, 0x2f00, 0x7036, 0x0010, 0x7037,
0x0000, 0x660c, 0x0066, 0x2c00, 0x9f06, 0x0110, 0x7e0e, 0x0008,
- 0x2678, 0x600f, 0x0000, 0x080c, 0xbf32, 0x1180, 0x080c, 0x30d4,
- 0x080c, 0xbf43, 0x1518, 0x080c, 0xa995, 0x0400, 0x080c, 0x9a6a,
- 0x6824, 0xd084, 0x09b0, 0x6827, 0x0001, 0x0898, 0x080c, 0xbf43,
- 0x1118, 0x080c, 0xa995, 0x0090, 0x6014, 0x2048, 0x080c, 0xbd39,
- 0x0168, 0x6020, 0x9086, 0x0003, 0x1520, 0xa867, 0x0103, 0xab7a,
- 0xa877, 0x0000, 0x080c, 0x6a23, 0x080c, 0xbf26, 0x080c, 0xc1af,
- 0x080c, 0xa007, 0x080c, 0x9940, 0x00ce, 0x0804, 0x9e37, 0x2c78,
- 0x600c, 0x2060, 0x0804, 0x9e37, 0x700f, 0x0000, 0x700b, 0x0000,
- 0x012e, 0x006e, 0x009e, 0x00ae, 0x00ce, 0x00de, 0x00ee, 0x00fe,
- 0x0005, 0x6020, 0x9086, 0x0006, 0x1d08, 0x080c, 0xd781, 0x08f0,
- 0x00d6, 0x0156, 0x080c, 0x911d, 0x7a14, 0x82ff, 0x0138, 0x7003,
- 0x0100, 0x700b, 0x0003, 0x60c3, 0x0008, 0x0490, 0x7003, 0x0200,
- 0x7007, 0x0000, 0x2069, 0x1800, 0x901e, 0x6800, 0x9086, 0x0004,
- 0x1110, 0xc38d, 0x0060, 0x080c, 0x717f, 0x1110, 0xc3ad, 0x0008,
- 0xc3a5, 0x6ad8, 0xd29c, 0x1110, 0xd2ac, 0x0108, 0xc39d, 0x730e,
- 0x2011, 0x1848, 0x63f0, 0x2312, 0x20a9, 0x0006, 0x2011, 0x1840,
- 0x2019, 0x1841, 0x2071, 0x0250, 0x2376, 0x8e70, 0x2276, 0x8e70,
- 0x9398, 0x0002, 0x9290, 0x0002, 0x1f04, 0x9efc, 0x60c3, 0x0020,
- 0x080c, 0x95d9, 0x015e, 0x00de, 0x0005, 0x0156, 0x080c, 0x911d,
- 0x7a14, 0x82ff, 0x0168, 0x9286, 0xffff, 0x0118, 0x9282, 0x000e,
- 0x1238, 0x7003, 0x0100, 0x700b, 0x0003, 0x60c3, 0x0008, 0x0488,
- 0x7003, 0x0200, 0x7007, 0x001c, 0x700f, 0x0001, 0x2011, 0x1998,
- 0x2204, 0x8007, 0x701a, 0x8210, 0x2204, 0x8007, 0x701e, 0x0421,
- 0x1120, 0xb8a0, 0x9082, 0x007f, 0x0248, 0x2001, 0x181e, 0x2004,
- 0x7022, 0x2001, 0x181f, 0x2004, 0x7026, 0x0030, 0x2001, 0x1817,
- 0x2004, 0x9084, 0x00ff, 0x7026, 0x20a9, 0x0004, 0x20e1, 0x0001,
- 0x2099, 0x1805, 0x20e9, 0x0000, 0x20a1, 0x0256, 0x4003, 0x60c3,
- 0x001c, 0x015e, 0x0804, 0x95d9, 0x0006, 0x2001, 0x1836, 0x2004,
- 0xd0ac, 0x000e, 0x0005, 0x2011, 0x0003, 0x080c, 0x990e, 0x2011,
- 0x0002, 0x080c, 0x9918, 0x080c, 0x9826, 0x0036, 0x901e, 0x080c,
- 0x989c, 0x003e, 0x0005, 0x2071, 0x188b, 0x7000, 0x9005, 0x0140,
- 0x2001, 0x0976, 0x2071, 0x1800, 0x7072, 0x7076, 0x7067, 0xffe0,
- 0x2071, 0x1800, 0x7070, 0x7052, 0x7057, 0x1cd0, 0x0005, 0x00e6,
- 0x0126, 0x2071, 0x1800, 0x2091, 0x8000, 0x7550, 0x9582, 0x0010,
- 0x0608, 0x7054, 0x2060, 0x6000, 0x9086, 0x0000, 0x0148, 0x9ce0,
- 0x0018, 0x7064, 0x9c02, 0x1208, 0x0cb0, 0x2061, 0x1cd0, 0x0c98,
- 0x6003, 0x0008, 0x8529, 0x7552, 0x9ca8, 0x0018, 0x7064, 0x9502,
- 0x1230, 0x7556, 0x9085, 0x0001, 0x012e, 0x00ee, 0x0005, 0x7057,
- 0x1cd0, 0x0cc0, 0x9006, 0x0cc0, 0x00e6, 0x2071, 0x1800, 0x7550,
- 0x9582, 0x0010, 0x0600, 0x7054, 0x2060, 0x6000, 0x9086, 0x0000,
- 0x0148, 0x9ce0, 0x0018, 0x7064, 0x9c02, 0x1208, 0x0cb0, 0x2061,
- 0x1cd0, 0x0c98, 0x6003, 0x0008, 0x8529, 0x7552, 0x9ca8, 0x0018,
- 0x7064, 0x9502, 0x1228, 0x7556, 0x9085, 0x0001, 0x00ee, 0x0005,
- 0x7057, 0x1cd0, 0x0cc8, 0x9006, 0x0cc8, 0x9c82, 0x1cd0, 0x0a0c,
- 0x0e02, 0x2001, 0x1819, 0x2004, 0x9c02, 0x1a0c, 0x0e02, 0x9006,
- 0x6006, 0x600a, 0x600e, 0x6016, 0x601a, 0x6012, 0x6023, 0x0000,
- 0x6003, 0x0000, 0x601e, 0x6056, 0x605a, 0x6026, 0x602a, 0x602e,
- 0x6032, 0x6036, 0x603a, 0x603e, 0x6042, 0x2061, 0x1800, 0x6050,
- 0x8000, 0x6052, 0x9086, 0x0001, 0x0108, 0x0005, 0x0126, 0x2091,
- 0x8000, 0x0016, 0x080c, 0x8b90, 0x001e, 0x012e, 0x0cb0, 0x0006,
- 0x6000, 0x9086, 0x0000, 0x01c0, 0x601c, 0xd084, 0x190c, 0x1938,
- 0x6017, 0x0000, 0x6023, 0x0007, 0x2001, 0x1960, 0x2004, 0x0006,
- 0x9082, 0x0051, 0x000e, 0x0208, 0x8004, 0x601a, 0x080c, 0xda33,
- 0x6043, 0x0000, 0x6013, 0x0000, 0x000e, 0x0005, 0x00e6, 0x0126,
- 0x2071, 0x1800, 0x2091, 0x8000, 0x7550, 0x9582, 0x0001, 0x0608,
+ 0x2678, 0x600f, 0x0000, 0x6014, 0x2048, 0x080c, 0xbd4c, 0x0110,
+ 0x080c, 0xd7e2, 0x080c, 0xa01c, 0x87ff, 0x1198, 0x00ce, 0x0804,
+ 0x9a1a, 0x2c78, 0x600c, 0x2060, 0x0804, 0x9a1a, 0x9006, 0x012e,
+ 0x000e, 0x002e, 0x006e, 0x00ce, 0x009e, 0x00de, 0x00ee, 0x00fe,
+ 0x0005, 0x601b, 0x0000, 0x00ce, 0x97bd, 0x0001, 0x0c80, 0x00e6,
+ 0x2071, 0x19c2, 0x2001, 0x1800, 0x2004, 0x9086, 0x0002, 0x1118,
+ 0x7007, 0x0005, 0x0010, 0x7007, 0x0000, 0x00ee, 0x0005, 0x00f6,
+ 0x00e6, 0x00c6, 0x0066, 0x0026, 0x0006, 0x0126, 0x2091, 0x8000,
+ 0x2071, 0x19c2, 0x2c10, 0x7638, 0x2660, 0x2678, 0x8cff, 0x0540,
+ 0x2200, 0x9c06, 0x1508, 0x7038, 0x9c36, 0x1110, 0x660c, 0x763a,
+ 0x7034, 0x9c36, 0x1140, 0x2c00, 0x9f36, 0x0118, 0x2f00, 0x7036,
+ 0x0010, 0x7037, 0x0000, 0x660c, 0x2c00, 0x9f06, 0x0110, 0x7e0e,
+ 0x0008, 0x2678, 0x600f, 0x0000, 0x6004, 0x9086, 0x0040, 0x090c,
+ 0x8a83, 0x9085, 0x0001, 0x0020, 0x2c78, 0x600c, 0x2060, 0x08b0,
+ 0x012e, 0x000e, 0x002e, 0x006e, 0x00ce, 0x00ee, 0x00fe, 0x0005,
+ 0x0096, 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x0066, 0x0026, 0x0006,
+ 0x0126, 0x2091, 0x8000, 0x2071, 0x19c2, 0x760c, 0x2660, 0x2678,
+ 0x8cff, 0x0904, 0x9b65, 0x6010, 0x00b6, 0x2058, 0xb8a0, 0x00be,
+ 0x9206, 0x1904, 0x9b60, 0x7024, 0x9c06, 0x1520, 0x2069, 0x0100,
+ 0x68c0, 0x9005, 0x0904, 0x9b37, 0x080c, 0x961a, 0x68c3, 0x0000,
+ 0x080c, 0x9a7f, 0x7027, 0x0000, 0x0036, 0x2069, 0x0140, 0x6b04,
+ 0x9384, 0x1000, 0x0138, 0x2001, 0x0100, 0x080c, 0x2b6f, 0x9006,
+ 0x080c, 0x2b6f, 0x2069, 0x0100, 0x6824, 0xd084, 0x0110, 0x6827,
+ 0x0001, 0x003e, 0x700c, 0x9c36, 0x1110, 0x660c, 0x760e, 0x7008,
+ 0x9c36, 0x1140, 0x2c00, 0x9f36, 0x0118, 0x2f00, 0x700a, 0x0010,
+ 0x700b, 0x0000, 0x660c, 0x0066, 0x2c00, 0x9f06, 0x0110, 0x7e0e,
+ 0x0008, 0x2678, 0x600f, 0x0000, 0x080c, 0xbf45, 0x1180, 0x080c,
+ 0x30be, 0x080c, 0xbf56, 0x1518, 0x080c, 0xa9a7, 0x0400, 0x080c,
+ 0x9a7f, 0x6824, 0xd084, 0x09b0, 0x6827, 0x0001, 0x0898, 0x080c,
+ 0xbf56, 0x1118, 0x080c, 0xa9a7, 0x0090, 0x6014, 0x2048, 0x080c,
+ 0xbd4c, 0x0168, 0x6020, 0x9086, 0x0003, 0x1508, 0xa867, 0x0103,
+ 0xab7a, 0xa877, 0x0000, 0x080c, 0x6a15, 0x080c, 0xbf39, 0x080c,
+ 0xc1c2, 0x080c, 0xa01c, 0x080c, 0x9955, 0x00ce, 0x0804, 0x9ae0,
+ 0x2c78, 0x600c, 0x2060, 0x0804, 0x9ae0, 0x012e, 0x000e, 0x002e,
+ 0x006e, 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x009e, 0x0005, 0x6020,
+ 0x9086, 0x0006, 0x1d20, 0x080c, 0xd7e2, 0x0c08, 0x00d6, 0x080c,
+ 0x9132, 0x7003, 0x0200, 0x7007, 0x0014, 0x60c3, 0x0014, 0x20e1,
+ 0x0001, 0x2099, 0x1963, 0x20e9, 0x0000, 0x20a1, 0x0250, 0x20a9,
+ 0x0004, 0x4003, 0x7023, 0x0004, 0x7027, 0x7878, 0x080c, 0x95ee,
+ 0x00de, 0x0005, 0x080c, 0x9132, 0x700b, 0x0800, 0x7814, 0x9084,
+ 0xff00, 0x700e, 0x7814, 0x9084, 0x00ff, 0x7022, 0x782c, 0x7026,
+ 0x7858, 0x9084, 0x00ff, 0x9085, 0x0200, 0x7002, 0x7858, 0x9084,
+ 0xff00, 0x8007, 0x7006, 0x60c2, 0x0804, 0x95ee, 0x00b6, 0x00d6,
+ 0x0016, 0x00d6, 0x2f68, 0x2009, 0x0035, 0x080c, 0xc3cf, 0x00de,
+ 0x1904, 0x9c13, 0x080c, 0x90e7, 0x7003, 0x1300, 0x782c, 0x080c,
+ 0x9d19, 0x2068, 0x6820, 0x9086, 0x0003, 0x0560, 0x7810, 0x2058,
+ 0xbaa0, 0x080c, 0x9f69, 0x11d8, 0x9286, 0x007e, 0x1128, 0x700b,
+ 0x00ff, 0x700f, 0xfffe, 0x0498, 0x9286, 0x007f, 0x1128, 0x700b,
+ 0x00ff, 0x700f, 0xfffd, 0x0458, 0x9284, 0xff80, 0x0180, 0x9286,
+ 0x0080, 0x1128, 0x700b, 0x00ff, 0x700f, 0xfffc, 0x0400, 0x92d8,
+ 0x1000, 0x2b5c, 0xb810, 0x700a, 0xb814, 0x700e, 0x00c0, 0x6098,
+ 0x700e, 0x00a8, 0x080c, 0x9f69, 0x1130, 0x7810, 0x2058, 0xb8a0,
+ 0x9082, 0x007e, 0x0250, 0x00d6, 0x2069, 0x181e, 0x2d04, 0x700a,
+ 0x8d68, 0x2d04, 0x700e, 0x00de, 0x0010, 0x6034, 0x700e, 0x7838,
+ 0x7012, 0x783c, 0x7016, 0x60c3, 0x000c, 0x001e, 0x00de, 0x080c,
+ 0x95ee, 0x00be, 0x0005, 0x781b, 0x0001, 0x7803, 0x0006, 0x001e,
+ 0x00de, 0x00be, 0x0005, 0x792c, 0x9180, 0x0008, 0x200c, 0x9186,
+ 0x0006, 0x01c0, 0x9186, 0x0003, 0x0904, 0x9c8e, 0x9186, 0x0005,
+ 0x0904, 0x9c76, 0x9186, 0x0004, 0x05d8, 0x9186, 0x0008, 0x0904,
+ 0x9c7f, 0x7807, 0x0037, 0x782f, 0x0003, 0x7817, 0x1700, 0x080c,
+ 0x9cf6, 0x0005, 0x080c, 0x9cb7, 0x00d6, 0x0026, 0x792c, 0x2168,
+ 0x2009, 0x4000, 0x6800, 0x0002, 0x9c57, 0x9c62, 0x9c59, 0x9c62,
+ 0x9c5e, 0x9c57, 0x9c57, 0x9c62, 0x9c62, 0x9c62, 0x9c62, 0x9c57,
+ 0x9c57, 0x9c57, 0x9c57, 0x9c57, 0x9c62, 0x9c57, 0x9c62, 0x080c,
+ 0x0df6, 0x6824, 0xd0e4, 0x0110, 0xd0cc, 0x0110, 0x900e, 0x0010,
+ 0x2009, 0x2000, 0x682c, 0x7022, 0x6830, 0x7026, 0x0804, 0x9cb0,
+ 0x080c, 0x9cb7, 0x00d6, 0x0026, 0x792c, 0x2168, 0x2009, 0x4000,
+ 0x6a00, 0x9286, 0x0002, 0x1108, 0x900e, 0x04d0, 0x080c, 0x9cb7,
+ 0x00d6, 0x0026, 0x792c, 0x2168, 0x2009, 0x4000, 0x0488, 0x04b9,
+ 0x00d6, 0x0026, 0x792c, 0x2168, 0x2009, 0x4000, 0x9286, 0x0005,
+ 0x0118, 0x9286, 0x0002, 0x1108, 0x900e, 0x0410, 0x0441, 0x00d6,
+ 0x0026, 0x792c, 0x2168, 0x6814, 0x6924, 0xc185, 0x6926, 0x0096,
+ 0x2048, 0xa9ac, 0xa834, 0x9112, 0xa9b0, 0xa838, 0x009e, 0x9103,
+ 0x7022, 0x7226, 0x792c, 0x9180, 0x0000, 0x2004, 0x908e, 0x0002,
+ 0x0130, 0x908e, 0x0004, 0x0118, 0x2009, 0x4000, 0x0008, 0x900e,
+ 0x712a, 0x60c3, 0x0018, 0x002e, 0x00de, 0x0804, 0x95ee, 0x00b6,
+ 0x0036, 0x0046, 0x0056, 0x0066, 0x080c, 0x9132, 0x9006, 0x7003,
+ 0x0200, 0x7938, 0x710a, 0x793c, 0x710e, 0x7810, 0x2058, 0xb8a0,
+ 0x080c, 0x9f69, 0x1118, 0x9092, 0x007e, 0x0268, 0x00d6, 0x2069,
+ 0x181e, 0x2d2c, 0x8d68, 0x2d34, 0x90d8, 0x1000, 0x2b5c, 0xbb10,
+ 0xbc14, 0x00de, 0x0028, 0x901e, 0x6498, 0x2029, 0x0000, 0x6634,
+ 0x782c, 0x9080, 0x0008, 0x2004, 0x9086, 0x0003, 0x1128, 0x7512,
+ 0x7616, 0x731a, 0x741e, 0x0020, 0x7312, 0x7416, 0x751a, 0x761e,
+ 0x006e, 0x005e, 0x004e, 0x003e, 0x00be, 0x0005, 0x080c, 0x9132,
+ 0x7003, 0x0100, 0x782c, 0x700a, 0x7814, 0x700e, 0x700e, 0x60c3,
+ 0x0008, 0x0804, 0x95ee, 0x080c, 0x90de, 0x7003, 0x1400, 0x7838,
+ 0x700a, 0x0079, 0x783c, 0x700e, 0x782c, 0x7012, 0x7830, 0x7016,
+ 0x7834, 0x9084, 0x00ff, 0x8007, 0x701a, 0x60c3, 0x0010, 0x0804,
+ 0x95ee, 0x00e6, 0x2071, 0x0240, 0x0006, 0x00f6, 0x2078, 0x7810,
+ 0x00b6, 0x2058, 0xb8bc, 0xd084, 0x0120, 0x7844, 0x702a, 0x7848,
+ 0x702e, 0x00be, 0x00fe, 0x000e, 0x00ee, 0x0005, 0x080c, 0x9129,
+ 0x7003, 0x0100, 0x782c, 0x700a, 0x7814, 0x700e, 0x60c3, 0x0008,
+ 0x0804, 0x95ee, 0x0021, 0x60c3, 0x0000, 0x0804, 0x95ee, 0x00d6,
+ 0x080c, 0x9df2, 0xb810, 0x9085, 0x0300, 0x7002, 0xb814, 0x7006,
+ 0x2069, 0x1800, 0x6878, 0x700a, 0x687c, 0x700e, 0x7013, 0x0819,
+ 0x080c, 0x95dc, 0x721a, 0x2f10, 0x7222, 0x7a08, 0x7226, 0x2071,
+ 0x024c, 0x00de, 0x0005, 0x00a9, 0x7914, 0x712a, 0x60c3, 0x0000,
+ 0x60a7, 0x9575, 0x0026, 0x080c, 0x29e9, 0x0228, 0x2011, 0x0101,
+ 0x2204, 0xc0c5, 0x2012, 0x002e, 0x080c, 0x9611, 0x080c, 0x82d0,
+ 0x0005, 0x0036, 0x0096, 0x00d6, 0x00e6, 0x7858, 0x2048, 0xaa7c,
+ 0x9296, 0x00c0, 0x9294, 0x00fd, 0xaa7e, 0xaa80, 0x9294, 0x0300,
+ 0xaa82, 0xa96c, 0x9194, 0x00ff, 0xab74, 0x9384, 0x00ff, 0x908d,
+ 0xc200, 0xa96e, 0x9384, 0xff00, 0x9215, 0xaa76, 0xa870, 0xaa78,
+ 0xa87a, 0xaa72, 0x00d6, 0x2069, 0x0200, 0x080c, 0x9df2, 0x00de,
+ 0x20e9, 0x0000, 0x20a1, 0x0240, 0x20a9, 0x000a, 0xa860, 0x20e0,
+ 0xa85c, 0x9080, 0x001b, 0x2098, 0x4003, 0x60a3, 0x0035, 0xaa68,
+ 0x9294, 0x7000, 0x9286, 0x3000, 0x0110, 0x60a3, 0x0037, 0x00ee,
+ 0x00de, 0x009e, 0x003e, 0x0005, 0x900e, 0x7814, 0x0096, 0x2048,
+ 0xa87c, 0xd0fc, 0x01c0, 0x9084, 0x0003, 0x11a8, 0x2001, 0x180c,
+ 0x2004, 0xd0bc, 0x0180, 0x7824, 0xd0cc, 0x1168, 0xd0c4, 0x1158,
+ 0xa8a8, 0x9005, 0x1140, 0x2001, 0x180c, 0x200c, 0xc1d5, 0x2102,
+ 0x2009, 0x198d, 0x210c, 0x009e, 0x918d, 0x0092, 0x0010, 0x2009,
+ 0x0096, 0x60ab, 0x0036, 0x6116, 0x0005, 0x2009, 0x0009, 0x00a0,
+ 0x2009, 0x000a, 0x0088, 0x2009, 0x000b, 0x0070, 0x2009, 0x000c,
+ 0x0058, 0x2009, 0x000d, 0x0040, 0x2009, 0x000e, 0x0028, 0x2009,
+ 0x000f, 0x0010, 0x2009, 0x0008, 0x6912, 0x0005, 0x00d6, 0x9290,
+ 0x0018, 0x8214, 0x20e9, 0x0000, 0x2069, 0x0200, 0x6813, 0x0000,
+ 0x22a8, 0x9284, 0x00e0, 0x0128, 0x20a9, 0x0020, 0x9292, 0x0020,
+ 0x0008, 0x9016, 0x20a1, 0x0240, 0x9006, 0x4004, 0x82ff, 0x0120,
+ 0x6810, 0x8000, 0x6812, 0x0c60, 0x00de, 0x0005, 0x00d6, 0x0096,
+ 0x6014, 0x2048, 0xa878, 0x6056, 0x9006, 0xa836, 0xa83a, 0xa99c,
+ 0xa946, 0xa84a, 0x6023, 0x0003, 0x6007, 0x0040, 0x6003, 0x0003,
+ 0x600b, 0xffff, 0xa817, 0x0001, 0xa842, 0xa83e, 0x2900, 0xa85a,
+ 0xa813, 0x1ebc, 0x080c, 0x865d, 0x0126, 0x2091, 0x8000, 0x080c,
+ 0x8c6c, 0x012e, 0x009e, 0x00de, 0x0005, 0x00f6, 0x00e6, 0x00d6,
+ 0x00c6, 0x00a6, 0x0096, 0x0066, 0x0126, 0x2091, 0x8000, 0x2071,
+ 0x19c2, 0x760c, 0x2660, 0x2678, 0x8cff, 0x0904, 0x9ec9, 0x7024,
+ 0x9c06, 0x1520, 0x2069, 0x0100, 0x68c0, 0x9005, 0x0904, 0x9e9b,
+ 0x080c, 0x961a, 0x68c3, 0x0000, 0x080c, 0x9a7f, 0x7027, 0x0000,
+ 0x0036, 0x2069, 0x0140, 0x6b04, 0x9384, 0x1000, 0x0138, 0x2001,
+ 0x0100, 0x080c, 0x2b6f, 0x9006, 0x080c, 0x2b6f, 0x2069, 0x0100,
+ 0x6824, 0xd084, 0x0110, 0x6827, 0x0001, 0x003e, 0x700c, 0x9c36,
+ 0x1110, 0x660c, 0x760e, 0x7008, 0x9c36, 0x1140, 0x2c00, 0x9f36,
+ 0x0118, 0x2f00, 0x700a, 0x0010, 0x700b, 0x0000, 0x660c, 0x0066,
+ 0x2c00, 0x9f06, 0x0110, 0x7e0e, 0x0008, 0x2678, 0x600f, 0x0000,
+ 0x080c, 0xbf45, 0x1180, 0x080c, 0x30be, 0x080c, 0xbf56, 0x1518,
+ 0x080c, 0xa9a7, 0x0400, 0x080c, 0x9a7f, 0x6824, 0xd084, 0x09b0,
+ 0x6827, 0x0001, 0x0898, 0x080c, 0xbf56, 0x1118, 0x080c, 0xa9a7,
+ 0x0090, 0x6014, 0x2048, 0x080c, 0xbd4c, 0x0168, 0x6020, 0x9086,
+ 0x0003, 0x1520, 0xa867, 0x0103, 0xab7a, 0xa877, 0x0000, 0x080c,
+ 0x6a22, 0x080c, 0xbf39, 0x080c, 0xc1c2, 0x080c, 0xa01c, 0x080c,
+ 0x9955, 0x00ce, 0x0804, 0x9e4c, 0x2c78, 0x600c, 0x2060, 0x0804,
+ 0x9e4c, 0x700f, 0x0000, 0x700b, 0x0000, 0x012e, 0x006e, 0x009e,
+ 0x00ae, 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x0005, 0x6020, 0x9086,
+ 0x0006, 0x1d08, 0x080c, 0xd7e2, 0x08f0, 0x00d6, 0x0156, 0x080c,
+ 0x9132, 0x7a14, 0x82ff, 0x0138, 0x7003, 0x0100, 0x700b, 0x0003,
+ 0x60c3, 0x0008, 0x0490, 0x7003, 0x0200, 0x7007, 0x0000, 0x2069,
+ 0x1800, 0x901e, 0x6800, 0x9086, 0x0004, 0x1110, 0xc38d, 0x0060,
+ 0x080c, 0x717e, 0x1110, 0xc3ad, 0x0008, 0xc3a5, 0x6ad8, 0xd29c,
+ 0x1110, 0xd2ac, 0x0108, 0xc39d, 0x730e, 0x2011, 0x1848, 0x63f0,
+ 0x2312, 0x20a9, 0x0006, 0x2011, 0x1840, 0x2019, 0x1841, 0x2071,
+ 0x0250, 0x2376, 0x8e70, 0x2276, 0x8e70, 0x9398, 0x0002, 0x9290,
+ 0x0002, 0x1f04, 0x9f11, 0x60c3, 0x0020, 0x080c, 0x95ee, 0x015e,
+ 0x00de, 0x0005, 0x0156, 0x080c, 0x9132, 0x7a14, 0x82ff, 0x0168,
+ 0x9286, 0xffff, 0x0118, 0x9282, 0x000e, 0x1238, 0x7003, 0x0100,
+ 0x700b, 0x0003, 0x60c3, 0x0008, 0x0488, 0x7003, 0x0200, 0x7007,
+ 0x001c, 0x700f, 0x0001, 0x2011, 0x1998, 0x2204, 0x8007, 0x701a,
+ 0x8210, 0x2204, 0x8007, 0x701e, 0x0421, 0x1120, 0xb8a0, 0x9082,
+ 0x007f, 0x0248, 0x2001, 0x181e, 0x2004, 0x7022, 0x2001, 0x181f,
+ 0x2004, 0x7026, 0x0030, 0x2001, 0x1817, 0x2004, 0x9084, 0x00ff,
+ 0x7026, 0x20a9, 0x0004, 0x20e1, 0x0001, 0x2099, 0x1805, 0x20e9,
+ 0x0000, 0x20a1, 0x0256, 0x4003, 0x60c3, 0x001c, 0x015e, 0x0804,
+ 0x95ee, 0x0006, 0x2001, 0x1836, 0x2004, 0xd0ac, 0x000e, 0x0005,
+ 0x2011, 0x0003, 0x080c, 0x9923, 0x2011, 0x0002, 0x080c, 0x992d,
+ 0x080c, 0x983b, 0x0036, 0x901e, 0x080c, 0x98b1, 0x003e, 0x0005,
+ 0x2071, 0x188b, 0x7000, 0x9005, 0x0140, 0x2001, 0x0976, 0x2071,
+ 0x1800, 0x7072, 0x7076, 0x7067, 0xffe0, 0x2071, 0x1800, 0x7070,
+ 0x7052, 0x7057, 0x1cd0, 0x0005, 0x00e6, 0x0126, 0x2071, 0x1800,
+ 0x2091, 0x8000, 0x7550, 0x9582, 0x0010, 0x0608, 0x7054, 0x2060,
+ 0x6000, 0x9086, 0x0000, 0x0148, 0x9ce0, 0x0018, 0x7064, 0x9c02,
+ 0x1208, 0x0cb0, 0x2061, 0x1cd0, 0x0c98, 0x6003, 0x0008, 0x8529,
+ 0x7552, 0x9ca8, 0x0018, 0x7064, 0x9502, 0x1230, 0x7556, 0x9085,
+ 0x0001, 0x012e, 0x00ee, 0x0005, 0x7057, 0x1cd0, 0x0cc0, 0x9006,
+ 0x0cc0, 0x00e6, 0x2071, 0x1800, 0x7550, 0x9582, 0x0010, 0x0600,
0x7054, 0x2060, 0x6000, 0x9086, 0x0000, 0x0148, 0x9ce0, 0x0018,
0x7064, 0x9c02, 0x1208, 0x0cb0, 0x2061, 0x1cd0, 0x0c98, 0x6003,
- 0x0008, 0x8529, 0x7552, 0x9ca8, 0x0018, 0x7064, 0x9502, 0x1230,
- 0x7556, 0x9085, 0x0001, 0x012e, 0x00ee, 0x0005, 0x7057, 0x1cd0,
- 0x0cc0, 0x9006, 0x0cc0, 0x6020, 0x9084, 0x000f, 0x0002, 0xa066,
- 0xa06f, 0xa08a, 0xa0a5, 0xc48c, 0xc4a9, 0xc4c4, 0xa066, 0xa06f,
- 0xa066, 0xa0c1, 0xa066, 0xa066, 0xa066, 0xa066, 0x9186, 0x0013,
- 0x1128, 0x080c, 0x8a84, 0x080c, 0x8b90, 0x0005, 0x0005, 0x0066,
- 0x6000, 0x90b2, 0x0016, 0x1a0c, 0x0e02, 0x0013, 0x006e, 0x0005,
- 0xa088, 0xa7f1, 0xa9dc, 0xa088, 0xaa6a, 0xa3a4, 0xa088, 0xa088,
- 0xa773, 0xb035, 0xa088, 0xa088, 0xa088, 0xa088, 0xa088, 0xa088,
- 0x080c, 0x0e02, 0x0066, 0x6000, 0x90b2, 0x0016, 0x1a0c, 0x0e02,
- 0x0013, 0x006e, 0x0005, 0xa0a3, 0xb6ff, 0xa0a3, 0xa0a3, 0xa0a3,
- 0xa0a3, 0xa0a3, 0xa0a3, 0xb696, 0xb881, 0xa0a3, 0xb740, 0xb7bf,
- 0xb740, 0xb7bf, 0xa0a3, 0x080c, 0x0e02, 0x6000, 0x9082, 0x0016,
- 0x1a0c, 0x0e02, 0x6000, 0x0002, 0xa0bf, 0xb07c, 0xb144, 0xb274,
- 0xb423, 0xa0bf, 0xa0bf, 0xa0bf, 0xb050, 0xb622, 0xb625, 0xa0bf,
- 0xa0bf, 0xa0bf, 0xa0bf, 0xb654, 0xa0bf, 0xa0bf, 0xa0bf, 0x080c,
- 0x0e02, 0x0066, 0x6000, 0x90b2, 0x0016, 0x1a0c, 0x0e02, 0x0013,
- 0x006e, 0x0005, 0xa0da, 0xa0da, 0xa11d, 0xa1bc, 0xa251, 0xa0da,
- 0xa0da, 0xa0da, 0xa0dc, 0xa0da, 0xa0da, 0xa0da, 0xa0da, 0xa0da,
- 0xa0da, 0xa0da, 0x080c, 0x0e02, 0x9186, 0x004c, 0x0588, 0x9186,
- 0x0003, 0x190c, 0x0e02, 0x0096, 0x601c, 0xc0ed, 0x601e, 0x6003,
- 0x0003, 0x6106, 0x6014, 0x2048, 0xa87c, 0x9084, 0xa000, 0xc0b5,
- 0xa87e, 0xa8ac, 0xa846, 0xa8b0, 0xa84a, 0x9006, 0xa836, 0xa83a,
- 0xa884, 0x9092, 0x199a, 0x0210, 0x2001, 0x1999, 0x8003, 0x8013,
- 0x8213, 0x9210, 0x621a, 0x009e, 0x2c10, 0x080c, 0x1a82, 0x080c,
- 0x865e, 0x0126, 0x2091, 0x8000, 0x080c, 0x8c6d, 0x012e, 0x0005,
- 0x6010, 0x00b6, 0x2058, 0xbca0, 0x00be, 0x2c00, 0x080c, 0xa273,
- 0x080c, 0xc45c, 0x6003, 0x0007, 0x0005, 0x00d6, 0x0096, 0x00f6,
- 0x2079, 0x1800, 0x7a8c, 0x6014, 0x2048, 0xa87c, 0xd0ec, 0x1110,
- 0x9290, 0x0018, 0xac78, 0xc4fc, 0x0046, 0xa8e0, 0x9005, 0x1140,
- 0xa8dc, 0x921a, 0x0140, 0x0220, 0xa87b, 0x0007, 0x2010, 0x0028,
- 0xa87b, 0x0015, 0x0010, 0xa87b, 0x0000, 0x8214, 0xa883, 0x0000,
- 0xaa02, 0x0006, 0x0016, 0x0026, 0x00c6, 0x00d6, 0x00e6, 0x00f6,
- 0x2400, 0x9005, 0x1108, 0x009a, 0x2100, 0x9086, 0x0015, 0x1118,
- 0x2001, 0x0001, 0x0038, 0x2100, 0x9086, 0x0016, 0x0118, 0x2001,
- 0x0001, 0x002a, 0x94a4, 0x0007, 0x8423, 0x9405, 0x0002, 0xa184,
- 0xa184, 0xa17f, 0xa182, 0xa184, 0xa17c, 0xa16f, 0xa16f, 0xa16f,
- 0xa16f, 0xa16f, 0xa16f, 0xa16f, 0xa16f, 0xa16f, 0xa16f, 0x00fe,
- 0x00ee, 0x00de, 0x00ce, 0x002e, 0x001e, 0x000e, 0x004e, 0x00fe,
- 0x009e, 0x00de, 0x080c, 0x0e02, 0x080c, 0xac67, 0x0028, 0x080c,
- 0xad98, 0x0010, 0x080c, 0xae86, 0x00fe, 0x00ee, 0x00de, 0x00ce,
- 0x002e, 0x001e, 0x2c00, 0xa896, 0x000e, 0x080c, 0xa331, 0x0530,
- 0xa804, 0xa80e, 0x00a6, 0x2050, 0xb100, 0x00ae, 0x8006, 0x8006,
- 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, 0x0002, 0xaacc,
- 0xabd0, 0xacd4, 0xadd8, 0x2031, 0x0000, 0x2041, 0x12b4, 0x080c,
- 0xa4df, 0x0160, 0x000e, 0x9005, 0x0120, 0x00fe, 0x009e, 0x00de,
- 0x0005, 0x00fe, 0x009e, 0x00de, 0x0804, 0x9fd5, 0x2001, 0x002c,
- 0x900e, 0x080c, 0xa397, 0x0c70, 0x91b6, 0x0015, 0x0170, 0x91b6,
- 0x0016, 0x0158, 0x91b2, 0x0047, 0x0a0c, 0x0e02, 0x91b2, 0x0050,
- 0x1a0c, 0x0e02, 0x9182, 0x0047, 0x00ca, 0x2001, 0x0109, 0x2004,
- 0xd08c, 0x0198, 0x0126, 0x2091, 0x2800, 0x0006, 0x0016, 0x0026,
- 0x080c, 0x85b2, 0x002e, 0x001e, 0x000e, 0x012e, 0xa001, 0x6000,
- 0x9086, 0x0002, 0x1110, 0x0804, 0xa11d, 0x0005, 0xa1ef, 0xa1ef,
- 0xa1f1, 0xa227, 0xa1ef, 0xa1ef, 0xa1ef, 0xa1ef, 0xa23a, 0x080c,
- 0x0e02, 0x00d6, 0x0016, 0x0096, 0x080c, 0x8b40, 0x080c, 0x8c6d,
- 0x6003, 0x0004, 0x6114, 0x2148, 0xa87c, 0xd0fc, 0x01c0, 0xa878,
- 0xc0fc, 0x9005, 0x1158, 0xa894, 0x9005, 0x0140, 0x2001, 0x0000,
- 0x900e, 0x080c, 0xa397, 0x080c, 0x9fd5, 0x00a8, 0x6003, 0x0002,
- 0xa8a4, 0xa9a8, 0x9105, 0x1178, 0xa8ae, 0xa8b2, 0x0c78, 0xa87f,
- 0x0020, 0xa88c, 0xa88a, 0xa8a4, 0xa8ae, 0xa8a8, 0xa8b2, 0xa8c7,
- 0x0000, 0xa8cb, 0x0000, 0x009e, 0x001e, 0x00de, 0x0005, 0x080c,
- 0x8b40, 0x00d6, 0x0096, 0x6114, 0x2148, 0x080c, 0xbd3b, 0x0120,
- 0xa87b, 0x0006, 0x080c, 0x6a23, 0x009e, 0x00de, 0x080c, 0x9fd5,
- 0x0804, 0x8c6d, 0x080c, 0x8b40, 0x080c, 0x30ab, 0x080c, 0xc459,
- 0x00d6, 0x0096, 0x6114, 0x2148, 0x080c, 0xbd3b, 0x0120, 0xa87b,
- 0x0029, 0x080c, 0x6a23, 0x009e, 0x00de, 0x080c, 0x9fd5, 0x0804,
- 0x8c6d, 0x9182, 0x0047, 0x0002, 0xa261, 0xa263, 0xa261, 0xa261,
- 0xa261, 0xa261, 0xa261, 0xa261, 0xa261, 0xa261, 0xa261, 0xa261,
- 0xa263, 0x080c, 0x0e02, 0x00d6, 0x0096, 0x080c, 0x1583, 0x6114,
- 0x2148, 0xa87b, 0x0000, 0xa883, 0x0000, 0x080c, 0x6a23, 0x009e,
- 0x00de, 0x0804, 0x9fd5, 0x0026, 0x0036, 0x0056, 0x0066, 0x0096,
- 0x00a6, 0x00f6, 0x0006, 0x080c, 0x1043, 0x000e, 0x090c, 0x0e02,
- 0xa960, 0x21e8, 0xa95c, 0x9188, 0x0019, 0x21a0, 0x900e, 0x20a9,
- 0x0020, 0x4104, 0xa87a, 0x2079, 0x1800, 0x798c, 0x9188, 0x0018,
- 0x918c, 0x0fff, 0xa972, 0xac76, 0x2950, 0x00a6, 0x2001, 0x0205,
- 0x2003, 0x0000, 0x901e, 0x2029, 0x0001, 0x9182, 0x0034, 0x1228,
- 0x2011, 0x001f, 0x080c, 0xb906, 0x04c0, 0x2130, 0x2009, 0x0034,
- 0x2011, 0x001f, 0x080c, 0xb906, 0x96b2, 0x0034, 0xb004, 0x904d,
- 0x0110, 0x080c, 0x0ff5, 0x080c, 0x1043, 0x01d0, 0x8528, 0xa867,
- 0x0110, 0xa86b, 0x0000, 0x2920, 0xb406, 0x968a, 0x003d, 0x1230,
- 0x2608, 0x2011, 0x001b, 0x080c, 0xb906, 0x00b8, 0x96b2, 0x003c,
- 0x2009, 0x003c, 0x2950, 0x2011, 0x001b, 0x080c, 0xb906, 0x0c18,
- 0x2001, 0x0205, 0x2003, 0x0000, 0x00ae, 0x852f, 0x95ad, 0x0050,
- 0xb566, 0xb070, 0xc0fd, 0xb072, 0x0048, 0x2001, 0x0205, 0x2003,
- 0x0000, 0x00ae, 0x852f, 0x95ad, 0x0050, 0xb566, 0x2a48, 0xa804,
- 0xa807, 0x0000, 0x0006, 0x080c, 0x6a23, 0x000e, 0x2048, 0x9005,
- 0x1db0, 0x00fe, 0x00ae, 0x009e, 0x006e, 0x005e, 0x003e, 0x002e,
- 0x0005, 0x00d6, 0x00f6, 0x0096, 0x0006, 0x080c, 0x1043, 0x000e,
- 0x090c, 0x0e02, 0xa960, 0x21e8, 0xa95c, 0x9188, 0x0019, 0x21a0,
- 0x900e, 0x20a9, 0x0020, 0x4104, 0xaa66, 0xa87a, 0x2079, 0x1800,
- 0x798c, 0x810c, 0x9188, 0x000c, 0x9182, 0x001a, 0x0210, 0x2009,
- 0x001a, 0x21a8, 0x810b, 0xa972, 0xac76, 0x2e98, 0xa85c, 0x9080,
- 0x001f, 0x20a0, 0x2001, 0x0205, 0x200c, 0x918d, 0x0080, 0x2102,
- 0x4003, 0x2003, 0x0000, 0x080c, 0x6a23, 0x009e, 0x00fe, 0x00de,
- 0x0005, 0x0016, 0x00d6, 0x00f6, 0x0096, 0x0016, 0x2001, 0x0205,
- 0x200c, 0x918d, 0x0080, 0x2102, 0x001e, 0x2079, 0x0200, 0x2e98,
- 0xa87c, 0xd0ec, 0x0118, 0x9e80, 0x000c, 0x2098, 0x2021, 0x003e,
- 0x901e, 0x9282, 0x0020, 0x0218, 0x2011, 0x0020, 0x2018, 0x9486,
- 0x003e, 0x1170, 0x0096, 0x080c, 0x1043, 0x2900, 0x009e, 0x05c0,
- 0xa806, 0x2048, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0002, 0x20a0,
- 0x3300, 0x908e, 0x0260, 0x0140, 0x2009, 0x0280, 0x9102, 0x920a,
- 0x0218, 0x2010, 0x2100, 0x9318, 0x2200, 0x9402, 0x1228, 0x2400,
- 0x9202, 0x2410, 0x9318, 0x9006, 0x2020, 0x22a8, 0xa800, 0x9200,
- 0xa802, 0x20e1, 0x0000, 0x4003, 0x83ff, 0x0180, 0x3300, 0x9086,
- 0x0280, 0x1130, 0x7814, 0x8000, 0x9085, 0x0080, 0x7816, 0x2e98,
- 0x2310, 0x84ff, 0x0904, 0xa346, 0x0804, 0xa348, 0x9085, 0x0001,
- 0x7817, 0x0000, 0x009e, 0x00fe, 0x00de, 0x001e, 0x0005, 0x00d6,
- 0x0036, 0x0096, 0x6314, 0x2348, 0xa87a, 0xa982, 0x080c, 0x6a16,
- 0x009e, 0x003e, 0x00de, 0x0005, 0x91b6, 0x0015, 0x1118, 0x080c,
- 0x9fd5, 0x0030, 0x91b6, 0x0016, 0x190c, 0x0e02, 0x080c, 0x9fd5,
- 0x0005, 0x20a9, 0x000e, 0x20e1, 0x0000, 0x2e98, 0x6014, 0x0096,
- 0x2048, 0xa860, 0x20e8, 0xa85c, 0x20a0, 0x009e, 0x4003, 0x9196,
- 0x0016, 0x01f0, 0x0136, 0x9080, 0x001b, 0x20a0, 0x2011, 0x0006,
- 0x20a9, 0x0001, 0x3418, 0x8318, 0x23a0, 0x4003, 0x3318, 0x8318,
- 0x2398, 0x8211, 0x1db8, 0x2011, 0x0006, 0x013e, 0x20a0, 0x3318,
- 0x8318, 0x2398, 0x4003, 0x3418, 0x8318, 0x23a0, 0x8211, 0x1db8,
- 0x0096, 0x080c, 0xbd3b, 0x0130, 0x6014, 0x2048, 0xa807, 0x0000,
- 0xa867, 0x0103, 0x009e, 0x0804, 0x9fd5, 0x0096, 0x00d6, 0x0036,
- 0x7330, 0x9386, 0x0200, 0x11a8, 0x6010, 0x00b6, 0x2058, 0xb8bf,
- 0x0000, 0x00be, 0x6014, 0x9005, 0x0130, 0x2048, 0xa807, 0x0000,
- 0xa867, 0x0103, 0xab32, 0x080c, 0x9fd5, 0x003e, 0x00de, 0x009e,
- 0x0005, 0x0011, 0x1d48, 0x0cc8, 0x0006, 0x0016, 0x080c, 0xc444,
- 0x0188, 0x6014, 0x9005, 0x1170, 0x600b, 0x0003, 0x601b, 0x0000,
- 0x6043, 0x0000, 0x2009, 0x0022, 0x080c, 0xa7c9, 0x9006, 0x001e,
- 0x000e, 0x0005, 0x9085, 0x0001, 0x0cd0, 0x0096, 0x0016, 0x20a9,
- 0x0014, 0x9e80, 0x000c, 0x20e1, 0x0000, 0x2098, 0x6014, 0x2048,
- 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0002, 0x20a0, 0x4003, 0x2001,
- 0x0205, 0x2003, 0x0001, 0x2099, 0x0260, 0x20a9, 0x0016, 0x4003,
- 0x20a9, 0x000a, 0xa804, 0x2048, 0xa860, 0x20e8, 0xa85c, 0x9080,
- 0x0002, 0x20a0, 0x4003, 0x2001, 0x0205, 0x2003, 0x0002, 0x2099,
- 0x0260, 0x20a9, 0x0020, 0x4003, 0x2003, 0x0000, 0x6014, 0x2048,
- 0xa800, 0x2048, 0xa867, 0x0103, 0x080c, 0x9fd5, 0x001e, 0x009e,
- 0x0005, 0x0096, 0x0016, 0x900e, 0x7030, 0x9086, 0x0100, 0x0140,
- 0x7038, 0x9084, 0x00ff, 0x800c, 0x703c, 0x9084, 0x00ff, 0x8004,
- 0x9080, 0x0004, 0x9108, 0x810b, 0x2011, 0x0002, 0x2019, 0x000c,
- 0x6014, 0x2048, 0x080c, 0xb906, 0x080c, 0xbd3b, 0x0140, 0x6014,
- 0x2048, 0xa807, 0x0000, 0xa864, 0xa8e2, 0xa867, 0x0103, 0x080c,
- 0x9fd5, 0x001e, 0x009e, 0x0005, 0x0016, 0x0096, 0x7030, 0x9086,
- 0x0100, 0x1118, 0x2009, 0x0004, 0x0010, 0x7034, 0x800c, 0x810b,
- 0x2011, 0x000c, 0x2019, 0x000c, 0x6014, 0x2048, 0xa804, 0x0096,
- 0x9005, 0x0108, 0x2048, 0x080c, 0xb906, 0x009e, 0x080c, 0xbd3b,
- 0x0148, 0xa804, 0x9005, 0x1158, 0xa807, 0x0000, 0xa864, 0xa8e2,
- 0xa867, 0x0103, 0x080c, 0x9fd5, 0x009e, 0x001e, 0x0005, 0x0086,
- 0x2040, 0xa030, 0x8007, 0x9086, 0x0100, 0x1118, 0x080c, 0xa995,
- 0x00e0, 0xa034, 0x8007, 0x800c, 0x8806, 0x8006, 0x8007, 0x90bc,
- 0x003f, 0x9084, 0xffc0, 0x9080, 0x000c, 0xa87b, 0x0000, 0xa883,
- 0x0000, 0xa897, 0x4000, 0xaaa0, 0xab9c, 0xaca8, 0xada4, 0x2031,
- 0x0000, 0x2041, 0x129a, 0x0019, 0x0d08, 0x008e, 0x0898, 0x0096,
- 0x0006, 0x080c, 0x1043, 0x000e, 0x01b0, 0xa8ab, 0x0dcb, 0xa876,
- 0x000e, 0xa8a2, 0x0006, 0xae6a, 0x2800, 0xa89e, 0xa97a, 0xaf72,
- 0xaa8e, 0xab92, 0xac96, 0xad9a, 0x0086, 0x2940, 0x080c, 0x1140,
- 0x008e, 0x9085, 0x0001, 0x009e, 0x0005, 0x00e6, 0x00d6, 0x0026,
- 0x7008, 0x9084, 0x00ff, 0x6210, 0x00b6, 0x2258, 0xba10, 0x00be,
- 0x9206, 0x1520, 0x700c, 0x6210, 0x00b6, 0x2258, 0xba14, 0x00be,
- 0x9206, 0x11e0, 0x6043, 0x0000, 0x2c68, 0x0016, 0x2009, 0x0035,
- 0x080c, 0xc3bc, 0x001e, 0x1158, 0x622c, 0x2268, 0x2071, 0x026c,
- 0x6b20, 0x9386, 0x0003, 0x0130, 0x9386, 0x0006, 0x0128, 0x080c,
- 0x9fd5, 0x0020, 0x0039, 0x0010, 0x080c, 0xa5fe, 0x002e, 0x00de,
- 0x00ee, 0x0005, 0x0096, 0x6814, 0x2048, 0x9186, 0x0015, 0x0904,
- 0xa5e6, 0x918e, 0x0016, 0x1904, 0xa5fc, 0x700c, 0x908c, 0xff00,
- 0x9186, 0x1700, 0x0120, 0x9186, 0x0300, 0x1904, 0xa5c0, 0x89ff,
- 0x1138, 0x6800, 0x9086, 0x000f, 0x0904, 0xa5a3, 0x0804, 0xa5fa,
- 0x6808, 0x9086, 0xffff, 0x1904, 0xa5e8, 0xa87c, 0x9084, 0x0060,
- 0x9086, 0x0020, 0x1128, 0xa83c, 0xa940, 0x9105, 0x1904, 0xa5e8,
- 0x6824, 0xd084, 0x1904, 0xa5e8, 0xd0b4, 0x0158, 0x0016, 0x2001,
- 0x1960, 0x200c, 0x6018, 0x9102, 0x9082, 0x0005, 0x001e, 0x1a04,
- 0xa5e8, 0x080c, 0xbf26, 0x685c, 0xa882, 0xa87c, 0xc0dc, 0xc0f4,
- 0xc0d4, 0xa87e, 0x0026, 0x900e, 0x6a18, 0x2001, 0x000a, 0x080c,
- 0x847f, 0xa884, 0x920a, 0x0208, 0x8011, 0xaa86, 0x82ff, 0x002e,
- 0x1138, 0x00c6, 0x2d60, 0x080c, 0xba68, 0x00ce, 0x0804, 0xa5fa,
- 0x00c6, 0xa868, 0xd0fc, 0x1118, 0x080c, 0x5eac, 0x0010, 0x080c,
- 0x625a, 0x00ce, 0x1904, 0xa5e8, 0x00c6, 0x2d60, 0x080c, 0x9fd5,
- 0x00ce, 0x0804, 0xa5fa, 0x00c6, 0x080c, 0xa026, 0x0198, 0x6017,
- 0x0000, 0x6810, 0x6012, 0x080c, 0xc1b7, 0x6023, 0x0003, 0x6904,
- 0x00c6, 0x2d60, 0x080c, 0x9fd5, 0x00ce, 0x080c, 0xa053, 0x00ce,
- 0x0804, 0xa5fa, 0x2001, 0x1962, 0x2004, 0x6842, 0x00ce, 0x04d0,
- 0x7008, 0x9086, 0x000b, 0x11c8, 0x6010, 0x00b6, 0x2058, 0xb900,
- 0xc1bc, 0xb902, 0x00be, 0x00c6, 0x2d60, 0xa87b, 0x0003, 0x080c,
- 0xc3fe, 0x6007, 0x0085, 0x6003, 0x000b, 0x6023, 0x0002, 0x080c,
- 0x85f9, 0x080c, 0x8b90, 0x00ce, 0x00e8, 0x700c, 0x9086, 0x2a00,
- 0x1138, 0x2001, 0x1962, 0x2004, 0x6842, 0x00a0, 0x0479, 0x00a0,
- 0x89ff, 0x090c, 0x0e02, 0x00c6, 0x00d6, 0x2d60, 0xa867, 0x0103,
- 0xa87b, 0x0003, 0x080c, 0x683d, 0x080c, 0xbf26, 0x080c, 0xa007,
- 0x00de, 0x00ce, 0x080c, 0x9fd5, 0x009e, 0x0005, 0x9186, 0x0015,
- 0x1128, 0x2001, 0x1962, 0x2004, 0x6842, 0x0068, 0x918e, 0x0016,
- 0x1160, 0x00c6, 0x2d00, 0x2060, 0x080c, 0xda33, 0x080c, 0x8426,
- 0x080c, 0x9fd5, 0x00ce, 0x080c, 0x9fd5, 0x0005, 0x0026, 0x0036,
- 0x0046, 0x7228, 0xacb0, 0xabac, 0xd2f4, 0x0130, 0x2001, 0x1962,
- 0x2004, 0x6842, 0x0804, 0xa678, 0x00c6, 0x2d60, 0x080c, 0xb967,
- 0x00ce, 0x6804, 0x9086, 0x0050, 0x1168, 0x00c6, 0x2d00, 0x2060,
- 0x6003, 0x0001, 0x6007, 0x0050, 0x080c, 0x85f9, 0x080c, 0x8b90,
- 0x00ce, 0x04f0, 0x6800, 0x9086, 0x000f, 0x01a8, 0x89ff, 0x090c,
- 0x0e02, 0x6800, 0x9086, 0x0004, 0x1190, 0xa87c, 0xd0ac, 0x0178,
- 0xa843, 0x0fff, 0xa83f, 0x0fff, 0xa880, 0xc0fc, 0xa882, 0x2001,
- 0x0001, 0x6832, 0x0400, 0x2001, 0x0007, 0x6832, 0x00e0, 0xa87c,
- 0xd0b4, 0x1150, 0xd0ac, 0x0db8, 0x6824, 0xd0f4, 0x1d48, 0xa838,
- 0xa934, 0x9105, 0x0d80, 0x0c20, 0xd2ec, 0x1d68, 0x7024, 0x9306,
- 0x1118, 0x7020, 0x9406, 0x0d38, 0x7020, 0x683e, 0x7024, 0x683a,
- 0x2001, 0x0005, 0x6832, 0x080c, 0xc0ae, 0x080c, 0x8b90, 0x0010,
- 0x080c, 0x9fd5, 0x004e, 0x003e, 0x002e, 0x0005, 0x00e6, 0x00d6,
- 0x0026, 0x7008, 0x9084, 0x00ff, 0x6210, 0x00b6, 0x2258, 0xba10,
- 0x00be, 0x9206, 0x1904, 0xa6e3, 0x700c, 0x6210, 0x00b6, 0x2258,
- 0xba14, 0x00be, 0x9206, 0x1904, 0xa6e3, 0x6038, 0x2068, 0x6824,
- 0xc0dc, 0x6826, 0x6a20, 0x9286, 0x0007, 0x0904, 0xa6e3, 0x9286,
- 0x0002, 0x0904, 0xa6e3, 0x9286, 0x0000, 0x05e8, 0x6808, 0x633c,
- 0x9306, 0x15c8, 0x2071, 0x026c, 0x9186, 0x0015, 0x0570, 0x918e,
- 0x0016, 0x1100, 0x00c6, 0x6038, 0x2060, 0x6104, 0x9186, 0x004b,
- 0x01c0, 0x9186, 0x004c, 0x01a8, 0x9186, 0x004d, 0x0190, 0x9186,
- 0x004e, 0x0178, 0x9186, 0x0052, 0x0160, 0x6014, 0x0096, 0x2048,
- 0x080c, 0xbd3b, 0x090c, 0x0e02, 0xa87b, 0x0003, 0x009e, 0x080c,
- 0xc3fe, 0x6007, 0x0085, 0x6003, 0x000b, 0x6023, 0x0002, 0x080c,
- 0x85f9, 0x080c, 0x8b90, 0x00ce, 0x0030, 0x6038, 0x2070, 0x2001,
- 0x1962, 0x2004, 0x7042, 0x080c, 0x9fd5, 0x002e, 0x00de, 0x00ee,
- 0x0005, 0x00b6, 0x0096, 0x00f6, 0x6014, 0x2048, 0x6010, 0x2058,
- 0x91b6, 0x0015, 0x0130, 0xba08, 0xbb0c, 0xbc00, 0xc48c, 0xbc02,
- 0x0460, 0x0096, 0x0156, 0x0036, 0x0026, 0x2b48, 0x9e90, 0x0010,
- 0x2019, 0x000a, 0x20a9, 0x0004, 0x080c, 0xb00b, 0x002e, 0x003e,
- 0x015e, 0x009e, 0x1904, 0xa752, 0x0096, 0x0156, 0x0036, 0x0026,
- 0x2b48, 0x9e90, 0x0014, 0x2019, 0x0006, 0x20a9, 0x0004, 0x080c,
- 0xb00b, 0x002e, 0x003e, 0x015e, 0x009e, 0x15a0, 0x7238, 0xba0a,
- 0x733c, 0xbb0e, 0xbc00, 0xc48d, 0xbc02, 0xa804, 0x9005, 0x1128,
- 0x00fe, 0x009e, 0x00be, 0x0804, 0xa3e0, 0x0096, 0x2048, 0xaa12,
- 0xab16, 0xac0a, 0x009e, 0x8006, 0x8006, 0x8007, 0x90bc, 0x003f,
- 0x9084, 0xffc0, 0x9080, 0x0002, 0x2009, 0x002b, 0xaaa0, 0xab9c,
- 0xaca8, 0xada4, 0x2031, 0x0000, 0x2041, 0x129a, 0x080c, 0xa4df,
- 0x0130, 0x00fe, 0x009e, 0x080c, 0x9fd5, 0x00be, 0x0005, 0x080c,
- 0xa995, 0x0cb8, 0x2b78, 0x00f6, 0x080c, 0x30ab, 0x080c, 0xc459,
- 0x00fe, 0x00c6, 0x080c, 0x9f7f, 0x2f00, 0x6012, 0x6017, 0x0000,
- 0x6023, 0x0001, 0x6007, 0x0001, 0x6003, 0x0001, 0x2001, 0x0007,
- 0x080c, 0x62f5, 0x080c, 0x6321, 0x080c, 0x8641, 0x080c, 0x8b90,
- 0x00ce, 0x0804, 0xa725, 0x2100, 0x91b2, 0x0053, 0x1a0c, 0x0e02,
- 0x91b2, 0x0040, 0x1a04, 0xa7db, 0x0002, 0xa7c9, 0xa7c9, 0xa7bf,
- 0xa7c9, 0xa7c9, 0xa7c9, 0xa7bd, 0xa7bd, 0xa7bd, 0xa7bd, 0xa7bd,
- 0xa7bd, 0xa7bd, 0xa7bd, 0xa7bd, 0xa7bd, 0xa7bd, 0xa7bd, 0xa7bd,
- 0xa7bd, 0xa7bd, 0xa7bd, 0xa7bd, 0xa7bd, 0xa7bd, 0xa7bd, 0xa7bd,
- 0xa7bd, 0xa7bd, 0xa7bd, 0xa7bd, 0xa7c9, 0xa7bd, 0xa7c9, 0xa7c9,
- 0xa7bd, 0xa7bd, 0xa7bd, 0xa7bd, 0xa7bd, 0xa7bf, 0xa7bd, 0xa7bd,
- 0xa7bd, 0xa7bd, 0xa7bd, 0xa7bd, 0xa7bd, 0xa7bd, 0xa7bd, 0xa7c9,
- 0xa7c9, 0xa7bd, 0xa7bd, 0xa7bd, 0xa7bd, 0xa7bd, 0xa7bd, 0xa7bd,
- 0xa7bd, 0xa7bd, 0xa7c9, 0xa7bd, 0xa7bd, 0x080c, 0x0e02, 0x0066,
- 0x00b6, 0x6610, 0x2658, 0xb8bc, 0xc08c, 0xb8be, 0x00be, 0x006e,
- 0x0000, 0x6003, 0x0001, 0x6106, 0x9186, 0x0032, 0x0118, 0x080c,
- 0x8641, 0x0010, 0x080c, 0x85f9, 0x0126, 0x2091, 0x8000, 0x080c,
- 0x8b90, 0x012e, 0x0005, 0x2600, 0x0002, 0xa7ef, 0xa7ef, 0xa7ef,
- 0xa7c9, 0xa7c9, 0xa7ef, 0xa7ef, 0xa7ef, 0xa7ef, 0xa7c9, 0xa7ef,
- 0xa7c9, 0xa7ef, 0xa7c9, 0xa7ef, 0xa7ef, 0xa7ef, 0xa7ef, 0x080c,
- 0x0e02, 0x6004, 0x90b2, 0x0053, 0x1a0c, 0x0e02, 0x91b6, 0x0013,
- 0x0904, 0xa8c4, 0x91b6, 0x0027, 0x1904, 0xa86e, 0x080c, 0x8a84,
- 0x6004, 0x080c, 0xbf32, 0x01b0, 0x080c, 0xbf43, 0x01a8, 0x908e,
- 0x0021, 0x0904, 0xa86b, 0x908e, 0x0022, 0x1130, 0x080c, 0xa40c,
- 0x0904, 0xa867, 0x0804, 0xa868, 0x908e, 0x003d, 0x0904, 0xa86b,
- 0x0804, 0xa861, 0x080c, 0x30d4, 0x2001, 0x0007, 0x080c, 0x62f5,
- 0x6010, 0x00b6, 0x2058, 0xb9a0, 0x00be, 0x080c, 0xa995, 0x9186,
- 0x007e, 0x1148, 0x2001, 0x1836, 0x2014, 0xc285, 0x080c, 0x717f,
- 0x1108, 0xc2ad, 0x2202, 0x0036, 0x0026, 0x2019, 0x0028, 0x2110,
- 0x080c, 0xda8f, 0x002e, 0x003e, 0x0016, 0x0026, 0x0036, 0x2110,
- 0x2019, 0x0028, 0x080c, 0x8783, 0x0076, 0x903e, 0x080c, 0x8671,
- 0x6010, 0x00b6, 0x905d, 0x0100, 0x00be, 0x2c08, 0x080c, 0xd53b,
- 0x007e, 0x003e, 0x002e, 0x001e, 0x080c, 0xc459, 0x0016, 0x080c,
- 0xc1af, 0x080c, 0x9fd5, 0x001e, 0x080c, 0x31a6, 0x080c, 0x8b90,
- 0x0030, 0x080c, 0xc1af, 0x080c, 0x9fd5, 0x080c, 0x8b90, 0x0005,
- 0x080c, 0xa995, 0x0cb0, 0x080c, 0xa9d1, 0x0c98, 0x9186, 0x0015,
- 0x0118, 0x9186, 0x0016, 0x1148, 0x080c, 0xc46a, 0x0d80, 0x6000,
- 0x9086, 0x0002, 0x0904, 0xa9dc, 0x0c50, 0x9186, 0x0014, 0x1d38,
- 0x080c, 0x8a84, 0x6004, 0x908e, 0x0022, 0x1118, 0x080c, 0xa40c,
- 0x09f0, 0x080c, 0x30ab, 0x080c, 0xc459, 0x080c, 0xbf32, 0x1198,
- 0x080c, 0x30d4, 0x6010, 0x00b6, 0x2058, 0xb9a0, 0x00be, 0x080c,
- 0xa995, 0x9186, 0x007e, 0x1128, 0x2001, 0x1836, 0x200c, 0xc185,
- 0x2102, 0x0804, 0xa861, 0x080c, 0xbf43, 0x1120, 0x080c, 0xa995,
- 0x0804, 0xa861, 0x6004, 0x908e, 0x0032, 0x1160, 0x00e6, 0x00f6,
- 0x2071, 0x189c, 0x2079, 0x0000, 0x080c, 0x343a, 0x00fe, 0x00ee,
- 0x0804, 0xa861, 0x6004, 0x908e, 0x0021, 0x0d40, 0x908e, 0x0022,
- 0x090c, 0xa995, 0x0804, 0xa861, 0x90b2, 0x0040, 0x1a04, 0xa97e,
- 0x2008, 0x0002, 0xa90c, 0xa90d, 0xa910, 0xa913, 0xa916, 0xa923,
- 0xa90a, 0xa90a, 0xa90a, 0xa90a, 0xa90a, 0xa90a, 0xa90a, 0xa90a,
- 0xa90a, 0xa90a, 0xa90a, 0xa90a, 0xa90a, 0xa90a, 0xa90a, 0xa90a,
- 0xa90a, 0xa90a, 0xa90a, 0xa90a, 0xa90a, 0xa90a, 0xa90a, 0xa90a,
- 0xa926, 0xa933, 0xa90a, 0xa935, 0xa933, 0xa90a, 0xa90a, 0xa90a,
- 0xa90a, 0xa90a, 0xa933, 0xa933, 0xa90a, 0xa90a, 0xa90a, 0xa90a,
- 0xa90a, 0xa90a, 0xa90a, 0xa90a, 0xa965, 0xa933, 0xa90a, 0xa92f,
- 0xa90a, 0xa90a, 0xa90a, 0xa930, 0xa90a, 0xa90a, 0xa90a, 0xa933,
- 0xa95c, 0xa90a, 0x080c, 0x0e02, 0x0430, 0x2001, 0x000b, 0x0470,
- 0x2001, 0x0003, 0x0458, 0x2001, 0x0005, 0x0440, 0x6010, 0x00b6,
- 0x2058, 0xb804, 0x00be, 0x9084, 0x00ff, 0x9086, 0x0000, 0x1500,
- 0x2001, 0x0001, 0x00d8, 0x2001, 0x0009, 0x00c0, 0x080c, 0x8a84,
- 0x6003, 0x0005, 0x080c, 0xc45c, 0x080c, 0x8b90, 0x0070, 0x0018,
- 0x0010, 0x080c, 0x62f5, 0x0804, 0xa976, 0x080c, 0x8a84, 0x080c,
- 0xc45c, 0x6003, 0x0004, 0x080c, 0x8b90, 0x0005, 0x080c, 0x62f5,
- 0x080c, 0x8a84, 0x6003, 0x0002, 0x0036, 0x2019, 0x1866, 0x2304,
- 0x9084, 0xff00, 0x1120, 0x2001, 0x1960, 0x201c, 0x0040, 0x8007,
- 0x909a, 0x0004, 0x0ec0, 0x8003, 0x801b, 0x831b, 0x9318, 0x631a,
- 0x003e, 0x080c, 0x8b90, 0x0c08, 0x080c, 0x8a84, 0x080c, 0xc1af,
- 0x080c, 0x9fd5, 0x080c, 0x8b90, 0x08c0, 0x00e6, 0x00f6, 0x2071,
- 0x189c, 0x2079, 0x0000, 0x080c, 0x343a, 0x00fe, 0x00ee, 0x080c,
- 0x8a84, 0x080c, 0x9fd5, 0x080c, 0x8b90, 0x0838, 0x080c, 0x8a84,
- 0x6003, 0x0002, 0x080c, 0xc45c, 0x0804, 0x8b90, 0x2600, 0x2008,
- 0x0002, 0xa993, 0xa993, 0xa993, 0xa976, 0xa976, 0xa993, 0xa993,
- 0xa993, 0xa993, 0xa976, 0xa993, 0xa976, 0xa993, 0xa976, 0xa993,
- 0xa993, 0xa993, 0xa993, 0x080c, 0x0e02, 0x00e6, 0x0096, 0x0026,
- 0x0016, 0x080c, 0xbd3b, 0x0568, 0x6014, 0x2048, 0xa864, 0x9086,
- 0x0139, 0x11a8, 0xa894, 0x9086, 0x0056, 0x1148, 0x080c, 0x5276,
- 0x0130, 0x2001, 0x0000, 0x900e, 0x2011, 0x4000, 0x0028, 0x2001,
- 0x0030, 0x900e, 0x2011, 0x4005, 0x080c, 0xc320, 0x0090, 0xa868,
- 0xd0fc, 0x0178, 0xa807, 0x0000, 0x0016, 0x6004, 0x908e, 0x0021,
- 0x0168, 0x908e, 0x003d, 0x0150, 0x001e, 0xa867, 0x0103, 0xa833,
- 0x0100, 0x001e, 0x002e, 0x009e, 0x00ee, 0x0005, 0x001e, 0x0009,
- 0x0cc0, 0x0096, 0x6014, 0x2048, 0xa800, 0x2048, 0xa867, 0x0103,
- 0xa823, 0x8001, 0x009e, 0x0005, 0x00b6, 0x6610, 0x2658, 0xb804,
- 0x9084, 0x00ff, 0x90b2, 0x000c, 0x1a0c, 0x0e02, 0x6604, 0x96b6,
- 0x004d, 0x1120, 0x080c, 0xc23f, 0x0804, 0xaa59, 0x6604, 0x96b6,
- 0x0043, 0x1120, 0x080c, 0xc288, 0x0804, 0xaa59, 0x6604, 0x96b6,
- 0x004b, 0x1120, 0x080c, 0xc2b4, 0x0804, 0xaa59, 0x6604, 0x96b6,
- 0x0033, 0x1120, 0x080c, 0xc1d1, 0x0804, 0xaa59, 0x6604, 0x96b6,
- 0x0028, 0x1120, 0x080c, 0xbf81, 0x0804, 0xaa59, 0x6604, 0x96b6,
- 0x0029, 0x1120, 0x080c, 0xbfc2, 0x0804, 0xaa59, 0x6604, 0x96b6,
- 0x001f, 0x1118, 0x080c, 0xa3b1, 0x04e0, 0x6604, 0x96b6, 0x0000,
- 0x1118, 0x080c, 0xa6e9, 0x04a8, 0x6604, 0x96b6, 0x0022, 0x1118,
- 0x080c, 0xa3ed, 0x0470, 0x6604, 0x96b6, 0x0035, 0x1118, 0x080c,
- 0xa4fd, 0x0438, 0x6604, 0x96b6, 0x0039, 0x1118, 0x080c, 0xa67e,
- 0x0400, 0x6604, 0x96b6, 0x003d, 0x1118, 0x080c, 0xa425, 0x00c8,
- 0x6604, 0x96b6, 0x0044, 0x1118, 0x080c, 0xa461, 0x0090, 0x6604,
- 0x96b6, 0x0049, 0x1118, 0x080c, 0xa48c, 0x0058, 0x91b6, 0x0015,
- 0x1110, 0x0063, 0x0030, 0x91b6, 0x0016, 0x1128, 0x00be, 0x0804,
- 0xad3f, 0x00be, 0x0005, 0x080c, 0xa06e, 0x0cd8, 0xaa76, 0xaa84,
- 0xaa76, 0xaac8, 0xaa76, 0xac67, 0xad4c, 0xaa76, 0xaa76, 0xad19,
- 0xaa76, 0xad2d, 0x0096, 0x080c, 0x1583, 0x6014, 0x2048, 0xa800,
- 0x2048, 0xa867, 0x0103, 0x009e, 0x0804, 0x9fd5, 0xa001, 0xa001,
- 0x0005, 0x6604, 0x96b6, 0x0004, 0x1130, 0x2001, 0x0001, 0x080c,
- 0x62e1, 0x0804, 0x9fd5, 0x0005, 0x00e6, 0x2071, 0x1800, 0x708c,
- 0x9086, 0x0074, 0x1540, 0x080c, 0xd50c, 0x11b0, 0x6010, 0x00b6,
- 0x2058, 0x7030, 0xd08c, 0x0128, 0xb800, 0xd0bc, 0x0110, 0xc0c5,
- 0xb802, 0x00e9, 0x00be, 0x2001, 0x0006, 0x080c, 0x62f5, 0x080c,
- 0x30d4, 0x080c, 0x9fd5, 0x0088, 0x2001, 0x000a, 0x080c, 0x62f5,
- 0x080c, 0x30d4, 0x6003, 0x0001, 0x6007, 0x0001, 0x080c, 0x8641,
- 0x080c, 0x8b90, 0x0010, 0x080c, 0xac52, 0x00ee, 0x0005, 0x00d6,
- 0xb800, 0xd084, 0x0158, 0x9006, 0x080c, 0x62e1, 0x2069, 0x185b,
- 0x6804, 0x0020, 0x2001, 0x0006, 0x080c, 0x6321, 0x00de, 0x0005,
- 0x00b6, 0x0096, 0x00d6, 0x2011, 0x1823, 0x2204, 0x9086, 0x0074,
- 0x1904, 0xac29, 0x6010, 0x2058, 0xbaa0, 0x9286, 0x007e, 0x1120,
- 0x080c, 0xae91, 0x0804, 0xab8b, 0x00d6, 0x080c, 0x717f, 0x01a0,
- 0x0026, 0x2011, 0x0010, 0x080c, 0x66ee, 0x002e, 0x0904, 0xab2c,
- 0x080c, 0x54f0, 0x1598, 0x6014, 0x2048, 0xa807, 0x0000, 0xa867,
- 0x0103, 0xa833, 0xdead, 0x0450, 0x6010, 0x00b6, 0x2058, 0xb910,
- 0x00be, 0x9186, 0x00ff, 0x0580, 0x0026, 0x2011, 0x8008, 0x080c,
- 0x66ee, 0x002e, 0x0548, 0x6014, 0x9005, 0x090c, 0x0e02, 0x2048,
- 0xa864, 0x9084, 0x00ff, 0x9086, 0x0039, 0x1140, 0x2001, 0x0030,
- 0x900e, 0x2011, 0x4009, 0x080c, 0xc320, 0x0040, 0x6014, 0x2048,
- 0xa807, 0x0000, 0xa867, 0x0103, 0xa833, 0xdead, 0x6010, 0x2058,
- 0xb9a0, 0x0016, 0x080c, 0x30d4, 0x080c, 0x9fd5, 0x001e, 0x080c,
- 0x31a6, 0x00de, 0x0804, 0xac2c, 0x00de, 0x080c, 0xae86, 0x6010,
- 0x2058, 0xbaa0, 0x9286, 0x0080, 0x1510, 0x6014, 0x9005, 0x01a8,
- 0x2048, 0xa864, 0x9084, 0x00ff, 0x9086, 0x0039, 0x1140, 0x2001,
- 0x0000, 0x900e, 0x2011, 0x4000, 0x080c, 0xc320, 0x0030, 0xa807,
- 0x0000, 0xa867, 0x0103, 0xa833, 0x0200, 0x2001, 0x0006, 0x080c,
- 0x62f5, 0x080c, 0x30d4, 0x080c, 0x9fd5, 0x0804, 0xac2c, 0x080c,
- 0xac3a, 0x6014, 0x9005, 0x0190, 0x2048, 0xa868, 0xd0f4, 0x01e8,
- 0xa864, 0x9084, 0x00ff, 0x9086, 0x0039, 0x1d08, 0x2001, 0x0000,
- 0x900e, 0x2011, 0x4000, 0x080c, 0xc320, 0x08f8, 0x080c, 0xac30,
- 0x0160, 0x9006, 0x080c, 0x62e1, 0x2001, 0x0004, 0x080c, 0x6321,
- 0x2001, 0x0007, 0x080c, 0x62f5, 0x08a0, 0x2001, 0x0004, 0x080c,
- 0x62f5, 0x6003, 0x0001, 0x6007, 0x0003, 0x080c, 0x8641, 0x080c,
- 0x8b90, 0x0804, 0xac2c, 0xb85c, 0xd0e4, 0x01d0, 0x080c, 0xc151,
- 0x080c, 0x717f, 0x0118, 0xd0dc, 0x1904, 0xab4d, 0x2011, 0x1836,
- 0x2204, 0xc0ad, 0x2012, 0x2001, 0x0002, 0x00f6, 0x2079, 0x0100,
- 0x78e3, 0x0000, 0x080c, 0x26e2, 0x78e2, 0x00fe, 0x0804, 0xab4d,
- 0x080c, 0xc18e, 0x2011, 0x1836, 0x2204, 0xc0a5, 0x2012, 0x0006,
- 0x080c, 0xd666, 0x000e, 0x1904, 0xab4d, 0xc0b5, 0x2012, 0x2001,
- 0x0006, 0x080c, 0x62f5, 0x9006, 0x080c, 0x62e1, 0x00c6, 0x2001,
- 0x180f, 0x2004, 0xd09c, 0x0520, 0x00f6, 0x2079, 0x0100, 0x00e6,
- 0x2071, 0x1800, 0x700c, 0x9084, 0x00ff, 0x78e6, 0x707a, 0x7010,
- 0x78ea, 0x707e, 0x908c, 0x00ff, 0x00ee, 0x780c, 0xc0b5, 0x780e,
- 0x00fe, 0x080c, 0x26b7, 0x00f6, 0x2100, 0x900e, 0x080c, 0x266e,
- 0x795a, 0x00fe, 0x9186, 0x0081, 0x01f0, 0x2009, 0x0081, 0x00e0,
- 0x2009, 0x00ef, 0x00f6, 0x2079, 0x0100, 0x79ea, 0x78e7, 0x0000,
- 0x7932, 0x7936, 0x780c, 0xc0b5, 0x780e, 0x00fe, 0x080c, 0x26b7,
- 0x00f6, 0x2079, 0x1800, 0x797e, 0x2100, 0x900e, 0x797a, 0x080c,
- 0x266e, 0x795a, 0x00fe, 0x8108, 0x080c, 0x6344, 0x2b00, 0x00ce,
- 0x1904, 0xab4d, 0x6012, 0x2009, 0x180f, 0x210c, 0xd19c, 0x0150,
- 0x2009, 0x027c, 0x210c, 0x918c, 0x00ff, 0xb912, 0x2009, 0x027d,
- 0x210c, 0xb916, 0x2001, 0x0002, 0x080c, 0x62f5, 0x6023, 0x0001,
- 0x6003, 0x0001, 0x6007, 0x0002, 0x080c, 0x8641, 0x080c, 0x8b90,
- 0x0018, 0x080c, 0xa995, 0x0431, 0x00de, 0x009e, 0x00be, 0x0005,
- 0x2001, 0x1810, 0x2004, 0xd0a4, 0x0120, 0x2001, 0x185c, 0x2004,
- 0xd0ac, 0x0005, 0x00e6, 0x080c, 0xdae8, 0x0190, 0x2071, 0x0260,
- 0x7108, 0x720c, 0x918c, 0x00ff, 0x1118, 0x9284, 0xff00, 0x0140,
- 0x6010, 0x2058, 0xb8a0, 0x9084, 0xff80, 0x1110, 0xb912, 0xba16,
- 0x00ee, 0x0005, 0x2030, 0x2001, 0x0007, 0x080c, 0x62f5, 0x080c,
- 0x54f0, 0x1120, 0x2001, 0x0007, 0x080c, 0x6321, 0x080c, 0x30d4,
- 0x6020, 0x9086, 0x000a, 0x1108, 0x0005, 0x0804, 0x9fd5, 0x00b6,
- 0x00e6, 0x0026, 0x0016, 0x2071, 0x1800, 0x708c, 0x9086, 0x0014,
- 0x1904, 0xad10, 0x00d6, 0x080c, 0x717f, 0x01a0, 0x0026, 0x2011,
- 0x0010, 0x080c, 0x66ee, 0x002e, 0x0904, 0xacc2, 0x080c, 0x54f0,
- 0x1598, 0x6014, 0x2048, 0xa807, 0x0000, 0xa867, 0x0103, 0xa833,
- 0xdead, 0x0450, 0x6010, 0x00b6, 0x2058, 0xb910, 0x00be, 0x9186,
- 0x00ff, 0x0580, 0x0026, 0x2011, 0x8008, 0x080c, 0x66ee, 0x002e,
- 0x0548, 0x6014, 0x9005, 0x090c, 0x0e02, 0x2048, 0xa864, 0x9084,
- 0x00ff, 0x9086, 0x0039, 0x1140, 0x2001, 0x0030, 0x900e, 0x2011,
- 0x4009, 0x080c, 0xc320, 0x0040, 0x6014, 0x2048, 0xa807, 0x0000,
- 0xa867, 0x0103, 0xa833, 0xdead, 0x6010, 0x2058, 0xb9a0, 0x0016,
- 0x080c, 0x30d4, 0x080c, 0x9fd5, 0x001e, 0x080c, 0x31a6, 0x00de,
- 0x0804, 0xad14, 0x00de, 0x080c, 0x54f0, 0x1170, 0x6014, 0x9005,
- 0x1158, 0x0036, 0x0046, 0x6010, 0x2058, 0xbba0, 0x2021, 0x0006,
- 0x080c, 0x4bb5, 0x004e, 0x003e, 0x00d6, 0x6010, 0x2058, 0x080c,
- 0x643f, 0x080c, 0xaab7, 0x00de, 0x080c, 0xaf57, 0x1588, 0x6010,
- 0x2058, 0xb890, 0x9005, 0x0560, 0x2001, 0x0006, 0x080c, 0x62f5,
- 0x0096, 0x6014, 0x904d, 0x01d0, 0xa864, 0x9084, 0x00ff, 0x9086,
- 0x0039, 0x1140, 0x2001, 0x0000, 0x900e, 0x2011, 0x4000, 0x080c,
- 0xc320, 0x0060, 0xa864, 0x9084, 0x00ff, 0x9086, 0x0029, 0x0130,
- 0xa807, 0x0000, 0xa867, 0x0103, 0xa833, 0x0200, 0x009e, 0x080c,
- 0x30d4, 0x6020, 0x9086, 0x000a, 0x0138, 0x080c, 0x9fd5, 0x0020,
- 0x080c, 0xa995, 0x080c, 0xac52, 0x001e, 0x002e, 0x00ee, 0x00be,
- 0x0005, 0x2011, 0x1823, 0x2204, 0x9086, 0x0014, 0x1160, 0x2001,
- 0x0002, 0x080c, 0x62f5, 0x6003, 0x0001, 0x6007, 0x0001, 0x080c,
- 0x8641, 0x0804, 0x8b90, 0x0804, 0xac52, 0x2030, 0x2011, 0x1823,
- 0x2204, 0x9086, 0x0004, 0x1148, 0x96b6, 0x000b, 0x1120, 0x2001,
- 0x0007, 0x080c, 0x62f5, 0x0804, 0x9fd5, 0x0804, 0xac52, 0x0002,
- 0xaa76, 0xad57, 0xaa76, 0xad98, 0xaa76, 0xae43, 0xad4c, 0xaa79,
- 0xaa76, 0xae55, 0xaa76, 0xae65, 0x6604, 0x9686, 0x0003, 0x0904,
- 0xac67, 0x96b6, 0x001e, 0x1110, 0x080c, 0x9fd5, 0x0005, 0x00b6,
- 0x00d6, 0x00c6, 0x080c, 0xae75, 0x11a0, 0x9006, 0x080c, 0x62e1,
- 0x080c, 0x30ab, 0x080c, 0xc459, 0x2001, 0x0002, 0x080c, 0x62f5,
- 0x6003, 0x0001, 0x6007, 0x0002, 0x080c, 0x8641, 0x080c, 0x8b90,
- 0x0418, 0x2009, 0x026e, 0x2104, 0x9086, 0x0009, 0x1160, 0x6010,
- 0x2058, 0xb840, 0x9084, 0x00ff, 0x9005, 0x0180, 0x8001, 0xb842,
- 0x601b, 0x000a, 0x0088, 0x2009, 0x026f, 0x2104, 0x9084, 0xff00,
- 0x908e, 0x1900, 0x0148, 0x908e, 0x1e00, 0x0990, 0x080c, 0x30ab,
- 0x080c, 0xc459, 0x080c, 0xac52, 0x00ce, 0x00de, 0x00be, 0x0005,
- 0x0096, 0x00b6, 0x0026, 0x9016, 0x080c, 0xae83, 0x00d6, 0x2069,
- 0x1956, 0x2d04, 0x9005, 0x0168, 0x6010, 0x2058, 0xb8a0, 0x9086,
- 0x007e, 0x1138, 0x2069, 0x181f, 0x2d04, 0x8000, 0x206a, 0x00de,
- 0x0010, 0x00de, 0x0088, 0x9006, 0x080c, 0x62e1, 0x2001, 0x0002,
- 0x080c, 0x62f5, 0x6003, 0x0001, 0x6007, 0x0002, 0x080c, 0x8641,
- 0x080c, 0x8b90, 0x0804, 0xae13, 0x080c, 0xbd3b, 0x01b0, 0x6014,
- 0x2048, 0xa864, 0x2010, 0x9086, 0x0139, 0x1138, 0x6007, 0x0016,
- 0x2001, 0x0002, 0x080c, 0xc37d, 0x00b0, 0x6014, 0x2048, 0xa864,
- 0xd0fc, 0x0118, 0x2001, 0x0001, 0x0ca8, 0x2001, 0x180e, 0x2004,
- 0xd0dc, 0x0148, 0x6010, 0x2058, 0xb840, 0x9084, 0x00ff, 0x9005,
- 0x1110, 0x9006, 0x0c38, 0x080c, 0xa995, 0x2009, 0x026e, 0x2134,
- 0x96b4, 0x00ff, 0x9686, 0x0005, 0x0510, 0x9686, 0x000b, 0x01c8,
- 0x2009, 0x026f, 0x2104, 0x9084, 0xff00, 0x1118, 0x9686, 0x0009,
- 0x01b0, 0x9086, 0x1900, 0x1168, 0x9686, 0x0009, 0x0180, 0x2001,
- 0x0004, 0x080c, 0x62f5, 0x2001, 0x0028, 0x601a, 0x6007, 0x0052,
- 0x0010, 0x080c, 0xac52, 0x002e, 0x00be, 0x009e, 0x0005, 0x9286,
- 0x0139, 0x0160, 0x6014, 0x2048, 0x080c, 0xbd3b, 0x0140, 0xa864,
- 0x9086, 0x0139, 0x0118, 0xa868, 0xd0fc, 0x0108, 0x0c50, 0x6010,
- 0x2058, 0xb840, 0x9084, 0x00ff, 0x9005, 0x0138, 0x8001, 0xb842,
- 0x601b, 0x000a, 0x6007, 0x0016, 0x08f0, 0xb8a0, 0x9086, 0x007e,
- 0x1138, 0x00e6, 0x2071, 0x1800, 0x080c, 0x5dc3, 0x00ee, 0x0010,
- 0x080c, 0x30ab, 0x0870, 0x2001, 0x0004, 0x080c, 0x62f5, 0x04d9,
- 0x1140, 0x6003, 0x0001, 0x6007, 0x0003, 0x080c, 0x8641, 0x0804,
- 0x8b90, 0x080c, 0xa995, 0x0804, 0xac52, 0x0469, 0x1160, 0x2001,
- 0x0008, 0x080c, 0x62f5, 0x6003, 0x0001, 0x6007, 0x0005, 0x080c,
- 0x8641, 0x0804, 0x8b90, 0x0804, 0xac52, 0x00e9, 0x1160, 0x2001,
- 0x000a, 0x080c, 0x62f5, 0x6003, 0x0001, 0x6007, 0x0001, 0x080c,
- 0x8641, 0x0804, 0x8b90, 0x0804, 0xac52, 0x2009, 0x026e, 0x2104,
- 0x9086, 0x0003, 0x1138, 0x2009, 0x026f, 0x2104, 0x9084, 0xff00,
- 0x9086, 0x2a00, 0x0005, 0x9085, 0x0001, 0x0005, 0x00b6, 0x00c6,
- 0x0016, 0x6110, 0x2158, 0x080c, 0x63b3, 0x001e, 0x00ce, 0x00be,
- 0x0005, 0x00b6, 0x00f6, 0x00e6, 0x00d6, 0x0036, 0x0016, 0x6010,
- 0x2058, 0x2009, 0x1836, 0x2104, 0x9085, 0x0003, 0x200a, 0x080c,
- 0xaf29, 0x0560, 0x2009, 0x1836, 0x2104, 0xc0cd, 0x200a, 0x080c,
- 0x66c6, 0x0158, 0x9006, 0x2020, 0x2009, 0x002a, 0x080c, 0xd7d6,
- 0x2001, 0x180c, 0x200c, 0xc195, 0x2102, 0x2019, 0x002a, 0x2009,
- 0x0001, 0x080c, 0x3076, 0x00e6, 0x2071, 0x1800, 0x080c, 0x2e8c,
- 0x00ee, 0x00c6, 0x0156, 0x20a9, 0x0781, 0x2009, 0x007f, 0x080c,
- 0x31a6, 0x8108, 0x1f04, 0xaec7, 0x015e, 0x00ce, 0x080c, 0xae86,
- 0x2071, 0x0260, 0x2079, 0x0200, 0x7817, 0x0001, 0x2001, 0x1836,
- 0x200c, 0xc1c5, 0x7018, 0xd0fc, 0x0110, 0xd0dc, 0x0118, 0x7038,
- 0xd0dc, 0x1108, 0xc1c4, 0x7817, 0x0000, 0x2001, 0x1836, 0x2102,
- 0x2079, 0x0100, 0x2e04, 0x9084, 0x00ff, 0x2069, 0x181e, 0x206a,
- 0x78e6, 0x0006, 0x8e70, 0x2e04, 0x2069, 0x181f, 0x206a, 0x78ea,
- 0x7832, 0x7836, 0x2010, 0x9084, 0xff00, 0x001e, 0x9105, 0x2009,
- 0x182b, 0x200a, 0x2200, 0x9084, 0x00ff, 0x2008, 0x080c, 0x26b7,
- 0x080c, 0x717f, 0x0170, 0x2071, 0x0260, 0x2069, 0x195c, 0x7048,
- 0x206a, 0x704c, 0x6806, 0x7050, 0x680a, 0x7054, 0x680e, 0x080c,
- 0xc151, 0x0040, 0x2001, 0x0006, 0x080c, 0x62f5, 0x080c, 0x30d4,
- 0x080c, 0x9fd5, 0x001e, 0x003e, 0x00de, 0x00ee, 0x00fe, 0x00be,
- 0x0005, 0x0096, 0x0026, 0x0036, 0x00e6, 0x0156, 0x2019, 0x182b,
- 0x231c, 0x83ff, 0x01f0, 0x2071, 0x0260, 0x7200, 0x9294, 0x00ff,
- 0x7004, 0x9084, 0xff00, 0x9205, 0x9306, 0x1198, 0x2011, 0x0276,
- 0x20a9, 0x0004, 0x2b48, 0x2019, 0x000a, 0x080c, 0xb00b, 0x1148,
- 0x2011, 0x027a, 0x20a9, 0x0004, 0x2019, 0x0006, 0x080c, 0xb00b,
- 0x1100, 0x015e, 0x00ee, 0x003e, 0x002e, 0x009e, 0x0005, 0x00e6,
- 0x2071, 0x0260, 0x7034, 0x9086, 0x0014, 0x11a8, 0x7038, 0x9086,
- 0x0800, 0x1188, 0x703c, 0xd0ec, 0x0160, 0x9084, 0x0f00, 0x9086,
- 0x0100, 0x1138, 0x7054, 0xd0a4, 0x1110, 0xd0ac, 0x0110, 0x9006,
- 0x0010, 0x9085, 0x0001, 0x00ee, 0x0005, 0x00e6, 0x0096, 0x00c6,
- 0x0076, 0x0056, 0x0046, 0x0026, 0x0006, 0x0126, 0x2091, 0x8000,
- 0x2029, 0x19cb, 0x252c, 0x2021, 0x19d1, 0x2424, 0x2061, 0x1cd0,
- 0x2071, 0x1800, 0x7250, 0x7070, 0x9202, 0x1a04, 0xafe3, 0x080c,
- 0xd807, 0x0904, 0xafdc, 0x6720, 0x9786, 0x0007, 0x0904, 0xafdc,
- 0x2500, 0x9c06, 0x0904, 0xafdc, 0x2400, 0x9c06, 0x05e8, 0x3e08,
- 0x9186, 0x0002, 0x1148, 0x6010, 0x9005, 0x0130, 0x00b6, 0x2058,
- 0xb800, 0x00be, 0xd0bc, 0x1580, 0x00c6, 0x6000, 0x9086, 0x0004,
- 0x1110, 0x080c, 0x1938, 0x9786, 0x000a, 0x0148, 0x080c, 0xbf43,
- 0x1130, 0x00ce, 0x080c, 0xa995, 0x080c, 0xa007, 0x00e8, 0x6014,
- 0x2048, 0x080c, 0xbd3b, 0x01a8, 0x9786, 0x0003, 0x1530, 0xa867,
- 0x0103, 0xa87c, 0xd0cc, 0x0130, 0x0096, 0xa878, 0x2048, 0x080c,
- 0x0ff5, 0x009e, 0xab7a, 0xa877, 0x0000, 0x080c, 0x6a16, 0x080c,
- 0xbf26, 0x080c, 0xa007, 0x00ce, 0x9ce0, 0x0018, 0x7064, 0x9c02,
- 0x1210, 0x0804, 0xaf8a, 0x012e, 0x000e, 0x002e, 0x004e, 0x005e,
- 0x007e, 0x00ce, 0x009e, 0x00ee, 0x0005, 0x9786, 0x0006, 0x1118,
- 0x080c, 0xd781, 0x0c30, 0x9786, 0x000a, 0x09e0, 0x0880, 0x220c,
- 0x2304, 0x9106, 0x1130, 0x8210, 0x8318, 0x1f04, 0xaff7, 0x9006,
- 0x0005, 0x2304, 0x9102, 0x0218, 0x2001, 0x0001, 0x0008, 0x9006,
- 0x918d, 0x0001, 0x0005, 0x0136, 0x01c6, 0x0016, 0x8906, 0x8006,
- 0x8007, 0x908c, 0x003f, 0x21e0, 0x9084, 0xffc0, 0x9300, 0x2098,
- 0x3518, 0x20a9, 0x0001, 0x220c, 0x4002, 0x910e, 0x1140, 0x8210,
- 0x8319, 0x1dc8, 0x9006, 0x001e, 0x01ce, 0x013e, 0x0005, 0x220c,
- 0x9102, 0x0218, 0x2001, 0x0001, 0x0010, 0x2001, 0x0000, 0x918d,
- 0x0001, 0x001e, 0x01ce, 0x013e, 0x0005, 0x6004, 0x908a, 0x0053,
- 0x1a0c, 0x0e02, 0x080c, 0xbf32, 0x0120, 0x080c, 0xbf43, 0x0168,
- 0x0028, 0x080c, 0x30d4, 0x080c, 0xbf43, 0x0138, 0x080c, 0x8a84,
- 0x080c, 0x9fd5, 0x080c, 0x8b90, 0x0005, 0x080c, 0xa995, 0x0cb0,
+ 0x0008, 0x8529, 0x7552, 0x9ca8, 0x0018, 0x7064, 0x9502, 0x1228,
+ 0x7556, 0x9085, 0x0001, 0x00ee, 0x0005, 0x7057, 0x1cd0, 0x0cc8,
+ 0x9006, 0x0cc8, 0x9c82, 0x1cd0, 0x0a0c, 0x0df6, 0x2001, 0x1819,
+ 0x2004, 0x9c02, 0x1a0c, 0x0df6, 0x9006, 0x6006, 0x600a, 0x600e,
+ 0x6016, 0x601a, 0x6012, 0x6023, 0x0000, 0x6003, 0x0000, 0x601e,
+ 0x6056, 0x605a, 0x6026, 0x602a, 0x602e, 0x6032, 0x6036, 0x603a,
+ 0x603e, 0x6042, 0x2061, 0x1800, 0x6050, 0x8000, 0x6052, 0x9086,
+ 0x0001, 0x0108, 0x0005, 0x0126, 0x2091, 0x8000, 0x0016, 0x080c,
+ 0x8b8f, 0x001e, 0x012e, 0x0cb0, 0x0006, 0x6000, 0x9086, 0x0000,
+ 0x01c0, 0x601c, 0xd084, 0x190c, 0x192c, 0x6017, 0x0000, 0x6023,
+ 0x0007, 0x2001, 0x1960, 0x2004, 0x0006, 0x9082, 0x0051, 0x000e,
+ 0x0208, 0x8004, 0x601a, 0x080c, 0xda94, 0x6043, 0x0000, 0x6013,
+ 0x0000, 0x000e, 0x0005, 0x00e6, 0x0126, 0x2071, 0x1800, 0x2091,
+ 0x8000, 0x7550, 0x9582, 0x0001, 0x0608, 0x7054, 0x2060, 0x6000,
+ 0x9086, 0x0000, 0x0148, 0x9ce0, 0x0018, 0x7064, 0x9c02, 0x1208,
+ 0x0cb0, 0x2061, 0x1cd0, 0x0c98, 0x6003, 0x0008, 0x8529, 0x7552,
+ 0x9ca8, 0x0018, 0x7064, 0x9502, 0x1230, 0x7556, 0x9085, 0x0001,
+ 0x012e, 0x00ee, 0x0005, 0x7057, 0x1cd0, 0x0cc0, 0x9006, 0x0cc0,
+ 0x6020, 0x9084, 0x000f, 0x0002, 0xa07b, 0xa084, 0xa09f, 0xa0ba,
+ 0xc4a1, 0xc4be, 0xc4d9, 0xa07b, 0xa084, 0xa07b, 0xa0d3, 0xa07b,
+ 0xa07b, 0xa07b, 0xa07b, 0x9186, 0x0013, 0x1128, 0x080c, 0x8a83,
+ 0x080c, 0x8b8f, 0x0005, 0x0005, 0x0066, 0x6000, 0x90b2, 0x0010,
+ 0x1a0c, 0x0df6, 0x0013, 0x006e, 0x0005, 0xa09d, 0xa803, 0xa9ee,
+ 0xa09d, 0xaa7c, 0xa3b6, 0xa09d, 0xa09d, 0xa785, 0xb041, 0xa09d,
+ 0xa09d, 0xa09d, 0xa09d, 0xa09d, 0xa09d, 0x080c, 0x0df6, 0x0066,
+ 0x6000, 0x90b2, 0x0010, 0x1a0c, 0x0df6, 0x0013, 0x006e, 0x0005,
+ 0xa0b8, 0xb70e, 0xa0b8, 0xa0b8, 0xa0b8, 0xa0b8, 0xa0b8, 0xa0b8,
+ 0xb6a5, 0xb890, 0xa0b8, 0xb74f, 0xb7ce, 0xb74f, 0xb7ce, 0xa0b8,
+ 0x080c, 0x0df6, 0x6000, 0x9082, 0x0010, 0x1a0c, 0x0df6, 0x6000,
+ 0x0002, 0xa0d1, 0xb088, 0xb150, 0xb283, 0xb432, 0xa0d1, 0xa0d1,
+ 0xa0d1, 0xb05c, 0xb631, 0xb634, 0xa0d1, 0xa0d1, 0xa0d1, 0xa0d1,
+ 0xb663, 0x080c, 0x0df6, 0x0066, 0x6000, 0x90b2, 0x0010, 0x1a0c,
+ 0x0df6, 0x0013, 0x006e, 0x0005, 0xa0ec, 0xa0ec, 0xa12f, 0xa1ce,
+ 0xa263, 0xa0ec, 0xa0ec, 0xa0ec, 0xa0ee, 0xa0ec, 0xa0ec, 0xa0ec,
+ 0xa0ec, 0xa0ec, 0xa0ec, 0xa0ec, 0x080c, 0x0df6, 0x9186, 0x004c,
+ 0x0588, 0x9186, 0x0003, 0x190c, 0x0df6, 0x0096, 0x601c, 0xc0ed,
+ 0x601e, 0x6003, 0x0003, 0x6106, 0x6014, 0x2048, 0xa87c, 0x9084,
+ 0xa000, 0xc0b5, 0xa87e, 0xa8ac, 0xa846, 0xa8b0, 0xa84a, 0x9006,
+ 0xa836, 0xa83a, 0xa884, 0x9092, 0x199a, 0x0210, 0x2001, 0x1999,
+ 0x8003, 0x8013, 0x8213, 0x9210, 0x621a, 0x009e, 0x2c10, 0x080c,
+ 0x1a7e, 0x080c, 0x865d, 0x0126, 0x2091, 0x8000, 0x080c, 0x8c6c,
+ 0x012e, 0x0005, 0x6010, 0x00b6, 0x2058, 0xbca0, 0x00be, 0x2c00,
+ 0x080c, 0xa285, 0x080c, 0xc471, 0x6003, 0x0007, 0x0005, 0x00d6,
+ 0x0096, 0x00f6, 0x2079, 0x1800, 0x7a8c, 0x6014, 0x2048, 0xa87c,
+ 0xd0ec, 0x1110, 0x9290, 0x0018, 0xac78, 0xc4fc, 0x0046, 0xa8e0,
+ 0x9005, 0x1140, 0xa8dc, 0x921a, 0x0140, 0x0220, 0xa87b, 0x0007,
+ 0x2010, 0x0028, 0xa87b, 0x0015, 0x0010, 0xa87b, 0x0000, 0x8214,
+ 0xa883, 0x0000, 0xaa02, 0x0006, 0x0016, 0x0026, 0x00c6, 0x00d6,
+ 0x00e6, 0x00f6, 0x2400, 0x9005, 0x1108, 0x009a, 0x2100, 0x9086,
+ 0x0015, 0x1118, 0x2001, 0x0001, 0x0038, 0x2100, 0x9086, 0x0016,
+ 0x0118, 0x2001, 0x0001, 0x002a, 0x94a4, 0x0007, 0x8423, 0x9405,
+ 0x0002, 0xa196, 0xa196, 0xa191, 0xa194, 0xa196, 0xa18e, 0xa181,
+ 0xa181, 0xa181, 0xa181, 0xa181, 0xa181, 0xa181, 0xa181, 0xa181,
+ 0xa181, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x002e, 0x001e, 0x000e,
+ 0x004e, 0x00fe, 0x009e, 0x00de, 0x080c, 0x0df6, 0x080c, 0xac6e,
+ 0x0028, 0x080c, 0xad9f, 0x0010, 0x080c, 0xae8d, 0x00fe, 0x00ee,
+ 0x00de, 0x00ce, 0x002e, 0x001e, 0x2c00, 0xa896, 0x000e, 0x080c,
+ 0xa343, 0x0530, 0xa804, 0xa80e, 0x00a6, 0x2050, 0xb100, 0x00ae,
+ 0x8006, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080,
+ 0x0002, 0xaacc, 0xabd0, 0xacd4, 0xadd8, 0x2031, 0x0000, 0x2041,
+ 0x12a8, 0x080c, 0xa4f1, 0x0160, 0x000e, 0x9005, 0x0120, 0x00fe,
+ 0x009e, 0x00de, 0x0005, 0x00fe, 0x009e, 0x00de, 0x0804, 0x9fea,
+ 0x2001, 0x002c, 0x900e, 0x080c, 0xa3a9, 0x0c70, 0x91b6, 0x0015,
+ 0x0170, 0x91b6, 0x0016, 0x0158, 0x91b2, 0x0047, 0x0a0c, 0x0df6,
+ 0x91b2, 0x0050, 0x1a0c, 0x0df6, 0x9182, 0x0047, 0x00ca, 0x2001,
+ 0x0109, 0x2004, 0xd08c, 0x0198, 0x0126, 0x2091, 0x2800, 0x0006,
+ 0x0016, 0x0026, 0x080c, 0x85b1, 0x002e, 0x001e, 0x000e, 0x012e,
+ 0xa001, 0x6000, 0x9086, 0x0002, 0x1110, 0x0804, 0xa12f, 0x0005,
+ 0xa201, 0xa201, 0xa203, 0xa239, 0xa201, 0xa201, 0xa201, 0xa201,
+ 0xa24c, 0x080c, 0x0df6, 0x00d6, 0x0016, 0x0096, 0x080c, 0x8b3f,
+ 0x080c, 0x8c6c, 0x6003, 0x0004, 0x6114, 0x2148, 0xa87c, 0xd0fc,
+ 0x01c0, 0xa878, 0xc0fc, 0x9005, 0x1158, 0xa894, 0x9005, 0x0140,
+ 0x2001, 0x0000, 0x900e, 0x080c, 0xa3a9, 0x080c, 0x9fea, 0x00a8,
+ 0x6003, 0x0002, 0xa8a4, 0xa9a8, 0x9105, 0x1178, 0xa8ae, 0xa8b2,
+ 0x0c78, 0xa87f, 0x0020, 0xa88c, 0xa88a, 0xa8a4, 0xa8ae, 0xa8a8,
+ 0xa8b2, 0xa8c7, 0x0000, 0xa8cb, 0x0000, 0x009e, 0x001e, 0x00de,
+ 0x0005, 0x080c, 0x8b3f, 0x00d6, 0x0096, 0x6114, 0x2148, 0x080c,
+ 0xbd4e, 0x0120, 0xa87b, 0x0006, 0x080c, 0x6a22, 0x009e, 0x00de,
+ 0x080c, 0x9fea, 0x0804, 0x8c6c, 0x080c, 0x8b3f, 0x080c, 0x3095,
+ 0x080c, 0xc46e, 0x00d6, 0x0096, 0x6114, 0x2148, 0x080c, 0xbd4e,
+ 0x0120, 0xa87b, 0x0029, 0x080c, 0x6a22, 0x009e, 0x00de, 0x080c,
+ 0x9fea, 0x0804, 0x8c6c, 0x9182, 0x0047, 0x0002, 0xa273, 0xa275,
+ 0xa273, 0xa273, 0xa273, 0xa273, 0xa273, 0xa273, 0xa273, 0xa273,
+ 0xa273, 0xa273, 0xa275, 0x080c, 0x0df6, 0x00d6, 0x0096, 0x080c,
+ 0x1577, 0x6114, 0x2148, 0xa87b, 0x0000, 0xa883, 0x0000, 0x080c,
+ 0x6a22, 0x009e, 0x00de, 0x0804, 0x9fea, 0x0026, 0x0036, 0x0056,
+ 0x0066, 0x0096, 0x00a6, 0x00f6, 0x0006, 0x080c, 0x1037, 0x000e,
+ 0x090c, 0x0df6, 0xa960, 0x21e8, 0xa95c, 0x9188, 0x0019, 0x21a0,
+ 0x900e, 0x20a9, 0x0020, 0x4104, 0xa87a, 0x2079, 0x1800, 0x798c,
+ 0x9188, 0x0018, 0x918c, 0x0fff, 0xa972, 0xac76, 0x2950, 0x00a6,
+ 0x2001, 0x0205, 0x2003, 0x0000, 0x901e, 0x2029, 0x0001, 0x9182,
+ 0x0035, 0x1228, 0x2011, 0x001f, 0x080c, 0xb915, 0x04c0, 0x2130,
+ 0x2009, 0x0034, 0x2011, 0x001f, 0x080c, 0xb915, 0x96b2, 0x0034,
+ 0xb004, 0x904d, 0x0110, 0x080c, 0x0fe9, 0x080c, 0x1037, 0x01d0,
+ 0x8528, 0xa867, 0x0110, 0xa86b, 0x0000, 0x2920, 0xb406, 0x968a,
+ 0x003d, 0x1230, 0x2608, 0x2011, 0x001b, 0x080c, 0xb915, 0x00b8,
+ 0x96b2, 0x003c, 0x2009, 0x003c, 0x2950, 0x2011, 0x001b, 0x080c,
+ 0xb915, 0x0c18, 0x2001, 0x0205, 0x2003, 0x0000, 0x00ae, 0x852f,
+ 0x95ad, 0x0050, 0xb566, 0xb070, 0xc0fd, 0xb072, 0x0048, 0x2001,
+ 0x0205, 0x2003, 0x0000, 0x00ae, 0x852f, 0x95ad, 0x0050, 0xb566,
+ 0x2a48, 0xa804, 0xa807, 0x0000, 0x0006, 0x080c, 0x6a22, 0x000e,
+ 0x2048, 0x9005, 0x1db0, 0x00fe, 0x00ae, 0x009e, 0x006e, 0x005e,
+ 0x003e, 0x002e, 0x0005, 0x00d6, 0x00f6, 0x0096, 0x0006, 0x080c,
+ 0x1037, 0x000e, 0x090c, 0x0df6, 0xa960, 0x21e8, 0xa95c, 0x9188,
+ 0x0019, 0x21a0, 0x900e, 0x20a9, 0x0020, 0x4104, 0xaa66, 0xa87a,
+ 0x2079, 0x1800, 0x798c, 0x810c, 0x9188, 0x000c, 0x9182, 0x001a,
+ 0x0210, 0x2009, 0x001a, 0x21a8, 0x810b, 0xa972, 0xac76, 0x2e98,
+ 0xa85c, 0x9080, 0x001f, 0x20a0, 0x2001, 0x0205, 0x200c, 0x918d,
+ 0x0080, 0x2102, 0x4003, 0x2003, 0x0000, 0x080c, 0x6a22, 0x009e,
+ 0x00fe, 0x00de, 0x0005, 0x0016, 0x00d6, 0x00f6, 0x0096, 0x0016,
+ 0x2001, 0x0205, 0x200c, 0x918d, 0x0080, 0x2102, 0x001e, 0x2079,
+ 0x0200, 0x2e98, 0xa87c, 0xd0ec, 0x0118, 0x9e80, 0x000c, 0x2098,
+ 0x2021, 0x003e, 0x901e, 0x9282, 0x0020, 0x0218, 0x2011, 0x0020,
+ 0x2018, 0x9486, 0x003e, 0x1170, 0x0096, 0x080c, 0x1037, 0x2900,
+ 0x009e, 0x05c0, 0xa806, 0x2048, 0xa860, 0x20e8, 0xa85c, 0x9080,
+ 0x0002, 0x20a0, 0x3300, 0x908e, 0x0260, 0x0140, 0x2009, 0x0280,
+ 0x9102, 0x920a, 0x0218, 0x2010, 0x2100, 0x9318, 0x2200, 0x9402,
+ 0x1228, 0x2400, 0x9202, 0x2410, 0x9318, 0x9006, 0x2020, 0x22a8,
+ 0xa800, 0x9200, 0xa802, 0x20e1, 0x0000, 0x4003, 0x83ff, 0x0180,
+ 0x3300, 0x9086, 0x0280, 0x1130, 0x7814, 0x8000, 0x9085, 0x0080,
+ 0x7816, 0x2e98, 0x2310, 0x84ff, 0x0904, 0xa358, 0x0804, 0xa35a,
+ 0x9085, 0x0001, 0x7817, 0x0000, 0x009e, 0x00fe, 0x00de, 0x001e,
+ 0x0005, 0x00d6, 0x0036, 0x0096, 0x6314, 0x2348, 0xa87a, 0xa982,
+ 0x080c, 0x6a15, 0x009e, 0x003e, 0x00de, 0x0005, 0x91b6, 0x0015,
+ 0x1118, 0x080c, 0x9fea, 0x0030, 0x91b6, 0x0016, 0x190c, 0x0df6,
+ 0x080c, 0x9fea, 0x0005, 0x20a9, 0x000e, 0x20e1, 0x0000, 0x2e98,
+ 0x6014, 0x0096, 0x2048, 0xa860, 0x20e8, 0xa85c, 0x20a0, 0x009e,
+ 0x4003, 0x9196, 0x0016, 0x01f0, 0x0136, 0x9080, 0x001b, 0x20a0,
+ 0x2011, 0x0006, 0x20a9, 0x0001, 0x3418, 0x8318, 0x23a0, 0x4003,
+ 0x3318, 0x8318, 0x2398, 0x8211, 0x1db8, 0x2011, 0x0006, 0x013e,
+ 0x20a0, 0x3318, 0x8318, 0x2398, 0x4003, 0x3418, 0x8318, 0x23a0,
+ 0x8211, 0x1db8, 0x0096, 0x080c, 0xbd4e, 0x0130, 0x6014, 0x2048,
+ 0xa807, 0x0000, 0xa867, 0x0103, 0x009e, 0x0804, 0x9fea, 0x0096,
+ 0x00d6, 0x0036, 0x7330, 0x9386, 0x0200, 0x11a8, 0x6010, 0x00b6,
+ 0x2058, 0xb8bf, 0x0000, 0x00be, 0x6014, 0x9005, 0x0130, 0x2048,
+ 0xa807, 0x0000, 0xa867, 0x0103, 0xab32, 0x080c, 0x9fea, 0x003e,
+ 0x00de, 0x009e, 0x0005, 0x0011, 0x1d48, 0x0cc8, 0x0006, 0x0016,
+ 0x080c, 0xc459, 0x0188, 0x6014, 0x9005, 0x1170, 0x600b, 0x0003,
+ 0x601b, 0x0000, 0x6043, 0x0000, 0x2009, 0x0022, 0x080c, 0xa7db,
+ 0x9006, 0x001e, 0x000e, 0x0005, 0x9085, 0x0001, 0x0cd0, 0x0096,
+ 0x0016, 0x20a9, 0x0014, 0x9e80, 0x000c, 0x20e1, 0x0000, 0x2098,
+ 0x6014, 0x2048, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0002, 0x20a0,
+ 0x4003, 0x2001, 0x0205, 0x2003, 0x0001, 0x2099, 0x0260, 0x20a9,
+ 0x0016, 0x4003, 0x20a9, 0x000a, 0xa804, 0x2048, 0xa860, 0x20e8,
+ 0xa85c, 0x9080, 0x0002, 0x20a0, 0x4003, 0x2001, 0x0205, 0x2003,
+ 0x0002, 0x2099, 0x0260, 0x20a9, 0x0020, 0x4003, 0x2003, 0x0000,
+ 0x6014, 0x2048, 0xa800, 0x2048, 0xa867, 0x0103, 0x080c, 0x9fea,
+ 0x001e, 0x009e, 0x0005, 0x0096, 0x0016, 0x900e, 0x7030, 0x9086,
+ 0x0100, 0x0140, 0x7038, 0x9084, 0x00ff, 0x800c, 0x703c, 0x9084,
+ 0x00ff, 0x8004, 0x9080, 0x0004, 0x9108, 0x810b, 0x2011, 0x0002,
+ 0x2019, 0x000c, 0x6014, 0x2048, 0x080c, 0xb915, 0x080c, 0xbd4e,
+ 0x0140, 0x6014, 0x2048, 0xa807, 0x0000, 0xa864, 0xa8e2, 0xa867,
+ 0x0103, 0x080c, 0x9fea, 0x001e, 0x009e, 0x0005, 0x0016, 0x0096,
+ 0x7030, 0x9086, 0x0100, 0x1118, 0x2009, 0x0004, 0x0010, 0x7034,
+ 0x800c, 0x810b, 0x2011, 0x000c, 0x2019, 0x000c, 0x6014, 0x2048,
+ 0xa804, 0x0096, 0x9005, 0x0108, 0x2048, 0x080c, 0xb915, 0x009e,
+ 0x080c, 0xbd4e, 0x0148, 0xa804, 0x9005, 0x1158, 0xa807, 0x0000,
+ 0xa864, 0xa8e2, 0xa867, 0x0103, 0x080c, 0x9fea, 0x009e, 0x001e,
+ 0x0005, 0x0086, 0x2040, 0xa030, 0x8007, 0x9086, 0x0100, 0x1118,
+ 0x080c, 0xa9a7, 0x00e0, 0xa034, 0x8007, 0x800c, 0x8806, 0x8006,
+ 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, 0x000c, 0xa87b,
+ 0x0000, 0xa883, 0x0000, 0xa897, 0x4000, 0xaaa0, 0xab9c, 0xaca8,
+ 0xada4, 0x2031, 0x0000, 0x2041, 0x128e, 0x0019, 0x0d08, 0x008e,
+ 0x0898, 0x0096, 0x0006, 0x080c, 0x1037, 0x000e, 0x01b0, 0xa8ab,
+ 0x0dcb, 0xa876, 0x000e, 0xa8a2, 0x0006, 0xae6a, 0x2800, 0xa89e,
+ 0xa97a, 0xaf72, 0xaa8e, 0xab92, 0xac96, 0xad9a, 0x0086, 0x2940,
+ 0x080c, 0x1134, 0x008e, 0x9085, 0x0001, 0x009e, 0x0005, 0x00e6,
+ 0x00d6, 0x0026, 0x7008, 0x9084, 0x00ff, 0x6210, 0x00b6, 0x2258,
+ 0xba10, 0x00be, 0x9206, 0x1520, 0x700c, 0x6210, 0x00b6, 0x2258,
+ 0xba14, 0x00be, 0x9206, 0x11e0, 0x6043, 0x0000, 0x2c68, 0x0016,
+ 0x2009, 0x0035, 0x080c, 0xc3cf, 0x001e, 0x1158, 0x622c, 0x2268,
+ 0x2071, 0x026c, 0x6b20, 0x9386, 0x0003, 0x0130, 0x9386, 0x0006,
+ 0x0128, 0x080c, 0x9fea, 0x0020, 0x0039, 0x0010, 0x080c, 0xa610,
+ 0x002e, 0x00de, 0x00ee, 0x0005, 0x0096, 0x6814, 0x2048, 0x9186,
+ 0x0015, 0x0904, 0xa5f8, 0x918e, 0x0016, 0x1904, 0xa60e, 0x700c,
+ 0x908c, 0xff00, 0x9186, 0x1700, 0x0120, 0x9186, 0x0300, 0x1904,
+ 0xa5d2, 0x89ff, 0x1138, 0x6800, 0x9086, 0x000f, 0x0904, 0xa5b5,
+ 0x0804, 0xa60c, 0x6808, 0x9086, 0xffff, 0x1904, 0xa5fa, 0xa87c,
+ 0x9084, 0x0060, 0x9086, 0x0020, 0x1128, 0xa83c, 0xa940, 0x9105,
+ 0x1904, 0xa5fa, 0x6824, 0xd084, 0x1904, 0xa5fa, 0xd0b4, 0x0158,
+ 0x0016, 0x2001, 0x1960, 0x200c, 0x6018, 0x9102, 0x9082, 0x0005,
+ 0x001e, 0x1a04, 0xa5fa, 0x080c, 0xbf39, 0x685c, 0xa882, 0xa87c,
+ 0xc0dc, 0xc0f4, 0xc0d4, 0xa87e, 0x0026, 0x900e, 0x6a18, 0x2001,
+ 0x000a, 0x080c, 0x847e, 0xa884, 0x920a, 0x0208, 0x8011, 0xaa86,
+ 0x82ff, 0x002e, 0x1138, 0x00c6, 0x2d60, 0x080c, 0xba77, 0x00ce,
+ 0x0804, 0xa60c, 0x00c6, 0xa868, 0xd0fc, 0x1118, 0x080c, 0x5eab,
+ 0x0010, 0x080c, 0x6259, 0x00ce, 0x1904, 0xa5fa, 0x00c6, 0x2d60,
+ 0x080c, 0x9fea, 0x00ce, 0x0804, 0xa60c, 0x00c6, 0x080c, 0xa03b,
+ 0x0198, 0x6017, 0x0000, 0x6810, 0x6012, 0x080c, 0xc1ca, 0x6023,
+ 0x0003, 0x6904, 0x00c6, 0x2d60, 0x080c, 0x9fea, 0x00ce, 0x080c,
+ 0xa068, 0x00ce, 0x0804, 0xa60c, 0x2001, 0x1962, 0x2004, 0x6842,
+ 0x00ce, 0x04d0, 0x7008, 0x9086, 0x000b, 0x11c8, 0x6010, 0x00b6,
+ 0x2058, 0xb900, 0xc1bc, 0xb902, 0x00be, 0x00c6, 0x2d60, 0xa87b,
+ 0x0003, 0x080c, 0xc413, 0x6007, 0x0085, 0x6003, 0x000b, 0x6023,
+ 0x0002, 0x080c, 0x85f8, 0x080c, 0x8b8f, 0x00ce, 0x00e8, 0x700c,
+ 0x9086, 0x2a00, 0x1138, 0x2001, 0x1962, 0x2004, 0x6842, 0x00a0,
+ 0x0479, 0x00a0, 0x89ff, 0x090c, 0x0df6, 0x00c6, 0x00d6, 0x2d60,
+ 0xa867, 0x0103, 0xa87b, 0x0003, 0x080c, 0x683c, 0x080c, 0xbf39,
+ 0x080c, 0xa01c, 0x00de, 0x00ce, 0x080c, 0x9fea, 0x009e, 0x0005,
+ 0x9186, 0x0015, 0x1128, 0x2001, 0x1962, 0x2004, 0x6842, 0x0068,
+ 0x918e, 0x0016, 0x1160, 0x00c6, 0x2d00, 0x2060, 0x080c, 0xda94,
+ 0x080c, 0x8425, 0x080c, 0x9fea, 0x00ce, 0x080c, 0x9fea, 0x0005,
+ 0x0026, 0x0036, 0x0046, 0x7228, 0xacb0, 0xabac, 0xd2f4, 0x0130,
+ 0x2001, 0x1962, 0x2004, 0x6842, 0x0804, 0xa68a, 0x00c6, 0x2d60,
+ 0x080c, 0xb976, 0x00ce, 0x6804, 0x9086, 0x0050, 0x1168, 0x00c6,
+ 0x2d00, 0x2060, 0x6003, 0x0001, 0x6007, 0x0050, 0x080c, 0x85f8,
+ 0x080c, 0x8b8f, 0x00ce, 0x04f0, 0x6800, 0x9086, 0x000f, 0x01a8,
+ 0x89ff, 0x090c, 0x0df6, 0x6800, 0x9086, 0x0004, 0x1190, 0xa87c,
+ 0xd0ac, 0x0178, 0xa843, 0x0fff, 0xa83f, 0x0fff, 0xa880, 0xc0fc,
+ 0xa882, 0x2001, 0x0001, 0x6832, 0x0400, 0x2001, 0x0007, 0x6832,
+ 0x00e0, 0xa87c, 0xd0b4, 0x1150, 0xd0ac, 0x0db8, 0x6824, 0xd0f4,
+ 0x1d48, 0xa838, 0xa934, 0x9105, 0x0d80, 0x0c20, 0xd2ec, 0x1d68,
+ 0x7024, 0x9306, 0x1118, 0x7020, 0x9406, 0x0d38, 0x7020, 0x683e,
+ 0x7024, 0x683a, 0x2001, 0x0005, 0x6832, 0x080c, 0xc0c1, 0x080c,
+ 0x8b8f, 0x0010, 0x080c, 0x9fea, 0x004e, 0x003e, 0x002e, 0x0005,
+ 0x00e6, 0x00d6, 0x0026, 0x7008, 0x9084, 0x00ff, 0x6210, 0x00b6,
+ 0x2258, 0xba10, 0x00be, 0x9206, 0x1904, 0xa6f5, 0x700c, 0x6210,
+ 0x00b6, 0x2258, 0xba14, 0x00be, 0x9206, 0x1904, 0xa6f5, 0x6038,
+ 0x2068, 0x6824, 0xc0dc, 0x6826, 0x6a20, 0x9286, 0x0007, 0x0904,
+ 0xa6f5, 0x9286, 0x0002, 0x0904, 0xa6f5, 0x9286, 0x0000, 0x05e8,
+ 0x6808, 0x633c, 0x9306, 0x15c8, 0x2071, 0x026c, 0x9186, 0x0015,
+ 0x0570, 0x918e, 0x0016, 0x1100, 0x00c6, 0x6038, 0x2060, 0x6104,
+ 0x9186, 0x004b, 0x01c0, 0x9186, 0x004c, 0x01a8, 0x9186, 0x004d,
+ 0x0190, 0x9186, 0x004e, 0x0178, 0x9186, 0x0052, 0x0160, 0x6014,
+ 0x0096, 0x2048, 0x080c, 0xbd4e, 0x090c, 0x0df6, 0xa87b, 0x0003,
+ 0x009e, 0x080c, 0xc413, 0x6007, 0x0085, 0x6003, 0x000b, 0x6023,
+ 0x0002, 0x080c, 0x85f8, 0x080c, 0x8b8f, 0x00ce, 0x0030, 0x6038,
+ 0x2070, 0x2001, 0x1962, 0x2004, 0x7042, 0x080c, 0x9fea, 0x002e,
+ 0x00de, 0x00ee, 0x0005, 0x00b6, 0x0096, 0x00f6, 0x6014, 0x2048,
+ 0x6010, 0x2058, 0x91b6, 0x0015, 0x0130, 0xba08, 0xbb0c, 0xbc00,
+ 0xc48c, 0xbc02, 0x0460, 0x0096, 0x0156, 0x0036, 0x0026, 0x2b48,
+ 0x9e90, 0x0010, 0x2019, 0x000a, 0x20a9, 0x0004, 0x080c, 0xb017,
+ 0x002e, 0x003e, 0x015e, 0x009e, 0x1904, 0xa764, 0x0096, 0x0156,
+ 0x0036, 0x0026, 0x2b48, 0x9e90, 0x0014, 0x2019, 0x0006, 0x20a9,
+ 0x0004, 0x080c, 0xb017, 0x002e, 0x003e, 0x015e, 0x009e, 0x15a0,
+ 0x7238, 0xba0a, 0x733c, 0xbb0e, 0xbc00, 0xc48d, 0xbc02, 0xa804,
+ 0x9005, 0x1128, 0x00fe, 0x009e, 0x00be, 0x0804, 0xa3f2, 0x0096,
+ 0x2048, 0xaa12, 0xab16, 0xac0a, 0x009e, 0x8006, 0x8006, 0x8007,
+ 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, 0x0002, 0x2009, 0x002b,
+ 0xaaa0, 0xab9c, 0xaca8, 0xada4, 0x2031, 0x0000, 0x2041, 0x128e,
+ 0x080c, 0xa4f1, 0x0130, 0x00fe, 0x009e, 0x080c, 0x9fea, 0x00be,
+ 0x0005, 0x080c, 0xa9a7, 0x0cb8, 0x2b78, 0x00f6, 0x080c, 0x3095,
+ 0x080c, 0xc46e, 0x00fe, 0x00c6, 0x080c, 0x9f94, 0x2f00, 0x6012,
+ 0x6017, 0x0000, 0x6023, 0x0001, 0x6007, 0x0001, 0x6003, 0x0001,
+ 0x2001, 0x0007, 0x080c, 0x62f4, 0x080c, 0x6320, 0x080c, 0x8640,
+ 0x080c, 0x8b8f, 0x00ce, 0x0804, 0xa737, 0x2100, 0x91b2, 0x0053,
+ 0x1a0c, 0x0df6, 0x91b2, 0x0040, 0x1a04, 0xa7ed, 0x0002, 0xa7db,
+ 0xa7db, 0xa7d1, 0xa7db, 0xa7db, 0xa7db, 0xa7cf, 0xa7cf, 0xa7cf,
+ 0xa7cf, 0xa7cf, 0xa7cf, 0xa7cf, 0xa7cf, 0xa7cf, 0xa7cf, 0xa7cf,
+ 0xa7cf, 0xa7cf, 0xa7cf, 0xa7cf, 0xa7cf, 0xa7cf, 0xa7cf, 0xa7cf,
+ 0xa7cf, 0xa7cf, 0xa7cf, 0xa7cf, 0xa7cf, 0xa7cf, 0xa7db, 0xa7cf,
+ 0xa7db, 0xa7db, 0xa7cf, 0xa7cf, 0xa7cf, 0xa7cf, 0xa7cf, 0xa7d1,
+ 0xa7cf, 0xa7cf, 0xa7cf, 0xa7cf, 0xa7cf, 0xa7cf, 0xa7cf, 0xa7cf,
+ 0xa7cf, 0xa7db, 0xa7db, 0xa7cf, 0xa7cf, 0xa7cf, 0xa7cf, 0xa7cf,
+ 0xa7cf, 0xa7cf, 0xa7cf, 0xa7cf, 0xa7db, 0xa7cf, 0xa7cf, 0x080c,
+ 0x0df6, 0x0066, 0x00b6, 0x6610, 0x2658, 0xb8bc, 0xc08c, 0xb8be,
+ 0x00be, 0x006e, 0x0000, 0x6003, 0x0001, 0x6106, 0x9186, 0x0032,
+ 0x0118, 0x080c, 0x8640, 0x0010, 0x080c, 0x85f8, 0x0126, 0x2091,
+ 0x8000, 0x080c, 0x8b8f, 0x012e, 0x0005, 0x2600, 0x0002, 0xa801,
+ 0xa801, 0xa801, 0xa7db, 0xa7db, 0xa801, 0xa801, 0xa801, 0xa801,
+ 0xa7db, 0xa801, 0xa7db, 0xa801, 0xa7db, 0xa801, 0xa801, 0xa801,
+ 0xa801, 0x080c, 0x0df6, 0x6004, 0x90b2, 0x0053, 0x1a0c, 0x0df6,
+ 0x91b6, 0x0013, 0x0904, 0xa8d6, 0x91b6, 0x0027, 0x1904, 0xa880,
+ 0x080c, 0x8a83, 0x6004, 0x080c, 0xbf45, 0x01b0, 0x080c, 0xbf56,
+ 0x01a8, 0x908e, 0x0021, 0x0904, 0xa87d, 0x908e, 0x0022, 0x1130,
+ 0x080c, 0xa41e, 0x0904, 0xa879, 0x0804, 0xa87a, 0x908e, 0x003d,
+ 0x0904, 0xa87d, 0x0804, 0xa873, 0x080c, 0x30be, 0x2001, 0x0007,
+ 0x080c, 0x62f4, 0x6010, 0x00b6, 0x2058, 0xb9a0, 0x00be, 0x080c,
+ 0xa9a7, 0x9186, 0x007e, 0x1148, 0x2001, 0x1836, 0x2014, 0xc285,
+ 0x080c, 0x717e, 0x1108, 0xc2ad, 0x2202, 0x0036, 0x0026, 0x2019,
+ 0x0028, 0x2110, 0x080c, 0xdaf0, 0x002e, 0x003e, 0x0016, 0x0026,
+ 0x0036, 0x2110, 0x2019, 0x0028, 0x080c, 0x8782, 0x0076, 0x903e,
+ 0x080c, 0x8670, 0x6010, 0x00b6, 0x905d, 0x0100, 0x00be, 0x2c08,
+ 0x080c, 0xd556, 0x007e, 0x003e, 0x002e, 0x001e, 0x080c, 0xc46e,
+ 0x0016, 0x080c, 0xc1c2, 0x080c, 0x9fea, 0x001e, 0x080c, 0x3190,
+ 0x080c, 0x8b8f, 0x0030, 0x080c, 0xc1c2, 0x080c, 0x9fea, 0x080c,
+ 0x8b8f, 0x0005, 0x080c, 0xa9a7, 0x0cb0, 0x080c, 0xa9e3, 0x0c98,
+ 0x9186, 0x0015, 0x0118, 0x9186, 0x0016, 0x1148, 0x080c, 0xc47f,
+ 0x0d80, 0x6000, 0x9086, 0x0002, 0x0904, 0xa9ee, 0x0c50, 0x9186,
+ 0x0014, 0x1d38, 0x080c, 0x8a83, 0x6004, 0x908e, 0x0022, 0x1118,
+ 0x080c, 0xa41e, 0x09f0, 0x080c, 0x3095, 0x080c, 0xc46e, 0x080c,
+ 0xbf45, 0x1198, 0x080c, 0x30be, 0x6010, 0x00b6, 0x2058, 0xb9a0,
+ 0x00be, 0x080c, 0xa9a7, 0x9186, 0x007e, 0x1128, 0x2001, 0x1836,
+ 0x200c, 0xc185, 0x2102, 0x0804, 0xa873, 0x080c, 0xbf56, 0x1120,
+ 0x080c, 0xa9a7, 0x0804, 0xa873, 0x6004, 0x908e, 0x0032, 0x1160,
+ 0x00e6, 0x00f6, 0x2071, 0x189c, 0x2079, 0x0000, 0x080c, 0x3424,
+ 0x00fe, 0x00ee, 0x0804, 0xa873, 0x6004, 0x908e, 0x0021, 0x0d40,
+ 0x908e, 0x0022, 0x090c, 0xa9a7, 0x0804, 0xa873, 0x90b2, 0x0040,
+ 0x1a04, 0xa990, 0x2008, 0x0002, 0xa91e, 0xa91f, 0xa922, 0xa925,
+ 0xa928, 0xa935, 0xa91c, 0xa91c, 0xa91c, 0xa91c, 0xa91c, 0xa91c,
+ 0xa91c, 0xa91c, 0xa91c, 0xa91c, 0xa91c, 0xa91c, 0xa91c, 0xa91c,
+ 0xa91c, 0xa91c, 0xa91c, 0xa91c, 0xa91c, 0xa91c, 0xa91c, 0xa91c,
+ 0xa91c, 0xa91c, 0xa938, 0xa945, 0xa91c, 0xa947, 0xa945, 0xa91c,
+ 0xa91c, 0xa91c, 0xa91c, 0xa91c, 0xa945, 0xa945, 0xa91c, 0xa91c,
+ 0xa91c, 0xa91c, 0xa91c, 0xa91c, 0xa91c, 0xa91c, 0xa977, 0xa945,
+ 0xa91c, 0xa941, 0xa91c, 0xa91c, 0xa91c, 0xa942, 0xa91c, 0xa91c,
+ 0xa91c, 0xa945, 0xa96e, 0xa91c, 0x080c, 0x0df6, 0x0430, 0x2001,
+ 0x000b, 0x0470, 0x2001, 0x0003, 0x0458, 0x2001, 0x0005, 0x0440,
+ 0x6010, 0x00b6, 0x2058, 0xb804, 0x00be, 0x9084, 0x00ff, 0x9086,
+ 0x0000, 0x1500, 0x2001, 0x0001, 0x00d8, 0x2001, 0x0009, 0x00c0,
+ 0x080c, 0x8a83, 0x6003, 0x0005, 0x080c, 0xc471, 0x080c, 0x8b8f,
+ 0x0070, 0x0018, 0x0010, 0x080c, 0x62f4, 0x0804, 0xa988, 0x080c,
+ 0x8a83, 0x080c, 0xc471, 0x6003, 0x0004, 0x080c, 0x8b8f, 0x0005,
+ 0x080c, 0x62f4, 0x080c, 0x8a83, 0x6003, 0x0002, 0x0036, 0x2019,
+ 0x1866, 0x2304, 0x9084, 0xff00, 0x1120, 0x2001, 0x1960, 0x201c,
+ 0x0040, 0x8007, 0x909a, 0x0004, 0x0ec0, 0x8003, 0x801b, 0x831b,
+ 0x9318, 0x631a, 0x003e, 0x080c, 0x8b8f, 0x0c08, 0x080c, 0x8a83,
+ 0x080c, 0xc1c2, 0x080c, 0x9fea, 0x080c, 0x8b8f, 0x08c0, 0x00e6,
+ 0x00f6, 0x2071, 0x189c, 0x2079, 0x0000, 0x080c, 0x3424, 0x00fe,
+ 0x00ee, 0x080c, 0x8a83, 0x080c, 0x9fea, 0x080c, 0x8b8f, 0x0838,
+ 0x080c, 0x8a83, 0x6003, 0x0002, 0x080c, 0xc471, 0x0804, 0x8b8f,
+ 0x2600, 0x2008, 0x0002, 0xa9a5, 0xa9a5, 0xa9a5, 0xa988, 0xa988,
+ 0xa9a5, 0xa9a5, 0xa9a5, 0xa9a5, 0xa988, 0xa9a5, 0xa988, 0xa9a5,
+ 0xa988, 0xa9a5, 0xa9a5, 0xa9a5, 0xa9a5, 0x080c, 0x0df6, 0x00e6,
+ 0x0096, 0x0026, 0x0016, 0x080c, 0xbd4e, 0x0568, 0x6014, 0x2048,
+ 0xa864, 0x9086, 0x0139, 0x11a8, 0xa894, 0x9086, 0x0056, 0x1148,
+ 0x080c, 0x5275, 0x0130, 0x2001, 0x0000, 0x900e, 0x2011, 0x4000,
+ 0x0028, 0x2001, 0x0030, 0x900e, 0x2011, 0x4005, 0x080c, 0xc333,
+ 0x0090, 0xa868, 0xd0fc, 0x0178, 0xa807, 0x0000, 0x0016, 0x6004,
+ 0x908e, 0x0021, 0x0168, 0x908e, 0x003d, 0x0150, 0x001e, 0xa867,
+ 0x0103, 0xa833, 0x0100, 0x001e, 0x002e, 0x009e, 0x00ee, 0x0005,
+ 0x001e, 0x0009, 0x0cc0, 0x0096, 0x6014, 0x2048, 0xa800, 0x2048,
+ 0xa867, 0x0103, 0xa823, 0x8001, 0x009e, 0x0005, 0x00b6, 0x6610,
+ 0x2658, 0xb804, 0x9084, 0x00ff, 0x90b2, 0x000c, 0x1a0c, 0x0df6,
+ 0x6604, 0x96b6, 0x004d, 0x1120, 0x080c, 0xc252, 0x0804, 0xaa6b,
+ 0x6604, 0x96b6, 0x0043, 0x1120, 0x080c, 0xc29b, 0x0804, 0xaa6b,
+ 0x6604, 0x96b6, 0x004b, 0x1120, 0x080c, 0xc2c7, 0x0804, 0xaa6b,
+ 0x6604, 0x96b6, 0x0033, 0x1120, 0x080c, 0xc1e4, 0x0804, 0xaa6b,
+ 0x6604, 0x96b6, 0x0028, 0x1120, 0x080c, 0xbf94, 0x0804, 0xaa6b,
+ 0x6604, 0x96b6, 0x0029, 0x1120, 0x080c, 0xbfd5, 0x0804, 0xaa6b,
+ 0x6604, 0x96b6, 0x001f, 0x1118, 0x080c, 0xa3c3, 0x04e0, 0x6604,
+ 0x96b6, 0x0000, 0x1118, 0x080c, 0xa6fb, 0x04a8, 0x6604, 0x96b6,
+ 0x0022, 0x1118, 0x080c, 0xa3ff, 0x0470, 0x6604, 0x96b6, 0x0035,
+ 0x1118, 0x080c, 0xa50f, 0x0438, 0x6604, 0x96b6, 0x0039, 0x1118,
+ 0x080c, 0xa690, 0x0400, 0x6604, 0x96b6, 0x003d, 0x1118, 0x080c,
+ 0xa437, 0x00c8, 0x6604, 0x96b6, 0x0044, 0x1118, 0x080c, 0xa473,
+ 0x0090, 0x6604, 0x96b6, 0x0049, 0x1118, 0x080c, 0xa49e, 0x0058,
+ 0x91b6, 0x0015, 0x1110, 0x0063, 0x0030, 0x91b6, 0x0016, 0x1128,
+ 0x00be, 0x0804, 0xad46, 0x00be, 0x0005, 0x080c, 0xa083, 0x0cd8,
+ 0xaa88, 0xaa96, 0xaa88, 0xaada, 0xaa88, 0xac6e, 0xad53, 0xaa88,
+ 0xaa88, 0xad20, 0xaa88, 0xad34, 0x0096, 0x080c, 0x1577, 0x6014,
+ 0x2048, 0xa800, 0x2048, 0xa867, 0x0103, 0x009e, 0x0804, 0x9fea,
+ 0xa001, 0xa001, 0x0005, 0x6604, 0x96b6, 0x0004, 0x1130, 0x2001,
+ 0x0001, 0x080c, 0x62e0, 0x0804, 0x9fea, 0x0005, 0x00e6, 0x2071,
+ 0x1800, 0x708c, 0x9086, 0x0074, 0x1540, 0x080c, 0xd527, 0x11b0,
+ 0x6010, 0x00b6, 0x2058, 0x7030, 0xd08c, 0x0128, 0xb800, 0xd0bc,
+ 0x0110, 0xc0c5, 0xb802, 0x00e9, 0x00be, 0x2001, 0x0006, 0x080c,
+ 0x62f4, 0x080c, 0x30be, 0x080c, 0x9fea, 0x0088, 0x2001, 0x000a,
+ 0x080c, 0x62f4, 0x080c, 0x30be, 0x6003, 0x0001, 0x6007, 0x0001,
+ 0x080c, 0x8640, 0x080c, 0x8b8f, 0x0010, 0x080c, 0xac59, 0x00ee,
+ 0x0005, 0x00d6, 0xb800, 0xd084, 0x0158, 0x9006, 0x080c, 0x62e0,
+ 0x2069, 0x185b, 0x6804, 0x0020, 0x2001, 0x0006, 0x080c, 0x6320,
+ 0x00de, 0x0005, 0x00b6, 0x0096, 0x00d6, 0x2011, 0x1823, 0x2204,
+ 0x9086, 0x0074, 0x1904, 0xac30, 0x6010, 0x2058, 0xbaa0, 0x9286,
+ 0x007e, 0x1120, 0x080c, 0xae98, 0x0804, 0xab9d, 0x00d6, 0x080c,
+ 0x717e, 0x01a0, 0x0026, 0x2011, 0x0010, 0x080c, 0x66ed, 0x002e,
+ 0x0904, 0xab3e, 0x080c, 0x54ef, 0x1598, 0x6014, 0x2048, 0xa807,
+ 0x0000, 0xa867, 0x0103, 0xa833, 0xdead, 0x0450, 0x6010, 0x00b6,
+ 0x2058, 0xb910, 0x00be, 0x9186, 0x00ff, 0x0580, 0x0026, 0x2011,
+ 0x8008, 0x080c, 0x66ed, 0x002e, 0x0548, 0x6014, 0x9005, 0x090c,
+ 0x0df6, 0x2048, 0xa864, 0x9084, 0x00ff, 0x9086, 0x0039, 0x1140,
+ 0x2001, 0x0030, 0x900e, 0x2011, 0x4009, 0x080c, 0xc333, 0x0040,
+ 0x6014, 0x2048, 0xa807, 0x0000, 0xa867, 0x0103, 0xa833, 0xdead,
+ 0x6010, 0x2058, 0xb9a0, 0x0016, 0x080c, 0x30be, 0x080c, 0x9fea,
+ 0x001e, 0x080c, 0x3190, 0x00de, 0x0804, 0xac33, 0x00de, 0x080c,
+ 0xae8d, 0x6010, 0x2058, 0xbaa0, 0x9286, 0x0080, 0x1510, 0x6014,
+ 0x9005, 0x01a8, 0x2048, 0xa864, 0x9084, 0x00ff, 0x9086, 0x0039,
+ 0x1140, 0x2001, 0x0000, 0x900e, 0x2011, 0x4000, 0x080c, 0xc333,
+ 0x0030, 0xa807, 0x0000, 0xa867, 0x0103, 0xa833, 0x0200, 0x2001,
+ 0x0006, 0x080c, 0x62f4, 0x080c, 0x30be, 0x080c, 0x9fea, 0x0804,
+ 0xac33, 0x080c, 0xac41, 0x6014, 0x9005, 0x0190, 0x2048, 0xa868,
+ 0xd0f4, 0x01e8, 0xa864, 0x9084, 0x00ff, 0x9086, 0x0039, 0x1d08,
+ 0x2001, 0x0000, 0x900e, 0x2011, 0x4000, 0x080c, 0xc333, 0x08f8,
+ 0x080c, 0xac37, 0x0160, 0x9006, 0x080c, 0x62e0, 0x2001, 0x0004,
+ 0x080c, 0x6320, 0x2001, 0x0007, 0x080c, 0x62f4, 0x08a0, 0x2001,
+ 0x0004, 0x080c, 0x62f4, 0x6003, 0x0001, 0x6007, 0x0003, 0x080c,
+ 0x8640, 0x080c, 0x8b8f, 0x0804, 0xac33, 0xb85c, 0xd0e4, 0x0178,
+ 0x080c, 0xc164, 0x080c, 0x717e, 0x0118, 0xd0dc, 0x1904, 0xab5f,
+ 0x2011, 0x1836, 0x2204, 0xc0ad, 0x2012, 0x0804, 0xab5f, 0x080c,
+ 0xc1a1, 0x2011, 0x1836, 0x2204, 0xc0a5, 0x2012, 0x0006, 0x080c,
+ 0xd6c7, 0x000e, 0x1904, 0xab5f, 0xc0b5, 0x2012, 0x2001, 0x0006,
+ 0x080c, 0x62f4, 0x9006, 0x080c, 0x62e0, 0x00c6, 0x2001, 0x180f,
+ 0x2004, 0xd09c, 0x0520, 0x00f6, 0x2079, 0x0100, 0x00e6, 0x2071,
+ 0x1800, 0x700c, 0x9084, 0x00ff, 0x78e6, 0x707a, 0x7010, 0x78ea,
+ 0x707e, 0x908c, 0x00ff, 0x00ee, 0x780c, 0xc0b5, 0x780e, 0x00fe,
+ 0x080c, 0x26b6, 0x00f6, 0x2100, 0x900e, 0x080c, 0x266d, 0x795a,
+ 0x00fe, 0x9186, 0x0081, 0x01f0, 0x2009, 0x0081, 0x00e0, 0x2009,
+ 0x00ef, 0x00f6, 0x2079, 0x0100, 0x79ea, 0x78e7, 0x0000, 0x7932,
+ 0x7936, 0x780c, 0xc0b5, 0x780e, 0x00fe, 0x080c, 0x26b6, 0x00f6,
+ 0x2079, 0x1800, 0x797e, 0x2100, 0x900e, 0x797a, 0x080c, 0x266d,
+ 0x795a, 0x00fe, 0x8108, 0x080c, 0x6343, 0x2b00, 0x00ce, 0x1904,
+ 0xab5f, 0x6012, 0x2009, 0x180f, 0x210c, 0xd19c, 0x0150, 0x2009,
+ 0x027c, 0x210c, 0x918c, 0x00ff, 0xb912, 0x2009, 0x027d, 0x210c,
+ 0xb916, 0x2001, 0x0002, 0x080c, 0x62f4, 0x6023, 0x0001, 0x6003,
+ 0x0001, 0x6007, 0x0002, 0x080c, 0x8640, 0x080c, 0x8b8f, 0x0018,
+ 0x080c, 0xa9a7, 0x0431, 0x00de, 0x009e, 0x00be, 0x0005, 0x2001,
+ 0x1810, 0x2004, 0xd0a4, 0x0120, 0x2001, 0x185c, 0x2004, 0xd0ac,
+ 0x0005, 0x00e6, 0x080c, 0xdb49, 0x0190, 0x2071, 0x0260, 0x7108,
+ 0x720c, 0x918c, 0x00ff, 0x1118, 0x9284, 0xff00, 0x0140, 0x6010,
+ 0x2058, 0xb8a0, 0x9084, 0xff80, 0x1110, 0xb912, 0xba16, 0x00ee,
+ 0x0005, 0x2030, 0x2001, 0x0007, 0x080c, 0x62f4, 0x080c, 0x54ef,
+ 0x1120, 0x2001, 0x0007, 0x080c, 0x6320, 0x080c, 0x30be, 0x6020,
+ 0x9086, 0x000a, 0x1108, 0x0005, 0x0804, 0x9fea, 0x00b6, 0x00e6,
+ 0x0026, 0x0016, 0x2071, 0x1800, 0x708c, 0x9086, 0x0014, 0x1904,
+ 0xad17, 0x00d6, 0x080c, 0x717e, 0x01a0, 0x0026, 0x2011, 0x0010,
+ 0x080c, 0x66ed, 0x002e, 0x0904, 0xacc9, 0x080c, 0x54ef, 0x1598,
+ 0x6014, 0x2048, 0xa807, 0x0000, 0xa867, 0x0103, 0xa833, 0xdead,
+ 0x0450, 0x6010, 0x00b6, 0x2058, 0xb910, 0x00be, 0x9186, 0x00ff,
+ 0x0580, 0x0026, 0x2011, 0x8008, 0x080c, 0x66ed, 0x002e, 0x0548,
+ 0x6014, 0x9005, 0x090c, 0x0df6, 0x2048, 0xa864, 0x9084, 0x00ff,
+ 0x9086, 0x0039, 0x1140, 0x2001, 0x0030, 0x900e, 0x2011, 0x4009,
+ 0x080c, 0xc333, 0x0040, 0x6014, 0x2048, 0xa807, 0x0000, 0xa867,
+ 0x0103, 0xa833, 0xdead, 0x6010, 0x2058, 0xb9a0, 0x0016, 0x080c,
+ 0x30be, 0x080c, 0x9fea, 0x001e, 0x080c, 0x3190, 0x00de, 0x0804,
+ 0xad1b, 0x00de, 0x080c, 0x54ef, 0x1170, 0x6014, 0x9005, 0x1158,
+ 0x0036, 0x0046, 0x6010, 0x2058, 0xbba0, 0x2021, 0x0006, 0x080c,
+ 0x4bb4, 0x004e, 0x003e, 0x00d6, 0x6010, 0x2058, 0x080c, 0x643e,
+ 0x080c, 0xaac9, 0x00de, 0x080c, 0xaf63, 0x1588, 0x6010, 0x2058,
+ 0xb890, 0x9005, 0x0560, 0x2001, 0x0006, 0x080c, 0x62f4, 0x0096,
+ 0x6014, 0x904d, 0x01d0, 0xa864, 0x9084, 0x00ff, 0x9086, 0x0039,
+ 0x1140, 0x2001, 0x0000, 0x900e, 0x2011, 0x4000, 0x080c, 0xc333,
+ 0x0060, 0xa864, 0x9084, 0x00ff, 0x9086, 0x0029, 0x0130, 0xa807,
+ 0x0000, 0xa867, 0x0103, 0xa833, 0x0200, 0x009e, 0x080c, 0x30be,
+ 0x6020, 0x9086, 0x000a, 0x0138, 0x080c, 0x9fea, 0x0020, 0x080c,
+ 0xa9a7, 0x080c, 0xac59, 0x001e, 0x002e, 0x00ee, 0x00be, 0x0005,
+ 0x2011, 0x1823, 0x2204, 0x9086, 0x0014, 0x1160, 0x2001, 0x0002,
+ 0x080c, 0x62f4, 0x6003, 0x0001, 0x6007, 0x0001, 0x080c, 0x8640,
+ 0x0804, 0x8b8f, 0x0804, 0xac59, 0x2030, 0x2011, 0x1823, 0x2204,
+ 0x9086, 0x0004, 0x1148, 0x96b6, 0x000b, 0x1120, 0x2001, 0x0007,
+ 0x080c, 0x62f4, 0x0804, 0x9fea, 0x0804, 0xac59, 0x0002, 0xaa88,
+ 0xad5e, 0xaa88, 0xad9f, 0xaa88, 0xae4a, 0xad53, 0xaa8b, 0xaa88,
+ 0xae5c, 0xaa88, 0xae6c, 0x6604, 0x9686, 0x0003, 0x0904, 0xac6e,
+ 0x96b6, 0x001e, 0x1110, 0x080c, 0x9fea, 0x0005, 0x00b6, 0x00d6,
+ 0x00c6, 0x080c, 0xae7c, 0x11a0, 0x9006, 0x080c, 0x62e0, 0x080c,
+ 0x3095, 0x080c, 0xc46e, 0x2001, 0x0002, 0x080c, 0x62f4, 0x6003,
+ 0x0001, 0x6007, 0x0002, 0x080c, 0x8640, 0x080c, 0x8b8f, 0x0418,
+ 0x2009, 0x026e, 0x2104, 0x9086, 0x0009, 0x1160, 0x6010, 0x2058,
+ 0xb840, 0x9084, 0x00ff, 0x9005, 0x0180, 0x8001, 0xb842, 0x601b,
+ 0x000a, 0x0088, 0x2009, 0x026f, 0x2104, 0x9084, 0xff00, 0x908e,
+ 0x1900, 0x0148, 0x908e, 0x1e00, 0x0990, 0x080c, 0x3095, 0x080c,
+ 0xc46e, 0x080c, 0xac59, 0x00ce, 0x00de, 0x00be, 0x0005, 0x0096,
+ 0x00b6, 0x0026, 0x9016, 0x080c, 0xae8a, 0x00d6, 0x2069, 0x1956,
+ 0x2d04, 0x9005, 0x0168, 0x6010, 0x2058, 0xb8a0, 0x9086, 0x007e,
+ 0x1138, 0x2069, 0x181f, 0x2d04, 0x8000, 0x206a, 0x00de, 0x0010,
+ 0x00de, 0x0088, 0x9006, 0x080c, 0x62e0, 0x2001, 0x0002, 0x080c,
+ 0x62f4, 0x6003, 0x0001, 0x6007, 0x0002, 0x080c, 0x8640, 0x080c,
+ 0x8b8f, 0x0804, 0xae1a, 0x080c, 0xbd4e, 0x01b0, 0x6014, 0x2048,
+ 0xa864, 0x2010, 0x9086, 0x0139, 0x1138, 0x6007, 0x0016, 0x2001,
+ 0x0002, 0x080c, 0xc390, 0x00b0, 0x6014, 0x2048, 0xa864, 0xd0fc,
+ 0x0118, 0x2001, 0x0001, 0x0ca8, 0x2001, 0x180e, 0x2004, 0xd0dc,
+ 0x0148, 0x6010, 0x2058, 0xb840, 0x9084, 0x00ff, 0x9005, 0x1110,
+ 0x9006, 0x0c38, 0x080c, 0xa9a7, 0x2009, 0x026e, 0x2134, 0x96b4,
+ 0x00ff, 0x9686, 0x0005, 0x0510, 0x9686, 0x000b, 0x01c8, 0x2009,
+ 0x026f, 0x2104, 0x9084, 0xff00, 0x1118, 0x9686, 0x0009, 0x01b0,
+ 0x9086, 0x1900, 0x1168, 0x9686, 0x0009, 0x0180, 0x2001, 0x0004,
+ 0x080c, 0x62f4, 0x2001, 0x0028, 0x601a, 0x6007, 0x0052, 0x0010,
+ 0x080c, 0xac59, 0x002e, 0x00be, 0x009e, 0x0005, 0x9286, 0x0139,
+ 0x0160, 0x6014, 0x2048, 0x080c, 0xbd4e, 0x0140, 0xa864, 0x9086,
+ 0x0139, 0x0118, 0xa868, 0xd0fc, 0x0108, 0x0c50, 0x6010, 0x2058,
+ 0xb840, 0x9084, 0x00ff, 0x9005, 0x0138, 0x8001, 0xb842, 0x601b,
+ 0x000a, 0x6007, 0x0016, 0x08f0, 0xb8a0, 0x9086, 0x007e, 0x1138,
+ 0x00e6, 0x2071, 0x1800, 0x080c, 0x5dc2, 0x00ee, 0x0010, 0x080c,
+ 0x3095, 0x0870, 0x2001, 0x0004, 0x080c, 0x62f4, 0x04d9, 0x1140,
+ 0x6003, 0x0001, 0x6007, 0x0003, 0x080c, 0x8640, 0x0804, 0x8b8f,
+ 0x080c, 0xa9a7, 0x0804, 0xac59, 0x0469, 0x1160, 0x2001, 0x0008,
+ 0x080c, 0x62f4, 0x6003, 0x0001, 0x6007, 0x0005, 0x080c, 0x8640,
+ 0x0804, 0x8b8f, 0x0804, 0xac59, 0x00e9, 0x1160, 0x2001, 0x000a,
+ 0x080c, 0x62f4, 0x6003, 0x0001, 0x6007, 0x0001, 0x080c, 0x8640,
+ 0x0804, 0x8b8f, 0x0804, 0xac59, 0x2009, 0x026e, 0x2104, 0x9086,
+ 0x0003, 0x1138, 0x2009, 0x026f, 0x2104, 0x9084, 0xff00, 0x9086,
+ 0x2a00, 0x0005, 0x9085, 0x0001, 0x0005, 0x00b6, 0x00c6, 0x0016,
+ 0x6110, 0x2158, 0x080c, 0x63b2, 0x001e, 0x00ce, 0x00be, 0x0005,
+ 0x00b6, 0x00f6, 0x00e6, 0x00d6, 0x0036, 0x0016, 0x6010, 0x2058,
+ 0x2009, 0x1836, 0x2104, 0x9085, 0x0003, 0x200a, 0x080c, 0xaf35,
+ 0x0560, 0x2009, 0x1836, 0x2104, 0xc0cd, 0x200a, 0x080c, 0x66c5,
+ 0x0158, 0x9006, 0x2020, 0x2009, 0x002a, 0x080c, 0xd837, 0x2001,
+ 0x180c, 0x200c, 0xc195, 0x2102, 0x2019, 0x002a, 0x2009, 0x0001,
+ 0x080c, 0x3060, 0x00e6, 0x2071, 0x1800, 0x080c, 0x2e73, 0x00ee,
+ 0x00c6, 0x0156, 0x20a9, 0x0781, 0x2009, 0x007f, 0x080c, 0x3190,
+ 0x8108, 0x1f04, 0xaece, 0x015e, 0x00ce, 0x080c, 0xae8d, 0x2071,
+ 0x0260, 0x2079, 0x0200, 0x7817, 0x0001, 0x2001, 0x1836, 0x200c,
+ 0xc1c5, 0x7018, 0xd0fc, 0x0110, 0xd0dc, 0x0118, 0x7038, 0xd0dc,
+ 0x1108, 0xc1c4, 0x7817, 0x0000, 0x2001, 0x1836, 0x2102, 0x9184,
+ 0x0050, 0x9086, 0x0050, 0x05d0, 0x2079, 0x0100, 0x2e04, 0x9084,
+ 0x00ff, 0x2069, 0x181e, 0x206a, 0x78e6, 0x0006, 0x8e70, 0x2e04,
+ 0x2069, 0x181f, 0x206a, 0x78ea, 0x7832, 0x7836, 0x2010, 0x9084,
+ 0xff00, 0x001e, 0x9105, 0x2009, 0x182b, 0x200a, 0x2200, 0x9084,
+ 0x00ff, 0x2008, 0x080c, 0x26b6, 0x080c, 0x717e, 0x0170, 0x2071,
+ 0x0260, 0x2069, 0x195c, 0x7048, 0x206a, 0x704c, 0x6806, 0x7050,
+ 0x680a, 0x7054, 0x680e, 0x080c, 0xc164, 0x0040, 0x2001, 0x0006,
+ 0x080c, 0x62f4, 0x080c, 0x30be, 0x080c, 0x9fea, 0x001e, 0x003e,
+ 0x00de, 0x00ee, 0x00fe, 0x00be, 0x0005, 0x0096, 0x0026, 0x0036,
+ 0x00e6, 0x0156, 0x2019, 0x182b, 0x231c, 0x83ff, 0x01f0, 0x2071,
+ 0x0260, 0x7200, 0x9294, 0x00ff, 0x7004, 0x9084, 0xff00, 0x9205,
+ 0x9306, 0x1198, 0x2011, 0x0276, 0x20a9, 0x0004, 0x2b48, 0x2019,
+ 0x000a, 0x080c, 0xb017, 0x1148, 0x2011, 0x027a, 0x20a9, 0x0004,
+ 0x2019, 0x0006, 0x080c, 0xb017, 0x1100, 0x015e, 0x00ee, 0x003e,
+ 0x002e, 0x009e, 0x0005, 0x00e6, 0x2071, 0x0260, 0x7034, 0x9086,
+ 0x0014, 0x11a8, 0x7038, 0x9086, 0x0800, 0x1188, 0x703c, 0xd0ec,
+ 0x0160, 0x9084, 0x0f00, 0x9086, 0x0100, 0x1138, 0x7054, 0xd0a4,
+ 0x1110, 0xd0ac, 0x0110, 0x9006, 0x0010, 0x9085, 0x0001, 0x00ee,
+ 0x0005, 0x00e6, 0x0096, 0x00c6, 0x0076, 0x0056, 0x0046, 0x0026,
+ 0x0006, 0x0126, 0x2091, 0x8000, 0x2029, 0x19cb, 0x252c, 0x2021,
+ 0x19d1, 0x2424, 0x2061, 0x1cd0, 0x2071, 0x1800, 0x7250, 0x7070,
+ 0x9202, 0x1a04, 0xafef, 0x080c, 0xd868, 0x0904, 0xafe8, 0x6720,
+ 0x9786, 0x0007, 0x0904, 0xafe8, 0x2500, 0x9c06, 0x0904, 0xafe8,
+ 0x2400, 0x9c06, 0x05e8, 0x3e08, 0x9186, 0x0002, 0x1148, 0x6010,
+ 0x9005, 0x0130, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x1580,
+ 0x00c6, 0x6000, 0x9086, 0x0004, 0x1110, 0x080c, 0x192c, 0x9786,
+ 0x000a, 0x0148, 0x080c, 0xbf56, 0x1130, 0x00ce, 0x080c, 0xa9a7,
+ 0x080c, 0xa01c, 0x00e8, 0x6014, 0x2048, 0x080c, 0xbd4e, 0x01a8,
+ 0x9786, 0x0003, 0x1530, 0xa867, 0x0103, 0xa87c, 0xd0cc, 0x0130,
+ 0x0096, 0xa878, 0x2048, 0x080c, 0x0fe9, 0x009e, 0xab7a, 0xa877,
+ 0x0000, 0x080c, 0x6a15, 0x080c, 0xbf39, 0x080c, 0xa01c, 0x00ce,
+ 0x9ce0, 0x0018, 0x7064, 0x9c02, 0x1210, 0x0804, 0xaf96, 0x012e,
+ 0x000e, 0x002e, 0x004e, 0x005e, 0x007e, 0x00ce, 0x009e, 0x00ee,
+ 0x0005, 0x9786, 0x0006, 0x1118, 0x080c, 0xd7e2, 0x0c30, 0x9786,
+ 0x000a, 0x09e0, 0x0880, 0x220c, 0x2304, 0x9106, 0x1130, 0x8210,
+ 0x8318, 0x1f04, 0xb003, 0x9006, 0x0005, 0x2304, 0x9102, 0x0218,
+ 0x2001, 0x0001, 0x0008, 0x9006, 0x918d, 0x0001, 0x0005, 0x0136,
+ 0x01c6, 0x0016, 0x8906, 0x8006, 0x8007, 0x908c, 0x003f, 0x21e0,
+ 0x9084, 0xffc0, 0x9300, 0x2098, 0x3518, 0x20a9, 0x0001, 0x220c,
+ 0x4002, 0x910e, 0x1140, 0x8210, 0x8319, 0x1dc8, 0x9006, 0x001e,
+ 0x01ce, 0x013e, 0x0005, 0x220c, 0x9102, 0x0218, 0x2001, 0x0001,
+ 0x0010, 0x2001, 0x0000, 0x918d, 0x0001, 0x001e, 0x01ce, 0x013e,
+ 0x0005, 0x6004, 0x908a, 0x0053, 0x1a0c, 0x0df6, 0x080c, 0xbf45,
+ 0x0120, 0x080c, 0xbf56, 0x0168, 0x0028, 0x080c, 0x30be, 0x080c,
+ 0xbf56, 0x0138, 0x080c, 0x8a83, 0x080c, 0x9fea, 0x080c, 0x8b8f,
+ 0x0005, 0x080c, 0xa9a7, 0x0cb0, 0x9182, 0x0054, 0x1220, 0x9182,
+ 0x0040, 0x0208, 0x000a, 0x0005, 0xb078, 0xb078, 0xb078, 0xb078,
+ 0xb078, 0xb078, 0xb078, 0xb078, 0xb078, 0xb078, 0xb078, 0xb07a,
+ 0xb07a, 0xb07a, 0xb07a, 0xb078, 0xb078, 0xb078, 0xb07a, 0xb078,
+ 0x080c, 0x0df6, 0x600b, 0xffff, 0x6003, 0x0001, 0x6106, 0x080c,
+ 0x85f8, 0x0126, 0x2091, 0x8000, 0x080c, 0x8b8f, 0x012e, 0x0005,
+ 0x9186, 0x0013, 0x1128, 0x6004, 0x9082, 0x0040, 0x0804, 0xb112,
+ 0x9186, 0x0027, 0x1520, 0x080c, 0x8a83, 0x080c, 0x3095, 0x080c,
+ 0xc46e, 0x0096, 0x6114, 0x2148, 0x080c, 0xbd4e, 0x0198, 0x080c,
+ 0xbf56, 0x1118, 0x080c, 0xa9a7, 0x0068, 0xa867, 0x0103, 0xa87b,
+ 0x0029, 0xa877, 0x0000, 0xa97c, 0xc1c5, 0xa97e, 0x080c, 0x6a22,
+ 0x080c, 0xbf39, 0x009e, 0x080c, 0x9fea, 0x0804, 0x8b8f, 0x9186,
+ 0x0014, 0x1120, 0x6004, 0x9082, 0x0040, 0x00b8, 0x9186, 0x0046,
+ 0x0150, 0x9186, 0x0045, 0x0138, 0x9186, 0x0053, 0x0120, 0x9186,
+ 0x0048, 0x190c, 0x0df6, 0x080c, 0xc47f, 0x0130, 0x6000, 0x9086,
+ 0x0002, 0x1110, 0x0804, 0xb150, 0x0005, 0x0002, 0xb0ec, 0xb0ea,
+ 0xb0ea, 0xb0ea, 0xb0ea, 0xb0ea, 0xb0ea, 0xb0ea, 0xb0ea, 0xb0ea,
+ 0xb0ea, 0xb107, 0xb107, 0xb107, 0xb107, 0xb0ea, 0xb107, 0xb0ea,
+ 0xb107, 0xb0ea, 0x080c, 0x0df6, 0x080c, 0x8a83, 0x0096, 0x6114,
+ 0x2148, 0x080c, 0xbd4e, 0x0168, 0xa867, 0x0103, 0xa87b, 0x0006,
+ 0xa877, 0x0000, 0xa880, 0xc0ec, 0xa882, 0x080c, 0x6a22, 0x080c,
+ 0xbf39, 0x009e, 0x080c, 0x9fea, 0x080c, 0x8b8f, 0x0005, 0x080c,
+ 0x8a83, 0x080c, 0xbf56, 0x090c, 0xa9a7, 0x080c, 0x9fea, 0x080c,
+ 0x8b8f, 0x0005, 0x0002, 0xb129, 0xb127, 0xb127, 0xb127, 0xb127,
+ 0xb127, 0xb127, 0xb127, 0xb127, 0xb127, 0xb127, 0xb140, 0xb140,
+ 0xb140, 0xb140, 0xb127, 0xb14a, 0xb127, 0xb140, 0xb127, 0x080c,
+ 0x0df6, 0x0096, 0x080c, 0x8a83, 0x6014, 0x2048, 0x2001, 0x1962,
+ 0x2004, 0x6042, 0xa97c, 0xd1ac, 0x0140, 0x6003, 0x0004, 0xa87c,
+ 0x9085, 0x0400, 0xa87e, 0x009e, 0x0005, 0x6003, 0x0002, 0x0cb8,
+ 0x080c, 0x8a83, 0x080c, 0xc471, 0x080c, 0xc476, 0x6003, 0x000f,
+ 0x0804, 0x8b8f, 0x080c, 0x8a83, 0x080c, 0x9fea, 0x0804, 0x8b8f,
0x9182, 0x0054, 0x1220, 0x9182, 0x0040, 0x0208, 0x000a, 0x0005,
- 0xb06c, 0xb06c, 0xb06c, 0xb06c, 0xb06c, 0xb06c, 0xb06c, 0xb06c,
- 0xb06c, 0xb06c, 0xb06c, 0xb06e, 0xb06e, 0xb06e, 0xb06e, 0xb06c,
- 0xb06c, 0xb06c, 0xb06e, 0xb06c, 0x080c, 0x0e02, 0x600b, 0xffff,
- 0x6003, 0x0001, 0x6106, 0x080c, 0x85f9, 0x0126, 0x2091, 0x8000,
- 0x080c, 0x8b90, 0x012e, 0x0005, 0x9186, 0x0013, 0x1128, 0x6004,
- 0x9082, 0x0040, 0x0804, 0xb106, 0x9186, 0x0027, 0x1520, 0x080c,
- 0x8a84, 0x080c, 0x30ab, 0x080c, 0xc459, 0x0096, 0x6114, 0x2148,
- 0x080c, 0xbd3b, 0x0198, 0x080c, 0xbf43, 0x1118, 0x080c, 0xa995,
- 0x0068, 0xa867, 0x0103, 0xa87b, 0x0029, 0xa877, 0x0000, 0xa97c,
- 0xc1c5, 0xa97e, 0x080c, 0x6a23, 0x080c, 0xbf26, 0x009e, 0x080c,
- 0x9fd5, 0x0804, 0x8b90, 0x9186, 0x0014, 0x1120, 0x6004, 0x9082,
- 0x0040, 0x00b8, 0x9186, 0x0046, 0x0150, 0x9186, 0x0045, 0x0138,
- 0x9186, 0x0053, 0x0120, 0x9186, 0x0048, 0x190c, 0x0e02, 0x080c,
- 0xc46a, 0x0130, 0x6000, 0x9086, 0x0002, 0x1110, 0x0804, 0xb144,
- 0x0005, 0x0002, 0xb0e0, 0xb0de, 0xb0de, 0xb0de, 0xb0de, 0xb0de,
- 0xb0de, 0xb0de, 0xb0de, 0xb0de, 0xb0de, 0xb0fb, 0xb0fb, 0xb0fb,
- 0xb0fb, 0xb0de, 0xb0fb, 0xb0de, 0xb0fb, 0xb0de, 0x080c, 0x0e02,
- 0x080c, 0x8a84, 0x0096, 0x6114, 0x2148, 0x080c, 0xbd3b, 0x0168,
- 0xa867, 0x0103, 0xa87b, 0x0006, 0xa877, 0x0000, 0xa880, 0xc0ec,
- 0xa882, 0x080c, 0x6a23, 0x080c, 0xbf26, 0x009e, 0x080c, 0x9fd5,
- 0x080c, 0x8b90, 0x0005, 0x080c, 0x8a84, 0x080c, 0xbf43, 0x090c,
- 0xa995, 0x080c, 0x9fd5, 0x080c, 0x8b90, 0x0005, 0x0002, 0xb11d,
- 0xb11b, 0xb11b, 0xb11b, 0xb11b, 0xb11b, 0xb11b, 0xb11b, 0xb11b,
- 0xb11b, 0xb11b, 0xb134, 0xb134, 0xb134, 0xb134, 0xb11b, 0xb13e,
- 0xb11b, 0xb134, 0xb11b, 0x080c, 0x0e02, 0x0096, 0x080c, 0x8a84,
- 0x6014, 0x2048, 0x2001, 0x1962, 0x2004, 0x6042, 0xa97c, 0xd1ac,
- 0x0140, 0x6003, 0x0004, 0xa87c, 0x9085, 0x0400, 0xa87e, 0x009e,
- 0x0005, 0x6003, 0x0002, 0x0cb8, 0x080c, 0x8a84, 0x080c, 0xc45c,
- 0x080c, 0xc461, 0x6003, 0x000f, 0x0804, 0x8b90, 0x080c, 0x8a84,
- 0x080c, 0x9fd5, 0x0804, 0x8b90, 0x9182, 0x0054, 0x1220, 0x9182,
- 0x0040, 0x0208, 0x000a, 0x0005, 0xb160, 0xb160, 0xb160, 0xb160,
- 0xb160, 0xb162, 0xb23f, 0xb160, 0xb273, 0xb160, 0xb160, 0xb160,
- 0xb160, 0xb160, 0xb160, 0xb160, 0xb160, 0xb160, 0xb160, 0xb273,
- 0x080c, 0x0e02, 0x00b6, 0x0096, 0x6114, 0x2148, 0x7644, 0x96b4,
- 0x0fff, 0x86ff, 0x1528, 0x6010, 0x2058, 0xb800, 0xd0bc, 0x1904,
- 0xb22e, 0xa87b, 0x0000, 0xa867, 0x0103, 0xae76, 0xa87c, 0xd0ac,
- 0x0128, 0xa834, 0xa938, 0x9115, 0x190c, 0xb40c, 0x080c, 0x683d,
- 0x6210, 0x2258, 0xba3c, 0x82ff, 0x0110, 0x8211, 0xba3e, 0x7044,
- 0xd0e4, 0x1904, 0xb212, 0x080c, 0x9fd5, 0x009e, 0x00be, 0x0005,
- 0x968c, 0x0c00, 0x0150, 0x6010, 0x2058, 0xb800, 0xd0bc, 0x1904,
- 0xb216, 0x7348, 0xab92, 0x734c, 0xab8e, 0x968c, 0x00ff, 0x9186,
- 0x0002, 0x0508, 0x9186, 0x0028, 0x1118, 0xa87b, 0x001c, 0x00e8,
- 0xd6dc, 0x01a0, 0xa87b, 0x0015, 0xa87c, 0xd0ac, 0x0170, 0xa938,
- 0xaa34, 0x2100, 0x9205, 0x0148, 0x7048, 0x9106, 0x1118, 0x704c,
- 0x9206, 0x0118, 0xa992, 0xaa8e, 0xc6dc, 0x0038, 0xd6d4, 0x0118,
- 0xa87b, 0x0007, 0x0010, 0xa87b, 0x0000, 0xa867, 0x0103, 0xae76,
- 0x901e, 0xd6c4, 0x01d8, 0x9686, 0x0100, 0x1130, 0x7064, 0x9005,
- 0x1118, 0xc6c4, 0x0804, 0xb169, 0x735c, 0xab86, 0x83ff, 0x0170,
- 0x938a, 0x0009, 0x0210, 0x2019, 0x0008, 0x0036, 0x2308, 0x2019,
- 0x0018, 0x2011, 0x0025, 0x080c, 0xb906, 0x003e, 0xd6cc, 0x0904,
- 0xb17e, 0x7154, 0xa98a, 0x81ff, 0x0904, 0xb17e, 0x9192, 0x0021,
- 0x1278, 0x8304, 0x9098, 0x0018, 0x2011, 0x0029, 0x080c, 0xb906,
- 0x2011, 0x0205, 0x2013, 0x0000, 0x080c, 0xc3e9, 0x0804, 0xb17e,
- 0xa868, 0xd0fc, 0x0120, 0x2009, 0x0020, 0xa98a, 0x0c50, 0x00a6,
- 0x2950, 0x080c, 0xb8a5, 0x00ae, 0x080c, 0xc3e9, 0x080c, 0xb8f6,
- 0x0804, 0xb180, 0x080c, 0xc03b, 0x0804, 0xb18d, 0xa87c, 0xd0ac,
- 0x0904, 0xb199, 0xa880, 0xd0bc, 0x1904, 0xb199, 0x7348, 0xa838,
- 0x9306, 0x11c8, 0x734c, 0xa834, 0x931e, 0x0904, 0xb199, 0xd6d4,
- 0x0190, 0xab38, 0x9305, 0x0904, 0xb199, 0x0068, 0xa87c, 0xd0ac,
- 0x0904, 0xb171, 0xa838, 0xa934, 0x9105, 0x0904, 0xb171, 0xa880,
- 0xd0bc, 0x1904, 0xb171, 0x080c, 0xc075, 0x0804, 0xb18d, 0x0096,
- 0x00f6, 0x6003, 0x0003, 0x6007, 0x0043, 0x2079, 0x026c, 0x7c04,
- 0x7b00, 0x7e0c, 0x7d08, 0x6014, 0x2048, 0xa87c, 0xd0ac, 0x0140,
- 0x6003, 0x0002, 0x00fe, 0x009e, 0x0005, 0x2130, 0x2228, 0x0058,
- 0x2400, 0xa9ac, 0x910a, 0x2300, 0xaab0, 0x9213, 0x2600, 0x9102,
- 0x2500, 0x9203, 0x0e90, 0xac36, 0xab3a, 0xae46, 0xad4a, 0x00fe,
- 0x6043, 0x0000, 0x2c10, 0x080c, 0x1a82, 0x080c, 0x865e, 0x080c,
- 0x8c6d, 0x009e, 0x0005, 0x0005, 0x9182, 0x0054, 0x1220, 0x9182,
- 0x0040, 0x0208, 0x000a, 0x0005, 0xb290, 0xb290, 0xb290, 0xb290,
- 0xb290, 0xb292, 0xb328, 0xb290, 0xb290, 0xb33f, 0xb3cf, 0xb290,
- 0xb290, 0xb290, 0xb290, 0xb3e4, 0xb290, 0xb290, 0xb290, 0xb290,
- 0x080c, 0x0e02, 0x0076, 0x00a6, 0x00e6, 0x0096, 0x2071, 0x0260,
- 0x6114, 0x2150, 0x7644, 0xb676, 0x96b4, 0x0fff, 0xb77c, 0xc7e5,
- 0xb77e, 0x6210, 0x00b6, 0x2258, 0xba3c, 0x82ff, 0x0110, 0x8211,
- 0xba3e, 0x00be, 0x86ff, 0x0904, 0xb323, 0x9694, 0xff00, 0x9284,
- 0x0c00, 0x0120, 0x7048, 0xb092, 0x704c, 0xb08e, 0x9284, 0x0300,
- 0x0904, 0xb323, 0x080c, 0x1043, 0x090c, 0x0e02, 0x2900, 0xb07a,
- 0xb77c, 0xc7cd, 0xb77e, 0xa867, 0x0103, 0xb068, 0xa86a, 0xb06c,
- 0xa86e, 0xb070, 0xa872, 0xae76, 0x968c, 0x0c00, 0x0120, 0x7348,
- 0xab92, 0x734c, 0xab8e, 0x968c, 0x00ff, 0x9186, 0x0002, 0x0180,
- 0x9186, 0x0028, 0x1118, 0xa87b, 0x001c, 0x0060, 0xd6dc, 0x0118,
- 0xa87b, 0x0015, 0x0038, 0xd6d4, 0x0118, 0xa87b, 0x0007, 0x0010,
- 0xa87b, 0x0000, 0xaf7e, 0xb080, 0xa882, 0xb084, 0xa886, 0x901e,
- 0xd6c4, 0x0190, 0x735c, 0xab86, 0x83ff, 0x0170, 0x938a, 0x0009,
- 0x0210, 0x2019, 0x0008, 0x0036, 0x2308, 0x2019, 0x0018, 0x2011,
- 0x0025, 0x080c, 0xb906, 0x003e, 0xd6cc, 0x01e8, 0x7154, 0xa98a,
- 0x81ff, 0x01c8, 0x9192, 0x0021, 0x1260, 0x8304, 0x9098, 0x0018,
- 0x2011, 0x0029, 0x080c, 0xb906, 0x2011, 0x0205, 0x2013, 0x0000,
- 0x0050, 0xb068, 0xd0fc, 0x0120, 0x2009, 0x0020, 0xa98a, 0x0c68,
- 0x2950, 0x080c, 0xb8a5, 0x009e, 0x00ee, 0x00ae, 0x007e, 0x0005,
- 0x00f6, 0x00a6, 0x6003, 0x0003, 0x2079, 0x026c, 0x7c04, 0x7b00,
- 0x7e0c, 0x7d08, 0x6014, 0x2050, 0xb436, 0xb33a, 0xb646, 0xb54a,
- 0x00ae, 0x00fe, 0x2c10, 0x080c, 0x1a82, 0x0804, 0x95d2, 0x6003,
- 0x0002, 0x6004, 0x9086, 0x0040, 0x11c8, 0x0096, 0x6014, 0x2048,
- 0xa87c, 0xd0ac, 0x0160, 0x601c, 0xd084, 0x1130, 0x00f6, 0x2c00,
- 0x2078, 0x080c, 0x165d, 0x00fe, 0x6003, 0x0004, 0x0010, 0x6003,
- 0x0002, 0x009e, 0x080c, 0x8a84, 0x080c, 0x8b90, 0x0096, 0x2001,
- 0x1962, 0x2004, 0x6042, 0x080c, 0x8b40, 0x080c, 0x8c6d, 0x6114,
- 0x2148, 0xa97c, 0xd1e4, 0x0904, 0xb3ca, 0xd1cc, 0x05c8, 0xa978,
- 0xa868, 0xd0fc, 0x0540, 0x0016, 0xa87c, 0x0006, 0xa880, 0x0006,
- 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0019, 0x20a0, 0x810e, 0x810e,
- 0x810f, 0x9184, 0x003f, 0x20e0, 0x9184, 0xffc0, 0x9080, 0x0019,
- 0x2098, 0x0156, 0x20a9, 0x0020, 0x4003, 0x015e, 0x000e, 0xa882,
- 0x000e, 0xc0cc, 0xa87e, 0x001e, 0xa874, 0x0006, 0x2148, 0x080c,
- 0x0ff5, 0x001e, 0x0458, 0x0016, 0x080c, 0x0ff5, 0x009e, 0xa87c,
- 0xc0cc, 0xa87e, 0xa974, 0x0016, 0x080c, 0xb8f6, 0x001e, 0x00f0,
- 0xa867, 0x0103, 0xa974, 0x9184, 0x00ff, 0x90b6, 0x0002, 0x0180,
- 0x9086, 0x0028, 0x1118, 0xa87b, 0x001c, 0x0060, 0xd1dc, 0x0118,
- 0xa87b, 0x0015, 0x0038, 0xd1d4, 0x0118, 0xa87b, 0x0007, 0x0010,
- 0xa87b, 0x0000, 0x0016, 0x080c, 0x683d, 0x001e, 0xd1e4, 0x1120,
- 0x080c, 0x9fd5, 0x009e, 0x0005, 0x080c, 0xc03b, 0x0cd8, 0x6004,
- 0x9086, 0x0040, 0x1120, 0x080c, 0x8a84, 0x080c, 0x8b90, 0x2019,
- 0x0001, 0x080c, 0x989c, 0x6003, 0x0002, 0x080c, 0xc461, 0x080c,
- 0x8b40, 0x080c, 0x8c6d, 0x0005, 0x6004, 0x9086, 0x0040, 0x1120,
- 0x080c, 0x8a84, 0x080c, 0x8b90, 0x2019, 0x0001, 0x080c, 0x989c,
- 0x080c, 0x8b40, 0x080c, 0x30ab, 0x080c, 0xc459, 0x0096, 0x6114,
- 0x2148, 0x080c, 0xbd3b, 0x0150, 0xa867, 0x0103, 0xa87b, 0x0029,
- 0xa877, 0x0000, 0x080c, 0x6a23, 0x080c, 0xbf26, 0x009e, 0x080c,
- 0x9fd5, 0x080c, 0x8c6d, 0x0005, 0xa87b, 0x0015, 0xd1fc, 0x0180,
- 0xa87b, 0x0007, 0x8002, 0x8000, 0x810a, 0x9189, 0x0000, 0x0006,
- 0x0016, 0x2009, 0x1a55, 0x2104, 0x8000, 0x200a, 0x001e, 0x000e,
- 0xa992, 0xa88e, 0x0005, 0x9182, 0x0054, 0x1220, 0x9182, 0x0040,
- 0x0208, 0x000a, 0x0005, 0xb43f, 0xb43f, 0xb43f, 0xb43f, 0xb43f,
- 0xb441, 0xb43f, 0xb43f, 0xb4e7, 0xb43f, 0xb43f, 0xb43f, 0xb43f,
- 0xb43f, 0xb43f, 0xb43f, 0xb43f, 0xb43f, 0xb43f, 0xb619, 0x080c,
- 0x0e02, 0x0076, 0x00a6, 0x00e6, 0x0096, 0x2071, 0x0260, 0x6114,
+ 0xb16c, 0xb16c, 0xb16c, 0xb16c, 0xb16c, 0xb16e, 0xb24e, 0xb16c,
+ 0xb282, 0xb16c, 0xb16c, 0xb16c, 0xb16c, 0xb16c, 0xb16c, 0xb16c,
+ 0xb16c, 0xb16c, 0xb16c, 0xb282, 0x080c, 0x0df6, 0x00b6, 0x0096,
+ 0x6114, 0x2148, 0x7644, 0x96b4, 0x0fff, 0x86ff, 0x1528, 0x6010,
+ 0x2058, 0xb800, 0xd0bc, 0x1904, 0xb23d, 0xa87b, 0x0000, 0xa867,
+ 0x0103, 0xae76, 0xa87c, 0xd0ac, 0x0128, 0xa834, 0xa938, 0x9115,
+ 0x190c, 0xb41b, 0x080c, 0x683c, 0x6210, 0x2258, 0xba3c, 0x82ff,
+ 0x0110, 0x8211, 0xba3e, 0x7044, 0xd0e4, 0x1904, 0xb21e, 0x080c,
+ 0x9fea, 0x009e, 0x00be, 0x0005, 0x968c, 0x0c00, 0x0150, 0x6010,
+ 0x2058, 0xb800, 0xd0bc, 0x1904, 0xb222, 0x7348, 0xab92, 0x734c,
+ 0xab8e, 0x968c, 0x00ff, 0x9186, 0x0002, 0x0508, 0x9186, 0x0028,
+ 0x1118, 0xa87b, 0x001c, 0x00e8, 0xd6dc, 0x01a0, 0xa87b, 0x0015,
+ 0xa87c, 0xd0ac, 0x0170, 0xa938, 0xaa34, 0x2100, 0x9205, 0x0148,
+ 0x7048, 0x9106, 0x1118, 0x704c, 0x9206, 0x0118, 0xa992, 0xaa8e,
+ 0xc6dc, 0x0038, 0xd6d4, 0x0118, 0xa87b, 0x0007, 0x0010, 0xa87b,
+ 0x0000, 0xa867, 0x0103, 0xae76, 0x901e, 0xd6c4, 0x01d8, 0x9686,
+ 0x0100, 0x1130, 0x7064, 0x9005, 0x1118, 0xc6c4, 0x0804, 0xb175,
+ 0x735c, 0xab86, 0x83ff, 0x0170, 0x938a, 0x0009, 0x0210, 0x2019,
+ 0x0008, 0x0036, 0x2308, 0x2019, 0x0018, 0x2011, 0x0025, 0x080c,
+ 0xb915, 0x003e, 0xd6cc, 0x0904, 0xb18a, 0x7154, 0xa98a, 0x81ff,
+ 0x0904, 0xb18a, 0x9192, 0x0021, 0x1278, 0x8304, 0x9098, 0x0018,
+ 0x2011, 0x0029, 0x080c, 0xb915, 0x2011, 0x0205, 0x2013, 0x0000,
+ 0x080c, 0xc3fc, 0x0804, 0xb18a, 0xa868, 0xd0fc, 0x0120, 0x2009,
+ 0x0020, 0xa98a, 0x0c50, 0x00a6, 0x2950, 0x080c, 0xb8b4, 0x00ae,
+ 0x080c, 0xc3fc, 0x080c, 0xb905, 0x0804, 0xb18c, 0x080c, 0xc04e,
+ 0x0804, 0xb199, 0xa87c, 0xd0ac, 0x0904, 0xb1a5, 0xa880, 0xd0bc,
+ 0x1904, 0xb1a5, 0x9684, 0x0400, 0x0130, 0xa838, 0xab34, 0x9305,
+ 0x0904, 0xb1a5, 0x00b8, 0x7348, 0xa838, 0x9306, 0x1198, 0x734c,
+ 0xa834, 0x931e, 0x0904, 0xb1a5, 0x0068, 0xa87c, 0xd0ac, 0x0904,
+ 0xb17d, 0xa838, 0xa934, 0x9105, 0x0904, 0xb17d, 0xa880, 0xd0bc,
+ 0x1904, 0xb17d, 0x080c, 0xc088, 0x0804, 0xb199, 0x0096, 0x00f6,
+ 0x6003, 0x0003, 0x6007, 0x0043, 0x2079, 0x026c, 0x7c04, 0x7b00,
+ 0x7e0c, 0x7d08, 0x6014, 0x2048, 0xa87c, 0xd0ac, 0x0140, 0x6003,
+ 0x0002, 0x00fe, 0x009e, 0x0005, 0x2130, 0x2228, 0x0058, 0x2400,
+ 0xa9ac, 0x910a, 0x2300, 0xaab0, 0x9213, 0x2600, 0x9102, 0x2500,
+ 0x9203, 0x0e90, 0xac36, 0xab3a, 0xae46, 0xad4a, 0x00fe, 0x6043,
+ 0x0000, 0x2c10, 0x080c, 0x1a7e, 0x080c, 0x865d, 0x080c, 0x8c6c,
+ 0x009e, 0x0005, 0x0005, 0x9182, 0x0054, 0x1220, 0x9182, 0x0040,
+ 0x0208, 0x000a, 0x0005, 0xb29f, 0xb29f, 0xb29f, 0xb29f, 0xb29f,
+ 0xb2a1, 0xb337, 0xb29f, 0xb29f, 0xb34e, 0xb3de, 0xb29f, 0xb29f,
+ 0xb29f, 0xb29f, 0xb3f3, 0xb29f, 0xb29f, 0xb29f, 0xb29f, 0x080c,
+ 0x0df6, 0x0076, 0x00a6, 0x00e6, 0x0096, 0x2071, 0x0260, 0x6114,
0x2150, 0x7644, 0xb676, 0x96b4, 0x0fff, 0xb77c, 0xc7e5, 0xb77e,
0x6210, 0x00b6, 0x2258, 0xba3c, 0x82ff, 0x0110, 0x8211, 0xba3e,
- 0x00be, 0x86ff, 0x0904, 0xb4e0, 0x9694, 0xff00, 0x9284, 0x0c00,
+ 0x00be, 0x86ff, 0x0904, 0xb332, 0x9694, 0xff00, 0x9284, 0x0c00,
0x0120, 0x7048, 0xb092, 0x704c, 0xb08e, 0x9284, 0x0300, 0x0904,
- 0xb4e0, 0x9686, 0x0100, 0x1130, 0x7064, 0x9005, 0x1118, 0xc6c4,
- 0xb676, 0x0c38, 0x080c, 0x1043, 0x090c, 0x0e02, 0x2900, 0xb07a,
- 0xb77c, 0x97bd, 0x0200, 0xb77e, 0xa867, 0x0103, 0xb068, 0xa86a,
- 0xb06c, 0xa86e, 0xb070, 0xa872, 0x7044, 0x9084, 0xf000, 0x9635,
- 0xae76, 0x968c, 0x0c00, 0x0120, 0x7348, 0xab92, 0x734c, 0xab8e,
- 0x968c, 0x00ff, 0x9186, 0x0002, 0x0180, 0x9186, 0x0028, 0x1118,
- 0xa87b, 0x001c, 0x0060, 0xd6dc, 0x0118, 0xa87b, 0x0015, 0x0038,
- 0xd6d4, 0x0118, 0xa87b, 0x0007, 0x0010, 0xa87b, 0x0000, 0xaf7e,
- 0xb080, 0xa882, 0xb084, 0xa886, 0x901e, 0xd6c4, 0x0190, 0x735c,
- 0xab86, 0x83ff, 0x0170, 0x938a, 0x0009, 0x0210, 0x2019, 0x0008,
- 0x0036, 0x2308, 0x2019, 0x0018, 0x2011, 0x0025, 0x080c, 0xb906,
- 0x003e, 0xd6cc, 0x01e8, 0x7154, 0xa98a, 0x81ff, 0x01c8, 0x9192,
- 0x0021, 0x1260, 0x8304, 0x9098, 0x0018, 0x2011, 0x0029, 0x080c,
- 0xb906, 0x2011, 0x0205, 0x2013, 0x0000, 0x0050, 0xb068, 0xd0fc,
- 0x0120, 0x2009, 0x0020, 0xa98a, 0x0c68, 0x2950, 0x080c, 0xb8a5,
- 0x080c, 0x1904, 0x009e, 0x00ee, 0x00ae, 0x007e, 0x0005, 0x2001,
- 0x1962, 0x2004, 0x6042, 0x0096, 0x6114, 0x2148, 0xa83c, 0xa940,
- 0x9105, 0x1118, 0xa87c, 0xc0dc, 0xa87e, 0x6003, 0x0002, 0xa97c,
- 0xd1e4, 0x0904, 0xb614, 0x6043, 0x0000, 0x6010, 0x00b6, 0x2058,
- 0xb800, 0x00be, 0xd0bc, 0x1500, 0xd1cc, 0x0904, 0xb5e3, 0xa978,
- 0xa868, 0xd0fc, 0x0904, 0xb5a4, 0x0016, 0xa87c, 0x0006, 0xa880,
- 0x0006, 0x00a6, 0x2150, 0xb174, 0x9184, 0x00ff, 0x90b6, 0x0002,
- 0x0904, 0xb571, 0x9086, 0x0028, 0x1904, 0xb55d, 0xa87b, 0x001c,
- 0xb07b, 0x001c, 0x0804, 0xb579, 0x6024, 0xd0f4, 0x11d0, 0xa838,
- 0xaa34, 0x9205, 0x09c8, 0xa838, 0xaa90, 0x9206, 0x1120, 0xa88c,
- 0xaa34, 0x9206, 0x0988, 0x6024, 0xd0d4, 0x1148, 0xa9ac, 0xa834,
- 0x9102, 0x603a, 0xa9b0, 0xa838, 0x9103, 0x603e, 0x6024, 0xc0f5,
- 0x6026, 0x6010, 0x00b6, 0x2058, 0xb83c, 0x8000, 0xb83e, 0x00be,
- 0x9006, 0xa876, 0xa892, 0xa88e, 0xa87c, 0xc0e4, 0xa87e, 0xd0cc,
- 0x0140, 0xc0cc, 0xa87e, 0x0096, 0xa878, 0x2048, 0x080c, 0x0ff5,
- 0x009e, 0x080c, 0xc075, 0x0804, 0xb614, 0xd1dc, 0x0158, 0xa87b,
- 0x0015, 0xb07b, 0x0015, 0x080c, 0xc309, 0x0118, 0xb174, 0xc1dc,
- 0xb176, 0x0078, 0xd1d4, 0x0128, 0xa87b, 0x0007, 0xb07b, 0x0007,
- 0x0040, 0xa87c, 0xd0ac, 0x0128, 0xa834, 0xa938, 0x9115, 0x190c,
- 0xb40c, 0xa87c, 0xb07e, 0xa890, 0xb092, 0xa88c, 0xb08e, 0xa860,
- 0x20e8, 0xa85c, 0x9080, 0x0019, 0x20a0, 0x20a9, 0x0020, 0x8a06,
- 0x8006, 0x8007, 0x9094, 0x003f, 0x22e0, 0x9084, 0xffc0, 0x9080,
- 0x0019, 0x2098, 0x4003, 0x00ae, 0x000e, 0xa882, 0x000e, 0xc0cc,
- 0xa87e, 0x080c, 0xc3e9, 0x001e, 0xa874, 0x0006, 0x2148, 0x080c,
- 0x0ff5, 0x001e, 0x0804, 0xb610, 0x0016, 0x00a6, 0x2150, 0xb174,
- 0x9184, 0x00ff, 0x90b6, 0x0002, 0x01e0, 0x9086, 0x0028, 0x1128,
- 0xa87b, 0x001c, 0xb07b, 0x001c, 0x00e0, 0xd1dc, 0x0158, 0xa87b,
- 0x0015, 0xb07b, 0x0015, 0x080c, 0xc309, 0x0118, 0xb174, 0xc1dc,
- 0xb176, 0x0078, 0xd1d4, 0x0128, 0xa87b, 0x0007, 0xb07b, 0x0007,
- 0x0040, 0xa87c, 0xd0ac, 0x0128, 0xa834, 0xa938, 0x9115, 0x190c,
- 0xb40c, 0xa890, 0xb092, 0xa88c, 0xb08e, 0xa87c, 0xb07e, 0x00ae,
- 0x080c, 0x0ff5, 0x009e, 0x080c, 0xc3e9, 0xa974, 0x0016, 0x080c,
- 0xb8f6, 0x001e, 0x0468, 0xa867, 0x0103, 0xa974, 0x9184, 0x00ff,
- 0x90b6, 0x0002, 0x01b0, 0x9086, 0x0028, 0x1118, 0xa87b, 0x001c,
- 0x00d0, 0xd1dc, 0x0148, 0xa87b, 0x0015, 0x080c, 0xc309, 0x0118,
- 0xa974, 0xc1dc, 0xa976, 0x0078, 0xd1d4, 0x0118, 0xa87b, 0x0007,
- 0x0050, 0xa87b, 0x0000, 0xa87c, 0xd0ac, 0x0128, 0xa834, 0xa938,
- 0x9115, 0x190c, 0xb40c, 0xa974, 0x0016, 0x080c, 0x683d, 0x001e,
- 0xd1e4, 0x1120, 0x080c, 0x9fd5, 0x009e, 0x0005, 0x080c, 0xc03b,
- 0x0cd8, 0x6114, 0x0096, 0x2148, 0xa97c, 0xd1e4, 0x190c, 0x1924,
- 0x009e, 0x0005, 0x080c, 0x8a84, 0x0010, 0x080c, 0x8b40, 0x080c,
- 0xbd3b, 0x01f0, 0x0096, 0x6114, 0x2148, 0x080c, 0xbf43, 0x1118,
- 0x080c, 0xa995, 0x00a0, 0xa867, 0x0103, 0x2009, 0x180c, 0x210c,
- 0xd18c, 0x11b8, 0xd184, 0x1190, 0x6108, 0xa97a, 0x918e, 0x0029,
- 0x1110, 0x080c, 0xda80, 0xa877, 0x0000, 0x080c, 0x6a23, 0x009e,
- 0x080c, 0x9fd5, 0x080c, 0x8b90, 0x0804, 0x8c6d, 0xa87b, 0x0004,
- 0x0c90, 0xa87b, 0x0004, 0x0c78, 0x9182, 0x0054, 0x1220, 0x9182,
- 0x0040, 0x0208, 0x000a, 0x0005, 0xb670, 0xb670, 0xb670, 0xb670,
- 0xb670, 0xb672, 0xb670, 0xb670, 0xb670, 0xb670, 0xb670, 0xb670,
- 0xb670, 0xb670, 0xb670, 0xb670, 0xb670, 0xb670, 0xb670, 0xb670,
- 0x080c, 0x0e02, 0x080c, 0x54e4, 0x01f8, 0x6014, 0x7144, 0x918c,
- 0x0fff, 0x9016, 0xd1c4, 0x0118, 0x7264, 0x9294, 0x00ff, 0x0096,
- 0x904d, 0x0188, 0xa87b, 0x0000, 0xa864, 0x9086, 0x0139, 0x0128,
- 0xa867, 0x0103, 0xa976, 0xaa96, 0x0030, 0xa897, 0x4000, 0xa99a,
- 0xaa9e, 0x080c, 0x6a23, 0x009e, 0x0804, 0x9fd5, 0x9182, 0x0085,
- 0x0002, 0xb6a8, 0xb6a6, 0xb6a6, 0xb6b4, 0xb6a6, 0xb6a6, 0xb6a6,
- 0xb6a6, 0xb6a6, 0xb6a6, 0xb6a6, 0xb6a6, 0xb6a6, 0x080c, 0x0e02,
- 0x6003, 0x0001, 0x6106, 0x080c, 0x85f9, 0x0126, 0x2091, 0x8000,
- 0x080c, 0x8b90, 0x012e, 0x0005, 0x0026, 0x0056, 0x00d6, 0x00e6,
- 0x2071, 0x0260, 0x7224, 0x6216, 0x7220, 0x080c, 0xbd29, 0x01f8,
- 0x2268, 0x6800, 0x9086, 0x0000, 0x01d0, 0x6010, 0x6d10, 0x952e,
- 0x11b0, 0x00c6, 0x2d60, 0x00d6, 0x080c, 0xb967, 0x00de, 0x00ce,
- 0x0158, 0x702c, 0xd084, 0x1118, 0x080c, 0xb931, 0x0010, 0x6803,
- 0x0002, 0x6007, 0x0086, 0x0028, 0x080c, 0xb953, 0x0d90, 0x6007,
- 0x0087, 0x6003, 0x0001, 0x080c, 0x85f9, 0x080c, 0x8b90, 0x7220,
- 0x080c, 0xbd29, 0x0178, 0x6810, 0x00b6, 0x2058, 0xb800, 0x00be,
- 0xd0bc, 0x0140, 0x6824, 0xd0ec, 0x0128, 0x00c6, 0x2d60, 0x080c,
- 0xc075, 0x00ce, 0x00ee, 0x00de, 0x005e, 0x002e, 0x0005, 0x9186,
- 0x0013, 0x1160, 0x6004, 0x908a, 0x0085, 0x0a0c, 0x0e02, 0x908a,
- 0x0092, 0x1a0c, 0x0e02, 0x9082, 0x0085, 0x00e2, 0x9186, 0x0027,
- 0x0120, 0x9186, 0x0014, 0x190c, 0x0e02, 0x080c, 0x8a84, 0x0096,
- 0x6014, 0x2048, 0x080c, 0xbd3b, 0x0140, 0xa867, 0x0103, 0xa877,
- 0x0000, 0xa87b, 0x0029, 0x080c, 0x6a23, 0x009e, 0x080c, 0xa007,
- 0x0804, 0x8b90, 0xb737, 0xb739, 0xb739, 0xb737, 0xb737, 0xb737,
- 0xb737, 0xb737, 0xb737, 0xb737, 0xb737, 0xb737, 0xb737, 0x080c,
- 0x0e02, 0x080c, 0x8a84, 0x080c, 0xa007, 0x080c, 0x8b90, 0x0005,
- 0x9186, 0x0013, 0x1128, 0x6004, 0x9082, 0x0085, 0x2008, 0x04b8,
- 0x9186, 0x0027, 0x11f8, 0x080c, 0x8a84, 0x080c, 0x30ab, 0x080c,
- 0xc459, 0x0096, 0x6014, 0x2048, 0x080c, 0xbd3b, 0x0150, 0xa867,
- 0x0103, 0xa877, 0x0000, 0xa87b, 0x0029, 0x080c, 0x6a23, 0x080c,
- 0xbf26, 0x009e, 0x080c, 0x9fd5, 0x080c, 0x8b90, 0x0005, 0x080c,
- 0xa06e, 0x0ce0, 0x9186, 0x0014, 0x1dd0, 0x080c, 0x8a84, 0x0096,
- 0x6014, 0x2048, 0x080c, 0xbd3b, 0x0d60, 0xa867, 0x0103, 0xa877,
- 0x0000, 0xa87b, 0x0006, 0xa880, 0xc0ec, 0xa882, 0x08f0, 0x0002,
- 0xb78f, 0xb78d, 0xb78d, 0xb78d, 0xb78d, 0xb78d, 0xb7a7, 0xb78d,
- 0xb78d, 0xb78d, 0xb78d, 0xb78d, 0xb78d, 0x080c, 0x0e02, 0x080c,
- 0x8a84, 0x6034, 0x908c, 0xff00, 0x810f, 0x9186, 0x0039, 0x0118,
- 0x9186, 0x0035, 0x1118, 0x2001, 0x1960, 0x0010, 0x2001, 0x1961,
- 0x2004, 0x601a, 0x6003, 0x000c, 0x080c, 0x8b90, 0x0005, 0x080c,
- 0x8a84, 0x6034, 0x908c, 0xff00, 0x810f, 0x9186, 0x0039, 0x0118,
- 0x9186, 0x0035, 0x1118, 0x2001, 0x1960, 0x0010, 0x2001, 0x1961,
- 0x2004, 0x601a, 0x6003, 0x000e, 0x080c, 0x8b90, 0x0005, 0x9182,
- 0x0092, 0x1220, 0x9182, 0x0085, 0x0208, 0x0012, 0x0804, 0xa06e,
- 0xb7d5, 0xb7d5, 0xb7d5, 0xb7d5, 0xb7d7, 0xb824, 0xb7d5, 0xb7d5,
- 0xb7d5, 0xb7d5, 0xb7d5, 0xb7d5, 0xb7d5, 0x080c, 0x0e02, 0x0096,
- 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x0168, 0x6034,
- 0x908c, 0xff00, 0x810f, 0x9186, 0x0039, 0x0118, 0x9186, 0x0035,
- 0x1118, 0x009e, 0x0804, 0xb838, 0x080c, 0xbd3b, 0x1118, 0x080c,
- 0xbf26, 0x0068, 0x6014, 0x2048, 0xa87c, 0xd0e4, 0x1110, 0x080c,
- 0xbf26, 0xa867, 0x0103, 0x080c, 0xc424, 0x080c, 0x6a23, 0x00d6,
- 0x2c68, 0x080c, 0x9f7f, 0x01d0, 0x6003, 0x0001, 0x6007, 0x001e,
- 0x600b, 0xffff, 0x2009, 0x026e, 0x210c, 0x613a, 0x2009, 0x026f,
- 0x210c, 0x613e, 0x6910, 0x6112, 0x080c, 0xc1b7, 0x6954, 0x6156,
- 0x6023, 0x0001, 0x080c, 0x85f9, 0x080c, 0x8b90, 0x2d60, 0x00de,
- 0x080c, 0x9fd5, 0x009e, 0x0005, 0x6010, 0x00b6, 0x2058, 0xb800,
- 0x00be, 0xd0bc, 0x05a0, 0x6034, 0x908c, 0xff00, 0x810f, 0x9186,
- 0x0035, 0x0130, 0x9186, 0x001e, 0x0118, 0x9186, 0x0039, 0x1538,
- 0x00d6, 0x2c68, 0x080c, 0xc3bc, 0x11f0, 0x080c, 0x9f7f, 0x01d8,
- 0x6106, 0x6003, 0x0001, 0x6023, 0x0001, 0x6910, 0x6112, 0x692c,
- 0x612e, 0x6930, 0x6132, 0x6934, 0x918c, 0x00ff, 0x6136, 0x6938,
- 0x613a, 0x693c, 0x613e, 0x6954, 0x6156, 0x080c, 0xc1b7, 0x080c,
- 0x85f9, 0x080c, 0x8b90, 0x2d60, 0x00de, 0x0804, 0x9fd5, 0x0096,
- 0x6014, 0x2048, 0x080c, 0xbd3b, 0x01c8, 0xa867, 0x0103, 0xa880,
- 0xd0b4, 0x0128, 0xc0ec, 0xa882, 0xa87b, 0x0006, 0x0048, 0xd0bc,
- 0x0118, 0xa87b, 0x0002, 0x0020, 0xa87b, 0x0005, 0x080c, 0xc037,
- 0xa877, 0x0000, 0x080c, 0x6a23, 0x080c, 0xbf26, 0x009e, 0x0804,
- 0x9fd5, 0x0016, 0x0096, 0x6014, 0x2048, 0x080c, 0xbd3b, 0x0140,
- 0xa867, 0x0103, 0xa87b, 0x0028, 0xa877, 0x0000, 0x080c, 0x6a23,
- 0x009e, 0x001e, 0x9186, 0x0013, 0x0148, 0x9186, 0x0014, 0x0130,
- 0x9186, 0x0027, 0x0118, 0x080c, 0xa06e, 0x0030, 0x080c, 0x8a84,
- 0x080c, 0xa007, 0x080c, 0x8b90, 0x0005, 0x0056, 0x0066, 0x0096,
- 0x00a6, 0x2029, 0x0001, 0x9182, 0x0101, 0x1208, 0x0010, 0x2009,
- 0x0100, 0x2130, 0x8304, 0x9098, 0x0018, 0x2009, 0x0020, 0x2011,
- 0x0029, 0x080c, 0xb906, 0x96b2, 0x0020, 0xb004, 0x904d, 0x0110,
- 0x080c, 0x0ff5, 0x080c, 0x1043, 0x0520, 0x8528, 0xa867, 0x0110,
- 0xa86b, 0x0000, 0x2920, 0xb406, 0x968a, 0x003d, 0x1228, 0x2608,
- 0x2011, 0x001b, 0x0499, 0x00a8, 0x96b2, 0x003c, 0x2009, 0x003c,
- 0x2950, 0x2011, 0x001b, 0x0451, 0x0c28, 0x2001, 0x0205, 0x2003,
- 0x0000, 0x00ae, 0x852f, 0x95ad, 0x0003, 0xb566, 0x95ac, 0x0000,
- 0x0048, 0x2001, 0x0205, 0x2003, 0x0000, 0x00ae, 0x852f, 0x95ad,
- 0x0003, 0xb566, 0x009e, 0x006e, 0x005e, 0x0005, 0x00a6, 0x89ff,
- 0x0158, 0xa804, 0x9055, 0x0130, 0xa807, 0x0000, 0x080c, 0x6a23,
- 0x2a48, 0x0cb8, 0x080c, 0x6a23, 0x00ae, 0x0005, 0x00f6, 0x2079,
- 0x0200, 0x7814, 0x9085, 0x0080, 0x7816, 0xd184, 0x0108, 0x8108,
- 0x810c, 0x20a9, 0x0001, 0xa860, 0x20e8, 0xa85c, 0x9200, 0x20a0,
- 0x20e1, 0x0000, 0x2300, 0x9e00, 0x2098, 0x4003, 0x8318, 0x9386,
- 0x0020, 0x1148, 0x2018, 0x2300, 0x9e00, 0x2098, 0x7814, 0x8000,
- 0x9085, 0x0080, 0x7816, 0x8109, 0x1d80, 0x7817, 0x0000, 0x00fe,
- 0x0005, 0x6920, 0x9186, 0x0003, 0x0118, 0x9186, 0x0002, 0x11d0,
- 0x00c6, 0x00d6, 0x00e6, 0x2d60, 0x0096, 0x6014, 0x2048, 0x080c,
- 0xbd3b, 0x0150, 0x2001, 0x0006, 0xa980, 0xc1d5, 0x080c, 0x6c6c,
- 0x080c, 0x6a16, 0x080c, 0xbf26, 0x009e, 0x080c, 0xa007, 0x00ee,
- 0x00de, 0x00ce, 0x0005, 0x00c6, 0x702c, 0xd084, 0x1170, 0x6008,
- 0x2060, 0x6020, 0x9086, 0x0002, 0x1140, 0x6104, 0x9186, 0x0085,
- 0x0118, 0x9186, 0x008b, 0x1108, 0x9006, 0x00ce, 0x0005, 0x0066,
- 0x0126, 0x2091, 0x8000, 0x2031, 0x0001, 0x6020, 0x9084, 0x000f,
- 0x0083, 0x012e, 0x006e, 0x0005, 0x0126, 0x2091, 0x8000, 0x0066,
- 0x2031, 0x0000, 0x6020, 0x9084, 0x000f, 0x001b, 0x006e, 0x012e,
- 0x0005, 0xb9a2, 0xb9a2, 0xb99d, 0xb9c4, 0xb990, 0xb99d, 0xb9c4,
- 0xb99d, 0xb990, 0xb990, 0xb99d, 0xb99d, 0xb99d, 0xb990, 0xb990,
- 0x080c, 0x0e02, 0x0036, 0x2019, 0x0010, 0x080c, 0xd385, 0x6023,
- 0x0006, 0x6003, 0x0007, 0x003e, 0x0005, 0x9006, 0x0005, 0x9085,
- 0x0001, 0x0005, 0x0096, 0x86ff, 0x11d8, 0x6014, 0x2048, 0x080c,
- 0xbd3b, 0x01c0, 0xa864, 0x9086, 0x0139, 0x1128, 0xa87b, 0x0005,
- 0xa883, 0x0000, 0x0028, 0x900e, 0x2001, 0x0005, 0x080c, 0x6c6c,
- 0x080c, 0xc037, 0x080c, 0x6a16, 0x080c, 0xa007, 0x9085, 0x0001,
- 0x009e, 0x0005, 0x9006, 0x0ce0, 0x6000, 0x908a, 0x0016, 0x1a0c,
- 0x0e02, 0x0002, 0xb9da, 0xba0a, 0xb9dc, 0xba2b, 0xba05, 0xb9da,
- 0xb99d, 0xb9a2, 0xb9a2, 0xb99d, 0xb99d, 0xb99d, 0xb99d, 0xb99d,
- 0xb99d, 0xb99d, 0x080c, 0x0e02, 0x86ff, 0x1520, 0x6020, 0x9086,
- 0x0006, 0x0500, 0x0096, 0x6014, 0x2048, 0x080c, 0xbd3b, 0x0168,
- 0xa87c, 0xd0cc, 0x0140, 0x0096, 0xc0cc, 0xa87e, 0xa878, 0x2048,
- 0x080c, 0x0ff5, 0x009e, 0x080c, 0xc037, 0x009e, 0x080c, 0xc3fe,
- 0x6007, 0x0085, 0x6003, 0x000b, 0x6023, 0x0002, 0x080c, 0x85f9,
- 0x080c, 0x8b90, 0x9085, 0x0001, 0x0005, 0x0066, 0x080c, 0x1938,
- 0x006e, 0x0890, 0x00e6, 0x2071, 0x19c2, 0x7024, 0x9c06, 0x1120,
- 0x080c, 0x9826, 0x00ee, 0x0840, 0x6020, 0x9084, 0x000f, 0x9086,
- 0x0006, 0x1150, 0x0086, 0x0096, 0x2049, 0x0001, 0x2c40, 0x080c,
- 0x994a, 0x009e, 0x008e, 0x0010, 0x080c, 0x9723, 0x00ee, 0x1904,
- 0xb9dc, 0x0804, 0xb99d, 0x0036, 0x00e6, 0x2071, 0x19c2, 0x703c,
- 0x9c06, 0x1138, 0x901e, 0x080c, 0x989c, 0x00ee, 0x003e, 0x0804,
- 0xb9dc, 0x080c, 0x9a7a, 0x00ee, 0x003e, 0x1904, 0xb9dc, 0x0804,
- 0xb99d, 0x00c6, 0x6020, 0x9084, 0x000f, 0x0013, 0x00ce, 0x0005,
- 0xba5e, 0xbb0f, 0xbc79, 0xba68, 0xa007, 0xba5e, 0xd377, 0xc466,
- 0xbb0f, 0xba57, 0xbd05, 0xba57, 0xba57, 0xba57, 0xba57, 0x080c,
- 0x0e02, 0x080c, 0xbf43, 0x1110, 0x080c, 0xa995, 0x0005, 0x080c,
- 0x8a84, 0x080c, 0x8b90, 0x0804, 0x9fd5, 0x601b, 0x0001, 0x0005,
- 0x080c, 0xbd3b, 0x0130, 0x6014, 0x0096, 0x2048, 0x2c00, 0xa896,
- 0x009e, 0x6000, 0x908a, 0x0016, 0x1a0c, 0x0e02, 0x0002, 0xba87,
- 0xba89, 0xbaad, 0xbac1, 0xbae7, 0xba87, 0xba5e, 0xba5e, 0xba5e,
- 0xbac1, 0xbac1, 0xba87, 0xba87, 0xba87, 0xba87, 0xbacb, 0x080c,
- 0x0e02, 0x00e6, 0x6014, 0x0096, 0x2048, 0xa880, 0xc0b5, 0xa882,
- 0x009e, 0x2071, 0x19c2, 0x7024, 0x9c06, 0x01a0, 0x080c, 0x9723,
- 0x080c, 0xc3fe, 0x6007, 0x0085, 0x6003, 0x000b, 0x6023, 0x0002,
- 0x2001, 0x1961, 0x2004, 0x601a, 0x080c, 0x85f9, 0x080c, 0x8b90,
- 0x00ee, 0x0005, 0x601b, 0x0001, 0x0cd8, 0x0096, 0x6014, 0x2048,
- 0xa880, 0xc0b5, 0xa882, 0x009e, 0x080c, 0xc3fe, 0x6007, 0x0085,
- 0x6003, 0x000b, 0x6023, 0x0002, 0x080c, 0x85f9, 0x080c, 0x8b90,
- 0x0005, 0x0096, 0x601b, 0x0001, 0x6014, 0x2048, 0xa880, 0xc0b5,
- 0xa882, 0x009e, 0x0005, 0x080c, 0x54e4, 0x01b8, 0x6014, 0x0096,
- 0x904d, 0x0190, 0xa864, 0xa867, 0x0103, 0xa87b, 0x0006, 0x9086,
- 0x0139, 0x1150, 0xa867, 0x0139, 0xa87b, 0x0030, 0xa897, 0x4005,
- 0xa89b, 0x0004, 0x080c, 0x6a23, 0x009e, 0x0804, 0x9fd5, 0x6014,
- 0x0096, 0x904d, 0x01f8, 0xa97c, 0xd1e4, 0x01e0, 0x2001, 0x180f,
- 0x2004, 0xd0c4, 0x0110, 0x009e, 0x0005, 0xa884, 0x009e, 0x8003,
- 0x800b, 0x810b, 0x9108, 0x611a, 0x2001, 0x0037, 0x2c08, 0x080c,
- 0x158c, 0x6000, 0x9086, 0x0004, 0x1120, 0x2009, 0x0048, 0x080c,
- 0xa053, 0x0005, 0x009e, 0x080c, 0x1938, 0x0804, 0xbaad, 0x6000,
- 0x908a, 0x0016, 0x1a0c, 0x0e02, 0x000b, 0x0005, 0xbb26, 0xba65,
- 0xbb28, 0xbb26, 0xbb28, 0xbb28, 0xba5f, 0xbb26, 0xba59, 0xba59,
- 0xbb26, 0xbb26, 0xbb26, 0xbb26, 0xbb26, 0xbb26, 0x080c, 0x0e02,
- 0x6010, 0x00b6, 0x2058, 0xb804, 0x9084, 0x00ff, 0x00be, 0x908a,
- 0x000c, 0x1a0c, 0x0e02, 0x00b6, 0x0013, 0x00be, 0x0005, 0xbb43,
- 0xbc10, 0xbb45, 0xbb85, 0xbb45, 0xbb85, 0xbb45, 0xbb53, 0xbb43,
- 0xbb85, 0xbb43, 0xbb74, 0x080c, 0x0e02, 0x6004, 0x908e, 0x0016,
- 0x05c0, 0x908e, 0x0004, 0x05a8, 0x908e, 0x0002, 0x0590, 0x908e,
- 0x0052, 0x0904, 0xbc0c, 0x6004, 0x080c, 0xbf43, 0x0904, 0xbc29,
- 0x908e, 0x0004, 0x1110, 0x080c, 0x30d4, 0x908e, 0x0021, 0x0904,
- 0xbc2d, 0x908e, 0x0022, 0x0904, 0xbc74, 0x908e, 0x003d, 0x0904,
- 0xbc2d, 0x908e, 0x0039, 0x0904, 0xbc31, 0x908e, 0x0035, 0x0904,
- 0xbc31, 0x908e, 0x001e, 0x0178, 0x908e, 0x0001, 0x1140, 0x6010,
- 0x2058, 0xb804, 0x9084, 0x00ff, 0x9086, 0x0006, 0x0110, 0x080c,
- 0x30ab, 0x080c, 0xa995, 0x0804, 0xa007, 0x00c6, 0x00d6, 0x6104,
- 0x9186, 0x0016, 0x0904, 0xbbfd, 0x9186, 0x0002, 0x1904, 0xbbd2,
- 0x2001, 0x1836, 0x2004, 0xd08c, 0x11c8, 0x080c, 0x717f, 0x11b0,
- 0x080c, 0xc444, 0x0138, 0x080c, 0x71a2, 0x1120, 0x080c, 0x707d,
- 0x0804, 0xbc5d, 0x2001, 0x1957, 0x2003, 0x0001, 0x2001, 0x1800,
- 0x2003, 0x0001, 0x080c, 0x709f, 0x0804, 0xbc5d, 0x6010, 0x2058,
- 0x2001, 0x1836, 0x2004, 0xd0ac, 0x1904, 0xbc5d, 0xb8a0, 0x9084,
- 0xff80, 0x1904, 0xbc5d, 0xb840, 0x9084, 0x00ff, 0x9005, 0x0190,
- 0x8001, 0xb842, 0x6017, 0x0000, 0x6023, 0x0007, 0x601b, 0x0398,
- 0x6043, 0x0000, 0x080c, 0x9f7f, 0x0128, 0x2b00, 0x6012, 0x6023,
- 0x0001, 0x0458, 0x00de, 0x00ce, 0x6004, 0x908e, 0x0002, 0x11a0,
- 0x6010, 0x2058, 0xb8a0, 0x9086, 0x007e, 0x1170, 0x2009, 0x1836,
- 0x2104, 0xc085, 0x200a, 0x00e6, 0x2071, 0x1800, 0x080c, 0x5dc3,
- 0x00ee, 0x080c, 0xa995, 0x0030, 0x080c, 0xa995, 0x080c, 0x30ab,
- 0x080c, 0xc459, 0x00e6, 0x0126, 0x2091, 0x8000, 0x080c, 0x30d4,
- 0x012e, 0x00ee, 0x080c, 0xa007, 0x0005, 0x2001, 0x0002, 0x080c,
- 0x62f5, 0x6003, 0x0001, 0x6007, 0x0002, 0x080c, 0x8641, 0x080c,
- 0x8b90, 0x00de, 0x00ce, 0x0c80, 0x080c, 0x30d4, 0x0804, 0xbb81,
- 0x00c6, 0x00d6, 0x6104, 0x9186, 0x0016, 0x0d38, 0x6010, 0x2058,
- 0xb840, 0x9084, 0x00ff, 0x9005, 0x0904, 0xbbd2, 0x8001, 0xb842,
- 0x6003, 0x0001, 0x080c, 0x8641, 0x080c, 0x8b90, 0x00de, 0x00ce,
- 0x0898, 0x080c, 0xa995, 0x0804, 0xbb83, 0x080c, 0xa9d1, 0x0804,
- 0xbb83, 0x00d6, 0x2c68, 0x6104, 0x080c, 0xc3bc, 0x00de, 0x0118,
- 0x080c, 0x9fd5, 0x0408, 0x6004, 0x8007, 0x6134, 0x918c, 0x00ff,
- 0x9105, 0x6036, 0x6007, 0x0085, 0x6003, 0x000b, 0x6023, 0x0002,
- 0x603c, 0x600a, 0x2001, 0x1961, 0x2004, 0x601a, 0x602c, 0x2c08,
- 0x2060, 0x6024, 0xd0b4, 0x0108, 0xc085, 0xc0b5, 0x6026, 0x2160,
- 0x080c, 0x85f9, 0x080c, 0x8b90, 0x0005, 0x00de, 0x00ce, 0x080c,
- 0xa995, 0x080c, 0x30ab, 0x00e6, 0x0126, 0x2091, 0x8000, 0x080c,
- 0x30d4, 0x6017, 0x0000, 0x6023, 0x0007, 0x601b, 0x0398, 0x6043,
- 0x0000, 0x012e, 0x00ee, 0x0005, 0x080c, 0xa40c, 0x1904, 0xbc29,
- 0x0005, 0x6000, 0x908a, 0x0016, 0x1a0c, 0x0e02, 0x0096, 0x00d6,
- 0x001b, 0x00de, 0x009e, 0x0005, 0xbc94, 0xbc94, 0xbc94, 0xbc94,
- 0xbc94, 0xbc94, 0xbc94, 0xbc94, 0xbc94, 0xba5e, 0xbc94, 0xba65,
- 0xbc96, 0xba65, 0xbcb0, 0xbc94, 0x080c, 0x0e02, 0x6004, 0x9086,
- 0x008b, 0x01b0, 0x6034, 0x908c, 0xff00, 0x810f, 0x9186, 0x0035,
- 0x1130, 0x602c, 0x9080, 0x0009, 0x200c, 0xc185, 0x2102, 0x6007,
- 0x008b, 0x6003, 0x000d, 0x080c, 0x85f9, 0x080c, 0x8b90, 0x0005,
- 0x080c, 0xc438, 0x0118, 0x080c, 0xc44b, 0x0010, 0x080c, 0xc459,
- 0x080c, 0xbf26, 0x080c, 0xbd3b, 0x0570, 0x080c, 0x30ab, 0x080c,
- 0xbd3b, 0x0168, 0x6014, 0x2048, 0xa867, 0x0103, 0xa87b, 0x0006,
- 0xa877, 0x0000, 0xa880, 0xc0ed, 0xa882, 0x080c, 0x6a23, 0x2c68,
- 0x080c, 0x9f7f, 0x0150, 0x6810, 0x6012, 0x080c, 0xc1b7, 0x00c6,
- 0x2d60, 0x080c, 0xa007, 0x00ce, 0x0008, 0x2d60, 0x6017, 0x0000,
- 0x6023, 0x0001, 0x6007, 0x0001, 0x6003, 0x0001, 0x080c, 0x8641,
- 0x080c, 0x8b90, 0x00c8, 0x080c, 0xc438, 0x0138, 0x6034, 0x9086,
- 0x4000, 0x1118, 0x080c, 0x30ab, 0x08d0, 0x6034, 0x908c, 0xff00,
- 0x810f, 0x9186, 0x0039, 0x0118, 0x9186, 0x0035, 0x1118, 0x080c,
- 0x30ab, 0x0868, 0x080c, 0xa007, 0x0005, 0x6000, 0x908a, 0x0016,
- 0x1a0c, 0x0e02, 0x0002, 0xbd1b, 0xbd1b, 0xbd1d, 0xbd1d, 0xbd1d,
- 0xbd1b, 0xbd1b, 0xa007, 0xbd1b, 0xbd1b, 0xbd1b, 0xbd1b, 0xbd1b,
- 0xbd1b, 0xbd1b, 0xbd1b, 0x080c, 0x0e02, 0x080c, 0x9a7a, 0x6114,
- 0x0096, 0x2148, 0xa87b, 0x0006, 0x080c, 0x6a23, 0x009e, 0x0804,
- 0x9fd5, 0x9284, 0x0007, 0x1158, 0x9282, 0x1cd0, 0x0240, 0x2001,
- 0x1819, 0x2004, 0x9202, 0x1218, 0x9085, 0x0001, 0x0005, 0x9006,
- 0x0ce8, 0x0096, 0x0028, 0x0096, 0x0006, 0x6014, 0x2048, 0x000e,
- 0x0006, 0x9984, 0xf000, 0x9086, 0xf000, 0x0110, 0x080c, 0x10ee,
- 0x000e, 0x009e, 0x0005, 0x00e6, 0x00c6, 0x0036, 0x0006, 0x0126,
- 0x2091, 0x8000, 0x2061, 0x1cd0, 0x2071, 0x1800, 0x7350, 0x7070,
- 0x9302, 0x1640, 0x6020, 0x9206, 0x11f8, 0x080c, 0xc444, 0x0180,
- 0x9286, 0x0001, 0x1168, 0x6004, 0x9086, 0x0004, 0x1148, 0x080c,
- 0x30ab, 0x080c, 0xc459, 0x00c6, 0x080c, 0xa007, 0x00ce, 0x0060,
- 0x080c, 0xc131, 0x0148, 0x080c, 0xbf43, 0x1110, 0x080c, 0xa995,
- 0x00c6, 0x080c, 0x9fd5, 0x00ce, 0x9ce0, 0x0018, 0x7064, 0x9c02,
- 0x1208, 0x08a0, 0x012e, 0x000e, 0x003e, 0x00ce, 0x00ee, 0x0005,
- 0x00e6, 0x00c6, 0x0016, 0x9188, 0x1000, 0x210c, 0x81ff, 0x0128,
- 0x2061, 0x1a88, 0x6112, 0x080c, 0x30ab, 0x9006, 0x0010, 0x9085,
- 0x0001, 0x001e, 0x00ce, 0x00ee, 0x0005, 0x00c6, 0x0126, 0x2091,
- 0x8000, 0x080c, 0x9f7f, 0x01b0, 0x6656, 0x2b00, 0x6012, 0x080c,
- 0x54e4, 0x0118, 0x080c, 0xbe6a, 0x0168, 0x080c, 0xc1b7, 0x6023,
- 0x0003, 0x2009, 0x004b, 0x080c, 0xa053, 0x9085, 0x0001, 0x012e,
- 0x00ce, 0x0005, 0x9006, 0x0cd8, 0x00c6, 0x0126, 0x2091, 0x8000,
- 0xbaa0, 0x080c, 0xa026, 0x0560, 0x6057, 0x0000, 0x2b00, 0x6012,
- 0x080c, 0xc1b7, 0x6023, 0x0003, 0x0016, 0x080c, 0x8783, 0x0076,
- 0x903e, 0x080c, 0x8671, 0x2c08, 0x080c, 0xd53b, 0x007e, 0x001e,
- 0xd184, 0x0128, 0x080c, 0x9fd5, 0x9085, 0x0001, 0x0070, 0x080c,
- 0x54e4, 0x0128, 0xd18c, 0x1170, 0x080c, 0xbe6a, 0x0148, 0x2009,
- 0x004c, 0x080c, 0xa053, 0x9085, 0x0001, 0x012e, 0x00ce, 0x0005,
- 0x9006, 0x0cd8, 0x2900, 0x6016, 0x0c90, 0x2009, 0x004d, 0x0010,
- 0x2009, 0x004e, 0x00f6, 0x00c6, 0x0046, 0x0016, 0x080c, 0x9f7f,
- 0x2c78, 0x05a0, 0x7e56, 0x2b00, 0x7812, 0x7823, 0x0003, 0x0016,
- 0x2021, 0x0005, 0x080c, 0xbe7c, 0x001e, 0x9186, 0x004d, 0x0118,
- 0x9186, 0x004e, 0x0148, 0x2001, 0x195a, 0x200c, 0xd1fc, 0x0168,
- 0x2f60, 0x080c, 0x9fd5, 0x00d0, 0x2001, 0x1959, 0x200c, 0xd1fc,
- 0x0120, 0x2f60, 0x080c, 0x9fd5, 0x0088, 0x2f60, 0x080c, 0x54e4,
- 0x0138, 0xd18c, 0x1118, 0x04f1, 0x0148, 0x0010, 0x2900, 0x7816,
- 0x001e, 0x0016, 0x080c, 0xa053, 0x9085, 0x0001, 0x001e, 0x004e,
- 0x00ce, 0x00fe, 0x0005, 0x00f6, 0x00c6, 0x0046, 0x080c, 0x9f7f,
- 0x2c78, 0x0508, 0x7e56, 0x2b00, 0x7812, 0x7823, 0x0003, 0x0096,
- 0x2021, 0x0004, 0x0489, 0x009e, 0x2001, 0x1958, 0x200c, 0xd1fc,
- 0x0120, 0x2f60, 0x080c, 0x9fd5, 0x0060, 0x2f60, 0x080c, 0x54e4,
- 0x0120, 0xd18c, 0x1160, 0x0071, 0x0130, 0x2009, 0x0052, 0x080c,
- 0xa053, 0x9085, 0x0001, 0x004e, 0x00ce, 0x00fe, 0x0005, 0x2900,
- 0x7816, 0x0c98, 0x00c6, 0x080c, 0x49b8, 0x00ce, 0x1120, 0x080c,
- 0x9fd5, 0x9006, 0x0005, 0xa867, 0x0000, 0xa86b, 0x8000, 0x2900,
- 0x6016, 0x9085, 0x0001, 0x0005, 0x0096, 0x0076, 0x0126, 0x2091,
- 0x8000, 0x080c, 0x64d8, 0x0158, 0x2001, 0xbe81, 0x0006, 0x900e,
- 0x2400, 0x080c, 0x6c6c, 0x080c, 0x6a23, 0x000e, 0x0807, 0x2418,
- 0x080c, 0x8a1e, 0xbaa0, 0x0086, 0x2041, 0x0001, 0x2039, 0x0001,
- 0x2608, 0x080c, 0x879b, 0x008e, 0x080c, 0x8671, 0x2f08, 0x2648,
- 0x080c, 0xd53b, 0xb93c, 0x81ff, 0x090c, 0x886e, 0x080c, 0x8b90,
- 0x012e, 0x007e, 0x009e, 0x0005, 0x00c6, 0x0126, 0x2091, 0x8000,
- 0x080c, 0x9f7f, 0x0190, 0x660a, 0x2b08, 0x6112, 0x080c, 0xc1b7,
- 0x6023, 0x0001, 0x2900, 0x6016, 0x2009, 0x001f, 0x080c, 0xa053,
+ 0xb332, 0x080c, 0x1037, 0x090c, 0x0df6, 0x2900, 0xb07a, 0xb77c,
+ 0xc7cd, 0xb77e, 0xa867, 0x0103, 0xb068, 0xa86a, 0xb06c, 0xa86e,
+ 0xb070, 0xa872, 0xae76, 0x968c, 0x0c00, 0x0120, 0x7348, 0xab92,
+ 0x734c, 0xab8e, 0x968c, 0x00ff, 0x9186, 0x0002, 0x0180, 0x9186,
+ 0x0028, 0x1118, 0xa87b, 0x001c, 0x0060, 0xd6dc, 0x0118, 0xa87b,
+ 0x0015, 0x0038, 0xd6d4, 0x0118, 0xa87b, 0x0007, 0x0010, 0xa87b,
+ 0x0000, 0xaf7e, 0xb080, 0xa882, 0xb084, 0xa886, 0x901e, 0xd6c4,
+ 0x0190, 0x735c, 0xab86, 0x83ff, 0x0170, 0x938a, 0x0009, 0x0210,
+ 0x2019, 0x0008, 0x0036, 0x2308, 0x2019, 0x0018, 0x2011, 0x0025,
+ 0x080c, 0xb915, 0x003e, 0xd6cc, 0x01e8, 0x7154, 0xa98a, 0x81ff,
+ 0x01c8, 0x9192, 0x0021, 0x1260, 0x8304, 0x9098, 0x0018, 0x2011,
+ 0x0029, 0x080c, 0xb915, 0x2011, 0x0205, 0x2013, 0x0000, 0x0050,
+ 0xb068, 0xd0fc, 0x0120, 0x2009, 0x0020, 0xa98a, 0x0c68, 0x2950,
+ 0x080c, 0xb8b4, 0x009e, 0x00ee, 0x00ae, 0x007e, 0x0005, 0x00f6,
+ 0x00a6, 0x6003, 0x0003, 0x2079, 0x026c, 0x7c04, 0x7b00, 0x7e0c,
+ 0x7d08, 0x6014, 0x2050, 0xb436, 0xb33a, 0xb646, 0xb54a, 0x00ae,
+ 0x00fe, 0x2c10, 0x080c, 0x1a7e, 0x0804, 0x95e7, 0x6003, 0x0002,
+ 0x6004, 0x9086, 0x0040, 0x11c8, 0x0096, 0x6014, 0x2048, 0xa87c,
+ 0xd0ac, 0x0160, 0x601c, 0xd084, 0x1130, 0x00f6, 0x2c00, 0x2078,
+ 0x080c, 0x1651, 0x00fe, 0x6003, 0x0004, 0x0010, 0x6003, 0x0002,
+ 0x009e, 0x080c, 0x8a83, 0x080c, 0x8b8f, 0x0096, 0x2001, 0x1962,
+ 0x2004, 0x6042, 0x080c, 0x8b3f, 0x080c, 0x8c6c, 0x6114, 0x2148,
+ 0xa97c, 0xd1e4, 0x0904, 0xb3d9, 0xd1cc, 0x05c8, 0xa978, 0xa868,
+ 0xd0fc, 0x0540, 0x0016, 0xa87c, 0x0006, 0xa880, 0x0006, 0xa860,
+ 0x20e8, 0xa85c, 0x9080, 0x0019, 0x20a0, 0x810e, 0x810e, 0x810f,
+ 0x9184, 0x003f, 0x20e0, 0x9184, 0xffc0, 0x9080, 0x0019, 0x2098,
+ 0x0156, 0x20a9, 0x0020, 0x4003, 0x015e, 0x000e, 0xa882, 0x000e,
+ 0xc0cc, 0xa87e, 0x001e, 0xa874, 0x0006, 0x2148, 0x080c, 0x0fe9,
+ 0x001e, 0x0458, 0x0016, 0x080c, 0x0fe9, 0x009e, 0xa87c, 0xc0cc,
+ 0xa87e, 0xa974, 0x0016, 0x080c, 0xb905, 0x001e, 0x00f0, 0xa867,
+ 0x0103, 0xa974, 0x9184, 0x00ff, 0x90b6, 0x0002, 0x0180, 0x9086,
+ 0x0028, 0x1118, 0xa87b, 0x001c, 0x0060, 0xd1dc, 0x0118, 0xa87b,
+ 0x0015, 0x0038, 0xd1d4, 0x0118, 0xa87b, 0x0007, 0x0010, 0xa87b,
+ 0x0000, 0x0016, 0x080c, 0x683c, 0x001e, 0xd1e4, 0x1120, 0x080c,
+ 0x9fea, 0x009e, 0x0005, 0x080c, 0xc04e, 0x0cd8, 0x6004, 0x9086,
+ 0x0040, 0x1120, 0x080c, 0x8a83, 0x080c, 0x8b8f, 0x2019, 0x0001,
+ 0x080c, 0x98b1, 0x6003, 0x0002, 0x080c, 0xc476, 0x080c, 0x8b3f,
+ 0x080c, 0x8c6c, 0x0005, 0x6004, 0x9086, 0x0040, 0x1120, 0x080c,
+ 0x8a83, 0x080c, 0x8b8f, 0x2019, 0x0001, 0x080c, 0x98b1, 0x080c,
+ 0x8b3f, 0x080c, 0x3095, 0x080c, 0xc46e, 0x0096, 0x6114, 0x2148,
+ 0x080c, 0xbd4e, 0x0150, 0xa867, 0x0103, 0xa87b, 0x0029, 0xa877,
+ 0x0000, 0x080c, 0x6a22, 0x080c, 0xbf39, 0x009e, 0x080c, 0x9fea,
+ 0x080c, 0x8c6c, 0x0005, 0xa87b, 0x0015, 0xd1fc, 0x0180, 0xa87b,
+ 0x0007, 0x8002, 0x8000, 0x810a, 0x9189, 0x0000, 0x0006, 0x0016,
+ 0x2009, 0x1a55, 0x2104, 0x8000, 0x200a, 0x001e, 0x000e, 0xa992,
+ 0xa88e, 0x0005, 0x9182, 0x0054, 0x1220, 0x9182, 0x0040, 0x0208,
+ 0x000a, 0x0005, 0xb44e, 0xb44e, 0xb44e, 0xb44e, 0xb44e, 0xb450,
+ 0xb44e, 0xb44e, 0xb4f6, 0xb44e, 0xb44e, 0xb44e, 0xb44e, 0xb44e,
+ 0xb44e, 0xb44e, 0xb44e, 0xb44e, 0xb44e, 0xb628, 0x080c, 0x0df6,
+ 0x0076, 0x00a6, 0x00e6, 0x0096, 0x2071, 0x0260, 0x6114, 0x2150,
+ 0x7644, 0xb676, 0x96b4, 0x0fff, 0xb77c, 0xc7e5, 0xb77e, 0x6210,
+ 0x00b6, 0x2258, 0xba3c, 0x82ff, 0x0110, 0x8211, 0xba3e, 0x00be,
+ 0x86ff, 0x0904, 0xb4ef, 0x9694, 0xff00, 0x9284, 0x0c00, 0x0120,
+ 0x7048, 0xb092, 0x704c, 0xb08e, 0x9284, 0x0300, 0x0904, 0xb4ef,
+ 0x9686, 0x0100, 0x1130, 0x7064, 0x9005, 0x1118, 0xc6c4, 0xb676,
+ 0x0c38, 0x080c, 0x1037, 0x090c, 0x0df6, 0x2900, 0xb07a, 0xb77c,
+ 0x97bd, 0x0200, 0xb77e, 0xa867, 0x0103, 0xb068, 0xa86a, 0xb06c,
+ 0xa86e, 0xb070, 0xa872, 0x7044, 0x9084, 0xf000, 0x9635, 0xae76,
+ 0x968c, 0x0c00, 0x0120, 0x7348, 0xab92, 0x734c, 0xab8e, 0x968c,
+ 0x00ff, 0x9186, 0x0002, 0x0180, 0x9186, 0x0028, 0x1118, 0xa87b,
+ 0x001c, 0x0060, 0xd6dc, 0x0118, 0xa87b, 0x0015, 0x0038, 0xd6d4,
+ 0x0118, 0xa87b, 0x0007, 0x0010, 0xa87b, 0x0000, 0xaf7e, 0xb080,
+ 0xa882, 0xb084, 0xa886, 0x901e, 0xd6c4, 0x0190, 0x735c, 0xab86,
+ 0x83ff, 0x0170, 0x938a, 0x0009, 0x0210, 0x2019, 0x0008, 0x0036,
+ 0x2308, 0x2019, 0x0018, 0x2011, 0x0025, 0x080c, 0xb915, 0x003e,
+ 0xd6cc, 0x01e8, 0x7154, 0xa98a, 0x81ff, 0x01c8, 0x9192, 0x0021,
+ 0x1260, 0x8304, 0x9098, 0x0018, 0x2011, 0x0029, 0x080c, 0xb915,
+ 0x2011, 0x0205, 0x2013, 0x0000, 0x0050, 0xb068, 0xd0fc, 0x0120,
+ 0x2009, 0x0020, 0xa98a, 0x0c68, 0x2950, 0x080c, 0xb8b4, 0x080c,
+ 0x18f8, 0x009e, 0x00ee, 0x00ae, 0x007e, 0x0005, 0x2001, 0x1962,
+ 0x2004, 0x6042, 0x0096, 0x6114, 0x2148, 0xa83c, 0xa940, 0x9105,
+ 0x1118, 0xa87c, 0xc0dc, 0xa87e, 0x6003, 0x0002, 0xa97c, 0xd1e4,
+ 0x0904, 0xb623, 0x6043, 0x0000, 0x6010, 0x00b6, 0x2058, 0xb800,
+ 0x00be, 0xd0bc, 0x1500, 0xd1cc, 0x0904, 0xb5f2, 0xa978, 0xa868,
+ 0xd0fc, 0x0904, 0xb5b3, 0x0016, 0xa87c, 0x0006, 0xa880, 0x0006,
+ 0x00a6, 0x2150, 0xb174, 0x9184, 0x00ff, 0x90b6, 0x0002, 0x0904,
+ 0xb580, 0x9086, 0x0028, 0x1904, 0xb56c, 0xa87b, 0x001c, 0xb07b,
+ 0x001c, 0x0804, 0xb588, 0x6024, 0xd0f4, 0x11d0, 0xa838, 0xaa34,
+ 0x9205, 0x09c8, 0xa838, 0xaa90, 0x9206, 0x1120, 0xa88c, 0xaa34,
+ 0x9206, 0x0988, 0x6024, 0xd0d4, 0x1148, 0xa9ac, 0xa834, 0x9102,
+ 0x603a, 0xa9b0, 0xa838, 0x9103, 0x603e, 0x6024, 0xc0f5, 0x6026,
+ 0x6010, 0x00b6, 0x2058, 0xb83c, 0x8000, 0xb83e, 0x00be, 0x9006,
+ 0xa876, 0xa892, 0xa88e, 0xa87c, 0xc0e4, 0xa87e, 0xd0cc, 0x0140,
+ 0xc0cc, 0xa87e, 0x0096, 0xa878, 0x2048, 0x080c, 0x0fe9, 0x009e,
+ 0x080c, 0xc088, 0x0804, 0xb623, 0xd1dc, 0x0158, 0xa87b, 0x0015,
+ 0xb07b, 0x0015, 0x080c, 0xc31c, 0x0118, 0xb174, 0xc1dc, 0xb176,
+ 0x0078, 0xd1d4, 0x0128, 0xa87b, 0x0007, 0xb07b, 0x0007, 0x0040,
+ 0xa87c, 0xd0ac, 0x0128, 0xa834, 0xa938, 0x9115, 0x190c, 0xb41b,
+ 0xa87c, 0xb07e, 0xa890, 0xb092, 0xa88c, 0xb08e, 0xa860, 0x20e8,
+ 0xa85c, 0x9080, 0x0019, 0x20a0, 0x20a9, 0x0020, 0x8a06, 0x8006,
+ 0x8007, 0x9094, 0x003f, 0x22e0, 0x9084, 0xffc0, 0x9080, 0x0019,
+ 0x2098, 0x4003, 0x00ae, 0x000e, 0xa882, 0x000e, 0xc0cc, 0xa87e,
+ 0x080c, 0xc3fc, 0x001e, 0xa874, 0x0006, 0x2148, 0x080c, 0x0fe9,
+ 0x001e, 0x0804, 0xb61f, 0x0016, 0x00a6, 0x2150, 0xb174, 0x9184,
+ 0x00ff, 0x90b6, 0x0002, 0x01e0, 0x9086, 0x0028, 0x1128, 0xa87b,
+ 0x001c, 0xb07b, 0x001c, 0x00e0, 0xd1dc, 0x0158, 0xa87b, 0x0015,
+ 0xb07b, 0x0015, 0x080c, 0xc31c, 0x0118, 0xb174, 0xc1dc, 0xb176,
+ 0x0078, 0xd1d4, 0x0128, 0xa87b, 0x0007, 0xb07b, 0x0007, 0x0040,
+ 0xa87c, 0xd0ac, 0x0128, 0xa834, 0xa938, 0x9115, 0x190c, 0xb41b,
+ 0xa890, 0xb092, 0xa88c, 0xb08e, 0xa87c, 0xb07e, 0x00ae, 0x080c,
+ 0x0fe9, 0x009e, 0x080c, 0xc3fc, 0xa974, 0x0016, 0x080c, 0xb905,
+ 0x001e, 0x0468, 0xa867, 0x0103, 0xa974, 0x9184, 0x00ff, 0x90b6,
+ 0x0002, 0x01b0, 0x9086, 0x0028, 0x1118, 0xa87b, 0x001c, 0x00d0,
+ 0xd1dc, 0x0148, 0xa87b, 0x0015, 0x080c, 0xc31c, 0x0118, 0xa974,
+ 0xc1dc, 0xa976, 0x0078, 0xd1d4, 0x0118, 0xa87b, 0x0007, 0x0050,
+ 0xa87b, 0x0000, 0xa87c, 0xd0ac, 0x0128, 0xa834, 0xa938, 0x9115,
+ 0x190c, 0xb41b, 0xa974, 0x0016, 0x080c, 0x683c, 0x001e, 0xd1e4,
+ 0x1120, 0x080c, 0x9fea, 0x009e, 0x0005, 0x080c, 0xc04e, 0x0cd8,
+ 0x6114, 0x0096, 0x2148, 0xa97c, 0xd1e4, 0x190c, 0x1918, 0x009e,
+ 0x0005, 0x080c, 0x8a83, 0x0010, 0x080c, 0x8b3f, 0x080c, 0xbd4e,
+ 0x01f0, 0x0096, 0x6114, 0x2148, 0x080c, 0xbf56, 0x1118, 0x080c,
+ 0xa9a7, 0x00a0, 0xa867, 0x0103, 0x2009, 0x180c, 0x210c, 0xd18c,
+ 0x11b8, 0xd184, 0x1190, 0x6108, 0xa97a, 0x918e, 0x0029, 0x1110,
+ 0x080c, 0xdae1, 0xa877, 0x0000, 0x080c, 0x6a22, 0x009e, 0x080c,
+ 0x9fea, 0x080c, 0x8b8f, 0x0804, 0x8c6c, 0xa87b, 0x0004, 0x0c90,
+ 0xa87b, 0x0004, 0x0c78, 0x9182, 0x0054, 0x1220, 0x9182, 0x0040,
+ 0x0208, 0x000a, 0x0005, 0xb67f, 0xb67f, 0xb67f, 0xb67f, 0xb67f,
+ 0xb681, 0xb67f, 0xb67f, 0xb67f, 0xb67f, 0xb67f, 0xb67f, 0xb67f,
+ 0xb67f, 0xb67f, 0xb67f, 0xb67f, 0xb67f, 0xb67f, 0xb67f, 0x080c,
+ 0x0df6, 0x080c, 0x54e3, 0x01f8, 0x6014, 0x7144, 0x918c, 0x0fff,
+ 0x9016, 0xd1c4, 0x0118, 0x7264, 0x9294, 0x00ff, 0x0096, 0x904d,
+ 0x0188, 0xa87b, 0x0000, 0xa864, 0x9086, 0x0139, 0x0128, 0xa867,
+ 0x0103, 0xa976, 0xaa96, 0x0030, 0xa897, 0x4000, 0xa99a, 0xaa9e,
+ 0x080c, 0x6a22, 0x009e, 0x0804, 0x9fea, 0x9182, 0x0085, 0x0002,
+ 0xb6b7, 0xb6b5, 0xb6b5, 0xb6c3, 0xb6b5, 0xb6b5, 0xb6b5, 0xb6b5,
+ 0xb6b5, 0xb6b5, 0xb6b5, 0xb6b5, 0xb6b5, 0x080c, 0x0df6, 0x6003,
+ 0x0001, 0x6106, 0x080c, 0x85f8, 0x0126, 0x2091, 0x8000, 0x080c,
+ 0x8b8f, 0x012e, 0x0005, 0x0026, 0x0056, 0x00d6, 0x00e6, 0x2071,
+ 0x0260, 0x7224, 0x6216, 0x7220, 0x080c, 0xbd3c, 0x01f8, 0x2268,
+ 0x6800, 0x9086, 0x0000, 0x01d0, 0x6010, 0x6d10, 0x952e, 0x11b0,
+ 0x00c6, 0x2d60, 0x00d6, 0x080c, 0xb976, 0x00de, 0x00ce, 0x0158,
+ 0x702c, 0xd084, 0x1118, 0x080c, 0xb940, 0x0010, 0x6803, 0x0002,
+ 0x6007, 0x0086, 0x0028, 0x080c, 0xb962, 0x0d90, 0x6007, 0x0087,
+ 0x6003, 0x0001, 0x080c, 0x85f8, 0x080c, 0x8b8f, 0x7220, 0x080c,
+ 0xbd3c, 0x0178, 0x6810, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc,
+ 0x0140, 0x6824, 0xd0ec, 0x0128, 0x00c6, 0x2d60, 0x080c, 0xc088,
+ 0x00ce, 0x00ee, 0x00de, 0x005e, 0x002e, 0x0005, 0x9186, 0x0013,
+ 0x1160, 0x6004, 0x908a, 0x0085, 0x0a0c, 0x0df6, 0x908a, 0x0092,
+ 0x1a0c, 0x0df6, 0x9082, 0x0085, 0x00e2, 0x9186, 0x0027, 0x0120,
+ 0x9186, 0x0014, 0x190c, 0x0df6, 0x080c, 0x8a83, 0x0096, 0x6014,
+ 0x2048, 0x080c, 0xbd4e, 0x0140, 0xa867, 0x0103, 0xa877, 0x0000,
+ 0xa87b, 0x0029, 0x080c, 0x6a22, 0x009e, 0x080c, 0xa01c, 0x0804,
+ 0x8b8f, 0xb746, 0xb748, 0xb748, 0xb746, 0xb746, 0xb746, 0xb746,
+ 0xb746, 0xb746, 0xb746, 0xb746, 0xb746, 0xb746, 0x080c, 0x0df6,
+ 0x080c, 0x8a83, 0x080c, 0xa01c, 0x080c, 0x8b8f, 0x0005, 0x9186,
+ 0x0013, 0x1128, 0x6004, 0x9082, 0x0085, 0x2008, 0x04b8, 0x9186,
+ 0x0027, 0x11f8, 0x080c, 0x8a83, 0x080c, 0x3095, 0x080c, 0xc46e,
+ 0x0096, 0x6014, 0x2048, 0x080c, 0xbd4e, 0x0150, 0xa867, 0x0103,
+ 0xa877, 0x0000, 0xa87b, 0x0029, 0x080c, 0x6a22, 0x080c, 0xbf39,
+ 0x009e, 0x080c, 0x9fea, 0x080c, 0x8b8f, 0x0005, 0x080c, 0xa083,
+ 0x0ce0, 0x9186, 0x0014, 0x1dd0, 0x080c, 0x8a83, 0x0096, 0x6014,
+ 0x2048, 0x080c, 0xbd4e, 0x0d60, 0xa867, 0x0103, 0xa877, 0x0000,
+ 0xa87b, 0x0006, 0xa880, 0xc0ec, 0xa882, 0x08f0, 0x0002, 0xb79e,
+ 0xb79c, 0xb79c, 0xb79c, 0xb79c, 0xb79c, 0xb7b6, 0xb79c, 0xb79c,
+ 0xb79c, 0xb79c, 0xb79c, 0xb79c, 0x080c, 0x0df6, 0x080c, 0x8a83,
+ 0x6034, 0x908c, 0xff00, 0x810f, 0x9186, 0x0039, 0x0118, 0x9186,
+ 0x0035, 0x1118, 0x2001, 0x1960, 0x0010, 0x2001, 0x1961, 0x2004,
+ 0x601a, 0x6003, 0x000c, 0x080c, 0x8b8f, 0x0005, 0x080c, 0x8a83,
+ 0x6034, 0x908c, 0xff00, 0x810f, 0x9186, 0x0039, 0x0118, 0x9186,
+ 0x0035, 0x1118, 0x2001, 0x1960, 0x0010, 0x2001, 0x1961, 0x2004,
+ 0x601a, 0x6003, 0x000e, 0x080c, 0x8b8f, 0x0005, 0x9182, 0x0092,
+ 0x1220, 0x9182, 0x0085, 0x0208, 0x0012, 0x0804, 0xa083, 0xb7e4,
+ 0xb7e4, 0xb7e4, 0xb7e4, 0xb7e6, 0xb833, 0xb7e4, 0xb7e4, 0xb7e4,
+ 0xb7e4, 0xb7e4, 0xb7e4, 0xb7e4, 0x080c, 0x0df6, 0x0096, 0x6010,
+ 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x0168, 0x6034, 0x908c,
+ 0xff00, 0x810f, 0x9186, 0x0039, 0x0118, 0x9186, 0x0035, 0x1118,
+ 0x009e, 0x0804, 0xb847, 0x080c, 0xbd4e, 0x1118, 0x080c, 0xbf39,
+ 0x0068, 0x6014, 0x2048, 0xa87c, 0xd0e4, 0x1110, 0x080c, 0xbf39,
+ 0xa867, 0x0103, 0x080c, 0xc439, 0x080c, 0x6a22, 0x00d6, 0x2c68,
+ 0x080c, 0x9f94, 0x01d0, 0x6003, 0x0001, 0x6007, 0x001e, 0x600b,
+ 0xffff, 0x2009, 0x026e, 0x210c, 0x613a, 0x2009, 0x026f, 0x210c,
+ 0x613e, 0x6910, 0x6112, 0x080c, 0xc1ca, 0x6954, 0x6156, 0x6023,
+ 0x0001, 0x080c, 0x85f8, 0x080c, 0x8b8f, 0x2d60, 0x00de, 0x080c,
+ 0x9fea, 0x009e, 0x0005, 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be,
+ 0xd0bc, 0x05a0, 0x6034, 0x908c, 0xff00, 0x810f, 0x9186, 0x0035,
+ 0x0130, 0x9186, 0x001e, 0x0118, 0x9186, 0x0039, 0x1538, 0x00d6,
+ 0x2c68, 0x080c, 0xc3cf, 0x11f0, 0x080c, 0x9f94, 0x01d8, 0x6106,
+ 0x6003, 0x0001, 0x6023, 0x0001, 0x6910, 0x6112, 0x692c, 0x612e,
+ 0x6930, 0x6132, 0x6934, 0x918c, 0x00ff, 0x6136, 0x6938, 0x613a,
+ 0x693c, 0x613e, 0x6954, 0x6156, 0x080c, 0xc1ca, 0x080c, 0x85f8,
+ 0x080c, 0x8b8f, 0x2d60, 0x00de, 0x0804, 0x9fea, 0x0096, 0x6014,
+ 0x2048, 0x080c, 0xbd4e, 0x01c8, 0xa867, 0x0103, 0xa880, 0xd0b4,
+ 0x0128, 0xc0ec, 0xa882, 0xa87b, 0x0006, 0x0048, 0xd0bc, 0x0118,
+ 0xa87b, 0x0002, 0x0020, 0xa87b, 0x0005, 0x080c, 0xc04a, 0xa877,
+ 0x0000, 0x080c, 0x6a22, 0x080c, 0xbf39, 0x009e, 0x0804, 0x9fea,
+ 0x0016, 0x0096, 0x6014, 0x2048, 0x080c, 0xbd4e, 0x0140, 0xa867,
+ 0x0103, 0xa87b, 0x0028, 0xa877, 0x0000, 0x080c, 0x6a22, 0x009e,
+ 0x001e, 0x9186, 0x0013, 0x0148, 0x9186, 0x0014, 0x0130, 0x9186,
+ 0x0027, 0x0118, 0x080c, 0xa083, 0x0030, 0x080c, 0x8a83, 0x080c,
+ 0xa01c, 0x080c, 0x8b8f, 0x0005, 0x0056, 0x0066, 0x0096, 0x00a6,
+ 0x2029, 0x0001, 0x9182, 0x0101, 0x1208, 0x0010, 0x2009, 0x0100,
+ 0x2130, 0x8304, 0x9098, 0x0018, 0x2009, 0x0020, 0x2011, 0x0029,
+ 0x080c, 0xb915, 0x96b2, 0x0020, 0xb004, 0x904d, 0x0110, 0x080c,
+ 0x0fe9, 0x080c, 0x1037, 0x0520, 0x8528, 0xa867, 0x0110, 0xa86b,
+ 0x0000, 0x2920, 0xb406, 0x968a, 0x003d, 0x1228, 0x2608, 0x2011,
+ 0x001b, 0x0499, 0x00a8, 0x96b2, 0x003c, 0x2009, 0x003c, 0x2950,
+ 0x2011, 0x001b, 0x0451, 0x0c28, 0x2001, 0x0205, 0x2003, 0x0000,
+ 0x00ae, 0x852f, 0x95ad, 0x0003, 0xb566, 0x95ac, 0x0000, 0x0048,
+ 0x2001, 0x0205, 0x2003, 0x0000, 0x00ae, 0x852f, 0x95ad, 0x0003,
+ 0xb566, 0x009e, 0x006e, 0x005e, 0x0005, 0x00a6, 0x89ff, 0x0158,
+ 0xa804, 0x9055, 0x0130, 0xa807, 0x0000, 0x080c, 0x6a22, 0x2a48,
+ 0x0cb8, 0x080c, 0x6a22, 0x00ae, 0x0005, 0x00f6, 0x2079, 0x0200,
+ 0x7814, 0x9085, 0x0080, 0x7816, 0xd184, 0x0108, 0x8108, 0x810c,
+ 0x20a9, 0x0001, 0xa860, 0x20e8, 0xa85c, 0x9200, 0x20a0, 0x20e1,
+ 0x0000, 0x2300, 0x9e00, 0x2098, 0x4003, 0x8318, 0x9386, 0x0020,
+ 0x1148, 0x2018, 0x2300, 0x9e00, 0x2098, 0x7814, 0x8000, 0x9085,
+ 0x0080, 0x7816, 0x8109, 0x1d80, 0x7817, 0x0000, 0x00fe, 0x0005,
+ 0x6920, 0x9186, 0x0003, 0x0118, 0x9186, 0x0002, 0x11d0, 0x00c6,
+ 0x00d6, 0x00e6, 0x2d60, 0x0096, 0x6014, 0x2048, 0x080c, 0xbd4e,
+ 0x0150, 0x2001, 0x0006, 0xa980, 0xc1d5, 0x080c, 0x6c6b, 0x080c,
+ 0x6a15, 0x080c, 0xbf39, 0x009e, 0x080c, 0xa01c, 0x00ee, 0x00de,
+ 0x00ce, 0x0005, 0x00c6, 0x702c, 0xd084, 0x1170, 0x6008, 0x2060,
+ 0x6020, 0x9086, 0x0002, 0x1140, 0x6104, 0x9186, 0x0085, 0x0118,
+ 0x9186, 0x008b, 0x1108, 0x9006, 0x00ce, 0x0005, 0x0066, 0x0126,
+ 0x2091, 0x8000, 0x2031, 0x0001, 0x6020, 0x9084, 0x000f, 0x0083,
+ 0x012e, 0x006e, 0x0005, 0x0126, 0x2091, 0x8000, 0x0066, 0x2031,
+ 0x0000, 0x6020, 0x9084, 0x000f, 0x001b, 0x006e, 0x012e, 0x0005,
+ 0xb9b1, 0xb9b1, 0xb9ac, 0xb9d3, 0xb99f, 0xb9ac, 0xb9d3, 0xb9ac,
+ 0xb9ac, 0xb99f, 0xb9ac, 0xb9ac, 0xb9ac, 0xb99f, 0xb99f, 0x080c,
+ 0x0df6, 0x0036, 0x2019, 0x0010, 0x080c, 0xd38f, 0x6023, 0x0006,
+ 0x6003, 0x0007, 0x003e, 0x0005, 0x9006, 0x0005, 0x9085, 0x0001,
+ 0x0005, 0x0096, 0x86ff, 0x11d8, 0x6014, 0x2048, 0x080c, 0xbd4e,
+ 0x01c0, 0xa864, 0x9086, 0x0139, 0x1128, 0xa87b, 0x0005, 0xa883,
+ 0x0000, 0x0028, 0x900e, 0x2001, 0x0005, 0x080c, 0x6c6b, 0x080c,
+ 0xc04a, 0x080c, 0x6a15, 0x080c, 0xa01c, 0x9085, 0x0001, 0x009e,
+ 0x0005, 0x9006, 0x0ce0, 0x6000, 0x908a, 0x0010, 0x1a0c, 0x0df6,
+ 0x0002, 0xb9e9, 0xba19, 0xb9eb, 0xba3a, 0xba14, 0xb9e9, 0xb9ac,
+ 0xb9b1, 0xb9b1, 0xb9ac, 0xb9ac, 0xb9ac, 0xb9ac, 0xb9ac, 0xb9ac,
+ 0xb9ac, 0x080c, 0x0df6, 0x86ff, 0x1520, 0x6020, 0x9086, 0x0006,
+ 0x0500, 0x0096, 0x6014, 0x2048, 0x080c, 0xbd4e, 0x0168, 0xa87c,
+ 0xd0cc, 0x0140, 0x0096, 0xc0cc, 0xa87e, 0xa878, 0x2048, 0x080c,
+ 0x0fe9, 0x009e, 0x080c, 0xc04a, 0x009e, 0x080c, 0xc413, 0x6007,
+ 0x0085, 0x6003, 0x000b, 0x6023, 0x0002, 0x080c, 0x85f8, 0x080c,
+ 0x8b8f, 0x9085, 0x0001, 0x0005, 0x0066, 0x080c, 0x192c, 0x006e,
+ 0x0890, 0x00e6, 0x2071, 0x19c2, 0x7024, 0x9c06, 0x1120, 0x080c,
+ 0x983b, 0x00ee, 0x0840, 0x6020, 0x9084, 0x000f, 0x9086, 0x0006,
+ 0x1150, 0x0086, 0x0096, 0x2049, 0x0001, 0x2c40, 0x080c, 0x995f,
+ 0x009e, 0x008e, 0x0010, 0x080c, 0x9738, 0x00ee, 0x1904, 0xb9eb,
+ 0x0804, 0xb9ac, 0x0036, 0x00e6, 0x2071, 0x19c2, 0x703c, 0x9c06,
+ 0x1138, 0x901e, 0x080c, 0x98b1, 0x00ee, 0x003e, 0x0804, 0xb9eb,
+ 0x080c, 0x9a8f, 0x00ee, 0x003e, 0x1904, 0xb9eb, 0x0804, 0xb9ac,
+ 0x00c6, 0x6020, 0x9084, 0x000f, 0x0013, 0x00ce, 0x0005, 0xba6d,
+ 0xbb1d, 0xbc87, 0xba77, 0xa01c, 0xba6d, 0xd381, 0xc47b, 0xbb1d,
+ 0xba66, 0xbd13, 0xba66, 0xba66, 0xba66, 0xba66, 0x080c, 0x0df6,
+ 0x080c, 0xbf56, 0x1110, 0x080c, 0xa9a7, 0x0005, 0x080c, 0x8a83,
+ 0x080c, 0x8b8f, 0x0804, 0x9fea, 0x601b, 0x0001, 0x0005, 0x080c,
+ 0xbd4e, 0x0130, 0x6014, 0x0096, 0x2048, 0x2c00, 0xa896, 0x009e,
+ 0x6000, 0x908a, 0x0010, 0x1a0c, 0x0df6, 0x0002, 0xba96, 0xba98,
+ 0xbabc, 0xbad0, 0xbaf6, 0xba96, 0xba6d, 0xba6d, 0xba6d, 0xbad0,
+ 0xbad0, 0xba96, 0xba96, 0xba96, 0xba96, 0xbada, 0x080c, 0x0df6,
+ 0x00e6, 0x6014, 0x0096, 0x2048, 0xa880, 0xc0b5, 0xa882, 0x009e,
+ 0x2071, 0x19c2, 0x7024, 0x9c06, 0x01a0, 0x080c, 0x9738, 0x080c,
+ 0xc413, 0x6007, 0x0085, 0x6003, 0x000b, 0x6023, 0x0002, 0x2001,
+ 0x1961, 0x2004, 0x601a, 0x080c, 0x85f8, 0x080c, 0x8b8f, 0x00ee,
+ 0x0005, 0x601b, 0x0001, 0x0cd8, 0x0096, 0x6014, 0x2048, 0xa880,
+ 0xc0b5, 0xa882, 0x009e, 0x080c, 0xc413, 0x6007, 0x0085, 0x6003,
+ 0x000b, 0x6023, 0x0002, 0x080c, 0x85f8, 0x080c, 0x8b8f, 0x0005,
+ 0x0096, 0x601b, 0x0001, 0x6014, 0x2048, 0xa880, 0xc0b5, 0xa882,
+ 0x009e, 0x0005, 0x080c, 0x54e3, 0x01b8, 0x6014, 0x0096, 0x904d,
+ 0x0190, 0xa864, 0xa867, 0x0103, 0xa87b, 0x0006, 0x9086, 0x0139,
+ 0x1150, 0xa867, 0x0139, 0xa87b, 0x0030, 0xa897, 0x4005, 0xa89b,
+ 0x0004, 0x080c, 0x6a22, 0x009e, 0x0804, 0x9fea, 0x6014, 0x0096,
+ 0x904d, 0x01f0, 0xa97c, 0xd1e4, 0x01d8, 0x2001, 0x180f, 0x2004,
+ 0xd0c4, 0x0110, 0x009e, 0x0005, 0xa884, 0x009e, 0x8003, 0x800b,
+ 0x810b, 0x9108, 0x611a, 0x00c6, 0x080c, 0x2165, 0x00ce, 0x6000,
+ 0x9086, 0x0004, 0x1120, 0x2009, 0x0048, 0x080c, 0xa068, 0x0005,
+ 0x009e, 0x080c, 0x192c, 0x0804, 0xbabc, 0x6000, 0x908a, 0x0010,
+ 0x1a0c, 0x0df6, 0x000b, 0x0005, 0xbb34, 0xba74, 0xbb36, 0xbb34,
+ 0xbb36, 0xbb36, 0xba6e, 0xbb34, 0xba68, 0xba68, 0xbb34, 0xbb34,
+ 0xbb34, 0xbb34, 0xbb34, 0xbb34, 0x080c, 0x0df6, 0x6010, 0x00b6,
+ 0x2058, 0xb804, 0x9084, 0x00ff, 0x00be, 0x908a, 0x000c, 0x1a0c,
+ 0x0df6, 0x00b6, 0x0013, 0x00be, 0x0005, 0xbb51, 0xbc1e, 0xbb53,
+ 0xbb93, 0xbb53, 0xbb93, 0xbb53, 0xbb61, 0xbb51, 0xbb93, 0xbb51,
+ 0xbb82, 0x080c, 0x0df6, 0x6004, 0x908e, 0x0016, 0x05c0, 0x908e,
+ 0x0004, 0x05a8, 0x908e, 0x0002, 0x0590, 0x908e, 0x0052, 0x0904,
+ 0xbc1a, 0x6004, 0x080c, 0xbf56, 0x0904, 0xbc37, 0x908e, 0x0004,
+ 0x1110, 0x080c, 0x30be, 0x908e, 0x0021, 0x0904, 0xbc3b, 0x908e,
+ 0x0022, 0x0904, 0xbc82, 0x908e, 0x003d, 0x0904, 0xbc3b, 0x908e,
+ 0x0039, 0x0904, 0xbc3f, 0x908e, 0x0035, 0x0904, 0xbc3f, 0x908e,
+ 0x001e, 0x0178, 0x908e, 0x0001, 0x1140, 0x6010, 0x2058, 0xb804,
+ 0x9084, 0x00ff, 0x9086, 0x0006, 0x0110, 0x080c, 0x3095, 0x080c,
+ 0xa9a7, 0x0804, 0xa01c, 0x00c6, 0x00d6, 0x6104, 0x9186, 0x0016,
+ 0x0904, 0xbc0b, 0x9186, 0x0002, 0x1904, 0xbbe0, 0x2001, 0x1836,
+ 0x2004, 0xd08c, 0x11c8, 0x080c, 0x717e, 0x11b0, 0x080c, 0xc459,
+ 0x0138, 0x080c, 0x71a1, 0x1120, 0x080c, 0x707c, 0x0804, 0xbc6b,
+ 0x2001, 0x1957, 0x2003, 0x0001, 0x2001, 0x1800, 0x2003, 0x0001,
+ 0x080c, 0x709e, 0x0804, 0xbc6b, 0x6010, 0x2058, 0x2001, 0x1836,
+ 0x2004, 0xd0ac, 0x1904, 0xbc6b, 0xb8a0, 0x9084, 0xff80, 0x1904,
+ 0xbc6b, 0xb840, 0x9084, 0x00ff, 0x9005, 0x0190, 0x8001, 0xb842,
+ 0x6017, 0x0000, 0x6023, 0x0007, 0x601b, 0x0398, 0x6043, 0x0000,
+ 0x080c, 0x9f94, 0x0128, 0x2b00, 0x6012, 0x6023, 0x0001, 0x0458,
+ 0x00de, 0x00ce, 0x6004, 0x908e, 0x0002, 0x11a0, 0x6010, 0x2058,
+ 0xb8a0, 0x9086, 0x007e, 0x1170, 0x2009, 0x1836, 0x2104, 0xc085,
+ 0x200a, 0x00e6, 0x2071, 0x1800, 0x080c, 0x5dc2, 0x00ee, 0x080c,
+ 0xa9a7, 0x0030, 0x080c, 0xa9a7, 0x080c, 0x3095, 0x080c, 0xc46e,
+ 0x00e6, 0x0126, 0x2091, 0x8000, 0x080c, 0x30be, 0x012e, 0x00ee,
+ 0x080c, 0xa01c, 0x0005, 0x2001, 0x0002, 0x080c, 0x62f4, 0x6003,
+ 0x0001, 0x6007, 0x0002, 0x080c, 0x8640, 0x080c, 0x8b8f, 0x00de,
+ 0x00ce, 0x0c80, 0x080c, 0x30be, 0x0804, 0xbb8f, 0x00c6, 0x00d6,
+ 0x6104, 0x9186, 0x0016, 0x0d38, 0x6010, 0x2058, 0xb840, 0x9084,
+ 0x00ff, 0x9005, 0x0904, 0xbbe0, 0x8001, 0xb842, 0x6003, 0x0001,
+ 0x080c, 0x8640, 0x080c, 0x8b8f, 0x00de, 0x00ce, 0x0898, 0x080c,
+ 0xa9a7, 0x0804, 0xbb91, 0x080c, 0xa9e3, 0x0804, 0xbb91, 0x00d6,
+ 0x2c68, 0x6104, 0x080c, 0xc3cf, 0x00de, 0x0118, 0x080c, 0x9fea,
+ 0x0408, 0x6004, 0x8007, 0x6134, 0x918c, 0x00ff, 0x9105, 0x6036,
+ 0x6007, 0x0085, 0x6003, 0x000b, 0x6023, 0x0002, 0x603c, 0x600a,
+ 0x2001, 0x1961, 0x2004, 0x601a, 0x602c, 0x2c08, 0x2060, 0x6024,
+ 0xd0b4, 0x0108, 0xc085, 0xc0b5, 0x6026, 0x2160, 0x080c, 0x85f8,
+ 0x080c, 0x8b8f, 0x0005, 0x00de, 0x00ce, 0x080c, 0xa9a7, 0x080c,
+ 0x3095, 0x00e6, 0x0126, 0x2091, 0x8000, 0x080c, 0x30be, 0x6017,
+ 0x0000, 0x6023, 0x0007, 0x601b, 0x0398, 0x6043, 0x0000, 0x012e,
+ 0x00ee, 0x0005, 0x080c, 0xa41e, 0x1904, 0xbc37, 0x0005, 0x6000,
+ 0x908a, 0x0010, 0x1a0c, 0x0df6, 0x0096, 0x00d6, 0x001b, 0x00de,
+ 0x009e, 0x0005, 0xbca2, 0xbca2, 0xbca2, 0xbca2, 0xbca2, 0xbca2,
+ 0xbca2, 0xbca2, 0xbca2, 0xba6d, 0xbca2, 0xba74, 0xbca4, 0xba74,
+ 0xbcbe, 0xbca2, 0x080c, 0x0df6, 0x6004, 0x9086, 0x008b, 0x01b0,
+ 0x6034, 0x908c, 0xff00, 0x810f, 0x9186, 0x0035, 0x1130, 0x602c,
+ 0x9080, 0x0009, 0x200c, 0xc185, 0x2102, 0x6007, 0x008b, 0x6003,
+ 0x000d, 0x080c, 0x85f8, 0x080c, 0x8b8f, 0x0005, 0x080c, 0xc44d,
+ 0x0118, 0x080c, 0xc460, 0x0010, 0x080c, 0xc46e, 0x080c, 0xbf39,
+ 0x080c, 0xbd4e, 0x0570, 0x080c, 0x3095, 0x080c, 0xbd4e, 0x0168,
+ 0x6014, 0x2048, 0xa867, 0x0103, 0xa87b, 0x0006, 0xa877, 0x0000,
+ 0xa880, 0xc0ed, 0xa882, 0x080c, 0x6a22, 0x2c68, 0x080c, 0x9f94,
+ 0x0150, 0x6810, 0x6012, 0x080c, 0xc1ca, 0x00c6, 0x2d60, 0x080c,
+ 0xa01c, 0x00ce, 0x0008, 0x2d60, 0x6017, 0x0000, 0x6023, 0x0001,
+ 0x6007, 0x0001, 0x6003, 0x0001, 0x080c, 0x8640, 0x080c, 0x8b8f,
+ 0x00c8, 0x080c, 0xc44d, 0x0138, 0x6034, 0x9086, 0x4000, 0x1118,
+ 0x080c, 0x3095, 0x08d0, 0x6034, 0x908c, 0xff00, 0x810f, 0x9186,
+ 0x0039, 0x0118, 0x9186, 0x0035, 0x1118, 0x080c, 0x3095, 0x0868,
+ 0x080c, 0xa01c, 0x0005, 0x6000, 0x908a, 0x0010, 0x1a0c, 0x0df6,
+ 0x0002, 0xbd29, 0xbd29, 0xbd2d, 0xbd2b, 0xbd37, 0xbd29, 0xbd29,
+ 0xa01c, 0xbd29, 0xbd29, 0xbd29, 0xbd29, 0xbd29, 0xbd29, 0xbd29,
+ 0xbd29, 0x080c, 0x0df6, 0x080c, 0x9a8f, 0x6114, 0x0096, 0x2148,
+ 0xa87b, 0x0006, 0x080c, 0x6a22, 0x009e, 0x0804, 0x9fea, 0x601c,
+ 0xd084, 0x190c, 0x192c, 0x0c88, 0x9284, 0x0007, 0x1158, 0x9282,
+ 0x1cd0, 0x0240, 0x2001, 0x1819, 0x2004, 0x9202, 0x1218, 0x9085,
+ 0x0001, 0x0005, 0x9006, 0x0ce8, 0x0096, 0x0028, 0x0096, 0x0006,
+ 0x6014, 0x2048, 0x000e, 0x0006, 0x9984, 0xf000, 0x9086, 0xf000,
+ 0x0110, 0x080c, 0x10e2, 0x000e, 0x009e, 0x0005, 0x00e6, 0x00c6,
+ 0x0036, 0x0006, 0x0126, 0x2091, 0x8000, 0x2061, 0x1cd0, 0x2071,
+ 0x1800, 0x7350, 0x7070, 0x9302, 0x1640, 0x6020, 0x9206, 0x11f8,
+ 0x080c, 0xc459, 0x0180, 0x9286, 0x0001, 0x1168, 0x6004, 0x9086,
+ 0x0004, 0x1148, 0x080c, 0x3095, 0x080c, 0xc46e, 0x00c6, 0x080c,
+ 0xa01c, 0x00ce, 0x0060, 0x080c, 0xc144, 0x0148, 0x080c, 0xbf56,
+ 0x1110, 0x080c, 0xa9a7, 0x00c6, 0x080c, 0x9fea, 0x00ce, 0x9ce0,
+ 0x0018, 0x7064, 0x9c02, 0x1208, 0x08a0, 0x012e, 0x000e, 0x003e,
+ 0x00ce, 0x00ee, 0x0005, 0x00e6, 0x00c6, 0x0016, 0x9188, 0x1000,
+ 0x210c, 0x81ff, 0x0128, 0x2061, 0x1a88, 0x6112, 0x080c, 0x3095,
+ 0x9006, 0x0010, 0x9085, 0x0001, 0x001e, 0x00ce, 0x00ee, 0x0005,
+ 0x00c6, 0x0126, 0x2091, 0x8000, 0x080c, 0x9f94, 0x01b0, 0x6656,
+ 0x2b00, 0x6012, 0x080c, 0x54e3, 0x0118, 0x080c, 0xbe7d, 0x0168,
+ 0x080c, 0xc1ca, 0x6023, 0x0003, 0x2009, 0x004b, 0x080c, 0xa068,
+ 0x9085, 0x0001, 0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd8, 0x00c6,
+ 0x0126, 0x2091, 0x8000, 0xbaa0, 0x080c, 0xa03b, 0x0560, 0x6057,
+ 0x0000, 0x2b00, 0x6012, 0x080c, 0xc1ca, 0x6023, 0x0003, 0x0016,
+ 0x080c, 0x8782, 0x0076, 0x903e, 0x080c, 0x8670, 0x2c08, 0x080c,
+ 0xd556, 0x007e, 0x001e, 0xd184, 0x0128, 0x080c, 0x9fea, 0x9085,
+ 0x0001, 0x0070, 0x080c, 0x54e3, 0x0128, 0xd18c, 0x1170, 0x080c,
+ 0xbe7d, 0x0148, 0x2009, 0x004c, 0x080c, 0xa068, 0x9085, 0x0001,
+ 0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd8, 0x2900, 0x6016, 0x0c90,
+ 0x2009, 0x004d, 0x0010, 0x2009, 0x004e, 0x00f6, 0x00c6, 0x0046,
+ 0x0016, 0x080c, 0x9f94, 0x2c78, 0x05a0, 0x7e56, 0x2b00, 0x7812,
+ 0x7823, 0x0003, 0x0016, 0x2021, 0x0005, 0x080c, 0xbe8f, 0x001e,
+ 0x9186, 0x004d, 0x0118, 0x9186, 0x004e, 0x0148, 0x2001, 0x195a,
+ 0x200c, 0xd1fc, 0x0168, 0x2f60, 0x080c, 0x9fea, 0x00d0, 0x2001,
+ 0x1959, 0x200c, 0xd1fc, 0x0120, 0x2f60, 0x080c, 0x9fea, 0x0088,
+ 0x2f60, 0x080c, 0x54e3, 0x0138, 0xd18c, 0x1118, 0x04f1, 0x0148,
+ 0x0010, 0x2900, 0x7816, 0x001e, 0x0016, 0x080c, 0xa068, 0x9085,
+ 0x0001, 0x001e, 0x004e, 0x00ce, 0x00fe, 0x0005, 0x00f6, 0x00c6,
+ 0x0046, 0x080c, 0x9f94, 0x2c78, 0x0508, 0x7e56, 0x2b00, 0x7812,
+ 0x7823, 0x0003, 0x0096, 0x2021, 0x0004, 0x0489, 0x009e, 0x2001,
+ 0x1958, 0x200c, 0xd1fc, 0x0120, 0x2f60, 0x080c, 0x9fea, 0x0060,
+ 0x2f60, 0x080c, 0x54e3, 0x0120, 0xd18c, 0x1160, 0x0071, 0x0130,
+ 0x2009, 0x0052, 0x080c, 0xa068, 0x9085, 0x0001, 0x004e, 0x00ce,
+ 0x00fe, 0x0005, 0x2900, 0x7816, 0x0c98, 0x00c6, 0x080c, 0x49b7,
+ 0x00ce, 0x1120, 0x080c, 0x9fea, 0x9006, 0x0005, 0xa867, 0x0000,
+ 0xa86b, 0x8000, 0x2900, 0x6016, 0x9085, 0x0001, 0x0005, 0x0096,
+ 0x0076, 0x0126, 0x2091, 0x8000, 0x080c, 0x64d7, 0x0158, 0x2001,
+ 0xbe94, 0x0006, 0x900e, 0x2400, 0x080c, 0x6c6b, 0x080c, 0x6a22,
+ 0x000e, 0x0807, 0x2418, 0x080c, 0x8a1d, 0xbaa0, 0x0086, 0x2041,
+ 0x0001, 0x2039, 0x0001, 0x2608, 0x080c, 0x879a, 0x008e, 0x080c,
+ 0x8670, 0x2f08, 0x2648, 0x080c, 0xd556, 0xb93c, 0x81ff, 0x090c,
+ 0x886d, 0x080c, 0x8b8f, 0x012e, 0x007e, 0x009e, 0x0005, 0x00c6,
+ 0x0126, 0x2091, 0x8000, 0x080c, 0x9f94, 0x0190, 0x660a, 0x2b08,
+ 0x6112, 0x080c, 0xc1ca, 0x6023, 0x0001, 0x2900, 0x6016, 0x2009,
+ 0x001f, 0x080c, 0xa068, 0x9085, 0x0001, 0x012e, 0x00ce, 0x0005,
+ 0x9006, 0x0cd8, 0x00c6, 0x0126, 0x2091, 0x8000, 0x080c, 0xa03b,
+ 0x01b8, 0x660a, 0x2b08, 0x6112, 0x080c, 0xc1ca, 0x6023, 0x0008,
+ 0x2900, 0x6016, 0x00f6, 0x2c78, 0x080c, 0x1651, 0x00fe, 0x2009,
+ 0x0021, 0x080c, 0xa068, 0x9085, 0x0001, 0x012e, 0x00ce, 0x0005,
+ 0x9006, 0x0cd8, 0x2009, 0x003d, 0x00c6, 0x0126, 0x0016, 0x2091,
+ 0x8000, 0x080c, 0x9f94, 0x0198, 0x660a, 0x2b08, 0x6112, 0x080c,
+ 0xc1ca, 0x6023, 0x0001, 0x2900, 0x6016, 0x001e, 0x0016, 0x080c,
+ 0xa068, 0x9085, 0x0001, 0x001e, 0x012e, 0x00ce, 0x0005, 0x9006,
+ 0x0cd0, 0x00c6, 0x0126, 0x2091, 0x8000, 0x080c, 0xa03b, 0x0188,
+ 0x2b08, 0x6112, 0x080c, 0xc1ca, 0x6023, 0x0001, 0x2900, 0x6016,
+ 0x2009, 0x0000, 0x080c, 0xa068, 0x9085, 0x0001, 0x012e, 0x00ce,
+ 0x0005, 0x9006, 0x0cd8, 0x2009, 0x0044, 0x0830, 0x2009, 0x0049,
+ 0x0818, 0x0026, 0x00b6, 0x6210, 0x2258, 0xba3c, 0x82ff, 0x0110,
+ 0x8211, 0xba3e, 0x00be, 0x002e, 0x0005, 0x0006, 0x0016, 0x6004,
+ 0x908e, 0x0002, 0x0140, 0x908e, 0x0003, 0x0128, 0x908e, 0x0004,
+ 0x0110, 0x9085, 0x0001, 0x001e, 0x000e, 0x0005, 0x0006, 0x0086,
+ 0x0096, 0x6020, 0x9086, 0x0004, 0x01a8, 0x6014, 0x904d, 0x080c,
+ 0xbd4e, 0x0180, 0xa864, 0x9086, 0x0139, 0x0170, 0x6020, 0x90c6,
+ 0x0003, 0x0140, 0x90c6, 0x0002, 0x0128, 0xa868, 0xd0fc, 0x0110,
+ 0x9006, 0x0010, 0x9085, 0x0001, 0x009e, 0x008e, 0x000e, 0x0005,
+ 0x00c6, 0x0126, 0x2091, 0x8000, 0x080c, 0xa03b, 0x0198, 0x2b08,
+ 0x6112, 0x080c, 0xc1ca, 0x6023, 0x0001, 0x2900, 0x6016, 0x080c,
+ 0x3095, 0x2009, 0x0028, 0x080c, 0xa068, 0x9085, 0x0001, 0x012e,
+ 0x00ce, 0x0005, 0x9006, 0x0cd8, 0x9186, 0x0015, 0x11a8, 0x2011,
+ 0x1823, 0x2204, 0x9086, 0x0074, 0x1178, 0x00b6, 0x080c, 0xac41,
+ 0x00be, 0x080c, 0xae8d, 0x6003, 0x0001, 0x6007, 0x0029, 0x080c,
+ 0x8640, 0x080c, 0x8b8f, 0x0078, 0x6014, 0x0096, 0x2048, 0xa868,
+ 0x009e, 0xd0fc, 0x0148, 0x2001, 0x0001, 0x080c, 0xc390, 0x080c,
+ 0xa9a7, 0x080c, 0x9fea, 0x0005, 0x0096, 0x6014, 0x904d, 0x090c,
+ 0x0df6, 0xa87b, 0x0030, 0xa883, 0x0000, 0xa897, 0x4005, 0xa89b,
+ 0x0004, 0xa867, 0x0139, 0x0126, 0x2091, 0x8000, 0x080c, 0x6a22,
+ 0x012e, 0x009e, 0x080c, 0x9fea, 0x0c30, 0x0096, 0x9186, 0x0016,
+ 0x1128, 0x2001, 0x0004, 0x080c, 0x62f4, 0x00e8, 0x9186, 0x0015,
+ 0x1510, 0x2011, 0x1823, 0x2204, 0x9086, 0x0014, 0x11e0, 0x6010,
+ 0x00b6, 0x2058, 0x080c, 0x643e, 0x00be, 0x080c, 0xaf63, 0x1198,
+ 0x6010, 0x00b6, 0x2058, 0xb890, 0x00be, 0x9005, 0x0160, 0x2001,
+ 0x0006, 0x080c, 0x62f4, 0x6014, 0x2048, 0xa868, 0xd0fc, 0x0170,
+ 0x080c, 0xa3f2, 0x0048, 0x6014, 0x2048, 0xa868, 0xd0fc, 0x0528,
+ 0x080c, 0xa9a7, 0x080c, 0x9fea, 0x009e, 0x0005, 0x6014, 0x6310,
+ 0x2358, 0x904d, 0x090c, 0x0df6, 0xa87b, 0x0000, 0xa883, 0x0000,
+ 0xa897, 0x4000, 0x900e, 0x080c, 0x65c3, 0x1108, 0xc185, 0xb800,
+ 0xd0bc, 0x0108, 0xc18d, 0xa99a, 0x0126, 0x2091, 0x8000, 0x080c,
+ 0x6a22, 0x012e, 0x080c, 0x9fea, 0x08f8, 0x6014, 0x904d, 0x090c,
+ 0x0df6, 0xa87b, 0x0030, 0xa883, 0x0000, 0xa897, 0x4005, 0xa89b,
+ 0x0004, 0xa867, 0x0139, 0x0126, 0x2091, 0x8000, 0x080c, 0x6a22,
+ 0x012e, 0x080c, 0x9fea, 0x0840, 0xa878, 0x9086, 0x0005, 0x1108,
+ 0x0009, 0x0005, 0xa880, 0xc0ad, 0xa882, 0x0005, 0x6043, 0x0000,
+ 0x6017, 0x0000, 0x6003, 0x0001, 0x6007, 0x0050, 0x080c, 0x85f8,
+ 0x080c, 0x8b8f, 0x0005, 0x00c6, 0x6010, 0x00b6, 0x2058, 0xb800,
+ 0x00be, 0xd0bc, 0x0120, 0x6020, 0x9084, 0x000f, 0x0013, 0x00ce,
+ 0x0005, 0xba6d, 0xc07a, 0xc07a, 0xc07d, 0xd886, 0xd8a1, 0xd8a4,
+ 0xba6d, 0xba6d, 0xba6d, 0xba6d, 0xba6d, 0xba6d, 0xba6d, 0xba6d,
+ 0x080c, 0x0df6, 0xa001, 0xa001, 0x0005, 0x0096, 0x6014, 0x904d,
+ 0x0118, 0xa87c, 0xd0e4, 0x1110, 0x009e, 0x0010, 0x009e, 0x0005,
+ 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x0550, 0x2001,
+ 0x1833, 0x2004, 0x9005, 0x1540, 0x00f6, 0x2c78, 0x080c, 0x9f94,
+ 0x0508, 0x7810, 0x6012, 0x080c, 0xc1ca, 0x7820, 0x9086, 0x0003,
+ 0x0128, 0x7808, 0x603a, 0x2f00, 0x603e, 0x0020, 0x7808, 0x603e,
+ 0x2f00, 0x603a, 0x602e, 0x6023, 0x0001, 0x6007, 0x0035, 0x6003,
+ 0x0001, 0x7954, 0x6156, 0x080c, 0x85f8, 0x080c, 0x8b8f, 0x2f60,
+ 0x00fe, 0x0005, 0x2f60, 0x00fe, 0x2001, 0x1962, 0x2004, 0x6042,
+ 0x0005, 0x0016, 0x0096, 0x6814, 0x2048, 0xa87c, 0xd0e4, 0x0180,
+ 0xc0e4, 0xa87e, 0xa877, 0x0000, 0xa893, 0x0000, 0xa88f, 0x0000,
+ 0xd0cc, 0x0130, 0xc0cc, 0xa87e, 0xa878, 0x2048, 0x080c, 0x0fe9,
+ 0x6830, 0x6036, 0x908e, 0x0001, 0x0148, 0x6803, 0x0002, 0x9086,
+ 0x0005, 0x0170, 0x9006, 0x602e, 0x6032, 0x00d0, 0x681c, 0xc085,
+ 0x681e, 0x6803, 0x0004, 0x6824, 0xc0f4, 0x9085, 0x0c00, 0x6826,
+ 0x6814, 0x2048, 0xa8ac, 0x6938, 0x9102, 0xa8b0, 0x693c, 0x9103,
+ 0x1e48, 0x683c, 0x602e, 0x6838, 0x9084, 0xfffc, 0x683a, 0x6032,
+ 0x2d00, 0x603a, 0x6808, 0x603e, 0x6910, 0x6112, 0x6954, 0x6156,
+ 0x6023, 0x0001, 0x6007, 0x0039, 0x6003, 0x0001, 0x080c, 0x85f8,
+ 0x080c, 0x8b8f, 0x009e, 0x001e, 0x0005, 0x6024, 0xd0d4, 0x0510,
+ 0xd0f4, 0x11f8, 0x6038, 0x940a, 0x603c, 0x9303, 0x0230, 0x9105,
+ 0x0120, 0x6024, 0xc0d4, 0xc0f5, 0x0098, 0x643a, 0x633e, 0xac3e,
+ 0xab42, 0x0046, 0x0036, 0x2400, 0xacac, 0x9402, 0xa836, 0x2300,
+ 0xabb0, 0x9303, 0xa83a, 0x003e, 0x004e, 0x6024, 0xc0d4, 0x0000,
+ 0x6026, 0x0005, 0xd0f4, 0x1138, 0xa83c, 0x603a, 0xa840, 0x603e,
+ 0x6024, 0xc0f5, 0x6026, 0x0005, 0x0006, 0x0016, 0x6004, 0x908e,
+ 0x0034, 0x01b8, 0x908e, 0x0035, 0x01a0, 0x908e, 0x0036, 0x0188,
+ 0x908e, 0x0037, 0x0170, 0x908e, 0x0038, 0x0158, 0x908e, 0x0039,
+ 0x0140, 0x908e, 0x003a, 0x0128, 0x908e, 0x003b, 0x0110, 0x9085,
+ 0x0001, 0x001e, 0x000e, 0x0005, 0x0006, 0x0016, 0x0026, 0x0036,
+ 0x00e6, 0x2001, 0x195c, 0x200c, 0x8000, 0x2014, 0x2001, 0x0032,
+ 0x080c, 0x847e, 0x2001, 0x1960, 0x82ff, 0x1110, 0x2011, 0x0014,
+ 0x2202, 0x2001, 0x195e, 0x200c, 0x8000, 0x2014, 0x2071, 0x1946,
+ 0x711a, 0x721e, 0x2001, 0x0064, 0x080c, 0x847e, 0x2001, 0x1961,
+ 0x82ff, 0x1110, 0x2011, 0x0014, 0x2202, 0x2001, 0x1962, 0x9288,
+ 0x000a, 0x2102, 0x2001, 0x1a69, 0x2102, 0x2001, 0x0032, 0x080c,
+ 0x1580, 0x080c, 0x66aa, 0x00ee, 0x003e, 0x002e, 0x001e, 0x000e,
+ 0x0005, 0x0006, 0x0016, 0x00e6, 0x2001, 0x1960, 0x2003, 0x0028,
+ 0x2001, 0x1961, 0x2003, 0x0014, 0x2071, 0x1946, 0x701b, 0x0000,
+ 0x701f, 0x07d0, 0x2001, 0x1962, 0x2009, 0x001e, 0x2102, 0x2001,
+ 0x1a69, 0x2102, 0x2001, 0x0032, 0x080c, 0x1580, 0x00ee, 0x001e,
+ 0x000e, 0x0005, 0x0096, 0x6058, 0x904d, 0x0110, 0x080c, 0x1069,
+ 0x009e, 0x0005, 0x0005, 0x00c6, 0x0126, 0x2091, 0x8000, 0x080c,
+ 0x9f94, 0x0180, 0x2b08, 0x6112, 0x0ca9, 0x6023, 0x0001, 0x2900,
+ 0x6016, 0x2009, 0x0033, 0x080c, 0xa068, 0x9085, 0x0001, 0x012e,
+ 0x00ce, 0x0005, 0x9006, 0x0cd8, 0x0096, 0x00e6, 0x00f6, 0x2071,
+ 0x1800, 0x9186, 0x0015, 0x1520, 0x708c, 0x9086, 0x0018, 0x0120,
+ 0x708c, 0x9086, 0x0014, 0x11e0, 0x6014, 0x2048, 0xaa3c, 0xd2e4,
+ 0x1160, 0x2c78, 0x080c, 0x8d93, 0x01d8, 0x7078, 0xaa50, 0x9206,
+ 0x1160, 0x707c, 0xaa54, 0x9206, 0x1140, 0x6210, 0x00b6, 0x2258,
+ 0xbaa0, 0x00be, 0x900e, 0x080c, 0x30de, 0x080c, 0xa3f2, 0x0020,
+ 0x080c, 0xa9a7, 0x080c, 0x9fea, 0x00fe, 0x00ee, 0x009e, 0x0005,
+ 0x705c, 0xaa54, 0x9206, 0x0d48, 0x0c80, 0x00c6, 0x0126, 0x2091,
+ 0x8000, 0x080c, 0x9f94, 0x0188, 0x2b08, 0x6112, 0x080c, 0xc1ca,
+ 0x6023, 0x0001, 0x2900, 0x6016, 0x2009, 0x004d, 0x080c, 0xa068,
0x9085, 0x0001, 0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd8, 0x00c6,
- 0x0126, 0x2091, 0x8000, 0x080c, 0xa026, 0x01b8, 0x660a, 0x2b08,
- 0x6112, 0x080c, 0xc1b7, 0x6023, 0x0008, 0x2900, 0x6016, 0x00f6,
- 0x2c78, 0x080c, 0x165d, 0x00fe, 0x2009, 0x0021, 0x080c, 0xa053,
- 0x9085, 0x0001, 0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd8, 0x2009,
- 0x003d, 0x00c6, 0x0126, 0x0016, 0x2091, 0x8000, 0x080c, 0x9f7f,
- 0x0198, 0x660a, 0x2b08, 0x6112, 0x080c, 0xc1b7, 0x6023, 0x0001,
- 0x2900, 0x6016, 0x001e, 0x0016, 0x080c, 0xa053, 0x9085, 0x0001,
- 0x001e, 0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd0, 0x00c6, 0x0126,
- 0x2091, 0x8000, 0x080c, 0xa026, 0x0188, 0x2b08, 0x6112, 0x080c,
- 0xc1b7, 0x6023, 0x0001, 0x2900, 0x6016, 0x2009, 0x0000, 0x080c,
- 0xa053, 0x9085, 0x0001, 0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd8,
- 0x2009, 0x0044, 0x0830, 0x2009, 0x0049, 0x0818, 0x0026, 0x00b6,
- 0x6210, 0x2258, 0xba3c, 0x82ff, 0x0110, 0x8211, 0xba3e, 0x00be,
- 0x002e, 0x0005, 0x0006, 0x0016, 0x6004, 0x908e, 0x0002, 0x0140,
- 0x908e, 0x0003, 0x0128, 0x908e, 0x0004, 0x0110, 0x9085, 0x0001,
- 0x001e, 0x000e, 0x0005, 0x0006, 0x0086, 0x0096, 0x6020, 0x9086,
- 0x0004, 0x01a8, 0x6014, 0x904d, 0x080c, 0xbd3b, 0x0180, 0xa864,
- 0x9086, 0x0139, 0x0170, 0x6020, 0x90c6, 0x0003, 0x0140, 0x90c6,
- 0x0002, 0x0128, 0xa868, 0xd0fc, 0x0110, 0x9006, 0x0010, 0x9085,
- 0x0001, 0x009e, 0x008e, 0x000e, 0x0005, 0x00c6, 0x0126, 0x2091,
- 0x8000, 0x080c, 0xa026, 0x0198, 0x2b08, 0x6112, 0x080c, 0xc1b7,
- 0x6023, 0x0001, 0x2900, 0x6016, 0x080c, 0x30ab, 0x2009, 0x0028,
- 0x080c, 0xa053, 0x9085, 0x0001, 0x012e, 0x00ce, 0x0005, 0x9006,
- 0x0cd8, 0x9186, 0x0015, 0x11a8, 0x2011, 0x1823, 0x2204, 0x9086,
- 0x0074, 0x1178, 0x00b6, 0x080c, 0xac3a, 0x00be, 0x080c, 0xae86,
- 0x6003, 0x0001, 0x6007, 0x0029, 0x080c, 0x8641, 0x080c, 0x8b90,
- 0x0078, 0x6014, 0x0096, 0x2048, 0xa868, 0x009e, 0xd0fc, 0x0148,
- 0x2001, 0x0001, 0x080c, 0xc37d, 0x080c, 0xa995, 0x080c, 0x9fd5,
- 0x0005, 0x0096, 0x6014, 0x904d, 0x090c, 0x0e02, 0xa87b, 0x0030,
- 0xa883, 0x0000, 0xa897, 0x4005, 0xa89b, 0x0004, 0xa867, 0x0139,
- 0x0126, 0x2091, 0x8000, 0x080c, 0x6a23, 0x012e, 0x009e, 0x080c,
- 0x9fd5, 0x0c30, 0x0096, 0x9186, 0x0016, 0x1128, 0x2001, 0x0004,
- 0x080c, 0x62f5, 0x00e8, 0x9186, 0x0015, 0x1510, 0x2011, 0x1823,
- 0x2204, 0x9086, 0x0014, 0x11e0, 0x6010, 0x00b6, 0x2058, 0x080c,
- 0x643f, 0x00be, 0x080c, 0xaf57, 0x1198, 0x6010, 0x00b6, 0x2058,
- 0xb890, 0x00be, 0x9005, 0x0160, 0x2001, 0x0006, 0x080c, 0x62f5,
- 0x6014, 0x2048, 0xa868, 0xd0fc, 0x0170, 0x080c, 0xa3e0, 0x0048,
- 0x6014, 0x2048, 0xa868, 0xd0fc, 0x0528, 0x080c, 0xa995, 0x080c,
- 0x9fd5, 0x009e, 0x0005, 0x6014, 0x6310, 0x2358, 0x904d, 0x090c,
- 0x0e02, 0xa87b, 0x0000, 0xa883, 0x0000, 0xa897, 0x4000, 0x900e,
- 0x080c, 0x65c4, 0x1108, 0xc185, 0xb800, 0xd0bc, 0x0108, 0xc18d,
- 0xa99a, 0x0126, 0x2091, 0x8000, 0x080c, 0x6a23, 0x012e, 0x080c,
- 0x9fd5, 0x08f8, 0x6014, 0x904d, 0x090c, 0x0e02, 0xa87b, 0x0030,
- 0xa883, 0x0000, 0xa897, 0x4005, 0xa89b, 0x0004, 0xa867, 0x0139,
- 0x0126, 0x2091, 0x8000, 0x080c, 0x6a23, 0x012e, 0x080c, 0x9fd5,
- 0x0840, 0xa878, 0x9086, 0x0005, 0x1108, 0x0009, 0x0005, 0xa880,
- 0xc0ad, 0xa882, 0x0005, 0x6043, 0x0000, 0x6017, 0x0000, 0x6003,
- 0x0001, 0x6007, 0x0050, 0x080c, 0x85f9, 0x080c, 0x8b90, 0x0005,
- 0x00c6, 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x0120,
- 0x6020, 0x9084, 0x000f, 0x0013, 0x00ce, 0x0005, 0xba5e, 0xc067,
- 0xc067, 0xc06a, 0xd825, 0xd840, 0xd843, 0xba5e, 0xba5e, 0xba5e,
- 0xba5e, 0xba5e, 0xba5e, 0xba5e, 0xba5e, 0x080c, 0x0e02, 0xa001,
- 0xa001, 0x0005, 0x0096, 0x6014, 0x904d, 0x0118, 0xa87c, 0xd0e4,
- 0x1110, 0x009e, 0x0010, 0x009e, 0x0005, 0x6010, 0x00b6, 0x2058,
- 0xb800, 0x00be, 0xd0bc, 0x0550, 0x2001, 0x1833, 0x2004, 0x9005,
- 0x1540, 0x00f6, 0x2c78, 0x080c, 0x9f7f, 0x0508, 0x7810, 0x6012,
- 0x080c, 0xc1b7, 0x7820, 0x9086, 0x0003, 0x0128, 0x7808, 0x603a,
- 0x2f00, 0x603e, 0x0020, 0x7808, 0x603e, 0x2f00, 0x603a, 0x602e,
- 0x6023, 0x0001, 0x6007, 0x0035, 0x6003, 0x0001, 0x7954, 0x6156,
- 0x080c, 0x85f9, 0x080c, 0x8b90, 0x2f60, 0x00fe, 0x0005, 0x2f60,
- 0x00fe, 0x2001, 0x1962, 0x2004, 0x6042, 0x0005, 0x0016, 0x0096,
- 0x6814, 0x2048, 0xa87c, 0xd0e4, 0x0180, 0xc0e4, 0xa87e, 0xa877,
- 0x0000, 0xa893, 0x0000, 0xa88f, 0x0000, 0xd0cc, 0x0130, 0xc0cc,
- 0xa87e, 0xa878, 0x2048, 0x080c, 0x0ff5, 0x6830, 0x6036, 0x908e,
- 0x0001, 0x0148, 0x6803, 0x0002, 0x9086, 0x0005, 0x0170, 0x9006,
- 0x602e, 0x6032, 0x00d0, 0x681c, 0xc085, 0x681e, 0x6803, 0x0004,
- 0x6824, 0xc0f4, 0x9085, 0x0c00, 0x6826, 0x6814, 0x2048, 0xa8ac,
- 0x6938, 0x9102, 0xa8b0, 0x693c, 0x9103, 0x1e48, 0x683c, 0x602e,
- 0x6838, 0x9084, 0xfffc, 0x683a, 0x6032, 0x2d00, 0x603a, 0x6808,
- 0x603e, 0x6910, 0x6112, 0x6954, 0x6156, 0x6023, 0x0001, 0x6007,
- 0x0039, 0x6003, 0x0001, 0x080c, 0x85f9, 0x080c, 0x8b90, 0x009e,
- 0x001e, 0x0005, 0x6024, 0xd0d4, 0x0510, 0xd0f4, 0x11f8, 0x6038,
- 0x940a, 0x603c, 0x9303, 0x0230, 0x9105, 0x0120, 0x6024, 0xc0d4,
- 0xc0f5, 0x0098, 0x643a, 0x633e, 0xac3e, 0xab42, 0x0046, 0x0036,
- 0x2400, 0xacac, 0x9402, 0xa836, 0x2300, 0xabb0, 0x9303, 0xa83a,
- 0x003e, 0x004e, 0x6024, 0xc0d4, 0x0000, 0x6026, 0x0005, 0xd0f4,
- 0x1138, 0xa83c, 0x603a, 0xa840, 0x603e, 0x6024, 0xc0f5, 0x6026,
- 0x0005, 0x0006, 0x0016, 0x6004, 0x908e, 0x0034, 0x01b8, 0x908e,
- 0x0035, 0x01a0, 0x908e, 0x0036, 0x0188, 0x908e, 0x0037, 0x0170,
- 0x908e, 0x0038, 0x0158, 0x908e, 0x0039, 0x0140, 0x908e, 0x003a,
- 0x0128, 0x908e, 0x003b, 0x0110, 0x9085, 0x0001, 0x001e, 0x000e,
- 0x0005, 0x0006, 0x0016, 0x0026, 0x0036, 0x00e6, 0x2001, 0x195c,
- 0x200c, 0x8000, 0x2014, 0x2001, 0x0032, 0x080c, 0x847f, 0x2001,
- 0x1960, 0x82ff, 0x1110, 0x2011, 0x0014, 0x2202, 0x2001, 0x195e,
- 0x200c, 0x8000, 0x2014, 0x2071, 0x1946, 0x711a, 0x721e, 0x2001,
- 0x0064, 0x080c, 0x847f, 0x2001, 0x1961, 0x82ff, 0x1110, 0x2011,
- 0x0014, 0x2202, 0x2001, 0x1962, 0x9288, 0x000a, 0x2102, 0x2001,
- 0x1a69, 0x2102, 0x2001, 0x0032, 0x080c, 0x158c, 0x080c, 0x66ab,
- 0x00ee, 0x003e, 0x002e, 0x001e, 0x000e, 0x0005, 0x0006, 0x0016,
- 0x00e6, 0x2001, 0x1960, 0x2003, 0x0028, 0x2001, 0x1961, 0x2003,
- 0x0014, 0x2071, 0x1946, 0x701b, 0x0000, 0x701f, 0x07d0, 0x2001,
- 0x1962, 0x2009, 0x001e, 0x2102, 0x2001, 0x1a69, 0x2102, 0x2001,
- 0x0032, 0x080c, 0x158c, 0x00ee, 0x001e, 0x000e, 0x0005, 0x0096,
- 0x6058, 0x904d, 0x0110, 0x080c, 0x1075, 0x009e, 0x0005, 0x0005,
- 0x00c6, 0x0126, 0x2091, 0x8000, 0x080c, 0x9f7f, 0x0180, 0x2b08,
- 0x6112, 0x0ca9, 0x6023, 0x0001, 0x2900, 0x6016, 0x2009, 0x0033,
- 0x080c, 0xa053, 0x9085, 0x0001, 0x012e, 0x00ce, 0x0005, 0x9006,
- 0x0cd8, 0x0096, 0x00e6, 0x00f6, 0x2071, 0x1800, 0x9186, 0x0015,
- 0x1520, 0x708c, 0x9086, 0x0018, 0x0120, 0x708c, 0x9086, 0x0014,
- 0x11e0, 0x6014, 0x2048, 0xaa3c, 0xd2e4, 0x1160, 0x2c78, 0x080c,
- 0x8d94, 0x01d8, 0x7078, 0xaa50, 0x9206, 0x1160, 0x707c, 0xaa54,
- 0x9206, 0x1140, 0x6210, 0x00b6, 0x2258, 0xbaa0, 0x00be, 0x900e,
- 0x080c, 0x30f4, 0x080c, 0xa3e0, 0x0020, 0x080c, 0xa995, 0x080c,
- 0x9fd5, 0x00fe, 0x00ee, 0x009e, 0x0005, 0x705c, 0xaa54, 0x9206,
- 0x0d48, 0x0c80, 0x00c6, 0x0126, 0x2091, 0x8000, 0x080c, 0x9f7f,
- 0x0188, 0x2b08, 0x6112, 0x080c, 0xc1b7, 0x6023, 0x0001, 0x2900,
- 0x6016, 0x2009, 0x004d, 0x080c, 0xa053, 0x9085, 0x0001, 0x012e,
- 0x00ce, 0x0005, 0x9006, 0x0cd8, 0x00c6, 0x0126, 0x2091, 0x8000,
- 0x0016, 0x080c, 0x9f7f, 0x0180, 0x2b08, 0x6112, 0x080c, 0xc1b7,
- 0x6023, 0x0001, 0x2900, 0x6016, 0x001e, 0x080c, 0xa053, 0x9085,
- 0x0001, 0x012e, 0x00ce, 0x0005, 0x001e, 0x9006, 0x0cd0, 0x0016,
- 0x0026, 0x0036, 0x0046, 0x0056, 0x0066, 0x0096, 0x00e6, 0x00f6,
- 0x2071, 0x1800, 0x9186, 0x0015, 0x1568, 0x718c, 0x6014, 0x2048,
- 0xa814, 0x8003, 0x9106, 0x1530, 0x20e1, 0x0000, 0x2001, 0x197a,
- 0x2003, 0x0000, 0x6014, 0x2048, 0xa830, 0x20a8, 0x8906, 0x8006,
- 0x8007, 0x9094, 0x003f, 0x22e8, 0x9084, 0xffc0, 0x9080, 0x001b,
- 0x20a0, 0x2001, 0x197a, 0x0016, 0x200c, 0x080c, 0xca60, 0x001e,
- 0xa804, 0x9005, 0x0110, 0x2048, 0x0c38, 0x6014, 0x2048, 0xa867,
- 0x0103, 0x0010, 0x080c, 0xa995, 0x080c, 0x9fd5, 0x00fe, 0x00ee,
- 0x009e, 0x006e, 0x005e, 0x004e, 0x003e, 0x002e, 0x001e, 0x0005,
- 0x0096, 0x00e6, 0x00f6, 0x2071, 0x1800, 0x9186, 0x0015, 0x11b8,
- 0x708c, 0x9086, 0x0004, 0x1198, 0x6014, 0x2048, 0x2c78, 0x080c,
- 0x8d94, 0x01a8, 0x7078, 0xaa74, 0x9206, 0x1130, 0x707c, 0xaa78,
- 0x9206, 0x1110, 0x080c, 0x30ab, 0x080c, 0xa3e0, 0x0020, 0x080c,
- 0xa995, 0x080c, 0x9fd5, 0x00fe, 0x00ee, 0x009e, 0x0005, 0x705c,
- 0xaa78, 0x9206, 0x0d78, 0x0c80, 0x0096, 0x00e6, 0x00f6, 0x2071,
- 0x1800, 0x9186, 0x0015, 0x1550, 0x708c, 0x9086, 0x0004, 0x1530,
- 0x6014, 0x2048, 0x2c78, 0x080c, 0x8d94, 0x05f0, 0x7078, 0xaacc,
- 0x9206, 0x1180, 0x707c, 0xaad0, 0x9206, 0x1160, 0x080c, 0x30ab,
- 0x0016, 0xa998, 0xaab0, 0x9284, 0x1000, 0xc0fd, 0x080c, 0x548b,
- 0x001e, 0x0010, 0x080c, 0x5276, 0x080c, 0xbd3b, 0x0508, 0xa87b,
- 0x0000, 0xa883, 0x0000, 0xa897, 0x4000, 0x0080, 0x080c, 0xbd3b,
- 0x01b8, 0x6014, 0x2048, 0x080c, 0x5276, 0x1d70, 0xa87b, 0x0030,
- 0xa883, 0x0000, 0xa897, 0x4005, 0xa89b, 0x0004, 0x0126, 0x2091,
- 0x8000, 0xa867, 0x0139, 0x080c, 0x6a23, 0x012e, 0x080c, 0x9fd5,
- 0x00fe, 0x00ee, 0x009e, 0x0005, 0x705c, 0xaad0, 0x9206, 0x0930,
- 0x0888, 0x0016, 0x0026, 0xa87c, 0xd0ac, 0x0178, 0xa938, 0xaa34,
- 0x2100, 0x9205, 0x0150, 0xa890, 0x9106, 0x1118, 0xa88c, 0x9206,
- 0x0120, 0xa992, 0xaa8e, 0x9085, 0x0001, 0x002e, 0x001e, 0x0005,
- 0x00b6, 0x00d6, 0x0036, 0x080c, 0xbd3b, 0x0904, 0xc379, 0x0096,
- 0x6314, 0x2348, 0xa87a, 0xa982, 0x929e, 0x4000, 0x1580, 0x6310,
- 0x00c6, 0x2358, 0x2009, 0x0000, 0xa868, 0xd0f4, 0x1140, 0x080c,
- 0x65c4, 0x1108, 0xc185, 0xb800, 0xd0bc, 0x0108, 0xc18d, 0xaa96,
- 0xa99a, 0x20a9, 0x0004, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0031,
- 0x20a0, 0xb8b4, 0x20e0, 0xb8b8, 0x9080, 0x0006, 0x2098, 0x080c,
- 0x0fc0, 0x20a9, 0x0004, 0xa85c, 0x9080, 0x0035, 0x20a0, 0xb8b8,
- 0x9080, 0x000a, 0x2098, 0x080c, 0x0fc0, 0x00ce, 0x0090, 0xaa96,
- 0x3918, 0x9398, 0x0007, 0x231c, 0x6004, 0x9086, 0x0016, 0x0110,
- 0xa89b, 0x0004, 0xaba2, 0x6310, 0x2358, 0xb804, 0x9084, 0x00ff,
- 0xa89e, 0xa868, 0xc0f4, 0xa86a, 0x080c, 0x6a16, 0x6017, 0x0000,
- 0x009e, 0x003e, 0x00de, 0x00be, 0x0005, 0x0026, 0x0036, 0x0046,
- 0x00b6, 0x0096, 0x00f6, 0x6214, 0x2248, 0x6210, 0x2258, 0x2079,
- 0x0260, 0x9096, 0x0000, 0x11a0, 0xb814, 0x9084, 0x00ff, 0x900e,
- 0x080c, 0x266e, 0x2118, 0x831f, 0x939c, 0xff00, 0x7838, 0x9084,
- 0x00ff, 0x931d, 0x7c3c, 0x2011, 0x8018, 0x080c, 0x4a18, 0x00a8,
- 0x9096, 0x0001, 0x1148, 0x89ff, 0x0180, 0xa89b, 0x000d, 0x7838,
- 0xa8a6, 0x783c, 0xa8aa, 0x0048, 0x9096, 0x0002, 0x1130, 0xa89b,
- 0x000d, 0x7838, 0xa8a6, 0x783c, 0xa8aa, 0x00fe, 0x009e, 0x00be,
- 0x004e, 0x003e, 0x002e, 0x0005, 0x00c6, 0x0026, 0x0016, 0x9186,
- 0x0035, 0x0110, 0x6a38, 0x0008, 0x6a2c, 0x080c, 0xbd29, 0x01f0,
- 0x2260, 0x6120, 0x9186, 0x0003, 0x0118, 0x9186, 0x0006, 0x1190,
- 0x6838, 0x9206, 0x0140, 0x683c, 0x9206, 0x1160, 0x6108, 0x6838,
- 0x9106, 0x1140, 0x0020, 0x6008, 0x693c, 0x9106, 0x1118, 0x6010,
- 0x6910, 0x9106, 0x001e, 0x002e, 0x00ce, 0x0005, 0x9085, 0x0001,
- 0x0cc8, 0xa974, 0xd1cc, 0x0188, 0x918c, 0x00ff, 0x918e, 0x0002,
- 0x1160, 0xa9a8, 0x918c, 0x0f00, 0x810f, 0x918e, 0x0001, 0x1128,
- 0xa834, 0xa938, 0x9115, 0x190c, 0xb40c, 0x0005, 0x0036, 0x2019,
- 0x0001, 0x0010, 0x0036, 0x901e, 0x0499, 0x01e0, 0x080c, 0xbd3b,
- 0x01c8, 0x080c, 0xbf26, 0x6037, 0x4000, 0x6014, 0x6017, 0x0000,
- 0x0096, 0x2048, 0xa87c, 0x080c, 0xbf43, 0x1118, 0x080c, 0xa995,
- 0x0040, 0xa867, 0x0103, 0xa877, 0x0000, 0x83ff, 0x1129, 0x080c,
- 0x6a23, 0x009e, 0x003e, 0x0005, 0xa880, 0xd0b4, 0x0128, 0xa87b,
- 0x0006, 0xc0ec, 0xa882, 0x0048, 0xd0bc, 0x0118, 0xa87b, 0x0002,
- 0x0020, 0xa87b, 0x0005, 0x080c, 0xc037, 0xa877, 0x0000, 0x0005,
- 0x2001, 0x1810, 0x2004, 0xd0ec, 0x0005, 0x0006, 0x2001, 0x1810,
- 0x2004, 0xd0f4, 0x000e, 0x0005, 0x0006, 0x2001, 0x1810, 0x2004,
- 0xd0e4, 0x000e, 0x0005, 0x0036, 0x0046, 0x6010, 0x00b6, 0x2058,
- 0xbba0, 0x00be, 0x2021, 0x0007, 0x080c, 0x4bb5, 0x004e, 0x003e,
- 0x0005, 0x0c51, 0x1d81, 0x0005, 0x2001, 0x1960, 0x2004, 0x601a,
- 0x0005, 0x2001, 0x1962, 0x2004, 0x6042, 0x0005, 0x080c, 0x9fd5,
- 0x0804, 0x8b90, 0x2001, 0x0109, 0x2004, 0xd084, 0x01e0, 0x0126,
- 0x2091, 0x2800, 0x0006, 0x0016, 0x0026, 0x0036, 0x00f6, 0x00e6,
- 0x00c6, 0x2079, 0x19c2, 0x2071, 0x1800, 0x2061, 0x0100, 0x080c,
- 0x84e3, 0x00ce, 0x00ee, 0x00fe, 0x003e, 0x002e, 0x001e, 0x000e,
- 0x012e, 0x9085, 0x0001, 0x0005, 0x00b6, 0x0066, 0x6000, 0x90b2,
- 0x0016, 0x1a0c, 0x0e02, 0x001b, 0x006e, 0x00be, 0x0005, 0xc4a7,
- 0xcbbf, 0xcd3d, 0xc4a7, 0xc4a7, 0xc4a7, 0xc4a7, 0xc4a7, 0xc4de,
- 0xcdc1, 0xc4a7, 0xc4a7, 0xc4a7, 0xc4a7, 0xc4a7, 0xc4a7, 0x080c,
- 0x0e02, 0x0066, 0x6000, 0x90b2, 0x0016, 0x1a0c, 0x0e02, 0x0013,
- 0x006e, 0x0005, 0xc4c2, 0xd310, 0xc4c2, 0xc4c2, 0xc4c2, 0xc4c2,
- 0xc4c2, 0xc4c2, 0xd2bd, 0xd364, 0xc4c2, 0xd960, 0xd996, 0xd960,
- 0xd996, 0xc4c2, 0x080c, 0x0e02, 0x6000, 0x9082, 0x0016, 0x1a0c,
- 0x0e02, 0x6000, 0x000a, 0x0005, 0xc4dc, 0xcf9f, 0xd06e, 0xd091,
- 0xd151, 0xc4dc, 0xd230, 0xd1d9, 0xcdcd, 0xd293, 0xd2a8, 0xc4dc,
- 0xc4dc, 0xc4dc, 0xc4dc, 0xc4dc, 0x080c, 0x0e02, 0x91b2, 0x0053,
- 0x1a0c, 0x0e02, 0x2100, 0x91b2, 0x0040, 0x1a04, 0xc95c, 0x0002,
- 0xc528, 0xc72a, 0xc528, 0xc528, 0xc528, 0xc733, 0xc528, 0xc528,
- 0xc528, 0xc528, 0xc528, 0xc528, 0xc528, 0xc528, 0xc528, 0xc528,
- 0xc528, 0xc528, 0xc528, 0xc528, 0xc528, 0xc528, 0xc528, 0xc52a,
- 0xc58d, 0xc59c, 0xc600, 0xc62b, 0xc6a3, 0xc715, 0xc528, 0xc528,
- 0xc736, 0xc528, 0xc528, 0xc74b, 0xc758, 0xc528, 0xc528, 0xc528,
- 0xc528, 0xc528, 0xc7fe, 0xc528, 0xc528, 0xc812, 0xc528, 0xc528,
- 0xc7cd, 0xc528, 0xc528, 0xc528, 0xc82a, 0xc528, 0xc528, 0xc528,
- 0xc8a7, 0xc528, 0xc528, 0xc528, 0xc528, 0xc528, 0xc528, 0xc924,
- 0x080c, 0x0e02, 0x080c, 0x6688, 0x1150, 0x2001, 0x1836, 0x2004,
- 0xd0cc, 0x1128, 0x9084, 0x0009, 0x9086, 0x0008, 0x1140, 0x6007,
- 0x0009, 0x602f, 0x0009, 0x6017, 0x0000, 0x0804, 0xc723, 0x080c,
- 0x6671, 0x00e6, 0x00c6, 0x0036, 0x0026, 0x0016, 0x6210, 0x2258,
- 0xbaa0, 0x0026, 0x2019, 0x0029, 0x080c, 0x8783, 0x0076, 0x903e,
- 0x080c, 0x8671, 0x2c08, 0x080c, 0xd53b, 0x007e, 0x001e, 0x001e,
- 0x002e, 0x003e, 0x00ce, 0x00ee, 0x6610, 0x2658, 0x080c, 0x63b3,
- 0xbe04, 0x9684, 0x00ff, 0x9082, 0x0006, 0x1268, 0x0016, 0x0026,
- 0x6210, 0x00b6, 0x2258, 0xbaa0, 0x00be, 0x2c08, 0x080c, 0xdb10,
- 0x002e, 0x001e, 0x1178, 0x080c, 0xd46e, 0x1904, 0xc5f8, 0x080c,
- 0xd40a, 0x1120, 0x6007, 0x0008, 0x0804, 0xc723, 0x6007, 0x0009,
- 0x0804, 0xc723, 0x080c, 0xd666, 0x0128, 0x080c, 0xd46e, 0x0d78,
- 0x0804, 0xc5f8, 0x6017, 0x1900, 0x0c88, 0x080c, 0x31ce, 0x1904,
- 0xc959, 0x6106, 0x080c, 0xd3bf, 0x6007, 0x0006, 0x0804, 0xc723,
- 0x6007, 0x0007, 0x0804, 0xc723, 0x080c, 0xd9d2, 0x1904, 0xc959,
- 0x080c, 0x31ce, 0x1904, 0xc959, 0x00d6, 0x6610, 0x2658, 0xbe04,
- 0x9684, 0x00ff, 0x9082, 0x0006, 0x1220, 0x2001, 0x0001, 0x080c,
- 0x62e1, 0x96b4, 0xff00, 0x8637, 0x9686, 0x0006, 0x0188, 0x9686,
- 0x0004, 0x0170, 0xbe04, 0x96b4, 0x00ff, 0x9686, 0x0006, 0x0140,
- 0x9686, 0x0004, 0x0128, 0x9686, 0x0005, 0x0110, 0x00de, 0x0480,
- 0x00e6, 0x2071, 0x0260, 0x7034, 0x9084, 0x0003, 0x1140, 0x7034,
- 0x9082, 0x0014, 0x0220, 0x7030, 0x9084, 0x0003, 0x0130, 0x00ee,
- 0x6017, 0x0000, 0x602f, 0x0007, 0x00b0, 0x00ee, 0x080c, 0xd4d1,
- 0x1190, 0x9686, 0x0006, 0x1140, 0x0026, 0x6210, 0x2258, 0xbaa0,
- 0x900e, 0x080c, 0x30f4, 0x002e, 0x080c, 0x643f, 0x6007, 0x000a,
- 0x00de, 0x0804, 0xc723, 0x6007, 0x000b, 0x00de, 0x0804, 0xc723,
- 0x080c, 0x30ab, 0x080c, 0xc459, 0x6007, 0x0001, 0x0804, 0xc723,
- 0x080c, 0xd9d2, 0x1904, 0xc959, 0x080c, 0x31ce, 0x1904, 0xc959,
- 0x2071, 0x0260, 0x7034, 0x90b4, 0x0003, 0x1948, 0x90b2, 0x0014,
- 0x0a30, 0x7030, 0x9084, 0x0003, 0x1910, 0x6610, 0x2658, 0xbe04,
- 0x9686, 0x0707, 0x09e8, 0x0026, 0x6210, 0x2258, 0xbaa0, 0x900e,
- 0x080c, 0x30f4, 0x002e, 0x6007, 0x000c, 0x2001, 0x0001, 0x080c,
- 0xdaef, 0x0804, 0xc723, 0x080c, 0x6688, 0x1140, 0x2001, 0x1836,
- 0x2004, 0x9084, 0x0009, 0x9086, 0x0008, 0x1110, 0x0804, 0xc537,
- 0x080c, 0x6671, 0x6610, 0x2658, 0xbe04, 0x9684, 0x00ff, 0x9082,
- 0x0006, 0x06c0, 0x1138, 0x0026, 0x2001, 0x0006, 0x080c, 0x6321,
- 0x002e, 0x0050, 0x96b4, 0xff00, 0x8637, 0x9686, 0x0004, 0x0120,
- 0x9686, 0x0006, 0x1904, 0xc5f8, 0x080c, 0xd4de, 0x1120, 0x6007,
- 0x000e, 0x0804, 0xc723, 0x0046, 0x6410, 0x2458, 0xbca0, 0x0046,
- 0x080c, 0x30ab, 0x080c, 0xc459, 0x004e, 0x0016, 0x9006, 0x2009,
- 0x185c, 0x210c, 0x0048, 0x2009, 0x0029, 0x080c, 0xd7d6, 0x6010,
- 0x2058, 0xb800, 0xc0e5, 0xb802, 0x001e, 0x004e, 0x6007, 0x0001,
- 0x0804, 0xc723, 0x2001, 0x0001, 0x080c, 0x62e1, 0x0156, 0x0016,
- 0x0026, 0x0036, 0x20a9, 0x0004, 0x2019, 0x1805, 0x2011, 0x0270,
- 0x080c, 0xaff7, 0x003e, 0x002e, 0x001e, 0x015e, 0x9005, 0x0168,
- 0x96b4, 0xff00, 0x8637, 0x9682, 0x0004, 0x0a04, 0xc5f8, 0x9682,
- 0x0007, 0x0a04, 0xc654, 0x0804, 0xc5f8, 0x6017, 0x1900, 0x6007,
- 0x0009, 0x0804, 0xc723, 0x080c, 0x6688, 0x1140, 0x2001, 0x1836,
- 0x2004, 0x9084, 0x0009, 0x9086, 0x0008, 0x1110, 0x0804, 0xc537,
- 0x080c, 0x6671, 0x6610, 0x2658, 0xbe04, 0x9684, 0x00ff, 0x0006,
- 0x0016, 0x908e, 0x0001, 0x0118, 0x908e, 0x0000, 0x1118, 0x001e,
- 0x000e, 0x0080, 0x001e, 0x000e, 0x9082, 0x0006, 0x0698, 0x0150,
- 0x96b4, 0xff00, 0x8637, 0x9686, 0x0004, 0x0120, 0x9686, 0x0006,
- 0x1904, 0xc5f8, 0x080c, 0xd50c, 0x1138, 0x080c, 0xd40a, 0x1120,
- 0x6007, 0x0010, 0x0804, 0xc723, 0x0046, 0x6410, 0x2458, 0xbca0,
- 0x0046, 0x080c, 0x30ab, 0x080c, 0xc459, 0x004e, 0x0016, 0x9006,
- 0x2009, 0x185c, 0x210c, 0x0048, 0x2009, 0x0029, 0x080c, 0xd7d6,
- 0x6010, 0x2058, 0xb800, 0xc0e5, 0xb802, 0x001e, 0x004e, 0x6007,
- 0x0001, 0x0448, 0x080c, 0xd666, 0x0198, 0x0016, 0x968c, 0x00ff,
- 0x9186, 0x0002, 0x0160, 0x9186, 0x0003, 0x0148, 0x001e, 0x96b4,
- 0xff00, 0x8637, 0x9686, 0x0006, 0x0928, 0x0804, 0xc5f8, 0x001e,
- 0x6017, 0x1900, 0x6007, 0x0009, 0x0070, 0x080c, 0x31ce, 0x1904,
- 0xc959, 0x080c, 0xd9d2, 0x1904, 0xc959, 0x080c, 0xcafd, 0x1904,
- 0xc5f8, 0x6007, 0x0012, 0x6003, 0x0001, 0x080c, 0x8641, 0x080c,
- 0x8b90, 0x0005, 0x6007, 0x0001, 0x6003, 0x0001, 0x080c, 0x8641,
- 0x080c, 0x8b90, 0x0cb0, 0x6007, 0x0005, 0x0c68, 0x080c, 0xd9d2,
- 0x1904, 0xc959, 0x080c, 0x31ce, 0x1904, 0xc959, 0x080c, 0xcafd,
- 0x1904, 0xc5f8, 0x6007, 0x0020, 0x6003, 0x0001, 0x080c, 0x8641,
- 0x080c, 0x8b90, 0x0005, 0x080c, 0x31ce, 0x1904, 0xc959, 0x6007,
- 0x0023, 0x6003, 0x0001, 0x080c, 0x8641, 0x080c, 0x8b90, 0x0005,
- 0x080c, 0xd9d2, 0x1904, 0xc959, 0x080c, 0x31ce, 0x1904, 0xc959,
- 0x080c, 0xcafd, 0x1904, 0xc5f8, 0x0016, 0x0026, 0x00e6, 0x2071,
- 0x0260, 0x2c08, 0x2011, 0x181f, 0x2214, 0x703c, 0x9206, 0x11e0,
- 0x2011, 0x181e, 0x2214, 0x7038, 0x9084, 0x00ff, 0x9206, 0x11a0,
- 0x7240, 0x080c, 0xbd29, 0x0570, 0x2260, 0x6008, 0x9086, 0xffff,
- 0x0120, 0x7244, 0x6008, 0x9206, 0x1528, 0x6020, 0x9086, 0x0007,
- 0x1508, 0x080c, 0x9fd5, 0x04a0, 0x7244, 0x9286, 0xffff, 0x0180,
- 0x2c08, 0x080c, 0xbd29, 0x01b0, 0x2260, 0x7240, 0x6008, 0x9206,
- 0x1188, 0x6010, 0x9190, 0x0004, 0x2214, 0x9206, 0x01b8, 0x0050,
- 0x7240, 0x2c08, 0x9006, 0x080c, 0xd7a8, 0x1180, 0x7244, 0x9286,
- 0xffff, 0x01b0, 0x2160, 0x6007, 0x0026, 0x6017, 0x1700, 0x7214,
- 0x9296, 0xffff, 0x1180, 0x6007, 0x0025, 0x0068, 0x6020, 0x9086,
- 0x0007, 0x1d80, 0x6004, 0x9086, 0x0024, 0x1110, 0x080c, 0x9fd5,
- 0x2160, 0x6007, 0x0025, 0x6003, 0x0001, 0x080c, 0x8641, 0x080c,
- 0x8b90, 0x00ee, 0x002e, 0x001e, 0x0005, 0x2001, 0x0001, 0x080c,
- 0x62e1, 0x0156, 0x0016, 0x0026, 0x0036, 0x20a9, 0x0004, 0x2019,
- 0x1805, 0x2011, 0x0276, 0x080c, 0xaff7, 0x003e, 0x002e, 0x001e,
- 0x015e, 0x0120, 0x6007, 0x0031, 0x0804, 0xc723, 0x080c, 0xac52,
- 0x080c, 0x717f, 0x1190, 0x0006, 0x0026, 0x0036, 0x080c, 0x7199,
- 0x1138, 0x080c, 0x747b, 0x080c, 0x5e30, 0x080c, 0x709f, 0x0010,
- 0x080c, 0x7157, 0x003e, 0x002e, 0x000e, 0x0005, 0x080c, 0x31ce,
- 0x1904, 0xc959, 0x080c, 0xcafd, 0x1904, 0xc5f8, 0x6106, 0x080c,
- 0xcb19, 0x1120, 0x6007, 0x002b, 0x0804, 0xc723, 0x6007, 0x002c,
- 0x0804, 0xc723, 0x080c, 0xd9d2, 0x1904, 0xc959, 0x080c, 0x31ce,
- 0x1904, 0xc959, 0x080c, 0xcafd, 0x1904, 0xc5f8, 0x6106, 0x080c,
- 0xcb1e, 0x1120, 0x6007, 0x002e, 0x0804, 0xc723, 0x6007, 0x002f,
- 0x0804, 0xc723, 0x080c, 0x31ce, 0x1904, 0xc959, 0x00e6, 0x00d6,
- 0x00c6, 0x6010, 0x2058, 0xb904, 0x9184, 0x00ff, 0x9086, 0x0006,
- 0x0158, 0x9184, 0xff00, 0x8007, 0x9086, 0x0006, 0x0128, 0x00ce,
- 0x00de, 0x00ee, 0x0804, 0xc72a, 0x080c, 0x54e0, 0xd0e4, 0x0904,
- 0xc8a4, 0x2071, 0x026c, 0x7010, 0x603a, 0x7014, 0x603e, 0x7108,
- 0x720c, 0x080c, 0x66c6, 0x0140, 0x6010, 0x2058, 0xb810, 0x9106,
- 0x1118, 0xb814, 0x9206, 0x0510, 0x080c, 0x66c2, 0x15b8, 0x2069,
- 0x1800, 0x687c, 0x9206, 0x1590, 0x6878, 0x9106, 0x1578, 0x7210,
- 0x080c, 0xbd29, 0x0590, 0x080c, 0xc9ea, 0x0578, 0x080c, 0xd852,
- 0x0560, 0x622e, 0x6007, 0x0036, 0x6003, 0x0001, 0x080c, 0x85f9,
- 0x080c, 0x8b90, 0x00ce, 0x00de, 0x00ee, 0x0005, 0x7214, 0x9286,
- 0xffff, 0x0150, 0x080c, 0xbd29, 0x01c0, 0x9280, 0x0002, 0x2004,
- 0x7110, 0x9106, 0x1190, 0x08e0, 0x7210, 0x2c08, 0x9085, 0x0001,
- 0x080c, 0xd7a8, 0x2c10, 0x2160, 0x0140, 0x0890, 0x6007, 0x0037,
- 0x602f, 0x0009, 0x6017, 0x1500, 0x08b8, 0x6007, 0x0037, 0x602f,
- 0x0003, 0x6017, 0x1700, 0x0880, 0x6007, 0x0012, 0x0868, 0x080c,
- 0x31ce, 0x1904, 0xc959, 0x6010, 0x2058, 0xb804, 0x9084, 0xff00,
- 0x8007, 0x9086, 0x0006, 0x1904, 0xc72a, 0x00e6, 0x00d6, 0x00c6,
- 0x080c, 0x54e0, 0xd0e4, 0x0904, 0xc91c, 0x2069, 0x1800, 0x2071,
- 0x026c, 0x7008, 0x603a, 0x720c, 0x623e, 0x9286, 0xffff, 0x1150,
- 0x7208, 0x00c6, 0x2c08, 0x9085, 0x0001, 0x080c, 0xd7a8, 0x2c10,
- 0x00ce, 0x05e8, 0x080c, 0xbd29, 0x05d0, 0x7108, 0x9280, 0x0002,
- 0x2004, 0x9106, 0x15a0, 0x00c6, 0x0026, 0x2260, 0x080c, 0xb967,
- 0x002e, 0x00ce, 0x7118, 0x918c, 0xff00, 0x810f, 0x9186, 0x0001,
- 0x0178, 0x9186, 0x0005, 0x0118, 0x9186, 0x0007, 0x1198, 0x9280,
- 0x0005, 0x2004, 0x9005, 0x0170, 0x080c, 0xc9ea, 0x0904, 0xc89d,
- 0x0056, 0x7510, 0x7614, 0x080c, 0xd86b, 0x005e, 0x00ce, 0x00de,
- 0x00ee, 0x0005, 0x6007, 0x003b, 0x602f, 0x0009, 0x6017, 0x2a00,
- 0x6003, 0x0001, 0x080c, 0x85f9, 0x080c, 0x8b90, 0x0c78, 0x6007,
- 0x003b, 0x602f, 0x0003, 0x6017, 0x0300, 0x6003, 0x0001, 0x080c,
- 0x85f9, 0x080c, 0x8b90, 0x0c10, 0x6007, 0x003b, 0x602f, 0x000b,
- 0x6017, 0x0000, 0x0804, 0xc874, 0x00e6, 0x0026, 0x080c, 0x6688,
- 0x0550, 0x080c, 0x6671, 0x080c, 0xda43, 0x1518, 0x2071, 0x1800,
- 0x70d8, 0x9085, 0x0003, 0x70da, 0x00f6, 0x2079, 0x0100, 0x72ac,
- 0x9284, 0x00ff, 0x707a, 0x78e6, 0x9284, 0xff00, 0x727c, 0x9205,
- 0x707e, 0x78ea, 0x00fe, 0x70e3, 0x0000, 0x080c, 0x66c6, 0x0120,
- 0x2011, 0x19db, 0x2013, 0x07d0, 0xd0ac, 0x1128, 0x080c, 0x2e8c,
- 0x0010, 0x080c, 0xda77, 0x002e, 0x00ee, 0x080c, 0x9fd5, 0x0804,
- 0xc729, 0x080c, 0x9fd5, 0x0005, 0x2600, 0x0002, 0xc970, 0xc970,
- 0xc970, 0xc970, 0xc970, 0xc972, 0xc970, 0xc970, 0xc970, 0xc970,
- 0xc98c, 0xc970, 0xc970, 0xc970, 0xc99e, 0xc9b4, 0xc9e5, 0xc970,
- 0x080c, 0x0e02, 0x080c, 0xd9d2, 0x1d20, 0x080c, 0x31ce, 0x1d08,
- 0x7038, 0x6016, 0x6007, 0x0045, 0x6003, 0x0001, 0x080c, 0x8641,
- 0x0005, 0x080c, 0x30ab, 0x080c, 0xc459, 0x6007, 0x0001, 0x6003,
- 0x0001, 0x080c, 0x8641, 0x0005, 0x080c, 0xd9d2, 0x1950, 0x080c,
- 0x31ce, 0x1938, 0x080c, 0xcafd, 0x1d60, 0x703c, 0x6016, 0x6007,
- 0x004a, 0x6003, 0x0001, 0x080c, 0x8641, 0x0005, 0x2001, 0x1823,
- 0x2004, 0x9082, 0x00e1, 0x1268, 0x080c, 0xca07, 0x0904, 0xc959,
- 0x6007, 0x004e, 0x6003, 0x0001, 0x080c, 0x8641, 0x080c, 0x8b90,
- 0x0005, 0x6007, 0x0012, 0x0cb0, 0x6007, 0x004f, 0x6017, 0x0000,
- 0x7134, 0x918c, 0x00ff, 0x81ff, 0x0508, 0x9186, 0x0001, 0x1160,
- 0x7140, 0x2001, 0x1998, 0x2004, 0x9106, 0x11b0, 0x7144, 0x2001,
- 0x1999, 0x2004, 0x9106, 0x0190, 0x9186, 0x0002, 0x1168, 0x2011,
- 0x0276, 0x20a9, 0x0004, 0x6010, 0x0096, 0x2048, 0x2019, 0x000a,
- 0x080c, 0xb00b, 0x009e, 0x0110, 0x6017, 0x0001, 0x6003, 0x0001,
- 0x080c, 0x8641, 0x080c, 0x8b90, 0x0005, 0x6007, 0x0050, 0x703c,
- 0x6016, 0x0ca0, 0x0016, 0x00e6, 0x2071, 0x0260, 0x00b6, 0x00c6,
- 0x2260, 0x6010, 0x2058, 0xb8bc, 0xd084, 0x0150, 0x7128, 0x6044,
- 0x9106, 0x1120, 0x712c, 0x6048, 0x9106, 0x0110, 0x9006, 0x0010,
- 0x9085, 0x0001, 0x00ce, 0x00be, 0x00ee, 0x001e, 0x0005, 0x0016,
- 0x0096, 0x0086, 0x00e6, 0x01c6, 0x01d6, 0x0126, 0x2091, 0x8000,
- 0x2071, 0x1800, 0x20e1, 0x0000, 0x2001, 0x197a, 0x2003, 0x0000,
- 0x080c, 0x105c, 0x05a0, 0x2900, 0x6016, 0x708c, 0x8004, 0xa816,
- 0x908a, 0x001e, 0x02d0, 0xa833, 0x001e, 0x20a9, 0x001e, 0xa860,
- 0x20e8, 0xa85c, 0x9080, 0x001b, 0x20a0, 0x2001, 0x197a, 0x0016,
- 0x200c, 0x0471, 0x001e, 0x81ff, 0x01b8, 0x2940, 0x080c, 0x105c,
- 0x01b0, 0x2900, 0xa006, 0x2100, 0x0c18, 0xa832, 0x20a8, 0xa860,
- 0x20e8, 0xa85c, 0x9080, 0x001b, 0x20a0, 0x2001, 0x197a, 0x0016,
- 0x200c, 0x00b1, 0x001e, 0x0000, 0x9085, 0x0001, 0x0048, 0x2071,
- 0x1800, 0x708f, 0x0000, 0x6014, 0x2048, 0x080c, 0x0ff5, 0x9006,
- 0x012e, 0x01de, 0x01ce, 0x00ee, 0x008e, 0x009e, 0x001e, 0x0005,
- 0x0006, 0x0016, 0x0026, 0x0036, 0x00c6, 0x918c, 0xffff, 0x11b0,
- 0x080c, 0x21dd, 0x2099, 0x026c, 0x2001, 0x0014, 0x3518, 0x9312,
- 0x0108, 0x1218, 0x23a8, 0x4003, 0x0400, 0x20a8, 0x4003, 0x22a8,
- 0x8108, 0x080c, 0x21dd, 0x2099, 0x0260, 0x0ca8, 0x080c, 0x21dd,
- 0x2061, 0x197a, 0x6004, 0x2098, 0x6008, 0x3518, 0x9312, 0x0108,
- 0x1218, 0x23a8, 0x4003, 0x0048, 0x20a8, 0x4003, 0x22a8, 0x8108,
- 0x080c, 0x21dd, 0x2099, 0x0260, 0x0ca8, 0x2061, 0x197a, 0x2019,
- 0x0280, 0x3300, 0x931e, 0x0110, 0x6006, 0x0020, 0x2001, 0x0260,
- 0x6006, 0x8108, 0x2162, 0x9292, 0x0021, 0x9296, 0xffff, 0x620a,
- 0x00ce, 0x003e, 0x002e, 0x001e, 0x000e, 0x0005, 0x0006, 0x0016,
- 0x0026, 0x0036, 0x00c6, 0x81ff, 0x11b8, 0x080c, 0x21f5, 0x20a1,
- 0x024c, 0x2001, 0x0014, 0x3518, 0x9312, 0x1218, 0x23a8, 0x4003,
- 0x0418, 0x20a8, 0x4003, 0x82ff, 0x01f8, 0x22a8, 0x8108, 0x080c,
- 0x21f5, 0x20a1, 0x0240, 0x0c98, 0x080c, 0x21f5, 0x2061, 0x197d,
- 0x6004, 0x20a0, 0x6008, 0x3518, 0x9312, 0x1218, 0x23a8, 0x4003,
- 0x0058, 0x20a8, 0x4003, 0x82ff, 0x0138, 0x22a8, 0x8108, 0x080c,
- 0x21f5, 0x20a1, 0x0240, 0x0c98, 0x2061, 0x197d, 0x2019, 0x0260,
- 0x3400, 0x931e, 0x0110, 0x6006, 0x0020, 0x2001, 0x0240, 0x6006,
- 0x8108, 0x2162, 0x9292, 0x0021, 0x9296, 0xffff, 0x620a, 0x00ce,
- 0x003e, 0x002e, 0x001e, 0x000e, 0x0005, 0x00b6, 0x0066, 0x6610,
- 0x2658, 0xbe04, 0x96b4, 0xff00, 0x8637, 0x9686, 0x0006, 0x0170,
- 0x9686, 0x0004, 0x0158, 0xbe04, 0x96b4, 0x00ff, 0x9686, 0x0006,
- 0x0128, 0x9686, 0x0004, 0x0110, 0x9085, 0x0001, 0x006e, 0x00be,
- 0x0005, 0x00d6, 0x080c, 0xcb95, 0x00de, 0x0005, 0x00d6, 0x080c,
- 0xcba2, 0x1520, 0x680c, 0x908c, 0xff00, 0x6820, 0x9084, 0x00ff,
- 0x9115, 0x6216, 0x6824, 0x602e, 0xd1e4, 0x0130, 0x9006, 0x080c,
- 0xdaef, 0x2009, 0x0001, 0x0078, 0xd1ec, 0x0180, 0x6920, 0x918c,
- 0x00ff, 0x6824, 0x080c, 0x266e, 0x1148, 0x2001, 0x0001, 0x080c,
- 0xdaef, 0x2110, 0x900e, 0x080c, 0x30f4, 0x0018, 0x9085, 0x0001,
- 0x0008, 0x9006, 0x00de, 0x0005, 0x00b6, 0x00c6, 0x080c, 0xa026,
- 0x05a8, 0x0016, 0x0026, 0x00c6, 0x2011, 0x0263, 0x2204, 0x8211,
- 0x220c, 0x080c, 0x266e, 0x1578, 0x080c, 0x6344, 0x1560, 0xbe12,
- 0xbd16, 0x00ce, 0x002e, 0x001e, 0x2b00, 0x6012, 0x080c, 0xd9d2,
- 0x11d8, 0x080c, 0x31ce, 0x11c0, 0x080c, 0xcafd, 0x0510, 0x2001,
- 0x0007, 0x080c, 0x62f5, 0x2001, 0x0007, 0x080c, 0x6321, 0x6017,
- 0x0000, 0x6023, 0x0001, 0x6007, 0x0001, 0x6003, 0x0001, 0x080c,
- 0x8641, 0x080c, 0x8b90, 0x0010, 0x080c, 0x9fd5, 0x9085, 0x0001,
- 0x00ce, 0x00be, 0x0005, 0x080c, 0x9fd5, 0x00ce, 0x002e, 0x001e,
- 0x0ca8, 0x080c, 0x9fd5, 0x9006, 0x0c98, 0x2069, 0x026d, 0x6800,
- 0x9082, 0x0010, 0x1228, 0x6017, 0x0000, 0x9085, 0x0001, 0x0008,
- 0x9006, 0x0005, 0x6017, 0x0000, 0x2069, 0x026c, 0x6808, 0x9084,
- 0xff00, 0x9086, 0x0800, 0x1190, 0x6904, 0x9186, 0x0018, 0x0118,
- 0x9186, 0x0014, 0x1158, 0x810f, 0x6800, 0x9084, 0x00ff, 0x910d,
- 0x615a, 0x908e, 0x0014, 0x0110, 0x908e, 0x0010, 0x0005, 0x6004,
- 0x90b2, 0x0053, 0x1a0c, 0x0e02, 0x91b6, 0x0013, 0x1130, 0x2008,
- 0x91b2, 0x0040, 0x1a04, 0xcd0d, 0x040a, 0x91b6, 0x0027, 0x0198,
- 0x9186, 0x0015, 0x0118, 0x9186, 0x0016, 0x1148, 0x080c, 0xc46a,
- 0x0128, 0x6000, 0x9086, 0x0002, 0x0904, 0xa9dc, 0x0005, 0x91b6,
- 0x0014, 0x190c, 0x0e02, 0x2001, 0x0007, 0x080c, 0x6321, 0x080c,
- 0x8a84, 0x080c, 0xa007, 0x080c, 0x8b90, 0x0005, 0xcc2e, 0xcc30,
- 0xcc2e, 0xcc2e, 0xcc2e, 0xcc30, 0xcc3f, 0xcd06, 0xcc91, 0xcd06,
- 0xccb7, 0xcd06, 0xcc3f, 0xcd06, 0xccfe, 0xcd06, 0xccfe, 0xcd06,
- 0xcd06, 0xcc2e, 0xcc2e, 0xcc2e, 0xcc2e, 0xcc2e, 0xcc2e, 0xcc2e,
- 0xcc2e, 0xcc2e, 0xcc2e, 0xcc2e, 0xcc30, 0xcc2e, 0xcd06, 0xcc2e,
- 0xcc2e, 0xcd06, 0xcc2e, 0xcd03, 0xcd06, 0xcc2e, 0xcc2e, 0xcc2e,
- 0xcc2e, 0xcd06, 0xcd06, 0xcc2e, 0xcd06, 0xcd06, 0xcc2e, 0xcc3a,
- 0xcc2e, 0xcc2e, 0xcc2e, 0xcc2e, 0xcd02, 0xcd06, 0xcc2e, 0xcc2e,
- 0xcd06, 0xcd06, 0xcc2e, 0xcc2e, 0xcc2e, 0xcc2e, 0x080c, 0x0e02,
- 0x080c, 0x8a84, 0x080c, 0xc45c, 0x6003, 0x0002, 0x080c, 0x8b90,
- 0x0804, 0xcd0c, 0x9006, 0x080c, 0x62e1, 0x0804, 0xcd06, 0x080c,
- 0x66c2, 0x1904, 0xcd06, 0x9006, 0x080c, 0x62e1, 0x6010, 0x2058,
- 0xb810, 0x9086, 0x00ff, 0x1140, 0x00f6, 0x2079, 0x1800, 0x78a4,
- 0x8000, 0x78a6, 0x00fe, 0x0428, 0x6010, 0x2058, 0xb8b0, 0x9005,
- 0x1178, 0x080c, 0xc444, 0x1904, 0xcd06, 0x0036, 0x0046, 0xbba0,
- 0x2021, 0x0007, 0x080c, 0x4bb5, 0x004e, 0x003e, 0x0804, 0xcd06,
- 0x080c, 0x31ff, 0x1904, 0xcd06, 0x2001, 0x1800, 0x2004, 0x9086,
- 0x0002, 0x1138, 0x00f6, 0x2079, 0x1800, 0x78a4, 0x8000, 0x78a6,
- 0x00fe, 0x2001, 0x0002, 0x080c, 0x62f5, 0x080c, 0x8a84, 0x6023,
- 0x0001, 0x6003, 0x0001, 0x6007, 0x0002, 0x080c, 0x8641, 0x080c,
- 0x8b90, 0x6110, 0x2158, 0x2009, 0x0001, 0x080c, 0x8268, 0x0804,
- 0xcd0c, 0x6610, 0x2658, 0xbe04, 0x96b4, 0xff00, 0x8637, 0x9686,
- 0x0006, 0x0138, 0x9686, 0x0004, 0x0120, 0x2001, 0x0004, 0x080c,
- 0x6321, 0x080c, 0xdb3e, 0x0904, 0xcd06, 0x080c, 0x8a84, 0x2001,
- 0x0004, 0x080c, 0x62f5, 0x6023, 0x0001, 0x6003, 0x0001, 0x6007,
- 0x0003, 0x080c, 0x8641, 0x080c, 0x8b90, 0x0804, 0xcd0c, 0x2001,
- 0x1800, 0x2004, 0x9086, 0x0003, 0x1158, 0x0036, 0x0046, 0x6010,
- 0x2058, 0xbba0, 0x2021, 0x0006, 0x080c, 0x4bb5, 0x004e, 0x003e,
- 0x2001, 0x0006, 0x080c, 0xcd2a, 0x6610, 0x2658, 0xbe04, 0x0066,
- 0x96b4, 0xff00, 0x8637, 0x9686, 0x0006, 0x006e, 0x0168, 0x2001,
- 0x0006, 0x080c, 0x6321, 0x9284, 0x00ff, 0x908e, 0x0007, 0x1120,
- 0x2001, 0x0006, 0x080c, 0x62f5, 0x080c, 0x66c2, 0x11f8, 0x2001,
- 0x1836, 0x2004, 0xd0a4, 0x01d0, 0xbe04, 0x96b4, 0x00ff, 0x9686,
- 0x0006, 0x01a0, 0x00f6, 0x2079, 0x1800, 0x78a4, 0x8000, 0x78a6,
- 0x00fe, 0x0804, 0xcc79, 0x2001, 0x0004, 0x0030, 0x2001, 0x0006,
- 0x0449, 0x0020, 0x0018, 0x0010, 0x080c, 0x6321, 0x080c, 0x8a84,
- 0x080c, 0x9fd5, 0x080c, 0x8b90, 0x0005, 0x2600, 0x0002, 0xcd21,
- 0xcd21, 0xcd21, 0xcd21, 0xcd21, 0xcd23, 0xcd21, 0xcd21, 0xcd21,
- 0xcd21, 0xcd23, 0xcd21, 0xcd21, 0xcd21, 0xcd23, 0xcd23, 0xcd23,
- 0xcd23, 0x080c, 0x0e02, 0x080c, 0x8a84, 0x080c, 0x9fd5, 0x080c,
- 0x8b90, 0x0005, 0x0016, 0x00b6, 0x00d6, 0x6110, 0x2158, 0xb900,
- 0xd184, 0x0138, 0x080c, 0x62f5, 0x9006, 0x080c, 0x62e1, 0x080c,
- 0x30d4, 0x00de, 0x00be, 0x001e, 0x0005, 0x6610, 0x2658, 0xb804,
- 0x9084, 0xff00, 0x8007, 0x90b2, 0x000c, 0x1a0c, 0x0e02, 0x91b6,
- 0x0015, 0x1110, 0x003b, 0x0028, 0x91b6, 0x0016, 0x190c, 0x0e02,
- 0x006b, 0x0005, 0xaa76, 0xaa76, 0xaa76, 0xaa76, 0xcdbf, 0xaa76,
- 0xcda9, 0xcd6a, 0xaa76, 0xaa76, 0xaa76, 0xaa76, 0xaa76, 0xaa76,
- 0xaa76, 0xaa76, 0xcdbf, 0xaa76, 0xcda9, 0xcdb0, 0xaa76, 0xaa76,
- 0xaa76, 0xaa76, 0x00f6, 0x080c, 0x66c2, 0x11d8, 0x080c, 0xc444,
- 0x11c0, 0x6010, 0x905d, 0x01a8, 0xb8b0, 0x9005, 0x0190, 0x9006,
- 0x080c, 0x62e1, 0x2001, 0x0002, 0x080c, 0x62f5, 0x6023, 0x0001,
- 0x6003, 0x0001, 0x6007, 0x0002, 0x080c, 0x8641, 0x080c, 0x8b90,
- 0x00f0, 0x2011, 0x0263, 0x2204, 0x8211, 0x220c, 0x080c, 0x266e,
- 0x11b0, 0x080c, 0x63a4, 0x0118, 0x080c, 0x9fd5, 0x0080, 0xb810,
- 0x0006, 0xb814, 0x0006, 0xb8b0, 0x0006, 0x080c, 0x5e4a, 0x000e,
- 0xb8b2, 0x000e, 0xb816, 0x000e, 0xb812, 0x080c, 0x9fd5, 0x00fe,
- 0x0005, 0x6604, 0x96b6, 0x001e, 0x1110, 0x080c, 0x9fd5, 0x0005,
- 0x080c, 0xae83, 0x1148, 0x6003, 0x0001, 0x6007, 0x0001, 0x080c,
- 0x8641, 0x080c, 0x8b90, 0x0010, 0x080c, 0x9fd5, 0x0005, 0x0804,
- 0x9fd5, 0x6004, 0x908a, 0x0053, 0x1a0c, 0x0e02, 0x080c, 0x8a84,
- 0x080c, 0xa007, 0x080c, 0x8b90, 0x0005, 0x9182, 0x0040, 0x0002,
- 0xcde4, 0xcde4, 0xcde4, 0xcde4, 0xcde6, 0xcde4, 0xcde4, 0xcde4,
- 0xcde4, 0xcde4, 0xcde4, 0xcde4, 0xcde4, 0xcde4, 0xcde4, 0xcde4,
- 0xcde4, 0xcde4, 0xcde4, 0xcde4, 0x080c, 0x0e02, 0x0096, 0x00b6,
- 0x00d6, 0x00e6, 0x00f6, 0x0046, 0x0026, 0x6210, 0x2258, 0xb8ac,
- 0x9005, 0x11a8, 0x6106, 0x2071, 0x0260, 0x7444, 0x94a4, 0xff00,
- 0x0904, 0xce4c, 0x080c, 0xdae3, 0x1170, 0x9486, 0x2000, 0x1158,
- 0x2009, 0x0001, 0x2011, 0x0200, 0x080c, 0x8451, 0x0020, 0x9026,
- 0x080c, 0xda17, 0x0c38, 0x080c, 0x1043, 0x090c, 0x0e02, 0x6003,
- 0x0007, 0xa867, 0x010d, 0x9006, 0xa802, 0xa86a, 0xac8a, 0x2c00,
- 0xa88e, 0x6008, 0xa8e2, 0x6010, 0x2058, 0xb8a0, 0x7130, 0xa97a,
- 0x0016, 0xa876, 0xa87f, 0x0000, 0xa883, 0x0000, 0xa887, 0x0036,
- 0x080c, 0x6a23, 0x001e, 0x080c, 0xdae3, 0x1904, 0xceac, 0x9486,
- 0x2000, 0x1130, 0x2019, 0x0017, 0x080c, 0xd74e, 0x0804, 0xceac,
- 0x9486, 0x0200, 0x1120, 0x080c, 0xd6e5, 0x0804, 0xceac, 0x9486,
- 0x0400, 0x0120, 0x9486, 0x1000, 0x1904, 0xceac, 0x2019, 0x0002,
- 0x080c, 0xd700, 0x0804, 0xceac, 0x2069, 0x1a4c, 0x6a00, 0xd284,
- 0x0904, 0xcf16, 0x9284, 0x0300, 0x1904, 0xcf0f, 0x6804, 0x9005,
- 0x0904, 0xcef7, 0x2d78, 0x6003, 0x0007, 0x080c, 0x105c, 0x0904,
- 0xceb8, 0x7800, 0xd08c, 0x1118, 0x7804, 0x8001, 0x7806, 0x6017,
- 0x0000, 0x2001, 0x180f, 0x2004, 0xd084, 0x1904, 0xcf1a, 0x9006,
- 0xa802, 0xa867, 0x0116, 0xa86a, 0x6008, 0xa8e2, 0x2c00, 0xa87a,
- 0x6010, 0x2058, 0xb8a0, 0x7130, 0xa9b6, 0xa876, 0xb928, 0xa9ba,
- 0xb92c, 0xa9be, 0xb930, 0xa9c2, 0xb934, 0xa9c6, 0xa883, 0x003d,
- 0x7044, 0x9084, 0x0003, 0x9080, 0xceb4, 0x2005, 0xa87e, 0x20a9,
- 0x000a, 0x2001, 0x0270, 0xaa5c, 0x9290, 0x0021, 0x2009, 0x0205,
- 0x200b, 0x0080, 0x20e1, 0x0000, 0xab60, 0x23e8, 0x2098, 0x22a0,
- 0x4003, 0x200b, 0x0000, 0x2001, 0x027a, 0x200c, 0xa9b2, 0x8000,
- 0x200c, 0xa9ae, 0x080c, 0x6a23, 0x002e, 0x004e, 0x00fe, 0x00ee,
- 0x00de, 0x00be, 0x009e, 0x0005, 0x0000, 0x0080, 0x0040, 0x0000,
- 0x2001, 0x1810, 0x2004, 0xd084, 0x0120, 0x080c, 0x1043, 0x1904,
- 0xce61, 0x6017, 0xf100, 0x6003, 0x0001, 0x6007, 0x0041, 0x080c,
- 0x85f9, 0x080c, 0x8b90, 0x0c00, 0x2069, 0x0260, 0x6848, 0x9084,
- 0xff00, 0x9086, 0x1200, 0x1198, 0x686c, 0x9084, 0x00ff, 0x0016,
- 0x6114, 0x918c, 0xf700, 0x910d, 0x6116, 0x001e, 0x6003, 0x0001,
- 0x6007, 0x0043, 0x080c, 0x85f9, 0x080c, 0x8b90, 0x0828, 0x6868,
- 0x602e, 0x686c, 0x6032, 0x6017, 0xf200, 0x6003, 0x0001, 0x6007,
- 0x0041, 0x080c, 0x85f9, 0x080c, 0x8b90, 0x0804, 0xceac, 0x2001,
- 0x180e, 0x2004, 0xd0ec, 0x0120, 0x2011, 0x8049, 0x080c, 0x4a18,
- 0x6017, 0xf300, 0x0010, 0x6017, 0xf100, 0x6003, 0x0001, 0x6007,
- 0x0041, 0x080c, 0x85f9, 0x080c, 0x8b90, 0x0804, 0xceac, 0x6017,
- 0xf500, 0x0c98, 0x6017, 0xf600, 0x0804, 0xcecc, 0x6017, 0xf200,
- 0x0804, 0xcecc, 0xa867, 0x0146, 0xa86b, 0x0000, 0x6008, 0xa886,
- 0x2c00, 0xa87a, 0x7044, 0x9084, 0x0003, 0x9080, 0xceb4, 0x2005,
- 0xa87e, 0x2928, 0x6010, 0x2058, 0xb8a0, 0xa876, 0xb828, 0xa88a,
- 0xb82c, 0xa88e, 0xb830, 0xa892, 0xb834, 0xa896, 0xa883, 0x003d,
- 0x2009, 0x0205, 0x2104, 0x9085, 0x0080, 0x200a, 0x20e1, 0x0000,
- 0x2011, 0x0210, 0x2214, 0x9294, 0x0fff, 0xaaa2, 0x9282, 0x0111,
- 0x1a0c, 0x0e02, 0x8210, 0x821c, 0x2001, 0x026c, 0x2098, 0xa860,
- 0x20e8, 0xa85c, 0x9080, 0x0029, 0x20a0, 0x2011, 0xcf96, 0x2041,
- 0x0001, 0x223d, 0x9784, 0x00ff, 0x9322, 0x1208, 0x2300, 0x20a8,
- 0x4003, 0x931a, 0x0530, 0x8210, 0xd7fc, 0x1130, 0x8d68, 0x2d0a,
- 0x2001, 0x0260, 0x2098, 0x0c68, 0x2950, 0x080c, 0x105c, 0x0170,
- 0x2900, 0xb002, 0xa867, 0x0147, 0xa86b, 0x0000, 0xa860, 0x20e8,
- 0xa85c, 0x9080, 0x001b, 0x20a0, 0x8840, 0x08d8, 0x2548, 0xa800,
- 0x902d, 0x0118, 0x080c, 0x1075, 0x0cc8, 0x080c, 0x1075, 0x0804,
- 0xceb8, 0x2548, 0x8847, 0x9885, 0x0046, 0xa866, 0x2009, 0x0205,
- 0x200b, 0x0000, 0x080c, 0xd781, 0x0804, 0xceac, 0x8010, 0x0004,
- 0x801a, 0x0006, 0x8018, 0x0008, 0x8016, 0x000a, 0x8014, 0x9186,
- 0x0013, 0x1160, 0x6004, 0x908a, 0x0054, 0x1a0c, 0x0e02, 0x9082,
- 0x0040, 0x0a0c, 0x0e02, 0x2008, 0x0804, 0xd025, 0x9186, 0x0051,
- 0x0108, 0x0048, 0x080c, 0xc46a, 0x0500, 0x6000, 0x9086, 0x0002,
- 0x11e0, 0x0804, 0xd06e, 0x9186, 0x0027, 0x0190, 0x9186, 0x0048,
- 0x0128, 0x9186, 0x0014, 0x0160, 0x190c, 0x0e02, 0x080c, 0xc46a,
- 0x0160, 0x6000, 0x9086, 0x0004, 0x190c, 0x0e02, 0x0804, 0xd151,
- 0x6004, 0x9082, 0x0040, 0x2008, 0x001a, 0x080c, 0xa06e, 0x0005,
- 0xcfec, 0xcfee, 0xcfee, 0xd015, 0xcfec, 0xcfec, 0xcfec, 0xcfec,
- 0xcfec, 0xcfec, 0xcfec, 0xcfec, 0xcfec, 0xcfec, 0xcfec, 0xcfec,
- 0xcfec, 0xcfec, 0xcfec, 0xcfec, 0x080c, 0x0e02, 0x080c, 0x8a84,
- 0x080c, 0x8b90, 0x0036, 0x0096, 0x6014, 0x904d, 0x01d8, 0x080c,
- 0xbd3b, 0x01c0, 0x6003, 0x0002, 0x6010, 0x00b6, 0x2058, 0xb800,
- 0x00be, 0xd0bc, 0x1178, 0x2019, 0x0004, 0x080c, 0xd781, 0x6017,
- 0x0000, 0x6018, 0x9005, 0x1120, 0x2001, 0x1961, 0x2004, 0x601a,
- 0x6003, 0x0007, 0x009e, 0x003e, 0x0005, 0x0096, 0x080c, 0x8a84,
- 0x080c, 0x8b90, 0x080c, 0xbd3b, 0x0120, 0x6014, 0x2048, 0x080c,
- 0x1075, 0x080c, 0xa007, 0x009e, 0x0005, 0x0002, 0xd03a, 0xd051,
- 0xd03c, 0xd068, 0xd03a, 0xd03a, 0xd03a, 0xd03a, 0xd03a, 0xd03a,
- 0xd03a, 0xd03a, 0xd03a, 0xd03a, 0xd03a, 0xd03a, 0xd03a, 0xd03a,
- 0xd03a, 0xd03a, 0x080c, 0x0e02, 0x0096, 0x080c, 0x8a84, 0x6014,
- 0x2048, 0xa87c, 0xd0b4, 0x0138, 0x6003, 0x0007, 0x2009, 0x0043,
- 0x080c, 0xa053, 0x0010, 0x6003, 0x0004, 0x080c, 0x8b90, 0x009e,
- 0x0005, 0x080c, 0x8a84, 0x080c, 0xbd3b, 0x0138, 0x6114, 0x0096,
- 0x2148, 0xa97c, 0x009e, 0xd1ec, 0x1138, 0x080c, 0x8426, 0x080c,
- 0x9fd5, 0x080c, 0x8b90, 0x0005, 0x080c, 0xd9db, 0x0db0, 0x0cc8,
- 0x080c, 0x8a84, 0x2009, 0x0041, 0x0804, 0xd1d9, 0x9182, 0x0040,
- 0x0002, 0xd085, 0xd087, 0xd085, 0xd085, 0xd085, 0xd085, 0xd085,
- 0xd085, 0xd085, 0xd085, 0xd085, 0xd085, 0xd085, 0xd085, 0xd085,
- 0xd085, 0xd085, 0xd088, 0xd085, 0xd085, 0x080c, 0x0e02, 0x0005,
- 0x00d6, 0x080c, 0x8426, 0x00de, 0x080c, 0xda33, 0x080c, 0x9fd5,
- 0x0005, 0x9182, 0x0040, 0x0002, 0xd0a8, 0xd0a8, 0xd0a8, 0xd0a8,
- 0xd0a8, 0xd0a8, 0xd0a8, 0xd0a8, 0xd0a8, 0xd0aa, 0xd119, 0xd0a8,
- 0xd0a8, 0xd0a8, 0xd0a8, 0xd119, 0xd0a8, 0xd0a8, 0xd0a8, 0xd0a8,
- 0x080c, 0x0e02, 0x2001, 0x0105, 0x2004, 0x9084, 0x1800, 0x01c8,
- 0x2001, 0x0132, 0x200c, 0x2001, 0x0131, 0x2004, 0x9105, 0x1904,
- 0xd119, 0x2009, 0x180c, 0x2104, 0xd0d4, 0x0904, 0xd119, 0xc0d4,
- 0x200a, 0x2009, 0x0105, 0x2104, 0x9084, 0xe7fd, 0x9085, 0x0010,
- 0x200a, 0x2001, 0x187b, 0x2004, 0xd0e4, 0x1528, 0x603b, 0x0000,
- 0x080c, 0x8b40, 0x6014, 0x0096, 0x2048, 0xa87c, 0xd0fc, 0x0188,
- 0x908c, 0x0003, 0x918e, 0x0002, 0x0508, 0x2001, 0x180c, 0x2004,
- 0xd0d4, 0x11e0, 0x080c, 0x8c6d, 0x2009, 0x0041, 0x009e, 0x0804,
- 0xd1d9, 0x080c, 0x8c6d, 0x6003, 0x0007, 0x601b, 0x0000, 0x080c,
- 0x8426, 0x009e, 0x0005, 0x2001, 0x0100, 0x2004, 0x9082, 0x0005,
- 0x0aa8, 0x2001, 0x011f, 0x2004, 0x603a, 0x0890, 0x2001, 0x180c,
- 0x200c, 0xc1d4, 0x2102, 0xd1cc, 0x0110, 0x080c, 0x2aca, 0x080c,
- 0x8c6d, 0x6014, 0x2048, 0xa97c, 0xd1ec, 0x1130, 0x080c, 0x8426,
- 0x080c, 0x9fd5, 0x009e, 0x0005, 0x080c, 0xd9db, 0x0db8, 0x009e,
- 0x0005, 0x2001, 0x180c, 0x200c, 0xc1d4, 0x2102, 0x0036, 0x080c,
- 0x8b40, 0x080c, 0x8c6d, 0x6014, 0x0096, 0x2048, 0x6010, 0x00b6,
- 0x2058, 0xb800, 0x00be, 0xd0bc, 0x0188, 0xa87c, 0x9084, 0x0003,
- 0x9086, 0x0002, 0x0140, 0xa8ac, 0x6330, 0x931a, 0x6332, 0xa8b0,
- 0x632c, 0x931b, 0x632e, 0x6003, 0x0002, 0x0080, 0x2019, 0x0004,
- 0x080c, 0xd781, 0x6018, 0x9005, 0x1128, 0x2001, 0x1961, 0x2004,
- 0x8003, 0x601a, 0x6017, 0x0000, 0x6003, 0x0007, 0x009e, 0x003e,
- 0x0005, 0x9182, 0x0040, 0x0002, 0xd168, 0xd168, 0xd168, 0xd168,
- 0xd168, 0xd168, 0xd168, 0xd168, 0xd16a, 0xd168, 0xd168, 0xd168,
- 0xd168, 0xd168, 0xd168, 0xd168, 0xd168, 0xd168, 0xd168, 0xd1b5,
- 0x080c, 0x0e02, 0x6014, 0x0096, 0x2048, 0xa834, 0xaa38, 0x6110,
- 0x00b6, 0x2158, 0xb900, 0x00be, 0xd1bc, 0x1190, 0x920d, 0x1518,
- 0xa87c, 0xd0fc, 0x0128, 0x2009, 0x0041, 0x009e, 0x0804, 0xd1d9,
- 0x6003, 0x0007, 0x601b, 0x0000, 0x080c, 0x8426, 0x009e, 0x0005,
- 0x6124, 0xd1f4, 0x1d58, 0x0006, 0x0046, 0xacac, 0x9422, 0xa9b0,
- 0x2200, 0x910b, 0x6030, 0x9420, 0x6432, 0x602c, 0x9109, 0x612e,
- 0x004e, 0x000e, 0x08d8, 0x6110, 0x00b6, 0x2158, 0xb900, 0x00be,
- 0xd1bc, 0x1178, 0x2009, 0x180e, 0x210c, 0xd19c, 0x0118, 0x6003,
- 0x0007, 0x0010, 0x6003, 0x0006, 0x00e9, 0x080c, 0x8428, 0x009e,
- 0x0005, 0x6003, 0x0002, 0x009e, 0x0005, 0x6024, 0xd0f4, 0x0128,
- 0x080c, 0x1583, 0x1904, 0xd16a, 0x0005, 0x6014, 0x0096, 0x2048,
- 0xa834, 0xa938, 0x009e, 0x9105, 0x1120, 0x080c, 0x1583, 0x1904,
- 0xd16a, 0x0005, 0xd2fc, 0x0140, 0x8002, 0x8000, 0x8212, 0x9291,
- 0x0000, 0x2009, 0x0009, 0x0010, 0x2009, 0x0015, 0xaa9a, 0xa896,
- 0x0005, 0x9182, 0x0040, 0x0208, 0x0062, 0x9186, 0x0013, 0x0120,
- 0x9186, 0x0014, 0x190c, 0x0e02, 0x6024, 0xd0dc, 0x090c, 0x0e02,
- 0x0005, 0xd1fd, 0xd209, 0xd215, 0xd221, 0xd1fd, 0xd1fd, 0xd1fd,
- 0xd1fd, 0xd204, 0xd1ff, 0xd1ff, 0xd1fd, 0xd1fd, 0xd1fd, 0xd1fd,
- 0xd1ff, 0xd1fd, 0xd1ff, 0xd1fd, 0xd204, 0x080c, 0x0e02, 0x6024,
- 0xd0dc, 0x090c, 0x0e02, 0x0005, 0x6014, 0x9005, 0x190c, 0x0e02,
- 0x0005, 0x6003, 0x0001, 0x6106, 0x080c, 0x85f9, 0x0126, 0x2091,
- 0x8000, 0x080c, 0x8b90, 0x012e, 0x0005, 0x6003, 0x0001, 0x6106,
- 0x080c, 0x85f9, 0x0126, 0x2091, 0x8000, 0x080c, 0x8b90, 0x012e,
- 0x0005, 0x6003, 0x0003, 0x6106, 0x2c10, 0x080c, 0x1a82, 0x0126,
- 0x2091, 0x8000, 0x080c, 0x865e, 0x080c, 0x8c6d, 0x012e, 0x0005,
- 0x0126, 0x2091, 0x8000, 0x0036, 0x0096, 0x9182, 0x0040, 0x0023,
- 0x009e, 0x003e, 0x012e, 0x0005, 0xd250, 0xd252, 0xd264, 0xd27e,
- 0xd250, 0xd250, 0xd250, 0xd250, 0xd250, 0xd250, 0xd250, 0xd250,
- 0xd250, 0xd250, 0xd250, 0xd250, 0xd250, 0xd250, 0xd250, 0xd250,
- 0x080c, 0x0e02, 0x6014, 0x2048, 0xa87c, 0xd0fc, 0x01f8, 0x909c,
- 0x0003, 0x939e, 0x0003, 0x01d0, 0x6003, 0x0001, 0x6106, 0x080c,
- 0x85f9, 0x080c, 0x8b90, 0x0470, 0x6014, 0x2048, 0xa87c, 0xd0fc,
- 0x0168, 0x909c, 0x0003, 0x939e, 0x0003, 0x0140, 0x6003, 0x0001,
- 0x6106, 0x080c, 0x85f9, 0x080c, 0x8b90, 0x00e0, 0x901e, 0x6316,
- 0x631a, 0x2019, 0x0004, 0x080c, 0xd781, 0x00a0, 0x6014, 0x2048,
- 0xa87c, 0xd0fc, 0x0d98, 0x909c, 0x0003, 0x939e, 0x0003, 0x0d70,
- 0x6003, 0x0003, 0x6106, 0x2c10, 0x080c, 0x1a82, 0x080c, 0x865e,
- 0x080c, 0x8c6d, 0x0005, 0x080c, 0x8a84, 0x6114, 0x81ff, 0x0158,
- 0x0096, 0x2148, 0x080c, 0xda80, 0x0036, 0x2019, 0x0029, 0x080c,
- 0xd781, 0x003e, 0x009e, 0x080c, 0xa007, 0x080c, 0x8b90, 0x0005,
- 0x080c, 0x8b40, 0x6114, 0x81ff, 0x0158, 0x0096, 0x2148, 0x080c,
- 0xda80, 0x0036, 0x2019, 0x0029, 0x080c, 0xd781, 0x003e, 0x009e,
- 0x080c, 0xa007, 0x080c, 0x8c6d, 0x0005, 0x9182, 0x0085, 0x0002,
- 0xd2cf, 0xd2cd, 0xd2cd, 0xd2db, 0xd2cd, 0xd2cd, 0xd2cd, 0xd2cd,
- 0xd2cd, 0xd2cd, 0xd2cd, 0xd2cd, 0xd2cd, 0x080c, 0x0e02, 0x6003,
- 0x000b, 0x6106, 0x080c, 0x85f9, 0x0126, 0x2091, 0x8000, 0x080c,
- 0x8b90, 0x012e, 0x0005, 0x0026, 0x00e6, 0x080c, 0xd9d2, 0x0118,
- 0x080c, 0x9fd5, 0x0450, 0x2071, 0x0260, 0x7224, 0x6216, 0x2001,
- 0x180e, 0x2004, 0xd0e4, 0x0150, 0x6010, 0x00b6, 0x2058, 0xbca0,
- 0x00be, 0x2c00, 0x2011, 0x014e, 0x080c, 0xa2f9, 0x7220, 0x080c,
- 0xd61c, 0x0118, 0x6007, 0x0086, 0x0040, 0x6007, 0x0087, 0x7224,
- 0x9296, 0xffff, 0x1110, 0x6007, 0x0086, 0x6003, 0x0001, 0x080c,
- 0x85f9, 0x080c, 0x8b90, 0x080c, 0x8c6d, 0x00ee, 0x002e, 0x0005,
- 0x9186, 0x0013, 0x1160, 0x6004, 0x908a, 0x0085, 0x0a0c, 0x0e02,
- 0x908a, 0x0092, 0x1a0c, 0x0e02, 0x9082, 0x0085, 0x00a2, 0x9186,
- 0x0027, 0x0130, 0x9186, 0x0014, 0x0118, 0x080c, 0xa06e, 0x0050,
- 0x2001, 0x0007, 0x080c, 0x6321, 0x080c, 0x8a84, 0x080c, 0xa007,
- 0x080c, 0x8b90, 0x0005, 0xd340, 0xd342, 0xd342, 0xd340, 0xd340,
- 0xd340, 0xd340, 0xd340, 0xd340, 0xd340, 0xd340, 0xd340, 0xd340,
- 0x080c, 0x0e02, 0x080c, 0x8a84, 0x080c, 0xa007, 0x080c, 0x8b90,
- 0x0005, 0x9182, 0x0085, 0x0a0c, 0x0e02, 0x9182, 0x0092, 0x1a0c,
- 0x0e02, 0x9182, 0x0085, 0x0002, 0xd361, 0xd361, 0xd361, 0xd363,
- 0xd361, 0xd361, 0xd361, 0xd361, 0xd361, 0xd361, 0xd361, 0xd361,
- 0xd361, 0x080c, 0x0e02, 0x0005, 0x9186, 0x0013, 0x0148, 0x9186,
- 0x0014, 0x0130, 0x9186, 0x0027, 0x0118, 0x080c, 0xa06e, 0x0030,
- 0x080c, 0x8a84, 0x080c, 0xa007, 0x080c, 0x8b90, 0x0005, 0x0036,
- 0x080c, 0xda33, 0x6043, 0x0000, 0x2019, 0x000b, 0x0031, 0x6023,
- 0x0006, 0x6003, 0x0007, 0x003e, 0x0005, 0x0126, 0x0036, 0x2091,
- 0x8000, 0x0086, 0x2c40, 0x0096, 0x904e, 0x080c, 0x994a, 0x009e,
- 0x008e, 0x1550, 0x0076, 0x2c38, 0x080c, 0x99f5, 0x007e, 0x1520,
- 0x6000, 0x9086, 0x0000, 0x0500, 0x6020, 0x9086, 0x0007, 0x01e0,
- 0x0096, 0x601c, 0xd084, 0x0140, 0x080c, 0xda33, 0x080c, 0xc45c,
- 0x080c, 0x1938, 0x6023, 0x0007, 0x6014, 0x2048, 0x080c, 0xbd3b,
- 0x0110, 0x080c, 0xd781, 0x009e, 0x6017, 0x0000, 0x080c, 0xda33,
- 0x6023, 0x0007, 0x080c, 0xc45c, 0x003e, 0x012e, 0x0005, 0x00f6,
- 0x00c6, 0x00b6, 0x0036, 0x0156, 0x2079, 0x0260, 0x7938, 0x783c,
- 0x080c, 0x266e, 0x15c8, 0x0016, 0x00c6, 0x080c, 0x63a4, 0x1590,
- 0x001e, 0x00c6, 0x2160, 0x080c, 0xc459, 0x00ce, 0x002e, 0x0026,
- 0x0016, 0x2019, 0x0029, 0x080c, 0x9abb, 0x080c, 0x8783, 0x0076,
- 0x903e, 0x080c, 0x8671, 0x007e, 0x001e, 0x0076, 0x903e, 0x080c,
- 0xd53b, 0x007e, 0x0026, 0xba04, 0x9294, 0xff00, 0x8217, 0x9286,
- 0x0006, 0x0118, 0x9286, 0x0004, 0x1118, 0xbaa0, 0x080c, 0x3168,
- 0x002e, 0xbcb0, 0x001e, 0x080c, 0x5e4a, 0xbe12, 0xbd16, 0xbcb2,
- 0x9006, 0x0010, 0x00ce, 0x001e, 0x015e, 0x003e, 0x00be, 0x00ce,
- 0x00fe, 0x0005, 0x00c6, 0x00d6, 0x00b6, 0x0016, 0x2009, 0x1823,
- 0x2104, 0x9086, 0x0074, 0x1904, 0xd463, 0x2069, 0x0260, 0x6944,
- 0x9182, 0x0100, 0x06e0, 0x6940, 0x9184, 0x8000, 0x0904, 0xd460,
- 0x2001, 0x1956, 0x2004, 0x9005, 0x1140, 0x6010, 0x2058, 0xb8b0,
- 0x9005, 0x0118, 0x9184, 0x0800, 0x0598, 0x6948, 0x918a, 0x0001,
- 0x0648, 0x080c, 0xdae8, 0x0118, 0x6978, 0xd1fc, 0x11b8, 0x2009,
- 0x0205, 0x200b, 0x0001, 0x693c, 0x81ff, 0x1198, 0x6944, 0x9182,
- 0x0100, 0x02a8, 0x6940, 0x81ff, 0x1178, 0x6948, 0x918a, 0x0001,
- 0x0288, 0x6950, 0x918a, 0x0001, 0x0298, 0x00d0, 0x6017, 0x0100,
- 0x00a0, 0x6017, 0x0300, 0x0088, 0x6017, 0x0500, 0x0070, 0x6017,
- 0x0700, 0x0058, 0x6017, 0x0900, 0x0040, 0x6017, 0x0b00, 0x0028,
- 0x6017, 0x0f00, 0x0010, 0x6017, 0x2d00, 0x9085, 0x0001, 0x0008,
- 0x9006, 0x001e, 0x00be, 0x00de, 0x00ce, 0x0005, 0x00c6, 0x00b6,
- 0x0026, 0x0036, 0x0156, 0x6210, 0x2258, 0xbb04, 0x9394, 0x00ff,
- 0x9286, 0x0006, 0x0180, 0x9286, 0x0004, 0x0168, 0x9394, 0xff00,
- 0x8217, 0x9286, 0x0006, 0x0138, 0x9286, 0x0004, 0x0120, 0x080c,
- 0x63b3, 0x0804, 0xd4ca, 0x2011, 0x0276, 0x20a9, 0x0004, 0x0096,
- 0x2b48, 0x2019, 0x000a, 0x080c, 0xb00b, 0x009e, 0x15a0, 0x2011,
- 0x027a, 0x20a9, 0x0004, 0x0096, 0x2b48, 0x2019, 0x0006, 0x080c,
- 0xb00b, 0x009e, 0x1540, 0x0046, 0x0016, 0xbaa0, 0x2220, 0x9006,
- 0x2009, 0x185c, 0x210c, 0x0038, 0x2009, 0x0029, 0x080c, 0xd7d6,
- 0xb800, 0xc0e5, 0xb802, 0x2019, 0x0029, 0x080c, 0x8783, 0x0076,
- 0x2039, 0x0000, 0x080c, 0x8671, 0x2c08, 0x080c, 0xd53b, 0x007e,
- 0x2001, 0x0007, 0x080c, 0x6321, 0x2001, 0x0007, 0x080c, 0x62f5,
- 0x001e, 0x004e, 0x9006, 0x015e, 0x003e, 0x002e, 0x00be, 0x00ce,
- 0x0005, 0x00d6, 0x2069, 0x026e, 0x6800, 0x9086, 0x0800, 0x0118,
- 0x6017, 0x0000, 0x0008, 0x9006, 0x00de, 0x0005, 0x00b6, 0x00f6,
- 0x0016, 0x0026, 0x0036, 0x0156, 0x2079, 0x026c, 0x7930, 0x7834,
- 0x080c, 0x266e, 0x11d0, 0x080c, 0x63a4, 0x11b8, 0x2011, 0x0270,
- 0x20a9, 0x0004, 0x0096, 0x2b48, 0x2019, 0x000a, 0x080c, 0xb00b,
- 0x009e, 0x1158, 0x2011, 0x0274, 0x20a9, 0x0004, 0x0096, 0x2b48,
- 0x2019, 0x0006, 0x080c, 0xb00b, 0x009e, 0x015e, 0x003e, 0x002e,
- 0x001e, 0x00fe, 0x00be, 0x0005, 0x00b6, 0x0006, 0x0016, 0x0026,
- 0x0036, 0x0156, 0x2011, 0x0263, 0x2204, 0x8211, 0x220c, 0x080c,
- 0x266e, 0x11d0, 0x080c, 0x63a4, 0x11b8, 0x2011, 0x0276, 0x20a9,
- 0x0004, 0x0096, 0x2b48, 0x2019, 0x000a, 0x080c, 0xb00b, 0x009e,
- 0x1158, 0x2011, 0x027a, 0x20a9, 0x0004, 0x0096, 0x2b48, 0x2019,
- 0x0006, 0x080c, 0xb00b, 0x009e, 0x015e, 0x003e, 0x002e, 0x001e,
- 0x000e, 0x00be, 0x0005, 0x00e6, 0x00c6, 0x0086, 0x0076, 0x0066,
- 0x0056, 0x0046, 0x0026, 0x0126, 0x2091, 0x8000, 0x2740, 0x2029,
- 0x19cb, 0x252c, 0x2021, 0x19d1, 0x2424, 0x2061, 0x1cd0, 0x2071,
- 0x1800, 0x7650, 0x7070, 0x81ff, 0x0150, 0x0006, 0x9186, 0x1a88,
- 0x000e, 0x0128, 0x8001, 0x9602, 0x1a04, 0xd5d5, 0x0018, 0x9606,
- 0x0904, 0xd5d5, 0x2100, 0x9c06, 0x0904, 0xd5cc, 0x6720, 0x9786,
- 0x0007, 0x0904, 0xd5cc, 0x080c, 0xd817, 0x1904, 0xd5cc, 0x080c,
- 0xdb06, 0x0904, 0xd5cc, 0x080c, 0xd807, 0x0904, 0xd5cc, 0x6720,
- 0x9786, 0x0001, 0x1148, 0x080c, 0x31ff, 0x0904, 0xd5f0, 0x6004,
- 0x9086, 0x0000, 0x1904, 0xd5f0, 0x9786, 0x0004, 0x0904, 0xd5f0,
- 0x2500, 0x9c06, 0x0904, 0xd5cc, 0x2400, 0x9c06, 0x05e8, 0x88ff,
- 0x0118, 0x6054, 0x9906, 0x15c0, 0x0096, 0x6000, 0x9086, 0x0004,
- 0x1120, 0x0016, 0x080c, 0x1938, 0x001e, 0x9786, 0x000a, 0x0148,
- 0x080c, 0xbf43, 0x1130, 0x080c, 0xa995, 0x009e, 0x080c, 0xa007,
- 0x0418, 0x6014, 0x2048, 0x080c, 0xbd3b, 0x01d8, 0x9786, 0x0003,
- 0x1570, 0xa867, 0x0103, 0xa87c, 0xd0cc, 0x0130, 0x0096, 0xa878,
- 0x2048, 0x080c, 0x0ff5, 0x009e, 0xab7a, 0xa877, 0x0000, 0x080c,
- 0xda80, 0x0016, 0x080c, 0xc031, 0x080c, 0x6a16, 0x001e, 0x080c,
- 0xbf26, 0x009e, 0x080c, 0xa007, 0x9ce0, 0x0018, 0x2001, 0x1819,
- 0x2004, 0x9c02, 0x1210, 0x0804, 0xd54f, 0x012e, 0x002e, 0x004e,
- 0x005e, 0x006e, 0x007e, 0x008e, 0x00ce, 0x00ee, 0x0005, 0x9786,
- 0x0006, 0x1150, 0x9386, 0x0005, 0x0128, 0x080c, 0xda80, 0x080c,
- 0xd781, 0x08f8, 0x009e, 0x0c00, 0x9786, 0x000a, 0x0968, 0x0808,
- 0x81ff, 0x09d0, 0x9180, 0x0001, 0x2004, 0x9086, 0x0018, 0x0130,
- 0x9180, 0x0001, 0x2004, 0x9086, 0x002d, 0x1970, 0x6000, 0x9086,
- 0x0002, 0x1950, 0x080c, 0xbf32, 0x0130, 0x080c, 0xbf43, 0x1920,
- 0x080c, 0xa995, 0x0038, 0x080c, 0x30d4, 0x080c, 0xbf43, 0x1110,
- 0x080c, 0xa995, 0x080c, 0xa007, 0x0804, 0xd5cc, 0xa864, 0x9084,
- 0x00ff, 0x9086, 0x0039, 0x0005, 0x00c6, 0x00e6, 0x0016, 0x2c08,
- 0x2170, 0x9006, 0x080c, 0xd7a8, 0x001e, 0x0120, 0x6020, 0x9084,
- 0x000f, 0x001b, 0x00ee, 0x00ce, 0x0005, 0xd63b, 0xd63b, 0xd63b,
- 0xd63b, 0xd63b, 0xd63b, 0xd63d, 0xd63b, 0xd63b, 0xd63b, 0xd63b,
- 0xa007, 0xa007, 0xd63b, 0x9006, 0x0005, 0x0036, 0x0046, 0x0016,
- 0x7010, 0x00b6, 0x2058, 0xbca0, 0x00be, 0x2c00, 0x2009, 0x0020,
- 0x080c, 0xd7d6, 0x001e, 0x004e, 0x2019, 0x0002, 0x080c, 0xd385,
- 0x003e, 0x9085, 0x0001, 0x0005, 0x0096, 0x080c, 0xbd3b, 0x0140,
- 0x6014, 0x904d, 0x080c, 0xb974, 0x687b, 0x0005, 0x080c, 0x6a23,
- 0x009e, 0x080c, 0xa007, 0x9085, 0x0001, 0x0005, 0x2001, 0x0001,
- 0x080c, 0x62e1, 0x0156, 0x0016, 0x0026, 0x0036, 0x20a9, 0x0004,
- 0x2019, 0x1805, 0x2011, 0x0276, 0x080c, 0xaff7, 0x003e, 0x002e,
- 0x001e, 0x015e, 0x9005, 0x0005, 0x00f6, 0x00e6, 0x00c6, 0x0086,
- 0x0076, 0x0066, 0x00b6, 0x0126, 0x2091, 0x8000, 0x2740, 0x2061,
- 0x1cd0, 0x2079, 0x0001, 0x8fff, 0x0904, 0xd6d8, 0x2071, 0x1800,
- 0x7650, 0x7070, 0x8001, 0x9602, 0x1a04, 0xd6d8, 0x88ff, 0x0120,
- 0x2800, 0x9c06, 0x15a0, 0x2078, 0x080c, 0xd807, 0x0580, 0x2400,
- 0x9c06, 0x0568, 0x6720, 0x9786, 0x0006, 0x1548, 0x9786, 0x0007,
- 0x0530, 0x88ff, 0x1150, 0xd58c, 0x1118, 0x6010, 0x9b06, 0x11f8,
- 0xd584, 0x0118, 0x6054, 0x9106, 0x11d0, 0x0096, 0x601c, 0xd084,
- 0x0140, 0x080c, 0xda33, 0x080c, 0xc45c, 0x080c, 0x1938, 0x6023,
- 0x0007, 0x6014, 0x2048, 0x080c, 0xbd3b, 0x0120, 0x0046, 0x080c,
- 0xd781, 0x004e, 0x009e, 0x080c, 0xa007, 0x88ff, 0x1198, 0x9ce0,
- 0x0018, 0x2001, 0x1819, 0x2004, 0x9c02, 0x1210, 0x0804, 0xd68b,
- 0x9006, 0x012e, 0x00be, 0x006e, 0x007e, 0x008e, 0x00ce, 0x00ee,
- 0x00fe, 0x0005, 0x98c5, 0x0001, 0x0ca0, 0x00b6, 0x0076, 0x0056,
- 0x0086, 0x9046, 0x2029, 0x0001, 0x2c20, 0x2019, 0x0002, 0x6210,
- 0x2258, 0x0096, 0x904e, 0x080c, 0x994a, 0x009e, 0x008e, 0x903e,
- 0x080c, 0x99f5, 0x080c, 0xd67c, 0x005e, 0x007e, 0x00be, 0x0005,
- 0x00b6, 0x0046, 0x0056, 0x0076, 0x00c6, 0x0156, 0x2c20, 0x2128,
- 0x20a9, 0x007f, 0x900e, 0x0016, 0x0036, 0x080c, 0x63a4, 0x1180,
- 0x0056, 0x0086, 0x9046, 0x2508, 0x2029, 0x0001, 0x0096, 0x904e,
- 0x080c, 0x994a, 0x009e, 0x008e, 0x903e, 0x080c, 0x99f5, 0x005e,
- 0x003e, 0x001e, 0x8108, 0x1f04, 0xd70b, 0x0036, 0x2508, 0x2029,
- 0x0003, 0x080c, 0xd67c, 0x003e, 0x015e, 0x00ce, 0x007e, 0x005e,
- 0x004e, 0x00be, 0x0005, 0x00b6, 0x0076, 0x0056, 0x6210, 0x2258,
- 0x0086, 0x9046, 0x2029, 0x0001, 0x2019, 0x0048, 0x0096, 0x904e,
- 0x080c, 0x994a, 0x009e, 0x008e, 0x903e, 0x080c, 0x99f5, 0x2c20,
- 0x080c, 0xd67c, 0x005e, 0x007e, 0x00be, 0x0005, 0x00b6, 0x0046,
- 0x0056, 0x0076, 0x00c6, 0x0156, 0x2c20, 0x20a9, 0x0800, 0x900e,
- 0x0016, 0x0036, 0x080c, 0x63a4, 0x1190, 0x0086, 0x9046, 0x2828,
- 0x0046, 0x2021, 0x0001, 0x080c, 0xda17, 0x004e, 0x0096, 0x904e,
- 0x080c, 0x994a, 0x009e, 0x008e, 0x903e, 0x080c, 0x99f5, 0x003e,
- 0x001e, 0x8108, 0x1f04, 0xd758, 0x0036, 0x2029, 0x0002, 0x080c,
- 0xd67c, 0x003e, 0x015e, 0x00ce, 0x007e, 0x005e, 0x004e, 0x00be,
- 0x0005, 0x0016, 0x00f6, 0x080c, 0xbd39, 0x0198, 0xa864, 0x9084,
- 0x00ff, 0x9086, 0x0046, 0x0180, 0xa800, 0x907d, 0x0138, 0xa803,
- 0x0000, 0xab82, 0x080c, 0x6a23, 0x2f48, 0x0cb0, 0xab82, 0x080c,
- 0x6a23, 0x00fe, 0x001e, 0x0005, 0xa800, 0x907d, 0x0130, 0xa803,
- 0x0000, 0x080c, 0x6a23, 0x2f48, 0x0cb8, 0x080c, 0x6a23, 0x0c88,
- 0x00e6, 0x0046, 0x0036, 0x2061, 0x1cd0, 0x9005, 0x1138, 0x2071,
+ 0x0126, 0x2091, 0x8000, 0x0016, 0x080c, 0x9f94, 0x0180, 0x2b08,
+ 0x6112, 0x080c, 0xc1ca, 0x6023, 0x0001, 0x2900, 0x6016, 0x001e,
+ 0x080c, 0xa068, 0x9085, 0x0001, 0x012e, 0x00ce, 0x0005, 0x001e,
+ 0x9006, 0x0cd0, 0x0016, 0x0026, 0x0036, 0x0046, 0x0056, 0x0066,
+ 0x0096, 0x00e6, 0x00f6, 0x2071, 0x1800, 0x9186, 0x0015, 0x1568,
+ 0x718c, 0x6014, 0x2048, 0xa814, 0x8003, 0x9106, 0x1530, 0x20e1,
+ 0x0000, 0x2001, 0x197b, 0x2003, 0x0000, 0x6014, 0x2048, 0xa830,
+ 0x20a8, 0x8906, 0x8006, 0x8007, 0x9094, 0x003f, 0x22e8, 0x9084,
+ 0xffc0, 0x9080, 0x001b, 0x20a0, 0x2001, 0x197b, 0x0016, 0x200c,
+ 0x080c, 0xca75, 0x001e, 0xa804, 0x9005, 0x0110, 0x2048, 0x0c38,
+ 0x6014, 0x2048, 0xa867, 0x0103, 0x0010, 0x080c, 0xa9a7, 0x080c,
+ 0x9fea, 0x00fe, 0x00ee, 0x009e, 0x006e, 0x005e, 0x004e, 0x003e,
+ 0x002e, 0x001e, 0x0005, 0x0096, 0x00e6, 0x00f6, 0x2071, 0x1800,
+ 0x9186, 0x0015, 0x11b8, 0x708c, 0x9086, 0x0004, 0x1198, 0x6014,
+ 0x2048, 0x2c78, 0x080c, 0x8d93, 0x01a8, 0x7078, 0xaa74, 0x9206,
+ 0x1130, 0x707c, 0xaa78, 0x9206, 0x1110, 0x080c, 0x3095, 0x080c,
+ 0xa3f2, 0x0020, 0x080c, 0xa9a7, 0x080c, 0x9fea, 0x00fe, 0x00ee,
+ 0x009e, 0x0005, 0x705c, 0xaa78, 0x9206, 0x0d78, 0x0c80, 0x0096,
+ 0x00e6, 0x00f6, 0x2071, 0x1800, 0x9186, 0x0015, 0x1550, 0x708c,
+ 0x9086, 0x0004, 0x1530, 0x6014, 0x2048, 0x2c78, 0x080c, 0x8d93,
+ 0x05f0, 0x7078, 0xaacc, 0x9206, 0x1180, 0x707c, 0xaad0, 0x9206,
+ 0x1160, 0x080c, 0x3095, 0x0016, 0xa998, 0xaab0, 0x9284, 0x1000,
+ 0xc0fd, 0x080c, 0x548a, 0x001e, 0x0010, 0x080c, 0x5275, 0x080c,
+ 0xbd4e, 0x0508, 0xa87b, 0x0000, 0xa883, 0x0000, 0xa897, 0x4000,
+ 0x0080, 0x080c, 0xbd4e, 0x01b8, 0x6014, 0x2048, 0x080c, 0x5275,
+ 0x1d70, 0xa87b, 0x0030, 0xa883, 0x0000, 0xa897, 0x4005, 0xa89b,
+ 0x0004, 0x0126, 0x2091, 0x8000, 0xa867, 0x0139, 0x080c, 0x6a22,
+ 0x012e, 0x080c, 0x9fea, 0x00fe, 0x00ee, 0x009e, 0x0005, 0x705c,
+ 0xaad0, 0x9206, 0x0930, 0x0888, 0x0016, 0x0026, 0xa87c, 0xd0ac,
+ 0x0178, 0xa938, 0xaa34, 0x2100, 0x9205, 0x0150, 0xa890, 0x9106,
+ 0x1118, 0xa88c, 0x9206, 0x0120, 0xa992, 0xaa8e, 0x9085, 0x0001,
+ 0x002e, 0x001e, 0x0005, 0x00b6, 0x00d6, 0x0036, 0x080c, 0xbd4e,
+ 0x0904, 0xc38c, 0x0096, 0x6314, 0x2348, 0xa87a, 0xa982, 0x929e,
+ 0x4000, 0x1580, 0x6310, 0x00c6, 0x2358, 0x2009, 0x0000, 0xa868,
+ 0xd0f4, 0x1140, 0x080c, 0x65c3, 0x1108, 0xc185, 0xb800, 0xd0bc,
+ 0x0108, 0xc18d, 0xaa96, 0xa99a, 0x20a9, 0x0004, 0xa860, 0x20e8,
+ 0xa85c, 0x9080, 0x0031, 0x20a0, 0xb8b4, 0x20e0, 0xb8b8, 0x9080,
+ 0x0006, 0x2098, 0x080c, 0x0fb4, 0x20a9, 0x0004, 0xa85c, 0x9080,
+ 0x0035, 0x20a0, 0xb8b8, 0x9080, 0x000a, 0x2098, 0x080c, 0x0fb4,
+ 0x00ce, 0x0090, 0xaa96, 0x3918, 0x9398, 0x0007, 0x231c, 0x6004,
+ 0x9086, 0x0016, 0x0110, 0xa89b, 0x0004, 0xaba2, 0x6310, 0x2358,
+ 0xb804, 0x9084, 0x00ff, 0xa89e, 0xa868, 0xc0f4, 0xa86a, 0x080c,
+ 0x6a15, 0x6017, 0x0000, 0x009e, 0x003e, 0x00de, 0x00be, 0x0005,
+ 0x0026, 0x0036, 0x0046, 0x00b6, 0x0096, 0x00f6, 0x6214, 0x2248,
+ 0x6210, 0x2258, 0x2079, 0x0260, 0x9096, 0x0000, 0x11a0, 0xb814,
+ 0x9084, 0x00ff, 0x900e, 0x080c, 0x266d, 0x2118, 0x831f, 0x939c,
+ 0xff00, 0x7838, 0x9084, 0x00ff, 0x931d, 0x7c3c, 0x2011, 0x8018,
+ 0x080c, 0x4a17, 0x00a8, 0x9096, 0x0001, 0x1148, 0x89ff, 0x0180,
+ 0xa89b, 0x000d, 0x7838, 0xa8a6, 0x783c, 0xa8aa, 0x0048, 0x9096,
+ 0x0002, 0x1130, 0xa89b, 0x000d, 0x7838, 0xa8a6, 0x783c, 0xa8aa,
+ 0x00fe, 0x009e, 0x00be, 0x004e, 0x003e, 0x002e, 0x0005, 0x00c6,
+ 0x0026, 0x0016, 0x9186, 0x0035, 0x0110, 0x6a38, 0x0008, 0x6a2c,
+ 0x080c, 0xbd3c, 0x01f0, 0x2260, 0x6120, 0x9186, 0x0003, 0x0118,
+ 0x9186, 0x0006, 0x1190, 0x6838, 0x9206, 0x0140, 0x683c, 0x9206,
+ 0x1160, 0x6108, 0x6838, 0x9106, 0x1140, 0x0020, 0x6008, 0x693c,
+ 0x9106, 0x1118, 0x6010, 0x6910, 0x9106, 0x001e, 0x002e, 0x00ce,
+ 0x0005, 0x9085, 0x0001, 0x0cc8, 0xa974, 0xd1cc, 0x0198, 0x918c,
+ 0x00ff, 0x918e, 0x0002, 0x1170, 0xa9a8, 0x918c, 0x000f, 0x918e,
+ 0x0001, 0x1140, 0xa87c, 0xd0ac, 0x0128, 0xa834, 0xa938, 0x9115,
+ 0x190c, 0xb41b, 0x0005, 0x0036, 0x2019, 0x0001, 0x0010, 0x0036,
+ 0x901e, 0x0499, 0x01e0, 0x080c, 0xbd4e, 0x01c8, 0x080c, 0xbf39,
+ 0x6037, 0x4000, 0x6014, 0x6017, 0x0000, 0x0096, 0x2048, 0xa87c,
+ 0x080c, 0xbf56, 0x1118, 0x080c, 0xa9a7, 0x0040, 0xa867, 0x0103,
+ 0xa877, 0x0000, 0x83ff, 0x1129, 0x080c, 0x6a22, 0x009e, 0x003e,
+ 0x0005, 0xa880, 0xd0b4, 0x0128, 0xa87b, 0x0006, 0xc0ec, 0xa882,
+ 0x0048, 0xd0bc, 0x0118, 0xa87b, 0x0002, 0x0020, 0xa87b, 0x0005,
+ 0x080c, 0xc04a, 0xa877, 0x0000, 0x0005, 0x2001, 0x1810, 0x2004,
+ 0xd0ec, 0x0005, 0x0006, 0x2001, 0x1810, 0x2004, 0xd0f4, 0x000e,
+ 0x0005, 0x0006, 0x2001, 0x1810, 0x2004, 0xd0e4, 0x000e, 0x0005,
+ 0x0036, 0x0046, 0x6010, 0x00b6, 0x2058, 0xbba0, 0x00be, 0x2021,
+ 0x0007, 0x080c, 0x4bb4, 0x004e, 0x003e, 0x0005, 0x0c51, 0x1d81,
+ 0x0005, 0x2001, 0x1960, 0x2004, 0x601a, 0x0005, 0x2001, 0x1962,
+ 0x2004, 0x6042, 0x0005, 0x080c, 0x9fea, 0x0804, 0x8b8f, 0x2001,
+ 0x0109, 0x2004, 0xd084, 0x01e0, 0x0126, 0x2091, 0x2800, 0x0006,
+ 0x0016, 0x0026, 0x0036, 0x00f6, 0x00e6, 0x00c6, 0x2079, 0x19c2,
+ 0x2071, 0x1800, 0x2061, 0x0100, 0x080c, 0x84e2, 0x00ce, 0x00ee,
+ 0x00fe, 0x003e, 0x002e, 0x001e, 0x000e, 0x012e, 0x9085, 0x0001,
+ 0x0005, 0x00b6, 0x0066, 0x6000, 0x90b2, 0x0010, 0x1a0c, 0x0df6,
+ 0x001b, 0x006e, 0x00be, 0x0005, 0xc4bc, 0xcbd4, 0xcd47, 0xc4bc,
+ 0xc4bc, 0xc4bc, 0xc4bc, 0xc4bc, 0xc4f3, 0xcdcb, 0xc4bc, 0xc4bc,
+ 0xc4bc, 0xc4bc, 0xc4bc, 0xc4bc, 0x080c, 0x0df6, 0x0066, 0x6000,
+ 0x90b2, 0x0010, 0x1a0c, 0x0df6, 0x0013, 0x006e, 0x0005, 0xc4d7,
+ 0xd31a, 0xc4d7, 0xc4d7, 0xc4d7, 0xc4d7, 0xc4d7, 0xc4d7, 0xd2c7,
+ 0xd36e, 0xc4d7, 0xd9c1, 0xd9f7, 0xd9c1, 0xd9f7, 0xc4d7, 0x080c,
+ 0x0df6, 0x6000, 0x9082, 0x0010, 0x1a0c, 0x0df6, 0x6000, 0x000a,
+ 0x0005, 0xc4f1, 0xcfa9, 0xd078, 0xd09b, 0xd15b, 0xc4f1, 0xd23a,
+ 0xd1e3, 0xcdd7, 0xd29d, 0xd2b2, 0xc4f1, 0xc4f1, 0xc4f1, 0xc4f1,
+ 0xc4f1, 0x080c, 0x0df6, 0x91b2, 0x0053, 0x1a0c, 0x0df6, 0x2100,
+ 0x91b2, 0x0040, 0x1a04, 0xc971, 0x0002, 0xc53d, 0xc73f, 0xc53d,
+ 0xc53d, 0xc53d, 0xc748, 0xc53d, 0xc53d, 0xc53d, 0xc53d, 0xc53d,
+ 0xc53d, 0xc53d, 0xc53d, 0xc53d, 0xc53d, 0xc53d, 0xc53d, 0xc53d,
+ 0xc53d, 0xc53d, 0xc53d, 0xc53d, 0xc53f, 0xc5a2, 0xc5b1, 0xc615,
+ 0xc640, 0xc6b8, 0xc72a, 0xc53d, 0xc53d, 0xc74b, 0xc53d, 0xc53d,
+ 0xc760, 0xc76d, 0xc53d, 0xc53d, 0xc53d, 0xc53d, 0xc53d, 0xc813,
+ 0xc53d, 0xc53d, 0xc827, 0xc53d, 0xc53d, 0xc7e2, 0xc53d, 0xc53d,
+ 0xc53d, 0xc83f, 0xc53d, 0xc53d, 0xc53d, 0xc8bc, 0xc53d, 0xc53d,
+ 0xc53d, 0xc53d, 0xc53d, 0xc53d, 0xc939, 0x080c, 0x0df6, 0x080c,
+ 0x6687, 0x1150, 0x2001, 0x1836, 0x2004, 0xd0cc, 0x1128, 0x9084,
+ 0x0009, 0x9086, 0x0008, 0x1140, 0x6007, 0x0009, 0x602f, 0x0009,
+ 0x6017, 0x0000, 0x0804, 0xc738, 0x080c, 0x6670, 0x00e6, 0x00c6,
+ 0x0036, 0x0026, 0x0016, 0x6210, 0x2258, 0xbaa0, 0x0026, 0x2019,
+ 0x0029, 0x080c, 0x8782, 0x0076, 0x903e, 0x080c, 0x8670, 0x2c08,
+ 0x080c, 0xd556, 0x007e, 0x001e, 0x001e, 0x002e, 0x003e, 0x00ce,
+ 0x00ee, 0x6610, 0x2658, 0x080c, 0x63b2, 0xbe04, 0x9684, 0x00ff,
+ 0x9082, 0x0006, 0x1268, 0x0016, 0x0026, 0x6210, 0x00b6, 0x2258,
+ 0xbaa0, 0x00be, 0x2c08, 0x080c, 0xdb71, 0x002e, 0x001e, 0x1178,
+ 0x080c, 0xd489, 0x1904, 0xc60d, 0x080c, 0xd425, 0x1120, 0x6007,
+ 0x0008, 0x0804, 0xc738, 0x6007, 0x0009, 0x0804, 0xc738, 0x080c,
+ 0xd6c7, 0x0128, 0x080c, 0xd489, 0x0d78, 0x0804, 0xc60d, 0x6017,
+ 0x1900, 0x0c88, 0x080c, 0x31b8, 0x1904, 0xc96e, 0x6106, 0x080c,
+ 0xd3c9, 0x6007, 0x0006, 0x0804, 0xc738, 0x6007, 0x0007, 0x0804,
+ 0xc738, 0x080c, 0xda33, 0x1904, 0xc96e, 0x080c, 0x31b8, 0x1904,
+ 0xc96e, 0x00d6, 0x6610, 0x2658, 0xbe04, 0x9684, 0x00ff, 0x9082,
+ 0x0006, 0x1220, 0x2001, 0x0001, 0x080c, 0x62e0, 0x96b4, 0xff00,
+ 0x8637, 0x9686, 0x0006, 0x0188, 0x9686, 0x0004, 0x0170, 0xbe04,
+ 0x96b4, 0x00ff, 0x9686, 0x0006, 0x0140, 0x9686, 0x0004, 0x0128,
+ 0x9686, 0x0005, 0x0110, 0x00de, 0x0480, 0x00e6, 0x2071, 0x0260,
+ 0x7034, 0x9084, 0x0003, 0x1140, 0x7034, 0x9082, 0x0014, 0x0220,
+ 0x7030, 0x9084, 0x0003, 0x0130, 0x00ee, 0x6017, 0x0000, 0x602f,
+ 0x0007, 0x00b0, 0x00ee, 0x080c, 0xd4ec, 0x1190, 0x9686, 0x0006,
+ 0x1140, 0x0026, 0x6210, 0x2258, 0xbaa0, 0x900e, 0x080c, 0x30de,
+ 0x002e, 0x080c, 0x643e, 0x6007, 0x000a, 0x00de, 0x0804, 0xc738,
+ 0x6007, 0x000b, 0x00de, 0x0804, 0xc738, 0x080c, 0x3095, 0x080c,
+ 0xc46e, 0x6007, 0x0001, 0x0804, 0xc738, 0x080c, 0xda33, 0x1904,
+ 0xc96e, 0x080c, 0x31b8, 0x1904, 0xc96e, 0x2071, 0x0260, 0x7034,
+ 0x90b4, 0x0003, 0x1948, 0x90b2, 0x0014, 0x0a30, 0x7030, 0x9084,
+ 0x0003, 0x1910, 0x6610, 0x2658, 0xbe04, 0x9686, 0x0707, 0x09e8,
+ 0x0026, 0x6210, 0x2258, 0xbaa0, 0x900e, 0x080c, 0x30de, 0x002e,
+ 0x6007, 0x000c, 0x2001, 0x0001, 0x080c, 0xdb50, 0x0804, 0xc738,
+ 0x080c, 0x6687, 0x1140, 0x2001, 0x1836, 0x2004, 0x9084, 0x0009,
+ 0x9086, 0x0008, 0x1110, 0x0804, 0xc54c, 0x080c, 0x6670, 0x6610,
+ 0x2658, 0xbe04, 0x9684, 0x00ff, 0x9082, 0x0006, 0x06c0, 0x1138,
+ 0x0026, 0x2001, 0x0006, 0x080c, 0x6320, 0x002e, 0x0050, 0x96b4,
+ 0xff00, 0x8637, 0x9686, 0x0004, 0x0120, 0x9686, 0x0006, 0x1904,
+ 0xc60d, 0x080c, 0xd4f9, 0x1120, 0x6007, 0x000e, 0x0804, 0xc738,
+ 0x0046, 0x6410, 0x2458, 0xbca0, 0x0046, 0x080c, 0x3095, 0x080c,
+ 0xc46e, 0x004e, 0x0016, 0x9006, 0x2009, 0x185c, 0x210c, 0x0048,
+ 0x2009, 0x0029, 0x080c, 0xd837, 0x6010, 0x2058, 0xb800, 0xc0e5,
+ 0xb802, 0x001e, 0x004e, 0x6007, 0x0001, 0x0804, 0xc738, 0x2001,
+ 0x0001, 0x080c, 0x62e0, 0x0156, 0x0016, 0x0026, 0x0036, 0x20a9,
+ 0x0004, 0x2019, 0x1805, 0x2011, 0x0270, 0x080c, 0xb003, 0x003e,
+ 0x002e, 0x001e, 0x015e, 0x9005, 0x0168, 0x96b4, 0xff00, 0x8637,
+ 0x9682, 0x0004, 0x0a04, 0xc60d, 0x9682, 0x0007, 0x0a04, 0xc669,
+ 0x0804, 0xc60d, 0x6017, 0x1900, 0x6007, 0x0009, 0x0804, 0xc738,
+ 0x080c, 0x6687, 0x1140, 0x2001, 0x1836, 0x2004, 0x9084, 0x0009,
+ 0x9086, 0x0008, 0x1110, 0x0804, 0xc54c, 0x080c, 0x6670, 0x6610,
+ 0x2658, 0xbe04, 0x9684, 0x00ff, 0x0006, 0x0016, 0x908e, 0x0001,
+ 0x0118, 0x908e, 0x0000, 0x1118, 0x001e, 0x000e, 0x0080, 0x001e,
+ 0x000e, 0x9082, 0x0006, 0x0698, 0x0150, 0x96b4, 0xff00, 0x8637,
+ 0x9686, 0x0004, 0x0120, 0x9686, 0x0006, 0x1904, 0xc60d, 0x080c,
+ 0xd527, 0x1138, 0x080c, 0xd425, 0x1120, 0x6007, 0x0010, 0x0804,
+ 0xc738, 0x0046, 0x6410, 0x2458, 0xbca0, 0x0046, 0x080c, 0x3095,
+ 0x080c, 0xc46e, 0x004e, 0x0016, 0x9006, 0x2009, 0x185c, 0x210c,
+ 0x0048, 0x2009, 0x0029, 0x080c, 0xd837, 0x6010, 0x2058, 0xb800,
+ 0xc0e5, 0xb802, 0x001e, 0x004e, 0x6007, 0x0001, 0x0448, 0x080c,
+ 0xd6c7, 0x0198, 0x0016, 0x968c, 0x00ff, 0x9186, 0x0002, 0x0160,
+ 0x9186, 0x0003, 0x0148, 0x001e, 0x96b4, 0xff00, 0x8637, 0x9686,
+ 0x0006, 0x0928, 0x0804, 0xc60d, 0x001e, 0x6017, 0x1900, 0x6007,
+ 0x0009, 0x0070, 0x080c, 0x31b8, 0x1904, 0xc96e, 0x080c, 0xda33,
+ 0x1904, 0xc96e, 0x080c, 0xcb12, 0x1904, 0xc60d, 0x6007, 0x0012,
+ 0x6003, 0x0001, 0x080c, 0x8640, 0x080c, 0x8b8f, 0x0005, 0x6007,
+ 0x0001, 0x6003, 0x0001, 0x080c, 0x8640, 0x080c, 0x8b8f, 0x0cb0,
+ 0x6007, 0x0005, 0x0c68, 0x080c, 0xda33, 0x1904, 0xc96e, 0x080c,
+ 0x31b8, 0x1904, 0xc96e, 0x080c, 0xcb12, 0x1904, 0xc60d, 0x6007,
+ 0x0020, 0x6003, 0x0001, 0x080c, 0x8640, 0x080c, 0x8b8f, 0x0005,
+ 0x080c, 0x31b8, 0x1904, 0xc96e, 0x6007, 0x0023, 0x6003, 0x0001,
+ 0x080c, 0x8640, 0x080c, 0x8b8f, 0x0005, 0x080c, 0xda33, 0x1904,
+ 0xc96e, 0x080c, 0x31b8, 0x1904, 0xc96e, 0x080c, 0xcb12, 0x1904,
+ 0xc60d, 0x0016, 0x0026, 0x00e6, 0x2071, 0x0260, 0x2c08, 0x2011,
+ 0x181f, 0x2214, 0x703c, 0x9206, 0x11e0, 0x2011, 0x181e, 0x2214,
+ 0x7038, 0x9084, 0x00ff, 0x9206, 0x11a0, 0x7240, 0x080c, 0xbd3c,
+ 0x0570, 0x2260, 0x6008, 0x9086, 0xffff, 0x0120, 0x7244, 0x6008,
+ 0x9206, 0x1528, 0x6020, 0x9086, 0x0007, 0x1508, 0x080c, 0x9fea,
+ 0x04a0, 0x7244, 0x9286, 0xffff, 0x0180, 0x2c08, 0x080c, 0xbd3c,
+ 0x01b0, 0x2260, 0x7240, 0x6008, 0x9206, 0x1188, 0x6010, 0x9190,
+ 0x0004, 0x2214, 0x9206, 0x01b8, 0x0050, 0x7240, 0x2c08, 0x9006,
+ 0x080c, 0xd809, 0x1180, 0x7244, 0x9286, 0xffff, 0x01b0, 0x2160,
+ 0x6007, 0x0026, 0x6017, 0x1700, 0x7214, 0x9296, 0xffff, 0x1180,
+ 0x6007, 0x0025, 0x0068, 0x6020, 0x9086, 0x0007, 0x1d80, 0x6004,
+ 0x9086, 0x0024, 0x1110, 0x080c, 0x9fea, 0x2160, 0x6007, 0x0025,
+ 0x6003, 0x0001, 0x080c, 0x8640, 0x080c, 0x8b8f, 0x00ee, 0x002e,
+ 0x001e, 0x0005, 0x2001, 0x0001, 0x080c, 0x62e0, 0x0156, 0x0016,
+ 0x0026, 0x0036, 0x20a9, 0x0004, 0x2019, 0x1805, 0x2011, 0x0276,
+ 0x080c, 0xb003, 0x003e, 0x002e, 0x001e, 0x015e, 0x0120, 0x6007,
+ 0x0031, 0x0804, 0xc738, 0x080c, 0xac59, 0x080c, 0x717e, 0x1190,
+ 0x0006, 0x0026, 0x0036, 0x080c, 0x7198, 0x1138, 0x080c, 0x747a,
+ 0x080c, 0x5e2f, 0x080c, 0x709e, 0x0010, 0x080c, 0x7156, 0x003e,
+ 0x002e, 0x000e, 0x0005, 0x080c, 0x31b8, 0x1904, 0xc96e, 0x080c,
+ 0xcb12, 0x1904, 0xc60d, 0x6106, 0x080c, 0xcb2e, 0x1120, 0x6007,
+ 0x002b, 0x0804, 0xc738, 0x6007, 0x002c, 0x0804, 0xc738, 0x080c,
+ 0xda33, 0x1904, 0xc96e, 0x080c, 0x31b8, 0x1904, 0xc96e, 0x080c,
+ 0xcb12, 0x1904, 0xc60d, 0x6106, 0x080c, 0xcb33, 0x1120, 0x6007,
+ 0x002e, 0x0804, 0xc738, 0x6007, 0x002f, 0x0804, 0xc738, 0x080c,
+ 0x31b8, 0x1904, 0xc96e, 0x00e6, 0x00d6, 0x00c6, 0x6010, 0x2058,
+ 0xb904, 0x9184, 0x00ff, 0x9086, 0x0006, 0x0158, 0x9184, 0xff00,
+ 0x8007, 0x9086, 0x0006, 0x0128, 0x00ce, 0x00de, 0x00ee, 0x0804,
+ 0xc73f, 0x080c, 0x54df, 0xd0e4, 0x0904, 0xc8b9, 0x2071, 0x026c,
+ 0x7010, 0x603a, 0x7014, 0x603e, 0x7108, 0x720c, 0x080c, 0x66c5,
+ 0x0140, 0x6010, 0x2058, 0xb810, 0x9106, 0x1118, 0xb814, 0x9206,
+ 0x0510, 0x080c, 0x66c1, 0x15b8, 0x2069, 0x1800, 0x687c, 0x9206,
+ 0x1590, 0x6878, 0x9106, 0x1578, 0x7210, 0x080c, 0xbd3c, 0x0590,
+ 0x080c, 0xc9ff, 0x0578, 0x080c, 0xd8b3, 0x0560, 0x622e, 0x6007,
+ 0x0036, 0x6003, 0x0001, 0x080c, 0x85f8, 0x080c, 0x8b8f, 0x00ce,
+ 0x00de, 0x00ee, 0x0005, 0x7214, 0x9286, 0xffff, 0x0150, 0x080c,
+ 0xbd3c, 0x01c0, 0x9280, 0x0002, 0x2004, 0x7110, 0x9106, 0x1190,
+ 0x08e0, 0x7210, 0x2c08, 0x9085, 0x0001, 0x080c, 0xd809, 0x2c10,
+ 0x2160, 0x0140, 0x0890, 0x6007, 0x0037, 0x602f, 0x0009, 0x6017,
+ 0x1500, 0x08b8, 0x6007, 0x0037, 0x602f, 0x0003, 0x6017, 0x1700,
+ 0x0880, 0x6007, 0x0012, 0x0868, 0x080c, 0x31b8, 0x1904, 0xc96e,
+ 0x6010, 0x2058, 0xb804, 0x9084, 0xff00, 0x8007, 0x9086, 0x0006,
+ 0x1904, 0xc73f, 0x00e6, 0x00d6, 0x00c6, 0x080c, 0x54df, 0xd0e4,
+ 0x0904, 0xc931, 0x2069, 0x1800, 0x2071, 0x026c, 0x7008, 0x603a,
+ 0x720c, 0x623e, 0x9286, 0xffff, 0x1150, 0x7208, 0x00c6, 0x2c08,
+ 0x9085, 0x0001, 0x080c, 0xd809, 0x2c10, 0x00ce, 0x05e8, 0x080c,
+ 0xbd3c, 0x05d0, 0x7108, 0x9280, 0x0002, 0x2004, 0x9106, 0x15a0,
+ 0x00c6, 0x0026, 0x2260, 0x080c, 0xb976, 0x002e, 0x00ce, 0x7118,
+ 0x918c, 0xff00, 0x810f, 0x9186, 0x0001, 0x0178, 0x9186, 0x0005,
+ 0x0118, 0x9186, 0x0007, 0x1198, 0x9280, 0x0005, 0x2004, 0x9005,
+ 0x0170, 0x080c, 0xc9ff, 0x0904, 0xc8b2, 0x0056, 0x7510, 0x7614,
+ 0x080c, 0xd8cc, 0x005e, 0x00ce, 0x00de, 0x00ee, 0x0005, 0x6007,
+ 0x003b, 0x602f, 0x0009, 0x6017, 0x2a00, 0x6003, 0x0001, 0x080c,
+ 0x85f8, 0x080c, 0x8b8f, 0x0c78, 0x6007, 0x003b, 0x602f, 0x0003,
+ 0x6017, 0x0300, 0x6003, 0x0001, 0x080c, 0x85f8, 0x080c, 0x8b8f,
+ 0x0c10, 0x6007, 0x003b, 0x602f, 0x000b, 0x6017, 0x0000, 0x0804,
+ 0xc889, 0x00e6, 0x0026, 0x080c, 0x6687, 0x0550, 0x080c, 0x6670,
+ 0x080c, 0xdaa4, 0x1518, 0x2071, 0x1800, 0x70d8, 0x9085, 0x0003,
+ 0x70da, 0x00f6, 0x2079, 0x0100, 0x72ac, 0x9284, 0x00ff, 0x707a,
+ 0x78e6, 0x9284, 0xff00, 0x727c, 0x9205, 0x707e, 0x78ea, 0x00fe,
+ 0x70e3, 0x0000, 0x080c, 0x66c5, 0x0120, 0x2011, 0x19db, 0x2013,
+ 0x07d0, 0xd0ac, 0x1128, 0x080c, 0x2e73, 0x0010, 0x080c, 0xdad8,
+ 0x002e, 0x00ee, 0x080c, 0x9fea, 0x0804, 0xc73e, 0x080c, 0x9fea,
+ 0x0005, 0x2600, 0x0002, 0xc985, 0xc985, 0xc985, 0xc985, 0xc985,
+ 0xc987, 0xc985, 0xc985, 0xc985, 0xc985, 0xc9a1, 0xc985, 0xc985,
+ 0xc985, 0xc9b3, 0xc9c9, 0xc9fa, 0xc985, 0x080c, 0x0df6, 0x080c,
+ 0xda33, 0x1d20, 0x080c, 0x31b8, 0x1d08, 0x7038, 0x6016, 0x6007,
+ 0x0045, 0x6003, 0x0001, 0x080c, 0x8640, 0x0005, 0x080c, 0x3095,
+ 0x080c, 0xc46e, 0x6007, 0x0001, 0x6003, 0x0001, 0x080c, 0x8640,
+ 0x0005, 0x080c, 0xda33, 0x1950, 0x080c, 0x31b8, 0x1938, 0x080c,
+ 0xcb12, 0x1d60, 0x703c, 0x6016, 0x6007, 0x004a, 0x6003, 0x0001,
+ 0x080c, 0x8640, 0x0005, 0x2001, 0x1823, 0x2004, 0x9082, 0x00e1,
+ 0x1268, 0x080c, 0xca1c, 0x0904, 0xc96e, 0x6007, 0x004e, 0x6003,
+ 0x0001, 0x080c, 0x8640, 0x080c, 0x8b8f, 0x0005, 0x6007, 0x0012,
+ 0x0cb0, 0x6007, 0x004f, 0x6017, 0x0000, 0x7134, 0x918c, 0x00ff,
+ 0x81ff, 0x0508, 0x9186, 0x0001, 0x1160, 0x7140, 0x2001, 0x1998,
+ 0x2004, 0x9106, 0x11b0, 0x7144, 0x2001, 0x1999, 0x2004, 0x9106,
+ 0x0190, 0x9186, 0x0002, 0x1168, 0x2011, 0x0276, 0x20a9, 0x0004,
+ 0x6010, 0x0096, 0x2048, 0x2019, 0x000a, 0x080c, 0xb017, 0x009e,
+ 0x0110, 0x6017, 0x0001, 0x6003, 0x0001, 0x080c, 0x8640, 0x080c,
+ 0x8b8f, 0x0005, 0x6007, 0x0050, 0x703c, 0x6016, 0x0ca0, 0x0016,
+ 0x00e6, 0x2071, 0x0260, 0x00b6, 0x00c6, 0x2260, 0x6010, 0x2058,
+ 0xb8bc, 0xd084, 0x0150, 0x7128, 0x6044, 0x9106, 0x1120, 0x712c,
+ 0x6048, 0x9106, 0x0110, 0x9006, 0x0010, 0x9085, 0x0001, 0x00ce,
+ 0x00be, 0x00ee, 0x001e, 0x0005, 0x0016, 0x0096, 0x0086, 0x00e6,
+ 0x01c6, 0x01d6, 0x0126, 0x2091, 0x8000, 0x2071, 0x1800, 0x20e1,
+ 0x0000, 0x2001, 0x197b, 0x2003, 0x0000, 0x080c, 0x1050, 0x05a0,
+ 0x2900, 0x6016, 0x708c, 0x8004, 0xa816, 0x908a, 0x001e, 0x02d0,
+ 0xa833, 0x001e, 0x20a9, 0x001e, 0xa860, 0x20e8, 0xa85c, 0x9080,
+ 0x001b, 0x20a0, 0x2001, 0x197b, 0x0016, 0x200c, 0x0471, 0x001e,
+ 0x81ff, 0x01b8, 0x2940, 0x080c, 0x1050, 0x01b0, 0x2900, 0xa006,
+ 0x2100, 0x0c18, 0xa832, 0x20a8, 0xa860, 0x20e8, 0xa85c, 0x9080,
+ 0x001b, 0x20a0, 0x2001, 0x197b, 0x0016, 0x200c, 0x00b1, 0x001e,
+ 0x0000, 0x9085, 0x0001, 0x0048, 0x2071, 0x1800, 0x708f, 0x0000,
+ 0x6014, 0x2048, 0x080c, 0x0fe9, 0x9006, 0x012e, 0x01de, 0x01ce,
+ 0x00ee, 0x008e, 0x009e, 0x001e, 0x0005, 0x0006, 0x0016, 0x0026,
+ 0x0036, 0x00c6, 0x918c, 0xffff, 0x11b0, 0x080c, 0x21d9, 0x2099,
+ 0x026c, 0x2001, 0x0014, 0x3518, 0x9312, 0x0108, 0x1218, 0x23a8,
+ 0x4003, 0x0400, 0x20a8, 0x4003, 0x22a8, 0x8108, 0x080c, 0x21d9,
+ 0x2099, 0x0260, 0x0ca8, 0x080c, 0x21d9, 0x2061, 0x197b, 0x6004,
+ 0x2098, 0x6008, 0x3518, 0x9312, 0x0108, 0x1218, 0x23a8, 0x4003,
+ 0x0048, 0x20a8, 0x4003, 0x22a8, 0x8108, 0x080c, 0x21d9, 0x2099,
+ 0x0260, 0x0ca8, 0x2061, 0x197b, 0x2019, 0x0280, 0x3300, 0x931e,
+ 0x0110, 0x6006, 0x0020, 0x2001, 0x0260, 0x6006, 0x8108, 0x2162,
+ 0x9292, 0x0021, 0x9296, 0xffff, 0x620a, 0x00ce, 0x003e, 0x002e,
+ 0x001e, 0x000e, 0x0005, 0x0006, 0x0016, 0x0026, 0x0036, 0x00c6,
+ 0x81ff, 0x11b8, 0x080c, 0x21f1, 0x20a1, 0x024c, 0x2001, 0x0014,
+ 0x3518, 0x9312, 0x1218, 0x23a8, 0x4003, 0x0418, 0x20a8, 0x4003,
+ 0x82ff, 0x01f8, 0x22a8, 0x8108, 0x080c, 0x21f1, 0x20a1, 0x0240,
+ 0x0c98, 0x080c, 0x21f1, 0x2061, 0x197e, 0x6004, 0x20a0, 0x6008,
+ 0x3518, 0x9312, 0x1218, 0x23a8, 0x4003, 0x0058, 0x20a8, 0x4003,
+ 0x82ff, 0x0138, 0x22a8, 0x8108, 0x080c, 0x21f1, 0x20a1, 0x0240,
+ 0x0c98, 0x2061, 0x197e, 0x2019, 0x0260, 0x3400, 0x931e, 0x0110,
+ 0x6006, 0x0020, 0x2001, 0x0240, 0x6006, 0x8108, 0x2162, 0x9292,
+ 0x0021, 0x9296, 0xffff, 0x620a, 0x00ce, 0x003e, 0x002e, 0x001e,
+ 0x000e, 0x0005, 0x00b6, 0x0066, 0x6610, 0x2658, 0xbe04, 0x96b4,
+ 0xff00, 0x8637, 0x9686, 0x0006, 0x0170, 0x9686, 0x0004, 0x0158,
+ 0xbe04, 0x96b4, 0x00ff, 0x9686, 0x0006, 0x0128, 0x9686, 0x0004,
+ 0x0110, 0x9085, 0x0001, 0x006e, 0x00be, 0x0005, 0x00d6, 0x080c,
+ 0xcbaa, 0x00de, 0x0005, 0x00d6, 0x080c, 0xcbb7, 0x1520, 0x680c,
+ 0x908c, 0xff00, 0x6820, 0x9084, 0x00ff, 0x9115, 0x6216, 0x6824,
+ 0x602e, 0xd1e4, 0x0130, 0x9006, 0x080c, 0xdb50, 0x2009, 0x0001,
+ 0x0078, 0xd1ec, 0x0180, 0x6920, 0x918c, 0x00ff, 0x6824, 0x080c,
+ 0x266d, 0x1148, 0x2001, 0x0001, 0x080c, 0xdb50, 0x2110, 0x900e,
+ 0x080c, 0x30de, 0x0018, 0x9085, 0x0001, 0x0008, 0x9006, 0x00de,
+ 0x0005, 0x00b6, 0x00c6, 0x080c, 0xa03b, 0x05a8, 0x0016, 0x0026,
+ 0x00c6, 0x2011, 0x0263, 0x2204, 0x8211, 0x220c, 0x080c, 0x266d,
+ 0x1578, 0x080c, 0x6343, 0x1560, 0xbe12, 0xbd16, 0x00ce, 0x002e,
+ 0x001e, 0x2b00, 0x6012, 0x080c, 0xda33, 0x11d8, 0x080c, 0x31b8,
+ 0x11c0, 0x080c, 0xcb12, 0x0510, 0x2001, 0x0007, 0x080c, 0x62f4,
+ 0x2001, 0x0007, 0x080c, 0x6320, 0x6017, 0x0000, 0x6023, 0x0001,
+ 0x6007, 0x0001, 0x6003, 0x0001, 0x080c, 0x8640, 0x080c, 0x8b8f,
+ 0x0010, 0x080c, 0x9fea, 0x9085, 0x0001, 0x00ce, 0x00be, 0x0005,
+ 0x080c, 0x9fea, 0x00ce, 0x002e, 0x001e, 0x0ca8, 0x080c, 0x9fea,
+ 0x9006, 0x0c98, 0x2069, 0x026d, 0x6800, 0x9082, 0x0010, 0x1228,
+ 0x6017, 0x0000, 0x9085, 0x0001, 0x0008, 0x9006, 0x0005, 0x6017,
+ 0x0000, 0x2069, 0x026c, 0x6808, 0x9084, 0xff00, 0x9086, 0x0800,
+ 0x1190, 0x6904, 0x9186, 0x0018, 0x0118, 0x9186, 0x0014, 0x1158,
+ 0x810f, 0x6800, 0x9084, 0x00ff, 0x910d, 0x615a, 0x908e, 0x0014,
+ 0x0110, 0x908e, 0x0010, 0x0005, 0x6004, 0x90b2, 0x0053, 0x1a0c,
+ 0x0df6, 0x91b6, 0x0013, 0x1130, 0x2008, 0x91b2, 0x0040, 0x1a04,
+ 0xcd17, 0x040a, 0x91b6, 0x0027, 0x0198, 0x9186, 0x0015, 0x0118,
+ 0x9186, 0x0016, 0x1148, 0x080c, 0xc47f, 0x0128, 0x6000, 0x9086,
+ 0x0002, 0x0904, 0xa9ee, 0x0005, 0x91b6, 0x0014, 0x190c, 0x0df6,
+ 0x2001, 0x0007, 0x080c, 0x6320, 0x080c, 0x8a83, 0x080c, 0xa01c,
+ 0x080c, 0x8b8f, 0x0005, 0xcc43, 0xcc45, 0xcc43, 0xcc43, 0xcc43,
+ 0xcc45, 0xcc54, 0xcd10, 0xcc98, 0xcd10, 0xccbe, 0xcd10, 0xcc54,
+ 0xcd10, 0xcd08, 0xcd10, 0xcd08, 0xcd10, 0xcd10, 0xcc43, 0xcc43,
+ 0xcc43, 0xcc43, 0xcc43, 0xcc43, 0xcc43, 0xcc43, 0xcc43, 0xcc43,
+ 0xcc43, 0xcc45, 0xcc43, 0xcd10, 0xcc43, 0xcc43, 0xcd10, 0xcc43,
+ 0xcd0d, 0xcd10, 0xcc43, 0xcc43, 0xcc43, 0xcc43, 0xcd10, 0xcd10,
+ 0xcc43, 0xcd10, 0xcd10, 0xcc43, 0xcc4f, 0xcc43, 0xcc43, 0xcc43,
+ 0xcc43, 0xcd0c, 0xcd10, 0xcc43, 0xcc43, 0xcd10, 0xcd10, 0xcc43,
+ 0xcc43, 0xcc43, 0xcc43, 0x080c, 0x0df6, 0x080c, 0x8a83, 0x080c,
+ 0xc471, 0x6003, 0x0002, 0x080c, 0x8b8f, 0x0804, 0xcd16, 0x9006,
+ 0x080c, 0x62e0, 0x0804, 0xcd10, 0x080c, 0x66c1, 0x1904, 0xcd10,
+ 0x9006, 0x080c, 0x62e0, 0x6010, 0x2058, 0xb810, 0x9086, 0x00ff,
+ 0x1140, 0x00f6, 0x2079, 0x1800, 0x78a4, 0x8000, 0x78a6, 0x00fe,
+ 0x00b8, 0x6010, 0x2058, 0xb8b0, 0x9005, 0x0904, 0xcd10, 0x080c,
+ 0x31e9, 0x1904, 0xcd10, 0x2001, 0x1800, 0x2004, 0x9086, 0x0002,
+ 0x1138, 0x00f6, 0x2079, 0x1800, 0x78a4, 0x8000, 0x78a6, 0x00fe,
+ 0x2001, 0x0002, 0x080c, 0x62f4, 0x080c, 0x8a83, 0x6023, 0x0001,
+ 0x6003, 0x0001, 0x6007, 0x0002, 0x080c, 0x8640, 0x080c, 0x8b8f,
+ 0x6110, 0x2158, 0x2009, 0x0001, 0x080c, 0x8267, 0x0804, 0xcd16,
+ 0x6610, 0x2658, 0xbe04, 0x96b4, 0xff00, 0x8637, 0x9686, 0x0006,
+ 0x0138, 0x9686, 0x0004, 0x0120, 0x2001, 0x0004, 0x080c, 0x6320,
+ 0x080c, 0xdb9f, 0x0904, 0xcd10, 0x080c, 0x8a83, 0x2001, 0x0004,
+ 0x080c, 0x62f4, 0x6023, 0x0001, 0x6003, 0x0001, 0x6007, 0x0003,
+ 0x080c, 0x8640, 0x080c, 0x8b8f, 0x0804, 0xcd16, 0x2001, 0x1800,
+ 0x2004, 0x9086, 0x0003, 0x1158, 0x0036, 0x0046, 0x6010, 0x2058,
+ 0xbba0, 0x2021, 0x0006, 0x080c, 0x4bb4, 0x004e, 0x003e, 0x2001,
+ 0x0006, 0x080c, 0xcd34, 0x6610, 0x2658, 0xbe04, 0x0066, 0x96b4,
+ 0xff00, 0x8637, 0x9686, 0x0006, 0x006e, 0x0180, 0x2001, 0x0006,
+ 0x080c, 0x6320, 0x9284, 0x00ff, 0x908e, 0x0007, 0x0118, 0x908e,
+ 0x0004, 0x1120, 0x2001, 0x0006, 0x080c, 0x62f4, 0x080c, 0x66c1,
+ 0x11f8, 0x2001, 0x1836, 0x2004, 0xd0a4, 0x01d0, 0xbe04, 0x96b4,
+ 0x00ff, 0x9686, 0x0006, 0x01a0, 0x00f6, 0x2079, 0x1800, 0x78a4,
+ 0x8000, 0x78a6, 0x00fe, 0x0804, 0xcc80, 0x2001, 0x0004, 0x0030,
+ 0x2001, 0x0006, 0x0449, 0x0020, 0x0018, 0x0010, 0x080c, 0x6320,
+ 0x080c, 0x8a83, 0x080c, 0x9fea, 0x080c, 0x8b8f, 0x0005, 0x2600,
+ 0x0002, 0xcd2b, 0xcd2b, 0xcd2b, 0xcd2b, 0xcd2b, 0xcd2d, 0xcd2b,
+ 0xcd2b, 0xcd2b, 0xcd2b, 0xcd2d, 0xcd2b, 0xcd2b, 0xcd2b, 0xcd2d,
+ 0xcd2d, 0xcd2d, 0xcd2d, 0x080c, 0x0df6, 0x080c, 0x8a83, 0x080c,
+ 0x9fea, 0x080c, 0x8b8f, 0x0005, 0x0016, 0x00b6, 0x00d6, 0x6110,
+ 0x2158, 0xb900, 0xd184, 0x0138, 0x080c, 0x62f4, 0x9006, 0x080c,
+ 0x62e0, 0x080c, 0x30be, 0x00de, 0x00be, 0x001e, 0x0005, 0x6610,
+ 0x2658, 0xb804, 0x9084, 0xff00, 0x8007, 0x90b2, 0x000c, 0x1a0c,
+ 0x0df6, 0x91b6, 0x0015, 0x1110, 0x003b, 0x0028, 0x91b6, 0x0016,
+ 0x190c, 0x0df6, 0x006b, 0x0005, 0xaa88, 0xaa88, 0xaa88, 0xaa88,
+ 0xcdc9, 0xaa88, 0xcdb3, 0xcd74, 0xaa88, 0xaa88, 0xaa88, 0xaa88,
+ 0xaa88, 0xaa88, 0xaa88, 0xaa88, 0xcdc9, 0xaa88, 0xcdb3, 0xcdba,
+ 0xaa88, 0xaa88, 0xaa88, 0xaa88, 0x00f6, 0x080c, 0x66c1, 0x11d8,
+ 0x080c, 0xc459, 0x11c0, 0x6010, 0x905d, 0x01a8, 0xb8b0, 0x9005,
+ 0x0190, 0x9006, 0x080c, 0x62e0, 0x2001, 0x0002, 0x080c, 0x62f4,
+ 0x6023, 0x0001, 0x6003, 0x0001, 0x6007, 0x0002, 0x080c, 0x8640,
+ 0x080c, 0x8b8f, 0x00f0, 0x2011, 0x0263, 0x2204, 0x8211, 0x220c,
+ 0x080c, 0x266d, 0x11b0, 0x080c, 0x63a3, 0x0118, 0x080c, 0x9fea,
+ 0x0080, 0xb810, 0x0006, 0xb814, 0x0006, 0xb8b0, 0x0006, 0x080c,
+ 0x5e49, 0x000e, 0xb8b2, 0x000e, 0xb816, 0x000e, 0xb812, 0x080c,
+ 0x9fea, 0x00fe, 0x0005, 0x6604, 0x96b6, 0x001e, 0x1110, 0x080c,
+ 0x9fea, 0x0005, 0x080c, 0xae8a, 0x1148, 0x6003, 0x0001, 0x6007,
+ 0x0001, 0x080c, 0x8640, 0x080c, 0x8b8f, 0x0010, 0x080c, 0x9fea,
+ 0x0005, 0x0804, 0x9fea, 0x6004, 0x908a, 0x0053, 0x1a0c, 0x0df6,
+ 0x080c, 0x8a83, 0x080c, 0xa01c, 0x080c, 0x8b8f, 0x0005, 0x9182,
+ 0x0040, 0x0002, 0xcdee, 0xcdee, 0xcdee, 0xcdee, 0xcdf0, 0xcdee,
+ 0xcdee, 0xcdee, 0xcdee, 0xcdee, 0xcdee, 0xcdee, 0xcdee, 0xcdee,
+ 0xcdee, 0xcdee, 0xcdee, 0xcdee, 0xcdee, 0xcdee, 0x080c, 0x0df6,
+ 0x0096, 0x00b6, 0x00d6, 0x00e6, 0x00f6, 0x0046, 0x0026, 0x6210,
+ 0x2258, 0xb8ac, 0x9005, 0x11a8, 0x6106, 0x2071, 0x0260, 0x7444,
+ 0x94a4, 0xff00, 0x0904, 0xce56, 0x080c, 0xdb44, 0x1170, 0x9486,
+ 0x2000, 0x1158, 0x2009, 0x0001, 0x2011, 0x0200, 0x080c, 0x8450,
+ 0x0020, 0x9026, 0x080c, 0xda78, 0x0c38, 0x080c, 0x1037, 0x090c,
+ 0x0df6, 0x6003, 0x0007, 0xa867, 0x010d, 0x9006, 0xa802, 0xa86a,
+ 0xac8a, 0x2c00, 0xa88e, 0x6008, 0xa8e2, 0x6010, 0x2058, 0xb8a0,
+ 0x7130, 0xa97a, 0x0016, 0xa876, 0xa87f, 0x0000, 0xa883, 0x0000,
+ 0xa887, 0x0036, 0x080c, 0x6a22, 0x001e, 0x080c, 0xdb44, 0x1904,
+ 0xceb6, 0x9486, 0x2000, 0x1130, 0x2019, 0x0017, 0x080c, 0xd7af,
+ 0x0804, 0xceb6, 0x9486, 0x0200, 0x1120, 0x080c, 0xd746, 0x0804,
+ 0xceb6, 0x9486, 0x0400, 0x0120, 0x9486, 0x1000, 0x1904, 0xceb6,
+ 0x2019, 0x0002, 0x080c, 0xd761, 0x0804, 0xceb6, 0x2069, 0x1a4c,
+ 0x6a00, 0xd284, 0x0904, 0xcf20, 0x9284, 0x0300, 0x1904, 0xcf19,
+ 0x6804, 0x9005, 0x0904, 0xcf01, 0x2d78, 0x6003, 0x0007, 0x080c,
+ 0x1050, 0x0904, 0xcec2, 0x7800, 0xd08c, 0x1118, 0x7804, 0x8001,
+ 0x7806, 0x6017, 0x0000, 0x2001, 0x180f, 0x2004, 0xd084, 0x1904,
+ 0xcf24, 0x9006, 0xa802, 0xa867, 0x0116, 0xa86a, 0x6008, 0xa8e2,
+ 0x2c00, 0xa87a, 0x6010, 0x2058, 0xb8a0, 0x7130, 0xa9b6, 0xa876,
+ 0xb928, 0xa9ba, 0xb92c, 0xa9be, 0xb930, 0xa9c2, 0xb934, 0xa9c6,
+ 0xa883, 0x003d, 0x7044, 0x9084, 0x0003, 0x9080, 0xcebe, 0x2005,
+ 0xa87e, 0x20a9, 0x000a, 0x2001, 0x0270, 0xaa5c, 0x9290, 0x0021,
+ 0x2009, 0x0205, 0x200b, 0x0080, 0x20e1, 0x0000, 0xab60, 0x23e8,
+ 0x2098, 0x22a0, 0x4003, 0x200b, 0x0000, 0x2001, 0x027a, 0x200c,
+ 0xa9b2, 0x8000, 0x200c, 0xa9ae, 0x080c, 0x6a22, 0x002e, 0x004e,
+ 0x00fe, 0x00ee, 0x00de, 0x00be, 0x009e, 0x0005, 0x0000, 0x0080,
+ 0x0040, 0x0000, 0x2001, 0x1810, 0x2004, 0xd084, 0x0120, 0x080c,
+ 0x1037, 0x1904, 0xce6b, 0x6017, 0xf100, 0x6003, 0x0001, 0x6007,
+ 0x0041, 0x080c, 0x85f8, 0x080c, 0x8b8f, 0x0c00, 0x2069, 0x0260,
+ 0x6848, 0x9084, 0xff00, 0x9086, 0x1200, 0x1198, 0x686c, 0x9084,
+ 0x00ff, 0x0016, 0x6114, 0x918c, 0xf700, 0x910d, 0x6116, 0x001e,
+ 0x6003, 0x0001, 0x6007, 0x0043, 0x080c, 0x85f8, 0x080c, 0x8b8f,
+ 0x0828, 0x6868, 0x602e, 0x686c, 0x6032, 0x6017, 0xf200, 0x6003,
+ 0x0001, 0x6007, 0x0041, 0x080c, 0x85f8, 0x080c, 0x8b8f, 0x0804,
+ 0xceb6, 0x2001, 0x180e, 0x2004, 0xd0ec, 0x0120, 0x2011, 0x8049,
+ 0x080c, 0x4a17, 0x6017, 0xf300, 0x0010, 0x6017, 0xf100, 0x6003,
+ 0x0001, 0x6007, 0x0041, 0x080c, 0x85f8, 0x080c, 0x8b8f, 0x0804,
+ 0xceb6, 0x6017, 0xf500, 0x0c98, 0x6017, 0xf600, 0x0804, 0xced6,
+ 0x6017, 0xf200, 0x0804, 0xced6, 0xa867, 0x0146, 0xa86b, 0x0000,
+ 0x6008, 0xa886, 0x2c00, 0xa87a, 0x7044, 0x9084, 0x0003, 0x9080,
+ 0xcebe, 0x2005, 0xa87e, 0x2928, 0x6010, 0x2058, 0xb8a0, 0xa876,
+ 0xb828, 0xa88a, 0xb82c, 0xa88e, 0xb830, 0xa892, 0xb834, 0xa896,
+ 0xa883, 0x003d, 0x2009, 0x0205, 0x2104, 0x9085, 0x0080, 0x200a,
+ 0x20e1, 0x0000, 0x2011, 0x0210, 0x2214, 0x9294, 0x0fff, 0xaaa2,
+ 0x9282, 0x0111, 0x1a0c, 0x0df6, 0x8210, 0x821c, 0x2001, 0x026c,
+ 0x2098, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0029, 0x20a0, 0x2011,
+ 0xcfa0, 0x2041, 0x0001, 0x223d, 0x9784, 0x00ff, 0x9322, 0x1208,
+ 0x2300, 0x20a8, 0x4003, 0x931a, 0x0530, 0x8210, 0xd7fc, 0x1130,
+ 0x8d68, 0x2d0a, 0x2001, 0x0260, 0x2098, 0x0c68, 0x2950, 0x080c,
+ 0x1050, 0x0170, 0x2900, 0xb002, 0xa867, 0x0147, 0xa86b, 0x0000,
+ 0xa860, 0x20e8, 0xa85c, 0x9080, 0x001b, 0x20a0, 0x8840, 0x08d8,
+ 0x2548, 0xa800, 0x902d, 0x0118, 0x080c, 0x1069, 0x0cc8, 0x080c,
+ 0x1069, 0x0804, 0xcec2, 0x2548, 0x8847, 0x9885, 0x0046, 0xa866,
+ 0x2009, 0x0205, 0x200b, 0x0000, 0x080c, 0xd7e2, 0x0804, 0xceb6,
+ 0x8010, 0x0004, 0x801a, 0x0006, 0x8018, 0x0008, 0x8016, 0x000a,
+ 0x8014, 0x9186, 0x0013, 0x1160, 0x6004, 0x908a, 0x0054, 0x1a0c,
+ 0x0df6, 0x9082, 0x0040, 0x0a0c, 0x0df6, 0x2008, 0x0804, 0xd02f,
+ 0x9186, 0x0051, 0x0108, 0x0048, 0x080c, 0xc47f, 0x0500, 0x6000,
+ 0x9086, 0x0002, 0x11e0, 0x0804, 0xd078, 0x9186, 0x0027, 0x0190,
+ 0x9186, 0x0048, 0x0128, 0x9186, 0x0014, 0x0160, 0x190c, 0x0df6,
+ 0x080c, 0xc47f, 0x0160, 0x6000, 0x9086, 0x0004, 0x190c, 0x0df6,
+ 0x0804, 0xd15b, 0x6004, 0x9082, 0x0040, 0x2008, 0x001a, 0x080c,
+ 0xa083, 0x0005, 0xcff6, 0xcff8, 0xcff8, 0xd01f, 0xcff6, 0xcff6,
+ 0xcff6, 0xcff6, 0xcff6, 0xcff6, 0xcff6, 0xcff6, 0xcff6, 0xcff6,
+ 0xcff6, 0xcff6, 0xcff6, 0xcff6, 0xcff6, 0xcff6, 0x080c, 0x0df6,
+ 0x080c, 0x8a83, 0x080c, 0x8b8f, 0x0036, 0x0096, 0x6014, 0x904d,
+ 0x01d8, 0x080c, 0xbd4e, 0x01c0, 0x6003, 0x0002, 0x6010, 0x00b6,
+ 0x2058, 0xb800, 0x00be, 0xd0bc, 0x1178, 0x2019, 0x0004, 0x080c,
+ 0xd7e2, 0x6017, 0x0000, 0x6018, 0x9005, 0x1120, 0x2001, 0x1961,
+ 0x2004, 0x601a, 0x6003, 0x0007, 0x009e, 0x003e, 0x0005, 0x0096,
+ 0x080c, 0x8a83, 0x080c, 0x8b8f, 0x080c, 0xbd4e, 0x0120, 0x6014,
+ 0x2048, 0x080c, 0x1069, 0x080c, 0xa01c, 0x009e, 0x0005, 0x0002,
+ 0xd044, 0xd05b, 0xd046, 0xd072, 0xd044, 0xd044, 0xd044, 0xd044,
+ 0xd044, 0xd044, 0xd044, 0xd044, 0xd044, 0xd044, 0xd044, 0xd044,
+ 0xd044, 0xd044, 0xd044, 0xd044, 0x080c, 0x0df6, 0x0096, 0x080c,
+ 0x8a83, 0x6014, 0x2048, 0xa87c, 0xd0b4, 0x0138, 0x6003, 0x0007,
+ 0x2009, 0x0043, 0x080c, 0xa068, 0x0010, 0x6003, 0x0004, 0x080c,
+ 0x8b8f, 0x009e, 0x0005, 0x080c, 0x8a83, 0x080c, 0xbd4e, 0x0138,
+ 0x6114, 0x0096, 0x2148, 0xa97c, 0x009e, 0xd1ec, 0x1138, 0x080c,
+ 0x8425, 0x080c, 0x9fea, 0x080c, 0x8b8f, 0x0005, 0x080c, 0xda3c,
+ 0x0db0, 0x0cc8, 0x080c, 0x8a83, 0x2009, 0x0041, 0x0804, 0xd1e3,
+ 0x9182, 0x0040, 0x0002, 0xd08f, 0xd091, 0xd08f, 0xd08f, 0xd08f,
+ 0xd08f, 0xd08f, 0xd08f, 0xd08f, 0xd08f, 0xd08f, 0xd08f, 0xd08f,
+ 0xd08f, 0xd08f, 0xd08f, 0xd08f, 0xd092, 0xd08f, 0xd08f, 0x080c,
+ 0x0df6, 0x0005, 0x00d6, 0x080c, 0x8425, 0x00de, 0x080c, 0xda94,
+ 0x080c, 0x9fea, 0x0005, 0x9182, 0x0040, 0x0002, 0xd0b2, 0xd0b2,
+ 0xd0b2, 0xd0b2, 0xd0b2, 0xd0b2, 0xd0b2, 0xd0b2, 0xd0b2, 0xd0b4,
+ 0xd123, 0xd0b2, 0xd0b2, 0xd0b2, 0xd0b2, 0xd123, 0xd0b2, 0xd0b2,
+ 0xd0b2, 0xd0b2, 0x080c, 0x0df6, 0x2001, 0x0105, 0x2004, 0x9084,
+ 0x1800, 0x01c8, 0x2001, 0x0132, 0x200c, 0x2001, 0x0131, 0x2004,
+ 0x9105, 0x1904, 0xd123, 0x2009, 0x180c, 0x2104, 0xd0d4, 0x0904,
+ 0xd123, 0xc0d4, 0x200a, 0x2009, 0x0105, 0x2104, 0x9084, 0xe7fd,
+ 0x9085, 0x0010, 0x200a, 0x2001, 0x187b, 0x2004, 0xd0e4, 0x1528,
+ 0x603b, 0x0000, 0x080c, 0x8b3f, 0x6014, 0x0096, 0x2048, 0xa87c,
+ 0xd0fc, 0x0188, 0x908c, 0x0003, 0x918e, 0x0002, 0x0508, 0x2001,
+ 0x180c, 0x2004, 0xd0d4, 0x11e0, 0x080c, 0x8c6c, 0x2009, 0x0041,
+ 0x009e, 0x0804, 0xd1e3, 0x080c, 0x8c6c, 0x6003, 0x0007, 0x601b,
+ 0x0000, 0x080c, 0x8425, 0x009e, 0x0005, 0x2001, 0x0100, 0x2004,
+ 0x9082, 0x0005, 0x0aa8, 0x2001, 0x011f, 0x2004, 0x603a, 0x0890,
+ 0x2001, 0x180c, 0x200c, 0xc1d4, 0x2102, 0xd1cc, 0x0110, 0x080c,
+ 0x2ab1, 0x080c, 0x8c6c, 0x6014, 0x2048, 0xa97c, 0xd1ec, 0x1130,
+ 0x080c, 0x8425, 0x080c, 0x9fea, 0x009e, 0x0005, 0x080c, 0xda3c,
+ 0x0db8, 0x009e, 0x0005, 0x2001, 0x180c, 0x200c, 0xc1d4, 0x2102,
+ 0x0036, 0x080c, 0x8b3f, 0x080c, 0x8c6c, 0x6014, 0x0096, 0x2048,
+ 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x0188, 0xa87c,
+ 0x9084, 0x0003, 0x9086, 0x0002, 0x0140, 0xa8ac, 0x6330, 0x931a,
+ 0x6332, 0xa8b0, 0x632c, 0x931b, 0x632e, 0x6003, 0x0002, 0x0080,
+ 0x2019, 0x0004, 0x080c, 0xd7e2, 0x6018, 0x9005, 0x1128, 0x2001,
+ 0x1961, 0x2004, 0x8003, 0x601a, 0x6017, 0x0000, 0x6003, 0x0007,
+ 0x009e, 0x003e, 0x0005, 0x9182, 0x0040, 0x0002, 0xd172, 0xd172,
+ 0xd172, 0xd172, 0xd172, 0xd172, 0xd172, 0xd172, 0xd174, 0xd172,
+ 0xd172, 0xd172, 0xd172, 0xd172, 0xd172, 0xd172, 0xd172, 0xd172,
+ 0xd172, 0xd1bf, 0x080c, 0x0df6, 0x6014, 0x0096, 0x2048, 0xa834,
+ 0xaa38, 0x6110, 0x00b6, 0x2158, 0xb900, 0x00be, 0xd1bc, 0x1190,
+ 0x920d, 0x1518, 0xa87c, 0xd0fc, 0x0128, 0x2009, 0x0041, 0x009e,
+ 0x0804, 0xd1e3, 0x6003, 0x0007, 0x601b, 0x0000, 0x080c, 0x8425,
+ 0x009e, 0x0005, 0x6124, 0xd1f4, 0x1d58, 0x0006, 0x0046, 0xacac,
+ 0x9422, 0xa9b0, 0x2200, 0x910b, 0x6030, 0x9420, 0x6432, 0x602c,
+ 0x9109, 0x612e, 0x004e, 0x000e, 0x08d8, 0x6110, 0x00b6, 0x2158,
+ 0xb900, 0x00be, 0xd1bc, 0x1178, 0x2009, 0x180e, 0x210c, 0xd19c,
+ 0x0118, 0x6003, 0x0007, 0x0010, 0x6003, 0x0006, 0x00e9, 0x080c,
+ 0x8427, 0x009e, 0x0005, 0x6003, 0x0002, 0x009e, 0x0005, 0x6024,
+ 0xd0f4, 0x0128, 0x080c, 0x1577, 0x1904, 0xd174, 0x0005, 0x6014,
+ 0x0096, 0x2048, 0xa834, 0xa938, 0x009e, 0x9105, 0x1120, 0x080c,
+ 0x1577, 0x1904, 0xd174, 0x0005, 0xd2fc, 0x0140, 0x8002, 0x8000,
+ 0x8212, 0x9291, 0x0000, 0x2009, 0x0009, 0x0010, 0x2009, 0x0015,
+ 0xaa9a, 0xa896, 0x0005, 0x9182, 0x0040, 0x0208, 0x0062, 0x9186,
+ 0x0013, 0x0120, 0x9186, 0x0014, 0x190c, 0x0df6, 0x6024, 0xd0dc,
+ 0x090c, 0x0df6, 0x0005, 0xd207, 0xd213, 0xd21f, 0xd22b, 0xd207,
+ 0xd207, 0xd207, 0xd207, 0xd20e, 0xd209, 0xd209, 0xd207, 0xd207,
+ 0xd207, 0xd207, 0xd209, 0xd207, 0xd209, 0xd207, 0xd20e, 0x080c,
+ 0x0df6, 0x6024, 0xd0dc, 0x090c, 0x0df6, 0x0005, 0x6014, 0x9005,
+ 0x190c, 0x0df6, 0x0005, 0x6003, 0x0001, 0x6106, 0x080c, 0x85f8,
+ 0x0126, 0x2091, 0x8000, 0x080c, 0x8b8f, 0x012e, 0x0005, 0x6003,
+ 0x0001, 0x6106, 0x080c, 0x85f8, 0x0126, 0x2091, 0x8000, 0x080c,
+ 0x8b8f, 0x012e, 0x0005, 0x6003, 0x0003, 0x6106, 0x2c10, 0x080c,
+ 0x1a7e, 0x0126, 0x2091, 0x8000, 0x080c, 0x865d, 0x080c, 0x8c6c,
+ 0x012e, 0x0005, 0x0126, 0x2091, 0x8000, 0x0036, 0x0096, 0x9182,
+ 0x0040, 0x0023, 0x009e, 0x003e, 0x012e, 0x0005, 0xd25a, 0xd25c,
+ 0xd26e, 0xd288, 0xd25a, 0xd25a, 0xd25a, 0xd25a, 0xd25a, 0xd25a,
+ 0xd25a, 0xd25a, 0xd25a, 0xd25a, 0xd25a, 0xd25a, 0xd25a, 0xd25a,
+ 0xd25a, 0xd25a, 0x080c, 0x0df6, 0x6014, 0x2048, 0xa87c, 0xd0fc,
+ 0x01f8, 0x909c, 0x0003, 0x939e, 0x0003, 0x01d0, 0x6003, 0x0001,
+ 0x6106, 0x080c, 0x85f8, 0x080c, 0x8b8f, 0x0470, 0x6014, 0x2048,
+ 0xa87c, 0xd0fc, 0x0168, 0x909c, 0x0003, 0x939e, 0x0003, 0x0140,
+ 0x6003, 0x0001, 0x6106, 0x080c, 0x85f8, 0x080c, 0x8b8f, 0x00e0,
+ 0x901e, 0x6316, 0x631a, 0x2019, 0x0004, 0x080c, 0xd7e2, 0x00a0,
+ 0x6014, 0x2048, 0xa87c, 0xd0fc, 0x0d98, 0x909c, 0x0003, 0x939e,
+ 0x0003, 0x0d70, 0x6003, 0x0003, 0x6106, 0x2c10, 0x080c, 0x1a7e,
+ 0x080c, 0x865d, 0x080c, 0x8c6c, 0x0005, 0x080c, 0x8a83, 0x6114,
+ 0x81ff, 0x0158, 0x0096, 0x2148, 0x080c, 0xdae1, 0x0036, 0x2019,
+ 0x0029, 0x080c, 0xd7e2, 0x003e, 0x009e, 0x080c, 0xa01c, 0x080c,
+ 0x8b8f, 0x0005, 0x080c, 0x8b3f, 0x6114, 0x81ff, 0x0158, 0x0096,
+ 0x2148, 0x080c, 0xdae1, 0x0036, 0x2019, 0x0029, 0x080c, 0xd7e2,
+ 0x003e, 0x009e, 0x080c, 0xa01c, 0x080c, 0x8c6c, 0x0005, 0x9182,
+ 0x0085, 0x0002, 0xd2d9, 0xd2d7, 0xd2d7, 0xd2e5, 0xd2d7, 0xd2d7,
+ 0xd2d7, 0xd2d7, 0xd2d7, 0xd2d7, 0xd2d7, 0xd2d7, 0xd2d7, 0x080c,
+ 0x0df6, 0x6003, 0x000b, 0x6106, 0x080c, 0x85f8, 0x0126, 0x2091,
+ 0x8000, 0x080c, 0x8b8f, 0x012e, 0x0005, 0x0026, 0x00e6, 0x080c,
+ 0xda33, 0x0118, 0x080c, 0x9fea, 0x0450, 0x2071, 0x0260, 0x7224,
+ 0x6216, 0x2001, 0x180e, 0x2004, 0xd0e4, 0x0150, 0x6010, 0x00b6,
+ 0x2058, 0xbca0, 0x00be, 0x2c00, 0x2011, 0x014e, 0x080c, 0xa30b,
+ 0x7220, 0x080c, 0xd637, 0x0118, 0x6007, 0x0086, 0x0040, 0x6007,
+ 0x0087, 0x7224, 0x9296, 0xffff, 0x1110, 0x6007, 0x0086, 0x6003,
+ 0x0001, 0x080c, 0x85f8, 0x080c, 0x8b8f, 0x080c, 0x8c6c, 0x00ee,
+ 0x002e, 0x0005, 0x9186, 0x0013, 0x1160, 0x6004, 0x908a, 0x0085,
+ 0x0a0c, 0x0df6, 0x908a, 0x0092, 0x1a0c, 0x0df6, 0x9082, 0x0085,
+ 0x00a2, 0x9186, 0x0027, 0x0130, 0x9186, 0x0014, 0x0118, 0x080c,
+ 0xa083, 0x0050, 0x2001, 0x0007, 0x080c, 0x6320, 0x080c, 0x8a83,
+ 0x080c, 0xa01c, 0x080c, 0x8b8f, 0x0005, 0xd34a, 0xd34c, 0xd34c,
+ 0xd34a, 0xd34a, 0xd34a, 0xd34a, 0xd34a, 0xd34a, 0xd34a, 0xd34a,
+ 0xd34a, 0xd34a, 0x080c, 0x0df6, 0x080c, 0x8a83, 0x080c, 0xa01c,
+ 0x080c, 0x8b8f, 0x0005, 0x9182, 0x0085, 0x0a0c, 0x0df6, 0x9182,
+ 0x0092, 0x1a0c, 0x0df6, 0x9182, 0x0085, 0x0002, 0xd36b, 0xd36b,
+ 0xd36b, 0xd36d, 0xd36b, 0xd36b, 0xd36b, 0xd36b, 0xd36b, 0xd36b,
+ 0xd36b, 0xd36b, 0xd36b, 0x080c, 0x0df6, 0x0005, 0x9186, 0x0013,
+ 0x0148, 0x9186, 0x0014, 0x0130, 0x9186, 0x0027, 0x0118, 0x080c,
+ 0xa083, 0x0030, 0x080c, 0x8a83, 0x080c, 0xa01c, 0x080c, 0x8b8f,
+ 0x0005, 0x0036, 0x080c, 0xda94, 0x6043, 0x0000, 0x2019, 0x000b,
+ 0x0031, 0x6023, 0x0006, 0x6003, 0x0007, 0x003e, 0x0005, 0x0126,
+ 0x0036, 0x2091, 0x8000, 0x0086, 0x2c40, 0x0096, 0x904e, 0x080c,
+ 0x995f, 0x009e, 0x008e, 0x1550, 0x0076, 0x2c38, 0x080c, 0x9a0a,
+ 0x007e, 0x1520, 0x6000, 0x9086, 0x0000, 0x0500, 0x6020, 0x9086,
+ 0x0007, 0x01e0, 0x0096, 0x601c, 0xd084, 0x0140, 0x080c, 0xda94,
+ 0x080c, 0xc471, 0x080c, 0x192c, 0x6023, 0x0007, 0x6014, 0x2048,
+ 0x080c, 0xbd4e, 0x0110, 0x080c, 0xd7e2, 0x009e, 0x6017, 0x0000,
+ 0x080c, 0xda94, 0x6023, 0x0007, 0x080c, 0xc471, 0x003e, 0x012e,
+ 0x0005, 0x00f6, 0x00c6, 0x00b6, 0x0036, 0x0156, 0x2079, 0x0260,
+ 0x7938, 0x783c, 0x080c, 0x266d, 0x1904, 0xd41f, 0x0016, 0x00c6,
+ 0x080c, 0x63a3, 0x1904, 0xd41d, 0x001e, 0x00c6, 0x080c, 0xc459,
+ 0x1130, 0xb8b0, 0x9005, 0x0118, 0x080c, 0x31e9, 0x0148, 0x2b10,
+ 0x2160, 0x6010, 0x0006, 0x6212, 0x080c, 0xc460, 0x000e, 0x6012,
+ 0x00ce, 0x002e, 0x0026, 0x0016, 0x2019, 0x0029, 0x080c, 0x9ad0,
+ 0x080c, 0x8782, 0x0076, 0x903e, 0x080c, 0x8670, 0x007e, 0x001e,
+ 0x0076, 0x903e, 0x080c, 0xd556, 0x007e, 0x0026, 0xba04, 0x9294,
+ 0xff00, 0x8217, 0x9286, 0x0006, 0x0118, 0x9286, 0x0004, 0x1118,
+ 0xbaa0, 0x080c, 0x3152, 0x002e, 0xbcb0, 0x001e, 0x080c, 0x5e49,
+ 0xbe12, 0xbd16, 0xbcb2, 0x9006, 0x0010, 0x00ce, 0x001e, 0x015e,
+ 0x003e, 0x00be, 0x00ce, 0x00fe, 0x0005, 0x00c6, 0x00d6, 0x00b6,
+ 0x0016, 0x2009, 0x1823, 0x2104, 0x9086, 0x0074, 0x1904, 0xd47e,
+ 0x2069, 0x0260, 0x6944, 0x9182, 0x0100, 0x06e0, 0x6940, 0x9184,
+ 0x8000, 0x0904, 0xd47b, 0x2001, 0x1956, 0x2004, 0x9005, 0x1140,
+ 0x6010, 0x2058, 0xb8b0, 0x9005, 0x0118, 0x9184, 0x0800, 0x0598,
+ 0x6948, 0x918a, 0x0001, 0x0648, 0x080c, 0xdb49, 0x0118, 0x6978,
+ 0xd1fc, 0x11b8, 0x2009, 0x0205, 0x200b, 0x0001, 0x693c, 0x81ff,
+ 0x1198, 0x6944, 0x9182, 0x0100, 0x02a8, 0x6940, 0x81ff, 0x1178,
+ 0x6948, 0x918a, 0x0001, 0x0288, 0x6950, 0x918a, 0x0001, 0x0298,
+ 0x00d0, 0x6017, 0x0100, 0x00a0, 0x6017, 0x0300, 0x0088, 0x6017,
+ 0x0500, 0x0070, 0x6017, 0x0700, 0x0058, 0x6017, 0x0900, 0x0040,
+ 0x6017, 0x0b00, 0x0028, 0x6017, 0x0f00, 0x0010, 0x6017, 0x2d00,
+ 0x9085, 0x0001, 0x0008, 0x9006, 0x001e, 0x00be, 0x00de, 0x00ce,
+ 0x0005, 0x00c6, 0x00b6, 0x0026, 0x0036, 0x0156, 0x6210, 0x2258,
+ 0xbb04, 0x9394, 0x00ff, 0x9286, 0x0006, 0x0180, 0x9286, 0x0004,
+ 0x0168, 0x9394, 0xff00, 0x8217, 0x9286, 0x0006, 0x0138, 0x9286,
+ 0x0004, 0x0120, 0x080c, 0x63b2, 0x0804, 0xd4e5, 0x2011, 0x0276,
+ 0x20a9, 0x0004, 0x0096, 0x2b48, 0x2019, 0x000a, 0x080c, 0xb017,
+ 0x009e, 0x15a0, 0x2011, 0x027a, 0x20a9, 0x0004, 0x0096, 0x2b48,
+ 0x2019, 0x0006, 0x080c, 0xb017, 0x009e, 0x1540, 0x0046, 0x0016,
+ 0xbaa0, 0x2220, 0x9006, 0x2009, 0x185c, 0x210c, 0x0038, 0x2009,
+ 0x0029, 0x080c, 0xd837, 0xb800, 0xc0e5, 0xb802, 0x2019, 0x0029,
+ 0x080c, 0x8782, 0x0076, 0x2039, 0x0000, 0x080c, 0x8670, 0x2c08,
+ 0x080c, 0xd556, 0x007e, 0x2001, 0x0007, 0x080c, 0x6320, 0x2001,
+ 0x0007, 0x080c, 0x62f4, 0x001e, 0x004e, 0x9006, 0x015e, 0x003e,
+ 0x002e, 0x00be, 0x00ce, 0x0005, 0x00d6, 0x2069, 0x026e, 0x6800,
+ 0x9086, 0x0800, 0x0118, 0x6017, 0x0000, 0x0008, 0x9006, 0x00de,
+ 0x0005, 0x00b6, 0x00f6, 0x0016, 0x0026, 0x0036, 0x0156, 0x2079,
+ 0x026c, 0x7930, 0x7834, 0x080c, 0x266d, 0x11d0, 0x080c, 0x63a3,
+ 0x11b8, 0x2011, 0x0270, 0x20a9, 0x0004, 0x0096, 0x2b48, 0x2019,
+ 0x000a, 0x080c, 0xb017, 0x009e, 0x1158, 0x2011, 0x0274, 0x20a9,
+ 0x0004, 0x0096, 0x2b48, 0x2019, 0x0006, 0x080c, 0xb017, 0x009e,
+ 0x015e, 0x003e, 0x002e, 0x001e, 0x00fe, 0x00be, 0x0005, 0x00b6,
+ 0x0006, 0x0016, 0x0026, 0x0036, 0x0156, 0x2011, 0x0263, 0x2204,
+ 0x8211, 0x220c, 0x080c, 0x266d, 0x11d0, 0x080c, 0x63a3, 0x11b8,
+ 0x2011, 0x0276, 0x20a9, 0x0004, 0x0096, 0x2b48, 0x2019, 0x000a,
+ 0x080c, 0xb017, 0x009e, 0x1158, 0x2011, 0x027a, 0x20a9, 0x0004,
+ 0x0096, 0x2b48, 0x2019, 0x0006, 0x080c, 0xb017, 0x009e, 0x015e,
+ 0x003e, 0x002e, 0x001e, 0x000e, 0x00be, 0x0005, 0x00e6, 0x00c6,
+ 0x0086, 0x0076, 0x0066, 0x0056, 0x0046, 0x0026, 0x0126, 0x2091,
+ 0x8000, 0x2740, 0x2029, 0x19cb, 0x252c, 0x2021, 0x19d1, 0x2424,
+ 0x2061, 0x1cd0, 0x2071, 0x1800, 0x7650, 0x7070, 0x81ff, 0x0150,
+ 0x0006, 0x9186, 0x1a88, 0x000e, 0x0128, 0x8001, 0x9602, 0x1a04,
+ 0xd5f0, 0x0018, 0x9606, 0x0904, 0xd5f0, 0x2100, 0x9c06, 0x0904,
+ 0xd5e7, 0x6720, 0x9786, 0x0007, 0x0904, 0xd5e7, 0x080c, 0xd878,
+ 0x1904, 0xd5e7, 0x080c, 0xdb67, 0x0904, 0xd5e7, 0x080c, 0xd868,
+ 0x0904, 0xd5e7, 0x6720, 0x9786, 0x0001, 0x1148, 0x080c, 0x31e9,
+ 0x0904, 0xd60b, 0x6004, 0x9086, 0x0000, 0x1904, 0xd60b, 0x9786,
+ 0x0004, 0x0904, 0xd60b, 0x2500, 0x9c06, 0x0904, 0xd5e7, 0x2400,
+ 0x9c06, 0x05e8, 0x88ff, 0x0118, 0x6054, 0x9906, 0x15c0, 0x0096,
+ 0x6000, 0x9086, 0x0004, 0x1120, 0x0016, 0x080c, 0x192c, 0x001e,
+ 0x9786, 0x000a, 0x0148, 0x080c, 0xbf56, 0x1130, 0x080c, 0xa9a7,
+ 0x009e, 0x080c, 0xa01c, 0x0418, 0x6014, 0x2048, 0x080c, 0xbd4e,
+ 0x01d8, 0x9786, 0x0003, 0x1570, 0xa867, 0x0103, 0xa87c, 0xd0cc,
+ 0x0130, 0x0096, 0xa878, 0x2048, 0x080c, 0x0fe9, 0x009e, 0xab7a,
+ 0xa877, 0x0000, 0x080c, 0xdae1, 0x0016, 0x080c, 0xc044, 0x080c,
+ 0x6a15, 0x001e, 0x080c, 0xbf39, 0x009e, 0x080c, 0xa01c, 0x9ce0,
+ 0x0018, 0x2001, 0x1819, 0x2004, 0x9c02, 0x1210, 0x0804, 0xd56a,
+ 0x012e, 0x002e, 0x004e, 0x005e, 0x006e, 0x007e, 0x008e, 0x00ce,
+ 0x00ee, 0x0005, 0x9786, 0x0006, 0x1150, 0x9386, 0x0005, 0x0128,
+ 0x080c, 0xdae1, 0x080c, 0xd7e2, 0x08f8, 0x009e, 0x0c00, 0x9786,
+ 0x000a, 0x0968, 0x0808, 0x81ff, 0x09d0, 0x9180, 0x0001, 0x2004,
+ 0x9086, 0x0018, 0x0130, 0x9180, 0x0001, 0x2004, 0x9086, 0x002d,
+ 0x1970, 0x6000, 0x9086, 0x0002, 0x1950, 0x080c, 0xbf45, 0x0130,
+ 0x080c, 0xbf56, 0x1920, 0x080c, 0xa9a7, 0x0038, 0x080c, 0x30be,
+ 0x080c, 0xbf56, 0x1110, 0x080c, 0xa9a7, 0x080c, 0xa01c, 0x0804,
+ 0xd5e7, 0xa864, 0x9084, 0x00ff, 0x9086, 0x0039, 0x0005, 0x00c6,
+ 0x00e6, 0x0016, 0x2c08, 0x2170, 0x9006, 0x080c, 0xd809, 0x001e,
+ 0x0120, 0x6020, 0x9084, 0x000f, 0x001b, 0x00ee, 0x00ce, 0x0005,
+ 0xd656, 0xd656, 0xd656, 0xd656, 0xd656, 0xd656, 0xd658, 0xd656,
+ 0xd656, 0xd656, 0xd681, 0xa01c, 0xa01c, 0xd656, 0x9006, 0x0005,
+ 0x0036, 0x0046, 0x0016, 0x7010, 0x00b6, 0x2058, 0xbca0, 0x00be,
+ 0x2c00, 0x2009, 0x0020, 0x080c, 0xd837, 0x001e, 0x004e, 0x2019,
+ 0x0002, 0x080c, 0xd38f, 0x003e, 0x9085, 0x0001, 0x0005, 0x0096,
+ 0x080c, 0xbd4e, 0x0140, 0x6014, 0x904d, 0x080c, 0xb983, 0x687b,
+ 0x0005, 0x080c, 0x6a22, 0x009e, 0x080c, 0xa01c, 0x9085, 0x0001,
+ 0x0005, 0x0019, 0x9085, 0x0001, 0x0005, 0x6000, 0x908a, 0x0010,
+ 0x1a0c, 0x0df6, 0x000b, 0x0005, 0xd69c, 0xd69c, 0xd6b3, 0xd6a3,
+ 0xd6c2, 0xd69c, 0xd69c, 0xd69e, 0xd69c, 0xd69c, 0xd69c, 0xd69c,
+ 0xd69c, 0xd69c, 0xd69c, 0xd69c, 0x080c, 0x0df6, 0x080c, 0xa01c,
+ 0x9085, 0x0001, 0x0005, 0x0036, 0x00e6, 0x2071, 0x19c2, 0x703c,
+ 0x9c06, 0x1128, 0x2019, 0x0001, 0x080c, 0x98b1, 0x0010, 0x080c,
+ 0x9a8f, 0x00ee, 0x003e, 0x0096, 0x00d6, 0x6014, 0x2048, 0xa87b,
+ 0x0005, 0x080c, 0x6a22, 0x080c, 0xa01c, 0x00de, 0x009e, 0x9085,
+ 0x0001, 0x0005, 0x601c, 0xd084, 0x190c, 0x192c, 0x0c60, 0x2001,
+ 0x0001, 0x080c, 0x62e0, 0x0156, 0x0016, 0x0026, 0x0036, 0x20a9,
+ 0x0004, 0x2019, 0x1805, 0x2011, 0x0276, 0x080c, 0xb003, 0x003e,
+ 0x002e, 0x001e, 0x015e, 0x9005, 0x0005, 0x00f6, 0x00e6, 0x00c6,
+ 0x0086, 0x0076, 0x0066, 0x00b6, 0x0126, 0x2091, 0x8000, 0x2740,
+ 0x2061, 0x1cd0, 0x2079, 0x0001, 0x8fff, 0x0904, 0xd739, 0x2071,
+ 0x1800, 0x7650, 0x7070, 0x8001, 0x9602, 0x1a04, 0xd739, 0x88ff,
+ 0x0120, 0x2800, 0x9c06, 0x15a0, 0x2078, 0x080c, 0xd868, 0x0580,
+ 0x2400, 0x9c06, 0x0568, 0x6720, 0x9786, 0x0006, 0x1548, 0x9786,
+ 0x0007, 0x0530, 0x88ff, 0x1150, 0xd58c, 0x1118, 0x6010, 0x9b06,
+ 0x11f8, 0xd584, 0x0118, 0x6054, 0x9106, 0x11d0, 0x0096, 0x601c,
+ 0xd084, 0x0140, 0x080c, 0xda94, 0x080c, 0xc471, 0x080c, 0x192c,
+ 0x6023, 0x0007, 0x6014, 0x2048, 0x080c, 0xbd4e, 0x0120, 0x0046,
+ 0x080c, 0xd7e2, 0x004e, 0x009e, 0x080c, 0xa01c, 0x88ff, 0x1198,
+ 0x9ce0, 0x0018, 0x2001, 0x1819, 0x2004, 0x9c02, 0x1210, 0x0804,
+ 0xd6ec, 0x9006, 0x012e, 0x00be, 0x006e, 0x007e, 0x008e, 0x00ce,
+ 0x00ee, 0x00fe, 0x0005, 0x98c5, 0x0001, 0x0ca0, 0x00b6, 0x0076,
+ 0x0056, 0x0086, 0x9046, 0x2029, 0x0001, 0x2c20, 0x2019, 0x0002,
+ 0x6210, 0x2258, 0x0096, 0x904e, 0x080c, 0x995f, 0x009e, 0x008e,
+ 0x903e, 0x080c, 0x9a0a, 0x080c, 0xd6dd, 0x005e, 0x007e, 0x00be,
+ 0x0005, 0x00b6, 0x0046, 0x0056, 0x0076, 0x00c6, 0x0156, 0x2c20,
+ 0x2128, 0x20a9, 0x007f, 0x900e, 0x0016, 0x0036, 0x080c, 0x63a3,
+ 0x1180, 0x0056, 0x0086, 0x9046, 0x2508, 0x2029, 0x0001, 0x0096,
+ 0x904e, 0x080c, 0x995f, 0x009e, 0x008e, 0x903e, 0x080c, 0x9a0a,
+ 0x005e, 0x003e, 0x001e, 0x8108, 0x1f04, 0xd76c, 0x0036, 0x2508,
+ 0x2029, 0x0003, 0x080c, 0xd6dd, 0x003e, 0x015e, 0x00ce, 0x007e,
+ 0x005e, 0x004e, 0x00be, 0x0005, 0x00b6, 0x0076, 0x0056, 0x6210,
+ 0x2258, 0x0086, 0x9046, 0x2029, 0x0001, 0x2019, 0x0048, 0x0096,
+ 0x904e, 0x080c, 0x995f, 0x009e, 0x008e, 0x903e, 0x080c, 0x9a0a,
+ 0x2c20, 0x080c, 0xd6dd, 0x005e, 0x007e, 0x00be, 0x0005, 0x00b6,
+ 0x0046, 0x0056, 0x0076, 0x00c6, 0x0156, 0x2c20, 0x20a9, 0x0800,
+ 0x900e, 0x0016, 0x0036, 0x080c, 0x63a3, 0x1190, 0x0086, 0x9046,
+ 0x2828, 0x0046, 0x2021, 0x0001, 0x080c, 0xda78, 0x004e, 0x0096,
+ 0x904e, 0x080c, 0x995f, 0x009e, 0x008e, 0x903e, 0x080c, 0x9a0a,
+ 0x003e, 0x001e, 0x8108, 0x1f04, 0xd7b9, 0x0036, 0x2029, 0x0002,
+ 0x080c, 0xd6dd, 0x003e, 0x015e, 0x00ce, 0x007e, 0x005e, 0x004e,
+ 0x00be, 0x0005, 0x0016, 0x00f6, 0x080c, 0xbd4c, 0x0198, 0xa864,
+ 0x9084, 0x00ff, 0x9086, 0x0046, 0x0180, 0xa800, 0x907d, 0x0138,
+ 0xa803, 0x0000, 0xab82, 0x080c, 0x6a22, 0x2f48, 0x0cb0, 0xab82,
+ 0x080c, 0x6a22, 0x00fe, 0x001e, 0x0005, 0xa800, 0x907d, 0x0130,
+ 0xa803, 0x0000, 0x080c, 0x6a22, 0x2f48, 0x0cb8, 0x080c, 0x6a22,
+ 0x0c88, 0x00e6, 0x0046, 0x0036, 0x2061, 0x1cd0, 0x9005, 0x1138,
+ 0x2071, 0x1800, 0x7450, 0x7070, 0x8001, 0x9402, 0x12d8, 0x2100,
+ 0x9c06, 0x0168, 0x6000, 0x9086, 0x0000, 0x0148, 0x6008, 0x9206,
+ 0x1130, 0x6010, 0x91a0, 0x0004, 0x2424, 0x9406, 0x0140, 0x9ce0,
+ 0x0018, 0x2001, 0x1819, 0x2004, 0x9c02, 0x1220, 0x0c40, 0x9085,
+ 0x0001, 0x0008, 0x9006, 0x003e, 0x004e, 0x00ee, 0x0005, 0x0096,
+ 0x0006, 0x080c, 0x1037, 0x000e, 0x090c, 0x0df6, 0xaae2, 0xa867,
+ 0x010d, 0xa88e, 0x0026, 0x2010, 0x080c, 0xbd3c, 0x2001, 0x0000,
+ 0x0120, 0x2200, 0x9080, 0x0015, 0x2004, 0x002e, 0xa87a, 0x9186,
+ 0x0020, 0x0110, 0xa8e3, 0xffff, 0xa986, 0xac76, 0xa87f, 0x0000,
+ 0x2001, 0x1968, 0x2004, 0xa882, 0x9006, 0xa802, 0xa86a, 0xa88a,
+ 0x0126, 0x2091, 0x8000, 0x080c, 0x6a22, 0x012e, 0x009e, 0x0005,
+ 0x6700, 0x9786, 0x0000, 0x0158, 0x9786, 0x0001, 0x0140, 0x9786,
+ 0x000a, 0x0128, 0x9786, 0x0009, 0x0110, 0x9085, 0x0001, 0x0005,
+ 0x00e6, 0x6010, 0x9075, 0x0138, 0x00b6, 0x2058, 0xb8a0, 0x00be,
+ 0x9206, 0x00ee, 0x0005, 0x9085, 0x0001, 0x0cd8, 0x0016, 0x6004,
+ 0x908e, 0x001e, 0x11a0, 0x8007, 0x6134, 0x918c, 0x00ff, 0x9105,
+ 0x6036, 0x6007, 0x0085, 0x6003, 0x000b, 0x6023, 0x0005, 0x2001,
+ 0x1961, 0x2004, 0x601a, 0x080c, 0x85f8, 0x080c, 0x8b8f, 0x001e,
+ 0x0005, 0xa001, 0xa001, 0x0005, 0x6024, 0xd0e4, 0x0158, 0xd0cc,
+ 0x0118, 0x080c, 0xc088, 0x0030, 0x080c, 0xda94, 0x080c, 0x8425,
+ 0x080c, 0x9fea, 0x0005, 0x9280, 0x0008, 0x2004, 0x9084, 0x000f,
+ 0x0002, 0xd8c7, 0xd8c7, 0xd8c7, 0xd8c9, 0xd8c7, 0xd8c9, 0xd8c9,
+ 0xd8c7, 0xd8c9, 0xd8c7, 0xd8c7, 0xd8c7, 0xd8c7, 0xd8c7, 0x9006,
+ 0x0005, 0x9085, 0x0001, 0x0005, 0x9280, 0x0008, 0x2004, 0x9084,
+ 0x000f, 0x0002, 0xd8e0, 0xd8e0, 0xd8e0, 0xd8e0, 0xd8e0, 0xd8e0,
+ 0xd8ed, 0xd8e0, 0xd8e0, 0xd8e0, 0xd8e0, 0xd8e0, 0xd8e0, 0xd8e0,
+ 0x6007, 0x003b, 0x602f, 0x0009, 0x6017, 0x2a00, 0x6003, 0x0001,
+ 0x080c, 0x85f8, 0x080c, 0x8b8f, 0x0005, 0x0096, 0x00c6, 0x2260,
+ 0x080c, 0xda94, 0x6043, 0x0000, 0x6024, 0xc0f4, 0xc0e4, 0x6026,
+ 0x603b, 0x0000, 0x00ce, 0x00d6, 0x2268, 0x9186, 0x0007, 0x1904,
+ 0xd946, 0x6814, 0x9005, 0x0138, 0x2048, 0xa87c, 0xd0fc, 0x1118,
+ 0x00de, 0x009e, 0x08a8, 0x6007, 0x003a, 0x6003, 0x0001, 0x080c,
+ 0x85f8, 0x080c, 0x8b8f, 0x00c6, 0x2d60, 0x6100, 0x9186, 0x0002,
+ 0x1904, 0xd9bd, 0x6014, 0x9005, 0x1138, 0x6000, 0x9086, 0x0007,
+ 0x190c, 0x0df6, 0x0804, 0xd9bd, 0x2048, 0x080c, 0xbd4e, 0x1130,
+ 0x0028, 0x2048, 0xa800, 0x9005, 0x1de0, 0x2900, 0x2048, 0xa87c,
+ 0x9084, 0x0003, 0x9086, 0x0002, 0x1168, 0xa87c, 0xc0dc, 0xc0f4,
+ 0xa87e, 0xa880, 0xc0fc, 0xa882, 0x2009, 0x0043, 0x080c, 0xd1e3,
+ 0x0804, 0xd9bd, 0x2009, 0x0041, 0x0804, 0xd9b7, 0x9186, 0x0005,
+ 0x15a0, 0x6814, 0x2048, 0xa87c, 0xd0bc, 0x1120, 0x00de, 0x009e,
+ 0x0804, 0xd8e0, 0xd0b4, 0x0128, 0xd0fc, 0x090c, 0x0df6, 0x0804,
+ 0xd901, 0x6007, 0x003a, 0x6003, 0x0001, 0x080c, 0x85f8, 0x080c,
+ 0x8b8f, 0x00c6, 0x2d60, 0x6100, 0x9186, 0x0002, 0x0120, 0x9186,
+ 0x0004, 0x1904, 0xd9bd, 0x6814, 0x2048, 0xa97c, 0xc1f4, 0xc1dc,
+ 0xa97e, 0xa980, 0xc1fc, 0xc1bc, 0xa982, 0x00f6, 0x2c78, 0x080c,
+ 0x1651, 0x00fe, 0x2009, 0x0042, 0x04d0, 0x0036, 0x080c, 0x1037,
+ 0x090c, 0x0df6, 0xa867, 0x010d, 0x9006, 0xa802, 0xa86a, 0xa88a,
+ 0x2d18, 0xab8e, 0xa887, 0x0045, 0x2c00, 0xa892, 0x6038, 0xa8a2,
+ 0x2360, 0x6024, 0xc0dd, 0x6026, 0x6010, 0x00b6, 0x2058, 0xb8a0,
+ 0x00be, 0x2004, 0x6354, 0xab7a, 0xa876, 0x9006, 0xa87e, 0xa882,
+ 0xad9a, 0xae96, 0xa89f, 0x0001, 0x080c, 0x6a22, 0x2019, 0x0045,
+ 0x6008, 0x2068, 0x080c, 0xd38f, 0x2d00, 0x600a, 0x6023, 0x0006,
+ 0x6003, 0x0007, 0x901e, 0x631a, 0x6342, 0x003e, 0x0038, 0x6043,
+ 0x0000, 0x6003, 0x0007, 0x080c, 0xd1e3, 0x00ce, 0x00de, 0x009e,
+ 0x0005, 0x9186, 0x0013, 0x1128, 0x6004, 0x9082, 0x0085, 0x2008,
+ 0x00c2, 0x9186, 0x0027, 0x1178, 0x080c, 0x8a83, 0x0036, 0x0096,
+ 0x6014, 0x2048, 0x2019, 0x0004, 0x080c, 0xd7e2, 0x009e, 0x003e,
+ 0x080c, 0x8b8f, 0x0005, 0x9186, 0x0014, 0x0d70, 0x080c, 0xa083,
+ 0x0005, 0xd9f0, 0xd9ee, 0xd9ee, 0xd9ee, 0xd9ee, 0xd9ee, 0xd9f0,
+ 0xd9ee, 0xd9ee, 0xd9ee, 0xd9ee, 0xd9ee, 0xd9ee, 0x080c, 0x0df6,
+ 0x080c, 0x8a83, 0x6003, 0x000c, 0x080c, 0x8b8f, 0x0005, 0x9182,
+ 0x0092, 0x1220, 0x9182, 0x0085, 0x0208, 0x001a, 0x080c, 0xa083,
+ 0x0005, 0xda0e, 0xda0e, 0xda0e, 0xda0e, 0xda10, 0xda30, 0xda0e,
+ 0xda0e, 0xda0e, 0xda0e, 0xda0e, 0xda0e, 0xda0e, 0x080c, 0x0df6,
+ 0x00d6, 0x2c68, 0x080c, 0x9f94, 0x01b0, 0x6003, 0x0001, 0x6007,
+ 0x001e, 0x2009, 0x026e, 0x210c, 0x613a, 0x2009, 0x026f, 0x210c,
+ 0x613e, 0x600b, 0xffff, 0x6910, 0x6112, 0x6023, 0x0004, 0x080c,
+ 0x85f8, 0x080c, 0x8b8f, 0x2d60, 0x080c, 0x9fea, 0x00de, 0x0005,
+ 0x080c, 0x9fea, 0x0005, 0x00e6, 0x6010, 0x00b6, 0x2058, 0xb800,
+ 0x00be, 0xd0ec, 0x00ee, 0x0005, 0x2009, 0x187b, 0x210c, 0xd1ec,
+ 0x05b0, 0x6003, 0x0002, 0x6024, 0xc0e5, 0x6026, 0xd0cc, 0x0150,
+ 0x2001, 0x1962, 0x2004, 0x6042, 0x2009, 0x187b, 0x210c, 0xd1f4,
+ 0x1520, 0x00a0, 0x2009, 0x187b, 0x210c, 0xd1f4, 0x0128, 0x6024,
+ 0xc0e4, 0x6026, 0x9006, 0x00d8, 0x2001, 0x1962, 0x200c, 0x2001,
+ 0x1960, 0x2004, 0x9100, 0x9080, 0x000a, 0x6042, 0x6010, 0x00b6,
+ 0x2058, 0xb8ac, 0x00be, 0x0008, 0x2104, 0x9005, 0x0118, 0x9088,
+ 0x0003, 0x0cd0, 0x2c0a, 0x600f, 0x0000, 0x9085, 0x0001, 0x0005,
+ 0x0016, 0x00c6, 0x00e6, 0x6154, 0xb8ac, 0x2060, 0x8cff, 0x0180,
+ 0x84ff, 0x1118, 0x6054, 0x9106, 0x1138, 0x600c, 0x2072, 0x080c,
+ 0x8425, 0x080c, 0x9fea, 0x0010, 0x9cf0, 0x0003, 0x2e64, 0x0c70,
+ 0x00ee, 0x00ce, 0x001e, 0x0005, 0x00d6, 0x00b6, 0x6010, 0x2058,
+ 0xb8ac, 0x906d, 0x0130, 0x9c06, 0x0110, 0x680c, 0x0cd0, 0x600c,
+ 0x680e, 0x00be, 0x00de, 0x0005, 0x0026, 0x0036, 0x0156, 0x2011,
+ 0x182b, 0x2204, 0x9084, 0x00ff, 0x2019, 0x026e, 0x2334, 0x96b4,
+ 0x00ff, 0x9636, 0x1508, 0x8318, 0x2334, 0x2204, 0x9084, 0xff00,
+ 0x9636, 0x11d0, 0x2011, 0x0270, 0x20a9, 0x0004, 0x6010, 0x0096,
+ 0x2048, 0x2019, 0x000a, 0x080c, 0xb017, 0x009e, 0x1168, 0x2011,
+ 0x0274, 0x20a9, 0x0004, 0x6010, 0x0096, 0x2048, 0x2019, 0x0006,
+ 0x080c, 0xb017, 0x009e, 0x1100, 0x015e, 0x003e, 0x002e, 0x0005,
+ 0x00e6, 0x2071, 0x1800, 0x080c, 0x5dc2, 0x080c, 0x2e73, 0x00ee,
+ 0x0005, 0x00e6, 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0fc,
+ 0x0108, 0x0011, 0x00ee, 0x0005, 0xa880, 0xc0e5, 0xa882, 0x0005,
+ 0x00e6, 0x00d6, 0x00c6, 0x0076, 0x0066, 0x0056, 0x0046, 0x0026,
+ 0x0016, 0x0126, 0x2091, 0x8000, 0x2029, 0x19cb, 0x252c, 0x2021,
+ 0x19d1, 0x2424, 0x2061, 0x1cd0, 0x2071, 0x1800, 0x7650, 0x7070,
+ 0x9606, 0x0578, 0x6720, 0x9786, 0x0001, 0x0118, 0x9786, 0x0008,
+ 0x1500, 0x2500, 0x9c06, 0x01e8, 0x2400, 0x9c06, 0x01d0, 0x080c,
+ 0xd868, 0x01b8, 0x080c, 0xd878, 0x11a0, 0x6000, 0x9086, 0x0004,
+ 0x1120, 0x0016, 0x080c, 0x192c, 0x001e, 0x080c, 0xbf45, 0x1110,
+ 0x080c, 0x30be, 0x080c, 0xbf56, 0x1110, 0x080c, 0xa9a7, 0x080c,
+ 0xa01c, 0x9ce0, 0x0018, 0x2001, 0x1819, 0x2004, 0x9c02, 0x1208,
+ 0x0858, 0x012e, 0x001e, 0x002e, 0x004e, 0x005e, 0x006e, 0x007e,
+ 0x00ce, 0x00de, 0x00ee, 0x0005, 0x2001, 0x1810, 0x2004, 0xd0dc,
+ 0x0005, 0x0006, 0x2001, 0x1836, 0x2004, 0xd09c, 0x000e, 0x0005,
+ 0x0006, 0x0036, 0x0046, 0x080c, 0xc459, 0x0168, 0x2019, 0xffff,
+ 0x9005, 0x0128, 0x6010, 0x00b6, 0x2058, 0xbba0, 0x00be, 0x2021,
+ 0x0004, 0x080c, 0x4bb4, 0x004e, 0x003e, 0x000e, 0x0005, 0x6004,
+ 0x9086, 0x0001, 0x1128, 0x080c, 0x9ad0, 0x080c, 0xa01c, 0x9006,
+ 0x0005, 0x00e6, 0x00c6, 0x00b6, 0x0046, 0x2061, 0x1cd0, 0x2071,
0x1800, 0x7450, 0x7070, 0x8001, 0x9402, 0x12d8, 0x2100, 0x9c06,
- 0x0168, 0x6000, 0x9086, 0x0000, 0x0148, 0x6008, 0x9206, 0x1130,
- 0x6010, 0x91a0, 0x0004, 0x2424, 0x9406, 0x0140, 0x9ce0, 0x0018,
+ 0x0168, 0x6000, 0x9086, 0x0000, 0x0148, 0x6010, 0x2058, 0xb8a0,
+ 0x9206, 0x1120, 0x6004, 0x9086, 0x0002, 0x0140, 0x9ce0, 0x0018,
0x2001, 0x1819, 0x2004, 0x9c02, 0x1220, 0x0c40, 0x9085, 0x0001,
- 0x0008, 0x9006, 0x003e, 0x004e, 0x00ee, 0x0005, 0x0096, 0x0006,
- 0x080c, 0x1043, 0x000e, 0x090c, 0x0e02, 0xaae2, 0xa867, 0x010d,
- 0xa88e, 0x0026, 0x2010, 0x080c, 0xbd29, 0x2001, 0x0000, 0x0120,
- 0x2200, 0x9080, 0x0015, 0x2004, 0x002e, 0xa87a, 0x9186, 0x0020,
- 0x0110, 0xa8e3, 0xffff, 0xa986, 0xac76, 0xa87f, 0x0000, 0x2001,
- 0x1968, 0x2004, 0xa882, 0x9006, 0xa802, 0xa86a, 0xa88a, 0x0126,
- 0x2091, 0x8000, 0x080c, 0x6a23, 0x012e, 0x009e, 0x0005, 0x6700,
- 0x9786, 0x0000, 0x0158, 0x9786, 0x0001, 0x0140, 0x9786, 0x000a,
- 0x0128, 0x9786, 0x0009, 0x0110, 0x9085, 0x0001, 0x0005, 0x00e6,
- 0x6010, 0x9075, 0x0138, 0x00b6, 0x2058, 0xb8a0, 0x00be, 0x9206,
- 0x00ee, 0x0005, 0x9085, 0x0001, 0x0cd8, 0x0016, 0x6004, 0x908e,
- 0x001e, 0x11a0, 0x8007, 0x6134, 0x918c, 0x00ff, 0x9105, 0x6036,
- 0x6007, 0x0085, 0x6003, 0x000b, 0x6023, 0x0005, 0x2001, 0x1961,
- 0x2004, 0x601a, 0x080c, 0x85f9, 0x080c, 0x8b90, 0x001e, 0x0005,
- 0xa001, 0xa001, 0x0005, 0x6024, 0xd0e4, 0x0158, 0xd0cc, 0x0118,
- 0x080c, 0xc075, 0x0030, 0x080c, 0xda33, 0x080c, 0x8426, 0x080c,
- 0x9fd5, 0x0005, 0x9280, 0x0008, 0x2004, 0x9084, 0x000f, 0x0002,
- 0xd866, 0xd866, 0xd866, 0xd868, 0xd866, 0xd868, 0xd868, 0xd866,
- 0xd868, 0xd866, 0xd866, 0xd866, 0xd866, 0xd866, 0x9006, 0x0005,
- 0x9085, 0x0001, 0x0005, 0x9280, 0x0008, 0x2004, 0x9084, 0x000f,
- 0x0002, 0xd87f, 0xd87f, 0xd87f, 0xd87f, 0xd87f, 0xd87f, 0xd88c,
- 0xd87f, 0xd87f, 0xd87f, 0xd87f, 0xd87f, 0xd87f, 0xd87f, 0x6007,
- 0x003b, 0x602f, 0x0009, 0x6017, 0x2a00, 0x6003, 0x0001, 0x080c,
- 0x85f9, 0x080c, 0x8b90, 0x0005, 0x0096, 0x00c6, 0x2260, 0x080c,
- 0xda33, 0x6043, 0x0000, 0x6024, 0xc0f4, 0xc0e4, 0x6026, 0x603b,
- 0x0000, 0x00ce, 0x00d6, 0x2268, 0x9186, 0x0007, 0x1904, 0xd8e5,
- 0x6814, 0x9005, 0x0138, 0x2048, 0xa87c, 0xd0fc, 0x1118, 0x00de,
- 0x009e, 0x08a8, 0x6007, 0x003a, 0x6003, 0x0001, 0x080c, 0x85f9,
- 0x080c, 0x8b90, 0x00c6, 0x2d60, 0x6100, 0x9186, 0x0002, 0x1904,
- 0xd95c, 0x6014, 0x9005, 0x1138, 0x6000, 0x9086, 0x0007, 0x190c,
- 0x0e02, 0x0804, 0xd95c, 0x2048, 0x080c, 0xbd3b, 0x1130, 0x0028,
- 0x2048, 0xa800, 0x9005, 0x1de0, 0x2900, 0x2048, 0xa87c, 0x9084,
- 0x0003, 0x9086, 0x0002, 0x1168, 0xa87c, 0xc0dc, 0xc0f4, 0xa87e,
- 0xa880, 0xc0fc, 0xa882, 0x2009, 0x0043, 0x080c, 0xd1d9, 0x0804,
- 0xd95c, 0x2009, 0x0041, 0x0804, 0xd956, 0x9186, 0x0005, 0x15a0,
- 0x6814, 0x2048, 0xa87c, 0xd0bc, 0x1120, 0x00de, 0x009e, 0x0804,
- 0xd87f, 0xd0b4, 0x0128, 0xd0fc, 0x090c, 0x0e02, 0x0804, 0xd8a0,
- 0x6007, 0x003a, 0x6003, 0x0001, 0x080c, 0x85f9, 0x080c, 0x8b90,
- 0x00c6, 0x2d60, 0x6100, 0x9186, 0x0002, 0x0120, 0x9186, 0x0004,
- 0x1904, 0xd95c, 0x6814, 0x2048, 0xa97c, 0xc1f4, 0xc1dc, 0xa97e,
- 0xa980, 0xc1fc, 0xc1bc, 0xa982, 0x00f6, 0x2c78, 0x080c, 0x165d,
- 0x00fe, 0x2009, 0x0042, 0x04d0, 0x0036, 0x080c, 0x1043, 0x090c,
- 0x0e02, 0xa867, 0x010d, 0x9006, 0xa802, 0xa86a, 0xa88a, 0x2d18,
- 0xab8e, 0xa887, 0x0045, 0x2c00, 0xa892, 0x6038, 0xa8a2, 0x2360,
- 0x6024, 0xc0dd, 0x6026, 0x6010, 0x00b6, 0x2058, 0xb8a0, 0x00be,
- 0x2004, 0x6354, 0xab7a, 0xa876, 0x9006, 0xa87e, 0xa882, 0xad9a,
- 0xae96, 0xa89f, 0x0001, 0x080c, 0x6a23, 0x2019, 0x0045, 0x6008,
- 0x2068, 0x080c, 0xd385, 0x2d00, 0x600a, 0x6023, 0x0006, 0x6003,
- 0x0007, 0x901e, 0x631a, 0x6342, 0x003e, 0x0038, 0x6043, 0x0000,
- 0x6003, 0x0007, 0x080c, 0xd1d9, 0x00ce, 0x00de, 0x009e, 0x0005,
- 0x9186, 0x0013, 0x1128, 0x6004, 0x9082, 0x0085, 0x2008, 0x00c2,
- 0x9186, 0x0027, 0x1178, 0x080c, 0x8a84, 0x0036, 0x0096, 0x6014,
- 0x2048, 0x2019, 0x0004, 0x080c, 0xd781, 0x009e, 0x003e, 0x080c,
- 0x8b90, 0x0005, 0x9186, 0x0014, 0x0d70, 0x080c, 0xa06e, 0x0005,
- 0xd98f, 0xd98d, 0xd98d, 0xd98d, 0xd98d, 0xd98d, 0xd98f, 0xd98d,
- 0xd98d, 0xd98d, 0xd98d, 0xd98d, 0xd98d, 0x080c, 0x0e02, 0x080c,
- 0x8a84, 0x6003, 0x000c, 0x080c, 0x8b90, 0x0005, 0x9182, 0x0092,
- 0x1220, 0x9182, 0x0085, 0x0208, 0x001a, 0x080c, 0xa06e, 0x0005,
- 0xd9ad, 0xd9ad, 0xd9ad, 0xd9ad, 0xd9af, 0xd9cf, 0xd9ad, 0xd9ad,
- 0xd9ad, 0xd9ad, 0xd9ad, 0xd9ad, 0xd9ad, 0x080c, 0x0e02, 0x00d6,
- 0x2c68, 0x080c, 0x9f7f, 0x01b0, 0x6003, 0x0001, 0x6007, 0x001e,
- 0x2009, 0x026e, 0x210c, 0x613a, 0x2009, 0x026f, 0x210c, 0x613e,
- 0x600b, 0xffff, 0x6910, 0x6112, 0x6023, 0x0004, 0x080c, 0x85f9,
- 0x080c, 0x8b90, 0x2d60, 0x080c, 0x9fd5, 0x00de, 0x0005, 0x080c,
- 0x9fd5, 0x0005, 0x00e6, 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be,
- 0xd0ec, 0x00ee, 0x0005, 0x2009, 0x187b, 0x210c, 0xd1ec, 0x05b0,
- 0x6003, 0x0002, 0x6024, 0xc0e5, 0x6026, 0xd0cc, 0x0150, 0x2001,
- 0x1962, 0x2004, 0x6042, 0x2009, 0x187b, 0x210c, 0xd1f4, 0x1520,
- 0x00a0, 0x2009, 0x187b, 0x210c, 0xd1f4, 0x0128, 0x6024, 0xc0e4,
- 0x6026, 0x9006, 0x00d8, 0x2001, 0x1962, 0x200c, 0x2001, 0x1960,
- 0x2004, 0x9100, 0x9080, 0x000a, 0x6042, 0x6010, 0x00b6, 0x2058,
- 0xb8ac, 0x00be, 0x0008, 0x2104, 0x9005, 0x0118, 0x9088, 0x0003,
- 0x0cd0, 0x2c0a, 0x600f, 0x0000, 0x9085, 0x0001, 0x0005, 0x0016,
- 0x00c6, 0x00e6, 0x6154, 0xb8ac, 0x2060, 0x8cff, 0x0180, 0x84ff,
- 0x1118, 0x6054, 0x9106, 0x1138, 0x600c, 0x2072, 0x080c, 0x8426,
- 0x080c, 0x9fd5, 0x0010, 0x9cf0, 0x0003, 0x2e64, 0x0c70, 0x00ee,
- 0x00ce, 0x001e, 0x0005, 0x00d6, 0x00b6, 0x6010, 0x2058, 0xb8ac,
- 0x906d, 0x0130, 0x9c06, 0x0110, 0x680c, 0x0cd0, 0x600c, 0x680e,
- 0x00be, 0x00de, 0x0005, 0x0026, 0x0036, 0x0156, 0x2011, 0x182b,
- 0x2204, 0x9084, 0x00ff, 0x2019, 0x026e, 0x2334, 0x96b4, 0x00ff,
- 0x9636, 0x1508, 0x8318, 0x2334, 0x2204, 0x9084, 0xff00, 0x9636,
- 0x11d0, 0x2011, 0x0270, 0x20a9, 0x0004, 0x6010, 0x0096, 0x2048,
- 0x2019, 0x000a, 0x080c, 0xb00b, 0x009e, 0x1168, 0x2011, 0x0274,
- 0x20a9, 0x0004, 0x6010, 0x0096, 0x2048, 0x2019, 0x0006, 0x080c,
- 0xb00b, 0x009e, 0x1100, 0x015e, 0x003e, 0x002e, 0x0005, 0x00e6,
- 0x2071, 0x1800, 0x080c, 0x5dc3, 0x080c, 0x2e8c, 0x00ee, 0x0005,
- 0x00e6, 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0fc, 0x0108,
- 0x0011, 0x00ee, 0x0005, 0xa880, 0xc0e5, 0xa882, 0x0005, 0x00e6,
- 0x00d6, 0x00c6, 0x0076, 0x0066, 0x0056, 0x0046, 0x0026, 0x0016,
- 0x0126, 0x2091, 0x8000, 0x2029, 0x19cb, 0x252c, 0x2021, 0x19d1,
- 0x2424, 0x2061, 0x1cd0, 0x2071, 0x1800, 0x7650, 0x7070, 0x9606,
- 0x0578, 0x6720, 0x9786, 0x0001, 0x0118, 0x9786, 0x0008, 0x1500,
- 0x2500, 0x9c06, 0x01e8, 0x2400, 0x9c06, 0x01d0, 0x080c, 0xd807,
- 0x01b8, 0x080c, 0xd817, 0x11a0, 0x6000, 0x9086, 0x0004, 0x1120,
- 0x0016, 0x080c, 0x1938, 0x001e, 0x080c, 0xbf32, 0x1110, 0x080c,
- 0x30d4, 0x080c, 0xbf43, 0x1110, 0x080c, 0xa995, 0x080c, 0xa007,
- 0x9ce0, 0x0018, 0x2001, 0x1819, 0x2004, 0x9c02, 0x1208, 0x0858,
- 0x012e, 0x001e, 0x002e, 0x004e, 0x005e, 0x006e, 0x007e, 0x00ce,
- 0x00de, 0x00ee, 0x0005, 0x2001, 0x1810, 0x2004, 0xd0dc, 0x0005,
- 0x0006, 0x2001, 0x1836, 0x2004, 0xd09c, 0x000e, 0x0005, 0x0006,
- 0x0036, 0x0046, 0x080c, 0xc444, 0x0168, 0x2019, 0xffff, 0x9005,
- 0x0128, 0x6010, 0x00b6, 0x2058, 0xbba0, 0x00be, 0x2021, 0x0004,
- 0x080c, 0x4bb5, 0x004e, 0x003e, 0x000e, 0x0005, 0x6004, 0x9086,
- 0x0001, 0x1128, 0x080c, 0x9abb, 0x080c, 0xa007, 0x9006, 0x0005,
- 0x00e6, 0x00c6, 0x00b6, 0x0046, 0x2061, 0x1cd0, 0x2071, 0x1800,
- 0x7450, 0x7070, 0x8001, 0x9402, 0x12d8, 0x2100, 0x9c06, 0x0168,
- 0x6000, 0x9086, 0x0000, 0x0148, 0x6010, 0x2058, 0xb8a0, 0x9206,
- 0x1120, 0x6004, 0x9086, 0x0002, 0x0140, 0x9ce0, 0x0018, 0x2001,
- 0x1819, 0x2004, 0x9c02, 0x1220, 0x0c40, 0x9085, 0x0001, 0x0008,
- 0x9006, 0x004e, 0x00be, 0x00ce, 0x00ee, 0x0005, 0x2001, 0x1810,
- 0x2004, 0xd0a4, 0x0160, 0x2001, 0x1836, 0x2004, 0xd0a4, 0x0138,
- 0x2001, 0x185c, 0x2004, 0xd0a4, 0x1118, 0x9085, 0x0001, 0x0005,
- 0x9006, 0x0ce8, 0x0126, 0x0006, 0x00e6, 0x0016, 0x2091, 0x8000,
- 0x2071, 0x1840, 0xd5a4, 0x0118, 0x7054, 0x8000, 0x7056, 0xd5b4,
- 0x0118, 0x7050, 0x8000, 0x7052, 0xd5ac, 0x0178, 0x2500, 0x9084,
- 0x0007, 0x908e, 0x0003, 0x0148, 0x908e, 0x0004, 0x0130, 0x908e,
- 0x0005, 0x0118, 0x2071, 0x184a, 0x0089, 0x001e, 0x00ee, 0x000e,
- 0x012e, 0x0005, 0x0126, 0x0006, 0x00e6, 0x2091, 0x8000, 0x2071,
- 0x1842, 0x0021, 0x00ee, 0x000e, 0x012e, 0x0005, 0x2e04, 0x8000,
- 0x2072, 0x1220, 0x8e70, 0x2e04, 0x8000, 0x2072, 0x0005, 0x00e6,
- 0x2071, 0x1840, 0x0c99, 0x00ee, 0x0005, 0x00e6, 0x2071, 0x1844,
- 0x0c69, 0x00ee, 0x0005, 0x0126, 0x0006, 0x00e6, 0x2091, 0x8000,
- 0x2071, 0x1840, 0x7064, 0x8000, 0x7066, 0x00ee, 0x000e, 0x012e,
- 0x0005, 0x0003, 0x000b, 0x03ce, 0x0000, 0xc000, 0x0001, 0x8064,
- 0x0008, 0x0010, 0x0000, 0x8066, 0x0000, 0x0101, 0x0008, 0x4407,
- 0x0003, 0x8060, 0x0000, 0x0400, 0x0000, 0x580d, 0x000b, 0x7924,
- 0x0003, 0x5096, 0x000b, 0x4c0a, 0x0003, 0xbac0, 0x0009, 0x008a,
- 0x0000, 0x0c0a, 0x000b, 0x15fe, 0x0008, 0x340a, 0x0003, 0xc4c0,
- 0x0009, 0x7000, 0x0000, 0xffa0, 0x0001, 0x2000, 0x0000, 0x15bf,
- 0x000b, 0x808c, 0x0008, 0x0001, 0x0000, 0x0000, 0x0007, 0x4047,
- 0x000a, 0x808c, 0x0008, 0x0002, 0x0000, 0x0821, 0x0003, 0x4022,
- 0x0000, 0x0022, 0x000b, 0x4122, 0x0008, 0x4447, 0x0002, 0x0de3,
- 0x000b, 0x0bfe, 0x0008, 0x11a0, 0x0001, 0x11c5, 0x000b, 0x0ca0,
- 0x0001, 0x11c5, 0x000b, 0x9180, 0x0001, 0x0004, 0x0000, 0x8060,
- 0x0000, 0x0400, 0x0000, 0x7f62, 0x0008, 0x8066, 0x0000, 0x0009,
- 0x0008, 0x4430, 0x000b, 0x808c, 0x0008, 0x0000, 0x0008, 0x0060,
- 0x0008, 0x8062, 0x0008, 0x0004, 0x0000, 0x8066, 0x0000, 0x0411,
- 0x0000, 0x4438, 0x0003, 0x03fe, 0x0000, 0x43e0, 0x0001, 0x0dc2,
- 0x000b, 0xc2c0, 0x0009, 0x00ff, 0x0008, 0x02e0, 0x0001, 0x0dc2,
- 0x000b, 0x9180, 0x0001, 0x0005, 0x0008, 0x8060, 0x0000, 0x0400,
- 0x0000, 0x7f62, 0x0008, 0x8066, 0x0000, 0x0019, 0x0000, 0x4447,
- 0x000b, 0x0240, 0x0002, 0x09bf, 0x0003, 0x00fe, 0x0000, 0x31c2,
- 0x000b, 0x112a, 0x0000, 0x002e, 0x0008, 0x022c, 0x0008, 0x3a44,
- 0x0002, 0x0c0a, 0x000b, 0x808c, 0x0008, 0x0002, 0x0000, 0x1760,
- 0x0008, 0x8062, 0x0008, 0x000f, 0x0008, 0x8066, 0x0000, 0x0011,
- 0x0008, 0x4458, 0x0003, 0x01fe, 0x0008, 0x42e0, 0x0009, 0x0db5,
- 0x000b, 0x00fe, 0x0000, 0x43e0, 0x0001, 0x0db5, 0x000b, 0x1734,
- 0x0000, 0x1530, 0x0000, 0x1632, 0x0008, 0x0d2a, 0x0008, 0x9880,
- 0x0001, 0x0010, 0x0000, 0x8060, 0x0000, 0x0400, 0x0000, 0x7f62,
- 0x0008, 0x8066, 0x0000, 0x1e0a, 0x0008, 0x446a, 0x000b, 0x808a,
- 0x0008, 0x0003, 0x0008, 0x1a60, 0x0000, 0x8062, 0x0008, 0x0002,
- 0x0000, 0x5870, 0x000b, 0x8066, 0x0000, 0x3679, 0x0000, 0x4473,
- 0x0003, 0x5874, 0x0003, 0x8054, 0x0008, 0x0011, 0x0008, 0x8074,
- 0x0000, 0x1010, 0x0008, 0x1efe, 0x0000, 0x300a, 0x000b, 0x007d,
- 0x0004, 0x000a, 0x000b, 0x1c60, 0x0000, 0x1b62, 0x0000, 0x8066,
- 0x0000, 0x0231, 0x0008, 0x4481, 0x000b, 0x5882, 0x0003, 0x0140,
- 0x0008, 0x0242, 0x0000, 0x1f43, 0x0002, 0x0c8c, 0x0003, 0x0d44,
- 0x0000, 0x0d46, 0x0008, 0x0348, 0x0008, 0x044a, 0x0008, 0x0090,
- 0x000b, 0x0344, 0x0008, 0x0446, 0x0008, 0x0548, 0x0008, 0x064a,
- 0x0000, 0x5890, 0x0003, 0x8054, 0x0008, 0x0001, 0x0000, 0x8074,
- 0x0000, 0x2020, 0x0008, 0x4000, 0x000f, 0x3a40, 0x000a, 0x0c0d,
- 0x0003, 0xabd0, 0x0001, 0x0000, 0x0008, 0x7f24, 0x0000, 0x589b,
- 0x000b, 0x8054, 0x0008, 0x0002, 0x0000, 0x1242, 0x0002, 0x08e1,
- 0x0003, 0x3a45, 0x000a, 0x08d0, 0x000b, 0x1e10, 0x000a, 0x7f3c,
- 0x0000, 0x08cd, 0x000b, 0x1d00, 0x0002, 0x7f3a, 0x0000, 0x0d60,
- 0x0000, 0x7f62, 0x0008, 0x8066, 0x0000, 0x0009, 0x0008, 0x44ab,
- 0x0003, 0x00fe, 0x0000, 0x34ca, 0x0003, 0x1c60, 0x0000, 0x8062,
- 0x0008, 0x0001, 0x0000, 0x8066, 0x0000, 0x0009, 0x0008, 0x44b3,
- 0x0003, 0x00fe, 0x0000, 0x319e, 0x000b, 0x0038, 0x0000, 0x0060,
- 0x0008, 0x8062, 0x0008, 0x0019, 0x0000, 0x8066, 0x0000, 0x0009,
- 0x0008, 0x44bc, 0x0003, 0x80c0, 0x0009, 0x00ff, 0x0008, 0x7f3e,
- 0x0008, 0x0d60, 0x0000, 0x0efe, 0x0008, 0x1f80, 0x0001, 0x7f62,
- 0x0008, 0x8066, 0x0000, 0x0009, 0x0008, 0x44c6, 0x000b, 0x003a,
- 0x0008, 0x1dfe, 0x0000, 0x00a7, 0x0003, 0x0036, 0x0008, 0x007d,
- 0x0004, 0x00e1, 0x000b, 0x8074, 0x0000, 0x2000, 0x0000, 0x00e1,
- 0x000b, 0x3a44, 0x0002, 0x09c8, 0x0003, 0x8074, 0x0000, 0x1000,
- 0x0000, 0xadd0, 0x0001, 0x0000, 0x0008, 0x7f0e, 0x0008, 0x359b,
- 0x0003, 0xa7d0, 0x0001, 0x0000, 0x0008, 0x7f00, 0x0000, 0xa6d0,
- 0x0009, 0x0000, 0x0008, 0x00d0, 0x0009, 0x0cf1, 0x0003, 0x8074,
- 0x0000, 0x4040, 0x0008, 0x58e1, 0x0003, 0x5096, 0x000b, 0x3a46,
- 0x000a, 0x0cf1, 0x0003, 0x3a47, 0x0002, 0x08ec, 0x000b, 0x8054,
- 0x0008, 0x0004, 0x0000, 0x8074, 0x0000, 0x8000, 0x0000, 0x0118,
- 0x0003, 0x92c0, 0x0009, 0x0fc8, 0x0000, 0x080a, 0x0003, 0x1246,
- 0x000a, 0x0d95, 0x0003, 0x1a60, 0x0000, 0x8062, 0x0008, 0x0002,
- 0x0000, 0x8066, 0x0000, 0x367a, 0x0000, 0x44f6, 0x000b, 0x92c0,
- 0x0009, 0x0780, 0x0008, 0x0daf, 0x0003, 0x124b, 0x0002, 0x08ff,
- 0x0003, 0x2e4d, 0x0002, 0x2e4d, 0x0002, 0x099b, 0x0003, 0x3a46,
- 0x000a, 0x0d0c, 0x0003, 0x5901, 0x0003, 0x8054, 0x0008, 0x0004,
- 0x0000, 0x1243, 0x000a, 0x0916, 0x0003, 0x8010, 0x0008, 0x000d,
- 0x0000, 0x0189, 0x0004, 0x1810, 0x0000, 0x0189, 0x0004, 0x0116,
- 0x000b, 0x194d, 0x000a, 0x0910, 0x0003, 0x1243, 0x000a, 0x09a5,
- 0x000b, 0x5910, 0x0003, 0x8054, 0x0008, 0x0004, 0x0000, 0x017e,
- 0x000c, 0x1810, 0x0000, 0x0189, 0x0004, 0x8074, 0x0000, 0xf000,
- 0x0008, 0x0d30, 0x0000, 0x3a42, 0x0002, 0x0d1e, 0x0003, 0x15fe,
- 0x0008, 0x3451, 0x000b, 0x000a, 0x000b, 0x8074, 0x0000, 0x0501,
- 0x0000, 0x8010, 0x0008, 0x000c, 0x0008, 0x0189, 0x0004, 0x000a,
- 0x000b, 0xbbe0, 0x0009, 0x0030, 0x0008, 0x0d34, 0x000b, 0x18fe,
- 0x0000, 0x3ce0, 0x0009, 0x0931, 0x0003, 0x15fe, 0x0008, 0x3ce0,
- 0x0009, 0x0931, 0x0003, 0x0179, 0x0004, 0x8076, 0x0008, 0x0040,
- 0x0000, 0x0176, 0x000b, 0x8076, 0x0008, 0x0041, 0x0008, 0x0176,
- 0x000b, 0xbbe0, 0x0009, 0x0032, 0x0000, 0x0d39, 0x0003, 0x3c1e,
- 0x0008, 0x0176, 0x000b, 0xbbe0, 0x0009, 0x0037, 0x0000, 0x0d5b,
- 0x000b, 0x18fe, 0x0000, 0x3ce0, 0x0009, 0x0d31, 0x000b, 0x8076,
- 0x0008, 0x0040, 0x0000, 0x1a60, 0x0000, 0x8062, 0x0008, 0x000d,
- 0x0000, 0xa6d0, 0x0009, 0x0000, 0x0008, 0x7f04, 0x0008, 0xa7d0,
- 0x0001, 0x0000, 0x0008, 0x7f06, 0x0000, 0xa8d0, 0x0001, 0x0000,
- 0x0008, 0x7f08, 0x0008, 0xa9d0, 0x0009, 0x0000, 0x0008, 0x7f0a,
- 0x0000, 0x8066, 0x0000, 0x0422, 0x0000, 0x4552, 0x000b, 0x017e,
- 0x000c, 0x8054, 0x0008, 0x0004, 0x0000, 0x8074, 0x0000, 0xf000,
- 0x0008, 0x8072, 0x0000, 0x8000, 0x0000, 0x0118, 0x0003, 0xbbe0,
- 0x0009, 0x0038, 0x0000, 0x0d6d, 0x000b, 0x18fe, 0x0000, 0x3ce0,
- 0x0009, 0x096a, 0x000b, 0x15fe, 0x0008, 0x3ce0, 0x0009, 0x0d2d,
- 0x0003, 0x0179, 0x0004, 0x8076, 0x0008, 0x0040, 0x0000, 0x8072,
- 0x0000, 0x8000, 0x0000, 0x01bf, 0x000b, 0x8076, 0x0008, 0x0042,
- 0x0008, 0x0176, 0x000b, 0xbbe0, 0x0009, 0x0016, 0x0000, 0x0d76,
- 0x000b, 0x3a44, 0x0002, 0x0c0c, 0x000b, 0x8072, 0x0000, 0x8000,
- 0x0000, 0x8000, 0x000f, 0x000a, 0x000b, 0x8072, 0x0000, 0x8000,
- 0x0000, 0x000a, 0x000b, 0x3d30, 0x000a, 0x7f00, 0x0000, 0xbc80,
- 0x0001, 0x0007, 0x0000, 0x0182, 0x0003, 0x1930, 0x000a, 0x7f00,
- 0x0000, 0x9880, 0x0001, 0x0007, 0x0000, 0x8060, 0x0000, 0x0400,
- 0x0000, 0x7f62, 0x0008, 0x8066, 0x0000, 0x000a, 0x0008, 0x4587,
- 0x0003, 0x4000, 0x000f, 0x2189, 0x0003, 0x0870, 0x0008, 0x4000,
- 0x000f, 0xbac0, 0x0009, 0x0090, 0x0008, 0x0992, 0x0003, 0x8074,
- 0x0000, 0x0706, 0x0000, 0x0194, 0x000b, 0x8074, 0x0000, 0x0703,
- 0x0000, 0x4000, 0x000f, 0x8010, 0x0008, 0x0023, 0x0000, 0x01cd,
- 0x000b, 0x8010, 0x0008, 0x0008, 0x0000, 0x01cd, 0x000b, 0x8010,
- 0x0008, 0x0022, 0x0008, 0x01cd, 0x000b, 0x017e, 0x000c, 0x8010,
- 0x0008, 0x0007, 0x0000, 0x0189, 0x0004, 0x1810, 0x0000, 0x0189,
- 0x0004, 0x01d7, 0x0003, 0x017e, 0x000c, 0x8010, 0x0008, 0x001b,
- 0x0008, 0x0189, 0x0004, 0x1810, 0x0000, 0x0189, 0x0004, 0x8074,
- 0x0000, 0xf080, 0x0000, 0x0d30, 0x0000, 0x000a, 0x000b, 0x8010,
- 0x0008, 0x0009, 0x0008, 0x01cd, 0x000b, 0x8010, 0x0008, 0x0005,
- 0x0008, 0x01cd, 0x000b, 0x808c, 0x0008, 0x0001, 0x0000, 0x8010,
- 0x0008, 0x0004, 0x0000, 0x4143, 0x000a, 0x085f, 0x0003, 0x3a44,
- 0x0002, 0x0c0a, 0x000b, 0x0d2a, 0x0008, 0x01cd, 0x000b, 0x8010,
- 0x0008, 0x0003, 0x0008, 0x01cf, 0x0003, 0x8010, 0x0008, 0x000b,
- 0x0000, 0x01cf, 0x0003, 0x8010, 0x0008, 0x0002, 0x0000, 0x01cf,
- 0x0003, 0x3a47, 0x0002, 0x0ce1, 0x000b, 0x8010, 0x0008, 0x0006,
- 0x0008, 0x01cf, 0x0003, 0x8074, 0x0000, 0xf000, 0x0008, 0x0189,
- 0x0004, 0x018c, 0x0004, 0x3a40, 0x000a, 0x080a, 0x0003, 0x8010,
- 0x0008, 0x000c, 0x0008, 0x0189, 0x0004, 0x000a, 0x000b, 0x8074,
- 0x0000, 0xf080, 0x0000, 0x0d30, 0x0000, 0x2e4d, 0x0002, 0x2e4d,
- 0x0002, 0x09e0, 0x0003, 0x8054, 0x0008, 0x0019, 0x0000, 0x000a,
- 0x000b, 0x8054, 0x0008, 0x0009, 0x0008, 0x000a, 0x000b, 0x3a44,
- 0x0002, 0x0c0a, 0x000b, 0x01c2, 0x000b, 0x0a0b, 0xf5dd, 0x0003,
- 0x000b, 0x03ce, 0x0000, 0xc000, 0x0001, 0x8064, 0x0008, 0x0010,
- 0x0000, 0x8066, 0x0000, 0x0101, 0x0008, 0xc007, 0x0003, 0x8060,
- 0x0000, 0x0400, 0x0000, 0x580d, 0x000b, 0x7924, 0x0003, 0x5096,
- 0x000b, 0xc80a, 0x0003, 0xbac0, 0x0009, 0x008a, 0x0000, 0x880a,
- 0x000b, 0x15fe, 0x0008, 0xb00a, 0x0003, 0xc4c0, 0x0009, 0x7000,
- 0x0000, 0xffa0, 0x0001, 0x2000, 0x0000, 0x91bf, 0x000b, 0x808c,
- 0x0008, 0x0001, 0x0000, 0x0000, 0x0007, 0x4047, 0x000a, 0x808c,
- 0x0008, 0x0002, 0x0000, 0x0821, 0x0003, 0x4022, 0x0000, 0x0022,
- 0x000b, 0x4122, 0x0008, 0x4447, 0x0002, 0x89e3, 0x000b, 0x0bfe,
- 0x0008, 0x11a0, 0x0001, 0x11c5, 0x000b, 0x0ca0, 0x0001, 0x11c5,
- 0x000b, 0x9180, 0x0001, 0x0004, 0x0000, 0x8060, 0x0000, 0x0400,
- 0x0000, 0x7f62, 0x0008, 0x8066, 0x0000, 0x0009, 0x0008, 0xc030,
- 0x000b, 0x808c, 0x0008, 0x0000, 0x0008, 0x0060, 0x0008, 0x8062,
- 0x0008, 0x0004, 0x0000, 0x8066, 0x0000, 0x0411, 0x0000, 0xc038,
- 0x0003, 0x03fe, 0x0000, 0x43e0, 0x0001, 0x89c2, 0x000b, 0xc2c0,
- 0x0009, 0x00ff, 0x0008, 0x02e0, 0x0001, 0x89c2, 0x000b, 0x9180,
- 0x0001, 0x0005, 0x0008, 0x8060, 0x0000, 0x0400, 0x0000, 0x7f62,
- 0x0008, 0x8066, 0x0000, 0x0019, 0x0000, 0xc047, 0x000b, 0x0240,
- 0x0002, 0x09bf, 0x0003, 0x00fe, 0x0000, 0x31c2, 0x000b, 0x112a,
- 0x0000, 0x002e, 0x0008, 0x022c, 0x0008, 0x3a44, 0x0002, 0x880a,
- 0x000b, 0x808c, 0x0008, 0x0002, 0x0000, 0x1760, 0x0008, 0x8062,
- 0x0008, 0x000f, 0x0008, 0x8066, 0x0000, 0x0011, 0x0008, 0xc058,
- 0x0003, 0x01fe, 0x0008, 0x42e0, 0x0009, 0x89b5, 0x000b, 0x00fe,
- 0x0000, 0x43e0, 0x0001, 0x89b5, 0x000b, 0x1734, 0x0000, 0x1530,
- 0x0000, 0x1632, 0x0008, 0x0d2a, 0x0008, 0x9880, 0x0001, 0x0010,
- 0x0000, 0x8060, 0x0000, 0x0400, 0x0000, 0x7f62, 0x0008, 0x8066,
- 0x0000, 0x1e0a, 0x0008, 0xc06a, 0x000b, 0x808a, 0x0008, 0x0003,
- 0x0008, 0x1a60, 0x0000, 0x8062, 0x0008, 0x0002, 0x0000, 0x5870,
- 0x000b, 0x8066, 0x0000, 0x3679, 0x0000, 0xc073, 0x0003, 0x5874,
- 0x0003, 0x8054, 0x0008, 0x0011, 0x0008, 0x8074, 0x0000, 0x1010,
- 0x0008, 0x1efe, 0x0000, 0x300a, 0x000b, 0x007d, 0x0004, 0x000a,
- 0x000b, 0x1c60, 0x0000, 0x1b62, 0x0000, 0x8066, 0x0000, 0x0231,
- 0x0008, 0xc081, 0x000b, 0x5882, 0x0003, 0x0140, 0x0008, 0x0242,
- 0x0000, 0x1f43, 0x0002, 0x888c, 0x0003, 0x0d44, 0x0000, 0x0d46,
- 0x0008, 0x0348, 0x0008, 0x044a, 0x0008, 0x0090, 0x000b, 0x0344,
- 0x0008, 0x0446, 0x0008, 0x0548, 0x0008, 0x064a, 0x0000, 0x5890,
- 0x0003, 0x8054, 0x0008, 0x0001, 0x0000, 0x8074, 0x0000, 0x2020,
- 0x0008, 0x4000, 0x000f, 0x3a40, 0x000a, 0x880d, 0x0003, 0xabd0,
- 0x0001, 0x0000, 0x0008, 0x7f24, 0x0000, 0x589b, 0x000b, 0x8054,
- 0x0008, 0x0002, 0x0000, 0x1242, 0x0002, 0x08e1, 0x0003, 0x3a45,
- 0x000a, 0x08d0, 0x000b, 0x1e10, 0x000a, 0x7f3c, 0x0000, 0x08cd,
- 0x000b, 0x1d00, 0x0002, 0x7f3a, 0x0000, 0x0d60, 0x0000, 0x7f62,
- 0x0008, 0x8066, 0x0000, 0x0009, 0x0008, 0xc0ab, 0x0003, 0x00fe,
- 0x0000, 0xb0ca, 0x0003, 0x1c60, 0x0000, 0x8062, 0x0008, 0x0001,
- 0x0000, 0x8066, 0x0000, 0x0009, 0x0008, 0xc0b3, 0x0003, 0x00fe,
- 0x0000, 0x319e, 0x000b, 0x0038, 0x0000, 0x0060, 0x0008, 0x8062,
- 0x0008, 0x0019, 0x0000, 0x8066, 0x0000, 0x0009, 0x0008, 0xc0bc,
- 0x0003, 0x80c0, 0x0009, 0x00ff, 0x0008, 0x7f3e, 0x0008, 0x0d60,
- 0x0000, 0x0efe, 0x0008, 0x1f80, 0x0001, 0x7f62, 0x0008, 0x8066,
- 0x0000, 0x0009, 0x0008, 0xc0c6, 0x000b, 0x003a, 0x0008, 0x1dfe,
- 0x0000, 0x00a7, 0x0003, 0x0036, 0x0008, 0x007d, 0x0004, 0x00e1,
- 0x000b, 0x8074, 0x0000, 0x2000, 0x0000, 0x00e1, 0x000b, 0x3a44,
- 0x0002, 0x09c8, 0x0003, 0x8074, 0x0000, 0x1000, 0x0000, 0xadd0,
- 0x0001, 0x0000, 0x0008, 0x7f0e, 0x0008, 0xb19b, 0x0003, 0xa7d0,
- 0x0001, 0x0000, 0x0008, 0x7f00, 0x0000, 0xa6d0, 0x0009, 0x0000,
- 0x0008, 0x00d0, 0x0009, 0x88f1, 0x0003, 0x8074, 0x0000, 0x4040,
- 0x0008, 0x58e1, 0x0003, 0x5096, 0x000b, 0x3a46, 0x000a, 0x88f1,
- 0x0003, 0x3a47, 0x0002, 0x08ec, 0x000b, 0x8054, 0x0008, 0x0004,
- 0x0000, 0x8074, 0x0000, 0x8000, 0x0000, 0x0118, 0x0003, 0x92c0,
- 0x0009, 0x0fc8, 0x0000, 0x080a, 0x0003, 0x1246, 0x000a, 0x8995,
- 0x0003, 0x1a60, 0x0000, 0x8062, 0x0008, 0x0002, 0x0000, 0x8066,
- 0x0000, 0x367a, 0x0000, 0xc0f6, 0x000b, 0x92c0, 0x0009, 0x0780,
- 0x0008, 0x89af, 0x0003, 0x124b, 0x0002, 0x08ff, 0x0003, 0x2e4d,
- 0x0002, 0x2e4d, 0x0002, 0x099b, 0x0003, 0x3a46, 0x000a, 0x890c,
- 0x0003, 0x5901, 0x0003, 0x8054, 0x0008, 0x0004, 0x0000, 0x1243,
- 0x000a, 0x0916, 0x0003, 0x8010, 0x0008, 0x000d, 0x0000, 0x0189,
- 0x0004, 0x1810, 0x0000, 0x0189, 0x0004, 0x0116, 0x000b, 0x194d,
- 0x000a, 0x0910, 0x0003, 0x1243, 0x000a, 0x09a5, 0x000b, 0x5910,
- 0x0003, 0x8054, 0x0008, 0x0004, 0x0000, 0x017e, 0x000c, 0x1810,
- 0x0000, 0x0189, 0x0004, 0x8074, 0x0000, 0xf000, 0x0008, 0x0d30,
- 0x0000, 0x3a42, 0x0002, 0x891e, 0x0003, 0x15fe, 0x0008, 0xb051,
- 0x000b, 0x000a, 0x000b, 0x8074, 0x0000, 0x0501, 0x0000, 0x8010,
- 0x0008, 0x000c, 0x0008, 0x0189, 0x0004, 0x000a, 0x000b, 0xbbe0,
- 0x0009, 0x0030, 0x0008, 0x8934, 0x000b, 0x18fe, 0x0000, 0x3ce0,
- 0x0009, 0x0931, 0x0003, 0x15fe, 0x0008, 0x3ce0, 0x0009, 0x0931,
- 0x0003, 0x0179, 0x0004, 0x8076, 0x0008, 0x0040, 0x0000, 0x0176,
- 0x000b, 0x8076, 0x0008, 0x0041, 0x0008, 0x0176, 0x000b, 0xbbe0,
- 0x0009, 0x0032, 0x0000, 0x8939, 0x0003, 0x3c1e, 0x0008, 0x0176,
- 0x000b, 0xbbe0, 0x0009, 0x0037, 0x0000, 0x895b, 0x000b, 0x18fe,
- 0x0000, 0x3ce0, 0x0009, 0x8931, 0x000b, 0x8076, 0x0008, 0x0040,
- 0x0000, 0x1a60, 0x0000, 0x8062, 0x0008, 0x000d, 0x0000, 0xa6d0,
- 0x0009, 0x0000, 0x0008, 0x7f04, 0x0008, 0xa7d0, 0x0001, 0x0000,
- 0x0008, 0x7f06, 0x0000, 0xa8d0, 0x0001, 0x0000, 0x0008, 0x7f08,
- 0x0008, 0xa9d0, 0x0009, 0x0000, 0x0008, 0x7f0a, 0x0000, 0x8066,
- 0x0000, 0x0422, 0x0000, 0xc152, 0x000b, 0x017e, 0x000c, 0x8054,
- 0x0008, 0x0004, 0x0000, 0x8074, 0x0000, 0xf000, 0x0008, 0x8072,
- 0x0000, 0x8000, 0x0000, 0x0118, 0x0003, 0xbbe0, 0x0009, 0x0038,
- 0x0000, 0x896d, 0x000b, 0x18fe, 0x0000, 0x3ce0, 0x0009, 0x096a,
- 0x000b, 0x15fe, 0x0008, 0x3ce0, 0x0009, 0x892d, 0x0003, 0x0179,
- 0x0004, 0x8076, 0x0008, 0x0040, 0x0000, 0x8072, 0x0000, 0x8000,
- 0x0000, 0x01bf, 0x000b, 0x8076, 0x0008, 0x0042, 0x0008, 0x0176,
- 0x000b, 0xbbe0, 0x0009, 0x0016, 0x0000, 0x8976, 0x000b, 0x3a44,
- 0x0002, 0x880c, 0x000b, 0x8072, 0x0000, 0x8000, 0x0000, 0x8000,
- 0x000f, 0x000a, 0x000b, 0x8072, 0x0000, 0x8000, 0x0000, 0x000a,
- 0x000b, 0x3d30, 0x000a, 0x7f00, 0x0000, 0xbc80, 0x0001, 0x0007,
- 0x0000, 0x0182, 0x0003, 0x1930, 0x000a, 0x7f00, 0x0000, 0x9880,
- 0x0001, 0x0007, 0x0000, 0x8060, 0x0000, 0x0400, 0x0000, 0x7f62,
- 0x0008, 0x8066, 0x0000, 0x000a, 0x0008, 0xc187, 0x0003, 0x4000,
- 0x000f, 0x2189, 0x0003, 0x0870, 0x0008, 0x4000, 0x000f, 0xbac0,
- 0x0009, 0x0090, 0x0008, 0x0992, 0x0003, 0x8074, 0x0000, 0x0706,
- 0x0000, 0x0194, 0x000b, 0x8074, 0x0000, 0x0703, 0x0000, 0x4000,
- 0x000f, 0x8010, 0x0008, 0x0023, 0x0000, 0x01cd, 0x000b, 0x8010,
- 0x0008, 0x0008, 0x0000, 0x01cd, 0x000b, 0x8010, 0x0008, 0x0022,
- 0x0008, 0x01cd, 0x000b, 0x017e, 0x000c, 0x8010, 0x0008, 0x0007,
- 0x0000, 0x0189, 0x0004, 0x1810, 0x0000, 0x0189, 0x0004, 0x01d7,
- 0x0003, 0x017e, 0x000c, 0x8010, 0x0008, 0x001b, 0x0008, 0x0189,
- 0x0004, 0x1810, 0x0000, 0x0189, 0x0004, 0x8074, 0x0000, 0xf080,
- 0x0000, 0x0d30, 0x0000, 0x000a, 0x000b, 0x8010, 0x0008, 0x0009,
- 0x0008, 0x01cd, 0x000b, 0x8010, 0x0008, 0x0005, 0x0008, 0x01cd,
- 0x000b, 0x808c, 0x0008, 0x0001, 0x0000, 0x8010, 0x0008, 0x0004,
- 0x0000, 0x4143, 0x000a, 0x085f, 0x0003, 0x3a44, 0x0002, 0x880a,
- 0x000b, 0x0d2a, 0x0008, 0x01cd, 0x000b, 0x8010, 0x0008, 0x0003,
- 0x0008, 0x01cf, 0x0003, 0x8010, 0x0008, 0x000b, 0x0000, 0x01cf,
- 0x0003, 0x8010, 0x0008, 0x0002, 0x0000, 0x01cf, 0x0003, 0x3a47,
- 0x0002, 0x88e1, 0x000b, 0x8010, 0x0008, 0x0006, 0x0008, 0x01cf,
- 0x0003, 0x8074, 0x0000, 0xf000, 0x0008, 0x0189, 0x0004, 0x018c,
- 0x0004, 0x3a40, 0x000a, 0x080a, 0x0003, 0x8010, 0x0008, 0x000c,
- 0x0008, 0x0189, 0x0004, 0x000a, 0x000b, 0x8074, 0x0000, 0xf080,
- 0x0000, 0x0d30, 0x0000, 0x2e4d, 0x0002, 0x2e4d, 0x0002, 0x09e0,
- 0x0003, 0x8054, 0x0008, 0x0019, 0x0000, 0x000a, 0x000b, 0x8054,
- 0x0008, 0x0009, 0x0008, 0x000a, 0x000b, 0x3a44, 0x0002, 0x880a,
- 0x000b, 0x01c2, 0x000b, 0x460b, 0xf5c6, 0x0001, 0x0002, 0x0004,
- 0x0008, 0x0010, 0x0020, 0x0040, 0x0080, 0x0100, 0x0200, 0x0400,
- 0x0800, 0x1000, 0x2000, 0x4000, 0x8000, 0xdac8
+ 0x0008, 0x9006, 0x004e, 0x00be, 0x00ce, 0x00ee, 0x0005, 0x2001,
+ 0x1810, 0x2004, 0xd0a4, 0x0160, 0x2001, 0x1836, 0x2004, 0xd0a4,
+ 0x0138, 0x2001, 0x185c, 0x2004, 0xd0a4, 0x1118, 0x9085, 0x0001,
+ 0x0005, 0x9006, 0x0ce8, 0x0126, 0x0006, 0x00e6, 0x0016, 0x2091,
+ 0x8000, 0x2071, 0x1840, 0xd5a4, 0x0118, 0x7054, 0x8000, 0x7056,
+ 0xd5b4, 0x0118, 0x7050, 0x8000, 0x7052, 0xd5ac, 0x0178, 0x2500,
+ 0x9084, 0x0007, 0x908e, 0x0003, 0x0148, 0x908e, 0x0004, 0x0130,
+ 0x908e, 0x0005, 0x0118, 0x2071, 0x184a, 0x0089, 0x001e, 0x00ee,
+ 0x000e, 0x012e, 0x0005, 0x0126, 0x0006, 0x00e6, 0x2091, 0x8000,
+ 0x2071, 0x1842, 0x0021, 0x00ee, 0x000e, 0x012e, 0x0005, 0x2e04,
+ 0x8000, 0x2072, 0x1220, 0x8e70, 0x2e04, 0x8000, 0x2072, 0x0005,
+ 0x00e6, 0x2071, 0x1840, 0x0c99, 0x00ee, 0x0005, 0x00e6, 0x2071,
+ 0x1844, 0x0c69, 0x00ee, 0x0005, 0x0126, 0x0006, 0x00e6, 0x2091,
+ 0x8000, 0x2071, 0x1840, 0x7064, 0x8000, 0x7066, 0x00ee, 0x000e,
+ 0x012e, 0x0005, 0x0003, 0x000b, 0x03ce, 0x0000, 0xc000, 0x0001,
+ 0x8064, 0x0008, 0x0010, 0x0000, 0x8066, 0x0000, 0x0101, 0x0008,
+ 0x4407, 0x0003, 0x8060, 0x0000, 0x0400, 0x0000, 0x580d, 0x000b,
+ 0x7924, 0x0003, 0x5096, 0x000b, 0x4c0a, 0x0003, 0xbac0, 0x0009,
+ 0x008a, 0x0000, 0x0c0a, 0x000b, 0x15fe, 0x0008, 0x340a, 0x0003,
+ 0xc4c0, 0x0009, 0x7000, 0x0000, 0xffa0, 0x0001, 0x2000, 0x0000,
+ 0x15bf, 0x000b, 0x808c, 0x0008, 0x0001, 0x0000, 0x0000, 0x0007,
+ 0x4047, 0x000a, 0x808c, 0x0008, 0x0002, 0x0000, 0x0821, 0x0003,
+ 0x4022, 0x0000, 0x0022, 0x000b, 0x4122, 0x0008, 0x4447, 0x0002,
+ 0x0de3, 0x000b, 0x0bfe, 0x0008, 0x11a0, 0x0001, 0x11c5, 0x000b,
+ 0x0ca0, 0x0001, 0x11c5, 0x000b, 0x9180, 0x0001, 0x0004, 0x0000,
+ 0x8060, 0x0000, 0x0400, 0x0000, 0x7f62, 0x0008, 0x8066, 0x0000,
+ 0x0009, 0x0008, 0x4430, 0x000b, 0x808c, 0x0008, 0x0000, 0x0008,
+ 0x0060, 0x0008, 0x8062, 0x0008, 0x0004, 0x0000, 0x8066, 0x0000,
+ 0x0411, 0x0000, 0x4438, 0x0003, 0x03fe, 0x0000, 0x43e0, 0x0001,
+ 0x0dc2, 0x000b, 0xc2c0, 0x0009, 0x00ff, 0x0008, 0x02e0, 0x0001,
+ 0x0dc2, 0x000b, 0x9180, 0x0001, 0x0005, 0x0008, 0x8060, 0x0000,
+ 0x0400, 0x0000, 0x7f62, 0x0008, 0x8066, 0x0000, 0x0019, 0x0000,
+ 0x4447, 0x000b, 0x0240, 0x0002, 0x09bf, 0x0003, 0x00fe, 0x0000,
+ 0x31c2, 0x000b, 0x112a, 0x0000, 0x002e, 0x0008, 0x022c, 0x0008,
+ 0x3a44, 0x0002, 0x0c0a, 0x000b, 0x808c, 0x0008, 0x0002, 0x0000,
+ 0x1760, 0x0008, 0x8062, 0x0008, 0x000f, 0x0008, 0x8066, 0x0000,
+ 0x0011, 0x0008, 0x4458, 0x0003, 0x01fe, 0x0008, 0x42e0, 0x0009,
+ 0x0db5, 0x000b, 0x00fe, 0x0000, 0x43e0, 0x0001, 0x0db5, 0x000b,
+ 0x1734, 0x0000, 0x1530, 0x0000, 0x1632, 0x0008, 0x0d2a, 0x0008,
+ 0x9880, 0x0001, 0x0010, 0x0000, 0x8060, 0x0000, 0x0400, 0x0000,
+ 0x7f62, 0x0008, 0x8066, 0x0000, 0x1e0a, 0x0008, 0x446a, 0x000b,
+ 0x808a, 0x0008, 0x0003, 0x0008, 0x1a60, 0x0000, 0x8062, 0x0008,
+ 0x0002, 0x0000, 0x5870, 0x000b, 0x8066, 0x0000, 0x3679, 0x0000,
+ 0x4473, 0x0003, 0x5874, 0x0003, 0x8054, 0x0008, 0x0011, 0x0008,
+ 0x8074, 0x0000, 0x1010, 0x0008, 0x1efe, 0x0000, 0x300a, 0x000b,
+ 0x007d, 0x0004, 0x000a, 0x000b, 0x1c60, 0x0000, 0x1b62, 0x0000,
+ 0x8066, 0x0000, 0x0231, 0x0008, 0x4481, 0x000b, 0x5882, 0x0003,
+ 0x0140, 0x0008, 0x0242, 0x0000, 0x1f43, 0x0002, 0x0c8c, 0x0003,
+ 0x0d44, 0x0000, 0x0d46, 0x0008, 0x0348, 0x0008, 0x044a, 0x0008,
+ 0x0090, 0x000b, 0x0344, 0x0008, 0x0446, 0x0008, 0x0548, 0x0008,
+ 0x064a, 0x0000, 0x5890, 0x0003, 0x8054, 0x0008, 0x0001, 0x0000,
+ 0x8074, 0x0000, 0x2020, 0x0008, 0x4000, 0x000f, 0x3a40, 0x000a,
+ 0x0c0d, 0x0003, 0xabd0, 0x0001, 0x0000, 0x0008, 0x7f24, 0x0000,
+ 0x589b, 0x000b, 0x8054, 0x0008, 0x0002, 0x0000, 0x1242, 0x0002,
+ 0x08e1, 0x0003, 0x3a45, 0x000a, 0x08d0, 0x000b, 0x1e10, 0x000a,
+ 0x7f3c, 0x0000, 0x08cd, 0x000b, 0x1d00, 0x0002, 0x7f3a, 0x0000,
+ 0x0d60, 0x0000, 0x7f62, 0x0008, 0x8066, 0x0000, 0x0009, 0x0008,
+ 0x44ab, 0x0003, 0x00fe, 0x0000, 0x34ca, 0x0003, 0x1c60, 0x0000,
+ 0x8062, 0x0008, 0x0001, 0x0000, 0x8066, 0x0000, 0x0009, 0x0008,
+ 0x44b3, 0x0003, 0x00fe, 0x0000, 0x319e, 0x000b, 0x0038, 0x0000,
+ 0x0060, 0x0008, 0x8062, 0x0008, 0x0019, 0x0000, 0x8066, 0x0000,
+ 0x0009, 0x0008, 0x44bc, 0x0003, 0x80c0, 0x0009, 0x00ff, 0x0008,
+ 0x7f3e, 0x0008, 0x0d60, 0x0000, 0x0efe, 0x0008, 0x1f80, 0x0001,
+ 0x7f62, 0x0008, 0x8066, 0x0000, 0x0009, 0x0008, 0x44c6, 0x000b,
+ 0x003a, 0x0008, 0x1dfe, 0x0000, 0x00a7, 0x0003, 0x0036, 0x0008,
+ 0x007d, 0x0004, 0x00e1, 0x000b, 0x8074, 0x0000, 0x2000, 0x0000,
+ 0x00e1, 0x000b, 0x3a44, 0x0002, 0x09c8, 0x0003, 0x8074, 0x0000,
+ 0x1000, 0x0000, 0xadd0, 0x0001, 0x0000, 0x0008, 0x7f0e, 0x0008,
+ 0x359b, 0x0003, 0xa7d0, 0x0001, 0x0000, 0x0008, 0x7f00, 0x0000,
+ 0xa6d0, 0x0009, 0x0000, 0x0008, 0x00d0, 0x0009, 0x0cf1, 0x0003,
+ 0x8074, 0x0000, 0x4040, 0x0008, 0x58e1, 0x0003, 0x5096, 0x000b,
+ 0x3a46, 0x000a, 0x0cf1, 0x0003, 0x3a47, 0x0002, 0x08ec, 0x000b,
+ 0x8054, 0x0008, 0x0004, 0x0000, 0x8074, 0x0000, 0x8000, 0x0000,
+ 0x0118, 0x0003, 0x92c0, 0x0009, 0x0fc8, 0x0000, 0x080a, 0x0003,
+ 0x1246, 0x000a, 0x0d95, 0x0003, 0x1a60, 0x0000, 0x8062, 0x0008,
+ 0x0002, 0x0000, 0x8066, 0x0000, 0x367a, 0x0000, 0x44f6, 0x000b,
+ 0x92c0, 0x0009, 0x0780, 0x0008, 0x0daf, 0x0003, 0x124b, 0x0002,
+ 0x08ff, 0x0003, 0x2e4d, 0x0002, 0x2e4d, 0x0002, 0x099b, 0x0003,
+ 0x3a46, 0x000a, 0x0d0c, 0x0003, 0x5901, 0x0003, 0x8054, 0x0008,
+ 0x0004, 0x0000, 0x1243, 0x000a, 0x0916, 0x0003, 0x8010, 0x0008,
+ 0x000d, 0x0000, 0x0189, 0x0004, 0x1810, 0x0000, 0x0189, 0x0004,
+ 0x0116, 0x000b, 0x194d, 0x000a, 0x0910, 0x0003, 0x1243, 0x000a,
+ 0x09a5, 0x000b, 0x5910, 0x0003, 0x8054, 0x0008, 0x0004, 0x0000,
+ 0x017e, 0x000c, 0x1810, 0x0000, 0x0189, 0x0004, 0x8074, 0x0000,
+ 0xf000, 0x0008, 0x0d30, 0x0000, 0x3a42, 0x0002, 0x0d1e, 0x0003,
+ 0x15fe, 0x0008, 0x3451, 0x000b, 0x000a, 0x000b, 0x8074, 0x0000,
+ 0x0501, 0x0000, 0x8010, 0x0008, 0x000c, 0x0008, 0x0189, 0x0004,
+ 0x000a, 0x000b, 0xbbe0, 0x0009, 0x0030, 0x0008, 0x0d34, 0x000b,
+ 0x18fe, 0x0000, 0x3ce0, 0x0009, 0x0931, 0x0003, 0x15fe, 0x0008,
+ 0x3ce0, 0x0009, 0x0931, 0x0003, 0x0179, 0x0004, 0x8076, 0x0008,
+ 0x0040, 0x0000, 0x0176, 0x000b, 0x8076, 0x0008, 0x0041, 0x0008,
+ 0x0176, 0x000b, 0xbbe0, 0x0009, 0x0032, 0x0000, 0x0d39, 0x0003,
+ 0x3c1e, 0x0008, 0x0176, 0x000b, 0xbbe0, 0x0009, 0x0037, 0x0000,
+ 0x0d5b, 0x000b, 0x18fe, 0x0000, 0x3ce0, 0x0009, 0x0d31, 0x000b,
+ 0x8076, 0x0008, 0x0040, 0x0000, 0x1a60, 0x0000, 0x8062, 0x0008,
+ 0x000d, 0x0000, 0xa6d0, 0x0009, 0x0000, 0x0008, 0x7f04, 0x0008,
+ 0xa7d0, 0x0001, 0x0000, 0x0008, 0x7f06, 0x0000, 0xa8d0, 0x0001,
+ 0x0000, 0x0008, 0x7f08, 0x0008, 0xa9d0, 0x0009, 0x0000, 0x0008,
+ 0x7f0a, 0x0000, 0x8066, 0x0000, 0x0422, 0x0000, 0x4552, 0x000b,
+ 0x017e, 0x000c, 0x8054, 0x0008, 0x0004, 0x0000, 0x8074, 0x0000,
+ 0xf000, 0x0008, 0x8072, 0x0000, 0x8000, 0x0000, 0x0118, 0x0003,
+ 0xbbe0, 0x0009, 0x0038, 0x0000, 0x0d6d, 0x000b, 0x18fe, 0x0000,
+ 0x3ce0, 0x0009, 0x096a, 0x000b, 0x15fe, 0x0008, 0x3ce0, 0x0009,
+ 0x0d2d, 0x0003, 0x0179, 0x0004, 0x8076, 0x0008, 0x0040, 0x0000,
+ 0x8072, 0x0000, 0x8000, 0x0000, 0x01bf, 0x000b, 0x8076, 0x0008,
+ 0x0042, 0x0008, 0x0176, 0x000b, 0xbbe0, 0x0009, 0x0016, 0x0000,
+ 0x0d76, 0x000b, 0x3a44, 0x0002, 0x0c0c, 0x000b, 0x8072, 0x0000,
+ 0x8000, 0x0000, 0x8000, 0x000f, 0x000a, 0x000b, 0x8072, 0x0000,
+ 0x8000, 0x0000, 0x000a, 0x000b, 0x3d30, 0x000a, 0x7f00, 0x0000,
+ 0xbc80, 0x0001, 0x0007, 0x0000, 0x0182, 0x0003, 0x1930, 0x000a,
+ 0x7f00, 0x0000, 0x9880, 0x0001, 0x0007, 0x0000, 0x8060, 0x0000,
+ 0x0400, 0x0000, 0x7f62, 0x0008, 0x8066, 0x0000, 0x000a, 0x0008,
+ 0x4587, 0x0003, 0x4000, 0x000f, 0x2189, 0x0003, 0x0870, 0x0008,
+ 0x4000, 0x000f, 0xbac0, 0x0009, 0x0090, 0x0008, 0x0992, 0x0003,
+ 0x8074, 0x0000, 0x0706, 0x0000, 0x0194, 0x000b, 0x8074, 0x0000,
+ 0x0703, 0x0000, 0x4000, 0x000f, 0x8010, 0x0008, 0x0023, 0x0000,
+ 0x01cd, 0x000b, 0x8010, 0x0008, 0x0008, 0x0000, 0x01cd, 0x000b,
+ 0x8010, 0x0008, 0x0022, 0x0008, 0x01cd, 0x000b, 0x017e, 0x000c,
+ 0x8010, 0x0008, 0x0007, 0x0000, 0x0189, 0x0004, 0x1810, 0x0000,
+ 0x0189, 0x0004, 0x01d7, 0x0003, 0x017e, 0x000c, 0x8010, 0x0008,
+ 0x001b, 0x0008, 0x0189, 0x0004, 0x1810, 0x0000, 0x0189, 0x0004,
+ 0x8074, 0x0000, 0xf080, 0x0000, 0x0d30, 0x0000, 0x000a, 0x000b,
+ 0x8010, 0x0008, 0x0009, 0x0008, 0x01cd, 0x000b, 0x8010, 0x0008,
+ 0x0005, 0x0008, 0x01cd, 0x000b, 0x808c, 0x0008, 0x0001, 0x0000,
+ 0x8010, 0x0008, 0x0004, 0x0000, 0x4143, 0x000a, 0x085f, 0x0003,
+ 0x3a44, 0x0002, 0x0c0a, 0x000b, 0x0d2a, 0x0008, 0x01cd, 0x000b,
+ 0x8010, 0x0008, 0x0003, 0x0008, 0x01cf, 0x0003, 0x8010, 0x0008,
+ 0x000b, 0x0000, 0x01cf, 0x0003, 0x8010, 0x0008, 0x0002, 0x0000,
+ 0x01cf, 0x0003, 0x3a47, 0x0002, 0x0ce1, 0x000b, 0x8010, 0x0008,
+ 0x0006, 0x0008, 0x01cf, 0x0003, 0x8074, 0x0000, 0xf000, 0x0008,
+ 0x0189, 0x0004, 0x018c, 0x0004, 0x3a40, 0x000a, 0x080a, 0x0003,
+ 0x8010, 0x0008, 0x000c, 0x0008, 0x0189, 0x0004, 0x000a, 0x000b,
+ 0x8074, 0x0000, 0xf080, 0x0000, 0x0d30, 0x0000, 0x2e4d, 0x0002,
+ 0x2e4d, 0x0002, 0x09e0, 0x0003, 0x8054, 0x0008, 0x0019, 0x0000,
+ 0x000a, 0x000b, 0x8054, 0x0008, 0x0009, 0x0008, 0x000a, 0x000b,
+ 0x3a44, 0x0002, 0x0c0a, 0x000b, 0x01c2, 0x000b, 0x0a0b, 0xf5dd,
+ 0x0003, 0x000b, 0x03ce, 0x0000, 0xc000, 0x0001, 0x8064, 0x0008,
+ 0x0010, 0x0000, 0x8066, 0x0000, 0x0101, 0x0008, 0xc007, 0x0003,
+ 0x8060, 0x0000, 0x0400, 0x0000, 0x580d, 0x000b, 0x7924, 0x0003,
+ 0x5096, 0x000b, 0xc80a, 0x0003, 0xbac0, 0x0009, 0x008a, 0x0000,
+ 0x880a, 0x000b, 0x15fe, 0x0008, 0xb00a, 0x0003, 0xc4c0, 0x0009,
+ 0x7000, 0x0000, 0xffa0, 0x0001, 0x2000, 0x0000, 0x91bf, 0x000b,
+ 0x808c, 0x0008, 0x0001, 0x0000, 0x0000, 0x0007, 0x4047, 0x000a,
+ 0x808c, 0x0008, 0x0002, 0x0000, 0x0821, 0x0003, 0x4022, 0x0000,
+ 0x0022, 0x000b, 0x4122, 0x0008, 0x4447, 0x0002, 0x89e3, 0x000b,
+ 0x0bfe, 0x0008, 0x11a0, 0x0001, 0x11c5, 0x000b, 0x0ca0, 0x0001,
+ 0x11c5, 0x000b, 0x9180, 0x0001, 0x0004, 0x0000, 0x8060, 0x0000,
+ 0x0400, 0x0000, 0x7f62, 0x0008, 0x8066, 0x0000, 0x0009, 0x0008,
+ 0xc030, 0x000b, 0x808c, 0x0008, 0x0000, 0x0008, 0x0060, 0x0008,
+ 0x8062, 0x0008, 0x0004, 0x0000, 0x8066, 0x0000, 0x0411, 0x0000,
+ 0xc038, 0x0003, 0x03fe, 0x0000, 0x43e0, 0x0001, 0x89c2, 0x000b,
+ 0xc2c0, 0x0009, 0x00ff, 0x0008, 0x02e0, 0x0001, 0x89c2, 0x000b,
+ 0x9180, 0x0001, 0x0005, 0x0008, 0x8060, 0x0000, 0x0400, 0x0000,
+ 0x7f62, 0x0008, 0x8066, 0x0000, 0x0019, 0x0000, 0xc047, 0x000b,
+ 0x0240, 0x0002, 0x09bf, 0x0003, 0x00fe, 0x0000, 0x31c2, 0x000b,
+ 0x112a, 0x0000, 0x002e, 0x0008, 0x022c, 0x0008, 0x3a44, 0x0002,
+ 0x880a, 0x000b, 0x808c, 0x0008, 0x0002, 0x0000, 0x1760, 0x0008,
+ 0x8062, 0x0008, 0x000f, 0x0008, 0x8066, 0x0000, 0x0011, 0x0008,
+ 0xc058, 0x0003, 0x01fe, 0x0008, 0x42e0, 0x0009, 0x89b5, 0x000b,
+ 0x00fe, 0x0000, 0x43e0, 0x0001, 0x89b5, 0x000b, 0x1734, 0x0000,
+ 0x1530, 0x0000, 0x1632, 0x0008, 0x0d2a, 0x0008, 0x9880, 0x0001,
+ 0x0010, 0x0000, 0x8060, 0x0000, 0x0400, 0x0000, 0x7f62, 0x0008,
+ 0x8066, 0x0000, 0x1e0a, 0x0008, 0xc06a, 0x000b, 0x808a, 0x0008,
+ 0x0003, 0x0008, 0x1a60, 0x0000, 0x8062, 0x0008, 0x0002, 0x0000,
+ 0x5870, 0x000b, 0x8066, 0x0000, 0x3679, 0x0000, 0xc073, 0x0003,
+ 0x5874, 0x0003, 0x8054, 0x0008, 0x0011, 0x0008, 0x8074, 0x0000,
+ 0x1010, 0x0008, 0x1efe, 0x0000, 0x300a, 0x000b, 0x007d, 0x0004,
+ 0x000a, 0x000b, 0x1c60, 0x0000, 0x1b62, 0x0000, 0x8066, 0x0000,
+ 0x0231, 0x0008, 0xc081, 0x000b, 0x5882, 0x0003, 0x0140, 0x0008,
+ 0x0242, 0x0000, 0x1f43, 0x0002, 0x888c, 0x0003, 0x0d44, 0x0000,
+ 0x0d46, 0x0008, 0x0348, 0x0008, 0x044a, 0x0008, 0x0090, 0x000b,
+ 0x0344, 0x0008, 0x0446, 0x0008, 0x0548, 0x0008, 0x064a, 0x0000,
+ 0x5890, 0x0003, 0x8054, 0x0008, 0x0001, 0x0000, 0x8074, 0x0000,
+ 0x2020, 0x0008, 0x4000, 0x000f, 0x3a40, 0x000a, 0x880d, 0x0003,
+ 0xabd0, 0x0001, 0x0000, 0x0008, 0x7f24, 0x0000, 0x589b, 0x000b,
+ 0x8054, 0x0008, 0x0002, 0x0000, 0x1242, 0x0002, 0x08e1, 0x0003,
+ 0x3a45, 0x000a, 0x08d0, 0x000b, 0x1e10, 0x000a, 0x7f3c, 0x0000,
+ 0x08cd, 0x000b, 0x1d00, 0x0002, 0x7f3a, 0x0000, 0x0d60, 0x0000,
+ 0x7f62, 0x0008, 0x8066, 0x0000, 0x0009, 0x0008, 0xc0ab, 0x0003,
+ 0x00fe, 0x0000, 0xb0ca, 0x0003, 0x1c60, 0x0000, 0x8062, 0x0008,
+ 0x0001, 0x0000, 0x8066, 0x0000, 0x0009, 0x0008, 0xc0b3, 0x0003,
+ 0x00fe, 0x0000, 0x319e, 0x000b, 0x0038, 0x0000, 0x0060, 0x0008,
+ 0x8062, 0x0008, 0x0019, 0x0000, 0x8066, 0x0000, 0x0009, 0x0008,
+ 0xc0bc, 0x0003, 0x80c0, 0x0009, 0x00ff, 0x0008, 0x7f3e, 0x0008,
+ 0x0d60, 0x0000, 0x0efe, 0x0008, 0x1f80, 0x0001, 0x7f62, 0x0008,
+ 0x8066, 0x0000, 0x0009, 0x0008, 0xc0c6, 0x000b, 0x003a, 0x0008,
+ 0x1dfe, 0x0000, 0x00a7, 0x0003, 0x0036, 0x0008, 0x007d, 0x0004,
+ 0x00e1, 0x000b, 0x8074, 0x0000, 0x2000, 0x0000, 0x00e1, 0x000b,
+ 0x3a44, 0x0002, 0x09c8, 0x0003, 0x8074, 0x0000, 0x1000, 0x0000,
+ 0xadd0, 0x0001, 0x0000, 0x0008, 0x7f0e, 0x0008, 0xb19b, 0x0003,
+ 0xa7d0, 0x0001, 0x0000, 0x0008, 0x7f00, 0x0000, 0xa6d0, 0x0009,
+ 0x0000, 0x0008, 0x00d0, 0x0009, 0x88f1, 0x0003, 0x8074, 0x0000,
+ 0x4040, 0x0008, 0x58e1, 0x0003, 0x5096, 0x000b, 0x3a46, 0x000a,
+ 0x88f1, 0x0003, 0x3a47, 0x0002, 0x08ec, 0x000b, 0x8054, 0x0008,
+ 0x0004, 0x0000, 0x8074, 0x0000, 0x8000, 0x0000, 0x0118, 0x0003,
+ 0x92c0, 0x0009, 0x0fc8, 0x0000, 0x080a, 0x0003, 0x1246, 0x000a,
+ 0x8995, 0x0003, 0x1a60, 0x0000, 0x8062, 0x0008, 0x0002, 0x0000,
+ 0x8066, 0x0000, 0x367a, 0x0000, 0xc0f6, 0x000b, 0x92c0, 0x0009,
+ 0x0780, 0x0008, 0x89af, 0x0003, 0x124b, 0x0002, 0x08ff, 0x0003,
+ 0x2e4d, 0x0002, 0x2e4d, 0x0002, 0x099b, 0x0003, 0x3a46, 0x000a,
+ 0x890c, 0x0003, 0x5901, 0x0003, 0x8054, 0x0008, 0x0004, 0x0000,
+ 0x1243, 0x000a, 0x0916, 0x0003, 0x8010, 0x0008, 0x000d, 0x0000,
+ 0x0189, 0x0004, 0x1810, 0x0000, 0x0189, 0x0004, 0x0116, 0x000b,
+ 0x194d, 0x000a, 0x0910, 0x0003, 0x1243, 0x000a, 0x09a5, 0x000b,
+ 0x5910, 0x0003, 0x8054, 0x0008, 0x0004, 0x0000, 0x017e, 0x000c,
+ 0x1810, 0x0000, 0x0189, 0x0004, 0x8074, 0x0000, 0xf000, 0x0008,
+ 0x0d30, 0x0000, 0x3a42, 0x0002, 0x891e, 0x0003, 0x15fe, 0x0008,
+ 0xb051, 0x000b, 0x000a, 0x000b, 0x8074, 0x0000, 0x0501, 0x0000,
+ 0x8010, 0x0008, 0x000c, 0x0008, 0x0189, 0x0004, 0x000a, 0x000b,
+ 0xbbe0, 0x0009, 0x0030, 0x0008, 0x8934, 0x000b, 0x18fe, 0x0000,
+ 0x3ce0, 0x0009, 0x0931, 0x0003, 0x15fe, 0x0008, 0x3ce0, 0x0009,
+ 0x0931, 0x0003, 0x0179, 0x0004, 0x8076, 0x0008, 0x0040, 0x0000,
+ 0x0176, 0x000b, 0x8076, 0x0008, 0x0041, 0x0008, 0x0176, 0x000b,
+ 0xbbe0, 0x0009, 0x0032, 0x0000, 0x8939, 0x0003, 0x3c1e, 0x0008,
+ 0x0176, 0x000b, 0xbbe0, 0x0009, 0x0037, 0x0000, 0x895b, 0x000b,
+ 0x18fe, 0x0000, 0x3ce0, 0x0009, 0x8931, 0x000b, 0x8076, 0x0008,
+ 0x0040, 0x0000, 0x1a60, 0x0000, 0x8062, 0x0008, 0x000d, 0x0000,
+ 0xa6d0, 0x0009, 0x0000, 0x0008, 0x7f04, 0x0008, 0xa7d0, 0x0001,
+ 0x0000, 0x0008, 0x7f06, 0x0000, 0xa8d0, 0x0001, 0x0000, 0x0008,
+ 0x7f08, 0x0008, 0xa9d0, 0x0009, 0x0000, 0x0008, 0x7f0a, 0x0000,
+ 0x8066, 0x0000, 0x0422, 0x0000, 0xc152, 0x000b, 0x017e, 0x000c,
+ 0x8054, 0x0008, 0x0004, 0x0000, 0x8074, 0x0000, 0xf000, 0x0008,
+ 0x8072, 0x0000, 0x8000, 0x0000, 0x0118, 0x0003, 0xbbe0, 0x0009,
+ 0x0038, 0x0000, 0x896d, 0x000b, 0x18fe, 0x0000, 0x3ce0, 0x0009,
+ 0x096a, 0x000b, 0x15fe, 0x0008, 0x3ce0, 0x0009, 0x892d, 0x0003,
+ 0x0179, 0x0004, 0x8076, 0x0008, 0x0040, 0x0000, 0x8072, 0x0000,
+ 0x8000, 0x0000, 0x01bf, 0x000b, 0x8076, 0x0008, 0x0042, 0x0008,
+ 0x0176, 0x000b, 0xbbe0, 0x0009, 0x0016, 0x0000, 0x8976, 0x000b,
+ 0x3a44, 0x0002, 0x880c, 0x000b, 0x8072, 0x0000, 0x8000, 0x0000,
+ 0x8000, 0x000f, 0x000a, 0x000b, 0x8072, 0x0000, 0x8000, 0x0000,
+ 0x000a, 0x000b, 0x3d30, 0x000a, 0x7f00, 0x0000, 0xbc80, 0x0001,
+ 0x0007, 0x0000, 0x0182, 0x0003, 0x1930, 0x000a, 0x7f00, 0x0000,
+ 0x9880, 0x0001, 0x0007, 0x0000, 0x8060, 0x0000, 0x0400, 0x0000,
+ 0x7f62, 0x0008, 0x8066, 0x0000, 0x000a, 0x0008, 0xc187, 0x0003,
+ 0x4000, 0x000f, 0x2189, 0x0003, 0x0870, 0x0008, 0x4000, 0x000f,
+ 0xbac0, 0x0009, 0x0090, 0x0008, 0x0992, 0x0003, 0x8074, 0x0000,
+ 0x0706, 0x0000, 0x0194, 0x000b, 0x8074, 0x0000, 0x0703, 0x0000,
+ 0x4000, 0x000f, 0x8010, 0x0008, 0x0023, 0x0000, 0x01cd, 0x000b,
+ 0x8010, 0x0008, 0x0008, 0x0000, 0x01cd, 0x000b, 0x8010, 0x0008,
+ 0x0022, 0x0008, 0x01cd, 0x000b, 0x017e, 0x000c, 0x8010, 0x0008,
+ 0x0007, 0x0000, 0x0189, 0x0004, 0x1810, 0x0000, 0x0189, 0x0004,
+ 0x01d7, 0x0003, 0x017e, 0x000c, 0x8010, 0x0008, 0x001b, 0x0008,
+ 0x0189, 0x0004, 0x1810, 0x0000, 0x0189, 0x0004, 0x8074, 0x0000,
+ 0xf080, 0x0000, 0x0d30, 0x0000, 0x000a, 0x000b, 0x8010, 0x0008,
+ 0x0009, 0x0008, 0x01cd, 0x000b, 0x8010, 0x0008, 0x0005, 0x0008,
+ 0x01cd, 0x000b, 0x808c, 0x0008, 0x0001, 0x0000, 0x8010, 0x0008,
+ 0x0004, 0x0000, 0x4143, 0x000a, 0x085f, 0x0003, 0x3a44, 0x0002,
+ 0x880a, 0x000b, 0x0d2a, 0x0008, 0x01cd, 0x000b, 0x8010, 0x0008,
+ 0x0003, 0x0008, 0x01cf, 0x0003, 0x8010, 0x0008, 0x000b, 0x0000,
+ 0x01cf, 0x0003, 0x8010, 0x0008, 0x0002, 0x0000, 0x01cf, 0x0003,
+ 0x3a47, 0x0002, 0x88e1, 0x000b, 0x8010, 0x0008, 0x0006, 0x0008,
+ 0x01cf, 0x0003, 0x8074, 0x0000, 0xf000, 0x0008, 0x0189, 0x0004,
+ 0x018c, 0x0004, 0x3a40, 0x000a, 0x080a, 0x0003, 0x8010, 0x0008,
+ 0x000c, 0x0008, 0x0189, 0x0004, 0x000a, 0x000b, 0x8074, 0x0000,
+ 0xf080, 0x0000, 0x0d30, 0x0000, 0x2e4d, 0x0002, 0x2e4d, 0x0002,
+ 0x09e0, 0x0003, 0x8054, 0x0008, 0x0019, 0x0000, 0x000a, 0x000b,
+ 0x8054, 0x0008, 0x0009, 0x0008, 0x000a, 0x000b, 0x3a44, 0x0002,
+ 0x880a, 0x000b, 0x01c2, 0x000b, 0x460b, 0xf5c6, 0x0001, 0x0002,
+ 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080, 0x0100, 0x0200,
+ 0x0400, 0x0800, 0x1000, 0x2000, 0x4000, 0x8000, 0x92c4
};
#ifdef UNIQUE_FW_NAME
-unsigned short fw2300flx_length01 = 0xdb56;
+unsigned short fw2300flx_length01 = 0xdbb7;
#else
-unsigned short risc_code_length01 = 0xdb56;
+unsigned short risc_code_length01 = 0xdbb7;
#endif
diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c
index fc25cd834668..48e460eef05a 100644
--- a/drivers/scsi/qla2xxx/qla_attr.c
+++ b/drivers/scsi/qla2xxx/qla_attr.c
@@ -1,20 +1,8 @@
/*
- * QLOGIC LINUX SOFTWARE
- *
- * QLogic ISP2x00 device driver for Linux 2.6.x
- * Copyright (C) 2003-2005 QLogic Corporation
- * (www.qlogic.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, 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.
+ * QLogic Fibre Channel HBA Driver
+ * Copyright (c) 2003-2005 QLogic Corporation
*
+ * See LICENSE.qla2xxx for copyright and licensing details.
*/
#include "qla_def.h"
@@ -319,6 +307,83 @@ qla2x00_state_show(struct class_device *cdev, char *buf)
return len;
}
+static ssize_t
+qla2x00_zio_show(struct class_device *cdev, char *buf)
+{
+ scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev));
+ int len = 0;
+
+ switch (ha->zio_mode) {
+ case QLA_ZIO_MODE_5:
+ len += snprintf(buf + len, PAGE_SIZE-len, "Mode 5\n");
+ break;
+ case QLA_ZIO_MODE_6:
+ len += snprintf(buf + len, PAGE_SIZE-len, "Mode 6\n");
+ break;
+ case QLA_ZIO_DISABLED:
+ len += snprintf(buf + len, PAGE_SIZE-len, "Disabled\n");
+ break;
+ }
+ return len;
+}
+
+static ssize_t
+qla2x00_zio_store(struct class_device *cdev, const char *buf, size_t count)
+{
+ scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev));
+ int val = 0;
+ uint16_t zio_mode;
+
+ if (sscanf(buf, "%d", &val) != 1)
+ return -EINVAL;
+
+ switch (val) {
+ case 1:
+ zio_mode = QLA_ZIO_MODE_5;
+ break;
+ case 2:
+ zio_mode = QLA_ZIO_MODE_6;
+ break;
+ default:
+ zio_mode = QLA_ZIO_DISABLED;
+ break;
+ }
+
+ /* Update per-hba values and queue a reset. */
+ if (zio_mode != QLA_ZIO_DISABLED || ha->zio_mode != QLA_ZIO_DISABLED) {
+ ha->zio_mode = zio_mode;
+ set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
+ }
+ return strlen(buf);
+}
+
+static ssize_t
+qla2x00_zio_timer_show(struct class_device *cdev, char *buf)
+{
+ scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev));
+
+ return snprintf(buf, PAGE_SIZE, "%d us\n", ha->zio_timer * 100);
+}
+
+static ssize_t
+qla2x00_zio_timer_store(struct class_device *cdev, const char *buf,
+ size_t count)
+{
+ scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev));
+ int val = 0;
+ uint16_t zio_timer;
+
+ if (sscanf(buf, "%d", &val) != 1)
+ return -EINVAL;
+ if (val > 25500 || val < 100)
+ return -ERANGE;
+
+ zio_timer = (uint16_t)(val / 100);
+ ha->zio_timer = zio_timer;
+
+ return strlen(buf);
+}
+
static CLASS_DEVICE_ATTR(driver_version, S_IRUGO, qla2x00_drvr_version_show,
NULL);
static CLASS_DEVICE_ATTR(fw_version, S_IRUGO, qla2x00_fw_version_show, NULL);
@@ -329,6 +394,10 @@ static CLASS_DEVICE_ATTR(model_name, S_IRUGO, qla2x00_model_name_show, NULL);
static CLASS_DEVICE_ATTR(model_desc, S_IRUGO, qla2x00_model_desc_show, NULL);
static CLASS_DEVICE_ATTR(pci_info, S_IRUGO, qla2x00_pci_info_show, NULL);
static CLASS_DEVICE_ATTR(state, S_IRUGO, qla2x00_state_show, NULL);
+static CLASS_DEVICE_ATTR(zio, S_IRUGO | S_IWUSR, qla2x00_zio_show,
+ qla2x00_zio_store);
+static CLASS_DEVICE_ATTR(zio_timer, S_IRUGO | S_IWUSR, qla2x00_zio_timer_show,
+ qla2x00_zio_timer_store);
struct class_device_attribute *qla2x00_host_attrs[] = {
&class_device_attr_driver_version,
@@ -340,6 +409,8 @@ struct class_device_attribute *qla2x00_host_attrs[] = {
&class_device_attr_model_desc,
&class_device_attr_pci_info,
&class_device_attr_state,
+ &class_device_attr_zio,
+ &class_device_attr_zio_timer,
NULL,
};
@@ -432,6 +503,15 @@ qla2x00_set_rport_loss_tmo(struct fc_rport *rport, uint32_t timeout)
rport->dev_loss_tmo = ha->port_down_retry_count + 5;
}
+static int
+qla2x00_issue_lip(struct Scsi_Host *shost)
+{
+ scsi_qla_host_t *ha = to_qla_host(shost);
+
+ set_bit(LOOP_RESET_NEEDED, &ha->dpc_flags);
+ return 0;
+}
+
struct fc_function_template qla2xxx_transport_functions = {
.show_host_node_name = 1,
@@ -455,6 +535,7 @@ struct fc_function_template qla2xxx_transport_functions = {
.set_rport_dev_loss_tmo = qla2x00_set_rport_loss_tmo,
.show_rport_dev_loss_tmo = 1,
+ .issue_fc_host_lip = qla2x00_issue_lip,
};
void
diff --git a/drivers/scsi/qla2xxx/qla_dbg.c b/drivers/scsi/qla2xxx/qla_dbg.c
index 9791496fa788..89793c1c06b1 100644
--- a/drivers/scsi/qla2xxx/qla_dbg.c
+++ b/drivers/scsi/qla2xxx/qla_dbg.c
@@ -1,20 +1,8 @@
/*
- * QLOGIC LINUX SOFTWARE
- *
- * QLogic ISP2x00 device driver for Linux 2.6.x
- * Copyright (C) 2003-2005 QLogic Corporation
- * (www.qlogic.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, 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.
+ * QLogic Fibre Channel HBA Driver
+ * Copyright (c) 2003-2005 QLogic Corporation
*
+ * See LICENSE.qla2xxx for copyright and licensing details.
*/
#include "qla_def.h"
diff --git a/drivers/scsi/qla2xxx/qla_dbg.h b/drivers/scsi/qla2xxx/qla_dbg.h
index 9684e7a91fa9..935a59a8c054 100644
--- a/drivers/scsi/qla2xxx/qla_dbg.h
+++ b/drivers/scsi/qla2xxx/qla_dbg.h
@@ -1,22 +1,9 @@
-/******************************************************************************
- * QLOGIC LINUX SOFTWARE
- *
- * QLogic ISP2x00 device driver for Linux 2.6.x
- * Copyright (C) 2003-2005 QLogic Corporation
- * (www.qlogic.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, 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.
+/*
+ * QLogic Fibre Channel HBA Driver
+ * Copyright (c) 2003-2005 QLogic Corporation
*
- ******************************************************************************/
-
+ * See LICENSE.qla2xxx for copyright and licensing details.
+ */
/*
* Driver debug definitions.
*/
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index b455c31405e4..7096945ea234 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -1,22 +1,9 @@
-/********************************************************************************
-* QLOGIC LINUX SOFTWARE
-*
-* QLogic ISP2x00 device driver for Linux 2.6.x
-* Copyright (C) 2003-2005 QLogic Corporation
-* (www.qlogic.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, 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.
-**
-******************************************************************************/
-
+/*
+ * QLogic Fibre Channel HBA Driver
+ * Copyright (c) 2003-2005 QLogic Corporation
+ *
+ * See LICENSE.qla2xxx for copyright and licensing details.
+ */
#ifndef __QLA_DEF_H
#define __QLA_DEF_H
@@ -34,6 +21,7 @@
#include <linux/spinlock.h>
#include <linux/completion.h>
#include <linux/interrupt.h>
+#include <linux/workqueue.h>
#include <asm/semaphore.h>
#include <scsi/scsi.h>
@@ -823,6 +811,11 @@ typedef struct {
#define PD_STATE_WAIT_PORT_LOGOUT_ACK 11
+#define QLA_ZIO_MODE_5 (BIT_2 | BIT_0)
+#define QLA_ZIO_MODE_6 (BIT_2 | BIT_1)
+#define QLA_ZIO_DISABLED 0
+#define QLA_ZIO_DEFAULT_TIMER 2
+
/*
* ISP Initialization Control Block.
* Little endian except where noted.
@@ -1673,6 +1666,8 @@ typedef struct fc_port {
struct fc_rport *rport;
u32 supported_classes;
+ struct work_struct rport_add_work;
+ struct work_struct rport_del_work;
} fc_port_t;
/*
@@ -2470,6 +2465,9 @@ typedef struct scsi_qla_host {
/* Needed for BEACON */
uint16_t beacon_blink_led;
uint16_t beacon_green_on;
+
+ uint16_t zio_mode;
+ uint16_t zio_timer;
} scsi_qla_host_t;
diff --git a/drivers/scsi/qla2xxx/qla_fw.h b/drivers/scsi/qla2xxx/qla_fw.h
index fd9df163410c..9fb562aa4acc 100644
--- a/drivers/scsi/qla2xxx/qla_fw.h
+++ b/drivers/scsi/qla2xxx/qla_fw.h
@@ -1,23 +1,9 @@
-
-/********************************************************************************
-* QLOGIC LINUX SOFTWARE
-*
-* QLogic ISP2x00 device driver for Linux 2.6.x
-* Copyright (C) 2003-2005 QLogic Corporation
-* (www.qlogic.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, 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.
-**
-******************************************************************************/
-
+/*
+ * QLogic Fibre Channel HBA Driver
+ * Copyright (c) 2003-2005 QLogic Corporation
+ *
+ * See LICENSE.qla2xxx for copyright and licensing details.
+ */
#ifndef __QLA_FW_H
#define __QLA_FW_H
@@ -394,7 +380,7 @@ struct cmd_type_6 {
uint16_t fcp_rsp_dsd_len; /* FCP_RSP DSD length. */
- uint8_t lun[8]; /* FCP LUN (BE). */
+ struct scsi_lun lun; /* FCP LUN (BE). */
uint16_t control_flags; /* Control flags. */
#define CF_DATA_SEG_DESCR_ENABLE BIT_2
@@ -432,7 +418,7 @@ struct cmd_type_7 {
uint16_t dseg_count; /* Data segment count. */
uint16_t reserved_1;
- uint8_t lun[8]; /* FCP LUN (BE). */
+ struct scsi_lun lun; /* FCP LUN (BE). */
uint16_t task_mgmt_flags; /* Task management flags. */
#define TMF_CLEAR_ACA BIT_14
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h
index 1ed32e7b5472..fedcb0d3fc72 100644
--- a/drivers/scsi/qla2xxx/qla_gbl.h
+++ b/drivers/scsi/qla2xxx/qla_gbl.h
@@ -1,25 +1,9 @@
-/********************************************************************************
-* QLOGIC LINUX SOFTWARE
-*
-* QLogic ISP2x00 device driver for Linux 2.6.x
-* Copyright (C) 2003-2005 QLogic Corporation
-* (www.qlogic.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, 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.
-*
-******************************************************************************
-* Global include file.
-******************************************************************************/
-
-
+/*
+ * QLogic Fibre Channel HBA Driver
+ * Copyright (c) 2003-2005 QLogic Corporation
+ *
+ * See LICENSE.qla2xxx for copyright and licensing details.
+ */
#ifndef __QLA_GBL_H
#define __QLA_GBL_H
@@ -52,7 +36,7 @@ extern int qla2x00_load_risc(struct scsi_qla_host *, uint32_t *);
extern int qla24xx_load_risc_flash(scsi_qla_host_t *, uint32_t *);
extern int qla24xx_load_risc_hotplug(scsi_qla_host_t *, uint32_t *);
-extern fc_port_t *qla2x00_alloc_fcport(scsi_qla_host_t *, int);
+extern fc_port_t *qla2x00_alloc_fcport(scsi_qla_host_t *, gfp_t);
extern int qla2x00_loop_resync(scsi_qla_host_t *);
@@ -76,8 +60,6 @@ extern char qla2x00_version_str[];
extern int ql2xlogintimeout;
extern int qlport_down_retry;
extern int ql2xplogiabsentdevice;
-extern int ql2xenablezio;
-extern int ql2xintrdelaytimer;
extern int ql2xloginretrycount;
extern int ql2xfdmienable;
@@ -223,6 +205,7 @@ extern irqreturn_t qla2100_intr_handler(int, void *, struct pt_regs *);
extern irqreturn_t qla2300_intr_handler(int, void *, struct pt_regs *);
extern irqreturn_t qla24xx_intr_handler(int, void *, struct pt_regs *);
extern void qla2x00_process_response_queue(struct scsi_qla_host *);
+extern void qla24xx_process_response_queue(struct scsi_qla_host *);
/*
* Global Function Prototypes in qla_sup.c source file.
@@ -277,7 +260,7 @@ extern int qla2x00_fdmi_register(scsi_qla_host_t *);
/*
* Global Function Prototypes in qla_rscn.c source file.
*/
-extern fc_port_t *qla2x00_alloc_rscn_fcport(scsi_qla_host_t *, int);
+extern fc_port_t *qla2x00_alloc_rscn_fcport(scsi_qla_host_t *, gfp_t);
extern int qla2x00_handle_port_rscn(scsi_qla_host_t *, uint32_t, fc_port_t *,
int);
extern void qla2x00_process_iodesc(scsi_qla_host_t *, struct mbx_entry *);
diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c
index e7b138c2e339..cd6f7c3cfe68 100644
--- a/drivers/scsi/qla2xxx/qla_gs.c
+++ b/drivers/scsi/qla2xxx/qla_gs.c
@@ -1,20 +1,8 @@
/*
- * QLOGIC LINUX SOFTWARE
- *
- * QLogic ISP2x00 device driver for Linux 2.6.x
- * Copyright (C) 2003-2005 QLogic Corporation
- * (www.qlogic.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, 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.
+ * QLogic Fibre Channel HBA Driver
+ * Copyright (c) 2003-2005 QLogic Corporation
*
+ * See LICENSE.qla2xxx for copyright and licensing details.
*/
#include "qla_def.h"
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index 23d095d3817b..72d9090df3df 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -1,20 +1,8 @@
/*
- * QLOGIC LINUX SOFTWARE
- *
- * QLogic ISP2x00 device driver for Linux 2.6.x
- * Copyright (C) 2003-2005 QLogic Corporation
- * (www.qlogic.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, 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.
+ * QLogic Fibre Channel HBA Driver
+ * Copyright (c) 2003-2005 QLogic Corporation
*
+ * See LICENSE.qla2xxx for copyright and licensing details.
*/
#include "qla_def.h"
@@ -1372,7 +1360,6 @@ qla2x00_nvram_config(scsi_qla_host_t *ha)
nvram_t *nv = (nvram_t *)ha->request_ring;
uint8_t *ptr = (uint8_t *)ha->request_ring;
struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
- uint8_t timer_mode;
rval = QLA_SUCCESS;
@@ -1650,22 +1637,26 @@ qla2x00_nvram_config(scsi_qla_host_t *ha)
ha->flags.process_response_queue = 1;
} else {
- /* Enable ZIO -- Support mode 5 only. */
- timer_mode = icb->add_firmware_options[0] &
- (BIT_3 | BIT_2 | BIT_1 | BIT_0);
+ /* Enable ZIO. */
+ if (!ha->flags.init_done) {
+ ha->zio_mode = icb->add_firmware_options[0] &
+ (BIT_3 | BIT_2 | BIT_1 | BIT_0);
+ ha->zio_timer = icb->interrupt_delay_timer ?
+ icb->interrupt_delay_timer: 2;
+ }
icb->add_firmware_options[0] &=
~(BIT_3 | BIT_2 | BIT_1 | BIT_0);
- if (ql2xenablezio)
- timer_mode = BIT_2 | BIT_0;
- if (timer_mode == (BIT_2 | BIT_0)) {
- DEBUG2(printk("scsi(%ld): ZIO enabled; timer delay "
- "(%d).\n", ha->host_no, ql2xintrdelaytimer));
+ ha->flags.process_response_queue = 0;
+ if (ha->zio_mode != QLA_ZIO_DISABLED) {
+ DEBUG2(printk("scsi(%ld): ZIO mode %d enabled; timer "
+ "delay (%d us).\n", ha->host_no, ha->zio_mode,
+ ha->zio_timer * 100));
qla_printk(KERN_INFO, ha,
- "ZIO enabled; timer delay (%d).\n",
- ql2xintrdelaytimer);
+ "ZIO mode %d enabled; timer delay (%d us).\n",
+ ha->zio_mode, ha->zio_timer * 100);
- icb->add_firmware_options[0] |= timer_mode;
- icb->interrupt_delay_timer = ql2xintrdelaytimer;
+ icb->add_firmware_options[0] |= (uint8_t)ha->zio_mode;
+ icb->interrupt_delay_timer = (uint8_t)ha->zio_timer;
ha->flags.process_response_queue = 1;
}
}
@@ -1677,6 +1668,24 @@ qla2x00_nvram_config(scsi_qla_host_t *ha)
return (rval);
}
+static void
+qla2x00_rport_add(void *data)
+{
+ fc_port_t *fcport = data;
+
+ qla2x00_reg_remote_port(fcport->ha, fcport);
+}
+
+static void
+qla2x00_rport_del(void *data)
+{
+ fc_port_t *fcport = data;
+
+ if (fcport->rport)
+ fc_remote_port_delete(fcport->rport);
+ fcport->rport = NULL;
+}
+
/**
* qla2x00_alloc_fcport() - Allocate a generic fcport.
* @ha: HA context
@@ -1685,7 +1694,7 @@ qla2x00_nvram_config(scsi_qla_host_t *ha)
* Returns a pointer to the allocated fcport, or NULL, if none available.
*/
fc_port_t *
-qla2x00_alloc_fcport(scsi_qla_host_t *ha, int flags)
+qla2x00_alloc_fcport(scsi_qla_host_t *ha, gfp_t flags)
{
fc_port_t *fcport;
@@ -1702,6 +1711,8 @@ qla2x00_alloc_fcport(scsi_qla_host_t *ha, int flags)
atomic_set(&fcport->state, FCS_UNCONFIGURED);
fcport->flags = FCF_RLC_SUPPORT;
fcport->supported_classes = FC_COS_UNSPECIFIED;
+ INIT_WORK(&fcport->rport_add_work, qla2x00_rport_add, fcport);
+ INIT_WORK(&fcport->rport_del_work, qla2x00_rport_del, fcport);
return (fcport);
}
@@ -1966,8 +1977,7 @@ qla2x00_configure_local_loop(scsi_qla_host_t *ha)
}
cleanup_allocation:
- if (new_fcport)
- kfree(new_fcport);
+ kfree(new_fcport);
if (rval != QLA_SUCCESS) {
DEBUG2(printk("scsi(%ld): Configure local loop error exit: "
@@ -2065,8 +2075,8 @@ qla2x00_reg_remote_port(scsi_qla_host_t *ha, fc_port_t *fcport)
struct fc_rport *rport;
if (fcport->rport) {
- fc_remote_port_unblock(fcport->rport);
- return;
+ fc_remote_port_delete(fcport->rport);
+ fcport->rport = NULL;
}
rport_ids.node_name = wwn_to_u64(fcport->node_name);
@@ -2080,7 +2090,7 @@ qla2x00_reg_remote_port(scsi_qla_host_t *ha, fc_port_t *fcport)
"Unable to allocate fc remote port!\n");
return;
}
- rport->dd_data = fcport;
+ *((fc_port_t **)rport->dd_data) = fcport;
rport->supported_classes = fcport->supported_classes;
rport_ids.roles = FC_RPORT_ROLE_UNKNOWN;
@@ -2337,8 +2347,7 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *ha, struct list_head *new_fcports)
/* Allocate temporary fcport for any new fcports discovered. */
new_fcport = qla2x00_alloc_fcport(ha, GFP_KERNEL);
if (new_fcport == NULL) {
- if (swl)
- kfree(swl);
+ kfree(swl);
return (QLA_MEMORY_ALLOC_FAILED);
}
new_fcport->flags |= (FCF_FABRIC_DEVICE | FCF_LOGIN_NEEDED);
@@ -2474,19 +2483,15 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *ha, struct list_head *new_fcports)
nxt_d_id.b24 = new_fcport->d_id.b24;
new_fcport = qla2x00_alloc_fcport(ha, GFP_KERNEL);
if (new_fcport == NULL) {
- if (swl)
- kfree(swl);
+ kfree(swl);
return (QLA_MEMORY_ALLOC_FAILED);
}
new_fcport->flags |= (FCF_FABRIC_DEVICE | FCF_LOGIN_NEEDED);
new_fcport->d_id.b24 = nxt_d_id.b24;
}
- if (swl)
- kfree(swl);
-
- if (new_fcport)
- kfree(new_fcport);
+ kfree(swl);
+ kfree(new_fcport);
if (!list_empty(new_fcports))
ha->device_flags |= DFLG_FABRIC_DEVICES;
@@ -2858,7 +2863,7 @@ qla2x00_fabric_login(scsi_qla_host_t *ha, fc_port_t *fcport,
fcport->d_id.b.domain, fcport->d_id.b.area,
fcport->d_id.b.al_pa);
fcport->loop_id = FC_NO_LOOP_ID;
- atomic_set(&fcport->state, FCS_DEVICE_DEAD);
+ fcport->login_retry = 0;
rval = 3;
break;
@@ -3442,6 +3447,30 @@ qla24xx_nvram_config(scsi_qla_host_t *ha)
if (ql2xloginretrycount)
ha->login_retry_count = ql2xloginretrycount;
+ /* Enable ZIO. */
+ if (!ha->flags.init_done) {
+ ha->zio_mode = le32_to_cpu(icb->firmware_options_2) &
+ (BIT_3 | BIT_2 | BIT_1 | BIT_0);
+ ha->zio_timer = le16_to_cpu(icb->interrupt_delay_timer) ?
+ le16_to_cpu(icb->interrupt_delay_timer): 2;
+ }
+ icb->firmware_options_2 &= __constant_cpu_to_le32(
+ ~(BIT_3 | BIT_2 | BIT_1 | BIT_0));
+ ha->flags.process_response_queue = 0;
+ if (ha->zio_mode != QLA_ZIO_DISABLED) {
+ DEBUG2(printk("scsi(%ld): ZIO mode %d enabled; timer delay "
+ "(%d us).\n", ha->host_no, ha->zio_mode,
+ ha->zio_timer * 100));
+ qla_printk(KERN_INFO, ha,
+ "ZIO mode %d enabled; timer delay (%d us).\n",
+ ha->zio_mode, ha->zio_timer * 100);
+
+ icb->firmware_options_2 |= cpu_to_le32(
+ (uint32_t)ha->zio_mode);
+ icb->interrupt_delay_timer = cpu_to_le16(ha->zio_timer);
+ ha->flags.process_response_queue = 1;
+ }
+
if (rval) {
DEBUG2_3(printk(KERN_WARNING
"scsi(%ld): NVRAM configuration failed!\n", ha->host_no));
diff --git a/drivers/scsi/qla2xxx/qla_inline.h b/drivers/scsi/qla2xxx/qla_inline.h
index b9ff85b03a5f..ecc3741a452e 100644
--- a/drivers/scsi/qla2xxx/qla_inline.h
+++ b/drivers/scsi/qla2xxx/qla_inline.h
@@ -1,23 +1,10 @@
/*
- * QLOGIC LINUX SOFTWARE
- *
- * QLogic ISP2x00 device driver for Linux 2.6.x
- * Copyright (C) 2003-2005 QLogic Corporation
- * (www.qlogic.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, 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.
+ * QLogic Fibre Channel HBA Driver
+ * Copyright (c) 2003-2005 QLogic Corporation
*
+ * See LICENSE.qla2xxx for copyright and licensing details.
*/
-
static __inline__ uint16_t qla2x00_debounce_register(volatile uint16_t __iomem *);
/*
* qla2x00_debounce_register
diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c
index 37f82e2cd7fb..7ec0b8d6f07b 100644
--- a/drivers/scsi/qla2xxx/qla_iocb.c
+++ b/drivers/scsi/qla2xxx/qla_iocb.c
@@ -1,22 +1,9 @@
-/******************************************************************************
- * QLOGIC LINUX SOFTWARE
+/*
+ * QLogic Fibre Channel HBA Driver
+ * Copyright (c) 2003-2005 QLogic Corporation
*
- * QLogic ISP2x00 device driver for Linux 2.6.x
- * Copyright (C) 2003-2005 QLogic Corporation
- * (www.qlogic.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, 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.
- *
- ******************************************************************************/
-
+ * See LICENSE.qla2xxx for copyright and licensing details.
+ */
#include "qla_def.h"
#include <linux/blkdev.h>
@@ -316,7 +303,6 @@ qla2x00_start_scsi(srb_t *sp)
uint16_t req_cnt;
uint16_t tot_dsds;
struct device_reg_2xxx __iomem *reg;
- char tag[2];
/* Setup device pointers. */
ret = 0;
@@ -401,18 +387,6 @@ qla2x00_start_scsi(srb_t *sp)
/* Update tagged queuing modifier */
cmd_pkt->control_flags = __constant_cpu_to_le16(CF_SIMPLE_TAG);
- if (scsi_populate_tag_msg(cmd, tag)) {
- switch (tag[0]) {
- case MSG_HEAD_TAG:
- cmd_pkt->control_flags =
- __constant_cpu_to_le16(CF_HEAD_TAG);
- break;
- case MSG_ORDERED_TAG:
- cmd_pkt->control_flags =
- __constant_cpu_to_le16(CF_ORDERED_TAG);
- break;
- }
- }
/* Load SCSI command packet. */
memcpy(cmd_pkt->scsi_cdb, cmd->cmnd, cmd->cmd_len);
@@ -440,6 +414,11 @@ qla2x00_start_scsi(srb_t *sp)
WRT_REG_WORD(ISP_REQ_Q_IN(ha, reg), ha->req_ring_index);
RD_REG_WORD_RELAXED(ISP_REQ_Q_IN(ha, reg)); /* PCI Posting. */
+ /* Manage unprocessed RIO/ZIO commands in response queue. */
+ if (ha->flags.process_response_queue &&
+ ha->response_ring_ptr->signature != RESPONSE_PROCESSED)
+ qla2x00_process_response_queue(ha);
+
spin_unlock_irqrestore(&ha->hardware_lock, flags);
return (QLA_SUCCESS);
@@ -749,7 +728,6 @@ qla24xx_start_scsi(srb_t *sp)
uint16_t req_cnt;
uint16_t tot_dsds;
struct device_reg_24xx __iomem *reg;
- char tag[2];
/* Setup device pointers. */
ret = 0;
@@ -824,6 +802,7 @@ qla24xx_start_scsi(srb_t *sp)
cmd_pkt->handle = handle;
/* Zero out remaining portion of packet. */
+ /* tagged queuing modifier -- default is TSK_SIMPLE (0). */
clr_ptr = (uint32_t *)cmd_pkt + 2;
memset(clr_ptr, 0, REQUEST_ENTRY_SIZE - 8);
cmd_pkt->dseg_count = cpu_to_le16(tot_dsds);
@@ -834,20 +813,7 @@ qla24xx_start_scsi(srb_t *sp)
cmd_pkt->port_id[1] = sp->fcport->d_id.b.area;
cmd_pkt->port_id[2] = sp->fcport->d_id.b.domain;
- cmd_pkt->lun[1] = LSB(sp->cmd->device->lun);
- cmd_pkt->lun[2] = MSB(sp->cmd->device->lun);
-
- /* Update tagged queuing modifier -- default is TSK_SIMPLE (0). */
- if (scsi_populate_tag_msg(cmd, tag)) {
- switch (tag[0]) {
- case MSG_HEAD_TAG:
- cmd_pkt->task = TSK_HEAD_OF_QUEUE;
- break;
- case MSG_ORDERED_TAG:
- cmd_pkt->task = TSK_ORDERED;
- break;
- }
- }
+ int_to_scsilun(sp->cmd->device->lun, &cmd_pkt->lun);
/* Load SCSI command packet. */
memcpy(cmd_pkt->fcp_cdb, cmd->cmnd, cmd->cmd_len);
@@ -877,6 +843,11 @@ qla24xx_start_scsi(srb_t *sp)
WRT_REG_DWORD(&reg->req_q_in, ha->req_ring_index);
RD_REG_DWORD_RELAXED(&reg->req_q_in); /* PCI Posting. */
+ /* Manage unprocessed RIO/ZIO commands in response queue. */
+ if (ha->flags.process_response_queue &&
+ ha->response_ring_ptr->signature != RESPONSE_PROCESSED)
+ qla24xx_process_response_queue(ha);
+
spin_unlock_irqrestore(&ha->hardware_lock, flags);
return QLA_SUCCESS;
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
index c255bb0268a9..09afc0f06bd4 100644
--- a/drivers/scsi/qla2xxx/qla_isr.c
+++ b/drivers/scsi/qla2xxx/qla_isr.c
@@ -1,33 +1,19 @@
/*
- * QLOGIC LINUX SOFTWARE
- *
- * QLogic ISP2x00 device driver for Linux 2.6.x
- * Copyright (C) 2003-2005 QLogic Corporation
- * (www.qlogic.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, 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.
+ * QLogic Fibre Channel HBA Driver
+ * Copyright (c) 2003-2005 QLogic Corporation
*
+ * See LICENSE.qla2xxx for copyright and licensing details.
*/
#include "qla_def.h"
static void qla2x00_mbx_completion(scsi_qla_host_t *, uint16_t);
static void qla2x00_async_event(scsi_qla_host_t *, uint16_t *);
static void qla2x00_process_completed_request(struct scsi_qla_host *, uint32_t);
-void qla2x00_process_response_queue(struct scsi_qla_host *);
static void qla2x00_status_entry(scsi_qla_host_t *, void *);
static void qla2x00_status_cont_entry(scsi_qla_host_t *, sts_cont_entry_t *);
static void qla2x00_error_entry(scsi_qla_host_t *, sts_entry_t *);
static void qla2x00_ms_entry(scsi_qla_host_t *, ms_iocb_entry_t *);
-void qla24xx_process_response_queue(scsi_qla_host_t *);
static void qla24xx_ms_entry(scsi_qla_host_t *, struct ct_entry_24xx *);
/**
@@ -651,7 +637,10 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb)
"scsi(%ld): [R|Z]IO update completion.\n",
ha->host_no));
- qla2x00_process_response_queue(ha);
+ if (IS_QLA24XX(ha) || IS_QLA25XX(ha))
+ qla24xx_process_response_queue(ha);
+ else
+ qla2x00_process_response_queue(ha);
break;
case MBA_DISCARD_RND_FRAME:
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c
index 13e1c9047079..ad3cacb9192d 100644
--- a/drivers/scsi/qla2xxx/qla_mbx.c
+++ b/drivers/scsi/qla2xxx/qla_mbx.c
@@ -1,20 +1,8 @@
/*
- * QLOGIC LINUX SOFTWARE
- *
- * QLogic ISP2x00 device driver for Linux 2.6.x
- * Copyright (C) 2003-2005 QLogic Corporation
- * (www.qlogic.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, 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.
+ * QLogic Fibre Channel HBA Driver
+ * Copyright (c) 2003-2005 QLogic Corporation
*
+ * See LICENSE.qla2xxx for copyright and licensing details.
*/
#include "qla_def.h"
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index 7aec93f9d423..c58c9d97b041 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -1,20 +1,8 @@
/*
- * QLOGIC LINUX SOFTWARE
- *
- * QLogic ISP2x00 device driver for Linux 2.6.x
- * Copyright (C) 2003-2005 QLogic Corporation
- * (www.qlogic.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, 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.
+ * QLogic Fibre Channel HBA Driver
+ * Copyright (c) 2003-2005 QLogic Corporation
*
+ * See LICENSE.qla2xxx for copyright and licensing details.
*/
#include "qla_def.h"
@@ -61,19 +49,6 @@ MODULE_PARM_DESC(ql2xplogiabsentdevice,
"a Fabric scan. This is needed for several broken switches."
"Default is 0 - no PLOGI. 1 - perfom PLOGI.");
-int ql2xenablezio = 0;
-module_param(ql2xenablezio, int, S_IRUGO|S_IRUSR);
-MODULE_PARM_DESC(ql2xenablezio,
- "Option to enable ZIO:If 1 then enable it otherwise"
- " use the default set in the NVRAM."
- " Default is 0 : disabled");
-
-int ql2xintrdelaytimer = 10;
-module_param(ql2xintrdelaytimer, int, S_IRUGO|S_IRUSR);
-MODULE_PARM_DESC(ql2xintrdelaytimer,
- "ZIO: Waiting time for Firmware before it generates an "
- "interrupt to the host to notify completion of request.");
-
int ql2xloginretrycount = 0;
module_param(ql2xloginretrycount, int, S_IRUGO|S_IRUSR);
MODULE_PARM_DESC(ql2xloginretrycount,
@@ -373,11 +348,13 @@ qla2x00_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
{
scsi_qla_host_t *ha = to_qla_host(cmd->device->host);
fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata;
+ struct fc_rport *rport = starget_to_rport(scsi_target(cmd->device));
srb_t *sp;
int rval;
- if (!fcport) {
- cmd->result = DID_NO_CONNECT << 16;
+ rval = fc_remote_port_chkready(rport);
+ if (rval) {
+ cmd->result = rval;
goto qc_fail_command;
}
@@ -400,16 +377,6 @@ qla2x00_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
if (rval != QLA_SUCCESS)
goto qc_host_busy_free_sp;
- /* Manage unprocessed RIO/ZIO commands in response queue. */
- if (ha->flags.online && ha->flags.process_response_queue &&
- ha->response_ring_ptr->signature != RESPONSE_PROCESSED) {
- unsigned long flags;
-
- spin_lock_irqsave(&ha->hardware_lock, flags);
- qla2x00_process_response_queue(ha);
- spin_unlock_irqrestore(&ha->hardware_lock, flags);
- }
-
spin_lock_irq(ha->host->host_lock);
return 0;
@@ -436,11 +403,13 @@ qla24xx_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
{
scsi_qla_host_t *ha = to_qla_host(cmd->device->host);
fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata;
+ struct fc_rport *rport = starget_to_rport(scsi_target(cmd->device));
srb_t *sp;
int rval;
- if (!fcport) {
- cmd->result = DID_NO_CONNECT << 16;
+ rval = fc_remote_port_chkready(rport);
+ if (rval) {
+ cmd->result = rval;
goto qc24_fail_command;
}
@@ -797,29 +766,19 @@ qla2xxx_eh_device_reset(struct scsi_cmnd *cmd)
goto eh_dev_reset_done;
}
- /*
- * If we are coming down the EH path, wait for all commands to
- * complete for the device.
- */
- if (cmd->device->host->eh_active) {
- if (qla2x00_eh_wait_for_pending_target_commands(ha, id))
- ret = FAILED;
-
- if (ret == FAILED) {
- DEBUG3(printk("%s(%ld): failed while waiting for "
- "commands\n", __func__, ha->host_no));
- qla_printk(KERN_INFO, ha,
- "%s: failed while waiting for commands\n",
- __func__);
-
- goto eh_dev_reset_done;
- }
- }
-
- qla_printk(KERN_INFO, ha,
- "scsi(%ld:%d:%d): DEVICE RESET SUCCEEDED.\n", ha->host_no, id, lun);
-
-eh_dev_reset_done:
+ /* Flush outstanding commands. */
+ if (qla2x00_eh_wait_for_pending_target_commands(ha, id))
+ ret = FAILED;
+ if (ret == FAILED) {
+ DEBUG3(printk("%s(%ld): failed while waiting for commands\n",
+ __func__, ha->host_no));
+ qla_printk(KERN_INFO, ha,
+ "%s: failed while waiting for commands\n", __func__);
+ } else
+ qla_printk(KERN_INFO, ha,
+ "scsi(%ld:%d:%d): DEVICE RESET SUCCEEDED.\n", ha->host_no,
+ id, lun);
+ eh_dev_reset_done:
return ret;
}
@@ -921,10 +880,9 @@ qla2xxx_eh_bus_reset(struct scsi_cmnd *cmd)
if (ret == FAILED)
goto eh_bus_reset_done;
- /* Waiting for our command in done_queue to be returned to OS.*/
- if (cmd->device->host->eh_active)
- if (!qla2x00_eh_wait_for_pending_commands(ha))
- ret = FAILED;
+ /* Flush outstanding commands. */
+ if (!qla2x00_eh_wait_for_pending_commands(ha))
+ ret = FAILED;
eh_bus_reset_done:
qla_printk(KERN_INFO, ha, "%s: reset %s\n", __func__,
@@ -1087,10 +1045,10 @@ qla2xxx_slave_alloc(struct scsi_device *sdev)
{
struct fc_rport *rport = starget_to_rport(scsi_target(sdev));
- if (!rport)
+ if (!rport || fc_remote_port_chkready(rport))
return -ENXIO;
- sdev->hostdata = rport->dd_data;
+ sdev->hostdata = *(fc_port_t **)rport->dd_data;
return 0;
}
@@ -1682,7 +1640,8 @@ void qla2x00_mark_device_lost(scsi_qla_host_t *ha, fc_port_t *fcport,
int do_login)
{
if (atomic_read(&fcport->state) == FCS_ONLINE && fcport->rport)
- fc_remote_port_block(fcport->rport);
+ schedule_work(&fcport->rport_del_work);
+
/*
* We may need to retry the login, so don't change the state of the
* port but do the retries.
@@ -1743,7 +1702,7 @@ qla2x00_mark_all_devices_lost(scsi_qla_host_t *ha)
if (atomic_read(&fcport->state) == FCS_DEVICE_DEAD)
continue;
if (atomic_read(&fcport->state) == FCS_ONLINE && fcport->rport)
- fc_remote_port_block(fcport->rport);
+ schedule_work(&fcport->rport_del_work);
atomic_set(&fcport->state, FCS_DEVICE_LOST);
}
}
@@ -2187,6 +2146,12 @@ qla2x00_do_dpc(void *data)
ha->host_no));
}
+ if (test_and_clear_bit(LOOP_RESET_NEEDED, &ha->dpc_flags)) {
+ DEBUG(printk("scsi(%ld): dpc: sched loop_reset()\n",
+ ha->host_no));
+ qla2x00_loop_reset(ha);
+ }
+
if (test_and_clear_bit(RESET_MARKER_NEEDED, &ha->dpc_flags) &&
(!(test_and_set_bit(RESET_ACTIVE, &ha->dpc_flags)))) {
@@ -2488,6 +2453,7 @@ qla2x00_timer(scsi_qla_host_t *ha)
/* Schedule the DPC routine if needed */
if ((test_bit(ISP_ABORT_NEEDED, &ha->dpc_flags) ||
test_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags) ||
+ test_bit(LOOP_RESET_NEEDED, &ha->dpc_flags) ||
start_dpc ||
test_bit(LOGIN_RETRY_NEEDED, &ha->dpc_flags) ||
test_bit(RESET_MARKER_NEEDED, &ha->dpc_flags) ||
diff --git a/drivers/scsi/qla2xxx/qla_rscn.c b/drivers/scsi/qla2xxx/qla_rscn.c
index 1eba98828636..2c3342108dd8 100644
--- a/drivers/scsi/qla2xxx/qla_rscn.c
+++ b/drivers/scsi/qla2xxx/qla_rscn.c
@@ -1,23 +1,13 @@
/*
- * QLOGIC LINUX SOFTWARE
- *
- * QLogic ISP2x00 device driver for Linux 2.6.x
- * Copyright (C) 2003-2005 QLogic Corporation
- * (www.qlogic.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, 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.
+ * QLogic Fibre Channel HBA Driver
+ * Copyright (c) 2003-2005 QLogic Corporation
*
+ * See LICENSE.qla2xxx for copyright and licensing details.
*/
#include "qla_def.h"
+#include <scsi/scsi_transport_fc.h>
+
/**
* IO descriptor handle definitions.
*
@@ -330,8 +320,7 @@ qla2x00_update_login_fcport(scsi_qla_host_t *ha, struct mbx_entry *mbxstat,
fcport->flags &= ~FCF_FAILOVER_NEEDED;
fcport->iodesc_idx_sent = IODESC_INVALID_INDEX;
atomic_set(&fcport->state, FCS_ONLINE);
- if (fcport->rport)
- fc_remote_port_unblock(fcport->rport);
+ schedule_work(&fcport->rport_add_work);
}
@@ -1066,7 +1055,7 @@ qla2x00_send_login_iocb_cb(scsi_qla_host_t *ha, struct io_descriptor *iodesc,
* Returns a pointer to the allocated RSCN fcport, or NULL, if none available.
*/
fc_port_t *
-qla2x00_alloc_rscn_fcport(scsi_qla_host_t *ha, int flags)
+qla2x00_alloc_rscn_fcport(scsi_qla_host_t *ha, gfp_t flags)
{
fc_port_t *fcport;
diff --git a/drivers/scsi/qla2xxx/qla_settings.h b/drivers/scsi/qla2xxx/qla_settings.h
index d85fbbed79cc..363205c0e84f 100644
--- a/drivers/scsi/qla2xxx/qla_settings.h
+++ b/drivers/scsi/qla2xxx/qla_settings.h
@@ -1,21 +1,9 @@
-/******************************************************************************
- * QLOGIC LINUX SOFTWARE
- *
- * QLogic ISP2x00 device driver for Linux 2.6.x
- * Copyright (C) 2003-2005 QLogic Corporation
- * (www.qlogic.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, 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.
+/*
+ * QLogic Fibre Channel HBA Driver
+ * Copyright (c) 2003-2005 QLogic Corporation
*
- ******************************************************************************/
+ * See LICENSE.qla2xxx for copyright and licensing details.
+ */
/*
* Compile time Options:
* 0 - Disable and 1 - Enable
diff --git a/drivers/scsi/qla2xxx/qla_sup.c b/drivers/scsi/qla2xxx/qla_sup.c
index c14abf743b7c..4bec0b4fb6b4 100644
--- a/drivers/scsi/qla2xxx/qla_sup.c
+++ b/drivers/scsi/qla2xxx/qla_sup.c
@@ -1,22 +1,9 @@
-/******************************************************************************
- * QLOGIC LINUX SOFTWARE
- *
- * QLogic ISP2x00 device driver for Linux 2.6.x
- * Copyright (C) 2003-2005 QLogic Corporation
- * (www.qlogic.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, 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.
+/*
+ * QLogic Fibre Channel HBA Driver
+ * Copyright (c) 2003-2005 QLogic Corporation
*
- ******************************************************************************/
-
+ * See LICENSE.qla2xxx for copyright and licensing details.
+ */
#include "qla_def.h"
#include <linux/delay.h>
diff --git a/drivers/scsi/qla2xxx/qla_version.h b/drivers/scsi/qla2xxx/qla_version.h
index eae7d6edd531..0d5472f2f59b 100644
--- a/drivers/scsi/qla2xxx/qla_version.h
+++ b/drivers/scsi/qla2xxx/qla_version.h
@@ -1,21 +1,9 @@
-/******************************************************************************
- * QLOGIC LINUX SOFTWARE
- *
- * QLogic ISP2x00 device driver for Linux 2.6.x
- * Copyright (C) 2003-2005 QLogic Corporation
- * (www.qlogic.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, 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.
+/*
+ * QLogic Fibre Channel HBA Driver
+ * Copyright (c) 2003-2005 QLogic Corporation
*
- ******************************************************************************/
+ * See LICENSE.qla2xxx for copyright and licensing details.
+ */
/*
* Driver version
*/
diff --git a/drivers/scsi/qlogicfas408.c b/drivers/scsi/qlogicfas408.c
index cb75e0b7baea..52fb2ec3da70 100644
--- a/drivers/scsi/qlogicfas408.c
+++ b/drivers/scsi/qlogicfas408.c
@@ -243,7 +243,7 @@ static void ql_icmd(Scsi_Cmnd * cmd)
/**/ outb(qlcfg5, qbase + 5); /* select timer */
outb(qlcfg9 & 7, qbase + 9); /* prescaler */
/* outb(0x99, qbase + 5); */
- outb(cmd->device->id, qbase + 4);
+ outb(scmd_id(cmd), qbase + 4);
for (i = 0; i < cmd->cmd_len; i++)
outb(cmd->cmnd[i], qbase + 2);
@@ -450,7 +450,7 @@ irqreturn_t qlogicfas408_ihandl(int irq, void *dev_id, struct pt_regs *regs)
int qlogicfas408_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
{
struct qlogicfas408_priv *priv = get_priv_by_cmd(cmd);
- if (cmd->device->id == priv->qinitid) {
+ if (scmd_id(cmd) == priv->qinitid) {
cmd->result = DID_BAD_TARGET << 16;
done(cmd);
return 0;
diff --git a/drivers/scsi/raid_class.c b/drivers/scsi/raid_class.c
index f1ea5027865f..caa0c3629626 100644
--- a/drivers/scsi/raid_class.c
+++ b/drivers/scsi/raid_class.c
@@ -4,6 +4,8 @@
#include <linux/init.h>
#include <linux/module.h>
#include <linux/list.h>
+#include <linux/slab.h>
+#include <linux/string.h>
#include <linux/raid_class.h>
#include <scsi/scsi_device.h>
#include <scsi/scsi_host.h>
diff --git a/drivers/scsi/sata_mv.c b/drivers/scsi/sata_mv.c
index ea76fe44585e..93d55233af7b 100644
--- a/drivers/scsi/sata_mv.c
+++ b/drivers/scsi/sata_mv.c
@@ -29,13 +29,14 @@
#include <linux/interrupt.h>
#include <linux/sched.h>
#include <linux/dma-mapping.h>
-#include "scsi.h"
+#include <linux/device.h>
#include <scsi/scsi_host.h>
+#include <scsi/scsi_cmnd.h>
#include <linux/libata.h>
#include <asm/io.h>
#define DRV_NAME "sata_mv"
-#define DRV_VERSION "0.12"
+#define DRV_VERSION "0.25"
enum {
/* BAR's are enumerated in terms of pci_resource_start() terms */
@@ -55,31 +56,61 @@ enum {
MV_SATAHC_ARBTR_REG_SZ = MV_MINOR_REG_AREA_SZ, /* arbiter */
MV_PORT_REG_SZ = MV_MINOR_REG_AREA_SZ,
- MV_Q_CT = 32,
- MV_CRQB_SZ = 32,
- MV_CRPB_SZ = 8,
+ MV_USE_Q_DEPTH = ATA_DEF_QUEUE,
- MV_DMA_BOUNDARY = 0xffffffffU,
- SATAHC_MASK = (~(MV_SATAHC_REG_SZ - 1)),
+ MV_MAX_Q_DEPTH = 32,
+ MV_MAX_Q_DEPTH_MASK = MV_MAX_Q_DEPTH - 1,
+
+ /* CRQB needs alignment on a 1KB boundary. Size == 1KB
+ * CRPB needs alignment on a 256B boundary. Size == 256B
+ * SG count of 176 leads to MV_PORT_PRIV_DMA_SZ == 4KB
+ * ePRD (SG) entries need alignment on a 16B boundary. Size == 16B
+ */
+ MV_CRQB_Q_SZ = (32 * MV_MAX_Q_DEPTH),
+ MV_CRPB_Q_SZ = (8 * MV_MAX_Q_DEPTH),
+ MV_MAX_SG_CT = 176,
+ MV_SG_TBL_SZ = (16 * MV_MAX_SG_CT),
+ MV_PORT_PRIV_DMA_SZ = (MV_CRQB_Q_SZ + MV_CRPB_Q_SZ + MV_SG_TBL_SZ),
+
+ /* Our DMA boundary is determined by an ePRD being unable to handle
+ * anything larger than 64KB
+ */
+ MV_DMA_BOUNDARY = 0xffffU,
MV_PORTS_PER_HC = 4,
/* == (port / MV_PORTS_PER_HC) to determine HC from 0-7 port */
MV_PORT_HC_SHIFT = 2,
- /* == (port % MV_PORTS_PER_HC) to determine port from 0-7 port */
+ /* == (port % MV_PORTS_PER_HC) to determine hard port from 0-7 port */
MV_PORT_MASK = 3,
/* Host Flags */
MV_FLAG_DUAL_HC = (1 << 30), /* two SATA Host Controllers */
MV_FLAG_IRQ_COALESCE = (1 << 29), /* IRQ coalescing capability */
- MV_FLAG_BDMA = (1 << 28), /* Basic DMA */
+ MV_FLAG_GLBL_SFT_RST = (1 << 28), /* Global Soft Reset support */
+ MV_COMMON_FLAGS = (ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
+ ATA_FLAG_SATA_RESET | ATA_FLAG_MMIO),
+ MV_6XXX_FLAGS = (MV_FLAG_IRQ_COALESCE |
+ MV_FLAG_GLBL_SFT_RST),
chip_504x = 0,
chip_508x = 1,
chip_604x = 2,
chip_608x = 3,
+ CRQB_FLAG_READ = (1 << 0),
+ CRQB_TAG_SHIFT = 1,
+ CRQB_CMD_ADDR_SHIFT = 8,
+ CRQB_CMD_CS = (0x2 << 11),
+ CRQB_CMD_LAST = (1 << 15),
+
+ CRPB_FLAG_STATUS_SHIFT = 8,
+
+ EPRD_FLAG_END_OF_TBL = (1 << 31),
+
/* PCI interface registers */
+ PCI_COMMAND_OFS = 0xc00,
+
PCI_MAIN_CMD_STS_OFS = 0xd30,
STOP_PCI_MASTER = (1 << 2),
PCI_MASTER_EMPTY = (1 << 3),
@@ -111,20 +142,13 @@ enum {
HC_CFG_OFS = 0,
HC_IRQ_CAUSE_OFS = 0x14,
- CRBP_DMA_DONE = (1 << 0), /* shift by port # */
+ CRPB_DMA_DONE = (1 << 0), /* shift by port # */
HC_IRQ_COAL = (1 << 4), /* IRQ coalescing */
DEV_IRQ = (1 << 8), /* shift by port # */
/* Shadow block registers */
- SHD_PIO_DATA_OFS = 0x100,
- SHD_FEA_ERR_OFS = 0x104,
- SHD_SECT_CNT_OFS = 0x108,
- SHD_LBA_L_OFS = 0x10C,
- SHD_LBA_M_OFS = 0x110,
- SHD_LBA_H_OFS = 0x114,
- SHD_DEV_HD_OFS = 0x118,
- SHD_CMD_STA_OFS = 0x11C,
- SHD_CTL_AST_OFS = 0x120,
+ SHD_BLK_OFS = 0x100,
+ SHD_CTL_AST_OFS = 0x20, /* ofs from SHD_BLK_OFS */
/* SATA registers */
SATA_STATUS_OFS = 0x300, /* ctrl, err regs follow status */
@@ -132,6 +156,11 @@ enum {
/* Port registers */
EDMA_CFG_OFS = 0,
+ EDMA_CFG_Q_DEPTH = 0, /* queueing disabled */
+ EDMA_CFG_NCQ = (1 << 5),
+ EDMA_CFG_NCQ_GO_ON_ERR = (1 << 14), /* continue on error */
+ EDMA_CFG_RD_BRST_EXT = (1 << 11), /* read burst 512B */
+ EDMA_CFG_WR_BUFF_LEN = (1 << 13), /* write buffer 512B */
EDMA_ERR_IRQ_CAUSE_OFS = 0x8,
EDMA_ERR_IRQ_MASK_OFS = 0xc,
@@ -161,48 +190,99 @@ enum {
EDMA_ERR_LNK_DATA_TX |
EDMA_ERR_TRANS_PROTO),
+ EDMA_REQ_Q_BASE_HI_OFS = 0x10,
+ EDMA_REQ_Q_IN_PTR_OFS = 0x14, /* also contains BASE_LO */
+ EDMA_REQ_Q_BASE_LO_MASK = 0xfffffc00U,
+
+ EDMA_REQ_Q_OUT_PTR_OFS = 0x18,
+ EDMA_REQ_Q_PTR_SHIFT = 5,
+
+ EDMA_RSP_Q_BASE_HI_OFS = 0x1c,
+ EDMA_RSP_Q_IN_PTR_OFS = 0x20,
+ EDMA_RSP_Q_OUT_PTR_OFS = 0x24, /* also contains BASE_LO */
+ EDMA_RSP_Q_BASE_LO_MASK = 0xffffff00U,
+ EDMA_RSP_Q_PTR_SHIFT = 3,
+
EDMA_CMD_OFS = 0x28,
EDMA_EN = (1 << 0),
EDMA_DS = (1 << 1),
ATA_RST = (1 << 2),
- /* BDMA is 6xxx part only */
- BDMA_CMD_OFS = 0x224,
- BDMA_START = (1 << 0),
+ /* Host private flags (hp_flags) */
+ MV_HP_FLAG_MSI = (1 << 0),
- MV_UNDEF = 0,
+ /* Port private flags (pp_flags) */
+ MV_PP_FLAG_EDMA_EN = (1 << 0),
+ MV_PP_FLAG_EDMA_DS_ACT = (1 << 1),
};
-struct mv_port_priv {
+/* Command ReQuest Block: 32B */
+struct mv_crqb {
+ u32 sg_addr;
+ u32 sg_addr_hi;
+ u16 ctrl_flags;
+ u16 ata_cmd[11];
+};
+/* Command ResPonse Block: 8B */
+struct mv_crpb {
+ u16 id;
+ u16 flags;
+ u32 tmstmp;
};
-struct mv_host_priv {
+/* EDMA Physical Region Descriptor (ePRD); A.K.A. SG */
+struct mv_sg {
+ u32 addr;
+ u32 flags_size;
+ u32 addr_hi;
+ u32 reserved;
+};
+struct mv_port_priv {
+ struct mv_crqb *crqb;
+ dma_addr_t crqb_dma;
+ struct mv_crpb *crpb;
+ dma_addr_t crpb_dma;
+ struct mv_sg *sg_tbl;
+ dma_addr_t sg_tbl_dma;
+
+ unsigned req_producer; /* cp of req_in_ptr */
+ unsigned rsp_consumer; /* cp of rsp_out_ptr */
+ u32 pp_flags;
+};
+
+struct mv_host_priv {
+ u32 hp_flags;
};
static void mv_irq_clear(struct ata_port *ap);
static u32 mv_scr_read(struct ata_port *ap, unsigned int sc_reg_in);
static void mv_scr_write(struct ata_port *ap, unsigned int sc_reg_in, u32 val);
static void mv_phy_reset(struct ata_port *ap);
-static int mv_master_reset(void __iomem *mmio_base);
+static void mv_host_stop(struct ata_host_set *host_set);
+static int mv_port_start(struct ata_port *ap);
+static void mv_port_stop(struct ata_port *ap);
+static void mv_qc_prep(struct ata_queued_cmd *qc);
+static int mv_qc_issue(struct ata_queued_cmd *qc);
static irqreturn_t mv_interrupt(int irq, void *dev_instance,
struct pt_regs *regs);
+static void mv_eng_timeout(struct ata_port *ap);
static int mv_init_one(struct pci_dev *pdev, const struct pci_device_id *ent);
-static Scsi_Host_Template mv_sht = {
+static struct scsi_host_template mv_sht = {
.module = THIS_MODULE,
.name = DRV_NAME,
.ioctl = ata_scsi_ioctl,
.queuecommand = ata_scsi_queuecmd,
.eh_strategy_handler = ata_scsi_error,
- .can_queue = ATA_DEF_QUEUE,
+ .can_queue = MV_USE_Q_DEPTH,
.this_id = ATA_SHT_THIS_ID,
- .sg_tablesize = MV_UNDEF,
+ .sg_tablesize = MV_MAX_SG_CT,
.max_sectors = ATA_MAX_SECTORS,
.cmd_per_lun = ATA_SHT_CMD_PER_LUN,
.emulated = ATA_SHT_EMULATED,
- .use_clustering = MV_UNDEF,
+ .use_clustering = ATA_SHT_USE_CLUSTERING,
.proc_name = DRV_NAME,
.dma_boundary = MV_DMA_BOUNDARY,
.slave_configure = ata_scsi_slave_config,
@@ -210,7 +290,7 @@ static Scsi_Host_Template mv_sht = {
.ordered_flush = 1,
};
-static struct ata_port_operations mv_ops = {
+static const struct ata_port_operations mv_ops = {
.port_disable = ata_port_disable,
.tf_load = ata_tf_load,
@@ -221,10 +301,10 @@ static struct ata_port_operations mv_ops = {
.phy_reset = mv_phy_reset,
- .qc_prep = ata_qc_prep,
- .qc_issue = ata_qc_issue_prot,
+ .qc_prep = mv_qc_prep,
+ .qc_issue = mv_qc_issue,
- .eng_timeout = ata_eng_timeout,
+ .eng_timeout = mv_eng_timeout,
.irq_handler = mv_interrupt,
.irq_clear = mv_irq_clear,
@@ -232,46 +312,39 @@ static struct ata_port_operations mv_ops = {
.scr_read = mv_scr_read,
.scr_write = mv_scr_write,
- .port_start = ata_port_start,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop,
+ .port_start = mv_port_start,
+ .port_stop = mv_port_stop,
+ .host_stop = mv_host_stop,
};
static struct ata_port_info mv_port_info[] = {
{ /* chip_504x */
.sht = &mv_sht,
- .host_flags = (ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
- ATA_FLAG_SATA_RESET | ATA_FLAG_MMIO),
- .pio_mask = 0x1f, /* pio4-0 */
- .udma_mask = 0, /* 0x7f (udma6-0 disabled for now) */
+ .host_flags = MV_COMMON_FLAGS,
+ .pio_mask = 0x1f, /* pio0-4 */
+ .udma_mask = 0, /* 0x7f (udma0-6 disabled for now) */
.port_ops = &mv_ops,
},
{ /* chip_508x */
.sht = &mv_sht,
- .host_flags = (ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
- ATA_FLAG_SATA_RESET | ATA_FLAG_MMIO |
- MV_FLAG_DUAL_HC),
- .pio_mask = 0x1f, /* pio4-0 */
- .udma_mask = 0, /* 0x7f (udma6-0 disabled for now) */
+ .host_flags = (MV_COMMON_FLAGS | MV_FLAG_DUAL_HC),
+ .pio_mask = 0x1f, /* pio0-4 */
+ .udma_mask = 0, /* 0x7f (udma0-6 disabled for now) */
.port_ops = &mv_ops,
},
{ /* chip_604x */
.sht = &mv_sht,
- .host_flags = (ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
- ATA_FLAG_SATA_RESET | ATA_FLAG_MMIO |
- MV_FLAG_IRQ_COALESCE | MV_FLAG_BDMA),
- .pio_mask = 0x1f, /* pio4-0 */
- .udma_mask = 0, /* 0x7f (udma6-0 disabled for now) */
+ .host_flags = (MV_COMMON_FLAGS | MV_6XXX_FLAGS),
+ .pio_mask = 0x1f, /* pio0-4 */
+ .udma_mask = 0x7f, /* udma0-6 */
.port_ops = &mv_ops,
},
{ /* chip_608x */
.sht = &mv_sht,
- .host_flags = (ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
- ATA_FLAG_SATA_RESET | ATA_FLAG_MMIO |
- MV_FLAG_IRQ_COALESCE | MV_FLAG_DUAL_HC |
- MV_FLAG_BDMA),
- .pio_mask = 0x1f, /* pio4-0 */
- .udma_mask = 0, /* 0x7f (udma6-0 disabled for now) */
+ .host_flags = (MV_COMMON_FLAGS | MV_6XXX_FLAGS |
+ MV_FLAG_DUAL_HC),
+ .pio_mask = 0x1f, /* pio0-4 */
+ .udma_mask = 0x7f, /* udma0-6 */
.port_ops = &mv_ops,
},
};
@@ -306,12 +379,6 @@ static inline void writelfl(unsigned long data, void __iomem *addr)
(void) readl(addr); /* flush to avoid PCI posted write */
}
-static inline void __iomem *mv_port_addr_to_hc_base(void __iomem *port_mmio)
-{
- return ((void __iomem *)((unsigned long)port_mmio &
- (unsigned long)SATAHC_MASK));
-}
-
static inline void __iomem *mv_hc_base(void __iomem *base, unsigned int hc)
{
return (base + MV_SATAHC0_REG_BASE + (hc * MV_SATAHC_REG_SZ));
@@ -329,24 +396,150 @@ static inline void __iomem *mv_ap_base(struct ata_port *ap)
return mv_port_base(ap->host_set->mmio_base, ap->port_no);
}
-static inline int mv_get_hc_count(unsigned long flags)
+static inline int mv_get_hc_count(unsigned long hp_flags)
{
- return ((flags & MV_FLAG_DUAL_HC) ? 2 : 1);
+ return ((hp_flags & MV_FLAG_DUAL_HC) ? 2 : 1);
}
-static inline int mv_is_edma_active(struct ata_port *ap)
+static void mv_irq_clear(struct ata_port *ap)
+{
+}
+
+/**
+ * mv_start_dma - Enable eDMA engine
+ * @base: port base address
+ * @pp: port private data
+ *
+ * Verify the local cache of the eDMA state is accurate with an
+ * assert.
+ *
+ * LOCKING:
+ * Inherited from caller.
+ */
+static void mv_start_dma(void __iomem *base, struct mv_port_priv *pp)
+{
+ if (!(MV_PP_FLAG_EDMA_EN & pp->pp_flags)) {
+ writelfl(EDMA_EN, base + EDMA_CMD_OFS);
+ pp->pp_flags |= MV_PP_FLAG_EDMA_EN;
+ }
+ assert(EDMA_EN & readl(base + EDMA_CMD_OFS));
+}
+
+/**
+ * mv_stop_dma - Disable eDMA engine
+ * @ap: ATA channel to manipulate
+ *
+ * Verify the local cache of the eDMA state is accurate with an
+ * assert.
+ *
+ * LOCKING:
+ * Inherited from caller.
+ */
+static void mv_stop_dma(struct ata_port *ap)
{
void __iomem *port_mmio = mv_ap_base(ap);
- return (EDMA_EN & readl(port_mmio + EDMA_CMD_OFS));
+ struct mv_port_priv *pp = ap->private_data;
+ u32 reg;
+ int i;
+
+ if (MV_PP_FLAG_EDMA_EN & pp->pp_flags) {
+ /* Disable EDMA if active. The disable bit auto clears.
+ */
+ writelfl(EDMA_DS, port_mmio + EDMA_CMD_OFS);
+ pp->pp_flags &= ~MV_PP_FLAG_EDMA_EN;
+ } else {
+ assert(!(EDMA_EN & readl(port_mmio + EDMA_CMD_OFS)));
+ }
+
+ /* now properly wait for the eDMA to stop */
+ for (i = 1000; i > 0; i--) {
+ reg = readl(port_mmio + EDMA_CMD_OFS);
+ if (!(EDMA_EN & reg)) {
+ break;
+ }
+ udelay(100);
+ }
+
+ if (EDMA_EN & reg) {
+ printk(KERN_ERR "ata%u: Unable to stop eDMA\n", ap->id);
+ /* FIXME: Consider doing a reset here to recover */
+ }
}
-static inline int mv_port_bdma_capable(struct ata_port *ap)
+#ifdef ATA_DEBUG
+static void mv_dump_mem(void __iomem *start, unsigned bytes)
{
- return (ap->flags & MV_FLAG_BDMA);
+ int b, w;
+ for (b = 0; b < bytes; ) {
+ DPRINTK("%p: ", start + b);
+ for (w = 0; b < bytes && w < 4; w++) {
+ printk("%08x ",readl(start + b));
+ b += sizeof(u32);
+ }
+ printk("\n");
+ }
}
+#endif
-static void mv_irq_clear(struct ata_port *ap)
+static void mv_dump_pci_cfg(struct pci_dev *pdev, unsigned bytes)
+{
+#ifdef ATA_DEBUG
+ int b, w;
+ u32 dw;
+ for (b = 0; b < bytes; ) {
+ DPRINTK("%02x: ", b);
+ for (w = 0; b < bytes && w < 4; w++) {
+ (void) pci_read_config_dword(pdev,b,&dw);
+ printk("%08x ",dw);
+ b += sizeof(u32);
+ }
+ printk("\n");
+ }
+#endif
+}
+static void mv_dump_all_regs(void __iomem *mmio_base, int port,
+ struct pci_dev *pdev)
{
+#ifdef ATA_DEBUG
+ void __iomem *hc_base = mv_hc_base(mmio_base,
+ port >> MV_PORT_HC_SHIFT);
+ void __iomem *port_base;
+ int start_port, num_ports, p, start_hc, num_hcs, hc;
+
+ if (0 > port) {
+ start_hc = start_port = 0;
+ num_ports = 8; /* shld be benign for 4 port devs */
+ num_hcs = 2;
+ } else {
+ start_hc = port >> MV_PORT_HC_SHIFT;
+ start_port = port;
+ num_ports = num_hcs = 1;
+ }
+ DPRINTK("All registers for port(s) %u-%u:\n", start_port,
+ num_ports > 1 ? num_ports - 1 : start_port);
+
+ if (NULL != pdev) {
+ DPRINTK("PCI config space regs:\n");
+ mv_dump_pci_cfg(pdev, 0x68);
+ }
+ DPRINTK("PCI regs:\n");
+ mv_dump_mem(mmio_base+0xc00, 0x3c);
+ mv_dump_mem(mmio_base+0xd00, 0x34);
+ mv_dump_mem(mmio_base+0xf00, 0x4);
+ mv_dump_mem(mmio_base+0x1d00, 0x6c);
+ for (hc = start_hc; hc < start_hc + num_hcs; hc++) {
+ hc_base = mv_hc_base(mmio_base, port >> MV_PORT_HC_SHIFT);
+ DPRINTK("HC regs (HC %i):\n", hc);
+ mv_dump_mem(hc_base, 0x1c);
+ }
+ for (p = start_port; p < start_port + num_ports; p++) {
+ port_base = mv_port_base(mmio_base, p);
+ DPRINTK("EDMA regs (port %i):\n",p);
+ mv_dump_mem(port_base, 0x54);
+ DPRINTK("SATA regs (port %i):\n",p);
+ mv_dump_mem(port_base+0x300, 0x60);
+ }
+#endif
}
static unsigned int mv_scr_offset(unsigned int sc_reg_in)
@@ -389,30 +582,37 @@ static void mv_scr_write(struct ata_port *ap, unsigned int sc_reg_in, u32 val)
}
}
-static int mv_master_reset(void __iomem *mmio_base)
+/**
+ * mv_global_soft_reset - Perform the 6xxx global soft reset
+ * @mmio_base: base address of the HBA
+ *
+ * This routine only applies to 6xxx parts.
+ *
+ * LOCKING:
+ * Inherited from caller.
+ */
+static int mv_global_soft_reset(void __iomem *mmio_base)
{
void __iomem *reg = mmio_base + PCI_MAIN_CMD_STS_OFS;
int i, rc = 0;
u32 t;
- VPRINTK("ENTER\n");
-
/* Following procedure defined in PCI "main command and status
* register" table.
*/
t = readl(reg);
writel(t | STOP_PCI_MASTER, reg);
- for (i = 0; i < 100; i++) {
- msleep(10);
+ for (i = 0; i < 1000; i++) {
+ udelay(1);
t = readl(reg);
if (PCI_MASTER_EMPTY & t) {
break;
}
}
if (!(PCI_MASTER_EMPTY & t)) {
- printk(KERN_ERR DRV_NAME "PCI master won't flush\n");
- rc = 1; /* broken HW? */
+ printk(KERN_ERR DRV_NAME ": PCI master won't flush\n");
+ rc = 1;
goto done;
}
@@ -425,39 +625,415 @@ static int mv_master_reset(void __iomem *mmio_base)
} while (!(GLOB_SFT_RST & t) && (i-- > 0));
if (!(GLOB_SFT_RST & t)) {
- printk(KERN_ERR DRV_NAME "can't set global reset\n");
- rc = 1; /* broken HW? */
+ printk(KERN_ERR DRV_NAME ": can't set global reset\n");
+ rc = 1;
goto done;
}
- /* clear reset */
+ /* clear reset and *reenable the PCI master* (not mentioned in spec) */
i = 5;
do {
- writel(t & ~GLOB_SFT_RST, reg);
+ writel(t & ~(GLOB_SFT_RST | STOP_PCI_MASTER), reg);
t = readl(reg);
udelay(1);
} while ((GLOB_SFT_RST & t) && (i-- > 0));
if (GLOB_SFT_RST & t) {
- printk(KERN_ERR DRV_NAME "can't clear global reset\n");
- rc = 1; /* broken HW? */
+ printk(KERN_ERR DRV_NAME ": can't clear global reset\n");
+ rc = 1;
+ }
+done:
+ return rc;
+}
+
+/**
+ * mv_host_stop - Host specific cleanup/stop routine.
+ * @host_set: host data structure
+ *
+ * Disable ints, cleanup host memory, call general purpose
+ * host_stop.
+ *
+ * LOCKING:
+ * Inherited from caller.
+ */
+static void mv_host_stop(struct ata_host_set *host_set)
+{
+ struct mv_host_priv *hpriv = host_set->private_data;
+ struct pci_dev *pdev = to_pci_dev(host_set->dev);
+
+ if (hpriv->hp_flags & MV_HP_FLAG_MSI) {
+ pci_disable_msi(pdev);
+ } else {
+ pci_intx(pdev, 0);
}
+ kfree(hpriv);
+ ata_host_stop(host_set);
+}
+
+static inline void mv_priv_free(struct mv_port_priv *pp, struct device *dev)
+{
+ dma_free_coherent(dev, MV_PORT_PRIV_DMA_SZ, pp->crpb, pp->crpb_dma);
+}
+
+/**
+ * mv_port_start - Port specific init/start routine.
+ * @ap: ATA channel to manipulate
+ *
+ * Allocate and point to DMA memory, init port private memory,
+ * zero indices.
+ *
+ * LOCKING:
+ * Inherited from caller.
+ */
+static int mv_port_start(struct ata_port *ap)
+{
+ struct device *dev = ap->host_set->dev;
+ struct mv_port_priv *pp;
+ void __iomem *port_mmio = mv_ap_base(ap);
+ void *mem;
+ dma_addr_t mem_dma;
+ int rc = -ENOMEM;
+
+ pp = kmalloc(sizeof(*pp), GFP_KERNEL);
+ if (!pp)
+ goto err_out;
+ memset(pp, 0, sizeof(*pp));
+
+ mem = dma_alloc_coherent(dev, MV_PORT_PRIV_DMA_SZ, &mem_dma,
+ GFP_KERNEL);
+ if (!mem)
+ goto err_out_pp;
+ memset(mem, 0, MV_PORT_PRIV_DMA_SZ);
+
+ rc = ata_pad_alloc(ap, dev);
+ if (rc)
+ goto err_out_priv;
+
+ /* First item in chunk of DMA memory:
+ * 32-slot command request table (CRQB), 32 bytes each in size
+ */
+ pp->crqb = mem;
+ pp->crqb_dma = mem_dma;
+ mem += MV_CRQB_Q_SZ;
+ mem_dma += MV_CRQB_Q_SZ;
+
+ /* Second item:
+ * 32-slot command response table (CRPB), 8 bytes each in size
+ */
+ pp->crpb = mem;
+ pp->crpb_dma = mem_dma;
+ mem += MV_CRPB_Q_SZ;
+ mem_dma += MV_CRPB_Q_SZ;
- done:
- VPRINTK("EXIT, rc = %i\n", rc);
+ /* Third item:
+ * Table of scatter-gather descriptors (ePRD), 16 bytes each
+ */
+ pp->sg_tbl = mem;
+ pp->sg_tbl_dma = mem_dma;
+
+ writelfl(EDMA_CFG_Q_DEPTH | EDMA_CFG_RD_BRST_EXT |
+ EDMA_CFG_WR_BUFF_LEN, port_mmio + EDMA_CFG_OFS);
+
+ writel((pp->crqb_dma >> 16) >> 16, port_mmio + EDMA_REQ_Q_BASE_HI_OFS);
+ writelfl(pp->crqb_dma & EDMA_REQ_Q_BASE_LO_MASK,
+ port_mmio + EDMA_REQ_Q_IN_PTR_OFS);
+
+ writelfl(0, port_mmio + EDMA_REQ_Q_OUT_PTR_OFS);
+ writelfl(0, port_mmio + EDMA_RSP_Q_IN_PTR_OFS);
+
+ writel((pp->crpb_dma >> 16) >> 16, port_mmio + EDMA_RSP_Q_BASE_HI_OFS);
+ writelfl(pp->crpb_dma & EDMA_RSP_Q_BASE_LO_MASK,
+ port_mmio + EDMA_RSP_Q_OUT_PTR_OFS);
+
+ pp->req_producer = pp->rsp_consumer = 0;
+
+ /* Don't turn on EDMA here...do it before DMA commands only. Else
+ * we'll be unable to send non-data, PIO, etc due to restricted access
+ * to shadow regs.
+ */
+ ap->private_data = pp;
+ return 0;
+
+err_out_priv:
+ mv_priv_free(pp, dev);
+err_out_pp:
+ kfree(pp);
+err_out:
return rc;
}
-static void mv_err_intr(struct ata_port *ap)
+/**
+ * mv_port_stop - Port specific cleanup/stop routine.
+ * @ap: ATA channel to manipulate
+ *
+ * Stop DMA, cleanup port memory.
+ *
+ * LOCKING:
+ * This routine uses the host_set lock to protect the DMA stop.
+ */
+static void mv_port_stop(struct ata_port *ap)
{
- void __iomem *port_mmio;
- u32 edma_err_cause, serr = 0;
+ struct device *dev = ap->host_set->dev;
+ struct mv_port_priv *pp = ap->private_data;
+ unsigned long flags;
+
+ spin_lock_irqsave(&ap->host_set->lock, flags);
+ mv_stop_dma(ap);
+ spin_unlock_irqrestore(&ap->host_set->lock, flags);
+
+ ap->private_data = NULL;
+ ata_pad_free(ap, dev);
+ mv_priv_free(pp, dev);
+ kfree(pp);
+}
+
+/**
+ * mv_fill_sg - Fill out the Marvell ePRD (scatter gather) entries
+ * @qc: queued command whose SG list to source from
+ *
+ * Populate the SG list and mark the last entry.
+ *
+ * LOCKING:
+ * Inherited from caller.
+ */
+static void mv_fill_sg(struct ata_queued_cmd *qc)
+{
+ struct mv_port_priv *pp = qc->ap->private_data;
+ unsigned int i = 0;
+ struct scatterlist *sg;
+
+ ata_for_each_sg(sg, qc) {
+ u32 sg_len;
+ dma_addr_t addr;
+
+ addr = sg_dma_address(sg);
+ sg_len = sg_dma_len(sg);
+
+ pp->sg_tbl[i].addr = cpu_to_le32(addr & 0xffffffff);
+ pp->sg_tbl[i].addr_hi = cpu_to_le32((addr >> 16) >> 16);
+ assert(0 == (sg_len & ~MV_DMA_BOUNDARY));
+ pp->sg_tbl[i].flags_size = cpu_to_le32(sg_len);
+ if (ata_sg_is_last(sg, qc))
+ pp->sg_tbl[i].flags_size |= cpu_to_le32(EPRD_FLAG_END_OF_TBL);
+
+ i++;
+ }
+}
+
+static inline unsigned mv_inc_q_index(unsigned *index)
+{
+ *index = (*index + 1) & MV_MAX_Q_DEPTH_MASK;
+ return *index;
+}
+
+static inline void mv_crqb_pack_cmd(u16 *cmdw, u8 data, u8 addr, unsigned last)
+{
+ *cmdw = data | (addr << CRQB_CMD_ADDR_SHIFT) | CRQB_CMD_CS |
+ (last ? CRQB_CMD_LAST : 0);
+}
- /* bug here b/c we got an err int on a port we don't know about,
- * so there's no way to clear it
+/**
+ * mv_qc_prep - Host specific command preparation.
+ * @qc: queued command to prepare
+ *
+ * This routine simply redirects to the general purpose routine
+ * if command is not DMA. Else, it handles prep of the CRQB
+ * (command request block), does some sanity checking, and calls
+ * the SG load routine.
+ *
+ * LOCKING:
+ * Inherited from caller.
+ */
+static void mv_qc_prep(struct ata_queued_cmd *qc)
+{
+ struct ata_port *ap = qc->ap;
+ struct mv_port_priv *pp = ap->private_data;
+ u16 *cw;
+ struct ata_taskfile *tf;
+ u16 flags = 0;
+
+ if (ATA_PROT_DMA != qc->tf.protocol) {
+ return;
+ }
+
+ /* the req producer index should be the same as we remember it */
+ assert(((readl(mv_ap_base(qc->ap) + EDMA_REQ_Q_IN_PTR_OFS) >>
+ EDMA_REQ_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK) ==
+ pp->req_producer);
+
+ /* Fill in command request block
+ */
+ if (!(qc->tf.flags & ATA_TFLAG_WRITE)) {
+ flags |= CRQB_FLAG_READ;
+ }
+ assert(MV_MAX_Q_DEPTH > qc->tag);
+ flags |= qc->tag << CRQB_TAG_SHIFT;
+
+ pp->crqb[pp->req_producer].sg_addr =
+ cpu_to_le32(pp->sg_tbl_dma & 0xffffffff);
+ pp->crqb[pp->req_producer].sg_addr_hi =
+ cpu_to_le32((pp->sg_tbl_dma >> 16) >> 16);
+ pp->crqb[pp->req_producer].ctrl_flags = cpu_to_le16(flags);
+
+ cw = &pp->crqb[pp->req_producer].ata_cmd[0];
+ tf = &qc->tf;
+
+ /* Sadly, the CRQB cannot accomodate all registers--there are
+ * only 11 bytes...so we must pick and choose required
+ * registers based on the command. So, we drop feature and
+ * hob_feature for [RW] DMA commands, but they are needed for
+ * NCQ. NCQ will drop hob_nsect.
*/
- BUG_ON(NULL == ap);
- port_mmio = mv_ap_base(ap);
+ switch (tf->command) {
+ case ATA_CMD_READ:
+ case ATA_CMD_READ_EXT:
+ case ATA_CMD_WRITE:
+ case ATA_CMD_WRITE_EXT:
+ mv_crqb_pack_cmd(cw++, tf->hob_nsect, ATA_REG_NSECT, 0);
+ break;
+#ifdef LIBATA_NCQ /* FIXME: remove this line when NCQ added */
+ case ATA_CMD_FPDMA_READ:
+ case ATA_CMD_FPDMA_WRITE:
+ mv_crqb_pack_cmd(cw++, tf->hob_feature, ATA_REG_FEATURE, 0);
+ mv_crqb_pack_cmd(cw++, tf->feature, ATA_REG_FEATURE, 0);
+ break;
+#endif /* FIXME: remove this line when NCQ added */
+ default:
+ /* The only other commands EDMA supports in non-queued and
+ * non-NCQ mode are: [RW] STREAM DMA and W DMA FUA EXT, none
+ * of which are defined/used by Linux. If we get here, this
+ * driver needs work.
+ *
+ * FIXME: modify libata to give qc_prep a return value and
+ * return error here.
+ */
+ BUG_ON(tf->command);
+ break;
+ }
+ mv_crqb_pack_cmd(cw++, tf->nsect, ATA_REG_NSECT, 0);
+ mv_crqb_pack_cmd(cw++, tf->hob_lbal, ATA_REG_LBAL, 0);
+ mv_crqb_pack_cmd(cw++, tf->lbal, ATA_REG_LBAL, 0);
+ mv_crqb_pack_cmd(cw++, tf->hob_lbam, ATA_REG_LBAM, 0);
+ mv_crqb_pack_cmd(cw++, tf->lbam, ATA_REG_LBAM, 0);
+ mv_crqb_pack_cmd(cw++, tf->hob_lbah, ATA_REG_LBAH, 0);
+ mv_crqb_pack_cmd(cw++, tf->lbah, ATA_REG_LBAH, 0);
+ mv_crqb_pack_cmd(cw++, tf->device, ATA_REG_DEVICE, 0);
+ mv_crqb_pack_cmd(cw++, tf->command, ATA_REG_CMD, 1); /* last */
+
+ if (!(qc->flags & ATA_QCFLAG_DMAMAP)) {
+ return;
+ }
+ mv_fill_sg(qc);
+}
+
+/**
+ * mv_qc_issue - Initiate a command to the host
+ * @qc: queued command to start
+ *
+ * This routine simply redirects to the general purpose routine
+ * if command is not DMA. Else, it sanity checks our local
+ * caches of the request producer/consumer indices then enables
+ * DMA and bumps the request producer index.
+ *
+ * LOCKING:
+ * Inherited from caller.
+ */
+static int mv_qc_issue(struct ata_queued_cmd *qc)
+{
+ void __iomem *port_mmio = mv_ap_base(qc->ap);
+ struct mv_port_priv *pp = qc->ap->private_data;
+ u32 in_ptr;
+
+ if (ATA_PROT_DMA != qc->tf.protocol) {
+ /* We're about to send a non-EDMA capable command to the
+ * port. Turn off EDMA so there won't be problems accessing
+ * shadow block, etc registers.
+ */
+ mv_stop_dma(qc->ap);
+ return ata_qc_issue_prot(qc);
+ }
+
+ in_ptr = readl(port_mmio + EDMA_REQ_Q_IN_PTR_OFS);
+
+ /* the req producer index should be the same as we remember it */
+ assert(((in_ptr >> EDMA_REQ_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK) ==
+ pp->req_producer);
+ /* until we do queuing, the queue should be empty at this point */
+ assert(((in_ptr >> EDMA_REQ_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK) ==
+ ((readl(port_mmio + EDMA_REQ_Q_OUT_PTR_OFS) >>
+ EDMA_REQ_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK));
+
+ mv_inc_q_index(&pp->req_producer); /* now incr producer index */
+
+ mv_start_dma(port_mmio, pp);
+
+ /* and write the request in pointer to kick the EDMA to life */
+ in_ptr &= EDMA_REQ_Q_BASE_LO_MASK;
+ in_ptr |= pp->req_producer << EDMA_REQ_Q_PTR_SHIFT;
+ writelfl(in_ptr, port_mmio + EDMA_REQ_Q_IN_PTR_OFS);
+
+ return 0;
+}
+
+/**
+ * mv_get_crpb_status - get status from most recently completed cmd
+ * @ap: ATA channel to manipulate
+ *
+ * This routine is for use when the port is in DMA mode, when it
+ * will be using the CRPB (command response block) method of
+ * returning command completion information. We assert indices
+ * are good, grab status, and bump the response consumer index to
+ * prove that we're up to date.
+ *
+ * LOCKING:
+ * Inherited from caller.
+ */
+static u8 mv_get_crpb_status(struct ata_port *ap)
+{
+ void __iomem *port_mmio = mv_ap_base(ap);
+ struct mv_port_priv *pp = ap->private_data;
+ u32 out_ptr;
+
+ out_ptr = readl(port_mmio + EDMA_RSP_Q_OUT_PTR_OFS);
+
+ /* the response consumer index should be the same as we remember it */
+ assert(((out_ptr >> EDMA_RSP_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK) ==
+ pp->rsp_consumer);
+
+ /* increment our consumer index... */
+ pp->rsp_consumer = mv_inc_q_index(&pp->rsp_consumer);
+
+ /* and, until we do NCQ, there should only be 1 CRPB waiting */
+ assert(((readl(port_mmio + EDMA_RSP_Q_IN_PTR_OFS) >>
+ EDMA_RSP_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK) ==
+ pp->rsp_consumer);
+
+ /* write out our inc'd consumer index so EDMA knows we're caught up */
+ out_ptr &= EDMA_RSP_Q_BASE_LO_MASK;
+ out_ptr |= pp->rsp_consumer << EDMA_RSP_Q_PTR_SHIFT;
+ writelfl(out_ptr, port_mmio + EDMA_RSP_Q_OUT_PTR_OFS);
+
+ /* Return ATA status register for completed CRPB */
+ return (pp->crpb[pp->rsp_consumer].flags >> CRPB_FLAG_STATUS_SHIFT);
+}
+
+/**
+ * mv_err_intr - Handle error interrupts on the port
+ * @ap: ATA channel to manipulate
+ *
+ * In most cases, just clear the interrupt and move on. However,
+ * some cases require an eDMA reset, which is done right before
+ * the COMRESET in mv_phy_reset(). The SERR case requires a
+ * clear of pending errors in the SATA SERROR register. Finally,
+ * if the port disabled DMA, update our cached copy to match.
+ *
+ * LOCKING:
+ * Inherited from caller.
+ */
+static void mv_err_intr(struct ata_port *ap)
+{
+ void __iomem *port_mmio = mv_ap_base(ap);
+ u32 edma_err_cause, serr = 0;
edma_err_cause = readl(port_mmio + EDMA_ERR_IRQ_CAUSE_OFS);
@@ -465,8 +1041,12 @@ static void mv_err_intr(struct ata_port *ap)
serr = scr_read(ap, SCR_ERROR);
scr_write_flush(ap, SCR_ERROR, serr);
}
- DPRINTK("port %u error; EDMA err cause: 0x%08x SERR: 0x%08x\n",
- ap->port_no, edma_err_cause, serr);
+ if (EDMA_ERR_SELF_DIS & edma_err_cause) {
+ struct mv_port_priv *pp = ap->private_data;
+ pp->pp_flags &= ~MV_PP_FLAG_EDMA_EN;
+ }
+ DPRINTK(KERN_ERR "ata%u: port error; EDMA err cause: 0x%08x "
+ "SERR: 0x%08x\n", ap->id, edma_err_cause, serr);
/* Clear EDMA now that SERR cleanup done */
writelfl(0, port_mmio + EDMA_ERR_IRQ_CAUSE_OFS);
@@ -477,7 +1057,21 @@ static void mv_err_intr(struct ata_port *ap)
}
}
-/* Handle any outstanding interrupts in a single SATAHC
+/**
+ * mv_host_intr - Handle all interrupts on the given host controller
+ * @host_set: host specific structure
+ * @relevant: port error bits relevant to this host controller
+ * @hc: which host controller we're to look at
+ *
+ * Read then write clear the HC interrupt status then walk each
+ * port connected to the HC and see if it needs servicing. Port
+ * success ints are reported in the HC interrupt status reg, the
+ * port error ints are reported in the higher level main
+ * interrupt status register and thus are passed in via the
+ * 'relevant' argument.
+ *
+ * LOCKING:
+ * Inherited from caller.
*/
static void mv_host_intr(struct ata_host_set *host_set, u32 relevant,
unsigned int hc)
@@ -487,8 +1081,9 @@ static void mv_host_intr(struct ata_host_set *host_set, u32 relevant,
struct ata_port *ap;
struct ata_queued_cmd *qc;
u32 hc_irq_cause;
- int shift, port, port0, hard_port;
- u8 ata_status;
+ int shift, port, port0, hard_port, handled;
+ unsigned int err_mask;
+ u8 ata_status = 0;
if (hc == 0) {
port0 = 0;
@@ -499,7 +1094,7 @@ static void mv_host_intr(struct ata_host_set *host_set, u32 relevant,
/* we'll need the HC success int register in most cases */
hc_irq_cause = readl(hc_mmio + HC_IRQ_CAUSE_OFS);
if (hc_irq_cause) {
- writelfl(0, hc_mmio + HC_IRQ_CAUSE_OFS);
+ writelfl(~hc_irq_cause, hc_mmio + HC_IRQ_CAUSE_OFS);
}
VPRINTK("ENTER, hc%u relevant=0x%08x HC IRQ cause=0x%08x\n",
@@ -508,54 +1103,70 @@ static void mv_host_intr(struct ata_host_set *host_set, u32 relevant,
for (port = port0; port < port0 + MV_PORTS_PER_HC; port++) {
ap = host_set->ports[port];
hard_port = port & MV_PORT_MASK; /* range 0-3 */
- ata_status = 0xffU;
+ handled = 0; /* ensure ata_status is set if handled++ */
- if (((CRBP_DMA_DONE | DEV_IRQ) << hard_port) & hc_irq_cause) {
- BUG_ON(NULL == ap);
- /* rcv'd new resp, basic DMA complete, or ATA IRQ */
- /* This is needed to clear the ATA INTRQ.
- * FIXME: don't read the status reg in EDMA mode!
+ if ((CRPB_DMA_DONE << hard_port) & hc_irq_cause) {
+ /* new CRPB on the queue; just one at a time until NCQ
+ */
+ ata_status = mv_get_crpb_status(ap);
+ handled++;
+ } else if ((DEV_IRQ << hard_port) & hc_irq_cause) {
+ /* received ATA IRQ; read the status reg to clear INTRQ
*/
ata_status = readb((void __iomem *)
ap->ioaddr.status_addr);
+ handled++;
}
- shift = port * 2;
+ err_mask = ac_err_mask(ata_status);
+
+ shift = port << 1; /* (port * 2) */
if (port >= MV_PORTS_PER_HC) {
shift++; /* skip bit 8 in the HC Main IRQ reg */
}
if ((PORT0_ERR << shift) & relevant) {
mv_err_intr(ap);
- /* FIXME: smart to OR in ATA_ERR? */
- ata_status = readb((void __iomem *)
- ap->ioaddr.status_addr) | ATA_ERR;
+ err_mask |= AC_ERR_OTHER;
+ handled++;
}
- if (ap) {
+ if (handled && ap) {
qc = ata_qc_from_tag(ap, ap->active_tag);
if (NULL != qc) {
VPRINTK("port %u IRQ found for qc, "
"ata_status 0x%x\n", port,ata_status);
- BUG_ON(0xffU == ata_status);
/* mark qc status appropriately */
- ata_qc_complete(qc, ata_status);
+ ata_qc_complete(qc, err_mask);
}
}
}
VPRINTK("EXIT\n");
}
+/**
+ * mv_interrupt -
+ * @irq: unused
+ * @dev_instance: private data; in this case the host structure
+ * @regs: unused
+ *
+ * Read the read only register to determine if any host
+ * controllers have pending interrupts. If so, call lower level
+ * routine to handle. Also check for PCI errors which are only
+ * reported here.
+ *
+ * LOCKING:
+ * This routine holds the host_set lock while processing pending
+ * interrupts.
+ */
static irqreturn_t mv_interrupt(int irq, void *dev_instance,
struct pt_regs *regs)
{
struct ata_host_set *host_set = dev_instance;
unsigned int hc, handled = 0, n_hcs;
- void __iomem *mmio;
+ void __iomem *mmio = host_set->mmio_base;
u32 irq_stat;
- mmio = host_set->mmio_base;
irq_stat = readl(mmio + HC_MAIN_IRQ_CAUSE_OFS);
- n_hcs = mv_get_hc_count(host_set->ports[0]->flags);
/* check the cases where we either have nothing pending or have read
* a bogus register value which can indicate HW removal or PCI fault
@@ -564,64 +1175,89 @@ static irqreturn_t mv_interrupt(int irq, void *dev_instance,
return IRQ_NONE;
}
+ n_hcs = mv_get_hc_count(host_set->ports[0]->flags);
spin_lock(&host_set->lock);
for (hc = 0; hc < n_hcs; hc++) {
u32 relevant = irq_stat & (HC0_IRQ_PEND << (hc * HC_SHIFT));
if (relevant) {
mv_host_intr(host_set, relevant, hc);
- handled = 1;
+ handled++;
}
}
if (PCI_ERR & irq_stat) {
- /* FIXME: these are all masked by default, but still need
- * to recover from them properly.
- */
- }
+ printk(KERN_ERR DRV_NAME ": PCI ERROR; PCI IRQ cause=0x%08x\n",
+ readl(mmio + PCI_IRQ_CAUSE_OFS));
+ DPRINTK("All regs @ PCI error\n");
+ mv_dump_all_regs(mmio, -1, to_pci_dev(host_set->dev));
+
+ writelfl(0, mmio + PCI_IRQ_CAUSE_OFS);
+ handled++;
+ }
spin_unlock(&host_set->lock);
return IRQ_RETVAL(handled);
}
+/**
+ * mv_phy_reset - Perform eDMA reset followed by COMRESET
+ * @ap: ATA channel to manipulate
+ *
+ * Part of this is taken from __sata_phy_reset and modified to
+ * not sleep since this routine gets called from interrupt level.
+ *
+ * LOCKING:
+ * Inherited from caller. This is coded to safe to call at
+ * interrupt level, i.e. it does not sleep.
+ */
static void mv_phy_reset(struct ata_port *ap)
{
void __iomem *port_mmio = mv_ap_base(ap);
struct ata_taskfile tf;
struct ata_device *dev = &ap->device[0];
- u32 edma = 0, bdma;
+ unsigned long timeout;
VPRINTK("ENTER, port %u, mmio 0x%p\n", ap->port_no, port_mmio);
- edma = readl(port_mmio + EDMA_CMD_OFS);
- if (EDMA_EN & edma) {
- /* disable EDMA if active */
- edma &= ~EDMA_EN;
- writelfl(edma | EDMA_DS, port_mmio + EDMA_CMD_OFS);
- udelay(1);
- } else if (mv_port_bdma_capable(ap) &&
- (bdma = readl(port_mmio + BDMA_CMD_OFS)) & BDMA_START) {
- /* disable BDMA if active */
- writelfl(bdma & ~BDMA_START, port_mmio + BDMA_CMD_OFS);
- }
+ mv_stop_dma(ap);
- writelfl(edma | ATA_RST, port_mmio + EDMA_CMD_OFS);
+ writelfl(ATA_RST, port_mmio + EDMA_CMD_OFS);
udelay(25); /* allow reset propagation */
/* Spec never mentions clearing the bit. Marvell's driver does
* clear the bit, however.
*/
- writelfl(edma & ~ATA_RST, port_mmio + EDMA_CMD_OFS);
+ writelfl(0, port_mmio + EDMA_CMD_OFS);
- VPRINTK("Done. Now calling __sata_phy_reset()\n");
+ VPRINTK("S-regs after ATA_RST: SStat 0x%08x SErr 0x%08x "
+ "SCtrl 0x%08x\n", mv_scr_read(ap, SCR_STATUS),
+ mv_scr_read(ap, SCR_ERROR), mv_scr_read(ap, SCR_CONTROL));
/* proceed to init communications via the scr_control reg */
- __sata_phy_reset(ap);
+ scr_write_flush(ap, SCR_CONTROL, 0x301);
+ mdelay(1);
+ scr_write_flush(ap, SCR_CONTROL, 0x300);
+ timeout = jiffies + (HZ * 1);
+ do {
+ mdelay(10);
+ if ((scr_read(ap, SCR_STATUS) & 0xf) != 1)
+ break;
+ } while (time_before(jiffies, timeout));
+
+ VPRINTK("S-regs after PHY wake: SStat 0x%08x SErr 0x%08x "
+ "SCtrl 0x%08x\n", mv_scr_read(ap, SCR_STATUS),
+ mv_scr_read(ap, SCR_ERROR), mv_scr_read(ap, SCR_CONTROL));
- if (ap->flags & ATA_FLAG_PORT_DISABLED) {
- VPRINTK("Port disabled pre-sig. Exiting.\n");
+ if (sata_dev_present(ap)) {
+ ata_port_probe(ap);
+ } else {
+ printk(KERN_INFO "ata%u: no device found (phy stat %08x)\n",
+ ap->id, scr_read(ap, SCR_STATUS));
+ ata_port_disable(ap);
return;
}
+ ap->cbl = ATA_CBL_SATA;
tf.lbah = readb((void __iomem *) ap->ioaddr.lbah_addr);
tf.lbam = readb((void __iomem *) ap->ioaddr.lbam_addr);
@@ -636,37 +1272,118 @@ static void mv_phy_reset(struct ata_port *ap)
VPRINTK("EXIT\n");
}
-static void mv_port_init(struct ata_ioports *port, unsigned long base)
+/**
+ * mv_eng_timeout - Routine called by libata when SCSI times out I/O
+ * @ap: ATA channel to manipulate
+ *
+ * Intent is to clear all pending error conditions, reset the
+ * chip/bus, fail the command, and move on.
+ *
+ * LOCKING:
+ * This routine holds the host_set lock while failing the command.
+ */
+static void mv_eng_timeout(struct ata_port *ap)
+{
+ struct ata_queued_cmd *qc;
+ unsigned long flags;
+
+ printk(KERN_ERR "ata%u: Entering mv_eng_timeout\n",ap->id);
+ DPRINTK("All regs @ start of eng_timeout\n");
+ mv_dump_all_regs(ap->host_set->mmio_base, ap->port_no,
+ to_pci_dev(ap->host_set->dev));
+
+ qc = ata_qc_from_tag(ap, ap->active_tag);
+ printk(KERN_ERR "mmio_base %p ap %p qc %p scsi_cmnd %p &cmnd %p\n",
+ ap->host_set->mmio_base, ap, qc, qc->scsicmd,
+ &qc->scsicmd->cmnd);
+
+ mv_err_intr(ap);
+ mv_phy_reset(ap);
+
+ if (!qc) {
+ printk(KERN_ERR "ata%u: BUG: timeout without command\n",
+ ap->id);
+ } else {
+ /* hack alert! We cannot use the supplied completion
+ * function from inside the ->eh_strategy_handler() thread.
+ * libata is the only user of ->eh_strategy_handler() in
+ * any kernel, so the default scsi_done() assumes it is
+ * not being called from the SCSI EH.
+ */
+ spin_lock_irqsave(&ap->host_set->lock, flags);
+ qc->scsidone = scsi_finish_command;
+ ata_qc_complete(qc, AC_ERR_OTHER);
+ spin_unlock_irqrestore(&ap->host_set->lock, flags);
+ }
+}
+
+/**
+ * mv_port_init - Perform some early initialization on a single port.
+ * @port: libata data structure storing shadow register addresses
+ * @port_mmio: base address of the port
+ *
+ * Initialize shadow register mmio addresses, clear outstanding
+ * interrupts on the port, and unmask interrupts for the future
+ * start of the port.
+ *
+ * LOCKING:
+ * Inherited from caller.
+ */
+static void mv_port_init(struct ata_ioports *port, void __iomem *port_mmio)
{
- /* PIO related setup */
- port->data_addr = base + SHD_PIO_DATA_OFS;
- port->error_addr = port->feature_addr = base + SHD_FEA_ERR_OFS;
- port->nsect_addr = base + SHD_SECT_CNT_OFS;
- port->lbal_addr = base + SHD_LBA_L_OFS;
- port->lbam_addr = base + SHD_LBA_M_OFS;
- port->lbah_addr = base + SHD_LBA_H_OFS;
- port->device_addr = base + SHD_DEV_HD_OFS;
- port->status_addr = port->command_addr = base + SHD_CMD_STA_OFS;
- port->altstatus_addr = port->ctl_addr = base + SHD_CTL_AST_OFS;
- /* unused */
+ unsigned long shd_base = (unsigned long) port_mmio + SHD_BLK_OFS;
+ unsigned serr_ofs;
+
+ /* PIO related setup
+ */
+ port->data_addr = shd_base + (sizeof(u32) * ATA_REG_DATA);
+ port->error_addr =
+ port->feature_addr = shd_base + (sizeof(u32) * ATA_REG_ERR);
+ port->nsect_addr = shd_base + (sizeof(u32) * ATA_REG_NSECT);
+ port->lbal_addr = shd_base + (sizeof(u32) * ATA_REG_LBAL);
+ port->lbam_addr = shd_base + (sizeof(u32) * ATA_REG_LBAM);
+ port->lbah_addr = shd_base + (sizeof(u32) * ATA_REG_LBAH);
+ port->device_addr = shd_base + (sizeof(u32) * ATA_REG_DEVICE);
+ port->status_addr =
+ port->command_addr = shd_base + (sizeof(u32) * ATA_REG_STATUS);
+ /* special case: control/altstatus doesn't have ATA_REG_ address */
+ port->altstatus_addr = port->ctl_addr = shd_base + SHD_CTL_AST_OFS;
+
+ /* unused: */
port->cmd_addr = port->bmdma_addr = port->scr_addr = 0;
+ /* Clear any currently outstanding port interrupt conditions */
+ serr_ofs = mv_scr_offset(SCR_ERROR);
+ writelfl(readl(port_mmio + serr_ofs), port_mmio + serr_ofs);
+ writelfl(0, port_mmio + EDMA_ERR_IRQ_CAUSE_OFS);
+
/* unmask all EDMA error interrupts */
- writel(~0, (void __iomem *)base + EDMA_ERR_IRQ_MASK_OFS);
+ writelfl(~0, port_mmio + EDMA_ERR_IRQ_MASK_OFS);
VPRINTK("EDMA cfg=0x%08x EDMA IRQ err cause/mask=0x%08x/0x%08x\n",
- readl((void __iomem *)base + EDMA_CFG_OFS),
- readl((void __iomem *)base + EDMA_ERR_IRQ_CAUSE_OFS),
- readl((void __iomem *)base + EDMA_ERR_IRQ_MASK_OFS));
+ readl(port_mmio + EDMA_CFG_OFS),
+ readl(port_mmio + EDMA_ERR_IRQ_CAUSE_OFS),
+ readl(port_mmio + EDMA_ERR_IRQ_MASK_OFS));
}
+/**
+ * mv_host_init - Perform some early initialization of the host.
+ * @probe_ent: early data struct representing the host
+ *
+ * If possible, do an early global reset of the host. Then do
+ * our port init and clear/unmask all/relevant host interrupts.
+ *
+ * LOCKING:
+ * Inherited from caller.
+ */
static int mv_host_init(struct ata_probe_ent *probe_ent)
{
int rc = 0, n_hc, port, hc;
void __iomem *mmio = probe_ent->mmio_base;
void __iomem *port_mmio;
- if (mv_master_reset(probe_ent->mmio_base)) {
+ if ((MV_FLAG_GLBL_SFT_RST & probe_ent->host_flags) &&
+ mv_global_soft_reset(probe_ent->mmio_base)) {
rc = 1;
goto done;
}
@@ -676,17 +1393,27 @@ static int mv_host_init(struct ata_probe_ent *probe_ent)
for (port = 0; port < probe_ent->n_ports; port++) {
port_mmio = mv_port_base(mmio, port);
- mv_port_init(&probe_ent->port[port], (unsigned long)port_mmio);
+ mv_port_init(&probe_ent->port[port], port_mmio);
}
for (hc = 0; hc < n_hc; hc++) {
- VPRINTK("HC%i: HC config=0x%08x HC IRQ cause=0x%08x\n", hc,
- readl(mv_hc_base(mmio, hc) + HC_CFG_OFS),
- readl(mv_hc_base(mmio, hc) + HC_IRQ_CAUSE_OFS));
+ void __iomem *hc_mmio = mv_hc_base(mmio, hc);
+
+ VPRINTK("HC%i: HC config=0x%08x HC IRQ cause "
+ "(before clear)=0x%08x\n", hc,
+ readl(hc_mmio + HC_CFG_OFS),
+ readl(hc_mmio + HC_IRQ_CAUSE_OFS));
+
+ /* Clear any currently outstanding hc interrupt conditions */
+ writelfl(0, hc_mmio + HC_IRQ_CAUSE_OFS);
}
- writel(~HC_MAIN_MASKED_IRQS, mmio + HC_MAIN_IRQ_MASK_OFS);
- writel(PCI_UNMASK_ALL_IRQS, mmio + PCI_IRQ_MASK_OFS);
+ /* Clear any currently outstanding host interrupt conditions */
+ writelfl(0, mmio + PCI_IRQ_CAUSE_OFS);
+
+ /* and unmask interrupt generation for host regs */
+ writelfl(PCI_UNMASK_ALL_IRQS, mmio + PCI_IRQ_MASK_OFS);
+ writelfl(~HC_MAIN_MASKED_IRQS, mmio + HC_MAIN_IRQ_MASK_OFS);
VPRINTK("HC MAIN IRQ cause/mask=0x%08x/0x%08x "
"PCI int cause/mask=0x%08x/0x%08x\n",
@@ -694,11 +1421,53 @@ static int mv_host_init(struct ata_probe_ent *probe_ent)
readl(mmio + HC_MAIN_IRQ_MASK_OFS),
readl(mmio + PCI_IRQ_CAUSE_OFS),
readl(mmio + PCI_IRQ_MASK_OFS));
-
- done:
+done:
return rc;
}
+/**
+ * mv_print_info - Dump key info to kernel log for perusal.
+ * @probe_ent: early data struct representing the host
+ *
+ * FIXME: complete this.
+ *
+ * LOCKING:
+ * Inherited from caller.
+ */
+static void mv_print_info(struct ata_probe_ent *probe_ent)
+{
+ struct pci_dev *pdev = to_pci_dev(probe_ent->dev);
+ struct mv_host_priv *hpriv = probe_ent->private_data;
+ u8 rev_id, scc;
+ const char *scc_s;
+
+ /* Use this to determine the HW stepping of the chip so we know
+ * what errata to workaround
+ */
+ pci_read_config_byte(pdev, PCI_REVISION_ID, &rev_id);
+
+ pci_read_config_byte(pdev, PCI_CLASS_DEVICE, &scc);
+ if (scc == 0)
+ scc_s = "SCSI";
+ else if (scc == 0x01)
+ scc_s = "RAID";
+ else
+ scc_s = "unknown";
+
+ dev_printk(KERN_INFO, &pdev->dev,
+ "%u slots %u ports %s mode IRQ via %s\n",
+ (unsigned)MV_MAX_Q_DEPTH, probe_ent->n_ports,
+ scc_s, (MV_HP_FLAG_MSI & hpriv->hp_flags) ? "MSI" : "INTx");
+}
+
+/**
+ * mv_init_one - handle a positive probe of a Marvell host
+ * @pdev: PCI device found
+ * @ent: PCI device ID entry for the matched host
+ *
+ * LOCKING:
+ * Inherited from caller.
+ */
static int mv_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
{
static int printed_version = 0;
@@ -706,15 +1475,10 @@ static int mv_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
struct mv_host_priv *hpriv;
unsigned int board_idx = (unsigned int)ent->driver_data;
void __iomem *mmio_base;
- int pci_dev_busy = 0;
- int rc;
+ int pci_dev_busy = 0, rc;
- if (!printed_version++) {
- printk(KERN_DEBUG DRV_NAME " version " DRV_VERSION "\n");
- }
-
- VPRINTK("ENTER for PCI Bus:Slot.Func=%u:%u.%u\n", pdev->bus->number,
- PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn));
+ if (!printed_version++)
+ dev_printk(KERN_INFO, &pdev->dev, "version " DRV_VERSION "\n");
rc = pci_enable_device(pdev);
if (rc) {
@@ -727,8 +1491,6 @@ static int mv_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
goto err_out;
}
- pci_intx(pdev, 1);
-
probe_ent = kmalloc(sizeof(*probe_ent), GFP_KERNEL);
if (probe_ent == NULL) {
rc = -ENOMEM;
@@ -739,8 +1501,7 @@ static int mv_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
probe_ent->dev = pci_dev_to_dev(pdev);
INIT_LIST_HEAD(&probe_ent->node);
- mmio_base = ioremap_nocache(pci_resource_start(pdev, MV_PRIMARY_BAR),
- pci_resource_len(pdev, MV_PRIMARY_BAR));
+ mmio_base = pci_iomap(pdev, MV_PRIMARY_BAR, 0);
if (mmio_base == NULL) {
rc = -ENOMEM;
goto err_out_free_ent;
@@ -769,37 +1530,40 @@ static int mv_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
if (rc) {
goto err_out_hpriv;
}
-/* mv_print_info(probe_ent); */
- {
- int b, w;
- u32 dw[4]; /* hold a line of 16b */
- VPRINTK("PCI config space:\n");
- for (b = 0; b < 0x40; ) {
- for (w = 0; w < 4; w++) {
- (void) pci_read_config_dword(pdev,b,&dw[w]);
- b += sizeof(*dw);
- }
- VPRINTK("%08x %08x %08x %08x\n",
- dw[0],dw[1],dw[2],dw[3]);
- }
+ /* Enable interrupts */
+ if (pci_enable_msi(pdev) == 0) {
+ hpriv->hp_flags |= MV_HP_FLAG_MSI;
+ } else {
+ pci_intx(pdev, 1);
}
- /* FIXME: check ata_device_add return value */
- ata_device_add(probe_ent);
- kfree(probe_ent);
+ mv_dump_pci_cfg(pdev, 0x68);
+ mv_print_info(probe_ent);
+
+ if (ata_device_add(probe_ent) == 0) {
+ rc = -ENODEV; /* No devices discovered */
+ goto err_out_dev_add;
+ }
+ kfree(probe_ent);
return 0;
- err_out_hpriv:
+err_out_dev_add:
+ if (MV_HP_FLAG_MSI & hpriv->hp_flags) {
+ pci_disable_msi(pdev);
+ } else {
+ pci_intx(pdev, 0);
+ }
+err_out_hpriv:
kfree(hpriv);
- err_out_iounmap:
- iounmap(mmio_base);
- err_out_free_ent:
+err_out_iounmap:
+ pci_iounmap(pdev, mmio_base);
+err_out_free_ent:
kfree(probe_ent);
- err_out_regions:
+err_out_regions:
pci_release_regions(pdev);
- err_out:
+err_out:
if (!pci_dev_busy) {
pci_disable_device(pdev);
}
diff --git a/drivers/scsi/sata_nv.c b/drivers/scsi/sata_nv.c
index cb832b03ec5e..37a4fae95ed4 100644
--- a/drivers/scsi/sata_nv.c
+++ b/drivers/scsi/sata_nv.c
@@ -61,7 +61,7 @@
#include <linux/blkdev.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
-#include "scsi.h"
+#include <linux/device.h>
#include <scsi/scsi_host.h>
#include <linux/libata.h>
@@ -218,7 +218,7 @@ static struct pci_driver nv_pci_driver = {
.remove = ata_pci_remove_one,
};
-static Scsi_Host_Template nv_sht = {
+static struct scsi_host_template nv_sht = {
.module = THIS_MODULE,
.name = DRV_NAME,
.ioctl = ata_scsi_ioctl,
@@ -238,7 +238,7 @@ static Scsi_Host_Template nv_sht = {
.ordered_flush = 1,
};
-static struct ata_port_operations nv_ops = {
+static const struct ata_port_operations nv_ops = {
.port_disable = ata_port_disable,
.tf_load = ata_tf_load,
.tf_read = ata_tf_read,
@@ -331,7 +331,7 @@ static u32 nv_scr_read (struct ata_port *ap, unsigned int sc_reg)
return 0xffffffffU;
if (host->host_flags & NV_HOST_FLAGS_SCR_MMIO)
- return readl((void*)ap->ioaddr.scr_addr + (sc_reg * 4));
+ return readl((void __iomem *)ap->ioaddr.scr_addr + (sc_reg * 4));
else
return inl(ap->ioaddr.scr_addr + (sc_reg * 4));
}
@@ -345,7 +345,7 @@ static void nv_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val)
return;
if (host->host_flags & NV_HOST_FLAGS_SCR_MMIO)
- writel(val, (void*)ap->ioaddr.scr_addr + (sc_reg * 4));
+ writel(val, (void __iomem *)ap->ioaddr.scr_addr + (sc_reg * 4));
else
outl(val, ap->ioaddr.scr_addr + (sc_reg * 4));
}
@@ -383,7 +383,7 @@ static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
return -ENODEV;
if (!printed_version++)
- printk(KERN_DEBUG DRV_NAME " version " DRV_VERSION "\n");
+ dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
rc = pci_enable_device(pdev);
if (rc)
@@ -405,7 +405,7 @@ static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
rc = -ENOMEM;
ppi = &nv_port_info;
- probe_ent = ata_pci_init_native_mode(pdev, &ppi);
+ probe_ent = ata_pci_init_native_mode(pdev, &ppi, ATA_PORT_PRIMARY | ATA_PORT_SECONDARY);
if (!probe_ent)
goto err_out_regions;
diff --git a/drivers/scsi/sata_promise.c b/drivers/scsi/sata_promise.c
index 538ad727bd2e..9edc9d91efc3 100644
--- a/drivers/scsi/sata_promise.c
+++ b/drivers/scsi/sata_promise.c
@@ -38,8 +38,9 @@
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/sched.h>
-#include "scsi.h"
+#include <linux/device.h>
#include <scsi/scsi_host.h>
+#include <scsi/scsi_cmnd.h>
#include <linux/libata.h>
#include <asm/io.h>
#include "sata_promise.h"
@@ -87,13 +88,13 @@ static void pdc_port_stop(struct ata_port *ap);
static void pdc_pata_phy_reset(struct ata_port *ap);
static void pdc_sata_phy_reset(struct ata_port *ap);
static void pdc_qc_prep(struct ata_queued_cmd *qc);
-static void pdc_tf_load_mmio(struct ata_port *ap, struct ata_taskfile *tf);
-static void pdc_exec_command_mmio(struct ata_port *ap, struct ata_taskfile *tf);
+static void pdc_tf_load_mmio(struct ata_port *ap, const struct ata_taskfile *tf);
+static void pdc_exec_command_mmio(struct ata_port *ap, const struct ata_taskfile *tf);
static void pdc_irq_clear(struct ata_port *ap);
static int pdc_qc_issue_prot(struct ata_queued_cmd *qc);
-static Scsi_Host_Template pdc_ata_sht = {
+static struct scsi_host_template pdc_ata_sht = {
.module = THIS_MODULE,
.name = DRV_NAME,
.ioctl = ata_scsi_ioctl,
@@ -113,7 +114,7 @@ static Scsi_Host_Template pdc_ata_sht = {
.ordered_flush = 1,
};
-static struct ata_port_operations pdc_sata_ops = {
+static const struct ata_port_operations pdc_sata_ops = {
.port_disable = ata_port_disable,
.tf_load = pdc_tf_load_mmio,
.tf_read = ata_tf_read,
@@ -136,7 +137,7 @@ static struct ata_port_operations pdc_sata_ops = {
.host_stop = ata_pci_host_stop,
};
-static struct ata_port_operations pdc_pata_ops = {
+static const struct ata_port_operations pdc_pata_ops = {
.port_disable = ata_port_disable,
.tf_load = pdc_tf_load_mmio,
.tf_read = ata_tf_read,
@@ -195,6 +196,8 @@ static struct ata_port_info pdc_port_info[] = {
static struct pci_device_id pdc_ata_pci_tbl[] = {
{ PCI_VENDOR_ID_PROMISE, 0x3371, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
board_2037x },
+ { PCI_VENDOR_ID_PROMISE, 0x3570, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ board_2037x },
{ PCI_VENDOR_ID_PROMISE, 0x3571, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
board_2037x },
{ PCI_VENDOR_ID_PROMISE, 0x3373, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
@@ -207,6 +210,8 @@ static struct pci_device_id pdc_ata_pci_tbl[] = {
board_2037x },
{ PCI_VENDOR_ID_PROMISE, 0x3d75, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
board_2037x },
+ { PCI_VENDOR_ID_PROMISE, 0x3d73, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ board_2037x },
{ PCI_VENDOR_ID_PROMISE, 0x3318, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
board_20319 },
@@ -324,7 +329,7 @@ static u32 pdc_sata_scr_read (struct ata_port *ap, unsigned int sc_reg)
{
if (sc_reg > SCR_CONTROL)
return 0xffffffffU;
- return readl((void *) ap->ioaddr.scr_addr + (sc_reg * 4));
+ return readl((void __iomem *) ap->ioaddr.scr_addr + (sc_reg * 4));
}
@@ -333,7 +338,7 @@ static void pdc_sata_scr_write (struct ata_port *ap, unsigned int sc_reg,
{
if (sc_reg > SCR_CONTROL)
return;
- writel(val, (void *) ap->ioaddr.scr_addr + (sc_reg * 4));
+ writel(val, (void __iomem *) ap->ioaddr.scr_addr + (sc_reg * 4));
}
static void pdc_qc_prep(struct ata_queued_cmd *qc)
@@ -395,7 +400,8 @@ static void pdc_eng_timeout(struct ata_port *ap)
case ATA_PROT_DMA:
case ATA_PROT_NODATA:
printk(KERN_ERR "ata%u: command timeout\n", ap->id);
- ata_qc_complete(qc, ata_wait_idle(ap) | ATA_ERR);
+ drv_stat = ata_wait_idle(ap);
+ ata_qc_complete(qc, __ac_err_mask(drv_stat));
break;
default:
@@ -404,7 +410,7 @@ static void pdc_eng_timeout(struct ata_port *ap)
printk(KERN_ERR "ata%u: unknown timeout, cmd 0x%x stat 0x%x\n",
ap->id, qc->tf.command, drv_stat);
- ata_qc_complete(qc, drv_stat);
+ ata_qc_complete(qc, ac_err_mask(drv_stat));
break;
}
@@ -416,33 +422,30 @@ out:
static inline unsigned int pdc_host_intr( struct ata_port *ap,
struct ata_queued_cmd *qc)
{
- u8 status;
- unsigned int handled = 0, have_err = 0;
+ unsigned int handled = 0, err_mask = 0;
u32 tmp;
void __iomem *mmio = (void __iomem *) ap->ioaddr.cmd_addr + PDC_GLOBAL_CTL;
tmp = readl(mmio);
if (tmp & PDC_ERR_MASK) {
- have_err = 1;
+ err_mask = AC_ERR_DEV;
pdc_reset_port(ap);
}
switch (qc->tf.protocol) {
case ATA_PROT_DMA:
case ATA_PROT_NODATA:
- status = ata_wait_idle(ap);
- if (have_err)
- status |= ATA_ERR;
- ata_qc_complete(qc, status);
+ err_mask |= ac_err_mask(ata_wait_idle(ap));
+ ata_qc_complete(qc, err_mask);
handled = 1;
break;
default:
- ap->stats.idle_irq++;
- break;
+ ap->stats.idle_irq++;
+ break;
}
- return handled;
+ return handled;
}
static void pdc_irq_clear(struct ata_port *ap)
@@ -523,8 +526,8 @@ static inline void pdc_packet_start(struct ata_queued_cmd *qc)
pp->pkt[2] = seq;
wmb(); /* flush PRD, pkt writes */
- writel(pp->pkt_dma, (void *) ap->ioaddr.cmd_addr + PDC_PKT_SUBMIT);
- readl((void *) ap->ioaddr.cmd_addr + PDC_PKT_SUBMIT); /* flush */
+ writel(pp->pkt_dma, (void __iomem *) ap->ioaddr.cmd_addr + PDC_PKT_SUBMIT);
+ readl((void __iomem *) ap->ioaddr.cmd_addr + PDC_PKT_SUBMIT); /* flush */
}
static int pdc_qc_issue_prot(struct ata_queued_cmd *qc)
@@ -546,7 +549,7 @@ static int pdc_qc_issue_prot(struct ata_queued_cmd *qc)
return ata_qc_issue_prot(qc);
}
-static void pdc_tf_load_mmio(struct ata_port *ap, struct ata_taskfile *tf)
+static void pdc_tf_load_mmio(struct ata_port *ap, const struct ata_taskfile *tf)
{
WARN_ON (tf->protocol == ATA_PROT_DMA ||
tf->protocol == ATA_PROT_NODATA);
@@ -554,7 +557,7 @@ static void pdc_tf_load_mmio(struct ata_port *ap, struct ata_taskfile *tf)
}
-static void pdc_exec_command_mmio(struct ata_port *ap, struct ata_taskfile *tf)
+static void pdc_exec_command_mmio(struct ata_port *ap, const struct ata_taskfile *tf)
{
WARN_ON (tf->protocol == ATA_PROT_DMA ||
tf->protocol == ATA_PROT_NODATA);
@@ -631,7 +634,7 @@ static int pdc_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *e
int rc;
if (!printed_version++)
- printk(KERN_DEBUG DRV_NAME " version " DRV_VERSION "\n");
+ dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
/*
* If this driver happens to only be useful on Apple's K2, then
diff --git a/drivers/scsi/sata_qstor.c b/drivers/scsi/sata_qstor.c
index ffcdeb68641c..d274ab235781 100644
--- a/drivers/scsi/sata_qstor.c
+++ b/drivers/scsi/sata_qstor.c
@@ -35,7 +35,7 @@
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/sched.h>
-#include "scsi.h"
+#include <linux/device.h>
#include <scsi/scsi_host.h>
#include <asm/io.h>
#include <linux/libata.h>
@@ -51,8 +51,6 @@ enum {
QS_PRD_BYTES = QS_MAX_PRD * 16,
QS_PKT_BYTES = QS_CPB_BYTES + QS_PRD_BYTES,
- QS_DMA_BOUNDARY = ~0UL,
-
/* global register offsets */
QS_HCF_CNFG3 = 0x0003, /* host configuration offset */
QS_HID_HPHY = 0x0004, /* host physical interface info */
@@ -101,6 +99,10 @@ enum {
board_2068_idx = 0, /* QStor 4-port SATA/RAID */
};
+enum {
+ QS_DMA_BOUNDARY = ~0UL
+};
+
typedef enum { qs_state_idle, qs_state_pkt, qs_state_mmio } qs_state_t;
struct qs_port_priv {
@@ -125,7 +127,7 @@ static u8 qs_bmdma_status(struct ata_port *ap);
static void qs_irq_clear(struct ata_port *ap);
static void qs_eng_timeout(struct ata_port *ap);
-static Scsi_Host_Template qs_ata_sht = {
+static struct scsi_host_template qs_ata_sht = {
.module = THIS_MODULE,
.name = DRV_NAME,
.ioctl = ata_scsi_ioctl,
@@ -145,7 +147,7 @@ static Scsi_Host_Template qs_ata_sht = {
.bios_param = ata_std_bios_param,
};
-static struct ata_port_operations qs_ata_ops = {
+static const struct ata_port_operations qs_ata_ops = {
.port_disable = ata_port_disable,
.tf_load = ata_tf_load,
.tf_read = ata_tf_read,
@@ -268,16 +270,17 @@ static void qs_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val)
static void qs_fill_sg(struct ata_queued_cmd *qc)
{
- struct scatterlist *sg = qc->sg;
+ struct scatterlist *sg;
struct ata_port *ap = qc->ap;
struct qs_port_priv *pp = ap->private_data;
unsigned int nelem;
u8 *prd = pp->pkt + QS_CPB_BYTES;
- assert(sg != NULL);
+ assert(qc->__sg != NULL);
assert(qc->n_elem > 0);
- for (nelem = 0; nelem < qc->n_elem; nelem++,sg++) {
+ nelem = 0;
+ ata_for_each_sg(sg, qc) {
u64 addr;
u32 len;
@@ -291,6 +294,7 @@ static void qs_fill_sg(struct ata_queued_cmd *qc)
VPRINTK("PRD[%u] = (0x%llX, 0x%X)\n", nelem,
(unsigned long long)addr, len);
+ nelem++;
}
}
@@ -398,11 +402,12 @@ static inline unsigned int qs_intr_pkt(struct ata_host_set *host_set)
qc = ata_qc_from_tag(ap, ap->active_tag);
if (qc && (!(qc->tf.ctl & ATA_NIEN))) {
switch (sHST) {
- case 0: /* sucessful CPB */
+ case 0: /* successful CPB */
case 3: /* device error */
pp->state = qs_state_idle;
qs_enter_reg_mode(qc->ap);
- ata_qc_complete(qc, sDST);
+ ata_qc_complete(qc,
+ ac_err_mask(sDST));
break;
default:
break;
@@ -431,7 +436,7 @@ static inline unsigned int qs_intr_mmio(struct ata_host_set *host_set)
if (qc && (!(qc->tf.ctl & ATA_NIEN))) {
/* check main status, clearing INTRQ */
- u8 status = ata_chk_status(ap);
+ u8 status = ata_check_status(ap);
if ((status & ATA_BUSY))
continue;
DPRINTK("ata%u: protocol %d (dev_stat 0x%X)\n",
@@ -439,7 +444,7 @@ static inline unsigned int qs_intr_mmio(struct ata_host_set *host_set)
/* complete taskfile transaction */
pp->state = qs_state_idle;
- ata_qc_complete(qc, status);
+ ata_qc_complete(qc, ac_err_mask(status));
handled = 1;
}
}
@@ -597,25 +602,22 @@ static int qs_set_dma_masks(struct pci_dev *pdev, void __iomem *mmio_base)
if (rc) {
rc = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
if (rc) {
- printk(KERN_ERR DRV_NAME
- "(%s): 64-bit DMA enable failed\n",
- pci_name(pdev));
+ dev_printk(KERN_ERR, &pdev->dev,
+ "64-bit DMA enable failed\n");
return rc;
}
}
} else {
rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
if (rc) {
- printk(KERN_ERR DRV_NAME
- "(%s): 32-bit DMA enable failed\n",
- pci_name(pdev));
+ dev_printk(KERN_ERR, &pdev->dev,
+ "32-bit DMA enable failed\n");
return rc;
}
rc = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
if (rc) {
- printk(KERN_ERR DRV_NAME
- "(%s): 32-bit consistent DMA enable failed\n",
- pci_name(pdev));
+ dev_printk(KERN_ERR, &pdev->dev,
+ "32-bit consistent DMA enable failed\n");
return rc;
}
}
@@ -632,7 +634,7 @@ static int qs_ata_init_one(struct pci_dev *pdev,
int rc, port_no;
if (!printed_version++)
- printk(KERN_DEBUG DRV_NAME " version " DRV_VERSION "\n");
+ dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
rc = pci_enable_device(pdev);
if (rc)
diff --git a/drivers/scsi/sata_sil.c b/drivers/scsi/sata_sil.c
index ba98a175ee3a..d0e3c3c6c25f 100644
--- a/drivers/scsi/sata_sil.c
+++ b/drivers/scsi/sata_sil.c
@@ -41,7 +41,7 @@
#include <linux/blkdev.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
-#include "scsi.h"
+#include <linux/device.h>
#include <scsi/scsi_host.h>
#include <linux/libata.h>
@@ -130,7 +130,7 @@ static struct pci_driver sil_pci_driver = {
.remove = ata_pci_remove_one,
};
-static Scsi_Host_Template sil_sht = {
+static struct scsi_host_template sil_sht = {
.module = THIS_MODULE,
.name = DRV_NAME,
.ioctl = ata_scsi_ioctl,
@@ -150,7 +150,7 @@ static Scsi_Host_Template sil_sht = {
.ordered_flush = 1,
};
-static struct ata_port_operations sil_ops = {
+static const struct ata_port_operations sil_ops = {
.port_disable = ata_port_disable,
.dev_config = sil_dev_config,
.tf_load = ata_tf_load,
@@ -289,7 +289,7 @@ static inline unsigned long sil_scr_addr(struct ata_port *ap, unsigned int sc_re
static u32 sil_scr_read (struct ata_port *ap, unsigned int sc_reg)
{
- void *mmio = (void *) sil_scr_addr(ap, sc_reg);
+ void __iomem *mmio = (void __iomem *) sil_scr_addr(ap, sc_reg);
if (mmio)
return readl(mmio);
return 0xffffffffU;
@@ -297,7 +297,7 @@ static u32 sil_scr_read (struct ata_port *ap, unsigned int sc_reg)
static void sil_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val)
{
- void *mmio = (void *) sil_scr_addr(ap, sc_reg);
+ void *mmio = (void __iomem *) sil_scr_addr(ap, sc_reg);
if (mmio)
writel(val, mmio);
}
@@ -386,7 +386,7 @@ static int sil_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
u8 cls;
if (!printed_version++)
- printk(KERN_DEBUG DRV_NAME " version " DRV_VERSION "\n");
+ dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
/*
* If this driver happens to only be useful on Apple's K2, then
@@ -463,8 +463,8 @@ static int sil_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
writeb(cls, mmio_base + SIL_FIFO_W3);
}
} else
- printk(KERN_WARNING DRV_NAME "(%s): cache line size not set. Driver may not function\n",
- pci_name(pdev));
+ dev_printk(KERN_WARNING, &pdev->dev,
+ "cache line size not set. Driver may not function\n");
if (ent->driver_data == sil_3114) {
irq_mask = SIL_MASK_4PORT;
diff --git a/drivers/scsi/sata_sil24.c b/drivers/scsi/sata_sil24.c
new file mode 100644
index 000000000000..4682a50650b4
--- /dev/null
+++ b/drivers/scsi/sata_sil24.c
@@ -0,0 +1,891 @@
+/*
+ * sata_sil24.c - Driver for Silicon Image 3124/3132 SATA-2 controllers
+ *
+ * Copyright 2005 Tejun Heo
+ *
+ * Based on preview driver from Silicon Image.
+ *
+ * NOTE: No NCQ/ATAPI support yet. The preview driver didn't support
+ * NCQ nor ATAPI, and, unfortunately, I couldn't find out how to make
+ * those work. Enabling those shouldn't be difficult. Basic
+ * structure is all there (in libata-dev tree). If you have any
+ * information about this hardware, please contact me or linux-ide.
+ * Info is needed on...
+ *
+ * - How to issue tagged commands and turn on sactive on issue accordingly.
+ * - Where to put an ATAPI command and how to tell the device to send it.
+ * - How to enable/use 64bit.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/blkdev.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/dma-mapping.h>
+#include <linux/device.h>
+#include <scsi/scsi_host.h>
+#include <scsi/scsi_cmnd.h>
+#include <linux/libata.h>
+#include <asm/io.h>
+
+#define DRV_NAME "sata_sil24"
+#define DRV_VERSION "0.22" /* Silicon Image's preview driver was 0.10 */
+
+/*
+ * Port request block (PRB) 32 bytes
+ */
+struct sil24_prb {
+ u16 ctrl;
+ u16 prot;
+ u32 rx_cnt;
+ u8 fis[6 * 4];
+};
+
+/*
+ * Scatter gather entry (SGE) 16 bytes
+ */
+struct sil24_sge {
+ u64 addr;
+ u32 cnt;
+ u32 flags;
+};
+
+/*
+ * Port multiplier
+ */
+struct sil24_port_multiplier {
+ u32 diag;
+ u32 sactive;
+};
+
+enum {
+ /*
+ * Global controller registers (128 bytes @ BAR0)
+ */
+ /* 32 bit regs */
+ HOST_SLOT_STAT = 0x00, /* 32 bit slot stat * 4 */
+ HOST_CTRL = 0x40,
+ HOST_IRQ_STAT = 0x44,
+ HOST_PHY_CFG = 0x48,
+ HOST_BIST_CTRL = 0x50,
+ HOST_BIST_PTRN = 0x54,
+ HOST_BIST_STAT = 0x58,
+ HOST_MEM_BIST_STAT = 0x5c,
+ HOST_FLASH_CMD = 0x70,
+ /* 8 bit regs */
+ HOST_FLASH_DATA = 0x74,
+ HOST_TRANSITION_DETECT = 0x75,
+ HOST_GPIO_CTRL = 0x76,
+ HOST_I2C_ADDR = 0x78, /* 32 bit */
+ HOST_I2C_DATA = 0x7c,
+ HOST_I2C_XFER_CNT = 0x7e,
+ HOST_I2C_CTRL = 0x7f,
+
+ /* HOST_SLOT_STAT bits */
+ HOST_SSTAT_ATTN = (1 << 31),
+
+ /*
+ * Port registers
+ * (8192 bytes @ +0x0000, +0x2000, +0x4000 and +0x6000 @ BAR2)
+ */
+ PORT_REGS_SIZE = 0x2000,
+ PORT_PRB = 0x0000, /* (32 bytes PRB + 16 bytes SGEs * 6) * 31 (3968 bytes) */
+
+ PORT_PM = 0x0f80, /* 8 bytes PM * 16 (128 bytes) */
+ /* 32 bit regs */
+ PORT_CTRL_STAT = 0x1000, /* write: ctrl-set, read: stat */
+ PORT_CTRL_CLR = 0x1004, /* write: ctrl-clear */
+ PORT_IRQ_STAT = 0x1008, /* high: status, low: interrupt */
+ PORT_IRQ_ENABLE_SET = 0x1010, /* write: enable-set */
+ PORT_IRQ_ENABLE_CLR = 0x1014, /* write: enable-clear */
+ PORT_ACTIVATE_UPPER_ADDR= 0x101c,
+ PORT_EXEC_FIFO = 0x1020, /* command execution fifo */
+ PORT_CMD_ERR = 0x1024, /* command error number */
+ PORT_FIS_CFG = 0x1028,
+ PORT_FIFO_THRES = 0x102c,
+ /* 16 bit regs */
+ PORT_DECODE_ERR_CNT = 0x1040,
+ PORT_DECODE_ERR_THRESH = 0x1042,
+ PORT_CRC_ERR_CNT = 0x1044,
+ PORT_CRC_ERR_THRESH = 0x1046,
+ PORT_HSHK_ERR_CNT = 0x1048,
+ PORT_HSHK_ERR_THRESH = 0x104a,
+ /* 32 bit regs */
+ PORT_PHY_CFG = 0x1050,
+ PORT_SLOT_STAT = 0x1800,
+ PORT_CMD_ACTIVATE = 0x1c00, /* 64 bit cmd activate * 31 (248 bytes) */
+ PORT_EXEC_DIAG = 0x1e00, /* 32bit exec diag * 16 (64 bytes, 0-10 used on 3124) */
+ PORT_PSD_DIAG = 0x1e40, /* 32bit psd diag * 16 (64 bytes, 0-8 used on 3124) */
+ PORT_SCONTROL = 0x1f00,
+ PORT_SSTATUS = 0x1f04,
+ PORT_SERROR = 0x1f08,
+ PORT_SACTIVE = 0x1f0c,
+
+ /* PORT_CTRL_STAT bits */
+ PORT_CS_PORT_RST = (1 << 0), /* port reset */
+ PORT_CS_DEV_RST = (1 << 1), /* device reset */
+ PORT_CS_INIT = (1 << 2), /* port initialize */
+ PORT_CS_IRQ_WOC = (1 << 3), /* interrupt write one to clear */
+ PORT_CS_RESUME = (1 << 6), /* port resume */
+ PORT_CS_32BIT_ACTV = (1 << 10), /* 32-bit activation */
+ PORT_CS_PM_EN = (1 << 13), /* port multiplier enable */
+ PORT_CS_RDY = (1 << 31), /* port ready to accept commands */
+
+ /* PORT_IRQ_STAT/ENABLE_SET/CLR */
+ /* bits[11:0] are masked */
+ PORT_IRQ_COMPLETE = (1 << 0), /* command(s) completed */
+ PORT_IRQ_ERROR = (1 << 1), /* command execution error */
+ PORT_IRQ_PORTRDY_CHG = (1 << 2), /* port ready change */
+ PORT_IRQ_PWR_CHG = (1 << 3), /* power management change */
+ PORT_IRQ_PHYRDY_CHG = (1 << 4), /* PHY ready change */
+ PORT_IRQ_COMWAKE = (1 << 5), /* COMWAKE received */
+ PORT_IRQ_UNK_FIS = (1 << 6), /* Unknown FIS received */
+ PORT_IRQ_SDB_FIS = (1 << 11), /* SDB FIS received */
+
+ /* bits[27:16] are unmasked (raw) */
+ PORT_IRQ_RAW_SHIFT = 16,
+ PORT_IRQ_MASKED_MASK = 0x7ff,
+ PORT_IRQ_RAW_MASK = (0x7ff << PORT_IRQ_RAW_SHIFT),
+
+ /* ENABLE_SET/CLR specific, intr steering - 2 bit field */
+ PORT_IRQ_STEER_SHIFT = 30,
+ PORT_IRQ_STEER_MASK = (3 << PORT_IRQ_STEER_SHIFT),
+
+ /* PORT_CMD_ERR constants */
+ PORT_CERR_DEV = 1, /* Error bit in D2H Register FIS */
+ PORT_CERR_SDB = 2, /* Error bit in SDB FIS */
+ PORT_CERR_DATA = 3, /* Error in data FIS not detected by dev */
+ PORT_CERR_SEND = 4, /* Initial cmd FIS transmission failure */
+ PORT_CERR_INCONSISTENT = 5, /* Protocol mismatch */
+ PORT_CERR_DIRECTION = 6, /* Data direction mismatch */
+ PORT_CERR_UNDERRUN = 7, /* Ran out of SGEs while writing */
+ PORT_CERR_OVERRUN = 8, /* Ran out of SGEs while reading */
+ PORT_CERR_PKT_PROT = 11, /* DIR invalid in 1st PIO setup of ATAPI */
+ PORT_CERR_SGT_BOUNDARY = 16, /* PLD ecode 00 - SGT not on qword boundary */
+ PORT_CERR_SGT_TGTABRT = 17, /* PLD ecode 01 - target abort */
+ PORT_CERR_SGT_MSTABRT = 18, /* PLD ecode 10 - master abort */
+ PORT_CERR_SGT_PCIPERR = 19, /* PLD ecode 11 - PCI parity err while fetching SGT */
+ PORT_CERR_CMD_BOUNDARY = 24, /* ctrl[15:13] 001 - PRB not on qword boundary */
+ PORT_CERR_CMD_TGTABRT = 25, /* ctrl[15:13] 010 - target abort */
+ PORT_CERR_CMD_MSTABRT = 26, /* ctrl[15:13] 100 - master abort */
+ PORT_CERR_CMD_PCIPERR = 27, /* ctrl[15:13] 110 - PCI parity err while fetching PRB */
+ PORT_CERR_XFR_UNDEF = 32, /* PSD ecode 00 - undefined */
+ PORT_CERR_XFR_TGTABRT = 33, /* PSD ecode 01 - target abort */
+ PORT_CERR_XFR_MSGABRT = 34, /* PSD ecode 10 - master abort */
+ PORT_CERR_XFR_PCIPERR = 35, /* PSD ecode 11 - PCI prity err during transfer */
+ PORT_CERR_SENDSERVICE = 36, /* FIS received while sending service */
+
+ /*
+ * Other constants
+ */
+ SGE_TRM = (1 << 31), /* Last SGE in chain */
+ PRB_SOFT_RST = (1 << 7), /* Soft reset request (ign BSY?) */
+
+ /* board id */
+ BID_SIL3124 = 0,
+ BID_SIL3132 = 1,
+ BID_SIL3131 = 2,
+
+ IRQ_STAT_4PORTS = 0xf,
+};
+
+struct sil24_cmd_block {
+ struct sil24_prb prb;
+ struct sil24_sge sge[LIBATA_MAX_PRD];
+};
+
+/*
+ * ap->private_data
+ *
+ * The preview driver always returned 0 for status. We emulate it
+ * here from the previous interrupt.
+ */
+struct sil24_port_priv {
+ struct sil24_cmd_block *cmd_block; /* 32 cmd blocks */
+ dma_addr_t cmd_block_dma; /* DMA base addr for them */
+ struct ata_taskfile tf; /* Cached taskfile registers */
+};
+
+/* ap->host_set->private_data */
+struct sil24_host_priv {
+ void __iomem *host_base; /* global controller control (128 bytes @BAR0) */
+ void __iomem *port_base; /* port registers (4 * 8192 bytes @BAR2) */
+};
+
+static u8 sil24_check_status(struct ata_port *ap);
+static u32 sil24_scr_read(struct ata_port *ap, unsigned sc_reg);
+static void sil24_scr_write(struct ata_port *ap, unsigned sc_reg, u32 val);
+static void sil24_tf_read(struct ata_port *ap, struct ata_taskfile *tf);
+static void sil24_phy_reset(struct ata_port *ap);
+static void sil24_qc_prep(struct ata_queued_cmd *qc);
+static int sil24_qc_issue(struct ata_queued_cmd *qc);
+static void sil24_irq_clear(struct ata_port *ap);
+static void sil24_eng_timeout(struct ata_port *ap);
+static irqreturn_t sil24_interrupt(int irq, void *dev_instance, struct pt_regs *regs);
+static int sil24_port_start(struct ata_port *ap);
+static void sil24_port_stop(struct ata_port *ap);
+static void sil24_host_stop(struct ata_host_set *host_set);
+static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent);
+
+static struct pci_device_id sil24_pci_tbl[] = {
+ { 0x1095, 0x3124, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BID_SIL3124 },
+ { 0x1095, 0x3132, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BID_SIL3132 },
+ { 0x1095, 0x3131, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BID_SIL3131 },
+ { 0x1095, 0x3531, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BID_SIL3131 },
+ { } /* terminate list */
+};
+
+static struct pci_driver sil24_pci_driver = {
+ .name = DRV_NAME,
+ .id_table = sil24_pci_tbl,
+ .probe = sil24_init_one,
+ .remove = ata_pci_remove_one, /* safe? */
+};
+
+static struct scsi_host_template sil24_sht = {
+ .module = THIS_MODULE,
+ .name = DRV_NAME,
+ .ioctl = ata_scsi_ioctl,
+ .queuecommand = ata_scsi_queuecmd,
+ .eh_strategy_handler = ata_scsi_error,
+ .can_queue = ATA_DEF_QUEUE,
+ .this_id = ATA_SHT_THIS_ID,
+ .sg_tablesize = LIBATA_MAX_PRD,
+ .max_sectors = ATA_MAX_SECTORS,
+ .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
+ .emulated = ATA_SHT_EMULATED,
+ .use_clustering = ATA_SHT_USE_CLUSTERING,
+ .proc_name = DRV_NAME,
+ .dma_boundary = ATA_DMA_BOUNDARY,
+ .slave_configure = ata_scsi_slave_config,
+ .bios_param = ata_std_bios_param,
+ .ordered_flush = 1, /* NCQ not supported yet */
+};
+
+static const struct ata_port_operations sil24_ops = {
+ .port_disable = ata_port_disable,
+
+ .check_status = sil24_check_status,
+ .check_altstatus = sil24_check_status,
+ .dev_select = ata_noop_dev_select,
+
+ .tf_read = sil24_tf_read,
+
+ .phy_reset = sil24_phy_reset,
+
+ .qc_prep = sil24_qc_prep,
+ .qc_issue = sil24_qc_issue,
+
+ .eng_timeout = sil24_eng_timeout,
+
+ .irq_handler = sil24_interrupt,
+ .irq_clear = sil24_irq_clear,
+
+ .scr_read = sil24_scr_read,
+ .scr_write = sil24_scr_write,
+
+ .port_start = sil24_port_start,
+ .port_stop = sil24_port_stop,
+ .host_stop = sil24_host_stop,
+};
+
+/*
+ * Use bits 30-31 of host_flags to encode available port numbers.
+ * Current maxium is 4.
+ */
+#define SIL24_NPORTS2FLAG(nports) ((((unsigned)(nports) - 1) & 0x3) << 30)
+#define SIL24_FLAG2NPORTS(flag) ((((flag) >> 30) & 0x3) + 1)
+
+static struct ata_port_info sil24_port_info[] = {
+ /* sil_3124 */
+ {
+ .sht = &sil24_sht,
+ .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
+ ATA_FLAG_SATA_RESET | ATA_FLAG_MMIO |
+ ATA_FLAG_PIO_DMA | SIL24_NPORTS2FLAG(4),
+ .pio_mask = 0x1f, /* pio0-4 */
+ .mwdma_mask = 0x07, /* mwdma0-2 */
+ .udma_mask = 0x3f, /* udma0-5 */
+ .port_ops = &sil24_ops,
+ },
+ /* sil_3132 */
+ {
+ .sht = &sil24_sht,
+ .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
+ ATA_FLAG_SATA_RESET | ATA_FLAG_MMIO |
+ ATA_FLAG_PIO_DMA | SIL24_NPORTS2FLAG(2),
+ .pio_mask = 0x1f, /* pio0-4 */
+ .mwdma_mask = 0x07, /* mwdma0-2 */
+ .udma_mask = 0x3f, /* udma0-5 */
+ .port_ops = &sil24_ops,
+ },
+ /* sil_3131/sil_3531 */
+ {
+ .sht = &sil24_sht,
+ .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
+ ATA_FLAG_SATA_RESET | ATA_FLAG_MMIO |
+ ATA_FLAG_PIO_DMA | SIL24_NPORTS2FLAG(1),
+ .pio_mask = 0x1f, /* pio0-4 */
+ .mwdma_mask = 0x07, /* mwdma0-2 */
+ .udma_mask = 0x3f, /* udma0-5 */
+ .port_ops = &sil24_ops,
+ },
+};
+
+static inline void sil24_update_tf(struct ata_port *ap)
+{
+ struct sil24_port_priv *pp = ap->private_data;
+ void __iomem *port = (void __iomem *)ap->ioaddr.cmd_addr;
+ struct sil24_prb __iomem *prb = port;
+ u8 fis[6 * 4];
+
+ memcpy_fromio(fis, prb->fis, 6 * 4);
+ ata_tf_from_fis(fis, &pp->tf);
+}
+
+static u8 sil24_check_status(struct ata_port *ap)
+{
+ struct sil24_port_priv *pp = ap->private_data;
+ return pp->tf.command;
+}
+
+static int sil24_scr_map[] = {
+ [SCR_CONTROL] = 0,
+ [SCR_STATUS] = 1,
+ [SCR_ERROR] = 2,
+ [SCR_ACTIVE] = 3,
+};
+
+static u32 sil24_scr_read(struct ata_port *ap, unsigned sc_reg)
+{
+ void __iomem *scr_addr = (void __iomem *)ap->ioaddr.scr_addr;
+ if (sc_reg < ARRAY_SIZE(sil24_scr_map)) {
+ void __iomem *addr;
+ addr = scr_addr + sil24_scr_map[sc_reg] * 4;
+ return readl(scr_addr + sil24_scr_map[sc_reg] * 4);
+ }
+ return 0xffffffffU;
+}
+
+static void sil24_scr_write(struct ata_port *ap, unsigned sc_reg, u32 val)
+{
+ void __iomem *scr_addr = (void __iomem *)ap->ioaddr.scr_addr;
+ if (sc_reg < ARRAY_SIZE(sil24_scr_map)) {
+ void __iomem *addr;
+ addr = scr_addr + sil24_scr_map[sc_reg] * 4;
+ writel(val, scr_addr + sil24_scr_map[sc_reg] * 4);
+ }
+}
+
+static void sil24_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
+{
+ struct sil24_port_priv *pp = ap->private_data;
+ *tf = pp->tf;
+}
+
+static void sil24_phy_reset(struct ata_port *ap)
+{
+ __sata_phy_reset(ap);
+ /*
+ * No ATAPI yet. Just unconditionally indicate ATA device.
+ * If ATAPI device is attached, it will fail ATA_CMD_ID_ATA
+ * and libata core will ignore the device.
+ */
+ if (!(ap->flags & ATA_FLAG_PORT_DISABLED))
+ ap->device[0].class = ATA_DEV_ATA;
+}
+
+static inline void sil24_fill_sg(struct ata_queued_cmd *qc,
+ struct sil24_cmd_block *cb)
+{
+ struct sil24_sge *sge = cb->sge;
+ struct scatterlist *sg;
+ unsigned int idx = 0;
+
+ ata_for_each_sg(sg, qc) {
+ sge->addr = cpu_to_le64(sg_dma_address(sg));
+ sge->cnt = cpu_to_le32(sg_dma_len(sg));
+ if (ata_sg_is_last(sg, qc))
+ sge->flags = cpu_to_le32(SGE_TRM);
+ else
+ sge->flags = 0;
+
+ sge++;
+ idx++;
+ }
+}
+
+static void sil24_qc_prep(struct ata_queued_cmd *qc)
+{
+ struct ata_port *ap = qc->ap;
+ struct sil24_port_priv *pp = ap->private_data;
+ struct sil24_cmd_block *cb = pp->cmd_block + qc->tag;
+ struct sil24_prb *prb = &cb->prb;
+
+ switch (qc->tf.protocol) {
+ case ATA_PROT_PIO:
+ case ATA_PROT_DMA:
+ case ATA_PROT_NODATA:
+ break;
+ default:
+ /* ATAPI isn't supported yet */
+ BUG();
+ }
+
+ ata_tf_to_fis(&qc->tf, prb->fis, 0);
+
+ if (qc->flags & ATA_QCFLAG_DMAMAP)
+ sil24_fill_sg(qc, cb);
+}
+
+static int sil24_qc_issue(struct ata_queued_cmd *qc)
+{
+ struct ata_port *ap = qc->ap;
+ void __iomem *port = (void __iomem *)ap->ioaddr.cmd_addr;
+ struct sil24_port_priv *pp = ap->private_data;
+ dma_addr_t paddr = pp->cmd_block_dma + qc->tag * sizeof(*pp->cmd_block);
+
+ writel((u32)paddr, port + PORT_CMD_ACTIVATE);
+ return 0;
+}
+
+static void sil24_irq_clear(struct ata_port *ap)
+{
+ /* unused */
+}
+
+static int __sil24_reset_controller(void __iomem *port)
+{
+ int cnt;
+ u32 tmp;
+
+ /* Reset controller state. Is this correct? */
+ writel(PORT_CS_DEV_RST, port + PORT_CTRL_STAT);
+ readl(port + PORT_CTRL_STAT); /* sync */
+
+ /* Max ~100ms */
+ for (cnt = 0; cnt < 1000; cnt++) {
+ udelay(100);
+ tmp = readl(port + PORT_CTRL_STAT);
+ if (!(tmp & PORT_CS_DEV_RST))
+ break;
+ }
+
+ if (tmp & PORT_CS_DEV_RST)
+ return -1;
+ return 0;
+}
+
+static void sil24_reset_controller(struct ata_port *ap)
+{
+ printk(KERN_NOTICE DRV_NAME
+ " ata%u: resetting controller...\n", ap->id);
+ if (__sil24_reset_controller((void __iomem *)ap->ioaddr.cmd_addr))
+ printk(KERN_ERR DRV_NAME
+ " ata%u: failed to reset controller\n", ap->id);
+}
+
+static void sil24_eng_timeout(struct ata_port *ap)
+{
+ struct ata_queued_cmd *qc;
+
+ qc = ata_qc_from_tag(ap, ap->active_tag);
+ if (!qc) {
+ printk(KERN_ERR "ata%u: BUG: timeout without command\n",
+ ap->id);
+ return;
+ }
+
+ /*
+ * hack alert! We cannot use the supplied completion
+ * function from inside the ->eh_strategy_handler() thread.
+ * libata is the only user of ->eh_strategy_handler() in
+ * any kernel, so the default scsi_done() assumes it is
+ * not being called from the SCSI EH.
+ */
+ printk(KERN_ERR "ata%u: command timeout\n", ap->id);
+ qc->scsidone = scsi_finish_command;
+ ata_qc_complete(qc, AC_ERR_OTHER);
+
+ sil24_reset_controller(ap);
+}
+
+static void sil24_error_intr(struct ata_port *ap, u32 slot_stat)
+{
+ struct ata_queued_cmd *qc = ata_qc_from_tag(ap, ap->active_tag);
+ struct sil24_port_priv *pp = ap->private_data;
+ void __iomem *port = (void __iomem *)ap->ioaddr.cmd_addr;
+ u32 irq_stat, cmd_err, sstatus, serror;
+ unsigned int err_mask;
+
+ irq_stat = readl(port + PORT_IRQ_STAT);
+ writel(irq_stat, port + PORT_IRQ_STAT); /* clear irq */
+
+ if (!(irq_stat & PORT_IRQ_ERROR)) {
+ /* ignore non-completion, non-error irqs for now */
+ printk(KERN_WARNING DRV_NAME
+ "ata%u: non-error exception irq (irq_stat %x)\n",
+ ap->id, irq_stat);
+ return;
+ }
+
+ cmd_err = readl(port + PORT_CMD_ERR);
+ sstatus = readl(port + PORT_SSTATUS);
+ serror = readl(port + PORT_SERROR);
+ if (serror)
+ writel(serror, port + PORT_SERROR);
+
+ printk(KERN_ERR DRV_NAME " ata%u: error interrupt on port%d\n"
+ " stat=0x%x irq=0x%x cmd_err=%d sstatus=0x%x serror=0x%x\n",
+ ap->id, ap->port_no, slot_stat, irq_stat, cmd_err, sstatus, serror);
+
+ if (cmd_err == PORT_CERR_DEV || cmd_err == PORT_CERR_SDB) {
+ /*
+ * Device is reporting error, tf registers are valid.
+ */
+ sil24_update_tf(ap);
+ err_mask = ac_err_mask(pp->tf.command);
+ } else {
+ /*
+ * Other errors. libata currently doesn't have any
+ * mechanism to report these errors. Just turn on
+ * ATA_ERR.
+ */
+ err_mask = AC_ERR_OTHER;
+ }
+
+ if (qc)
+ ata_qc_complete(qc, err_mask);
+
+ sil24_reset_controller(ap);
+}
+
+static inline void sil24_host_intr(struct ata_port *ap)
+{
+ struct ata_queued_cmd *qc = ata_qc_from_tag(ap, ap->active_tag);
+ void __iomem *port = (void __iomem *)ap->ioaddr.cmd_addr;
+ u32 slot_stat;
+
+ slot_stat = readl(port + PORT_SLOT_STAT);
+ if (!(slot_stat & HOST_SSTAT_ATTN)) {
+ struct sil24_port_priv *pp = ap->private_data;
+ /*
+ * !HOST_SSAT_ATTN guarantees successful completion,
+ * so reading back tf registers is unnecessary for
+ * most commands. TODO: read tf registers for
+ * commands which require these values on successful
+ * completion (EXECUTE DEVICE DIAGNOSTIC, CHECK POWER,
+ * DEVICE RESET and READ PORT MULTIPLIER (any more?).
+ */
+ sil24_update_tf(ap);
+
+ if (qc)
+ ata_qc_complete(qc, ac_err_mask(pp->tf.command));
+ } else
+ sil24_error_intr(ap, slot_stat);
+}
+
+static irqreturn_t sil24_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
+{
+ struct ata_host_set *host_set = dev_instance;
+ struct sil24_host_priv *hpriv = host_set->private_data;
+ unsigned handled = 0;
+ u32 status;
+ int i;
+
+ status = readl(hpriv->host_base + HOST_IRQ_STAT);
+
+ if (status == 0xffffffff) {
+ printk(KERN_ERR DRV_NAME ": IRQ status == 0xffffffff, "
+ "PCI fault or device removal?\n");
+ goto out;
+ }
+
+ if (!(status & IRQ_STAT_4PORTS))
+ goto out;
+
+ spin_lock(&host_set->lock);
+
+ for (i = 0; i < host_set->n_ports; i++)
+ if (status & (1 << i)) {
+ struct ata_port *ap = host_set->ports[i];
+ if (ap && !(ap->flags & ATA_FLAG_PORT_DISABLED)) {
+ sil24_host_intr(host_set->ports[i]);
+ handled++;
+ } else
+ printk(KERN_ERR DRV_NAME
+ ": interrupt from disabled port %d\n", i);
+ }
+
+ spin_unlock(&host_set->lock);
+ out:
+ return IRQ_RETVAL(handled);
+}
+
+static inline void sil24_cblk_free(struct sil24_port_priv *pp, struct device *dev)
+{
+ const size_t cb_size = sizeof(*pp->cmd_block);
+
+ dma_free_coherent(dev, cb_size, pp->cmd_block, pp->cmd_block_dma);
+}
+
+static int sil24_port_start(struct ata_port *ap)
+{
+ struct device *dev = ap->host_set->dev;
+ struct sil24_port_priv *pp;
+ struct sil24_cmd_block *cb;
+ size_t cb_size = sizeof(*cb);
+ dma_addr_t cb_dma;
+ int rc = -ENOMEM;
+
+ pp = kzalloc(sizeof(*pp), GFP_KERNEL);
+ if (!pp)
+ goto err_out;
+
+ pp->tf.command = ATA_DRDY;
+
+ cb = dma_alloc_coherent(dev, cb_size, &cb_dma, GFP_KERNEL);
+ if (!cb)
+ goto err_out_pp;
+ memset(cb, 0, cb_size);
+
+ rc = ata_pad_alloc(ap, dev);
+ if (rc)
+ goto err_out_pad;
+
+ pp->cmd_block = cb;
+ pp->cmd_block_dma = cb_dma;
+
+ ap->private_data = pp;
+
+ return 0;
+
+err_out_pad:
+ sil24_cblk_free(pp, dev);
+err_out_pp:
+ kfree(pp);
+err_out:
+ return rc;
+}
+
+static void sil24_port_stop(struct ata_port *ap)
+{
+ struct device *dev = ap->host_set->dev;
+ struct sil24_port_priv *pp = ap->private_data;
+
+ sil24_cblk_free(pp, dev);
+ kfree(pp);
+}
+
+static void sil24_host_stop(struct ata_host_set *host_set)
+{
+ struct sil24_host_priv *hpriv = host_set->private_data;
+
+ iounmap(hpriv->host_base);
+ iounmap(hpriv->port_base);
+ kfree(hpriv);
+}
+
+static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
+{
+ static int printed_version = 0;
+ unsigned int board_id = (unsigned int)ent->driver_data;
+ struct ata_port_info *pinfo = &sil24_port_info[board_id];
+ struct ata_probe_ent *probe_ent = NULL;
+ struct sil24_host_priv *hpriv = NULL;
+ void __iomem *host_base = NULL;
+ void __iomem *port_base = NULL;
+ int i, rc;
+
+ if (!printed_version++)
+ dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
+
+ rc = pci_enable_device(pdev);
+ if (rc)
+ return rc;
+
+ rc = pci_request_regions(pdev, DRV_NAME);
+ if (rc)
+ goto out_disable;
+
+ rc = -ENOMEM;
+ /* ioremap mmio registers */
+ host_base = ioremap(pci_resource_start(pdev, 0),
+ pci_resource_len(pdev, 0));
+ if (!host_base)
+ goto out_free;
+ port_base = ioremap(pci_resource_start(pdev, 2),
+ pci_resource_len(pdev, 2));
+ if (!port_base)
+ goto out_free;
+
+ /* allocate & init probe_ent and hpriv */
+ probe_ent = kmalloc(sizeof(*probe_ent), GFP_KERNEL);
+ if (!probe_ent)
+ goto out_free;
+
+ hpriv = kmalloc(sizeof(*hpriv), GFP_KERNEL);
+ if (!hpriv)
+ goto out_free;
+
+ memset(probe_ent, 0, sizeof(*probe_ent));
+ probe_ent->dev = pci_dev_to_dev(pdev);
+ INIT_LIST_HEAD(&probe_ent->node);
+
+ probe_ent->sht = pinfo->sht;
+ probe_ent->host_flags = pinfo->host_flags;
+ probe_ent->pio_mask = pinfo->pio_mask;
+ probe_ent->udma_mask = pinfo->udma_mask;
+ probe_ent->port_ops = pinfo->port_ops;
+ probe_ent->n_ports = SIL24_FLAG2NPORTS(pinfo->host_flags);
+
+ probe_ent->irq = pdev->irq;
+ probe_ent->irq_flags = SA_SHIRQ;
+ probe_ent->mmio_base = port_base;
+ probe_ent->private_data = hpriv;
+
+ memset(hpriv, 0, sizeof(*hpriv));
+ hpriv->host_base = host_base;
+ hpriv->port_base = port_base;
+
+ /*
+ * Configure the device
+ */
+ /*
+ * FIXME: This device is certainly 64-bit capable. We just
+ * don't know how to use it. After fixing 32bit activation in
+ * this function, enable 64bit masks here.
+ */
+ rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+ if (rc) {
+ dev_printk(KERN_ERR, &pdev->dev,
+ "32-bit DMA enable failed\n");
+ goto out_free;
+ }
+ rc = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
+ if (rc) {
+ dev_printk(KERN_ERR, &pdev->dev,
+ "32-bit consistent DMA enable failed\n");
+ goto out_free;
+ }
+
+ /* GPIO off */
+ writel(0, host_base + HOST_FLASH_CMD);
+
+ /* Mask interrupts during initialization */
+ writel(0, host_base + HOST_CTRL);
+
+ for (i = 0; i < probe_ent->n_ports; i++) {
+ void __iomem *port = port_base + i * PORT_REGS_SIZE;
+ unsigned long portu = (unsigned long)port;
+ u32 tmp;
+ int cnt;
+
+ probe_ent->port[i].cmd_addr = portu + PORT_PRB;
+ probe_ent->port[i].scr_addr = portu + PORT_SCONTROL;
+
+ ata_std_ports(&probe_ent->port[i]);
+
+ /* Initial PHY setting */
+ writel(0x20c, port + PORT_PHY_CFG);
+
+ /* Clear port RST */
+ tmp = readl(port + PORT_CTRL_STAT);
+ if (tmp & PORT_CS_PORT_RST) {
+ writel(PORT_CS_PORT_RST, port + PORT_CTRL_CLR);
+ readl(port + PORT_CTRL_STAT); /* sync */
+ for (cnt = 0; cnt < 10; cnt++) {
+ msleep(10);
+ tmp = readl(port + PORT_CTRL_STAT);
+ if (!(tmp & PORT_CS_PORT_RST))
+ break;
+ }
+ if (tmp & PORT_CS_PORT_RST)
+ dev_printk(KERN_ERR, &pdev->dev,
+ "failed to clear port RST\n");
+ }
+
+ /* Zero error counters. */
+ writel(0x8000, port + PORT_DECODE_ERR_THRESH);
+ writel(0x8000, port + PORT_CRC_ERR_THRESH);
+ writel(0x8000, port + PORT_HSHK_ERR_THRESH);
+ writel(0x0000, port + PORT_DECODE_ERR_CNT);
+ writel(0x0000, port + PORT_CRC_ERR_CNT);
+ writel(0x0000, port + PORT_HSHK_ERR_CNT);
+
+ /* FIXME: 32bit activation? */
+ writel(0, port + PORT_ACTIVATE_UPPER_ADDR);
+ writel(PORT_CS_32BIT_ACTV, port + PORT_CTRL_STAT);
+
+ /* Configure interrupts */
+ writel(0xffff, port + PORT_IRQ_ENABLE_CLR);
+ writel(PORT_IRQ_COMPLETE | PORT_IRQ_ERROR | PORT_IRQ_SDB_FIS,
+ port + PORT_IRQ_ENABLE_SET);
+
+ /* Clear interrupts */
+ writel(0x0fff0fff, port + PORT_IRQ_STAT);
+ writel(PORT_CS_IRQ_WOC, port + PORT_CTRL_CLR);
+
+ /* Clear port multiplier enable and resume bits */
+ writel(PORT_CS_PM_EN | PORT_CS_RESUME, port + PORT_CTRL_CLR);
+
+ /* Reset itself */
+ if (__sil24_reset_controller(port))
+ dev_printk(KERN_ERR, &pdev->dev,
+ "failed to reset controller\n");
+ }
+
+ /* Turn on interrupts */
+ writel(IRQ_STAT_4PORTS, host_base + HOST_CTRL);
+
+ pci_set_master(pdev);
+
+ /* FIXME: check ata_device_add return value */
+ ata_device_add(probe_ent);
+
+ kfree(probe_ent);
+ return 0;
+
+ out_free:
+ if (host_base)
+ iounmap(host_base);
+ if (port_base)
+ iounmap(port_base);
+ kfree(probe_ent);
+ kfree(hpriv);
+ pci_release_regions(pdev);
+ out_disable:
+ pci_disable_device(pdev);
+ return rc;
+}
+
+static int __init sil24_init(void)
+{
+ return pci_module_init(&sil24_pci_driver);
+}
+
+static void __exit sil24_exit(void)
+{
+ pci_unregister_driver(&sil24_pci_driver);
+}
+
+MODULE_AUTHOR("Tejun Heo");
+MODULE_DESCRIPTION("Silicon Image 3124/3132 SATA low-level driver");
+MODULE_LICENSE("GPL");
+MODULE_DEVICE_TABLE(pci, sil24_pci_tbl);
+
+module_init(sil24_init);
+module_exit(sil24_exit);
diff --git a/drivers/scsi/sata_sis.c b/drivers/scsi/sata_sis.c
index b227e51d12f4..42d7c4e92501 100644
--- a/drivers/scsi/sata_sis.c
+++ b/drivers/scsi/sata_sis.c
@@ -38,7 +38,7 @@
#include <linux/blkdev.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
-#include "scsi.h"
+#include <linux/device.h>
#include <scsi/scsi_host.h>
#include <linux/libata.h>
@@ -82,7 +82,7 @@ static struct pci_driver sis_pci_driver = {
.remove = ata_pci_remove_one,
};
-static Scsi_Host_Template sis_sht = {
+static struct scsi_host_template sis_sht = {
.module = THIS_MODULE,
.name = DRV_NAME,
.ioctl = ata_scsi_ioctl,
@@ -102,7 +102,7 @@ static Scsi_Host_Template sis_sht = {
.ordered_flush = 1,
};
-static struct ata_port_operations sis_ops = {
+static const struct ata_port_operations sis_ops = {
.port_disable = ata_port_disable,
.tf_load = ata_tf_load,
.tf_read = ata_tf_read,
@@ -237,6 +237,7 @@ static void sis_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val)
static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
{
+ static int printed_version;
struct ata_probe_ent *probe_ent = NULL;
int rc;
u32 genctl;
@@ -245,6 +246,9 @@ static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
u8 pmr;
u8 port2_start;
+ if (!printed_version++)
+ dev_printk(KERN_INFO, &pdev->dev, "version " DRV_VERSION "\n");
+
rc = pci_enable_device(pdev);
if (rc)
return rc;
@@ -263,7 +267,7 @@ static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
goto err_out_regions;
ppi = &sis_port_info;
- probe_ent = ata_pci_init_native_mode(pdev, &ppi);
+ probe_ent = ata_pci_init_native_mode(pdev, &ppi, ATA_PORT_PRIMARY | ATA_PORT_SECONDARY);
if (!probe_ent) {
rc = -ENOMEM;
goto err_out_regions;
@@ -288,16 +292,18 @@ static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
pci_read_config_byte(pdev, SIS_PMR, &pmr);
if (ent->device != 0x182) {
if ((pmr & SIS_PMR_COMBINED) == 0) {
- printk(KERN_INFO "sata_sis: Detected SiS 180/181 chipset in SATA mode\n");
+ dev_printk(KERN_INFO, &pdev->dev,
+ "Detected SiS 180/181 chipset in SATA mode\n");
port2_start = 64;
}
else {
- printk(KERN_INFO "sata_sis: Detected SiS 180/181 chipset in combined mode\n");
+ dev_printk(KERN_INFO, &pdev->dev,
+ "Detected SiS 180/181 chipset in combined mode\n");
port2_start=0;
}
}
else {
- printk(KERN_INFO "sata_sis: Detected SiS 182 chipset\n");
+ dev_printk(KERN_INFO, &pdev->dev, "Detected SiS 182 chipset\n");
port2_start = 0x20;
}
diff --git a/drivers/scsi/sata_svw.c b/drivers/scsi/sata_svw.c
index d89d968bedac..9895d1caefcf 100644
--- a/drivers/scsi/sata_svw.c
+++ b/drivers/scsi/sata_svw.c
@@ -44,7 +44,7 @@
#include <linux/blkdev.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
-#include "scsi.h"
+#include <linux/device.h>
#include <scsi/scsi_host.h>
#include <linux/libata.h>
@@ -84,6 +84,8 @@
/* Port stride */
#define K2_SATA_PORT_OFFSET 0x100
+static u8 k2_stat_check_status(struct ata_port *ap);
+
static u32 k2_sata_scr_read (struct ata_port *ap, unsigned int sc_reg)
{
@@ -102,7 +104,7 @@ static void k2_sata_scr_write (struct ata_port *ap, unsigned int sc_reg,
}
-static void k2_sata_tf_load(struct ata_port *ap, struct ata_taskfile *tf)
+static void k2_sata_tf_load(struct ata_port *ap, const struct ata_taskfile *tf)
{
struct ata_ioports *ioaddr = &ap->ioaddr;
unsigned int is_addr = tf->flags & ATA_TFLAG_ISADDR;
@@ -136,16 +138,24 @@ static void k2_sata_tf_load(struct ata_port *ap, struct ata_taskfile *tf)
static void k2_sata_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
{
struct ata_ioports *ioaddr = &ap->ioaddr;
- u16 nsect, lbal, lbam, lbah;
+ u16 nsect, lbal, lbam, lbah, feature;
- nsect = tf->nsect = readw(ioaddr->nsect_addr);
- lbal = tf->lbal = readw(ioaddr->lbal_addr);
- lbam = tf->lbam = readw(ioaddr->lbam_addr);
- lbah = tf->lbah = readw(ioaddr->lbah_addr);
+ tf->command = k2_stat_check_status(ap);
tf->device = readw(ioaddr->device_addr);
+ feature = readw(ioaddr->error_addr);
+ nsect = readw(ioaddr->nsect_addr);
+ lbal = readw(ioaddr->lbal_addr);
+ lbam = readw(ioaddr->lbam_addr);
+ lbah = readw(ioaddr->lbah_addr);
+
+ tf->feature = feature;
+ tf->nsect = nsect;
+ tf->lbal = lbal;
+ tf->lbam = lbam;
+ tf->lbah = lbah;
if (tf->flags & ATA_TFLAG_LBA48) {
- tf->hob_feature = readw(ioaddr->error_addr) >> 8;
+ tf->hob_feature = feature >> 8;
tf->hob_nsect = nsect >> 8;
tf->hob_lbal = lbal >> 8;
tf->hob_lbam = lbam >> 8;
@@ -273,7 +283,7 @@ static int k2_sata_proc_info(struct Scsi_Host *shost, char *page, char **start,
#endif /* CONFIG_PPC_OF */
-static Scsi_Host_Template k2_sata_sht = {
+static struct scsi_host_template k2_sata_sht = {
.module = THIS_MODULE,
.name = DRV_NAME,
.ioctl = ata_scsi_ioctl,
@@ -297,7 +307,7 @@ static Scsi_Host_Template k2_sata_sht = {
};
-static struct ata_port_operations k2_sata_ops = {
+static const struct ata_port_operations k2_sata_ops = {
.port_disable = ata_port_disable,
.tf_load = k2_sata_tf_load,
.tf_read = k2_sata_tf_read,
@@ -352,7 +362,7 @@ static int k2_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *e
int i;
if (!printed_version++)
- printk(KERN_DEBUG DRV_NAME " version " DRV_VERSION "\n");
+ dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
/*
* If this driver happens to only be useful on Apple's K2, then
diff --git a/drivers/scsi/sata_sx4.c b/drivers/scsi/sata_sx4.c
index 540a85191172..d5a38784352b 100644
--- a/drivers/scsi/sata_sx4.c
+++ b/drivers/scsi/sata_sx4.c
@@ -38,8 +38,9 @@
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/sched.h>
-#include "scsi.h"
+#include <linux/device.h>
#include <scsi/scsi_host.h>
+#include <scsi/scsi_cmnd.h>
#include <linux/libata.h>
#include <asm/io.h>
#include "sata_promise.h"
@@ -137,7 +138,7 @@ struct pdc_port_priv {
};
struct pdc_host_priv {
- void *dimm_mmio;
+ void __iomem *dimm_mmio;
unsigned int doing_hdma;
unsigned int hdma_prod;
@@ -157,8 +158,8 @@ static void pdc_20621_phy_reset (struct ata_port *ap);
static int pdc_port_start(struct ata_port *ap);
static void pdc_port_stop(struct ata_port *ap);
static void pdc20621_qc_prep(struct ata_queued_cmd *qc);
-static void pdc_tf_load_mmio(struct ata_port *ap, struct ata_taskfile *tf);
-static void pdc_exec_command_mmio(struct ata_port *ap, struct ata_taskfile *tf);
+static void pdc_tf_load_mmio(struct ata_port *ap, const struct ata_taskfile *tf);
+static void pdc_exec_command_mmio(struct ata_port *ap, const struct ata_taskfile *tf);
static void pdc20621_host_stop(struct ata_host_set *host_set);
static unsigned int pdc20621_dimm_init(struct ata_probe_ent *pe);
static int pdc20621_detect_dimm(struct ata_probe_ent *pe);
@@ -176,7 +177,7 @@ static void pdc20621_irq_clear(struct ata_port *ap);
static int pdc20621_qc_issue_prot(struct ata_queued_cmd *qc);
-static Scsi_Host_Template pdc_sata_sht = {
+static struct scsi_host_template pdc_sata_sht = {
.module = THIS_MODULE,
.name = DRV_NAME,
.ioctl = ata_scsi_ioctl,
@@ -196,7 +197,7 @@ static Scsi_Host_Template pdc_sata_sht = {
.ordered_flush = 1,
};
-static struct ata_port_operations pdc_20621_ops = {
+static const struct ata_port_operations pdc_20621_ops = {
.port_disable = ata_port_disable,
.tf_load = pdc_tf_load_mmio,
.tf_read = ata_tf_read,
@@ -247,7 +248,7 @@ static void pdc20621_host_stop(struct ata_host_set *host_set)
{
struct pci_dev *pdev = to_pci_dev(host_set->dev);
struct pdc_host_priv *hpriv = host_set->private_data;
- void *dimm_mmio = hpriv->dimm_mmio;
+ void __iomem *dimm_mmio = hpriv->dimm_mmio;
pci_iounmap(pdev, dimm_mmio);
kfree(hpriv);
@@ -449,14 +450,14 @@ static inline void pdc20621_host_pkt(struct ata_taskfile *tf, u8 *buf,
static void pdc20621_dma_prep(struct ata_queued_cmd *qc)
{
- struct scatterlist *sg = qc->sg;
+ struct scatterlist *sg;
struct ata_port *ap = qc->ap;
struct pdc_port_priv *pp = ap->private_data;
void __iomem *mmio = ap->host_set->mmio_base;
struct pdc_host_priv *hpriv = ap->host_set->private_data;
void __iomem *dimm_mmio = hpriv->dimm_mmio;
unsigned int portno = ap->port_no;
- unsigned int i, last, idx, total_len = 0, sgt_len;
+ unsigned int i, idx, total_len = 0, sgt_len;
u32 *buf = (u32 *) &pp->dimm_buf[PDC_DIMM_HEADER_SZ];
assert(qc->flags & ATA_QCFLAG_DMAMAP);
@@ -469,12 +470,11 @@ static void pdc20621_dma_prep(struct ata_queued_cmd *qc)
/*
* Build S/G table
*/
- last = qc->n_elem;
idx = 0;
- for (i = 0; i < last; i++) {
- buf[idx++] = cpu_to_le32(sg_dma_address(&sg[i]));
- buf[idx++] = cpu_to_le32(sg_dma_len(&sg[i]));
- total_len += sg_dma_len(&sg[i]);
+ ata_for_each_sg(sg, qc) {
+ buf[idx++] = cpu_to_le32(sg_dma_address(sg));
+ buf[idx++] = cpu_to_le32(sg_dma_len(sg));
+ total_len += sg_dma_len(sg);
}
buf[idx - 1] |= cpu_to_le32(ATA_PRD_EOT);
sgt_len = idx * 4;
@@ -669,8 +669,8 @@ static void pdc20621_packet_start(struct ata_queued_cmd *qc)
readl(mmio + PDC_20621_SEQCTL + (seq * 4)); /* flush */
writel(port_ofs + PDC_DIMM_ATA_PKT,
- (void *) ap->ioaddr.cmd_addr + PDC_PKT_SUBMIT);
- readl((void *) ap->ioaddr.cmd_addr + PDC_PKT_SUBMIT);
+ (void __iomem *) ap->ioaddr.cmd_addr + PDC_PKT_SUBMIT);
+ readl((void __iomem *) ap->ioaddr.cmd_addr + PDC_PKT_SUBMIT);
VPRINTK("submitted ofs 0x%x (%u), seq %u\n",
port_ofs + PDC_DIMM_ATA_PKT,
port_ofs + PDC_DIMM_ATA_PKT,
@@ -718,7 +718,7 @@ static inline unsigned int pdc20621_host_intr( struct ata_port *ap,
VPRINTK("ata%u: read hdma, 0x%x 0x%x\n", ap->id,
readl(mmio + 0x104), readl(mmio + PDC_HDMA_CTLSTAT));
/* get drive status; clear intr; complete txn */
- ata_qc_complete(qc, ata_wait_idle(ap));
+ ata_qc_complete(qc, ac_err_mask(ata_wait_idle(ap)));
pdc20621_pop_hdma(qc);
}
@@ -747,8 +747,8 @@ static inline unsigned int pdc20621_host_intr( struct ata_port *ap,
writel(0x00000001, mmio + PDC_20621_SEQCTL + (seq * 4));
readl(mmio + PDC_20621_SEQCTL + (seq * 4));
writel(port_ofs + PDC_DIMM_ATA_PKT,
- (void *) ap->ioaddr.cmd_addr + PDC_PKT_SUBMIT);
- readl((void *) ap->ioaddr.cmd_addr + PDC_PKT_SUBMIT);
+ (void __iomem *) ap->ioaddr.cmd_addr + PDC_PKT_SUBMIT);
+ readl((void __iomem *) ap->ioaddr.cmd_addr + PDC_PKT_SUBMIT);
}
/* step two - execute ATA command */
@@ -756,7 +756,7 @@ static inline unsigned int pdc20621_host_intr( struct ata_port *ap,
VPRINTK("ata%u: write ata, 0x%x 0x%x\n", ap->id,
readl(mmio + 0x104), readl(mmio + PDC_HDMA_CTLSTAT));
/* get drive status; clear intr; complete txn */
- ata_qc_complete(qc, ata_wait_idle(ap));
+ ata_qc_complete(qc, ac_err_mask(ata_wait_idle(ap)));
pdc20621_pop_hdma(qc);
}
handled = 1;
@@ -766,7 +766,7 @@ static inline unsigned int pdc20621_host_intr( struct ata_port *ap,
status = ata_busy_wait(ap, ATA_BUSY | ATA_DRQ, 1000);
DPRINTK("BUS_NODATA (drv_stat 0x%X)\n", status);
- ata_qc_complete(qc, status);
+ ata_qc_complete(qc, ac_err_mask(status));
handled = 1;
} else {
@@ -881,7 +881,7 @@ static void pdc_eng_timeout(struct ata_port *ap)
case ATA_PROT_DMA:
case ATA_PROT_NODATA:
printk(KERN_ERR "ata%u: command timeout\n", ap->id);
- ata_qc_complete(qc, ata_wait_idle(ap) | ATA_ERR);
+ ata_qc_complete(qc, __ac_err_mask(ata_wait_idle(ap)));
break;
default:
@@ -890,7 +890,7 @@ static void pdc_eng_timeout(struct ata_port *ap)
printk(KERN_ERR "ata%u: unknown timeout, cmd 0x%x stat 0x%x\n",
ap->id, qc->tf.command, drv_stat);
- ata_qc_complete(qc, drv_stat);
+ ata_qc_complete(qc, ac_err_mask(drv_stat));
break;
}
@@ -899,7 +899,7 @@ out:
DPRINTK("EXIT\n");
}
-static void pdc_tf_load_mmio(struct ata_port *ap, struct ata_taskfile *tf)
+static void pdc_tf_load_mmio(struct ata_port *ap, const struct ata_taskfile *tf)
{
WARN_ON (tf->protocol == ATA_PROT_DMA ||
tf->protocol == ATA_PROT_NODATA);
@@ -907,7 +907,7 @@ static void pdc_tf_load_mmio(struct ata_port *ap, struct ata_taskfile *tf)
}
-static void pdc_exec_command_mmio(struct ata_port *ap, struct ata_taskfile *tf)
+static void pdc_exec_command_mmio(struct ata_port *ap, const struct ata_taskfile *tf)
{
WARN_ON (tf->protocol == ATA_PROT_DMA ||
tf->protocol == ATA_PROT_NODATA);
@@ -1014,7 +1014,7 @@ static void pdc20621_put_to_dimm(struct ata_probe_ent *pe, void *psource,
idx++;
dist = ((long)(s32)(window_size - (offset + size))) >= 0 ? size :
(long) (window_size - offset);
- memcpy_toio((char *) (dimm_mmio + offset / 4), (char *) psource, dist);
+ memcpy_toio(dimm_mmio + offset / 4, psource, dist);
writel(0x01, mmio + PDC_GENERAL_CTLR);
readl(mmio + PDC_GENERAL_CTLR);
@@ -1023,8 +1023,7 @@ static void pdc20621_put_to_dimm(struct ata_probe_ent *pe, void *psource,
for (; (long) size >= (long) window_size ;) {
writel(((idx) << page_mask), mmio + PDC_DIMM_WINDOW_CTLR);
readl(mmio + PDC_DIMM_WINDOW_CTLR);
- memcpy_toio((char *) (dimm_mmio), (char *) psource,
- window_size / 4);
+ memcpy_toio(dimm_mmio, psource, window_size / 4);
writel(0x01, mmio + PDC_GENERAL_CTLR);
readl(mmio + PDC_GENERAL_CTLR);
psource += window_size;
@@ -1035,7 +1034,7 @@ static void pdc20621_put_to_dimm(struct ata_probe_ent *pe, void *psource,
if (size) {
writel(((idx) << page_mask), mmio + PDC_DIMM_WINDOW_CTLR);
readl(mmio + PDC_DIMM_WINDOW_CTLR);
- memcpy_toio((char *) (dimm_mmio), (char *) psource, size / 4);
+ memcpy_toio(dimm_mmio, psource, size / 4);
writel(0x01, mmio + PDC_GENERAL_CTLR);
readl(mmio + PDC_GENERAL_CTLR);
}
@@ -1386,7 +1385,7 @@ static int pdc_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *
int rc;
if (!printed_version++)
- printk(KERN_DEBUG DRV_NAME " version " DRV_VERSION "\n");
+ dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
/*
* If this driver happens to only be useful on Apple's K2, then
diff --git a/drivers/scsi/sata_uli.c b/drivers/scsi/sata_uli.c
index 4c9fb8b71be1..cf0baaa4e045 100644
--- a/drivers/scsi/sata_uli.c
+++ b/drivers/scsi/sata_uli.c
@@ -32,7 +32,7 @@
#include <linux/blkdev.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
-#include "scsi.h"
+#include <linux/device.h>
#include <scsi/scsi_host.h>
#include <linux/libata.h>
@@ -70,7 +70,7 @@ static struct pci_driver uli_pci_driver = {
.remove = ata_pci_remove_one,
};
-static Scsi_Host_Template uli_sht = {
+static struct scsi_host_template uli_sht = {
.module = THIS_MODULE,
.name = DRV_NAME,
.ioctl = ata_scsi_ioctl,
@@ -90,7 +90,7 @@ static Scsi_Host_Template uli_sht = {
.ordered_flush = 1,
};
-static struct ata_port_operations uli_ops = {
+static const struct ata_port_operations uli_ops = {
.port_disable = ata_port_disable,
.tf_load = ata_tf_load,
@@ -178,12 +178,16 @@ static void uli_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val)
static int uli_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
{
+ static int printed_version;
struct ata_probe_ent *probe_ent;
struct ata_port_info *ppi;
int rc;
unsigned int board_idx = (unsigned int) ent->driver_data;
int pci_dev_busy = 0;
+ if (!printed_version++)
+ dev_printk(KERN_INFO, &pdev->dev, "version " DRV_VERSION "\n");
+
rc = pci_enable_device(pdev);
if (rc)
return rc;
@@ -202,7 +206,7 @@ static int uli_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
goto err_out_regions;
ppi = &uli_port_info;
- probe_ent = ata_pci_init_native_mode(pdev, &ppi);
+ probe_ent = ata_pci_init_native_mode(pdev, &ppi, ATA_PORT_PRIMARY | ATA_PORT_SECONDARY);
if (!probe_ent) {
rc = -ENOMEM;
goto err_out_regions;
diff --git a/drivers/scsi/sata_via.c b/drivers/scsi/sata_via.c
index 128b996b07b7..ab19d2ba2a4b 100644
--- a/drivers/scsi/sata_via.c
+++ b/drivers/scsi/sata_via.c
@@ -41,7 +41,7 @@
#include <linux/init.h>
#include <linux/blkdev.h>
#include <linux/delay.h>
-#include "scsi.h"
+#include <linux/device.h>
#include <scsi/scsi_host.h>
#include <linux/libata.h>
#include <asm/io.h>
@@ -89,7 +89,7 @@ static struct pci_driver svia_pci_driver = {
.remove = ata_pci_remove_one,
};
-static Scsi_Host_Template svia_sht = {
+static struct scsi_host_template svia_sht = {
.module = THIS_MODULE,
.name = DRV_NAME,
.ioctl = ata_scsi_ioctl,
@@ -109,7 +109,7 @@ static Scsi_Host_Template svia_sht = {
.ordered_flush = 1,
};
-static struct ata_port_operations svia_sata_ops = {
+static const struct ata_port_operations svia_sata_ops = {
.port_disable = ata_port_disable,
.tf_load = ata_tf_load,
@@ -212,7 +212,7 @@ static struct ata_probe_ent *vt6420_init_probe_ent(struct pci_dev *pdev)
struct ata_probe_ent *probe_ent;
struct ata_port_info *ppi = &svia_port_info;
- probe_ent = ata_pci_init_native_mode(pdev, &ppi);
+ probe_ent = ata_pci_init_native_mode(pdev, &ppi, ATA_PORT_PRIMARY | ATA_PORT_SECONDARY);
if (!probe_ent)
return NULL;
@@ -259,15 +259,15 @@ static void svia_configure(struct pci_dev *pdev)
u8 tmp8;
pci_read_config_byte(pdev, PCI_INTERRUPT_LINE, &tmp8);
- printk(KERN_INFO DRV_NAME "(%s): routed to hard irq line %d\n",
- pci_name(pdev),
+ dev_printk(KERN_INFO, &pdev->dev, "routed to hard irq line %d\n",
(int) (tmp8 & 0xf0) == 0xf0 ? 0 : tmp8 & 0x0f);
/* make sure SATA channels are enabled */
pci_read_config_byte(pdev, SATA_CHAN_ENAB, &tmp8);
if ((tmp8 & ALL_PORTS) != ALL_PORTS) {
- printk(KERN_DEBUG DRV_NAME "(%s): enabling SATA channels (0x%x)\n",
- pci_name(pdev), (int) tmp8);
+ dev_printk(KERN_DEBUG, &pdev->dev,
+ "enabling SATA channels (0x%x)\n",
+ (int) tmp8);
tmp8 |= ALL_PORTS;
pci_write_config_byte(pdev, SATA_CHAN_ENAB, tmp8);
}
@@ -275,8 +275,9 @@ static void svia_configure(struct pci_dev *pdev)
/* make sure interrupts for each channel sent to us */
pci_read_config_byte(pdev, SATA_INT_GATE, &tmp8);
if ((tmp8 & ALL_PORTS) != ALL_PORTS) {
- printk(KERN_DEBUG DRV_NAME "(%s): enabling SATA channel interrupts (0x%x)\n",
- pci_name(pdev), (int) tmp8);
+ dev_printk(KERN_DEBUG, &pdev->dev,
+ "enabling SATA channel interrupts (0x%x)\n",
+ (int) tmp8);
tmp8 |= ALL_PORTS;
pci_write_config_byte(pdev, SATA_INT_GATE, tmp8);
}
@@ -284,8 +285,9 @@ static void svia_configure(struct pci_dev *pdev)
/* make sure native mode is enabled */
pci_read_config_byte(pdev, SATA_NATIVE_MODE, &tmp8);
if ((tmp8 & NATIVE_MODE_ALL) != NATIVE_MODE_ALL) {
- printk(KERN_DEBUG DRV_NAME "(%s): enabling SATA channel native mode (0x%x)\n",
- pci_name(pdev), (int) tmp8);
+ dev_printk(KERN_DEBUG, &pdev->dev,
+ "enabling SATA channel native mode (0x%x)\n",
+ (int) tmp8);
tmp8 |= NATIVE_MODE_ALL;
pci_write_config_byte(pdev, SATA_NATIVE_MODE, tmp8);
}
@@ -303,7 +305,7 @@ static int svia_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
u8 tmp8;
if (!printed_version++)
- printk(KERN_DEBUG DRV_NAME " version " DRV_VERSION "\n");
+ dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
rc = pci_enable_device(pdev);
if (rc)
@@ -318,8 +320,9 @@ static int svia_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
if (board_id == vt6420) {
pci_read_config_byte(pdev, SATA_PATA_SHARING, &tmp8);
if (tmp8 & SATA_2DEV) {
- printk(KERN_ERR DRV_NAME "(%s): SATA master/slave not supported (0x%x)\n",
- pci_name(pdev), (int) tmp8);
+ dev_printk(KERN_ERR, &pdev->dev,
+ "SATA master/slave not supported (0x%x)\n",
+ (int) tmp8);
rc = -EIO;
goto err_out_regions;
}
@@ -332,10 +335,11 @@ static int svia_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
for (i = 0; i < ARRAY_SIZE(svia_bar_sizes); i++)
if ((pci_resource_start(pdev, i) == 0) ||
(pci_resource_len(pdev, i) < bar_sizes[i])) {
- printk(KERN_ERR DRV_NAME "(%s): invalid PCI BAR %u (sz 0x%lx, val 0x%lx)\n",
- pci_name(pdev), i,
- pci_resource_start(pdev, i),
- pci_resource_len(pdev, i));
+ dev_printk(KERN_ERR, &pdev->dev,
+ "invalid PCI BAR %u (sz 0x%lx, val 0x%lx)\n",
+ i,
+ pci_resource_start(pdev, i),
+ pci_resource_len(pdev, i));
rc = -ENODEV;
goto err_out_regions;
}
@@ -353,8 +357,7 @@ static int svia_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
probe_ent = vt6421_init_probe_ent(pdev);
if (!probe_ent) {
- printk(KERN_ERR DRV_NAME "(%s): out of memory\n",
- pci_name(pdev));
+ dev_printk(KERN_ERR, &pdev->dev, "out of memory\n");
rc = -ENOMEM;
goto err_out_regions;
}
diff --git a/drivers/scsi/sata_vsc.c b/drivers/scsi/sata_vsc.c
index cf94e0158a8d..ce8a2fd7da84 100644
--- a/drivers/scsi/sata_vsc.c
+++ b/drivers/scsi/sata_vsc.c
@@ -42,7 +42,7 @@
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/dma-mapping.h>
-#include "scsi.h"
+#include <linux/device.h>
#include <scsi/scsi_host.h>
#include <linux/libata.h>
@@ -86,7 +86,7 @@ static u32 vsc_sata_scr_read (struct ata_port *ap, unsigned int sc_reg)
{
if (sc_reg > SCR_CONTROL)
return 0xffffffffU;
- return readl((void *) ap->ioaddr.scr_addr + (sc_reg * 4));
+ return readl((void __iomem *) ap->ioaddr.scr_addr + (sc_reg * 4));
}
@@ -95,16 +95,16 @@ static void vsc_sata_scr_write (struct ata_port *ap, unsigned int sc_reg,
{
if (sc_reg > SCR_CONTROL)
return;
- writel(val, (void *) ap->ioaddr.scr_addr + (sc_reg * 4));
+ writel(val, (void __iomem *) ap->ioaddr.scr_addr + (sc_reg * 4));
}
static void vsc_intr_mask_update(struct ata_port *ap, u8 ctl)
{
- unsigned long mask_addr;
+ void __iomem *mask_addr;
u8 mask;
- mask_addr = (unsigned long) ap->host_set->mmio_base +
+ mask_addr = ap->host_set->mmio_base +
VSC_SATA_INT_MASK_OFFSET + ap->port_no;
mask = readb(mask_addr);
if (ctl & ATA_NIEN)
@@ -115,7 +115,7 @@ static void vsc_intr_mask_update(struct ata_port *ap, u8 ctl)
}
-static void vsc_sata_tf_load(struct ata_port *ap, struct ata_taskfile *tf)
+static void vsc_sata_tf_load(struct ata_port *ap, const struct ata_taskfile *tf)
{
struct ata_ioports *ioaddr = &ap->ioaddr;
unsigned int is_addr = tf->flags & ATA_TFLAG_ISADDR;
@@ -153,16 +153,24 @@ static void vsc_sata_tf_load(struct ata_port *ap, struct ata_taskfile *tf)
static void vsc_sata_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
{
struct ata_ioports *ioaddr = &ap->ioaddr;
- u16 nsect, lbal, lbam, lbah;
+ u16 nsect, lbal, lbam, lbah, feature;
- nsect = tf->nsect = readw(ioaddr->nsect_addr);
- lbal = tf->lbal = readw(ioaddr->lbal_addr);
- lbam = tf->lbam = readw(ioaddr->lbam_addr);
- lbah = tf->lbah = readw(ioaddr->lbah_addr);
+ tf->command = ata_check_status(ap);
tf->device = readw(ioaddr->device_addr);
+ feature = readw(ioaddr->error_addr);
+ nsect = readw(ioaddr->nsect_addr);
+ lbal = readw(ioaddr->lbal_addr);
+ lbam = readw(ioaddr->lbam_addr);
+ lbah = readw(ioaddr->lbah_addr);
+
+ tf->feature = feature;
+ tf->nsect = nsect;
+ tf->lbal = lbal;
+ tf->lbam = lbam;
+ tf->lbah = lbah;
if (tf->flags & ATA_TFLAG_LBA48) {
- tf->hob_feature = readb(ioaddr->error_addr);
+ tf->hob_feature = feature >> 8;
tf->hob_nsect = nsect >> 8;
tf->hob_lbal = lbal >> 8;
tf->hob_lbam = lbam >> 8;
@@ -210,7 +218,7 @@ static irqreturn_t vsc_sata_interrupt (int irq, void *dev_instance,
}
-static Scsi_Host_Template vsc_sata_sht = {
+static struct scsi_host_template vsc_sata_sht = {
.module = THIS_MODULE,
.name = DRV_NAME,
.ioctl = ata_scsi_ioctl,
@@ -231,7 +239,7 @@ static Scsi_Host_Template vsc_sata_sht = {
};
-static struct ata_port_operations vsc_sata_ops = {
+static const struct ata_port_operations vsc_sata_ops = {
.port_disable = ata_port_disable,
.tf_load = vsc_sata_tf_load,
.tf_read = vsc_sata_tf_read,
@@ -283,11 +291,11 @@ static int __devinit vsc_sata_init_one (struct pci_dev *pdev, const struct pci_d
struct ata_probe_ent *probe_ent = NULL;
unsigned long base;
int pci_dev_busy = 0;
- void *mmio_base;
+ void __iomem *mmio_base;
int rc;
if (!printed_version++)
- printk(KERN_DEBUG DRV_NAME " version " DRV_VERSION "\n");
+ dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
rc = pci_enable_device(pdev);
if (rc)
diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c
index 1f0ebabf6d47..0be60bba58d3 100644
--- a/drivers/scsi/scsi.c
+++ b/drivers/scsi/scsi.c
@@ -130,7 +130,7 @@ EXPORT_SYMBOL(scsi_device_types);
* Returns: Pointer to request block.
*/
struct scsi_request *scsi_allocate_request(struct scsi_device *sdev,
- int gfp_mask)
+ gfp_t gfp_mask)
{
const int offset = ALIGN(sizeof(struct scsi_request), 4);
const int size = offset + sizeof(struct request);
@@ -196,7 +196,7 @@ struct scsi_host_cmd_pool {
unsigned int users;
char *name;
unsigned int slab_flags;
- unsigned int gfp_mask;
+ gfp_t gfp_mask;
};
static struct scsi_host_cmd_pool scsi_cmd_pool = {
@@ -213,7 +213,7 @@ static struct scsi_host_cmd_pool scsi_cmd_dma_pool = {
static DECLARE_MUTEX(host_cmd_pool_mutex);
static struct scsi_cmnd *__scsi_get_command(struct Scsi_Host *shost,
- int gfp_mask)
+ gfp_t gfp_mask)
{
struct scsi_cmnd *cmd;
@@ -245,7 +245,7 @@ static struct scsi_cmnd *__scsi_get_command(struct Scsi_Host *shost,
*
* Returns: The allocated scsi command structure.
*/
-struct scsi_cmnd *scsi_get_command(struct scsi_device *dev, int gfp_mask)
+struct scsi_cmnd *scsi_get_command(struct scsi_device *dev, gfp_t gfp_mask)
{
struct scsi_cmnd *cmd;
@@ -410,9 +410,7 @@ void scsi_log_send(struct scsi_cmnd *cmd)
SCSI_LOG_MLQUEUE_BITS);
if (level > 1) {
sdev = cmd->device;
- printk(KERN_INFO "scsi <%d:%d:%d:%d> send ",
- sdev->host->host_no, sdev->channel, sdev->id,
- sdev->lun);
+ sdev_printk(KERN_INFO, sdev, "send ");
if (level > 2)
printk("0x%p ", cmd);
/*
@@ -456,9 +454,7 @@ void scsi_log_completion(struct scsi_cmnd *cmd, int disposition)
if (((level > 0) && (cmd->result || disposition != SUCCESS)) ||
(level > 1)) {
sdev = cmd->device;
- printk(KERN_INFO "scsi <%d:%d:%d:%d> done ",
- sdev->host->host_no, sdev->channel, sdev->id,
- sdev->lun);
+ sdev_printk(KERN_INFO, sdev, "done ");
if (level > 2)
printk("0x%p ", cmd);
/*
@@ -810,9 +806,9 @@ static void scsi_softirq(struct softirq_action *h)
disposition = scsi_decide_disposition(cmd);
if (disposition != SUCCESS &&
time_before(cmd->jiffies_at_alloc + wait_for, jiffies)) {
- dev_printk(KERN_ERR, &cmd->device->sdev_gendev,
- "timing out command, waited %lus\n",
- wait_for/HZ);
+ sdev_printk(KERN_ERR, cmd->device,
+ "timing out command, waited %lus\n",
+ wait_for/HZ);
disposition = SUCCESS;
}
@@ -893,8 +889,9 @@ void scsi_finish_command(struct scsi_cmnd *cmd)
if (SCSI_SENSE_VALID(cmd))
cmd->result |= (DRIVER_SENSE << 24);
- SCSI_LOG_MLCOMPLETE(4, printk("Notifying upper driver of completion "
- "for device %d %x\n", sdev->id, cmd->result));
+ SCSI_LOG_MLCOMPLETE(4, sdev_printk(KERN_INFO, sdev,
+ "Notifying upper driver of completion "
+ "(result %x)\n", cmd->result));
/*
* We can get here with use_sg=0, causing a panic in the upper level
@@ -970,10 +967,9 @@ void scsi_adjust_queue_depth(struct scsi_device *sdev, int tagged, int tags)
sdev->simple_tags = 1;
break;
default:
- printk(KERN_WARNING "(scsi%d:%d:%d:%d) "
- "scsi_adjust_queue_depth, bad queue type, "
- "disabled\n", sdev->host->host_no,
- sdev->channel, sdev->id, sdev->lun);
+ sdev_printk(KERN_WARNING, sdev,
+ "scsi_adjust_queue_depth, bad queue type, "
+ "disabled\n");
case 0:
sdev->ordered_tags = sdev->simple_tags = 0;
sdev->queue_depth = tags;
diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
index 322b5a41a36f..b61fb1295b8b 100644
--- a/drivers/scsi/scsi_debug.c
+++ b/drivers/scsi/scsi_debug.c
@@ -48,10 +48,6 @@
#include <linux/stat.h>
-#ifndef LINUX_VERSION_CODE
-#include <linux/version.h>
-#endif
-
#include "scsi_logging.h"
#include "scsi_debug.h"
@@ -283,7 +279,7 @@ int scsi_debug_queuecommand(struct scsi_cmnd * SCpnt, done_funct_t done)
unsigned char *cmd = (unsigned char *) SCpnt->cmnd;
int block, upper_blk, num, k;
int errsts = 0;
- int target = SCpnt->device->id;
+ int target = scmd_id(SCpnt);
struct sdebug_dev_info * devip = NULL;
int inj_recovered = 0;
@@ -1008,8 +1004,7 @@ static void timer_intr_handler(unsigned long indx)
static int scsi_debug_slave_alloc(struct scsi_device * sdp)
{
if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)
- printk(KERN_INFO "scsi_debug: slave_alloc <%u %u %u %u>\n",
- sdp->host->host_no, sdp->channel, sdp->id, sdp->lun);
+ sdev_printk(KERN_INFO, sdp, "scsi_debug: slave_alloc\n");
return 0;
}
@@ -1018,8 +1013,7 @@ static int scsi_debug_slave_configure(struct scsi_device * sdp)
struct sdebug_dev_info * devip;
if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)
- printk(KERN_INFO "scsi_debug: slave_configure <%u %u %u %u>\n",
- sdp->host->host_no, sdp->channel, sdp->id, sdp->lun);
+ sdev_printk(KERN_INFO, sdp, "scsi_debug: slave_configure\n");
if (sdp->host->max_cmd_len != SCSI_DEBUG_MAX_CMD_LEN)
sdp->host->max_cmd_len = SCSI_DEBUG_MAX_CMD_LEN;
devip = devInfoReg(sdp);
@@ -1036,8 +1030,7 @@ static void scsi_debug_slave_destroy(struct scsi_device * sdp)
(struct sdebug_dev_info *)sdp->hostdata;
if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)
- printk(KERN_INFO "scsi_debug: slave_destroy <%u %u %u %u>\n",
- sdp->host->host_no, sdp->channel, sdp->id, sdp->lun);
+ sdev_printk(KERN_INFO, sdp, "scsi_debug: slave_destroy\n");
if (devip) {
/* make this slot avaliable for re-use */
devip->used = 0;
@@ -1326,9 +1319,9 @@ static int schedule_resp(struct scsi_cmnd * cmnd,
if (scsi_result) {
struct scsi_device * sdp = cmnd->device;
- printk(KERN_INFO "scsi_debug: <%u %u %u %u> "
- "non-zero result=0x%x\n", sdp->host->host_no,
- sdp->channel, sdp->id, sdp->lun, scsi_result);
+ sdev_printk(KERN_INFO, sdp,
+ "non-zero result=0x%x\n",
+ scsi_result);
}
}
if (cmnd && devip) {
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
index 52b348c36d56..0c5b02d4c7f8 100644
--- a/drivers/scsi/scsi_error.c
+++ b/drivers/scsi/scsi_error.c
@@ -241,11 +241,10 @@ static inline void scsi_eh_prt_fail_stats(struct Scsi_Host *shost,
if (cmd_cancel || cmd_failed) {
SCSI_LOG_ERROR_RECOVERY(3,
- printk("%s: %d:%d:%d:%d cmds failed: %d,"
- " cancel: %d\n",
- __FUNCTION__, shost->host_no,
- sdev->channel, sdev->id, sdev->lun,
- cmd_failed, cmd_cancel));
+ sdev_printk(KERN_INFO, sdev,
+ "%s: cmds failed: %d, cancel: %d\n",
+ __FUNCTION__, cmd_failed,
+ cmd_cancel));
cmd_cancel = 0;
cmd_failed = 0;
++devices_failed;
@@ -674,10 +673,9 @@ static int scsi_eh_get_sense(struct list_head *work_q,
SCSI_SENSE_VALID(scmd))
continue;
- SCSI_LOG_ERROR_RECOVERY(2, printk("%s: requesting sense"
- " for id: %d\n",
- current->comm,
- scmd->device->id));
+ SCSI_LOG_ERROR_RECOVERY(2, scmd_printk(KERN_INFO, scmd,
+ "%s: requesting sense\n",
+ current->comm));
rtn = scsi_request_sense(scmd);
if (rtn != SUCCESS)
continue;
@@ -1035,7 +1033,8 @@ static int scsi_try_bus_reset(struct scsi_cmnd *scmd)
if (!scmd->device->host->hostt->skip_settle_delay)
ssleep(BUS_RESET_SETTLE_TIME);
spin_lock_irqsave(scmd->device->host->host_lock, flags);
- scsi_report_bus_reset(scmd->device->host, scmd->device->channel);
+ scsi_report_bus_reset(scmd->device->host,
+ scmd_channel(scmd));
spin_unlock_irqrestore(scmd->device->host->host_lock, flags);
}
@@ -1063,7 +1062,8 @@ static int scsi_try_host_reset(struct scsi_cmnd *scmd)
if (!scmd->device->host->hostt->skip_settle_delay)
ssleep(HOST_RESET_SETTLE_TIME);
spin_lock_irqsave(scmd->device->host->host_lock, flags);
- scsi_report_bus_reset(scmd->device->host, scmd->device->channel);
+ scsi_report_bus_reset(scmd->device->host,
+ scmd_channel(scmd));
spin_unlock_irqrestore(scmd->device->host->host_lock, flags);
}
@@ -1093,7 +1093,7 @@ static int scsi_eh_bus_reset(struct Scsi_Host *shost,
for (channel = 0; channel <= shost->max_channel; channel++) {
chan_scmd = NULL;
list_for_each_entry(scmd, work_q, eh_entry) {
- if (channel == scmd->device->channel) {
+ if (channel == scmd_channel(scmd)) {
chan_scmd = scmd;
break;
/*
@@ -1111,7 +1111,7 @@ static int scsi_eh_bus_reset(struct Scsi_Host *shost,
rtn = scsi_try_bus_reset(chan_scmd);
if (rtn == SUCCESS) {
list_for_each_entry_safe(scmd, next, work_q, eh_entry) {
- if (channel == scmd->device->channel)
+ if (channel == scmd_channel(scmd))
if (!scsi_device_online(scmd->device) ||
!scsi_eh_tur(scmd))
scsi_eh_finish_cmd(scmd,
@@ -1174,13 +1174,9 @@ static void scsi_eh_offline_sdevs(struct list_head *work_q,
struct scsi_cmnd *scmd, *next;
list_for_each_entry_safe(scmd, next, work_q, eh_entry) {
- printk(KERN_INFO "scsi: Device offlined - not"
- " ready after error recovery: host"
- " %d channel %d id %d lun %d\n",
- scmd->device->host->host_no,
- scmd->device->channel,
- scmd->device->id,
- scmd->device->lun);
+ sdev_printk(KERN_INFO, scmd->device,
+ "scsi: Device offlined - not"
+ " ready after error recovery\n");
scsi_device_set_state(scmd->device, SDEV_OFFLINE);
if (scmd->eh_eflags & SCSI_EH_CANCEL_CMD) {
/*
@@ -1342,10 +1338,8 @@ int scsi_decide_disposition(struct scsi_cmnd *scmd)
return SUCCESS;
case RESERVATION_CONFLICT:
- printk(KERN_INFO "scsi: reservation conflict: host"
- " %d channel %d id %d lun %d\n",
- scmd->device->host->host_no, scmd->device->channel,
- scmd->device->id, scmd->device->lun);
+ sdev_printk(KERN_INFO, scmd->device,
+ "reservation conflict\n");
return SUCCESS; /* causes immediate i/o error */
default:
return FAILED;
@@ -1683,7 +1677,7 @@ void scsi_report_bus_reset(struct Scsi_Host *shost, int channel)
struct scsi_device *sdev;
__shost_for_each_device(sdev, shost) {
- if (channel == sdev->channel) {
+ if (channel == sdev_channel(sdev)) {
sdev->was_reset = 1;
sdev->expecting_cc_ua = 1;
}
@@ -1718,8 +1712,8 @@ void scsi_report_device_reset(struct Scsi_Host *shost, int channel, int target)
struct scsi_device *sdev;
__shost_for_each_device(sdev, shost) {
- if (channel == sdev->channel &&
- target == sdev->id) {
+ if (channel == sdev_channel(sdev) &&
+ target == sdev_id(sdev)) {
sdev->was_reset = 1;
sdev->expecting_cc_ua = 1;
}
diff --git a/drivers/scsi/scsi_ioctl.c b/drivers/scsi/scsi_ioctl.c
index de7f98cc38fe..0bba7d8eebb0 100644
--- a/drivers/scsi/scsi_ioctl.c
+++ b/drivers/scsi/scsi_ioctl.c
@@ -122,13 +122,9 @@ static int ioctl_internal_command(struct scsi_device *sdev, char *cmd,
break;
}
default: /* Fall through for non-removable media */
- printk(KERN_INFO "ioctl_internal_command: <%d %d %d "
- "%d> return code = %x\n",
- sdev->host->host_no,
- sdev->channel,
- sdev->id,
- sdev->lun,
- result);
+ sdev_printk(KERN_INFO, sdev,
+ "ioctl_internal_command return code = %x\n",
+ result);
scsi_print_sense_hdr(" ", &sshdr);
break;
}
@@ -205,7 +201,8 @@ int scsi_ioctl_send_command(struct scsi_device *sdev,
unsigned int inlen, outlen, cmdlen;
unsigned int needed, buf_needed;
int timeout, retries, result;
- int data_direction, gfp_mask = GFP_KERNEL;
+ int data_direction;
+ gfp_t gfp_mask = GFP_KERNEL;
if (!sic)
return -EINVAL;
@@ -281,7 +278,7 @@ int scsi_ioctl_send_command(struct scsi_device *sdev,
* Obtain the data to be sent to the device (if any).
*/
- if(copy_from_user(buf, cmd_in + cmdlen, inlen))
+ if(inlen && copy_from_user(buf, cmd_in + cmdlen, inlen))
goto error;
switch (opcode) {
@@ -325,7 +322,7 @@ int scsi_ioctl_send_command(struct scsi_device *sdev,
if (copy_to_user(cmd_in, sense, sb_len))
result = -EFAULT;
} else {
- if (copy_to_user(cmd_in, buf, outlen))
+ if (outlen && copy_to_user(cmd_in, buf, outlen))
result = -EFAULT;
}
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index 0074f28c37b2..e40c8b66da40 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -677,7 +677,7 @@ static struct scsi_cmnd *scsi_end_request(struct scsi_cmnd *cmd, int uptodate,
return NULL;
}
-static struct scatterlist *scsi_alloc_sgtable(struct scsi_cmnd *cmd, int gfp_mask)
+static struct scatterlist *scsi_alloc_sgtable(struct scsi_cmnd *cmd, gfp_t gfp_mask)
{
struct scsi_host_sg_pool *sgp;
struct scatterlist *sgl;
@@ -951,15 +951,13 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes,
return;
}
if (!(req->flags & REQ_QUIET))
- dev_printk(KERN_INFO,
- &cmd->device->sdev_gendev,
+ scmd_printk(KERN_INFO, cmd,
"Device not ready.\n");
scsi_end_request(cmd, 0, this_count, 1);
return;
case VOLUME_OVERFLOW:
if (!(req->flags & REQ_QUIET)) {
- dev_printk(KERN_INFO,
- &cmd->device->sdev_gendev,
+ scmd_printk(KERN_INFO, cmd,
"Volume overflow, CDB: ");
__scsi_print_command(cmd->data_cmnd);
scsi_print_sense("", cmd);
@@ -981,7 +979,7 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes,
}
if (result) {
if (!(req->flags & REQ_QUIET)) {
- dev_printk(KERN_INFO, &cmd->device->sdev_gendev,
+ scmd_printk(KERN_INFO, cmd,
"SCSI error: return code = 0x%x\n", result);
if (driver_byte(result) & DRIVER_SENSE)
@@ -1141,8 +1139,8 @@ static int scsi_prep_fn(struct request_queue *q, struct request *req)
* online before trying any recovery commands
*/
if (unlikely(!scsi_device_online(sdev))) {
- printk(KERN_ERR "scsi%d (%d:%d): rejecting I/O to offline device\n",
- sdev->host->host_no, sdev->id, sdev->lun);
+ sdev_printk(KERN_ERR, sdev,
+ "rejecting I/O to offline device\n");
goto kill;
}
if (unlikely(sdev->sdev_state != SDEV_RUNNING)) {
@@ -1151,8 +1149,8 @@ static int scsi_prep_fn(struct request_queue *q, struct request *req)
if (sdev->sdev_state == SDEV_DEL) {
/* Device is fully deleted, no commands
* at all allowed down */
- printk(KERN_ERR "scsi%d (%d:%d): rejecting I/O to dead device\n",
- sdev->host->host_no, sdev->id, sdev->lun);
+ sdev_printk(KERN_ERR, sdev,
+ "rejecting I/O to dead device\n");
goto kill;
}
/* OK, we only allow special commands (i.e. not
@@ -1187,8 +1185,8 @@ static int scsi_prep_fn(struct request_queue *q, struct request *req)
specials_only == SDEV_BLOCK)
goto defer;
- printk(KERN_ERR "scsi%d (%d:%d): rejecting I/O to device being removed\n",
- sdev->host->host_no, sdev->id, sdev->lun);
+ sdev_printk(KERN_ERR, sdev,
+ "rejecting I/O to device being removed\n");
goto kill;
}
@@ -1315,9 +1313,8 @@ static inline int scsi_dev_queue_ready(struct request_queue *q,
*/
if (--sdev->device_blocked == 0) {
SCSI_LOG_MLQUEUE(3,
- printk("scsi%d (%d:%d) unblocking device at"
- " zero depth\n", sdev->host->host_no,
- sdev->id, sdev->lun));
+ sdev_printk(KERN_INFO, sdev,
+ "unblocking device at zero depth\n"));
} else {
blk_plug_device(q);
return 0;
@@ -1436,8 +1433,8 @@ static void scsi_request_fn(struct request_queue *q)
break;
if (unlikely(!scsi_device_online(sdev))) {
- printk(KERN_ERR "scsi%d (%d:%d): rejecting I/O to offline device\n",
- sdev->host->host_no, sdev->id, sdev->lun);
+ sdev_printk(KERN_ERR, sdev,
+ "rejecting I/O to offline device\n");
scsi_kill_request(req, q);
continue;
}
@@ -1893,10 +1890,10 @@ scsi_device_set_state(struct scsi_device *sdev, enum scsi_device_state state)
illegal:
SCSI_LOG_ERROR_RECOVERY(1,
- dev_printk(KERN_ERR, &sdev->sdev_gendev,
- "Illegal state transition %s->%s\n",
- scsi_device_state_name(oldstate),
- scsi_device_state_name(state))
+ sdev_printk(KERN_ERR, sdev,
+ "Illegal state transition %s->%s\n",
+ scsi_device_state_name(oldstate),
+ scsi_device_state_name(state))
);
return -EINVAL;
}
diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c
index 327c5d7e5bd2..7eb3a2d40dc5 100644
--- a/drivers/scsi/scsi_scan.c
+++ b/drivers/scsi/scsi_scan.c
@@ -462,10 +462,9 @@ static int scsi_probe_lun(struct scsi_device *sdev, char *inq_result,
pass = 1;
next_pass:
- SCSI_LOG_SCAN_BUS(3, printk(KERN_INFO "scsi scan: INQUIRY pass %d "
- "to host %d channel %d id %d lun %d, length %d\n",
- pass, sdev->host->host_no, sdev->channel,
- sdev->id, sdev->lun, try_inquiry_len));
+ SCSI_LOG_SCAN_BUS(3, sdev_printk(KERN_INFO, sdev,
+ "scsi scan: INQUIRY pass %d length %d\n",
+ pass, try_inquiry_len));
/* Each pass gets up to three chances to ignore Unit Attention */
for (count = 0; count < 3; ++count) {
@@ -1190,9 +1189,8 @@ static int scsi_report_lun_scan(struct scsi_target *starget, int bflags,
num_luns = max_scsi_report_luns;
}
- SCSI_LOG_SCAN_BUS(3, printk (KERN_INFO "scsi scan: REPORT LUN scan of"
- " host %d channel %d id %d\n", sdev->host->host_no,
- sdev->channel, sdev->id));
+ SCSI_LOG_SCAN_BUS(3, sdev_printk (KERN_INFO, sdev,
+ "scsi scan: REPORT LUN scan\n"));
/*
* Scan the luns in lun_data. The entry at offset 0 is really
@@ -1231,9 +1229,10 @@ static int scsi_report_lun_scan(struct scsi_target *starget, int bflags,
/*
* Got some results, but now none, abort.
*/
- printk(KERN_ERR "scsi: Unexpected response"
- " from %s lun %d while scanning, scan"
- " aborted\n", devname, lun);
+ sdev_printk(KERN_ERR, sdev,
+ "Unexpected response"
+ " from lun %d while scanning, scan"
+ " aborted\n", lun);
break;
}
}
@@ -1418,8 +1417,9 @@ static void scsi_scan_channel(struct Scsi_Host *shost, unsigned int channel,
int scsi_scan_host_selected(struct Scsi_Host *shost, unsigned int channel,
unsigned int id, unsigned int lun, int rescan)
{
- SCSI_LOG_SCAN_BUS(3, printk (KERN_INFO "%s: <%u:%u:%u:%u>\n",
- __FUNCTION__, shost->host_no, channel, id, lun));
+ SCSI_LOG_SCAN_BUS(3, shost_printk (KERN_INFO, shost,
+ "%s: <%u:%u:%u>\n",
+ __FUNCTION__, channel, id, lun));
if (((channel != SCAN_WILD_CARD) && (channel > shost->max_channel)) ||
((id != SCAN_WILD_CARD) && (id > shost->max_id)) ||
@@ -1452,19 +1452,6 @@ void scsi_scan_host(struct Scsi_Host *shost)
}
EXPORT_SYMBOL(scsi_scan_host);
-/**
- * scsi_scan_single_target - scan the given SCSI target
- * @shost: adapter to scan
- * @chan: channel to scan
- * @id: target id to scan
- **/
-void scsi_scan_single_target(struct Scsi_Host *shost,
- unsigned int chan, unsigned int id)
-{
- scsi_scan_host_selected(shost, chan, id, SCAN_WILD_CARD, 1);
-}
-EXPORT_SYMBOL(scsi_scan_single_target);
-
void scsi_forget_host(struct Scsi_Host *shost)
{
struct scsi_device *sdev;
diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c
index 771e97ef136e..6cd5931d9a54 100644
--- a/drivers/scsi/scsi_transport_fc.c
+++ b/drivers/scsi/scsi_transport_fc.c
@@ -26,14 +26,13 @@
*/
#include <linux/module.h>
#include <linux/init.h>
+#include <linux/sched.h> /* workqueue stuff, HZ */
#include <scsi/scsi_device.h>
#include <scsi/scsi_host.h>
#include <scsi/scsi_transport.h>
#include <scsi/scsi_transport_fc.h>
#include "scsi_priv.h"
-#define FC_PRINTK(x, l, f, a...) printk(l "scsi(%d:%d:%d:%d): " f, (x)->host->host_no, (x)->channel, (x)->id, (x)->lun , ##a)
-
/*
* Redefine so that we can have same named attributes in the
* sdev/starget/host objects.
@@ -212,7 +211,7 @@ fc_bitfield_name_search(remote_port_roles, fc_remote_port_role_names)
#define FC_MGMTSRVR_PORTID 0x00000a
-static void fc_timeout_blocked_rport(void *data);
+static void fc_timeout_deleted_rport(void *data);
static void fc_scsi_scan_rport(void *data);
static void fc_rport_terminate(struct fc_rport *rport);
@@ -222,7 +221,7 @@ static void fc_rport_terminate(struct fc_rport *rport);
*/
#define FC_STARGET_NUM_ATTRS 3
#define FC_RPORT_NUM_ATTRS 9
-#define FC_HOST_NUM_ATTRS 15
+#define FC_HOST_NUM_ATTRS 16
struct fc_internal {
struct scsi_transport_template t;
@@ -386,7 +385,9 @@ show_fc_rport_##field (struct class_device *cdev, char *buf) \
struct fc_rport *rport = transport_class_to_rport(cdev); \
struct Scsi_Host *shost = rport_to_shost(rport); \
struct fc_internal *i = to_fc_internal(shost->transportt); \
- if (i->f->get_rport_##field) \
+ if ((i->f->get_rport_##field) && \
+ !((rport->port_state == FC_PORTSTATE_BLOCKED) || \
+ (rport->port_state == FC_PORTSTATE_NOTPRESENT))) \
i->f->get_rport_##field(rport); \
return snprintf(buf, sz, format_string, cast rport->field); \
}
@@ -400,6 +401,9 @@ store_fc_rport_##field(struct class_device *cdev, const char *buf, \
struct fc_rport *rport = transport_class_to_rport(cdev); \
struct Scsi_Host *shost = rport_to_shost(rport); \
struct fc_internal *i = to_fc_internal(shost->transportt); \
+ if ((rport->port_state == FC_PORTSTATE_BLOCKED) || \
+ (rport->port_state == FC_PORTSTATE_NOTPRESENT)) \
+ return -EBUSY; \
val = simple_strtoul(buf, NULL, 0); \
i->f->set_rport_##field(rport, val); \
return count; \
@@ -502,7 +506,29 @@ static FC_CLASS_DEVICE_ATTR(rport, supported_classes, S_IRUGO,
/* Dynamic Remote Port Attributes */
-fc_rport_rw_attr(dev_loss_tmo, "%d\n", 20);
+/*
+ * dev_loss_tmo attribute
+ */
+fc_rport_show_function(dev_loss_tmo, "%d\n", 20, )
+static ssize_t
+store_fc_rport_dev_loss_tmo(struct class_device *cdev, const char *buf,
+ size_t count)
+{
+ int val;
+ struct fc_rport *rport = transport_class_to_rport(cdev);
+ struct Scsi_Host *shost = rport_to_shost(rport);
+ struct fc_internal *i = to_fc_internal(shost->transportt);
+ if ((rport->port_state == FC_PORTSTATE_BLOCKED) ||
+ (rport->port_state == FC_PORTSTATE_NOTPRESENT))
+ return -EBUSY;
+ val = simple_strtoul(buf, NULL, 0);
+ if ((val < 0) || (val > SCSI_DEVICE_BLOCK_MAX_TIMEOUT))
+ return -EINVAL;
+ i->f->set_rport_dev_loss_tmo(rport, val);
+ return count;
+}
+static FC_CLASS_DEVICE_ATTR(rport, dev_loss_tmo, S_IRUGO | S_IWUSR,
+ show_fc_rport_dev_loss_tmo, store_fc_rport_dev_loss_tmo);
/* Private Remote Port Attributes */
@@ -715,9 +741,11 @@ static FC_CLASS_DEVICE_ATTR(host, field, S_IRUGO, \
count++
#define SETUP_PRIVATE_HOST_ATTRIBUTE_RW(field) \
+{ \
i->private_host_attrs[count] = class_device_attr_host_##field; \
i->host_attrs[count] = &i->private_host_attrs[count]; \
- count++
+ count++; \
+}
/* Fixed Host Attributes */
@@ -855,6 +883,26 @@ static FC_CLASS_DEVICE_ATTR(host, tgtid_bind_type, S_IRUGO | S_IWUSR,
show_fc_private_host_tgtid_bind_type,
store_fc_private_host_tgtid_bind_type);
+static ssize_t
+store_fc_private_host_issue_lip(struct class_device *cdev,
+ const char *buf, size_t count)
+{
+ struct Scsi_Host *shost = transport_class_to_shost(cdev);
+ struct fc_internal *i = to_fc_internal(shost->transportt);
+ int ret;
+
+ /* ignore any data value written to the attribute */
+ if (i->f->issue_fc_host_lip) {
+ ret = i->f->issue_fc_host_lip(shost);
+ return ret ? ret: count;
+ }
+
+ return -ENOENT;
+}
+
+static FC_CLASS_DEVICE_ATTR(host, issue_lip, S_IWUSR, NULL,
+ store_fc_private_host_issue_lip);
+
/*
* Host Statistics Management
*/
@@ -1121,6 +1169,8 @@ fc_attach_transport(struct fc_function_template *ft)
/* Transport-managed attributes */
SETUP_PRIVATE_HOST_ATTRIBUTE_RW(tgtid_bind_type);
+ if (ft->issue_fc_host_lip)
+ SETUP_PRIVATE_HOST_ATTRIBUTE_RW(issue_lip);
BUG_ON(count > FC_HOST_NUM_ATTRS);
@@ -1192,6 +1242,25 @@ fc_remove_host(struct Scsi_Host *shost)
}
EXPORT_SYMBOL(fc_remove_host);
+/*
+ * fc_rport_tgt_remove - Removes the scsi target on the remote port
+ * @rport: The remote port to be operated on
+ */
+static void
+fc_rport_tgt_remove(struct fc_rport *rport)
+{
+ struct Scsi_Host *shost = rport_to_shost(rport);
+
+ scsi_target_unblock(&rport->dev);
+
+ /* Stop anything on the workq */
+ if (!cancel_delayed_work(&rport->dev_loss_work))
+ flush_scheduled_work();
+ scsi_flush_work(shost);
+
+ scsi_remove_target(&rport->dev);
+}
+
/**
* fc_rport_create - allocates and creates a remote FC port.
* @shost: scsi host the remote port is connected to.
@@ -1238,7 +1307,7 @@ fc_rport_create(struct Scsi_Host *shost, int channel,
rport->dd_data = &rport[1];
rport->channel = channel;
- INIT_WORK(&rport->dev_loss_work, fc_timeout_blocked_rport, rport);
+ INIT_WORK(&rport->dev_loss_work, fc_timeout_deleted_rport, rport);
INIT_WORK(&rport->scan_work, fc_scsi_scan_rport, rport);
spin_lock_irqsave(shost->host_lock, flags);
@@ -1330,17 +1399,93 @@ struct fc_rport *
fc_remote_port_add(struct Scsi_Host *shost, int channel,
struct fc_rport_identifiers *ids)
{
+ struct fc_internal *fci = to_fc_internal(shost->transportt);
struct fc_rport *rport;
unsigned long flags;
int match = 0;
+ /*
+ * Search the list of "active" rports, for an rport that has been
+ * deleted, but we've held off the real delete while the target
+ * is in a "blocked" state.
+ */
+ spin_lock_irqsave(shost->host_lock, flags);
+
+ list_for_each_entry(rport, &fc_host_rports(shost), peers) {
+
+ if ((rport->port_state == FC_PORTSTATE_BLOCKED) &&
+ (rport->channel == channel)) {
+
+ switch (fc_host_tgtid_bind_type(shost)) {
+ case FC_TGTID_BIND_BY_WWPN:
+ case FC_TGTID_BIND_NONE:
+ if (rport->port_name == ids->port_name)
+ match = 1;
+ break;
+ case FC_TGTID_BIND_BY_WWNN:
+ if (rport->node_name == ids->node_name)
+ match = 1;
+ break;
+ case FC_TGTID_BIND_BY_ID:
+ if (rport->port_id == ids->port_id)
+ match = 1;
+ break;
+ }
+
+ if (match) {
+ struct work_struct *work =
+ &rport->dev_loss_work;
+
+ memcpy(&rport->node_name, &ids->node_name,
+ sizeof(rport->node_name));
+ memcpy(&rport->port_name, &ids->port_name,
+ sizeof(rport->port_name));
+ rport->port_id = ids->port_id;
+
+ rport->port_state = FC_PORTSTATE_ONLINE;
+ rport->roles = ids->roles;
+
+ spin_unlock_irqrestore(shost->host_lock, flags);
+
+ if (fci->f->dd_fcrport_size)
+ memset(rport->dd_data, 0,
+ fci->f->dd_fcrport_size);
+
+ /*
+ * If we were blocked, we were a target.
+ * If no longer a target, we leave the timer
+ * running in case the port changes roles
+ * prior to the timer expiring. If the timer
+ * fires, the target will be torn down.
+ */
+ if (!(ids->roles & FC_RPORT_ROLE_FCP_TARGET))
+ return rport;
+
+ /* restart the target */
+
+ /*
+ * Stop the target timer first. Take no action
+ * on the del_timer failure as the state
+ * machine state change will validate the
+ * transaction.
+ */
+ if (!cancel_delayed_work(work))
+ flush_scheduled_work();
+
+ /* initiate a scan of the target */
+ scsi_queue_work(shost, &rport->scan_work);
+
+ return rport;
+ }
+ }
+ }
+
+ /* Search the bindings array */
if (likely((ids->roles & FC_RPORT_ROLE_FCP_TARGET) &&
(fc_host_tgtid_bind_type(shost) != FC_TGTID_BIND_NONE))) {
/* search for a matching consistent binding */
- spin_lock_irqsave(shost->host_lock, flags);
-
list_for_each_entry(rport, &fc_host_rport_bindings(shost),
peers) {
if (rport->channel != channel)
@@ -1370,8 +1515,6 @@ fc_remote_port_add(struct Scsi_Host *shost, int channel,
}
}
- spin_unlock_irqrestore(shost->host_lock, flags);
-
if (match) {
memcpy(&rport->node_name, &ids->node_name,
sizeof(rport->node_name));
@@ -1381,6 +1524,12 @@ fc_remote_port_add(struct Scsi_Host *shost, int channel,
rport->roles = ids->roles;
rport->port_state = FC_PORTSTATE_ONLINE;
+ spin_unlock_irqrestore(shost->host_lock, flags);
+
+ if (fci->f->dd_fcrport_size)
+ memset(rport->dd_data, 0,
+ fci->f->dd_fcrport_size);
+
if (rport->roles & FC_RPORT_ROLE_FCP_TARGET)
/* initiate a scan of the target */
scsi_queue_work(shost, &rport->scan_work);
@@ -1389,6 +1538,8 @@ fc_remote_port_add(struct Scsi_Host *shost, int channel,
}
}
+ spin_unlock_irqrestore(shost->host_lock, flags);
+
/* No consistent binding found - create new remote port entry */
rport = fc_rport_create(shost, channel, ids);
@@ -1397,25 +1548,6 @@ fc_remote_port_add(struct Scsi_Host *shost, int channel,
EXPORT_SYMBOL(fc_remote_port_add);
/*
- * fc_rport_tgt_remove - Removes the scsi target on the remote port
- * @rport: The remote port to be operated on
- */
-static void
-fc_rport_tgt_remove(struct fc_rport *rport)
-{
- struct Scsi_Host *shost = rport_to_shost(rport);
-
- scsi_target_unblock(&rport->dev);
-
- /* Stop anything on the workq */
- if (!cancel_delayed_work(&rport->dev_loss_work))
- flush_scheduled_work();
- scsi_flush_work(shost);
-
- scsi_remove_target(&rport->dev);
-}
-
-/*
* fc_rport_terminate - this routine tears down and deallocates a remote port.
* @rport: The remote port to be terminated
*
@@ -1448,24 +1580,44 @@ fc_rport_terminate(struct fc_rport *rport)
* The LLDD calls this routine to notify the transport that a remote
* port is no longer part of the topology. Note: Although a port
* may no longer be part of the topology, it may persist in the remote
- * ports displayed by the fc_host. This is done so that target id
- * mappings (managed via the remote port structures), are always visible
- * as long as the mapping is valid, regardless of port state,
+ * ports displayed by the fc_host. We do this under 2 conditions:
+ * - If the port was a scsi target, we delay its deletion by "blocking" it.
+ * This allows the port to temporarily disappear, then reappear without
+ * disrupting the SCSI device tree attached to it. During the "blocked"
+ * period the port will still exist.
+ * - If the port was a scsi target and disappears for longer than we
+ * expect, we'll delete the port and the tear down the SCSI device tree
+ * attached to it. However, we want to semi-persist the target id assigned
+ * to that port if it eventually does exist. The port structure will
+ * remain (although with minimal information) so that the target id
+ * bindings remails.
*
* If the remote port is not an FCP Target, it will be fully torn down
* and deallocated, including the fc_remote_port class device.
*
- * If the remote port is an FCP Target, the port structure will be
- * marked as Not Present, but will remain as long as there is a valid
- * SCSI target id mapping associated with the port structure. Validity
- * is determined by the binding type. If binding by wwpn, then the port
- * structure is always valid and will not be deallocated until the host
- * is removed. If binding by wwnn, then the port structure is valid
- * until another port with the same node name is found in the topology.
- * If binding by port id (fc address), then the port structure is valid
- * valid until another port with the same address is identified.
+ * If the remote port is an FCP Target, the port will be placed in a
+ * temporary blocked state. From the LLDD's perspective, the rport no
+ * longer exists. From the SCSI midlayer's perspective, the SCSI target
+ * exists, but all sdevs on it are blocked from further I/O. The following
+ * is then expected:
+ * If the remote port does not return (signaled by a LLDD call to
+ * fc_remote_port_add()) within the dev_loss_tmo timeout, then the
+ * scsi target is removed - killing all outstanding i/o and removing the
+ * scsi devices attached ot it. The port structure will be marked Not
+ * Present and be partially cleared, leaving only enough information to
+ * recognize the remote port relative to the scsi target id binding if
+ * it later appears. The port will remain as long as there is a valid
+ * binding (e.g. until the user changes the binding type or unloads the
+ * scsi host with the binding).
*
- * Called from interrupt or normal process context.
+ * If the remote port returns within the dev_loss_tmo value (and matches
+ * according to the target id binding type), the port structure will be
+ * reused. If it is no longer a SCSI target, the target will be torn
+ * down. If it continues to be a SCSI target, then the target will be
+ * unblocked (allowing i/o to be resumed), and a scan will be activated
+ * to ensure that all luns are detected.
+ *
+ * Called from normal process context only - cannot be called from interrupt.
*
* Notes:
* This routine assumes no locks are held on entry.
@@ -1473,53 +1625,20 @@ fc_rport_terminate(struct fc_rport *rport)
void
fc_remote_port_delete(struct fc_rport *rport)
{
- struct Scsi_Host *shost = rport_to_shost(rport);
- unsigned long flags;
+ int timeout = rport->dev_loss_tmo;
- /* If no scsi target id mapping or consistent binding type, delete it */
- if ((rport->scsi_target_id == -1) ||
- (fc_host_tgtid_bind_type(shost) == FC_TGTID_BIND_NONE)) {
+ /* If no scsi target id mapping, delete it */
+ if (rport->scsi_target_id == -1) {
fc_rport_terminate(rport);
return;
}
- fc_rport_tgt_remove(rport);
+ scsi_target_block(&rport->dev);
- spin_lock_irqsave(shost->host_lock, flags);
- list_move_tail(&rport->peers, &fc_host_rport_bindings(shost));
- spin_unlock_irqrestore(shost->host_lock, flags);
+ /* cap the length the devices can be blocked until they are deleted */
+ schedule_delayed_work(&rport->dev_loss_work, timeout * HZ);
- /*
- * Note: We do not remove or clear the hostdata area. This allows
- * host-specific target data to persist along with the
- * scsi_target_id. It's up to the host to manage it's hostdata area.
- */
-
- /*
- * Reinitialize port attributes that may change if the port comes back.
- */
- rport->maxframe_size = -1;
- rport->supported_classes = FC_COS_UNSPECIFIED;
- rport->roles = FC_RPORT_ROLE_UNKNOWN;
- rport->port_state = FC_PORTSTATE_NOTPRESENT;
-
- /* remove the identifiers that aren't used in the consisting binding */
- switch (fc_host_tgtid_bind_type(shost)) {
- case FC_TGTID_BIND_BY_WWPN:
- rport->node_name = -1;
- rport->port_id = -1;
- break;
- case FC_TGTID_BIND_BY_WWNN:
- rport->port_name = -1;
- rport->port_id = -1;
- break;
- case FC_TGTID_BIND_BY_ID:
- rport->node_name = -1;
- rport->port_name = -1;
- break;
- case FC_TGTID_BIND_NONE: /* to keep compiler happy */
- break;
- }
+ rport->port_state = FC_PORTSTATE_BLOCKED;
}
EXPORT_SYMBOL(fc_remote_port_delete);
@@ -1552,127 +1671,140 @@ fc_remote_port_rolechg(struct fc_rport *rport, u32 roles)
unsigned long flags;
int create = 0;
- rport->roles = roles;
-
spin_lock_irqsave(shost->host_lock, flags);
- if ((rport->scsi_target_id == -1) &&
- (rport->roles & FC_RPORT_ROLE_FCP_TARGET)) {
- rport->scsi_target_id = fc_host->next_target_id++;
- create = 1;
+ if (roles & FC_RPORT_ROLE_FCP_TARGET) {
+ if (rport->scsi_target_id == -1) {
+ rport->scsi_target_id = fc_host->next_target_id++;
+ create = 1;
+ } else if (!(rport->roles & FC_RPORT_ROLE_FCP_TARGET))
+ create = 1;
}
spin_unlock_irqrestore(shost->host_lock, flags);
- if (create)
+ rport->roles = roles;
+
+ if (create) {
+ /*
+ * There may have been a delete timer running on the
+ * port. Ensure that it is cancelled as we now know
+ * the port is an FCP Target.
+ * Note: we know the rport is exists and in an online
+ * state as the LLDD would not have had an rport
+ * reference to pass us.
+ *
+ * Take no action on the del_timer failure as the state
+ * machine state change will validate the
+ * transaction.
+ */
+ if (!cancel_delayed_work(&rport->dev_loss_work))
+ flush_scheduled_work();
+
/* initiate a scan of the target */
scsi_queue_work(shost, &rport->scan_work);
+ }
}
EXPORT_SYMBOL(fc_remote_port_rolechg);
/**
- * fc_timeout_blocked_rport - Timeout handler for blocked remote port
- * that fails to return in the alloted time.
- * @data: scsi target that failed to reappear in the alloted time.
+ * fc_timeout_deleted_rport - Timeout handler for a deleted remote port that
+ * was a SCSI target (thus was blocked), and failed
+ * to return in the alloted time.
+ *
+ * @data: rport target that failed to reappear in the alloted time.
**/
static void
-fc_timeout_blocked_rport(void *data)
+fc_timeout_deleted_rport(void *data)
{
struct fc_rport *rport = (struct fc_rport *)data;
+ struct Scsi_Host *shost = rport_to_shost(rport);
+ unsigned long flags;
- rport->port_state = FC_PORTSTATE_OFFLINE;
-
- dev_printk(KERN_ERR, &rport->dev,
- "blocked FC remote port time out: removing target\n");
+ spin_lock_irqsave(shost->host_lock, flags);
/*
- * As this only occurs if the remote port (scsi target)
- * went away and didn't come back - we'll remove
- * all attached scsi devices.
+ * If the port is ONLINE, then it came back, but was no longer an
+ * FCP target. Thus we need to tear down the scsi_target on it.
*/
- scsi_target_unblock(&rport->dev);
- scsi_remove_target(&rport->dev);
-}
+ if (rport->port_state == FC_PORTSTATE_ONLINE) {
+ spin_unlock_irqrestore(shost->host_lock, flags);
-/**
- * fc_remote_port_block - temporarily block any scsi traffic to a remote port.
- * @rport: remote port to be blocked.
- *
- * scsi lldd's with a FC transport call this routine to temporarily stop
- * all scsi traffic to a remote port. If the port is not a SCSI target,
- * no action is taken. If the port is a SCSI target, all attached devices
- * are placed into a SDEV_BLOCK state and a timer is started. The timer is
- * represents the maximum amount of time the port may be blocked. If the
- * timer expires, the port is considered non-existent and the attached
- * scsi devices will be removed.
- *
- * Called from interrupt or normal process context.
- *
- * Returns zero if successful or error if not
- *
- * Notes:
- * This routine assumes no locks are held on entry.
- *
- * The timeout and timer types are extracted from the fc transport
- * attributes from the caller's rport pointer.
- **/
-int
-fc_remote_port_block(struct fc_rport *rport)
-{
- int timeout = rport->dev_loss_tmo;
- struct work_struct *work = &rport->dev_loss_work;
+ dev_printk(KERN_ERR, &rport->dev,
+ "blocked FC remote port time out: removing target\n");
- if (timeout < 0 || timeout > SCSI_DEVICE_BLOCK_MAX_TIMEOUT)
- return -EINVAL;
+ fc_rport_tgt_remove(rport);
- scsi_target_block(&rport->dev);
+ return;
+ }
- /* cap the length the devices can be blocked */
- schedule_delayed_work(work, timeout * HZ);
+ if (rport->port_state != FC_PORTSTATE_BLOCKED) {
+ spin_unlock_irqrestore(shost->host_lock, flags);
+ dev_printk(KERN_ERR, &rport->dev,
+ "blocked FC remote port time out: leaving target alone\n");
+ return;
+ }
- rport->port_state = FC_PORTSTATE_BLOCKED;
- return 0;
-}
-EXPORT_SYMBOL(fc_remote_port_block);
+ if (fc_host_tgtid_bind_type(shost) == FC_TGTID_BIND_NONE) {
+ spin_unlock_irqrestore(shost->host_lock, flags);
+ dev_printk(KERN_ERR, &rport->dev,
+ "blocked FC remote port time out: removing target\n");
+ fc_rport_terminate(rport);
+ return;
+ }
-/**
- * fc_remote_port_unblock - restart any blocked scsi traffic to a remote port.
- * @rport: remote port to be unblocked.
- *
- * scsi lld's with a FC transport call this routine to restart IO to all
- * devices associated with the caller's scsi target following a fc_target_block
- * request. Called from interrupt or normal process context.
- *
- * Notes:
- * This routine assumes no locks are held on entry.
- **/
- void
-fc_remote_port_unblock(struct fc_rport *rport)
-{
- struct work_struct *work = &rport->dev_loss_work;
- struct Scsi_Host *shost = rport_to_shost(rport);
+ dev_printk(KERN_ERR, &rport->dev,
+ "blocked FC remote port time out: removing target and "
+ "saving binding\n");
+
+ list_move_tail(&rport->peers, &fc_host_rport_bindings(shost));
/*
- * Stop the target timer first. Take no action on the del_timer
- * failure as the state machine state change will validate the
- * transaction.
+ * Note: We do not remove or clear the hostdata area. This allows
+ * host-specific target data to persist along with the
+ * scsi_target_id. It's up to the host to manage it's hostdata area.
*/
- if (!cancel_delayed_work(work))
- flush_scheduled_work();
- if (rport->port_state == FC_PORTSTATE_OFFLINE)
- /*
- * initiate a scan of the target as the target has
- * been torn down.
- */
- scsi_queue_work(shost, &rport->scan_work);
- else
- scsi_target_unblock(&rport->dev);
+ /*
+ * Reinitialize port attributes that may change if the port comes back.
+ */
+ rport->maxframe_size = -1;
+ rport->supported_classes = FC_COS_UNSPECIFIED;
+ rport->roles = FC_RPORT_ROLE_UNKNOWN;
+ rport->port_state = FC_PORTSTATE_NOTPRESENT;
- rport->port_state = FC_PORTSTATE_ONLINE;
+ /* remove the identifiers that aren't used in the consisting binding */
+ switch (fc_host_tgtid_bind_type(shost)) {
+ case FC_TGTID_BIND_BY_WWPN:
+ rport->node_name = -1;
+ rport->port_id = -1;
+ break;
+ case FC_TGTID_BIND_BY_WWNN:
+ rport->port_name = -1;
+ rport->port_id = -1;
+ break;
+ case FC_TGTID_BIND_BY_ID:
+ rport->node_name = -1;
+ rport->port_name = -1;
+ break;
+ case FC_TGTID_BIND_NONE: /* to keep compiler happy */
+ break;
+ }
+
+ spin_unlock_irqrestore(shost->host_lock, flags);
+
+ /*
+ * As this only occurs if the remote port (scsi target)
+ * went away and didn't come back - we'll remove
+ * all attached scsi devices.
+ */
+ fc_rport_tgt_remove(rport);
}
-EXPORT_SYMBOL(fc_remote_port_unblock);
/**
* fc_scsi_scan_rport - called to perform a scsi scan on a remote port.
+ *
+ * Will unblock the target (in case it went away and has now come back),
+ * then invoke a scan.
+ *
* @data: remote port to be scanned.
**/
static void
@@ -1680,6 +1812,7 @@ fc_scsi_scan_rport(void *data)
{
struct fc_rport *rport = (struct fc_rport *)data;
+ scsi_target_unblock(&rport->dev);
scsi_scan_target(&rport->dev, rport->channel, rport->scsi_target_id,
SCAN_WILD_CARD, 1);
}
diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c
index 8bb8222ea589..49fd18c1a9c6 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -1,8 +1,10 @@
-/*
+/*
* iSCSI transport class definitions
*
* Copyright (C) IBM Corporation, 2004
- * Copyright (C) Mike Christie, 2004
+ * Copyright (C) Mike Christie, 2004 - 2005
+ * Copyright (C) Dmitry Yusupov, 2004 - 2005
+ * Copyright (C) Alex Aizman, 2004 - 2005
*
* 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
@@ -19,370 +21,1257 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/mempool.h>
+#include <net/tcp.h>
+
#include <scsi/scsi.h>
#include <scsi/scsi_host.h>
#include <scsi/scsi_device.h>
#include <scsi/scsi_transport.h>
#include <scsi/scsi_transport_iscsi.h>
+#include <scsi/iscsi_if.h>
-#define ISCSI_SESSION_ATTRS 20
-#define ISCSI_HOST_ATTRS 2
+#define ISCSI_SESSION_ATTRS 8
+#define ISCSI_CONN_ATTRS 6
struct iscsi_internal {
struct scsi_transport_template t;
- struct iscsi_function_template *fnt;
+ struct iscsi_transport *iscsi_transport;
+ struct list_head list;
+ /*
+ * List of sessions for this transport
+ */
+ struct list_head sessions;
+ /*
+ * lock to serialize access to the sessions list which must
+ * be taken after the rx_queue_sema
+ */
+ spinlock_t session_lock;
+ /*
+ * based on transport capabilities, at register time we set these
+ * bits to tell the transport class it wants attributes displayed
+ * in sysfs or that it can support different iSCSI Data-Path
+ * capabilities
+ */
+ uint32_t param_mask;
+
+ struct class_device cdev;
/*
* We do not have any private or other attrs.
*/
+ struct transport_container conn_cont;
+ struct class_device_attribute *conn_attrs[ISCSI_CONN_ATTRS + 1];
+ struct transport_container session_cont;
struct class_device_attribute *session_attrs[ISCSI_SESSION_ATTRS + 1];
- struct class_device_attribute *host_attrs[ISCSI_HOST_ATTRS + 1];
};
-#define to_iscsi_internal(tmpl) container_of(tmpl, struct iscsi_internal, t)
+/*
+ * list of registered transports and lock that must
+ * be held while accessing list. The iscsi_transport_lock must
+ * be acquired after the rx_queue_sema.
+ */
+static LIST_HEAD(iscsi_transports);
+static DEFINE_SPINLOCK(iscsi_transport_lock);
+
+#define to_iscsi_internal(tmpl) \
+ container_of(tmpl, struct iscsi_internal, t)
+
+#define cdev_to_iscsi_internal(_cdev) \
+ container_of(_cdev, struct iscsi_internal, cdev)
-static DECLARE_TRANSPORT_CLASS(iscsi_transport_class,
- "iscsi_transport",
+static void iscsi_transport_release(struct class_device *cdev)
+{
+ struct iscsi_internal *priv = cdev_to_iscsi_internal(cdev);
+ kfree(priv);
+}
+
+/*
+ * iscsi_transport_class represents the iscsi_transports that are
+ * registered.
+ */
+static struct class iscsi_transport_class = {
+ .name = "iscsi_transport",
+ .release = iscsi_transport_release,
+};
+
+static ssize_t
+show_transport_handle(struct class_device *cdev, char *buf)
+{
+ struct iscsi_internal *priv = cdev_to_iscsi_internal(cdev);
+ return sprintf(buf, "%llu\n", (unsigned long long)iscsi_handle(priv->iscsi_transport));
+}
+static CLASS_DEVICE_ATTR(handle, S_IRUGO, show_transport_handle, NULL);
+
+#define show_transport_attr(name, format) \
+static ssize_t \
+show_transport_##name(struct class_device *cdev, char *buf) \
+{ \
+ struct iscsi_internal *priv = cdev_to_iscsi_internal(cdev); \
+ return sprintf(buf, format"\n", priv->iscsi_transport->name); \
+} \
+static CLASS_DEVICE_ATTR(name, S_IRUGO, show_transport_##name, NULL);
+
+show_transport_attr(caps, "0x%x");
+show_transport_attr(max_lun, "%d");
+show_transport_attr(max_conn, "%d");
+show_transport_attr(max_cmd_len, "%d");
+
+static struct attribute *iscsi_transport_attrs[] = {
+ &class_device_attr_handle.attr,
+ &class_device_attr_caps.attr,
+ &class_device_attr_max_lun.attr,
+ &class_device_attr_max_conn.attr,
+ &class_device_attr_max_cmd_len.attr,
+ NULL,
+};
+
+static struct attribute_group iscsi_transport_group = {
+ .attrs = iscsi_transport_attrs,
+};
+
+static DECLARE_TRANSPORT_CLASS(iscsi_session_class,
+ "iscsi_session",
NULL,
NULL,
NULL);
-static DECLARE_TRANSPORT_CLASS(iscsi_host_class,
- "iscsi_host",
+static DECLARE_TRANSPORT_CLASS(iscsi_connection_class,
+ "iscsi_connection",
NULL,
NULL,
NULL);
+
+static struct sock *nls;
+static int daemon_pid;
+static DECLARE_MUTEX(rx_queue_sema);
+
+struct mempool_zone {
+ mempool_t *pool;
+ atomic_t allocated;
+ int size;
+ int hiwat;
+ struct list_head freequeue;
+ spinlock_t freelock;
+};
+
+static struct mempool_zone z_reply;
+
/*
- * iSCSI target and session attrs
+ * Z_MAX_* - actual mempool size allocated at the mempool_zone_init() time
+ * Z_HIWAT_* - zone's high watermark when if_error bit will be set to -ENOMEM
+ * so daemon will notice OOM on NETLINK tranposrt level and will
+ * be able to predict or change operational behavior
*/
-#define iscsi_session_show_fn(field, format) \
- \
-static ssize_t \
-show_session_##field(struct class_device *cdev, char *buf) \
-{ \
- struct scsi_target *starget = transport_class_to_starget(cdev); \
- struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); \
- struct iscsi_internal *i = to_iscsi_internal(shost->transportt); \
- \
- if (i->fnt->get_##field) \
- i->fnt->get_##field(starget); \
- return snprintf(buf, 20, format"\n", iscsi_##field(starget)); \
+#define Z_MAX_REPLY 8
+#define Z_HIWAT_REPLY 6
+#define Z_MAX_PDU 8
+#define Z_HIWAT_PDU 6
+#define Z_MAX_ERROR 16
+#define Z_HIWAT_ERROR 12
+
+struct iscsi_if_conn {
+ struct list_head conn_list; /* item in connlist */
+ struct list_head session_list; /* item in session->connections */
+ iscsi_connh_t connh;
+ int active; /* must be accessed with the connlock */
+ struct Scsi_Host *host; /* originated shost */
+ struct device dev; /* sysfs transport/container device */
+ struct iscsi_transport *transport;
+ struct mempool_zone z_error;
+ struct mempool_zone z_pdu;
+ struct list_head freequeue;
+};
+
+#define iscsi_dev_to_if_conn(_dev) \
+ container_of(_dev, struct iscsi_if_conn, dev)
+
+#define iscsi_cdev_to_if_conn(_cdev) \
+ iscsi_dev_to_if_conn(_cdev->dev)
+
+static LIST_HEAD(connlist);
+static DEFINE_SPINLOCK(connlock);
+
+struct iscsi_if_session {
+ struct list_head list; /* item in session_list */
+ struct list_head connections;
+ iscsi_sessionh_t sessionh;
+ struct iscsi_transport *transport;
+ struct device dev; /* sysfs transport/container device */
+};
+
+#define iscsi_dev_to_if_session(_dev) \
+ container_of(_dev, struct iscsi_if_session, dev)
+
+#define iscsi_cdev_to_if_session(_cdev) \
+ iscsi_dev_to_if_session(_cdev->dev)
+
+#define iscsi_if_session_to_shost(_session) \
+ dev_to_shost(_session->dev.parent)
+
+static struct iscsi_if_conn*
+iscsi_if_find_conn(uint64_t key)
+{
+ unsigned long flags;
+ struct iscsi_if_conn *conn;
+
+ spin_lock_irqsave(&connlock, flags);
+ list_for_each_entry(conn, &connlist, conn_list)
+ if (conn->connh == key) {
+ spin_unlock_irqrestore(&connlock, flags);
+ return conn;
+ }
+ spin_unlock_irqrestore(&connlock, flags);
+ return NULL;
}
-#define iscsi_session_rd_attr(field, format) \
- iscsi_session_show_fn(field, format) \
-static CLASS_DEVICE_ATTR(field, S_IRUGO, show_session_##field, NULL);
+static struct iscsi_internal *
+iscsi_if_transport_lookup(struct iscsi_transport *tt)
+{
+ struct iscsi_internal *priv;
+ unsigned long flags;
+
+ spin_lock_irqsave(&iscsi_transport_lock, flags);
+ list_for_each_entry(priv, &iscsi_transports, list) {
+ if (tt == priv->iscsi_transport) {
+ spin_unlock_irqrestore(&iscsi_transport_lock, flags);
+ return priv;
+ }
+ }
+ spin_unlock_irqrestore(&iscsi_transport_lock, flags);
+ return NULL;
+}
-iscsi_session_rd_attr(tpgt, "%hu");
-iscsi_session_rd_attr(tsih, "%2x");
-iscsi_session_rd_attr(max_recv_data_segment_len, "%u");
-iscsi_session_rd_attr(max_burst_len, "%u");
-iscsi_session_rd_attr(first_burst_len, "%u");
-iscsi_session_rd_attr(def_time2wait, "%hu");
-iscsi_session_rd_attr(def_time2retain, "%hu");
-iscsi_session_rd_attr(max_outstanding_r2t, "%hu");
-iscsi_session_rd_attr(erl, "%d");
+static inline struct list_head *skb_to_lh(struct sk_buff *skb)
+{
+ return (struct list_head *)&skb->cb;
+}
+static void*
+mempool_zone_alloc_skb(unsigned int gfp_mask, void *pool_data)
+{
+ struct mempool_zone *zone = pool_data;
-#define iscsi_session_show_bool_fn(field) \
- \
-static ssize_t \
-show_session_bool_##field(struct class_device *cdev, char *buf) \
-{ \
- struct scsi_target *starget = transport_class_to_starget(cdev); \
- struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); \
- struct iscsi_internal *i = to_iscsi_internal(shost->transportt); \
- \
- if (i->fnt->get_##field) \
- i->fnt->get_##field(starget); \
- \
- if (iscsi_##field(starget)) \
- return sprintf(buf, "Yes\n"); \
- return sprintf(buf, "No\n"); \
+ return alloc_skb(zone->size, gfp_mask);
}
-#define iscsi_session_rd_bool_attr(field) \
- iscsi_session_show_bool_fn(field) \
-static CLASS_DEVICE_ATTR(field, S_IRUGO, show_session_bool_##field, NULL);
+static void
+mempool_zone_free_skb(void *element, void *pool_data)
+{
+ kfree_skb(element);
+}
-iscsi_session_rd_bool_attr(initial_r2t);
-iscsi_session_rd_bool_attr(immediate_data);
-iscsi_session_rd_bool_attr(data_pdu_in_order);
-iscsi_session_rd_bool_attr(data_sequence_in_order);
+static void
+mempool_zone_complete(struct mempool_zone *zone)
+{
+ unsigned long flags;
+ struct list_head *lh, *n;
-#define iscsi_session_show_digest_fn(field) \
- \
-static ssize_t \
-show_##field(struct class_device *cdev, char *buf) \
-{ \
- struct scsi_target *starget = transport_class_to_starget(cdev); \
- struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); \
- struct iscsi_internal *i = to_iscsi_internal(shost->transportt); \
- \
- if (i->fnt->get_##field) \
- i->fnt->get_##field(starget); \
- \
- if (iscsi_##field(starget)) \
- return sprintf(buf, "CRC32C\n"); \
- return sprintf(buf, "None\n"); \
+ spin_lock_irqsave(&zone->freelock, flags);
+ list_for_each_safe(lh, n, &zone->freequeue) {
+ struct sk_buff *skb = (struct sk_buff *)((char *)lh -
+ offsetof(struct sk_buff, cb));
+ if (!skb_shared(skb)) {
+ list_del(skb_to_lh(skb));
+ mempool_free(skb, zone->pool);
+ atomic_dec(&zone->allocated);
+ }
+ }
+ spin_unlock_irqrestore(&zone->freelock, flags);
}
-#define iscsi_session_rd_digest_attr(field) \
- iscsi_session_show_digest_fn(field) \
-static CLASS_DEVICE_ATTR(field, S_IRUGO, show_##field, NULL);
+static int
+mempool_zone_init(struct mempool_zone *zp, unsigned max, unsigned size,
+ unsigned hiwat)
+{
+ zp->pool = mempool_create(max, mempool_zone_alloc_skb,
+ mempool_zone_free_skb, zp);
+ if (!zp->pool)
+ return -ENOMEM;
-iscsi_session_rd_digest_attr(header_digest);
-iscsi_session_rd_digest_attr(data_digest);
+ zp->size = size;
+ zp->hiwat = hiwat;
-static ssize_t
-show_port(struct class_device *cdev, char *buf)
+ INIT_LIST_HEAD(&zp->freequeue);
+ spin_lock_init(&zp->freelock);
+ atomic_set(&zp->allocated, 0);
+
+ return 0;
+}
+
+
+static struct sk_buff*
+mempool_zone_get_skb(struct mempool_zone *zone)
{
- struct scsi_target *starget = transport_class_to_starget(cdev);
- struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
- struct iscsi_internal *i = to_iscsi_internal(shost->transportt);
+ struct sk_buff *skb;
- if (i->fnt->get_port)
- i->fnt->get_port(starget);
+ skb = mempool_alloc(zone->pool, GFP_ATOMIC);
+ if (skb)
+ atomic_inc(&zone->allocated);
+ return skb;
+}
- return snprintf(buf, 20, "%hu\n", ntohs(iscsi_port(starget)));
+static int
+iscsi_unicast_skb(struct mempool_zone *zone, struct sk_buff *skb)
+{
+ unsigned long flags;
+ int rc;
+
+ skb_get(skb);
+ rc = netlink_unicast(nls, skb, daemon_pid, MSG_DONTWAIT);
+ if (rc < 0) {
+ mempool_free(skb, zone->pool);
+ printk(KERN_ERR "iscsi: can not unicast skb (%d)\n", rc);
+ return rc;
+ }
+
+ spin_lock_irqsave(&zone->freelock, flags);
+ list_add(skb_to_lh(skb), &zone->freequeue);
+ spin_unlock_irqrestore(&zone->freelock, flags);
+
+ return 0;
}
-static CLASS_DEVICE_ATTR(port, S_IRUGO, show_port, NULL);
-static ssize_t
-show_ip_address(struct class_device *cdev, char *buf)
+int iscsi_recv_pdu(iscsi_connh_t connh, struct iscsi_hdr *hdr,
+ char *data, uint32_t data_size)
{
- struct scsi_target *starget = transport_class_to_starget(cdev);
- struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
- struct iscsi_internal *i = to_iscsi_internal(shost->transportt);
+ struct nlmsghdr *nlh;
+ struct sk_buff *skb;
+ struct iscsi_uevent *ev;
+ struct iscsi_if_conn *conn;
+ char *pdu;
+ int len = NLMSG_SPACE(sizeof(*ev) + sizeof(struct iscsi_hdr) +
+ data_size);
+
+ conn = iscsi_if_find_conn(connh);
+ BUG_ON(!conn);
+
+ mempool_zone_complete(&conn->z_pdu);
+
+ skb = mempool_zone_get_skb(&conn->z_pdu);
+ if (!skb) {
+ iscsi_conn_error(connh, ISCSI_ERR_CONN_FAILED);
+ printk(KERN_ERR "iscsi%d: can not deliver control PDU: OOM\n",
+ conn->host->host_no);
+ return -ENOMEM;
+ }
- if (i->fnt->get_ip_address)
- i->fnt->get_ip_address(starget);
+ nlh = __nlmsg_put(skb, daemon_pid, 0, 0, (len - sizeof(*nlh)), 0);
+ ev = NLMSG_DATA(nlh);
+ memset(ev, 0, sizeof(*ev));
+ ev->transport_handle = iscsi_handle(conn->transport);
+ ev->type = ISCSI_KEVENT_RECV_PDU;
+ if (atomic_read(&conn->z_pdu.allocated) >= conn->z_pdu.hiwat)
+ ev->iferror = -ENOMEM;
+ ev->r.recv_req.conn_handle = connh;
+ pdu = (char*)ev + sizeof(*ev);
+ memcpy(pdu, hdr, sizeof(struct iscsi_hdr));
+ memcpy(pdu + sizeof(struct iscsi_hdr), data, data_size);
- if (iscsi_addr_type(starget) == AF_INET)
- return sprintf(buf, "%u.%u.%u.%u\n",
- NIPQUAD(iscsi_sin_addr(starget)));
- else if(iscsi_addr_type(starget) == AF_INET6)
- return sprintf(buf, "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n",
- NIP6(iscsi_sin6_addr(starget)));
- return -EINVAL;
+ return iscsi_unicast_skb(&conn->z_pdu, skb);
}
-static CLASS_DEVICE_ATTR(ip_address, S_IRUGO, show_ip_address, NULL);
+EXPORT_SYMBOL_GPL(iscsi_recv_pdu);
-static ssize_t
-show_isid(struct class_device *cdev, char *buf)
+void iscsi_conn_error(iscsi_connh_t connh, enum iscsi_err error)
+{
+ struct nlmsghdr *nlh;
+ struct sk_buff *skb;
+ struct iscsi_uevent *ev;
+ struct iscsi_if_conn *conn;
+ int len = NLMSG_SPACE(sizeof(*ev));
+
+ conn = iscsi_if_find_conn(connh);
+ BUG_ON(!conn);
+
+ mempool_zone_complete(&conn->z_error);
+
+ skb = mempool_zone_get_skb(&conn->z_error);
+ if (!skb) {
+ printk(KERN_ERR "iscsi%d: gracefully ignored conn error (%d)\n",
+ conn->host->host_no, error);
+ return;
+ }
+
+ nlh = __nlmsg_put(skb, daemon_pid, 0, 0, (len - sizeof(*nlh)), 0);
+ ev = NLMSG_DATA(nlh);
+ ev->transport_handle = iscsi_handle(conn->transport);
+ ev->type = ISCSI_KEVENT_CONN_ERROR;
+ if (atomic_read(&conn->z_error.allocated) >= conn->z_error.hiwat)
+ ev->iferror = -ENOMEM;
+ ev->r.connerror.error = error;
+ ev->r.connerror.conn_handle = connh;
+
+ iscsi_unicast_skb(&conn->z_error, skb);
+
+ printk(KERN_INFO "iscsi%d: detected conn error (%d)\n",
+ conn->host->host_no, error);
+}
+EXPORT_SYMBOL_GPL(iscsi_conn_error);
+
+static int
+iscsi_if_send_reply(int pid, int seq, int type, int done, int multi,
+ void *payload, int size)
{
- struct scsi_target *starget = transport_class_to_starget(cdev);
- struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
- struct iscsi_internal *i = to_iscsi_internal(shost->transportt);
+ struct sk_buff *skb;
+ struct nlmsghdr *nlh;
+ int len = NLMSG_SPACE(size);
+ int flags = multi ? NLM_F_MULTI : 0;
+ int t = done ? NLMSG_DONE : type;
- if (i->fnt->get_isid)
- i->fnt->get_isid(starget);
+ mempool_zone_complete(&z_reply);
- return sprintf(buf, "%02x%02x%02x%02x%02x%02x\n",
- iscsi_isid(starget)[0], iscsi_isid(starget)[1],
- iscsi_isid(starget)[2], iscsi_isid(starget)[3],
- iscsi_isid(starget)[4], iscsi_isid(starget)[5]);
+ skb = mempool_zone_get_skb(&z_reply);
+ /*
+ * FIXME:
+ * user is supposed to react on iferror == -ENOMEM;
+ * see iscsi_if_rx().
+ */
+ BUG_ON(!skb);
+
+ nlh = __nlmsg_put(skb, pid, seq, t, (len - sizeof(*nlh)), 0);
+ nlh->nlmsg_flags = flags;
+ memcpy(NLMSG_DATA(nlh), payload, size);
+ return iscsi_unicast_skb(&z_reply, skb);
}
-static CLASS_DEVICE_ATTR(isid, S_IRUGO, show_isid, NULL);
/*
- * This is used for iSCSI names. Normally, we follow
- * the transport class convention of having the lld
- * set the field, but in these cases the value is
- * too large.
+ * iSCSI Session's hostdata organization:
+ *
+ * *------------------* <== host->hostdata
+ * | transport |
+ * |------------------| <== iscsi_hostdata(host->hostdata)
+ * | transport's data |
+ * |------------------| <== hostdata_session(host->hostdata)
+ * | interface's data |
+ * *------------------*
*/
-#define iscsi_session_show_str_fn(field) \
- \
-static ssize_t \
-show_session_str_##field(struct class_device *cdev, char *buf) \
-{ \
- ssize_t ret = 0; \
- struct scsi_target *starget = transport_class_to_starget(cdev); \
- struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); \
- struct iscsi_internal *i = to_iscsi_internal(shost->transportt); \
- \
- if (i->fnt->get_##field) \
- ret = i->fnt->get_##field(starget, buf, PAGE_SIZE); \
- return ret; \
+
+#define hostdata_privsize(_t) (sizeof(unsigned long) + _t->hostdata_size + \
+ _t->hostdata_size % sizeof(unsigned long) + \
+ sizeof(struct iscsi_if_session))
+
+#define hostdata_session(_hostdata) ((void*)_hostdata + sizeof(unsigned long) + \
+ ((struct iscsi_transport *) \
+ iscsi_ptr(*(uint64_t *)_hostdata))->hostdata_size)
+
+static void iscsi_if_session_dev_release(struct device *dev)
+{
+ struct iscsi_if_session *session = iscsi_dev_to_if_session(dev);
+ struct iscsi_transport *transport = session->transport;
+ struct Scsi_Host *shost = iscsi_if_session_to_shost(session);
+ struct iscsi_if_conn *conn, *tmp;
+ unsigned long flags;
+
+ /* now free connections */
+ spin_lock_irqsave(&connlock, flags);
+ list_for_each_entry_safe(conn, tmp, &session->connections,
+ session_list) {
+ list_del(&conn->session_list);
+ mempool_destroy(conn->z_pdu.pool);
+ mempool_destroy(conn->z_error.pool);
+ kfree(conn);
+ }
+ spin_unlock_irqrestore(&connlock, flags);
+ scsi_host_put(shost);
+ module_put(transport->owner);
}
-#define iscsi_session_rd_str_attr(field) \
- iscsi_session_show_str_fn(field) \
-static CLASS_DEVICE_ATTR(field, S_IRUGO, show_session_str_##field, NULL);
+static int
+iscsi_if_create_session(struct iscsi_internal *priv, struct iscsi_uevent *ev)
+{
+ struct iscsi_transport *transport = priv->iscsi_transport;
+ struct iscsi_if_session *session;
+ struct Scsi_Host *shost;
+ unsigned long flags;
+ int error;
+
+ if (!try_module_get(transport->owner))
+ return -EPERM;
+
+ shost = scsi_host_alloc(transport->host_template,
+ hostdata_privsize(transport));
+ if (!shost) {
+ ev->r.c_session_ret.session_handle = iscsi_handle(NULL);
+ printk(KERN_ERR "iscsi: can not allocate SCSI host for "
+ "session\n");
+ error = -ENOMEM;
+ goto out_module_put;
+ }
+ shost->max_id = 1;
+ shost->max_channel = 0;
+ shost->max_lun = transport->max_lun;
+ shost->max_cmd_len = transport->max_cmd_len;
+ shost->transportt = &priv->t;
+
+ /* store struct iscsi_transport in hostdata */
+ *(uint64_t*)shost->hostdata = ev->transport_handle;
+
+ ev->r.c_session_ret.session_handle = transport->create_session(
+ ev->u.c_session.initial_cmdsn, shost);
+ if (ev->r.c_session_ret.session_handle == iscsi_handle(NULL)) {
+ error = 0;
+ goto out_host_put;
+ }
+
+ /* host_no becomes assigned SID */
+ ev->r.c_session_ret.sid = shost->host_no;
+ /* initialize session */
+ session = hostdata_session(shost->hostdata);
+ INIT_LIST_HEAD(&session->connections);
+ INIT_LIST_HEAD(&session->list);
+ session->sessionh = ev->r.c_session_ret.session_handle;
+ session->transport = transport;
+
+ error = scsi_add_host(shost, NULL);
+ if (error)
+ goto out_destroy_session;
+
+ /*
+ * this is released in the dev's release function)
+ */
+ scsi_host_get(shost);
+ snprintf(session->dev.bus_id, BUS_ID_SIZE, "session%u", shost->host_no);
+ session->dev.parent = &shost->shost_gendev;
+ session->dev.release = iscsi_if_session_dev_release;
+ error = device_register(&session->dev);
+ if (error) {
+ printk(KERN_ERR "iscsi: could not register session%d's dev\n",
+ shost->host_no);
+ goto out_remove_host;
+ }
+ transport_register_device(&session->dev);
+
+ /* add this session to the list of active sessions */
+ spin_lock_irqsave(&priv->session_lock, flags);
+ list_add(&session->list, &priv->sessions);
+ spin_unlock_irqrestore(&priv->session_lock, flags);
-iscsi_session_rd_str_attr(target_name);
-iscsi_session_rd_str_attr(target_alias);
+ return 0;
+
+out_remove_host:
+ scsi_remove_host(shost);
+out_destroy_session:
+ transport->destroy_session(ev->r.c_session_ret.session_handle);
+ ev->r.c_session_ret.session_handle = iscsi_handle(NULL);
+out_host_put:
+ scsi_host_put(shost);
+out_module_put:
+ module_put(transport->owner);
+ return error;
+}
+
+static int
+iscsi_if_destroy_session(struct iscsi_internal *priv, struct iscsi_uevent *ev)
+{
+ struct iscsi_transport *transport = priv->iscsi_transport;
+ struct Scsi_Host *shost;
+ struct iscsi_if_session *session;
+ unsigned long flags;
+ struct iscsi_if_conn *conn;
+ int error = 0;
+
+ shost = scsi_host_lookup(ev->u.d_session.sid);
+ if (shost == ERR_PTR(-ENXIO))
+ return -EEXIST;
+ session = hostdata_session(shost->hostdata);
+
+ /* check if we have active connections */
+ spin_lock_irqsave(&connlock, flags);
+ list_for_each_entry(conn, &session->connections, session_list) {
+ if (conn->active) {
+ printk(KERN_ERR "iscsi%d: can not destroy session: "
+ "has active connection (%p)\n",
+ shost->host_no, iscsi_ptr(conn->connh));
+ spin_unlock_irqrestore(&connlock, flags);
+ error = EIO;
+ goto out_release_ref;
+ }
+ }
+ spin_unlock_irqrestore(&connlock, flags);
+
+ scsi_remove_host(shost);
+ transport->destroy_session(ev->u.d_session.session_handle);
+ transport_unregister_device(&session->dev);
+ device_unregister(&session->dev);
+
+ /* remove this session from the list of active sessions */
+ spin_lock_irqsave(&priv->session_lock, flags);
+ list_del(&session->list);
+ spin_unlock_irqrestore(&priv->session_lock, flags);
+
+ /* ref from host alloc */
+ scsi_host_put(shost);
+out_release_ref:
+ /* ref from host lookup */
+ scsi_host_put(shost);
+ return error;
+}
+
+static void iscsi_if_conn_dev_release(struct device *dev)
+{
+ struct iscsi_if_conn *conn = iscsi_dev_to_if_conn(dev);
+ struct Scsi_Host *shost = conn->host;
+
+ scsi_host_put(shost);
+}
+
+static int
+iscsi_if_create_conn(struct iscsi_transport *transport, struct iscsi_uevent *ev)
+{
+ struct iscsi_if_session *session;
+ struct Scsi_Host *shost;
+ struct iscsi_if_conn *conn;
+ unsigned long flags;
+ int error;
+
+ shost = scsi_host_lookup(ev->u.c_conn.sid);
+ if (shost == ERR_PTR(-ENXIO))
+ return -EEXIST;
+ session = hostdata_session(shost->hostdata);
+
+ conn = kmalloc(sizeof(struct iscsi_if_conn), GFP_KERNEL);
+ if (!conn) {
+ error = -ENOMEM;
+ goto out_release_ref;
+ }
+ memset(conn, 0, sizeof(struct iscsi_if_conn));
+ INIT_LIST_HEAD(&conn->session_list);
+ INIT_LIST_HEAD(&conn->conn_list);
+ conn->host = shost;
+ conn->transport = transport;
+
+ error = mempool_zone_init(&conn->z_pdu, Z_MAX_PDU,
+ NLMSG_SPACE(sizeof(struct iscsi_uevent) +
+ sizeof(struct iscsi_hdr) +
+ DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH),
+ Z_HIWAT_PDU);
+ if (error) {
+ printk(KERN_ERR "iscsi%d: can not allocate pdu zone for new "
+ "conn\n", shost->host_no);
+ goto out_free_conn;
+ }
+ error = mempool_zone_init(&conn->z_error, Z_MAX_ERROR,
+ NLMSG_SPACE(sizeof(struct iscsi_uevent)),
+ Z_HIWAT_ERROR);
+ if (error) {
+ printk(KERN_ERR "iscsi%d: can not allocate error zone for "
+ "new conn\n", shost->host_no);
+ goto out_free_pdu_pool;
+ }
+
+ ev->r.handle = transport->create_conn(ev->u.c_conn.session_handle,
+ ev->u.c_conn.cid);
+ if (!ev->r.handle) {
+ error = -ENODEV;
+ goto out_free_error_pool;
+ }
+
+ conn->connh = ev->r.handle;
+
+ /*
+ * this is released in the dev's release function
+ */
+ if (!scsi_host_get(shost))
+ goto out_destroy_conn;
+ snprintf(conn->dev.bus_id, BUS_ID_SIZE, "connection%d:%u",
+ shost->host_no, ev->u.c_conn.cid);
+ conn->dev.parent = &session->dev;
+ conn->dev.release = iscsi_if_conn_dev_release;
+ error = device_register(&conn->dev);
+ if (error) {
+ printk(KERN_ERR "iscsi%d: could not register connections%u "
+ "dev\n", shost->host_no, ev->u.c_conn.cid);
+ goto out_release_parent_ref;
+ }
+ transport_register_device(&conn->dev);
+
+ spin_lock_irqsave(&connlock, flags);
+ list_add(&conn->conn_list, &connlist);
+ list_add(&conn->session_list, &session->connections);
+ conn->active = 1;
+ spin_unlock_irqrestore(&connlock, flags);
+
+ scsi_host_put(shost);
+ return 0;
+
+out_release_parent_ref:
+ scsi_host_put(shost);
+out_destroy_conn:
+ transport->destroy_conn(ev->r.handle);
+out_free_error_pool:
+ mempool_destroy(conn->z_error.pool);
+out_free_pdu_pool:
+ mempool_destroy(conn->z_pdu.pool);
+out_free_conn:
+ kfree(conn);
+out_release_ref:
+ scsi_host_put(shost);
+ return error;
+}
+
+static int
+iscsi_if_destroy_conn(struct iscsi_transport *transport, struct iscsi_uevent *ev)
+{
+ unsigned long flags;
+ struct iscsi_if_conn *conn;
+
+ conn = iscsi_if_find_conn(ev->u.d_conn.conn_handle);
+ if (!conn)
+ return -EEXIST;
+
+ transport->destroy_conn(ev->u.d_conn.conn_handle);
+
+ spin_lock_irqsave(&connlock, flags);
+ conn->active = 0;
+ list_del(&conn->conn_list);
+ spin_unlock_irqrestore(&connlock, flags);
+
+ transport_unregister_device(&conn->dev);
+ device_unregister(&conn->dev);
+ return 0;
+}
+
+static int
+iscsi_if_get_stats(struct iscsi_transport *transport, struct sk_buff *skb,
+ struct nlmsghdr *nlh)
+{
+ struct iscsi_uevent *ev = NLMSG_DATA(nlh);
+ struct iscsi_stats *stats;
+ struct sk_buff *skbstat;
+ struct iscsi_if_conn *conn;
+ struct nlmsghdr *nlhstat;
+ struct iscsi_uevent *evstat;
+ int len = NLMSG_SPACE(sizeof(*ev) +
+ sizeof(struct iscsi_stats) +
+ sizeof(struct iscsi_stats_custom) *
+ ISCSI_STATS_CUSTOM_MAX);
+ int err = 0;
+
+ conn = iscsi_if_find_conn(ev->u.get_stats.conn_handle);
+ if (!conn)
+ return -EEXIST;
+
+ do {
+ int actual_size;
+
+ mempool_zone_complete(&conn->z_pdu);
+
+ skbstat = mempool_zone_get_skb(&conn->z_pdu);
+ if (!skbstat) {
+ printk(KERN_ERR "iscsi%d: can not deliver stats: OOM\n",
+ conn->host->host_no);
+ return -ENOMEM;
+ }
+
+ nlhstat = __nlmsg_put(skbstat, daemon_pid, 0, 0,
+ (len - sizeof(*nlhstat)), 0);
+ evstat = NLMSG_DATA(nlhstat);
+ memset(evstat, 0, sizeof(*evstat));
+ evstat->transport_handle = iscsi_handle(conn->transport);
+ evstat->type = nlh->nlmsg_type;
+ if (atomic_read(&conn->z_pdu.allocated) >= conn->z_pdu.hiwat)
+ evstat->iferror = -ENOMEM;
+ evstat->u.get_stats.conn_handle =
+ ev->u.get_stats.conn_handle;
+ stats = (struct iscsi_stats *)
+ ((char*)evstat + sizeof(*evstat));
+ memset(stats, 0, sizeof(*stats));
+
+ transport->get_stats(ev->u.get_stats.conn_handle, stats);
+ actual_size = NLMSG_SPACE(sizeof(struct iscsi_uevent) +
+ sizeof(struct iscsi_stats) +
+ sizeof(struct iscsi_stats_custom) *
+ stats->custom_length);
+ actual_size -= sizeof(*nlhstat);
+ actual_size = NLMSG_LENGTH(actual_size);
+ skb_trim(skb, NLMSG_ALIGN(actual_size));
+ nlhstat->nlmsg_len = actual_size;
+
+ err = iscsi_unicast_skb(&conn->z_pdu, skbstat);
+ } while (err < 0 && err != -ECONNREFUSED);
+
+ return err;
+}
+
+static int
+iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
+{
+ int err = 0;
+ struct iscsi_uevent *ev = NLMSG_DATA(nlh);
+ struct iscsi_transport *transport = NULL;
+ struct iscsi_internal *priv;
+
+ if (NETLINK_CREDS(skb)->uid)
+ return -EPERM;
+
+ priv = iscsi_if_transport_lookup(iscsi_ptr(ev->transport_handle));
+ if (!priv)
+ return -EINVAL;
+ transport = priv->iscsi_transport;
+
+ daemon_pid = NETLINK_CREDS(skb)->pid;
+
+ switch (nlh->nlmsg_type) {
+ case ISCSI_UEVENT_CREATE_SESSION:
+ err = iscsi_if_create_session(priv, ev);
+ break;
+ case ISCSI_UEVENT_DESTROY_SESSION:
+ err = iscsi_if_destroy_session(priv, ev);
+ break;
+ case ISCSI_UEVENT_CREATE_CONN:
+ err = iscsi_if_create_conn(transport, ev);
+ break;
+ case ISCSI_UEVENT_DESTROY_CONN:
+ err = iscsi_if_destroy_conn(transport, ev);
+ break;
+ case ISCSI_UEVENT_BIND_CONN:
+ if (!iscsi_if_find_conn(ev->u.b_conn.conn_handle))
+ return -EEXIST;
+ ev->r.retcode = transport->bind_conn(
+ ev->u.b_conn.session_handle,
+ ev->u.b_conn.conn_handle,
+ ev->u.b_conn.transport_fd,
+ ev->u.b_conn.is_leading);
+ break;
+ case ISCSI_UEVENT_SET_PARAM:
+ if (!iscsi_if_find_conn(ev->u.set_param.conn_handle))
+ return -EEXIST;
+ ev->r.retcode = transport->set_param(
+ ev->u.set_param.conn_handle,
+ ev->u.set_param.param, ev->u.set_param.value);
+ break;
+ case ISCSI_UEVENT_START_CONN:
+ if (!iscsi_if_find_conn(ev->u.start_conn.conn_handle))
+ return -EEXIST;
+ ev->r.retcode = transport->start_conn(
+ ev->u.start_conn.conn_handle);
+ break;
+ case ISCSI_UEVENT_STOP_CONN:
+ if (!iscsi_if_find_conn(ev->u.stop_conn.conn_handle))
+ return -EEXIST;
+ transport->stop_conn(ev->u.stop_conn.conn_handle,
+ ev->u.stop_conn.flag);
+ break;
+ case ISCSI_UEVENT_SEND_PDU:
+ if (!iscsi_if_find_conn(ev->u.send_pdu.conn_handle))
+ return -EEXIST;
+ ev->r.retcode = transport->send_pdu(
+ ev->u.send_pdu.conn_handle,
+ (struct iscsi_hdr*)((char*)ev + sizeof(*ev)),
+ (char*)ev + sizeof(*ev) + ev->u.send_pdu.hdr_size,
+ ev->u.send_pdu.data_size);
+ break;
+ case ISCSI_UEVENT_GET_STATS:
+ err = iscsi_if_get_stats(transport, skb, nlh);
+ break;
+ default:
+ err = -EINVAL;
+ break;
+ }
+
+ return err;
+}
+
+/* Get message from skb (based on rtnetlink_rcv_skb). Each message is
+ * processed by iscsi_if_recv_msg. Malformed skbs with wrong length are
+ * discarded silently. */
+static void
+iscsi_if_rx(struct sock *sk, int len)
+{
+ struct sk_buff *skb;
+
+ down(&rx_queue_sema);
+ while ((skb = skb_dequeue(&sk->sk_receive_queue)) != NULL) {
+ while (skb->len >= NLMSG_SPACE(0)) {
+ int err;
+ uint32_t rlen;
+ struct nlmsghdr *nlh;
+ struct iscsi_uevent *ev;
+
+ nlh = (struct nlmsghdr *)skb->data;
+ if (nlh->nlmsg_len < sizeof(*nlh) ||
+ skb->len < nlh->nlmsg_len) {
+ break;
+ }
+ ev = NLMSG_DATA(nlh);
+ rlen = NLMSG_ALIGN(nlh->nlmsg_len);
+ if (rlen > skb->len)
+ rlen = skb->len;
+ err = iscsi_if_recv_msg(skb, nlh);
+ if (err) {
+ ev->type = ISCSI_KEVENT_IF_ERROR;
+ ev->iferror = err;
+ }
+ do {
+ /*
+ * special case for GET_STATS:
+ * on success - sending reply and stats from
+ * inside of if_recv_msg(),
+ * on error - fall through.
+ */
+ if (ev->type == ISCSI_UEVENT_GET_STATS && !err)
+ break;
+ err = iscsi_if_send_reply(
+ NETLINK_CREDS(skb)->pid, nlh->nlmsg_seq,
+ nlh->nlmsg_type, 0, 0, ev, sizeof(*ev));
+ if (atomic_read(&z_reply.allocated) >=
+ z_reply.hiwat)
+ ev->iferror = -ENOMEM;
+ } while (err < 0 && err != -ECONNREFUSED);
+ skb_pull(skb, rlen);
+ }
+ kfree_skb(skb);
+ }
+ up(&rx_queue_sema);
+}
/*
- * iSCSI host attrs
+ * iSCSI connection attrs
*/
+#define iscsi_conn_int_attr_show(param, format) \
+static ssize_t \
+show_conn_int_param_##param(struct class_device *cdev, char *buf) \
+{ \
+ uint32_t value = 0; \
+ struct iscsi_if_conn *conn = iscsi_cdev_to_if_conn(cdev); \
+ struct iscsi_internal *priv; \
+ \
+ priv = to_iscsi_internal(conn->host->transportt); \
+ if (priv->param_mask & (1 << param)) \
+ priv->iscsi_transport->get_param(conn->connh, param, &value); \
+ return snprintf(buf, 20, format"\n", value); \
+}
+
+#define iscsi_conn_int_attr(field, param, format) \
+ iscsi_conn_int_attr_show(param, format) \
+static CLASS_DEVICE_ATTR(field, S_IRUGO, show_conn_int_param_##param, NULL);
+
+iscsi_conn_int_attr(max_recv_dlength, ISCSI_PARAM_MAX_RECV_DLENGTH, "%u");
+iscsi_conn_int_attr(max_xmit_dlength, ISCSI_PARAM_MAX_XMIT_DLENGTH, "%u");
+iscsi_conn_int_attr(header_digest, ISCSI_PARAM_HDRDGST_EN, "%d");
+iscsi_conn_int_attr(data_digest, ISCSI_PARAM_DATADGST_EN, "%d");
+iscsi_conn_int_attr(ifmarker, ISCSI_PARAM_IFMARKER_EN, "%d");
+iscsi_conn_int_attr(ofmarker, ISCSI_PARAM_OFMARKER_EN, "%d");
/*
- * Again, this is used for iSCSI names. Normally, we follow
- * the transport class convention of having the lld set
- * the field, but in these cases the value is too large.
+ * iSCSI session attrs
*/
-#define iscsi_host_show_str_fn(field) \
- \
+#define iscsi_session_int_attr_show(param, format) \
static ssize_t \
-show_host_str_##field(struct class_device *cdev, char *buf) \
+show_session_int_param_##param(struct class_device *cdev, char *buf) \
{ \
- int ret = 0; \
- struct Scsi_Host *shost = transport_class_to_shost(cdev); \
- struct iscsi_internal *i = to_iscsi_internal(shost->transportt); \
+ uint32_t value = 0; \
+ struct iscsi_if_session *session = iscsi_cdev_to_if_session(cdev); \
+ struct Scsi_Host *shost = iscsi_if_session_to_shost(session); \
+ struct iscsi_internal *priv = to_iscsi_internal(shost->transportt); \
+ struct iscsi_if_conn *conn = NULL; \
+ unsigned long flags; \
+ \
+ spin_lock_irqsave(&connlock, flags); \
+ if (!list_empty(&session->connections)) \
+ conn = list_entry(session->connections.next, \
+ struct iscsi_if_conn, session_list); \
+ spin_unlock_irqrestore(&connlock, flags); \
\
- if (i->fnt->get_##field) \
- ret = i->fnt->get_##field(shost, buf, PAGE_SIZE); \
- return ret; \
+ if (conn && (priv->param_mask & (1 << param))) \
+ priv->iscsi_transport->get_param(conn->connh, param, &value);\
+ return snprintf(buf, 20, format"\n", value); \
}
-#define iscsi_host_rd_str_attr(field) \
- iscsi_host_show_str_fn(field) \
-static CLASS_DEVICE_ATTR(field, S_IRUGO, show_host_str_##field, NULL);
+#define iscsi_session_int_attr(field, param, format) \
+ iscsi_session_int_attr_show(param, format) \
+static CLASS_DEVICE_ATTR(field, S_IRUGO, show_session_int_param_##param, NULL);
-iscsi_host_rd_str_attr(initiator_name);
-iscsi_host_rd_str_attr(initiator_alias);
+iscsi_session_int_attr(initial_r2t, ISCSI_PARAM_INITIAL_R2T_EN, "%d");
+iscsi_session_int_attr(max_outstanding_r2t, ISCSI_PARAM_MAX_R2T, "%hu");
+iscsi_session_int_attr(immediate_data, ISCSI_PARAM_IMM_DATA_EN, "%d");
+iscsi_session_int_attr(first_burst_len, ISCSI_PARAM_FIRST_BURST, "%u");
+iscsi_session_int_attr(max_burst_len, ISCSI_PARAM_MAX_BURST, "%u");
+iscsi_session_int_attr(data_pdu_in_order, ISCSI_PARAM_PDU_INORDER_EN, "%d");
+iscsi_session_int_attr(data_seq_in_order, ISCSI_PARAM_DATASEQ_INORDER_EN, "%d");
+iscsi_session_int_attr(erl, ISCSI_PARAM_ERL, "%d");
-#define SETUP_SESSION_RD_ATTR(field) \
- if (i->fnt->show_##field) { \
- i->session_attrs[count] = &class_device_attr_##field; \
+#define SETUP_SESSION_RD_ATTR(field, param) \
+ if (priv->param_mask & (1 << param)) { \
+ priv->session_attrs[count] = &class_device_attr_##field;\
count++; \
}
-#define SETUP_HOST_RD_ATTR(field) \
- if (i->fnt->show_##field) { \
- i->host_attrs[count] = &class_device_attr_##field; \
+#define SETUP_CONN_RD_ATTR(field, param) \
+ if (priv->param_mask & (1 << param)) { \
+ priv->conn_attrs[count] = &class_device_attr_##field; \
count++; \
}
-static int iscsi_host_match(struct attribute_container *cont,
- struct device *dev)
+static int iscsi_is_session_dev(const struct device *dev)
+{
+ return dev->release == iscsi_if_session_dev_release;
+}
+
+static int iscsi_session_match(struct attribute_container *cont,
+ struct device *dev)
{
+ struct iscsi_if_session *session;
struct Scsi_Host *shost;
- struct iscsi_internal *i;
+ struct iscsi_internal *priv;
+
+ if (!iscsi_is_session_dev(dev))
+ return 0;
- if (!scsi_is_host_device(dev))
+ session = iscsi_dev_to_if_session(dev);
+ shost = iscsi_if_session_to_shost(session);
+ if (!shost->transportt)
return 0;
- shost = dev_to_shost(dev);
- if (!shost->transportt || shost->transportt->host_attrs.ac.class
- != &iscsi_host_class.class)
+ priv = to_iscsi_internal(shost->transportt);
+ if (priv->session_cont.ac.class != &iscsi_session_class.class)
return 0;
- i = to_iscsi_internal(shost->transportt);
-
- return &i->t.host_attrs.ac == cont;
+ return &priv->session_cont.ac == cont;
}
-static int iscsi_target_match(struct attribute_container *cont,
- struct device *dev)
+static int iscsi_is_conn_dev(const struct device *dev)
{
+ return dev->release == iscsi_if_conn_dev_release;
+}
+
+static int iscsi_conn_match(struct attribute_container *cont,
+ struct device *dev)
+{
+ struct iscsi_if_conn *conn;
struct Scsi_Host *shost;
- struct iscsi_internal *i;
+ struct iscsi_internal *priv;
- if (!scsi_is_target_device(dev))
+ if (!iscsi_is_conn_dev(dev))
return 0;
- shost = dev_to_shost(dev->parent);
- if (!shost->transportt || shost->transportt->host_attrs.ac.class
- != &iscsi_host_class.class)
+ conn = iscsi_dev_to_if_conn(dev);
+ shost = conn->host;
+ if (!shost->transportt)
return 0;
- i = to_iscsi_internal(shost->transportt);
-
- return &i->t.target_attrs.ac == cont;
-}
-
-struct scsi_transport_template *
-iscsi_attach_transport(struct iscsi_function_template *fnt)
-{
- struct iscsi_internal *i = kmalloc(sizeof(struct iscsi_internal),
- GFP_KERNEL);
- int count = 0;
-
- if (unlikely(!i))
- return NULL;
-
- memset(i, 0, sizeof(struct iscsi_internal));
- i->fnt = fnt;
-
- i->t.target_attrs.ac.attrs = &i->session_attrs[0];
- i->t.target_attrs.ac.class = &iscsi_transport_class.class;
- i->t.target_attrs.ac.match = iscsi_target_match;
- transport_container_register(&i->t.target_attrs);
- i->t.target_size = sizeof(struct iscsi_class_session);
-
- SETUP_SESSION_RD_ATTR(tsih);
- SETUP_SESSION_RD_ATTR(isid);
- SETUP_SESSION_RD_ATTR(header_digest);
- SETUP_SESSION_RD_ATTR(data_digest);
- SETUP_SESSION_RD_ATTR(target_name);
- SETUP_SESSION_RD_ATTR(target_alias);
- SETUP_SESSION_RD_ATTR(port);
- SETUP_SESSION_RD_ATTR(tpgt);
- SETUP_SESSION_RD_ATTR(ip_address);
- SETUP_SESSION_RD_ATTR(initial_r2t);
- SETUP_SESSION_RD_ATTR(immediate_data);
- SETUP_SESSION_RD_ATTR(max_recv_data_segment_len);
- SETUP_SESSION_RD_ATTR(max_burst_len);
- SETUP_SESSION_RD_ATTR(first_burst_len);
- SETUP_SESSION_RD_ATTR(def_time2wait);
- SETUP_SESSION_RD_ATTR(def_time2retain);
- SETUP_SESSION_RD_ATTR(max_outstanding_r2t);
- SETUP_SESSION_RD_ATTR(data_pdu_in_order);
- SETUP_SESSION_RD_ATTR(data_sequence_in_order);
- SETUP_SESSION_RD_ATTR(erl);
+ priv = to_iscsi_internal(shost->transportt);
+ if (priv->conn_cont.ac.class != &iscsi_connection_class.class)
+ return 0;
- BUG_ON(count > ISCSI_SESSION_ATTRS);
- i->session_attrs[count] = NULL;
+ return &priv->conn_cont.ac == cont;
+}
+
+int iscsi_register_transport(struct iscsi_transport *tt)
+{
+ struct iscsi_internal *priv;
+ unsigned long flags;
+ int count = 0, err;
+
+ BUG_ON(!tt);
+
+ priv = iscsi_if_transport_lookup(tt);
+ if (priv)
+ return -EEXIST;
+
+ priv = kmalloc(sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+ memset(priv, 0, sizeof(*priv));
+ INIT_LIST_HEAD(&priv->list);
+ INIT_LIST_HEAD(&priv->sessions);
+ spin_lock_init(&priv->session_lock);
+ priv->iscsi_transport = tt;
+
+ priv->cdev.class = &iscsi_transport_class;
+ snprintf(priv->cdev.class_id, BUS_ID_SIZE, "%s", tt->name);
+ err = class_device_register(&priv->cdev);
+ if (err)
+ goto free_priv;
+
+ err = sysfs_create_group(&priv->cdev.kobj, &iscsi_transport_group);
+ if (err)
+ goto unregister_cdev;
+
+ /* setup parameters mask */
+ priv->param_mask = 0xFFFFFFFF;
+ if (!(tt->caps & CAP_MULTI_R2T))
+ priv->param_mask &= ~(1 << ISCSI_PARAM_MAX_R2T);
+ if (!(tt->caps & CAP_HDRDGST))
+ priv->param_mask &= ~(1 << ISCSI_PARAM_HDRDGST_EN);
+ if (!(tt->caps & CAP_DATADGST))
+ priv->param_mask &= ~(1 << ISCSI_PARAM_DATADGST_EN);
+ if (!(tt->caps & CAP_MARKERS)) {
+ priv->param_mask &= ~(1 << ISCSI_PARAM_IFMARKER_EN);
+ priv->param_mask &= ~(1 << ISCSI_PARAM_OFMARKER_EN);
+ }
- i->t.host_attrs.ac.attrs = &i->host_attrs[0];
- i->t.host_attrs.ac.class = &iscsi_host_class.class;
- i->t.host_attrs.ac.match = iscsi_host_match;
- transport_container_register(&i->t.host_attrs);
- i->t.host_size = 0;
+ /* connection parameters */
+ priv->conn_cont.ac.attrs = &priv->conn_attrs[0];
+ priv->conn_cont.ac.class = &iscsi_connection_class.class;
+ priv->conn_cont.ac.match = iscsi_conn_match;
+ transport_container_register(&priv->conn_cont);
+ SETUP_CONN_RD_ATTR(max_recv_dlength, ISCSI_PARAM_MAX_RECV_DLENGTH);
+ SETUP_CONN_RD_ATTR(max_xmit_dlength, ISCSI_PARAM_MAX_XMIT_DLENGTH);
+ SETUP_CONN_RD_ATTR(header_digest, ISCSI_PARAM_HDRDGST_EN);
+ SETUP_CONN_RD_ATTR(data_digest, ISCSI_PARAM_DATADGST_EN);
+ SETUP_CONN_RD_ATTR(ifmarker, ISCSI_PARAM_IFMARKER_EN);
+ SETUP_CONN_RD_ATTR(ofmarker, ISCSI_PARAM_OFMARKER_EN);
+
+ BUG_ON(count > ISCSI_CONN_ATTRS);
+ priv->conn_attrs[count] = NULL;
count = 0;
- SETUP_HOST_RD_ATTR(initiator_name);
- SETUP_HOST_RD_ATTR(initiator_alias);
- BUG_ON(count > ISCSI_HOST_ATTRS);
- i->host_attrs[count] = NULL;
+ /* session parameters */
+ priv->session_cont.ac.attrs = &priv->session_attrs[0];
+ priv->session_cont.ac.class = &iscsi_session_class.class;
+ priv->session_cont.ac.match = iscsi_session_match;
+ transport_container_register(&priv->session_cont);
+
+ SETUP_SESSION_RD_ATTR(initial_r2t, ISCSI_PARAM_INITIAL_R2T_EN);
+ SETUP_SESSION_RD_ATTR(max_outstanding_r2t, ISCSI_PARAM_MAX_R2T);
+ SETUP_SESSION_RD_ATTR(immediate_data, ISCSI_PARAM_IMM_DATA_EN);
+ SETUP_SESSION_RD_ATTR(first_burst_len, ISCSI_PARAM_FIRST_BURST);
+ SETUP_SESSION_RD_ATTR(max_burst_len, ISCSI_PARAM_MAX_BURST);
+ SETUP_SESSION_RD_ATTR(data_pdu_in_order, ISCSI_PARAM_PDU_INORDER_EN);
+ SETUP_SESSION_RD_ATTR(data_seq_in_order,ISCSI_PARAM_DATASEQ_INORDER_EN)
+ SETUP_SESSION_RD_ATTR(erl, ISCSI_PARAM_ERL);
+
+ BUG_ON(count > ISCSI_SESSION_ATTRS);
+ priv->session_attrs[count] = NULL;
+
+ spin_lock_irqsave(&iscsi_transport_lock, flags);
+ list_add(&priv->list, &iscsi_transports);
+ spin_unlock_irqrestore(&iscsi_transport_lock, flags);
+
+ printk(KERN_NOTICE "iscsi: registered transport (%s)\n", tt->name);
+ return 0;
- return &i->t;
+unregister_cdev:
+ class_device_unregister(&priv->cdev);
+free_priv:
+ kfree(priv);
+ return err;
}
+EXPORT_SYMBOL_GPL(iscsi_register_transport);
+
+int iscsi_unregister_transport(struct iscsi_transport *tt)
+{
+ struct iscsi_internal *priv;
+ unsigned long flags;
+
+ BUG_ON(!tt);
+
+ down(&rx_queue_sema);
+
+ priv = iscsi_if_transport_lookup(tt);
+ BUG_ON (!priv);
+
+ spin_lock_irqsave(&priv->session_lock, flags);
+ if (!list_empty(&priv->sessions)) {
+ spin_unlock_irqrestore(&priv->session_lock, flags);
+ up(&rx_queue_sema);
+ return -EPERM;
+ }
+ spin_unlock_irqrestore(&priv->session_lock, flags);
+
+ spin_lock_irqsave(&iscsi_transport_lock, flags);
+ list_del(&priv->list);
+ spin_unlock_irqrestore(&iscsi_transport_lock, flags);
+
+ transport_container_unregister(&priv->conn_cont);
+ transport_container_unregister(&priv->session_cont);
+
+ sysfs_remove_group(&priv->cdev.kobj, &iscsi_transport_group);
+ class_device_unregister(&priv->cdev);
+ up(&rx_queue_sema);
-EXPORT_SYMBOL(iscsi_attach_transport);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(iscsi_unregister_transport);
-void iscsi_release_transport(struct scsi_transport_template *t)
+static int
+iscsi_rcv_nl_event(struct notifier_block *this, unsigned long event, void *ptr)
{
- struct iscsi_internal *i = to_iscsi_internal(t);
+ struct netlink_notify *n = ptr;
+
+ if (event == NETLINK_URELEASE &&
+ n->protocol == NETLINK_ISCSI && n->pid) {
+ struct iscsi_if_conn *conn;
+ unsigned long flags;
+
+ mempool_zone_complete(&z_reply);
+ spin_lock_irqsave(&connlock, flags);
+ list_for_each_entry(conn, &connlist, conn_list) {
+ mempool_zone_complete(&conn->z_error);
+ mempool_zone_complete(&conn->z_pdu);
+ }
+ spin_unlock_irqrestore(&connlock, flags);
+ }
- transport_container_unregister(&i->t.target_attrs);
- transport_container_unregister(&i->t.host_attrs);
-
- kfree(i);
+ return NOTIFY_DONE;
}
-EXPORT_SYMBOL(iscsi_release_transport);
+static struct notifier_block iscsi_nl_notifier = {
+ .notifier_call = iscsi_rcv_nl_event,
+};
static __init int iscsi_transport_init(void)
{
- int err = transport_class_register(&iscsi_transport_class);
+ int err;
+ err = class_register(&iscsi_transport_class);
if (err)
return err;
- return transport_class_register(&iscsi_host_class);
+
+ err = transport_class_register(&iscsi_connection_class);
+ if (err)
+ goto unregister_transport_class;
+
+ err = transport_class_register(&iscsi_session_class);
+ if (err)
+ goto unregister_conn_class;
+
+ err = netlink_register_notifier(&iscsi_nl_notifier);
+ if (err)
+ goto unregister_session_class;
+
+ nls = netlink_kernel_create(NETLINK_ISCSI, 1, iscsi_if_rx,
+ THIS_MODULE);
+ if (!nls) {
+ err = -ENOBUFS;
+ goto unregister_notifier;
+ }
+
+ err = mempool_zone_init(&z_reply, Z_MAX_REPLY,
+ NLMSG_SPACE(sizeof(struct iscsi_uevent)), Z_HIWAT_REPLY);
+ if (!err)
+ return 0;
+
+ sock_release(nls->sk_socket);
+unregister_notifier:
+ netlink_unregister_notifier(&iscsi_nl_notifier);
+unregister_session_class:
+ transport_class_unregister(&iscsi_session_class);
+unregister_conn_class:
+ transport_class_unregister(&iscsi_connection_class);
+unregister_transport_class:
+ class_unregister(&iscsi_transport_class);
+ return err;
}
static void __exit iscsi_transport_exit(void)
{
- transport_class_unregister(&iscsi_host_class);
- transport_class_unregister(&iscsi_transport_class);
+ mempool_destroy(z_reply.pool);
+ sock_release(nls->sk_socket);
+ netlink_unregister_notifier(&iscsi_nl_notifier);
+ transport_class_unregister(&iscsi_connection_class);
+ transport_class_unregister(&iscsi_session_class);
+ class_unregister(&iscsi_transport_class);
}
module_init(iscsi_transport_init);
module_exit(iscsi_transport_exit);
-MODULE_AUTHOR("Mike Christie");
-MODULE_DESCRIPTION("iSCSI Transport Attributes");
+MODULE_AUTHOR("Mike Christie <michaelc@cs.wisc.edu>, "
+ "Dmitry Yusupov <dmitry_yus@yahoo.com>, "
+ "Alex Aizman <itn780@yahoo.com>");
+MODULE_DESCRIPTION("iSCSI Transport Interface");
MODULE_LICENSE("GPL");
diff --git a/drivers/scsi/scsi_transport_sas.c b/drivers/scsi/scsi_transport_sas.c
index 1d145d2f9a38..edabbd05d258 100644
--- a/drivers/scsi/scsi_transport_sas.c
+++ b/drivers/scsi/scsi_transport_sas.c
@@ -26,6 +26,8 @@
#include <linux/init.h>
#include <linux/module.h>
#include <linux/err.h>
+#include <linux/slab.h>
+#include <linux/string.h>
#include <scsi/scsi_device.h>
#include <scsi/scsi_host.h>
@@ -34,7 +36,7 @@
#define SAS_HOST_ATTRS 0
-#define SAS_PORT_ATTRS 11
+#define SAS_PORT_ATTRS 17
#define SAS_RPORT_ATTRS 5
struct sas_internal {
@@ -257,6 +259,29 @@ show_sas_phy_##field(struct class_device *cdev, char *buf) \
sas_phy_show_linkspeed(field) \
static CLASS_DEVICE_ATTR(field, S_IRUGO, show_sas_phy_##field, NULL)
+#define sas_phy_show_linkerror(field) \
+static ssize_t \
+show_sas_phy_##field(struct class_device *cdev, char *buf) \
+{ \
+ struct sas_phy *phy = transport_class_to_phy(cdev); \
+ struct Scsi_Host *shost = dev_to_shost(phy->dev.parent); \
+ struct sas_internal *i = to_sas_internal(shost->transportt); \
+ int error; \
+ \
+ if (!phy->local_attached) \
+ return -EINVAL; \
+ \
+ error = i->f->get_linkerrors(phy); \
+ if (error) \
+ return error; \
+ return snprintf(buf, 20, "%u\n", phy->field); \
+}
+
+#define sas_phy_linkerror_attr(field) \
+ sas_phy_show_linkerror(field) \
+static CLASS_DEVICE_ATTR(field, S_IRUGO, show_sas_phy_##field, NULL)
+
+
static ssize_t
show_sas_device_type(struct class_device *cdev, char *buf)
{
@@ -266,9 +291,39 @@ show_sas_device_type(struct class_device *cdev, char *buf)
return snprintf(buf, 20, "none\n");
return get_sas_device_type_names(phy->identify.device_type, buf);
}
-
static CLASS_DEVICE_ATTR(device_type, S_IRUGO, show_sas_device_type, NULL);
+static ssize_t do_sas_phy_reset(struct class_device *cdev,
+ size_t count, int hard_reset)
+{
+ struct sas_phy *phy = transport_class_to_phy(cdev);
+ struct Scsi_Host *shost = dev_to_shost(phy->dev.parent);
+ struct sas_internal *i = to_sas_internal(shost->transportt);
+ int error;
+
+ if (!phy->local_attached)
+ return -EINVAL;
+
+ error = i->f->phy_reset(phy, hard_reset);
+ if (error)
+ return error;
+ return count;
+};
+
+static ssize_t store_sas_link_reset(struct class_device *cdev,
+ const char *buf, size_t count)
+{
+ return do_sas_phy_reset(cdev, count, 0);
+}
+static CLASS_DEVICE_ATTR(link_reset, S_IWUSR, NULL, store_sas_link_reset);
+
+static ssize_t store_sas_hard_reset(struct class_device *cdev,
+ const char *buf, size_t count)
+{
+ return do_sas_phy_reset(cdev, count, 1);
+}
+static CLASS_DEVICE_ATTR(hard_reset, S_IWUSR, NULL, store_sas_hard_reset);
+
sas_phy_protocol_attr(identify.initiator_port_protocols,
initiator_port_protocols);
sas_phy_protocol_attr(identify.target_port_protocols,
@@ -282,6 +337,10 @@ sas_phy_linkspeed_attr(minimum_linkrate_hw);
sas_phy_linkspeed_attr(minimum_linkrate);
sas_phy_linkspeed_attr(maximum_linkrate_hw);
sas_phy_linkspeed_attr(maximum_linkrate);
+sas_phy_linkerror_attr(invalid_dword_count);
+sas_phy_linkerror_attr(running_disparity_error_count);
+sas_phy_linkerror_attr(loss_of_dword_sync_count);
+sas_phy_linkerror_attr(phy_reset_problem_count);
static DECLARE_TRANSPORT_CLASS(sas_phy_class,
@@ -698,6 +757,13 @@ static struct device *sas_target_parent(struct Scsi_Host *shost,
i->phy_attrs[count] = &i->private_phy_attrs[count]; \
count++
+#define SETUP_PORT_ATTRIBUTE_WRONLY(field) \
+ i->private_phy_attrs[count] = class_device_attr_##field; \
+ i->private_phy_attrs[count].attr.mode = S_IWUGO; \
+ i->private_phy_attrs[count].show = NULL; \
+ i->phy_attrs[count] = &i->private_phy_attrs[count]; \
+ count++
+
/**
* sas_attach_transport -- instantiate SAS transport template
@@ -749,6 +815,13 @@ sas_attach_transport(struct sas_function_template *ft)
SETUP_PORT_ATTRIBUTE(minimum_linkrate);
SETUP_PORT_ATTRIBUTE(maximum_linkrate_hw);
SETUP_PORT_ATTRIBUTE(maximum_linkrate);
+
+ SETUP_PORT_ATTRIBUTE(invalid_dword_count);
+ SETUP_PORT_ATTRIBUTE(running_disparity_error_count);
+ SETUP_PORT_ATTRIBUTE(loss_of_dword_sync_count);
+ SETUP_PORT_ATTRIBUTE(phy_reset_problem_count);
+ SETUP_PORT_ATTRIBUTE_WRONLY(link_reset);
+ SETUP_PORT_ATTRIBUTE_WRONLY(hard_reset);
i->phy_attrs[count] = NULL;
count = 0;
diff --git a/drivers/scsi/scsi_transport_spi.c b/drivers/scsi/scsi_transport_spi.c
index ef577c8c2182..718a2bc4ed5e 100644
--- a/drivers/scsi/scsi_transport_spi.c
+++ b/drivers/scsi/scsi_transport_spi.c
@@ -33,8 +33,6 @@
#include <scsi/scsi_transport.h>
#include <scsi/scsi_transport_spi.h>
-#define SPI_PRINTK(x, l, f, a...) dev_printk(l, &(x)->dev, f , ##a)
-
#define SPI_NUM_ATTRS 14 /* increase this if you add attributes */
#define SPI_OTHER_ATTRS 1 /* Increase this if you add "always
* on" attributes */
@@ -618,7 +616,7 @@ spi_dv_device_echo_buffer(struct scsi_device *sdev, u8 *buffer,
return SPI_COMPARE_SKIP_TEST;
- SPI_PRINTK(sdev->sdev_target, KERN_ERR, "Write Buffer failure %x\n", result);
+ sdev_printk(KERN_ERR, sdev, "Write Buffer failure %x\n", result);
return SPI_COMPARE_FAILURE;
}
@@ -702,10 +700,10 @@ spi_dv_retrain(struct scsi_device *sdev, u8 *buffer, u8 *ptr,
* IU, then QAS (if we can control them), then finally
* fall down the periods */
if (i->f->set_iu && spi_iu(starget)) {
- SPI_PRINTK(starget, KERN_ERR, "Domain Validation Disabing Information Units\n");
+ starget_printk(KERN_ERR, starget, "Domain Validation Disabing Information Units\n");
DV_SET(iu, 0);
} else if (i->f->set_qas && spi_qas(starget)) {
- SPI_PRINTK(starget, KERN_ERR, "Domain Validation Disabing Quick Arbitration and Selection\n");
+ starget_printk(KERN_ERR, starget, "Domain Validation Disabing Quick Arbitration and Selection\n");
DV_SET(qas, 0);
} else {
newperiod = spi_period(starget);
@@ -717,11 +715,11 @@ spi_dv_retrain(struct scsi_device *sdev, u8 *buffer, u8 *ptr,
if (unlikely(period > 0xff || period == prevperiod)) {
/* Total failure; set to async and return */
- SPI_PRINTK(starget, KERN_ERR, "Domain Validation Failure, dropping back to Asynchronous\n");
+ starget_printk(KERN_ERR, starget, "Domain Validation Failure, dropping back to Asynchronous\n");
DV_SET(offset, 0);
return SPI_COMPARE_FAILURE;
}
- SPI_PRINTK(starget, KERN_ERR, "Domain Validation detected failure, dropping back\n");
+ starget_printk(KERN_ERR, starget, "Domain Validation detected failure, dropping back\n");
DV_SET(period, period);
prevperiod = period;
}
@@ -788,7 +786,7 @@ spi_dv_device_internal(struct scsi_device *sdev, u8 *buffer)
if (spi_dv_device_compare_inquiry(sdev, buffer, buffer, DV_LOOPS)
!= SPI_COMPARE_SUCCESS) {
- SPI_PRINTK(starget, KERN_ERR, "Domain Validation Initial Inquiry Failed\n");
+ starget_printk(KERN_ERR, starget, "Domain Validation Initial Inquiry Failed\n");
/* FIXME: should probably offline the device here? */
return;
}
@@ -802,7 +800,7 @@ spi_dv_device_internal(struct scsi_device *sdev, u8 *buffer)
buffer + len,
DV_LOOPS)
!= SPI_COMPARE_SUCCESS) {
- SPI_PRINTK(starget, KERN_ERR, "Wide Transfers Fail\n");
+ starget_printk(KERN_ERR, starget, "Wide Transfers Fail\n");
i->f->set_width(starget, 0);
}
}
@@ -844,14 +842,14 @@ spi_dv_device_internal(struct scsi_device *sdev, u8 *buffer)
}
if (len == 0) {
- SPI_PRINTK(starget, KERN_INFO, "Domain Validation skipping write tests\n");
+ starget_printk(KERN_INFO, starget, "Domain Validation skipping write tests\n");
spi_dv_retrain(sdev, buffer, buffer + len,
spi_dv_device_compare_inquiry);
return;
}
if (len > SPI_MAX_ECHO_BUFFER_SIZE) {
- SPI_PRINTK(starget, KERN_WARNING, "Echo buffer size %d is too big, trimming to %d\n", len, SPI_MAX_ECHO_BUFFER_SIZE);
+ starget_printk(KERN_WARNING, starget, "Echo buffer size %d is too big, trimming to %d\n", len, SPI_MAX_ECHO_BUFFER_SIZE);
len = SPI_MAX_ECHO_BUFFER_SIZE;
}
@@ -902,11 +900,11 @@ spi_dv_device(struct scsi_device *sdev)
spi_dv_pending(starget) = 1;
down(&spi_dv_sem(starget));
- SPI_PRINTK(starget, KERN_INFO, "Beginning Domain Validation\n");
+ starget_printk(KERN_INFO, starget, "Beginning Domain Validation\n");
spi_dv_device_internal(sdev, buffer);
- SPI_PRINTK(starget, KERN_INFO, "Ending Domain Validation\n");
+ starget_printk(KERN_INFO, starget, "Ending Domain Validation\n");
up(&spi_dv_sem(starget));
spi_dv_pending(starget) = 0;
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 9a1dc0cea03c..bb5b242ac6b4 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -177,24 +177,38 @@ static inline struct scsi_disk *scsi_disk(struct gendisk *disk)
return container_of(disk->private_data, struct scsi_disk, driver);
}
-static struct scsi_disk *scsi_disk_get(struct gendisk *disk)
+static struct scsi_disk *__scsi_disk_get(struct gendisk *disk)
{
struct scsi_disk *sdkp = NULL;
+ if (disk->private_data) {
+ sdkp = scsi_disk(disk);
+ if (scsi_device_get(sdkp->device) == 0)
+ kref_get(&sdkp->kref);
+ else
+ sdkp = NULL;
+ }
+ return sdkp;
+}
+
+static struct scsi_disk *scsi_disk_get(struct gendisk *disk)
+{
+ struct scsi_disk *sdkp;
+
down(&sd_ref_sem);
- if (disk->private_data == NULL)
- goto out;
- sdkp = scsi_disk(disk);
- kref_get(&sdkp->kref);
- if (scsi_device_get(sdkp->device))
- goto out_put;
+ sdkp = __scsi_disk_get(disk);
up(&sd_ref_sem);
return sdkp;
+}
- out_put:
- kref_put(&sdkp->kref, scsi_disk_release);
- sdkp = NULL;
- out:
+static struct scsi_disk *scsi_disk_get_from_dev(struct device *dev)
+{
+ struct scsi_disk *sdkp;
+
+ down(&sd_ref_sem);
+ sdkp = dev_get_drvdata(dev);
+ if (sdkp)
+ sdkp = __scsi_disk_get(sdkp->disk);
up(&sd_ref_sem);
return sdkp;
}
@@ -716,16 +730,17 @@ static int sd_sync_cache(struct scsi_device *sdp)
static int sd_issue_flush(struct device *dev, sector_t *error_sector)
{
+ int ret = 0;
struct scsi_device *sdp = to_scsi_device(dev);
- struct scsi_disk *sdkp = dev_get_drvdata(dev);
+ struct scsi_disk *sdkp = scsi_disk_get_from_dev(dev);
if (!sdkp)
return -ENODEV;
- if (!sdkp->WCE)
- return 0;
-
- return sd_sync_cache(sdp);
+ if (sdkp->WCE)
+ ret = sd_sync_cache(sdp);
+ scsi_disk_put(sdkp);
+ return ret;
}
static void sd_end_flush(request_queue_t *q, struct request *flush_rq)
@@ -754,23 +769,30 @@ static void sd_end_flush(request_queue_t *q, struct request *flush_rq)
static int sd_prepare_flush(request_queue_t *q, struct request *rq)
{
struct scsi_device *sdev = q->queuedata;
- struct scsi_disk *sdkp = dev_get_drvdata(&sdev->sdev_gendev);
-
- if (sdkp->WCE) {
- memset(rq->cmd, 0, sizeof(rq->cmd));
- rq->flags |= REQ_BLOCK_PC | REQ_SOFTBARRIER;
- rq->timeout = SD_TIMEOUT;
- rq->cmd[0] = SYNCHRONIZE_CACHE;
- return 1;
+ struct scsi_disk *sdkp = scsi_disk_get_from_dev(&sdev->sdev_gendev);
+ int ret = 0;
+
+ if (sdkp) {
+ if (sdkp->WCE) {
+ memset(rq->cmd, 0, sizeof(rq->cmd));
+ rq->flags |= REQ_BLOCK_PC | REQ_SOFTBARRIER;
+ rq->timeout = SD_TIMEOUT;
+ rq->cmd[0] = SYNCHRONIZE_CACHE;
+ ret = 1;
+ }
+ scsi_disk_put(sdkp);
}
-
- return 0;
+ return ret;
}
static void sd_rescan(struct device *dev)
{
- struct scsi_disk *sdkp = dev_get_drvdata(dev);
- sd_revalidate_disk(sdkp->disk);
+ struct scsi_disk *sdkp = scsi_disk_get_from_dev(dev);
+
+ if (sdkp) {
+ sd_revalidate_disk(sdkp->disk);
+ scsi_disk_put(sdkp);
+ }
}
@@ -1253,14 +1275,13 @@ got_data:
* Jacques Gelinas (Jacques@solucorp.qc.ca)
*/
int hard_sector = sector_size;
- sector_t sz = sdkp->capacity * (hard_sector/256);
+ sector_t sz = (sdkp->capacity/2) * (hard_sector/256);
request_queue_t *queue = sdp->request_queue;
- sector_t mb;
+ sector_t mb = sz;
blk_queue_hardsect_size(queue, hard_sector);
/* avoid 64-bit division on 32-bit platforms */
- mb = sz >> 1;
- sector_div(sz, 1250);
+ sector_div(sz, 625);
mb -= sz - 974;
sector_div(mb, 1950);
@@ -1535,8 +1556,8 @@ static int sd_probe(struct device *dev)
if (sdp->type != TYPE_DISK && sdp->type != TYPE_MOD && sdp->type != TYPE_RBC)
goto out;
- SCSI_LOG_HLQUEUE(3, printk("sd_attach: scsi device: <%d,%d,%d,%d>\n",
- sdp->host->host_no, sdp->channel, sdp->id, sdp->lun));
+ SCSI_LOG_HLQUEUE(3, sdev_printk(KERN_INFO, sdp,
+ "sd_attach\n"));
error = -ENOMEM;
sdkp = kmalloc(sizeof(*sdkp), GFP_KERNEL);
@@ -1562,6 +1583,7 @@ static int sd_probe(struct device *dev)
if (error)
goto out_put;
+ get_device(&sdp->sdev_gendev);
sdkp->device = sdp;
sdkp->driver = &sd_template;
sdkp->disk = gd;
@@ -1608,10 +1630,8 @@ static int sd_probe(struct device *dev)
dev_set_drvdata(dev, sdkp);
add_disk(gd);
- printk(KERN_NOTICE "Attached scsi %sdisk %s at scsi%d, channel %d, "
- "id %d, lun %d\n", sdp->removable ? "removable " : "",
- gd->disk_name, sdp->host->host_no, sdp->channel,
- sdp->id, sdp->lun);
+ sdev_printk(KERN_NOTICE, sdp, "Attached scsi %sdisk %s\n",
+ sdp->removable ? "removable " : "", gd->disk_name);
return 0;
@@ -1640,7 +1660,9 @@ static int sd_remove(struct device *dev)
del_gendisk(sdkp->disk);
sd_shutdown(dev);
+
down(&sd_ref_sem);
+ dev_set_drvdata(dev, NULL);
kref_put(&sdkp->kref, scsi_disk_release);
up(&sd_ref_sem);
@@ -1666,8 +1688,8 @@ static void scsi_disk_release(struct kref *kref)
spin_unlock(&sd_index_lock);
disk->private_data = NULL;
-
put_disk(disk);
+ put_device(&sdkp->device->sdev_gendev);
kfree(sdkp);
}
@@ -1680,18 +1702,18 @@ static void scsi_disk_release(struct kref *kref)
static void sd_shutdown(struct device *dev)
{
struct scsi_device *sdp = to_scsi_device(dev);
- struct scsi_disk *sdkp = dev_get_drvdata(dev);
+ struct scsi_disk *sdkp = scsi_disk_get_from_dev(dev);
if (!sdkp)
return; /* this can happen */
- if (!sdkp->WCE)
- return;
-
- printk(KERN_NOTICE "Synchronizing SCSI cache for disk %s: \n",
- sdkp->disk->disk_name);
- sd_sync_cache(sdp);
-}
+ if (sdkp->WCE) {
+ printk(KERN_NOTICE "Synchronizing SCSI cache for disk %s: \n",
+ sdkp->disk->disk_name);
+ sd_sync_cache(sdp);
+ }
+ scsi_disk_put(sdkp);
+}
/**
* init_sd - entry point for this driver (both when built in or when
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index ad94367df430..72ec59456e69 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -49,6 +49,7 @@ static int sg_version_num = 30533; /* 2 digits for each component */
#include <linux/seq_file.h>
#include <linux/blkdev.h>
#include <linux/delay.h>
+#include <linux/scatterlist.h>
#include "scsi.h"
#include <scsi/scsi_dbg.h>
@@ -67,10 +68,6 @@ static int sg_proc_init(void);
static void sg_proc_cleanup(void);
#endif
-#ifndef LINUX_VERSION_CODE
-#include <linux/version.h>
-#endif /* LINUX_VERSION_CODE */
-
#define SG_ALLOW_DIO_DEF 0
#define SG_ALLOW_DIO_CODE /* compile out by commenting this define */
@@ -104,8 +101,8 @@ static int sg_allow_dio = SG_ALLOW_DIO_DEF;
#define SG_DEV_ARR_LUMP 32 /* amount to over allocate sg_dev_arr by */
-static int sg_add(struct class_device *);
-static void sg_remove(struct class_device *);
+static int sg_add(struct class_device *, struct class_interface *);
+static void sg_remove(struct class_device *, struct class_interface *);
static Scsi_Request *dummy_cmdp; /* only used for sizeof */
@@ -475,8 +472,7 @@ sg_read(struct file *filp, char __user *buf, size_t count, loff_t * ppos)
sg_finish_rem_req(srp);
retval = count;
free_old_hdr:
- if (old_hdr)
- kfree(old_hdr);
+ kfree(old_hdr);
return retval;
}
@@ -1497,16 +1493,15 @@ static int sg_alloc(struct gendisk *disk, struct scsi_device *scsidp)
overflow:
write_unlock_irqrestore(&sg_dev_arr_lock, iflags);
- printk(KERN_WARNING
- "Unable to attach sg device <%d, %d, %d, %d> type=%d, minor "
- "number exceeds %d\n", scsidp->host->host_no, scsidp->channel,
- scsidp->id, scsidp->lun, scsidp->type, SG_MAX_DEVS - 1);
+ sdev_printk(KERN_WARNING, scsidp,
+ "Unable to attach sg device type=%d, minor "
+ "number exceeds %d\n", scsidp->type, SG_MAX_DEVS - 1);
error = -ENODEV;
goto out;
}
static int
-sg_add(struct class_device *cl_dev)
+sg_add(struct class_device *cl_dev, struct class_interface *cl_intf)
{
struct scsi_device *scsidp = to_scsi_device(cl_dev->dev);
struct gendisk *disk;
@@ -1550,7 +1545,7 @@ sg_add(struct class_device *cl_dev)
if (sg_sysfs_valid) {
struct class_device * sg_class_member;
- sg_class_member = class_device_create(sg_sysfs_class,
+ sg_class_member = class_device_create(sg_sysfs_class, NULL,
MKDEV(SCSI_GENERIC_MAJOR, k),
cl_dev->dev, "%s",
disk->disk_name);
@@ -1566,11 +1561,8 @@ sg_add(struct class_device *cl_dev)
} else
printk(KERN_WARNING "sg_add: sg_sys INvalid\n");
- printk(KERN_NOTICE
- "Attached scsi generic sg%d at scsi%d, channel"
- " %d, id %d, lun %d, type %d\n", k,
- scsidp->host->host_no, scsidp->channel, scsidp->id,
- scsidp->lun, scsidp->type);
+ sdev_printk(KERN_NOTICE, scsidp,
+ "Attached scsi generic sg%d type %d\n", k,scsidp->type);
return 0;
@@ -1582,7 +1574,7 @@ out:
}
static void
-sg_remove(struct class_device *cl_dev)
+sg_remove(struct class_device *cl_dev, struct class_interface *cl_intf)
{
struct scsi_device *scsidp = to_scsi_device(cl_dev->dev);
Sg_device *sdp = NULL;
@@ -1706,10 +1698,8 @@ exit_sg(void)
sg_sysfs_valid = 0;
unregister_chrdev_region(MKDEV(SCSI_GENERIC_MAJOR, 0),
SG_MAX_DEVS);
- if (sg_dev_arr != NULL) {
- kfree((char *) sg_dev_arr);
- sg_dev_arr = NULL;
- }
+ kfree((char *)sg_dev_arr);
+ sg_dev_arr = NULL;
sg_dev_max = 0;
}
@@ -1886,13 +1876,17 @@ st_unmap_user_pages(struct scatterlist *sgl, const unsigned int nr_pages,
int i;
for (i=0; i < nr_pages; i++) {
- if (dirtied && !PageReserved(sgl[i].page))
- SetPageDirty(sgl[i].page);
- /* unlock_page(sgl[i].page); */
+ struct page *page = sgl[i].page;
+
+ /* XXX: just for debug. Remove when PageReserved is removed */
+ BUG_ON(PageReserved(page));
+ if (dirtied)
+ SetPageDirty(page);
+ /* unlock_page(page); */
/* FIXME: cache flush missing for rw==READ
* FIXME: call the correct reference counting function
*/
- page_cache_release(sgl[i].page);
+ page_cache_release(page);
}
return 0;
@@ -1992,9 +1986,7 @@ sg_build_indirect(Sg_scatter_hold * schp, Sg_fd * sfp, int buff_size)
if (!p)
break;
}
- sclp->page = virt_to_page(p);
- sclp->offset = offset_in_page(p);
- sclp->length = ret_sz;
+ sg_set_buf(sclp, p, ret_sz);
SCSI_LOG_TIMEOUT(5, printk("sg_build_build: k=%d, a=0x%p, len=%d\n",
k, sg_scatg2virt(sclp), ret_sz));
@@ -2644,7 +2636,7 @@ static char *
sg_page_malloc(int rqSz, int lowDma, int *retSzp)
{
char *resp = NULL;
- int page_mask;
+ gfp_t page_mask;
int order, a_size;
int resSz = rqSz;
diff --git a/drivers/scsi/sgiwd93.c b/drivers/scsi/sgiwd93.c
index a5ba2c692752..f37147f8f7bf 100644
--- a/drivers/scsi/sgiwd93.c
+++ b/drivers/scsi/sgiwd93.c
@@ -15,7 +15,6 @@
#include <linux/types.h>
#include <linux/mm.h>
#include <linux/blkdev.h>
-#include <linux/version.h>
#include <linux/delay.h>
#include <linux/dma-mapping.h>
#include <linux/spinlock.h>
@@ -33,7 +32,6 @@
#include "scsi.h"
#include <scsi/scsi_host.h>
#include "wd33c93.h"
-#include "sgiwd93.h"
#include <linux/stat.h>
@@ -335,10 +333,10 @@ static Scsi_Host_Template driver_template = {
.eh_abort_handler = wd33c93_abort,
.eh_bus_reset_handler = sgiwd93_bus_reset,
.eh_host_reset_handler = wd33c93_host_reset,
- .can_queue = CAN_QUEUE,
+ .can_queue = 16,
.this_id = 7,
.sg_tablesize = SG_ALL,
- .cmd_per_lun = CMD_PER_LUN,
+ .cmd_per_lun = 8,
.use_clustering = DISABLE_CLUSTERING,
};
#include "scsi_module.c"
diff --git a/drivers/scsi/sgiwd93.h b/drivers/scsi/sgiwd93.h
deleted file mode 100644
index 981d0b7a85d4..000000000000
--- a/drivers/scsi/sgiwd93.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/* $Id: sgiwd93.h,v 1.5 1998/08/25 09:18:50 ralf Exp $
- * sgiwd93.h: SGI WD93 scsi definitions.
- *
- * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
- */
-#ifndef _SGIWD93_H
-#define _SGIWD93_H
-
-#ifndef CMD_PER_LUN
-#define CMD_PER_LUN 8
-#endif
-
-#ifndef CAN_QUEUE
-#define CAN_QUEUE 16
-#endif
-
-int sgiwd93_detect(Scsi_Host_Template *);
-int sgiwd93_release(struct Scsi_Host *instance);
-const char *wd33c93_info(void);
-int wd33c93_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
-int wd33c93_abort(Scsi_Cmnd *);
-int wd33c93_host_reset(Scsi_Cmnd * SCpnt);
-
-#endif /* !(_SGIWD93_H) */
diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c
index 561901b1cf11..d68cea753bb2 100644
--- a/drivers/scsi/sr.c
+++ b/drivers/scsi/sr.c
@@ -360,7 +360,7 @@ static int sr_init_command(struct scsi_cmnd * SCpnt)
}
if (s_size != 512 && s_size != 1024 && s_size != 2048) {
- printk("sr: bad sector size %d\n", s_size);
+ scmd_printk(KERN_ERR, SCpnt, "bad sector size %d\n", s_size);
return 0;
}
@@ -385,8 +385,9 @@ static int sr_init_command(struct scsi_cmnd * SCpnt)
size += sg[i].length;
if (size != SCpnt->request_bufflen && SCpnt->use_sg) {
- printk(KERN_ERR "sr: mismatch count %d, bytes %d\n",
- size, SCpnt->request_bufflen);
+ scmd_printk(KERN_ERR, SCpnt,
+ "mismatch count %d, bytes %d\n",
+ size, SCpnt->request_bufflen);
if (SCpnt->request_bufflen > size)
SCpnt->request_bufflen = SCpnt->bufflen = size;
}
@@ -397,7 +398,7 @@ static int sr_init_command(struct scsi_cmnd * SCpnt)
*/
if (((unsigned int)SCpnt->request->sector % (s_size >> 9)) ||
(SCpnt->request_bufflen % s_size)) {
- printk("sr: unaligned transfer\n");
+ scmd_printk(KERN_NOTICE, SCpnt, "unaligned transfer\n");
return 0;
}
@@ -455,7 +456,7 @@ queue:
static int sr_block_open(struct inode *inode, struct file *file)
{
struct gendisk *disk = inode->i_bdev->bd_disk;
- struct scsi_cd *cd = scsi_cd(inode->i_bdev->bd_disk);
+ struct scsi_cd *cd;
int ret = 0;
if(!(cd = scsi_cd_get(disk)))
@@ -622,10 +623,8 @@ static int sr_probe(struct device *dev)
disk->flags |= GENHD_FL_REMOVABLE;
add_disk(disk);
- printk(KERN_DEBUG
- "Attached scsi CD-ROM %s at scsi%d, channel %d, id %d, lun %d\n",
- cd->cdi.name, sdev->host->host_no, sdev->channel,
- sdev->id, sdev->lun);
+ sdev_printk(KERN_DEBUG, sdev,
+ "Attached scsi CD-ROM %s\n", cd->cdi.name);
return 0;
fail_put:
diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c
index d001c046551b..770c4324f3d5 100644
--- a/drivers/scsi/st.c
+++ b/drivers/scsi/st.c
@@ -3577,7 +3577,8 @@ static long st_compat_ioctl(struct file *file, unsigned int cmd, unsigned long a
static struct st_buffer *
new_tape_buffer(int from_initialization, int need_dma, int max_sg)
{
- int i, priority, got = 0, segs = 0;
+ int i, got = 0, segs = 0;
+ gfp_t priority;
struct st_buffer *tb;
if (from_initialization)
@@ -3610,7 +3611,8 @@ static struct st_buffer *
/* Try to allocate enough space in the tape buffer */
static int enlarge_buffer(struct st_buffer * STbuffer, int new_size, int need_dma)
{
- int segs, nbr, max_segs, b_size, priority, order, got;
+ int segs, nbr, max_segs, b_size, order, got;
+ gfp_t priority;
if (new_size <= STbuffer->buffer_size)
return 1;
@@ -3885,9 +3887,7 @@ static int st_probe(struct device *dev)
if (SDp->type != TYPE_TAPE)
return -ENODEV;
if ((stp = st_incompatible(SDp))) {
- printk(KERN_INFO
- "st: Found incompatible tape at scsi%d, channel %d, id %d, lun %d\n",
- SDp->host->host_no, SDp->channel, SDp->id, SDp->lun);
+ sdev_printk(KERN_INFO, SDp, "Found incompatible tape\n");
printk(KERN_INFO "st: The suggested driver is %s.\n", stp);
return -ENODEV;
}
@@ -4075,9 +4075,8 @@ static int st_probe(struct device *dev)
}
disk->number = devfs_register_tape(SDp->devfs_name);
- printk(KERN_WARNING
- "Attached scsi tape %s at scsi%d, channel %d, id %d, lun %d\n",
- tape_name(tpnt), SDp->host->host_no, SDp->channel, SDp->id, SDp->lun);
+ sdev_printk(KERN_WARNING, SDp,
+ "Attached scsi tape %s", tape_name(tpnt));
printk(KERN_WARNING "%s: try direct i/o: %s (alignment %d B), max page reachable by HBA %lu\n",
tape_name(tpnt), tpnt->try_dio ? "yes" : "no",
queue_dma_alignment(SDp->request_queue) + 1, tpnt->max_pfn);
@@ -4108,8 +4107,7 @@ out_free_tape:
write_unlock(&st_dev_arr_lock);
out_put_disk:
put_disk(disk);
- if (tpnt)
- kfree(tpnt);
+ kfree(tpnt);
out_buffer_free:
kfree(buffer);
out:
@@ -4375,7 +4373,7 @@ static void do_create_class_files(struct scsi_tape *STp, int dev_num, int mode)
snprintf(name, 10, "%s%s%s", rew ? "n" : "",
STp->disk->disk_name, st_formats[i]);
st_class_member =
- class_device_create(st_sysfs_class,
+ class_device_create(st_sysfs_class, NULL,
MKDEV(SCSI_TAPE_MAJOR,
TAPE_MINOR(dev_num, mode, rew)),
&STp->device->sdev_gendev, "%s", name);
@@ -4524,12 +4522,16 @@ static int sgl_unmap_user_pages(struct scatterlist *sgl, const unsigned int nr_p
int i;
for (i=0; i < nr_pages; i++) {
- if (dirtied && !PageReserved(sgl[i].page))
- SetPageDirty(sgl[i].page);
+ struct page *page = sgl[i].page;
+
+ /* XXX: just for debug. Remove when PageReserved is removed */
+ BUG_ON(PageReserved(page));
+ if (dirtied)
+ SetPageDirty(page);
/* FIXME: cache flush missing for rw==READ
* FIXME: call the correct reference counting function
*/
- page_cache_release(sgl[i].page);
+ page_cache_release(page);
}
return 0;
diff --git a/drivers/scsi/sym53c416.c b/drivers/scsi/sym53c416.c
index ef19adc67eff..93dc7b665ccf 100644
--- a/drivers/scsi/sym53c416.c
+++ b/drivers/scsi/sym53c416.c
@@ -773,7 +773,7 @@ int sym53c416_queuecommand(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
current_command->SCp.Message = 0;
spin_lock_irqsave(&sym53c416_lock, flags);
- outb(SCpnt->device->id, base + DEST_BUS_ID); /* Set scsi id target */
+ outb(scmd_id(SCpnt), base + DEST_BUS_ID); /* Set scsi id target */
outb(FLUSH_FIFO, base + COMMAND_REG); /* Flush SCSI and PIO FIFO's */
/* Write SCSI command into the SCSI fifo */
for(i = 0; i < SCpnt->cmd_len; i++)
diff --git a/drivers/scsi/sym53c8xx_2/sym_hipd.c b/drivers/scsi/sym53c8xx_2/sym_hipd.c
index e753ba27dc59..a7420cad4547 100644
--- a/drivers/scsi/sym53c8xx_2/sym_hipd.c
+++ b/drivers/scsi/sym53c8xx_2/sym_hipd.c
@@ -37,6 +37,10 @@
* 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/slab.h>
+#include <asm/param.h> /* for timeouts in units of HZ */
+
#include "sym_glue.h"
#include "sym_nvram.h"
diff --git a/drivers/scsi/sym53c8xx_2/sym_hipd.h b/drivers/scsi/sym53c8xx_2/sym_hipd.h
index 3131a6bf7ab7..3a264a408216 100644
--- a/drivers/scsi/sym53c8xx_2/sym_hipd.h
+++ b/drivers/scsi/sym53c8xx_2/sym_hipd.h
@@ -37,6 +37,8 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#include <linux/gfp.h>
+
#ifndef SYM_HIPD_H
#define SYM_HIPD_H
diff --git a/drivers/scsi/sym53c8xx_defs.h b/drivers/scsi/sym53c8xx_defs.h
index 4c4ae7d4713f..139cd0e12e62 100644
--- a/drivers/scsi/sym53c8xx_defs.h
+++ b/drivers/scsi/sym53c8xx_defs.h
@@ -281,19 +281,6 @@
#endif
/*
-** These simple macros limit expression involving
-** kernel time values (jiffies) to some that have
-** chance not to be too much incorrect. :-)
-*/
-#define ktime_get(o) (jiffies + (u_long) o)
-#define ktime_exp(b) ((long)(jiffies) - (long)(b) >= 0)
-#define ktime_dif(a, b) ((long)(a) - (long)(b))
-/* These ones are not used in this driver */
-#define ktime_add(a, o) ((a) + (u_long)(o))
-#define ktime_sub(a, o) ((a) - (u_long)(o))
-
-
-/*
* IO functions definition for big/little endian CPU support.
* For now, the NCR is only supported in little endian addressing mode,
*/
diff --git a/drivers/scsi/tmscsim.c b/drivers/scsi/tmscsim.c
index 9589c67de535..91322aff241d 100644
--- a/drivers/scsi/tmscsim.c
+++ b/drivers/scsi/tmscsim.c
@@ -988,7 +988,15 @@ din_1:
if( residual )
{
+ static int feedback_requested;
bval = DC390_read8 (ScsiFifo); /* get one residual byte */
+
+ if (!feedback_requested) {
+ feedback_requested = 1;
+ printk(KERN_WARNING "%s: Please, contact <linux-scsi@vger.kernel.org> "
+ "to help improve support for your system.\n", __FILE__);
+ }
+
ptr = (u8 *) bus_to_virt( pSRB->SGBusAddr );
*ptr = bval;
pSRB->SGBusAddr++; xferCnt++;
@@ -2077,8 +2085,8 @@ static int DC390_abort(struct scsi_cmnd *cmd)
struct dc390_acb *pACB = (struct dc390_acb*) cmd->device->host->hostdata;
struct dc390_dcb *pDCB = (struct dc390_dcb*) cmd->device->hostdata;
- printk("DC390: Abort command (pid %li, Device %02i-%02i)\n",
- cmd->pid, cmd->device->id, cmd->device->lun);
+ scmd_printk(KERN_WARNING, cmd,
+ "DC390: Abort command (pid %li)\n", cmd->pid);
/* abort() is too stupid for already sent commands at the moment.
* If it's called we are in trouble anyway, so let's dump some info
diff --git a/drivers/scsi/u14-34f.c b/drivers/scsi/u14-34f.c
index b0b6cdf02cbd..1ce29ba683eb 100644
--- a/drivers/scsi/u14-34f.c
+++ b/drivers/scsi/u14-34f.c
@@ -726,8 +726,7 @@ static int u14_34f_slave_configure(struct scsi_device *dev) {
else
link_suffix = "";
- printk("%s: scsi%d, channel %d, id %d, lun %d, cmds/lun %d%s%s.\n",
- BN(j), host->host_no, dev->channel, dev->id, dev->lun,
+ sdev_printk(KERN_INFO, dev, "cmds/lun %d%s%s.\n",
dev->queue_depth, link_suffix, tag_suffix);
return FALSE;
@@ -1319,8 +1318,8 @@ static int u14_34f_queuecommand(struct scsi_cmnd *SCpnt, void (*done)(struct scs
if (wait_on_busy(sh[j]->io_port, MAXLOOP)) {
unmap_dma(i, j);
SCpnt->host_scribble = NULL;
- printk("%s: qcomm, target %d.%d:%d, pid %ld, adapter busy.\n",
- BN(j), SCpnt->device->channel, SCpnt->device->id, SCpnt->device->lun, SCpnt->pid);
+ scmd_printk(KERN_INFO, SCpnt,
+ "qcomm, pid %ld, adapter busy.\n", SCpnt->pid);
return 1;
}
@@ -1340,14 +1339,14 @@ static int u14_34f_eh_abort(struct scsi_cmnd *SCarg) {
j = ((struct hostdata *) SCarg->device->host->hostdata)->board_number;
if (SCarg->host_scribble == NULL) {
- printk("%s: abort, target %d.%d:%d, pid %ld inactive.\n",
- BN(j), SCarg->device->channel, SCarg->device->id, SCarg->device->lun, SCarg->pid);
+ scmd_printk(KERN_INFO, SCarg, "abort, pid %ld inactive.\n",
+ SCarg->pid);
return SUCCESS;
}
i = *(unsigned int *)SCarg->host_scribble;
- printk("%s: abort, mbox %d, target %d.%d:%d, pid %ld.\n",
- BN(j), i, SCarg->device->channel, SCarg->device->id, SCarg->device->lun, SCarg->pid);
+ scmd_printk(KERN_INFO, SCarg, "abort, mbox %d, pid %ld.\n",
+ i, SCarg->pid);
if (i >= sh[j]->can_queue)
panic("%s: abort, invalid SCarg->host_scribble.\n", BN(j));
@@ -1405,8 +1404,7 @@ static int u14_34f_eh_host_reset(struct scsi_cmnd *SCarg) {
struct scsi_cmnd *SCpnt;
j = ((struct hostdata *) SCarg->device->host->hostdata)->board_number;
- printk("%s: reset, enter, target %d.%d:%d, pid %ld.\n",
- BN(j), SCarg->device->channel, SCarg->device->id, SCarg->device->lun, SCarg->pid);
+ scmd_printk(KERN_INFO, SCarg, "reset, enter, pid %ld.\n", SCarg->pid);
spin_lock_irq(sh[j]->host_lock);
@@ -1709,9 +1707,10 @@ static void flush_dev(struct scsi_device *dev, unsigned long cursec, unsigned in
k = il[n]; cpp = &HD(j)->cp[k]; SCpnt = cpp->SCpnt;
if (wait_on_busy(sh[j]->io_port, MAXLOOP)) {
- printk("%s: %s, target %d.%d:%d, pid %ld, mbox %d, adapter"\
- " busy, will abort.\n", BN(j), (ihdlr ? "ihdlr" : "qcomm"),
- SCpnt->device->channel, SCpnt->device->id, SCpnt->device->lun, SCpnt->pid, k);
+ scmd_printk(KERN_INFO, SCpnt,
+ "%s, pid %ld, mbox %d, adapter"
+ " busy, will abort.\n", (ihdlr ? "ihdlr" : "qcomm"),
+ SCpnt->pid, k);
HD(j)->cp_stat[k] = ABORTING;
continue;
}
@@ -1823,7 +1822,7 @@ static irqreturn_t ihdlr(int irq, unsigned int j) {
/* If there was a bus reset, redo operation on each target */
else if (tstatus != GOOD && SCpnt->device->type == TYPE_DISK
- && HD(j)->target_redo[SCpnt->device->id][SCpnt->device->channel])
+ && HD(j)->target_redo[scmd_id(SCpnt)][scmd_channel(SCpnt)])
status = DID_BUS_BUSY << 16;
/* Works around a flaw in scsi.c */
@@ -1836,29 +1835,28 @@ static irqreturn_t ihdlr(int irq, unsigned int j) {
status = DID_OK << 16;
if (tstatus == GOOD)
- HD(j)->target_redo[SCpnt->device->id][SCpnt->device->channel] = FALSE;
+ HD(j)->target_redo[scmd_id(SCpnt)][scmd_channel(SCpnt)] = FALSE;
if (spp->target_status && SCpnt->device->type == TYPE_DISK &&
(!(tstatus == CHECK_CONDITION && HD(j)->iocount <= 1000 &&
(SCpnt->sense_buffer[2] & 0xf) == NOT_READY)))
- printk("%s: ihdlr, target %d.%d:%d, pid %ld, "\
- "target_status 0x%x, sense key 0x%x.\n", BN(j),
- SCpnt->device->channel, SCpnt->device->id, SCpnt->device->lun,
+ scmd_printk(KERN_INFO, SCpnt,
+ "ihdlr, pid %ld, target_status 0x%x, sense key 0x%x.\n",
SCpnt->pid, spp->target_status,
SCpnt->sense_buffer[2]);
- HD(j)->target_to[SCpnt->device->id][SCpnt->device->channel] = 0;
+ HD(j)->target_to[scmd_id(SCpnt)][scmd_channel(SCpnt)] = 0;
if (HD(j)->last_retried_pid == SCpnt->pid) HD(j)->retries = 0;
break;
case ASST: /* Selection Time Out */
- if (HD(j)->target_to[SCpnt->device->id][SCpnt->device->channel] > 1)
+ if (HD(j)->target_to[scmd_id(SCpnt)][scmd_channel(SCpnt)] > 1)
status = DID_ERROR << 16;
else {
status = DID_TIME_OUT << 16;
- HD(j)->target_to[SCpnt->device->id][SCpnt->device->channel]++;
+ HD(j)->target_to[scmd_id(SCpnt)][scmd_channel(SCpnt)]++;
}
break;
@@ -1914,10 +1912,9 @@ static irqreturn_t ihdlr(int irq, unsigned int j) {
spp->adapter_status != ASST && HD(j)->iocount <= 1000) ||
do_trace || msg_byte(spp->target_status))
#endif
- printk("%s: ihdlr, mbox %2d, err 0x%x:%x,"\
- " target %d.%d:%d, pid %ld, reg 0x%x, count %d.\n",
- BN(j), i, spp->adapter_status, spp->target_status,
- SCpnt->device->channel, SCpnt->device->id, SCpnt->device->lun, SCpnt->pid,
+ scmd_printk(KERN_INFO, SCpnt, "ihdlr, mbox %2d, err 0x%x:%x,"\
+ " pid %ld, reg 0x%x, count %d.\n",
+ i, spp->adapter_status, spp->target_status, SCpnt->pid,
reg, HD(j)->iocount);
unmap_dma(i, j);
@@ -1956,11 +1953,11 @@ static int u14_34f_release(struct Scsi_Host *shpnt) {
for (j = 0; sh[j] != NULL && sh[j] != shpnt; j++);
- if (sh[j] == NULL) panic("%s: release, invalid Scsi_Host pointer.\n",
- driver_name);
+ if (sh[j] == NULL)
+ panic("%s: release, invalid Scsi_Host pointer.\n", driver_name);
for (i = 0; i < sh[j]->can_queue; i++)
- if ((&HD(j)->cp[i])->sglist) kfree((&HD(j)->cp[i])->sglist);
+ kfree((&HD(j)->cp[i])->sglist);
for (i = 0; i < sh[j]->can_queue; i++)
pci_unmap_single(HD(j)->pdev, HD(j)->cp[i].cp_dma_addr,
@@ -1968,7 +1965,8 @@ static int u14_34f_release(struct Scsi_Host *shpnt) {
free_irq(sh[j]->irq, &sha[j]);
- if (sh[j]->dma_channel != NO_DMA) free_dma(sh[j]->dma_channel);
+ if (sh[j]->dma_channel != NO_DMA)
+ free_dma(sh[j]->dma_channel);
release_region(sh[j]->io_port, sh[j]->n_io_port);
scsi_unregister(sh[j]);
diff --git a/drivers/scsi/wd33c93.c b/drivers/scsi/wd33c93.c
index 5754445fb36a..fd63add6a577 100644
--- a/drivers/scsi/wd33c93.c
+++ b/drivers/scsi/wd33c93.c
@@ -77,7 +77,6 @@
#include <linux/sched.h>
#include <linux/string.h>
#include <linux/delay.h>
-#include <linux/version.h>
#include <linux/init.h>
#include <linux/blkdev.h>
#include <asm/irq.h>
diff --git a/drivers/scsi/zalon.c b/drivers/scsi/zalon.c
index 5a51051e31f0..b131432c677d 100644
--- a/drivers/scsi/zalon.c
+++ b/drivers/scsi/zalon.c
@@ -88,7 +88,7 @@ zalon_probe(struct parisc_device *dev)
struct gsc_irq gsc_irq;
u32 zalon_vers;
int error = -ENODEV;
- void __iomem *zalon = ioremap(dev->hpa, 4096);
+ void __iomem *zalon = ioremap(dev->hpa.start, 4096);
void __iomem *io_port = zalon + GSC_SCSI_ZALON_OFFSET;
static int unit = 0;
struct Scsi_Host *host;
@@ -127,7 +127,7 @@ zalon_probe(struct parisc_device *dev)
device.chip = zalon720_chip;
device.host_id = 7;
device.dev = &dev->dev;
- device.slot.base = dev->hpa + GSC_SCSI_ZALON_OFFSET;
+ device.slot.base = dev->hpa.start + GSC_SCSI_ZALON_OFFSET;
device.slot.base_v = io_port;
device.slot.irq = dev->irq;
device.differential = 2;
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
index 4d75cdfa0a0a..98820603e75f 100644
--- a/drivers/serial/8250.c
+++ b/drivers/serial/8250.c
@@ -33,13 +33,14 @@
#include <linux/sysrq.h>
#include <linux/mca.h>
#include <linux/delay.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <linux/tty.h>
#include <linux/tty_flip.h>
#include <linux/serial_reg.h>
#include <linux/serial_core.h>
#include <linux/serial.h>
#include <linux/serial_8250.h>
+#include <linux/nmi.h>
#include <asm/io.h>
#include <asm/irq.h>
@@ -251,9 +252,53 @@ static const struct serial8250_config uart_config[] = {
},
};
+#ifdef CONFIG_SERIAL_8250_AU1X00
+
+/* Au1x00 UART hardware has a weird register layout */
+static const u8 au_io_in_map[] = {
+ [UART_RX] = 0,
+ [UART_IER] = 2,
+ [UART_IIR] = 3,
+ [UART_LCR] = 5,
+ [UART_MCR] = 6,
+ [UART_LSR] = 7,
+ [UART_MSR] = 8,
+};
+
+static const u8 au_io_out_map[] = {
+ [UART_TX] = 1,
+ [UART_IER] = 2,
+ [UART_FCR] = 4,
+ [UART_LCR] = 5,
+ [UART_MCR] = 6,
+};
+
+/* sane hardware needs no mapping */
+static inline int map_8250_in_reg(struct uart_8250_port *up, int offset)
+{
+ if (up->port.iotype != UPIO_AU)
+ return offset;
+ return au_io_in_map[offset];
+}
+
+static inline int map_8250_out_reg(struct uart_8250_port *up, int offset)
+{
+ if (up->port.iotype != UPIO_AU)
+ return offset;
+ return au_io_out_map[offset];
+}
+
+#else
+
+/* sane hardware needs no mapping */
+#define map_8250_in_reg(up, offset) (offset)
+#define map_8250_out_reg(up, offset) (offset)
+
+#endif
+
static _INLINE_ unsigned int serial_in(struct uart_8250_port *up, int offset)
{
- offset <<= up->port.regshift;
+ offset = map_8250_in_reg(up, offset) << up->port.regshift;
switch (up->port.iotype) {
case UPIO_HUB6:
@@ -266,6 +311,11 @@ static _INLINE_ unsigned int serial_in(struct uart_8250_port *up, int offset)
case UPIO_MEM32:
return readl(up->port.membase + offset);
+#ifdef CONFIG_SERIAL_8250_AU1X00
+ case UPIO_AU:
+ return __raw_readl(up->port.membase + offset);
+#endif
+
default:
return inb(up->port.iobase + offset);
}
@@ -274,7 +324,7 @@ static _INLINE_ unsigned int serial_in(struct uart_8250_port *up, int offset)
static _INLINE_ void
serial_out(struct uart_8250_port *up, int offset, int value)
{
- offset <<= up->port.regshift;
+ offset = map_8250_out_reg(up, offset) << up->port.regshift;
switch (up->port.iotype) {
case UPIO_HUB6:
@@ -290,6 +340,12 @@ serial_out(struct uart_8250_port *up, int offset, int value)
writel(value, up->port.membase + offset);
break;
+#ifdef CONFIG_SERIAL_8250_AU1X00
+ case UPIO_AU:
+ __raw_writel(value, up->port.membase + offset);
+ break;
+#endif
+
default:
outb(value, up->port.iobase + offset);
}
@@ -910,6 +966,13 @@ static void autoconfig(struct uart_8250_port *up, unsigned int probeflags)
}
}
#endif
+
+#ifdef CONFIG_SERIAL_8250_AU1X00
+ /* if access method is AU, it is a 16550 with a quirk */
+ if (up->port.type == PORT_16550A && up->port.iotype == UPIO_AU)
+ up->bugs |= UART_BUG_NOMSR;
+#endif
+
serial_outp(up, UART_LCR, save_lcr);
if (up->capabilities != uart_config[up->port.type].flags) {
@@ -1057,6 +1120,10 @@ static void serial8250_enable_ms(struct uart_port *port)
{
struct uart_8250_port *up = (struct uart_8250_port *)port;
+ /* no MSR capabilities */
+ if (up->bugs & UART_BUG_NOMSR)
+ return;
+
up->ier |= UART_IER_MSI;
serial_out(up, UART_IER, up->ier);
}
@@ -1774,7 +1841,8 @@ serial8250_set_termios(struct uart_port *port, struct termios *termios,
* CTS flow control flag and modem status interrupts
*/
up->ier &= ~UART_IER_MSI;
- if (UART_ENABLE_MS(&up->port, termios->c_cflag))
+ if (!(up->bugs & UART_BUG_NOMSR) &&
+ UART_ENABLE_MS(&up->port, termios->c_cflag))
up->ier |= UART_IER_MSI;
if (up->capabilities & UART_CAP_UUE)
up->ier |= UART_IER_UUE | UART_IER_RTOIE;
@@ -2141,6 +2209,8 @@ serial8250_console_write(struct console *co, const char *s, unsigned int count)
unsigned int ier;
int i;
+ touch_nmi_watchdog();
+
/*
* First save the UER then disable the interrupts
*/
@@ -2358,13 +2428,10 @@ static int __devexit serial8250_remove(struct device *dev)
return 0;
}
-static int serial8250_suspend(struct device *dev, pm_message_t state, u32 level)
+static int serial8250_suspend(struct device *dev, pm_message_t state)
{
int i;
- if (level != SUSPEND_DISABLE)
- return 0;
-
for (i = 0; i < UART_NR; i++) {
struct uart_8250_port *up = &serial8250_ports[i];
@@ -2375,13 +2442,10 @@ static int serial8250_suspend(struct device *dev, pm_message_t state, u32 level)
return 0;
}
-static int serial8250_resume(struct device *dev, u32 level)
+static int serial8250_resume(struct device *dev)
{
int i;
- if (level != RESUME_ENABLE)
- return 0;
-
for (i = 0; i < UART_NR; i++) {
struct uart_8250_port *up = &serial8250_ports[i];
diff --git a/drivers/serial/8250.h b/drivers/serial/8250.h
index b1b459efda52..a607b98016db 100644
--- a/drivers/serial/8250.h
+++ b/drivers/serial/8250.h
@@ -49,6 +49,7 @@ struct serial8250_config {
#define UART_BUG_QUOT (1 << 0) /* UART has buggy quot LSB */
#define UART_BUG_TXEN (1 << 1) /* UART has buggy TX IIR status */
+#define UART_BUG_NOMSR (1 << 2) /* UART has buggy MSR status bits (Au1x00) */
#if defined(__i386__) && (defined(CONFIG_M386) || defined(CONFIG_M486))
#define _INLINE_ inline
diff --git a/drivers/serial/8250_au1x00.c b/drivers/serial/8250_au1x00.c
new file mode 100644
index 000000000000..06ae8fbcc947
--- /dev/null
+++ b/drivers/serial/8250_au1x00.c
@@ -0,0 +1,102 @@
+/*
+ * Serial Device Initialisation for Au1x00
+ *
+ * (C) Copyright Embedded Alley Solutions, Inc 2005
+ * Author: Pantelis Antoniou <pantelis@embeddedalley.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/errno.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/module.h>
+#include <linux/serial_core.h>
+#include <linux/signal.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+
+#include <linux/serial_8250.h>
+
+#include <asm/mach-au1x00/au1000.h>
+
+#include "8250.h"
+
+#define PORT(_base, _irq) \
+ { \
+ .iobase = _base, \
+ .membase = (void __iomem *)_base,\
+ .mapbase = _base, \
+ .irq = _irq, \
+ .uartclk = 0, /* filled */ \
+ .regshift = 2, \
+ .iotype = UPIO_AU, \
+ .flags = UPF_SKIP_TEST | \
+ UPF_IOREMAP, \
+ }
+
+static struct plat_serial8250_port au1x00_data[] = {
+#if defined(CONFIG_SOC_AU1000)
+ PORT(UART0_ADDR, AU1000_UART0_INT),
+ PORT(UART1_ADDR, AU1000_UART1_INT),
+ PORT(UART2_ADDR, AU1000_UART2_INT),
+ PORT(UART3_ADDR, AU1000_UART3_INT),
+#elif defined(CONFIG_SOC_AU1500)
+ PORT(UART0_ADDR, AU1500_UART0_INT),
+ PORT(UART3_ADDR, AU1500_UART3_INT),
+#elif defined(CONFIG_SOC_AU1100)
+ PORT(UART0_ADDR, AU1100_UART0_INT),
+ PORT(UART1_ADDR, AU1100_UART1_INT),
+ PORT(UART2_ADDR, AU1100_UART2_INT),
+ PORT(UART3_ADDR, AU1100_UART3_INT),
+#elif defined(CONFIG_SOC_AU1550)
+ PORT(UART0_ADDR, AU1550_UART0_INT),
+ PORT(UART1_ADDR, AU1550_UART1_INT),
+ PORT(UART2_ADDR, AU1550_UART2_INT),
+ PORT(UART3_ADDR, AU1550_UART3_INT),
+#elif defined(CONFIG_SOC_AU1200)
+ PORT(UART0_ADDR, AU1200_UART0_INT),
+ PORT(UART1_ADDR, AU1200_UART1_INT),
+#endif
+ { },
+};
+
+static struct platform_device au1x00_device = {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_AU1X00,
+ .dev = {
+ .platform_data = au1x00_data,
+ },
+};
+
+static int __init au1x00_init(void)
+{
+ int i;
+ unsigned int uartclk;
+
+ /* get uart clock */
+ uartclk = get_au1x00_uart_baud_base() * 16;
+
+ /* fill up uartclk */
+ for (i = 0; au1x00_data[i].flags ; i++)
+ au1x00_data[i].uartclk = uartclk;
+
+ return platform_device_register(&au1x00_device);
+}
+
+/* XXX: Yes, I know this doesn't yet work. */
+static void __exit au1x00_exit(void)
+{
+ platform_device_unregister(&au1x00_device);
+}
+
+module_init(au1x00_init);
+module_exit(au1x00_exit);
+
+MODULE_AUTHOR("Pantelis Antoniou <pantelis@embeddedalley.com>");
+MODULE_DESCRIPTION("8250 serial probe module for Au1x000 cards");
+MODULE_LICENSE("GPL");
diff --git a/drivers/serial/8250_early.c b/drivers/serial/8250_early.c
index b7a5dd710228..59ba5d993b4b 100644
--- a/drivers/serial/8250_early.c
+++ b/drivers/serial/8250_early.c
@@ -164,7 +164,7 @@ static int __init parse_options(struct early_uart_device *device, char *options)
if ((options = strchr(options, ','))) {
options++;
- device->baud = simple_strtoul(options, 0, 0);
+ device->baud = simple_strtoul(options, NULL, 0);
length = min(strcspn(options, " "), sizeof(device->options));
strncpy(device->options, options, length);
} else {
diff --git a/drivers/serial/8250_gsc.c b/drivers/serial/8250_gsc.c
index 431aa5761a7a..8b4947933d9b 100644
--- a/drivers/serial/8250_gsc.c
+++ b/drivers/serial/8250_gsc.c
@@ -29,7 +29,6 @@
static int __init
serial_init_chip(struct parisc_device *dev)
{
- static int serial_line_nr;
struct uart_port port;
unsigned long address;
int err;
@@ -42,12 +41,13 @@ serial_init_chip(struct parisc_device *dev)
*/
if (parisc_parent(dev)->id.hw_type != HPHW_IOA) {
printk(KERN_INFO "Serial: device 0x%lx not configured.\n"
- "Enable support for Wax, Lasi, Asp or Dino.\n", dev->hpa);
+ "Enable support for Wax, Lasi, Asp or Dino.\n",
+ dev->hpa.start);
}
return -ENODEV;
}
- address = dev->hpa;
+ address = dev->hpa.start;
if (dev->id.sversion != 0x8d) {
address += 0x800;
}
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index b745a1b9e835..ff36f0c9fdad 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -207,6 +207,14 @@ config SERIAL_8250_ACORN
system, say Y to this option. The driver can handle 1, 2, or 3 port
cards. If unsure, say N.
+config SERIAL_8250_AU1X00
+ bool "AU1X00 serial port support"
+ depends on SERIAL_8250 != n && SOC_AU1X00
+ help
+ If you have an Au1x00 board and want to use the serial port, say Y
+ to this option. The driver can handle 1 or 2 serial ports.
+ If unsure, say N.
+
comment "Non-8250 serial port support"
config SERIAL_AMBA_PL010
diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile
index 11c7dc483f93..d7c7c7180e33 100644
--- a/drivers/serial/Makefile
+++ b/drivers/serial/Makefile
@@ -22,6 +22,7 @@ obj-$(CONFIG_SERIAL_8250_ACCENT) += 8250_accent.o
obj-$(CONFIG_SERIAL_8250_BOCA) += 8250_boca.o
obj-$(CONFIG_SERIAL_8250_HUB6) += 8250_hub6.o
obj-$(CONFIG_SERIAL_8250_MCA) += 8250_mca.o
+obj-$(CONFIG_SERIAL_8250_AU1X00) += 8250_au1x00.o
obj-$(CONFIG_SERIAL_AMBA_PL010) += amba-pl010.o
obj-$(CONFIG_SERIAL_AMBA_PL011) += amba-pl011.o
obj-$(CONFIG_SERIAL_CLPS711X) += clps711x.o
diff --git a/drivers/serial/amba-pl010.c b/drivers/serial/amba-pl010.c
index 679e678c7e6a..ddd0307fece2 100644
--- a/drivers/serial/amba-pl010.c
+++ b/drivers/serial/amba-pl010.c
@@ -50,6 +50,7 @@
#include <asm/io.h>
#include <asm/irq.h>
+#include <asm/hardware.h>
#include <asm/hardware/amba.h>
#include <asm/hardware/amba_serial.h>
diff --git a/drivers/serial/amba-pl011.c b/drivers/serial/amba-pl011.c
index 1ff629c74750..938d185841c9 100644
--- a/drivers/serial/amba-pl011.c
+++ b/drivers/serial/amba-pl011.c
@@ -50,6 +50,7 @@
#include <asm/io.h>
#include <asm/irq.h>
+#include <asm/sizes.h>
#include <asm/hardware/amba.h>
#include <asm/hardware/clock.h>
#include <asm/hardware/amba_serial.h>
diff --git a/drivers/serial/crisv10.c b/drivers/serial/crisv10.c
index 40d3e7139cfe..08c42c000188 100644
--- a/drivers/serial/crisv10.c
+++ b/drivers/serial/crisv10.c
@@ -4416,10 +4416,8 @@ rs_close(struct tty_struct *tty, struct file * filp)
info->event = 0;
info->tty = 0;
if (info->blocked_open) {
- if (info->close_delay) {
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(info->close_delay);
- }
+ if (info->close_delay)
+ schedule_timeout_interruptible(info->close_delay);
wake_up_interruptible(&info->open_wait);
}
info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
@@ -4469,8 +4467,7 @@ static void rs_wait_until_sent(struct tty_struct *tty, int timeout)
while (info->xmit.head != info->xmit.tail || /* More in send queue */
(*info->ostatusadr & 0x007f) || /* more in FIFO */
(elapsed_usec < 2*info->char_time_usec)) {
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(1);
+ schedule_timeout_interruptible(1);
if (signal_pending(current))
break;
if (timeout && time_after(jiffies, orig_jiffies + timeout))
diff --git a/drivers/serial/imx.c b/drivers/serial/imx.c
index bdb4e454b8b0..4a54ff584700 100644
--- a/drivers/serial/imx.c
+++ b/drivers/serial/imx.c
@@ -36,7 +36,7 @@
#include <linux/init.h>
#include <linux/console.h>
#include <linux/sysrq.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <linux/tty.h>
#include <linux/tty_flip.h>
#include <linux/serial_core.h>
@@ -921,21 +921,21 @@ static struct uart_driver imx_reg = {
.cons = IMX_CONSOLE,
};
-static int serial_imx_suspend(struct device *_dev, pm_message_t state, u32 level)
+static int serial_imx_suspend(struct device *_dev, pm_message_t state)
{
struct imx_port *sport = dev_get_drvdata(_dev);
- if (sport && level == SUSPEND_DISABLE)
+ if (sport)
uart_suspend_port(&imx_reg, &sport->port);
return 0;
}
-static int serial_imx_resume(struct device *_dev, u32 level)
+static int serial_imx_resume(struct device *_dev)
{
struct imx_port *sport = dev_get_drvdata(_dev);
- if (sport && level == RESUME_ENABLE)
+ if (sport)
uart_resume_port(&imx_reg, &sport->port);
return 0;
@@ -995,6 +995,7 @@ static int __init imx_serial_init(void)
static void __exit imx_serial_exit(void)
{
uart_unregister_driver(&imx_reg);
+ driver_unregister(&serial_imx_driver);
}
module_init(imx_serial_init);
diff --git a/drivers/serial/ioc4_serial.c b/drivers/serial/ioc4_serial.c
index f88fdd480685..771676abee60 100644
--- a/drivers/serial/ioc4_serial.c
+++ b/drivers/serial/ioc4_serial.c
@@ -308,6 +308,8 @@ struct ioc4_serial {
typedef void ioc4_intr_func_f(void *, uint32_t);
typedef ioc4_intr_func_f *ioc4_intr_func_t;
+static unsigned int Num_of_ioc4_cards;
+
/* defining this will get you LOTS of great debug info */
//#define DEBUG_INTERRUPTS
#define DPRINT_CONFIG(_x...) ;
@@ -317,7 +319,8 @@ typedef ioc4_intr_func_f *ioc4_intr_func_t;
#define WAKEUP_CHARS 256
/* number of characters we want to transmit to the lower level at a time */
-#define IOC4_MAX_CHARS 128
+#define IOC4_MAX_CHARS 256
+#define IOC4_FIFO_CHARS 255
/* Device name we're using */
#define DEVICE_NAME "ttyIOC"
@@ -1038,6 +1041,7 @@ static int inline ioc4_attach_local(struct ioc4_driver_data *idd)
return -ENOMEM;
}
memset(port, 0, sizeof(struct ioc4_port));
+ spin_lock_init(&port->ip_lock);
/* we need to remember the previous ones, to point back to
* them farther down - setting up the ring buffers.
@@ -1691,12 +1695,14 @@ ioc4_change_speed(struct uart_port *the_port,
baud = 9600;
if (!the_port->fifosize)
- the_port->fifosize = IOC4_MAX_CHARS;
+ the_port->fifosize = IOC4_FIFO_CHARS;
the_port->timeout = ((the_port->fifosize * HZ * bits) / (baud / 10));
the_port->timeout += HZ / 50; /* Add .02 seconds of slop */
the_port->ignore_status_mask = N_ALL_INPUT;
+ info->tty->low_latency = 1;
+
if (I_IGNPAR(info->tty))
the_port->ignore_status_mask &= ~(N_PARITY_ERROR
| N_FRAMING_ERROR);
@@ -1742,7 +1748,6 @@ ioc4_change_speed(struct uart_port *the_port,
*/
static inline int ic4_startup_local(struct uart_port *the_port)
{
- int retval = 0;
struct ioc4_port *port;
struct uart_info *info;
@@ -1754,9 +1759,6 @@ static inline int ic4_startup_local(struct uart_port *the_port)
return -1;
info = the_port->info;
- if (info->flags & UIF_INITIALIZED) {
- return retval;
- }
if (info->tty) {
set_bit(TTY_IO_ERROR, &info->tty->flags);
@@ -1775,7 +1777,6 @@ static inline int ic4_startup_local(struct uart_port *the_port)
/* set the speed of the serial port */
ioc4_change_speed(the_port, info->tty->termios, (struct termios *)0);
- info->flags |= UIF_INITIALIZED;
return 0;
}
@@ -1785,9 +1786,13 @@ static inline int ic4_startup_local(struct uart_port *the_port)
*/
static void ioc4_cb_output_lowat(struct ioc4_port *port)
{
+ unsigned long pflags;
+
/* ip_lock is set on the call here */
if (port->ip_port) {
+ spin_lock_irqsave(&port->ip_port->lock, pflags);
transmit_chars(port->ip_port);
+ spin_unlock_irqrestore(&port->ip_port->lock, pflags);
}
}
@@ -2064,8 +2069,7 @@ static inline int do_read(struct uart_port *the_port, unsigned char *buf,
* available data as long as it returns some.
*/
/* Re-arm the timer */
- writel(port->ip_rx_cons | IOC4_SRCIR_ARM,
- &port->ip_serial_regs->srcir);
+ writel(port->ip_rx_cons | IOC4_SRCIR_ARM, &port->ip_serial_regs->srcir);
prod_ptr = readl(&port->ip_serial_regs->srpir) & PROD_CONS_MASK;
cons_ptr = port->ip_rx_cons;
@@ -2299,6 +2303,7 @@ static inline int do_read(struct uart_port *the_port, unsigned char *buf,
}
return total;
}
+
/**
* receive_chars - upper level read. Called with ip_lock.
* @the_port: port to read from
@@ -2307,9 +2312,11 @@ static void receive_chars(struct uart_port *the_port)
{
struct tty_struct *tty;
unsigned char ch[IOC4_MAX_CHARS];
- int read_count, request_count;
+ int read_count, request_count = IOC4_MAX_CHARS;
struct uart_icount *icount;
struct uart_info *info = the_port->info;
+ int flip = 0;
+ unsigned long pflags;
/* Make sure all the pointers are "good" ones */
if (!info)
@@ -2317,16 +2324,17 @@ static void receive_chars(struct uart_port *the_port)
if (!info->tty)
return;
+ spin_lock_irqsave(&the_port->lock, pflags);
tty = info->tty;
- request_count = TTY_FLIPBUF_SIZE - tty->flip.count - 1;
+ if (request_count > TTY_FLIPBUF_SIZE - tty->flip.count)
+ request_count = TTY_FLIPBUF_SIZE - tty->flip.count;
if (request_count > 0) {
- if (request_count > IOC4_MAX_CHARS - 2)
- request_count = IOC4_MAX_CHARS - 2;
icount = &the_port->icount;
read_count = do_read(the_port, ch, request_count);
if (read_count > 0) {
+ flip = 1;
memcpy(tty->flip.char_buf_ptr, ch, read_count);
memset(tty->flip.flag_buf_ptr, TTY_NORMAL, read_count);
tty->flip.char_buf_ptr += read_count;
@@ -2335,7 +2343,11 @@ static void receive_chars(struct uart_port *the_port)
icount->rx += read_count;
}
}
- tty_flip_buffer_push(tty);
+
+ spin_unlock_irqrestore(&the_port->lock, pflags);
+
+ if (flip)
+ tty_flip_buffer_push(tty);
}
/**
@@ -2393,18 +2405,14 @@ static void ic4_shutdown(struct uart_port *the_port)
info = the_port->info;
- if (!(info->flags & UIF_INITIALIZED))
- return;
-
wake_up_interruptible(&info->delta_msr_wait);
if (info->tty)
set_bit(TTY_IO_ERROR, &info->tty->flags);
- spin_lock_irqsave(&port->ip_lock, port_flags);
+ spin_lock_irqsave(&the_port->lock, port_flags);
set_notification(port, N_ALL, 0);
- info->flags &= ~UIF_INITIALIZED;
- spin_unlock_irqrestore(&port->ip_lock, port_flags);
+ spin_unlock_irqrestore(&the_port->lock, port_flags);
}
/**
@@ -2463,12 +2471,10 @@ static unsigned int ic4_get_mctrl(struct uart_port *the_port)
static void ic4_start_tx(struct uart_port *the_port)
{
struct ioc4_port *port = get_ioc4_port(the_port);
- unsigned long flags;
if (port) {
- spin_lock_irqsave(&port->ip_lock, flags);
- transmit_chars(the_port);
- spin_unlock_irqrestore(&port->ip_lock, flags);
+ set_notification(port, N_OUTPUT_LOWAT, 1);
+ enable_intrs(port, port->ip_hooks->intr_tx_mt);
}
}
@@ -2510,9 +2516,9 @@ static int ic4_startup(struct uart_port *the_port)
}
/* Start up the serial port */
- spin_lock_irqsave(&port->ip_lock, port_flags);
+ spin_lock_irqsave(&the_port->lock, port_flags);
retval = ic4_startup_local(the_port);
- spin_unlock_irqrestore(&port->ip_lock, port_flags);
+ spin_unlock_irqrestore(&the_port->lock, port_flags);
return retval;
}
@@ -2527,12 +2533,11 @@ static void
ic4_set_termios(struct uart_port *the_port,
struct termios *termios, struct termios *old_termios)
{
- struct ioc4_port *port = get_ioc4_port(the_port);
unsigned long port_flags;
- spin_lock_irqsave(&port->ip_lock, port_flags);
+ spin_lock_irqsave(&the_port->lock, port_flags);
ioc4_change_speed(the_port, termios, old_termios);
- spin_unlock_irqrestore(&port->ip_lock, port_flags);
+ spin_unlock_irqrestore(&the_port->lock, port_flags);
}
/**
@@ -2607,24 +2612,25 @@ ioc4_serial_core_attach(struct pci_dev *pdev)
__FUNCTION__, (void *)the_port,
(void *)port));
- spin_lock_init(&the_port->lock);
/* membase, iobase and mapbase just need to be non-0 */
the_port->membase = (unsigned char __iomem *)1;
- the_port->line = the_port->iobase = ii;
+ the_port->iobase = (pdev->bus->number << 16) | ii;
+ the_port->line = (Num_of_ioc4_cards << 2) | ii;
the_port->mapbase = 1;
the_port->type = PORT_16550A;
- the_port->fifosize = IOC4_MAX_CHARS;
+ the_port->fifosize = IOC4_FIFO_CHARS;
the_port->ops = &ioc4_ops;
the_port->irq = control->ic_irq;
the_port->dev = &pdev->dev;
+ spin_lock_init(&the_port->lock);
if (uart_add_one_port(&ioc4_uart, the_port) < 0) {
printk(KERN_WARNING
- "%s: unable to add port %d\n",
- __FUNCTION__, the_port->line);
+ "%s: unable to add port %d bus %d\n",
+ __FUNCTION__, the_port->line, pdev->bus->number);
} else {
DPRINT_CONFIG(
- ("IOC4 serial driver port %d irq = %d\n",
- the_port->line, the_port->irq));
+ ("IOC4 serial port %d irq = %d, bus %d\n",
+ the_port->line, the_port->irq, pdev->bus->number));
}
/* all ports are rs232 for now */
ioc4_set_proto(port, PROTO_RS232);
@@ -2734,6 +2740,8 @@ ioc4_serial_attach_one(struct ioc4_driver_data *idd)
if ((ret = ioc4_serial_core_attach(idd->idd_pdev)))
goto out4;
+ Num_of_ioc4_cards++;
+
return ret;
/* error exits that give back resources */
diff --git a/drivers/serial/mcfserial.c b/drivers/serial/mcfserial.c
index e2ebdcad553c..47f7404cb045 100644
--- a/drivers/serial/mcfserial.c
+++ b/drivers/serial/mcfserial.c
@@ -57,7 +57,8 @@ struct timer_list mcfrs_timer_struct;
* keep going. Perhaps one day the cflag settings for the
* console can be used instead.
*/
-#if defined(CONFIG_ARNEWSH) || defined(CONFIG_MOTOROLA) || defined(CONFIG_senTec) || defined(CONFIG_SNEHA)
+#if defined(CONFIG_ARNEWSH) || defined(CONFIG_FREESCALE) || \
+ defined(CONFIG_senTec) || defined(CONFIG_SNEHA)
#define CONSOLE_BAUD_RATE 19200
#define DEFAULT_CBAUD B19200
#endif
@@ -67,7 +68,7 @@ struct timer_list mcfrs_timer_struct;
#define DEFAULT_CBAUD B38400
#endif
-#if defined(CONFIG_MOD5272)
+#if defined(CONFIG_MOD5272) || defined(CONFIG_M5208EVB)
#define CONSOLE_BAUD_RATE 115200
#define DEFAULT_CBAUD B115200
#endif
@@ -95,7 +96,8 @@ static struct tty_driver *mcfrs_serial_driver;
#undef SERIAL_DEBUG_OPEN
#undef SERIAL_DEBUG_FLOW
-#if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x)
+#if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) || \
+ defined(CONFIG_M520x)
#define IRQBASE (MCFINT_VECBASE+MCFINT_UART0)
#else
#define IRQBASE 73
@@ -1528,6 +1530,35 @@ static void mcfrs_irqinit(struct mcf_serial *info)
imrp = (volatile unsigned long *) (MCF_MBAR + MCFICM_INTC0 +
MCFINTC_IMRL);
*imrp &= ~((1 << (info->irq - MCFINT_VECBASE)) | 1);
+#elif defined(CONFIG_M520x)
+ volatile unsigned char *icrp, *uartp;
+ volatile unsigned long *imrp;
+
+ uartp = info->addr;
+
+ icrp = (volatile unsigned char *) (MCF_MBAR + MCFICM_INTC0 +
+ MCFINTC_ICR0 + MCFINT_UART0 + info->line);
+ *icrp = 0x03;
+
+ imrp = (volatile unsigned long *) (MCF_MBAR + MCFICM_INTC0 +
+ MCFINTC_IMRL);
+ *imrp &= ~((1 << (info->irq - MCFINT_VECBASE)) | 1);
+ if (info->line < 2) {
+ unsigned short *uart_par;
+ uart_par = (unsigned short *)(MCF_IPSBAR + MCF_GPIO_PAR_UART);
+ if (info->line == 0)
+ *uart_par |= MCF_GPIO_PAR_UART_PAR_UTXD0
+ | MCF_GPIO_PAR_UART_PAR_URXD0;
+ else if (info->line == 1)
+ *uart_par |= MCF_GPIO_PAR_UART_PAR_UTXD1
+ | MCF_GPIO_PAR_UART_PAR_URXD1;
+ } else if (info->line == 2) {
+ unsigned char *feci2c_par;
+ feci2c_par = (unsigned char *)(MCF_IPSBAR + MCF_GPIO_PAR_FECI2C);
+ *feci2c_par &= ~0x0F;
+ *feci2c_par |= MCF_GPIO_PAR_FECI2C_PAR_SCL_UTXD2
+ | MCF_GPIO_PAR_FECI2C_PAR_SDA_URXD2;
+ }
#else
volatile unsigned char *icrp, *uartp;
diff --git a/drivers/serial/mpc52xx_uart.c b/drivers/serial/mpc52xx_uart.c
index 0585ab27ffde..0dd08a09e7e6 100644
--- a/drivers/serial/mpc52xx_uart.c
+++ b/drivers/serial/mpc52xx_uart.c
@@ -45,7 +45,7 @@
*/
#include <linux/config.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <linux/module.h>
#include <linux/tty.h>
#include <linux/serial.h>
@@ -781,22 +781,22 @@ mpc52xx_uart_remove(struct device *dev)
#ifdef CONFIG_PM
static int
-mpc52xx_uart_suspend(struct device *dev, pm_message_t state, u32 level)
+mpc52xx_uart_suspend(struct device *dev, pm_message_t state)
{
struct uart_port *port = (struct uart_port *) dev_get_drvdata(dev);
- if (sport && level == SUSPEND_DISABLE)
+ if (sport)
uart_suspend_port(&mpc52xx_uart_driver, port);
return 0;
}
static int
-mpc52xx_uart_resume(struct device *dev, u32 level)
+mpc52xx_uart_resume(struct device *dev)
{
struct uart_port *port = (struct uart_port *) dev_get_drvdata(dev);
- if (port && level == RESUME_ENABLE)
+ if (port)
uart_resume_port(&mpc52xx_uart_driver, port);
return 0;
diff --git a/drivers/serial/mpsc.c b/drivers/serial/mpsc.c
index efe79b1fd431..ba8838b234da 100644
--- a/drivers/serial/mpsc.c
+++ b/drivers/serial/mpsc.c
@@ -52,6 +52,8 @@
* 4) AFAICT, hardware flow control isn't supported by the controller --MAG.
*/
+#include <linux/platform_device.h>
+
#include "mpsc.h"
/*
@@ -1100,6 +1102,8 @@ mpsc_start_rx(struct mpsc_port_info *pi)
{
pr_debug("mpsc_start_rx[%d]: Starting...\n", pi->port.line);
+ /* Issue a Receive Abort to clear any receive errors */
+ writel(MPSC_CHR_2_RA, pi->mpsc_base + MPSC_CHR_2);
if (pi->rcv_data) {
mpsc_enter_hunt(pi);
mpsc_sdma_cmd(pi, SDMA_SDCM_ERD);
diff --git a/drivers/serial/mux.c b/drivers/serial/mux.c
index 189064607709..660bae5ba179 100644
--- a/drivers/serial/mux.c
+++ b/drivers/serial/mux.c
@@ -27,6 +27,7 @@
#include <linux/delay.h> /* for udelay */
#include <linux/device.h>
#include <asm/io.h>
+#include <asm/irq.h>
#include <asm/parisc-device.h>
#ifdef CONFIG_MAGIC_SYSRQ
@@ -444,7 +445,7 @@ static int __init mux_probe(struct parisc_device *dev)
unsigned long bytecnt;
struct uart_port *port;
- status = pdc_iodc_read(&bytecnt, dev->hpa, 0, iodc_data, 32);
+ status = pdc_iodc_read(&bytecnt, dev->hpa.start, 0, iodc_data, 32);
if(status != PDC_OK) {
printk(KERN_ERR "Serial mux: Unable to read IODC.\n");
return 1;
@@ -469,16 +470,18 @@ static int __init mux_probe(struct parisc_device *dev)
for(i = 0; i < ports; ++i, ++port_cnt) {
port = &mux_ports[port_cnt];
port->iobase = 0;
- port->mapbase = dev->hpa + MUX_OFFSET + (i * MUX_LINE_OFFSET);
+ port->mapbase = dev->hpa.start + MUX_OFFSET +
+ (i * MUX_LINE_OFFSET);
port->membase = ioremap(port->mapbase, MUX_LINE_OFFSET);
port->iotype = SERIAL_IO_MEM;
port->type = PORT_MUX;
- port->irq = SERIAL_IRQ_NONE;
+ port->irq = NO_IRQ;
port->uartclk = 0;
port->fifosize = MUX_FIFO_SIZE;
port->ops = &mux_pops;
port->flags = UPF_BOOT_AUTOCONF;
port->line = port_cnt;
+ spin_lock_init(&port->lock);
status = uart_add_one_port(&mux_driver, port);
BUG_ON(status);
}
@@ -497,7 +500,7 @@ static struct parisc_device_id mux_tbl[] = {
MODULE_DEVICE_TABLE(parisc, mux_tbl);
static struct parisc_driver serial_mux_driver = {
- .name = "Serial MUX",
+ .name = "serial_mux",
.id_table = mux_tbl,
.probe = mux_probe,
};
diff --git a/drivers/serial/pxa.c b/drivers/serial/pxa.c
index 90c2a86c421b..16b2f9417af9 100644
--- a/drivers/serial/pxa.c
+++ b/drivers/serial/pxa.c
@@ -39,7 +39,7 @@
#include <linux/circ_buf.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <linux/tty.h>
#include <linux/tty_flip.h>
#include <linux/serial_core.h>
@@ -358,6 +358,9 @@ static int serial_pxa_startup(struct uart_port *port)
unsigned long flags;
int retval;
+ if (port->line == 3) /* HWUART */
+ up->mcr |= UART_MCR_AFE;
+ else
up->mcr = 0;
/*
@@ -481,8 +484,10 @@ serial_pxa_set_termios(struct uart_port *port, struct termios *termios,
if ((up->port.uartclk / quot) < (2400 * 16))
fcr = UART_FCR_ENABLE_FIFO | UART_FCR_PXAR1;
- else
+ else if ((up->port.uartclk / quot) < (230400 * 16))
fcr = UART_FCR_ENABLE_FIFO | UART_FCR_PXAR8;
+ else
+ fcr = UART_FCR_ENABLE_FIFO | UART_FCR_PXAR32;
/*
* Ok, we're now changing the port state. Do it with
@@ -772,6 +777,20 @@ static struct uart_pxa_port serial_pxa_ports[] = {
.ops = &serial_pxa_pops,
.line = 2,
},
+ }, { /* HWUART */
+ .name = "HWUART",
+ .cken = CKEN4_HWUART,
+ .port = {
+ .type = PORT_PXA,
+ .iotype = UPIO_MEM,
+ .membase = (void *)&HWUART,
+ .mapbase = __PREG(HWUART),
+ .irq = IRQ_HWUART,
+ .uartclk = 921600 * 16,
+ .fifosize = 64,
+ .ops = &serial_pxa_pops,
+ .line = 3,
+ },
}
};
@@ -786,21 +805,21 @@ static struct uart_driver serial_pxa_reg = {
.cons = PXA_CONSOLE,
};
-static int serial_pxa_suspend(struct device *_dev, pm_message_t state, u32 level)
+static int serial_pxa_suspend(struct device *_dev, pm_message_t state)
{
struct uart_pxa_port *sport = dev_get_drvdata(_dev);
- if (sport && level == SUSPEND_DISABLE)
+ if (sport)
uart_suspend_port(&serial_pxa_reg, &sport->port);
return 0;
}
-static int serial_pxa_resume(struct device *_dev, u32 level)
+static int serial_pxa_resume(struct device *_dev)
{
struct uart_pxa_port *sport = dev_get_drvdata(_dev);
- if (sport && level == RESUME_ENABLE)
+ if (sport)
uart_resume_port(&serial_pxa_reg, &sport->port);
return 0;
diff --git a/drivers/serial/s3c2410.c b/drivers/serial/s3c2410.c
index 52692aa345ec..036792328d49 100644
--- a/drivers/serial/s3c2410.c
+++ b/drivers/serial/s3c2410.c
@@ -63,7 +63,7 @@
#include <linux/module.h>
#include <linux/ioport.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <linux/init.h>
#include <linux/sysrq.h>
#include <linux/console.h>
@@ -1134,23 +1134,22 @@ static int s3c24xx_serial_remove(struct device *_dev)
#ifdef CONFIG_PM
-static int s3c24xx_serial_suspend(struct device *dev, pm_message_t state,
- u32 level)
+static int s3c24xx_serial_suspend(struct device *dev, pm_message_t state)
{
struct uart_port *port = s3c24xx_dev_to_port(dev);
- if (port && level == SUSPEND_DISABLE)
+ if (port)
uart_suspend_port(&s3c24xx_uart_drv, port);
return 0;
}
-static int s3c24xx_serial_resume(struct device *dev, u32 level)
+static int s3c24xx_serial_resume(struct device *dev)
{
struct uart_port *port = s3c24xx_dev_to_port(dev);
struct s3c24xx_uart_port *ourport = to_ourport(port);
- if (port && level == RESUME_ENABLE) {
+ if (port) {
clk_enable(ourport->clk);
s3c24xx_serial_resetport(port, s3c24xx_port_to_cfg(port));
clk_disable(ourport->clk);
diff --git a/drivers/serial/sa1100.c b/drivers/serial/sa1100.c
index dd8aed242357..ed618cc7ae96 100644
--- a/drivers/serial/sa1100.c
+++ b/drivers/serial/sa1100.c
@@ -35,7 +35,7 @@
#include <linux/init.h>
#include <linux/console.h>
#include <linux/sysrq.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <linux/tty.h>
#include <linux/tty_flip.h>
#include <linux/serial_core.h>
@@ -834,21 +834,21 @@ static struct uart_driver sa1100_reg = {
.cons = SA1100_CONSOLE,
};
-static int sa1100_serial_suspend(struct device *_dev, pm_message_t state, u32 level)
+static int sa1100_serial_suspend(struct device *_dev, pm_message_t state)
{
struct sa1100_port *sport = dev_get_drvdata(_dev);
- if (sport && level == SUSPEND_DISABLE)
+ if (sport)
uart_suspend_port(&sa1100_reg, &sport->port);
return 0;
}
-static int sa1100_serial_resume(struct device *_dev, u32 level)
+static int sa1100_serial_resume(struct device *_dev)
{
struct sa1100_port *sport = dev_get_drvdata(_dev);
- if (sport && level == RESUME_ENABLE)
+ if (sport)
uart_resume_port(&sa1100_reg, &sport->port);
return 0;
diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c
index 2d8622eef701..427a23858076 100644
--- a/drivers/serial/serial_core.c
+++ b/drivers/serial/serial_core.c
@@ -147,8 +147,7 @@ static int uart_startup(struct uart_state *state, int init_hw)
* once we have successfully opened the port. Also set
* up the tty->alt_speed kludge
*/
- if (info->tty)
- set_bit(TTY_IO_ERROR, &info->tty->flags);
+ set_bit(TTY_IO_ERROR, &info->tty->flags);
if (port->type == PORT_UNKNOWN)
return 0;
@@ -1960,6 +1959,7 @@ uart_report_port(struct uart_driver *drv, struct uart_port *port)
break;
case UPIO_MEM:
case UPIO_MEM32:
+ case UPIO_AU:
snprintf(address, sizeof(address),
"MMIO 0x%lx", port->mapbase);
break;
@@ -1968,7 +1968,9 @@ uart_report_port(struct uart_driver *drv, struct uart_port *port)
break;
}
- printk(KERN_INFO "%s%d at %s (irq = %d) is a %s\n",
+ printk(KERN_INFO "%s%s%s%d at %s (irq = %d) is a %s\n",
+ port->dev ? port->dev->bus_id : "",
+ port->dev ? ": " : "",
drv->dev_name, port->line, address, port->irq, uart_type(port));
}
diff --git a/drivers/serial/sunsu.c b/drivers/serial/sunsu.c
index 656c0e8d160e..f0738533f39a 100644
--- a/drivers/serial/sunsu.c
+++ b/drivers/serial/sunsu.c
@@ -1441,7 +1441,7 @@ static void sunsu_console_write(struct console *co, const char *s,
* - initialize the serial port
* Return non-zero if we didn't find a serial port.
*/
-static int __init sunsu_console_setup(struct console *co, char *options)
+static int sunsu_console_setup(struct console *co, char *options)
{
struct uart_port *port;
int baud = 9600;
diff --git a/drivers/serial/vr41xx_siu.c b/drivers/serial/vr41xx_siu.c
index 0c5d65a08f6e..01696b3e3f61 100644
--- a/drivers/serial/vr41xx_siu.c
+++ b/drivers/serial/vr41xx_siu.c
@@ -26,7 +26,7 @@
#endif
#include <linux/console.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <linux/err.h>
#include <linux/ioport.h>
#include <linux/init.h>
@@ -976,14 +976,11 @@ static int siu_remove(struct device *dev)
return 0;
}
-static int siu_suspend(struct device *dev, pm_message_t state, u32 level)
+static int siu_suspend(struct device *dev, pm_message_t state)
{
struct uart_port *port;
int i;
- if (level != SUSPEND_DISABLE)
- return 0;
-
for (i = 0; i < siu_uart_driver.nr; i++) {
port = &siu_uart_ports[i];
if ((port->type == PORT_VR41XX_SIU ||
@@ -995,14 +992,11 @@ static int siu_suspend(struct device *dev, pm_message_t state, u32 level)
return 0;
}
-static int siu_resume(struct device *dev, u32 level)
+static int siu_resume(struct device *dev)
{
struct uart_port *port;
int i;
- if (level != RESUME_ENABLE)
- return 0;
-
for (i = 0; i < siu_uart_driver.nr; i++) {
port = &siu_uart_ports[i];
if ((port->type == PORT_VR41XX_SIU ||
diff --git a/drivers/sh/superhyway/superhyway-sysfs.c b/drivers/sh/superhyway/superhyway-sysfs.c
index dc119ce68e3e..55434330867b 100644
--- a/drivers/sh/superhyway/superhyway-sysfs.c
+++ b/drivers/sh/superhyway/superhyway-sysfs.c
@@ -30,7 +30,7 @@ superhyway_ro_attr(bot_mb, "0x%02x\n", vcr.bot_mb);
superhyway_ro_attr(top_mb, "0x%02x\n", vcr.top_mb);
/* Misc */
-superhyway_ro_attr(resource, "0x%08lx\n", resource.start);
+superhyway_ro_attr(resource, "0x%08lx\n", resource[0].start);
struct device_attribute superhyway_dev_attrs[] = {
__ATTR_RO(perr_flags),
diff --git a/drivers/sh/superhyway/superhyway.c b/drivers/sh/superhyway/superhyway.c
index f056276b08a1..7bdab2a7f59c 100644
--- a/drivers/sh/superhyway/superhyway.c
+++ b/drivers/sh/superhyway/superhyway.c
@@ -16,6 +16,8 @@
#include <linux/types.h>
#include <linux/list.h>
#include <linux/superhyway.h>
+#include <linux/string.h>
+#include <linux/slab.h>
static int superhyway_devices;
@@ -25,19 +27,20 @@ static struct device superhyway_bus_device = {
static void superhyway_device_release(struct device *dev)
{
- kfree(to_superhyway_device(dev));
+ struct superhyway_device *sdev = to_superhyway_device(dev);
+
+ kfree(sdev->resource);
+ kfree(sdev);
}
/**
* superhyway_add_device - Add a SuperHyway module
- * @mod_id: Module ID (taken from MODULE.VCR.MOD_ID).
* @base: Physical address where module is mapped.
- * @vcr: VCR value.
+ * @sdev: SuperHyway device to add, or NULL to allocate a new one.
+ * @bus: Bus where SuperHyway module resides.
*
* This is responsible for adding a new SuperHyway module. This sets up a new
- * struct superhyway_device for the module being added. Each one of @mod_id,
- * @base, and @vcr are registered with the new device for further use
- * elsewhere.
+ * struct superhyway_device for the module being added if @sdev == NULL.
*
* Devices are initially added in the order that they are scanned (from the
* top-down of the memory map), and are assigned an ID based on the order that
@@ -47,28 +50,40 @@ static void superhyway_device_release(struct device *dev)
* Further work can and should be done in superhyway_scan_bus(), to be sure
* that any new modules are properly discovered and subsequently registered.
*/
-int superhyway_add_device(unsigned int mod_id, unsigned long base,
- unsigned long long vcr)
+int superhyway_add_device(unsigned long base, struct superhyway_device *sdev,
+ struct superhyway_bus *bus)
{
- struct superhyway_device *dev;
+ struct superhyway_device *dev = sdev;
+
+ if (!dev) {
+ dev = kmalloc(sizeof(struct superhyway_device), GFP_KERNEL);
+ if (!dev)
+ return -ENOMEM;
- dev = kmalloc(sizeof(struct superhyway_device), GFP_KERNEL);
- if (!dev)
- return -ENOMEM;
+ memset(dev, 0, sizeof(struct superhyway_device));
+ }
- memset(dev, 0, sizeof(struct superhyway_device));
+ dev->bus = bus;
+ superhyway_read_vcr(dev, base, &dev->vcr);
- dev->id.id = mod_id;
- sprintf(dev->name, "SuperHyway device %04x", dev->id.id);
+ if (!dev->resource) {
+ dev->resource = kmalloc(sizeof(struct resource), GFP_KERNEL);
+ if (!dev->resource) {
+ kfree(dev);
+ return -ENOMEM;
+ }
+
+ dev->resource->name = dev->name;
+ dev->resource->start = base;
+ dev->resource->end = dev->resource->start + 0x01000000;
+ }
- dev->vcr = *((struct vcr_info *)(&vcr));
- dev->resource.name = dev->name;
- dev->resource.start = base;
- dev->resource.end = dev->resource.start + 0x01000000;
dev->dev.parent = &superhyway_bus_device;
dev->dev.bus = &superhyway_bus_type;
dev->dev.release = superhyway_device_release;
+ dev->id.id = dev->vcr.mod_id;
+ sprintf(dev->name, "SuperHyway device %04x", dev->id.id);
sprintf(dev->dev.bus_id, "%02x", superhyway_devices);
superhyway_devices++;
@@ -76,10 +91,31 @@ int superhyway_add_device(unsigned int mod_id, unsigned long base,
return device_register(&dev->dev);
}
+int superhyway_add_devices(struct superhyway_bus *bus,
+ struct superhyway_device **devices,
+ int nr_devices)
+{
+ int i, ret = 0;
+
+ for (i = 0; i < nr_devices; i++) {
+ struct superhyway_device *dev = devices[i];
+ ret |= superhyway_add_device(dev->resource[0].start, dev, bus);
+ }
+
+ return ret;
+}
+
static int __init superhyway_init(void)
{
+ struct superhyway_bus *bus;
+ int ret = 0;
+
device_register(&superhyway_bus_device);
- return superhyway_scan_bus();
+
+ for (bus = superhyway_channels; bus->ops; bus++)
+ ret |= superhyway_scan_bus(bus);
+
+ return ret;
}
postcore_initcall(superhyway_init);
@@ -195,6 +231,7 @@ module_exit(superhyway_bus_exit);
EXPORT_SYMBOL(superhyway_bus_type);
EXPORT_SYMBOL(superhyway_add_device);
+EXPORT_SYMBOL(superhyway_add_devices);
EXPORT_SYMBOL(superhyway_register_driver);
EXPORT_SYMBOL(superhyway_unregister_driver);
diff --git a/drivers/tc/.gitignore b/drivers/tc/.gitignore
new file mode 100644
index 000000000000..acc0e1e6a650
--- /dev/null
+++ b/drivers/tc/.gitignore
@@ -0,0 +1 @@
+lk201-map.c
diff --git a/drivers/tc/tc.c b/drivers/tc/tc.c
index a89ef4df80c3..a0e5af638e0e 100644
--- a/drivers/tc/tc.c
+++ b/drivers/tc/tc.c
@@ -8,33 +8,31 @@
* for more details.
*
* Copyright (c) Harald Koerfgen, 1998
- * Copyright (c) 2001, 2003 Maciej W. Rozycki
+ * Copyright (c) 2001, 2003, 2005 Maciej W. Rozycki
*/
-#include <linux/string.h>
#include <linux/init.h>
-#include <linux/ioport.h>
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/types.h>
#include <asm/addrspace.h>
+#include <asm/bug.h>
#include <asm/errno.h>
+#include <asm/io.h>
+#include <asm/paccess.h>
+
#include <asm/dec/machtype.h>
#include <asm/dec/prom.h>
#include <asm/dec/tcinfo.h>
#include <asm/dec/tcmodule.h>
#include <asm/dec/interrupts.h>
-#include <asm/paccess.h>
-#include <asm/ptrace.h>
-
-#define TC_DEBUG
MODULE_LICENSE("GPL");
slot_info tc_bus[MAX_SLOT];
static int num_tcslots;
static tcinfo *info;
-unsigned long system_base;
-
/*
* Interface to the world. Read comment in include/asm-mips/tc.h.
*/
@@ -97,13 +95,16 @@ unsigned long get_tc_speed(void)
static void __init tc_probe(unsigned long startaddr, unsigned long size,
int slots)
{
+ unsigned long slotaddr;
int i, slot, err;
long offset;
- unsigned char pattern[4];
- unsigned char *module;
+ u8 pattern[4];
+ volatile u8 *module;
for (slot = 0; slot < slots; slot++) {
- module = (char *)(startaddr + slot * size);
+ slotaddr = startaddr + slot * size;
+ module = ioremap_nocache(slotaddr, size);
+ BUG_ON(!module);
offset = OLDCARD;
@@ -112,8 +113,10 @@ static void __init tc_probe(unsigned long startaddr, unsigned long size,
err |= get_dbe(pattern[1], module + OLDCARD + TC_PATTERN1);
err |= get_dbe(pattern[2], module + OLDCARD + TC_PATTERN2);
err |= get_dbe(pattern[3], module + OLDCARD + TC_PATTERN3);
- if (err)
+ if (err) {
+ iounmap(module);
continue;
+ }
if (pattern[0] != 0x55 || pattern[1] != 0x00 ||
pattern[2] != 0xaa || pattern[3] != 0xff) {
@@ -124,16 +127,20 @@ static void __init tc_probe(unsigned long startaddr, unsigned long size,
err |= get_dbe(pattern[1], module + TC_PATTERN1);
err |= get_dbe(pattern[2], module + TC_PATTERN2);
err |= get_dbe(pattern[3], module + TC_PATTERN3);
- if (err)
+ if (err) {
+ iounmap(module);
continue;
+ }
}
if (pattern[0] != 0x55 || pattern[1] != 0x00 ||
- pattern[2] != 0xaa || pattern[3] != 0xff)
+ pattern[2] != 0xaa || pattern[3] != 0xff) {
+ iounmap(module);
continue;
+ }
- tc_bus[slot].base_addr = (unsigned long)module;
- for(i = 0; i < 8; i++) {
+ tc_bus[slot].base_addr = slotaddr;
+ for (i = 0; i < 8; i++) {
tc_bus[slot].firmware[i] =
module[TC_FIRM_VER + offset + 4 * i];
tc_bus[slot].vendor[i] =
@@ -171,13 +178,15 @@ static void __init tc_probe(unsigned long startaddr, unsigned long size,
tc_bus[slot].interrupt = -1;
break;
}
+
+ iounmap(module);
}
}
/*
* the main entry
*/
-void __init tc_init(void)
+static int __init tc_init(void)
{
int tc_clock;
int i;
@@ -185,7 +194,7 @@ void __init tc_init(void)
unsigned long slot_size;
if (!TURBOCHANNEL)
- return;
+ return 0;
for (i = 0; i < MAX_SLOT; i++) {
tc_bus[i].base_addr = 0;
@@ -196,8 +205,8 @@ void __init tc_init(void)
tc_bus[i].flags = FREE;
}
- info = (tcinfo *) rex_gettcinfo();
- slot0addr = (unsigned long)KSEG1ADDR(rex_slot_address(0));
+ info = rex_gettcinfo();
+ slot0addr = CPHYSADDR((long)rex_slot_address(0));
switch (mips_machtype) {
case MACH_DS5000_200:
@@ -216,37 +225,24 @@ void __init tc_init(void)
tc_clock = 10000 / info->clk_period;
- if (TURBOCHANNEL && info->slot_size && slot0addr) {
- printk("TURBOchannel rev. %1d at %2d.%1d MHz ", info->revision,
- tc_clock / 10, tc_clock % 10);
- printk("(with%s parity)\n", info->parity ? "" : "out");
+ if (info->slot_size && slot0addr) {
+ pr_info("TURBOchannel rev. %d at %d.%d MHz (with%s parity)\n",
+ info->revision, tc_clock / 10, tc_clock % 10,
+ info->parity ? "" : "out");
slot_size = info->slot_size << 20;
tc_probe(slot0addr, slot_size, num_tcslots);
- /*
- * All TURBOchannel DECstations have the onboard devices
- * where the (num_tcslots + 0 or 1 on DS5k/xx) Option Module
- * would be.
- */
- if(mips_machtype == MACH_DS5000_XX)
- i = 1;
- else
- i = 0;
-
- system_base = slot0addr + slot_size * (num_tcslots + i);
-
-#ifdef TC_DEBUG
- for (i = 0; i < num_tcslots; i++)
- if (tc_bus[i].base_addr) {
- printk(" slot %d: ", i);
- printk("%s %s %s\n", tc_bus[i].vendor,
- tc_bus[i].name, tc_bus[i].firmware);
- }
-#endif
- ioport_resource.end = KSEG2 - 1;
+ for (i = 0; i < num_tcslots; i++) {
+ if (!tc_bus[i].base_addr)
+ continue;
+ pr_info(" slot %d: %s %s %s\n", i, tc_bus[i].vendor,
+ tc_bus[i].name, tc_bus[i].firmware);
+ }
}
+
+ return 0;
}
subsys_initcall(tc_init);
@@ -257,4 +253,3 @@ EXPORT_SYMBOL(release_tc_card);
EXPORT_SYMBOL(get_tc_base_addr);
EXPORT_SYMBOL(get_tc_irq_nr);
EXPORT_SYMBOL(get_tc_speed);
-EXPORT_SYMBOL(system_base);
diff --git a/drivers/tc/zs.c b/drivers/tc/zs.c
index 6bed8713897e..c52af73a251b 100644
--- a/drivers/tc/zs.c
+++ b/drivers/tc/zs.c
@@ -65,14 +65,14 @@
#include <asm/system.h>
#include <asm/uaccess.h>
#include <asm/bootinfo.h>
-#include <asm/dec/serial.h>
-#ifdef CONFIG_MACH_DECSTATION
#include <asm/dec/interrupts.h>
+#include <asm/dec/ioasic_addrs.h>
#include <asm/dec/machtype.h>
+#include <asm/dec/serial.h>
+#include <asm/dec/system.h>
#include <asm/dec/tc.h>
-#include <asm/dec/ioasic_addrs.h>
-#endif
+
#ifdef CONFIG_KGDB
#include <asm/kgdb.h>
#endif
@@ -192,18 +192,6 @@ static void probe_sccs(void);
static void change_speed(struct dec_serial *info);
static void rs_wait_until_sent(struct tty_struct *tty, int timeout);
-/*
- * tmp_buf is used as a temporary buffer by serial_write. We need to
- * lock it in case the copy_from_user blocks while swapping in a page,
- * and some other program tries to do a serial write at the same time.
- * Since the lock will only come under contention when the system is
- * swapping and available memory is low, it makes sense to share one
- * buffer across all the serial ports, since it significantly saves
- * memory if large numbers of serial ports are open.
- */
-static unsigned char tmp_buf[4096]; /* This is cheating */
-static DECLARE_MUTEX(tmp_buf_sem);
-
static inline int serial_paranoia_check(struct dec_serial *info,
char *name, const char *routine)
{
@@ -1628,30 +1616,22 @@ static void __init probe_sccs(void)
return;
}
- /*
- * When serial console is activated, tc_init has not been called yet
- * and system_base is undefined. Unfortunately we have to hardcode
- * system_base for this case :-(. HK
- */
switch(mips_machtype) {
#ifdef CONFIG_MACH_DECSTATION
case MACH_DS5000_2X0:
case MACH_DS5900:
- system_base = KSEG1ADDR(0x1f800000);
n_chips = 2;
zs_parms = &ds_parms;
zs_parms->irq0 = dec_interrupt[DEC_IRQ_SCC0];
zs_parms->irq1 = dec_interrupt[DEC_IRQ_SCC1];
break;
case MACH_DS5000_1XX:
- system_base = KSEG1ADDR(0x1c000000);
n_chips = 2;
zs_parms = &ds_parms;
zs_parms->irq0 = dec_interrupt[DEC_IRQ_SCC0];
zs_parms->irq1 = dec_interrupt[DEC_IRQ_SCC1];
break;
case MACH_DS5000_XX:
- system_base = KSEG1ADDR(0x1c000000);
n_chips = 1;
zs_parms = &ds_parms;
zs_parms->irq0 = dec_interrupt[DEC_IRQ_SCC0];
@@ -1673,10 +1653,10 @@ static void __init probe_sccs(void)
* The sccs reside on the high byte of the 16 bit IOBUS
*/
zs_channels[n_channels].control =
- (volatile unsigned char *)system_base +
+ (volatile void *)CKSEG1ADDR(dec_kn_slot_base +
(0 == chip ? zs_parms->scc0 : zs_parms->scc1) +
(0 == channel ? zs_parms->channel_a_offset :
- zs_parms->channel_b_offset);
+ zs_parms->channel_b_offset));
zs_channels[n_channels].data =
zs_channels[n_channels].control + 4;
diff --git a/drivers/telephony/ixj.h b/drivers/telephony/ixj.h
index 51e3f7f6597b..fbea4541c234 100644
--- a/drivers/telephony/ixj.h
+++ b/drivers/telephony/ixj.h
@@ -40,7 +40,6 @@
*****************************************************************************/
#define IXJ_VERSION 3031
-#include <linux/version.h>
#include <linux/types.h>
#include <linux/ixjuser.h>
diff --git a/drivers/usb/Makefile b/drivers/usb/Makefile
index df014c2a7c54..a50c2bc506f2 100644
--- a/drivers/usb/Makefile
+++ b/drivers/usb/Makefile
@@ -8,6 +8,7 @@ obj-$(CONFIG_USB) += core/
obj-$(CONFIG_USB_MON) += mon/
+obj-$(CONFIG_PCI) += host/
obj-$(CONFIG_USB_EHCI_HCD) += host/
obj-$(CONFIG_USB_ISP116X_HCD) += host/
obj-$(CONFIG_USB_OHCI_HCD) += host/
@@ -17,7 +18,6 @@ obj-$(CONFIG_ETRAX_USB_HOST) += host/
obj-$(CONFIG_USB_ACM) += class/
obj-$(CONFIG_USB_AUDIO) += class/
-obj-$(CONFIG_USB_BLUETOOTH_TTY) += class/
obj-$(CONFIG_USB_MIDI) += class/
obj-$(CONFIG_USB_PRINTER) += class/
diff --git a/drivers/usb/class/Kconfig b/drivers/usb/class/Kconfig
index 333e39bb105f..ef105a92a7bd 100644
--- a/drivers/usb/class/Kconfig
+++ b/drivers/usb/class/Kconfig
@@ -28,29 +28,6 @@ config USB_AUDIO
To compile this driver as a module, choose M here: the
module will be called audio.
-comment "USB Bluetooth TTY can only be used with disabled Bluetooth subsystem"
- depends on USB && BT
-
-config USB_BLUETOOTH_TTY
- tristate "USB Bluetooth TTY support"
- depends on USB && BT=n
- ---help---
- This driver implements a nonstandard tty interface to a Bluetooth
- device that can be used only by specialized Bluetooth HCI software.
-
- Say Y here if you want to use OpenBT Bluetooth stack (available
- at <http://developer.axis.com/software>), or other TTY based
- Bluetooth stacks, and want to connect a USB Bluetooth device
- to your computer's USB port.
-
- Do *not* enable this driver if you want to use generic Linux
- Bluetooth support.
-
- If in doubt, say N here.
-
- To compile this driver as a module, choose M here: the
- module will be called bluetty.
-
config USB_MIDI
tristate "USB MIDI support"
depends on USB && SOUND && OBSOLETE_OSS_USB_DRIVER
diff --git a/drivers/usb/class/Makefile b/drivers/usb/class/Makefile
index 971e5497a3fd..229471247751 100644
--- a/drivers/usb/class/Makefile
+++ b/drivers/usb/class/Makefile
@@ -5,6 +5,5 @@
obj-$(CONFIG_USB_ACM) += cdc-acm.o
obj-$(CONFIG_USB_AUDIO) += audio.o
-obj-$(CONFIG_USB_BLUETOOTH_TTY) += bluetty.o
obj-$(CONFIG_USB_MIDI) += usb-midi.o
obj-$(CONFIG_USB_PRINTER) += usblp.o
diff --git a/drivers/usb/class/bluetty.c b/drivers/usb/class/bluetty.c
deleted file mode 100644
index 524023327c49..000000000000
--- a/drivers/usb/class/bluetty.c
+++ /dev/null
@@ -1,1279 +0,0 @@
-/*
- * bluetty.c Version 0.13
- *
- * Copyright (C) 2000, 2001 Greg Kroah-Hartman <greg@kroah.com>
- * Copyright (C) 2000 Mark Douglas Corner <mcorner@umich.edu>
- *
- * USB Bluetooth TTY driver, based on the Bluetooth Spec version 1.0B
- *
- * (2001/11/30) Version 0.13 gkh
- * - added locking patch from Masoodur Rahman <rmasoodu@in.ibm.com>
- * - removed active variable, as open_count will do.
- *
- * (2001/07/09) Version 0.12 gkh
- * - removed in_interrupt() call, as it doesn't make sense to do
- * that anymore.
- *
- * (2001/06/05) Version 0.11 gkh
- * - Fixed problem with read urb status saying that we have shutdown,
- * and that we shouldn't resubmit the urb. Patch from unknown.
- *
- * (2001/05/28) Version 0.10 gkh
- * - Fixed problem with using data from userspace in the bluetooth_write
- * function as found by the CHECKER project.
- * - Added a buffer to the write_urb_pool which reduces the number of
- * buffers being created and destroyed for ever write. Also cleans
- * up the logic a bit.
- * - Added a buffer to the control_urb_pool which fixes a memory leak
- * when the device is removed from the system.
- *
- * (2001/05/28) Version 0.9 gkh
- * Fixed problem with bluetooth==NULL for bluetooth_read_bulk_callback
- * which was found by both the CHECKER project and Mikko Rahkonen.
- *
- * (08/04/2001) gb
- * Identify version on module load.
- *
- * (2001/03/10) Version 0.8 gkh
- * Fixed problem with not unlinking interrupt urb on device close
- * and resubmitting the read urb on error with bluetooth struct.
- * Thanks to Narayan Mohanram <narayan@RovingNetworks.com> for the
- * fixes.
- *
- * (11/29/2000) Version 0.7 gkh
- * Fixed problem with overrunning the tty flip buffer.
- * Removed unneeded NULL pointer initialization.
- *
- * (10/05/2000) Version 0.6 gkh
- * Fixed bug with urb->dev not being set properly, now that the usb
- * core needs it.
- * Got a real major id number and name.
- *
- * (08/06/2000) Version 0.5 gkh
- * Fixed problem of not resubmitting the bulk read urb if there is
- * an error in the callback. Ericsson devices seem to need this.
- *
- * (07/11/2000) Version 0.4 gkh
- * Fixed bug in disconnect for when we call tty_hangup
- * Fixed bug in bluetooth_ctrl_msg where the bluetooth struct was not
- * getting attached to the control urb properly.
- * Fixed bug in bluetooth_write where we pay attention to the result
- * of bluetooth_ctrl_msg.
- *
- * (08/03/2000) Version 0.3 gkh mdc
- * Merged in Mark's changes to make the driver play nice with the Axis
- * stack.
- * Made the write bulk use an urb pool to enable larger transfers with
- * fewer calls to the driver.
- * Fixed off by one bug in acl pkt receive
- * Made packet counters specific to each bluetooth device
- * Added checks for zero length callbacks
- * Added buffers for int and bulk packets. Had to do this otherwise
- * packet types could intermingle.
- * Made a control urb pool for the control messages.
- *
- * (07/11/2000) Version 0.2 gkh
- * Fixed a small bug found by Nils Faerber in the usb_bluetooth_probe
- * function.
- *
- * (07/09/2000) Version 0.1 gkh
- * Initial release. Has support for sending ACL data (which is really just
- * a HCI frame.) Raw HCI commands and HCI events are not supported.
- * A ioctl will probably be needed for the HCI commands and events in the
- * future. All isoch endpoints are ignored at this time also.
- * This driver should work for all currently shipping USB Bluetooth
- * devices at this time :)
- *
- */
-
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/tty.h>
-#include <linux/tty_driver.h>
-#include <linux/tty_flip.h>
-#include <linux/module.h>
-#include <asm/uaccess.h>
-
-#define DEBUG
-#include <linux/usb.h>
-
-/*
- * Version Information
- */
-#define DRIVER_VERSION "v0.13"
-#define DRIVER_AUTHOR "Greg Kroah-Hartman, Mark Douglas Corner"
-#define DRIVER_DESC "USB Bluetooth tty driver"
-
-/* define this if you have hardware that is not good */
-/*#define BTBUGGYHARDWARE */
-
-/* Class, SubClass, and Protocol codes that describe a Bluetooth device */
-#define WIRELESS_CLASS_CODE 0xe0
-#define RF_SUBCLASS_CODE 0x01
-#define BLUETOOTH_PROGRAMMING_PROTOCOL_CODE 0x01
-
-
-#define BLUETOOTH_TTY_MAJOR 216 /* real device node major id */
-#define BLUETOOTH_TTY_MINORS 256 /* whole lotta bluetooth devices */
-
-#define USB_BLUETOOTH_MAGIC 0x6d02 /* magic number for bluetooth struct */
-
-#define BLUETOOTH_CONTROL_REQUEST_TYPE 0x20
-
-/* Bluetooth packet types */
-#define CMD_PKT 0x01
-#define ACL_PKT 0x02
-#define SCO_PKT 0x03
-#define EVENT_PKT 0x04
-#define ERROR_PKT 0x05
-#define NEG_PKT 0x06
-
-/* Message sizes */
-#define MAX_EVENT_SIZE 0xFF
-#define EVENT_HDR_SIZE 3 /* 2 for the header + 1 for the type indicator */
-#define EVENT_BUFFER_SIZE (MAX_EVENT_SIZE + EVENT_HDR_SIZE)
-
-#define MAX_ACL_SIZE 0xFFFF
-#define ACL_HDR_SIZE 5 /* 4 for the header + 1 for the type indicator */
-#define ACL_BUFFER_SIZE (MAX_ACL_SIZE + ACL_HDR_SIZE)
-
-/* parity check flag */
-#define RELEVANT_IFLAG(iflag) (iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK))
-
-#define CHAR2INT16(c1,c0) (((u32)((c1) & 0xff) << 8) + (u32)((c0) & 0xff))
-
-#define NUM_BULK_URBS 24
-#define NUM_CONTROL_URBS 16
-
-struct usb_bluetooth {
- int magic;
- struct usb_device * dev;
- struct tty_driver * tty_driver; /* the tty_driver for this device */
- struct tty_struct * tty; /* the corresponding tty for this port */
-
- unsigned char minor; /* the starting minor number for this device */
- int throttle; /* throttled by tty layer */
- int open_count;
-
- __u8 control_out_bInterfaceNum;
- struct urb * control_urb_pool[NUM_CONTROL_URBS];
- struct usb_ctrlrequest dr[NUM_CONTROL_URBS];
-
- unsigned char * interrupt_in_buffer;
- struct urb * interrupt_in_urb;
- __u8 interrupt_in_endpointAddress;
- __u8 interrupt_in_interval;
- int interrupt_in_buffer_size;
-
- unsigned char * bulk_in_buffer;
- struct urb * read_urb;
- __u8 bulk_in_endpointAddress;
- int bulk_in_buffer_size;
-
- int bulk_out_buffer_size;
- __u8 bulk_out_endpointAddress;
-
- wait_queue_head_t write_wait;
-
- struct work_struct work; /* work queue entry for line discipline waking up */
-
- unsigned int int_packet_pos;
- unsigned char int_buffer[EVENT_BUFFER_SIZE];
- unsigned int bulk_packet_pos;
- unsigned char bulk_buffer[ACL_BUFFER_SIZE]; /* 64k preallocated, fix? */
- struct semaphore lock;
-};
-
-
-/* local function prototypes */
-static int bluetooth_open (struct tty_struct *tty, struct file *filp);
-static void bluetooth_close (struct tty_struct *tty, struct file *filp);
-static int bluetooth_write (struct tty_struct *tty, const unsigned char *buf, int count);
-static int bluetooth_write_room (struct tty_struct *tty);
-static int bluetooth_chars_in_buffer (struct tty_struct *tty);
-static void bluetooth_throttle (struct tty_struct *tty);
-static void bluetooth_unthrottle (struct tty_struct *tty);
-static int bluetooth_ioctl (struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg);
-static void bluetooth_set_termios (struct tty_struct *tty, struct termios *old);
-
-static void bluetooth_int_callback (struct urb *urb, struct pt_regs *regs);
-static void bluetooth_ctrl_callback (struct urb *urb, struct pt_regs *regs);
-static void bluetooth_read_bulk_callback (struct urb *urb, struct pt_regs *regs);
-static void bluetooth_write_bulk_callback (struct urb *urb, struct pt_regs *regs);
-
-static int usb_bluetooth_probe (struct usb_interface *intf,
- const struct usb_device_id *id);
-static void usb_bluetooth_disconnect (struct usb_interface *intf);
-
-
-static struct usb_device_id usb_bluetooth_ids [] = {
- { USB_DEVICE_INFO(WIRELESS_CLASS_CODE, RF_SUBCLASS_CODE, BLUETOOTH_PROGRAMMING_PROTOCOL_CODE) },
- { } /* Terminating entry */
-};
-
-MODULE_DEVICE_TABLE (usb, usb_bluetooth_ids);
-
-static struct usb_driver usb_bluetooth_driver = {
- .owner = THIS_MODULE,
- .name = "bluetty",
- .probe = usb_bluetooth_probe,
- .disconnect = usb_bluetooth_disconnect,
- .id_table = usb_bluetooth_ids,
-};
-
-static struct tty_driver *bluetooth_tty_driver;
-static struct usb_bluetooth *bluetooth_table[BLUETOOTH_TTY_MINORS];
-
-
-static inline int bluetooth_paranoia_check (struct usb_bluetooth *bluetooth, const char *function)
-{
- if (!bluetooth) {
- dbg("%s - bluetooth == NULL", function);
- return -1;
- }
- if (bluetooth->magic != USB_BLUETOOTH_MAGIC) {
- dbg("%s - bad magic number for bluetooth", function);
- return -1;
- }
-
- return 0;
-}
-
-
-static inline struct usb_bluetooth* get_usb_bluetooth (struct usb_bluetooth *bluetooth, const char *function)
-{
- if (!bluetooth ||
- bluetooth_paranoia_check (bluetooth, function)) {
- /* then say that we don't have a valid usb_bluetooth thing, which will
- * end up generating -ENODEV return values */
- return NULL;
- }
-
- return bluetooth;
-}
-
-
-static inline struct usb_bluetooth *get_bluetooth_by_index (int index)
-{
- return bluetooth_table[index];
-}
-
-
-static int bluetooth_ctrl_msg (struct usb_bluetooth *bluetooth, int request, int value, const unsigned char *buf, int len)
-{
- struct urb *urb = NULL;
- struct usb_ctrlrequest *dr = NULL;
- int i;
- int status;
-
- dbg ("%s", __FUNCTION__);
-
- /* try to find a free urb in our list */
- for (i = 0; i < NUM_CONTROL_URBS; ++i) {
- if (bluetooth->control_urb_pool[i]->status != -EINPROGRESS) {
- urb = bluetooth->control_urb_pool[i];
- dr = &bluetooth->dr[i];
- break;
- }
- }
- if (urb == NULL) {
- dbg ("%s - no free urbs", __FUNCTION__);
- return -ENOMEM;
- }
-
- /* keep increasing the urb transfer buffer to fit the size of the message */
- if (urb->transfer_buffer == NULL) {
- urb->transfer_buffer = kmalloc (len, GFP_KERNEL);
- if (urb->transfer_buffer == NULL) {
- err ("%s - out of memory", __FUNCTION__);
- return -ENOMEM;
- }
- }
- if (urb->transfer_buffer_length < len) {
- kfree(urb->transfer_buffer);
- urb->transfer_buffer = kmalloc (len, GFP_KERNEL);
- if (urb->transfer_buffer == NULL) {
- err ("%s - out of memory", __FUNCTION__);
- return -ENOMEM;
- }
- }
- memcpy (urb->transfer_buffer, buf, len);
-
- dr->bRequestType= BLUETOOTH_CONTROL_REQUEST_TYPE;
- dr->bRequest = request;
- dr->wValue = cpu_to_le16((u16) value);
- dr->wIndex = cpu_to_le16((u16) bluetooth->control_out_bInterfaceNum);
- dr->wLength = cpu_to_le16((u16) len);
-
- usb_fill_control_urb (urb, bluetooth->dev, usb_sndctrlpipe(bluetooth->dev, 0),
- (unsigned char*)dr, urb->transfer_buffer, len, bluetooth_ctrl_callback, bluetooth);
-
- /* send it down the pipe */
- status = usb_submit_urb(urb, GFP_KERNEL);
- if (status)
- dbg("%s - usb_submit_urb(control) failed with status = %d", __FUNCTION__, status);
-
- return status;
-}
-
-
-
-
-
-/*****************************************************************************
- * Driver tty interface functions
- *****************************************************************************/
-static int bluetooth_open (struct tty_struct *tty, struct file * filp)
-{
- struct usb_bluetooth *bluetooth;
- int result;
-
- dbg("%s", __FUNCTION__);
-
- /* initialize the pointer incase something fails */
- tty->driver_data = NULL;
-
- /* get the bluetooth object associated with this tty pointer */
- bluetooth = get_bluetooth_by_index (tty->index);
-
- if (bluetooth_paranoia_check (bluetooth, __FUNCTION__)) {
- return -ENODEV;
- }
-
- down (&bluetooth->lock);
-
- ++bluetooth->open_count;
- if (bluetooth->open_count == 1) {
- /* set up our structure making the tty driver remember our object, and us it */
- tty->driver_data = bluetooth;
- bluetooth->tty = tty;
-
- /* force low_latency on so that our tty_push actually forces the data through,
- * otherwise it is scheduled, and with high data rates (like with OHCI) data
- * can get lost. */
- bluetooth->tty->low_latency = 1;
-
- /* Reset the packet position counters */
- bluetooth->int_packet_pos = 0;
- bluetooth->bulk_packet_pos = 0;
-
-#ifndef BTBUGGYHARDWARE
- /* Start reading from the device */
- usb_fill_bulk_urb (bluetooth->read_urb, bluetooth->dev,
- usb_rcvbulkpipe(bluetooth->dev, bluetooth->bulk_in_endpointAddress),
- bluetooth->bulk_in_buffer,
- bluetooth->bulk_in_buffer_size,
- bluetooth_read_bulk_callback, bluetooth);
- result = usb_submit_urb(bluetooth->read_urb, GFP_KERNEL);
- if (result)
- dbg("%s - usb_submit_urb(read bulk) failed with status %d", __FUNCTION__, result);
-#endif
- usb_fill_int_urb (bluetooth->interrupt_in_urb, bluetooth->dev,
- usb_rcvintpipe(bluetooth->dev, bluetooth->interrupt_in_endpointAddress),
- bluetooth->interrupt_in_buffer,
- bluetooth->interrupt_in_buffer_size,
- bluetooth_int_callback, bluetooth,
- bluetooth->interrupt_in_interval);
- result = usb_submit_urb(bluetooth->interrupt_in_urb, GFP_KERNEL);
- if (result)
- dbg("%s - usb_submit_urb(interrupt in) failed with status %d", __FUNCTION__, result);
- }
-
- up(&bluetooth->lock);
-
- return 0;
-}
-
-
-static void bluetooth_close (struct tty_struct *tty, struct file * filp)
-{
- struct usb_bluetooth *bluetooth = get_usb_bluetooth ((struct usb_bluetooth *)tty->driver_data, __FUNCTION__);
-
- if (!bluetooth) {
- return;
- }
-
- dbg("%s", __FUNCTION__);
-
- if (!bluetooth->open_count) {
- dbg ("%s - device not opened", __FUNCTION__);
- return;
- }
-
- down (&bluetooth->lock);
-
- --bluetooth->open_count;
- if (bluetooth->open_count <= 0) {
- bluetooth->open_count = 0;
-
- /* shutdown any in-flight urbs that we know about */
- usb_kill_urb (bluetooth->read_urb);
- usb_kill_urb (bluetooth->interrupt_in_urb);
- }
- up(&bluetooth->lock);
-}
-
-
-static int bluetooth_write (struct tty_struct * tty, const unsigned char *buf, int count)
-{
- struct usb_bluetooth *bluetooth = get_usb_bluetooth ((struct usb_bluetooth *)tty->driver_data, __FUNCTION__);
- struct urb *urb = NULL;
- unsigned char *temp_buffer = NULL;
- const unsigned char *current_buffer;
- unsigned char *urb_buffer;
- int i;
- int retval = 0;
-
- if (!bluetooth) {
- return -ENODEV;
- }
-
- dbg("%s - %d byte(s)", __FUNCTION__, count);
-
- if (!bluetooth->open_count) {
- dbg ("%s - device not opened", __FUNCTION__);
- return -EINVAL;
- }
-
- if (count == 0) {
- dbg("%s - write request of 0 bytes", __FUNCTION__);
- return 0;
- }
- if (count == 1) {
- dbg("%s - write request only included type %d", __FUNCTION__, buf[0]);
- return 1;
- }
-
-#ifdef DEBUG
- printk (KERN_DEBUG __FILE__ ": %s - length = %d, data = ", __FUNCTION__, count);
- for (i = 0; i < count; ++i) {
- printk ("%.2x ", buf[i]);
- }
- printk ("\n");
-#endif
-
- current_buffer = buf;
-
- switch (*current_buffer) {
- /* First byte indicates the type of packet */
- case CMD_PKT:
- /* dbg("%s- Send cmd_pkt len:%d", __FUNCTION__, count);*/
-
- retval = bluetooth_ctrl_msg (bluetooth, 0x00, 0x00, &current_buffer[1], count-1);
- if (retval) {
- goto exit;
- }
- retval = count;
- break;
-
- case ACL_PKT:
- ++current_buffer;
- --count;
-
- urb_buffer = kmalloc (count, GFP_ATOMIC);
- if (!urb_buffer) {
- dev_err(&bluetooth->dev->dev, "out of memory\n");
- retval = -ENOMEM;
- goto exit;
- }
-
- urb = usb_alloc_urb(0, GFP_ATOMIC);
- if (!urb) {
- dev_err(&bluetooth->dev->dev, "no more free urbs\n");
- kfree(urb_buffer);
- retval = -ENOMEM;
- goto exit;
- }
- memcpy (urb_buffer, current_buffer, count);
-
- /* build up our urb */
- usb_fill_bulk_urb(urb, bluetooth->dev,
- usb_sndbulkpipe(bluetooth->dev,
- bluetooth->bulk_out_endpointAddress),
- urb_buffer,
- count,
- bluetooth_write_bulk_callback,
- bluetooth);
-
-
- /* send it down the pipe */
- retval = usb_submit_urb(urb, GFP_KERNEL);
- if (retval) {
- dbg("%s - usb_submit_urb(write bulk) failed with error = %d", __FUNCTION__, retval);
- goto exit;
- }
-
- /* we are done with this urb, so let the host driver
- * really free it when it is finished with it */
- usb_free_urb (urb);
- retval = count + 1;
- break;
-
- default :
- dbg("%s - unsupported (at this time) write type", __FUNCTION__);
- retval = -EINVAL;
- break;
- }
-
-exit:
- kfree(temp_buffer);
-
- return retval;
-}
-
-
-static int bluetooth_write_room (struct tty_struct *tty)
-{
- dbg("%s", __FUNCTION__);
-
- /*
- * We really can take anything the user throws at us
- * but let's pick a nice big number to tell the tty
- * layer that we have lots of free space
- */
- return 2048;
-}
-
-
-static int bluetooth_chars_in_buffer (struct tty_struct *tty)
-{
- dbg("%s", __FUNCTION__);
-
- /*
- * We can't really account for how much data we
- * have sent out, but hasn't made it through to the
- * device, so just tell the tty layer that everything
- * is flushed.
- */
- return 0;
-}
-
-
-static void bluetooth_throttle (struct tty_struct * tty)
-{
- struct usb_bluetooth *bluetooth = get_usb_bluetooth ((struct usb_bluetooth *)tty->driver_data, __FUNCTION__);
-
- if (!bluetooth) {
- return;
- }
-
- dbg("%s", __FUNCTION__);
-
- if (!bluetooth->open_count) {
- dbg ("%s - device not open", __FUNCTION__);
- return;
- }
-
- dbg("%s unsupported (at this time)", __FUNCTION__);
-
- return;
-}
-
-
-static void bluetooth_unthrottle (struct tty_struct * tty)
-{
- struct usb_bluetooth *bluetooth = get_usb_bluetooth ((struct usb_bluetooth *)tty->driver_data, __FUNCTION__);
-
- if (!bluetooth) {
- return;
- }
-
- dbg("%s", __FUNCTION__);
-
- if (!bluetooth->open_count) {
- dbg ("%s - device not open", __FUNCTION__);
- return;
- }
-
- dbg("%s unsupported (at this time)", __FUNCTION__);
-}
-
-
-static int bluetooth_ioctl (struct tty_struct *tty, struct file * file, unsigned int cmd, unsigned long arg)
-{
- struct usb_bluetooth *bluetooth = get_usb_bluetooth ((struct usb_bluetooth *)tty->driver_data, __FUNCTION__);
-
- if (!bluetooth) {
- return -ENODEV;
- }
-
- dbg("%s - cmd 0x%.4x", __FUNCTION__, cmd);
-
- if (!bluetooth->open_count) {
- dbg ("%s - device not open", __FUNCTION__);
- return -ENODEV;
- }
-
- /* FIXME!!! */
- return -ENOIOCTLCMD;
-}
-
-
-static void bluetooth_set_termios (struct tty_struct *tty, struct termios * old)
-{
- struct usb_bluetooth *bluetooth = get_usb_bluetooth ((struct usb_bluetooth *)tty->driver_data, __FUNCTION__);
-
- if (!bluetooth) {
- return;
- }
-
- dbg("%s", __FUNCTION__);
-
- if (!bluetooth->open_count) {
- dbg ("%s - device not open", __FUNCTION__);
- return;
- }
-
- /* FIXME!!! */
-
- return;
-}
-
-
-#ifdef BTBUGGYHARDWARE
-void btusb_enable_bulk_read(struct tty_struct *tty){
- struct usb_bluetooth *bluetooth = get_usb_bluetooth ((struct usb_bluetooth *)tty->driver_data, __FUNCTION__);
- int result;
-
- if (!bluetooth) {
- return;
- }
-
- dbg("%s", __FUNCTION__);
-
- if (!bluetooth->open_count) {
- dbg ("%s - device not open", __FUNCTION__);
- return;
- }
-
- if (bluetooth->read_urb) {
- usb_fill_bulk_urb(bluetooth->read_urb, bluetooth->dev,
- usb_rcvbulkpipe(bluetooth->dev, bluetooth->bulk_in_endpointAddress),
- bluetooth->bulk_in_buffer, bluetooth->bulk_in_buffer_size,
- bluetooth_read_bulk_callback, bluetooth);
- result = usb_submit_urb(bluetooth->read_urb, GFP_KERNEL);
- if (result)
- err ("%s - failed submitting read urb, error %d", __FUNCTION__, result);
- }
-}
-
-void btusb_disable_bulk_read(struct tty_struct *tty){
- struct usb_bluetooth *bluetooth = get_usb_bluetooth ((struct usb_bluetooth *)tty->driver_data, __FUNCTION__);
-
- if (!bluetooth) {
- return;
- }
-
- dbg("%s", __FUNCTION__);
-
- if (!bluetooth->open_count) {
- dbg ("%s - device not open", __FUNCTION__);
- return;
- }
-
- if ((bluetooth->read_urb) && (bluetooth->read_urb->actual_length))
- usb_kill_urb(bluetooth->read_urb);
-}
-#endif
-
-
-/*****************************************************************************
- * urb callback functions
- *****************************************************************************/
-
-
-static void bluetooth_int_callback (struct urb *urb, struct pt_regs *regs)
-{
- struct usb_bluetooth *bluetooth = get_usb_bluetooth ((struct usb_bluetooth *)urb->context, __FUNCTION__);
- unsigned char *data = urb->transfer_buffer;
- unsigned int i;
- unsigned int count = urb->actual_length;
- unsigned int packet_size;
- int status;
-
- dbg("%s", __FUNCTION__);
-
- if (!bluetooth) {
- dbg("%s - bad bluetooth pointer, exiting", __FUNCTION__);
- return;
- }
-
- switch (urb->status) {
- case 0:
- /* success */
- break;
- case -ECONNRESET:
- case -ENOENT:
- case -ESHUTDOWN:
- /* this urb is terminated, clean up */
- dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status);
- return;
- default:
- dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status);
- goto exit;
- }
-
- if (!count) {
- dbg("%s - zero length int", __FUNCTION__);
- goto exit;
- }
-
-
-#ifdef DEBUG
- if (count) {
- printk (KERN_DEBUG __FILE__ ": %s- length = %d, data = ", __FUNCTION__, count);
- for (i = 0; i < count; ++i) {
- printk ("%.2x ", data[i]);
- }
- printk ("\n");
- }
-#endif
-
-#ifdef BTBUGGYHARDWARE
- if ((count >= 2) && (data[0] == 0xFF) && (data[1] == 0x00)) {
- data += 2;
- count -= 2;
- }
- if (count == 0) {
- urb->actual_length = 0;
- goto exit;
- }
-#endif
- /* We add a packet type identifier to the beginning of each
- HCI frame. This makes the data in the tty look like a
- serial USB devices. Each HCI frame can be broken across
- multiple URBs so we buffer them until we have a full hci
- packet */
-
- if (!bluetooth->int_packet_pos) {
- bluetooth->int_buffer[0] = EVENT_PKT;
- bluetooth->int_packet_pos++;
- }
-
- if (bluetooth->int_packet_pos + count > EVENT_BUFFER_SIZE) {
- err("%s - exceeded EVENT_BUFFER_SIZE", __FUNCTION__);
- bluetooth->int_packet_pos = 0;
- goto exit;
- }
-
- memcpy (&bluetooth->int_buffer[bluetooth->int_packet_pos],
- urb->transfer_buffer, count);
- bluetooth->int_packet_pos += count;
- urb->actual_length = 0;
-
- if (bluetooth->int_packet_pos >= EVENT_HDR_SIZE)
- packet_size = bluetooth->int_buffer[2];
- else
- goto exit;
-
- if (packet_size + EVENT_HDR_SIZE < bluetooth->int_packet_pos) {
- err("%s - packet was too long", __FUNCTION__);
- bluetooth->int_packet_pos = 0;
- goto exit;
- }
-
- if (packet_size + EVENT_HDR_SIZE == bluetooth->int_packet_pos) {
- for (i = 0; i < bluetooth->int_packet_pos; ++i) {
- /* if we insert more than TTY_FLIPBUF_SIZE characters, we drop them */
- if (bluetooth->tty->flip.count >= TTY_FLIPBUF_SIZE) {
- tty_flip_buffer_push(bluetooth->tty);
- }
- tty_insert_flip_char(bluetooth->tty, bluetooth->int_buffer[i], 0);
- }
- tty_flip_buffer_push(bluetooth->tty);
-
- bluetooth->int_packet_pos = 0;
- }
-
-exit:
- status = usb_submit_urb (urb, GFP_ATOMIC);
- if (status)
- err ("%s - usb_submit_urb failed with result %d",
- __FUNCTION__, status);
-}
-
-
-static void bluetooth_ctrl_callback (struct urb *urb, struct pt_regs *regs)
-{
- struct usb_bluetooth *bluetooth = get_usb_bluetooth ((struct usb_bluetooth *)urb->context, __FUNCTION__);
-
- dbg("%s", __FUNCTION__);
-
- if (!bluetooth) {
- dbg("%s - bad bluetooth pointer, exiting", __FUNCTION__);
- return;
- }
-
- if (urb->status) {
- dbg("%s - nonzero read bulk status received: %d", __FUNCTION__, urb->status);
- return;
- }
-}
-
-
-static void bluetooth_read_bulk_callback (struct urb *urb, struct pt_regs *regs)
-{
- struct usb_bluetooth *bluetooth = get_usb_bluetooth ((struct usb_bluetooth *)urb->context, __FUNCTION__);
- unsigned char *data = urb->transfer_buffer;
- unsigned int count = urb->actual_length;
- unsigned int i;
- unsigned int packet_size;
- int result;
-
-
- dbg("%s", __FUNCTION__);
-
- if (!bluetooth) {
- dbg("%s - bad bluetooth pointer, exiting", __FUNCTION__);
- return;
- }
-
- if (urb->status) {
- dbg("%s - nonzero read bulk status received: %d", __FUNCTION__, urb->status);
- if (urb->status == -ENOENT) {
- dbg("%s - URB canceled, won't reschedule", __FUNCTION__);
- return;
- }
- goto exit;
- }
-
- if (!count) {
- dbg("%s - zero length read bulk", __FUNCTION__);
- goto exit;
- }
-
-#ifdef DEBUG
- if (count) {
- printk (KERN_DEBUG __FILE__ ": %s- length = %d, data = ", __FUNCTION__, count);
- for (i = 0; i < count; ++i) {
- printk ("%.2x ", data[i]);
- }
- printk ("\n");
- }
-#endif
-#ifdef BTBUGGYHARDWARE
- if ((count == 4) && (data[0] == 0x00) && (data[1] == 0x00)
- && (data[2] == 0x00) && (data[3] == 0x00)) {
- urb->actual_length = 0;
- usb_fill_bulk_urb(bluetooth->read_urb, bluetooth->dev,
- usb_rcvbulkpipe(bluetooth->dev, bluetooth->bulk_in_endpointAddress),
- bluetooth->bulk_in_buffer, bluetooth->bulk_in_buffer_size,
- bluetooth_read_bulk_callback, bluetooth);
- result = usb_submit_urb(bluetooth->read_urb, GFP_KERNEL);
- if (result)
- err ("%s - failed resubmitting read urb, error %d", __FUNCTION__, result);
-
- return;
- }
-#endif
- /* We add a packet type identifier to the beginning of each
- HCI frame. This makes the data in the tty look like a
- serial USB devices. Each HCI frame can be broken across
- multiple URBs so we buffer them until we have a full hci
- packet */
-
- if (!bluetooth->bulk_packet_pos) {
- bluetooth->bulk_buffer[0] = ACL_PKT;
- bluetooth->bulk_packet_pos++;
- }
-
- if (bluetooth->bulk_packet_pos + count > ACL_BUFFER_SIZE) {
- err("%s - exceeded ACL_BUFFER_SIZE", __FUNCTION__);
- bluetooth->bulk_packet_pos = 0;
- goto exit;
- }
-
- memcpy (&bluetooth->bulk_buffer[bluetooth->bulk_packet_pos],
- urb->transfer_buffer, count);
- bluetooth->bulk_packet_pos += count;
- urb->actual_length = 0;
-
- if (bluetooth->bulk_packet_pos >= ACL_HDR_SIZE) {
- packet_size = CHAR2INT16(bluetooth->bulk_buffer[4],bluetooth->bulk_buffer[3]);
- } else {
- goto exit;
- }
-
- if (packet_size + ACL_HDR_SIZE < bluetooth->bulk_packet_pos) {
- err("%s - packet was too long", __FUNCTION__);
- bluetooth->bulk_packet_pos = 0;
- goto exit;
- }
-
- if (packet_size + ACL_HDR_SIZE == bluetooth->bulk_packet_pos) {
- for (i = 0; i < bluetooth->bulk_packet_pos; ++i) {
- /* if we insert more than TTY_FLIPBUF_SIZE characters, we drop them. */
- if (bluetooth->tty->flip.count >= TTY_FLIPBUF_SIZE) {
- tty_flip_buffer_push(bluetooth->tty);
- }
- tty_insert_flip_char(bluetooth->tty, bluetooth->bulk_buffer[i], 0);
- }
- tty_flip_buffer_push(bluetooth->tty);
- bluetooth->bulk_packet_pos = 0;
- }
-
-exit:
- if (!bluetooth || !bluetooth->open_count)
- return;
-
- usb_fill_bulk_urb(bluetooth->read_urb, bluetooth->dev,
- usb_rcvbulkpipe(bluetooth->dev, bluetooth->bulk_in_endpointAddress),
- bluetooth->bulk_in_buffer, bluetooth->bulk_in_buffer_size,
- bluetooth_read_bulk_callback, bluetooth);
- result = usb_submit_urb(bluetooth->read_urb, GFP_KERNEL);
- if (result)
- err ("%s - failed resubmitting read urb, error %d", __FUNCTION__, result);
-
- return;
-}
-
-
-static void bluetooth_write_bulk_callback (struct urb *urb, struct pt_regs *regs)
-{
- struct usb_bluetooth *bluetooth = get_usb_bluetooth ((struct usb_bluetooth *)urb->context, __FUNCTION__);
-
- dbg("%s", __FUNCTION__);
-
- /* free up the transfer buffer, as usb_free_urb() does not do this */
- kfree(urb->transfer_buffer);
-
- if (!bluetooth) {
- dbg("%s - bad bluetooth pointer, exiting", __FUNCTION__);
- return;
- }
-
- if (urb->status) {
- dbg("%s - nonzero write bulk status received: %d", __FUNCTION__, urb->status);
- return;
- }
-
- /* wake up our little function to let the tty layer know that something happened */
- schedule_work(&bluetooth->work);
-}
-
-
-static void bluetooth_softint(void *private)
-{
- struct usb_bluetooth *bluetooth = get_usb_bluetooth ((struct usb_bluetooth *)private, __FUNCTION__);
-
- dbg("%s", __FUNCTION__);
-
- if (!bluetooth)
- return;
-
- tty_wakeup(bluetooth->tty);
-}
-
-
-static int usb_bluetooth_probe (struct usb_interface *intf,
- const struct usb_device_id *id)
-{
- struct usb_device *dev = interface_to_usbdev (intf);
- struct usb_bluetooth *bluetooth = NULL;
- struct usb_host_interface *interface;
- struct usb_endpoint_descriptor *endpoint;
- struct usb_endpoint_descriptor *interrupt_in_endpoint[8];
- struct usb_endpoint_descriptor *bulk_in_endpoint[8];
- struct usb_endpoint_descriptor *bulk_out_endpoint[8];
- int control_out_endpoint;
-
- int minor;
- int buffer_size;
- int i;
- int num_interrupt_in = 0;
- int num_bulk_in = 0;
- int num_bulk_out = 0;
-
- interface = intf->cur_altsetting;
- control_out_endpoint = interface->desc.bInterfaceNumber;
-
- /* find the endpoints that we need */
- for (i = 0; i < interface->desc.bNumEndpoints; ++i) {
- endpoint = &interface->endpoint[i].desc;
-
- if ((endpoint->bEndpointAddress & 0x80) &&
- ((endpoint->bmAttributes & 3) == 0x02)) {
- /* we found a bulk in endpoint */
- dbg("found bulk in");
- bulk_in_endpoint[num_bulk_in] = endpoint;
- ++num_bulk_in;
- }
-
- if (((endpoint->bEndpointAddress & 0x80) == 0x00) &&
- ((endpoint->bmAttributes & 3) == 0x02)) {
- /* we found a bulk out endpoint */
- dbg("found bulk out");
- bulk_out_endpoint[num_bulk_out] = endpoint;
- ++num_bulk_out;
- }
-
- if ((endpoint->bEndpointAddress & 0x80) &&
- ((endpoint->bmAttributes & 3) == 0x03)) {
- /* we found a interrupt in endpoint */
- dbg("found interrupt in");
- interrupt_in_endpoint[num_interrupt_in] = endpoint;
- ++num_interrupt_in;
- }
- }
-
- /* according to the spec, we can only have 1 bulk_in, 1 bulk_out, and 1 interrupt_in endpoints */
- if ((num_bulk_in != 1) ||
- (num_bulk_out != 1) ||
- (num_interrupt_in != 1)) {
- dbg ("%s - improper number of endpoints. Bluetooth driver not bound.", __FUNCTION__);
- return -EIO;
- }
-
- info("USB Bluetooth converter detected");
-
- for (minor = 0; minor < BLUETOOTH_TTY_MINORS && bluetooth_table[minor]; ++minor)
- ;
- if (bluetooth_table[minor]) {
- err("No more free Bluetooth devices");
- return -ENODEV;
- }
-
- if (!(bluetooth = kmalloc(sizeof(struct usb_bluetooth), GFP_KERNEL))) {
- err("Out of memory");
- return -ENOMEM;
- }
-
- memset(bluetooth, 0, sizeof(struct usb_bluetooth));
-
- bluetooth->magic = USB_BLUETOOTH_MAGIC;
- bluetooth->dev = dev;
- bluetooth->minor = minor;
- INIT_WORK(&bluetooth->work, bluetooth_softint, bluetooth);
- init_MUTEX(&bluetooth->lock);
-
- /* record the interface number for the control out */
- bluetooth->control_out_bInterfaceNum = control_out_endpoint;
-
- /* create our control out urb pool */
- for (i = 0; i < NUM_CONTROL_URBS; ++i) {
- struct urb *urb = usb_alloc_urb(0, GFP_KERNEL);
- if (urb == NULL) {
- err("No free urbs available");
- goto probe_error;
- }
- urb->transfer_buffer = NULL;
- bluetooth->control_urb_pool[i] = urb;
- }
-
- /* set up the endpoint information */
- endpoint = bulk_in_endpoint[0];
- bluetooth->read_urb = usb_alloc_urb (0, GFP_KERNEL);
- if (!bluetooth->read_urb) {
- err("No free urbs available");
- goto probe_error;
- }
- bluetooth->bulk_in_buffer_size = buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);
- bluetooth->bulk_in_endpointAddress = endpoint->bEndpointAddress;
- bluetooth->bulk_in_buffer = kmalloc (buffer_size, GFP_KERNEL);
- if (!bluetooth->bulk_in_buffer) {
- err("Couldn't allocate bulk_in_buffer");
- goto probe_error;
- }
- usb_fill_bulk_urb(bluetooth->read_urb, dev, usb_rcvbulkpipe(dev, endpoint->bEndpointAddress),
- bluetooth->bulk_in_buffer, buffer_size, bluetooth_read_bulk_callback, bluetooth);
-
- endpoint = bulk_out_endpoint[0];
- bluetooth->bulk_out_endpointAddress = endpoint->bEndpointAddress;
- bluetooth->bulk_out_buffer_size = le16_to_cpu(endpoint->wMaxPacketSize) * 2;
-
- endpoint = interrupt_in_endpoint[0];
- bluetooth->interrupt_in_urb = usb_alloc_urb(0, GFP_KERNEL);
- if (!bluetooth->interrupt_in_urb) {
- err("No free urbs available");
- goto probe_error;
- }
- bluetooth->interrupt_in_buffer_size = buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);
- bluetooth->interrupt_in_endpointAddress = endpoint->bEndpointAddress;
- bluetooth->interrupt_in_interval = endpoint->bInterval;
- bluetooth->interrupt_in_buffer = kmalloc (buffer_size, GFP_KERNEL);
- if (!bluetooth->interrupt_in_buffer) {
- err("Couldn't allocate interrupt_in_buffer");
- goto probe_error;
- }
- usb_fill_int_urb(bluetooth->interrupt_in_urb, dev, usb_rcvintpipe(dev, endpoint->bEndpointAddress),
- bluetooth->interrupt_in_buffer, buffer_size, bluetooth_int_callback,
- bluetooth, endpoint->bInterval);
-
- /* initialize the devfs nodes for this device and let the user know what bluetooths we are bound to */
- tty_register_device (bluetooth_tty_driver, minor, &intf->dev);
- info("Bluetooth converter now attached to ttyUB%d (or usb/ttub/%d for devfs)", minor, minor);
-
- bluetooth_table[minor] = bluetooth;
-
- /* success */
- usb_set_intfdata (intf, bluetooth);
- return 0;
-
-probe_error:
- if (bluetooth->read_urb)
- usb_free_urb (bluetooth->read_urb);
- if (bluetooth->bulk_in_buffer)
- kfree (bluetooth->bulk_in_buffer);
- if (bluetooth->interrupt_in_urb)
- usb_free_urb (bluetooth->interrupt_in_urb);
- if (bluetooth->interrupt_in_buffer)
- kfree (bluetooth->interrupt_in_buffer);
- for (i = 0; i < NUM_CONTROL_URBS; ++i)
- if (bluetooth->control_urb_pool[i]) {
- if (bluetooth->control_urb_pool[i]->transfer_buffer)
- kfree (bluetooth->control_urb_pool[i]->transfer_buffer);
- usb_free_urb (bluetooth->control_urb_pool[i]);
- }
-
- bluetooth_table[minor] = NULL;
-
- /* free up any memory that we allocated */
- kfree (bluetooth);
- return -EIO;
-}
-
-
-static void usb_bluetooth_disconnect(struct usb_interface *intf)
-{
- struct usb_bluetooth *bluetooth = usb_get_intfdata (intf);
- int i;
-
- usb_set_intfdata (intf, NULL);
- if (bluetooth) {
- if ((bluetooth->open_count) && (bluetooth->tty))
- tty_hangup(bluetooth->tty);
-
- bluetooth->open_count = 0;
-
- if (bluetooth->read_urb) {
- usb_kill_urb (bluetooth->read_urb);
- usb_free_urb (bluetooth->read_urb);
- }
- if (bluetooth->bulk_in_buffer)
- kfree (bluetooth->bulk_in_buffer);
-
- if (bluetooth->interrupt_in_urb) {
- usb_kill_urb (bluetooth->interrupt_in_urb);
- usb_free_urb (bluetooth->interrupt_in_urb);
- }
- if (bluetooth->interrupt_in_buffer)
- kfree (bluetooth->interrupt_in_buffer);
-
- tty_unregister_device (bluetooth_tty_driver, bluetooth->minor);
-
- for (i = 0; i < NUM_CONTROL_URBS; ++i) {
- if (bluetooth->control_urb_pool[i]) {
- usb_kill_urb (bluetooth->control_urb_pool[i]);
- if (bluetooth->control_urb_pool[i]->transfer_buffer)
- kfree (bluetooth->control_urb_pool[i]->transfer_buffer);
- usb_free_urb (bluetooth->control_urb_pool[i]);
- }
- }
-
- info("Bluetooth converter now disconnected from ttyUB%d", bluetooth->minor);
-
- bluetooth_table[bluetooth->minor] = NULL;
-
- /* free up any memory that we allocated */
- kfree (bluetooth);
- } else {
- info("device disconnected");
- }
-}
-
-static struct tty_operations bluetooth_ops = {
- .open = bluetooth_open,
- .close = bluetooth_close,
- .write = bluetooth_write,
- .write_room = bluetooth_write_room,
- .ioctl = bluetooth_ioctl,
- .set_termios = bluetooth_set_termios,
- .throttle = bluetooth_throttle,
- .unthrottle = bluetooth_unthrottle,
- .chars_in_buffer = bluetooth_chars_in_buffer,
-};
-
-static int usb_bluetooth_init(void)
-{
- int i;
- int result;
-
- /* Initialize our global data */
- for (i = 0; i < BLUETOOTH_TTY_MINORS; ++i) {
- bluetooth_table[i] = NULL;
- }
-
- info ("USB Bluetooth support registered");
-
- bluetooth_tty_driver = alloc_tty_driver(BLUETOOTH_TTY_MINORS);
- if (!bluetooth_tty_driver)
- return -ENOMEM;
-
- bluetooth_tty_driver->owner = THIS_MODULE;
- bluetooth_tty_driver->driver_name = "usb-bluetooth";
- bluetooth_tty_driver->name = "ttyUB";
- bluetooth_tty_driver->devfs_name = "usb/ttub/";
- bluetooth_tty_driver->major = BLUETOOTH_TTY_MAJOR;
- bluetooth_tty_driver->minor_start = 0;
- bluetooth_tty_driver->type = TTY_DRIVER_TYPE_SERIAL;
- bluetooth_tty_driver->subtype = SERIAL_TYPE_NORMAL;
- bluetooth_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS;
- bluetooth_tty_driver->init_termios = tty_std_termios;
- bluetooth_tty_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
- tty_set_operations(bluetooth_tty_driver, &bluetooth_ops);
- if (tty_register_driver (bluetooth_tty_driver)) {
- err("%s - failed to register tty driver", __FUNCTION__);
- put_tty_driver(bluetooth_tty_driver);
- return -1;
- }
-
- /* register the USB driver */
- result = usb_register(&usb_bluetooth_driver);
- if (result < 0) {
- tty_unregister_driver(bluetooth_tty_driver);
- put_tty_driver(bluetooth_tty_driver);
- err("usb_register failed for the USB bluetooth driver. Error number %d", result);
- return -1;
- }
-
- info(DRIVER_DESC " " DRIVER_VERSION);
-
- return 0;
-}
-
-
-static void usb_bluetooth_exit(void)
-{
- usb_deregister(&usb_bluetooth_driver);
- tty_unregister_driver(bluetooth_tty_driver);
- put_tty_driver(bluetooth_tty_driver);
-}
-
-
-module_init(usb_bluetooth_init);
-module_exit(usb_bluetooth_exit);
-
-/* Module information */
-MODULE_AUTHOR( DRIVER_AUTHOR );
-MODULE_DESCRIPTION( DRIVER_DESC );
-MODULE_LICENSE("GPL");
-
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
index 16ecad30e29c..1b4751412970 100644
--- a/drivers/usb/class/cdc-acm.c
+++ b/drivers/usb/class/cdc-acm.c
@@ -827,11 +827,10 @@ skip_normal_probe:
return -ENODEV;
}
- if (!(acm = kmalloc(sizeof(struct acm), GFP_KERNEL))) {
- dev_dbg(&intf->dev, "out of memory (acm kmalloc)\n");
+ if (!(acm = kzalloc(sizeof(struct acm), GFP_KERNEL))) {
+ dev_dbg(&intf->dev, "out of memory (acm kzalloc)\n");
goto alloc_fail;
}
- memset(acm, 0, sizeof(struct acm));
ctrlsize = le16_to_cpu(epctrl->wMaxPacketSize);
readsize = le16_to_cpu(epread->wMaxPacketSize);
diff --git a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c
index e195709c9c7f..357e75335f17 100644
--- a/drivers/usb/class/usblp.c
+++ b/drivers/usb/class/usblp.c
@@ -844,9 +844,8 @@ static struct file_operations usblp_fops = {
};
static struct usb_class_driver usblp_class = {
- .name = "usb/lp%d",
+ .name = "lp%d",
.fops = &usblp_fops,
- .mode = S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP,
.minor_base = USBLP_MINOR_BASE,
};
diff --git a/drivers/usb/core/Kconfig b/drivers/usb/core/Kconfig
index 1a9ff6184943..ff03184da403 100644
--- a/drivers/usb/core/Kconfig
+++ b/drivers/usb/core/Kconfig
@@ -61,14 +61,17 @@ config USB_DYNAMIC_MINORS
If you are unsure about this, say N here.
config USB_SUSPEND
- bool "USB suspend/resume (EXPERIMENTAL)"
+ bool "USB selective suspend/resume and wakeup (EXPERIMENTAL)"
depends on USB && PM && EXPERIMENTAL
help
If you say Y here, you can use driver calls or the sysfs
"power/state" file to suspend or resume individual USB
- peripherals. There are many related features, such as
- remote wakeup and driver-specific suspend processing, that
- may not yet work as expected.
+ peripherals.
+
+ Also, USB "remote wakeup" signaling is supported, whereby some
+ USB devices (like keyboards and network adapters) can wake up
+ their parent hub. That wakeup cascades up the USB tree, and
+ could wake the system from states like suspend-to-RAM.
If you are unsure about this, say N here.
diff --git a/drivers/usb/core/Makefile b/drivers/usb/core/Makefile
index d5503cf0bf74..dd1c4d2a0c31 100644
--- a/drivers/usb/core/Makefile
+++ b/drivers/usb/core/Makefile
@@ -3,7 +3,7 @@
#
usbcore-objs := usb.o hub.o hcd.o urb.o message.o \
- config.o file.o buffer.o sysfs.o devio.o
+ config.o file.o buffer.o sysfs.o devio.o notify.o
ifeq ($(CONFIG_PCI),y)
usbcore-objs += hcd-pci.o
diff --git a/drivers/usb/core/buffer.c b/drivers/usb/core/buffer.c
index fc15b4acc8af..57e800ac3cee 100644
--- a/drivers/usb/core/buffer.c
+++ b/drivers/usb/core/buffer.c
@@ -106,7 +106,7 @@ void hcd_buffer_destroy (struct usb_hcd *hcd)
void *hcd_buffer_alloc (
struct usb_bus *bus,
size_t size,
- unsigned mem_flags,
+ gfp_t mem_flags,
dma_addr_t *dma
)
{
diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c
index 99595e07b653..993019500cc3 100644
--- a/drivers/usb/core/config.c
+++ b/drivers/usb/core/config.c
@@ -112,8 +112,12 @@ void usb_release_interface_cache(struct kref *ref)
struct usb_interface_cache *intfc = ref_to_usb_interface_cache(ref);
int j;
- for (j = 0; j < intfc->num_altsetting; j++)
- kfree(intfc->altsetting[j].endpoint);
+ for (j = 0; j < intfc->num_altsetting; j++) {
+ struct usb_host_interface *alt = &intfc->altsetting[j];
+
+ kfree(alt->endpoint);
+ kfree(alt->string);
+ }
kfree(intfc);
}
@@ -188,10 +192,9 @@ static int usb_parse_interface(struct device *ddev, int cfgno,
}
len = sizeof(struct usb_host_endpoint) * num_ep;
- alt->endpoint = kmalloc(len, GFP_KERNEL);
+ alt->endpoint = kzalloc(len, GFP_KERNEL);
if (!alt->endpoint)
return -ENOMEM;
- memset(alt->endpoint, 0, len);
/* Parse all the endpoint descriptors */
n = 0;
@@ -353,10 +356,9 @@ static int usb_parse_configuration(struct device *ddev, int cfgidx,
}
len = sizeof(*intfc) + sizeof(struct usb_host_interface) * j;
- config->intf_cache[i] = intfc = kmalloc(len, GFP_KERNEL);
+ config->intf_cache[i] = intfc = kzalloc(len, GFP_KERNEL);
if (!intfc)
return -ENOMEM;
- memset(intfc, 0, len);
kref_init(&intfc->ref);
}
@@ -422,8 +424,6 @@ void usb_destroy_configuration(struct usb_device *dev)
struct usb_host_config *cf = &dev->config[c];
kfree(cf->string);
- cf->string = NULL;
-
for (i = 0; i < cf->desc.bNumInterfaces; i++) {
if (cf->intf_cache[i])
kref_put(&cf->intf_cache[i]->ref,
@@ -459,16 +459,14 @@ int usb_get_configuration(struct usb_device *dev)
}
length = ncfg * sizeof(struct usb_host_config);
- dev->config = kmalloc(length, GFP_KERNEL);
+ dev->config = kzalloc(length, GFP_KERNEL);
if (!dev->config)
goto err2;
- memset(dev->config, 0, length);
length = ncfg * sizeof(char *);
- dev->rawdescriptors = kmalloc(length, GFP_KERNEL);
+ dev->rawdescriptors = kzalloc(length, GFP_KERNEL);
if (!dev->rawdescriptors)
goto err2;
- memset(dev->rawdescriptors, 0, length);
buffer = kmalloc(USB_DT_CONFIG_SIZE, GFP_KERNEL);
if (!buffer)
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c
index 487ff672b104..942cd437dc48 100644
--- a/drivers/usb/core/devio.c
+++ b/drivers/usb/core/devio.c
@@ -46,6 +46,7 @@
#include <linux/usb.h>
#include <linux/usbdevice_fs.h>
#include <linux/cdev.h>
+#include <linux/notifier.h>
#include <asm/uaccess.h>
#include <asm/byteorder.h>
#include <linux/moduleparam.h>
@@ -209,10 +210,10 @@ err:
static struct async *alloc_async(unsigned int numisoframes)
{
unsigned int assize = sizeof(struct async) + numisoframes * sizeof(struct usb_iso_packet_descriptor);
- struct async *as = kmalloc(assize, GFP_KERNEL);
+ struct async *as = kzalloc(assize, GFP_KERNEL);
+
if (!as)
return NULL;
- memset(as, 0, assize);
as->urb = usb_alloc_urb(numisoframes, GFP_KERNEL);
if (!as->urb) {
kfree(as);
@@ -279,6 +280,28 @@ static inline struct async *async_getpending(struct dev_state *ps, void __user *
return NULL;
}
+static void snoop_urb(struct urb *urb, void __user *userurb)
+{
+ int j;
+ unsigned char *data = urb->transfer_buffer;
+
+ if (!usbfs_snoop)
+ return;
+
+ if (urb->pipe & USB_DIR_IN)
+ dev_info(&urb->dev->dev, "direction=IN\n");
+ else
+ dev_info(&urb->dev->dev, "direction=OUT\n");
+ dev_info(&urb->dev->dev, "userurb=%p\n", userurb);
+ dev_info(&urb->dev->dev, "transfer_buffer_length=%d\n",
+ urb->transfer_buffer_length);
+ dev_info(&urb->dev->dev, "actual_length=%d\n", urb->actual_length);
+ dev_info(&urb->dev->dev, "data: ");
+ for (j = 0; j < urb->transfer_buffer_length; ++j)
+ printk ("%02x ", data[j]);
+ printk("\n");
+}
+
static void async_completed(struct urb *urb, struct pt_regs *regs)
{
struct async *as = (struct async *)urb->context;
@@ -296,7 +319,9 @@ static void async_completed(struct urb *urb, struct pt_regs *regs)
kill_proc_info_as_uid(as->signr, &sinfo, as->pid, as->uid,
as->euid);
}
- wake_up(&ps->wait);
+ snoop(&urb->dev->dev, "urb complete\n");
+ snoop_urb(urb, as->userurb);
+ wake_up(&ps->wait);
}
static void destroy_async (struct dev_state *ps, struct list_head *list)
@@ -493,6 +518,23 @@ static int check_ctrlrecip(struct dev_state *ps, unsigned int requesttype, unsig
return ret;
}
+static struct usb_device *usbdev_lookup_minor(int minor)
+{
+ struct class_device *class_dev;
+ struct usb_device *dev = NULL;
+
+ down(&usb_device_class->sem);
+ list_for_each_entry(class_dev, &usb_device_class->children, node) {
+ if (class_dev->devt == MKDEV(USB_DEVICE_MAJOR, minor)) {
+ dev = class_dev->class_data;
+ break;
+ }
+ }
+ up(&usb_device_class->sem);
+
+ return dev;
+};
+
/*
* file operations
*/
@@ -601,7 +643,7 @@ static int proc_control(struct dev_state *ps, void __user *arg)
if (usbfs_snoop) {
dev_info(&dev->dev, "control read: data ");
for (j = 0; j < i; ++j)
- printk ("%02x ", (unsigned char)(tbuf)[j]);
+ printk("%02x ", (unsigned char)(tbuf)[j]);
printk("\n");
}
if (copy_to_user(ctrl.data, tbuf, i)) {
@@ -624,7 +666,7 @@ static int proc_control(struct dev_state *ps, void __user *arg)
if (usbfs_snoop) {
dev_info(&dev->dev, "control write: data: ");
for (j = 0; j < ctrl.wLength; ++j)
- printk ("%02x ", (unsigned char)(tbuf)[j]);
+ printk("%02x ", (unsigned char)(tbuf)[j]);
printk("\n");
}
usb_unlock_device(dev);
@@ -649,7 +691,7 @@ static int proc_bulk(struct dev_state *ps, void __user *arg)
unsigned int tmo, len1, pipe;
int len2;
unsigned char *tbuf;
- int i, ret;
+ int i, j, ret;
if (copy_from_user(&bulk, arg, sizeof(bulk)))
return -EFAULT;
@@ -674,10 +716,18 @@ static int proc_bulk(struct dev_state *ps, void __user *arg)
kfree(tbuf);
return -EINVAL;
}
+ snoop(&dev->dev, "bulk read: len=0x%02x timeout=%04d\n",
+ bulk.len, bulk.timeout);
usb_unlock_device(dev);
i = usb_bulk_msg(dev, pipe, tbuf, len1, &len2, tmo);
usb_lock_device(dev);
if (!i && len2) {
+ if (usbfs_snoop) {
+ dev_info(&dev->dev, "bulk read: data ");
+ for (j = 0; j < len2; ++j)
+ printk("%02x ", (unsigned char)(tbuf)[j]);
+ printk("\n");
+ }
if (copy_to_user(bulk.data, tbuf, len2)) {
kfree(tbuf);
return -EFAULT;
@@ -690,6 +740,14 @@ static int proc_bulk(struct dev_state *ps, void __user *arg)
return -EFAULT;
}
}
+ snoop(&dev->dev, "bulk write: len=0x%02x timeout=%04d\n",
+ bulk.len, bulk.timeout);
+ if (usbfs_snoop) {
+ dev_info(&dev->dev, "bulk write: data: ");
+ for (j = 0; j < len1; ++j)
+ printk("%02x ", (unsigned char)(tbuf)[j]);
+ printk("\n");
+ }
usb_unlock_device(dev);
i = usb_bulk_msg(dev, pipe, tbuf, len1, &len2, tmo);
usb_lock_device(dev);
@@ -835,7 +893,6 @@ static int proc_setconfig(struct dev_state *ps, void __user *arg)
return status;
}
-
static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb,
struct usbdevfs_iso_packet_desc __user *iso_frame_desc,
void __user *arg)
@@ -896,6 +953,7 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb,
kfree(dr);
return -EFAULT;
}
+ snoop(&ps->dev->dev, "control urb\n");
break;
case USBDEVFS_URB_TYPE_BULK:
@@ -910,6 +968,7 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb,
return -EINVAL;
if (!access_ok((uurb->endpoint & USB_DIR_IN) ? VERIFY_WRITE : VERIFY_READ, uurb->buffer, uurb->buffer_length))
return -EFAULT;
+ snoop(&ps->dev->dev, "bulk urb\n");
break;
case USBDEVFS_URB_TYPE_ISO:
@@ -939,6 +998,7 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb,
return -EINVAL;
}
uurb->buffer_length = totlen;
+ snoop(&ps->dev->dev, "iso urb\n");
break;
case USBDEVFS_URB_TYPE_INTERRUPT:
@@ -954,6 +1014,7 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb,
return -EINVAL;
if (!access_ok((uurb->endpoint & USB_DIR_IN) ? VERIFY_WRITE : VERIFY_READ, uurb->buffer, uurb->buffer_length))
return -EFAULT;
+ snoop(&ps->dev->dev, "interrupt urb\n");
break;
default:
@@ -1003,6 +1064,8 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb,
return -EFAULT;
}
}
+ snoop(&as->urb->dev->dev, "submit urb\n");
+ snoop_urb(as->urb, as->userurb);
async_newpending(as);
if ((ret = usb_submit_urb(as->urb, GFP_KERNEL))) {
dev_printk(KERN_DEBUG, &ps->dev->dev, "usbfs: usb_submit_urb returned %d\n", ret);
@@ -1238,23 +1301,20 @@ static int proc_releaseinterface(struct dev_state *ps, void __user *arg)
return 0;
}
-static int proc_ioctl (struct dev_state *ps, void __user *arg)
+static int proc_ioctl(struct dev_state *ps, struct usbdevfs_ioctl *ctl)
{
- struct usbdevfs_ioctl ctrl;
int size;
void *buf = NULL;
int retval = 0;
struct usb_interface *intf = NULL;
struct usb_driver *driver = NULL;
- /* get input parameters and alloc buffer */
- if (copy_from_user(&ctrl, arg, sizeof (ctrl)))
- return -EFAULT;
- if ((size = _IOC_SIZE (ctrl.ioctl_code)) > 0) {
+ /* alloc buffer */
+ if ((size = _IOC_SIZE (ctl->ioctl_code)) > 0) {
if ((buf = kmalloc (size, GFP_KERNEL)) == NULL)
return -ENOMEM;
- if ((_IOC_DIR(ctrl.ioctl_code) & _IOC_WRITE)) {
- if (copy_from_user (buf, ctrl.data, size)) {
+ if ((_IOC_DIR(ctl->ioctl_code) & _IOC_WRITE)) {
+ if (copy_from_user (buf, ctl->data, size)) {
kfree(buf);
return -EFAULT;
}
@@ -1270,9 +1330,9 @@ static int proc_ioctl (struct dev_state *ps, void __user *arg)
if (ps->dev->state != USB_STATE_CONFIGURED)
retval = -EHOSTUNREACH;
- else if (!(intf = usb_ifnum_to_if (ps->dev, ctrl.ifno)))
+ else if (!(intf = usb_ifnum_to_if (ps->dev, ctl->ifno)))
retval = -EINVAL;
- else switch (ctrl.ioctl_code) {
+ else switch (ctl->ioctl_code) {
/* disconnect kernel driver from interface */
case USBDEVFS_DISCONNECT:
@@ -1304,7 +1364,7 @@ static int proc_ioctl (struct dev_state *ps, void __user *arg)
if (driver == NULL || driver->ioctl == NULL) {
retval = -ENOTTY;
} else {
- retval = driver->ioctl (intf, ctrl.ioctl_code, buf);
+ retval = driver->ioctl (intf, ctl->ioctl_code, buf);
if (retval == -ENOIOCTLCMD)
retval = -ENOTTY;
}
@@ -1313,15 +1373,42 @@ static int proc_ioctl (struct dev_state *ps, void __user *arg)
/* cleanup and return */
if (retval >= 0
- && (_IOC_DIR (ctrl.ioctl_code) & _IOC_READ) != 0
+ && (_IOC_DIR (ctl->ioctl_code) & _IOC_READ) != 0
&& size > 0
- && copy_to_user (ctrl.data, buf, size) != 0)
+ && copy_to_user (ctl->data, buf, size) != 0)
retval = -EFAULT;
kfree(buf);
return retval;
}
+static int proc_ioctl_default(struct dev_state *ps, void __user *arg)
+{
+ struct usbdevfs_ioctl ctrl;
+
+ if (copy_from_user(&ctrl, arg, sizeof (ctrl)))
+ return -EFAULT;
+ return proc_ioctl(ps, &ctrl);
+}
+
+#ifdef CONFIG_COMPAT
+static int proc_ioctl_compat(struct dev_state *ps, void __user *arg)
+{
+ struct usbdevfs_ioctl32 __user *uioc;
+ struct usbdevfs_ioctl ctrl;
+ u32 udata;
+
+ uioc = compat_ptr(arg);
+ if (get_user(ctrl.ifno, &uioc->ifno) ||
+ get_user(ctrl.ioctl_code, &uioc->ioctl_code) ||
+ __get_user(udata, &uioc->data))
+ return -EFAULT;
+ ctrl.data = compat_ptr(udata);
+
+ return proc_ioctl(ps, &ctrl);
+}
+#endif
+
/*
* NOTE: All requests here that have interface numbers as parameters
* are assuming that somehow the configuration has been prevented from
@@ -1422,6 +1509,10 @@ static int usbdev_ioctl(struct inode *inode, struct file *file, unsigned int cmd
ret = proc_reapurbnonblock_compat(ps, p);
break;
+ case USBDEVFS_IOCTL32:
+ snoop(&dev->dev, "%s: IOCTL\n", __FUNCTION__);
+ ret = proc_ioctl_compat(ps, p);
+ break;
#endif
case USBDEVFS_DISCARDURB:
@@ -1456,7 +1547,7 @@ static int usbdev_ioctl(struct inode *inode, struct file *file, unsigned int cmd
case USBDEVFS_IOCTL:
snoop(&dev->dev, "%s: IOCTL\n", __FUNCTION__);
- ret = proc_ioctl(ps, p);
+ ret = proc_ioctl_default(ps, p);
break;
}
usb_unlock_device(dev);
@@ -1488,39 +1579,40 @@ struct file_operations usbfs_device_file_operations = {
.release = usbdev_release,
};
-struct usb_device *usbdev_lookup_minor(int minor)
-{
- struct class_device *class_dev;
- struct usb_device *dev = NULL;
-
- down(&usb_device_class->sem);
- list_for_each_entry(class_dev, &usb_device_class->children, node) {
- if (class_dev->devt == MKDEV(USB_DEVICE_MAJOR, minor)) {
- dev = class_dev->class_data;
- break;
- }
- }
- up(&usb_device_class->sem);
-
- return dev;
-};
-
-void usbdev_add(struct usb_device *dev)
+static void usbdev_add(struct usb_device *dev)
{
int minor = ((dev->bus->busnum-1) * 128) + (dev->devnum-1);
- dev->class_dev = class_device_create(usb_device_class,
+ dev->class_dev = class_device_create(usb_device_class, NULL,
MKDEV(USB_DEVICE_MAJOR, minor), &dev->dev,
"usbdev%d.%d", dev->bus->busnum, dev->devnum);
dev->class_dev->class_data = dev;
}
-void usbdev_remove(struct usb_device *dev)
+static void usbdev_remove(struct usb_device *dev)
{
class_device_unregister(dev->class_dev);
}
+static int usbdev_notify(struct notifier_block *self, unsigned long action,
+ void *dev)
+{
+ switch (action) {
+ case USB_DEVICE_ADD:
+ usbdev_add(dev);
+ break;
+ case USB_DEVICE_REMOVE:
+ usbdev_remove(dev);
+ break;
+ }
+ return NOTIFY_OK;
+}
+
+static struct notifier_block usbdev_nb = {
+ .notifier_call = usbdev_notify,
+};
+
static struct cdev usb_device_cdev = {
.kobj = {.name = "usb_device", },
.owner = THIS_MODULE,
@@ -1540,24 +1632,32 @@ int __init usbdev_init(void)
retval = cdev_add(&usb_device_cdev, USB_DEVICE_DEV, USB_DEVICE_MAX);
if (retval) {
err("unable to get usb_device major %d", USB_DEVICE_MAJOR);
- unregister_chrdev_region(USB_DEVICE_DEV, USB_DEVICE_MAX);
- goto out;
+ goto error_cdev;
}
usb_device_class = class_create(THIS_MODULE, "usb_device");
if (IS_ERR(usb_device_class)) {
err("unable to register usb_device class");
retval = PTR_ERR(usb_device_class);
- usb_device_class = NULL;
- cdev_del(&usb_device_cdev);
- unregister_chrdev_region(USB_DEVICE_DEV, USB_DEVICE_MAX);
+ goto error_class;
}
+ usb_register_notify(&usbdev_nb);
+
out:
return retval;
+
+error_class:
+ usb_device_class = NULL;
+ cdev_del(&usb_device_cdev);
+
+error_cdev:
+ unregister_chrdev_region(USB_DEVICE_DEV, USB_DEVICE_MAX);
+ goto out;
}
void usbdev_cleanup(void)
{
+ usb_unregister_notify(&usbdev_nb);
class_destroy(usb_device_class);
cdev_del(&usb_device_cdev);
unregister_chrdev_region(USB_DEVICE_DEV, USB_DEVICE_MAX);
diff --git a/drivers/usb/core/file.c b/drivers/usb/core/file.c
index 65ca131cc44c..e695308095ae 100644
--- a/drivers/usb/core/file.c
+++ b/drivers/usb/core/file.c
@@ -17,7 +17,6 @@
#include <linux/config.h>
#include <linux/module.h>
-#include <linux/devfs_fs_kernel.h>
#include <linux/spinlock.h>
#include <linux/errno.h>
@@ -88,8 +87,6 @@ int usb_major_init(void)
goto out;
}
- devfs_mk_dir("usb");
-
out:
return error;
}
@@ -97,7 +94,6 @@ out:
void usb_major_cleanup(void)
{
class_destroy(usb_class);
- devfs_remove("usb");
unregister_chrdev(USB_MAJOR, "usb");
}
@@ -112,8 +108,7 @@ void usb_major_cleanup(void)
* enabled, the minor number will be based on the next available free minor,
* starting at the class_driver->minor_base.
*
- * This function also creates the devfs file for the usb device, if devfs
- * is enabled, and creates a usb class device in the sysfs tree.
+ * This function also creates a usb class device in the sysfs tree.
*
* usb_deregister_dev() must be called when the driver is done with
* the minor numbers given out by this function.
@@ -162,22 +157,20 @@ int usb_register_dev(struct usb_interface *intf,
intf->minor = minor;
- /* handle the devfs registration */
- snprintf(name, BUS_ID_SIZE, class_driver->name, minor - minor_base);
- devfs_mk_cdev(MKDEV(USB_MAJOR, minor), class_driver->mode, name);
-
/* create a usb class device for this usb interface */
+ snprintf(name, BUS_ID_SIZE, class_driver->name, minor - minor_base);
temp = strrchr(name, '/');
if (temp && (temp[1] != 0x00))
++temp;
else
temp = name;
- intf->class_dev = class_device_create(usb_class, MKDEV(USB_MAJOR, minor), &intf->dev, "%s", temp);
+ intf->class_dev = class_device_create(usb_class, NULL,
+ MKDEV(USB_MAJOR, minor),
+ &intf->dev, "%s", temp);
if (IS_ERR(intf->class_dev)) {
spin_lock (&minor_lock);
usb_minors[intf->minor] = NULL;
spin_unlock (&minor_lock);
- devfs_remove (name);
retval = PTR_ERR(intf->class_dev);
}
exit:
@@ -195,9 +188,8 @@ EXPORT_SYMBOL(usb_register_dev);
* call to usb_register_dev() (usually when the device is disconnected
* from the system.)
*
- * This function also cleans up the devfs file for the usb device, if devfs
- * is enabled, and removes the usb class device from the sysfs tree.
- *
+ * This function also removes the usb class device from the sysfs tree.
+ *
* This should be called by all drivers that use the USB major number.
*/
void usb_deregister_dev(struct usb_interface *intf,
@@ -220,7 +212,6 @@ void usb_deregister_dev(struct usb_interface *intf,
spin_unlock (&minor_lock);
snprintf(name, BUS_ID_SIZE, class_driver->name, intf->minor - minor_base);
- devfs_remove (name);
class_device_destroy(usb_class, MKDEV(USB_MAJOR, intf->minor));
intf->class_dev = NULL;
intf->minor = -1;
diff --git a/drivers/usb/core/hcd-pci.c b/drivers/usb/core/hcd-pci.c
index 6385d1a99b60..84d9e69329bb 100644
--- a/drivers/usb/core/hcd-pci.c
+++ b/drivers/usb/core/hcd-pci.c
@@ -30,6 +30,8 @@
#include <asm/io.h>
#include <asm/irq.h>
#include <linux/usb.h>
+
+#include "usb.h"
#include "hcd.h"
@@ -197,6 +199,26 @@ int usb_hcd_pci_suspend (struct pci_dev *dev, pm_message_t message)
hcd = pci_get_drvdata(dev);
+ /* Root hub suspend should have stopped all downstream traffic,
+ * and all bus master traffic. And done so for both the interface
+ * and the stub usb_device (which we check here). But maybe it
+ * didn't; writing sysfs power/state files ignores such rules...
+ *
+ * We must ignore the FREEZE vs SUSPEND distinction here, because
+ * otherwise the swsusp will save (and restore) garbage state.
+ */
+ if (hcd->self.root_hub->dev.power.power_state.event == PM_EVENT_ON)
+ return -EBUSY;
+
+ if (hcd->driver->suspend) {
+ retval = hcd->driver->suspend(hcd, message);
+ if (retval) {
+ dev_dbg (&dev->dev, "PCI pre-suspend fail, %d\n",
+ retval);
+ goto done;
+ }
+ }
+
/* FIXME until the generic PM interfaces change a lot more, this
* can't use PCI D1 and D2 states. For example, the confusion
* between messages and states will need to vanish, and messages
@@ -215,31 +237,13 @@ int usb_hcd_pci_suspend (struct pci_dev *dev, pm_message_t message)
*/
has_pci_pm = pci_find_capability(dev, PCI_CAP_ID_PM);
- switch (hcd->state) {
-
- /* entry if root hub wasn't yet suspended ... from sysfs,
- * without autosuspend, or if USB_SUSPEND isn't configured.
+ /* Downstream ports from this root hub should already be quiesced, so
+ * there will be no DMA activity. Now we can shut down the upstream
+ * link (except maybe for PME# resume signaling) and enter some PCI
+ * low power state, if the hardware allows.
*/
- case HC_STATE_RUNNING:
- hcd->state = HC_STATE_QUIESCING;
- retval = hcd->driver->suspend (hcd, message);
- if (retval) {
- dev_dbg (hcd->self.controller,
- "suspend fail, retval %d\n",
- retval);
- break;
- }
- hcd->state = HC_STATE_SUSPENDED;
- /* FALLTHROUGH */
+ if (hcd->state == HC_STATE_SUSPENDED) {
- /* entry with CONFIG_USB_SUSPEND, or hcds that autosuspend: the
- * controller and/or root hub will already have been suspended,
- * but it won't be ready for a PCI resume call.
- *
- * FIXME only CONFIG_USB_SUSPEND guarantees hub_suspend() will
- * have been called, otherwise root hub timers still run ...
- */
- case HC_STATE_SUSPENDED:
/* no DMA or IRQs except when HC is active */
if (dev->current_state == PCI_D0) {
pci_save_state (dev);
@@ -248,7 +252,7 @@ int usb_hcd_pci_suspend (struct pci_dev *dev, pm_message_t message)
if (!has_pci_pm) {
dev_dbg (hcd->self.controller, "--> PCI D0/legacy\n");
- break;
+ goto done;
}
/* NOTE: dev->current_state becomes nonzero only here, and
@@ -259,28 +263,29 @@ int usb_hcd_pci_suspend (struct pci_dev *dev, pm_message_t message)
retval = pci_set_power_state (dev, PCI_D3hot);
if (retval == 0) {
dev_dbg (hcd->self.controller, "--> PCI D3\n");
- retval = pci_enable_wake (dev, PCI_D3hot, hcd->remote_wakeup);
- if (retval)
- break;
- retval = pci_enable_wake (dev, PCI_D3cold, hcd->remote_wakeup);
- } else if (retval < 0) {
+
+ /* Ignore these return values. We rely on pci code to
+ * reject requests the hardware can't implement, rather
+ * than coding the same thing.
+ */
+ (void) pci_enable_wake (dev, PCI_D3hot, hcd->remote_wakeup);
+ (void) pci_enable_wake (dev, PCI_D3cold, hcd->remote_wakeup);
+ } else {
dev_dbg (&dev->dev, "PCI D3 suspend fail, %d\n",
retval);
(void) usb_hcd_pci_resume (dev);
- break;
}
- break;
- default:
+
+ } else {
dev_dbg (hcd->self.controller, "hcd state %d; not suspended\n",
hcd->state);
WARN_ON(1);
retval = -EINVAL;
- break;
}
- /* update power_state **ONLY** to make sysfs happier */
+done:
if (retval == 0)
- dev->dev.power.power_state = message;
+ dev->dev.power.power_state = PMSG_SUSPEND;
return retval;
}
EXPORT_SYMBOL (usb_hcd_pci_suspend);
@@ -336,20 +341,9 @@ int usb_hcd_pci_resume (struct pci_dev *dev)
dev->current_state);
}
#endif
- retval = pci_enable_wake (dev, dev->current_state, 0);
- if (retval) {
- dev_err(hcd->self.controller,
- "can't enable_wake to %d, %d!\n",
- dev->current_state, retval);
- return retval;
- }
- retval = pci_enable_wake (dev, PCI_D3cold, 0);
- if (retval) {
- dev_err(hcd->self.controller,
- "can't enable_wake to %d, %d!\n",
- PCI_D3cold, retval);
- return retval;
- }
+ /* yes, ignore these results too... */
+ (void) pci_enable_wake (dev, dev->current_state, 0);
+ (void) pci_enable_wake (dev, PCI_D3cold, 0);
} else {
/* Same basic cases: clean (powered/not), dirty */
dev_dbg(hcd->self.controller, "PCI legacy resume\n");
@@ -371,17 +365,17 @@ int usb_hcd_pci_resume (struct pci_dev *dev)
dev->dev.power.power_state = PMSG_ON;
- hcd->state = HC_STATE_RESUMING;
hcd->saw_irq = 0;
- retval = hcd->driver->resume (hcd);
- if (!HC_IS_RUNNING (hcd->state)) {
- dev_dbg (hcd->self.controller,
- "resume fail, retval %d\n", retval);
- usb_hc_died (hcd);
+ if (hcd->driver->resume) {
+ retval = hcd->driver->resume(hcd);
+ if (retval) {
+ dev_err (hcd->self.controller,
+ "PCI post-resume error %d!\n", retval);
+ usb_hc_died (hcd);
+ }
}
- retval = pci_enable_device(dev);
return retval;
}
EXPORT_SYMBOL (usb_hcd_pci_resume);
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index 1017a97a418b..6c7ca5b08cd6 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -130,7 +130,7 @@ static const u8 usb2_rh_dev_descriptor [18] = {
0x09, /* __u8 bDeviceClass; HUB_CLASSCODE */
0x00, /* __u8 bDeviceSubClass; */
0x01, /* __u8 bDeviceProtocol; [ usb 2.0 single TT ]*/
- 0x08, /* __u8 bMaxPacketSize0; 8 Bytes */
+ 0x40, /* __u8 bMaxPacketSize0; 64 Bytes */
0x00, 0x00, /* __le16 idVendor; */
0x00, 0x00, /* __le16 idProduct; */
@@ -153,7 +153,7 @@ static const u8 usb11_rh_dev_descriptor [18] = {
0x09, /* __u8 bDeviceClass; HUB_CLASSCODE */
0x00, /* __u8 bDeviceSubClass; */
0x00, /* __u8 bDeviceProtocol; [ low/full speeds only ] */
- 0x08, /* __u8 bMaxPacketSize0; 8 Bytes */
+ 0x40, /* __u8 bMaxPacketSize0; 64 Bytes */
0x00, 0x00, /* __le16 idVendor; */
0x00, 0x00, /* __le16 idProduct; */
@@ -458,22 +458,18 @@ static int rh_call_control (struct usb_hcd *hcd, struct urb *urb)
default:
/* non-generic request */
- if (HC_IS_SUSPENDED (hcd->state))
- status = -EAGAIN;
- else {
- switch (typeReq) {
- case GetHubStatus:
- case GetPortStatus:
- len = 4;
- break;
- case GetHubDescriptor:
- len = sizeof (struct usb_hub_descriptor);
- break;
- }
- status = hcd->driver->hub_control (hcd,
- typeReq, wValue, wIndex,
- tbuf, wLength);
+ switch (typeReq) {
+ case GetHubStatus:
+ case GetPortStatus:
+ len = 4;
+ break;
+ case GetHubDescriptor:
+ len = sizeof (struct usb_hub_descriptor);
+ break;
}
+ status = hcd->driver->hub_control (hcd,
+ typeReq, wValue, wIndex,
+ tbuf, wLength);
break;
error:
/* "protocol stall" on error */
@@ -487,7 +483,7 @@ error:
"CTRL: TypeReq=0x%x val=0x%x "
"idx=0x%x len=%d ==> %d\n",
typeReq, wValue, wIndex,
- wLength, urb->status);
+ wLength, status);
}
}
if (len) {
@@ -748,10 +744,9 @@ struct usb_bus *usb_alloc_bus (struct usb_operations *op)
{
struct usb_bus *bus;
- bus = kmalloc (sizeof *bus, GFP_KERNEL);
+ bus = kzalloc (sizeof *bus, GFP_KERNEL);
if (!bus)
return NULL;
- memset(bus, 0, sizeof(struct usb_bus));
usb_bus_init (bus);
bus->op = op;
return bus;
@@ -782,7 +777,8 @@ static int usb_register_bus(struct usb_bus *bus)
return -E2BIG;
}
- bus->class_dev = class_device_create(usb_host_class, MKDEV(0,0), bus->controller, "usb_host%d", busnum);
+ bus->class_dev = class_device_create(usb_host_class, NULL, MKDEV(0,0),
+ bus->controller, "usb_host%d", busnum);
if (IS_ERR(bus->class_dev)) {
clear_bit(busnum, busmap.busmap);
up(&usb_bus_list_lock);
@@ -795,8 +791,7 @@ static int usb_register_bus(struct usb_bus *bus)
list_add (&bus->bus_list, &usb_bus_list);
up (&usb_bus_list_lock);
- usbfs_add_bus (bus);
- usbmon_notify_bus_add (bus);
+ usb_notify_add_bus(bus);
dev_info (bus->controller, "new USB bus registered, assigned bus number %d\n", bus->busnum);
return 0;
@@ -823,8 +818,7 @@ static void usb_deregister_bus (struct usb_bus *bus)
list_del (&bus->bus_list);
up (&usb_bus_list_lock);
- usbmon_notify_bus_remove (bus);
- usbfs_remove_bus (bus);
+ usb_notify_remove_bus(bus);
clear_bit (bus->busnum, busmap.busmap);
@@ -1112,7 +1106,7 @@ static void urb_unlink (struct urb *urb)
* expects usb_submit_urb() to have sanity checked and conditioned all
* inputs in the urb
*/
-static int hcd_submit_urb (struct urb *urb, unsigned mem_flags)
+static int hcd_submit_urb (struct urb *urb, gfp_t mem_flags)
{
int status;
struct usb_hcd *hcd = urb->dev->bus->hcpriv;
@@ -1142,10 +1136,20 @@ static int hcd_submit_urb (struct urb *urb, unsigned mem_flags)
else switch (hcd->state) {
case HC_STATE_RUNNING:
case HC_STATE_RESUMING:
+doit:
usb_get_dev (urb->dev);
list_add_tail (&urb->urb_list, &ep->urb_list);
status = 0;
break;
+ case HC_STATE_SUSPENDED:
+ /* HC upstream links (register access, wakeup signaling) can work
+ * even when the downstream links (and DMA etc) are quiesced; let
+ * usbcore talk to the root hub.
+ */
+ if (hcd->self.controller->power.power_state.event == PM_EVENT_ON
+ && urb->dev->parent == NULL)
+ goto doit;
+ /* FALL THROUGH */
default:
status = -ESHUTDOWN;
break;
@@ -1293,12 +1297,6 @@ static int hcd_unlink_urb (struct urb *urb, int status)
goto done;
}
- /* running ~= hc unlink handshake works (irq, timer, etc)
- * halted ~= no unlink handshake is needed
- * suspended, resuming == should never happen
- */
- WARN_ON (!HC_IS_RUNNING (hcd->state) && hcd->state != HC_STATE_HALT);
-
/* insist the urb is still queued */
list_for_each(tmp, &ep->urb_list) {
if (tmp == &urb->urb_list)
@@ -1430,28 +1428,92 @@ rescan:
/*-------------------------------------------------------------------------*/
-#ifdef CONFIG_USB_SUSPEND
+#ifdef CONFIG_PM
-static int hcd_hub_suspend (struct usb_bus *bus)
+int hcd_bus_suspend (struct usb_bus *bus)
{
struct usb_hcd *hcd;
+ int status;
hcd = container_of (bus, struct usb_hcd, self);
- if (hcd->driver->hub_suspend)
- return hcd->driver->hub_suspend (hcd);
- return 0;
+ if (!hcd->driver->bus_suspend)
+ return -ENOENT;
+ hcd->state = HC_STATE_QUIESCING;
+ status = hcd->driver->bus_suspend (hcd);
+ if (status == 0)
+ hcd->state = HC_STATE_SUSPENDED;
+ else
+ dev_dbg(&bus->root_hub->dev, "%s fail, err %d\n",
+ "suspend", status);
+ return status;
}
-static int hcd_hub_resume (struct usb_bus *bus)
+int hcd_bus_resume (struct usb_bus *bus)
{
struct usb_hcd *hcd;
+ int status;
hcd = container_of (bus, struct usb_hcd, self);
- if (hcd->driver->hub_resume)
- return hcd->driver->hub_resume (hcd);
- return 0;
+ if (!hcd->driver->bus_resume)
+ return -ENOENT;
+ if (hcd->state == HC_STATE_RUNNING)
+ return 0;
+ hcd->state = HC_STATE_RESUMING;
+ status = hcd->driver->bus_resume (hcd);
+ if (status == 0)
+ hcd->state = HC_STATE_RUNNING;
+ else {
+ dev_dbg(&bus->root_hub->dev, "%s fail, err %d\n",
+ "resume", status);
+ usb_hc_died(hcd);
+ }
+ return status;
}
+/*
+ * usb_hcd_suspend_root_hub - HCD autosuspends downstream ports
+ * @hcd: host controller for this root hub
+ *
+ * This call arranges that usb_hcd_resume_root_hub() is safe to call later;
+ * that the HCD's root hub polling is deactivated; and that the root's hub
+ * driver is suspended. HCDs may call this to autosuspend when their root
+ * hub's downstream ports are all inactive: unpowered, disconnected,
+ * disabled, or suspended.
+ *
+ * The HCD will autoresume on device connect change detection (using SRP
+ * or a D+/D- pullup). The HCD also autoresumes on remote wakeup signaling
+ * from any ports that are suspended (if that is enabled). In most cases,
+ * overcurrent signaling (on powered ports) will also start autoresume.
+ *
+ * Always called with IRQs blocked.
+ */
+void usb_hcd_suspend_root_hub (struct usb_hcd *hcd)
+{
+ struct urb *urb;
+
+ spin_lock (&hcd_root_hub_lock);
+ usb_suspend_root_hub (hcd->self.root_hub);
+
+ /* force status urb to complete/unlink while suspended */
+ if (hcd->status_urb) {
+ urb = hcd->status_urb;
+ urb->status = -ECONNRESET;
+ urb->hcpriv = NULL;
+ urb->actual_length = 0;
+
+ del_timer (&hcd->rh_timer);
+ hcd->poll_pending = 0;
+ hcd->status_urb = NULL;
+ } else
+ urb = NULL;
+ spin_unlock (&hcd_root_hub_lock);
+ hcd->state = HC_STATE_SUSPENDED;
+
+ if (urb)
+ usb_hcd_giveback_urb (hcd, urb, NULL);
+}
+EXPORT_SYMBOL_GPL(usb_hcd_suspend_root_hub);
+
/**
* usb_hcd_resume_root_hub - called by HCD to resume its root hub
* @hcd: host controller for this root hub
@@ -1459,7 +1521,7 @@ static int hcd_hub_resume (struct usb_bus *bus)
* The USB host controller calls this function when its root hub is
* suspended (with the remote wakeup feature enabled) and a remote
* wakeup request is received. It queues a request for khubd to
- * resume the root hub.
+ * resume the root hub (that is, manage its downstream ports again).
*/
void usb_hcd_resume_root_hub (struct usb_hcd *hcd)
{
@@ -1470,13 +1532,9 @@ void usb_hcd_resume_root_hub (struct usb_hcd *hcd)
usb_resume_root_hub (hcd->self.root_hub);
spin_unlock_irqrestore (&hcd_root_hub_lock, flags);
}
+EXPORT_SYMBOL_GPL(usb_hcd_resume_root_hub);
-#else
-void usb_hcd_resume_root_hub (struct usb_hcd *hcd)
-{
-}
#endif
-EXPORT_SYMBOL_GPL(usb_hcd_resume_root_hub);
/*-------------------------------------------------------------------------*/
@@ -1529,10 +1587,6 @@ static struct usb_operations usb_hcd_operations = {
.buffer_alloc = hcd_buffer_alloc,
.buffer_free = hcd_buffer_free,
.disable = hcd_endpoint_disable,
-#ifdef CONFIG_USB_SUSPEND
- .hub_suspend = hcd_hub_suspend,
- .hub_resume = hcd_hub_resume,
-#endif
};
/*-------------------------------------------------------------------------*/
diff --git a/drivers/usb/core/hcd.h b/drivers/usb/core/hcd.h
index ac451fa7e4d2..24a62a2ff86d 100644
--- a/drivers/usb/core/hcd.h
+++ b/drivers/usb/core/hcd.h
@@ -142,22 +142,18 @@ struct hcd_timeout { /* timeouts we allocate */
struct usb_operations {
int (*get_frame_number) (struct usb_device *usb_dev);
- int (*submit_urb) (struct urb *urb, unsigned mem_flags);
+ int (*submit_urb) (struct urb *urb, gfp_t mem_flags);
int (*unlink_urb) (struct urb *urb, int status);
/* allocate dma-consistent buffer for URB_DMA_NOMAPPING */
void *(*buffer_alloc)(struct usb_bus *bus, size_t size,
- unsigned mem_flags,
+ gfp_t mem_flags,
dma_addr_t *dma);
void (*buffer_free)(struct usb_bus *bus, size_t size,
void *addr, dma_addr_t dma);
void (*disable)(struct usb_device *udev,
struct usb_host_endpoint *ep);
-
- /* global suspend/resume of bus */
- int (*hub_suspend)(struct usb_bus *);
- int (*hub_resume)(struct usb_bus *);
};
/* each driver provides one of these, and hardware init support */
@@ -182,12 +178,12 @@ struct hc_driver {
int (*start) (struct usb_hcd *hcd);
/* NOTE: these suspend/resume calls relate to the HC as
- * a whole, not just the root hub; they're for bus glue.
+ * a whole, not just the root hub; they're for PCI bus glue.
*/
- /* called after all devices were suspended */
+ /* called after suspending the hub, before entering D3 etc */
int (*suspend) (struct usb_hcd *hcd, pm_message_t message);
- /* called before any devices get resumed */
+ /* called after entering D0 (etc), before resuming the hub */
int (*resume) (struct usb_hcd *hcd);
/* cleanly make HCD stop writing memory and doing I/O */
@@ -200,7 +196,7 @@ struct hc_driver {
int (*urb_enqueue) (struct usb_hcd *hcd,
struct usb_host_endpoint *ep,
struct urb *urb,
- unsigned mem_flags);
+ gfp_t mem_flags);
int (*urb_dequeue) (struct usb_hcd *hcd, struct urb *urb);
/* hw synch, freeing endpoint resources that urb_dequeue can't */
@@ -212,8 +208,8 @@ struct hc_driver {
int (*hub_control) (struct usb_hcd *hcd,
u16 typeReq, u16 wValue, u16 wIndex,
char *buf, u16 wLength);
- int (*hub_suspend)(struct usb_hcd *);
- int (*hub_resume)(struct usb_hcd *);
+ int (*bus_suspend)(struct usb_hcd *);
+ int (*bus_resume)(struct usb_hcd *);
int (*start_port_reset)(struct usb_hcd *, unsigned port_num);
void (*hub_irq_enable)(struct usb_hcd *);
/* Needed only if port-change IRQs are level-triggered */
@@ -247,7 +243,7 @@ int hcd_buffer_create (struct usb_hcd *hcd);
void hcd_buffer_destroy (struct usb_hcd *hcd);
void *hcd_buffer_alloc (struct usb_bus *bus, size_t size,
- unsigned mem_flags, dma_addr_t *dma);
+ gfp_t mem_flags, dma_addr_t *dma);
void hcd_buffer_free (struct usb_bus *bus, size_t size,
void *addr, dma_addr_t dma);
@@ -355,8 +351,6 @@ extern long usb_calc_bus_time (int speed, int is_input,
extern struct usb_bus *usb_alloc_bus (struct usb_operations *);
-extern void usb_hcd_resume_root_hub (struct usb_hcd *hcd);
-
extern void usb_set_device_state(struct usb_device *udev,
enum usb_device_state new_state);
@@ -378,6 +372,33 @@ extern int usb_find_interface_driver (struct usb_device *dev,
#define usb_endpoint_out(ep_dir) (!((ep_dir) & USB_DIR_IN))
+#ifdef CONFIG_PM
+extern void usb_hcd_suspend_root_hub (struct usb_hcd *hcd);
+extern void usb_hcd_resume_root_hub (struct usb_hcd *hcd);
+extern int hcd_bus_suspend (struct usb_bus *bus);
+extern int hcd_bus_resume (struct usb_bus *bus);
+#else
+static inline void usb_hcd_suspend_root_hub(struct usb_hcd *hcd)
+{
+ return;
+}
+
+static inline void usb_hcd_resume_root_hub(struct usb_hcd *hcd)
+{
+ return;
+}
+
+static inline int hcd_bus_suspend(struct usb_bus *bus)
+{
+ return 0;
+}
+
+static inline int hcd_bus_resume (struct usb_bus *bus)
+{
+ return 0;
+}
+#endif /* CONFIG_PM */
+
/*
* USB device fs stuff
*/
@@ -388,23 +409,13 @@ extern int usb_find_interface_driver (struct usb_device *dev,
* these are expected to be called from the USB core/hub thread
* with the kernel lock held
*/
-extern void usbfs_add_bus(struct usb_bus *bus);
-extern void usbfs_remove_bus(struct usb_bus *bus);
-extern void usbfs_add_device(struct usb_device *dev);
-extern void usbfs_remove_device(struct usb_device *dev);
extern void usbfs_update_special (void);
-
extern int usbfs_init(void);
extern void usbfs_cleanup(void);
#else /* CONFIG_USB_DEVICEFS */
-static inline void usbfs_add_bus(struct usb_bus *bus) {}
-static inline void usbfs_remove_bus(struct usb_bus *bus) {}
-static inline void usbfs_add_device(struct usb_device *dev) {}
-static inline void usbfs_remove_device(struct usb_device *dev) {}
static inline void usbfs_update_special (void) {}
-
static inline int usbfs_init(void) { return 0; }
static inline void usbfs_cleanup(void) { }
@@ -419,8 +430,6 @@ struct usb_mon_operations {
void (*urb_submit_error)(struct usb_bus *bus, struct urb *urb, int err);
void (*urb_complete)(struct usb_bus *bus, struct urb *urb);
/* void (*urb_unlink)(struct usb_bus *bus, struct urb *urb); */
- void (*bus_add)(struct usb_bus *bus);
- void (*bus_remove)(struct usb_bus *bus);
};
extern struct usb_mon_operations *mon_ops;
@@ -443,18 +452,6 @@ static inline void usbmon_urb_complete(struct usb_bus *bus, struct urb *urb)
if (bus->monitored)
(*mon_ops->urb_complete)(bus, urb);
}
-
-static inline void usbmon_notify_bus_add(struct usb_bus *bus)
-{
- if (mon_ops)
- (*mon_ops->bus_add)(bus);
-}
-
-static inline void usbmon_notify_bus_remove(struct usb_bus *bus)
-{
- if (mon_ops)
- (*mon_ops->bus_remove)(bus);
-}
int usb_mon_register(struct usb_mon_operations *ops);
void usb_mon_deregister(void);
@@ -465,8 +462,6 @@ static inline void usbmon_urb_submit(struct usb_bus *bus, struct urb *urb) {}
static inline void usbmon_urb_submit_error(struct usb_bus *bus, struct urb *urb,
int error) {}
static inline void usbmon_urb_complete(struct usb_bus *bus, struct urb *urb) {}
-static inline void usbmon_notify_bus_add(struct usb_bus *bus) {}
-static inline void usbmon_notify_bus_remove(struct usb_bus *bus) {}
#endif /* CONFIG_USB_MON */
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index a12cab5314e9..256d9f698715 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -436,9 +436,10 @@ static void hub_power_on(struct usb_hub *hub)
{
int port1;
unsigned pgood_delay = hub->descriptor->bPwrOn2PwrGood * 2;
+ u16 wHubCharacteristics = le16_to_cpu(hub->descriptor->wHubCharacteristics);
/* if hub supports power switching, enable power on each port */
- if ((hub->descriptor->wHubCharacteristics & HUB_CHAR_LPSM) < 2) {
+ if ((wHubCharacteristics & HUB_CHAR_LPSM) < 2) {
dev_dbg(hub->intfdev, "enabling power on all ports\n");
for (port1 = 1; port1 <= hub->descriptor->bNbrPorts; port1++)
set_port_feature(hub->hdev, port1,
@@ -449,10 +450,18 @@ static void hub_power_on(struct usb_hub *hub)
msleep(max(pgood_delay, (unsigned) 100));
}
-static void hub_quiesce(struct usb_hub *hub)
+static inline void __hub_quiesce(struct usb_hub *hub)
{
- /* stop khubd and related activity */
+ /* (nonblocking) khubd and related activity won't re-trigger */
hub->quiescing = 1;
+ hub->activating = 0;
+ hub->resume_root_hub = 0;
+}
+
+static void hub_quiesce(struct usb_hub *hub)
+{
+ /* (blocking) stop khubd and related activity */
+ __hub_quiesce(hub);
usb_kill_urb(hub->urb);
if (hub->has_indicators)
cancel_delayed_work(&hub->leds);
@@ -466,6 +475,7 @@ static void hub_activate(struct usb_hub *hub)
hub->quiescing = 0;
hub->activating = 1;
+ hub->resume_root_hub = 0;
status = usb_submit_urb(hub->urb, GFP_NOIO);
if (status < 0)
dev_err(hub->intfdev, "activate --> %d\n", status);
@@ -516,6 +526,7 @@ static int hub_configure(struct usb_hub *hub,
struct usb_device *hdev = hub->hdev;
struct device *hub_dev = hub->intfdev;
u16 hubstatus, hubchange;
+ u16 wHubCharacteristics;
unsigned int pipe;
int maxp, ret;
char *message;
@@ -561,9 +572,9 @@ static int hub_configure(struct usb_hub *hub,
dev_info (hub_dev, "%d port%s detected\n", hdev->maxchild,
(hdev->maxchild == 1) ? "" : "s");
- le16_to_cpus(&hub->descriptor->wHubCharacteristics);
+ wHubCharacteristics = le16_to_cpu(hub->descriptor->wHubCharacteristics);
- if (hub->descriptor->wHubCharacteristics & HUB_CHAR_COMPOUND) {
+ if (wHubCharacteristics & HUB_CHAR_COMPOUND) {
int i;
char portstr [USB_MAXCHILDREN + 1];
@@ -576,7 +587,7 @@ static int hub_configure(struct usb_hub *hub,
} else
dev_dbg(hub_dev, "standalone hub\n");
- switch (hub->descriptor->wHubCharacteristics & HUB_CHAR_LPSM) {
+ switch (wHubCharacteristics & HUB_CHAR_LPSM) {
case 0x00:
dev_dbg(hub_dev, "ganged power switching\n");
break;
@@ -589,7 +600,7 @@ static int hub_configure(struct usb_hub *hub,
break;
}
- switch (hub->descriptor->wHubCharacteristics & HUB_CHAR_OCPM) {
+ switch (wHubCharacteristics & HUB_CHAR_OCPM) {
case 0x00:
dev_dbg(hub_dev, "global over-current protection\n");
break;
@@ -629,7 +640,7 @@ static int hub_configure(struct usb_hub *hub,
}
/* Note 8 FS bit times == (8 bits / 12000000 bps) ~= 666ns */
- switch (hub->descriptor->wHubCharacteristics & HUB_CHAR_TTTT) {
+ switch (wHubCharacteristics & HUB_CHAR_TTTT) {
case HUB_TTTT_8_BITS:
if (hdev->descriptor.bDeviceProtocol != 0) {
hub->tt.think_time = 666;
@@ -659,7 +670,7 @@ static int hub_configure(struct usb_hub *hub,
}
/* probe() zeroes hub->indicator[] */
- if (hub->descriptor->wHubCharacteristics & HUB_CHAR_PORTIND) {
+ if (wHubCharacteristics & HUB_CHAR_PORTIND) {
hub->has_indicators = 1;
dev_dbg(hub_dev, "Port indicators are supported\n");
}
@@ -704,7 +715,7 @@ static int hub_configure(struct usb_hub *hub,
(hubstatus & HUB_STATUS_LOCAL_POWER)
? "lost (inactive)" : "good");
- if ((hub->descriptor->wHubCharacteristics & HUB_CHAR_OCPM) == 0)
+ if ((wHubCharacteristics & HUB_CHAR_OCPM) == 0)
dev_dbg(hub_dev, "%sover-current condition exists\n",
(hubstatus & HUB_STATUS_OVERCURRENT) ? "" : "no ");
@@ -854,14 +865,12 @@ descriptor_error:
/* We found a hub */
dev_info (&intf->dev, "USB hub found\n");
- hub = kmalloc(sizeof(*hub), GFP_KERNEL);
+ hub = kzalloc(sizeof(*hub), GFP_KERNEL);
if (!hub) {
dev_dbg (&intf->dev, "couldn't kmalloc hub struct\n");
return -ENOMEM;
}
- memset(hub, 0, sizeof(*hub));
-
INIT_LIST_HEAD(&hub->event_list);
hub->intfdev = &intf->dev;
hub->hdev = hdev;
@@ -1020,9 +1029,15 @@ void usb_set_device_state(struct usb_device *udev,
spin_lock_irqsave(&device_state_lock, flags);
if (udev->state == USB_STATE_NOTATTACHED)
; /* do nothing */
- else if (new_state != USB_STATE_NOTATTACHED)
+ else if (new_state != USB_STATE_NOTATTACHED) {
udev->state = new_state;
- else
+ if (new_state == USB_STATE_CONFIGURED)
+ device_init_wakeup(&udev->dev,
+ (udev->actconfig->desc.bmAttributes
+ & USB_CONFIG_ATT_WAKEUP));
+ else if (new_state != USB_STATE_SUSPENDED)
+ device_init_wakeup(&udev->dev, 0);
+ } else
recursively_mark_NOTATTACHED(udev);
spin_unlock_irqrestore(&device_state_lock, flags);
}
@@ -1111,14 +1126,14 @@ void usb_disconnect(struct usb_device **pdev)
*/
usb_disable_device(udev, 0);
+ usb_notify_remove_device(udev);
+
/* Free the device number, remove the /proc/bus/usb entry and
* the sysfs attributes, and delete the parent's children[]
* (or root_hub) pointer.
*/
dev_dbg (&udev->dev, "unregistering device\n");
release_address(udev);
- usbfs_remove_device(udev);
- usbdev_remove(udev);
usb_remove_sysfs_dev_files(udev);
/* Avoid races with recursively_mark_NOTATTACHED() */
@@ -1189,21 +1204,6 @@ static inline void show_string(struct usb_device *udev, char *id, char *string)
{}
#endif
-static void get_string(struct usb_device *udev, char **string, int index)
-{
- char *buf;
-
- if (!index)
- return;
- buf = kmalloc(256, GFP_KERNEL);
- if (!buf)
- return;
- if (usb_string(udev, index, buf, 256) > 0)
- *string = buf;
- else
- kfree(buf);
-}
-
#ifdef CONFIG_USB_OTG
#include "otg_whitelist.h"
@@ -1242,9 +1242,10 @@ int usb_new_device(struct usb_device *udev)
}
/* read the standard strings and cache them if present */
- get_string(udev, &udev->product, udev->descriptor.iProduct);
- get_string(udev, &udev->manufacturer, udev->descriptor.iManufacturer);
- get_string(udev, &udev->serial, udev->descriptor.iSerialNumber);
+ udev->product = usb_cache_string(udev, udev->descriptor.iProduct);
+ udev->manufacturer = usb_cache_string(udev,
+ udev->descriptor.iManufacturer);
+ udev->serial = usb_cache_string(udev, udev->descriptor.iSerialNumber);
/* Tell the world! */
dev_dbg(&udev->dev, "new device strings: Mfr=%d, Product=%d, "
@@ -1316,11 +1317,9 @@ int usb_new_device(struct usb_device *udev)
* (Includes HNP test device.)
*/
if (udev->bus->b_hnp_enable || udev->bus->is_b_host) {
- static int __usb_suspend_device (struct usb_device *,
- int port1, pm_message_t state);
- err = __usb_suspend_device(udev,
- udev->bus->otg_port,
- PMSG_SUSPEND);
+ static int __usb_suspend_device(struct usb_device *,
+ int port1);
+ err = __usb_suspend_device(udev, udev->bus->otg_port);
if (err < 0)
dev_dbg(&udev->dev, "HNP fail, %d\n", err);
}
@@ -1356,10 +1355,8 @@ int usb_new_device(struct usb_device *udev)
}
/* USB device state == configured ... usable */
+ usb_notify_add_device(udev);
- /* add a /proc/bus/usb entry */
- usbdev_add(udev);
- usbfs_add_device(udev);
return 0;
fail:
@@ -1510,7 +1507,7 @@ static void hub_port_logical_disconnect(struct usb_hub *hub, int port1)
/* FIXME let caller ask to power down the port:
* - some devices won't enumerate without a VBUS power cycle
* - SRP saves power that way
- * - usb_suspend_device(dev, PMSG_SUSPEND)
+ * - ... new call, TBD ...
* That's easy if this hub can switch power per-port, and
* khubd reactivates the port later (timer, SRP, etc).
* Powerdown must be optional, because of reset/DFU.
@@ -1546,11 +1543,7 @@ static int hub_port_suspend(struct usb_hub *hub, int port1,
* NOTE: OTG devices may issue remote wakeup (or SRP) even when
* we don't explicitly enable it here.
*/
- if (udev->actconfig
- // && FIXME (remote wakeup enabled on this bus)
- // ... currently assuming it's always appropriate
- && (udev->actconfig->desc.bmAttributes
- & USB_CONFIG_ATT_WAKEUP) != 0) {
+ if (device_may_wakeup(&udev->dev)) {
status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
USB_REQ_SET_FEATURE, USB_RECIP_DEVICE,
USB_DEVICE_REMOTE_WAKEUP, 0,
@@ -1596,11 +1589,14 @@ static int hub_port_suspend(struct usb_hub *hub, int port1,
* Other than re-initializing the hub (plug/unplug, except for root hubs),
* Linux (2.6) currently has NO mechanisms to initiate that: no khubd
* timer, no SRP, no requests through sysfs.
+ *
+ * If CONFIG_USB_SUSPEND isn't enabled, devices only really suspend when
+ * the root hub for their bus goes into global suspend ... so we don't
+ * (falsely) update the device power state to say it suspended.
*/
-static int __usb_suspend_device (struct usb_device *udev, int port1,
- pm_message_t state)
+static int __usb_suspend_device (struct usb_device *udev, int port1)
{
- int status;
+ int status = 0;
/* caller owns the udev device lock */
if (port1 < 0)
@@ -1611,95 +1607,39 @@ static int __usb_suspend_device (struct usb_device *udev, int port1,
return 0;
}
- /* suspend interface drivers; if this is a hub, it
- * suspends the child devices
- */
+ /* all interfaces must already be suspended */
if (udev->actconfig) {
int i;
for (i = 0; i < udev->actconfig->desc.bNumInterfaces; i++) {
struct usb_interface *intf;
- struct usb_driver *driver;
intf = udev->actconfig->interface[i];
- if (state.event <= intf->dev.power.power_state.event)
- continue;
- if (!intf->dev.driver)
- continue;
- driver = to_usb_driver(intf->dev.driver);
-
- if (driver->suspend) {
- status = driver->suspend(intf, state);
- if (intf->dev.power.power_state.event != state.event
- || status)
- dev_err(&intf->dev,
- "suspend %d fail, code %d\n",
- state.event, status);
- }
-
- /* only drivers with suspend() can ever resume();
- * and after power loss, even they won't.
- * bus_rescan_devices() can rebind drivers later.
- *
- * FIXME the PM core self-deadlocks when unbinding
- * drivers during suspend/resume ... everything grabs
- * dpm_sem (not a spinlock, ugh). we want to unbind,
- * since we know every driver's probe/disconnect works
- * even for drivers that can't suspend.
- */
- if (!driver->suspend || state.event > PM_EVENT_FREEZE) {
-#if 1
- dev_warn(&intf->dev, "resume is unsafe!\n");
-#else
- down_write(&usb_bus_type.rwsem);
- device_release_driver(&intf->dev);
- up_write(&usb_bus_type.rwsem);
-#endif
+ if (is_active(intf)) {
+ dev_dbg(&intf->dev, "nyet suspended\n");
+ return -EBUSY;
}
}
}
- /*
- * FIXME this needs port power off call paths too, to help force
- * USB into the "generic" PM model. At least for devices on
- * ports that aren't using ganged switching (usually root hubs).
- *
- * NOTE: SRP-capable links should adopt more aggressive poweroff
- * policies (when HNP doesn't apply) once we have mechanisms to
- * turn power back on! (Likely not before 2.7...)
+ /* we only change a device's upstream USB link.
+ * root hubs have no upstream USB link.
*/
- if (state.event > PM_EVENT_FREEZE) {
- dev_warn(&udev->dev, "no poweroff yet, suspending instead\n");
- }
-
- /* "global suspend" of the HC-to-USB interface (root hub), or
- * "selective suspend" of just one hub-device link.
- */
- if (!udev->parent) {
- struct usb_bus *bus = udev->bus;
- if (bus && bus->op->hub_suspend) {
- status = bus->op->hub_suspend (bus);
- if (status == 0) {
- dev_dbg(&udev->dev, "usb suspend\n");
- usb_set_device_state(udev,
- USB_STATE_SUSPENDED);
- }
- } else
- status = -EOPNOTSUPP;
- } else
+ if (udev->parent)
status = hub_port_suspend(hdev_to_hub(udev->parent), port1,
udev);
if (status == 0)
- udev->dev.power.power_state = state;
+ udev->dev.power.power_state = PMSG_SUSPEND;
return status;
}
-/**
+#endif
+
+/*
* usb_suspend_device - suspend a usb device
* @udev: device that's no longer in active use
- * @state: PMSG_SUSPEND to suspend
- * Context: must be able to sleep; device not locked
+ * Context: must be able to sleep; device not locked; pm locks held
*
* Suspends a USB device that isn't in active use, conserving power.
* Devices may wake out of a suspend, if anything important happens,
@@ -1707,37 +1647,50 @@ static int __usb_suspend_device (struct usb_device *udev, int port1,
* suspend by the host, using usb_resume_device(). It's also routine
* to disconnect devices while they are suspended.
*
+ * This only affects the USB hardware for a device; its interfaces
+ * (and, for hubs, child devices) must already have been suspended.
+ *
* Suspending OTG devices may trigger HNP, if that's been enabled
* between a pair of dual-role devices. That will change roles, such
* as from A-Host to A-Peripheral or from B-Host back to B-Peripheral.
*
* Returns 0 on success, else negative errno.
*/
-int usb_suspend_device(struct usb_device *udev, pm_message_t state)
+int usb_suspend_device(struct usb_device *udev)
{
+#ifdef CONFIG_USB_SUSPEND
int port1, status;
port1 = locktree(udev);
if (port1 < 0)
return port1;
- status = __usb_suspend_device(udev, port1, state);
+ status = __usb_suspend_device(udev, port1);
usb_unlock_device(udev);
return status;
+#else
+ /* NOTE: udev->state unchanged, it's not lying ... */
+ udev->dev.power.power_state = PMSG_SUSPEND;
+ return 0;
+#endif
}
+EXPORT_SYMBOL_GPL(usb_suspend_device);
/*
+ * If the USB "suspend" state is in use (rather than "global suspend"),
+ * many devices will be individually taken out of suspend state using
+ * special" resume" signaling. These routines kick in shortly after
* hardware resume signaling is finished, either because of selective
* resume (by host) or remote wakeup (by device) ... now see what changed
* in the tree that's rooted at this device.
*/
-static int finish_port_resume(struct usb_device *udev)
+static int finish_device_resume(struct usb_device *udev)
{
int status;
u16 devstatus;
/* caller owns the udev device lock */
- dev_dbg(&udev->dev, "usb resume\n");
+ dev_dbg(&udev->dev, "finish resume\n");
/* usb ch9 identifies four variants of SUSPENDED, based on what
* state the device resumes to. Linux currently won't see the
@@ -1747,7 +1700,6 @@ static int finish_port_resume(struct usb_device *udev)
usb_set_device_state(udev, udev->actconfig
? USB_STATE_CONFIGURED
: USB_STATE_ADDRESS);
- udev->dev.power.power_state = PMSG_ON;
/* 10.5.4.5 says be sure devices in the tree are still there.
* For now let's assume the device didn't go crazy on resume,
@@ -1760,9 +1712,11 @@ static int finish_port_resume(struct usb_device *udev)
status);
else if (udev->actconfig) {
unsigned i;
+ int (*resume)(struct device *);
le16_to_cpus(&devstatus);
- if (devstatus & (1 << USB_DEVICE_REMOTE_WAKEUP)) {
+ if (devstatus & (1 << USB_DEVICE_REMOTE_WAKEUP)
+ && udev->parent) {
status = usb_control_msg(udev,
usb_sndctrlpipe(udev, 0),
USB_REQ_CLEAR_FEATURE,
@@ -1778,33 +1732,11 @@ static int finish_port_resume(struct usb_device *udev)
}
/* resume interface drivers; if this is a hub, it
- * resumes the child devices
+ * may have a child resume event to deal with soon
*/
- for (i = 0; i < udev->actconfig->desc.bNumInterfaces; i++) {
- struct usb_interface *intf;
- struct usb_driver *driver;
-
- intf = udev->actconfig->interface[i];
- if (intf->dev.power.power_state.event == PM_EVENT_ON)
- continue;
- if (!intf->dev.driver) {
- /* FIXME maybe force to alt 0 */
- continue;
- }
- driver = to_usb_driver(intf->dev.driver);
-
- /* bus_rescan_devices() may rebind drivers */
- if (!driver->resume)
- continue;
-
- /* can we do better than just logging errors? */
- status = driver->resume(intf);
- if (intf->dev.power.power_state.event != PM_EVENT_ON
- || status)
- dev_dbg(&intf->dev,
- "resume fail, state %d code %d\n",
- intf->dev.power.power_state.event, status);
- }
+ resume = udev->dev.bus->resume;
+ for (i = 0; i < udev->actconfig->desc.bNumInterfaces; i++)
+ (void) resume(&udev->actconfig->interface[i]->dev);
status = 0;
} else if (udev->devnum <= 0) {
@@ -1814,6 +1746,8 @@ static int finish_port_resume(struct usb_device *udev)
return status;
}
+#ifdef CONFIG_USB_SUSPEND
+
static int
hub_port_resume(struct usb_hub *hub, int port1, struct usb_device *udev)
{
@@ -1859,7 +1793,7 @@ hub_port_resume(struct usb_hub *hub, int port1, struct usb_device *udev)
/* TRSMRCY = 10 msec */
msleep(10);
if (udev)
- status = finish_port_resume(udev);
+ status = finish_device_resume(udev);
}
}
if (status < 0)
@@ -1868,12 +1802,12 @@ hub_port_resume(struct usb_hub *hub, int port1, struct usb_device *udev)
return status;
}
-static int hub_resume (struct usb_interface *intf);
+#endif
-/**
+/*
* usb_resume_device - re-activate a suspended usb device
* @udev: device to re-activate
- * Context: must be able to sleep; device not locked
+ * Context: must be able to sleep; device not locked; pm locks held
*
* This will re-activate the suspended device, increasing power usage
* while letting drivers communicate again with its endpoints.
@@ -1891,35 +1825,22 @@ int usb_resume_device(struct usb_device *udev)
if (port1 < 0)
return port1;
- /* "global resume" of the HC-to-USB interface (root hub), or
- * selective resume of one hub-to-device port
- */
- if (!udev->parent) {
- struct usb_bus *bus = udev->bus;
- if (bus && bus->op->hub_resume) {
- status = bus->op->hub_resume (bus);
+#ifdef CONFIG_USB_SUSPEND
+ /* selective resume of one downstream hub-to-device port */
+ if (udev->parent) {
+ if (udev->state == USB_STATE_SUSPENDED) {
+ // NOTE swsusp may bork us, device state being wrong...
+ // NOTE this fails if parent is also suspended...
+ status = hub_port_resume(hdev_to_hub(udev->parent),
+ port1, udev);
} else
- status = -EOPNOTSUPP;
- if (status == 0) {
- dev_dbg(&udev->dev, "usb resume\n");
- /* TRSMRCY = 10 msec */
- msleep(10);
- usb_set_device_state (udev, USB_STATE_CONFIGURED);
- udev->dev.power.power_state = PMSG_ON;
- status = hub_resume (udev
- ->actconfig->interface[0]);
- }
- } else if (udev->state == USB_STATE_SUSPENDED) {
- // NOTE this fails if parent is also suspended...
- status = hub_port_resume(hdev_to_hub(udev->parent),
- port1, udev);
- } else {
- status = 0;
- }
- if (status < 0) {
+ status = 0;
+ } else
+#endif
+ status = finish_device_resume(udev);
+ if (status < 0)
dev_dbg(&udev->dev, "can't resume, status %d\n",
status);
- }
usb_unlock_device(udev);
@@ -1936,6 +1857,8 @@ static int remote_wakeup(struct usb_device *udev)
{
int status = 0;
+#ifdef CONFIG_USB_SUSPEND
+
/* don't repeat RESUME sequence if this device
* was already woken up by some other task
*/
@@ -1944,38 +1867,52 @@ static int remote_wakeup(struct usb_device *udev)
dev_dbg(&udev->dev, "RESUME (wakeup)\n");
/* TRSMRCY = 10 msec */
msleep(10);
- status = finish_port_resume(udev);
+ status = finish_device_resume(udev);
}
up(&udev->serialize);
+#endif
return status;
}
-static int hub_suspend(struct usb_interface *intf, pm_message_t state)
+static int hub_suspend(struct usb_interface *intf, pm_message_t msg)
{
struct usb_hub *hub = usb_get_intfdata (intf);
struct usb_device *hdev = hub->hdev;
unsigned port1;
- int status;
- /* stop khubd and related activity */
- hub_quiesce(hub);
-
- /* then suspend every port */
+ /* fail if children aren't already suspended */
for (port1 = 1; port1 <= hdev->maxchild; port1++) {
struct usb_device *udev;
udev = hdev->children [port1-1];
- if (!udev)
- continue;
- down(&udev->serialize);
- status = __usb_suspend_device(udev, port1, state);
- up(&udev->serialize);
- if (status < 0)
- dev_dbg(&intf->dev, "suspend port %d --> %d\n",
- port1, status);
+ if (udev && (udev->dev.power.power_state.event
+ == PM_EVENT_ON
+#ifdef CONFIG_USB_SUSPEND
+ || udev->state != USB_STATE_SUSPENDED
+#endif
+ )) {
+ dev_dbg(&intf->dev, "port %d nyet suspended\n", port1);
+ return -EBUSY;
+ }
}
- intf->dev.power.power_state = state;
+ /* "global suspend" of the downstream HC-to-USB interface */
+ if (!hdev->parent) {
+ struct usb_bus *bus = hdev->bus;
+ if (bus) {
+ int status = hcd_bus_suspend (bus);
+
+ if (status != 0) {
+ dev_dbg(&hdev->dev, "'global' suspend %d\n",
+ status);
+ return status;
+ }
+ } else
+ return -EOPNOTSUPP;
+ }
+
+ /* stop khubd and related activity */
+ hub_quiesce(hub);
return 0;
}
@@ -1983,11 +1920,35 @@ static int hub_resume(struct usb_interface *intf)
{
struct usb_device *hdev = interface_to_usbdev(intf);
struct usb_hub *hub = usb_get_intfdata (intf);
- unsigned port1;
int status;
- if (intf->dev.power.power_state.event == PM_EVENT_ON)
- return 0;
+ /* "global resume" of the downstream HC-to-USB interface */
+ if (!hdev->parent) {
+ struct usb_bus *bus = hdev->bus;
+ if (bus) {
+ status = hcd_bus_resume (bus);
+ if (status) {
+ dev_dbg(&intf->dev, "'global' resume %d\n",
+ status);
+ return status;
+ }
+ } else
+ return -EOPNOTSUPP;
+ if (status == 0) {
+ /* TRSMRCY = 10 msec */
+ msleep(10);
+ }
+ }
+
+ hub_activate(hub);
+
+ /* REVISIT: this recursion probably shouldn't exist. Remove
+ * this code sometime, after retesting with different root and
+ * external hubs.
+ */
+#ifdef CONFIG_USB_SUSPEND
+ {
+ unsigned port1;
for (port1 = 1; port1 <= hdev->maxchild; port1++) {
struct usb_device *udev;
@@ -2013,7 +1974,7 @@ static int hub_resume(struct usb_interface *intf)
if (portstat & USB_PORT_STAT_SUSPEND)
status = hub_port_resume(hub, port1, udev);
else {
- status = finish_port_resume(udev);
+ status = finish_device_resume(udev);
if (status < 0) {
dev_dbg(&intf->dev, "resume port %d --> %d\n",
port1, status);
@@ -2022,43 +1983,31 @@ static int hub_resume(struct usb_interface *intf)
}
up(&udev->serialize);
}
- intf->dev.power.power_state = PMSG_ON;
-
- hub->resume_root_hub = 0;
- hub_activate(hub);
+ }
+#endif
return 0;
}
-void usb_resume_root_hub(struct usb_device *hdev)
+void usb_suspend_root_hub(struct usb_device *hdev)
{
struct usb_hub *hub = hdev_to_hub(hdev);
- hub->resume_root_hub = 1;
- kick_khubd(hub);
+ /* This also makes any led blinker stop retriggering. We're called
+ * from irq, so the blinker might still be scheduled. Caller promises
+ * that the root hub status URB will be canceled.
+ */
+ __hub_quiesce(hub);
+ mark_quiesced(to_usb_interface(hub->intfdev));
}
-#else /* !CONFIG_USB_SUSPEND */
-
-int usb_suspend_device(struct usb_device *udev, pm_message_t state)
+void usb_resume_root_hub(struct usb_device *hdev)
{
- return 0;
-}
+ struct usb_hub *hub = hdev_to_hub(hdev);
-int usb_resume_device(struct usb_device *udev)
-{
- return 0;
+ hub->resume_root_hub = 1;
+ kick_khubd(hub);
}
-#define hub_suspend NULL
-#define hub_resume NULL
-#define remote_wakeup(x) 0
-
-#endif /* CONFIG_USB_SUSPEND */
-
-EXPORT_SYMBOL(usb_suspend_device);
-EXPORT_SYMBOL(usb_resume_device);
-
-
/* USB 2.0 spec, 7.1.7.3 / fig 7-29:
*
@@ -2467,6 +2416,7 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1,
{
struct usb_device *hdev = hub->hdev;
struct device *hub_dev = hub->intfdev;
+ u16 wHubCharacteristics = le16_to_cpu(hub->descriptor->wHubCharacteristics);
int status, i;
dev_dbg (hub_dev,
@@ -2504,8 +2454,7 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1,
if (!(portstatus & USB_PORT_STAT_CONNECTION)) {
/* maybe switch power back on (e.g. root hub was reset) */
- if ((hub->descriptor->wHubCharacteristics
- & HUB_CHAR_LPSM) < 2
+ if ((wHubCharacteristics & HUB_CHAR_LPSM) < 2
&& !(portstatus & (1 << USB_PORT_FEAT_POWER)))
set_port_feature(hdev, port1, USB_PORT_FEAT_POWER);
@@ -2684,21 +2633,28 @@ static void hub_events(void)
intf = to_usb_interface(hub->intfdev);
hub_dev = &intf->dev;
- dev_dbg(hub_dev, "state %d ports %d chg %04x evt %04x\n",
+ i = hub->resume_root_hub;
+
+ dev_dbg(hub_dev, "state %d ports %d chg %04x evt %04x%s\n",
hdev->state, hub->descriptor
? hub->descriptor->bNbrPorts
: 0,
/* NOTE: expects max 15 ports... */
(u16) hub->change_bits[0],
- (u16) hub->event_bits[0]);
+ (u16) hub->event_bits[0],
+ i ? ", resume root" : "");
usb_get_intf(intf);
- i = hub->resume_root_hub;
spin_unlock_irq(&hub_event_lock);
- /* Is this is a root hub wanting to be resumed? */
- if (i)
- usb_resume_device(hdev);
+ /* Is this is a root hub wanting to reactivate the downstream
+ * ports? If so, be sure the interface resumes even if its
+ * stub "device" node was never suspended.
+ */
+ if (i) {
+ dpm_runtime_resume(&hdev->dev);
+ dpm_runtime_resume(&intf->dev);
+ }
/* Lock the device, then check to see if we were
* disconnected while waiting for the lock to succeed. */
diff --git a/drivers/usb/core/hub.h b/drivers/usb/core/hub.h
index e7fa9b5a521e..bf23f8978024 100644
--- a/drivers/usb/core/hub.h
+++ b/drivers/usb/core/hub.h
@@ -131,7 +131,7 @@ struct usb_hub_descriptor {
__u8 bDescLength;
__u8 bDescriptorType;
__u8 bNbrPorts;
- __u16 wHubCharacteristics;
+ __le16 wHubCharacteristics;
__u8 bPwrOn2PwrGood;
__u8 bHubContrCurrent;
/* add 1 bit for hub status change; round to bytes */
diff --git a/drivers/usb/core/inode.c b/drivers/usb/core/inode.c
index d07bba01995b..12f490fdee8f 100644
--- a/drivers/usb/core/inode.c
+++ b/drivers/usb/core/inode.c
@@ -39,6 +39,7 @@
#include <linux/usbdevice_fs.h>
#include <linux/smp_lock.h>
#include <linux/parser.h>
+#include <linux/notifier.h>
#include <asm/byteorder.h>
#include "usb.h"
#include "hcd.h"
@@ -619,7 +620,7 @@ void usbfs_update_special (void)
}
}
-void usbfs_add_bus(struct usb_bus *bus)
+static void usbfs_add_bus(struct usb_bus *bus)
{
struct dentry *parent;
char name[8];
@@ -642,12 +643,9 @@ void usbfs_add_bus(struct usb_bus *bus)
err ("error creating usbfs bus entry");
return;
}
-
- usbfs_update_special();
- usbfs_conn_disc_event();
}
-void usbfs_remove_bus(struct usb_bus *bus)
+static void usbfs_remove_bus(struct usb_bus *bus)
{
if (bus->usbfs_dentry) {
fs_remove_file (bus->usbfs_dentry);
@@ -659,12 +657,9 @@ void usbfs_remove_bus(struct usb_bus *bus)
remove_special_files();
num_buses = 0;
}
-
- usbfs_update_special();
- usbfs_conn_disc_event();
}
-void usbfs_add_device(struct usb_device *dev)
+static void usbfs_add_device(struct usb_device *dev)
{
char name[8];
int i;
@@ -690,12 +685,9 @@ void usbfs_add_device(struct usb_device *dev)
}
if (dev->usbfs_dentry->d_inode)
dev->usbfs_dentry->d_inode->i_size = i_size;
-
- usbfs_update_special();
- usbfs_conn_disc_event();
}
-void usbfs_remove_device(struct usb_device *dev)
+static void usbfs_remove_device(struct usb_device *dev)
{
struct dev_state *ds;
struct siginfo sinfo;
@@ -716,10 +708,33 @@ void usbfs_remove_device(struct usb_device *dev)
kill_proc_info_as_uid(ds->discsignr, &sinfo, ds->disc_pid, ds->disc_uid, ds->disc_euid);
}
}
+}
+
+static int usbfs_notify(struct notifier_block *self, unsigned long action, void *dev)
+{
+ switch (action) {
+ case USB_DEVICE_ADD:
+ usbfs_add_device(dev);
+ break;
+ case USB_DEVICE_REMOVE:
+ usbfs_remove_device(dev);
+ break;
+ case USB_BUS_ADD:
+ usbfs_add_bus(dev);
+ break;
+ case USB_BUS_REMOVE:
+ usbfs_remove_bus(dev);
+ }
+
usbfs_update_special();
usbfs_conn_disc_event();
+ return NOTIFY_OK;
}
+static struct notifier_block usbfs_nb = {
+ .notifier_call = usbfs_notify,
+};
+
/* --------------------------------------------------------------------- */
static struct proc_dir_entry *usbdir = NULL;
@@ -732,6 +747,8 @@ int __init usbfs_init(void)
if (retval)
return retval;
+ usb_register_notify(&usbfs_nb);
+
/* create mount point for usbfs */
usbdir = proc_mkdir("usb", proc_bus);
@@ -740,6 +757,7 @@ int __init usbfs_init(void)
void usbfs_cleanup(void)
{
+ usb_unregister_notify(&usbfs_nb);
unregister_filesystem(&usb_fs_type);
if (usbdir)
remove_proc_entry("usb", proc_bus);
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c
index f1fb67fe22a8..644a3d4f12aa 100644
--- a/drivers/usb/core/message.c
+++ b/drivers/usb/core/message.c
@@ -187,21 +187,37 @@ int usb_control_msg(struct usb_device *dev, unsigned int pipe, __u8 request, __u
* If a thread in your driver uses this call, make sure your disconnect()
* method can wait for it to complete. Since you don't have a handle on
* the URB used, you can't cancel the request.
+ *
+ * Because there is no usb_interrupt_msg() and no USBDEVFS_INTERRUPT
+ * ioctl, users are forced to abuse this routine by using it to submit
+ * URBs for interrupt endpoints. We will take the liberty of creating
+ * an interrupt URB (with the default interval) if the target is an
+ * interrupt endpoint.
*/
int usb_bulk_msg(struct usb_device *usb_dev, unsigned int pipe,
void *data, int len, int *actual_length, int timeout)
{
struct urb *urb;
+ struct usb_host_endpoint *ep;
- if (len < 0)
+ ep = (usb_pipein(pipe) ? usb_dev->ep_in : usb_dev->ep_out)
+ [usb_pipeendpoint(pipe)];
+ if (!ep || len < 0)
return -EINVAL;
- urb=usb_alloc_urb(0, GFP_KERNEL);
+ urb = usb_alloc_urb(0, GFP_KERNEL);
if (!urb)
return -ENOMEM;
- usb_fill_bulk_urb(urb, usb_dev, pipe, data, len,
- usb_api_blocking_completion, NULL);
+ if ((ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
+ USB_ENDPOINT_XFER_INT) {
+ pipe = (pipe & ~(3 << 30)) | (PIPE_INTERRUPT << 30);
+ usb_fill_int_urb(urb, usb_dev, pipe, data, len,
+ usb_api_blocking_completion, NULL,
+ ep->desc.bInterval);
+ } else
+ usb_fill_bulk_urb(urb, usb_dev, pipe, data, len,
+ usb_api_blocking_completion, NULL);
return usb_start_wait_urb(urb, timeout, actual_length);
}
@@ -321,7 +337,7 @@ int usb_sg_init (
struct scatterlist *sg,
int nents,
size_t length,
- unsigned mem_flags
+ gfp_t mem_flags
)
{
int i;
@@ -771,6 +787,31 @@ int usb_string(struct usb_device *dev, int index, char *buf, size_t size)
return err;
}
+/**
+ * usb_cache_string - read a string descriptor and cache it for later use
+ * @udev: the device whose string descriptor is being read
+ * @index: the descriptor index
+ *
+ * Returns a pointer to a kmalloc'ed buffer containing the descriptor string,
+ * or NULL if the index is 0 or the string could not be read.
+ */
+char *usb_cache_string(struct usb_device *udev, int index)
+{
+ char *buf;
+ char *smallbuf = NULL;
+ int len;
+
+ if (index > 0 && (buf = kmalloc(256, GFP_KERNEL)) != NULL) {
+ if ((len = usb_string(udev, index, buf, 256)) > 0) {
+ if ((smallbuf = kmalloc(++len, GFP_KERNEL)) == NULL)
+ return buf;
+ memcpy(smallbuf, buf, len);
+ }
+ kfree(buf);
+ }
+ return smallbuf;
+}
+
/*
* usb_get_device_descriptor - (re)reads the device descriptor (usbcore)
* @dev: the device whose device descriptor is being updated
@@ -992,8 +1033,6 @@ void usb_disable_device(struct usb_device *dev, int skip_ep0)
dev_dbg (&dev->dev, "unregistering interface %s\n",
interface->dev.bus_id);
usb_remove_sysfs_intf_files(interface);
- kfree(interface->cur_altsetting->string);
- interface->cur_altsetting->string = NULL;
device_del (&interface->dev);
}
@@ -1133,6 +1172,8 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate)
*/
/* prevent submissions using previous endpoint settings */
+ if (device_is_registered(&iface->dev))
+ usb_remove_sysfs_intf_files(iface);
usb_disable_interface(dev, iface);
iface->cur_altsetting = alt;
@@ -1168,6 +1209,8 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate)
* (Likewise, EP0 never "halts" on well designed devices.)
*/
usb_enable_interface(dev, iface);
+ if (device_is_registered(&iface->dev))
+ usb_create_sysfs_intf_files(iface);
return 0;
}
@@ -1217,10 +1260,8 @@ int usb_reset_configuration(struct usb_device *dev)
USB_REQ_SET_CONFIGURATION, 0,
config->desc.bConfigurationValue, 0,
NULL, 0, USB_CTRL_SET_TIMEOUT);
- if (retval < 0) {
- usb_set_device_state(dev, USB_STATE_ADDRESS);
+ if (retval < 0)
return retval;
- }
dev->toggle[0] = dev->toggle[1] = 0;
@@ -1229,6 +1270,8 @@ int usb_reset_configuration(struct usb_device *dev)
struct usb_interface *intf = config->interface[i];
struct usb_host_interface *alt;
+ if (device_is_registered(&intf->dev))
+ usb_remove_sysfs_intf_files(intf);
alt = usb_altnum_to_altsetting(intf, 0);
/* No altsetting 0? We'll assume the first altsetting.
@@ -1241,6 +1284,8 @@ int usb_reset_configuration(struct usb_device *dev)
intf->cur_altsetting = alt;
usb_enable_interface(dev, intf);
+ if (device_is_registered(&intf->dev))
+ usb_create_sysfs_intf_files(intf);
}
return 0;
}
@@ -1328,7 +1373,7 @@ int usb_set_configuration(struct usb_device *dev, int configuration)
}
for (; n < nintf; ++n) {
- new_interfaces[n] = kmalloc(
+ new_interfaces[n] = kzalloc(
sizeof(struct usb_interface),
GFP_KERNEL);
if (!new_interfaces[n]) {
@@ -1369,7 +1414,6 @@ free_interfaces:
struct usb_host_interface *alt;
cp->interface[i] = intf = new_interfaces[i];
- memset(intf, 0, sizeof(*intf));
intfc = cp->intf_cache[i];
intf->altsetting = intfc->altsetting;
intf->num_altsetting = intfc->num_altsetting;
@@ -1393,6 +1437,7 @@ free_interfaces:
intf->dev.dma_mask = dev->dev.dma_mask;
intf->dev.release = release_interface;
device_initialize (&intf->dev);
+ mark_quiesced(intf);
sprintf (&intf->dev.bus_id[0], "%d-%s:%d.%d",
dev->bus->busnum, dev->devpath,
configuration,
@@ -1400,12 +1445,9 @@ free_interfaces:
}
kfree(new_interfaces);
- if ((cp->desc.iConfiguration) &&
- (cp->string == NULL)) {
- cp->string = kmalloc(256, GFP_KERNEL);
- if (cp->string)
- usb_string(dev, cp->desc.iConfiguration, cp->string, 256);
- }
+ if (cp->string == NULL)
+ cp->string = usb_cache_string(dev,
+ cp->desc.iConfiguration);
/* Now that all the interfaces are set up, register them
* to trigger binding of drivers to interfaces. probe()
@@ -1415,13 +1457,12 @@ free_interfaces:
*/
for (i = 0; i < nintf; ++i) {
struct usb_interface *intf = cp->interface[i];
- struct usb_interface_descriptor *desc;
+ struct usb_host_interface *alt = intf->cur_altsetting;
- desc = &intf->altsetting [0].desc;
dev_dbg (&dev->dev,
"adding %s (config #%d, interface %d)\n",
intf->dev.bus_id, configuration,
- desc->bInterfaceNumber);
+ alt->desc.bInterfaceNumber);
ret = device_add (&intf->dev);
if (ret != 0) {
dev_err(&dev->dev,
@@ -1430,13 +1471,6 @@ free_interfaces:
ret);
continue;
}
- if ((intf->cur_altsetting->desc.iInterface) &&
- (intf->cur_altsetting->string == NULL)) {
- intf->cur_altsetting->string = kmalloc(256, GFP_KERNEL);
- if (intf->cur_altsetting->string)
- usb_string(dev, intf->cur_altsetting->desc.iInterface,
- intf->cur_altsetting->string, 256);
- }
usb_create_sysfs_intf_files (intf);
}
}
diff --git a/drivers/usb/core/notify.c b/drivers/usb/core/notify.c
new file mode 100644
index 000000000000..37da059eced7
--- /dev/null
+++ b/drivers/usb/core/notify.c
@@ -0,0 +1,120 @@
+/*
+ * All the USB notify logic
+ *
+ * (C) Copyright 2005 Greg Kroah-Hartman <gregkh@suse.de>
+ *
+ * notifier functions originally based on those in kernel/sys.c
+ * but fixed up to not be so broken.
+ *
+ */
+
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/notifier.h>
+#ifdef CONFIG_USB_DEBUG
+ #define DEBUG
+#else
+ #undef DEBUG
+#endif
+#include <linux/usb.h>
+
+#include "usb.h"
+
+
+static struct notifier_block *usb_notifier_list;
+static DECLARE_MUTEX(usb_notifier_lock);
+
+static void usb_notifier_chain_register(struct notifier_block **list,
+ struct notifier_block *n)
+{
+ down(&usb_notifier_lock);
+ while (*list) {
+ if (n->priority > (*list)->priority)
+ break;
+ list = &((*list)->next);
+ }
+ n->next = *list;
+ *list = n;
+ up(&usb_notifier_lock);
+}
+
+static void usb_notifier_chain_unregister(struct notifier_block **nl,
+ struct notifier_block *n)
+{
+ down(&usb_notifier_lock);
+ while ((*nl)!=NULL) {
+ if ((*nl)==n) {
+ *nl = n->next;
+ goto exit;
+ }
+ nl=&((*nl)->next);
+ }
+exit:
+ up(&usb_notifier_lock);
+}
+
+static int usb_notifier_call_chain(struct notifier_block **n,
+ unsigned long val, void *v)
+{
+ int ret=NOTIFY_DONE;
+ struct notifier_block *nb = *n;
+
+ down(&usb_notifier_lock);
+ while (nb) {
+ ret = nb->notifier_call(nb,val,v);
+ if (ret&NOTIFY_STOP_MASK) {
+ goto exit;
+ }
+ nb = nb->next;
+ }
+exit:
+ up(&usb_notifier_lock);
+ return ret;
+}
+
+/**
+ * usb_register_notify - register a notifier callback whenever a usb change happens
+ * @nb: pointer to the notifier block for the callback events.
+ *
+ * These changes are either USB devices or busses being added or removed.
+ */
+void usb_register_notify(struct notifier_block *nb)
+{
+ usb_notifier_chain_register(&usb_notifier_list, nb);
+}
+EXPORT_SYMBOL_GPL(usb_register_notify);
+
+/**
+ * usb_unregister_notify - unregister a notifier callback
+ * @nb: pointer to the notifier block for the callback events.
+ *
+ * usb_register_notifier() must have been previously called for this function
+ * to work properly.
+ */
+void usb_unregister_notify(struct notifier_block *nb)
+{
+ usb_notifier_chain_unregister(&usb_notifier_list, nb);
+}
+EXPORT_SYMBOL_GPL(usb_unregister_notify);
+
+
+void usb_notify_add_device(struct usb_device *udev)
+{
+ usb_notifier_call_chain(&usb_notifier_list, USB_DEVICE_ADD, udev);
+}
+
+void usb_notify_remove_device(struct usb_device *udev)
+{
+ usb_notifier_call_chain(&usb_notifier_list, USB_DEVICE_REMOVE, udev);
+}
+
+void usb_notify_add_bus(struct usb_bus *ubus)
+{
+ usb_notifier_call_chain(&usb_notifier_list, USB_BUS_ADD, ubus);
+}
+
+void usb_notify_remove_bus(struct usb_bus *ubus)
+{
+ usb_notifier_call_chain(&usb_notifier_list, USB_BUS_REMOVE, ubus);
+}
diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c
index 00297f113849..edd83e014452 100644
--- a/drivers/usb/core/sysfs.c
+++ b/drivers/usb/core/sysfs.c
@@ -22,9 +22,207 @@
#include "usb.h"
+/* endpoint stuff */
+struct ep_object {
+ struct usb_endpoint_descriptor *desc;
+ struct usb_device *udev;
+ struct kobject kobj;
+};
+#define to_ep_object(_kobj) \
+ container_of(_kobj, struct ep_object, kobj)
+
+struct ep_attribute {
+ struct attribute attr;
+ ssize_t (*show)(struct usb_device *,
+ struct usb_endpoint_descriptor *, char *);
+};
+#define to_ep_attribute(_attr) \
+ container_of(_attr, struct ep_attribute, attr)
+
+#define EP_ATTR(_name) \
+struct ep_attribute ep_##_name = { \
+ .attr = {.name = #_name, .owner = THIS_MODULE, \
+ .mode = S_IRUGO}, \
+ .show = show_ep_##_name}
+
+#define usb_ep_attr(field, format_string) \
+static ssize_t show_ep_##field(struct usb_device *udev, \
+ struct usb_endpoint_descriptor *desc, \
+ char *buf) \
+{ \
+ return sprintf(buf, format_string, desc->field); \
+} \
+static EP_ATTR(field);
+
+usb_ep_attr(bLength, "%02x\n")
+usb_ep_attr(bEndpointAddress, "%02x\n")
+usb_ep_attr(bmAttributes, "%02x\n")
+usb_ep_attr(bInterval, "%02x\n")
+
+static ssize_t show_ep_wMaxPacketSize(struct usb_device *udev,
+ struct usb_endpoint_descriptor *desc, char *buf)
+{
+ return sprintf(buf, "%04x\n",
+ le16_to_cpu(desc->wMaxPacketSize) & 0x07ff);
+}
+static EP_ATTR(wMaxPacketSize);
+
+static ssize_t show_ep_type(struct usb_device *udev,
+ struct usb_endpoint_descriptor *desc, char *buf)
+{
+ char *type = "unknown";
+
+ switch (desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) {
+ case USB_ENDPOINT_XFER_CONTROL:
+ type = "Control";
+ break;
+ case USB_ENDPOINT_XFER_ISOC:
+ type = "Isoc";
+ break;
+ case USB_ENDPOINT_XFER_BULK:
+ type = "Bulk";
+ break;
+ case USB_ENDPOINT_XFER_INT:
+ type = "Interrupt";
+ break;
+ }
+ return sprintf(buf, "%s\n", type);
+}
+static EP_ATTR(type);
+
+static ssize_t show_ep_interval(struct usb_device *udev,
+ struct usb_endpoint_descriptor *desc, char *buf)
+{
+ char unit;
+ unsigned interval = 0;
+ unsigned in;
+
+ in = (desc->bEndpointAddress & USB_DIR_IN);
+
+ switch (desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) {
+ case USB_ENDPOINT_XFER_CONTROL:
+ if (udev->speed == USB_SPEED_HIGH) /* uframes per NAK */
+ interval = desc->bInterval;
+ break;
+ case USB_ENDPOINT_XFER_ISOC:
+ interval = 1 << (desc->bInterval - 1);
+ break;
+ case USB_ENDPOINT_XFER_BULK:
+ if (udev->speed == USB_SPEED_HIGH && !in) /* uframes per NAK */
+ interval = desc->bInterval;
+ break;
+ case USB_ENDPOINT_XFER_INT:
+ if (udev->speed == USB_SPEED_HIGH)
+ interval = 1 << (desc->bInterval - 1);
+ else
+ interval = desc->bInterval;
+ break;
+ }
+ interval *= (udev->speed == USB_SPEED_HIGH) ? 125 : 1000;
+ if (interval % 1000)
+ unit = 'u';
+ else {
+ unit = 'm';
+ interval /= 1000;
+ }
+
+ return sprintf(buf, "%d%cs\n", interval, unit);
+}
+static EP_ATTR(interval);
+
+static ssize_t show_ep_direction(struct usb_device *udev,
+ struct usb_endpoint_descriptor *desc, char *buf)
+{
+ char *direction;
+
+ if ((desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
+ USB_ENDPOINT_XFER_CONTROL)
+ direction = "both";
+ else if (desc->bEndpointAddress & USB_DIR_IN)
+ direction = "in";
+ else
+ direction = "out";
+ return sprintf(buf, "%s\n", direction);
+}
+static EP_ATTR(direction);
+
+static struct attribute *ep_attrs[] = {
+ &ep_bLength.attr,
+ &ep_bEndpointAddress.attr,
+ &ep_bmAttributes.attr,
+ &ep_bInterval.attr,
+ &ep_wMaxPacketSize.attr,
+ &ep_type.attr,
+ &ep_interval.attr,
+ &ep_direction.attr,
+ NULL,
+};
+
+static void ep_object_release(struct kobject *kobj)
+{
+ kfree(to_ep_object(kobj));
+}
+
+static ssize_t ep_object_show(struct kobject *kobj, struct attribute *attr,
+ char *buf)
+{
+ struct ep_object *ep_obj = to_ep_object(kobj);
+ struct ep_attribute *ep_attr = to_ep_attribute(attr);
+
+ return (ep_attr->show)(ep_obj->udev, ep_obj->desc, buf);
+}
+
+static struct sysfs_ops ep_object_sysfs_ops = {
+ .show = ep_object_show,
+};
+
+static struct kobj_type ep_object_ktype = {
+ .release = ep_object_release,
+ .sysfs_ops = &ep_object_sysfs_ops,
+ .default_attrs = ep_attrs,
+};
+
+static void usb_create_ep_files(struct kobject *parent,
+ struct usb_host_endpoint *endpoint,
+ struct usb_device *udev)
+{
+ struct ep_object *ep_obj;
+ struct kobject *kobj;
+
+ ep_obj = kzalloc(sizeof(struct ep_object), GFP_KERNEL);
+ if (!ep_obj)
+ return;
+
+ ep_obj->desc = &endpoint->desc;
+ ep_obj->udev = udev;
+
+ kobj = &ep_obj->kobj;
+ kobject_set_name(kobj, "ep_%02x", endpoint->desc.bEndpointAddress);
+ kobj->parent = parent;
+ kobj->ktype = &ep_object_ktype;
+
+ /* Don't use kobject_register, because it generates a hotplug event */
+ kobject_init(kobj);
+ if (kobject_add(kobj) == 0)
+ endpoint->kobj = kobj;
+ else
+ kobject_put(kobj);
+}
+
+static void usb_remove_ep_files(struct usb_host_endpoint *endpoint)
+{
+
+ if (endpoint->kobj) {
+ kobject_del(endpoint->kobj);
+ kobject_put(endpoint->kobj);
+ endpoint->kobj = NULL;
+ }
+}
+
/* Active configuration fields */
#define usb_actconfig_show(field, multiplier, format_string) \
-static ssize_t show_##field (struct device *dev, struct device_attribute *attr, char *buf) \
+static ssize_t show_##field (struct device *dev, \
+ struct device_attribute *attr, char *buf) \
{ \
struct usb_device *udev; \
struct usb_host_config *actconfig; \
@@ -46,22 +244,17 @@ usb_actconfig_attr (bNumInterfaces, 1, "%2d\n")
usb_actconfig_attr (bmAttributes, 1, "%2x\n")
usb_actconfig_attr (bMaxPower, 2, "%3dmA\n")
-static ssize_t show_configuration_string(struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t show_configuration_string(struct device *dev,
+ struct device_attribute *attr, char *buf)
{
struct usb_device *udev;
struct usb_host_config *actconfig;
- int len;
udev = to_usb_device (dev);
actconfig = udev->actconfig;
if ((!actconfig) || (!actconfig->string))
return 0;
- len = sprintf(buf, actconfig->string, PAGE_SIZE);
- if (len < 0)
- return 0;
- buf[len] = '\n';
- buf[len+1] = 0;
- return len+1;
+ return sprintf(buf, "%s\n", actconfig->string);
}
static DEVICE_ATTR(configuration, S_IRUGO, show_configuration_string, NULL);
@@ -69,7 +262,8 @@ static DEVICE_ATTR(configuration, S_IRUGO, show_configuration_string, NULL);
usb_actconfig_show(bConfigurationValue, 1, "%u\n");
static ssize_t
-set_bConfigurationValue (struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+set_bConfigurationValue (struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
{
struct usb_device *udev = udev = to_usb_device (dev);
int config, value;
@@ -87,18 +281,13 @@ static DEVICE_ATTR(bConfigurationValue, S_IRUGO | S_IWUSR,
/* String fields */
#define usb_string_attr(name) \
-static ssize_t show_##name(struct device *dev, struct device_attribute *attr, char *buf) \
+static ssize_t show_##name(struct device *dev, \
+ struct device_attribute *attr, char *buf) \
{ \
struct usb_device *udev; \
- int len; \
\
udev = to_usb_device (dev); \
- len = snprintf(buf, 256, "%s", udev->name); \
- if (len < 0) \
- return 0; \
- buf[len] = '\n'; \
- buf[len+1] = 0; \
- return len+1; \
+ return sprintf(buf, "%s\n", udev->name); \
} \
static DEVICE_ATTR(name, S_IRUGO, show_##name, NULL);
@@ -167,7 +356,8 @@ static DEVICE_ATTR(maxchild, S_IRUGO, show_maxchild, NULL);
/* Descriptor fields */
#define usb_descriptor_attr_le16(field, format_string) \
static ssize_t \
-show_##field (struct device *dev, struct device_attribute *attr, char *buf) \
+show_##field (struct device *dev, struct device_attribute *attr, \
+ char *buf) \
{ \
struct usb_device *udev; \
\
@@ -183,7 +373,8 @@ usb_descriptor_attr_le16(bcdDevice, "%04x\n")
#define usb_descriptor_attr(field, format_string) \
static ssize_t \
-show_##field (struct device *dev, struct device_attribute *attr, char *buf) \
+show_##field (struct device *dev, struct device_attribute *attr, \
+ char *buf) \
{ \
struct usb_device *udev; \
\
@@ -236,19 +427,21 @@ void usb_create_sysfs_dev_files (struct usb_device *udev)
if (udev->serial)
device_create_file (dev, &dev_attr_serial);
device_create_file (dev, &dev_attr_configuration);
+ usb_create_ep_files(&dev->kobj, &udev->ep0, udev);
}
void usb_remove_sysfs_dev_files (struct usb_device *udev)
{
struct device *dev = &udev->dev;
+ usb_remove_ep_files(&udev->ep0);
sysfs_remove_group(&dev->kobj, &dev_attr_grp);
- if (udev->descriptor.iManufacturer)
+ if (udev->manufacturer)
device_remove_file(dev, &dev_attr_manufacturer);
- if (udev->descriptor.iProduct)
+ if (udev->product)
device_remove_file(dev, &dev_attr_product);
- if (udev->descriptor.iSerialNumber)
+ if (udev->serial)
device_remove_file(dev, &dev_attr_serial);
device_remove_file (dev, &dev_attr_configuration);
}
@@ -256,11 +449,13 @@ void usb_remove_sysfs_dev_files (struct usb_device *udev)
/* Interface fields */
#define usb_intf_attr(field, format_string) \
static ssize_t \
-show_##field (struct device *dev, struct device_attribute *attr, char *buf) \
+show_##field (struct device *dev, struct device_attribute *attr, \
+ char *buf) \
{ \
struct usb_interface *intf = to_usb_interface (dev); \
\
- return sprintf (buf, format_string, intf->cur_altsetting->desc.field); \
+ return sprintf (buf, format_string, \
+ intf->cur_altsetting->desc.field); \
} \
static DEVICE_ATTR(field, S_IRUGO, show_##field, NULL);
@@ -271,7 +466,8 @@ usb_intf_attr (bInterfaceClass, "%02x\n")
usb_intf_attr (bInterfaceSubClass, "%02x\n")
usb_intf_attr (bInterfaceProtocol, "%02x\n")
-static ssize_t show_interface_string(struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t show_interface_string(struct device *dev,
+ struct device_attribute *attr, char *buf)
{
struct usb_interface *intf;
struct usb_device *udev;
@@ -288,34 +484,28 @@ static ssize_t show_interface_string(struct device *dev, struct device_attribute
}
static DEVICE_ATTR(interface, S_IRUGO, show_interface_string, NULL);
-static ssize_t show_modalias(struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t show_modalias(struct device *dev,
+ struct device_attribute *attr, char *buf)
{
struct usb_interface *intf;
struct usb_device *udev;
- int len;
+ struct usb_host_interface *alt;
intf = to_usb_interface(dev);
udev = interface_to_usbdev(intf);
-
- len = sprintf(buf, "usb:v%04Xp%04Xd%04Xdc%02Xdsc%02Xdp%02Xic",
- le16_to_cpu(udev->descriptor.idVendor),
- le16_to_cpu(udev->descriptor.idProduct),
- le16_to_cpu(udev->descriptor.bcdDevice),
- udev->descriptor.bDeviceClass,
- udev->descriptor.bDeviceSubClass,
- udev->descriptor.bDeviceProtocol);
- buf += len;
-
- if (udev->descriptor.bDeviceClass == 0) {
- struct usb_host_interface *alt = intf->cur_altsetting;
-
- return len + sprintf(buf, "%02Xisc%02Xip%02X\n",
- alt->desc.bInterfaceClass,
- alt->desc.bInterfaceSubClass,
- alt->desc.bInterfaceProtocol);
- } else {
- return len + sprintf(buf, "*isc*ip*\n");
- }
+ alt = intf->cur_altsetting;
+
+ return sprintf(buf, "usb:v%04Xp%04Xd%04Xdc%02Xdsc%02Xdp%02X"
+ "ic%02Xisc%02Xip%02X\n",
+ le16_to_cpu(udev->descriptor.idVendor),
+ le16_to_cpu(udev->descriptor.idProduct),
+ le16_to_cpu(udev->descriptor.bcdDevice),
+ udev->descriptor.bDeviceClass,
+ udev->descriptor.bDeviceSubClass,
+ udev->descriptor.bDeviceProtocol,
+ alt->desc.bInterfaceClass,
+ alt->desc.bInterfaceSubClass,
+ alt->desc.bInterfaceProtocol);
}
static DEVICE_ATTR(modalias, S_IRUGO, show_modalias, NULL);
@@ -333,20 +523,47 @@ static struct attribute_group intf_attr_grp = {
.attrs = intf_attrs,
};
+static inline void usb_create_intf_ep_files(struct usb_interface *intf,
+ struct usb_device *udev)
+{
+ struct usb_host_interface *iface_desc;
+ int i;
+
+ iface_desc = intf->cur_altsetting;
+ for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i)
+ usb_create_ep_files(&intf->dev.kobj, &iface_desc->endpoint[i],
+ udev);
+}
+
+static inline void usb_remove_intf_ep_files(struct usb_interface *intf)
+{
+ struct usb_host_interface *iface_desc;
+ int i;
+
+ iface_desc = intf->cur_altsetting;
+ for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i)
+ usb_remove_ep_files(&iface_desc->endpoint[i]);
+}
+
void usb_create_sysfs_intf_files (struct usb_interface *intf)
{
+ struct usb_device *udev = interface_to_usbdev(intf);
+ struct usb_host_interface *alt = intf->cur_altsetting;
+
sysfs_create_group(&intf->dev.kobj, &intf_attr_grp);
- if (intf->cur_altsetting->string)
+ if (alt->string == NULL)
+ alt->string = usb_cache_string(udev, alt->desc.iInterface);
+ if (alt->string)
device_create_file(&intf->dev, &dev_attr_interface);
-
+ usb_create_intf_ep_files(intf, udev);
}
void usb_remove_sysfs_intf_files (struct usb_interface *intf)
{
+ usb_remove_intf_ep_files(intf);
sysfs_remove_group(&intf->dev.kobj, &intf_attr_grp);
if (intf->cur_altsetting->string)
device_remove_file(&intf->dev, &dev_attr_interface);
-
}
diff --git a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c
index c846fefb7386..f2a1fed2a802 100644
--- a/drivers/usb/core/urb.c
+++ b/drivers/usb/core/urb.c
@@ -60,7 +60,7 @@ void usb_init_urb(struct urb *urb)
*
* The driver must call usb_free_urb() when it is finished with the urb.
*/
-struct urb *usb_alloc_urb(int iso_packets, unsigned mem_flags)
+struct urb *usb_alloc_urb(int iso_packets, gfp_t mem_flags)
{
struct urb *urb;
@@ -224,7 +224,7 @@ struct urb * usb_get_urb(struct urb *urb)
* GFP_NOIO, unless b) or c) apply
*
*/
-int usb_submit_urb(struct urb *urb, unsigned mem_flags)
+int usb_submit_urb(struct urb *urb, gfp_t mem_flags)
{
int pipe, temp, max;
struct usb_device *dev;
@@ -237,7 +237,8 @@ int usb_submit_urb(struct urb *urb, unsigned mem_flags)
(dev->state < USB_STATE_DEFAULT) ||
(!dev->bus) || (dev->devnum <= 0))
return -ENODEV;
- if (dev->state == USB_STATE_SUSPENDED)
+ if (dev->bus->controller->power.power_state.event != PM_EVENT_ON
+ || dev->state == USB_STATE_SUSPENDED)
return -EHOSTUNREACH;
if (!(op = dev->bus->op) || !op->submit_urb)
return -ENODEV;
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
index 7d131509e419..0eefff7bcb3c 100644
--- a/drivers/usb/core/usb.c
+++ b/drivers/usb/core/usb.c
@@ -107,10 +107,19 @@ static int usb_probe_interface(struct device *dev)
id = usb_match_id (intf, driver->id_table);
if (id) {
dev_dbg (dev, "%s - got id\n", __FUNCTION__);
+
+ /* Interface "power state" doesn't correspond to any hardware
+ * state whatsoever. We use it to record when it's bound to
+ * a driver that may start I/0: it's not frozen/quiesced.
+ */
+ mark_active(intf);
intf->condition = USB_INTERFACE_BINDING;
error = driver->probe (intf, id);
- intf->condition = error ? USB_INTERFACE_UNBOUND :
- USB_INTERFACE_BOUND;
+ if (error) {
+ mark_quiesced(intf);
+ intf->condition = USB_INTERFACE_UNBOUND;
+ } else
+ intf->condition = USB_INTERFACE_BOUND;
}
return error;
@@ -136,6 +145,7 @@ static int usb_unbind_interface(struct device *dev)
0);
usb_set_intfdata(intf, NULL);
intf->condition = USB_INTERFACE_UNBOUND;
+ mark_quiesced(intf);
return 0;
}
@@ -299,6 +309,7 @@ int usb_driver_claim_interface(struct usb_driver *driver,
dev->driver = &driver->driver;
usb_set_intfdata(iface, priv);
iface->condition = USB_INTERFACE_BOUND;
+ mark_active(iface);
/* if interface was already added, bind now; else let
* the future device_add() bind it, bypassing probe()
@@ -345,6 +356,7 @@ void usb_driver_release_interface(struct usb_driver *driver,
dev->driver = NULL;
usb_set_intfdata(iface, NULL);
iface->condition = USB_INTERFACE_UNBOUND;
+ mark_quiesced(iface);
}
/**
@@ -557,6 +569,7 @@ static int usb_hotplug (struct device *dev, char **envp, int num_envp,
{
struct usb_interface *intf;
struct usb_device *usb_dev;
+ struct usb_host_interface *alt;
int i = 0;
int length = 0;
@@ -573,7 +586,8 @@ static int usb_hotplug (struct device *dev, char **envp, int num_envp,
intf = to_usb_interface(dev);
usb_dev = interface_to_usbdev (intf);
-
+ alt = intf->cur_altsetting;
+
if (usb_dev->devnum < 0) {
pr_debug ("usb %s: already deleted?\n", dev->bus_id);
return -ENODEV;
@@ -615,46 +629,27 @@ static int usb_hotplug (struct device *dev, char **envp, int num_envp,
usb_dev->descriptor.bDeviceProtocol))
return -ENOMEM;
- if (usb_dev->descriptor.bDeviceClass == 0) {
- struct usb_host_interface *alt = intf->cur_altsetting;
+ if (add_hotplug_env_var(envp, num_envp, &i,
+ buffer, buffer_size, &length,
+ "INTERFACE=%d/%d/%d",
+ alt->desc.bInterfaceClass,
+ alt->desc.bInterfaceSubClass,
+ alt->desc.bInterfaceProtocol))
+ return -ENOMEM;
- /* 2.4 only exposed interface zero. in 2.5, hotplug
- * agents are called for all interfaces, and can use
- * $DEVPATH/bInterfaceNumber if necessary.
- */
- if (add_hotplug_env_var(envp, num_envp, &i,
- buffer, buffer_size, &length,
- "INTERFACE=%d/%d/%d",
- alt->desc.bInterfaceClass,
- alt->desc.bInterfaceSubClass,
- alt->desc.bInterfaceProtocol))
- return -ENOMEM;
-
- if (add_hotplug_env_var(envp, num_envp, &i,
- buffer, buffer_size, &length,
- "MODALIAS=usb:v%04Xp%04Xd%04Xdc%02Xdsc%02Xdp%02Xic%02Xisc%02Xip%02X",
- le16_to_cpu(usb_dev->descriptor.idVendor),
- le16_to_cpu(usb_dev->descriptor.idProduct),
- le16_to_cpu(usb_dev->descriptor.bcdDevice),
- usb_dev->descriptor.bDeviceClass,
- usb_dev->descriptor.bDeviceSubClass,
- usb_dev->descriptor.bDeviceProtocol,
- alt->desc.bInterfaceClass,
- alt->desc.bInterfaceSubClass,
- alt->desc.bInterfaceProtocol))
- return -ENOMEM;
- } else {
- if (add_hotplug_env_var(envp, num_envp, &i,
- buffer, buffer_size, &length,
- "MODALIAS=usb:v%04Xp%04Xd%04Xdc%02Xdsc%02Xdp%02Xic*isc*ip*",
- le16_to_cpu(usb_dev->descriptor.idVendor),
- le16_to_cpu(usb_dev->descriptor.idProduct),
- le16_to_cpu(usb_dev->descriptor.bcdDevice),
- usb_dev->descriptor.bDeviceClass,
- usb_dev->descriptor.bDeviceSubClass,
- usb_dev->descriptor.bDeviceProtocol))
- return -ENOMEM;
- }
+ if (add_hotplug_env_var(envp, num_envp, &i,
+ buffer, buffer_size, &length,
+ "MODALIAS=usb:v%04Xp%04Xd%04Xdc%02Xdsc%02Xdp%02Xic%02Xisc%02Xip%02X",
+ le16_to_cpu(usb_dev->descriptor.idVendor),
+ le16_to_cpu(usb_dev->descriptor.idProduct),
+ le16_to_cpu(usb_dev->descriptor.bcdDevice),
+ usb_dev->descriptor.bDeviceClass,
+ usb_dev->descriptor.bDeviceSubClass,
+ usb_dev->descriptor.bDeviceProtocol,
+ alt->desc.bInterfaceClass,
+ alt->desc.bInterfaceSubClass,
+ alt->desc.bInterfaceProtocol))
+ return -ENOMEM;
envp[i] = NULL;
@@ -709,12 +704,10 @@ usb_alloc_dev(struct usb_device *parent, struct usb_bus *bus, unsigned port1)
{
struct usb_device *dev;
- dev = kmalloc(sizeof(*dev), GFP_KERNEL);
+ dev = kzalloc(sizeof(*dev), GFP_KERNEL);
if (!dev)
return NULL;
- memset(dev, 0, sizeof(*dev));
-
bus = usb_bus_get(bus);
if (!bus) {
kfree(dev);
@@ -1147,7 +1140,7 @@ int __usb_get_extra_descriptor(char *buffer, unsigned size,
void *usb_buffer_alloc (
struct usb_device *dev,
size_t size,
- unsigned mem_flags,
+ gfp_t mem_flags,
dma_addr_t *dma
)
{
@@ -1402,13 +1395,30 @@ void usb_buffer_unmap_sg (struct usb_device *dev, unsigned pipe,
usb_pipein (pipe) ? DMA_FROM_DEVICE : DMA_TO_DEVICE);
}
+static int verify_suspended(struct device *dev, void *unused)
+{
+ return (dev->power.power_state.event == PM_EVENT_ON) ? -EBUSY : 0;
+}
+
static int usb_generic_suspend(struct device *dev, pm_message_t message)
{
- struct usb_interface *intf;
- struct usb_driver *driver;
+ struct usb_interface *intf;
+ struct usb_driver *driver;
+ int status;
- if (dev->driver == &usb_generic_driver)
- return usb_suspend_device (to_usb_device(dev), message);
+ /* USB devices enter SUSPEND state through their hubs, but can be
+ * marked for FREEZE as soon as their children are already idled.
+ * But those semantics are useless, so we equate the two (sigh).
+ */
+ if (dev->driver == &usb_generic_driver) {
+ if (dev->power.power_state.event == message.event)
+ return 0;
+ /* we need to rule out bogus requests through sysfs */
+ status = device_for_each_child(dev, NULL, verify_suspended);
+ if (status)
+ return status;
+ return usb_suspend_device (to_usb_device(dev));
+ }
if ((dev->driver == NULL) ||
(dev->driver_data == &usb_generic_driver_data))
@@ -1417,23 +1427,44 @@ static int usb_generic_suspend(struct device *dev, pm_message_t message)
intf = to_usb_interface(dev);
driver = to_usb_driver(dev->driver);
- /* there's only one USB suspend state */
- if (intf->dev.power.power_state.event)
+ /* with no hardware, USB interfaces only use FREEZE and ON states */
+ if (!is_active(intf))
return 0;
- if (driver->suspend)
- return driver->suspend(intf, message);
- return 0;
+ if (driver->suspend && driver->resume) {
+ status = driver->suspend(intf, message);
+ if (status)
+ dev_err(dev, "%s error %d\n", "suspend", status);
+ else
+ mark_quiesced(intf);
+ } else {
+ // FIXME else if there's no suspend method, disconnect...
+ dev_warn(dev, "no %s?\n", "suspend");
+ status = 0;
+ }
+ return status;
}
static int usb_generic_resume(struct device *dev)
{
- struct usb_interface *intf;
- struct usb_driver *driver;
+ struct usb_interface *intf;
+ struct usb_driver *driver;
+ struct usb_device *udev;
+ int status;
- /* devices resume through their hub */
- if (dev->driver == &usb_generic_driver)
+ if (dev->power.power_state.event == PM_EVENT_ON)
+ return 0;
+
+ /* mark things as "on" immediately, no matter what errors crop up */
+ dev->power.power_state.event = PM_EVENT_ON;
+
+ /* devices resume through their hubs */
+ if (dev->driver == &usb_generic_driver) {
+ udev = to_usb_device(dev);
+ if (udev->state == USB_STATE_NOTATTACHED)
+ return 0;
return usb_resume_device (to_usb_device(dev));
+ }
if ((dev->driver == NULL) ||
(dev->driver_data == &usb_generic_driver_data))
@@ -1442,8 +1473,22 @@ static int usb_generic_resume(struct device *dev)
intf = to_usb_interface(dev);
driver = to_usb_driver(dev->driver);
- if (driver->resume)
- return driver->resume(intf);
+ udev = interface_to_usbdev(intf);
+ if (udev->state == USB_STATE_NOTATTACHED)
+ return 0;
+
+ /* if driver was suspended, it has a resume method;
+ * however, sysfs can wrongly mark things as suspended
+ * (on the "no suspend method" FIXME path above)
+ */
+ if (driver->resume) {
+ status = driver->resume(intf);
+ if (status) {
+ dev_err(dev, "%s error %d\n", "resume", status);
+ mark_quiesced(intf);
+ }
+ } else
+ dev_warn(dev, "no %s?\n", "resume");
return 0;
}
diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h
index e6504f3370ad..1c4a68499dce 100644
--- a/drivers/usb/core/usb.h
+++ b/drivers/usb/core/usb.h
@@ -13,12 +13,14 @@ extern void usb_disable_device (struct usb_device *dev, int skip_ep0);
extern int usb_get_device_descriptor(struct usb_device *dev,
unsigned int size);
+extern char *usb_cache_string(struct usb_device *udev, int index);
extern int usb_set_configuration(struct usb_device *dev, int configuration);
extern void usb_lock_all_devices(void);
extern void usb_unlock_all_devices(void);
extern void usb_kick_khubd(struct usb_device *dev);
+extern void usb_suspend_root_hub(struct usb_device *hdev);
extern void usb_resume_root_hub(struct usb_device *dev);
extern int usb_hub_init(void);
@@ -28,6 +30,28 @@ extern void usb_major_cleanup(void);
extern int usb_host_init(void);
extern void usb_host_cleanup(void);
+extern int usb_suspend_device(struct usb_device *dev);
+extern int usb_resume_device(struct usb_device *dev);
+
+
+/* Interfaces and their "power state" are owned by usbcore */
+
+static inline void mark_active(struct usb_interface *f)
+{
+ f->dev.power.power_state.event = PM_EVENT_ON;
+}
+
+static inline void mark_quiesced(struct usb_interface *f)
+{
+ f->dev.power.power_state.event = PM_EVENT_FREEZE;
+}
+
+static inline int is_active(struct usb_interface *f)
+{
+ return f->dev.power.power_state.event == PM_EVENT_ON;
+}
+
+
/* for labeling diagnostics */
extern const char *usbcore_name;
@@ -39,9 +63,6 @@ extern void usbfs_conn_disc_event(void);
extern int usbdev_init(void);
extern void usbdev_cleanup(void);
-extern void usbdev_add(struct usb_device *dev);
-extern void usbdev_remove(struct usb_device *dev);
-extern struct usb_device *usbdev_lookup_minor(int minor);
struct dev_state {
struct list_head list; /* state list */
@@ -58,3 +79,9 @@ struct dev_state {
unsigned long ifclaimed;
};
+/* internal notify stuff */
+extern void usb_notify_add_device(struct usb_device *udev);
+extern void usb_notify_remove_device(struct usb_device *udev);
+extern void usb_notify_add_bus(struct usb_bus *ubus);
+extern void usb_notify_remove_bus(struct usb_bus *ubus);
+
diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c
index 583db7c38cf1..904519085334 100644
--- a/drivers/usb/gadget/dummy_hcd.c
+++ b/drivers/usb/gadget/dummy_hcd.c
@@ -49,8 +49,7 @@
#include <linux/timer.h>
#include <linux/list.h>
#include <linux/interrupt.h>
-#include <linux/version.h>
-
+#include <linux/platform_device.h>
#include <linux/usb.h>
#include <linux/usb_gadget.h>
@@ -470,7 +469,7 @@ static int dummy_disable (struct usb_ep *_ep)
}
static struct usb_request *
-dummy_alloc_request (struct usb_ep *_ep, unsigned mem_flags)
+dummy_alloc_request (struct usb_ep *_ep, gfp_t mem_flags)
{
struct dummy_ep *ep;
struct dummy_request *req;
@@ -507,7 +506,7 @@ dummy_alloc_buffer (
struct usb_ep *_ep,
unsigned bytes,
dma_addr_t *dma,
- unsigned mem_flags
+ gfp_t mem_flags
) {
char *retval;
struct dummy_ep *ep;
@@ -541,7 +540,7 @@ fifo_complete (struct usb_ep *ep, struct usb_request *req)
static int
dummy_queue (struct usb_ep *_ep, struct usb_request *_req,
- unsigned mem_flags)
+ gfp_t mem_flags)
{
struct dummy_ep *ep;
struct dummy_request *req;
@@ -935,14 +934,10 @@ static int dummy_udc_remove (struct device *dev)
return 0;
}
-static int dummy_udc_suspend (struct device *dev, pm_message_t state,
- u32 level)
+static int dummy_udc_suspend (struct device *dev, pm_message_t state)
{
struct dummy *dum = dev_get_drvdata(dev);
- if (level != SUSPEND_DISABLE)
- return 0;
-
dev_dbg (dev, "%s\n", __FUNCTION__);
spin_lock_irq (&dum->lock);
dum->udc_suspended = 1;
@@ -954,13 +949,10 @@ static int dummy_udc_suspend (struct device *dev, pm_message_t state,
return 0;
}
-static int dummy_udc_resume (struct device *dev, u32 level)
+static int dummy_udc_resume (struct device *dev)
{
struct dummy *dum = dev_get_drvdata(dev);
- if (level != RESUME_ENABLE)
- return 0;
-
dev_dbg (dev, "%s\n", __FUNCTION__);
spin_lock_irq (&dum->lock);
dum->udc_suspended = 0;
@@ -974,6 +966,7 @@ static int dummy_udc_resume (struct device *dev, u32 level)
static struct device_driver dummy_udc_driver = {
.name = (char *) gadget_name,
+ .owner = THIS_MODULE,
.bus = &platform_bus_type,
.probe = dummy_udc_probe,
.remove = dummy_udc_remove,
@@ -999,7 +992,7 @@ static int dummy_urb_enqueue (
struct usb_hcd *hcd,
struct usb_host_endpoint *ep,
struct urb *urb,
- unsigned mem_flags
+ gfp_t mem_flags
) {
struct dummy *dum;
struct urbp *urbp;
@@ -1758,7 +1751,7 @@ static int dummy_hub_control (
return retval;
}
-static int dummy_hub_suspend (struct usb_hcd *hcd)
+static int dummy_bus_suspend (struct usb_hcd *hcd)
{
struct dummy *dum = hcd_to_dummy (hcd);
@@ -1769,7 +1762,7 @@ static int dummy_hub_suspend (struct usb_hcd *hcd)
return 0;
}
-static int dummy_hub_resume (struct usb_hcd *hcd)
+static int dummy_bus_resume (struct usb_hcd *hcd)
{
struct dummy *dum = hcd_to_dummy (hcd);
@@ -1901,8 +1894,8 @@ static const struct hc_driver dummy_hcd = {
.hub_status_data = dummy_hub_status,
.hub_control = dummy_hub_control,
- .hub_suspend = dummy_hub_suspend,
- .hub_resume = dummy_hub_resume,
+ .bus_suspend = dummy_bus_suspend,
+ .bus_resume = dummy_bus_resume,
};
static int dummy_hcd_probe (struct device *dev)
@@ -1936,52 +1929,32 @@ static int dummy_hcd_remove (struct device *dev)
return 0;
}
-static int dummy_hcd_suspend (struct device *dev, pm_message_t state,
- u32 level)
+static int dummy_hcd_suspend (struct device *dev, pm_message_t state)
{
struct usb_hcd *hcd;
- if (level != SUSPEND_DISABLE)
- return 0;
-
dev_dbg (dev, "%s\n", __FUNCTION__);
hcd = dev_get_drvdata (dev);
-#ifndef CONFIG_USB_SUSPEND
- /* Otherwise this would never happen */
- usb_lock_device (hcd->self.root_hub);
- dummy_hub_suspend (hcd);
- usb_unlock_device (hcd->self.root_hub);
-#endif
-
hcd->state = HC_STATE_SUSPENDED;
return 0;
}
-static int dummy_hcd_resume (struct device *dev, u32 level)
+static int dummy_hcd_resume (struct device *dev)
{
struct usb_hcd *hcd;
- if (level != RESUME_ENABLE)
- return 0;
-
dev_dbg (dev, "%s\n", __FUNCTION__);
hcd = dev_get_drvdata (dev);
hcd->state = HC_STATE_RUNNING;
-#ifndef CONFIG_USB_SUSPEND
- /* Otherwise this would never happen */
- usb_lock_device (hcd->self.root_hub);
- dummy_hub_resume (hcd);
- usb_unlock_device (hcd->self.root_hub);
-#endif
-
usb_hcd_poll_rh_status (hcd);
return 0;
}
static struct device_driver dummy_hcd_driver = {
.name = (char *) driver_name,
+ .owner = THIS_MODULE,
.bus = &platform_bus_type,
.probe = dummy_hcd_probe,
.remove = dummy_hcd_remove,
diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c
index 49459e33e952..8f402f85e1ca 100644
--- a/drivers/usb/gadget/ether.c
+++ b/drivers/usb/gadget/ether.c
@@ -945,11 +945,11 @@ config_buf (enum usb_device_speed speed,
/*-------------------------------------------------------------------------*/
-static void eth_start (struct eth_dev *dev, unsigned gfp_flags);
-static int alloc_requests (struct eth_dev *dev, unsigned n, unsigned gfp_flags);
+static void eth_start (struct eth_dev *dev, gfp_t gfp_flags);
+static int alloc_requests (struct eth_dev *dev, unsigned n, gfp_t gfp_flags);
static int
-set_ether_config (struct eth_dev *dev, unsigned gfp_flags)
+set_ether_config (struct eth_dev *dev, gfp_t gfp_flags)
{
int result = 0;
struct usb_gadget *gadget = dev->gadget;
@@ -1081,7 +1081,7 @@ static void eth_reset_config (struct eth_dev *dev)
* that returns config descriptors, and altsetting code.
*/
static int
-eth_set_config (struct eth_dev *dev, unsigned number, unsigned gfp_flags)
+eth_set_config (struct eth_dev *dev, unsigned number, gfp_t gfp_flags)
{
int result = 0;
struct usb_gadget *gadget = dev->gadget;
@@ -1598,7 +1598,7 @@ static void defer_kevent (struct eth_dev *dev, int flag)
static void rx_complete (struct usb_ep *ep, struct usb_request *req);
static int
-rx_submit (struct eth_dev *dev, struct usb_request *req, unsigned gfp_flags)
+rx_submit (struct eth_dev *dev, struct usb_request *req, gfp_t gfp_flags)
{
struct sk_buff *skb;
int retval = -ENOMEM;
@@ -1724,7 +1724,7 @@ clean:
}
static int prealloc (struct list_head *list, struct usb_ep *ep,
- unsigned n, unsigned gfp_flags)
+ unsigned n, gfp_t gfp_flags)
{
unsigned i;
struct usb_request *req;
@@ -1763,7 +1763,7 @@ extra:
return 0;
}
-static int alloc_requests (struct eth_dev *dev, unsigned n, unsigned gfp_flags)
+static int alloc_requests (struct eth_dev *dev, unsigned n, gfp_t gfp_flags)
{
int status;
@@ -1779,7 +1779,7 @@ fail:
return status;
}
-static void rx_fill (struct eth_dev *dev, unsigned gfp_flags)
+static void rx_fill (struct eth_dev *dev, gfp_t gfp_flags)
{
struct usb_request *req;
unsigned long flags;
@@ -1962,7 +1962,7 @@ drop:
* normally just one notification will be queued.
*/
-static struct usb_request *eth_req_alloc (struct usb_ep *, unsigned, unsigned);
+static struct usb_request *eth_req_alloc (struct usb_ep *, unsigned, gfp_t);
static void eth_req_free (struct usb_ep *ep, struct usb_request *req);
static void
@@ -2024,7 +2024,7 @@ static int rndis_control_ack (struct net_device *net)
#endif /* RNDIS */
-static void eth_start (struct eth_dev *dev, unsigned gfp_flags)
+static void eth_start (struct eth_dev *dev, gfp_t gfp_flags)
{
DEBUG (dev, "%s\n", __FUNCTION__);
@@ -2092,7 +2092,7 @@ static int eth_stop (struct net_device *net)
/*-------------------------------------------------------------------------*/
static struct usb_request *
-eth_req_alloc (struct usb_ep *ep, unsigned size, unsigned gfp_flags)
+eth_req_alloc (struct usb_ep *ep, unsigned size, gfp_t gfp_flags)
{
struct usb_request *req;
@@ -2533,6 +2533,7 @@ static struct usb_gadget_driver eth_driver = {
.driver = {
.name = (char *) shortname,
+ .owner = THIS_MODULE,
// .shutdown = ...
// .suspend = ...
// .resume = ...
diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c
index a41d9d4baee3..ea09aaa3cab6 100644
--- a/drivers/usb/gadget/file_storage.c
+++ b/drivers/usb/gadget/file_storage.c
@@ -224,6 +224,7 @@
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/kernel.h>
+#include <linux/kthread.h>
#include <linux/limits.h>
#include <linux/list.h>
#include <linux/module.h>
@@ -669,7 +670,6 @@ struct fsg_dev {
wait_queue_head_t thread_wqh;
int thread_wakeup_needed;
struct completion thread_notifier;
- int thread_pid;
struct task_struct *thread_task;
sigset_t thread_signal_mask;
@@ -1084,7 +1084,6 @@ static void wakeup_thread(struct fsg_dev *fsg)
static void raise_exception(struct fsg_dev *fsg, enum fsg_state new_state)
{
unsigned long flags;
- struct task_struct *thread_task;
/* Do nothing if a higher-priority exception is already in progress.
* If a lower-or-equal priority exception is in progress, preempt it
@@ -1093,9 +1092,9 @@ static void raise_exception(struct fsg_dev *fsg, enum fsg_state new_state)
if (fsg->state <= new_state) {
fsg->exception_req_tag = fsg->ep0_req_tag;
fsg->state = new_state;
- thread_task = fsg->thread_task;
- if (thread_task)
- send_sig_info(SIGUSR1, SEND_SIG_FORCED, thread_task);
+ if (fsg->thread_task)
+ send_sig_info(SIGUSR1, SEND_SIG_FORCED,
+ fsg->thread_task);
}
spin_unlock_irqrestore(&fsg->lock, flags);
}
@@ -3383,11 +3382,6 @@ static int fsg_main_thread(void *fsg_)
{
struct fsg_dev *fsg = (struct fsg_dev *) fsg_;
- fsg->thread_task = current;
-
- /* Release all our userspace resources */
- daemonize("file-storage-gadget");
-
/* Allow the thread to be killed by a signal, but set the signal mask
* to block everything but INT, TERM, KILL, and USR1. */
siginitsetinv(&fsg->thread_signal_mask, sigmask(SIGINT) |
@@ -3400,9 +3394,6 @@ static int fsg_main_thread(void *fsg_)
* that expects a __user pointer and it will work okay. */
set_fs(get_ds());
- /* Wait for the gadget registration to finish up */
- wait_for_completion(&fsg->thread_notifier);
-
/* The main loop */
while (fsg->state != FSG_STATE_TERMINATED) {
if (exception_in_progress(fsg) || signal_pending(current)) {
@@ -3440,8 +3431,9 @@ static int fsg_main_thread(void *fsg_)
spin_unlock_irq(&fsg->lock);
}
+ spin_lock_irq(&fsg->lock);
fsg->thread_task = NULL;
- flush_signals(current);
+ spin_unlock_irq(&fsg->lock);
/* In case we are exiting because of a signal, unregister the
* gadget driver and close the backing file. */
@@ -3831,12 +3823,11 @@ static int __init fsg_bind(struct usb_gadget *gadget)
/* Create the LUNs, open their backing files, and register the
* LUN devices in sysfs. */
- fsg->luns = kmalloc(i * sizeof(struct lun), GFP_KERNEL);
+ fsg->luns = kzalloc(i * sizeof(struct lun), GFP_KERNEL);
if (!fsg->luns) {
rc = -ENOMEM;
goto out;
}
- memset(fsg->luns, 0, i * sizeof(struct lun));
fsg->nluns = i;
for (i = 0; i < fsg->nluns; ++i) {
@@ -3959,10 +3950,12 @@ static int __init fsg_bind(struct usb_gadget *gadget)
sprintf(&serial[i], "%02X", c);
}
- if ((rc = kernel_thread(fsg_main_thread, fsg, (CLONE_VM | CLONE_FS |
- CLONE_FILES))) < 0)
+ fsg->thread_task = kthread_create(fsg_main_thread, fsg,
+ "file-storage-gadget");
+ if (IS_ERR(fsg->thread_task)) {
+ rc = PTR_ERR(fsg->thread_task);
goto out;
- fsg->thread_pid = rc;
+ }
INFO(fsg, DRIVER_DESC ", version: " DRIVER_VERSION "\n");
INFO(fsg, "Number of LUNs=%d\n", fsg->nluns);
@@ -3994,7 +3987,12 @@ static int __init fsg_bind(struct usb_gadget *gadget)
DBG(fsg, "removable=%d, stall=%d, buflen=%u\n",
mod_data.removable, mod_data.can_stall,
mod_data.buflen);
- DBG(fsg, "I/O thread pid: %d\n", fsg->thread_pid);
+ DBG(fsg, "I/O thread pid: %d\n", fsg->thread_task->pid);
+
+ set_bit(REGISTERED, &fsg->atomic_bitflags);
+
+ /* Tell the thread to start working */
+ wake_up_process(fsg->thread_task);
return 0;
autoconf_fail:
@@ -4046,6 +4044,7 @@ static struct usb_gadget_driver fsg_driver = {
.driver = {
.name = (char *) shortname,
+ .owner = THIS_MODULE,
// .release = ...
// .suspend = ...
// .resume = ...
@@ -4057,10 +4056,9 @@ static int __init fsg_alloc(void)
{
struct fsg_dev *fsg;
- fsg = kmalloc(sizeof *fsg, GFP_KERNEL);
+ fsg = kzalloc(sizeof *fsg, GFP_KERNEL);
if (!fsg)
return -ENOMEM;
- memset(fsg, 0, sizeof *fsg);
spin_lock_init(&fsg->lock);
init_rwsem(&fsg->filesem);
init_waitqueue_head(&fsg->thread_wqh);
@@ -4086,15 +4084,9 @@ static int __init fsg_init(void)
if ((rc = fsg_alloc()) != 0)
return rc;
fsg = the_fsg;
- if ((rc = usb_gadget_register_driver(&fsg_driver)) != 0) {
+ if ((rc = usb_gadget_register_driver(&fsg_driver)) != 0)
fsg_free(fsg);
- return rc;
- }
- set_bit(REGISTERED, &fsg->atomic_bitflags);
-
- /* Tell the thread to start working */
- complete(&fsg->thread_notifier);
- return 0;
+ return rc;
}
module_init(fsg_init);
diff --git a/drivers/usb/gadget/goku_udc.c b/drivers/usb/gadget/goku_udc.c
index eaab26f4ed37..b0f3cd63e3b9 100644
--- a/drivers/usb/gadget/goku_udc.c
+++ b/drivers/usb/gadget/goku_udc.c
@@ -269,7 +269,7 @@ static int goku_ep_disable(struct usb_ep *_ep)
/*-------------------------------------------------------------------------*/
static struct usb_request *
-goku_alloc_request(struct usb_ep *_ep, unsigned gfp_flags)
+goku_alloc_request(struct usb_ep *_ep, gfp_t gfp_flags)
{
struct goku_request *req;
@@ -327,7 +327,7 @@ goku_free_request(struct usb_ep *_ep, struct usb_request *_req)
*/
static void *
goku_alloc_buffer(struct usb_ep *_ep, unsigned bytes,
- dma_addr_t *dma, unsigned gfp_flags)
+ dma_addr_t *dma, gfp_t gfp_flags)
{
void *retval;
struct goku_ep *ep;
@@ -789,7 +789,7 @@ finished:
/*-------------------------------------------------------------------------*/
static int
-goku_queue(struct usb_ep *_ep, struct usb_request *_req, unsigned gfp_flags)
+goku_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags)
{
struct goku_request *req;
struct goku_ep *ep;
diff --git a/drivers/usb/gadget/lh7a40x_udc.c b/drivers/usb/gadget/lh7a40x_udc.c
index 4842577789c9..bc6269f10cbb 100644
--- a/drivers/usb/gadget/lh7a40x_udc.c
+++ b/drivers/usb/gadget/lh7a40x_udc.c
@@ -21,6 +21,8 @@
*
*/
+#include <linux/platform_device.h>
+
#include "lh7a40x_udc.h"
//#define DEBUG printk
@@ -71,13 +73,13 @@ static char *state_names[] = {
static int lh7a40x_ep_enable(struct usb_ep *ep,
const struct usb_endpoint_descriptor *);
static int lh7a40x_ep_disable(struct usb_ep *ep);
-static struct usb_request *lh7a40x_alloc_request(struct usb_ep *ep, int);
+static struct usb_request *lh7a40x_alloc_request(struct usb_ep *ep, gfp_t);
static void lh7a40x_free_request(struct usb_ep *ep, struct usb_request *);
static void *lh7a40x_alloc_buffer(struct usb_ep *ep, unsigned, dma_addr_t *,
- int);
+ gfp_t);
static void lh7a40x_free_buffer(struct usb_ep *ep, void *, dma_addr_t,
unsigned);
-static int lh7a40x_queue(struct usb_ep *ep, struct usb_request *, int);
+static int lh7a40x_queue(struct usb_ep *ep, struct usb_request *, gfp_t);
static int lh7a40x_dequeue(struct usb_ep *ep, struct usb_request *);
static int lh7a40x_set_halt(struct usb_ep *ep, int);
static int lh7a40x_fifo_status(struct usb_ep *ep);
@@ -1106,7 +1108,7 @@ static int lh7a40x_ep_disable(struct usb_ep *_ep)
}
static struct usb_request *lh7a40x_alloc_request(struct usb_ep *ep,
- unsigned gfp_flags)
+ gfp_t gfp_flags)
{
struct lh7a40x_request *req;
@@ -1134,7 +1136,7 @@ static void lh7a40x_free_request(struct usb_ep *ep, struct usb_request *_req)
}
static void *lh7a40x_alloc_buffer(struct usb_ep *ep, unsigned bytes,
- dma_addr_t * dma, unsigned gfp_flags)
+ dma_addr_t * dma, gfp_t gfp_flags)
{
char *retval;
@@ -1158,7 +1160,7 @@ static void lh7a40x_free_buffer(struct usb_ep *ep, void *buf, dma_addr_t dma,
* NOTE: Sets INDEX register
*/
static int lh7a40x_queue(struct usb_ep *_ep, struct usb_request *_req,
- unsigned gfp_flags)
+ gfp_t gfp_flags)
{
struct lh7a40x_request *req;
struct lh7a40x_ep *ep;
@@ -2140,6 +2142,7 @@ static int lh7a40x_udc_remove(struct device *_dev)
static struct device_driver udc_driver = {
.name = (char *)driver_name,
+ .owner = THIS_MODULE,
.bus = &platform_bus_type,
.probe = lh7a40x_udc_probe,
.remove = lh7a40x_udc_remove
diff --git a/drivers/usb/gadget/lh7a40x_udc.h b/drivers/usb/gadget/lh7a40x_udc.h
index 1bb455c045a9..9b2e6f7cbb8b 100644
--- a/drivers/usb/gadget/lh7a40x_udc.h
+++ b/drivers/usb/gadget/lh7a40x_udc.h
@@ -29,7 +29,6 @@
#include <linux/kernel.h>
#include <linux/ioport.h>
#include <linux/types.h>
-#include <linux/version.h>
#include <linux/errno.h>
#include <linux/delay.h>
#include <linux/sched.h>
diff --git a/drivers/usb/gadget/net2280.c b/drivers/usb/gadget/net2280.c
index 477fab2e74d1..c32e1f7476da 100644
--- a/drivers/usb/gadget/net2280.c
+++ b/drivers/usb/gadget/net2280.c
@@ -376,7 +376,7 @@ static int net2280_disable (struct usb_ep *_ep)
/*-------------------------------------------------------------------------*/
static struct usb_request *
-net2280_alloc_request (struct usb_ep *_ep, unsigned gfp_flags)
+net2280_alloc_request (struct usb_ep *_ep, gfp_t gfp_flags)
{
struct net2280_ep *ep;
struct net2280_request *req;
@@ -463,7 +463,7 @@ net2280_alloc_buffer (
struct usb_ep *_ep,
unsigned bytes,
dma_addr_t *dma,
- unsigned gfp_flags
+ gfp_t gfp_flags
)
{
void *retval;
@@ -897,7 +897,7 @@ done (struct net2280_ep *ep, struct net2280_request *req, int status)
/*-------------------------------------------------------------------------*/
static int
-net2280_queue (struct usb_ep *_ep, struct usb_request *_req, unsigned gfp_flags)
+net2280_queue (struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags)
{
struct net2280_request *req;
struct net2280_ep *ep;
diff --git a/drivers/usb/gadget/omap_udc.c b/drivers/usb/gadget/omap_udc.c
index ff5533e69560..387692a3611e 100644
--- a/drivers/usb/gadget/omap_udc.c
+++ b/drivers/usb/gadget/omap_udc.c
@@ -38,7 +38,7 @@
#include <linux/proc_fs.h>
#include <linux/mm.h>
#include <linux/moduleparam.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <linux/usb_ch9.h>
#include <linux/usb_gadget.h>
#include <linux/usb_otg.h>
@@ -269,7 +269,7 @@ static int omap_ep_disable(struct usb_ep *_ep)
/*-------------------------------------------------------------------------*/
static struct usb_request *
-omap_alloc_request(struct usb_ep *ep, unsigned gfp_flags)
+omap_alloc_request(struct usb_ep *ep, gfp_t gfp_flags)
{
struct omap_req *req;
@@ -298,7 +298,7 @@ omap_alloc_buffer(
struct usb_ep *_ep,
unsigned bytes,
dma_addr_t *dma,
- unsigned gfp_flags
+ gfp_t gfp_flags
)
{
void *retval;
@@ -691,7 +691,7 @@ static void next_out_dma(struct omap_ep *ep, struct omap_req *req)
}
static void
-finish_out_dma(struct omap_ep *ep, struct omap_req *req, int status)
+finish_out_dma(struct omap_ep *ep, struct omap_req *req, int status, int one)
{
u16 count;
@@ -699,6 +699,8 @@ finish_out_dma(struct omap_ep *ep, struct omap_req *req, int status)
ep->dma_counter = (u16) (req->req.dma + req->req.actual);
count = dma_dest_len(ep, req->req.dma + req->req.actual);
count += req->req.actual;
+ if (one)
+ count--;
if (count <= req->req.length)
req->req.actual = count;
@@ -747,7 +749,7 @@ static void dma_irq(struct omap_udc *udc, u16 irq_src)
if (!list_empty(&ep->queue)) {
req = container_of(ep->queue.next,
struct omap_req, queue);
- finish_out_dma(ep, req, 0);
+ finish_out_dma(ep, req, 0, dman_stat & UDC_DMA_RX_SB);
}
UDC_IRQ_SRC_REG = UDC_RXN_EOT;
@@ -925,7 +927,7 @@ static void dma_channel_release(struct omap_ep *ep)
while (UDC_RXDMA_CFG_REG & mask)
udelay(10);
if (req)
- finish_out_dma(ep, req, -ECONNRESET);
+ finish_out_dma(ep, req, -ECONNRESET, 0);
}
omap_free_dma(ep->lch);
ep->dma_channel = 0;
@@ -937,7 +939,7 @@ static void dma_channel_release(struct omap_ep *ep)
/*-------------------------------------------------------------------------*/
static int
-omap_ep_queue(struct usb_ep *_ep, struct usb_request *_req, unsigned gfp_flags)
+omap_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags)
{
struct omap_ep *ep = container_of(_ep, struct omap_ep, ep);
struct omap_req *req = container_of(_req, struct omap_req, req);
@@ -1786,8 +1788,12 @@ static void devstate_irq(struct omap_udc *udc, u16 irq_src)
udc->driver->suspend(&udc->gadget);
spin_lock(&udc->lock);
}
+ if (udc->transceiver)
+ otg_set_suspend(udc->transceiver, 1);
} else {
VDBG("resume\n");
+ if (udc->transceiver)
+ otg_set_suspend(udc->transceiver, 0);
if (udc->gadget.speed == USB_SPEED_FULL
&& udc->driver->resume) {
spin_unlock(&udc->lock);
@@ -2909,12 +2915,10 @@ static int __exit omap_udc_remove(struct device *dev)
* may involve talking to an external transceiver (e.g. isp1301).
*/
-static int omap_udc_suspend(struct device *dev, pm_message_t message, u32 level)
+static int omap_udc_suspend(struct device *dev, pm_message_t message)
{
u32 devstat;
- if (level != SUSPEND_POWER_DOWN)
- return 0;
devstat = UDC_DEVSTAT_REG;
/* we're requesting 48 MHz clock if the pullup is enabled
@@ -2931,11 +2935,8 @@ static int omap_udc_suspend(struct device *dev, pm_message_t message, u32 level)
return 0;
}
-static int omap_udc_resume(struct device *dev, u32 level)
+static int omap_udc_resume(struct device *dev)
{
- if (level != RESUME_POWER_ON)
- return 0;
-
DBG("resume + wakeup/SRP\n");
omap_pullup(&udc->gadget, 1);
@@ -2948,6 +2949,7 @@ static int omap_udc_resume(struct device *dev, u32 level)
static struct device_driver udc_driver = {
.name = (char *) driver_name,
+ .owner = THIS_MODULE,
.bus = &platform_bus_type,
.probe = omap_udc_probe,
.remove = __exit_p(omap_udc_remove),
diff --git a/drivers/usb/gadget/pxa2xx_udc.c b/drivers/usb/gadget/pxa2xx_udc.c
index 73f8c9404156..510d28a924db 100644
--- a/drivers/usb/gadget/pxa2xx_udc.c
+++ b/drivers/usb/gadget/pxa2xx_udc.c
@@ -32,7 +32,6 @@
#include <linux/kernel.h>
#include <linux/ioport.h>
#include <linux/types.h>
-#include <linux/version.h>
#include <linux/errno.h>
#include <linux/delay.h>
#include <linux/sched.h>
@@ -43,7 +42,7 @@
#include <linux/interrupt.h>
#include <linux/proc_fs.h>
#include <linux/mm.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
#include <asm/byteorder.h>
@@ -332,7 +331,7 @@ static int pxa2xx_ep_disable (struct usb_ep *_ep)
* pxa2xx_ep_alloc_request - allocate a request data structure
*/
static struct usb_request *
-pxa2xx_ep_alloc_request (struct usb_ep *_ep, unsigned gfp_flags)
+pxa2xx_ep_alloc_request (struct usb_ep *_ep, gfp_t gfp_flags)
{
struct pxa2xx_request *req;
@@ -367,7 +366,7 @@ pxa2xx_ep_free_request (struct usb_ep *_ep, struct usb_request *_req)
*/
static void *
pxa2xx_ep_alloc_buffer(struct usb_ep *_ep, unsigned bytes,
- dma_addr_t *dma, unsigned gfp_flags)
+ dma_addr_t *dma, gfp_t gfp_flags)
{
char *retval;
@@ -422,7 +421,7 @@ static inline void ep0_idle (struct pxa2xx_udc *dev)
}
static int
-write_packet(volatile unsigned long *uddr, struct pxa2xx_request *req, unsigned max)
+write_packet(volatile u32 *uddr, struct pxa2xx_request *req, unsigned max)
{
u8 *buf;
unsigned length, count;
@@ -874,7 +873,7 @@ done:
/*-------------------------------------------------------------------------*/
static int
-pxa2xx_ep_queue(struct usb_ep *_ep, struct usb_request *_req, unsigned gfp_flags)
+pxa2xx_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags)
{
struct pxa2xx_request *req;
struct pxa2xx_ep *ep;
@@ -2602,24 +2601,23 @@ static int __exit pxa2xx_udc_remove(struct device *_dev)
* VBUS IRQs should probably be ignored so that the PXA device just acts
* "dead" to USB hosts until system resume.
*/
-static int pxa2xx_udc_suspend(struct device *dev, pm_message_t state, u32 level)
+static int pxa2xx_udc_suspend(struct device *dev, pm_message_t state)
{
struct pxa2xx_udc *udc = dev_get_drvdata(dev);
- if (level == SUSPEND_POWER_DOWN) {
- if (!udc->mach->udc_command)
- WARN("USB host won't detect disconnect!\n");
- pullup(udc, 0);
- }
+ if (!udc->mach->udc_command)
+ WARN("USB host won't detect disconnect!\n");
+ pullup(udc, 0);
+
return 0;
}
-static int pxa2xx_udc_resume(struct device *dev, u32 level)
+static int pxa2xx_udc_resume(struct device *dev)
{
struct pxa2xx_udc *udc = dev_get_drvdata(dev);
- if (level == RESUME_POWER_ON)
- pullup(udc, 1);
+ pullup(udc, 1);
+
return 0;
}
@@ -2632,6 +2630,7 @@ static int pxa2xx_udc_resume(struct device *dev, u32 level)
static struct device_driver udc_driver = {
.name = "pxa2xx-udc",
+ .owner = THIS_MODULE,
.bus = &platform_bus_type,
.probe = pxa2xx_udc_probe,
.shutdown = pxa2xx_udc_shutdown,
diff --git a/drivers/usb/gadget/pxa2xx_udc.h b/drivers/usb/gadget/pxa2xx_udc.h
index a58f3e6e71f1..19a883f7d1b8 100644
--- a/drivers/usb/gadget/pxa2xx_udc.h
+++ b/drivers/usb/gadget/pxa2xx_udc.h
@@ -69,11 +69,11 @@ struct pxa2xx_ep {
* UDDR = UDC Endpoint Data Register (the fifo)
* DRCM = DMA Request Channel Map
*/
- volatile unsigned long *reg_udccs;
- volatile unsigned long *reg_ubcr;
- volatile unsigned long *reg_uddr;
+ volatile u32 *reg_udccs;
+ volatile u32 *reg_ubcr;
+ volatile u32 *reg_uddr;
#ifdef USE_DMA
- volatile unsigned long *reg_drcmr;
+ volatile u32 *reg_drcmr;
#define drcmr(n) .reg_drcmr = & DRCMR ## n ,
#else
#define drcmr(n)
diff --git a/drivers/usb/gadget/rndis.c b/drivers/usb/gadget/rndis.c
index 06b6eba925b5..9689efeb364c 100644
--- a/drivers/usb/gadget/rndis.c
+++ b/drivers/usb/gadget/rndis.c
@@ -28,7 +28,6 @@
#include <linux/moduleparam.h>
#include <linux/kernel.h>
#include <linux/errno.h>
-#include <linux/version.h>
#include <linux/init.h>
#include <linux/list.h>
#include <linux/proc_fs.h>
diff --git a/drivers/usb/gadget/serial.c b/drivers/usb/gadget/serial.c
index c925d9222f53..b35ac6d334f8 100644
--- a/drivers/usb/gadget/serial.c
+++ b/drivers/usb/gadget/serial.c
@@ -300,18 +300,18 @@ static int gs_build_config_buf(u8 *buf, enum usb_device_speed speed,
u8 type, unsigned int index, int is_otg);
static struct usb_request *gs_alloc_req(struct usb_ep *ep, unsigned int len,
- unsigned kmalloc_flags);
+ gfp_t kmalloc_flags);
static void gs_free_req(struct usb_ep *ep, struct usb_request *req);
static struct gs_req_entry *gs_alloc_req_entry(struct usb_ep *ep, unsigned len,
- unsigned kmalloc_flags);
+ gfp_t kmalloc_flags);
static void gs_free_req_entry(struct usb_ep *ep, struct gs_req_entry *req);
-static int gs_alloc_ports(struct gs_dev *dev, unsigned kmalloc_flags);
+static int gs_alloc_ports(struct gs_dev *dev, gfp_t kmalloc_flags);
static void gs_free_ports(struct gs_dev *dev);
/* circular buffer */
-static struct gs_buf *gs_buf_alloc(unsigned int size, unsigned kmalloc_flags);
+static struct gs_buf *gs_buf_alloc(unsigned int size, gfp_t kmalloc_flags);
static void gs_buf_free(struct gs_buf *gb);
static void gs_buf_clear(struct gs_buf *gb);
static unsigned int gs_buf_data_avail(struct gs_buf *gb);
@@ -2091,7 +2091,7 @@ static int gs_build_config_buf(u8 *buf, enum usb_device_speed speed,
* usb_request or NULL if there is an error.
*/
static struct usb_request *
-gs_alloc_req(struct usb_ep *ep, unsigned int len, unsigned kmalloc_flags)
+gs_alloc_req(struct usb_ep *ep, unsigned int len, gfp_t kmalloc_flags)
{
struct usb_request *req;
@@ -2132,7 +2132,7 @@ static void gs_free_req(struct usb_ep *ep, struct usb_request *req)
* endpoint, buffer len, and kmalloc flags.
*/
static struct gs_req_entry *
-gs_alloc_req_entry(struct usb_ep *ep, unsigned len, unsigned kmalloc_flags)
+gs_alloc_req_entry(struct usb_ep *ep, unsigned len, gfp_t kmalloc_flags)
{
struct gs_req_entry *req;
@@ -2173,7 +2173,7 @@ static void gs_free_req_entry(struct usb_ep *ep, struct gs_req_entry *req)
*
* The device lock is normally held when calling this function.
*/
-static int gs_alloc_ports(struct gs_dev *dev, unsigned kmalloc_flags)
+static int gs_alloc_ports(struct gs_dev *dev, gfp_t kmalloc_flags)
{
int i;
struct gs_port *port;
@@ -2255,7 +2255,7 @@ static void gs_free_ports(struct gs_dev *dev)
*
* Allocate a circular buffer and all associated memory.
*/
-static struct gs_buf *gs_buf_alloc(unsigned int size, unsigned kmalloc_flags)
+static struct gs_buf *gs_buf_alloc(unsigned int size, gfp_t kmalloc_flags)
{
struct gs_buf *gb;
diff --git a/drivers/usb/gadget/zero.c b/drivers/usb/gadget/zero.c
index 6890e773b2a2..6c58636e914b 100644
--- a/drivers/usb/gadget/zero.c
+++ b/drivers/usb/gadget/zero.c
@@ -612,7 +612,7 @@ static void source_sink_complete (struct usb_ep *ep, struct usb_request *req)
}
static struct usb_request *
-source_sink_start_ep (struct usb_ep *ep, unsigned gfp_flags)
+source_sink_start_ep (struct usb_ep *ep, gfp_t gfp_flags)
{
struct usb_request *req;
int status;
@@ -640,7 +640,7 @@ source_sink_start_ep (struct usb_ep *ep, unsigned gfp_flags)
}
static int
-set_source_sink_config (struct zero_dev *dev, unsigned gfp_flags)
+set_source_sink_config (struct zero_dev *dev, gfp_t gfp_flags)
{
int result = 0;
struct usb_ep *ep;
@@ -744,7 +744,7 @@ static void loopback_complete (struct usb_ep *ep, struct usb_request *req)
}
static int
-set_loopback_config (struct zero_dev *dev, unsigned gfp_flags)
+set_loopback_config (struct zero_dev *dev, gfp_t gfp_flags)
{
int result = 0;
struct usb_ep *ep;
@@ -845,7 +845,7 @@ static void zero_reset_config (struct zero_dev *dev)
* by limiting configuration choices (like the pxa2xx).
*/
static int
-zero_set_config (struct zero_dev *dev, unsigned number, unsigned gfp_flags)
+zero_set_config (struct zero_dev *dev, unsigned number, gfp_t gfp_flags)
{
int result = 0;
struct usb_gadget *gadget = dev->gadget;
@@ -1302,6 +1302,7 @@ static struct usb_gadget_driver zero_driver = {
.driver = {
.name = (char *) shortname,
+ .owner = THIS_MODULE,
// .shutdown = ...
// .suspend = ...
// .resume = ...
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index 350d14fc1cc9..58321d3f314c 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -1,8 +1,9 @@
#
-# Makefile for USB Host Controller Driver
-# framework and drivers
+# Makefile for USB Host Controller Drivers
#
+obj-$(CONFIG_PCI) += pci-quirks.o
+
obj-$(CONFIG_USB_EHCI_HCD) += ehci-hcd.o
obj-$(CONFIG_USB_ISP116X_HCD) += isp116x-hcd.o
obj-$(CONFIG_USB_OHCI_HCD) += ohci-hcd.o
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index b948ffd94f45..af3c05eb86fc 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -182,6 +182,9 @@ static int ehci_halt (struct ehci_hcd *ehci)
{
u32 temp = readl (&ehci->regs->status);
+ /* disable any irqs left enabled by previous code */
+ writel (0, &ehci->regs->intr_enable);
+
if ((temp & STS_HALT) != 0)
return 0;
@@ -297,50 +300,17 @@ static void ehci_watchdog (unsigned long param)
spin_unlock_irqrestore (&ehci->lock, flags);
}
-#ifdef CONFIG_PCI
-
-/* EHCI 0.96 (and later) section 5.1 says how to kick BIOS/SMM/...
- * off the controller (maybe it can boot from highspeed USB disks).
+/* Reboot notifiers kick in for silicon on any bus (not just pci, etc).
+ * This forcibly disables dma and IRQs, helping kexec and other cases
+ * where the next system software may expect clean state.
*/
-static int bios_handoff (struct ehci_hcd *ehci, int where, u32 cap)
-{
- struct pci_dev *pdev = to_pci_dev(ehci_to_hcd(ehci)->self.controller);
-
- /* always say Linux will own the hardware */
- pci_write_config_byte(pdev, where + 3, 1);
-
- /* maybe wait a while for BIOS to respond */
- if (cap & (1 << 16)) {
- int msec = 5000;
-
- do {
- msleep(10);
- msec -= 10;
- pci_read_config_dword(pdev, where, &cap);
- } while ((cap & (1 << 16)) && msec);
- if (cap & (1 << 16)) {
- ehci_err(ehci, "BIOS handoff failed (%d, %08x)\n",
- where, cap);
- // some BIOS versions seem buggy...
- // return 1;
- ehci_warn (ehci, "continuing after BIOS bug...\n");
- /* disable all SMIs, and clear "BIOS owns" flag */
- pci_write_config_dword(pdev, where + 4, 0);
- pci_write_config_byte(pdev, where + 2, 0);
- } else
- ehci_dbg(ehci, "BIOS handoff succeeded\n");
- }
- return 0;
-}
-
-#endif
-
static int
ehci_reboot (struct notifier_block *self, unsigned long code, void *null)
{
struct ehci_hcd *ehci;
ehci = container_of (self, struct ehci_hcd, reboot_notifier);
+ (void) ehci_halt (ehci);
/* make BIOS/etc use companion controller during reboot */
writel (0, &ehci->regs->configured_flag);
@@ -363,156 +333,90 @@ static void ehci_port_power (struct ehci_hcd *ehci, int is_on)
msleep(20);
}
+/*-------------------------------------------------------------------------*/
+
+/*
+ * ehci_work is called from some interrupts, timers, and so on.
+ * it calls driver completion functions, after dropping ehci->lock.
+ */
+static void ehci_work (struct ehci_hcd *ehci, struct pt_regs *regs)
+{
+ timer_action_done (ehci, TIMER_IO_WATCHDOG);
+ if (ehci->reclaim_ready)
+ end_unlink_async (ehci, regs);
+
+ /* another CPU may drop ehci->lock during a schedule scan while
+ * it reports urb completions. this flag guards against bogus
+ * attempts at re-entrant schedule scanning.
+ */
+ if (ehci->scanning)
+ return;
+ ehci->scanning = 1;
+ scan_async (ehci, regs);
+ if (ehci->next_uframe != -1)
+ scan_periodic (ehci, regs);
+ ehci->scanning = 0;
-/* called by khubd or root hub init threads */
+ /* the IO watchdog guards against hardware or driver bugs that
+ * misplace IRQs, and should let us run completely without IRQs.
+ * such lossage has been observed on both VT6202 and VT8235.
+ */
+ if (HC_IS_RUNNING (ehci_to_hcd(ehci)->state) &&
+ (ehci->async->qh_next.ptr != NULL ||
+ ehci->periodic_sched != 0))
+ timer_action (ehci, TIMER_IO_WATCHDOG);
+}
-static int ehci_hc_reset (struct usb_hcd *hcd)
+static void ehci_stop (struct usb_hcd *hcd)
{
struct ehci_hcd *ehci = hcd_to_ehci (hcd);
- u32 temp;
- unsigned count = 256/4;
- spin_lock_init (&ehci->lock);
+ ehci_dbg (ehci, "stop\n");
- ehci->caps = hcd->regs;
- ehci->regs = hcd->regs + HC_LENGTH (readl (&ehci->caps->hc_capbase));
- dbg_hcs_params (ehci, "reset");
- dbg_hcc_params (ehci, "reset");
+ /* Turn off port power on all root hub ports. */
+ ehci_port_power (ehci, 0);
- /* cache this readonly data; minimize chip reads */
- ehci->hcs_params = readl (&ehci->caps->hcs_params);
+ /* no more interrupts ... */
+ del_timer_sync (&ehci->watchdog);
-#ifdef CONFIG_PCI
- if (hcd->self.controller->bus == &pci_bus_type) {
- struct pci_dev *pdev = to_pci_dev(hcd->self.controller);
+ spin_lock_irq(&ehci->lock);
+ if (HC_IS_RUNNING (hcd->state))
+ ehci_quiesce (ehci);
- switch (pdev->vendor) {
- case PCI_VENDOR_ID_TDI:
- if (pdev->device == PCI_DEVICE_ID_TDI_EHCI) {
- ehci->is_tdi_rh_tt = 1;
- tdi_reset (ehci);
- }
- break;
- case PCI_VENDOR_ID_AMD:
- /* AMD8111 EHCI doesn't work, according to AMD errata */
- if (pdev->device == 0x7463) {
- ehci_info (ehci, "ignoring AMD8111 (errata)\n");
- return -EIO;
- }
- break;
- case PCI_VENDOR_ID_NVIDIA:
- /* NVidia reports that certain chips don't handle
- * QH, ITD, or SITD addresses above 2GB. (But TD,
- * data buffer, and periodic schedule are normal.)
- */
- switch (pdev->device) {
- case 0x003c: /* MCP04 */
- case 0x005b: /* CK804 */
- case 0x00d8: /* CK8 */
- case 0x00e8: /* CK8S */
- if (pci_set_consistent_dma_mask(pdev,
- DMA_31BIT_MASK) < 0)
- ehci_warn (ehci, "can't enable NVidia "
- "workaround for >2GB RAM\n");
- break;
- }
- break;
- }
+ ehci_reset (ehci);
+ writel (0, &ehci->regs->intr_enable);
+ spin_unlock_irq(&ehci->lock);
- /* optional debug port, normally in the first BAR */
- temp = pci_find_capability (pdev, 0x0a);
- if (temp) {
- pci_read_config_dword(pdev, temp, &temp);
- temp >>= 16;
- if ((temp & (3 << 13)) == (1 << 13)) {
- temp &= 0x1fff;
- ehci->debug = hcd->regs + temp;
- temp = readl (&ehci->debug->control);
- ehci_info (ehci, "debug port %d%s\n",
- HCS_DEBUG_PORT(ehci->hcs_params),
- (temp & DBGP_ENABLED)
- ? " IN USE"
- : "");
- if (!(temp & DBGP_ENABLED))
- ehci->debug = NULL;
- }
- }
+ /* let companion controllers work when we aren't */
+ writel (0, &ehci->regs->configured_flag);
+ unregister_reboot_notifier (&ehci->reboot_notifier);
- temp = HCC_EXT_CAPS (readl (&ehci->caps->hcc_params));
- } else
- temp = 0;
-
- /* EHCI 0.96 and later may have "extended capabilities" */
- while (temp && count--) {
- u32 cap;
-
- pci_read_config_dword (to_pci_dev(hcd->self.controller),
- temp, &cap);
- ehci_dbg (ehci, "capability %04x at %02x\n", cap, temp);
- switch (cap & 0xff) {
- case 1: /* BIOS/SMM/... handoff */
- if (bios_handoff (ehci, temp, cap) != 0)
- return -EOPNOTSUPP;
- break;
- case 0: /* illegal reserved capability */
- ehci_warn (ehci, "illegal capability!\n");
- cap = 0;
- /* FALLTHROUGH */
- default: /* unknown */
- break;
- }
- temp = (cap >> 8) & 0xff;
- }
- if (!count) {
- ehci_err (ehci, "bogus capabilities ... PCI problems!\n");
- return -EIO;
- }
- if (ehci_is_TDI(ehci))
- ehci_reset (ehci);
-#endif
+ remove_debug_files (ehci);
- ehci_port_power (ehci, 0);
+ /* root hub is shut down separately (first, when possible) */
+ spin_lock_irq (&ehci->lock);
+ if (ehci->async)
+ ehci_work (ehci, NULL);
+ spin_unlock_irq (&ehci->lock);
+ ehci_mem_cleanup (ehci);
- /* at least the Genesys GL880S needs fixup here */
- temp = HCS_N_CC(ehci->hcs_params) * HCS_N_PCC(ehci->hcs_params);
- temp &= 0x0f;
- if (temp && HCS_N_PORTS(ehci->hcs_params) > temp) {
- ehci_dbg (ehci, "bogus port configuration: "
- "cc=%d x pcc=%d < ports=%d\n",
- HCS_N_CC(ehci->hcs_params),
- HCS_N_PCC(ehci->hcs_params),
- HCS_N_PORTS(ehci->hcs_params));
-
-#ifdef CONFIG_PCI
- if (hcd->self.controller->bus == &pci_bus_type) {
- struct pci_dev *pdev;
-
- pdev = to_pci_dev(hcd->self.controller);
- switch (pdev->vendor) {
- case 0x17a0: /* GENESYS */
- /* GL880S: should be PORTS=2 */
- temp |= (ehci->hcs_params & ~0xf);
- ehci->hcs_params = temp;
- break;
- case PCI_VENDOR_ID_NVIDIA:
- /* NF4: should be PCC=10 */
- break;
- }
- }
+#ifdef EHCI_STATS
+ ehci_dbg (ehci, "irq normal %ld err %ld reclaim %ld (lost %ld)\n",
+ ehci->stats.normal, ehci->stats.error, ehci->stats.reclaim,
+ ehci->stats.lost_iaa);
+ ehci_dbg (ehci, "complete %ld unlink %ld\n",
+ ehci->stats.complete, ehci->stats.unlink);
#endif
- }
- /* force HC to halt state */
- return ehci_halt (ehci);
+ dbg_status (ehci, "ehci_stop completed", readl (&ehci->regs->status));
}
-static int ehci_start (struct usb_hcd *hcd)
+static int ehci_run (struct usb_hcd *hcd)
{
struct ehci_hcd *ehci = hcd_to_ehci (hcd);
u32 temp;
int retval;
u32 hcc_params;
- u8 sbrn = 0;
int first;
/* skip some things on restart paths */
@@ -551,27 +455,6 @@ static int ehci_start (struct usb_hcd *hcd)
}
writel (ehci->periodic_dma, &ehci->regs->frame_list);
-#ifdef CONFIG_PCI
- if (hcd->self.controller->bus == &pci_bus_type) {
- struct pci_dev *pdev;
- u16 port_wake;
-
- pdev = to_pci_dev(hcd->self.controller);
-
- /* Serial Bus Release Number is at PCI 0x60 offset */
- pci_read_config_byte(pdev, 0x60, &sbrn);
-
- /* port wake capability, reported by boot firmware */
- pci_read_config_word(pdev, 0x62, &port_wake);
- hcd->can_wakeup = (port_wake & 1) != 0;
-
- /* help hc dma work well with cachelines */
- retval = pci_set_mwi(pdev);
- if (retval)
- ehci_dbg(ehci, "unable to enable MWI - not fatal.\n");
- }
-#endif
-
/*
* dedicate a qh for the async ring head, since we couldn't unlink
* a 'real' qh without stopping the async schedule [4.8]. use it
@@ -667,7 +550,7 @@ static int ehci_start (struct usb_hcd *hcd)
temp = HC_VERSION(readl (&ehci->caps->hc_capbase));
ehci_info (ehci,
"USB %x.%x %s, EHCI %x.%02x, driver %s\n",
- ((sbrn & 0xf0)>>4), (sbrn & 0x0f),
+ ((ehci->sbrn & 0xf0)>>4), (ehci->sbrn & 0x0f),
first ? "initialized" : "restarted",
temp >> 8, temp & 0xff, DRIVER_VERSION);
@@ -679,188 +562,6 @@ static int ehci_start (struct usb_hcd *hcd)
return 0;
}
-/* always called by thread; normally rmmod */
-
-static void ehci_stop (struct usb_hcd *hcd)
-{
- struct ehci_hcd *ehci = hcd_to_ehci (hcd);
-
- ehci_dbg (ehci, "stop\n");
-
- /* Turn off port power on all root hub ports. */
- ehci_port_power (ehci, 0);
-
- /* no more interrupts ... */
- del_timer_sync (&ehci->watchdog);
-
- spin_lock_irq(&ehci->lock);
- if (HC_IS_RUNNING (hcd->state))
- ehci_quiesce (ehci);
-
- ehci_reset (ehci);
- writel (0, &ehci->regs->intr_enable);
- spin_unlock_irq(&ehci->lock);
-
- /* let companion controllers work when we aren't */
- writel (0, &ehci->regs->configured_flag);
- unregister_reboot_notifier (&ehci->reboot_notifier);
-
- remove_debug_files (ehci);
-
- /* root hub is shut down separately (first, when possible) */
- spin_lock_irq (&ehci->lock);
- if (ehci->async)
- ehci_work (ehci, NULL);
- spin_unlock_irq (&ehci->lock);
- ehci_mem_cleanup (ehci);
-
-#ifdef EHCI_STATS
- ehci_dbg (ehci, "irq normal %ld err %ld reclaim %ld (lost %ld)\n",
- ehci->stats.normal, ehci->stats.error, ehci->stats.reclaim,
- ehci->stats.lost_iaa);
- ehci_dbg (ehci, "complete %ld unlink %ld\n",
- ehci->stats.complete, ehci->stats.unlink);
-#endif
-
- dbg_status (ehci, "ehci_stop completed", readl (&ehci->regs->status));
-}
-
-static int ehci_get_frame (struct usb_hcd *hcd)
-{
- struct ehci_hcd *ehci = hcd_to_ehci (hcd);
- return (readl (&ehci->regs->frame_index) >> 3) % ehci->periodic_size;
-}
-
-/*-------------------------------------------------------------------------*/
-
-#ifdef CONFIG_PM
-
-/* suspend/resume, section 4.3 */
-
-/* These routines rely on the bus (pci, platform, etc)
- * to handle powerdown and wakeup, and currently also on
- * transceivers that don't need any software attention to set up
- * the right sort of wakeup.
- */
-
-static int ehci_suspend (struct usb_hcd *hcd, pm_message_t message)
-{
- struct ehci_hcd *ehci = hcd_to_ehci (hcd);
-
- if (time_before (jiffies, ehci->next_statechange))
- msleep (100);
-
-#ifdef CONFIG_USB_SUSPEND
- (void) usb_suspend_device (hcd->self.root_hub, message);
-#else
- usb_lock_device (hcd->self.root_hub);
- (void) ehci_hub_suspend (hcd);
- usb_unlock_device (hcd->self.root_hub);
-#endif
-
- // save (PCI) FLADJ in case of Vaux power loss
- // ... we'd only use it to handle clock skew
-
- return 0;
-}
-
-static int ehci_resume (struct usb_hcd *hcd)
-{
- struct ehci_hcd *ehci = hcd_to_ehci (hcd);
- unsigned port;
- struct usb_device *root = hcd->self.root_hub;
- int retval = -EINVAL;
-
- // maybe restore (PCI) FLADJ
-
- if (time_before (jiffies, ehci->next_statechange))
- msleep (100);
-
- /* If any port is suspended (or owned by the companion),
- * we know we can/must resume the HC (and mustn't reset it).
- */
- for (port = HCS_N_PORTS (ehci->hcs_params); port > 0; ) {
- u32 status;
- port--;
- status = readl (&ehci->regs->port_status [port]);
- if (!(status & PORT_POWER))
- continue;
- if (status & (PORT_SUSPEND | PORT_OWNER)) {
- down (&hcd->self.root_hub->serialize);
- retval = ehci_hub_resume (hcd);
- up (&hcd->self.root_hub->serialize);
- break;
- }
- if (!root->children [port])
- continue;
- dbg_port (ehci, __FUNCTION__, port + 1, status);
- usb_set_device_state (root->children[port],
- USB_STATE_NOTATTACHED);
- }
-
- /* Else reset, to cope with power loss or flush-to-storage
- * style "resume" having activated BIOS during reboot.
- */
- if (port == 0) {
- (void) ehci_halt (ehci);
- (void) ehci_reset (ehci);
- (void) ehci_hc_reset (hcd);
-
- /* emptying the schedule aborts any urbs */
- spin_lock_irq (&ehci->lock);
- if (ehci->reclaim)
- ehci->reclaim_ready = 1;
- ehci_work (ehci, NULL);
- spin_unlock_irq (&ehci->lock);
-
- /* restart; khubd will disconnect devices */
- retval = ehci_start (hcd);
-
- /* here we "know" root ports should always stay powered;
- * but some controllers may lose all power.
- */
- ehci_port_power (ehci, 1);
- }
-
- return retval;
-}
-
-#endif
-
-/*-------------------------------------------------------------------------*/
-
-/*
- * ehci_work is called from some interrupts, timers, and so on.
- * it calls driver completion functions, after dropping ehci->lock.
- */
-static void ehci_work (struct ehci_hcd *ehci, struct pt_regs *regs)
-{
- timer_action_done (ehci, TIMER_IO_WATCHDOG);
- if (ehci->reclaim_ready)
- end_unlink_async (ehci, regs);
-
- /* another CPU may drop ehci->lock during a schedule scan while
- * it reports urb completions. this flag guards against bogus
- * attempts at re-entrant schedule scanning.
- */
- if (ehci->scanning)
- return;
- ehci->scanning = 1;
- scan_async (ehci, regs);
- if (ehci->next_uframe != -1)
- scan_periodic (ehci, regs);
- ehci->scanning = 0;
-
- /* the IO watchdog guards against hardware or driver bugs that
- * misplace IRQs, and should let us run completely without IRQs.
- * such lossage has been observed on both VT6202 and VT8235.
- */
- if (HC_IS_RUNNING (ehci_to_hcd(ehci)->state) &&
- (ehci->async->qh_next.ptr != NULL ||
- ehci->periodic_sched != 0))
- timer_action (ehci, TIMER_IO_WATCHDOG);
-}
-
/*-------------------------------------------------------------------------*/
static irqreturn_t ehci_irq (struct usb_hcd *hcd, struct pt_regs *regs)
@@ -983,7 +684,7 @@ static int ehci_urb_enqueue (
struct usb_hcd *hcd,
struct usb_host_endpoint *ep,
struct urb *urb,
- unsigned mem_flags
+ gfp_t mem_flags
) {
struct ehci_hcd *ehci = hcd_to_ehci (hcd);
struct list_head qtd_list;
@@ -1171,106 +872,24 @@ done:
return;
}
-/*-------------------------------------------------------------------------*/
-
-static const struct hc_driver ehci_driver = {
- .description = hcd_name,
- .product_desc = "EHCI Host Controller",
- .hcd_priv_size = sizeof(struct ehci_hcd),
-
- /*
- * generic hardware linkage
- */
- .irq = ehci_irq,
- .flags = HCD_MEMORY | HCD_USB2,
-
- /*
- * basic lifecycle operations
- */
- .reset = ehci_hc_reset,
- .start = ehci_start,
-#ifdef CONFIG_PM
- .suspend = ehci_suspend,
- .resume = ehci_resume,
-#endif
- .stop = ehci_stop,
-
- /*
- * managing i/o requests and associated device resources
- */
- .urb_enqueue = ehci_urb_enqueue,
- .urb_dequeue = ehci_urb_dequeue,
- .endpoint_disable = ehci_endpoint_disable,
-
- /*
- * scheduling support
- */
- .get_frame_number = ehci_get_frame,
-
- /*
- * root hub support
- */
- .hub_status_data = ehci_hub_status_data,
- .hub_control = ehci_hub_control,
- .hub_suspend = ehci_hub_suspend,
- .hub_resume = ehci_hub_resume,
-};
+static int ehci_get_frame (struct usb_hcd *hcd)
+{
+ struct ehci_hcd *ehci = hcd_to_ehci (hcd);
+ return (readl (&ehci->regs->frame_index) >> 3) % ehci->periodic_size;
+}
/*-------------------------------------------------------------------------*/
-/* EHCI 1.0 doesn't require PCI */
-
-#ifdef CONFIG_PCI
-
-/* PCI driver selection metadata; PCI hotplugging uses this */
-static const struct pci_device_id pci_ids [] = { {
- /* handle any USB 2.0 EHCI controller */
- PCI_DEVICE_CLASS(((PCI_CLASS_SERIAL_USB << 8) | 0x20), ~0),
- .driver_data = (unsigned long) &ehci_driver,
- },
- { /* end: all zeroes */ }
-};
-MODULE_DEVICE_TABLE (pci, pci_ids);
-
-/* pci driver glue; this is a "new style" PCI driver module */
-static struct pci_driver ehci_pci_driver = {
- .name = (char *) hcd_name,
- .id_table = pci_ids,
-
- .probe = usb_hcd_pci_probe,
- .remove = usb_hcd_pci_remove,
-
-#ifdef CONFIG_PM
- .suspend = usb_hcd_pci_suspend,
- .resume = usb_hcd_pci_resume,
-#endif
-};
-
-#endif /* PCI */
-
-
#define DRIVER_INFO DRIVER_VERSION " " DRIVER_DESC
MODULE_DESCRIPTION (DRIVER_INFO);
MODULE_AUTHOR (DRIVER_AUTHOR);
MODULE_LICENSE ("GPL");
-static int __init init (void)
-{
- if (usb_disabled())
- return -ENODEV;
-
- pr_debug ("%s: block sizes: qh %Zd qtd %Zd itd %Zd sitd %Zd\n",
- hcd_name,
- sizeof (struct ehci_qh), sizeof (struct ehci_qtd),
- sizeof (struct ehci_itd), sizeof (struct ehci_sitd));
-
- return pci_register_driver (&ehci_pci_driver);
-}
-module_init (init);
+#ifdef CONFIG_PCI
+#include "ehci-pci.c"
+#endif
-static void __exit cleanup (void)
-{
- pci_unregister_driver (&ehci_pci_driver);
-}
-module_exit (cleanup);
+#if !defined(CONFIG_PCI)
+#error "missing bus glue for ehci-hcd"
+#endif
diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c
index 18d3f2270316..88cb4ada686e 100644
--- a/drivers/usb/host/ehci-hub.c
+++ b/drivers/usb/host/ehci-hub.c
@@ -30,7 +30,7 @@
#ifdef CONFIG_PM
-static int ehci_hub_suspend (struct usb_hcd *hcd)
+static int ehci_bus_suspend (struct usb_hcd *hcd)
{
struct ehci_hcd *ehci = hcd_to_ehci (hcd);
int port;
@@ -83,7 +83,7 @@ static int ehci_hub_suspend (struct usb_hcd *hcd)
/* caller has locked the root hub, and should reset/reinit on error */
-static int ehci_hub_resume (struct usb_hcd *hcd)
+static int ehci_bus_resume (struct usb_hcd *hcd)
{
struct ehci_hcd *ehci = hcd_to_ehci (hcd);
u32 temp;
@@ -159,8 +159,8 @@ static int ehci_hub_resume (struct usb_hcd *hcd)
#else
-#define ehci_hub_suspend NULL
-#define ehci_hub_resume NULL
+#define ehci_bus_suspend NULL
+#define ehci_bus_resume NULL
#endif /* CONFIG_PM */
diff --git a/drivers/usb/host/ehci-mem.c b/drivers/usb/host/ehci-mem.c
index 5c38ad869485..91c2ab43cbcc 100644
--- a/drivers/usb/host/ehci-mem.c
+++ b/drivers/usb/host/ehci-mem.c
@@ -45,7 +45,7 @@ static inline void ehci_qtd_init (struct ehci_qtd *qtd, dma_addr_t dma)
INIT_LIST_HEAD (&qtd->qtd_list);
}
-static struct ehci_qtd *ehci_qtd_alloc (struct ehci_hcd *ehci, int flags)
+static struct ehci_qtd *ehci_qtd_alloc (struct ehci_hcd *ehci, gfp_t flags)
{
struct ehci_qtd *qtd;
dma_addr_t dma;
@@ -79,7 +79,7 @@ static void qh_destroy (struct kref *kref)
dma_pool_free (ehci->qh_pool, qh, qh->qh_dma);
}
-static struct ehci_qh *ehci_qh_alloc (struct ehci_hcd *ehci, int flags)
+static struct ehci_qh *ehci_qh_alloc (struct ehci_hcd *ehci, gfp_t flags)
{
struct ehci_qh *qh;
dma_addr_t dma;
@@ -161,7 +161,7 @@ static void ehci_mem_cleanup (struct ehci_hcd *ehci)
}
/* remember to add cleanup code (above) if you add anything here */
-static int ehci_mem_init (struct ehci_hcd *ehci, int flags)
+static int ehci_mem_init (struct ehci_hcd *ehci, gfp_t flags)
{
int i;
diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c
new file mode 100644
index 000000000000..dfd9bd0b1828
--- /dev/null
+++ b/drivers/usb/host/ehci-pci.c
@@ -0,0 +1,414 @@
+/*
+ * EHCI HCD (Host Controller Driver) PCI Bus Glue.
+ *
+ * Copyright (c) 2000-2004 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.
+ *
+ * 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 CONFIG_PCI
+#error "This file is PCI bus glue. CONFIG_PCI must be defined."
+#endif
+
+/*-------------------------------------------------------------------------*/
+
+/* EHCI 0.96 (and later) section 5.1 says how to kick BIOS/SMM/...
+ * off the controller (maybe it can boot from highspeed USB disks).
+ */
+static int bios_handoff (struct ehci_hcd *ehci, int where, u32 cap)
+{
+ struct pci_dev *pdev = to_pci_dev(ehci_to_hcd(ehci)->self.controller);
+
+ /* always say Linux will own the hardware */
+ pci_write_config_byte(pdev, where + 3, 1);
+
+ /* maybe wait a while for BIOS to respond */
+ if (cap & (1 << 16)) {
+ int msec = 5000;
+
+ do {
+ msleep(10);
+ msec -= 10;
+ pci_read_config_dword(pdev, where, &cap);
+ } while ((cap & (1 << 16)) && msec);
+ if (cap & (1 << 16)) {
+ ehci_err(ehci, "BIOS handoff failed (%d, %08x)\n",
+ where, cap);
+ // some BIOS versions seem buggy...
+ // return 1;
+ ehci_warn (ehci, "continuing after BIOS bug...\n");
+ /* disable all SMIs, and clear "BIOS owns" flag */
+ pci_write_config_dword(pdev, where + 4, 0);
+ pci_write_config_byte(pdev, where + 2, 0);
+ } else
+ ehci_dbg(ehci, "BIOS handoff succeeded\n");
+ }
+ return 0;
+}
+
+/* called by khubd or root hub init threads */
+static int ehci_pci_reset (struct usb_hcd *hcd)
+{
+ struct ehci_hcd *ehci = hcd_to_ehci (hcd);
+ u32 temp;
+ unsigned count = 256/4;
+
+ spin_lock_init (&ehci->lock);
+
+ ehci->caps = hcd->regs;
+ ehci->regs = hcd->regs + HC_LENGTH (readl (&ehci->caps->hc_capbase));
+ dbg_hcs_params (ehci, "reset");
+ dbg_hcc_params (ehci, "reset");
+
+ /* cache this readonly data; minimize chip reads */
+ ehci->hcs_params = readl (&ehci->caps->hcs_params);
+
+ if (hcd->self.controller->bus == &pci_bus_type) {
+ struct pci_dev *pdev = to_pci_dev(hcd->self.controller);
+
+ switch (pdev->vendor) {
+ case PCI_VENDOR_ID_TDI:
+ if (pdev->device == PCI_DEVICE_ID_TDI_EHCI) {
+ ehci->is_tdi_rh_tt = 1;
+ tdi_reset (ehci);
+ }
+ break;
+ case PCI_VENDOR_ID_AMD:
+ /* AMD8111 EHCI doesn't work, according to AMD errata */
+ if (pdev->device == 0x7463) {
+ ehci_info (ehci, "ignoring AMD8111 (errata)\n");
+ return -EIO;
+ }
+ break;
+ case PCI_VENDOR_ID_NVIDIA:
+ /* NVidia reports that certain chips don't handle
+ * QH, ITD, or SITD addresses above 2GB. (But TD,
+ * data buffer, and periodic schedule are normal.)
+ */
+ switch (pdev->device) {
+ case 0x003c: /* MCP04 */
+ case 0x005b: /* CK804 */
+ case 0x00d8: /* CK8 */
+ case 0x00e8: /* CK8S */
+ if (pci_set_consistent_dma_mask(pdev,
+ DMA_31BIT_MASK) < 0)
+ ehci_warn (ehci, "can't enable NVidia "
+ "workaround for >2GB RAM\n");
+ break;
+ }
+ break;
+ }
+
+ /* optional debug port, normally in the first BAR */
+ temp = pci_find_capability (pdev, 0x0a);
+ if (temp) {
+ pci_read_config_dword(pdev, temp, &temp);
+ temp >>= 16;
+ if ((temp & (3 << 13)) == (1 << 13)) {
+ temp &= 0x1fff;
+ ehci->debug = hcd->regs + temp;
+ temp = readl (&ehci->debug->control);
+ ehci_info (ehci, "debug port %d%s\n",
+ HCS_DEBUG_PORT(ehci->hcs_params),
+ (temp & DBGP_ENABLED)
+ ? " IN USE"
+ : "");
+ if (!(temp & DBGP_ENABLED))
+ ehci->debug = NULL;
+ }
+ }
+
+ temp = HCC_EXT_CAPS (readl (&ehci->caps->hcc_params));
+ } else
+ temp = 0;
+
+ /* EHCI 0.96 and later may have "extended capabilities" */
+ while (temp && count--) {
+ u32 cap;
+
+ pci_read_config_dword (to_pci_dev(hcd->self.controller),
+ temp, &cap);
+ ehci_dbg (ehci, "capability %04x at %02x\n", cap, temp);
+ switch (cap & 0xff) {
+ case 1: /* BIOS/SMM/... handoff */
+ if (bios_handoff (ehci, temp, cap) != 0)
+ return -EOPNOTSUPP;
+ break;
+ case 0: /* illegal reserved capability */
+ ehci_warn (ehci, "illegal capability!\n");
+ cap = 0;
+ /* FALLTHROUGH */
+ default: /* unknown */
+ break;
+ }
+ temp = (cap >> 8) & 0xff;
+ }
+ if (!count) {
+ ehci_err (ehci, "bogus capabilities ... PCI problems!\n");
+ return -EIO;
+ }
+ if (ehci_is_TDI(ehci))
+ ehci_reset (ehci);
+
+ ehci_port_power (ehci, 0);
+
+ /* at least the Genesys GL880S needs fixup here */
+ temp = HCS_N_CC(ehci->hcs_params) * HCS_N_PCC(ehci->hcs_params);
+ temp &= 0x0f;
+ if (temp && HCS_N_PORTS(ehci->hcs_params) > temp) {
+ ehci_dbg (ehci, "bogus port configuration: "
+ "cc=%d x pcc=%d < ports=%d\n",
+ HCS_N_CC(ehci->hcs_params),
+ HCS_N_PCC(ehci->hcs_params),
+ HCS_N_PORTS(ehci->hcs_params));
+
+ if (hcd->self.controller->bus == &pci_bus_type) {
+ struct pci_dev *pdev;
+
+ pdev = to_pci_dev(hcd->self.controller);
+ switch (pdev->vendor) {
+ case 0x17a0: /* GENESYS */
+ /* GL880S: should be PORTS=2 */
+ temp |= (ehci->hcs_params & ~0xf);
+ ehci->hcs_params = temp;
+ break;
+ case PCI_VENDOR_ID_NVIDIA:
+ /* NF4: should be PCC=10 */
+ break;
+ }
+ }
+ }
+
+ /* force HC to halt state */
+ return ehci_halt (ehci);
+}
+
+static int ehci_pci_start (struct usb_hcd *hcd)
+{
+ struct ehci_hcd *ehci = hcd_to_ehci (hcd);
+ int result = 0;
+
+ if (hcd->self.controller->bus == &pci_bus_type) {
+ struct pci_dev *pdev;
+ u16 port_wake;
+
+ pdev = to_pci_dev(hcd->self.controller);
+
+ /* Serial Bus Release Number is at PCI 0x60 offset */
+ pci_read_config_byte(pdev, 0x60, &ehci->sbrn);
+
+ /* port wake capability, reported by boot firmware */
+ pci_read_config_word(pdev, 0x62, &port_wake);
+ hcd->can_wakeup = (port_wake & 1) != 0;
+
+ /* help hc dma work well with cachelines */
+ result = pci_set_mwi(pdev);
+ if (result)
+ ehci_dbg(ehci, "unable to enable MWI - not fatal.\n");
+ }
+
+ return ehci_run (hcd);
+}
+
+/* always called by thread; normally rmmod */
+
+static void ehci_pci_stop (struct usb_hcd *hcd)
+{
+ ehci_stop (hcd);
+}
+
+/*-------------------------------------------------------------------------*/
+
+#ifdef CONFIG_PM
+
+/* suspend/resume, section 4.3 */
+
+/* These routines rely on the bus (pci, platform, etc)
+ * to handle powerdown and wakeup, and currently also on
+ * transceivers that don't need any software attention to set up
+ * the right sort of wakeup.
+ */
+
+static int ehci_pci_suspend (struct usb_hcd *hcd, pm_message_t message)
+{
+ struct ehci_hcd *ehci = hcd_to_ehci (hcd);
+
+ if (time_before (jiffies, ehci->next_statechange))
+ msleep (100);
+
+#ifdef CONFIG_USB_SUSPEND
+ (void) usb_suspend_device (hcd->self.root_hub);
+#else
+ usb_lock_device (hcd->self.root_hub);
+ (void) ehci_bus_suspend (hcd);
+ usb_unlock_device (hcd->self.root_hub);
+#endif
+
+ // save (PCI) FLADJ in case of Vaux power loss
+ // ... we'd only use it to handle clock skew
+
+ return 0;
+}
+
+static int ehci_pci_resume (struct usb_hcd *hcd)
+{
+ struct ehci_hcd *ehci = hcd_to_ehci (hcd);
+ unsigned port;
+ struct usb_device *root = hcd->self.root_hub;
+ int retval = -EINVAL;
+
+ // maybe restore (PCI) FLADJ
+
+ if (time_before (jiffies, ehci->next_statechange))
+ msleep (100);
+
+ /* If any port is suspended (or owned by the companion),
+ * we know we can/must resume the HC (and mustn't reset it).
+ */
+ for (port = HCS_N_PORTS (ehci->hcs_params); port > 0; ) {
+ u32 status;
+ port--;
+ status = readl (&ehci->regs->port_status [port]);
+ if (!(status & PORT_POWER))
+ continue;
+ if (status & (PORT_SUSPEND | PORT_OWNER)) {
+ down (&hcd->self.root_hub->serialize);
+ retval = ehci_bus_resume (hcd);
+ up (&hcd->self.root_hub->serialize);
+ break;
+ }
+ if (!root->children [port])
+ continue;
+ dbg_port (ehci, __FUNCTION__, port + 1, status);
+ usb_set_device_state (root->children[port],
+ USB_STATE_NOTATTACHED);
+ }
+
+ /* Else reset, to cope with power loss or flush-to-storage
+ * style "resume" having activated BIOS during reboot.
+ */
+ if (port == 0) {
+ (void) ehci_halt (ehci);
+ (void) ehci_reset (ehci);
+ (void) ehci_pci_reset (hcd);
+
+ /* emptying the schedule aborts any urbs */
+ spin_lock_irq (&ehci->lock);
+ if (ehci->reclaim)
+ ehci->reclaim_ready = 1;
+ ehci_work (ehci, NULL);
+ spin_unlock_irq (&ehci->lock);
+
+ /* restart; khubd will disconnect devices */
+ retval = ehci_run (hcd);
+
+ /* here we "know" root ports should always stay powered;
+ * but some controllers may lose all power.
+ */
+ ehci_port_power (ehci, 1);
+ }
+
+ return retval;
+}
+#endif
+
+static const struct hc_driver ehci_pci_hc_driver = {
+ .description = hcd_name,
+ .product_desc = "EHCI Host Controller",
+ .hcd_priv_size = sizeof(struct ehci_hcd),
+
+ /*
+ * generic hardware linkage
+ */
+ .irq = ehci_irq,
+ .flags = HCD_MEMORY | HCD_USB2,
+
+ /*
+ * basic lifecycle operations
+ */
+ .reset = ehci_pci_reset,
+ .start = ehci_pci_start,
+#ifdef CONFIG_PM
+ .suspend = ehci_pci_suspend,
+ .resume = ehci_pci_resume,
+#endif
+ .stop = ehci_pci_stop,
+
+ /*
+ * managing i/o requests and associated device resources
+ */
+ .urb_enqueue = ehci_urb_enqueue,
+ .urb_dequeue = ehci_urb_dequeue,
+ .endpoint_disable = ehci_endpoint_disable,
+
+ /*
+ * scheduling support
+ */
+ .get_frame_number = ehci_get_frame,
+
+ /*
+ * root hub support
+ */
+ .hub_status_data = ehci_hub_status_data,
+ .hub_control = ehci_hub_control,
+ .bus_suspend = ehci_bus_suspend,
+ .bus_resume = ehci_bus_resume,
+};
+
+/*-------------------------------------------------------------------------*/
+
+/* PCI driver selection metadata; PCI hotplugging uses this */
+static const struct pci_device_id pci_ids [] = { {
+ /* handle any USB 2.0 EHCI controller */
+ PCI_DEVICE_CLASS(((PCI_CLASS_SERIAL_USB << 8) | 0x20), ~0),
+ .driver_data = (unsigned long) &ehci_pci_hc_driver,
+ },
+ { /* end: all zeroes */ }
+};
+MODULE_DEVICE_TABLE (pci, pci_ids);
+
+/* pci driver glue; this is a "new style" PCI driver module */
+static struct pci_driver ehci_pci_driver = {
+ .name = (char *) hcd_name,
+ .id_table = pci_ids,
+
+ .probe = usb_hcd_pci_probe,
+ .remove = usb_hcd_pci_remove,
+
+#ifdef CONFIG_PM
+ .suspend = usb_hcd_pci_suspend,
+ .resume = usb_hcd_pci_resume,
+#endif
+};
+
+static int __init ehci_hcd_pci_init (void)
+{
+ if (usb_disabled())
+ return -ENODEV;
+
+ pr_debug ("%s: block sizes: qh %Zd qtd %Zd itd %Zd sitd %Zd\n",
+ hcd_name,
+ sizeof (struct ehci_qh), sizeof (struct ehci_qtd),
+ sizeof (struct ehci_itd), sizeof (struct ehci_sitd));
+
+ return pci_register_driver (&ehci_pci_driver);
+}
+module_init (ehci_hcd_pci_init);
+
+static void __exit ehci_hcd_pci_cleanup (void)
+{
+ pci_unregister_driver (&ehci_pci_driver);
+}
+module_exit (ehci_hcd_pci_cleanup);
diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c
index 940d38ca7d91..5bb872c3496d 100644
--- a/drivers/usb/host/ehci-q.c
+++ b/drivers/usb/host/ehci-q.c
@@ -477,7 +477,7 @@ qh_urb_transaction (
struct ehci_hcd *ehci,
struct urb *urb,
struct list_head *head,
- int flags
+ gfp_t flags
) {
struct ehci_qtd *qtd, *qtd_prev;
dma_addr_t buf;
@@ -629,7 +629,7 @@ static struct ehci_qh *
qh_make (
struct ehci_hcd *ehci,
struct urb *urb,
- int flags
+ gfp_t flags
) {
struct ehci_qh *qh = ehci_qh_alloc (ehci, flags);
u32 info1 = 0, info2 = 0;
@@ -906,7 +906,7 @@ submit_async (
struct usb_host_endpoint *ep,
struct urb *urb,
struct list_head *qtd_list,
- unsigned mem_flags
+ gfp_t mem_flags
) {
struct ehci_qtd *qtd;
int epnum;
diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c
index ccc7300baa6d..f0c8aa1ccd5d 100644
--- a/drivers/usb/host/ehci-sched.c
+++ b/drivers/usb/host/ehci-sched.c
@@ -589,7 +589,7 @@ static int intr_submit (
struct usb_host_endpoint *ep,
struct urb *urb,
struct list_head *qtd_list,
- unsigned mem_flags
+ gfp_t mem_flags
) {
unsigned epnum;
unsigned long flags;
@@ -634,7 +634,7 @@ done:
/* ehci_iso_stream ops work with both ITD and SITD */
static struct ehci_iso_stream *
-iso_stream_alloc (unsigned mem_flags)
+iso_stream_alloc (gfp_t mem_flags)
{
struct ehci_iso_stream *stream;
@@ -851,7 +851,7 @@ iso_stream_find (struct ehci_hcd *ehci, struct urb *urb)
/* ehci_iso_sched ops can be ITD-only or SITD-only */
static struct ehci_iso_sched *
-iso_sched_alloc (unsigned packets, unsigned mem_flags)
+iso_sched_alloc (unsigned packets, gfp_t mem_flags)
{
struct ehci_iso_sched *iso_sched;
int size = sizeof *iso_sched;
@@ -924,7 +924,7 @@ itd_urb_transaction (
struct ehci_iso_stream *stream,
struct ehci_hcd *ehci,
struct urb *urb,
- unsigned mem_flags
+ gfp_t mem_flags
)
{
struct ehci_itd *itd;
@@ -1418,7 +1418,7 @@ itd_complete (
/*-------------------------------------------------------------------------*/
static int itd_submit (struct ehci_hcd *ehci, struct urb *urb,
- unsigned mem_flags)
+ gfp_t mem_flags)
{
int status = -EINVAL;
unsigned long flags;
@@ -1529,7 +1529,7 @@ sitd_urb_transaction (
struct ehci_iso_stream *stream,
struct ehci_hcd *ehci,
struct urb *urb,
- unsigned mem_flags
+ gfp_t mem_flags
)
{
struct ehci_sitd *sitd;
@@ -1779,7 +1779,7 @@ sitd_complete (
static int sitd_submit (struct ehci_hcd *ehci, struct urb *urb,
- unsigned mem_flags)
+ gfp_t mem_flags)
{
int status = -EINVAL;
unsigned long flags;
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h
index f34a0516d35f..18e257c2bdb5 100644
--- a/drivers/usb/host/ehci.h
+++ b/drivers/usb/host/ehci.h
@@ -97,6 +97,7 @@ struct ehci_hcd { /* one per controller */
#else
# define COUNT(x) do {} while (0)
#endif
+ u8 sbrn; /* packed release number */
};
/* convert between an HCD pointer and the corresponding EHCI_HCD */
diff --git a/drivers/usb/host/hc_crisv10.c b/drivers/usb/host/hc_crisv10.c
index a8267cf17db4..0eaabeb37ac3 100644
--- a/drivers/usb/host/hc_crisv10.c
+++ b/drivers/usb/host/hc_crisv10.c
@@ -14,7 +14,6 @@
#include <linux/unistd.h>
#include <linux/interrupt.h>
#include <linux/init.h>
-#include <linux/version.h>
#include <linux/list.h>
#include <linux/spinlock.h>
diff --git a/drivers/usb/host/isp116x-hcd.c b/drivers/usb/host/isp116x-hcd.c
index e142056b0d2c..f9c3f5b8dd1c 100644
--- a/drivers/usb/host/isp116x-hcd.c
+++ b/drivers/usb/host/isp116x-hcd.c
@@ -70,6 +70,7 @@
#include <linux/interrupt.h>
#include <linux/usb.h>
#include <linux/usb_isp116x.h>
+#include <linux/platform_device.h>
#include <asm/io.h>
#include <asm/irq.h>
@@ -638,7 +639,7 @@ static irqreturn_t isp116x_irq(struct usb_hcd *hcd, struct pt_regs *regs)
+ msecs_to_jiffies(20) + 1);
if (intstat & HCINT_RD) {
DBG("---- remote wakeup\n");
- schedule_work(&isp116x->rh_resume);
+ usb_hcd_resume_root_hub(hcd);
ret = IRQ_HANDLED;
}
irqstat &= ~HCuPINT_OPR;
@@ -694,7 +695,7 @@ static int balance(struct isp116x *isp116x, u16 period, u16 load)
static int isp116x_urb_enqueue(struct usb_hcd *hcd,
struct usb_host_endpoint *hep, struct urb *urb,
- unsigned mem_flags)
+ gfp_t mem_flags)
{
struct isp116x *isp116x = hcd_to_isp116x(hcd);
struct usb_device *udev = urb->dev;
@@ -1160,7 +1161,7 @@ static int isp116x_hub_control(struct usb_hcd *hcd,
#ifdef CONFIG_PM
-static int isp116x_hub_suspend(struct usb_hcd *hcd)
+static int isp116x_bus_suspend(struct usb_hcd *hcd)
{
struct isp116x *isp116x = hcd_to_isp116x(hcd);
unsigned long flags;
@@ -1200,7 +1201,7 @@ static int isp116x_hub_suspend(struct usb_hcd *hcd)
return ret;
}
-static int isp116x_hub_resume(struct usb_hcd *hcd)
+static int isp116x_bus_resume(struct usb_hcd *hcd)
{
struct isp116x *isp116x = hcd_to_isp116x(hcd);
u32 val;
@@ -1263,21 +1264,11 @@ static int isp116x_hub_resume(struct usb_hcd *hcd)
return 0;
}
-static void isp116x_rh_resume(void *_hcd)
-{
- struct usb_hcd *hcd = _hcd;
-
- usb_resume_device(hcd->self.root_hub);
-}
#else
-#define isp116x_hub_suspend NULL
-#define isp116x_hub_resume NULL
-
-static void isp116x_rh_resume(void *_hcd)
-{
-}
+#define isp116x_bus_suspend NULL
+#define isp116x_bus_resume NULL
#endif
@@ -1636,8 +1627,8 @@ static struct hc_driver isp116x_hc_driver = {
.hub_status_data = isp116x_hub_status_data,
.hub_control = isp116x_hub_control,
- .hub_suspend = isp116x_hub_suspend,
- .hub_resume = isp116x_hub_resume,
+ .bus_suspend = isp116x_bus_suspend,
+ .bus_resume = isp116x_bus_resume,
};
/*----------------------------------------------------------------*/
@@ -1732,7 +1723,6 @@ static int __init isp116x_probe(struct device *dev)
isp116x->addr_reg = addr_reg;
spin_lock_init(&isp116x->lock);
INIT_LIST_HEAD(&isp116x->async);
- INIT_WORK(&isp116x->rh_resume, isp116x_rh_resume, hcd);
isp116x->board = dev->platform_data;
if (!isp116x->board) {
@@ -1774,22 +1764,13 @@ static int __init isp116x_probe(struct device *dev)
/*
Suspend of platform device
*/
-static int isp116x_suspend(struct device *dev, pm_message_t state, u32 phase)
+static int isp116x_suspend(struct device *dev, pm_message_t state)
{
int ret = 0;
- struct usb_hcd *hcd = dev_get_drvdata(dev);
- VDBG("%s: state %x, phase %x\n", __func__, state, phase);
+ VDBG("%s: state %x\n", __func__, state);
- if (phase != SUSPEND_DISABLE && phase != SUSPEND_POWER_DOWN)
- return 0;
-
- ret = usb_suspend_device(hcd->self.root_hub, state);
- if (!ret) {
- dev->power.power_state = state;
- INFO("%s suspended\n", hcd_name);
- } else
- ERR("%s suspend failed\n", hcd_name);
+ dev->power.power_state = state;
return ret;
}
@@ -1797,21 +1778,14 @@ static int isp116x_suspend(struct device *dev, pm_message_t state, u32 phase)
/*
Resume platform device
*/
-static int isp116x_resume(struct device *dev, u32 phase)
+static int isp116x_resume(struct device *dev)
{
int ret = 0;
- struct usb_hcd *hcd = dev_get_drvdata(dev);
- VDBG("%s: state %x, phase %x\n", __func__, dev->power.power_state,
- phase);
- if (phase != RESUME_POWER_ON)
- return 0;
+ VDBG("%s: state %x\n", __func__, dev->power.power_state);
+
+ dev->power.power_state = PMSG_ON;
- ret = usb_resume_device(hcd->self.root_hub);
- if (!ret) {
- dev->power.power_state = PMSG_ON;
- VDBG("%s resumed\n", (char *)hcd_name);
- }
return ret;
}
diff --git a/drivers/usb/host/isp116x.h b/drivers/usb/host/isp116x.h
index 58873470dcf5..c6fec96785fe 100644
--- a/drivers/usb/host/isp116x.h
+++ b/drivers/usb/host/isp116x.h
@@ -253,7 +253,6 @@ static const int cc_to_error[16] = {
struct isp116x {
spinlock_t lock;
- struct work_struct rh_resume;
void __iomem *addr_reg;
void __iomem *data_reg;
diff --git a/drivers/usb/host/ohci-au1xxx.c b/drivers/usb/host/ohci-au1xxx.c
index 3981bf15c8c7..f0c78cf14b6c 100644
--- a/drivers/usb/host/ohci-au1xxx.c
+++ b/drivers/usb/host/ohci-au1xxx.c
@@ -18,6 +18,8 @@
* This file is licenced under the GPL.
*/
+#include <linux/platform_device.h>
+
#include <asm/mach-au1x00/au1000.h>
#define USBH_ENABLE_BE (1<<0)
@@ -214,6 +216,11 @@ static const struct hc_driver ohci_au1xxx_hc_driver = {
*/
.hub_status_data = ohci_hub_status_data,
.hub_control = ohci_hub_control,
+#ifdef CONFIG_PM
+ .bus_suspend = ohci_bus_suspend,
+ .bus_resume = ohci_bus_resume,
+#endif
+ .start_port_reset = ohci_start_port_reset,
};
/*-------------------------------------------------------------------------*/
@@ -259,6 +266,7 @@ static int ohci_hcd_au1xxx_drv_resume(struct device *dev)
static struct device_driver ohci_hcd_au1xxx_driver = {
.name = "au1xxx-ohci",
+ .owner = THIS_MODULE,
.bus = &platform_bus_type,
.probe = ohci_hcd_au1xxx_drv_probe,
.remove = ohci_hcd_au1xxx_drv_remove,
diff --git a/drivers/usb/host/ohci-dbg.c b/drivers/usb/host/ohci-dbg.c
index 7924c74f958e..7bfffcbbd226 100644
--- a/drivers/usb/host/ohci-dbg.c
+++ b/drivers/usb/host/ohci-dbg.c
@@ -193,10 +193,6 @@ ohci_dump_status (struct ohci_hcd *controller, char **next, unsigned *size)
maybe_print_eds (controller, "donehead",
ohci_readl (controller, &regs->donehead), next, size);
-
- /* broken fminterval means traffic won't flow! */
- ohci_dbg (controller, "fminterval %08x\n",
- ohci_readl (controller, &regs->fminterval));
}
#define dbg_port_sw(hc,num,value,next,size) \
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index 67c1aa5eb1c1..5c0c6c8a7a82 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -180,7 +180,7 @@ static int ohci_urb_enqueue (
struct usb_hcd *hcd,
struct usb_host_endpoint *ep,
struct urb *urb,
- unsigned mem_flags
+ gfp_t mem_flags
) {
struct ohci_hcd *ohci = hcd_to_ohci (hcd);
struct ed *ed;
@@ -723,7 +723,7 @@ static irqreturn_t ohci_irq (struct usb_hcd *hcd, struct pt_regs *ptregs)
ohci_vdbg (ohci, "resume detect\n");
ohci_writel (ohci, OHCI_INTR_RD, &regs->intrstatus);
if (hcd->state != HC_STATE_QUIESCING)
- schedule_work(&ohci->rh_resume);
+ usb_hcd_resume_root_hub(hcd);
}
if (ints & OHCI_INTR_WDH) {
@@ -791,7 +791,7 @@ static void ohci_stop (struct usb_hcd *hcd)
/* must not be called from interrupt context */
-#if defined(CONFIG_USB_SUSPEND) || defined(CONFIG_PM)
+#ifdef CONFIG_PM
static int ohci_restart (struct ohci_hcd *ohci)
{
diff --git a/drivers/usb/host/ohci-hub.c b/drivers/usb/host/ohci-hub.c
index ce7b28da7a15..e01e77bc324b 100644
--- a/drivers/usb/host/ohci-hub.c
+++ b/drivers/usb/host/ohci-hub.c
@@ -36,7 +36,7 @@
/*-------------------------------------------------------------------------*/
-#if defined(CONFIG_USB_SUSPEND) || defined(CONFIG_PM)
+#ifdef CONFIG_PM
#define OHCI_SCHED_ENABLES \
(OHCI_CTRL_CLE|OHCI_CTRL_BLE|OHCI_CTRL_PLE|OHCI_CTRL_IE)
@@ -45,7 +45,7 @@ static void dl_done_list (struct ohci_hcd *, struct pt_regs *);
static void finish_unlinks (struct ohci_hcd *, u16 , struct pt_regs *);
static int ohci_restart (struct ohci_hcd *ohci);
-static int ohci_hub_suspend (struct usb_hcd *hcd)
+static int ohci_bus_suspend (struct usb_hcd *hcd)
{
struct ohci_hcd *ohci = hcd_to_ohci (hcd);
int status = 0;
@@ -73,7 +73,6 @@ static int ohci_hub_suspend (struct usb_hcd *hcd)
ohci_dbg (ohci, "suspend root hub\n");
/* First stop any processing */
- hcd->state = HC_STATE_QUIESCING;
if (ohci->hc_control & OHCI_SCHED_ENABLES) {
int limit;
@@ -108,7 +107,9 @@ static int ohci_hub_suspend (struct usb_hcd *hcd)
else
ohci->hc_control &= ~OHCI_CTRL_RWE;
- /* Suspend hub */
+ /* Suspend hub ... this is the "global (to this bus) suspend" mode,
+ * which doesn't imply ports will first be individually suspended.
+ */
ohci->hc_control &= ~OHCI_CTRL_HCFS;
ohci->hc_control |= OHCI_USB_SUSPEND;
ohci_writel (ohci, ohci->hc_control, &ohci->regs->control);
@@ -118,8 +119,9 @@ static int ohci_hub_suspend (struct usb_hcd *hcd)
ohci->next_statechange = jiffies + msecs_to_jiffies (5);
done:
+ /* external suspend vs self autosuspend ... same effect */
if (status == 0)
- hcd->state = HC_STATE_SUSPENDED;
+ usb_hcd_suspend_root_hub(hcd);
spin_unlock_irqrestore (&ohci->lock, flags);
return status;
}
@@ -133,7 +135,7 @@ static inline struct ed *find_head (struct ed *ed)
}
/* caller has locked the root hub */
-static int ohci_hub_resume (struct usb_hcd *hcd)
+static int ohci_bus_resume (struct usb_hcd *hcd)
{
struct ohci_hcd *ohci = hcd_to_ohci (hcd);
u32 temp, enables;
@@ -146,7 +148,7 @@ static int ohci_hub_resume (struct usb_hcd *hcd)
ohci->hc_control = ohci_readl (ohci, &ohci->regs->control);
if (ohci->hc_control & (OHCI_CTRL_IR | OHCI_SCHED_ENABLES)) {
- /* this can happen after suspend-to-disk */
+ /* this can happen after resuming a swsusp snapshot */
if (hcd->state == HC_STATE_RESUMING) {
ohci_dbg (ohci, "BIOS/SMM active, control %03x\n",
ohci->hc_control);
@@ -169,11 +171,12 @@ static int ohci_hub_resume (struct usb_hcd *hcd)
ohci_info (ohci, "wakeup\n");
break;
case OHCI_USB_OPER:
- ohci_dbg (ohci, "already resumed\n");
- status = 0;
+ /* this can happen after resuming a swsusp snapshot */
+ ohci_dbg (ohci, "snapshot resume? reinit\n");
+ status = -EBUSY;
break;
default: /* RESET, we lost power */
- ohci_dbg (ohci, "root hub hardware reset\n");
+ ohci_dbg (ohci, "lost power\n");
status = -EBUSY;
}
spin_unlock_irq (&ohci->lock);
@@ -198,8 +201,7 @@ static int ohci_hub_resume (struct usb_hcd *hcd)
}
/* Some controllers (lucent erratum) need extra-long delays */
- hcd->state = HC_STATE_RESUMING;
- mdelay (20 /* usb 11.5.1.10 */ + 15);
+ msleep (20 /* usb 11.5.1.10 */ + 12 /* 32 msec counter */ + 1);
temp = ohci_readl (ohci, &ohci->regs->control);
temp &= OHCI_CTRL_HCFS;
@@ -273,28 +275,10 @@ static int ohci_hub_resume (struct usb_hcd *hcd)
(void) ohci_readl (ohci, &ohci->regs->control);
}
- hcd->state = HC_STATE_RUNNING;
return 0;
}
-static void ohci_rh_resume (void *_hcd)
-{
- struct usb_hcd *hcd = _hcd;
-
- usb_lock_device (hcd->self.root_hub);
- (void) ohci_hub_resume (hcd);
- usb_unlock_device (hcd->self.root_hub);
-}
-
-#else
-
-static void ohci_rh_resume (void *_hcd)
-{
- struct ohci_hcd *ohci = hcd_to_ohci (_hcd);
- ohci_dbg(ohci, "rh_resume ??\n");
-}
-
-#endif /* CONFIG_USB_SUSPEND || CONFIG_PM */
+#endif /* CONFIG_PM */
/*-------------------------------------------------------------------------*/
@@ -367,7 +351,6 @@ done:
#ifdef CONFIG_PM
/* save power by suspending idle root hubs;
* INTR_RD wakes us when there's work
- * NOTE: if we can do this, we don't need a root hub timer!
*/
if (can_suspend
&& !changed
@@ -379,8 +362,7 @@ done:
&& usb_trylock_device (hcd->self.root_hub)
) {
ohci_vdbg (ohci, "autosuspend\n");
- (void) ohci_hub_suspend (hcd);
- hcd->state = HC_STATE_RUNNING;
+ (void) ohci_bus_suspend (hcd);
usb_unlock_device (hcd->self.root_hub);
}
#endif
@@ -554,7 +536,7 @@ static int ohci_hub_control (
temp = RH_PS_POCI;
if ((ohci->hc_control & OHCI_CTRL_HCFS)
!= OHCI_USB_OPER)
- schedule_work (&ohci->rh_resume);
+ usb_hcd_resume_root_hub(hcd);
break;
case USB_PORT_FEAT_C_SUSPEND:
temp = RH_PS_PSSC;
diff --git a/drivers/usb/host/ohci-lh7a404.c b/drivers/usb/host/ohci-lh7a404.c
index 859aca7be753..336c766c6e29 100644
--- a/drivers/usb/host/ohci-lh7a404.c
+++ b/drivers/usb/host/ohci-lh7a404.c
@@ -16,6 +16,8 @@
* This file is licenced under the GPL.
*/
+#include <linux/platform_device.h>
+
#include <asm/hardware.h>
@@ -193,6 +195,11 @@ static const struct hc_driver ohci_lh7a404_hc_driver = {
*/
.hub_status_data = ohci_hub_status_data,
.hub_control = ohci_hub_control,
+#ifdef CONFIG_PM
+ .bus_suspend = ohci_bus_suspend,
+ .bus_resume = ohci_bus_resume,
+#endif
+ .start_port_reset = ohci_start_port_reset,
};
/*-------------------------------------------------------------------------*/
@@ -239,6 +246,7 @@ static int ohci_hcd_lh7a404_drv_resume(struct device *dev)
static struct device_driver ohci_hcd_lh7a404_driver = {
.name = "lh7a404-ohci",
+ .owner = THIS_MODULE,
.bus = &platform_bus_type,
.probe = ohci_hcd_lh7a404_drv_probe,
.remove = ohci_hcd_lh7a404_drv_remove,
diff --git a/drivers/usb/host/ohci-mem.c b/drivers/usb/host/ohci-mem.c
index fd3c4d3714bd..bfbe328a4788 100644
--- a/drivers/usb/host/ohci-mem.c
+++ b/drivers/usb/host/ohci-mem.c
@@ -28,7 +28,6 @@ static void ohci_hcd_init (struct ohci_hcd *ohci)
ohci->next_statechange = jiffies;
spin_lock_init (&ohci->lock);
INIT_LIST_HEAD (&ohci->pending);
- INIT_WORK (&ohci->rh_resume, ohci_rh_resume, ohci_to_hcd(ohci));
ohci->reboot_notifier.notifier_call = ohci_reboot;
}
@@ -84,7 +83,7 @@ dma_to_td (struct ohci_hcd *hc, dma_addr_t td_dma)
/* TDs ... */
static struct td *
-td_alloc (struct ohci_hcd *hc, unsigned mem_flags)
+td_alloc (struct ohci_hcd *hc, gfp_t mem_flags)
{
dma_addr_t dma;
struct td *td;
@@ -118,7 +117,7 @@ td_free (struct ohci_hcd *hc, struct td *td)
/* EDs ... */
static struct ed *
-ed_alloc (struct ohci_hcd *hc, unsigned mem_flags)
+ed_alloc (struct ohci_hcd *hc, gfp_t mem_flags)
{
dma_addr_t dma;
struct ed *ed;
diff --git a/drivers/usb/host/ohci-omap.c b/drivers/usb/host/ohci-omap.c
index d8f3ba7ad52e..e46cc540cf4d 100644
--- a/drivers/usb/host/ohci-omap.c
+++ b/drivers/usb/host/ohci-omap.c
@@ -14,6 +14,10 @@
* This file is licenced under the GPL.
*/
+#include <linux/signal.h> /* SA_INTERRUPT */
+#include <linux/jiffies.h>
+#include <linux/platform_device.h>
+
#include <asm/hardware.h>
#include <asm/io.h>
#include <asm/mach-types.h>
@@ -420,9 +424,9 @@ static const struct hc_driver ohci_omap_hc_driver = {
*/
.hub_status_data = ohci_hub_status_data,
.hub_control = ohci_hub_control,
-#ifdef CONFIG_USB_SUSPEND
- .hub_suspend = ohci_hub_suspend,
- .hub_resume = ohci_hub_resume,
+#ifdef CONFIG_PM
+ .bus_suspend = ohci_bus_suspend,
+ .bus_resume = ohci_bus_resume,
#endif
.start_port_reset = ohci_start_port_reset,
};
@@ -455,50 +459,32 @@ static int ohci_hcd_omap_drv_remove(struct device *dev)
#ifdef CONFIG_PM
-static int ohci_omap_suspend(struct device *dev, pm_message_t message, u32 level)
+static int ohci_omap_suspend(struct device *dev, pm_message_t message)
{
struct ohci_hcd *ohci = hcd_to_ohci(dev_get_drvdata(dev));
- int status = -EINVAL;
-
- if (level != SUSPEND_POWER_DOWN)
- return 0;
-
- down(&ohci_to_hcd(ohci)->self.root_hub->serialize);
- status = ohci_hub_suspend(ohci_to_hcd(ohci));
- if (status == 0) {
- omap_ohci_clock_power(0);
- ohci_to_hcd(ohci)->self.root_hub->state =
- USB_STATE_SUSPENDED;
- ohci_to_hcd(ohci)->state = HC_STATE_SUSPENDED;
- dev->power.power_state = PMSG_SUSPEND;
- }
- up(&ohci_to_hcd(ohci)->self.root_hub->serialize);
- return status;
+
+ if (time_before(jiffies, ohci->next_statechange))
+ msleep(5);
+ ohci->next_statechange = jiffies;
+
+ omap_ohci_clock_power(0);
+ ohci_to_hcd(ohci)->state = HC_STATE_SUSPENDED;
+ dev->power.power_state = PMSG_SUSPEND;
+ return 0;
}
-static int ohci_omap_resume(struct device *dev, u32 level)
+static int ohci_omap_resume(struct device *dev)
{
struct ohci_hcd *ohci = hcd_to_ohci(dev_get_drvdata(dev));
- int status = 0;
-
- if (level != RESUME_POWER_ON)
- return 0;
if (time_before(jiffies, ohci->next_statechange))
msleep(5);
ohci->next_statechange = jiffies;
+
omap_ohci_clock_power(1);
-#ifdef CONFIG_USB_SUSPEND
- /* get extra cleanup even if remote wakeup isn't in use */
- status = usb_resume_device(ohci_to_hcd(ohci)->self.root_hub);
-#else
- down(&ohci_to_hcd(ohci)->self.root_hub->serialize);
- status = ohci_hub_resume(ohci_to_hcd(ohci));
- up(&ohci_to_hcd(ohci)->self.root_hub->serialize);
-#endif
- if (status == 0)
- dev->power.power_state = PMSG_ON;
- return status;
+ dev->power.power_state = PMSG_ON;
+ usb_hcd_resume_root_hub(dev_get_drvdata(dev));
+ return 0;
}
#endif
@@ -510,6 +496,7 @@ static int ohci_omap_resume(struct device *dev, u32 level)
*/
static struct device_driver ohci_hcd_omap_driver = {
.name = "ohci",
+ .owner = THIS_MODULE,
.bus = &platform_bus_type,
.probe = ohci_hcd_omap_drv_probe,
.remove = ohci_hcd_omap_drv_remove,
diff --git a/drivers/usb/host/ohci-pci.c b/drivers/usb/host/ohci-pci.c
index eede6be098d2..a59e536441e1 100644
--- a/drivers/usb/host/ohci-pci.c
+++ b/drivers/usb/host/ohci-pci.c
@@ -14,6 +14,8 @@
* This file is licenced under the GPL.
*/
+#include <linux/jiffies.h>
+
#ifdef CONFIG_PPC_PMAC
#include <asm/machdep.h>
#include <asm/pmac_feature.h>
@@ -112,23 +114,13 @@ ohci_pci_start (struct usb_hcd *hcd)
static int ohci_pci_suspend (struct usb_hcd *hcd, pm_message_t message)
{
- struct ohci_hcd *ohci = hcd_to_ohci (hcd);
-
- /* suspend root hub, hoping it keeps power during suspend */
- if (time_before (jiffies, ohci->next_statechange))
- msleep (100);
-
-#ifdef CONFIG_USB_SUSPEND
- (void) usb_suspend_device (hcd->self.root_hub, message);
-#else
- usb_lock_device (hcd->self.root_hub);
- (void) ohci_hub_suspend (hcd);
- usb_unlock_device (hcd->self.root_hub);
-#endif
+ /* root hub was already suspended */
- /* let things settle down a bit */
- msleep (100);
-
+ /* FIXME these PMAC things get called in the wrong places. ASIC
+ * clocks should be turned off AFTER entering D3, and on BEFORE
+ * trying to enter D0. Evidently the PCI layer doesn't currently
+ * provide the right sort of platform hooks for this ...
+ */
#ifdef CONFIG_PPC_PMAC
if (_machine == _MACH_Pmac) {
struct device_node *of_node;
@@ -145,9 +137,6 @@ static int ohci_pci_suspend (struct usb_hcd *hcd, pm_message_t message)
static int ohci_pci_resume (struct usb_hcd *hcd)
{
- struct ohci_hcd *ohci = hcd_to_ohci (hcd);
- int retval = 0;
-
#ifdef CONFIG_PPC_PMAC
if (_machine == _MACH_Pmac) {
struct device_node *of_node;
@@ -159,19 +148,8 @@ static int ohci_pci_resume (struct usb_hcd *hcd)
}
#endif /* CONFIG_PPC_PMAC */
- /* resume root hub */
- if (time_before (jiffies, ohci->next_statechange))
- msleep (100);
-#ifdef CONFIG_USB_SUSPEND
- /* get extra cleanup even if remote wakeup isn't in use */
- retval = usb_resume_device (hcd->self.root_hub);
-#else
- usb_lock_device (hcd->self.root_hub);
- retval = ohci_hub_resume (hcd);
- usb_unlock_device (hcd->self.root_hub);
-#endif
-
- return retval;
+ usb_hcd_resume_root_hub(hcd);
+ return 0;
}
#endif /* CONFIG_PM */
@@ -218,9 +196,9 @@ static const struct hc_driver ohci_pci_hc_driver = {
*/
.hub_status_data = ohci_hub_status_data,
.hub_control = ohci_hub_control,
-#ifdef CONFIG_USB_SUSPEND
- .hub_suspend = ohci_hub_suspend,
- .hub_resume = ohci_hub_resume,
+#ifdef CONFIG_PM
+ .bus_suspend = ohci_bus_suspend,
+ .bus_resume = ohci_bus_resume,
#endif
.start_port_reset = ohci_start_port_reset,
};
diff --git a/drivers/usb/host/ohci-ppc-soc.c b/drivers/usb/host/ohci-ppc-soc.c
index 251533363028..92cf6f4a1374 100644
--- a/drivers/usb/host/ohci-ppc-soc.c
+++ b/drivers/usb/host/ohci-ppc-soc.c
@@ -14,6 +14,8 @@
* This file is licenced under the GPL.
*/
+#include <linux/platform_device.h>
+
/* configure so an HC device and id are always provided */
/* always called with process context; sleeping is OK */
@@ -163,9 +165,9 @@ static const struct hc_driver ohci_ppc_soc_hc_driver = {
*/
.hub_status_data = ohci_hub_status_data,
.hub_control = ohci_hub_control,
-#ifdef CONFIG_USB_SUSPEND
- .hub_suspend = ohci_hub_suspend,
- .hub_resume = ohci_hub_resume,
+#ifdef CONFIG_PM
+ .bus_suspend = ohci_bus_suspend,
+ .bus_resume = ohci_bus_resume,
#endif
.start_port_reset = ohci_start_port_reset,
};
@@ -193,10 +195,11 @@ static int ohci_hcd_ppc_soc_drv_remove(struct device *dev)
static struct device_driver ohci_hcd_ppc_soc_driver = {
.name = "ppc-soc-ohci",
+ .owner = THIS_MODULE,
.bus = &platform_bus_type,
.probe = ohci_hcd_ppc_soc_drv_probe,
.remove = ohci_hcd_ppc_soc_drv_remove,
-#if defined(CONFIG_USB_SUSPEND) || defined(CONFIG_PM)
+#ifdef CONFIG_PM
/*.suspend = ohci_hcd_ppc_soc_drv_suspend,*/
/*.resume = ohci_hcd_ppc_soc_drv_resume,*/
#endif
diff --git a/drivers/usb/host/ohci-pxa27x.c b/drivers/usb/host/ohci-pxa27x.c
index 2fdb262d4726..59e20568e8f9 100644
--- a/drivers/usb/host/ohci-pxa27x.c
+++ b/drivers/usb/host/ohci-pxa27x.c
@@ -20,6 +20,9 @@
*/
#include <linux/device.h>
+#include <linux/signal.h>
+#include <linux/platform_device.h>
+
#include <asm/mach-types.h>
#include <asm/hardware.h>
#include <asm/arch/pxa-regs.h>
@@ -278,10 +281,11 @@ static const struct hc_driver ohci_pxa27x_hc_driver = {
*/
.hub_status_data = ohci_hub_status_data,
.hub_control = ohci_hub_control,
-#ifdef CONFIG_USB_SUSPEND
- .hub_suspend = ohci_hub_suspend,
- .hub_resume = ohci_hub_resume,
+#ifdef CONFIG_PM
+ .bus_suspend = ohci_bus_suspend,
+ .bus_resume = ohci_bus_resume,
#endif
+ .start_port_reset = ohci_start_port_reset,
};
/*-------------------------------------------------------------------------*/
@@ -309,7 +313,7 @@ static int ohci_hcd_pxa27x_drv_remove(struct device *dev)
return 0;
}
-static int ohci_hcd_pxa27x_drv_suspend(struct device *dev, pm_message_t state, u32 level)
+static int ohci_hcd_pxa27x_drv_suspend(struct device *dev, pm_message_t state)
{
// struct platform_device *pdev = to_platform_device(dev);
// struct usb_hcd *hcd = dev_get_drvdata(dev);
@@ -318,7 +322,7 @@ static int ohci_hcd_pxa27x_drv_suspend(struct device *dev, pm_message_t state, u
return 0;
}
-static int ohci_hcd_pxa27x_drv_resume(struct device *dev, u32 level)
+static int ohci_hcd_pxa27x_drv_resume(struct device *dev)
{
// struct platform_device *pdev = to_platform_device(dev);
// struct usb_hcd *hcd = dev_get_drvdata(dev);
diff --git a/drivers/usb/host/ohci-s3c2410.c b/drivers/usb/host/ohci-s3c2410.c
index da7d5478f74d..ee1fc605b402 100644
--- a/drivers/usb/host/ohci-s3c2410.c
+++ b/drivers/usb/host/ohci-s3c2410.c
@@ -19,6 +19,8 @@
* This file is licenced under the GPL.
*/
+#include <linux/platform_device.h>
+
#include <asm/hardware.h>
#include <asm/hardware/clock.h>
#include <asm/arch/usb-control.h>
@@ -448,11 +450,11 @@ static const struct hc_driver ohci_s3c2410_hc_driver = {
*/
.hub_status_data = ohci_s3c2410_hub_status_data,
.hub_control = ohci_s3c2410_hub_control,
-
-#if defined(CONFIG_USB_SUSPEND) && 0
- .hub_suspend = ohci_hub_suspend,
- .hub_resume = ohci_hub_resume,
+#ifdef CONFIG_PM
+ .bus_suspend = ohci_bus_suspend,
+ .bus_resume = ohci_bus_resume,
#endif
+ .start_port_reset = ohci_start_port_reset,
};
/* device driver */
@@ -474,6 +476,7 @@ static int ohci_hcd_s3c2410_drv_remove(struct device *dev)
static struct device_driver ohci_hcd_s3c2410_driver = {
.name = "s3c2410-ohci",
+ .owner = THIS_MODULE,
.bus = &platform_bus_type,
.probe = ohci_hcd_s3c2410_drv_probe,
.remove = ohci_hcd_s3c2410_drv_remove,
diff --git a/drivers/usb/host/ohci-sa1111.c b/drivers/usb/host/ohci-sa1111.c
index 814d2be4ee7b..fb3221ebbb29 100644
--- a/drivers/usb/host/ohci-sa1111.c
+++ b/drivers/usb/host/ohci-sa1111.c
@@ -235,10 +235,11 @@ static const struct hc_driver ohci_sa1111_hc_driver = {
*/
.hub_status_data = ohci_hub_status_data,
.hub_control = ohci_hub_control,
-#ifdef CONFIG_USB_SUSPEND
- .hub_suspend = ohci_hub_suspend,
- .hub_resume = ohci_hub_resume,
+#ifdef CONFIG_PM
+ .bus_suspend = ohci_bus_suspend,
+ .bus_resume = ohci_bus_resume,
#endif
+ .start_port_reset = ohci_start_port_reset,
};
/*-------------------------------------------------------------------------*/
diff --git a/drivers/usb/host/ohci.h b/drivers/usb/host/ohci.h
index 8a9b9d9209e9..caacf14371f5 100644
--- a/drivers/usb/host/ohci.h
+++ b/drivers/usb/host/ohci.h
@@ -389,7 +389,6 @@ struct ohci_hcd {
unsigned long next_statechange; /* suspend/resume */
u32 fminterval; /* saved register */
- struct work_struct rh_resume;
struct notifier_block reboot_notifier;
unsigned long flags; /* for HC bugs */
diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c
new file mode 100644
index 000000000000..e46528c825bf
--- /dev/null
+++ b/drivers/usb/host/pci-quirks.c
@@ -0,0 +1,319 @@
+/*
+ * This file contains code to reset and initialize USB host controllers.
+ * Some of it includes work-arounds for PCI hardware and BIOS quirks.
+ * It may need to run early during booting -- before USB would normally
+ * initialize -- to ensure that Linux doesn't use any legacy modes.
+ *
+ * Copyright (c) 1999 Martin Mares <mj@ucw.cz>
+ * (and others)
+ */
+
+#include <linux/config.h>
+#ifdef CONFIG_USB_DEBUG
+#define DEBUG
+#else
+#undef DEBUG
+#endif
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/acpi.h>
+
+
+#define UHCI_USBLEGSUP 0xc0 /* legacy support */
+#define UHCI_USBCMD 0 /* command register */
+#define UHCI_USBINTR 4 /* interrupt register */
+#define UHCI_USBLEGSUP_RWC 0x8f00 /* the R/WC bits */
+#define UHCI_USBLEGSUP_RO 0x5040 /* R/O and reserved bits */
+#define UHCI_USBCMD_RUN 0x0001 /* RUN/STOP bit */
+#define UHCI_USBCMD_HCRESET 0x0002 /* Host Controller reset */
+#define UHCI_USBCMD_EGSM 0x0008 /* Global Suspend Mode */
+#define UHCI_USBCMD_CONFIGURE 0x0040 /* Config Flag */
+#define UHCI_USBINTR_RESUME 0x0002 /* Resume interrupt enable */
+
+#define OHCI_CONTROL 0x04
+#define OHCI_CMDSTATUS 0x08
+#define OHCI_INTRSTATUS 0x0c
+#define OHCI_INTRENABLE 0x10
+#define OHCI_INTRDISABLE 0x14
+#define OHCI_OCR (1 << 3) /* ownership change request */
+#define OHCI_CTRL_RWC (1 << 9) /* remote wakeup connected */
+#define OHCI_CTRL_IR (1 << 8) /* interrupt routing */
+#define OHCI_INTR_OC (1 << 30) /* ownership change */
+
+#define EHCI_HCC_PARAMS 0x08 /* extended capabilities */
+#define EHCI_USBCMD 0 /* command register */
+#define EHCI_USBCMD_RUN (1 << 0) /* RUN/STOP bit */
+#define EHCI_USBSTS 4 /* status register */
+#define EHCI_USBSTS_HALTED (1 << 12) /* HCHalted bit */
+#define EHCI_USBINTR 8 /* interrupt register */
+#define EHCI_USBLEGSUP 0 /* legacy support register */
+#define EHCI_USBLEGSUP_BIOS (1 << 16) /* BIOS semaphore */
+#define EHCI_USBLEGSUP_OS (1 << 24) /* OS semaphore */
+#define EHCI_USBLEGCTLSTS 4 /* legacy control/status */
+#define EHCI_USBLEGCTLSTS_SOOE (1 << 13) /* SMI on ownership change */
+
+
+/*
+ * Make sure the controller is completely inactive, unable to
+ * generate interrupts or do DMA.
+ */
+void uhci_reset_hc(struct pci_dev *pdev, unsigned long base)
+{
+ /* Turn off PIRQ enable and SMI enable. (This also turns off the
+ * BIOS's USB Legacy Support.) Turn off all the R/WC bits too.
+ */
+ pci_write_config_word(pdev, UHCI_USBLEGSUP, UHCI_USBLEGSUP_RWC);
+
+ /* Reset the HC - this will force us to get a
+ * new notification of any already connected
+ * ports due to the virtual disconnect that it
+ * implies.
+ */
+ outw(UHCI_USBCMD_HCRESET, base + UHCI_USBCMD);
+ mb();
+ udelay(5);
+ if (inw(base + UHCI_USBCMD) & UHCI_USBCMD_HCRESET)
+ dev_warn(&pdev->dev, "HCRESET not completed yet!\n");
+
+ /* Just to be safe, disable interrupt requests and
+ * make sure the controller is stopped.
+ */
+ outw(0, base + UHCI_USBINTR);
+ outw(0, base + UHCI_USBCMD);
+}
+EXPORT_SYMBOL_GPL(uhci_reset_hc);
+
+/*
+ * Initialize a controller that was newly discovered or has just been
+ * resumed. In either case we can't be sure of its previous state.
+ *
+ * Returns: 1 if the controller was reset, 0 otherwise.
+ */
+int uhci_check_and_reset_hc(struct pci_dev *pdev, unsigned long base)
+{
+ u16 legsup;
+ unsigned int cmd, intr;
+
+ /*
+ * When restarting a suspended controller, we expect all the
+ * settings to be the same as we left them:
+ *
+ * PIRQ and SMI disabled, no R/W bits set in USBLEGSUP;
+ * Controller is stopped and configured with EGSM set;
+ * No interrupts enabled except possibly Resume Detect.
+ *
+ * If any of these conditions are violated we do a complete reset.
+ */
+ pci_read_config_word(pdev, UHCI_USBLEGSUP, &legsup);
+ if (legsup & ~(UHCI_USBLEGSUP_RO | UHCI_USBLEGSUP_RWC)) {
+ dev_dbg(&pdev->dev, "%s: legsup = 0x%04x\n",
+ __FUNCTION__, legsup);
+ goto reset_needed;
+ }
+
+ cmd = inw(base + UHCI_USBCMD);
+ if ((cmd & UHCI_USBCMD_RUN) || !(cmd & UHCI_USBCMD_CONFIGURE) ||
+ !(cmd & UHCI_USBCMD_EGSM)) {
+ dev_dbg(&pdev->dev, "%s: cmd = 0x%04x\n",
+ __FUNCTION__, cmd);
+ goto reset_needed;
+ }
+
+ intr = inw(base + UHCI_USBINTR);
+ if (intr & (~UHCI_USBINTR_RESUME)) {
+ dev_dbg(&pdev->dev, "%s: intr = 0x%04x\n",
+ __FUNCTION__, intr);
+ goto reset_needed;
+ }
+ return 0;
+
+reset_needed:
+ dev_dbg(&pdev->dev, "Performing full reset\n");
+ uhci_reset_hc(pdev, base);
+ return 1;
+}
+EXPORT_SYMBOL_GPL(uhci_check_and_reset_hc);
+
+static inline int io_type_enabled(struct pci_dev *pdev, unsigned int mask)
+{
+ u16 cmd;
+ return !pci_read_config_word(pdev, PCI_COMMAND, &cmd) && (cmd & mask);
+}
+
+#define pio_enabled(dev) io_type_enabled(dev, PCI_COMMAND_IO)
+#define mmio_enabled(dev) io_type_enabled(dev, PCI_COMMAND_MEMORY)
+
+static void __devinit quirk_usb_handoff_uhci(struct pci_dev *pdev)
+{
+ unsigned long base = 0;
+ int i;
+
+ if (!pio_enabled(pdev))
+ return;
+
+ for (i = 0; i < PCI_ROM_RESOURCE; i++)
+ if ((pci_resource_flags(pdev, i) & IORESOURCE_IO)) {
+ base = pci_resource_start(pdev, i);
+ break;
+ }
+
+ if (base)
+ uhci_check_and_reset_hc(pdev, base);
+}
+
+static int __devinit mmio_resource_enabled(struct pci_dev *pdev, int idx)
+{
+ return pci_resource_start(pdev, idx) && mmio_enabled(pdev);
+}
+
+static void __devinit quirk_usb_handoff_ohci(struct pci_dev *pdev)
+{
+ void __iomem *base;
+ int wait_time;
+ u32 control;
+
+ if (!mmio_resource_enabled(pdev, 0))
+ return;
+
+ base = ioremap_nocache(pci_resource_start(pdev, 0),
+ pci_resource_len(pdev, 0));
+ if (base == NULL) return;
+
+/* On PA-RISC, PDC can leave IR set incorrectly; ignore it there. */
+#ifndef __hppa__
+ control = readl(base + OHCI_CONTROL);
+ if (control & OHCI_CTRL_IR) {
+ wait_time = 500; /* arbitrary; 5 seconds */
+ writel(OHCI_INTR_OC, base + OHCI_INTRENABLE);
+ writel(OHCI_OCR, base + OHCI_CMDSTATUS);
+ while (wait_time > 0 &&
+ readl(base + OHCI_CONTROL) & OHCI_CTRL_IR) {
+ wait_time -= 10;
+ msleep(10);
+ }
+ if (wait_time <= 0)
+ printk(KERN_WARNING "%s %s: early BIOS handoff "
+ "failed (BIOS bug ?)\n",
+ pdev->dev.bus_id, "OHCI");
+
+ /* reset controller, preserving RWC */
+ writel(control & OHCI_CTRL_RWC, base + OHCI_CONTROL);
+ }
+#endif
+
+ /*
+ * disable interrupts
+ */
+ writel(~(u32)0, base + OHCI_INTRDISABLE);
+ writel(~(u32)0, base + OHCI_INTRSTATUS);
+
+ iounmap(base);
+}
+
+static void __devinit quirk_usb_disable_ehci(struct pci_dev *pdev)
+{
+ int wait_time, delta;
+ void __iomem *base, *op_reg_base;
+ u32 hcc_params, val, temp;
+ u8 cap_length;
+
+ if (!mmio_resource_enabled(pdev, 0))
+ return;
+
+ base = ioremap_nocache(pci_resource_start(pdev, 0),
+ pci_resource_len(pdev, 0));
+ if (base == NULL) return;
+
+ cap_length = readb(base);
+ op_reg_base = base + cap_length;
+ hcc_params = readl(base + EHCI_HCC_PARAMS);
+ hcc_params = (hcc_params >> 8) & 0xff;
+ if (hcc_params) {
+ pci_read_config_dword(pdev,
+ hcc_params + EHCI_USBLEGSUP,
+ &val);
+ if (((val & 0xff) == 1) && (val & EHCI_USBLEGSUP_BIOS)) {
+ /*
+ * Ok, BIOS is in smm mode, try to hand off...
+ */
+ pci_read_config_dword(pdev,
+ hcc_params + EHCI_USBLEGCTLSTS,
+ &temp);
+ pci_write_config_dword(pdev,
+ hcc_params + EHCI_USBLEGCTLSTS,
+ temp | EHCI_USBLEGCTLSTS_SOOE);
+ val |= EHCI_USBLEGSUP_OS;
+ pci_write_config_dword(pdev,
+ hcc_params + EHCI_USBLEGSUP,
+ val);
+
+ wait_time = 500;
+ do {
+ msleep(10);
+ wait_time -= 10;
+ pci_read_config_dword(pdev,
+ hcc_params + EHCI_USBLEGSUP,
+ &val);
+ } while (wait_time && (val & EHCI_USBLEGSUP_BIOS));
+ if (!wait_time) {
+ /*
+ * well, possibly buggy BIOS...
+ */
+ printk(KERN_WARNING "%s %s: early BIOS handoff "
+ "failed (BIOS bug ?)\n",
+ pdev->dev.bus_id, "EHCI");
+ pci_write_config_dword(pdev,
+ hcc_params + EHCI_USBLEGSUP,
+ EHCI_USBLEGSUP_OS);
+ pci_write_config_dword(pdev,
+ hcc_params + EHCI_USBLEGCTLSTS,
+ 0);
+ }
+ }
+ }
+
+ /*
+ * halt EHCI & disable its interrupts in any case
+ */
+ val = readl(op_reg_base + EHCI_USBSTS);
+ if ((val & EHCI_USBSTS_HALTED) == 0) {
+ val = readl(op_reg_base + EHCI_USBCMD);
+ val &= ~EHCI_USBCMD_RUN;
+ writel(val, op_reg_base + EHCI_USBCMD);
+
+ wait_time = 2000;
+ delta = 100;
+ do {
+ writel(0x3f, op_reg_base + EHCI_USBSTS);
+ udelay(delta);
+ wait_time -= delta;
+ val = readl(op_reg_base + EHCI_USBSTS);
+ if ((val == ~(u32)0) || (val & EHCI_USBSTS_HALTED)) {
+ break;
+ }
+ } while (wait_time > 0);
+ }
+ writel(0, op_reg_base + EHCI_USBINTR);
+ writel(0x3f, op_reg_base + EHCI_USBSTS);
+
+ iounmap(base);
+
+ return;
+}
+
+
+
+static void __devinit quirk_usb_early_handoff(struct pci_dev *pdev)
+{
+ if (pdev->class == PCI_CLASS_SERIAL_USB_UHCI)
+ quirk_usb_handoff_uhci(pdev);
+ else if (pdev->class == PCI_CLASS_SERIAL_USB_OHCI)
+ quirk_usb_handoff_ohci(pdev);
+ else if (pdev->class == PCI_CLASS_SERIAL_USB_EHCI)
+ quirk_usb_disable_ehci(pdev);
+}
+DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, quirk_usb_early_handoff);
diff --git a/drivers/usb/host/sl811-hcd.c b/drivers/usb/host/sl811-hcd.c
index d42a15d10a46..5607c0ae6835 100644
--- a/drivers/usb/host/sl811-hcd.c
+++ b/drivers/usb/host/sl811-hcd.c
@@ -54,6 +54,7 @@
#include <linux/interrupt.h>
#include <linux/usb.h>
#include <linux/usb_sl811.h>
+#include <linux/platform_device.h>
#include <asm/io.h>
#include <asm/irq.h>
@@ -818,7 +819,7 @@ static int sl811h_urb_enqueue(
struct usb_hcd *hcd,
struct usb_host_endpoint *hep,
struct urb *urb,
- unsigned mem_flags
+ gfp_t mem_flags
) {
struct sl811 *sl811 = hcd_to_sl811(hcd);
struct usb_device *udev = urb->dev;
@@ -1363,7 +1364,7 @@ error:
#ifdef CONFIG_PM
static int
-sl811h_hub_suspend(struct usb_hcd *hcd)
+sl811h_bus_suspend(struct usb_hcd *hcd)
{
// SOFs off
DBG("%s\n", __FUNCTION__);
@@ -1371,7 +1372,7 @@ sl811h_hub_suspend(struct usb_hcd *hcd)
}
static int
-sl811h_hub_resume(struct usb_hcd *hcd)
+sl811h_bus_resume(struct usb_hcd *hcd)
{
// SOFs on
DBG("%s\n", __FUNCTION__);
@@ -1380,8 +1381,8 @@ sl811h_hub_resume(struct usb_hcd *hcd)
#else
-#define sl811h_hub_suspend NULL
-#define sl811h_hub_resume NULL
+#define sl811h_bus_suspend NULL
+#define sl811h_bus_resume NULL
#endif
@@ -1623,8 +1624,8 @@ static struct hc_driver sl811h_hc_driver = {
*/
.hub_status_data = sl811h_hub_status_data,
.hub_control = sl811h_hub_control,
- .hub_suspend = sl811h_hub_suspend,
- .hub_resume = sl811h_hub_resume,
+ .bus_suspend = sl811h_bus_suspend,
+ .bus_resume = sl811h_bus_resume,
};
/*-------------------------------------------------------------------------*/
@@ -1784,17 +1785,14 @@ sl811h_probe(struct device *dev)
*/
static int
-sl811h_suspend(struct device *dev, pm_message_t state, u32 phase)
+sl811h_suspend(struct device *dev, pm_message_t state)
{
struct usb_hcd *hcd = dev_get_drvdata(dev);
struct sl811 *sl811 = hcd_to_sl811(hcd);
int retval = 0;
- if (phase != SUSPEND_POWER_DOWN)
- return retval;
-
if (state.event == PM_EVENT_FREEZE)
- retval = sl811h_hub_suspend(hcd);
+ retval = sl811h_bus_suspend(hcd);
else if (state.event == PM_EVENT_SUSPEND)
port_power(sl811, 0);
if (retval == 0)
@@ -1803,14 +1801,11 @@ sl811h_suspend(struct device *dev, pm_message_t state, u32 phase)
}
static int
-sl811h_resume(struct device *dev, u32 phase)
+sl811h_resume(struct device *dev)
{
struct usb_hcd *hcd = dev_get_drvdata(dev);
struct sl811 *sl811 = hcd_to_sl811(hcd);
- if (phase != RESUME_POWER_ON)
- return 0;
-
/* with no "check to see if VBUS is still powered" board hook,
* let's assume it'd only be powered to enable remote wakeup.
*/
@@ -1822,7 +1817,7 @@ sl811h_resume(struct device *dev, u32 phase)
}
dev->power.power_state = PMSG_ON;
- return sl811h_hub_resume(hcd);
+ return sl811h_bus_resume(hcd);
}
#else
@@ -1837,6 +1832,7 @@ sl811h_resume(struct device *dev, u32 phase)
struct device_driver sl811h_driver = {
.name = (char *) hcd_name,
.bus = &platform_bus_type,
+ .owner = THIS_MODULE,
.probe = sl811h_probe,
.remove = __devexit_p(sl811h_remove),
diff --git a/drivers/usb/host/sl811_cs.c b/drivers/usb/host/sl811_cs.c
index 38aebe361ca1..e73faf831b24 100644
--- a/drivers/usb/host/sl811_cs.c
+++ b/drivers/usb/host/sl811_cs.c
@@ -19,6 +19,7 @@
#include <linux/string.h>
#include <linux/timer.h>
#include <linux/ioport.h>
+#include <linux/platform_device.h>
#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
diff --git a/drivers/usb/host/uhci-debug.c b/drivers/usb/host/uhci-debug.c
index 4538a98b6f9d..151154df37fa 100644
--- a/drivers/usb/host/uhci-debug.c
+++ b/drivers/usb/host/uhci-debug.c
@@ -348,7 +348,6 @@ static int uhci_show_urbp(struct uhci_hcd *uhci, struct urb_priv *urbp, char *bu
if (urbp->urb->status != -EINPROGRESS)
out += sprintf(out, "Status=%d ", urbp->urb->status);
- //out += sprintf(out, "Inserttime=%lx ",urbp->inserttime);
//out += sprintf(out, "FSBRtime=%lx ",urbp->fsbrtime);
count = 0;
@@ -446,11 +445,11 @@ static int uhci_sprint_schedule(struct uhci_hcd *uhci, char *buf, int len)
out += sprintf(out, "Frame List\n");
for (i = 0; i < UHCI_NUMFRAMES; ++i) {
int shown = 0;
- td = uhci->fl->frame_cpu[i];
+ td = uhci->frame_cpu[i];
if (!td)
continue;
- if (td->dma_handle != (dma_addr_t)uhci->fl->frame[i]) {
+ if (td->dma_handle != (dma_addr_t)uhci->frame[i]) {
show_frame_num();
out += sprintf(out, " frame list does not match td->dma_handle!\n");
}
diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c
index 0c024898cbea..d33ce3982a5f 100644
--- a/drivers/usb/host/uhci-hcd.c
+++ b/drivers/usb/host/uhci-hcd.c
@@ -101,37 +101,16 @@ static void uhci_get_current_frame_number(struct uhci_hcd *uhci);
#include "uhci-q.c"
#include "uhci-hub.c"
+extern void uhci_reset_hc(struct pci_dev *pdev, unsigned long base);
+extern int uhci_check_and_reset_hc(struct pci_dev *pdev, unsigned long base);
+
/*
- * Make sure the controller is completely inactive, unable to
- * generate interrupts or do DMA.
+ * Finish up a host controller reset and update the recorded state.
*/
-static void reset_hc(struct uhci_hcd *uhci)
+static void finish_reset(struct uhci_hcd *uhci)
{
int port;
- /* Turn off PIRQ enable and SMI enable. (This also turns off the
- * BIOS's USB Legacy Support.) Turn off all the R/WC bits too.
- */
- pci_write_config_word(to_pci_dev(uhci_dev(uhci)), USBLEGSUP,
- USBLEGSUP_RWC);
-
- /* Reset the HC - this will force us to get a
- * new notification of any already connected
- * ports due to the virtual disconnect that it
- * implies.
- */
- outw(USBCMD_HCRESET, uhci->io_addr + USBCMD);
- mb();
- udelay(5);
- if (inw(uhci->io_addr + USBCMD) & USBCMD_HCRESET)
- dev_warn(uhci_dev(uhci), "HCRESET not completed yet!\n");
-
- /* Just to be safe, disable interrupt requests and
- * make sure the controller is stopped.
- */
- outw(0, uhci->io_addr + USBINTR);
- outw(0, uhci->io_addr + USBCMD);
-
/* HCRESET doesn't affect the Suspend, Reset, and Resume Detect
* bits in the port status and control registers.
* We have to clear them by hand.
@@ -153,7 +132,8 @@ static void reset_hc(struct uhci_hcd *uhci)
*/
static void hc_died(struct uhci_hcd *uhci)
{
- reset_hc(uhci);
+ uhci_reset_hc(to_pci_dev(uhci_dev(uhci)), uhci->io_addr);
+ finish_reset(uhci);
uhci->hc_inaccessible = 1;
}
@@ -163,44 +143,8 @@ static void hc_died(struct uhci_hcd *uhci)
*/
static void check_and_reset_hc(struct uhci_hcd *uhci)
{
- u16 legsup;
- unsigned int cmd, intr;
-
- /*
- * When restarting a suspended controller, we expect all the
- * settings to be the same as we left them:
- *
- * PIRQ and SMI disabled, no R/W bits set in USBLEGSUP;
- * Controller is stopped and configured with EGSM set;
- * No interrupts enabled except possibly Resume Detect.
- *
- * If any of these conditions are violated we do a complete reset.
- */
- pci_read_config_word(to_pci_dev(uhci_dev(uhci)), USBLEGSUP, &legsup);
- if (legsup & ~(USBLEGSUP_RO | USBLEGSUP_RWC)) {
- dev_dbg(uhci_dev(uhci), "%s: legsup = 0x%04x\n",
- __FUNCTION__, legsup);
- goto reset_needed;
- }
-
- cmd = inw(uhci->io_addr + USBCMD);
- if ((cmd & USBCMD_RS) || !(cmd & USBCMD_CF) || !(cmd & USBCMD_EGSM)) {
- dev_dbg(uhci_dev(uhci), "%s: cmd = 0x%04x\n",
- __FUNCTION__, cmd);
- goto reset_needed;
- }
-
- intr = inw(uhci->io_addr + USBINTR);
- if (intr & (~USBINTR_RESUME)) {
- dev_dbg(uhci_dev(uhci), "%s: intr = 0x%04x\n",
- __FUNCTION__, intr);
- goto reset_needed;
- }
- return;
-
-reset_needed:
- dev_dbg(uhci_dev(uhci), "Performing full reset\n");
- reset_hc(uhci);
+ if (uhci_check_and_reset_hc(to_pci_dev(uhci_dev(uhci)), uhci->io_addr))
+ finish_reset(uhci);
}
/*
@@ -212,13 +156,13 @@ static void configure_hc(struct uhci_hcd *uhci)
outb(USBSOF_DEFAULT, uhci->io_addr + USBSOF);
/* Store the frame list base address */
- outl(uhci->fl->dma_handle, uhci->io_addr + USBFLBASEADD);
+ outl(uhci->frame_dma_handle, uhci->io_addr + USBFLBASEADD);
/* Set the current frame number */
outw(uhci->frame_number, uhci->io_addr + USBFRNUM);
- /* Mark controller as running before we enable interrupts */
- uhci_to_hcd(uhci)->state = HC_STATE_RUNNING;
+ /* Mark controller as not halted before we enable interrupts */
+ uhci_to_hcd(uhci)->state = HC_STATE_SUSPENDED;
mb();
/* Enable PIRQ */
@@ -319,6 +263,7 @@ __acquires(uhci->lock)
static void start_rh(struct uhci_hcd *uhci)
{
+ uhci_to_hcd(uhci)->state = HC_STATE_RUNNING;
uhci->is_stopped = 0;
smp_wmb();
@@ -437,36 +382,21 @@ static void release_uhci(struct uhci_hcd *uhci)
int i;
for (i = 0; i < UHCI_NUM_SKELQH; i++)
- if (uhci->skelqh[i]) {
- uhci_free_qh(uhci, uhci->skelqh[i]);
- uhci->skelqh[i] = NULL;
- }
+ uhci_free_qh(uhci, uhci->skelqh[i]);
- if (uhci->term_td) {
- uhci_free_td(uhci, uhci->term_td);
- uhci->term_td = NULL;
- }
+ uhci_free_td(uhci, uhci->term_td);
- if (uhci->qh_pool) {
- dma_pool_destroy(uhci->qh_pool);
- uhci->qh_pool = NULL;
- }
+ dma_pool_destroy(uhci->qh_pool);
- if (uhci->td_pool) {
- dma_pool_destroy(uhci->td_pool);
- uhci->td_pool = NULL;
- }
+ dma_pool_destroy(uhci->td_pool);
- if (uhci->fl) {
- dma_free_coherent(uhci_dev(uhci), sizeof(*uhci->fl),
- uhci->fl, uhci->fl->dma_handle);
- uhci->fl = NULL;
- }
+ kfree(uhci->frame_cpu);
- if (uhci->dentry) {
- debugfs_remove(uhci->dentry);
- uhci->dentry = NULL;
- }
+ dma_free_coherent(uhci_dev(uhci),
+ UHCI_NUMFRAMES * sizeof(*uhci->frame),
+ uhci->frame, uhci->frame_dma_handle);
+
+ debugfs_remove(uhci->dentry);
}
static int uhci_reset(struct usb_hcd *hcd)
@@ -545,7 +475,6 @@ static int uhci_start(struct usb_hcd *hcd)
struct uhci_hcd *uhci = hcd_to_uhci(hcd);
int retval = -EBUSY;
int i;
- dma_addr_t dma_handle;
struct dentry *dentry;
hcd->uses_new_polling = 1;
@@ -579,17 +508,23 @@ static int uhci_start(struct usb_hcd *hcd)
init_waitqueue_head(&uhci->waitqh);
- uhci->fl = dma_alloc_coherent(uhci_dev(uhci), sizeof(*uhci->fl),
- &dma_handle, 0);
- if (!uhci->fl) {
+ uhci->frame = dma_alloc_coherent(uhci_dev(uhci),
+ UHCI_NUMFRAMES * sizeof(*uhci->frame),
+ &uhci->frame_dma_handle, 0);
+ if (!uhci->frame) {
dev_err(uhci_dev(uhci), "unable to allocate "
"consistent memory for frame list\n");
- goto err_alloc_fl;
+ goto err_alloc_frame;
}
+ memset(uhci->frame, 0, UHCI_NUMFRAMES * sizeof(*uhci->frame));
- memset((void *)uhci->fl, 0, sizeof(*uhci->fl));
-
- uhci->fl->dma_handle = dma_handle;
+ uhci->frame_cpu = kcalloc(UHCI_NUMFRAMES, sizeof(*uhci->frame_cpu),
+ GFP_KERNEL);
+ if (!uhci->frame_cpu) {
+ dev_err(uhci_dev(uhci), "unable to allocate "
+ "memory for frame pointers\n");
+ goto err_alloc_frame_cpu;
+ }
uhci->td_pool = dma_pool_create("uhci_td", uhci_dev(uhci),
sizeof(struct uhci_td), 16, 0);
@@ -672,7 +607,7 @@ static int uhci_start(struct usb_hcd *hcd)
irq = 7;
/* Only place we don't use the frame list routines */
- uhci->fl->frame[i] = UHCI_PTR_QH |
+ uhci->frame[i] = UHCI_PTR_QH |
cpu_to_le32(uhci->skelqh[irq]->dma_handle);
}
@@ -690,31 +625,29 @@ static int uhci_start(struct usb_hcd *hcd)
* error exits:
*/
err_alloc_skelqh:
- for (i = 0; i < UHCI_NUM_SKELQH; i++)
- if (uhci->skelqh[i]) {
+ for (i = 0; i < UHCI_NUM_SKELQH; i++) {
+ if (uhci->skelqh[i])
uhci_free_qh(uhci, uhci->skelqh[i]);
- uhci->skelqh[i] = NULL;
- }
+ }
uhci_free_td(uhci, uhci->term_td);
- uhci->term_td = NULL;
err_alloc_term_td:
dma_pool_destroy(uhci->qh_pool);
- uhci->qh_pool = NULL;
err_create_qh_pool:
dma_pool_destroy(uhci->td_pool);
- uhci->td_pool = NULL;
err_create_td_pool:
- dma_free_coherent(uhci_dev(uhci), sizeof(*uhci->fl),
- uhci->fl, uhci->fl->dma_handle);
- uhci->fl = NULL;
+ kfree(uhci->frame_cpu);
+
+err_alloc_frame_cpu:
+ dma_free_coherent(uhci_dev(uhci),
+ UHCI_NUMFRAMES * sizeof(*uhci->frame),
+ uhci->frame, uhci->frame_dma_handle);
-err_alloc_fl:
+err_alloc_frame:
debugfs_remove(uhci->dentry);
- uhci->dentry = NULL;
err_create_debug_entry:
return retval;
@@ -726,7 +659,7 @@ static void uhci_stop(struct usb_hcd *hcd)
spin_lock_irq(&uhci->lock);
if (!uhci->hc_inaccessible)
- reset_hc(uhci);
+ hc_died(uhci);
uhci_scan_schedule(uhci, NULL);
spin_unlock_irq(&uhci->lock);
@@ -774,14 +707,8 @@ static int uhci_suspend(struct usb_hcd *hcd, pm_message_t message)
if (uhci->hc_inaccessible) /* Dead or already suspended */
goto done;
-#ifndef CONFIG_USB_SUSPEND
- /* Otherwise this would never happen */
- suspend_rh(uhci, UHCI_RH_SUSPENDED);
-#endif
-
if (uhci->rh_state > UHCI_RH_SUSPENDED) {
dev_warn(uhci_dev(uhci), "Root hub isn't suspended!\n");
- hcd->state = HC_STATE_RUNNING;
rc = -EBUSY;
goto done;
};
@@ -820,10 +747,6 @@ static int uhci_resume(struct usb_hcd *hcd)
check_and_reset_hc(uhci);
configure_hc(uhci);
-#ifndef CONFIG_USB_SUSPEND
- /* Otherwise this would never happen */
- wakeup_rh(uhci);
-#endif
if (uhci->rh_state == UHCI_RH_RESET)
suspend_rh(uhci, UHCI_RH_SUSPENDED);
@@ -881,8 +804,8 @@ static const struct hc_driver uhci_driver = {
#ifdef CONFIG_PM
.suspend = uhci_suspend,
.resume = uhci_resume,
- .hub_suspend = uhci_rh_suspend,
- .hub_resume = uhci_rh_resume,
+ .bus_suspend = uhci_rh_suspend,
+ .bus_resume = uhci_rh_resume,
#endif
.stop = uhci_stop,
diff --git a/drivers/usb/host/uhci-hcd.h b/drivers/usb/host/uhci-hcd.h
index 282f40b75881..e576db57a926 100644
--- a/drivers/usb/host/uhci-hcd.h
+++ b/drivers/usb/host/uhci-hcd.h
@@ -7,6 +7,7 @@
#define usb_packetid(pipe) (usb_pipein(pipe) ? USB_PID_IN : USB_PID_OUT)
#define PIPE_DEVEP_MASK 0x0007ff00
+
/*
* Universal Host Controller Interface data structures and defines
*/
@@ -82,15 +83,10 @@
#define UHCI_MAX_SOF_NUMBER 2047 /* in an SOF packet */
#define CAN_SCHEDULE_FRAMES 1000 /* how far future frames can be scheduled */
-struct uhci_frame_list {
- __le32 frame[UHCI_NUMFRAMES];
-
- void *frame_cpu[UHCI_NUMFRAMES];
-
- dma_addr_t dma_handle;
-};
-struct urb_priv;
+/*
+ * Queue Headers
+ */
/*
* One role of a QH is to hold a queue of TDs for some endpoint. Each QH is
@@ -116,13 +112,13 @@ struct uhci_qh {
struct urb_priv *urbp;
- struct list_head list; /* P: uhci->frame_list_lock */
- struct list_head remove_list; /* P: uhci->remove_list_lock */
+ struct list_head list;
+ struct list_head remove_list;
} __attribute__((aligned(16)));
/*
* We need a special accessor for the element pointer because it is
- * subject to asynchronous updates by the controller
+ * subject to asynchronous updates by the controller.
*/
static __le32 inline qh_element(struct uhci_qh *qh) {
__le32 element = qh->element;
@@ -131,6 +127,11 @@ static __le32 inline qh_element(struct uhci_qh *qh) {
return element;
}
+
+/*
+ * Transfer Descriptors
+ */
+
/*
* for TD <status>:
*/
@@ -183,17 +184,10 @@ static __le32 inline qh_element(struct uhci_qh *qh) {
*
* That's silly, the hardware doesn't care. The hardware only cares that
* the hardware words are 16-byte aligned, and we can have any amount of
- * sw space after the TD entry as far as I can tell.
- *
- * But let's just go with the documentation, at least for 32-bit machines.
- * On 64-bit machines we probably want to take advantage of the fact that
- * hw doesn't really care about the size of the sw-only area.
- *
- * Alas, not anymore, we have more than 4 words for software, woops.
- * Everything still works tho, surprise! -jerdfelt
+ * sw space after the TD entry.
*
* td->link points to either another TD (not necessarily for the same urb or
- * even the same endpoint), or nothing (PTR_TERM), or a QH (for queued urbs)
+ * even the same endpoint), or nothing (PTR_TERM), or a QH (for queued urbs).
*/
struct uhci_td {
/* Hardware fields */
@@ -205,18 +199,16 @@ struct uhci_td {
/* Software fields */
dma_addr_t dma_handle;
- struct urb *urb;
-
- struct list_head list; /* P: urb->lock */
- struct list_head remove_list; /* P: uhci->td_remove_list_lock */
+ struct list_head list;
+ struct list_head remove_list;
int frame; /* for iso: what frame? */
- struct list_head fl_list; /* P: uhci->frame_list_lock */
+ struct list_head fl_list;
} __attribute__((aligned(16)));
/*
* We need a special accessor for the control/status word because it is
- * subject to asynchronous updates by the controller
+ * subject to asynchronous updates by the controller.
*/
static u32 inline td_status(struct uhci_td *td) {
__le32 status = td->status;
@@ -227,6 +219,10 @@ static u32 inline td_status(struct uhci_td *td) {
/*
+ * Skeleton Queue Headers
+ */
+
+/*
* The UHCI driver places Interrupt, Control and Bulk into QH's both
* to group together TD's for one transfer, and also to faciliate queuing
* of URB's. To make it easy to insert entries into the schedule, we have
@@ -256,15 +252,15 @@ static u32 inline td_status(struct uhci_td *td) {
*
* The terminating QH is used for 2 reasons:
* - To place a terminating TD which is used to workaround a PIIX bug
- * (see Intel errata for explanation)
+ * (see Intel errata for explanation), and
* - To loop back to the full-speed control queue for full-speed bandwidth
- * reclamation
+ * reclamation.
*
* Isochronous transfers are stored before the start of the skeleton
* schedule and don't use QH's. While the UHCI spec doesn't forbid the
- * use of QH's for Isochronous, it doesn't use them either. Since we don't
- * need to use them either, we follow the spec diagrams in hope that it'll
- * be more compatible with future UHCI implementations.
+ * use of QH's for Isochronous, it doesn't use them either. And the spec
+ * says that queues never advance on an error completion status, which
+ * makes them totally unsuitable for Isochronous transfers.
*/
#define UHCI_NUM_SKELQH 12
@@ -314,8 +310,13 @@ static inline int __interval_to_skel(int interval)
return 0; /* int128 for 128-255 ms (Max.) */
}
+
+/*
+ * The UHCI controller and root hub
+ */
+
/*
- * States for the root hub.
+ * States for the root hub:
*
* To prevent "bouncing" in the presence of electrical noise,
* when there are no devices attached we delay for 1 second in the
@@ -326,7 +327,7 @@ static inline int __interval_to_skel(int interval)
*/
enum uhci_rh_state {
/* In the following states the HC must be halted.
- * These two must come first */
+ * These two must come first. */
UHCI_RH_RESET,
UHCI_RH_SUSPENDED,
@@ -338,13 +339,13 @@ enum uhci_rh_state {
UHCI_RH_SUSPENDING,
/* In the following states it's an error if the HC is halted.
- * These two must come last */
+ * These two must come last. */
UHCI_RH_RUNNING, /* The normal state */
UHCI_RH_RUNNING_NODEVS, /* Running with no devices attached */
};
/*
- * This describes the full uhci information.
+ * The full UHCI controller information:
*/
struct uhci_hcd {
@@ -361,7 +362,11 @@ struct uhci_hcd {
struct uhci_qh *skelqh[UHCI_NUM_SKELQH]; /* Skeleton QH's */
spinlock_t lock;
- struct uhci_frame_list *fl; /* P: uhci->lock */
+
+ dma_addr_t frame_dma_handle; /* Hardware frame list */
+ __le32 *frame;
+ void **frame_cpu; /* CPU's frame list */
+
int fsbr; /* Full-speed bandwidth reclamation */
unsigned long fsbrtimeout; /* FSBR delay */
@@ -385,22 +390,22 @@ struct uhci_hcd {
unsigned long ports_timeout; /* Time to stop signalling */
/* Main list of URB's currently controlled by this HC */
- struct list_head urb_list; /* P: uhci->lock */
+ struct list_head urb_list;
/* List of QH's that are done, but waiting to be unlinked (race) */
- struct list_head qh_remove_list; /* P: uhci->lock */
+ struct list_head qh_remove_list;
unsigned int qh_remove_age; /* Age in frames */
/* List of TD's that are done, but waiting to be freed (race) */
- struct list_head td_remove_list; /* P: uhci->lock */
+ struct list_head td_remove_list;
unsigned int td_remove_age; /* Age in frames */
/* List of asynchronously unlinked URB's */
- struct list_head urb_remove_list; /* P: uhci->lock */
+ struct list_head urb_remove_list;
unsigned int urb_remove_age; /* Age in frames */
/* List of URB's awaiting completion callback */
- struct list_head complete_list; /* P: uhci->lock */
+ struct list_head complete_list;
int rh_numports; /* Number of root-hub ports */
@@ -419,13 +424,17 @@ static inline struct usb_hcd *uhci_to_hcd(struct uhci_hcd *uhci)
#define uhci_dev(u) (uhci_to_hcd(u)->self.controller)
+
+/*
+ * Private per-URB data
+ */
struct urb_priv {
struct list_head urb_list;
struct urb *urb;
struct uhci_qh *qh; /* QH for this URB */
- struct list_head td_list; /* P: urb->lock */
+ struct list_head td_list;
unsigned fsbr : 1; /* URB turned on FSBR */
unsigned fsbr_timeout : 1; /* URB timed out on FSBR */
@@ -434,12 +443,12 @@ struct urb_priv {
/* a control transfer, retrigger */
/* the status phase */
- unsigned long inserttime; /* In jiffies */
unsigned long fsbrtime; /* In jiffies */
- struct list_head queue_list; /* P: uhci->frame_list_lock */
+ struct list_head queue_list;
};
+
/*
* Locking in uhci.c
*
@@ -459,6 +468,5 @@ struct urb_priv {
#define PCI_VENDOR_ID_GENESYS 0x17a0
#define PCI_DEVICE_ID_GL880S_UHCI 0x8083
-#define PCI_DEVICE_ID_GL880S_EHCI 0x8084
#endif
diff --git a/drivers/usb/host/uhci-q.c b/drivers/usb/host/uhci-q.c
index ea0d168a8c67..7e46887d9e12 100644
--- a/drivers/usb/host/uhci-q.c
+++ b/drivers/usb/host/uhci-q.c
@@ -89,10 +89,10 @@ static void uhci_insert_td_frame_list(struct uhci_hcd *uhci, struct uhci_td *td,
td->frame = framenum;
/* Is there a TD already mapped there? */
- if (uhci->fl->frame_cpu[framenum]) {
+ if (uhci->frame_cpu[framenum]) {
struct uhci_td *ftd, *ltd;
- ftd = uhci->fl->frame_cpu[framenum];
+ ftd = uhci->frame_cpu[framenum];
ltd = list_entry(ftd->fl_list.prev, struct uhci_td, fl_list);
list_add_tail(&td->fl_list, &ftd->fl_list);
@@ -101,29 +101,32 @@ static void uhci_insert_td_frame_list(struct uhci_hcd *uhci, struct uhci_td *td,
wmb();
ltd->link = cpu_to_le32(td->dma_handle);
} else {
- td->link = uhci->fl->frame[framenum];
+ td->link = uhci->frame[framenum];
wmb();
- uhci->fl->frame[framenum] = cpu_to_le32(td->dma_handle);
- uhci->fl->frame_cpu[framenum] = td;
+ uhci->frame[framenum] = cpu_to_le32(td->dma_handle);
+ uhci->frame_cpu[framenum] = td;
}
}
-static void uhci_remove_td(struct uhci_hcd *uhci, struct uhci_td *td)
+static inline void uhci_remove_td_frame_list(struct uhci_hcd *uhci,
+ struct uhci_td *td)
{
/* If it's not inserted, don't remove it */
- if (td->frame == -1 && list_empty(&td->fl_list))
+ if (td->frame == -1) {
+ WARN_ON(!list_empty(&td->fl_list));
return;
+ }
- if (td->frame != -1 && uhci->fl->frame_cpu[td->frame] == td) {
+ if (uhci->frame_cpu[td->frame] == td) {
if (list_empty(&td->fl_list)) {
- uhci->fl->frame[td->frame] = td->link;
- uhci->fl->frame_cpu[td->frame] = NULL;
+ uhci->frame[td->frame] = td->link;
+ uhci->frame_cpu[td->frame] = NULL;
} else {
struct uhci_td *ntd;
ntd = list_entry(td->fl_list.next, struct uhci_td, fl_list);
- uhci->fl->frame[td->frame] = cpu_to_le32(ntd->dma_handle);
- uhci->fl->frame_cpu[td->frame] = ntd;
+ uhci->frame[td->frame] = cpu_to_le32(ntd->dma_handle);
+ uhci->frame_cpu[td->frame] = ntd;
}
} else {
struct uhci_td *ptd;
@@ -132,13 +135,20 @@ static void uhci_remove_td(struct uhci_hcd *uhci, struct uhci_td *td)
ptd->link = td->link;
}
- wmb();
- td->link = UHCI_PTR_TERM;
-
list_del_init(&td->fl_list);
td->frame = -1;
}
+static void unlink_isochronous_tds(struct uhci_hcd *uhci, struct urb *urb)
+{
+ struct urb_priv *urbp = (struct urb_priv *) urb->hcpriv;
+ struct uhci_td *td;
+
+ list_for_each_entry(td, &urbp->td_list, list)
+ uhci_remove_td_frame_list(uhci, td);
+ wmb();
+}
+
/*
* Inserts a td list into qh.
*/
@@ -443,7 +453,6 @@ static struct urb_priv *uhci_alloc_urb_priv(struct uhci_hcd *uhci, struct urb *u
memset((void *)urbp, 0, sizeof(*urbp));
- urbp->inserttime = jiffies;
urbp->fsbrtime = jiffies;
urbp->urb = urb;
@@ -462,8 +471,6 @@ static void uhci_add_td_to_urb(struct urb *urb, struct uhci_td *td)
{
struct urb_priv *urbp = (struct urb_priv *)urb->hcpriv;
- td->urb = urb;
-
list_add_tail(&td->list, &urbp->td_list);
}
@@ -473,8 +480,6 @@ static void uhci_remove_td_from_urb(struct uhci_td *td)
return;
list_del_init(&td->list);
-
- td->urb = NULL;
}
static void uhci_destroy_urb_priv(struct uhci_hcd *uhci, struct urb *urb)
@@ -503,7 +508,6 @@ static void uhci_destroy_urb_priv(struct uhci_hcd *uhci, struct urb *urb)
list_for_each_entry_safe(td, tmp, &urbp->td_list, list) {
uhci_remove_td_from_urb(td);
- uhci_remove_td(uhci, td);
list_add(&td->remove_list, &uhci->td_remove_list);
}
@@ -1073,6 +1077,7 @@ static int uhci_submit_isochronous(struct uhci_hcd *uhci, struct urb *urb)
struct uhci_td *td;
int i, ret, frame;
int status, destination;
+ struct urb_priv *urbp = (struct urb_priv *) urb->hcpriv;
status = TD_CTRL_ACTIVE | TD_CTRL_IOS;
destination = (urb->pipe & PIPE_DEVEP_MASK) | usb_packetid(urb->pipe);
@@ -1081,11 +1086,7 @@ static int uhci_submit_isochronous(struct uhci_hcd *uhci, struct urb *urb)
if (ret)
return ret;
- frame = urb->start_frame;
- for (i = 0; i < urb->number_of_packets; i++, frame += urb->interval) {
- if (!urb->iso_frame_desc[i].length)
- continue;
-
+ for (i = 0; i < urb->number_of_packets; i++) {
td = uhci_alloc_td(uhci);
if (!td)
return -ENOMEM;
@@ -1096,8 +1097,12 @@ static int uhci_submit_isochronous(struct uhci_hcd *uhci, struct urb *urb)
if (i + 1 >= urb->number_of_packets)
td->status |= cpu_to_le32(TD_CTRL_IOC);
+ }
+ frame = urb->start_frame;
+ list_for_each_entry(td, &urbp->td_list, list) {
uhci_insert_td_frame_list(uhci, td, frame);
+ frame += urb->interval;
}
return -EINPROGRESS;
@@ -1110,7 +1115,7 @@ static int uhci_result_isochronous(struct uhci_hcd *uhci, struct urb *urb)
int status;
int i, ret = 0;
- urb->actual_length = 0;
+ urb->actual_length = urb->error_count = 0;
i = 0;
list_for_each_entry(td, &urbp->td_list, list) {
@@ -1134,6 +1139,7 @@ static int uhci_result_isochronous(struct uhci_hcd *uhci, struct urb *urb)
i++;
}
+ unlink_isochronous_tds(uhci, urb);
return ret;
}
@@ -1164,7 +1170,7 @@ static struct urb *uhci_find_urb_ep(struct uhci_hcd *uhci, struct urb *urb)
static int uhci_urb_enqueue(struct usb_hcd *hcd,
struct usb_host_endpoint *ep,
- struct urb *urb, unsigned mem_flags)
+ struct urb *urb, gfp_t mem_flags)
{
int ret;
struct uhci_hcd *uhci = hcd_to_uhci(hcd);
@@ -1366,6 +1372,8 @@ static int uhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb)
goto done;
list_del_init(&urbp->urb_list);
+ if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS)
+ unlink_isochronous_tds(uhci, urb);
uhci_unlink_generic(uhci, urb);
uhci_get_current_frame_number(uhci);
diff --git a/drivers/usb/image/mdc800.c b/drivers/usb/image/mdc800.c
index a330a4b50e16..1d973bcf56aa 100644
--- a/drivers/usb/image/mdc800.c
+++ b/drivers/usb/image/mdc800.c
@@ -425,9 +425,8 @@ static void mdc800_usb_download_notify (struct urb *urb, struct pt_regs *res)
static struct usb_driver mdc800_usb_driver;
static struct file_operations mdc800_device_ops;
static struct usb_class_driver mdc800_class = {
- .name = "usb/mdc800%d",
+ .name = "mdc800%d",
.fops = &mdc800_device_ops,
- .mode = S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP,
.minor_base = MDC800_DEVICE_MINOR_BASE,
};
@@ -976,13 +975,13 @@ static struct usb_driver mdc800_usb_driver =
Init and Cleanup this driver (Main Functions)
*************************************************************************/
-#define try(A) if (!(A)) goto cleanup_on_fail;
-
static int __init usb_mdc800_init (void)
{
int retval = -ENODEV;
/* Allocate Memory */
- try (mdc800=kmalloc (sizeof (struct mdc800_data), GFP_KERNEL));
+ mdc800=kmalloc (sizeof (struct mdc800_data), GFP_KERNEL);
+ if (!mdc800)
+ goto cleanup_on_fail;
memset(mdc800, 0, sizeof(struct mdc800_data));
mdc800->dev = NULL;
@@ -998,13 +997,25 @@ static int __init usb_mdc800_init (void)
mdc800->downloaded = 0;
mdc800->written = 0;
- try (mdc800->irq_urb_buffer=kmalloc (8, GFP_KERNEL));
- try (mdc800->write_urb_buffer=kmalloc (8, GFP_KERNEL));
- try (mdc800->download_urb_buffer=kmalloc (64, GFP_KERNEL));
+ mdc800->irq_urb_buffer=kmalloc (8, GFP_KERNEL);
+ if (!mdc800->irq_urb_buffer)
+ goto cleanup_on_fail;
+ mdc800->write_urb_buffer=kmalloc (8, GFP_KERNEL);
+ if (!mdc800->write_urb_buffer)
+ goto cleanup_on_fail;
+ mdc800->download_urb_buffer=kmalloc (64, GFP_KERNEL);
+ if (!mdc800->download_urb_buffer)
+ goto cleanup_on_fail;
- try (mdc800->irq_urb=usb_alloc_urb (0, GFP_KERNEL));
- try (mdc800->download_urb=usb_alloc_urb (0, GFP_KERNEL));
- try (mdc800->write_urb=usb_alloc_urb (0, GFP_KERNEL));
+ mdc800->irq_urb=usb_alloc_urb (0, GFP_KERNEL);
+ if (!mdc800->irq_urb)
+ goto cleanup_on_fail;
+ mdc800->download_urb=usb_alloc_urb (0, GFP_KERNEL);
+ if (!mdc800->download_urb)
+ goto cleanup_on_fail;
+ mdc800->write_urb=usb_alloc_urb (0, GFP_KERNEL);
+ if (!mdc800->write_urb)
+ goto cleanup_on_fail;
/* Register the driver */
retval = usb_register(&mdc800_usb_driver);
diff --git a/drivers/usb/image/microtek.c b/drivers/usb/image/microtek.c
index c84e1486054f..c89d0769b3da 100644
--- a/drivers/usb/image/microtek.c
+++ b/drivers/usb/image/microtek.c
@@ -773,11 +773,10 @@ static int mts_usb_probe(struct usb_interface *intf,
}
- new_desc = kmalloc(sizeof(struct mts_desc), GFP_KERNEL);
+ new_desc = kzalloc(sizeof(struct mts_desc), GFP_KERNEL);
if (!new_desc)
goto out;
- memset(new_desc, 0, sizeof(*new_desc));
new_desc->urb = usb_alloc_urb(0, GFP_KERNEL);
if (!new_desc->urb)
goto out_kfree;
diff --git a/drivers/usb/input/acecad.c b/drivers/usb/input/acecad.c
index 74f8760d7c07..a32558b4048e 100644
--- a/drivers/usb/input/acecad.c
+++ b/drivers/usb/input/acecad.c
@@ -53,7 +53,7 @@ struct usb_acecad {
char name[128];
char phys[64];
struct usb_device *usbdev;
- struct input_dev dev;
+ struct input_dev *input;
struct urb *irq;
signed char *data;
@@ -64,7 +64,7 @@ static void usb_acecad_irq(struct urb *urb, struct pt_regs *regs)
{
struct usb_acecad *acecad = urb->context;
unsigned char *data = acecad->data;
- struct input_dev *dev = &acecad->dev;
+ struct input_dev *dev = acecad->input;
int prox, status;
switch (urb->status) {
@@ -135,8 +135,8 @@ static int usb_acecad_probe(struct usb_interface *intf, const struct usb_device_
struct usb_host_interface *interface = intf->cur_altsetting;
struct usb_endpoint_descriptor *endpoint;
struct usb_acecad *acecad;
+ struct input_dev *input_dev;
int pipe, maxp;
- char path[64];
if (interface->desc.bNumEndpoints != 1)
return -ENODEV;
@@ -153,8 +153,9 @@ static int usb_acecad_probe(struct usb_interface *intf, const struct usb_device_
maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe));
acecad = kzalloc(sizeof(struct usb_acecad), GFP_KERNEL);
- if (!acecad)
- return -ENOMEM;
+ input_dev = input_allocate_device();
+ if (!acecad || !input_dev)
+ goto fail1;
acecad->data = usb_buffer_alloc(dev, 8, SLAB_KERNEL, &acecad->data_dma);
if (!acecad->data)
@@ -164,6 +165,9 @@ static int usb_acecad_probe(struct usb_interface *intf, const struct usb_device_
if (!acecad->irq)
goto fail2;
+ acecad->usbdev = dev;
+ acecad->input = input_dev;
+
if (dev->manufacturer)
strlcpy(acecad->name, dev->manufacturer, sizeof(acecad->name));
@@ -173,48 +177,48 @@ static int usb_acecad_probe(struct usb_interface *intf, const struct usb_device_
strlcat(acecad->name, dev->product, sizeof(acecad->name));
}
- usb_make_path(dev, path, sizeof(path));
- snprintf(acecad->phys, sizeof(acecad->phys), "%s/input0", path);
+ usb_make_path(dev, acecad->phys, sizeof(acecad->phys));
+ strlcat(acecad->phys, "/input0", sizeof(acecad->phys));
- acecad->usbdev = dev;
+ input_dev->name = acecad->name;
+ input_dev->phys = acecad->phys;
+ usb_to_input_id(dev, &input_dev->id);
+ input_dev->cdev.dev = &intf->dev;
+ input_dev->private = acecad;
- acecad->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
- acecad->dev.absbit[0] = BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_PRESSURE);
- acecad->dev.keybit[LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE);
- acecad->dev.keybit[LONG(BTN_DIGI)] = BIT(BTN_TOOL_PEN) |BIT(BTN_TOUCH) | BIT(BTN_STYLUS) | BIT(BTN_STYLUS2);
+ input_dev->open = usb_acecad_open;
+ input_dev->close = usb_acecad_close;
+
+ input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+ input_dev->absbit[0] = BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_PRESSURE);
+ input_dev->keybit[LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE);
+ input_dev->keybit[LONG(BTN_DIGI)] = BIT(BTN_TOOL_PEN) |BIT(BTN_TOUCH) | BIT(BTN_STYLUS) | BIT(BTN_STYLUS2);
switch (id->driver_info) {
case 0:
- acecad->dev.absmax[ABS_X] = 5000;
- acecad->dev.absmax[ABS_Y] = 3750;
- acecad->dev.absmax[ABS_PRESSURE] = 512;
+ input_dev->absmax[ABS_X] = 5000;
+ input_dev->absmax[ABS_Y] = 3750;
+ input_dev->absmax[ABS_PRESSURE] = 512;
if (!strlen(acecad->name))
snprintf(acecad->name, sizeof(acecad->name),
"USB Acecad Flair Tablet %04x:%04x",
- dev->descriptor.idVendor, dev->descriptor.idProduct);
+ le16_to_cpu(dev->descriptor.idVendor),
+ le16_to_cpu(dev->descriptor.idProduct));
break;
case 1:
- acecad->dev.absmax[ABS_X] = 3000;
- acecad->dev.absmax[ABS_Y] = 2250;
- acecad->dev.absmax[ABS_PRESSURE] = 1024;
+ input_dev->absmax[ABS_X] = 3000;
+ input_dev->absmax[ABS_Y] = 2250;
+ input_dev->absmax[ABS_PRESSURE] = 1024;
if (!strlen(acecad->name))
snprintf(acecad->name, sizeof(acecad->name),
"USB Acecad 302 Tablet %04x:%04x",
- dev->descriptor.idVendor, dev->descriptor.idProduct);
+ le16_to_cpu(dev->descriptor.idVendor),
+ le16_to_cpu(dev->descriptor.idProduct));
break;
}
- acecad->dev.absfuzz[ABS_X] = 4;
- acecad->dev.absfuzz[ABS_Y] = 4;
-
- acecad->dev.private = acecad;
- acecad->dev.open = usb_acecad_open;
- acecad->dev.close = usb_acecad_close;
-
- acecad->dev.name = acecad->name;
- acecad->dev.phys = acecad->phys;
- usb_to_input_id(dev, &acecad->dev.id);
- acecad->dev.dev = &intf->dev;
+ input_dev->absfuzz[ABS_X] = 4;
+ input_dev->absfuzz[ABS_Y] = 4;
usb_fill_int_urb(acecad->irq, dev, pipe,
acecad->data, maxp > 8 ? 8 : maxp,
@@ -222,17 +226,15 @@ static int usb_acecad_probe(struct usb_interface *intf, const struct usb_device_
acecad->irq->transfer_dma = acecad->data_dma;
acecad->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
- input_register_device(&acecad->dev);
-
- printk(KERN_INFO "input: %s with packet size %d on %s\n",
- acecad->name, maxp, path);
+ input_register_device(acecad->input);
usb_set_intfdata(intf, acecad);
return 0;
fail2: usb_buffer_free(dev, 8, acecad->data, acecad->data_dma);
- fail1: kfree(acecad);
+ fail1: input_free_device(input_dev);
+ kfree(acecad);
return -ENOMEM;
}
@@ -243,7 +245,7 @@ static void usb_acecad_disconnect(struct usb_interface *intf)
usb_set_intfdata(intf, NULL);
if (acecad) {
usb_kill_urb(acecad->irq);
- input_unregister_device(&acecad->dev);
+ input_unregister_device(acecad->input);
usb_free_urb(acecad->irq);
usb_buffer_free(interface_to_usbdev(intf), 10, acecad->data, acecad->data_dma);
kfree(acecad);
diff --git a/drivers/usb/input/aiptek.c b/drivers/usb/input/aiptek.c
index cd0cbfe20723..1c3b472a3bca 100644
--- a/drivers/usb/input/aiptek.c
+++ b/drivers/usb/input/aiptek.c
@@ -317,7 +317,7 @@ struct aiptek_settings {
};
struct aiptek {
- struct input_dev inputdev; /* input device struct */
+ struct input_dev *inputdev; /* input device struct */
struct usb_device *usbdev; /* usb device struct */
struct urb *urb; /* urb for incoming reports */
dma_addr_t data_dma; /* our dma stuffage */
@@ -402,7 +402,7 @@ static void aiptek_irq(struct urb *urb, struct pt_regs *regs)
{
struct aiptek *aiptek = urb->context;
unsigned char *data = aiptek->data;
- struct input_dev *inputdev = &aiptek->inputdev;
+ struct input_dev *inputdev = aiptek->inputdev;
int jitterable = 0;
int retval, macro, x, y, z, left, right, middle, p, dv, tip, bs, pck;
@@ -955,20 +955,20 @@ static int aiptek_program_tablet(struct aiptek *aiptek)
/* Query getXextension */
if ((ret = aiptek_query(aiptek, 0x01, 0x00)) < 0)
return ret;
- aiptek->inputdev.absmin[ABS_X] = 0;
- aiptek->inputdev.absmax[ABS_X] = ret - 1;
+ aiptek->inputdev->absmin[ABS_X] = 0;
+ aiptek->inputdev->absmax[ABS_X] = ret - 1;
/* Query getYextension */
if ((ret = aiptek_query(aiptek, 0x01, 0x01)) < 0)
return ret;
- aiptek->inputdev.absmin[ABS_Y] = 0;
- aiptek->inputdev.absmax[ABS_Y] = ret - 1;
+ aiptek->inputdev->absmin[ABS_Y] = 0;
+ aiptek->inputdev->absmax[ABS_Y] = ret - 1;
/* Query getPressureLevels */
if ((ret = aiptek_query(aiptek, 0x08, 0x00)) < 0)
return ret;
- aiptek->inputdev.absmin[ABS_PRESSURE] = 0;
- aiptek->inputdev.absmax[ABS_PRESSURE] = ret - 1;
+ aiptek->inputdev->absmin[ABS_PRESSURE] = 0;
+ aiptek->inputdev->absmax[ABS_PRESSURE] = ret - 1;
/* Depending on whether we are in absolute or relative mode, we will
* do a switchToTablet(absolute) or switchToMouse(relative) command.
@@ -1025,8 +1025,8 @@ static ssize_t show_tabletSize(struct device *dev, struct device_attribute *attr
return 0;
return snprintf(buf, PAGE_SIZE, "%dx%d\n",
- aiptek->inputdev.absmax[ABS_X] + 1,
- aiptek->inputdev.absmax[ABS_Y] + 1);
+ aiptek->inputdev->absmax[ABS_X] + 1,
+ aiptek->inputdev->absmax[ABS_Y] + 1);
}
/* These structs define the sysfs files, param #1 is the name of the
@@ -1048,7 +1048,7 @@ static ssize_t show_tabletProductId(struct device *dev, struct device_attribute
return 0;
return snprintf(buf, PAGE_SIZE, "0x%04x\n",
- aiptek->inputdev.id.product);
+ aiptek->inputdev->id.product);
}
static DEVICE_ATTR(product_id, S_IRUGO, show_tabletProductId, NULL);
@@ -1063,7 +1063,7 @@ static ssize_t show_tabletVendorId(struct device *dev, struct device_attribute *
if (aiptek == NULL)
return 0;
- return snprintf(buf, PAGE_SIZE, "0x%04x\n", aiptek->inputdev.id.vendor);
+ return snprintf(buf, PAGE_SIZE, "0x%04x\n", aiptek->inputdev->id.vendor);
}
static DEVICE_ATTR(vendor_id, S_IRUGO, show_tabletVendorId, NULL);
@@ -1977,7 +1977,6 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id)
struct input_dev *inputdev;
struct input_handle *inputhandle;
struct list_head *node, *next;
- char path[64 + 1];
int i;
int speeds[] = { 0,
AIPTEK_PROGRAMMABLE_DELAY_50,
@@ -1996,24 +1995,26 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id)
*/
speeds[0] = programmableDelay;
- if ((aiptek = kmalloc(sizeof(struct aiptek), GFP_KERNEL)) == NULL)
- return -ENOMEM;
- memset(aiptek, 0, sizeof(struct aiptek));
+ aiptek = kzalloc(sizeof(struct aiptek), GFP_KERNEL);
+ inputdev = input_allocate_device();
+ if (!aiptek || !inputdev)
+ goto fail1;
aiptek->data = usb_buffer_alloc(usbdev, AIPTEK_PACKET_LENGTH,
SLAB_ATOMIC, &aiptek->data_dma);
- if (aiptek->data == NULL) {
- kfree(aiptek);
- return -ENOMEM;
- }
+ if (!aiptek->data)
+ goto fail1;
aiptek->urb = usb_alloc_urb(0, GFP_KERNEL);
- if (aiptek->urb == NULL) {
- usb_buffer_free(usbdev, AIPTEK_PACKET_LENGTH, aiptek->data,
- aiptek->data_dma);
- kfree(aiptek);
- return -ENOMEM;
- }
+ if (!aiptek->urb)
+ goto fail2;
+
+ aiptek->inputdev = inputdev;
+ aiptek->usbdev = usbdev;
+ aiptek->ifnum = intf->altsetting[0].desc.bInterfaceNumber;
+ aiptek->inDelay = 0;
+ aiptek->endDelay = 0;
+ aiptek->previousJitterable = 0;
/* Set up the curSettings struct. Said struct contains the current
* programmable parameters. The newSetting struct contains changes
@@ -2036,31 +2037,48 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id)
/* Both structs should have equivalent settings
*/
- memcpy(&aiptek->newSetting, &aiptek->curSetting,
- sizeof(struct aiptek_settings));
+ aiptek->newSetting = aiptek->curSetting;
+
+ /* Determine the usb devices' physical path.
+ * Asketh not why we always pretend we're using "../input0",
+ * but I suspect this will have to be refactored one
+ * day if a single USB device can be a keyboard & a mouse
+ * & a tablet, and the inputX number actually will tell
+ * us something...
+ */
+ usb_make_path(usbdev, aiptek->features.usbPath,
+ sizeof(aiptek->features.usbPath));
+ strlcat(aiptek->features.usbPath, "/input0",
+ sizeof(aiptek->features.usbPath));
+
+ /* Set up client data, pointers to open and close routines
+ * for the input device.
+ */
+ inputdev->name = "Aiptek";
+ inputdev->phys = aiptek->features.usbPath;
+ usb_to_input_id(usbdev, &inputdev->id);
+ inputdev->cdev.dev = &intf->dev;
+ inputdev->private = aiptek;
+ inputdev->open = aiptek_open;
+ inputdev->close = aiptek_close;
/* Now program the capacities of the tablet, in terms of being
* an input device.
*/
- aiptek->inputdev.evbit[0] |= BIT(EV_KEY)
+ inputdev->evbit[0] |= BIT(EV_KEY)
| BIT(EV_ABS)
| BIT(EV_REL)
| BIT(EV_MSC);
- aiptek->inputdev.absbit[0] |=
- (BIT(ABS_X) |
- BIT(ABS_Y) |
- BIT(ABS_PRESSURE) |
- BIT(ABS_TILT_X) |
- BIT(ABS_TILT_Y) | BIT(ABS_WHEEL) | BIT(ABS_MISC));
+ inputdev->absbit[0] |= BIT(ABS_MISC);
- aiptek->inputdev.relbit[0] |=
+ inputdev->relbit[0] |=
(BIT(REL_X) | BIT(REL_Y) | BIT(REL_WHEEL) | BIT(REL_MISC));
- aiptek->inputdev.keybit[LONG(BTN_LEFT)] |=
+ inputdev->keybit[LONG(BTN_LEFT)] |=
(BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE));
- aiptek->inputdev.keybit[LONG(BTN_DIGI)] |=
+ inputdev->keybit[LONG(BTN_DIGI)] |=
(BIT(BTN_TOOL_PEN) |
BIT(BTN_TOOL_RUBBER) |
BIT(BTN_TOOL_PENCIL) |
@@ -2070,70 +2088,26 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id)
BIT(BTN_TOOL_LENS) |
BIT(BTN_TOUCH) | BIT(BTN_STYLUS) | BIT(BTN_STYLUS2));
- aiptek->inputdev.mscbit[0] = BIT(MSC_SERIAL);
+ inputdev->mscbit[0] = BIT(MSC_SERIAL);
/* Programming the tablet macro keys needs to be done with a for loop
* as the keycodes are discontiguous.
*/
for (i = 0; i < sizeof(macroKeyEvents) / sizeof(macroKeyEvents[0]); ++i)
- set_bit(macroKeyEvents[i], aiptek->inputdev.keybit);
-
- /* Set up client data, pointers to open and close routines
- * for the input device.
- */
- aiptek->inputdev.private = aiptek;
- aiptek->inputdev.open = aiptek_open;
- aiptek->inputdev.close = aiptek_close;
+ set_bit(macroKeyEvents[i], inputdev->keybit);
- /* Determine the usb devices' physical path.
- * Asketh not why we always pretend we're using "../input0",
- * but I suspect this will have to be refactored one
- * day if a single USB device can be a keyboard & a mouse
- * & a tablet, and the inputX number actually will tell
- * us something...
- */
- if (usb_make_path(usbdev, path, 64) > 0)
- sprintf(aiptek->features.usbPath, "%s/input0", path);
-
- /* Program the input device coordinate capacities. We do not yet
+ /*
+ * Program the input device coordinate capacities. We do not yet
* know what maximum X, Y, and Z values are, so we're putting fake
* values in. Later, we'll ask the tablet to put in the correct
* values.
*/
- aiptek->inputdev.absmin[ABS_X] = 0;
- aiptek->inputdev.absmax[ABS_X] = 2999;
- aiptek->inputdev.absmin[ABS_Y] = 0;
- aiptek->inputdev.absmax[ABS_Y] = 2249;
- aiptek->inputdev.absmin[ABS_PRESSURE] = 0;
- aiptek->inputdev.absmax[ABS_PRESSURE] = 511;
- aiptek->inputdev.absmin[ABS_TILT_X] = AIPTEK_TILT_MIN;
- aiptek->inputdev.absmax[ABS_TILT_X] = AIPTEK_TILT_MAX;
- aiptek->inputdev.absmin[ABS_TILT_Y] = AIPTEK_TILT_MIN;
- aiptek->inputdev.absmax[ABS_TILT_Y] = AIPTEK_TILT_MAX;
- aiptek->inputdev.absmin[ABS_WHEEL] = AIPTEK_WHEEL_MIN;
- aiptek->inputdev.absmax[ABS_WHEEL] = AIPTEK_WHEEL_MAX - 1;
- aiptek->inputdev.absfuzz[ABS_X] = 0;
- aiptek->inputdev.absfuzz[ABS_Y] = 0;
- aiptek->inputdev.absfuzz[ABS_PRESSURE] = 0;
- aiptek->inputdev.absfuzz[ABS_TILT_X] = 0;
- aiptek->inputdev.absfuzz[ABS_TILT_Y] = 0;
- aiptek->inputdev.absfuzz[ABS_WHEEL] = 0;
- aiptek->inputdev.absflat[ABS_X] = 0;
- aiptek->inputdev.absflat[ABS_Y] = 0;
- aiptek->inputdev.absflat[ABS_PRESSURE] = 0;
- aiptek->inputdev.absflat[ABS_TILT_X] = 0;
- aiptek->inputdev.absflat[ABS_TILT_Y] = 0;
- aiptek->inputdev.absflat[ABS_WHEEL] = 0;
- aiptek->inputdev.name = "Aiptek";
- aiptek->inputdev.phys = aiptek->features.usbPath;
- usb_to_input_id(usbdev, &aiptek->inputdev.id);
- aiptek->inputdev.dev = &intf->dev;
-
- aiptek->usbdev = usbdev;
- aiptek->ifnum = intf->altsetting[0].desc.bInterfaceNumber;
- aiptek->inDelay = 0;
- aiptek->endDelay = 0;
- aiptek->previousJitterable = 0;
+ input_set_abs_params(inputdev, ABS_X, 0, 2999, 0, 0);
+ input_set_abs_params(inputdev, ABS_X, 0, 2249, 0, 0);
+ input_set_abs_params(inputdev, ABS_PRESSURE, 0, 511, 0, 0);
+ input_set_abs_params(inputdev, ABS_TILT_X, AIPTEK_TILT_MIN, AIPTEK_TILT_MAX, 0, 0);
+ input_set_abs_params(inputdev, ABS_TILT_Y, AIPTEK_TILT_MIN, AIPTEK_TILT_MAX, 0, 0);
+ input_set_abs_params(inputdev, ABS_WHEEL, AIPTEK_WHEEL_MIN, AIPTEK_WHEEL_MAX - 1, 0, 0);
endpoint = &intf->altsetting[0].endpoint[0].desc;
@@ -2150,28 +2124,6 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id)
aiptek->urb->transfer_dma = aiptek->data_dma;
aiptek->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
- /* Register the tablet as an Input Device
- */
- input_register_device(&aiptek->inputdev);
-
- /* We now will look for the evdev device which is mapped to
- * the tablet. The partial name is kept in the link list of
- * input_handles associated with this input device.
- * What identifies an evdev input_handler is that it begins
- * with 'event', continues with a digit, and that in turn
- * is mapped to /{devfs}/input/eventN.
- */
- inputdev = &aiptek->inputdev;
- list_for_each_safe(node, next, &inputdev->h_list) {
- inputhandle = to_handle(node);
- if (strncmp(inputhandle->name, "event", 5) == 0) {
- strcpy(aiptek->features.inputPath, inputhandle->name);
- break;
- }
- }
-
- info("input: Aiptek on %s (%s)\n", path, aiptek->features.inputPath);
-
/* Program the tablet. This sets the tablet up in the mode
* specified in newSetting, and also queries the tablet's
* physical capacities.
@@ -2186,13 +2138,32 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id)
for (i = 0; i < sizeof(speeds) / sizeof(speeds[0]); ++i) {
aiptek->curSetting.programmableDelay = speeds[i];
(void)aiptek_program_tablet(aiptek);
- if (aiptek->inputdev.absmax[ABS_X] > 0) {
+ if (aiptek->inputdev->absmax[ABS_X] > 0) {
info("input: Aiptek using %d ms programming speed\n",
aiptek->curSetting.programmableDelay);
break;
}
}
+ /* Register the tablet as an Input Device
+ */
+ input_register_device(aiptek->inputdev);
+
+ /* We now will look for the evdev device which is mapped to
+ * the tablet. The partial name is kept in the link list of
+ * input_handles associated with this input device.
+ * What identifies an evdev input_handler is that it begins
+ * with 'event', continues with a digit, and that in turn
+ * is mapped to input/eventN.
+ */
+ list_for_each_safe(node, next, &inputdev->h_list) {
+ inputhandle = to_handle(node);
+ if (strncmp(inputhandle->name, "event", 5) == 0) {
+ strcpy(aiptek->features.inputPath, inputhandle->name);
+ break;
+ }
+ }
+
/* Associate this driver's struct with the usb interface.
*/
usb_set_intfdata(intf, aiptek);
@@ -2207,6 +2178,12 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id)
info("aiptek: error loading 'evdev' module");
return 0;
+
+fail2: usb_buffer_free(usbdev, AIPTEK_PACKET_LENGTH, aiptek->data,
+ aiptek->data_dma);
+fail1: input_free_device(inputdev);
+ kfree(aiptek);
+ return -ENOMEM;
}
/* Forward declaration */
@@ -2234,7 +2211,7 @@ static void aiptek_disconnect(struct usb_interface *intf)
/* Free & unhook everything from the system.
*/
usb_kill_urb(aiptek->urb);
- input_unregister_device(&aiptek->inputdev);
+ input_unregister_device(aiptek->inputdev);
aiptek_delete_files(&intf->dev);
usb_free_urb(aiptek->urb);
usb_buffer_free(interface_to_usbdev(intf),
diff --git a/drivers/usb/input/appletouch.c b/drivers/usb/input/appletouch.c
index e03c1c567a14..15840db092a5 100644
--- a/drivers/usb/input/appletouch.c
+++ b/drivers/usb/input/appletouch.c
@@ -39,7 +39,7 @@
#define APPLE_VENDOR_ID 0x05AC
#define ATP_DEVICE(prod) \
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE | \
+ .match_flags = USB_DEVICE_ID_MATCH_DEVICE | \
USB_DEVICE_ID_MATCH_INT_CLASS | \
USB_DEVICE_ID_MATCH_INT_PROTOCOL, \
.idVendor = APPLE_VENDOR_ID, \
@@ -78,9 +78,9 @@ MODULE_DEVICE_TABLE (usb, atp_table);
* We try to keep the touchpad aspect ratio while still doing only simple
* arithmetics.
* The factors below give coordinates like:
- * 0 <= x < 960 on 12" and 15" Powerbooks
- * 0 <= x < 1600 on 17" Powerbooks
- * 0 <= y < 646
+ * 0 <= x < 960 on 12" and 15" Powerbooks
+ * 0 <= x < 1600 on 17" Powerbooks
+ * 0 <= y < 646
*/
#define ATP_XFACT 64
#define ATP_YFACT 43
@@ -93,11 +93,12 @@ MODULE_DEVICE_TABLE (usb, atp_table);
/* Structure to hold all of our device specific stuff */
struct atp {
+ char phys[64];
struct usb_device * udev; /* usb device */
struct urb * urb; /* usb request block */
signed char * data; /* transferred data */
int open; /* non-zero if opened */
- struct input_dev input; /* input dev */
+ struct input_dev *input; /* input dev */
int valid; /* are the sensors valid ? */
int x_old; /* last reported x/y, */
int y_old; /* used for smoothing */
@@ -114,11 +115,11 @@ struct atp {
int i; \
printk("appletouch: %s %lld", msg, (long long)jiffies); \
for (i = 0; i < ATP_XSENSORS + ATP_YSENSORS; i++) \
- printk(" %02x", tab[i]); \
- printk("\n"); \
+ printk(" %02x", tab[i]); \
+ printk("\n"); \
}
-#define dprintk(format, a...) \
+#define dprintk(format, a...) \
do { \
if (debug) printk(format, ##a); \
} while (0)
@@ -219,8 +220,8 @@ static void atp_complete(struct urb* urb, struct pt_regs* regs)
for (i = 16; i < ATP_XSENSORS; i++)
if (dev->xy_cur[i]) {
printk("appletouch: 17\" model detected.\n");
- input_set_abs_params(&dev->input, ABS_X, 0,
- (ATP_XSENSORS - 1) *
+ input_set_abs_params(dev->input, ABS_X, 0,
+ (ATP_XSENSORS - 1) *
ATP_XFACT - 1,
ATP_FUZZ, 0);
break;
@@ -260,12 +261,12 @@ static void atp_complete(struct urb* urb, struct pt_regs* regs)
"Xz: %3d Yz: %3d\n",
x, y, x_z, y_z);
- input_report_key(&dev->input, BTN_TOUCH, 1);
- input_report_abs(&dev->input, ABS_X, x);
- input_report_abs(&dev->input, ABS_Y, y);
- input_report_abs(&dev->input, ABS_PRESSURE,
+ input_report_key(dev->input, BTN_TOUCH, 1);
+ input_report_abs(dev->input, ABS_X, x);
+ input_report_abs(dev->input, ABS_Y, y);
+ input_report_abs(dev->input, ABS_PRESSURE,
min(ATP_PRESSURE, x_z + y_z));
- atp_report_fingers(&dev->input, max(x_f, y_f));
+ atp_report_fingers(dev->input, max(x_f, y_f));
}
dev->x_old = x;
dev->y_old = y;
@@ -273,17 +274,17 @@ static void atp_complete(struct urb* urb, struct pt_regs* regs)
else if (!x && !y) {
dev->x_old = dev->y_old = -1;
- input_report_key(&dev->input, BTN_TOUCH, 0);
- input_report_abs(&dev->input, ABS_PRESSURE, 0);
- atp_report_fingers(&dev->input, 0);
+ input_report_key(dev->input, BTN_TOUCH, 0);
+ input_report_abs(dev->input, ABS_PRESSURE, 0);
+ atp_report_fingers(dev->input, 0);
/* reset the accumulator on release */
memset(dev->xy_acc, 0, sizeof(dev->xy_acc));
}
- input_report_key(&dev->input, BTN_LEFT, !!dev->data[80]);
+ input_report_key(dev->input, BTN_LEFT, !!dev->data[80]);
- input_sync(&dev->input);
+ input_sync(dev->input);
exit:
retval = usb_submit_urb(dev->urb, GFP_ATOMIC);
@@ -314,21 +315,14 @@ static void atp_close(struct input_dev *input)
static int atp_probe(struct usb_interface *iface, const struct usb_device_id *id)
{
- struct atp *dev = NULL;
+ struct atp *dev;
+ struct input_dev *input_dev;
+ struct usb_device *udev = interface_to_usbdev(iface);
struct usb_host_interface *iface_desc;
struct usb_endpoint_descriptor *endpoint;
int int_in_endpointAddr = 0;
int i, retval = -ENOMEM;
- /* allocate memory for our device state and initialize it */
- dev = kmalloc(sizeof(struct atp), GFP_KERNEL);
- if (dev == NULL) {
- err("Out of memory");
- goto err_kmalloc;
- }
- memset(dev, 0, sizeof(struct atp));
-
- dev->udev = interface_to_usbdev(iface);
/* set up the endpoint information */
/* use only the first interrupt-in endpoint */
@@ -345,70 +339,82 @@ static int atp_probe(struct usb_interface *iface, const struct usb_device_id *id
}
}
if (!int_in_endpointAddr) {
- retval = -EIO;
err("Could not find int-in endpoint");
- goto err_endpoint;
+ return -EIO;
}
- /* save our data pointer in this interface device */
- usb_set_intfdata(iface, dev);
+ /* allocate memory for our device state and initialize it */
+ dev = kzalloc(sizeof(struct atp), GFP_KERNEL);
+ input_dev = input_allocate_device();
+ if (!dev || !input_dev) {
+ err("Out of memory");
+ goto err_free_devs;
+ }
+
+ dev->udev = udev;
+ dev->input = input_dev;
dev->urb = usb_alloc_urb(0, GFP_KERNEL);
if (!dev->urb) {
retval = -ENOMEM;
- goto err_usballoc;
+ goto err_free_devs;
}
+
dev->data = usb_buffer_alloc(dev->udev, ATP_DATASIZE, GFP_KERNEL,
&dev->urb->transfer_dma);
if (!dev->data) {
retval = -ENOMEM;
- goto err_usbbufalloc;
+ goto err_free_urb;
}
- usb_fill_int_urb(dev->urb, dev->udev,
- usb_rcvintpipe(dev->udev, int_in_endpointAddr),
+
+ usb_fill_int_urb(dev->urb, udev,
+ usb_rcvintpipe(udev, int_in_endpointAddr),
dev->data, ATP_DATASIZE, atp_complete, dev, 1);
- init_input_dev(&dev->input);
- dev->input.name = "appletouch";
- dev->input.dev = &iface->dev;
- dev->input.private = dev;
- dev->input.open = atp_open;
- dev->input.close = atp_close;
+ usb_make_path(udev, dev->phys, sizeof(dev->phys));
+ strlcat(dev->phys, "/input0", sizeof(dev->phys));
+
+ input_dev->name = "appletouch";
+ input_dev->phys = dev->phys;
+ usb_to_input_id(dev->udev, &input_dev->id);
+ input_dev->cdev.dev = &iface->dev;
- usb_to_input_id(dev->udev, &dev->input.id);
+ input_dev->private = dev;
+ input_dev->open = atp_open;
+ input_dev->close = atp_close;
- set_bit(EV_ABS, dev->input.evbit);
+ set_bit(EV_ABS, input_dev->evbit);
/*
* 12" and 15" Powerbooks only have 16 x sensors,
* 17" models are detected later.
*/
- input_set_abs_params(&dev->input, ABS_X, 0,
+ input_set_abs_params(input_dev, ABS_X, 0,
(16 - 1) * ATP_XFACT - 1, ATP_FUZZ, 0);
- input_set_abs_params(&dev->input, ABS_Y, 0,
+ input_set_abs_params(input_dev, ABS_Y, 0,
(ATP_YSENSORS - 1) * ATP_YFACT - 1, ATP_FUZZ, 0);
- input_set_abs_params(&dev->input, ABS_PRESSURE, 0, ATP_PRESSURE, 0, 0);
+ input_set_abs_params(input_dev, ABS_PRESSURE, 0, ATP_PRESSURE, 0, 0);
- set_bit(EV_KEY, dev->input.evbit);
- set_bit(BTN_TOUCH, dev->input.keybit);
- set_bit(BTN_TOOL_FINGER, dev->input.keybit);
- set_bit(BTN_TOOL_DOUBLETAP, dev->input.keybit);
- set_bit(BTN_TOOL_TRIPLETAP, dev->input.keybit);
- set_bit(BTN_LEFT, dev->input.keybit);
+ set_bit(EV_KEY, input_dev->evbit);
+ set_bit(BTN_TOUCH, input_dev->keybit);
+ set_bit(BTN_TOOL_FINGER, input_dev->keybit);
+ set_bit(BTN_TOOL_DOUBLETAP, input_dev->keybit);
+ set_bit(BTN_TOOL_TRIPLETAP, input_dev->keybit);
+ set_bit(BTN_LEFT, input_dev->keybit);
- input_register_device(&dev->input);
+ input_register_device(dev->input);
- printk(KERN_INFO "input: appletouch connected\n");
+ /* save our data pointer in this interface device */
+ usb_set_intfdata(iface, dev);
return 0;
-err_usbbufalloc:
+ err_free_urb:
usb_free_urb(dev->urb);
-err_usballoc:
+ err_free_devs:
usb_set_intfdata(iface, NULL);
-err_endpoint:
kfree(dev);
-err_kmalloc:
+ input_free_device(input_dev);
return retval;
}
@@ -419,7 +425,7 @@ static void atp_disconnect(struct usb_interface *iface)
usb_set_intfdata(iface, NULL);
if (dev) {
usb_kill_urb(dev->urb);
- input_unregister_device(&dev->input);
+ input_unregister_device(dev->input);
usb_free_urb(dev->urb);
usb_buffer_free(dev->udev, ATP_DATASIZE,
dev->data, dev->urb->transfer_dma);
diff --git a/drivers/usb/input/ati_remote.c b/drivers/usb/input/ati_remote.c
index fd99681ee483..9a2a47db9494 100644
--- a/drivers/usb/input/ati_remote.c
+++ b/drivers/usb/input/ati_remote.c
@@ -112,7 +112,6 @@
#define NAME_BUFSIZE 80 /* size of product name, path buffers */
#define DATA_BUFSIZE 63 /* size of URB data buffers */
-#define ATI_INPUTNUM 1 /* Which input device to register as */
static unsigned long channel_mask;
module_param(channel_mask, ulong, 0444);
@@ -162,7 +161,7 @@ static char accel[] = { 1, 2, 4, 6, 9, 13, 20 };
static DECLARE_MUTEX(disconnect_sem);
struct ati_remote {
- struct input_dev idev;
+ struct input_dev *idev;
struct usb_device *udev;
struct usb_interface *interface;
@@ -198,15 +197,13 @@ struct ati_remote {
#define KIND_ACCEL 7 /* Directional keypad - left, right, up, down.*/
/* Translation table from hardware messages to input events. */
-static struct
-{
+static struct {
short kind;
unsigned char data1, data2;
int type;
unsigned int code;
int value;
-} ati_remote_tbl[] =
-{
+} ati_remote_tbl[] = {
/* Directional control pad axes */
{KIND_ACCEL, 0x35, 0x70, EV_REL, REL_X, -1}, /* left */
{KIND_ACCEL, 0x36, 0x71, EV_REL, REL_X, 1}, /* right */
@@ -286,7 +283,6 @@ static struct
/* Local function prototypes */
static void ati_remote_dump (unsigned char *data, unsigned int actual_length);
-static void ati_remote_delete (struct ati_remote *dev);
static int ati_remote_open (struct input_dev *inputdev);
static void ati_remote_close (struct input_dev *inputdev);
static int ati_remote_sendpacket (struct ati_remote *ati_remote, u16 cmd, unsigned char *data);
@@ -428,7 +424,7 @@ static void ati_remote_input_report(struct urb *urb, struct pt_regs *regs)
{
struct ati_remote *ati_remote = urb->context;
unsigned char *data= ati_remote->inbuf;
- struct input_dev *dev = &ati_remote->idev;
+ struct input_dev *dev = ati_remote->idev;
int index, acc;
int remote_num;
@@ -587,38 +583,55 @@ static void ati_remote_irq_in(struct urb *urb, struct pt_regs *regs)
}
/*
- * ati_remote_delete
+ * ati_remote_alloc_buffers
*/
-static void ati_remote_delete(struct ati_remote *ati_remote)
+static int ati_remote_alloc_buffers(struct usb_device *udev,
+ struct ati_remote *ati_remote)
{
- if (ati_remote->irq_urb)
- usb_kill_urb(ati_remote->irq_urb);
+ ati_remote->inbuf = usb_buffer_alloc(udev, DATA_BUFSIZE, SLAB_ATOMIC,
+ &ati_remote->inbuf_dma);
+ if (!ati_remote->inbuf)
+ return -1;
- if (ati_remote->out_urb)
- usb_kill_urb(ati_remote->out_urb);
+ ati_remote->outbuf = usb_buffer_alloc(udev, DATA_BUFSIZE, SLAB_ATOMIC,
+ &ati_remote->outbuf_dma);
+ if (!ati_remote->outbuf)
+ return -1;
- input_unregister_device(&ati_remote->idev);
+ ati_remote->irq_urb = usb_alloc_urb(0, GFP_KERNEL);
+ if (!ati_remote->irq_urb)
+ return -1;
- if (ati_remote->inbuf)
- usb_buffer_free(ati_remote->udev, DATA_BUFSIZE,
- ati_remote->inbuf, ati_remote->inbuf_dma);
+ ati_remote->out_urb = usb_alloc_urb(0, GFP_KERNEL);
+ if (!ati_remote->out_urb)
+ return -1;
- if (ati_remote->outbuf)
- usb_buffer_free(ati_remote->udev, DATA_BUFSIZE,
- ati_remote->outbuf, ati_remote->outbuf_dma);
+ return 0;
+}
+/*
+ * ati_remote_free_buffers
+ */
+static void ati_remote_free_buffers(struct ati_remote *ati_remote)
+{
if (ati_remote->irq_urb)
usb_free_urb(ati_remote->irq_urb);
if (ati_remote->out_urb)
usb_free_urb(ati_remote->out_urb);
- kfree(ati_remote);
+ if (ati_remote->inbuf)
+ usb_buffer_free(ati_remote->udev, DATA_BUFSIZE,
+ ati_remote->inbuf, ati_remote->inbuf_dma);
+
+ if (ati_remote->outbuf)
+ usb_buffer_free(ati_remote->udev, DATA_BUFSIZE,
+ ati_remote->inbuf, ati_remote->outbuf_dma);
}
static void ati_remote_input_init(struct ati_remote *ati_remote)
{
- struct input_dev *idev = &(ati_remote->idev);
+ struct input_dev *idev = ati_remote->idev;
int i;
idev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
@@ -637,7 +650,7 @@ static void ati_remote_input_init(struct ati_remote *ati_remote)
idev->phys = ati_remote->phys;
usb_to_input_id(ati_remote->udev, &idev->id);
- idev->dev = &ati_remote->udev->dev;
+ idev->cdev.dev = &ati_remote->udev->dev;
}
static int ati_remote_initialize(struct ati_remote *ati_remote)
@@ -674,7 +687,7 @@ static int ati_remote_initialize(struct ati_remote *ati_remote)
(ati_remote_sendpacket(ati_remote, 0x8007, init2))) {
dev_err(&ati_remote->interface->dev,
"Initializing ati_remote hardware failed.\n");
- return 1;
+ return -EIO;
}
return 0;
@@ -686,95 +699,83 @@ static int ati_remote_initialize(struct ati_remote *ati_remote)
static int ati_remote_probe(struct usb_interface *interface, const struct usb_device_id *id)
{
struct usb_device *udev = interface_to_usbdev(interface);
- struct ati_remote *ati_remote = NULL;
- struct usb_host_interface *iface_host;
- int retval = -ENOMEM;
- char path[64];
-
- /* Allocate and clear an ati_remote struct */
- if (!(ati_remote = kmalloc(sizeof (struct ati_remote), GFP_KERNEL)))
- return -ENOMEM;
- memset(ati_remote, 0x00, sizeof (struct ati_remote));
+ struct usb_host_interface *iface_host = interface->cur_altsetting;
+ struct usb_endpoint_descriptor *endpoint_in, *endpoint_out;
+ struct ati_remote *ati_remote;
+ struct input_dev *input_dev;
+ int err = -ENOMEM;
- iface_host = interface->cur_altsetting;
if (iface_host->desc.bNumEndpoints != 2) {
err("%s: Unexpected desc.bNumEndpoints\n", __FUNCTION__);
- retval = -ENODEV;
- goto error;
+ return -ENODEV;
}
- ati_remote->endpoint_in = &(iface_host->endpoint[0].desc);
- ati_remote->endpoint_out = &(iface_host->endpoint[1].desc);
- ati_remote->udev = udev;
- ati_remote->interface = interface;
+ endpoint_in = &iface_host->endpoint[0].desc;
+ endpoint_out = &iface_host->endpoint[1].desc;
- if (!(ati_remote->endpoint_in->bEndpointAddress & 0x80)) {
+ if (!(endpoint_in->bEndpointAddress & USB_DIR_IN)) {
err("%s: Unexpected endpoint_in->bEndpointAddress\n", __FUNCTION__);
- retval = -ENODEV;
- goto error;
+ return -ENODEV;
}
- if ((ati_remote->endpoint_in->bmAttributes & 3) != 3) {
+ if ((endpoint_in->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_INT) {
err("%s: Unexpected endpoint_in->bmAttributes\n", __FUNCTION__);
- retval = -ENODEV;
- goto error;
+ return -ENODEV;
}
- if (le16_to_cpu(ati_remote->endpoint_in->wMaxPacketSize) == 0) {
+ if (le16_to_cpu(endpoint_in->wMaxPacketSize) == 0) {
err("%s: endpoint_in message size==0? \n", __FUNCTION__);
- retval = -ENODEV;
- goto error;
+ return -ENODEV;
}
- /* Allocate URB buffers, URBs */
- ati_remote->inbuf = usb_buffer_alloc(udev, DATA_BUFSIZE, SLAB_ATOMIC,
- &ati_remote->inbuf_dma);
- if (!ati_remote->inbuf)
- goto error;
+ ati_remote = kzalloc(sizeof (struct ati_remote), GFP_KERNEL);
+ input_dev = input_allocate_device();
+ if (!ati_remote || !input_dev)
+ goto fail1;
- ati_remote->outbuf = usb_buffer_alloc(udev, DATA_BUFSIZE, SLAB_ATOMIC,
- &ati_remote->outbuf_dma);
- if (!ati_remote->outbuf)
- goto error;
+ /* Allocate URB buffers, URBs */
+ if (ati_remote_alloc_buffers(udev, ati_remote))
+ goto fail2;
- ati_remote->irq_urb = usb_alloc_urb(0, GFP_KERNEL);
- if (!ati_remote->irq_urb)
- goto error;
+ ati_remote->endpoint_in = endpoint_in;
+ ati_remote->endpoint_out = endpoint_out;
+ ati_remote->udev = udev;
+ ati_remote->idev = input_dev;
+ ati_remote->interface = interface;
- ati_remote->out_urb = usb_alloc_urb(0, GFP_KERNEL);
- if (!ati_remote->out_urb)
- goto error;
+ usb_make_path(udev, ati_remote->phys, sizeof(ati_remote->phys));
+ strlcpy(ati_remote->phys, "/input0", sizeof(ati_remote->phys));
- usb_make_path(udev, path, NAME_BUFSIZE);
- sprintf(ati_remote->phys, "%s/input%d", path, ATI_INPUTNUM);
if (udev->manufacturer)
- strcat(ati_remote->name, udev->manufacturer);
+ strlcpy(ati_remote->name, udev->manufacturer, sizeof(ati_remote->name));
if (udev->product)
- sprintf(ati_remote->name, "%s %s", ati_remote->name, udev->product);
+ snprintf(ati_remote->name, sizeof(ati_remote->name),
+ "%s %s", ati_remote->name, udev->product);
if (!strlen(ati_remote->name))
- sprintf(ati_remote->name, DRIVER_DESC "(%04x,%04x)",
+ snprintf(ati_remote->name, sizeof(ati_remote->name),
+ DRIVER_DESC "(%04x,%04x)",
le16_to_cpu(ati_remote->udev->descriptor.idVendor),
le16_to_cpu(ati_remote->udev->descriptor.idProduct));
+ ati_remote_input_init(ati_remote);
+
/* Device Hardware Initialization - fills in ati_remote->idev from udev. */
- retval = ati_remote_initialize(ati_remote);
- if (retval)
- goto error;
+ err = ati_remote_initialize(ati_remote);
+ if (err)
+ goto fail3;
/* Set up and register input device */
- ati_remote_input_init(ati_remote);
- input_register_device(&ati_remote->idev);
-
- dev_info(&ati_remote->interface->dev, "Input registered: %s on %s\n",
- ati_remote->name, path);
+ input_register_device(ati_remote->idev);
usb_set_intfdata(interface, ati_remote);
+ return 0;
-error:
- if (retval)
- ati_remote_delete(ati_remote);
-
- return retval;
+fail3: usb_kill_urb(ati_remote->irq_urb);
+ usb_kill_urb(ati_remote->out_urb);
+fail2: ati_remote_free_buffers(ati_remote);
+fail1: input_free_device(input_dev);
+ kfree(ati_remote);
+ return err;
}
/*
@@ -791,7 +792,11 @@ static void ati_remote_disconnect(struct usb_interface *interface)
return;
}
- ati_remote_delete(ati_remote);
+ usb_kill_urb(ati_remote->irq_urb);
+ usb_kill_urb(ati_remote->out_urb);
+ input_unregister_device(ati_remote->idev);
+ ati_remote_free_buffers(ati_remote);
+ kfree(ati_remote);
}
/*
diff --git a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c
index 41f92b924761..79ddce4555ab 100644
--- a/drivers/usb/input/hid-core.c
+++ b/drivers/usb/input/hid-core.c
@@ -1619,8 +1619,8 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf)
struct hid_descriptor *hdesc;
struct hid_device *hid;
unsigned quirks = 0, rsize = 0;
- char *buf, *rdesc;
- int n, insize = 0;
+ char *rdesc;
+ int n, len, insize = 0;
for (n = 0; hid_blacklist[n].idVendor; n++)
if ((hid_blacklist[n].idVendor == le16_to_cpu(dev->descriptor.idVendor)) &&
@@ -1630,10 +1630,11 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf)
if (quirks & HID_QUIRK_IGNORE)
return NULL;
- if (usb_get_extra_descriptor(interface, HID_DT_HID, &hdesc) && ((!interface->desc.bNumEndpoints) ||
- usb_get_extra_descriptor(&interface->endpoint[0], HID_DT_HID, &hdesc))) {
- dbg("class descriptor not present\n");
- return NULL;
+ if (usb_get_extra_descriptor(interface, HID_DT_HID, &hdesc) &&
+ (!interface->desc.bNumEndpoints ||
+ usb_get_extra_descriptor(&interface->endpoint[0], HID_DT_HID, &hdesc))) {
+ dbg("class descriptor not present\n");
+ return NULL;
}
for (n = 0; n < hdesc->bNumDescriptors; n++)
@@ -1749,38 +1750,43 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf)
hid->name[0] = 0;
- if (!(buf = kmalloc(64, GFP_KERNEL)))
- goto fail;
+ if (dev->manufacturer)
+ strlcpy(hid->name, dev->manufacturer, sizeof(hid->name));
+
+ if (dev->product) {
+ if (dev->manufacturer)
+ strlcat(hid->name, " ", sizeof(hid->name));
+ strlcat(hid->name, dev->product, sizeof(hid->name));
+ }
- if (dev->manufacturer) {
- strcat(hid->name, dev->manufacturer);
- if (dev->product)
- snprintf(hid->name, 64, "%s %s", hid->name, dev->product);
- } else if (dev->product) {
- snprintf(hid->name, 128, "%s", dev->product);
- } else
- snprintf(hid->name, 128, "%04x:%04x",
- le16_to_cpu(dev->descriptor.idVendor),
- le16_to_cpu(dev->descriptor.idProduct));
-
- usb_make_path(dev, buf, 64);
- snprintf(hid->phys, 64, "%s/input%d", buf,
- intf->altsetting[0].desc.bInterfaceNumber);
+ if (!strlen(hid->name))
+ snprintf(hid->name, sizeof(hid->name), "HID %04x:%04x",
+ le16_to_cpu(dev->descriptor.idVendor),
+ le16_to_cpu(dev->descriptor.idProduct));
+
+ usb_make_path(dev, hid->phys, sizeof(hid->phys));
+ strlcat(hid->phys, "/input", sizeof(hid->phys));
+ len = strlen(hid->phys);
+ if (len < sizeof(hid->phys) - 1)
+ snprintf(hid->phys + len, sizeof(hid->phys) - len,
+ "%d", intf->altsetting[0].desc.bInterfaceNumber);
if (usb_string(dev, dev->descriptor.iSerialNumber, hid->uniq, 64) <= 0)
hid->uniq[0] = 0;
- kfree(buf);
-
hid->urbctrl = usb_alloc_urb(0, GFP_KERNEL);
if (!hid->urbctrl)
goto fail;
+
usb_fill_control_urb(hid->urbctrl, dev, 0, (void *) hid->cr,
hid->ctrlbuf, 1, hid_ctrl, hid);
hid->urbctrl->setup_dma = hid->cr_dma;
hid->urbctrl->transfer_dma = hid->ctrlbuf_dma;
hid->urbctrl->transfer_flags |= (URB_NO_TRANSFER_DMA_MAP | URB_NO_SETUP_DMA_MAP);
+ /* May be needed for some devices */
+ usb_clear_halt(hid->dev, hid->urbin->pipe);
+
return hid;
fail:
@@ -1884,7 +1890,6 @@ static int hid_suspend(struct usb_interface *intf, pm_message_t message)
struct hid_device *hid = usb_get_intfdata (intf);
usb_kill_urb(hid->urbin);
- intf->dev.power.power_state = PMSG_SUSPEND;
dev_dbg(&intf->dev, "suspend\n");
return 0;
}
@@ -1894,7 +1899,6 @@ static int hid_resume(struct usb_interface *intf)
struct hid_device *hid = usb_get_intfdata (intf);
int status;
- intf->dev.power.power_state = PMSG_ON;
if (hid->open)
status = usb_submit_urb(hid->urbin, GFP_NOIO);
else
diff --git a/drivers/usb/input/hid-input.c b/drivers/usb/input/hid-input.c
index 0b6452248a39..9ff25eb520a6 100644
--- a/drivers/usb/input/hid-input.c
+++ b/drivers/usb/input/hid-input.c
@@ -76,8 +76,8 @@ static struct {
static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_field *field,
struct hid_usage *usage)
{
- struct input_dev *input = &hidinput->input;
- struct hid_device *device = hidinput->input.private;
+ struct input_dev *input = hidinput->input;
+ struct hid_device *device = input->private;
int max = 0, code;
unsigned long *bit = NULL;
@@ -461,7 +461,8 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct
if (!field->hidinput)
return;
- input = &field->hidinput->input;
+
+ input = field->hidinput->input;
input_regs(input, regs);
@@ -533,13 +534,10 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct
void hidinput_report_event(struct hid_device *hid, struct hid_report *report)
{
- struct list_head *lh;
struct hid_input *hidinput;
- list_for_each (lh, &hid->inputs) {
- hidinput = list_entry(lh, struct hid_input, list);
- input_sync(&hidinput->input);
- }
+ list_for_each_entry(hidinput, &hid->inputs, list)
+ input_sync(hidinput->input);
}
static int hidinput_find_field(struct hid_device *hid, unsigned int type, unsigned int code, struct hid_field **field)
@@ -604,6 +602,7 @@ int hidinput_connect(struct hid_device *hid)
struct usb_device *dev = hid->dev;
struct hid_report *report;
struct hid_input *hidinput = NULL;
+ struct input_dev *input_dev;
int i, j, k;
INIT_LIST_HEAD(&hid->inputs);
@@ -624,25 +623,28 @@ int hidinput_connect(struct hid_device *hid)
continue;
if (!hidinput) {
- hidinput = kmalloc(sizeof(*hidinput), GFP_KERNEL);
- if (!hidinput) {
+ hidinput = kzalloc(sizeof(*hidinput), GFP_KERNEL);
+ input_dev = input_allocate_device();
+ if (!hidinput || !input_dev) {
+ kfree(hidinput);
+ input_free_device(input_dev);
err("Out of memory during hid input probe");
return -1;
}
- memset(hidinput, 0, sizeof(*hidinput));
- list_add_tail(&hidinput->list, &hid->inputs);
+ input_dev->private = hid;
+ input_dev->event = hidinput_input_event;
+ input_dev->open = hidinput_open;
+ input_dev->close = hidinput_close;
- hidinput->input.private = hid;
- hidinput->input.event = hidinput_input_event;
- hidinput->input.open = hidinput_open;
- hidinput->input.close = hidinput_close;
+ input_dev->name = hid->name;
+ input_dev->phys = hid->phys;
+ input_dev->uniq = hid->uniq;
+ usb_to_input_id(dev, &input_dev->id);
+ input_dev->cdev.dev = &hid->intf->dev;
- hidinput->input.name = hid->name;
- hidinput->input.phys = hid->phys;
- hidinput->input.uniq = hid->uniq;
- usb_to_input_id(dev, &hidinput->input.id);
- hidinput->input.dev = &hid->intf->dev;
+ hidinput->input = input_dev;
+ list_add_tail(&hidinput->list, &hid->inputs);
}
for (i = 0; i < report->maxfield; i++)
@@ -657,7 +659,7 @@ int hidinput_connect(struct hid_device *hid)
* UGCI) cram a lot of unrelated inputs into the
* same interface. */
hidinput->report = report;
- input_register_device(&hidinput->input);
+ input_register_device(hidinput->input);
hidinput = NULL;
}
}
@@ -667,7 +669,7 @@ int hidinput_connect(struct hid_device *hid)
* only useful in this case, and not for multi-input quirks. */
if (hidinput) {
hid_ff_init(hid);
- input_register_device(&hidinput->input);
+ input_register_device(hidinput->input);
}
return 0;
@@ -675,13 +677,11 @@ int hidinput_connect(struct hid_device *hid)
void hidinput_disconnect(struct hid_device *hid)
{
- struct list_head *lh, *next;
- struct hid_input *hidinput;
+ struct hid_input *hidinput, *next;
- list_for_each_safe(lh, next, &hid->inputs) {
- hidinput = list_entry(lh, struct hid_input, list);
- input_unregister_device(&hidinput->input);
+ list_for_each_entry_safe(hidinput, next, &hid->inputs, list) {
list_del(&hidinput->list);
+ input_unregister_device(hidinput->input);
kfree(hidinput);
}
}
diff --git a/drivers/usb/input/hid-lgff.c b/drivers/usb/input/hid-lgff.c
index 0c4c77aa31ea..f82c9c9e5d51 100644
--- a/drivers/usb/input/hid-lgff.c
+++ b/drivers/usb/input/hid-lgff.c
@@ -255,22 +255,19 @@ static void hid_lgff_input_init(struct hid_device* hid)
u16 idVendor = le16_to_cpu(hid->dev->descriptor.idVendor);
u16 idProduct = le16_to_cpu(hid->dev->descriptor.idProduct);
struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list);
+ struct input_dev *input_dev = hidinput->input;
while (dev->idVendor && (idVendor != dev->idVendor || idProduct != dev->idProduct))
dev++;
- ff = dev->ff;
+ for (ff = dev->ff; *ff >= 0; ff++)
+ set_bit(*ff, input_dev->ffbit);
- while (*ff >= 0) {
- set_bit(*ff, hidinput->input.ffbit);
- ++ff;
- }
-
- hidinput->input.upload_effect = hid_lgff_upload_effect;
- hidinput->input.flush = hid_lgff_flush;
+ input_dev->upload_effect = hid_lgff_upload_effect;
+ input_dev->flush = hid_lgff_flush;
- set_bit(EV_FF, hidinput->input.evbit);
- hidinput->input.ff_effects_max = LGFF_EFFECTS;
+ set_bit(EV_FF, input_dev->evbit);
+ input_dev->ff_effects_max = LGFF_EFFECTS;
}
static void hid_lgff_exit(struct hid_device* hid)
diff --git a/drivers/usb/input/hid-tmff.c b/drivers/usb/input/hid-tmff.c
index 8f6a0a6f94a9..023fd5ac31c8 100644
--- a/drivers/usb/input/hid-tmff.c
+++ b/drivers/usb/input/hid-tmff.c
@@ -111,6 +111,7 @@ int hid_tmff_init(struct hid_device *hid)
struct tmff_device *private;
struct list_head *pos;
struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list);
+ struct input_dev *input_dev = hidinput->input;
private = kmalloc(sizeof(struct tmff_device), GFP_KERNEL);
if (!private)
@@ -155,7 +156,7 @@ int hid_tmff_init(struct hid_device *hid)
private->report = report;
private->rumble = field;
- set_bit(FF_RUMBLE, hidinput->input.ffbit);
+ set_bit(FF_RUMBLE, input_dev->ffbit);
break;
default:
@@ -164,11 +165,11 @@ int hid_tmff_init(struct hid_device *hid)
}
/* Fallthrough to here only when a valid usage is found */
- hidinput->input.upload_effect = hid_tmff_upload_effect;
- hidinput->input.flush = hid_tmff_flush;
+ input_dev->upload_effect = hid_tmff_upload_effect;
+ input_dev->flush = hid_tmff_flush;
- set_bit(EV_FF, hidinput->input.evbit);
- hidinput->input.ff_effects_max = TMFF_EFFECTS;
+ set_bit(EV_FF, input_dev->evbit);
+ input_dev->ff_effects_max = TMFF_EFFECTS;
}
}
diff --git a/drivers/usb/input/hid.h b/drivers/usb/input/hid.h
index ec2412c42f1e..ee48a2276104 100644
--- a/drivers/usb/input/hid.h
+++ b/drivers/usb/input/hid.h
@@ -371,7 +371,7 @@ struct hid_control_fifo {
struct hid_input {
struct list_head list;
struct hid_report *report;
- struct input_dev input;
+ struct input_dev *input;
};
struct hid_device { /* device report descriptor */
diff --git a/drivers/usb/input/hiddev.c b/drivers/usb/input/hiddev.c
index d32427818af7..440377c7a0da 100644
--- a/drivers/usb/input/hiddev.c
+++ b/drivers/usb/input/hiddev.c
@@ -732,9 +732,8 @@ static struct file_operations hiddev_fops = {
};
static struct usb_class_driver hiddev_class = {
- .name = "usb/hid/hiddev%d",
+ .name = "hiddev%d",
.fops = &hiddev_fops,
- .mode = S_IFCHR | S_IRUGO | S_IWUSR,
.minor_base = HIDDEV_MINOR_BASE,
};
diff --git a/drivers/usb/input/itmtouch.c b/drivers/usb/input/itmtouch.c
index becb87efb869..3b581853cf10 100644
--- a/drivers/usb/input/itmtouch.c
+++ b/drivers/usb/input/itmtouch.c
@@ -73,7 +73,7 @@ MODULE_LICENSE( DRIVER_LICENSE );
struct itmtouch_dev {
struct usb_device *usbdev; /* usb device */
- struct input_dev inputdev; /* input device */
+ struct input_dev *inputdev; /* input device */
struct urb *readurb; /* urb */
char rbuf[ITM_BUFSIZE]; /* data */
int users;
@@ -88,9 +88,9 @@ static struct usb_device_id itmtouch_ids [] = {
static void itmtouch_irq(struct urb *urb, struct pt_regs *regs)
{
- struct itmtouch_dev * itmtouch = urb->context;
+ struct itmtouch_dev *itmtouch = urb->context;
unsigned char *data = urb->transfer_buffer;
- struct input_dev *dev = &itmtouch->inputdev;
+ struct input_dev *dev = itmtouch->inputdev;
int retval;
switch (urb->status) {
@@ -156,49 +156,62 @@ static void itmtouch_close(struct input_dev *input)
static int itmtouch_probe(struct usb_interface *intf, const struct usb_device_id *id)
{
struct itmtouch_dev *itmtouch;
+ struct input_dev *input_dev;
struct usb_host_interface *interface;
struct usb_endpoint_descriptor *endpoint;
struct usb_device *udev = interface_to_usbdev(intf);
unsigned int pipe;
unsigned int maxp;
- char path[PATH_SIZE];
interface = intf->cur_altsetting;
endpoint = &interface->endpoint[0].desc;
- if (!(itmtouch = kzalloc(sizeof(struct itmtouch_dev), GFP_KERNEL))) {
+ itmtouch = kzalloc(sizeof(struct itmtouch_dev), GFP_KERNEL);
+ input_dev = input_allocate_device();
+ if (!itmtouch || !input_dev) {
err("%s - Out of memory.", __FUNCTION__);
- return -ENOMEM;
+ goto fail;
}
itmtouch->usbdev = udev;
+ itmtouch->inputdev = input_dev;
- itmtouch->inputdev.private = itmtouch;
- itmtouch->inputdev.open = itmtouch_open;
- itmtouch->inputdev.close = itmtouch_close;
+ if (udev->manufacturer)
+ strlcpy(itmtouch->name, udev->manufacturer, sizeof(itmtouch->name));
- usb_make_path(udev, path, PATH_SIZE);
-
- itmtouch->inputdev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
- itmtouch->inputdev.absbit[0] = BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_PRESSURE);
- itmtouch->inputdev.keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
-
- itmtouch->inputdev.name = itmtouch->name;
- itmtouch->inputdev.phys = itmtouch->phys;
- usb_to_input_id(udev, &itmtouch->inputdev.id);
- itmtouch->inputdev.dev = &intf->dev;
+ if (udev->product) {
+ if (udev->manufacturer)
+ strlcat(itmtouch->name, " ", sizeof(itmtouch->name));
+ strlcat(itmtouch->name, udev->product, sizeof(itmtouch->name));
+ }
if (!strlen(itmtouch->name))
sprintf(itmtouch->name, "USB ITM touchscreen");
+ usb_make_path(udev, itmtouch->phys, sizeof(itmtouch->phys));
+ strlcpy(itmtouch->phys, "/input0", sizeof(itmtouch->phys));
+
+ input_dev->name = itmtouch->name;
+ input_dev->phys = itmtouch->phys;
+ usb_to_input_id(udev, &input_dev->id);
+ input_dev->cdev.dev = &intf->dev;
+ input_dev->private = itmtouch;
+
+ input_dev->open = itmtouch_open;
+ input_dev->close = itmtouch_close;
+
+ input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+ input_dev->absbit[0] = BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_PRESSURE);
+ input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
+
/* device limits */
/* as specified by the ITM datasheet, X and Y are 12bit,
* Z (pressure) is 8 bit. However, the fields are defined up
* to 14 bits for future possible expansion.
*/
- input_set_abs_params(&itmtouch->inputdev, ABS_X, 0, 0x0FFF, 2, 0);
- input_set_abs_params(&itmtouch->inputdev, ABS_Y, 0, 0x0FFF, 2, 0);
- input_set_abs_params(&itmtouch->inputdev, ABS_PRESSURE, 0, 0xFF, 2, 0);
+ input_set_abs_params(input_dev, ABS_X, 0, 0x0FFF, 2, 0);
+ input_set_abs_params(input_dev, ABS_Y, 0, 0x0FFF, 2, 0);
+ input_set_abs_params(input_dev, ABS_PRESSURE, 0, 0xFF, 2, 0);
/* initialise the URB so we can read from the transport stream */
pipe = usb_rcvintpipe(itmtouch->usbdev, endpoint->bEndpointAddress);
@@ -208,22 +221,23 @@ static int itmtouch_probe(struct usb_interface *intf, const struct usb_device_id
maxp = ITM_BUFSIZE;
itmtouch->readurb = usb_alloc_urb(0, GFP_KERNEL);
-
if (!itmtouch->readurb) {
dbg("%s - usb_alloc_urb failed: itmtouch->readurb", __FUNCTION__);
- kfree(itmtouch);
- return -ENOMEM;
+ goto fail;
}
usb_fill_int_urb(itmtouch->readurb, itmtouch->usbdev, pipe, itmtouch->rbuf,
maxp, itmtouch_irq, itmtouch, endpoint->bInterval);
- input_register_device(&itmtouch->inputdev);
+ input_register_device(itmtouch->inputdev);
- printk(KERN_INFO "itmtouch: %s registered on %s\n", itmtouch->name, path);
usb_set_intfdata(intf, itmtouch);
return 0;
+
+ fail: input_free_device(input_dev);
+ kfree(itmtouch);
+ return -ENOMEM;
}
static void itmtouch_disconnect(struct usb_interface *intf)
@@ -233,7 +247,7 @@ static void itmtouch_disconnect(struct usb_interface *intf)
usb_set_intfdata(intf, NULL);
if (itmtouch) {
- input_unregister_device(&itmtouch->inputdev);
+ input_unregister_device(itmtouch->inputdev);
usb_kill_urb(itmtouch->readurb);
usb_free_urb(itmtouch->readurb);
kfree(itmtouch);
diff --git a/drivers/usb/input/kbtab.c b/drivers/usb/input/kbtab.c
index b6f6ac8d9c2f..a248664b5d1d 100644
--- a/drivers/usb/input/kbtab.c
+++ b/drivers/usb/input/kbtab.c
@@ -34,7 +34,7 @@ MODULE_PARM_DESC(kb_pressure_click, "pressure threshold for clicks");
struct kbtab {
signed char *data;
dma_addr_t data_dma;
- struct input_dev dev;
+ struct input_dev *dev;
struct usb_device *usbdev;
struct urb *irq;
int x, y;
@@ -48,7 +48,7 @@ static void kbtab_irq(struct urb *urb, struct pt_regs *regs)
{
struct kbtab *kbtab = urb->context;
unsigned char *data = kbtab->data;
- struct input_dev *dev = &kbtab->dev;
+ struct input_dev *dev = kbtab->dev;
int retval;
switch (urb->status) {
@@ -124,53 +124,43 @@ static int kbtab_probe(struct usb_interface *intf, const struct usb_device_id *i
struct usb_device *dev = interface_to_usbdev(intf);
struct usb_endpoint_descriptor *endpoint;
struct kbtab *kbtab;
- char path[64];
+ struct input_dev *input_dev;
- if (!(kbtab = kmalloc(sizeof(struct kbtab), GFP_KERNEL)))
- return -ENOMEM;
- memset(kbtab, 0, sizeof(struct kbtab));
+ kbtab = kzalloc(sizeof(struct kbtab), GFP_KERNEL);
+ input_dev = input_allocate_device();
+ if (!kbtab || !input_dev)
+ goto fail1;
kbtab->data = usb_buffer_alloc(dev, 8, GFP_KERNEL, &kbtab->data_dma);
- if (!kbtab->data) {
- kfree(kbtab);
- return -ENOMEM;
- }
+ if (!kbtab->data)
+ goto fail1;
kbtab->irq = usb_alloc_urb(0, GFP_KERNEL);
- if (!kbtab->irq) {
- usb_buffer_free(dev, 10, kbtab->data, kbtab->data_dma);
- kfree(kbtab);
- return -ENOMEM;
- }
-
- kbtab->dev.evbit[0] |= BIT(EV_KEY) | BIT(EV_ABS) | BIT(EV_MSC);
- kbtab->dev.absbit[0] |= BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_PRESSURE);
-
- kbtab->dev.keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE);
-
- kbtab->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_PEN) | BIT(BTN_TOUCH);
+ if (!kbtab->irq)
+ goto fail2;
- kbtab->dev.mscbit[0] |= BIT(MSC_SERIAL);
-
- kbtab->dev.absmax[ABS_X] = 0x2000;
- kbtab->dev.absmax[ABS_Y] = 0x1750;
- kbtab->dev.absmax[ABS_PRESSURE] = 0xff;
+ kbtab->usbdev = dev;
+ kbtab->dev = input_dev;
- kbtab->dev.absfuzz[ABS_X] = 4;
- kbtab->dev.absfuzz[ABS_Y] = 4;
+ usb_make_path(dev, kbtab->phys, sizeof(kbtab->phys));
+ strlcat(kbtab->phys, "/input0", sizeof(kbtab->phys));
- kbtab->dev.private = kbtab;
- kbtab->dev.open = kbtab_open;
- kbtab->dev.close = kbtab_close;
+ input_dev->name = "KB Gear Tablet";
+ input_dev->phys = kbtab->phys;
+ usb_to_input_id(dev, &input_dev->id);
+ input_dev->cdev.dev = &intf->dev;
+ input_dev->private = kbtab;
- usb_make_path(dev, path, 64);
- sprintf(kbtab->phys, "%s/input0", path);
+ input_dev->open = kbtab_open;
+ input_dev->close = kbtab_close;
- kbtab->dev.name = "KB Gear Tablet";
- kbtab->dev.phys = kbtab->phys;
- usb_to_input_id(dev, &kbtab->dev.id);
- kbtab->dev.dev = &intf->dev;
- kbtab->usbdev = dev;
+ input_dev->evbit[0] |= BIT(EV_KEY) | BIT(EV_ABS) | BIT(EV_MSC);
+ input_dev->keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE);
+ input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_PEN) | BIT(BTN_TOUCH);
+ input_dev->mscbit[0] |= BIT(MSC_SERIAL);
+ input_set_abs_params(input_dev, ABS_X, 0, 0x2000, 4, 0);
+ input_set_abs_params(input_dev, ABS_X, 0, 0x1750, 4, 0);
+ input_set_abs_params(input_dev, ABS_PRESSURE, 0, 0xff, 0, 0);
endpoint = &intf->cur_altsetting->endpoint[0].desc;
@@ -181,23 +171,25 @@ static int kbtab_probe(struct usb_interface *intf, const struct usb_device_id *i
kbtab->irq->transfer_dma = kbtab->data_dma;
kbtab->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
- input_register_device(&kbtab->dev);
-
- printk(KERN_INFO "input: KB Gear Tablet on %s\n", path);
+ input_register_device(kbtab->dev);
usb_set_intfdata(intf, kbtab);
-
return 0;
+
+fail2: usb_buffer_free(dev, 10, kbtab->data, kbtab->data_dma);
+fail1: input_free_device(input_dev);
+ kfree(kbtab);
+ return -ENOMEM;
}
static void kbtab_disconnect(struct usb_interface *intf)
{
- struct kbtab *kbtab = usb_get_intfdata (intf);
+ struct kbtab *kbtab = usb_get_intfdata(intf);
usb_set_intfdata(intf, NULL);
if (kbtab) {
usb_kill_urb(kbtab->irq);
- input_unregister_device(&kbtab->dev);
+ input_unregister_device(kbtab->dev);
usb_free_urb(kbtab->irq);
usb_buffer_free(interface_to_usbdev(intf), 10, kbtab->data, kbtab->data_dma);
kfree(kbtab);
diff --git a/drivers/usb/input/keyspan_remote.c b/drivers/usb/input/keyspan_remote.c
index 99de1b33c07d..5b8d65f62abf 100644
--- a/drivers/usb/input/keyspan_remote.c
+++ b/drivers/usb/input/keyspan_remote.c
@@ -20,6 +20,7 @@
#include <linux/moduleparam.h>
#include <linux/input.h>
#include <linux/usb.h>
+#include <linux/usb_input.h>
#define DRIVER_VERSION "v0.1"
#define DRIVER_AUTHOR "Michael Downey <downey@zymeta.com>"
@@ -75,7 +76,7 @@ struct usb_keyspan {
char name[128];
char phys[64];
struct usb_device* udev;
- struct input_dev input;
+ struct input_dev *input;
struct usb_interface* interface;
struct usb_endpoint_descriptor* in_endpoint;
struct urb* irq_urb;
@@ -136,12 +137,11 @@ static struct usb_driver keyspan_driver;
*/
static void keyspan_print(struct usb_keyspan* dev) /*unsigned char* data)*/
{
- char codes[4*RECV_SIZE];
+ char codes[4 * RECV_SIZE];
int i;
- for (i = 0; i < RECV_SIZE; i++) {
- snprintf(codes+i*3, 4, "%02x ", dev->in_buffer[i]);
- }
+ for (i = 0; i < RECV_SIZE; i++)
+ snprintf(codes + i * 3, 4, "%02x ", dev->in_buffer[i]);
dev_info(&dev->udev->dev, "%s\n", codes);
}
@@ -153,7 +153,7 @@ static void keyspan_print(struct usb_keyspan* dev) /*unsigned char* data)*/
static int keyspan_load_tester(struct usb_keyspan* dev, int bits_needed)
{
if (dev->data.bits_left >= bits_needed)
- return(0);
+ return 0;
/*
* Somehow we've missed the last message. The message will be repeated
@@ -162,7 +162,7 @@ static int keyspan_load_tester(struct usb_keyspan* dev, int bits_needed)
if (dev->data.pos >= dev->data.len) {
dev_dbg(&dev->udev, "%s - Error ran out of data. pos: %d, len: %d\n",
__FUNCTION__, dev->data.pos, dev->data.len);
- return(-1);
+ return -1;
}
/* Load as much as we can into the tester. */
@@ -172,7 +172,7 @@ static int keyspan_load_tester(struct usb_keyspan* dev, int bits_needed)
dev->data.bits_left += 8;
}
- return(0);
+ return 0;
}
/*
@@ -311,10 +311,10 @@ static void keyspan_check_data(struct usb_keyspan *remote, struct pt_regs *regs)
__FUNCTION__, message.system, message.button, message.toggle);
if (message.toggle != remote->toggle) {
- input_regs(&remote->input, regs);
- input_report_key(&remote->input, keyspan_key_table[message.button], 1);
- input_report_key(&remote->input, keyspan_key_table[message.button], 0);
- input_sync(&remote->input);
+ input_regs(remote->input, regs);
+ input_report_key(remote->input, keyspan_key_table[message.button], 1);
+ input_report_key(remote->input, keyspan_key_table[message.button], 0);
+ input_sync(remote->input);
remote->toggle = message.toggle;
}
@@ -397,14 +397,9 @@ static int keyspan_open(struct input_dev *dev)
{
struct usb_keyspan *remote = dev->private;
- if (remote->open++)
- return 0;
-
remote->irq_urb->dev = remote->udev;
- if (usb_submit_urb(remote->irq_urb, GFP_KERNEL)) {
- remote->open--;
+ if (usb_submit_urb(remote->irq_urb, GFP_KERNEL))
return -EIO;
- }
return 0;
}
@@ -413,8 +408,26 @@ static void keyspan_close(struct input_dev *dev)
{
struct usb_keyspan *remote = dev->private;
- if (!--remote->open)
- usb_kill_urb(remote->irq_urb);
+ usb_kill_urb(remote->irq_urb);
+}
+
+static struct usb_endpoint_descriptor *keyspan_get_in_endpoint(struct usb_host_interface *iface)
+{
+
+ struct usb_endpoint_descriptor *endpoint;
+ int i;
+
+ for (i = 0; i < iface->desc.bNumEndpoints; ++i) {
+ endpoint = &iface->endpoint[i].desc;
+
+ if ((endpoint->bEndpointAddress & USB_DIR_IN) &&
+ ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT)) {
+ /* we found our interrupt in endpoint */
+ return endpoint;
+ }
+ }
+
+ return NULL;
}
/*
@@ -422,110 +435,78 @@ static void keyspan_close(struct input_dev *dev)
*/
static int keyspan_probe(struct usb_interface *interface, const struct usb_device_id *id)
{
- int i;
- int retval = -ENOMEM;
- char path[64];
- char *buf;
- struct usb_keyspan *remote = NULL;
- struct usb_host_interface *iface_desc;
+ struct usb_device *udev = interface_to_usbdev(interface);
struct usb_endpoint_descriptor *endpoint;
- struct usb_device *udev = usb_get_dev(interface_to_usbdev(interface));
+ struct usb_keyspan *remote;
+ struct input_dev *input_dev;
+ int i, retval;
- /* allocate memory for our device state and initialize it */
- remote = kmalloc(sizeof(*remote), GFP_KERNEL);
- if (remote == NULL) {
- err("Out of memory\n");
- goto error;
+ endpoint = keyspan_get_in_endpoint(interface->cur_altsetting);
+ if (!endpoint)
+ return -ENODEV;
+
+ remote = kzalloc(sizeof(*remote), GFP_KERNEL);
+ input_dev = input_allocate_device();
+ if (!remote || !input_dev) {
+ retval = -ENOMEM;
+ goto fail1;
}
- memset(remote, 0x00, sizeof(*remote));
remote->udev = udev;
+ remote->input = input_dev;
remote->interface = interface;
+ remote->in_endpoint = endpoint;
remote->toggle = -1; /* Set to -1 so we will always not match the toggle from the first remote message. */
- /* set up the endpoint information */
- /* use only the first in interrupt endpoint */
- iface_desc = interface->cur_altsetting;
- for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
- endpoint = &iface_desc->endpoint[i].desc;
-
- if (!remote->in_endpoint &&
- (endpoint->bEndpointAddress & USB_DIR_IN) &&
- ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT)) {
- /* we found our interrupt in endpoint */
- remote->in_endpoint = endpoint;
-
- remote->in_buffer = usb_buffer_alloc(remote->udev, RECV_SIZE, SLAB_ATOMIC, &remote->in_dma);
- if (!remote->in_buffer) {
- retval = -ENOMEM;
- goto error;
- }
- }
- }
-
- if (!remote->in_endpoint) {
- err("Could not find interrupt input endpoint.\n");
- retval = -ENODEV;
- goto error;
+ remote->in_buffer = usb_buffer_alloc(udev, RECV_SIZE, SLAB_ATOMIC, &remote->in_dma);
+ if (!remote->in_buffer) {
+ retval = -ENOMEM;
+ goto fail1;
}
remote->irq_urb = usb_alloc_urb(0, GFP_KERNEL);
if (!remote->irq_urb) {
- err("Failed to allocate urb.\n");
retval = -ENOMEM;
- goto error;
+ goto fail2;
}
- retval = keyspan_setup(remote->udev);
+ retval = keyspan_setup(udev);
if (retval) {
- err("Failed to setup device.\n");
retval = -ENODEV;
- goto error;
- }
-
- /*
- * Setup the input system with the bits we are going to be reporting
- */
- remote->input.evbit[0] = BIT(EV_KEY); /* We will only report KEY events. */
- for (i = 0; i < 32; ++i) {
- if (keyspan_key_table[i] != KEY_RESERVED) {
- set_bit(keyspan_key_table[i], remote->input.keybit);
- }
+ goto fail3;
}
- remote->input.private = remote;
- remote->input.open = keyspan_open;
- remote->input.close = keyspan_close;
-
- usb_make_path(remote->udev, path, 64);
- sprintf(remote->phys, "%s/input0", path);
+ if (udev->manufacturer)
+ strlcpy(remote->name, udev->manufacturer, sizeof(remote->name));
- remote->input.name = remote->name;
- remote->input.phys = remote->phys;
- remote->input.id.bustype = BUS_USB;
- remote->input.id.vendor = le16_to_cpu(remote->udev->descriptor.idVendor);
- remote->input.id.product = le16_to_cpu(remote->udev->descriptor.idProduct);
- remote->input.id.version = le16_to_cpu(remote->udev->descriptor.bcdDevice);
-
- if (!(buf = kmalloc(63, GFP_KERNEL))) {
- usb_buffer_free(remote->udev, RECV_SIZE, remote->in_buffer, remote->in_dma);
- kfree(remote);
- return -ENOMEM;
+ if (udev->product) {
+ if (udev->manufacturer)
+ strlcat(remote->name, " ", sizeof(remote->name));
+ strlcat(remote->name, udev->product, sizeof(remote->name));
}
- if (remote->udev->descriptor.iManufacturer &&
- usb_string(remote->udev, remote->udev->descriptor.iManufacturer, buf, 63) > 0)
- strcat(remote->name, buf);
+ if (!strlen(remote->name))
+ snprintf(remote->name, sizeof(remote->name),
+ "USB Keyspan Remote %04x:%04x",
+ le16_to_cpu(udev->descriptor.idVendor),
+ le16_to_cpu(udev->descriptor.idProduct));
- if (remote->udev->descriptor.iProduct &&
- usb_string(remote->udev, remote->udev->descriptor.iProduct, buf, 63) > 0)
- sprintf(remote->name, "%s %s", remote->name, buf);
+ usb_make_path(udev, remote->phys, sizeof(remote->phys));
+ strlcat(remote->phys, "/input0", sizeof(remote->phys));
- if (!strlen(remote->name))
- sprintf(remote->name, "USB Keyspan Remote %04x:%04x",
- remote->input.id.vendor, remote->input.id.product);
+ input_dev->name = remote->name;
+ input_dev->phys = remote->phys;
+ usb_to_input_id(udev, &input_dev->id);
+ input_dev->cdev.dev = &interface->dev;
- kfree(buf);
+ input_dev->evbit[0] = BIT(EV_KEY); /* We will only report KEY events. */
+ for (i = 0; i < ARRAY_SIZE(keyspan_key_table); i++)
+ if (keyspan_key_table[i] != KEY_RESERVED)
+ set_bit(keyspan_key_table[i], input_dev->keybit);
+
+ input_dev->private = remote;
+ input_dev->open = keyspan_open;
+ input_dev->close = keyspan_close;
/*
* Initialize the URB to access the device. The urb gets sent to the device in keyspan_open()
@@ -538,27 +519,17 @@ static int keyspan_probe(struct usb_interface *interface, const struct usb_devic
remote->irq_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
/* we can register the device now, as it is ready */
- input_register_device(&remote->input);
+ input_register_device(remote->input);
/* save our data pointer in this interface device */
usb_set_intfdata(interface, remote);
- /* let the user know what node this device is now attached to */
- info("connected: %s on %s", remote->name, path);
return 0;
-error:
- /*
- * In case of error we need to clean up any allocated buffers
- */
- if (remote->irq_urb)
- usb_free_urb(remote->irq_urb);
-
- if (remote->in_buffer)
- usb_buffer_free(remote->udev, RECV_SIZE, remote->in_buffer, remote->in_dma);
-
- if (remote)
- kfree(remote);
+ fail3: usb_free_urb(remote->irq_urb);
+ fail2: usb_buffer_free(udev, RECV_SIZE, remote->in_buffer, remote->in_dma);
+ fail1: kfree(remote);
+ input_free_device(input_dev);
return retval;
}
@@ -570,23 +541,16 @@ static void keyspan_disconnect(struct usb_interface *interface)
{
struct usb_keyspan *remote;
- /* prevent keyspan_open() from racing keyspan_disconnect() */
- lock_kernel();
-
remote = usb_get_intfdata(interface);
usb_set_intfdata(interface, NULL);
if (remote) { /* We have a valid driver structure so clean up everything we allocated. */
- input_unregister_device(&remote->input);
+ input_unregister_device(remote->input);
usb_kill_urb(remote->irq_urb);
usb_free_urb(remote->irq_urb);
- usb_buffer_free(interface_to_usbdev(interface), RECV_SIZE, remote->in_buffer, remote->in_dma);
+ usb_buffer_free(remote->udev, RECV_SIZE, remote->in_buffer, remote->in_dma);
kfree(remote);
}
-
- unlock_kernel();
-
- info("USB Keyspan now disconnected");
}
/*
diff --git a/drivers/usb/input/map_to_7segment.h b/drivers/usb/input/map_to_7segment.h
index 52ff27f15127..a424094d9fe2 100644
--- a/drivers/usb/input/map_to_7segment.h
+++ b/drivers/usb/input/map_to_7segment.h
@@ -79,7 +79,7 @@ struct seg7_conversion_map {
static inline int map_to_seg7(struct seg7_conversion_map *map, int c)
{
- return c & 0x7f ? map->table[c] : -EINVAL;
+ return c >= 0 && c < sizeof(map->table) ? map->table[c] : -EINVAL;
}
#define SEG7_CONVERSION_MAP(_name, _map) \
diff --git a/drivers/usb/input/mtouchusb.c b/drivers/usb/input/mtouchusb.c
index ff9275057a18..7fce526560ca 100644
--- a/drivers/usb/input/mtouchusb.c
+++ b/drivers/usb/input/mtouchusb.c
@@ -98,7 +98,7 @@ struct mtouch_usb {
dma_addr_t data_dma;
struct urb *irq;
struct usb_device *udev;
- struct input_dev input;
+ struct input_dev *input;
char name[128];
char phys[64];
};
@@ -135,14 +135,14 @@ static void mtouchusb_irq(struct urb *urb, struct pt_regs *regs)
goto exit;
}
- input_regs(&mtouch->input, regs);
- input_report_key(&mtouch->input, BTN_TOUCH,
+ input_regs(mtouch->input, regs);
+ input_report_key(mtouch->input, BTN_TOUCH,
MTOUCHUSB_GET_TOUCHED(mtouch->data));
- input_report_abs(&mtouch->input, ABS_X, MTOUCHUSB_GET_XC(mtouch->data));
- input_report_abs(&mtouch->input, ABS_Y,
+ input_report_abs(mtouch->input, ABS_X, MTOUCHUSB_GET_XC(mtouch->data));
+ input_report_abs(mtouch->input, ABS_Y,
(raw_coordinates ? MTOUCHUSB_MAX_RAW_YC : MTOUCHUSB_MAX_CALIB_YC)
- MTOUCHUSB_GET_YC(mtouch->data));
- input_sync(&mtouch->input);
+ input_sync(mtouch->input);
exit:
retval = usb_submit_urb(urb, GFP_ATOMIC);
@@ -195,10 +195,10 @@ static void mtouchusb_free_buffers(struct usb_device *udev, struct mtouch_usb *m
static int mtouchusb_probe(struct usb_interface *intf, const struct usb_device_id *id)
{
struct mtouch_usb *mtouch;
+ struct input_dev *input_dev;
struct usb_host_interface *interface;
struct usb_endpoint_descriptor *endpoint;
struct usb_device *udev = interface_to_usbdev(intf);
- char path[64];
int nRet;
dbg("%s - called", __FUNCTION__);
@@ -209,57 +209,55 @@ static int mtouchusb_probe(struct usb_interface *intf, const struct usb_device_i
dbg("%s - setting endpoint", __FUNCTION__);
endpoint = &interface->endpoint[0].desc;
- if (!(mtouch = kmalloc(sizeof(struct mtouch_usb), GFP_KERNEL))) {
+ mtouch = kzalloc(sizeof(struct mtouch_usb), GFP_KERNEL);
+ input_dev = input_allocate_device();
+ if (!mtouch || !input_dev) {
err("%s - Out of memory.", __FUNCTION__);
- return -ENOMEM;
+ goto fail1;
}
- memset(mtouch, 0, sizeof(struct mtouch_usb));
- mtouch->udev = udev;
-
dbg("%s - allocating buffers", __FUNCTION__);
- if (mtouchusb_alloc_buffers(udev, mtouch)) {
- mtouchusb_free_buffers(udev, mtouch);
- kfree(mtouch);
- return -ENOMEM;
- }
+ if (mtouchusb_alloc_buffers(udev, mtouch))
+ goto fail2;
- mtouch->input.private = mtouch;
- mtouch->input.open = mtouchusb_open;
- mtouch->input.close = mtouchusb_close;
-
- usb_make_path(udev, path, 64);
- sprintf(mtouch->phys, "%s/input0", path);
-
- mtouch->input.name = mtouch->name;
- mtouch->input.phys = mtouch->phys;
- usb_to_input_id(udev, &mtouch->input.id);
- mtouch->input.dev = &intf->dev;
-
- mtouch->input.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
- mtouch->input.absbit[0] = BIT(ABS_X) | BIT(ABS_Y);
- mtouch->input.keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
-
- /* Used to Scale Compensated Data and Flip Y */
- mtouch->input.absmin[ABS_X] = MTOUCHUSB_MIN_XC;
- mtouch->input.absmax[ABS_X] = raw_coordinates ?
- MTOUCHUSB_MAX_RAW_XC : MTOUCHUSB_MAX_CALIB_XC;
- mtouch->input.absfuzz[ABS_X] = MTOUCHUSB_XC_FUZZ;
- mtouch->input.absflat[ABS_X] = MTOUCHUSB_XC_FLAT;
- mtouch->input.absmin[ABS_Y] = MTOUCHUSB_MIN_YC;
- mtouch->input.absmax[ABS_Y] = raw_coordinates ?
- MTOUCHUSB_MAX_RAW_YC : MTOUCHUSB_MAX_CALIB_YC;
- mtouch->input.absfuzz[ABS_Y] = MTOUCHUSB_YC_FUZZ;
- mtouch->input.absflat[ABS_Y] = MTOUCHUSB_YC_FLAT;
+ mtouch->udev = udev;
+ mtouch->input = input_dev;
if (udev->manufacturer)
- strcat(mtouch->name, udev->manufacturer);
- if (udev->product)
- sprintf(mtouch->name, "%s %s", mtouch->name, udev->product);
+ strlcpy(mtouch->name, udev->manufacturer, sizeof(mtouch->name));
+
+ if (udev->product) {
+ if (udev->manufacturer)
+ strlcat(mtouch->name, " ", sizeof(mtouch->name));
+ strlcat(mtouch->name, udev->product, sizeof(mtouch->name));
+ }
if (!strlen(mtouch->name))
- sprintf(mtouch->name, "USB Touchscreen %04x:%04x",
- mtouch->input.id.vendor, mtouch->input.id.product);
+ snprintf(mtouch->name, sizeof(mtouch->name),
+ "USB Touchscreen %04x:%04x",
+ le16_to_cpu(udev->descriptor.idVendor),
+ le16_to_cpu(udev->descriptor.idProduct));
+
+ usb_make_path(udev, mtouch->phys, sizeof(mtouch->phys));
+ strlcpy(mtouch->phys, "/input0", sizeof(mtouch->phys));
+
+ input_dev->name = mtouch->name;
+ input_dev->phys = mtouch->phys;
+ usb_to_input_id(udev, &input_dev->id);
+ input_dev->cdev.dev = &intf->dev;
+ input_dev->private = mtouch;
+
+ input_dev->open = mtouchusb_open;
+ input_dev->close = mtouchusb_close;
+
+ input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+ input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
+ input_set_abs_params(input_dev, ABS_X, MTOUCHUSB_MIN_XC,
+ raw_coordinates ? MTOUCHUSB_MAX_RAW_XC : MTOUCHUSB_MAX_CALIB_XC,
+ MTOUCHUSB_XC_FUZZ, MTOUCHUSB_XC_FLAT);
+ input_set_abs_params(input_dev, ABS_Y, MTOUCHUSB_MIN_YC,
+ raw_coordinates ? MTOUCHUSB_MAX_RAW_YC : MTOUCHUSB_MAX_CALIB_YC,
+ MTOUCHUSB_YC_FUZZ, MTOUCHUSB_YC_FLAT);
nRet = usb_control_msg(mtouch->udev, usb_rcvctrlpipe(udev, 0),
MTOUCHUSB_RESET,
@@ -272,9 +270,7 @@ static int mtouchusb_probe(struct usb_interface *intf, const struct usb_device_i
mtouch->irq = usb_alloc_urb(0, GFP_KERNEL);
if (!mtouch->irq) {
dbg("%s - usb_alloc_urb failed: mtouch->irq", __FUNCTION__);
- mtouchusb_free_buffers(udev, mtouch);
- kfree(mtouch);
- return -ENOMEM;
+ goto fail2;
}
dbg("%s - usb_fill_int_urb", __FUNCTION__);
@@ -284,7 +280,7 @@ static int mtouchusb_probe(struct usb_interface *intf, const struct usb_device_i
mtouchusb_irq, mtouch, endpoint->bInterval);
dbg("%s - input_register_device", __FUNCTION__);
- input_register_device(&mtouch->input);
+ input_register_device(mtouch->input);
nRet = usb_control_msg(mtouch->udev, usb_rcvctrlpipe(udev, 0),
MTOUCHUSB_ASYNC_REPORT,
@@ -293,10 +289,13 @@ static int mtouchusb_probe(struct usb_interface *intf, const struct usb_device_i
dbg("%s - usb_control_msg - MTOUCHUSB_ASYNC_REPORT - bytes|err: %d",
__FUNCTION__, nRet);
- printk(KERN_INFO "input: %s on %s\n", mtouch->name, path);
usb_set_intfdata(intf, mtouch);
-
return 0;
+
+fail2: mtouchusb_free_buffers(udev, mtouch);
+fail1: input_free_device(input_dev);
+ kfree(mtouch);
+ return -ENOMEM;
}
static void mtouchusb_disconnect(struct usb_interface *intf)
@@ -308,7 +307,7 @@ static void mtouchusb_disconnect(struct usb_interface *intf)
if (mtouch) {
dbg("%s - mtouch is initialized, cleaning up", __FUNCTION__);
usb_kill_urb(mtouch->irq);
- input_unregister_device(&mtouch->input);
+ input_unregister_device(mtouch->input);
usb_free_urb(mtouch->irq);
mtouchusb_free_buffers(interface_to_usbdev(intf), mtouch);
kfree(mtouch);
diff --git a/drivers/usb/input/pid.c b/drivers/usb/input/pid.c
index acc71ec560e9..dca5ee93a4ef 100644
--- a/drivers/usb/input/pid.c
+++ b/drivers/usb/input/pid.c
@@ -198,7 +198,7 @@ static int hid_pid_upload_effect(struct input_dev *dev,
}
effect->id = id;
- dev_dbg(&pid_private->hid->dev->dev, "effect ID is %d\n.", id);
+ dev_dbg(&pid_private->hid->dev->dev, "effect ID is %d.\n", id);
pid_private->effects[id].owner = current->pid;
pid_private->effects[id].flags = (1 << FF_PID_FLAGS_USED);
spin_unlock_irqrestore(&pid_private->lock, flags);
@@ -262,6 +262,7 @@ int hid_pid_init(struct hid_device *hid)
{
struct hid_ff_pid *private;
struct hid_input *hidinput = list_entry(&hid->inputs, struct hid_input, list);
+ struct input_dev *input_dev = hidinput->input;
private = hid->ff_private = kzalloc(sizeof(struct hid_ff_pid), GFP_KERNEL);
if (!private)
@@ -281,11 +282,12 @@ int hid_pid_init(struct hid_device *hid)
usb_fill_control_urb(private->urbffout, hid->dev, 0,
(void *)&private->ffcr, private->ctrl_buffer, 8,
hid_pid_ctrl_out, hid);
- hidinput->input.upload_effect = hid_pid_upload_effect;
- hidinput->input.flush = hid_pid_flush;
- hidinput->input.ff_effects_max = 8; // A random default
- set_bit(EV_FF, hidinput->input.evbit);
- set_bit(EV_FF_STATUS, hidinput->input.evbit);
+
+ input_dev->upload_effect = hid_pid_upload_effect;
+ input_dev->flush = hid_pid_flush;
+ input_dev->ff_effects_max = 8; // A random default
+ set_bit(EV_FF, input_dev->evbit);
+ set_bit(EV_FF_STATUS, input_dev->evbit);
spin_lock_init(&private->lock);
diff --git a/drivers/usb/input/powermate.c b/drivers/usb/input/powermate.c
index ad4afe7e5897..b7476233ef5d 100644
--- a/drivers/usb/input/powermate.c
+++ b/drivers/usb/input/powermate.c
@@ -68,7 +68,7 @@ struct powermate_device {
struct usb_ctrlrequest *configcr;
dma_addr_t configcr_dma;
struct usb_device *udev;
- struct input_dev input;
+ struct input_dev *input;
spinlock_t lock;
int static_brightness;
int pulse_speed;
@@ -106,10 +106,10 @@ static void powermate_irq(struct urb *urb, struct pt_regs *regs)
}
/* handle updates to device state */
- input_regs(&pm->input, regs);
- input_report_key(&pm->input, BTN_0, pm->data[0] & 0x01);
- input_report_rel(&pm->input, REL_DIAL, pm->data[1]);
- input_sync(&pm->input);
+ input_regs(pm->input, regs);
+ input_report_key(pm->input, BTN_0, pm->data[0] & 0x01);
+ input_report_rel(pm->input, REL_DIAL, pm->data[1]);
+ input_sync(pm->input);
exit:
retval = usb_submit_urb (urb, GFP_ATOMIC);
@@ -153,10 +153,10 @@ static void powermate_sync_state(struct powermate_device *pm)
Only values of 'arg' quite close to 255 are particularly useful/spectacular.
*/
- if (pm->pulse_speed < 255){
+ if (pm->pulse_speed < 255) {
op = 0; // divide
arg = 255 - pm->pulse_speed;
- } else if (pm->pulse_speed > 255){
+ } else if (pm->pulse_speed > 255) {
op = 2; // multiply
arg = pm->pulse_speed - 255;
} else {
@@ -166,11 +166,11 @@ static void powermate_sync_state(struct powermate_device *pm)
pm->configcr->wValue = cpu_to_le16( (pm->pulse_table << 8) | SET_PULSE_MODE );
pm->configcr->wIndex = cpu_to_le16( (arg << 8) | op );
pm->requires_update &= ~UPDATE_PULSE_MODE;
- }else if (pm->requires_update & UPDATE_STATIC_BRIGHTNESS){
+ } else if (pm->requires_update & UPDATE_STATIC_BRIGHTNESS) {
pm->configcr->wValue = cpu_to_le16( SET_STATIC_BRIGHTNESS );
pm->configcr->wIndex = cpu_to_le16( pm->static_brightness );
pm->requires_update &= ~UPDATE_STATIC_BRIGHTNESS;
- }else{
+ } else {
printk(KERN_ERR "powermate: unknown update required");
pm->requires_update = 0; /* fudge the bug */
return;
@@ -228,19 +228,19 @@ static void powermate_pulse_led(struct powermate_device *pm, int static_brightne
spin_lock_irqsave(&pm->lock, flags);
/* mark state updates which are required */
- if (static_brightness != pm->static_brightness){
+ if (static_brightness != pm->static_brightness) {
pm->static_brightness = static_brightness;
pm->requires_update |= UPDATE_STATIC_BRIGHTNESS;
}
- if (pulse_asleep != pm->pulse_asleep){
+ if (pulse_asleep != pm->pulse_asleep) {
pm->pulse_asleep = pulse_asleep;
pm->requires_update |= (UPDATE_PULSE_ASLEEP | UPDATE_STATIC_BRIGHTNESS);
}
- if (pulse_awake != pm->pulse_awake){
+ if (pulse_awake != pm->pulse_awake) {
pm->pulse_awake = pulse_awake;
pm->requires_update |= (UPDATE_PULSE_AWAKE | UPDATE_STATIC_BRIGHTNESS);
}
- if (pulse_speed != pm->pulse_speed || pulse_table != pm->pulse_table){
+ if (pulse_speed != pm->pulse_speed || pulse_table != pm->pulse_table) {
pm->pulse_speed = pulse_speed;
pm->pulse_table = pulse_table;
pm->requires_update |= UPDATE_PULSE_MODE;
@@ -283,6 +283,7 @@ static int powermate_alloc_buffers(struct usb_device *udev, struct powermate_dev
SLAB_ATOMIC, &pm->data_dma);
if (!pm->data)
return -1;
+
pm->configcr = usb_buffer_alloc(udev, sizeof(*(pm->configcr)),
SLAB_ATOMIC, &pm->configcr_dma);
if (!pm->configcr)
@@ -308,8 +309,9 @@ static int powermate_probe(struct usb_interface *intf, const struct usb_device_i
struct usb_host_interface *interface;
struct usb_endpoint_descriptor *endpoint;
struct powermate_device *pm;
+ struct input_dev *input_dev;
int pipe, maxp;
- char path[64];
+ int err = -ENOMEM;
interface = intf->cur_altsetting;
endpoint = &interface->endpoint[0].desc;
@@ -323,42 +325,61 @@ static int powermate_probe(struct usb_interface *intf, const struct usb_device_i
0, interface->desc.bInterfaceNumber, NULL, 0,
USB_CTRL_SET_TIMEOUT);
- if (!(pm = kmalloc(sizeof(struct powermate_device), GFP_KERNEL)))
- return -ENOMEM;
-
- memset(pm, 0, sizeof(struct powermate_device));
- pm->udev = udev;
+ pm = kzalloc(sizeof(struct powermate_device), GFP_KERNEL);
+ input_dev = input_allocate_device();
+ if (!pm || !input_dev)
+ goto fail1;
- if (powermate_alloc_buffers(udev, pm)) {
- powermate_free_buffers(udev, pm);
- kfree(pm);
- return -ENOMEM;
- }
+ if (powermate_alloc_buffers(udev, pm))
+ goto fail2;
pm->irq = usb_alloc_urb(0, GFP_KERNEL);
- if (!pm->irq) {
- powermate_free_buffers(udev, pm);
- kfree(pm);
- return -ENOMEM;
- }
+ if (!pm->irq)
+ goto fail2;
pm->config = usb_alloc_urb(0, GFP_KERNEL);
- if (!pm->config) {
- usb_free_urb(pm->irq);
- powermate_free_buffers(udev, pm);
- kfree(pm);
- return -ENOMEM;
- }
+ if (!pm->config)
+ goto fail3;
+
+ pm->udev = udev;
+ pm->input = input_dev;
+
+ usb_make_path(udev, pm->phys, sizeof(pm->phys));
+ strlcpy(pm->phys, "/input0", sizeof(pm->phys));
spin_lock_init(&pm->lock);
- init_input_dev(&pm->input);
+
+ switch (le16_to_cpu(udev->descriptor.idProduct)) {
+ case POWERMATE_PRODUCT_NEW:
+ input_dev->name = pm_name_powermate;
+ break;
+ case POWERMATE_PRODUCT_OLD:
+ input_dev->name = pm_name_soundknob;
+ break;
+ default:
+ input_dev->name = pm_name_soundknob;
+ printk(KERN_WARNING "powermate: unknown product id %04x\n",
+ le16_to_cpu(udev->descriptor.idProduct));
+ }
+
+ input_dev->phys = pm->phys;
+ usb_to_input_id(udev, &input_dev->id);
+ input_dev->cdev.dev = &intf->dev;
+ input_dev->private = pm;
+
+ input_dev->event = powermate_input_event;
+
+ input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL) | BIT(EV_MSC);
+ input_dev->keybit[LONG(BTN_0)] = BIT(BTN_0);
+ input_dev->relbit[LONG(REL_DIAL)] = BIT(REL_DIAL);
+ input_dev->mscbit[LONG(MSC_PULSELED)] = BIT(MSC_PULSELED);
/* get a handle to the interrupt data pipe */
pipe = usb_rcvintpipe(udev, endpoint->bEndpointAddress);
maxp = usb_maxpacket(udev, pipe, usb_pipeout(pipe));
- if(maxp < POWERMATE_PAYLOAD_SIZE_MIN || maxp > POWERMATE_PAYLOAD_SIZE_MAX){
- printk("powermate: Expected payload of %d--%d bytes, found %d bytes!\n",
+ if (maxp < POWERMATE_PAYLOAD_SIZE_MIN || maxp > POWERMATE_PAYLOAD_SIZE_MAX) {
+ printk(KERN_WARNING "powermate: Expected payload of %d--%d bytes, found %d bytes!\n",
POWERMATE_PAYLOAD_SIZE_MIN, POWERMATE_PAYLOAD_SIZE_MAX, maxp);
maxp = POWERMATE_PAYLOAD_SIZE_MAX;
}
@@ -371,35 +392,11 @@ static int powermate_probe(struct usb_interface *intf, const struct usb_device_i
/* register our interrupt URB with the USB system */
if (usb_submit_urb(pm->irq, GFP_KERNEL)) {
- powermate_free_buffers(udev, pm);
- kfree(pm);
- return -EIO; /* failure */
+ err = -EIO;
+ goto fail4;
}
- switch (le16_to_cpu(udev->descriptor.idProduct)) {
- case POWERMATE_PRODUCT_NEW: pm->input.name = pm_name_powermate; break;
- case POWERMATE_PRODUCT_OLD: pm->input.name = pm_name_soundknob; break;
- default:
- pm->input.name = pm_name_soundknob;
- printk(KERN_WARNING "powermate: unknown product id %04x\n",
- le16_to_cpu(udev->descriptor.idProduct));
- }
-
- pm->input.private = pm;
- pm->input.evbit[0] = BIT(EV_KEY) | BIT(EV_REL) | BIT(EV_MSC);
- pm->input.keybit[LONG(BTN_0)] = BIT(BTN_0);
- pm->input.relbit[LONG(REL_DIAL)] = BIT(REL_DIAL);
- pm->input.mscbit[LONG(MSC_PULSELED)] = BIT(MSC_PULSELED);
- usb_to_input_id(udev, &pm->input.id);
- pm->input.event = powermate_input_event;
- pm->input.dev = &intf->dev;
- pm->input.phys = pm->phys;
-
- input_register_device(&pm->input);
-
- usb_make_path(udev, path, 64);
- snprintf(pm->phys, 64, "%s/input0", path);
- printk(KERN_INFO "input: %s on %s\n", pm->input.name, pm->input.phys);
+ input_register_device(pm->input);
/* force an update of everything */
pm->requires_update = UPDATE_PULSE_ASLEEP | UPDATE_PULSE_AWAKE | UPDATE_PULSE_MODE | UPDATE_STATIC_BRIGHTNESS;
@@ -407,6 +404,13 @@ static int powermate_probe(struct usb_interface *intf, const struct usb_device_i
usb_set_intfdata(intf, pm);
return 0;
+
+fail4: usb_free_urb(pm->config);
+fail3: usb_free_urb(pm->irq);
+fail2: powermate_free_buffers(udev, pm);
+fail1: input_free_device(input_dev);
+ kfree(pm);
+ return err;
}
/* Called when a USB device we've accepted ownership of is removed */
@@ -418,7 +422,7 @@ static void powermate_disconnect(struct usb_interface *intf)
if (pm) {
pm->requires_update = 0;
usb_kill_urb(pm->irq);
- input_unregister_device(&pm->input);
+ input_unregister_device(pm->input);
usb_free_urb(pm->irq);
usb_free_urb(pm->config);
powermate_free_buffers(interface_to_usbdev(intf), pm);
diff --git a/drivers/usb/input/touchkitusb.c b/drivers/usb/input/touchkitusb.c
index 4276c24a5080..0043e6ebcd1f 100644
--- a/drivers/usb/input/touchkitusb.c
+++ b/drivers/usb/input/touchkitusb.c
@@ -68,14 +68,16 @@ struct touchkit_usb {
dma_addr_t data_dma;
struct urb *irq;
struct usb_device *udev;
- struct input_dev input;
+ struct input_dev *input;
char name[128];
char phys[64];
};
static struct usb_device_id touchkit_devices[] = {
{USB_DEVICE(0x3823, 0x0001)},
+ {USB_DEVICE(0x0123, 0x0001)},
{USB_DEVICE(0x0eef, 0x0001)},
+ {USB_DEVICE(0x0eef, 0x0002)},
{}
};
@@ -115,12 +117,12 @@ static void touchkit_irq(struct urb *urb, struct pt_regs *regs)
y = TOUCHKIT_GET_Y(touchkit->data);
}
- input_regs(&touchkit->input, regs);
- input_report_key(&touchkit->input, BTN_TOUCH,
+ input_regs(touchkit->input, regs);
+ input_report_key(touchkit->input, BTN_TOUCH,
TOUCHKIT_GET_TOUCHED(touchkit->data));
- input_report_abs(&touchkit->input, ABS_X, x);
- input_report_abs(&touchkit->input, ABS_Y, y);
- input_sync(&touchkit->input);
+ input_report_abs(touchkit->input, ABS_X, x);
+ input_report_abs(touchkit->input, ABS_Y, y);
+ input_sync(touchkit->input);
exit:
retval = usb_submit_urb(urb, GFP_ATOMIC);
@@ -171,87 +173,81 @@ static void touchkit_free_buffers(struct usb_device *udev,
static int touchkit_probe(struct usb_interface *intf,
const struct usb_device_id *id)
{
- int ret;
struct touchkit_usb *touchkit;
+ struct input_dev *input_dev;
struct usb_host_interface *interface;
struct usb_endpoint_descriptor *endpoint;
struct usb_device *udev = interface_to_usbdev(intf);
- char path[64];
interface = intf->cur_altsetting;
endpoint = &interface->endpoint[0].desc;
- touchkit = kmalloc(sizeof(struct touchkit_usb), GFP_KERNEL);
- if (!touchkit)
- return -ENOMEM;
-
- memset(touchkit, 0, sizeof(struct touchkit_usb));
- touchkit->udev = udev;
-
- if (touchkit_alloc_buffers(udev, touchkit)) {
- ret = -ENOMEM;
+ touchkit = kzalloc(sizeof(struct touchkit_usb), GFP_KERNEL);
+ input_dev = input_allocate_device();
+ if (!touchkit || !input_dev)
goto out_free;
- }
-
- touchkit->input.private = touchkit;
- touchkit->input.open = touchkit_open;
- touchkit->input.close = touchkit_close;
-
- usb_make_path(udev, path, 64);
- sprintf(touchkit->phys, "%s/input0", path);
-
- touchkit->input.name = touchkit->name;
- touchkit->input.phys = touchkit->phys;
- usb_to_input_id(udev, &touchkit->input.id);
- touchkit->input.dev = &intf->dev;
-
- touchkit->input.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
- touchkit->input.absbit[0] = BIT(ABS_X) | BIT(ABS_Y);
- touchkit->input.keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
-
- /* Used to Scale Compensated Data */
- touchkit->input.absmin[ABS_X] = TOUCHKIT_MIN_XC;
- touchkit->input.absmax[ABS_X] = TOUCHKIT_MAX_XC;
- touchkit->input.absfuzz[ABS_X] = TOUCHKIT_XC_FUZZ;
- touchkit->input.absflat[ABS_X] = TOUCHKIT_XC_FLAT;
- touchkit->input.absmin[ABS_Y] = TOUCHKIT_MIN_YC;
- touchkit->input.absmax[ABS_Y] = TOUCHKIT_MAX_YC;
- touchkit->input.absfuzz[ABS_Y] = TOUCHKIT_YC_FUZZ;
- touchkit->input.absflat[ABS_Y] = TOUCHKIT_YC_FLAT;
-
- if (udev->manufacturer)
- strcat(touchkit->name, udev->manufacturer);
- if (udev->product)
- sprintf(touchkit->name, "%s %s", touchkit->name, udev->product);
- if (!strlen(touchkit->name))
- sprintf(touchkit->name, "USB Touchscreen %04x:%04x",
- touchkit->input.id.vendor, touchkit->input.id.product);
+ if (touchkit_alloc_buffers(udev, touchkit))
+ goto out_free;
touchkit->irq = usb_alloc_urb(0, GFP_KERNEL);
if (!touchkit->irq) {
dbg("%s - usb_alloc_urb failed: touchkit->irq", __FUNCTION__);
- ret = -ENOMEM;
goto out_free_buffers;
}
+ touchkit->udev = udev;
+ touchkit->input = input_dev;
+
+ if (udev->manufacturer)
+ strlcpy(touchkit->name, udev->manufacturer, sizeof(touchkit->name));
+
+ if (udev->product) {
+ if (udev->manufacturer)
+ strlcat(touchkit->name, " ", sizeof(touchkit->name));
+ strlcat(touchkit->name, udev->product, sizeof(touchkit->name));
+ }
+
+ if (!strlen(touchkit->name))
+ snprintf(touchkit->name, sizeof(touchkit->name),
+ "USB Touchscreen %04x:%04x",
+ le16_to_cpu(udev->descriptor.idVendor),
+ le16_to_cpu(udev->descriptor.idProduct));
+
+ usb_make_path(udev, touchkit->phys, sizeof(touchkit->phys));
+ strlcpy(touchkit->phys, "/input0", sizeof(touchkit->phys));
+
+ input_dev->name = touchkit->name;
+ input_dev->phys = touchkit->phys;
+ usb_to_input_id(udev, &input_dev->id);
+ input_dev->cdev.dev = &intf->dev;
+ input_dev->private = touchkit;
+ input_dev->open = touchkit_open;
+ input_dev->close = touchkit_close;
+
+ input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+ input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
+ input_set_abs_params(input_dev, ABS_X, TOUCHKIT_MIN_XC, TOUCHKIT_MAX_XC,
+ TOUCHKIT_XC_FUZZ, TOUCHKIT_XC_FLAT);
+ input_set_abs_params(input_dev, ABS_Y, TOUCHKIT_MIN_YC, TOUCHKIT_MAX_YC,
+ TOUCHKIT_YC_FUZZ, TOUCHKIT_YC_FLAT);
+
usb_fill_int_urb(touchkit->irq, touchkit->udev,
- usb_rcvintpipe(touchkit->udev, 0x81),
- touchkit->data, TOUCHKIT_REPORT_DATA_SIZE,
- touchkit_irq, touchkit, endpoint->bInterval);
+ usb_rcvintpipe(touchkit->udev, 0x81),
+ touchkit->data, TOUCHKIT_REPORT_DATA_SIZE,
+ touchkit_irq, touchkit, endpoint->bInterval);
- input_register_device(&touchkit->input);
+ input_register_device(touchkit->input);
- printk(KERN_INFO "input: %s on %s\n", touchkit->name, path);
usb_set_intfdata(intf, touchkit);
-
return 0;
out_free_buffers:
touchkit_free_buffers(udev, touchkit);
out_free:
+ input_free_device(input_dev);
kfree(touchkit);
- return ret;
+ return -ENOMEM;
}
static void touchkit_disconnect(struct usb_interface *intf)
@@ -265,8 +261,8 @@ static void touchkit_disconnect(struct usb_interface *intf)
dbg("%s - touchkit is initialized, cleaning up", __FUNCTION__);
usb_set_intfdata(intf, NULL);
- input_unregister_device(&touchkit->input);
usb_kill_urb(touchkit->irq);
+ input_unregister_device(touchkit->input);
usb_free_urb(touchkit->irq);
touchkit_free_buffers(interface_to_usbdev(intf), touchkit);
kfree(touchkit);
diff --git a/drivers/usb/input/usbkbd.c b/drivers/usb/input/usbkbd.c
index 28987f15eeee..226b6f90a907 100644
--- a/drivers/usb/input/usbkbd.c
+++ b/drivers/usb/input/usbkbd.c
@@ -66,7 +66,7 @@ static unsigned char usb_kbd_keycode[256] = {
};
struct usb_kbd {
- struct input_dev dev;
+ struct input_dev *dev;
struct usb_device *usbdev;
unsigned char old[8];
struct urb *irq, *led;
@@ -99,29 +99,29 @@ static void usb_kbd_irq(struct urb *urb, struct pt_regs *regs)
goto resubmit;
}
- input_regs(&kbd->dev, regs);
+ input_regs(kbd->dev, regs);
for (i = 0; i < 8; i++)
- input_report_key(&kbd->dev, usb_kbd_keycode[i + 224], (kbd->new[0] >> i) & 1);
+ input_report_key(kbd->dev, usb_kbd_keycode[i + 224], (kbd->new[0] >> i) & 1);
for (i = 2; i < 8; i++) {
if (kbd->old[i] > 3 && memscan(kbd->new + 2, kbd->old[i], 6) == kbd->new + 8) {
if (usb_kbd_keycode[kbd->old[i]])
- input_report_key(&kbd->dev, usb_kbd_keycode[kbd->old[i]], 0);
+ input_report_key(kbd->dev, usb_kbd_keycode[kbd->old[i]], 0);
else
info("Unknown key (scancode %#x) released.", kbd->old[i]);
}
if (kbd->new[i] > 3 && memscan(kbd->old + 2, kbd->new[i], 6) == kbd->old + 8) {
if (usb_kbd_keycode[kbd->new[i]])
- input_report_key(&kbd->dev, usb_kbd_keycode[kbd->new[i]], 1);
+ input_report_key(kbd->dev, usb_kbd_keycode[kbd->new[i]], 1);
else
info("Unknown key (scancode %#x) pressed.", kbd->new[i]);
}
}
- input_sync(&kbd->dev);
+ input_sync(kbd->dev);
memcpy(kbd->old, kbd->new, 8);
@@ -227,12 +227,12 @@ static void usb_kbd_free_mem(struct usb_device *dev, struct usb_kbd *kbd)
static int usb_kbd_probe(struct usb_interface *iface,
const struct usb_device_id *id)
{
- struct usb_device * dev = interface_to_usbdev(iface);
+ struct usb_device *dev = interface_to_usbdev(iface);
struct usb_host_interface *interface;
struct usb_endpoint_descriptor *endpoint;
struct usb_kbd *kbd;
+ struct input_dev *input_dev;
int i, pipe, maxp;
- char path[64];
interface = iface->cur_altsetting;
@@ -240,37 +240,59 @@ static int usb_kbd_probe(struct usb_interface *iface,
return -ENODEV;
endpoint = &interface->endpoint[0].desc;
- if (!(endpoint->bEndpointAddress & 0x80))
+ if (!(endpoint->bEndpointAddress & USB_DIR_IN))
return -ENODEV;
- if ((endpoint->bmAttributes & 3) != 3)
+ if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_INT)
return -ENODEV;
pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);
maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe));
- if (!(kbd = kmalloc(sizeof(struct usb_kbd), GFP_KERNEL)))
- return -ENOMEM;
- memset(kbd, 0, sizeof(struct usb_kbd));
+ kbd = kzalloc(sizeof(struct usb_kbd), GFP_KERNEL);
+ input_dev = input_allocate_device();
+ if (!kbd || !input_dev)
+ goto fail1;
- if (usb_kbd_alloc_mem(dev, kbd)) {
- usb_kbd_free_mem(dev, kbd);
- kfree(kbd);
- return -ENOMEM;
- }
+ if (usb_kbd_alloc_mem(dev, kbd))
+ goto fail2;
kbd->usbdev = dev;
+ kbd->dev = input_dev;
+
+ if (dev->manufacturer)
+ strlcpy(kbd->name, dev->manufacturer, sizeof(kbd->name));
+
+ if (dev->product) {
+ if (dev->manufacturer)
+ strlcat(kbd->name, " ", sizeof(kbd->name));
+ strlcat(kbd->name, dev->product, sizeof(kbd->name));
+ }
+
+ if (!strlen(kbd->name))
+ snprintf(kbd->name, sizeof(kbd->name),
+ "USB HIDBP Keyboard %04x:%04x",
+ le16_to_cpu(dev->descriptor.idVendor),
+ le16_to_cpu(dev->descriptor.idProduct));
+
+ usb_make_path(dev, kbd->phys, sizeof(kbd->phys));
+ strlcpy(kbd->phys, "/input0", sizeof(kbd->phys));
- kbd->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_LED) | BIT(EV_REP);
- kbd->dev.ledbit[0] = BIT(LED_NUML) | BIT(LED_CAPSL) | BIT(LED_SCROLLL) | BIT(LED_COMPOSE) | BIT(LED_KANA);
+ input_dev->name = kbd->name;
+ input_dev->phys = kbd->phys;
+ usb_to_input_id(dev, &input_dev->id);
+ input_dev->cdev.dev = &iface->dev;
+ input_dev->private = kbd;
+
+ input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_LED) | BIT(EV_REP);
+ input_dev->ledbit[0] = BIT(LED_NUML) | BIT(LED_CAPSL) | BIT(LED_SCROLLL) | BIT(LED_COMPOSE) | BIT(LED_KANA);
for (i = 0; i < 255; i++)
- set_bit(usb_kbd_keycode[i], kbd->dev.keybit);
- clear_bit(0, kbd->dev.keybit);
+ set_bit(usb_kbd_keycode[i], input_dev->keybit);
+ clear_bit(0, input_dev->keybit);
- kbd->dev.private = kbd;
- kbd->dev.event = usb_kbd_event;
- kbd->dev.open = usb_kbd_open;
- kbd->dev.close = usb_kbd_close;
+ input_dev->event = usb_kbd_event;
+ input_dev->open = usb_kbd_open;
+ input_dev->close = usb_kbd_close;
usb_fill_int_urb(kbd->irq, dev, pipe,
kbd->new, (maxp > 8 ? 8 : maxp),
@@ -284,37 +306,22 @@ static int usb_kbd_probe(struct usb_interface *iface,
kbd->cr->wIndex = cpu_to_le16(interface->desc.bInterfaceNumber);
kbd->cr->wLength = cpu_to_le16(1);
- usb_make_path(dev, path, 64);
- sprintf(kbd->phys, "%s/input0", path);
-
- kbd->dev.name = kbd->name;
- kbd->dev.phys = kbd->phys;
- usb_to_input_id(dev, &kbd->dev.id);
- kbd->dev.dev = &iface->dev;
-
- if (dev->manufacturer)
- strcat(kbd->name, dev->manufacturer);
- if (dev->product)
- sprintf(kbd->name, "%s %s", kbd->name, dev->product);
-
- if (!strlen(kbd->name))
- sprintf(kbd->name, "USB HIDBP Keyboard %04x:%04x",
- kbd->dev.id.vendor, kbd->dev.id.product);
-
usb_fill_control_urb(kbd->led, dev, usb_sndctrlpipe(dev, 0),
(void *) kbd->cr, kbd->leds, 1,
usb_kbd_led, kbd);
kbd->led->setup_dma = kbd->cr_dma;
kbd->led->transfer_dma = kbd->leds_dma;
- kbd->led->transfer_flags |= (URB_NO_TRANSFER_DMA_MAP
- | URB_NO_SETUP_DMA_MAP);
+ kbd->led->transfer_flags |= (URB_NO_TRANSFER_DMA_MAP | URB_NO_SETUP_DMA_MAP);
- input_register_device(&kbd->dev);
-
- printk(KERN_INFO "input: %s on %s\n", kbd->name, path);
+ input_register_device(kbd->dev);
usb_set_intfdata(iface, kbd);
return 0;
+
+fail2: usb_kbd_free_mem(dev, kbd);
+fail1: input_free_device(input_dev);
+ kfree(kbd);
+ return -ENOMEM;
}
static void usb_kbd_disconnect(struct usb_interface *intf)
@@ -324,7 +331,7 @@ static void usb_kbd_disconnect(struct usb_interface *intf)
usb_set_intfdata(intf, NULL);
if (kbd) {
usb_kill_urb(kbd->irq);
- input_unregister_device(&kbd->dev);
+ input_unregister_device(kbd->dev);
usb_kbd_free_mem(interface_to_usbdev(intf), kbd);
kfree(kbd);
}
diff --git a/drivers/usb/input/usbmouse.c b/drivers/usb/input/usbmouse.c
index 4104dec847fb..230f6b1b314a 100644
--- a/drivers/usb/input/usbmouse.c
+++ b/drivers/usb/input/usbmouse.c
@@ -50,7 +50,7 @@ struct usb_mouse {
char name[128];
char phys[64];
struct usb_device *usbdev;
- struct input_dev dev;
+ struct input_dev *dev;
struct urb *irq;
signed char *data;
@@ -61,7 +61,7 @@ static void usb_mouse_irq(struct urb *urb, struct pt_regs *regs)
{
struct usb_mouse *mouse = urb->context;
signed char *data = mouse->data;
- struct input_dev *dev = &mouse->dev;
+ struct input_dev *dev = mouse->dev;
int status;
switch (urb->status) {
@@ -115,14 +115,14 @@ static void usb_mouse_close(struct input_dev *dev)
usb_kill_urb(mouse->irq);
}
-static int usb_mouse_probe(struct usb_interface * intf, const struct usb_device_id * id)
+static int usb_mouse_probe(struct usb_interface *intf, const struct usb_device_id *id)
{
- struct usb_device * dev = interface_to_usbdev(intf);
+ struct usb_device *dev = interface_to_usbdev(intf);
struct usb_host_interface *interface;
struct usb_endpoint_descriptor *endpoint;
struct usb_mouse *mouse;
+ struct input_dev *input_dev;
int pipe, maxp;
- char path[64];
interface = intf->cur_altsetting;
@@ -130,59 +130,62 @@ static int usb_mouse_probe(struct usb_interface * intf, const struct usb_device_
return -ENODEV;
endpoint = &interface->endpoint[0].desc;
- if (!(endpoint->bEndpointAddress & 0x80))
+ if (!(endpoint->bEndpointAddress & USB_DIR_IN))
return -ENODEV;
- if ((endpoint->bmAttributes & 3) != 3)
+ if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_INT)
return -ENODEV;
pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);
maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe));
- if (!(mouse = kmalloc(sizeof(struct usb_mouse), GFP_KERNEL)))
- return -ENOMEM;
- memset(mouse, 0, sizeof(struct usb_mouse));
+ mouse = kzalloc(sizeof(struct usb_mouse), GFP_KERNEL);
+ input_dev = input_allocate_device();
+ if (!mouse || !input_dev)
+ goto fail1;
mouse->data = usb_buffer_alloc(dev, 8, SLAB_ATOMIC, &mouse->data_dma);
- if (!mouse->data) {
- kfree(mouse);
- return -ENOMEM;
- }
+ if (!mouse->data)
+ goto fail1;
mouse->irq = usb_alloc_urb(0, GFP_KERNEL);
- if (!mouse->irq) {
- usb_buffer_free(dev, 8, mouse->data, mouse->data_dma);
- kfree(mouse);
- return -ENODEV;
- }
+ if (!mouse->irq)
+ goto fail2;
mouse->usbdev = dev;
+ mouse->dev = input_dev;
+
+ if (dev->manufacturer)
+ strlcpy(mouse->name, dev->manufacturer, sizeof(mouse->name));
- mouse->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
- mouse->dev.keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE);
- mouse->dev.relbit[0] = BIT(REL_X) | BIT(REL_Y);
- mouse->dev.keybit[LONG(BTN_MOUSE)] |= BIT(BTN_SIDE) | BIT(BTN_EXTRA);
- mouse->dev.relbit[0] |= BIT(REL_WHEEL);
+ if (dev->product) {
+ if (dev->manufacturer)
+ strlcat(mouse->name, " ", sizeof(mouse->name));
+ strlcat(mouse->name, dev->product, sizeof(mouse->name));
+ }
- mouse->dev.private = mouse;
- mouse->dev.open = usb_mouse_open;
- mouse->dev.close = usb_mouse_close;
+ if (!strlen(mouse->name))
+ snprintf(mouse->name, sizeof(mouse->name),
+ "USB HIDBP Mouse %04x:%04x",
+ le16_to_cpu(dev->descriptor.idVendor),
+ le16_to_cpu(dev->descriptor.idProduct));
- usb_make_path(dev, path, 64);
- sprintf(mouse->phys, "%s/input0", path);
+ usb_make_path(dev, mouse->phys, sizeof(mouse->phys));
+ strlcat(mouse->phys, "/input0", sizeof(mouse->phys));
- mouse->dev.name = mouse->name;
- mouse->dev.phys = mouse->phys;
- usb_to_input_id(dev, &mouse->dev.id);
- mouse->dev.dev = &intf->dev;
+ input_dev->name = mouse->name;
+ input_dev->phys = mouse->phys;
+ usb_to_input_id(dev, &input_dev->id);
+ input_dev->cdev.dev = &intf->dev;
- if (dev->manufacturer)
- strcat(mouse->name, dev->manufacturer);
- if (dev->product)
- sprintf(mouse->name, "%s %s", mouse->name, dev->product);
+ input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
+ input_dev->keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE);
+ input_dev->relbit[0] = BIT(REL_X) | BIT(REL_Y);
+ input_dev->keybit[LONG(BTN_MOUSE)] |= BIT(BTN_SIDE) | BIT(BTN_EXTRA);
+ input_dev->relbit[0] |= BIT(REL_WHEEL);
- if (!strlen(mouse->name))
- sprintf(mouse->name, "USB HIDBP Mouse %04x:%04x",
- mouse->dev.id.vendor, mouse->dev.id.product);
+ input_dev->private = mouse;
+ input_dev->open = usb_mouse_open;
+ input_dev->close = usb_mouse_close;
usb_fill_int_urb(mouse->irq, dev, pipe, mouse->data,
(maxp > 8 ? 8 : maxp),
@@ -190,11 +193,15 @@ static int usb_mouse_probe(struct usb_interface * intf, const struct usb_device_
mouse->irq->transfer_dma = mouse->data_dma;
mouse->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
- input_register_device(&mouse->dev);
- printk(KERN_INFO "input: %s on %s\n", mouse->name, path);
+ input_register_device(mouse->dev);
usb_set_intfdata(intf, mouse);
return 0;
+
+fail2: usb_buffer_free(dev, 8, mouse->data, mouse->data_dma);
+fail1: input_free_device(input_dev);
+ kfree(mouse);
+ return -ENOMEM;
}
static void usb_mouse_disconnect(struct usb_interface *intf)
@@ -204,7 +211,7 @@ static void usb_mouse_disconnect(struct usb_interface *intf)
usb_set_intfdata(intf, NULL);
if (mouse) {
usb_kill_urb(mouse->irq);
- input_unregister_device(&mouse->dev);
+ input_unregister_device(mouse->dev);
usb_free_urb(mouse->irq);
usb_buffer_free(interface_to_usbdev(intf), 8, mouse->data, mouse->data_dma);
kfree(mouse);
diff --git a/drivers/usb/input/wacom.c b/drivers/usb/input/wacom.c
index 3b266af3048a..ea0f75773ae1 100644
--- a/drivers/usb/input/wacom.c
+++ b/drivers/usb/input/wacom.c
@@ -111,7 +111,7 @@ struct wacom_features {
struct wacom {
signed char *data;
dma_addr_t data_dma;
- struct input_dev dev;
+ struct input_dev *dev;
struct usb_device *usbdev;
struct urb *irq;
struct wacom_features *features;
@@ -135,7 +135,7 @@ static void wacom_pl_irq(struct urb *urb, struct pt_regs *regs)
{
struct wacom *wacom = urb->context;
unsigned char *data = wacom->data;
- struct input_dev *dev = &wacom->dev;
+ struct input_dev *dev = wacom->dev;
int prox, pressure;
int retval;
@@ -225,7 +225,7 @@ static void wacom_ptu_irq(struct urb *urb, struct pt_regs *regs)
{
struct wacom *wacom = urb->context;
unsigned char *data = wacom->data;
- struct input_dev *dev = &wacom->dev;
+ struct input_dev *dev = wacom->dev;
int retval;
switch (urb->status) {
@@ -275,7 +275,7 @@ static void wacom_penpartner_irq(struct urb *urb, struct pt_regs *regs)
{
struct wacom *wacom = urb->context;
unsigned char *data = wacom->data;
- struct input_dev *dev = &wacom->dev;
+ struct input_dev *dev = wacom->dev;
int retval;
switch (urb->status) {
@@ -318,7 +318,7 @@ static void wacom_graphire_irq(struct urb *urb, struct pt_regs *regs)
{
struct wacom *wacom = urb->context;
unsigned char *data = wacom->data;
- struct input_dev *dev = &wacom->dev;
+ struct input_dev *dev = wacom->dev;
int x, y;
int retval;
@@ -397,7 +397,7 @@ static int wacom_intuos_inout(struct urb *urb)
{
struct wacom *wacom = urb->context;
unsigned char *data = wacom->data;
- struct input_dev *dev = &wacom->dev;
+ struct input_dev *dev = wacom->dev;
int idx;
/* tool number */
@@ -479,7 +479,7 @@ static void wacom_intuos_general(struct urb *urb)
{
struct wacom *wacom = urb->context;
unsigned char *data = wacom->data;
- struct input_dev *dev = &wacom->dev;
+ struct input_dev *dev = wacom->dev;
unsigned int t;
/* general pen packet */
@@ -509,7 +509,7 @@ static void wacom_intuos_irq(struct urb *urb, struct pt_regs *regs)
{
struct wacom *wacom = urb->context;
unsigned char *data = wacom->data;
- struct input_dev *dev = &wacom->dev;
+ struct input_dev *dev = wacom->dev;
unsigned int t;
int idx;
int retval;
@@ -738,95 +738,83 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i
{
struct usb_device *dev = interface_to_usbdev(intf);
struct usb_endpoint_descriptor *endpoint;
- char rep_data[2] = {0x02, 0x02};
struct wacom *wacom;
- char path[64];
+ struct input_dev *input_dev;
+ char rep_data[2] = {0x02, 0x02};
- if (!(wacom = kmalloc(sizeof(struct wacom), GFP_KERNEL)))
- return -ENOMEM;
- memset(wacom, 0, sizeof(struct wacom));
+ wacom = kzalloc(sizeof(struct wacom), GFP_KERNEL);
+ input_dev = input_allocate_device();
+ if (!wacom || !input_dev)
+ goto fail1;
wacom->data = usb_buffer_alloc(dev, 10, GFP_KERNEL, &wacom->data_dma);
- if (!wacom->data) {
- kfree(wacom);
- return -ENOMEM;
- }
+ if (!wacom->data)
+ goto fail1;
wacom->irq = usb_alloc_urb(0, GFP_KERNEL);
- if (!wacom->irq) {
- usb_buffer_free(dev, 10, wacom->data, wacom->data_dma);
- kfree(wacom);
- return -ENOMEM;
- }
+ if (!wacom->irq)
+ goto fail2;
+
+ wacom->usbdev = dev;
+ wacom->dev = input_dev;
+ usb_make_path(dev, wacom->phys, sizeof(wacom->phys));
+ strlcat(wacom->phys, "/input0", sizeof(wacom->phys));
wacom->features = wacom_features + (id - wacom_ids);
+ if (wacom->features->pktlen > 10)
+ BUG();
+
+ input_dev->name = wacom->features->name;
+ usb_to_input_id(dev, &input_dev->id);
- wacom->dev.evbit[0] |= BIT(EV_KEY) | BIT(EV_ABS);
- wacom->dev.absbit[0] |= BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_PRESSURE);
- wacom->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_PEN) | BIT(BTN_TOUCH) | BIT(BTN_STYLUS);
+ input_dev->cdev.dev = &intf->dev;
+ input_dev->private = wacom;
+ input_dev->open = wacom_open;
+ input_dev->close = wacom_close;
+
+ input_dev->evbit[0] |= BIT(EV_KEY) | BIT(EV_ABS);
+ input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_PEN) | BIT(BTN_TOUCH) | BIT(BTN_STYLUS);
+ input_set_abs_params(input_dev, ABS_X, 0, wacom->features->y_max, 4, 0);
+ input_set_abs_params(input_dev, ABS_Y, 0, wacom->features->y_max, 4, 0);
+ input_set_abs_params(input_dev, ABS_PRESSURE, 0, wacom->features->pressure_max, 0, 0);
switch (wacom->features->type) {
case GRAPHIRE:
- wacom->dev.evbit[0] |= BIT(EV_REL);
- wacom->dev.relbit[0] |= BIT(REL_WHEEL);
- wacom->dev.absbit[0] |= BIT(ABS_DISTANCE);
- wacom->dev.keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE);
- wacom->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_RUBBER) | BIT(BTN_TOOL_MOUSE) | BIT(BTN_STYLUS2);
+ input_dev->evbit[0] |= BIT(EV_REL);
+ input_dev->relbit[0] |= BIT(REL_WHEEL);
+ input_dev->keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE);
+ input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_RUBBER) | BIT(BTN_TOOL_MOUSE) | BIT(BTN_STYLUS2);
+ input_set_abs_params(input_dev, ABS_DISTANCE, 0, wacom->features->distance_max, 0, 0);
break;
case INTUOS3:
case CINTIQ:
- wacom->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_FINGER);
- wacom->dev.keybit[LONG(BTN_LEFT)] |= BIT(BTN_0) | BIT(BTN_1) | BIT(BTN_2) | BIT(BTN_3) | BIT(BTN_4) | BIT(BTN_5) | BIT(BTN_6) | BIT(BTN_7);
- wacom->dev.absbit[0] |= BIT(ABS_RX) | BIT(ABS_RY);
+ input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_FINGER);
+ input_dev->keybit[LONG(BTN_LEFT)] |= BIT(BTN_0) | BIT(BTN_1) | BIT(BTN_2) | BIT(BTN_3) | BIT(BTN_4) | BIT(BTN_5) | BIT(BTN_6) | BIT(BTN_7);
+ input_set_abs_params(input_dev, ABS_RX, 0, 4097, 0, 0);
+ input_set_abs_params(input_dev, ABS_RY, 0, 4097, 0, 0);
/* fall through */
case INTUOS:
- wacom->dev.evbit[0] |= BIT(EV_MSC) | BIT(EV_REL);
- wacom->dev.mscbit[0] |= BIT(MSC_SERIAL);
- wacom->dev.relbit[0] |= BIT(REL_WHEEL);
- wacom->dev.keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE) | BIT(BTN_SIDE) | BIT(BTN_EXTRA);
- wacom->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_RUBBER) | BIT(BTN_TOOL_MOUSE) | BIT(BTN_TOOL_BRUSH)
+ input_dev->evbit[0] |= BIT(EV_MSC) | BIT(EV_REL);
+ input_dev->mscbit[0] |= BIT(MSC_SERIAL);
+ input_dev->relbit[0] |= BIT(REL_WHEEL);
+ input_dev->keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE) | BIT(BTN_SIDE) | BIT(BTN_EXTRA);
+ input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_RUBBER) | BIT(BTN_TOOL_MOUSE) | BIT(BTN_TOOL_BRUSH)
| BIT(BTN_TOOL_PENCIL) | BIT(BTN_TOOL_AIRBRUSH) | BIT(BTN_TOOL_LENS) | BIT(BTN_STYLUS2);
- wacom->dev.absbit[0] |= BIT(ABS_DISTANCE) | BIT(ABS_WHEEL) | BIT(ABS_TILT_X) | BIT(ABS_TILT_Y) | BIT(ABS_RZ) | BIT(ABS_THROTTLE);
+ input_set_abs_params(input_dev, ABS_DISTANCE, 0, wacom->features->distance_max, 0, 0);
+ input_set_abs_params(input_dev, ABS_WHEEL, 0, 1023, 0, 0);
+ input_set_abs_params(input_dev, ABS_TILT_X, 0, 127, 0, 0);
+ input_set_abs_params(input_dev, ABS_TILT_Y, 0, 127, 0, 0);
+ input_set_abs_params(input_dev, ABS_RZ, -900, 899, 0, 0);
+ input_set_abs_params(input_dev, ABS_THROTTLE, -1023, 1023, 0, 0);
break;
case PL:
- wacom->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_STYLUS2) | BIT(BTN_TOOL_RUBBER);
+ input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_STYLUS2) | BIT(BTN_TOOL_RUBBER);
break;
}
- wacom->dev.absmax[ABS_X] = wacom->features->x_max;
- wacom->dev.absmax[ABS_Y] = wacom->features->y_max;
- wacom->dev.absmax[ABS_PRESSURE] = wacom->features->pressure_max;
- wacom->dev.absmax[ABS_DISTANCE] = wacom->features->distance_max;
- wacom->dev.absmax[ABS_TILT_X] = 127;
- wacom->dev.absmax[ABS_TILT_Y] = 127;
- wacom->dev.absmax[ABS_WHEEL] = 1023;
-
- wacom->dev.absmax[ABS_RX] = 4097;
- wacom->dev.absmax[ABS_RY] = 4097;
- wacom->dev.absmin[ABS_RZ] = -900;
- wacom->dev.absmax[ABS_RZ] = 899;
- wacom->dev.absmin[ABS_THROTTLE] = -1023;
- wacom->dev.absmax[ABS_THROTTLE] = 1023;
-
- wacom->dev.absfuzz[ABS_X] = 4;
- wacom->dev.absfuzz[ABS_Y] = 4;
-
- wacom->dev.private = wacom;
- wacom->dev.open = wacom_open;
- wacom->dev.close = wacom_close;
-
- usb_make_path(dev, path, 64);
- sprintf(wacom->phys, "%s/input0", path);
-
- wacom->dev.name = wacom->features->name;
- wacom->dev.phys = wacom->phys;
- usb_to_input_id(dev, &wacom->dev.id);
- wacom->dev.dev = &intf->dev;
- wacom->usbdev = dev;
-
endpoint = &intf->cur_altsetting->endpoint[0].desc;
if (wacom->features->pktlen > 10)
@@ -839,18 +827,20 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i
wacom->irq->transfer_dma = wacom->data_dma;
wacom->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
- input_register_device(&wacom->dev);
+ input_register_device(wacom->dev);
/* ask the tablet to report tablet data */
usb_set_report(intf, 3, 2, rep_data, 2);
/* repeat once (not sure why the first call often fails) */
usb_set_report(intf, 3, 2, rep_data, 2);
- printk(KERN_INFO "input: %s on %s\n", wacom->features->name, path);
-
usb_set_intfdata(intf, wacom);
-
return 0;
+
+fail2: usb_buffer_free(dev, 10, wacom->data, wacom->data_dma);
+fail1: input_free_device(input_dev);
+ kfree(wacom);
+ return -ENOMEM;
}
static void wacom_disconnect(struct usb_interface *intf)
@@ -860,7 +850,7 @@ static void wacom_disconnect(struct usb_interface *intf)
usb_set_intfdata(intf, NULL);
if (wacom) {
usb_kill_urb(wacom->irq);
- input_unregister_device(&wacom->dev);
+ input_unregister_device(wacom->dev);
usb_free_urb(wacom->irq);
usb_buffer_free(interface_to_usbdev(intf), 10, wacom->data, wacom->data_dma);
kfree(wacom);
diff --git a/drivers/usb/input/xpad.c b/drivers/usb/input/xpad.c
index 18125e0bffa2..43112f040b6d 100644
--- a/drivers/usb/input/xpad.c
+++ b/drivers/usb/input/xpad.c
@@ -103,7 +103,7 @@ static struct usb_device_id xpad_table [] = {
MODULE_DEVICE_TABLE (usb, xpad_table);
struct usb_xpad {
- struct input_dev dev; /* input device interface */
+ struct input_dev *dev; /* input device interface */
struct usb_device *udev; /* usb device */
struct urb *irq_in; /* urb for interrupt in report */
@@ -125,7 +125,7 @@ struct usb_xpad {
static void xpad_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char *data, struct pt_regs *regs)
{
- struct input_dev *dev = &xpad->dev;
+ struct input_dev *dev = xpad->dev;
input_regs(dev, regs);
@@ -214,9 +214,9 @@ static void xpad_close (struct input_dev *dev)
static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id)
{
struct usb_device *udev = interface_to_usbdev (intf);
- struct usb_xpad *xpad = NULL;
+ struct usb_xpad *xpad;
+ struct input_dev *input_dev;
struct usb_endpoint_descriptor *ep_irq_in;
- char path[64];
int i;
for (i = 0; xpad_device[i].idVendor; i++) {
@@ -225,89 +225,80 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
break;
}
- if ((xpad = kmalloc (sizeof(struct usb_xpad), GFP_KERNEL)) == NULL) {
- err("cannot allocate memory for new pad");
- return -ENOMEM;
- }
- memset(xpad, 0, sizeof(struct usb_xpad));
+ xpad = kzalloc(sizeof(struct usb_xpad), GFP_KERNEL);
+ input_dev = input_allocate_device();
+ if (!xpad || !input_dev)
+ goto fail1;
xpad->idata = usb_buffer_alloc(udev, XPAD_PKT_LEN,
SLAB_ATOMIC, &xpad->idata_dma);
- if (!xpad->idata) {
- kfree(xpad);
- return -ENOMEM;
- }
+ if (!xpad->idata)
+ goto fail1;
xpad->irq_in = usb_alloc_urb(0, GFP_KERNEL);
- if (!xpad->irq_in) {
- err("cannot allocate memory for new pad irq urb");
- usb_buffer_free(udev, XPAD_PKT_LEN, xpad->idata, xpad->idata_dma);
- kfree(xpad);
- return -ENOMEM;
- }
-
- ep_irq_in = &intf->cur_altsetting->endpoint[0].desc;
-
- usb_fill_int_urb(xpad->irq_in, udev,
- usb_rcvintpipe(udev, ep_irq_in->bEndpointAddress),
- xpad->idata, XPAD_PKT_LEN, xpad_irq_in,
- xpad, ep_irq_in->bInterval);
- xpad->irq_in->transfer_dma = xpad->idata_dma;
- xpad->irq_in->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+ if (!xpad->irq_in)
+ goto fail2;
xpad->udev = udev;
+ xpad->dev = input_dev;
+ usb_make_path(udev, xpad->phys, sizeof(xpad->phys));
+ strlcat(xpad->phys, "/input0", sizeof(xpad->phys));
- usb_to_input_id(udev, &xpad->dev.id);
- xpad->dev.dev = &intf->dev;
- xpad->dev.private = xpad;
- xpad->dev.name = xpad_device[i].name;
- xpad->dev.phys = xpad->phys;
- xpad->dev.open = xpad_open;
- xpad->dev.close = xpad_close;
-
- usb_make_path(udev, path, 64);
- snprintf(xpad->phys, 64, "%s/input0", path);
+ input_dev->name = xpad_device[i].name;
+ input_dev->phys = xpad->phys;
+ usb_to_input_id(udev, &input_dev->id);
+ input_dev->cdev.dev = &intf->dev;
+ input_dev->private = xpad;
+ input_dev->open = xpad_open;
+ input_dev->close = xpad_close;
- xpad->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+ input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
for (i = 0; xpad_btn[i] >= 0; i++)
- set_bit(xpad_btn[i], xpad->dev.keybit);
+ set_bit(xpad_btn[i], input_dev->keybit);
for (i = 0; xpad_abs[i] >= 0; i++) {
signed short t = xpad_abs[i];
- set_bit(t, xpad->dev.absbit);
+ set_bit(t, input_dev->absbit);
switch (t) {
case ABS_X:
case ABS_Y:
case ABS_RX:
case ABS_RY: /* the two sticks */
- xpad->dev.absmax[t] = 32767;
- xpad->dev.absmin[t] = -32768;
- xpad->dev.absflat[t] = 128;
- xpad->dev.absfuzz[t] = 16;
+ input_set_abs_params(input_dev, t, -32768, 32767, 16, 128);
break;
case ABS_Z:
case ABS_RZ: /* the triggers */
- xpad->dev.absmax[t] = 255;
- xpad->dev.absmin[t] = 0;
+ input_set_abs_params(input_dev, t, 0, 255, 0, 0);
break;
case ABS_HAT0X:
case ABS_HAT0Y: /* the d-pad */
- xpad->dev.absmax[t] = 1;
- xpad->dev.absmin[t] = -1;
+ input_set_abs_params(input_dev, t, -1, 1, 0, 0);
break;
}
}
- input_register_device(&xpad->dev);
+ ep_irq_in = &intf->cur_altsetting->endpoint[0].desc;
+ usb_fill_int_urb(xpad->irq_in, udev,
+ usb_rcvintpipe(udev, ep_irq_in->bEndpointAddress),
+ xpad->idata, XPAD_PKT_LEN, xpad_irq_in,
+ xpad, ep_irq_in->bInterval);
+ xpad->irq_in->transfer_dma = xpad->idata_dma;
+ xpad->irq_in->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
- printk(KERN_INFO "input: %s on %s", xpad->dev.name, path);
+ input_register_device(xpad->dev);
usb_set_intfdata(intf, xpad);
return 0;
+
+fail2: usb_buffer_free(udev, XPAD_PKT_LEN, xpad->idata, xpad->idata_dma);
+fail1: input_free_device(input_dev);
+ kfree(xpad);
+ return -ENOMEM;
+
}
static void xpad_disconnect(struct usb_interface *intf)
@@ -317,7 +308,7 @@ static void xpad_disconnect(struct usb_interface *intf)
usb_set_intfdata(intf, NULL);
if (xpad) {
usb_kill_urb(xpad->irq_in);
- input_unregister_device(&xpad->dev);
+ input_unregister_device(xpad->dev);
usb_free_urb(xpad->irq_in);
usb_buffer_free(interface_to_usbdev(intf), XPAD_PKT_LEN, xpad->idata, xpad->idata_dma);
kfree(xpad);
diff --git a/drivers/usb/input/yealink.c b/drivers/usb/input/yealink.c
index 58a176ef96a5..f526aebea502 100644
--- a/drivers/usb/input/yealink.c
+++ b/drivers/usb/input/yealink.c
@@ -54,6 +54,7 @@
#include <linux/module.h>
#include <linux/rwsem.h>
#include <linux/usb.h>
+#include <linux/usb_input.h>
#include "map_to_7segment.h"
#include "yealink.h"
@@ -101,12 +102,12 @@ static const struct lcd_segment_map {
};
struct yealink_dev {
- struct input_dev idev; /* input device */
+ struct input_dev *idev; /* input device */
struct usb_device *udev; /* usb device */
/* irq input channel */
struct yld_ctl_packet *irq_data;
- dma_addr_t irq_dma;
+ dma_addr_t irq_dma;
struct urb *urb_irq;
/* control output channel */
@@ -237,7 +238,7 @@ static int map_p1k_to_key(int scancode)
*/
static void report_key(struct yealink_dev *yld, int key, struct pt_regs *regs)
{
- struct input_dev *idev = &yld->idev;
+ struct input_dev *idev = yld->idev;
input_regs(idev, regs);
if (yld->key_code >= 0) {
@@ -809,8 +810,12 @@ static int usb_cleanup(struct yealink_dev *yld, int err)
}
if (yld->urb_ctl)
usb_free_urb(yld->urb_ctl);
- if (yld->idev.dev)
- input_unregister_device(&yld->idev);
+ if (yld->idev) {
+ if (err)
+ input_free_device(yld->idev);
+ else
+ input_unregister_device(yld->idev);
+ }
if (yld->ctl_req)
usb_buffer_free(yld->udev, sizeof(*(yld->ctl_req)),
yld->ctl_req, yld->ctl_req_dma);
@@ -857,7 +862,7 @@ static int usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
struct usb_host_interface *interface;
struct usb_endpoint_descriptor *endpoint;
struct yealink_dev *yld;
- char path[64];
+ struct input_dev *input_dev;
int ret, pipe, i;
i = usb_match(udev);
@@ -866,17 +871,21 @@ static int usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
interface = intf->cur_altsetting;
endpoint = &interface->endpoint[0].desc;
- if (!(endpoint->bEndpointAddress & 0x80))
+ if (!(endpoint->bEndpointAddress & USB_DIR_IN))
return -EIO;
- if ((endpoint->bmAttributes & 3) != 3)
+ if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_INT)
return -EIO;
- if ((yld = kmalloc(sizeof(struct yealink_dev), GFP_KERNEL)) == NULL)
+ yld = kzalloc(sizeof(struct yealink_dev), GFP_KERNEL);
+ if (!yld)
return -ENOMEM;
- memset(yld, 0, sizeof(*yld));
yld->udev = udev;
+ yld->idev = input_dev = input_allocate_device();
+ if (!input_dev)
+ return usb_cleanup(yld, -ENOMEM);
+
/* allocate usb buffers */
yld->irq_data = usb_buffer_alloc(udev, USB_PKT_LEN,
SLAB_ATOMIC, &yld->irq_dma);
@@ -935,42 +944,37 @@ static int usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
yld->urb_ctl->dev = udev;
/* find out the physical bus location */
- if (usb_make_path(udev, path, sizeof(path)) > 0)
- snprintf(yld->phys, sizeof(yld->phys)-1, "%s/input0", path);
+ usb_make_path(udev, yld->phys, sizeof(yld->phys));
+ strlcat(yld->phys, "/input0", sizeof(yld->phys));
/* register settings for the input device */
- init_input_dev(&yld->idev);
- yld->idev.private = yld;
- yld->idev.id.bustype = BUS_USB;
- yld->idev.id.vendor = le16_to_cpu(udev->descriptor.idVendor);
- yld->idev.id.product = le16_to_cpu(udev->descriptor.idProduct);
- yld->idev.id.version = le16_to_cpu(udev->descriptor.bcdDevice);
- yld->idev.dev = &intf->dev;
- yld->idev.name = yld_device[i].name;
- yld->idev.phys = yld->phys;
- /* yld->idev.event = input_ev; TODO */
- yld->idev.open = input_open;
- yld->idev.close = input_close;
+ input_dev->name = yld_device[i].name;
+ input_dev->phys = yld->phys;
+ usb_to_input_id(udev, &input_dev->id);
+ input_dev->cdev.dev = &intf->dev;
+
+ input_dev->private = yld;
+ input_dev->open = input_open;
+ input_dev->close = input_close;
+ /* input_dev->event = input_ev; TODO */
/* register available key events */
- yld->idev.evbit[0] = BIT(EV_KEY);
+ input_dev->evbit[0] = BIT(EV_KEY);
for (i = 0; i < 256; i++) {
int k = map_p1k_to_key(i);
if (k >= 0) {
- set_bit(k & 0xff, yld->idev.keybit);
+ set_bit(k & 0xff, input_dev->keybit);
if (k >> 8)
- set_bit(k >> 8, yld->idev.keybit);
+ set_bit(k >> 8, input_dev->keybit);
}
}
- printk(KERN_INFO "input: %s on %s\n", yld->idev.name, path);
-
- input_register_device(&yld->idev);
+ input_register_device(yld->idev);
usb_set_intfdata(intf, yld);
/* clear visible elements */
- for (i=0; i<ARRAY_SIZE(lcdMap); i++)
+ for (i = 0; i < ARRAY_SIZE(lcdMap); i++)
setChar(yld, i, ' ');
/* display driver version on LCD line 3 */
diff --git a/drivers/usb/media/dabusb.c b/drivers/usb/media/dabusb.c
index 6ca2fae99d2d..27b23c55bbc7 100644
--- a/drivers/usb/media/dabusb.c
+++ b/drivers/usb/media/dabusb.c
@@ -707,9 +707,8 @@ static struct file_operations dabusb_fops =
};
static struct usb_class_driver dabusb_class = {
- .name = "usb/dabusb%d",
+ .name = "dabusb%d",
.fops = &dabusb_fops,
- .mode = S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP,
.minor_base = DABUSB_MINOR,
};
diff --git a/drivers/usb/media/konicawc.c b/drivers/usb/media/konicawc.c
index 20ac9e1069d4..9fe2c2710d13 100644
--- a/drivers/usb/media/konicawc.c
+++ b/drivers/usb/media/konicawc.c
@@ -119,7 +119,7 @@ struct konicawc {
int yplanesz; /* Number of bytes in the Y plane */
unsigned int buttonsts:1;
#ifdef CONFIG_INPUT
- struct input_dev input;
+ struct input_dev *input;
char input_physname[64];
#endif
};
@@ -218,6 +218,57 @@ static void konicawc_adjust_picture(struct uvd *uvd)
konicawc_camera_on(uvd);
}
+#ifdef CONFIG_INPUT
+
+static void konicawc_register_input(struct konicawc *cam, struct usb_device *dev)
+{
+ struct input_dev *input_dev;
+
+ usb_make_path(dev, cam->input_physname, sizeof(cam->input_physname));
+ strncat(cam->input_physname, "/input0", sizeof(cam->input_physname));
+
+ cam->input = input_dev = input_allocate_device();
+ if (!input_dev) {
+ warn("Not enough memory for camera's input device\n");
+ return;
+ }
+
+ input_dev->name = "Konicawc snapshot button";
+ input_dev->phys = cam->input_physname;
+ usb_to_input_id(dev, &input_dev->id);
+ input_dev->cdev.dev = &dev->dev;
+
+ input_dev->evbit[0] = BIT(EV_KEY);
+ input_dev->keybit[LONG(BTN_0)] = BIT(BTN_0);
+
+ input_dev->private = cam;
+
+ input_register_device(cam->input);
+}
+
+static void konicawc_unregister_input(struct konicawc *cam)
+{
+ if (cam->input) {
+ input_unregister_device(cam->input);
+ cam->input = NULL;
+ }
+}
+
+static void konicawc_report_buttonstat(struct konicawc *cam)
+{
+ if (cam->input) {
+ input_report_key(cam->input, BTN_0, cam->buttonsts);
+ input_sync(cam->input);
+ }
+}
+
+#else
+
+static inline void konicawc_register_input(struct konicawc *cam, struct usb_device *dev) { }
+static inline void konicawc_unregister_input(struct konicawc *cam) { }
+static inline void konicawc_report_buttonstat(struct konicawc *cam) { }
+
+#endif /* CONFIG_INPUT */
static int konicawc_compress_iso(struct uvd *uvd, struct urb *dataurb, struct urb *stsurb)
{
@@ -273,10 +324,7 @@ static int konicawc_compress_iso(struct uvd *uvd, struct urb *dataurb, struct ur
if(button != cam->buttonsts) {
DEBUG(2, "button: %sclicked", button ? "" : "un");
cam->buttonsts = button;
-#ifdef CONFIG_INPUT
- input_report_key(&cam->input, BTN_0, cam->buttonsts);
- input_sync(&cam->input);
-#endif
+ konicawc_report_buttonstat(cam);
}
if(sts == 0x01) { /* drop frame */
@@ -645,9 +693,9 @@ static int konicawc_set_video_mode(struct uvd *uvd, struct video_window *vw)
RingQueue_Flush(&uvd->dp);
cam->lastframe = -2;
if(uvd->curframe != -1) {
- uvd->frame[uvd->curframe].curline = 0;
- uvd->frame[uvd->curframe].seqRead_Length = 0;
- uvd->frame[uvd->curframe].seqRead_Index = 0;
+ uvd->frame[uvd->curframe].curline = 0;
+ uvd->frame[uvd->curframe].seqRead_Length = 0;
+ uvd->frame[uvd->curframe].seqRead_Index = 0;
}
konicawc_start_data(uvd);
@@ -718,7 +766,6 @@ static void konicawc_configure_video(struct uvd *uvd)
DEBUG(1, "setting initial values");
}
-
static int konicawc_probe(struct usb_interface *intf, const struct usb_device_id *devid)
{
struct usb_device *dev = interface_to_usbdev(intf);
@@ -839,21 +886,8 @@ static int konicawc_probe(struct usb_interface *intf, const struct usb_device_id
err("usbvideo_RegisterVideoDevice() failed.");
uvd = NULL;
}
-#ifdef CONFIG_INPUT
- /* Register input device for button */
- memset(&cam->input, 0, sizeof(struct input_dev));
- cam->input.name = "Konicawc snapshot button";
- cam->input.private = cam;
- cam->input.evbit[0] = BIT(EV_KEY);
- cam->input.keybit[LONG(BTN_0)] = BIT(BTN_0);
- usb_to_input_id(dev, &cam->input.id);
- input_register_device(&cam->input);
-
- usb_make_path(dev, cam->input_physname, 56);
- strcat(cam->input_physname, "/input0");
- cam->input.phys = cam->input_physname;
- info("konicawc: %s on %s\n", cam->input.name, cam->input.phys);
-#endif
+
+ konicawc_register_input(cam, dev);
}
if (uvd) {
@@ -869,10 +903,9 @@ static void konicawc_free_uvd(struct uvd *uvd)
int i;
struct konicawc *cam = (struct konicawc *)uvd->user_data;
-#ifdef CONFIG_INPUT
- input_unregister_device(&cam->input);
-#endif
- for (i=0; i < USBVIDEO_NUMSBUF; i++) {
+ konicawc_unregister_input(cam);
+
+ for (i = 0; i < USBVIDEO_NUMSBUF; i++) {
usb_free_urb(cam->sts_urb[i]);
cam->sts_urb[i] = NULL;
}
diff --git a/drivers/usb/media/pwc/pwc-if.c b/drivers/usb/media/pwc/pwc-if.c
index b77e65c03659..5524fd70210b 100644
--- a/drivers/usb/media/pwc/pwc-if.c
+++ b/drivers/usb/media/pwc/pwc-if.c
@@ -62,6 +62,7 @@
#include <linux/poll.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
+#include <linux/version.h>
#include <asm/io.h>
#include "pwc.h"
diff --git a/drivers/usb/media/pwc/pwc.h b/drivers/usb/media/pwc/pwc.h
index 267869dab185..6dd76bb3dff1 100644
--- a/drivers/usb/media/pwc/pwc.h
+++ b/drivers/usb/media/pwc/pwc.h
@@ -25,8 +25,6 @@
#ifndef PWC_H
#define PWC_H
-#include <linux/version.h>
-
#include <linux/config.h>
#include <linux/module.h>
#include <linux/usb.h>
diff --git a/drivers/usb/media/w9968cf.c b/drivers/usb/media/w9968cf.c
index f36c0b6c6e36..67612c81cb9f 100644
--- a/drivers/usb/media/w9968cf.c
+++ b/drivers/usb/media/w9968cf.c
@@ -25,7 +25,6 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
***************************************************************************/
-#include <linux/version.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/kmod.h>
diff --git a/drivers/usb/misc/auerswald.c b/drivers/usb/misc/auerswald.c
index ae4681f9f0ea..5f33f7c64885 100644
--- a/drivers/usb/misc/auerswald.c
+++ b/drivers/usb/misc/auerswald.c
@@ -1873,9 +1873,8 @@ static struct file_operations auerswald_fops =
};
static struct usb_class_driver auerswald_class = {
- .name = "usb/auer%d",
+ .name = "auer%d",
.fops = &auerswald_fops,
- .mode = S_IFCHR | S_IRUGO | S_IWUGO,
.minor_base = AUER_MINOR_BASE,
};
diff --git a/drivers/usb/misc/idmouse.c b/drivers/usb/misc/idmouse.c
index 733acc213726..1dc3e0f73014 100644
--- a/drivers/usb/misc/idmouse.c
+++ b/drivers/usb/misc/idmouse.c
@@ -105,11 +105,10 @@ static struct file_operations idmouse_fops = {
.release = idmouse_release,
};
-/* class driver information for devfs */
+/* class driver information */
static struct usb_class_driver idmouse_class = {
- .name = "usb/idmouse%d",
+ .name = "idmouse%d",
.fops = &idmouse_fops,
- .mode = S_IFCHR | S_IRUSR | S_IRGRP | S_IROTH, /* filemode (char, 444) */
.minor_base = USB_IDMOUSE_MINOR_BASE,
};
@@ -320,20 +319,8 @@ static ssize_t idmouse_read(struct file *file, char __user *buffer, size_t count
return -ENODEV;
}
- if (*ppos >= IMGSIZE) {
- up (&dev->sem);
- return 0;
- }
-
- count = min ((loff_t)count, IMGSIZE - (*ppos));
-
- if (copy_to_user (buffer, dev->bulk_in_buffer + *ppos, count)) {
- result = -EFAULT;
- } else {
- result = count;
- *ppos += count;
- }
-
+ result = simple_read_from_buffer(buffer, count, ppos,
+ dev->bulk_in_buffer, IMGSIZE);
/* unlock the device */
up(&dev->sem);
return result;
diff --git a/drivers/usb/misc/legousbtower.c b/drivers/usb/misc/legousbtower.c
index 7d06105763d4..2703e205bc8f 100644
--- a/drivers/usb/misc/legousbtower.c
+++ b/drivers/usb/misc/legousbtower.c
@@ -271,12 +271,11 @@ static struct file_operations tower_fops = {
/*
* usb class driver info in order to get a minor number from the usb core,
- * and to have the device registered with devfs and the driver core
+ * and to have the device registered with the driver core
*/
static struct usb_class_driver tower_class = {
- .name = "usb/legousbtower%d",
+ .name = "legousbtower%d",
.fops = &tower_fops,
- .mode = S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH,
.minor_base = LEGO_USB_TOWER_MINOR_BASE,
};
diff --git a/drivers/usb/misc/rio500.c b/drivers/usb/misc/rio500.c
index 26f77e29c7a6..7d02d8ec6b1a 100644
--- a/drivers/usb/misc/rio500.c
+++ b/drivers/usb/misc/rio500.c
@@ -443,9 +443,8 @@ file_operations usb_rio_fops = {
};
static struct usb_class_driver usb_rio_class = {
- .name = "usb/rio500%d",
+ .name = "rio500%d",
.fops = &usb_rio_fops,
- .mode = S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP,
.minor_base = RIO_MINOR,
};
diff --git a/drivers/usb/misc/sisusbvga/sisusb.c b/drivers/usb/misc/sisusbvga/sisusb.c
index 39db3155723a..41ef2b606751 100644
--- a/drivers/usb/misc/sisusbvga/sisusb.c
+++ b/drivers/usb/misc/sisusbvga/sisusb.c
@@ -37,7 +37,6 @@
*/
#include <linux/config.h>
-#include <linux/version.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/signal.h>
@@ -2440,7 +2439,7 @@ int
sisusb_reset_text_mode(struct sisusb_usb_data *sisusb, int init)
{
int ret = 0, slot = sisusb->font_slot, i;
- struct font_desc *myfont;
+ const struct font_desc *myfont;
u8 *tempbuf;
u16 *tempbufb;
size_t written;
@@ -3239,12 +3238,7 @@ static struct file_operations usb_sisusb_fops = {
};
static struct usb_class_driver usb_sisusb_class = {
-#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,13)
- .name = "usb/sisusbvga%d",
- .mode = S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP,
-#else
.name = "sisusbvga%d",
-#endif
.fops = &usb_sisusb_fops,
.minor_base = SISUSB_MINOR
};
diff --git a/drivers/usb/misc/sisusbvga/sisusb.h b/drivers/usb/misc/sisusbvga/sisusb.h
index 401ff21d7881..1d7a77cc7c4a 100644
--- a/drivers/usb/misc/sisusbvga/sisusb.h
+++ b/drivers/usb/misc/sisusbvga/sisusb.h
@@ -37,6 +37,7 @@
#ifndef _SISUSB_H_
#define _SISUSB_H_
+#include <linux/version.h>
#ifdef CONFIG_COMPAT
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,10)
#include <linux/ioctl32.h>
diff --git a/drivers/usb/misc/sisusbvga/sisusb_con.c b/drivers/usb/misc/sisusbvga/sisusb_con.c
index 24584463553d..be5c1a25ae21 100644
--- a/drivers/usb/misc/sisusbvga/sisusb_con.c
+++ b/drivers/usb/misc/sisusbvga/sisusb_con.c
@@ -48,7 +48,6 @@
*/
#include <linux/config.h>
-#include <linux/version.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/signal.h>
diff --git a/drivers/usb/misc/sisusbvga/sisusb_init.c b/drivers/usb/misc/sisusbvga/sisusb_init.c
index f28bc240f9b6..044fa4482f9f 100644
--- a/drivers/usb/misc/sisusbvga/sisusb_init.c
+++ b/drivers/usb/misc/sisusbvga/sisusb_init.c
@@ -37,7 +37,6 @@
*/
#include <linux/config.h>
-#include <linux/version.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/errno.h>
diff --git a/drivers/usb/misc/usblcd.c b/drivers/usb/misc/usblcd.c
index 096ab3029676..85f3725334b0 100644
--- a/drivers/usb/misc/usblcd.c
+++ b/drivers/usb/misc/usblcd.c
@@ -251,13 +251,12 @@ static struct file_operations lcd_fops = {
};
/*
- * * usb class driver info in order to get a minor number from the usb core,
- * * and to have the device registered with devfs and the driver core
- * */
+ * usb class driver info in order to get a minor number from the usb core,
+ * and to have the device registered with the driver core
+ */
static struct usb_class_driver lcd_class = {
- .name = "usb/lcd%d",
+ .name = "lcd%d",
.fops = &lcd_fops,
- .mode = S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH,
.minor_base = USBLCD_MINOR,
};
diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c
index 54799eb0bc60..2997f558159b 100644
--- a/drivers/usb/misc/usbtest.c
+++ b/drivers/usb/misc/usbtest.c
@@ -9,7 +9,7 @@
#include <linux/mm.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
-#include <asm/scatterlist.h>
+#include <linux/scatterlist.h>
#include <linux/usb.h>
@@ -381,7 +381,6 @@ alloc_sglist (int nents, int max, int vary)
sg = kmalloc (nents * sizeof *sg, SLAB_KERNEL);
if (!sg)
return NULL;
- memset (sg, 0, nents * sizeof *sg);
for (i = 0; i < nents; i++) {
char *buf;
@@ -394,9 +393,7 @@ alloc_sglist (int nents, int max, int vary)
memset (buf, 0, size);
/* kmalloc pages are always physically contiguous! */
- sg [i].page = virt_to_page (buf);
- sg [i].offset = offset_in_page (buf);
- sg [i].length = size;
+ sg_init_one(&sg[i], buf, size);
if (vary) {
size += vary;
@@ -983,6 +980,7 @@ test_ctrl_queue (struct usbtest_dev *dev, struct usbtest_param *param)
reqp->number = i % NUM_SUBCASES;
reqp->expected = expected;
u->setup_packet = (char *) &reqp->setup;
+ u->transfer_flags |= URB_NO_SETUP_DMA_MAP;
u->context = &context;
u->complete = ctrl_complete;
@@ -1948,21 +1946,11 @@ usbtest_probe (struct usb_interface *intf, const struct usb_device_id *id)
static int usbtest_suspend (struct usb_interface *intf, pm_message_t message)
{
- struct usbtest_dev *dev = usb_get_intfdata (intf);
-
- down (&dev->sem);
- intf->dev.power.power_state = PMSG_SUSPEND;
- up (&dev->sem);
return 0;
}
static int usbtest_resume (struct usb_interface *intf)
{
- struct usbtest_dev *dev = usb_get_intfdata (intf);
-
- down (&dev->sem);
- intf->dev.power.power_state = PMSG_ON;
- up (&dev->sem);
return 0;
}
diff --git a/drivers/usb/misc/uss720.c b/drivers/usb/misc/uss720.c
index 03fb70ef2eb3..0592cb5e6c4d 100644
--- a/drivers/usb/misc/uss720.c
+++ b/drivers/usb/misc/uss720.c
@@ -137,7 +137,7 @@ static void async_complete(struct urb *urb, struct pt_regs *ptregs)
static struct uss720_async_request *submit_async_request(struct parport_uss720_private *priv,
__u8 request, __u8 requesttype, __u16 value, __u16 index,
- unsigned int mem_flags)
+ gfp_t mem_flags)
{
struct usb_device *usbdev;
struct uss720_async_request *rq;
@@ -204,7 +204,7 @@ static unsigned int kill_all_async_requests_priv(struct parport_uss720_private *
/* --------------------------------------------------------------------- */
-static int get_1284_register(struct parport *pp, unsigned char reg, unsigned char *val, unsigned int mem_flags)
+static int get_1284_register(struct parport *pp, unsigned char reg, unsigned char *val, gfp_t mem_flags)
{
struct parport_uss720_private *priv;
struct uss720_async_request *rq;
@@ -238,7 +238,7 @@ static int get_1284_register(struct parport *pp, unsigned char reg, unsigned cha
return -EIO;
}
-static int set_1284_register(struct parport *pp, unsigned char reg, unsigned char val, unsigned int mem_flags)
+static int set_1284_register(struct parport *pp, unsigned char reg, unsigned char val, gfp_t mem_flags)
{
struct parport_uss720_private *priv;
struct uss720_async_request *rq;
diff --git a/drivers/usb/mon/mon_main.c b/drivers/usb/mon/mon_main.c
index 508a21028db4..c34944c75047 100644
--- a/drivers/usb/mon/mon_main.c
+++ b/drivers/usb/mon/mon_main.c
@@ -11,6 +11,7 @@
#include <linux/usb.h>
#include <linux/debugfs.h>
#include <linux/smp_lock.h>
+#include <linux/notifier.h>
#include "usb_mon.h"
#include "../core/hcd.h"
@@ -205,6 +206,23 @@ static void mon_bus_remove(struct usb_bus *ubus)
up(&mon_lock);
}
+static int mon_notify(struct notifier_block *self, unsigned long action,
+ void *dev)
+{
+ switch (action) {
+ case USB_BUS_ADD:
+ mon_bus_add(dev);
+ break;
+ case USB_BUS_REMOVE:
+ mon_bus_remove(dev);
+ }
+ return NOTIFY_OK;
+}
+
+static struct notifier_block mon_nb = {
+ .notifier_call = mon_notify,
+};
+
/*
* Ops
*/
@@ -212,8 +230,6 @@ static struct usb_mon_operations mon_ops_0 = {
.urb_submit = mon_submit,
.urb_submit_error = mon_submit_error,
.urb_complete = mon_complete,
- .bus_add = mon_bus_add,
- .bus_remove = mon_bus_remove,
};
/*
@@ -329,6 +345,8 @@ static int __init mon_init(void)
}
// MOD_INC_USE_COUNT(which_module?);
+ usb_register_notify(&mon_nb);
+
down(&usb_bus_list_lock);
list_for_each_entry (ubus, &usb_bus_list, bus_list) {
mon_bus_init(mondir, ubus);
@@ -342,6 +360,7 @@ static void __exit mon_exit(void)
struct mon_bus *mbus;
struct list_head *p;
+ usb_unregister_notify(&mon_nb);
usb_mon_deregister();
down(&mon_lock);
diff --git a/drivers/usb/net/Kconfig b/drivers/usb/net/Kconfig
index 8c010bb44eb8..efd6ca7e4ac5 100644
--- a/drivers/usb/net/Kconfig
+++ b/drivers/usb/net/Kconfig
@@ -294,7 +294,7 @@ config USB_NET_ZAURUS
This also supports some related device firmware, as used in some
PDAs from Olympus and some cell phones from Motorola.
- If you install an alternate ROM image, such as the Linux 2.6 based
+ If you install an alternate image, such as the Linux 2.6 based
versions of OpenZaurus, you should no longer need to support this
protocol. Only the "eth-fd" or "net_fd" drivers in these devices
really need this non-conformant variant of CDC Ethernet (or in
diff --git a/drivers/usb/net/asix.c b/drivers/usb/net/asix.c
index 861f00a43750..252a34fbb42c 100644
--- a/drivers/usb/net/asix.c
+++ b/drivers/usb/net/asix.c
@@ -753,7 +753,7 @@ static int ax88772_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
}
static struct sk_buff *ax88772_tx_fixup(struct usbnet *dev, struct sk_buff *skb,
- unsigned flags)
+ gfp_t flags)
{
int padlen;
int headroom = skb_headroom(skb);
diff --git a/drivers/usb/net/gl620a.c b/drivers/usb/net/gl620a.c
index c8763ae33c73..c0f263b202a6 100644
--- a/drivers/usb/net/gl620a.c
+++ b/drivers/usb/net/gl620a.c
@@ -301,7 +301,7 @@ static int genelink_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
}
static struct sk_buff *
-genelink_tx_fixup(struct usbnet *dev, struct sk_buff *skb, unsigned flags)
+genelink_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags)
{
int padlen;
int length = skb->len;
diff --git a/drivers/usb/net/kaweth.c b/drivers/usb/net/kaweth.c
index e04b0ce3611a..6bef1be6b36c 100644
--- a/drivers/usb/net/kaweth.c
+++ b/drivers/usb/net/kaweth.c
@@ -469,7 +469,7 @@ static int kaweth_reset(struct kaweth_device *kaweth)
0,
KAWETH_CONTROL_TIMEOUT);
- udelay(10000);
+ mdelay(10);
kaweth_dbg("kaweth_reset() returns %d.",result);
@@ -477,13 +477,13 @@ static int kaweth_reset(struct kaweth_device *kaweth)
}
static void kaweth_usb_receive(struct urb *, struct pt_regs *regs);
-static int kaweth_resubmit_rx_urb(struct kaweth_device *, unsigned);
+static int kaweth_resubmit_rx_urb(struct kaweth_device *, gfp_t);
/****************************************************************
int_callback
*****************************************************************/
-static void kaweth_resubmit_int_urb(struct kaweth_device *kaweth, int mf)
+static void kaweth_resubmit_int_urb(struct kaweth_device *kaweth, gfp_t mf)
{
int status;
@@ -550,7 +550,7 @@ static void kaweth_resubmit_tl(void *d)
* kaweth_resubmit_rx_urb
****************************************************************/
static int kaweth_resubmit_rx_urb(struct kaweth_device *kaweth,
- unsigned mem_flags)
+ gfp_t mem_flags)
{
int result;
diff --git a/drivers/usb/net/net1080.c b/drivers/usb/net/net1080.c
index a4309c4a491b..cee55f8cf64f 100644
--- a/drivers/usb/net/net1080.c
+++ b/drivers/usb/net/net1080.c
@@ -500,7 +500,7 @@ static int net1080_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
}
static struct sk_buff *
-net1080_tx_fixup(struct usbnet *dev, struct sk_buff *skb, unsigned flags)
+net1080_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags)
{
int padlen;
struct sk_buff *skb2;
diff --git a/drivers/usb/net/pegasus.c b/drivers/usb/net/pegasus.c
index 6a4ffe6c3977..537eb181d985 100644
--- a/drivers/usb/net/pegasus.c
+++ b/drivers/usb/net/pegasus.c
@@ -1384,7 +1384,6 @@ static int pegasus_suspend (struct usb_interface *intf, pm_message_t message)
usb_kill_urb(pegasus->rx_urb);
usb_kill_urb(pegasus->intr_urb);
}
- intf->dev.power.power_state = PMSG_SUSPEND;
return 0;
}
@@ -1392,7 +1391,6 @@ static int pegasus_resume (struct usb_interface *intf)
{
struct pegasus *pegasus = usb_get_intfdata(intf);
- intf->dev.power.power_state = PMSG_ON;
netif_device_attach (pegasus->net);
if (netif_running(pegasus->net)) {
pegasus->rx_urb->status = 0;
diff --git a/drivers/usb/net/pegasus.h b/drivers/usb/net/pegasus.h
index b98f2a833442..9fbd59b55cb6 100644
--- a/drivers/usb/net/pegasus.h
+++ b/drivers/usb/net/pegasus.h
@@ -181,6 +181,8 @@ PEGASUS_DEV( "Accton USB 10/100 Ethernet Adapter", VENDOR_ACCTON, 0x1046,
DEFAULT_GPIO_RESET )
PEGASUS_DEV( "SpeedStream USB 10/100 Ethernet", VENDOR_ACCTON, 0x5046,
DEFAULT_GPIO_RESET | PEGASUS_II )
+PEGASUS_DEV( "Philips USB 10/100 Ethernet", VENDOR_ACCTON, 0xb004,
+ DEFAULT_GPIO_RESET | PEGASUS_II )
PEGASUS_DEV( "ADMtek ADM8511 \"Pegasus II\" USB Ethernet",
VENDOR_ADMTEK, 0x8511,
DEFAULT_GPIO_RESET | PEGASUS_II | HAS_HOME_PNA )
diff --git a/drivers/usb/net/rndis_host.c b/drivers/usb/net/rndis_host.c
index 2ed2e5fb7778..b5a925dc1beb 100644
--- a/drivers/usb/net/rndis_host.c
+++ b/drivers/usb/net/rndis_host.c
@@ -517,7 +517,7 @@ static int rndis_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
}
static struct sk_buff *
-rndis_tx_fixup(struct usbnet *dev, struct sk_buff *skb, unsigned flags)
+rndis_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags)
{
struct rndis_data_hdr *hdr;
struct sk_buff *skb2;
diff --git a/drivers/usb/net/rtl8150.c b/drivers/usb/net/rtl8150.c
index c3d4e3589e30..787dd3591d6a 100644
--- a/drivers/usb/net/rtl8150.c
+++ b/drivers/usb/net/rtl8150.c
@@ -909,6 +909,7 @@ static void rtl8150_disconnect(struct usb_interface *intf)
usb_set_intfdata(intf, NULL);
if (dev) {
set_bit(RTL8150_UNPLUG, &dev->flags);
+ tasklet_disable(&dev->tl);
unregister_netdev(dev->netdev);
unlink_all_urbs(dev);
free_all_urbs(dev);
diff --git a/drivers/usb/net/usbnet.c b/drivers/usb/net/usbnet.c
index 6c460918d54f..74f05c9c84d5 100644
--- a/drivers/usb/net/usbnet.c
+++ b/drivers/usb/net/usbnet.c
@@ -288,7 +288,7 @@ EXPORT_SYMBOL_GPL(usbnet_defer_kevent);
static void rx_complete (struct urb *urb, struct pt_regs *regs);
-static void rx_submit (struct usbnet *dev, struct urb *urb, unsigned flags)
+static void rx_submit (struct usbnet *dev, struct urb *urb, gfp_t flags)
{
struct sk_buff *skb;
struct skb_data *entry;
@@ -1185,7 +1185,6 @@ int usbnet_suspend (struct usb_interface *intf, pm_message_t message)
netif_device_detach (dev->net);
(void) unlink_urbs (dev, &dev->rxq);
(void) unlink_urbs (dev, &dev->txq);
- intf->dev.power.power_state = PMSG_SUSPEND;
return 0;
}
EXPORT_SYMBOL_GPL(usbnet_suspend);
@@ -1194,7 +1193,6 @@ int usbnet_resume (struct usb_interface *intf)
{
struct usbnet *dev = usb_get_intfdata(intf);
- intf->dev.power.power_state = PMSG_ON;
netif_device_attach (dev->net);
tasklet_schedule (&dev->bh);
return 0;
diff --git a/drivers/usb/net/usbnet.h b/drivers/usb/net/usbnet.h
index 7aa0abd1a9bd..89fc4958eecf 100644
--- a/drivers/usb/net/usbnet.h
+++ b/drivers/usb/net/usbnet.h
@@ -107,7 +107,7 @@ struct driver_info {
/* fixup tx packet (add framing) */
struct sk_buff *(*tx_fixup)(struct usbnet *dev,
- struct sk_buff *skb, unsigned flags);
+ struct sk_buff *skb, gfp_t flags);
/* for new devices, use the descriptor-reading code instead */
int in; /* rx endpoint */
diff --git a/drivers/usb/net/zaurus.c b/drivers/usb/net/zaurus.c
index ee3b892aeabc..5d4b7d55b097 100644
--- a/drivers/usb/net/zaurus.c
+++ b/drivers/usb/net/zaurus.c
@@ -62,7 +62,7 @@
*/
static struct sk_buff *
-zaurus_tx_fixup(struct usbnet *dev, struct sk_buff *skb, unsigned flags)
+zaurus_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags)
{
int padlen;
struct sk_buff *skb2;
diff --git a/drivers/usb/net/zd1201.c b/drivers/usb/net/zd1201.c
index c4e479ee926a..2f52261c7cc1 100644
--- a/drivers/usb/net/zd1201.c
+++ b/drivers/usb/net/zd1201.c
@@ -521,7 +521,7 @@ static int zd1201_setconfig(struct zd1201 *zd, int rid, void *buf, int len, int
int reqlen;
char seq=0;
struct urb *urb;
- unsigned int gfp_mask = wait ? GFP_NOIO : GFP_ATOMIC;
+ gfp_t gfp_mask = wait ? GFP_NOIO : GFP_ATOMIC;
len += 4; /* first 4 are for header */
diff --git a/drivers/usb/serial/ChangeLog.old b/drivers/usb/serial/ChangeLog.old
new file mode 100644
index 000000000000..c1b279939bbf
--- /dev/null
+++ b/drivers/usb/serial/ChangeLog.old
@@ -0,0 +1,730 @@
+This is the contents of some of the drivers/usb/serial/ files that had old
+changelog comments. They were quite old, and out of date, and we don't keep
+them anymore, so I've put them here, away from the source files, in case
+people still care to see them.
+
+- Greg Kroah-Hartman <greg@kroah.com> October 20, 2005
+
+-----------------------------------------------------------------------
+usb-serial.h Change Log comments:
+
+ (03/26/2002) gkh
+ removed the port->tty check from port_paranoia_check() due to serial
+ consoles not having a tty device assigned to them.
+
+ (12/03/2001) gkh
+ removed active from the port structure.
+ added documentation to the usb_serial_device_type structure
+
+ (10/10/2001) gkh
+ added vendor and product to serial structure. Needed to determine device
+ owner when the device is disconnected.
+
+ (05/30/2001) gkh
+ added sem to port structure and removed port_lock
+
+ (10/05/2000) gkh
+ Added interrupt_in_endpointAddress and bulk_in_endpointAddress to help
+ fix bug with urb->dev not being set properly, now that the usb core
+ needs it.
+
+ (09/11/2000) gkh
+ Added usb_serial_debug_data function to help get rid of #DEBUG in the
+ drivers.
+
+ (08/28/2000) gkh
+ Added port_lock to port structure.
+
+ (08/08/2000) gkh
+ Added open_count to port structure.
+
+ (07/23/2000) gkh
+ Added bulk_out_endpointAddress to port structure.
+
+ (07/19/2000) gkh, pberger, and borchers
+ Modifications to allow usb-serial drivers to be modules.
+
+-----------------------------------------------------------------------
+usb-serial.c Change Log comments:
+
+ (12/10/2002) gkh
+ Split the ports off into their own struct device, and added a
+ usb-serial bus driver.
+
+ (11/19/2002) gkh
+ removed a few #ifdefs for the generic code and cleaned up the failure
+ logic in initialization.
+
+ (10/02/2002) gkh
+ moved the console code to console.c and out of this file.
+
+ (06/05/2002) gkh
+ moved location of startup() call in serial_probe() until after all
+ of the port information and endpoints are initialized. This makes
+ things easier for some drivers.
+
+ (04/10/2002) gkh
+ added serial_read_proc function which creates a
+ /proc/tty/driver/usb-serial file.
+
+ (03/27/2002) gkh
+ Got USB serial console code working properly and merged into the main
+ version of the tree. Thanks to Randy Dunlap for the initial version
+ of this code, and for pushing me to finish it up.
+ The USB serial console works with any usb serial driver device.
+
+ (03/21/2002) gkh
+ Moved all manipulation of port->open_count into the core. Now the
+ individual driver's open and close functions are called only when the
+ first open() and last close() is called. Making the drivers a bit
+ smaller and simpler.
+ Fixed a bug if a driver didn't have the owner field set.
+
+ (02/26/2002) gkh
+ Moved all locking into the main serial_* functions, instead of having
+ the individual drivers have to grab the port semaphore. This should
+ reduce races.
+ Reworked the MOD_INC logic a bit to always increment and decrement, even
+ if the generic driver is being used.
+
+ (10/10/2001) gkh
+ usb_serial_disconnect() now sets the serial->dev pointer is to NULL to
+ help prevent child drivers from accessing the device since it is now
+ gone.
+
+ (09/13/2001) gkh
+ Moved generic driver initialize after we have registered with the USB
+ core. Thanks to Randy Dunlap for pointing this problem out.
+
+ (07/03/2001) gkh
+ Fixed module paramater size. Thanks to John Brockmeyer for the pointer.
+ Fixed vendor and product getting defined through the MODULE_PARM macro
+ if the Generic driver wasn't compiled in.
+ Fixed problem with generic_shutdown() not being called for drivers that
+ don't have a shutdown() function.
+
+ (06/06/2001) gkh
+ added evil hack that is needed for the prolific pl2303 device due to the
+ crazy way its endpoints are set up.
+
+ (05/30/2001) gkh
+ switched from using spinlock to a semaphore, which fixes lots of problems.
+
+ (04/08/2001) gb
+ Identify version on module load.
+
+ 2001_02_05 gkh
+ Fixed buffer overflows bug with the generic serial driver. Thanks to
+ Todd Squires <squirest@ct0.com> for fixing this.
+
+ (01/10/2001) gkh
+ Fixed bug where the generic serial adaptor grabbed _any_ device that was
+ offered to it.
+
+ (12/12/2000) gkh
+ Removed MOD_INC and MOD_DEC from poll and disconnect functions, and
+ moved them to the serial_open and serial_close functions.
+ Also fixed bug with there not being a MOD_DEC for the generic driver
+ (thanks to Gary Brubaker for finding this.)
+
+ (11/29/2000) gkh
+ Small NULL pointer initialization cleanup which saves a bit of disk image
+
+ (11/01/2000) Adam J. Richter
+ instead of using idVendor/idProduct pairs, usb serial drivers
+ now identify their hardware interest with usb_device_id tables,
+ which they usually have anyhow for use with MODULE_DEVICE_TABLE.
+
+ (10/05/2000) gkh
+ Fixed bug with urb->dev not being set properly, now that the usb
+ core needs it.
+
+ (09/11/2000) gkh
+ Removed DEBUG #ifdefs with call to usb_serial_debug_data
+
+ (08/28/2000) gkh
+ Added port_lock to port structure.
+ Added locks for SMP safeness to generic driver
+ Fixed the ability to open a generic device's port more than once.
+
+ (07/23/2000) gkh
+ Added bulk_out_endpointAddress to port structure.
+
+ (07/19/2000) gkh, pberger, and borchers
+ Modifications to allow usb-serial drivers to be modules.
+
+ (07/03/2000) gkh
+ Added more debugging to serial_ioctl call
+
+ (06/25/2000) gkh
+ Changed generic_write_bulk_callback to not call wake_up_interruptible
+ directly, but to have port_softint do it at a safer time.
+
+ (06/23/2000) gkh
+ Cleaned up debugging statements in a quest to find UHCI timeout bug.
+
+ (05/22/2000) gkh
+ Changed the makefile, enabling the big CONFIG_USB_SERIAL_SOMTHING to be
+ removed from the individual device source files.
+
+ (05/03/2000) gkh
+ Added the Digi Acceleport driver from Al Borchers and Peter Berger.
+
+ (05/02/2000) gkh
+ Changed devfs and tty register code to work properly now. This was based on
+ the ACM driver changes by Vojtech Pavlik.
+
+ (04/27/2000) Ryan VanderBijl
+ Put calls to *_paranoia_checks into one function.
+
+ (04/23/2000) gkh
+ Fixed bug that Randy Dunlap found for Generic devices with no bulk out ports.
+ Moved when the startup code printed out the devices that are supported.
+
+ (04/19/2000) gkh
+ Added driver for ZyXEL omni.net lcd plus ISDN TA
+ Made startup info message specify which drivers were compiled in.
+
+ (04/03/2000) gkh
+ Changed the probe process to remove the module unload races.
+ Changed where the tty layer gets initialized to have devfs work nicer.
+ Added initial devfs support.
+
+ (03/26/2000) gkh
+ Split driver up into device specific pieces.
+
+ (03/19/2000) gkh
+ Fixed oops that could happen when device was removed while a program
+ was talking to the device.
+ Removed the static urbs and now all urbs are created and destroyed
+ dynamically.
+ Reworked the internal interface. Now everything is based on the
+ usb_serial_port structure instead of the larger usb_serial structure.
+ This fixes the bug that a multiport device could not have more than
+ one port open at one time.
+
+ (03/17/2000) gkh
+ Added config option for debugging messages.
+ Added patch for keyspan pda from Brian Warner.
+
+ (03/06/2000) gkh
+ Added the keyspan pda code from Brian Warner <warner@lothar.com>
+ Moved a bunch of the port specific stuff into its own structure. This
+ is in anticipation of the true multiport devices (there's a bug if you
+ try to access more than one port of any multiport device right now)
+
+ (02/21/2000) gkh
+ Made it so that any serial devices only have to specify which functions
+ they want to overload from the generic function calls (great,
+ inheritance in C, in a driver, just what I wanted...)
+ Added support for set_termios and ioctl function calls. No drivers take
+ advantage of this yet.
+ Removed the #ifdef MODULE, now there is no module specific code.
+ Cleaned up a few comments in usb-serial.h that were wrong (thanks again
+ to Miles Lott).
+ Small fix to get_free_serial.
+
+ (02/14/2000) gkh
+ Removed the Belkin and Peracom functionality from the driver due to
+ the lack of support from the vendor, and me not wanting people to
+ accidenatly buy the device, expecting it to work with Linux.
+ Added read_bulk_callback and write_bulk_callback to the type structure
+ for the needs of the FTDI and WhiteHEAT driver.
+ Changed all reverences to FTDI to FTDI_SIO at the request of Bill
+ Ryder.
+ Changed the output urb size back to the max endpoint size to make
+ the ftdi_sio driver have it easier, and due to the fact that it didn't
+ really increase the speed any.
+
+ (02/11/2000) gkh
+ Added VISOR_FUNCTION_CONSOLE to the visor startup function. This was a
+ patch from Miles Lott (milos@insync.net).
+ Fixed bug with not restoring the minor range that a device grabs, if
+ the startup function fails (thanks Miles for finding this).
+
+ (02/05/2000) gkh
+ Added initial framework for the Keyspan PDA serial converter so that
+ Brian Warner has a place to put his code.
+ Made the ezusb specific functions generic enough that different
+ devices can use them (whiteheat and keyspan_pda both need them).
+ Split out a whole bunch of structure and other stuff to a separate
+ usb-serial.h file.
+ Made the Visor connection messages a little more understandable, now
+ that Miles Lott (milos@insync.net) has gotten the Generic channel to
+ work. Also made them always show up in the log file.
+
+ (01/25/2000) gkh
+ Added initial framework for FTDI serial converter so that Bill Ryder
+ has a place to put his code.
+ Added the vendor specific info from Handspring. Now we can print out
+ informational debug messages as well as understand what is happening.
+
+ (01/23/2000) gkh
+ Fixed problem of crash when trying to open a port that didn't have a
+ device assigned to it. Made the minor node finding a little smarter,
+ now it looks to find a continuous space for the new device.
+
+ (01/21/2000) gkh
+ Fixed bug in visor_startup with patch from Miles Lott (milos@insync.net)
+ Fixed get_serial_by_minor which was all messed up for multi port
+ devices. Fixed multi port problem for generic devices. Now the number
+ of ports is determined by the number of bulk out endpoints for the
+ generic device.
+
+ (01/19/2000) gkh
+ Removed lots of cruft that was around from the old (pre urb) driver
+ interface.
+ Made the serial_table dynamic. This should save lots of memory when
+ the number of minor nodes goes up to 256.
+ Added initial support for devices that have more than one port.
+ Added more debugging comments for the Visor, and added a needed
+ set_configuration call.
+
+ (01/17/2000) gkh
+ Fixed the WhiteHEAT firmware (my processing tool had a bug)
+ and added new debug loader firmware for it.
+ Removed the put_char function as it isn't really needed.
+ Added visor startup commands as found by the Win98 dump.
+
+ (01/13/2000) gkh
+ Fixed the vendor id for the generic driver to the one I meant it to be.
+
+ (01/12/2000) gkh
+ Forget the version numbering...that's pretty useless...
+ Made the driver able to be compiled so that the user can select which
+ converter they want to use. This allows people who only want the Visor
+ support to not pay the memory size price of the WhiteHEAT.
+ Fixed bug where the generic driver (idVendor=0000 and idProduct=0000)
+ grabbed the root hub. Not good.
+
+ version 0.4.0 (01/10/2000) gkh
+ Added whiteheat.h containing the firmware for the ConnectTech WhiteHEAT
+ device. Added startup function to allow firmware to be downloaded to
+ a device if it needs to be.
+ Added firmware download logic to the WhiteHEAT device.
+ Started to add #defines to split up the different drivers for potential
+ configuration option.
+
+ version 0.3.1 (12/30/99) gkh
+ Fixed problems with urb for bulk out.
+ Added initial support for multiple sets of endpoints. This enables
+ the Handspring Visor to be attached successfully. Only the first
+ bulk in / bulk out endpoint pair is being used right now.
+
+ version 0.3.0 (12/27/99) gkh
+ Added initial support for the Handspring Visor based on a patch from
+ Miles Lott (milos@sneety.insync.net)
+ Cleaned up the code a bunch and converted over to using urbs only.
+
+ version 0.2.3 (12/21/99) gkh
+ Added initial support for the Connect Tech WhiteHEAT converter.
+ Incremented the number of ports in expectation of getting the
+ WhiteHEAT to work properly (4 ports per connection).
+ Added notification on insertion and removal of what port the
+ device is/was connected to (and what kind of device it was).
+
+ version 0.2.2 (12/16/99) gkh
+ Changed major number to the new allocated number. We're legal now!
+
+ version 0.2.1 (12/14/99) gkh
+ Fixed bug that happens when device node is opened when there isn't a
+ device attached to it. Thanks to marek@webdesign.no for noticing this.
+
+ version 0.2.0 (11/10/99) gkh
+ Split up internals to make it easier to add different types of serial
+ converters to the code.
+ Added a "generic" driver that gets it's vendor and product id
+ from when the module is loaded. Thanks to David E. Nelson (dnelson@jump.net)
+ for the idea and sample code (from the usb scanner driver.)
+ Cleared up any licensing questions by releasing it under the GNU GPL.
+
+ version 0.1.2 (10/25/99) gkh
+ Fixed bug in detecting device.
+
+ version 0.1.1 (10/05/99) gkh
+ Changed the major number to not conflict with anything else.
+
+ version 0.1 (09/28/99) gkh
+ Can recognize the two different devices and start up a read from
+ device when asked to. Writes also work. No control signals yet, this
+ all is vendor specific data (i.e. no spec), also no control for
+ different baud rates or other bit settings.
+ Currently we are using the same devid as the acm driver. This needs
+ to change.
+
+-----------------------------------------------------------------------
+visor.c Change Log comments:
+
+ (06/03/2003) Judd Montgomery <judd at jpilot.org>
+ Added support for module parameter options for untested/unknown
+ devices.
+
+ (03/09/2003) gkh
+ Added support for the Sony Clie NZ90V device. Thanks to Martin Brachtl
+ <brachtl@redgrep.cz> for the information.
+
+ (03/05/2003) gkh
+ Think Treo support is now working.
+
+ (04/03/2002) gkh
+ Added support for the Sony OS 4.1 devices. Thanks to Hiroyuki ARAKI
+ <hiro@zob.ne.jp> for the information.
+
+ (03/27/2002) gkh
+ Removed assumptions that port->tty was always valid (is not true
+ for usb serial console devices.)
+
+ (03/23/2002) gkh
+ Added support for the Palm i705 device, thanks to Thomas Riemer
+ <tom@netmech.com> for the information.
+
+ (03/21/2002) gkh
+ Added support for the Palm m130 device, thanks to Udo Eisenbarth
+ <udo.eisenbarth@web.de> for the information.
+
+ (02/27/2002) gkh
+ Reworked the urb handling logic. We have no more pool, but dynamically
+ allocate the urb and the transfer buffer on the fly. In testing this
+ does not incure any measurable overhead. This also relies on the fact
+ that we have proper reference counting logic for urbs.
+
+ (02/21/2002) SilaS
+ Added initial support for the Palm m515 devices.
+
+ (02/14/2002) gkh
+ Added support for the Clie S-360 device.
+
+ (12/18/2001) gkh
+ Added better Clie support for 3.5 devices. Thanks to Geoffrey Levand
+ for the patch.
+
+ (11/11/2001) gkh
+ Added support for the m125 devices, and added check to prevent oopses
+ for Clié devices that lie about the number of ports they have.
+
+ (08/30/2001) gkh
+ Added support for the Clie devices, both the 3.5 and 4.0 os versions.
+ Many thanks to Daniel Burke, and Bryan Payne for helping with this.
+
+ (08/23/2001) gkh
+ fixed a few potential bugs pointed out by Oliver Neukum.
+
+ (05/30/2001) gkh
+ switched from using spinlock to a semaphore, which fixes lots of problems.
+
+ (05/28/2000) gkh
+ Added initial support for the Palm m500 and Palm m505 devices.
+
+ (04/08/2001) gb
+ Identify version on module load.
+
+ (01/21/2000) gkh
+ Added write_room and chars_in_buffer, as they were previously using the
+ generic driver versions which is all wrong now that we are using an urb
+ pool. Thanks to Wolfgang Grandegger for pointing this out to me.
+ Removed count assignment in the write function, which was not needed anymore
+ either. Thanks to Al Borchers for pointing this out.
+
+ (12/12/2000) gkh
+ Moved MOD_DEC to end of visor_close to be nicer, as the final write
+ message can sleep.
+
+ (11/12/2000) gkh
+ Fixed bug with data being dropped on the floor by forcing tty->low_latency
+ to be on. Hopefully this fixes the OHCI issue!
+
+ (11/01/2000) Adam J. Richter
+ usb_device_id table support
+
+ (10/05/2000) gkh
+ Fixed bug with urb->dev not being set properly, now that the usb
+ core needs it.
+
+ (09/11/2000) gkh
+ Got rid of always calling kmalloc for every urb we wrote out to the
+ device.
+ Added visor_read_callback so we can keep track of bytes in and out for
+ those people who like to know the speed of their device.
+ Removed DEBUG #ifdefs with call to usb_serial_debug_data
+
+ (09/06/2000) gkh
+ Fixed oops in visor_exit. Need to uncomment usb_unlink_urb call _after_
+ the host controller drivers set urb->dev = NULL when the urb is finished.
+
+ (08/28/2000) gkh
+ Added locks for SMP safeness.
+
+ (08/08/2000) gkh
+ Fixed endian problem in visor_startup.
+ Fixed MOD_INC and MOD_DEC logic and the ability to open a port more
+ than once.
+
+ (07/23/2000) gkh
+ Added pool of write urbs to speed up transfers to the visor.
+
+ (07/19/2000) gkh
+ Added module_init and module_exit functions to handle the fact that this
+ driver is a loadable module now.
+
+ (07/03/2000) gkh
+ Added visor_set_ioctl and visor_set_termios functions (they don't do much
+ of anything, but are good for debugging.)
+
+ (06/25/2000) gkh
+ Fixed bug in visor_unthrottle that should help with the disconnect in PPP
+ bug that people have been reporting.
+
+ (06/23/2000) gkh
+ Cleaned up debugging statements in a quest to find UHCI timeout bug.
+
+ (04/27/2000) Ryan VanderBijl
+ Fixed memory leak in visor_close
+
+ (03/26/2000) gkh
+ Split driver up into device specific pieces.
+
+-----------------------------------------------------------------------
+pl2303.c Change Log comments:
+
+ 2002_Mar_26 gkh
+ allowed driver to work properly if there is no tty assigned to a port
+ (this happens for serial console devices.)
+
+ 2001_Oct_06 gkh
+ Added RTS and DTR line control. Thanks to joe@bndlg.de for parts of it.
+
+ 2001_Sep_19 gkh
+ Added break support.
+
+ 2001_Aug_30 gkh
+ fixed oops in write_bulk_callback.
+
+ 2001_Aug_28 gkh
+ reworked buffer logic to be like other usb-serial drivers. Hopefully
+ removing some reported problems.
+
+ 2001_Jun_06 gkh
+ finished porting to 2.4 format.
+
+
+-----------------------------------------------------------------------
+io_edgeport.c Change Log comments:
+
+ 2003_04_03 al borchers
+ - fixed a bug (that shows up with dosemu) where the tty struct is
+ used in a callback after it has been freed
+
+ 2.3 2002_03_08 greg kroah-hartman
+ - fixed bug when multiple devices were attached at the same time.
+
+ 2.2 2001_11_14 greg kroah-hartman
+ - fixed bug in edge_close that kept the port from being used more
+ than once.
+ - fixed memory leak on device removal.
+ - fixed potential double free of memory when command urb submitting
+ failed.
+ - other small cleanups when the device is removed
+
+ 2.1 2001_07_09 greg kroah-hartman
+ - added support for TIOCMBIS and TIOCMBIC.
+
+ (04/08/2001) gb
+ - Identify version on module load.
+
+ 2.0 2001_03_05 greg kroah-hartman
+ - reworked entire driver to fit properly in with the other usb-serial
+ drivers. Occasional oopses still happen, but it's a good start.
+
+ 1.2.3 (02/23/2001) greg kroah-hartman
+ - changed device table to work properly for 2.4.x final format.
+ - fixed problem with dropping data at high data rates.
+
+ 1.2.2 (11/27/2000) greg kroah-hartman
+ - cleaned up more NTisms.
+ - Added device table for 2.4.0-test11
+
+ 1.2.1 (11/08/2000) greg kroah-hartman
+ - Started to clean up NTisms.
+ - Fixed problem with dev field of urb for kernels >= 2.4.0-test9
+
+ 1.2 (10/17/2000) David Iacovelli
+ Remove all EPIC code and GPL source
+ Fix RELEVANT_IFLAG macro to include flow control
+ changes port configuration changes.
+ Fix redefinition of SERIAL_MAGIC
+ Change all timeout values to 5 seconds
+ Tried to fix the UHCI multiple urb submission, but failed miserably.
+ it seems to work fine with OHCI.
+ ( Greg take a look at the #if 0 at end of WriteCmdUsb() we must
+ find a way to work arount this UHCI bug )
+
+ 1.1 (10/11/2000) David Iacovelli
+ Fix XON/XOFF flow control to support both IXON and IXOFF
+
+ 0.9.27 (06/30/2000) David Iacovelli
+ Added transmit queue and now allocate urb for command writes.
+
+ 0.9.26 (06/29/2000) David Iacovelli
+ Add support for 80251 based edgeport
+
+ 0.9.25 (06/27/2000) David Iacovelli
+ Do not close the port if it has multiple opens.
+
+ 0.9.24 (05/26/2000) David Iacovelli
+ Add IOCTLs to support RXTX and JAVA POS
+ and first cut at running BlackBox Demo
+
+ 0.9.23 (05/24/2000) David Iacovelli
+ Add IOCTLs to support RXTX and JAVA POS
+
+ 0.9.22 (05/23/2000) David Iacovelli
+ fixed bug in enumeration. If epconfig turns on mapping by
+ path after a device is already plugged in, we now update
+ the mapping correctly
+
+ 0.9.21 (05/16/2000) David Iacovelli
+ Added BlockUntilChaseResp() to also wait for txcredits
+ Updated the way we allocate and handle write URBs
+ Add debug code to dump buffers
+
+ 0.9.20 (05/01/2000) David Iacovelli
+ change driver to use usb/tts/
+
+ 0.9.19 (05/01/2000) David Iacovelli
+ Update code to compile if DEBUG is off
+
+ 0.9.18 (04/28/2000) David Iacovelli
+ cleanup and test tty_register with devfs
+
+ 0.9.17 (04/27/2000) greg kroah-hartman
+ changed tty_register around to be like the way it
+ was before, but now it works properly with devfs.
+
+ 0.9.16 (04/26/2000) david iacovelli
+ Fixed bug in GetProductInfo()
+
+ 0.9.15 (04/25/2000) david iacovelli
+ Updated enumeration
+
+ 0.9.14 (04/24/2000) david iacovelli
+ Removed all config/status IOCTLS and
+ converted to using /proc/edgeport
+ still playing with devfs
+
+ 0.9.13 (04/24/2000) david iacovelli
+ Removed configuration based on ttyUSB0
+ Added support for configuration using /prod/edgeport
+ first attempt at using devfs (not working yet!)
+ Added IOCTL to GetProductInfo()
+ Added support for custom baud rates
+ Add support for random port numbers
+
+ 0.9.12 (04/18/2000) david iacovelli
+ added additional configuration IOCTLs
+ use ttyUSB0 for configuration
+
+ 0.9.11 (04/17/2000) greg kroah-hartman
+ fixed module initialization race conditions.
+ made all urbs dynamically allocated.
+ made driver devfs compatible. now it only registers the tty device
+ when the device is actually plugged in.
+
+ 0.9.10 (04/13/2000) greg kroah-hartman
+ added proc interface framework.
+
+ 0.9.9 (04/13/2000) david iacovelli
+ added enumeration code and ioctls to configure the device
+
+ 0.9.8 (04/12/2000) david iacovelli
+ Change interrupt read start when device is plugged in
+ and stop when device is removed
+ process interrupt reads when all ports are closed
+ (keep value of rxBytesAvail consistent with the edgeport)
+ set the USB_BULK_QUEUE flag so that we can shove a bunch
+ of urbs at once down the pipe
+
+ 0.9.7 (04/10/2000) david iacovelli
+ start to add enumeration code.
+ generate serial number for epic devices
+ add support for kdb
+
+ 0.9.6 (03/30/2000) david iacovelli
+ add IOCTL to get string, manufacture, and boot descriptors
+
+ 0.9.5 (03/14/2000) greg kroah-hartman
+ more error checking added to SerialOpen to try to fix UHCI open problem
+
+ 0.9.4 (03/09/2000) greg kroah-hartman
+ added more error checking to handle oops when data is hanging
+ around and tty is abruptly closed.
+
+ 0.9.3 (03/09/2000) david iacovelli
+ Add epic support for xon/xoff chars
+ play with performance
+
+ 0.9.2 (03/08/2000) greg kroah-hartman
+ changed most "info" calls to "dbg"
+ implemented flow control properly in the termios call
+
+ 0.9.1 (03/08/2000) david iacovelli
+ added EPIC support
+ enabled bootloader update
+
+ 0.9 (03/08/2000) greg kroah-hartman
+ Release to IO networks.
+ Integrated changes that David made
+ made getting urbs for writing SMP safe
+
+ 0.8 (03/07/2000) greg kroah-hartman
+ Release to IO networks.
+ Fixed problems that were seen in code by David.
+ Now both Edgeport/4 and Edgeport/2 works properly.
+ Changed most of the functions to use port instead of serial.
+
+ 0.7 (02/27/2000) greg kroah-hartman
+ Milestone 3 release.
+ Release to IO Networks
+ ioctl for waiting on line change implemented.
+ ioctl for getting statistics implemented.
+ multiport support working.
+ lsr and msr registers are now handled properly.
+ change break now hooked up and working.
+ support for all known Edgeport devices.
+
+ 0.6 (02/22/2000) greg kroah-hartman
+ Release to IO networks.
+ CHASE is implemented correctly when port is closed.
+ SerialOpen now blocks correctly until port is fully opened.
+
+ 0.5 (02/20/2000) greg kroah-hartman
+ Release to IO networks.
+ Known problems:
+ modem status register changes are not sent on to the user
+ CHASE is not implemented when the port is closed.
+
+ 0.4 (02/16/2000) greg kroah-hartman
+ Second cut at the CeBit demo.
+ Doesn't leak memory on every write to the port
+ Still small leaks on startup.
+ Added support for Edgeport/2 and Edgeport/8
+
+ 0.3 (02/15/2000) greg kroah-hartman
+ CeBit demo release.
+ Force the line settings to 4800, 8, 1, e for the demo.
+ Warning! This version leaks memory like crazy!
+
+ 0.2 (01/30/2000) greg kroah-hartman
+ Milestone 1 release.
+ Device is found by USB subsystem, enumerated, fimware is downloaded
+ and the descriptors are printed to the debug log, config is set, and
+ green light starts to blink. Open port works, and data can be sent
+ and received at the default settings of the UART. Loopback connector
+ and debug log confirms this.
+
+ 0.1 (01/23/2000) greg kroah-hartman
+ Initial release to help IO Networks try to set up their test system.
+ Edgeport4 is recognized, firmware is downloaded, config is set so
+ device blinks green light every 3 sec. Port is bound, but opening,
+ closing, and sending data do not work properly.
+
+
diff --git a/drivers/usb/serial/Kconfig b/drivers/usb/serial/Kconfig
index 9438909e87a5..7b5e8e4ee2bb 100644
--- a/drivers/usb/serial/Kconfig
+++ b/drivers/usb/serial/Kconfig
@@ -394,6 +394,15 @@ config USB_SERIAL_MCT_U232
To compile this driver as a module, choose M here: the
module will be called mct_u232.
+config USB_SERIAL_NOKIA_DKU2
+ tristate "USB Nokia DKU2 Driver"
+ depends on USB_SERIAL
+ help
+ Say Y here if you want to use a Nokia DKU2 device.
+
+ To compile this driver as a module, choose M here: the
+ module will be called nokia_dku2.
+
config USB_SERIAL_PL2303
tristate "USB Prolific 2303 Single Port Serial Driver"
depends on USB_SERIAL
diff --git a/drivers/usb/serial/Makefile b/drivers/usb/serial/Makefile
index 6c7cdcc99a9e..55fd461793b7 100644
--- a/drivers/usb/serial/Makefile
+++ b/drivers/usb/serial/Makefile
@@ -31,6 +31,7 @@ obj-$(CONFIG_USB_SERIAL_KEYSPAN_PDA) += keyspan_pda.o
obj-$(CONFIG_USB_SERIAL_KLSI) += kl5kusb105.o
obj-$(CONFIG_USB_SERIAL_KOBIL_SCT) += kobil_sct.o
obj-$(CONFIG_USB_SERIAL_MCT_U232) += mct_u232.o
+obj-$(CONFIG_USB_SERIAL_NOKIA_DKU2) += nokia_dku2.o
obj-$(CONFIG_USB_SERIAL_OMNINET) += omninet.o
obj-$(CONFIG_USB_SERIAL_OPTION) += option.o
obj-$(CONFIG_USB_SERIAL_PL2303) += pl2303.o
diff --git a/drivers/usb/serial/airprime.c b/drivers/usb/serial/airprime.c
index 926d4c2c1600..1f29d8837327 100644
--- a/drivers/usb/serial/airprime.c
+++ b/drivers/usb/serial/airprime.c
@@ -30,9 +30,11 @@ static struct usb_driver airprime_driver = {
.id_table = id_table,
};
-static struct usb_serial_device_type airprime_device = {
- .owner = THIS_MODULE,
- .name = "airprime",
+static struct usb_serial_driver airprime_device = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "airprime",
+ },
.id_table = id_table,
.num_interrupt_in = NUM_DONT_CARE,
.num_bulk_in = NUM_DONT_CARE,
diff --git a/drivers/usb/serial/belkin_sa.c b/drivers/usb/serial/belkin_sa.c
index abb1b2c543bb..84bc0ee4f061 100644
--- a/drivers/usb/serial/belkin_sa.c
+++ b/drivers/usb/serial/belkin_sa.c
@@ -121,10 +121,12 @@ static struct usb_driver belkin_driver = {
};
/* All of the device info needed for the serial converters */
-static struct usb_serial_device_type belkin_device = {
- .owner = THIS_MODULE,
- .name = "Belkin / Peracom / GoHubs USB Serial Adapter",
- .short_name = "belkin",
+static struct usb_serial_driver belkin_device = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "belkin",
+ },
+ .description = "Belkin / Peracom / GoHubs USB Serial Adapter",
.id_table = id_table_combined,
.num_interrupt_in = 1,
.num_bulk_in = 1,
diff --git a/drivers/usb/serial/bus.c b/drivers/usb/serial/bus.c
index 2f612c2d894b..664139afcfa9 100644
--- a/drivers/usb/serial/bus.c
+++ b/drivers/usb/serial/bus.c
@@ -18,7 +18,7 @@
static int usb_serial_device_match (struct device *dev, struct device_driver *drv)
{
- struct usb_serial_device_type *driver;
+ struct usb_serial_driver *driver;
const struct usb_serial_port *port;
/*
@@ -44,7 +44,7 @@ struct bus_type usb_serial_bus_type = {
static int usb_serial_device_probe (struct device *dev)
{
- struct usb_serial_device_type *driver;
+ struct usb_serial_driver *driver;
struct usb_serial_port *port;
int retval = 0;
int minor;
@@ -57,13 +57,13 @@ static int usb_serial_device_probe (struct device *dev)
driver = port->serial->type;
if (driver->port_probe) {
- if (!try_module_get(driver->owner)) {
+ if (!try_module_get(driver->driver.owner)) {
dev_err(dev, "module get failed, exiting\n");
retval = -EIO;
goto exit;
}
retval = driver->port_probe (port);
- module_put(driver->owner);
+ module_put(driver->driver.owner);
if (retval)
goto exit;
}
@@ -72,7 +72,7 @@ static int usb_serial_device_probe (struct device *dev)
tty_register_device (usb_serial_tty_driver, minor, dev);
dev_info(&port->serial->dev->dev,
"%s converter now attached to ttyUSB%d\n",
- driver->name, minor);
+ driver->description, minor);
exit:
return retval;
@@ -80,7 +80,7 @@ exit:
static int usb_serial_device_remove (struct device *dev)
{
- struct usb_serial_device_type *driver;
+ struct usb_serial_driver *driver;
struct usb_serial_port *port;
int retval = 0;
int minor;
@@ -92,43 +92,38 @@ static int usb_serial_device_remove (struct device *dev)
driver = port->serial->type;
if (driver->port_remove) {
- if (!try_module_get(driver->owner)) {
+ if (!try_module_get(driver->driver.owner)) {
dev_err(dev, "module get failed, exiting\n");
retval = -EIO;
goto exit;
}
retval = driver->port_remove (port);
- module_put(driver->owner);
+ module_put(driver->driver.owner);
}
exit:
minor = port->number;
tty_unregister_device (usb_serial_tty_driver, minor);
dev_info(dev, "%s converter now disconnected from ttyUSB%d\n",
- driver->name, minor);
+ driver->description, minor);
return retval;
}
-int usb_serial_bus_register(struct usb_serial_device_type *device)
+int usb_serial_bus_register(struct usb_serial_driver *driver)
{
int retval;
- if (device->short_name)
- device->driver.name = (char *)device->short_name;
- else
- device->driver.name = (char *)device->name;
- device->driver.bus = &usb_serial_bus_type;
- device->driver.probe = usb_serial_device_probe;
- device->driver.remove = usb_serial_device_remove;
- device->driver.owner = device->owner;
+ driver->driver.bus = &usb_serial_bus_type;
+ driver->driver.probe = usb_serial_device_probe;
+ driver->driver.remove = usb_serial_device_remove;
- retval = driver_register(&device->driver);
+ retval = driver_register(&driver->driver);
return retval;
}
-void usb_serial_bus_deregister(struct usb_serial_device_type *device)
+void usb_serial_bus_deregister(struct usb_serial_driver *driver)
{
- driver_unregister (&device->driver);
+ driver_unregister(&driver->driver);
}
diff --git a/drivers/usb/serial/cp2101.c b/drivers/usb/serial/cp2101.c
index 97c78c21e8d1..c5334dd89b12 100644
--- a/drivers/usb/serial/cp2101.c
+++ b/drivers/usb/serial/cp2101.c
@@ -67,15 +67,17 @@ MODULE_DEVICE_TABLE (usb, id_table);
static struct usb_driver cp2101_driver = {
.owner = THIS_MODULE,
- .name = "CP2101",
+ .name = "cp2101",
.probe = usb_serial_probe,
.disconnect = usb_serial_disconnect,
.id_table = id_table,
};
-static struct usb_serial_device_type cp2101_device = {
- .owner = THIS_MODULE,
- .name = "CP2101",
+static struct usb_serial_driver cp2101_device = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "cp2101",
+ },
.id_table = id_table,
.num_interrupt_in = 0,
.num_bulk_in = 0,
diff --git a/drivers/usb/serial/cyberjack.c b/drivers/usb/serial/cyberjack.c
index b5b431067b08..e581e4ae8483 100644
--- a/drivers/usb/serial/cyberjack.c
+++ b/drivers/usb/serial/cyberjack.c
@@ -83,10 +83,12 @@ static struct usb_driver cyberjack_driver = {
.id_table = id_table,
};
-static struct usb_serial_device_type cyberjack_device = {
- .owner = THIS_MODULE,
- .name = "Reiner SCT Cyberjack USB card reader",
- .short_name = "cyberjack",
+static struct usb_serial_driver cyberjack_device = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "cyberjack",
+ },
+ .description = "Reiner SCT Cyberjack USB card reader",
.id_table = id_table,
.num_interrupt_in = 1,
.num_bulk_in = 1,
diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c
index 9ee1aaff2fcd..af9290ed257b 100644
--- a/drivers/usb/serial/cypress_m8.c
+++ b/drivers/usb/serial/cypress_m8.c
@@ -176,10 +176,12 @@ static unsigned int cypress_buf_put(struct cypress_buf *cb, const char *buf, u
static unsigned int cypress_buf_get(struct cypress_buf *cb, char *buf, unsigned int count);
-static struct usb_serial_device_type cypress_earthmate_device = {
- .owner = THIS_MODULE,
- .name = "DeLorme Earthmate USB",
- .short_name = "earthmate",
+static struct usb_serial_driver cypress_earthmate_device = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "earthmate",
+ },
+ .description = "DeLorme Earthmate USB",
.id_table = id_table_earthmate,
.num_interrupt_in = 1,
.num_interrupt_out = 1,
@@ -203,10 +205,12 @@ static struct usb_serial_device_type cypress_earthmate_device = {
.write_int_callback = cypress_write_int_callback,
};
-static struct usb_serial_device_type cypress_hidcom_device = {
- .owner = THIS_MODULE,
- .name = "HID->COM RS232 Adapter",
- .short_name = "cyphidcom",
+static struct usb_serial_driver cypress_hidcom_device = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "cyphidcom",
+ },
+ .description = "HID->COM RS232 Adapter",
.id_table = id_table_cyphidcomrs232,
.num_interrupt_in = 1,
.num_interrupt_out = 1,
diff --git a/drivers/usb/serial/digi_acceleport.c b/drivers/usb/serial/digi_acceleport.c
index a19a47f6cf12..dc74644a603d 100644
--- a/drivers/usb/serial/digi_acceleport.c
+++ b/drivers/usb/serial/digi_acceleport.c
@@ -503,10 +503,12 @@ static struct usb_driver digi_driver = {
/* device info needed for the Digi serial converter */
-static struct usb_serial_device_type digi_acceleport_2_device = {
- .owner = THIS_MODULE,
- .name = "Digi 2 port USB adapter",
- .short_name = "digi_2",
+static struct usb_serial_driver digi_acceleport_2_device = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "digi_2",
+ },
+ .description = "Digi 2 port USB adapter",
.id_table = id_table_2,
.num_interrupt_in = 0,
.num_bulk_in = 4,
@@ -530,10 +532,12 @@ static struct usb_serial_device_type digi_acceleport_2_device = {
.shutdown = digi_shutdown,
};
-static struct usb_serial_device_type digi_acceleport_4_device = {
- .owner = THIS_MODULE,
- .name = "Digi 4 port USB adapter",
- .short_name = "digi_4",
+static struct usb_serial_driver digi_acceleport_4_device = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "digi_4",
+ },
+ .description = "Digi 4 port USB adapter",
.id_table = id_table_4,
.num_interrupt_in = 0,
.num_bulk_in = 5,
diff --git a/drivers/usb/serial/empeg.c b/drivers/usb/serial/empeg.c
index 8d562ab454a8..0b0546dcc7b9 100644
--- a/drivers/usb/serial/empeg.c
+++ b/drivers/usb/serial/empeg.c
@@ -112,9 +112,11 @@ static struct usb_driver empeg_driver = {
.id_table = id_table,
};
-static struct usb_serial_device_type empeg_device = {
- .owner = THIS_MODULE,
- .name = "Empeg",
+static struct usb_serial_driver empeg_device = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "empeg",
+ },
.id_table = id_table,
.num_interrupt_in = 0,
.num_bulk_in = 1,
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
index 5a8631c8a4a7..61204bf7cd78 100644
--- a/drivers/usb/serial/ftdi_sio.c
+++ b/drivers/usb/serial/ftdi_sio.c
@@ -411,6 +411,8 @@ static struct usb_device_id id_table_combined [] = {
{ USB_DEVICE(FTDI_VID, FTDI_ELV_UM100_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_ELV_UR100_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_ELV_ALC8500_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_PYRAMID_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_ELV_FHZ1000PC_PID) },
/*
* These will probably use user-space drivers. Uncomment them if
* you need them or use the user-specified vendor/product module
@@ -428,7 +430,6 @@ static struct usb_device_id id_table_combined [] = {
/* { USB_DEVICE(FTDI_VID, FTDI_ELV_T1100_PID) }, */
/* { USB_DEVICE(FTDI_VID, FTDI_ELV_PCD200_PID) }, */
/* { USB_DEVICE(FTDI_VID, FTDI_ELV_ULA200_PID) }, */
- /* { USB_DEVICE(FTDI_VID, FTDI_ELV_FHZ1000PC_PID) }, */
/* { USB_DEVICE(FTDI_VID, FTDI_ELV_CSI8_PID) }, */
/* { USB_DEVICE(FTDI_VID, FTDI_ELV_EM1000DL_PID) }, */
/* { USB_DEVICE(FTDI_VID, FTDI_ELV_PCK100_PID) }, */
@@ -471,6 +472,9 @@ static struct usb_device_id id_table_combined [] = {
{ USB_DEVICE(FTDI_VID, FTDI_MHAM_Y6_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_MHAM_Y8_PID) },
{ USB_DEVICE(EVOLUTION_VID, EVOLUTION_ER1_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_ARTEMIS_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16HR_PID) },
{ }, /* Optional parameter entry */
{ } /* Terminating entry */
};
@@ -558,10 +562,12 @@ static unsigned short int ftdi_232am_baud_to_divisor (int baud);
static __u32 ftdi_232bm_baud_base_to_divisor (int baud, int base);
static __u32 ftdi_232bm_baud_to_divisor (int baud);
-static struct usb_serial_device_type ftdi_sio_device = {
- .owner = THIS_MODULE,
- .name = "FTDI USB Serial Device",
- .short_name = "ftdi_sio",
+static struct usb_serial_driver ftdi_sio_device = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "ftdi_sio",
+ },
+ .description = "FTDI USB Serial Device",
.id_table = id_table_combined,
.num_interrupt_in = 0,
.num_bulk_in = 1,
diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h
index 2c35d74cc6d6..ddb63df31ce6 100644
--- a/drivers/usb/serial/ftdi_sio.h
+++ b/drivers/usb/serial/ftdi_sio.h
@@ -199,6 +199,19 @@
#define FTDI_PIEGROUP_PID 0xF208 /* Product Id */
/*
+ * Definitions for Artemis astronomical USB based cameras
+ * Check it at http://www.artemisccd.co.uk/
+ */
+#define FTDI_ARTEMIS_PID 0xDF28 /* All Artemis Cameras */
+
+/*
+ * Definitions for ATIK Instruments astronomical USB based cameras
+ * Check it at http://www.atik-instruments.com/
+ */
+#define FTDI_ATIK_ATK16_PID 0xDF30 /* ATIK ATK-16 Camera */
+#define FTDI_ATIK_ATK16HR_PID 0xDF31 /* ATIK ATK-16HR Camera */
+
+/*
* Protego product ids
*/
#define PROTEGO_SPECIAL_1 0xFC70 /* special/unknown device */
@@ -329,6 +342,9 @@
#define EVOLUTION_VID 0xDEEE /* Vendor ID */
#define EVOLUTION_ER1_PID 0x0300 /* ER1 Control Module */
+/* Pyramid Computer GmbH */
+#define FTDI_PYRAMID_PID 0xE6C8 /* Pyramid Appliance Display */
+
/* Commands */
#define FTDI_SIO_RESET 0 /* Reset the port */
#define FTDI_SIO_MODEM_CTRL 1 /* Set the modem control register */
diff --git a/drivers/usb/serial/garmin_gps.c b/drivers/usb/serial/garmin_gps.c
index 2ef614d5c8f2..35820bda7ae1 100644
--- a/drivers/usb/serial/garmin_gps.c
+++ b/drivers/usb/serial/garmin_gps.c
@@ -1468,16 +1468,13 @@ static void garmin_shutdown (struct usb_serial *serial)
}
-
-
-
-
-
/* All of the device info needed */
-static struct usb_serial_device_type garmin_device = {
- .owner = THIS_MODULE,
- .name = "Garmin GPS usb/tty",
- .short_name = "garmin_gps",
+static struct usb_serial_driver garmin_device = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "garmin_gps",
+ },
+ .description = "Garmin GPS usb/tty",
.id_table = id_table,
.num_interrupt_in = 1,
.num_bulk_in = 1,
diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c
index 5f7d3193d355..8909208f506a 100644
--- a/drivers/usb/serial/generic.c
+++ b/drivers/usb/serial/generic.c
@@ -36,10 +36,11 @@ MODULE_PARM_DESC(product, "User specified USB idProduct");
static struct usb_device_id generic_device_ids[2]; /* Initially all zeroes. */
/* All of the device info needed for the Generic Serial Converter */
-struct usb_serial_device_type usb_serial_generic_device = {
- .owner = THIS_MODULE,
- .name = "Generic",
- .short_name = "generic",
+struct usb_serial_driver usb_serial_generic_device = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "generic",
+ },
.id_table = generic_device_ids,
.num_interrupt_in = NUM_DONT_CARE,
.num_bulk_in = NUM_DONT_CARE,
diff --git a/drivers/usb/serial/hp4x.c b/drivers/usb/serial/hp4x.c
index 64d55fbd206e..8eadfb705601 100644
--- a/drivers/usb/serial/hp4x.c
+++ b/drivers/usb/serial/hp4x.c
@@ -38,15 +38,17 @@ MODULE_DEVICE_TABLE(usb, id_table);
static struct usb_driver hp49gp_driver = {
.owner = THIS_MODULE,
- .name = "HP4X",
+ .name = "hp4X",
.probe = usb_serial_probe,
.disconnect = usb_serial_disconnect,
.id_table = id_table,
};
-static struct usb_serial_device_type hp49gp_device = {
- .owner = THIS_MODULE,
- .name = "HP4X",
+static struct usb_serial_driver hp49gp_device = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "hp4X",
+ },
.id_table = id_table,
.num_interrupt_in = NUM_DONT_CARE,
.num_bulk_in = NUM_DONT_CARE,
diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c
index 04bfe279d763..dc4c498bd1ed 100644
--- a/drivers/usb/serial/io_edgeport.c
+++ b/drivers/usb/serial/io_edgeport.c
@@ -27,225 +27,6 @@
* Networks technical support, or Peter Berger <pberger@brimson.com>,
* or Al Borchers <alborchers@steinerpoint.com>.
*
- * Version history:
- *
- * 2003_04_03 al borchers
- * - fixed a bug (that shows up with dosemu) where the tty struct is
- * used in a callback after it has been freed
- *
- * 2.3 2002_03_08 greg kroah-hartman
- * - fixed bug when multiple devices were attached at the same time.
- *
- * 2.2 2001_11_14 greg kroah-hartman
- * - fixed bug in edge_close that kept the port from being used more
- * than once.
- * - fixed memory leak on device removal.
- * - fixed potential double free of memory when command urb submitting
- * failed.
- * - other small cleanups when the device is removed
- *
- * 2.1 2001_07_09 greg kroah-hartman
- * - added support for TIOCMBIS and TIOCMBIC.
- *
- * (04/08/2001) gb
- * - Identify version on module load.
- *
- * 2.0 2001_03_05 greg kroah-hartman
- * - reworked entire driver to fit properly in with the other usb-serial
- * drivers. Occasional oopses still happen, but it's a good start.
- *
- * 1.2.3 (02/23/2001) greg kroah-hartman
- * - changed device table to work properly for 2.4.x final format.
- * - fixed problem with dropping data at high data rates.
- *
- * 1.2.2 (11/27/2000) greg kroah-hartman
- * - cleaned up more NTisms.
- * - Added device table for 2.4.0-test11
- *
- * 1.2.1 (11/08/2000) greg kroah-hartman
- * - Started to clean up NTisms.
- * - Fixed problem with dev field of urb for kernels >= 2.4.0-test9
- *
- * 1.2 (10/17/2000) David Iacovelli
- * Remove all EPIC code and GPL source
- * Fix RELEVANT_IFLAG macro to include flow control
- * changes port configuration changes.
- * Fix redefinition of SERIAL_MAGIC
- * Change all timeout values to 5 seconds
- * Tried to fix the UHCI multiple urb submission, but failed miserably.
- * it seems to work fine with OHCI.
- * ( Greg take a look at the #if 0 at end of WriteCmdUsb() we must
- * find a way to work arount this UHCI bug )
- *
- * 1.1 (10/11/2000) David Iacovelli
- * Fix XON/XOFF flow control to support both IXON and IXOFF
- *
- * 0.9.27 (06/30/2000) David Iacovelli
- * Added transmit queue and now allocate urb for command writes.
- *
- * 0.9.26 (06/29/2000) David Iacovelli
- * Add support for 80251 based edgeport
- *
- * 0.9.25 (06/27/2000) David Iacovelli
- * Do not close the port if it has multiple opens.
- *
- * 0.9.24 (05/26/2000) David Iacovelli
- * Add IOCTLs to support RXTX and JAVA POS
- * and first cut at running BlackBox Demo
- *
- * 0.9.23 (05/24/2000) David Iacovelli
- * Add IOCTLs to support RXTX and JAVA POS
- *
- * 0.9.22 (05/23/2000) David Iacovelli
- * fixed bug in enumeration. If epconfig turns on mapping by
- * path after a device is already plugged in, we now update
- * the mapping correctly
- *
- * 0.9.21 (05/16/2000) David Iacovelli
- * Added BlockUntilChaseResp() to also wait for txcredits
- * Updated the way we allocate and handle write URBs
- * Add debug code to dump buffers
- *
- * 0.9.20 (05/01/2000) David Iacovelli
- * change driver to use usb/tts/
- *
- * 0.9.19 (05/01/2000) David Iacovelli
- * Update code to compile if DEBUG is off
- *
- * 0.9.18 (04/28/2000) David Iacovelli
- * cleanup and test tty_register with devfs
- *
- * 0.9.17 (04/27/2000) greg kroah-hartman
- * changed tty_register around to be like the way it
- * was before, but now it works properly with devfs.
- *
- * 0.9.16 (04/26/2000) david iacovelli
- * Fixed bug in GetProductInfo()
- *
- * 0.9.15 (04/25/2000) david iacovelli
- * Updated enumeration
- *
- * 0.9.14 (04/24/2000) david iacovelli
- * Removed all config/status IOCTLS and
- * converted to using /proc/edgeport
- * still playing with devfs
- *
- * 0.9.13 (04/24/2000) david iacovelli
- * Removed configuration based on ttyUSB0
- * Added support for configuration using /prod/edgeport
- * first attempt at using devfs (not working yet!)
- * Added IOCTL to GetProductInfo()
- * Added support for custom baud rates
- * Add support for random port numbers
- *
- * 0.9.12 (04/18/2000) david iacovelli
- * added additional configuration IOCTLs
- * use ttyUSB0 for configuration
- *
- * 0.9.11 (04/17/2000) greg kroah-hartman
- * fixed module initialization race conditions.
- * made all urbs dynamically allocated.
- * made driver devfs compatible. now it only registers the tty device
- * when the device is actually plugged in.
- *
- * 0.9.10 (04/13/2000) greg kroah-hartman
- * added proc interface framework.
- *
- * 0.9.9 (04/13/2000) david iacovelli
- * added enumeration code and ioctls to configure the device
- *
- * 0.9.8 (04/12/2000) david iacovelli
- * Change interrupt read start when device is plugged in
- * and stop when device is removed
- * process interrupt reads when all ports are closed
- * (keep value of rxBytesAvail consistent with the edgeport)
- * set the USB_BULK_QUEUE flag so that we can shove a bunch
- * of urbs at once down the pipe
- *
- * 0.9.7 (04/10/2000) david iacovelli
- * start to add enumeration code.
- * generate serial number for epic devices
- * add support for kdb
- *
- * 0.9.6 (03/30/2000) david iacovelli
- * add IOCTL to get string, manufacture, and boot descriptors
- *
- * 0.9.5 (03/14/2000) greg kroah-hartman
- * more error checking added to SerialOpen to try to fix UHCI open problem
- *
- * 0.9.4 (03/09/2000) greg kroah-hartman
- * added more error checking to handle oops when data is hanging
- * around and tty is abruptly closed.
- *
- * 0.9.3 (03/09/2000) david iacovelli
- * Add epic support for xon/xoff chars
- * play with performance
- *
- * 0.9.2 (03/08/2000) greg kroah-hartman
- * changed most "info" calls to "dbg"
- * implemented flow control properly in the termios call
- *
- * 0.9.1 (03/08/2000) david iacovelli
- * added EPIC support
- * enabled bootloader update
- *
- * 0.9 (03/08/2000) greg kroah-hartman
- * Release to IO networks.
- * Integrated changes that David made
- * made getting urbs for writing SMP safe
- *
- * 0.8 (03/07/2000) greg kroah-hartman
- * Release to IO networks.
- * Fixed problems that were seen in code by David.
- * Now both Edgeport/4 and Edgeport/2 works properly.
- * Changed most of the functions to use port instead of serial.
- *
- * 0.7 (02/27/2000) greg kroah-hartman
- * Milestone 3 release.
- * Release to IO Networks
- * ioctl for waiting on line change implemented.
- * ioctl for getting statistics implemented.
- * multiport support working.
- * lsr and msr registers are now handled properly.
- * change break now hooked up and working.
- * support for all known Edgeport devices.
- *
- * 0.6 (02/22/2000) greg kroah-hartman
- * Release to IO networks.
- * CHASE is implemented correctly when port is closed.
- * SerialOpen now blocks correctly until port is fully opened.
- *
- * 0.5 (02/20/2000) greg kroah-hartman
- * Release to IO networks.
- * Known problems:
- * modem status register changes are not sent on to the user
- * CHASE is not implemented when the port is closed.
- *
- * 0.4 (02/16/2000) greg kroah-hartman
- * Second cut at the CeBit demo.
- * Doesn't leak memory on every write to the port
- * Still small leaks on startup.
- * Added support for Edgeport/2 and Edgeport/8
- *
- * 0.3 (02/15/2000) greg kroah-hartman
- * CeBit demo release.
- * Force the line settings to 4800, 8, 1, e for the demo.
- * Warning! This version leaks memory like crazy!
- *
- * 0.2 (01/30/2000) greg kroah-hartman
- * Milestone 1 release.
- * Device is found by USB subsystem, enumerated, fimware is downloaded
- * and the descriptors are printed to the debug log, config is set, and
- * green light starts to blink. Open port works, and data can be sent
- * and received at the default settings of the UART. Loopback connector
- * and debug log confirms this.
- *
- * 0.1 (01/23/2000) greg kroah-hartman
- * Initial release to help IO Networks try to set up their test system.
- * Edgeport4 is recognized, firmware is downloaded, config is set so
- * device blinks green light every 3 sec. Port is bound, but opening,
- * closing, and sending data do not work properly.
- *
*/
#include <linux/config.h>
diff --git a/drivers/usb/serial/io_tables.h b/drivers/usb/serial/io_tables.h
index e7ffe02408bd..fad561c04c76 100644
--- a/drivers/usb/serial/io_tables.h
+++ b/drivers/usb/serial/io_tables.h
@@ -75,10 +75,12 @@ static struct usb_device_id id_table_combined [] = {
MODULE_DEVICE_TABLE (usb, id_table_combined);
-static struct usb_serial_device_type edgeport_2port_device = {
- .owner = THIS_MODULE,
- .name = "Edgeport 2 port adapter",
- .short_name = "edgeport_2",
+static struct usb_serial_driver edgeport_2port_device = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "edgeport_2",
+ },
+ .description = "Edgeport 2 port adapter",
.id_table = edgeport_2port_id_table,
.num_interrupt_in = 1,
.num_bulk_in = 1,
@@ -103,10 +105,12 @@ static struct usb_serial_device_type edgeport_2port_device = {
.write_bulk_callback = edge_bulk_out_data_callback,
};
-static struct usb_serial_device_type edgeport_4port_device = {
- .owner = THIS_MODULE,
- .name = "Edgeport 4 port adapter",
- .short_name = "edgeport_4",
+static struct usb_serial_driver edgeport_4port_device = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "edgeport_4",
+ },
+ .description = "Edgeport 4 port adapter",
.id_table = edgeport_4port_id_table,
.num_interrupt_in = 1,
.num_bulk_in = 1,
@@ -131,10 +135,12 @@ static struct usb_serial_device_type edgeport_4port_device = {
.write_bulk_callback = edge_bulk_out_data_callback,
};
-static struct usb_serial_device_type edgeport_8port_device = {
- .owner = THIS_MODULE,
- .name = "Edgeport 8 port adapter",
- .short_name = "edgeport_8",
+static struct usb_serial_driver edgeport_8port_device = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "edgeport_8",
+ },
+ .description = "Edgeport 8 port adapter",
.id_table = edgeport_8port_id_table,
.num_interrupt_in = 1,
.num_bulk_in = 1,
diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c
index ebf9967f7c86..832b6d6734c0 100644
--- a/drivers/usb/serial/io_ti.c
+++ b/drivers/usb/serial/io_ti.c
@@ -2982,10 +2982,12 @@ static unsigned int edge_buf_get(struct edge_buf *eb, char *buf,
}
-static struct usb_serial_device_type edgeport_1port_device = {
- .owner = THIS_MODULE,
- .name = "Edgeport TI 1 port adapter",
- .short_name = "edgeport_ti_1",
+static struct usb_serial_driver edgeport_1port_device = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "edgeport_ti_1",
+ },
+ .description = "Edgeport TI 1 port adapter",
.id_table = edgeport_1port_id_table,
.num_interrupt_in = 1,
.num_bulk_in = 1,
@@ -3010,10 +3012,12 @@ static struct usb_serial_device_type edgeport_1port_device = {
.write_bulk_callback = edge_bulk_out_callback,
};
-static struct usb_serial_device_type edgeport_2port_device = {
- .owner = THIS_MODULE,
- .name = "Edgeport TI 2 port adapter",
- .short_name = "edgeport_ti_2",
+static struct usb_serial_driver edgeport_2port_device = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "edgeport_ti_2",
+ },
+ .description = "Edgeport TI 2 port adapter",
.id_table = edgeport_2port_id_table,
.num_interrupt_in = 1,
.num_bulk_in = 2,
diff --git a/drivers/usb/serial/ipaq.c b/drivers/usb/serial/ipaq.c
index c05c2a2a0f31..d5d066488100 100644
--- a/drivers/usb/serial/ipaq.c
+++ b/drivers/usb/serial/ipaq.c
@@ -92,24 +92,7 @@ static void ipaq_destroy_lists(struct usb_serial_port *port);
static struct usb_device_id ipaq_id_table [] = {
/* The first entry is a placeholder for the insmod-specified device */
{ USB_DEVICE(0x049F, 0x0003) },
- { USB_DEVICE(0x1690, 0x0601) }, /* Askey USB Sync */
- { USB_DEVICE(0x0960, 0x0065) }, /* BCOM USB Sync 0065 */
- { USB_DEVICE(0x0960, 0x0066) }, /* BCOM USB Sync 0066 */
- { USB_DEVICE(0x0960, 0x0067) }, /* BCOM USB Sync 0067 */
- { USB_DEVICE(0x07CF, 0x2001) }, /* CASIO USB Sync 2001 */
- { USB_DEVICE(0x07CF, 0x2002) }, /* CASIO USB Sync 2002 */
- { USB_DEVICE(0x07CF, 0x2003) }, /* CASIO USB Sync 2003 */
- { USB_DEVICE(0x049F, 0x0003) }, /* Compaq iPAQ USB Sync */
- { USB_DEVICE(0x049F, 0x0032) }, /* Compaq iPAQ USB Sync */
- { USB_DEVICE(0x413C, 0x4001) }, /* Dell Axim USB Sync */
- { USB_DEVICE(0x413C, 0x4002) }, /* Dell Axim USB Sync */
- { USB_DEVICE(0x413C, 0x4003) }, /* Dell Axim USB Sync */
- { USB_DEVICE(0x413C, 0x4004) }, /* Dell Axim USB Sync */
- { USB_DEVICE(0x413C, 0x4005) }, /* Dell Axim USB Sync */
- { USB_DEVICE(0x413C, 0x4006) }, /* Dell Axim USB Sync */
- { USB_DEVICE(0x413C, 0x4007) }, /* Dell Axim USB Sync */
- { USB_DEVICE(0x413C, 0x4008) }, /* Dell Axim USB Sync */
- { USB_DEVICE(0x413C, 0x4009) }, /* Dell Axim USB Sync */
+ { USB_DEVICE(0x0104, 0x00BE) }, /* Socket USB Sync */
{ USB_DEVICE(0x03F0, 0x1016) }, /* HP USB Sync */
{ USB_DEVICE(0x03F0, 0x1116) }, /* HP USB Sync 1611 */
{ USB_DEVICE(0x03F0, 0x1216) }, /* HP USB Sync 1612 */
@@ -125,7 +108,13 @@ static struct usb_device_id ipaq_id_table [] = {
{ USB_DEVICE(0x03F0, 0x5016) }, /* HP USB Sync 1650 */
{ USB_DEVICE(0x03F0, 0x5116) }, /* HP USB Sync 1651 */
{ USB_DEVICE(0x03F0, 0x5216) }, /* HP USB Sync 1652 */
- { USB_DEVICE(0x094B, 0x0001) }, /* Linkup Systems USB Sync */
+ { USB_DEVICE(0x0409, 0x00D5) }, /* NEC USB Sync */
+ { USB_DEVICE(0x0409, 0x00D6) }, /* NEC USB Sync */
+ { USB_DEVICE(0x0409, 0x00D7) }, /* NEC USB Sync */
+ { USB_DEVICE(0x0409, 0x8024) }, /* NEC USB Sync */
+ { USB_DEVICE(0x0409, 0x8025) }, /* NEC USB Sync */
+ { USB_DEVICE(0x043E, 0x9C01) }, /* LGE USB Sync */
+ { USB_DEVICE(0x045E, 0x00CE) }, /* Microsoft USB Sync */
{ USB_DEVICE(0x045E, 0x0400) }, /* Windows Powered Pocket PC 2002 */
{ USB_DEVICE(0x045E, 0x0401) }, /* Windows Powered Pocket PC 2002 */
{ USB_DEVICE(0x045E, 0x0402) }, /* Windows Powered Pocket PC 2002 */
@@ -251,17 +240,81 @@ static struct usb_device_id ipaq_id_table [] = {
{ USB_DEVICE(0x045E, 0x04E8) }, /* Windows Powered Smartphone 2003 */
{ USB_DEVICE(0x045E, 0x04E9) }, /* Windows Powered Smartphone 2003 */
{ USB_DEVICE(0x045E, 0x04EA) }, /* Windows Powered Smartphone 2003 */
- { USB_DEVICE(0x0961, 0x0010) }, /* Portatec USB Sync */
- { USB_DEVICE(0x5E04, 0xCE00) }, /* SAGEM Wireless Assistant */
- { USB_DEVICE(0x0104, 0x00BE) }, /* Socket USB Sync */
+ { USB_DEVICE(0x049F, 0x0003) }, /* Compaq iPAQ USB Sync */
+ { USB_DEVICE(0x049F, 0x0032) }, /* Compaq iPAQ USB Sync */
+ { USB_DEVICE(0x04A4, 0x0014) }, /* Hitachi USB Sync */
+ { USB_DEVICE(0x04AD, 0x0301) }, /* USB Sync 0301 */
+ { USB_DEVICE(0x04AD, 0x0302) }, /* USB Sync 0302 */
+ { USB_DEVICE(0x04AD, 0x0303) }, /* USB Sync 0303 */
+ { USB_DEVICE(0x04C5, 0x1058) }, /* FUJITSU USB Sync */
+ { USB_DEVICE(0x04C5, 0x1079) }, /* FUJITSU USB Sync */
+ { USB_DEVICE(0x04DA, 0x2500) }, /* Panasonic USB Sync */
+ { USB_DEVICE(0x04E8, 0x5F00) }, /* Samsung NEXiO USB Sync */
+ { USB_DEVICE(0x04E8, 0x5F01) }, /* Samsung NEXiO USB Sync */
+ { USB_DEVICE(0x04E8, 0x5F02) }, /* Samsung NEXiO USB Sync */
+ { USB_DEVICE(0x04E8, 0x5F03) }, /* Samsung NEXiO USB Sync */
+ { USB_DEVICE(0x04E8, 0x5F04) }, /* Samsung NEXiO USB Sync */
+ { USB_DEVICE(0x04E8, 0x6611) }, /* Samsung MITs USB Sync */
+ { USB_DEVICE(0x04E8, 0x6613) }, /* Samsung MITs USB Sync */
+ { USB_DEVICE(0x04E8, 0x6615) }, /* Samsung MITs USB Sync */
+ { USB_DEVICE(0x04E8, 0x6617) }, /* Samsung MITs USB Sync */
+ { USB_DEVICE(0x04E8, 0x6619) }, /* Samsung MITs USB Sync */
+ { USB_DEVICE(0x04E8, 0x661B) }, /* Samsung MITs USB Sync */
+ { USB_DEVICE(0x04E8, 0x662E) }, /* Samsung MITs USB Sync */
+ { USB_DEVICE(0x04E8, 0x6630) }, /* Samsung MITs USB Sync */
+ { USB_DEVICE(0x04E8, 0x6632) }, /* Samsung MITs USB Sync */
+ { USB_DEVICE(0x04f1, 0x3011) }, /* JVC USB Sync */
+ { USB_DEVICE(0x04F1, 0x3012) }, /* JVC USB Sync */
+ { USB_DEVICE(0x0502, 0x1631) }, /* c10 Series */
+ { USB_DEVICE(0x0502, 0x1632) }, /* c20 Series */
+ { USB_DEVICE(0x0502, 0x16E1) }, /* Acer n10 Handheld USB Sync */
+ { USB_DEVICE(0x0502, 0x16E2) }, /* Acer n20 Handheld USB Sync */
+ { USB_DEVICE(0x0502, 0x16E3) }, /* Acer n30 Handheld USB Sync */
+ { USB_DEVICE(0x0536, 0x01A0) }, /* HHP PDT */
+ { USB_DEVICE(0x0543, 0x0ED9) }, /* ViewSonic Color Pocket PC V35 */
+ { USB_DEVICE(0x0543, 0x1527) }, /* ViewSonic Color Pocket PC V36 */
+ { USB_DEVICE(0x0543, 0x1529) }, /* ViewSonic Color Pocket PC V37 */
+ { USB_DEVICE(0x0543, 0x152B) }, /* ViewSonic Color Pocket PC V38 */
+ { USB_DEVICE(0x0543, 0x152E) }, /* ViewSonic Pocket PC */
+ { USB_DEVICE(0x0543, 0x1921) }, /* ViewSonic Communicator Pocket PC */
+ { USB_DEVICE(0x0543, 0x1922) }, /* ViewSonic Smartphone */
+ { USB_DEVICE(0x0543, 0x1923) }, /* ViewSonic Pocket PC V30 */
+ { USB_DEVICE(0x05E0, 0x2000) }, /* Symbol USB Sync */
+ { USB_DEVICE(0x05E0, 0x2001) }, /* Symbol USB Sync 0x2001 */
+ { USB_DEVICE(0x05E0, 0x2002) }, /* Symbol USB Sync 0x2002 */
+ { USB_DEVICE(0x05E0, 0x2003) }, /* Symbol USB Sync 0x2003 */
+ { USB_DEVICE(0x05E0, 0x2004) }, /* Symbol USB Sync 0x2004 */
+ { USB_DEVICE(0x05E0, 0x2005) }, /* Symbol USB Sync 0x2005 */
+ { USB_DEVICE(0x05E0, 0x2006) }, /* Symbol USB Sync 0x2006 */
+ { USB_DEVICE(0x05E0, 0x2007) }, /* Symbol USB Sync 0x2007 */
+ { USB_DEVICE(0x05E0, 0x2008) }, /* Symbol USB Sync 0x2008 */
+ { USB_DEVICE(0x05E0, 0x2009) }, /* Symbol USB Sync 0x2009 */
+ { USB_DEVICE(0x05E0, 0x200A) }, /* Symbol USB Sync 0x200A */
+ { USB_DEVICE(0x067E, 0x1001) }, /* Intermec Mobile Computer */
+ { USB_DEVICE(0x07CF, 0x2001) }, /* CASIO USB Sync 2001 */
+ { USB_DEVICE(0x07CF, 0x2002) }, /* CASIO USB Sync 2002 */
+ { USB_DEVICE(0x07CF, 0x2003) }, /* CASIO USB Sync 2003 */
{ USB_DEVICE(0x0930, 0x0700) }, /* TOSHIBA USB Sync 0700 */
{ USB_DEVICE(0x0930, 0x0705) }, /* TOSHIBA Pocket PC e310 */
+ { USB_DEVICE(0x0930, 0x0706) }, /* TOSHIBA Pocket PC e740 */
{ USB_DEVICE(0x0930, 0x0707) }, /* TOSHIBA Pocket PC e330 Series */
{ USB_DEVICE(0x0930, 0x0708) }, /* TOSHIBA Pocket PC e350 Series */
- { USB_DEVICE(0x0930, 0x0706) }, /* TOSHIBA Pocket PC e740 */
{ USB_DEVICE(0x0930, 0x0709) }, /* TOSHIBA Pocket PC e750 Series */
{ USB_DEVICE(0x0930, 0x070A) }, /* TOSHIBA Pocket PC e400 Series */
{ USB_DEVICE(0x0930, 0x070B) }, /* TOSHIBA Pocket PC e800 Series */
+ { USB_DEVICE(0x094B, 0x0001) }, /* Linkup Systems USB Sync */
+ { USB_DEVICE(0x0960, 0x0065) }, /* BCOM USB Sync 0065 */
+ { USB_DEVICE(0x0960, 0x0066) }, /* BCOM USB Sync 0066 */
+ { USB_DEVICE(0x0960, 0x0067) }, /* BCOM USB Sync 0067 */
+ { USB_DEVICE(0x0961, 0x0010) }, /* Portatec USB Sync */
+ { USB_DEVICE(0x099E, 0x0052) }, /* Trimble GeoExplorer */
+ { USB_DEVICE(0x099E, 0x4000) }, /* TDS Data Collector */
+ { USB_DEVICE(0x0B05, 0x4200) }, /* ASUS USB Sync */
+ { USB_DEVICE(0x0B05, 0x4201) }, /* ASUS USB Sync */
+ { USB_DEVICE(0x0B05, 0x4202) }, /* ASUS USB Sync */
+ { USB_DEVICE(0x0B05, 0x420F) }, /* ASUS USB Sync */
+ { USB_DEVICE(0x0B05, 0x9200) }, /* ASUS USB Sync */
+ { USB_DEVICE(0x0B05, 0x9202) }, /* ASUS USB Sync */
{ USB_DEVICE(0x0BB4, 0x00CE) }, /* HTC USB Sync */
{ USB_DEVICE(0x0BB4, 0x0A01) }, /* PocketPC USB Sync */
{ USB_DEVICE(0x0BB4, 0x0A02) }, /* PocketPC USB Sync */
@@ -422,116 +475,67 @@ static struct usb_device_id ipaq_id_table [] = {
{ USB_DEVICE(0x0BB4, 0x0A9D) }, /* SmartPhone USB Sync */
{ USB_DEVICE(0x0BB4, 0x0A9E) }, /* SmartPhone USB Sync */
{ USB_DEVICE(0x0BB4, 0x0A9F) }, /* SmartPhone USB Sync */
- { USB_DEVICE(0x0409, 0x00D5) }, /* NEC USB Sync */
- { USB_DEVICE(0x0409, 0x00D6) }, /* NEC USB Sync */
- { USB_DEVICE(0x0409, 0x00D7) }, /* NEC USB Sync */
- { USB_DEVICE(0x0409, 0x8024) }, /* NEC USB Sync */
- { USB_DEVICE(0x0409, 0x8025) }, /* NEC USB Sync */
- { USB_DEVICE(0x04A4, 0x0014) }, /* Hitachi USB Sync */
{ USB_DEVICE(0x0BF8, 0x1001) }, /* Fujitsu Siemens Computers USB Sync */
- { USB_DEVICE(0x0F98, 0x0201) }, /* Cyberbank USB Sync */
- { USB_DEVICE(0x0502, 0x16E1) }, /* Acer n10 Handheld USB Sync */
- { USB_DEVICE(0x0502, 0x16E3) }, /* Acer n30 Handheld USB Sync */
- { USB_DEVICE(0x0502, 0x16E2) }, /* Acer n20 Handheld USB Sync */
- { USB_DEVICE(0x0502, 0x1631) }, /* c10 Series */
- { USB_DEVICE(0x0502, 0x1632) }, /* c20 Series */
- { USB_DEVICE(0x0B05, 0x9202) }, /* ASUS USB Sync */
- { USB_DEVICE(0x0B05, 0x420F) }, /* ASUS USB Sync */
- { USB_DEVICE(0x0B05, 0x4200) }, /* ASUS USB Sync */
- { USB_DEVICE(0x0B05, 0x4201) }, /* ASUS USB Sync */
- { USB_DEVICE(0x0B05, 0x4202) }, /* ASUS USB Sync */
- { USB_DEVICE(0x0B05, 0x9200) }, /* ASUS USB Sync */
+ { USB_DEVICE(0x0C44, 0x03A2) }, /* Motorola iDEN Smartphone */
{ USB_DEVICE(0x0C8E, 0x6000) }, /* Cesscom Luxian Series */
- { USB_DEVICE(0x04AD, 0x0301) }, /* USB Sync 0301 */
- { USB_DEVICE(0x04AD, 0x0302) }, /* USB Sync 0302 */
- { USB_DEVICE(0x04AD, 0x0303) }, /* USB Sync 0303 */
+ { USB_DEVICE(0x0CAD, 0x9001) }, /* Motorola PowerPad Pocket PC Device */
+ { USB_DEVICE(0x0F4E, 0x0200) }, /* Freedom Scientific USB Sync */
+ { USB_DEVICE(0x0F98, 0x0201) }, /* Cyberbank USB Sync */
+ { USB_DEVICE(0x0FB8, 0x3001) }, /* Wistron USB Sync */
+ { USB_DEVICE(0x0FB8, 0x3002) }, /* Wistron USB Sync */
+ { USB_DEVICE(0x0FB8, 0x3003) }, /* Wistron USB Sync */
+ { USB_DEVICE(0x0FB8, 0x4001) }, /* Wistron USB Sync */
+ { USB_DEVICE(0x1066, 0x00CE) }, /* E-TEN USB Sync */
{ USB_DEVICE(0x1066, 0x0300) }, /* E-TEN P3XX Pocket PC */
{ USB_DEVICE(0x1066, 0x0500) }, /* E-TEN P5XX Pocket PC */
{ USB_DEVICE(0x1066, 0x0600) }, /* E-TEN P6XX Pocket PC */
{ USB_DEVICE(0x1066, 0x0700) }, /* E-TEN P7XX Pocket PC */
- { USB_DEVICE(0x1066, 0x00CE) }, /* E-TEN USB Sync */
- { USB_DEVICE(0x0F4E, 0x0200) }, /* Freedom Scientific USB Sync */
- { USB_DEVICE(0x04C5, 0x1058) }, /* FUJITSU USB Sync */
- { USB_DEVICE(0x04C5, 0x1079) }, /* FUJITSU USB Sync */
- { USB_DEVICE(0x067E, 0x1001) }, /* Intermec Mobile Computer */
- { USB_DEVICE(0x04f1, 0x3011) }, /* JVC USB Sync */
- { USB_DEVICE(0x04F1, 0x3012) }, /* JVC USB Sync */
- { USB_DEVICE(0x3708, 0x20CE) }, /* Legend USB Sync */
- { USB_DEVICE(0x3708, 0x21CE) }, /* Lenovo USB Sync */
- { USB_DEVICE(0x043E, 0x9C01) }, /* LGE USB Sync */
- { USB_DEVICE(0x04DA, 0x2500) }, /* Panasonic USB Sync */
- { USB_DEVICE(0x3340, 0x0B1C) }, /* Generic PPC StrongARM */
- { USB_DEVICE(0x3340, 0x0E3A) }, /* Generic PPC USB Sync */
- { USB_DEVICE(0x3340, 0x0F3A) }, /* Generic SmartPhone USB Sync */
- { USB_DEVICE(0x3340, 0x0F1C) }, /* Itautec USB Sync */
- { USB_DEVICE(0x3340, 0x1326) }, /* Itautec USB Sync */
- { USB_DEVICE(0x3340, 0x3326) }, /* MEDION Winodws Moble USB Sync */
+ { USB_DEVICE(0x1114, 0x0001) }, /* Psion Teklogix Sync 753x */
+ { USB_DEVICE(0x1114, 0x0004) }, /* Psion Teklogix Sync netBookPro */
+ { USB_DEVICE(0x1114, 0x0006) }, /* Psion Teklogix Sync 7525 */
+ { USB_DEVICE(0x1182, 0x1388) }, /* VES USB Sync */
+ { USB_DEVICE(0x11D9, 0x1002) }, /* Rugged Pocket PC 2003 */
+ { USB_DEVICE(0x11D9, 0x1003) }, /* Rugged Pocket PC 2003 */
+ { USB_DEVICE(0x1231, 0xCE01) }, /* USB Sync 03 */
+ { USB_DEVICE(0x1231, 0xCE02) }, /* USB Sync 03 */
+ { USB_DEVICE(0x1690, 0x0601) }, /* Askey USB Sync */
+ { USB_DEVICE(0x22B8, 0x4204) }, /* Motorola MPx200 Smartphone */
+ { USB_DEVICE(0x22B8, 0x4214) }, /* Motorola MPc GSM */
+ { USB_DEVICE(0x22B8, 0x4224) }, /* Motorola MPx220 Smartphone */
+ { USB_DEVICE(0x22B8, 0x4234) }, /* Motorola MPc CDMA */
+ { USB_DEVICE(0x22B8, 0x4244) }, /* Motorola MPx100 Smartphone */
+ { USB_DEVICE(0x3340, 0x011C) }, /* Mio DigiWalker PPC StrongARM */
{ USB_DEVICE(0x3340, 0x0326) }, /* Mio DigiWalker 338 */
{ USB_DEVICE(0x3340, 0x0426) }, /* Mio DigiWalker 338 */
- { USB_DEVICE(0x3340, 0x011C) }, /* Mio DigiWalker PPC StrongARM */
- { USB_DEVICE(0x3340, 0x053A) }, /* Mio DigiWalker SmartPhone USB Sync */
{ USB_DEVICE(0x3340, 0x043A) }, /* Mio DigiWalker USB Sync */
- { USB_DEVICE(0x3340, 0x071C) }, /* MiTAC USB Sync */
{ USB_DEVICE(0x3340, 0x051C) }, /* MiTAC USB Sync 528 */
- { USB_DEVICE(0x3340, 0x2326) }, /* Vobis USB Sync */
+ { USB_DEVICE(0x3340, 0x053A) }, /* Mio DigiWalker SmartPhone USB Sync */
+ { USB_DEVICE(0x3340, 0x071C) }, /* MiTAC USB Sync */
+ { USB_DEVICE(0x3340, 0x0B1C) }, /* Generic PPC StrongARM */
+ { USB_DEVICE(0x3340, 0x0E3A) }, /* Generic PPC USB Sync */
+ { USB_DEVICE(0x3340, 0x0F1C) }, /* Itautec USB Sync */
+ { USB_DEVICE(0x3340, 0x0F3A) }, /* Generic SmartPhone USB Sync */
+ { USB_DEVICE(0x3340, 0x1326) }, /* Itautec USB Sync */
{ USB_DEVICE(0x3340, 0x191C) }, /* YAKUMO USB Sync */
+ { USB_DEVICE(0x3340, 0x2326) }, /* Vobis USB Sync */
+ { USB_DEVICE(0x3340, 0x3326) }, /* MEDION Winodws Moble USB Sync */
+ { USB_DEVICE(0x3708, 0x20CE) }, /* Legend USB Sync */
+ { USB_DEVICE(0x3708, 0x21CE) }, /* Lenovo USB Sync */
{ USB_DEVICE(0x4113, 0x0210) }, /* Mobile Media Technology USB Sync */
{ USB_DEVICE(0x4113, 0x0211) }, /* Mobile Media Technology USB Sync */
{ USB_DEVICE(0x4113, 0x0400) }, /* Mobile Media Technology USB Sync */
{ USB_DEVICE(0x4113, 0x0410) }, /* Mobile Media Technology USB Sync */
- { USB_DEVICE(0x0CAD, 0x9001) }, /* Motorola PowerPad Pocket PC Device */
- { USB_DEVICE(0x0C44, 0x03A2) }, /* Motorola iDEN Smartphone */
- { USB_DEVICE(0x04E8, 0x6611) }, /* Samsung MITs USB Sync */
- { USB_DEVICE(0x04E8, 0x6613) }, /* Samsung MITs USB Sync */
- { USB_DEVICE(0x04E8, 0x6615) }, /* Samsung MITs USB Sync */
- { USB_DEVICE(0x04E8, 0x6617) }, /* Samsung MITs USB Sync */
- { USB_DEVICE(0x04E8, 0x6619) }, /* Samsung MITs USB Sync */
- { USB_DEVICE(0x04E8, 0x661B) }, /* Samsung MITs USB Sync */
- { USB_DEVICE(0x04E8, 0x5F00) }, /* Samsung NEXiO USB Sync */
- { USB_DEVICE(0x04E8, 0x5F01) }, /* Samsung NEXiO USB Sync */
- { USB_DEVICE(0x04E8, 0x5F02) }, /* Samsung NEXiO USB Sync */
- { USB_DEVICE(0x04E8, 0x5F03) }, /* Samsung NEXiO USB Sync */
- { USB_DEVICE(0x04E8, 0x5F04) }, /* Samsung NEXiO USB Sync */
- { USB_DEVICE(0x04E8, 0x662E) }, /* Samsung MITs USB Sync */
- { USB_DEVICE(0x04E8, 0x6630) }, /* Samsung MITs USB Sync */
- { USB_DEVICE(0x04E8, 0x6632) }, /* Samsung MITs USB Sync */
+ { USB_DEVICE(0x413C, 0x4001) }, /* Dell Axim USB Sync */
+ { USB_DEVICE(0x413C, 0x4002) }, /* Dell Axim USB Sync */
+ { USB_DEVICE(0x413C, 0x4003) }, /* Dell Axim USB Sync */
+ { USB_DEVICE(0x413C, 0x4004) }, /* Dell Axim USB Sync */
+ { USB_DEVICE(0x413C, 0x4005) }, /* Dell Axim USB Sync */
+ { USB_DEVICE(0x413C, 0x4006) }, /* Dell Axim USB Sync */
+ { USB_DEVICE(0x413C, 0x4007) }, /* Dell Axim USB Sync */
+ { USB_DEVICE(0x413C, 0x4008) }, /* Dell Axim USB Sync */
+ { USB_DEVICE(0x413C, 0x4009) }, /* Dell Axim USB Sync */
{ USB_DEVICE(0x4505, 0x0010) }, /* Smartphone */
- { USB_DEVICE(0x05E0, 0x2000) }, /* Symbol USB Sync */
- { USB_DEVICE(0x05E0, 0x2001) }, /* Symbol USB Sync 0x2001 */
- { USB_DEVICE(0x05E0, 0x2002) }, /* Symbol USB Sync 0x2002 */
- { USB_DEVICE(0x05E0, 0x2003) }, /* Symbol USB Sync 0x2003 */
- { USB_DEVICE(0x05E0, 0x2004) }, /* Symbol USB Sync 0x2004 */
- { USB_DEVICE(0x05E0, 0x2005) }, /* Symbol USB Sync 0x2005 */
- { USB_DEVICE(0x05E0, 0x2006) }, /* Symbol USB Sync 0x2006 */
- { USB_DEVICE(0x05E0, 0x2007) }, /* Symbol USB Sync 0x2007 */
- { USB_DEVICE(0x05E0, 0x2008) }, /* Symbol USB Sync 0x2008 */
- { USB_DEVICE(0x05E0, 0x2009) }, /* Symbol USB Sync 0x2009 */
- { USB_DEVICE(0x05E0, 0x200A) }, /* Symbol USB Sync 0x200A */
- { USB_DEVICE(0x1182, 0x1388) }, /* VES USB Sync */
- { USB_DEVICE(0x0543, 0x0ED9) }, /* ViewSonic Color Pocket PC V35 */
- { USB_DEVICE(0x0543, 0x1527) }, /* ViewSonic Color Pocket PC V36 */
- { USB_DEVICE(0x0543, 0x1529) }, /* ViewSonic Color Pocket PC V37 */
- { USB_DEVICE(0x0543, 0x152B) }, /* ViewSonic Color Pocket PC V38 */
- { USB_DEVICE(0x0543, 0x152E) }, /* ViewSonic Pocket PC */
- { USB_DEVICE(0x0543, 0x1921) }, /* ViewSonic Communicator Pocket PC */
- { USB_DEVICE(0x0543, 0x1922) }, /* ViewSonic Smartphone */
- { USB_DEVICE(0x0543, 0x1923) }, /* ViewSonic Pocket PC V30 */
- { USB_DEVICE(0x0536, 0x01A0) }, /* HHP PDT */
- { USB_DEVICE(0x099E, 0x0052) }, /* Trimble GeoExplorer */
- { USB_DEVICE(0x099E, 0x4000) }, /* TDS Data Collector */
- { USB_DEVICE(0x0FB8, 0x3001) }, /* Wistron USB Sync */
- { USB_DEVICE(0x0FB8, 0x3002) }, /* Wistron USB Sync */
- { USB_DEVICE(0x0FB8, 0x3003) }, /* Wistron USB Sync */
- { USB_DEVICE(0x0FB8, 0x4001) }, /* Wistron USB Sync */
- { USB_DEVICE(0x11D9, 0x1003) }, /* Rugged Pocket PC 2003 */
- { USB_DEVICE(0x11D9, 0x1002) }, /* Rugged Pocket PC 2003 */
- { USB_DEVICE(0x22B8, 0x4204) }, /* Motorola MPx200 Smartphone */
- { USB_DEVICE(0x22B8, 0x4214) }, /* Motorola MPc GSM */
- { USB_DEVICE(0x22B8, 0x4224) }, /* Motorola MPx220 Smartphone */
- { USB_DEVICE(0x22B8, 0x4234) }, /* Motorola MPc CDMA */
- { USB_DEVICE(0x22B8, 0x4244) }, /* Motorola MPx100 Smartphone */
- { USB_DEVICE(0x1231, 0xCE01) }, /* USB Sync 03 */
- { USB_DEVICE(0x1231, 0xCE02) }, /* USB Sync 03 */
+ { USB_DEVICE(0x5E04, 0xCE00) }, /* SAGEM Wireless Assistant */
{ } /* Terminating entry */
};
@@ -547,9 +551,12 @@ static struct usb_driver ipaq_driver = {
/* All of the device info needed for the Compaq iPAQ */
-static struct usb_serial_device_type ipaq_device = {
- .owner = THIS_MODULE,
- .name = "PocketPC PDA",
+static struct usb_serial_driver ipaq_device = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "ipaq",
+ },
+ .description = "PocketPC PDA",
.id_table = ipaq_id_table,
.num_interrupt_in = NUM_DONT_CARE,
.num_bulk_in = 1,
diff --git a/drivers/usb/serial/ipw.c b/drivers/usb/serial/ipw.c
index 85e242459c27..a02fada85362 100644
--- a/drivers/usb/serial/ipw.c
+++ b/drivers/usb/serial/ipw.c
@@ -443,10 +443,12 @@ static int ipw_disconnect(struct usb_serial_port *port)
return 0;
}
-static struct usb_serial_device_type ipw_device = {
- .owner = THIS_MODULE,
- .name = "IPWireless converter",
- .short_name = "ipw",
+static struct usb_serial_driver ipw_device = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "ipw",
+ },
+ .description = "IPWireless converter",
.id_table = usb_ipw_ids,
.num_interrupt_in = NUM_DONT_CARE,
.num_bulk_in = 1,
diff --git a/drivers/usb/serial/ir-usb.c b/drivers/usb/serial/ir-usb.c
index 937b2fdd7171..19f329e9bdcf 100644
--- a/drivers/usb/serial/ir-usb.c
+++ b/drivers/usb/serial/ir-usb.c
@@ -133,9 +133,12 @@ static struct usb_driver ir_driver = {
};
-static struct usb_serial_device_type ir_device = {
- .owner = THIS_MODULE,
- .name = "IR Dongle",
+static struct usb_serial_driver ir_device = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "ir-usb",
+ },
+ .description = "IR Dongle",
.id_table = id_table,
.num_interrupt_in = 1,
.num_bulk_in = 1,
diff --git a/drivers/usb/serial/keyspan.h b/drivers/usb/serial/keyspan.h
index e9b45b768aca..5cfc13b5e56f 100644
--- a/drivers/usb/serial/keyspan.h
+++ b/drivers/usb/serial/keyspan.h
@@ -570,10 +570,12 @@ static struct usb_device_id keyspan_4port_ids[] = {
};
/* Structs for the devices, pre and post renumeration. */
-static struct usb_serial_device_type keyspan_pre_device = {
- .owner = THIS_MODULE,
- .name = "Keyspan - (without firmware)",
- .short_name = "keyspan_no_firm",
+static struct usb_serial_driver keyspan_pre_device = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "keyspan_no_firm",
+ },
+ .description = "Keyspan - (without firmware)",
.id_table = keyspan_pre_ids,
.num_interrupt_in = NUM_DONT_CARE,
.num_bulk_in = NUM_DONT_CARE,
@@ -582,10 +584,12 @@ static struct usb_serial_device_type keyspan_pre_device = {
.attach = keyspan_fake_startup,
};
-static struct usb_serial_device_type keyspan_1port_device = {
- .owner = THIS_MODULE,
- .name = "Keyspan 1 port adapter",
- .short_name = "keyspan_1",
+static struct usb_serial_driver keyspan_1port_device = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "keyspan_1",
+ },
+ .description = "Keyspan 1 port adapter",
.id_table = keyspan_1port_ids,
.num_interrupt_in = NUM_DONT_CARE,
.num_bulk_in = NUM_DONT_CARE,
@@ -607,10 +611,12 @@ static struct usb_serial_device_type keyspan_1port_device = {
.shutdown = keyspan_shutdown,
};
-static struct usb_serial_device_type keyspan_2port_device = {
- .owner = THIS_MODULE,
- .name = "Keyspan 2 port adapter",
- .short_name = "keyspan_2",
+static struct usb_serial_driver keyspan_2port_device = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "keyspan_2",
+ },
+ .description = "Keyspan 2 port adapter",
.id_table = keyspan_2port_ids,
.num_interrupt_in = NUM_DONT_CARE,
.num_bulk_in = NUM_DONT_CARE,
@@ -632,10 +638,12 @@ static struct usb_serial_device_type keyspan_2port_device = {
.shutdown = keyspan_shutdown,
};
-static struct usb_serial_device_type keyspan_4port_device = {
- .owner = THIS_MODULE,
- .name = "Keyspan 4 port adapter",
- .short_name = "keyspan_4",
+static struct usb_serial_driver keyspan_4port_device = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "keyspan_4",
+ },
+ .description = "Keyspan 4 port adapter",
.id_table = keyspan_4port_ids,
.num_interrupt_in = NUM_DONT_CARE,
.num_bulk_in = 5,
diff --git a/drivers/usb/serial/keyspan_pda.c b/drivers/usb/serial/keyspan_pda.c
index 635c384cb15a..cd4f48bd83b6 100644
--- a/drivers/usb/serial/keyspan_pda.c
+++ b/drivers/usb/serial/keyspan_pda.c
@@ -783,10 +783,12 @@ static void keyspan_pda_shutdown (struct usb_serial *serial)
}
#ifdef KEYSPAN
-static struct usb_serial_device_type keyspan_pda_fake_device = {
- .owner = THIS_MODULE,
- .name = "Keyspan PDA - (prerenumeration)",
- .short_name = "keyspan_pda_pre",
+static struct usb_serial_driver keyspan_pda_fake_device = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "keyspan_pda_pre",
+ },
+ .description = "Keyspan PDA - (prerenumeration)",
.id_table = id_table_fake,
.num_interrupt_in = NUM_DONT_CARE,
.num_bulk_in = NUM_DONT_CARE,
@@ -797,10 +799,12 @@ static struct usb_serial_device_type keyspan_pda_fake_device = {
#endif
#ifdef XIRCOM
-static struct usb_serial_device_type xircom_pgs_fake_device = {
- .owner = THIS_MODULE,
- .name = "Xircom / Entregra PGS - (prerenumeration)",
- .short_name = "xircom_no_firm",
+static struct usb_serial_driver xircom_pgs_fake_device = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "xircom_no_firm",
+ },
+ .description = "Xircom / Entregra PGS - (prerenumeration)",
.id_table = id_table_fake_xircom,
.num_interrupt_in = NUM_DONT_CARE,
.num_bulk_in = NUM_DONT_CARE,
@@ -810,10 +814,12 @@ static struct usb_serial_device_type xircom_pgs_fake_device = {
};
#endif
-static struct usb_serial_device_type keyspan_pda_device = {
- .owner = THIS_MODULE,
- .name = "Keyspan PDA",
- .short_name = "keyspan_pda",
+static struct usb_serial_driver keyspan_pda_device = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "keyspan_pda",
+ },
+ .description = "Keyspan PDA",
.id_table = id_table_std,
.num_interrupt_in = 1,
.num_bulk_in = 0,
diff --git a/drivers/usb/serial/kl5kusb105.c b/drivers/usb/serial/kl5kusb105.c
index a11e829e38c8..a8951c0fd020 100644
--- a/drivers/usb/serial/kl5kusb105.c
+++ b/drivers/usb/serial/kl5kusb105.c
@@ -123,10 +123,12 @@ static struct usb_driver kl5kusb105d_driver = {
.id_table = id_table,
};
-static struct usb_serial_device_type kl5kusb105d_device = {
- .owner = THIS_MODULE,
- .name = "KL5KUSB105D / PalmConnect",
- .short_name = "kl5kusb105d",
+static struct usb_serial_driver kl5kusb105d_device = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "kl5kusb105d",
+ },
+ .description = "KL5KUSB105D / PalmConnect",
.id_table = id_table,
.num_interrupt_in = 1,
.num_bulk_in = 1,
diff --git a/drivers/usb/serial/kobil_sct.c b/drivers/usb/serial/kobil_sct.c
index fe4c98a75171..9456dd9dd136 100644
--- a/drivers/usb/serial/kobil_sct.c
+++ b/drivers/usb/serial/kobil_sct.c
@@ -105,9 +105,12 @@ static struct usb_driver kobil_driver = {
};
-static struct usb_serial_device_type kobil_device = {
- .owner = THIS_MODULE,
- .name = "KOBIL USB smart card terminal",
+static struct usb_serial_driver kobil_device = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "kobil",
+ },
+ .description = "KOBIL USB smart card terminal",
.id_table = id_table,
.num_interrupt_in = NUM_DONT_CARE,
.num_bulk_in = 0,
diff --git a/drivers/usb/serial/mct_u232.c b/drivers/usb/serial/mct_u232.c
index 50b6369647d2..ca5dbadb9b7e 100644
--- a/drivers/usb/serial/mct_u232.c
+++ b/drivers/usb/serial/mct_u232.c
@@ -132,10 +132,12 @@ static struct usb_driver mct_u232_driver = {
.id_table = id_table_combined,
};
-static struct usb_serial_device_type mct_u232_device = {
- .owner = THIS_MODULE,
- .name = "MCT U232",
- .short_name = "mct_u232",
+static struct usb_serial_driver mct_u232_device = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "mct_u232",
+ },
+ .description = "MCT U232",
.id_table = id_table_combined,
.num_interrupt_in = 2,
.num_bulk_in = 0,
diff --git a/drivers/usb/serial/nokia_dku2.c b/drivers/usb/serial/nokia_dku2.c
new file mode 100644
index 000000000000..fad01bef3a64
--- /dev/null
+++ b/drivers/usb/serial/nokia_dku2.c
@@ -0,0 +1,142 @@
+/*
+ * Nokia DKU2 USB driver
+ *
+ * Copyright (C) 2004
+ * Author: C Kemp
+ *
+ * This program is largely derived from work by the linux-usb group
+ * and associated source files. Please see the usb/serial files for
+ * individual credits and copyrights.
+ *
+ * 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.
+ *
+ * 20.09.2005 - Matthias Blaesing <matthias.blaesing@rwth-aachen.de>
+ * Added short name to device structure to make driver load into kernel 2.6.13
+ *
+ * 20.09.2005 - Matthias Blaesing <matthias.blaesing@rwth-aachen.de>
+ * Added usb_deregister to exit code - to allow remove and reinsert of module
+ */
+
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/tty.h>
+#include <linux/tty_driver.h>
+#include <linux/tty_flip.h>
+#include <linux/module.h>
+#include <linux/usb.h>
+#include "usb-serial.h"
+
+
+#define NOKIA_VENDOR_ID 0x0421
+#define NOKIA7600_PRODUCT_ID 0x0400
+#define NOKIA6230_PRODUCT_ID 0x040f
+#define NOKIA6170_PRODUCT_ID 0x0416
+#define NOKIA6670_PRODUCT_ID 0x041d
+#define NOKIA6680_PRODUCT_ID 0x041e
+#define NOKIA6230i_PRODUCT_ID 0x0428
+
+#define NOKIA_AT_PORT 0x82
+#define NOKIA_FBUS_PORT 0x86
+
+/*
+ * Version Information
+ */
+#define DRIVER_VERSION "v0.2"
+#define DRIVER_AUTHOR "C Kemp"
+#define DRIVER_DESC "Nokia DKU2 Driver"
+
+static struct usb_device_id id_table [] = {
+ { USB_DEVICE(NOKIA_VENDOR_ID, NOKIA7600_PRODUCT_ID) },
+ { USB_DEVICE(NOKIA_VENDOR_ID, NOKIA6230_PRODUCT_ID) },
+ { USB_DEVICE(NOKIA_VENDOR_ID, NOKIA6170_PRODUCT_ID) },
+ { USB_DEVICE(NOKIA_VENDOR_ID, NOKIA6670_PRODUCT_ID) },
+ { USB_DEVICE(NOKIA_VENDOR_ID, NOKIA6680_PRODUCT_ID) },
+ { USB_DEVICE(NOKIA_VENDOR_ID, NOKIA6230i_PRODUCT_ID) },
+ { } /* Terminating entry */
+};
+MODULE_DEVICE_TABLE(usb, id_table);
+
+/* The only thing which makes this device different from a generic
+ * device is that we have to set an alternative configuration to make
+ * the relevant endpoints available. In 2.6 this is really easy... */
+static int nokia_probe(struct usb_serial *serial,
+ const struct usb_device_id *id)
+{
+ int retval = -ENODEV;
+
+ if (serial->interface->altsetting[0].endpoint[0].desc.bEndpointAddress == NOKIA_AT_PORT) {
+ /* the AT port */
+ dev_info(&serial->dev->dev, "Nokia AT Port:\n");
+ retval = 0;
+ } else if (serial->interface->num_altsetting == 2 &&
+ serial->interface->altsetting[1].endpoint[0].desc.bEndpointAddress == NOKIA_FBUS_PORT) {
+ /* the FBUS port */
+ dev_info(&serial->dev->dev, "Nokia FBUS Port:\n");
+ usb_set_interface(serial->dev, 10, 1);
+ retval = 0;
+ }
+
+ return retval;
+}
+
+static struct usb_driver nokia_driver = {
+ .owner = THIS_MODULE,
+ .name = "nokia_dku2",
+ .probe = usb_serial_probe,
+ .disconnect = usb_serial_disconnect,
+ .id_table = id_table,
+};
+
+static struct usb_serial_driver nokia_serial_driver = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "nokia_dku2",
+ },
+ .description = "Nokia 7600/6230(i)/6170/66x0 DKU2 driver",
+ .id_table = id_table,
+ .num_interrupt_in = 1,
+ .num_bulk_in = 1,
+ .num_bulk_out = 1,
+ .num_ports = 1,
+ .probe = nokia_probe,
+};
+
+static int __init nokia_init(void)
+{
+ int retval;
+
+ retval = usb_serial_register(&nokia_serial_driver);
+ if (retval)
+ return retval;
+
+ retval = usb_register(&nokia_driver);
+ if (retval) {
+ usb_serial_deregister(&nokia_serial_driver);
+ return retval;
+ }
+
+ info(DRIVER_VERSION " " DRIVER_AUTHOR);
+ info(DRIVER_DESC);
+
+ return retval;
+}
+
+static void __exit nokia_exit(void)
+{
+ usb_deregister(&nokia_driver);
+ usb_serial_deregister(&nokia_serial_driver);
+}
+
+module_init(nokia_init);
+module_exit(nokia_exit);
+
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
diff --git a/drivers/usb/serial/omninet.c b/drivers/usb/serial/omninet.c
index 6a99ae192df1..3caf97072ac0 100644
--- a/drivers/usb/serial/omninet.c
+++ b/drivers/usb/serial/omninet.c
@@ -88,10 +88,12 @@ static struct usb_driver omninet_driver = {
};
-static struct usb_serial_device_type zyxel_omninet_device = {
- .owner = THIS_MODULE,
- .name = "ZyXEL - omni.net lcd plus usb",
- .short_name = "omninet",
+static struct usb_serial_driver zyxel_omninet_device = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "omninet",
+ },
+ .description = "ZyXEL - omni.net lcd plus usb",
.id_table = id_table,
.num_interrupt_in = 1,
.num_bulk_in = 1,
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
index 4989e5740d18..7716000045b7 100644
--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -105,10 +105,12 @@ static struct usb_driver option_driver = {
/* The card has three separate interfaces, wich the serial driver
* recognizes separately, thus num_port=1.
*/
-static struct usb_serial_device_type option_3port_device = {
- .owner = THIS_MODULE,
- .name = "Option 3G data card",
- .short_name = "option",
+static struct usb_serial_driver option_3port_device = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "option",
+ },
+ .description = "Option 3G data card",
.id_table = option_ids,
.num_interrupt_in = NUM_DONT_CARE,
.num_bulk_in = NUM_DONT_CARE,
diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c
index 3cf245bdda54..165c119bf10e 100644
--- a/drivers/usb/serial/pl2303.c
+++ b/drivers/usb/serial/pl2303.c
@@ -8,31 +8,10 @@
*
* 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; either version 2 of the License.
*
* See Documentation/usb/usb-serial.txt for more information on using this driver
*
- * 2002_Mar_26 gkh
- * allowed driver to work properly if there is no tty assigned to a port
- * (this happens for serial console devices.)
- *
- * 2001_Oct_06 gkh
- * Added RTS and DTR line control. Thanks to joe@bndlg.de for parts of it.
- *
- * 2001_Sep_19 gkh
- * Added break support.
- *
- * 2001_Aug_30 gkh
- * fixed oops in write_bulk_callback.
- *
- * 2001_Aug_28 gkh
- * reworked buffer logic to be like other usb-serial drivers. Hopefully
- * removing some reported problems.
- *
- * 2001_Jun_06 gkh
- * finished porting to 2.4 format.
- *
*/
#include <linux/config.h>
@@ -55,7 +34,6 @@
/*
* Version Information
*/
-#define DRIVER_VERSION "v0.12"
#define DRIVER_DESC "Prolific PL2303 USB to serial adaptor driver"
static int debug;
@@ -175,9 +153,11 @@ static unsigned int pl2303_buf_get(struct pl2303_buf *pb, char *buf,
/* All of the device info needed for the PL2303 SIO serial converter */
-static struct usb_serial_device_type pl2303_device = {
- .owner = THIS_MODULE,
- .name = "PL-2303",
+static struct usb_serial_driver pl2303_device = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "pl2303",
+ },
.id_table = id_table,
.num_interrupt_in = NUM_DONT_CARE,
.num_bulk_in = 1,
@@ -1195,7 +1175,7 @@ static int __init pl2303_init (void)
retval = usb_register(&pl2303_driver);
if (retval)
goto failed_usb_register;
- info(DRIVER_DESC " " DRIVER_VERSION);
+ info(DRIVER_DESC);
return 0;
failed_usb_register:
usb_serial_deregister(&pl2303_device);
@@ -1215,7 +1195,6 @@ module_init(pl2303_init);
module_exit(pl2303_exit);
MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_VERSION(DRIVER_VERSION);
MODULE_LICENSE("GPL");
module_param(debug, bool, S_IRUGO | S_IWUSR);
diff --git a/drivers/usb/serial/safe_serial.c b/drivers/usb/serial/safe_serial.c
index 96a17568cbf1..c22bdc0c4dfd 100644
--- a/drivers/usb/serial/safe_serial.c
+++ b/drivers/usb/serial/safe_serial.c
@@ -92,7 +92,7 @@ MODULE_DESCRIPTION (DRIVER_DESC);
MODULE_LICENSE("GPL");
#if defined(CONFIG_USBD_SAFE_SERIAL_VENDOR) && !defined(CONFIG_USBD_SAFE_SERIAL_PRODUCT)
-#abort "SAFE_SERIAL_VENDOR defined without SAFE_SERIAL_PRODUCT"
+#error "SAFE_SERIAL_VENDOR defined without SAFE_SERIAL_PRODUCT"
#endif
#if ! defined(CONFIG_USBD_SAFE_SERIAL_VENDOR)
@@ -397,9 +397,11 @@ static int safe_startup (struct usb_serial *serial)
return 0;
}
-static struct usb_serial_device_type safe_device = {
- .owner = THIS_MODULE,
- .name = "Safe",
+static struct usb_serial_driver safe_device = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "safe_serial",
+ },
.id_table = id_table,
.num_interrupt_in = NUM_DONT_CARE,
.num_bulk_in = NUM_DONT_CARE,
diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c
index 59c88de3e7ae..205dbf7201da 100644
--- a/drivers/usb/serial/ti_usb_3410_5052.c
+++ b/drivers/usb/serial/ti_usb_3410_5052.c
@@ -255,9 +255,12 @@ static struct usb_driver ti_usb_driver = {
.id_table = ti_id_table_combined,
};
-static struct usb_serial_device_type ti_1port_device = {
- .owner = THIS_MODULE,
- .name = "TI USB 3410 1 port adapter",
+static struct usb_serial_driver ti_1port_device = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "ti_usb_3410_5052_1",
+ },
+ .description = "TI USB 3410 1 port adapter",
.id_table = ti_id_table_3410,
.num_interrupt_in = 1,
.num_bulk_in = 1,
@@ -282,9 +285,12 @@ static struct usb_serial_device_type ti_1port_device = {
.write_bulk_callback = ti_bulk_out_callback,
};
-static struct usb_serial_device_type ti_2port_device = {
- .owner = THIS_MODULE,
- .name = "TI USB 5052 2 port adapter",
+static struct usb_serial_driver ti_2port_device = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "ti_usb_3410_5052_2",
+ },
+ .description = "TI USB 5052 2 port adapter",
.id_table = ti_id_table_5052,
.num_interrupt_in = 1,
.num_bulk_in = 2,
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c
index e77fbdfc782d..0c4881d18cd5 100644
--- a/drivers/usb/serial/usb-serial.c
+++ b/drivers/usb/serial/usb-serial.c
@@ -1,7 +1,7 @@
/*
* USB Serial Converter driver
*
- * Copyright (C) 1999 - 2004 Greg Kroah-Hartman (greg@kroah.com)
+ * Copyright (C) 1999 - 2005 Greg Kroah-Hartman (greg@kroah.com)
* Copyright (C) 2000 Peter Berger (pberger@brimson.com)
* Copyright (C) 2000 Al Borchers (borchers@steinerpoint.com)
*
@@ -9,316 +9,11 @@
* modify it under the terms of the GNU General Public License version
* 2 as published by the Free Software Foundation.
*
- * This driver was originally based on the ACM driver by Armin Fuerst (which was
+ * This driver was originally based on the ACM driver by Armin Fuerst (which was
* based on a driver by Brad Keryan)
*
* See Documentation/usb/usb-serial.txt for more information on using this driver
*
- * (12/10/2002) gkh
- * Split the ports off into their own struct device, and added a
- * usb-serial bus driver.
- *
- * (11/19/2002) gkh
- * removed a few #ifdefs for the generic code and cleaned up the failure
- * logic in initialization.
- *
- * (10/02/2002) gkh
- * moved the console code to console.c and out of this file.
- *
- * (06/05/2002) gkh
- * moved location of startup() call in serial_probe() until after all
- * of the port information and endpoints are initialized. This makes
- * things easier for some drivers.
- *
- * (04/10/2002) gkh
- * added serial_read_proc function which creates a
- * /proc/tty/driver/usb-serial file.
- *
- * (03/27/2002) gkh
- * Got USB serial console code working properly and merged into the main
- * version of the tree. Thanks to Randy Dunlap for the initial version
- * of this code, and for pushing me to finish it up.
- * The USB serial console works with any usb serial driver device.
- *
- * (03/21/2002) gkh
- * Moved all manipulation of port->open_count into the core. Now the
- * individual driver's open and close functions are called only when the
- * first open() and last close() is called. Making the drivers a bit
- * smaller and simpler.
- * Fixed a bug if a driver didn't have the owner field set.
- *
- * (02/26/2002) gkh
- * Moved all locking into the main serial_* functions, instead of having
- * the individual drivers have to grab the port semaphore. This should
- * reduce races.
- * Reworked the MOD_INC logic a bit to always increment and decrement, even
- * if the generic driver is being used.
- *
- * (10/10/2001) gkh
- * usb_serial_disconnect() now sets the serial->dev pointer is to NULL to
- * help prevent child drivers from accessing the device since it is now
- * gone.
- *
- * (09/13/2001) gkh
- * Moved generic driver initialize after we have registered with the USB
- * core. Thanks to Randy Dunlap for pointing this problem out.
- *
- * (07/03/2001) gkh
- * Fixed module paramater size. Thanks to John Brockmeyer for the pointer.
- * Fixed vendor and product getting defined through the MODULE_PARM macro
- * if the Generic driver wasn't compiled in.
- * Fixed problem with generic_shutdown() not being called for drivers that
- * don't have a shutdown() function.
- *
- * (06/06/2001) gkh
- * added evil hack that is needed for the prolific pl2303 device due to the
- * crazy way its endpoints are set up.
- *
- * (05/30/2001) gkh
- * switched from using spinlock to a semaphore, which fixes lots of problems.
- *
- * (04/08/2001) gb
- * Identify version on module load.
- *
- * 2001_02_05 gkh
- * Fixed buffer overflows bug with the generic serial driver. Thanks to
- * Todd Squires <squirest@ct0.com> for fixing this.
- *
- * (01/10/2001) gkh
- * Fixed bug where the generic serial adaptor grabbed _any_ device that was
- * offered to it.
- *
- * (12/12/2000) gkh
- * Removed MOD_INC and MOD_DEC from poll and disconnect functions, and
- * moved them to the serial_open and serial_close functions.
- * Also fixed bug with there not being a MOD_DEC for the generic driver
- * (thanks to Gary Brubaker for finding this.)
- *
- * (11/29/2000) gkh
- * Small NULL pointer initialization cleanup which saves a bit of disk image
- *
- * (11/01/2000) Adam J. Richter
- * instead of using idVendor/idProduct pairs, usb serial drivers
- * now identify their hardware interest with usb_device_id tables,
- * which they usually have anyhow for use with MODULE_DEVICE_TABLE.
- *
- * (10/05/2000) gkh
- * Fixed bug with urb->dev not being set properly, now that the usb
- * core needs it.
- *
- * (09/11/2000) gkh
- * Removed DEBUG #ifdefs with call to usb_serial_debug_data
- *
- * (08/28/2000) gkh
- * Added port_lock to port structure.
- * Added locks for SMP safeness to generic driver
- * Fixed the ability to open a generic device's port more than once.
- *
- * (07/23/2000) gkh
- * Added bulk_out_endpointAddress to port structure.
- *
- * (07/19/2000) gkh, pberger, and borchers
- * Modifications to allow usb-serial drivers to be modules.
- *
- * (07/03/2000) gkh
- * Added more debugging to serial_ioctl call
- *
- * (06/25/2000) gkh
- * Changed generic_write_bulk_callback to not call wake_up_interruptible
- * directly, but to have port_softint do it at a safer time.
- *
- * (06/23/2000) gkh
- * Cleaned up debugging statements in a quest to find UHCI timeout bug.
- *
- * (05/22/2000) gkh
- * Changed the makefile, enabling the big CONFIG_USB_SERIAL_SOMTHING to be
- * removed from the individual device source files.
- *
- * (05/03/2000) gkh
- * Added the Digi Acceleport driver from Al Borchers and Peter Berger.
- *
- * (05/02/2000) gkh
- * Changed devfs and tty register code to work properly now. This was based on
- * the ACM driver changes by Vojtech Pavlik.
- *
- * (04/27/2000) Ryan VanderBijl
- * Put calls to *_paranoia_checks into one function.
- *
- * (04/23/2000) gkh
- * Fixed bug that Randy Dunlap found for Generic devices with no bulk out ports.
- * Moved when the startup code printed out the devices that are supported.
- *
- * (04/19/2000) gkh
- * Added driver for ZyXEL omni.net lcd plus ISDN TA
- * Made startup info message specify which drivers were compiled in.
- *
- * (04/03/2000) gkh
- * Changed the probe process to remove the module unload races.
- * Changed where the tty layer gets initialized to have devfs work nicer.
- * Added initial devfs support.
- *
- * (03/26/2000) gkh
- * Split driver up into device specific pieces.
- *
- * (03/19/2000) gkh
- * Fixed oops that could happen when device was removed while a program
- * was talking to the device.
- * Removed the static urbs and now all urbs are created and destroyed
- * dynamically.
- * Reworked the internal interface. Now everything is based on the
- * usb_serial_port structure instead of the larger usb_serial structure.
- * This fixes the bug that a multiport device could not have more than
- * one port open at one time.
- *
- * (03/17/2000) gkh
- * Added config option for debugging messages.
- * Added patch for keyspan pda from Brian Warner.
- *
- * (03/06/2000) gkh
- * Added the keyspan pda code from Brian Warner <warner@lothar.com>
- * Moved a bunch of the port specific stuff into its own structure. This
- * is in anticipation of the true multiport devices (there's a bug if you
- * try to access more than one port of any multiport device right now)
- *
- * (02/21/2000) gkh
- * Made it so that any serial devices only have to specify which functions
- * they want to overload from the generic function calls (great,
- * inheritance in C, in a driver, just what I wanted...)
- * Added support for set_termios and ioctl function calls. No drivers take
- * advantage of this yet.
- * Removed the #ifdef MODULE, now there is no module specific code.
- * Cleaned up a few comments in usb-serial.h that were wrong (thanks again
- * to Miles Lott).
- * Small fix to get_free_serial.
- *
- * (02/14/2000) gkh
- * Removed the Belkin and Peracom functionality from the driver due to
- * the lack of support from the vendor, and me not wanting people to
- * accidenatly buy the device, expecting it to work with Linux.
- * Added read_bulk_callback and write_bulk_callback to the type structure
- * for the needs of the FTDI and WhiteHEAT driver.
- * Changed all reverences to FTDI to FTDI_SIO at the request of Bill
- * Ryder.
- * Changed the output urb size back to the max endpoint size to make
- * the ftdi_sio driver have it easier, and due to the fact that it didn't
- * really increase the speed any.
- *
- * (02/11/2000) gkh
- * Added VISOR_FUNCTION_CONSOLE to the visor startup function. This was a
- * patch from Miles Lott (milos@insync.net).
- * Fixed bug with not restoring the minor range that a device grabs, if
- * the startup function fails (thanks Miles for finding this).
- *
- * (02/05/2000) gkh
- * Added initial framework for the Keyspan PDA serial converter so that
- * Brian Warner has a place to put his code.
- * Made the ezusb specific functions generic enough that different
- * devices can use them (whiteheat and keyspan_pda both need them).
- * Split out a whole bunch of structure and other stuff to a separate
- * usb-serial.h file.
- * Made the Visor connection messages a little more understandable, now
- * that Miles Lott (milos@insync.net) has gotten the Generic channel to
- * work. Also made them always show up in the log file.
- *
- * (01/25/2000) gkh
- * Added initial framework for FTDI serial converter so that Bill Ryder
- * has a place to put his code.
- * Added the vendor specific info from Handspring. Now we can print out
- * informational debug messages as well as understand what is happening.
- *
- * (01/23/2000) gkh
- * Fixed problem of crash when trying to open a port that didn't have a
- * device assigned to it. Made the minor node finding a little smarter,
- * now it looks to find a continuous space for the new device.
- *
- * (01/21/2000) gkh
- * Fixed bug in visor_startup with patch from Miles Lott (milos@insync.net)
- * Fixed get_serial_by_minor which was all messed up for multi port
- * devices. Fixed multi port problem for generic devices. Now the number
- * of ports is determined by the number of bulk out endpoints for the
- * generic device.
- *
- * (01/19/2000) gkh
- * Removed lots of cruft that was around from the old (pre urb) driver
- * interface.
- * Made the serial_table dynamic. This should save lots of memory when
- * the number of minor nodes goes up to 256.
- * Added initial support for devices that have more than one port.
- * Added more debugging comments for the Visor, and added a needed
- * set_configuration call.
- *
- * (01/17/2000) gkh
- * Fixed the WhiteHEAT firmware (my processing tool had a bug)
- * and added new debug loader firmware for it.
- * Removed the put_char function as it isn't really needed.
- * Added visor startup commands as found by the Win98 dump.
- *
- * (01/13/2000) gkh
- * Fixed the vendor id for the generic driver to the one I meant it to be.
- *
- * (01/12/2000) gkh
- * Forget the version numbering...that's pretty useless...
- * Made the driver able to be compiled so that the user can select which
- * converter they want to use. This allows people who only want the Visor
- * support to not pay the memory size price of the WhiteHEAT.
- * Fixed bug where the generic driver (idVendor=0000 and idProduct=0000)
- * grabbed the root hub. Not good.
- *
- * version 0.4.0 (01/10/2000) gkh
- * Added whiteheat.h containing the firmware for the ConnectTech WhiteHEAT
- * device. Added startup function to allow firmware to be downloaded to
- * a device if it needs to be.
- * Added firmware download logic to the WhiteHEAT device.
- * Started to add #defines to split up the different drivers for potential
- * configuration option.
- *
- * version 0.3.1 (12/30/99) gkh
- * Fixed problems with urb for bulk out.
- * Added initial support for multiple sets of endpoints. This enables
- * the Handspring Visor to be attached successfully. Only the first
- * bulk in / bulk out endpoint pair is being used right now.
- *
- * version 0.3.0 (12/27/99) gkh
- * Added initial support for the Handspring Visor based on a patch from
- * Miles Lott (milos@sneety.insync.net)
- * Cleaned up the code a bunch and converted over to using urbs only.
- *
- * version 0.2.3 (12/21/99) gkh
- * Added initial support for the Connect Tech WhiteHEAT converter.
- * Incremented the number of ports in expectation of getting the
- * WhiteHEAT to work properly (4 ports per connection).
- * Added notification on insertion and removal of what port the
- * device is/was connected to (and what kind of device it was).
- *
- * version 0.2.2 (12/16/99) gkh
- * Changed major number to the new allocated number. We're legal now!
- *
- * version 0.2.1 (12/14/99) gkh
- * Fixed bug that happens when device node is opened when there isn't a
- * device attached to it. Thanks to marek@webdesign.no for noticing this.
- *
- * version 0.2.0 (11/10/99) gkh
- * Split up internals to make it easier to add different types of serial
- * converters to the code.
- * Added a "generic" driver that gets it's vendor and product id
- * from when the module is loaded. Thanks to David E. Nelson (dnelson@jump.net)
- * for the idea and sample code (from the usb scanner driver.)
- * Cleared up any licensing questions by releasing it under the GNU GPL.
- *
- * version 0.1.2 (10/25/99) gkh
- * Fixed bug in detecting device.
- *
- * version 0.1.1 (10/05/99) gkh
- * Changed the major number to not conflict with anything else.
- *
- * version 0.1 (09/28/99) gkh
- * Can recognize the two different devices and start up a read from
- * device when asked to. Writes also work. No control signals yet, this
- * all is vendor specific data (i.e. no spec), also no control for
- * different baud rates or other bit settings.
- * Currently we are using the same devid as the acm driver. This needs
- * to change.
- *
*/
#include <linux/config.h>
@@ -342,7 +37,6 @@
/*
* Version Information
*/
-#define DRIVER_VERSION "v2.0"
#define DRIVER_AUTHOR "Greg Kroah-Hartman, greg@kroah.com, http://www.kroah.com/linux/"
#define DRIVER_DESC "USB Serial Driver core"
@@ -427,7 +121,7 @@ static void destroy_serial(struct kref *kref)
serial = to_usb_serial(kref);
- dbg ("%s - %s", __FUNCTION__, serial->type->name);
+ dbg("%s - %s", __FUNCTION__, serial->type->description);
serial->type->shutdown(serial);
@@ -507,7 +201,7 @@ static int serial_open (struct tty_struct *tty, struct file * filp)
/* lock this module before we call it
* this may fail, which means we must bail out,
* safe because we are called with BKL held */
- if (!try_module_get(serial->type->owner)) {
+ if (!try_module_get(serial->type->driver.owner)) {
retval = -ENODEV;
goto bailout_kref_put;
}
@@ -522,7 +216,7 @@ static int serial_open (struct tty_struct *tty, struct file * filp)
return 0;
bailout_module_put:
- module_put(serial->type->owner);
+ module_put(serial->type->driver.owner);
bailout_kref_put:
kref_put(&serial->kref, destroy_serial);
port->open_count = 0;
@@ -553,7 +247,7 @@ static void serial_close(struct tty_struct *tty, struct file * filp)
port->tty = NULL;
}
- module_put(port->serial->type->owner);
+ module_put(port->serial->type->driver.owner);
}
kref_put(&port->serial->kref, destroy_serial);
@@ -711,16 +405,16 @@ static int serial_read_proc (char *page, char **start, off_t off, int count, int
char tmp[40];
dbg("%s", __FUNCTION__);
- length += sprintf (page, "usbserinfo:1.0 driver:%s\n", DRIVER_VERSION);
+ length += sprintf (page, "usbserinfo:1.0 driver:2.0\n");
for (i = 0; i < SERIAL_TTY_MINORS && length < PAGE_SIZE; ++i) {
serial = usb_serial_get_by_index(i);
if (serial == NULL)
continue;
length += sprintf (page+length, "%d:", i);
- if (serial->type->owner)
- length += sprintf (page+length, " module:%s", module_name(serial->type->owner));
- length += sprintf (page+length, " name:\"%s\"", serial->type->name);
+ if (serial->type->driver.owner)
+ length += sprintf (page+length, " module:%s", module_name(serial->type->driver.owner));
+ length += sprintf (page+length, " name:\"%s\"", serial->type->description);
length += sprintf (page+length, " vendor:%04x product:%04x",
le16_to_cpu(serial->dev->descriptor.idVendor),
le16_to_cpu(serial->dev->descriptor.idProduct));
@@ -823,7 +517,7 @@ static void port_release(struct device *dev)
static struct usb_serial * create_serial (struct usb_device *dev,
struct usb_interface *interface,
- struct usb_serial_device_type *type)
+ struct usb_serial_driver *driver)
{
struct usb_serial *serial;
@@ -834,22 +528,22 @@ static struct usb_serial * create_serial (struct usb_device *dev,
}
memset (serial, 0, sizeof(*serial));
serial->dev = usb_get_dev(dev);
- serial->type = type;
+ serial->type = driver;
serial->interface = interface;
kref_init(&serial->kref);
return serial;
}
-static struct usb_serial_device_type *search_serial_device(struct usb_interface *iface)
+static struct usb_serial_driver *search_serial_device(struct usb_interface *iface)
{
struct list_head *p;
const struct usb_device_id *id;
- struct usb_serial_device_type *t;
+ struct usb_serial_driver *t;
/* List trough know devices and see if the usb id matches */
list_for_each(p, &usb_serial_driver_list) {
- t = list_entry(p, struct usb_serial_device_type, driver_list);
+ t = list_entry(p, struct usb_serial_driver, driver_list);
id = usb_match_id(iface, t->id_table);
if (id != NULL) {
dbg("descriptor matches");
@@ -872,7 +566,7 @@ int usb_serial_probe(struct usb_interface *interface,
struct usb_endpoint_descriptor *interrupt_out_endpoint[MAX_NUM_PORTS];
struct usb_endpoint_descriptor *bulk_in_endpoint[MAX_NUM_PORTS];
struct usb_endpoint_descriptor *bulk_out_endpoint[MAX_NUM_PORTS];
- struct usb_serial_device_type *type = NULL;
+ struct usb_serial_driver *type = NULL;
int retval;
int minor;
int buffer_size;
@@ -900,7 +594,7 @@ int usb_serial_probe(struct usb_interface *interface,
if (type->probe) {
const struct usb_device_id *id;
- if (!try_module_get(type->owner)) {
+ if (!try_module_get(type->driver.owner)) {
dev_err(&interface->dev, "module get failed, exiting\n");
kfree (serial);
return -EIO;
@@ -908,7 +602,7 @@ int usb_serial_probe(struct usb_interface *interface,
id = usb_match_id(interface, type->id_table);
retval = type->probe(serial, id);
- module_put(type->owner);
+ module_put(type->driver.owner);
if (retval) {
dbg ("sub driver rejected device");
@@ -992,7 +686,7 @@ int usb_serial_probe(struct usb_interface *interface,
#endif
/* found all that we need */
- dev_info(&interface->dev, "%s converter detected\n", type->name);
+ dev_info(&interface->dev, "%s converter detected\n", type->description);
#ifdef CONFIG_USB_SERIAL_GENERIC
if (type == &usb_serial_generic_device) {
@@ -1007,13 +701,13 @@ int usb_serial_probe(struct usb_interface *interface,
if (!num_ports) {
/* if this device type has a calc_num_ports function, call it */
if (type->calc_num_ports) {
- if (!try_module_get(type->owner)) {
+ if (!try_module_get(type->driver.owner)) {
dev_err(&interface->dev, "module get failed, exiting\n");
kfree (serial);
return -EIO;
}
num_ports = type->calc_num_ports (serial);
- module_put(type->owner);
+ module_put(type->driver.owner);
}
if (!num_ports)
num_ports = type->num_ports;
@@ -1158,12 +852,12 @@ int usb_serial_probe(struct usb_interface *interface,
/* if this device type has an attach function, call it */
if (type->attach) {
- if (!try_module_get(type->owner)) {
+ if (!try_module_get(type->driver.owner)) {
dev_err(&interface->dev, "module get failed, exiting\n");
goto probe_error;
}
retval = type->attach (serial);
- module_put(type->owner);
+ module_put(type->driver.owner);
if (retval < 0)
goto probe_error;
if (retval > 0) {
@@ -1330,7 +1024,7 @@ static int __init usb_serial_init(void)
goto exit_generic;
}
- info(DRIVER_DESC " " DRIVER_VERSION);
+ info(DRIVER_DESC);
return result;
@@ -1375,7 +1069,7 @@ module_exit(usb_serial_exit);
} \
} while (0)
-static void fixup_generic(struct usb_serial_device_type *device)
+static void fixup_generic(struct usb_serial_driver *device)
{
set_to_generic_if_null(device, open);
set_to_generic_if_null(device, write);
@@ -1387,30 +1081,33 @@ static void fixup_generic(struct usb_serial_device_type *device)
set_to_generic_if_null(device, shutdown);
}
-int usb_serial_register(struct usb_serial_device_type *new_device)
+int usb_serial_register(struct usb_serial_driver *driver)
{
int retval;
- fixup_generic(new_device);
+ fixup_generic(driver);
+
+ if (!driver->description)
+ driver->description = driver->driver.name;
/* Add this device to our list of devices */
- list_add(&new_device->driver_list, &usb_serial_driver_list);
+ list_add(&driver->driver_list, &usb_serial_driver_list);
- retval = usb_serial_bus_register(new_device);
+ retval = usb_serial_bus_register(driver);
if (retval) {
- err("problem %d when registering driver %s", retval, new_device->name);
- list_del(&new_device->driver_list);
+ err("problem %d when registering driver %s", retval, driver->description);
+ list_del(&driver->driver_list);
}
else
- info("USB Serial support registered for %s", new_device->name);
+ info("USB Serial support registered for %s", driver->description);
return retval;
}
-void usb_serial_deregister(struct usb_serial_device_type *device)
+void usb_serial_deregister(struct usb_serial_driver *device)
{
- info("USB Serial deregistering driver %s", device->name);
+ info("USB Serial deregistering driver %s", device->description);
list_del(&device->driver_list);
usb_serial_bus_deregister(device);
}
@@ -1429,7 +1126,6 @@ EXPORT_SYMBOL_GPL(usb_serial_port_softint);
/* Module information */
MODULE_AUTHOR( DRIVER_AUTHOR );
MODULE_DESCRIPTION( DRIVER_DESC );
-MODULE_VERSION( DRIVER_VERSION );
MODULE_LICENSE("GPL");
module_param(debug, bool, S_IRUGO | S_IWUSR);
diff --git a/drivers/usb/serial/usb-serial.h b/drivers/usb/serial/usb-serial.h
index 57f92f054c75..238a5a871ed6 100644
--- a/drivers/usb/serial/usb-serial.h
+++ b/drivers/usb/serial/usb-serial.h
@@ -1,53 +1,13 @@
/*
* USB Serial Converter driver
*
- * Copyright (C) 1999 - 2004
+ * Copyright (C) 1999 - 2005
* Greg Kroah-Hartman (greg@kroah.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.
+ * the Free Software Foundation; either version 2 of the License.
*
- * See Documentation/usb/usb-serial.txt for more information on using this driver
- *
- * (03/26/2002) gkh
- * removed the port->tty check from port_paranoia_check() due to serial
- * consoles not having a tty device assigned to them.
- *
- * (12/03/2001) gkh
- * removed active from the port structure.
- * added documentation to the usb_serial_device_type structure
- *
- * (10/10/2001) gkh
- * added vendor and product to serial structure. Needed to determine device
- * owner when the device is disconnected.
- *
- * (05/30/2001) gkh
- * added sem to port structure and removed port_lock
- *
- * (10/05/2000) gkh
- * Added interrupt_in_endpointAddress and bulk_in_endpointAddress to help
- * fix bug with urb->dev not being set properly, now that the usb core
- * needs it.
- *
- * (09/11/2000) gkh
- * Added usb_serial_debug_data function to help get rid of #DEBUG in the
- * drivers.
- *
- * (08/28/2000) gkh
- * Added port_lock to port structure.
- *
- * (08/08/2000) gkh
- * Added open_count to port structure.
- *
- * (07/23/2000) gkh
- * Added bulk_out_endpointAddress to port structure.
- *
- * (07/19/2000) gkh, pberger, and borchers
- * Modifications to allow usb-serial drivers to be modules.
- *
- *
*/
@@ -143,7 +103,7 @@ static inline void usb_set_serial_port_data (struct usb_serial_port *port, void
/**
* usb_serial - structure used by the usb-serial core for a device
* @dev: pointer to the struct usb_device for this device
- * @type: pointer to the struct usb_serial_device_type for this device
+ * @type: pointer to the struct usb_serial_driver for this device
* @interface: pointer to the struct usb_interface for this device
* @minor: the starting minor number for this device
* @num_ports: the number of ports this device has
@@ -159,7 +119,7 @@ static inline void usb_set_serial_port_data (struct usb_serial_port *port, void
*/
struct usb_serial {
struct usb_device * dev;
- struct usb_serial_device_type * type;
+ struct usb_serial_driver * type;
struct usb_interface * interface;
unsigned char minor;
unsigned char num_ports;
@@ -188,13 +148,9 @@ static inline void usb_set_serial_data (struct usb_serial *serial, void *data)
}
/**
- * usb_serial_device_type - a structure that defines a usb serial device
- * @owner: pointer to the module that owns this device.
- * @name: pointer to a string that describes this device. This string used
+ * usb_serial_driver - describes a usb serial driver
+ * @description: pointer to a string that describes this driver. This string used
* in the syslog messages when a device is inserted or removed.
- * @short_name: a pointer to a string that describes this device in
- * KOBJ_NAME_LEN characters or less. This is used for the sysfs interface
- * to describe the driver.
* @id_table: pointer to a list of usb_device_id structures that define all
* of the devices this structure can support.
* @num_interrupt_in: the number of interrupt in endpoints this device will
@@ -221,16 +177,19 @@ static inline void usb_set_serial_data (struct usb_serial *serial, void *data)
* @shutdown: pointer to the driver's shutdown function. This will be
* called when the device is removed from the system.
*
- * This structure is defines a USB Serial device. It provides all of
+ * This structure is defines a USB Serial driver. It provides all of
* the information that the USB serial core code needs. If the function
* pointers are defined, then the USB serial core code will call them when
* the corresponding tty port functions are called. If they are not
* called, the generic serial function will be used instead.
+ *
+ * The driver.owner field should be set to the module owner of this driver.
+ * The driver.name field should be set to the name of this driver (remember
+ * it will show up in sysfs, so it needs to be short and to the point.
+ * Useing the module name is a good idea.)
*/
-struct usb_serial_device_type {
- struct module *owner;
- char *name;
- char *short_name;
+struct usb_serial_driver {
+ const char *description;
const struct usb_device_id *id_table;
char num_interrupt_in;
char num_interrupt_out;
@@ -269,10 +228,10 @@ struct usb_serial_device_type {
void (*read_bulk_callback)(struct urb *urb, struct pt_regs *regs);
void (*write_bulk_callback)(struct urb *urb, struct pt_regs *regs);
};
-#define to_usb_serial_driver(d) container_of(d, struct usb_serial_device_type, driver)
+#define to_usb_serial_driver(d) container_of(d, struct usb_serial_driver, driver)
-extern int usb_serial_register(struct usb_serial_device_type *new_device);
-extern void usb_serial_deregister(struct usb_serial_device_type *device);
+extern int usb_serial_register(struct usb_serial_driver *driver);
+extern void usb_serial_deregister(struct usb_serial_driver *driver);
extern void usb_serial_port_softint(void *private);
extern int usb_serial_probe(struct usb_interface *iface, const struct usb_device_id *id);
@@ -303,10 +262,10 @@ extern void usb_serial_generic_shutdown (struct usb_serial *serial);
extern int usb_serial_generic_register (int debug);
extern void usb_serial_generic_deregister (void);
-extern int usb_serial_bus_register (struct usb_serial_device_type *device);
-extern void usb_serial_bus_deregister (struct usb_serial_device_type *device);
+extern int usb_serial_bus_register (struct usb_serial_driver *device);
+extern void usb_serial_bus_deregister (struct usb_serial_driver *device);
-extern struct usb_serial_device_type usb_serial_generic_device;
+extern struct usb_serial_driver usb_serial_generic_device;
extern struct bus_type usb_serial_bus_type;
extern struct tty_driver *usb_serial_tty_driver;
diff --git a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c
index 31c57adcb623..a473c1c34559 100644
--- a/drivers/usb/serial/visor.c
+++ b/drivers/usb/serial/visor.c
@@ -7,139 +7,10 @@
*
* 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; either version 2 of the License.
*
* See Documentation/usb/usb-serial.txt for more information on using this driver
*
- * (06/03/2003) Judd Montgomery <judd at jpilot.org>
- * Added support for module parameter options for untested/unknown
- * devices.
- *
- * (03/09/2003) gkh
- * Added support for the Sony Clie NZ90V device. Thanks to Martin Brachtl
- * <brachtl@redgrep.cz> for the information.
- *
- * (03/05/2003) gkh
- * Think Treo support is now working.
- *
- * (04/03/2002) gkh
- * Added support for the Sony OS 4.1 devices. Thanks to Hiroyuki ARAKI
- * <hiro@zob.ne.jp> for the information.
- *
- * (03/27/2002) gkh
- * Removed assumptions that port->tty was always valid (is not true
- * for usb serial console devices.)
- *
- * (03/23/2002) gkh
- * Added support for the Palm i705 device, thanks to Thomas Riemer
- * <tom@netmech.com> for the information.
- *
- * (03/21/2002) gkh
- * Added support for the Palm m130 device, thanks to Udo Eisenbarth
- * <udo.eisenbarth@web.de> for the information.
- *
- * (02/27/2002) gkh
- * Reworked the urb handling logic. We have no more pool, but dynamically
- * allocate the urb and the transfer buffer on the fly. In testing this
- * does not incure any measurable overhead. This also relies on the fact
- * that we have proper reference counting logic for urbs.
- *
- * (02/21/2002) SilaS
- * Added initial support for the Palm m515 devices.
- *
- * (02/14/2002) gkh
- * Added support for the Clie S-360 device.
- *
- * (12/18/2001) gkh
- * Added better Clie support for 3.5 devices. Thanks to Geoffrey Levand
- * for the patch.
- *
- * (11/11/2001) gkh
- * Added support for the m125 devices, and added check to prevent oopses
- * for Clié devices that lie about the number of ports they have.
- *
- * (08/30/2001) gkh
- * Added support for the Clie devices, both the 3.5 and 4.0 os versions.
- * Many thanks to Daniel Burke, and Bryan Payne for helping with this.
- *
- * (08/23/2001) gkh
- * fixed a few potential bugs pointed out by Oliver Neukum.
- *
- * (05/30/2001) gkh
- * switched from using spinlock to a semaphore, which fixes lots of problems.
- *
- * (05/28/2000) gkh
- * Added initial support for the Palm m500 and Palm m505 devices.
- *
- * (04/08/2001) gb
- * Identify version on module load.
- *
- * (01/21/2000) gkh
- * Added write_room and chars_in_buffer, as they were previously using the
- * generic driver versions which is all wrong now that we are using an urb
- * pool. Thanks to Wolfgang Grandegger for pointing this out to me.
- * Removed count assignment in the write function, which was not needed anymore
- * either. Thanks to Al Borchers for pointing this out.
- *
- * (12/12/2000) gkh
- * Moved MOD_DEC to end of visor_close to be nicer, as the final write
- * message can sleep.
- *
- * (11/12/2000) gkh
- * Fixed bug with data being dropped on the floor by forcing tty->low_latency
- * to be on. Hopefully this fixes the OHCI issue!
- *
- * (11/01/2000) Adam J. Richter
- * usb_device_id table support
- *
- * (10/05/2000) gkh
- * Fixed bug with urb->dev not being set properly, now that the usb
- * core needs it.
- *
- * (09/11/2000) gkh
- * Got rid of always calling kmalloc for every urb we wrote out to the
- * device.
- * Added visor_read_callback so we can keep track of bytes in and out for
- * those people who like to know the speed of their device.
- * Removed DEBUG #ifdefs with call to usb_serial_debug_data
- *
- * (09/06/2000) gkh
- * Fixed oops in visor_exit. Need to uncomment usb_unlink_urb call _after_
- * the host controller drivers set urb->dev = NULL when the urb is finished.
- *
- * (08/28/2000) gkh
- * Added locks for SMP safeness.
- *
- * (08/08/2000) gkh
- * Fixed endian problem in visor_startup.
- * Fixed MOD_INC and MOD_DEC logic and the ability to open a port more
- * than once.
- *
- * (07/23/2000) gkh
- * Added pool of write urbs to speed up transfers to the visor.
- *
- * (07/19/2000) gkh
- * Added module_init and module_exit functions to handle the fact that this
- * driver is a loadable module now.
- *
- * (07/03/2000) gkh
- * Added visor_set_ioctl and visor_set_termios functions (they don't do much
- * of anything, but are good for debugging.)
- *
- * (06/25/2000) gkh
- * Fixed bug in visor_unthrottle that should help with the disconnect in PPP
- * bug that people have been reporting.
- *
- * (06/23/2000) gkh
- * Cleaned up debugging statements in a quest to find UHCI timeout bug.
- *
- * (04/27/2000) Ryan VanderBijl
- * Fixed memory leak in visor_close
- *
- * (03/26/2000) gkh
- * Split driver up into device specific pieces.
- *
*/
#include <linux/config.h>
@@ -161,7 +32,6 @@
/*
* Version Information
*/
-#define DRIVER_VERSION "v2.1"
#define DRIVER_AUTHOR "Greg Kroah-Hartman <greg@kroah.com>"
#define DRIVER_DESC "USB HandSpring Visor / Palm OS driver"
@@ -311,10 +181,12 @@ static struct usb_driver visor_driver = {
};
/* All of the device info needed for the Handspring Visor, and Palm 4.0 devices */
-static struct usb_serial_device_type handspring_device = {
- .owner = THIS_MODULE,
- .name = "Handspring Visor / Palm OS",
- .short_name = "visor",
+static struct usb_serial_driver handspring_device = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "visor",
+ },
+ .description = "Handspring Visor / Palm OS",
.id_table = id_table,
.num_interrupt_in = NUM_DONT_CARE,
.num_bulk_in = 2,
@@ -339,10 +211,12 @@ static struct usb_serial_device_type handspring_device = {
};
/* All of the device info needed for the Clie UX50, TH55 Palm 5.0 devices */
-static struct usb_serial_device_type clie_5_device = {
- .owner = THIS_MODULE,
- .name = "Sony Clie 5.0",
- .short_name = "clie_5",
+static struct usb_serial_driver clie_5_device = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "clie_5",
+ },
+ .description = "Sony Clie 5.0",
.id_table = clie_id_5_table,
.num_interrupt_in = NUM_DONT_CARE,
.num_bulk_in = 2,
@@ -367,10 +241,12 @@ static struct usb_serial_device_type clie_5_device = {
};
/* device info for the Sony Clie OS version 3.5 */
-static struct usb_serial_device_type clie_3_5_device = {
- .owner = THIS_MODULE,
- .name = "Sony Clie 3.5",
- .short_name = "clie_3.5",
+static struct usb_serial_driver clie_3_5_device = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "clie_3.5",
+ },
+ .description = "Sony Clie 3.5",
.id_table = clie_id_3_5_table,
.num_interrupt_in = 0,
.num_bulk_in = 1,
@@ -782,7 +658,7 @@ static int palm_os_3_probe (struct usb_serial *serial, const struct usb_device_i
break;
}
dev_info(dev, "%s: port %d, is for %s use\n",
- serial->type->name,
+ serial->type->description,
connection_info->connections[i].port, string);
}
}
@@ -791,11 +667,11 @@ static int palm_os_3_probe (struct usb_serial *serial, const struct usb_device_i
*/
if (num_ports == 0 || num_ports > 2) {
dev_warn (dev, "%s: No valid connect info available\n",
- serial->type->name);
+ serial->type->description);
num_ports = 2;
}
- dev_info(dev, "%s: Number of ports: %d\n", serial->type->name,
+ dev_info(dev, "%s: Number of ports: %d\n", serial->type->description,
num_ports);
/*
@@ -1125,7 +1001,7 @@ static int __init visor_init (void)
retval = usb_register(&visor_driver);
if (retval)
goto failed_usb_register;
- info(DRIVER_DESC " " DRIVER_VERSION);
+ info(DRIVER_DESC);
return 0;
failed_usb_register:
diff --git a/drivers/usb/serial/whiteheat.c b/drivers/usb/serial/whiteheat.c
index cf3bc30675a1..18c3183be769 100644
--- a/drivers/usb/serial/whiteheat.c
+++ b/drivers/usb/serial/whiteheat.c
@@ -156,10 +156,12 @@ static void whiteheat_unthrottle (struct usb_serial_port *port);
static void whiteheat_read_callback (struct urb *urb, struct pt_regs *regs);
static void whiteheat_write_callback (struct urb *urb, struct pt_regs *regs);
-static struct usb_serial_device_type whiteheat_fake_device = {
- .owner = THIS_MODULE,
- .name = "Connect Tech - WhiteHEAT - (prerenumeration)",
- .short_name = "whiteheatnofirm",
+static struct usb_serial_driver whiteheat_fake_device = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "whiteheatnofirm",
+ },
+ .description = "Connect Tech - WhiteHEAT - (prerenumeration)",
.id_table = id_table_prerenumeration,
.num_interrupt_in = NUM_DONT_CARE,
.num_bulk_in = NUM_DONT_CARE,
@@ -169,10 +171,12 @@ static struct usb_serial_device_type whiteheat_fake_device = {
.attach = whiteheat_firmware_attach,
};
-static struct usb_serial_device_type whiteheat_device = {
- .owner = THIS_MODULE,
- .name = "Connect Tech - WhiteHEAT",
- .short_name = "whiteheat",
+static struct usb_serial_driver whiteheat_device = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "whiteheat",
+ },
+ .description = "Connect Tech - WhiteHEAT",
.id_table = id_table_std,
.num_interrupt_in = NUM_DONT_CARE,
.num_bulk_in = NUM_DONT_CARE,
@@ -382,10 +386,10 @@ static int whiteheat_attach (struct usb_serial *serial)
usb_clear_halt(serial->dev, pipe);
ret = usb_bulk_msg (serial->dev, pipe, command, 2, &alen, COMMAND_TIMEOUT_MS);
if (ret) {
- err("%s: Couldn't send command [%d]", serial->type->name, ret);
+ err("%s: Couldn't send command [%d]", serial->type->description, ret);
goto no_firmware;
} else if (alen != sizeof(command)) {
- err("%s: Send command incomplete [%d]", serial->type->name, alen);
+ err("%s: Send command incomplete [%d]", serial->type->description, alen);
goto no_firmware;
}
@@ -394,19 +398,19 @@ static int whiteheat_attach (struct usb_serial *serial)
usb_clear_halt(serial->dev, pipe);
ret = usb_bulk_msg (serial->dev, pipe, result, sizeof(*hw_info) + 1, &alen, COMMAND_TIMEOUT_MS);
if (ret) {
- err("%s: Couldn't get results [%d]", serial->type->name, ret);
+ err("%s: Couldn't get results [%d]", serial->type->description, ret);
goto no_firmware;
} else if (alen != sizeof(result)) {
- err("%s: Get results incomplete [%d]", serial->type->name, alen);
+ err("%s: Get results incomplete [%d]", serial->type->description, alen);
goto no_firmware;
} else if (result[0] != command[0]) {
- err("%s: Command failed [%d]", serial->type->name, result[0]);
+ err("%s: Command failed [%d]", serial->type->description, result[0]);
goto no_firmware;
}
hw_info = (struct whiteheat_hw_info *)&result[1];
- info("%s: Driver %s: Firmware v%d.%02d", serial->type->name,
+ info("%s: Driver %s: Firmware v%d.%02d", serial->type->description,
DRIVER_VERSION, hw_info->sw_major_rev, hw_info->sw_minor_rev);
for (i = 0; i < serial->num_ports; i++) {
@@ -414,7 +418,7 @@ static int whiteheat_attach (struct usb_serial *serial)
info = (struct whiteheat_private *)kmalloc(sizeof(struct whiteheat_private), GFP_KERNEL);
if (info == NULL) {
- err("%s: Out of memory for port structures\n", serial->type->name);
+ err("%s: Out of memory for port structures\n", serial->type->description);
goto no_private;
}
@@ -484,7 +488,7 @@ static int whiteheat_attach (struct usb_serial *serial)
command_info = (struct whiteheat_command_private *)kmalloc(sizeof(struct whiteheat_command_private), GFP_KERNEL);
if (command_info == NULL) {
- err("%s: Out of memory for port structures\n", serial->type->name);
+ err("%s: Out of memory for port structures\n", serial->type->description);
goto no_command_private;
}
@@ -501,9 +505,9 @@ static int whiteheat_attach (struct usb_serial *serial)
no_firmware:
/* Firmware likely not running */
- err("%s: Unable to retrieve firmware version, try replugging\n", serial->type->name);
- err("%s: If the firmware is not running (status led not blinking)\n", serial->type->name);
- err("%s: please contact support@connecttech.com\n", serial->type->name);
+ err("%s: Unable to retrieve firmware version, try replugging\n", serial->type->description);
+ err("%s: If the firmware is not running (status led not blinking)\n", serial->type->description);
+ err("%s: please contact support@connecttech.com\n", serial->type->description);
return -ENODEV;
no_command_private:
diff --git a/drivers/usb/storage/Kconfig b/drivers/usb/storage/Kconfig
index bb9819cc8826..1a9679f76f5a 100644
--- a/drivers/usb/storage/Kconfig
+++ b/drivers/usb/storage/Kconfig
@@ -2,7 +2,8 @@
# USB Storage driver configuration
#
-comment "NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information"
+comment "NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'"
+comment "may also be needed; see USB_STORAGE Help for more information"
depends on USB
config USB_STORAGE
diff --git a/drivers/usb/storage/onetouch.c b/drivers/usb/storage/onetouch.c
index 2c9402dc702b..89401a59f952 100644
--- a/drivers/usb/storage/onetouch.c
+++ b/drivers/usb/storage/onetouch.c
@@ -5,7 +5,7 @@
* Copyright (c) 2005 Nick Sillik <n.sillik@temple.edu>
*
* Initial work by:
- * Copyright (c) 2003 Erik Thyren <erth7411@student.uu.se>
+ * Copyright (c) 2003 Erik Thyren <erth7411@student.uu.se>
*
* Based on usbmouse.c (Vojtech Pavlik) and xpad.c (Marko Friedemann)
*
@@ -46,7 +46,7 @@ void onetouch_release_input(void *onetouch_);
struct usb_onetouch {
char name[128];
char phys[64];
- struct input_dev dev; /* input device interface */
+ struct input_dev *dev; /* input device interface */
struct usb_device *udev; /* usb device */
struct urb *irq; /* urb for interrupt in report */
@@ -58,7 +58,7 @@ static void usb_onetouch_irq(struct urb *urb, struct pt_regs *regs)
{
struct usb_onetouch *onetouch = urb->context;
signed char *data = onetouch->data;
- struct input_dev *dev = &onetouch->dev;
+ struct input_dev *dev = onetouch->dev;
int status;
switch (urb->status) {
@@ -74,11 +74,9 @@ static void usb_onetouch_irq(struct urb *urb, struct pt_regs *regs)
}
input_regs(dev, regs);
-
- input_report_key(&onetouch->dev, ONETOUCH_BUTTON,
- data[0] & 0x02);
-
+ input_report_key(dev, ONETOUCH_BUTTON, data[0] & 0x02);
input_sync(dev);
+
resubmit:
status = usb_submit_urb (urb, SLAB_ATOMIC);
if (status)
@@ -113,8 +111,8 @@ int onetouch_connect_input(struct us_data *ss)
struct usb_host_interface *interface;
struct usb_endpoint_descriptor *endpoint;
struct usb_onetouch *onetouch;
+ struct input_dev *input_dev;
int pipe, maxp;
- char path[64];
interface = ss->pusb_intf->cur_altsetting;
@@ -122,62 +120,62 @@ int onetouch_connect_input(struct us_data *ss)
return -ENODEV;
endpoint = &interface->endpoint[2].desc;
- if(!(endpoint->bEndpointAddress & USB_DIR_IN))
+ if (!(endpoint->bEndpointAddress & USB_DIR_IN))
return -ENODEV;
- if((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
+ if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
!= USB_ENDPOINT_XFER_INT)
return -ENODEV;
pipe = usb_rcvintpipe(udev, endpoint->bEndpointAddress);
maxp = usb_maxpacket(udev, pipe, usb_pipeout(pipe));
- if (!(onetouch = kcalloc(1, sizeof(struct usb_onetouch), GFP_KERNEL)))
- return -ENOMEM;
+ onetouch = kzalloc(sizeof(struct usb_onetouch), GFP_KERNEL);
+ input_dev = input_allocate_device();
+ if (!onetouch || !input_dev)
+ goto fail1;
onetouch->data = usb_buffer_alloc(udev, ONETOUCH_PKT_LEN,
SLAB_ATOMIC, &onetouch->data_dma);
- if (!onetouch->data){
- kfree(onetouch);
- return -ENOMEM;
- }
+ if (!onetouch->data)
+ goto fail1;
onetouch->irq = usb_alloc_urb(0, GFP_KERNEL);
- if (!onetouch->irq){
- kfree(onetouch);
- usb_buffer_free(udev, ONETOUCH_PKT_LEN,
- onetouch->data, onetouch->data_dma);
- return -ENODEV;
- }
-
+ if (!onetouch->irq)
+ goto fail2;
onetouch->udev = udev;
+ onetouch->dev = input_dev;
- set_bit(EV_KEY, onetouch->dev.evbit);
- set_bit(ONETOUCH_BUTTON, onetouch->dev.keybit);
- clear_bit(0, onetouch->dev.keybit);
+ if (udev->manufacturer)
+ strlcpy(onetouch->name, udev->manufacturer,
+ sizeof(onetouch->name));
+ if (udev->product) {
+ if (udev->manufacturer)
+ strlcat(onetouch->name, " ", sizeof(onetouch->name));
+ strlcat(onetouch->name, udev->product, sizeof(onetouch->name));
+ }
- onetouch->dev.private = onetouch;
- onetouch->dev.open = usb_onetouch_open;
- onetouch->dev.close = usb_onetouch_close;
+ if (!strlen(onetouch->name))
+ snprintf(onetouch->name, sizeof(onetouch->name),
+ "Maxtor Onetouch %04x:%04x",
+ le16_to_cpu(udev->descriptor.idVendor),
+ le16_to_cpu(udev->descriptor.idProduct));
- usb_make_path(udev, path, sizeof(path));
- sprintf(onetouch->phys, "%s/input0", path);
+ usb_make_path(udev, onetouch->phys, sizeof(onetouch->phys));
+ strlcat(onetouch->phys, "/input0", sizeof(onetouch->phys));
- onetouch->dev.name = onetouch->name;
- onetouch->dev.phys = onetouch->phys;
+ input_dev->name = onetouch->name;
+ input_dev->phys = onetouch->phys;
+ usb_to_input_id(udev, &input_dev->id);
+ input_dev->cdev.dev = &udev->dev;
- usb_to_input_id(udev, &onetouch->dev.id);
+ set_bit(EV_KEY, input_dev->evbit);
+ set_bit(ONETOUCH_BUTTON, input_dev->keybit);
+ clear_bit(0, input_dev->keybit);
- onetouch->dev.dev = &udev->dev;
-
- if (udev->manufacturer)
- strcat(onetouch->name, udev->manufacturer);
- if (udev->product)
- sprintf(onetouch->name, "%s %s", onetouch->name,
- udev->product);
- if (!strlen(onetouch->name))
- sprintf(onetouch->name, "Maxtor Onetouch %04x:%04x",
- onetouch->dev.id.vendor, onetouch->dev.id.product);
+ input_dev->private = onetouch;
+ input_dev->open = usb_onetouch_open;
+ input_dev->close = usb_onetouch_close;
usb_fill_int_urb(onetouch->irq, udev, pipe, onetouch->data,
(maxp > 8 ? 8 : maxp),
@@ -188,10 +186,15 @@ int onetouch_connect_input(struct us_data *ss)
ss->extra_destructor = onetouch_release_input;
ss->extra = onetouch;
- input_register_device(&onetouch->dev);
- printk(KERN_INFO "usb-input: %s on %s\n", onetouch->dev.name, path);
+ input_register_device(onetouch->dev);
return 0;
+
+ fail2: usb_buffer_free(udev, ONETOUCH_PKT_LEN,
+ onetouch->data, onetouch->data_dma);
+ fail1: kfree(onetouch);
+ input_free_device(input_dev);
+ return -ENOMEM;
}
void onetouch_release_input(void *onetouch_)
@@ -200,11 +203,9 @@ void onetouch_release_input(void *onetouch_)
if (onetouch) {
usb_kill_urb(onetouch->irq);
- input_unregister_device(&onetouch->dev);
+ input_unregister_device(onetouch->dev);
usb_free_urb(onetouch->irq);
usb_buffer_free(onetouch->udev, ONETOUCH_PKT_LEN,
onetouch->data, onetouch->data_dma);
- printk(KERN_INFO "usb-input: deregistering %s\n",
- onetouch->dev.name);
}
}
diff --git a/drivers/usb/storage/shuttle_usbat.c b/drivers/usb/storage/shuttle_usbat.c
index 356342c6e7a2..33c55a6261bb 100644
--- a/drivers/usb/storage/shuttle_usbat.c
+++ b/drivers/usb/storage/shuttle_usbat.c
@@ -1,4 +1,4 @@
-/* Driver for SCM Microsystems USB-ATAPI cable
+/* Driver for SCM Microsystems (a.k.a. Shuttle) USB-ATAPI cable
*
* $Id: shuttle_usbat.c,v 1.17 2002/04/22 03:39:43 mdharm Exp $
*
@@ -67,10 +67,10 @@ static int usbat_flash_transport(struct scsi_cmnd * srb, struct us_data *us);
static int usbat_hp8200e_transport(struct scsi_cmnd *srb, struct us_data *us);
/*
- * Convenience function to produce an ATAPI read/write sectors command
+ * Convenience function to produce an ATA read/write sectors command
* Use cmd=0x20 for read, cmd=0x30 for write
*/
-static void usbat_pack_atapi_sector_cmd(unsigned char *buf,
+static void usbat_pack_ata_sector_cmd(unsigned char *buf,
unsigned char thistime,
u32 sector, unsigned char cmd)
{
@@ -196,10 +196,12 @@ static int usbat_check_status(struct us_data *us)
if (rc != USB_STOR_XFER_GOOD)
return USB_STOR_TRANSPORT_FAILED;
- if (*reply & 0x01 && *reply != 0x51) // error/check condition (0x51 is ok)
+ /* error/check condition (0x51 is ok) */
+ if (*reply & 0x01 && *reply != 0x51)
return USB_STOR_TRANSPORT_FAILED;
- if (*reply & 0x20) // device fault
+ /* device fault */
+ if (*reply & 0x20)
return USB_STOR_TRANSPORT_FAILED;
return USB_STOR_TRANSPORT_GOOD;
@@ -222,29 +224,39 @@ static int usbat_set_shuttle_features(struct us_data *us,
command[0] = 0x40;
command[1] = USBAT_CMD_SET_FEAT;
- // The only bit relevant to ATA access is bit 6
- // which defines 8 bit data access (set) or 16 bit (unset)
+ /*
+ * The only bit relevant to ATA access is bit 6
+ * which defines 8 bit data access (set) or 16 bit (unset)
+ */
command[2] = epp_control;
- // If FCQ is set in the qualifier (defined in R/W cmd), then bits U0, U1,
- // ET1 and ET2 define an external event to be checked for on event of a
- // _read_blocks or _write_blocks operation. The read/write will not take
- // place unless the defined trigger signal is active.
+ /*
+ * If FCQ is set in the qualifier (defined in R/W cmd), then bits U0, U1,
+ * ET1 and ET2 define an external event to be checked for on event of a
+ * _read_blocks or _write_blocks operation. The read/write will not take
+ * place unless the defined trigger signal is active.
+ */
command[3] = external_trigger;
- // The resultant byte of the mask operation (see mask_byte) is compared for
- // equivalence with this test pattern. If equal, the read/write will take
- // place.
+ /*
+ * The resultant byte of the mask operation (see mask_byte) is compared for
+ * equivalence with this test pattern. If equal, the read/write will take
+ * place.
+ */
command[4] = test_pattern;
- // This value is logically ANDed with the status register field specified
- // in the read/write command.
+ /*
+ * This value is logically ANDed with the status register field specified
+ * in the read/write command.
+ */
command[5] = mask_byte;
- // If ALQ is set in the qualifier, this field contains the address of the
- // registers where the byte count should be read for transferring the data.
- // If ALQ is not set, then this field contains the number of bytes to be
- // transferred.
+ /*
+ * If ALQ is set in the qualifier, this field contains the address of the
+ * registers where the byte count should be read for transferring the data.
+ * If ALQ is not set, then this field contains the number of bytes to be
+ * transferred.
+ */
command[6] = subcountL;
command[7] = subcountH;
@@ -273,26 +285,26 @@ static int usbat_wait_not_busy(struct us_data *us, int minutes)
if (result!=USB_STOR_XFER_GOOD)
return USB_STOR_TRANSPORT_ERROR;
- if (*status & 0x01) { // check condition
+ if (*status & 0x01) { /* check condition */
result = usbat_read(us, USBAT_ATA, 0x10, status);
return USB_STOR_TRANSPORT_FAILED;
}
- if (*status & 0x20) // device fault
+ if (*status & 0x20) /* device fault */
return USB_STOR_TRANSPORT_FAILED;
- if ((*status & 0x80)==0x00) { // not busy
+ if ((*status & 0x80)==0x00) { /* not busy */
US_DEBUGP("Waited not busy for %d steps\n", i);
return USB_STOR_TRANSPORT_GOOD;
}
if (i<500)
- msleep(10); // 5 seconds
+ msleep(10); /* 5 seconds */
else if (i<700)
- msleep(50); // 10 seconds
+ msleep(50); /* 10 seconds */
else if (i<1200)
- msleep(100); // 50 seconds
+ msleep(100); /* 50 seconds */
else
- msleep(1000); // X minutes
+ msleep(1000); /* X minutes */
}
US_DEBUGP("Waited not busy for %d minutes, timing out.\n",
@@ -412,9 +424,12 @@ static int usbat_hp8200e_rw_block_test(struct us_data *us,
if (i==0) {
cmdlen = 16;
- // Write to multiple registers
- // Not really sure the 0x07, 0x17, 0xfc, 0xe7 is necessary here,
- // but that's what came out of the trace every single time.
+ /*
+ * Write to multiple registers
+ * Not really sure the 0x07, 0x17, 0xfc, 0xe7 is
+ * necessary here, but that's what came out of the
+ * trace every single time.
+ */
command[0] = 0x40;
command[1] = access | USBAT_CMD_WRITE_REGS;
command[2] = 0x07;
@@ -426,7 +441,7 @@ static int usbat_hp8200e_rw_block_test(struct us_data *us,
} else
cmdlen = 8;
- // Conditionally read or write blocks
+ /* Conditionally read or write blocks */
command[cmdlen-8] = (direction==DMA_TO_DEVICE ? 0x40 : 0xC0);
command[cmdlen-7] = access |
(direction==DMA_TO_DEVICE ?
@@ -456,11 +471,6 @@ static int usbat_hp8200e_rw_block_test(struct us_data *us,
}
-
- //US_DEBUGP("Transfer %s %d bytes, sg buffers %d\n",
- // direction == DMA_TO_DEVICE ? "out" : "in",
- // len, use_sg);
-
result = usb_stor_bulk_transfer_sg(us,
pipe, content, len, use_sg, NULL);
@@ -508,9 +518,9 @@ static int usbat_hp8200e_rw_block_test(struct us_data *us,
if (result!=USB_STOR_XFER_GOOD)
return USB_STOR_TRANSPORT_ERROR;
- if (*status & 0x01) // check condition
+ if (*status & 0x01) /* check condition */
return USB_STOR_TRANSPORT_FAILED;
- if (*status & 0x20) // device fault
+ if (*status & 0x20) /* device fault */
return USB_STOR_TRANSPORT_FAILED;
US_DEBUGP("Redoing %s\n",
@@ -547,32 +557,32 @@ static int usbat_multiple_write(struct us_data *us,
BUG_ON(num_registers > US_IOBUF_SIZE/2);
- // Write to multiple registers, ATA access
+ /* Write to multiple registers, ATA access */
command[0] = 0x40;
command[1] = USBAT_ATA | USBAT_CMD_WRITE_REGS;
- // No relevance
+ /* No relevance */
command[2] = 0;
command[3] = 0;
command[4] = 0;
command[5] = 0;
- // Number of bytes to be transferred (incl. addresses and data)
+ /* Number of bytes to be transferred (incl. addresses and data) */
command[6] = LSB_of(num_registers*2);
command[7] = MSB_of(num_registers*2);
- // The setup command
+ /* The setup command */
result = usbat_execute_command(us, command, 8);
if (result != USB_STOR_XFER_GOOD)
return USB_STOR_TRANSPORT_ERROR;
- // Create the reg/data, reg/data sequence
+ /* Create the reg/data, reg/data sequence */
for (i=0; i<num_registers; i++) {
data[i<<1] = registers[i];
data[1+(i<<1)] = data_out[i];
}
- // Send the data
+ /* Send the data */
result = usbat_bulk_write(us, data, num_registers*2);
if (result != USB_STOR_XFER_GOOD)
return USB_STOR_TRANSPORT_ERROR;
@@ -606,17 +616,17 @@ static int usbat_read_blocks(struct us_data *us,
command[1] = USBAT_ATA | USBAT_CMD_COND_READ_BLOCK;
command[2] = USBAT_ATA_DATA;
command[3] = USBAT_ATA_STATUS;
- command[4] = 0xFD; // Timeout (ms);
+ command[4] = 0xFD; /* Timeout (ms); */
command[5] = USBAT_QUAL_FCQ;
command[6] = LSB_of(len);
command[7] = MSB_of(len);
- // Multiple block read setup command
+ /* Multiple block read setup command */
result = usbat_execute_command(us, command, 8);
if (result != USB_STOR_XFER_GOOD)
return USB_STOR_TRANSPORT_FAILED;
- // Read the blocks we just asked for
+ /* Read the blocks we just asked for */
result = usbat_bulk_read(us, buffer, len);
if (result != USB_STOR_XFER_GOOD)
return USB_STOR_TRANSPORT_FAILED;
@@ -647,17 +657,17 @@ static int usbat_write_blocks(struct us_data *us,
command[1] = USBAT_ATA | USBAT_CMD_COND_WRITE_BLOCK;
command[2] = USBAT_ATA_DATA;
command[3] = USBAT_ATA_STATUS;
- command[4] = 0xFD; // Timeout (ms)
+ command[4] = 0xFD; /* Timeout (ms) */
command[5] = USBAT_QUAL_FCQ;
command[6] = LSB_of(len);
command[7] = MSB_of(len);
- // Multiple block write setup command
+ /* Multiple block write setup command */
result = usbat_execute_command(us, command, 8);
if (result != USB_STOR_XFER_GOOD)
return USB_STOR_TRANSPORT_FAILED;
- // Write the data
+ /* Write the data */
result = usbat_bulk_write(us, buffer, len);
if (result != USB_STOR_XFER_GOOD)
return USB_STOR_TRANSPORT_FAILED;
@@ -711,16 +721,20 @@ static int usbat_device_reset(struct us_data *us)
{
int rc;
- // Reset peripheral, enable peripheral control signals
- // (bring reset signal up)
+ /*
+ * Reset peripheral, enable peripheral control signals
+ * (bring reset signal up)
+ */
rc = usbat_write_user_io(us,
USBAT_UIO_DRVRST | USBAT_UIO_OE1 | USBAT_UIO_OE0,
USBAT_UIO_EPAD | USBAT_UIO_1);
if (rc != USB_STOR_XFER_GOOD)
return USB_STOR_TRANSPORT_ERROR;
- // Enable peripheral control signals
- // (bring reset signal down)
+ /*
+ * Enable peripheral control signals
+ * (bring reset signal down)
+ */
rc = usbat_write_user_io(us,
USBAT_UIO_OE1 | USBAT_UIO_OE0,
USBAT_UIO_EPAD | USBAT_UIO_1);
@@ -737,7 +751,7 @@ static int usbat_device_enable_cdt(struct us_data *us)
{
int rc;
- // Enable peripheral control signals and card detect
+ /* Enable peripheral control signals and card detect */
rc = usbat_write_user_io(us,
USBAT_UIO_ACKD | USBAT_UIO_OE1 | USBAT_UIO_OE0,
USBAT_UIO_EPAD | USBAT_UIO_1);
@@ -786,7 +800,7 @@ static int usbat_flash_check_media(struct us_data *us,
if (rc != USB_STOR_XFER_GOOD)
return USB_STOR_TRANSPORT_ERROR;
- // Check for media existence
+ /* Check for media existence */
rc = usbat_flash_check_media_present(uio);
if (rc == USBAT_FLASH_MEDIA_NONE) {
info->sense_key = 0x02;
@@ -795,11 +809,11 @@ static int usbat_flash_check_media(struct us_data *us,
return USB_STOR_TRANSPORT_FAILED;
}
- // Check for media change
+ /* Check for media change */
rc = usbat_flash_check_media_changed(uio);
if (rc == USBAT_FLASH_MEDIA_CHANGED) {
- // Reset and re-enable card detect
+ /* Reset and re-enable card detect */
rc = usbat_device_reset(us);
if (rc != USB_STOR_TRANSPORT_GOOD)
return rc;
@@ -855,15 +869,15 @@ static int usbat_identify_device(struct us_data *us,
if (rc != USB_STOR_XFER_GOOD)
return USB_STOR_TRANSPORT_ERROR;
- // Check for error bit
- if (status & 0x01) {
- // Device is a CompactFlash reader/writer
- US_DEBUGP("usbat_identify_device: Detected Flash reader/writer\n");
- info->devicetype = USBAT_DEV_FLASH;
- } else {
- // Device is HP 8200
+ /* Check for error bit, or if the command 'fell through' */
+ if (status == 0xA1 || !(status & 0x01)) {
+ /* Device is HP 8200 */
US_DEBUGP("usbat_identify_device: Detected HP8200 CDRW\n");
info->devicetype = USBAT_DEV_HP8200;
+ } else {
+ /* Device is a CompactFlash reader/writer */
+ US_DEBUGP("usbat_identify_device: Detected Flash reader/writer\n");
+ info->devicetype = USBAT_DEV_FLASH;
}
return USB_STOR_TRANSPORT_GOOD;
@@ -916,7 +930,7 @@ static int usbat_flash_get_sector_count(struct us_data *us,
if (!reply)
return USB_STOR_TRANSPORT_ERROR;
- // ATAPI command : IDENTIFY DEVICE
+ /* ATA command : IDENTIFY DEVICE */
rc = usbat_multiple_write(us, registers, command, 3);
if (rc != USB_STOR_XFER_GOOD) {
US_DEBUGP("usbat_flash_get_sector_count: Gah! identify_device failed\n");
@@ -924,7 +938,7 @@ static int usbat_flash_get_sector_count(struct us_data *us,
goto leave;
}
- // Read device status
+ /* Read device status */
if (usbat_get_status(us, &status) != USB_STOR_XFER_GOOD) {
rc = USB_STOR_TRANSPORT_ERROR;
goto leave;
@@ -932,7 +946,7 @@ static int usbat_flash_get_sector_count(struct us_data *us,
msleep(100);
- // Read the device identification data
+ /* Read the device identification data */
rc = usbat_read_block(us, reply, 512);
if (rc != USB_STOR_TRANSPORT_GOOD)
goto leave;
@@ -977,19 +991,23 @@ static int usbat_flash_read_data(struct us_data *us,
if (result != USB_STOR_TRANSPORT_GOOD)
return result;
- // we're working in LBA mode. according to the ATA spec,
- // we can support up to 28-bit addressing. I don't know if Jumpshot
- // supports beyond 24-bit addressing. It's kind of hard to test
- // since it requires > 8GB CF card.
+ /*
+ * we're working in LBA mode. according to the ATA spec,
+ * we can support up to 28-bit addressing. I don't know if Jumpshot
+ * supports beyond 24-bit addressing. It's kind of hard to test
+ * since it requires > 8GB CF card.
+ */
if (sector > 0x0FFFFFFF)
return USB_STOR_TRANSPORT_ERROR;
totallen = sectors * info->ssize;
- // Since we don't read more than 64 KB at a time, we have to create
- // a bounce buffer and move the data a piece at a time between the
- // bounce buffer and the actual transfer buffer.
+ /*
+ * Since we don't read more than 64 KB at a time, we have to create
+ * a bounce buffer and move the data a piece at a time between the
+ * bounce buffer and the actual transfer buffer.
+ */
alloclen = min(totallen, 65536u);
buffer = kmalloc(alloclen, GFP_NOIO);
@@ -997,27 +1015,29 @@ static int usbat_flash_read_data(struct us_data *us,
return USB_STOR_TRANSPORT_ERROR;
do {
- // loop, never allocate or transfer more than 64k at once
- // (min(128k, 255*info->ssize) is the real limit)
+ /*
+ * loop, never allocate or transfer more than 64k at once
+ * (min(128k, 255*info->ssize) is the real limit)
+ */
len = min(totallen, alloclen);
thistime = (len / info->ssize) & 0xff;
- // ATAPI command 0x20 (READ SECTORS)
- usbat_pack_atapi_sector_cmd(command, thistime, sector, 0x20);
+ /* ATA command 0x20 (READ SECTORS) */
+ usbat_pack_ata_sector_cmd(command, thistime, sector, 0x20);
- // Write/execute ATAPI read command
+ /* Write/execute ATA read command */
result = usbat_multiple_write(us, registers, command, 7);
if (result != USB_STOR_TRANSPORT_GOOD)
goto leave;
- // Read the data we just requested
+ /* Read the data we just requested */
result = usbat_read_blocks(us, buffer, len);
if (result != USB_STOR_TRANSPORT_GOOD)
goto leave;
US_DEBUGP("usbat_flash_read_data: %d bytes\n", len);
- // Store the data in the transfer buffer
+ /* Store the data in the transfer buffer */
usb_stor_access_xfer_buf(buffer, len, us->srb,
&sg_idx, &sg_offset, TO_XFER_BUF);
@@ -1061,19 +1081,23 @@ static int usbat_flash_write_data(struct us_data *us,
if (result != USB_STOR_TRANSPORT_GOOD)
return result;
- // we're working in LBA mode. according to the ATA spec,
- // we can support up to 28-bit addressing. I don't know if Jumpshot
- // supports beyond 24-bit addressing. It's kind of hard to test
- // since it requires > 8GB CF card.
+ /*
+ * we're working in LBA mode. according to the ATA spec,
+ * we can support up to 28-bit addressing. I don't know if the device
+ * supports beyond 24-bit addressing. It's kind of hard to test
+ * since it requires > 8GB media.
+ */
if (sector > 0x0FFFFFFF)
return USB_STOR_TRANSPORT_ERROR;
totallen = sectors * info->ssize;
- // Since we don't write more than 64 KB at a time, we have to create
- // a bounce buffer and move the data a piece at a time between the
- // bounce buffer and the actual transfer buffer.
+ /*
+ * Since we don't write more than 64 KB at a time, we have to create
+ * a bounce buffer and move the data a piece at a time between the
+ * bounce buffer and the actual transfer buffer.
+ */
alloclen = min(totallen, 65536u);
buffer = kmalloc(alloclen, GFP_NOIO);
@@ -1081,24 +1105,26 @@ static int usbat_flash_write_data(struct us_data *us,
return USB_STOR_TRANSPORT_ERROR;
do {
- // loop, never allocate or transfer more than 64k at once
- // (min(128k, 255*info->ssize) is the real limit)
+ /*
+ * loop, never allocate or transfer more than 64k at once
+ * (min(128k, 255*info->ssize) is the real limit)
+ */
len = min(totallen, alloclen);
thistime = (len / info->ssize) & 0xff;
- // Get the data from the transfer buffer
+ /* Get the data from the transfer buffer */
usb_stor_access_xfer_buf(buffer, len, us->srb,
&sg_idx, &sg_offset, FROM_XFER_BUF);
- // ATAPI command 0x30 (WRITE SECTORS)
- usbat_pack_atapi_sector_cmd(command, thistime, sector, 0x30);
+ /* ATA command 0x30 (WRITE SECTORS) */
+ usbat_pack_ata_sector_cmd(command, thistime, sector, 0x30);
- // Write/execute ATAPI write command
+ /* Write/execute ATA write command */
result = usbat_multiple_write(us, registers, command, 7);
if (result != USB_STOR_TRANSPORT_GOOD)
goto leave;
- // Write the data
+ /* Write the data */
result = usbat_write_blocks(us, buffer, len);
if (result != USB_STOR_TRANSPORT_GOOD)
goto leave;
@@ -1169,42 +1195,44 @@ static int usbat_hp8200e_handle_read10(struct us_data *us,
srb->transfersize);
}
- // Since we only read in one block at a time, we have to create
- // a bounce buffer and move the data a piece at a time between the
- // bounce buffer and the actual transfer buffer.
+ /*
+ * Since we only read in one block at a time, we have to create
+ * a bounce buffer and move the data a piece at a time between the
+ * bounce buffer and the actual transfer buffer.
+ */
len = (65535/srb->transfersize) * srb->transfersize;
US_DEBUGP("Max read is %d bytes\n", len);
len = min(len, srb->request_bufflen);
buffer = kmalloc(len, GFP_NOIO);
- if (buffer == NULL) // bloody hell!
+ if (buffer == NULL) /* bloody hell! */
return USB_STOR_TRANSPORT_FAILED;
sector = short_pack(data[7+3], data[7+2]);
sector <<= 16;
sector |= short_pack(data[7+5], data[7+4]);
transferred = 0;
- sg_segment = 0; // for keeping track of where we are in
- sg_offset = 0; // the scatter/gather list
+ sg_segment = 0; /* for keeping track of where we are in */
+ sg_offset = 0; /* the scatter/gather list */
while (transferred != srb->request_bufflen) {
if (len > srb->request_bufflen - transferred)
len = srb->request_bufflen - transferred;
- data[3] = len&0xFF; // (cylL) = expected length (L)
- data[4] = (len>>8)&0xFF; // (cylH) = expected length (H)
+ data[3] = len&0xFF; /* (cylL) = expected length (L) */
+ data[4] = (len>>8)&0xFF; /* (cylH) = expected length (H) */
- // Fix up the SCSI command sector and num sectors
+ /* Fix up the SCSI command sector and num sectors */
- data[7+2] = MSB_of(sector>>16); // SCSI command sector
+ data[7+2] = MSB_of(sector>>16); /* SCSI command sector */
data[7+3] = LSB_of(sector>>16);
data[7+4] = MSB_of(sector&0xFFFF);
data[7+5] = LSB_of(sector&0xFFFF);
if (data[7+0] == GPCMD_READ_CD)
data[7+6] = 0;
- data[7+7] = MSB_of(len / srb->transfersize); // SCSI command
- data[7+8] = LSB_of(len / srb->transfersize); // num sectors
+ data[7+7] = MSB_of(len / srb->transfersize); /* SCSI command */
+ data[7+8] = LSB_of(len / srb->transfersize); /* num sectors */
result = usbat_hp8200e_rw_block_test(us, USBAT_ATA,
registers, data, 19,
@@ -1217,16 +1245,16 @@ static int usbat_hp8200e_handle_read10(struct us_data *us,
if (result != USB_STOR_TRANSPORT_GOOD)
break;
- // Store the data in the transfer buffer
+ /* Store the data in the transfer buffer */
usb_stor_access_xfer_buf(buffer, len, srb,
&sg_segment, &sg_offset, TO_XFER_BUF);
- // Update the amount transferred and the sector number
+ /* Update the amount transferred and the sector number */
transferred += len;
sector += len / srb->transfersize;
- } // while transferred != srb->request_bufflen
+ } /* while transferred != srb->request_bufflen */
kfree(buffer);
return result;
@@ -1237,7 +1265,7 @@ static int usbat_select_and_test_registers(struct us_data *us)
int selector;
unsigned char *status = us->iobuf;
- // try device = master, then device = slave.
+ /* try device = master, then device = slave. */
for (selector = 0xA0; selector <= 0xB0; selector += 0x10) {
if (usbat_write(us, USBAT_ATA, USBAT_ATA_DEVICE, selector) !=
USB_STOR_XFER_GOOD)
@@ -1298,7 +1326,7 @@ int init_usbat(struct us_data *us)
memset(us->extra, 0, sizeof(struct usbat_info));
info = (struct usbat_info *) (us->extra);
- // Enable peripheral control signals
+ /* Enable peripheral control signals */
rc = usbat_write_user_io(us,
USBAT_UIO_OE1 | USBAT_UIO_OE0,
USBAT_UIO_EPAD | USBAT_UIO_1);
@@ -1337,7 +1365,7 @@ int init_usbat(struct us_data *us)
US_DEBUGP("INIT 5\n");
- // Enable peripheral control signals and card detect
+ /* Enable peripheral control signals and card detect */
rc = usbat_device_enable_cdt(us);
if (rc != USB_STOR_TRANSPORT_GOOD)
return rc;
@@ -1364,7 +1392,7 @@ int init_usbat(struct us_data *us)
US_DEBUGP("INIT 9\n");
- // At this point, we need to detect which device we are using
+ /* At this point, we need to detect which device we are using */
if (usbat_set_transport(us, info))
return USB_STOR_TRANSPORT_ERROR;
@@ -1414,10 +1442,10 @@ static int usbat_hp8200e_transport(struct scsi_cmnd *srb, struct us_data *us)
data[0] = 0x00;
data[1] = 0x00;
data[2] = 0x00;
- data[3] = len&0xFF; // (cylL) = expected length (L)
- data[4] = (len>>8)&0xFF; // (cylH) = expected length (H)
- data[5] = 0xB0; // (device sel) = slave
- data[6] = 0xA0; // (command) = ATA PACKET COMMAND
+ data[3] = len&0xFF; /* (cylL) = expected length (L) */
+ data[4] = (len>>8)&0xFF; /* (cylH) = expected length (H) */
+ data[5] = 0xB0; /* (device sel) = slave */
+ data[6] = 0xA0; /* (command) = ATA PACKET COMMAND */
for (i=7; i<19; i++) {
registers[i] = 0x10;
@@ -1466,13 +1494,15 @@ static int usbat_hp8200e_transport(struct scsi_cmnd *srb, struct us_data *us)
return result;
}
- // Write the 12-byte command header.
-
- // If the command is BLANK then set the timer for 75 minutes.
- // Otherwise set it for 10 minutes.
-
- // NOTE: THE 8200 DOCUMENTATION STATES THAT BLANKING A CDRW
- // AT SPEED 4 IS UNRELIABLE!!!
+ /*
+ * Write the 12-byte command header.
+ *
+ * If the command is BLANK then set the timer for 75 minutes.
+ * Otherwise set it for 10 minutes.
+ *
+ * NOTE: THE 8200 DOCUMENTATION STATES THAT BLANKING A CDRW
+ * AT SPEED 4 IS UNRELIABLE!!!
+ */
if ( (result = usbat_write_block(us,
USBAT_ATA, srb->cmnd, 12,
@@ -1481,19 +1511,18 @@ static int usbat_hp8200e_transport(struct scsi_cmnd *srb, struct us_data *us)
return result;
}
- // If there is response data to be read in
- // then do it here.
+ /* If there is response data to be read in then do it here. */
if (len != 0 && (srb->sc_data_direction == DMA_FROM_DEVICE)) {
- // How many bytes to read in? Check cylL register
+ /* How many bytes to read in? Check cylL register */
if (usbat_read(us, USBAT_ATA, USBAT_ATA_LBA_ME, status) !=
USB_STOR_XFER_GOOD) {
return USB_STOR_TRANSPORT_ERROR;
}
- if (len > 0xFF) { // need to read cylH also
+ if (len > 0xFF) { /* need to read cylH also */
len = *status;
if (usbat_read(us, USBAT_ATA, USBAT_ATA_LBA_HI, status) !=
USB_STOR_XFER_GOOD) {
@@ -1556,13 +1585,16 @@ static int usbat_flash_transport(struct scsi_cmnd * srb, struct us_data *us)
if (rc != USB_STOR_TRANSPORT_GOOD)
return rc;
- info->ssize = 0x200; // hard coded 512 byte sectors as per ATA spec
+ /* hard coded 512 byte sectors as per ATA spec */
+ info->ssize = 0x200;
US_DEBUGP("usbat_flash_transport: READ_CAPACITY: %ld sectors, %ld bytes per sector\n",
info->sectors, info->ssize);
- // build the reply
- // note: must return the sector number of the last sector,
- // *not* the total number of sectors
+ /*
+ * build the reply
+ * note: must return the sector number of the last sector,
+ * *not* the total number of sectors
+ */
((__be32 *) ptr)[0] = cpu_to_be32(info->sectors - 1);
((__be32 *) ptr)[1] = cpu_to_be32(info->ssize);
usb_stor_set_xfer_buf(ptr, 8, srb);
@@ -1586,7 +1618,9 @@ static int usbat_flash_transport(struct scsi_cmnd * srb, struct us_data *us)
}
if (srb->cmnd[0] == READ_12) {
- // I don't think we'll ever see a READ_12 but support it anyway...
+ /*
+ * I don't think we'll ever see a READ_12 but support it anyway
+ */
block = ((u32)(srb->cmnd[2]) << 24) | ((u32)(srb->cmnd[3]) << 16) |
((u32)(srb->cmnd[4]) << 8) | ((u32)(srb->cmnd[5]));
@@ -1608,7 +1642,9 @@ static int usbat_flash_transport(struct scsi_cmnd * srb, struct us_data *us)
}
if (srb->cmnd[0] == WRITE_12) {
- // I don't think we'll ever see a WRITE_12 but support it anyway...
+ /*
+ * I don't think we'll ever see a WRITE_12 but support it anyway
+ */
block = ((u32)(srb->cmnd[2]) << 24) | ((u32)(srb->cmnd[3]) << 16) |
((u32)(srb->cmnd[4]) << 8) | ((u32)(srb->cmnd[5]));
@@ -1645,8 +1681,10 @@ static int usbat_flash_transport(struct scsi_cmnd * srb, struct us_data *us)
}
if (srb->cmnd[0] == ALLOW_MEDIUM_REMOVAL) {
- // sure. whatever. not like we can stop the user from popping
- // the media out of the device (no locking doors, etc)
+ /*
+ * sure. whatever. not like we can stop the user from popping
+ * the media out of the device (no locking doors, etc)
+ */
return USB_STOR_TRANSPORT_GOOD;
}
diff --git a/drivers/usb/storage/shuttle_usbat.h b/drivers/usb/storage/shuttle_usbat.h
index 5b8e867e2ae5..25e7d8b340b8 100644
--- a/drivers/usb/storage/shuttle_usbat.h
+++ b/drivers/usb/storage/shuttle_usbat.h
@@ -55,8 +55,8 @@
#define USBAT_UIO_WRITE 0
/* Qualifier bits */
-#define USBAT_QUAL_FCQ 0x20 // full compare
-#define USBAT_QUAL_ALQ 0x10 // auto load subcount
+#define USBAT_QUAL_FCQ 0x20 /* full compare */
+#define USBAT_QUAL_ALQ 0x10 /* auto load subcount */
/* USBAT Flash Media status types */
#define USBAT_FLASH_MEDIA_NONE 0
@@ -67,39 +67,39 @@
#define USBAT_FLASH_MEDIA_CHANGED 1
/* USBAT ATA registers */
-#define USBAT_ATA_DATA 0x10 // read/write data (R/W)
-#define USBAT_ATA_FEATURES 0x11 // set features (W)
-#define USBAT_ATA_ERROR 0x11 // error (R)
-#define USBAT_ATA_SECCNT 0x12 // sector count (R/W)
-#define USBAT_ATA_SECNUM 0x13 // sector number (R/W)
-#define USBAT_ATA_LBA_ME 0x14 // cylinder low (R/W)
-#define USBAT_ATA_LBA_HI 0x15 // cylinder high (R/W)
-#define USBAT_ATA_DEVICE 0x16 // head/device selection (R/W)
-#define USBAT_ATA_STATUS 0x17 // device status (R)
-#define USBAT_ATA_CMD 0x17 // device command (W)
-#define USBAT_ATA_ALTSTATUS 0x0E // status (no clear IRQ) (R)
+#define USBAT_ATA_DATA 0x10 /* read/write data (R/W) */
+#define USBAT_ATA_FEATURES 0x11 /* set features (W) */
+#define USBAT_ATA_ERROR 0x11 /* error (R) */
+#define USBAT_ATA_SECCNT 0x12 /* sector count (R/W) */
+#define USBAT_ATA_SECNUM 0x13 /* sector number (R/W) */
+#define USBAT_ATA_LBA_ME 0x14 /* cylinder low (R/W) */
+#define USBAT_ATA_LBA_HI 0x15 /* cylinder high (R/W) */
+#define USBAT_ATA_DEVICE 0x16 /* head/device selection (R/W) */
+#define USBAT_ATA_STATUS 0x17 /* device status (R) */
+#define USBAT_ATA_CMD 0x17 /* device command (W) */
+#define USBAT_ATA_ALTSTATUS 0x0E /* status (no clear IRQ) (R) */
/* USBAT User I/O Data registers */
-#define USBAT_UIO_EPAD 0x80 // Enable Peripheral Control Signals
-#define USBAT_UIO_CDT 0x40 // Card Detect (Read Only)
- // CDT = ACKD & !UI1 & !UI0
-#define USBAT_UIO_1 0x20 // I/O 1
-#define USBAT_UIO_0 0x10 // I/O 0
-#define USBAT_UIO_EPP_ATA 0x08 // 1=EPP mode, 0=ATA mode
-#define USBAT_UIO_UI1 0x04 // Input 1
-#define USBAT_UIO_UI0 0x02 // Input 0
-#define USBAT_UIO_INTR_ACK 0x01 // Interrupt (ATA & ISA)/Acknowledge (EPP)
+#define USBAT_UIO_EPAD 0x80 /* Enable Peripheral Control Signals */
+#define USBAT_UIO_CDT 0x40 /* Card Detect (Read Only) */
+ /* CDT = ACKD & !UI1 & !UI0 */
+#define USBAT_UIO_1 0x20 /* I/O 1 */
+#define USBAT_UIO_0 0x10 /* I/O 0 */
+#define USBAT_UIO_EPP_ATA 0x08 /* 1=EPP mode, 0=ATA mode */
+#define USBAT_UIO_UI1 0x04 /* Input 1 */
+#define USBAT_UIO_UI0 0x02 /* Input 0 */
+#define USBAT_UIO_INTR_ACK 0x01 /* Interrupt (ATA/ISA)/Acknowledge (EPP) */
/* USBAT User I/O Enable registers */
-#define USBAT_UIO_DRVRST 0x80 // Reset Peripheral
-#define USBAT_UIO_ACKD 0x40 // Enable Card Detect
-#define USBAT_UIO_OE1 0x20 // I/O 1 set=output/clr=input
- // If ACKD=1, set OE1 to 1 also.
-#define USBAT_UIO_OE0 0x10 // I/O 0 set=output/clr=input
-#define USBAT_UIO_ADPRST 0x01 // Reset SCM chip
+#define USBAT_UIO_DRVRST 0x80 /* Reset Peripheral */
+#define USBAT_UIO_ACKD 0x40 /* Enable Card Detect */
+#define USBAT_UIO_OE1 0x20 /* I/O 1 set=output/clr=input */
+ /* If ACKD=1, set OE1 to 1 also. */
+#define USBAT_UIO_OE0 0x10 /* I/O 0 set=output/clr=input */
+#define USBAT_UIO_ADPRST 0x01 /* Reset SCM chip */
/* USBAT Features */
-#define USBAT_FEAT_ETEN 0x80 // External trigger enable
+#define USBAT_FEAT_ETEN 0x80 /* External trigger enable */
#define USBAT_FEAT_U1 0x08
#define USBAT_FEAT_U0 0x04
#define USBAT_FEAT_ET1 0x02
@@ -112,12 +112,12 @@ struct usbat_info {
int devicetype;
/* Used for Flash readers only */
- unsigned long sectors; // total sector count
- unsigned long ssize; // sector size in bytes
+ unsigned long sectors; /* total sector count */
+ unsigned long ssize; /* sector size in bytes */
unsigned char sense_key;
- unsigned long sense_asc; // additional sense code
- unsigned long sense_ascq; // additional sense code qualifier
+ unsigned long sense_asc; /* additional sense code */
+ unsigned long sense_ascq; /* additional sense code qualifier */
};
#endif
diff --git a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c
index c1ba5301ebfc..7ca896a342e3 100644
--- a/drivers/usb/storage/transport.c
+++ b/drivers/usb/storage/transport.c
@@ -636,11 +636,11 @@ void usb_stor_invoke_transport(struct scsi_cmnd *srb, struct us_data *us)
/* use the new buffer we have */
old_request_buffer = srb->request_buffer;
- srb->request_buffer = srb->sense_buffer;
+ srb->request_buffer = us->sensebuf;
/* set the buffer length for transfer */
old_request_bufflen = srb->request_bufflen;
- srb->request_bufflen = 18;
+ srb->request_bufflen = US_SENSE_SIZE;
/* set up for no scatter-gather use */
old_sg = srb->use_sg;
@@ -652,6 +652,7 @@ void usb_stor_invoke_transport(struct scsi_cmnd *srb, struct us_data *us)
temp_result = us->transport(us->srb, us);
/* let's clean up right away */
+ memcpy(srb->sense_buffer, us->sensebuf, US_SENSE_SIZE);
srb->resid = old_resid;
srb->request_buffer = old_request_buffer;
srb->request_bufflen = old_request_bufflen;
@@ -923,6 +924,7 @@ int usb_stor_Bulk_max_lun(struct us_data *us)
int result;
/* issue the command */
+ us->iobuf[0] = 0;
result = usb_stor_control_msg(us, us->recv_ctrl_pipe,
US_BULK_GET_MAX_LUN,
USB_DIR_IN | USB_TYPE_CLASS |
diff --git a/drivers/usb/storage/transport.h b/drivers/usb/storage/transport.h
index 8d9e0663f8fe..0a362cc781ad 100644
--- a/drivers/usb/storage/transport.h
+++ b/drivers/usb/storage/transport.h
@@ -50,7 +50,7 @@
#define US_PR_CB 0x01 /* Control/Bulk w/o interrupt */
#define US_PR_BULK 0x50 /* bulk only */
#ifdef CONFIG_USB_STORAGE_USBAT
-#define US_PR_SCM_ATAPI 0x80 /* SCM-ATAPI bridge */
+#define US_PR_USBAT 0x80 /* SCM-ATAPI bridge */
#endif
#ifdef CONFIG_USB_STORAGE_SDDR09
#define US_PR_EUSB_SDDR09 0x81 /* SCM-SCSI bridge for SDDR-09 */
diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h
index b79dad1b598c..9e926a8f2116 100644
--- a/drivers/usb/storage/unusual_devs.h
+++ b/drivers/usb/storage/unusual_devs.h
@@ -71,12 +71,12 @@ UNUSUAL_DEV( 0x03f0, 0x0107, 0x0200, 0x0200,
UNUSUAL_DEV( 0x03f0, 0x0207, 0x0001, 0x0001,
"HP",
"CD-Writer+ 8200e",
- US_SC_8070, US_PR_SCM_ATAPI, init_usbat, 0),
+ US_SC_8070, US_PR_USBAT, init_usbat, 0),
UNUSUAL_DEV( 0x03f0, 0x0307, 0x0001, 0x0001,
"HP",
"CD-Writer+ CD-4e",
- US_SC_8070, US_PR_SCM_ATAPI, init_usbat, 0),
+ US_SC_8070, US_PR_USBAT, init_usbat, 0),
#endif
/* Patch submitted by Mihnea-Costin Grigore <mihnea@zulu.ro> */
@@ -106,6 +106,13 @@ UNUSUAL_DEV( 0x0411, 0x001c, 0x0113, 0x0113,
US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_FIX_INQUIRY ),
+/* Reported by Stefan Werner <dustbln@gmx.de> */
+UNUSUAL_DEV( 0x0419, 0xaaf6, 0x0100, 0x0100,
+ "TrekStor",
+ "i.Beat Joy 2.0",
+ US_SC_DEVICE, US_PR_DEVICE, NULL,
+ US_FL_IGNORE_RESIDUE ),
+
/* Reported by Olaf Hering <olh@suse.de> from novell bug #105878 */
UNUSUAL_DEV( 0x0424, 0x0fdc, 0x0210, 0x0210,
"SMSC",
@@ -244,6 +251,13 @@ UNUSUAL_DEV( 0x04da, 0x2372, 0x0000, 0x9999,
US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_FIX_CAPACITY | US_FL_NOT_LOCKABLE ),
+/* Reported by Simeon Simeonov <simeonov_2000@yahoo.com> */
+UNUSUAL_DEV( 0x04da, 0x2373, 0x0000, 0x9999,
+ "LEICA",
+ "D-LUX Camera",
+ US_SC_DEVICE, US_PR_DEVICE, NULL,
+ US_FL_FIX_CAPACITY | US_FL_NOT_LOCKABLE ),
+
/* Most of the following entries were developed with the help of
* Shuttle/SCM directly.
*/
@@ -333,9 +347,9 @@ UNUSUAL_DEV( 0x04fc, 0x80c2, 0x0100, 0x0100,
#ifdef CONFIG_USB_STORAGE_USBAT
UNUSUAL_DEV( 0x04e6, 0x1010, 0x0000, 0x9999,
- "SCM",
- "SCM USBAT-02",
- US_SC_SCSI, US_PR_SCM_ATAPI, init_usbat,
+ "Shuttle/SCM",
+ "USBAT-02",
+ US_SC_SCSI, US_PR_USBAT, init_usbat,
US_FL_SINGLE_LUN),
#endif
@@ -598,6 +612,16 @@ UNUSUAL_DEV( 0x05ac, 0x1205, 0x0000, 0x9999,
US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_FIX_CAPACITY ),
+/*
+ * Reported by Tyson Vinson <lornoss@gmail.com>
+ * This particular productId is the iPod Nano
+ */
+UNUSUAL_DEV( 0x05ac, 0x120a, 0x0000, 0x9999,
+ "Apple",
+ "iPod",
+ US_SC_DEVICE, US_PR_DEVICE, NULL,
+ US_FL_FIX_CAPACITY ),
+
#ifdef CONFIG_USB_STORAGE_JUMPSHOT
UNUSUAL_DEV( 0x05dc, 0x0001, 0x0000, 0x0001,
"Lexar",
@@ -702,6 +726,14 @@ UNUSUAL_DEV( 0x0781, 0x0001, 0x0200, 0x0200,
US_SC_SCSI, US_PR_CB, NULL,
US_FL_SINGLE_LUN ),
+#ifdef CONFIG_USB_STORAGE_USBAT
+UNUSUAL_DEV( 0x0781, 0x0005, 0x0005, 0x0005,
+ "Sandisk",
+ "ImageMate SDDR-05b",
+ US_SC_SCSI, US_PR_USBAT, init_usbat,
+ US_FL_SINGLE_LUN ),
+#endif
+
UNUSUAL_DEV( 0x0781, 0x0100, 0x0100, 0x0100,
"Sandisk",
"ImageMate SDDR-12",
@@ -724,7 +756,7 @@ UNUSUAL_DEV( 0x07ab, 0xfc01, 0x0000, 0x9999,
#endif
/* Reported by Eero Volotinen <eero@ping-viini.org> */
-UNUSUAL_DEV( 0x07ab, 0xfccd, 0x0406, 0x0406,
+UNUSUAL_DEV( 0x07ab, 0xfccd, 0x0000, 0x9999,
"Freecom Technologies",
"FHD-Classic",
US_SC_DEVICE, US_PR_DEVICE, NULL,
diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c
index f9a9bfa1aef5..3847ebed2aa4 100644
--- a/drivers/usb/storage/usb.c
+++ b/drivers/usb/storage/usb.c
@@ -54,6 +54,7 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
+#include <linux/kthread.h>
#include <scsi/scsi.h>
#include <scsi/scsi_cmnd.h>
@@ -111,11 +112,6 @@ static atomic_t total_threads = ATOMIC_INIT(0);
static DECLARE_COMPLETION(threads_gone);
-static int storage_probe(struct usb_interface *iface,
- const struct usb_device_id *id);
-
-static void storage_disconnect(struct usb_interface *iface);
-
/* The entries in this table, except for final ones here
* (USB_MASS_STORAGE_CLASS and the empty entry), correspond,
* line for line with the entries of us_unsuaul_dev_list[].
@@ -233,13 +229,40 @@ static struct us_unusual_dev us_unusual_dev_list[] = {
{ NULL }
};
-static struct usb_driver usb_storage_driver = {
- .owner = THIS_MODULE,
- .name = "usb-storage",
- .probe = storage_probe,
- .disconnect = storage_disconnect,
- .id_table = storage_usb_ids,
-};
+
+#ifdef CONFIG_PM /* Minimal support for suspend and resume */
+
+static int storage_suspend(struct usb_interface *iface, pm_message_t message)
+{
+ struct us_data *us = usb_get_intfdata(iface);
+
+ /* Wait until no command is running */
+ down(&us->dev_semaphore);
+
+ US_DEBUGP("%s\n", __FUNCTION__);
+ iface->dev.power.power_state.event = message.event;
+
+ /* When runtime PM is working, we'll set a flag to indicate
+ * whether we should autoresume when a SCSI request arrives. */
+
+ up(&us->dev_semaphore);
+ return 0;
+}
+
+static int storage_resume(struct usb_interface *iface)
+{
+ struct us_data *us = usb_get_intfdata(iface);
+
+ down(&us->dev_semaphore);
+
+ US_DEBUGP("%s\n", __FUNCTION__);
+ iface->dev.power.power_state.event = PM_EVENT_ON;
+
+ up(&us->dev_semaphore);
+ return 0;
+}
+
+#endif /* CONFIG_PM */
/*
* fill_inquiry_response takes an unsigned char array (which must
@@ -288,22 +311,7 @@ static int usb_stor_control_thread(void * __us)
struct us_data *us = (struct us_data *)__us;
struct Scsi_Host *host = us_to_host(us);
- lock_kernel();
-
- /*
- * This thread doesn't need any user-level access,
- * so get rid of all our resources.
- */
- daemonize("usb-storage");
current->flags |= PF_NOFREEZE;
- unlock_kernel();
-
- /* acquire a reference to the host, so it won't be deallocated
- * until we're ready to exit */
- scsi_host_get(host);
-
- /* signal that we've started the thread */
- complete(&(us->notify));
for(;;) {
US_DEBUGP("*** thread sleeping.\n");
@@ -467,6 +475,12 @@ static int associate_dev(struct us_data *us, struct usb_interface *intf)
US_DEBUGP("I/O buffer allocation failed\n");
return -ENOMEM;
}
+
+ us->sensebuf = kmalloc(US_SENSE_SIZE, GFP_KERNEL);
+ if (!us->sensebuf) {
+ US_DEBUGP("Sense buffer allocation failed\n");
+ return -ENOMEM;
+ }
return 0;
}
@@ -555,8 +569,8 @@ static int get_transport(struct us_data *us)
break;
#ifdef CONFIG_USB_STORAGE_USBAT
- case US_PR_SCM_ATAPI:
- us->transport_name = "SCM/ATAPI";
+ case US_PR_USBAT:
+ us->transport_name = "Shuttle USBAT";
us->transport = usbat_transport;
us->transport_reset = usb_stor_CB_reset;
us->max_lun = 1;
@@ -740,6 +754,7 @@ static int get_pipes(struct us_data *us)
static int usb_stor_acquire_resources(struct us_data *us)
{
int p;
+ struct task_struct *th;
us->current_urb = usb_alloc_urb(0, GFP_KERNEL);
if (!us->current_urb) {
@@ -747,38 +762,28 @@ static int usb_stor_acquire_resources(struct us_data *us)
return -ENOMEM;
}
- /* Lock the device while we carry out the next two operations */
- down(&us->dev_semaphore);
-
- /* For bulk-only devices, determine the max LUN value */
- if (us->protocol == US_PR_BULK) {
- p = usb_stor_Bulk_max_lun(us);
- if (p < 0) {
- up(&us->dev_semaphore);
- return p;
- }
- us->max_lun = p;
- }
-
/* Just before we start our control thread, initialize
* the device if it needs initialization */
- if (us->unusual_dev->initFunction)
- us->unusual_dev->initFunction(us);
-
- up(&us->dev_semaphore);
+ if (us->unusual_dev->initFunction) {
+ p = us->unusual_dev->initFunction(us);
+ if (p)
+ return p;
+ }
/* Start up our control thread */
- p = kernel_thread(usb_stor_control_thread, us, CLONE_VM);
- if (p < 0) {
+ th = kthread_create(usb_stor_control_thread, us, "usb-storage");
+ if (IS_ERR(th)) {
printk(KERN_WARNING USB_STORAGE
"Unable to start control thread\n");
- return p;
+ return PTR_ERR(th);
}
- us->pid = p;
- atomic_inc(&total_threads);
- /* Wait for the thread to start */
- wait_for_completion(&(us->notify));
+ /* Take a reference to the host for the control thread and
+ * count it among all the threads we have launched. Then
+ * start it up. */
+ scsi_host_get(us_to_host(us));
+ atomic_inc(&total_threads);
+ wake_up_process(th);
return 0;
}
@@ -812,6 +817,8 @@ static void dissociate_dev(struct us_data *us)
{
US_DEBUGP("-- %s\n", __FUNCTION__);
+ kfree(us->sensebuf);
+
/* Free the device-related DMA-mapped buffers */
if (us->cr)
usb_buffer_free(us->pusb_dev, sizeof(*us->cr), us->cr,
@@ -872,21 +879,6 @@ static int usb_stor_scan_thread(void * __us)
{
struct us_data *us = (struct us_data *)__us;
- /*
- * This thread doesn't need any user-level access,
- * so get rid of all our resources.
- */
- lock_kernel();
- daemonize("usb-stor-scan");
- unlock_kernel();
-
- /* Acquire a reference to the host, so it won't be deallocated
- * until we're ready to exit */
- scsi_host_get(us_to_host(us));
-
- /* Signal that we've started the thread */
- complete(&(us->notify));
-
printk(KERN_DEBUG
"usb-storage: device found at %d\n", us->pusb_dev->devnum);
@@ -904,6 +896,14 @@ retry:
/* If the device is still connected, perform the scanning */
if (!test_bit(US_FLIDX_DISCONNECTING, &us->flags)) {
+
+ /* For bulk-only devices, determine the max LUN value */
+ if (us->protocol == US_PR_BULK &&
+ !(us->flags & US_FL_SINGLE_LUN)) {
+ down(&us->dev_semaphore);
+ us->max_lun = usb_stor_Bulk_max_lun(us);
+ up(&us->dev_semaphore);
+ }
scsi_scan_host(us_to_host(us));
printk(KERN_DEBUG "usb-storage: device scan complete\n");
@@ -923,6 +923,7 @@ static int storage_probe(struct usb_interface *intf,
struct us_data *us;
const int id_index = id - storage_usb_ids;
int result;
+ struct task_struct *th;
US_DEBUGP("USB Mass Storage device detected\n");
@@ -1003,17 +1004,21 @@ static int storage_probe(struct usb_interface *intf,
}
/* Start up the thread for delayed SCSI-device scanning */
- result = kernel_thread(usb_stor_scan_thread, us, CLONE_VM);
- if (result < 0) {
+ th = kthread_create(usb_stor_scan_thread, us, "usb-stor-scan");
+ if (IS_ERR(th)) {
printk(KERN_WARNING USB_STORAGE
"Unable to start the device-scanning thread\n");
quiesce_and_remove_host(us);
+ result = PTR_ERR(th);
goto BadDevice;
}
- atomic_inc(&total_threads);
- /* Wait for the thread to start */
- wait_for_completion(&(us->notify));
+ /* Take a reference to the host for the scanning thread and
+ * count it among all the threads we have launched. Then
+ * start it up. */
+ scsi_host_get(us_to_host(us));
+ atomic_inc(&total_threads);
+ wake_up_process(th);
return 0;
@@ -1038,6 +1043,18 @@ static void storage_disconnect(struct usb_interface *intf)
* Initialization and registration
***********************************************************************/
+static struct usb_driver usb_storage_driver = {
+ .owner = THIS_MODULE,
+ .name = "usb-storage",
+ .probe = storage_probe,
+ .disconnect = storage_disconnect,
+#ifdef CONFIG_PM
+ .suspend = storage_suspend,
+ .resume = storage_resume,
+#endif
+ .id_table = storage_usb_ids,
+};
+
static int __init usb_stor_init(void)
{
int retval;
diff --git a/drivers/usb/storage/usb.h b/drivers/usb/storage/usb.h
index a195adae57b6..98b09711a739 100644
--- a/drivers/usb/storage/usb.h
+++ b/drivers/usb/storage/usb.h
@@ -117,6 +117,7 @@ enum { US_DO_ALL_FLAGS };
*/
#define US_IOBUF_SIZE 64 /* Size of the DMA-mapped I/O buffer */
+#define US_SENSE_SIZE 18 /* Size of the autosense data buffer */
typedef int (*trans_cmnd)(struct scsi_cmnd *, struct us_data*);
typedef int (*trans_reset)(struct us_data*);
@@ -160,14 +161,12 @@ struct us_data {
struct scsi_cmnd *srb; /* current srb */
unsigned int tag; /* current dCBWTag */
- /* thread information */
- int pid; /* control thread */
-
/* control and bulk communications data */
struct urb *current_urb; /* USB requests */
struct usb_ctrlrequest *cr; /* control requests */
struct usb_sg_request current_sg; /* scatter-gather req. */
unsigned char *iobuf; /* I/O buffer */
+ unsigned char *sensebuf; /* sense data buffer */
dma_addr_t cr_dma; /* buffer DMA addresses */
dma_addr_t iobuf_dma;
diff --git a/drivers/usb/usb-skeleton.c b/drivers/usb/usb-skeleton.c
index 353f24d45bc1..6c3a53f8f26c 100644
--- a/drivers/usb/usb-skeleton.c
+++ b/drivers/usb/usb-skeleton.c
@@ -223,9 +223,8 @@ static struct file_operations skel_fops = {
* and to have the device registered with devfs and the driver core
*/
static struct usb_class_driver skel_class = {
- .name = "usb/skel%d",
+ .name = "skel%d",
.fops = &skel_fops,
- .mode = S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH,
.minor_base = USB_SKEL_MINOR_BASE,
};
diff --git a/drivers/video/68328fb.c b/drivers/video/68328fb.c
index 6a3cfbdc6dc9..3b0ddc55236b 100644
--- a/drivers/video/68328fb.c
+++ b/drivers/video/68328fb.c
@@ -113,7 +113,6 @@ static struct fb_ops mc68x328fb_ops = {
.fb_fillrect = cfb_fillrect,
.fb_copyarea = cfb_copyarea,
.fb_imageblit = cfb_imageblit,
- .fb_cursor = soft_cursor,
.fb_mmap = mc68x328fb_mmap,
};
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 1cd942abb580..25b6ca6ad081 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -65,15 +65,6 @@ config FB_CFB_IMAGEBLIT
blitting. This is used by drivers that don't provide their own
(accelerated) version.
-config FB_SOFT_CURSOR
- tristate
- depends on FB
- default n
- ---help---
- Include the soft_cursor function for generic software cursor support.
- This is used by drivers that don't provide their own (accelerated)
- version.
-
config FB_MACMODES
tristate
depends on FB
@@ -114,7 +105,6 @@ config FB_CIRRUS
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
- select FB_SOFT_CURSOR
---help---
This enables support for Cirrus Logic GD542x/543x based boards on
Amiga: SD64, Piccolo, Picasso II/II+, Picasso IV, or EGS Spectrum.
@@ -133,7 +123,6 @@ config FB_PM2
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
- select FB_SOFT_CURSOR
help
This is the frame buffer device driver for the Permedia2 AGP frame
buffer card from ASK, aka `Graphic Blaster Exxtreme'. There is a
@@ -152,7 +141,6 @@ config FB_ARMCLCD
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
- select FB_SOFT_CURSOR
help
This framebuffer device driver is for the ARM PrimeCell PL110
Colour LCD controller. ARM PrimeCells provide the building
@@ -169,7 +157,6 @@ config FB_ACORN
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
- select FB_SOFT_CURSOR
help
This is the frame buffer device driver for the Acorn VIDC graphics
hardware found in Acorn RISC PCs and other ARM-based machines. If
@@ -181,7 +168,9 @@ config FB_CLPS711X
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
- select FB_SOFT_CURSOR
+ help
+ Say Y to enable the Framebuffer driver for the CLPS7111 and
+ EP7212 processors.
config FB_SA1100
bool "SA-1100 LCD support"
@@ -189,7 +178,6 @@ config FB_SA1100
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
- select FB_SOFT_CURSOR
help
This is a framebuffer device for the SA-1100 LCD Controller.
See <http://www.linux-fbdev.org/> for information on framebuffer
@@ -204,7 +192,6 @@ config FB_IMX
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
- select FB_SOFT_CURSOR
config FB_CYBER2000
tristate "CyberPro 2000/2010/5000 support"
@@ -212,7 +199,6 @@ config FB_CYBER2000
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
- select FB_SOFT_CURSOR
help
This enables support for the Integraphics CyberPro 20x0 and 5000
VGA chips used in the Rebel.com Netwinder and other machines.
@@ -225,7 +211,6 @@ config FB_APOLLO
default y
select FB_CFB_FILLRECT
select FB_CFB_IMAGEBLIT
- select FB_SOFT_CURSOR
config FB_Q40
bool
@@ -234,12 +219,10 @@ config FB_Q40
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
- select FB_SOFT_CURSOR
config FB_AMIGA
tristate "Amiga native chipset support"
depends on FB && AMIGA
- select FB_SOFT_CURSOR
help
This is the frame buffer device driver for the builtin graphics
chipset found in Amigas.
@@ -279,7 +262,6 @@ config FB_CYBER
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
- select FB_SOFT_CURSOR
help
This enables support for the Cybervision 64 graphics card from
Phase5. Please note that its use is not all that intuitive (i.e. if
@@ -294,7 +276,6 @@ config FB_VIRGE
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
- select FB_SOFT_CURSOR
help
This enables support for the Cybervision 64/3D graphics card from
Phase5. Please note that its use is not all that intuitive (i.e. if
@@ -317,7 +298,6 @@ config FB_FM2
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
- select FB_SOFT_CURSOR
help
This is the frame buffer device driver for the Amiga FrameMaster
card from BSC (exhibited 1992 but not shipped as a CBM product).
@@ -328,7 +308,6 @@ config FB_ARC
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
- select FB_SOFT_CURSOR
help
This enables support for the Arc Monochrome LCD board. The board
is based on the KS-108 lcd controller and is typically a matrix
@@ -351,7 +330,6 @@ config FB_OF
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
- select FB_SOFT_CURSOR
select FB_MACMODES
help
Say Y if you want support with Open Firmware for your graphics
@@ -363,7 +341,6 @@ config FB_CONTROL
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
- select FB_SOFT_CURSOR
select FB_MACMODES
help
This driver supports a frame buffer for the graphics adapter in the
@@ -375,7 +352,6 @@ config FB_PLATINUM
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
- select FB_SOFT_CURSOR
select FB_MACMODES
help
This driver supports a frame buffer for the "platinum" graphics
@@ -387,7 +363,6 @@ config FB_VALKYRIE
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
- select FB_SOFT_CURSOR
select FB_MACMODES
help
This driver supports a frame buffer for the "valkyrie" graphics
@@ -399,42 +374,32 @@ config FB_CT65550
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
- select FB_SOFT_CURSOR
help
This is the frame buffer device driver for the Chips & Technologies
65550 graphics chip in PowerBooks.
config FB_ASILIANT
- bool "Chips 69000 display support"
+ bool "Asiliant (Chips) 69000 display support"
depends on (FB = y) && PCI
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
- select FB_SOFT_CURSOR
config FB_IMSTT
bool "IMS Twin Turbo display support"
depends on (FB = y) && PCI
select FB_CFB_IMAGEBLIT
- select FB_SOFT_CURSOR
select FB_MACMODES if PPC
help
The IMS Twin Turbo is a PCI-based frame buffer card bundled with
many Macintosh and compatible computers.
-config FB_S3TRIO
- bool "S3 Trio display support"
- depends on (FB = y) && PPC && BROKEN
- help
- If you have a S3 Trio say Y. Say N for S3 Virge.
-
config FB_VGA16
tristate "VGA 16-color graphics support"
depends on FB && (X86 || PPC)
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
- select FB_SOFT_CURSOR
help
This is the frame buffer device driver for VGA 16 color graphic
cards. Say Y if you have such a card.
@@ -448,7 +413,6 @@ config FB_STI
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
- select FB_SOFT_CURSOR
default y
---help---
STI refers to the HP "Standard Text Interface" which is a set of
@@ -469,7 +433,6 @@ config FB_MAC
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
- select FB_SOFT_CURSOR
select FB_MACMODES
# bool ' Apple DAFB display support' CONFIG_FB_DAFB
@@ -478,7 +441,6 @@ config FB_HP300
depends on (FB = y) && HP300
select FB_CFB_FILLRECT
select FB_CFB_IMAGEBLIT
- select FB_SOFT_CURSOR
default y
config FB_TGA
@@ -487,18 +449,16 @@ config FB_TGA
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
- select FB_SOFT_CURSOR
help
This is the frame buffer device driver for generic TGA graphic
cards. Say Y if you have one of those.
config FB_VESA
bool "VESA VGA graphics support"
- depends on (FB = y) && (X86 || X86_64)
+ depends on (FB = y) && X86
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
- select FB_SOFT_CURSOR
help
This is the frame buffer device driver for generic VESA 2.0
compliant graphic cards. The older VESA 1.2 cards are not supported.
@@ -516,7 +476,6 @@ config FB_HGA
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
- select FB_SOFT_CURSOR
help
Say Y here if you have a Hercules mono graphics card.
@@ -545,7 +504,6 @@ config FB_SGIVW
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
- select FB_SOFT_CURSOR
help
SGI Visual Workstation support for framebuffer graphics.
@@ -555,7 +513,6 @@ config FB_GBE
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
- select FB_SOFT_CURSOR
help
This is the frame buffer device driver for SGI Graphics Backend.
This chip is used in SGI O2 and Visual Workstation 320/540.
@@ -583,7 +540,6 @@ config FB_BW2
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
- select FB_SOFT_CURSOR
help
This is the frame buffer device driver for the BWtwo frame buffer.
@@ -592,7 +548,6 @@ config FB_CG3
depends on (FB = y) && ((SPARC32 || SPARC64) && FB_SBUS || (SUN3 || SUN3X) && FB_SUN3)
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
- select FB_SOFT_CURSOR
help
This is the frame buffer device driver for the CGthree frame buffer.
@@ -601,7 +556,6 @@ config FB_CG6
depends on (FB = y) && ((SPARC32 || SPARC64) && FB_SBUS || (SUN3 || SUN3X) && FB_SUN3)
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
- select FB_SOFT_CURSOR
help
This is the frame buffer device driver for the CGsix (GX, TurboGX)
frame buffer.
@@ -612,7 +566,6 @@ config FB_PVR2
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
- select FB_SOFT_CURSOR
---help---
Say Y here if you have a PowerVR 2 card in your box. If you plan to
run linux on your Dreamcast, you will have to say Y here.
@@ -634,13 +587,23 @@ config FB_EPSON1355
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
- select FB_SOFT_CURSOR
help
Build in support for the SED1355 Epson Research Embedded RAMDAC
LCD/CRT Controller (since redesignated as the S1D13505) as a
framebuffer. Product specs at
<http://www.erd.epson.com/vdc/html/products.htm>.
+config FB_S1D13XXX
+ tristate "Epson S1D13XXX framebuffer support"
+ depends on FB
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ help
+ Support for S1D13XXX framebuffer device family (currently only
+ working with S1D13806). Product specs at
+ <http://www.erd.epson.com/vdc/html/legacy_13xxx.htm>
+
config FB_NVIDIA
tristate "nVidia Framebuffer Support"
depends on FB && PCI
@@ -650,7 +613,6 @@ config FB_NVIDIA
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
- select FB_SOFT_CURSOR
help
This driver supports graphics boards with the nVidia chips, TNT
and newer. For very old chipsets, such as the RIVA128, then use
@@ -662,7 +624,7 @@ config FB_NVIDIA
config FB_NVIDIA_I2C
bool "Enable DDC Support"
- depends on FB_NVIDIA && !PPC_OF
+ depends on FB_NVIDIA
help
This enables I2C support for nVidia Chipsets. This is used
only for getting EDID information from the attached display
@@ -712,7 +674,7 @@ config FB_RIVA_DEBUG
config FB_I810
tristate "Intel 810/815 support (EXPERIMENTAL)"
- depends on FB && EXPERIMENTAL && PCI && X86 && !X86_64
+ depends on FB && EXPERIMENTAL && PCI && X86_32
select AGP
select AGP_INTEL
select FB_MODE_HELPERS
@@ -761,14 +723,13 @@ config FB_I810_I2C
config FB_INTEL
tristate "Intel 830M/845G/852GM/855GM/865G support (EXPERIMENTAL)"
- depends on FB && EXPERIMENTAL && PCI && X86 && !X86_64
+ depends on FB && EXPERIMENTAL && PCI && X86_32
select AGP
select AGP_INTEL
select FB_MODE_HELPERS
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
- select FB_SOFT_CURSOR
help
This driver supports the on-board graphics built in to the Intel
830M/845G/852GM/855GM/865G chipsets.
@@ -791,7 +752,6 @@ config FB_MATROX
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
- select FB_SOFT_CURSOR
select FB_TILEBLITTING
select FB_MACMODES if PPC_PMAC
---help---
@@ -932,7 +892,6 @@ config FB_RADEON_OLD
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
- select FB_SOFT_CURSOR
select FB_MACMODES if PPC
help
Choose this option if you want to use an ATI Radeon graphics card as
@@ -950,7 +909,6 @@ config FB_RADEON
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
- select FB_SOFT_CURSOR
select FB_MACMODES if PPC_OF
help
Choose this option if you want to use an ATI Radeon graphics card as
@@ -988,7 +946,6 @@ config FB_ATY128
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
- select FB_SOFT_CURSOR
select FB_MACMODES if PPC_PMAC
help
This driver supports graphics boards with the ATI Rage128 chips.
@@ -1004,7 +961,6 @@ config FB_ATY
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
- select FB_SOFT_CURSOR
select FB_MACMODES if PPC
help
This driver supports graphics boards with the ATI Mach64 chips.
@@ -1047,6 +1003,12 @@ config FB_ATY_GX
is at
<http://support.ati.com/products/pc/mach64/graphics_xpression.html>.
+config FB_S3TRIO
+ bool "S3 Trio display support"
+ depends on (FB = y) && PPC && BROKEN
+ help
+ If you have a S3 Trio say Y. Say N for S3 Virge.
+
config FB_SAVAGE
tristate "S3 Savage support"
depends on FB && PCI && EXPERIMENTAL
@@ -1056,7 +1018,6 @@ config FB_SAVAGE
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
- select FB_SOFT_CURSOR
help
This driver supports notebooks and computers with S3 Savage PCI/AGP
chips.
@@ -1093,7 +1054,6 @@ config FB_SIS
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
- select FB_SOFT_CURSOR
help
This is the frame buffer device driver for the SiS 300, 315, 330
and 340 series as well as XGI V3XT, V5, V8, Z7 graphics chipsets.
@@ -1123,7 +1083,6 @@ config FB_NEOMAGIC
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
- select FB_SOFT_CURSOR
help
This driver supports notebooks with NeoMagic PCI chips.
Say Y if you have such a graphics card.
@@ -1137,7 +1096,6 @@ config FB_KYRO
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
- select FB_SOFT_CURSOR
help
Say Y here if you have a STG4000 / Kyro / PowerVR 3 based
graphics board.
@@ -1151,7 +1109,6 @@ config FB_3DFX
select FB_CFB_IMAGEBLIT
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
- select FB_SOFT_CURSOR
help
This driver supports graphics boards with the 3Dfx Banshee/Voodoo3
chips. Say Y if you have such a graphics board.
@@ -1173,7 +1130,6 @@ config FB_VOODOO1
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
- select FB_SOFT_CURSOR
---help---
Say Y here if you have a 3Dfx Voodoo Graphics (Voodoo1/sst1) or
Voodoo2 (cvg) based graphics card.
@@ -1190,7 +1146,6 @@ config FB_CYBLA
tristate "Cyberblade/i1 support"
depends on FB && PCI
select FB_CFB_IMAGEBLIT
- select FB_SOFT_CURSOR
select VIDEO_SELECT
---help---
This driver is supposed to support the Trident Cyberblade/i1
@@ -1218,7 +1173,6 @@ config FB_TRIDENT
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
- select FB_SOFT_CURSOR
---help---
This driver is supposed to support graphics boards with the
Trident CyberXXXX/Image/CyberBlade chips mostly found in laptops
@@ -1250,38 +1204,6 @@ config FB_PM3
similar boards, 3DLabs Permedia3 Create!, Appian Jeronimo 2000
and maybe other boards.
-config FB_E1356
- tristate "Epson SED1356 framebuffer support"
- depends on FB && EXPERIMENTAL && PCI && MIPS
-
-config PB1000_CRT
- bool "Use CRT on Pb1000 (J65)"
- depends on MIPS_PB1000=y && FB_E1356
-
-config PB1000_NTSC
- bool "Use Compsite NTSC on Pb1000 (J63)"
- depends on MIPS_PB1000=y && FB_E1356
-
-config PB1000_TFT
- bool "Use TFT Panel on Pb1000 (J64)"
- depends on MIPS_PB1000=y && FB_E1356
-
-config PB1500_CRT
- bool "Use CRT on Pb1500 " if MIPS_PB1500=y
- depends on FB_E1356
-
-config PB1500_CRT
- prompt "Use CRT on Pb1100 "
- depends on FB_E1356 && MIPS_PB1100=y
-
-config PB1500_TFT
- bool "Use TFT Panel on Pb1500 " if MIPS_PB1500=y
- depends on FB_E1356
-
-config PB1500_TFT
- prompt "Use TFT Panel on Pb1100 "
- depends on FB_E1356 && MIPS_PB1100=y
-
config FB_AU1100
bool "Au1100 LCD Driver"
depends on (FB = y) && EXPERIMENTAL && PCI && MIPS && MIPS_PB1100=y
@@ -1299,7 +1221,6 @@ config FB_FFB
depends on FB_SBUS && SPARC64
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
- select FB_SOFT_CURSOR
help
This is the frame buffer device driver for the Creator, Creator3D,
and Elite3D graphics boards.
@@ -1310,7 +1231,6 @@ config FB_TCX
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
- select FB_SOFT_CURSOR
help
This is the frame buffer device driver for the TCX 24/8bit frame
buffer.
@@ -1321,7 +1241,6 @@ config FB_CG14
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
- select FB_SOFT_CURSOR
help
This is the frame buffer device driver for the CGfourteen frame
buffer on Desktop SPARCsystems with the SX graphics option.
@@ -1332,7 +1251,6 @@ config FB_P9100
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
- select FB_SOFT_CURSOR
help
This is the frame buffer device driver for the P9100 card
supported on Sparcbook 3 machines.
@@ -1343,7 +1261,6 @@ config FB_LEO
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
- select FB_SOFT_CURSOR
help
This is the frame buffer device driver for the SBUS-based Sun ZX
(leo) frame buffer cards.
@@ -1358,7 +1275,6 @@ config FB_IGA
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
- select FB_SOFT_CURSOR
help
This is the framebuffer device for the INTERGRAPHICS 1680 and
successor frame buffer cards.
@@ -1369,40 +1285,36 @@ config FB_HIT
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
- select FB_SOFT_CURSOR
help
This is the frame buffer device driver for the Hitachi HD64461 LCD
frame buffer card.
config FB_PMAG_AA
bool "PMAG-AA TURBOchannel framebuffer support"
- depends on (FB = y) && MACH_DECSTATION && TC
+ depends on (FB = y) && TC
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
- select FB_SOFT_CURSOR
help
Support for the PMAG-AA TURBOchannel framebuffer card (1280x1024x1)
used mainly in the MIPS-based DECstation series.
config FB_PMAG_BA
bool "PMAG-BA TURBOchannel framebuffer support"
- depends on (FB = y) && MACH_DECSTATION && TC
+ depends on (FB = y) && TC
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
- select FB_SOFT_CURSOR
help
Support for the PMAG-BA TURBOchannel framebuffer card (1024x864x8)
used mainly in the MIPS-based DECstation series.
config FB_PMAGB_B
bool "PMAGB-B TURBOchannel framebuffer support"
- depends on (FB = y) && MACH_DECSTATION && TC
+ depends on (FB = y) && TC
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
- select FB_SOFT_CURSOR
help
Support for the PMAGB-B TURBOchannel framebuffer card used mainly
in the MIPS-based DECstation series. The card is currently only
@@ -1410,11 +1322,10 @@ config FB_PMAGB_B
config FB_MAXINE
bool "Maxine (Personal DECstation) onboard framebuffer support"
- depends on (FB = y) && MACH_DECSTATION && TC
+ depends on (FB = y) && MACH_DECSTATION
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
- select FB_SOFT_CURSOR
help
Support for the onboard framebuffer (1024x768x8) in the Personal
DECstation series (Personal DECstation 5000/20, /25, /33, /50,
@@ -1426,7 +1337,6 @@ config FB_TX3912
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
- select FB_SOFT_CURSOR
help
The TX3912 is a Toshiba RISC processor based on the MIPS 3900 core
see <http://www.toshiba.com/taec/components/Generic/risc/tx3912.htm>.
@@ -1439,7 +1349,6 @@ config FB_G364
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
- select FB_SOFT_CURSOR
help
The G364 driver is the framebuffer used in MIPS Magnum 4000 and
Olivetti M700-10 systems.
@@ -1450,7 +1359,6 @@ config FB_68328
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
- select FB_SOFT_CURSOR
help
Say Y here if you want to support the built-in frame buffer of
the Motorola 68328 CPU family.
@@ -1461,7 +1369,6 @@ config FB_PXA
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
- select FB_SOFT_CURSOR
---help---
Frame buffer driver for the built-in LCD controller in the Intel
PXA2x0 processor.
@@ -1473,23 +1380,6 @@ config FB_PXA
If unsure, say N.
-config FB_W100
- tristate "W100 frame buffer support"
- depends on FB && PXA_SHARPSL
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- select FB_SOFT_CURSOR
- ---help---
- Frame buffer driver for the w100 as found on the Sharp SL-Cxx series.
-
- This driver is also available as a module ( = code which can be
- inserted and removed from the running kernel whenever you want). The
- module will be called vfb. If you want to compile it as a module,
- say M here and read <file:Documentation/modules.txt>.
-
- If unsure, say N.
-
config FB_PXA_PARAMETERS
bool "PXA LCD command line parameters"
default n
@@ -1507,17 +1397,21 @@ config FB_PXA_PARAMETERS
<file:Documentation/fb/pxafb.txt> describes the available parameters.
-config FB_S1D13XXX
- tristate "Epson S1D13XXX framebuffer support"
- depends on FB
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- select FB_SOFT_CURSOR
- help
- Support for S1D13XXX framebuffer device family (currently only
- working with S1D13806). Product specs at
- <http://www.erd.epson.com/vdc/html/legacy_13xxx.htm>
+config FB_W100
+ tristate "W100 frame buffer support"
+ depends on FB && PXA_SHARPSL
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ ---help---
+ Frame buffer driver for the w100 as found on the Sharp SL-Cxx series.
+
+ This driver is also available as a module ( = code which can be
+ inserted and removed from the running kernel whenever you want). The
+ module will be called vfb. If you want to compile it as a module,
+ say M here and read <file:Documentation/modules.txt>.
+
+ If unsure, say N.
config FB_S3C2410
tristate "S3C2410 LCD framebuffer support"
@@ -1525,7 +1419,6 @@ config FB_S3C2410
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
- select FB_SOFT_CURSOR
---help---
Frame buffer driver for the built-in LCD controller in the Samsung
S3C2410 processor.
@@ -1549,7 +1442,6 @@ config FB_VIRTUAL
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
- select FB_SOFT_CURSOR
---help---
This is a `virtual' frame buffer device. It operates on a chunk of
unswappable kernel memory instead of on the memory of a graphics
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index 1fff29f48ca8..aa434e725c0d 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -16,7 +16,6 @@ fb-objs := $(fb-y)
obj-$(CONFIG_FB_CFB_FILLRECT) += cfbfillrect.o
obj-$(CONFIG_FB_CFB_COPYAREA) += cfbcopyarea.o
obj-$(CONFIG_FB_CFB_IMAGEBLIT) += cfbimgblt.o
-obj-$(CONFIG_FB_SOFT_CURSOR) += softcursor.o
obj-$(CONFIG_FB_MACMODES) += macmodes.o
# Hardware specific drivers go first
@@ -86,7 +85,7 @@ obj-$(CONFIG_FB_CIRRUS) += cirrusfb.o
obj-$(CONFIG_FB_ASILIANT) += asiliantfb.o
obj-$(CONFIG_FB_PXA) += pxafb.o
obj-$(CONFIG_FB_W100) += w100fb.o
-obj-$(CONFIG_FB_AU1100) += au1100fb.o fbgen.o
+obj-$(CONFIG_FB_AU1100) += au1100fb.o
obj-$(CONFIG_FB_PMAG_AA) += pmag-aa-fb.o
obj-$(CONFIG_FB_PMAG_BA) += pmag-ba-fb.o
obj-$(CONFIG_FB_PMAGB_B) += pmagb-b-fb.o
diff --git a/drivers/video/acornfb.c b/drivers/video/acornfb.c
index f02965f39501..193b482570c7 100644
--- a/drivers/video/acornfb.c
+++ b/drivers/video/acornfb.c
@@ -26,7 +26,7 @@
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/fb.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
#include <asm/hardware.h>
@@ -926,7 +926,6 @@ static struct fb_ops acornfb_ops = {
.fb_copyarea = cfb_copyarea,
.fb_imageblit = cfb_imageblit,
.fb_mmap = acornfb_mmap,
- .fb_cursor = soft_cursor,
};
/*
diff --git a/drivers/video/amba-clcd.c b/drivers/video/amba-clcd.c
index 321dbe91dc14..a3c2c45e29e0 100644
--- a/drivers/video/amba-clcd.c
+++ b/drivers/video/amba-clcd.c
@@ -22,6 +22,7 @@
#include <linux/ioport.h>
#include <linux/list.h>
+#include <asm/sizes.h>
#include <asm/hardware/amba.h>
#include <asm/hardware/clock.h>
@@ -332,7 +333,6 @@ static struct fb_ops clcdfb_ops = {
.fb_fillrect = cfb_fillrect,
.fb_copyarea = cfb_copyarea,
.fb_imageblit = cfb_imageblit,
- .fb_cursor = soft_cursor,
.fb_mmap = clcdfb_mmap,
};
@@ -504,21 +504,21 @@ static int clcdfb_remove(struct amba_device *dev)
static struct amba_id clcdfb_id_table[] = {
{
.id = 0x00041110,
- .mask = 0x000fffff,
+ .mask = 0x000ffffe,
},
{ 0, 0 },
};
static struct amba_driver clcd_driver = {
.drv = {
- .name = "clcd-pl110",
+ .name = "clcd-pl11x",
},
.probe = clcdfb_probe,
.remove = clcdfb_remove,
.id_table = clcdfb_id_table,
};
-int __init amba_clcdfb_init(void)
+static int __init amba_clcdfb_init(void)
{
if (fb_get_options("ambafb", NULL))
return -ENODEV;
diff --git a/drivers/video/amifb.c b/drivers/video/amifb.c
index cf8bb67462dc..d549e215f3c5 100644
--- a/drivers/video/amifb.c
+++ b/drivers/video/amifb.c
@@ -1185,7 +1185,6 @@ static struct fb_ops amifb_ops = {
.fb_fillrect = amifb_fillrect,
.fb_copyarea = amifb_copyarea,
.fb_imageblit = amifb_imageblit,
- .fb_cursor = soft_cursor,
.fb_ioctl = amifb_ioctl,
};
diff --git a/drivers/video/arcfb.c b/drivers/video/arcfb.c
index d28457e0c063..a1fc8bbb1090 100644
--- a/drivers/video/arcfb.c
+++ b/drivers/video/arcfb.c
@@ -47,6 +47,7 @@
#include <linux/fb.h>
#include <linux/init.h>
#include <linux/arcfb.h>
+#include <linux/platform_device.h>
#include <asm/uaccess.h>
@@ -501,10 +502,6 @@ static ssize_t arcfb_write(struct file *file, const char *buf, size_t count,
return err;
}
-static void arcfb_platform_release(struct device *device)
-{
-}
-
static struct fb_ops arcfb_ops = {
.owner = THIS_MODULE,
.fb_open = arcfb_open,
@@ -514,7 +511,6 @@ static struct fb_ops arcfb_ops = {
.fb_fillrect = arcfb_fillrect,
.fb_copyarea = arcfb_copyarea,
.fb_imageblit = arcfb_imageblit,
- .fb_cursor = soft_cursor,
.fb_ioctl = arcfb_ioctl,
};
@@ -623,13 +619,7 @@ static struct device_driver arcfb_driver = {
.remove = arcfb_remove,
};
-static struct platform_device arcfb_device = {
- .name = "arcfb",
- .id = 0,
- .dev = {
- .release = arcfb_platform_release,
- }
-};
+static struct platform_device *arcfb_device;
static int __init arcfb_init(void)
{
@@ -640,9 +630,16 @@ static int __init arcfb_init(void)
ret = driver_register(&arcfb_driver);
if (!ret) {
- ret = platform_device_register(&arcfb_device);
- if (ret)
+ arcfb_device = platform_device_alloc("arcfb", 0);
+ if (arcfb_device) {
+ ret = platform_device_add(arcfb_device);
+ } else {
+ ret = -ENOMEM;
+ }
+ if (ret) {
+ platform_device_put(arcfb_device);
driver_unregister(&arcfb_driver);
+ }
}
return ret;
@@ -650,7 +647,7 @@ static int __init arcfb_init(void)
static void __exit arcfb_exit(void)
{
- platform_device_unregister(&arcfb_device);
+ platform_device_unregister(arcfb_device);
driver_unregister(&arcfb_driver);
}
diff --git a/drivers/video/asiliantfb.c b/drivers/video/asiliantfb.c
index f4729f4df8ce..c64de59398f4 100644
--- a/drivers/video/asiliantfb.c
+++ b/drivers/video/asiliantfb.c
@@ -106,7 +106,6 @@ static struct fb_ops asiliantfb_ops = {
.fb_fillrect = cfb_fillrect,
.fb_copyarea = cfb_copyarea,
.fb_imageblit = cfb_imageblit,
- .fb_cursor = soft_cursor,
};
/* Calculate the ratios for the dot clocks without using a single long long
diff --git a/drivers/video/aty/ati_ids.h b/drivers/video/aty/ati_ids.h
index 13321c689cf6..39ab483fc250 100644
--- a/drivers/video/aty/ati_ids.h
+++ b/drivers/video/aty/ati_ids.h
@@ -150,6 +150,7 @@
#define PCI_CHIP_RV200_QX 0x5158
#define PCI_CHIP_RV100_QY 0x5159
#define PCI_CHIP_RV100_QZ 0x515A
+#define PCI_CHIP_RN50 0x515E
#define PCI_CHIP_RAGE128RE 0x5245
#define PCI_CHIP_RAGE128RF 0x5246
#define PCI_CHIP_RAGE128RG 0x5247
diff --git a/drivers/video/aty/aty128fb.c b/drivers/video/aty/aty128fb.c
index e380ee8b0247..e686185a076d 100644
--- a/drivers/video/aty/aty128fb.c
+++ b/drivers/video/aty/aty128fb.c
@@ -478,7 +478,6 @@ static struct fb_ops aty128fb_ops = {
.fb_fillrect = cfb_fillrect,
.fb_copyarea = cfb_copyarea,
.fb_imageblit = cfb_imageblit,
- .fb_cursor = soft_cursor,
};
#ifdef CONFIG_PMAC_BACKLIGHT
diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c
index 037fe9d32fe3..08edbfcfca58 100644
--- a/drivers/video/aty/atyfb_base.c
+++ b/drivers/video/aty/atyfb_base.c
@@ -292,7 +292,6 @@ static struct fb_ops atyfb_ops = {
.fb_fillrect = atyfb_fillrect,
.fb_copyarea = atyfb_copyarea,
.fb_imageblit = atyfb_imageblit,
- .fb_cursor = soft_cursor,
#ifdef __sparc__
.fb_mmap = atyfb_mmap,
#endif
@@ -2157,11 +2156,38 @@ static void __init aty_calc_mem_refresh(struct atyfb_par *par, int xclk)
static struct fb_info *fb_list = NULL;
+#if defined(__i386__) && defined(CONFIG_FB_ATY_GENERIC_LCD)
+static int __devinit atyfb_get_timings_from_lcd(struct atyfb_par *par,
+ struct fb_var_screeninfo *var)
+{
+ int ret = -EINVAL;
+
+ if (par->lcd_table != 0 && (aty_ld_lcd(LCD_GEN_CNTL, par) & LCD_ON)) {
+ *var = default_var;
+ var->xres = var->xres_virtual = par->lcd_hdisp;
+ var->right_margin = par->lcd_right_margin;
+ var->left_margin = par->lcd_hblank_len -
+ (par->lcd_right_margin + par->lcd_hsync_dly +
+ par->lcd_hsync_len);
+ var->hsync_len = par->lcd_hsync_len + par->lcd_hsync_dly;
+ var->yres = var->yres_virtual = par->lcd_vdisp;
+ var->lower_margin = par->lcd_lower_margin;
+ var->upper_margin = par->lcd_vblank_len -
+ (par->lcd_lower_margin + par->lcd_vsync_len);
+ var->vsync_len = par->lcd_vsync_len;
+ var->pixclock = par->lcd_pixclock;
+ ret = 0;
+ }
+
+ return ret;
+}
+#endif /* defined(__i386__) && defined(CONFIG_FB_ATY_GENERIC_LCD) */
+
static int __init aty_init(struct fb_info *info, const char *name)
{
struct atyfb_par *par = (struct atyfb_par *) info->par;
const char *ramname = NULL, *xtal;
- int gtb_memsize;
+ int gtb_memsize, has_var = 0;
struct fb_var_screeninfo var;
u8 pll_ref_div;
u32 i;
@@ -2469,8 +2495,8 @@ static int __init aty_init(struct fb_info *info, const char *name)
* applies to all Mac video cards
*/
if (mode) {
- if (!mac_find_mode(&var, info, mode, 8))
- var = default_var;
+ if (mac_find_mode(&var, info, mode, 8))
+ has_var = 1;
} else {
if (default_vmode == VMODE_CHOOSE) {
if (M64_HAS(G3_PB_1024x768))
@@ -2492,20 +2518,23 @@ static int __init aty_init(struct fb_info *info, const char *name)
default_vmode = VMODE_640_480_60;
if (default_cmode < CMODE_8 || default_cmode > CMODE_32)
default_cmode = CMODE_8;
- if (mac_vmode_to_var(default_vmode, default_cmode, &var))
- var = default_var;
+ if (!mac_vmode_to_var(default_vmode, default_cmode,
+ &var))
+ has_var = 1;
}
- } else
+ }
+
#endif /* !CONFIG_PPC */
- if (
-#if defined(CONFIG_SPARC32) || defined(CONFIG_SPARC64)
- /* On Sparc, unless the user gave a specific mode
- * specification, use the PROM probed values in
- * default_var.
- */
- !mode ||
+
+#if defined(__i386__) && defined(CONFIG_FB_ATY_GENERIC_LCD)
+ if (!atyfb_get_timings_from_lcd(par, &var))
+ has_var = 1;
#endif
- !fb_find_mode(&var, info, mode, NULL, 0, &defmode, 8))
+
+ if (mode && fb_find_mode(&var, info, mode, NULL, 0, &defmode, 8))
+ has_var = 1;
+
+ if (!has_var)
var = default_var;
if (noaccel)
diff --git a/drivers/video/aty/radeon_base.c b/drivers/video/aty/radeon_base.c
index 8a24a66d9ba8..4f01ccc02aa4 100644
--- a/drivers/video/aty/radeon_base.c
+++ b/drivers/video/aty/radeon_base.c
@@ -69,7 +69,6 @@
#include <linux/pci.h>
#include <linux/vmalloc.h>
#include <linux/device.h>
-#include <linux/i2c.h>
#include <asm/io.h>
#include <asm/uaccess.h>
@@ -113,6 +112,7 @@ static struct pci_device_id radeonfb_pci_table[] = {
/* Radeon VE/7000 */
CHIP_DEF(PCI_CHIP_RV100_QY, RV100, CHIP_HAS_CRTC2),
CHIP_DEF(PCI_CHIP_RV100_QZ, RV100, CHIP_HAS_CRTC2),
+ CHIP_DEF(PCI_CHIP_RN50, RV100, CHIP_HAS_CRTC2),
/* Radeon IGP320M (U1) */
CHIP_DEF(PCI_CHIP_RS100_4336, RS100, CHIP_HAS_CRTC2 | CHIP_IS_IGP | CHIP_IS_MOBILITY),
/* Radeon IGP320 (A3) */
@@ -1874,7 +1874,6 @@ static struct fb_ops radeonfb_ops = {
.fb_fillrect = radeonfb_fillrect,
.fb_copyarea = radeonfb_copyarea,
.fb_imageblit = radeonfb_imageblit,
- .fb_cursor = soft_cursor,
};
diff --git a/drivers/video/aty/radeonfb.h b/drivers/video/aty/radeonfb.h
index 01b8b2f78514..217e00ab4a2d 100644
--- a/drivers/video/aty/radeonfb.h
+++ b/drivers/video/aty/radeonfb.h
@@ -10,9 +10,10 @@
#include <linux/fb.h>
+#ifdef CONFIG_FB_RADEON_I2C
#include <linux/i2c.h>
-#include <linux/i2c-id.h>
#include <linux/i2c-algo-bit.h>
+#endif
#include <asm/io.h>
diff --git a/drivers/video/au1100fb.c b/drivers/video/au1100fb.c
index b6fe30c3ad62..a5129806172f 100644
--- a/drivers/video/au1100fb.c
+++ b/drivers/video/au1100fb.c
@@ -2,6 +2,11 @@
* BRIEF MODULE DESCRIPTION
* Au1100 LCD Driver.
*
+ * Rewritten for 2.6 by Embedded Alley Solutions
+ * <source@embeddedalley.com>, based on submissions by
+ * Karl Lessard <klessard@sunrisetelecom.com>
+ * <c.pellegrin@exadron.com>
+ *
* Copyright 2002 MontaVista Software
* Author: MontaVista Software, Inc.
* ppopov@mvista.com or source@mvista.com
@@ -33,298 +38,253 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-
+#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
-#include <linux/tty.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
#include <linux/fb.h>
#include <linux/init.h>
-#include <linux/pci.h>
+#include <linux/interrupt.h>
+#include <linux/ctype.h>
+#include <linux/dma-mapping.h>
-#include <asm/au1000.h>
-#include <asm/pb1100.h>
-#include "au1100fb.h"
+#include <asm/mach-au1x00/au1000.h>
-#include <video/fbcon.h>
-#include <video/fbcon-mfb.h>
-#include <video/fbcon-cfb2.h>
-#include <video/fbcon-cfb4.h>
-#include <video/fbcon-cfb8.h>
-#include <video/fbcon-cfb16.h>
+#define DEBUG 0
+
+#include "au1100fb.h"
/*
* Sanity check. If this is a new Au1100 based board, search for
* the PB1100 ifdefs to make sure you modify the code accordingly.
*/
-#if defined(CONFIG_MIPS_PB1100) || defined(CONFIG_MIPS_DB1100) || defined(CONFIG_MIPS_HYDROGEN3)
+#if defined(CONFIG_MIPS_PB1100)
+ #include <asm/mach-pb1x00/pb1100.h>
+#elif defined(CONFIG_MIPS_DB1100)
+ #include <asm/mach-db1x00/db1x00.h>
#else
-error Unknown Au1100 board
+ #error "Unknown Au1100 board, Au1100 FB driver not supported"
#endif
-#define CMAPSIZE 16
-
-static int my_lcd_index; /* default is zero */
-struct known_lcd_panels *p_lcd;
-AU1100_LCD *p_lcd_reg = (AU1100_LCD *)AU1100_LCD_ADDR;
-
-struct au1100fb_info {
- struct fb_info_gen gen;
- unsigned long fb_virt_start;
- unsigned long fb_size;
- unsigned long fb_phys;
- int mmaped;
- int nohwcursor;
+#define DRIVER_NAME "au1100fb"
+#define DRIVER_DESC "LCD controller driver for AU1100 processors"
- struct { unsigned red, green, blue, pad; } palette[256];
+#define to_au1100fb_device(_info) \
+ (_info ? container_of(_info, struct au1100fb_device, info) : NULL);
-#if defined(FBCON_HAS_CFB16)
- u16 fbcon_cmap16[16];
-#endif
+/* Bitfields format supported by the controller. Note that the order of formats
+ * SHOULD be the same as in the LCD_CONTROL_SBPPF field, so we can retrieve the
+ * right pixel format by doing rgb_bitfields[LCD_CONTROL_SBPPF_XXX >> LCD_CONTROL_SBPPF]
+ */
+struct fb_bitfield rgb_bitfields[][4] =
+{
+ /* Red, Green, Blue, Transp */
+ { { 10, 6, 0 }, { 5, 5, 0 }, { 0, 5, 0 }, { 0, 0, 0 } },
+ { { 11, 5, 0 }, { 5, 6, 0 }, { 0, 5, 0 }, { 0, 0, 0 } },
+ { { 11, 5, 0 }, { 6, 5, 0 }, { 0, 6, 0 }, { 0, 0, 0 } },
+ { { 10, 5, 0 }, { 5, 5, 0 }, { 0, 5, 0 }, { 15, 1, 0 } },
+ { { 11, 5, 0 }, { 6, 5, 0 }, { 1, 5, 0 }, { 0, 1, 0 } },
+
+ /* The last is used to describe 12bpp format */
+ { { 8, 4, 0 }, { 4, 4, 0 }, { 0, 4, 0 }, { 0, 0, 0 } },
};
-
-struct au1100fb_par {
- struct fb_var_screeninfo var;
-
- int line_length; // in bytes
- int cmap_len; // color-map length
+static struct fb_fix_screeninfo au1100fb_fix __initdata = {
+ .id = "AU1100 FB",
+ .xpanstep = 1,
+ .ypanstep = 1,
+ .type = FB_TYPE_PACKED_PIXELS,
+ .accel = FB_ACCEL_NONE,
};
-
-static struct au1100fb_info fb_info;
-static struct au1100fb_par current_par;
-static struct display disp;
-
-int au1100fb_init(void);
-void au1100fb_setup(char *options, int *ints);
-static int au1100fb_mmap(struct fb_info *fb, struct file *file,
- struct vm_area_struct *vma);
-static int au1100_blank(int blank_mode, struct fb_info_gen *info);
-static int au1100fb_ioctl(struct inode *inode, struct file *file, u_int cmd,
- u_long arg, int con, struct fb_info *info);
-
-void au1100_nocursor(struct display *p, int mode, int xx, int yy){};
-
-static struct fb_ops au1100fb_ops = {
- .owner = THIS_MODULE,
- .fb_get_fix = fbgen_get_fix,
- .fb_get_var = fbgen_get_var,
- .fb_set_var = fbgen_set_var,
- .fb_get_cmap = fbgen_get_cmap,
- .fb_set_cmap = fbgen_set_cmap,
- .fb_pan_display = fbgen_pan_display,
- .fb_ioctl = au1100fb_ioctl,
- .fb_mmap = au1100fb_mmap,
+static struct fb_var_screeninfo au1100fb_var __initdata = {
+ .activate = FB_ACTIVATE_NOW,
+ .height = -1,
+ .width = -1,
+ .vmode = FB_VMODE_NONINTERLACED,
};
-static void au1100_detect(void)
-{
- /*
- * This function should detect the current video mode settings
- * and store it as the default video mode
- */
+static struct au1100fb_drv_info drv_info;
- /*
- * Yeh, well, we're not going to change any settings so we're
- * always stuck with the default ...
+/*
+ * Set hardware with var settings. This will enable the controller with a specific
+ * mode, normally validated with the fb_check_var method
*/
-
-}
-
-static int au1100_encode_fix(struct fb_fix_screeninfo *fix,
- const void *_par, struct fb_info_gen *_info)
+int au1100fb_setmode(struct au1100fb_device *fbdev)
{
- struct au1100fb_info *info = (struct au1100fb_info *) _info;
- struct au1100fb_par *par = (struct au1100fb_par *) _par;
- struct fb_var_screeninfo *var = &par->var;
-
- memset(fix, 0, sizeof(struct fb_fix_screeninfo));
-
- fix->smem_start = info->fb_phys;
- fix->smem_len = info->fb_size;
- fix->type = FB_TYPE_PACKED_PIXELS;
- fix->type_aux = 0;
- fix->visual = (var->bits_per_pixel == 8) ?
- FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR;
- fix->ywrapstep = 0;
- fix->xpanstep = 1;
- fix->ypanstep = 1;
- fix->line_length = current_par.line_length;
- return 0;
-}
+ struct fb_info *info = &fbdev->info;
+ u32 words;
+ int index;
-static void set_color_bitfields(struct fb_var_screeninfo *var)
-{
- switch (var->bits_per_pixel) {
- case 8:
- var->red.offset = 0;
- var->red.length = 8;
- var->green.offset = 0;
- var->green.length = 8;
- var->blue.offset = 0;
- var->blue.length = 8;
- var->transp.offset = 0;
- var->transp.length = 0;
- break;
- case 16: /* RGB 565 */
- var->red.offset = 11;
- var->red.length = 5;
- var->green.offset = 5;
- var->green.length = 6;
- var->blue.offset = 0;
- var->blue.length = 5;
- var->transp.offset = 0;
- var->transp.length = 0;
- break;
+ if (!fbdev)
+ return -EINVAL;
+
+ /* Update var-dependent FB info */
+ if (panel_is_active(fbdev->panel) || panel_is_color(fbdev->panel)) {
+ if (info->var.bits_per_pixel <= 8) {
+ /* palettized */
+ info->var.red.offset = 0;
+ info->var.red.length = info->var.bits_per_pixel;
+ info->var.red.msb_right = 0;
+
+ info->var.green.offset = 0;
+ info->var.green.length = info->var.bits_per_pixel;
+ info->var.green.msb_right = 0;
+
+ info->var.blue.offset = 0;
+ info->var.blue.length = info->var.bits_per_pixel;
+ info->var.blue.msb_right = 0;
+
+ info->var.transp.offset = 0;
+ info->var.transp.length = 0;
+ info->var.transp.msb_right = 0;
+
+ info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
+ info->fix.line_length = info->var.xres_virtual /
+ (8/info->var.bits_per_pixel);
+ } else {
+ /* non-palettized */
+ index = (fbdev->panel->control_base & LCD_CONTROL_SBPPF_MASK) >> LCD_CONTROL_SBPPF_BIT;
+ info->var.red = rgb_bitfields[index][0];
+ info->var.green = rgb_bitfields[index][1];
+ info->var.blue = rgb_bitfields[index][2];
+ info->var.transp = rgb_bitfields[index][3];
+
+ info->fix.visual = FB_VISUAL_TRUECOLOR;
+ info->fix.line_length = info->var.xres_virtual << 1; /* depth=16 */
+ }
+ } else {
+ /* mono */
+ info->fix.visual = FB_VISUAL_MONO10;
+ info->fix.line_length = info->var.xres_virtual / 8;
}
- var->red.msb_right = 0;
- var->green.msb_right = 0;
- var->blue.msb_right = 0;
- var->transp.msb_right = 0;
-}
+ info->screen_size = info->fix.line_length * info->var.yres_virtual;
-static int au1100_decode_var(const struct fb_var_screeninfo *var,
- void *_par, struct fb_info_gen *_info)
-{
+ /* Determine BPP mode and format */
+ fbdev->regs->lcd_control = fbdev->panel->control_base |
+ ((info->var.rotate/90) << LCD_CONTROL_SM_BIT);
- struct au1100fb_par *par = (struct au1100fb_par *)_par;
+ fbdev->regs->lcd_intenable = 0;
+ fbdev->regs->lcd_intstatus = 0;
- /*
- * Don't allow setting any of these yet: xres and yres don't
- * make sense for LCD panels.
- */
- if (var->xres != p_lcd->xres ||
- var->yres != p_lcd->yres ||
- var->xres != p_lcd->xres ||
- var->yres != p_lcd->yres) {
- return -EINVAL;
- }
- if(var->bits_per_pixel != p_lcd->bpp) {
- return -EINVAL;
- }
+ fbdev->regs->lcd_horztiming = fbdev->panel->horztiming;
- memset(par, 0, sizeof(struct au1100fb_par));
- par->var = *var;
-
- /* FIXME */
- switch (var->bits_per_pixel) {
- case 8:
- par->var.bits_per_pixel = 8;
- break;
- case 16:
- par->var.bits_per_pixel = 16;
- break;
- default:
- printk("color depth %d bpp not supported\n",
- var->bits_per_pixel);
- return -EINVAL;
+ fbdev->regs->lcd_verttiming = fbdev->panel->verttiming;
+
+ fbdev->regs->lcd_clkcontrol = fbdev->panel->clkcontrol_base;
+ fbdev->regs->lcd_dmaaddr0 = LCD_DMA_SA_N(fbdev->fb_phys);
+
+ if (panel_is_dual(fbdev->panel)) {
+ /* Second panel display seconf half of screen if possible,
+ * otherwise display the same as the first panel */
+ if (info->var.yres_virtual >= (info->var.yres << 1)) {
+ fbdev->regs->lcd_dmaaddr1 = LCD_DMA_SA_N(fbdev->fb_phys +
+ (info->fix.line_length *
+ (info->var.yres_virtual >> 1)));
+ } else {
+ fbdev->regs->lcd_dmaaddr1 = LCD_DMA_SA_N(fbdev->fb_phys);
+ }
}
- set_color_bitfields(&par->var);
- par->cmap_len = (par->var.bits_per_pixel == 8) ? 256 : 16;
- return 0;
-}
-static int au1100_encode_var(struct fb_var_screeninfo *var,
- const void *par, struct fb_info_gen *_info)
-{
+ words = info->fix.line_length / sizeof(u32);
+ if (!info->var.rotate || (info->var.rotate == 180)) {
+ words *= info->var.yres_virtual;
+ if (info->var.rotate /* 180 */) {
+ words -= (words % 8); /* should be divisable by 8 */
+ }
+ }
+ fbdev->regs->lcd_words = LCD_WRD_WRDS_N(words);
- *var = ((struct au1100fb_par *)par)->var;
- return 0;
-}
+ fbdev->regs->lcd_pwmdiv = 0;
+ fbdev->regs->lcd_pwmhi = 0;
-static void
-au1100_get_par(void *_par, struct fb_info_gen *_info)
-{
- *(struct au1100fb_par *)_par = current_par;
-}
+ /* Resume controller */
+ fbdev->regs->lcd_control |= LCD_CONTROL_GO;
-static void au1100_set_par(const void *par, struct fb_info_gen *info)
-{
- /* nothing to do: we don't change any settings */
+ return 0;
}
-static int au1100_getcolreg(unsigned regno, unsigned *red, unsigned *green,
- unsigned *blue, unsigned *transp,
- struct fb_info *info)
+/* fb_setcolreg
+ * Set color in LCD palette.
+ */
+int au1100fb_fb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue, unsigned transp, struct fb_info *fbi)
{
+ struct au1100fb_device *fbdev = to_au1100fb_device(fbi);
+ u32 *palette = fbdev->regs->lcd_pallettebase;
+ u32 value;
- struct au1100fb_info* i = (struct au1100fb_info*)info;
-
- if (regno > 255)
- return 1;
+ if (regno > (AU1100_LCD_NBR_PALETTE_ENTRIES - 1))
+ return -EINVAL;
- *red = i->palette[regno].red;
- *green = i->palette[regno].green;
- *blue = i->palette[regno].blue;
- *transp = 0;
+ if (fbi->var.grayscale) {
+ /* Convert color to grayscale */
+ red = green = blue =
+ (19595 * red + 38470 * green + 7471 * blue) >> 16;
+ }
- return 0;
-}
+ if (fbi->fix.visual == FB_VISUAL_TRUECOLOR) {
+ /* Place color in the pseudopalette */
+ if (regno > 16)
+ return -EINVAL;
-static int au1100_setcolreg(unsigned regno, unsigned red, unsigned green,
- unsigned blue, unsigned transp,
- struct fb_info *info)
-{
- struct au1100fb_info* i = (struct au1100fb_info *)info;
- u32 rgbcol;
-
- if (regno > 255)
- return 1;
-
- i->palette[regno].red = red;
- i->palette[regno].green = green;
- i->palette[regno].blue = blue;
-
- switch(p_lcd->bpp) {
-#ifdef FBCON_HAS_CFB8
- case 8:
- red >>= 10;
- green >>= 10;
- blue >>= 10;
- p_lcd_reg->lcd_pallettebase[regno] = (blue&0x1f) |
- ((green&0x3f)<<5) | ((red&0x1f)<<11);
- break;
-#endif
-#ifdef FBCON_HAS_CFB16
- case 16:
- i->fbcon_cmap16[regno] =
- ((red & 0xf800) >> 0) |
- ((green & 0xfc00) >> 5) |
- ((blue & 0xf800) >> 11);
- break;
-#endif
- default:
- break;
+ palette = (u32*)fbi->pseudo_palette;
+
+ red >>= (16 - fbi->var.red.length);
+ green >>= (16 - fbi->var.green.length);
+ blue >>= (16 - fbi->var.blue.length);
+
+ value = (red << fbi->var.red.offset) |
+ (green << fbi->var.green.offset)|
+ (blue << fbi->var.blue.offset);
+ value &= 0xFFFF;
+
+ } else if (panel_is_active(fbdev->panel)) {
+ /* COLOR TFT PALLETTIZED (use RGB 565) */
+ value = (red & 0xF800)|((green >> 5) & 0x07E0)|((blue >> 11) & 0x001F);
+ value &= 0xFFFF;
+
+ } else if (panel_is_color(fbdev->panel)) {
+ /* COLOR STN MODE */
+ value = (((panel_swap_rgb(fbdev->panel) ? blue : red) >> 12) & 0x000F) |
+ ((green >> 8) & 0x00F0) |
+ (((panel_swap_rgb(fbdev->panel) ? red : blue) >> 4) & 0x0F00);
+ value &= 0xFFF;
+ } else {
+ /* MONOCHROME MODE */
+ value = (green >> 12) & 0x000F;
+ value &= 0xF;
}
+ palette[regno] = value;
+
return 0;
}
-
-static int au1100_blank(int blank_mode, struct fb_info_gen *_info)
+/* fb_blank
+ * Blank the screen. Depending on the mode, the screen will be
+ * activated with the backlight color, or desactivated
+ */
+int au1100fb_fb_blank(int blank_mode, struct fb_info *fbi)
{
+ struct au1100fb_device *fbdev = to_au1100fb_device(fbi);
+
+ print_dbg("fb_blank %d %p", blank_mode, fbi);
switch (blank_mode) {
+
case VESA_NO_BLANKING:
- /* turn on panel */
- //printk("turn on panel\n");
+ /* Turn on panel */
+ fbdev->regs->lcd_control |= LCD_CONTROL_GO;
#ifdef CONFIG_MIPS_PB1100
- p_lcd_reg->lcd_control |= LCD_CONTROL_GO;
- au_writew(au_readw(PB1100_G_CONTROL) | p_lcd->mode_backlight,
+ if (drv_info.panel_idx == 1) {
+ au_writew(au_readw(PB1100_G_CONTROL)
+ | (PB1100_G_CONTROL_BL | PB1100_G_CONTROL_VDD),
PB1100_G_CONTROL);
-#endif
-#ifdef CONFIG_MIPS_HYDROGEN3
- /* Turn controller & power supply on, GPIO213 */
- au_writel(0x20002000, 0xB1700008);
- au_writel(0x00040000, 0xB1900108);
- au_writel(0x01000100, 0xB1700008);
+ }
#endif
au_sync();
break;
@@ -332,12 +292,14 @@ static int au1100_blank(int blank_mode, struct fb_info_gen *_info)
case VESA_VSYNC_SUSPEND:
case VESA_HSYNC_SUSPEND:
case VESA_POWERDOWN:
- /* turn off panel */
- //printk("turn off panel\n");
+ /* Turn off panel */
+ fbdev->regs->lcd_control &= ~LCD_CONTROL_GO;
#ifdef CONFIG_MIPS_PB1100
- au_writew(au_readw(PB1100_G_CONTROL) & ~p_lcd->mode_backlight,
+ if (drv_info.panel_idx == 1) {
+ au_writew(au_readw(PB1100_G_CONTROL)
+ & ~(PB1100_G_CONTROL_BL | PB1100_G_CONTROL_VDD),
PB1100_G_CONTROL);
- p_lcd_reg->lcd_control &= ~LCD_CONTROL_GO;
+ }
#endif
au_sync();
break;
@@ -348,49 +310,87 @@ static int au1100_blank(int blank_mode, struct fb_info_gen *_info)
return 0;
}
-static void au1100_set_disp(const void *unused, struct display *disp,
- struct fb_info_gen *info)
+/* fb_pan_display
+ * Pan display in x and/or y as specified
+ */
+int au1100fb_fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *fbi)
{
- disp->screen_base = (char *)fb_info.fb_virt_start;
-
- switch (disp->var.bits_per_pixel) {
-#ifdef FBCON_HAS_CFB8
- case 8:
- disp->dispsw = &fbcon_cfb8;
- if (fb_info.nohwcursor)
- fbcon_cfb8.cursor = au1100_nocursor;
- break;
-#endif
-#ifdef FBCON_HAS_CFB16
- case 16:
- disp->dispsw = &fbcon_cfb16;
- disp->dispsw_data = fb_info.fbcon_cmap16;
- if (fb_info.nohwcursor)
- fbcon_cfb16.cursor = au1100_nocursor;
- break;
-#endif
- default:
- disp->dispsw = &fbcon_dummy;
- disp->dispsw_data = NULL;
- break;
+ struct au1100fb_device *fbdev = to_au1100fb_device(fbi);
+ int dy;
+
+ print_dbg("fb_pan_display %p %p", var, fbi);
+
+ if (!var || !fbdev) {
+ return -EINVAL;
+ }
+
+ if (var->xoffset - fbi->var.xoffset) {
+ /* No support for X panning for now! */
+ return -EINVAL;
+ }
+
+ print_dbg("fb_pan_display 2 %p %p", var, fbi);
+ dy = var->yoffset - fbi->var.yoffset;
+ if (dy) {
+
+ u32 dmaaddr;
+
+ print_dbg("Panning screen of %d lines", dy);
+
+ dmaaddr = fbdev->regs->lcd_dmaaddr0;
+ dmaaddr += (fbi->fix.line_length * dy);
+
+ /* TODO: Wait for current frame to finished */
+ fbdev->regs->lcd_dmaaddr0 = LCD_DMA_SA_N(dmaaddr);
+
+ if (panel_is_dual(fbdev->panel)) {
+ dmaaddr = fbdev->regs->lcd_dmaaddr1;
+ dmaaddr += (fbi->fix.line_length * dy);
+ fbdev->regs->lcd_dmaaddr0 = LCD_DMA_SA_N(dmaaddr);
+ }
+ }
+ print_dbg("fb_pan_display 3 %p %p", var, fbi);
+
+ return 0;
+}
+
+/* fb_rotate
+ * Rotate the display of this angle. This doesn't seems to be used by the core,
+ * but as our hardware supports it, so why not implementing it...
+ */
+void au1100fb_fb_rotate(struct fb_info *fbi, int angle)
+{
+ struct au1100fb_device *fbdev = to_au1100fb_device(fbi);
+
+ print_dbg("fb_rotate %p %d", fbi, angle);
+
+ if (fbdev && (angle > 0) && !(angle % 90)) {
+
+ fbdev->regs->lcd_control &= ~LCD_CONTROL_GO;
+
+ fbdev->regs->lcd_control &= ~(LCD_CONTROL_SM_MASK);
+ fbdev->regs->lcd_control |= ((angle/90) << LCD_CONTROL_SM_BIT);
+
+ fbdev->regs->lcd_control |= LCD_CONTROL_GO;
}
}
-static int
-au1100fb_mmap(struct fb_info *_fb,
- struct file *file,
- struct vm_area_struct *vma)
+/* fb_mmap
+ * Map video memory in user space. We don't use the generic fb_mmap method mainly
+ * to allow the use of the TLB streaming flag (CCA=6)
+ */
+int au1100fb_fb_mmap(struct fb_info *fbi, struct file *file, struct vm_area_struct *vma)
{
+ struct au1100fb_device *fbdev = to_au1100fb_device(fbi);
unsigned int len;
unsigned long start=0, off;
- struct au1100fb_info *fb = (struct au1100fb_info *)_fb;
if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT)) {
return -EINVAL;
}
- start = fb_info.fb_phys & PAGE_MASK;
- len = PAGE_ALIGN((start & ~PAGE_MASK) + fb_info.fb_size);
+ start = fbdev->fb_phys & PAGE_MASK;
+ len = PAGE_ALIGN((start & ~PAGE_MASK) + fbdev->fb_len);
off = vma->vm_pgoff << PAGE_SHIFT;
@@ -401,276 +401,309 @@ au1100fb_mmap(struct fb_info *_fb,
off += start;
vma->vm_pgoff = off >> PAGE_SHIFT;
- pgprot_val(vma->vm_page_prot) &= ~_CACHE_MASK;
- //pgprot_val(vma->vm_page_prot) |= _CACHE_CACHABLE_NONCOHERENT;
+ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
pgprot_val(vma->vm_page_prot) |= (6 << 9); //CCA=6
- /* This is an IO map - tell maydump to skip this VMA */
vma->vm_flags |= VM_IO;
- if (io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT,
+ if (io_remap_page_range(vma, vma->vm_start, off,
vma->vm_end - vma->vm_start,
vma->vm_page_prot)) {
return -EAGAIN;
}
- fb->mmaped = 1;
return 0;
}
-int au1100_pan_display(const struct fb_var_screeninfo *var,
- struct fb_info_gen *info)
+static struct fb_ops au1100fb_ops =
{
- return 0;
-}
+ .owner = THIS_MODULE,
+ .fb_setcolreg = au1100fb_fb_setcolreg,
+ .fb_blank = au1100fb_fb_blank,
+ .fb_pan_display = au1100fb_fb_pan_display,
+ .fb_fillrect = cfb_fillrect,
+ .fb_copyarea = cfb_copyarea,
+ .fb_imageblit = cfb_imageblit,
+ .fb_rotate = au1100fb_fb_rotate,
+ .fb_mmap = au1100fb_fb_mmap,
+};
-static int au1100fb_ioctl(struct inode *inode, struct file *file, u_int cmd,
- u_long arg, int con, struct fb_info *info)
-{
- /* nothing to do yet */
- return -EINVAL;
-}
-static struct fbgen_hwswitch au1100_switch = {
- au1100_detect,
- au1100_encode_fix,
- au1100_decode_var,
- au1100_encode_var,
- au1100_get_par,
- au1100_set_par,
- au1100_getcolreg,
- au1100_setcolreg,
- au1100_pan_display,
- au1100_blank,
- au1100_set_disp
-};
+/*-------------------------------------------------------------------------*/
+/* AU1100 LCD controller device driver */
-int au1100_setmode(void)
+int au1100fb_drv_probe(struct device *dev)
{
- int words;
-
- /* FIXME Need to accomodate for swivel mode and 12bpp, <8bpp*/
- switch (p_lcd->mode_control & LCD_CONTROL_SM)
- {
- case LCD_CONTROL_SM_0:
- case LCD_CONTROL_SM_180:
- words = (p_lcd->xres * p_lcd->yres * p_lcd->bpp) / 32;
- break;
- case LCD_CONTROL_SM_90:
- case LCD_CONTROL_SM_270:
- /* is this correct? */
- words = (p_lcd->xres * p_lcd->bpp) / 8;
- break;
- default:
- printk("mode_control reg not initialized\n");
+ struct au1100fb_device *fbdev = NULL;
+ struct resource *regs_res;
+ unsigned long page;
+ u32 sys_clksrc;
+
+ if (!dev)
return -EINVAL;
+
+ /* Allocate new device private */
+ if (!(fbdev = kmalloc(sizeof(struct au1100fb_device), GFP_KERNEL))) {
+ print_err("fail to allocate device private record");
+ return -ENOMEM;
}
+ memset((void*)fbdev, 0, sizeof(struct au1100fb_device));
- /*
- * Setup LCD controller
- */
+ fbdev->panel = &known_lcd_panels[drv_info.panel_idx];
- p_lcd_reg->lcd_control = p_lcd->mode_control;
- p_lcd_reg->lcd_intstatus = 0;
- p_lcd_reg->lcd_intenable = 0;
- p_lcd_reg->lcd_horztiming = p_lcd->mode_horztiming;
- p_lcd_reg->lcd_verttiming = p_lcd->mode_verttiming;
- p_lcd_reg->lcd_clkcontrol = p_lcd->mode_clkcontrol;
- p_lcd_reg->lcd_words = words - 1;
- p_lcd_reg->lcd_dmaaddr0 = fb_info.fb_phys;
+ dev_set_drvdata(dev, (void*)fbdev);
- /* turn on panel */
-#ifdef CONFIG_MIPS_PB1100
- au_writew(au_readw(PB1100_G_CONTROL) | p_lcd->mode_backlight,
- PB1100_G_CONTROL);
-#endif
-#ifdef CONFIG_MIPS_HYDROGEN3
- /* Turn controller & power supply on, GPIO213 */
- au_writel(0x20002000, 0xB1700008);
- au_writel(0x00040000, 0xB1900108);
- au_writel(0x01000100, 0xB1700008);
-#endif
+ /* Allocate region for our registers and map them */
+ if (!(regs_res = platform_get_resource(to_platform_device(dev),
+ IORESOURCE_MEM, 0))) {
+ print_err("fail to retrieve registers resource");
+ return -EFAULT;
+ }
- p_lcd_reg->lcd_control |= LCD_CONTROL_GO;
+ au1100fb_fix.mmio_start = regs_res->start;
+ au1100fb_fix.mmio_len = regs_res->end - regs_res->start + 1;
- return 0;
-}
+ if (!request_mem_region(au1100fb_fix.mmio_start, au1100fb_fix.mmio_len,
+ DRIVER_NAME)) {
+ print_err("fail to lock memory region at 0x%08x",
+ au1100fb_fix.mmio_start);
+ return -EBUSY;
+ }
+ fbdev->regs = (struct au1100fb_regs*)KSEG1ADDR(au1100fb_fix.mmio_start);
-int __init au1100fb_init(void)
-{
- uint32 sys_clksrc;
- unsigned long page;
+ print_dbg("Register memory map at %p", fbdev->regs);
+ print_dbg("phys=0x%08x, size=%d", fbdev->regs_phys, fbdev->regs_len);
- /*
- * Get the panel information/display mode and update the registry
- */
- p_lcd = &panels[my_lcd_index];
-
- switch (p_lcd->mode_control & LCD_CONTROL_SM)
- {
- case LCD_CONTROL_SM_0:
- case LCD_CONTROL_SM_180:
- p_lcd->xres =
- (p_lcd->mode_horztiming & LCD_HORZTIMING_PPL) + 1;
- p_lcd->yres =
- (p_lcd->mode_verttiming & LCD_VERTTIMING_LPP) + 1;
- break;
- case LCD_CONTROL_SM_90:
- case LCD_CONTROL_SM_270:
- p_lcd->yres =
- (p_lcd->mode_horztiming & LCD_HORZTIMING_PPL) + 1;
- p_lcd->xres =
- (p_lcd->mode_verttiming & LCD_VERTTIMING_LPP) + 1;
- break;
- }
- /*
- * Panel dimensions x bpp must be divisible by 32
- */
- if (((p_lcd->yres * p_lcd->bpp) % 32) != 0)
- printk("VERT %% 32\n");
- if (((p_lcd->xres * p_lcd->bpp) % 32) != 0)
- printk("HORZ %% 32\n");
- /*
- * Allocate LCD framebuffer from system memory
- */
- fb_info.fb_size = (p_lcd->xres * p_lcd->yres * p_lcd->bpp) / 8;
-
- current_par.var.xres = p_lcd->xres;
- current_par.var.xres_virtual = p_lcd->xres;
- current_par.var.yres = p_lcd->yres;
- current_par.var.yres_virtual = p_lcd->yres;
- current_par.var.bits_per_pixel = p_lcd->bpp;
-
- /* FIX!!! only works for 8/16 bpp */
- current_par.line_length = p_lcd->xres * p_lcd->bpp / 8; /* in bytes */
- fb_info.fb_virt_start = (unsigned long )
- __get_free_pages(GFP_ATOMIC | GFP_DMA,
- get_order(fb_info.fb_size + 0x1000));
- if (!fb_info.fb_virt_start) {
- printk("Unable to allocate fb memory\n");
+ /* Allocate the framebuffer to the maximum screen size * nbr of video buffers */
+ fbdev->fb_len = fbdev->panel->xres * fbdev->panel->yres *
+ (fbdev->panel->bpp >> 3) * AU1100FB_NBR_VIDEO_BUFFERS;
+
+ fbdev->fb_mem = dma_alloc_coherent(dev, PAGE_ALIGN(fbdev->fb_len),
+ &fbdev->fb_phys, GFP_KERNEL);
+ if (!fbdev->fb_mem) {
+ print_err("fail to allocate frambuffer (size: %dK))",
+ fbdev->fb_len / 1024);
return -ENOMEM;
}
- fb_info.fb_phys = virt_to_bus((void *)fb_info.fb_virt_start);
+
+ au1100fb_fix.smem_start = fbdev->fb_phys;
+ au1100fb_fix.smem_len = fbdev->fb_len;
/*
* Set page reserved so that mmap will work. This is necessary
* since we'll be remapping normal memory.
*/
- for (page = fb_info.fb_virt_start;
- page < PAGE_ALIGN(fb_info.fb_virt_start + fb_info.fb_size);
+ for (page = (unsigned long)fbdev->fb_mem;
+ page < PAGE_ALIGN((unsigned long)fbdev->fb_mem + fbdev->fb_len);
page += PAGE_SIZE) {
+#if CONFIG_DMA_NONCOHERENT
+ SetPageReserved(virt_to_page(CAC_ADDR(page)));
+#else
SetPageReserved(virt_to_page(page));
+#endif
}
- memset((void *)fb_info.fb_virt_start, 0, fb_info.fb_size);
-
- /* set freqctrl now to allow more time to stabilize */
- /* zero-out out LCD bits */
- sys_clksrc = au_readl(SYS_CLKSRC) & ~0x000003e0;
- sys_clksrc |= p_lcd->mode_toyclksrc;
- au_writel(sys_clksrc, SYS_CLKSRC);
-
- /* FIXME add check to make sure auxpll is what is expected! */
- au1100_setmode();
-
- fb_info.gen.parsize = sizeof(struct au1100fb_par);
- fb_info.gen.fbhw = &au1100_switch;
-
- strcpy(fb_info.gen.info.modename, "Au1100 LCD");
- fb_info.gen.info.changevar = NULL;
- fb_info.gen.info.node = -1;
-
- fb_info.gen.info.fbops = &au1100fb_ops;
- fb_info.gen.info.disp = &disp;
- fb_info.gen.info.switch_con = &fbgen_switch;
- fb_info.gen.info.updatevar = &fbgen_update_var;
- fb_info.gen.info.blank = &fbgen_blank;
- fb_info.gen.info.flags = FBINFO_FLAG_DEFAULT;
-
- /* This should give a reasonable default video mode */
- fbgen_get_var(&disp.var, -1, &fb_info.gen.info);
- fbgen_do_set_var(&disp.var, 1, &fb_info.gen);
- fbgen_set_disp(-1, &fb_info.gen);
- fbgen_install_cmap(0, &fb_info.gen);
- if (register_framebuffer(&fb_info.gen.info) < 0)
- return -EINVAL;
- printk(KERN_INFO "fb%d: %s frame buffer device\n",
- GET_FB_IDX(fb_info.gen.info.node),
- fb_info.gen.info.modename);
+ print_dbg("Framebuffer memory map at %p", fbdev->fb_mem);
+ print_dbg("phys=0x%08x, size=%dK", fbdev->fb_phys, fbdev->fb_len / 1024);
+
+ /* Setup LCD clock to AUX (48 MHz) */
+ sys_clksrc = au_readl(SYS_CLKSRC) & ~(SYS_CS_ML_MASK | SYS_CS_DL | SYS_CS_CL);
+ au_writel((sys_clksrc | (1 << SYS_CS_ML_BIT)), SYS_CLKSRC);
+
+ /* load the panel info into the var struct */
+ au1100fb_var.bits_per_pixel = fbdev->panel->bpp;
+ au1100fb_var.xres = fbdev->panel->xres;
+ au1100fb_var.xres_virtual = au1100fb_var.xres;
+ au1100fb_var.yres = fbdev->panel->yres;
+ au1100fb_var.yres_virtual = au1100fb_var.yres;
+
+ fbdev->info.screen_base = fbdev->fb_mem;
+ fbdev->info.fbops = &au1100fb_ops;
+ fbdev->info.fix = au1100fb_fix;
+
+ if (!(fbdev->info.pseudo_palette = kmalloc(sizeof(u32) * 16, GFP_KERNEL))) {
+ return -ENOMEM;
+ }
+ memset(fbdev->info.pseudo_palette, 0, sizeof(u32) * 16);
+
+ if (fb_alloc_cmap(&fbdev->info.cmap, AU1100_LCD_NBR_PALETTE_ENTRIES, 0) < 0) {
+ print_err("Fail to allocate colormap (%d entries)",
+ AU1100_LCD_NBR_PALETTE_ENTRIES);
+ kfree(fbdev->info.pseudo_palette);
+ return -EFAULT;
+ }
+
+ fbdev->info.var = au1100fb_var;
+
+ /* Set h/w registers */
+ au1100fb_setmode(fbdev);
+
+ /* Register new framebuffer */
+ if (register_framebuffer(&fbdev->info) < 0) {
+ print_err("cannot register new framebuffer");
+ goto failed;
+ }
+
+ return 0;
+
+failed:
+ if (fbdev->regs) {
+ release_mem_region(fbdev->regs_phys, fbdev->regs_len);
+ }
+ if (fbdev->fb_mem) {
+ dma_free_noncoherent(dev, fbdev->fb_len, fbdev->fb_mem, fbdev->fb_phys);
+ }
+ if (fbdev->info.cmap.len != 0) {
+ fb_dealloc_cmap(&fbdev->info.cmap);
+ }
+ kfree(fbdev);
+ dev_set_drvdata(dev, NULL);
return 0;
}
+int au1100fb_drv_remove(struct device *dev)
+{
+ struct au1100fb_device *fbdev = NULL;
+
+ if (!dev)
+ return -ENODEV;
+
+ fbdev = (struct au1100fb_device*) dev_get_drvdata(dev);
+
+#if !defined(CONFIG_FRAMEBUFFER_CONSOLE) && defined(CONFIG_LOGO)
+ au1100fb_fb_blank(VESA_POWERDOWN, &fbdev->info);
+#endif
+ fbdev->regs->lcd_control &= ~LCD_CONTROL_GO;
-void au1100fb_cleanup(struct fb_info *info)
+ /* Clean up all probe data */
+ unregister_framebuffer(&fbdev->info);
+
+ release_mem_region(fbdev->regs_phys, fbdev->regs_len);
+
+ dma_free_coherent(dev, PAGE_ALIGN(fbdev->fb_len), fbdev->fb_mem, fbdev->fb_phys);
+
+ fb_dealloc_cmap(&fbdev->info.cmap);
+ kfree(fbdev->info.pseudo_palette);
+ kfree((void*)fbdev);
+
+ return 0;
+}
+
+int au1100fb_drv_suspend(struct device *dev, u32 state, u32 level)
+{
+ /* TODO */
+ return 0;
+}
+
+int au1100fb_drv_resume(struct device *dev, u32 level)
{
- unregister_framebuffer(info);
+ /* TODO */
+ return 0;
}
+static struct device_driver au1100fb_driver = {
+ .name = "au1100-lcd",
+ .bus = &platform_bus_type,
-void au1100fb_setup(char *options, int *ints)
+ .probe = au1100fb_drv_probe,
+ .remove = au1100fb_drv_remove,
+ .suspend = au1100fb_drv_suspend,
+ .resume = au1100fb_drv_resume,
+};
+
+/*-------------------------------------------------------------------------*/
+
+/* Kernel driver */
+
+int au1100fb_setup(char *options)
{
char* this_opt;
- int i;
- int num_panels = sizeof(panels)/sizeof(struct known_lcd_panels);
+ int num_panels = ARRAY_SIZE(known_lcd_panels);
+ char* mode = NULL;
+ int panel_idx = 0;
+ if (num_panels <= 0) {
+ print_err("No LCD panels supported by driver!");
+ return -EFAULT;
+ }
- if (!options || !*options)
- return;
-
- for(this_opt=strtok(options, ","); this_opt;
- this_opt=strtok(NULL, ",")) {
+ if (options) {
+ while ((this_opt = strsep(&options,",")) != NULL) {
+ /* Panel option */
if (!strncmp(this_opt, "panel:", 6)) {
-#if defined(CONFIG_MIPS_PB1100) || defined(CONFIG_MIPS_DB1100)
- /* Read Pb1100 Switch S10 ? */
- if (!strncmp(this_opt+6, "s10", 3))
- {
- int panel;
- panel = *(volatile int *)0xAE000008; /* BCSR SWITCHES */
- panel >>= 8;
- panel &= 0x0F;
- if (panel >= num_panels) panel = 0;
- my_lcd_index = panel;
- }
- else
-#endif
- /* Get the panel name, everything else if fixed */
- for (i=0; i<num_panels; i++) {
- if (!strncmp(this_opt+6, panels[i].panel_name,
+ int i;
+ this_opt += 6;
+ for (i = 0; i < num_panels; i++) {
+ if (!strncmp(this_opt,
+ known_lcd_panels[i].name,
strlen(this_opt))) {
- my_lcd_index = i;
+ panel_idx = i;
break;
}
}
+ if (i >= num_panels) {
+ print_warn("Panel %s not supported!", this_opt);
+ }
+ }
+ /* Mode option (only option that start with digit) */
+ else if (isdigit(this_opt[0])) {
+ mode = kmalloc(strlen(this_opt) + 1, GFP_KERNEL);
+ strncpy(mode, this_opt, strlen(this_opt) + 1);
+ }
+ /* Unsupported option */
+ else {
+ print_warn("Unsupported option \"%s\"", this_opt);
}
- else if (!strncmp(this_opt, "nohwcursor", 10)) {
- printk("nohwcursor\n");
- fb_info.nohwcursor = 1;
}
}
- printk("au1100fb: Panel %d %s\n", my_lcd_index,
- panels[my_lcd_index].panel_name);
-}
+ drv_info.panel_idx = panel_idx;
+ drv_info.opt_mode = mode;
+ print_info("Panel=%s Mode=%s",
+ known_lcd_panels[drv_info.panel_idx].name,
+ drv_info.opt_mode ? drv_info.opt_mode : "default");
+ return 0;
+}
-#ifdef MODULE
-MODULE_LICENSE("GPL");
-int init_module(void)
+int __init au1100fb_init(void)
{
- return au1100fb_init();
+ char* options;
+ int ret;
+
+ print_info("" DRIVER_DESC "");
+
+ memset(&drv_info, 0, sizeof(drv_info));
+
+ if (fb_get_options(DRIVER_NAME, &options))
+ return -ENODEV;
+
+ /* Setup driver with options */
+ ret = au1100fb_setup(options);
+ if (ret < 0) {
+ print_err("Fail to setup driver");
+ return ret;
+ }
+
+ return driver_register(&au1100fb_driver);
}
-void cleanup_module(void)
+void __exit au1100fb_cleanup(void)
{
- au1100fb_cleanup(void);
+ driver_unregister(&au1100fb_driver);
+
+ if (drv_info.opt_mode)
+ kfree(drv_info.opt_mode);
}
-MODULE_AUTHOR("Pete Popov <ppopov@mvista.com>");
-MODULE_DESCRIPTION("Au1100 LCD framebuffer device driver");
-#endif /* MODULE */
+module_init(au1100fb_init);
+module_exit(au1100fb_cleanup);
+
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
diff --git a/drivers/video/au1100fb.h b/drivers/video/au1100fb.h
index 657c560ab73c..2855534dc235 100644
--- a/drivers/video/au1100fb.h
+++ b/drivers/video/au1100fb.h
@@ -30,352 +30,352 @@
#ifndef _AU1100LCD_H
#define _AU1100LCD_H
+#include <asm/mach-au1x00/au1000.h>
+
+#define print_err(f, arg...) printk(KERN_ERR DRIVER_NAME ": " f "\n", ## arg)
+#define print_warn(f, arg...) printk(KERN_WARNING DRIVER_NAME ": " f "\n", ## arg)
+#define print_info(f, arg...) printk(KERN_INFO DRIVER_NAME ": " f "\n", ## arg)
+
+#if DEBUG
+#define print_dbg(f, arg...) printk(__FILE__ ": " f "\n", ## arg)
+#else
+#define print_dbg(f, arg...) do {} while (0)
+#endif
+
+#if defined(__BIG_ENDIAN)
+#define LCD_CONTROL_DEFAULT_PO LCD_CONTROL_PO_11
+#else
+#define LCD_CONTROL_DEFAULT_PO LCD_CONTROL_PO_00
+#endif
+#define LCD_CONTROL_DEFAULT_SBPPF LCD_CONTROL_SBPPF_565
+
/********************************************************************/
-#define uint32 unsigned long
-typedef volatile struct
-{
- uint32 lcd_control;
- uint32 lcd_intstatus;
- uint32 lcd_intenable;
- uint32 lcd_horztiming;
- uint32 lcd_verttiming;
- uint32 lcd_clkcontrol;
- uint32 lcd_dmaaddr0;
- uint32 lcd_dmaaddr1;
- uint32 lcd_words;
- uint32 lcd_pwmdiv;
- uint32 lcd_pwmhi;
- uint32 reserved[(0x0400-0x002C)/4];
- uint32 lcd_pallettebase[256];
-
-} AU1100_LCD;
+
+/* LCD controller restrictions */
+#define AU1100_LCD_MAX_XRES 800
+#define AU1100_LCD_MAX_YRES 600
+#define AU1100_LCD_MAX_BPP 16
+#define AU1100_LCD_MAX_CLK 48000000
+#define AU1100_LCD_NBR_PALETTE_ENTRIES 256
+
+/* Default number of visible screen buffer to allocate */
+#define AU1100FB_NBR_VIDEO_BUFFERS 4
/********************************************************************/
-#define AU1100_LCD_ADDR 0xB5000000
+struct au1100fb_panel
+{
+ const char name[25]; /* Full name <vendor>_<model> */
-/*
- * Register bit definitions
- */
+ u32 control_base; /* Mode-independent control values */
+ u32 clkcontrol_base; /* Panel pixclock preferences */
-/* lcd_control */
-#define LCD_CONTROL_SBPPF (7<<18)
-#define LCD_CONTROL_SBPPF_655 (0<<18)
-#define LCD_CONTROL_SBPPF_565 (1<<18)
-#define LCD_CONTROL_SBPPF_556 (2<<18)
-#define LCD_CONTROL_SBPPF_1555 (3<<18)
-#define LCD_CONTROL_SBPPF_5551 (4<<18)
-#define LCD_CONTROL_WP (1<<17)
-#define LCD_CONTROL_WD (1<<16)
-#define LCD_CONTROL_C (1<<15)
-#define LCD_CONTROL_SM (3<<13)
-#define LCD_CONTROL_SM_0 (0<<13)
-#define LCD_CONTROL_SM_90 (1<<13)
-#define LCD_CONTROL_SM_180 (2<<13)
-#define LCD_CONTROL_SM_270 (3<<13)
-#define LCD_CONTROL_DB (1<<12)
-#define LCD_CONTROL_CCO (1<<11)
-#define LCD_CONTROL_DP (1<<10)
-#define LCD_CONTROL_PO (3<<8)
-#define LCD_CONTROL_PO_00 (0<<8)
-#define LCD_CONTROL_PO_01 (1<<8)
-#define LCD_CONTROL_PO_10 (2<<8)
-#define LCD_CONTROL_PO_11 (3<<8)
-#define LCD_CONTROL_MPI (1<<7)
-#define LCD_CONTROL_PT (1<<6)
-#define LCD_CONTROL_PC (1<<5)
-#define LCD_CONTROL_BPP (7<<1)
-#define LCD_CONTROL_BPP_1 (0<<1)
-#define LCD_CONTROL_BPP_2 (1<<1)
-#define LCD_CONTROL_BPP_4 (2<<1)
-#define LCD_CONTROL_BPP_8 (3<<1)
-#define LCD_CONTROL_BPP_12 (4<<1)
-#define LCD_CONTROL_BPP_16 (5<<1)
-#define LCD_CONTROL_GO (1<<0)
-
-/* lcd_intstatus, lcd_intenable */
-#define LCD_INT_SD (1<<7)
-#define LCD_INT_OF (1<<6)
-#define LCD_INT_UF (1<<5)
-#define LCD_INT_SA (1<<3)
-#define LCD_INT_SS (1<<2)
-#define LCD_INT_S1 (1<<1)
-#define LCD_INT_S0 (1<<0)
-
-/* lcd_horztiming */
-#define LCD_HORZTIMING_HN2 (255<<24)
-#define LCD_HORZTIMING_HN2_N(N) (((N)-1)<<24)
-#define LCD_HORZTIMING_HN1 (255<<16)
-#define LCD_HORZTIMING_HN1_N(N) (((N)-1)<<16)
-#define LCD_HORZTIMING_HPW (63<<10)
-#define LCD_HORZTIMING_HPW_N(N) (((N)-1)<<10)
-#define LCD_HORZTIMING_PPL (1023<<0)
-#define LCD_HORZTIMING_PPL_N(N) (((N)-1)<<0)
-
-/* lcd_verttiming */
-#define LCD_VERTTIMING_VN2 (255<<24)
-#define LCD_VERTTIMING_VN2_N(N) (((N)-1)<<24)
-#define LCD_VERTTIMING_VN1 (255<<16)
-#define LCD_VERTTIMING_VN1_N(N) (((N)-1)<<16)
-#define LCD_VERTTIMING_VPW (63<<10)
-#define LCD_VERTTIMING_VPW_N(N) (((N)-1)<<10)
-#define LCD_VERTTIMING_LPP (1023<<0)
-#define LCD_VERTTIMING_LPP_N(N) (((N)-1)<<0)
-
-/* lcd_clkcontrol */
-#define LCD_CLKCONTROL_IB (1<<18)
-#define LCD_CLKCONTROL_IC (1<<17)
-#define LCD_CLKCONTROL_IH (1<<16)
-#define LCD_CLKCONTROL_IV (1<<15)
-#define LCD_CLKCONTROL_BF (31<<10)
-#define LCD_CLKCONTROL_BF_N(N) (((N)-1)<<10)
-#define LCD_CLKCONTROL_PCD (1023<<0)
-#define LCD_CLKCONTROL_PCD_N(N) ((N)<<0)
-
-/* lcd_pwmdiv */
-#define LCD_PWMDIV_EN (1<<12)
-#define LCD_PWMDIV_PWMDIV (2047<<0)
-#define LCD_PWMDIV_PWMDIV_N(N) (((N)-1)<<0)
-
-/* lcd_pwmhi */
-#define LCD_PWMHI_PWMHI1 (2047<<12)
-#define LCD_PWMHI_PWMHI1_N(N) ((N)<<12)
-#define LCD_PWMHI_PWMHI0 (2047<<0)
-#define LCD_PWMHI_PWMHI0_N(N) ((N)<<0)
-
-/* lcd_pallettebase - MONOCHROME */
-#define LCD_PALLETTE_MONO_MI (15<<0)
-#define LCD_PALLETTE_MONO_MI_N(N) ((N)<<0)
-
-/* lcd_pallettebase - COLOR */
-#define LCD_PALLETTE_COLOR_BI (15<<8)
-#define LCD_PALLETTE_COLOR_BI_N(N) ((N)<<8)
-#define LCD_PALLETTE_COLOR_GI (15<<4)
-#define LCD_PALLETTE_COLOR_GI_N(N) ((N)<<4)
-#define LCD_PALLETTE_COLOR_RI (15<<0)
-#define LCD_PALLETTE_COLOR_RI_N(N) ((N)<<0)
-
-/* lcd_palletebase - COLOR TFT PALLETIZED */
-#define LCD_PALLETTE_TFT_DC (65535<<0)
-#define LCD_PALLETTE_TFT_DC_N(N) ((N)<<0)
+ u32 horztiming;
+ u32 verttiming;
-/********************************************************************/
+ u32 xres; /* Maximum horizontal resolution */
+ u32 yres; /* Maximum vertical resolution */
+ u32 bpp; /* Maximum depth supported */
+};
-struct known_lcd_panels
+struct au1100fb_regs
{
- uint32 xres;
- uint32 yres;
- uint32 bpp;
- unsigned char panel_name[256];
- uint32 mode_control;
- uint32 mode_horztiming;
- uint32 mode_verttiming;
- uint32 mode_clkcontrol;
- uint32 mode_pwmdiv;
- uint32 mode_pwmhi;
- uint32 mode_toyclksrc;
- uint32 mode_backlight;
+ u32 lcd_control;
+ u32 lcd_intstatus;
+ u32 lcd_intenable;
+ u32 lcd_horztiming;
+ u32 lcd_verttiming;
+ u32 lcd_clkcontrol;
+ u32 lcd_dmaaddr0;
+ u32 lcd_dmaaddr1;
+ u32 lcd_words;
+ u32 lcd_pwmdiv;
+ u32 lcd_pwmhi;
+ u32 reserved[(0x0400-0x002C)/4];
+ u32 lcd_pallettebase[256];
+};
+
+struct au1100fb_device {
+
+ struct fb_info info; /* FB driver info record */
+ struct au1100fb_panel *panel; /* Panel connected to this device */
+
+ struct au1100fb_regs* regs; /* Registers memory map */
+ size_t regs_len;
+ unsigned int regs_phys;
+
+ unsigned char* fb_mem; /* FrameBuffer memory map */
+ size_t fb_len;
+ dma_addr_t fb_phys;
};
-#if defined(__BIG_ENDIAN)
-#define LCD_DEFAULT_PIX_FORMAT LCD_CONTROL_PO_11
-#else
-#define LCD_DEFAULT_PIX_FORMAT LCD_CONTROL_PO_00
-#endif
+/********************************************************************/
-/*
- * The fb driver assumes that AUX PLL is at 48MHz. That can
- * cover up to 800x600 resolution; if you need higher resolution,
- * you should modify the driver as needed, not just this structure.
+#define LCD_CONTROL (AU1100_LCD_BASE + 0x0)
+ #define LCD_CONTROL_SBB_BIT 21
+ #define LCD_CONTROL_SBB_MASK (0x3 << LCD_CONTROL_SBB_BIT)
+ #define LCD_CONTROL_SBB_1 (0 << LCD_CONTROL_SBB_BIT)
+ #define LCD_CONTROL_SBB_2 (1 << LCD_CONTROL_SBB_BIT)
+ #define LCD_CONTROL_SBB_3 (2 << LCD_CONTROL_SBB_BIT)
+ #define LCD_CONTROL_SBB_4 (3 << LCD_CONTROL_SBB_BIT)
+ #define LCD_CONTROL_SBPPF_BIT 18
+ #define LCD_CONTROL_SBPPF_MASK (0x7 << LCD_CONTROL_SBPPF_BIT)
+ #define LCD_CONTROL_SBPPF_655 (0 << LCD_CONTROL_SBPPF_BIT)
+ #define LCD_CONTROL_SBPPF_565 (1 << LCD_CONTROL_SBPPF_BIT)
+ #define LCD_CONTROL_SBPPF_556 (2 << LCD_CONTROL_SBPPF_BIT)
+ #define LCD_CONTROL_SBPPF_1555 (3 << LCD_CONTROL_SBPPF_BIT)
+ #define LCD_CONTROL_SBPPF_5551 (4 << LCD_CONTROL_SBPPF_BIT)
+ #define LCD_CONTROL_WP (1<<17)
+ #define LCD_CONTROL_WD (1<<16)
+ #define LCD_CONTROL_C (1<<15)
+ #define LCD_CONTROL_SM_BIT 13
+ #define LCD_CONTROL_SM_MASK (0x3 << LCD_CONTROL_SM_BIT)
+ #define LCD_CONTROL_SM_0 (0 << LCD_CONTROL_SM_BIT)
+ #define LCD_CONTROL_SM_90 (1 << LCD_CONTROL_SM_BIT)
+ #define LCD_CONTROL_SM_180 (2 << LCD_CONTROL_SM_BIT)
+ #define LCD_CONTROL_SM_270 (3 << LCD_CONTROL_SM_BIT)
+ #define LCD_CONTROL_DB (1<<12)
+ #define LCD_CONTROL_CCO (1<<11)
+ #define LCD_CONTROL_DP (1<<10)
+ #define LCD_CONTROL_PO_BIT 8
+ #define LCD_CONTROL_PO_MASK (0x3 << LCD_CONTROL_PO_BIT)
+ #define LCD_CONTROL_PO_00 (0 << LCD_CONTROL_PO_BIT)
+ #define LCD_CONTROL_PO_01 (1 << LCD_CONTROL_PO_BIT)
+ #define LCD_CONTROL_PO_10 (2 << LCD_CONTROL_PO_BIT)
+ #define LCD_CONTROL_PO_11 (3 << LCD_CONTROL_PO_BIT)
+ #define LCD_CONTROL_MPI (1<<7)
+ #define LCD_CONTROL_PT (1<<6)
+ #define LCD_CONTROL_PC (1<<5)
+ #define LCD_CONTROL_BPP_BIT 1
+ #define LCD_CONTROL_BPP_MASK (0x7 << LCD_CONTROL_BPP_BIT)
+ #define LCD_CONTROL_BPP_1 (0 << LCD_CONTROL_BPP_BIT)
+ #define LCD_CONTROL_BPP_2 (1 << LCD_CONTROL_BPP_BIT)
+ #define LCD_CONTROL_BPP_4 (2 << LCD_CONTROL_BPP_BIT)
+ #define LCD_CONTROL_BPP_8 (3 << LCD_CONTROL_BPP_BIT)
+ #define LCD_CONTROL_BPP_12 (4 << LCD_CONTROL_BPP_BIT)
+ #define LCD_CONTROL_BPP_16 (5 << LCD_CONTROL_BPP_BIT)
+ #define LCD_CONTROL_GO (1<<0)
+
+#define LCD_INTSTATUS (AU1100_LCD_BASE + 0x4)
+#define LCD_INTENABLE (AU1100_LCD_BASE + 0x8)
+ #define LCD_INT_SD (1<<7)
+ #define LCD_INT_OF (1<<6)
+ #define LCD_INT_UF (1<<5)
+ #define LCD_INT_SA (1<<3)
+ #define LCD_INT_SS (1<<2)
+ #define LCD_INT_S1 (1<<1)
+ #define LCD_INT_S0 (1<<0)
+
+#define LCD_HORZTIMING (AU1100_LCD_BASE + 0xC)
+ #define LCD_HORZTIMING_HN2_BIT 24
+ #define LCD_HORZTIMING_HN2_MASK (0xFF << LCD_HORZTIMING_HN2_BIT)
+ #define LCD_HORZTIMING_HN2_N(N) ((((N)-1) << LCD_HORZTIMING_HN2_BIT) & LCD_HORZTIMING_HN2_MASK)
+ #define LCD_HORZTIMING_HN1_BIT 16
+ #define LCD_HORZTIMING_HN1_MASK (0xFF << LCD_HORZTIMING_HN1_BIT)
+ #define LCD_HORZTIMING_HN1_N(N) ((((N)-1) << LCD_HORZTIMING_HN1_BIT) & LCD_HORZTIMING_HN1_MASK)
+ #define LCD_HORZTIMING_HPW_BIT 10
+ #define LCD_HORZTIMING_HPW_MASK (0x3F << LCD_HORZTIMING_HPW_BIT)
+ #define LCD_HORZTIMING_HPW_N(N) ((((N)-1) << LCD_HORZTIMING_HPW_BIT) & LCD_HORZTIMING_HPW_MASK)
+ #define LCD_HORZTIMING_PPL_BIT 0
+ #define LCD_HORZTIMING_PPL_MASK (0x3FF << LCD_HORZTIMING_PPL_BIT)
+ #define LCD_HORZTIMING_PPL_N(N) ((((N)-1) << LCD_HORZTIMING_PPL_BIT) & LCD_HORZTIMING_PPL_MASK)
+
+#define LCD_VERTTIMING (AU1100_LCD_BASE + 0x10)
+ #define LCD_VERTTIMING_VN2_BIT 24
+ #define LCD_VERTTIMING_VN2_MASK (0xFF << LCD_VERTTIMING_VN2_BIT)
+ #define LCD_VERTTIMING_VN2_N(N) ((((N)-1) << LCD_VERTTIMING_VN2_BIT) & LCD_VERTTIMING_VN2_MASK)
+ #define LCD_VERTTIMING_VN1_BIT 16
+ #define LCD_VERTTIMING_VN1_MASK (0xFF << LCD_VERTTIMING_VN1_BIT)
+ #define LCD_VERTTIMING_VN1_N(N) ((((N)-1) << LCD_VERTTIMING_VN1_BIT) & LCD_VERTTIMING_VN1_MASK)
+ #define LCD_VERTTIMING_VPW_BIT 10
+ #define LCD_VERTTIMING_VPW_MASK (0x3F << LCD_VERTTIMING_VPW_BIT)
+ #define LCD_VERTTIMING_VPW_N(N) ((((N)-1) << LCD_VERTTIMING_VPW_BIT) & LCD_VERTTIMING_VPW_MASK)
+ #define LCD_VERTTIMING_LPP_BIT 0
+ #define LCD_VERTTIMING_LPP_MASK (0x3FF << LCD_VERTTIMING_LPP_BIT)
+ #define LCD_VERTTIMING_LPP_N(N) ((((N)-1) << LCD_VERTTIMING_LPP_BIT) & LCD_VERTTIMING_LPP_MASK)
+
+#define LCD_CLKCONTROL (AU1100_LCD_BASE + 0x14)
+ #define LCD_CLKCONTROL_IB (1<<18)
+ #define LCD_CLKCONTROL_IC (1<<17)
+ #define LCD_CLKCONTROL_IH (1<<16)
+ #define LCD_CLKCONTROL_IV (1<<15)
+ #define LCD_CLKCONTROL_BF_BIT 10
+ #define LCD_CLKCONTROL_BF_MASK (0x1F << LCD_CLKCONTROL_BF_BIT)
+ #define LCD_CLKCONTROL_BF_N(N) ((((N)-1) << LCD_CLKCONTROL_BF_BIT) & LCD_CLKCONTROL_BF_MASK)
+ #define LCD_CLKCONTROL_PCD_BIT 0
+ #define LCD_CLKCONTROL_PCD_MASK (0x3FF << LCD_CLKCONTROL_PCD_BIT)
+ #define LCD_CLKCONTROL_PCD_N(N) (((N) << LCD_CLKCONTROL_PCD_BIT) & LCD_CLKCONTROL_PCD_MASK)
+
+#define LCD_DMAADDR0 (AU1100_LCD_BASE + 0x18)
+#define LCD_DMAADDR1 (AU1100_LCD_BASE + 0x1C)
+ #define LCD_DMA_SA_BIT 5
+ #define LCD_DMA_SA_MASK (0x7FFFFFF << LCD_DMA_SA_BIT)
+ #define LCD_DMA_SA_N(N) ((N) & LCD_DMA_SA_MASK)
+
+#define LCD_WORDS (AU1100_LCD_BASE + 0x20)
+ #define LCD_WRD_WRDS_BIT 0
+ #define LCD_WRD_WRDS_MASK (0xFFFFFFFF << LCD_WRD_WRDS_BIT)
+ #define LCD_WRD_WRDS_N(N) ((((N)-1) << LCD_WRD_WRDS_BIT) & LCD_WRD_WRDS_MASK)
+
+#define LCD_PWMDIV (AU1100_LCD_BASE + 0x24)
+ #define LCD_PWMDIV_EN (1<<12)
+ #define LCD_PWMDIV_PWMDIV_BIT 0
+ #define LCD_PWMDIV_PWMDIV_MASK (0xFFF << LCD_PWMDIV_PWMDIV_BIT)
+ #define LCD_PWMDIV_PWMDIV_N(N) ((((N)-1) << LCD_PWMDIV_PWMDIV_BIT) & LCD_PWMDIV_PWMDIV_MASK)
+
+#define LCD_PWMHI (AU1100_LCD_BASE + 0x28)
+ #define LCD_PWMHI_PWMHI1_BIT 12
+ #define LCD_PWMHI_PWMHI1_MASK (0xFFF << LCD_PWMHI_PWMHI1_BIT)
+ #define LCD_PWMHI_PWMHI1_N(N) (((N) << LCD_PWMHI_PWMHI1_BIT) & LCD_PWMHI_PWMHI1_MASK)
+ #define LCD_PWMHI_PWMHI0_BIT 0
+ #define LCD_PWMHI_PWMHI0_MASK (0xFFF << LCD_PWMHI_PWMHI0_BIT)
+ #define LCD_PWMHI_PWMHI0_N(N) (((N) << LCD_PWMHI_PWMHI0_BIT) & LCD_PWMHI_PWMHI0_MASK)
+
+#define LCD_PALLETTEBASE (AU1100_LCD_BASE + 0x400)
+ #define LCD_PALLETTE_MONO_MI_BIT 0
+ #define LCD_PALLETTE_MONO_MI_MASK (0xF << LCD_PALLETTE_MONO_MI_BIT)
+ #define LCD_PALLETTE_MONO_MI_N(N) (((N)<< LCD_PALLETTE_MONO_MI_BIT) & LCD_PALLETTE_MONO_MI_MASK)
+
+ #define LCD_PALLETTE_COLOR_RI_BIT 8
+ #define LCD_PALLETTE_COLOR_RI_MASK (0xF << LCD_PALLETTE_COLOR_RI_BIT)
+ #define LCD_PALLETTE_COLOR_RI_N(N) (((N)<< LCD_PALLETTE_COLOR_RI_BIT) & LCD_PALLETTE_COLOR_RI_MASK)
+ #define LCD_PALLETTE_COLOR_GI_BIT 4
+ #define LCD_PALLETTE_COLOR_GI_MASK (0xF << LCD_PALLETTE_COLOR_GI_BIT)
+ #define LCD_PALLETTE_COLOR_GI_N(N) (((N)<< LCD_PALLETTE_COLOR_GI_BIT) & LCD_PALLETTE_COLOR_GI_MASK)
+ #define LCD_PALLETTE_COLOR_BI_BIT 0
+ #define LCD_PALLETTE_COLOR_BI_MASK (0xF << LCD_PALLETTE_COLOR_BI_BIT)
+ #define LCD_PALLETTE_COLOR_BI_N(N) (((N)<< LCD_PALLETTE_COLOR_BI_BIT) & LCD_PALLETTE_COLOR_BI_MASK)
+
+ #define LCD_PALLETTE_TFT_DC_BIT 0
+ #define LCD_PALLETTE_TFT_DC_MASK (0xFFFF << LCD_PALLETTE_TFT_DC_BIT)
+ #define LCD_PALLETTE_TFT_DC_N(N) (((N)<< LCD_PALLETTE_TFT_DC_BIT) & LCD_PALLETTE_TFT_DC_MASK)
+
+/********************************************************************/
+
+/* List of panels known to work with the AU1100 LCD controller.
+ * To add a new panel, enter the same specifications as the
+ * Generic_TFT one, and MAKE SURE that it doesn't conflicts
+ * with the controller restrictions. Restrictions are:
+ *
+ * STN color panels: max_bpp <= 12
+ * STN mono panels: max_bpp <= 4
+ * TFT panels: max_bpp <= 16
+ * max_xres <= 800
+ * max_yres <= 600
*/
-struct known_lcd_panels panels[] =
+static struct au1100fb_panel known_lcd_panels[] =
{
- { /* 0: Pb1100 LCDA: Sharp 320x240 TFT panel */
- 320, /* xres */
- 240, /* yres */
- 16, /* bpp */
-
- "Sharp_320x240_16",
- /* mode_control */
+ /* 800x600x16bpp CRT */
+ [0] = {
+ .name = "CRT_800x600_16",
+ .xres = 800,
+ .yres = 600,
+ .bpp = 16,
+ .control_base = 0x0004886A |
+ LCD_CONTROL_DEFAULT_PO | LCD_CONTROL_DEFAULT_SBPPF |
+ LCD_CONTROL_BPP_16,
+ .clkcontrol_base = 0x00020000,
+ .horztiming = 0x005aff1f,
+ .verttiming = 0x16000e57,
+ },
+ /* just the standard LCD */
+ [1] = {
+ .name = "WWPC LCD",
+ .xres = 240,
+ .yres = 320,
+ .bpp = 16,
+ .control_base = 0x0006806A,
+ .horztiming = 0x0A1010EF,
+ .verttiming = 0x0301013F,
+ .clkcontrol_base = 0x00018001,
+ },
+ /* Sharp 320x240 TFT panel */
+ [2] = {
+ .name = "Sharp_LQ038Q5DR01",
+ .xres = 320,
+ .yres = 240,
+ .bpp = 16,
+ .control_base =
( LCD_CONTROL_SBPPF_565
- /*LCD_CONTROL_WP*/
- /*LCD_CONTROL_WD*/
| LCD_CONTROL_C
| LCD_CONTROL_SM_0
- /*LCD_CONTROL_DB*/
- /*LCD_CONTROL_CCO*/
- /*LCD_CONTROL_DP*/
- | LCD_DEFAULT_PIX_FORMAT
- /*LCD_CONTROL_MPI*/
+ | LCD_CONTROL_DEFAULT_PO
| LCD_CONTROL_PT
| LCD_CONTROL_PC
| LCD_CONTROL_BPP_16 ),
-
- /* mode_horztiming */
+ .horztiming =
( LCD_HORZTIMING_HN2_N(8)
| LCD_HORZTIMING_HN1_N(60)
| LCD_HORZTIMING_HPW_N(12)
| LCD_HORZTIMING_PPL_N(320) ),
-
- /* mode_verttiming */
+ .verttiming =
( LCD_VERTTIMING_VN2_N(5)
| LCD_VERTTIMING_VN1_N(17)
| LCD_VERTTIMING_VPW_N(1)
| LCD_VERTTIMING_LPP_N(240) ),
-
- /* mode_clkcontrol */
- ( 0
- /*LCD_CLKCONTROL_IB*/
- /*LCD_CLKCONTROL_IC*/
- /*LCD_CLKCONTROL_IH*/
- /*LCD_CLKCONTROL_IV*/
- | LCD_CLKCONTROL_PCD_N(1) ),
-
- /* mode_pwmdiv */
- 0,
-
- /* mode_pwmhi */
- 0,
-
- /* mode_toyclksrc */
- ((1<<7) | (1<<6) | (1<<5)),
-
- /* mode_backlight */
- 6
+ .clkcontrol_base = LCD_CLKCONTROL_PCD_N(1),
},
- { /* 1: Pb1100 LCDC 640x480 TFT panel */
- 640, /* xres */
- 480, /* yres */
- 16, /* bpp */
-
- "Generic_640x480_16",
-
- /* mode_control */
- 0x004806a | LCD_DEFAULT_PIX_FORMAT,
-
- /* mode_horztiming */
- 0x3434d67f,
-
- /* mode_verttiming */
- 0x0e0e39df,
-
- /* mode_clkcontrol */
- ( 0
- /*LCD_CLKCONTROL_IB*/
- /*LCD_CLKCONTROL_IC*/
- /*LCD_CLKCONTROL_IH*/
- /*LCD_CLKCONTROL_IV*/
- | LCD_CLKCONTROL_PCD_N(1) ),
-
- /* mode_pwmdiv */
- 0,
-
- /* mode_pwmhi */
- 0,
-
- /* mode_toyclksrc */
- ((1<<7) | (1<<6) | (0<<5)),
-
- /* mode_backlight */
- 7
+ /* Hitachi SP14Q005 and possibly others */
+ [3] = {
+ .name = "Hitachi_SP14Qxxx",
+ .xres = 320,
+ .yres = 240,
+ .bpp = 4,
+ .control_base =
+ ( LCD_CONTROL_C
+ | LCD_CONTROL_BPP_4 ),
+ .horztiming =
+ ( LCD_HORZTIMING_HN2_N(1)
+ | LCD_HORZTIMING_HN1_N(1)
+ | LCD_HORZTIMING_HPW_N(1)
+ | LCD_HORZTIMING_PPL_N(320) ),
+ .verttiming =
+ ( LCD_VERTTIMING_VN2_N(1)
+ | LCD_VERTTIMING_VN1_N(1)
+ | LCD_VERTTIMING_VPW_N(1)
+ | LCD_VERTTIMING_LPP_N(240) ),
+ .clkcontrol_base = LCD_CLKCONTROL_PCD_N(4),
},
- { /* 2: Pb1100 LCDB 640x480 PrimeView TFT panel */
- 640, /* xres */
- 480, /* yres */
- 16, /* bpp */
-
- "PrimeView_640x480_16",
-
- /* mode_control */
- 0x0004886a | LCD_DEFAULT_PIX_FORMAT,
-
- /* mode_horztiming */
- 0x0e4bfe7f,
-
- /* mode_verttiming */
- 0x210805df,
-
- /* mode_clkcontrol */
- 0x00038001,
-
- /* mode_pwmdiv */
- 0,
-
- /* mode_pwmhi */
- 0,
-
- /* mode_toyclksrc */
- ((1<<7) | (1<<6) | (0<<5)),
-
- /* mode_backlight */
- 7
+ /* Generic 640x480 TFT panel */
+ [4] = {
+ .name = "TFT_640x480_16",
+ .xres = 640,
+ .yres = 480,
+ .bpp = 16,
+ .control_base = 0x004806a | LCD_CONTROL_DEFAULT_PO,
+ .horztiming = 0x3434d67f,
+ .verttiming = 0x0e0e39df,
+ .clkcontrol_base = LCD_CLKCONTROL_PCD_N(1),
},
- { /* 3: Pb1100 800x600x16bpp NEON CRT */
- 800, /* xres */
- 600, /* yres */
- 16, /* bpp */
-
- "NEON_800x600_16",
-
- /* mode_control */
- 0x0004886A | LCD_DEFAULT_PIX_FORMAT,
-
- /* mode_horztiming */
- 0x005AFF1F,
-
- /* mode_verttiming */
- 0x16000E57,
-
- /* mode_clkcontrol */
- 0x00020000,
-
- /* mode_pwmdiv */
- 0,
-
- /* mode_pwmhi */
- 0,
-
- /* mode_toyclksrc */
- ((1<<7) | (1<<6) | (0<<5)),
-
- /* mode_backlight */
- 7
+ /* Pb1100 LCDB 640x480 PrimeView TFT panel */
+ [5] = {
+ .name = "PrimeView_640x480_16",
+ .xres = 640,
+ .yres = 480,
+ .bpp = 16,
+ .control_base = 0x0004886a | LCD_CONTROL_DEFAULT_PO,
+ .horztiming = 0x0e4bfe7f,
+ .verttiming = 0x210805df,
+ .clkcontrol_base = 0x00038001,
},
+};
- { /* 4: Pb1100 640x480x16bpp NEON CRT */
- 640, /* xres */
- 480, /* yres */
- 16, /* bpp */
-
- "NEON_640x480_16",
-
- /* mode_control */
- 0x0004886A | LCD_DEFAULT_PIX_FORMAT,
-
- /* mode_horztiming */
- 0x0052E27F,
-
- /* mode_verttiming */
- 0x18000DDF,
-
- /* mode_clkcontrol */
- 0x00020000,
+struct au1100fb_drv_info {
+ int panel_idx;
+ char *opt_mode;
+};
- /* mode_pwmdiv */
- 0,
+/********************************************************************/
- /* mode_pwmhi */
- 0,
+/* Inline helpers */
- /* mode_toyclksrc */
- ((1<<7) | (1<<6) | (0<<5)),
+#define panel_is_dual(panel) (panel->control_base & LCD_CONTROL_DP)
+#define panel_is_active(panel)(panel->control_base & LCD_CONTROL_PT)
+#define panel_is_color(panel) (panel->control_base & LCD_CONTROL_PC)
+#define panel_swap_rgb(panel) (panel->control_base & LCD_CONTROL_CCO)
- /* mode_backlight */
- 7
- },
-};
#endif /* _AU1100LCD_H */
diff --git a/drivers/video/backlight/backlight.c b/drivers/video/backlight/backlight.c
index acc81cb01d56..9d5015e99372 100644
--- a/drivers/video/backlight/backlight.c
+++ b/drivers/video/backlight/backlight.c
@@ -5,7 +5,6 @@
*
*/
-#include <linux/version.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/device.h>
diff --git a/drivers/video/backlight/corgi_bl.c b/drivers/video/backlight/corgi_bl.c
index 3c72c627e65e..bd9a6996aee7 100644
--- a/drivers/video/backlight/corgi_bl.c
+++ b/drivers/video/backlight/corgi_bl.c
@@ -14,7 +14,7 @@
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <linux/spinlock.h>
#include <linux/fb.h>
#include <linux/backlight.h>
@@ -48,6 +48,12 @@ static void corgibl_send_intensity(int intensity)
corgibl_mach_set_intensity(intensity);
spin_unlock_irqrestore(&bl_lock, flags);
+
+ corgi_kick_batt = symbol_get(sharpsl_battery_kick);
+ if (corgi_kick_batt) {
+ corgi_kick_batt();
+ symbol_put(sharpsl_battery_kick);
+ }
}
static void corgibl_blank(int blank)
@@ -73,17 +79,15 @@ static void corgibl_blank(int blank)
}
#ifdef CONFIG_PM
-static int corgibl_suspend(struct device *dev, pm_message_t state, u32 level)
+static int corgibl_suspend(struct device *dev, pm_message_t state)
{
- if (level == SUSPEND_POWER_DOWN)
- corgibl_blank(FB_BLANK_POWERDOWN);
+ corgibl_blank(FB_BLANK_POWERDOWN);
return 0;
}
-static int corgibl_resume(struct device *dev, u32 level)
+static int corgibl_resume(struct device *dev)
{
- if (level == RESUME_POWER_ON)
- corgibl_blank(FB_BLANK_UNBLANK);
+ corgibl_blank(FB_BLANK_UNBLANK);
return 0;
}
#else
diff --git a/drivers/video/backlight/lcd.c b/drivers/video/backlight/lcd.c
index 470e6f0ee4dd..68c690605aa7 100644
--- a/drivers/video/backlight/lcd.c
+++ b/drivers/video/backlight/lcd.c
@@ -5,7 +5,6 @@
*
*/
-#include <linux/version.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/device.h>
diff --git a/drivers/video/bw2.c b/drivers/video/bw2.c
index 3d20b2d47d46..f53bf3ba1278 100644
--- a/drivers/video/bw2.c
+++ b/drivers/video/bw2.c
@@ -51,7 +51,6 @@ static struct fb_ops bw2_ops = {
.fb_imageblit = cfb_imageblit,
.fb_mmap = bw2_mmap,
.fb_ioctl = bw2_ioctl,
- .fb_cursor = soft_cursor,
};
/* OBio addresses for the bwtwo registers */
diff --git a/drivers/video/cfbcopyarea.c b/drivers/video/cfbcopyarea.c
index 67711f7b11b1..cdc71572cf35 100644
--- a/drivers/video/cfbcopyarea.c
+++ b/drivers/video/cfbcopyarea.c
@@ -349,46 +349,10 @@ void cfb_copyarea(struct fb_info *p, const struct fb_copyarea *area)
unsigned long __iomem *dst = NULL, *src = NULL;
int bits = BITS_PER_LONG, bytes = bits >> 3;
int dst_idx = 0, src_idx = 0, rev_copy = 0;
- int x2, y2, vxres, vyres;
if (p->state != FBINFO_STATE_RUNNING)
return;
- /* We want rotation but lack hardware to do it for us. */
- if (!p->fbops->fb_rotate && p->var.rotate) {
- }
-
- vxres = p->var.xres_virtual;
- vyres = p->var.yres_virtual;
-
- if (area->dx > vxres || area->sx > vxres ||
- area->dy > vyres || area->sy > vyres)
- return;
-
- /* clip the destination
- * We could use hardware clipping but on many cards you get around
- * hardware clipping by writing to framebuffer directly.
- */
- x2 = area->dx + area->width;
- y2 = area->dy + area->height;
- dx = area->dx > 0 ? area->dx : 0;
- dy = area->dy > 0 ? area->dy : 0;
- x2 = x2 < vxres ? x2 : vxres;
- y2 = y2 < vyres ? y2 : vyres;
- width = x2 - dx;
- height = y2 - dy;
-
- if ((width==0) ||(height==0))
- return;
-
- /* update sx1,sy1 */
- sx += (dx - area->dx);
- sy += (dy - area->dy);
-
- /* the source must be completely inside the virtual screen */
- if (sx < 0 || sy < 0 || (sx + width) > vxres || (sy + height) > vyres)
- return;
-
/* if the beginning of the target area might overlap with the end of
the source area, be have to copy the area reverse. */
if ((dy == sy && dx > sx) || (dy > sy)) {
diff --git a/drivers/video/cfbfillrect.c b/drivers/video/cfbfillrect.c
index e4fc42b013eb..167d9314e6eb 100644
--- a/drivers/video/cfbfillrect.c
+++ b/drivers/video/cfbfillrect.c
@@ -344,7 +344,8 @@ bitfill_unaligned_rev(unsigned long __iomem *dst, int dst_idx, unsigned long pat
void cfb_fillrect(struct fb_info *p, const struct fb_fillrect *rect)
{
- unsigned long x2, y2, vxres, vyres, height, width, pat, fg;
+ unsigned long pat, fg;
+ unsigned long width = rect->width, height = rect->height;
int bits = BITS_PER_LONG, bytes = bits >> 3;
u32 bpp = p->var.bits_per_pixel;
unsigned long __iomem *dst;
@@ -353,27 +354,6 @@ void cfb_fillrect(struct fb_info *p, const struct fb_fillrect *rect)
if (p->state != FBINFO_STATE_RUNNING)
return;
- /* We want rotation but lack hardware to do it for us. */
- if (!p->fbops->fb_rotate && p->var.rotate) {
- }
-
- vxres = p->var.xres_virtual;
- vyres = p->var.yres_virtual;
-
- if (!rect->width || !rect->height ||
- rect->dx > vxres || rect->dy > vyres)
- return;
-
- /* We could use hardware clipping but on many cards you get around
- * hardware clipping by writing to framebuffer directly. */
-
- x2 = rect->dx + rect->width;
- y2 = rect->dy + rect->height;
- x2 = x2 < vxres ? x2 : vxres;
- y2 = y2 < vyres ? y2 : vyres;
- width = x2 - rect->dx;
- height = y2 - rect->dy;
-
if (p->fix.visual == FB_VISUAL_TRUECOLOR ||
p->fix.visual == FB_VISUAL_DIRECTCOLOR )
fg = ((u32 *) (p->pseudo_palette))[rect->color];
diff --git a/drivers/video/cfbimgblt.c b/drivers/video/cfbimgblt.c
index 4c123abaa843..a7770c4f17d0 100644
--- a/drivers/video/cfbimgblt.c
+++ b/drivers/video/cfbimgblt.c
@@ -80,10 +80,12 @@ static u32 cfb_tab32[] = {
#define LEFT_POS(bpp) (32 - bpp)
#define SHIFT_HIGH(val, bits) ((val) >> (bits))
#define SHIFT_LOW(val, bits) ((val) << (bits))
+#define BIT_NR(b) (7 - (b))
#else
#define LEFT_POS(bpp) (0)
#define SHIFT_HIGH(val, bits) ((val) << (bits))
#define SHIFT_LOW(val, bits) ((val) >> (bits))
+#define BIT_NR(b) (b)
#endif
static inline void color_imageblit(const struct fb_image *image,
@@ -177,7 +179,7 @@ static inline void slow_imageblit(const struct fb_image *image, struct fb_info *
while (j--) {
l--;
- color = (*s & (1 << l)) ? fgcolor : bgcolor;
+ color = (*s & 1 << (BIT_NR(l))) ? fgcolor : bgcolor;
color <<= LEFT_POS(bpp);
val |= SHIFT_HIGH(color, shift);
@@ -272,33 +274,13 @@ void cfb_imageblit(struct fb_info *p, const struct fb_image *image)
{
u32 fgcolor, bgcolor, start_index, bitstart, pitch_index = 0;
u32 bpl = sizeof(u32), bpp = p->var.bits_per_pixel;
- u32 width = image->width, height = image->height;
+ u32 width = image->width;
u32 dx = image->dx, dy = image->dy;
- int x2, y2, vxres, vyres;
u8 __iomem *dst1;
if (p->state != FBINFO_STATE_RUNNING)
return;
- vxres = p->var.xres_virtual;
- vyres = p->var.yres_virtual;
- /*
- * We could use hardware clipping but on many cards you get around
- * hardware clipping by writing to framebuffer directly like we are
- * doing here.
- */
- if (image->dx > vxres || image->dy > vyres)
- return;
-
- x2 = image->dx + image->width;
- y2 = image->dy + image->height;
- dx = image->dx > 0 ? image->dx : 0;
- dy = image->dy > 0 ? image->dy : 0;
- x2 = x2 < vxres ? x2 : vxres;
- y2 = y2 < vyres ? y2 : vyres;
- width = x2 - dx;
- height = y2 - dy;
-
bitstart = (dy * p->fix.line_length * 8) + (dx * bpp);
start_index = bitstart & (32 - 1);
pitch_index = (p->fix.line_length & (bpl - 1)) * 8;
diff --git a/drivers/video/cg14.c b/drivers/video/cg14.c
index 18e60b941e21..030d4b13b1c2 100644
--- a/drivers/video/cg14.c
+++ b/drivers/video/cg14.c
@@ -49,7 +49,6 @@ static struct fb_ops cg14_ops = {
.fb_imageblit = cfb_imageblit,
.fb_mmap = cg14_mmap,
.fb_ioctl = cg14_ioctl,
- .fb_cursor = soft_cursor,
};
#define CG14_MCR_INTENABLE_SHIFT 7
diff --git a/drivers/video/cg3.c b/drivers/video/cg3.c
index 6e7d8d45dc68..b94eee8c42d5 100644
--- a/drivers/video/cg3.c
+++ b/drivers/video/cg3.c
@@ -50,7 +50,6 @@ static struct fb_ops cg3_ops = {
.fb_imageblit = cfb_imageblit,
.fb_mmap = cg3_mmap,
.fb_ioctl = cg3_ioctl,
- .fb_cursor = soft_cursor,
};
diff --git a/drivers/video/cg6.c b/drivers/video/cg6.c
index 49a2545671d9..414c4409e924 100644
--- a/drivers/video/cg6.c
+++ b/drivers/video/cg6.c
@@ -54,7 +54,6 @@ static struct fb_ops cg6_ops = {
.fb_sync = cg6_sync,
.fb_mmap = cg6_mmap,
.fb_ioctl = cg6_ioctl,
- .fb_cursor = soft_cursor,
};
/* Offset of interesting structures in the OBIO space */
@@ -654,12 +653,6 @@ static void cg6_chip_init(struct fb_info *info)
sbus_writel(0, &fbc->clipminy);
sbus_writel(info->var.xres - 1, &fbc->clipmaxx);
sbus_writel(info->var.yres - 1, &fbc->clipmaxy);
-
- /* Disable cursor in Brooktree DAC. */
- sbus_writel(0x06 << 24, &par->bt->addr);
- tmp = sbus_readl(&par->bt->control);
- tmp &= ~(0x03 << 24);
- sbus_writel(tmp, &par->bt->control);
}
struct all_info {
diff --git a/drivers/video/chipsfb.c b/drivers/video/chipsfb.c
index 4131243cfdf8..bc061d4ec786 100644
--- a/drivers/video/chipsfb.c
+++ b/drivers/video/chipsfb.c
@@ -91,7 +91,6 @@ static struct fb_ops chipsfb_ops = {
.fb_fillrect = cfb_fillrect,
.fb_copyarea = cfb_copyarea,
.fb_imageblit = cfb_imageblit,
- .fb_cursor = soft_cursor,
};
static int chipsfb_check_var(struct fb_var_screeninfo *var,
diff --git a/drivers/video/cirrusfb.c b/drivers/video/cirrusfb.c
index a3040429c27b..2858c5c8ba3c 100644
--- a/drivers/video/cirrusfb.c
+++ b/drivers/video/cirrusfb.c
@@ -275,20 +275,20 @@ static const struct cirrusfb_board_info_rec {
#ifdef CONFIG_PCI
#define CHIP(id, btype) \
- { PCI_VENDOR_ID_CIRRUS, PCI_DEVICE_ID_##id, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (btype) }
+ { PCI_VENDOR_ID_CIRRUS, id, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (btype) }
static struct pci_device_id cirrusfb_pci_table[] = {
- CHIP( CIRRUS_5436, BT_ALPINE ),
- CHIP( CIRRUS_5434_8, BT_ALPINE ),
- CHIP( CIRRUS_5434_4, BT_ALPINE ),
- CHIP( CIRRUS_5430, BT_ALPINE ), /* GD-5440 has identical id */
- CHIP( CIRRUS_7543, BT_ALPINE ),
- CHIP( CIRRUS_7548, BT_ALPINE ),
- CHIP( CIRRUS_5480, BT_GD5480 ), /* MacPicasso probably */
- CHIP( CIRRUS_5446, BT_PICASSO4 ), /* Picasso 4 is a GD5446 */
- CHIP( CIRRUS_5462, BT_LAGUNA ), /* CL Laguna */
- CHIP( CIRRUS_5464, BT_LAGUNA ), /* CL Laguna 3D */
- CHIP( CIRRUS_5465, BT_LAGUNA ), /* CL Laguna 3DA*/
+ CHIP( PCI_DEVICE_ID_CIRRUS_5436, BT_ALPINE ),
+ CHIP( PCI_DEVICE_ID_CIRRUS_5434_8, BT_ALPINE ),
+ CHIP( PCI_DEVICE_ID_CIRRUS_5434_4, BT_ALPINE ),
+ CHIP( PCI_DEVICE_ID_CIRRUS_5430, BT_ALPINE ), /* GD-5440 is same id */
+ CHIP( PCI_DEVICE_ID_CIRRUS_7543, BT_ALPINE ),
+ CHIP( PCI_DEVICE_ID_CIRRUS_7548, BT_ALPINE ),
+ CHIP( PCI_DEVICE_ID_CIRRUS_5480, BT_GD5480 ), /* MacPicasso likely */
+ CHIP( PCI_DEVICE_ID_CIRRUS_5446, BT_PICASSO4 ), /* Picasso 4 is 5446 */
+ CHIP( PCI_DEVICE_ID_CIRRUS_5462, BT_LAGUNA ), /* CL Laguna */
+ CHIP( PCI_DEVICE_ID_CIRRUS_5464, BT_LAGUNA ), /* CL Laguna 3D */
+ CHIP( PCI_DEVICE_ID_CIRRUS_5465, BT_LAGUNA ), /* CL Laguna 3DA*/
{ 0, }
};
MODULE_DEVICE_TABLE(pci, cirrusfb_pci_table);
@@ -548,7 +548,6 @@ static struct fb_ops cirrusfb_ops = {
.fb_fillrect = cirrusfb_fillrect,
.fb_copyarea = cirrusfb_copyarea,
.fb_imageblit = cirrusfb_imageblit,
- .fb_cursor = soft_cursor,
};
/*--- Hardware Specific Routines -------------------------------------------*/
diff --git a/drivers/video/clps711xfb.c b/drivers/video/clps711xfb.c
index 8692e002986b..50b78af0fa24 100644
--- a/drivers/video/clps711xfb.c
+++ b/drivers/video/clps711xfb.c
@@ -219,7 +219,6 @@ static struct fb_ops clps7111fb_ops = {
.fb_fillrect = cfb_fillrect,
.fb_copyarea = cfb_copyarea,
.fb_imageblit = cfb_imageblit,
- .fb_cursor = soft_cursor,
};
static int
diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig
index eb83a7874c71..94c5f1392cce 100644
--- a/drivers/video/console/Kconfig
+++ b/drivers/video/console/Kconfig
@@ -28,7 +28,7 @@ config VGA_CONSOLE
config VIDEO_SELECT
bool "Video mode selection support"
- depends on (X86 || X86_64) && VGA_CONSOLE
+ depends on X86 && VGA_CONSOLE
---help---
This enables support for text mode selection on kernel startup. If
you want to take advantage of some high-resolution text mode your
@@ -98,6 +98,18 @@ config FRAMEBUFFER_CONSOLE
tristate "Framebuffer Console support"
depends on FB
select CRC32
+ help
+ Low-level framebuffer-based console driver.
+
+config FRAMEBUFFER_CONSOLE_ROTATION
+ bool "Framebuffer Console Rotation"
+ depends on FRAMEBUFFER_CONSOLE
+ help
+ Enable display rotation for the framebuffer console. This is done
+ in software and may be significantly slower than a normally oriented
+ display. Note that the rotation is done at the console level only
+ such that other users of the framebuffer will remain normally
+ oriented.
config STI_CONSOLE
tristate "STI text console"
@@ -110,7 +122,7 @@ config STI_CONSOLE
config FONTS
bool "Select compiled-in fonts"
- depends on FRAMEBUFFER_CONSOLE
+ depends on FRAMEBUFFER_CONSOLE || STI_CONSOLE
help
Say Y here if you would like to use fonts other than the default
your frame buffer console usually use.
@@ -123,7 +135,7 @@ config FONTS
config FONT_8x8
bool "VGA 8x8 font" if FONTS
- depends on FRAMEBUFFER_CONSOLE
+ depends on FRAMEBUFFER_CONSOLE || STI_CONSOLE
default y if !SPARC32 && !SPARC64 && !FONTS
help
This is the "high resolution" font for the VGA frame buffer (the one
@@ -137,7 +149,7 @@ config FONT_8x8
config FONT_8x16
bool "VGA 8x16 font" if FONTS
- depends on FRAMEBUFFER_CONSOLE || SGI_NEWPORT_CONSOLE=y || USB_SISUSBVGA_CON
+ depends on FRAMEBUFFER_CONSOLE || SGI_NEWPORT_CONSOLE=y || STI_CONSOLE || USB_SISUSBVGA_CON
default y if !SPARC32 && !SPARC64 && !FONTS
help
This is the "high resolution" font for the VGA frame buffer (the one
@@ -147,7 +159,7 @@ config FONT_8x16
config FONT_6x11
bool "Mac console 6x11 font (not supported by all drivers)" if FONTS
- depends on FRAMEBUFFER_CONSOLE
+ depends on FRAMEBUFFER_CONSOLE || STI_CONSOLE
default y if !SPARC32 && !SPARC64 && !FONTS && MAC
help
Small console font with Macintosh-style high-half glyphs. Some Mac
@@ -203,5 +215,12 @@ config FONT_10x18
big letters. It fits between the sun 12x22 and the normal 8x16 font.
If other fonts are too big or too small for you, say Y, otherwise say N.
+config FONT_RL
+ bool "console Roman Large 8x16 font" if FONTS
+ depends on FRAMEBUFFER_CONSOLE
+ help
+ This is the visually-appealing "RL" console font that is
+ included with the kbd package.
+
endmenu
diff --git a/drivers/video/console/Makefile b/drivers/video/console/Makefile
index 42c7b8dcd220..fed600c9ca55 100644
--- a/drivers/video/console/Makefile
+++ b/drivers/video/console/Makefile
@@ -15,6 +15,7 @@ font-objs-$(CONFIG_FONT_10x18) += font_10x18.o
font-objs-$(CONFIG_FONT_PEARL_8x8) += font_pearl_8x8.o
font-objs-$(CONFIG_FONT_ACORN_8x8) += font_acorn_8x8.o
font-objs-$(CONFIG_FONT_MINI_4x6) += font_mini_4x6.o
+font-objs-$(CONFIG_FONT_RL) += font_rl.o
font-objs += $(font-objs-y)
@@ -26,10 +27,14 @@ obj-$(CONFIG_PROM_CONSOLE) += promcon.o promcon_tbl.o
obj-$(CONFIG_STI_CONSOLE) += sticon.o sticore.o font.o
obj-$(CONFIG_VGA_CONSOLE) += vgacon.o
obj-$(CONFIG_MDA_CONSOLE) += mdacon.o
-obj-$(CONFIG_FRAMEBUFFER_CONSOLE) += fbcon.o bitblit.o font.o
+obj-$(CONFIG_FRAMEBUFFER_CONSOLE) += fbcon.o bitblit.o font.o softcursor.o
ifeq ($(CONFIG_FB_TILEBLITTING),y)
obj-$(CONFIG_FRAMEBUFFER_CONSOLE) += tileblit.o
endif
+ifeq ($(CONFIG_FRAMEBUFFER_CONSOLE_ROTATION),y)
+obj-$(CONFIG_FRAMEBUFFER_CONSOLE) += fbcon_rotate.o fbcon_cw.o fbcon_ud.o \
+ fbcon_ccw.o
+endif
obj-$(CONFIG_FB_STI) += sticore.o font.o
diff --git a/drivers/video/console/bitblit.c b/drivers/video/console/bitblit.c
index 9f70e512b88b..e65fc3ef7630 100644
--- a/drivers/video/console/bitblit.c
+++ b/drivers/video/console/bitblit.c
@@ -22,35 +22,6 @@
/*
* Accelerated handlers.
*/
-#define FBCON_ATTRIBUTE_UNDERLINE 1
-#define FBCON_ATTRIBUTE_REVERSE 2
-#define FBCON_ATTRIBUTE_BOLD 4
-
-static inline int real_y(struct display *p, int ypos)
-{
- int rows = p->vrows;
-
- ypos += p->yscroll;
- return ypos < rows ? ypos : ypos - rows;
-}
-
-
-static inline int get_attribute(struct fb_info *info, u16 c)
-{
- int attribute = 0;
-
- if (fb_get_color_depth(&info->var, &info->fix) == 1) {
- if (attr_underline(c))
- attribute |= FBCON_ATTRIBUTE_UNDERLINE;
- if (attr_reverse(c))
- attribute |= FBCON_ATTRIBUTE_REVERSE;
- if (attr_bold(c))
- attribute |= FBCON_ATTRIBUTE_BOLD;
- }
-
- return attribute;
-}
-
static inline void update_attr(u8 *dst, u8 *src, int attribute,
struct vc_data *vc)
{
@@ -272,6 +243,7 @@ static void bit_cursor(struct vc_data *vc, struct fb_info *info,
int w = (vc->vc_font.width + 7) >> 3, c;
int y = real_y(p, vc->vc_y);
int attribute, use_sw = (vc->vc_cursor_type & 0x10);
+ int err = 1;
char *src;
cursor.set = 0;
@@ -408,11 +380,27 @@ static void bit_cursor(struct vc_data *vc, struct fb_info *info,
cursor.image.depth = 1;
cursor.rop = ROP_XOR;
- info->fbops->fb_cursor(info, &cursor);
+ if (info->fbops->fb_cursor)
+ err = info->fbops->fb_cursor(info, &cursor);
+
+ if (err)
+ soft_cursor(info, &cursor);
ops->cursor_reset = 0;
}
+static int bit_update_start(struct fb_info *info)
+{
+ struct fbcon_ops *ops = info->fbcon_par;
+ int err;
+
+ err = fb_pan_display(info, &ops->var);
+ ops->var.xoffset = info->var.xoffset;
+ ops->var.yoffset = info->var.yoffset;
+ ops->var.vmode = info->var.vmode;
+ return err;
+}
+
void fbcon_set_bitops(struct fbcon_ops *ops)
{
ops->bmove = bit_bmove;
@@ -420,6 +408,11 @@ void fbcon_set_bitops(struct fbcon_ops *ops)
ops->putcs = bit_putcs;
ops->clear_margins = bit_clear_margins;
ops->cursor = bit_cursor;
+ ops->update_start = bit_update_start;
+ ops->rotate_font = NULL;
+
+ if (ops->rotate)
+ fbcon_set_rotate(ops);
}
EXPORT_SYMBOL(fbcon_set_bitops);
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
index 0fc8bb499c3f..e7802ffe549a 100644
--- a/drivers/video/console/fbcon.c
+++ b/drivers/video/console/fbcon.c
@@ -107,6 +107,8 @@ enum {
};
struct display fb_display[MAX_NR_CONSOLES];
+EXPORT_SYMBOL(fb_display);
+
static signed char con2fb_map[MAX_NR_CONSOLES];
static signed char con2fb_map_boot[MAX_NR_CONSOLES];
static int logo_height;
@@ -130,6 +132,9 @@ static char fontname[40];
/* current fb_info */
static int info_idx = -1;
+/* console rotation */
+static int rotate;
+
static const struct consw fb_con;
#define CM_SOFTBACK (8)
@@ -176,7 +181,6 @@ static int fbcon_scrolldelta(struct vc_data *vc, int lines);
/*
* Internal routines
*/
-static __inline__ int real_y(struct display *p, int ypos);
static __inline__ void ywrap_up(struct vc_data *vc, int count);
static __inline__ void ywrap_down(struct vc_data *vc, int count);
static __inline__ void ypan_up(struct vc_data *vc, int count);
@@ -189,6 +193,8 @@ static void fbcon_preset_disp(struct fb_info *info, struct fb_var_screeninfo *va
int unit);
static void fbcon_redraw_move(struct vc_data *vc, struct display *p,
int line, int count, int dy);
+static void fbcon_modechanged(struct fb_info *info);
+static void fbcon_set_all_vcs(struct fb_info *info);
#ifdef CONFIG_MAC
/*
@@ -203,6 +209,88 @@ static irqreturn_t fb_vbl_detect(int irq, void *dummy, struct pt_regs *fp)
}
#endif
+#ifdef CONFIG_FRAMEBUFFER_CONSOLE_ROTATION
+static inline void fbcon_set_rotation(struct fb_info *info, struct display *p)
+{
+ struct fbcon_ops *ops = info->fbcon_par;
+
+ if (!(info->flags & FBINFO_MISC_TILEBLITTING) &&
+ p->con_rotate < 4)
+ ops->rotate = p->con_rotate;
+ else
+ ops->rotate = 0;
+}
+
+static void fbcon_rotate(struct fb_info *info, u32 rotate)
+{
+ struct fbcon_ops *ops= info->fbcon_par;
+ struct fb_info *fb_info;
+
+ if (!ops || ops->currcon == -1)
+ return;
+
+ fb_info = registered_fb[con2fb_map[ops->currcon]];
+
+ if (info == fb_info) {
+ struct display *p = &fb_display[ops->currcon];
+
+ if (rotate < 4)
+ p->con_rotate = rotate;
+ else
+ p->con_rotate = 0;
+
+ fbcon_modechanged(info);
+ }
+}
+
+static void fbcon_rotate_all(struct fb_info *info, u32 rotate)
+{
+ struct fbcon_ops *ops = info->fbcon_par;
+ struct vc_data *vc;
+ struct display *p;
+ int i;
+
+ if (!ops || ops->currcon < 0 || rotate > 3)
+ return;
+
+ for (i = 0; i < MAX_NR_CONSOLES; i++) {
+ vc = vc_cons[i].d;
+ if (!vc || vc->vc_mode != KD_TEXT ||
+ registered_fb[con2fb_map[i]] != info)
+ continue;
+
+ p = &fb_display[vc->vc_num];
+ p->con_rotate = rotate;
+ }
+
+ fbcon_set_all_vcs(info);
+}
+#else
+static inline void fbcon_set_rotation(struct fb_info *info, struct display *p)
+{
+ struct fbcon_ops *ops = info->fbcon_par;
+
+ ops->rotate = FB_ROTATE_UR;
+}
+
+static void fbcon_rotate(struct fb_info *info, u32 rotate)
+{
+ return;
+}
+
+static void fbcon_rotate_all(struct fb_info *info, u32 rotate)
+{
+ return;
+}
+#endif /* CONFIG_FRAMEBUFFER_CONSOLE_ROTATION */
+
+static int fbcon_get_rotate(struct fb_info *info)
+{
+ struct fbcon_ops *ops = info->fbcon_par;
+
+ return (ops) ? ops->rotate : 0;
+}
+
static inline int fbcon_is_inactive(struct vc_data *vc, struct fb_info *info)
{
struct fbcon_ops *ops = info->fbcon_par;
@@ -281,6 +369,18 @@ static inline int get_color(struct vc_data *vc, struct fb_info *info,
return color;
}
+static void fbcon_update_softback(struct vc_data *vc)
+{
+ int l = fbcon_softback_size / vc->vc_size_row;
+
+ if (l > 5)
+ softback_end = softback_buf + l * vc->vc_size_row;
+ else
+ /* Smaller scrollback makes no sense, and 0 would screw
+ the operation totally */
+ softback_top = 0;
+}
+
static void fb_flashcursor(void *private)
{
struct fb_info *info = private;
@@ -410,6 +510,14 @@ static int __init fb_console_setup(char *this_opt)
last_fb_vc = simple_strtoul(options, &options, 10) - 1;
fbcon_is_default = 0;
}
+
+ if (!strncmp(options, "rotate:", 7)) {
+ options += 7;
+ if (*options)
+ rotate = simple_strtoul(options, &options, 0);
+ if (rotate > 3)
+ rotate = 0;
+ }
}
return 0;
}
@@ -468,6 +576,7 @@ static void fbcon_prepare_logo(struct vc_data *vc, struct fb_info *info,
int cols, int rows, int new_cols, int new_rows)
{
/* Need to make room for the logo */
+ struct fbcon_ops *ops = info->fbcon_par;
int cnt, erase = vc->vc_video_erase_char, step;
unsigned short *save = NULL, *r, *q;
@@ -477,7 +586,7 @@ static void fbcon_prepare_logo(struct vc_data *vc, struct fb_info *info,
*/
if (fb_get_color_depth(&info->var, &info->fix) == 1)
erase &= ~0x400;
- logo_height = fb_prepare_logo(info);
+ logo_height = fb_prepare_logo(info, ops->rotate);
logo_lines = (logo_height + vc->vc_font.height - 1) /
vc->vc_font.height;
q = (unsigned short *) (vc->vc_origin +
@@ -546,16 +655,24 @@ static void set_blitting_type(struct vc_data *vc, struct fb_info *info,
if ((info->flags & FBINFO_MISC_TILEBLITTING))
fbcon_set_tileops(vc, info, p, ops);
- else
+ else {
+ struct display *disp;
+
+ disp = (p) ? p : &fb_display[vc->vc_num];
+ fbcon_set_rotation(info, disp);
fbcon_set_bitops(ops);
+ }
}
#else
static void set_blitting_type(struct vc_data *vc, struct fb_info *info,
struct display *p)
{
struct fbcon_ops *ops = info->fbcon_par;
+ struct display *disp;
info->flags &= ~FBINFO_MISC_TILEBLITTING;
+ disp = (p) ? p : &fb_display[vc->vc_num];
+ fbcon_set_rotation(info, disp);
fbcon_set_bitops(ops);
}
#endif /* CONFIG_MISC_TILEBLITTING */
@@ -615,9 +732,19 @@ static int con2fb_release_oldinfo(struct vc_data *vc, struct fb_info *oldinfo,
fbcon_del_cursor_timer(oldinfo);
kfree(ops->cursor_state.mask);
kfree(ops->cursor_data);
+ kfree(ops->fontbuffer);
kfree(oldinfo->fbcon_par);
oldinfo->fbcon_par = NULL;
module_put(oldinfo->fbops->owner);
+ /*
+ If oldinfo and newinfo are driving the same hardware,
+ the fb_release() method of oldinfo may attempt to
+ restore the hardware state. This will leave the
+ newinfo in an undefined state. Thus, a call to
+ fb_set_par() may be needed for the newinfo.
+ */
+ if (newinfo->fbops->fb_set_par)
+ newinfo->fbops->fb_set_par(newinfo);
}
return err;
@@ -806,7 +933,9 @@ static const char *fbcon_startup(void)
memset(ops, 0, sizeof(struct fbcon_ops));
ops->currcon = -1;
ops->graphics = 1;
+ ops->cur_rotate = -1;
info->fbcon_par = ops;
+ p->con_rotate = rotate;
set_blitting_type(vc, info, NULL);
if (info->fix.type != FB_TYPE_TEXT) {
@@ -845,8 +974,10 @@ static const char *fbcon_startup(void)
vc->vc_font.charcount = 256; /* FIXME Need to support more fonts */
}
- cols = info->var.xres / vc->vc_font.width;
- rows = info->var.yres / vc->vc_font.height;
+ cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres);
+ rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
+ cols /= vc->vc_font.width;
+ rows /= vc->vc_font.height;
vc_resize(vc, cols, rows);
DPRINTK("mode: %s\n", info->fix.id);
@@ -932,8 +1063,6 @@ static void fbcon_init(struct vc_data *vc, int init)
(info->fix.type == FB_TYPE_TEXT))
logo = 0;
- info->var.xoffset = info->var.yoffset = p->yscroll = 0; /* reset wrap/pan */
-
if (var_to_display(p, &info->var, info))
return;
@@ -965,13 +1094,18 @@ static void fbcon_init(struct vc_data *vc, int init)
if (!*vc->vc_uni_pagedir_loc)
con_copy_unimap(vc, svc);
+ ops = info->fbcon_par;
+ p->con_rotate = rotate;
+ set_blitting_type(vc, info, NULL);
+
cols = vc->vc_cols;
rows = vc->vc_rows;
- new_cols = info->var.xres / vc->vc_font.width;
- new_rows = info->var.yres / vc->vc_font.height;
+ new_cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres);
+ new_rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
+ new_cols /= vc->vc_font.width;
+ new_rows /= vc->vc_font.height;
vc_resize(vc, new_cols, new_rows);
- ops = info->fbcon_par;
/*
* We must always set the mode. The mode of the previous console
* driver could be in the same resolution but we are using different
@@ -1007,16 +1141,14 @@ static void fbcon_init(struct vc_data *vc, int init)
if (logo)
fbcon_prepare_logo(vc, info, cols, rows, new_cols, new_rows);
- if (vc == svc && softback_buf) {
- int l = fbcon_softback_size / vc->vc_size_row;
- if (l > 5)
- softback_end = softback_buf + l * vc->vc_size_row;
- else {
- /* Smaller scrollback makes no sense, and 0 would screw
- the operation totally */
- softback_top = 0;
- }
+ if (vc == svc && softback_buf)
+ fbcon_update_softback(vc);
+
+ if (ops->rotate_font && ops->rotate_font(info, vc, p)) {
+ ops->rotate = FB_ROTATE_UR;
+ set_blitting_type(vc, info, p);
}
+
}
static void fbcon_deinit(struct vc_data *vc)
@@ -1053,15 +1185,6 @@ static void fbcon_deinit(struct vc_data *vc)
* restriction is simplicity & efficiency at the moment.
*/
-static __inline__ int real_y(struct display *p, int ypos)
-{
- int rows = p->vrows;
-
- ypos += p->yscroll;
- return ypos < rows ? ypos : ypos - rows;
-}
-
-
static void fbcon_clear(struct vc_data *vc, int sy, int sx, int height,
int width)
{
@@ -1149,13 +1272,6 @@ static int scrollback_phys_max = 0;
static int scrollback_max = 0;
static int scrollback_current = 0;
-static int update_var(int con, struct fb_info *info)
-{
- if (con == ((struct fbcon_ops *)info->fbcon_par)->currcon)
- return fb_pan_display(info, &info->var);
- return 0;
-}
-
/*
* If no vc is existent yet, just set struct display
*/
@@ -1165,7 +1281,6 @@ static void fbcon_preset_disp(struct fb_info *info, struct fb_var_screeninfo *va
struct display *p = &fb_display[unit];
struct display *t = &fb_display[fg_console];
- var->xoffset = var->yoffset = p->yscroll = 0;
if (var_to_display(p, var, info))
return;
@@ -1181,9 +1296,9 @@ static void fbcon_set_disp(struct fb_info *info, struct fb_var_screeninfo *var,
struct display *p = &fb_display[vc->vc_num], *t;
struct vc_data **default_mode = vc->vc_display_fg;
struct vc_data *svc = *default_mode;
+ struct fbcon_ops *ops = info->fbcon_par;
int rows, cols, charcnt = 256;
- var->xoffset = var->yoffset = p->yscroll = 0;
if (var_to_display(p, var, info))
return;
t = &fb_display[svc->vc_num];
@@ -1200,9 +1315,10 @@ static void fbcon_set_disp(struct fb_info *info, struct fb_var_screeninfo *var,
var->activate = FB_ACTIVATE_NOW;
info->var.activate = var->activate;
- info->var.yoffset = info->var.xoffset = 0;
+ var->yoffset = info->var.yoffset;
+ var->xoffset = info->var.xoffset;
fb_set_var(info, var);
-
+ ops->var = info->var;
vc->vc_can_do_color = (fb_get_color_depth(&info->var, &info->fix)!=1);
vc->vc_complement_mask = vc->vc_can_do_color ? 0x7700 : 0x0800;
if (charcnt == 256) {
@@ -1218,38 +1334,32 @@ static void fbcon_set_disp(struct fb_info *info, struct fb_var_screeninfo *var,
if (!*vc->vc_uni_pagedir_loc)
con_copy_unimap(vc, svc);
- cols = var->xres / vc->vc_font.width;
- rows = var->yres / vc->vc_font.height;
+ cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres);
+ rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
+ cols /= vc->vc_font.width;
+ rows /= vc->vc_font.height;
vc_resize(vc, cols, rows);
+
if (CON_IS_VISIBLE(vc)) {
update_screen(vc);
- if (softback_buf) {
- int l = fbcon_softback_size / vc->vc_size_row;
-
- if (l > 5)
- softback_end = softback_buf + l *
- vc->vc_size_row;
- else {
- /* Smaller scrollback makes no sense, and 0
- would screw the operation totally */
- softback_top = 0;
- }
- }
+ if (softback_buf)
+ fbcon_update_softback(vc);
}
}
static __inline__ void ywrap_up(struct vc_data *vc, int count)
{
struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
+ struct fbcon_ops *ops = info->fbcon_par;
struct display *p = &fb_display[vc->vc_num];
p->yscroll += count;
if (p->yscroll >= p->vrows) /* Deal with wrap */
p->yscroll -= p->vrows;
- info->var.xoffset = 0;
- info->var.yoffset = p->yscroll * vc->vc_font.height;
- info->var.vmode |= FB_VMODE_YWRAP;
- update_var(vc->vc_num, info);
+ ops->var.xoffset = 0;
+ ops->var.yoffset = p->yscroll * vc->vc_font.height;
+ ops->var.vmode |= FB_VMODE_YWRAP;
+ ops->update_start(info);
scrollback_max += count;
if (scrollback_max > scrollback_phys_max)
scrollback_max = scrollback_phys_max;
@@ -1259,15 +1369,16 @@ static __inline__ void ywrap_up(struct vc_data *vc, int count)
static __inline__ void ywrap_down(struct vc_data *vc, int count)
{
struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
+ struct fbcon_ops *ops = info->fbcon_par;
struct display *p = &fb_display[vc->vc_num];
p->yscroll -= count;
if (p->yscroll < 0) /* Deal with wrap */
p->yscroll += p->vrows;
- info->var.xoffset = 0;
- info->var.yoffset = p->yscroll * vc->vc_font.height;
- info->var.vmode |= FB_VMODE_YWRAP;
- update_var(vc->vc_num, info);
+ ops->var.xoffset = 0;
+ ops->var.yoffset = p->yscroll * vc->vc_font.height;
+ ops->var.vmode |= FB_VMODE_YWRAP;
+ ops->update_start(info);
scrollback_max -= count;
if (scrollback_max < 0)
scrollback_max = 0;
@@ -1286,10 +1397,11 @@ static __inline__ void ypan_up(struct vc_data *vc, int count)
0, 0, 0, vc->vc_rows, vc->vc_cols);
p->yscroll -= p->vrows - vc->vc_rows;
}
- info->var.xoffset = 0;
- info->var.yoffset = p->yscroll * vc->vc_font.height;
- info->var.vmode &= ~FB_VMODE_YWRAP;
- update_var(vc->vc_num, info);
+
+ ops->var.xoffset = 0;
+ ops->var.yoffset = p->yscroll * vc->vc_font.height;
+ ops->var.vmode &= ~FB_VMODE_YWRAP;
+ ops->update_start(info);
fbcon_clear_margins(vc, 1);
scrollback_max += count;
if (scrollback_max > scrollback_phys_max)
@@ -1300,6 +1412,7 @@ static __inline__ void ypan_up(struct vc_data *vc, int count)
static __inline__ void ypan_up_redraw(struct vc_data *vc, int t, int count)
{
struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
+ struct fbcon_ops *ops = info->fbcon_par;
struct display *p = &fb_display[vc->vc_num];
int redraw = 0;
@@ -1309,12 +1422,13 @@ static __inline__ void ypan_up_redraw(struct vc_data *vc, int t, int count)
redraw = 1;
}
- info->var.xoffset = 0;
- info->var.yoffset = p->yscroll * vc->vc_font.height;
- info->var.vmode &= ~FB_VMODE_YWRAP;
if (redraw)
fbcon_redraw_move(vc, p, t + count, vc->vc_rows - count, t);
- update_var(vc->vc_num, info);
+
+ ops->var.xoffset = 0;
+ ops->var.yoffset = p->yscroll * vc->vc_font.height;
+ ops->var.vmode &= ~FB_VMODE_YWRAP;
+ ops->update_start(info);
fbcon_clear_margins(vc, 1);
scrollback_max += count;
if (scrollback_max > scrollback_phys_max)
@@ -1334,10 +1448,11 @@ static __inline__ void ypan_down(struct vc_data *vc, int count)
0, vc->vc_rows, vc->vc_cols);
p->yscroll += p->vrows - vc->vc_rows;
}
- info->var.xoffset = 0;
- info->var.yoffset = p->yscroll * vc->vc_font.height;
- info->var.vmode &= ~FB_VMODE_YWRAP;
- update_var(vc->vc_num, info);
+
+ ops->var.xoffset = 0;
+ ops->var.yoffset = p->yscroll * vc->vc_font.height;
+ ops->var.vmode &= ~FB_VMODE_YWRAP;
+ ops->update_start(info);
fbcon_clear_margins(vc, 1);
scrollback_max -= count;
if (scrollback_max < 0)
@@ -1348,6 +1463,7 @@ static __inline__ void ypan_down(struct vc_data *vc, int count)
static __inline__ void ypan_down_redraw(struct vc_data *vc, int t, int count)
{
struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
+ struct fbcon_ops *ops = info->fbcon_par;
struct display *p = &fb_display[vc->vc_num];
int redraw = 0;
@@ -1356,12 +1472,14 @@ static __inline__ void ypan_down_redraw(struct vc_data *vc, int t, int count)
p->yscroll += p->vrows - vc->vc_rows;
redraw = 1;
}
- info->var.xoffset = 0;
- info->var.yoffset = p->yscroll * vc->vc_font.height;
- info->var.vmode &= ~FB_VMODE_YWRAP;
+
if (redraw)
fbcon_redraw_move(vc, p, t, vc->vc_rows - count, t + count);
- update_var(vc->vc_num, info);
+
+ ops->var.xoffset = 0;
+ ops->var.yoffset = p->yscroll * vc->vc_font.height;
+ ops->var.vmode &= ~FB_VMODE_YWRAP;
+ ops->update_start(info);
fbcon_clear_margins(vc, 1);
scrollback_max -= count;
if (scrollback_max < 0)
@@ -1835,31 +1953,41 @@ static void fbcon_bmove_rec(struct vc_data *vc, struct display *p, int sy, int s
height, width);
}
-static __inline__ void updatescrollmode(struct display *p, struct fb_info *info,
+static __inline__ void updatescrollmode(struct display *p,
+ struct fb_info *info,
struct vc_data *vc)
{
+ struct fbcon_ops *ops = info->fbcon_par;
int fh = vc->vc_font.height;
int cap = info->flags;
- int good_pan = (cap & FBINFO_HWACCEL_YPAN)
- && divides(info->fix.ypanstep, vc->vc_font.height)
- && info->var.yres_virtual > info->var.yres;
- int good_wrap = (cap & FBINFO_HWACCEL_YWRAP)
- && divides(info->fix.ywrapstep, vc->vc_font.height)
- && divides(vc->vc_font.height, info->var.yres_virtual);
+ u16 t = 0;
+ int ypan = FBCON_SWAP(ops->rotate, info->fix.ypanstep,
+ info->fix.xpanstep);
+ int ywrap = FBCON_SWAP(ops->rotate, info->fix.ywrapstep, t);
+ int yres = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
+ int vyres = FBCON_SWAP(ops->rotate, info->var.yres_virtual,
+ info->var.xres_virtual);
+ int good_pan = (cap & FBINFO_HWACCEL_YPAN) &&
+ divides(ypan, vc->vc_font.height) && vyres > yres;
+ int good_wrap = (cap & FBINFO_HWACCEL_YWRAP) &&
+ divides(ywrap, vc->vc_font.height) &&
+ divides(vc->vc_font.height, vyres);
int reading_fast = cap & FBINFO_READS_FAST;
- int fast_copyarea = (cap & FBINFO_HWACCEL_COPYAREA) && !(cap & FBINFO_HWACCEL_DISABLED);
- int fast_imageblit = (cap & FBINFO_HWACCEL_IMAGEBLIT) && !(cap & FBINFO_HWACCEL_DISABLED);
-
- p->vrows = info->var.yres_virtual/fh;
- if (info->var.yres > (fh * (vc->vc_rows + 1)))
- p->vrows -= (info->var.yres - (fh * vc->vc_rows)) / fh;
- if ((info->var.yres % fh) && (info->var.yres_virtual % fh <
- info->var.yres % fh))
+ int fast_copyarea = (cap & FBINFO_HWACCEL_COPYAREA) &&
+ !(cap & FBINFO_HWACCEL_DISABLED);
+ int fast_imageblit = (cap & FBINFO_HWACCEL_IMAGEBLIT) &&
+ !(cap & FBINFO_HWACCEL_DISABLED);
+
+ p->vrows = vyres/fh;
+ if (yres > (fh * (vc->vc_rows + 1)))
+ p->vrows -= (yres - (fh * vc->vc_rows)) / fh;
+ if ((yres % fh) && (vyres % fh < yres % fh))
p->vrows--;
if (good_wrap || good_pan) {
if (reading_fast || fast_copyarea)
- p->scrollmode = good_wrap ? SCROLL_WRAP_MOVE : SCROLL_PAN_MOVE;
+ p->scrollmode = good_wrap ?
+ SCROLL_WRAP_MOVE : SCROLL_PAN_MOVE;
else
p->scrollmode = good_wrap ? SCROLL_REDRAW :
SCROLL_PAN_REDRAW;
@@ -1875,41 +2003,34 @@ static int fbcon_resize(struct vc_data *vc, unsigned int width,
unsigned int height)
{
struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
+ struct fbcon_ops *ops = info->fbcon_par;
struct display *p = &fb_display[vc->vc_num];
struct fb_var_screeninfo var = info->var;
- int x_diff, y_diff;
- int fw = vc->vc_font.width;
- int fh = vc->vc_font.height;
-
- var.xres = width * fw;
- var.yres = height * fh;
+ int x_diff, y_diff, virt_w, virt_h, virt_fw, virt_fh;
+
+ virt_w = FBCON_SWAP(ops->rotate, width, height);
+ virt_h = FBCON_SWAP(ops->rotate, height, width);
+ virt_fw = FBCON_SWAP(ops->rotate, vc->vc_font.width,
+ vc->vc_font.height);
+ virt_fh = FBCON_SWAP(ops->rotate, vc->vc_font.height,
+ vc->vc_font.width);
+ var.xres = virt_w * virt_fw;
+ var.yres = virt_h * virt_fh;
x_diff = info->var.xres - var.xres;
y_diff = info->var.yres - var.yres;
- if (x_diff < 0 || x_diff > fw || (y_diff < 0 || y_diff > fh)) {
+ if (x_diff < 0 || x_diff > virt_fw ||
+ y_diff < 0 || y_diff > virt_fh) {
struct fb_videomode *mode;
DPRINTK("attempting resize %ix%i\n", var.xres, var.yres);
mode = fb_find_best_mode(&var, &info->modelist);
if (mode == NULL)
return -EINVAL;
+ display_to_var(&var, p);
fb_videomode_to_var(&var, mode);
- if (width > var.xres/fw || height > var.yres/fh)
+
+ if (virt_w > var.xres/virt_fw || virt_h > var.yres/virt_fh)
return -EINVAL;
- /*
- * The following can probably have any value... Do we need to
- * set all of them?
- */
- var.bits_per_pixel = p->bits_per_pixel;
- var.xres_virtual = p->xres_virtual;
- var.yres_virtual = p->yres_virtual;
- var.accel_flags = p->accel_flags;
- var.width = p->width;
- var.height = p->height;
- var.red = p->red;
- var.green = p->green;
- var.blue = p->blue;
- var.transp = p->transp;
- var.nonstd = p->nonstd;
DPRINTK("resize now %ix%i\n", var.xres, var.yres);
if (CON_IS_VISIBLE(vc)) {
@@ -1918,6 +2039,7 @@ static int fbcon_resize(struct vc_data *vc, unsigned int width,
fb_set_var(info, &var);
}
var_to_display(p, &info->var, info);
+ ops->var = info->var;
}
updatescrollmode(p, info, vc);
return 0;
@@ -1926,26 +2048,20 @@ static int fbcon_resize(struct vc_data *vc, unsigned int width,
static int fbcon_switch(struct vc_data *vc)
{
struct fb_info *info, *old_info = NULL;
+ struct fbcon_ops *ops;
struct display *p = &fb_display[vc->vc_num];
struct fb_var_screeninfo var;
int i, prev_console;
info = registered_fb[con2fb_map[vc->vc_num]];
+ ops = info->fbcon_par;
if (softback_top) {
- int l = fbcon_softback_size / vc->vc_size_row;
if (softback_lines)
fbcon_set_origin(vc);
softback_top = softback_curr = softback_in = softback_buf;
softback_lines = 0;
-
- if (l > 5)
- softback_end = softback_buf + l * vc->vc_size_row;
- else {
- /* Smaller scrollback makes no sense, and 0 would screw
- the operation totally */
- softback_top = 0;
- }
+ fbcon_update_softback(vc);
}
if (logo_shown >= 0) {
@@ -1957,7 +2073,7 @@ static int fbcon_switch(struct vc_data *vc)
logo_shown = FBCON_LOGO_CANSHOW;
}
- prev_console = ((struct fbcon_ops *)info->fbcon_par)->currcon;
+ prev_console = ops->currcon;
if (prev_console != -1)
old_info = registered_fb[con2fb_map[prev_console]];
/*
@@ -1970,9 +2086,9 @@ static int fbcon_switch(struct vc_data *vc)
*/
for (i = 0; i < FB_MAX; i++) {
if (registered_fb[i] != NULL && registered_fb[i]->fbcon_par) {
- struct fbcon_ops *ops = registered_fb[i]->fbcon_par;
+ struct fbcon_ops *o = registered_fb[i]->fbcon_par;
- ops->currcon = vc->vc_num;
+ o->currcon = vc->vc_num;
}
}
memset(&var, 0, sizeof(struct fb_var_screeninfo));
@@ -1984,8 +2100,11 @@ static int fbcon_switch(struct vc_data *vc)
* in fb_set_var()
*/
info->var.activate = var.activate;
- info->var.yoffset = info->var.xoffset = p->yscroll = 0;
+ var.yoffset = info->var.yoffset;
+ var.xoffset = info->var.xoffset;
+ var.vmode = info->var.vmode;
fb_set_var(info, &var);
+ ops->var = info->var;
if (old_info != NULL && old_info != info) {
if (info->fbops->fb_set_par)
@@ -1995,7 +2114,12 @@ static int fbcon_switch(struct vc_data *vc)
}
set_blitting_type(vc, info, p);
- ((struct fbcon_ops *)info->fbcon_par)->cursor_reset = 1;
+ ops->cursor_reset = 1;
+
+ if (ops->rotate_font && ops->rotate_font(info, vc, p)) {
+ ops->rotate = FB_ROTATE_UR;
+ set_blitting_type(vc, info, p);
+ }
vc->vc_can_do_color = (fb_get_color_depth(&info->var, &info->fix)!=1);
vc->vc_complement_mask = vc->vc_can_do_color ? 0x7700 : 0x0800;
@@ -2015,10 +2139,11 @@ static int fbcon_switch(struct vc_data *vc)
scrollback_phys_max = 0;
break;
}
+
scrollback_max = 0;
scrollback_current = 0;
-
- update_var(vc->vc_num, info);
+ ops->var.xoffset = ops->var.yoffset = p->yscroll = 0;
+ ops->update_start(info);
fbcon_set_palette(vc, color_table);
fbcon_clear_margins(vc, 0);
@@ -2026,7 +2151,7 @@ static int fbcon_switch(struct vc_data *vc)
logo_shown = fg_console;
/* This is protected above by initmem_freed */
- fb_show_logo(info);
+ fb_show_logo(info, ops->rotate);
update_region(vc,
vc->vc_origin + vc->vc_size_row * vc->vc_top,
vc->vc_size_row * (vc->vc_bottom -
@@ -2065,6 +2190,7 @@ static int fbcon_blank(struct vc_data *vc, int blank, int mode_switch)
var.activate = FB_ACTIVATE_NOW | FB_ACTIVATE_FORCE;
fb_set_var(info, &var);
ops->graphics = 0;
+ ops->var = info->var;
}
}
@@ -2153,6 +2279,7 @@ static int fbcon_do_set_font(struct vc_data *vc, int w, int h,
const u8 * data, int userfont)
{
struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
+ struct fbcon_ops *ops = info->fbcon_par;
struct display *p = &fb_display[vc->vc_num];
int resize;
int cnt;
@@ -2232,20 +2359,15 @@ static int fbcon_do_set_font(struct vc_data *vc, int w, int h,
}
if (resize) {
- /* reset wrap/pan */
- info->var.xoffset = info->var.yoffset = p->yscroll = 0;
- vc_resize(vc, info->var.xres / w, info->var.yres / h);
- if (CON_IS_VISIBLE(vc) && softback_buf) {
- int l = fbcon_softback_size / vc->vc_size_row;
- if (l > 5)
- softback_end =
- softback_buf + l * vc->vc_size_row;
- else {
- /* Smaller scrollback makes no sense, and 0 would screw
- the operation totally */
- softback_top = 0;
- }
- }
+ int cols, rows;
+
+ cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres);
+ rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
+ cols /= w;
+ rows /= h;
+ vc_resize(vc, cols, rows);
+ if (CON_IS_VISIBLE(vc) && softback_buf)
+ fbcon_update_softback(vc);
} else if (CON_IS_VISIBLE(vc)
&& vc->vc_mode == KD_TEXT) {
fbcon_clear_margins(vc, 0);
@@ -2471,6 +2593,7 @@ static void fbcon_invert_region(struct vc_data *vc, u16 * p, int cnt)
static int fbcon_scrolldelta(struct vc_data *vc, int lines)
{
struct fb_info *info = registered_fb[con2fb_map[fg_console]];
+ struct fbcon_ops *ops = info->fbcon_par;
struct display *p = &fb_display[fg_console];
int offset, limit, scrollback_old;
@@ -2547,9 +2670,11 @@ static int fbcon_scrolldelta(struct vc_data *vc, int lines)
offset += limit;
else if (offset >= limit)
offset -= limit;
- info->var.xoffset = 0;
- info->var.yoffset = offset * vc->vc_font.height;
- update_var(vc->vc_num, info);
+
+ ops->var.xoffset = 0;
+ ops->var.yoffset = offset * vc->vc_font.height;
+ ops->update_start(info);
+
if (!scrollback_current)
fbcon_cursor(vc, CM_DRAW);
return 0;
@@ -2597,34 +2722,29 @@ static void fbcon_modechanged(struct fb_info *info)
if (!ops || ops->currcon < 0)
return;
vc = vc_cons[ops->currcon].d;
- if (vc->vc_mode != KD_TEXT || registered_fb[con2fb_map[ops->currcon]] != info)
+ if (vc->vc_mode != KD_TEXT ||
+ registered_fb[con2fb_map[ops->currcon]] != info)
return;
p = &fb_display[vc->vc_num];
-
- info->var.xoffset = info->var.yoffset = p->yscroll = 0;
+ set_blitting_type(vc, info, p);
if (CON_IS_VISIBLE(vc)) {
var_to_display(p, &info->var, info);
- cols = info->var.xres / vc->vc_font.width;
- rows = info->var.yres / vc->vc_font.height;
+ cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres);
+ rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
+ cols /= vc->vc_font.width;
+ rows /= vc->vc_font.height;
vc_resize(vc, cols, rows);
updatescrollmode(p, info, vc);
scrollback_max = 0;
scrollback_current = 0;
- update_var(vc->vc_num, info);
+ ops->var.xoffset = ops->var.yoffset = p->yscroll = 0;
+ ops->update_start(info);
fbcon_set_palette(vc, color_table);
update_screen(vc);
- if (softback_buf) {
- int l = fbcon_softback_size / vc->vc_size_row;
- if (l > 5)
- softback_end = softback_buf + l * vc->vc_size_row;
- else {
- /* Smaller scrollback makes no sense, and 0
- would screw the operation totally */
- softback_top = 0;
- }
- }
+ if (softback_buf)
+ fbcon_update_softback(vc);
}
}
@@ -2645,30 +2765,24 @@ static void fbcon_set_all_vcs(struct fb_info *info)
continue;
p = &fb_display[vc->vc_num];
-
- info->var.xoffset = info->var.yoffset = p->yscroll = 0;
+ set_blitting_type(vc, info, p);
var_to_display(p, &info->var, info);
- cols = info->var.xres / vc->vc_font.width;
- rows = info->var.yres / vc->vc_font.height;
+ cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres);
+ rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
+ cols /= vc->vc_font.width;
+ rows /= vc->vc_font.height;
vc_resize(vc, cols, rows);
if (CON_IS_VISIBLE(vc)) {
updatescrollmode(p, info, vc);
scrollback_max = 0;
scrollback_current = 0;
- update_var(vc->vc_num, info);
+ ops->var.xoffset = ops->var.yoffset = p->yscroll = 0;
+ ops->update_start(info);
fbcon_set_palette(vc, color_table);
update_screen(vc);
- if (softback_buf) {
- int l = fbcon_softback_size / vc->vc_size_row;
- if (l > 5)
- softback_end = softback_buf + l * vc->vc_size_row;
- else {
- /* Smaller scrollback makes no sense, and 0
- would screw the operation totally */
- softback_top = 0;
- }
- }
+ if (softback_buf)
+ fbcon_update_softback(vc);
}
}
}
@@ -2758,7 +2872,8 @@ static void fbcon_new_modelist(struct fb_info *info)
continue;
vc = vc_cons[i].d;
display_to_var(&var, &fb_display[i]);
- mode = fb_find_nearest_mode(&var, &info->modelist);
+ mode = fb_find_nearest_mode(fb_display[i].mode,
+ &info->modelist);
fb_videomode_to_var(&var, mode);
if (vc)
@@ -2813,6 +2928,14 @@ static int fbcon_event_notify(struct notifier_block *self,
case FB_EVENT_NEW_MODELIST:
fbcon_new_modelist(info);
break;
+ case FB_EVENT_SET_CON_ROTATE:
+ fbcon_rotate(info, *(int *)event->data);
+ break;
+ case FB_EVENT_GET_CON_ROTATE:
+ ret = fbcon_get_rotate(info);
+ break;
+ case FB_EVENT_SET_CON_ROTATE_ALL:
+ fbcon_rotate_all(info, *(int *)event->data);
}
return ret;
diff --git a/drivers/video/console/fbcon.h b/drivers/video/console/fbcon.h
index 0738cd62def2..accfd7bd8e93 100644
--- a/drivers/video/console/fbcon.h
+++ b/drivers/video/console/fbcon.h
@@ -27,15 +27,15 @@
*/
struct display {
- /* Filled in by the frame buffer device */
- u_short inverse; /* != 0 text black on white as default */
/* Filled in by the low-level console driver */
const u_char *fontdata;
int userfont; /* != 0 if fontdata kmalloc()ed */
u_short scrollmode; /* Scroll Method */
+ u_short inverse; /* != 0 text black on white as default */
short yscroll; /* Hardware scrolling */
int vrows; /* number of virtual rows */
int cursor_shape;
+ int con_rotate;
u32 xres_virtual;
u32 yres_virtual;
u32 height;
@@ -52,6 +52,8 @@ struct display {
struct fb_videomode *mode;
};
+extern struct display fb_display[];
+
struct fbcon_ops {
void (*bmove)(struct vc_data *vc, struct fb_info *info, int sy,
int sx, int dy, int dx, int height, int width);
@@ -63,8 +65,12 @@ struct fbcon_ops {
void (*clear_margins)(struct vc_data *vc, struct fb_info *info,
int bottom_only);
void (*cursor)(struct vc_data *vc, struct fb_info *info,
- struct display *p, int mode, int softback_lines, int fg, int bg);
-
+ struct display *p, int mode, int softback_lines,
+ int fg, int bg);
+ int (*update_start)(struct fb_info *info);
+ int (*rotate_font)(struct fb_info *info, struct vc_data *vc,
+ struct display *p);
+ struct fb_var_screeninfo var; /* copy of the current fb_var_screeninfo */
struct timer_list cursor_timer; /* Cursor timer */
struct fb_cursor cursor_state;
int currcon; /* Current VC. */
@@ -73,7 +79,12 @@ struct fbcon_ops {
int blank_state;
int graphics;
int flags;
+ int rotate;
+ int cur_rotate;
char *cursor_data;
+ u8 *fontbuffer;
+ u8 *fontdata;
+ u32 fd_size;
};
/*
* Attribute Decoding
@@ -167,5 +178,48 @@ extern void fbcon_set_tileops(struct vc_data *vc, struct fb_info *info,
struct display *p, struct fbcon_ops *ops);
#endif
extern void fbcon_set_bitops(struct fbcon_ops *ops);
+extern int soft_cursor(struct fb_info *info, struct fb_cursor *cursor);
+
+#define FBCON_ATTRIBUTE_UNDERLINE 1
+#define FBCON_ATTRIBUTE_REVERSE 2
+#define FBCON_ATTRIBUTE_BOLD 4
+
+static inline int real_y(struct display *p, int ypos)
+{
+ int rows = p->vrows;
+
+ ypos += p->yscroll;
+ return ypos < rows ? ypos : ypos - rows;
+}
+
+
+static inline int get_attribute(struct fb_info *info, u16 c)
+{
+ int attribute = 0;
+
+ if (fb_get_color_depth(&info->var, &info->fix) == 1) {
+ if (attr_underline(c))
+ attribute |= FBCON_ATTRIBUTE_UNDERLINE;
+ if (attr_reverse(c))
+ attribute |= FBCON_ATTRIBUTE_REVERSE;
+ if (attr_bold(c))
+ attribute |= FBCON_ATTRIBUTE_BOLD;
+ }
+
+ return attribute;
+}
+
+#define FBCON_SWAP(i,r,v) ({ \
+ typeof(r) _r = (r); \
+ typeof(v) _v = (v); \
+ (void) (&_r == &_v); \
+ (i == FB_ROTATE_UR || i == FB_ROTATE_UD) ? _r : _v; })
+
+#ifdef CONFIG_FRAMEBUFFER_CONSOLE_ROTATION
+extern void fbcon_set_rotate(struct fbcon_ops *ops);
+#else
+#define fbcon_set_rotate(x) do {} while(0)
+#endif /* CONFIG_FRAMEBUFFER_CONSOLE_ROTATION */
#endif /* _VIDEO_FBCON_H */
+
diff --git a/drivers/video/console/fbcon_ccw.c b/drivers/video/console/fbcon_ccw.c
new file mode 100644
index 000000000000..680aabab73c5
--- /dev/null
+++ b/drivers/video/console/fbcon_ccw.c
@@ -0,0 +1,428 @@
+/*
+ * linux/drivers/video/console/fbcon_ccw.c -- Software Rotation - 270 degrees
+ *
+ * Copyright (C) 2005 Antonino Daplas <adaplas @pol.net>
+ *
+ * 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/config.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/fb.h>
+#include <linux/vt_kern.h>
+#include <linux/console.h>
+#include <asm/types.h>
+#include "fbcon.h"
+#include "fbcon_rotate.h"
+
+/*
+ * Rotation 270 degrees
+ */
+
+static inline void ccw_update_attr(u8 *dst, u8 *src, int attribute,
+ struct vc_data *vc)
+{
+ int i, j, offset = (vc->vc_font.height < 10) ? 1 : 2;
+ int width = (vc->vc_font.height + 7) >> 3;
+ int mod = vc->vc_font.height % 8;
+ u8 c, msk = ~(0xff << offset), msk1 = 0;
+
+ if (mod)
+ msk <<= (8 - mod);
+
+ if (offset > mod)
+ set_bit(FBCON_BIT(7), (void *)&msk1);
+
+ for (i = 0; i < vc->vc_font.width; i++) {
+ for (j = 0; j < width; j++) {
+ c = *src;
+
+ if (attribute & FBCON_ATTRIBUTE_UNDERLINE) {
+ if (j == width - 1)
+ c |= msk;
+
+ if (msk1 && j == width - 2)
+ c |= msk1;
+ }
+
+ if (attribute & FBCON_ATTRIBUTE_BOLD && i)
+ *(dst - width) |= c;
+
+ if (attribute & FBCON_ATTRIBUTE_REVERSE)
+ c = ~c;
+ src++;
+ *dst++ = c;
+ }
+ }
+}
+
+
+static void ccw_bmove(struct vc_data *vc, struct fb_info *info, int sy,
+ int sx, int dy, int dx, int height, int width)
+{
+ struct display *p = &fb_display[vc->vc_num];
+ struct fb_copyarea area;
+ u32 vyres = GETVYRES(p->scrollmode, info);
+
+ area.sx = sy * vc->vc_font.height;
+ area.sy = vyres - ((sx + width) * vc->vc_font.width);
+ area.dx = dy * vc->vc_font.height;
+ area.dy = vyres - ((dx + width) * vc->vc_font.width);
+ area.width = height * vc->vc_font.height;
+ area.height = width * vc->vc_font.width;
+
+ info->fbops->fb_copyarea(info, &area);
+}
+
+static void ccw_clear(struct vc_data *vc, struct fb_info *info, int sy,
+ int sx, int height, int width)
+{
+ struct display *p = &fb_display[vc->vc_num];
+ struct fb_fillrect region;
+ int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
+ u32 vyres = GETVYRES(p->scrollmode, info);
+
+ region.color = attr_bgcol_ec(bgshift,vc);
+ region.dx = sy * vc->vc_font.height;
+ region.dy = vyres - ((sx + width) * vc->vc_font.width);
+ region.height = width * vc->vc_font.width;
+ region.width = height * vc->vc_font.height;
+ region.rop = ROP_COPY;
+
+ info->fbops->fb_fillrect(info, &region);
+}
+
+static inline void ccw_putcs_aligned(struct vc_data *vc, struct fb_info *info,
+ const u16 *s, u32 attr, u32 cnt,
+ u32 d_pitch, u32 s_pitch, u32 cellsize,
+ struct fb_image *image, u8 *buf, u8 *dst)
+{
+ struct fbcon_ops *ops = info->fbcon_par;
+ u16 charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
+ u32 idx = (vc->vc_font.height + 7) >> 3;
+ u8 *src;
+
+ while (cnt--) {
+ src = ops->fontbuffer + (scr_readw(s--) & charmask)*cellsize;
+
+ if (attr) {
+ ccw_update_attr(buf, src, attr, vc);
+ src = buf;
+ }
+
+ if (likely(idx == 1))
+ __fb_pad_aligned_buffer(dst, d_pitch, src, idx,
+ vc->vc_font.width);
+ else
+ fb_pad_aligned_buffer(dst, d_pitch, src, idx,
+ vc->vc_font.width);
+
+ dst += d_pitch * vc->vc_font.width;
+ }
+
+ info->fbops->fb_imageblit(info, image);
+}
+
+static void ccw_putcs(struct vc_data *vc, struct fb_info *info,
+ const unsigned short *s, int count, int yy, int xx,
+ int fg, int bg)
+{
+ struct fb_image image;
+ struct display *p = &fb_display[vc->vc_num];
+ struct fbcon_ops *ops = info->fbcon_par;
+ u32 width = (vc->vc_font.height + 7)/8;
+ u32 cellsize = width * vc->vc_font.width;
+ u32 maxcnt = info->pixmap.size/cellsize;
+ u32 scan_align = info->pixmap.scan_align - 1;
+ u32 buf_align = info->pixmap.buf_align - 1;
+ u32 cnt, pitch, size;
+ u32 attribute = get_attribute(info, scr_readw(s));
+ u8 *dst, *buf = NULL;
+ u32 vyres = GETVYRES(p->scrollmode, info);
+
+ if (!ops->fontbuffer)
+ return;
+
+ image.fg_color = fg;
+ image.bg_color = bg;
+ image.dx = yy * vc->vc_font.height;
+ image.dy = vyres - ((xx + count) * vc->vc_font.width);
+ image.width = vc->vc_font.height;
+ image.depth = 1;
+
+ if (attribute) {
+ buf = kmalloc(cellsize, GFP_KERNEL);
+ if (!buf)
+ return;
+ }
+
+ s += count - 1;
+
+ while (count) {
+ if (count > maxcnt)
+ cnt = maxcnt;
+ else
+ cnt = count;
+
+ image.height = vc->vc_font.width * cnt;
+ pitch = ((image.width + 7) >> 3) + scan_align;
+ pitch &= ~scan_align;
+ size = pitch * image.height + buf_align;
+ size &= ~buf_align;
+ dst = fb_get_buffer_offset(info, &info->pixmap, size);
+ image.data = dst;
+ ccw_putcs_aligned(vc, info, s, attribute, cnt, pitch,
+ width, cellsize, &image, buf, dst);
+ image.dy += image.height;
+ count -= cnt;
+ s -= cnt;
+ }
+
+ /* buf is always NULL except when in monochrome mode, so in this case
+ it's a gain to check buf against NULL even though kfree() handles
+ NULL pointers just fine */
+ if (unlikely(buf))
+ kfree(buf);
+
+}
+
+static void ccw_clear_margins(struct vc_data *vc, struct fb_info *info,
+ int bottom_only)
+{
+ unsigned int cw = vc->vc_font.width;
+ unsigned int ch = vc->vc_font.height;
+ unsigned int rw = info->var.yres - (vc->vc_cols*cw);
+ unsigned int bh = info->var.xres - (vc->vc_rows*ch);
+ unsigned int bs = vc->vc_rows*ch;
+ struct fb_fillrect region;
+ int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
+
+ region.color = attr_bgcol_ec(bgshift,vc);
+ region.rop = ROP_COPY;
+
+ if (rw && !bottom_only) {
+ region.dx = 0;
+ region.dy = info->var.yoffset;
+ region.height = rw;
+ region.width = info->var.xres_virtual;
+ info->fbops->fb_fillrect(info, &region);
+ }
+
+ if (bh) {
+ region.dx = info->var.xoffset + bs;
+ region.dy = 0;
+ region.height = info->var.yres_virtual;
+ region.width = bh;
+ info->fbops->fb_fillrect(info, &region);
+ }
+}
+
+static void ccw_cursor(struct vc_data *vc, struct fb_info *info,
+ struct display *p, int mode, int softback_lines,
+ int fg, int bg)
+{
+ struct fb_cursor cursor;
+ struct fbcon_ops *ops = (struct fbcon_ops *) info->fbcon_par;
+ unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
+ int w = (vc->vc_font.height + 7) >> 3, c;
+ int y = real_y(p, vc->vc_y);
+ int attribute, use_sw = (vc->vc_cursor_type & 0x10);
+ int err = 1, dx, dy;
+ char *src;
+ u32 vyres = GETVYRES(p->scrollmode, info);
+
+ if (!ops->fontbuffer)
+ return;
+
+ cursor.set = 0;
+
+ if (softback_lines) {
+ if (y + softback_lines >= vc->vc_rows) {
+ mode = CM_ERASE;
+ ops->cursor_flash = 0;
+ return;
+ } else
+ y += softback_lines;
+ }
+
+ c = scr_readw((u16 *) vc->vc_pos);
+ attribute = get_attribute(info, c);
+ src = ops->fontbuffer + ((c & charmask) * (w * vc->vc_font.width));
+
+ if (ops->cursor_state.image.data != src ||
+ ops->cursor_reset) {
+ ops->cursor_state.image.data = src;
+ cursor.set |= FB_CUR_SETIMAGE;
+ }
+
+ if (attribute) {
+ u8 *dst;
+
+ dst = kmalloc(w * vc->vc_font.width, GFP_ATOMIC);
+ if (!dst)
+ return;
+ kfree(ops->cursor_data);
+ ops->cursor_data = dst;
+ ccw_update_attr(dst, src, attribute, vc);
+ src = dst;
+ }
+
+ if (ops->cursor_state.image.fg_color != fg ||
+ ops->cursor_state.image.bg_color != bg ||
+ ops->cursor_reset) {
+ ops->cursor_state.image.fg_color = fg;
+ ops->cursor_state.image.bg_color = bg;
+ cursor.set |= FB_CUR_SETCMAP;
+ }
+
+ if (ops->cursor_state.image.height != vc->vc_font.width ||
+ ops->cursor_state.image.width != vc->vc_font.height ||
+ ops->cursor_reset) {
+ ops->cursor_state.image.height = vc->vc_font.width;
+ ops->cursor_state.image.width = vc->vc_font.height;
+ cursor.set |= FB_CUR_SETSIZE;
+ }
+
+ dx = y * vc->vc_font.height;
+ dy = vyres - ((vc->vc_x + 1) * vc->vc_font.width);
+
+ if (ops->cursor_state.image.dx != dx ||
+ ops->cursor_state.image.dy != dy ||
+ ops->cursor_reset) {
+ ops->cursor_state.image.dx = dx;
+ ops->cursor_state.image.dy = dy;
+ cursor.set |= FB_CUR_SETPOS;
+ }
+
+ if (ops->cursor_state.hot.x || ops->cursor_state.hot.y ||
+ ops->cursor_reset) {
+ ops->cursor_state.hot.x = cursor.hot.y = 0;
+ cursor.set |= FB_CUR_SETHOT;
+ }
+
+ if (cursor.set & FB_CUR_SETSIZE ||
+ vc->vc_cursor_type != p->cursor_shape ||
+ ops->cursor_state.mask == NULL ||
+ ops->cursor_reset) {
+ char *tmp, *mask = kmalloc(w*vc->vc_font.width, GFP_ATOMIC);
+ int cur_height, size, i = 0;
+ int width = (vc->vc_font.width + 7)/8;
+
+ if (!mask)
+ return;
+
+ tmp = kmalloc(width * vc->vc_font.height, GFP_ATOMIC);
+
+ if (!tmp) {
+ kfree(mask);
+ return;
+ }
+
+ kfree(ops->cursor_state.mask);
+ ops->cursor_state.mask = mask;
+
+ p->cursor_shape = vc->vc_cursor_type;
+ cursor.set |= FB_CUR_SETSHAPE;
+
+ switch (p->cursor_shape & CUR_HWMASK) {
+ case CUR_NONE:
+ cur_height = 0;
+ break;
+ case CUR_UNDERLINE:
+ cur_height = (vc->vc_font.height < 10) ? 1 : 2;
+ break;
+ case CUR_LOWER_THIRD:
+ cur_height = vc->vc_font.height/3;
+ break;
+ case CUR_LOWER_HALF:
+ cur_height = vc->vc_font.height >> 1;
+ break;
+ case CUR_TWO_THIRDS:
+ cur_height = (vc->vc_font.height << 1)/3;
+ break;
+ case CUR_BLOCK:
+ default:
+ cur_height = vc->vc_font.height;
+ break;
+ }
+
+ size = (vc->vc_font.height - cur_height) * width;
+ while (size--)
+ tmp[i++] = 0;
+ size = cur_height * width;
+ while (size--)
+ tmp[i++] = 0xff;
+ memset(mask, 0, w * vc->vc_font.width);
+ rotate_ccw(tmp, mask, vc->vc_font.width, vc->vc_font.height);
+ kfree(tmp);
+ }
+
+ switch (mode) {
+ case CM_ERASE:
+ ops->cursor_state.enable = 0;
+ break;
+ case CM_DRAW:
+ case CM_MOVE:
+ default:
+ ops->cursor_state.enable = (use_sw) ? 0 : 1;
+ break;
+ }
+
+ cursor.image.data = src;
+ cursor.image.fg_color = ops->cursor_state.image.fg_color;
+ cursor.image.bg_color = ops->cursor_state.image.bg_color;
+ cursor.image.dx = ops->cursor_state.image.dx;
+ cursor.image.dy = ops->cursor_state.image.dy;
+ cursor.image.height = ops->cursor_state.image.height;
+ cursor.image.width = ops->cursor_state.image.width;
+ cursor.hot.x = ops->cursor_state.hot.x;
+ cursor.hot.y = ops->cursor_state.hot.y;
+ cursor.mask = ops->cursor_state.mask;
+ cursor.enable = ops->cursor_state.enable;
+ cursor.image.depth = 1;
+ cursor.rop = ROP_XOR;
+
+ if (info->fbops->fb_cursor)
+ err = info->fbops->fb_cursor(info, &cursor);
+
+ if (err)
+ soft_cursor(info, &cursor);
+
+ ops->cursor_reset = 0;
+}
+
+int ccw_update_start(struct fb_info *info)
+{
+ struct fbcon_ops *ops = info->fbcon_par;
+ struct display *p = &fb_display[ops->currcon];
+ u32 yoffset;
+ u32 vyres = GETVYRES(p->scrollmode, info);
+ int err;
+
+ yoffset = (vyres - info->var.yres) - ops->var.xoffset;
+ ops->var.xoffset = ops->var.yoffset;
+ ops->var.yoffset = yoffset;
+ err = fb_pan_display(info, &ops->var);
+ ops->var.xoffset = info->var.xoffset;
+ ops->var.yoffset = info->var.yoffset;
+ ops->var.vmode = info->var.vmode;
+ return err;
+}
+
+void fbcon_rotate_ccw(struct fbcon_ops *ops)
+{
+ ops->bmove = ccw_bmove;
+ ops->clear = ccw_clear;
+ ops->putcs = ccw_putcs;
+ ops->clear_margins = ccw_clear_margins;
+ ops->cursor = ccw_cursor;
+ ops->update_start = ccw_update_start;
+}
+EXPORT_SYMBOL(fbcon_rotate_ccw);
+
+MODULE_AUTHOR("Antonino Daplas <adaplas@pol.net>");
+MODULE_DESCRIPTION("Console Rotation (270 degrees) Support");
+MODULE_LICENSE("GPL");
diff --git a/drivers/video/console/fbcon_cw.c b/drivers/video/console/fbcon_cw.c
new file mode 100644
index 000000000000..6c6f3b6dd175
--- /dev/null
+++ b/drivers/video/console/fbcon_cw.c
@@ -0,0 +1,412 @@
+/*
+ * linux/drivers/video/console/fbcon_ud.c -- Software Rotation - 90 degrees
+ *
+ * Copyright (C) 2005 Antonino Daplas <adaplas @pol.net>
+ *
+ * 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/config.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/fb.h>
+#include <linux/vt_kern.h>
+#include <linux/console.h>
+#include <asm/types.h>
+#include "fbcon.h"
+#include "fbcon_rotate.h"
+
+/*
+ * Rotation 90 degrees
+ */
+
+static inline void cw_update_attr(u8 *dst, u8 *src, int attribute,
+ struct vc_data *vc)
+{
+ int i, j, offset = (vc->vc_font.height < 10) ? 1 : 2;
+ int width = (vc->vc_font.height + 7) >> 3;
+ u8 c, t = 0, msk = ~(0xff >> offset);
+
+ for (i = 0; i < vc->vc_font.width; i++) {
+ for (j = 0; j < width; j++) {
+ c = *src;
+ if (attribute & FBCON_ATTRIBUTE_UNDERLINE && !j)
+ c |= msk;
+ if (attribute & FBCON_ATTRIBUTE_BOLD && i)
+ c |= *(src-width);
+ if (attribute & FBCON_ATTRIBUTE_REVERSE)
+ c = ~c;
+ src++;
+ *dst++ = c;
+ t = c;
+ }
+ }
+}
+
+
+static void cw_bmove(struct vc_data *vc, struct fb_info *info, int sy,
+ int sx, int dy, int dx, int height, int width)
+{
+ struct display *p = &fb_display[vc->vc_num];
+ struct fb_copyarea area;
+ u32 vxres = GETVXRES(p->scrollmode, info);
+
+ area.sx = vxres - ((sy + height) * vc->vc_font.height);
+ area.sy = sx * vc->vc_font.width;
+ area.dx = vxres - ((dy + height) * vc->vc_font.height);
+ area.dy = dx * vc->vc_font.width;
+ area.width = height * vc->vc_font.height;
+ area.height = width * vc->vc_font.width;
+
+ info->fbops->fb_copyarea(info, &area);
+}
+
+static void cw_clear(struct vc_data *vc, struct fb_info *info, int sy,
+ int sx, int height, int width)
+{
+ struct display *p = &fb_display[vc->vc_num];
+ struct fb_fillrect region;
+ int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
+ u32 vxres = GETVXRES(p->scrollmode, info);
+
+ region.color = attr_bgcol_ec(bgshift,vc);
+ region.dx = vxres - ((sy + height) * vc->vc_font.height);
+ region.dy = sx * vc->vc_font.width;
+ region.height = width * vc->vc_font.width;
+ region.width = height * vc->vc_font.height;
+ region.rop = ROP_COPY;
+
+ info->fbops->fb_fillrect(info, &region);
+}
+
+static inline void cw_putcs_aligned(struct vc_data *vc, struct fb_info *info,
+ const u16 *s, u32 attr, u32 cnt,
+ u32 d_pitch, u32 s_pitch, u32 cellsize,
+ struct fb_image *image, u8 *buf, u8 *dst)
+{
+ struct fbcon_ops *ops = info->fbcon_par;
+ u16 charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
+ u32 idx = (vc->vc_font.height + 7) >> 3;
+ u8 *src;
+
+ while (cnt--) {
+ src = ops->fontbuffer + (scr_readw(s++) & charmask)*cellsize;
+
+ if (attr) {
+ cw_update_attr(buf, src, attr, vc);
+ src = buf;
+ }
+
+ if (likely(idx == 1))
+ __fb_pad_aligned_buffer(dst, d_pitch, src, idx,
+ vc->vc_font.width);
+ else
+ fb_pad_aligned_buffer(dst, d_pitch, src, idx,
+ vc->vc_font.width);
+
+ dst += d_pitch * vc->vc_font.width;
+ }
+
+ info->fbops->fb_imageblit(info, image);
+}
+
+static void cw_putcs(struct vc_data *vc, struct fb_info *info,
+ const unsigned short *s, int count, int yy, int xx,
+ int fg, int bg)
+{
+ struct fb_image image;
+ struct display *p = &fb_display[vc->vc_num];
+ struct fbcon_ops *ops = info->fbcon_par;
+ u32 width = (vc->vc_font.height + 7)/8;
+ u32 cellsize = width * vc->vc_font.width;
+ u32 maxcnt = info->pixmap.size/cellsize;
+ u32 scan_align = info->pixmap.scan_align - 1;
+ u32 buf_align = info->pixmap.buf_align - 1;
+ u32 cnt, pitch, size;
+ u32 attribute = get_attribute(info, scr_readw(s));
+ u8 *dst, *buf = NULL;
+ u32 vxres = GETVXRES(p->scrollmode, info);
+
+ if (!ops->fontbuffer)
+ return;
+
+ image.fg_color = fg;
+ image.bg_color = bg;
+ image.dx = vxres - ((yy + 1) * vc->vc_font.height);
+ image.dy = xx * vc->vc_font.width;
+ image.width = vc->vc_font.height;
+ image.depth = 1;
+
+ if (attribute) {
+ buf = kmalloc(cellsize, GFP_KERNEL);
+ if (!buf)
+ return;
+ }
+
+ while (count) {
+ if (count > maxcnt)
+ cnt = maxcnt;
+ else
+ cnt = count;
+
+ image.height = vc->vc_font.width * cnt;
+ pitch = ((image.width + 7) >> 3) + scan_align;
+ pitch &= ~scan_align;
+ size = pitch * image.height + buf_align;
+ size &= ~buf_align;
+ dst = fb_get_buffer_offset(info, &info->pixmap, size);
+ image.data = dst;
+ cw_putcs_aligned(vc, info, s, attribute, cnt, pitch,
+ width, cellsize, &image, buf, dst);
+ image.dy += image.height;
+ count -= cnt;
+ s += cnt;
+ }
+
+ /* buf is always NULL except when in monochrome mode, so in this case
+ it's a gain to check buf against NULL even though kfree() handles
+ NULL pointers just fine */
+ if (unlikely(buf))
+ kfree(buf);
+
+}
+
+static void cw_clear_margins(struct vc_data *vc, struct fb_info *info,
+ int bottom_only)
+{
+ unsigned int cw = vc->vc_font.width;
+ unsigned int ch = vc->vc_font.height;
+ unsigned int rw = info->var.yres - (vc->vc_cols*cw);
+ unsigned int bh = info->var.xres - (vc->vc_rows*ch);
+ unsigned int rs = info->var.yres - rw;
+ struct fb_fillrect region;
+ int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
+
+ region.color = attr_bgcol_ec(bgshift,vc);
+ region.rop = ROP_COPY;
+
+ if (rw && !bottom_only) {
+ region.dx = 0;
+ region.dy = info->var.yoffset + rs;
+ region.height = rw;
+ region.width = info->var.xres_virtual;
+ info->fbops->fb_fillrect(info, &region);
+ }
+
+ if (bh) {
+ region.dx = info->var.xoffset;
+ region.dy = info->var.yoffset;
+ region.height = info->var.yres;
+ region.width = bh;
+ info->fbops->fb_fillrect(info, &region);
+ }
+}
+
+static void cw_cursor(struct vc_data *vc, struct fb_info *info,
+ struct display *p, int mode, int softback_lines,
+ int fg, int bg)
+{
+ struct fb_cursor cursor;
+ struct fbcon_ops *ops = (struct fbcon_ops *) info->fbcon_par;
+ unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
+ int w = (vc->vc_font.height + 7) >> 3, c;
+ int y = real_y(p, vc->vc_y);
+ int attribute, use_sw = (vc->vc_cursor_type & 0x10);
+ int err = 1, dx, dy;
+ char *src;
+ u32 vxres = GETVXRES(p->scrollmode, info);
+
+ if (!ops->fontbuffer)
+ return;
+
+ cursor.set = 0;
+
+ if (softback_lines) {
+ if (y + softback_lines >= vc->vc_rows) {
+ mode = CM_ERASE;
+ ops->cursor_flash = 0;
+ return;
+ } else
+ y += softback_lines;
+ }
+
+ c = scr_readw((u16 *) vc->vc_pos);
+ attribute = get_attribute(info, c);
+ src = ops->fontbuffer + ((c & charmask) * (w * vc->vc_font.width));
+
+ if (ops->cursor_state.image.data != src ||
+ ops->cursor_reset) {
+ ops->cursor_state.image.data = src;
+ cursor.set |= FB_CUR_SETIMAGE;
+ }
+
+ if (attribute) {
+ u8 *dst;
+
+ dst = kmalloc(w * vc->vc_font.width, GFP_ATOMIC);
+ if (!dst)
+ return;
+ kfree(ops->cursor_data);
+ ops->cursor_data = dst;
+ cw_update_attr(dst, src, attribute, vc);
+ src = dst;
+ }
+
+ if (ops->cursor_state.image.fg_color != fg ||
+ ops->cursor_state.image.bg_color != bg ||
+ ops->cursor_reset) {
+ ops->cursor_state.image.fg_color = fg;
+ ops->cursor_state.image.bg_color = bg;
+ cursor.set |= FB_CUR_SETCMAP;
+ }
+
+ if (ops->cursor_state.image.height != vc->vc_font.width ||
+ ops->cursor_state.image.width != vc->vc_font.height ||
+ ops->cursor_reset) {
+ ops->cursor_state.image.height = vc->vc_font.width;
+ ops->cursor_state.image.width = vc->vc_font.height;
+ cursor.set |= FB_CUR_SETSIZE;
+ }
+
+ dx = vxres - ((y * vc->vc_font.height) + vc->vc_font.height);
+ dy = vc->vc_x * vc->vc_font.width;
+
+ if (ops->cursor_state.image.dx != dx ||
+ ops->cursor_state.image.dy != dy ||
+ ops->cursor_reset) {
+ ops->cursor_state.image.dx = dx;
+ ops->cursor_state.image.dy = dy;
+ cursor.set |= FB_CUR_SETPOS;
+ }
+
+ if (ops->cursor_state.hot.x || ops->cursor_state.hot.y ||
+ ops->cursor_reset) {
+ ops->cursor_state.hot.x = cursor.hot.y = 0;
+ cursor.set |= FB_CUR_SETHOT;
+ }
+
+ if (cursor.set & FB_CUR_SETSIZE ||
+ vc->vc_cursor_type != p->cursor_shape ||
+ ops->cursor_state.mask == NULL ||
+ ops->cursor_reset) {
+ char *tmp, *mask = kmalloc(w*vc->vc_font.width, GFP_ATOMIC);
+ int cur_height, size, i = 0;
+ int width = (vc->vc_font.width + 7)/8;
+
+ if (!mask)
+ return;
+
+ tmp = kmalloc(width * vc->vc_font.height, GFP_ATOMIC);
+
+ if (!tmp) {
+ kfree(mask);
+ return;
+ }
+
+ kfree(ops->cursor_state.mask);
+ ops->cursor_state.mask = mask;
+
+ p->cursor_shape = vc->vc_cursor_type;
+ cursor.set |= FB_CUR_SETSHAPE;
+
+ switch (p->cursor_shape & CUR_HWMASK) {
+ case CUR_NONE:
+ cur_height = 0;
+ break;
+ case CUR_UNDERLINE:
+ cur_height = (vc->vc_font.height < 10) ? 1 : 2;
+ break;
+ case CUR_LOWER_THIRD:
+ cur_height = vc->vc_font.height/3;
+ break;
+ case CUR_LOWER_HALF:
+ cur_height = vc->vc_font.height >> 1;
+ break;
+ case CUR_TWO_THIRDS:
+ cur_height = (vc->vc_font.height << 1)/3;
+ break;
+ case CUR_BLOCK:
+ default:
+ cur_height = vc->vc_font.height;
+ break;
+ }
+
+ size = (vc->vc_font.height - cur_height) * width;
+ while (size--)
+ tmp[i++] = 0;
+ size = cur_height * width;
+ while (size--)
+ tmp[i++] = 0xff;
+ memset(mask, 0, w * vc->vc_font.width);
+ rotate_cw(tmp, mask, vc->vc_font.width, vc->vc_font.height);
+ kfree(tmp);
+ }
+
+ switch (mode) {
+ case CM_ERASE:
+ ops->cursor_state.enable = 0;
+ break;
+ case CM_DRAW:
+ case CM_MOVE:
+ default:
+ ops->cursor_state.enable = (use_sw) ? 0 : 1;
+ break;
+ }
+
+ cursor.image.data = src;
+ cursor.image.fg_color = ops->cursor_state.image.fg_color;
+ cursor.image.bg_color = ops->cursor_state.image.bg_color;
+ cursor.image.dx = ops->cursor_state.image.dx;
+ cursor.image.dy = ops->cursor_state.image.dy;
+ cursor.image.height = ops->cursor_state.image.height;
+ cursor.image.width = ops->cursor_state.image.width;
+ cursor.hot.x = ops->cursor_state.hot.x;
+ cursor.hot.y = ops->cursor_state.hot.y;
+ cursor.mask = ops->cursor_state.mask;
+ cursor.enable = ops->cursor_state.enable;
+ cursor.image.depth = 1;
+ cursor.rop = ROP_XOR;
+
+ if (info->fbops->fb_cursor)
+ err = info->fbops->fb_cursor(info, &cursor);
+
+ if (err)
+ soft_cursor(info, &cursor);
+
+ ops->cursor_reset = 0;
+}
+
+int cw_update_start(struct fb_info *info)
+{
+ struct fbcon_ops *ops = info->fbcon_par;
+ struct display *p = &fb_display[ops->currcon];
+ u32 vxres = GETVXRES(p->scrollmode, info);
+ u32 xoffset;
+ int err;
+
+ xoffset = vxres - (info->var.xres + ops->var.yoffset);
+ ops->var.yoffset = ops->var.xoffset;
+ ops->var.xoffset = xoffset;
+ err = fb_pan_display(info, &ops->var);
+ ops->var.xoffset = info->var.xoffset;
+ ops->var.yoffset = info->var.yoffset;
+ ops->var.vmode = info->var.vmode;
+ return err;
+}
+
+void fbcon_rotate_cw(struct fbcon_ops *ops)
+{
+ ops->bmove = cw_bmove;
+ ops->clear = cw_clear;
+ ops->putcs = cw_putcs;
+ ops->clear_margins = cw_clear_margins;
+ ops->cursor = cw_cursor;
+ ops->update_start = cw_update_start;
+}
+EXPORT_SYMBOL(fbcon_rotate_cw);
+
+MODULE_AUTHOR("Antonino Daplas <adaplas@pol.net>");
+MODULE_DESCRIPTION("Console Rotation (90 degrees) Support");
+MODULE_LICENSE("GPL");
diff --git a/drivers/video/console/fbcon_rotate.c b/drivers/video/console/fbcon_rotate.c
new file mode 100644
index 000000000000..ec0dd8fe241c
--- /dev/null
+++ b/drivers/video/console/fbcon_rotate.c
@@ -0,0 +1,117 @@
+/*
+ * linux/drivers/video/console/fbcon_rotate.c -- Software Rotation
+ *
+ * Copyright (C) 2005 Antonino Daplas <adaplas @pol.net>
+ *
+ * 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/config.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/fb.h>
+#include <linux/vt_kern.h>
+#include <linux/console.h>
+#include <asm/types.h>
+#include "fbcon.h"
+#include "fbcon_rotate.h"
+
+static int fbcon_rotate_font(struct fb_info *info, struct vc_data *vc,
+ struct display *p)
+{
+ struct fbcon_ops *ops = info->fbcon_par;
+ int len, err = 0;
+ int s_cellsize, d_cellsize, i;
+ const u8 *src;
+ u8 *dst;
+
+ if (vc->vc_font.data == ops->fontdata &&
+ p->con_rotate == ops->cur_rotate)
+ goto finished;
+
+ src = ops->fontdata = vc->vc_font.data;
+ ops->cur_rotate = p->con_rotate;
+ len = (!p->userfont) ? 256 : FNTCHARCNT(src);
+ s_cellsize = ((vc->vc_font.width + 7)/8) *
+ vc->vc_font.height;
+ d_cellsize = s_cellsize;
+
+ if (ops->rotate == FB_ROTATE_CW ||
+ ops->rotate == FB_ROTATE_CCW)
+ d_cellsize = ((vc->vc_font.height + 7)/8) *
+ vc->vc_font.width;
+
+ if (info->fbops->fb_sync)
+ info->fbops->fb_sync(info);
+
+ if (ops->fd_size < d_cellsize * len) {
+ dst = kmalloc(d_cellsize * len, GFP_KERNEL);
+
+ if (dst == NULL) {
+ err = -ENOMEM;
+ goto finished;
+ }
+
+ ops->fd_size = d_cellsize * len;
+ kfree(ops->fontbuffer);
+ ops->fontbuffer = dst;
+ }
+
+ dst = ops->fontbuffer;
+ memset(dst, 0, ops->fd_size);
+
+ switch (ops->rotate) {
+ case FB_ROTATE_UD:
+ for (i = len; i--; ) {
+ rotate_ud(src, dst, vc->vc_font.width,
+ vc->vc_font.height);
+
+ src += s_cellsize;
+ dst += d_cellsize;
+ }
+ break;
+ case FB_ROTATE_CW:
+ for (i = len; i--; ) {
+ rotate_cw(src, dst, vc->vc_font.width,
+ vc->vc_font.height);
+ src += s_cellsize;
+ dst += d_cellsize;
+ }
+ break;
+ case FB_ROTATE_CCW:
+ for (i = len; i--; ) {
+ rotate_ccw(src, dst, vc->vc_font.width,
+ vc->vc_font.height);
+ src += s_cellsize;
+ dst += d_cellsize;
+ }
+ break;
+ }
+
+finished:
+ return err;
+}
+
+void fbcon_set_rotate(struct fbcon_ops *ops)
+{
+ ops->rotate_font = fbcon_rotate_font;
+
+ switch(ops->rotate) {
+ case FB_ROTATE_CW:
+ fbcon_rotate_cw(ops);
+ break;
+ case FB_ROTATE_UD:
+ fbcon_rotate_ud(ops);
+ break;
+ case FB_ROTATE_CCW:
+ fbcon_rotate_ccw(ops);
+ break;
+ }
+}
+EXPORT_SYMBOL(fbcon_set_rotate);
+
+MODULE_AUTHOR("Antonino Daplas <adaplas@pol.net>");
+MODULE_DESCRIPTION("Console Rotation Support");
+MODULE_LICENSE("GPL");
diff --git a/drivers/video/console/fbcon_rotate.h b/drivers/video/console/fbcon_rotate.h
new file mode 100644
index 000000000000..90c672096c2e
--- /dev/null
+++ b/drivers/video/console/fbcon_rotate.h
@@ -0,0 +1,105 @@
+/*
+ * linux/drivers/video/console/fbcon_rotate.h -- Software Display Rotation
+ *
+ * Copyright (C) 2005 Antonino Daplas <adaplas@pol.net>
+ *
+ * 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 _FBCON_ROTATE_H
+#define _FBCON_ROTATE_H
+
+#define FNTCHARCNT(fd) (((int *)(fd))[-3])
+
+#define GETVYRES(s,i) ({ \
+ (s == SCROLL_REDRAW || s == SCROLL_MOVE) ? \
+ (i)->var.yres : (i)->var.yres_virtual; })
+
+#define GETVXRES(s,i) ({ \
+ (s == SCROLL_REDRAW || s == SCROLL_MOVE || !(i)->fix.xpanstep) ? \
+ (i)->var.xres : (i)->var.xres_virtual; })
+
+/*
+ * The bitmap is always big endian
+ */
+#if defined(__LITTLE_ENDIAN)
+#define FBCON_BIT(b) (7 - (b))
+#else
+#define FBCON_BIT(b) (b)
+#endif
+
+static inline int pattern_test_bit(u32 x, u32 y, u32 pitch, const char *pat)
+{
+ u32 tmp = (y * pitch) + x, index = tmp / 8, bit = tmp % 8;
+
+ pat +=index;
+ return (test_bit(FBCON_BIT(bit), (void *)pat));
+}
+
+static inline void pattern_set_bit(u32 x, u32 y, u32 pitch, char *pat)
+{
+ u32 tmp = (y * pitch) + x, index = tmp / 8, bit = tmp % 8;
+
+ pat += index;
+ set_bit(FBCON_BIT(bit), (void *)pat);
+}
+
+static inline void rotate_ud(const char *in, char *out, u32 width, u32 height)
+{
+ int i, j;
+ int shift = width % 8;
+
+ width = (width + 7) & ~7;
+
+ for (i = 0; i < height; i++) {
+ for (j = 0; j < width; j++) {
+ if (pattern_test_bit(j, i, width, in))
+ pattern_set_bit(width - (1 + j + shift),
+ height - (1 + i),
+ width, out);
+ }
+
+ }
+}
+
+static inline void rotate_cw(const char *in, char *out, u32 width, u32 height)
+{
+ int i, j, h = height, w = width;
+ int shift = (8 - (height % 8)) & 7;
+
+ width = (width + 7) & ~7;
+ height = (height + 7) & ~7;
+
+ for (i = 0; i < h; i++) {
+ for (j = 0; j < w; j++) {
+ if (pattern_test_bit(j, i, width, in))
+ pattern_set_bit(height - 1 - i - shift, j,
+ height, out);
+
+ }
+ }
+}
+
+static inline void rotate_ccw(const char *in, char *out, u32 width, u32 height)
+{
+ int i, j, h = height, w = width;
+ int shift = width % 8;
+
+ width = (width + 7) & ~7;
+ height = (height + 7) & ~7;
+
+ for (i = 0; i < h; i++) {
+ for (j = 0; j < w; j++) {
+ if (pattern_test_bit(j, i, width, in))
+ pattern_set_bit(i, width - 1 - j - shift,
+ height, out);
+ }
+ }
+}
+
+extern void fbcon_rotate_cw(struct fbcon_ops *ops);
+extern void fbcon_rotate_ud(struct fbcon_ops *ops);
+extern void fbcon_rotate_ccw(struct fbcon_ops *ops);
+#endif
diff --git a/drivers/video/console/fbcon_ud.c b/drivers/video/console/fbcon_ud.c
new file mode 100644
index 000000000000..2e1d9d4249cd
--- /dev/null
+++ b/drivers/video/console/fbcon_ud.c
@@ -0,0 +1,454 @@
+/*
+ * linux/drivers/video/console/fbcon_ud.c -- Software Rotation - 180 degrees
+ *
+ * Copyright (C) 2005 Antonino Daplas <adaplas @pol.net>
+ *
+ * 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/config.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/fb.h>
+#include <linux/vt_kern.h>
+#include <linux/console.h>
+#include <asm/types.h>
+#include "fbcon.h"
+#include "fbcon_rotate.h"
+
+/*
+ * Rotation 180 degrees
+ */
+
+static inline void ud_update_attr(u8 *dst, u8 *src, int attribute,
+ struct vc_data *vc)
+{
+ int i, offset = (vc->vc_font.height < 10) ? 1 : 2;
+ int width = (vc->vc_font.width + 7) >> 3;
+ unsigned int cellsize = vc->vc_font.height * width;
+ u8 c;
+
+ offset = offset * width;
+
+ for (i = 0; i < cellsize; i++) {
+ c = src[i];
+ if (attribute & FBCON_ATTRIBUTE_UNDERLINE && i < offset)
+ c = 0xff;
+ if (attribute & FBCON_ATTRIBUTE_BOLD)
+ c |= c << 1;
+ if (attribute & FBCON_ATTRIBUTE_REVERSE)
+ c = ~c;
+ dst[i] = c;
+ }
+}
+
+
+static void ud_bmove(struct vc_data *vc, struct fb_info *info, int sy,
+ int sx, int dy, int dx, int height, int width)
+{
+ struct display *p = &fb_display[vc->vc_num];
+ struct fb_copyarea area;
+ u32 vyres = GETVYRES(p->scrollmode, info);
+ u32 vxres = GETVXRES(p->scrollmode, info);
+
+ area.sy = vyres - ((sy + height) * vc->vc_font.height);
+ area.sx = vxres - ((sx + width) * vc->vc_font.width);
+ area.dy = vyres - ((dy + height) * vc->vc_font.height);
+ area.dx = vxres - ((dx + width) * vc->vc_font.width);
+ area.height = height * vc->vc_font.height;
+ area.width = width * vc->vc_font.width;
+
+ info->fbops->fb_copyarea(info, &area);
+}
+
+static void ud_clear(struct vc_data *vc, struct fb_info *info, int sy,
+ int sx, int height, int width)
+{
+ struct display *p = &fb_display[vc->vc_num];
+ struct fb_fillrect region;
+ int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
+ u32 vyres = GETVYRES(p->scrollmode, info);
+ u32 vxres = GETVXRES(p->scrollmode, info);
+
+ region.color = attr_bgcol_ec(bgshift,vc);
+ region.dy = vyres - ((sy + height) * vc->vc_font.height);
+ region.dx = vxres - ((sx + width) * vc->vc_font.width);
+ region.width = width * vc->vc_font.width;
+ region.height = height * vc->vc_font.height;
+ region.rop = ROP_COPY;
+
+ info->fbops->fb_fillrect(info, &region);
+}
+
+static inline void ud_putcs_aligned(struct vc_data *vc, struct fb_info *info,
+ const u16 *s, u32 attr, u32 cnt,
+ u32 d_pitch, u32 s_pitch, u32 cellsize,
+ struct fb_image *image, u8 *buf, u8 *dst)
+{
+ struct fbcon_ops *ops = info->fbcon_par;
+ u16 charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
+ u32 idx = vc->vc_font.width >> 3;
+ u8 *src;
+
+ while (cnt--) {
+ src = ops->fontbuffer + (scr_readw(s--) & charmask)*cellsize;
+
+ if (attr) {
+ ud_update_attr(buf, src, attr, vc);
+ src = buf;
+ }
+
+ if (likely(idx == 1))
+ __fb_pad_aligned_buffer(dst, d_pitch, src, idx,
+ image->height);
+ else
+ fb_pad_aligned_buffer(dst, d_pitch, src, idx,
+ image->height);
+
+ dst += s_pitch;
+ }
+
+ info->fbops->fb_imageblit(info, image);
+}
+
+static inline void ud_putcs_unaligned(struct vc_data *vc,
+ struct fb_info *info, const u16 *s,
+ u32 attr, u32 cnt, u32 d_pitch,
+ u32 s_pitch, u32 cellsize,
+ struct fb_image *image, u8 *buf,
+ u8 *dst)
+{
+ struct fbcon_ops *ops = info->fbcon_par;
+ u16 charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
+ u32 shift_low = 0, mod = vc->vc_font.width % 8;
+ u32 shift_high = 8;
+ u32 idx = vc->vc_font.width >> 3;
+ u8 *src;
+
+ while (cnt--) {
+ src = ops->fontbuffer + (scr_readw(s--) & charmask)*cellsize;
+
+ if (attr) {
+ ud_update_attr(buf, src, attr, vc);
+ src = buf;
+ }
+
+ fb_pad_unaligned_buffer(dst, d_pitch, src, idx,
+ image->height, shift_high,
+ shift_low, mod);
+ shift_low += mod;
+ dst += (shift_low >= 8) ? s_pitch : s_pitch - 1;
+ shift_low &= 7;
+ shift_high = 8 - shift_low;
+ }
+
+ info->fbops->fb_imageblit(info, image);
+
+}
+
+static void ud_putcs(struct vc_data *vc, struct fb_info *info,
+ const unsigned short *s, int count, int yy, int xx,
+ int fg, int bg)
+{
+ struct fb_image image;
+ struct display *p = &fb_display[vc->vc_num];
+ struct fbcon_ops *ops = info->fbcon_par;
+ u32 width = (vc->vc_font.width + 7)/8;
+ u32 cellsize = width * vc->vc_font.height;
+ u32 maxcnt = info->pixmap.size/cellsize;
+ u32 scan_align = info->pixmap.scan_align - 1;
+ u32 buf_align = info->pixmap.buf_align - 1;
+ u32 mod = vc->vc_font.width % 8, cnt, pitch, size;
+ u32 attribute = get_attribute(info, scr_readw(s));
+ u8 *dst, *buf = NULL;
+ u32 vyres = GETVYRES(p->scrollmode, info);
+ u32 vxres = GETVXRES(p->scrollmode, info);
+
+ if (!ops->fontbuffer)
+ return;
+
+ image.fg_color = fg;
+ image.bg_color = bg;
+ image.dy = vyres - ((yy * vc->vc_font.height) + vc->vc_font.height);
+ image.dx = vxres - ((xx + count) * vc->vc_font.width);
+ image.height = vc->vc_font.height;
+ image.depth = 1;
+
+ if (attribute) {
+ buf = kmalloc(cellsize, GFP_KERNEL);
+ if (!buf)
+ return;
+ }
+
+ s += count - 1;
+
+ while (count) {
+ if (count > maxcnt)
+ cnt = maxcnt;
+ else
+ cnt = count;
+
+ image.width = vc->vc_font.width * cnt;
+ pitch = ((image.width + 7) >> 3) + scan_align;
+ pitch &= ~scan_align;
+ size = pitch * image.height + buf_align;
+ size &= ~buf_align;
+ dst = fb_get_buffer_offset(info, &info->pixmap, size);
+ image.data = dst;
+
+ if (!mod)
+ ud_putcs_aligned(vc, info, s, attribute, cnt, pitch,
+ width, cellsize, &image, buf, dst);
+ else
+ ud_putcs_unaligned(vc, info, s, attribute, cnt, pitch,
+ width, cellsize, &image,
+ buf, dst);
+
+ image.dx += image.width;
+ count -= cnt;
+ s -= cnt;
+ xx += cnt;
+ }
+
+ /* buf is always NULL except when in monochrome mode, so in this case
+ it's a gain to check buf against NULL even though kfree() handles
+ NULL pointers just fine */
+ if (unlikely(buf))
+ kfree(buf);
+
+}
+
+static void ud_clear_margins(struct vc_data *vc, struct fb_info *info,
+ int bottom_only)
+{
+ unsigned int cw = vc->vc_font.width;
+ unsigned int ch = vc->vc_font.height;
+ unsigned int rw = info->var.xres - (vc->vc_cols*cw);
+ unsigned int bh = info->var.yres - (vc->vc_rows*ch);
+ struct fb_fillrect region;
+ int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
+
+ region.color = attr_bgcol_ec(bgshift,vc);
+ region.rop = ROP_COPY;
+
+ if (rw && !bottom_only) {
+ region.dy = 0;
+ region.dx = info->var.xoffset;
+ region.width = rw;
+ region.height = info->var.yres_virtual;
+ info->fbops->fb_fillrect(info, &region);
+ }
+
+ if (bh) {
+ region.dy = info->var.yoffset;
+ region.dx = info->var.xoffset;
+ region.height = bh;
+ region.width = info->var.xres;
+ info->fbops->fb_fillrect(info, &region);
+ }
+}
+
+static void ud_cursor(struct vc_data *vc, struct fb_info *info,
+ struct display *p, int mode, int softback_lines,
+ int fg, int bg)
+{
+ struct fb_cursor cursor;
+ struct fbcon_ops *ops = (struct fbcon_ops *) info->fbcon_par;
+ unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
+ int w = (vc->vc_font.width + 7) >> 3, c;
+ int y = real_y(p, vc->vc_y);
+ int attribute, use_sw = (vc->vc_cursor_type & 0x10);
+ int err = 1, dx, dy;
+ char *src;
+ u32 vyres = GETVYRES(p->scrollmode, info);
+ u32 vxres = GETVXRES(p->scrollmode, info);
+
+ if (!ops->fontbuffer)
+ return;
+
+ cursor.set = 0;
+
+ if (softback_lines) {
+ if (y + softback_lines >= vc->vc_rows) {
+ mode = CM_ERASE;
+ ops->cursor_flash = 0;
+ return;
+ } else
+ y += softback_lines;
+ }
+
+ c = scr_readw((u16 *) vc->vc_pos);
+ attribute = get_attribute(info, c);
+ src = ops->fontbuffer + ((c & charmask) * (w * vc->vc_font.height));
+
+ if (ops->cursor_state.image.data != src ||
+ ops->cursor_reset) {
+ ops->cursor_state.image.data = src;
+ cursor.set |= FB_CUR_SETIMAGE;
+ }
+
+ if (attribute) {
+ u8 *dst;
+
+ dst = kmalloc(w * vc->vc_font.height, GFP_ATOMIC);
+ if (!dst)
+ return;
+ kfree(ops->cursor_data);
+ ops->cursor_data = dst;
+ ud_update_attr(dst, src, attribute, vc);
+ src = dst;
+ }
+
+ if (ops->cursor_state.image.fg_color != fg ||
+ ops->cursor_state.image.bg_color != bg ||
+ ops->cursor_reset) {
+ ops->cursor_state.image.fg_color = fg;
+ ops->cursor_state.image.bg_color = bg;
+ cursor.set |= FB_CUR_SETCMAP;
+ }
+
+ if (ops->cursor_state.image.height != vc->vc_font.height ||
+ ops->cursor_state.image.width != vc->vc_font.width ||
+ ops->cursor_reset) {
+ ops->cursor_state.image.height = vc->vc_font.height;
+ ops->cursor_state.image.width = vc->vc_font.width;
+ cursor.set |= FB_CUR_SETSIZE;
+ }
+
+ dy = vyres - ((y * vc->vc_font.height) + vc->vc_font.height);
+ dx = vxres - ((vc->vc_x * vc->vc_font.width) + vc->vc_font.width);
+
+ if (ops->cursor_state.image.dx != dx ||
+ ops->cursor_state.image.dy != dy ||
+ ops->cursor_reset) {
+ ops->cursor_state.image.dx = dx;
+ ops->cursor_state.image.dy = dy;
+ cursor.set |= FB_CUR_SETPOS;
+ }
+
+ if (ops->cursor_state.hot.x || ops->cursor_state.hot.y ||
+ ops->cursor_reset) {
+ ops->cursor_state.hot.x = cursor.hot.y = 0;
+ cursor.set |= FB_CUR_SETHOT;
+ }
+
+ if (cursor.set & FB_CUR_SETSIZE ||
+ vc->vc_cursor_type != p->cursor_shape ||
+ ops->cursor_state.mask == NULL ||
+ ops->cursor_reset) {
+ char *mask = kmalloc(w*vc->vc_font.height, GFP_ATOMIC);
+ int cur_height, size, i = 0;
+ u8 msk = 0xff;
+
+ if (!mask)
+ return;
+
+ kfree(ops->cursor_state.mask);
+ ops->cursor_state.mask = mask;
+
+ p->cursor_shape = vc->vc_cursor_type;
+ cursor.set |= FB_CUR_SETSHAPE;
+
+ switch (p->cursor_shape & CUR_HWMASK) {
+ case CUR_NONE:
+ cur_height = 0;
+ break;
+ case CUR_UNDERLINE:
+ cur_height = (vc->vc_font.height < 10) ? 1 : 2;
+ break;
+ case CUR_LOWER_THIRD:
+ cur_height = vc->vc_font.height/3;
+ break;
+ case CUR_LOWER_HALF:
+ cur_height = vc->vc_font.height >> 1;
+ break;
+ case CUR_TWO_THIRDS:
+ cur_height = (vc->vc_font.height << 1)/3;
+ break;
+ case CUR_BLOCK:
+ default:
+ cur_height = vc->vc_font.height;
+ break;
+ }
+
+ size = cur_height * w;
+
+ while (size--)
+ mask[i++] = msk;
+
+ size = (vc->vc_font.height - cur_height) * w;
+
+ while (size--)
+ mask[i++] = ~msk;
+ }
+
+ switch (mode) {
+ case CM_ERASE:
+ ops->cursor_state.enable = 0;
+ break;
+ case CM_DRAW:
+ case CM_MOVE:
+ default:
+ ops->cursor_state.enable = (use_sw) ? 0 : 1;
+ break;
+ }
+
+ cursor.image.data = src;
+ cursor.image.fg_color = ops->cursor_state.image.fg_color;
+ cursor.image.bg_color = ops->cursor_state.image.bg_color;
+ cursor.image.dx = ops->cursor_state.image.dx;
+ cursor.image.dy = ops->cursor_state.image.dy;
+ cursor.image.height = ops->cursor_state.image.height;
+ cursor.image.width = ops->cursor_state.image.width;
+ cursor.hot.x = ops->cursor_state.hot.x;
+ cursor.hot.y = ops->cursor_state.hot.y;
+ cursor.mask = ops->cursor_state.mask;
+ cursor.enable = ops->cursor_state.enable;
+ cursor.image.depth = 1;
+ cursor.rop = ROP_XOR;
+
+ if (info->fbops->fb_cursor)
+ err = info->fbops->fb_cursor(info, &cursor);
+
+ if (err)
+ soft_cursor(info, &cursor);
+
+ ops->cursor_reset = 0;
+}
+
+int ud_update_start(struct fb_info *info)
+{
+ struct fbcon_ops *ops = info->fbcon_par;
+ struct display *p = &fb_display[ops->currcon];
+ u32 xoffset, yoffset;
+ u32 vyres = GETVYRES(p->scrollmode, info);
+ u32 vxres = GETVXRES(p->scrollmode, info);
+ int err;
+
+ xoffset = (vxres - info->var.xres) - ops->var.xoffset;
+ yoffset = (vyres - info->var.yres) - ops->var.yoffset;
+ ops->var.xoffset = xoffset;
+ ops->var.yoffset = yoffset;
+ err = fb_pan_display(info, &ops->var);
+ ops->var.xoffset = info->var.xoffset;
+ ops->var.yoffset = info->var.yoffset;
+ ops->var.vmode = info->var.vmode;
+ return err;
+}
+
+void fbcon_rotate_ud(struct fbcon_ops *ops)
+{
+ ops->bmove = ud_bmove;
+ ops->clear = ud_clear;
+ ops->putcs = ud_putcs;
+ ops->clear_margins = ud_clear_margins;
+ ops->cursor = ud_cursor;
+ ops->update_start = ud_update_start;
+}
+EXPORT_SYMBOL(fbcon_rotate_ud);
+
+MODULE_AUTHOR("Antonino Daplas <adaplas@pol.net>");
+MODULE_DESCRIPTION("Console Rotation (180 degrees) Support");
+MODULE_LICENSE("GPL");
diff --git a/drivers/video/console/font_rl.c b/drivers/video/console/font_rl.c
new file mode 100644
index 000000000000..dfecc27d8ded
--- /dev/null
+++ b/drivers/video/console/font_rl.c
@@ -0,0 +1,4374 @@
+
+/* This font is simply the "rl.fnt" console font from the kbd utility.
+ * Converted by Zack T Smith, fbui@comcast.net.
+ * The original binary file is covered under the GNU Public License.
+ */
+
+#include <linux/font.h>
+
+#define FONTDATAMAX 4096
+
+static unsigned char patterns[4096] = {
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x3c,
+0x42,
+0x81,
+0xe7,
+0xa5,
+0x99,
+0x81,
+0x81,
+0x99,
+0x42,
+0x3c,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x3c,
+0x7e,
+0xff,
+0x99,
+0xdb,
+0xe7,
+0xff,
+0xff,
+0xe7,
+0x7e,
+0x3c,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x6c,
+0xfe,
+0xfe,
+0xfe,
+0xfe,
+0xfe,
+0x7c,
+0x38,
+0x10,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x10,
+0x38,
+0x7c,
+0xfe,
+0x7c,
+0x38,
+0x10,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x38,
+0x38,
+0x10,
+0xd6,
+0xfe,
+0xd6,
+0x10,
+0x10,
+0x38,
+0x7c,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x10,
+0x38,
+0x7c,
+0xfe,
+0xfe,
+0x54,
+0x10,
+0x10,
+0x38,
+0x7c,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x18,
+0x3c,
+0x3c,
+0x18,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xe7,
+0xc3,
+0xc3,
+0xe7,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x3c,
+0x66,
+0x42,
+0x42,
+0x66,
+0x3c,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xc3,
+0x99,
+0xbd,
+0xbd,
+0x99,
+0xc3,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+
+0x00,
+0x00,
+0x0f,
+0x07,
+0x0d,
+0x18,
+0x78,
+0xcc,
+0xcc,
+0xcc,
+0xcc,
+0x78,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x3c,
+0x66,
+0x66,
+0x66,
+0x3c,
+0x18,
+0x7e,
+0x18,
+0x18,
+0x18,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x08,
+0x0c,
+0x0a,
+0x0a,
+0x0a,
+0x08,
+0x08,
+0x08,
+0x38,
+0x78,
+0x30,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x10,
+0x18,
+0x1c,
+0x1e,
+0x1e,
+0x16,
+0x12,
+0x72,
+0xf2,
+0x62,
+0x0e,
+0x1e,
+0x0c,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x10,
+0x92,
+0x54,
+0x38,
+0xfe,
+0x38,
+0x54,
+0x92,
+0x10,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x80,
+0xc0,
+0xe0,
+0xb8,
+0x8e,
+0xb8,
+0xe0,
+0xc0,
+0x80,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x02,
+0x06,
+0x0e,
+0x3a,
+0xe2,
+0x3a,
+0x0e,
+0x06,
+0x02,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x10,
+0x38,
+0x7c,
+0xd6,
+0x10,
+0x10,
+0x10,
+0x10,
+0xd6,
+0x7c,
+0x38,
+0x10,
+0x00,
+0x00,
+
+0x00,
+0x42,
+0xe7,
+0xe7,
+0xe7,
+0xe7,
+0x42,
+0x42,
+0x42,
+0x00,
+0x66,
+0x66,
+0x66,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x7f,
+0xca,
+0xca,
+0xca,
+0xca,
+0x7a,
+0x0a,
+0x0a,
+0x0a,
+0x0a,
+0x0a,
+0x1b,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x1e,
+0x31,
+0x78,
+0xcc,
+0xc6,
+0xc3,
+0x63,
+0x33,
+0x1e,
+0x8c,
+0x78,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0xfe,
+0xfe,
+0xfe,
+0xfe,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x10,
+0x38,
+0x7c,
+0xd6,
+0x10,
+0x10,
+0x10,
+0x10,
+0xd6,
+0x7c,
+0x38,
+0x10,
+0xfe,
+0x00,
+
+0x00,
+0x00,
+0x10,
+0x38,
+0x7c,
+0xd6,
+0x10,
+0x10,
+0x10,
+0x10,
+0x10,
+0x10,
+0x10,
+0x10,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x10,
+0x10,
+0x10,
+0x10,
+0x10,
+0x10,
+0x10,
+0x10,
+0xd6,
+0x7c,
+0x38,
+0x10,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x08,
+0x0c,
+0x06,
+0xff,
+0x06,
+0x0c,
+0x08,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x10,
+0x30,
+0x60,
+0xff,
+0x60,
+0x30,
+0x10,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x22,
+0x44,
+0x88,
+0xcc,
+0xee,
+0x44,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x24,
+0x42,
+0xff,
+0x42,
+0x24,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x10,
+0x38,
+0x38,
+0x6c,
+0x6c,
+0xc6,
+0xfe,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0xfe,
+0xc6,
+0x6c,
+0x6c,
+0x38,
+0x38,
+0x10,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x18,
+0x3c,
+0x3c,
+0x3c,
+0x3c,
+0x18,
+0x18,
+0x18,
+0x10,
+0x00,
+0x18,
+0x18,
+0x00,
+0x00,
+0x00,
+
+0x22,
+0x77,
+0x33,
+0x11,
+0x22,
+0x44,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x12,
+0x12,
+0x12,
+0x7f,
+0x24,
+0x24,
+0x24,
+0xfe,
+0x48,
+0x48,
+0x48,
+0x00,
+0x00,
+0x00,
+
+0x10,
+0x10,
+0x7c,
+0xd2,
+0xd0,
+0xd0,
+0xd0,
+0x7c,
+0x16,
+0x16,
+0x16,
+0x96,
+0x7c,
+0x10,
+0x10,
+0x00,
+
+0x00,
+0x42,
+0xbe,
+0x44,
+0x0c,
+0x08,
+0x18,
+0x10,
+0x30,
+0x20,
+0x64,
+0x4a,
+0xc4,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x38,
+0x6c,
+0x6c,
+0x6c,
+0x38,
+0x37,
+0x72,
+0xdc,
+0xcc,
+0xcc,
+0xcc,
+0x77,
+0x00,
+0x00,
+0x00,
+
+0x10,
+0x38,
+0x18,
+0x08,
+0x10,
+0x20,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x04,
+0x08,
+0x10,
+0x10,
+0x30,
+0x30,
+0x30,
+0x30,
+0x30,
+0x10,
+0x10,
+0x08,
+0x04,
+0x00,
+0x00,
+
+0x00,
+0x20,
+0x10,
+0x08,
+0x08,
+0x0c,
+0x0c,
+0x0c,
+0x0c,
+0x0c,
+0x08,
+0x08,
+0x10,
+0x20,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x44,
+0x28,
+0x38,
+0xfe,
+0x38,
+0x28,
+0x44,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x18,
+0x18,
+0x7e,
+0x18,
+0x18,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x10,
+0x38,
+0x18,
+0x08,
+0x10,
+0x20,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x7e,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x10,
+0x38,
+0x10,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x06,
+0x06,
+0x0c,
+0x0c,
+0x18,
+0x18,
+0x30,
+0x30,
+0x60,
+0x60,
+0xc0,
+0xc0,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x3c,
+0x46,
+0xc6,
+0xc6,
+0xc6,
+0xc6,
+0xc6,
+0xc4,
+0x78,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x08,
+0x18,
+0x78,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x7e,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x7c,
+0x86,
+0x06,
+0x0c,
+0x18,
+0x20,
+0x40,
+0xc1,
+0xfe,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x3c,
+0x46,
+0x04,
+0x08,
+0x1c,
+0x06,
+0x06,
+0x06,
+0x06,
+0x0c,
+0x70,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x04,
+0x08,
+0x10,
+0x2c,
+0x4c,
+0x8c,
+0x8c,
+0xfe,
+0x0c,
+0x0c,
+0x0c,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x02,
+0x3c,
+0x20,
+0x20,
+0x70,
+0x0c,
+0x06,
+0x06,
+0x06,
+0x06,
+0x0c,
+0x70,
+0x00,
+
+0x00,
+0x00,
+0x18,
+0x20,
+0x40,
+0xc0,
+0xdc,
+0xc6,
+0xc6,
+0xc6,
+0xc6,
+0x44,
+0x38,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x40,
+0x7e,
+0x82,
+0x06,
+0x04,
+0x0c,
+0x18,
+0x18,
+0x30,
+0x30,
+0x30,
+0x30,
+0x00,
+
+0x00,
+0x00,
+0x7c,
+0xc6,
+0xc6,
+0x64,
+0x38,
+0x4c,
+0xc6,
+0xc6,
+0xc6,
+0xc6,
+0x7c,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x38,
+0x44,
+0xc6,
+0xc6,
+0x76,
+0x06,
+0x06,
+0x06,
+0x04,
+0x08,
+0x30,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x10,
+0x38,
+0x10,
+0x00,
+0x00,
+0x00,
+0x10,
+0x38,
+0x10,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x10,
+0x38,
+0x10,
+0x00,
+0x00,
+0x00,
+0x10,
+0x38,
+0x18,
+0x08,
+0x10,
+0x20,
+
+0x00,
+0x06,
+0x0c,
+0x18,
+0x30,
+0x60,
+0xa0,
+0xa0,
+0x60,
+0x30,
+0x18,
+0x0c,
+0x06,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x7e,
+0x00,
+0x00,
+0x7e,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x60,
+0x30,
+0x18,
+0x0c,
+0x06,
+0x05,
+0x05,
+0x06,
+0x0c,
+0x18,
+0x30,
+0x60,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x7c,
+0x86,
+0xc6,
+0x06,
+0x04,
+0x08,
+0x10,
+0x10,
+0x18,
+0x00,
+0x18,
+0x18,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x3c,
+0x46,
+0xc6,
+0xce,
+0xd6,
+0xd6,
+0xd6,
+0xdc,
+0xc0,
+0xc4,
+0x78,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x18,
+0x18,
+0x18,
+0x3c,
+0x2c,
+0x2c,
+0x2c,
+0x7e,
+0x46,
+0x46,
+0x46,
+0xef,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0xfc,
+0x66,
+0x66,
+0x66,
+0x66,
+0x7c,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0xfc,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x3a,
+0x66,
+0xc2,
+0xc0,
+0xc0,
+0xc0,
+0xc0,
+0xc0,
+0xc0,
+0xc0,
+0x62,
+0x3c,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0xfc,
+0x66,
+0x63,
+0x63,
+0x63,
+0x63,
+0x63,
+0x63,
+0x63,
+0x63,
+0x66,
+0xfc,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0xff,
+0x61,
+0x60,
+0x60,
+0x64,
+0x7c,
+0x64,
+0x60,
+0x60,
+0x60,
+0x61,
+0xfe,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0xff,
+0x61,
+0x61,
+0x60,
+0x64,
+0x7c,
+0x64,
+0x60,
+0x60,
+0x60,
+0x60,
+0xf0,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x3a,
+0x66,
+0xc2,
+0xc0,
+0xc0,
+0xc0,
+0xcf,
+0xc6,
+0xc6,
+0xc6,
+0x66,
+0x38,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0xf7,
+0x62,
+0x62,
+0x62,
+0x62,
+0x7e,
+0x62,
+0x62,
+0x62,
+0x62,
+0x62,
+0xf7,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x3c,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x3c,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x1e,
+0x0c,
+0x0c,
+0x0c,
+0x0c,
+0x0c,
+0x0c,
+0x0c,
+0x0c,
+0x0c,
+0x0c,
+0x0c,
+0x0c,
+0x08,
+0xf0,
+
+0x00,
+0xf7,
+0x64,
+0x6c,
+0x68,
+0x68,
+0x78,
+0x6c,
+0x6c,
+0x6c,
+0x66,
+0x66,
+0xf7,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0xf8,
+0x60,
+0x60,
+0x60,
+0x60,
+0x60,
+0x60,
+0x60,
+0x60,
+0x60,
+0x61,
+0xfe,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0xc3,
+0x66,
+0x76,
+0x7e,
+0x56,
+0x56,
+0x46,
+0x46,
+0x46,
+0x46,
+0x46,
+0xef,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0xe7,
+0x62,
+0x62,
+0x72,
+0x52,
+0x5a,
+0x4a,
+0x4e,
+0x46,
+0x46,
+0x42,
+0xe2,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x3c,
+0x66,
+0xc3,
+0xc3,
+0xc3,
+0xc3,
+0xc3,
+0xc3,
+0xc3,
+0xc3,
+0x66,
+0x3c,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0xfc,
+0x66,
+0x66,
+0x66,
+0x66,
+0x6c,
+0x60,
+0x60,
+0x60,
+0x60,
+0x60,
+0xf0,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x3c,
+0x66,
+0xc3,
+0xc3,
+0xc3,
+0xc3,
+0xc3,
+0xc3,
+0xc3,
+0xc3,
+0x66,
+0x3c,
+0x10,
+0x39,
+0x0e,
+
+0x00,
+0xfc,
+0x66,
+0x66,
+0x66,
+0x66,
+0x7c,
+0x6c,
+0x66,
+0x66,
+0x66,
+0x66,
+0xf3,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x7a,
+0xc6,
+0xc2,
+0xc0,
+0x70,
+0x3c,
+0x0e,
+0x06,
+0x06,
+0x86,
+0xc6,
+0xbc,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0xff,
+0x99,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x3c,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0xf7,
+0x62,
+0x62,
+0x62,
+0x62,
+0x62,
+0x62,
+0x62,
+0x62,
+0x62,
+0x62,
+0x3c,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0xf7,
+0x62,
+0x62,
+0x62,
+0x76,
+0x34,
+0x34,
+0x34,
+0x3c,
+0x18,
+0x18,
+0x18,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0xf7,
+0x62,
+0x62,
+0x62,
+0x62,
+0x6a,
+0x6a,
+0x6a,
+0x6a,
+0x7e,
+0x7e,
+0x34,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0xf7,
+0x62,
+0x62,
+0x34,
+0x34,
+0x18,
+0x18,
+0x2c,
+0x2c,
+0x46,
+0x46,
+0xef,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0xf7,
+0x62,
+0x62,
+0x62,
+0x34,
+0x34,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x3c,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x7f,
+0x46,
+0x86,
+0x0c,
+0x0c,
+0x18,
+0x18,
+0x30,
+0x30,
+0x61,
+0x62,
+0xfe,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x3c,
+0x30,
+0x30,
+0x30,
+0x30,
+0x30,
+0x30,
+0x30,
+0x30,
+0x30,
+0x30,
+0x3c,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0xc0,
+0xc0,
+0x60,
+0x60,
+0x30,
+0x30,
+0x18,
+0x18,
+0x0c,
+0x0c,
+0x06,
+0x06,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x3c,
+0x0c,
+0x0c,
+0x0c,
+0x0c,
+0x0c,
+0x0c,
+0x0c,
+0x0c,
+0x0c,
+0x0c,
+0x3c,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x10,
+0x38,
+0x4c,
+0x86,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0xff,
+0x00,
+0x00,
+
+0x00,
+0x18,
+0x20,
+0x30,
+0x38,
+0x10,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x78,
+0x8c,
+0x0c,
+0x3c,
+0xcc,
+0xcc,
+0xcd,
+0x76,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x20,
+0xe0,
+0x60,
+0x60,
+0x6c,
+0x76,
+0x66,
+0x66,
+0x66,
+0x66,
+0x76,
+0x6c,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x3c,
+0x66,
+0x60,
+0x60,
+0x60,
+0x60,
+0x62,
+0x3c,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x04,
+0x1c,
+0x0c,
+0x0c,
+0x6c,
+0xdc,
+0xcc,
+0xcc,
+0xcc,
+0xcc,
+0xdc,
+0x66,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x3c,
+0x66,
+0x7e,
+0x60,
+0x60,
+0x60,
+0x62,
+0x3c,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x1e,
+0x31,
+0x33,
+0x30,
+0x30,
+0x78,
+0x30,
+0x30,
+0x30,
+0x30,
+0x30,
+0x78,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x7b,
+0xce,
+0xcc,
+0xcc,
+0xcc,
+0x78,
+0x60,
+0x7c,
+0x86,
+0xc6,
+0x7c,
+
+0x00,
+0x20,
+0xe0,
+0x60,
+0x60,
+0x6c,
+0x76,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0xf7,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x10,
+0x38,
+0x10,
+0x00,
+0x18,
+0x38,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x3c,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x08,
+0x1c,
+0x08,
+0x00,
+0x0c,
+0x1c,
+0x0c,
+0x0c,
+0x0c,
+0x0c,
+0x0c,
+0x6c,
+0x4c,
+0x38,
+0x00,
+
+0x00,
+0x20,
+0xe0,
+0x60,
+0x60,
+0x67,
+0x66,
+0x6c,
+0x78,
+0x6c,
+0x6c,
+0x66,
+0xe7,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x08,
+0x38,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x3c,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x6a,
+0xfe,
+0x6a,
+0x6a,
+0x6a,
+0x62,
+0x62,
+0xf7,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x5c,
+0xf6,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0xf7,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x3c,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x3c,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x5c,
+0xe6,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x7c,
+0x60,
+0x60,
+0xf0,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x76,
+0xcc,
+0xcc,
+0xcc,
+0xcc,
+0xcc,
+0xcc,
+0x7c,
+0x0c,
+0x0c,
+0x1e,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x5e,
+0xf6,
+0x60,
+0x60,
+0x60,
+0x60,
+0x60,
+0xf0,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x7a,
+0xc6,
+0x72,
+0x1c,
+0x06,
+0x86,
+0xc6,
+0xbc,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x10,
+0x30,
+0x7c,
+0x30,
+0x30,
+0x30,
+0x30,
+0x30,
+0x34,
+0x18,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0xee,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x67,
+0x3a,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0xf7,
+0x62,
+0x76,
+0x34,
+0x34,
+0x3c,
+0x18,
+0x18,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0xf7,
+0x62,
+0x6a,
+0x6a,
+0x6a,
+0x6a,
+0x7e,
+0x24,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0xf7,
+0x62,
+0x34,
+0x18,
+0x2c,
+0x46,
+0x46,
+0xef,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0xf7,
+0x62,
+0x62,
+0x34,
+0x34,
+0x18,
+0x18,
+0x18,
+0x10,
+0xb0,
+0xe0,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0xfe,
+0x8c,
+0x18,
+0x30,
+0x30,
+0x60,
+0xc2,
+0xfe,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x0e,
+0x18,
+0x10,
+0x10,
+0x08,
+0x70,
+0x70,
+0x08,
+0x10,
+0x10,
+0x18,
+0x0e,
+0x00,
+0x00,
+0x00,
+
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x00,
+0x00,
+
+0x00,
+0x70,
+0x18,
+0x08,
+0x08,
+0x10,
+0x0e,
+0x0e,
+0x10,
+0x08,
+0x08,
+0x18,
+0x70,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x76,
+0xdc,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x10,
+0x38,
+0x6c,
+0xc6,
+0xc6,
+0xc6,
+0xfe,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x3a,
+0x66,
+0xc2,
+0xc0,
+0xc0,
+0xc0,
+0xc0,
+0xc0,
+0x62,
+0x3c,
+0x18,
+0x0c,
+0x24,
+0x18,
+
+0x00,
+0x00,
+0x66,
+0x00,
+0x00,
+0xee,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x3b,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x0c,
+0x18,
+0x20,
+0x00,
+0x3c,
+0x66,
+0x7e,
+0x60,
+0x60,
+0x60,
+0x62,
+0x3c,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x30,
+0x58,
+0x8c,
+0x00,
+0x78,
+0x8c,
+0x0c,
+0x3c,
+0xcc,
+0xcc,
+0xcd,
+0x76,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x66,
+0x00,
+0x00,
+0x78,
+0x8c,
+0x0c,
+0x3c,
+0xcc,
+0xcc,
+0xcd,
+0x76,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x30,
+0x18,
+0x04,
+0x00,
+0x78,
+0x8c,
+0x0c,
+0x3c,
+0xcc,
+0xcc,
+0xcd,
+0x76,
+0x00,
+0x00,
+0x00,
+
+0x38,
+0x44,
+0x44,
+0x38,
+0x00,
+0x78,
+0x8c,
+0x0c,
+0x3c,
+0xcc,
+0xcc,
+0xcd,
+0x76,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x3c,
+0x66,
+0x60,
+0x60,
+0x60,
+0x60,
+0x62,
+0x3c,
+0x08,
+0x24,
+0x18,
+
+0x00,
+0x18,
+0x2c,
+0x46,
+0x00,
+0x3c,
+0x66,
+0x7e,
+0x60,
+0x60,
+0x60,
+0x62,
+0x3c,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x66,
+0x00,
+0x00,
+0x3c,
+0x66,
+0x7e,
+0x60,
+0x60,
+0x60,
+0x62,
+0x3c,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x30,
+0x18,
+0x04,
+0x00,
+0x3c,
+0x66,
+0x7e,
+0x60,
+0x60,
+0x60,
+0x62,
+0x3c,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x66,
+0x00,
+0x00,
+0x38,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x3c,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x18,
+0x2c,
+0x46,
+0x00,
+0x38,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x3c,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x60,
+0x30,
+0x08,
+0x00,
+0x38,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x3c,
+0x00,
+0x00,
+0x00,
+
+0x66,
+0x18,
+0x18,
+0x18,
+0x3c,
+0x2c,
+0x2c,
+0x2c,
+0x7e,
+0x46,
+0x46,
+0x46,
+0xef,
+0x00,
+0x00,
+0x00,
+
+0x18,
+0x24,
+0x18,
+0x18,
+0x3c,
+0x2c,
+0x2c,
+0x2c,
+0x7e,
+0x46,
+0x46,
+0x46,
+0xef,
+0x00,
+0x00,
+0x00,
+
+0x0c,
+0x18,
+0xff,
+0x61,
+0x60,
+0x60,
+0x64,
+0x7c,
+0x64,
+0x60,
+0x60,
+0x61,
+0xfe,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x76,
+0x9b,
+0x1b,
+0x3f,
+0xd8,
+0xd8,
+0xd9,
+0x6e,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x1f,
+0x1d,
+0x1d,
+0x3c,
+0x2c,
+0x2e,
+0x2c,
+0x7c,
+0x4c,
+0x4c,
+0x4d,
+0xef,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x18,
+0x2c,
+0x46,
+0x00,
+0x3c,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x3c,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x66,
+0x00,
+0x00,
+0x3c,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x3c,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x30,
+0x18,
+0x04,
+0x00,
+0x3c,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x3c,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x18,
+0x2c,
+0x46,
+0x00,
+0xee,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x67,
+0x3a,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x30,
+0x18,
+0x04,
+0x00,
+0xee,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x67,
+0x3a,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x66,
+0x00,
+0x00,
+0xf7,
+0x62,
+0x62,
+0x34,
+0x34,
+0x18,
+0x18,
+0x18,
+0x10,
+0xb0,
+0xe0,
+
+0x66,
+0x00,
+0x3c,
+0x66,
+0xc3,
+0xc3,
+0xc3,
+0xc3,
+0xc3,
+0xc3,
+0xc3,
+0x66,
+0x3c,
+0x00,
+0x00,
+0x00,
+
+0x66,
+0x00,
+0xf7,
+0x62,
+0x62,
+0x62,
+0x62,
+0x62,
+0x62,
+0x62,
+0x62,
+0x62,
+0x3c,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x10,
+0x10,
+0x10,
+0x7c,
+0xc6,
+0xc0,
+0xc0,
+0xc0,
+0xc0,
+0xc2,
+0x7c,
+0x10,
+0x10,
+0x00,
+
+0x00,
+0x38,
+0x64,
+0x6c,
+0x60,
+0x60,
+0xf0,
+0x60,
+0x60,
+0x60,
+0x60,
+0x66,
+0xfc,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x81,
+0xc3,
+0x66,
+0x3c,
+0x18,
+0xff,
+0x18,
+0x18,
+0xff,
+0x18,
+0x18,
+0x18,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0xfe,
+0x63,
+0x63,
+0x63,
+0x63,
+0x6e,
+0x60,
+0x64,
+0x6e,
+0x64,
+0x64,
+0xf5,
+0x06,
+0x00,
+0x00,
+
+0x00,
+0x0e,
+0x19,
+0x1b,
+0x18,
+0x18,
+0x3c,
+0x18,
+0x18,
+0x18,
+0x18,
+0xd8,
+0x98,
+0x70,
+0x00,
+0x00,
+
+0x00,
+0x0c,
+0x18,
+0x20,
+0x00,
+0x78,
+0x8c,
+0x0c,
+0x3c,
+0xcc,
+0xcc,
+0xcd,
+0x76,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x06,
+0x0c,
+0x10,
+0x00,
+0x38,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x3c,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x0c,
+0x18,
+0x20,
+0x00,
+0x3c,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x3c,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x0c,
+0x18,
+0x20,
+0x00,
+0xee,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x67,
+0x3a,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x32,
+0x4c,
+0x00,
+0x5c,
+0xf6,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0xf7,
+0x00,
+0x00,
+0x00,
+
+0x32,
+0x4c,
+0x00,
+0xe7,
+0x72,
+0x52,
+0x5a,
+0x4a,
+0x4e,
+0x46,
+0x46,
+0x42,
+0xe2,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x78,
+0x8c,
+0x0c,
+0x3c,
+0xcc,
+0xcc,
+0xcd,
+0x76,
+0x00,
+0xfe,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x3c,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x3c,
+0x00,
+0x7e,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x30,
+0x30,
+0x00,
+0x30,
+0x10,
+0x10,
+0x20,
+0x40,
+0xc0,
+0xc6,
+0xc2,
+0x7c,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0xfe,
+0xc0,
+0xc0,
+0xc0,
+0xc0,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0xfe,
+0x06,
+0x06,
+0x06,
+0x06,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x20,
+0xe0,
+0x63,
+0x66,
+0xfc,
+0x18,
+0x30,
+0x60,
+0xce,
+0x93,
+0x06,
+0x0c,
+0x1f,
+0x00,
+0x00,
+
+0x00,
+0x20,
+0xe0,
+0x63,
+0x66,
+0xfc,
+0x18,
+0x30,
+0x64,
+0xc8,
+0x96,
+0x3f,
+0x06,
+0x06,
+0x00,
+0x00,
+
+0x00,
+0x18,
+0x18,
+0x00,
+0x08,
+0x18,
+0x18,
+0x18,
+0x3c,
+0x3c,
+0x3c,
+0x3c,
+0x18,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x36,
+0x6c,
+0xd8,
+0xd8,
+0x6c,
+0x36,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0xd8,
+0x6c,
+0x36,
+0x36,
+0x6c,
+0xd8,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x82,
+0x10,
+0x82,
+0x10,
+0x82,
+0x10,
+0x82,
+0x10,
+0x82,
+0x10,
+0x82,
+0x10,
+0x82,
+0x10,
+0x82,
+0x10,
+
+0x00,
+0x95,
+0x00,
+0xa9,
+0x00,
+0x95,
+0x00,
+0xa9,
+0x00,
+0x95,
+0x00,
+0xa9,
+0x00,
+0x95,
+0x00,
+0xa9,
+
+0x92,
+0x49,
+0x92,
+0x49,
+0x92,
+0x49,
+0x92,
+0x49,
+0x92,
+0x49,
+0x92,
+0x49,
+0x92,
+0x49,
+0x92,
+0x49,
+
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0xf8,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0xf8,
+0x18,
+0x18,
+0xf8,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0xe6,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0xfe,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0xf8,
+0x18,
+0x18,
+0xf8,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0xe6,
+0x06,
+0x06,
+0xe6,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0xfe,
+0x06,
+0x06,
+0xe6,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0xe6,
+0x06,
+0x06,
+0xfe,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0xfe,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0xf8,
+0x18,
+0x18,
+0xf8,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0xf8,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x1f,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0xff,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0xff,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x1f,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0xff,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0xff,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x1f,
+0x18,
+0x18,
+0x1f,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x67,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x67,
+0x60,
+0x60,
+0x7f,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x7f,
+0x60,
+0x60,
+0x67,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0xe7,
+0x00,
+0x00,
+0xff,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0xff,
+0x00,
+0x00,
+0xe7,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x67,
+0x60,
+0x60,
+0x67,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0xff,
+0x00,
+0x00,
+0xff,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0xe7,
+0x00,
+0x00,
+0xe7,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0xff,
+0x00,
+0x00,
+0xff,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0xff,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0xff,
+0x00,
+0x00,
+0xff,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0xff,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x7f,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x1f,
+0x18,
+0x18,
+0x1f,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x1f,
+0x18,
+0x18,
+0x1f,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x7f,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0xff,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0xff,
+0x00,
+0x00,
+0xff,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0xf8,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x1f,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+
+0xf0,
+0xf0,
+0xf0,
+0xf0,
+0xf0,
+0xf0,
+0xf0,
+0xf0,
+0xf0,
+0xf0,
+0xf0,
+0xf0,
+0xf0,
+0xf0,
+0xf0,
+0xf0,
+
+0x0f,
+0x0f,
+0x0f,
+0x0f,
+0x0f,
+0x0f,
+0x0f,
+0x0f,
+0x0f,
+0x0f,
+0x0f,
+0x0f,
+0x0f,
+0x0f,
+0x0f,
+0x0f,
+
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x77,
+0xcc,
+0xcc,
+0xcc,
+0xcc,
+0xde,
+0x73,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x7c,
+0xc6,
+0xc6,
+0xc6,
+0xc4,
+0xc8,
+0xc4,
+0xc6,
+0xc6,
+0xc6,
+0xc6,
+0xdc,
+0xc0,
+0xc0,
+0x00,
+
+0x00,
+0xff,
+0x61,
+0x60,
+0x60,
+0x60,
+0x60,
+0x60,
+0x60,
+0x60,
+0x60,
+0x60,
+0xf0,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x01,
+0x7e,
+0xa4,
+0x24,
+0x2c,
+0x6c,
+0x6c,
+0x6c,
+0x48,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0xff,
+0xc1,
+0x60,
+0x30,
+0x18,
+0x0c,
+0x18,
+0x30,
+0x60,
+0xc0,
+0xc1,
+0xfe,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x7f,
+0xc8,
+0xc8,
+0xc8,
+0xc8,
+0xc8,
+0xc8,
+0x70,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x22,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x7c,
+0x60,
+0x60,
+0x60,
+0xc0,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x76,
+0xdc,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x10,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x38,
+0x10,
+0x7c,
+0xd6,
+0xd6,
+0xd6,
+0xd6,
+0xd6,
+0xd6,
+0x7c,
+0x10,
+0x38,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x38,
+0x6c,
+0xc6,
+0xc6,
+0xc6,
+0xfe,
+0xc6,
+0xc6,
+0xc6,
+0xc6,
+0x6c,
+0x38,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x3c,
+0x66,
+0xc3,
+0xc3,
+0xc3,
+0xc3,
+0xc3,
+0x66,
+0x24,
+0x24,
+0xa5,
+0xe7,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x1e,
+0x31,
+0x30,
+0x18,
+0x0c,
+0x3e,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x3c,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x6e,
+0xff,
+0x99,
+0x99,
+0x99,
+0x99,
+0xff,
+0x76,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x02,
+0x04,
+0x7c,
+0xca,
+0x92,
+0xa6,
+0x7c,
+0x40,
+0x80,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x1c,
+0x30,
+0x60,
+0x60,
+0x60,
+0x7c,
+0x60,
+0x60,
+0x60,
+0x60,
+0x30,
+0x1c,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x7c,
+0xc6,
+0xc6,
+0xc6,
+0xc6,
+0xc6,
+0xc6,
+0xc6,
+0xc6,
+0xc6,
+0xc6,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0xfe,
+0x00,
+0x00,
+0x00,
+0x7c,
+0x00,
+0x00,
+0x00,
+0xfe,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x18,
+0x18,
+0x7e,
+0x18,
+0x18,
+0x00,
+0x00,
+0x7e,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x30,
+0x18,
+0x0c,
+0x06,
+0x0c,
+0x18,
+0x30,
+0x00,
+0x7e,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x0c,
+0x18,
+0x30,
+0x60,
+0x30,
+0x18,
+0x0c,
+0x00,
+0x7e,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x0e,
+0x19,
+0x1b,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0xd8,
+0x98,
+0x70,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x18,
+0x18,
+0x00,
+0x7e,
+0x00,
+0x18,
+0x18,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x76,
+0xdc,
+0x00,
+0x00,
+0x76,
+0xdc,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x38,
+0x44,
+0x44,
+0x44,
+0x38,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x18,
+0x18,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x18,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x07,
+0x06,
+0x06,
+0x0c,
+0x0c,
+0x08,
+0x98,
+0xd0,
+0xf0,
+0x60,
+0x20,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0xcc,
+0x76,
+0x66,
+0x66,
+0x66,
+0x66,
+0xf7,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x70,
+0x98,
+0x18,
+0x30,
+0x60,
+0x88,
+0xf8,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x7c,
+0x64,
+0x64,
+0x64,
+0x64,
+0x64,
+0x7c,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+};
+
+
+const struct font_desc font_rl = {
+ RL_IDX,
+ "RomanLarge",
+ 8,
+ 16,
+ patterns,
+ -1
+};
diff --git a/drivers/video/console/fonts.c b/drivers/video/console/fonts.c
index 4fd07d9eca03..9be83bed1959 100644
--- a/drivers/video/console/fonts.c
+++ b/drivers/video/console/fonts.c
@@ -64,6 +64,10 @@ static const struct font_desc *fonts[] = {
#undef NO_FONTS
&font_mini_4x6,
#endif
+#ifdef CONFIG_FONT_RL
+#undef NO_FONTS
+ &font_rl,
+#endif
};
#define num_fonts (sizeof(fonts)/sizeof(*fonts))
diff --git a/drivers/video/console/newport_con.c b/drivers/video/console/newport_con.c
index e793ffd39db5..762c7a593141 100644
--- a/drivers/video/console/newport_con.c
+++ b/drivers/video/console/newport_con.c
@@ -32,7 +32,6 @@
#include <linux/font.h>
-extern struct font_desc font_vga_8x16;
extern unsigned long sgi_gfxaddr;
#define FONT_DATA ((unsigned char *)font_vga_8x16.data)
diff --git a/drivers/video/softcursor.c b/drivers/video/console/softcursor.c
index 229c4bc35079..8529bf08db28 100644
--- a/drivers/video/softcursor.c
+++ b/drivers/video/console/softcursor.c
@@ -1,7 +1,7 @@
/*
* linux/drivers/video/softcursor.c -- Generic software cursor for frame buffer devices
*
- * Created 14 Nov 2002 by James Simmons
+ * Created 14 Nov 2002 by James Simmons
*
* 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
@@ -55,9 +55,9 @@ int soft_cursor(struct fb_info *info, struct fb_cursor *cursor)
src[i] = image->data[i] & cursor->mask[i];
break;
}
- } else
+ } else
memcpy(src, image->data, dsize);
-
+
fb_pad_aligned_buffer(dst, d_pitch, src, s_pitch, image->height);
image->data = dst;
info->fbops->fb_imageblit(info, image);
@@ -66,7 +66,7 @@ int soft_cursor(struct fb_info *info, struct fb_cursor *cursor)
}
EXPORT_SYMBOL(soft_cursor);
-
+
MODULE_AUTHOR("James Simmons <jsimmons@users.sf.net>");
MODULE_DESCRIPTION("Generic software cursor");
MODULE_LICENSE("GPL");
diff --git a/drivers/video/console/sticore.c b/drivers/video/console/sticore.c
index d940f605acb6..a7bcd17112c0 100644
--- a/drivers/video/console/sticore.c
+++ b/drivers/video/console/sticore.c
@@ -511,12 +511,12 @@ sti_select_fbfont( struct sti_cooked_rom *cooked_rom, char *fbfont_name )
struct sti_cooked_font *cooked_font;
if (!fbfont_name || !strlen(fbfont_name))
- return NULL;
+ return NULL;
fbfont = find_font(fbfont_name);
if (!fbfont)
- fbfont = get_default_font(1024,768);
+ fbfont = get_default_font(1024,768);
if (!fbfont)
- return NULL;
+ return NULL;
DPRINTK((KERN_DEBUG "selected %dx%d fb-font %s\n",
fbfont->width, fbfont->height, fbfont->name));
@@ -527,7 +527,7 @@ sti_select_fbfont( struct sti_cooked_rom *cooked_rom, char *fbfont_name )
nf = kmalloc(size, GFP_KERNEL);
if (!nf)
- return NULL;
+ return NULL;
memset(nf, 0, size);
nf->first_char = 0;
@@ -546,8 +546,8 @@ sti_select_fbfont( struct sti_cooked_rom *cooked_rom, char *fbfont_name )
cooked_font = kmalloc(sizeof(*cooked_font), GFP_KERNEL);
if (!cooked_font) {
- kfree(nf);
- return NULL;
+ kfree(nf);
+ return NULL;
}
cooked_font->raw = nf;
@@ -595,7 +595,7 @@ sti_select_font(struct sti_cooked_rom *rom,
static void __init
sti_dump_rom(struct sti_rom *rom)
{
- printk(KERN_INFO " id %04x-%04x, conforms to spec rev. %d.%02x\n",
+ printk(KERN_INFO " id %04x-%04x, conforms to spec rev. %d.%02x\n",
rom->graphics_id[0],
rom->graphics_id[1],
rom->revno[0] >> 4,
@@ -651,15 +651,16 @@ sti_search_font(struct sti_cooked_rom *rom, int height, int width)
struct sti_cooked_font *font;
int i = 0;
- for(font = rom->font_start; font; font = font->next_font, i++) {
- if((font->raw->width == width) && (font->raw->height == height))
+ for (font = rom->font_start; font; font = font->next_font, i++) {
+ if ((font->raw->width == width) &&
+ (font->raw->height == height))
return i;
}
return 0;
}
-#define BMODE_RELOCATE(offset) offset = (offset) / 4;
-#define BMODE_LAST_ADDR_OFFS 0x50
+#define BMODE_RELOCATE(offset) offset = (offset) / 4;
+#define BMODE_LAST_ADDR_OFFS 0x50
static void * __init
sti_bmode_font_raw(struct sti_cooked_font *f)
@@ -700,35 +701,35 @@ sti_get_bmode_rom (unsigned long address)
{
struct sti_rom *raw;
u32 size;
- struct sti_rom_font *raw_font, *font_start;
-
+ struct sti_rom_font *raw_font, *font_start;
+
sti_bmode_rom_copy(address + BMODE_LAST_ADDR_OFFS, sizeof(size), &size);
-
- size = (size+3) / 4;
+
+ size = (size+3) / 4;
raw = kmalloc(size, GFP_KERNEL);
if (raw) {
- sti_bmode_rom_copy(address, size, raw);
- memmove (&raw->res004, &raw->type[0], 0x3c);
- raw->type[3] = raw->res004;
+ sti_bmode_rom_copy(address, size, raw);
+ memmove (&raw->res004, &raw->type[0], 0x3c);
+ raw->type[3] = raw->res004;
- BMODE_RELOCATE (raw->region_list);
- BMODE_RELOCATE (raw->font_start);
+ BMODE_RELOCATE (raw->region_list);
+ BMODE_RELOCATE (raw->font_start);
- BMODE_RELOCATE (raw->init_graph);
- BMODE_RELOCATE (raw->state_mgmt);
- BMODE_RELOCATE (raw->font_unpmv);
- BMODE_RELOCATE (raw->block_move);
- BMODE_RELOCATE (raw->inq_conf);
+ BMODE_RELOCATE (raw->init_graph);
+ BMODE_RELOCATE (raw->state_mgmt);
+ BMODE_RELOCATE (raw->font_unpmv);
+ BMODE_RELOCATE (raw->block_move);
+ BMODE_RELOCATE (raw->inq_conf);
- raw_font = ((void *)raw) + raw->font_start;
- font_start = raw_font;
+ raw_font = ((void *)raw) + raw->font_start;
+ font_start = raw_font;
- while (raw_font->next_font) {
- BMODE_RELOCATE (raw_font->next_font);
- raw_font = ((void *)font_start) + raw_font->next_font;
- }
+ while (raw_font->next_font) {
+ BMODE_RELOCATE (raw_font->next_font);
+ raw_font = ((void *)font_start) + raw_font->next_font;
+ }
}
- return raw;
+ return raw;
}
struct sti_rom * __init
@@ -736,15 +737,15 @@ sti_get_wmode_rom (unsigned long address)
{
struct sti_rom *raw;
unsigned long size;
-
+
/* read the ROM size directly from the struct in ROM */
size = gsc_readl(address + offsetof(struct sti_rom,last_addr));
raw = kmalloc(size, GFP_KERNEL);
- if(raw)
- sti_rom_copy(address, size, raw);
+ if (raw)
+ sti_rom_copy(address, size, raw);
- return raw;
+ return raw;
}
int __init
@@ -757,14 +758,14 @@ sti_read_rom(int wordmode, struct sti_struct *sti, unsigned long address)
if (!cooked)
goto out_err;
- if (wordmode)
- raw = sti_get_wmode_rom (address);
- else
- raw = sti_get_bmode_rom (address);
+ if (wordmode)
+ raw = sti_get_wmode_rom (address);
+ else
+ raw = sti_get_bmode_rom (address);
+
+ if (!raw)
+ goto out_err;
- if (!raw)
- goto out_err;
-
if (!sti_cook_fonts(cooked, raw)) {
printk(KERN_ERR "No font found for STI at %08lx\n", address);
goto out_err;
@@ -787,7 +788,7 @@ sti_read_rom(int wordmode, struct sti_struct *sti, unsigned long address)
sti->font_width = sti->font->raw->width;
sti->font_height = sti->font->raw->height;
if (!wordmode)
- sti->font->raw = sti_bmode_font_raw(sti->font);
+ sti->font->raw = sti_bmode_font_raw(sti->font);
sti->sti_mem_request = raw->sti_mem_req;
sti->graphics_id[0] = raw->graphics_id[0];
@@ -811,16 +812,16 @@ sti_try_rom_generic(unsigned long address, unsigned long hpa, struct pci_dev *pd
u32 sig;
if (num_sti_roms >= MAX_STI_ROMS) {
- printk(KERN_WARNING "maximum number of STI ROMS reached !\n");
- return NULL;
+ printk(KERN_WARNING "maximum number of STI ROMS reached !\n");
+ return NULL;
}
sti = kmalloc(sizeof(*sti), GFP_KERNEL);
if (!sti) {
- printk(KERN_ERR "Not enough memory !\n");
- return NULL;
+ printk(KERN_ERR "Not enough memory !\n");
+ return NULL;
}
-
+
memset(sti, 0, sizeof(*sti));
spin_lock_init(&sti->lock);
@@ -932,28 +933,21 @@ static void __init sticore_check_for_default_sti(struct sti_struct *sti, char *p
*/
static int __init sticore_pa_init(struct parisc_device *dev)
{
- unsigned long rom = 0;
char pa_path[21];
struct sti_struct *sti = NULL;
-
- if(dev->num_addrs) {
- rom = dev->addr[0];
- }
- if (!rom) {
- rom = dev->hpa;
- DPRINTK((KERN_DEBUG "Trying STI ROM at %08lx, hpa at %08lx\n", rom, dev->hpa));
- sti = sti_try_rom_generic(rom, dev->hpa, NULL);
- rom = PAGE0->proc_sti;
- }
- if (!sti) {
- DPRINTK((KERN_DEBUG "Trying STI ROM at %08lx, hpa at %08lx\n", rom, dev->hpa));
- sti = sti_try_rom_generic(rom, dev->hpa, NULL);
- }
+ int hpa = dev->hpa.start;
+
+ if (dev->num_addrs && dev->addr[0])
+ sti = sti_try_rom_generic(dev->addr[0], hpa, NULL);
+ if (!sti)
+ sti = sti_try_rom_generic(hpa, hpa, NULL);
+ if (!sti)
+ sti = sti_try_rom_generic(PAGE0->proc_sti, hpa, NULL);
if (!sti)
return 1;
-
+
print_pa_hwpath(dev, pa_path);
- sticore_check_for_default_sti (sti, pa_path);
+ sticore_check_for_default_sti(sti, pa_path);
return 0;
}
diff --git a/drivers/video/console/tileblit.c b/drivers/video/console/tileblit.c
index 7f76e2c6a4a1..cb25324a5635 100644
--- a/drivers/video/console/tileblit.c
+++ b/drivers/video/console/tileblit.c
@@ -118,6 +118,18 @@ static void tile_cursor(struct vc_data *vc, struct fb_info *info,
info->tileops->fb_tilecursor(info, &cursor);
}
+static int tile_update_start(struct fb_info *info)
+{
+ struct fbcon_ops *ops = info->fbcon_par;
+ int err;
+
+ err = fb_pan_display(info, &ops->var);
+ ops->var.xoffset = info->var.xoffset;
+ ops->var.yoffset = info->var.yoffset;
+ ops->var.vmode = info->var.vmode;
+ return err;
+}
+
void fbcon_set_tileops(struct vc_data *vc, struct fb_info *info,
struct display *p, struct fbcon_ops *ops)
{
@@ -128,6 +140,7 @@ void fbcon_set_tileops(struct vc_data *vc, struct fb_info *info,
ops->putcs = tile_putcs;
ops->clear_margins = tile_clear_margins;
ops->cursor = tile_cursor;
+ ops->update_start = tile_update_start;
if (p) {
map.width = vc->vc_font.width;
diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c
index 809fee2140ac..274f90543e32 100644
--- a/drivers/video/console/vgacon.c
+++ b/drivers/video/console/vgacon.c
@@ -448,7 +448,8 @@ static void vgacon_cursor(struct vc_data *c, int mode)
vgacon_scrolldelta(c, 0);
switch (mode) {
case CM_ERASE:
- write_vga(14, (vga_vram_end - vga_vram_base - 1) / 2);
+ write_vga(14, (c->vc_pos - vga_vram_base) / 2);
+ vgacon_set_cursor_size(c->vc_x, 31, 30);
break;
case CM_MOVE:
@@ -579,6 +580,7 @@ static void vga_set_palette(struct vc_data *vc, unsigned char *table)
{
int i, j;
+ vga_w(state.vgabase, VGA_PEL_MSK, 0xff);
for (i = j = 0; i < 16; i++) {
vga_w(state.vgabase, VGA_PEL_IW, table[i]);
vga_w(state.vgabase, VGA_PEL_D, vc->vc_palette[j++] >> 2);
@@ -721,6 +723,7 @@ static void vga_pal_blank(struct vgastate *state)
{
int i;
+ vga_w(state->vgabase, VGA_PEL_MSK, 0xff);
for (i = 0; i < 16; i++) {
vga_w(state->vgabase, VGA_PEL_IW, i);
vga_w(state->vgabase, VGA_PEL_D, 0);
diff --git a/drivers/video/controlfb.c b/drivers/video/controlfb.c
index 989e700159e0..403d17377f8d 100644
--- a/drivers/video/controlfb.c
+++ b/drivers/video/controlfb.c
@@ -176,7 +176,6 @@ static struct fb_ops controlfb_ops = {
.fb_fillrect = cfb_fillrect,
.fb_copyarea = cfb_copyarea,
.fb_imageblit = cfb_imageblit,
- .fb_cursor = soft_cursor,
};
diff --git a/drivers/video/cyber2000fb.c b/drivers/video/cyber2000fb.c
index 3894b2a501d6..c589d23e7f91 100644
--- a/drivers/video/cyber2000fb.c
+++ b/drivers/video/cyber2000fb.c
@@ -1064,7 +1064,6 @@ static struct fb_ops cyber2000fb_ops = {
.fb_fillrect = cyber2000fb_fillrect,
.fb_copyarea = cyber2000fb_copyarea,
.fb_imageblit = cyber2000fb_imageblit,
- .fb_cursor = soft_cursor,
.fb_sync = cyber2000fb_sync,
};
diff --git a/drivers/video/cyblafb.c b/drivers/video/cyblafb.c
index 6992100a508c..03fbe83d71a8 100644
--- a/drivers/video/cyblafb.c
+++ b/drivers/video/cyblafb.c
@@ -968,7 +968,6 @@ static struct fb_ops cyblafb_ops __devinitdata = {
.fb_fillrect = cyblafb_fillrect,
.fb_copyarea= cyblafb_copyarea,
.fb_imageblit = cyblafb_imageblit,
- .fb_cursor = soft_cursor,
};
//==========================================================================
diff --git a/drivers/video/dnfb.c b/drivers/video/dnfb.c
index 1dbb82dca40b..957a3ada2b75 100644
--- a/drivers/video/dnfb.c
+++ b/drivers/video/dnfb.c
@@ -6,6 +6,8 @@
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+
#include <asm/setup.h>
#include <asm/system.h>
#include <asm/irq.h>
@@ -114,7 +116,6 @@ static struct fb_ops dn_fb_ops = {
.fb_fillrect = cfb_fillrect,
.fb_copyarea = dnfb_copyarea,
.fb_imageblit = cfb_imageblit,
- .fb_cursor = soft_cursor,
};
struct fb_var_screeninfo dnfb_var __devinitdata = {
diff --git a/drivers/video/epson1355fb.c b/drivers/video/epson1355fb.c
index 116e808d71cd..6a81a1dd8f3d 100644
--- a/drivers/video/epson1355fb.c
+++ b/drivers/video/epson1355fb.c
@@ -54,6 +54,8 @@
#include <linux/fb.h>
#include <linux/init.h>
#include <linux/ioport.h>
+#include <linux/platform_device.h>
+
#include <asm/types.h>
#include <asm/io.h>
#include <asm/uaccess.h>
@@ -482,7 +484,6 @@ static struct fb_ops epson1355fb_fbops = {
.fb_imageblit = cfb_imageblit,
.fb_read = epson1355fb_read,
.fb_write = epson1355fb_write,
- .fb_cursor = soft_cursor,
};
/* ------------------------------------------------------------------------- */
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
index 70be7009f8af..9f180096c896 100644
--- a/drivers/video/fbmem.c
+++ b/drivers/video/fbmem.c
@@ -14,6 +14,7 @@
#include <linux/config.h>
#include <linux/module.h>
+#include <linux/compat.h>
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/sched.h>
@@ -323,9 +324,103 @@ static struct logo_data {
const struct linux_logo *logo;
} fb_logo;
-int fb_prepare_logo(struct fb_info *info)
+static void fb_rotate_logo_ud(const u8 *in, u8 *out, u32 width, u32 height)
+{
+ u32 size = width * height, i;
+
+ out += size - 1;
+
+ for (i = size; i--; )
+ *out-- = *in++;
+}
+
+static void fb_rotate_logo_cw(const u8 *in, u8 *out, u32 width, u32 height)
+{
+ int i, j, w = width - 1;
+
+ for (i = 0; i < height; i++)
+ for (j = 0; j < width; j++)
+ out[height * j + w - i] = *in++;
+}
+
+static void fb_rotate_logo_ccw(const u8 *in, u8 *out, u32 width, u32 height)
+{
+ int i, j, w = width - 1;
+
+ for (i = 0; i < height; i++)
+ for (j = 0; j < width; j++)
+ out[height * (w - j) + i] = *in++;
+}
+
+static void fb_rotate_logo(struct fb_info *info, u8 *dst,
+ struct fb_image *image, int rotate)
+{
+ u32 tmp;
+
+ if (rotate == FB_ROTATE_UD) {
+ image->dx = info->var.xres - image->width;
+ image->dy = info->var.yres - image->height;
+ fb_rotate_logo_ud(image->data, dst, image->width,
+ image->height);
+ } else if (rotate == FB_ROTATE_CW) {
+ tmp = image->width;
+ image->width = image->height;
+ image->height = tmp;
+ image->dx = info->var.xres - image->height;
+ fb_rotate_logo_cw(image->data, dst, image->width,
+ image->height);
+ } else if (rotate == FB_ROTATE_CCW) {
+ tmp = image->width;
+ image->width = image->height;
+ image->height = tmp;
+ image->dy = info->var.yres - image->width;
+ fb_rotate_logo_ccw(image->data, dst, image->width,
+ image->height);
+ }
+
+ image->data = dst;
+}
+
+static void fb_do_show_logo(struct fb_info *info, struct fb_image *image,
+ int rotate)
+{
+ int x;
+
+ if (rotate == FB_ROTATE_UR) {
+ for (x = 0; x < num_online_cpus() &&
+ x * (fb_logo.logo->width + 8) <=
+ info->var.xres - fb_logo.logo->width; x++) {
+ info->fbops->fb_imageblit(info, image);
+ image->dx += fb_logo.logo->width + 8;
+ }
+ } else if (rotate == FB_ROTATE_UD) {
+ for (x = 0; x < num_online_cpus() &&
+ x * (fb_logo.logo->width + 8) <=
+ info->var.xres - fb_logo.logo->width; x++) {
+ info->fbops->fb_imageblit(info, image);
+ image->dx -= fb_logo.logo->width + 8;
+ }
+ } else if (rotate == FB_ROTATE_CW) {
+ for (x = 0; x < num_online_cpus() &&
+ x * (fb_logo.logo->width + 8) <=
+ info->var.yres - fb_logo.logo->width; x++) {
+ info->fbops->fb_imageblit(info, image);
+ image->dy += fb_logo.logo->width + 8;
+ }
+ } else if (rotate == FB_ROTATE_CCW) {
+ for (x = 0; x < num_online_cpus() &&
+ x * (fb_logo.logo->width + 8) <=
+ info->var.yres - fb_logo.logo->width; x++) {
+ info->fbops->fb_imageblit(info, image);
+ image->dy -= fb_logo.logo->width + 8;
+ }
+ }
+}
+
+int fb_prepare_logo(struct fb_info *info, int rotate)
{
int depth = fb_get_color_depth(&info->var, &info->fix);
+ int yres;
memset(&fb_logo, 0, sizeof(struct logo_data));
@@ -358,10 +453,16 @@ int fb_prepare_logo(struct fb_info *info)
/* Return if no suitable logo was found */
fb_logo.logo = fb_find_logo(depth);
- if (!fb_logo.logo || fb_logo.logo->height > info->var.yres) {
+ if (rotate == FB_ROTATE_UR || rotate == FB_ROTATE_UD)
+ yres = info->var.yres;
+ else
+ yres = info->var.xres;
+
+ if (fb_logo.logo && fb_logo.logo->height > yres) {
fb_logo.logo = NULL;
return 0;
}
+
/* What depth we asked for might be different from what we get */
if (fb_logo.logo->type == LINUX_LOGO_CLUT224)
fb_logo.depth = 8;
@@ -372,12 +473,11 @@ int fb_prepare_logo(struct fb_info *info)
return fb_logo.logo->height;
}
-int fb_show_logo(struct fb_info *info)
+int fb_show_logo(struct fb_info *info, int rotate)
{
u32 *palette = NULL, *saved_pseudo_palette = NULL;
- unsigned char *logo_new = NULL;
+ unsigned char *logo_new = NULL, *logo_rotate = NULL;
struct fb_image image;
- int x;
/* Return if the frame buffer is not mapped or suspended */
if (fb_logo.logo == NULL || info->state != FBINFO_STATE_RUNNING)
@@ -417,25 +517,30 @@ int fb_show_logo(struct fb_info *info)
fb_set_logo(info, fb_logo.logo, logo_new, fb_logo.depth);
}
+ image.dx = 0;
+ image.dy = 0;
image.width = fb_logo.logo->width;
image.height = fb_logo.logo->height;
- image.dy = 0;
- for (x = 0; x < num_online_cpus() * (fb_logo.logo->width + 8) &&
- x <= info->var.xres-fb_logo.logo->width; x += (fb_logo.logo->width + 8)) {
- image.dx = x;
- info->fbops->fb_imageblit(info, &image);
+ if (rotate) {
+ logo_rotate = kmalloc(fb_logo.logo->width *
+ fb_logo.logo->height, GFP_KERNEL);
+ if (logo_rotate)
+ fb_rotate_logo(info, logo_rotate, &image, rotate);
}
-
+
+ fb_do_show_logo(info, &image, rotate);
+
kfree(palette);
if (saved_pseudo_palette != NULL)
info->pseudo_palette = saved_pseudo_palette;
kfree(logo_new);
+ kfree(logo_rotate);
return fb_logo.logo->height;
}
#else
-int fb_prepare_logo(struct fb_info *info) { return 0; }
-int fb_show_logo(struct fb_info *info) { return 0; }
+int fb_prepare_logo(struct fb_info *info, int rotate) { return 0; }
+int fb_show_logo(struct fb_info *info, int rotate) { return 0; }
#endif /* CONFIG_LOGO */
static int fbmem_read_proc(char *buf, char **start, off_t offset,
@@ -829,18 +934,154 @@ fb_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
}
#ifdef CONFIG_COMPAT
+struct fb_fix_screeninfo32 {
+ char id[16];
+ compat_caddr_t smem_start;
+ u32 smem_len;
+ u32 type;
+ u32 type_aux;
+ u32 visual;
+ u16 xpanstep;
+ u16 ypanstep;
+ u16 ywrapstep;
+ u32 line_length;
+ compat_caddr_t mmio_start;
+ u32 mmio_len;
+ u32 accel;
+ u16 reserved[3];
+};
+
+struct fb_cmap32 {
+ u32 start;
+ u32 len;
+ compat_caddr_t red;
+ compat_caddr_t green;
+ compat_caddr_t blue;
+ compat_caddr_t transp;
+};
+
+static int fb_getput_cmap(struct inode *inode, struct file *file,
+ unsigned int cmd, unsigned long arg)
+{
+ struct fb_cmap_user __user *cmap;
+ struct fb_cmap32 __user *cmap32;
+ __u32 data;
+ int err;
+
+ cmap = compat_alloc_user_space(sizeof(*cmap));
+ cmap32 = compat_ptr(arg);
+
+ if (copy_in_user(&cmap->start, &cmap32->start, 2 * sizeof(__u32)))
+ return -EFAULT;
+
+ if (get_user(data, &cmap32->red) ||
+ put_user(compat_ptr(data), &cmap->red) ||
+ get_user(data, &cmap32->green) ||
+ put_user(compat_ptr(data), &cmap->green) ||
+ get_user(data, &cmap32->blue) ||
+ put_user(compat_ptr(data), &cmap->blue) ||
+ get_user(data, &cmap32->transp) ||
+ put_user(compat_ptr(data), &cmap->transp))
+ return -EFAULT;
+
+ err = fb_ioctl(inode, file, cmd, (unsigned long) cmap);
+
+ if (!err) {
+ if (copy_in_user(&cmap32->start,
+ &cmap->start,
+ 2 * sizeof(__u32)))
+ err = -EFAULT;
+ }
+ return err;
+}
+
+static int do_fscreeninfo_to_user(struct fb_fix_screeninfo *fix,
+ struct fb_fix_screeninfo32 __user *fix32)
+{
+ __u32 data;
+ int err;
+
+ err = copy_to_user(&fix32->id, &fix->id, sizeof(fix32->id));
+
+ data = (__u32) (unsigned long) fix->smem_start;
+ err |= put_user(data, &fix32->smem_start);
+
+ err |= put_user(fix->smem_len, &fix32->smem_len);
+ err |= put_user(fix->type, &fix32->type);
+ err |= put_user(fix->type_aux, &fix32->type_aux);
+ err |= put_user(fix->visual, &fix32->visual);
+ err |= put_user(fix->xpanstep, &fix32->xpanstep);
+ err |= put_user(fix->ypanstep, &fix32->ypanstep);
+ err |= put_user(fix->ywrapstep, &fix32->ywrapstep);
+ err |= put_user(fix->line_length, &fix32->line_length);
+
+ data = (__u32) (unsigned long) fix->mmio_start;
+ err |= put_user(data, &fix32->mmio_start);
+
+ err |= put_user(fix->mmio_len, &fix32->mmio_len);
+ err |= put_user(fix->accel, &fix32->accel);
+ err |= copy_to_user(fix32->reserved, fix->reserved,
+ sizeof(fix->reserved));
+
+ return err;
+}
+
+static int fb_get_fscreeninfo(struct inode *inode, struct file *file,
+ unsigned int cmd, unsigned long arg)
+{
+ mm_segment_t old_fs;
+ struct fb_fix_screeninfo fix;
+ struct fb_fix_screeninfo32 __user *fix32;
+ int err;
+
+ fix32 = compat_ptr(arg);
+
+ old_fs = get_fs();
+ set_fs(KERNEL_DS);
+ err = fb_ioctl(inode, file, cmd, (unsigned long) &fix);
+ set_fs(old_fs);
+
+ if (!err)
+ err = do_fscreeninfo_to_user(&fix, fix32);
+
+ return err;
+}
+
static long
fb_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
- int fbidx = iminor(file->f_dentry->d_inode);
+ struct inode *inode = file->f_dentry->d_inode;
+ int fbidx = iminor(inode);
struct fb_info *info = registered_fb[fbidx];
struct fb_ops *fb = info->fbops;
- long ret;
+ long ret = -ENOIOCTLCMD;
- if (fb->fb_compat_ioctl == NULL)
- return -ENOIOCTLCMD;
lock_kernel();
- ret = fb->fb_compat_ioctl(file, cmd, arg, info);
+ switch(cmd) {
+ case FBIOGET_VSCREENINFO:
+ case FBIOPUT_VSCREENINFO:
+ case FBIOPAN_DISPLAY:
+ case FBIOGET_CON2FBMAP:
+ case FBIOPUT_CON2FBMAP:
+ arg = (unsigned long) compat_ptr(arg);
+ case FBIOBLANK:
+ ret = fb_ioctl(inode, file, cmd, arg);
+ break;
+
+ case FBIOGET_FSCREENINFO:
+ ret = fb_get_fscreeninfo(inode, file, cmd, arg);
+ break;
+
+ case FBIOGETCMAP:
+ case FBIOPUTCMAP:
+ ret = fb_getput_cmap(inode, file, cmd, arg);
+ break;
+
+ default:
+ if (fb->fb_compat_ioctl)
+ ret = fb->fb_compat_ioctl(file, cmd, arg, info);
+ break;
+ }
unlock_kernel();
return ret;
}
@@ -918,7 +1159,7 @@ fb_mmap(struct file *file, struct vm_area_struct * vma)
}
#endif
#elif defined(__powerpc__)
- vma->vm_page_prot = phys_mem_access_prot(file, off,
+ vma->vm_page_prot = phys_mem_access_prot(file, off >> PAGE_SHIFT,
vma->vm_end - vma->vm_start,
vma->vm_page_prot);
#elif defined(__alpha__)
@@ -1031,7 +1272,7 @@ register_framebuffer(struct fb_info *fb_info)
break;
fb_info->node = i;
- fb_info->class_device = class_device_create(fb_class, MKDEV(FB_MAJOR, i),
+ fb_info->class_device = class_device_create(fb_class, NULL, MKDEV(FB_MAJOR, i),
fb_info->device, "fb%d", i);
if (IS_ERR(fb_info->class_device)) {
/* Not fatal */
@@ -1215,6 +1456,28 @@ int fb_new_modelist(struct fb_info *info)
return err;
}
+/**
+ * fb_con_duit - user<->fbcon passthrough
+ * @info: struct fb_info
+ * @event: notification event to be passed to fbcon
+ * @data: private data
+ *
+ * DESCRIPTION
+ * This function is an fbcon-user event passing channel
+ * which bypasses fbdev. This is hopefully temporary
+ * until a user interface for fbcon is created
+ */
+int fb_con_duit(struct fb_info *info, int event, void *data)
+{
+ struct fb_event evnt;
+
+ evnt.info = info;
+ evnt.data = data;
+
+ return notifier_call_chain(&fb_notifier_list, event, &evnt);
+}
+EXPORT_SYMBOL(fb_con_duit);
+
static char *video_options[FB_MAX];
static int ofonly;
diff --git a/drivers/video/fbmon.c b/drivers/video/fbmon.c
index 713226cdf3c6..fc7965b66775 100644
--- a/drivers/video/fbmon.c
+++ b/drivers/video/fbmon.c
@@ -538,25 +538,12 @@ static struct fb_videomode *fb_create_modedb(unsigned char *edid, int *dbsize)
*dbsize = 0;
- DPRINTK(" Supported VESA Modes\n");
- block = edid + ESTABLISHED_TIMING_1;
- num += get_est_timing(block, &mode[num]);
-
- DPRINTK(" Standard Timings\n");
- block = edid + STD_TIMING_DESCRIPTIONS_START;
- for (i = 0; i < STD_TIMING; i++, block += STD_TIMING_DESCRIPTION_SIZE)
- num += get_std_timing(block, &mode[num]);
-
DPRINTK(" Detailed Timings\n");
block = edid + DETAILED_TIMING_DESCRIPTIONS_START;
for (i = 0; i < 4; i++, block+= DETAILED_TIMING_DESCRIPTION_SIZE) {
int first = 1;
- if (block[0] == 0x00 && block[1] == 0x00) {
- if (block[3] == 0xfa) {
- num += get_dst_timing(block + 5, &mode[num]);
- }
- } else {
+ if (!(block[0] == 0x00 && block[1] == 0x00)) {
get_detailed_timing(block, &mode[num]);
if (first) {
mode[num].flag |= FB_MODE_IS_FIRST;
@@ -565,6 +552,21 @@ static struct fb_videomode *fb_create_modedb(unsigned char *edid, int *dbsize)
num++;
}
}
+
+ DPRINTK(" Supported VESA Modes\n");
+ block = edid + ESTABLISHED_TIMING_1;
+ num += get_est_timing(block, &mode[num]);
+
+ DPRINTK(" Standard Timings\n");
+ block = edid + STD_TIMING_DESCRIPTIONS_START;
+ for (i = 0; i < STD_TIMING; i++, block += STD_TIMING_DESCRIPTION_SIZE)
+ num += get_std_timing(block, &mode[num]);
+
+ block = edid + DETAILED_TIMING_DESCRIPTIONS_START;
+ for (i = 0; i < 4; i++, block+= DETAILED_TIMING_DESCRIPTION_SIZE) {
+ if (block[0] == 0x00 && block[1] == 0x00 && block[3] == 0xfa)
+ num += get_dst_timing(block + 5, &mode[num]);
+ }
/* Yikes, EDID data is totally useless */
if (!num) {
@@ -827,7 +829,7 @@ int fb_parse_edid(unsigned char *edid, struct fb_var_screeninfo *var)
void fb_edid_to_monspecs(unsigned char *edid, struct fb_monspecs *specs)
{
unsigned char *block;
- int i;
+ int i, found = 0;
if (edid == NULL)
return;
@@ -869,6 +871,22 @@ void fb_edid_to_monspecs(unsigned char *edid, struct fb_monspecs *specs)
get_monspecs(edid, specs);
specs->modedb = fb_create_modedb(edid, &specs->modedb_len);
+
+ /*
+ * Workaround for buggy EDIDs that sets that the first
+ * detailed timing is preferred but has not detailed
+ * timing specified
+ */
+ for (i = 0; i < specs->modedb_len; i++) {
+ if (specs->modedb[i].flag & FB_MODE_IS_DETAILED) {
+ found = 1;
+ break;
+ }
+ }
+
+ if (!found)
+ specs->misc &= ~FB_MISC_1ST_DETAIL;
+
DPRINTK("========================================\n");
}
diff --git a/drivers/video/fbsysfs.c b/drivers/video/fbsysfs.c
index 007c8e9b2b39..08dac9580d15 100644
--- a/drivers/video/fbsysfs.c
+++ b/drivers/video/fbsysfs.c
@@ -213,6 +213,70 @@ static ssize_t show_bpp(struct class_device *class_device, char *buf)
return snprintf(buf, PAGE_SIZE, "%d\n", fb_info->var.bits_per_pixel);
}
+static ssize_t store_rotate(struct class_device *class_device, const char *buf,
+ size_t count)
+{
+ struct fb_info *fb_info = class_get_devdata(class_device);
+ struct fb_var_screeninfo var;
+ char **last = NULL;
+ int err;
+
+ var = fb_info->var;
+ var.rotate = simple_strtoul(buf, last, 0);
+
+ if ((err = activate(fb_info, &var)))
+ return err;
+
+ return count;
+}
+
+
+static ssize_t show_rotate(struct class_device *class_device, char *buf)
+{
+ struct fb_info *fb_info = class_get_devdata(class_device);
+
+ return snprintf(buf, PAGE_SIZE, "%d\n", fb_info->var.rotate);
+}
+
+static ssize_t store_con_rotate(struct class_device *class_device,
+ const char *buf, size_t count)
+{
+ struct fb_info *fb_info = class_get_devdata(class_device);
+ int rotate;
+ char **last = NULL;
+
+ acquire_console_sem();
+ rotate = simple_strtoul(buf, last, 0);
+ fb_con_duit(fb_info, FB_EVENT_SET_CON_ROTATE, &rotate);
+ release_console_sem();
+ return count;
+}
+
+static ssize_t store_con_rotate_all(struct class_device *class_device,
+ const char *buf, size_t count)
+{
+ struct fb_info *fb_info = class_get_devdata(class_device);
+ int rotate;
+ char **last = NULL;
+
+ acquire_console_sem();
+ rotate = simple_strtoul(buf, last, 0);
+ fb_con_duit(fb_info, FB_EVENT_SET_CON_ROTATE_ALL, &rotate);
+ release_console_sem();
+ return count;
+}
+
+static ssize_t show_con_rotate(struct class_device *class_device, char *buf)
+{
+ struct fb_info *fb_info = class_get_devdata(class_device);
+ int rotate;
+
+ acquire_console_sem();
+ rotate = fb_con_duit(fb_info, FB_EVENT_GET_CON_ROTATE, NULL);
+ release_console_sem();
+ return snprintf(buf, PAGE_SIZE, "%d\n", rotate);
+}
+
static ssize_t store_virtual(struct class_device *class_device,
const char * buf, size_t count)
{
@@ -440,6 +504,9 @@ static struct class_device_attribute class_device_attrs[] = {
__ATTR(virtual_size, S_IRUGO|S_IWUSR, show_virtual, store_virtual),
__ATTR(name, S_IRUGO, show_name, NULL),
__ATTR(stride, S_IRUGO, show_stride, NULL),
+ __ATTR(rotate, S_IRUGO|S_IWUSR, show_rotate, store_rotate),
+ __ATTR(con_rotate, S_IRUGO|S_IWUSR, show_con_rotate, store_con_rotate),
+ __ATTR(con_rotate_all, S_IWUSR, NULL, store_con_rotate_all),
};
int fb_init_class_device(struct fb_info *fb_info)
diff --git a/drivers/video/ffb.c b/drivers/video/ffb.c
index 10cd05059fe9..04417dc16c2e 100644
--- a/drivers/video/ffb.c
+++ b/drivers/video/ffb.c
@@ -57,9 +57,6 @@ static struct fb_ops ffb_ops = {
.fb_sync = ffb_sync,
.fb_mmap = ffb_mmap,
.fb_ioctl = ffb_ioctl,
-
- /* XXX Use FFB hw cursor once fb cursor API is better understood... */
- .fb_cursor = soft_cursor,
};
/* Register layout and definitions */
diff --git a/drivers/video/fm2fb.c b/drivers/video/fm2fb.c
index a0763283d776..998374cfae6d 100644
--- a/drivers/video/fm2fb.c
+++ b/drivers/video/fm2fb.c
@@ -172,7 +172,6 @@ static struct fb_ops fm2fb_ops = {
.fb_fillrect = cfb_fillrect,
.fb_copyarea = cfb_copyarea,
.fb_imageblit = cfb_imageblit,
- .fb_cursor = soft_cursor,
};
/*
diff --git a/drivers/video/gbefb.c b/drivers/video/gbefb.c
index d3c1922cb13a..9d5e4f342110 100644
--- a/drivers/video/gbefb.c
+++ b/drivers/video/gbefb.c
@@ -11,7 +11,7 @@
#include <linux/config.h>
#include <linux/delay.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
#include <linux/errno.h>
#include <linux/fb.h>
@@ -1038,7 +1038,6 @@ static struct fb_ops gbefb_ops = {
.fb_fillrect = cfb_fillrect,
.fb_copyarea = cfb_copyarea,
.fb_imageblit = cfb_imageblit,
- .fb_cursor = soft_cursor,
};
/*
@@ -1126,7 +1125,7 @@ static int __init gbefb_probe(struct device *dev)
gbefb_setup(options);
#endif
- if (!request_mem_region(GBE_BASE, sizeof(struct sgi_gbe), "GBE")) {
+ if (!request_region(GBE_BASE, sizeof(struct sgi_gbe), "GBE")) {
printk(KERN_ERR "gbefb: couldn't reserve mmio region\n");
ret = -EBUSY;
goto out_release_framebuffer;
@@ -1152,12 +1151,24 @@ static int __init gbefb_probe(struct device *dev)
if (gbe_mem_phys) {
/* memory was allocated at boot time */
gbe_mem = ioremap_nocache(gbe_mem_phys, gbe_mem_size);
+ if (!gbe_mem) {
+ printk(KERN_ERR "gbefb: couldn't map framebuffer\n");
+ ret = -ENOMEM;
+ goto out_tiles_free;
+ }
+
gbe_dma_addr = 0;
} else {
/* try to allocate memory with the classical allocator
* this has high chance to fail on low memory machines */
gbe_mem = dma_alloc_coherent(NULL, gbe_mem_size, &gbe_dma_addr,
GFP_KERNEL);
+ if (!gbe_mem) {
+ printk(KERN_ERR "gbefb: couldn't allocate framebuffer memory\n");
+ ret = -ENOMEM;
+ goto out_tiles_free;
+ }
+
gbe_mem_phys = (unsigned long) gbe_dma_addr;
}
@@ -1165,12 +1176,6 @@ static int __init gbefb_probe(struct device *dev)
mtrr_add(gbe_mem_phys, gbe_mem_size, MTRR_TYPE_WRCOMB, 1);
#endif
- if (!gbe_mem) {
- printk(KERN_ERR "gbefb: couldn't map framebuffer\n");
- ret = -ENXIO;
- goto out_tiles_free;
- }
-
/* map framebuffer memory into tiles table */
for (i = 0; i < (gbe_mem_size >> TILE_SHIFT); i++)
gbe_tiles.cpu[i] = (gbe_mem_phys >> TILE_SHIFT) + i;
@@ -1254,24 +1259,30 @@ static struct device_driver gbefb_driver = {
.remove = __devexit_p(gbefb_remove),
};
-static struct platform_device gbefb_device = {
- .name = "gbefb",
-};
+static struct platform_device *gbefb_device;
int __init gbefb_init(void)
{
int ret = driver_register(&gbefb_driver);
if (!ret) {
- ret = platform_device_register(&gbefb_device);
- if (ret)
+ gbefb_device = platform_device_alloc("gbefb", 0);
+ if (gbefb_device) {
+ ret = platform_device_add(gbefb_device);
+ } else {
+ ret = -ENOMEM;
+ }
+ if (ret) {
+ platform_device_put(gbefb_device);
driver_unregister(&gbefb_driver);
+ }
}
return ret;
}
void __exit gbefb_exit(void)
{
- driver_unregister(&gbefb_driver);
+ platform_device_unregister(gbefb_device);
+ driver_unregister(&gbefb_driver);
}
module_init(gbefb_init);
diff --git a/drivers/video/geode/Kconfig b/drivers/video/geode/Kconfig
index 5a9b89c3831b..42fb9a89a792 100644
--- a/drivers/video/geode/Kconfig
+++ b/drivers/video/geode/Kconfig
@@ -14,7 +14,6 @@ config FB_GEODE_GX1
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
- select FB_SOFT_CURSOR
---help---
Framebuffer driver for the display controller integrated into the
AMD Geode GX1 processor.
diff --git a/drivers/video/geode/gx1fb_core.c b/drivers/video/geode/gx1fb_core.c
index 74a5fca86b8a..8e8da7433994 100644
--- a/drivers/video/geode/gx1fb_core.c
+++ b/drivers/video/geode/gx1fb_core.c
@@ -275,7 +275,6 @@ static struct fb_ops gx1fb_ops = {
.fb_fillrect = cfb_fillrect,
.fb_copyarea = cfb_copyarea,
.fb_imageblit = cfb_imageblit,
- .fb_cursor = soft_cursor,
};
static struct fb_info * __init gx1fb_init_fbinfo(struct device *dev)
diff --git a/drivers/video/hitfb.c b/drivers/video/hitfb.c
index 0d376ba54814..f04ca721f94c 100644
--- a/drivers/video/hitfb.c
+++ b/drivers/video/hitfb.c
@@ -262,7 +262,6 @@ static struct fb_ops hitfb_ops = {
.fb_fillrect = hitfb_fillrect,
.fb_copyarea = hitfb_copyarea,
.fb_imageblit = cfb_imageblit,
- .fb_cursor = soft_cursor,
};
int __init hitfb_init(void)
diff --git a/drivers/video/hpfb.c b/drivers/video/hpfb.c
index e97fe8481d59..bebdac59d231 100644
--- a/drivers/video/hpfb.c
+++ b/drivers/video/hpfb.c
@@ -193,7 +193,6 @@ static struct fb_ops hpfb_ops = {
.fb_fillrect = hpfb_fillrect,
.fb_copyarea = hpfb_copyarea,
.fb_imageblit = cfb_imageblit,
- .fb_cursor = soft_cursor,
.fb_sync = hpfb_sync,
};
diff --git a/drivers/video/i810/i810-i2c.c b/drivers/video/i810/i810-i2c.c
index 689d2586366d..c61bad0da20f 100644
--- a/drivers/video/i810/i810-i2c.c
+++ b/drivers/video/i810/i810-i2c.c
@@ -46,92 +46,45 @@ static void i810i2c_setscl(void *data, int state)
struct i810fb_par *par = chan->par;
u8 __iomem *mmio = par->mmio_start_virtual;
- i810_writel(mmio, GPIOB, (state ? SCL_VAL_OUT : 0) | SCL_DIR |
+ i810_writel(mmio, chan->ddc_base, (state ? SCL_VAL_OUT : 0) | SCL_DIR |
SCL_DIR_MASK | SCL_VAL_MASK);
- i810_readl(mmio, GPIOB); /* flush posted write */
+ i810_readl(mmio, chan->ddc_base); /* flush posted write */
}
static void i810i2c_setsda(void *data, int state)
{
- struct i810fb_i2c_chan *chan = (struct i810fb_i2c_chan *)data;
+ struct i810fb_i2c_chan *chan = data;
struct i810fb_par *par = chan->par;
u8 __iomem *mmio = par->mmio_start_virtual;
- i810_writel(mmio, GPIOB, (state ? SDA_VAL_OUT : 0) | SDA_DIR |
+ i810_writel(mmio, chan->ddc_base, (state ? SDA_VAL_OUT : 0) | SDA_DIR |
SDA_DIR_MASK | SDA_VAL_MASK);
- i810_readl(mmio, GPIOB); /* flush posted write */
+ i810_readl(mmio, chan->ddc_base); /* flush posted write */
}
static int i810i2c_getscl(void *data)
{
- struct i810fb_i2c_chan *chan = (struct i810fb_i2c_chan *)data;
+ struct i810fb_i2c_chan *chan = data;
struct i810fb_par *par = chan->par;
u8 __iomem *mmio = par->mmio_start_virtual;
- i810_writel(mmio, GPIOB, SCL_DIR_MASK);
- i810_writel(mmio, GPIOB, 0);
- return (0 != (i810_readl(mmio, GPIOB) & SCL_VAL_IN));
+ i810_writel(mmio, chan->ddc_base, SCL_DIR_MASK);
+ i810_writel(mmio, chan->ddc_base, 0);
+ return ((i810_readl(mmio, chan->ddc_base) & SCL_VAL_IN) != 0);
}
static int i810i2c_getsda(void *data)
{
- struct i810fb_i2c_chan *chan = (struct i810fb_i2c_chan *)data;
+ struct i810fb_i2c_chan *chan = data;
struct i810fb_par *par = chan->par;
u8 __iomem *mmio = par->mmio_start_virtual;
- i810_writel(mmio, GPIOB, SDA_DIR_MASK);
- i810_writel(mmio, GPIOB, 0);
- return (0 != (i810_readl(mmio, GPIOB) & SDA_VAL_IN));
-}
-
-static void i810ddc_setscl(void *data, int state)
-{
- struct i810fb_i2c_chan *chan = (struct i810fb_i2c_chan *)data;
- struct i810fb_par *par = chan->par;
- u8 __iomem *mmio = par->mmio_start_virtual;
-
- i810_writel(mmio, GPIOA, (state ? SCL_VAL_OUT : 0) | SCL_DIR |
- SCL_DIR_MASK | SCL_VAL_MASK);
- i810_readl(mmio, GPIOA); /* flush posted write */
-}
-
-static void i810ddc_setsda(void *data, int state)
-{
- struct i810fb_i2c_chan *chan = (struct i810fb_i2c_chan *)data;
- struct i810fb_par *par = chan->par;
- u8 __iomem *mmio = par->mmio_start_virtual;
-
- i810_writel(mmio, GPIOA, (state ? SDA_VAL_OUT : 0) | SDA_DIR |
- SDA_DIR_MASK | SDA_VAL_MASK);
- i810_readl(mmio, GPIOA); /* flush posted write */
-}
-
-static int i810ddc_getscl(void *data)
-{
- struct i810fb_i2c_chan *chan = (struct i810fb_i2c_chan *)data;
- struct i810fb_par *par = chan->par;
- u8 __iomem *mmio = par->mmio_start_virtual;
-
- i810_writel(mmio, GPIOA, SCL_DIR_MASK);
- i810_writel(mmio, GPIOA, 0);
- return (0 != (i810_readl(mmio, GPIOA) & SCL_VAL_IN));
-}
-
-static int i810ddc_getsda(void *data)
-{
- struct i810fb_i2c_chan *chan = (struct i810fb_i2c_chan *)data;
- struct i810fb_par *par = chan->par;
- u8 __iomem *mmio = par->mmio_start_virtual;
-
- i810_writel(mmio, GPIOA, SDA_DIR_MASK);
- i810_writel(mmio, GPIOA, 0);
- return (0 != (i810_readl(mmio, GPIOA) & SDA_VAL_IN));
+ i810_writel(mmio, chan->ddc_base, SDA_DIR_MASK);
+ i810_writel(mmio, chan->ddc_base, 0);
+ return ((i810_readl(mmio, chan->ddc_base) & SDA_VAL_IN) != 0);
}
-#define I2C_ALGO_DDC_I810 0x0e0000
-#define I2C_ALGO_I2C_I810 0x0f0000
-static int i810_setup_i2c_bus(struct i810fb_i2c_chan *chan, const char *name,
- int conn)
+static int i810_setup_i2c_bus(struct i810fb_i2c_chan *chan, const char *name)
{
int rc;
@@ -139,22 +92,11 @@ static int i810_setup_i2c_bus(struct i810fb_i2c_chan *chan, const char *name,
chan->adapter.owner = THIS_MODULE;
chan->adapter.algo_data = &chan->algo;
chan->adapter.dev.parent = &chan->par->dev->dev;
- switch (conn) {
- case 1:
- chan->adapter.id = I2C_ALGO_DDC_I810;
- chan->algo.setsda = i810ddc_setsda;
- chan->algo.setscl = i810ddc_setscl;
- chan->algo.getsda = i810ddc_getsda;
- chan->algo.getscl = i810ddc_getscl;
- break;
- case 2:
- chan->adapter.id = I2C_ALGO_I2C_I810;
- chan->algo.setsda = i810i2c_setsda;
- chan->algo.setscl = i810i2c_setscl;
- chan->algo.getsda = i810i2c_getsda;
- chan->algo.getscl = i810i2c_getscl;
- break;
- }
+ chan->adapter.id = I2C_HW_B_I810;
+ chan->algo.setsda = i810i2c_setsda;
+ chan->algo.setscl = i810i2c_setscl;
+ chan->algo.getsda = i810i2c_getsda;
+ chan->algo.getscl = i810i2c_getscl;
chan->algo.udelay = 10;
chan->algo.mdelay = 10;
chan->algo.timeout = (HZ/2);
@@ -168,11 +110,15 @@ static int i810_setup_i2c_bus(struct i810fb_i2c_chan *chan, const char *name,
udelay(20);
rc = i2c_bit_add_bus(&chan->adapter);
+
if (rc == 0)
dev_dbg(&chan->par->dev->dev, "I2C bus %s registered.\n",name);
- else
+ else {
dev_warn(&chan->par->dev->dev, "Failed to register I2C bus "
"%s.\n", name);
+ chan->par = NULL;
+ }
+
return rc;
}
@@ -180,8 +126,14 @@ void i810_create_i2c_busses(struct i810fb_par *par)
{
par->chan[0].par = par;
par->chan[1].par = par;
- i810_setup_i2c_bus(&par->chan[0], "I810-DDC", 1);
- i810_setup_i2c_bus(&par->chan[1], "I810-I2C", 2);
+ par->chan[2].par = par;
+
+ par->chan[0].ddc_base = GPIOA;
+ i810_setup_i2c_bus(&par->chan[0], "I810-DDC");
+ par->chan[1].ddc_base = GPIOB;
+ i810_setup_i2c_bus(&par->chan[1], "I810-I2C");
+ par->chan[2].ddc_base = GPIOC;
+ i810_setup_i2c_bus(&par->chan[2], "I810-GPIOC");
}
void i810_delete_i2c_busses(struct i810fb_par *par)
@@ -189,9 +141,14 @@ void i810_delete_i2c_busses(struct i810fb_par *par)
if (par->chan[0].par)
i2c_bit_del_bus(&par->chan[0].adapter);
par->chan[0].par = NULL;
+
if (par->chan[1].par)
i2c_bit_del_bus(&par->chan[1].adapter);
par->chan[1].par = NULL;
+
+ if (par->chan[2].par)
+ i2c_bit_del_bus(&par->chan[2].adapter);
+ par->chan[2].par = NULL;
}
static u8 *i810_do_probe_i2c_edid(struct i810fb_i2c_chan *chan)
@@ -221,6 +178,7 @@ static u8 *i810_do_probe_i2c_edid(struct i810fb_i2c_chan *chan)
DPRINTK("i810-i2c: I2C Transfer successful\n");
return buf;
}
+
DPRINTK("i810-i2c: Unable to read EDID block.\n");
kfree(buf);
return NULL;
@@ -233,7 +191,7 @@ int i810_probe_i2c_connector(struct fb_info *info, u8 **out_edid, int conn)
int i;
DPRINTK("i810-i2c: Probe DDC%i Bus\n", conn);
- if (conn < 3) {
+ if (conn < 4) {
for (i = 0; i < 3; i++) {
/* Do the real work */
edid = i810_do_probe_i2c_edid(&par->chan[conn-1]);
@@ -241,11 +199,14 @@ int i810_probe_i2c_connector(struct fb_info *info, u8 **out_edid, int conn)
break;
}
} else {
- DPRINTK("i810-i2c: Getting EDID from BIOS\n");
- edid = kmalloc(EDID_LENGTH, GFP_KERNEL);
- if (edid)
- memcpy(edid, fb_firmware_edid(info->device),
- EDID_LENGTH);
+ const u8 *e = fb_firmware_edid(info->device);
+
+ if (e != NULL) {
+ DPRINTK("i810-i2c: Getting EDID from BIOS\n");
+ edid = kmalloc(EDID_LENGTH, GFP_KERNEL);
+ if (edid)
+ memcpy(edid, e, EDID_LENGTH);
+ }
}
if (out_edid)
@@ -253,5 +214,3 @@ int i810_probe_i2c_connector(struct fb_info *info, u8 **out_edid, int conn)
return (edid) ? 0 : 1;
}
-
-
diff --git a/drivers/video/i810/i810.h b/drivers/video/i810/i810.h
index d48949ceaacc..6c187d5fe951 100644
--- a/drivers/video/i810/i810.h
+++ b/drivers/video/i810/i810.h
@@ -249,6 +249,7 @@ struct i810fb_i2c_chan {
struct i810fb_par *par;
struct i2c_adapter adapter;
struct i2c_algo_bit_data algo;
+ unsigned long ddc_base;
};
struct i810fb_par {
@@ -262,7 +263,7 @@ struct i810fb_par {
struct heap_data iring;
struct heap_data cursor_heap;
struct vgastate state;
- struct i810fb_i2c_chan chan[2];
+ struct i810fb_i2c_chan chan[3];
atomic_t use_count;
u32 pseudo_palette[17];
unsigned long mmio_start_phys;
diff --git a/drivers/video/i810/i810_main.c b/drivers/video/i810/i810_main.c
index 0dbc9ddb6766..c0c974b1afaa 100644
--- a/drivers/video/i810/i810_main.c
+++ b/drivers/video/i810/i810_main.c
@@ -1854,7 +1854,7 @@ static void __devinit i810fb_find_init_mode(struct fb_info *info)
#ifdef CONFIG_FB_I810_I2C
i810_create_i2c_busses(par);
- for (i = 0; i < 3; i++) {
+ for (i = 0; i < 4; i++) {
err = i810_probe_i2c_connector(info, &par->edid, i+1);
if (!err)
break;
@@ -1871,27 +1871,18 @@ static void __devinit i810fb_find_init_mode(struct fb_info *info)
fb_videomode_to_modelist(specs->modedb, specs->modedb_len,
&info->modelist);
if (specs->modedb != NULL) {
- if (xres && yres) {
- struct fb_videomode *m;
+ struct fb_videomode *m;
+ if (xres && yres) {
if ((m = fb_find_best_mode(&var, &info->modelist))) {
mode = *m;
found = 1;
}
}
- if (!found && specs->misc & FB_MISC_1ST_DETAIL) {
- for (i = 0; i < specs->modedb_len; i++) {
- if (specs->modedb[i].flag & FB_MODE_IS_FIRST) {
- mode = specs->modedb[i];
- found = 1;
- break;
- }
- }
- }
-
if (!found) {
- mode = specs->modedb[0];
+ m = fb_find_best_display(&info->monspecs, &info->modelist);
+ mode = *m;
found = 1;
}
@@ -2066,8 +2057,7 @@ static void i810fb_release_resource(struct fb_info *info,
iounmap(par->mmio_start_virtual);
if (par->aperture.virtual)
iounmap(par->aperture.virtual);
- if (par->edid)
- kfree(par->edid);
+ kfree(par->edid);
if (par->res_flags & FRAMEBUFFER_REQ)
release_mem_region(par->aperture.physical,
par->aperture.size);
diff --git a/drivers/video/i810/i810_regs.h b/drivers/video/i810/i810_regs.h
index 6e4b9afa4d98..91c6bd9d0d0d 100644
--- a/drivers/video/i810/i810_regs.h
+++ b/drivers/video/i810/i810_regs.h
@@ -70,6 +70,7 @@
#define HVSYNC 0x05000
#define GPIOA 0x05010
#define GPIOB 0x05014
+#define GPIOC 0x0501C
/* Clock Control and Power Management Registers (06000h 06FFFh) */
#define DCLK_0D 0x06000
diff --git a/drivers/video/imsttfb.c b/drivers/video/imsttfb.c
index 7b9bf45ab6fe..7fbe24206b19 100644
--- a/drivers/video/imsttfb.c
+++ b/drivers/video/imsttfb.c
@@ -1344,7 +1344,6 @@ static struct fb_ops imsttfb_ops = {
.fb_fillrect = imsttfb_fillrect,
.fb_copyarea = imsttfb_copyarea,
.fb_imageblit = cfb_imageblit,
- .fb_cursor = soft_cursor,
.fb_ioctl = imsttfb_ioctl,
};
diff --git a/drivers/video/imxfb.c b/drivers/video/imxfb.c
index 1d54d3d6960b..e20b9f3a255f 100644
--- a/drivers/video/imxfb.c
+++ b/drivers/video/imxfb.c
@@ -31,7 +31,7 @@
#include <linux/init.h>
#include <linux/ioport.h>
#include <linux/cpufreq.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
#include <asm/hardware.h>
@@ -298,7 +298,6 @@ static struct fb_ops imxfb_ops = {
.fb_copyarea = cfb_copyarea,
.fb_imageblit = cfb_imageblit,
.fb_blank = imxfb_blank,
- .fb_cursor = soft_cursor, /* FIXME: i.MX can do hardware cursor */
};
/*
@@ -424,23 +423,21 @@ static void imxfb_setup_gpio(struct imxfb_info *fbi)
* Power management hooks. Note that we won't be called from IRQ context,
* unlike the blank functions above, so we may sleep.
*/
-static int imxfb_suspend(struct device *dev, pm_message_t state, u32 level)
+static int imxfb_suspend(struct device *dev, pm_message_t state)
{
struct imxfb_info *fbi = dev_get_drvdata(dev);
pr_debug("%s\n",__FUNCTION__);
- if (level == SUSPEND_DISABLE || level == SUSPEND_POWER_DOWN)
- imxfb_disable_controller(fbi);
+ imxfb_disable_controller(fbi);
return 0;
}
-static int imxfb_resume(struct device *dev, u32 level)
+static int imxfb_resume(struct device *dev)
{
struct imxfb_info *fbi = dev_get_drvdata(dev);
pr_debug("%s\n",__FUNCTION__);
- if (level == RESUME_ENABLE)
- imxfb_enable_controller(fbi);
+ imxfb_enable_controller(fbi);
return 0;
}
#else
diff --git a/drivers/video/intelfb/intelfb.h b/drivers/video/intelfb/intelfb.h
index 011e11626558..f077ca34faba 100644
--- a/drivers/video/intelfb/intelfb.h
+++ b/drivers/video/intelfb/intelfb.h
@@ -10,7 +10,7 @@
/*** Version/name ***/
#define INTELFB_VERSION "0.9.2"
#define INTELFB_MODULE_NAME "intelfb"
-#define SUPPORTED_CHIPSETS "830M/845G/852GM/855GM/865G/915G"
+#define SUPPORTED_CHIPSETS "830M/845G/852GM/855GM/865G/915G/915GM"
/*** Debug/feature defines ***/
@@ -47,6 +47,7 @@
#define PCI_DEVICE_ID_INTEL_85XGM 0x3582
#define PCI_DEVICE_ID_INTEL_865G 0x2572
#define PCI_DEVICE_ID_INTEL_915G 0x2582
+#define PCI_DEVICE_ID_INTEL_915GM 0x2592
/* Size of MMIO region */
#define INTEL_REG_SIZE 0x80000
@@ -119,7 +120,8 @@ enum intel_chips {
INTEL_855GM,
INTEL_855GME,
INTEL_865G,
- INTEL_915G
+ INTEL_915G,
+ INTEL_915GM
};
struct intelfb_hwstate {
diff --git a/drivers/video/intelfb/intelfbdrv.c b/drivers/video/intelfb/intelfbdrv.c
index 80a09344f1aa..427689e584da 100644
--- a/drivers/video/intelfb/intelfbdrv.c
+++ b/drivers/video/intelfb/intelfbdrv.c
@@ -1,7 +1,7 @@
/*
* intelfb
*
- * Linux framebuffer driver for Intel(R) 830M/845G/852GM/855GM/865G/915G
+ * Linux framebuffer driver for Intel(R) 830M/845G/852GM/855GM/865G/915G/915GM
* integrated graphics chips.
*
* Copyright © 2002, 2003 David Dawes <dawes@xfree86.org>
@@ -122,7 +122,6 @@
#include <linux/pci.h>
#include <linux/vmalloc.h>
#include <linux/pagemap.h>
-#include <linux/version.h>
#include <asm/io.h>
@@ -186,6 +185,7 @@ static struct pci_device_id intelfb_pci_table[] __devinitdata = {
{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_85XGM, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_85XGM },
{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_865G, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_865G },
{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_915G, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_915G },
+ { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_915GM, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_915GM },
{ 0, }
};
@@ -549,10 +549,11 @@ intelfb_pci_register(struct pci_dev *pdev, const struct pci_device_id *ent)
}
/* Set base addresses. */
- if (ent->device == PCI_DEVICE_ID_INTEL_915G) {
+ if ((ent->device == PCI_DEVICE_ID_INTEL_915G) ||
+ (ent->device == PCI_DEVICE_ID_INTEL_915GM)) {
aperture_bar = 2;
mmio_bar = 0;
- /* Disable HW cursor on 915G (not implemented yet) */
+ /* Disable HW cursor on 915G/M (not implemented yet) */
hwcursor = 0;
}
dinfo->aperture.physical = pci_resource_start(pdev, aperture_bar);
@@ -1483,7 +1484,7 @@ intelfb_cursor(struct fb_info *info, struct fb_cursor *cursor)
#endif
if (!dinfo->hwcursor)
- return soft_cursor(info, cursor);
+ return -ENODEV;
intelfbhw_cursor_hide(dinfo);
diff --git a/drivers/video/intelfb/intelfbhw.c b/drivers/video/intelfb/intelfbhw.c
index 5bafc3c54db7..624c4bc96f0d 100644
--- a/drivers/video/intelfb/intelfbhw.c
+++ b/drivers/video/intelfb/intelfbhw.c
@@ -34,7 +34,6 @@
#include <linux/pci.h>
#include <linux/vmalloc.h>
#include <linux/pagemap.h>
-#include <linux/version.h>
#include <asm/io.h>
@@ -99,6 +98,11 @@ intelfbhw_get_chipset(struct pci_dev *pdev, const char **name, int *chipset,
*chipset = INTEL_915G;
*mobile = 0;
return 0;
+ case PCI_DEVICE_ID_INTEL_915GM:
+ *name = "Intel(R) 915GM";
+ *chipset = INTEL_915GM;
+ *mobile = 1;
+ return 0;
default:
return 1;
}
diff --git a/drivers/video/kyro/fbdev.c b/drivers/video/kyro/fbdev.c
index d8bac9e97842..5eb4d5c177bd 100644
--- a/drivers/video/kyro/fbdev.c
+++ b/drivers/video/kyro/fbdev.c
@@ -669,7 +669,6 @@ static struct fb_ops kyrofb_ops = {
.fb_fillrect = cfb_fillrect,
.fb_copyarea = cfb_copyarea,
.fb_imageblit = cfb_imageblit,
- .fb_cursor = soft_cursor,
};
static int __devinit kyrofb_probe(struct pci_dev *pdev,
diff --git a/drivers/video/leo.c b/drivers/video/leo.c
index 7e1e7fb168bd..84a7fe435bb8 100644
--- a/drivers/video/leo.c
+++ b/drivers/video/leo.c
@@ -51,7 +51,6 @@ static struct fb_ops leo_ops = {
.fb_imageblit = cfb_imageblit,
.fb_mmap = leo_mmap,
.fb_ioctl = leo_ioctl,
- .fb_cursor = soft_cursor,
};
#define LEO_OFF_LC_SS0_KRN 0x00200000UL
diff --git a/drivers/video/logo/Kconfig b/drivers/video/logo/Kconfig
index 3e9ccf370ab2..8cb7fb4db441 100644
--- a/drivers/video/logo/Kconfig
+++ b/drivers/video/logo/Kconfig
@@ -7,6 +7,8 @@ menu "Logo configuration"
config LOGO
bool "Bootup logo"
depends on FB || SGI_NEWPORT_CONSOLE
+ help
+ Enable and select frame buffer bootup logos.
config LOGO_LINUX_MONO
bool "Standard black and white Linux logo"
diff --git a/drivers/video/macfb.c b/drivers/video/macfb.c
index 4945a4c02209..cfc748e94272 100644
--- a/drivers/video/macfb.c
+++ b/drivers/video/macfb.c
@@ -589,7 +589,6 @@ static struct fb_ops macfb_ops = {
.fb_fillrect = cfb_fillrect,
.fb_copyarea = cfb_copyarea,
.fb_imageblit = cfb_imageblit,
- .fb_cursor = soft_cursor,
};
void __init macfb_setup(char *options)
diff --git a/drivers/video/matrox/matroxfb_DAC1064.c b/drivers/video/matrox/matroxfb_DAC1064.c
index 149680f8bcf0..0fbd9b5149f1 100644
--- a/drivers/video/matrox/matroxfb_DAC1064.c
+++ b/drivers/video/matrox/matroxfb_DAC1064.c
@@ -657,7 +657,6 @@ static int MGA1064_preinit(WPMINFO2) {
/* ACCESS_FBINFO(capable.cfb4) = 0; ... preinitialized by 0 */
ACCESS_FBINFO(capable.text) = 1;
ACCESS_FBINFO(capable.vxres) = vxres_mystique;
- ACCESS_FBINFO(features.accel.has_cacheflush) = 1;
ACCESS_FBINFO(outputs[0]).output = &m1064;
ACCESS_FBINFO(outputs[0]).src = ACCESS_FBINFO(outputs[0]).default_src;
@@ -842,7 +841,6 @@ static int MGAG100_preinit(WPMINFO2) {
/* ACCESS_FBINFO(capable.cfb4) = 0; ... preinitialized by 0 */
ACCESS_FBINFO(capable.text) = 1;
ACCESS_FBINFO(capable.vxres) = vxres_g100;
- ACCESS_FBINFO(features.accel.has_cacheflush) = 1;
ACCESS_FBINFO(capable.plnwt) = ACCESS_FBINFO(devflags.accelerator) == FB_ACCEL_MATROX_MGAG100
? ACCESS_FBINFO(devflags.sgram) : 1;
@@ -980,7 +978,7 @@ static void MGAG100_reset(WPMINFO2) {
hw->MXoptionReg |= 0x40; /* FIXME... */
pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, hw->MXoptionReg);
}
- mga_setr(M_EXTVGA_INDEX, 0x06, 0x50);
+ mga_setr(M_EXTVGA_INDEX, 0x06, 0x00);
}
}
if (ACCESS_FBINFO(devflags.g450dac)) {
diff --git a/drivers/video/matrox/matroxfb_accel.c b/drivers/video/matrox/matroxfb_accel.c
index c7f3e1321224..a5c825d99466 100644
--- a/drivers/video/matrox/matroxfb_accel.c
+++ b/drivers/video/matrox/matroxfb_accel.c
@@ -122,7 +122,7 @@ void matrox_cfbX_init(WPMINFO2) {
ACCESS_FBINFO(fbops).fb_copyarea = cfb_copyarea;
ACCESS_FBINFO(fbops).fb_fillrect = cfb_fillrect;
ACCESS_FBINFO(fbops).fb_imageblit = cfb_imageblit;
- ACCESS_FBINFO(fbops).fb_cursor = soft_cursor;
+ ACCESS_FBINFO(fbops).fb_cursor = NULL;
accel = (ACCESS_FBINFO(fbcon).var.accel_flags & FB_ACCELF_TEXT) == FB_ACCELF_TEXT;
diff --git a/drivers/video/matrox/matroxfb_base.c b/drivers/video/matrox/matroxfb_base.c
index e02da41f1b26..1e74f4cca53b 100644
--- a/drivers/video/matrox/matroxfb_base.c
+++ b/drivers/video/matrox/matroxfb_base.c
@@ -264,7 +264,6 @@ static void matroxfb_disable_irq(WPMINFO2) {
}
int matroxfb_wait_for_sync(WPMINFO u_int32_t crtc) {
- wait_queue_t __wait;
struct matrox_vsync *vs;
unsigned int cnt;
int ret;
@@ -286,7 +285,6 @@ int matroxfb_wait_for_sync(WPMINFO u_int32_t crtc) {
if (ret) {
return ret;
}
- init_waitqueue_entry(&__wait, current);
cnt = vs->cnt;
ret = wait_event_interruptible_timeout(vs->wait, cnt != vs->cnt, HZ/10);
@@ -500,10 +498,6 @@ static int matroxfb_pitch_adjust(CPMINFO int xres, int bpp) {
} else {
xres_new = matroxfb_test_and_set_rounding(PMINFO xres, bpp);
}
- if (!xres_new) return 0;
- if (xres != xres_new) {
- printk(KERN_INFO "matroxfb: cannot set xres to %d, rounded up to %d\n", xres, xres_new);
- }
return xres_new;
}
@@ -1285,7 +1279,7 @@ static int matroxfb_getmemory(WPMINFO unsigned int maxSize, unsigned int *realSi
vaddr_t vm;
unsigned int offs;
unsigned int offs2;
- unsigned char store, orig;
+ unsigned char orig;
unsigned char bytes[32];
unsigned char* tmp;
@@ -1301,16 +1295,12 @@ static int matroxfb_getmemory(WPMINFO unsigned int maxSize, unsigned int *realSi
orig = mga_inb(M_EXTVGA_DATA);
mga_outb(M_EXTVGA_DATA, orig | 0x80);
- store = mga_readb(vm, 0x1234);
tmp = bytes;
for (offs = 0x100000; offs < maxSize; offs += 0x200000)
*tmp++ = mga_readb(vm, offs);
for (offs = 0x100000; offs < maxSize; offs += 0x200000)
mga_writeb(vm, offs, 0x02);
- if (ACCESS_FBINFO(features.accel.has_cacheflush))
- mga_outb(M_CACHEFLUSH, 0x00);
- else
- mga_writeb(vm, 0x1234, 0x99);
+ mga_outb(M_CACHEFLUSH, 0x00);
for (offs = 0x100000; offs < maxSize; offs += 0x200000) {
if (mga_readb(vm, offs) != 0x02)
break;
@@ -1321,7 +1311,6 @@ static int matroxfb_getmemory(WPMINFO unsigned int maxSize, unsigned int *realSi
tmp = bytes;
for (offs2 = 0x100000; offs2 < maxSize; offs2 += 0x200000)
mga_writeb(vm, offs2, *tmp++);
- mga_writeb(vm, 0x1234, store);
mga_outb(M_EXTVGA_INDEX, 0x03);
mga_outb(M_EXTVGA_DATA, orig);
@@ -1430,6 +1419,20 @@ static struct board {
MGA_1164,
&vbMystique,
"Mystique 220 (PCI)"},
+ {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_MYS_AGP, 0x02,
+ 0, 0,
+ DEVF_VIDEO64BIT | DEVF_CROSS4MB,
+ 180000,
+ MGA_1064,
+ &vbMystique,
+ "Mystique (AGP)"},
+ {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_MYS_AGP, 0xFF,
+ 0, 0,
+ DEVF_VIDEO64BIT | DEVF_SWAPS | DEVF_CROSS4MB,
+ 220000,
+ MGA_1164,
+ &vbMystique,
+ "Mystique 220 (AGP)"},
#endif
#ifdef CONFIG_FB_MATROX_G
{PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G100_MM, 0xFF,
diff --git a/drivers/video/matrox/matroxfb_base.h b/drivers/video/matrox/matroxfb_base.h
index 85a0b2558452..a8c47ad2cdb6 100644
--- a/drivers/video/matrox/matroxfb_base.h
+++ b/drivers/video/matrox/matroxfb_base.h
@@ -272,10 +272,6 @@ struct matrox_DAC1064_features {
u_int8_t xmiscctrl;
};
-struct matrox_accel_features {
- int has_cacheflush;
-};
-
/* current hardware status */
struct mavenregs {
u_int8_t regs[256];
@@ -440,7 +436,6 @@ struct matrox_fb_info {
struct {
struct matrox_pll_features pll;
struct matrox_DAC1064_features DAC1064;
- struct matrox_accel_features accel;
} features;
struct {
spinlock_t DAC;
diff --git a/drivers/video/matrox/matroxfb_crtc2.c b/drivers/video/matrox/matroxfb_crtc2.c
index 429047ac615a..d52d7d825c41 100644
--- a/drivers/video/matrox/matroxfb_crtc2.c
+++ b/drivers/video/matrox/matroxfb_crtc2.c
@@ -576,7 +576,6 @@ static struct fb_ops matroxfb_dh_ops = {
.fb_fillrect = cfb_fillrect,
.fb_copyarea = cfb_copyarea,
.fb_imageblit = cfb_imageblit,
- .fb_cursor = soft_cursor,
};
static struct fb_var_screeninfo matroxfb_dh_defined = {
diff --git a/drivers/video/maxinefb.c b/drivers/video/maxinefb.c
index f192d995d030..743e7ad26acc 100644
--- a/drivers/video/maxinefb.c
+++ b/drivers/video/maxinefb.c
@@ -113,7 +113,6 @@ static struct fb_ops maxinefb_ops = {
.fb_fillrect = cfb_fillrect,
.fb_copyarea = cfb_copyarea,
.fb_imageblit = cfb_imageblit,
- .fb_cursor = soft_cursor,
};
int __init maxinefb_init(void)
diff --git a/drivers/video/modedb.c b/drivers/video/modedb.c
index 47516c44a390..1da2f84bdc25 100644
--- a/drivers/video/modedb.c
+++ b/drivers/video/modedb.c
@@ -251,6 +251,10 @@ static const struct fb_videomode modedb[] = {
NULL, 60, 1920, 1200, 5177, 128, 336, 1, 38, 208, 3,
FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
FB_VMODE_NONINTERLACED
+ }, {
+ /* 1152x768, 60 Hz, PowerBook G4 Titanium I and II */
+ NULL, 60, 1152, 768, 15386, 158, 26, 29, 3, 136, 6,
+ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
},
};
@@ -676,6 +680,8 @@ void fb_var_to_videomode(struct fb_videomode *mode,
mode->sync = var->sync;
mode->vmode = var->vmode & FB_VMODE_MASK;
mode->flag = FB_MODE_IS_FROM_VAR;
+ mode->refresh = 0;
+
if (!var->pixclock)
return;
@@ -785,39 +791,39 @@ struct fb_videomode *fb_find_best_mode(struct fb_var_screeninfo *var,
}
/**
- * fb_find_nearest_mode - find mode closest video mode
+ * fb_find_nearest_mode - find closest videomode
*
- * @var: pointer to struct fb_var_screeninfo
+ * @mode: pointer to struct fb_videomode
* @head: pointer to modelist
*
* Finds best matching videomode, smaller or greater in dimension.
* If more than 1 videomode is found, will return the videomode with
- * the closest refresh rate
+ * the closest refresh rate.
*/
-struct fb_videomode *fb_find_nearest_mode(struct fb_var_screeninfo *var,
+struct fb_videomode *fb_find_nearest_mode(struct fb_videomode *mode,
struct list_head *head)
{
struct list_head *pos;
struct fb_modelist *modelist;
- struct fb_videomode *mode, *best = NULL;
+ struct fb_videomode *cmode, *best = NULL;
u32 diff = -1, diff_refresh = -1;
list_for_each(pos, head) {
u32 d;
modelist = list_entry(pos, struct fb_modelist, list);
- mode = &modelist->mode;
+ cmode = &modelist->mode;
- d = abs(mode->xres - var->xres) +
- abs(mode->yres - var->yres);
+ d = abs(cmode->xres - mode->xres) +
+ abs(cmode->yres - mode->yres);
if (diff > d) {
diff = d;
- best = mode;
+ best = cmode;
} else if (diff == d) {
- d = abs(mode->refresh - best->refresh);
+ d = abs(cmode->refresh - mode->refresh);
if (diff_refresh > d) {
diff_refresh = d;
- best = mode;
+ best = cmode;
}
}
}
@@ -942,6 +948,66 @@ void fb_videomode_to_modelist(struct fb_videomode *modedb, int num,
}
}
+struct fb_videomode *fb_find_best_display(struct fb_monspecs *specs,
+ struct list_head *head)
+{
+ struct list_head *pos;
+ struct fb_modelist *modelist;
+ struct fb_videomode *m, *m1 = NULL, *md = NULL, *best = NULL;
+ int first = 0;
+
+ if (!head->prev || !head->next || list_empty(head))
+ goto finished;
+
+ /* get the first detailed mode and the very first mode */
+ list_for_each(pos, head) {
+ modelist = list_entry(pos, struct fb_modelist, list);
+ m = &modelist->mode;
+
+ if (!first) {
+ m1 = m;
+ first = 1;
+ }
+
+ if (m->flag & FB_MODE_IS_FIRST) {
+ md = m;
+ break;
+ }
+ }
+
+ /* first detailed timing is preferred */
+ if (specs->misc & FB_MISC_1ST_DETAIL) {
+ best = md;
+ goto finished;
+ }
+
+ /* find best mode based on display width and height */
+ if (specs->max_x && specs->max_y) {
+ struct fb_var_screeninfo var;
+
+ memset(&var, 0, sizeof(struct fb_var_screeninfo));
+ var.xres = (specs->max_x * 7200)/254;
+ var.yres = (specs->max_y * 7200)/254;
+ m = fb_find_best_mode(&var, head);
+ if (m) {
+ best = m;
+ goto finished;
+ }
+ }
+
+ /* use first detailed mode */
+ if (md) {
+ best = md;
+ goto finished;
+ }
+
+ /* last resort, use the very first mode */
+ best = m1;
+finished:
+ return best;
+}
+EXPORT_SYMBOL(fb_find_best_display);
+
EXPORT_SYMBOL(fb_videomode_to_var);
EXPORT_SYMBOL(fb_var_to_videomode);
EXPORT_SYMBOL(fb_mode_is_equal);
diff --git a/drivers/video/neofb.c b/drivers/video/neofb.c
index 5d424a30270a..8486e77872dc 100644
--- a/drivers/video/neofb.c
+++ b/drivers/video/neofb.c
@@ -1665,7 +1665,6 @@ static struct fb_ops neofb_ops = {
.fb_fillrect = neofb_fillrect,
.fb_copyarea = neofb_copyarea,
.fb_imageblit = neofb_imageblit,
- .fb_cursor = soft_cursor,
};
/* --------------------------------------------------------------------- */
diff --git a/drivers/video/nvidia/nv_local.h b/drivers/video/nvidia/nv_local.h
index afee284fc73c..4243d7fae972 100644
--- a/drivers/video/nvidia/nv_local.h
+++ b/drivers/video/nvidia/nv_local.h
@@ -105,7 +105,7 @@ do { \
*a = byte_rev[*a]; \
} while(0)
#else
-#define reverse_order(l)
+#define reverse_order(l) do { } while(0)
#endif /* __LITTLE_ENDIAN */
#endif /* __NV_LOCAL_H__ */
diff --git a/drivers/video/nvidia/nv_of.c b/drivers/video/nvidia/nv_of.c
index 4fa2cf9a8af2..7a03d040b1a3 100644
--- a/drivers/video/nvidia/nv_of.c
+++ b/drivers/video/nvidia/nv_of.c
@@ -27,34 +27,60 @@
#include "nv_local.h"
#include "nv_proto.h"
-void nvidia_create_i2c_busses(struct nvidia_par *par) {}
-void nvidia_delete_i2c_busses(struct nvidia_par *par) {}
+#include "../edid.h"
-int nvidia_probe_i2c_connector(struct fb_info *info, int conn, u8 **out_edid)
+int nvidia_probe_of_connector(struct fb_info *info, int conn, u8 **out_edid)
{
struct nvidia_par *par = info->par;
- struct device_node *dp;
+ struct device_node *parent, *dp;
unsigned char *pedid = NULL;
- unsigned char *disptype = NULL;
static char *propnames[] = {
- "DFP,EDID", "LCD,EDID", "EDID", "EDID1", "EDID,B", "EDID,A", NULL };
+ "DFP,EDID", "LCD,EDID", "EDID", "EDID1",
+ "EDID,B", "EDID,A", NULL };
int i;
- dp = pci_device_to_OF_node(par->pci_dev);
- for (; dp != NULL; dp = dp->child) {
- disptype = (unsigned char *)get_property(dp, "display-type", NULL);
- if (disptype == NULL)
- continue;
- if (strncmp(disptype, "LCD", 3) != 0)
- continue;
+ parent = pci_device_to_OF_node(par->pci_dev);
+ if (parent == NULL)
+ return -1;
+ if (par->twoHeads) {
+ char *pname;
+ int len;
+
+ for (dp = NULL;
+ (dp = of_get_next_child(parent, dp)) != NULL;) {
+ pname = (char *)get_property(dp, "name", NULL);
+ if (!pname)
+ continue;
+ len = strlen(pname);
+ if ((pname[len-1] == 'A' && conn == 1) ||
+ (pname[len-1] == 'B' && conn == 2)) {
+ for (i = 0; propnames[i] != NULL; ++i) {
+ pedid = (unsigned char *)
+ get_property(dp, propnames[i],
+ NULL);
+ if (pedid != NULL)
+ break;
+ }
+ of_node_put(dp);
+ break;
+ }
+ }
+ }
+ if (pedid == NULL) {
for (i = 0; propnames[i] != NULL; ++i) {
pedid = (unsigned char *)
- get_property(dp, propnames[i], NULL);
- if (pedid != NULL) {
- *out_edid = pedid;
- return 0;
- }
+ get_property(parent, propnames[i], NULL);
+ if (pedid != NULL)
+ break;
}
}
- return 1;
+ if (pedid) {
+ *out_edid = kmalloc(EDID_LENGTH, GFP_KERNEL);
+ if (*out_edid == NULL)
+ return -1;
+ memcpy(*out_edid, pedid, EDID_LENGTH);
+ printk(KERN_DEBUG "nvidiafb: Found OF EDID for head %d\n", conn);
+ return 0;
+ }
+ return -1;
}
diff --git a/drivers/video/nvidia/nv_proto.h b/drivers/video/nvidia/nv_proto.h
index cac44fc7f587..f60b1f432270 100644
--- a/drivers/video/nvidia/nv_proto.h
+++ b/drivers/video/nvidia/nv_proto.h
@@ -31,7 +31,7 @@ int NVShowHideCursor(struct nvidia_par *par, int);
void NVLockUnlock(struct nvidia_par *par, int);
/* in nvidia-i2c.c */
-#if defined(CONFIG_FB_NVIDIA_I2C) || defined (CONFIG_PPC_OF)
+#ifdef CONFIG_FB_NVIDIA_I2C
void nvidia_create_i2c_busses(struct nvidia_par *par);
void nvidia_delete_i2c_busses(struct nvidia_par *par);
int nvidia_probe_i2c_connector(struct fb_info *info, int conn,
@@ -39,10 +39,18 @@ int nvidia_probe_i2c_connector(struct fb_info *info, int conn,
#else
#define nvidia_create_i2c_busses(...)
#define nvidia_delete_i2c_busses(...)
-#define nvidia_probe_i2c_connector(p, c, edid) \
-do { \
- *(edid) = NULL; \
-} while(0)
+#define nvidia_probe_i2c_connector(p, c, edid) (-1)
+#endif
+
+#ifdef CONFIG_FB_OF
+int nvidia_probe_of_connector(struct fb_info *info, int conn,
+ u8 ** out_edid);
+#else
+static inline int nvidia_probe_of_connector(struct fb_info *info, int conn,
+ u8 ** out_edid)
+{
+ return -1;
+}
#endif
/* in nv_accel.c */
diff --git a/drivers/video/nvidia/nv_setup.c b/drivers/video/nvidia/nv_setup.c
index 11c84178f420..1f06a9f1bd0f 100644
--- a/drivers/video/nvidia/nv_setup.c
+++ b/drivers/video/nvidia/nv_setup.c
@@ -190,9 +190,9 @@ static int NVIsConnected(struct nvidia_par *par, int output)
present = (NV_RD32(PRAMDAC, 0x0608) & (1 << 28)) ? 1 : 0;
if (present)
- printk("nvidiafb: CRTC%i found\n", output);
+ printk("nvidiafb: CRTC%i analog found\n", output);
else
- printk("nvidiafb: CRTC%i not found\n", output);
+ printk("nvidiafb: CRTC%i analog not found\n", output);
NV_WR32(par->PRAMDAC0, 0x0608, NV_RD32(par->PRAMDAC0, 0x0608) &
0x0000EFFF);
@@ -305,6 +305,9 @@ void NVCommonSetup(struct fb_info *info)
int FlatPanel = -1; /* really means the CRTC is slaved */
int Television = 0;
+ memset(&monitorA, 0, sizeof(struct fb_monspecs));
+ memset(&monitorB, 0, sizeof(struct fb_monspecs));
+
par->PRAMIN = par->REGS + (0x00710000 / 4);
par->PCRTC0 = par->REGS + (0x00600000 / 4);
par->PRAMDAC0 = par->REGS + (0x00680000 / 4);
@@ -401,7 +404,8 @@ void NVCommonSetup(struct fb_info *info)
nvidia_create_i2c_busses(par);
if (!par->twoHeads) {
par->CRTCnumber = 0;
- nvidia_probe_i2c_connector(info, 1, &edidA);
+ if (nvidia_probe_i2c_connector(info, 1, &edidA))
+ nvidia_probe_of_connector(info, 1, &edidA);
if (edidA && !fb_parse_edid(edidA, &var)) {
printk("nvidiafb: EDID found from BUS1\n");
monA = &monitorA;
@@ -488,14 +492,16 @@ void NVCommonSetup(struct fb_info *info)
oldhead = NV_RD32(par->PCRTC0, 0x00000860);
NV_WR32(par->PCRTC0, 0x00000860, oldhead | 0x00000010);
- nvidia_probe_i2c_connector(info, 1, &edidA);
+ if (nvidia_probe_i2c_connector(info, 1, &edidA))
+ nvidia_probe_of_connector(info, 1, &edidA);
if (edidA && !fb_parse_edid(edidA, &var)) {
printk("nvidiafb: EDID found from BUS1\n");
monA = &monitorA;
fb_edid_to_monspecs(edidA, monA);
}
- nvidia_probe_i2c_connector(info, 2, &edidB);
+ if (nvidia_probe_i2c_connector(info, 2, &edidB))
+ nvidia_probe_of_connector(info, 2, &edidB);
if (edidB && !fb_parse_edid(edidB, &var)) {
printk("nvidiafb: EDID found from BUS2\n");
monB = &monitorB;
diff --git a/drivers/video/nvidia/nvidia.c b/drivers/video/nvidia/nvidia.c
index a7f020ada630..0b40a2a721c1 100644
--- a/drivers/video/nvidia/nvidia.c
+++ b/drivers/video/nvidia/nvidia.c
@@ -384,6 +384,14 @@ static struct pci_device_id nvidiafb_pci_tbl[] = {
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
{PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_6800B_GT,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_7800_GT,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_7800_GTX,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_GO_7800,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_GO_7800_GTX,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
{PCI_VENDOR_ID_NVIDIA, 0x021d,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
{PCI_VENDOR_ID_NVIDIA, 0x021e,
@@ -403,6 +411,7 @@ MODULE_DEVICE_TABLE(pci, nvidiafb_pci_tbl);
/* command line data, set in nvidiafb_setup() */
static int flatpanel __devinitdata = -1; /* Autodetect later */
+static int fpdither __devinitdata = -1;
static int forceCRTC __devinitdata = -1;
static int hwcur __devinitdata = 0;
static int noaccel __devinitdata = 0;
@@ -619,41 +628,85 @@ static void nvidia_save_vga(struct nvidia_par *par,
NVTRACE_LEAVE();
}
+#undef DUMP_REG
+
static void nvidia_write_regs(struct nvidia_par *par)
{
struct _riva_hw_state *state = &par->ModeReg;
int i;
NVTRACE_ENTER();
- NVWriteCrtc(par, 0x11, 0x00);
-
- NVLockUnlock(par, 0);
NVLoadStateExt(par, state);
NVWriteMiscOut(par, state->misc_output);
+ for (i = 1; i < NUM_SEQ_REGS; i++) {
+#ifdef DUMP_REG
+ printk(" SEQ[%02x] = %08x\n", i, state->seq[i]);
+#endif
+ NVWriteSeq(par, i, state->seq[i]);
+ }
+
+ /* Ensure CRTC registers 0-7 are unlocked by clearing bit 7 of CRTC[17] */
+ NVWriteCrtc(par, 0x11, state->crtc[0x11] & ~0x80);
+
for (i = 0; i < NUM_CRT_REGS; i++) {
switch (i) {
case 0x19:
case 0x20 ... 0x40:
break;
default:
+#ifdef DUMP_REG
+ printk("CRTC[%02x] = %08x\n", i, state->crtc[i]);
+#endif
NVWriteCrtc(par, i, state->crtc[i]);
}
}
- for (i = 0; i < NUM_ATC_REGS; i++)
- NVWriteAttr(par, i, state->attr[i]);
-
- for (i = 0; i < NUM_GRC_REGS; i++)
+ for (i = 0; i < NUM_GRC_REGS; i++) {
+#ifdef DUMP_REG
+ printk(" GRA[%02x] = %08x\n", i, state->gra[i]);
+#endif
NVWriteGr(par, i, state->gra[i]);
+ }
+
+ for (i = 0; i < NUM_ATC_REGS; i++) {
+#ifdef DUMP_REG
+ printk("ATTR[%02x] = %08x\n", i, state->attr[i]);
+#endif
+ NVWriteAttr(par, i, state->attr[i]);
+ }
- for (i = 0; i < NUM_SEQ_REGS; i++)
- NVWriteSeq(par, i, state->seq[i]);
NVTRACE_LEAVE();
}
+static void nvidia_vga_protect(struct nvidia_par *par, int on)
+{
+ unsigned char tmp;
+
+ if (on) {
+ /*
+ * Turn off screen and disable sequencer.
+ */
+ tmp = NVReadSeq(par, 0x01);
+
+ NVWriteSeq(par, 0x00, 0x01); /* Synchronous Reset */
+ NVWriteSeq(par, 0x01, tmp | 0x20); /* disable the display */
+ } else {
+ /*
+ * Reenable sequencer, then turn on screen.
+ */
+
+ tmp = NVReadSeq(par, 0x01);
+
+ NVWriteSeq(par, 0x01, tmp & ~0x20); /* reenable display */
+ NVWriteSeq(par, 0x00, 0x03); /* End Reset */
+ }
+}
+
+
+
static int nvidia_calc_regs(struct fb_info *info)
{
struct nvidia_par *par = info->par;
@@ -860,7 +913,7 @@ static void nvidia_init_vga(struct fb_info *info)
for (i = 0; i < 0x10; i++)
state->attr[i] = i;
state->attr[0x10] = 0x41;
- state->attr[0x11] = 0x01;
+ state->attr[0x11] = 0xff;
state->attr[0x12] = 0x0f;
state->attr[0x13] = 0x00;
state->attr[0x14] = 0x00;
@@ -974,16 +1027,24 @@ static int nvidiafb_set_par(struct fb_info *info)
NVTRACE_ENTER();
NVLockUnlock(par, 1);
- if (!par->FlatPanel || (info->var.bits_per_pixel != 24) ||
- !par->twoHeads)
+ if (!par->FlatPanel || !par->twoHeads)
par->FPDither = 0;
+ if (par->FPDither < 0) {
+ if ((par->Chipset & 0x0ff0) == 0x0110)
+ par->FPDither = !!(NV_RD32(par->PRAMDAC, 0x0528)
+ & 0x00010000);
+ else
+ par->FPDither = !!(NV_RD32(par->PRAMDAC, 0x083C) & 1);
+ printk(KERN_INFO PFX "Flat panel dithering %s\n",
+ par->FPDither ? "enabled" : "disabled");
+ }
+
info->fix.visual = (info->var.bits_per_pixel == 8) ?
FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR;
nvidia_init_vga(info);
nvidia_calc_regs(info);
- nvidia_write_regs(par);
NVLockUnlock(par, 0);
if (par->twoHeads) {
@@ -992,7 +1053,22 @@ static int nvidiafb_set_par(struct fb_info *info)
NVLockUnlock(par, 0);
}
- NVWriteCrtc(par, 0x11, 0x00);
+ nvidia_vga_protect(par, 1);
+
+ nvidia_write_regs(par);
+
+#if defined (__BIG_ENDIAN)
+ /* turn on LFB swapping */
+ {
+ unsigned char tmp;
+
+ VGA_WR08(par->PCIO, 0x3d4, 0x46);
+ tmp = VGA_RD08(par->PCIO, 0x3d5);
+ tmp |= (1 << 7);
+ VGA_WR08(par->PCIO, 0x3d5, tmp);
+ }
+#endif
+
info->fix.line_length = (info->var.xres_virtual *
info->var.bits_per_pixel) >> 3;
if (info->var.accel_flags) {
@@ -1014,7 +1090,7 @@ static int nvidiafb_set_par(struct fb_info *info)
par->cursor_reset = 1;
- NVWriteCrtc(par, 0x11, 0xff);
+ nvidia_vga_protect(par, 0);
NVTRACE_LEAVE();
return 0;
@@ -1307,22 +1383,10 @@ static int __devinit nvidia_set_fbinfo(struct fb_info *info)
fb_var_to_videomode(&modedb, &nvidiafb_default_var);
if (specs->modedb != NULL) {
- /* get preferred timing */
- if (specs->misc & FB_MISC_1ST_DETAIL) {
- int i;
-
- for (i = 0; i < specs->modedb_len; i++) {
- if (specs->modedb[i].flag & FB_MODE_IS_FIRST) {
- modedb = specs->modedb[i];
- break;
- }
- }
- } else {
- /* otherwise, get first mode in database */
- modedb = specs->modedb[0];
- }
+ struct fb_videomode *modedb;
- fb_videomode_to_var(&nvidiafb_default_var, &modedb);
+ modedb = fb_find_best_display(specs, &info->modelist);
+ fb_videomode_to_var(&nvidiafb_default_var, modedb);
nvidiafb_default_var.bits_per_pixel = 8;
} else if (par->fpWidth && par->fpHeight) {
char buf[16];
@@ -1357,7 +1421,7 @@ static int __devinit nvidia_set_fbinfo(struct fb_info *info)
info->pixmap.flags = FB_PIXMAP_SYSTEM;
if (!hwcur)
- info->fbops->fb_cursor = soft_cursor;
+ info->fbops->fb_cursor = NULL;
info->var.accel_flags = (!noaccel);
@@ -1482,9 +1546,9 @@ static int __devinit nvidiafb_probe(struct pci_dev *pd,
sprintf(nvidiafb_fix.id, "NV%x", (pd->device & 0x0ff0) >> 4);
par->FlatPanel = flatpanel;
-
if (flatpanel == 1)
printk(KERN_INFO PFX "flatpanel support enabled\n");
+ par->FPDither = fpdither;
par->CRTCnumber = forceCRTC;
par->FpScale = (!noscale);
@@ -1663,6 +1727,8 @@ static int __devinit nvidiafb_setup(char *options)
} else if (!strncmp(this_opt, "nomtrr", 6)) {
nomtrr = 1;
#endif
+ } else if (!strncmp(this_opt, "fpdither:", 9)) {
+ fpdither = simple_strtol(this_opt+9, NULL, 0);
} else
mode_option = this_opt;
}
@@ -1709,7 +1775,11 @@ module_exit(nvidiafb_exit);
module_param(flatpanel, int, 0);
MODULE_PARM_DESC(flatpanel,
"Enables experimental flat panel support for some chipsets. "
- "(0 or 1=enabled) (default=0)");
+ "(0=disabled, 1=enabled, -1=autodetect) (default=-1)");
+module_param(fpdither, int, 0);
+MODULE_PARM_DESC(fpdither,
+ "Enables dithering of flat panel for 6 bits panels. "
+ "(0=disabled, 1=enabled, -1=autodetect) (default=-1)");
module_param(hwcur, int, 0);
MODULE_PARM_DESC(hwcur,
"Enables hardware cursor implementation. (0 or 1=enabled) "
diff --git a/drivers/video/offb.c b/drivers/video/offb.c
index 611922c0b22f..2c856838694e 100644
--- a/drivers/video/offb.c
+++ b/drivers/video/offb.c
@@ -85,7 +85,6 @@ static struct fb_ops offb_ops = {
.fb_fillrect = cfb_fillrect,
.fb_copyarea = cfb_copyarea,
.fb_imageblit = cfb_imageblit,
- .fb_cursor = soft_cursor,
};
/*
diff --git a/drivers/video/p9100.c b/drivers/video/p9100.c
index b76a5a9a125b..9aaf65fb623a 100644
--- a/drivers/video/p9100.c
+++ b/drivers/video/p9100.c
@@ -48,7 +48,6 @@ static struct fb_ops p9100_ops = {
.fb_imageblit = cfb_imageblit,
.fb_mmap = p9100_mmap,
.fb_ioctl = p9100_ioctl,
- .fb_cursor = soft_cursor,
};
/* P9100 control registers */
diff --git a/drivers/video/platinumfb.c b/drivers/video/platinumfb.c
index b00887e9851c..ca4082ae5a18 100644
--- a/drivers/video/platinumfb.c
+++ b/drivers/video/platinumfb.c
@@ -109,7 +109,6 @@ static struct fb_ops platinumfb_ops = {
.fb_fillrect = cfb_fillrect,
.fb_copyarea = cfb_copyarea,
.fb_imageblit = cfb_imageblit,
- .fb_cursor = soft_cursor,
};
/*
diff --git a/drivers/video/pm2fb.c b/drivers/video/pm2fb.c
index 42c17efa9fb0..0277ce031e5e 100644
--- a/drivers/video/pm2fb.c
+++ b/drivers/video/pm2fb.c
@@ -1034,7 +1034,6 @@ static struct fb_ops pm2fb_ops = {
.fb_fillrect = cfb_fillrect,
.fb_copyarea = cfb_copyarea,
.fb_imageblit = cfb_imageblit,
- .fb_cursor = soft_cursor,
};
/*
@@ -1121,6 +1120,22 @@ static int __devinit pm2fb_probe(struct pci_dev *pdev,
default_par->mem_control, default_par->boot_address,
default_par->mem_config);
+ if(default_par->mem_control == 0 &&
+ default_par->boot_address == 0x31 &&
+ default_par->mem_config == 0x259fffff &&
+ pdev->subsystem_vendor == 0x1048 &&
+ pdev->subsystem_device == 0x0a31) {
+ DPRINTK("subsystem_vendor: %04x, subsystem_device: %04x\n",
+ pdev->subsystem_vendor, pdev->subsystem_device);
+ DPRINTK("We have not been initialized by VGA BIOS "
+ "and are running on an Elsa Winner 2000 Office\n");
+ DPRINTK("Initializing card timings manually...\n");
+ default_par->mem_control=0;
+ default_par->boot_address=0x20;
+ default_par->mem_config=0xe6002021;
+ default_par->memclock=100000;
+ }
+
/* Now work out how big lfb is going to be. */
switch(default_par->mem_config & PM2F_MEM_CONFIG_RAM_MASK) {
case PM2F_MEM_BANKS_1:
diff --git a/drivers/video/pmag-ba-fb.c b/drivers/video/pmag-ba-fb.c
index c98f1c8d7dc2..f3927b6cda9d 100644
--- a/drivers/video/pmag-ba-fb.c
+++ b/drivers/video/pmag-ba-fb.c
@@ -128,7 +128,6 @@ static struct fb_ops pmagbafb_ops = {
.fb_fillrect = cfb_fillrect,
.fb_copyarea = cfb_copyarea,
.fb_imageblit = cfb_imageblit,
- .fb_cursor = soft_cursor,
};
diff --git a/drivers/video/pmagb-b-fb.c b/drivers/video/pmagb-b-fb.c
index a483b13e117b..25148de5fe67 100644
--- a/drivers/video/pmagb-b-fb.c
+++ b/drivers/video/pmagb-b-fb.c
@@ -132,7 +132,6 @@ static struct fb_ops pmagbbfb_ops = {
.fb_fillrect = cfb_fillrect,
.fb_copyarea = cfb_copyarea,
.fb_imageblit = cfb_imageblit,
- .fb_cursor = soft_cursor,
};
diff --git a/drivers/video/pvr2fb.c b/drivers/video/pvr2fb.c
index 31c547fd383b..ec4bacf9dd2e 100644
--- a/drivers/video/pvr2fb.c
+++ b/drivers/video/pvr2fb.c
@@ -230,7 +230,6 @@ static struct fb_ops pvr2fb_ops = {
.fb_fillrect = cfb_fillrect,
.fb_copyarea = cfb_copyarea,
.fb_imageblit = cfb_imageblit,
- .fb_cursor = soft_cursor,
};
static struct fb_videomode pvr2_modedb[] __initdata = {
diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c
index 194eed0a238c..f305a5b77b23 100644
--- a/drivers/video/pxafb.c
+++ b/drivers/video/pxafb.c
@@ -36,7 +36,7 @@
#include <linux/init.h>
#include <linux/ioport.h>
#include <linux/cpufreq.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
#include <asm/hardware.h>
@@ -418,7 +418,6 @@ static struct fb_ops pxafb_ops = {
.fb_copyarea = cfb_copyarea,
.fb_imageblit = cfb_imageblit,
.fb_blank = pxafb_blank,
- .fb_cursor = soft_cursor,
.fb_mmap = pxafb_mmap,
};
@@ -981,21 +980,19 @@ pxafb_freq_policy(struct notifier_block *nb, unsigned long val, void *data)
* Power management hooks. Note that we won't be called from IRQ context,
* unlike the blank functions above, so we may sleep.
*/
-static int pxafb_suspend(struct device *dev, pm_message_t state, u32 level)
+static int pxafb_suspend(struct device *dev, pm_message_t state)
{
struct pxafb_info *fbi = dev_get_drvdata(dev);
- if (level == SUSPEND_DISABLE || level == SUSPEND_POWER_DOWN)
- set_ctrlr_state(fbi, C_DISABLE_PM);
+ set_ctrlr_state(fbi, C_DISABLE_PM);
return 0;
}
-static int pxafb_resume(struct device *dev, u32 level)
+static int pxafb_resume(struct device *dev)
{
struct pxafb_info *fbi = dev_get_drvdata(dev);
- if (level == RESUME_ENABLE)
- set_ctrlr_state(fbi, C_ENABLE_PM);
+ set_ctrlr_state(fbi, C_ENABLE_PM);
return 0;
}
#else
diff --git a/drivers/video/q40fb.c b/drivers/video/q40fb.c
index 162012bb9264..bfc41f2c902a 100644
--- a/drivers/video/q40fb.c
+++ b/drivers/video/q40fb.c
@@ -18,6 +18,7 @@
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
+#include <linux/platform_device.h>
#include <asm/uaccess.h>
#include <asm/setup.h>
@@ -83,7 +84,6 @@ static struct fb_ops q40fb_ops = {
.fb_fillrect = cfb_fillrect,
.fb_copyarea = cfb_copyarea,
.fb_imageblit = cfb_imageblit,
- .fb_cursor = soft_cursor,
};
static int __init q40fb_probe(struct device *device)
diff --git a/drivers/video/radeonfb.c b/drivers/video/radeonfb.c
index a78b9bd8f897..600318f708f2 100644
--- a/drivers/video/radeonfb.c
+++ b/drivers/video/radeonfb.c
@@ -2218,7 +2218,6 @@ static struct fb_ops radeonfb_ops = {
.fb_copyarea = cfb_copyarea,
.fb_imageblit = cfb_imageblit,
#endif
- .fb_cursor = soft_cursor,
};
diff --git a/drivers/video/s1d13xxxfb.c b/drivers/video/s1d13xxxfb.c
index fa98d91c42eb..3edbd14c5c46 100644
--- a/drivers/video/s1d13xxxfb.c
+++ b/drivers/video/s1d13xxxfb.c
@@ -30,7 +30,7 @@
#include <linux/config.h>
#include <linux/module.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <linux/delay.h>
#include <linux/types.h>
@@ -388,7 +388,6 @@ static struct fb_ops s1d13xxxfb_fbops = {
.fb_fillrect = cfb_fillrect,
.fb_copyarea = cfb_copyarea,
.fb_imageblit = cfb_imageblit,
- .fb_cursor = soft_cursor
};
static int s1d13xxxfb_width_tab[2][4] __devinitdata = {
@@ -655,7 +654,7 @@ bail:
}
#ifdef CONFIG_PM
-static int s1d13xxxfb_suspend(struct device *dev, pm_message_t state, u32 level)
+static int s1d13xxxfb_suspend(struct device *dev, pm_message_t state)
{
struct fb_info *info = dev_get_drvdata(dev);
struct s1d13xxxfb_par *s1dfb = info->par;
@@ -702,15 +701,12 @@ static int s1d13xxxfb_suspend(struct device *dev, pm_message_t state, u32 level)
return 0;
}
-static int s1d13xxxfb_resume(struct device *dev, u32 level)
+static int s1d13xxxfb_resume(struct device *dev)
{
struct fb_info *info = dev_get_drvdata(dev);
struct s1d13xxxfb_par *s1dfb = info->par;
struct s1d13xxxfb_pdata *pdata = NULL;
- if (level != RESUME_ENABLE)
- return 0;
-
/* awaken the chip */
s1d13xxxfb_writereg(s1dfb, S1DREG_PS_CNF, 0x10);
diff --git a/drivers/video/s3c2410fb.c b/drivers/video/s3c2410fb.c
index 5ab79afb53b7..855a6778b9eb 100644
--- a/drivers/video/s3c2410fb.c
+++ b/drivers/video/s3c2410fb.c
@@ -86,6 +86,7 @@
#include <linux/interrupt.h>
#include <linux/workqueue.h>
#include <linux/wait.h>
+#include <linux/platform_device.h>
#include <asm/io.h>
#include <asm/uaccess.h>
@@ -494,7 +495,6 @@ static struct fb_ops s3c2410fb_ops = {
.fb_fillrect = cfb_fillrect,
.fb_copyarea = cfb_copyarea,
.fb_imageblit = cfb_imageblit,
- .fb_cursor = soft_cursor,
};
@@ -847,37 +847,32 @@ static int s3c2410fb_remove(struct device *dev)
/* suspend and resume support for the lcd controller */
-static int s3c2410fb_suspend(struct device *dev, pm_message_t state, u32 level)
+static int s3c2410fb_suspend(struct device *dev, pm_message_t state)
{
struct fb_info *fbinfo = dev_get_drvdata(dev);
struct s3c2410fb_info *info = fbinfo->par;
- if (level == SUSPEND_DISABLE || level == SUSPEND_POWER_DOWN) {
- s3c2410fb_stop_lcd();
+ s3c2410fb_stop_lcd();
- /* sleep before disabling the clock, we need to ensure
- * the LCD DMA engine is not going to get back on the bus
- * before the clock goes off again (bjd) */
+ /* sleep before disabling the clock, we need to ensure
+ * the LCD DMA engine is not going to get back on the bus
+ * before the clock goes off again (bjd) */
- msleep(1);
- clk_disable(info->clk);
- }
+ msleep(1);
+ clk_disable(info->clk);
return 0;
}
-static int s3c2410fb_resume(struct device *dev, u32 level)
+static int s3c2410fb_resume(struct device *dev)
{
struct fb_info *fbinfo = dev_get_drvdata(dev);
struct s3c2410fb_info *info = fbinfo->par;
- if (level == RESUME_ENABLE) {
- clk_enable(info->clk);
- msleep(1);
-
- s3c2410fb_init_registers(info);
+ clk_enable(info->clk);
+ msleep(1);
- }
+ s3c2410fb_init_registers(info);
return 0;
}
@@ -889,6 +884,7 @@ static int s3c2410fb_resume(struct device *dev, u32 level)
static struct device_driver s3c2410fb_driver = {
.name = "s3c2410-lcd",
+ .owner = THIS_MODULE,
.bus = &platform_bus_type,
.probe = s3c2410fb_probe,
.suspend = s3c2410fb_suspend,
diff --git a/drivers/video/sa1100fb.c b/drivers/video/sa1100fb.c
index 8000890e4271..a5184575cfae 100644
--- a/drivers/video/sa1100fb.c
+++ b/drivers/video/sa1100fb.c
@@ -173,7 +173,7 @@
#include <linux/init.h>
#include <linux/ioport.h>
#include <linux/cpufreq.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
#include <asm/hardware.h>
@@ -853,7 +853,6 @@ static struct fb_ops sa1100fb_ops = {
.fb_copyarea = cfb_copyarea,
.fb_imageblit = cfb_imageblit,
.fb_blank = sa1100fb_blank,
- .fb_cursor = soft_cursor,
.fb_mmap = sa1100fb_mmap,
};
@@ -1309,21 +1308,19 @@ sa1100fb_freq_policy(struct notifier_block *nb, unsigned long val,
* Power management hooks. Note that we won't be called from IRQ context,
* unlike the blank functions above, so we may sleep.
*/
-static int sa1100fb_suspend(struct device *dev, pm_message_t state, u32 level)
+static int sa1100fb_suspend(struct device *dev, pm_message_t state)
{
struct sa1100fb_info *fbi = dev_get_drvdata(dev);
- if (level == SUSPEND_DISABLE || level == SUSPEND_POWER_DOWN)
- set_ctrlr_state(fbi, C_DISABLE_PM);
+ set_ctrlr_state(fbi, C_DISABLE_PM);
return 0;
}
-static int sa1100fb_resume(struct device *dev, u32 level)
+static int sa1100fb_resume(struct device *dev)
{
struct sa1100fb_info *fbi = dev_get_drvdata(dev);
- if (level == RESUME_ENABLE)
- set_ctrlr_state(fbi, C_ENABLE_PM);
+ set_ctrlr_state(fbi, C_ENABLE_PM);
return 0;
}
#else
diff --git a/drivers/video/savage/savagefb.h b/drivers/video/savage/savagefb.h
index ea17f7e0482c..58cfdfb41833 100644
--- a/drivers/video/savage/savagefb.h
+++ b/drivers/video/savage/savagefb.h
@@ -169,6 +169,7 @@ struct savagefb_par {
struct savagefb_i2c_chan chan;
unsigned char *edid;
u32 pseudo_palette[16];
+ int paletteEnabled;
int pm_state;
int display_type;
int dvi;
@@ -244,105 +245,150 @@ struct savagefb_par {
/* IO functions */
+static inline u8 savage_in8(u32 addr, struct savagefb_par *par)
+{
+ return readb(par->mmio.vbase + addr);
+}
+
+static inline u16 savage_in16(u32 addr, struct savagefb_par *par)
+{
+ return readw(par->mmio.vbase + addr);
+}
+
+static inline u32 savage_in32(u32 addr, struct savagefb_par *par)
+{
+ return readl(par->mmio.vbase + addr);
+}
+
+static inline void savage_out8(u32 addr, u8 val, struct savagefb_par *par)
+{
+ writeb(val, par->mmio.vbase + addr);
+}
+
+static inline void savage_out16(u32 addr, u16 val, struct savagefb_par *par)
+{
+ writew(val, par->mmio.vbase + addr);
+}
+
+static inline void savage_out32(u32 addr, u32 val, struct savagefb_par *par)
+{
+ writel(val, par->mmio.vbase + addr);
+}
+
+static inline u8 vga_in8(int addr, struct savagefb_par *par)
+{
+ return savage_in8(0x8000 + addr, par);
+}
+
+static inline u16 vga_in16(int addr, struct savagefb_par *par)
+{
+ return savage_in16(0x8000 + addr, par);
+}
+
+static inline u8 vga_in32(int addr, struct savagefb_par *par)
+{
+ return savage_in32(0x8000 + addr, par);
+}
+
+static inline void vga_out8(int addr, u8 val, struct savagefb_par *par)
+{
+ savage_out8(0x8000 + addr, val, par);
+}
+
+static inline void vga_out16(int addr, u16 val, struct savagefb_par *par)
+{
+ savage_out16(0x8000 + addr, val, par);
+}
+
+static inline void vga_out32(int addr, u32 val, struct savagefb_par *par)
+{
+ savage_out32(0x8000 + addr, val, par);
+}
-#define vga_in8(addr) (inb (addr))
-#define vga_in16(addr) (inw (addr))
-#define vga_in32(addr) (inl (addr))
+static inline u8 VGArCR (u8 index, struct savagefb_par *par)
+{
+ vga_out8(0x3d4, index, par);
+ return vga_in8(0x3d5, par);
+}
+
+static inline u8 VGArGR (u8 index, struct savagefb_par *par)
+{
+ vga_out8(0x3ce, index, par);
+ return vga_in8(0x3cf, par);
+}
+
+static inline u8 VGArSEQ (u8 index, struct savagefb_par *par)
+{
+ vga_out8(0x3c4, index, par);
+ return vga_in8(0x3c5, par);
+}
-#define vga_out8(addr,val) (outb ((val), (addr)))
-#define vga_out16(addr,val) (outw ((val), (addr)))
-#define vga_out32(addr,val) (outl ((val), (addr)))
+static inline void VGAwCR(u8 index, u8 val, struct savagefb_par *par)
+{
+ vga_out8(0x3d4, index, par);
+ vga_out8(0x3d5, val, par);
+}
-#define savage_in16(addr) readw(par->mmio.vbase + (addr))
-#define savage_in32(addr) readl(par->mmio.vbase + (addr))
+static inline void VGAwGR(u8 index, u8 val, struct savagefb_par *par)
+{
+ vga_out8(0x3ce, index, par);
+ vga_out8(0x3cf, val, par);
+}
-#define savage_out16(addr,val) writew((val), par->mmio.vbase + (addr))
-#define savage_out32(addr,val) writel((val), par->mmio.vbase + (addr))
+static inline void VGAwSEQ(u8 index, u8 val, struct savagefb_par *par)
+{
+ vga_out8(0x3c4, index, par);
+ vga_out8 (0x3c5, val, par);
+}
-static inline u8 VGArCR (u8 index)
+static inline void VGAenablePalette(struct savagefb_par *par)
{
- outb (index, 0x3d4);
- return inb (0x3d5);
+ u8 tmp;
+
+ tmp = vga_in8(0x3da, par);
+ vga_out8(0x3c0, 0x00, par);
+ par->paletteEnabled = 1;
}
-static inline u8 VGArGR (u8 index)
+static inline void VGAdisablePalette(struct savagefb_par *par)
{
- outb (index, 0x3ce);
- return inb (0x3cf);
+ u8 tmp;
+
+ tmp = vga_in8(0x3da, par);
+ vga_out8(0x3c0, 0x20, par);
+ par->paletteEnabled = 0;
}
-static inline u8 VGArSEQ (u8 index)
+static inline void VGAwATTR(u8 index, u8 value, struct savagefb_par *par)
{
- outb (index, 0x3c4);
- return inb (0x3c5);
+ u8 tmp;
+
+ if (par->paletteEnabled)
+ index &= ~0x20;
+ else
+ index |= 0x20;
+
+ tmp = vga_in8(0x3da, par);
+ vga_out8(0x3c0, index, par);
+ vga_out8 (0x3c0, value, par);
}
-#define VGAwCR(index, val) \
-do { \
- vga_out8 (0x3d4, index); \
- vga_out8 (0x3d5, val); \
-} while (0)
-
-#define VGAwGR(index, val) \
-do { \
- vga_out8 (0x3ce, index); \
- vga_out8 (0x3cf, val); \
-} while (0)
-
-#define VGAwSEQ(index, val) \
-do { \
- vga_out8 (0x3c4, index); \
- vga_out8 (0x3c5, val); \
-} while (0)
-
-#define VGAenablePalette() \
-do { \
- u8 tmp; \
- \
- tmp = vga_in8 (0x3da); \
- vga_out8 (0x3c0, 0x00); \
- paletteEnabled = 1; \
-} while (0)
-
-#define VGAdisablePalette() \
-do { \
- u8 tmp; \
- \
- tmp = vga_in8 (0x3da); \
- vga_out8 (0x3c0, 0x20); \
- paletteEnabled = 0; \
-} while (0)
-
-#define VGAwATTR(index, value) \
-do { \
- u8 tmp; \
- \
- if (paletteEnabled) \
- index &= ~0x20; \
- else \
- index |= 0x20; \
- \
- tmp = vga_in8 (0x3da); \
- vga_out8 (0x3c0, index); \
- vga_out8 (0x3c0, value); \
-} while (0)
-
-#define VGAwMISC(value) \
-do { \
- vga_out8 (0x3c2, value); \
-} while (0)
+static inline void VGAwMISC(u8 value, struct savagefb_par *par)
+{
+ vga_out8(0x3c2, value, par);
+}
#ifndef CONFIG_FB_SAVAGE_ACCEL
#define savagefb_set_clip(x)
#endif
-#define VerticalRetraceWait() \
-{ \
- vga_out8 (0x3d4, 0x17); \
- if (vga_in8 (0x3d5) & 0x80) { \
- while ((vga_in8(0x3da) & 0x08) == 0x08) ; \
- while ((vga_in8(0x3da) & 0x08) == 0x00) ; \
- } \
+static inline void VerticalRetraceWait(struct savagefb_par *par)
+{
+ vga_out8(0x3d4, 0x17, par);
+ if (vga_in8(0x3d5, par) & 0x80) {
+ while ((vga_in8(0x3da, par) & 0x08) == 0x08);
+ while ((vga_in8(0x3da, par) & 0x08) == 0x00);
+ }
}
extern int savagefb_probe_i2c_connector(struct fb_info *info,
diff --git a/drivers/video/savage/savagefb_driver.c b/drivers/video/savage/savagefb_driver.c
index 7c285455c924..09e2f2841901 100644
--- a/drivers/video/savage/savagefb_driver.c
+++ b/drivers/video/savage/savagefb_driver.c
@@ -74,7 +74,6 @@
static char *mode_option __initdata = NULL;
-static int paletteEnabled = 0;
#ifdef MODULE
@@ -90,9 +89,9 @@ MODULE_DESCRIPTION("FBDev driver for S3 Savage PCI/AGP Chips");
static void vgaHWSeqReset (struct savagefb_par *par, int start)
{
if (start)
- VGAwSEQ (0x00, 0x01); /* Synchronous Reset */
+ VGAwSEQ (0x00, 0x01, par); /* Synchronous Reset */
else
- VGAwSEQ (0x00, 0x03); /* End Reset */
+ VGAwSEQ (0x00, 0x03, par); /* End Reset */
}
static void vgaHWProtect (struct savagefb_par *par, int on)
@@ -103,23 +102,23 @@ static void vgaHWProtect (struct savagefb_par *par, int on)
/*
* Turn off screen and disable sequencer.
*/
- tmp = VGArSEQ (0x01);
+ tmp = VGArSEQ (0x01, par);
vgaHWSeqReset (par, 1); /* start synchronous reset */
- VGAwSEQ (0x01, tmp | 0x20); /* disable the display */
+ VGAwSEQ (0x01, tmp | 0x20, par);/* disable the display */
- VGAenablePalette();
+ VGAenablePalette(par);
} else {
/*
* Reenable sequencer, then turn on screen.
*/
- tmp = VGArSEQ (0x01);
+ tmp = VGArSEQ (0x01, par);
- VGAwSEQ (0x01, tmp & ~0x20); /* reenable display */
+ VGAwSEQ (0x01, tmp & ~0x20, par);/* reenable display */
vgaHWSeqReset (par, 0); /* clear synchronous reset */
- VGAdisablePalette();
+ VGAdisablePalette(par);
}
}
@@ -127,27 +126,27 @@ static void vgaHWRestore (struct savagefb_par *par)
{
int i;
- VGAwMISC (par->MiscOutReg);
+ VGAwMISC (par->MiscOutReg, par);
for (i = 1; i < 5; i++)
- VGAwSEQ (i, par->Sequencer[i]);
+ VGAwSEQ (i, par->Sequencer[i], par);
/* Ensure CRTC registers 0-7 are unlocked by clearing bit 7 or
CRTC[17] */
- VGAwCR (17, par->CRTC[17] & ~0x80);
+ VGAwCR (17, par->CRTC[17] & ~0x80, par);
for (i = 0; i < 25; i++)
- VGAwCR (i, par->CRTC[i]);
+ VGAwCR (i, par->CRTC[i], par);
for (i = 0; i < 9; i++)
- VGAwGR (i, par->Graphics[i]);
+ VGAwGR (i, par->Graphics[i], par);
- VGAenablePalette();
+ VGAenablePalette(par);
for (i = 0; i < 21; i++)
- VGAwATTR (i, par->Attribute[i]);
+ VGAwATTR (i, par->Attribute[i], par);
- VGAdisablePalette();
+ VGAdisablePalette(par);
}
static void vgaHWInit (struct fb_var_screeninfo *var,
@@ -267,7 +266,7 @@ savage3D_waitfifo(struct savagefb_par *par, int space)
{
int slots = MAXFIFO - space;
- while ((savage_in32(0x48C00) & 0x0000ffff) > slots);
+ while ((savage_in32(0x48C00, par) & 0x0000ffff) > slots);
}
static void
@@ -275,7 +274,7 @@ savage4_waitfifo(struct savagefb_par *par, int space)
{
int slots = MAXFIFO - space;
- while ((savage_in32(0x48C60) & 0x001fffff) > slots);
+ while ((savage_in32(0x48C60, par) & 0x001fffff) > slots);
}
static void
@@ -283,26 +282,26 @@ savage2000_waitfifo(struct savagefb_par *par, int space)
{
int slots = MAXFIFO - space;
- while ((savage_in32(0x48C60) & 0x0000ffff) > slots);
+ while ((savage_in32(0x48C60, par) & 0x0000ffff) > slots);
}
/* Wait for idle accelerator */
static void
savage3D_waitidle(struct savagefb_par *par)
{
- while ((savage_in32(0x48C00) & 0x0008ffff) != 0x80000);
+ while ((savage_in32(0x48C00, par) & 0x0008ffff) != 0x80000);
}
static void
savage4_waitidle(struct savagefb_par *par)
{
- while ((savage_in32(0x48C60) & 0x00a00000) != 0x00a00000);
+ while ((savage_in32(0x48C60, par) & 0x00a00000) != 0x00a00000);
}
static void
savage2000_waitidle(struct savagefb_par *par)
{
- while ((savage_in32(0x48C60) & 0x009fffff));
+ while ((savage_in32(0x48C60, par) & 0x009fffff));
}
@@ -319,59 +318,64 @@ SavageSetup2DEngine (struct savagefb_par *par)
case S3_SAVAGE3D:
case S3_SAVAGE_MX:
/* Disable BCI */
- savage_out32(0x48C18, savage_in32(0x48C18) & 0x3FF0);
+ savage_out32(0x48C18, savage_in32(0x48C18, par) & 0x3FF0, par);
/* Setup BCI command overflow buffer */
- savage_out32(0x48C14, (par->cob_offset >> 11) | (par->cob_index << 29));
+ savage_out32(0x48C14,
+ (par->cob_offset >> 11) | (par->cob_index << 29),
+ par);
/* Program shadow status update. */
- savage_out32(0x48C10, 0x78207220);
- savage_out32(0x48C0C, 0);
+ savage_out32(0x48C10, 0x78207220, par);
+ savage_out32(0x48C0C, 0, par);
/* Enable BCI and command overflow buffer */
- savage_out32(0x48C18, savage_in32(0x48C18) | 0x0C);
+ savage_out32(0x48C18, savage_in32(0x48C18, par) | 0x0C, par);
break;
case S3_SAVAGE4:
case S3_PROSAVAGE:
case S3_SUPERSAVAGE:
/* Disable BCI */
- savage_out32(0x48C18, savage_in32(0x48C18) & 0x3FF0);
+ savage_out32(0x48C18, savage_in32(0x48C18, par) & 0x3FF0, par);
/* Program shadow status update */
- savage_out32(0x48C10, 0x00700040);
- savage_out32(0x48C0C, 0);
+ savage_out32(0x48C10, 0x00700040, par);
+ savage_out32(0x48C0C, 0, par);
/* Enable BCI without the COB */
- savage_out32(0x48C18, savage_in32(0x48C18) | 0x08);
+ savage_out32(0x48C18, savage_in32(0x48C18, par) | 0x08, par);
break;
case S3_SAVAGE2000:
/* Disable BCI */
- savage_out32(0x48C18, 0);
+ savage_out32(0x48C18, 0, par);
/* Setup BCI command overflow buffer */
- savage_out32(0x48C18, (par->cob_offset >> 7) | (par->cob_index));
+ savage_out32(0x48C18,
+ (par->cob_offset >> 7) | (par->cob_index),
+ par);
/* Disable shadow status update */
- savage_out32(0x48A30, 0);
+ savage_out32(0x48A30, 0, par);
/* Enable BCI and command overflow buffer */
- savage_out32(0x48C18, savage_in32(0x48C18) | 0x00280000 );
+ savage_out32(0x48C18, savage_in32(0x48C18, par) | 0x00280000,
+ par);
break;
default:
break;
}
/* Turn on 16-bit register access. */
- vga_out8(0x3d4, 0x31);
- vga_out8(0x3d5, 0x0c);
+ vga_out8(0x3d4, 0x31, par);
+ vga_out8(0x3d5, 0x0c, par);
/* Set stride to use GBD. */
- vga_out8 (0x3d4, 0x50);
- vga_out8 (0x3d5, vga_in8 (0x3d5 ) | 0xC1);
+ vga_out8 (0x3d4, 0x50, par);
+ vga_out8 (0x3d5, vga_in8(0x3d5, par) | 0xC1, par);
/* Enable 2D engine. */
- vga_out8 (0x3d4, 0x40 );
- vga_out8 (0x3d5, 0x01 );
+ vga_out8 (0x3d4, 0x40, par);
+ vga_out8 (0x3d5, 0x01, par);
- savage_out32 (MONO_PAT_0, ~0);
- savage_out32 (MONO_PAT_1, ~0);
+ savage_out32 (MONO_PAT_0, ~0, par);
+ savage_out32 (MONO_PAT_1, ~0, par);
/* Setup plane masks */
- savage_out32 (0x8128, ~0 ); /* enable all write planes */
- savage_out32 (0x812C, ~0 ); /* enable all read planes */
- savage_out16 (0x8134, 0x27 );
- savage_out16 (0x8136, 0x07 );
+ savage_out32 (0x8128, ~0, par); /* enable all write planes */
+ savage_out32 (0x812C, ~0, par); /* enable all read planes */
+ savage_out16 (0x8134, 0x27, par);
+ savage_out16 (0x8136, 0x07, par);
/* Now set the GBD */
par->bci_ptr = 0;
@@ -489,8 +493,8 @@ static void SavagePrintRegs(void)
for( i = 0; i < 0x70; i++ ) {
if( !(i % 16) )
printk(KERN_DEBUG "\nSR%xx ", i >> 4 );
- vga_out8( 0x3c4, i );
- printk(KERN_DEBUG " %02x", vga_in8(0x3c5) );
+ vga_out8( 0x3c4, i, par);
+ printk(KERN_DEBUG " %02x", vga_in8(0x3c5, par) );
}
printk(KERN_DEBUG "\n\nCR x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC "
@@ -499,8 +503,8 @@ static void SavagePrintRegs(void)
for( i = 0; i < 0xB7; i++ ) {
if( !(i % 16) )
printk(KERN_DEBUG "\nCR%xx ", i >> 4 );
- vga_out8( vgaCRIndex, i );
- printk(KERN_DEBUG " %02x", vga_in8(vgaCRReg) );
+ vga_out8( vgaCRIndex, i, par);
+ printk(KERN_DEBUG " %02x", vga_in8(vgaCRReg, par) );
}
printk(KERN_DEBUG "\n\n");
@@ -513,152 +517,152 @@ static void savage_get_default_par(struct savagefb_par *par)
{
unsigned char cr3a, cr53, cr66;
- vga_out16 (0x3d4, 0x4838);
- vga_out16 (0x3d4, 0xa039);
- vga_out16 (0x3c4, 0x0608);
-
- vga_out8 (0x3d4, 0x66);
- cr66 = vga_in8 (0x3d5);
- vga_out8 (0x3d5, cr66 | 0x80);
- vga_out8 (0x3d4, 0x3a);
- cr3a = vga_in8 (0x3d5);
- vga_out8 (0x3d5, cr3a | 0x80);
- vga_out8 (0x3d4, 0x53);
- cr53 = vga_in8 (0x3d5);
- vga_out8 (0x3d5, cr53 & 0x7f);
-
- vga_out8 (0x3d4, 0x66);
- vga_out8 (0x3d5, cr66);
- vga_out8 (0x3d4, 0x3a);
- vga_out8 (0x3d5, cr3a);
-
- vga_out8 (0x3d4, 0x66);
- vga_out8 (0x3d5, cr66);
- vga_out8 (0x3d4, 0x3a);
- vga_out8 (0x3d5, cr3a);
+ vga_out16 (0x3d4, 0x4838, par);
+ vga_out16 (0x3d4, 0xa039, par);
+ vga_out16 (0x3c4, 0x0608, par);
+
+ vga_out8 (0x3d4, 0x66, par);
+ cr66 = vga_in8 (0x3d5, par);
+ vga_out8 (0x3d5, cr66 | 0x80, par);
+ vga_out8 (0x3d4, 0x3a, par);
+ cr3a = vga_in8 (0x3d5, par);
+ vga_out8 (0x3d5, cr3a | 0x80, par);
+ vga_out8 (0x3d4, 0x53, par);
+ cr53 = vga_in8 (0x3d5, par);
+ vga_out8 (0x3d5, cr53 & 0x7f, par);
+
+ vga_out8 (0x3d4, 0x66, par);
+ vga_out8 (0x3d5, cr66, par);
+ vga_out8 (0x3d4, 0x3a, par);
+ vga_out8 (0x3d5, cr3a, par);
+
+ vga_out8 (0x3d4, 0x66, par);
+ vga_out8 (0x3d5, cr66, par);
+ vga_out8 (0x3d4, 0x3a, par);
+ vga_out8 (0x3d5, cr3a, par);
/* unlock extended seq regs */
- vga_out8 (0x3c4, 0x08);
- par->SR08 = vga_in8 (0x3c5);
- vga_out8 (0x3c5, 0x06);
+ vga_out8 (0x3c4, 0x08, par);
+ par->SR08 = vga_in8 (0x3c5, par);
+ vga_out8 (0x3c5, 0x06, par);
/* now save all the extended regs we need */
- vga_out8 (0x3d4, 0x31);
- par->CR31 = vga_in8 (0x3d5);
- vga_out8 (0x3d4, 0x32);
- par->CR32 = vga_in8 (0x3d5);
- vga_out8 (0x3d4, 0x34);
- par->CR34 = vga_in8 (0x3d5);
- vga_out8 (0x3d4, 0x36);
- par->CR36 = vga_in8 (0x3d5);
- vga_out8 (0x3d4, 0x3a);
- par->CR3A = vga_in8 (0x3d5);
- vga_out8 (0x3d4, 0x40);
- par->CR40 = vga_in8 (0x3d5);
- vga_out8 (0x3d4, 0x42);
- par->CR42 = vga_in8 (0x3d5);
- vga_out8 (0x3d4, 0x45);
- par->CR45 = vga_in8 (0x3d5);
- vga_out8 (0x3d4, 0x50);
- par->CR50 = vga_in8 (0x3d5);
- vga_out8 (0x3d4, 0x51);
- par->CR51 = vga_in8 (0x3d5);
- vga_out8 (0x3d4, 0x53);
- par->CR53 = vga_in8 (0x3d5);
- vga_out8 (0x3d4, 0x58);
- par->CR58 = vga_in8 (0x3d5);
- vga_out8 (0x3d4, 0x60);
- par->CR60 = vga_in8 (0x3d5);
- vga_out8 (0x3d4, 0x66);
- par->CR66 = vga_in8 (0x3d5);
- vga_out8 (0x3d4, 0x67);
- par->CR67 = vga_in8 (0x3d5);
- vga_out8 (0x3d4, 0x68);
- par->CR68 = vga_in8 (0x3d5);
- vga_out8 (0x3d4, 0x69);
- par->CR69 = vga_in8 (0x3d5);
- vga_out8 (0x3d4, 0x6f);
- par->CR6F = vga_in8 (0x3d5);
-
- vga_out8 (0x3d4, 0x33);
- par->CR33 = vga_in8 (0x3d5);
- vga_out8 (0x3d4, 0x86);
- par->CR86 = vga_in8 (0x3d5);
- vga_out8 (0x3d4, 0x88);
- par->CR88 = vga_in8 (0x3d5);
- vga_out8 (0x3d4, 0x90);
- par->CR90 = vga_in8 (0x3d5);
- vga_out8 (0x3d4, 0x91);
- par->CR91 = vga_in8 (0x3d5);
- vga_out8 (0x3d4, 0xb0);
- par->CRB0 = vga_in8 (0x3d5) | 0x80;
+ vga_out8 (0x3d4, 0x31, par);
+ par->CR31 = vga_in8 (0x3d5, par);
+ vga_out8 (0x3d4, 0x32, par);
+ par->CR32 = vga_in8 (0x3d5, par);
+ vga_out8 (0x3d4, 0x34, par);
+ par->CR34 = vga_in8 (0x3d5, par);
+ vga_out8 (0x3d4, 0x36, par);
+ par->CR36 = vga_in8 (0x3d5, par);
+ vga_out8 (0x3d4, 0x3a, par);
+ par->CR3A = vga_in8 (0x3d5, par);
+ vga_out8 (0x3d4, 0x40, par);
+ par->CR40 = vga_in8 (0x3d5, par);
+ vga_out8 (0x3d4, 0x42, par);
+ par->CR42 = vga_in8 (0x3d5, par);
+ vga_out8 (0x3d4, 0x45, par);
+ par->CR45 = vga_in8 (0x3d5, par);
+ vga_out8 (0x3d4, 0x50, par);
+ par->CR50 = vga_in8 (0x3d5, par);
+ vga_out8 (0x3d4, 0x51, par);
+ par->CR51 = vga_in8 (0x3d5, par);
+ vga_out8 (0x3d4, 0x53, par);
+ par->CR53 = vga_in8 (0x3d5, par);
+ vga_out8 (0x3d4, 0x58, par);
+ par->CR58 = vga_in8 (0x3d5, par);
+ vga_out8 (0x3d4, 0x60, par);
+ par->CR60 = vga_in8 (0x3d5, par);
+ vga_out8 (0x3d4, 0x66, par);
+ par->CR66 = vga_in8 (0x3d5, par);
+ vga_out8 (0x3d4, 0x67, par);
+ par->CR67 = vga_in8 (0x3d5, par);
+ vga_out8 (0x3d4, 0x68, par);
+ par->CR68 = vga_in8 (0x3d5, par);
+ vga_out8 (0x3d4, 0x69, par);
+ par->CR69 = vga_in8 (0x3d5, par);
+ vga_out8 (0x3d4, 0x6f, par);
+ par->CR6F = vga_in8 (0x3d5, par);
+
+ vga_out8 (0x3d4, 0x33, par);
+ par->CR33 = vga_in8 (0x3d5, par);
+ vga_out8 (0x3d4, 0x86, par);
+ par->CR86 = vga_in8 (0x3d5, par);
+ vga_out8 (0x3d4, 0x88, par);
+ par->CR88 = vga_in8 (0x3d5, par);
+ vga_out8 (0x3d4, 0x90, par);
+ par->CR90 = vga_in8 (0x3d5, par);
+ vga_out8 (0x3d4, 0x91, par);
+ par->CR91 = vga_in8 (0x3d5, par);
+ vga_out8 (0x3d4, 0xb0, par);
+ par->CRB0 = vga_in8 (0x3d5, par) | 0x80;
/* extended mode timing regs */
- vga_out8 (0x3d4, 0x3b);
- par->CR3B = vga_in8 (0x3d5);
- vga_out8 (0x3d4, 0x3c);
- par->CR3C = vga_in8 (0x3d5);
- vga_out8 (0x3d4, 0x43);
- par->CR43 = vga_in8 (0x3d5);
- vga_out8 (0x3d4, 0x5d);
- par->CR5D = vga_in8 (0x3d5);
- vga_out8 (0x3d4, 0x5e);
- par->CR5E = vga_in8 (0x3d5);
- vga_out8 (0x3d4, 0x65);
- par->CR65 = vga_in8 (0x3d5);
+ vga_out8 (0x3d4, 0x3b, par);
+ par->CR3B = vga_in8 (0x3d5, par);
+ vga_out8 (0x3d4, 0x3c, par);
+ par->CR3C = vga_in8 (0x3d5, par);
+ vga_out8 (0x3d4, 0x43, par);
+ par->CR43 = vga_in8 (0x3d5, par);
+ vga_out8 (0x3d4, 0x5d, par);
+ par->CR5D = vga_in8 (0x3d5, par);
+ vga_out8 (0x3d4, 0x5e, par);
+ par->CR5E = vga_in8 (0x3d5, par);
+ vga_out8 (0x3d4, 0x65, par);
+ par->CR65 = vga_in8 (0x3d5, par);
/* save seq extended regs for DCLK PLL programming */
- vga_out8 (0x3c4, 0x0e);
- par->SR0E = vga_in8 (0x3c5);
- vga_out8 (0x3c4, 0x0f);
- par->SR0F = vga_in8 (0x3c5);
- vga_out8 (0x3c4, 0x10);
- par->SR10 = vga_in8 (0x3c5);
- vga_out8 (0x3c4, 0x11);
- par->SR11 = vga_in8 (0x3c5);
- vga_out8 (0x3c4, 0x12);
- par->SR12 = vga_in8 (0x3c5);
- vga_out8 (0x3c4, 0x13);
- par->SR13 = vga_in8 (0x3c5);
- vga_out8 (0x3c4, 0x29);
- par->SR29 = vga_in8 (0x3c5);
-
- vga_out8 (0x3c4, 0x15);
- par->SR15 = vga_in8 (0x3c5);
- vga_out8 (0x3c4, 0x30);
- par->SR30 = vga_in8 (0x3c5);
- vga_out8 (0x3c4, 0x18);
- par->SR18 = vga_in8 (0x3c5);
+ vga_out8 (0x3c4, 0x0e, par);
+ par->SR0E = vga_in8 (0x3c5, par);
+ vga_out8 (0x3c4, 0x0f, par);
+ par->SR0F = vga_in8 (0x3c5, par);
+ vga_out8 (0x3c4, 0x10, par);
+ par->SR10 = vga_in8 (0x3c5, par);
+ vga_out8 (0x3c4, 0x11, par);
+ par->SR11 = vga_in8 (0x3c5, par);
+ vga_out8 (0x3c4, 0x12, par);
+ par->SR12 = vga_in8 (0x3c5, par);
+ vga_out8 (0x3c4, 0x13, par);
+ par->SR13 = vga_in8 (0x3c5, par);
+ vga_out8 (0x3c4, 0x29, par);
+ par->SR29 = vga_in8 (0x3c5, par);
+
+ vga_out8 (0x3c4, 0x15, par);
+ par->SR15 = vga_in8 (0x3c5, par);
+ vga_out8 (0x3c4, 0x30, par);
+ par->SR30 = vga_in8 (0x3c5, par);
+ vga_out8 (0x3c4, 0x18, par);
+ par->SR18 = vga_in8 (0x3c5, par);
/* Save flat panel expansion regsters. */
if (par->chip == S3_SAVAGE_MX) {
int i;
for (i = 0; i < 8; i++) {
- vga_out8 (0x3c4, 0x54+i);
- par->SR54[i] = vga_in8 (0x3c5);
+ vga_out8 (0x3c4, 0x54+i, par);
+ par->SR54[i] = vga_in8 (0x3c5, par);
}
}
- vga_out8 (0x3d4, 0x66);
- cr66 = vga_in8 (0x3d5);
- vga_out8 (0x3d5, cr66 | 0x80);
- vga_out8 (0x3d4, 0x3a);
- cr3a = vga_in8 (0x3d5);
- vga_out8 (0x3d5, cr3a | 0x80);
+ vga_out8 (0x3d4, 0x66, par);
+ cr66 = vga_in8 (0x3d5, par);
+ vga_out8 (0x3d5, cr66 | 0x80, par);
+ vga_out8 (0x3d4, 0x3a, par);
+ cr3a = vga_in8 (0x3d5, par);
+ vga_out8 (0x3d5, cr3a | 0x80, par);
/* now save MIU regs */
if (par->chip != S3_SAVAGE_MX) {
- par->MMPR0 = savage_in32(FIFO_CONTROL_REG);
- par->MMPR1 = savage_in32(MIU_CONTROL_REG);
- par->MMPR2 = savage_in32(STREAMS_TIMEOUT_REG);
- par->MMPR3 = savage_in32(MISC_TIMEOUT_REG);
+ par->MMPR0 = savage_in32(FIFO_CONTROL_REG, par);
+ par->MMPR1 = savage_in32(MIU_CONTROL_REG, par);
+ par->MMPR2 = savage_in32(STREAMS_TIMEOUT_REG, par);
+ par->MMPR3 = savage_in32(MISC_TIMEOUT_REG, par);
}
- vga_out8 (0x3d4, 0x3a);
- vga_out8 (0x3d5, cr3a);
- vga_out8 (0x3d4, 0x66);
- vga_out8 (0x3d5, cr66);
+ vga_out8 (0x3d4, 0x3a, par);
+ vga_out8 (0x3d5, cr3a, par);
+ vga_out8 (0x3d4, 0x66, par);
+ vga_out8 (0x3d5, cr66, par);
}
static void savage_update_var(struct fb_var_screeninfo *var, struct fb_videomode *modedb)
@@ -868,8 +872,8 @@ static int savagefb_decode_var (struct fb_var_screeninfo *var,
* match. Fall back to traditional register-crunching.
*/
- vga_out8 (0x3d4, 0x3a);
- tmp = vga_in8 (0x3d5);
+ vga_out8 (0x3d4, 0x3a, par);
+ tmp = vga_in8 (0x3d5, par);
if (1 /*FIXME:psav->pci_burst*/)
par->CR3A = (tmp & 0x7f) | 0x15;
else
@@ -879,16 +883,16 @@ static int savagefb_decode_var (struct fb_var_screeninfo *var,
par->CR31 = 0x8c;
par->CR66 = 0x89;
- vga_out8 (0x3d4, 0x58);
- par->CR58 = vga_in8 (0x3d5) & 0x80;
+ vga_out8 (0x3d4, 0x58, par);
+ par->CR58 = vga_in8 (0x3d5, par) & 0x80;
par->CR58 |= 0x13;
par->SR15 = 0x03 | 0x80;
par->SR18 = 0x00;
par->CR43 = par->CR45 = par->CR65 = 0x00;
- vga_out8 (0x3d4, 0x40);
- par->CR40 = vga_in8 (0x3d5) & ~0x01;
+ vga_out8 (0x3d4, 0x40, par);
+ par->CR40 = vga_in8 (0x3d5, par) & ~0x01;
par->MMPR0 = 0x010400;
par->MMPR1 = 0x00;
@@ -992,19 +996,19 @@ static int savagefb_decode_var (struct fb_var_screeninfo *var,
par->CR67 |= 1;
- vga_out8(0x3d4, 0x36);
- par->CR36 = vga_in8 (0x3d5);
- vga_out8 (0x3d4, 0x68);
- par->CR68 = vga_in8 (0x3d5);
+ vga_out8(0x3d4, 0x36, par);
+ par->CR36 = vga_in8 (0x3d5, par);
+ vga_out8 (0x3d4, 0x68, par);
+ par->CR68 = vga_in8 (0x3d5, par);
par->CR69 = 0;
- vga_out8 (0x3d4, 0x6f);
- par->CR6F = vga_in8 (0x3d5);
- vga_out8 (0x3d4, 0x86);
- par->CR86 = vga_in8 (0x3d5);
- vga_out8 (0x3d4, 0x88);
- par->CR88 = vga_in8 (0x3d5) | 0x08;
- vga_out8 (0x3d4, 0xb0);
- par->CRB0 = vga_in8 (0x3d5) | 0x80;
+ vga_out8 (0x3d4, 0x6f, par);
+ par->CR6F = vga_in8 (0x3d5, par);
+ vga_out8 (0x3d4, 0x86, par);
+ par->CR86 = vga_in8 (0x3d5, par);
+ vga_out8 (0x3d4, 0x88, par);
+ par->CR88 = vga_in8 (0x3d5, par) | 0x08;
+ vga_out8 (0x3d4, 0xb0, par);
+ par->CRB0 = vga_in8 (0x3d5, par) | 0x80;
return 0;
}
@@ -1033,11 +1037,11 @@ static int savagefb_setcolreg(unsigned regno,
switch (info->var.bits_per_pixel) {
case 8:
- vga_out8 (0x3c8, regno);
+ vga_out8 (0x3c8, regno, par);
- vga_out8 (0x3c9, red >> 10);
- vga_out8 (0x3c9, green >> 10);
- vga_out8 (0x3c9, blue >> 10);
+ vga_out8 (0x3c9, red >> 10, par);
+ vga_out8 (0x3c9, green >> 10, par);
+ vga_out8 (0x3c9, blue >> 10, par);
break;
case 16:
@@ -1079,11 +1083,11 @@ static void savagefb_set_par_int (struct savagefb_par *par)
par->SavageWaitIdle (par);
- vga_out8 (0x3c2, 0x23);
+ vga_out8 (0x3c2, 0x23, par);
- vga_out16 (0x3d4, 0x4838);
- vga_out16 (0x3d4, 0xa539);
- vga_out16 (0x3c4, 0x0608);
+ vga_out16 (0x3d4, 0x4838, par);
+ vga_out16 (0x3d4, 0xa539, par);
+ vga_out16 (0x3c4, 0x0608, par);
vgaHWProtect (par, 1);
@@ -1094,197 +1098,197 @@ static void savagefb_set_par_int (struct savagefb_par *par)
* switch to mode 3 here seems to eliminate the issue.
*/
- VerticalRetraceWait();
- vga_out8 (0x3d4, 0x67);
- cr67 = vga_in8 (0x3d5);
- vga_out8 (0x3d5, cr67/*par->CR67*/ & ~0x0c); /* no STREAMS yet */
+ VerticalRetraceWait(par);
+ vga_out8 (0x3d4, 0x67, par);
+ cr67 = vga_in8 (0x3d5, par);
+ vga_out8 (0x3d5, cr67/*par->CR67*/ & ~0x0c, par); /* no STREAMS yet */
- vga_out8 (0x3d4, 0x23);
- vga_out8 (0x3d5, 0x00);
- vga_out8 (0x3d4, 0x26);
- vga_out8 (0x3d5, 0x00);
+ vga_out8 (0x3d4, 0x23, par);
+ vga_out8 (0x3d5, 0x00, par);
+ vga_out8 (0x3d4, 0x26, par);
+ vga_out8 (0x3d5, 0x00, par);
/* restore extended regs */
- vga_out8 (0x3d4, 0x66);
- vga_out8 (0x3d5, par->CR66);
- vga_out8 (0x3d4, 0x3a);
- vga_out8 (0x3d5, par->CR3A);
- vga_out8 (0x3d4, 0x31);
- vga_out8 (0x3d5, par->CR31);
- vga_out8 (0x3d4, 0x32);
- vga_out8 (0x3d5, par->CR32);
- vga_out8 (0x3d4, 0x58);
- vga_out8 (0x3d5, par->CR58);
- vga_out8 (0x3d4, 0x53);
- vga_out8 (0x3d5, par->CR53 & 0x7f);
-
- vga_out16 (0x3c4, 0x0608);
+ vga_out8 (0x3d4, 0x66, par);
+ vga_out8 (0x3d5, par->CR66, par);
+ vga_out8 (0x3d4, 0x3a, par);
+ vga_out8 (0x3d5, par->CR3A, par);
+ vga_out8 (0x3d4, 0x31, par);
+ vga_out8 (0x3d5, par->CR31, par);
+ vga_out8 (0x3d4, 0x32, par);
+ vga_out8 (0x3d5, par->CR32, par);
+ vga_out8 (0x3d4, 0x58, par);
+ vga_out8 (0x3d5, par->CR58, par);
+ vga_out8 (0x3d4, 0x53, par);
+ vga_out8 (0x3d5, par->CR53 & 0x7f, par);
+
+ vga_out16 (0x3c4, 0x0608, par);
/* Restore DCLK registers. */
- vga_out8 (0x3c4, 0x0e);
- vga_out8 (0x3c5, par->SR0E);
- vga_out8 (0x3c4, 0x0f);
- vga_out8 (0x3c5, par->SR0F);
- vga_out8 (0x3c4, 0x29);
- vga_out8 (0x3c5, par->SR29);
- vga_out8 (0x3c4, 0x15);
- vga_out8 (0x3c5, par->SR15);
+ vga_out8 (0x3c4, 0x0e, par);
+ vga_out8 (0x3c5, par->SR0E, par);
+ vga_out8 (0x3c4, 0x0f, par);
+ vga_out8 (0x3c5, par->SR0F, par);
+ vga_out8 (0x3c4, 0x29, par);
+ vga_out8 (0x3c5, par->SR29, par);
+ vga_out8 (0x3c4, 0x15, par);
+ vga_out8 (0x3c5, par->SR15, par);
/* Restore flat panel expansion regsters. */
if( par->chip == S3_SAVAGE_MX ) {
int i;
for( i = 0; i < 8; i++ ) {
- vga_out8 (0x3c4, 0x54+i);
- vga_out8 (0x3c5, par->SR54[i]);
+ vga_out8 (0x3c4, 0x54+i, par);
+ vga_out8 (0x3c5, par->SR54[i], par);
}
}
vgaHWRestore (par);
/* extended mode timing registers */
- vga_out8 (0x3d4, 0x53);
- vga_out8 (0x3d5, par->CR53);
- vga_out8 (0x3d4, 0x5d);
- vga_out8 (0x3d5, par->CR5D);
- vga_out8 (0x3d4, 0x5e);
- vga_out8 (0x3d5, par->CR5E);
- vga_out8 (0x3d4, 0x3b);
- vga_out8 (0x3d5, par->CR3B);
- vga_out8 (0x3d4, 0x3c);
- vga_out8 (0x3d5, par->CR3C);
- vga_out8 (0x3d4, 0x43);
- vga_out8 (0x3d5, par->CR43);
- vga_out8 (0x3d4, 0x65);
- vga_out8 (0x3d5, par->CR65);
+ vga_out8 (0x3d4, 0x53, par);
+ vga_out8 (0x3d5, par->CR53, par);
+ vga_out8 (0x3d4, 0x5d, par);
+ vga_out8 (0x3d5, par->CR5D, par);
+ vga_out8 (0x3d4, 0x5e, par);
+ vga_out8 (0x3d5, par->CR5E, par);
+ vga_out8 (0x3d4, 0x3b, par);
+ vga_out8 (0x3d5, par->CR3B, par);
+ vga_out8 (0x3d4, 0x3c, par);
+ vga_out8 (0x3d5, par->CR3C, par);
+ vga_out8 (0x3d4, 0x43, par);
+ vga_out8 (0x3d5, par->CR43, par);
+ vga_out8 (0x3d4, 0x65, par);
+ vga_out8 (0x3d5, par->CR65, par);
/* restore the desired video mode with cr67 */
- vga_out8 (0x3d4, 0x67);
+ vga_out8 (0x3d4, 0x67, par);
/* following part not present in X11 driver */
- cr67 = vga_in8 (0x3d5) & 0xf;
- vga_out8 (0x3d5, 0x50 | cr67);
+ cr67 = vga_in8 (0x3d5, par) & 0xf;
+ vga_out8 (0x3d5, 0x50 | cr67, par);
udelay (10000);
- vga_out8 (0x3d4, 0x67);
+ vga_out8 (0x3d4, 0x67, par);
/* end of part */
- vga_out8 (0x3d5, par->CR67 & ~0x0c);
+ vga_out8 (0x3d5, par->CR67 & ~0x0c, par);
/* other mode timing and extended regs */
- vga_out8 (0x3d4, 0x34);
- vga_out8 (0x3d5, par->CR34);
- vga_out8 (0x3d4, 0x40);
- vga_out8 (0x3d5, par->CR40);
- vga_out8 (0x3d4, 0x42);
- vga_out8 (0x3d5, par->CR42);
- vga_out8 (0x3d4, 0x45);
- vga_out8 (0x3d5, par->CR45);
- vga_out8 (0x3d4, 0x50);
- vga_out8 (0x3d5, par->CR50);
- vga_out8 (0x3d4, 0x51);
- vga_out8 (0x3d5, par->CR51);
+ vga_out8 (0x3d4, 0x34, par);
+ vga_out8 (0x3d5, par->CR34, par);
+ vga_out8 (0x3d4, 0x40, par);
+ vga_out8 (0x3d5, par->CR40, par);
+ vga_out8 (0x3d4, 0x42, par);
+ vga_out8 (0x3d5, par->CR42, par);
+ vga_out8 (0x3d4, 0x45, par);
+ vga_out8 (0x3d5, par->CR45, par);
+ vga_out8 (0x3d4, 0x50, par);
+ vga_out8 (0x3d5, par->CR50, par);
+ vga_out8 (0x3d4, 0x51, par);
+ vga_out8 (0x3d5, par->CR51, par);
/* memory timings */
- vga_out8 (0x3d4, 0x36);
- vga_out8 (0x3d5, par->CR36);
- vga_out8 (0x3d4, 0x60);
- vga_out8 (0x3d5, par->CR60);
- vga_out8 (0x3d4, 0x68);
- vga_out8 (0x3d5, par->CR68);
- vga_out8 (0x3d4, 0x69);
- vga_out8 (0x3d5, par->CR69);
- vga_out8 (0x3d4, 0x6f);
- vga_out8 (0x3d5, par->CR6F);
-
- vga_out8 (0x3d4, 0x33);
- vga_out8 (0x3d5, par->CR33);
- vga_out8 (0x3d4, 0x86);
- vga_out8 (0x3d5, par->CR86);
- vga_out8 (0x3d4, 0x88);
- vga_out8 (0x3d5, par->CR88);
- vga_out8 (0x3d4, 0x90);
- vga_out8 (0x3d5, par->CR90);
- vga_out8 (0x3d4, 0x91);
- vga_out8 (0x3d5, par->CR91);
+ vga_out8 (0x3d4, 0x36, par);
+ vga_out8 (0x3d5, par->CR36, par);
+ vga_out8 (0x3d4, 0x60, par);
+ vga_out8 (0x3d5, par->CR60, par);
+ vga_out8 (0x3d4, 0x68, par);
+ vga_out8 (0x3d5, par->CR68, par);
+ vga_out8 (0x3d4, 0x69, par);
+ vga_out8 (0x3d5, par->CR69, par);
+ vga_out8 (0x3d4, 0x6f, par);
+ vga_out8 (0x3d5, par->CR6F, par);
+
+ vga_out8 (0x3d4, 0x33, par);
+ vga_out8 (0x3d5, par->CR33, par);
+ vga_out8 (0x3d4, 0x86, par);
+ vga_out8 (0x3d5, par->CR86, par);
+ vga_out8 (0x3d4, 0x88, par);
+ vga_out8 (0x3d5, par->CR88, par);
+ vga_out8 (0x3d4, 0x90, par);
+ vga_out8 (0x3d5, par->CR90, par);
+ vga_out8 (0x3d4, 0x91, par);
+ vga_out8 (0x3d5, par->CR91, par);
if (par->chip == S3_SAVAGE4) {
- vga_out8 (0x3d4, 0xb0);
- vga_out8 (0x3d5, par->CRB0);
+ vga_out8 (0x3d4, 0xb0, par);
+ vga_out8 (0x3d5, par->CRB0, par);
}
- vga_out8 (0x3d4, 0x32);
- vga_out8 (0x3d5, par->CR32);
+ vga_out8 (0x3d4, 0x32, par);
+ vga_out8 (0x3d5, par->CR32, par);
/* unlock extended seq regs */
- vga_out8 (0x3c4, 0x08);
- vga_out8 (0x3c5, 0x06);
+ vga_out8 (0x3c4, 0x08, par);
+ vga_out8 (0x3c5, 0x06, par);
/* Restore extended sequencer regs for MCLK. SR10 == 255 indicates
* that we should leave the default SR10 and SR11 values there.
*/
if (par->SR10 != 255) {
- vga_out8 (0x3c4, 0x10);
- vga_out8 (0x3c5, par->SR10);
- vga_out8 (0x3c4, 0x11);
- vga_out8 (0x3c5, par->SR11);
+ vga_out8 (0x3c4, 0x10, par);
+ vga_out8 (0x3c5, par->SR10, par);
+ vga_out8 (0x3c4, 0x11, par);
+ vga_out8 (0x3c5, par->SR11, par);
}
/* restore extended seq regs for dclk */
- vga_out8 (0x3c4, 0x0e);
- vga_out8 (0x3c5, par->SR0E);
- vga_out8 (0x3c4, 0x0f);
- vga_out8 (0x3c5, par->SR0F);
- vga_out8 (0x3c4, 0x12);
- vga_out8 (0x3c5, par->SR12);
- vga_out8 (0x3c4, 0x13);
- vga_out8 (0x3c5, par->SR13);
- vga_out8 (0x3c4, 0x29);
- vga_out8 (0x3c5, par->SR29);
-
- vga_out8 (0x3c4, 0x18);
- vga_out8 (0x3c5, par->SR18);
+ vga_out8 (0x3c4, 0x0e, par);
+ vga_out8 (0x3c5, par->SR0E, par);
+ vga_out8 (0x3c4, 0x0f, par);
+ vga_out8 (0x3c5, par->SR0F, par);
+ vga_out8 (0x3c4, 0x12, par);
+ vga_out8 (0x3c5, par->SR12, par);
+ vga_out8 (0x3c4, 0x13, par);
+ vga_out8 (0x3c5, par->SR13, par);
+ vga_out8 (0x3c4, 0x29, par);
+ vga_out8 (0x3c5, par->SR29, par);
+
+ vga_out8 (0x3c4, 0x18, par);
+ vga_out8 (0x3c5, par->SR18, par);
/* load new m, n pll values for dclk & mclk */
- vga_out8 (0x3c4, 0x15);
- tmp = vga_in8 (0x3c5) & ~0x21;
+ vga_out8 (0x3c4, 0x15, par);
+ tmp = vga_in8 (0x3c5, par) & ~0x21;
- vga_out8 (0x3c5, tmp | 0x03);
- vga_out8 (0x3c5, tmp | 0x23);
- vga_out8 (0x3c5, tmp | 0x03);
- vga_out8 (0x3c5, par->SR15);
+ vga_out8 (0x3c5, tmp | 0x03, par);
+ vga_out8 (0x3c5, tmp | 0x23, par);
+ vga_out8 (0x3c5, tmp | 0x03, par);
+ vga_out8 (0x3c5, par->SR15, par);
udelay (100);
- vga_out8 (0x3c4, 0x30);
- vga_out8 (0x3c5, par->SR30);
- vga_out8 (0x3c4, 0x08);
- vga_out8 (0x3c5, par->SR08);
+ vga_out8 (0x3c4, 0x30, par);
+ vga_out8 (0x3c5, par->SR30, par);
+ vga_out8 (0x3c4, 0x08, par);
+ vga_out8 (0x3c5, par->SR08, par);
/* now write out cr67 in full, possibly starting STREAMS */
- VerticalRetraceWait();
- vga_out8 (0x3d4, 0x67);
- vga_out8 (0x3d5, par->CR67);
+ VerticalRetraceWait(par);
+ vga_out8 (0x3d4, 0x67, par);
+ vga_out8 (0x3d5, par->CR67, par);
- vga_out8 (0x3d4, 0x66);
- cr66 = vga_in8 (0x3d5);
- vga_out8 (0x3d5, cr66 | 0x80);
- vga_out8 (0x3d4, 0x3a);
- cr3a = vga_in8 (0x3d5);
- vga_out8 (0x3d5, cr3a | 0x80);
+ vga_out8 (0x3d4, 0x66, par);
+ cr66 = vga_in8 (0x3d5, par);
+ vga_out8 (0x3d5, cr66 | 0x80, par);
+ vga_out8 (0x3d4, 0x3a, par);
+ cr3a = vga_in8 (0x3d5, par);
+ vga_out8 (0x3d5, cr3a | 0x80, par);
if (par->chip != S3_SAVAGE_MX) {
- VerticalRetraceWait();
- savage_out32 (FIFO_CONTROL_REG, par->MMPR0);
+ VerticalRetraceWait(par);
+ savage_out32 (FIFO_CONTROL_REG, par->MMPR0, par);
par->SavageWaitIdle (par);
- savage_out32 (MIU_CONTROL_REG, par->MMPR1);
+ savage_out32 (MIU_CONTROL_REG, par->MMPR1, par);
par->SavageWaitIdle (par);
- savage_out32 (STREAMS_TIMEOUT_REG, par->MMPR2);
+ savage_out32 (STREAMS_TIMEOUT_REG, par->MMPR2, par);
par->SavageWaitIdle (par);
- savage_out32 (MISC_TIMEOUT_REG, par->MMPR3);
+ savage_out32 (MISC_TIMEOUT_REG, par->MMPR3, par);
}
- vga_out8 (0x3d4, 0x66);
- vga_out8 (0x3d5, cr66);
- vga_out8 (0x3d4, 0x3a);
- vga_out8 (0x3d5, cr3a);
+ vga_out8 (0x3d4, 0x66, par);
+ vga_out8 (0x3d5, cr66, par);
+ vga_out8 (0x3d4, 0x3a, par);
+ vga_out8 (0x3d5, cr3a, par);
SavageSetup2DEngine (par);
vgaHWProtect (par, 0);
@@ -1299,10 +1303,10 @@ static void savagefb_update_start (struct savagefb_par *par,
* ((var->bits_per_pixel+7) / 8)) >> 2;
/* now program the start address registers */
- vga_out16(0x3d4, (base & 0x00ff00) | 0x0c);
- vga_out16(0x3d4, ((base & 0x00ff) << 8) | 0x0d);
- vga_out8 (0x3d4, 0x69);
- vga_out8 (0x3d5, (base & 0x7f0000) >> 16);
+ vga_out16(0x3d4, (base & 0x00ff00) | 0x0c, par);
+ vga_out16(0x3d4, ((base & 0x00ff) << 8) | 0x0d, par);
+ vga_out8 (0x3d4, 0x69, par);
+ vga_out8 (0x3d5, (base & 0x7f0000) >> 16, par);
}
@@ -1311,10 +1315,14 @@ static void savagefb_set_fix(struct fb_info *info)
info->fix.line_length = info->var.xres_virtual *
info->var.bits_per_pixel / 8;
- if (info->var.bits_per_pixel == 8)
+ if (info->var.bits_per_pixel == 8) {
info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
- else
+ info->fix.xpanstep = 4;
+ } else {
info->fix.visual = FB_VISUAL_TRUECOLOR;
+ info->fix.xpanstep = 2;
+ }
+
}
#if defined(CONFIG_FB_SAVAGE_ACCEL)
@@ -1359,7 +1367,6 @@ static int savagefb_set_par (struct fb_info *info)
par->minClock = 10000;
savagefb_set_par_int (par);
- savagefb_update_start (par, var);
fb_set_cmap (&info->cmap, info);
savagefb_set_fix(info);
savagefb_set_clip(info);
@@ -1406,12 +1413,12 @@ static int savagefb_blank(int blank, struct fb_info *info)
u8 sr8 = 0, srd = 0;
if (par->display_type == DISP_CRT) {
- vga_out8(0x3c4, 0x08);
- sr8 = vga_in8(0x3c5);
+ vga_out8(0x3c4, 0x08, par);
+ sr8 = vga_in8(0x3c5, par);
sr8 |= 0x06;
- vga_out8(0x3c5, sr8);
- vga_out8(0x3c4, 0x0d);
- srd = vga_in8(0x3c5);
+ vga_out8(0x3c5, sr8, par);
+ vga_out8(0x3c4, 0x0d, par);
+ srd = vga_in8(0x3c5, par);
srd &= 0x03;
switch (blank) {
@@ -1429,8 +1436,8 @@ static int savagefb_blank(int blank, struct fb_info *info)
break;
}
- vga_out8(0x3c4, 0x0d);
- vga_out8(0x3c5, srd);
+ vga_out8(0x3c4, 0x0d, par);
+ vga_out8(0x3c5, srd, par);
}
if (par->display_type == DISP_LCD ||
@@ -1438,14 +1445,14 @@ static int savagefb_blank(int blank, struct fb_info *info)
switch(blank) {
case FB_BLANK_UNBLANK:
case FB_BLANK_NORMAL:
- vga_out8(0x3c4, 0x31); /* SR31 bit 4 - FP enable */
- vga_out8(0x3c5, vga_in8(0x3c5) | 0x10);
+ vga_out8(0x3c4, 0x31, par); /* SR31 bit 4 - FP enable */
+ vga_out8(0x3c5, vga_in8(0x3c5, par) | 0x10, par);
break;
case FB_BLANK_VSYNC_SUSPEND:
case FB_BLANK_HSYNC_SUSPEND:
case FB_BLANK_POWERDOWN:
- vga_out8(0x3c4, 0x31); /* SR31 bit 4 - FP enable */
- vga_out8(0x3c5, vga_in8(0x3c5) & ~0x10);
+ vga_out8(0x3c4, 0x31, par); /* SR31 bit 4 - FP enable */
+ vga_out8(0x3c5, vga_in8(0x3c5, par) & ~0x10, par);
break;
}
}
@@ -1470,7 +1477,6 @@ static struct fb_ops savagefb_ops = {
.fb_copyarea = cfb_copyarea,
.fb_imageblit = cfb_imageblit,
#endif
- .fb_cursor = soft_cursor,
};
/* --------------------------------------------------------------------- */
@@ -1499,15 +1505,15 @@ static void savage_enable_mmio (struct savagefb_par *par)
DBG ("savage_enable_mmio\n");
- val = vga_in8 (0x3c3);
- vga_out8 (0x3c3, val | 0x01);
- val = vga_in8 (0x3cc);
- vga_out8 (0x3c2, val | 0x01);
+ val = vga_in8 (0x3c3, par);
+ vga_out8 (0x3c3, val | 0x01, par);
+ val = vga_in8 (0x3cc, par);
+ vga_out8 (0x3c2, val | 0x01, par);
if (par->chip >= S3_SAVAGE4) {
- vga_out8 (0x3d4, 0x40);
- val = vga_in8 (0x3d5);
- vga_out8 (0x3d5, val | 1);
+ vga_out8 (0x3d4, 0x40, par);
+ val = vga_in8 (0x3d5, par);
+ vga_out8 (0x3d5, val | 1, par);
}
}
@@ -1519,9 +1525,9 @@ static void savage_disable_mmio (struct savagefb_par *par)
DBG ("savage_disable_mmio\n");
if(par->chip >= S3_SAVAGE4 ) {
- vga_out8 (0x3d4, 0x40);
- val = vga_in8 (0x3d5);
- vga_out8 (0x3d5, val | 1);
+ vga_out8 (0x3d4, 0x40, par);
+ val = vga_in8 (0x3d5, par);
+ vga_out8 (0x3d5, val | 1, par);
}
}
@@ -1641,30 +1647,30 @@ static int __devinit savage_init_hw (struct savagefb_par *par)
DBG("savage_init_hw");
/* unprotect CRTC[0-7] */
- vga_out8(0x3d4, 0x11);
- tmp = vga_in8(0x3d5);
- vga_out8(0x3d5, tmp & 0x7f);
+ vga_out8(0x3d4, 0x11, par);
+ tmp = vga_in8(0x3d5, par);
+ vga_out8(0x3d5, tmp & 0x7f, par);
/* unlock extended regs */
- vga_out16(0x3d4, 0x4838);
- vga_out16(0x3d4, 0xa039);
- vga_out16(0x3c4, 0x0608);
+ vga_out16(0x3d4, 0x4838, par);
+ vga_out16(0x3d4, 0xa039, par);
+ vga_out16(0x3c4, 0x0608, par);
- vga_out8(0x3d4, 0x40);
- tmp = vga_in8(0x3d5);
- vga_out8(0x3d5, tmp & ~0x01);
+ vga_out8(0x3d4, 0x40, par);
+ tmp = vga_in8(0x3d5, par);
+ vga_out8(0x3d5, tmp & ~0x01, par);
/* unlock sys regs */
- vga_out8(0x3d4, 0x38);
- vga_out8(0x3d5, 0x48);
+ vga_out8(0x3d4, 0x38, par);
+ vga_out8(0x3d5, 0x48, par);
/* Unlock system registers. */
- vga_out16(0x3d4, 0x4838);
+ vga_out16(0x3d4, 0x4838, par);
/* Next go on to detect amount of installed ram */
- vga_out8(0x3d4, 0x36); /* for register CR36 (CONFG_REG1), */
- config1 = vga_in8(0x3d5); /* get amount of vram installed */
+ vga_out8(0x3d4, 0x36, par); /* for register CR36 (CONFG_REG1), */
+ config1 = vga_in8(0x3d5, par); /* get amount of vram installed */
/* Compute the amount of video memory and offscreen memory. */
@@ -1680,8 +1686,8 @@ static int __devinit savage_init_hw (struct savagefb_par *par)
* when it really means 8MB. Why do it the same when you
* can do it different...
*/
- vga_out8(0x3d4, 0x68); /* memory control 1 */
- if( (vga_in8(0x3d5) & 0xC0) == (0x01 << 6) )
+ vga_out8(0x3d4, 0x68, par); /* memory control 1 */
+ if( (vga_in8(0x3d5, par) & 0xC0) == (0x01 << 6) )
RamSavage4[1] = 8;
/*FALLTHROUGH*/
@@ -1710,13 +1716,13 @@ static int __devinit savage_init_hw (struct savagefb_par *par)
printk (KERN_INFO "savagefb: probed videoram: %dk\n", videoRam);
/* reset graphics engine to avoid memory corruption */
- vga_out8 (0x3d4, 0x66);
- cr66 = vga_in8 (0x3d5);
- vga_out8 (0x3d5, cr66 | 0x02);
+ vga_out8 (0x3d4, 0x66, par);
+ cr66 = vga_in8 (0x3d5, par);
+ vga_out8 (0x3d5, cr66 | 0x02, par);
udelay (10000);
- vga_out8 (0x3d4, 0x66);
- vga_out8 (0x3d5, cr66 & ~0x02); /* clear reset flag */
+ vga_out8 (0x3d4, 0x66, par);
+ vga_out8 (0x3d5, cr66 & ~0x02, par); /* clear reset flag */
udelay (10000);
@@ -1724,13 +1730,13 @@ static int __devinit savage_init_hw (struct savagefb_par *par)
* reset memory interface, 3D engine, AGP master, PCI master,
* master engine unit, motion compensation/LPB
*/
- vga_out8 (0x3d4, 0x3f);
- cr3f = vga_in8 (0x3d5);
- vga_out8 (0x3d5, cr3f | 0x08);
+ vga_out8 (0x3d4, 0x3f, par);
+ cr3f = vga_in8 (0x3d5, par);
+ vga_out8 (0x3d5, cr3f | 0x08, par);
udelay (10000);
- vga_out8 (0x3d4, 0x3f);
- vga_out8 (0x3d5, cr3f & ~0x08); /* clear reset flags */
+ vga_out8 (0x3d4, 0x3f, par);
+ vga_out8 (0x3d5, cr3f & ~0x08, par); /* clear reset flags */
udelay (10000);
/* Savage ramdac speeds */
@@ -1741,15 +1747,15 @@ static int __devinit savage_init_hw (struct savagefb_par *par)
par->clock[3] = 220000;
/* detect current mclk */
- vga_out8(0x3c4, 0x08);
- sr8 = vga_in8(0x3c5);
- vga_out8(0x3c5, 0x06);
- vga_out8(0x3c4, 0x10);
- n = vga_in8(0x3c5);
- vga_out8(0x3c4, 0x11);
- m = vga_in8(0x3c5);
- vga_out8(0x3c4, 0x08);
- vga_out8(0x3c5, sr8);
+ vga_out8(0x3c4, 0x08, par);
+ sr8 = vga_in8(0x3c5, par);
+ vga_out8(0x3c5, 0x06, par);
+ vga_out8(0x3c4, 0x10, par);
+ n = vga_in8(0x3c5, par);
+ vga_out8(0x3c4, 0x11, par);
+ m = vga_in8(0x3c5, par);
+ vga_out8(0x3c4, 0x08, par);
+ vga_out8(0x3c5, sr8, par);
m &= 0x7f;
n1 = n & 0x1f;
n2 = (n >> 5) & 0x03;
@@ -1763,10 +1769,10 @@ static int __devinit savage_init_hw (struct savagefb_par *par)
if (par->chip == S3_SAVAGE4) {
unsigned char sr30 = 0x00;
- vga_out8(0x3c4, 0x30);
+ vga_out8(0x3c4, 0x30, par);
/* clear bit 1 */
- vga_out8(0x3c5, vga_in8(0x3c5) & ~0x02);
- sr30 = vga_in8(0x3c5);
+ vga_out8(0x3c5, vga_in8(0x3c5, par) & ~0x02, par);
+ sr30 = vga_in8(0x3c5, par);
if (sr30 & 0x02 /*0x04 */) {
dvi = 1;
printk("savagefb: Digital Flat Panel Detected\n");
@@ -1783,12 +1789,12 @@ static int __devinit savage_init_hw (struct savagefb_par *par)
/* Check LCD panel parrmation */
if (par->display_type == DISP_LCD) {
- unsigned char cr6b = VGArCR( 0x6b );
+ unsigned char cr6b = VGArCR( 0x6b, par);
- int panelX = (VGArSEQ (0x61) +
- ((VGArSEQ (0x66) & 0x02) << 7) + 1) * 8;
- int panelY = (VGArSEQ (0x69) +
- ((VGArSEQ (0x6e) & 0x70) << 4) + 1);
+ int panelX = (VGArSEQ (0x61, par) +
+ ((VGArSEQ (0x66, par) & 0x02) << 7) + 1) * 8;
+ int panelY = (VGArSEQ (0x69, par) +
+ ((VGArSEQ (0x6e, par) & 0x70) << 4) + 1);
char * sTechnology = "Unknown";
@@ -1810,9 +1816,9 @@ static int __devinit savage_init_hw (struct savagefb_par *par)
ActiveDUO = 0x80
};
- if ((VGArSEQ (0x39) & 0x03) == 0) {
+ if ((VGArSEQ (0x39, par) & 0x03) == 0) {
sTechnology = "TFT";
- } else if ((VGArSEQ (0x30) & 0x01) == 0) {
+ } else if ((VGArSEQ (0x30, par) & 0x01) == 0) {
sTechnology = "DSTN";
} else {
sTechnology = "STN";
@@ -1870,7 +1876,6 @@ static int __devinit savage_init_fb_info (struct fb_info *info,
info->fix.type = FB_TYPE_PACKED_PIXELS;
info->fix.type_aux = 0;
- info->fix.xpanstep = 2;
info->fix.ypanstep = 1;
info->fix.ywrapstep = 0;
info->fix.accel = id->driver_data;
@@ -2049,24 +2054,11 @@ static int __devinit savagefb_probe (struct pci_dev* dev,
info->monspecs.modedb, info->monspecs.modedb_len,
NULL, 8);
} else if (info->monspecs.modedb != NULL) {
- struct fb_monspecs *specs = &info->monspecs;
- struct fb_videomode modedb;
-
- if (info->monspecs.misc & FB_MISC_1ST_DETAIL) {
- int i;
-
- for (i = 0; i < specs->modedb_len; i++) {
- if (specs->modedb[i].flag & FB_MODE_IS_FIRST) {
- modedb = specs->modedb[i];
- break;
- }
- }
- } else {
- /* otherwise, get first mode in database */
- modedb = specs->modedb[0];
- }
+ struct fb_videomode *modedb;
- savage_update_var(&info->var, &modedb);
+ modedb = fb_find_best_display(&info->monspecs,
+ &info->modelist);
+ savage_update_var(&info->var, modedb);
}
/* maximize virtual vertical length */
diff --git a/drivers/video/sgivwfb.c b/drivers/video/sgivwfb.c
index 8413907b379a..2e8769dd345a 100644
--- a/drivers/video/sgivwfb.c
+++ b/drivers/video/sgivwfb.c
@@ -18,6 +18,8 @@
#include <linux/fb.h>
#include <linux/init.h>
#include <linux/ioport.h>
+#include <linux/platform_device.h>
+
#include <asm/io.h>
#include <asm/mtrr.h>
@@ -124,7 +126,6 @@ static struct fb_ops sgivwfb_ops = {
.fb_fillrect = cfb_fillrect,
.fb_copyarea = cfb_copyarea,
.fb_imageblit = cfb_imageblit,
- .fb_cursor = soft_cursor,
.fb_mmap = sgivwfb_mmap,
};
@@ -749,10 +750,6 @@ int __init sgivwfb_setup(char *options)
/*
* Initialisation
*/
-static void sgivwfb_release(struct device *device)
-{
-}
-
static int __init sgivwfb_probe(struct device *device)
{
struct platform_device *dev = to_platform_device(device);
@@ -857,13 +854,7 @@ static struct device_driver sgivwfb_driver = {
.remove = sgivwfb_remove,
};
-static struct platform_device sgivwfb_device = {
- .name = "sgivwfb",
- .id = 0,
- .dev = {
- .release = sgivwfb_release,
- }
-};
+static struct platform_device *sgivwfb_device;
int __init sgivwfb_init(void)
{
@@ -878,9 +869,15 @@ int __init sgivwfb_init(void)
#endif
ret = driver_register(&sgivwfb_driver);
if (!ret) {
- ret = platform_device_register(&sgivwfb_device);
- if (ret)
+ sgivwfb_device = platform_device_alloc("sgivwfb", 0);
+ if (sgivwfb_device) {
+ ret = platform_device_add(sgivwfb_device);
+ } else
+ ret = -ENOMEM;
+ if (ret) {
driver_unregister(&sgivwfb_driver);
+ platform_device_put(sgivwfb_device);
+ }
}
return ret;
}
@@ -892,7 +889,7 @@ MODULE_LICENSE("GPL");
static void __exit sgivwfb_exit(void)
{
- platform_device_unregister(&sgivwfb_device);
+ platform_device_unregister(sgivwfb_device);
driver_unregister(&sgivwfb_driver);
}
diff --git a/drivers/video/sis/sis_main.c b/drivers/video/sis/sis_main.c
index 42c54b69726e..dea1a46c67c4 100644
--- a/drivers/video/sis/sis_main.c
+++ b/drivers/video/sis/sis_main.c
@@ -2002,7 +2002,9 @@ static struct fb_ops sisfb_ops = {
.fb_fillrect = fbcon_sis_fillrect,
.fb_copyarea = fbcon_sis_copyarea,
.fb_imageblit = cfb_imageblit,
+#ifdef CONFIG_FB_SOFT_CURSOR
.fb_cursor = soft_cursor,
+#endif
.fb_sync = fbcon_sis_sync,
#ifdef SIS_NEW_CONFIG_COMPAT
.fb_compat_ioctl= sisfb_compat_ioctl,
diff --git a/drivers/video/skeletonfb.c b/drivers/video/skeletonfb.c
index 7b43716ab665..a01e7ecc15ed 100644
--- a/drivers/video/skeletonfb.c
+++ b/drivers/video/skeletonfb.c
@@ -457,11 +457,8 @@ void xxxfb_imageblit(struct fb_info *p, const struct fb_image *image)
}
/**
- * xxxfb_cursor - REQUIRED function. If your hardware lacks support
- * for a cursor you can use the default cursor whose
- * function is called soft_cursor. It will always
- * work since it uses xxxfb_imageblit function which
- * is required.
+ * xxxfb_cursor - OPTIONAL. If your hardware lacks support
+ * for a cursor, leave this field NULL.
*
* @info: frame buffer structure that represents a single frame buffer
* @cursor: structure defining the cursor to draw.
@@ -663,7 +660,7 @@ static struct fb_ops xxxfb_ops = {
.fb_fillrect = xxxfb_fillrect, /* Needed !!! */
.fb_copyarea = xxxfb_copyarea, /* Needed !!! */
.fb_imageblit = xxxfb_imageblit, /* Needed !!! */
- .fb_cursor = xxxfb_cursor, /* Needed !!! */
+ .fb_cursor = xxxfb_cursor, /* Optional !!! */
.fb_rotate = xxxfb_rotate,
.fb_poll = xxxfb_poll,
.fb_sync = xxxfb_sync,
diff --git a/drivers/video/sstfb.c b/drivers/video/sstfb.c
index 663d53657fa4..e0f14df840d9 100644
--- a/drivers/video/sstfb.c
+++ b/drivers/video/sstfb.c
@@ -1382,7 +1382,6 @@ static struct fb_ops sstfb_ops = {
.fb_fillrect = cfb_fillrect, /* sstfb_fillrect */
.fb_copyarea = cfb_copyarea, /* sstfb_copyarea */
.fb_imageblit = cfb_imageblit,
- .fb_cursor = soft_cursor,
.fb_ioctl = sstfb_ioctl,
};
diff --git a/drivers/video/stifb.c b/drivers/video/stifb.c
index 9e52794768e6..fbb17332afd7 100644
--- a/drivers/video/stifb.c
+++ b/drivers/video/stifb.c
@@ -1147,7 +1147,6 @@ static struct fb_ops stifb_ops = {
.fb_fillrect = cfb_fillrect,
.fb_copyarea = cfb_copyarea,
.fb_imageblit = cfb_imageblit,
- .fb_cursor = soft_cursor,
};
diff --git a/drivers/video/tcx.c b/drivers/video/tcx.c
index 1986a8b3833c..59fff29bc02e 100644
--- a/drivers/video/tcx.c
+++ b/drivers/video/tcx.c
@@ -52,7 +52,6 @@ static struct fb_ops tcx_ops = {
.fb_imageblit = cfb_imageblit,
.fb_mmap = tcx_mmap,
.fb_ioctl = tcx_ioctl,
- .fb_cursor = soft_cursor,
};
/* THC definitions */
diff --git a/drivers/video/tdfxfb.c b/drivers/video/tdfxfb.c
index 7044226c5d4c..9d53387e6a66 100644
--- a/drivers/video/tdfxfb.c
+++ b/drivers/video/tdfxfb.c
@@ -184,7 +184,6 @@ static struct fb_ops tdfxfb_ops = {
.fb_copyarea = cfb_copyarea,
.fb_imageblit = cfb_imageblit,
#endif
- .fb_cursor = soft_cursor,
};
/*
diff --git a/drivers/video/tgafb.c b/drivers/video/tgafb.c
index 9d9d2009ad8c..7398bd48ba6c 100644
--- a/drivers/video/tgafb.c
+++ b/drivers/video/tgafb.c
@@ -63,7 +63,6 @@ static struct fb_ops tgafb_ops = {
.fb_fillrect = tgafb_fillrect,
.fb_copyarea = tgafb_copyarea,
.fb_imageblit = tgafb_imageblit,
- .fb_cursor = soft_cursor,
};
diff --git a/drivers/video/tridentfb.c b/drivers/video/tridentfb.c
index 81a6d9f188cf..9ac2d3171187 100644
--- a/drivers/video/tridentfb.c
+++ b/drivers/video/tridentfb.c
@@ -1293,7 +1293,6 @@ static struct fb_ops tridentfb_ops = {
.fb_fillrect = tridentfb_fillrect,
.fb_copyarea= tridentfb_copyarea,
.fb_imageblit = cfb_imageblit,
- .fb_cursor = soft_cursor,
};
module_init(tridentfb_init);
diff --git a/drivers/video/tx3912fb.c b/drivers/video/tx3912fb.c
index 39d9ca71856b..d904da44e1aa 100644
--- a/drivers/video/tx3912fb.c
+++ b/drivers/video/tx3912fb.c
@@ -89,7 +89,6 @@ static struct fb_ops tx3912fb_ops = {
.fb_fillrect = cfb_fillrect,
.fb_copyarea = cfb_copyarea,
.fb_imageblit = cfb_imageblit,
- .fb_cursor = soft_cursor,
};
static int tx3912fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
diff --git a/drivers/video/valkyriefb.c b/drivers/video/valkyriefb.c
index 31a2bbc53974..ce97ec8eae97 100644
--- a/drivers/video/valkyriefb.c
+++ b/drivers/video/valkyriefb.c
@@ -135,7 +135,6 @@ static struct fb_ops valkyriefb_ops = {
.fb_fillrect = cfb_fillrect,
.fb_copyarea = cfb_copyarea,
.fb_imageblit = cfb_imageblit,
- .fb_cursor = soft_cursor,
};
/* Sets the video mode according to info->var */
diff --git a/drivers/video/vesafb.c b/drivers/video/vesafb.c
index b1243da55fc5..e25eae1a78c1 100644
--- a/drivers/video/vesafb.c
+++ b/drivers/video/vesafb.c
@@ -19,6 +19,8 @@
#include <linux/fb.h>
#include <linux/ioport.h>
#include <linux/init.h>
+#include <linux/platform_device.h>
+
#include <video/vga.h>
#include <asm/io.h>
#include <asm/mtrr.h>
@@ -46,7 +48,7 @@ static struct fb_fix_screeninfo vesafb_fix __initdata = {
};
static int inverse = 0;
-static int mtrr = 3; /* default to write-combining */
+static int mtrr = 0; /* disable mtrr */
static int vram_remap __initdata = 0; /* Set amount of memory to be used */
static int vram_total __initdata = 0; /* Set total amount of memory */
static int pmi_setpal = 0; /* pmi for palette changes ??? */
@@ -164,45 +166,39 @@ static int vesafb_setcolreg(unsigned regno, unsigned red, unsigned green,
if (regno >= info->cmap.len)
return 1;
- switch (info->var.bits_per_pixel) {
- case 8:
+ if (info->var.bits_per_pixel == 8)
vesa_setpalette(regno,red,green,blue);
- break;
- case 16:
- if (info->var.red.offset == 10) {
- /* 1:5:5:5 */
- ((u32*) (info->pseudo_palette))[regno] =
+ else if (regno < 16) {
+ switch (info->var.bits_per_pixel) {
+ case 16:
+ if (info->var.red.offset == 10) {
+ /* 1:5:5:5 */
+ ((u32*) (info->pseudo_palette))[regno] =
((red & 0xf800) >> 1) |
((green & 0xf800) >> 6) |
((blue & 0xf800) >> 11);
- } else {
- /* 0:5:6:5 */
- ((u32*) (info->pseudo_palette))[regno] =
+ } else {
+ /* 0:5:6:5 */
+ ((u32*) (info->pseudo_palette))[regno] =
((red & 0xf800) ) |
((green & 0xfc00) >> 5) |
((blue & 0xf800) >> 11);
+ }
+ break;
+ case 24:
+ case 32:
+ red >>= 8;
+ green >>= 8;
+ blue >>= 8;
+ ((u32 *)(info->pseudo_palette))[regno] =
+ (red << info->var.red.offset) |
+ (green << info->var.green.offset) |
+ (blue << info->var.blue.offset);
+ break;
}
- break;
- case 24:
- red >>= 8;
- green >>= 8;
- blue >>= 8;
- ((u32 *)(info->pseudo_palette))[regno] =
- (red << info->var.red.offset) |
- (green << info->var.green.offset) |
- (blue << info->var.blue.offset);
- break;
- case 32:
- red >>= 8;
- green >>= 8;
- blue >>= 8;
- ((u32 *)(info->pseudo_palette))[regno] =
- (red << info->var.red.offset) |
- (green << info->var.green.offset) |
- (blue << info->var.blue.offset);
- break;
- }
- return 0;
+ }
+
+ return 0;
}
static struct fb_ops vesafb_ops = {
@@ -213,7 +209,6 @@ static struct fb_ops vesafb_ops = {
.fb_fillrect = cfb_fillrect,
.fb_copyarea = cfb_copyarea,
.fb_imageblit = cfb_imageblit,
- .fb_cursor = soft_cursor,
};
static int __init vesafb_setup(char *options)
diff --git a/drivers/video/vfb.c b/drivers/video/vfb.c
index b137a3fe0752..8794dc5d2466 100644
--- a/drivers/video/vfb.c
+++ b/drivers/video/vfb.c
@@ -20,6 +20,8 @@
#include <linux/vmalloc.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+
#include <asm/uaccess.h>
#include <linux/fb.h>
#include <linux/init.h>
@@ -90,7 +92,6 @@ static struct fb_ops vfb_ops = {
.fb_fillrect = cfb_fillrect,
.fb_copyarea = cfb_copyarea,
.fb_imageblit = cfb_imageblit,
- .fb_cursor = soft_cursor,
.fb_mmap = vfb_mmap,
};
diff --git a/drivers/video/vga16fb.c b/drivers/video/vga16fb.c
index b46454c55c91..226ae8a88482 100644
--- a/drivers/video/vga16fb.c
+++ b/drivers/video/vga16fb.c
@@ -21,6 +21,7 @@
#include <linux/fb.h>
#include <linux/ioport.h>
#include <linux/init.h>
+#include <linux/platform_device.h>
#include <asm/io.h>
#include <video/vga.h>
@@ -51,35 +52,33 @@
* card parameters
*/
-static struct fb_info vga16fb;
-
-static struct vga16fb_par {
+struct vga16fb_par {
/* structure holding original VGA register settings when the
screen is blanked */
struct {
- unsigned char SeqCtrlIndex; /* Sequencer Index reg. */
- unsigned char CrtCtrlIndex; /* CRT-Contr. Index reg. */
- unsigned char CrtMiscIO; /* Miscellaneous register */
- unsigned char HorizontalTotal; /* CRT-Controller:00h */
- unsigned char HorizDisplayEnd; /* CRT-Controller:01h */
- unsigned char StartHorizRetrace; /* CRT-Controller:04h */
- unsigned char EndHorizRetrace; /* CRT-Controller:05h */
- unsigned char Overflow; /* CRT-Controller:07h */
- unsigned char StartVertRetrace; /* CRT-Controller:10h */
- unsigned char EndVertRetrace; /* CRT-Controller:11h */
- unsigned char ModeControl; /* CRT-Controller:17h */
- unsigned char ClockingMode; /* Seq-Controller:01h */
+ unsigned char SeqCtrlIndex; /* Sequencer Index reg. */
+ unsigned char CrtCtrlIndex; /* CRT-Contr. Index reg. */
+ unsigned char CrtMiscIO; /* Miscellaneous register */
+ unsigned char HorizontalTotal; /* CRT-Controller:00h */
+ unsigned char HorizDisplayEnd; /* CRT-Controller:01h */
+ unsigned char StartHorizRetrace;/* CRT-Controller:04h */
+ unsigned char EndHorizRetrace; /* CRT-Controller:05h */
+ unsigned char Overflow; /* CRT-Controller:07h */
+ unsigned char StartVertRetrace; /* CRT-Controller:10h */
+ unsigned char EndVertRetrace; /* CRT-Controller:11h */
+ unsigned char ModeControl; /* CRT-Controller:17h */
+ unsigned char ClockingMode; /* Seq-Controller:01h */
} vga_state;
struct vgastate state;
atomic_t ref_count;
int palette_blanked, vesa_blanked, mode, isVGA;
u8 misc, pel_msk, vss, clkdiv;
u8 crtc[VGA_CRT_C];
-} vga16_par;
+};
/* --------------------------------------------------------------------- */
-static struct fb_var_screeninfo vga16fb_defined = {
+static struct fb_var_screeninfo vga16fb_defined __initdata = {
.xres = 640,
.yres = 480,
.xres_virtual = 640,
@@ -205,7 +204,7 @@ static inline void setindex(int index)
static void vga16fb_pan_var(struct fb_info *info,
struct fb_var_screeninfo *var)
{
- struct vga16fb_par *par = (struct vga16fb_par *) info->par;
+ struct vga16fb_par *par = info->par;
u32 xoffset, pos;
xoffset = var->xoffset;
@@ -300,7 +299,7 @@ static void vga16fb_clock_chip(struct vga16fb_par *par,
static int vga16fb_open(struct fb_info *info, int user)
{
- struct vga16fb_par *par = (struct vga16fb_par *) info->par;
+ struct vga16fb_par *par = info->par;
int cnt = atomic_read(&par->ref_count);
if (!cnt) {
@@ -315,7 +314,7 @@ static int vga16fb_open(struct fb_info *info, int user)
static int vga16fb_release(struct fb_info *info, int user)
{
- struct vga16fb_par *par = (struct vga16fb_par *) info->par;
+ struct vga16fb_par *par = info->par;
int cnt = atomic_read(&par->ref_count);
if (!cnt)
@@ -330,7 +329,7 @@ static int vga16fb_release(struct fb_info *info, int user)
static int vga16fb_check_var(struct fb_var_screeninfo *var,
struct fb_info *info)
{
- struct vga16fb_par *par = (struct vga16fb_par *) info->par;
+ struct vga16fb_par *par = info->par;
u32 xres, right, hslen, left, xtotal;
u32 yres, lower, vslen, upper, ytotal;
u32 vxres, xoffset, vyres, yoffset;
@@ -535,7 +534,7 @@ static int vga16fb_check_var(struct fb_var_screeninfo *var,
static int vga16fb_set_par(struct fb_info *info)
{
- struct vga16fb_par *par = (struct vga16fb_par *) info->par;
+ struct vga16fb_par *par = info->par;
u8 gdc[VGA_GFX_C];
u8 seq[VGA_SEQ_C];
u8 atc[VGA_ATT_C];
@@ -677,7 +676,7 @@ static int vga16fb_setcolreg(unsigned regno, unsigned red, unsigned green,
unsigned blue, unsigned transp,
struct fb_info *info)
{
- struct vga16fb_par *par = (struct vga16fb_par *) info->par;
+ struct vga16fb_par *par = info->par;
int gray;
/*
@@ -850,7 +849,7 @@ static void vga_pal_blank(void)
/* 0 unblank, 1 blank, 2 no vsync, 3 no hsync, 4 off */
static int vga16fb_blank(int blank, struct fb_info *info)
{
- struct vga16fb_par *par = (struct vga16fb_par *) info->par;
+ struct vga16fb_par *par = info->par;
switch (blank) {
case FB_BLANK_UNBLANK: /* Unblank */
@@ -1201,7 +1200,7 @@ static void vga_imageblit_expand(struct fb_info *info, const struct fb_image *im
{
char __iomem *where = info->screen_base + (image->dx/8) +
image->dy * info->fix.line_length;
- struct vga16fb_par *par = (struct vga16fb_par *) info->par;
+ struct vga16fb_par *par = info->par;
char *cdat = (char *) image->data;
char __iomem *dst;
int x, y;
@@ -1266,7 +1265,7 @@ static void vga_imageblit_color(struct fb_info *info, const struct fb_image *ima
/*
* Draw logo
*/
- struct vga16fb_par *par = (struct vga16fb_par *) info->par;
+ struct vga16fb_par *par = info->par;
char __iomem *where =
info->screen_base + image->dy * info->fix.line_length +
image->dx/8;
@@ -1326,7 +1325,6 @@ static struct fb_ops vga16fb_ops = {
.fb_fillrect = vga16fb_fillrect,
.fb_copyarea = vga16fb_copyarea,
.fb_imageblit = vga16fb_imageblit,
- .fb_cursor = soft_cursor,
};
#ifndef MODULE
@@ -1344,89 +1342,141 @@ static int vga16fb_setup(char *options)
}
#endif
-static int __init vga16fb_init(void)
+static int __init vga16fb_probe(struct device *device)
{
+ struct platform_device *dev = to_platform_device(device);
+ struct fb_info *info;
+ struct vga16fb_par *par;
int i;
- int ret;
-#ifndef MODULE
- char *option = NULL;
+ int ret = 0;
- if (fb_get_options("vga16fb", &option))
- return -ENODEV;
-
- vga16fb_setup(option);
-#endif
printk(KERN_DEBUG "vga16fb: initializing\n");
+ info = framebuffer_alloc(sizeof(struct vga16fb_par), &dev->dev);
+
+ if (!info) {
+ ret = -ENOMEM;
+ goto err_fb_alloc;
+ }
/* XXX share VGA_FB_PHYS and I/O region with vgacon and others */
+ info->screen_base = (void __iomem *)VGA_MAP_MEM(VGA_FB_PHYS);
- vga16fb.screen_base = (void __iomem *)VGA_MAP_MEM(VGA_FB_PHYS);
- if (!vga16fb.screen_base) {
+ if (!info->screen_base) {
printk(KERN_ERR "vga16fb: unable to map device\n");
ret = -ENOMEM;
goto err_ioremap;
}
- printk(KERN_INFO "vga16fb: mapped to 0x%p\n", vga16fb.screen_base);
- vga16_par.isVGA = ORIG_VIDEO_ISVGA;
- vga16_par.palette_blanked = 0;
- vga16_par.vesa_blanked = 0;
+ printk(KERN_INFO "vga16fb: mapped to 0x%p\n", info->screen_base);
+ par = info->par;
- i = vga16_par.isVGA? 6 : 2;
+ par->isVGA = ORIG_VIDEO_ISVGA;
+ par->palette_blanked = 0;
+ par->vesa_blanked = 0;
+
+ i = par->isVGA? 6 : 2;
vga16fb_defined.red.length = i;
vga16fb_defined.green.length = i;
vga16fb_defined.blue.length = i;
/* name should not depend on EGA/VGA */
- vga16fb.fbops = &vga16fb_ops;
- vga16fb.var = vga16fb_defined;
- vga16fb.fix = vga16fb_fix;
- vga16fb.par = &vga16_par;
- vga16fb.flags = FBINFO_FLAG_DEFAULT |
+ info->fbops = &vga16fb_ops;
+ info->var = vga16fb_defined;
+ info->fix = vga16fb_fix;
+ info->flags = FBINFO_FLAG_DEFAULT |
FBINFO_HWACCEL_YPAN;
- i = (vga16fb_defined.bits_per_pixel == 8) ? 256 : 16;
- ret = fb_alloc_cmap(&vga16fb.cmap, i, 0);
+ i = (info->var.bits_per_pixel == 8) ? 256 : 16;
+ ret = fb_alloc_cmap(&info->cmap, i, 0);
if (ret) {
printk(KERN_ERR "vga16fb: unable to allocate colormap\n");
ret = -ENOMEM;
goto err_alloc_cmap;
}
- if (vga16fb_check_var(&vga16fb.var, &vga16fb)) {
+ if (vga16fb_check_var(&info->var, info)) {
printk(KERN_ERR "vga16fb: unable to validate variable\n");
ret = -EINVAL;
goto err_check_var;
}
- vga16fb_update_fix(&vga16fb);
+ vga16fb_update_fix(info);
- if (register_framebuffer(&vga16fb) < 0) {
+ if (register_framebuffer(info) < 0) {
printk(KERN_ERR "vga16fb: unable to register framebuffer\n");
ret = -EINVAL;
goto err_check_var;
}
printk(KERN_INFO "fb%d: %s frame buffer device\n",
- vga16fb.node, vga16fb.fix.id);
+ info->node, info->fix.id);
+ dev_set_drvdata(device, info);
return 0;
err_check_var:
- fb_dealloc_cmap(&vga16fb.cmap);
+ fb_dealloc_cmap(&info->cmap);
err_alloc_cmap:
- iounmap(vga16fb.screen_base);
+ iounmap(info->screen_base);
err_ioremap:
+ framebuffer_release(info);
+ err_fb_alloc:
+ return ret;
+}
+
+static int vga16fb_remove(struct device *device)
+{
+ struct fb_info *info = dev_get_drvdata(device);
+
+ if (info) {
+ unregister_framebuffer(info);
+ iounmap(info->screen_base);
+ fb_dealloc_cmap(&info->cmap);
+ /* XXX unshare VGA regions */
+ framebuffer_release(info);
+ }
+
+ return 0;
+}
+
+static struct device_driver vga16fb_driver = {
+ .name = "vga16fb",
+ .bus = &platform_bus_type,
+ .probe = vga16fb_probe,
+ .remove = vga16fb_remove,
+};
+
+static struct platform_device vga16fb_device = {
+ .name = "vga16fb",
+};
+
+static int __init vga16fb_init(void)
+{
+ int ret;
+#ifndef MODULE
+ char *option = NULL;
+
+ if (fb_get_options("vga16fb", &option))
+ return -ENODEV;
+
+ vga16fb_setup(option);
+#endif
+ ret = driver_register(&vga16fb_driver);
+
+ if (!ret) {
+ ret = platform_device_register(&vga16fb_device);
+ if (ret)
+ driver_unregister(&vga16fb_driver);
+ }
+
return ret;
}
static void __exit vga16fb_exit(void)
{
- unregister_framebuffer(&vga16fb);
- iounmap(vga16fb.screen_base);
- fb_dealloc_cmap(&vga16fb.cmap);
- /* XXX unshare VGA regions */
+ platform_device_unregister(&vga16fb_device);
+ driver_unregister(&vga16fb_driver);
}
MODULE_LICENSE("GPL");
diff --git a/drivers/video/vgastate.c b/drivers/video/vgastate.c
index ca92940f3943..d9e01daee630 100644
--- a/drivers/video/vgastate.c
+++ b/drivers/video/vgastate.c
@@ -485,11 +485,6 @@ int restore_vga (struct vgastate *state)
return 0;
}
-#ifdef MODULE
-int init_module(void) { return 0; };
-void cleanup_module(void) {};
-#endif
-
EXPORT_SYMBOL(save_vga);
EXPORT_SYMBOL(restore_vga);
diff --git a/drivers/video/w100fb.c b/drivers/video/w100fb.c
index 0030c071da8f..48e70f153c4b 100644
--- a/drivers/video/w100fb.c
+++ b/drivers/video/w100fb.c
@@ -25,7 +25,7 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/mm.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <linux/string.h>
#include <linux/vmalloc.h>
#include <asm/io.h>
@@ -397,7 +397,6 @@ static struct fb_ops w100fb_ops = {
.fb_fillrect = cfb_fillrect,
.fb_copyarea = cfb_copyarea,
.fb_imageblit = cfb_imageblit,
- .fb_cursor = soft_cursor,
};
#ifdef CONFIG_PM
@@ -438,36 +437,34 @@ static void w100fb_restore_vidmem(struct w100fb_par *par)
}
}
-static int w100fb_suspend(struct device *dev, pm_message_t state, uint32_t level)
+static int w100fb_suspend(struct device *dev, pm_message_t state)
{
- if (level == SUSPEND_POWER_DOWN) {
- struct fb_info *info = dev_get_drvdata(dev);
- struct w100fb_par *par=info->par;
- struct w100_tg_info *tg = par->mach->tg;
-
- w100fb_save_vidmem(par);
- if(tg && tg->suspend)
- tg->suspend(par);
- w100_suspend(W100_SUSPEND_ALL);
- par->blanked = 1;
- }
+ struct fb_info *info = dev_get_drvdata(dev);
+ struct w100fb_par *par=info->par;
+ struct w100_tg_info *tg = par->mach->tg;
+
+ w100fb_save_vidmem(par);
+ if(tg && tg->suspend)
+ tg->suspend(par);
+ w100_suspend(W100_SUSPEND_ALL);
+ par->blanked = 1;
+
return 0;
}
-static int w100fb_resume(struct device *dev, uint32_t level)
+static int w100fb_resume(struct device *dev)
{
- if (level == RESUME_POWER_ON) {
- struct fb_info *info = dev_get_drvdata(dev);
- struct w100fb_par *par=info->par;
- struct w100_tg_info *tg = par->mach->tg;
+ struct fb_info *info = dev_get_drvdata(dev);
+ struct w100fb_par *par=info->par;
+ struct w100_tg_info *tg = par->mach->tg;
+
+ w100_hw_init(par);
+ w100fb_activate_var(par);
+ w100fb_restore_vidmem(par);
+ if(tg && tg->resume)
+ tg->resume(par);
+ par->blanked = 0;
- w100_hw_init(par);
- w100fb_activate_var(par);
- w100fb_restore_vidmem(par);
- if(tg && tg->resume)
- tg->resume(par);
- par->blanked = 0;
- }
return 0;
}
#else
diff --git a/drivers/w1/w1_ds2433.c b/drivers/w1/w1_ds2433.c
index 279e0e0363d6..1e3d98aac12d 100644
--- a/drivers/w1/w1_ds2433.c
+++ b/drivers/w1/w1_ds2433.c
@@ -299,10 +299,8 @@ static int w1_f23_add_slave(struct w1_slave *sl)
static void w1_f23_remove_slave(struct w1_slave *sl)
{
#ifdef CONFIG_W1_F23_CRC
- if (sl->family_data) {
- kfree(sl->family_data);
- sl->family_data = NULL;
- }
+ kfree(sl->family_data);
+ sl->family_data = NULL;
#endif /* CONFIG_W1_F23_CRC */
sysfs_remove_bin_file(&sl->dev.kobj, &w1_f23_bin_attr);
}
diff --git a/drivers/w1/w1_family.c b/drivers/w1/w1_family.c
index 88c517a4c178..9e293e139a0e 100644
--- a/drivers/w1/w1_family.c
+++ b/drivers/w1/w1_family.c
@@ -21,6 +21,7 @@
#include <linux/spinlock.h>
#include <linux/list.h>
+#include <linux/sched.h> /* schedule_timeout() */
#include <linux/delay.h>
#include "w1_family.h"
diff --git a/drivers/zorro/zorro-sysfs.c b/drivers/zorro/zorro-sysfs.c
index 04ca8840acf1..87c29d7b6c17 100644
--- a/drivers/zorro/zorro-sysfs.c
+++ b/drivers/zorro/zorro-sysfs.c
@@ -14,6 +14,7 @@
#include <linux/kernel.h>
#include <linux/zorro.h>
#include <linux/stat.h>
+#include <linux/string.h>
#include "zorro.h"
diff --git a/drivers/zorro/zorro.c b/drivers/zorro/zorro.c
index d3c05dfe20d2..0f2b40605b06 100644
--- a/drivers/zorro/zorro.c
+++ b/drivers/zorro/zorro.c
@@ -16,6 +16,8 @@
#include <linux/init.h>
#include <linux/zorro.h>
#include <linux/bitops.h>
+#include <linux/string.h>
+
#include <asm/setup.h>
#include <asm/amigahw.h>
diff --git a/fs/9p/error.c b/fs/9p/error.c
index fee5d19179c5..834cb179e388 100644
--- a/fs/9p/error.c
+++ b/fs/9p/error.c
@@ -33,6 +33,7 @@
#include <linux/list.h>
#include <linux/jhash.h>
+#include <linux/string.h>
#include "debug.h"
#include "error.h"
diff --git a/fs/9p/trans_sock.c b/fs/9p/trans_sock.c
index 01e26f0013ac..a93c2bf94c33 100644
--- a/fs/9p/trans_sock.c
+++ b/fs/9p/trans_sock.c
@@ -269,8 +269,7 @@ static void v9fs_sock_close(struct v9fs_transport *trans)
dprintk(DEBUG_TRANS, "socket closed\n");
}
- if (ts)
- kfree(ts);
+ kfree(ts);
trans->priv = NULL;
}
diff --git a/fs/9p/v9fs.c b/fs/9p/v9fs.c
index 82303f3bf76f..418c3743fdee 100644
--- a/fs/9p/v9fs.c
+++ b/fs/9p/v9fs.c
@@ -266,7 +266,7 @@ v9fs_session_init(struct v9fs_session_info *v9ses,
v9ses->remotename = __getname();
if (!v9ses->remotename) {
- putname(v9ses->name);
+ __putname(v9ses->name);
return -ENOMEM;
}
@@ -411,8 +411,8 @@ void v9fs_session_close(struct v9fs_session_info *v9ses)
if (v9ses->transport)
v9ses->transport->close(v9ses->transport);
- putname(v9ses->name);
- putname(v9ses->remotename);
+ __putname(v9ses->name);
+ __putname(v9ses->remotename);
}
/**
diff --git a/fs/9p/vfs_file.c b/fs/9p/vfs_file.c
index bbc3cc63854f..89c849da8504 100644
--- a/fs/9p/vfs_file.c
+++ b/fs/9p/vfs_file.c
@@ -32,7 +32,6 @@
#include <linux/string.h>
#include <linux/smp_lock.h>
#include <linux/inet.h>
-#include <linux/version.h>
#include <linux/list.h>
#include <asm/uaccess.h>
#include <linux/idr.h>
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c
index 2b696ae6655a..be7288184fa9 100644
--- a/fs/9p/vfs_inode.c
+++ b/fs/9p/vfs_inode.c
@@ -1105,7 +1105,7 @@ static int v9fs_vfs_readlink(struct dentry *dentry, char __user * buffer,
}
}
- putname(link);
+ __putname(link);
return retval;
}
@@ -1129,7 +1129,7 @@ static void *v9fs_vfs_follow_link(struct dentry *dentry, struct nameidata *nd)
len = v9fs_readlink(dentry, link, strlen(link));
if (len < 0) {
- putname(link);
+ __putname(link);
link = ERR_PTR(len);
} else
link[len] = 0;
@@ -1152,7 +1152,7 @@ static void v9fs_vfs_put_link(struct dentry *dentry, struct nameidata *nd, void
dprintk(DEBUG_VFS, " %s %s\n", dentry->d_name.name, s);
if (!IS_ERR(s))
- putname(s);
+ __putname(s);
}
/**
@@ -1228,7 +1228,7 @@ v9fs_vfs_link(struct dentry *old_dentry, struct inode *dir,
FreeMem:
kfree(mistat);
kfree(fcall);
- putname(symname);
+ __putname(symname);
return retval;
}
@@ -1319,7 +1319,7 @@ v9fs_vfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t rdev)
FreeMem:
kfree(mistat);
kfree(fcall);
- putname(symname);
+ __putname(symname);
return retval;
}
diff --git a/fs/Kconfig b/fs/Kconfig
index 48f5422cb19a..d5255e627b5f 100644
--- a/fs/Kconfig
+++ b/fs/Kconfig
@@ -810,7 +810,7 @@ config TMPFS
config HUGETLBFS
bool "HugeTLB file system support"
- depends X86 || IA64 || PPC64 || SPARC64 || SUPERH || X86_64 || BROKEN
+ depends X86 || IA64 || PPC64 || SPARC64 || SUPERH || BROKEN
config HUGETLB_PAGE
def_bool HUGETLBFS
@@ -898,6 +898,7 @@ config AFFS_FS
config HFS_FS
tristate "Apple Macintosh file system support (EXPERIMENTAL)"
depends on EXPERIMENTAL
+ select NLS
help
If you say Y here, you will be able to mount Macintosh-formatted
floppy disks and hard drive partitions with full read-write access.
@@ -1050,6 +1051,19 @@ config JFFS2_FS_WRITEBUFFER
- NOR flash with transparent ECC
- DataFlash
+config JFFS2_SUMMARY
+ bool "JFFS2 summary support (EXPERIMENTAL)"
+ depends on JFFS2_FS && EXPERIMENTAL
+ default n
+ help
+ This feature makes it possible to use summary information
+ for faster filesystem mount.
+
+ The summary information can be inserted into a filesystem image
+ by the utility 'sumtool'.
+
+ If unsure, say 'N'.
+
config JFFS2_COMPRESSION_OPTIONS
bool "Advanced compression options for JFFS2"
depends on JFFS2_FS
@@ -1071,10 +1085,10 @@ config JFFS2_ZLIB
default y
help
Zlib is designed to be a free, general-purpose, legally unencumbered,
- lossless data-compression library for use on virtually any computer
+ lossless data-compression library for use on virtually any computer
hardware and operating system. See <http://www.gzip.org/zlib/> for
further information.
-
+
Say 'Y' if unsure.
config JFFS2_RTIME
@@ -1096,7 +1110,7 @@ choice
default JFFS2_CMODE_PRIORITY
depends on JFFS2_FS
help
- You can set here the default compression mode of JFFS2 from
+ You can set here the default compression mode of JFFS2 from
the available compression modes. Don't touch if unsure.
config JFFS2_CMODE_NONE
@@ -1107,13 +1121,13 @@ config JFFS2_CMODE_NONE
config JFFS2_CMODE_PRIORITY
bool "priority"
help
- Tries the compressors in a predefinied order and chooses the first
+ Tries the compressors in a predefinied order and chooses the first
successful one.
config JFFS2_CMODE_SIZE
bool "size (EXPERIMENTAL)"
help
- Tries all compressors and chooses the one which has the smallest
+ Tries all compressors and chooses the one which has the smallest
result.
endchoice
@@ -1587,9 +1601,10 @@ config CIFS
PC operating systems. The CIFS protocol is fully supported by
file servers such as Windows 2000 (including Windows 2003, NT 4
and Windows XP) as well by Samba (which provides excellent CIFS
- server support for Linux and many other operating systems). Currently
- you must use the smbfs client filesystem to access older SMB servers
- such as Windows 9x and OS/2.
+ server support for Linux and many other operating systems). Limited
+ support for Windows ME and similar servers is provided as well.
+ You must use the smbfs client filesystem to access older SMB servers
+ such as OS/2 and DOS.
The intent of the cifs module is to provide an advanced
network file system client for mounting to CIFS compliant servers,
@@ -1600,7 +1615,7 @@ config CIFS
cifs if running only a (Samba) server. It is possible to enable both
smbfs and cifs (e.g. if you are using CIFS for accessing Windows 2003
and Samba 3 servers, and smbfs for accessing old servers). If you need
- to mount to Samba or Windows 2003 servers from this machine, say Y.
+ to mount to Samba or Windows from this machine, say Y.
config CIFS_STATS
bool "CIFS statistics"
@@ -1609,8 +1624,22 @@ config CIFS_STATS
Enabling this option will cause statistics for each server share
mounted by the cifs client to be displayed in /proc/fs/cifs/Stats
+config CIFS_STATS2
+ bool "CIFS extended statistics"
+ depends on CIFS_STATS
+ help
+ Enabling this option will allow more detailed statistics on SMB
+ request timing to be displayed in /proc/fs/cifs/DebugData and also
+ allow optional logging of slow responses to dmesg (depending on the
+ value of /proc/fs/cifs/cifsFYI, see fs/cifs/README for more details).
+ These additional statistics may have a minor effect on performance
+ and memory utilization.
+
+ Unless you are a developer or are doing network performance analysis
+ or tuning, say N.
+
config CIFS_XATTR
- bool "CIFS extended attributes (EXPERIMENTAL)"
+ bool "CIFS extended attributes"
depends on CIFS
help
Extended attributes are name:value pairs associated with inodes by
@@ -1622,11 +1651,11 @@ config CIFS_XATTR
prefaced by the user namespace prefix. The system namespace
(used by some filesystems to store ACLs) is not supported at
this time.
-
+
If unsure, say N.
config CIFS_POSIX
- bool "CIFS POSIX Extensions (EXPERIMENTAL)"
+ bool "CIFS POSIX Extensions"
depends on CIFS_XATTR
help
Enabling this option will cause the cifs client to attempt to
@@ -1639,10 +1668,28 @@ config CIFS_POSIX
config CIFS_EXPERIMENTAL
bool "CIFS Experimental Features (EXPERIMENTAL)"
- depends on CIFS
+ depends on CIFS && EXPERIMENTAL
+ help
+ Enables cifs features under testing. These features are
+ experimental and currently include support for writepages
+ (multipage writebehind performance improvements) and directory
+ change notification ie fcntl(F_DNOTIFY) as well as some security
+ improvements. Some also depend on setting at runtime the
+ pseudo-file /proc/fs/cifs/Experimental (which is disabled by
+ default). See the file fs/cifs/README for more details.
+
+ If unsure, say N.
+
+config CIFS_UPCALL
+ bool "CIFS Kerberos/SPNEGO advanced session setup (EXPERIMENTAL)"
+ depends on CIFS_EXPERIMENTAL
+ select CONNECTOR
help
- Enables cifs features under testing. These features
- are highly experimental. If unsure, say N.
+ Enables an upcall mechanism for CIFS which will be used to contact
+ userspace helper utilities to provide SPNEGO packaged Kerberos
+ tickets which are needed to mount to certain secure servers
+ (for which more secure Kerberos authentication is required). If
+ unsure, say N.
config NCP_FS
tristate "NCP file system support (to mount NetWare volumes)"
diff --git a/fs/Kconfig.binfmt b/fs/Kconfig.binfmt
index 434c19d076ac..175b2e8177c1 100644
--- a/fs/Kconfig.binfmt
+++ b/fs/Kconfig.binfmt
@@ -57,7 +57,7 @@ config BINFMT_SHARED_FLAT
config BINFMT_AOUT
tristate "Kernel support for a.out and ECOFF binaries"
- depends on (X86 && !X86_64) || ALPHA || ARM || M68K || SPARC32
+ depends on X86_32 || ALPHA || ARM || M68K || SPARC32
---help---
A.out (Assembler.OUTput) is a set of formats for libraries and
executables used in the earliest versions of UNIX. Linux used
diff --git a/fs/Makefile b/fs/Makefile
index 1972da186272..4c2655759078 100644
--- a/fs/Makefile
+++ b/fs/Makefile
@@ -10,7 +10,7 @@ obj-y := open.o read_write.o file_table.o buffer.o bio.o super.o \
ioctl.o readdir.o select.o fifo.o locks.o dcache.o inode.o \
attr.o bad_inode.o file.o filesystems.o namespace.o aio.o \
seq_file.o xattr.o libfs.o fs-writeback.o mpage.o direct-io.o \
- ioprio.o
+ ioprio.o pnode.o
obj-$(CONFIG_INOTIFY) += inotify.o
obj-$(CONFIG_EPOLL) += eventpoll.o
diff --git a/fs/adfs/adfs.h b/fs/adfs/adfs.h
index fd528433de43..f6cd01352cc8 100644
--- a/fs/adfs/adfs.h
+++ b/fs/adfs/adfs.h
@@ -12,7 +12,6 @@
#define ADFS_NDA_PUBLIC_READ (1 << 5)
#define ADFS_NDA_PUBLIC_WRITE (1 << 6)
-#include <linux/version.h>
#include "dir_f.h"
struct buffer_head;
diff --git a/fs/affs/file.c b/fs/affs/file.c
index 6744924b6905..f72fb776ecdf 100644
--- a/fs/affs/file.c
+++ b/fs/affs/file.c
@@ -22,14 +22,13 @@ static int affs_grow_extcache(struct inode *inode, u32 lc_idx);
static struct buffer_head *affs_alloc_extblock(struct inode *inode, struct buffer_head *bh, u32 ext);
static inline struct buffer_head *affs_get_extblock(struct inode *inode, u32 ext);
static struct buffer_head *affs_get_extblock_slow(struct inode *inode, u32 ext);
-static ssize_t affs_file_write(struct file *filp, const char __user *buf, size_t count, loff_t *ppos);
static int affs_file_open(struct inode *inode, struct file *filp);
static int affs_file_release(struct inode *inode, struct file *filp);
struct file_operations affs_file_operations = {
.llseek = generic_file_llseek,
.read = generic_file_read,
- .write = affs_file_write,
+ .write = generic_file_write,
.mmap = generic_file_mmap,
.open = affs_file_open,
.release = affs_file_release,
@@ -473,21 +472,6 @@ affs_getemptyblk_ino(struct inode *inode, int block)
return ERR_PTR(err);
}
-static ssize_t
-affs_file_write(struct file *file, const char __user *buf,
- size_t count, loff_t *ppos)
-{
- ssize_t retval;
-
- retval = generic_file_write (file, buf, count, ppos);
- if (retval >0) {
- struct inode *inode = file->f_dentry->d_inode;
- inode->i_ctime = inode->i_mtime = CURRENT_TIME_SEC;
- mark_inode_dirty(inode);
- }
- return retval;
-}
-
static int
affs_do_readpage_ofs(struct file *file, struct page *page, unsigned from, unsigned to)
{
diff --git a/fs/affs/super.c b/fs/affs/super.c
index 9c3080716c92..aaec015a16e4 100644
--- a/fs/affs/super.c
+++ b/fs/affs/super.c
@@ -35,8 +35,7 @@ affs_put_super(struct super_block *sb)
mark_buffer_dirty(sbi->s_root_bh);
}
- if (sbi->s_prefix)
- kfree(sbi->s_prefix);
+ kfree(sbi->s_prefix);
affs_free_bitmap(sb);
affs_brelse(sbi->s_root_bh);
kfree(sbi);
@@ -198,10 +197,9 @@ parse_options(char *options, uid_t *uid, gid_t *gid, int *mode, int *reserved, s
*mount_opts |= SF_MUFS;
break;
case Opt_prefix:
- if (*prefix) { /* Free any previous prefix */
- kfree(*prefix);
- *prefix = NULL;
- }
+ /* Free any previous prefix */
+ kfree(*prefix);
+ *prefix = NULL;
*prefix = match_strdup(&args[0]);
if (!*prefix)
return 0;
@@ -462,11 +460,9 @@ got_root:
out_error:
if (root_inode)
iput(root_inode);
- if (sbi->s_bitmap)
- kfree(sbi->s_bitmap);
+ kfree(sbi->s_bitmap);
affs_brelse(root_bh);
- if (sbi->s_prefix)
- kfree(sbi->s_prefix);
+ kfree(sbi->s_prefix);
kfree(sbi);
sb->s_fs_info = NULL;
return -EINVAL;
diff --git a/fs/afs/file.c b/fs/afs/file.c
index 23c125128024..150b19227922 100644
--- a/fs/afs/file.c
+++ b/fs/afs/file.c
@@ -29,26 +29,12 @@ static int afs_file_release(struct inode *inode, struct file *file);
static int afs_file_readpage(struct file *file, struct page *page);
static int afs_file_invalidatepage(struct page *page, unsigned long offset);
-static int afs_file_releasepage(struct page *page, int gfp_flags);
-
-static ssize_t afs_file_write(struct file *file, const char __user *buf,
- size_t size, loff_t *off);
+static int afs_file_releasepage(struct page *page, gfp_t gfp_flags);
struct inode_operations afs_file_inode_operations = {
.getattr = afs_inode_getattr,
};
-struct file_operations afs_file_file_operations = {
- .read = generic_file_read,
- .write = afs_file_write,
- .mmap = generic_file_mmap,
-#if 0
- .open = afs_file_open,
- .release = afs_file_release,
- .fsync = afs_file_fsync,
-#endif
-};
-
struct address_space_operations afs_fs_aops = {
.readpage = afs_file_readpage,
.sync_page = block_sync_page,
@@ -59,22 +45,6 @@ struct address_space_operations afs_fs_aops = {
/*****************************************************************************/
/*
- * AFS file write
- */
-static ssize_t afs_file_write(struct file *file, const char __user *buf,
- size_t size, loff_t *off)
-{
- struct afs_vnode *vnode;
-
- vnode = AFS_FS_I(file->f_dentry->d_inode);
- if (vnode->flags & AFS_VNODE_DELETED)
- return -ESTALE;
-
- return -EIO;
-} /* end afs_file_write() */
-
-/*****************************************************************************/
-/*
* deal with notification that a page was read from the cache
*/
#ifdef AFS_CACHING_SUPPORT
@@ -279,7 +249,7 @@ static int afs_file_invalidatepage(struct page *page, unsigned long offset)
/*
* release a page and cleanup its private data
*/
-static int afs_file_releasepage(struct page *page, int gfp_flags)
+static int afs_file_releasepage(struct page *page, gfp_t gfp_flags)
{
struct cachefs_page *pageio;
@@ -291,12 +261,11 @@ static int afs_file_releasepage(struct page *page, int gfp_flags)
cachefs_uncache_page(vnode->cache, page);
#endif
- pageio = (struct cachefs_page *) page->private;
- page->private = 0;
+ pageio = (struct cachefs_page *) page_private(page);
+ set_page_private(page, 0);
ClearPagePrivate(page);
- if (pageio)
- kfree(pageio);
+ kfree(pageio);
}
_leave(" = 0");
diff --git a/fs/afs/inode.c b/fs/afs/inode.c
index c476fde33fbc..4ebb30a50ed5 100644
--- a/fs/afs/inode.c
+++ b/fs/afs/inode.c
@@ -49,7 +49,7 @@ static int afs_inode_map_status(struct afs_vnode *vnode)
case AFS_FTYPE_FILE:
inode->i_mode = S_IFREG | vnode->status.mode;
inode->i_op = &afs_file_inode_operations;
- inode->i_fop = &afs_file_file_operations;
+ inode->i_fop = &generic_ro_fops;
break;
case AFS_FTYPE_DIR:
inode->i_mode = S_IFDIR | vnode->status.mode;
diff --git a/fs/afs/internal.h b/fs/afs/internal.h
index f09860b45c1a..ab8f87c66319 100644
--- a/fs/afs/internal.h
+++ b/fs/afs/internal.h
@@ -71,7 +71,6 @@ extern struct file_operations afs_dir_file_operations;
*/
extern struct address_space_operations afs_fs_aops;
extern struct inode_operations afs_file_inode_operations;
-extern struct file_operations afs_file_file_operations;
#ifdef AFS_CACHING_SUPPORT
extern int afs_cache_get_page_cookie(struct page *page,
diff --git a/fs/aio.c b/fs/aio.c
index edfca5b75535..20bb919eb195 100644
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -42,8 +42,9 @@
#endif
/*------ sysctl variables----*/
-atomic_t aio_nr = ATOMIC_INIT(0); /* current system wide number of aio requests */
-unsigned aio_max_nr = 0x10000; /* system wide maximum number of aio requests */
+static DEFINE_SPINLOCK(aio_nr_lock);
+unsigned long aio_nr; /* current system wide number of aio requests */
+unsigned long aio_max_nr = 0x10000; /* system wide maximum number of aio requests */
/*----end sysctl variables---*/
static kmem_cache_t *kiocb_cachep;
@@ -208,7 +209,7 @@ static struct kioctx *ioctx_alloc(unsigned nr_events)
return ERR_PTR(-EINVAL);
}
- if (nr_events > aio_max_nr)
+ if ((unsigned long)nr_events > aio_max_nr)
return ERR_PTR(-EAGAIN);
ctx = kmem_cache_alloc(kioctx_cachep, GFP_KERNEL);
@@ -233,8 +234,14 @@ static struct kioctx *ioctx_alloc(unsigned nr_events)
goto out_freectx;
/* limit the number of system wide aios */
- atomic_add(ctx->max_reqs, &aio_nr); /* undone by __put_ioctx */
- if (unlikely(atomic_read(&aio_nr) > aio_max_nr))
+ spin_lock(&aio_nr_lock);
+ if (aio_nr + ctx->max_reqs > aio_max_nr ||
+ aio_nr + ctx->max_reqs < aio_nr)
+ ctx->max_reqs = 0;
+ else
+ aio_nr += ctx->max_reqs;
+ spin_unlock(&aio_nr_lock);
+ if (ctx->max_reqs == 0)
goto out_cleanup;
/* now link into global list. kludge. FIXME */
@@ -248,8 +255,6 @@ static struct kioctx *ioctx_alloc(unsigned nr_events)
return ctx;
out_cleanup:
- atomic_sub(ctx->max_reqs, &aio_nr);
- ctx->max_reqs = 0; /* prevent __put_ioctx from sub'ing aio_nr */
__put_ioctx(ctx);
return ERR_PTR(-EAGAIN);
@@ -374,7 +379,12 @@ void fastcall __put_ioctx(struct kioctx *ctx)
pr_debug("__put_ioctx: freeing %p\n", ctx);
kmem_cache_free(kioctx_cachep, ctx);
- atomic_sub(nr_events, &aio_nr);
+ if (nr_events) {
+ spin_lock(&aio_nr_lock);
+ BUG_ON(aio_nr - nr_events > aio_nr);
+ aio_nr -= nr_events;
+ spin_unlock(&aio_nr_lock);
+ }
}
/* aio_get_req
@@ -1258,8 +1268,9 @@ asmlinkage long sys_io_setup(unsigned nr_events, aio_context_t __user *ctxp)
goto out;
ret = -EINVAL;
- if (unlikely(ctx || (int)nr_events <= 0)) {
- pr_debug("EINVAL: io_setup: ctx or nr_events > max\n");
+ if (unlikely(ctx || nr_events == 0)) {
+ pr_debug("EINVAL: io_setup: ctx %lu nr_events %u\n",
+ ctx, nr_events);
goto out;
}
diff --git a/fs/attr.c b/fs/attr.c
index b1796fb9e524..67bcd9b14ea5 100644
--- a/fs/attr.c
+++ b/fs/attr.c
@@ -117,9 +117,6 @@ int notify_change(struct dentry * dentry, struct iattr * attr)
struct timespec now;
unsigned int ia_valid = attr->ia_valid;
- if (!inode)
- BUG();
-
mode = inode->i_mode;
now = current_fs_time(inode->i_sb);
diff --git a/fs/autofs/waitq.c b/fs/autofs/waitq.c
index 1fcaa1568541..633f628005b4 100644
--- a/fs/autofs/waitq.c
+++ b/fs/autofs/waitq.c
@@ -150,10 +150,8 @@ int autofs_wait(struct autofs_sb_info *sbi, struct qstr *name)
if ( sbi->catatonic ) {
/* We might have slept, so check again for catatonic mode */
wq->status = -ENOENT;
- if ( wq->name ) {
- kfree(wq->name);
- wq->name = NULL;
- }
+ kfree(wq->name);
+ wq->name = NULL;
}
if ( wq->name ) {
diff --git a/fs/autofs4/inode.c b/fs/autofs4/inode.c
index 0a3c05d10167..818b37be5153 100644
--- a/fs/autofs4/inode.c
+++ b/fs/autofs4/inode.c
@@ -22,10 +22,8 @@
static void ino_lnkfree(struct autofs_info *ino)
{
- if (ino->u.symlink) {
- kfree(ino->u.symlink);
- ino->u.symlink = NULL;
- }
+ kfree(ino->u.symlink);
+ ino->u.symlink = NULL;
}
struct autofs_info *autofs4_init_ino(struct autofs_info *ino,
diff --git a/fs/autofs4/waitq.c b/fs/autofs4/waitq.c
index 3df86285a1c7..394ff36ef8f1 100644
--- a/fs/autofs4/waitq.c
+++ b/fs/autofs4/waitq.c
@@ -243,10 +243,8 @@ int autofs4_wait(struct autofs_sb_info *sbi, struct dentry *dentry,
if ( sbi->catatonic ) {
/* We might have slept, so check again for catatonic mode */
wq->status = -ENOENT;
- if ( wq->name ) {
- kfree(wq->name);
- wq->name = NULL;
- }
+ kfree(wq->name);
+ wq->name = NULL;
}
if ( wq->name ) {
diff --git a/fs/befs/linuxvfs.c b/fs/befs/linuxvfs.c
index e0a6025f1d06..2d365cb8eec6 100644
--- a/fs/befs/linuxvfs.c
+++ b/fs/befs/linuxvfs.c
@@ -73,12 +73,6 @@ static struct inode_operations befs_dir_inode_operations = {
.lookup = befs_lookup,
};
-static struct file_operations befs_file_operations = {
- .llseek = default_llseek,
- .read = generic_file_read,
- .mmap = generic_file_readonly_mmap,
-};
-
static struct address_space_operations befs_aops = {
.readpage = befs_readpage,
.sync_page = block_sync_page,
@@ -398,7 +392,7 @@ befs_read_inode(struct inode *inode)
inode->i_mapping->a_ops = &befs_aops;
if (S_ISREG(inode->i_mode)) {
- inode->i_fop = &befs_file_operations;
+ inode->i_fop = &generic_ro_fops;
} else if (S_ISDIR(inode->i_mode)) {
inode->i_op = &befs_dir_inode_operations;
inode->i_fop = &befs_dir_operations;
@@ -731,20 +725,16 @@ parse_options(char *options, befs_mount_options * opts)
static void
befs_put_super(struct super_block *sb)
{
- if (BEFS_SB(sb)->mount_opts.iocharset) {
- kfree(BEFS_SB(sb)->mount_opts.iocharset);
- BEFS_SB(sb)->mount_opts.iocharset = NULL;
- }
+ kfree(BEFS_SB(sb)->mount_opts.iocharset);
+ BEFS_SB(sb)->mount_opts.iocharset = NULL;
if (BEFS_SB(sb)->nls) {
unload_nls(BEFS_SB(sb)->nls);
BEFS_SB(sb)->nls = NULL;
}
- if (sb->s_fs_info) {
- kfree(sb->s_fs_info);
- sb->s_fs_info = NULL;
- }
+ kfree(sb->s_fs_info);
+ sb->s_fs_info = NULL;
return;
}
diff --git a/fs/binfmt_aout.c b/fs/binfmt_aout.c
index dd9baabaf016..72011826f0cb 100644
--- a/fs/binfmt_aout.c
+++ b/fs/binfmt_aout.c
@@ -318,7 +318,6 @@ static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs)
current->mm->free_area_cache = current->mm->mmap_base;
current->mm->cached_hole_size = 0;
- set_mm_counter(current->mm, rss, 0);
current->mm->mmap = NULL;
compute_creds(bprm);
current->flags &= ~PF_FORKNOEXEC;
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index d4b15576e584..f36f2210204f 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -773,7 +773,6 @@ static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
/* Do this so that we can load the interpreter, if need be. We will
change some of these later */
- set_mm_counter(current->mm, rss, 0);
current->mm->free_area_cache = current->mm->mmap_base;
current->mm->cached_hole_size = 0;
retval = setup_arg_pages(bprm, randomize_stack_top(STACK_TOP),
@@ -1007,8 +1006,7 @@ out_free_dentry:
if (interpreter)
fput(interpreter);
out_free_interp:
- if (elf_interpreter)
- kfree(elf_interpreter);
+ kfree(elf_interpreter);
out_free_file:
sys_close(elf_exec_fileno);
out_free_fh:
@@ -1503,9 +1501,7 @@ static int elf_core_dump(long signr, struct pt_regs * regs, struct file * file)
fill_psinfo(psinfo, current->group_leader, current->mm);
fill_note(notes +1, "CORE", NT_PRPSINFO, sizeof(*psinfo), psinfo);
- fill_note(notes +2, "CORE", NT_TASKSTRUCT, sizeof(*current), current);
-
- numnote = 3;
+ numnote = 2;
auxv = (elf_addr_t *) current->mm->saved_auxv;
diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c
index 134c9c0d1f54..e0344f69c79d 100644
--- a/fs/binfmt_elf_fdpic.c
+++ b/fs/binfmt_elf_fdpic.c
@@ -294,14 +294,7 @@ static int load_elf_fdpic_binary(struct linux_binprm *bprm, struct pt_regs *regs
&interp_params,
&current->mm->start_stack,
&current->mm->start_brk);
-#endif
-
- /* do this so that we can load the interpreter, if need be
- * - we will change some of these later
- */
- set_mm_counter(current->mm, rss, 0);
-#ifdef CONFIG_MMU
retval = setup_arg_pages(bprm, current->mm->start_stack, executable_stack);
if (retval < 0) {
send_sig(SIGKILL, current, 0);
@@ -418,16 +411,11 @@ error:
allow_write_access(interpreter);
fput(interpreter);
}
- if (interpreter_name)
- kfree(interpreter_name);
- if (exec_params.phdrs)
- kfree(exec_params.phdrs);
- if (exec_params.loadmap)
- kfree(exec_params.loadmap);
- if (interp_params.phdrs)
- kfree(interp_params.phdrs);
- if (interp_params.loadmap)
- kfree(interp_params.loadmap);
+ kfree(interpreter_name);
+ kfree(exec_params.phdrs);
+ kfree(exec_params.loadmap);
+ kfree(interp_params.phdrs);
+ kfree(interp_params.loadmap);
return retval;
/* unrecoverable error - kill the process */
diff --git a/fs/binfmt_flat.c b/fs/binfmt_flat.c
index 7974efa107bc..9d6625829b99 100644
--- a/fs/binfmt_flat.c
+++ b/fs/binfmt_flat.c
@@ -650,7 +650,6 @@ static int load_flat_file(struct linux_binprm * bprm,
current->mm->start_brk = datapos + data_len + bss_len;
current->mm->brk = (current->mm->start_brk + 3) & ~3;
current->mm->context.end_brk = memp + ksize((void *) memp) - stack_len;
- set_mm_counter(current->mm, rss, 0);
}
if (flags & FLAT_FLAG_KTRACE)
diff --git a/fs/binfmt_misc.c b/fs/binfmt_misc.c
index 8ae0db6cd69c..2568eb41cb3a 100644
--- a/fs/binfmt_misc.c
+++ b/fs/binfmt_misc.c
@@ -150,7 +150,7 @@ static int load_misc_binary(struct linux_binprm *bprm, struct pt_regs *regs)
/* if the binary is not readable than enforce mm->dumpable=0
regardless of the interpreter's permissions */
- if (permission(bprm->file->f_dentry->d_inode, MAY_READ, NULL))
+ if (file_permission(bprm->file, MAY_READ))
bprm->interp_flags |= BINPRM_FLAGS_ENFORCE_NONDUMP;
allow_write_access(bprm->file);
diff --git a/fs/binfmt_som.c b/fs/binfmt_som.c
index 227a2682d2bf..00a91dc25d16 100644
--- a/fs/binfmt_som.c
+++ b/fs/binfmt_som.c
@@ -259,7 +259,6 @@ load_som_binary(struct linux_binprm * bprm, struct pt_regs * regs)
create_som_tables(bprm);
current->mm->start_stack = bprm->p;
- set_mm_counter(current->mm, rss, 0);
#if 0
printk("(start_brk) %08lx\n" , (unsigned long) current->mm->start_brk);
diff --git a/fs/bio.c b/fs/bio.c
index 7d81a93afd48..460554b07ff9 100644
--- a/fs/bio.c
+++ b/fs/bio.c
@@ -778,7 +778,7 @@ static int bio_map_kern_endio(struct bio *bio, unsigned int bytes_done, int err)
static struct bio *__bio_map_kern(request_queue_t *q, void *data,
- unsigned int len, unsigned int gfp_mask)
+ unsigned int len, gfp_t gfp_mask)
{
unsigned long kaddr = (unsigned long)data;
unsigned long end = (kaddr + len + PAGE_SIZE - 1) >> PAGE_SHIFT;
@@ -825,7 +825,7 @@ static struct bio *__bio_map_kern(request_queue_t *q, void *data,
* device. Returns an error pointer in case of error.
*/
struct bio *bio_map_kern(request_queue_t *q, void *data, unsigned int len,
- unsigned int gfp_mask)
+ gfp_t gfp_mask)
{
struct bio *bio;
diff --git a/fs/buffer.c b/fs/buffer.c
index 1216c0d3c8ce..5287be18633b 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -96,7 +96,7 @@ static void
__clear_page_buffers(struct page *page)
{
ClearPagePrivate(page);
- page->private = 0;
+ set_page_private(page, 0);
page_cache_release(page);
}
@@ -396,7 +396,7 @@ asmlinkage long sys_fdatasync(unsigned int fd)
* private_lock is contended then so is mapping->tree_lock).
*/
static struct buffer_head *
-__find_get_block_slow(struct block_device *bdev, sector_t block, int unused)
+__find_get_block_slow(struct block_device *bdev, sector_t block)
{
struct inode *bd_inode = bdev->bd_inode;
struct address_space *bd_mapping = bd_inode->i_mapping;
@@ -502,7 +502,7 @@ static void free_more_memory(void)
yield();
for_each_pgdat(pgdat) {
- zones = pgdat->node_zonelists[GFP_NOFS&GFP_ZONEMASK].zones;
+ zones = pgdat->node_zonelists[gfp_zone(GFP_NOFS)].zones;
if (*zones)
try_to_free_pages(zones, GFP_NOFS);
}
@@ -1438,7 +1438,7 @@ __find_get_block(struct block_device *bdev, sector_t block, int size)
struct buffer_head *bh = lookup_bh_lru(bdev, block, size);
if (bh == NULL) {
- bh = __find_get_block_slow(bdev, block, size);
+ bh = __find_get_block_slow(bdev, block);
if (bh)
bh_lru_install(bh);
}
@@ -1478,8 +1478,10 @@ EXPORT_SYMBOL(__getblk);
void __breadahead(struct block_device *bdev, sector_t block, int size)
{
struct buffer_head *bh = __getblk(bdev, block, size);
- ll_rw_block(READA, 1, &bh);
- brelse(bh);
+ if (likely(bh)) {
+ ll_rw_block(READA, 1, &bh);
+ brelse(bh);
+ }
}
EXPORT_SYMBOL(__breadahead);
@@ -1497,7 +1499,7 @@ __bread(struct block_device *bdev, sector_t block, int size)
{
struct buffer_head *bh = __getblk(bdev, block, size);
- if (!buffer_uptodate(bh))
+ if (likely(bh) && !buffer_uptodate(bh))
bh = __bread_slow(bh);
return bh;
}
@@ -1571,7 +1573,7 @@ static inline void discard_buffer(struct buffer_head * bh)
*
* NOTE: @gfp_mask may go away, and this function may become non-blocking.
*/
-int try_to_release_page(struct page *page, int gfp_mask)
+int try_to_release_page(struct page *page, gfp_t gfp_mask)
{
struct address_space * const mapping = page->mapping;
@@ -1637,6 +1639,15 @@ out:
}
EXPORT_SYMBOL(block_invalidatepage);
+int do_invalidatepage(struct page *page, unsigned long offset)
+{
+ int (*invalidatepage)(struct page *, unsigned long);
+ invalidatepage = page->mapping->a_ops->invalidatepage;
+ if (invalidatepage == NULL)
+ invalidatepage = block_invalidatepage;
+ return (*invalidatepage)(page, offset);
+}
+
/*
* We attach and possibly dirty the buffers atomically wrt
* __set_page_dirty_buffers() via private_lock. try_to_free_buffers
@@ -1694,7 +1705,7 @@ void unmap_underlying_metadata(struct block_device *bdev, sector_t block)
might_sleep();
- old_bh = __find_get_block_slow(bdev, block, 0);
+ old_bh = __find_get_block_slow(bdev, block);
if (old_bh) {
clear_buffer_dirty(old_bh);
wait_on_buffer(old_bh);
@@ -2696,7 +2707,7 @@ int block_write_full_page(struct page *page, get_block_t *get_block,
* they may have been added in ext3_writepage(). Make them
* freeable here, so the page does not leak.
*/
- block_invalidatepage(page, 0);
+ do_invalidatepage(page, 0);
unlock_page(page);
return 0; /* don't care */
}
diff --git a/fs/cifs/AUTHORS b/fs/cifs/AUTHORS
index 72fdc10dfdd7..8848e4dfa026 100644
--- a/fs/cifs/AUTHORS
+++ b/fs/cifs/AUTHORS
@@ -32,6 +32,10 @@ Domen Puncer
Jesper Juhl (in particular for lots of whitespace/formatting cleanup)
Vince Negri and Dave Stahl (for finding an important caching bug)
Adrian Bunk (kcalloc cleanups)
+Miklos Szeredi
+Kazeon team for various fixes especially for 2.4 version.
+Asser Ferno (Change Notify support)
+Shaggy (Dave Kleikamp) for inumerable small fs suggestions and some good cleanup
Test case and Bug Report contributors
-------------------------------------
diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES
index 3196d4c4eed3..eab3750cf304 100644
--- a/fs/cifs/CHANGES
+++ b/fs/cifs/CHANGES
@@ -1,8 +1,52 @@
+Version 1.39
+------------
+Defer close of a file handle slightly if pending writes depend on that file handle
+(this reduces the EBADF bad file handle errors that can be logged under heavy
+stress on writes). Modify cifs Kconfig options to expose CONFIG_CIFS_STATS2
+
+Version 1.38
+------------
+Fix tcp socket retransmission timeouts (e.g. on ENOSPACE from the socket)
+to be smaller at first (but increasing) so large write performance performance
+over GigE is better. Do not hang thread on illegal byte range lock response
+from Windows (Windows can send an RFC1001 size which does not match smb size) by
+allowing an SMBs TCP length to be up to a few bytes longer than it should be.
+wsize and rsize can now be larger than negotiated buffer size if server
+supports large readx/writex, even when directio mount flag not specified.
+Write size will in many cases now be 16K instead of 4K which greatly helps
+file copy performance on lightly loaded networks. Fix oops in dnotify
+when experimental config flag enabled. Make cifsFYI more granular.
+
+Version 1.37
+------------
+Fix readdir caching when unlink removes file in current search buffer,
+and this is followed by a rewind search to just before the deleted entry.
+Do not attempt to set ctime unless atime and/or mtime change requested
+(most servers throw it away anyway). Fix length check of received smbs
+to be more accurate. Fix big endian problem with mapchars mount option,
+and with a field returned by statfs.
+
+Version 1.36
+------------
+Add support for mounting to older pre-CIFS servers such as Windows9x and ME.
+For these older servers, add option for passing netbios name of server in
+on mount (servernetbiosname). Add suspend support for power management, to
+avoid cifsd thread preventing software suspend from working.
+Add mount option for disabling the default behavior of sending byte range lock
+requests to the server (necessary for certain applications which break with
+mandatory lock behavior such as Evolution), and also mount option for
+requesting case insensitive matching for path based requests (requesting
+case sensitive is the default).
+
Version 1.35
------------
Add writepage performance improvements. Fix path name conversions
for long filenames on mounts which were done with "mapchars" mount option
-specified.
+specified. Ensure multiplex ids do not collide. Fix case in which
+rmmod can oops if done soon after last unmount. Fix truncated
+search (readdir) output when resume filename was a long filename.
+Fix filename conversion when mapchars mount option was specified and
+filename was a long filename.
Version 1.34
------------
@@ -11,7 +55,7 @@ Do not oops if root user kills cifs oplock kernel thread or
kills the cifsd thread (NB: killing the cifs kernel threads is not
recommended, unmount and rmmod cifs will kill them when they are
no longer needed). Fix readdir to ASCII servers (ie older servers
-which do not support Unicode) and also require asterik.
+which do not support Unicode) and also require asterisk.
Fix out of memory case in which data could be written one page
off in the page cache.
@@ -101,7 +145,7 @@ improperly zeroed buffer in CIFS Unix extensions set times call.
Version 1.25
------------
-Fix internationlization problem in cifs readdir with filenames that map to
+Fix internationalization problem in cifs readdir with filenames that map to
longer UTF8 strings than the string on the wire was in Unicode. Add workaround
for readdir to netapp servers. Fix search rewind (seek into readdir to return
non-consecutive entries). Do not do readdir when server negotiates
@@ -276,7 +320,7 @@ Fix caching problem when files opened by multiple clients in which
page cache could contain stale data, and write through did
not occur often enough while file was still open when read ahead
(read oplock) not allowed. Treat "sep=" when first mount option
-as an overrride of comma as the default separator between mount
+as an override of comma as the default separator between mount
options.
Version 1.01
@@ -286,7 +330,7 @@ Allow passwords longer than 16 bytes. Allow null password string.
Version 1.00
------------
Gracefully clean up failed mounts when attempting to mount to servers such as
-Windows 98 that terminate tcp sessions during prototocol negotiation. Handle
+Windows 98 that terminate tcp sessions during protocol negotiation. Handle
embedded commas in mount parsing of passwords.
Version 0.99
@@ -295,7 +339,7 @@ Invalidate local inode cached pages on oplock break and when last file
instance is closed so that the client does not continue using stale local
copy rather than later modified server copy of file. Do not reconnect
when server drops the tcp session prematurely before negotiate
-protocol response. Fix oops in roepen_file when dentry freed. Allow
+protocol response. Fix oops in reopen_file when dentry freed. Allow
the support for CIFS Unix Extensions to be disabled via proc interface.
Version 0.98
@@ -637,7 +681,7 @@ versions of 2.4 kernel (now builds and works again on kernels at least as early
Version 0.41
------------
Various minor fixes for Connectathon Posix "basic" file i/o test suite. Directory caching fixed so hardlinked
-files now return the correct rumber of links on fstat as they are repeatedly linked and unlinked.
+files now return the correct number of links on fstat as they are repeatedly linked and unlinked.
Version 0.40
------------
@@ -704,7 +748,7 @@ session)
and cleaned them up and made them more consistent with other cifs functions.
7) Server support for Unix extensions is now fully detected and FindFirst is implemented both ways
-(with or without Unix exentions) but FindNext and QueryPathInfo with the Unix extensions are not completed,
+(with or without Unix extensions) but FindNext and QueryPathInfo with the Unix extensions are not completed,
nor is the symlink support using the Unix extensions
8) Started adding the readlink and follow_link code
diff --git a/fs/cifs/README b/fs/cifs/README
index 34b0cf7111f3..bb90941826ad 100644
--- a/fs/cifs/README
+++ b/fs/cifs/README
@@ -294,8 +294,10 @@ A partial list of the supported mount options follows:
during the local client kernel build will be used.
If server does not support Unicode, this parameter is
unused.
- rsize default read size
- wsize default write size
+ rsize default read size (usually 16K)
+ wsize default write size (usually 16K, 32K is often better over GigE)
+ maximum wsize currently allowed by CIFS is 57344 (14 4096 byte
+ pages)
rw mount the network share read-write (note that the
server may still consider the share read-only)
ro mount network share read-only
@@ -407,6 +409,13 @@ A partial list of the supported mount options follows:
This has no effect if the server does not support
Unicode on the wire.
nomapchars Do not translate any of these seven characters (default).
+ nocase Request case insensitive path name matching (case
+ sensitive is the default if the server suports it).
+ nobrl Do not send byte range lock requests to the server.
+ This is necessary for certain applications that break
+ with cifs style mandatory byte range locks (and most
+ cifs servers do not yet support requesting advisory
+ byte range locks).
remount remount the share (often used to change from ro to rw mounts
or vice versa)
@@ -473,9 +482,16 @@ These experimental features and tracing can be enabled by changing flags in
kernel, e.g. insmod cifs). To enable a feature set it to 1 e.g. to enable
tracing to the kernel message log type:
- echo 1 > /proc/fs/cifs/cifsFYI
+ echo 7 > /proc/fs/cifs/cifsFYI
-and for more extensive tracing including the start of smb requests and responses
+cifsFYI functions as a bit mask. Setting it to 1 enables additional kernel
+logging of various informational messages. 2 enables logging of non-zero
+SMB return codes while 4 enables logging of requests that take longer
+than one second to complete (except for byte range lock requests).
+Setting it to 4 requires defining CONFIG_CIFS_STATS2 manually in the
+source code (typically by setting it in the beginning of cifsglob.h),
+and setting it to seven enables all three. Finally, tracing
+the start of smb requests and responses can be enabled via:
echo 1 > /proc/fs/cifs/traceSMB
diff --git a/fs/cifs/TODO b/fs/cifs/TODO
index 8cc881694e29..c909298d11ed 100644
--- a/fs/cifs/TODO
+++ b/fs/cifs/TODO
@@ -1,4 +1,4 @@
-version 1.34 April 29, 2005
+version 1.37 October 9, 2005
A Partial List of Missing Features
==================================
@@ -7,14 +7,14 @@ Contributions are welcome. There are plenty of opportunities
for visible, important contributions to this module. Here
is a partial list of the known problems and missing features:
-a) Support for SecurityDescriptors for chmod/chgrp/chown so
-these can be supported for Windows servers
+a) Support for SecurityDescriptors(Windows/CIFS ACLs) for chmod/chgrp/chown
+so that these operations can be supported to Windows servers
-b) Better pam/winbind integration (e.g. to handle uid mapping
-better)
+b) Mapping POSIX ACLs (and eventually NFSv4 ACLs) to CIFS
+SecurityDescriptors
-c) multi-user mounts - multiplexed sessionsetups over single vc
-(ie tcp session) - more testing needed
+c) Better pam/winbind integration (e.g. to handle uid mapping
+better)
d) Kerberos/SPNEGO session setup support - (started)
@@ -29,12 +29,17 @@ f) Directory entry caching relies on a 1 second timer, rather than
using FindNotify or equivalent. - (started)
g) A few byte range testcases fail due to POSIX vs. Windows/CIFS
-style byte range lock differences
+style byte range lock differences. Save byte range locks so
+reconnect can replay them.
-h) quota support
+h) Support unlock all (unlock 0,MAX_OFFSET)
+by unlocking all known byte range locks that we locked on the file.
-j) finish writepages support (multi-page write behind for improved
-performance) and syncpage
+i) quota support (needs minor kernel change since quota calls
+to make it to network filesystems or deviceless filesystems)
+
+j) investigate sync behavior (including syncpage) and check
+for proper behavior of intr/nointr
k) hook lower into the sockets api (as NFS/SunRPC does) to avoid the
extra copy in/out of the socket buffers in some cases.
@@ -57,20 +62,18 @@ p) Add support for storing symlink and fifo info to Windows servers
in the Extended Attribute format their SFU clients would recognize.
q) Finish fcntl D_NOTIFY support so kde and gnome file list windows
-will autorefresh (started)
+will autorefresh (partially complete by Asser). Needs minor kernel
+vfs change to support removing D_NOTIFY on a file.
r) Add GUI tool to configure /proc/fs/cifs settings and for display of
the CIFS statistics (started)
-q) implement support for security and trusted categories of xattrs
+s) implement support for security and trusted categories of xattrs
(requires minor protocol extension) to enable better support for SELINUX
-r) Implement O_DIRECT flag on open (already supported on mount)
-
-s) Allow remapping of last remaining character (\) to +0xF000 which
-(this character is valid for POSIX but not for Windows)
+t) Implement O_DIRECT flag on open (already supported on mount)
-t) Create UID mapping facility so server UIDs can be mapped on a per
+u) Create UID mapping facility so server UIDs can be mapped on a per
mount or a per server basis to client UIDs or nobody if no mapping
exists. This is helpful when Unix extensions are negotiated to
allow better permission checking when UIDs differ on the server
@@ -78,6 +81,17 @@ and client. Add new protocol request to the CIFS protocol
standard for asking the server for the corresponding name of a
particular uid.
+v) Add support for CIFS Unix and also the newer POSIX extensions to the
+server side for Samba 4.
+
+w) Finish up the dos time conversion routines needed to return old server
+time to the client (default time, of now or time 0 is used now for these
+very old servers)
+
+x) Add support for OS/2 (LANMAN 1.2 and LANMAN2.1 based SMB servers)
+
+y) Finish testing of Windows 9x/Windows ME server support (started).
+
KNOWN BUGS (updated April 29, 2005)
====================================
See http://bugzilla.samba.org - search on product "CifsVFS" for
diff --git a/fs/cifs/asn1.c b/fs/cifs/asn1.c
index e02010dd73ec..086ae8f4a207 100644
--- a/fs/cifs/asn1.c
+++ b/fs/cifs/asn1.c
@@ -191,7 +191,8 @@ asn1_header_decode(struct asn1_ctx *ctx,
unsigned char **eoc,
unsigned int *cls, unsigned int *con, unsigned int *tag)
{
- unsigned int def, len;
+ unsigned int def = 0;
+ unsigned int len = 0;
if (!asn1_id_decode(ctx, cls, con, tag))
return 0;
@@ -552,8 +553,7 @@ decode_negTokenInit(unsigned char *security_blob, int length,
*(oid + 3)));
rc = compare_oid(oid, oidlen, NTLMSSP_OID,
NTLMSSP_OID_LEN);
- if(oid)
- kfree(oid);
+ kfree(oid);
if (rc)
use_ntlmssp = TRUE;
}
diff --git a/fs/cifs/cifs_debug.c b/fs/cifs/cifs_debug.c
index 4061e43471c1..22a444a3fe4c 100644
--- a/fs/cifs/cifs_debug.c
+++ b/fs/cifs/cifs_debug.c
@@ -81,6 +81,8 @@ cifs_debug_data_read(char *buf, char **beginBuffer, off_t offset,
buf += length;
length = sprintf(buf,"CIFS Version %s\n",CIFS_VERSION);
buf += length;
+ length = sprintf(buf,"Active VFS Requests: %d\n", GlobalTotalActiveXid);
+ buf += length;
length = sprintf(buf, "Servers:");
buf += length;
@@ -97,7 +99,7 @@ cifs_debug_data_read(char *buf, char **beginBuffer, off_t offset,
} else {
length =
sprintf(buf,
- "\n%d) Name: %s Domain: %s Mounts: %d ServerOS: %s \n\tServerNOS: %s\tCapabilities: 0x%x\n\tSMB session status: %d\t",
+ "\n%d) Name: %s Domain: %s Mounts: %d OS: %s \n\tNOS: %s\tCapability: 0x%x\n\tSMB session status: %d\t",
i, ses->serverName, ses->serverDomain,
atomic_read(&ses->inUse),
ses->serverOS, ses->serverNOS,
@@ -105,12 +107,18 @@ cifs_debug_data_read(char *buf, char **beginBuffer, off_t offset,
buf += length;
}
if(ses->server) {
- buf += sprintf(buf, "TCP status: %d\n\tLocal Users To Server: %d SecMode: 0x%x Req Active: %d",
+ buf += sprintf(buf, "TCP status: %d\n\tLocal Users To Server: %d SecMode: 0x%x Req On Wire: %d",
ses->server->tcpStatus,
atomic_read(&ses->server->socketUseCount),
ses->server->secMode,
atomic_read(&ses->server->inFlight));
-
+
+#ifdef CONFIG_CIFS_STATS2
+ buf += sprintf(buf, " In Send: %d In MaxReq Wait: %d",
+ atomic_read(&ses->server->inSend),
+ atomic_read(&ses->server->num_waiters));
+#endif
+
length = sprintf(buf, "\nMIDs:\n");
buf += length;
@@ -149,7 +157,7 @@ cifs_debug_data_read(char *buf, char **beginBuffer, off_t offset,
dev_type = le32_to_cpu(tcon->fsDevInfo.DeviceType);
length =
sprintf(buf,
- "\n%d) %s Uses: %d Type: %s Characteristics: 0x%x Attributes: 0x%x\nPathComponentMax: %d Status: %d",
+ "\n%d) %s Uses: %d Type: %s DevInfo: 0x%x Attributes: 0x%x\nPathComponentMax: %d Status: %d",
i, tcon->treeName,
atomic_read(&tcon->useCount),
tcon->nativeFileSystem,
@@ -195,6 +203,49 @@ cifs_debug_data_read(char *buf, char **beginBuffer, off_t offset,
}
#ifdef CONFIG_CIFS_STATS
+
+static int
+cifs_stats_write(struct file *file, const char __user *buffer,
+ unsigned long count, void *data)
+{
+ char c;
+ int rc;
+ struct list_head *tmp;
+ struct cifsTconInfo *tcon;
+
+ rc = get_user(c, buffer);
+ if (rc)
+ return rc;
+
+ if (c == '1' || c == 'y' || c == 'Y' || c == '0') {
+ read_lock(&GlobalSMBSeslock);
+ list_for_each(tmp, &GlobalTreeConnectionList) {
+ tcon = list_entry(tmp, struct cifsTconInfo,
+ cifsConnectionList);
+ atomic_set(&tcon->num_smbs_sent, 0);
+ atomic_set(&tcon->num_writes, 0);
+ atomic_set(&tcon->num_reads, 0);
+ atomic_set(&tcon->num_oplock_brks, 0);
+ atomic_set(&tcon->num_opens, 0);
+ atomic_set(&tcon->num_closes, 0);
+ atomic_set(&tcon->num_deletes, 0);
+ atomic_set(&tcon->num_mkdirs, 0);
+ atomic_set(&tcon->num_rmdirs, 0);
+ atomic_set(&tcon->num_renames, 0);
+ atomic_set(&tcon->num_t2renames, 0);
+ atomic_set(&tcon->num_ffirst, 0);
+ atomic_set(&tcon->num_fnext, 0);
+ atomic_set(&tcon->num_fclose, 0);
+ atomic_set(&tcon->num_hardlinks, 0);
+ atomic_set(&tcon->num_symlinks, 0);
+ atomic_set(&tcon->num_locks, 0);
+ }
+ read_unlock(&GlobalSMBSeslock);
+ }
+
+ return count;
+}
+
static int
cifs_stats_read(char *buf, char **beginBuffer, off_t offset,
int count, int *eof, void *data)
@@ -254,35 +305,51 @@ cifs_stats_read(char *buf, char **beginBuffer, off_t offset,
buf += sprintf(buf, "\tDISCONNECTED ");
length += 14;
}
- item_length = sprintf(buf,"\nSMBs: %d Oplock Breaks: %d",
+ item_length = sprintf(buf, "\nSMBs: %d Oplock Breaks: %d",
atomic_read(&tcon->num_smbs_sent),
atomic_read(&tcon->num_oplock_brks));
buf += item_length;
length += item_length;
- item_length = sprintf(buf,"\nReads: %d Bytes %lld",
+ item_length = sprintf(buf, "\nReads: %d Bytes: %lld",
atomic_read(&tcon->num_reads),
(long long)(tcon->bytes_read));
buf += item_length;
length += item_length;
- item_length = sprintf(buf,"\nWrites: %d Bytes: %lld",
+ item_length = sprintf(buf, "\nWrites: %d Bytes: %lld",
atomic_read(&tcon->num_writes),
(long long)(tcon->bytes_written));
+ buf += item_length;
+ length += item_length;
+ item_length = sprintf(buf,
+ "\nLocks: %d HardLinks: %d Symlinks: %d",
+ atomic_read(&tcon->num_locks),
+ atomic_read(&tcon->num_hardlinks),
+ atomic_read(&tcon->num_symlinks));
+ buf += item_length;
+ length += item_length;
+
+ item_length = sprintf(buf, "\nOpens: %d Closes: %d Deletes: %d",
+ atomic_read(&tcon->num_opens),
+ atomic_read(&tcon->num_closes),
+ atomic_read(&tcon->num_deletes));
buf += item_length;
length += item_length;
- item_length = sprintf(buf,
- "\nOpens: %d Deletes: %d\nMkdirs: %d Rmdirs: %d",
- atomic_read(&tcon->num_opens),
- atomic_read(&tcon->num_deletes),
+ item_length = sprintf(buf, "\nMkdirs: %d Rmdirs: %d",
atomic_read(&tcon->num_mkdirs),
atomic_read(&tcon->num_rmdirs));
buf += item_length;
length += item_length;
- item_length = sprintf(buf,
- "\nRenames: %d T2 Renames %d",
+ item_length = sprintf(buf, "\nRenames: %d T2 Renames %d",
atomic_read(&tcon->num_renames),
atomic_read(&tcon->num_t2renames));
buf += item_length;
length += item_length;
+ item_length = sprintf(buf, "\nFindFirst: %d FNext %d FClose %d",
+ atomic_read(&tcon->num_ffirst),
+ atomic_read(&tcon->num_fnext),
+ atomic_read(&tcon->num_fclose));
+ buf += item_length;
+ length += item_length;
}
read_unlock(&GlobalSMBSeslock);
@@ -341,8 +408,10 @@ cifs_proc_init(void)
cifs_debug_data_read, NULL);
#ifdef CONFIG_CIFS_STATS
- create_proc_read_entry("Stats", 0, proc_fs_cifs,
+ pde = create_proc_read_entry("Stats", 0, proc_fs_cifs,
cifs_stats_read, NULL);
+ if (pde)
+ pde->write_proc = cifs_stats_write;
#endif
pde = create_proc_read_entry("cifsFYI", 0, proc_fs_cifs,
cifsFYI_read, NULL);
@@ -360,7 +429,7 @@ cifs_proc_init(void)
if (pde)
pde->write_proc = oplockEnabled_write;
- pde = create_proc_read_entry("ReenableOldCifsReaddirCode", 0, proc_fs_cifs,
+ pde = create_proc_read_entry("Experimental", 0, proc_fs_cifs,
quotaEnabled_read, NULL);
if (pde)
pde->write_proc = quotaEnabled_write;
@@ -419,7 +488,7 @@ cifs_proc_clean(void)
remove_proc_entry("ExtendedSecurity",proc_fs_cifs);
remove_proc_entry("PacketSigningEnabled",proc_fs_cifs);
remove_proc_entry("LinuxExtensionsEnabled",proc_fs_cifs);
- remove_proc_entry("ReenableOldCifsReaddirCode",proc_fs_cifs);
+ remove_proc_entry("Experimental",proc_fs_cifs);
remove_proc_entry("LookupCacheEnabled",proc_fs_cifs);
remove_proc_entry("cifs", proc_root_fs);
}
@@ -459,6 +528,8 @@ cifsFYI_write(struct file *file, const char __user *buffer,
cifsFYI = 0;
else if (c == '1' || c == 'y' || c == 'Y')
cifsFYI = 1;
+ else if((c > '1') && (c <= '9'))
+ cifsFYI = (int) (c - '0'); /* see cifs_debug.h for meanings */
return count;
}
diff --git a/fs/cifs/cifs_debug.h b/fs/cifs/cifs_debug.h
index bf24d2828f68..4304d9dcfb6c 100644
--- a/fs/cifs/cifs_debug.h
+++ b/fs/cifs/cifs_debug.h
@@ -26,6 +26,9 @@
void cifs_dump_mem(char *label, void *data, int length);
extern int traceSMB; /* flag which enables the function below */
void dump_smb(struct smb_hdr *, int);
+#define CIFS_INFO 0x01
+#define CIFS_RC 0x02
+#define CIFS_TIMER 0x04
/*
* debug ON
@@ -36,7 +39,7 @@ void dump_smb(struct smb_hdr *, int);
/* information message: e.g., configuration, major event */
extern int cifsFYI;
-#define cifsfyi(format,arg...) if (cifsFYI) printk(KERN_DEBUG " " __FILE__ ": " format "\n" "" , ## arg)
+#define cifsfyi(format,arg...) if (cifsFYI & CIFS_INFO) printk(KERN_DEBUG " " __FILE__ ": " format "\n" "" , ## arg)
#define cFYI(button,prspec) if (button) cifsfyi prspec
diff --git a/fs/cifs/cifs_fs_sb.h b/fs/cifs/cifs_fs_sb.h
index ec00d61d5308..f799f6f0e729 100644
--- a/fs/cifs/cifs_fs_sb.h
+++ b/fs/cifs/cifs_fs_sb.h
@@ -24,6 +24,9 @@
#define CIFS_MOUNT_DIRECT_IO 8 /* do not write nor read through page cache */
#define CIFS_MOUNT_NO_XATTR 0x10 /* if set - disable xattr support */
#define CIFS_MOUNT_MAP_SPECIAL_CHR 0x20 /* remap illegal chars in filenames */
+#define CIFS_MOUNT_POSIX_PATHS 0x40 /* Negotiate posix pathnames if possible. */
+#define CIFS_MOUNT_UNX_EMUL 0x80 /* Network compat with SFUnix emulation */
+#define CIFS_MOUNT_NO_BRL 0x100 /* No sending byte range locks to srv */
struct cifs_sb_info {
struct cifsTconInfo *tcon; /* primary mount */
diff --git a/fs/cifs/cifs_unicode.c b/fs/cifs/cifs_unicode.c
index 99a096d3f84d..4e12053f0806 100644
--- a/fs/cifs/cifs_unicode.c
+++ b/fs/cifs/cifs_unicode.c
@@ -74,10 +74,11 @@ cifs_strtoUCS(wchar_t * to, const char *from, int len,
cERROR(1,
("cifs_strtoUCS: char2uni returned %d",
charlen));
- to[i] = cpu_to_le16(0x003f); /* a question mark */
+ /* A question mark */
+ to[i] = (wchar_t)cpu_to_le16(0x003f);
charlen = 1;
} else
- to[i] = cpu_to_le16(to[i]);
+ to[i] = (wchar_t)cpu_to_le16(to[i]);
}
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index 1ebf7dafc1d7..682b0235ad9a 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -59,6 +59,8 @@ unsigned int ntlmv2_support = 0;
unsigned int sign_CIFS_PDUs = 1;
extern struct task_struct * oplockThread; /* remove sparse warning */
struct task_struct * oplockThread = NULL;
+extern struct task_struct * dnotifyThread; /* remove sparse warning */
+struct task_struct * dnotifyThread = NULL;
unsigned int CIFSMaxBufSize = CIFS_MAX_MSGSIZE;
module_param(CIFSMaxBufSize, int, 0);
MODULE_PARM_DESC(CIFSMaxBufSize,"Network buffer size (not including header). Default: 16384 Range: 8192 to 130048");
@@ -73,6 +75,7 @@ module_param(cifs_max_pending, int, 0);
MODULE_PARM_DESC(cifs_max_pending,"Simultaneous requests to server. Default: 50 Range: 2 to 256");
static DECLARE_COMPLETION(cifs_oplock_exited);
+static DECLARE_COMPLETION(cifs_dnotify_exited);
extern mempool_t *cifs_sm_req_poolp;
extern mempool_t *cifs_req_poolp;
@@ -202,6 +205,10 @@ cifs_statfs(struct super_block *sb, struct kstatfs *buf)
#endif /* CIFS_EXPERIMENTAL */
rc = CIFSSMBQFSInfo(xid, pTcon, buf);
+ /* Old Windows servers do not support level 103, retry with level
+ one if old server failed the previous call */
+ if(rc)
+ rc = SMBOldQFSInfo(xid, pTcon, buf);
/*
int f_type;
__fsid_t f_fsid;
@@ -253,7 +260,7 @@ cifs_alloc_inode(struct super_block *sb)
cifs_inode->clientCanCacheAll = FALSE;
cifs_inode->vfs_inode.i_blksize = CIFS_MAX_MSGSIZE;
cifs_inode->vfs_inode.i_blkbits = 14; /* 2**14 = CIFS_MAX_MSGSIZE */
-
+ cifs_inode->vfs_inode.i_flags = S_NOATIME | S_NOCMTIME;
INIT_LIST_HEAD(&cifs_inode->openFileList);
return &cifs_inode->vfs_inode;
}
@@ -398,6 +405,37 @@ static struct quotactl_ops cifs_quotactl_ops = {
};
#endif
+#ifdef CONFIG_CIFS_EXPERIMENTAL
+static void cifs_umount_begin(struct super_block * sblock)
+{
+ struct cifs_sb_info *cifs_sb;
+ struct cifsTconInfo * tcon;
+
+ cifs_sb = CIFS_SB(sblock);
+ if(cifs_sb == NULL)
+ return;
+
+ tcon = cifs_sb->tcon;
+ if(tcon == NULL)
+ return;
+ down(&tcon->tconSem);
+ if (atomic_read(&tcon->useCount) == 1)
+ tcon->tidStatus = CifsExiting;
+ up(&tcon->tconSem);
+
+ /* cancel_brl_requests(tcon); */
+ /* cancel_notify_requests(tcon); */
+ if(tcon->ses && tcon->ses->server)
+ {
+ cFYI(1,("wake up tasks now - umount begin not complete"));
+ wake_up_all(&tcon->ses->server->request_q);
+ }
+/* BB FIXME - finish add checks for tidStatus BB */
+
+ return;
+}
+#endif
+
static int cifs_remount(struct super_block *sb, int *flags, char *data)
{
*flags |= MS_NODIRATIME;
@@ -415,7 +453,9 @@ struct super_operations cifs_super_ops = {
unless later we add lazy close of inodes or unless the kernel forgets to call
us with the same number of releases (closes) as opens */
.show_options = cifs_show_options,
-/* .umount_begin = cifs_umount_begin, *//* consider adding in the future */
+#ifdef CONFIG_CIFS_EXPERIMENTAL
+ .umount_begin = cifs_umount_begin,
+#endif
.remount_fs = cifs_remount,
};
@@ -783,9 +823,7 @@ static int cifs_oplock_thread(void * dummyarg)
do {
if (try_to_freeze())
continue;
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(1*HZ);
spin_lock(&GlobalMid_Lock);
if(list_empty(&GlobalOplock_Q)) {
spin_unlock(&GlobalMid_Lock);
@@ -834,10 +872,27 @@ static int cifs_oplock_thread(void * dummyarg)
}
} else
spin_unlock(&GlobalMid_Lock);
+ set_current_state(TASK_INTERRUPTIBLE);
+ schedule_timeout(1); /* yield in case q were corrupt */
}
} while(!signal_pending(current));
- complete_and_exit (&cifs_oplock_exited, 0);
oplockThread = NULL;
+ complete_and_exit (&cifs_oplock_exited, 0);
+}
+
+static int cifs_dnotify_thread(void * dummyarg)
+{
+ daemonize("cifsdnotifyd");
+ allow_signal(SIGTERM);
+
+ dnotifyThread = current;
+ do {
+ if(try_to_freeze())
+ continue;
+ set_current_state(TASK_INTERRUPTIBLE);
+ schedule_timeout(39*HZ);
+ } while(!signal_pending(current));
+ complete_and_exit (&cifs_dnotify_exited, 0);
}
static int __init
@@ -851,6 +906,10 @@ init_cifs(void)
INIT_LIST_HEAD(&GlobalSMBSessionList);
INIT_LIST_HEAD(&GlobalTreeConnectionList);
INIT_LIST_HEAD(&GlobalOplock_Q);
+#ifdef CONFIG_CIFS_EXPERIMENTAL
+ INIT_LIST_HEAD(&GlobalDnotifyReqList);
+ INIT_LIST_HEAD(&GlobalDnotifyRsp_Q);
+#endif
/*
* Initialize Global counters
*/
@@ -886,10 +945,16 @@ init_cifs(void)
if (!rc) {
rc = (int)kernel_thread(cifs_oplock_thread, NULL,
CLONE_FS | CLONE_FILES | CLONE_VM);
- if(rc > 0)
- return 0;
- else
+ if(rc > 0) {
+ rc = (int)kernel_thread(cifs_dnotify_thread, NULL,
+ CLONE_FS | CLONE_FILES | CLONE_VM);
+ if(rc > 0)
+ return 0;
+ else
+ cERROR(1,("error %d create dnotify thread", rc));
+ } else {
cERROR(1,("error %d create oplock thread",rc));
+ }
}
cifs_destroy_request_bufs();
}
@@ -918,6 +983,10 @@ exit_cifs(void)
send_sig(SIGTERM, oplockThread, 1);
wait_for_completion(&cifs_oplock_exited);
}
+ if(dnotifyThread) {
+ send_sig(SIGTERM, dnotifyThread, 1);
+ wait_for_completion(&cifs_dnotify_exited);
+ }
}
MODULE_AUTHOR("Steve French <sfrench@us.ibm.com>");
diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h
index 1fd21f66f243..1223fa81dbd2 100644
--- a/fs/cifs/cifsfs.h
+++ b/fs/cifs/cifsfs.h
@@ -81,6 +81,7 @@ extern int cifs_dir_notify(struct file *, unsigned long arg);
/* Functions related to dir entries */
extern struct dentry_operations cifs_dentry_ops;
+extern struct dentry_operations cifs_ci_dentry_ops;
/* Functions related to symlinks */
extern void *cifs_follow_link(struct dentry *direntry, struct nameidata *nd);
@@ -96,5 +97,5 @@ extern ssize_t cifs_getxattr(struct dentry *, const char *, void *, size_t);
extern ssize_t cifs_listxattr(struct dentry *, char *, size_t);
extern int cifs_ioctl (struct inode * inode, struct file * filep,
unsigned int command, unsigned long arg);
-#define CIFS_VERSION "1.35"
+#define CIFS_VERSION "1.39"
#endif /* _CIFSFS_H */
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index 81babab265e1..1ba08f8c5bc4 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -110,8 +110,9 @@ enum protocolEnum {
*/
struct TCP_Server_Info {
- char server_Name[SERVER_NAME_LEN_WITH_NULL]; /* 15 chars + X'20'in 16th */
- char unicode_server_Name[SERVER_NAME_LEN_WITH_NULL * 2]; /* Unicode version of server_Name */
+ /* 15 character server name + 0x20 16th byte indicating type = srv */
+ char server_RFC1001_name[SERVER_NAME_LEN_WITH_NULL];
+ char unicode_server_Name[SERVER_NAME_LEN_WITH_NULL * 2];
struct socket *ssocket;
union {
struct sockaddr_in sockAddr;
@@ -122,13 +123,17 @@ struct TCP_Server_Info {
struct list_head pending_mid_q;
void *Server_NlsInfo; /* BB - placeholder for future NLS info */
unsigned short server_codepage; /* codepage for the server */
- unsigned long ip_address; /* IP addr for the server if known */
+ unsigned long ip_address; /* IP addr for the server if known */
enum protocolEnum protocolType;
char versionMajor;
char versionMinor;
unsigned svlocal:1; /* local server or remote */
atomic_t socketUseCount; /* number of open cifs sessions on socket */
atomic_t inFlight; /* number of requests on the wire to server */
+#ifdef CONFIG_CIFS_STATS2
+ atomic_t inSend; /* requests trying to send */
+ atomic_t num_waiters; /* blocked waiting to get in sendrecv */
+#endif
enum statusEnum tcpStatus; /* what we think the status is */
struct semaphore tcpSem;
struct task_struct *tsk;
@@ -147,8 +152,10 @@ struct TCP_Server_Info {
/* (returned on Negotiate */
int capabilities; /* allow selective disabling of caps by smb sess */
__u16 timeZone;
+ __u16 CurrentMid; /* multiplex id - rotating counter */
char cryptKey[CIFS_CRYPTO_KEY_SIZE];
- char workstation_RFC1001_name[16]; /* 16th byte is always zero */
+ /* 16th byte of RFC1001 workstation name is always null */
+ char workstation_RFC1001_name[SERVER_NAME_LEN_WITH_NULL];
__u32 sequence_number; /* needed for CIFS PDU signature */
char mac_signing_key[CIFS_SESSION_KEY_SIZE + 16];
};
@@ -214,19 +221,41 @@ struct cifsTconInfo {
atomic_t num_reads;
atomic_t num_oplock_brks;
atomic_t num_opens;
+ atomic_t num_closes;
atomic_t num_deletes;
atomic_t num_mkdirs;
atomic_t num_rmdirs;
atomic_t num_renames;
atomic_t num_t2renames;
+ atomic_t num_ffirst;
+ atomic_t num_fnext;
+ atomic_t num_fclose;
+ atomic_t num_hardlinks;
+ atomic_t num_symlinks;
+ atomic_t num_locks;
+#ifdef CONFIG_CIFS_STATS2
+ unsigned long long time_writes;
+ unsigned long long time_reads;
+ unsigned long long time_opens;
+ unsigned long long time_deletes;
+ unsigned long long time_closes;
+ unsigned long long time_mkdirs;
+ unsigned long long time_rmdirs;
+ unsigned long long time_renames;
+ unsigned long long time_t2renames;
+ unsigned long long time_ffirst;
+ unsigned long long time_fnext;
+ unsigned long long time_fclose;
+#endif /* CONFIG_CIFS_STATS2 */
__u64 bytes_read;
__u64 bytes_written;
spinlock_t stat_lock;
-#endif
+#endif /* CONFIG_CIFS_STATS */
FILE_SYSTEM_DEVICE_INFO fsDevInfo;
FILE_SYSTEM_ATTRIBUTE_INFO fsAttrInfo; /* ok if file system name truncated */
FILE_SYSTEM_UNIX_INFO fsUnixInfo;
unsigned retry:1;
+ unsigned nocase:1;
/* BB add field for back pointer to sb struct? */
};
@@ -270,6 +299,7 @@ struct cifsFileInfo {
struct inode * pInode; /* needed for oplock break */
unsigned closePend:1; /* file is marked to close */
unsigned invalidHandle:1; /* file closed via session abend */
+ atomic_t wrtPending; /* handle in use - defer close */
struct semaphore fh_sem; /* prevents reopen race after dead ses*/
char * search_resume_name; /* BB removeme BB */
unsigned int resume_name_length; /* BB removeme - field renamed and moved BB */
@@ -306,6 +336,41 @@ CIFS_SB(struct super_block *sb)
return sb->s_fs_info;
}
+static inline char CIFS_DIR_SEP(const struct cifs_sb_info *cifs_sb)
+{
+ if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS)
+ return '/';
+ else
+ return '\\';
+}
+
+#ifdef CONFIG_CIFS_STATS
+#define cifs_stats_inc atomic_inc
+
+static inline void cifs_stats_bytes_written(struct cifsTconInfo *tcon,
+ unsigned int bytes)
+{
+ if (bytes) {
+ spin_lock(&tcon->stat_lock);
+ tcon->bytes_written += bytes;
+ spin_unlock(&tcon->stat_lock);
+ }
+}
+
+static inline void cifs_stats_bytes_read(struct cifsTconInfo *tcon,
+ unsigned int bytes)
+{
+ spin_lock(&tcon->stat_lock);
+ tcon->bytes_read += bytes;
+ spin_unlock(&tcon->stat_lock);
+}
+#else
+
+#define cifs_stats_inc(field) do {} while(0)
+#define cifs_stats_bytes_written(tcon, bytes) do {} while(0)
+#define cifs_stats_bytes_read(tcon, bytes) do {} while(0)
+
+#endif
/* one of these for every pending CIFS request to the server */
struct mid_q_entry {
@@ -313,7 +378,11 @@ struct mid_q_entry {
__u16 mid; /* multiplex id */
__u16 pid; /* process id */
__u32 sequence_number; /* for CIFS signing */
- struct timeval when_sent; /* time when smb sent */
+ unsigned long when_alloc; /* when mid was created */
+#ifdef CONFIG_CIFS_STATS2
+ unsigned long when_sent; /* time when smb send finished */
+ unsigned long when_received; /* when demux complete (taken off wire) */
+#endif
struct cifsSesInfo *ses; /* smb was sent to this server */
struct task_struct *tsk; /* task waiting for response */
struct smb_hdr *resp_buf; /* response buffer */
@@ -331,6 +400,20 @@ struct oplock_q_entry {
__u16 netfid;
};
+/* for pending dnotify requests */
+struct dir_notify_req {
+ struct list_head lhead;
+ __le16 Pid;
+ __le16 PidHigh;
+ __u16 Mid;
+ __u16 Tid;
+ __u16 Uid;
+ __u16 netfid;
+ __u32 filter; /* CompletionFilter (for multishot) */
+ int multishot;
+ struct file * pfile;
+};
+
#define MID_FREE 0
#define MID_REQUEST_ALLOCATED 1
#define MID_REQUEST_SUBMITTED 2
@@ -399,6 +482,9 @@ GLOBAL_EXTERN rwlock_t GlobalSMBSeslock; /* protects list inserts on 3 above */
GLOBAL_EXTERN struct list_head GlobalOplock_Q;
+GLOBAL_EXTERN struct list_head GlobalDnotifyReqList; /* Outstanding dir notify requests */
+GLOBAL_EXTERN struct list_head GlobalDnotifyRsp_Q; /* Dir notify response queue */
+
/*
* Global transaction id (XID) information
*/
diff --git a/fs/cifs/cifspdu.h b/fs/cifs/cifspdu.h
index aede6a813167..48a05b9df7eb 100644
--- a/fs/cifs/cifspdu.h
+++ b/fs/cifs/cifspdu.h
@@ -36,9 +36,11 @@
#define SMB_COM_CLOSE 0x04 /* triv req/rsp, timestamp ignored */
#define SMB_COM_DELETE 0x06 /* trivial response */
#define SMB_COM_RENAME 0x07 /* trivial response */
+#define SMB_COM_QUERY_INFORMATION 0x08 /* aka getattr */
#define SMB_COM_SETATTR 0x09 /* trivial response */
#define SMB_COM_LOCKING_ANDX 0x24 /* trivial response */
#define SMB_COM_COPY 0x29 /* trivial rsp, fail filename ignrd*/
+#define SMB_COM_OPEN_ANDX 0x2D /* Legacy open for old servers */
#define SMB_COM_READ_ANDX 0x2E
#define SMB_COM_WRITE_ANDX 0x2F
#define SMB_COM_TRANSACTION2 0x32
@@ -52,6 +54,7 @@
#define SMB_COM_NT_TRANSACT 0xA0
#define SMB_COM_NT_TRANSACT_SECONDARY 0xA1
#define SMB_COM_NT_CREATE_ANDX 0xA2
+#define SMB_COM_NT_CANCEL 0xA4 /* no response */
#define SMB_COM_NT_RENAME 0xA5 /* trivial response */
/* Transact2 subcommand codes */
@@ -59,6 +62,7 @@
#define TRANS2_FIND_FIRST 0x01
#define TRANS2_FIND_NEXT 0x02
#define TRANS2_QUERY_FS_INFORMATION 0x03
+#define TRANS2_SET_FS_INFORMATION 0x04
#define TRANS2_QUERY_PATH_INFORMATION 0x05
#define TRANS2_SET_PATH_INFORMATION 0x06
#define TRANS2_QUERY_FILE_INFORMATION 0x07
@@ -76,7 +80,7 @@
#define NT_TRANSACT_GET_USER_QUOTA 0x07
#define NT_TRANSACT_SET_USER_QUOTA 0x08
-#define MAX_CIFS_HDR_SIZE 256 /* chained NTCreateXReadX will probably be biggest */
+#define MAX_CIFS_HDR_SIZE 256 /* is future chained NTCreateXReadX bigger? */
/* internal cifs vfs structures */
/*****************************************************************
@@ -129,10 +133,11 @@
/*
* SMB flag definitions
*/
-#define SMBFLG_EXTD_LOCK 0x01 /* server supports lock-read write-unlock primitives */
+#define SMBFLG_EXTD_LOCK 0x01 /* server supports lock-read write-unlock smb */
#define SMBFLG_RCV_POSTED 0x02 /* obsolete */
#define SMBFLG_RSVD 0x04
-#define SMBFLG_CASELESS 0x08 /* all pathnames treated as caseless (off implies case sensitive file handling requested) */
+#define SMBFLG_CASELESS 0x08 /* all pathnames treated as caseless (off
+ implies case sensitive file handling request) */
#define SMBFLG_CANONICAL_PATH_FORMAT 0x10 /* obsolete */
#define SMBFLG_OLD_OPLOCK 0x20 /* obsolete */
#define SMBFLG_OLD_OPLOCK_NOTIFY 0x40 /* obsolete */
@@ -141,7 +146,8 @@
/*
* SMB flag2 definitions
*/
-#define SMBFLG2_KNOWS_LONG_NAMES cpu_to_le16(1) /* can send long (non-8.3) path names in response */
+#define SMBFLG2_KNOWS_LONG_NAMES cpu_to_le16(1) /* can send long (non-8.3)
+ path names in response */
#define SMBFLG2_KNOWS_EAS cpu_to_le16(2)
#define SMBFLG2_SECURITY_SIGNATURE cpu_to_le16(4)
#define SMBFLG2_IS_LONG_NAME cpu_to_le16(0x40)
@@ -160,32 +166,32 @@
* file and can have any suitable combination of the following values:
*/
-#define FILE_READ_DATA 0x00000001 /* Data can be read from the file */
-#define FILE_WRITE_DATA 0x00000002 /* Data can be written to the file */
-#define FILE_APPEND_DATA 0x00000004 /* Data can be appended to the file */
-#define FILE_READ_EA 0x00000008 /* Extended attributes associated */
- /* with the file can be read */
-#define FILE_WRITE_EA 0x00000010 /* Extended attributes associated */
- /* with the file can be written */
-#define FILE_EXECUTE 0x00000020 /*Data can be read into memory from */
- /* the file using system paging I/O */
+#define FILE_READ_DATA 0x00000001 /* Data can be read from the file */
+#define FILE_WRITE_DATA 0x00000002 /* Data can be written to the file */
+#define FILE_APPEND_DATA 0x00000004 /* Data can be appended to the file */
+#define FILE_READ_EA 0x00000008 /* Extended attributes associated */
+ /* with the file can be read */
+#define FILE_WRITE_EA 0x00000010 /* Extended attributes associated */
+ /* with the file can be written */
+#define FILE_EXECUTE 0x00000020 /*Data can be read into memory from */
+ /* the file using system paging I/O */
#define FILE_DELETE_CHILD 0x00000040
-#define FILE_READ_ATTRIBUTES 0x00000080 /* Attributes associated with the */
- /* file can be read */
-#define FILE_WRITE_ATTRIBUTES 0x00000100 /* Attributes associated with the */
- /* file can be written */
-#define DELETE 0x00010000 /* The file can be deleted */
-#define READ_CONTROL 0x00020000 /* The access control list and */
- /* ownership associated with the */
- /* file can be read */
-#define WRITE_DAC 0x00040000 /* The access control list and */
- /* ownership associated with the */
- /* file can be written. */
-#define WRITE_OWNER 0x00080000 /* Ownership information associated */
- /* with the file can be written */
-#define SYNCHRONIZE 0x00100000 /* The file handle can waited on to */
- /* synchronize with the completion */
- /* of an input/output request */
+#define FILE_READ_ATTRIBUTES 0x00000080 /* Attributes associated with the */
+ /* file can be read */
+#define FILE_WRITE_ATTRIBUTES 0x00000100 /* Attributes associated with the */
+ /* file can be written */
+#define DELETE 0x00010000 /* The file can be deleted */
+#define READ_CONTROL 0x00020000 /* The access control list and */
+ /* ownership associated with the */
+ /* file can be read */
+#define WRITE_DAC 0x00040000 /* The access control list and */
+ /* ownership associated with the */
+ /* file can be written. */
+#define WRITE_OWNER 0x00080000 /* Ownership information associated */
+ /* with the file can be written */
+#define SYNCHRONIZE 0x00100000 /* The file handle can waited on to */
+ /* synchronize with the completion */
+ /* of an input/output request */
#define GENERIC_ALL 0x10000000
#define GENERIC_EXECUTE 0x20000000
#define GENERIC_WRITE 0x40000000
@@ -193,7 +199,7 @@
/* In summary - Relevant file */
/* access flags from CIFS are */
/* file_read_data, file_write_data */
- /* file_execute, file_read_attributes */
+ /* file_execute, file_read_attributes*/
/* write_dac, and delete. */
/*
@@ -238,7 +244,8 @@
#define ATTR_SPARSE 0x0200
#define ATTR_REPARSE 0x0400
#define ATTR_COMPRESSED 0x0800
-#define ATTR_OFFLINE 0x1000 /* ie file not immediately available - offline storage */
+#define ATTR_OFFLINE 0x1000 /* ie file not immediately available -
+ on offline storage */
#define ATTR_NOT_CONTENT_INDEXED 0x2000
#define ATTR_ENCRYPTED 0x4000
#define ATTR_POSIX_SEMANTICS 0x01000000
@@ -267,10 +274,18 @@
/* CreateOptions */
#define CREATE_NOT_FILE 0x00000001 /* if set must not be file */
#define CREATE_WRITE_THROUGH 0x00000002
-#define CREATE_NOT_DIR 0x00000040 /* if set must not be directory */
+#define CREATE_SEQUENTIAL 0x00000004
+#define CREATE_SYNC_ALERT 0x00000010
+#define CREATE_ASYNC_ALERT 0x00000020
+#define CREATE_NOT_DIR 0x00000040 /* if set must not be directory */
+#define CREATE_NO_EA_KNOWLEDGE 0x00000200
+#define CREATE_EIGHT_DOT_THREE 0x00000400
#define CREATE_RANDOM_ACCESS 0x00000800
#define CREATE_DELETE_ON_CLOSE 0x00001000
+#define CREATE_OPEN_BY_ID 0x00002000
#define OPEN_REPARSE_POINT 0x00200000
+#define CREATE_OPTIONS_MASK 0x007FFFFF
+#define CREATE_OPTION_SPECIAL 0x20000000 /* system. NB not sent over wire */
/* ImpersonationLevel flags */
#define SECURITY_ANONYMOUS 0
@@ -297,10 +312,10 @@
#define GETU16(var) (*((__u16 *)var)) /* BB check for endian issues */
#define GETU32(var) (*((__u32 *)var)) /* BB check for endian issues */
-#pragma pack(1)
-
struct smb_hdr {
- __u32 smb_buf_length; /* big endian on wire *//* BB length is only two or three bytes - with one or two byte type preceding it but that is always zero - we could mask the type byte off just in case BB */
+ __u32 smb_buf_length; /* big endian on wire *//* BB length is only two
+ or three bytes - with one or two byte type preceding it that are
+ zero - we could mask the type byte off just in case BB */
__u8 Protocol[4];
__u8 Command;
union {
@@ -308,9 +323,9 @@ struct smb_hdr {
__u8 ErrorClass;
__u8 Reserved;
__le16 Error;
- } DosError;
+ } __attribute__((packed)) DosError;
__le32 CifsError;
- } Status;
+ } __attribute__((packed)) Status;
__u8 Flags;
__le16 Flags2; /* note: le */
__le16 PidHigh;
@@ -318,16 +333,16 @@ struct smb_hdr {
struct {
__le32 SequenceNumber; /* le */
__u32 Reserved; /* zero */
- } Sequence;
+ } __attribute__((packed)) Sequence;
__u8 SecuritySignature[8]; /* le */
- } Signature;
+ } __attribute__((packed)) Signature;
__u8 pad[2];
__u16 Tid;
__le16 Pid;
__u16 Uid;
__u16 Mid;
__u8 WordCount;
-};
+} __attribute__((packed));
/* given a pointer to an smb_hdr retrieve the value of byte count */
#define BCC(smb_var) ( *(__u16 *)((char *)smb_var + sizeof(struct smb_hdr) + (2* smb_var->WordCount) ) )
#define BCC_LE(smb_var) ( *(__le16 *)((char *)smb_var + sizeof(struct smb_hdr) + (2* smb_var->WordCount) ) )
@@ -379,7 +394,7 @@ typedef struct negotiate_req {
struct smb_hdr hdr; /* wct = 0 */
__le16 ByteCount;
unsigned char DialectsArray[1];
-} NEGOTIATE_REQ;
+} __attribute__((packed)) NEGOTIATE_REQ;
typedef struct negotiate_rsp {
struct smb_hdr hdr; /* wct = 17 */
@@ -397,16 +412,16 @@ typedef struct negotiate_rsp {
__u8 EncryptionKeyLength;
__u16 ByteCount;
union {
- unsigned char EncryptionKey[1]; /* if cap extended security is off */
+ unsigned char EncryptionKey[1]; /* cap extended security off */
/* followed by Domain name - if extended security is off */
/* followed by 16 bytes of server GUID */
- /* followed by security blob if cap_extended_security negotiated */
+ /* then security blob if cap_extended_security negotiated */
struct {
unsigned char GUID[16];
unsigned char SecurityBlob[1];
- } extended_response;
- } u;
-} NEGOTIATE_RSP;
+ } __attribute__((packed)) extended_response;
+ } __attribute__((packed)) u;
+} __attribute__((packed)) NEGOTIATE_RSP;
/* SecurityMode bits */
#define SECMODE_USER 0x01 /* off indicates share level security */
@@ -452,7 +467,8 @@ typedef union smb_com_session_setup_andx {
unsigned char SecurityBlob[1]; /* followed by */
/* STRING NativeOS */
/* STRING NativeLanMan */
- } req; /* NTLM request format (with extended security */
+ } __attribute__((packed)) req; /* NTLM request format (with
+ extended security */
struct { /* request format */
struct smb_hdr hdr; /* wct = 13 */
@@ -463,18 +479,19 @@ typedef union smb_com_session_setup_andx {
__le16 MaxMpxCount;
__le16 VcNumber;
__u32 SessionKey;
- __le16 CaseInsensitivePasswordLength; /* ASCII password length */
- __le16 CaseSensitivePasswordLength; /* Unicode password length */
+ __le16 CaseInsensitivePasswordLength; /* ASCII password len */
+ __le16 CaseSensitivePasswordLength; /* Unicode password length*/
__u32 Reserved; /* see below */
__le32 Capabilities;
__le16 ByteCount;
- unsigned char CaseInsensitivePassword[1]; /* followed by: */
+ unsigned char CaseInsensitivePassword[1]; /* followed by: */
/* unsigned char * CaseSensitivePassword; */
/* STRING AccountName */
/* STRING PrimaryDomain */
/* STRING NativeOS */
/* STRING NativeLanMan */
- } req_no_secext; /* NTLM request format (without extended security */
+ } __attribute__((packed)) req_no_secext; /* NTLM request format (without
+ extended security */
struct { /* default (NTLM) response format */
struct smb_hdr hdr; /* wct = 4 */
@@ -488,7 +505,7 @@ typedef union smb_com_session_setup_andx {
/* unsigned char * NativeOS; */
/* unsigned char * NativeLanMan; */
/* unsigned char * PrimaryDomain; */
- } resp; /* NTLM response format (with or without extended security */
+ } __attribute__((packed)) resp; /* NTLM response format (with or without extended security */
struct { /* request format */
struct smb_hdr hdr; /* wct = 10 */
@@ -507,7 +524,7 @@ typedef union smb_com_session_setup_andx {
/* STRING PrimaryDomain */
/* STRING NativeOS */
/* STRING NativeLanMan */
- } old_req; /* pre-NTLM (LANMAN2.1) request format */
+ } __attribute__((packed)) old_req; /* pre-NTLM (LANMAN2.1) request format */
struct { /* default (NTLM) response format */
struct smb_hdr hdr; /* wct = 3 */
@@ -519,8 +536,8 @@ typedef union smb_com_session_setup_andx {
unsigned char NativeOS[1]; /* followed by */
/* unsigned char * NativeLanMan; */
/* unsigned char * PrimaryDomain; */
- } old_resp; /* pre-NTLM (LANMAN2.1) response format */
-} SESSION_SETUP_ANDX;
+ } __attribute__((packed)) old_resp; /* pre-NTLM (LANMAN2.1) response format */
+} __attribute__((packed)) SESSION_SETUP_ANDX;
#define CIFS_NETWORK_OPSYS "CIFS VFS Client for Linux"
@@ -530,7 +547,8 @@ typedef union smb_com_session_setup_andx {
#define CAP_NT_SMBS 0x00000010
#define CAP_STATUS32 0x00000040
#define CAP_LEVEL_II_OPLOCKS 0x00000080
-#define CAP_NT_FIND 0x00000200 /* reserved should be zero (presumably because NT_SMBs implies the same thing) */
+#define CAP_NT_FIND 0x00000200 /* reserved should be zero
+ (because NT_SMBs implies the same thing?) */
#define CAP_BULK_TRANSFER 0x20000000
#define CAP_EXTENDED_SECURITY 0x80000000
@@ -548,7 +566,7 @@ typedef struct smb_com_tconx_req {
unsigned char Password[1]; /* followed by */
/* STRING Path *//* \\server\share name */
/* STRING Service */
-} TCONX_REQ;
+} __attribute__((packed)) TCONX_REQ;
typedef struct smb_com_tconx_rsp {
struct smb_hdr hdr; /* wct = 3 *//* note that Win2000 has sent wct=7 in some cases on responses. Four unspecified words followed OptionalSupport */
@@ -559,13 +577,14 @@ typedef struct smb_com_tconx_rsp {
__u16 ByteCount;
unsigned char Service[1]; /* always ASCII, not Unicode */
/* STRING NativeFileSystem */
-} TCONX_RSP;
+} __attribute__((packed)) TCONX_RSP;
/* tree connect Flags */
#define DISCONNECT_TID 0x0001
#define TCON_EXTENDED_SECINFO 0x0008
/* OptionalSupport bits */
-#define SMB_SUPPORT_SEARCH_BITS 0x0001 /* must have bits (exclusive searches suppt. */
+#define SMB_SUPPORT_SEARCH_BITS 0x0001 /* "must have" directory search bits
+ (exclusive searches supported) */
#define SMB_SHARE_IS_IN_DFS 0x0002
typedef struct smb_com_logoff_andx_req {
@@ -574,7 +593,7 @@ typedef struct smb_com_logoff_andx_req {
__u8 AndXReserved;
__u16 AndXOffset;
__u16 ByteCount;
-} LOGOFF_ANDX_REQ;
+} __attribute__((packed)) LOGOFF_ANDX_REQ;
typedef struct smb_com_logoff_andx_rsp {
struct smb_hdr hdr; /* wct = 2 */
@@ -582,38 +601,39 @@ typedef struct smb_com_logoff_andx_rsp {
__u8 AndXReserved;
__u16 AndXOffset;
__u16 ByteCount;
-} LOGOFF_ANDX_RSP;
+} __attribute__((packed)) LOGOFF_ANDX_RSP;
typedef union smb_com_tree_disconnect { /* as an altetnative can use flag on tree_connect PDU to effect disconnect *//* probably the simplest SMB PDU */
struct {
struct smb_hdr hdr; /* wct = 0 */
__u16 ByteCount; /* bcc = 0 */
- } req;
+ } __attribute__((packed)) req;
struct {
struct smb_hdr hdr; /* wct = 0 */
__u16 ByteCount; /* bcc = 0 */
- } resp;
-} TREE_DISCONNECT;
+ } __attribute__((packed)) resp;
+} __attribute__((packed)) TREE_DISCONNECT;
typedef struct smb_com_close_req {
struct smb_hdr hdr; /* wct = 3 */
__u16 FileID;
__u32 LastWriteTime; /* should be zero */
__u16 ByteCount; /* 0 */
-} CLOSE_REQ;
+} __attribute__((packed)) CLOSE_REQ;
typedef struct smb_com_close_rsp {
struct smb_hdr hdr; /* wct = 0 */
__u16 ByteCount; /* bct = 0 */
-} CLOSE_RSP;
+} __attribute__((packed)) CLOSE_RSP;
typedef struct smb_com_findclose_req {
struct smb_hdr hdr; /* wct = 1 */
__u16 FileID;
__u16 ByteCount; /* 0 */
-} FINDCLOSE_REQ;
+} __attribute__((packed)) FINDCLOSE_REQ;
/* OpenFlags */
+#define REQ_MORE_INFO 0x00000001 /* legacy (OPEN_AND_X) only */
#define REQ_OPLOCK 0x00000002
#define REQ_BATCHOPLOCK 0x00000004
#define REQ_OPENDIRONLY 0x00000008
@@ -637,7 +657,7 @@ typedef struct smb_com_open_req { /* also handles create */
__u8 SecurityFlags;
__le16 ByteCount;
char fileName[1];
-} OPEN_REQ;
+} __attribute__((packed)) OPEN_REQ;
/* open response: oplock levels */
#define OPLOCK_NONE 0
@@ -667,7 +687,63 @@ typedef struct smb_com_open_rsp {
__le16 DeviceState;
__u8 DirectoryFlag;
__u16 ByteCount; /* bct = 0 */
-} OPEN_RSP;
+} __attribute__((packed)) OPEN_RSP;
+
+/* format of legacy open request */
+typedef struct smb_com_openx_req {
+ struct smb_hdr hdr; /* wct = 15 */
+ __u8 AndXCommand;
+ __u8 AndXReserved;
+ __le16 AndXOffset;
+ __le16 OpenFlags;
+ __le16 Mode;
+ __le16 Sattr; /* search attributes */
+ __le16 FileAttributes; /* dos attrs */
+ __le32 CreateTime; /* os2 format */
+ __le16 OpenFunction;
+ __le32 EndOfFile;
+ __le32 Timeout;
+ __le32 Reserved;
+ __le16 ByteCount; /* file name follows */
+ char fileName[1];
+} __attribute__((packed)) OPENX_REQ;
+
+typedef struct smb_com_openx_rsp {
+ struct smb_hdr hdr; /* wct = 15 */
+ __u8 AndXCommand;
+ __u8 AndXReserved;
+ __le16 AndXOffset;
+ __u16 Fid;
+ __le16 FileAttributes;
+ __le32 LastWriteTime; /* os2 format */
+ __le32 EndOfFile;
+ __le16 Access;
+ __le16 FileType;
+ __le16 IPCState;
+ __le16 Action;
+ __u32 FileId;
+ __u16 Reserved;
+ __u16 ByteCount;
+} __attribute__((packed)) OPENX_RSP;
+
+/* Legacy write request for older servers */
+typedef struct smb_com_writex_req {
+ struct smb_hdr hdr; /* wct = 12 */
+ __u8 AndXCommand;
+ __u8 AndXReserved;
+ __le16 AndXOffset;
+ __u16 Fid;
+ __le32 OffsetLow;
+ __u32 Reserved; /* Timeout */
+ __le16 WriteMode; /* 1 = write through */
+ __le16 Remaining;
+ __le16 Reserved2;
+ __le16 DataLengthLow;
+ __le16 DataOffset;
+ __le16 ByteCount;
+ __u8 Pad; /* BB check for whether padded to DWORD boundary and optimum performance here */
+ char Data[0];
+} __attribute__((packed)) WRITEX_REQ;
typedef struct smb_com_write_req {
struct smb_hdr hdr; /* wct = 14 */
@@ -686,7 +762,7 @@ typedef struct smb_com_write_req {
__le16 ByteCount;
__u8 Pad; /* BB check for whether padded to DWORD boundary and optimum performance here */
char Data[0];
-} WRITE_REQ;
+} __attribute__((packed)) WRITE_REQ;
typedef struct smb_com_write_rsp {
struct smb_hdr hdr; /* wct = 6 */
@@ -698,7 +774,22 @@ typedef struct smb_com_write_rsp {
__le16 CountHigh;
__u16 Reserved;
__u16 ByteCount;
-} WRITE_RSP;
+} __attribute__((packed)) WRITE_RSP;
+
+/* legacy read request for older servers */
+typedef struct smb_com_readx_req {
+ struct smb_hdr hdr; /* wct = 10 */
+ __u8 AndXCommand;
+ __u8 AndXReserved;
+ __le16 AndXOffset;
+ __u16 Fid;
+ __le32 OffsetLow;
+ __le16 MaxCount;
+ __le16 MinCount; /* obsolete */
+ __le32 Reserved;
+ __le16 Remaining;
+ __le16 ByteCount;
+} __attribute__((packed)) READX_REQ;
typedef struct smb_com_read_req {
struct smb_hdr hdr; /* wct = 12 */
@@ -713,7 +804,7 @@ typedef struct smb_com_read_req {
__le16 Remaining;
__le32 OffsetHigh;
__le16 ByteCount;
-} READ_REQ;
+} __attribute__((packed)) READ_REQ;
typedef struct smb_com_read_rsp {
struct smb_hdr hdr; /* wct = 12 */
@@ -730,7 +821,7 @@ typedef struct smb_com_read_rsp {
__u16 ByteCount;
__u8 Pad; /* BB check for whether padded to DWORD boundary and optimum performance here */
char Data[1];
-} READ_RSP;
+} __attribute__((packed)) READ_RSP;
typedef struct locking_andx_range {
__le16 Pid;
@@ -739,7 +830,7 @@ typedef struct locking_andx_range {
__le32 OffsetLow;
__le32 LengthHigh;
__le32 LengthLow;
-} LOCKING_ANDX_RANGE;
+} __attribute__((packed)) LOCKING_ANDX_RANGE;
#define LOCKING_ANDX_SHARED_LOCK 0x01
#define LOCKING_ANDX_OPLOCK_RELEASE 0x02
@@ -760,7 +851,7 @@ typedef struct smb_com_lock_req {
__le16 NumberOfLocks;
__le16 ByteCount;
LOCKING_ANDX_RANGE Locks[1];
-} LOCK_REQ;
+} __attribute__((packed)) LOCK_REQ;
typedef struct cifs_posix_lock {
@@ -770,7 +861,7 @@ typedef struct cifs_posix_lock {
__le64 start;
__le64 length;
/* BB what about additional owner info to identify network client */
-} CIFS_POSIX_LOCK;
+} __attribute__((packed)) CIFS_POSIX_LOCK;
typedef struct smb_com_lock_rsp {
struct smb_hdr hdr; /* wct = 2 */
@@ -778,7 +869,7 @@ typedef struct smb_com_lock_rsp {
__u8 AndXReserved;
__le16 AndXOffset;
__u16 ByteCount;
-} LOCK_RSP;
+} __attribute__((packed)) LOCK_RSP;
typedef struct smb_com_rename_req {
struct smb_hdr hdr; /* wct = 1 */
@@ -788,7 +879,7 @@ typedef struct smb_com_rename_req {
unsigned char OldFileName[1];
/* followed by __u8 BufferFormat2 */
/* followed by NewFileName */
-} RENAME_REQ;
+} __attribute__((packed)) RENAME_REQ;
/* copy request flags */
#define COPY_MUST_BE_FILE 0x0001
@@ -808,7 +899,7 @@ typedef struct smb_com_copy_req {
unsigned char OldFileName[1];
/* followed by __u8 BufferFormat2 */
/* followed by NewFileName string */
-} COPY_REQ;
+} __attribute__((packed)) COPY_REQ;
typedef struct smb_com_copy_rsp {
struct smb_hdr hdr; /* wct = 1 */
@@ -816,7 +907,7 @@ typedef struct smb_com_copy_rsp {
__u16 ByteCount; /* may be zero */
__u8 BufferFormat; /* 0x04 - only present if errored file follows */
unsigned char ErrorFileName[1]; /* only present if error in copy */
-} COPY_RSP;
+} __attribute__((packed)) COPY_RSP;
#define CREATE_HARD_LINK 0x103
#define MOVEFILE_COPY_ALLOWED 0x0002
@@ -832,12 +923,12 @@ typedef struct smb_com_nt_rename_req { /* A5 - also used for create hardlink */
unsigned char OldFileName[1];
/* followed by __u8 BufferFormat2 */
/* followed by NewFileName */
-} NT_RENAME_REQ;
+} __attribute__((packed)) NT_RENAME_REQ;
typedef struct smb_com_rename_rsp {
struct smb_hdr hdr; /* wct = 0 */
__u16 ByteCount; /* bct = 0 */
-} RENAME_RSP;
+} __attribute__((packed)) RENAME_RSP;
typedef struct smb_com_delete_file_req {
struct smb_hdr hdr; /* wct = 1 */
@@ -845,36 +936,52 @@ typedef struct smb_com_delete_file_req {
__le16 ByteCount;
__u8 BufferFormat; /* 4 = ASCII */
unsigned char fileName[1];
-} DELETE_FILE_REQ;
+} __attribute__((packed)) DELETE_FILE_REQ;
typedef struct smb_com_delete_file_rsp {
struct smb_hdr hdr; /* wct = 0 */
__u16 ByteCount; /* bct = 0 */
-} DELETE_FILE_RSP;
+} __attribute__((packed)) DELETE_FILE_RSP;
typedef struct smb_com_delete_directory_req {
struct smb_hdr hdr; /* wct = 0 */
__le16 ByteCount;
__u8 BufferFormat; /* 4 = ASCII */
unsigned char DirName[1];
-} DELETE_DIRECTORY_REQ;
+} __attribute__((packed)) DELETE_DIRECTORY_REQ;
typedef struct smb_com_delete_directory_rsp {
struct smb_hdr hdr; /* wct = 0 */
__u16 ByteCount; /* bct = 0 */
-} DELETE_DIRECTORY_RSP;
+} __attribute__((packed)) DELETE_DIRECTORY_RSP;
typedef struct smb_com_create_directory_req {
struct smb_hdr hdr; /* wct = 0 */
__le16 ByteCount;
__u8 BufferFormat; /* 4 = ASCII */
unsigned char DirName[1];
-} CREATE_DIRECTORY_REQ;
+} __attribute__((packed)) CREATE_DIRECTORY_REQ;
typedef struct smb_com_create_directory_rsp {
struct smb_hdr hdr; /* wct = 0 */
__u16 ByteCount; /* bct = 0 */
-} CREATE_DIRECTORY_RSP;
+} __attribute__((packed)) CREATE_DIRECTORY_RSP;
+
+typedef struct smb_com_query_information_req {
+ struct smb_hdr hdr; /* wct = 0 */
+ __le16 ByteCount; /* 1 + namelen + 1 */
+ __u8 BufferFormat; /* 4 = ASCII */
+ unsigned char FileName[1];
+} __attribute__((packed)) QUERY_INFORMATION_REQ;
+
+typedef struct smb_com_query_information_rsp {
+ struct smb_hdr hdr; /* wct = 10 */
+ __le16 attr;
+ __le32 last_write_time;
+ __le32 size;
+ __u16 reserved[5];
+ __le16 ByteCount; /* bcc = 0 */
+} __attribute__((packed)) QUERY_INFORMATION_RSP;
typedef struct smb_com_setattr_req {
struct smb_hdr hdr; /* wct = 8 */
@@ -885,12 +992,12 @@ typedef struct smb_com_setattr_req {
__u16 ByteCount;
__u8 BufferFormat; /* 4 = ASCII */
unsigned char fileName[1];
-} SETATTR_REQ;
+} __attribute__((packed)) SETATTR_REQ;
typedef struct smb_com_setattr_rsp {
struct smb_hdr hdr; /* wct = 0 */
__u16 ByteCount; /* bct = 0 */
-} SETATTR_RSP;
+} __attribute__((packed)) SETATTR_RSP;
/* empty wct response to setattr */
@@ -920,7 +1027,7 @@ typedef struct smb_com_transaction_ioctl_req {
__le16 ByteCount;
__u8 Pad[3];
__u8 Data[1];
-} TRANSACT_IOCTL_REQ;
+} __attribute__((packed)) TRANSACT_IOCTL_REQ;
typedef struct smb_com_transaction_ioctl_rsp {
struct smb_hdr hdr; /* wct = 19 */
@@ -937,7 +1044,7 @@ typedef struct smb_com_transaction_ioctl_rsp {
__le16 ReturnedDataLen;
__u16 ByteCount;
__u8 Pad[3];
-} TRANSACT_IOCTL_RSP;
+} __attribute__((packed)) TRANSACT_IOCTL_RSP;
typedef struct smb_com_transaction_change_notify_req {
struct smb_hdr hdr; /* wct = 23 */
@@ -961,7 +1068,7 @@ typedef struct smb_com_transaction_change_notify_req {
__le16 ByteCount;
/* __u8 Pad[3];*/
/* __u8 Data[1];*/
-} TRANSACT_CHANGE_NOTIFY_REQ;
+} __attribute__((packed)) TRANSACT_CHANGE_NOTIFY_REQ;
typedef struct smb_com_transaction_change_notify_rsp {
struct smb_hdr hdr; /* wct = 18 */
@@ -977,7 +1084,7 @@ typedef struct smb_com_transaction_change_notify_rsp {
__u8 SetupCount; /* 0 */
__u16 ByteCount;
/* __u8 Pad[3]; */
-} TRANSACT_CHANGE_NOTIFY_RSP;
+} __attribute__((packed)) TRANSACT_CHANGE_NOTIFY_RSP;
/* Completion Filter flags for Notify */
#define FILE_NOTIFY_CHANGE_FILE_NAME 0x00000001
#define FILE_NOTIFY_CHANGE_DIR_NAME 0x00000002
@@ -1008,7 +1115,7 @@ struct file_notify_information {
__le32 Action;
__le32 FileNameLength;
__u8 FileName[0];
-};
+} __attribute__((packed));
struct reparse_data {
__u32 ReparseTag;
@@ -1019,7 +1126,7 @@ struct reparse_data {
__u16 TargetNameOffset;
__u16 TargetNameLen;
char LinkNamesBuf[1];
-};
+} __attribute__((packed));
struct cifs_quota_data {
__u32 rsrvd1; /* 0 */
@@ -1029,7 +1136,7 @@ struct cifs_quota_data {
__u64 soft_limit;
__u64 hard_limit;
char sid[1]; /* variable size? */
-};
+} __attribute__((packed));
/* quota sub commands */
#define QUOTA_LIST_CONTINUE 0
@@ -1055,12 +1162,12 @@ struct trans2_req {
__u8 Reserved3;
__le16 SubCommand; /* 1st setup word - SetupCount words follow */
__le16 ByteCount;
-};
+} __attribute__((packed));
struct smb_t2_req {
struct smb_hdr hdr;
struct trans2_req t2_req;
-};
+} __attribute__((packed));
struct trans2_resp {
/* struct smb_hdr hdr precedes. Note wct = 10 + setup count */
@@ -1079,12 +1186,12 @@ struct trans2_resp {
__u16 ByteCount;
__u16 Reserved2;*/
/* data area follows */
-};
+} __attribute__((packed));
struct smb_t2_rsp {
struct smb_hdr hdr;
struct trans2_resp t2_rsp;
-};
+} __attribute__((packed));
/* PathInfo/FileInfo infolevels */
#define SMB_INFO_STANDARD 1
@@ -1171,14 +1278,14 @@ typedef struct smb_com_transaction2_qpi_req {
__le16 InformationLevel;
__u32 Reserved4;
char FileName[1];
-} TRANSACTION2_QPI_REQ;
+} __attribute__((packed)) TRANSACTION2_QPI_REQ;
typedef struct smb_com_transaction2_qpi_rsp {
struct smb_hdr hdr; /* wct = 10 + SetupCount */
struct trans2_resp t2;
__u16 ByteCount;
__u16 Reserved2; /* parameter word reserved - present for infolevels > 100 */
-} TRANSACTION2_QPI_RSP;
+} __attribute__((packed)) TRANSACTION2_QPI_RSP;
typedef struct smb_com_transaction2_spi_req {
struct smb_hdr hdr; /* wct = 15 */
@@ -1204,21 +1311,21 @@ typedef struct smb_com_transaction2_spi_req {
__le16 InformationLevel;
__u32 Reserved4;
char FileName[1];
-} TRANSACTION2_SPI_REQ;
+} __attribute__((packed)) TRANSACTION2_SPI_REQ;
typedef struct smb_com_transaction2_spi_rsp {
struct smb_hdr hdr; /* wct = 10 + SetupCount */
struct trans2_resp t2;
__u16 ByteCount;
__u16 Reserved2; /* parameter word reserved - present for infolevels > 100 */
-} TRANSACTION2_SPI_RSP;
+} __attribute__((packed)) TRANSACTION2_SPI_RSP;
struct set_file_rename {
__le32 overwrite; /* 1 = overwrite dest */
__u32 root_fid; /* zero */
__le32 target_name_len;
char target_name[0]; /* Must be unicode */
-};
+} __attribute__((packed));
struct smb_com_transaction2_sfi_req {
struct smb_hdr hdr; /* wct = 15 */
@@ -1244,7 +1351,7 @@ struct smb_com_transaction2_sfi_req {
__u16 Fid;
__le16 InformationLevel;
__u16 Reserved4;
-};
+} __attribute__((packed));
struct smb_com_transaction2_sfi_rsp {
struct smb_hdr hdr; /* wct = 10 + SetupCount */
@@ -1252,7 +1359,7 @@ struct smb_com_transaction2_sfi_rsp {
__u16 ByteCount;
__u16 Reserved2; /* parameter word reserved -
present for infolevels > 100 */
-};
+} __attribute__((packed));
struct smb_t2_qfi_req {
struct smb_hdr hdr;
@@ -1260,7 +1367,7 @@ struct smb_t2_qfi_req {
__u8 Pad;
__u16 Fid;
__le16 InformationLevel;
-};
+} __attribute__((packed));
struct smb_t2_qfi_rsp {
struct smb_hdr hdr; /* wct = 10 + SetupCount */
@@ -1268,7 +1375,7 @@ struct smb_t2_qfi_rsp {
__u16 ByteCount;
__u16 Reserved2; /* parameter word reserved -
present for infolevels > 100 */
-};
+} __attribute__((packed));
/*
* Flags on T2 FINDFIRST and FINDNEXT
@@ -1310,13 +1417,13 @@ typedef struct smb_com_transaction2_ffirst_req {
__le16 InformationLevel;
__le32 SearchStorageType;
char FileName[1];
-} TRANSACTION2_FFIRST_REQ;
+} __attribute__((packed)) TRANSACTION2_FFIRST_REQ;
typedef struct smb_com_transaction2_ffirst_rsp {
struct smb_hdr hdr; /* wct = 10 */
struct trans2_resp t2;
__u16 ByteCount;
-} TRANSACTION2_FFIRST_RSP;
+} __attribute__((packed)) TRANSACTION2_FFIRST_RSP;
typedef struct smb_com_transaction2_ffirst_rsp_parms {
__u16 SearchHandle;
@@ -1324,7 +1431,7 @@ typedef struct smb_com_transaction2_ffirst_rsp_parms {
__le16 EndofSearch;
__le16 EAErrorOffset;
__le16 LastNameOffset;
-} T2_FFIRST_RSP_PARMS;
+} __attribute__((packed)) T2_FFIRST_RSP_PARMS;
typedef struct smb_com_transaction2_fnext_req {
struct smb_hdr hdr; /* wct = 15 */
@@ -1352,20 +1459,20 @@ typedef struct smb_com_transaction2_fnext_req {
__u32 ResumeKey;
__le16 SearchFlags;
char ResumeFileName[1];
-} TRANSACTION2_FNEXT_REQ;
+} __attribute__((packed)) TRANSACTION2_FNEXT_REQ;
typedef struct smb_com_transaction2_fnext_rsp {
struct smb_hdr hdr; /* wct = 10 */
struct trans2_resp t2;
__u16 ByteCount;
-} TRANSACTION2_FNEXT_RSP;
+} __attribute__((packed)) TRANSACTION2_FNEXT_RSP;
typedef struct smb_com_transaction2_fnext_rsp_parms {
__le16 SearchCount;
__le16 EndofSearch;
__le16 EAErrorOffset;
__le16 LastNameOffset;
-} T2_FNEXT_RSP_PARMS;
+} __attribute__((packed)) T2_FNEXT_RSP_PARMS;
/* QFSInfo Levels */
#define SMB_INFO_ALLOCATION 1
@@ -1402,14 +1509,51 @@ typedef struct smb_com_transaction2_qfsi_req {
__le16 ByteCount;
__u8 Pad;
__le16 InformationLevel;
-} TRANSACTION2_QFSI_REQ;
+} __attribute__((packed)) TRANSACTION2_QFSI_REQ;
typedef struct smb_com_transaction_qfsi_rsp {
struct smb_hdr hdr; /* wct = 10 + SetupCount */
struct trans2_resp t2;
__u16 ByteCount;
__u8 Pad; /* may be three bytes *//* followed by data area */
-} TRANSACTION2_QFSI_RSP;
+} __attribute__((packed)) TRANSACTION2_QFSI_RSP;
+
+
+/* SETFSInfo Levels */
+#define SMB_SET_CIFS_UNIX_INFO 0x200
+typedef struct smb_com_transaction2_setfsi_req {
+ struct smb_hdr hdr; /* wct = 15 */
+ __le16 TotalParameterCount;
+ __le16 TotalDataCount;
+ __le16 MaxParameterCount;
+ __le16 MaxDataCount;
+ __u8 MaxSetupCount;
+ __u8 Reserved;
+ __le16 Flags;
+ __le32 Timeout;
+ __u16 Reserved2;
+ __le16 ParameterCount; /* 4 */
+ __le16 ParameterOffset;
+ __le16 DataCount; /* 12 */
+ __le16 DataOffset;
+ __u8 SetupCount; /* one */
+ __u8 Reserved3;
+ __le16 SubCommand; /* TRANS2_SET_FS_INFORMATION */
+ __le16 ByteCount;
+ __u8 Pad;
+ __u16 FileNum; /* Parameters start. */
+ __le16 InformationLevel;/* Parameters end. */
+ __le16 ClientUnixMajor; /* Data start. */
+ __le16 ClientUnixMinor;
+ __le64 ClientUnixCap; /* Data end */
+} __attribute__((packed)) TRANSACTION2_SETFSI_REQ;
+
+typedef struct smb_com_transaction2_setfsi_rsp {
+ struct smb_hdr hdr; /* wct = 10 */
+ struct trans2_resp t2;
+ __u16 ByteCount;
+} __attribute__((packed)) TRANSACTION2_SETFSI_RSP;
+
typedef struct smb_com_transaction2_get_dfs_refer_req {
struct smb_hdr hdr; /* wct = 15 */
@@ -1433,7 +1577,7 @@ typedef struct smb_com_transaction2_get_dfs_refer_req {
__u8 Pad[3]; /* Win2K has sent 0x0F01 (max resp length perhaps?) followed by one byte pad - doesn't seem to matter though */
__le16 MaxReferralLevel;
char RequestFileName[1];
-} TRANSACTION2_GET_DFS_REFER_REQ;
+} __attribute__((packed)) TRANSACTION2_GET_DFS_REFER_REQ;
typedef struct dfs_referral_level_3 {
__le16 VersionNumber;
@@ -1445,7 +1589,7 @@ typedef struct dfs_referral_level_3 {
__le16 DfsPathOffset;
__le16 DfsAlternatePathOffset;
__le16 NetworkAddressOffset;
-} REFERRAL3;
+} __attribute__((packed)) REFERRAL3;
typedef struct smb_com_transaction_get_dfs_refer_rsp {
struct smb_hdr hdr; /* wct = 10 */
@@ -1458,7 +1602,7 @@ typedef struct smb_com_transaction_get_dfs_refer_rsp {
__u16 Pad2;
REFERRAL3 referrals[1]; /* array of level 3 dfs_referral structures */
/* followed by the strings pointed to by the referral structures */
-} TRANSACTION2_GET_DFS_REFER_RSP;
+} __attribute__((packed)) TRANSACTION2_GET_DFS_REFER_RSP;
/* DFS Flags */
#define DFSREF_REFERRAL_SERVER 0x0001
@@ -1512,7 +1656,7 @@ struct serverInfo {
unsigned char versionMinor;
unsigned long type;
unsigned int commentOffset;
-};
+} __attribute__((packed));
/*
* The following structure is the format of the data returned on a NetShareEnum
@@ -1524,39 +1668,55 @@ struct shareInfo {
char pad;
unsigned short type;
unsigned int commentOffset;
-};
+} __attribute__((packed));
struct aliasInfo {
char aliasName[9];
char pad;
unsigned int commentOffset;
unsigned char type[2];
-};
+} __attribute__((packed));
struct aliasInfo92 {
int aliasNameOffset;
int serverNameOffset;
int shareNameOffset;
-};
+} __attribute__((packed));
typedef struct {
__le64 TotalAllocationUnits;
__le64 FreeAllocationUnits;
__le32 SectorsPerAllocationUnit;
__le32 BytesPerSector;
-} FILE_SYSTEM_INFO; /* size info, level 0x103 */
+} __attribute__((packed)) FILE_SYSTEM_INFO; /* size info, level 0x103 */
+
+typedef struct {
+ __le32 fsid;
+ __le32 SectorsPerAllocationUnit;
+ __le32 TotalAllocationUnits;
+ __le32 FreeAllocationUnits;
+ __le16 BytesPerSector;
+} __attribute__((packed)) FILE_SYSTEM_ALLOC_INFO;
typedef struct {
__le16 MajorVersionNumber;
__le16 MinorVersionNumber;
__le64 Capability;
-} FILE_SYSTEM_UNIX_INFO; /* Unix extensions info, level 0x200 */
+} __attribute__((packed)) FILE_SYSTEM_UNIX_INFO; /* Unix extensions info, level 0x200 */
+
+/* Version numbers for CIFS UNIX major and minor. */
+#define CIFS_UNIX_MAJOR_VERSION 1
+#define CIFS_UNIX_MINOR_VERSION 0
+
/* Linux/Unix extensions capability flags */
#define CIFS_UNIX_FCNTL_CAP 0x00000001 /* support for fcntl locks */
#define CIFS_UNIX_POSIX_ACL_CAP 0x00000002 /* support getfacl/setfacl */
#define CIFS_UNIX_XATTR_CAP 0x00000004 /* support new namespace */
#define CIFS_UNIX_EXTATTR_CAP 0x00000008 /* support chattr/chflag */
+#define CIFS_UNIX_POSIX_PATHNAMES_CAP 0x00000010 /* Use POSIX pathnames on the wire. */
+
#define CIFS_POSIX_EXTENSIONS 0x00000010 /* support for new QFSInfo */
+
typedef struct {
/* For undefined recommended transfer size return -1 in that field */
__le32 OptimalTransferSize; /* bsize on some os, iosize on other os */
@@ -1577,7 +1737,7 @@ typedef struct {
__le64 FileSysIdentifier; /* fsid */
/* NB Namelen comes from FILE_SYSTEM_ATTRIBUTE_INFO call */
/* NB flags can come from FILE_SYSTEM_DEVICE_INFO call */
-} FILE_SYSTEM_POSIX_INFO;
+} __attribute__((packed)) FILE_SYSTEM_POSIX_INFO;
/* DeviceType Flags */
#define FILE_DEVICE_CD_ROM 0x00000002
@@ -1602,14 +1762,14 @@ typedef struct {
typedef struct {
__le32 DeviceType;
__le32 DeviceCharacteristics;
-} FILE_SYSTEM_DEVICE_INFO; /* device info, level 0x104 */
+} __attribute__((packed)) FILE_SYSTEM_DEVICE_INFO; /* device info, level 0x104 */
typedef struct {
__le32 Attributes;
__le32 MaxPathNameComponentLength;
__le32 FileSystemNameLen;
char FileSystemName[52]; /* do not really need to save this - so potentially get only subset of name */
-} FILE_SYSTEM_ATTRIBUTE_INFO;
+} __attribute__((packed)) FILE_SYSTEM_ATTRIBUTE_INFO;
/******************************************************************************/
/* QueryFileInfo/QueryPathinfo (also for SetPath/SetFile) data buffer formats */
@@ -1636,7 +1796,7 @@ typedef struct { /* data block encoding of response to level 263 QPathInfo */
__le32 AlignmentRequirement;
__le32 FileNameLength;
char FileName[1];
-} FILE_ALL_INFO; /* level 0x107 QPathInfo */
+} __attribute__((packed)) FILE_ALL_INFO; /* level 0x107 QPathInfo */
/* defines for enumerating possible values of the Unix type field below */
#define UNIX_FILE 0
@@ -1660,11 +1820,11 @@ typedef struct {
__u64 UniqueId;
__le64 Permissions;
__le64 Nlinks;
-} FILE_UNIX_BASIC_INFO; /* level 0x200 QPathInfo */
+} __attribute__((packed)) FILE_UNIX_BASIC_INFO; /* level 0x200 QPathInfo */
typedef struct {
char LinkDest[1];
-} FILE_UNIX_LINK_INFO; /* level 0x201 QPathInfo */
+} __attribute__((packed)) FILE_UNIX_LINK_INFO; /* level 0x201 QPathInfo */
/* The following three structures are needed only for
setting time to NT4 and some older servers via
@@ -1673,13 +1833,13 @@ typedef struct {
__u16 Day:5;
__u16 Month:4;
__u16 Year:7;
-} SMB_DATE;
+} __attribute__((packed)) SMB_DATE;
typedef struct {
__u16 TwoSeconds:5;
__u16 Minutes:6;
__u16 Hours:5;
-} SMB_TIME;
+} __attribute__((packed)) SMB_TIME;
typedef struct {
__le16 CreationDate; /* SMB Date see above */
@@ -1692,7 +1852,7 @@ typedef struct {
__le32 AllocationSize;
__le16 Attributes; /* verify not u32 */
__le32 EASize;
-} FILE_INFO_STANDARD; /* level 1 SetPath/FileInfo */
+} __attribute__((packed)) FILE_INFO_STANDARD; /* level 1 SetPath/FileInfo */
typedef struct {
__le64 CreationTime;
@@ -1701,19 +1861,19 @@ typedef struct {
__le64 ChangeTime;
__le32 Attributes;
__u32 Pad;
-} FILE_BASIC_INFO; /* size info, level 0x101 */
+} __attribute__((packed)) FILE_BASIC_INFO; /* size info, level 0x101 */
struct file_allocation_info {
__le64 AllocationSize; /* Note old Samba srvr rounds this up too much */
-}; /* size used on disk, level 0x103 for set, 0x105 for query */
+} __attribute__((packed)); /* size used on disk, level 0x103 for set, 0x105 for query */
struct file_end_of_file_info {
__le64 FileSize; /* offset to end of file */
-}; /* size info, level 0x104 for set, 0x106 for query */
+} __attribute__((packed)); /* size info, level 0x104 for set, 0x106 for query */
struct file_alt_name_info {
__u8 alt_name[1];
-}; /* level 0x0108 */
+} __attribute__((packed)); /* level 0x0108 */
struct file_stream_info {
__le32 number_of_streams; /* BB check sizes and verify location */
@@ -1730,7 +1890,7 @@ struct file_compression_info {
__u8 ch_shift;
__u8 cl_shift;
__u8 pad[3];
-}; /* level 0x10b */
+} __attribute__((packed)); /* level 0x10b */
/* POSIX ACL set/query path info structures */
#define CIFS_ACL_VERSION 1
@@ -1738,7 +1898,7 @@ struct cifs_posix_ace { /* access control entry (ACE) */
__u8 cifs_e_tag;
__u8 cifs_e_perm;
__le64 cifs_uid; /* or gid */
-};
+} __attribute__((packed));
struct cifs_posix_acl { /* access conrol list (ACL) */
__le16 version;
@@ -1747,7 +1907,7 @@ struct cifs_posix_acl { /* access conrol list (ACL) */
struct cifs_posix_ace ace_array[0];
/* followed by
struct cifs_posix_ace default_ace_arraay[] */
-}; /* level 0x204 */
+} __attribute__((packed)); /* level 0x204 */
/* types of access control entries already defined in posix_acl.h */
/* #define CIFS_POSIX_ACL_USER_OBJ 0x01
@@ -1766,15 +1926,15 @@ struct cifs_posix_acl { /* access conrol list (ACL) */
struct file_internal_info {
__u64 UniqueId; /* inode number */
-}; /* level 0x3ee */
+} __attribute__((packed)); /* level 0x3ee */
struct file_mode_info {
__le32 Mode;
-}; /* level 0x3f8 */
+} __attribute__((packed)); /* level 0x3f8 */
struct file_attrib_tag {
__le32 Attribute;
__le32 ReparseTag;
-}; /* level 0x40b */
+} __attribute__((packed)); /* level 0x40b */
/********************************************************/
@@ -1798,7 +1958,7 @@ typedef struct {
__le64 Permissions;
__le64 Nlinks;
char FileName[1];
-} FILE_UNIX_INFO; /* level 0x202 */
+} __attribute__((packed)) FILE_UNIX_INFO; /* level 0x202 */
typedef struct {
__le32 NextEntryOffset;
@@ -1812,7 +1972,7 @@ typedef struct {
__le32 ExtFileAttributes;
__le32 FileNameLength;
char FileName[1];
-} FILE_DIRECTORY_INFO; /* level 0x101 FF response data area */
+} __attribute__((packed)) FILE_DIRECTORY_INFO; /* level 0x101 FF response data area */
typedef struct {
__le32 NextEntryOffset;
@@ -1827,7 +1987,7 @@ typedef struct {
__le32 FileNameLength;
__le32 EaSize; /* length of the xattrs */
char FileName[1];
-} FILE_FULL_DIRECTORY_INFO; /* level 0x102 FF response data area */
+} __attribute__((packed)) FILE_FULL_DIRECTORY_INFO; /* level 0x102 FF response data area */
typedef struct {
__le32 NextEntryOffset;
@@ -1844,7 +2004,7 @@ typedef struct {
__le32 Reserved;
__u64 UniqueId; /* inode num - le since Samba puts ino in low 32 bit*/
char FileName[1];
-} SEARCH_ID_FULL_DIR_INFO; /* level 0x105 FF response data area */
+} __attribute__((packed)) SEARCH_ID_FULL_DIR_INFO; /* level 0x105 FF response data area */
typedef struct {
__le32 NextEntryOffset;
@@ -1862,18 +2022,18 @@ typedef struct {
__u8 Reserved;
__u8 ShortName[12];
char FileName[1];
-} FILE_BOTH_DIRECTORY_INFO; /* level 0x104 FF response data area */
+} __attribute__((packed)) FILE_BOTH_DIRECTORY_INFO; /* level 0x104 FF response data area */
struct gea {
unsigned char name_len;
char name[1];
-};
+} __attribute__((packed));
struct gealist {
unsigned long list_len;
struct gea list[1];
-};
+} __attribute__((packed));
struct fea {
unsigned char EA_flags;
@@ -1881,21 +2041,21 @@ struct fea {
__le16 value_len;
char name[1];
/* optionally followed by value */
-};
+} __attribute__((packed));
/* flags for _FEA.fEA */
#define FEA_NEEDEA 0x80 /* need EA bit */
struct fealist {
__le32 list_len;
struct fea list[1];
-};
+} __attribute__((packed));
/* used to hold an arbitrary blob of data */
struct data_blob {
__u8 *data;
size_t length;
void (*free) (struct data_blob * data_blob);
-};
+} __attribute__((packed));
#ifdef CONFIG_CIFS_POSIX
@@ -1907,18 +2067,17 @@ struct data_blob {
perhaps add a CreateDevice - to create Pipes and other special .inodes
Also note POSIX open flags
2) Close - to return the last write time to do cache across close more safely
- 3) PosixQFSInfo - to return statfs info
- 4) FindFirst return unique inode number - what about resume key, two forms short (matches readdir) and full (enough info to cache inodes)
- 5) Mkdir - set mode
+ 3) FindFirst return unique inode number - what about resume key, two
+ forms short (matches readdir) and full (enough info to cache inodes)
+ 4) Mkdir - set mode
And under consideration:
- 6) FindClose2 (return nanosecond timestamp ??)
- 7) Use nanosecond timestamps throughout all time fields if
+ 5) FindClose2 (return nanosecond timestamp ??)
+ 6) Use nanosecond timestamps throughout all time fields if
corresponding attribute flag is set
- 8) sendfile - handle based copy
- 9) Direct i/o
- 10) "POSIX ACL" support
- 11) Misc fcntls?
+ 7) sendfile - handle based copy
+ 8) Direct i/o
+ 9) Misc fcntls?
what about fixing 64 bit alignment
@@ -1974,7 +2133,7 @@ struct data_blob {
*/
-/* xsymlink is a symlink format that can be used
+/* xsymlink is a symlink format (used by MacOS) that can be used
to save symlink info in a regular file when
mounted to operating systems that do not
support the cifs Unix extensions or EAs (for xattr
@@ -1999,7 +2158,7 @@ struct xsymlink {
char cr2; /* \n */
/* if room left, then end with \n then 0x20s by convention but not required */
char path[1024];
-};
+} __attribute__((packed));
typedef struct file_xattr_info {
/* BB do we need another field for flags? BB */
@@ -2007,7 +2166,7 @@ typedef struct file_xattr_info {
__u32 xattr_value_len;
char xattr_name[0];
/* followed by xattr_value[xattr_value_len], no pad */
-} FILE_XATTR_INFO; /* extended attribute, info level 0x205 */
+} __attribute__((packed)) FILE_XATTR_INFO; /* extended attribute, info level 0x205 */
/* flags for chattr command */
@@ -2033,10 +2192,8 @@ typedef struct file_xattr_info {
typedef struct file_chattr_info {
__le64 mask; /* list of all possible attribute bits */
__le64 mode; /* list of actual attribute bits on this inode */
-} FILE_CHATTR_INFO; /* ext attributes (chattr, chflags) level 0x206 */
+} __attribute__((packed)) FILE_CHATTR_INFO; /* ext attributes (chattr, chflags) level 0x206 */
#endif
-#pragma pack() /* resume default structure packing */
-
#endif /* _CIFSPDU_H */
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
index ea239dea571e..1b73f4f4c5ce 100644
--- a/fs/cifs/cifsproto.h
+++ b/fs/cifs/cifsproto.h
@@ -47,19 +47,24 @@ extern int SendReceive(const unsigned int /* xid */ , struct cifsSesInfo *,
struct smb_hdr * /* input */ ,
struct smb_hdr * /* out */ ,
int * /* bytes returned */ , const int long_op);
+extern int SendReceive2(const unsigned int /* xid */ , struct cifsSesInfo *,
+ struct kvec *, int /* nvec */,
+ int * /* bytes returned */ , const int long_op);
extern int checkSMBhdr(struct smb_hdr *smb, __u16 mid);
extern int checkSMB(struct smb_hdr *smb, __u16 mid, int length);
extern int is_valid_oplock_break(struct smb_hdr *smb);
extern int is_size_safe_to_change(struct cifsInodeInfo *);
+extern struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *);
extern unsigned int smbCalcSize(struct smb_hdr *ptr);
+extern unsigned int smbCalcSize_LE(struct smb_hdr *ptr);
extern int decode_negTokenInit(unsigned char *security_blob, int length,
enum securityEnum *secType);
extern int cifs_inet_pton(int, char * source, void *dst);
extern int map_smb_to_linux_error(struct smb_hdr *smb);
extern void header_assemble(struct smb_hdr *, char /* command */ ,
- const struct cifsTconInfo *, int /* specifies length
- of fixed section (word count) in two byte units */
- );
+ const struct cifsTconInfo *, int /* length of
+ fixed section (word count) in two byte units */);
+extern __u16 GetNextMid(struct TCP_Server_Info *server);
extern struct oplock_q_entry * AllocOplockQEntry(struct inode *, u16,
struct cifsTconInfo *);
extern void DeleteOplockQEntry(struct oplock_q_entry *);
@@ -89,7 +94,7 @@ extern int CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
extern int CIFSFindFirst(const int xid, struct cifsTconInfo *tcon,
const char *searchName, const struct nls_table *nls_codepage,
- __u16 *searchHandle, struct cifs_search_info * psrch_inf, int map);
+ __u16 *searchHandle, struct cifs_search_info * psrch_inf, int map, const char dirsep);
extern int CIFSFindNext(const int xid, struct cifsTconInfo *tcon,
__u16 searchHandle, struct cifs_search_info * psrch_inf);
@@ -101,6 +106,10 @@ extern int CIFSSMBQPathInfo(const int xid, struct cifsTconInfo *tcon,
const unsigned char *searchName,
FILE_ALL_INFO * findData,
const struct nls_table *nls_codepage, int remap);
+extern int SMBQueryInformation(const int xid, struct cifsTconInfo *tcon,
+ const unsigned char *searchName,
+ FILE_ALL_INFO * findData,
+ const struct nls_table *nls_codepage, int remap);
extern int CIFSSMBUnixQPathInfo(const int xid,
struct cifsTconInfo *tcon,
@@ -125,6 +134,11 @@ extern int get_dfs_path(int xid, struct cifsSesInfo *pSesInfo,
int remap);
extern int CIFSSMBQFSInfo(const int xid, struct cifsTconInfo *tcon,
struct kstatfs *FSData);
+extern int SMBOldQFSInfo(const int xid, struct cifsTconInfo *tcon,
+ struct kstatfs *FSData);
+extern int CIFSSMBSetFSUnixInfo(const int xid, struct cifsTconInfo *tcon,
+ __u64 cap);
+
extern int CIFSSMBQFSAttributeInfo(const int xid,
struct cifsTconInfo *tcon);
extern int CIFSSMBQFSDeviceInfo(const int xid, struct cifsTconInfo *tcon);
@@ -207,6 +221,11 @@ extern int CIFSSMBOpen(const int xid, struct cifsTconInfo *tcon,
const int access_flags, const int omode,
__u16 * netfid, int *pOplock, FILE_ALL_INFO *,
const struct nls_table *nls_codepage, int remap);
+extern int SMBLegacyOpen(const int xid, struct cifsTconInfo *tcon,
+ const char *fileName, const int disposition,
+ const int access_flags, const int omode,
+ __u16 * netfid, int *pOplock, FILE_ALL_INFO *,
+ const struct nls_table *nls_codepage, int remap);
extern int CIFSSMBClose(const int xid, struct cifsTconInfo *tcon,
const int smb_file_id);
@@ -222,12 +241,12 @@ extern int CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
extern int CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
const int netfid, const unsigned int count,
const __u64 offset, unsigned int *nbytes,
- const char __user *buf,const int long_op);
+ struct kvec *iov, const int nvec, const int long_op);
+#endif /* CONFIG_CIFS_EXPERIMENTAL */
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);
-#endif /* CONFIG_CIFS_EXPERIMENTAL */
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,
@@ -264,7 +283,8 @@ extern int CIFSSMBCopy(int xid,
int remap_special_chars);
extern int CIFSSMBNotify(const int xid, struct cifsTconInfo *tcon,
const int notify_subdirs,const __u16 netfid,
- __u32 filter, const struct nls_table *nls_codepage);
+ __u32 filter, struct file * file, int multishot,
+ const struct nls_table *nls_codepage);
extern ssize_t CIFSSMBQAllEAs(const int xid, struct cifsTconInfo *tcon,
const unsigned char *searchName, char * EAData,
size_t bufsize, const struct nls_table *nls_codepage,
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index 0db0b313d715..a53c596e1082 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -125,6 +125,9 @@ small_smb_init(int smb_command, int wct, struct cifsTconInfo *tcon,
rc = CIFSTCon(0, tcon->ses, tcon->treeName, tcon
, nls_codepage);
up(&tcon->ses->sesSem);
+ /* BB FIXME add code to check if wsize needs
+ update due to negotiated smb buffer size
+ shrinking */
if(rc == 0)
atomic_inc(&tconInfoReconnectCount);
@@ -166,11 +169,9 @@ small_smb_init(int smb_command, int wct, struct cifsTconInfo *tcon,
header_assemble((struct smb_hdr *) *request_buf, smb_command, tcon,wct);
-#ifdef CONFIG_CIFS_STATS
- if(tcon != NULL) {
- atomic_inc(&tcon->num_smbs_sent);
- }
-#endif /* CONFIG_CIFS_STATS */
+ if(tcon != NULL)
+ cifs_stats_inc(&tcon->num_smbs_sent);
+
return rc;
}
@@ -222,6 +223,9 @@ smb_init(int smb_command, int wct, struct cifsTconInfo *tcon,
rc = CIFSTCon(0, tcon->ses, tcon->treeName,
tcon, nls_codepage);
up(&tcon->ses->sesSem);
+ /* BB FIXME add code to check if wsize needs
+ update due to negotiated smb buffer size
+ shrinking */
if(rc == 0)
atomic_inc(&tconInfoReconnectCount);
@@ -269,11 +273,9 @@ smb_init(int smb_command, int wct, struct cifsTconInfo *tcon,
header_assemble((struct smb_hdr *) *request_buf, smb_command, tcon,
wct /*wct */ );
-#ifdef CONFIG_CIFS_STATS
- if(tcon != NULL) {
- atomic_inc(&tcon->num_smbs_sent);
- }
-#endif /* CONFIG_CIFS_STATS */
+ if(tcon != NULL)
+ cifs_stats_inc(&tcon->num_smbs_sent);
+
return rc;
}
@@ -330,7 +332,7 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
(void **) &pSMB, (void **) &pSMBr);
if (rc)
return rc;
-
+ pSMB->hdr.Mid = GetNextMid(server);
pSMB->hdr.Flags2 |= SMBFLG2_UNICODE;
if (extended_security)
pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC;
@@ -422,8 +424,8 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
}
}
- if (pSMB)
- cifs_buf_release(pSMB);
+
+ cifs_buf_release(pSMB);
return rc;
}
@@ -518,6 +520,8 @@ CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses)
smb_buffer_response = (struct smb_hdr *)pSMB; /* BB removeme BB */
if(ses->server) {
+ pSMB->hdr.Mid = GetNextMid(ses->server);
+
if(ses->server->secMode &
(SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
@@ -537,9 +541,8 @@ CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses)
rc = -ESHUTDOWN;
}
}
- if (pSMB)
- cifs_small_buf_release(pSMB);
up(&ses->sesSem);
+ cifs_small_buf_release(pSMB);
/* if session dead then we do not need to do ulogoff,
since server closed smb session, no sense reporting
@@ -583,14 +586,10 @@ DelFileRetry:
pSMB->ByteCount = cpu_to_le16(name_len + 1);
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
(struct smb_hdr *) pSMBr, &bytes_returned, 0);
+ cifs_stats_inc(&tcon->num_deletes);
if (rc) {
cFYI(1, ("Error in RMFile = %d", rc));
}
-#ifdef CONFIG_CIFS_STATS
- else {
- atomic_inc(&tcon->num_deletes);
- }
-#endif
cifs_buf_release(pSMB);
if (rc == -EAGAIN)
@@ -632,14 +631,10 @@ RmDirRetry:
pSMB->ByteCount = cpu_to_le16(name_len + 1);
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
(struct smb_hdr *) pSMBr, &bytes_returned, 0);
+ cifs_stats_inc(&tcon->num_rmdirs);
if (rc) {
cFYI(1, ("Error in RMDir = %d", rc));
}
-#ifdef CONFIG_CIFS_STATS
- else {
- atomic_inc(&tcon->num_rmdirs);
- }
-#endif
cifs_buf_release(pSMB);
if (rc == -EAGAIN)
@@ -680,20 +675,161 @@ MkDirRetry:
pSMB->ByteCount = cpu_to_le16(name_len + 1);
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
(struct smb_hdr *) pSMBr, &bytes_returned, 0);
+ cifs_stats_inc(&tcon->num_mkdirs);
if (rc) {
cFYI(1, ("Error in Mkdir = %d", rc));
}
-#ifdef CONFIG_CIFS_STATS
- else {
- atomic_inc(&tcon->num_mkdirs);
- }
-#endif
+
cifs_buf_release(pSMB);
if (rc == -EAGAIN)
goto MkDirRetry;
return rc;
}
+static __u16 convert_disposition(int disposition)
+{
+ __u16 ofun = 0;
+
+ switch (disposition) {
+ case FILE_SUPERSEDE:
+ ofun = SMBOPEN_OCREATE | SMBOPEN_OTRUNC;
+ break;
+ case FILE_OPEN:
+ ofun = SMBOPEN_OAPPEND;
+ break;
+ case FILE_CREATE:
+ ofun = SMBOPEN_OCREATE;
+ break;
+ case FILE_OPEN_IF:
+ ofun = SMBOPEN_OCREATE | SMBOPEN_OAPPEND;
+ break;
+ case FILE_OVERWRITE:
+ ofun = SMBOPEN_OTRUNC;
+ break;
+ case FILE_OVERWRITE_IF:
+ ofun = SMBOPEN_OCREATE | SMBOPEN_OTRUNC;
+ break;
+ default:
+ cFYI(1,("unknown disposition %d",disposition));
+ ofun = SMBOPEN_OAPPEND; /* regular open */
+ }
+ return ofun;
+}
+
+int
+SMBLegacyOpen(const int xid, struct cifsTconInfo *tcon,
+ const char *fileName, const int openDisposition,
+ const int access_flags, const int create_options, __u16 * netfid,
+ int *pOplock, FILE_ALL_INFO * pfile_info,
+ const struct nls_table *nls_codepage, int remap)
+{
+ int rc = -EACCES;
+ OPENX_REQ *pSMB = NULL;
+ OPENX_RSP *pSMBr = NULL;
+ int bytes_returned;
+ int name_len;
+ __u16 count;
+
+OldOpenRetry:
+ rc = smb_init(SMB_COM_OPEN_ANDX, 15, tcon, (void **) &pSMB,
+ (void **) &pSMBr);
+ if (rc)
+ return rc;
+
+ pSMB->AndXCommand = 0xFF; /* none */
+
+ if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
+ count = 1; /* account for one byte pad to word boundary */
+ name_len =
+ cifsConvertToUCS((__le16 *) (pSMB->fileName + 1),
+ fileName, PATH_MAX, nls_codepage, remap);
+ name_len++; /* trailing null */
+ name_len *= 2;
+ } else { /* BB improve check for buffer overruns BB */
+ count = 0; /* no pad */
+ name_len = strnlen(fileName, PATH_MAX);
+ name_len++; /* trailing null */
+ strncpy(pSMB->fileName, fileName, name_len);
+ }
+ if (*pOplock & REQ_OPLOCK)
+ pSMB->OpenFlags = cpu_to_le16(REQ_OPLOCK);
+ else if (*pOplock & REQ_BATCHOPLOCK) {
+ pSMB->OpenFlags = cpu_to_le16(REQ_BATCHOPLOCK);
+ }
+ pSMB->OpenFlags |= cpu_to_le16(REQ_MORE_INFO);
+ /* BB fixme add conversion for access_flags to bits 0 - 2 of mode */
+ /* 0 = read
+ 1 = write
+ 2 = rw
+ 3 = execute
+ */
+ pSMB->Mode = cpu_to_le16(2);
+ pSMB->Mode |= cpu_to_le16(0x40); /* deny none */
+ /* set file as system file if special file such
+ as fifo and server expecting SFU style and
+ no Unix extensions */
+
+ if(create_options & CREATE_OPTION_SPECIAL)
+ pSMB->FileAttributes = cpu_to_le16(ATTR_SYSTEM);
+ else
+ pSMB->FileAttributes = cpu_to_le16(0/*ATTR_NORMAL*/); /* BB FIXME */
+
+ /* if ((omode & S_IWUGO) == 0)
+ pSMB->FileAttributes |= cpu_to_le32(ATTR_READONLY);*/
+ /* Above line causes problems due to vfs splitting create into two
+ pieces - need to set mode after file created not while it is
+ being created */
+
+ /* BB FIXME BB */
+/* pSMB->CreateOptions = cpu_to_le32(create_options & CREATE_OPTIONS_MASK); */
+ /* BB FIXME END BB */
+
+ pSMB->Sattr = cpu_to_le16(ATTR_HIDDEN | ATTR_SYSTEM | ATTR_DIRECTORY);
+ pSMB->OpenFunction = cpu_to_le16(convert_disposition(openDisposition));
+ count += name_len;
+ pSMB->hdr.smb_buf_length += count;
+
+ pSMB->ByteCount = cpu_to_le16(count);
+ /* long_op set to 1 to allow for oplock break timeouts */
+ rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
+ (struct smb_hdr *) pSMBr, &bytes_returned, 1);
+ cifs_stats_inc(&tcon->num_opens);
+ if (rc) {
+ cFYI(1, ("Error in Open = %d", rc));
+ } else {
+ /* BB verify if wct == 15 */
+
+/* *pOplock = pSMBr->OplockLevel; */ /* BB take from action field BB */
+
+ *netfid = pSMBr->Fid; /* cifs fid stays in le */
+ /* Let caller know file was created so we can set the mode. */
+ /* Do we care about the CreateAction in any other cases? */
+ /* BB FIXME BB */
+/* if(cpu_to_le32(FILE_CREATE) == pSMBr->CreateAction)
+ *pOplock |= CIFS_CREATE_ACTION; */
+ /* BB FIXME END */
+
+ if(pfile_info) {
+ pfile_info->CreationTime = 0; /* BB convert CreateTime*/
+ pfile_info->LastAccessTime = 0; /* BB fixme */
+ pfile_info->LastWriteTime = 0; /* BB fixme */
+ pfile_info->ChangeTime = 0; /* BB fixme */
+ pfile_info->Attributes =
+ cpu_to_le32(le16_to_cpu(pSMBr->FileAttributes));
+ /* the file_info buf is endian converted by caller */
+ pfile_info->AllocationSize =
+ cpu_to_le64(le32_to_cpu(pSMBr->EndOfFile));
+ pfile_info->EndOfFile = pfile_info->AllocationSize;
+ pfile_info->NumberOfLinks = cpu_to_le32(1);
+ }
+ }
+
+ cifs_buf_release(pSMB);
+ if (rc == -EAGAIN)
+ goto OldOpenRetry;
+ return rc;
+}
+
int
CIFSSMBOpen(const int xid, struct cifsTconInfo *tcon,
const char *fileName, const int openDisposition,
@@ -738,7 +874,13 @@ openRetry:
}
pSMB->DesiredAccess = cpu_to_le32(access_flags);
pSMB->AllocationSize = 0;
- pSMB->FileAttributes = cpu_to_le32(ATTR_NORMAL);
+ /* set file as system file if special file such
+ as fifo and server expecting SFU style and
+ no Unix extensions */
+ if(create_options & CREATE_OPTION_SPECIAL)
+ pSMB->FileAttributes = cpu_to_le32(ATTR_SYSTEM);
+ else
+ pSMB->FileAttributes = cpu_to_le32(ATTR_NORMAL);
/* XP does not handle ATTR_POSIX_SEMANTICS */
/* but it helps speed up case sensitive checks for other
servers such as Samba */
@@ -752,7 +894,7 @@ openRetry:
being created */
pSMB->ShareAccess = cpu_to_le32(FILE_SHARE_ALL);
pSMB->CreateDisposition = cpu_to_le32(openDisposition);
- pSMB->CreateOptions = cpu_to_le32(create_options);
+ pSMB->CreateOptions = cpu_to_le32(create_options & CREATE_OPTIONS_MASK);
/* BB Expirement with various impersonation levels and verify */
pSMB->ImpersonationLevel = cpu_to_le32(SECURITY_IMPERSONATION);
pSMB->SecurityFlags =
@@ -765,6 +907,7 @@ openRetry:
/* long_op set to 1 to allow for oplock break timeouts */
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
(struct smb_hdr *) pSMBr, &bytes_returned, 1);
+ cifs_stats_inc(&tcon->num_opens);
if (rc) {
cFYI(1, ("Error in Open = %d", rc));
} else {
@@ -782,11 +925,8 @@ openRetry:
pfile_info->EndOfFile = pSMBr->EndOfFile;
pfile_info->NumberOfLinks = cpu_to_le32(1);
}
-
-#ifdef CONFIG_CIFS_STATS
- atomic_inc(&tcon->num_opens);
-#endif
}
+
cifs_buf_release(pSMB);
if (rc == -EAGAIN)
goto openRetry;
@@ -807,11 +947,16 @@ CIFSSMBRead(const int xid, struct cifsTconInfo *tcon,
READ_RSP *pSMBr = NULL;
char *pReadData = NULL;
int bytes_returned;
+ int wct;
cFYI(1,("Reading %d bytes on fid %d",count,netfid));
+ if(tcon->ses->capabilities & CAP_LARGE_FILES)
+ wct = 12;
+ else
+ wct = 10; /* old style read */
*nbytes = 0;
- rc = smb_init(SMB_COM_READ_ANDX, 12, tcon, (void **) &pSMB,
+ rc = smb_init(SMB_COM_READ_ANDX, wct, tcon, (void **) &pSMB,
(void **) &pSMBr);
if (rc)
return rc;
@@ -823,14 +968,26 @@ CIFSSMBRead(const int xid, struct cifsTconInfo *tcon,
pSMB->AndXCommand = 0xFF; /* none */
pSMB->Fid = netfid;
pSMB->OffsetLow = cpu_to_le32(lseek & 0xFFFFFFFF);
- pSMB->OffsetHigh = cpu_to_le32(lseek >> 32);
+ if(wct == 12)
+ pSMB->OffsetHigh = cpu_to_le32(lseek >> 32);
+ else if((lseek >> 32) > 0) /* can not handle this big offset for old */
+ return -EIO;
+
pSMB->Remaining = 0;
pSMB->MaxCount = cpu_to_le16(count & 0xFFFF);
pSMB->MaxCountHigh = cpu_to_le32(count >> 16);
- pSMB->ByteCount = 0; /* no need to do le conversion since it is 0 */
-
+ if(wct == 12)
+ pSMB->ByteCount = 0; /* no need to do le conversion since 0 */
+ else {
+ /* old style read */
+ struct smb_com_readx_req * pSMBW =
+ (struct smb_com_readx_req *)pSMB;
+ pSMBW->ByteCount = 0;
+ }
+
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
(struct smb_hdr *) pSMBr, &bytes_returned, 0);
+ cifs_stats_inc(&tcon->num_reads);
if (rc) {
cERROR(1, ("Send error in read = %d", rc));
} else {
@@ -876,12 +1033,20 @@ CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
int rc = -EACCES;
WRITE_REQ *pSMB = NULL;
WRITE_RSP *pSMBr = NULL;
- int bytes_returned;
+ int bytes_returned, wct;
__u32 bytes_sent;
__u16 byte_count;
/* cFYI(1,("write at %lld %d bytes",offset,count));*/
- rc = smb_init(SMB_COM_WRITE_ANDX, 14, tcon, (void **) &pSMB,
+ if(tcon->ses == NULL)
+ return -ECONNABORTED;
+
+ if(tcon->ses->capabilities & CAP_LARGE_FILES)
+ wct = 14;
+ else
+ wct = 12;
+
+ rc = smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB,
(void **) &pSMBr);
if (rc)
return rc;
@@ -892,7 +1057,11 @@ CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
pSMB->AndXCommand = 0xFF; /* none */
pSMB->Fid = netfid;
pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
- pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
+ if(wct == 14)
+ pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
+ else if((offset >> 32) > 0) /* can not handle this big offset for old */
+ return -EIO;
+
pSMB->Reserved = 0xFFFFFFFF;
pSMB->WriteMode = 0;
pSMB->Remaining = 0;
@@ -911,7 +1080,7 @@ CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
if (bytes_sent > count)
bytes_sent = count;
pSMB->DataOffset =
- cpu_to_le16(offsetof(struct smb_com_write_req,Data) - 4);
+ cpu_to_le16(offsetof(struct smb_com_write_req,Data) - 4);
if(buf)
memcpy(pSMB->Data,buf,bytes_sent);
else if(ubuf) {
@@ -919,20 +1088,31 @@ CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
cifs_buf_release(pSMB);
return -EFAULT;
}
- } else {
+ } else if (count != 0) {
/* No buffer */
cifs_buf_release(pSMB);
return -EINVAL;
+ } /* else setting file size with write of zero bytes */
+ if(wct == 14)
+ byte_count = bytes_sent + 1; /* pad */
+ else /* wct == 12 */ {
+ byte_count = bytes_sent + 5; /* bigger pad, smaller smb hdr */
}
-
- byte_count = bytes_sent + 1 /* pad */ ; /* BB fix this for sends > 64K */
pSMB->DataLengthLow = cpu_to_le16(bytes_sent & 0xFFFF);
pSMB->DataLengthHigh = cpu_to_le16(bytes_sent >> 16);
- pSMB->hdr.smb_buf_length += bytes_sent+1;
- pSMB->ByteCount = cpu_to_le16(byte_count);
+ pSMB->hdr.smb_buf_length += byte_count;
+
+ if(wct == 14)
+ pSMB->ByteCount = cpu_to_le16(byte_count);
+ else { /* old style write has byte count 4 bytes earlier so 4 bytes pad */
+ struct smb_com_writex_req * pSMBW =
+ (struct smb_com_writex_req *)pSMB;
+ pSMBW->ByteCount = cpu_to_le16(byte_count);
+ }
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
(struct smb_hdr *) pSMBr, &bytes_returned, long_op);
+ cifs_stats_inc(&tcon->num_writes);
if (rc) {
cFYI(1, ("Send error in write = %d", rc));
*nbytes = 0;
@@ -951,56 +1131,72 @@ CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
}
#ifdef CONFIG_CIFS_EXPERIMENTAL
-int CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
+int
+CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
const int netfid, const unsigned int count,
- const __u64 offset, unsigned int *nbytes, const char __user *buf,
- const int long_op)
+ const __u64 offset, unsigned int *nbytes, struct kvec *iov,
+ int n_vec, const int long_op)
{
int rc = -EACCES;
WRITE_REQ *pSMB = NULL;
- WRITE_RSP *pSMBr = NULL;
- /*int bytes_returned;*/
- unsigned bytes_sent;
- __u16 byte_count;
+ int bytes_returned, wct;
+ int smb_hdr_len;
- rc = small_smb_init(SMB_COM_WRITE_ANDX, 14, tcon, (void **) &pSMB);
-
+ cFYI(1,("write2 at %lld %d bytes",offset,count)); /* BB removeme BB */
+ if(tcon->ses->capabilities & CAP_LARGE_FILES)
+ wct = 14;
+ else
+ wct = 12;
+ rc = small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB);
if (rc)
return rc;
-
- pSMBr = (WRITE_RSP *)pSMB; /* BB removeme BB */
-
/* tcon and ses pointer are checked in smb_init */
if (tcon->ses->server == NULL)
return -ECONNABORTED;
- pSMB->AndXCommand = 0xFF; /* none */
+ pSMB->AndXCommand = 0xFF; /* none */
pSMB->Fid = netfid;
pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
- pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
+ if(wct == 14)
+ pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
+ else if((offset >> 32) > 0) /* can not handle this big offset for old */
+ return -EIO;
pSMB->Reserved = 0xFFFFFFFF;
pSMB->WriteMode = 0;
pSMB->Remaining = 0;
- bytes_sent = (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE) & ~0xFF;
- if (bytes_sent > count)
- bytes_sent = count;
- pSMB->DataLengthHigh = 0;
+
pSMB->DataOffset =
cpu_to_le16(offsetof(struct smb_com_write_req,Data) - 4);
- byte_count = bytes_sent + 1 /* pad */ ;
- pSMB->DataLengthLow = cpu_to_le16(bytes_sent);
- pSMB->DataLengthHigh = 0;
- pSMB->hdr.smb_buf_length += byte_count;
- pSMB->ByteCount = cpu_to_le16(byte_count);
+ pSMB->DataLengthLow = cpu_to_le16(count & 0xFFFF);
+ pSMB->DataLengthHigh = cpu_to_le16(count >> 16);
+ smb_hdr_len = pSMB->hdr.smb_buf_length + 1; /* hdr + 1 byte pad */
+ if(wct == 14)
+ pSMB->hdr.smb_buf_length += count+1;
+ else /* wct == 12 */
+ pSMB->hdr.smb_buf_length += count+5; /* smb data starts later */
+ if(wct == 14)
+ pSMB->ByteCount = cpu_to_le16(count + 1);
+ else /* wct == 12 */ /* bigger pad, smaller smb hdr, keep offset ok */ {
+ struct smb_com_writex_req * pSMBW =
+ (struct smb_com_writex_req *)pSMB;
+ pSMBW->ByteCount = cpu_to_le16(count + 5);
+ }
+ iov[0].iov_base = pSMB;
+ iov[0].iov_len = smb_hdr_len + 4;
-/* rc = SendReceive2(xid, tcon->ses, (struct smb_hdr *) pSMB,
- (struct smb_hdr *) pSMBr, buf, buflen, &bytes_returned, long_op); */ /* BB fixme BB */
+ rc = SendReceive2(xid, tcon->ses, iov, n_vec + 1, &bytes_returned,
+ long_op);
+ cifs_stats_inc(&tcon->num_writes);
if (rc) {
- cFYI(1, ("Send error in write2 (large write) = %d", rc));
+ cFYI(1, ("Send error Write2 = %d", rc));
*nbytes = 0;
- } else
- *nbytes = le16_to_cpu(pSMBr->Count);
+ } else {
+ WRITE_RSP * pSMBr = (WRITE_RSP *)pSMB;
+ *nbytes = le16_to_cpu(pSMBr->CountHigh);
+ *nbytes = (*nbytes) << 16;
+ *nbytes += le16_to_cpu(pSMBr->Count);
+ }
cifs_small_buf_release(pSMB);
@@ -1009,6 +1205,8 @@ int CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
return rc;
}
+
+
#endif /* CIFS_EXPERIMENTAL */
int
@@ -1065,7 +1263,7 @@ CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
(struct smb_hdr *) pSMBr, &bytes_returned, timeout);
-
+ cifs_stats_inc(&tcon->num_locks);
if (rc) {
cFYI(1, ("Send error in Lock = %d", rc));
}
@@ -1099,6 +1297,7 @@ CIFSSMBClose(const int xid, struct cifsTconInfo *tcon, int smb_file_id)
pSMB->ByteCount = 0;
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
(struct smb_hdr *) pSMBr, &bytes_returned, 0);
+ cifs_stats_inc(&tcon->num_closes);
if (rc) {
if(rc!=-EINTR) {
/* EINTR is expected when user ctl-c to kill app */
@@ -1171,16 +1370,11 @@ renameRetry:
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
(struct smb_hdr *) pSMBr, &bytes_returned, 0);
+ cifs_stats_inc(&tcon->num_renames);
if (rc) {
cFYI(1, ("Send error in rename = %d", rc));
}
-#ifdef CONFIG_CIFS_STATS
- else {
- atomic_inc(&tcon->num_renames);
- }
-#endif
-
cifs_buf_release(pSMB);
if (rc == -EAGAIN)
@@ -1255,14 +1449,11 @@ int CIFSSMBRenameOpenFile(const int xid,struct cifsTconInfo *pTcon,
pSMB->ByteCount = cpu_to_le16(byte_count);
rc = SendReceive(xid, pTcon->ses, (struct smb_hdr *) pSMB,
(struct smb_hdr *) pSMBr, &bytes_returned, 0);
+ cifs_stats_inc(&pTcon->num_t2renames);
if (rc) {
cFYI(1,("Send error in Rename (by file handle) = %d", rc));
}
-#ifdef CONFIG_CIFS_STATS
- else {
- atomic_inc(&pTcon->num_t2renames);
- }
-#endif
+
cifs_buf_release(pSMB);
/* Note: On -EAGAIN error only caller can retry on handle based calls
@@ -1416,6 +1607,7 @@ createSymLinkRetry:
pSMB->ByteCount = cpu_to_le16(byte_count);
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
(struct smb_hdr *) pSMBr, &bytes_returned, 0);
+ cifs_stats_inc(&tcon->num_symlinks);
if (rc) {
cFYI(1,
("Send error in SetPathInfo (create symlink) = %d",
@@ -1505,6 +1697,7 @@ createHardLinkRetry:
pSMB->ByteCount = cpu_to_le16(byte_count);
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
(struct smb_hdr *) pSMBr, &bytes_returned, 0);
+ cifs_stats_inc(&tcon->num_hardlinks);
if (rc) {
cFYI(1, ("Send error in SetPathInfo (hard link) = %d", rc));
}
@@ -1575,6 +1768,7 @@ winCreateHardLinkRetry:
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
(struct smb_hdr *) pSMBr, &bytes_returned, 0);
+ cifs_stats_inc(&tcon->num_hardlinks);
if (rc) {
cFYI(1, ("Send error in hard link (NT rename) = %d", rc));
}
@@ -1775,8 +1969,7 @@ CIFSSMBQueryReparseLinkInfo(const int xid, struct cifsTconInfo *tcon,
}
}
qreparse_out:
- if (pSMB)
- cifs_buf_release(pSMB);
+ cifs_buf_release(pSMB);
/* Note: On -EAGAIN error only caller can retry on handle based calls
since file handle passed in no longer valid */
@@ -2165,6 +2358,67 @@ GetExtAttrOut:
#endif /* CONFIG_POSIX */
+/* Legacy Query Path Information call for lookup to old servers such
+ as Win9x/WinME */
+int SMBQueryInformation(const int xid, struct cifsTconInfo *tcon,
+ const unsigned char *searchName,
+ FILE_ALL_INFO * pFinfo,
+ const struct nls_table *nls_codepage, int remap)
+{
+ QUERY_INFORMATION_REQ * pSMB;
+ QUERY_INFORMATION_RSP * pSMBr;
+ int rc = 0;
+ int bytes_returned;
+ int name_len;
+
+ cFYI(1, ("In SMBQPath path %s", searchName));
+QInfRetry:
+ rc = smb_init(SMB_COM_QUERY_INFORMATION, 0, tcon, (void **) &pSMB,
+ (void **) &pSMBr);
+ if (rc)
+ return rc;
+
+ if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
+ name_len =
+ cifsConvertToUCS((__le16 *) pSMB->FileName, searchName,
+ PATH_MAX, nls_codepage, remap);
+ name_len++; /* trailing null */
+ name_len *= 2;
+ } else {
+ name_len = strnlen(searchName, PATH_MAX);
+ name_len++; /* trailing null */
+ strncpy(pSMB->FileName, searchName, name_len);
+ }
+ pSMB->BufferFormat = 0x04;
+ name_len++; /* account for buffer type byte */
+ pSMB->hdr.smb_buf_length += (__u16) name_len;
+ pSMB->ByteCount = cpu_to_le16(name_len);
+
+ rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
+ (struct smb_hdr *) pSMBr, &bytes_returned, 0);
+ if (rc) {
+ cFYI(1, ("Send error in QueryInfo = %d", rc));
+ } else if (pFinfo) { /* decode response */
+ memset(pFinfo, 0, sizeof(FILE_ALL_INFO));
+ pFinfo->AllocationSize =
+ cpu_to_le64(le32_to_cpu(pSMBr->size));
+ pFinfo->EndOfFile = pFinfo->AllocationSize;
+ pFinfo->Attributes =
+ cpu_to_le32(le16_to_cpu(pSMBr->attr));
+ } else
+ rc = -EIO; /* bad buffer passed in */
+
+ cifs_buf_release(pSMB);
+
+ if (rc == -EAGAIN)
+ goto QInfRetry;
+
+ return rc;
+}
+
+
+
+
int
CIFSSMBQPathInfo(const int xid, struct cifsTconInfo *tcon,
const unsigned char *searchName,
@@ -2396,7 +2650,7 @@ findUniqueRetry:
if (rc) {
cFYI(1, ("Send error in FindFileDirInfo = %d", rc));
} else { /* decode response */
-
+ cifs_stats_inc(&tcon->num_ffirst);
/* BB fill in */
}
@@ -2414,7 +2668,7 @@ CIFSFindFirst(const int xid, struct cifsTconInfo *tcon,
const char *searchName,
const struct nls_table *nls_codepage,
__u16 * pnetfid,
- struct cifs_search_info * psrch_inf, int remap)
+ struct cifs_search_info * psrch_inf, int remap, const char dirsep)
{
/* level 257 SMB_ */
TRANSACTION2_FFIRST_REQ *pSMB = NULL;
@@ -2441,7 +2695,7 @@ findFirstRetry:
it got remapped to 0xF03A as if it were part of the
directory name instead of a wildcard */
name_len *= 2;
- pSMB->FileName[name_len] = '\\';
+ pSMB->FileName[name_len] = dirsep;
pSMB->FileName[name_len+1] = 0;
pSMB->FileName[name_len+2] = '*';
pSMB->FileName[name_len+3] = 0;
@@ -2455,7 +2709,7 @@ findFirstRetry:
if(name_len > buffersize-header)
free buffer exit; BB */
strncpy(pSMB->FileName, searchName, name_len);
- pSMB->FileName[name_len] = '\\';
+ pSMB->FileName[name_len] = dirsep;
pSMB->FileName[name_len+1] = '*';
pSMB->FileName[name_len+2] = 0;
name_len += 3;
@@ -2496,6 +2750,7 @@ findFirstRetry:
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
(struct smb_hdr *) pSMBr, &bytes_returned, 0);
+ cifs_stats_inc(&tcon->num_ffirst);
if (rc) {/* BB add logic to retry regular search if Unix search rejected unexpectedly by server */
/* BB Add code to handle unsupported level rc */
@@ -2617,7 +2872,7 @@ int CIFSFindNext(const int xid, struct cifsTconInfo *tcon,
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
(struct smb_hdr *) pSMBr, &bytes_returned, 0);
-
+ cifs_stats_inc(&tcon->num_fnext);
if (rc) {
if (rc == -EBADF) {
psrch_inf->endOfSearch = TRUE;
@@ -2694,6 +2949,7 @@ CIFSFindClose(const int xid, struct cifsTconInfo *tcon, const __u16 searchHandle
if (rc) {
cERROR(1, ("Send error in FindClose = %d", rc));
}
+ cifs_stats_inc(&tcon->num_fclose);
cifs_small_buf_release(pSMB);
/* Since session is dead, search handle closed on server already */
@@ -2703,7 +2959,6 @@ CIFSFindClose(const int xid, struct cifsTconInfo *tcon, const __u16 searchHandle
return rc;
}
-#ifdef CONFIG_CIFS_EXPERIMENTAL
int
CIFSGetSrvInodeNumber(const int xid, struct cifsTconInfo *tcon,
const unsigned char *searchName,
@@ -2797,7 +3052,6 @@ GetInodeNumOut:
goto GetInodeNumberRetry;
return rc;
}
-#endif /* CIFS_EXPERIMENTAL */
int
CIFSGetDFSRefer(const int xid, struct cifsSesInfo *ses,
@@ -2827,7 +3081,10 @@ getDFSRetry:
(void **) &pSMBr);
if (rc)
return rc;
-
+
+ /* server pointer checked in called function,
+ but should never be null here anyway */
+ pSMB->hdr.Mid = GetNextMid(ses->server);
pSMB->hdr.Tid = ses->ipc_tid;
pSMB->hdr.Uid = ses->Suid;
if (ses->capabilities & CAP_STATUS32) {
@@ -2968,6 +3225,92 @@ GetDFSRefExit:
return rc;
}
+/* Query File System Info such as free space to old servers such as Win 9x */
+int
+SMBOldQFSInfo(const int xid, struct cifsTconInfo *tcon, struct kstatfs *FSData)
+{
+/* level 0x01 SMB_QUERY_FILE_SYSTEM_INFO */
+ TRANSACTION2_QFSI_REQ *pSMB = NULL;
+ TRANSACTION2_QFSI_RSP *pSMBr = NULL;
+ FILE_SYSTEM_ALLOC_INFO *response_data;
+ int rc = 0;
+ int bytes_returned = 0;
+ __u16 params, byte_count;
+
+ cFYI(1, ("OldQFSInfo"));
+oldQFSInfoRetry:
+ rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
+ (void **) &pSMBr);
+ if (rc)
+ return rc;
+ rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
+ (void **) &pSMBr);
+ if (rc)
+ return rc;
+
+ params = 2; /* level */
+ pSMB->TotalDataCount = 0;
+ pSMB->MaxParameterCount = cpu_to_le16(2);
+ pSMB->MaxDataCount = cpu_to_le16(1000);
+ pSMB->MaxSetupCount = 0;
+ pSMB->Reserved = 0;
+ pSMB->Flags = 0;
+ pSMB->Timeout = 0;
+ pSMB->Reserved2 = 0;
+ byte_count = params + 1 /* pad */ ;
+ pSMB->TotalParameterCount = cpu_to_le16(params);
+ pSMB->ParameterCount = pSMB->TotalParameterCount;
+ pSMB->ParameterOffset = cpu_to_le16(offsetof(
+ struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
+ pSMB->DataCount = 0;
+ pSMB->DataOffset = 0;
+ pSMB->SetupCount = 1;
+ pSMB->Reserved3 = 0;
+ pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
+ pSMB->InformationLevel = cpu_to_le16(SMB_INFO_ALLOCATION);
+ pSMB->hdr.smb_buf_length += byte_count;
+ pSMB->ByteCount = cpu_to_le16(byte_count);
+
+ rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
+ (struct smb_hdr *) pSMBr, &bytes_returned, 0);
+ if (rc) {
+ cFYI(1, ("Send error in QFSInfo = %d", rc));
+ } else { /* decode response */
+ rc = validate_t2((struct smb_t2_rsp *)pSMBr);
+
+ if (rc || (pSMBr->ByteCount < 18))
+ rc = -EIO; /* bad smb */
+ else {
+ __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
+ cFYI(1,("qfsinf resp BCC: %d Offset %d",
+ pSMBr->ByteCount, data_offset));
+
+ response_data =
+ (FILE_SYSTEM_ALLOC_INFO *)
+ (((char *) &pSMBr->hdr.Protocol) + data_offset);
+ FSData->f_bsize =
+ le16_to_cpu(response_data->BytesPerSector) *
+ le32_to_cpu(response_data->
+ SectorsPerAllocationUnit);
+ FSData->f_blocks =
+ le32_to_cpu(response_data->TotalAllocationUnits);
+ FSData->f_bfree = FSData->f_bavail =
+ le32_to_cpu(response_data->FreeAllocationUnits);
+ cFYI(1,
+ ("Blocks: %lld Free: %lld Block size %ld",
+ (unsigned long long)FSData->f_blocks,
+ (unsigned long long)FSData->f_bfree,
+ FSData->f_bsize));
+ }
+ }
+ cifs_buf_release(pSMB);
+
+ if (rc == -EAGAIN)
+ goto oldQFSInfoRetry;
+
+ return rc;
+}
+
int
CIFSSMBQFSInfo(const int xid, struct cifsTconInfo *tcon, struct kstatfs *FSData)
{
@@ -2989,7 +3332,7 @@ QFSInfoRetry:
params = 2; /* level */
pSMB->TotalDataCount = 0;
pSMB->MaxParameterCount = cpu_to_le16(2);
- pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find exact max SMB PDU from sess structure BB */
+ pSMB->MaxDataCount = cpu_to_le16(1000);
pSMB->MaxSetupCount = 0;
pSMB->Reserved = 0;
pSMB->Flags = 0;
@@ -3012,17 +3355,14 @@ QFSInfoRetry:
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
(struct smb_hdr *) pSMBr, &bytes_returned, 0);
if (rc) {
- cERROR(1, ("Send error in QFSInfo = %d", rc));
+ cFYI(1, ("Send error in QFSInfo = %d", rc));
} else { /* decode response */
rc = validate_t2((struct smb_t2_rsp *)pSMBr);
- if (rc || (pSMBr->ByteCount < 24)) /* BB alsO CHEck enough total bytes returned */
+ if (rc || (pSMBr->ByteCount < 24))
rc = -EIO; /* bad smb */
else {
__u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
- cFYI(1,
- ("Decoding qfsinfo response. BCC: %d Offset %d",
- pSMBr->ByteCount, data_offset));
response_data =
(FILE_SYSTEM_INFO
@@ -3257,6 +3597,77 @@ QFSUnixRetry:
return rc;
}
+int
+CIFSSMBSetFSUnixInfo(const int xid, struct cifsTconInfo *tcon, __u64 cap)
+{
+/* level 0x200 SMB_SET_CIFS_UNIX_INFO */
+ TRANSACTION2_SETFSI_REQ *pSMB = NULL;
+ TRANSACTION2_SETFSI_RSP *pSMBr = NULL;
+ int rc = 0;
+ int bytes_returned = 0;
+ __u16 params, param_offset, offset, byte_count;
+
+ cFYI(1, ("In SETFSUnixInfo"));
+SETFSUnixRetry:
+ rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
+ (void **) &pSMBr);
+ if (rc)
+ return rc;
+
+ params = 4; /* 2 bytes zero followed by info level. */
+ pSMB->MaxSetupCount = 0;
+ pSMB->Reserved = 0;
+ pSMB->Flags = 0;
+ pSMB->Timeout = 0;
+ pSMB->Reserved2 = 0;
+ param_offset = offsetof(struct smb_com_transaction2_setfsi_req, FileNum) - 4;
+ offset = param_offset + params;
+
+ pSMB->MaxParameterCount = cpu_to_le16(4);
+ pSMB->MaxDataCount = cpu_to_le16(100); /* BB find exact max SMB PDU from sess structure BB */
+ pSMB->SetupCount = 1;
+ pSMB->Reserved3 = 0;
+ pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FS_INFORMATION);
+ byte_count = 1 /* pad */ + params + 12;
+
+ pSMB->DataCount = cpu_to_le16(12);
+ pSMB->ParameterCount = cpu_to_le16(params);
+ pSMB->TotalDataCount = pSMB->DataCount;
+ pSMB->TotalParameterCount = pSMB->ParameterCount;
+ pSMB->ParameterOffset = cpu_to_le16(param_offset);
+ pSMB->DataOffset = cpu_to_le16(offset);
+
+ /* Params. */
+ pSMB->FileNum = 0;
+ pSMB->InformationLevel = cpu_to_le16(SMB_SET_CIFS_UNIX_INFO);
+
+ /* Data. */
+ pSMB->ClientUnixMajor = cpu_to_le16(CIFS_UNIX_MAJOR_VERSION);
+ pSMB->ClientUnixMinor = cpu_to_le16(CIFS_UNIX_MINOR_VERSION);
+ pSMB->ClientUnixCap = cpu_to_le64(cap);
+
+ pSMB->hdr.smb_buf_length += byte_count;
+ pSMB->ByteCount = cpu_to_le16(byte_count);
+
+ rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
+ (struct smb_hdr *) pSMBr, &bytes_returned, 0);
+ if (rc) {
+ cERROR(1, ("Send error in SETFSUnixInfo = %d", rc));
+ } else { /* decode response */
+ rc = validate_t2((struct smb_t2_rsp *)pSMBr);
+ if (rc) {
+ rc = -EIO; /* bad smb */
+ }
+ }
+ cifs_buf_release(pSMB);
+
+ if (rc == -EAGAIN)
+ goto SETFSUnixRetry;
+
+ return rc;
+}
+
+
int
CIFSSMBQFSPosixInfo(const int xid, struct cifsTconInfo *tcon,
@@ -3321,16 +3732,16 @@ QFSPosixRetry:
le64_to_cpu(response_data->TotalBlocks);
FSData->f_bfree =
le64_to_cpu(response_data->BlocksAvail);
- if(response_data->UserBlocksAvail == -1) {
+ if(response_data->UserBlocksAvail == cpu_to_le64(-1)) {
FSData->f_bavail = FSData->f_bfree;
} else {
FSData->f_bavail =
le64_to_cpu(response_data->UserBlocksAvail);
}
- if(response_data->TotalFileNodes != -1)
+ if(response_data->TotalFileNodes != cpu_to_le64(-1))
FSData->f_files =
le64_to_cpu(response_data->TotalFileNodes);
- if(response_data->FreeFileNodes != -1)
+ if(response_data->FreeFileNodes != cpu_to_le64(-1))
FSData->f_ffree =
le64_to_cpu(response_data->FreeFileNodes);
}
@@ -3376,7 +3787,7 @@ SetEOFRetry:
PATH_MAX, nls_codepage, remap);
name_len++; /* trailing null */
name_len *= 2;
- } else { /* BB improve the check for buffer overruns BB */
+ } else { /* BB improve the check for buffer overruns BB */
name_len = strnlen(fileName, PATH_MAX);
name_len++; /* trailing null */
strncpy(pSMB->FileName, fileName, name_len);
@@ -3384,7 +3795,7 @@ SetEOFRetry:
params = 6 + name_len;
data_count = sizeof (struct file_end_of_file_info);
pSMB->MaxParameterCount = cpu_to_le16(2);
- pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB size from sess */
+ pSMB->MaxDataCount = cpu_to_le16(4100);
pSMB->MaxSetupCount = 0;
pSMB->Reserved = 0;
pSMB->Flags = 0;
@@ -3766,7 +4177,7 @@ setPermsRetry:
PATH_MAX, nls_codepage, remap);
name_len++; /* trailing null */
name_len *= 2;
- } else { /* BB improve the check for buffer overruns BB */
+ } else { /* BB improve the check for buffer overruns BB */
name_len = strnlen(fileName, PATH_MAX);
name_len++; /* trailing null */
strncpy(pSMB->FileName, fileName, name_len);
@@ -3839,12 +4250,14 @@ setPermsRetry:
}
int CIFSSMBNotify(const int xid, struct cifsTconInfo *tcon,
- const int notify_subdirs, const __u16 netfid,
- __u32 filter, const struct nls_table *nls_codepage)
+ const int notify_subdirs, const __u16 netfid,
+ __u32 filter, struct file * pfile, int multishot,
+ const struct nls_table *nls_codepage)
{
int rc = 0;
struct smb_com_transaction_change_notify_req * pSMB = NULL;
struct smb_com_transaction_change_notify_rsp * pSMBr = NULL;
+ struct dir_notify_req *dnotify_req;
int bytes_returned;
cFYI(1, ("In CIFSSMBNotify for file handle %d",(int)netfid));
@@ -3877,6 +4290,28 @@ int CIFSSMBNotify(const int xid, struct cifsTconInfo *tcon,
(struct smb_hdr *) pSMBr, &bytes_returned, -1);
if (rc) {
cFYI(1, ("Error in Notify = %d", rc));
+ } else {
+ /* Add file to outstanding requests */
+ /* BB change to kmem cache alloc */
+ dnotify_req = (struct dir_notify_req *) kmalloc(
+ sizeof(struct dir_notify_req),
+ GFP_KERNEL);
+ if(dnotify_req) {
+ dnotify_req->Pid = pSMB->hdr.Pid;
+ dnotify_req->PidHigh = pSMB->hdr.PidHigh;
+ dnotify_req->Mid = pSMB->hdr.Mid;
+ dnotify_req->Tid = pSMB->hdr.Tid;
+ dnotify_req->Uid = pSMB->hdr.Uid;
+ dnotify_req->netfid = netfid;
+ dnotify_req->pfile = pfile;
+ dnotify_req->filter = filter;
+ dnotify_req->multishot = multishot;
+ spin_lock(&GlobalMid_Lock);
+ list_add_tail(&dnotify_req->lhead,
+ &GlobalDnotifyReqList);
+ spin_unlock(&GlobalMid_Lock);
+ } else
+ rc = -ENOMEM;
}
cifs_buf_release(pSMB);
return rc;
diff --git a/fs/cifs/cn_cifs.h b/fs/cifs/cn_cifs.h
new file mode 100644
index 000000000000..ea59ccac2eb1
--- /dev/null
+++ b/fs/cifs/cn_cifs.h
@@ -0,0 +1,37 @@
+/*
+ * fs/cifs/cn_cifs.h
+ *
+ * Copyright (c) International Business Machines Corp., 2002
+ * Author(s): Steve French (sfrench@us.ibm.com)
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
+ * the GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _CN_CIFS_H
+#define _CN_CIFS_H
+#ifdef CONFIG_CIFS_UPCALL
+#include <linux/types.h>
+#include <linux/connector.h>
+
+struct cifs_upcall {
+ char signature[4]; /* CIFS */
+ enum command {
+ CIFS_GET_IP = 0x00000001, /* get ip address for hostname */
+ CIFS_GET_SECBLOB = 0x00000002, /* get SPNEGO wrapped blob */
+ } command;
+ /* union cifs upcall data follows */
+};
+#endif /* CIFS_UPCALL */
+#endif /* _CN_CIFS_H */
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 47360156cc54..2cb620716bc1 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -29,6 +29,8 @@
#include <linux/utsname.h>
#include <linux/mempool.h>
#include <linux/delay.h>
+#include <linux/completion.h>
+#include <linux/pagevec.h>
#include <asm/uaccess.h>
#include <asm/processor.h>
#include "cifspdu.h"
@@ -40,10 +42,13 @@
#include "ntlmssp.h"
#include "nterr.h"
#include "rfc1002pdu.h"
+#include "cn_cifs.h"
#define CIFS_PORT 445
#define RFC1001_PORT 139
+static DECLARE_COMPLETION(cifsd_complete);
+
extern void SMBencrypt(unsigned char *passwd, unsigned char *c8,
unsigned char *p24);
extern void SMBNTencrypt(unsigned char *passwd, unsigned char *c8,
@@ -60,6 +65,7 @@ struct smb_vol {
char *in6_addr; /* ipv6 address as human readable form of in6_addr */
char *iocharset; /* local code page for mapping to and from Unicode */
char source_rfc1001_name[16]; /* netbios name of client */
+ char target_rfc1001_name[16]; /* netbios name of server for Win9x/ME */
uid_t linux_uid;
gid_t linux_gid;
mode_t file_mode;
@@ -74,6 +80,10 @@ struct smb_vol {
unsigned server_ino:1; /* use inode numbers from server ie UniqueId */
unsigned direct_io:1;
unsigned remap:1; /* set to remap seven reserved chars in filenames */
+ unsigned posix_paths:1; /* unset to not ask for posix pathnames. */
+ unsigned sfu_emul:1;
+ unsigned nocase; /* request case insensitive filenames */
+ unsigned nobrl; /* disable sending byte range locks to srv */
unsigned int rsize;
unsigned int wsize;
unsigned int sockopt;
@@ -82,7 +92,8 @@ struct smb_vol {
static int ipv4_connect(struct sockaddr_in *psin_server,
struct socket **csocket,
- char * netb_name);
+ char * netb_name,
+ char * server_netb_name);
static int ipv6_connect(struct sockaddr_in6 *psin_server,
struct socket **csocket);
@@ -175,9 +186,11 @@ cifs_reconnect(struct TCP_Server_Info *server)
} else {
rc = ipv4_connect(&server->addr.sockAddr,
&server->ssocket,
- server->workstation_RFC1001_name);
+ server->workstation_RFC1001_name,
+ server->server_RFC1001_name);
}
if(rc) {
+ cFYI(1,("reconnect error %d",rc));
msleep(3000);
} else {
atomic_inc(&tcpSesReconnectCount);
@@ -293,12 +306,12 @@ static int coalesce_t2(struct smb_hdr * psecond, struct smb_hdr *pTargetSMB)
byte_count += total_in_buf2;
BCC_LE(pTargetSMB) = cpu_to_le16(byte_count);
- byte_count = be32_to_cpu(pTargetSMB->smb_buf_length);
+ byte_count = pTargetSMB->smb_buf_length;
byte_count += total_in_buf2;
/* BB also add check that we are not beyond maximum buffer size */
- pTargetSMB->smb_buf_length = cpu_to_be32(byte_count);
+ pTargetSMB->smb_buf_length = byte_count;
if(remaining == total_in_buf2) {
cFYI(1,("found the last secondary response"));
@@ -323,7 +336,7 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
struct cifsSesInfo *ses;
struct task_struct *task_to_wake = NULL;
struct mid_q_entry *mid_entry;
- char *temp;
+ char temp;
int isLargeBuf = FALSE;
int isMultiRsp;
int reconnect;
@@ -337,6 +350,7 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
atomic_inc(&tcpSesAllocCount);
length = tcpSesAllocCount.counter;
write_unlock(&GlobalSMBSeslock);
+ complete(&cifsd_complete);
if(length > 1) {
mempool_resize(cifs_req_poolp,
length + cifs_min_rcv,
@@ -424,22 +438,32 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
continue;
}
- /* the right amount was read from socket - 4 bytes */
+ /* The right amount was read from socket - 4 bytes */
+ /* so we can now interpret the length field */
+
+ /* the first byte big endian of the length field,
+ is actually not part of the length but the type
+ with the most common, zero, as regular data */
+ temp = *((char *) smb_buffer);
+ /* Note that FC 1001 length is big endian on the wire,
+ but we convert it here so it is always manipulated
+ as host byte order */
pdu_length = ntohl(smb_buffer->smb_buf_length);
- cFYI(1,("rfc1002 length(big endian)0x%x)", pdu_length+4));
+ smb_buffer->smb_buf_length = pdu_length;
+
+ cFYI(1,("rfc1002 length 0x%x)", pdu_length+4));
- temp = (char *) smb_buffer;
- if (temp[0] == (char) RFC1002_SESSION_KEEP_ALIVE) {
+ if (temp == (char) RFC1002_SESSION_KEEP_ALIVE) {
continue;
- } else if (temp[0] == (char)RFC1002_POSITIVE_SESSION_RESPONSE) {
+ } else if (temp == (char)RFC1002_POSITIVE_SESSION_RESPONSE) {
cFYI(1,("Good RFC 1002 session rsp"));
continue;
- } else if (temp[0] == (char)RFC1002_NEGATIVE_SESSION_RESPONSE) {
+ } else if (temp == (char)RFC1002_NEGATIVE_SESSION_RESPONSE) {
/* we get this from Windows 98 instead of
an error on SMB negprot response */
cFYI(1,("Negative RFC1002 Session Response Error 0x%x)",
- temp[4]));
+ pdu_length));
if(server->tcpStatus == CifsNew) {
/* if nack on negprot (rather than
ret of smb negprot error) reconnecting
@@ -461,9 +485,10 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
wake_up(&server->response_q);
continue;
}
- } else if (temp[0] != (char) 0) {
+ } else if (temp != (char) 0) {
cERROR(1,("Unknown RFC 1002 frame"));
- cifs_dump_mem(" Received Data: ", temp, length);
+ cifs_dump_mem(" Received Data: ", (char *)smb_buffer,
+ length);
cifs_reconnect(server);
csocket = server->ssocket;
continue;
@@ -533,7 +558,7 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
dump_smb(smb_buffer, length);
if (checkSMB (smb_buffer, smb_buffer->Mid, total_read+4)) {
- cERROR(1, ("Bad SMB Received "));
+ cifs_dump_mem("Bad SMB: ", smb_buffer, 48);
continue;
}
@@ -581,6 +606,9 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
multi_t2_fnd:
task_to_wake = mid_entry->tsk;
mid_entry->midState = MID_RESPONSE_RECEIVED;
+#ifdef CONFIG_CIFS_STATS2
+ mid_entry->when_received = jiffies;
+#endif
break;
}
}
@@ -598,7 +626,8 @@ multi_t2_fnd:
} else if ((is_valid_oplock_break(smb_buffer) == FALSE)
&& (isMultiRsp == FALSE)) {
cERROR(1, ("No task to wake, unknown frame rcvd!"));
- cifs_dump_mem("Received Data is: ",temp,sizeof(struct smb_hdr));
+ cifs_dump_mem("Received Data is: ",(char *)smb_buffer,
+ sizeof(struct smb_hdr));
}
} /* end while !EXITING */
@@ -676,7 +705,7 @@ multi_t2_fnd:
msleep(125);
}
- if (list_empty(&server->pending_mid_q)) {
+ if (!list_empty(&server->pending_mid_q)) {
/* mpx threads have not exited yet give them
at least the smb send timeout time for long ops */
/* due to delays on oplock break requests, we need
@@ -713,7 +742,7 @@ multi_t2_fnd:
GFP_KERNEL);
}
- msleep(250);
+ complete_and_exit(&cifsd_complete, 0);
return 0;
}
@@ -737,7 +766,9 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol)
toupper(system_utsname.nodename[i]);
}
vol->source_rfc1001_name[15] = 0;
-
+ /* null target name indicates to use *SMBSERVR default called name
+ if we end up sending RFC1001 session initialize */
+ vol->target_rfc1001_name[0] = 0;
vol->linux_uid = current->uid; /* current->euid instead? */
vol->linux_gid = current->gid;
vol->dir_mode = S_IRWXUGO;
@@ -747,6 +778,9 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol)
/* vol->retry default is 0 (i.e. "soft" limited retry not hard retry) */
vol->rw = TRUE;
+ /* default is always to request posix paths. */
+ vol->posix_paths = 1;
+
if (!options)
return 1;
@@ -987,7 +1021,31 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol)
/* The string has 16th byte zero still from
set at top of the function */
if((i==15) && (value[i] != 0))
- printk(KERN_WARNING "CIFS: netbiosname longer than 15 and was truncated.\n");
+ printk(KERN_WARNING "CIFS: netbiosname longer than 15 truncated.\n");
+ }
+ } else if (strnicmp(data, "servern", 7) == 0) {
+ /* servernetbiosname specified override *SMBSERVER */
+ if (!value || !*value || (*value == ' ')) {
+ cFYI(1,("empty server netbiosname specified"));
+ } else {
+ /* last byte, type, is 0x20 for servr type */
+ memset(vol->target_rfc1001_name,0x20,16);
+
+ for(i=0;i<15;i++) {
+ /* BB are there cases in which a comma can be
+ valid in this workstation netbios name (and need
+ special handling)? */
+
+ /* user or mount helper must uppercase netbiosname */
+ if (value[i]==0)
+ break;
+ else
+ vol->target_rfc1001_name[i] = value[i];
+ }
+ /* The string has 16th byte zero still from
+ set at top of the function */
+ if((i==15) && (value[i] != 0))
+ printk(KERN_WARNING "CIFS: server netbiosname longer than 15 truncated.\n");
}
} else if (strnicmp(data, "credentials", 4) == 0) {
/* ignore */
@@ -1025,6 +1083,27 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol)
vol->remap = 1;
} else if (strnicmp(data, "nomapchars", 10) == 0) {
vol->remap = 0;
+ } else if (strnicmp(data, "sfu", 3) == 0) {
+ vol->sfu_emul = 1;
+ } else if (strnicmp(data, "nosfu", 5) == 0) {
+ vol->sfu_emul = 0;
+ } else if (strnicmp(data, "posixpaths", 10) == 0) {
+ vol->posix_paths = 1;
+ } else if (strnicmp(data, "noposixpaths", 12) == 0) {
+ vol->posix_paths = 0;
+ } else if ((strnicmp(data, "nocase", 6) == 0) ||
+ (strnicmp(data, "ignorecase", 10) == 0)) {
+ vol->nocase = 1;
+ } else if (strnicmp(data, "brl", 3) == 0) {
+ vol->nobrl = 0;
+ } else if ((strnicmp(data, "nobrl", 5) == 0) ||
+ (strnicmp(data, "nolock", 6) == 0)) {
+ vol->nobrl = 1;
+ /* turn off mandatory locking in mode
+ if remote locking is turned off since the
+ local vfs will do advisory */
+ if(vol->file_mode == (S_IALLUGO & ~(S_ISUID | S_IXGRP)))
+ vol->file_mode = S_IALLUGO;
} else if (strnicmp(data, "setuids", 7) == 0) {
vol->setuids = 1;
} else if (strnicmp(data, "nosetuids", 9) == 0) {
@@ -1187,8 +1266,7 @@ connect_to_dfs_path(int xid, struct cifsSesInfo *pSesInfo,
the helper that resolves tcp names, mount to it, try to
tcon to it unmount it if fail */
- if(referrals)
- kfree(referrals);
+ kfree(referrals);
return rc;
}
@@ -1244,7 +1322,7 @@ static void rfc1002mangle(char * target,char * source, unsigned int length)
static int
ipv4_connect(struct sockaddr_in *psin_server, struct socket **csocket,
- char * netbios_name)
+ char * netbios_name, char * target_name)
{
int rc = 0;
int connected = 0;
@@ -1309,10 +1387,16 @@ ipv4_connect(struct sockaddr_in *psin_server, struct socket **csocket,
/* Eventually check for other socket options to change from
the default. sock_setsockopt not used because it expects
user space buffer */
+ cFYI(1,("sndbuf %d rcvbuf %d rcvtimeo 0x%lx",(*csocket)->sk->sk_sndbuf,
+ (*csocket)->sk->sk_rcvbuf, (*csocket)->sk->sk_rcvtimeo));
(*csocket)->sk->sk_rcvtimeo = 7 * HZ;
+ /* make the bufsizes depend on wsize/rsize and max requests */
+ if((*csocket)->sk->sk_sndbuf < (200 * 1024))
+ (*csocket)->sk->sk_sndbuf = 200 * 1024;
+ if((*csocket)->sk->sk_rcvbuf < (140 * 1024))
+ (*csocket)->sk->sk_rcvbuf = 140 * 1024;
/* send RFC1001 sessinit */
-
if(psin_server->sin_port == htons(RFC1001_PORT)) {
/* some servers require RFC1001 sessinit before sending
negprot - BB check reconnection in case where second
@@ -1322,8 +1406,14 @@ ipv4_connect(struct sockaddr_in *psin_server, struct socket **csocket,
ses_init_buf = kzalloc(sizeof(struct rfc1002_session_packet), GFP_KERNEL);
if(ses_init_buf) {
ses_init_buf->trailer.session_req.called_len = 32;
- rfc1002mangle(ses_init_buf->trailer.session_req.called_name,
- DEFAULT_CIFS_CALLED_NAME,16);
+ if(target_name && (target_name[0] != 0)) {
+ rfc1002mangle(ses_init_buf->trailer.session_req.called_name,
+ target_name, 16);
+ } else {
+ rfc1002mangle(ses_init_buf->trailer.session_req.called_name,
+ DEFAULT_CIFS_CALLED_NAME,16);
+ }
+
ses_init_buf->trailer.session_req.calling_len = 32;
/* calling name ends in null (byte 16) from old smb
convention. */
@@ -1445,10 +1535,8 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
memset(&volume_info,0,sizeof(struct smb_vol));
if (cifs_parse_mount_options(mount_data, devname, &volume_info)) {
- if(volume_info.UNC)
- kfree(volume_info.UNC);
- if(volume_info.password)
- kfree(volume_info.password);
+ kfree(volume_info.UNC);
+ kfree(volume_info.password);
FreeXid(xid);
return -EINVAL;
}
@@ -1461,10 +1549,8 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
cifserror("No username specified ");
/* In userspace mount helper we can get user name from alternate
locations such as env variables and files on disk */
- if(volume_info.UNC)
- kfree(volume_info.UNC);
- if(volume_info.password)
- kfree(volume_info.password);
+ kfree(volume_info.UNC);
+ kfree(volume_info.password);
FreeXid(xid);
return -EINVAL;
}
@@ -1483,10 +1569,8 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
if(rc <= 0) {
/* we failed translating address */
- if(volume_info.UNC)
- kfree(volume_info.UNC);
- if(volume_info.password)
- kfree(volume_info.password);
+ kfree(volume_info.UNC);
+ kfree(volume_info.password);
FreeXid(xid);
return -EINVAL;
}
@@ -1497,19 +1581,15 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
} else if (volume_info.UNCip){
/* BB using ip addr as server name connect to the DFS root below */
cERROR(1,("Connecting to DFS root not implemented yet"));
- if(volume_info.UNC)
- kfree(volume_info.UNC);
- if(volume_info.password)
- kfree(volume_info.password);
+ kfree(volume_info.UNC);
+ kfree(volume_info.password);
FreeXid(xid);
return -EINVAL;
} else /* which servers DFS root would we conect to */ {
cERROR(1,
("CIFS mount error: No UNC path (e.g. -o unc=//192.168.1.100/public) specified "));
- if(volume_info.UNC)
- kfree(volume_info.UNC);
- if(volume_info.password)
- kfree(volume_info.password);
+ kfree(volume_info.UNC);
+ kfree(volume_info.password);
FreeXid(xid);
return -EINVAL;
}
@@ -1522,10 +1602,8 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
cifs_sb->local_nls = load_nls(volume_info.iocharset);
if(cifs_sb->local_nls == NULL) {
cERROR(1,("CIFS mount error: iocharset %s not found",volume_info.iocharset));
- if(volume_info.UNC)
- kfree(volume_info.UNC);
- if(volume_info.password)
- kfree(volume_info.password);
+ kfree(volume_info.UNC);
+ kfree(volume_info.password);
FreeXid(xid);
return -ELIBACC;
}
@@ -1540,10 +1618,8 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
&sin_server6.sin6_addr,
volume_info.username, &srvTcp);
else {
- if(volume_info.UNC)
- kfree(volume_info.UNC);
- if(volume_info.password)
- kfree(volume_info.password);
+ kfree(volume_info.UNC);
+ kfree(volume_info.password);
FreeXid(xid);
return -EINVAL;
}
@@ -1556,16 +1632,16 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
sin_server.sin_port = htons(volume_info.port);
else
sin_server.sin_port = 0;
- rc = ipv4_connect(&sin_server,&csocket,volume_info.source_rfc1001_name);
+ rc = ipv4_connect(&sin_server,&csocket,
+ volume_info.source_rfc1001_name,
+ volume_info.target_rfc1001_name);
if (rc < 0) {
cERROR(1,
("Error connecting to IPv4 socket. Aborting operation"));
if(csocket != NULL)
sock_release(csocket);
- if(volume_info.UNC)
- kfree(volume_info.UNC);
- if(volume_info.password)
- kfree(volume_info.password);
+ kfree(volume_info.UNC);
+ kfree(volume_info.password);
FreeXid(xid);
return rc;
}
@@ -1574,10 +1650,8 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
if (srvTcp == NULL) {
rc = -ENOMEM;
sock_release(csocket);
- if(volume_info.UNC)
- kfree(volume_info.UNC);
- if(volume_info.password)
- kfree(volume_info.password);
+ kfree(volume_info.UNC);
+ kfree(volume_info.password);
FreeXid(xid);
return rc;
} else {
@@ -1600,15 +1674,15 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
if(rc < 0) {
rc = -ENOMEM;
sock_release(csocket);
- if(volume_info.UNC)
- kfree(volume_info.UNC);
- if(volume_info.password)
- kfree(volume_info.password);
+ kfree(volume_info.UNC);
+ kfree(volume_info.password);
FreeXid(xid);
return rc;
- } else
- rc = 0;
+ }
+ wait_for_completion(&cifsd_complete);
+ rc = 0;
memcpy(srvTcp->workstation_RFC1001_name, volume_info.source_rfc1001_name,16);
+ memcpy(srvTcp->server_RFC1001_name, volume_info.target_rfc1001_name,16);
srvTcp->sequence_number = 0;
}
}
@@ -1616,8 +1690,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
if (existingCifsSes) {
pSesInfo = existingCifsSes;
cFYI(1, ("Existing smb sess found "));
- if(volume_info.password)
- kfree(volume_info.password);
+ kfree(volume_info.password);
/* volume_info.UNC freed at end of function */
} else if (!rc) {
cFYI(1, ("Existing smb sess not found "));
@@ -1647,23 +1720,32 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
if(!rc)
atomic_inc(&srvTcp->socketUseCount);
} else
- if(volume_info.password)
- kfree(volume_info.password);
+ kfree(volume_info.password);
}
/* search for existing tcon to this server share */
if (!rc) {
- if((volume_info.rsize) && (volume_info.rsize <= CIFSMaxBufSize))
+ if(volume_info.rsize > CIFSMaxBufSize) {
+ cERROR(1,("rsize %d too large, using MaxBufSize",
+ volume_info.rsize));
+ cifs_sb->rsize = CIFSMaxBufSize;
+ } else if((volume_info.rsize) && (volume_info.rsize <= CIFSMaxBufSize))
cifs_sb->rsize = volume_info.rsize;
- else
- cifs_sb->rsize = srvTcp->maxBuf - MAX_CIFS_HDR_SIZE; /* default */
- if((volume_info.wsize) && (volume_info.wsize <= CIFSMaxBufSize))
+ else /* default */
+ cifs_sb->rsize = CIFSMaxBufSize;
+
+ if(volume_info.wsize > PAGEVEC_SIZE * PAGE_CACHE_SIZE) {
+ cERROR(1,("wsize %d too large using 4096 instead",
+ volume_info.wsize));
+ cifs_sb->wsize = 4096;
+ } else if(volume_info.wsize)
cifs_sb->wsize = volume_info.wsize;
else
cifs_sb->wsize = CIFSMaxBufSize; /* default */
if(cifs_sb->rsize < PAGE_CACHE_SIZE) {
- cifs_sb->rsize = PAGE_CACHE_SIZE;
- cERROR(1,("Attempt to set readsize for mount to less than one page (4096)"));
+ cifs_sb->rsize = PAGE_CACHE_SIZE;
+ /* Windows ME does this */
+ cFYI(1,("Attempt to set readsize for mount to less than one page (4096)"));
}
cifs_sb->mnt_uid = volume_info.linux_uid;
cifs_sb->mnt_gid = volume_info.linux_gid;
@@ -1681,8 +1763,13 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_MAP_SPECIAL_CHR;
if(volume_info.no_xattr)
cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_XATTR;
+ if(volume_info.sfu_emul)
+ cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_UNX_EMUL;
+ if(volume_info.nobrl)
+ cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_BRL;
+
if(volume_info.direct_io) {
- cERROR(1,("mounting share using direct i/o"));
+ cFYI(1,("mounting share using direct i/o"));
cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DIRECT_IO;
}
@@ -1696,6 +1783,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
to the same server share the last value passed in
for the retry flag is used */
tcon->retry = volume_info.retry;
+ tcon->nocase = volume_info.nocase;
} else {
tcon = tconInfoAlloc();
if (tcon == NULL)
@@ -1711,8 +1799,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
"", cifs_sb->local_nls,
cifs_sb->mnt_cifs_flags &
CIFS_MOUNT_MAP_SPECIAL_CHR);
- if(volume_info.UNC)
- kfree(volume_info.UNC);
+ kfree(volume_info.UNC);
FreeXid(xid);
return -ENODEV;
} else {
@@ -1724,6 +1811,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
if (!rc) {
atomic_inc(&pSesInfo->inUse);
tcon->retry = volume_info.retry;
+ tcon->nocase = volume_info.nocase;
}
}
}
@@ -1745,8 +1833,10 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
spin_lock(&GlobalMid_Lock);
srvTcp->tcpStatus = CifsExiting;
spin_unlock(&GlobalMid_Lock);
- if(srvTcp->tsk)
+ if(srvTcp->tsk) {
send_sig(SIGKILL,srvTcp->tsk,1);
+ wait_for_completion(&cifsd_complete);
+ }
}
/* If find_unc succeeded then rc == 0 so we can not end */
if (tcon) /* up accidently freeing someone elses tcon struct */
@@ -1759,8 +1849,10 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
temp_rc = CIFSSMBLogoff(xid, pSesInfo);
/* if the socketUseCount is now zero */
if((temp_rc == -ESHUTDOWN) &&
- (pSesInfo->server->tsk))
+ (pSesInfo->server->tsk)) {
send_sig(SIGKILL,pSesInfo->server->tsk,1);
+ wait_for_completion(&cifsd_complete);
+ }
} else
cFYI(1, ("No session or bad tcon"));
sesInfoFree(pSesInfo);
@@ -1783,16 +1875,34 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
cFYI(1,("server negotiated posix acl support"));
sb->s_flags |= MS_POSIXACL;
}
+
+ /* Try and negotiate POSIX pathnames if we can. */
+ if (volume_info.posix_paths && (CIFS_UNIX_POSIX_PATHNAMES_CAP &
+ le64_to_cpu(tcon->fsUnixInfo.Capability))) {
+ if (!CIFSSMBSetFSUnixInfo(xid, tcon, CIFS_UNIX_POSIX_PATHNAMES_CAP)) {
+ cFYI(1,("negotiated posix pathnames support"));
+ cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_POSIX_PATHS;
+ } else {
+ cFYI(1,("posix pathnames support requested but not supported"));
+ }
+ }
}
}
+ if (!(tcon->ses->capabilities & CAP_LARGE_WRITE_X))
+ cifs_sb->wsize = min(cifs_sb->wsize,
+ (tcon->ses->server->maxBuf -
+ MAX_CIFS_HDR_SIZE));
+ if (!(tcon->ses->capabilities & CAP_LARGE_READ_X))
+ cifs_sb->rsize = min(cifs_sb->rsize,
+ (tcon->ses->server->maxBuf -
+ MAX_CIFS_HDR_SIZE));
}
/* volume_info.password is freed above when existing session found
(in which case it is not needed anymore) but when new sesion is created
the password ptr is put in the new session structure (in which case the
password will be freed at unmount time) */
- if(volume_info.UNC)
- kfree(volume_info.UNC);
+ kfree(volume_info.UNC);
FreeXid(xid);
return rc;
}
@@ -1832,6 +1942,7 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses,
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);
@@ -2107,6 +2218,8 @@ CIFSSpnegoSessSetup(unsigned int xid, struct cifsSesInfo *ses,
/* 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.AndXCommand = 0xFF;
pSMB->req.MaxBufferSize = cpu_to_le16(ses->server->maxBuf);
@@ -2373,6 +2486,8 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
/* 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);
@@ -2715,6 +2830,8 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
/* 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;
@@ -3086,6 +3203,8 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
header_assemble(smb_buffer, SMB_COM_TREE_CONNECT_ANDX,
NULL /*no tid */ , 4 /*wct */ );
+
+ smb_buffer->Mid = GetNextMid(ses->server);
smb_buffer->Uid = ses->Suid;
pSMB = (TCONX_REQ *) smb_buffer;
pSMBr = (TCONX_RSP *) smb_buffer_response;
@@ -3140,8 +3259,7 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
if ((bcc_ptr + (2 * length)) -
pByteArea(smb_buffer_response) <=
BCC(smb_buffer_response)) {
- if(tcon->nativeFileSystem)
- kfree(tcon->nativeFileSystem);
+ kfree(tcon->nativeFileSystem);
tcon->nativeFileSystem =
kzalloc(length + 2, GFP_KERNEL);
cifs_strfromUCS_le(tcon->nativeFileSystem,
@@ -3158,8 +3276,7 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
if ((bcc_ptr + length) -
pByteArea(smb_buffer_response) <=
BCC(smb_buffer_response)) {
- if(tcon->nativeFileSystem)
- kfree(tcon->nativeFileSystem);
+ kfree(tcon->nativeFileSystem);
tcon->nativeFileSystem =
kzalloc(length + 1, GFP_KERNEL);
strncpy(tcon->nativeFileSystem, bcc_ptr,
@@ -3207,8 +3324,10 @@ cifs_umount(struct super_block *sb, struct cifs_sb_info *cifs_sb)
return 0;
} else if (rc == -ESHUTDOWN) {
cFYI(1,("Waking up socket by sending it signal"));
- if(cifsd_task)
+ if(cifsd_task) {
send_sig(SIGKILL,cifsd_task,1);
+ wait_for_completion(&cifsd_complete);
+ }
rc = 0;
} /* else - we have an smb session
left on this socket do not kill cifsd */
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
index d335269bd91c..8dfe717a332a 100644
--- a/fs/cifs/dir.c
+++ b/fs/cifs/dir.c
@@ -48,6 +48,7 @@ build_path_from_dentry(struct dentry *direntry)
struct dentry *temp;
int namelen = 0;
char *full_path;
+ char dirsep = CIFS_DIR_SEP(CIFS_SB(direntry->d_sb));
if(direntry == NULL)
return NULL; /* not much we can do if dentry is freed and
@@ -74,7 +75,7 @@ cifs_bp_rename_retry:
if (namelen < 0) {
break;
} else {
- full_path[namelen] = '\\';
+ full_path[namelen] = dirsep;
strncpy(full_path + namelen + 1, temp->d_name.name,
temp->d_name.len);
cFYI(0, (" name: %s ", full_path + namelen));
@@ -183,6 +184,13 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
desiredAccess, CREATE_NOT_DIR,
&fileHandle, &oplock, buf, cifs_sb->local_nls,
cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
+ if(rc == -EIO) {
+ /* old server, retry the open legacy style */
+ rc = SMBLegacyOpen(xid, pTcon, full_path, disposition,
+ desiredAccess, CREATE_NOT_DIR,
+ &fileHandle, &oplock, buf, cifs_sb->local_nls,
+ cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
+ }
if (rc) {
cFYI(1, ("cifs_create returned 0x%x ", rc));
} else {
@@ -208,7 +216,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
CIFS_MOUNT_MAP_SPECIAL_CHR);
}
else {
- /* BB implement via Windows security descriptors */
+ /* BB implement mode setting via Windows security descriptors */
/* eg CIFSSMBWinSetPerms(xid,pTcon,full_path,mode,-1,-1,local_nls);*/
/* could set r/o dos attribute if mode & 0222 == 0 */
}
@@ -225,10 +233,14 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
}
if (rc != 0) {
- cFYI(1,("Create worked but get_inode_info failed with rc = %d",
+ cFYI(1,
+ ("Create worked but get_inode_info failed rc = %d",
rc));
} else {
- direntry->d_op = &cifs_dentry_ops;
+ if (pTcon->nocase)
+ direntry->d_op = &cifs_ci_dentry_ops;
+ else
+ direntry->d_op = &cifs_dentry_ops;
d_instantiate(direntry, newinode);
}
if((nd->flags & LOOKUP_OPEN) == FALSE) {
@@ -302,8 +314,7 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode, dev_t dev
up(&direntry->d_sb->s_vfs_rename_sem);
if(full_path == NULL)
rc = -ENOMEM;
-
- if (full_path && (pTcon->ses->capabilities & CAP_UNIX)) {
+ else if (pTcon->ses->capabilities & CAP_UNIX) {
if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
rc = CIFSSMBUnixSetPerms(xid, pTcon, full_path,
mode,(__u64)current->euid,(__u64)current->egid,
@@ -321,10 +332,49 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode, dev_t dev
if(!rc) {
rc = cifs_get_inode_info_unix(&newinode, full_path,
inode->i_sb,xid);
- direntry->d_op = &cifs_dentry_ops;
+ if (pTcon->nocase)
+ direntry->d_op = &cifs_ci_dentry_ops;
+ else
+ direntry->d_op = &cifs_dentry_ops;
if(rc == 0)
d_instantiate(direntry, newinode);
}
+ } else {
+ if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) {
+ int oplock = 0;
+ u16 fileHandle;
+ FILE_ALL_INFO * buf;
+
+ cFYI(1,("sfu compat create special file"));
+
+ buf = kmalloc(sizeof(FILE_ALL_INFO),GFP_KERNEL);
+ if(buf == NULL) {
+ kfree(full_path);
+ FreeXid(xid);
+ return -ENOMEM;
+ }
+
+ rc = CIFSSMBOpen(xid, pTcon, full_path,
+ FILE_CREATE, /* fail if exists */
+ GENERIC_WRITE /* BB would
+ WRITE_OWNER | WRITE_DAC be better? */,
+ /* Create a file and set the
+ file attribute to SYSTEM */
+ CREATE_NOT_DIR | CREATE_OPTION_SPECIAL,
+ &fileHandle, &oplock, buf,
+ cifs_sb->local_nls,
+ cifs_sb->mnt_cifs_flags &
+ CIFS_MOUNT_MAP_SPECIAL_CHR);
+
+ if(!rc) {
+ /* BB Do not bother to decode buf since no
+ local inode yet to put timestamps in */
+ CIFSSMBClose(xid, pTcon, fileHandle);
+ d_drop(direntry);
+ }
+ kfree(buf);
+ /* add code here to set EAs */
+ }
}
kfree(full_path);
@@ -381,7 +431,10 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, struct name
parent_dir_inode->i_sb,xid);
if ((rc == 0) && (newInode != NULL)) {
- direntry->d_op = &cifs_dentry_ops;
+ if (pTcon->nocase)
+ direntry->d_op = &cifs_ci_dentry_ops;
+ else
+ direntry->d_op = &cifs_dentry_ops;
d_add(direntry, newInode);
/* since paths are not looked up by component - the parent directories are presumed to be good here */
@@ -440,3 +493,42 @@ struct dentry_operations cifs_dentry_ops = {
/* d_delete: cifs_d_delete, *//* not needed except for debugging */
/* no need for d_hash, d_compare, d_release, d_iput ... yet. BB confirm this BB */
};
+
+static int cifs_ci_hash(struct dentry *dentry, struct qstr *q)
+{
+ struct nls_table *codepage = CIFS_SB(dentry->d_inode->i_sb)->local_nls;
+ unsigned long hash;
+ int i;
+
+ hash = init_name_hash();
+ for (i = 0; i < q->len; i++)
+ hash = partial_name_hash(nls_tolower(codepage, q->name[i]),
+ hash);
+ q->hash = end_name_hash(hash);
+
+ return 0;
+}
+
+static int cifs_ci_compare(struct dentry *dentry, struct qstr *a,
+ struct qstr *b)
+{
+ struct nls_table *codepage = CIFS_SB(dentry->d_inode->i_sb)->local_nls;
+
+ if ((a->len == b->len) &&
+ (nls_strnicmp(codepage, a->name, b->name, a->len) == 0)) {
+ /*
+ * To preserve case, don't let an existing negative dentry's
+ * case take precedence. If a is not a negative dentry, this
+ * should have no side effects
+ */
+ memcpy((unsigned char *)a->name, b->name, a->len);
+ return 0;
+ }
+ return 1;
+}
+
+struct dentry_operations cifs_ci_dentry_ops = {
+ .d_revalidate = cifs_d_revalidate,
+ .d_hash = cifs_ci_hash,
+ .d_compare = cifs_ci_compare,
+};
diff --git a/fs/cifs/fcntl.c b/fs/cifs/fcntl.c
index 7d2a9202c39a..a7a47bb36bf3 100644
--- a/fs/cifs/fcntl.c
+++ b/fs/cifs/fcntl.c
@@ -78,6 +78,10 @@ int cifs_dir_notify(struct file * file, unsigned long arg)
__u32 filter = FILE_NOTIFY_CHANGE_NAME | FILE_NOTIFY_CHANGE_ATTRIBUTES;
__u16 netfid;
+
+ if(experimEnabled == 0)
+ return 0;
+
xid = GetXid();
cifs_sb = CIFS_SB(file->f_dentry->d_sb);
pTcon = cifs_sb->tcon;
@@ -100,8 +104,10 @@ int cifs_dir_notify(struct file * file, unsigned long arg)
} else {
filter = convert_to_cifs_notify_flags(arg);
if(filter != 0) {
- rc = CIFSSMBNotify(xid, pTcon, 0 /* no subdirs */, netfid,
- filter, cifs_sb->local_nls);
+ rc = CIFSSMBNotify(xid, pTcon,
+ 0 /* no subdirs */, netfid,
+ filter, file, arg & DN_MULTISHOT,
+ cifs_sb->local_nls);
} else {
rc = -EINVAL;
}
@@ -109,7 +115,7 @@ int cifs_dir_notify(struct file * file, unsigned long arg)
it would close automatically but may be a way
to do it easily when inode freed or when
notify info is cleared/changed */
- cERROR(1,("notify rc %d",rc));
+ cFYI(1,("notify rc %d",rc));
}
}
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index 3497125189df..da4f5e10b3cc 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -21,11 +21,15 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <linux/fs.h>
+#include <linux/backing-dev.h>
#include <linux/stat.h>
#include <linux/fcntl.h>
+#include <linux/mpage.h>
#include <linux/pagemap.h>
#include <linux/pagevec.h>
#include <linux/smp_lock.h>
+#include <linux/writeback.h>
+#include <linux/delay.h>
#include <asm/div64.h>
#include "cifsfs.h"
#include "cifspdu.h"
@@ -47,6 +51,11 @@ static inline struct cifsFileInfo *cifs_init_private(
private_data->pInode = inode;
private_data->invalidHandle = FALSE;
private_data->closePend = FALSE;
+ /* we have to track num writers to the inode, since writepages
+ does not tell us which handle the write is for so there can
+ be a close (overlapping with write) of the filehandle that
+ cifs_writepages chose to use */
+ atomic_set(&private_data->wrtPending,0);
return private_data;
}
@@ -256,6 +265,13 @@ int cifs_open(struct inode *inode, struct file *file)
CREATE_NOT_DIR, &netfid, &oplock, buf,
cifs_sb->local_nls, cifs_sb->mnt_cifs_flags
& CIFS_MOUNT_MAP_SPECIAL_CHR);
+ if (rc == -EIO) {
+ /* Old server, try legacy style OpenX */
+ rc = SMBLegacyOpen(xid, pTcon, full_path, disposition,
+ desiredAccess, CREATE_NOT_DIR, &netfid, &oplock, buf,
+ cifs_sb->local_nls, cifs_sb->mnt_cifs_flags
+ & CIFS_MOUNT_MAP_SPECIAL_CHR);
+ }
if (rc) {
cFYI(1, ("cifs_open returned 0x%x ", rc));
goto out;
@@ -463,6 +479,20 @@ int cifs_close(struct inode *inode, struct file *file)
/* no sense reconnecting to close a file that is
already closed */
if (pTcon->tidStatus != CifsNeedReconnect) {
+ int timeout = 2;
+ while((atomic_read(&pSMBFile->wrtPending) != 0)
+ && (timeout < 1000) ) {
+ /* Give write a better chance to get to
+ server ahead of the close. We do not
+ want to add a wait_q here as it would
+ increase the memory utilization as
+ the struct would be in each open file,
+ but this should give enough time to
+ clear the socket */
+ cERROR(1,("close with pending writes"));
+ msleep(timeout);
+ timeout *= 4;
+ }
write_unlock(&file->f_owner.lock);
rc = CIFSSMBClose(xid, pTcon,
pSMBFile->netfid);
@@ -744,14 +774,7 @@ ssize_t cifs_user_write(struct file *file, const char __user *write_data,
15 seconds is plenty */
}
-#ifdef CONFIG_CIFS_STATS
- if (total_written > 0) {
- atomic_inc(&pTcon->num_writes);
- spin_lock(&pTcon->stat_lock);
- pTcon->bytes_written += total_written;
- spin_unlock(&pTcon->stat_lock);
- }
-#endif
+ cifs_stats_bytes_written(pTcon, total_written);
/* since the write may have blocked check these pointers again */
if (file->f_dentry) {
@@ -791,9 +814,8 @@ static ssize_t cifs_write(struct file *file, const char *write_data,
pTcon = cifs_sb->tcon;
- /* cFYI(1,
- (" write %d bytes to offset %lld of %s", write_size,
- *poffset, file->f_dentry->d_name.name)); */
+ cFYI(1,("write %zd bytes to offset %lld of %s", write_size,
+ *poffset, file->f_dentry->d_name.name));
if (file->private_data == NULL)
return -EBADF;
@@ -846,7 +868,26 @@ static ssize_t cifs_write(struct file *file, const char *write_data,
if (rc != 0)
break;
}
-
+#ifdef CONFIG_CIFS_EXPERIMENTAL
+ /* BB FIXME We can not sign across two buffers yet */
+ if((experimEnabled) && ((pTcon->ses->server->secMode &
+ (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) == 0)) {
+ struct kvec iov[2];
+ unsigned int len;
+
+ len = min((size_t)cifs_sb->wsize,
+ write_size - total_written);
+ /* iov[0] is reserved for smb header */
+ iov[1].iov_base = (char *)write_data +
+ total_written;
+ iov[1].iov_len = len;
+ rc = CIFSSMBWrite2(xid, pTcon,
+ open_file->netfid, len,
+ *poffset, &bytes_written,
+ iov, 1, long_op);
+ } else
+ /* BB FIXME fixup indentation of line below */
+#endif
rc = CIFSSMBWrite(xid, pTcon,
open_file->netfid,
min_t(const int, cifs_sb->wsize,
@@ -867,14 +908,7 @@ static ssize_t cifs_write(struct file *file, const char *write_data,
15 seconds is plenty */
}
-#ifdef CONFIG_CIFS_STATS
- if (total_written > 0) {
- atomic_inc(&pTcon->num_writes);
- spin_lock(&pTcon->stat_lock);
- pTcon->bytes_written += total_written;
- spin_unlock(&pTcon->stat_lock);
- }
-#endif
+ cifs_stats_bytes_written(pTcon, total_written);
/* since the write may have blocked check these pointers again */
if (file->f_dentry) {
@@ -893,6 +927,43 @@ static ssize_t cifs_write(struct file *file, const char *write_data,
return total_written;
}
+struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode)
+{
+ struct cifsFileInfo *open_file;
+ int rc;
+
+ read_lock(&GlobalSMBSeslock);
+ list_for_each_entry(open_file, &cifs_inode->openFileList, flist) {
+ if (open_file->closePend)
+ continue;
+ if (open_file->pfile &&
+ ((open_file->pfile->f_flags & O_RDWR) ||
+ (open_file->pfile->f_flags & O_WRONLY))) {
+ atomic_inc(&open_file->wrtPending);
+ read_unlock(&GlobalSMBSeslock);
+ if((open_file->invalidHandle) &&
+ (!open_file->closePend) /* BB fixme -since the second clause can not be true remove it BB */) {
+ rc = cifs_reopen_file(&cifs_inode->vfs_inode,
+ open_file->pfile, FALSE);
+ /* if it fails, try another handle - might be */
+ /* dangerous to hold up writepages with retry */
+ if(rc) {
+ cFYI(1,("failed on reopen file in wp"));
+ read_lock(&GlobalSMBSeslock);
+ /* can not use this handle, no write
+ pending on this one after all */
+ atomic_dec
+ (&open_file->wrtPending);
+ continue;
+ }
+ }
+ return open_file;
+ }
+ }
+ read_unlock(&GlobalSMBSeslock);
+ return NULL;
+}
+
static int cifs_partialpagewrite(struct page *page, unsigned from, unsigned to)
{
struct address_space *mapping = page->mapping;
@@ -903,10 +974,7 @@ static int cifs_partialpagewrite(struct page *page, unsigned from, unsigned to)
struct cifs_sb_info *cifs_sb;
struct cifsTconInfo *pTcon;
struct inode *inode;
- struct cifsInodeInfo *cifsInode;
- struct cifsFileInfo *open_file = NULL;
- struct list_head *tmp;
- struct list_head *tmp1;
+ struct cifsFileInfo *open_file;
if (!mapping || !mapping->host)
return -EFAULT;
@@ -934,49 +1002,20 @@ static int cifs_partialpagewrite(struct page *page, unsigned from, unsigned to)
if (mapping->host->i_size - offset < (loff_t)to)
to = (unsigned)(mapping->host->i_size - offset);
- cifsInode = CIFS_I(mapping->host);
- read_lock(&GlobalSMBSeslock);
- /* BB we should start at the end */
- list_for_each_safe(tmp, tmp1, &cifsInode->openFileList) {
- open_file = list_entry(tmp, struct cifsFileInfo, flist);
- if (open_file->closePend)
- continue;
- /* We check if file is open for writing first */
- if ((open_file->pfile) &&
- ((open_file->pfile->f_flags & O_RDWR) ||
- (open_file->pfile->f_flags & O_WRONLY))) {
- read_unlock(&GlobalSMBSeslock);
- bytes_written = cifs_write(open_file->pfile,
- write_data, to-from,
- &offset);
- read_lock(&GlobalSMBSeslock);
+ open_file = find_writable_file(CIFS_I(mapping->host));
+ if (open_file) {
+ bytes_written = cifs_write(open_file->pfile, write_data,
+ to-from, &offset);
+ atomic_dec(&open_file->wrtPending);
/* Does mm or vfs already set times? */
- inode->i_atime =
- inode->i_mtime = current_fs_time(inode->i_sb);
- if ((bytes_written > 0) && (offset)) {
- rc = 0;
- } else if (bytes_written < 0) {
- if (rc == -EBADF) {
- /* have seen a case in which kernel seemed to
- have closed/freed a file even with writes
- active so we might as well see if there are
- other file structs to try for the same
- inode before giving up */
- continue;
- } else
- rc = bytes_written;
- }
- break; /* now that we found a valid file handle and
- tried to write to it we are done, no sense
- continuing to loop looking for another */
- }
- if (tmp->next == NULL) {
- cFYI(1, ("File instance %p removed", tmp));
- break;
+ inode->i_atime = inode->i_mtime = current_fs_time(inode->i_sb);
+ if ((bytes_written > 0) && (offset)) {
+ rc = 0;
+ } else if (bytes_written < 0) {
+ if (rc != -EBADF)
+ rc = bytes_written;
}
- }
- read_unlock(&GlobalSMBSeslock);
- if (open_file == NULL) {
+ } else {
cFYI(1, ("No writeable filehandles for inode"));
rc = -EIO;
}
@@ -985,20 +1024,207 @@ static int cifs_partialpagewrite(struct page *page, unsigned from, unsigned to)
return rc;
}
-#if 0
+#ifdef CONFIG_CIFS_EXPERIMENTAL
static int cifs_writepages(struct address_space *mapping,
- struct writeback_control *wbc)
+ struct writeback_control *wbc)
{
- int rc = -EFAULT;
+ struct backing_dev_info *bdi = mapping->backing_dev_info;
+ unsigned int bytes_to_write;
+ unsigned int bytes_written;
+ struct cifs_sb_info *cifs_sb;
+ int done = 0;
+ pgoff_t end = -1;
+ pgoff_t index;
+ int is_range = 0;
+ struct kvec iov[32];
+ int len;
+ int n_iov = 0;
+ pgoff_t next;
+ int nr_pages;
+ __u64 offset = 0;
+ struct cifsFileInfo *open_file;
+ struct page *page;
+ struct pagevec pvec;
+ int rc = 0;
+ int scanned = 0;
int xid;
+ cifs_sb = CIFS_SB(mapping->host->i_sb);
+
+ /*
+ * If wsize is smaller that the page cache size, default to writing
+ * one page at a time via cifs_writepage
+ */
+ if (cifs_sb->wsize < PAGE_CACHE_SIZE)
+ return generic_writepages(mapping, wbc);
+
+ /* BB FIXME we do not have code to sign across multiple buffers yet,
+ so go to older writepage style write which we can sign if needed */
+ if((cifs_sb->tcon->ses) && (cifs_sb->tcon->ses->server))
+ if(cifs_sb->tcon->ses->server->secMode &
+ (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
+ return generic_writepages(mapping, wbc);
+
+ /*
+ * BB: Is this meaningful for a non-block-device file system?
+ * If it is, we should test it again after we do I/O
+ */
+ if (wbc->nonblocking && bdi_write_congested(bdi)) {
+ wbc->encountered_congestion = 1;
+ return 0;
+ }
+
xid = GetXid();
- /* Find contiguous pages then iterate through repeating
- call 16K write then Setpageuptodate or if LARGE_WRITE_X
- support then send larger writes via kevec so as to eliminate
- a memcpy */
+ pagevec_init(&pvec, 0);
+ if (wbc->sync_mode == WB_SYNC_NONE)
+ index = mapping->writeback_index; /* Start from prev offset */
+ else {
+ index = 0;
+ scanned = 1;
+ }
+ if (wbc->start || wbc->end) {
+ index = wbc->start >> PAGE_CACHE_SHIFT;
+ end = wbc->end >> PAGE_CACHE_SHIFT;
+ is_range = 1;
+ scanned = 1;
+ }
+retry:
+ while (!done && (index <= end) &&
+ (nr_pages = pagevec_lookup_tag(&pvec, mapping, &index,
+ PAGECACHE_TAG_DIRTY,
+ min(end - index, (pgoff_t)PAGEVEC_SIZE - 1) + 1))) {
+ int first;
+ unsigned int i;
+
+ first = -1;
+ next = 0;
+ n_iov = 0;
+ bytes_to_write = 0;
+
+ for (i = 0; i < nr_pages; i++) {
+ page = pvec.pages[i];
+ /*
+ * At this point we hold neither mapping->tree_lock nor
+ * lock on the page itself: the page may be truncated or
+ * invalidated (changing page->mapping to NULL), or even
+ * swizzled back from swapper_space to tmpfs file
+ * mapping
+ */
+
+ if (first < 0)
+ lock_page(page);
+ else if (TestSetPageLocked(page))
+ break;
+
+ if (unlikely(page->mapping != mapping)) {
+ unlock_page(page);
+ break;
+ }
+
+ if (unlikely(is_range) && (page->index > end)) {
+ done = 1;
+ unlock_page(page);
+ break;
+ }
+
+ if (next && (page->index != next)) {
+ /* Not next consecutive page */
+ unlock_page(page);
+ break;
+ }
+
+ if (wbc->sync_mode != WB_SYNC_NONE)
+ wait_on_page_writeback(page);
+
+ if (PageWriteback(page) ||
+ !test_clear_page_dirty(page)) {
+ unlock_page(page);
+ break;
+ }
+
+ if (page_offset(page) >= mapping->host->i_size) {
+ done = 1;
+ unlock_page(page);
+ break;
+ }
+
+ /*
+ * BB can we get rid of this? pages are held by pvec
+ */
+ page_cache_get(page);
+
+ len = min(mapping->host->i_size - page_offset(page),
+ (loff_t)PAGE_CACHE_SIZE);
+
+ /* reserve iov[0] for the smb header */
+ n_iov++;
+ iov[n_iov].iov_base = kmap(page);
+ iov[n_iov].iov_len = len;
+ bytes_to_write += len;
+
+ if (first < 0) {
+ first = i;
+ offset = page_offset(page);
+ }
+ next = page->index + 1;
+ if (bytes_to_write + PAGE_CACHE_SIZE > cifs_sb->wsize)
+ break;
+ }
+ if (n_iov) {
+ /* Search for a writable handle every time we call
+ * CIFSSMBWrite2. We can't rely on the last handle
+ * we used to still be valid
+ */
+ open_file = find_writable_file(CIFS_I(mapping->host));
+ if (!open_file) {
+ cERROR(1, ("No writable handles for inode"));
+ rc = -EBADF;
+ } else {
+ rc = CIFSSMBWrite2(xid, cifs_sb->tcon,
+ open_file->netfid,
+ bytes_to_write, offset,
+ &bytes_written, iov, n_iov,
+ 1);
+ atomic_dec(&open_file->wrtPending);
+ if (rc || bytes_written < bytes_to_write) {
+ cERROR(1,("Write2 ret %d, written = %d",
+ rc, bytes_written));
+ /* BB what if continued retry is
+ requested via mount flags? */
+ set_bit(AS_EIO, &mapping->flags);
+ SetPageError(page);
+ } else {
+ cifs_stats_bytes_written(cifs_sb->tcon,
+ bytes_written);
+ }
+ }
+ for (i = 0; i < n_iov; i++) {
+ page = pvec.pages[first + i];
+ kunmap(page);
+ unlock_page(page);
+ page_cache_release(page);
+ }
+ if ((wbc->nr_to_write -= n_iov) <= 0)
+ done = 1;
+ index = next;
+ }
+ pagevec_release(&pvec);
+ }
+ if (!scanned && !done) {
+ /*
+ * We hit the last page and there is more work to be done: wrap
+ * back to the start of the file
+ */
+ scanned = 1;
+ index = 0;
+ goto retry;
+ }
+ if (!is_range)
+ mapping->writeback_index = index;
+
FreeXid(xid);
+
return rc;
}
#endif
@@ -1207,12 +1433,10 @@ ssize_t cifs_user_read(struct file *file, char __user *read_data,
if (rc != 0)
break;
}
-
rc = CIFSSMBRead(xid, pTcon,
- open_file->netfid,
- current_read_size, *poffset,
- &bytes_read, &smb_read_data);
-
+ open_file->netfid,
+ current_read_size, *poffset,
+ &bytes_read, &smb_read_data);
pSMBr = (struct smb_com_read_rsp *)smb_read_data;
if (copy_to_user(current_offset,
smb_read_data + 4 /* RFC1001 hdr */
@@ -1235,12 +1459,7 @@ ssize_t cifs_user_read(struct file *file, char __user *read_data,
return rc;
}
} else {
-#ifdef CONFIG_CIFS_STATS
- atomic_inc(&pTcon->num_reads);
- spin_lock(&pTcon->stat_lock);
- pTcon->bytes_read += total_read;
- spin_unlock(&pTcon->stat_lock);
-#endif
+ cifs_stats_bytes_read(pTcon, bytes_read);
*poffset += bytes_read;
}
}
@@ -1280,6 +1499,13 @@ static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size,
total_read += bytes_read, current_offset += bytes_read) {
current_read_size = min_t(const int, read_size - total_read,
cifs_sb->rsize);
+ /* For windows me and 9x we do not want to request more
+ than it negotiated since it will refuse the read then */
+ if((pTcon->ses) &&
+ !(pTcon->ses->capabilities & CAP_LARGE_FILES)) {
+ current_read_size = min_t(const int, current_read_size,
+ pTcon->ses->server->maxBuf - 128);
+ }
rc = -EAGAIN;
while (rc == -EAGAIN) {
if ((open_file->invalidHandle) &&
@@ -1289,11 +1515,10 @@ static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size,
if (rc != 0)
break;
}
-
rc = CIFSSMBRead(xid, pTcon,
- open_file->netfid,
- current_read_size, *poffset,
- &bytes_read, &current_offset);
+ open_file->netfid,
+ current_read_size, *poffset,
+ &bytes_read, &current_offset);
}
if (rc || (bytes_read == 0)) {
if (total_read) {
@@ -1303,12 +1528,7 @@ static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size,
return rc;
}
} else {
-#ifdef CONFIG_CIFS_STATS
- atomic_inc(&pTcon->num_reads);
- spin_lock(&pTcon->stat_lock);
- pTcon->bytes_read += total_read;
- spin_unlock(&pTcon->stat_lock);
-#endif
+ cifs_stats_bytes_read(pTcon, total_read);
*poffset += bytes_read;
}
}
@@ -1452,10 +1672,11 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
}
rc = CIFSSMBRead(xid, pTcon,
- open_file->netfid,
- read_size, offset,
- &bytes_read, &smb_read_data);
- /* BB need to check return code here */
+ open_file->netfid,
+ read_size, offset,
+ &bytes_read, &smb_read_data);
+
+ /* BB more RC checks ? */
if (rc== -EAGAIN) {
if (smb_read_data) {
cifs_buf_release(smb_read_data);
@@ -1480,12 +1701,7 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
le16_to_cpu(pSMBr->DataOffset), &lru_pvec);
i += bytes_read >> PAGE_CACHE_SHIFT;
-#ifdef CONFIG_CIFS_STATS
- atomic_inc(&pTcon->num_reads);
- spin_lock(&pTcon->stat_lock);
- pTcon->bytes_read += bytes_read;
- spin_unlock(&pTcon->stat_lock);
-#endif
+ cifs_stats_bytes_read(pTcon, bytes_read);
if ((int)(bytes_read & PAGE_CACHE_MASK) != bytes_read) {
i++; /* account for partial page */
@@ -1603,40 +1819,21 @@ static int cifs_readpage(struct file *file, struct page *page)
page caching in the current Linux kernel design */
int is_size_safe_to_change(struct cifsInodeInfo *cifsInode)
{
- struct list_head *tmp;
- struct list_head *tmp1;
struct cifsFileInfo *open_file = NULL;
- int rc = TRUE;
- if (cifsInode == NULL)
- return rc;
-
- read_lock(&GlobalSMBSeslock);
- list_for_each_safe(tmp, tmp1, &cifsInode->openFileList) {
- open_file = list_entry(tmp, struct cifsFileInfo, flist);
- if (open_file == NULL)
- break;
- if (open_file->closePend)
- continue;
- /* We check if file is open for writing,
- BB we could supplement this with a check to see if file size
- changes have been flushed to server - ie inode metadata dirty */
- if ((open_file->pfile) &&
- ((open_file->pfile->f_flags & O_RDWR) ||
- (open_file->pfile->f_flags & O_WRONLY))) {
- rc = FALSE;
- break;
- }
- if (tmp->next == NULL) {
- cFYI(1, ("File instance %p removed", tmp));
- break;
- }
- }
- read_unlock(&GlobalSMBSeslock);
- return rc;
+ if (cifsInode)
+ open_file = find_writable_file(cifsInode);
+
+ if(open_file) {
+ /* there is not actually a write pending so let
+ this handle go free and allow it to
+ be closable if needed */
+ atomic_dec(&open_file->wrtPending);
+ return 0;
+ } else
+ return 1;
}
-
static int cifs_prepare_write(struct file *file, struct page *page,
unsigned from, unsigned to)
{
@@ -1676,6 +1873,9 @@ struct address_space_operations cifs_addr_ops = {
.readpage = cifs_readpage,
.readpages = cifs_readpages,
.writepage = cifs_writepage,
+#ifdef CONFIG_CIFS_EXPERIMENTAL
+ .writepages = cifs_writepages,
+#endif
.prepare_write = cifs_prepare_write,
.commit_write = cifs_commit_write,
.set_page_dirty = __set_page_dirty_nobuffers,
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index 8d336a900255..923d071163b2 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -166,7 +166,13 @@ int cifs_get_inode_info_unix(struct inode **pinode,
inode->i_fop = &cifs_file_direct_ops;
else
inode->i_fop = &cifs_file_ops;
+ if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
+ inode->i_fop->lock = NULL;
inode->i_data.a_ops = &cifs_addr_ops;
+ /* check if server can support readpages */
+ if(pTcon->ses->server->maxBuf <
+ 4096 + MAX_CIFS_HDR_SIZE)
+ inode->i_data.a_ops->readpages = NULL;
} else if (S_ISDIR(inode->i_mode)) {
cFYI(1, (" Directory inode"));
inode->i_op = &cifs_dir_inode_ops;
@@ -213,8 +219,18 @@ int cifs_get_inode_info(struct inode **pinode,
pfindData = (FILE_ALL_INFO *)buf;
/* could do find first instead but this returns more info */
rc = CIFSSMBQPathInfo(xid, pTcon, search_path, pfindData,
- cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
+ cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
CIFS_MOUNT_MAP_SPECIAL_CHR);
+ /* BB optimize code so we do not make the above call
+ when server claims no NT SMB support and the above call
+ failed at least once - set flag in tcon or mount */
+ if((rc == -EOPNOTSUPP) || (rc == -EINVAL)) {
+ rc = SMBQueryInformation(xid, pTcon, search_path,
+ pfindData, cifs_sb->local_nls,
+ cifs_sb->mnt_cifs_flags &
+ CIFS_MOUNT_MAP_SPECIAL_CHR);
+ }
+
}
/* dump_mem("\nQPathInfo return data",&findData, sizeof(findData)); */
if (rc) {
@@ -267,7 +283,6 @@ int cifs_get_inode_info(struct inode **pinode,
there Windows server or network appliances for which
IndexNumber field is not guaranteed unique? */
-#ifdef CONFIG_CIFS_EXPERIMENTAL
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM){
int rc1 = 0;
__u64 inode_num;
@@ -283,7 +298,6 @@ int cifs_get_inode_info(struct inode **pinode,
} else /* do we need cast or hash to ino? */
(*pinode)->i_ino = inode_num;
} /* else ino incremented to unique num in new_inode*/
-#endif /* CIFS_EXPERIMENTAL */
insert_inode_hash(*pinode);
}
inode = *pinode;
@@ -320,6 +334,16 @@ int cifs_get_inode_info(struct inode **pinode,
on dirs */
inode->i_mode = cifs_sb->mnt_dir_mode;
inode->i_mode |= S_IFDIR;
+ } else if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) &&
+ (cifsInfo->cifsAttrs & ATTR_SYSTEM) &&
+ /* No need to le64 convert size of zero */
+ (pfindData->EndOfFile == 0)) {
+ inode->i_mode = cifs_sb->mnt_file_mode;
+ inode->i_mode |= S_IFIFO;
+/* BB Finish for SFU style symlinks and devies */
+/* } else if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) &&
+ (cifsInfo->cifsAttrs & ATTR_SYSTEM) && ) */
+
} else {
inode->i_mode |= S_IFREG;
/* treat the dos attribute of read-only as read-only
@@ -359,7 +383,12 @@ int cifs_get_inode_info(struct inode **pinode,
inode->i_fop = &cifs_file_direct_ops;
else
inode->i_fop = &cifs_file_ops;
+ if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
+ inode->i_fop->lock = NULL;
inode->i_data.a_ops = &cifs_addr_ops;
+ if(pTcon->ses->server->maxBuf <
+ 4096 + MAX_CIFS_HDR_SIZE)
+ inode->i_data.a_ops->readpages = NULL;
} else if (S_ISDIR(inode->i_mode)) {
cFYI(1, (" Directory inode "));
inode->i_op = &cifs_dir_inode_ops;
@@ -577,7 +606,10 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode)
rc = cifs_get_inode_info(&newinode, full_path, NULL,
inode->i_sb,xid);
- direntry->d_op = &cifs_dentry_ops;
+ if (pTcon->nocase)
+ direntry->d_op = &cifs_ci_dentry_ops;
+ else
+ direntry->d_op = &cifs_dentry_ops;
d_instantiate(direntry, newinode);
if (direntry->d_inode)
direntry->d_inode->i_nlink = 2;
@@ -928,7 +960,6 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
struct cifsTconInfo *pTcon;
char *full_path = NULL;
int rc = -EACCES;
- int found = FALSE;
struct cifsFileInfo *open_file = NULL;
FILE_BASIC_INFO time_buf;
int set_time = FALSE;
@@ -936,7 +967,6 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
__u64 uid = 0xFFFFFFFFFFFFFFFFULL;
__u64 gid = 0xFFFFFFFFFFFFFFFFULL;
struct cifsInodeInfo *cifsInode;
- struct list_head *tmp;
xid = GetXid();
@@ -961,7 +991,6 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
filemap_fdatawait(direntry->d_inode->i_mapping);
if (attrs->ia_valid & ATTR_SIZE) {
- read_lock(&GlobalSMBSeslock);
/* To avoid spurious oplock breaks from server, in the case of
inodes that we already have open, avoid doing path based
setting of file size if we can do it by handle.
@@ -969,40 +998,23 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
when the local oplock break takes longer to flush
writebehind data than the SMB timeout for the SetPathInfo
request would allow */
- list_for_each(tmp, &cifsInode->openFileList) {
- open_file = list_entry(tmp, struct cifsFileInfo,
- flist);
- /* We check if file is open for writing first */
- if ((open_file->pfile) &&
- ((open_file->pfile->f_flags & O_RDWR) ||
- (open_file->pfile->f_flags & O_WRONLY))) {
- if (open_file->invalidHandle == FALSE) {
- /* we found a valid, writeable network
- file handle to use to try to set the
- file size */
- __u16 nfid = open_file->netfid;
- __u32 npid = open_file->pid;
- read_unlock(&GlobalSMBSeslock);
- found = TRUE;
- rc = CIFSSMBSetFileSize(xid, pTcon,
- attrs->ia_size, nfid, npid,
- FALSE);
- cFYI(1, ("SetFileSize by handle "
- "(setattrs) rc = %d", rc));
- /* Do not need reopen and retry on
- EAGAIN since we will retry by
- pathname below */
-
- /* now that we found one valid file
- handle no sense continuing to loop
- trying others, so break here */
- break;
- }
+ open_file = find_writable_file(cifsInode);
+ if (open_file) {
+ __u16 nfid = open_file->netfid;
+ __u32 npid = open_file->pid;
+ rc = CIFSSMBSetFileSize(xid, pTcon, attrs->ia_size,
+ nfid, npid, FALSE);
+ atomic_dec(&open_file->wrtPending);
+ cFYI(1,("SetFSize for attrs rc = %d", rc));
+ if(rc == -EINVAL) {
+ int bytes_written;
+ rc = CIFSSMBWrite(xid, pTcon,
+ nfid, 0, attrs->ia_size,
+ &bytes_written, NULL, NULL,
+ 1 /* 45 seconds */);
+ cFYI(1,("Wrt seteof rc %d", rc));
}
}
- if (found == FALSE)
- read_unlock(&GlobalSMBSeslock);
-
if (rc != 0) {
/* Set file size by pathname rather than by handle
either because no valid, writeable file handle for
@@ -1013,7 +1025,30 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
cifs_sb->local_nls,
cifs_sb->mnt_cifs_flags &
CIFS_MOUNT_MAP_SPECIAL_CHR);
- cFYI(1, (" SetEOF by path (setattrs) rc = %d", rc));
+ cFYI(1, ("SetEOF by path (setattrs) rc = %d", rc));
+ if(rc == -EINVAL) {
+ __u16 netfid;
+ int oplock = FALSE;
+
+ rc = SMBLegacyOpen(xid, pTcon, full_path,
+ FILE_OPEN,
+ SYNCHRONIZE | FILE_WRITE_ATTRIBUTES,
+ CREATE_NOT_DIR, &netfid, &oplock,
+ NULL, cifs_sb->local_nls,
+ cifs_sb->mnt_cifs_flags &
+ CIFS_MOUNT_MAP_SPECIAL_CHR);
+ if (rc==0) {
+ int bytes_written;
+ rc = CIFSSMBWrite(xid, pTcon,
+ netfid, 0,
+ attrs->ia_size,
+ &bytes_written, NULL,
+ NULL, 1 /* 45 sec */);
+ cFYI(1,("wrt seteof rc %d",rc));
+ CIFSSMBClose(xid, pTcon, netfid);
+ }
+
+ }
}
/* Server is ok setting allocation size implicitly - no need
@@ -1026,24 +1061,22 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
rc = vmtruncate(direntry->d_inode, attrs->ia_size);
cifs_truncate_page(direntry->d_inode->i_mapping,
direntry->d_inode->i_size);
- }
+ } else
+ goto cifs_setattr_exit;
}
if (attrs->ia_valid & ATTR_UID) {
- cFYI(1, (" CIFS - UID changed to %d", attrs->ia_uid));
+ cFYI(1, ("UID changed to %d", attrs->ia_uid));
uid = attrs->ia_uid;
- /* entry->uid = cpu_to_le16(attr->ia_uid); */
}
if (attrs->ia_valid & ATTR_GID) {
- cFYI(1, (" CIFS - GID changed to %d", attrs->ia_gid));
+ cFYI(1, ("GID changed to %d", attrs->ia_gid));
gid = attrs->ia_gid;
- /* entry->gid = cpu_to_le16(attr->ia_gid); */
}
time_buf.Attributes = 0;
if (attrs->ia_valid & ATTR_MODE) {
- cFYI(1, (" CIFS - Mode changed to 0x%x", attrs->ia_mode));
+ cFYI(1, ("Mode changed to 0x%x", attrs->ia_mode));
mode = attrs->ia_mode;
- /* entry->mode = cpu_to_le16(attr->ia_mode); */
}
if ((cifs_sb->tcon->ses->capabilities & CAP_UNIX)
@@ -1083,18 +1116,24 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
cpu_to_le64(cifs_UnixTimeToNT(attrs->ia_mtime));
} else
time_buf.LastWriteTime = 0;
-
- if (attrs->ia_valid & ATTR_CTIME) {
+ /* Do not set ctime explicitly unless other time
+ stamps are changed explicitly (i.e. by utime()
+ since we would then have a mix of client and
+ server times */
+
+ if (set_time && (attrs->ia_valid & ATTR_CTIME)) {
set_time = TRUE;
- cFYI(1, (" CIFS - CTIME changed ")); /* BB probably no need */
+ /* Although Samba throws this field away
+ it may be useful to Windows - but we do
+ not want to set ctime unless some other
+ timestamp is changing */
+ cFYI(1, ("CIFS - CTIME changed "));
time_buf.ChangeTime =
cpu_to_le64(cifs_UnixTimeToNT(attrs->ia_ctime));
} else
time_buf.ChangeTime = 0;
if (set_time || time_buf.Attributes) {
- /* BB what if setting one attribute fails (such as size) but
- time setting works? */
time_buf.CreationTime = 0; /* do not change */
/* In the future we should experiment - try setting timestamps
via Handle (SetFileInfo) instead of by path */
@@ -1133,12 +1172,21 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
&time_buf, cifs_sb->local_nls); */
}
}
+ /* Even if error on time set, no sense failing the call if
+ the server would set the time to a reasonable value anyway,
+ and this check ensures that we are not being called from
+ sys_utimes in which case we ought to fail the call back to
+ the user when the server rejects the call */
+ if((rc) && (attrs->ia_valid &&
+ (ATTR_MODE | ATTR_GID | ATTR_UID | ATTR_SIZE)))
+ rc = 0;
}
/* do not need local check to inode_check_ok since the server does
that */
if (!rc)
rc = inode_setattr(direntry->d_inode, attrs);
+cifs_setattr_exit:
kfree(full_path);
FreeXid(xid);
return rc;
diff --git a/fs/cifs/link.c b/fs/cifs/link.c
index ab925ef4f863..0f99aae33162 100644
--- a/fs/cifs/link.c
+++ b/fs/cifs/link.c
@@ -84,10 +84,8 @@ cifs_hardlink(struct dentry *old_file, struct inode *inode,
cifsInode->time = 0; /* will force revalidate to go get info when needed */
cifs_hl_exit:
- if (fromName)
- kfree(fromName);
- if (toName)
- kfree(toName);
+ kfree(fromName);
+ kfree(toName);
FreeXid(xid);
return rc;
}
@@ -198,13 +196,15 @@ cifs_symlink(struct inode *inode, struct dentry *direntry, const char *symname)
("Create symlink worked but get_inode_info failed with rc = %d ",
rc));
} else {
- direntry->d_op = &cifs_dentry_ops;
+ if (pTcon->nocase)
+ direntry->d_op = &cifs_ci_dentry_ops;
+ else
+ direntry->d_op = &cifs_dentry_ops;
d_instantiate(direntry, newinode);
}
}
- if (full_path)
- kfree(full_path);
+ kfree(full_path);
FreeXid(xid);
return rc;
}
@@ -250,8 +250,7 @@ cifs_readlink(struct dentry *direntry, char __user *pBuffer, int buflen)
len = buflen;
tmpbuffer = kmalloc(len,GFP_KERNEL);
if(tmpbuffer == NULL) {
- if (full_path)
- kfree(full_path);
+ kfree(full_path);
FreeXid(xid);
return -ENOMEM;
}
@@ -300,8 +299,7 @@ cifs_readlink(struct dentry *direntry, char __user *pBuffer, int buflen)
strncpy(tmpbuffer, referrals, len-1);
}
}
- if(referrals)
- kfree(referrals);
+ kfree(referrals);
kfree(tmp_path);
}
/* BB add code like else decode referrals then memcpy to
@@ -320,12 +318,8 @@ cifs_readlink(struct dentry *direntry, char __user *pBuffer, int buflen)
rc));
}
- if (tmpbuffer) {
- kfree(tmpbuffer);
- }
- if (full_path) {
- kfree(full_path);
- }
+ kfree(tmpbuffer);
+ kfree(full_path);
FreeXid(xid);
return rc;
}
diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c
index 20ae4153f791..34a06692e4fa 100644
--- a/fs/cifs/misc.c
+++ b/fs/cifs/misc.c
@@ -34,8 +34,6 @@ extern mempool_t *cifs_sm_req_poolp;
extern mempool_t *cifs_req_poolp;
extern struct task_struct * oplockThread;
-static __u16 GlobalMid; /* multiplex id - rotating counter */
-
/* The xid serves as a useful identifier for each incoming vfs request,
in a similar way to the mid which is useful to track each sent smb,
and CurrentXid can also provide a running counter (although it
@@ -51,6 +49,8 @@ _GetXid(void)
GlobalTotalActiveXid++;
if (GlobalTotalActiveXid > GlobalMaxActiveXid)
GlobalMaxActiveXid = GlobalTotalActiveXid; /* keep high water mark for number of simultaneous vfs ops in our filesystem */
+ if(GlobalTotalActiveXid > 65000)
+ cFYI(1,("warning: more than 65000 requests active"));
xid = GlobalCurrentXid++;
spin_unlock(&GlobalMid_Lock);
return xid;
@@ -98,14 +98,10 @@ sesInfoFree(struct cifsSesInfo *buf_to_free)
atomic_dec(&sesInfoAllocCount);
list_del(&buf_to_free->cifsSessionList);
write_unlock(&GlobalSMBSeslock);
- if (buf_to_free->serverOS)
- kfree(buf_to_free->serverOS);
- if (buf_to_free->serverDomain)
- kfree(buf_to_free->serverDomain);
- if (buf_to_free->serverNOS)
- kfree(buf_to_free->serverNOS);
- if (buf_to_free->password)
- kfree(buf_to_free->password);
+ kfree(buf_to_free->serverOS);
+ kfree(buf_to_free->serverDomain);
+ kfree(buf_to_free->serverNOS);
+ kfree(buf_to_free->password);
kfree(buf_to_free);
}
@@ -144,8 +140,7 @@ tconInfoFree(struct cifsTconInfo *buf_to_free)
atomic_dec(&tconInfoAllocCount);
list_del(&buf_to_free->cifsConnectionList);
write_unlock(&GlobalSMBSeslock);
- if (buf_to_free->nativeFileSystem)
- kfree(buf_to_free->nativeFileSystem);
+ kfree(buf_to_free->nativeFileSystem);
kfree(buf_to_free);
}
@@ -218,6 +213,76 @@ cifs_small_buf_release(void *buf_to_free)
return;
}
+/*
+ Find a free multiplex id (SMB mid). Otherwise there could be
+ mid collisions which might cause problems, demultiplexing the
+ wrong response to this request. Multiplex ids could collide if
+ one of a series requests takes much longer than the others, or
+ if a very large number of long lived requests (byte range
+ locks or FindNotify requests) are pending. No more than
+ 64K-1 requests can be outstanding at one time. If no
+ mids are available, return zero. A future optimization
+ could make the combination of mids and uid the key we use
+ to demultiplex on (rather than mid alone).
+ In addition to the above check, the cifs demultiplex
+ code already used the command code as a secondary
+ check of the frame and if signing is negotiated the
+ response would be discarded if the mid were the same
+ but the signature was wrong. Since the mid is not put in the
+ pending queue until later (when it is about to be dispatched)
+ we do have to limit the number of outstanding requests
+ to somewhat less than 64K-1 although it is hard to imagine
+ so many threads being in the vfs at one time.
+*/
+__u16 GetNextMid(struct TCP_Server_Info *server)
+{
+ __u16 mid = 0;
+ __u16 last_mid;
+ int collision;
+
+ if(server == NULL)
+ return mid;
+
+ spin_lock(&GlobalMid_Lock);
+ last_mid = server->CurrentMid; /* we do not want to loop forever */
+ server->CurrentMid++;
+ /* This nested loop looks more expensive than it is.
+ In practice the list of pending requests is short,
+ fewer than 50, and the mids are likely to be unique
+ on the first pass through the loop unless some request
+ takes longer than the 64 thousand requests before it
+ (and it would also have to have been a request that
+ did not time out) */
+ while(server->CurrentMid != last_mid) {
+ struct list_head *tmp;
+ struct mid_q_entry *mid_entry;
+
+ collision = 0;
+ if(server->CurrentMid == 0)
+ server->CurrentMid++;
+
+ list_for_each(tmp, &server->pending_mid_q) {
+ mid_entry = list_entry(tmp, struct mid_q_entry, qhead);
+
+ if ((mid_entry->mid == server->CurrentMid) &&
+ (mid_entry->midState == MID_REQUEST_SUBMITTED)) {
+ /* This mid is in use, try a different one */
+ collision = 1;
+ break;
+ }
+ }
+ if(collision == 0) {
+ mid = server->CurrentMid;
+ break;
+ }
+ server->CurrentMid++;
+ }
+ spin_unlock(&GlobalMid_Lock);
+ return mid;
+}
+
+/* NB: MID can not be set if treeCon not passed in, in that
+ case it is responsbility of caller to set the mid */
void
header_assemble(struct smb_hdr *buffer, char smb_command /* command */ ,
const struct cifsTconInfo *treeCon, int word_count
@@ -233,7 +298,8 @@ header_assemble(struct smb_hdr *buffer, char smb_command /* command */ ,
(2 * word_count) + sizeof (struct smb_hdr) -
4 /* RFC 1001 length field does not count */ +
2 /* for bcc field itself */ ;
- /* Note that this is the only network field that has to be converted to big endian and it is done just before we send it */
+ /* Note that this is the only network field that has to be converted
+ to big endian and it is done just before we send it */
buffer->Protocol[0] = 0xFF;
buffer->Protocol[1] = 'S';
@@ -245,8 +311,6 @@ header_assemble(struct smb_hdr *buffer, char smb_command /* command */ ,
buffer->Pid = cpu_to_le16((__u16)current->tgid);
buffer->PidHigh = cpu_to_le16((__u16)(current->tgid >> 16));
spin_lock(&GlobalMid_Lock);
- GlobalMid++;
- buffer->Mid = GlobalMid;
spin_unlock(&GlobalMid_Lock);
if (treeCon) {
buffer->Tid = treeCon->tid;
@@ -256,8 +320,9 @@ header_assemble(struct smb_hdr *buffer, char smb_command /* command */ ,
if (treeCon->ses->capabilities & CAP_STATUS32) {
buffer->Flags2 |= SMBFLG2_ERR_STATUS;
}
-
- buffer->Uid = treeCon->ses->Suid; /* always in LE format */
+ /* Uid is not converted */
+ buffer->Uid = treeCon->ses->Suid;
+ buffer->Mid = GetNextMid(treeCon->ses->server);
if(multiuser_mount != 0) {
/* For the multiuser case, there are few obvious technically */
/* possible mechanisms to match the local linux user (uid) */
@@ -305,6 +370,8 @@ header_assemble(struct smb_hdr *buffer, char smb_command /* command */ ,
}
if (treeCon->Flags & SMB_SHARE_IS_IN_DFS)
buffer->Flags2 |= SMBFLG2_DFS;
+ if (treeCon->nocase)
+ buffer->Flags |= SMBFLG_CASELESS;
if((treeCon->ses) && (treeCon->ses->server))
if(treeCon->ses->server->secMode &
(SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
@@ -347,7 +414,8 @@ checkSMBhdr(struct smb_hdr *smb, __u16 mid)
int
checkSMB(struct smb_hdr *smb, __u16 mid, int length)
{
- __u32 len = be32_to_cpu(smb->smb_buf_length);
+ __u32 len = smb->smb_buf_length;
+ __u32 clc_len; /* calculated length */
cFYI(0,
("Entering checkSMB with Length: %x, smb_buf_length: %x ",
length, len));
@@ -368,23 +436,29 @@ checkSMB(struct smb_hdr *smb, __u16 mid, int length)
cERROR(1,
("smb_buf_length greater than MaxBufSize"));
cERROR(1,
- ("bad smb detected. Illegal length. The mid=%d",
+ ("bad smb detected. Illegal length. mid=%d",
smb->Mid));
return 1;
}
if (checkSMBhdr(smb, mid))
return 1;
-
- if ((4 + len != smbCalcSize(smb))
+ clc_len = smbCalcSize_LE(smb);
+ if ((4 + len != clc_len)
|| (4 + len != (unsigned int)length)) {
- return 0;
- } else {
- cERROR(1, ("smbCalcSize %x ", smbCalcSize(smb)));
- cERROR(1,
- ("bad smb size detected. The Mid=%d", smb->Mid));
- return 1;
+ cERROR(1, ("Calculated size 0x%x vs actual length 0x%x",
+ clc_len, 4 + len));
+ cERROR(1, ("bad smb size detected for Mid=%d", smb->Mid));
+ /* Windows XP can return a few bytes too much, presumably
+ an illegal pad, at the end of byte range lock responses
+ so we allow for up to eight byte pad, as long as actual
+ received length is as long or longer than calculated length */
+ if((4+len > clc_len) && (len <= clc_len + 3))
+ return 0;
+ else
+ return 1;
}
+ return 0;
}
int
is_valid_oplock_break(struct smb_hdr *buf)
@@ -448,9 +522,7 @@ is_valid_oplock_break(struct smb_hdr *buf)
list_for_each(tmp, &GlobalTreeConnectionList) {
tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList);
if (tcon->tid == buf->Tid) {
-#ifdef CONFIG_CIFS_STATS
- atomic_inc(&tcon->num_oplock_brks);
-#endif
+ cifs_stats_inc(&tcon->num_oplock_brks);
list_for_each(tmp1,&tcon->openFileList){
netfile = list_entry(tmp1,struct cifsFileInfo,
tlist);
@@ -603,6 +675,7 @@ cifsConvertToUCS(__le16 * target, const char *source, int maxlen,
int i,j,charlen;
int len_remaining = maxlen;
char src_char;
+ __u16 temp;
if(!mapChars)
return cifs_strtoUCS((wchar_t *) target, source, PATH_MAX, cp);
@@ -639,13 +712,14 @@ cifsConvertToUCS(__le16 * target, const char *source, int maxlen,
break;*/
default:
charlen = cp->char2uni(source+i,
- len_remaining, target+j);
+ len_remaining, &temp);
/* if no match, use question mark, which
at least in some cases servers as wild card */
if(charlen < 1) {
target[j] = cpu_to_le16(0x003f);
charlen = 1;
- }
+ } else
+ target[j] = cpu_to_le16(temp);
len_remaining -= charlen;
/* character may take more than one byte in the
the source string, but will take exactly two
diff --git a/fs/cifs/netmisc.c b/fs/cifs/netmisc.c
index a92af41d4411..f7814689844b 100644
--- a/fs/cifs/netmisc.c
+++ b/fs/cifs/netmisc.c
@@ -133,7 +133,6 @@ static const struct smb_to_posix_error mapping_table_ERRHRD[] = {
int
cifs_inet_pton(int address_family, char *cp,void *dst)
{
- struct in_addr address;
int value;
int digit;
int i;
@@ -190,8 +189,7 @@ cifs_inet_pton(int address_family, char *cp,void *dst)
if (value > addr_class_max[end - bytes])
return 0;
- address.s_addr = *((__be32 *) bytes) | htonl(value);
- *((__be32 *)dst) = address.s_addr;
+ *((__be32 *)dst) = *((__be32 *) bytes) | htonl(value);
return 1; /* success */
}
@@ -815,7 +813,7 @@ map_smb_to_linux_error(struct smb_hdr *smb)
if (smb->Flags2 & SMBFLG2_ERR_STATUS) {
/* translate the newer STATUS codes to old style errors and then to POSIX errors */
__u32 err = le32_to_cpu(smb->Status.CifsError);
- if(cifsFYI)
+ if(cifsFYI & CIFS_RC)
cifs_print_status(err);
ntstatus_to_dos(err, &smberrclass, &smberrcode);
} else {
@@ -870,7 +868,14 @@ unsigned int
smbCalcSize(struct smb_hdr *ptr)
{
return (sizeof (struct smb_hdr) + (2 * ptr->WordCount) +
- BCC(ptr));
+ 2 /* size of the bcc field */ + BCC(ptr));
+}
+
+unsigned int
+smbCalcSize_LE(struct smb_hdr *ptr)
+{
+ return (sizeof (struct smb_hdr) + (2 * ptr->WordCount) +
+ 2 /* size of the bcc field */ + le16_to_cpu(BCC_LE(ptr)));
}
/* The following are taken from fs/ntfs/util.c */
diff --git a/fs/cifs/ntlmssp.h b/fs/cifs/ntlmssp.h
index 6facb41117a3..803389b64a2c 100644
--- a/fs/cifs/ntlmssp.h
+++ b/fs/cifs/ntlmssp.h
@@ -19,8 +19,6 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#pragma pack(1)
-
#define NTLMSSP_SIGNATURE "NTLMSSP"
/* Message Types */
#define NtLmNegotiate cpu_to_le32(1)
@@ -63,7 +61,7 @@ typedef struct _SECURITY_BUFFER {
__le16 Length;
__le16 MaximumLength;
__le32 Buffer; /* offset to buffer */
-} SECURITY_BUFFER;
+} __attribute__((packed)) SECURITY_BUFFER;
typedef struct _NEGOTIATE_MESSAGE {
__u8 Signature[sizeof (NTLMSSP_SIGNATURE)];
@@ -73,7 +71,7 @@ typedef struct _NEGOTIATE_MESSAGE {
SECURITY_BUFFER WorkstationName; /* RFC 1001 and ASCII */
char DomainString[0];
/* followed by WorkstationString */
-} NEGOTIATE_MESSAGE, *PNEGOTIATE_MESSAGE;
+} __attribute__((packed)) NEGOTIATE_MESSAGE, *PNEGOTIATE_MESSAGE;
typedef struct _CHALLENGE_MESSAGE {
__u8 Signature[sizeof (NTLMSSP_SIGNATURE)];
@@ -83,7 +81,7 @@ typedef struct _CHALLENGE_MESSAGE {
__u8 Challenge[CIFS_CRYPTO_KEY_SIZE];
__u8 Reserved[8];
SECURITY_BUFFER TargetInfoArray;
-} CHALLENGE_MESSAGE, *PCHALLENGE_MESSAGE;
+} __attribute__((packed)) CHALLENGE_MESSAGE, *PCHALLENGE_MESSAGE;
typedef struct _AUTHENTICATE_MESSAGE {
__u8 Signature[sizeof (NTLMSSP_SIGNATURE)];
@@ -96,6 +94,4 @@ typedef struct _AUTHENTICATE_MESSAGE {
SECURITY_BUFFER SessionKey;
__le32 NegotiateFlags;
char UserString[0];
-} AUTHENTICATE_MESSAGE, *PAUTHENTICATE_MESSAGE;
-
-#pragma pack() /* resume default structure packing */
+} __attribute__((packed)) AUTHENTICATE_MESSAGE, *PAUTHENTICATE_MESSAGE;
diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c
index 22557716f9af..a86bd1c07602 100644
--- a/fs/cifs/readdir.c
+++ b/fs/cifs/readdir.c
@@ -91,7 +91,10 @@ static int construct_dentry(struct qstr *qstring, struct file *file,
}
*ptmp_inode = new_inode(file->f_dentry->d_sb);
- tmp_dentry->d_op = &cifs_dentry_ops;
+ if (pTcon->nocase)
+ tmp_dentry->d_op = &cifs_ci_dentry_ops;
+ else
+ tmp_dentry->d_op = &cifs_dentry_ops;
if(*ptmp_inode == NULL)
return rc;
rc = 1;
@@ -148,6 +151,13 @@ static void fill_in_inode(struct inode *tmp_inode,
tmp_inode->i_mode = cifs_sb->mnt_dir_mode;
}
tmp_inode->i_mode |= S_IFDIR;
+ } else if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) &&
+ (attr & ATTR_SYSTEM) && (end_of_file == 0)) {
+ *pobject_type = DT_FIFO;
+ tmp_inode->i_mode |= S_IFIFO;
+/* BB Finish for SFU style symlinks and devies */
+/* } else if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) &&
+ (attr & ATTR_SYSTEM) && ) { */
/* we no longer mark these because we could not follow them */
/* } else if (attr & ATTR_REPARSE) {
*pobject_type = DT_LNK;
@@ -187,11 +197,17 @@ static void fill_in_inode(struct inode *tmp_inode,
tmp_inode->i_fop = &cifs_file_direct_ops;
else
tmp_inode->i_fop = &cifs_file_ops;
+ if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
+ tmp_inode->i_fop->lock = NULL;
tmp_inode->i_data.a_ops = &cifs_addr_ops;
-
+ if((cifs_sb->tcon) && (cifs_sb->tcon->ses) &&
+ (cifs_sb->tcon->ses->server->maxBuf <
+ 4096 + MAX_CIFS_HDR_SIZE))
+ tmp_inode->i_data.a_ops->readpages = NULL;
if(isNewInode)
- return; /* No sense invalidating pages for new inode since we
- have not started caching readahead file data yet */
+ return; /* No sense invalidating pages for new inode
+ since have not started caching readahead file
+ data yet */
if (timespec_equal(&tmp_inode->i_mtime, &local_mtime) &&
(local_size == tmp_inode->i_size)) {
@@ -290,7 +306,13 @@ static void unix_fill_in_inode(struct inode *tmp_inode,
tmp_inode->i_fop = &cifs_file_direct_ops;
else
tmp_inode->i_fop = &cifs_file_ops;
+ if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
+ tmp_inode->i_fop->lock = NULL;
tmp_inode->i_data.a_ops = &cifs_addr_ops;
+ if((cifs_sb->tcon) && (cifs_sb->tcon->ses) &&
+ (cifs_sb->tcon->ses->server->maxBuf <
+ 4096 + MAX_CIFS_HDR_SIZE))
+ tmp_inode->i_data.a_ops->readpages = NULL;
if(isNewInode)
return; /* No sense invalidating pages for new inode since we
@@ -374,7 +396,8 @@ ffirst_retry:
rc = CIFSFindFirst(xid, pTcon,full_path,cifs_sb->local_nls,
&cifsFile->netfid, &cifsFile->srch_inf,
- cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
+ cifs_sb->mnt_cifs_flags &
+ CIFS_MOUNT_MAP_SPECIAL_CHR, CIFS_DIR_SEP(cifs_sb));
if(rc == 0)
cifsFile->invalidHandle = FALSE;
if((rc == -EOPNOTSUPP) &&
@@ -491,6 +514,30 @@ static int cifs_entry_is_dot(char *current_entry, struct cifsFileInfo *cfile)
return rc;
}
+/* Check if directory that we are searching has changed so we can decide
+ whether we can use the cached search results from the previous search */
+static int is_dir_changed(struct file * file)
+{
+ struct inode * inode;
+ struct cifsInodeInfo *cifsInfo;
+
+ if(file->f_dentry == NULL)
+ return 0;
+
+ inode = file->f_dentry->d_inode;
+
+ if(inode == NULL)
+ return 0;
+
+ cifsInfo = CIFS_I(inode);
+
+ if(cifsInfo->time == 0)
+ return 1; /* directory was changed, perhaps due to unlink */
+ else
+ return 0;
+
+}
+
/* find the corresponding entry in the search */
/* Note that the SMB server returns search entries for . and .. which
complicates logic here if we choose to parse for them and we do not
@@ -507,7 +554,8 @@ static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon,
struct cifsFileInfo * cifsFile = file->private_data;
/* check if index in the buffer */
- if((cifsFile == NULL) || (ppCurrentEntry == NULL) || (num_to_ret == NULL))
+ if((cifsFile == NULL) || (ppCurrentEntry == NULL) ||
+ (num_to_ret == NULL))
return -ENOENT;
*ppCurrentEntry = NULL;
@@ -515,7 +563,9 @@ static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon,
cifsFile->srch_inf.index_of_last_entry -
cifsFile->srch_inf.entries_in_buffer;
/* dump_cifs_file_struct(file, "In fce ");*/
- if(index_to_find < first_entry_in_buffer) {
+ if(((index_to_find < cifsFile->srch_inf.index_of_last_entry) &&
+ is_dir_changed(file)) ||
+ (index_to_find < first_entry_in_buffer)) {
/* close and restart search */
cFYI(1,("search backing up - close and restart search"));
cifsFile->invalidHandle = TRUE;
@@ -536,7 +586,8 @@ static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon,
while((index_to_find >= cifsFile->srch_inf.index_of_last_entry) &&
(rc == 0) && (cifsFile->srch_inf.endOfSearch == FALSE)){
cFYI(1,("calling findnext2"));
- rc = CIFSFindNext(xid,pTcon,cifsFile->netfid, &cifsFile->srch_inf);
+ rc = CIFSFindNext(xid,pTcon,cifsFile->netfid,
+ &cifsFile->srch_inf);
if(rc)
return -ENOENT;
}
@@ -548,14 +599,13 @@ static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon,
char * end_of_smb = cifsFile->srch_inf.ntwrk_buf_start +
smbCalcSize((struct smb_hdr *)
cifsFile->srch_inf.ntwrk_buf_start);
-/* dump_cifs_file_struct(file,"found entry in fce "); */
first_entry_in_buffer = cifsFile->srch_inf.index_of_last_entry
- cifsFile->srch_inf.entries_in_buffer;
pos_in_buf = index_to_find - first_entry_in_buffer;
cFYI(1,("found entry - pos_in_buf %d",pos_in_buf));
current_entry = cifsFile->srch_inf.srch_entries_start;
for(i=0;(i<(pos_in_buf)) && (current_entry != NULL);i++) {
- /* go entry to next entry figuring out which we need to start with */
+ /* go entry by entry figuring out which is first */
/* if( . or ..)
skip */
rc = cifs_entry_is_dot(current_entry,cifsFile);
@@ -582,11 +632,10 @@ static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon,
}
if(pos_in_buf >= cifsFile->srch_inf.entries_in_buffer) {
- cFYI(1,("can not return entries when pos_in_buf beyond last entry"));
+ cFYI(1,("can not return entries pos_in_buf beyond last entry"));
*num_to_ret = 0;
} else
*num_to_ret = cifsFile->srch_inf.entries_in_buffer - pos_in_buf;
-/* dump_cifs_file_struct(file, "end fce ");*/
return rc;
}
@@ -721,7 +770,8 @@ static int cifs_filldir(char *pfindEntry, struct file *file,
(FILE_DIRECTORY_INFO *)pfindEntry,&obj_type, rc);
}
- rc = filldir(direntry,qstring.name,qstring.len,file->f_pos,tmp_inode->i_ino,obj_type);
+ rc = filldir(direntry,qstring.name,qstring.len,file->f_pos,
+ tmp_inode->i_ino,obj_type);
if(rc) {
cFYI(1,("filldir rc = %d",rc));
}
@@ -805,15 +855,12 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
FreeXid(xid);
return -EIO;
}
-/* dump_cifs_file_struct(file, "Begin rdir "); */
cifs_sb = CIFS_SB(file->f_dentry->d_sb);
pTcon = cifs_sb->tcon;
if(pTcon == NULL)
return -EINVAL;
-/* cFYI(1,("readdir2 pos: %lld",file->f_pos)); */
-
switch ((int) file->f_pos) {
case 0:
/*if (filldir(direntry, ".", 1, file->f_pos,
@@ -866,7 +913,6 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
cifsFile->search_resume_name = NULL; */
/* BB account for . and .. in f_pos as special case */
- /* dump_cifs_file_struct(file, "rdir after default ");*/
rc = find_cifs_entry(xid,pTcon, file,
&current_entry,&num_to_fill);
@@ -906,14 +952,14 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
cifs_save_resume_key(current_entry,cifsFile);
break;
} else
- current_entry = nxt_dir_entry(current_entry,end_of_smb);
+ current_entry = nxt_dir_entry(current_entry,
+ end_of_smb);
}
kfree(tmp_buf);
break;
} /* end switch */
rddir2_exit:
- /* dump_cifs_file_struct(file, "end rdir "); */
FreeXid(xid);
return rc;
}
diff --git a/fs/cifs/rfc1002pdu.h b/fs/cifs/rfc1002pdu.h
index 806c0ed06da9..9222033cad8e 100644
--- a/fs/cifs/rfc1002pdu.h
+++ b/fs/cifs/rfc1002pdu.h
@@ -21,8 +21,6 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#pragma pack(1)
-
/* NB: unlike smb/cifs packets, the RFC1002 structures are big endian */
/* RFC 1002 session packet types */
@@ -48,17 +46,17 @@ struct rfc1002_session_packet {
__u8 calling_len;
__u8 calling_name[32];
__u8 scope2; /* null */
- } session_req;
+ } __attribute__((packed)) session_req;
struct {
__u32 retarget_ip_addr;
__u16 port;
- } retarget_resp;
+ } __attribute__((packed)) retarget_resp;
__u8 neg_ses_resp_error_code;
/* POSITIVE_SESSION_RESPONSE packet does not include trailer.
SESSION_KEEP_ALIVE packet also does not include a trailer.
Trailer for the SESSION_MESSAGE packet is SMB/CIFS header */
- } trailer;
-};
+ } __attribute__((packed)) trailer;
+} __attribute__((packed));
/* Negative Session Response error codes */
#define RFC1002_NOT_LISTENING_CALLED 0x80 /* not listening on called name */
@@ -74,6 +72,3 @@ server netbios name). Currently server names are resolved only via DNS
(tcp name) or ip address or an /etc/hosts equivalent mapping to ip address.*/
#define DEFAULT_CIFS_CALLED_NAME "*SMBSERVER "
-
-#pragma pack() /* resume default structure packing */
-
diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c
index 0046c219833d..981ea0d8b9cd 100644
--- a/fs/cifs/transport.c
+++ b/fs/cifs/transport.c
@@ -49,7 +49,8 @@ AllocMidQEntry(struct smb_hdr *smb_buffer, struct cifsSesInfo *ses)
return NULL;
}
- temp = (struct mid_q_entry *) mempool_alloc(cifs_mid_poolp,SLAB_KERNEL | SLAB_NOFS);
+ temp = (struct mid_q_entry *) mempool_alloc(cifs_mid_poolp,
+ SLAB_KERNEL | SLAB_NOFS);
if (temp == NULL)
return temp;
else {
@@ -58,7 +59,9 @@ AllocMidQEntry(struct smb_hdr *smb_buffer, struct cifsSesInfo *ses)
temp->pid = current->pid;
temp->command = smb_buffer->Command;
cFYI(1, ("For smb_command %d", temp->command));
- do_gettimeofday(&temp->when_sent);
+ /* do_gettimeofday(&temp->when_sent);*/ /* easier to use jiffies */
+ /* when mid allocated can be before when sent */
+ temp->when_alloc = jiffies;
temp->ses = ses;
temp->tsk = current;
}
@@ -74,6 +77,9 @@ AllocMidQEntry(struct smb_hdr *smb_buffer, struct cifsSesInfo *ses)
static void
DeleteMidQEntry(struct mid_q_entry *midEntry)
{
+#ifdef CONFIG_CIFS_STATS2
+ unsigned long now;
+#endif
spin_lock(&GlobalMid_Lock);
midEntry->midState = MID_FREE;
list_del(&midEntry->qhead);
@@ -83,6 +89,22 @@ DeleteMidQEntry(struct mid_q_entry *midEntry)
cifs_buf_release(midEntry->resp_buf);
else
cifs_small_buf_release(midEntry->resp_buf);
+#ifdef CONFIG_CIFS_STATS2
+ now = jiffies;
+ /* commands taking longer than one second are indications that
+ something is wrong, unless it is quite a slow link or server */
+ if((now - midEntry->when_alloc) > HZ) {
+ if((cifsFYI & CIFS_TIMER) &&
+ (midEntry->command != SMB_COM_LOCKING_ANDX)) {
+ printk(KERN_DEBUG " CIFS slow rsp: cmd %d mid %d",
+ midEntry->command, midEntry->mid);
+ printk(" A: 0x%lx S: 0x%lx R: 0x%lx\n",
+ now - midEntry->when_alloc,
+ now - midEntry->when_sent,
+ now - midEntry->when_received);
+ }
+ }
+#endif
mempool_free(midEntry, cifs_mid_poolp);
}
@@ -146,32 +168,37 @@ smb_send(struct socket *ssocket, struct smb_hdr *smb_buffer,
Flags2 is converted in SendReceive */
smb_buffer->smb_buf_length = cpu_to_be32(smb_buffer->smb_buf_length);
- cFYI(1, ("Sending smb of length %d ", smb_buf_length));
+ cFYI(1, ("Sending smb of length %d", smb_buf_length));
dump_smb(smb_buffer, len);
while (len > 0) {
rc = kernel_sendmsg(ssocket, &smb_msg, &iov, 1, len);
if ((rc == -ENOSPC) || (rc == -EAGAIN)) {
i++;
- if(i > 60) {
+ /* smaller timeout here than send2 since smaller size */
+ /* Although it may not be required, this also is smaller
+ oplock break time */
+ if(i > 12) {
cERROR(1,
- ("sends on sock %p stuck for 30 seconds",
+ ("sends on sock %p stuck for 7 seconds",
ssocket));
rc = -EAGAIN;
break;
}
- msleep(500);
+ msleep(1 << i);
continue;
}
if (rc < 0)
break;
+ else
+ i = 0; /* reset i after each successful send */
iov.iov_base += rc;
iov.iov_len -= rc;
len -= rc;
}
if (rc < 0) {
- cERROR(1,("Error %d sending data on socket to server.", rc));
+ cERROR(1,("Error %d sending data on socket to server", rc));
} else {
rc = 0;
}
@@ -179,26 +206,21 @@ smb_send(struct socket *ssocket, struct smb_hdr *smb_buffer,
return rc;
}
-#ifdef CIFS_EXPERIMENTAL
-/* BB finish off this function, adding support for writing set of pages as iovec */
-/* and also adding support for operations that need to parse the response smb */
-
-int
-smb_sendv(struct socket *ssocket, struct smb_hdr *smb_buffer,
- unsigned int smb_buf_length, struct kvec * write_vector
- /* page list */, struct sockaddr *sin)
+#ifdef CONFIG_CIFS_EXPERIMENTAL
+static int
+smb_send2(struct socket *ssocket, struct kvec *iov, int n_vec,
+ struct sockaddr *sin)
{
int rc = 0;
int i = 0;
struct msghdr smb_msg;
- number_of_pages += 1; /* account for SMB header */
- struct kvec * piov = kmalloc(number_of_pages * sizeof(struct kvec));
- unsigned len = smb_buf_length + 4;
-
+ struct smb_hdr *smb_buffer = iov[0].iov_base;
+ unsigned int len = iov[0].iov_len;
+ unsigned int total_len;
+ int first_vec = 0;
+
if(ssocket == NULL)
return -ENOTSOCK; /* BB eventually add reconnect code here */
- iov.iov_base = smb_buffer;
- iov.iov_len = len;
smb_msg.msg_name = sin;
smb_msg.msg_namelen = sizeof (struct sockaddr);
@@ -211,49 +233,80 @@ smb_sendv(struct socket *ssocket, struct smb_hdr *smb_buffer,
cifssmb.c and RFC1001 len is converted to bigendian in smb_send
Flags2 is converted in SendReceive */
+
+ total_len = 0;
+ for (i = 0; i < n_vec; i++)
+ total_len += iov[i].iov_len;
+
smb_buffer->smb_buf_length = cpu_to_be32(smb_buffer->smb_buf_length);
- cFYI(1, ("Sending smb of length %d ", smb_buf_length));
+ cFYI(1, ("Sending smb: total_len %d", total_len));
dump_smb(smb_buffer, len);
- while (len > 0) {
- rc = kernel_sendmsg(ssocket, &smb_msg, &iov, number_of_pages,
- len);
+ while (total_len) {
+ rc = kernel_sendmsg(ssocket, &smb_msg, &iov[first_vec],
+ n_vec - first_vec, total_len);
if ((rc == -ENOSPC) || (rc == -EAGAIN)) {
i++;
- if(i > 60) {
+ if(i >= 14) {
cERROR(1,
- ("sends on sock %p stuck for 30 seconds",
+ ("sends on sock %p stuck for 15 seconds",
ssocket));
rc = -EAGAIN;
break;
}
- msleep(500);
+ msleep(1 << i);
continue;
}
if (rc < 0)
break;
- iov.iov_base += rc;
- iov.iov_len -= rc;
- len -= rc;
+
+ if (rc >= total_len) {
+ WARN_ON(rc > total_len);
+ break;
+ }
+ if(rc == 0) {
+ /* should never happen, letting socket clear before
+ retrying is our only obvious option here */
+ cERROR(1,("tcp sent no data"));
+ msleep(500);
+ continue;
+ }
+ total_len -= rc;
+ /* the line below resets i */
+ for (i = first_vec; i < n_vec; i++) {
+ if (iov[i].iov_len) {
+ if (rc > iov[i].iov_len) {
+ rc -= iov[i].iov_len;
+ iov[i].iov_len = 0;
+ } else {
+ iov[i].iov_base += rc;
+ iov[i].iov_len -= rc;
+ first_vec = i;
+ break;
+ }
+ }
+ }
+ i = 0; /* in case we get ENOSPC on the next send */
}
if (rc < 0) {
- cERROR(1,("Error %d sending data on socket to server.", rc));
- } else {
+ cERROR(1,("Error %d sending data on socket to server", rc));
+ } else
rc = 0;
- }
return rc;
}
-
int
-CIFSSendRcv(const unsigned int xid, struct cifsSesInfo *ses,
- struct smb_hdr *in_buf, struct kvec * write_vector /* page list */, int *pbytes_returned, const int long_op)
+SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
+ struct kvec *iov, int n_vec, int *pbytes_returned,
+ const int long_op)
{
int rc = 0;
- unsigned long timeout = 15 * HZ;
- struct mid_q_entry *midQ = NULL;
+ unsigned int receive_len;
+ unsigned long timeout;
+ struct mid_q_entry *midQ;
+ struct smb_hdr *in_buf = iov[0].iov_base;
if (ses == NULL) {
cERROR(1,("Null smb session"));
@@ -263,14 +316,8 @@ CIFSSendRcv(const unsigned int xid, struct cifsSesInfo *ses,
cERROR(1,("Null tcp session"));
return -EIO;
}
- if(pbytes_returned == NULL)
- return -EIO;
- else
- *pbytes_returned = 0;
-
-
- if(ses->server->tcpStatus == CIFS_EXITING)
+ if(ses->server->tcpStatus == CifsExiting)
return -ENOENT;
/* Ensure that we do not send more than 50 overlapping requests
@@ -282,11 +329,18 @@ CIFSSendRcv(const unsigned int xid, struct cifsSesInfo *ses,
} else {
spin_lock(&GlobalMid_Lock);
while(1) {
- if(atomic_read(&ses->server->inFlight) >= cifs_max_pending){
+ if(atomic_read(&ses->server->inFlight) >=
+ cifs_max_pending){
spin_unlock(&GlobalMid_Lock);
+#ifdef CONFIG_CIFS_STATS2
+ atomic_inc(&ses->server->num_waiters);
+#endif
wait_event(ses->server->request_q,
atomic_read(&ses->server->inFlight)
< cifs_max_pending);
+#ifdef CONFIG_CIFS_STATS2
+ atomic_dec(&ses->server->num_waiters);
+#endif
spin_lock(&GlobalMid_Lock);
} else {
if(ses->server->tcpStatus == CifsExiting) {
@@ -314,17 +368,17 @@ CIFSSendRcv(const unsigned int xid, struct cifsSesInfo *ses,
if (ses->server->tcpStatus == CifsExiting) {
rc = -ENOENT;
- goto cifs_out_label;
+ goto out_unlock2;
} else if (ses->server->tcpStatus == CifsNeedReconnect) {
cFYI(1,("tcp session dead - return to caller to retry"));
rc = -EAGAIN;
- goto cifs_out_label;
+ goto out_unlock2;
} else if (ses->status != CifsGood) {
/* check if SMB session is bad because we are setting it up */
if((in_buf->Command != SMB_COM_SESSION_SETUP_ANDX) &&
(in_buf->Command != SMB_COM_NEGOTIATE)) {
rc = -EAGAIN;
- goto cifs_out_label;
+ goto out_unlock2;
} /* else ok - we are setting up session */
}
midQ = AllocMidQEntry(in_buf, ses);
@@ -338,51 +392,162 @@ CIFSSendRcv(const unsigned int xid, struct cifsSesInfo *ses,
return -ENOMEM;
}
- if (in_buf->smb_buf_length > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) {
- up(&ses->server->tcpSem);
- cERROR(1,
- ("Illegal length, greater than maximum frame, %d ",
- in_buf->smb_buf_length));
+/* BB FIXME */
+/* rc = cifs_sign_smb2(iov, n_vec, ses->server, &midQ->sequence_number); */
+
+ midQ->midState = MID_REQUEST_SUBMITTED;
+#ifdef CONFIG_CIFS_STATS2
+ atomic_inc(&ses->server->inSend);
+#endif
+ rc = smb_send2(ses->server->ssocket, iov, n_vec,
+ (struct sockaddr *) &(ses->server->addr.sockAddr));
+#ifdef CONFIG_CIFS_STATS2
+ atomic_dec(&ses->server->inSend);
+ midQ->when_sent = jiffies;
+#endif
+ if(rc < 0) {
DeleteMidQEntry(midQ);
+ up(&ses->server->tcpSem);
/* If not lock req, update # of requests on wire to server */
if(long_op < 3) {
atomic_dec(&ses->server->inFlight);
wake_up(&ses->server->request_q);
}
- return -EIO;
+ return rc;
+ } else
+ up(&ses->server->tcpSem);
+ if (long_op == -1)
+ goto cifs_no_response_exit2;
+ else if (long_op == 2) /* writes past end of file can take loong time */
+ timeout = 180 * HZ;
+ else if (long_op == 1)
+ timeout = 45 * HZ; /* should be greater than
+ servers oplock break timeout (about 43 seconds) */
+ else if (long_op > 2) {
+ timeout = MAX_SCHEDULE_TIMEOUT;
+ } else
+ timeout = 15 * HZ;
+ /* wait for 15 seconds or until woken up due to response arriving or
+ due to last connection to this server being unmounted */
+ if (signal_pending(current)) {
+ /* if signal pending do not hold up user for full smb timeout
+ but we still give response a change to complete */
+ timeout = 2 * HZ;
+ }
+
+ /* No user interrupts in wait - wreaks havoc with performance */
+ if(timeout != MAX_SCHEDULE_TIMEOUT) {
+ timeout += jiffies;
+ wait_event(ses->server->response_q,
+ (!(midQ->midState & MID_REQUEST_SUBMITTED)) ||
+ time_after(jiffies, timeout) ||
+ ((ses->server->tcpStatus != CifsGood) &&
+ (ses->server->tcpStatus != CifsNew)));
+ } else {
+ wait_event(ses->server->response_q,
+ (!(midQ->midState & MID_REQUEST_SUBMITTED)) ||
+ ((ses->server->tcpStatus != CifsGood) &&
+ (ses->server->tcpStatus != CifsNew)));
}
- /* BB can we sign efficiently in this path? */
- rc = cifs_sign_smb(in_buf, ses->server, &midQ->sequence_number);
+ spin_lock(&GlobalMid_Lock);
+ if (midQ->resp_buf) {
+ spin_unlock(&GlobalMid_Lock);
+ receive_len = midQ->resp_buf->smb_buf_length;
+ } else {
+ cERROR(1,("No response to cmd %d mid %d",
+ midQ->command, midQ->mid));
+ if(midQ->midState == MID_REQUEST_SUBMITTED) {
+ if(ses->server->tcpStatus == CifsExiting)
+ rc = -EHOSTDOWN;
+ else {
+ ses->server->tcpStatus = CifsNeedReconnect;
+ midQ->midState = MID_RETRY_NEEDED;
+ }
+ }
- midQ->midState = MID_REQUEST_SUBMITTED;
-/* rc = smb_sendv(ses->server->ssocket, in_buf, in_buf->smb_buf_length,
- piovec,
- (struct sockaddr *) &(ses->server->addr.sockAddr));*/
- if(rc < 0) {
+ if (rc != -EHOSTDOWN) {
+ if(midQ->midState == MID_RETRY_NEEDED) {
+ rc = -EAGAIN;
+ cFYI(1,("marking request for retry"));
+ } else {
+ rc = -EIO;
+ }
+ }
+ spin_unlock(&GlobalMid_Lock);
DeleteMidQEntry(midQ);
- up(&ses->server->tcpSem);
/* If not lock req, update # of requests on wire to server */
if(long_op < 3) {
atomic_dec(&ses->server->inFlight);
wake_up(&ses->server->request_q);
}
return rc;
- } else
- up(&ses->server->tcpSem);
-cifs_out_label:
- if(midQ)
- DeleteMidQEntry(midQ);
-
+ }
+
+ if (receive_len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE) {
+ cERROR(1, ("Frame too large received. Length: %d Xid: %d",
+ receive_len, xid));
+ rc = -EIO;
+ } else { /* rcvd frame is ok */
+
+ if (midQ->resp_buf &&
+ (midQ->midState == MID_RESPONSE_RECEIVED)) {
+ in_buf->smb_buf_length = receive_len;
+ /* BB verify that length would not overrun small buf */
+ memcpy((char *)in_buf + 4,
+ (char *)midQ->resp_buf + 4,
+ receive_len);
+
+ dump_smb(in_buf, 80);
+ /* convert the length into a more usable form */
+ if((receive_len > 24) &&
+ (ses->server->secMode & (SECMODE_SIGN_REQUIRED |
+ SECMODE_SIGN_ENABLED))) {
+ rc = cifs_verify_signature(in_buf,
+ ses->server->mac_signing_key,
+ midQ->sequence_number+1);
+ if(rc) {
+ cERROR(1,("Unexpected SMB signature"));
+ /* BB FIXME add code to kill session */
+ }
+ }
+
+ *pbytes_returned = in_buf->smb_buf_length;
+
+ /* BB special case reconnect tid and uid here? */
+ rc = map_smb_to_linux_error(in_buf);
+
+ /* convert ByteCount if necessary */
+ if (receive_len >=
+ sizeof (struct smb_hdr) -
+ 4 /* do not count RFC1001 header */ +
+ (2 * in_buf->WordCount) + 2 /* bcc */ )
+ BCC(in_buf) = le16_to_cpu(BCC(in_buf));
+ } else {
+ rc = -EIO;
+ cFYI(1,("Bad MID state?"));
+ }
+ }
+cifs_no_response_exit2:
+ DeleteMidQEntry(midQ);
+
if(long_op < 3) {
- atomic_dec(&ses->server->inFlight);
+ atomic_dec(&ses->server->inFlight);
wake_up(&ses->server->request_q);
}
return rc;
-}
+out_unlock2:
+ up(&ses->server->tcpSem);
+ /* If not lock req, update # of requests on wire to server */
+ if(long_op < 3) {
+ atomic_dec(&ses->server->inFlight);
+ wake_up(&ses->server->request_q);
+ }
+ return rc;
+}
#endif /* CIFS_EXPERIMENTAL */
int
@@ -419,9 +584,15 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
if(atomic_read(&ses->server->inFlight) >=
cifs_max_pending){
spin_unlock(&GlobalMid_Lock);
+#ifdef CONFIG_CIFS_STATS2
+ atomic_inc(&ses->server->num_waiters);
+#endif
wait_event(ses->server->request_q,
atomic_read(&ses->server->inFlight)
< cifs_max_pending);
+#ifdef CONFIG_CIFS_STATS2
+ atomic_dec(&ses->server->num_waiters);
+#endif
spin_lock(&GlobalMid_Lock);
} else {
if(ses->server->tcpStatus == CifsExiting) {
@@ -490,8 +661,15 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
rc = cifs_sign_smb(in_buf, ses->server, &midQ->sequence_number);
midQ->midState = MID_REQUEST_SUBMITTED;
+#ifdef CONFIG_CIFS_STATS2
+ atomic_inc(&ses->server->inSend);
+#endif
rc = smb_send(ses->server->ssocket, in_buf, in_buf->smb_buf_length,
(struct sockaddr *) &(ses->server->addr.sockAddr));
+#ifdef CONFIG_CIFS_STATS2
+ atomic_dec(&ses->server->inSend);
+ midQ->when_sent = jiffies;
+#endif
if(rc < 0) {
DeleteMidQEntry(midQ);
up(&ses->server->tcpSem);
@@ -506,7 +684,7 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
if (long_op == -1)
goto cifs_no_response_exit;
else if (long_op == 2) /* writes past end of file can take loong time */
- timeout = 300 * HZ;
+ timeout = 180 * HZ;
else if (long_op == 1)
timeout = 45 * HZ; /* should be greater than
servers oplock break timeout (about 43 seconds) */
@@ -540,9 +718,10 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
spin_lock(&GlobalMid_Lock);
if (midQ->resp_buf) {
spin_unlock(&GlobalMid_Lock);
- receive_len = be32_to_cpu(*(__be32 *)midQ->resp_buf);
+ receive_len = midQ->resp_buf->smb_buf_length;
} else {
- cERROR(1,("No response buffer"));
+ cERROR(1,("No response for cmd %d mid %d",
+ midQ->command, midQ->mid));
if(midQ->midState == MID_REQUEST_SUBMITTED) {
if(ses->server->tcpStatus == CifsExiting)
rc = -EHOSTDOWN;
@@ -610,7 +789,7 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
BCC(out_buf) = le16_to_cpu(BCC(out_buf));
} else {
rc = -EIO;
- cFYI(1,("Bad MID state? "));
+ cERROR(1,("Bad MID state? "));
}
}
cifs_no_response_exit:
diff --git a/fs/cifs/xattr.c b/fs/cifs/xattr.c
index c1e02eff1d25..f375f87c7dbd 100644
--- a/fs/cifs/xattr.c
+++ b/fs/cifs/xattr.c
@@ -87,8 +87,7 @@ int cifs_removexattr(struct dentry * direntry, const char * ea_name)
cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
}
remove_ea_exit:
- if (full_path)
- kfree(full_path);
+ kfree(full_path);
FreeXid(xid);
#endif
return rc;
@@ -132,8 +131,7 @@ int cifs_setxattr(struct dentry * direntry, const char * ea_name,
returns as xattrs */
if(value_size > MAX_EA_VALUE_SIZE) {
cFYI(1,("size of EA value too large"));
- if(full_path)
- kfree(full_path);
+ kfree(full_path);
FreeXid(xid);
return -EOPNOTSUPP;
}
@@ -195,8 +193,7 @@ int cifs_setxattr(struct dentry * direntry, const char * ea_name,
}
set_ea_exit:
- if (full_path)
- kfree(full_path);
+ kfree(full_path);
FreeXid(xid);
#endif
return rc;
@@ -298,8 +295,7 @@ ssize_t cifs_getxattr(struct dentry * direntry, const char * ea_name,
rc = -EOPNOTSUPP;
get_ea_exit:
- if (full_path)
- kfree(full_path);
+ kfree(full_path);
FreeXid(xid);
#endif
return rc;
@@ -345,8 +341,7 @@ ssize_t cifs_listxattr(struct dentry * direntry, char * data, size_t buf_size)
cifs_sb->mnt_cifs_flags &
CIFS_MOUNT_MAP_SPECIAL_CHR);
- if (full_path)
- kfree(full_path);
+ kfree(full_path);
FreeXid(xid);
#endif
return rc;
diff --git a/fs/coda/psdev.c b/fs/coda/psdev.c
index 3d1cce3653b8..6a3df88accfe 100644
--- a/fs/coda/psdev.c
+++ b/fs/coda/psdev.c
@@ -370,8 +370,8 @@ static int init_coda_psdev(void)
}
devfs_mk_dir ("coda");
for (i = 0; i < MAX_CODADEVS; i++) {
- class_device_create(coda_psdev_class, MKDEV(CODA_PSDEV_MAJOR,i),
- NULL, "cfs%d", i);
+ class_device_create(coda_psdev_class, NULL,
+ MKDEV(CODA_PSDEV_MAJOR,i), NULL, "cfs%d", i);
err = devfs_mk_cdev(MKDEV(CODA_PSDEV_MAJOR, i),
S_IFCHR|S_IRUSR|S_IWUSR, "coda/%d", i);
if (err)
diff --git a/fs/compat.c b/fs/compat.c
index a719e158e002..8e71cdbecc7c 100644
--- a/fs/compat.c
+++ b/fs/compat.c
@@ -1490,7 +1490,6 @@ int compat_do_execve(char * filename,
/* execve success */
security_bprm_free(bprm);
acct_update_integrals(current);
- update_mem_hiwater(current);
kfree(bprm);
return retval;
}
diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c
index e28a74203f3b..26300fccb4fc 100644
--- a/fs/compat_ioctl.c
+++ b/fs/compat_ioctl.c
@@ -840,146 +840,6 @@ static int hdio_getgeo(unsigned int fd, unsigned int cmd, unsigned long arg)
return err ? -EFAULT : 0;
}
-struct fb_fix_screeninfo32 {
- char id[16];
- compat_caddr_t smem_start;
- u32 smem_len;
- u32 type;
- u32 type_aux;
- u32 visual;
- u16 xpanstep;
- u16 ypanstep;
- u16 ywrapstep;
- u32 line_length;
- compat_caddr_t mmio_start;
- u32 mmio_len;
- u32 accel;
- u16 reserved[3];
-};
-
-struct fb_cmap32 {
- u32 start;
- u32 len;
- compat_caddr_t red;
- compat_caddr_t green;
- compat_caddr_t blue;
- compat_caddr_t transp;
-};
-
-static int fb_getput_cmap(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- struct fb_cmap_user __user *cmap;
- struct fb_cmap32 __user *cmap32;
- __u32 data;
- int err;
-
- cmap = compat_alloc_user_space(sizeof(*cmap));
- cmap32 = compat_ptr(arg);
-
- if (copy_in_user(&cmap->start, &cmap32->start, 2 * sizeof(__u32)))
- return -EFAULT;
-
- if (get_user(data, &cmap32->red) ||
- put_user(compat_ptr(data), &cmap->red) ||
- get_user(data, &cmap32->green) ||
- put_user(compat_ptr(data), &cmap->green) ||
- get_user(data, &cmap32->blue) ||
- put_user(compat_ptr(data), &cmap->blue) ||
- get_user(data, &cmap32->transp) ||
- put_user(compat_ptr(data), &cmap->transp))
- return -EFAULT;
-
- err = sys_ioctl(fd, cmd, (unsigned long) cmap);
-
- if (!err) {
- if (copy_in_user(&cmap32->start,
- &cmap->start,
- 2 * sizeof(__u32)))
- err = -EFAULT;
- }
- return err;
-}
-
-static int do_fscreeninfo_to_user(struct fb_fix_screeninfo *fix,
- struct fb_fix_screeninfo32 __user *fix32)
-{
- __u32 data;
- int err;
-
- err = copy_to_user(&fix32->id, &fix->id, sizeof(fix32->id));
-
- data = (__u32) (unsigned long) fix->smem_start;
- err |= put_user(data, &fix32->smem_start);
-
- err |= put_user(fix->smem_len, &fix32->smem_len);
- err |= put_user(fix->type, &fix32->type);
- err |= put_user(fix->type_aux, &fix32->type_aux);
- err |= put_user(fix->visual, &fix32->visual);
- err |= put_user(fix->xpanstep, &fix32->xpanstep);
- err |= put_user(fix->ypanstep, &fix32->ypanstep);
- err |= put_user(fix->ywrapstep, &fix32->ywrapstep);
- err |= put_user(fix->line_length, &fix32->line_length);
-
- data = (__u32) (unsigned long) fix->mmio_start;
- err |= put_user(data, &fix32->mmio_start);
-
- err |= put_user(fix->mmio_len, &fix32->mmio_len);
- err |= put_user(fix->accel, &fix32->accel);
- err |= copy_to_user(fix32->reserved, fix->reserved,
- sizeof(fix->reserved));
-
- return err;
-}
-
-static int fb_get_fscreeninfo(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- mm_segment_t old_fs;
- struct fb_fix_screeninfo fix;
- struct fb_fix_screeninfo32 __user *fix32;
- int err;
-
- fix32 = compat_ptr(arg);
-
- old_fs = get_fs();
- set_fs(KERNEL_DS);
- err = sys_ioctl(fd, cmd, (unsigned long) &fix);
- set_fs(old_fs);
-
- if (!err)
- err = do_fscreeninfo_to_user(&fix, fix32);
-
- return err;
-}
-
-static int fb_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- int err;
-
- switch (cmd) {
- case FBIOGET_FSCREENINFO:
- err = fb_get_fscreeninfo(fd,cmd, arg);
- break;
-
- case FBIOGETCMAP:
- case FBIOPUTCMAP:
- err = fb_getput_cmap(fd, cmd, arg);
- break;
-
- default:
- do {
- static int count;
- if (++count <= 20)
- printk("%s: Unknown fb ioctl cmd fd(%d) "
- "cmd(%08x) arg(%08lx)\n",
- __FUNCTION__, fd, cmd, arg);
- } while(0);
- err = -ENOSYS;
- break;
- };
-
- return err;
-}
-
static int hdio_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
{
mm_segment_t old_fs = get_fs();
@@ -2235,7 +2095,8 @@ static int fd_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
if (err)
err = -EFAULT;
-out: if (karg) kfree(karg);
+out:
+ kfree(karg);
return err;
}
@@ -2952,10 +2813,7 @@ HANDLE_IOCTL(BLKGETSIZE, w_long)
HANDLE_IOCTL(0x1260, broken_blkgetsize)
HANDLE_IOCTL(BLKFRAGET, w_long)
HANDLE_IOCTL(BLKSECTGET, w_long)
-HANDLE_IOCTL(FBIOGET_FSCREENINFO, fb_ioctl_trans)
HANDLE_IOCTL(BLKPG, blkpg_ioctl_trans)
-HANDLE_IOCTL(FBIOGETCMAP, fb_ioctl_trans)
-HANDLE_IOCTL(FBIOPUTCMAP, fb_ioctl_trans)
HANDLE_IOCTL(HDIO_GET_KEEPSETTINGS, hdio_ioctl_trans)
HANDLE_IOCTL(HDIO_GET_UNMASKINTR, hdio_ioctl_trans)
HANDLE_IOCTL(HDIO_GET_DMA, hdio_ioctl_trans)
@@ -3046,10 +2904,25 @@ HANDLE_IOCTL(RAW_GETBIND, raw_ioctl)
/* Serial */
HANDLE_IOCTL(TIOCGSERIAL, serial_struct_ioctl)
HANDLE_IOCTL(TIOCSSERIAL, serial_struct_ioctl)
+#ifdef TIOCGLTC
+COMPATIBLE_IOCTL(TIOCGLTC)
+COMPATIBLE_IOCTL(TIOCSLTC)
+#endif
+#ifdef TIOCSTART
+/*
+ * For these two we have defintions in ioctls.h and/or termios.h on
+ * some architectures but no actual implemention. Some applications
+ * like bash call them if they are defined in the headers, so we provide
+ * entries here to avoid syslog message spew.
+ */
+COMPATIBLE_IOCTL(TIOCSTART)
+COMPATIBLE_IOCTL(TIOCSTOP)
+#endif
/* Usbdevfs */
HANDLE_IOCTL(USBDEVFS_CONTROL32, do_usbdevfs_control)
HANDLE_IOCTL(USBDEVFS_BULK32, do_usbdevfs_bulk)
HANDLE_IOCTL(USBDEVFS_DISCSIGNAL32, do_usbdevfs_discsignal)
+COMPATIBLE_IOCTL(USBDEVFS_IOCTL32)
/* i2c */
HANDLE_IOCTL(I2C_FUNCS, w_long)
HANDLE_IOCTL(I2C_RDWR, do_i2c_rdwr_ioctl)
diff --git a/fs/dcache.c b/fs/dcache.c
index fb10386c59be..17e439138681 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -644,7 +644,7 @@ void shrink_dcache_parent(struct dentry * parent)
*
* Prune the dentries that are anonymous
*
- * parsing d_hash list does not hlist_for_each_rcu() as it
+ * parsing d_hash list does not hlist_for_each_entry_rcu() as it
* done under dcache_lock.
*
*/
@@ -689,7 +689,7 @@ void shrink_dcache_anon(struct hlist_head *head)
*
* In this case we return -1 to tell the caller that we baled.
*/
-static int shrink_dcache_memory(int nr, unsigned int gfp_mask)
+static int shrink_dcache_memory(int nr, gfp_t gfp_mask)
{
if (nr) {
if (!(gfp_mask & __GFP_FS))
@@ -1043,15 +1043,13 @@ struct dentry * __d_lookup(struct dentry * parent, struct qstr * name)
struct hlist_head *head = d_hash(parent,hash);
struct dentry *found = NULL;
struct hlist_node *node;
+ struct dentry *dentry;
rcu_read_lock();
- hlist_for_each_rcu(node, head) {
- struct dentry *dentry;
+ hlist_for_each_entry_rcu(dentry, node, head, d_hash) {
struct qstr *qstr;
- dentry = hlist_entry(node, struct dentry, d_hash);
-
if (dentry->d_name.hash != hash)
continue;
if (dentry->d_parent != parent)
@@ -1123,7 +1121,7 @@ int d_validate(struct dentry *dentry, struct dentry *dparent)
spin_lock(&dcache_lock);
base = d_hash(dparent, dentry->d_name.hash);
hlist_for_each(lhp,base) {
- /* hlist_for_each_rcu() not required for d_hash list
+ /* hlist_for_each_entry_rcu() not required for d_hash list
* as it is parsed under dcache_lock
*/
if (dentry == hlist_entry(lhp, struct dentry, d_hash)) {
diff --git a/fs/devfs/base.c b/fs/devfs/base.c
index 8b679b67e5e0..1274422a5384 100644
--- a/fs/devfs/base.c
+++ b/fs/devfs/base.c
@@ -2738,10 +2738,8 @@ static int devfsd_close(struct inode *inode, struct file *file)
entry = fs_info->devfsd_first_event;
fs_info->devfsd_first_event = NULL;
fs_info->devfsd_last_event = NULL;
- if (fs_info->devfsd_info) {
- kfree(fs_info->devfsd_info);
- fs_info->devfsd_info = NULL;
- }
+ kfree(fs_info->devfsd_info);
+ fs_info->devfsd_info = NULL;
spin_unlock(&fs_info->devfsd_buffer_lock);
fs_info->devfsd_pgrp = 0;
fs_info->devfsd_task = NULL;
diff --git a/fs/direct-io.c b/fs/direct-io.c
index 0d06097bc995..3931e7f1e6bf 100644
--- a/fs/direct-io.c
+++ b/fs/direct-io.c
@@ -162,6 +162,7 @@ static int dio_refill_pages(struct dio *dio)
up_read(&current->mm->mmap_sem);
if (ret < 0 && dio->blocks_available && (dio->rw == WRITE)) {
+ struct page *page = ZERO_PAGE(dio->curr_user_address);
/*
* A memory fault, but the filesystem has some outstanding
* mapped blocks. We need to use those blocks up to avoid
@@ -169,7 +170,8 @@ static int dio_refill_pages(struct dio *dio)
*/
if (dio->page_errors == 0)
dio->page_errors = ret;
- dio->pages[0] = ZERO_PAGE(dio->curr_user_address);
+ page_cache_get(page);
+ dio->pages[0] = page;
dio->head = 0;
dio->tail = 1;
ret = 0;
diff --git a/fs/dquot.c b/fs/dquot.c
index b9732335bcdc..05b60283c9c2 100644
--- a/fs/dquot.c
+++ b/fs/dquot.c
@@ -77,6 +77,7 @@
#include <linux/kmod.h>
#include <linux/namei.h>
#include <linux/buffer_head.h>
+#include <linux/quotaops.h>
#include <asm/uaccess.h>
@@ -500,7 +501,7 @@ static void prune_dqcache(int count)
* more memory
*/
-static int shrink_dqcache_memory(int nr, unsigned int gfp_mask)
+static int shrink_dqcache_memory(int nr, gfp_t gfp_mask)
{
if (nr) {
spin_lock(&dq_list_lock);
@@ -662,7 +663,7 @@ static void add_dquot_ref(struct super_block *sb, int type)
restart:
file_list_lock();
list_for_each(p, &sb->s_files) {
- struct file *filp = list_entry(p, struct file, f_list);
+ struct file *filp = list_entry(p, struct file, f_u.fu_list);
struct inode *inode = filp->f_dentry->d_inode;
if (filp->f_mode & FMODE_WRITE && dqinit_needed(inode, type)) {
struct dentry *dentry = dget(filp->f_dentry);
@@ -1320,13 +1321,11 @@ int vfs_quota_off(struct super_block *sb, int type)
int cnt;
struct quota_info *dqopt = sb_dqopt(sb);
struct inode *toputinode[MAXQUOTAS];
- struct vfsmount *toputmnt[MAXQUOTAS];
/* We need to serialize quota_off() for device */
down(&dqopt->dqonoff_sem);
for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
toputinode[cnt] = NULL;
- toputmnt[cnt] = NULL;
if (type != -1 && cnt != type)
continue;
if (!sb_has_quota_enabled(sb, cnt))
@@ -1347,9 +1346,7 @@ int vfs_quota_off(struct super_block *sb, int type)
put_quota_format(dqopt->info[cnt].dqi_format);
toputinode[cnt] = dqopt->files[cnt];
- toputmnt[cnt] = dqopt->mnt[cnt];
dqopt->files[cnt] = NULL;
- dqopt->mnt[cnt] = NULL;
dqopt->info[cnt].dqi_flags = 0;
dqopt->info[cnt].dqi_igrace = 0;
dqopt->info[cnt].dqi_bgrace = 0;
@@ -1357,10 +1354,7 @@ int vfs_quota_off(struct super_block *sb, int type)
}
up(&dqopt->dqonoff_sem);
/* Sync the superblock so that buffers with quota data are written to
- * disk (and so userspace sees correct data afterwards).
- * The reference to vfsmnt we are still holding protects us from
- * umount (we don't have it only when quotas are turned on/off for
- * journal replay but in that case we are guarded by the fs anyway). */
+ * disk (and so userspace sees correct data afterwards). */
if (sb->s_op->sync_fs)
sb->s_op->sync_fs(sb, 1);
sync_blockdev(sb->s_bdev);
@@ -1384,10 +1378,6 @@ int vfs_quota_off(struct super_block *sb, int type)
iput(toputinode[cnt]);
}
up(&dqopt->dqonoff_sem);
- /* We don't hold the reference when we turned on quotas
- * just for the journal replay... */
- if (toputmnt[cnt])
- mntput(toputmnt[cnt]);
}
if (sb->s_bdev)
invalidate_bdev(sb->s_bdev, 0);
@@ -1502,11 +1492,8 @@ int vfs_quota_on(struct super_block *sb, int type, int format_id, char *path)
/* Quota file not on the same filesystem? */
if (nd.mnt->mnt_sb != sb)
error = -EXDEV;
- else {
+ else
error = vfs_quota_on_inode(nd.dentry->d_inode, type, format_id);
- if (!error)
- sb_dqopt(sb)->mnt[type] = mntget(nd.mnt);
- }
out_path:
path_release(&nd);
return error;
diff --git a/fs/exec.c b/fs/exec.c
index a04a575ad433..c466fec5de20 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -48,6 +48,7 @@
#include <linux/syscalls.h>
#include <linux/rmap.h>
#include <linux/acct.h>
+#include <linux/cn_proc.h>
#include <asm/uaccess.h>
#include <asm/mmu_context.h>
@@ -126,8 +127,7 @@ asmlinkage long sys_uselib(const char __user * library)
struct nameidata nd;
int error;
- nd.intent.open.flags = FMODE_READ;
- error = __user_walk(library, LOOKUP_FOLLOW|LOOKUP_OPEN, &nd);
+ error = __user_path_lookup_open(library, LOOKUP_FOLLOW, &nd, FMODE_READ);
if (error)
goto out;
@@ -135,11 +135,11 @@ asmlinkage long sys_uselib(const char __user * library)
if (!S_ISREG(nd.dentry->d_inode->i_mode))
goto exit;
- error = permission(nd.dentry->d_inode, MAY_READ | MAY_EXEC, &nd);
+ error = vfs_permission(&nd, MAY_READ | MAY_EXEC);
if (error)
goto exit;
- file = dentry_open(nd.dentry, nd.mnt, O_RDONLY);
+ file = nameidata_to_filp(&nd, O_RDONLY);
error = PTR_ERR(file);
if (IS_ERR(file))
goto out;
@@ -167,6 +167,7 @@ asmlinkage long sys_uselib(const char __user * library)
out:
return error;
exit:
+ release_open_intent(&nd);
path_release(&nd);
goto out;
}
@@ -309,40 +310,36 @@ void install_arg_page(struct vm_area_struct *vma,
pud_t * pud;
pmd_t * pmd;
pte_t * pte;
+ spinlock_t *ptl;
if (unlikely(anon_vma_prepare(vma)))
- goto out_sig;
+ goto out;
flush_dcache_page(page);
pgd = pgd_offset(mm, address);
-
- spin_lock(&mm->page_table_lock);
pud = pud_alloc(mm, pgd, address);
if (!pud)
goto out;
pmd = pmd_alloc(mm, pud, address);
if (!pmd)
goto out;
- pte = pte_alloc_map(mm, pmd, address);
+ pte = pte_alloc_map_lock(mm, pmd, address, &ptl);
if (!pte)
goto out;
if (!pte_none(*pte)) {
- pte_unmap(pte);
+ pte_unmap_unlock(pte, ptl);
goto out;
}
- inc_mm_counter(mm, rss);
+ inc_mm_counter(mm, anon_rss);
lru_cache_add_active(page);
set_pte_at(mm, address, pte, pte_mkdirty(pte_mkwrite(mk_pte(
page, vma->vm_page_prot))));
page_add_anon_rmap(page, vma, address);
- pte_unmap(pte);
- spin_unlock(&mm->page_table_lock);
+ pte_unmap_unlock(pte, ptl);
/* no need for flush_tlb */
return;
out:
- spin_unlock(&mm->page_table_lock);
-out_sig:
__free_page(page);
force_sig(SIGKILL, current);
}
@@ -490,8 +487,7 @@ struct file *open_exec(const char *name)
int err;
struct file *file;
- nd.intent.open.flags = FMODE_READ;
- err = path_lookup(name, LOOKUP_FOLLOW|LOOKUP_OPEN, &nd);
+ err = path_lookup_open(name, LOOKUP_FOLLOW, &nd, FMODE_READ);
file = ERR_PTR(err);
if (!err) {
@@ -499,12 +495,12 @@ struct file *open_exec(const char *name)
file = ERR_PTR(-EACCES);
if (!(nd.mnt->mnt_flags & MNT_NOEXEC) &&
S_ISREG(inode->i_mode)) {
- int err = permission(inode, MAY_EXEC, &nd);
+ int err = vfs_permission(&nd, MAY_EXEC);
if (!err && !(inode->i_mode & 0111))
err = -EACCES;
file = ERR_PTR(err);
if (!err) {
- file = dentry_open(nd.dentry, nd.mnt, O_RDONLY);
+ file = nameidata_to_filp(&nd, O_RDONLY);
if (!IS_ERR(file)) {
err = deny_write_access(file);
if (err) {
@@ -516,6 +512,7 @@ out:
return file;
}
}
+ release_open_intent(&nd);
path_release(&nd);
}
goto out;
@@ -593,6 +590,7 @@ static inline int de_thread(struct task_struct *tsk)
struct signal_struct *sig = tsk->signal;
struct sighand_struct *newsighand, *oldsighand = tsk->sighand;
spinlock_t *lock = &oldsighand->siglock;
+ struct task_struct *leader = NULL;
int count;
/*
@@ -634,10 +632,9 @@ static inline int de_thread(struct task_struct *tsk)
/*
* Account for the thread group leader hanging around:
*/
- count = 2;
- if (thread_group_leader(current))
- count = 1;
- else {
+ count = 1;
+ if (!thread_group_leader(current)) {
+ count = 2;
/*
* The SIGALRM timer survives the exec, but needs to point
* at us as the new group leader now. We have a race with
@@ -646,8 +643,10 @@ static inline int de_thread(struct task_struct *tsk)
* before we can safely let the old group leader die.
*/
sig->real_timer.data = (unsigned long)current;
+ spin_unlock_irq(lock);
if (del_timer_sync(&sig->real_timer))
add_timer(&sig->real_timer);
+ spin_lock_irq(lock);
}
while (atomic_read(&sig->count) > count) {
sig->group_exit_task = current;
@@ -659,7 +658,6 @@ static inline int de_thread(struct task_struct *tsk)
}
sig->group_exit_task = NULL;
sig->notify_count = 0;
- sig->real_timer.data = (unsigned long)current;
spin_unlock_irq(lock);
/*
@@ -668,7 +666,7 @@ static inline int de_thread(struct task_struct *tsk)
* and to assume its PID:
*/
if (!thread_group_leader(current)) {
- struct task_struct *leader = current->group_leader, *parent;
+ struct task_struct *parent;
struct dentry *proc_dentry1, *proc_dentry2;
unsigned long exit_state, ptrace;
@@ -677,6 +675,7 @@ static inline int de_thread(struct task_struct *tsk)
* It should already be zombie at this point, most
* of the time.
*/
+ leader = current->group_leader;
while (leader->exit_state != EXIT_ZOMBIE)
yield();
@@ -736,7 +735,6 @@ static inline int de_thread(struct task_struct *tsk)
proc_pid_flush(proc_dentry2);
BUG_ON(exit_state != EXIT_ZOMBIE);
- release_task(leader);
}
/*
@@ -746,8 +744,11 @@ static inline int de_thread(struct task_struct *tsk)
sig->flags = 0;
no_thread_group:
- BUG_ON(atomic_read(&sig->count) != 1);
exit_itimers(sig);
+ if (leader)
+ release_task(leader);
+
+ BUG_ON(atomic_read(&sig->count) != 1);
if (atomic_read(&oldsighand->count) == 1) {
/*
@@ -895,7 +896,7 @@ int flush_old_exec(struct linux_binprm * bprm)
flush_thread();
if (bprm->e_uid != current->euid || bprm->e_gid != current->egid ||
- permission(bprm->file->f_dentry->d_inode,MAY_READ, NULL) ||
+ file_permission(bprm->file, MAY_READ) ||
(bprm->interp_flags & BINPRM_FLAGS_ENFORCE_NONDUMP)) {
suid_keys(current);
current->mm->dumpable = suid_dumpable;
@@ -1100,6 +1101,7 @@ int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs)
fput(bprm->file);
bprm->file = NULL;
current->did_exec = 1;
+ proc_exec_connector(current);
return retval;
}
read_lock(&binfmt_lock);
@@ -1207,7 +1209,6 @@ int do_execve(char * filename,
/* execve success */
security_bprm_free(bprm);
acct_update_integrals(current);
- update_mem_hiwater(current);
kfree(bprm);
return retval;
}
@@ -1422,19 +1423,16 @@ static void zap_threads (struct mm_struct *mm)
static void coredump_wait(struct mm_struct *mm)
{
DECLARE_COMPLETION(startup_done);
+ int core_waiters;
- mm->core_waiters++; /* let other threads block */
mm->core_startup_done = &startup_done;
- /* give other threads a chance to run: */
- yield();
-
zap_threads(mm);
- if (--mm->core_waiters) {
- up_write(&mm->mmap_sem);
+ core_waiters = mm->core_waiters;
+ up_write(&mm->mmap_sem);
+
+ if (core_waiters)
wait_for_completion(&startup_done);
- } else
- up_write(&mm->mmap_sem);
BUG_ON(mm->core_waiters);
}
@@ -1468,11 +1466,21 @@ int do_coredump(long signr, int exit_code, struct pt_regs * regs)
current->fsuid = 0; /* Dump root private */
}
mm->dumpable = 0;
- init_completion(&mm->core_done);
+
+ retval = -EAGAIN;
spin_lock_irq(&current->sighand->siglock);
- current->signal->flags = SIGNAL_GROUP_EXIT;
- current->signal->group_exit_code = exit_code;
+ if (!(current->signal->flags & SIGNAL_GROUP_EXIT)) {
+ current->signal->flags = SIGNAL_GROUP_EXIT;
+ current->signal->group_exit_code = exit_code;
+ retval = 0;
+ }
spin_unlock_irq(&current->sighand->siglock);
+ if (retval) {
+ up_write(&mm->mmap_sem);
+ goto fail;
+ }
+
+ init_completion(&mm->core_done);
coredump_wait(mm);
/*
@@ -1507,7 +1515,7 @@ int do_coredump(long signr, int exit_code, struct pt_regs * regs)
goto close_fail;
if (!file->f_op->write)
goto close_fail;
- if (do_truncate(file->f_dentry, 0) != 0)
+ if (do_truncate(file->f_dentry, 0, file) != 0)
goto close_fail;
retval = binfmt->core_dump(signr, regs, file);
diff --git a/fs/ext2/CHANGES b/fs/ext2/CHANGES
deleted file mode 100644
index aa5aaf0e5911..000000000000
--- a/fs/ext2/CHANGES
+++ /dev/null
@@ -1,157 +0,0 @@
-Changes from version 0.5a to version 0.5b
-=========================================
- - Now that we have sysctl(), the immutable flag cannot be changed when
- the system is running at security level > 0.
- - Some cleanups in the code.
- - More consistency checks on directories.
- - The ext2.diff patch from Tom May <ftom@netcom.com> has been
- integrated. This patch replaces expensive "/" and "%" with
- cheap ">>" and "&" where possible.
-
-Changes from version 0.5 to version 0.5a
-========================================
- - Zero the partial block following the end of the file when a file
- is truncated.
- - Dates updated in the copyright.
- - More checks when the filesystem is mounted: the count of blocks,
- fragments, and inodes per group is checked against the block size.
- - The buffers used by the error routines are now static variables, to
- avoid using space on the kernel stack, as requested by Linus.
- - Some cleanups in the error messages (some versions of syslog contain
- a bug which truncates an error message if it contains '\n').
- - Check that no data can be written to a file past the 2GB limit.
- - The famous readdir() bug has been fixed by Stephen Tweedie.
- - Added a revision level in the superblock.
- - Full support for O_SYNC flag of the open system call.
- - New mount options: `resuid=#uid' and `resgid=#gid'. `resuid' causes
- ext2fs to consider user #uid like root for the reserved blocks.
- `resgid' acts the same way with group #gid. New fields in the
- superblock contain default values for resuid and resgid and can
- be modified by tune2fs.
- Idea comes from Rene Cougnenc <cougnenc@renux.frmug.fr.net>.
- - New mount options: `bsddf' and `minixdf'. `bsddf' causes ext2fs
- to remove the blocks used for FS structures from the total block
- count in statfs. With `minixdf', ext2fs mimics Minix behavior
- in statfs (i.e. it returns the total number of blocks on the
- partition). This is intended to make bde happy :-)
- - New file attributes:
- - Immutable files cannot be modified. Data cannot be written to
- these files. They cannot be removed, renamed and new links cannot
- be created. Even root cannot modify the files. He has to remove
- the immutable attribute first.
- - Append-only files: can only be written in append-mode when writing.
- They cannot be removed, renamed and new links cannot be created.
- Note: files may only be added to an append-only directory.
- - No-dump files: the attribute is not used by the kernel. My port
- of dump uses it to avoid backing up files which are not important.
- - New check in ext2_check_dir_entry: the inode number is checked.
- - Support for big file systems: the copy of the FS descriptor is now
- dynamically allocated (previous versions used a fixed size array).
- This allows to mount 2GB+ FS.
- - Reorganization of the ext2_inode structure to allow other operating
- systems to create specific fields if they use ext2fs as their native
- file system. Currently, ext2fs is only implemented in Linux but
- will soon be part of Gnu Hurd and of Masix.
-
-Changes from version 0.4b to version 0.5
-========================================
- - New superblock fields: s_lastcheck and s_checkinterval added
- by Uwe Ohse <uwe@tirka.gun.de> to implement timedependent checks
- of the file system
- - Real random numbers for secure rm added by Pierre del Perugia
- <delperug@gla.ecoledoc.ibp.fr>
- - The mount warnings related to the state of a fs are not printed
- if the fs is mounted read-only, idea by Nick Holloway
- <alfie@dcs.warwick.ac.uk>
-
-Changes from version 0.4a to version 0.4b
-=========================================
- - Copyrights changed to include the name of my laboratory.
- - Clean up of balloc.c and ialloc.c.
- - More consistency checks.
- - Block preallocation added by Stephen Tweedie.
- - Direct reads of directories disallowed.
- - Readahead implemented in readdir by Stephen Tweedie.
- - Bugs in block and inodes allocation fixed.
- - Readahead implemented in ext2_find_entry by Chip Salzenberg.
- - New mount options:
- `check=none|normal|strict'
- `debug'
- `errors=continue|remount-ro|panic'
- `grpid', `bsdgroups'
- `nocheck'
- `nogrpid', `sysvgroups'
- - truncate() now tries to deallocate contiguous blocks in a single call
- to ext2_free_blocks().
- - lots of cosmetic changes.
-
-Changes from version 0.4 to version 0.4a
-========================================
- - the `sync' option support is now complete. Version 0.4 was not
- supporting it when truncating a file. I have tested the synchronous
- writes and they work but they make the system very slow :-( I have
- to work again on this to make it faster.
- - when detecting an error on a mounted filesystem, version 0.4 used
- to try to write a flag in the super block even if the filesystem had
- been mounted read-only. This is fixed.
- - the `sb=#' option now causes the kernel code to use the filesystem
- descriptors located at block #+1. Version 0.4 used the superblock
- backup located at block # but used the main copy of the descriptors.
- - a new file attribute `S' is supported. This attribute causes
- synchronous writes but is applied to a file not to the entire file
- system (thanks to Michael Kraehe <kraehe@bakunin.north.de> for
- suggesting it).
- - the directory cache is inhibited by default. The cache management
- code seems to be buggy and I have to look at it carefully before
- using it again.
- - deleting a file with the `s' attribute (secure deletion) causes its
- blocks to be overwritten with random values not with zeros (thanks to
- Michael A. Griffith <grif@cs.ucr.edu> for suggesting it).
- - lots of cosmetic changes have been made.
-
-Changes from version 0.3 to version 0.4
-=======================================
- - Three new mount options are supported: `check', `sync' and `sb=#'.
- `check' tells the kernel code to make more consistency checks
- when the file system is mounted. Currently, the kernel code checks
- that the blocks and inodes bitmaps are consistent with the free
- blocks and inodes counts. More checks will be added in future
- releases.
- `sync' tells the kernel code to use synchronous writes when updating
- an inode, a bitmap, a directory entry or an indirect block. This
- can make the file system much slower but can be a big win for files
- recovery in case of a crash (and we can now say to the BSD folks
- that Linux also supports synchronous updates :-).
- `sb=#' tells the kernel code to use an alternate super block instead
- of its master copy. `#' is the number of the block (counted in
- 1024 bytes blocks) which contains the alternate super block.
- An ext2 file system typically contains backups of the super block
- at blocks 8193, 16385, and so on.
- - I have change the meaning of the valid flag used by e2fsck. it
- now contains the state of the file system. If the kernel code
- detects an inconsistency while the file system is mounted, it flags
- it as erroneous and e2fsck will detect that on next run.
- - The super block now contains a mount counter. This counter is
- incremented each time the file system is mounted read/write. When
- this counter becomes bigger than a maximal mount counts (also stored
- in the super block), e2fsck checks the file system, even if it had
- been unmounted cleanly, and resets this counter to 0.
- - File attributes are now supported. One can associate a set of
- attributes to a file. Three attributes are defined:
- `c': the file is marked for automatic compression,
- `s': the file is marked for secure deletion: when the file is
- deleted, its blocks are zeroed and written back to the disk,
- `u': the file is marked for undeletion: when the file is deleted,
- its contents are saved to allow a future undeletion.
- Currently, only the `s' attribute is implemented in the kernel
- code. Support for the other attributes will be added in a future
- release.
- - a few bugs related to times updates have been fixed by Bruce
- Evans and me.
- - a bug related to the links count of deleted inodes has been fixed.
- Previous versions used to keep the links count set to 1 when a file
- was deleted. The new version now sets links_count to 0 when deleting
- the last link.
- - a race condition when deallocating an inode has been fixed by
- Stephen Tweedie.
-
diff --git a/fs/ext2/acl.c b/fs/ext2/acl.c
index 213148c36ebe..6af2f4130290 100644
--- a/fs/ext2/acl.c
+++ b/fs/ext2/acl.c
@@ -194,8 +194,7 @@ ext2_get_acl(struct inode *inode, int type)
acl = NULL;
else
acl = ERR_PTR(retval);
- if (value)
- kfree(value);
+ kfree(value);
if (!IS_ERR(acl)) {
switch(type) {
@@ -262,8 +261,7 @@ ext2_set_acl(struct inode *inode, int type, struct posix_acl *acl)
error = ext2_xattr_set(inode, name_index, "", value, size, 0);
- if (value)
- kfree(value);
+ kfree(value);
if (!error) {
switch(type) {
case ACL_TYPE_ACCESS:
diff --git a/fs/ext2/balloc.c b/fs/ext2/balloc.c
index 6591abef64d0..bb6908066494 100644
--- a/fs/ext2/balloc.c
+++ b/fs/ext2/balloc.c
@@ -624,76 +624,3 @@ unsigned long ext2_bg_num_gdb(struct super_block *sb, int group)
return EXT2_SB(sb)->s_gdb_count;
}
-#ifdef CONFIG_EXT2_CHECK
-/* Called at mount-time, super-block is locked */
-void ext2_check_blocks_bitmap (struct super_block * sb)
-{
- struct buffer_head *bitmap_bh = NULL;
- struct ext2_super_block * es;
- unsigned long desc_count, bitmap_count, x, j;
- unsigned long desc_blocks;
- struct ext2_group_desc * desc;
- int i;
-
- es = EXT2_SB(sb)->s_es;
- desc_count = 0;
- bitmap_count = 0;
- desc = NULL;
- for (i = 0; i < EXT2_SB(sb)->s_groups_count; i++) {
- desc = ext2_get_group_desc (sb, i, NULL);
- if (!desc)
- continue;
- desc_count += le16_to_cpu(desc->bg_free_blocks_count);
- brelse(bitmap_bh);
- bitmap_bh = read_block_bitmap(sb, i);
- if (!bitmap_bh)
- continue;
-
- if (ext2_bg_has_super(sb, i) &&
- !ext2_test_bit(0, bitmap_bh->b_data))
- ext2_error(sb, __FUNCTION__,
- "Superblock in group %d is marked free", i);
-
- desc_blocks = ext2_bg_num_gdb(sb, i);
- for (j = 0; j < desc_blocks; j++)
- if (!ext2_test_bit(j + 1, bitmap_bh->b_data))
- ext2_error(sb, __FUNCTION__,
- "Descriptor block #%ld in group "
- "%d is marked free", j, i);
-
- if (!block_in_use(le32_to_cpu(desc->bg_block_bitmap),
- sb, bitmap_bh->b_data))
- ext2_error(sb, "ext2_check_blocks_bitmap",
- "Block bitmap for group %d is marked free",
- i);
-
- if (!block_in_use(le32_to_cpu(desc->bg_inode_bitmap),
- sb, bitmap_bh->b_data))
- ext2_error(sb, "ext2_check_blocks_bitmap",
- "Inode bitmap for group %d is marked free",
- i);
-
- for (j = 0; j < EXT2_SB(sb)->s_itb_per_group; j++)
- if (!block_in_use(le32_to_cpu(desc->bg_inode_table) + j,
- sb, bitmap_bh->b_data))
- ext2_error (sb, "ext2_check_blocks_bitmap",
- "Block #%ld of the inode table in "
- "group %d is marked free", j, i);
-
- x = ext2_count_free(bitmap_bh, sb->s_blocksize);
- if (le16_to_cpu(desc->bg_free_blocks_count) != x)
- ext2_error (sb, "ext2_check_blocks_bitmap",
- "Wrong free blocks count for group %d, "
- "stored = %d, counted = %lu", i,
- le16_to_cpu(desc->bg_free_blocks_count), x);
- bitmap_count += x;
- }
- if (le32_to_cpu(es->s_free_blocks_count) != bitmap_count)
- ext2_error (sb, "ext2_check_blocks_bitmap",
- "Wrong free blocks count in super block, "
- "stored = %lu, counted = %lu",
- (unsigned long)le32_to_cpu(es->s_free_blocks_count),
- bitmap_count);
- brelse(bitmap_bh);
-}
-#endif
diff --git a/fs/ext2/ialloc.c b/fs/ext2/ialloc.c
index e2d6208633a7..74714af4ae69 100644
--- a/fs/ext2/ialloc.c
+++ b/fs/ext2/ialloc.c
@@ -700,43 +700,3 @@ unsigned long ext2_count_dirs (struct super_block * sb)
return count;
}
-#ifdef CONFIG_EXT2_CHECK
-/* Called at mount-time, super-block is locked */
-void ext2_check_inodes_bitmap (struct super_block * sb)
-{
- struct ext2_super_block * es = EXT2_SB(sb)->s_es;
- unsigned long desc_count = 0, bitmap_count = 0;
- struct buffer_head *bitmap_bh = NULL;
- int i;
-
- for (i = 0; i < EXT2_SB(sb)->s_groups_count; i++) {
- struct ext2_group_desc *desc;
- unsigned x;
-
- desc = ext2_get_group_desc(sb, i, NULL);
- if (!desc)
- continue;
- desc_count += le16_to_cpu(desc->bg_free_inodes_count);
- brelse(bitmap_bh);
- bitmap_bh = read_inode_bitmap(sb, i);
- if (!bitmap_bh)
- continue;
-
- x = ext2_count_free(bitmap_bh, EXT2_INODES_PER_GROUP(sb) / 8);
- if (le16_to_cpu(desc->bg_free_inodes_count) != x)
- ext2_error (sb, "ext2_check_inodes_bitmap",
- "Wrong free inodes count in group %d, "
- "stored = %d, counted = %lu", i,
- le16_to_cpu(desc->bg_free_inodes_count), x);
- bitmap_count += x;
- }
- brelse(bitmap_bh);
- if (percpu_counter_read(&EXT2_SB(sb)->s_freeinodes_counter) !=
- bitmap_count)
- ext2_error(sb, "ext2_check_inodes_bitmap",
- "Wrong free inodes count in super block, "
- "stored = %lu, counted = %lu",
- (unsigned long)le32_to_cpu(es->s_free_inodes_count),
- bitmap_count);
-}
-#endif
diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c
index fdba4d1d3c60..e7d3f0522d01 100644
--- a/fs/ext2/inode.c
+++ b/fs/ext2/inode.c
@@ -440,6 +440,10 @@ static int ext2_alloc_branch(struct inode *inode,
* the pointer to new one, then send parent to disk.
*/
bh = sb_getblk(inode->i_sb, parent);
+ if (!bh) {
+ err = -EIO;
+ break;
+ }
lock_buffer(bh);
memset(bh->b_data, 0, blocksize);
branch[n].bh = bh;
diff --git a/fs/ext2/super.c b/fs/ext2/super.c
index 3c0c7c6a5b44..e4ed4b31a433 100644
--- a/fs/ext2/super.c
+++ b/fs/ext2/super.c
@@ -281,7 +281,7 @@ static unsigned long get_sb_block(void **data)
enum {
Opt_bsd_df, Opt_minix_df, Opt_grpid, Opt_nogrpid,
Opt_resgid, Opt_resuid, Opt_sb, Opt_err_cont, Opt_err_panic,
- Opt_err_ro, Opt_nouid32, Opt_check, Opt_nocheck, Opt_debug,
+ Opt_err_ro, Opt_nouid32, Opt_nocheck, Opt_debug,
Opt_oldalloc, Opt_orlov, Opt_nobh, Opt_user_xattr, Opt_nouser_xattr,
Opt_acl, Opt_noacl, Opt_xip, Opt_ignore, Opt_err, Opt_quota,
Opt_usrquota, Opt_grpquota
@@ -303,7 +303,6 @@ static match_table_t tokens = {
{Opt_nouid32, "nouid32"},
{Opt_nocheck, "check=none"},
{Opt_nocheck, "nocheck"},
- {Opt_check, "check"},
{Opt_debug, "debug"},
{Opt_oldalloc, "oldalloc"},
{Opt_orlov, "orlov"},
@@ -376,13 +375,6 @@ static int parse_options (char * options,
case Opt_nouid32:
set_opt (sbi->s_mount_opt, NO_UID32);
break;
- case Opt_check:
-#ifdef CONFIG_EXT2_CHECK
- set_opt (sbi->s_mount_opt, CHECK);
-#else
- printk("EXT2 Check option not supported\n");
-#endif
- break;
case Opt_nocheck:
clear_opt (sbi->s_mount_opt, CHECK);
break;
@@ -503,12 +495,6 @@ static int ext2_setup_super (struct super_block * sb,
EXT2_BLOCKS_PER_GROUP(sb),
EXT2_INODES_PER_GROUP(sb),
sbi->s_mount_opt);
-#ifdef CONFIG_EXT2_CHECK
- if (test_opt (sb, CHECK)) {
- ext2_check_blocks_bitmap (sb);
- ext2_check_inodes_bitmap (sb);
- }
-#endif
return res;
}
diff --git a/fs/ext3/balloc.c b/fs/ext3/balloc.c
index 0213db4911a2..ae1148c24c53 100644
--- a/fs/ext3/balloc.c
+++ b/fs/ext3/balloc.c
@@ -20,6 +20,8 @@
#include <linux/quotaops.h>
#include <linux/buffer_head.h>
+#include "bitmap.h"
+
/*
* balloc.c contains the blocks allocation and deallocation routines
*/
@@ -1010,7 +1012,7 @@ retry:
* allocation within the reservation window.
*
* This will avoid keeping on searching the reservation list again and
- * again when someboday is looking for a free block (without
+ * again when somebody is looking for a free block (without
* reservation), and there are lots of free blocks, but they are all
* being reserved.
*
@@ -1416,12 +1418,12 @@ unsigned long ext3_count_free_blocks(struct super_block *sb)
unsigned long bitmap_count, x;
struct buffer_head *bitmap_bh = NULL;
- lock_super(sb);
es = EXT3_SB(sb)->s_es;
desc_count = 0;
bitmap_count = 0;
gdp = NULL;
+ smp_rmb();
for (i = 0; i < ngroups; i++) {
gdp = ext3_get_group_desc(sb, i, NULL);
if (!gdp)
@@ -1440,7 +1442,6 @@ unsigned long ext3_count_free_blocks(struct super_block *sb)
brelse(bitmap_bh);
printk("ext3_count_free_blocks: stored = %u, computed = %lu, %lu\n",
le32_to_cpu(es->s_free_blocks_count), desc_count, bitmap_count);
- unlock_super(sb);
return bitmap_count;
#else
desc_count = 0;
@@ -1516,76 +1517,3 @@ unsigned long ext3_bg_num_gdb(struct super_block *sb, int group)
return EXT3_SB(sb)->s_gdb_count;
}
-#ifdef CONFIG_EXT3_CHECK
-/* Called at mount-time, super-block is locked */
-void ext3_check_blocks_bitmap (struct super_block * sb)
-{
- struct ext3_super_block *es;
- unsigned long desc_count, bitmap_count, x, j;
- unsigned long desc_blocks;
- struct buffer_head *bitmap_bh = NULL;
- struct ext3_group_desc *gdp;
- int i;
-
- es = EXT3_SB(sb)->s_es;
- desc_count = 0;
- bitmap_count = 0;
- gdp = NULL;
- for (i = 0; i < EXT3_SB(sb)->s_groups_count; i++) {
- gdp = ext3_get_group_desc (sb, i, NULL);
- if (!gdp)
- continue;
- desc_count += le16_to_cpu(gdp->bg_free_blocks_count);
- brelse(bitmap_bh);
- bitmap_bh = read_block_bitmap(sb, i);
- if (bitmap_bh == NULL)
- continue;
-
- if (ext3_bg_has_super(sb, i) &&
- !ext3_test_bit(0, bitmap_bh->b_data))
- ext3_error(sb, __FUNCTION__,
- "Superblock in group %d is marked free", i);
-
- desc_blocks = ext3_bg_num_gdb(sb, i);
- for (j = 0; j < desc_blocks; j++)
- if (!ext3_test_bit(j + 1, bitmap_bh->b_data))
- ext3_error(sb, __FUNCTION__,
- "Descriptor block #%ld in group "
- "%d is marked free", j, i);
-
- if (!block_in_use (le32_to_cpu(gdp->bg_block_bitmap),
- sb, bitmap_bh->b_data))
- ext3_error (sb, "ext3_check_blocks_bitmap",
- "Block bitmap for group %d is marked free",
- i);
-
- if (!block_in_use (le32_to_cpu(gdp->bg_inode_bitmap),
- sb, bitmap_bh->b_data))
- ext3_error (sb, "ext3_check_blocks_bitmap",
- "Inode bitmap for group %d is marked free",
- i);
-
- for (j = 0; j < EXT3_SB(sb)->s_itb_per_group; j++)
- if (!block_in_use (le32_to_cpu(gdp->bg_inode_table) + j,
- sb, bitmap_bh->b_data))
- ext3_error (sb, "ext3_check_blocks_bitmap",
- "Block #%d of the inode table in "
- "group %d is marked free", j, i);
-
- x = ext3_count_free(bitmap_bh, sb->s_blocksize);
- if (le16_to_cpu(gdp->bg_free_blocks_count) != x)
- ext3_error (sb, "ext3_check_blocks_bitmap",
- "Wrong free blocks count for group %d, "
- "stored = %d, counted = %lu", i,
- le16_to_cpu(gdp->bg_free_blocks_count), x);
- bitmap_count += x;
- }
- brelse(bitmap_bh);
- if (le32_to_cpu(es->s_free_blocks_count) != bitmap_count)
- ext3_error (sb, "ext3_check_blocks_bitmap",
- "Wrong free blocks count in super block, "
- "stored = %lu, counted = %lu",
- (unsigned long)le32_to_cpu(es->s_free_blocks_count),
- bitmap_count);
-}
-#endif
diff --git a/fs/ext3/bitmap.c b/fs/ext3/bitmap.c
index 6c419b9ab0e8..5b4ba3e246e6 100644
--- a/fs/ext3/bitmap.c
+++ b/fs/ext3/bitmap.c
@@ -8,7 +8,7 @@
*/
#include <linux/buffer_head.h>
-
+#include "bitmap.h"
static int nibblemap[] = {4, 3, 3, 2, 3, 2, 2, 1, 3, 2, 2, 1, 2, 1, 1, 0};
diff --git a/fs/ext3/bitmap.h b/fs/ext3/bitmap.h
new file mode 100644
index 000000000000..6ee503a6bb4e
--- /dev/null
+++ b/fs/ext3/bitmap.h
@@ -0,0 +1,8 @@
+/* linux/fs/ext3/bitmap.c
+ *
+ * Copyright (C) 2005 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+*/
+
+extern unsigned long ext3_count_free (struct buffer_head *, unsigned int );
diff --git a/fs/ext3/ialloc.c b/fs/ext3/ialloc.c
index 6549945f9ac1..9e4a24376210 100644
--- a/fs/ext3/ialloc.c
+++ b/fs/ext3/ialloc.c
@@ -26,6 +26,7 @@
#include <asm/byteorder.h>
+#include "bitmap.h"
#include "xattr.h"
#include "acl.h"
@@ -704,7 +705,6 @@ unsigned long ext3_count_free_inodes (struct super_block * sb)
unsigned long bitmap_count, x;
struct buffer_head *bitmap_bh = NULL;
- lock_super (sb);
es = EXT3_SB(sb)->s_es;
desc_count = 0;
bitmap_count = 0;
@@ -727,7 +727,6 @@ unsigned long ext3_count_free_inodes (struct super_block * sb)
brelse(bitmap_bh);
printk("ext3_count_free_inodes: stored = %u, computed = %lu, %lu\n",
le32_to_cpu(es->s_free_inodes_count), desc_count, bitmap_count);
- unlock_super(sb);
return desc_count;
#else
desc_count = 0;
@@ -757,44 +756,3 @@ unsigned long ext3_count_dirs (struct super_block * sb)
return count;
}
-#ifdef CONFIG_EXT3_CHECK
-/* Called at mount-time, super-block is locked */
-void ext3_check_inodes_bitmap (struct super_block * sb)
-{
- struct ext3_super_block * es;
- unsigned long desc_count, bitmap_count, x;
- struct buffer_head *bitmap_bh = NULL;
- struct ext3_group_desc * gdp;
- int i;
-
- es = EXT3_SB(sb)->s_es;
- desc_count = 0;
- bitmap_count = 0;
- gdp = NULL;
- for (i = 0; i < EXT3_SB(sb)->s_groups_count; i++) {
- gdp = ext3_get_group_desc (sb, i, NULL);
- if (!gdp)
- continue;
- desc_count += le16_to_cpu(gdp->bg_free_inodes_count);
- brelse(bitmap_bh);
- bitmap_bh = read_inode_bitmap(sb, i);
- if (!bitmap_bh)
- continue;
-
- x = ext3_count_free(bitmap_bh, EXT3_INODES_PER_GROUP(sb) / 8);
- if (le16_to_cpu(gdp->bg_free_inodes_count) != x)
- ext3_error (sb, "ext3_check_inodes_bitmap",
- "Wrong free inodes count in group %d, "
- "stored = %d, counted = %lu", i,
- le16_to_cpu(gdp->bg_free_inodes_count), x);
- bitmap_count += x;
- }
- brelse(bitmap_bh);
- if (le32_to_cpu(es->s_free_inodes_count) != bitmap_count)
- ext3_error (sb, "ext3_check_inodes_bitmap",
- "Wrong free inodes count in super block, "
- "stored = %lu, counted = %lu",
- (unsigned long)le32_to_cpu(es->s_free_inodes_count),
- bitmap_count);
-}
-#endif
diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c
index b5177c90d6f1..5d9b00e28837 100644
--- a/fs/ext3/inode.c
+++ b/fs/ext3/inode.c
@@ -491,7 +491,7 @@ static unsigned long ext3_find_goal(struct inode *inode, long block,
* the same format as ext3_get_branch() would do. We are calling it after
* we had read the existing part of chain and partial points to the last
* triple of that (one with zero ->key). Upon the exit we have the same
- * picture as after the successful ext3_get_block(), excpet that in one
+ * picture as after the successful ext3_get_block(), except that in one
* place chain is disconnected - *branch->p is still zero (we did not
* set the last link), but branch->key contains the number that should
* be placed into *branch->p to fill that gap.
@@ -523,7 +523,6 @@ static int ext3_alloc_branch(handle_t *handle, struct inode *inode,
if (!nr)
break;
branch[n].key = cpu_to_le32(nr);
- keys = n+1;
/*
* Get buffer_head for parent block, zero it out
@@ -531,6 +530,9 @@ static int ext3_alloc_branch(handle_t *handle, struct inode *inode,
* parent to disk.
*/
bh = sb_getblk(inode->i_sb, parent);
+ if (!bh)
+ break;
+ keys = n+1;
branch[n].bh = bh;
lock_buffer(bh);
BUFFER_TRACE(bh, "call get_create_access");
@@ -864,6 +866,10 @@ struct buffer_head *ext3_getblk(handle_t *handle, struct inode * inode,
if (!*errp && buffer_mapped(&dummy)) {
struct buffer_head *bh;
bh = sb_getblk(inode->i_sb, dummy.b_blocknr);
+ if (!bh) {
+ *errp = -EIO;
+ goto err;
+ }
if (buffer_new(&dummy)) {
J_ASSERT(create != 0);
J_ASSERT(handle != 0);
@@ -896,6 +902,7 @@ struct buffer_head *ext3_getblk(handle_t *handle, struct inode * inode,
}
return bh;
}
+err:
return NULL;
}
@@ -1434,7 +1441,7 @@ static int ext3_invalidatepage(struct page *page, unsigned long offset)
return journal_invalidatepage(journal, page, offset);
}
-static int ext3_releasepage(struct page *page, int wait)
+static int ext3_releasepage(struct page *page, gfp_t wait)
{
journal_t *journal = EXT3_JOURNAL(page->mapping->host);
diff --git a/fs/ext3/namei.c b/fs/ext3/namei.c
index 50378d8ff84b..b3c690a3b54a 100644
--- a/fs/ext3/namei.c
+++ b/fs/ext3/namei.c
@@ -36,6 +36,8 @@
#include <linux/quotaops.h>
#include <linux/buffer_head.h>
#include <linux/smp_lock.h>
+
+#include "namei.h"
#include "xattr.h"
#include "acl.h"
diff --git a/fs/ext3/namei.h b/fs/ext3/namei.h
new file mode 100644
index 000000000000..f2ce2b0065c9
--- /dev/null
+++ b/fs/ext3/namei.h
@@ -0,0 +1,8 @@
+/* linux/fs/ext3/namei.h
+ *
+ * Copyright (C) 2005 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+*/
+
+extern struct dentry *ext3_get_parent(struct dentry *child);
diff --git a/fs/ext3/resize.c b/fs/ext3/resize.c
index 57f79106267d..1be78b4b4de9 100644
--- a/fs/ext3/resize.c
+++ b/fs/ext3/resize.c
@@ -118,6 +118,8 @@ static struct buffer_head *bclean(handle_t *handle, struct super_block *sb,
int err;
bh = sb_getblk(sb, blk);
+ if (!bh)
+ return ERR_PTR(-EIO);
if ((err = ext3_journal_get_write_access(handle, bh))) {
brelse(bh);
bh = ERR_PTR(err);
@@ -202,6 +204,10 @@ static int setup_new_group_blocks(struct super_block *sb,
ext3_debug("update backup group %#04lx (+%d)\n", block, bit);
gdb = sb_getblk(sb, block);
+ if (!gdb) {
+ err = -EIO;
+ goto exit_bh;
+ }
if ((err = ext3_journal_get_write_access(handle, gdb))) {
brelse(gdb);
goto exit_bh;
@@ -643,6 +649,10 @@ static void update_backups(struct super_block *sb,
break;
bh = sb_getblk(sb, group * bpg + blk_off);
+ if (!bh) {
+ err = -EIO;
+ break;
+ }
ext3_debug("update metadata backup %#04lx\n",
(unsigned long)bh->b_blocknr);
if ((err = ext3_journal_get_write_access(handle, bh)))
diff --git a/fs/ext3/super.c b/fs/ext3/super.c
index 9e24ceb019fe..4e6730622d90 100644
--- a/fs/ext3/super.c
+++ b/fs/ext3/super.c
@@ -36,9 +36,12 @@
#include <linux/namei.h>
#include <linux/quotaops.h>
#include <linux/seq_file.h>
+
#include <asm/uaccess.h>
+
#include "xattr.h"
#include "acl.h"
+#include "namei.h"
static int ext3_load_journal(struct super_block *, struct ext3_super_block *);
static int ext3_create_journal(struct super_block *, struct ext3_super_block *,
@@ -510,19 +513,11 @@ static void ext3_clear_inode(struct inode *inode)
kfree(rsv);
}
-static int ext3_show_options(struct seq_file *seq, struct vfsmount *vfs)
+static inline void ext3_show_quota_options(struct seq_file *seq, struct super_block *sb)
{
- struct super_block *sb = vfs->mnt_sb;
+#if defined(CONFIG_QUOTA)
struct ext3_sb_info *sbi = EXT3_SB(sb);
- if (test_opt(sb, DATA_FLAGS) == EXT3_MOUNT_JOURNAL_DATA)
- seq_puts(seq, ",data=journal");
- else if (test_opt(sb, DATA_FLAGS) == EXT3_MOUNT_ORDERED_DATA)
- seq_puts(seq, ",data=ordered");
- else if (test_opt(sb, DATA_FLAGS) == EXT3_MOUNT_WRITEBACK_DATA)
- seq_puts(seq, ",data=writeback");
-
-#if defined(CONFIG_QUOTA)
if (sbi->s_jquota_fmt)
seq_printf(seq, ",jqfmt=%s",
(sbi->s_jquota_fmt == QFMT_VFS_OLD) ? "vfsold": "vfsv0");
@@ -539,6 +534,20 @@ static int ext3_show_options(struct seq_file *seq, struct vfsmount *vfs)
if (sbi->s_mount_opt & EXT3_MOUNT_GRPQUOTA)
seq_puts(seq, ",grpquota");
#endif
+}
+
+static int ext3_show_options(struct seq_file *seq, struct vfsmount *vfs)
+{
+ struct super_block *sb = vfs->mnt_sb;
+
+ if (test_opt(sb, DATA_FLAGS) == EXT3_MOUNT_JOURNAL_DATA)
+ seq_puts(seq, ",data=journal");
+ else if (test_opt(sb, DATA_FLAGS) == EXT3_MOUNT_ORDERED_DATA)
+ seq_puts(seq, ",data=ordered");
+ else if (test_opt(sb, DATA_FLAGS) == EXT3_MOUNT_WRITEBACK_DATA)
+ seq_puts(seq, ",data=writeback");
+
+ ext3_show_quota_options(seq, sb);
return 0;
}
@@ -609,7 +618,6 @@ static struct super_operations ext3_sops = {
#endif
};
-struct dentry *ext3_get_parent(struct dentry *child);
static struct export_operations ext3_export_ops = {
.get_parent = ext3_get_parent,
};
@@ -617,7 +625,7 @@ static struct export_operations ext3_export_ops = {
enum {
Opt_bsd_df, Opt_minix_df, Opt_grpid, Opt_nogrpid,
Opt_resgid, Opt_resuid, Opt_sb, Opt_err_cont, Opt_err_panic, Opt_err_ro,
- Opt_nouid32, Opt_check, Opt_nocheck, Opt_debug, Opt_oldalloc, Opt_orlov,
+ Opt_nouid32, Opt_nocheck, Opt_debug, Opt_oldalloc, Opt_orlov,
Opt_user_xattr, Opt_nouser_xattr, Opt_acl, Opt_noacl,
Opt_reservation, Opt_noreservation, Opt_noload, Opt_nobh,
Opt_commit, Opt_journal_update, Opt_journal_inum,
@@ -644,7 +652,6 @@ static match_table_t tokens = {
{Opt_nouid32, "nouid32"},
{Opt_nocheck, "nocheck"},
{Opt_nocheck, "check=none"},
- {Opt_check, "check"},
{Opt_debug, "debug"},
{Opt_oldalloc, "oldalloc"},
{Opt_orlov, "orlov"},
@@ -765,14 +772,6 @@ static int parse_options (char * options, struct super_block *sb,
case Opt_nouid32:
set_opt (sbi->s_mount_opt, NO_UID32);
break;
- case Opt_check:
-#ifdef CONFIG_EXT3_CHECK
- set_opt (sbi->s_mount_opt, CHECK);
-#else
- printk(KERN_ERR
- "EXT3 Check option not supported\n");
-#endif
- break;
case Opt_nocheck:
clear_opt (sbi->s_mount_opt, CHECK);
break;
@@ -1107,12 +1106,6 @@ static int ext3_setup_super(struct super_block *sb, struct ext3_super_block *es,
} else {
printk("internal journal\n");
}
-#ifdef CONFIG_EXT3_CHECK
- if (test_opt (sb, CHECK)) {
- ext3_check_blocks_bitmap (sb);
- ext3_check_inodes_bitmap (sb);
- }
-#endif
return res;
}
diff --git a/fs/ext3/xattr.c b/fs/ext3/xattr.c
index 269c7b92db9a..430de9f63be3 100644
--- a/fs/ext3/xattr.c
+++ b/fs/ext3/xattr.c
@@ -210,7 +210,7 @@ ext3_xattr_find_entry(struct ext3_xattr_entry **pentry, int name_index,
return cmp ? -ENODATA : 0;
}
-int
+static int
ext3_xattr_block_get(struct inode *inode, int name_index, const char *name,
void *buffer, size_t buffer_size)
{
@@ -354,7 +354,7 @@ ext3_xattr_list_entries(struct inode *inode, struct ext3_xattr_entry *entry,
return buffer_size - rest;
}
-int
+static int
ext3_xattr_block_list(struct inode *inode, char *buffer, size_t buffer_size)
{
struct buffer_head *bh = NULL;
@@ -626,7 +626,7 @@ struct ext3_xattr_block_find {
struct buffer_head *bh;
};
-int
+static int
ext3_xattr_block_find(struct inode *inode, struct ext3_xattr_info *i,
struct ext3_xattr_block_find *bs)
{
@@ -859,7 +859,7 @@ struct ext3_xattr_ibody_find {
struct ext3_iloc iloc;
};
-int
+static int
ext3_xattr_ibody_find(struct inode *inode, struct ext3_xattr_info *i,
struct ext3_xattr_ibody_find *is)
{
diff --git a/fs/fat/dir.c b/fs/fat/dir.c
index 895049b2ac9c..ba824964b9bb 100644
--- a/fs/fat/dir.c
+++ b/fs/fat/dir.c
@@ -222,6 +222,80 @@ fat_shortname2uni(struct nls_table *nls, unsigned char *buf, int buf_size,
return len;
}
+enum { PARSE_INVALID = 1, PARSE_NOT_LONGNAME, PARSE_EOF, };
+
+/**
+ * fat_parse_long - Parse extended directory entry.
+ *
+ * This function returns zero on success, negative value on error, or one of
+ * the following:
+ *
+ * %PARSE_INVALID - Directory entry is invalid.
+ * %PARSE_NOT_LONGNAME - Directory entry does not contain longname.
+ * %PARSE_EOF - Directory has no more entries.
+ */
+static int fat_parse_long(struct inode *dir, loff_t *pos,
+ struct buffer_head **bh, struct msdos_dir_entry **de,
+ wchar_t **unicode, unsigned char *nr_slots)
+{
+ struct msdos_dir_slot *ds;
+ unsigned char id, slot, slots, alias_checksum;
+
+ if (!*unicode) {
+ *unicode = (wchar_t *)__get_free_page(GFP_KERNEL);
+ if (!*unicode) {
+ brelse(*bh);
+ return -ENOMEM;
+ }
+ }
+parse_long:
+ slots = 0;
+ ds = (struct msdos_dir_slot *)*de;
+ id = ds->id;
+ if (!(id & 0x40))
+ return PARSE_INVALID;
+ slots = id & ~0x40;
+ if (slots > 20 || !slots) /* ceil(256 * 2 / 26) */
+ return PARSE_INVALID;
+ *nr_slots = slots;
+ alias_checksum = ds->alias_checksum;
+
+ slot = slots;
+ while (1) {
+ int offset;
+
+ slot--;
+ offset = slot * 13;
+ fat16_towchar(*unicode + offset, ds->name0_4, 5);
+ fat16_towchar(*unicode + offset + 5, ds->name5_10, 6);
+ fat16_towchar(*unicode + offset + 11, ds->name11_12, 2);
+
+ if (ds->id & 0x40)
+ (*unicode)[offset + 13] = 0;
+ if (fat_get_entry(dir, pos, bh, de) < 0)
+ return PARSE_EOF;
+ if (slot == 0)
+ break;
+ ds = (struct msdos_dir_slot *)*de;
+ if (ds->attr != ATTR_EXT)
+ return PARSE_NOT_LONGNAME;
+ if ((ds->id & ~0x40) != slot)
+ goto parse_long;
+ if (ds->alias_checksum != alias_checksum)
+ goto parse_long;
+ }
+ if ((*de)->name[0] == DELETED_FLAG)
+ return PARSE_INVALID;
+ if ((*de)->attr == ATTR_EXT)
+ goto parse_long;
+ if (IS_FREE((*de)->name) || ((*de)->attr & ATTR_VOLUME))
+ return PARSE_INVALID;
+ if (fat_checksum((*de)->name) != alias_checksum)
+ *nr_slots = 0;
+
+ return 0;
+}
+
/*
* Return values: negative -> error, 0 -> not found, positive -> found,
* value is the total amount of slots, including the shortname entry.
@@ -259,68 +333,16 @@ parse_record:
if (de->attr != ATTR_EXT && IS_FREE(de->name))
continue;
if (de->attr == ATTR_EXT) {
- struct msdos_dir_slot *ds;
- unsigned char id;
- unsigned char slot;
- unsigned char slots;
- unsigned char sum;
- unsigned char alias_checksum;
-
- if (!unicode) {
- unicode = (wchar_t *)
- __get_free_page(GFP_KERNEL);
- if (!unicode) {
- brelse(bh);
- return -ENOMEM;
- }
- }
-parse_long:
- slots = 0;
- ds = (struct msdos_dir_slot *) de;
- id = ds->id;
- if (!(id & 0x40))
- continue;
- slots = id & ~0x40;
- if (slots > 20 || !slots) /* ceil(256 * 2 / 26) */
- continue;
- nr_slots = slots;
- alias_checksum = ds->alias_checksum;
-
- slot = slots;
- while (1) {
- int offset;
-
- slot--;
- offset = slot * 13;
- fat16_towchar(unicode + offset, ds->name0_4, 5);
- fat16_towchar(unicode + offset + 5, ds->name5_10, 6);
- fat16_towchar(unicode + offset + 11, ds->name11_12, 2);
-
- if (ds->id & 0x40) {
- unicode[offset + 13] = 0;
- }
- if (fat_get_entry(inode, &cpos, &bh, &de) < 0)
- goto EODir;
- if (slot == 0)
- break;
- ds = (struct msdos_dir_slot *) de;
- if (ds->attr != ATTR_EXT)
- goto parse_record;
- if ((ds->id & ~0x40) != slot)
- goto parse_long;
- if (ds->alias_checksum != alias_checksum)
- goto parse_long;
- }
- if (de->name[0] == DELETED_FLAG)
- continue;
- if (de->attr == ATTR_EXT)
- goto parse_long;
- if (IS_FREE(de->name) || (de->attr & ATTR_VOLUME))
+ int status = fat_parse_long(inode, &cpos, &bh, &de,
+ &unicode, &nr_slots);
+ if (status < 0)
+ return status;
+ else if (status == PARSE_INVALID)
continue;
- for (sum = 0, i = 0; i < 11; i++)
- sum = (((sum&1)<<7)|((sum&0xfe)>>1)) + de->name[i];
- if (sum != alias_checksum)
- nr_slots = 0;
+ else if (status == PARSE_NOT_LONGNAME)
+ goto parse_record;
+ else if (status == PARSE_EOF)
+ goto EODir;
}
memcpy(work, de->name, sizeof(de->name));
@@ -408,8 +430,8 @@ struct fat_ioctl_filldir_callback {
int short_len;
};
-static int fat_readdirx(struct inode *inode, struct file *filp, void *dirent,
- filldir_t filldir, int short_only, int both)
+static int __fat_readdir(struct inode *inode, struct file *filp, void *dirent,
+ filldir_t filldir, int short_only, int both)
{
struct super_block *sb = inode->i_sb;
struct msdos_sb_info *sbi = MSDOS_SB(sb);
@@ -458,9 +480,10 @@ static int fat_readdirx(struct inode *inode, struct file *filp, void *dirent,
bh = NULL;
GetNew:
- long_slots = 0;
if (fat_get_entry(inode, &cpos, &bh, &de) == -1)
goto EODir;
+parse_record:
+ long_slots = 0;
/* Check for long filename entry */
if (isvfat) {
if (de->name[0] == DELETED_FLAG)
@@ -475,69 +498,18 @@ GetNew:
}
if (isvfat && de->attr == ATTR_EXT) {
- struct msdos_dir_slot *ds;
- unsigned char id;
- unsigned char slot;
- unsigned char slots;
- unsigned char sum;
- unsigned char alias_checksum;
-
- if (!unicode) {
- unicode = (wchar_t *)__get_free_page(GFP_KERNEL);
- if (!unicode) {
- filp->f_pos = cpos;
- brelse(bh);
- ret = -ENOMEM;
- goto out;
- }
- }
-ParseLong:
- slots = 0;
- ds = (struct msdos_dir_slot *) de;
- id = ds->id;
- if (!(id & 0x40))
- goto RecEnd;
- slots = id & ~0x40;
- if (slots > 20 || !slots) /* ceil(256 * 2 / 26) */
+ int status = fat_parse_long(inode, &cpos, &bh, &de,
+ &unicode, &long_slots);
+ if (status < 0) {
+ filp->f_pos = cpos;
+ ret = status;
+ goto out;
+ } else if (status == PARSE_INVALID)
goto RecEnd;
- long_slots = slots;
- alias_checksum = ds->alias_checksum;
-
- slot = slots;
- while (1) {
- int offset;
-
- slot--;
- offset = slot * 13;
- fat16_towchar(unicode + offset, ds->name0_4, 5);
- fat16_towchar(unicode + offset + 5, ds->name5_10, 6);
- fat16_towchar(unicode + offset + 11, ds->name11_12, 2);
-
- if (ds->id & 0x40) {
- unicode[offset + 13] = 0;
- }
- if (fat_get_entry(inode, &cpos, &bh, &de) == -1)
- goto EODir;
- if (slot == 0)
- break;
- ds = (struct msdos_dir_slot *) de;
- if (ds->attr != ATTR_EXT)
- goto RecEnd; /* XXX */
- if ((ds->id & ~0x40) != slot)
- goto ParseLong;
- if (ds->alias_checksum != alias_checksum)
- goto ParseLong;
- }
- if (de->name[0] == DELETED_FLAG)
- goto RecEnd;
- if (de->attr == ATTR_EXT)
- goto ParseLong;
- if (IS_FREE(de->name) || (de->attr & ATTR_VOLUME))
- goto RecEnd;
- for (sum = 0, i = 0; i < 11; i++)
- sum = (((sum&1)<<7)|((sum&0xfe)>>1)) + de->name[i];
- if (sum != alias_checksum)
- long_slots = 0;
+ else if (status == PARSE_NOT_LONGNAME)
+ goto parse_record;
+ else if (status == PARSE_EOF)
+ goto EODir;
}
if (sbi->options.dotsOK) {
@@ -671,7 +643,7 @@ out:
static int fat_readdir(struct file *filp, void *dirent, filldir_t filldir)
{
struct inode *inode = filp->f_dentry->d_inode;
- return fat_readdirx(inode, filp, dirent, filldir, 0, 0);
+ return __fat_readdir(inode, filp, dirent, filldir, 0, 0);
}
static int fat_ioctl_filldir(void *__buf, const char *name, int name_len,
@@ -760,8 +732,8 @@ static int fat_dir_ioctl(struct inode * inode, struct file * filp,
down(&inode->i_sem);
ret = -ENOENT;
if (!IS_DEADDIR(inode)) {
- ret = fat_readdirx(inode, filp, &buf, fat_ioctl_filldir,
- short_only, both);
+ ret = __fat_readdir(inode, filp, &buf, fat_ioctl_filldir,
+ short_only, both);
}
up(&inode->i_sem);
if (ret >= 0)
diff --git a/fs/fat/inode.c b/fs/fat/inode.c
index e2effe2dc9b2..a0f9b9fe1307 100644
--- a/fs/fat/inode.c
+++ b/fs/fat/inode.c
@@ -846,7 +846,7 @@ static match_table_t vfat_tokens = {
{Opt_err, NULL}
};
-static int parse_options(char *options, int is_vfat, int *debug,
+static int parse_options(char *options, int is_vfat, int silent, int *debug,
struct fat_mount_options *opts)
{
char *p;
@@ -1008,8 +1008,11 @@ static int parse_options(char *options, int is_vfat, int *debug,
break;
/* unknown option */
default:
- printk(KERN_ERR "FAT: Unrecognized mount option \"%s\" "
- "or missing value\n", p);
+ if (!silent) {
+ printk(KERN_ERR
+ "FAT: Unrecognized mount option \"%s\" "
+ "or missing value\n", p);
+ }
return -EINVAL;
}
}
@@ -1091,7 +1094,7 @@ int fat_fill_super(struct super_block *sb, void *data, int silent,
sb->s_export_op = &fat_export_ops;
sbi->dir_ops = fs_dir_inode_ops;
- error = parse_options(data, isvfat, &debug, &sbi->options);
+ error = parse_options(data, isvfat, silent, &debug, &sbi->options);
if (error)
goto out_fail;
diff --git a/fs/file_table.c b/fs/file_table.c
index 86ec8ae985b4..c3a5e2fd663b 100644
--- a/fs/file_table.c
+++ b/fs/file_table.c
@@ -35,7 +35,7 @@ static DEFINE_SPINLOCK(filp_count_lock);
* context and must be fully threaded - use a local spinlock
* to protect files_stat.nr_files
*/
-void filp_ctor(void * objp, struct kmem_cache_s *cachep, unsigned long cflags)
+void filp_ctor(void *objp, struct kmem_cache *cachep, unsigned long cflags)
{
if ((cflags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
SLAB_CTOR_CONSTRUCTOR) {
@@ -46,7 +46,7 @@ void filp_ctor(void * objp, struct kmem_cache_s *cachep, unsigned long cflags)
}
}
-void filp_dtor(void * objp, struct kmem_cache_s *cachep, unsigned long dflags)
+void filp_dtor(void *objp, struct kmem_cache *cachep, unsigned long dflags)
{
unsigned long flags;
spin_lock_irqsave(&filp_count_lock, flags);
@@ -56,13 +56,13 @@ void filp_dtor(void * objp, struct kmem_cache_s *cachep, unsigned long dflags)
static inline void file_free_rcu(struct rcu_head *head)
{
- struct file *f = container_of(head, struct file, f_rcuhead);
+ struct file *f = container_of(head, struct file, f_u.fu_rcuhead);
kmem_cache_free(filp_cachep, f);
}
static inline void file_free(struct file *f)
{
- call_rcu(&f->f_rcuhead, file_free_rcu);
+ call_rcu(&f->f_u.fu_rcuhead, file_free_rcu);
}
/* Find an unused file structure and return a pointer to it.
@@ -95,7 +95,7 @@ struct file *get_empty_filp(void)
f->f_gid = current->fsgid;
rwlock_init(&f->f_owner.lock);
/* f->f_version: 0 */
- INIT_LIST_HEAD(&f->f_list);
+ INIT_LIST_HEAD(&f->f_u.fu_list);
return f;
over:
@@ -225,15 +225,15 @@ void file_move(struct file *file, struct list_head *list)
if (!list)
return;
file_list_lock();
- list_move(&file->f_list, list);
+ list_move(&file->f_u.fu_list, list);
file_list_unlock();
}
void file_kill(struct file *file)
{
- if (!list_empty(&file->f_list)) {
+ if (!list_empty(&file->f_u.fu_list)) {
file_list_lock();
- list_del_init(&file->f_list);
+ list_del_init(&file->f_u.fu_list);
file_list_unlock();
}
}
@@ -245,7 +245,7 @@ int fs_may_remount_ro(struct super_block *sb)
/* Check that no files are currently opened for writing. */
file_list_lock();
list_for_each(p, &sb->s_files) {
- struct file *file = list_entry(p, struct file, f_list);
+ struct file *file = list_entry(p, struct file, f_u.fu_list);
struct inode *inode = file->f_dentry->d_inode;
/* File with pending delete? */
diff --git a/fs/filesystems.c b/fs/filesystems.c
index 44082bfdfec9..9f1072836c8e 100644
--- a/fs/filesystems.c
+++ b/fs/filesystems.c
@@ -12,6 +12,7 @@
#include <linux/kmod.h>
#include <linux/init.h>
#include <linux/module.h>
+#include <linux/sched.h> /* for 'current' */
#include <asm/uaccess.h>
/*
diff --git a/fs/freevxfs/vxfs_extern.h b/fs/freevxfs/vxfs_extern.h
index d8be917f9797..927acf70c591 100644
--- a/fs/freevxfs/vxfs_extern.h
+++ b/fs/freevxfs/vxfs_extern.h
@@ -38,7 +38,7 @@
*/
-struct kmem_cache_s;
+struct kmem_cache;
struct super_block;
struct vxfs_inode_info;
struct inode;
@@ -51,7 +51,7 @@ extern daddr_t vxfs_bmap1(struct inode *, long);
extern int vxfs_read_fshead(struct super_block *);
/* vxfs_inode.c */
-extern struct kmem_cache_s *vxfs_inode_cachep;
+extern struct kmem_cache *vxfs_inode_cachep;
extern void vxfs_dumpi(struct vxfs_inode_info *, ino_t);
extern struct inode * vxfs_get_fake_inode(struct super_block *,
struct vxfs_inode_info *);
diff --git a/fs/freevxfs/vxfs_inode.c b/fs/freevxfs/vxfs_inode.c
index 9672d2facffe..f544aae9169f 100644
--- a/fs/freevxfs/vxfs_inode.c
+++ b/fs/freevxfs/vxfs_inode.c
@@ -46,15 +46,6 @@ extern struct address_space_operations vxfs_immed_aops;
extern struct inode_operations vxfs_immed_symlink_iops;
-static struct file_operations vxfs_file_operations = {
- .open = generic_file_open,
- .llseek = generic_file_llseek,
- .read = generic_file_read,
- .mmap = generic_file_mmap,
- .sendfile = generic_file_sendfile,
-};
-
-
kmem_cache_t *vxfs_inode_cachep;
@@ -318,7 +309,7 @@ vxfs_read_inode(struct inode *ip)
aops = &vxfs_aops;
if (S_ISREG(ip->i_mode)) {
- ip->i_fop = &vxfs_file_operations;
+ ip->i_fop = &generic_ro_fops;
ip->i_mapping->a_ops = aops;
} else if (S_ISDIR(ip->i_mode)) {
ip->i_op = &vxfs_dir_inode_ops;
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
index e94ab398b717..785c7213a54f 100644
--- a/fs/fs-writeback.c
+++ b/fs/fs-writeback.c
@@ -230,7 +230,6 @@ __sync_single_inode(struct inode *inode, struct writeback_control *wbc)
* The inode is clean, unused
*/
list_move(&inode->i_list, &inode_unused);
- inodes_stat.nr_unused++;
}
}
wake_up_inode(inode);
@@ -238,14 +237,20 @@ __sync_single_inode(struct inode *inode, struct writeback_control *wbc)
}
/*
- * Write out an inode's dirty pages. Called under inode_lock.
+ * Write out an inode's dirty pages. Called under inode_lock. Either the
+ * caller has ref on the inode (either via __iget or via syscall against an fd)
+ * or the inode has I_WILL_FREE set (via generic_forget_inode)
*/
static int
-__writeback_single_inode(struct inode *inode,
- struct writeback_control *wbc)
+__writeback_single_inode(struct inode *inode, struct writeback_control *wbc)
{
wait_queue_head_t *wqh;
+ if (!atomic_read(&inode->i_count))
+ WARN_ON(!(inode->i_state & (I_WILL_FREE|I_FREEING)));
+ else
+ WARN_ON(inode->i_state & I_WILL_FREE);
+
if ((wbc->sync_mode != WB_SYNC_ALL) && (inode->i_state & I_LOCK)) {
list_move(&inode->i_list, &inode->i_sb->s_dirty);
return 0;
@@ -259,11 +264,9 @@ __writeback_single_inode(struct inode *inode,
wqh = bit_waitqueue(&inode->i_state, __I_LOCK);
do {
- __iget(inode);
spin_unlock(&inode_lock);
__wait_on_bit(wqh, &wq, inode_wait,
TASK_UNINTERRUPTIBLE);
- iput(inode);
spin_lock(&inode_lock);
} while (inode->i_state & I_LOCK);
}
@@ -541,14 +544,15 @@ void sync_inodes(int wait)
}
/**
- * write_inode_now - write an inode to disk
- * @inode: inode to write to disk
- * @sync: whether the write should be synchronous or not
+ * write_inode_now - write an inode to disk
+ * @inode: inode to write to disk
+ * @sync: whether the write should be synchronous or not
+ *
+ * This function commits an inode to disk immediately if it is dirty. This is
+ * primarily needed by knfsd.
*
- * This function commits an inode to disk immediately if it is
- * dirty. This is primarily needed by knfsd.
+ * The caller must either have a ref on the inode or must have set I_WILL_FREE.
*/
-
int write_inode_now(struct inode *inode, int sync)
{
int ret;
@@ -558,7 +562,7 @@ int write_inode_now(struct inode *inode, int sync)
};
if (!mapping_cap_writeback_dirty(inode->i_mapping))
- return 0;
+ wbc.nr_to_write = 0;
might_sleep();
spin_lock(&inode_lock);
@@ -602,7 +606,7 @@ EXPORT_SYMBOL(sync_inode);
* O_SYNC flag set, to flush dirty writes to disk.
*
* @what is a bitmask, specifying which part of the inode's data should be
- * written and waited upon:
+ * written and waited upon.
*
* OSYNC_DATA: i_mapping's dirty data
* OSYNC_METADATA: the buffers at i_mapping->private_list
@@ -668,8 +672,9 @@ int writeback_acquire(struct backing_dev_info *bdi)
/**
* writeback_in_progress: determine whether there is writeback in progress
- * against a backing device.
* @bdi: the device's backing_dev_info structure.
+ *
+ * Determine whether there is writeback in progress against a backing device.
*/
int writeback_in_progress(struct backing_dev_info *bdi)
{
diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c
index d4c869c6d01b..8f873e621f41 100644
--- a/fs/fuse/dev.c
+++ b/fs/fuse/dev.c
@@ -151,9 +151,9 @@ void fuse_release_background(struct fuse_req *req)
/*
* This function is called when a request is finished. Either a reply
* has arrived or it was interrupted (and not yet sent) or some error
- * occured during communication with userspace, or the device file was
- * closed. It decreases the referece count for the request. In case
- * of a background request the referece to the stored objects are
+ * occurred during communication with userspace, or the device file was
+ * closed. It decreases the reference count for the request. In case
+ * of a background request the reference to the stored objects are
* released. The requester thread is woken up (if still waiting), and
* finally the request is either freed or put on the unused_list
*
@@ -184,6 +184,13 @@ static void request_end(struct fuse_conn *fc, struct fuse_req *req)
fuse_putback_request() */
for (i = 1; i < FUSE_MAX_OUTSTANDING; i++)
up(&fc->outstanding_sem);
+ } else if (req->in.h.opcode == FUSE_RELEASE && req->inode == NULL) {
+ /* Special case for failed iget in CREATE */
+ u64 nodeid = req->in.h.nodeid;
+ __fuse_get_request(req);
+ fuse_reset_request(req);
+ fuse_send_forget(fc, req, nodeid, 1);
+ putback = 0;
}
if (putback)
fuse_putback_request(fc, req);
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
index 29f1e9f6e85c..c045cc70c749 100644
--- a/fs/fuse/dir.c
+++ b/fs/fuse/dir.c
@@ -13,6 +13,7 @@
#include <linux/gfp.h>
#include <linux/sched.h>
#include <linux/namei.h>
+#include <linux/mount.h>
static inline unsigned long time_to_jiffies(unsigned long sec,
unsigned long nsec)
@@ -134,6 +135,101 @@ static void fuse_invalidate_entry(struct dentry *entry)
entry->d_time = jiffies - 1;
}
+static int fuse_create_open(struct inode *dir, struct dentry *entry, int mode,
+ struct nameidata *nd)
+{
+ int err;
+ struct inode *inode;
+ struct fuse_conn *fc = get_fuse_conn(dir);
+ struct fuse_req *req;
+ struct fuse_open_in inarg;
+ struct fuse_open_out outopen;
+ struct fuse_entry_out outentry;
+ struct fuse_inode *fi;
+ struct fuse_file *ff;
+ struct file *file;
+ int flags = nd->intent.open.flags - 1;
+
+ err = -ENOSYS;
+ if (fc->no_create)
+ goto out;
+
+ err = -ENAMETOOLONG;
+ if (entry->d_name.len > FUSE_NAME_MAX)
+ goto out;
+
+ err = -EINTR;
+ req = fuse_get_request(fc);
+ if (!req)
+ goto out;
+
+ ff = fuse_file_alloc();
+ if (!ff)
+ goto out_put_request;
+
+ flags &= ~O_NOCTTY;
+ memset(&inarg, 0, sizeof(inarg));
+ inarg.flags = flags;
+ inarg.mode = mode;
+ req->in.h.opcode = FUSE_CREATE;
+ req->in.h.nodeid = get_node_id(dir);
+ req->inode = dir;
+ req->in.numargs = 2;
+ req->in.args[0].size = sizeof(inarg);
+ req->in.args[0].value = &inarg;
+ req->in.args[1].size = entry->d_name.len + 1;
+ req->in.args[1].value = entry->d_name.name;
+ req->out.numargs = 2;
+ req->out.args[0].size = sizeof(outentry);
+ req->out.args[0].value = &outentry;
+ req->out.args[1].size = sizeof(outopen);
+ req->out.args[1].value = &outopen;
+ request_send(fc, req);
+ err = req->out.h.error;
+ if (err) {
+ if (err == -ENOSYS)
+ fc->no_create = 1;
+ goto out_free_ff;
+ }
+
+ err = -EIO;
+ if (!S_ISREG(outentry.attr.mode))
+ goto out_free_ff;
+
+ inode = fuse_iget(dir->i_sb, outentry.nodeid, outentry.generation,
+ &outentry.attr);
+ err = -ENOMEM;
+ if (!inode) {
+ flags &= ~(O_CREAT | O_EXCL | O_TRUNC);
+ ff->fh = outopen.fh;
+ fuse_send_release(fc, ff, outentry.nodeid, NULL, flags, 0);
+ goto out_put_request;
+ }
+ fuse_put_request(fc, req);
+ entry->d_time = time_to_jiffies(outentry.entry_valid,
+ outentry.entry_valid_nsec);
+ fi = get_fuse_inode(inode);
+ fi->i_time = time_to_jiffies(outentry.attr_valid,
+ outentry.attr_valid_nsec);
+
+ d_instantiate(entry, inode);
+ file = lookup_instantiate_filp(nd, entry, generic_file_open);
+ if (IS_ERR(file)) {
+ ff->fh = outopen.fh;
+ fuse_send_release(fc, ff, outentry.nodeid, inode, flags, 0);
+ return PTR_ERR(file);
+ }
+ fuse_finish_open(inode, file, ff, &outopen);
+ return 0;
+
+ out_free_ff:
+ fuse_file_free(ff);
+ out_put_request:
+ fuse_put_request(fc, req);
+ out:
+ return err;
+}
+
static int create_new_entry(struct fuse_conn *fc, struct fuse_req *req,
struct inode *dir, struct dentry *entry,
int mode)
@@ -208,6 +304,12 @@ static int fuse_mknod(struct inode *dir, struct dentry *entry, int mode,
static int fuse_create(struct inode *dir, struct dentry *entry, int mode,
struct nameidata *nd)
{
+ if (nd && (nd->flags & LOOKUP_CREATE)) {
+ int err = fuse_create_open(dir, entry, mode, nd);
+ if (err != -ENOSYS)
+ return err;
+ /* Fall back on mknod */
+ }
return fuse_mknod(dir, entry, mode, 0);
}
@@ -461,6 +563,38 @@ static int fuse_revalidate(struct dentry *entry)
return fuse_do_getattr(inode);
}
+static int fuse_access(struct inode *inode, int mask)
+{
+ struct fuse_conn *fc = get_fuse_conn(inode);
+ struct fuse_req *req;
+ struct fuse_access_in inarg;
+ int err;
+
+ if (fc->no_access)
+ return 0;
+
+ req = fuse_get_request(fc);
+ if (!req)
+ return -EINTR;
+
+ memset(&inarg, 0, sizeof(inarg));
+ inarg.mask = mask;
+ req->in.h.opcode = FUSE_ACCESS;
+ req->in.h.nodeid = get_node_id(inode);
+ req->inode = inode;
+ req->in.numargs = 1;
+ req->in.args[0].size = sizeof(inarg);
+ req->in.args[0].value = &inarg;
+ request_send(fc, req);
+ err = req->out.h.error;
+ fuse_put_request(fc, req);
+ if (err == -ENOSYS) {
+ fc->no_access = 1;
+ err = 0;
+ }
+ return err;
+}
+
static int fuse_permission(struct inode *inode, int mask, struct nameidata *nd)
{
struct fuse_conn *fc = get_fuse_conn(inode);
@@ -491,11 +625,11 @@ static int fuse_permission(struct inode *inode, int mask, struct nameidata *nd)
return err;
} else {
int mode = inode->i_mode;
- if ((mask & MAY_WRITE) && IS_RDONLY(inode) &&
- (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)))
- return -EROFS;
if ((mask & MAY_EXEC) && !S_ISDIR(mode) && !(mode & S_IXUGO))
return -EACCES;
+
+ if (nd && (nd->flags & LOOKUP_ACCESS))
+ return fuse_access(inode, mask);
return 0;
}
}
@@ -629,29 +763,29 @@ static int fuse_dir_fsync(struct file *file, struct dentry *de, int datasync)
return file ? fuse_fsync_common(file, de, datasync, 1) : 0;
}
-static unsigned iattr_to_fattr(struct iattr *iattr, struct fuse_attr *fattr)
+static void iattr_to_fattr(struct iattr *iattr, struct fuse_setattr_in *arg)
{
unsigned ivalid = iattr->ia_valid;
- unsigned fvalid = 0;
-
- memset(fattr, 0, sizeof(*fattr));
if (ivalid & ATTR_MODE)
- fvalid |= FATTR_MODE, fattr->mode = iattr->ia_mode;
+ arg->valid |= FATTR_MODE, arg->mode = iattr->ia_mode;
if (ivalid & ATTR_UID)
- fvalid |= FATTR_UID, fattr->uid = iattr->ia_uid;
+ arg->valid |= FATTR_UID, arg->uid = iattr->ia_uid;
if (ivalid & ATTR_GID)
- fvalid |= FATTR_GID, fattr->gid = iattr->ia_gid;
+ arg->valid |= FATTR_GID, arg->gid = iattr->ia_gid;
if (ivalid & ATTR_SIZE)
- fvalid |= FATTR_SIZE, fattr->size = iattr->ia_size;
+ arg->valid |= FATTR_SIZE, arg->size = iattr->ia_size;
/* You can only _set_ these together (they may change by themselves) */
if ((ivalid & (ATTR_ATIME | ATTR_MTIME)) == (ATTR_ATIME | ATTR_MTIME)) {
- fvalid |= FATTR_ATIME | FATTR_MTIME;
- fattr->atime = iattr->ia_atime.tv_sec;
- fattr->mtime = iattr->ia_mtime.tv_sec;
+ arg->valid |= FATTR_ATIME | FATTR_MTIME;
+ arg->atime = iattr->ia_atime.tv_sec;
+ arg->mtime = iattr->ia_mtime.tv_sec;
+ }
+ if (ivalid & ATTR_FILE) {
+ struct fuse_file *ff = iattr->ia_file->private_data;
+ arg->valid |= FATTR_FH;
+ arg->fh = ff->fh;
}
-
- return fvalid;
}
static int fuse_setattr(struct dentry *entry, struct iattr *attr)
@@ -686,7 +820,7 @@ static int fuse_setattr(struct dentry *entry, struct iattr *attr)
return -EINTR;
memset(&inarg, 0, sizeof(inarg));
- inarg.valid = iattr_to_fattr(attr, &inarg.attr);
+ iattr_to_fattr(attr, &inarg);
req->in.h.opcode = FUSE_SETATTR;
req->in.h.nodeid = get_node_id(inode);
req->inode = inode;
@@ -735,19 +869,22 @@ static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry,
struct nameidata *nd)
{
struct inode *inode;
- int err = fuse_lookup_iget(dir, entry, &inode);
+ int err;
+
+ err = fuse_lookup_iget(dir, entry, &inode);
if (err)
return ERR_PTR(err);
if (inode && S_ISDIR(inode->i_mode)) {
/* Don't allow creating an alias to a directory */
struct dentry *alias = d_find_alias(inode);
- if (alias && !(alias->d_flags & DCACHE_DISCONNECTED)) {
+ if (alias) {
dput(alias);
iput(inode);
return ERR_PTR(-EIO);
}
}
- return d_splice_alias(inode, entry);
+ d_add(entry, inode);
+ return NULL;
}
static int fuse_setxattr(struct dentry *entry, const char *name,
diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index 657ab11c173b..2ca86141d13a 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -14,11 +14,69 @@
static struct file_operations fuse_direct_io_file_operations;
-int fuse_open_common(struct inode *inode, struct file *file, int isdir)
+static int fuse_send_open(struct inode *inode, struct file *file, int isdir,
+ struct fuse_open_out *outargp)
{
struct fuse_conn *fc = get_fuse_conn(inode);
- struct fuse_req *req;
struct fuse_open_in inarg;
+ struct fuse_req *req;
+ int err;
+
+ req = fuse_get_request(fc);
+ if (!req)
+ return -EINTR;
+
+ memset(&inarg, 0, sizeof(inarg));
+ inarg.flags = file->f_flags & ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC);
+ req->in.h.opcode = isdir ? FUSE_OPENDIR : FUSE_OPEN;
+ req->in.h.nodeid = get_node_id(inode);
+ req->inode = inode;
+ req->in.numargs = 1;
+ req->in.args[0].size = sizeof(inarg);
+ req->in.args[0].value = &inarg;
+ req->out.numargs = 1;
+ req->out.args[0].size = sizeof(*outargp);
+ req->out.args[0].value = outargp;
+ request_send(fc, req);
+ err = req->out.h.error;
+ fuse_put_request(fc, req);
+
+ return err;
+}
+
+struct fuse_file *fuse_file_alloc(void)
+{
+ struct fuse_file *ff;
+ ff = kmalloc(sizeof(struct fuse_file), GFP_KERNEL);
+ if (ff) {
+ ff->release_req = fuse_request_alloc();
+ if (!ff->release_req) {
+ kfree(ff);
+ ff = NULL;
+ }
+ }
+ return ff;
+}
+
+void fuse_file_free(struct fuse_file *ff)
+{
+ fuse_request_free(ff->release_req);
+ kfree(ff);
+}
+
+void fuse_finish_open(struct inode *inode, struct file *file,
+ struct fuse_file *ff, struct fuse_open_out *outarg)
+{
+ if (outarg->open_flags & FOPEN_DIRECT_IO)
+ file->f_op = &fuse_direct_io_file_operations;
+ if (!(outarg->open_flags & FOPEN_KEEP_CACHE))
+ invalidate_inode_pages(inode->i_mapping);
+ ff->fh = outarg->fh;
+ file->private_data = ff;
+}
+
+int fuse_open_common(struct inode *inode, struct file *file, int isdir)
+{
struct fuse_open_out outarg;
struct fuse_file *ff;
int err;
@@ -34,73 +92,53 @@ int fuse_open_common(struct inode *inode, struct file *file, int isdir)
/* If opening the root node, no lookup has been performed on
it, so the attributes must be refreshed */
if (get_node_id(inode) == FUSE_ROOT_ID) {
- int err = fuse_do_getattr(inode);
+ err = fuse_do_getattr(inode);
if (err)
return err;
}
- req = fuse_get_request(fc);
- if (!req)
- return -EINTR;
-
- err = -ENOMEM;
- ff = kmalloc(sizeof(struct fuse_file), GFP_KERNEL);
+ ff = fuse_file_alloc();
if (!ff)
- goto out_put_request;
+ return -ENOMEM;
- ff->release_req = fuse_request_alloc();
- if (!ff->release_req) {
- kfree(ff);
- goto out_put_request;
- }
-
- memset(&inarg, 0, sizeof(inarg));
- inarg.flags = file->f_flags & ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC);
- req->in.h.opcode = isdir ? FUSE_OPENDIR : FUSE_OPEN;
- req->in.h.nodeid = get_node_id(inode);
- req->inode = inode;
- req->in.numargs = 1;
- req->in.args[0].size = sizeof(inarg);
- req->in.args[0].value = &inarg;
- req->out.numargs = 1;
- req->out.args[0].size = sizeof(outarg);
- req->out.args[0].value = &outarg;
- request_send(fc, req);
- err = req->out.h.error;
- if (err) {
- fuse_request_free(ff->release_req);
- kfree(ff);
- } else {
- if (!isdir && (outarg.open_flags & FOPEN_DIRECT_IO))
- file->f_op = &fuse_direct_io_file_operations;
- if (!(outarg.open_flags & FOPEN_KEEP_CACHE))
- invalidate_inode_pages(inode->i_mapping);
- ff->fh = outarg.fh;
- file->private_data = ff;
+ err = fuse_send_open(inode, file, isdir, &outarg);
+ if (err)
+ fuse_file_free(ff);
+ else {
+ if (isdir)
+ outarg.open_flags &= ~FOPEN_DIRECT_IO;
+ fuse_finish_open(inode, file, ff, &outarg);
}
- out_put_request:
- fuse_put_request(fc, req);
return err;
}
-int fuse_release_common(struct inode *inode, struct file *file, int isdir)
+void fuse_send_release(struct fuse_conn *fc, struct fuse_file *ff,
+ u64 nodeid, struct inode *inode, int flags, int isdir)
{
- struct fuse_conn *fc = get_fuse_conn(inode);
- struct fuse_file *ff = file->private_data;
- struct fuse_req *req = ff->release_req;
+ struct fuse_req * req = ff->release_req;
struct fuse_release_in *inarg = &req->misc.release_in;
inarg->fh = ff->fh;
- inarg->flags = file->f_flags & ~O_EXCL;
+ inarg->flags = flags;
req->in.h.opcode = isdir ? FUSE_RELEASEDIR : FUSE_RELEASE;
- req->in.h.nodeid = get_node_id(inode);
+ req->in.h.nodeid = nodeid;
req->inode = inode;
req->in.numargs = 1;
req->in.args[0].size = sizeof(struct fuse_release_in);
req->in.args[0].value = inarg;
request_send_background(fc, req);
kfree(ff);
+}
+
+int fuse_release_common(struct inode *inode, struct file *file, int isdir)
+{
+ struct fuse_file *ff = file->private_data;
+ if (ff) {
+ struct fuse_conn *fc = get_fuse_conn(inode);
+ u64 nodeid = get_node_id(inode);
+ fuse_send_release(fc, ff, nodeid, inode, file->f_flags, isdir);
+ }
/* Return value is ignored by VFS */
return 0;
diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h
index 24d761518d86..0ea5301f86be 100644
--- a/fs/fuse/fuse_i.h
+++ b/fs/fuse/fuse_i.h
@@ -266,6 +266,12 @@ struct fuse_conn {
/** Is removexattr not implemented by fs? */
unsigned no_removexattr : 1;
+ /** Is access not implemented by fs? */
+ unsigned no_access : 1;
+
+ /** Is create not implemented by fs? */
+ unsigned no_create : 1;
+
/** Backing dev info */
struct backing_dev_info bdi;
};
@@ -337,6 +343,17 @@ size_t fuse_send_read_common(struct fuse_req *req, struct file *file,
*/
int fuse_open_common(struct inode *inode, struct file *file, int isdir);
+struct fuse_file *fuse_file_alloc(void);
+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);
+
+/**
+ * Send a RELEASE request
+ */
+void fuse_send_release(struct fuse_conn *fc, struct fuse_file *ff,
+ u64 nodeid, struct inode *inode, int flags, int isdir);
+
/**
* Send RELEASE or RELEASEDIR request
*/
@@ -349,22 +366,22 @@ int fuse_fsync_common(struct file *file, struct dentry *de, int datasync,
int isdir);
/**
- * Initialise file operations on a regular file
+ * Initialize file operations on a regular file
*/
void fuse_init_file_inode(struct inode *inode);
/**
- * Initialise inode operations on regular files and special files
+ * Initialize inode operations on regular files and special files
*/
void fuse_init_common(struct inode *inode);
/**
- * Initialise inode and file operations on a directory
+ * Initialize inode and file operations on a directory
*/
void fuse_init_dir(struct inode *inode);
/**
- * Initialise inode operations on a symlink
+ * Initialize inode operations on a symlink
*/
void fuse_init_symlink(struct inode *inode);
@@ -411,7 +428,7 @@ struct fuse_req *fuse_get_request(struct fuse_conn *fc);
/**
* Decrement reference count of a request. If count goes to zero put
- * on unused list (preallocated) or free reqest (not preallocated).
+ * on unused list (preallocated) or free request (not preallocated).
*/
void fuse_put_request(struct fuse_conn *fc, struct fuse_req *req);
@@ -431,7 +448,7 @@ void request_send_noreply(struct fuse_conn *fc, struct fuse_req *req);
void request_send_background(struct fuse_conn *fc, struct fuse_req *req);
/**
- * Release inodes and file assiciated with background request
+ * Release inodes and file associated with background request
*/
void fuse_release_background(struct fuse_req *req);
diff --git a/fs/hfs/hfs_fs.h b/fs/hfs/hfs_fs.h
index aae019aadf88..cc5dcd52e23d 100644
--- a/fs/hfs/hfs_fs.h
+++ b/fs/hfs/hfs_fs.h
@@ -9,7 +9,6 @@
#ifndef _LINUX_HFS_FS_H
#define _LINUX_HFS_FS_H
-#include <linux/version.h>
#include <linux/slab.h>
#include <linux/types.h>
#include <linux/buffer_head.h>
diff --git a/fs/hfs/inode.c b/fs/hfs/inode.c
index f1570b9f9de3..d499393a8ae7 100644
--- a/fs/hfs/inode.c
+++ b/fs/hfs/inode.c
@@ -12,7 +12,6 @@
*/
#include <linux/pagemap.h>
-#include <linux/version.h>
#include <linux/mpage.h>
#include "hfs_fs.h"
@@ -46,7 +45,7 @@ static sector_t hfs_bmap(struct address_space *mapping, sector_t block)
return generic_block_bmap(mapping, block, hfs_get_block);
}
-static int hfs_releasepage(struct page *page, int mask)
+static int hfs_releasepage(struct page *page, gfp_t mask)
{
struct inode *inode = page->mapping->host;
struct super_block *sb = inode->i_sb;
diff --git a/fs/hfsplus/bnode.c b/fs/hfsplus/bnode.c
index b85abc6e6f83..930cd9212de8 100644
--- a/fs/hfsplus/bnode.c
+++ b/fs/hfsplus/bnode.c
@@ -13,7 +13,6 @@
#include <linux/pagemap.h>
#include <linux/fs.h>
#include <linux/swap.h>
-#include <linux/version.h>
#include "hfsplus_fs.h"
#include "hfsplus_raw.h"
diff --git a/fs/hfsplus/dir.c b/fs/hfsplus/dir.c
index 7bda76667a4a..50c8f44b6c66 100644
--- a/fs/hfsplus/dir.c
+++ b/fs/hfsplus/dir.c
@@ -13,7 +13,6 @@
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/random.h>
-#include <linux/version.h>
#include "hfsplus_fs.h"
#include "hfsplus_raw.h"
diff --git a/fs/hfsplus/extents.c b/fs/hfsplus/extents.c
index e7235ca79a95..e3ff56a03011 100644
--- a/fs/hfsplus/extents.c
+++ b/fs/hfsplus/extents.c
@@ -11,7 +11,6 @@
#include <linux/errno.h>
#include <linux/fs.h>
#include <linux/pagemap.h>
-#include <linux/version.h>
#include "hfsplus_fs.h"
#include "hfsplus_raw.h"
diff --git a/fs/hfsplus/hfsplus_fs.h b/fs/hfsplus/hfsplus_fs.h
index 2bc0cdd30e56..c60e5635498d 100644
--- a/fs/hfsplus/hfsplus_fs.h
+++ b/fs/hfsplus/hfsplus_fs.h
@@ -11,7 +11,6 @@
#define _LINUX_HFSPLUS_FS_H
#include <linux/fs.h>
-#include <linux/version.h>
#include <linux/buffer_head.h>
#include "hfsplus_raw.h"
diff --git a/fs/hfsplus/inode.c b/fs/hfsplus/inode.c
index d5642705f633..fc98583cf045 100644
--- a/fs/hfsplus/inode.c
+++ b/fs/hfsplus/inode.c
@@ -11,7 +11,6 @@
#include <linux/mm.h>
#include <linux/fs.h>
#include <linux/pagemap.h>
-#include <linux/version.h>
#include <linux/mpage.h>
#include "hfsplus_fs.h"
@@ -40,7 +39,7 @@ static sector_t hfsplus_bmap(struct address_space *mapping, sector_t block)
return generic_block_bmap(mapping, block, hfsplus_get_block);
}
-static int hfsplus_releasepage(struct page *page, int mask)
+static int hfsplus_releasepage(struct page *page, gfp_t mask)
{
struct inode *inode = page->mapping->host;
struct super_block *sb = inode->i_sb;
diff --git a/fs/hfsplus/super.c b/fs/hfsplus/super.c
index 452fc1fdbd32..0ce1c455ae55 100644
--- a/fs/hfsplus/super.c
+++ b/fs/hfsplus/super.c
@@ -14,7 +14,6 @@
#include <linux/fs.h>
#include <linux/sched.h>
#include <linux/slab.h>
-#include <linux/version.h>
#include <linux/vfs.h>
#include <linux/nls.h>
diff --git a/fs/hfsplus/wrapper.c b/fs/hfsplus/wrapper.c
index 0c51d6338b0b..95455e839231 100644
--- a/fs/hfsplus/wrapper.c
+++ b/fs/hfsplus/wrapper.c
@@ -12,7 +12,6 @@
#include <linux/blkdev.h>
#include <linux/cdrom.h>
#include <linux/genhd.h>
-#include <linux/version.h>
#include <asm/unaligned.h>
#include "hfsplus_fs.h"
diff --git a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c
index dd7113106269..4684eb7d48c6 100644
--- a/fs/hostfs/hostfs_kern.c
+++ b/fs/hostfs/hostfs_kern.c
@@ -8,7 +8,6 @@
#include <linux/stddef.h>
#include <linux/fs.h>
-#include <linux/version.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
@@ -294,8 +293,7 @@ static void hostfs_delete_inode(struct inode *inode)
static void hostfs_destroy_inode(struct inode *inode)
{
- if(HOSTFS_I(inode)->host_filename)
- kfree(HOSTFS_I(inode)->host_filename);
+ kfree(HOSTFS_I(inode)->host_filename);
/*XXX: This should not happen, probably. The check is here for
* additional safety.*/
diff --git a/fs/hpfs/dnode.c b/fs/hpfs/dnode.c
index 1d21307730a8..229ff2fb1809 100644
--- a/fs/hpfs/dnode.c
+++ b/fs/hpfs/dnode.c
@@ -244,12 +244,12 @@ static int hpfs_add_to_dnode(struct inode *i, dnode_secno dno,
go_up:
if (namelen >= 256) {
hpfs_error(i->i_sb, "hpfs_add_to_dnode: namelen == %d", namelen);
- if (nd) kfree(nd);
+ kfree(nd);
kfree(nname);
return 1;
}
if (!(d = hpfs_map_dnode(i->i_sb, dno, &qbh))) {
- if (nd) kfree(nd);
+ kfree(nd);
kfree(nname);
return 1;
}
@@ -257,7 +257,7 @@ static int hpfs_add_to_dnode(struct inode *i, dnode_secno dno,
if (hpfs_sb(i->i_sb)->sb_chk)
if (hpfs_stop_cycles(i->i_sb, dno, &c1, &c2, "hpfs_add_to_dnode")) {
hpfs_brelse4(&qbh);
- if (nd) kfree(nd);
+ kfree(nd);
kfree(nname);
return 1;
}
@@ -270,7 +270,7 @@ static int hpfs_add_to_dnode(struct inode *i, dnode_secno dno,
for_all_poss(i, hpfs_pos_subst, 5, t + 1);
hpfs_mark_4buffers_dirty(&qbh);
hpfs_brelse4(&qbh);
- if (nd) kfree(nd);
+ kfree(nd);
kfree(nname);
return 0;
}
diff --git a/fs/hpfs/file.c b/fs/hpfs/file.c
index ab144dabd870..7c995ac4081b 100644
--- a/fs/hpfs/file.c
+++ b/fs/hpfs/file.c
@@ -114,11 +114,8 @@ static ssize_t hpfs_file_write(struct file *file, const char __user *buf,
ssize_t retval;
retval = generic_file_write(file, buf, count, ppos);
- if (retval > 0) {
- struct inode *inode = file->f_dentry->d_inode;
- inode->i_mtime = CURRENT_TIME_SEC;
- hpfs_i(inode)->i_dirty = 1;
- }
+ if (retval > 0)
+ hpfs_i(file->f_dentry->d_inode)->i_dirty = 1;
return retval;
}
diff --git a/fs/hpfs/super.c b/fs/hpfs/super.c
index 8eefa6366db7..63e88d7e2c3b 100644
--- a/fs/hpfs/super.c
+++ b/fs/hpfs/super.c
@@ -75,7 +75,7 @@ void hpfs_error(struct super_block *s, char *m,...)
} else if (s->s_flags & MS_RDONLY) printk("; going on - but anything won't be destroyed because it's read-only\n");
else printk("; corrupted filesystem mounted read/write - your computer will explode within 20 seconds ... but you wanted it so!\n");
} else printk("\n");
- if (buf) kfree(buf);
+ kfree(buf);
hpfs_sb(s)->sb_was_error = 1;
}
@@ -102,8 +102,8 @@ 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);
- if (sbi->sb_cp_table) kfree(sbi->sb_cp_table);
- if (sbi->sb_bmp_dir) kfree(sbi->sb_bmp_dir);
+ kfree(sbi->sb_cp_table);
+ kfree(sbi->sb_bmp_dir);
unmark_dirty(s);
s->s_fs_info = NULL;
kfree(sbi);
@@ -654,8 +654,8 @@ bail3: brelse(bh1);
bail2: brelse(bh0);
bail1:
bail0:
- if (sbi->sb_bmp_dir) kfree(sbi->sb_bmp_dir);
- if (sbi->sb_cp_table) kfree(sbi->sb_cp_table);
+ kfree(sbi->sb_bmp_dir);
+ kfree(sbi->sb_cp_table);
s->s_fs_info = NULL;
kfree(sbi);
return -EINVAL;
diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c
index 3a9b6d179cbd..64983ab55586 100644
--- a/fs/hugetlbfs/inode.c
+++ b/fs/hugetlbfs/inode.c
@@ -45,10 +45,58 @@ static struct backing_dev_info hugetlbfs_backing_dev_info = {
int sysctl_hugetlb_shm_group;
+static void huge_pagevec_release(struct pagevec *pvec)
+{
+ int i;
+
+ for (i = 0; i < pagevec_count(pvec); ++i)
+ put_page(pvec->pages[i]);
+
+ pagevec_reinit(pvec);
+}
+
+/*
+ * huge_pages_needed tries to determine the number of new huge pages that
+ * will be required to fully populate this VMA. This will be equal to
+ * the size of the VMA in huge pages minus the number of huge pages
+ * (covered by this VMA) that are found in the page cache.
+ *
+ * Result is in bytes to be compatible with is_hugepage_mem_enough()
+ */
+static unsigned long
+huge_pages_needed(struct address_space *mapping, struct vm_area_struct *vma)
+{
+ int i;
+ struct pagevec pvec;
+ unsigned long start = vma->vm_start;
+ unsigned long end = vma->vm_end;
+ unsigned long hugepages = (end - start) >> HPAGE_SHIFT;
+ pgoff_t next = vma->vm_pgoff;
+ pgoff_t endpg = next + ((end - start) >> PAGE_SHIFT);
+
+ pagevec_init(&pvec, 0);
+ while (next < endpg) {
+ if (!pagevec_lookup(&pvec, mapping, next, PAGEVEC_SIZE))
+ break;
+ for (i = 0; i < pagevec_count(&pvec); i++) {
+ struct page *page = pvec.pages[i];
+ if (page->index > next)
+ next = page->index;
+ if (page->index >= endpg)
+ break;
+ next++;
+ hugepages--;
+ }
+ huge_pagevec_release(&pvec);
+ }
+ return hugepages << HPAGE_SHIFT;
+}
+
static int hugetlbfs_file_mmap(struct file *file, struct vm_area_struct *vma)
{
struct inode *inode = file->f_dentry->d_inode;
struct address_space *mapping = inode->i_mapping;
+ unsigned long bytes;
loff_t len, vma_len;
int ret;
@@ -67,6 +115,10 @@ static int hugetlbfs_file_mmap(struct file *file, struct vm_area_struct *vma)
if (vma->vm_end - vma->vm_start < HPAGE_SIZE)
return -EINVAL;
+ bytes = huge_pages_needed(mapping, vma);
+ if (!is_hugepage_mem_enough(bytes))
+ return -ENOMEM;
+
vma_len = (loff_t)(vma->vm_end - vma->vm_start);
down(&inode->i_sem);
@@ -79,10 +131,8 @@ static int hugetlbfs_file_mmap(struct file *file, struct vm_area_struct *vma)
if (!(vma->vm_flags & VM_WRITE) && len > inode->i_size)
goto out;
- ret = hugetlb_prefault(mapping, vma);
- if (ret)
- goto out;
-
+ ret = 0;
+ hugetlb_prefault_arch_hook(vma->vm_mm);
if (inode->i_size < len)
inode->i_size = len;
out:
@@ -92,7 +142,7 @@ out:
}
/*
- * Called under down_write(mmap_sem), page_table_lock is not held
+ * Called under down_write(mmap_sem).
*/
#ifdef HAVE_ARCH_HUGETLB_UNMAPPED_AREA
@@ -171,16 +221,6 @@ static int hugetlbfs_commit_write(struct file *file,
return -EINVAL;
}
-static void huge_pagevec_release(struct pagevec *pvec)
-{
- int i;
-
- for (i = 0; i < pagevec_count(pvec); ++i)
- put_page(pvec->pages[i]);
-
- pagevec_reinit(pvec);
-}
-
static void truncate_huge_page(struct page *page)
{
clear_page_dirty(page);
@@ -224,52 +264,35 @@ static void truncate_hugepages(struct address_space *mapping, loff_t lstart)
static void hugetlbfs_delete_inode(struct inode *inode)
{
- struct hugetlbfs_sb_info *sbinfo = HUGETLBFS_SB(inode->i_sb);
-
- hlist_del_init(&inode->i_hash);
- list_del_init(&inode->i_list);
- list_del_init(&inode->i_sb_list);
- inode->i_state |= I_FREEING;
- inodes_stat.nr_inodes--;
- spin_unlock(&inode_lock);
-
if (inode->i_data.nrpages)
truncate_hugepages(&inode->i_data, 0);
-
- security_inode_delete(inode);
-
- if (sbinfo->free_inodes >= 0) {
- spin_lock(&sbinfo->stat_lock);
- sbinfo->free_inodes++;
- spin_unlock(&sbinfo->stat_lock);
- }
-
clear_inode(inode);
- destroy_inode(inode);
}
static void hugetlbfs_forget_inode(struct inode *inode)
{
- struct super_block *super_block = inode->i_sb;
- struct hugetlbfs_sb_info *sbinfo = HUGETLBFS_SB(super_block);
+ struct super_block *sb = inode->i_sb;
- if (hlist_unhashed(&inode->i_hash))
- goto out_truncate;
-
- if (!(inode->i_state & (I_DIRTY|I_LOCK))) {
- list_del(&inode->i_list);
- list_add(&inode->i_list, &inode_unused);
- }
- inodes_stat.nr_unused++;
- if (!super_block || (super_block->s_flags & MS_ACTIVE)) {
+ if (!hlist_unhashed(&inode->i_hash)) {
+ if (!(inode->i_state & (I_DIRTY|I_LOCK)))
+ list_move(&inode->i_list, &inode_unused);
+ inodes_stat.nr_unused++;
+ if (!sb || (sb->s_flags & MS_ACTIVE)) {
+ spin_unlock(&inode_lock);
+ return;
+ }
+ inode->i_state |= I_WILL_FREE;
spin_unlock(&inode_lock);
- return;
+ /*
+ * write_inode_now is a noop as we set BDI_CAP_NO_WRITEBACK
+ * in our backing_dev_info.
+ */
+ write_inode_now(inode, 1);
+ spin_lock(&inode_lock);
+ inode->i_state &= ~I_WILL_FREE;
+ inodes_stat.nr_unused--;
+ hlist_del_init(&inode->i_hash);
}
-
- /* write_inode_now() ? */
- inodes_stat.nr_unused--;
- hlist_del_init(&inode->i_hash);
-out_truncate:
list_del_init(&inode->i_list);
list_del_init(&inode->i_sb_list);
inode->i_state |= I_FREEING;
@@ -277,13 +300,6 @@ out_truncate:
spin_unlock(&inode_lock);
if (inode->i_data.nrpages)
truncate_hugepages(&inode->i_data, 0);
-
- if (sbinfo->free_inodes >= 0) {
- spin_lock(&sbinfo->stat_lock);
- sbinfo->free_inodes++;
- spin_unlock(&sbinfo->stat_lock);
- }
-
clear_inode(inode);
destroy_inode(inode);
}
@@ -291,7 +307,7 @@ out_truncate:
static void hugetlbfs_drop_inode(struct inode *inode)
{
if (!inode->i_nlink)
- hugetlbfs_delete_inode(inode);
+ generic_delete_inode(inode);
else
hugetlbfs_forget_inode(inode);
}
@@ -308,7 +324,6 @@ hugetlb_vmtruncate_list(struct prio_tree_root *root, unsigned long h_pgoff)
vma_prio_tree_foreach(vma, &iter, root, h_pgoff, ULONG_MAX) {
unsigned long h_vm_pgoff;
- unsigned long v_length;
unsigned long v_offset;
h_vm_pgoff = vma->vm_pgoff >> (HPAGE_SHIFT - PAGE_SHIFT);
@@ -319,11 +334,8 @@ hugetlb_vmtruncate_list(struct prio_tree_root *root, unsigned long h_pgoff)
if (h_vm_pgoff >= h_pgoff)
v_offset = 0;
- v_length = vma->vm_end - vma->vm_start;
-
- zap_hugepage_range(vma,
- vma->vm_start + v_offset,
- v_length - v_offset);
+ unmap_hugepage_range(vma,
+ vma->vm_start + v_offset, vma->vm_end);
}
}
@@ -379,17 +391,6 @@ static struct inode *hugetlbfs_get_inode(struct super_block *sb, uid_t uid,
gid_t gid, int mode, dev_t dev)
{
struct inode *inode;
- struct hugetlbfs_sb_info *sbinfo = HUGETLBFS_SB(sb);
-
- if (sbinfo->free_inodes >= 0) {
- spin_lock(&sbinfo->stat_lock);
- if (!sbinfo->free_inodes) {
- spin_unlock(&sbinfo->stat_lock);
- return NULL;
- }
- sbinfo->free_inodes--;
- spin_unlock(&sbinfo->stat_lock);
- }
inode = new_inode(sb);
if (inode) {
@@ -531,29 +532,51 @@ static void hugetlbfs_put_super(struct super_block *sb)
}
}
+static inline int hugetlbfs_dec_free_inodes(struct hugetlbfs_sb_info *sbinfo)
+{
+ if (sbinfo->free_inodes >= 0) {
+ spin_lock(&sbinfo->stat_lock);
+ if (unlikely(!sbinfo->free_inodes)) {
+ spin_unlock(&sbinfo->stat_lock);
+ return 0;
+ }
+ sbinfo->free_inodes--;
+ spin_unlock(&sbinfo->stat_lock);
+ }
+
+ return 1;
+}
+
+static void hugetlbfs_inc_free_inodes(struct hugetlbfs_sb_info *sbinfo)
+{
+ if (sbinfo->free_inodes >= 0) {
+ spin_lock(&sbinfo->stat_lock);
+ sbinfo->free_inodes++;
+ spin_unlock(&sbinfo->stat_lock);
+ }
+}
+
+
static kmem_cache_t *hugetlbfs_inode_cachep;
static struct inode *hugetlbfs_alloc_inode(struct super_block *sb)
{
+ struct hugetlbfs_sb_info *sbinfo = HUGETLBFS_SB(sb);
struct hugetlbfs_inode_info *p;
+ if (unlikely(!hugetlbfs_dec_free_inodes(sbinfo)))
+ return NULL;
p = kmem_cache_alloc(hugetlbfs_inode_cachep, SLAB_KERNEL);
- if (!p)
+ if (unlikely(!p)) {
+ hugetlbfs_inc_free_inodes(sbinfo);
return NULL;
+ }
return &p->vfs_inode;
}
-static void init_once(void *foo, kmem_cache_t *cachep, unsigned long flags)
-{
- struct hugetlbfs_inode_info *ei = (struct hugetlbfs_inode_info *)foo;
-
- if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
- SLAB_CTOR_CONSTRUCTOR)
- inode_init_once(&ei->vfs_inode);
-}
-
static void hugetlbfs_destroy_inode(struct inode *inode)
{
+ hugetlbfs_inc_free_inodes(HUGETLBFS_SB(inode->i_sb));
mpol_free_shared_policy(&HUGETLBFS_I(inode)->policy);
kmem_cache_free(hugetlbfs_inode_cachep, HUGETLBFS_I(inode));
}
@@ -565,6 +588,16 @@ static struct address_space_operations hugetlbfs_aops = {
.set_page_dirty = hugetlbfs_set_page_dirty,
};
+
+static void init_once(void *foo, kmem_cache_t *cachep, unsigned long flags)
+{
+ struct hugetlbfs_inode_info *ei = (struct hugetlbfs_inode_info *)foo;
+
+ if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
+ SLAB_CTOR_CONSTRUCTOR)
+ inode_init_once(&ei->vfs_inode);
+}
+
struct file_operations hugetlbfs_file_operations = {
.mmap = hugetlbfs_file_mmap,
.fsync = simple_sync_file,
@@ -592,6 +625,7 @@ static struct super_operations hugetlbfs_ops = {
.alloc_inode = hugetlbfs_alloc_inode,
.destroy_inode = hugetlbfs_destroy_inode,
.statfs = hugetlbfs_statfs,
+ .delete_inode = hugetlbfs_delete_inode,
.drop_inode = hugetlbfs_drop_inode,
.put_super = hugetlbfs_put_super,
};
diff --git a/fs/inode.c b/fs/inode.c
index f80a79ff156b..d8d04bd72b59 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -475,7 +475,7 @@ static void prune_icache(int nr_to_scan)
* This function is passed the number of inodes to scan, and it returns the
* total number of remaining possibly-reclaimable inodes.
*/
-static int shrink_icache_memory(int nr, unsigned int gfp_mask)
+static int shrink_icache_memory(int nr, gfp_t gfp_mask)
{
if (nr) {
/*
@@ -1088,6 +1088,7 @@ static void generic_forget_inode(struct inode *inode)
if (inode->i_data.nrpages)
truncate_inode_pages(&inode->i_data, 0);
clear_inode(inode);
+ wake_up_inode(inode);
destroy_inode(inode);
}
diff --git a/fs/inotify.c b/fs/inotify.c
index 9fbaebfdf40b..bf7ce1d2412b 100644
--- a/fs/inotify.c
+++ b/fs/inotify.c
@@ -372,7 +372,7 @@ static int find_inode(const char __user *dirname, struct nameidata *nd)
if (error)
return error;
/* you can only watch an inode if you have read permissions on it */
- error = permission(nd->dentry->d_inode, MAY_READ, NULL);
+ error = vfs_permission(nd, MAY_READ);
if (error)
path_release(nd);
return error;
diff --git a/fs/isofs/inode.c b/fs/isofs/inode.c
index 1652de1b6cb9..298f08be22d4 100644
--- a/fs/isofs/inode.c
+++ b/fs/isofs/inode.c
@@ -855,8 +855,7 @@ root_found:
if (opt.check == 'r') table++;
s->s_root->d_op = &isofs_dentry_ops[table];
- if (opt.iocharset)
- kfree(opt.iocharset);
+ kfree(opt.iocharset);
return 0;
@@ -895,8 +894,7 @@ out_unknown_format:
out_freebh:
brelse(bh);
out_freesbi:
- if (opt.iocharset)
- kfree(opt.iocharset);
+ kfree(opt.iocharset);
kfree(sbi);
s->s_fs_info = NULL;
return -EINVAL;
@@ -1164,8 +1162,7 @@ out_nomem:
out_noread:
printk(KERN_INFO "ISOFS: unable to read i-node block %lu\n", block);
- if (tmpde)
- kfree(tmpde);
+ kfree(tmpde);
return -EIO;
out_toomany:
@@ -1334,8 +1331,7 @@ static void isofs_read_inode(struct inode *inode)
init_special_inode(inode, inode->i_mode, inode->i_rdev);
out:
- if (tmpde)
- kfree(tmpde);
+ kfree(tmpde);
if (bh)
brelse(bh);
return;
diff --git a/fs/jbd/commit.c b/fs/jbd/commit.c
index 2a3e310f79ef..002ad2bbc769 100644
--- a/fs/jbd/commit.c
+++ b/fs/jbd/commit.c
@@ -261,10 +261,8 @@ void journal_commit_transaction(journal_t *journal)
struct buffer_head *bh = jh2bh(jh);
jbd_lock_bh_state(bh);
- if (jh->b_committed_data) {
- kfree(jh->b_committed_data);
- jh->b_committed_data = NULL;
- }
+ kfree(jh->b_committed_data);
+ jh->b_committed_data = NULL;
jbd_unlock_bh_state(bh);
}
journal_refile_buffer(journal, jh);
diff --git a/fs/jbd/journal.c b/fs/jbd/journal.c
index 7ae2c4fe506b..e4b516ac4989 100644
--- a/fs/jbd/journal.c
+++ b/fs/jbd/journal.c
@@ -1606,7 +1606,7 @@ int journal_blocks_per_page(struct inode *inode)
* Simple support for retrying memory allocations. Introduced to help to
* debug different VM deadlock avoidance strategies.
*/
-void * __jbd_kmalloc (const char *where, size_t size, int flags, int retry)
+void * __jbd_kmalloc (const char *where, size_t size, gfp_t flags, int retry)
{
return kmalloc(size, flags | (retry ? __GFP_NOFAIL : 0));
}
diff --git a/fs/jbd/recovery.c b/fs/jbd/recovery.c
index 103c34e4fb28..80d7f53fd0a7 100644
--- a/fs/jbd/recovery.c
+++ b/fs/jbd/recovery.c
@@ -210,7 +210,7 @@ do { \
} while (0)
/**
- * int journal_recover(journal_t *journal) - recovers a on-disk journal
+ * journal_recover - recovers a on-disk journal
* @journal: the journal to recover
*
* The primary function for recovering the log contents when mounting a
@@ -266,7 +266,7 @@ int journal_recover(journal_t *journal)
}
/**
- * int journal_skip_recovery() - Start journal and wipe exiting records
+ * journal_skip_recovery - Start journal and wipe exiting records
* @journal: journal to startup
*
* Locate any valid recovery information from the journal and set up the
diff --git a/fs/jbd/transaction.c b/fs/jbd/transaction.c
index 49bbc2be3d72..429f4b263cf1 100644
--- a/fs/jbd/transaction.c
+++ b/fs/jbd/transaction.c
@@ -227,8 +227,7 @@ repeat_locked:
spin_unlock(&transaction->t_handle_lock);
spin_unlock(&journal->j_state_lock);
out:
- if (new_transaction)
- kfree(new_transaction);
+ kfree(new_transaction);
return ret;
}
@@ -725,8 +724,7 @@ done:
journal_cancel_revoke(handle, jh);
out:
- if (frozen_buffer)
- kfree(frozen_buffer);
+ kfree(frozen_buffer);
JBUFFER_TRACE(jh, "exit");
return error;
@@ -905,8 +903,7 @@ repeat:
jbd_unlock_bh_state(bh);
out:
journal_put_journal_head(jh);
- if (committed_data)
- kfree(committed_data);
+ kfree(committed_data);
return err;
}
@@ -1621,7 +1618,7 @@ out:
* while the data is part of a transaction. Yes?
*/
int journal_try_to_free_buffers(journal_t *journal,
- struct page *page, int unused_gfp_mask)
+ struct page *page, gfp_t unused_gfp_mask)
{
struct buffer_head *head;
struct buffer_head *bh;
diff --git a/fs/jffs/intrep.c b/fs/jffs/intrep.c
index 27f199e94cfc..b2e95421d932 100644
--- a/fs/jffs/intrep.c
+++ b/fs/jffs/intrep.c
@@ -462,7 +462,7 @@ jffs_checksum_flash(struct mtd_info *mtd, loff_t start, int size, __u32 *result)
}
/* Free read buffer */
- kfree (read_buf);
+ kfree(read_buf);
/* Return result */
D3(printk("checksum result: 0x%08x\n", sum));
@@ -1011,12 +1011,12 @@ jffs_scan_flash(struct jffs_control *c)
offset , fmc->sector_size);
flash_safe_release(fmc->mtd);
- kfree (read_buf);
+ kfree(read_buf);
return -1; /* bad, bad, bad! */
}
flash_safe_release(fmc->mtd);
- kfree (read_buf);
+ kfree(read_buf);
return -EAGAIN; /* erased offending sector. Try mount one more time please. */
}
@@ -1112,7 +1112,7 @@ jffs_scan_flash(struct jffs_control *c)
if (!node) {
if (!(node = jffs_alloc_node())) {
/* Free read buffer */
- kfree (read_buf);
+ kfree(read_buf);
/* Release the flash device */
flash_safe_release(fmc->mtd);
@@ -1269,7 +1269,7 @@ jffs_scan_flash(struct jffs_control *c)
DJM(no_jffs_node--);
/* Free read buffer */
- kfree (read_buf);
+ kfree(read_buf);
/* Release the flash device */
flash_safe_release(fmc->mtd);
@@ -1296,7 +1296,7 @@ jffs_scan_flash(struct jffs_control *c)
flash_safe_release(fmc->flash_part);
/* Free read buffer */
- kfree (read_buf);
+ kfree(read_buf);
return -ENOMEM;
}
@@ -1324,7 +1324,7 @@ jffs_scan_flash(struct jffs_control *c)
jffs_build_end(fmc);
/* Free read buffer */
- kfree (read_buf);
+ kfree(read_buf);
if(!num_free_space){
printk(KERN_WARNING "jffs_scan_flash(): Did not find even a single "
@@ -1747,9 +1747,7 @@ jffs_find_child(struct jffs_file *dir, const char *name, int len)
}
printk("jffs_find_child(): Didn't find the file \"%s\".\n",
(copy ? copy : ""));
- if (copy) {
- kfree(copy);
- }
+ kfree(copy);
});
return f;
diff --git a/fs/jffs2/Makefile b/fs/jffs2/Makefile
index f1afe681ecd6..77dc5561a04e 100644
--- a/fs/jffs2/Makefile
+++ b/fs/jffs2/Makefile
@@ -1,7 +1,7 @@
#
# Makefile for the Linux Journalling Flash File System v2 (JFFS2)
#
-# $Id: Makefile.common,v 1.9 2005/02/09 09:23:53 pavlov Exp $
+# $Id: Makefile.common,v 1.11 2005/09/07 08:34:53 havasi Exp $
#
obj-$(CONFIG_JFFS2_FS) += jffs2.o
@@ -9,9 +9,10 @@ obj-$(CONFIG_JFFS2_FS) += jffs2.o
jffs2-y := compr.o dir.o file.o ioctl.o nodelist.o malloc.o
jffs2-y += read.o nodemgmt.o readinode.o write.o scan.o gc.o
jffs2-y += symlink.o build.o erase.o background.o fs.o writev.o
-jffs2-y += super.o
+jffs2-y += super.o debug.o
jffs2-$(CONFIG_JFFS2_FS_WRITEBUFFER) += wbuf.o
jffs2-$(CONFIG_JFFS2_RUBIN) += compr_rubin.o
jffs2-$(CONFIG_JFFS2_RTIME) += compr_rtime.o
jffs2-$(CONFIG_JFFS2_ZLIB) += compr_zlib.o
+jffs2-$(CONFIG_JFFS2_SUMMARY) += summary.o
diff --git a/fs/jffs2/TODO b/fs/jffs2/TODO
index 2bff82fd221f..d0e23b26fa50 100644
--- a/fs/jffs2/TODO
+++ b/fs/jffs2/TODO
@@ -1,5 +1,11 @@
-$Id: TODO,v 1.10 2002/09/09 16:31:21 dwmw2 Exp $
+$Id: TODO,v 1.18 2005/09/22 11:24:56 dedekind Exp $
+ - support asynchronous operation -- add a per-fs 'reserved_space' count,
+ let each outstanding write reserve the _maximum_ amount of physical
+ space it could take. Let GC flush the outstanding writes because the
+ reservations will necessarily be pessimistic. With this we could even
+ do shared writable mmap, if we can have a fs hook for do_wp_page() to
+ make the reservation.
- disable compression in commit_write()?
- fine-tune the allocation / GC thresholds
- chattr support - turning on/off and tuning compression per-inode
@@ -11,26 +17,15 @@ $Id: TODO,v 1.10 2002/09/09 16:31:21 dwmw2 Exp $
- test, test, test
- NAND flash support:
- - flush_wbuf using GC to fill it, don't just pad.
- - Deal with write errors. Data don't get lost - we just have to write
- the affected node(s) out again somewhere else.
- - make fsync flush only if actually required
- - make sys_sync() work.
- - reboot notifier
- - timed flush of old wbuf
- - fix magical second arg of jffs2_flush_wbuf(). Split into two or more functions instead.
-
+ - almost done :)
+ - use bad block check instead of the hardwired byte check
- Optimisations:
- - Stop GC from decompressing and immediately recompressing nodes which could
- just be copied intact. (We now keep track of REF_PRISTINE flag. Easy now.)
- - Furthermore, in the case where it could be copied intact we don't even need
- to call iget() for it -- if we use (raw_node_raw->flash_offset & 2) as a flag
- to show a node can be copied intact and it's _not_ in icache, we could just do
- it, fix up the next_in_ino list and move on. We would need a way to find out
- _whether_ it's in icache though -- if it's in icache we also need to do the
- fragment lists, etc. P'raps a flag or pointer in the jffs2_inode_cache could
- help. (We have half of this now.)
+ - Split writes so they go to two separate blocks rather than just c->nextblock.
+ By writing _new_ nodes to one block, and garbage-collected REF_PRISTINE
+ nodes to a different one, we can separate clean nodes from those which
+ are likely to become dirty, and end up with blocks which are each far
+ closer to 100% or 0% clean, hence speeding up later GC progress dramatically.
- Stop keeping name in-core with struct jffs2_full_dirent. If we keep the hash in
the full dirent, we only need to go to the flash in lookup() when we think we've
got a match, and in readdir().
@@ -38,3 +33,8 @@ $Id: TODO,v 1.10 2002/09/09 16:31:21 dwmw2 Exp $
- Remove totlen from jffs2_raw_node_ref? Need to have totlen passed into
jffs2_mark_node_obsolete(). Can all callers work it out?
- Remove size from jffs2_raw_node_frag.
+
+dedekind:
+1. __jffs2_flush_wbuf() has a strange 'pad' parameter. Eliminate.
+2. get_sb()->build_fs()->scan() path... Why get_sb() removes scan()'s crap in
+ case of failure? scan() does not clean everything. Fix.
diff --git a/fs/jffs2/background.c b/fs/jffs2/background.c
index 0f224384f176..7b77a9541125 100644
--- a/fs/jffs2/background.c
+++ b/fs/jffs2/background.c
@@ -15,6 +15,7 @@
#include <linux/jffs2.h>
#include <linux/mtd/mtd.h>
#include <linux/completion.h>
+#include <linux/sched.h>
#include "nodelist.h"
@@ -50,7 +51,7 @@ int jffs2_start_garbage_collect_thread(struct jffs2_sb_info *c)
D1(printk(KERN_DEBUG "JFFS2: Garbage collect thread is pid %d\n", pid));
wait_for_completion(&c->gc_thread_start);
}
-
+
return ret;
}
@@ -100,7 +101,7 @@ static int jffs2_garbage_collect_thread(void *_c)
cond_resched();
- /* Put_super will send a SIGKILL and then wait on the sem.
+ /* Put_super will send a SIGKILL and then wait on the sem.
*/
while (signal_pending(current)) {
siginfo_t info;
diff --git a/fs/jffs2/build.c b/fs/jffs2/build.c
index 97dc39796e2c..fff108bb118b 100644
--- a/fs/jffs2/build.c
+++ b/fs/jffs2/build.c
@@ -7,7 +7,7 @@
*
* For licensing information, see the file 'LICENCE' in this directory.
*
- * $Id: build.c,v 1.71 2005/07/12 16:37:08 dedekind Exp $
+ * $Id: build.c,v 1.85 2005/11/07 11:14:38 gleixner Exp $
*
*/
@@ -18,7 +18,8 @@
#include <linux/mtd/mtd.h>
#include "nodelist.h"
-static void jffs2_build_remove_unlinked_inode(struct jffs2_sb_info *, struct jffs2_inode_cache *, struct jffs2_full_dirent **);
+static void jffs2_build_remove_unlinked_inode(struct jffs2_sb_info *,
+ struct jffs2_inode_cache *, struct jffs2_full_dirent **);
static inline struct jffs2_inode_cache *
first_inode_chain(int *i, struct jffs2_sb_info *c)
@@ -46,11 +47,12 @@ next_inode(int *i, struct jffs2_inode_cache *ic, struct jffs2_sb_info *c)
ic = next_inode(&i, ic, (c)))
-static inline void jffs2_build_inode_pass1(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic)
+static inline void jffs2_build_inode_pass1(struct jffs2_sb_info *c,
+ struct jffs2_inode_cache *ic)
{
struct jffs2_full_dirent *fd;
- D1(printk(KERN_DEBUG "jffs2_build_inode building directory inode #%u\n", ic->ino));
+ dbg_fsbuild("building directory inode #%u\n", ic->ino);
/* For each child, increase nlink */
for(fd = ic->scan_dents; fd; fd = fd->next) {
@@ -58,26 +60,23 @@ static inline void jffs2_build_inode_pass1(struct jffs2_sb_info *c, struct jffs2
if (!fd->ino)
continue;
- /* XXX: Can get high latency here with huge directories */
+ /* we can get high latency here with huge directories */
child_ic = jffs2_get_ino_cache(c, fd->ino);
if (!child_ic) {
- printk(KERN_NOTICE "Eep. Child \"%s\" (ino #%u) of dir ino #%u doesn't exist!\n",
+ dbg_fsbuild("child \"%s\" (ino #%u) of dir ino #%u doesn't exist!\n",
fd->name, fd->ino, ic->ino);
jffs2_mark_node_obsolete(c, fd->raw);
continue;
}
if (child_ic->nlink++ && fd->type == DT_DIR) {
- printk(KERN_NOTICE "Child dir \"%s\" (ino #%u) of dir ino #%u appears to be a hard link\n", fd->name, fd->ino, ic->ino);
- if (fd->ino == 1 && ic->ino == 1) {
- printk(KERN_NOTICE "This is mostly harmless, and probably caused by creating a JFFS2 image\n");
- printk(KERN_NOTICE "using a buggy version of mkfs.jffs2. Use at least v1.17.\n");
- }
- /* What do we do about it? */
+ JFFS2_ERROR("child dir \"%s\" (ino #%u) of dir ino #%u appears to be a hard link\n",
+ fd->name, fd->ino, ic->ino);
+ /* TODO: What do we do about it? */
}
- D1(printk(KERN_DEBUG "Increased nlink for child \"%s\" (ino #%u)\n", fd->name, fd->ino));
- /* Can't free them. We might need them in pass 2 */
+ dbg_fsbuild("increased nlink for child \"%s\" (ino #%u)\n", fd->name, fd->ino);
+ /* Can't free scan_dents so far. We might need them in pass 2 */
}
}
@@ -94,6 +93,8 @@ static int jffs2_build_filesystem(struct jffs2_sb_info *c)
struct jffs2_full_dirent *fd;
struct jffs2_full_dirent *dead_fds = NULL;
+ dbg_fsbuild("build FS data structures\n");
+
/* First, scan the medium and build all the inode caches with
lists of physical nodes */
@@ -103,60 +104,54 @@ static int jffs2_build_filesystem(struct jffs2_sb_info *c)
if (ret)
goto exit;
- D1(printk(KERN_DEBUG "Scanned flash completely\n"));
- D2(jffs2_dump_block_lists(c));
+ dbg_fsbuild("scanned flash completely\n");
+ jffs2_dbg_dump_block_lists_nolock(c);
+ dbg_fsbuild("pass 1 starting\n");
c->flags |= JFFS2_SB_FLAG_BUILDING;
/* Now scan the directory tree, increasing nlink according to every dirent found. */
for_each_inode(i, c, ic) {
- D1(printk(KERN_DEBUG "Pass 1: ino #%u\n", ic->ino));
-
- D1(BUG_ON(ic->ino > c->highest_ino));
-
if (ic->scan_dents) {
jffs2_build_inode_pass1(c, ic);
cond_resched();
}
}
- D1(printk(KERN_DEBUG "Pass 1 complete\n"));
+ dbg_fsbuild("pass 1 complete\n");
/* Next, scan for inodes with nlink == 0 and remove them. If
they were directories, then decrement the nlink of their
children too, and repeat the scan. As that's going to be
a fairly uncommon occurrence, it's not so evil to do it this
way. Recursion bad. */
- D1(printk(KERN_DEBUG "Pass 2 starting\n"));
+ dbg_fsbuild("pass 2 starting\n");
for_each_inode(i, c, ic) {
- D1(printk(KERN_DEBUG "Pass 2: ino #%u, nlink %d, ic %p, nodes %p\n", ic->ino, ic->nlink, ic, ic->nodes));
if (ic->nlink)
continue;
-
+
jffs2_build_remove_unlinked_inode(c, ic, &dead_fds);
cond_resched();
- }
+ }
- D1(printk(KERN_DEBUG "Pass 2a starting\n"));
+ dbg_fsbuild("pass 2a starting\n");
while (dead_fds) {
fd = dead_fds;
dead_fds = fd->next;
ic = jffs2_get_ino_cache(c, fd->ino);
- D1(printk(KERN_DEBUG "Removing dead_fd ino #%u (\"%s\"), ic at %p\n", fd->ino, fd->name, ic));
if (ic)
jffs2_build_remove_unlinked_inode(c, ic, &dead_fds);
jffs2_free_full_dirent(fd);
}
- D1(printk(KERN_DEBUG "Pass 2 complete\n"));
-
+ dbg_fsbuild("pass 2a complete\n");
+ dbg_fsbuild("freeing temporary data structures\n");
+
/* Finally, we can scan again and free the dirent structs */
for_each_inode(i, c, ic) {
- D1(printk(KERN_DEBUG "Pass 3: ino #%u, ic %p, nodes %p\n", ic->ino, ic, ic->nodes));
-
while(ic->scan_dents) {
fd = ic->scan_dents;
ic->scan_dents = fd->next;
@@ -166,9 +161,8 @@ static int jffs2_build_filesystem(struct jffs2_sb_info *c)
cond_resched();
}
c->flags &= ~JFFS2_SB_FLAG_BUILDING;
-
- D1(printk(KERN_DEBUG "Pass 3 complete\n"));
- D2(jffs2_dump_block_lists(c));
+
+ dbg_fsbuild("FS build complete\n");
/* Rotate the lists by some number to ensure wear levelling */
jffs2_rotate_lists(c);
@@ -189,24 +183,26 @@ exit:
return ret;
}
-static void jffs2_build_remove_unlinked_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic, struct jffs2_full_dirent **dead_fds)
+static void jffs2_build_remove_unlinked_inode(struct jffs2_sb_info *c,
+ struct jffs2_inode_cache *ic,
+ struct jffs2_full_dirent **dead_fds)
{
struct jffs2_raw_node_ref *raw;
struct jffs2_full_dirent *fd;
- D1(printk(KERN_DEBUG "JFFS2: Removing ino #%u with nlink == zero.\n", ic->ino));
-
+ dbg_fsbuild("removing ino #%u with nlink == zero.\n", ic->ino);
+
raw = ic->nodes;
while (raw != (void *)ic) {
struct jffs2_raw_node_ref *next = raw->next_in_ino;
- D1(printk(KERN_DEBUG "obsoleting node at 0x%08x\n", ref_offset(raw)));
+ dbg_fsbuild("obsoleting node at 0x%08x\n", ref_offset(raw));
jffs2_mark_node_obsolete(c, raw);
raw = next;
}
if (ic->scan_dents) {
int whinged = 0;
- D1(printk(KERN_DEBUG "Inode #%u was a directory which may have children...\n", ic->ino));
+ dbg_fsbuild("inode #%u was a directory which may have children...\n", ic->ino);
while(ic->scan_dents) {
struct jffs2_inode_cache *child_ic;
@@ -216,45 +212,43 @@ static void jffs2_build_remove_unlinked_inode(struct jffs2_sb_info *c, struct jf
if (!fd->ino) {
/* It's a deletion dirent. Ignore it */
- D1(printk(KERN_DEBUG "Child \"%s\" is a deletion dirent, skipping...\n", fd->name));
+ dbg_fsbuild("child \"%s\" is a deletion dirent, skipping...\n", fd->name);
jffs2_free_full_dirent(fd);
continue;
}
- if (!whinged) {
+ if (!whinged)
whinged = 1;
- printk(KERN_NOTICE "Inode #%u was a directory with children - removing those too...\n", ic->ino);
- }
- D1(printk(KERN_DEBUG "Removing child \"%s\", ino #%u\n",
- fd->name, fd->ino));
-
+ dbg_fsbuild("removing child \"%s\", ino #%u\n", fd->name, fd->ino);
+
child_ic = jffs2_get_ino_cache(c, fd->ino);
if (!child_ic) {
- printk(KERN_NOTICE "Cannot remove child \"%s\", ino #%u, because it doesn't exist\n", fd->name, fd->ino);
+ dbg_fsbuild("cannot remove child \"%s\", ino #%u, because it doesn't exist\n",
+ fd->name, fd->ino);
jffs2_free_full_dirent(fd);
continue;
}
- /* Reduce nlink of the child. If it's now zero, stick it on the
+ /* Reduce nlink of the child. If it's now zero, stick it on the
dead_fds list to be cleaned up later. Else just free the fd */
child_ic->nlink--;
-
+
if (!child_ic->nlink) {
- D1(printk(KERN_DEBUG "Inode #%u (\"%s\") has now got zero nlink. Adding to dead_fds list.\n",
- fd->ino, fd->name));
+ dbg_fsbuild("inode #%u (\"%s\") has now got zero nlink, adding to dead_fds list.\n",
+ fd->ino, fd->name);
fd->next = *dead_fds;
*dead_fds = fd;
} else {
- D1(printk(KERN_DEBUG "Inode #%u (\"%s\") has now got nlink %d. Ignoring.\n",
- fd->ino, fd->name, child_ic->nlink));
+ dbg_fsbuild("inode #%u (\"%s\") has now got nlink %d. Ignoring.\n",
+ fd->ino, fd->name, child_ic->nlink);
jffs2_free_full_dirent(fd);
}
}
}
/*
- We don't delete the inocache from the hash list and free it yet.
+ We don't delete the inocache from the hash list and free it yet.
The erase code will do that, when all the nodes are completely gone.
*/
}
@@ -268,7 +262,7 @@ static void jffs2_calc_trigger_levels(struct jffs2_sb_info *c)
because there's not enough free space... */
c->resv_blocks_deletion = 2;
- /* Be conservative about how much space we need before we allow writes.
+ /* Be conservative about how much space we need before we allow writes.
On top of that which is required for deletia, require an extra 2%
of the medium to be available, for overhead caused by nodes being
split across blocks, etc. */
@@ -283,7 +277,7 @@ static void jffs2_calc_trigger_levels(struct jffs2_sb_info *c)
c->resv_blocks_gctrigger = c->resv_blocks_write + 1;
- /* When do we allow garbage collection to merge nodes to make
+ /* When do we allow garbage collection to merge nodes to make
long-term progress at the expense of short-term space exhaustion? */
c->resv_blocks_gcmerge = c->resv_blocks_deletion + 1;
@@ -295,45 +289,45 @@ static void jffs2_calc_trigger_levels(struct jffs2_sb_info *c)
trying to GC to make more space. It'll be a fruitless task */
c->nospc_dirty_size = c->sector_size + (c->flash_size / 100);
- D1(printk(KERN_DEBUG "JFFS2 trigger levels (size %d KiB, block size %d KiB, %d blocks)\n",
- c->flash_size / 1024, c->sector_size / 1024, c->nr_blocks));
- D1(printk(KERN_DEBUG "Blocks required to allow deletion: %d (%d KiB)\n",
- c->resv_blocks_deletion, c->resv_blocks_deletion*c->sector_size/1024));
- D1(printk(KERN_DEBUG "Blocks required to allow writes: %d (%d KiB)\n",
- c->resv_blocks_write, c->resv_blocks_write*c->sector_size/1024));
- D1(printk(KERN_DEBUG "Blocks required to quiesce GC thread: %d (%d KiB)\n",
- c->resv_blocks_gctrigger, c->resv_blocks_gctrigger*c->sector_size/1024));
- D1(printk(KERN_DEBUG "Blocks required to allow GC merges: %d (%d KiB)\n",
- c->resv_blocks_gcmerge, c->resv_blocks_gcmerge*c->sector_size/1024));
- D1(printk(KERN_DEBUG "Blocks required to GC bad blocks: %d (%d KiB)\n",
- c->resv_blocks_gcbad, c->resv_blocks_gcbad*c->sector_size/1024));
- D1(printk(KERN_DEBUG "Amount of dirty space required to GC: %d bytes\n",
- c->nospc_dirty_size));
-}
+ dbg_fsbuild("JFFS2 trigger levels (size %d KiB, block size %d KiB, %d blocks)\n",
+ c->flash_size / 1024, c->sector_size / 1024, c->nr_blocks);
+ dbg_fsbuild("Blocks required to allow deletion: %d (%d KiB)\n",
+ c->resv_blocks_deletion, c->resv_blocks_deletion*c->sector_size/1024);
+ dbg_fsbuild("Blocks required to allow writes: %d (%d KiB)\n",
+ c->resv_blocks_write, c->resv_blocks_write*c->sector_size/1024);
+ dbg_fsbuild("Blocks required to quiesce GC thread: %d (%d KiB)\n",
+ c->resv_blocks_gctrigger, c->resv_blocks_gctrigger*c->sector_size/1024);
+ dbg_fsbuild("Blocks required to allow GC merges: %d (%d KiB)\n",
+ c->resv_blocks_gcmerge, c->resv_blocks_gcmerge*c->sector_size/1024);
+ dbg_fsbuild("Blocks required to GC bad blocks: %d (%d KiB)\n",
+ c->resv_blocks_gcbad, c->resv_blocks_gcbad*c->sector_size/1024);
+ dbg_fsbuild("Amount of dirty space required to GC: %d bytes\n",
+ c->nospc_dirty_size);
+}
int jffs2_do_mount_fs(struct jffs2_sb_info *c)
{
+ int ret;
int i;
+ int size;
c->free_size = c->flash_size;
c->nr_blocks = c->flash_size / c->sector_size;
- if (c->mtd->flags & MTD_NO_VIRTBLOCKS)
- c->blocks = vmalloc(sizeof(struct jffs2_eraseblock) * c->nr_blocks);
+ size = sizeof(struct jffs2_eraseblock) * c->nr_blocks;
+#ifndef __ECOS
+ if (jffs2_blocks_use_vmalloc(c))
+ c->blocks = vmalloc(size);
else
- c->blocks = kmalloc(sizeof(struct jffs2_eraseblock) * c->nr_blocks, GFP_KERNEL);
+#endif
+ c->blocks = kmalloc(size, GFP_KERNEL);
if (!c->blocks)
return -ENOMEM;
+
+ memset(c->blocks, 0, size);
for (i=0; i<c->nr_blocks; i++) {
INIT_LIST_HEAD(&c->blocks[i].list);
c->blocks[i].offset = i * c->sector_size;
c->blocks[i].free_size = c->sector_size;
- c->blocks[i].dirty_size = 0;
- c->blocks[i].wasted_size = 0;
- c->blocks[i].unchecked_size = 0;
- c->blocks[i].used_size = 0;
- c->blocks[i].first_node = NULL;
- c->blocks[i].last_node = NULL;
- c->blocks[i].bad_count = 0;
}
INIT_LIST_HEAD(&c->clean_list);
@@ -348,16 +342,23 @@ int jffs2_do_mount_fs(struct jffs2_sb_info *c)
INIT_LIST_HEAD(&c->bad_list);
INIT_LIST_HEAD(&c->bad_used_list);
c->highest_ino = 1;
+ c->summary = NULL;
+
+ ret = jffs2_sum_init(c);
+ if (ret)
+ return ret;
if (jffs2_build_filesystem(c)) {
- D1(printk(KERN_DEBUG "build_fs failed\n"));
+ dbg_fsbuild("build_fs failed\n");
jffs2_free_ino_caches(c);
jffs2_free_raw_node_refs(c);
- if (c->mtd->flags & MTD_NO_VIRTBLOCKS) {
+#ifndef __ECOS
+ if (jffs2_blocks_use_vmalloc(c))
vfree(c->blocks);
- } else {
+ else
+#endif
kfree(c->blocks);
- }
+
return -EIO;
}
diff --git a/fs/jffs2/compr.c b/fs/jffs2/compr.c
index af922a9618ac..e7944e665b9f 100644
--- a/fs/jffs2/compr.c
+++ b/fs/jffs2/compr.c
@@ -9,7 +9,7 @@
*
* For licensing information, see the file 'LICENCE' in this directory.
*
- * $Id: compr.c,v 1.42 2004/08/07 21:56:08 dwmw2 Exp $
+ * $Id: compr.c,v 1.46 2005/11/07 11:14:38 gleixner Exp $
*
*/
@@ -36,16 +36,16 @@ static uint32_t none_stat_compr_blocks=0,none_stat_decompr_blocks=0,none_stat_co
* data.
*
* Returns: Lower byte to be stored with data indicating compression type used.
- * Zero is used to show that the data could not be compressed - the
+ * Zero is used to show that the data could not be compressed - the
* compressed version was actually larger than the original.
* Upper byte will be used later. (soon)
*
* If the cdata buffer isn't large enough to hold all the uncompressed data,
- * jffs2_compress should compress as much as will fit, and should set
+ * jffs2_compress should compress as much as will fit, and should set
* *datalen accordingly to show the amount of data which were compressed.
*/
uint16_t jffs2_compress(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
- unsigned char *data_in, unsigned char **cpage_out,
+ unsigned char *data_in, unsigned char **cpage_out,
uint32_t *datalen, uint32_t *cdatalen)
{
int ret = JFFS2_COMPR_NONE;
@@ -164,7 +164,7 @@ uint16_t jffs2_compress(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
}
int jffs2_decompress(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
- uint16_t comprtype, unsigned char *cdata_in,
+ uint16_t comprtype, unsigned char *cdata_in,
unsigned char *data_out, uint32_t cdatalen, uint32_t datalen)
{
struct jffs2_compressor *this;
@@ -298,7 +298,7 @@ char *jffs2_stats(void)
act_buf += sprintf(act_buf,"JFFS2 compressor statistics:\n");
act_buf += sprintf(act_buf,"%10s ","none");
- act_buf += sprintf(act_buf,"compr: %d blocks (%d) decompr: %d blocks\n", none_stat_compr_blocks,
+ act_buf += sprintf(act_buf,"compr: %d blocks (%d) decompr: %d blocks\n", none_stat_compr_blocks,
none_stat_compr_size, none_stat_decompr_blocks);
spin_lock(&jffs2_compressor_list_lock);
list_for_each_entry(this, &jffs2_compressor_list, list) {
@@ -307,8 +307,8 @@ char *jffs2_stats(void)
act_buf += sprintf(act_buf,"- ");
else
act_buf += sprintf(act_buf,"+ ");
- act_buf += sprintf(act_buf,"compr: %d blocks (%d/%d) decompr: %d blocks ", this->stat_compr_blocks,
- this->stat_compr_new_size, this->stat_compr_orig_size,
+ act_buf += sprintf(act_buf,"compr: %d blocks (%d/%d) decompr: %d blocks ", this->stat_compr_blocks,
+ this->stat_compr_new_size, this->stat_compr_orig_size,
this->stat_decompr_blocks);
act_buf += sprintf(act_buf,"\n");
}
@@ -317,7 +317,7 @@ char *jffs2_stats(void)
return buf;
}
-char *jffs2_get_compression_mode_name(void)
+char *jffs2_get_compression_mode_name(void)
{
switch (jffs2_compression_mode) {
case JFFS2_COMPR_MODE_NONE:
@@ -330,7 +330,7 @@ char *jffs2_get_compression_mode_name(void)
return "unkown";
}
-int jffs2_set_compression_mode_name(const char *name)
+int jffs2_set_compression_mode_name(const char *name)
{
if (!strcmp("none",name)) {
jffs2_compression_mode = JFFS2_COMPR_MODE_NONE;
@@ -355,7 +355,7 @@ static int jffs2_compressor_Xable(const char *name, int disabled)
if (!strcmp(this->name, name)) {
this->disabled = disabled;
spin_unlock(&jffs2_compressor_list_lock);
- return 0;
+ return 0;
}
}
spin_unlock(&jffs2_compressor_list_lock);
@@ -385,7 +385,7 @@ int jffs2_set_compressor_priority(const char *name, int priority)
}
}
spin_unlock(&jffs2_compressor_list_lock);
- printk(KERN_WARNING "JFFS2: compressor %s not found.\n",name);
+ printk(KERN_WARNING "JFFS2: compressor %s not found.\n",name);
return 1;
reinsert:
/* list is sorted in the order of priority, so if
@@ -412,7 +412,7 @@ void jffs2_free_comprbuf(unsigned char *comprbuf, unsigned char *orig)
kfree(comprbuf);
}
-int jffs2_compressors_init(void)
+int jffs2_compressors_init(void)
{
/* Registering compressors */
#ifdef CONFIG_JFFS2_ZLIB
@@ -425,12 +425,6 @@ int jffs2_compressors_init(void)
jffs2_rubinmips_init();
jffs2_dynrubin_init();
#endif
-#ifdef CONFIG_JFFS2_LZARI
- jffs2_lzari_init();
-#endif
-#ifdef CONFIG_JFFS2_LZO
- jffs2_lzo_init();
-#endif
/* Setting default compression mode */
#ifdef CONFIG_JFFS2_CMODE_NONE
jffs2_compression_mode = JFFS2_COMPR_MODE_NONE;
@@ -446,15 +440,9 @@ int jffs2_compressors_init(void)
return 0;
}
-int jffs2_compressors_exit(void)
+int jffs2_compressors_exit(void)
{
/* Unregistering compressors */
-#ifdef CONFIG_JFFS2_LZO
- jffs2_lzo_exit();
-#endif
-#ifdef CONFIG_JFFS2_LZARI
- jffs2_lzari_exit();
-#endif
#ifdef CONFIG_JFFS2_RUBIN
jffs2_dynrubin_exit();
jffs2_rubinmips_exit();
diff --git a/fs/jffs2/compr.h b/fs/jffs2/compr.h
index 89ceeed201eb..a77e830d85c5 100644
--- a/fs/jffs2/compr.h
+++ b/fs/jffs2/compr.h
@@ -4,10 +4,10 @@
* Copyright (C) 2004 Ferenc Havasi <havasi@inf.u-szeged.hu>,
* University of Szeged, Hungary
*
- * For licensing information, see the file 'LICENCE' in the
+ * For licensing information, see the file 'LICENCE' in the
* jffs2 directory.
*
- * $Id: compr.h,v 1.6 2004/07/16 15:17:57 dwmw2 Exp $
+ * $Id: compr.h,v 1.9 2005/11/07 11:14:38 gleixner Exp $
*
*/
@@ -103,13 +103,5 @@ void jffs2_rtime_exit(void);
int jffs2_zlib_init(void);
void jffs2_zlib_exit(void);
#endif
-#ifdef CONFIG_JFFS2_LZARI
-int jffs2_lzari_init(void);
-void jffs2_lzari_exit(void);
-#endif
-#ifdef CONFIG_JFFS2_LZO
-int jffs2_lzo_init(void);
-void jffs2_lzo_exit(void);
-#endif
#endif /* __JFFS2_COMPR_H__ */
diff --git a/fs/jffs2/compr_rtime.c b/fs/jffs2/compr_rtime.c
index 393129418666..2eb1b7428d16 100644
--- a/fs/jffs2/compr_rtime.c
+++ b/fs/jffs2/compr_rtime.c
@@ -24,8 +24,8 @@
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/errno.h>
-#include <linux/string.h>
-#include <linux/jffs2.h>
+#include <linux/string.h>
+#include <linux/jffs2.h>
#include "compr.h"
/* _compress returns the compressed size, -1 if bigger */
@@ -38,19 +38,19 @@ static int jffs2_rtime_compress(unsigned char *data_in,
int outpos = 0;
int pos=0;
- memset(positions,0,sizeof(positions));
-
+ memset(positions,0,sizeof(positions));
+
while (pos < (*sourcelen) && outpos <= (*dstlen)-2) {
int backpos, runlen=0;
unsigned char value;
-
+
value = data_in[pos];
cpage_out[outpos++] = data_in[pos++];
-
+
backpos = positions[value];
positions[value]=pos;
-
+
while ((backpos < pos) && (pos < (*sourcelen)) &&
(data_in[pos]==data_in[backpos++]) && (runlen<255)) {
pos++;
@@ -63,12 +63,12 @@ static int jffs2_rtime_compress(unsigned char *data_in,
/* We failed */
return -1;
}
-
+
/* Tell the caller how much we managed to compress, and how much space it took */
*sourcelen = pos;
*dstlen = outpos;
return 0;
-}
+}
static int jffs2_rtime_decompress(unsigned char *data_in,
@@ -79,19 +79,19 @@ static int jffs2_rtime_decompress(unsigned char *data_in,
short positions[256];
int outpos = 0;
int pos=0;
-
- memset(positions,0,sizeof(positions));
-
+
+ memset(positions,0,sizeof(positions));
+
while (outpos<destlen) {
unsigned char value;
int backoffs;
int repeat;
-
+
value = data_in[pos++];
cpage_out[outpos++] = value; /* first the verbatim copied byte */
repeat = data_in[pos++];
backoffs = positions[value];
-
+
positions[value]=outpos;
if (repeat) {
if (backoffs + repeat >= outpos) {
@@ -101,12 +101,12 @@ static int jffs2_rtime_decompress(unsigned char *data_in,
}
} else {
memcpy(&cpage_out[outpos],&cpage_out[backoffs],repeat);
- outpos+=repeat;
+ outpos+=repeat;
}
}
}
return 0;
-}
+}
static struct jffs2_compressor jffs2_rtime_comp = {
.priority = JFFS2_RTIME_PRIORITY,
diff --git a/fs/jffs2/compr_rubin.c b/fs/jffs2/compr_rubin.c
index 09422388fb96..e792e675d624 100644
--- a/fs/jffs2/compr_rubin.c
+++ b/fs/jffs2/compr_rubin.c
@@ -11,7 +11,6 @@
*
*/
-
#include <linux/string.h>
#include <linux/types.h>
#include <linux/jffs2.h>
@@ -20,7 +19,7 @@
#include "compr.h"
static void init_rubin(struct rubin_state *rs, int div, int *bits)
-{
+{
int c;
rs->q = 0;
@@ -40,7 +39,7 @@ static int encode(struct rubin_state *rs, long A, long B, int symbol)
while ((rs->q >= UPPER_BIT_RUBIN) || ((rs->p + rs->q) <= UPPER_BIT_RUBIN)) {
rs->bit_number++;
-
+
ret = pushbit(&rs->pp, (rs->q & UPPER_BIT_RUBIN) ? 1 : 0, 0);
if (ret)
return ret;
@@ -68,7 +67,7 @@ static int encode(struct rubin_state *rs, long A, long B, int symbol)
static void end_rubin(struct rubin_state *rs)
-{
+{
int i;
@@ -82,7 +81,7 @@ static void end_rubin(struct rubin_state *rs)
static void init_decode(struct rubin_state *rs, int div, int *bits)
{
- init_rubin(rs, div, bits);
+ init_rubin(rs, div, bits);
/* behalve lower */
rs->rec_q = 0;
@@ -188,7 +187,7 @@ static int in_byte(struct rubin_state *rs)
-static int rubin_do_compress(int bit_divider, int *bits, unsigned char *data_in,
+static int rubin_do_compress(int bit_divider, int *bits, unsigned char *data_in,
unsigned char *cpage_out, uint32_t *sourcelen, uint32_t *dstlen)
{
int outpos = 0;
@@ -198,31 +197,31 @@ static int rubin_do_compress(int bit_divider, int *bits, unsigned char *data_in,
init_pushpull(&rs.pp, cpage_out, *dstlen * 8, 0, 32);
init_rubin(&rs, bit_divider, bits);
-
+
while (pos < (*sourcelen) && !out_byte(&rs, data_in[pos]))
pos++;
-
+
end_rubin(&rs);
if (outpos > pos) {
/* We failed */
return -1;
}
-
- /* Tell the caller how much we managed to compress,
+
+ /* Tell the caller how much we managed to compress,
* and how much space it took */
-
+
outpos = (pushedbits(&rs.pp)+7)/8;
-
+
if (outpos >= pos)
return -1; /* We didn't actually compress */
*sourcelen = pos;
*dstlen = outpos;
return 0;
-}
+}
#if 0
/* _compress returns the compressed size, -1 if bigger */
-int jffs2_rubinmips_compress(unsigned char *data_in, unsigned char *cpage_out,
+int jffs2_rubinmips_compress(unsigned char *data_in, unsigned char *cpage_out,
uint32_t *sourcelen, uint32_t *dstlen, void *model)
{
return rubin_do_compress(BIT_DIVIDER_MIPS, bits_mips, data_in, cpage_out, sourcelen, dstlen);
@@ -277,7 +276,7 @@ static int jffs2_dynrubin_compress(unsigned char *data_in,
}
ret = rubin_do_compress(256, bits, data_in, cpage_out+8, &mysrclen, &mydstlen);
- if (ret)
+ if (ret)
return ret;
/* Add back the 8 bytes we took for the probabilities */
@@ -293,19 +292,19 @@ static int jffs2_dynrubin_compress(unsigned char *data_in,
return 0;
}
-static void rubin_do_decompress(int bit_divider, int *bits, unsigned char *cdata_in,
+static void rubin_do_decompress(int bit_divider, int *bits, unsigned char *cdata_in,
unsigned char *page_out, uint32_t srclen, uint32_t destlen)
{
int outpos = 0;
struct rubin_state rs;
-
+
init_pushpull(&rs.pp, cdata_in, srclen, 0, 0);
init_decode(&rs, bit_divider, bits);
-
+
while (outpos < destlen) {
page_out[outpos++] = in_byte(&rs);
}
-}
+}
static int jffs2_rubinmips_decompress(unsigned char *data_in,
diff --git a/fs/jffs2/compr_rubin.h b/fs/jffs2/compr_rubin.h
index cf51e34f6574..bf1a93451621 100644
--- a/fs/jffs2/compr_rubin.h
+++ b/fs/jffs2/compr_rubin.h
@@ -1,7 +1,7 @@
/* Rubin encoder/decoder header */
/* work started at : aug 3, 1994 */
/* last modification : aug 15, 1994 */
-/* $Id: compr_rubin.h,v 1.6 2002/01/25 01:49:26 dwmw2 Exp $ */
+/* $Id: compr_rubin.h,v 1.7 2005/11/07 11:14:38 gleixner Exp $ */
#include "pushpull.h"
@@ -11,8 +11,8 @@
struct rubin_state {
- unsigned long p;
- unsigned long q;
+ unsigned long p;
+ unsigned long q;
unsigned long rec_q;
long bit_number;
struct pushpull pp;
diff --git a/fs/jffs2/compr_zlib.c b/fs/jffs2/compr_zlib.c
index 83f7e0788fd0..4db8be8e90cc 100644
--- a/fs/jffs2/compr_zlib.c
+++ b/fs/jffs2/compr_zlib.c
@@ -7,7 +7,7 @@
*
* For licensing information, see the file 'LICENCE' in this directory.
*
- * $Id: compr_zlib.c,v 1.31 2005/05/20 19:30:06 gleixner Exp $
+ * $Id: compr_zlib.c,v 1.32 2005/11/07 11:14:38 gleixner Exp $
*
*/
@@ -24,11 +24,11 @@
#include "nodelist.h"
#include "compr.h"
- /* Plan: call deflate() with avail_in == *sourcelen,
- avail_out = *dstlen - 12 and flush == Z_FINISH.
+ /* Plan: call deflate() with avail_in == *sourcelen,
+ avail_out = *dstlen - 12 and flush == Z_FINISH.
If it doesn't manage to finish, call it again with
avail_in == 0 and avail_out set to the remaining 12
- bytes for it to clean up.
+ bytes for it to clean up.
Q: Is 12 bytes sufficient?
*/
#define STREAM_END_SPACE 12
@@ -89,7 +89,7 @@ static int jffs2_zlib_compress(unsigned char *data_in,
def_strm.next_in = data_in;
def_strm.total_in = 0;
-
+
def_strm.next_out = cpage_out;
def_strm.total_out = 0;
@@ -99,7 +99,7 @@ static int jffs2_zlib_compress(unsigned char *data_in,
D1(printk(KERN_DEBUG "calling deflate with avail_in %d, avail_out %d\n",
def_strm.avail_in, def_strm.avail_out));
ret = zlib_deflate(&def_strm, Z_PARTIAL_FLUSH);
- D1(printk(KERN_DEBUG "deflate returned with avail_in %d, avail_out %d, total_in %ld, total_out %ld\n",
+ D1(printk(KERN_DEBUG "deflate returned with avail_in %d, avail_out %d, total_in %ld, total_out %ld\n",
def_strm.avail_in, def_strm.avail_out, def_strm.total_in, def_strm.total_out));
if (ret != Z_OK) {
D1(printk(KERN_DEBUG "deflate in loop returned %d\n", ret));
@@ -150,7 +150,7 @@ static int jffs2_zlib_decompress(unsigned char *data_in,
inf_strm.next_in = data_in;
inf_strm.avail_in = srclen;
inf_strm.total_in = 0;
-
+
inf_strm.next_out = cpage_out;
inf_strm.avail_out = destlen;
inf_strm.total_out = 0;
diff --git a/fs/jffs2/comprtest.c b/fs/jffs2/comprtest.c
index cf51f091d0e7..f0fb8be7740c 100644
--- a/fs/jffs2/comprtest.c
+++ b/fs/jffs2/comprtest.c
@@ -1,4 +1,4 @@
-/* $Id: comprtest.c,v 1.5 2002/01/03 15:20:44 dwmw2 Exp $ */
+/* $Id: comprtest.c,v 1.6 2005/11/07 11:14:38 gleixner Exp $ */
#include <linux/kernel.h>
#include <linux/string.h>
@@ -265,9 +265,9 @@ static unsigned char testdata[TESTDATA_LEN] = {
static unsigned char comprbuf[TESTDATA_LEN];
static unsigned char decomprbuf[TESTDATA_LEN];
-int jffs2_decompress(unsigned char comprtype, unsigned char *cdata_in,
+int jffs2_decompress(unsigned char comprtype, unsigned char *cdata_in,
unsigned char *data_out, uint32_t cdatalen, uint32_t datalen);
-unsigned char jffs2_compress(unsigned char *data_in, unsigned char *cpage_out,
+unsigned char jffs2_compress(unsigned char *data_in, unsigned char *cpage_out,
uint32_t *datalen, uint32_t *cdatalen);
int init_module(void ) {
@@ -276,10 +276,10 @@ int init_module(void ) {
int ret;
printk("Original data: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
- testdata[0],testdata[1],testdata[2],testdata[3],
- testdata[4],testdata[5],testdata[6],testdata[7],
- testdata[8],testdata[9],testdata[10],testdata[11],
- testdata[12],testdata[13],testdata[14],testdata[15]);
+ testdata[0],testdata[1],testdata[2],testdata[3],
+ testdata[4],testdata[5],testdata[6],testdata[7],
+ testdata[8],testdata[9],testdata[10],testdata[11],
+ testdata[12],testdata[13],testdata[14],testdata[15]);
d = TESTDATA_LEN;
c = TESTDATA_LEN;
comprtype = jffs2_compress(testdata, comprbuf, &d, &c);
@@ -287,18 +287,18 @@ int init_module(void ) {
printk("jffs2_compress used compression type %d. Compressed size %d, uncompressed size %d\n",
comprtype, c, d);
printk("Compressed data: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
- comprbuf[0],comprbuf[1],comprbuf[2],comprbuf[3],
- comprbuf[4],comprbuf[5],comprbuf[6],comprbuf[7],
- comprbuf[8],comprbuf[9],comprbuf[10],comprbuf[11],
- comprbuf[12],comprbuf[13],comprbuf[14],comprbuf[15]);
+ comprbuf[0],comprbuf[1],comprbuf[2],comprbuf[3],
+ comprbuf[4],comprbuf[5],comprbuf[6],comprbuf[7],
+ comprbuf[8],comprbuf[9],comprbuf[10],comprbuf[11],
+ comprbuf[12],comprbuf[13],comprbuf[14],comprbuf[15]);
ret = jffs2_decompress(comprtype, comprbuf, decomprbuf, c, d);
printk("jffs2_decompress returned %d\n", ret);
printk("Decompressed data: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
- decomprbuf[0],decomprbuf[1],decomprbuf[2],decomprbuf[3],
- decomprbuf[4],decomprbuf[5],decomprbuf[6],decomprbuf[7],
- decomprbuf[8],decomprbuf[9],decomprbuf[10],decomprbuf[11],
- decomprbuf[12],decomprbuf[13],decomprbuf[14],decomprbuf[15]);
+ decomprbuf[0],decomprbuf[1],decomprbuf[2],decomprbuf[3],
+ decomprbuf[4],decomprbuf[5],decomprbuf[6],decomprbuf[7],
+ decomprbuf[8],decomprbuf[9],decomprbuf[10],decomprbuf[11],
+ decomprbuf[12],decomprbuf[13],decomprbuf[14],decomprbuf[15]);
if (memcmp(decomprbuf, testdata, d))
printk("Compression and decompression corrupted data\n");
else
diff --git a/fs/jffs2/debug.c b/fs/jffs2/debug.c
new file mode 100644
index 000000000000..1fe17de713e8
--- /dev/null
+++ b/fs/jffs2/debug.c
@@ -0,0 +1,705 @@
+/*
+ * JFFS2 -- Journalling Flash File System, Version 2.
+ *
+ * Copyright (C) 2001-2003 Red Hat, Inc.
+ *
+ * Created by David Woodhouse <dwmw2@infradead.org>
+ *
+ * For licensing information, see the file 'LICENCE' in this directory.
+ *
+ * $Id: debug.c,v 1.12 2005/11/07 11:14:39 gleixner Exp $
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/pagemap.h>
+#include <linux/crc32.h>
+#include <linux/jffs2.h>
+#include <linux/mtd/mtd.h>
+#include "nodelist.h"
+#include "debug.h"
+
+#ifdef JFFS2_DBG_SANITY_CHECKS
+
+void
+__jffs2_dbg_acct_sanity_check_nolock(struct jffs2_sb_info *c,
+ struct jffs2_eraseblock *jeb)
+{
+ if (unlikely(jeb && jeb->used_size + jeb->dirty_size +
+ jeb->free_size + jeb->wasted_size +
+ jeb->unchecked_size != c->sector_size)) {
+ JFFS2_ERROR("eeep, space accounting for block at 0x%08x is screwed.\n", jeb->offset);
+ JFFS2_ERROR("free %#08x + dirty %#08x + used %#08x + wasted %#08x + unchecked %#08x != total %#08x.\n",
+ jeb->free_size, jeb->dirty_size, jeb->used_size,
+ jeb->wasted_size, jeb->unchecked_size, c->sector_size);
+ BUG();
+ }
+
+ if (unlikely(c->used_size + c->dirty_size + c->free_size + c->erasing_size + c->bad_size
+ + c->wasted_size + c->unchecked_size != c->flash_size)) {
+ JFFS2_ERROR("eeep, space accounting superblock info is screwed.\n");
+ JFFS2_ERROR("free %#08x + dirty %#08x + used %#08x + erasing %#08x + bad %#08x + wasted %#08x + unchecked %#08x != total %#08x.\n",
+ c->free_size, c->dirty_size, c->used_size, c->erasing_size, c->bad_size,
+ c->wasted_size, c->unchecked_size, c->flash_size);
+ BUG();
+ }
+}
+
+void
+__jffs2_dbg_acct_sanity_check(struct jffs2_sb_info *c,
+ struct jffs2_eraseblock *jeb)
+{
+ spin_lock(&c->erase_completion_lock);
+ jffs2_dbg_acct_sanity_check_nolock(c, jeb);
+ spin_unlock(&c->erase_completion_lock);
+}
+
+#endif /* JFFS2_DBG_SANITY_CHECKS */
+
+#ifdef JFFS2_DBG_PARANOIA_CHECKS
+/*
+ * Check the fragtree.
+ */
+void
+__jffs2_dbg_fragtree_paranoia_check(struct jffs2_inode_info *f)
+{
+ down(&f->sem);
+ __jffs2_dbg_fragtree_paranoia_check_nolock(f);
+ up(&f->sem);
+}
+
+void
+__jffs2_dbg_fragtree_paranoia_check_nolock(struct jffs2_inode_info *f)
+{
+ struct jffs2_node_frag *frag;
+ int bitched = 0;
+
+ for (frag = frag_first(&f->fragtree); frag; frag = frag_next(frag)) {
+ struct jffs2_full_dnode *fn = frag->node;
+
+ if (!fn || !fn->raw)
+ continue;
+
+ if (ref_flags(fn->raw) == REF_PRISTINE) {
+ if (fn->frags > 1) {
+ JFFS2_ERROR("REF_PRISTINE node at 0x%08x had %d frags. Tell dwmw2.\n",
+ ref_offset(fn->raw), fn->frags);
+ bitched = 1;
+ }
+
+ /* A hole node which isn't multi-page should be garbage-collected
+ and merged anyway, so we just check for the frag size here,
+ rather than mucking around with actually reading the node
+ and checking the compression type, which is the real way
+ to tell a hole node. */
+ if (frag->ofs & (PAGE_CACHE_SIZE-1) && frag_prev(frag)
+ && frag_prev(frag)->size < PAGE_CACHE_SIZE && frag_prev(frag)->node) {
+ JFFS2_ERROR("REF_PRISTINE node at 0x%08x had a previous non-hole frag in the same page. Tell dwmw2.\n",
+ ref_offset(fn->raw));
+ bitched = 1;
+ }
+
+ if ((frag->ofs+frag->size) & (PAGE_CACHE_SIZE-1) && frag_next(frag)
+ && frag_next(frag)->size < PAGE_CACHE_SIZE && frag_next(frag)->node) {
+ JFFS2_ERROR("REF_PRISTINE node at 0x%08x (%08x-%08x) had a following non-hole frag in the same page. Tell dwmw2.\n",
+ ref_offset(fn->raw), frag->ofs, frag->ofs+frag->size);
+ bitched = 1;
+ }
+ }
+ }
+
+ if (bitched) {
+ JFFS2_ERROR("fragtree is corrupted.\n");
+ __jffs2_dbg_dump_fragtree_nolock(f);
+ BUG();
+ }
+}
+
+/*
+ * Check if the flash contains all 0xFF before we start writing.
+ */
+void
+__jffs2_dbg_prewrite_paranoia_check(struct jffs2_sb_info *c,
+ uint32_t ofs, int len)
+{
+ size_t retlen;
+ int ret, i;
+ unsigned char *buf;
+
+ buf = kmalloc(len, GFP_KERNEL);
+ if (!buf)
+ return;
+
+ ret = jffs2_flash_read(c, ofs, len, &retlen, buf);
+ if (ret || (retlen != len)) {
+ JFFS2_WARNING("read %d bytes failed or short. ret %d, retlen %zd.\n",
+ len, ret, retlen);
+ kfree(buf);
+ return;
+ }
+
+ ret = 0;
+ for (i = 0; i < len; i++)
+ if (buf[i] != 0xff)
+ ret = 1;
+
+ if (ret) {
+ JFFS2_ERROR("argh, about to write node to %#08x on flash, but there are data already there. The first corrupted byte is at %#08x offset.\n",
+ ofs, ofs + i);
+ __jffs2_dbg_dump_buffer(buf, len, ofs);
+ kfree(buf);
+ BUG();
+ }
+
+ kfree(buf);
+}
+
+/*
+ * Check the space accounting and node_ref list correctness for the JFFS2 erasable block 'jeb'.
+ */
+void
+__jffs2_dbg_acct_paranoia_check(struct jffs2_sb_info *c,
+ struct jffs2_eraseblock *jeb)
+{
+ spin_lock(&c->erase_completion_lock);
+ __jffs2_dbg_acct_paranoia_check_nolock(c, jeb);
+ spin_unlock(&c->erase_completion_lock);
+}
+
+void
+__jffs2_dbg_acct_paranoia_check_nolock(struct jffs2_sb_info *c,
+ struct jffs2_eraseblock *jeb)
+{
+ uint32_t my_used_size = 0;
+ uint32_t my_unchecked_size = 0;
+ uint32_t my_dirty_size = 0;
+ struct jffs2_raw_node_ref *ref2 = jeb->first_node;
+
+ while (ref2) {
+ uint32_t totlen = ref_totlen(c, jeb, ref2);
+
+ if (ref2->flash_offset < jeb->offset ||
+ ref2->flash_offset > jeb->offset + c->sector_size) {
+ JFFS2_ERROR("node_ref %#08x shouldn't be in block at %#08x.\n",
+ ref_offset(ref2), jeb->offset);
+ goto error;
+
+ }
+ if (ref_flags(ref2) == REF_UNCHECKED)
+ my_unchecked_size += totlen;
+ else if (!ref_obsolete(ref2))
+ my_used_size += totlen;
+ else
+ my_dirty_size += totlen;
+
+ if ((!ref2->next_phys) != (ref2 == jeb->last_node)) {
+ JFFS2_ERROR("node_ref for node at %#08x (mem %p) has next_phys at %#08x (mem %p), last_node is at %#08x (mem %p).\n",
+ ref_offset(ref2), ref2, ref_offset(ref2->next_phys), ref2->next_phys,
+ ref_offset(jeb->last_node), jeb->last_node);
+ goto error;
+ }
+ ref2 = ref2->next_phys;
+ }
+
+ if (my_used_size != jeb->used_size) {
+ JFFS2_ERROR("Calculated used size %#08x != stored used size %#08x.\n",
+ my_used_size, jeb->used_size);
+ goto error;
+ }
+
+ if (my_unchecked_size != jeb->unchecked_size) {
+ JFFS2_ERROR("Calculated unchecked size %#08x != stored unchecked size %#08x.\n",
+ my_unchecked_size, jeb->unchecked_size);
+ goto error;
+ }
+
+#if 0
+ /* This should work when we implement ref->__totlen elemination */
+ if (my_dirty_size != jeb->dirty_size + jeb->wasted_size) {
+ JFFS2_ERROR("Calculated dirty+wasted size %#08x != stored dirty + wasted size %#08x\n",
+ my_dirty_size, jeb->dirty_size + jeb->wasted_size);
+ goto error;
+ }
+
+ if (jeb->free_size == 0
+ && my_used_size + my_unchecked_size + my_dirty_size != c->sector_size) {
+ JFFS2_ERROR("The sum of all nodes in block (%#x) != size of block (%#x)\n",
+ my_used_size + my_unchecked_size + my_dirty_size,
+ c->sector_size);
+ goto error;
+ }
+#endif
+
+ return;
+
+error:
+ __jffs2_dbg_dump_node_refs_nolock(c, jeb);
+ __jffs2_dbg_dump_jeb_nolock(jeb);
+ __jffs2_dbg_dump_block_lists_nolock(c);
+ BUG();
+
+}
+#endif /* JFFS2_DBG_PARANOIA_CHECKS */
+
+#if defined(JFFS2_DBG_DUMPS) || defined(JFFS2_DBG_PARANOIA_CHECKS)
+/*
+ * Dump the node_refs of the 'jeb' JFFS2 eraseblock.
+ */
+void
+__jffs2_dbg_dump_node_refs(struct jffs2_sb_info *c,
+ struct jffs2_eraseblock *jeb)
+{
+ spin_lock(&c->erase_completion_lock);
+ __jffs2_dbg_dump_node_refs_nolock(c, jeb);
+ spin_unlock(&c->erase_completion_lock);
+}
+
+void
+__jffs2_dbg_dump_node_refs_nolock(struct jffs2_sb_info *c,
+ struct jffs2_eraseblock *jeb)
+{
+ struct jffs2_raw_node_ref *ref;
+ int i = 0;
+
+ printk(JFFS2_DBG_MSG_PREFIX " Dump node_refs of the eraseblock %#08x\n", jeb->offset);
+ if (!jeb->first_node) {
+ printk(JFFS2_DBG_MSG_PREFIX " no nodes in the eraseblock %#08x\n", jeb->offset);
+ return;
+ }
+
+ printk(JFFS2_DBG);
+ for (ref = jeb->first_node; ; ref = ref->next_phys) {
+ printk("%#08x(%#x)", ref_offset(ref), ref->__totlen);
+ if (ref->next_phys)
+ printk("->");
+ else
+ break;
+ if (++i == 4) {
+ i = 0;
+ printk("\n" JFFS2_DBG);
+ }
+ }
+ printk("\n");
+}
+
+/*
+ * Dump an eraseblock's space accounting.
+ */
+void
+__jffs2_dbg_dump_jeb(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb)
+{
+ spin_lock(&c->erase_completion_lock);
+ __jffs2_dbg_dump_jeb_nolock(jeb);
+ spin_unlock(&c->erase_completion_lock);
+}
+
+void
+__jffs2_dbg_dump_jeb_nolock(struct jffs2_eraseblock *jeb)
+{
+ if (!jeb)
+ return;
+
+ printk(JFFS2_DBG_MSG_PREFIX " dump space accounting for the eraseblock at %#08x:\n",
+ jeb->offset);
+
+ printk(JFFS2_DBG "used_size: %#08x\n", jeb->used_size);
+ printk(JFFS2_DBG "dirty_size: %#08x\n", jeb->dirty_size);
+ printk(JFFS2_DBG "wasted_size: %#08x\n", jeb->wasted_size);
+ printk(JFFS2_DBG "unchecked_size: %#08x\n", jeb->unchecked_size);
+ printk(JFFS2_DBG "free_size: %#08x\n", jeb->free_size);
+}
+
+void
+__jffs2_dbg_dump_block_lists(struct jffs2_sb_info *c)
+{
+ spin_lock(&c->erase_completion_lock);
+ __jffs2_dbg_dump_block_lists_nolock(c);
+ spin_unlock(&c->erase_completion_lock);
+}
+
+void
+__jffs2_dbg_dump_block_lists_nolock(struct jffs2_sb_info *c)
+{
+ printk(JFFS2_DBG_MSG_PREFIX " dump JFFS2 blocks lists:\n");
+
+ printk(JFFS2_DBG "flash_size: %#08x\n", c->flash_size);
+ printk(JFFS2_DBG "used_size: %#08x\n", c->used_size);
+ printk(JFFS2_DBG "dirty_size: %#08x\n", c->dirty_size);
+ printk(JFFS2_DBG "wasted_size: %#08x\n", c->wasted_size);
+ printk(JFFS2_DBG "unchecked_size: %#08x\n", c->unchecked_size);
+ printk(JFFS2_DBG "free_size: %#08x\n", c->free_size);
+ printk(JFFS2_DBG "erasing_size: %#08x\n", c->erasing_size);
+ printk(JFFS2_DBG "bad_size: %#08x\n", c->bad_size);
+ printk(JFFS2_DBG "sector_size: %#08x\n", c->sector_size);
+ printk(JFFS2_DBG "jffs2_reserved_blocks size: %#08x\n",
+ c->sector_size * c->resv_blocks_write);
+
+ if (c->nextblock)
+ printk(JFFS2_DBG "nextblock: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n",
+ c->nextblock->offset, c->nextblock->used_size,
+ c->nextblock->dirty_size, c->nextblock->wasted_size,
+ c->nextblock->unchecked_size, c->nextblock->free_size);
+ else
+ printk(JFFS2_DBG "nextblock: NULL\n");
+
+ if (c->gcblock)
+ printk(JFFS2_DBG "gcblock: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n",
+ c->gcblock->offset, c->gcblock->used_size, c->gcblock->dirty_size,
+ c->gcblock->wasted_size, c->gcblock->unchecked_size, c->gcblock->free_size);
+ else
+ printk(JFFS2_DBG "gcblock: NULL\n");
+
+ if (list_empty(&c->clean_list)) {
+ printk(JFFS2_DBG "clean_list: empty\n");
+ } else {
+ struct list_head *this;
+ int numblocks = 0;
+ uint32_t dirty = 0;
+
+ list_for_each(this, &c->clean_list) {
+ struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
+ numblocks ++;
+ dirty += jeb->wasted_size;
+ if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
+ printk(JFFS2_DBG "clean_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n",
+ jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
+ jeb->unchecked_size, jeb->free_size);
+ }
+ }
+
+ printk (JFFS2_DBG "Contains %d blocks with total wasted size %u, average wasted size: %u\n",
+ numblocks, dirty, dirty / numblocks);
+ }
+
+ if (list_empty(&c->very_dirty_list)) {
+ printk(JFFS2_DBG "very_dirty_list: empty\n");
+ } else {
+ struct list_head *this;
+ int numblocks = 0;
+ uint32_t dirty = 0;
+
+ list_for_each(this, &c->very_dirty_list) {
+ struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
+
+ numblocks ++;
+ dirty += jeb->dirty_size;
+ if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
+ printk(JFFS2_DBG "very_dirty_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n",
+ jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
+ jeb->unchecked_size, jeb->free_size);
+ }
+ }
+
+ printk (JFFS2_DBG "Contains %d blocks with total dirty size %u, average dirty size: %u\n",
+ numblocks, dirty, dirty / numblocks);
+ }
+
+ if (list_empty(&c->dirty_list)) {
+ printk(JFFS2_DBG "dirty_list: empty\n");
+ } else {
+ struct list_head *this;
+ int numblocks = 0;
+ uint32_t dirty = 0;
+
+ list_for_each(this, &c->dirty_list) {
+ struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
+
+ numblocks ++;
+ dirty += jeb->dirty_size;
+ if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
+ printk(JFFS2_DBG "dirty_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n",
+ jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
+ jeb->unchecked_size, jeb->free_size);
+ }
+ }
+
+ printk (JFFS2_DBG "contains %d blocks with total dirty size %u, average dirty size: %u\n",
+ numblocks, dirty, dirty / numblocks);
+ }
+
+ if (list_empty(&c->erasable_list)) {
+ printk(JFFS2_DBG "erasable_list: empty\n");
+ } else {
+ struct list_head *this;
+
+ list_for_each(this, &c->erasable_list) {
+ struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
+
+ if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
+ printk(JFFS2_DBG "erasable_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n",
+ jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
+ jeb->unchecked_size, jeb->free_size);
+ }
+ }
+ }
+
+ if (list_empty(&c->erasing_list)) {
+ printk(JFFS2_DBG "erasing_list: empty\n");
+ } else {
+ struct list_head *this;
+
+ list_for_each(this, &c->erasing_list) {
+ struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
+
+ if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
+ printk(JFFS2_DBG "erasing_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n",
+ jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
+ jeb->unchecked_size, jeb->free_size);
+ }
+ }
+ }
+
+ if (list_empty(&c->erase_pending_list)) {
+ printk(JFFS2_DBG "erase_pending_list: empty\n");
+ } else {
+ struct list_head *this;
+
+ list_for_each(this, &c->erase_pending_list) {
+ struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
+
+ if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
+ printk(JFFS2_DBG "erase_pending_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n",
+ jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
+ jeb->unchecked_size, jeb->free_size);
+ }
+ }
+ }
+
+ if (list_empty(&c->erasable_pending_wbuf_list)) {
+ printk(JFFS2_DBG "erasable_pending_wbuf_list: empty\n");
+ } else {
+ struct list_head *this;
+
+ list_for_each(this, &c->erasable_pending_wbuf_list) {
+ struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
+
+ if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
+ printk(JFFS2_DBG "erasable_pending_wbuf_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n",
+ jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
+ jeb->unchecked_size, jeb->free_size);
+ }
+ }
+ }
+
+ if (list_empty(&c->free_list)) {
+ printk(JFFS2_DBG "free_list: empty\n");
+ } else {
+ struct list_head *this;
+
+ list_for_each(this, &c->free_list) {
+ struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
+
+ if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
+ printk(JFFS2_DBG "free_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n",
+ jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
+ jeb->unchecked_size, jeb->free_size);
+ }
+ }
+ }
+
+ if (list_empty(&c->bad_list)) {
+ printk(JFFS2_DBG "bad_list: empty\n");
+ } else {
+ struct list_head *this;
+
+ list_for_each(this, &c->bad_list) {
+ struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
+
+ if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
+ printk(JFFS2_DBG "bad_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n",
+ jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
+ jeb->unchecked_size, jeb->free_size);
+ }
+ }
+ }
+
+ if (list_empty(&c->bad_used_list)) {
+ printk(JFFS2_DBG "bad_used_list: empty\n");
+ } else {
+ struct list_head *this;
+
+ list_for_each(this, &c->bad_used_list) {
+ struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
+
+ if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
+ printk(JFFS2_DBG "bad_used_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n",
+ jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
+ jeb->unchecked_size, jeb->free_size);
+ }
+ }
+ }
+}
+
+void
+__jffs2_dbg_dump_fragtree(struct jffs2_inode_info *f)
+{
+ down(&f->sem);
+ jffs2_dbg_dump_fragtree_nolock(f);
+ up(&f->sem);
+}
+
+void
+__jffs2_dbg_dump_fragtree_nolock(struct jffs2_inode_info *f)
+{
+ struct jffs2_node_frag *this = frag_first(&f->fragtree);
+ uint32_t lastofs = 0;
+ int buggy = 0;
+
+ printk(JFFS2_DBG_MSG_PREFIX " dump fragtree of ino #%u\n", f->inocache->ino);
+ while(this) {
+ if (this->node)
+ printk(JFFS2_DBG "frag %#04x-%#04x: %#08x(%d) on flash (*%p), left (%p), right (%p), parent (%p)\n",
+ this->ofs, this->ofs+this->size, ref_offset(this->node->raw),
+ ref_flags(this->node->raw), this, frag_left(this), frag_right(this),
+ frag_parent(this));
+ else
+ printk(JFFS2_DBG "frag %#04x-%#04x: hole (*%p). left (%p), right (%p), parent (%p)\n",
+ this->ofs, this->ofs+this->size, this, frag_left(this),
+ frag_right(this), frag_parent(this));
+ if (this->ofs != lastofs)
+ buggy = 1;
+ lastofs = this->ofs + this->size;
+ this = frag_next(this);
+ }
+
+ if (f->metadata)
+ printk(JFFS2_DBG "metadata at 0x%08x\n", ref_offset(f->metadata->raw));
+
+ if (buggy) {
+ JFFS2_ERROR("frag tree got a hole in it.\n");
+ BUG();
+ }
+}
+
+#define JFFS2_BUFDUMP_BYTES_PER_LINE 32
+void
+__jffs2_dbg_dump_buffer(unsigned char *buf, int len, uint32_t offs)
+{
+ int skip;
+ int i;
+
+ printk(JFFS2_DBG_MSG_PREFIX " dump from offset %#08x to offset %#08x (%x bytes).\n",
+ offs, offs + len, len);
+ i = skip = offs % JFFS2_BUFDUMP_BYTES_PER_LINE;
+ offs = offs & ~(JFFS2_BUFDUMP_BYTES_PER_LINE - 1);
+
+ if (skip != 0)
+ printk(JFFS2_DBG "%#08x: ", offs);
+
+ while (skip--)
+ printk(" ");
+
+ while (i < len) {
+ if ((i % JFFS2_BUFDUMP_BYTES_PER_LINE) == 0 && i != len -1) {
+ if (i != 0)
+ printk("\n");
+ offs += JFFS2_BUFDUMP_BYTES_PER_LINE;
+ printk(JFFS2_DBG "%0#8x: ", offs);
+ }
+
+ printk("%02x ", buf[i]);
+
+ i += 1;
+ }
+
+ printk("\n");
+}
+
+/*
+ * Dump a JFFS2 node.
+ */
+void
+__jffs2_dbg_dump_node(struct jffs2_sb_info *c, uint32_t ofs)
+{
+ union jffs2_node_union node;
+ int len = sizeof(union jffs2_node_union);
+ size_t retlen;
+ uint32_t crc;
+ int ret;
+
+ printk(JFFS2_DBG_MSG_PREFIX " dump node at offset %#08x.\n", ofs);
+
+ ret = jffs2_flash_read(c, ofs, len, &retlen, (unsigned char *)&node);
+ if (ret || (retlen != len)) {
+ JFFS2_ERROR("read %d bytes failed or short. ret %d, retlen %zd.\n",
+ len, ret, retlen);
+ return;
+ }
+
+ printk(JFFS2_DBG "magic:\t%#04x\n", je16_to_cpu(node.u.magic));
+ printk(JFFS2_DBG "nodetype:\t%#04x\n", je16_to_cpu(node.u.nodetype));
+ printk(JFFS2_DBG "totlen:\t%#08x\n", je32_to_cpu(node.u.totlen));
+ printk(JFFS2_DBG "hdr_crc:\t%#08x\n", je32_to_cpu(node.u.hdr_crc));
+
+ crc = crc32(0, &node.u, sizeof(node.u) - 4);
+ if (crc != je32_to_cpu(node.u.hdr_crc)) {
+ JFFS2_ERROR("wrong common header CRC.\n");
+ return;
+ }
+
+ if (je16_to_cpu(node.u.magic) != JFFS2_MAGIC_BITMASK &&
+ je16_to_cpu(node.u.magic) != JFFS2_OLD_MAGIC_BITMASK)
+ {
+ JFFS2_ERROR("wrong node magic: %#04x instead of %#04x.\n",
+ je16_to_cpu(node.u.magic), JFFS2_MAGIC_BITMASK);
+ return;
+ }
+
+ switch(je16_to_cpu(node.u.nodetype)) {
+
+ case JFFS2_NODETYPE_INODE:
+
+ printk(JFFS2_DBG "the node is inode node\n");
+ printk(JFFS2_DBG "ino:\t%#08x\n", je32_to_cpu(node.i.ino));
+ printk(JFFS2_DBG "version:\t%#08x\n", je32_to_cpu(node.i.version));
+ printk(JFFS2_DBG "mode:\t%#08x\n", node.i.mode.m);
+ printk(JFFS2_DBG "uid:\t%#04x\n", je16_to_cpu(node.i.uid));
+ printk(JFFS2_DBG "gid:\t%#04x\n", je16_to_cpu(node.i.gid));
+ printk(JFFS2_DBG "isize:\t%#08x\n", je32_to_cpu(node.i.isize));
+ printk(JFFS2_DBG "atime:\t%#08x\n", je32_to_cpu(node.i.atime));
+ printk(JFFS2_DBG "mtime:\t%#08x\n", je32_to_cpu(node.i.mtime));
+ printk(JFFS2_DBG "ctime:\t%#08x\n", je32_to_cpu(node.i.ctime));
+ printk(JFFS2_DBG "offset:\t%#08x\n", je32_to_cpu(node.i.offset));
+ printk(JFFS2_DBG "csize:\t%#08x\n", je32_to_cpu(node.i.csize));
+ printk(JFFS2_DBG "dsize:\t%#08x\n", je32_to_cpu(node.i.dsize));
+ printk(JFFS2_DBG "compr:\t%#02x\n", node.i.compr);
+ printk(JFFS2_DBG "usercompr:\t%#02x\n", node.i.usercompr);
+ printk(JFFS2_DBG "flags:\t%#04x\n", je16_to_cpu(node.i.flags));
+ printk(JFFS2_DBG "data_crc:\t%#08x\n", je32_to_cpu(node.i.data_crc));
+ printk(JFFS2_DBG "node_crc:\t%#08x\n", je32_to_cpu(node.i.node_crc));
+
+ crc = crc32(0, &node.i, sizeof(node.i) - 8);
+ if (crc != je32_to_cpu(node.i.node_crc)) {
+ JFFS2_ERROR("wrong node header CRC.\n");
+ return;
+ }
+ break;
+
+ case JFFS2_NODETYPE_DIRENT:
+
+ printk(JFFS2_DBG "the node is dirent node\n");
+ printk(JFFS2_DBG "pino:\t%#08x\n", je32_to_cpu(node.d.pino));
+ printk(JFFS2_DBG "version:\t%#08x\n", je32_to_cpu(node.d.version));
+ printk(JFFS2_DBG "ino:\t%#08x\n", je32_to_cpu(node.d.ino));
+ printk(JFFS2_DBG "mctime:\t%#08x\n", je32_to_cpu(node.d.mctime));
+ printk(JFFS2_DBG "nsize:\t%#02x\n", node.d.nsize);
+ printk(JFFS2_DBG "type:\t%#02x\n", node.d.type);
+ printk(JFFS2_DBG "node_crc:\t%#08x\n", je32_to_cpu(node.d.node_crc));
+ printk(JFFS2_DBG "name_crc:\t%#08x\n", je32_to_cpu(node.d.name_crc));
+
+ node.d.name[node.d.nsize] = '\0';
+ printk(JFFS2_DBG "name:\t\"%s\"\n", node.d.name);
+
+ crc = crc32(0, &node.d, sizeof(node.d) - 8);
+ if (crc != je32_to_cpu(node.d.node_crc)) {
+ JFFS2_ERROR("wrong node header CRC.\n");
+ return;
+ }
+ break;
+
+ default:
+ printk(JFFS2_DBG "node type is unknown\n");
+ break;
+ }
+}
+#endif /* JFFS2_DBG_DUMPS || JFFS2_DBG_PARANOIA_CHECKS */
diff --git a/fs/jffs2/debug.h b/fs/jffs2/debug.h
new file mode 100644
index 000000000000..f193d43a8a59
--- /dev/null
+++ b/fs/jffs2/debug.h
@@ -0,0 +1,279 @@
+/*
+ * JFFS2 -- Journalling Flash File System, Version 2.
+ *
+ * Copyright (C) 2001-2003 Red Hat, Inc.
+ *
+ * Created by David Woodhouse <dwmw2@infradead.org>
+ *
+ * For licensing information, see the file 'LICENCE' in this directory.
+ *
+ * $Id: debug.h,v 1.21 2005/11/07 11:14:39 gleixner Exp $
+ *
+ */
+#ifndef _JFFS2_DEBUG_H_
+#define _JFFS2_DEBUG_H_
+
+#include <linux/config.h>
+
+#ifndef CONFIG_JFFS2_FS_DEBUG
+#define CONFIG_JFFS2_FS_DEBUG 0
+#endif
+
+#if CONFIG_JFFS2_FS_DEBUG > 0
+/* Enable "paranoia" checks and dumps */
+#define JFFS2_DBG_PARANOIA_CHECKS
+#define JFFS2_DBG_DUMPS
+
+/*
+ * By defining/undefining the below macros one may select debugging messages
+ * fro specific JFFS2 subsystems.
+ */
+#define JFFS2_DBG_READINODE_MESSAGES
+#define JFFS2_DBG_FRAGTREE_MESSAGES
+#define JFFS2_DBG_DENTLIST_MESSAGES
+#define JFFS2_DBG_NODEREF_MESSAGES
+#define JFFS2_DBG_INOCACHE_MESSAGES
+#define JFFS2_DBG_SUMMARY_MESSAGES
+#define JFFS2_DBG_FSBUILD_MESSAGES
+#endif
+
+#if CONFIG_JFFS2_FS_DEBUG > 1
+#define JFFS2_DBG_FRAGTREE2_MESSAGES
+#define JFFS2_DBG_MEMALLOC_MESSAGES
+#endif
+
+/* Sanity checks are supposed to be light-weight and enabled by default */
+#define JFFS2_DBG_SANITY_CHECKS
+
+/*
+ * Dx() are mainly used for debugging messages, they must go away and be
+ * superseded by nicer dbg_xxx() macros...
+ */
+#if CONFIG_JFFS2_FS_DEBUG > 0
+#define D1(x) x
+#else
+#define D1(x)
+#endif
+
+#if CONFIG_JFFS2_FS_DEBUG > 1
+#define D2(x) x
+#else
+#define D2(x)
+#endif
+
+/* The prefixes of JFFS2 messages */
+#define JFFS2_DBG_PREFIX "[JFFS2 DBG]"
+#define JFFS2_ERR_PREFIX "JFFS2 error:"
+#define JFFS2_WARN_PREFIX "JFFS2 warning:"
+#define JFFS2_NOTICE_PREFIX "JFFS2 notice:"
+
+#define JFFS2_ERR KERN_ERR
+#define JFFS2_WARN KERN_WARNING
+#define JFFS2_NOT KERN_NOTICE
+#define JFFS2_DBG KERN_DEBUG
+
+#define JFFS2_DBG_MSG_PREFIX JFFS2_DBG JFFS2_DBG_PREFIX
+#define JFFS2_ERR_MSG_PREFIX JFFS2_ERR JFFS2_ERR_PREFIX
+#define JFFS2_WARN_MSG_PREFIX JFFS2_WARN JFFS2_WARN_PREFIX
+#define JFFS2_NOTICE_MSG_PREFIX JFFS2_NOT JFFS2_NOTICE_PREFIX
+
+/* JFFS2 message macros */
+#define JFFS2_ERROR(fmt, ...) \
+ do { \
+ printk(JFFS2_ERR_MSG_PREFIX \
+ " (%d) %s: " fmt, current->pid, \
+ __FUNCTION__, ##__VA_ARGS__); \
+ } while(0)
+
+#define JFFS2_WARNING(fmt, ...) \
+ do { \
+ printk(JFFS2_WARN_MSG_PREFIX \
+ " (%d) %s: " fmt, current->pid, \
+ __FUNCTION__, ##__VA_ARGS__); \
+ } while(0)
+
+#define JFFS2_NOTICE(fmt, ...) \
+ do { \
+ printk(JFFS2_NOTICE_MSG_PREFIX \
+ " (%d) %s: " fmt, current->pid, \
+ __FUNCTION__, ##__VA_ARGS__); \
+ } while(0)
+
+#define JFFS2_DEBUG(fmt, ...) \
+ do { \
+ printk(JFFS2_DBG_MSG_PREFIX \
+ " (%d) %s: " fmt, current->pid, \
+ __FUNCTION__, ##__VA_ARGS__); \
+ } while(0)
+
+/*
+ * We split our debugging messages on several parts, depending on the JFFS2
+ * subsystem the message belongs to.
+ */
+/* Read inode debugging messages */
+#ifdef JFFS2_DBG_READINODE_MESSAGES
+#define dbg_readinode(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
+#else
+#define dbg_readinode(fmt, ...)
+#endif
+
+/* Fragtree build debugging messages */
+#ifdef JFFS2_DBG_FRAGTREE_MESSAGES
+#define dbg_fragtree(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
+#else
+#define dbg_fragtree(fmt, ...)
+#endif
+#ifdef JFFS2_DBG_FRAGTREE2_MESSAGES
+#define dbg_fragtree2(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
+#else
+#define dbg_fragtree2(fmt, ...)
+#endif
+
+/* Directory entry list manilulation debugging messages */
+#ifdef JFFS2_DBG_DENTLIST_MESSAGES
+#define dbg_dentlist(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
+#else
+#define dbg_dentlist(fmt, ...)
+#endif
+
+/* Print the messages about manipulating node_refs */
+#ifdef JFFS2_DBG_NODEREF_MESSAGES
+#define dbg_noderef(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
+#else
+#define dbg_noderef(fmt, ...)
+#endif
+
+/* Manipulations with the list of inodes (JFFS2 inocache) */
+#ifdef JFFS2_DBG_INOCACHE_MESSAGES
+#define dbg_inocache(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
+#else
+#define dbg_inocache(fmt, ...)
+#endif
+
+/* Summary debugging messages */
+#ifdef JFFS2_DBG_SUMMARY_MESSAGES
+#define dbg_summary(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
+#else
+#define dbg_summary(fmt, ...)
+#endif
+
+/* File system build messages */
+#ifdef JFFS2_DBG_FSBUILD_MESSAGES
+#define dbg_fsbuild(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
+#else
+#define dbg_fsbuild(fmt, ...)
+#endif
+
+/* Watch the object allocations */
+#ifdef JFFS2_DBG_MEMALLOC_MESSAGES
+#define dbg_memalloc(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
+#else
+#define dbg_memalloc(fmt, ...)
+#endif
+
+
+/* "Sanity" checks */
+void
+__jffs2_dbg_acct_sanity_check_nolock(struct jffs2_sb_info *c,
+ struct jffs2_eraseblock *jeb);
+void
+__jffs2_dbg_acct_sanity_check(struct jffs2_sb_info *c,
+ struct jffs2_eraseblock *jeb);
+
+/* "Paranoia" checks */
+void
+__jffs2_dbg_fragtree_paranoia_check(struct jffs2_inode_info *f);
+void
+__jffs2_dbg_fragtree_paranoia_check_nolock(struct jffs2_inode_info *f);
+void
+__jffs2_dbg_acct_paranoia_check(struct jffs2_sb_info *c,
+ struct jffs2_eraseblock *jeb);
+void
+__jffs2_dbg_acct_paranoia_check_nolock(struct jffs2_sb_info *c,
+ struct jffs2_eraseblock *jeb);
+void
+__jffs2_dbg_prewrite_paranoia_check(struct jffs2_sb_info *c,
+ uint32_t ofs, int len);
+
+/* "Dump" functions */
+void
+__jffs2_dbg_dump_jeb(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb);
+void
+__jffs2_dbg_dump_jeb_nolock(struct jffs2_eraseblock *jeb);
+void
+__jffs2_dbg_dump_block_lists(struct jffs2_sb_info *c);
+void
+__jffs2_dbg_dump_block_lists_nolock(struct jffs2_sb_info *c);
+void
+__jffs2_dbg_dump_node_refs(struct jffs2_sb_info *c,
+ struct jffs2_eraseblock *jeb);
+void
+__jffs2_dbg_dump_node_refs_nolock(struct jffs2_sb_info *c,
+ struct jffs2_eraseblock *jeb);
+void
+__jffs2_dbg_dump_fragtree(struct jffs2_inode_info *f);
+void
+__jffs2_dbg_dump_fragtree_nolock(struct jffs2_inode_info *f);
+void
+__jffs2_dbg_dump_buffer(unsigned char *buf, int len, uint32_t offs);
+void
+__jffs2_dbg_dump_node(struct jffs2_sb_info *c, uint32_t ofs);
+
+#ifdef JFFS2_DBG_PARANOIA_CHECKS
+#define jffs2_dbg_fragtree_paranoia_check(f) \
+ __jffs2_dbg_fragtree_paranoia_check(f)
+#define jffs2_dbg_fragtree_paranoia_check_nolock(f) \
+ __jffs2_dbg_fragtree_paranoia_check_nolock(f)
+#define jffs2_dbg_acct_paranoia_check(c, jeb) \
+ __jffs2_dbg_acct_paranoia_check(c,jeb)
+#define jffs2_dbg_acct_paranoia_check_nolock(c, jeb) \
+ __jffs2_dbg_acct_paranoia_check_nolock(c,jeb)
+#define jffs2_dbg_prewrite_paranoia_check(c, ofs, len) \
+ __jffs2_dbg_prewrite_paranoia_check(c, ofs, len)
+#else
+#define jffs2_dbg_fragtree_paranoia_check(f)
+#define jffs2_dbg_fragtree_paranoia_check_nolock(f)
+#define jffs2_dbg_acct_paranoia_check(c, jeb)
+#define jffs2_dbg_acct_paranoia_check_nolock(c, jeb)
+#define jffs2_dbg_prewrite_paranoia_check(c, ofs, len)
+#endif /* !JFFS2_PARANOIA_CHECKS */
+
+#ifdef JFFS2_DBG_DUMPS
+#define jffs2_dbg_dump_jeb(c, jeb) \
+ __jffs2_dbg_dump_jeb(c, jeb);
+#define jffs2_dbg_dump_jeb_nolock(jeb) \
+ __jffs2_dbg_dump_jeb_nolock(jeb);
+#define jffs2_dbg_dump_block_lists(c) \
+ __jffs2_dbg_dump_block_lists(c)
+#define jffs2_dbg_dump_block_lists_nolock(c) \
+ __jffs2_dbg_dump_block_lists_nolock(c)
+#define jffs2_dbg_dump_fragtree(f) \
+ __jffs2_dbg_dump_fragtree(f);
+#define jffs2_dbg_dump_fragtree_nolock(f) \
+ __jffs2_dbg_dump_fragtree_nolock(f);
+#define jffs2_dbg_dump_buffer(buf, len, offs) \
+ __jffs2_dbg_dump_buffer(*buf, len, offs);
+#define jffs2_dbg_dump_node(c, ofs) \
+ __jffs2_dbg_dump_node(c, ofs);
+#else
+#define jffs2_dbg_dump_jeb(c, jeb)
+#define jffs2_dbg_dump_jeb_nolock(jeb)
+#define jffs2_dbg_dump_block_lists(c)
+#define jffs2_dbg_dump_block_lists_nolock(c)
+#define jffs2_dbg_dump_fragtree(f)
+#define jffs2_dbg_dump_fragtree_nolock(f)
+#define jffs2_dbg_dump_buffer(buf, len, offs)
+#define jffs2_dbg_dump_node(c, ofs)
+#endif /* !JFFS2_DBG_DUMPS */
+
+#ifdef JFFS2_DBG_SANITY_CHECKS
+#define jffs2_dbg_acct_sanity_check(c, jeb) \
+ __jffs2_dbg_acct_sanity_check(c, jeb)
+#define jffs2_dbg_acct_sanity_check_nolock(c, jeb) \
+ __jffs2_dbg_acct_sanity_check_nolock(c, jeb)
+#else
+#define jffs2_dbg_acct_sanity_check(c, jeb)
+#define jffs2_dbg_acct_sanity_check_nolock(c, jeb)
+#endif /* !JFFS2_DBG_SANITY_CHECKS */
+
+#endif /* _JFFS2_DEBUG_H_ */
diff --git a/fs/jffs2/dir.c b/fs/jffs2/dir.c
index 3ca0d25eef1d..a7bf9cb2567f 100644
--- a/fs/jffs2/dir.c
+++ b/fs/jffs2/dir.c
@@ -7,7 +7,7 @@
*
* For licensing information, see the file 'LICENCE' in this directory.
*
- * $Id: dir.c,v 1.86 2005/07/06 12:13:09 dwmw2 Exp $
+ * $Id: dir.c,v 1.90 2005/11/07 11:14:39 gleixner Exp $
*
*/
@@ -64,7 +64,7 @@ struct inode_operations jffs2_dir_inode_operations =
/* We keep the dirent list sorted in increasing order of name hash,
- and we use the same hash function as the dentries. Makes this
+ and we use the same hash function as the dentries. Makes this
nice and simple
*/
static struct dentry *jffs2_lookup(struct inode *dir_i, struct dentry *target,
@@ -85,7 +85,7 @@ static struct dentry *jffs2_lookup(struct inode *dir_i, struct dentry *target,
/* NB: The 2.2 backport will need to explicitly check for '.' and '..' here */
for (fd_list = dir_f->dents; fd_list && fd_list->nhash <= target->d_name.hash; fd_list = fd_list->next) {
- if (fd_list->nhash == target->d_name.hash &&
+ if (fd_list->nhash == target->d_name.hash &&
(!fd || fd_list->version > fd->version) &&
strlen(fd_list->name) == target->d_name.len &&
!strncmp(fd_list->name, target->d_name.name, target->d_name.len)) {
@@ -147,7 +147,7 @@ static int jffs2_readdir(struct file *filp, void *dirent, filldir_t filldir)
curofs++;
/* First loop: curofs = 2; offset = 2 */
if (curofs < offset) {
- D2(printk(KERN_DEBUG "Skipping dirent: \"%s\", ino #%u, type %d, because curofs %ld < offset %ld\n",
+ D2(printk(KERN_DEBUG "Skipping dirent: \"%s\", ino #%u, type %d, because curofs %ld < offset %ld\n",
fd->name, fd->ino, fd->type, curofs, offset));
continue;
}
@@ -182,7 +182,7 @@ static int jffs2_create(struct inode *dir_i, struct dentry *dentry, int mode,
ri = jffs2_alloc_raw_inode();
if (!ri)
return -ENOMEM;
-
+
c = JFFS2_SB_INFO(dir_i->i_sb);
D1(printk(KERN_DEBUG "jffs2_create()\n"));
@@ -203,7 +203,7 @@ static int jffs2_create(struct inode *dir_i, struct dentry *dentry, int mode,
f = JFFS2_INODE_INFO(inode);
dir_f = JFFS2_INODE_INFO(dir_i);
- ret = jffs2_do_create(c, dir_f, f, ri,
+ ret = jffs2_do_create(c, dir_f, f, ri,
dentry->d_name.name, dentry->d_name.len);
if (ret) {
@@ -232,11 +232,14 @@ static int jffs2_unlink(struct inode *dir_i, struct dentry *dentry)
struct jffs2_inode_info *dir_f = JFFS2_INODE_INFO(dir_i);
struct jffs2_inode_info *dead_f = JFFS2_INODE_INFO(dentry->d_inode);
int ret;
+ uint32_t now = get_seconds();
- ret = jffs2_do_unlink(c, dir_f, dentry->d_name.name,
- dentry->d_name.len, dead_f);
+ ret = jffs2_do_unlink(c, dir_f, dentry->d_name.name,
+ dentry->d_name.len, dead_f, now);
if (dead_f->inocache)
dentry->d_inode->i_nlink = dead_f->inocache->nlink;
+ if (!ret)
+ dir_i->i_mtime = dir_i->i_ctime = ITIME(now);
return ret;
}
/***********************************************************************/
@@ -249,6 +252,7 @@ static int jffs2_link (struct dentry *old_dentry, struct inode *dir_i, struct de
struct jffs2_inode_info *dir_f = JFFS2_INODE_INFO(dir_i);
int ret;
uint8_t type;
+ uint32_t now;
/* Don't let people make hard links to bad inodes. */
if (!f->inocache)
@@ -261,13 +265,15 @@ static int jffs2_link (struct dentry *old_dentry, struct inode *dir_i, struct de
type = (old_dentry->d_inode->i_mode & S_IFMT) >> 12;
if (!type) type = DT_REG;
- ret = jffs2_do_link(c, dir_f, f->inocache->ino, type, dentry->d_name.name, dentry->d_name.len);
+ now = get_seconds();
+ ret = jffs2_do_link(c, dir_f, f->inocache->ino, type, dentry->d_name.name, dentry->d_name.len, now);
if (!ret) {
down(&f->sem);
old_dentry->d_inode->i_nlink = ++f->inocache->nlink;
up(&f->sem);
d_instantiate(dentry, old_dentry->d_inode);
+ dir_i->i_mtime = dir_i->i_ctime = ITIME(now);
atomic_inc(&old_dentry->d_inode->i_count);
}
return ret;
@@ -297,14 +303,15 @@ static int jffs2_symlink (struct inode *dir_i, struct dentry *dentry, const char
if (!ri)
return -ENOMEM;
-
+
c = JFFS2_SB_INFO(dir_i->i_sb);
-
- /* Try to reserve enough space for both node and dirent.
- * Just the node will do for now, though
+
+ /* Try to reserve enough space for both node and dirent.
+ * Just the node will do for now, though
*/
namelen = dentry->d_name.len;
- ret = jffs2_reserve_space(c, sizeof(*ri) + targetlen, &phys_ofs, &alloclen, ALLOC_NORMAL);
+ ret = jffs2_reserve_space(c, sizeof(*ri) + targetlen, &phys_ofs, &alloclen,
+ ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE);
if (ret) {
jffs2_free_raw_inode(ri);
@@ -331,7 +338,7 @@ static int jffs2_symlink (struct inode *dir_i, struct dentry *dentry, const char
ri->compr = JFFS2_COMPR_NONE;
ri->data_crc = cpu_to_je32(crc32(0, target, targetlen));
ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8));
-
+
fn = jffs2_write_dnode(c, f, ri, target, targetlen, phys_ofs, ALLOC_NORMAL);
jffs2_free_raw_inode(ri);
@@ -344,9 +351,9 @@ static int jffs2_symlink (struct inode *dir_i, struct dentry *dentry, const char
return PTR_ERR(fn);
}
- /* We use f->dents field to store the target path. */
- f->dents = kmalloc(targetlen + 1, GFP_KERNEL);
- if (!f->dents) {
+ /* We use f->target field to store the target path. */
+ f->target = kmalloc(targetlen + 1, GFP_KERNEL);
+ if (!f->target) {
printk(KERN_WARNING "Can't allocate %d bytes of memory\n", targetlen + 1);
up(&f->sem);
jffs2_complete_reservation(c);
@@ -354,17 +361,18 @@ static int jffs2_symlink (struct inode *dir_i, struct dentry *dentry, const char
return -ENOMEM;
}
- memcpy(f->dents, target, targetlen + 1);
- D1(printk(KERN_DEBUG "jffs2_symlink: symlink's target '%s' cached\n", (char *)f->dents));
+ memcpy(f->target, target, targetlen + 1);
+ D1(printk(KERN_DEBUG "jffs2_symlink: symlink's target '%s' cached\n", (char *)f->target));
- /* No data here. Only a metadata node, which will be
+ /* No data here. Only a metadata node, which will be
obsoleted by the first data write
*/
f->metadata = fn;
up(&f->sem);
jffs2_complete_reservation(c);
- ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen, ALLOC_NORMAL);
+ ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen,
+ ALLOC_NORMAL, JFFS2_SUMMARY_DIRENT_SIZE(namelen));
if (ret) {
/* Eep. */
jffs2_clear_inode(inode);
@@ -399,7 +407,7 @@ static int jffs2_symlink (struct inode *dir_i, struct dentry *dentry, const char
fd = jffs2_write_dirent(c, dir_f, rd, dentry->d_name.name, namelen, phys_ofs, ALLOC_NORMAL);
if (IS_ERR(fd)) {
- /* dirent failed to write. Delete the inode normally
+ /* dirent failed to write. Delete the inode normally
as if it were the final unlink() */
jffs2_complete_reservation(c);
jffs2_free_raw_dirent(rd);
@@ -442,14 +450,15 @@ static int jffs2_mkdir (struct inode *dir_i, struct dentry *dentry, int mode)
ri = jffs2_alloc_raw_inode();
if (!ri)
return -ENOMEM;
-
+
c = JFFS2_SB_INFO(dir_i->i_sb);
- /* Try to reserve enough space for both node and dirent.
- * Just the node will do for now, though
+ /* Try to reserve enough space for both node and dirent.
+ * Just the node will do for now, though
*/
namelen = dentry->d_name.len;
- ret = jffs2_reserve_space(c, sizeof(*ri), &phys_ofs, &alloclen, ALLOC_NORMAL);
+ ret = jffs2_reserve_space(c, sizeof(*ri), &phys_ofs, &alloclen, ALLOC_NORMAL,
+ JFFS2_SUMMARY_INODE_SIZE);
if (ret) {
jffs2_free_raw_inode(ri);
@@ -473,7 +482,7 @@ static int jffs2_mkdir (struct inode *dir_i, struct dentry *dentry, int mode)
ri->data_crc = cpu_to_je32(0);
ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8));
-
+
fn = jffs2_write_dnode(c, f, ri, NULL, 0, phys_ofs, ALLOC_NORMAL);
jffs2_free_raw_inode(ri);
@@ -485,20 +494,21 @@ static int jffs2_mkdir (struct inode *dir_i, struct dentry *dentry, int mode)
jffs2_clear_inode(inode);
return PTR_ERR(fn);
}
- /* No data here. Only a metadata node, which will be
+ /* No data here. Only a metadata node, which will be
obsoleted by the first data write
*/
f->metadata = fn;
up(&f->sem);
jffs2_complete_reservation(c);
- ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen, ALLOC_NORMAL);
+ ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen,
+ ALLOC_NORMAL, JFFS2_SUMMARY_DIRENT_SIZE(namelen));
if (ret) {
/* Eep. */
jffs2_clear_inode(inode);
return ret;
}
-
+
rd = jffs2_alloc_raw_dirent();
if (!rd) {
/* Argh. Now we treat it like a normal delete */
@@ -525,9 +535,9 @@ static int jffs2_mkdir (struct inode *dir_i, struct dentry *dentry, int mode)
rd->name_crc = cpu_to_je32(crc32(0, dentry->d_name.name, namelen));
fd = jffs2_write_dirent(c, dir_f, rd, dentry->d_name.name, namelen, phys_ofs, ALLOC_NORMAL);
-
+
if (IS_ERR(fd)) {
- /* dirent failed to write. Delete the inode normally
+ /* dirent failed to write. Delete the inode normally
as if it were the final unlink() */
jffs2_complete_reservation(c);
jffs2_free_raw_dirent(rd);
@@ -589,19 +599,20 @@ static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, int mode, de
ri = jffs2_alloc_raw_inode();
if (!ri)
return -ENOMEM;
-
+
c = JFFS2_SB_INFO(dir_i->i_sb);
-
+
if (S_ISBLK(mode) || S_ISCHR(mode)) {
dev = cpu_to_je16(old_encode_dev(rdev));
devlen = sizeof(dev);
}
-
- /* Try to reserve enough space for both node and dirent.
- * Just the node will do for now, though
+
+ /* Try to reserve enough space for both node and dirent.
+ * Just the node will do for now, though
*/
namelen = dentry->d_name.len;
- ret = jffs2_reserve_space(c, sizeof(*ri) + devlen, &phys_ofs, &alloclen, ALLOC_NORMAL);
+ ret = jffs2_reserve_space(c, sizeof(*ri) + devlen, &phys_ofs, &alloclen,
+ ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE);
if (ret) {
jffs2_free_raw_inode(ri);
@@ -627,7 +638,7 @@ static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, int mode, de
ri->compr = JFFS2_COMPR_NONE;
ri->data_crc = cpu_to_je32(crc32(0, &dev, devlen));
ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8));
-
+
fn = jffs2_write_dnode(c, f, ri, (char *)&dev, devlen, phys_ofs, ALLOC_NORMAL);
jffs2_free_raw_inode(ri);
@@ -639,14 +650,15 @@ static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, int mode, de
jffs2_clear_inode(inode);
return PTR_ERR(fn);
}
- /* No data here. Only a metadata node, which will be
+ /* No data here. Only a metadata node, which will be
obsoleted by the first data write
*/
f->metadata = fn;
up(&f->sem);
jffs2_complete_reservation(c);
- ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen, ALLOC_NORMAL);
+ ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen,
+ ALLOC_NORMAL, JFFS2_SUMMARY_DIRENT_SIZE(namelen));
if (ret) {
/* Eep. */
jffs2_clear_inode(inode);
@@ -682,9 +694,9 @@ static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, int mode, de
rd->name_crc = cpu_to_je32(crc32(0, dentry->d_name.name, namelen));
fd = jffs2_write_dirent(c, dir_f, rd, dentry->d_name.name, namelen, phys_ofs, ALLOC_NORMAL);
-
+
if (IS_ERR(fd)) {
- /* dirent failed to write. Delete the inode normally
+ /* dirent failed to write. Delete the inode normally
as if it were the final unlink() */
jffs2_complete_reservation(c);
jffs2_free_raw_dirent(rd);
@@ -716,8 +728,9 @@ static int jffs2_rename (struct inode *old_dir_i, struct dentry *old_dentry,
struct jffs2_sb_info *c = JFFS2_SB_INFO(old_dir_i->i_sb);
struct jffs2_inode_info *victim_f = NULL;
uint8_t type;
+ uint32_t now;
- /* The VFS will check for us and prevent trying to rename a
+ /* The VFS will check for us and prevent trying to rename a
* file over a directory and vice versa, but if it's a directory,
* the VFS can't check whether the victim is empty. The filesystem
* needs to do that for itself.
@@ -739,19 +752,20 @@ static int jffs2_rename (struct inode *old_dir_i, struct dentry *old_dentry,
}
/* XXX: We probably ought to alloc enough space for
- both nodes at the same time. Writing the new link,
+ both nodes at the same time. Writing the new link,
then getting -ENOSPC, is quite bad :)
*/
/* Make a hard link */
-
+
/* XXX: This is ugly */
type = (old_dentry->d_inode->i_mode & S_IFMT) >> 12;
if (!type) type = DT_REG;
- ret = jffs2_do_link(c, JFFS2_INODE_INFO(new_dir_i),
+ now = get_seconds();
+ ret = jffs2_do_link(c, JFFS2_INODE_INFO(new_dir_i),
old_dentry->d_inode->i_ino, type,
- new_dentry->d_name.name, new_dentry->d_name.len);
+ new_dentry->d_name.name, new_dentry->d_name.len, now);
if (ret)
return ret;
@@ -768,14 +782,14 @@ static int jffs2_rename (struct inode *old_dir_i, struct dentry *old_dentry,
}
}
- /* If it was a directory we moved, and there was no victim,
+ /* If it was a directory we moved, and there was no victim,
increase i_nlink on its new parent */
if (S_ISDIR(old_dentry->d_inode->i_mode) && !victim_f)
new_dir_i->i_nlink++;
/* Unlink the original */
- ret = jffs2_do_unlink(c, JFFS2_INODE_INFO(old_dir_i),
- old_dentry->d_name.name, old_dentry->d_name.len, NULL);
+ ret = jffs2_do_unlink(c, JFFS2_INODE_INFO(old_dir_i),
+ old_dentry->d_name.name, old_dentry->d_name.len, NULL, now);
/* We don't touch inode->i_nlink */
@@ -792,12 +806,15 @@ static int jffs2_rename (struct inode *old_dir_i, struct dentry *old_dentry,
/* Might as well let the VFS know */
d_instantiate(new_dentry, old_dentry->d_inode);
atomic_inc(&old_dentry->d_inode->i_count);
+ new_dir_i->i_mtime = new_dir_i->i_ctime = ITIME(now);
return ret;
}
if (S_ISDIR(old_dentry->d_inode->i_mode))
old_dir_i->i_nlink--;
+ new_dir_i->i_mtime = new_dir_i->i_ctime = old_dir_i->i_mtime = old_dir_i->i_ctime = ITIME(now);
+
return 0;
}
diff --git a/fs/jffs2/erase.c b/fs/jffs2/erase.c
index 787d84ac2bcd..dad68fdffe9e 100644
--- a/fs/jffs2/erase.c
+++ b/fs/jffs2/erase.c
@@ -7,7 +7,7 @@
*
* For licensing information, see the file 'LICENCE' in this directory.
*
- * $Id: erase.c,v 1.80 2005/07/14 19:46:24 joern Exp $
+ * $Id: erase.c,v 1.85 2005/09/20 14:53:15 dedekind Exp $
*
*/
@@ -24,7 +24,7 @@ struct erase_priv_struct {
struct jffs2_eraseblock *jeb;
struct jffs2_sb_info *c;
};
-
+
#ifndef __ECOS
static void jffs2_erase_callback(struct erase_info *);
#endif
@@ -48,7 +48,8 @@ static void jffs2_erase_block(struct jffs2_sb_info *c,
#else /* Linux */
struct erase_info *instr;
- D1(printk(KERN_DEBUG "jffs2_erase_block(): erase block %#x (range %#x-%#x)\n", jeb->offset, jeb->offset, jeb->offset + c->sector_size));
+ D1(printk(KERN_DEBUG "jffs2_erase_block(): erase block %#08x (range %#08x-%#08x)\n",
+ jeb->offset, jeb->offset, jeb->offset + c->sector_size));
instr = kmalloc(sizeof(struct erase_info) + sizeof(struct erase_priv_struct), GFP_KERNEL);
if (!instr) {
printk(KERN_WARNING "kmalloc for struct erase_info in jffs2_erase_block failed. Refiling block for later\n");
@@ -70,7 +71,7 @@ static void jffs2_erase_block(struct jffs2_sb_info *c,
instr->callback = jffs2_erase_callback;
instr->priv = (unsigned long)(&instr[1]);
instr->fail_addr = 0xffffffff;
-
+
((struct erase_priv_struct *)instr->priv)->jeb = jeb;
((struct erase_priv_struct *)instr->priv)->c = c;
@@ -95,7 +96,7 @@ static void jffs2_erase_block(struct jffs2_sb_info *c,
return;
}
- if (ret == -EROFS)
+ if (ret == -EROFS)
printk(KERN_WARNING "Erase at 0x%08x failed immediately: -EROFS. Is the sector locked?\n", jeb->offset);
else
printk(KERN_WARNING "Erase at 0x%08x failed immediately: errno %d\n", jeb->offset, ret);
@@ -196,7 +197,7 @@ static void jffs2_erase_failed(struct jffs2_sb_info *c, struct jffs2_eraseblock
c->nr_erasing_blocks--;
spin_unlock(&c->erase_completion_lock);
wake_up(&c->erase_wait);
-}
+}
#ifndef __ECOS
static void jffs2_erase_callback(struct erase_info *instr)
@@ -208,7 +209,7 @@ static void jffs2_erase_callback(struct erase_info *instr)
jffs2_erase_failed(priv->c, priv->jeb, instr->fail_addr);
} else {
jffs2_erase_succeeded(priv->c, priv->jeb);
- }
+ }
kfree(instr);
}
#endif /* !__ECOS */
@@ -226,13 +227,13 @@ static inline void jffs2_remove_node_refs_from_ino_list(struct jffs2_sb_info *c,
/* Walk the inode's list once, removing any nodes from this eraseblock */
while (1) {
if (!(*prev)->next_in_ino) {
- /* We're looking at the jffs2_inode_cache, which is
+ /* We're looking at the jffs2_inode_cache, which is
at the end of the linked list. Stash it and continue
from the beginning of the list */
ic = (struct jffs2_inode_cache *)(*prev);
prev = &ic->nodes;
continue;
- }
+ }
if (SECTOR_ADDR((*prev)->flash_offset) == jeb->offset) {
/* It's in the block we're erasing */
@@ -266,7 +267,7 @@ static inline void jffs2_remove_node_refs_from_ino_list(struct jffs2_sb_info *c,
printk(KERN_DEBUG "After remove_node_refs_from_ino_list: \n" KERN_DEBUG);
this = ic->nodes;
-
+
while(this) {
printk( "0x%08x(%d)->", ref_offset(this), ref_flags(this));
if (++i == 5) {
@@ -289,7 +290,7 @@ static void jffs2_free_all_node_refs(struct jffs2_sb_info *c, struct jffs2_erase
while(jeb->first_node) {
ref = jeb->first_node;
jeb->first_node = ref->next_phys;
-
+
/* Remove from the inode-list */
if (ref->next_in_ino)
jffs2_remove_node_refs_from_ino_list(c, ref, jeb);
@@ -306,7 +307,7 @@ static int jffs2_block_check_erase(struct jffs2_sb_info *c, struct jffs2_erasebl
uint32_t ofs;
size_t retlen;
int ret = -EIO;
-
+
ebuf = kmalloc(PAGE_SIZE, GFP_KERNEL);
if (!ebuf) {
printk(KERN_WARNING "Failed to allocate page buffer for verifying erase at 0x%08x. Refiling\n", jeb->offset);
@@ -360,7 +361,7 @@ static void jffs2_mark_erased_block(struct jffs2_sb_info *c, struct jffs2_eraseb
case -EIO: goto filebad;
}
- /* Write the erase complete marker */
+ /* Write the erase complete marker */
D1(printk(KERN_DEBUG "Writing erased marker to block at 0x%08x\n", jeb->offset));
bad_offset = jeb->offset;
@@ -398,7 +399,7 @@ static void jffs2_mark_erased_block(struct jffs2_sb_info *c, struct jffs2_eraseb
vecs[0].iov_base = (unsigned char *) &marker;
vecs[0].iov_len = sizeof(marker);
ret = jffs2_flash_direct_writev(c, vecs, 1, jeb->offset, &retlen);
-
+
if (ret || retlen != sizeof(marker)) {
if (ret)
printk(KERN_WARNING "Write clean marker to block at 0x%08x failed: %d\n",
@@ -415,9 +416,9 @@ static void jffs2_mark_erased_block(struct jffs2_sb_info *c, struct jffs2_eraseb
marker_ref->next_phys = NULL;
marker_ref->flash_offset = jeb->offset | REF_NORMAL;
marker_ref->__totlen = c->cleanmarker_size;
-
+
jeb->first_node = jeb->last_node = marker_ref;
-
+
jeb->free_size = c->sector_size - c->cleanmarker_size;
jeb->used_size = c->cleanmarker_size;
jeb->dirty_size = 0;
@@ -429,8 +430,8 @@ static void jffs2_mark_erased_block(struct jffs2_sb_info *c, struct jffs2_eraseb
c->free_size += jeb->free_size;
c->used_size += jeb->used_size;
- ACCT_SANITY_CHECK(c,jeb);
- D1(ACCT_PARANOIA_CHECK(jeb));
+ jffs2_dbg_acct_sanity_check_nolock(c,jeb);
+ jffs2_dbg_acct_paranoia_check_nolock(c, jeb);
list_add_tail(&jeb->list, &c->free_list);
c->nr_erasing_blocks--;
diff --git a/fs/jffs2/file.c b/fs/jffs2/file.c
index 8279bf0133ff..935f273dc57b 100644
--- a/fs/jffs2/file.c
+++ b/fs/jffs2/file.c
@@ -7,7 +7,7 @@
*
* For licensing information, see the file 'LICENCE' in this directory.
*
- * $Id: file.c,v 1.102 2005/07/06 12:13:09 dwmw2 Exp $
+ * $Id: file.c,v 1.104 2005/10/18 23:29:35 tpoynor Exp $
*
*/
@@ -34,8 +34,8 @@ int jffs2_fsync(struct file *filp, struct dentry *dentry, int datasync)
/* Trigger GC to flush any pending writes for this inode */
jffs2_flush_wbuf_gc(c, inode->i_ino);
-
- return 0;
+
+ return 0;
}
struct file_operations jffs2_file_operations =
@@ -107,7 +107,7 @@ static int jffs2_readpage (struct file *filp, struct page *pg)
{
struct jffs2_inode_info *f = JFFS2_INODE_INFO(pg->mapping->host);
int ret;
-
+
down(&f->sem);
ret = jffs2_do_readpage_unlock(pg->mapping->host, pg);
up(&f->sem);
@@ -130,11 +130,12 @@ static int jffs2_prepare_write (struct file *filp, struct page *pg,
struct jffs2_raw_inode ri;
struct jffs2_full_dnode *fn;
uint32_t phys_ofs, alloc_len;
-
+
D1(printk(KERN_DEBUG "Writing new hole frag 0x%x-0x%x between current EOF and new page\n",
(unsigned int)inode->i_size, pageofs));
- ret = jffs2_reserve_space(c, sizeof(ri), &phys_ofs, &alloc_len, ALLOC_NORMAL);
+ ret = jffs2_reserve_space(c, sizeof(ri), &phys_ofs, &alloc_len,
+ ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE);
if (ret)
return ret;
@@ -159,7 +160,7 @@ static int jffs2_prepare_write (struct file *filp, struct page *pg,
ri.compr = JFFS2_COMPR_ZERO;
ri.node_crc = cpu_to_je32(crc32(0, &ri, sizeof(ri)-8));
ri.data_crc = cpu_to_je32(0);
-
+
fn = jffs2_write_dnode(c, f, &ri, NULL, 0, phys_ofs, ALLOC_NORMAL);
if (IS_ERR(fn)) {
@@ -186,7 +187,7 @@ static int jffs2_prepare_write (struct file *filp, struct page *pg,
inode->i_size = pageofs;
up(&f->sem);
}
-
+
/* Read in the page if it wasn't already present, unless it's a whole page */
if (!PageUptodate(pg) && (start || end < PAGE_CACHE_SIZE)) {
down(&f->sem);
@@ -217,7 +218,7 @@ static int jffs2_commit_write (struct file *filp, struct page *pg,
if (!start && end == PAGE_CACHE_SIZE) {
/* We need to avoid deadlock with page_cache_read() in
jffs2_garbage_collect_pass(). So we have to mark the
- page up to date, to prevent page_cache_read() from
+ page up to date, to prevent page_cache_read() from
trying to re-lock it. */
SetPageUptodate(pg);
}
@@ -251,7 +252,7 @@ static int jffs2_commit_write (struct file *filp, struct page *pg,
/* There was an error writing. */
SetPageError(pg);
}
-
+
/* Adjust writtenlen for the padding we did, so we don't confuse our caller */
if (writtenlen < (start&3))
writtenlen = 0;
@@ -262,7 +263,7 @@ static int jffs2_commit_write (struct file *filp, struct page *pg,
if (inode->i_size < (pg->index << PAGE_CACHE_SHIFT) + start + writtenlen) {
inode->i_size = (pg->index << PAGE_CACHE_SHIFT) + start + writtenlen;
inode->i_blocks = (inode->i_size + 511) >> 9;
-
+
inode->i_ctime = inode->i_mtime = ITIME(je32_to_cpu(ri->ctime));
}
}
@@ -271,13 +272,13 @@ static int jffs2_commit_write (struct file *filp, struct page *pg,
if (start+writtenlen < end) {
/* generic_file_write has written more to the page cache than we've
- actually written to the medium. Mark the page !Uptodate so that
+ actually written to the medium. Mark the page !Uptodate so that
it gets reread */
D1(printk(KERN_DEBUG "jffs2_commit_write(): Not all bytes written. Marking page !uptodate\n"));
SetPageError(pg);
ClearPageUptodate(pg);
}
- D1(printk(KERN_DEBUG "jffs2_commit_write() returning %d\n",writtenlen?writtenlen:ret));
- return writtenlen?writtenlen:ret;
+ D1(printk(KERN_DEBUG "jffs2_commit_write() returning %d\n",start+writtenlen==end?0:ret));
+ return start+writtenlen==end?0:ret;
}
diff --git a/fs/jffs2/fs.c b/fs/jffs2/fs.c
index 5687c3f42002..543420665c5b 100644
--- a/fs/jffs2/fs.c
+++ b/fs/jffs2/fs.c
@@ -7,7 +7,7 @@
*
* For licensing information, see the file 'LICENCE' in this directory.
*
- * $Id: fs.c,v 1.56 2005/07/06 12:13:09 dwmw2 Exp $
+ * $Id: fs.c,v 1.66 2005/09/27 13:17:29 dedekind Exp $
*
*/
@@ -40,7 +40,7 @@ static int jffs2_do_setattr (struct inode *inode, struct iattr *iattr)
int ret;
D1(printk(KERN_DEBUG "jffs2_setattr(): ino #%lu\n", inode->i_ino));
ret = inode_change_ok(inode, iattr);
- if (ret)
+ if (ret)
return ret;
/* Special cases - we don't want more than one data node
@@ -73,8 +73,9 @@ static int jffs2_do_setattr (struct inode *inode, struct iattr *iattr)
kfree(mdata);
return -ENOMEM;
}
-
- ret = jffs2_reserve_space(c, sizeof(*ri) + mdatalen, &phys_ofs, &alloclen, ALLOC_NORMAL);
+
+ ret = jffs2_reserve_space(c, sizeof(*ri) + mdatalen, &phys_ofs, &alloclen,
+ ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE);
if (ret) {
jffs2_free_raw_inode(ri);
if (S_ISLNK(inode->i_mode & S_IFMT))
@@ -83,7 +84,7 @@ static int jffs2_do_setattr (struct inode *inode, struct iattr *iattr)
}
down(&f->sem);
ivalid = iattr->ia_valid;
-
+
ri->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
ri->nodetype = cpu_to_je16(JFFS2_NODETYPE_INODE);
ri->totlen = cpu_to_je32(sizeof(*ri) + mdatalen);
@@ -99,7 +100,7 @@ static int jffs2_do_setattr (struct inode *inode, struct iattr *iattr)
if (iattr->ia_mode & S_ISGID &&
!in_group_p(je16_to_cpu(ri->gid)) && !capable(CAP_FSETID))
ri->mode = cpu_to_jemode(iattr->ia_mode & ~S_ISGID);
- else
+ else
ri->mode = cpu_to_jemode(iattr->ia_mode);
else
ri->mode = cpu_to_jemode(inode->i_mode);
@@ -128,7 +129,7 @@ static int jffs2_do_setattr (struct inode *inode, struct iattr *iattr)
new_metadata = jffs2_write_dnode(c, f, ri, mdata, mdatalen, phys_ofs, ALLOC_NORMAL);
if (S_ISLNK(inode->i_mode))
kfree(mdata);
-
+
if (IS_ERR(new_metadata)) {
jffs2_complete_reservation(c);
jffs2_free_raw_inode(ri);
@@ -147,7 +148,7 @@ static int jffs2_do_setattr (struct inode *inode, struct iattr *iattr)
old_metadata = f->metadata;
if (ivalid & ATTR_SIZE && inode->i_size > iattr->ia_size)
- jffs2_truncate_fraglist (c, &f->fragtree, iattr->ia_size);
+ jffs2_truncate_fragtree (c, &f->fragtree, iattr->ia_size);
if (ivalid & ATTR_SIZE && inode->i_size < iattr->ia_size) {
jffs2_add_full_dnode_to_inode(c, f, new_metadata);
@@ -166,7 +167,7 @@ static int jffs2_do_setattr (struct inode *inode, struct iattr *iattr)
jffs2_complete_reservation(c);
/* We have to do the vmtruncate() without f->sem held, since
- some pages may be locked and waiting for it in readpage().
+ some pages may be locked and waiting for it in readpage().
We are protected from a simultaneous write() extending i_size
back past iattr->ia_size, because do_truncate() holds the
generic inode semaphore. */
@@ -194,31 +195,27 @@ int jffs2_statfs(struct super_block *sb, struct kstatfs *buf)
buf->f_namelen = JFFS2_MAX_NAME_LEN;
spin_lock(&c->erase_completion_lock);
-
avail = c->dirty_size + c->free_size;
if (avail > c->sector_size * c->resv_blocks_write)
avail -= c->sector_size * c->resv_blocks_write;
else
avail = 0;
+ spin_unlock(&c->erase_completion_lock);
buf->f_bavail = buf->f_bfree = avail >> PAGE_SHIFT;
- D2(jffs2_dump_block_lists(c));
-
- spin_unlock(&c->erase_completion_lock);
-
return 0;
}
void jffs2_clear_inode (struct inode *inode)
{
- /* We can forget about this inode for now - drop all
+ /* We can forget about this inode for now - drop all
* the nodelists associated with it, etc.
*/
struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
-
+
D1(printk(KERN_DEBUG "jffs2_clear_inode(): ino #%lu mode %o\n", inode->i_ino, inode->i_mode));
jffs2_do_clear_inode(c, f);
@@ -237,7 +234,7 @@ void jffs2_read_inode (struct inode *inode)
c = JFFS2_SB_INFO(inode->i_sb);
jffs2_init_inode_info(f);
-
+
ret = jffs2_do_read_inode(c, f, inode->i_ino, &latest_node);
if (ret) {
@@ -257,14 +254,14 @@ void jffs2_read_inode (struct inode *inode)
inode->i_blksize = PAGE_SIZE;
inode->i_blocks = (inode->i_size + 511) >> 9;
-
+
switch (inode->i_mode & S_IFMT) {
jint16_t rdev;
case S_IFLNK:
inode->i_op = &jffs2_symlink_inode_operations;
break;
-
+
case S_IFDIR:
{
struct jffs2_full_dirent *fd;
@@ -301,7 +298,7 @@ void jffs2_read_inode (struct inode *inode)
jffs2_do_clear_inode(c, f);
make_bad_inode(inode);
return;
- }
+ }
case S_IFSOCK:
case S_IFIFO:
@@ -357,11 +354,11 @@ int jffs2_remount_fs (struct super_block *sb, int *flags, char *data)
down(&c->alloc_sem);
jffs2_flush_wbuf_pad(c);
up(&c->alloc_sem);
- }
+ }
if (!(*flags & MS_RDONLY))
jffs2_start_garbage_collect_thread(c);
-
+
*flags |= MS_NOATIME;
return 0;
@@ -395,9 +392,9 @@ struct inode *jffs2_new_inode (struct inode *dir_i, int mode, struct jffs2_raw_i
D1(printk(KERN_DEBUG "jffs2_new_inode(): dir_i %ld, mode 0x%x\n", dir_i->i_ino, mode));
c = JFFS2_SB_INFO(sb);
-
+
inode = new_inode(sb);
-
+
if (!inode)
return ERR_PTR(-ENOMEM);
@@ -461,40 +458,24 @@ int jffs2_do_fill_super(struct super_block *sb, void *data, int silent)
#endif
c->flash_size = c->mtd->size;
-
- /*
- * Check, if we have to concatenate physical blocks to larger virtual blocks
- * to reduce the memorysize for c->blocks. (kmalloc allows max. 128K allocation)
- */
- c->sector_size = c->mtd->erasesize;
+ c->sector_size = c->mtd->erasesize;
blocks = c->flash_size / c->sector_size;
- if (!(c->mtd->flags & MTD_NO_VIRTBLOCKS)) {
- while ((blocks * sizeof (struct jffs2_eraseblock)) > (128 * 1024)) {
- blocks >>= 1;
- c->sector_size <<= 1;
- }
- }
/*
* Size alignment check
*/
if ((c->sector_size * blocks) != c->flash_size) {
- c->flash_size = c->sector_size * blocks;
+ c->flash_size = c->sector_size * blocks;
printk(KERN_INFO "jffs2: Flash size not aligned to erasesize, reducing to %dKiB\n",
c->flash_size / 1024);
}
- if (c->sector_size != c->mtd->erasesize)
- printk(KERN_INFO "jffs2: Erase block size too small (%dKiB). Using virtual blocks size (%dKiB) instead\n",
- c->mtd->erasesize / 1024, c->sector_size / 1024);
-
if (c->flash_size < 5*c->sector_size) {
printk(KERN_ERR "jffs2: Too few erase blocks (%d)\n", c->flash_size / c->sector_size);
return -EINVAL;
}
c->cleanmarker_size = sizeof(struct jffs2_unknown_node);
- /* Joern -- stick alignment for weird 8-byte-page flash here */
/* NAND (or other bizarre) flash... do setup accordingly */
ret = jffs2_flash_setup(c);
@@ -517,7 +498,7 @@ int jffs2_do_fill_super(struct super_block *sb, void *data, int silent)
root_i = iget(sb, 1);
if (is_bad_inode(root_i)) {
D1(printk(KERN_WARNING "get root inode failed\n"));
- goto out_nodes;
+ goto out_root_i;
}
D1(printk(KERN_DEBUG "jffs2_do_fill_super(): d_alloc_root()\n"));
@@ -535,10 +516,9 @@ int jffs2_do_fill_super(struct super_block *sb, void *data, int silent)
out_root_i:
iput(root_i);
- out_nodes:
jffs2_free_ino_caches(c);
jffs2_free_raw_node_refs(c);
- if (c->mtd->flags & MTD_NO_VIRTBLOCKS)
+ if (jffs2_blocks_use_vmalloc(c))
vfree(c->blocks);
else
kfree(c->blocks);
@@ -563,16 +543,16 @@ struct jffs2_inode_info *jffs2_gc_fetch_inode(struct jffs2_sb_info *c,
struct jffs2_inode_cache *ic;
if (!nlink) {
/* The inode has zero nlink but its nodes weren't yet marked
- obsolete. This has to be because we're still waiting for
+ obsolete. This has to be because we're still waiting for
the final (close() and) iput() to happen.
- There's a possibility that the final iput() could have
+ There's a possibility that the final iput() could have
happened while we were contemplating. In order to ensure
that we don't cause a new read_inode() (which would fail)
for the inode in question, we use ilookup() in this case
instead of iget().
- The nlink can't _become_ zero at this point because we're
+ The nlink can't _become_ zero at this point because we're
holding the alloc_sem, and jffs2_do_unlink() would also
need that while decrementing nlink on any inode.
*/
@@ -619,19 +599,19 @@ struct jffs2_inode_info *jffs2_gc_fetch_inode(struct jffs2_sb_info *c,
return JFFS2_INODE_INFO(inode);
}
-unsigned char *jffs2_gc_fetch_page(struct jffs2_sb_info *c,
- struct jffs2_inode_info *f,
+unsigned char *jffs2_gc_fetch_page(struct jffs2_sb_info *c,
+ struct jffs2_inode_info *f,
unsigned long offset,
unsigned long *priv)
{
struct inode *inode = OFNI_EDONI_2SFFJ(f);
struct page *pg;
- pg = read_cache_page(inode->i_mapping, offset >> PAGE_CACHE_SHIFT,
+ pg = read_cache_page(inode->i_mapping, offset >> PAGE_CACHE_SHIFT,
(void *)jffs2_do_readpage_unlock, inode);
if (IS_ERR(pg))
return (void *)pg;
-
+
*priv = (unsigned long)pg;
return kmap(pg);
}
@@ -648,7 +628,7 @@ void jffs2_gc_release_page(struct jffs2_sb_info *c,
static int jffs2_flash_setup(struct jffs2_sb_info *c) {
int ret = 0;
-
+
if (jffs2_cleanmarker_oob(c)) {
/* NAND flash... do setup accordingly */
ret = jffs2_nand_flash_setup(c);
@@ -662,14 +642,21 @@ static int jffs2_flash_setup(struct jffs2_sb_info *c) {
if (ret)
return ret;
}
-
+
/* and Dataflash */
if (jffs2_dataflash(c)) {
ret = jffs2_dataflash_setup(c);
if (ret)
return ret;
}
-
+
+ /* and Intel "Sibley" flash */
+ if (jffs2_nor_wbuf_flash(c)) {
+ ret = jffs2_nor_wbuf_flash_setup(c);
+ if (ret)
+ return ret;
+ }
+
return ret;
}
@@ -683,9 +670,14 @@ void jffs2_flash_cleanup(struct jffs2_sb_info *c) {
if (jffs2_nor_ecc(c)) {
jffs2_nor_ecc_flash_cleanup(c);
}
-
+
/* and DataFlash */
if (jffs2_dataflash(c)) {
jffs2_dataflash_cleanup(c);
}
+
+ /* and Intel "Sibley" flash */
+ if (jffs2_nor_wbuf_flash(c)) {
+ jffs2_nor_wbuf_flash_cleanup(c);
+ }
}
diff --git a/fs/jffs2/gc.c b/fs/jffs2/gc.c
index 7086cd634503..f9ffece453a3 100644
--- a/fs/jffs2/gc.c
+++ b/fs/jffs2/gc.c
@@ -7,7 +7,7 @@
*
* For licensing information, see the file 'LICENCE' in this directory.
*
- * $Id: gc.c,v 1.148 2005/04/09 10:47:00 dedekind Exp $
+ * $Id: gc.c,v 1.155 2005/11/07 11:14:39 gleixner Exp $
*
*/
@@ -21,14 +21,14 @@
#include "nodelist.h"
#include "compr.h"
-static int jffs2_garbage_collect_pristine(struct jffs2_sb_info *c,
+static int jffs2_garbage_collect_pristine(struct jffs2_sb_info *c,
struct jffs2_inode_cache *ic,
struct jffs2_raw_node_ref *raw);
-static int jffs2_garbage_collect_metadata(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
+static int jffs2_garbage_collect_metadata(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
struct jffs2_inode_info *f, struct jffs2_full_dnode *fd);
-static int jffs2_garbage_collect_dirent(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
+static int jffs2_garbage_collect_dirent(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
struct jffs2_inode_info *f, struct jffs2_full_dirent *fd);
-static int jffs2_garbage_collect_deletion_dirent(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
+static int jffs2_garbage_collect_deletion_dirent(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
struct jffs2_inode_info *f, struct jffs2_full_dirent *fd);
static int jffs2_garbage_collect_hole(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
struct jffs2_inode_info *f, struct jffs2_full_dnode *fn,
@@ -55,7 +55,7 @@ again:
D1(printk(KERN_DEBUG "Picking block from bad_used_list to GC next\n"));
nextlist = &c->bad_used_list;
} else if (n < 50 && !list_empty(&c->erasable_list)) {
- /* Note that most of them will have gone directly to be erased.
+ /* Note that most of them will have gone directly to be erased.
So don't favour the erasable_list _too_ much. */
D1(printk(KERN_DEBUG "Picking block from erasable_list to GC next\n"));
nextlist = &c->erasable_list;
@@ -101,7 +101,7 @@ again:
printk(KERN_WARNING "Eep. ret->gc_node for block at 0x%08x is NULL\n", ret->offset);
BUG();
}
-
+
/* Have we accidentally picked a clean block with wasted space ? */
if (ret->wasted_size) {
D1(printk(KERN_DEBUG "Converting wasted_size %08x to dirty_size\n", ret->wasted_size));
@@ -111,7 +111,6 @@ again:
ret->wasted_size = 0;
}
- D2(jffs2_dump_block_lists(c));
return ret;
}
@@ -137,12 +136,12 @@ int jffs2_garbage_collect_pass(struct jffs2_sb_info *c)
/* We can't start doing GC yet. We haven't finished checking
the node CRCs etc. Do it now. */
-
+
/* checked_ino is protected by the alloc_sem */
if (c->checked_ino > c->highest_ino) {
printk(KERN_CRIT "Checked all inodes but still 0x%x bytes of unchecked space?\n",
c->unchecked_size);
- D2(jffs2_dump_block_lists(c));
+ jffs2_dbg_dump_block_lists_nolock(c);
spin_unlock(&c->erase_completion_lock);
BUG();
}
@@ -179,7 +178,7 @@ int jffs2_garbage_collect_pass(struct jffs2_sb_info *c)
case INO_STATE_READING:
/* We need to wait for it to finish, lest we move on
- and trigger the BUG() above while we haven't yet
+ and trigger the BUG() above while we haven't yet
finished checking all its nodes */
D1(printk(KERN_DEBUG "Waiting for ino #%u to finish reading\n", ic->ino));
up(&c->alloc_sem);
@@ -229,13 +228,13 @@ int jffs2_garbage_collect_pass(struct jffs2_sb_info *c)
}
raw = jeb->gc_node;
-
+
while(ref_obsolete(raw)) {
D1(printk(KERN_DEBUG "Node at 0x%08x is obsolete... skipping\n", ref_offset(raw)));
raw = raw->next_phys;
if (unlikely(!raw)) {
printk(KERN_WARNING "eep. End of raw list while still supposedly nodes to GC\n");
- printk(KERN_WARNING "erase block at 0x%08x. free_size 0x%08x, dirty_size 0x%08x, used_size 0x%08x\n",
+ printk(KERN_WARNING "erase block at 0x%08x. free_size 0x%08x, dirty_size 0x%08x, used_size 0x%08x\n",
jeb->offset, jeb->free_size, jeb->dirty_size, jeb->used_size);
jeb->gc_node = raw;
spin_unlock(&c->erase_completion_lock);
@@ -260,7 +259,7 @@ int jffs2_garbage_collect_pass(struct jffs2_sb_info *c)
ic = jffs2_raw_ref_to_ic(raw);
/* We need to hold the inocache. Either the erase_completion_lock or
- the inocache_lock are sufficient; we trade down since the inocache_lock
+ the inocache_lock are sufficient; we trade down since the inocache_lock
causes less contention. */
spin_lock(&c->inocache_lock);
@@ -279,14 +278,14 @@ int jffs2_garbage_collect_pass(struct jffs2_sb_info *c)
switch(ic->state) {
case INO_STATE_CHECKEDABSENT:
- /* It's been checked, but it's not currently in-core.
+ /* It's been checked, but it's not currently in-core.
We can just copy any pristine nodes, but have
to prevent anyone else from doing read_inode() while
we're at it, so we set the state accordingly */
if (ref_flags(raw) == REF_PRISTINE)
ic->state = INO_STATE_GC;
else {
- D1(printk(KERN_DEBUG "Ino #%u is absent but node not REF_PRISTINE. Reading.\n",
+ D1(printk(KERN_DEBUG "Ino #%u is absent but node not REF_PRISTINE. Reading.\n",
ic->ino));
}
break;
@@ -299,8 +298,8 @@ int jffs2_garbage_collect_pass(struct jffs2_sb_info *c)
case INO_STATE_CHECKING:
case INO_STATE_GC:
/* Should never happen. We should have finished checking
- by the time we actually start doing any GC, and since
- we're holding the alloc_sem, no other garbage collection
+ by the time we actually start doing any GC, and since
+ we're holding the alloc_sem, no other garbage collection
can happen.
*/
printk(KERN_CRIT "Inode #%u already in state %d in jffs2_garbage_collect_pass()!\n",
@@ -320,21 +319,21 @@ int jffs2_garbage_collect_pass(struct jffs2_sb_info *c)
D1(printk(KERN_DEBUG "jffs2_garbage_collect_pass() waiting for ino #%u in state %d\n",
ic->ino, ic->state));
sleep_on_spinunlock(&c->inocache_wq, &c->inocache_lock);
- /* And because we dropped the alloc_sem we must start again from the
+ /* And because we dropped the alloc_sem we must start again from the
beginning. Ponder chance of livelock here -- we're returning success
without actually making any progress.
- Q: What are the chances that the inode is back in INO_STATE_READING
+ Q: What are the chances that the inode is back in INO_STATE_READING
again by the time we next enter this function? And that this happens
enough times to cause a real delay?
- A: Small enough that I don't care :)
+ A: Small enough that I don't care :)
*/
return 0;
}
/* OK. Now if the inode is in state INO_STATE_GC, we are going to copy the
- node intact, and we don't have to muck about with the fragtree etc.
+ node intact, and we don't have to muck about with the fragtree etc.
because we know it's not in-core. If it _was_ in-core, we go through
all the iget() crap anyway */
@@ -454,7 +453,7 @@ static int jffs2_garbage_collect_live(struct jffs2_sb_info *c, struct jffs2_era
if (!ret) {
/* Urgh. Return it sensibly. */
frag->node->raw = f->inocache->nodes;
- }
+ }
if (ret != -EBADFD)
goto upnout;
}
@@ -468,7 +467,7 @@ static int jffs2_garbage_collect_live(struct jffs2_sb_info *c, struct jffs2_era
}
goto upnout;
}
-
+
/* Wasn't a dnode. Try dirent */
for (fd = f->dents; fd; fd=fd->next) {
if (fd->raw == raw)
@@ -485,7 +484,8 @@ static int jffs2_garbage_collect_live(struct jffs2_sb_info *c, struct jffs2_era
if (ref_obsolete(raw)) {
printk(KERN_WARNING "But it's obsolete so we don't mind too much\n");
} else {
- ret = -EIO;
+ jffs2_dbg_dump_node(c, ref_offset(raw));
+ BUG();
}
}
upnout:
@@ -494,7 +494,7 @@ static int jffs2_garbage_collect_live(struct jffs2_sb_info *c, struct jffs2_era
return ret;
}
-static int jffs2_garbage_collect_pristine(struct jffs2_sb_info *c,
+static int jffs2_garbage_collect_pristine(struct jffs2_sb_info *c,
struct jffs2_inode_cache *ic,
struct jffs2_raw_node_ref *raw)
{
@@ -513,8 +513,11 @@ static int jffs2_garbage_collect_pristine(struct jffs2_sb_info *c,
/* Ask for a small amount of space (or the totlen if smaller) because we
don't want to force wastage of the end of a block if splitting would
work. */
- ret = jffs2_reserve_space_gc(c, min_t(uint32_t, sizeof(struct jffs2_raw_inode) + JFFS2_MIN_DATA_LEN,
- rawlen), &phys_ofs, &alloclen);
+ ret = jffs2_reserve_space_gc(c, min_t(uint32_t, sizeof(struct jffs2_raw_inode) +
+ JFFS2_MIN_DATA_LEN, rawlen), &phys_ofs, &alloclen, rawlen);
+ /* this is not the exact summary size of it,
+ it is only an upper estimation */
+
if (ret)
return ret;
@@ -577,7 +580,7 @@ static int jffs2_garbage_collect_pristine(struct jffs2_sb_info *c,
}
break;
default:
- printk(KERN_WARNING "Unknown node type for REF_PRISTINE node at 0x%08x: 0x%04x\n",
+ printk(KERN_WARNING "Unknown node type for REF_PRISTINE node at 0x%08x: 0x%04x\n",
ref_offset(raw), je16_to_cpu(node->u.nodetype));
goto bail;
}
@@ -618,17 +621,19 @@ static int jffs2_garbage_collect_pristine(struct jffs2_sb_info *c,
retried = 1;
D1(printk(KERN_DEBUG "Retrying failed write of REF_PRISTINE node.\n"));
-
- ACCT_SANITY_CHECK(c,jeb);
- D1(ACCT_PARANOIA_CHECK(jeb));
- ret = jffs2_reserve_space_gc(c, rawlen, &phys_ofs, &dummy);
+ jffs2_dbg_acct_sanity_check(c,jeb);
+ jffs2_dbg_acct_paranoia_check(c, jeb);
+
+ ret = jffs2_reserve_space_gc(c, rawlen, &phys_ofs, &dummy, rawlen);
+ /* this is not the exact summary size of it,
+ it is only an upper estimation */
if (!ret) {
D1(printk(KERN_DEBUG "Allocated space at 0x%08x to retry failed write.\n", phys_ofs));
- ACCT_SANITY_CHECK(c,jeb);
- D1(ACCT_PARANOIA_CHECK(jeb));
+ jffs2_dbg_acct_sanity_check(c,jeb);
+ jffs2_dbg_acct_paranoia_check(c, jeb);
goto retry;
}
@@ -664,7 +669,7 @@ static int jffs2_garbage_collect_pristine(struct jffs2_sb_info *c,
goto out_node;
}
-static int jffs2_garbage_collect_metadata(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
+static int jffs2_garbage_collect_metadata(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
struct jffs2_inode_info *f, struct jffs2_full_dnode *fn)
{
struct jffs2_full_dnode *new_fn;
@@ -679,7 +684,7 @@ static int jffs2_garbage_collect_metadata(struct jffs2_sb_info *c, struct jffs2_
S_ISCHR(JFFS2_F_I_MODE(f)) ) {
/* For these, we don't actually need to read the old node */
/* FIXME: for minor or major > 255. */
- dev = cpu_to_je16(((JFFS2_F_I_RDEV_MAJ(f) << 8) |
+ dev = cpu_to_je16(((JFFS2_F_I_RDEV_MAJ(f) << 8) |
JFFS2_F_I_RDEV_MIN(f)));
mdata = (char *)&dev;
mdatalen = sizeof(dev);
@@ -700,14 +705,15 @@ static int jffs2_garbage_collect_metadata(struct jffs2_sb_info *c, struct jffs2_
D1(printk(KERN_DEBUG "jffs2_garbage_collect_metadata(): Writing %d bites of symlink target\n", mdatalen));
}
-
- ret = jffs2_reserve_space_gc(c, sizeof(ri) + mdatalen, &phys_ofs, &alloclen);
+
+ ret = jffs2_reserve_space_gc(c, sizeof(ri) + mdatalen, &phys_ofs, &alloclen,
+ JFFS2_SUMMARY_INODE_SIZE);
if (ret) {
printk(KERN_WARNING "jffs2_reserve_space_gc of %zd bytes for garbage_collect_metadata failed: %d\n",
sizeof(ri)+ mdatalen, ret);
goto out;
}
-
+
last_frag = frag_last(&f->fragtree);
if (last_frag)
/* Fetch the inode length from the fragtree rather then
@@ -715,7 +721,7 @@ static int jffs2_garbage_collect_metadata(struct jffs2_sb_info *c, struct jffs2_
ilen = last_frag->ofs + last_frag->size;
else
ilen = JFFS2_F_I_SIZE(f);
-
+
memset(&ri, 0, sizeof(ri));
ri.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
ri.nodetype = cpu_to_je16(JFFS2_NODETYPE_INODE);
@@ -754,7 +760,7 @@ static int jffs2_garbage_collect_metadata(struct jffs2_sb_info *c, struct jffs2_
return ret;
}
-static int jffs2_garbage_collect_dirent(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
+static int jffs2_garbage_collect_dirent(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
struct jffs2_inode_info *f, struct jffs2_full_dirent *fd)
{
struct jffs2_full_dirent *new_fd;
@@ -771,12 +777,18 @@ static int jffs2_garbage_collect_dirent(struct jffs2_sb_info *c, struct jffs2_er
rd.pino = cpu_to_je32(f->inocache->ino);
rd.version = cpu_to_je32(++f->highest_version);
rd.ino = cpu_to_je32(fd->ino);
- rd.mctime = cpu_to_je32(max(JFFS2_F_I_MTIME(f), JFFS2_F_I_CTIME(f)));
+ /* If the times on this inode were set by explicit utime() they can be different,
+ so refrain from splatting them. */
+ if (JFFS2_F_I_MTIME(f) == JFFS2_F_I_CTIME(f))
+ rd.mctime = cpu_to_je32(JFFS2_F_I_MTIME(f));
+ else
+ rd.mctime = cpu_to_je32(0);
rd.type = fd->type;
rd.node_crc = cpu_to_je32(crc32(0, &rd, sizeof(rd)-8));
rd.name_crc = cpu_to_je32(crc32(0, fd->name, rd.nsize));
-
- ret = jffs2_reserve_space_gc(c, sizeof(rd)+rd.nsize, &phys_ofs, &alloclen);
+
+ ret = jffs2_reserve_space_gc(c, sizeof(rd)+rd.nsize, &phys_ofs, &alloclen,
+ JFFS2_SUMMARY_DIRENT_SIZE(rd.nsize));
if (ret) {
printk(KERN_WARNING "jffs2_reserve_space_gc of %zd bytes for garbage_collect_dirent failed: %d\n",
sizeof(rd)+rd.nsize, ret);
@@ -792,7 +804,7 @@ static int jffs2_garbage_collect_dirent(struct jffs2_sb_info *c, struct jffs2_er
return 0;
}
-static int jffs2_garbage_collect_deletion_dirent(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
+static int jffs2_garbage_collect_deletion_dirent(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
struct jffs2_inode_info *f, struct jffs2_full_dirent *fd)
{
struct jffs2_full_dirent **fdp = &f->dents;
@@ -831,7 +843,7 @@ static int jffs2_garbage_collect_deletion_dirent(struct jffs2_sb_info *c, struct
if (ref_totlen(c, NULL, raw) != rawlen)
continue;
- /* Doesn't matter if there's one in the same erase block. We're going to
+ /* Doesn't matter if there's one in the same erase block. We're going to
delete it too at the same time. */
if (SECTOR_ADDR(raw->flash_offset) == SECTOR_ADDR(fd->raw->flash_offset))
continue;
@@ -883,6 +895,9 @@ static int jffs2_garbage_collect_deletion_dirent(struct jffs2_sb_info *c, struct
kfree(rd);
}
+ /* FIXME: If we're deleting a dirent which contains the current mtime and ctime,
+ we should update the metadata node with those times accordingly */
+
/* No need for it any more. Just mark it obsolete and remove it from the list */
while (*fdp) {
if ((*fdp) == fd) {
@@ -912,13 +927,13 @@ static int jffs2_garbage_collect_hole(struct jffs2_sb_info *c, struct jffs2_eras
D1(printk(KERN_DEBUG "Writing replacement hole node for ino #%u from offset 0x%x to 0x%x\n",
f->inocache->ino, start, end));
-
+
memset(&ri, 0, sizeof(ri));
if(fn->frags > 1) {
size_t readlen;
uint32_t crc;
- /* It's partially obsoleted by a later write. So we have to
+ /* It's partially obsoleted by a later write. So we have to
write it out again with the _same_ version as before */
ret = jffs2_flash_read(c, ref_offset(fn->raw), sizeof(ri), &readlen, (char *)&ri);
if (readlen != sizeof(ri) || ret) {
@@ -940,16 +955,16 @@ static int jffs2_garbage_collect_hole(struct jffs2_sb_info *c, struct jffs2_eras
crc = crc32(0, &ri, sizeof(ri)-8);
if (crc != je32_to_cpu(ri.node_crc)) {
printk(KERN_WARNING "jffs2_garbage_collect_hole: Node at 0x%08x had CRC 0x%08x which doesn't match calculated CRC 0x%08x\n",
- ref_offset(fn->raw),
+ ref_offset(fn->raw),
je32_to_cpu(ri.node_crc), crc);
/* FIXME: We could possibly deal with this by writing new holes for each frag */
- printk(KERN_WARNING "Data in the range 0x%08x to 0x%08x of inode #%u will be lost\n",
+ printk(KERN_WARNING "Data in the range 0x%08x to 0x%08x of inode #%u will be lost\n",
start, end, f->inocache->ino);
goto fill;
}
if (ri.compr != JFFS2_COMPR_ZERO) {
printk(KERN_WARNING "jffs2_garbage_collect_hole: Node 0x%08x wasn't a hole node!\n", ref_offset(fn->raw));
- printk(KERN_WARNING "Data in the range 0x%08x to 0x%08x of inode #%u will be lost\n",
+ printk(KERN_WARNING "Data in the range 0x%08x to 0x%08x of inode #%u will be lost\n",
start, end, f->inocache->ino);
goto fill;
}
@@ -967,7 +982,7 @@ static int jffs2_garbage_collect_hole(struct jffs2_sb_info *c, struct jffs2_eras
ri.csize = cpu_to_je32(0);
ri.compr = JFFS2_COMPR_ZERO;
}
-
+
frag = frag_last(&f->fragtree);
if (frag)
/* Fetch the inode length from the fragtree rather then
@@ -986,7 +1001,8 @@ static int jffs2_garbage_collect_hole(struct jffs2_sb_info *c, struct jffs2_eras
ri.data_crc = cpu_to_je32(0);
ri.node_crc = cpu_to_je32(crc32(0, &ri, sizeof(ri)-8));
- ret = jffs2_reserve_space_gc(c, sizeof(ri), &phys_ofs, &alloclen);
+ ret = jffs2_reserve_space_gc(c, sizeof(ri), &phys_ofs, &alloclen,
+ JFFS2_SUMMARY_INODE_SIZE);
if (ret) {
printk(KERN_WARNING "jffs2_reserve_space_gc of %zd bytes for garbage_collect_hole failed: %d\n",
sizeof(ri), ret);
@@ -1008,10 +1024,10 @@ static int jffs2_garbage_collect_hole(struct jffs2_sb_info *c, struct jffs2_eras
return 0;
}
- /*
+ /*
* We should only get here in the case where the node we are
* replacing had more than one frag, so we kept the same version
- * number as before. (Except in case of error -- see 'goto fill;'
+ * number as before. (Except in case of error -- see 'goto fill;'
* above.)
*/
D1(if(unlikely(fn->frags <= 1)) {
@@ -1023,7 +1039,7 @@ static int jffs2_garbage_collect_hole(struct jffs2_sb_info *c, struct jffs2_eras
/* This is a partially-overlapped hole node. Mark it REF_NORMAL not REF_PRISTINE */
mark_ref_normal(new_fn->raw);
- for (frag = jffs2_lookup_node_frag(&f->fragtree, fn->ofs);
+ for (frag = jffs2_lookup_node_frag(&f->fragtree, fn->ofs);
frag; frag = frag_next(frag)) {
if (frag->ofs > fn->size + fn->ofs)
break;
@@ -1041,10 +1057,10 @@ static int jffs2_garbage_collect_hole(struct jffs2_sb_info *c, struct jffs2_eras
printk(KERN_WARNING "jffs2_garbage_collect_hole: New node has no frags!\n");
BUG();
}
-
+
jffs2_mark_node_obsolete(c, fn->raw);
jffs2_free_full_dnode(fn);
-
+
return 0;
}
@@ -1054,12 +1070,12 @@ static int jffs2_garbage_collect_dnode(struct jffs2_sb_info *c, struct jffs2_era
{
struct jffs2_full_dnode *new_fn;
struct jffs2_raw_inode ri;
- uint32_t alloclen, phys_ofs, offset, orig_end, orig_start;
+ uint32_t alloclen, phys_ofs, offset, orig_end, orig_start;
int ret = 0;
unsigned char *comprbuf = NULL, *writebuf;
unsigned long pg;
unsigned char *pg_ptr;
-
+
memset(&ri, 0, sizeof(ri));
D1(printk(KERN_DEBUG "Writing replacement dnode for ino #%u from offset 0x%x to 0x%x\n",
@@ -1071,8 +1087,8 @@ static int jffs2_garbage_collect_dnode(struct jffs2_sb_info *c, struct jffs2_era
if (c->nr_free_blocks + c->nr_erasing_blocks > c->resv_blocks_gcmerge) {
/* Attempt to do some merging. But only expand to cover logically
adjacent frags if the block containing them is already considered
- to be dirty. Otherwise we end up with GC just going round in
- circles dirtying the nodes it already wrote out, especially
+ to be dirty. Otherwise we end up with GC just going round in
+ circles dirtying the nodes it already wrote out, especially
on NAND where we have small eraseblocks and hence a much higher
chance of nodes having to be split to cross boundaries. */
@@ -1106,7 +1122,7 @@ static int jffs2_garbage_collect_dnode(struct jffs2_sb_info *c, struct jffs2_era
break;
} else {
- /* OK, it's a frag which extends to the beginning of the page. Does it live
+ /* OK, it's a frag which extends to the beginning of the page. Does it live
in a block which is still considered clean? If so, don't obsolete it.
If not, cover it anyway. */
@@ -1156,7 +1172,7 @@ static int jffs2_garbage_collect_dnode(struct jffs2_sb_info *c, struct jffs2_era
break;
} else {
- /* OK, it's a frag which extends to the beginning of the page. Does it live
+ /* OK, it's a frag which extends to the beginning of the page. Does it live
in a block which is still considered clean? If so, don't obsolete it.
If not, cover it anyway. */
@@ -1183,14 +1199,14 @@ static int jffs2_garbage_collect_dnode(struct jffs2_sb_info *c, struct jffs2_era
break;
}
}
- D1(printk(KERN_DEBUG "Expanded dnode to write from (0x%x-0x%x) to (0x%x-0x%x)\n",
+ D1(printk(KERN_DEBUG "Expanded dnode to write from (0x%x-0x%x) to (0x%x-0x%x)\n",
orig_start, orig_end, start, end));
D1(BUG_ON(end > frag_last(&f->fragtree)->ofs + frag_last(&f->fragtree)->size));
BUG_ON(end < orig_end);
BUG_ON(start > orig_start);
}
-
+
/* First, use readpage() to read the appropriate page into the page cache */
/* Q: What happens if we actually try to GC the _same_ page for which commit_write()
* triggered garbage collection in the first place?
@@ -1211,7 +1227,8 @@ static int jffs2_garbage_collect_dnode(struct jffs2_sb_info *c, struct jffs2_era
uint32_t cdatalen;
uint16_t comprtype = JFFS2_COMPR_NONE;
- ret = jffs2_reserve_space_gc(c, sizeof(ri) + JFFS2_MIN_DATA_LEN, &phys_ofs, &alloclen);
+ ret = jffs2_reserve_space_gc(c, sizeof(ri) + JFFS2_MIN_DATA_LEN, &phys_ofs,
+ &alloclen, JFFS2_SUMMARY_INODE_SIZE);
if (ret) {
printk(KERN_WARNING "jffs2_reserve_space_gc of %zd bytes for garbage_collect_dnode failed: %d\n",
@@ -1246,7 +1263,7 @@ static int jffs2_garbage_collect_dnode(struct jffs2_sb_info *c, struct jffs2_era
ri.usercompr = (comprtype >> 8) & 0xff;
ri.node_crc = cpu_to_je32(crc32(0, &ri, sizeof(ri)-8));
ri.data_crc = cpu_to_je32(crc32(0, comprbuf, cdatalen));
-
+
new_fn = jffs2_write_dnode(c, f, &ri, comprbuf, cdatalen, phys_ofs, ALLOC_GC);
jffs2_free_comprbuf(comprbuf, writebuf);
@@ -1268,4 +1285,3 @@ static int jffs2_garbage_collect_dnode(struct jffs2_sb_info *c, struct jffs2_era
jffs2_gc_release_page(c, pg_ptr, &pg);
return ret;
}
-
diff --git a/fs/jffs2/histo.h b/fs/jffs2/histo.h
index 84f184f0836f..22a93a08210c 100644
--- a/fs/jffs2/histo.h
+++ b/fs/jffs2/histo.h
@@ -1,3 +1,3 @@
/* This file provides the bit-probabilities for the input file */
-#define BIT_DIVIDER 629
+#define BIT_DIVIDER 629
static int bits[9] = { 179,167,183,165,159,198,178,119,}; /* ia32 .so files */
diff --git a/fs/jffs2/histo_mips.h b/fs/jffs2/histo_mips.h
index 9a443268d885..fa3dac19a109 100644
--- a/fs/jffs2/histo_mips.h
+++ b/fs/jffs2/histo_mips.h
@@ -1,2 +1,2 @@
-#define BIT_DIVIDER_MIPS 1043
+#define BIT_DIVIDER_MIPS 1043
static int bits_mips[8] = { 277,249,290,267,229,341,212,241}; /* mips32 */
diff --git a/fs/jffs2/ioctl.c b/fs/jffs2/ioctl.c
index 238c7992064c..69099835de1c 100644
--- a/fs/jffs2/ioctl.c
+++ b/fs/jffs2/ioctl.c
@@ -7,17 +7,17 @@
*
* For licensing information, see the file 'LICENCE' in this directory.
*
- * $Id: ioctl.c,v 1.9 2004/11/16 20:36:11 dwmw2 Exp $
+ * $Id: ioctl.c,v 1.10 2005/11/07 11:14:40 gleixner Exp $
*
*/
#include <linux/fs.h>
-int jffs2_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
+int jffs2_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
unsigned long arg)
{
/* Later, this will provide for lsattr.jffs2 and chattr.jffs2, which
will include compression support etc. */
return -ENOTTY;
}
-
+
diff --git a/fs/jffs2/malloc.c b/fs/jffs2/malloc.c
index 5abb431c2a00..036cbd11c004 100644
--- a/fs/jffs2/malloc.c
+++ b/fs/jffs2/malloc.c
@@ -7,7 +7,7 @@
*
* For licensing information, see the file 'LICENCE' in this directory.
*
- * $Id: malloc.c,v 1.28 2004/11/16 20:36:11 dwmw2 Exp $
+ * $Id: malloc.c,v 1.31 2005/11/07 11:14:40 gleixner Exp $
*
*/
@@ -17,15 +17,6 @@
#include <linux/jffs2.h>
#include "nodelist.h"
-#if 0
-#define JFFS2_SLAB_POISON SLAB_POISON
-#else
-#define JFFS2_SLAB_POISON 0
-#endif
-
-// replace this by #define D3 (x) x for cache debugging
-#define D3(x)
-
/* These are initialised to NULL in the kernel startup code.
If you're porting to other operating systems, beware */
static kmem_cache_t *full_dnode_slab;
@@ -38,45 +29,45 @@ static kmem_cache_t *inode_cache_slab;
int __init jffs2_create_slab_caches(void)
{
- full_dnode_slab = kmem_cache_create("jffs2_full_dnode",
+ full_dnode_slab = kmem_cache_create("jffs2_full_dnode",
sizeof(struct jffs2_full_dnode),
- 0, JFFS2_SLAB_POISON, NULL, NULL);
+ 0, 0, NULL, NULL);
if (!full_dnode_slab)
goto err;
raw_dirent_slab = kmem_cache_create("jffs2_raw_dirent",
sizeof(struct jffs2_raw_dirent),
- 0, JFFS2_SLAB_POISON, NULL, NULL);
+ 0, 0, NULL, NULL);
if (!raw_dirent_slab)
goto err;
raw_inode_slab = kmem_cache_create("jffs2_raw_inode",
sizeof(struct jffs2_raw_inode),
- 0, JFFS2_SLAB_POISON, NULL, NULL);
+ 0, 0, NULL, NULL);
if (!raw_inode_slab)
goto err;
tmp_dnode_info_slab = kmem_cache_create("jffs2_tmp_dnode",
sizeof(struct jffs2_tmp_dnode_info),
- 0, JFFS2_SLAB_POISON, NULL, NULL);
+ 0, 0, NULL, NULL);
if (!tmp_dnode_info_slab)
goto err;
raw_node_ref_slab = kmem_cache_create("jffs2_raw_node_ref",
sizeof(struct jffs2_raw_node_ref),
- 0, JFFS2_SLAB_POISON, NULL, NULL);
+ 0, 0, NULL, NULL);
if (!raw_node_ref_slab)
goto err;
node_frag_slab = kmem_cache_create("jffs2_node_frag",
sizeof(struct jffs2_node_frag),
- 0, JFFS2_SLAB_POISON, NULL, NULL);
+ 0, 0, NULL, NULL);
if (!node_frag_slab)
goto err;
inode_cache_slab = kmem_cache_create("jffs2_inode_cache",
sizeof(struct jffs2_inode_cache),
- 0, JFFS2_SLAB_POISON, NULL, NULL);
+ 0, 0, NULL, NULL);
if (inode_cache_slab)
return 0;
err:
@@ -104,102 +95,113 @@ void jffs2_destroy_slab_caches(void)
struct jffs2_full_dirent *jffs2_alloc_full_dirent(int namesize)
{
- return kmalloc(sizeof(struct jffs2_full_dirent) + namesize, GFP_KERNEL);
+ struct jffs2_full_dirent *ret;
+ ret = kmalloc(sizeof(struct jffs2_full_dirent) + namesize, GFP_KERNEL);
+ dbg_memalloc("%p\n", ret);
+ return ret;
}
void jffs2_free_full_dirent(struct jffs2_full_dirent *x)
{
+ dbg_memalloc("%p\n", x);
kfree(x);
}
struct jffs2_full_dnode *jffs2_alloc_full_dnode(void)
{
- struct jffs2_full_dnode *ret = kmem_cache_alloc(full_dnode_slab, GFP_KERNEL);
- D3 (printk (KERN_DEBUG "alloc_full_dnode at %p\n", ret));
+ struct jffs2_full_dnode *ret;
+ ret = kmem_cache_alloc(full_dnode_slab, GFP_KERNEL);
+ dbg_memalloc("%p\n", ret);
return ret;
}
void jffs2_free_full_dnode(struct jffs2_full_dnode *x)
{
- D3 (printk (KERN_DEBUG "free full_dnode at %p\n", x));
+ dbg_memalloc("%p\n", x);
kmem_cache_free(full_dnode_slab, x);
}
struct jffs2_raw_dirent *jffs2_alloc_raw_dirent(void)
{
- struct jffs2_raw_dirent *ret = kmem_cache_alloc(raw_dirent_slab, GFP_KERNEL);
- D3 (printk (KERN_DEBUG "alloc_raw_dirent\n", ret));
+ struct jffs2_raw_dirent *ret;
+ ret = kmem_cache_alloc(raw_dirent_slab, GFP_KERNEL);
+ dbg_memalloc("%p\n", ret);
return ret;
}
void jffs2_free_raw_dirent(struct jffs2_raw_dirent *x)
{
- D3 (printk (KERN_DEBUG "free_raw_dirent at %p\n", x));
+ dbg_memalloc("%p\n", x);
kmem_cache_free(raw_dirent_slab, x);
}
struct jffs2_raw_inode *jffs2_alloc_raw_inode(void)
{
- struct jffs2_raw_inode *ret = kmem_cache_alloc(raw_inode_slab, GFP_KERNEL);
- D3 (printk (KERN_DEBUG "alloc_raw_inode at %p\n", ret));
+ struct jffs2_raw_inode *ret;
+ ret = kmem_cache_alloc(raw_inode_slab, GFP_KERNEL);
+ dbg_memalloc("%p\n", ret);
return ret;
}
void jffs2_free_raw_inode(struct jffs2_raw_inode *x)
{
- D3 (printk (KERN_DEBUG "free_raw_inode at %p\n", x));
+ dbg_memalloc("%p\n", x);
kmem_cache_free(raw_inode_slab, x);
}
struct jffs2_tmp_dnode_info *jffs2_alloc_tmp_dnode_info(void)
{
- struct jffs2_tmp_dnode_info *ret = kmem_cache_alloc(tmp_dnode_info_slab, GFP_KERNEL);
- D3 (printk (KERN_DEBUG "alloc_tmp_dnode_info at %p\n", ret));
+ struct jffs2_tmp_dnode_info *ret;
+ ret = kmem_cache_alloc(tmp_dnode_info_slab, GFP_KERNEL);
+ dbg_memalloc("%p\n",
+ ret);
return ret;
}
void jffs2_free_tmp_dnode_info(struct jffs2_tmp_dnode_info *x)
{
- D3 (printk (KERN_DEBUG "free_tmp_dnode_info at %p\n", x));
+ dbg_memalloc("%p\n", x);
kmem_cache_free(tmp_dnode_info_slab, x);
}
struct jffs2_raw_node_ref *jffs2_alloc_raw_node_ref(void)
{
- struct jffs2_raw_node_ref *ret = kmem_cache_alloc(raw_node_ref_slab, GFP_KERNEL);
- D3 (printk (KERN_DEBUG "alloc_raw_node_ref at %p\n", ret));
+ struct jffs2_raw_node_ref *ret;
+ ret = kmem_cache_alloc(raw_node_ref_slab, GFP_KERNEL);
+ dbg_memalloc("%p\n", ret);
return ret;
}
void jffs2_free_raw_node_ref(struct jffs2_raw_node_ref *x)
{
- D3 (printk (KERN_DEBUG "free_raw_node_ref at %p\n", x));
+ dbg_memalloc("%p\n", x);
kmem_cache_free(raw_node_ref_slab, x);
}
struct jffs2_node_frag *jffs2_alloc_node_frag(void)
{
- struct jffs2_node_frag *ret = kmem_cache_alloc(node_frag_slab, GFP_KERNEL);
- D3 (printk (KERN_DEBUG "alloc_node_frag at %p\n", ret));
+ struct jffs2_node_frag *ret;
+ ret = kmem_cache_alloc(node_frag_slab, GFP_KERNEL);
+ dbg_memalloc("%p\n", ret);
return ret;
}
void jffs2_free_node_frag(struct jffs2_node_frag *x)
{
- D3 (printk (KERN_DEBUG "free_node_frag at %p\n", x));
+ dbg_memalloc("%p\n", x);
kmem_cache_free(node_frag_slab, x);
}
struct jffs2_inode_cache *jffs2_alloc_inode_cache(void)
{
- struct jffs2_inode_cache *ret = kmem_cache_alloc(inode_cache_slab, GFP_KERNEL);
- D3 (printk(KERN_DEBUG "Allocated inocache at %p\n", ret));
+ struct jffs2_inode_cache *ret;
+ ret = kmem_cache_alloc(inode_cache_slab, GFP_KERNEL);
+ dbg_memalloc("%p\n", ret);
return ret;
}
void jffs2_free_inode_cache(struct jffs2_inode_cache *x)
{
- D3 (printk(KERN_DEBUG "Freeing inocache at %p\n", x));
+ dbg_memalloc("%p\n", x);
kmem_cache_free(inode_cache_slab, x);
}
-
diff --git a/fs/jffs2/nodelist.c b/fs/jffs2/nodelist.c
index 4991c348f6ec..c79eebb8ab32 100644
--- a/fs/jffs2/nodelist.c
+++ b/fs/jffs2/nodelist.c
@@ -7,7 +7,7 @@
*
* For licensing information, see the file 'LICENCE' in this directory.
*
- * $Id: nodelist.c,v 1.98 2005/07/10 15:15:32 dedekind Exp $
+ * $Id: nodelist.c,v 1.115 2005/11/07 11:14:40 gleixner Exp $
*
*/
@@ -24,469 +24,832 @@
void jffs2_add_fd_to_list(struct jffs2_sb_info *c, struct jffs2_full_dirent *new, struct jffs2_full_dirent **list)
{
struct jffs2_full_dirent **prev = list;
- D1(printk(KERN_DEBUG "jffs2_add_fd_to_list( %p, %p (->%p))\n", new, list, *list));
+
+ dbg_dentlist("add dirent \"%s\", ino #%u\n", new->name, new->ino);
while ((*prev) && (*prev)->nhash <= new->nhash) {
if ((*prev)->nhash == new->nhash && !strcmp((*prev)->name, new->name)) {
/* Duplicate. Free one */
if (new->version < (*prev)->version) {
- D1(printk(KERN_DEBUG "Eep! Marking new dirent node obsolete\n"));
- D1(printk(KERN_DEBUG "New dirent is \"%s\"->ino #%u. Old is \"%s\"->ino #%u\n", new->name, new->ino, (*prev)->name, (*prev)->ino));
+ dbg_dentlist("Eep! Marking new dirent node is obsolete, old is \"%s\", ino #%u\n",
+ (*prev)->name, (*prev)->ino);
jffs2_mark_node_obsolete(c, new->raw);
jffs2_free_full_dirent(new);
} else {
- D1(printk(KERN_DEBUG "Marking old dirent node (ino #%u) obsolete\n", (*prev)->ino));
+ dbg_dentlist("marking old dirent \"%s\", ino #%u bsolete\n",
+ (*prev)->name, (*prev)->ino);
new->next = (*prev)->next;
jffs2_mark_node_obsolete(c, ((*prev)->raw));
jffs2_free_full_dirent(*prev);
*prev = new;
}
- goto out;
+ return;
}
prev = &((*prev)->next);
}
new->next = *prev;
*prev = new;
+}
+
+void jffs2_truncate_fragtree(struct jffs2_sb_info *c, struct rb_root *list, uint32_t size)
+{
+ struct jffs2_node_frag *frag = jffs2_lookup_node_frag(list, size);
+
+ dbg_fragtree("truncating fragtree to 0x%08x bytes\n", size);
+
+ /* We know frag->ofs <= size. That's what lookup does for us */
+ if (frag && frag->ofs != size) {
+ if (frag->ofs+frag->size > size) {
+ frag->size = size - frag->ofs;
+ }
+ frag = frag_next(frag);
+ }
+ while (frag && frag->ofs >= size) {
+ struct jffs2_node_frag *next = frag_next(frag);
+
+ frag_erase(frag, list);
+ jffs2_obsolete_node_frag(c, frag);
+ frag = next;
+ }
- out:
- D2(while(*list) {
- printk(KERN_DEBUG "Dirent \"%s\" (hash 0x%08x, ino #%u\n", (*list)->name, (*list)->nhash, (*list)->ino);
- list = &(*list)->next;
- });
+ if (size == 0)
+ return;
+
+ /*
+ * If the last fragment starts at the RAM page boundary, it is
+ * REF_PRISTINE irrespective of its size.
+ */
+ frag = frag_last(list);
+ if (frag->node && (frag->ofs & (PAGE_CACHE_SIZE - 1)) == 0) {
+ dbg_fragtree2("marking the last fragment 0x%08x-0x%08x REF_PRISTINE.\n",
+ frag->ofs, frag->ofs + frag->size);
+ frag->node->raw->flash_offset = ref_offset(frag->node->raw) | REF_PRISTINE;
+ }
}
-/*
- * Put a new tmp_dnode_info into the temporaty RB-tree, keeping the list in
- * order of increasing version.
- */
-static void jffs2_add_tn_to_tree(struct jffs2_tmp_dnode_info *tn, struct rb_root *list)
+void jffs2_obsolete_node_frag(struct jffs2_sb_info *c, struct jffs2_node_frag *this)
{
- struct rb_node **p = &list->rb_node;
- struct rb_node * parent = NULL;
- struct jffs2_tmp_dnode_info *this;
-
- while (*p) {
- parent = *p;
- this = rb_entry(parent, struct jffs2_tmp_dnode_info, rb);
-
- /* There may actually be a collision here, but it doesn't
- actually matter. As long as the two nodes with the same
- version are together, it's all fine. */
- if (tn->version < this->version)
- p = &(*p)->rb_left;
- else
- p = &(*p)->rb_right;
- }
+ if (this->node) {
+ this->node->frags--;
+ if (!this->node->frags) {
+ /* The node has no valid frags left. It's totally obsoleted */
+ dbg_fragtree2("marking old node @0x%08x (0x%04x-0x%04x) obsolete\n",
+ ref_offset(this->node->raw), this->node->ofs, this->node->ofs+this->node->size);
+ jffs2_mark_node_obsolete(c, this->node->raw);
+ jffs2_free_full_dnode(this->node);
+ } else {
+ dbg_fragtree2("marking old node @0x%08x (0x%04x-0x%04x) REF_NORMAL. frags is %d\n",
+ ref_offset(this->node->raw), this->node->ofs, this->node->ofs+this->node->size, this->node->frags);
+ mark_ref_normal(this->node->raw);
+ }
- rb_link_node(&tn->rb, parent, p);
- rb_insert_color(&tn->rb, list);
+ }
+ jffs2_free_node_frag(this);
}
-static void jffs2_free_tmp_dnode_info_list(struct rb_root *list)
+static void jffs2_fragtree_insert(struct jffs2_node_frag *newfrag, struct jffs2_node_frag *base)
{
- struct rb_node *this;
- struct jffs2_tmp_dnode_info *tn;
+ struct rb_node *parent = &base->rb;
+ struct rb_node **link = &parent;
- this = list->rb_node;
+ dbg_fragtree2("insert frag (0x%04x-0x%04x)\n", newfrag->ofs, newfrag->ofs + newfrag->size);
- /* Now at bottom of tree */
- while (this) {
- if (this->rb_left)
- this = this->rb_left;
- else if (this->rb_right)
- this = this->rb_right;
+ while (*link) {
+ parent = *link;
+ base = rb_entry(parent, struct jffs2_node_frag, rb);
+
+ if (newfrag->ofs > base->ofs)
+ link = &base->rb.rb_right;
+ else if (newfrag->ofs < base->ofs)
+ link = &base->rb.rb_left;
else {
- tn = rb_entry(this, struct jffs2_tmp_dnode_info, rb);
- jffs2_free_full_dnode(tn->fn);
- jffs2_free_tmp_dnode_info(tn);
-
- this = this->rb_parent;
- if (!this)
- break;
-
- if (this->rb_left == &tn->rb)
- this->rb_left = NULL;
- else if (this->rb_right == &tn->rb)
- this->rb_right = NULL;
- else BUG();
+ JFFS2_ERROR("duplicate frag at %08x (%p,%p)\n", newfrag->ofs, newfrag, base);
+ BUG();
}
}
- list->rb_node = NULL;
+
+ rb_link_node(&newfrag->rb, &base->rb, link);
}
-static void jffs2_free_full_dirent_list(struct jffs2_full_dirent *fd)
+/*
+ * Allocate and initializes a new fragment.
+ */
+static inline struct jffs2_node_frag * new_fragment(struct jffs2_full_dnode *fn, uint32_t ofs, uint32_t size)
{
- struct jffs2_full_dirent *next;
-
- while (fd) {
- next = fd->next;
- jffs2_free_full_dirent(fd);
- fd = next;
+ struct jffs2_node_frag *newfrag;
+
+ newfrag = jffs2_alloc_node_frag();
+ if (likely(newfrag)) {
+ newfrag->ofs = ofs;
+ newfrag->size = size;
+ newfrag->node = fn;
+ } else {
+ JFFS2_ERROR("cannot allocate a jffs2_node_frag object\n");
}
+
+ return newfrag;
}
-/* Returns first valid node after 'ref'. May return 'ref' */
-static struct jffs2_raw_node_ref *jffs2_first_valid_node(struct jffs2_raw_node_ref *ref)
+/*
+ * Called when there is no overlapping fragment exist. Inserts a hole before the new
+ * fragment and inserts the new fragment to the fragtree.
+ */
+static int no_overlapping_node(struct jffs2_sb_info *c, struct rb_root *root,
+ struct jffs2_node_frag *newfrag,
+ struct jffs2_node_frag *this, uint32_t lastend)
{
- while (ref && ref->next_in_ino) {
- if (!ref_obsolete(ref))
- return ref;
- D1(printk(KERN_DEBUG "node at 0x%08x is obsoleted. Ignoring.\n", ref_offset(ref)));
- ref = ref->next_in_ino;
+ if (lastend < newfrag->node->ofs) {
+ /* put a hole in before the new fragment */
+ struct jffs2_node_frag *holefrag;
+
+ holefrag= new_fragment(NULL, lastend, newfrag->node->ofs - lastend);
+ if (unlikely(!holefrag)) {
+ jffs2_free_node_frag(newfrag);
+ return -ENOMEM;
+ }
+
+ if (this) {
+ /* By definition, the 'this' node has no right-hand child,
+ because there are no frags with offset greater than it.
+ So that's where we want to put the hole */
+ dbg_fragtree2("add hole frag %#04x-%#04x on the right of the new frag.\n",
+ holefrag->ofs, holefrag->ofs + holefrag->size);
+ rb_link_node(&holefrag->rb, &this->rb, &this->rb.rb_right);
+ } else {
+ dbg_fragtree2("Add hole frag %#04x-%#04x to the root of the tree.\n",
+ holefrag->ofs, holefrag->ofs + holefrag->size);
+ rb_link_node(&holefrag->rb, NULL, &root->rb_node);
+ }
+ rb_insert_color(&holefrag->rb, root);
+ this = holefrag;
+ }
+
+ if (this) {
+ /* By definition, the 'this' node has no right-hand child,
+ because there are no frags with offset greater than it.
+ So that's where we want to put new fragment */
+ dbg_fragtree2("add the new node at the right\n");
+ rb_link_node(&newfrag->rb, &this->rb, &this->rb.rb_right);
+ } else {
+ dbg_fragtree2("insert the new node at the root of the tree\n");
+ rb_link_node(&newfrag->rb, NULL, &root->rb_node);
}
- return NULL;
+ rb_insert_color(&newfrag->rb, root);
+
+ return 0;
}
-/* Get tmp_dnode_info and full_dirent for all non-obsolete nodes associated
- with this ino, returning the former in order of version */
+/* Doesn't set inode->i_size */
+static int jffs2_add_frag_to_fragtree(struct jffs2_sb_info *c, struct rb_root *root, struct jffs2_node_frag *newfrag)
+{
+ struct jffs2_node_frag *this;
+ uint32_t lastend;
+
+ /* Skip all the nodes which are completed before this one starts */
+ this = jffs2_lookup_node_frag(root, newfrag->node->ofs);
+
+ if (this) {
+ dbg_fragtree2("lookup gave frag 0x%04x-0x%04x; phys 0x%08x (*%p)\n",
+ this->ofs, this->ofs+this->size, this->node?(ref_offset(this->node->raw)):0xffffffff, this);
+ lastend = this->ofs + this->size;
+ } else {
+ dbg_fragtree2("lookup gave no frag\n");
+ lastend = 0;
+ }
+
+ /* See if we ran off the end of the fragtree */
+ if (lastend <= newfrag->ofs) {
+ /* We did */
+
+ /* Check if 'this' node was on the same page as the new node.
+ If so, both 'this' and the new node get marked REF_NORMAL so
+ the GC can take a look.
+ */
+ if (lastend && (lastend-1) >> PAGE_CACHE_SHIFT == newfrag->ofs >> PAGE_CACHE_SHIFT) {
+ if (this->node)
+ mark_ref_normal(this->node->raw);
+ mark_ref_normal(newfrag->node->raw);
+ }
+
+ return no_overlapping_node(c, root, newfrag, this, lastend);
+ }
-int jffs2_get_inode_nodes(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
- struct rb_root *tnp, struct jffs2_full_dirent **fdp,
- uint32_t *highest_version, uint32_t *latest_mctime,
- uint32_t *mctime_ver)
+ if (this->node)
+ dbg_fragtree2("dealing with frag %u-%u, phys %#08x(%d).\n",
+ this->ofs, this->ofs + this->size,
+ ref_offset(this->node->raw), ref_flags(this->node->raw));
+ else
+ dbg_fragtree2("dealing with hole frag %u-%u.\n",
+ this->ofs, this->ofs + this->size);
+
+ /* OK. 'this' is pointing at the first frag that newfrag->ofs at least partially obsoletes,
+ * - i.e. newfrag->ofs < this->ofs+this->size && newfrag->ofs >= this->ofs
+ */
+ if (newfrag->ofs > this->ofs) {
+ /* This node isn't completely obsoleted. The start of it remains valid */
+
+ /* Mark the new node and the partially covered node REF_NORMAL -- let
+ the GC take a look at them */
+ mark_ref_normal(newfrag->node->raw);
+ if (this->node)
+ mark_ref_normal(this->node->raw);
+
+ if (this->ofs + this->size > newfrag->ofs + newfrag->size) {
+ /* The new node splits 'this' frag into two */
+ struct jffs2_node_frag *newfrag2;
+
+ if (this->node)
+ dbg_fragtree2("split old frag 0x%04x-0x%04x, phys 0x%08x\n",
+ this->ofs, this->ofs+this->size, ref_offset(this->node->raw));
+ else
+ dbg_fragtree2("split old hole frag 0x%04x-0x%04x\n",
+ this->ofs, this->ofs+this->size);
+
+ /* New second frag pointing to this's node */
+ newfrag2 = new_fragment(this->node, newfrag->ofs + newfrag->size,
+ this->ofs + this->size - newfrag->ofs - newfrag->size);
+ if (unlikely(!newfrag2))
+ return -ENOMEM;
+ if (this->node)
+ this->node->frags++;
+
+ /* Adjust size of original 'this' */
+ this->size = newfrag->ofs - this->ofs;
+
+ /* Now, we know there's no node with offset
+ greater than this->ofs but smaller than
+ newfrag2->ofs or newfrag->ofs, for obvious
+ reasons. So we can do a tree insert from
+ 'this' to insert newfrag, and a tree insert
+ from newfrag to insert newfrag2. */
+ jffs2_fragtree_insert(newfrag, this);
+ rb_insert_color(&newfrag->rb, root);
+
+ jffs2_fragtree_insert(newfrag2, newfrag);
+ rb_insert_color(&newfrag2->rb, root);
+
+ return 0;
+ }
+ /* New node just reduces 'this' frag in size, doesn't split it */
+ this->size = newfrag->ofs - this->ofs;
+
+ /* Again, we know it lives down here in the tree */
+ jffs2_fragtree_insert(newfrag, this);
+ rb_insert_color(&newfrag->rb, root);
+ } else {
+ /* New frag starts at the same point as 'this' used to. Replace
+ it in the tree without doing a delete and insertion */
+ dbg_fragtree2("inserting newfrag (*%p),%d-%d in before 'this' (*%p),%d-%d\n",
+ newfrag, newfrag->ofs, newfrag->ofs+newfrag->size, this, this->ofs, this->ofs+this->size);
+
+ rb_replace_node(&this->rb, &newfrag->rb, root);
+
+ if (newfrag->ofs + newfrag->size >= this->ofs+this->size) {
+ dbg_fragtree2("obsoleting node frag %p (%x-%x)\n", this, this->ofs, this->ofs+this->size);
+ jffs2_obsolete_node_frag(c, this);
+ } else {
+ this->ofs += newfrag->size;
+ this->size -= newfrag->size;
+
+ jffs2_fragtree_insert(this, newfrag);
+ rb_insert_color(&this->rb, root);
+ return 0;
+ }
+ }
+ /* OK, now we have newfrag added in the correct place in the tree, but
+ frag_next(newfrag) may be a fragment which is overlapped by it
+ */
+ while ((this = frag_next(newfrag)) && newfrag->ofs + newfrag->size >= this->ofs + this->size) {
+ /* 'this' frag is obsoleted completely. */
+ dbg_fragtree2("obsoleting node frag %p (%x-%x) and removing from tree\n",
+ this, this->ofs, this->ofs+this->size);
+ rb_erase(&this->rb, root);
+ jffs2_obsolete_node_frag(c, this);
+ }
+ /* Now we're pointing at the first frag which isn't totally obsoleted by
+ the new frag */
+
+ if (!this || newfrag->ofs + newfrag->size == this->ofs)
+ return 0;
+
+ /* Still some overlap but we don't need to move it in the tree */
+ this->size = (this->ofs + this->size) - (newfrag->ofs + newfrag->size);
+ this->ofs = newfrag->ofs + newfrag->size;
+
+ /* And mark them REF_NORMAL so the GC takes a look at them */
+ if (this->node)
+ mark_ref_normal(this->node->raw);
+ mark_ref_normal(newfrag->node->raw);
+
+ return 0;
+}
+
+/*
+ * Given an inode, probably with existing tree of fragments, add the new node
+ * to the fragment tree.
+ */
+int jffs2_add_full_dnode_to_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, struct jffs2_full_dnode *fn)
{
- struct jffs2_raw_node_ref *ref, *valid_ref;
- struct jffs2_tmp_dnode_info *tn;
- struct rb_root ret_tn = RB_ROOT;
- struct jffs2_full_dirent *fd, *ret_fd = NULL;
- union jffs2_node_union node;
- size_t retlen;
- int err;
-
- *mctime_ver = 0;
-
- D1(printk(KERN_DEBUG "jffs2_get_inode_nodes(): ino #%u\n", f->inocache->ino));
+ int ret;
+ struct jffs2_node_frag *newfrag;
- spin_lock(&c->erase_completion_lock);
+ if (unlikely(!fn->size))
+ return 0;
- valid_ref = jffs2_first_valid_node(f->inocache->nodes);
+ newfrag = new_fragment(fn, fn->ofs, fn->size);
+ if (unlikely(!newfrag))
+ return -ENOMEM;
+ newfrag->node->frags = 1;
- if (!valid_ref && (f->inocache->ino != 1))
- printk(KERN_WARNING "Eep. No valid nodes for ino #%u\n", f->inocache->ino);
+ dbg_fragtree("adding node %#04x-%#04x @0x%08x on flash, newfrag *%p\n",
+ fn->ofs, fn->ofs+fn->size, ref_offset(fn->raw), newfrag);
- while (valid_ref) {
- /* We can hold a pointer to a non-obsolete node without the spinlock,
- but _obsolete_ nodes may disappear at any time, if the block
- they're in gets erased. So if we mark 'ref' obsolete while we're
- not holding the lock, it can go away immediately. For that reason,
- we find the next valid node first, before processing 'ref'.
- */
- ref = valid_ref;
- valid_ref = jffs2_first_valid_node(ref->next_in_ino);
- spin_unlock(&c->erase_completion_lock);
+ ret = jffs2_add_frag_to_fragtree(c, &f->fragtree, newfrag);
+ if (unlikely(ret))
+ return ret;
- cond_resched();
+ /* If we now share a page with other nodes, mark either previous
+ or next node REF_NORMAL, as appropriate. */
+ if (newfrag->ofs & (PAGE_CACHE_SIZE-1)) {
+ struct jffs2_node_frag *prev = frag_prev(newfrag);
+
+ mark_ref_normal(fn->raw);
+ /* If we don't start at zero there's _always_ a previous */
+ if (prev->node)
+ mark_ref_normal(prev->node->raw);
+ }
+
+ if ((newfrag->ofs+newfrag->size) & (PAGE_CACHE_SIZE-1)) {
+ struct jffs2_node_frag *next = frag_next(newfrag);
+
+ if (next) {
+ mark_ref_normal(fn->raw);
+ if (next->node)
+ mark_ref_normal(next->node->raw);
+ }
+ }
+ jffs2_dbg_fragtree_paranoia_check_nolock(f);
+
+ return 0;
+}
+
+/*
+ * Check the data CRC of the node.
+ *
+ * Returns: 0 if the data CRC is correct;
+ * 1 - if incorrect;
+ * error code if an error occured.
+ */
+static int check_node_data(struct jffs2_sb_info *c, struct jffs2_tmp_dnode_info *tn)
+{
+ struct jffs2_raw_node_ref *ref = tn->fn->raw;
+ int err = 0, pointed = 0;
+ struct jffs2_eraseblock *jeb;
+ unsigned char *buffer;
+ uint32_t crc, ofs, retlen, len;
+
+ BUG_ON(tn->csize == 0);
+
+ if (!jffs2_is_writebuffered(c))
+ goto adj_acc;
+
+ /* Calculate how many bytes were already checked */
+ ofs = ref_offset(ref) + sizeof(struct jffs2_raw_inode);
+ len = ofs % c->wbuf_pagesize;
+ if (likely(len))
+ len = c->wbuf_pagesize - len;
+
+ if (len >= tn->csize) {
+ dbg_readinode("no need to check node at %#08x, data length %u, data starts at %#08x - it has already been checked.\n",
+ ref_offset(ref), tn->csize, ofs);
+ goto adj_acc;
+ }
+
+ ofs += len;
+ len = tn->csize - len;
+
+ dbg_readinode("check node at %#08x, data length %u, partial CRC %#08x, correct CRC %#08x, data starts at %#08x, start checking from %#08x - %u bytes.\n",
+ ref_offset(ref), tn->csize, tn->partial_crc, tn->data_crc, ofs - len, ofs, len);
+
+#ifndef __ECOS
+ /* TODO: instead, incapsulate point() stuff to jffs2_flash_read(),
+ * adding and jffs2_flash_read_end() interface. */
+ if (c->mtd->point) {
+ err = c->mtd->point(c->mtd, ofs, len, &retlen, &buffer);
+ if (!err && retlen < tn->csize) {
+ JFFS2_WARNING("MTD point returned len too short: %u instead of %u.\n", retlen, tn->csize);
+ c->mtd->unpoint(c->mtd, buffer, ofs, len);
+ } else if (err)
+ JFFS2_WARNING("MTD point failed: error code %d.\n", err);
+ else
+ pointed = 1; /* succefully pointed to device */
+ }
+#endif
+
+ if (!pointed) {
+ buffer = kmalloc(len, GFP_KERNEL);
+ if (unlikely(!buffer))
+ return -ENOMEM;
- /* FIXME: point() */
- err = jffs2_flash_read(c, (ref_offset(ref)),
- min_t(uint32_t, ref_totlen(c, NULL, ref), sizeof(node)),
- &retlen, (void *)&node);
+ /* TODO: this is very frequent pattern, make it a separate
+ * routine */
+ err = jffs2_flash_read(c, ofs, len, &retlen, buffer);
if (err) {
- printk(KERN_WARNING "error %d reading node at 0x%08x in get_inode_nodes()\n", err, ref_offset(ref));
+ JFFS2_ERROR("can not read %d bytes from 0x%08x, error code: %d.\n", len, ofs, err);
goto free_out;
}
-
- /* Check we've managed to read at least the common node header */
- if (retlen < min_t(uint32_t, ref_totlen(c, NULL, ref), sizeof(node.u))) {
- printk(KERN_WARNING "short read in get_inode_nodes()\n");
+ if (retlen != len) {
+ JFFS2_ERROR("short read at %#08x: %d instead of %d.\n", ofs, retlen, len);
err = -EIO;
goto free_out;
}
-
- switch (je16_to_cpu(node.u.nodetype)) {
- case JFFS2_NODETYPE_DIRENT:
- D1(printk(KERN_DEBUG "Node at %08x (%d) is a dirent node\n", ref_offset(ref), ref_flags(ref)));
- if (ref_flags(ref) == REF_UNCHECKED) {
- printk(KERN_WARNING "BUG: Dirent node at 0x%08x never got checked? How?\n", ref_offset(ref));
- BUG();
- }
- if (retlen < sizeof(node.d)) {
- printk(KERN_WARNING "short read in get_inode_nodes()\n");
- err = -EIO;
- goto free_out;
- }
- /* sanity check */
- if (PAD((node.d.nsize + sizeof (node.d))) != PAD(je32_to_cpu (node.d.totlen))) {
- printk(KERN_NOTICE "jffs2_get_inode_nodes(): Illegal nsize in node at 0x%08x: nsize 0x%02x, totlen %04x\n",
- ref_offset(ref), node.d.nsize, je32_to_cpu(node.d.totlen));
- jffs2_mark_node_obsolete(c, ref);
- spin_lock(&c->erase_completion_lock);
- continue;
- }
- if (je32_to_cpu(node.d.version) > *highest_version)
- *highest_version = je32_to_cpu(node.d.version);
- if (ref_obsolete(ref)) {
- /* Obsoleted. This cannot happen, surely? dwmw2 20020308 */
- printk(KERN_ERR "Dirent node at 0x%08x became obsolete while we weren't looking\n",
- ref_offset(ref));
- BUG();
- }
-
- fd = jffs2_alloc_full_dirent(node.d.nsize+1);
- if (!fd) {
- err = -ENOMEM;
- goto free_out;
- }
- fd->raw = ref;
- fd->version = je32_to_cpu(node.d.version);
- fd->ino = je32_to_cpu(node.d.ino);
- fd->type = node.d.type;
-
- /* Pick out the mctime of the latest dirent */
- if(fd->version > *mctime_ver) {
- *mctime_ver = fd->version;
- *latest_mctime = je32_to_cpu(node.d.mctime);
- }
+ }
- /* memcpy as much of the name as possible from the raw
- dirent we've already read from the flash
- */
- if (retlen > sizeof(struct jffs2_raw_dirent))
- memcpy(&fd->name[0], &node.d.name[0], min_t(uint32_t, node.d.nsize, (retlen-sizeof(struct jffs2_raw_dirent))));
-
- /* Do we need to copy any more of the name directly
- from the flash?
- */
- if (node.d.nsize + sizeof(struct jffs2_raw_dirent) > retlen) {
- /* FIXME: point() */
- int already = retlen - sizeof(struct jffs2_raw_dirent);
-
- err = jffs2_flash_read(c, (ref_offset(ref)) + retlen,
- node.d.nsize - already, &retlen, &fd->name[already]);
- if (!err && retlen != node.d.nsize - already)
- err = -EIO;
-
- if (err) {
- printk(KERN_WARNING "Read remainder of name in jffs2_get_inode_nodes(): error %d\n", err);
- jffs2_free_full_dirent(fd);
- goto free_out;
- }
- }
- fd->nhash = full_name_hash(fd->name, node.d.nsize);
- fd->next = NULL;
- fd->name[node.d.nsize] = '\0';
- /* Wheee. We now have a complete jffs2_full_dirent structure, with
- the name in it and everything. Link it into the list
- */
- D1(printk(KERN_DEBUG "Adding fd \"%s\", ino #%u\n", fd->name, fd->ino));
- jffs2_add_fd_to_list(c, fd, &ret_fd);
- break;
-
- case JFFS2_NODETYPE_INODE:
- D1(printk(KERN_DEBUG "Node at %08x (%d) is a data node\n", ref_offset(ref), ref_flags(ref)));
- if (retlen < sizeof(node.i)) {
- printk(KERN_WARNING "read too short for dnode\n");
- err = -EIO;
- goto free_out;
- }
- if (je32_to_cpu(node.i.version) > *highest_version)
- *highest_version = je32_to_cpu(node.i.version);
- D1(printk(KERN_DEBUG "version %d, highest_version now %d\n", je32_to_cpu(node.i.version), *highest_version));
-
- if (ref_obsolete(ref)) {
- /* Obsoleted. This cannot happen, surely? dwmw2 20020308 */
- printk(KERN_ERR "Inode node at 0x%08x became obsolete while we weren't looking\n",
- ref_offset(ref));
- BUG();
- }
+ /* Continue calculating CRC */
+ crc = crc32(tn->partial_crc, buffer, len);
+ if(!pointed)
+ kfree(buffer);
+#ifndef __ECOS
+ else
+ c->mtd->unpoint(c->mtd, buffer, ofs, len);
+#endif
- /* If we've never checked the CRCs on this node, check them now. */
- if (ref_flags(ref) == REF_UNCHECKED) {
- uint32_t crc, len;
- struct jffs2_eraseblock *jeb;
-
- crc = crc32(0, &node, sizeof(node.i)-8);
- if (crc != je32_to_cpu(node.i.node_crc)) {
- printk(KERN_NOTICE "jffs2_get_inode_nodes(): CRC failed on node at 0x%08x: Read 0x%08x, calculated 0x%08x\n",
- ref_offset(ref), je32_to_cpu(node.i.node_crc), crc);
- jffs2_mark_node_obsolete(c, ref);
- spin_lock(&c->erase_completion_lock);
- continue;
- }
-
- /* sanity checks */
- if ( je32_to_cpu(node.i.offset) > je32_to_cpu(node.i.isize) ||
- PAD(je32_to_cpu(node.i.csize) + sizeof (node.i)) != PAD(je32_to_cpu(node.i.totlen))) {
- printk(KERN_NOTICE "jffs2_get_inode_nodes(): Inode corrupted at 0x%08x, totlen %d, #ino %d, version %d, isize %d, csize %d, dsize %d \n",
- ref_offset(ref), je32_to_cpu(node.i.totlen), je32_to_cpu(node.i.ino),
- je32_to_cpu(node.i.version), je32_to_cpu(node.i.isize),
- je32_to_cpu(node.i.csize), je32_to_cpu(node.i.dsize));
- jffs2_mark_node_obsolete(c, ref);
- spin_lock(&c->erase_completion_lock);
- continue;
- }
+ if (crc != tn->data_crc) {
+ JFFS2_NOTICE("wrong data CRC in data node at 0x%08x: read %#08x, calculated %#08x.\n",
+ ofs, tn->data_crc, crc);
+ return 1;
+ }
- if (node.i.compr != JFFS2_COMPR_ZERO && je32_to_cpu(node.i.csize)) {
- unsigned char *buf=NULL;
- uint32_t pointed = 0;
-#ifndef __ECOS
- if (c->mtd->point) {
- err = c->mtd->point (c->mtd, ref_offset(ref) + sizeof(node.i), je32_to_cpu(node.i.csize),
- &retlen, &buf);
- if (!err && retlen < je32_to_cpu(node.i.csize)) {
- D1(printk(KERN_DEBUG "MTD point returned len too short: 0x%zx\n", retlen));
- c->mtd->unpoint(c->mtd, buf, ref_offset(ref) + sizeof(node.i), je32_to_cpu(node.i.csize));
- } else if (err){
- D1(printk(KERN_DEBUG "MTD point failed %d\n", err));
- } else
- pointed = 1; /* succefully pointed to device */
- }
-#endif
- if(!pointed){
- buf = kmalloc(je32_to_cpu(node.i.csize), GFP_KERNEL);
- if (!buf)
- return -ENOMEM;
-
- err = jffs2_flash_read(c, ref_offset(ref) + sizeof(node.i), je32_to_cpu(node.i.csize),
- &retlen, buf);
- if (!err && retlen != je32_to_cpu(node.i.csize))
- err = -EIO;
- if (err) {
- kfree(buf);
- return err;
- }
- }
- crc = crc32(0, buf, je32_to_cpu(node.i.csize));
- if(!pointed)
- kfree(buf);
+adj_acc:
+ jeb = &c->blocks[ref->flash_offset / c->sector_size];
+ len = ref_totlen(c, jeb, ref);
+
+ /*
+ * Mark the node as having been checked and fix the
+ * accounting accordingly.
+ */
+ spin_lock(&c->erase_completion_lock);
+ jeb->used_size += len;
+ jeb->unchecked_size -= len;
+ c->used_size += len;
+ c->unchecked_size -= len;
+ spin_unlock(&c->erase_completion_lock);
+
+ return 0;
+
+free_out:
+ if(!pointed)
+ kfree(buffer);
#ifndef __ECOS
- else
- c->mtd->unpoint(c->mtd, buf, ref_offset(ref) + sizeof(node.i), je32_to_cpu(node.i.csize));
+ else
+ c->mtd->unpoint(c->mtd, buffer, ofs, len);
#endif
+ return err;
+}
- if (crc != je32_to_cpu(node.i.data_crc)) {
- printk(KERN_NOTICE "jffs2_get_inode_nodes(): Data CRC failed on node at 0x%08x: Read 0x%08x, calculated 0x%08x\n",
- ref_offset(ref), je32_to_cpu(node.i.data_crc), crc);
- jffs2_mark_node_obsolete(c, ref);
- spin_lock(&c->erase_completion_lock);
- continue;
- }
-
- }
+/*
+ * Helper function for jffs2_add_older_frag_to_fragtree().
+ *
+ * Checks the node if we are in the checking stage.
+ */
+static inline int check_node(struct jffs2_sb_info *c, struct jffs2_inode_info *f, struct jffs2_tmp_dnode_info *tn)
+{
+ int ret;
- /* Mark the node as having been checked and fix the accounting accordingly */
- spin_lock(&c->erase_completion_lock);
- jeb = &c->blocks[ref->flash_offset / c->sector_size];
- len = ref_totlen(c, jeb, ref);
-
- jeb->used_size += len;
- jeb->unchecked_size -= len;
- c->used_size += len;
- c->unchecked_size -= len;
-
- /* If node covers at least a whole page, or if it starts at the
- beginning of a page and runs to the end of the file, or if
- it's a hole node, mark it REF_PRISTINE, else REF_NORMAL.
-
- If it's actually overlapped, it'll get made NORMAL (or OBSOLETE)
- when the overlapping node(s) get added to the tree anyway.
- */
- if ((je32_to_cpu(node.i.dsize) >= PAGE_CACHE_SIZE) ||
- ( ((je32_to_cpu(node.i.offset)&(PAGE_CACHE_SIZE-1))==0) &&
- (je32_to_cpu(node.i.dsize)+je32_to_cpu(node.i.offset) == je32_to_cpu(node.i.isize)))) {
- D1(printk(KERN_DEBUG "Marking node at 0x%08x REF_PRISTINE\n", ref_offset(ref)));
- ref->flash_offset = ref_offset(ref) | REF_PRISTINE;
- } else {
- D1(printk(KERN_DEBUG "Marking node at 0x%08x REF_NORMAL\n", ref_offset(ref)));
- ref->flash_offset = ref_offset(ref) | REF_NORMAL;
- }
- spin_unlock(&c->erase_completion_lock);
+ BUG_ON(ref_obsolete(tn->fn->raw));
+
+ /* We only check the data CRC of unchecked nodes */
+ if (ref_flags(tn->fn->raw) != REF_UNCHECKED)
+ return 0;
+
+ dbg_fragtree2("check node %#04x-%#04x, phys offs %#08x.\n",
+ tn->fn->ofs, tn->fn->ofs + tn->fn->size, ref_offset(tn->fn->raw));
+
+ ret = check_node_data(c, tn);
+ if (unlikely(ret < 0)) {
+ JFFS2_ERROR("check_node_data() returned error: %d.\n",
+ ret);
+ } else if (unlikely(ret > 0)) {
+ dbg_fragtree2("CRC error, mark it obsolete.\n");
+ jffs2_mark_node_obsolete(c, tn->fn->raw);
+ }
+
+ return ret;
+}
+
+/*
+ * Helper function for jffs2_add_older_frag_to_fragtree().
+ *
+ * Called when the new fragment that is being inserted
+ * splits a hole fragment.
+ */
+static int split_hole(struct jffs2_sb_info *c, struct rb_root *root,
+ struct jffs2_node_frag *newfrag, struct jffs2_node_frag *hole)
+{
+ dbg_fragtree2("fragment %#04x-%#04x splits the hole %#04x-%#04x\n",
+ newfrag->ofs, newfrag->ofs + newfrag->size, hole->ofs, hole->ofs + hole->size);
+
+ if (hole->ofs == newfrag->ofs) {
+ /*
+ * Well, the new fragment actually starts at the same offset as
+ * the hole.
+ */
+ if (hole->ofs + hole->size > newfrag->ofs + newfrag->size) {
+ /*
+ * We replace the overlapped left part of the hole by
+ * the new node.
+ */
+
+ dbg_fragtree2("insert fragment %#04x-%#04x and cut the left part of the hole\n",
+ newfrag->ofs, newfrag->ofs + newfrag->size);
+ rb_replace_node(&hole->rb, &newfrag->rb, root);
+
+ hole->ofs += newfrag->size;
+ hole->size -= newfrag->size;
+
+ /*
+ * We know that 'hole' should be the right hand
+ * fragment.
+ */
+ jffs2_fragtree_insert(hole, newfrag);
+ rb_insert_color(&hole->rb, root);
+ } else {
+ /*
+ * Ah, the new fragment is of the same size as the hole.
+ * Relace the hole by it.
+ */
+ dbg_fragtree2("insert fragment %#04x-%#04x and overwrite hole\n",
+ newfrag->ofs, newfrag->ofs + newfrag->size);
+ rb_replace_node(&hole->rb, &newfrag->rb, root);
+ jffs2_free_node_frag(hole);
+ }
+ } else {
+ /* The new fragment lefts some hole space at the left */
+
+ struct jffs2_node_frag * newfrag2 = NULL;
+
+ if (hole->ofs + hole->size > newfrag->ofs + newfrag->size) {
+ /* The new frag also lefts some space at the right */
+ newfrag2 = new_fragment(NULL, newfrag->ofs +
+ newfrag->size, hole->ofs + hole->size
+ - newfrag->ofs - newfrag->size);
+ if (unlikely(!newfrag2)) {
+ jffs2_free_node_frag(newfrag);
+ return -ENOMEM;
}
+ }
+
+ hole->size = newfrag->ofs - hole->ofs;
+ dbg_fragtree2("left the hole %#04x-%#04x at the left and inserd fragment %#04x-%#04x\n",
+ hole->ofs, hole->ofs + hole->size, newfrag->ofs, newfrag->ofs + newfrag->size);
+
+ jffs2_fragtree_insert(newfrag, hole);
+ rb_insert_color(&newfrag->rb, root);
+
+ if (newfrag2) {
+ dbg_fragtree2("left the hole %#04x-%#04x at the right\n",
+ newfrag2->ofs, newfrag2->ofs + newfrag2->size);
+ jffs2_fragtree_insert(newfrag2, newfrag);
+ rb_insert_color(&newfrag2->rb, root);
+ }
+ }
+
+ return 0;
+}
+
+/*
+ * This function is used when we build inode. It expects the nodes are passed
+ * in the decreasing version order. The whole point of this is to improve the
+ * inodes checking on NAND: we check the nodes' data CRC only when they are not
+ * obsoleted. Previously, add_frag_to_fragtree() function was used and
+ * nodes were passed to it in the increasing version ordes and CRCs of all
+ * nodes were checked.
+ *
+ * Note: tn->fn->size shouldn't be zero.
+ *
+ * Returns 0 if the node was inserted
+ * 1 if it wasn't inserted (since it is obsolete)
+ * < 0 an if error occured
+ */
+int jffs2_add_older_frag_to_fragtree(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
+ struct jffs2_tmp_dnode_info *tn)
+{
+ struct jffs2_node_frag *this, *newfrag;
+ uint32_t lastend;
+ struct jffs2_full_dnode *fn = tn->fn;
+ struct rb_root *root = &f->fragtree;
+ uint32_t fn_size = fn->size, fn_ofs = fn->ofs;
+ int err, checked = 0;
+ int ref_flag;
+
+ dbg_fragtree("insert fragment %#04x-%#04x, ver %u\n", fn_ofs, fn_ofs + fn_size, tn->version);
+
+ /* Skip all the nodes which are completed before this one starts */
+ this = jffs2_lookup_node_frag(root, fn_ofs);
+ if (this)
+ dbg_fragtree2("'this' found %#04x-%#04x (%s)\n", this->ofs, this->ofs + this->size, this->node ? "data" : "hole");
+
+ if (this)
+ lastend = this->ofs + this->size;
+ else
+ lastend = 0;
+
+ /* Detect the preliminary type of node */
+ if (fn->size >= PAGE_CACHE_SIZE)
+ ref_flag = REF_PRISTINE;
+ else
+ ref_flag = REF_NORMAL;
+
+ /* See if we ran off the end of the root */
+ if (lastend <= fn_ofs) {
+ /* We did */
+
+ /*
+ * We are going to insert the new node into the
+ * fragment tree, so check it.
+ */
+ err = check_node(c, f, tn);
+ if (err != 0)
+ return err;
+
+ fn->frags = 1;
+
+ newfrag = new_fragment(fn, fn_ofs, fn_size);
+ if (unlikely(!newfrag))
+ return -ENOMEM;
+
+ err = no_overlapping_node(c, root, newfrag, this, lastend);
+ if (unlikely(err != 0)) {
+ jffs2_free_node_frag(newfrag);
+ return err;
+ }
+
+ goto out_ok;
+ }
- tn = jffs2_alloc_tmp_dnode_info();
- if (!tn) {
- D1(printk(KERN_DEBUG "alloc tn failed\n"));
- err = -ENOMEM;
- goto free_out;
+ fn->frags = 0;
+
+ while (1) {
+ /*
+ * Here we have:
+ * fn_ofs < this->ofs + this->size && fn_ofs >= this->ofs.
+ *
+ * Remember, 'this' has higher version, any non-hole node
+ * which is already in the fragtree is newer then the newly
+ * inserted.
+ */
+ if (!this->node) {
+ /*
+ * 'this' is the hole fragment, so at least the
+ * beginning of the new fragment is valid.
+ */
+
+ /*
+ * We are going to insert the new node into the
+ * fragment tree, so check it.
+ */
+ if (!checked) {
+ err = check_node(c, f, tn);
+ if (unlikely(err != 0))
+ return err;
+ checked = 1;
}
- tn->fn = jffs2_alloc_full_dnode();
- if (!tn->fn) {
- D1(printk(KERN_DEBUG "alloc fn failed\n"));
- err = -ENOMEM;
- jffs2_free_tmp_dnode_info(tn);
- goto free_out;
+ if (this->ofs + this->size >= fn_ofs + fn_size) {
+ /* We split the hole on two parts */
+
+ fn->frags += 1;
+ newfrag = new_fragment(fn, fn_ofs, fn_size);
+ if (unlikely(!newfrag))
+ return -ENOMEM;
+
+ err = split_hole(c, root, newfrag, this);
+ if (unlikely(err))
+ return err;
+ goto out_ok;
}
- tn->version = je32_to_cpu(node.i.version);
- tn->fn->ofs = je32_to_cpu(node.i.offset);
- /* There was a bug where we wrote hole nodes out with
- csize/dsize swapped. Deal with it */
- if (node.i.compr == JFFS2_COMPR_ZERO && !je32_to_cpu(node.i.dsize) && je32_to_cpu(node.i.csize))
- tn->fn->size = je32_to_cpu(node.i.csize);
- else // normal case...
- tn->fn->size = je32_to_cpu(node.i.dsize);
- tn->fn->raw = ref;
- D1(printk(KERN_DEBUG "dnode @%08x: ver %u, offset %04x, dsize %04x\n",
- ref_offset(ref), je32_to_cpu(node.i.version),
- je32_to_cpu(node.i.offset), je32_to_cpu(node.i.dsize)));
- jffs2_add_tn_to_tree(tn, &ret_tn);
- break;
-
- default:
- if (ref_flags(ref) == REF_UNCHECKED) {
- struct jffs2_eraseblock *jeb;
- uint32_t len;
-
- printk(KERN_ERR "Eep. Unknown node type %04x at %08x was marked REF_UNCHECKED\n",
- je16_to_cpu(node.u.nodetype), ref_offset(ref));
-
- /* Mark the node as having been checked and fix the accounting accordingly */
- spin_lock(&c->erase_completion_lock);
- jeb = &c->blocks[ref->flash_offset / c->sector_size];
- len = ref_totlen(c, jeb, ref);
-
- jeb->used_size += len;
- jeb->unchecked_size -= len;
- c->used_size += len;
- c->unchecked_size -= len;
-
- mark_ref_normal(ref);
- spin_unlock(&c->erase_completion_lock);
+
+ /*
+ * The beginning of the new fragment is valid since it
+ * overlaps the hole node.
+ */
+
+ ref_flag = REF_NORMAL;
+
+ fn->frags += 1;
+ newfrag = new_fragment(fn, fn_ofs,
+ this->ofs + this->size - fn_ofs);
+ if (unlikely(!newfrag))
+ return -ENOMEM;
+
+ if (fn_ofs == this->ofs) {
+ /*
+ * The new node starts at the same offset as
+ * the hole and supersieds the hole.
+ */
+ dbg_fragtree2("add the new fragment instead of hole %#04x-%#04x, refcnt %d\n",
+ fn_ofs, fn_ofs + this->ofs + this->size - fn_ofs, fn->frags);
+
+ rb_replace_node(&this->rb, &newfrag->rb, root);
+ jffs2_free_node_frag(this);
+ } else {
+ /*
+ * The hole becomes shorter as its right part
+ * is supersieded by the new fragment.
+ */
+ dbg_fragtree2("reduce size of hole %#04x-%#04x to %#04x-%#04x\n",
+ this->ofs, this->ofs + this->size, this->ofs, this->ofs + this->size - newfrag->size);
+
+ dbg_fragtree2("add new fragment %#04x-%#04x, refcnt %d\n", fn_ofs,
+ fn_ofs + this->ofs + this->size - fn_ofs, fn->frags);
+
+ this->size -= newfrag->size;
+ jffs2_fragtree_insert(newfrag, this);
+ rb_insert_color(&newfrag->rb, root);
}
- node.u.nodetype = cpu_to_je16(JFFS2_NODE_ACCURATE | je16_to_cpu(node.u.nodetype));
- if (crc32(0, &node, sizeof(struct jffs2_unknown_node)-4) != je32_to_cpu(node.u.hdr_crc)) {
- /* Hmmm. This should have been caught at scan time. */
- printk(KERN_ERR "Node header CRC failed at %08x. But it must have been OK earlier.\n",
- ref_offset(ref));
- printk(KERN_ERR "Node was: { %04x, %04x, %08x, %08x }\n",
- je16_to_cpu(node.u.magic), je16_to_cpu(node.u.nodetype), je32_to_cpu(node.u.totlen),
- je32_to_cpu(node.u.hdr_crc));
- jffs2_mark_node_obsolete(c, ref);
- } else switch(je16_to_cpu(node.u.nodetype) & JFFS2_COMPAT_MASK) {
- case JFFS2_FEATURE_INCOMPAT:
- printk(KERN_NOTICE "Unknown INCOMPAT nodetype %04X at %08x\n", je16_to_cpu(node.u.nodetype), ref_offset(ref));
- /* EEP */
- BUG();
- break;
- case JFFS2_FEATURE_ROCOMPAT:
- printk(KERN_NOTICE "Unknown ROCOMPAT nodetype %04X at %08x\n", je16_to_cpu(node.u.nodetype), ref_offset(ref));
- if (!(c->flags & JFFS2_SB_FLAG_RO))
- BUG();
- break;
- case JFFS2_FEATURE_RWCOMPAT_COPY:
- printk(KERN_NOTICE "Unknown RWCOMPAT_COPY nodetype %04X at %08x\n", je16_to_cpu(node.u.nodetype), ref_offset(ref));
- break;
- case JFFS2_FEATURE_RWCOMPAT_DELETE:
- printk(KERN_NOTICE "Unknown RWCOMPAT_DELETE nodetype %04X at %08x\n", je16_to_cpu(node.u.nodetype), ref_offset(ref));
- jffs2_mark_node_obsolete(c, ref);
- break;
+
+ fn_ofs += newfrag->size;
+ fn_size -= newfrag->size;
+ this = rb_entry(rb_next(&newfrag->rb),
+ struct jffs2_node_frag, rb);
+
+ dbg_fragtree2("switch to the next 'this' fragment: %#04x-%#04x %s\n",
+ this->ofs, this->ofs + this->size, this->node ? "(data)" : "(hole)");
+ }
+
+ /*
+ * 'This' node is not the hole so it obsoletes the new fragment
+ * either fully or partially.
+ */
+ if (this->ofs + this->size >= fn_ofs + fn_size) {
+ /* The new node is obsolete, drop it */
+ if (fn->frags == 0) {
+ dbg_fragtree2("%#04x-%#04x is obsolete, mark it obsolete\n", fn_ofs, fn_ofs + fn_size);
+ ref_flag = REF_OBSOLETE;
}
+ goto out_ok;
+ } else {
+ struct jffs2_node_frag *new_this;
+
+ /* 'This' node obsoletes the beginning of the new node */
+ dbg_fragtree2("the beginning %#04x-%#04x is obsolete\n", fn_ofs, this->ofs + this->size);
+
+ ref_flag = REF_NORMAL;
+
+ fn_size -= this->ofs + this->size - fn_ofs;
+ fn_ofs = this->ofs + this->size;
+ dbg_fragtree2("now considering %#04x-%#04x\n", fn_ofs, fn_ofs + fn_size);
+
+ new_this = rb_entry(rb_next(&this->rb), struct jffs2_node_frag, rb);
+ if (!new_this) {
+ /*
+ * There is no next fragment. Add the rest of
+ * the new node as the right-hand child.
+ */
+ if (!checked) {
+ err = check_node(c, f, tn);
+ if (unlikely(err != 0))
+ return err;
+ checked = 1;
+ }
+ fn->frags += 1;
+ newfrag = new_fragment(fn, fn_ofs, fn_size);
+ if (unlikely(!newfrag))
+ return -ENOMEM;
+
+ dbg_fragtree2("there are no more fragments, insert %#04x-%#04x\n",
+ newfrag->ofs, newfrag->ofs + newfrag->size);
+ rb_link_node(&newfrag->rb, &this->rb, &this->rb.rb_right);
+ rb_insert_color(&newfrag->rb, root);
+ goto out_ok;
+ } else {
+ this = new_this;
+ dbg_fragtree2("switch to the next 'this' fragment: %#04x-%#04x %s\n",
+ this->ofs, this->ofs + this->size, this->node ? "(data)" : "(hole)");
+ }
}
- spin_lock(&c->erase_completion_lock);
+ }
+
+out_ok:
+ BUG_ON(fn->size < PAGE_CACHE_SIZE && ref_flag == REF_PRISTINE);
+ if (ref_flag == REF_OBSOLETE) {
+ dbg_fragtree2("the node is obsolete now\n");
+ /* jffs2_mark_node_obsolete() will adjust space accounting */
+ jffs2_mark_node_obsolete(c, fn->raw);
+ return 1;
}
+
+ dbg_fragtree2("the node is \"%s\" now\n", ref_flag == REF_NORMAL ? "REF_NORMAL" : "REF_PRISTINE");
+
+ /* Space accounting was adjusted at check_node_data() */
+ spin_lock(&c->erase_completion_lock);
+ fn->raw->flash_offset = ref_offset(fn->raw) | ref_flag;
spin_unlock(&c->erase_completion_lock);
- *tnp = ret_tn;
- *fdp = ret_fd;
return 0;
-
- free_out:
- jffs2_free_tmp_dnode_info_list(&ret_tn);
- jffs2_free_full_dirent_list(ret_fd);
- return err;
}
void jffs2_set_inocache_state(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic, int state)
@@ -499,24 +862,21 @@ void jffs2_set_inocache_state(struct jffs2_sb_info *c, struct jffs2_inode_cache
/* During mount, this needs no locking. During normal operation, its
callers want to do other stuff while still holding the inocache_lock.
- Rather than introducing special case get_ino_cache functions or
+ Rather than introducing special case get_ino_cache functions or
callbacks, we just let the caller do the locking itself. */
-
+
struct jffs2_inode_cache *jffs2_get_ino_cache(struct jffs2_sb_info *c, uint32_t ino)
{
struct jffs2_inode_cache *ret;
- D2(printk(KERN_DEBUG "jffs2_get_ino_cache(): ino %u\n", ino));
-
ret = c->inocache_list[ino % INOCACHE_HASHSIZE];
while (ret && ret->ino < ino) {
ret = ret->next;
}
-
+
if (ret && ret->ino != ino)
ret = NULL;
- D2(printk(KERN_DEBUG "jffs2_get_ino_cache found %p for ino %u\n", ret, ino));
return ret;
}
@@ -528,7 +888,7 @@ void jffs2_add_ino_cache (struct jffs2_sb_info *c, struct jffs2_inode_cache *new
if (!new->ino)
new->ino = ++c->highest_ino;
- D2(printk(KERN_DEBUG "jffs2_add_ino_cache: Add %p (ino #%u)\n", new, new->ino));
+ dbg_inocache("add %p (ino #%u)\n", new, new->ino);
prev = &c->inocache_list[new->ino % INOCACHE_HASHSIZE];
@@ -544,11 +904,12 @@ void jffs2_add_ino_cache (struct jffs2_sb_info *c, struct jffs2_inode_cache *new
void jffs2_del_ino_cache(struct jffs2_sb_info *c, struct jffs2_inode_cache *old)
{
struct jffs2_inode_cache **prev;
- D1(printk(KERN_DEBUG "jffs2_del_ino_cache: Del %p (ino #%u)\n", old, old->ino));
+
+ dbg_inocache("del %p (ino #%u)\n", old, old->ino);
spin_lock(&c->inocache_lock);
-
+
prev = &c->inocache_list[old->ino % INOCACHE_HASHSIZE];
-
+
while ((*prev) && (*prev)->ino < old->ino) {
prev = &(*prev)->next;
}
@@ -558,7 +919,7 @@ void jffs2_del_ino_cache(struct jffs2_sb_info *c, struct jffs2_inode_cache *old)
/* Free it now unless it's in READING or CLEARING state, which
are the transitions upon read_inode() and clear_inode(). The
- rest of the time we know nobody else is looking at it, and
+ rest of the time we know nobody else is looking at it, and
if it's held by read_inode() or clear_inode() they'll free it
for themselves. */
if (old->state != INO_STATE_READING && old->state != INO_STATE_CLEARING)
@@ -571,7 +932,7 @@ void jffs2_free_ino_caches(struct jffs2_sb_info *c)
{
int i;
struct jffs2_inode_cache *this, *next;
-
+
for (i=0; i<INOCACHE_HASHSIZE; i++) {
this = c->inocache_list[i];
while (this) {
@@ -598,38 +959,30 @@ void jffs2_free_raw_node_refs(struct jffs2_sb_info *c)
c->blocks[i].first_node = c->blocks[i].last_node = NULL;
}
}
-
+
struct jffs2_node_frag *jffs2_lookup_node_frag(struct rb_root *fragtree, uint32_t offset)
{
- /* The common case in lookup is that there will be a node
+ /* The common case in lookup is that there will be a node
which precisely matches. So we go looking for that first */
struct rb_node *next;
struct jffs2_node_frag *prev = NULL;
struct jffs2_node_frag *frag = NULL;
- D2(printk(KERN_DEBUG "jffs2_lookup_node_frag(%p, %d)\n", fragtree, offset));
+ dbg_fragtree2("root %p, offset %d\n", fragtree, offset);
next = fragtree->rb_node;
while(next) {
frag = rb_entry(next, struct jffs2_node_frag, rb);
- D2(printk(KERN_DEBUG "Considering frag %d-%d (%p). left %p, right %p\n",
- frag->ofs, frag->ofs+frag->size, frag, frag->rb.rb_left, frag->rb.rb_right));
if (frag->ofs + frag->size <= offset) {
- D2(printk(KERN_DEBUG "Going right from frag %d-%d, before the region we care about\n",
- frag->ofs, frag->ofs+frag->size));
/* Remember the closest smaller match on the way down */
if (!prev || frag->ofs > prev->ofs)
prev = frag;
next = frag->rb.rb_right;
} else if (frag->ofs > offset) {
- D2(printk(KERN_DEBUG "Going left from frag %d-%d, after the region we care about\n",
- frag->ofs, frag->ofs+frag->size));
next = frag->rb.rb_left;
} else {
- D2(printk(KERN_DEBUG "Returning frag %d,%d, matched\n",
- frag->ofs, frag->ofs+frag->size));
return frag;
}
}
@@ -638,11 +991,11 @@ struct jffs2_node_frag *jffs2_lookup_node_frag(struct rb_root *fragtree, uint32_
and return the closest smaller one */
if (prev)
- D2(printk(KERN_DEBUG "No match. Returning frag %d,%d, closest previous\n",
- prev->ofs, prev->ofs+prev->size));
- else
- D2(printk(KERN_DEBUG "Returning NULL, empty fragtree\n"));
-
+ dbg_fragtree2("no match. Returning frag %#04x-%#04x, closest previous\n",
+ prev->ofs, prev->ofs+prev->size);
+ else
+ dbg_fragtree2("returning NULL, empty fragtree\n");
+
return prev;
}
@@ -656,39 +1009,32 @@ void jffs2_kill_fragtree(struct rb_root *root, struct jffs2_sb_info *c)
if (!root->rb_node)
return;
- frag = (rb_entry(root->rb_node, struct jffs2_node_frag, rb));
+ dbg_fragtree("killing\n");
+ frag = (rb_entry(root->rb_node, struct jffs2_node_frag, rb));
while(frag) {
if (frag->rb.rb_left) {
- D2(printk(KERN_DEBUG "Going left from frag (%p) %d-%d\n",
- frag, frag->ofs, frag->ofs+frag->size));
frag = frag_left(frag);
continue;
}
if (frag->rb.rb_right) {
- D2(printk(KERN_DEBUG "Going right from frag (%p) %d-%d\n",
- frag, frag->ofs, frag->ofs+frag->size));
frag = frag_right(frag);
continue;
}
- D2(printk(KERN_DEBUG "jffs2_kill_fragtree: frag at 0x%x-0x%x: node %p, frags %d--\n",
- frag->ofs, frag->ofs+frag->size, frag->node,
- frag->node?frag->node->frags:0));
-
if (frag->node && !(--frag->node->frags)) {
- /* Not a hole, and it's the final remaining frag
+ /* Not a hole, and it's the final remaining frag
of this node. Free the node */
if (c)
jffs2_mark_node_obsolete(c, frag->node->raw);
-
+
jffs2_free_full_dnode(frag->node);
}
parent = frag_parent(frag);
if (parent) {
if (frag_left(parent) == frag)
parent->rb.rb_left = NULL;
- else
+ else
parent->rb.rb_right = NULL;
}
@@ -698,29 +1044,3 @@ void jffs2_kill_fragtree(struct rb_root *root, struct jffs2_sb_info *c)
cond_resched();
}
}
-
-void jffs2_fragtree_insert(struct jffs2_node_frag *newfrag, struct jffs2_node_frag *base)
-{
- struct rb_node *parent = &base->rb;
- struct rb_node **link = &parent;
-
- D2(printk(KERN_DEBUG "jffs2_fragtree_insert(%p; %d-%d, %p)\n", newfrag,
- newfrag->ofs, newfrag->ofs+newfrag->size, base));
-
- while (*link) {
- parent = *link;
- base = rb_entry(parent, struct jffs2_node_frag, rb);
-
- D2(printk(KERN_DEBUG "fragtree_insert considering frag at 0x%x\n", base->ofs));
- if (newfrag->ofs > base->ofs)
- link = &base->rb.rb_right;
- else if (newfrag->ofs < base->ofs)
- link = &base->rb.rb_left;
- else {
- printk(KERN_CRIT "Duplicate frag at %08x (%p,%p)\n", newfrag->ofs, newfrag, base);
- BUG();
- }
- }
-
- rb_link_node(&newfrag->rb, &base->rb, link);
-}
diff --git a/fs/jffs2/nodelist.h b/fs/jffs2/nodelist.h
index b34c397909ef..23a67bb3052f 100644
--- a/fs/jffs2/nodelist.h
+++ b/fs/jffs2/nodelist.h
@@ -7,7 +7,7 @@
*
* For licensing information, see the file 'LICENCE' in this directory.
*
- * $Id: nodelist.h,v 1.131 2005/07/05 21:03:07 dwmw2 Exp $
+ * $Id: nodelist.h,v 1.140 2005/09/07 08:34:54 havasi Exp $
*
*/
@@ -20,30 +20,15 @@
#include <linux/jffs2.h>
#include <linux/jffs2_fs_sb.h>
#include <linux/jffs2_fs_i.h>
+#include "summary.h"
#ifdef __ECOS
#include "os-ecos.h"
#else
-#include <linux/mtd/compatmac.h> /* For min/max in older kernels */
+#include <linux/mtd/compatmac.h> /* For compatibility with older kernels */
#include "os-linux.h"
#endif
-#ifndef CONFIG_JFFS2_FS_DEBUG
-#define CONFIG_JFFS2_FS_DEBUG 1
-#endif
-
-#if CONFIG_JFFS2_FS_DEBUG > 0
-#define D1(x) x
-#else
-#define D1(x)
-#endif
-
-#if CONFIG_JFFS2_FS_DEBUG > 1
-#define D2(x) x
-#else
-#define D2(x)
-#endif
-
#define JFFS2_NATIVE_ENDIAN
/* Note we handle mode bits conversion from JFFS2 (i.e. Linux) to/from
@@ -73,14 +58,17 @@
#define je16_to_cpu(x) (le16_to_cpu(x.v16))
#define je32_to_cpu(x) (le32_to_cpu(x.v32))
#define jemode_to_cpu(x) (le32_to_cpu(jffs2_to_os_mode((x).m)))
-#else
+#else
#error wibble
#endif
+/* The minimal node header size */
+#define JFFS2_MIN_NODE_HEADER sizeof(struct jffs2_raw_dirent)
+
/*
This is all we need to keep in-core for each raw node during normal
operation. As and when we do read_inode on a particular inode, we can
- scan the nodes which are listed for it and build up a proper map of
+ scan the nodes which are listed for it and build up a proper map of
which nodes are currently valid. JFFSv1 always used to keep that whole
map in core for each inode.
*/
@@ -97,7 +85,7 @@ struct jffs2_raw_node_ref
/* flash_offset & 3 always has to be zero, because nodes are
always aligned at 4 bytes. So we have a couple of extra bits
- to play with, which indicate the node's status; see below: */
+ to play with, which indicate the node's status; see below: */
#define REF_UNCHECKED 0 /* We haven't yet checked the CRC or built its inode */
#define REF_OBSOLETE 1 /* Obsolete, can be completely ignored */
#define REF_PRISTINE 2 /* Completely clean. GC without looking */
@@ -110,7 +98,7 @@ struct jffs2_raw_node_ref
/* For each inode in the filesystem, we need to keep a record of
nlink, because it would be a PITA to scan the whole directory tree
at read_inode() time to calculate it, and to keep sufficient information
- in the raw_node_ref (basically both parent and child inode number for
+ in the raw_node_ref (basically both parent and child inode number for
dirent nodes) would take more space than this does. We also keep
a pointer to the first physical node which is part of this inode, too.
*/
@@ -140,7 +128,7 @@ struct jffs2_inode_cache {
#define INOCACHE_HASHSIZE 128
/*
- Larger representation of a raw node, kept in-core only when the
+ Larger representation of a raw node, kept in-core only when the
struct inode for this particular ino is instantiated.
*/
@@ -150,11 +138,11 @@ struct jffs2_full_dnode
uint32_t ofs; /* The offset to which the data of this node belongs */
uint32_t size;
uint32_t frags; /* Number of fragments which currently refer
- to this node. When this reaches zero,
+ to this node. When this reaches zero,
the node is obsolete. */
};
-/*
+/*
Even larger representation of a raw node, kept in-core only while
we're actually building up the original map of which nodes go where,
in read_inode()
@@ -164,7 +152,10 @@ struct jffs2_tmp_dnode_info
struct rb_node rb;
struct jffs2_full_dnode *fn;
uint32_t version;
-};
+ uint32_t data_crc;
+ uint32_t partial_crc;
+ uint32_t csize;
+};
struct jffs2_full_dirent
{
@@ -178,7 +169,7 @@ struct jffs2_full_dirent
};
/*
- Fragments - used to build a map of which raw node to obtain
+ Fragments - used to build a map of which raw node to obtain
data from for each part of the ino
*/
struct jffs2_node_frag
@@ -207,86 +198,18 @@ struct jffs2_eraseblock
struct jffs2_raw_node_ref *gc_node; /* Next node to be garbage collected */
};
-#define ACCT_SANITY_CHECK(c, jeb) do { \
- struct jffs2_eraseblock *___j = jeb; \
- if ((___j) && ___j->used_size + ___j->dirty_size + ___j->free_size + ___j->wasted_size + ___j->unchecked_size != c->sector_size) { \
- printk(KERN_NOTICE "Eeep. Space accounting for block at 0x%08x is screwed\n", ___j->offset); \
- printk(KERN_NOTICE "free 0x%08x + dirty 0x%08x + used %08x + wasted %08x + unchecked %08x != total %08x\n", \
- ___j->free_size, ___j->dirty_size, ___j->used_size, ___j->wasted_size, ___j->unchecked_size, c->sector_size); \
- BUG(); \
- } \
- if (c->used_size + c->dirty_size + c->free_size + c->erasing_size + c->bad_size + c->wasted_size + c->unchecked_size != c->flash_size) { \
- printk(KERN_NOTICE "Eeep. Space accounting superblock info is screwed\n"); \
- printk(KERN_NOTICE "free 0x%08x + dirty 0x%08x + used %08x + erasing %08x + bad %08x + wasted %08x + unchecked %08x != total %08x\n", \
- c->free_size, c->dirty_size, c->used_size, c->erasing_size, c->bad_size, c->wasted_size, c->unchecked_size, c->flash_size); \
- BUG(); \
- } \
-} while(0)
-
-static inline void paranoia_failed_dump(struct jffs2_eraseblock *jeb)
+static inline int jffs2_blocks_use_vmalloc(struct jffs2_sb_info *c)
{
- struct jffs2_raw_node_ref *ref;
- int i=0;
-
- printk(KERN_NOTICE);
- for (ref = jeb->first_node; ref; ref = ref->next_phys) {
- printk("%08x->", ref_offset(ref));
- if (++i == 8) {
- i = 0;
- printk("\n" KERN_NOTICE);
- }
- }
- printk("\n");
+ return ((c->flash_size / c->sector_size) * sizeof (struct jffs2_eraseblock)) > (128 * 1024);
}
-
-#define ACCT_PARANOIA_CHECK(jeb) do { \
- uint32_t my_used_size = 0; \
- uint32_t my_unchecked_size = 0; \
- struct jffs2_raw_node_ref *ref2 = jeb->first_node; \
- while (ref2) { \
- if (unlikely(ref2->flash_offset < jeb->offset || \
- ref2->flash_offset > jeb->offset + c->sector_size)) { \
- printk(KERN_NOTICE "Node %08x shouldn't be in block at %08x!\n", \
- ref_offset(ref2), jeb->offset); \
- paranoia_failed_dump(jeb); \
- BUG(); \
- } \
- if (ref_flags(ref2) == REF_UNCHECKED) \
- my_unchecked_size += ref_totlen(c, jeb, ref2); \
- else if (!ref_obsolete(ref2)) \
- my_used_size += ref_totlen(c, jeb, ref2); \
- if (unlikely((!ref2->next_phys) != (ref2 == jeb->last_node))) { \
- if (!ref2->next_phys) \
- printk("ref for node at %p (phys %08x) has next_phys->%p (----), last_node->%p (phys %08x)\n", \
- ref2, ref_offset(ref2), ref2->next_phys, \
- jeb->last_node, ref_offset(jeb->last_node)); \
- else \
- printk("ref for node at %p (phys %08x) has next_phys->%p (%08x), last_node->%p (phys %08x)\n", \
- ref2, ref_offset(ref2), ref2->next_phys, ref_offset(ref2->next_phys), \
- jeb->last_node, ref_offset(jeb->last_node)); \
- paranoia_failed_dump(jeb); \
- BUG(); \
- } \
- ref2 = ref2->next_phys; \
- } \
- if (my_used_size != jeb->used_size) { \
- printk(KERN_NOTICE "Calculated used size %08x != stored used size %08x\n", my_used_size, jeb->used_size); \
- BUG(); \
- } \
- if (my_unchecked_size != jeb->unchecked_size) { \
- printk(KERN_NOTICE "Calculated unchecked size %08x != stored unchecked size %08x\n", my_unchecked_size, jeb->unchecked_size); \
- BUG(); \
- } \
- } while(0)
-
/* Calculate totlen from surrounding nodes or eraseblock */
static inline uint32_t __ref_totlen(struct jffs2_sb_info *c,
struct jffs2_eraseblock *jeb,
struct jffs2_raw_node_ref *ref)
{
uint32_t ref_end;
-
+
if (ref->next_phys)
ref_end = ref_offset(ref->next_phys);
else {
@@ -306,11 +229,13 @@ static inline uint32_t ref_totlen(struct jffs2_sb_info *c,
{
uint32_t ret;
- D1(if (jeb && jeb != &c->blocks[ref->flash_offset / c->sector_size]) {
+#if CONFIG_JFFS2_FS_DEBUG > 0
+ if (jeb && jeb != &c->blocks[ref->flash_offset / c->sector_size]) {
printk(KERN_CRIT "ref_totlen called with wrong block -- at 0x%08x instead of 0x%08x; ref 0x%08x\n",
jeb->offset, c->blocks[ref->flash_offset / c->sector_size].offset, ref_offset(ref));
BUG();
- })
+ }
+#endif
#if 1
ret = ref->__totlen;
@@ -323,14 +248,13 @@ static inline uint32_t ref_totlen(struct jffs2_sb_info *c,
ret, ref->__totlen);
if (!jeb)
jeb = &c->blocks[ref->flash_offset / c->sector_size];
- paranoia_failed_dump(jeb);
+ jffs2_dbg_dump_node_refs_nolock(c, jeb);
BUG();
}
#endif
return ret;
}
-
#define ALLOC_NORMAL 0 /* Normal allocation */
#define ALLOC_DELETION 1 /* Deletion node. Best to allow it */
#define ALLOC_GC 2 /* Space requested for GC. Give it or die */
@@ -340,7 +264,7 @@ static inline uint32_t ref_totlen(struct jffs2_sb_info *c,
#define VERYDIRTY(c, size) ((size) >= ((c)->sector_size / 2))
/* check if dirty space is more than 255 Byte */
-#define ISDIRTY(size) ((size) > sizeof (struct jffs2_raw_inode) + JFFS2_MIN_DATA_LEN)
+#define ISDIRTY(size) ((size) > sizeof (struct jffs2_raw_inode) + JFFS2_MIN_DATA_LEN)
#define PAD(x) (((x)+3)&~3)
@@ -384,12 +308,7 @@ static inline struct jffs2_node_frag *frag_last(struct rb_root *root)
#define frag_erase(frag, list) rb_erase(&frag->rb, list);
/* nodelist.c */
-D2(void jffs2_print_frag_list(struct jffs2_inode_info *f));
void jffs2_add_fd_to_list(struct jffs2_sb_info *c, struct jffs2_full_dirent *new, struct jffs2_full_dirent **list);
-int jffs2_get_inode_nodes(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
- struct rb_root *tnp, struct jffs2_full_dirent **fdp,
- uint32_t *highest_version, uint32_t *latest_mctime,
- uint32_t *mctime_ver);
void jffs2_set_inocache_state(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic, int state);
struct jffs2_inode_cache *jffs2_get_ino_cache(struct jffs2_sb_info *c, uint32_t ino);
void jffs2_add_ino_cache (struct jffs2_sb_info *c, struct jffs2_inode_cache *new);
@@ -398,19 +317,23 @@ void jffs2_free_ino_caches(struct jffs2_sb_info *c);
void jffs2_free_raw_node_refs(struct jffs2_sb_info *c);
struct jffs2_node_frag *jffs2_lookup_node_frag(struct rb_root *fragtree, uint32_t offset);
void jffs2_kill_fragtree(struct rb_root *root, struct jffs2_sb_info *c_delete);
-void jffs2_fragtree_insert(struct jffs2_node_frag *newfrag, struct jffs2_node_frag *base);
struct rb_node *rb_next(struct rb_node *);
struct rb_node *rb_prev(struct rb_node *);
void rb_replace_node(struct rb_node *victim, struct rb_node *new, struct rb_root *root);
+void jffs2_obsolete_node_frag(struct jffs2_sb_info *c, struct jffs2_node_frag *this);
+int jffs2_add_full_dnode_to_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, struct jffs2_full_dnode *fn);
+void jffs2_truncate_fragtree (struct jffs2_sb_info *c, struct rb_root *list, uint32_t size);
+int jffs2_add_older_frag_to_fragtree(struct jffs2_sb_info *c, struct jffs2_inode_info *f, struct jffs2_tmp_dnode_info *tn);
/* nodemgmt.c */
int jffs2_thread_should_wake(struct jffs2_sb_info *c);
-int jffs2_reserve_space(struct jffs2_sb_info *c, uint32_t minsize, uint32_t *ofs, uint32_t *len, int prio);
-int jffs2_reserve_space_gc(struct jffs2_sb_info *c, uint32_t minsize, uint32_t *ofs, uint32_t *len);
+int jffs2_reserve_space(struct jffs2_sb_info *c, uint32_t minsize, uint32_t *ofs,
+ uint32_t *len, int prio, uint32_t sumsize);
+int jffs2_reserve_space_gc(struct jffs2_sb_info *c, uint32_t minsize, uint32_t *ofs,
+ uint32_t *len, uint32_t sumsize);
int jffs2_add_physical_node_ref(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *new);
void jffs2_complete_reservation(struct jffs2_sb_info *c);
void jffs2_mark_node_obsolete(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *raw);
-void jffs2_dump_block_lists(struct jffs2_sb_info *c);
/* write.c */
int jffs2_do_new_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, uint32_t mode, struct jffs2_raw_inode *ri);
@@ -418,17 +341,15 @@ int jffs2_do_new_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, uint
struct jffs2_full_dnode *jffs2_write_dnode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, struct jffs2_raw_inode *ri, const unsigned char *data, uint32_t datalen, uint32_t flash_ofs, int alloc_mode);
struct jffs2_full_dirent *jffs2_write_dirent(struct jffs2_sb_info *c, struct jffs2_inode_info *f, struct jffs2_raw_dirent *rd, const unsigned char *name, uint32_t namelen, uint32_t flash_ofs, int alloc_mode);
int jffs2_write_inode_range(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
- struct jffs2_raw_inode *ri, unsigned char *buf,
+ struct jffs2_raw_inode *ri, unsigned char *buf,
uint32_t offset, uint32_t writelen, uint32_t *retlen);
int jffs2_do_create(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, struct jffs2_inode_info *f, struct jffs2_raw_inode *ri, const char *name, int namelen);
-int jffs2_do_unlink(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, const char *name, int namelen, struct jffs2_inode_info *dead_f);
-int jffs2_do_link (struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, uint32_t ino, uint8_t type, const char *name, int namelen);
+int jffs2_do_unlink(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, const char *name, int namelen, struct jffs2_inode_info *dead_f, uint32_t time);
+int jffs2_do_link (struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, uint32_t ino, uint8_t type, const char *name, int namelen, uint32_t time);
/* readinode.c */
-void jffs2_truncate_fraglist (struct jffs2_sb_info *c, struct rb_root *list, uint32_t size);
-int jffs2_add_full_dnode_to_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, struct jffs2_full_dnode *fn);
-int jffs2_do_read_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
+int jffs2_do_read_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
uint32_t ino, struct jffs2_raw_inode *latest_node);
int jffs2_do_crccheck_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic);
void jffs2_do_clear_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f);
@@ -468,6 +389,10 @@ char *jffs2_getlink(struct jffs2_sb_info *c, struct jffs2_inode_info *f);
/* scan.c */
int jffs2_scan_medium(struct jffs2_sb_info *c);
void jffs2_rotate_lists(struct jffs2_sb_info *c);
+int jffs2_fill_scan_buf(struct jffs2_sb_info *c, void *buf,
+ uint32_t ofs, uint32_t len);
+struct jffs2_inode_cache *jffs2_scan_make_ino_cache(struct jffs2_sb_info *c, uint32_t ino);
+int jffs2_scan_classify_jeb(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb);
/* build.c */
int jffs2_do_mount_fs(struct jffs2_sb_info *c);
@@ -483,4 +408,6 @@ int jffs2_check_nand_cleanmarker(struct jffs2_sb_info *c, struct jffs2_erasebloc
int jffs2_write_nand_cleanmarker(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb);
#endif
+#include "debug.h"
+
#endif /* __JFFS2_NODELIST_H__ */
diff --git a/fs/jffs2/nodemgmt.c b/fs/jffs2/nodemgmt.c
index c1d8b5ed9ab9..49127a1f0458 100644
--- a/fs/jffs2/nodemgmt.c
+++ b/fs/jffs2/nodemgmt.c
@@ -7,7 +7,7 @@
*
* For licensing information, see the file 'LICENCE' in this directory.
*
- * $Id: nodemgmt.c,v 1.122 2005/05/06 09:30:27 dedekind Exp $
+ * $Id: nodemgmt.c,v 1.127 2005/09/20 15:49:12 dedekind Exp $
*
*/
@@ -17,6 +17,7 @@
#include <linux/compiler.h>
#include <linux/sched.h> /* For cond_resched() */
#include "nodelist.h"
+#include "debug.h"
/**
* jffs2_reserve_space - request physical space to write nodes to flash
@@ -38,9 +39,11 @@
* for the requested allocation.
*/
-static int jffs2_do_reserve_space(struct jffs2_sb_info *c, uint32_t minsize, uint32_t *ofs, uint32_t *len);
+static int jffs2_do_reserve_space(struct jffs2_sb_info *c, uint32_t minsize,
+ uint32_t *ofs, uint32_t *len, uint32_t sumsize);
-int jffs2_reserve_space(struct jffs2_sb_info *c, uint32_t minsize, uint32_t *ofs, uint32_t *len, int prio)
+int jffs2_reserve_space(struct jffs2_sb_info *c, uint32_t minsize, uint32_t *ofs,
+ uint32_t *len, int prio, uint32_t sumsize)
{
int ret = -EAGAIN;
int blocksneeded = c->resv_blocks_write;
@@ -85,12 +88,12 @@ int jffs2_reserve_space(struct jffs2_sb_info *c, uint32_t minsize, uint32_t *ofs
up(&c->alloc_sem);
return -ENOSPC;
}
-
+
/* Calc possibly available space. Possibly available means that we
* don't know, if unchecked size contains obsoleted nodes, which could give us some
* more usable space. This will affect the sum only once, as gc first finishes checking
* of nodes.
- + Return -ENOSPC, if the maximum possibly available space is less or equal than
+ + Return -ENOSPC, if the maximum possibly available space is less or equal than
* blocksneeded * sector_size.
* This blocks endless gc looping on a filesystem, which is nearly full, even if
* the check above passes.
@@ -115,7 +118,7 @@ int jffs2_reserve_space(struct jffs2_sb_info *c, uint32_t minsize, uint32_t *ofs
c->nr_free_blocks, c->nr_erasing_blocks, c->free_size, c->dirty_size, c->wasted_size, c->used_size, c->erasing_size, c->bad_size,
c->free_size + c->dirty_size + c->wasted_size + c->used_size + c->erasing_size + c->bad_size, c->flash_size));
spin_unlock(&c->erase_completion_lock);
-
+
ret = jffs2_garbage_collect_pass(c);
if (ret)
return ret;
@@ -129,7 +132,7 @@ int jffs2_reserve_space(struct jffs2_sb_info *c, uint32_t minsize, uint32_t *ofs
spin_lock(&c->erase_completion_lock);
}
- ret = jffs2_do_reserve_space(c, minsize, ofs, len);
+ ret = jffs2_do_reserve_space(c, minsize, ofs, len, sumsize);
if (ret) {
D1(printk(KERN_DEBUG "jffs2_reserve_space: ret is %d\n", ret));
}
@@ -140,7 +143,8 @@ int jffs2_reserve_space(struct jffs2_sb_info *c, uint32_t minsize, uint32_t *ofs
return ret;
}
-int jffs2_reserve_space_gc(struct jffs2_sb_info *c, uint32_t minsize, uint32_t *ofs, uint32_t *len)
+int jffs2_reserve_space_gc(struct jffs2_sb_info *c, uint32_t minsize, uint32_t *ofs,
+ uint32_t *len, uint32_t sumsize)
{
int ret = -EAGAIN;
minsize = PAD(minsize);
@@ -149,7 +153,7 @@ int jffs2_reserve_space_gc(struct jffs2_sb_info *c, uint32_t minsize, uint32_t *
spin_lock(&c->erase_completion_lock);
while(ret == -EAGAIN) {
- ret = jffs2_do_reserve_space(c, minsize, ofs, len);
+ ret = jffs2_do_reserve_space(c, minsize, ofs, len, sumsize);
if (ret) {
D1(printk(KERN_DEBUG "jffs2_reserve_space_gc: looping, ret is %d\n", ret));
}
@@ -158,105 +162,185 @@ int jffs2_reserve_space_gc(struct jffs2_sb_info *c, uint32_t minsize, uint32_t *
return ret;
}
-/* Called with alloc sem _and_ erase_completion_lock */
-static int jffs2_do_reserve_space(struct jffs2_sb_info *c, uint32_t minsize, uint32_t *ofs, uint32_t *len)
+
+/* Classify nextblock (clean, dirty of verydirty) and force to select an other one */
+
+static void jffs2_close_nextblock(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb)
{
- struct jffs2_eraseblock *jeb = c->nextblock;
-
- restart:
- if (jeb && minsize > jeb->free_size) {
- /* Skip the end of this block and file it as having some dirty space */
- /* If there's a pending write to it, flush now */
- if (jffs2_wbuf_dirty(c)) {
+
+ /* Check, if we have a dirty block now, or if it was dirty already */
+ if (ISDIRTY (jeb->wasted_size + jeb->dirty_size)) {
+ c->dirty_size += jeb->wasted_size;
+ c->wasted_size -= jeb->wasted_size;
+ jeb->dirty_size += jeb->wasted_size;
+ jeb->wasted_size = 0;
+ if (VERYDIRTY(c, jeb->dirty_size)) {
+ D1(printk(KERN_DEBUG "Adding full erase block at 0x%08x to very_dirty_list (free 0x%08x, dirty 0x%08x, used 0x%08x\n",
+ jeb->offset, jeb->free_size, jeb->dirty_size, jeb->used_size));
+ list_add_tail(&jeb->list, &c->very_dirty_list);
+ } else {
+ D1(printk(KERN_DEBUG "Adding full erase block at 0x%08x to dirty_list (free 0x%08x, dirty 0x%08x, used 0x%08x\n",
+ jeb->offset, jeb->free_size, jeb->dirty_size, jeb->used_size));
+ list_add_tail(&jeb->list, &c->dirty_list);
+ }
+ } else {
+ D1(printk(KERN_DEBUG "Adding full erase block at 0x%08x to clean_list (free 0x%08x, dirty 0x%08x, used 0x%08x\n",
+ jeb->offset, jeb->free_size, jeb->dirty_size, jeb->used_size));
+ list_add_tail(&jeb->list, &c->clean_list);
+ }
+ c->nextblock = NULL;
+
+}
+
+/* Select a new jeb for nextblock */
+
+static int jffs2_find_nextblock(struct jffs2_sb_info *c)
+{
+ struct list_head *next;
+
+ /* Take the next block off the 'free' list */
+
+ if (list_empty(&c->free_list)) {
+
+ if (!c->nr_erasing_blocks &&
+ !list_empty(&c->erasable_list)) {
+ struct jffs2_eraseblock *ejeb;
+
+ ejeb = list_entry(c->erasable_list.next, struct jffs2_eraseblock, list);
+ list_del(&ejeb->list);
+ list_add_tail(&ejeb->list, &c->erase_pending_list);
+ c->nr_erasing_blocks++;
+ jffs2_erase_pending_trigger(c);
+ D1(printk(KERN_DEBUG "jffs2_find_nextblock: Triggering erase of erasable block at 0x%08x\n",
+ ejeb->offset));
+ }
+
+ if (!c->nr_erasing_blocks &&
+ !list_empty(&c->erasable_pending_wbuf_list)) {
+ D1(printk(KERN_DEBUG "jffs2_find_nextblock: Flushing write buffer\n"));
+ /* c->nextblock is NULL, no update to c->nextblock allowed */
spin_unlock(&c->erase_completion_lock);
- D1(printk(KERN_DEBUG "jffs2_do_reserve_space: Flushing write buffer\n"));
jffs2_flush_wbuf_pad(c);
spin_lock(&c->erase_completion_lock);
- jeb = c->nextblock;
- goto restart;
+ /* Have another go. It'll be on the erasable_list now */
+ return -EAGAIN;
}
- c->wasted_size += jeb->free_size;
- c->free_size -= jeb->free_size;
- jeb->wasted_size += jeb->free_size;
- jeb->free_size = 0;
-
- /* Check, if we have a dirty block now, or if it was dirty already */
- if (ISDIRTY (jeb->wasted_size + jeb->dirty_size)) {
- c->dirty_size += jeb->wasted_size;
- c->wasted_size -= jeb->wasted_size;
- jeb->dirty_size += jeb->wasted_size;
- jeb->wasted_size = 0;
- if (VERYDIRTY(c, jeb->dirty_size)) {
- D1(printk(KERN_DEBUG "Adding full erase block at 0x%08x to very_dirty_list (free 0x%08x, dirty 0x%08x, used 0x%08x\n",
- jeb->offset, jeb->free_size, jeb->dirty_size, jeb->used_size));
- list_add_tail(&jeb->list, &c->very_dirty_list);
- } else {
- D1(printk(KERN_DEBUG "Adding full erase block at 0x%08x to dirty_list (free 0x%08x, dirty 0x%08x, used 0x%08x\n",
- jeb->offset, jeb->free_size, jeb->dirty_size, jeb->used_size));
- list_add_tail(&jeb->list, &c->dirty_list);
- }
- } else {
- D1(printk(KERN_DEBUG "Adding full erase block at 0x%08x to clean_list (free 0x%08x, dirty 0x%08x, used 0x%08x\n",
- jeb->offset, jeb->free_size, jeb->dirty_size, jeb->used_size));
- list_add_tail(&jeb->list, &c->clean_list);
+
+ if (!c->nr_erasing_blocks) {
+ /* Ouch. We're in GC, or we wouldn't have got here.
+ And there's no space left. At all. */
+ printk(KERN_CRIT "Argh. No free space left for GC. nr_erasing_blocks is %d. nr_free_blocks is %d. (erasableempty: %s, erasingempty: %s, erasependingempty: %s)\n",
+ c->nr_erasing_blocks, c->nr_free_blocks, list_empty(&c->erasable_list)?"yes":"no",
+ list_empty(&c->erasing_list)?"yes":"no", list_empty(&c->erase_pending_list)?"yes":"no");
+ return -ENOSPC;
}
- c->nextblock = jeb = NULL;
+
+ spin_unlock(&c->erase_completion_lock);
+ /* Don't wait for it; just erase one right now */
+ jffs2_erase_pending_blocks(c, 1);
+ spin_lock(&c->erase_completion_lock);
+
+ /* An erase may have failed, decreasing the
+ amount of free space available. So we must
+ restart from the beginning */
+ return -EAGAIN;
}
-
- if (!jeb) {
- struct list_head *next;
- /* Take the next block off the 'free' list */
- if (list_empty(&c->free_list)) {
+ next = c->free_list.next;
+ list_del(next);
+ c->nextblock = list_entry(next, struct jffs2_eraseblock, list);
+ c->nr_free_blocks--;
- if (!c->nr_erasing_blocks &&
- !list_empty(&c->erasable_list)) {
- struct jffs2_eraseblock *ejeb;
+ jffs2_sum_reset_collected(c->summary); /* reset collected summary */
- ejeb = list_entry(c->erasable_list.next, struct jffs2_eraseblock, list);
- list_del(&ejeb->list);
- list_add_tail(&ejeb->list, &c->erase_pending_list);
- c->nr_erasing_blocks++;
- jffs2_erase_pending_trigger(c);
- D1(printk(KERN_DEBUG "jffs2_do_reserve_space: Triggering erase of erasable block at 0x%08x\n",
- ejeb->offset));
+ D1(printk(KERN_DEBUG "jffs2_find_nextblock(): new nextblock = 0x%08x\n", c->nextblock->offset));
+
+ return 0;
+}
+
+/* Called with alloc sem _and_ erase_completion_lock */
+static int jffs2_do_reserve_space(struct jffs2_sb_info *c, uint32_t minsize, uint32_t *ofs, uint32_t *len, uint32_t sumsize)
+{
+ struct jffs2_eraseblock *jeb = c->nextblock;
+ uint32_t reserved_size; /* for summary information at the end of the jeb */
+ int ret;
+
+ restart:
+ reserved_size = 0;
+
+ if (jffs2_sum_active() && (sumsize != JFFS2_SUMMARY_NOSUM_SIZE)) {
+ /* NOSUM_SIZE means not to generate summary */
+
+ if (jeb) {
+ reserved_size = PAD(sumsize + c->summary->sum_size + JFFS2_SUMMARY_FRAME_SIZE);
+ dbg_summary("minsize=%d , jeb->free=%d ,"
+ "summary->size=%d , sumsize=%d\n",
+ minsize, jeb->free_size,
+ c->summary->sum_size, sumsize);
+ }
+
+ /* Is there enough space for writing out the current node, or we have to
+ write out summary information now, close this jeb and select new nextblock? */
+ if (jeb && (PAD(minsize) + PAD(c->summary->sum_size + sumsize +
+ JFFS2_SUMMARY_FRAME_SIZE) > jeb->free_size)) {
+
+ /* Has summary been disabled for this jeb? */
+ if (jffs2_sum_is_disabled(c->summary)) {
+ sumsize = JFFS2_SUMMARY_NOSUM_SIZE;
+ goto restart;
}
- if (!c->nr_erasing_blocks &&
- !list_empty(&c->erasable_pending_wbuf_list)) {
- D1(printk(KERN_DEBUG "jffs2_do_reserve_space: Flushing write buffer\n"));
- /* c->nextblock is NULL, no update to c->nextblock allowed */
+ /* Writing out the collected summary information */
+ dbg_summary("generating summary for 0x%08x.\n", jeb->offset);
+ ret = jffs2_sum_write_sumnode(c);
+
+ if (ret)
+ return ret;
+
+ if (jffs2_sum_is_disabled(c->summary)) {
+ /* jffs2_write_sumnode() couldn't write out the summary information
+ diabling summary for this jeb and free the collected information
+ */
+ sumsize = JFFS2_SUMMARY_NOSUM_SIZE;
+ goto restart;
+ }
+
+ jffs2_close_nextblock(c, jeb);
+ jeb = NULL;
+ /* keep always valid value in reserved_size */
+ reserved_size = PAD(sumsize + c->summary->sum_size + JFFS2_SUMMARY_FRAME_SIZE);
+ }
+ } else {
+ if (jeb && minsize > jeb->free_size) {
+ /* Skip the end of this block and file it as having some dirty space */
+ /* If there's a pending write to it, flush now */
+
+ if (jffs2_wbuf_dirty(c)) {
spin_unlock(&c->erase_completion_lock);
+ D1(printk(KERN_DEBUG "jffs2_do_reserve_space: Flushing write buffer\n"));
jffs2_flush_wbuf_pad(c);
spin_lock(&c->erase_completion_lock);
- /* Have another go. It'll be on the erasable_list now */
- return -EAGAIN;
+ jeb = c->nextblock;
+ goto restart;
}
- if (!c->nr_erasing_blocks) {
- /* Ouch. We're in GC, or we wouldn't have got here.
- And there's no space left. At all. */
- printk(KERN_CRIT "Argh. No free space left for GC. nr_erasing_blocks is %d. nr_free_blocks is %d. (erasableempty: %s, erasingempty: %s, erasependingempty: %s)\n",
- c->nr_erasing_blocks, c->nr_free_blocks, list_empty(&c->erasable_list)?"yes":"no",
- list_empty(&c->erasing_list)?"yes":"no", list_empty(&c->erase_pending_list)?"yes":"no");
- return -ENOSPC;
- }
-
- spin_unlock(&c->erase_completion_lock);
- /* Don't wait for it; just erase one right now */
- jffs2_erase_pending_blocks(c, 1);
- spin_lock(&c->erase_completion_lock);
+ c->wasted_size += jeb->free_size;
+ c->free_size -= jeb->free_size;
+ jeb->wasted_size += jeb->free_size;
+ jeb->free_size = 0;
- /* An erase may have failed, decreasing the
- amount of free space available. So we must
- restart from the beginning */
- return -EAGAIN;
+ jffs2_close_nextblock(c, jeb);
+ jeb = NULL;
}
+ }
+
+ if (!jeb) {
- next = c->free_list.next;
- list_del(next);
- c->nextblock = jeb = list_entry(next, struct jffs2_eraseblock, list);
- c->nr_free_blocks--;
+ ret = jffs2_find_nextblock(c);
+ if (ret)
+ return ret;
+
+ jeb = c->nextblock;
if (jeb->free_size != c->sector_size - c->cleanmarker_size) {
printk(KERN_WARNING "Eep. Block 0x%08x taken from free_list had free_size of 0x%08x!!\n", jeb->offset, jeb->free_size);
@@ -266,13 +350,13 @@ static int jffs2_do_reserve_space(struct jffs2_sb_info *c, uint32_t minsize, ui
/* OK, jeb (==c->nextblock) is now pointing at a block which definitely has
enough space */
*ofs = jeb->offset + (c->sector_size - jeb->free_size);
- *len = jeb->free_size;
+ *len = jeb->free_size - reserved_size;
if (c->cleanmarker_size && jeb->used_size == c->cleanmarker_size &&
!jeb->first_node->next_in_ino) {
- /* Only node in it beforehand was a CLEANMARKER node (we think).
+ /* Only node in it beforehand was a CLEANMARKER node (we think).
So mark it obsolete now that there's going to be another node
- in the block. This will reduce used_size to zero but We've
+ in the block. This will reduce used_size to zero but We've
already set c->nextblock so that jffs2_mark_node_obsolete()
won't try to refile it to the dirty_list.
*/
@@ -292,12 +376,12 @@ static int jffs2_do_reserve_space(struct jffs2_sb_info *c, uint32_t minsize, ui
* @len: length of this physical node
* @dirty: dirty flag for new node
*
- * Should only be used to report nodes for which space has been allocated
+ * Should only be used to report nodes for which space has been allocated
* by jffs2_reserve_space.
*
* Must be called with the alloc_sem held.
*/
-
+
int jffs2_add_physical_node_ref(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *new)
{
struct jffs2_eraseblock *jeb;
@@ -349,8 +433,8 @@ int jffs2_add_physical_node_ref(struct jffs2_sb_info *c, struct jffs2_raw_node_r
list_add_tail(&jeb->list, &c->clean_list);
c->nextblock = NULL;
}
- ACCT_SANITY_CHECK(c,jeb);
- D1(ACCT_PARANOIA_CHECK(jeb));
+ jffs2_dbg_acct_sanity_check_nolock(c,jeb);
+ jffs2_dbg_acct_paranoia_check_nolock(c, jeb);
spin_unlock(&c->erase_completion_lock);
@@ -404,8 +488,8 @@ void jffs2_mark_node_obsolete(struct jffs2_sb_info *c, struct jffs2_raw_node_ref
if (jffs2_can_mark_obsolete(c) && !jffs2_is_readonly(c) &&
!(c->flags & (JFFS2_SB_FLAG_SCANNING | JFFS2_SB_FLAG_BUILDING))) {
- /* Hm. This may confuse static lock analysis. If any of the above
- three conditions is false, we're going to return from this
+ /* Hm. This may confuse static lock analysis. If any of the above
+ three conditions is false, we're going to return from this
function without actually obliterating any nodes or freeing
any jffs2_raw_node_refs. So we don't need to stop erases from
happening, or protect against people holding an obsolete
@@ -430,7 +514,7 @@ void jffs2_mark_node_obsolete(struct jffs2_sb_info *c, struct jffs2_raw_node_ref
ref_totlen(c, jeb, ref), blocknr, ref->flash_offset, jeb->used_size);
BUG();
})
- D1(printk(KERN_DEBUG "Obsoleting node at 0x%08x of len %x: ", ref_offset(ref), ref_totlen(c, jeb, ref)));
+ D1(printk(KERN_DEBUG "Obsoleting node at 0x%08x of len %#x: ", ref_offset(ref), ref_totlen(c, jeb, ref)));
jeb->used_size -= ref_totlen(c, jeb, ref);
c->used_size -= ref_totlen(c, jeb, ref);
}
@@ -462,18 +546,17 @@ void jffs2_mark_node_obsolete(struct jffs2_sb_info *c, struct jffs2_raw_node_ref
D1(printk(KERN_DEBUG "Wasting\n"));
addedsize = 0;
jeb->wasted_size += ref_totlen(c, jeb, ref);
- c->wasted_size += ref_totlen(c, jeb, ref);
+ c->wasted_size += ref_totlen(c, jeb, ref);
}
ref->flash_offset = ref_offset(ref) | REF_OBSOLETE;
-
- ACCT_SANITY_CHECK(c, jeb);
- D1(ACCT_PARANOIA_CHECK(jeb));
+ jffs2_dbg_acct_sanity_check_nolock(c, jeb);
+ jffs2_dbg_acct_paranoia_check_nolock(c, jeb);
if (c->flags & JFFS2_SB_FLAG_SCANNING) {
/* Flash scanning is in progress. Don't muck about with the block
lists because they're not ready yet, and don't actually
- obliterate nodes that look obsolete. If they weren't
+ obliterate nodes that look obsolete. If they weren't
marked obsolete on the flash at the time they _became_
obsolete, there was probably a reason for that. */
spin_unlock(&c->erase_completion_lock);
@@ -507,7 +590,7 @@ void jffs2_mark_node_obsolete(struct jffs2_sb_info *c, struct jffs2_raw_node_ref
immediately reused, and we spread the load a bit. */
D1(printk(KERN_DEBUG "...and adding to erasable_list\n"));
list_add_tail(&jeb->list, &c->erasable_list);
- }
+ }
}
D1(printk(KERN_DEBUG "Done OK\n"));
} else if (jeb == c->gcblock) {
@@ -525,8 +608,8 @@ void jffs2_mark_node_obsolete(struct jffs2_sb_info *c, struct jffs2_raw_node_ref
list_add_tail(&jeb->list, &c->very_dirty_list);
} else {
D1(printk(KERN_DEBUG "Eraseblock at 0x%08x not moved anywhere. (free 0x%08x, dirty 0x%08x, used 0x%08x)\n",
- jeb->offset, jeb->free_size, jeb->dirty_size, jeb->used_size));
- }
+ jeb->offset, jeb->free_size, jeb->dirty_size, jeb->used_size));
+ }
spin_unlock(&c->erase_completion_lock);
@@ -573,11 +656,11 @@ void jffs2_mark_node_obsolete(struct jffs2_sb_info *c, struct jffs2_raw_node_ref
/* Nodes which have been marked obsolete no longer need to be
associated with any inode. Remove them from the per-inode list.
-
- Note we can't do this for NAND at the moment because we need
+
+ Note we can't do this for NAND at the moment because we need
obsolete dirent nodes to stay on the lists, because of the
horridness in jffs2_garbage_collect_deletion_dirent(). Also
- because we delete the inocache, and on NAND we need that to
+ because we delete the inocache, and on NAND we need that to
stay around until all the nodes are actually erased, in order
to stop us from giving the same inode number to another newly
created inode. */
@@ -606,7 +689,7 @@ void jffs2_mark_node_obsolete(struct jffs2_sb_info *c, struct jffs2_raw_node_ref
if (ref->next_phys && ref_obsolete(ref->next_phys) &&
!ref->next_phys->next_in_ino) {
struct jffs2_raw_node_ref *n = ref->next_phys;
-
+
spin_lock(&c->erase_completion_lock);
ref->__totlen += n->__totlen;
@@ -620,7 +703,7 @@ void jffs2_mark_node_obsolete(struct jffs2_sb_info *c, struct jffs2_raw_node_ref
jffs2_free_raw_node_ref(n);
}
-
+
/* Also merge with the previous node in the list, if there is one
and that one is obsolete */
if (ref != jeb->first_node ) {
@@ -630,7 +713,7 @@ void jffs2_mark_node_obsolete(struct jffs2_sb_info *c, struct jffs2_raw_node_ref
while (p->next_phys != ref)
p = p->next_phys;
-
+
if (ref_obsolete(p) && !ref->next_in_ino) {
p->__totlen += ref->__totlen;
if (jeb->last_node == ref) {
@@ -649,164 +732,6 @@ void jffs2_mark_node_obsolete(struct jffs2_sb_info *c, struct jffs2_raw_node_ref
up(&c->erase_free_sem);
}
-#if CONFIG_JFFS2_FS_DEBUG >= 2
-void jffs2_dump_block_lists(struct jffs2_sb_info *c)
-{
-
-
- printk(KERN_DEBUG "jffs2_dump_block_lists:\n");
- printk(KERN_DEBUG "flash_size: %08x\n", c->flash_size);
- printk(KERN_DEBUG "used_size: %08x\n", c->used_size);
- printk(KERN_DEBUG "dirty_size: %08x\n", c->dirty_size);
- printk(KERN_DEBUG "wasted_size: %08x\n", c->wasted_size);
- printk(KERN_DEBUG "unchecked_size: %08x\n", c->unchecked_size);
- printk(KERN_DEBUG "free_size: %08x\n", c->free_size);
- printk(KERN_DEBUG "erasing_size: %08x\n", c->erasing_size);
- printk(KERN_DEBUG "bad_size: %08x\n", c->bad_size);
- printk(KERN_DEBUG "sector_size: %08x\n", c->sector_size);
- printk(KERN_DEBUG "jffs2_reserved_blocks size: %08x\n",c->sector_size * c->resv_blocks_write);
-
- if (c->nextblock) {
- printk(KERN_DEBUG "nextblock: %08x (used %08x, dirty %08x, wasted %08x, unchecked %08x, free %08x)\n",
- c->nextblock->offset, c->nextblock->used_size, c->nextblock->dirty_size, c->nextblock->wasted_size, c->nextblock->unchecked_size, c->nextblock->free_size);
- } else {
- printk(KERN_DEBUG "nextblock: NULL\n");
- }
- if (c->gcblock) {
- printk(KERN_DEBUG "gcblock: %08x (used %08x, dirty %08x, wasted %08x, unchecked %08x, free %08x)\n",
- c->gcblock->offset, c->gcblock->used_size, c->gcblock->dirty_size, c->gcblock->wasted_size, c->gcblock->unchecked_size, c->gcblock->free_size);
- } else {
- printk(KERN_DEBUG "gcblock: NULL\n");
- }
- if (list_empty(&c->clean_list)) {
- printk(KERN_DEBUG "clean_list: empty\n");
- } else {
- struct list_head *this;
- int numblocks = 0;
- uint32_t dirty = 0;
-
- list_for_each(this, &c->clean_list) {
- struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
- numblocks ++;
- dirty += jeb->wasted_size;
- printk(KERN_DEBUG "clean_list: %08x (used %08x, dirty %08x, wasted %08x, unchecked %08x, free %08x)\n", jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size, jeb->unchecked_size, jeb->free_size);
- }
- printk (KERN_DEBUG "Contains %d blocks with total wasted size %u, average wasted size: %u\n", numblocks, dirty, dirty / numblocks);
- }
- if (list_empty(&c->very_dirty_list)) {
- printk(KERN_DEBUG "very_dirty_list: empty\n");
- } else {
- struct list_head *this;
- int numblocks = 0;
- uint32_t dirty = 0;
-
- list_for_each(this, &c->very_dirty_list) {
- struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
- numblocks ++;
- dirty += jeb->dirty_size;
- printk(KERN_DEBUG "very_dirty_list: %08x (used %08x, dirty %08x, wasted %08x, unchecked %08x, free %08x)\n",
- jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size, jeb->unchecked_size, jeb->free_size);
- }
- printk (KERN_DEBUG "Contains %d blocks with total dirty size %u, average dirty size: %u\n",
- numblocks, dirty, dirty / numblocks);
- }
- if (list_empty(&c->dirty_list)) {
- printk(KERN_DEBUG "dirty_list: empty\n");
- } else {
- struct list_head *this;
- int numblocks = 0;
- uint32_t dirty = 0;
-
- list_for_each(this, &c->dirty_list) {
- struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
- numblocks ++;
- dirty += jeb->dirty_size;
- printk(KERN_DEBUG "dirty_list: %08x (used %08x, dirty %08x, wasted %08x, unchecked %08x, free %08x)\n",
- jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size, jeb->unchecked_size, jeb->free_size);
- }
- printk (KERN_DEBUG "Contains %d blocks with total dirty size %u, average dirty size: %u\n",
- numblocks, dirty, dirty / numblocks);
- }
- if (list_empty(&c->erasable_list)) {
- printk(KERN_DEBUG "erasable_list: empty\n");
- } else {
- struct list_head *this;
-
- list_for_each(this, &c->erasable_list) {
- struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
- printk(KERN_DEBUG "erasable_list: %08x (used %08x, dirty %08x, wasted %08x, unchecked %08x, free %08x)\n",
- jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size, jeb->unchecked_size, jeb->free_size);
- }
- }
- if (list_empty(&c->erasing_list)) {
- printk(KERN_DEBUG "erasing_list: empty\n");
- } else {
- struct list_head *this;
-
- list_for_each(this, &c->erasing_list) {
- struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
- printk(KERN_DEBUG "erasing_list: %08x (used %08x, dirty %08x, wasted %08x, unchecked %08x, free %08x)\n",
- jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size, jeb->unchecked_size, jeb->free_size);
- }
- }
- if (list_empty(&c->erase_pending_list)) {
- printk(KERN_DEBUG "erase_pending_list: empty\n");
- } else {
- struct list_head *this;
-
- list_for_each(this, &c->erase_pending_list) {
- struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
- printk(KERN_DEBUG "erase_pending_list: %08x (used %08x, dirty %08x, wasted %08x, unchecked %08x, free %08x)\n",
- jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size, jeb->unchecked_size, jeb->free_size);
- }
- }
- if (list_empty(&c->erasable_pending_wbuf_list)) {
- printk(KERN_DEBUG "erasable_pending_wbuf_list: empty\n");
- } else {
- struct list_head *this;
-
- list_for_each(this, &c->erasable_pending_wbuf_list) {
- struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
- printk(KERN_DEBUG "erasable_pending_wbuf_list: %08x (used %08x, dirty %08x, wasted %08x, unchecked %08x, free %08x)\n",
- jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size, jeb->unchecked_size, jeb->free_size);
- }
- }
- if (list_empty(&c->free_list)) {
- printk(KERN_DEBUG "free_list: empty\n");
- } else {
- struct list_head *this;
-
- list_for_each(this, &c->free_list) {
- struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
- printk(KERN_DEBUG "free_list: %08x (used %08x, dirty %08x, wasted %08x, unchecked %08x, free %08x)\n",
- jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size, jeb->unchecked_size, jeb->free_size);
- }
- }
- if (list_empty(&c->bad_list)) {
- printk(KERN_DEBUG "bad_list: empty\n");
- } else {
- struct list_head *this;
-
- list_for_each(this, &c->bad_list) {
- struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
- printk(KERN_DEBUG "bad_list: %08x (used %08x, dirty %08x, wasted %08x, unchecked %08x, free %08x)\n",
- jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size, jeb->unchecked_size, jeb->free_size);
- }
- }
- if (list_empty(&c->bad_used_list)) {
- printk(KERN_DEBUG "bad_used_list: empty\n");
- } else {
- struct list_head *this;
-
- list_for_each(this, &c->bad_used_list) {
- struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
- printk(KERN_DEBUG "bad_used_list: %08x (used %08x, dirty %08x, wasted %08x, unchecked %08x, free %08x)\n",
- jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size, jeb->unchecked_size, jeb->free_size);
- }
- }
-}
-#endif /* CONFIG_JFFS2_FS_DEBUG */
-
int jffs2_thread_should_wake(struct jffs2_sb_info *c)
{
int ret = 0;
@@ -828,11 +753,11 @@ int jffs2_thread_should_wake(struct jffs2_sb_info *c)
*/
dirty = c->dirty_size + c->erasing_size - c->nr_erasing_blocks * c->sector_size;
- if (c->nr_free_blocks + c->nr_erasing_blocks < c->resv_blocks_gctrigger &&
- (dirty > c->nospc_dirty_size))
+ if (c->nr_free_blocks + c->nr_erasing_blocks < c->resv_blocks_gctrigger &&
+ (dirty > c->nospc_dirty_size))
ret = 1;
- D1(printk(KERN_DEBUG "jffs2_thread_should_wake(): nr_free_blocks %d, nr_erasing_blocks %d, dirty_size 0x%x: %s\n",
+ D1(printk(KERN_DEBUG "jffs2_thread_should_wake(): nr_free_blocks %d, nr_erasing_blocks %d, dirty_size 0x%x: %s\n",
c->nr_free_blocks, c->nr_erasing_blocks, c->dirty_size, ret?"yes":"no"));
return ret;
diff --git a/fs/jffs2/os-linux.h b/fs/jffs2/os-linux.h
index d900c8929b09..59e7a393200c 100644
--- a/fs/jffs2/os-linux.h
+++ b/fs/jffs2/os-linux.h
@@ -7,7 +7,7 @@
*
* For licensing information, see the file 'LICENCE' in this directory.
*
- * $Id: os-linux.h,v 1.58 2005/07/12 02:34:35 tpoynor Exp $
+ * $Id: os-linux.h,v 1.64 2005/09/30 13:59:13 dedekind Exp $
*
*/
@@ -57,6 +57,7 @@ static inline void jffs2_init_inode_info(struct jffs2_inode_info *f)
f->fragtree = RB_ROOT;
f->metadata = NULL;
f->dents = NULL;
+ f->target = NULL;
f->flags = 0;
f->usercompr = 0;
}
@@ -64,17 +65,24 @@ static inline void jffs2_init_inode_info(struct jffs2_inode_info *f)
#define jffs2_is_readonly(c) (OFNI_BS_2SFFJ(c)->s_flags & MS_RDONLY)
+#define SECTOR_ADDR(x) ( (((unsigned long)(x) / c->sector_size) * c->sector_size) )
#ifndef CONFIG_JFFS2_FS_WRITEBUFFER
-#define SECTOR_ADDR(x) ( ((unsigned long)(x) & ~(c->sector_size-1)) )
+
+
+#ifdef CONFIG_JFFS2_SUMMARY
+#define jffs2_can_mark_obsolete(c) (0)
+#else
#define jffs2_can_mark_obsolete(c) (1)
+#endif
+
#define jffs2_is_writebuffered(c) (0)
#define jffs2_cleanmarker_oob(c) (0)
#define jffs2_write_nand_cleanmarker(c,jeb) (-EIO)
-#define jffs2_flash_write(c, ofs, len, retlen, buf) ((c)->mtd->write((c)->mtd, ofs, len, retlen, buf))
+#define jffs2_flash_write(c, ofs, len, retlen, buf) jffs2_flash_direct_write(c, ofs, len, retlen, buf)
#define jffs2_flash_read(c, ofs, len, retlen, buf) ((c)->mtd->read((c)->mtd, ofs, len, retlen, buf))
-#define jffs2_flush_wbuf_pad(c) ({ (void)(c), 0; })
-#define jffs2_flush_wbuf_gc(c, i) ({ (void)(c), (void) i, 0; })
+#define jffs2_flush_wbuf_pad(c) ({ do{} while(0); (void)(c), 0; })
+#define jffs2_flush_wbuf_gc(c, i) ({ do{} while(0); (void)(c), (void) i, 0; })
#define jffs2_write_nand_badblock(c,jeb,bad_offset) (1)
#define jffs2_nand_flash_setup(c) (0)
#define jffs2_nand_flash_cleanup(c) do {} while(0)
@@ -84,16 +92,26 @@ static inline void jffs2_init_inode_info(struct jffs2_inode_info *f)
#define jffs2_wbuf_process NULL
#define jffs2_nor_ecc(c) (0)
#define jffs2_dataflash(c) (0)
+#define jffs2_nor_wbuf_flash(c) (0)
#define jffs2_nor_ecc_flash_setup(c) (0)
#define jffs2_nor_ecc_flash_cleanup(c) do {} while (0)
#define jffs2_dataflash_setup(c) (0)
#define jffs2_dataflash_cleanup(c) do {} while (0)
+#define jffs2_nor_wbuf_flash_setup(c) (0)
+#define jffs2_nor_wbuf_flash_cleanup(c) do {} while (0)
#else /* NAND and/or ECC'd NOR support present */
#define jffs2_is_writebuffered(c) (c->wbuf != NULL)
-#define SECTOR_ADDR(x) ( ((unsigned long)(x) / (unsigned long)(c->sector_size)) * c->sector_size )
-#define jffs2_can_mark_obsolete(c) ((c->mtd->type == MTD_NORFLASH && !(c->mtd->flags & MTD_ECC)) || c->mtd->type == MTD_RAM)
+
+#ifdef CONFIG_JFFS2_SUMMARY
+#define jffs2_can_mark_obsolete(c) (0)
+#else
+#define jffs2_can_mark_obsolete(c) \
+ ((c->mtd->type == MTD_NORFLASH && !(c->mtd->flags & (MTD_ECC|MTD_PROGRAM_REGIONS))) || \
+ c->mtd->type == MTD_RAM)
+#endif
+
#define jffs2_cleanmarker_oob(c) (c->mtd->type == MTD_NANDFLASH)
#define jffs2_flash_write_oob(c, ofs, len, retlen, buf) ((c)->mtd->write_oob((c)->mtd, ofs, len, retlen, buf))
@@ -123,6 +141,10 @@ void jffs2_nor_ecc_flash_cleanup(struct jffs2_sb_info *c);
int jffs2_dataflash_setup(struct jffs2_sb_info *c);
void jffs2_dataflash_cleanup(struct jffs2_sb_info *c);
+#define jffs2_nor_wbuf_flash(c) (c->mtd->type == MTD_NORFLASH && (c->mtd->flags & MTD_PROGRAM_REGIONS))
+int jffs2_nor_wbuf_flash_setup(struct jffs2_sb_info *c);
+void jffs2_nor_wbuf_flash_cleanup(struct jffs2_sb_info *c);
+
#endif /* WRITEBUFFER */
/* erase.c */
@@ -169,20 +191,21 @@ void jffs2_gc_release_inode(struct jffs2_sb_info *c,
struct jffs2_inode_info *jffs2_gc_fetch_inode(struct jffs2_sb_info *c,
int inum, int nlink);
-unsigned char *jffs2_gc_fetch_page(struct jffs2_sb_info *c,
- struct jffs2_inode_info *f,
+unsigned char *jffs2_gc_fetch_page(struct jffs2_sb_info *c,
+ struct jffs2_inode_info *f,
unsigned long offset,
unsigned long *priv);
void jffs2_gc_release_page(struct jffs2_sb_info *c,
unsigned char *pg,
unsigned long *priv);
void jffs2_flash_cleanup(struct jffs2_sb_info *c);
-
+
/* writev.c */
-int jffs2_flash_direct_writev(struct jffs2_sb_info *c, const struct kvec *vecs,
+int jffs2_flash_direct_writev(struct jffs2_sb_info *c, const struct kvec *vecs,
unsigned long count, loff_t to, size_t *retlen);
-
+int jffs2_flash_direct_write(struct jffs2_sb_info *c, loff_t ofs, size_t len,
+ size_t *retlen, const u_char *buf);
#endif /* __JFFS2_OS_LINUX_H__ */
diff --git a/fs/jffs2/read.c b/fs/jffs2/read.c
index c7f9068907cf..f3b86da833ba 100644
--- a/fs/jffs2/read.c
+++ b/fs/jffs2/read.c
@@ -7,7 +7,7 @@
*
* For licensing information, see the file 'LICENCE' in this directory.
*
- * $Id: read.c,v 1.39 2005/03/01 10:34:03 dedekind Exp $
+ * $Id: read.c,v 1.42 2005/11/07 11:14:41 gleixner Exp $
*
*/
@@ -43,7 +43,7 @@ int jffs2_read_dnode(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
}
if (readlen != sizeof(*ri)) {
jffs2_free_raw_inode(ri);
- printk(KERN_WARNING "Short read from 0x%08x: wanted 0x%zx bytes, got 0x%zx\n",
+ printk(KERN_WARNING "Short read from 0x%08x: wanted 0x%zx bytes, got 0x%zx\n",
ref_offset(fd->raw), sizeof(*ri), readlen);
return -EIO;
}
@@ -61,7 +61,7 @@ int jffs2_read_dnode(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
}
/* There was a bug where we wrote hole nodes out with csize/dsize
swapped. Deal with it */
- if (ri->compr == JFFS2_COMPR_ZERO && !je32_to_cpu(ri->dsize) &&
+ if (ri->compr == JFFS2_COMPR_ZERO && !je32_to_cpu(ri->dsize) &&
je32_to_cpu(ri->csize)) {
ri->dsize = ri->csize;
ri->csize = cpu_to_je32(0);
@@ -74,7 +74,7 @@ int jffs2_read_dnode(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
goto out_ri;
});
-
+
if (ri->compr == JFFS2_COMPR_ZERO) {
memset(buf, 0, len);
goto out_ri;
@@ -82,8 +82,8 @@ int jffs2_read_dnode(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
/* Cases:
Reading whole node and it's uncompressed - read directly to buffer provided, check CRC.
- Reading whole node and it's compressed - read into comprbuf, check CRC and decompress to buffer provided
- Reading partial node and it's uncompressed - read into readbuf, check CRC, and copy
+ Reading whole node and it's compressed - read into comprbuf, check CRC and decompress to buffer provided
+ Reading partial node and it's uncompressed - read into readbuf, check CRC, and copy
Reading partial node and it's compressed - read into readbuf, check checksum, decompress to decomprbuf and copy
*/
if (ri->compr == JFFS2_COMPR_NONE && len == je32_to_cpu(ri->dsize)) {
@@ -129,7 +129,7 @@ int jffs2_read_dnode(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
D2(printk(KERN_DEBUG "Data CRC matches calculated CRC %08x\n", crc));
if (ri->compr != JFFS2_COMPR_NONE) {
D2(printk(KERN_DEBUG "Decompress %d bytes from %p to %d bytes at %p\n",
- je32_to_cpu(ri->csize), readbuf, je32_to_cpu(ri->dsize), decomprbuf));
+ je32_to_cpu(ri->csize), readbuf, je32_to_cpu(ri->dsize), decomprbuf));
ret = jffs2_decompress(c, f, ri->compr | (ri->usercompr << 8), readbuf, decomprbuf, je32_to_cpu(ri->csize), je32_to_cpu(ri->dsize));
if (ret) {
printk(KERN_WARNING "Error: jffs2_decompress returned %d\n", ret);
@@ -174,7 +174,6 @@ int jffs2_read_inode_range(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
if (frag) {
D1(printk(KERN_NOTICE "Eep. Hole in ino #%u fraglist. frag->ofs = 0x%08x, offset = 0x%08x\n", f->inocache->ino, frag->ofs, offset));
holesize = min(holesize, frag->ofs - offset);
- D2(jffs2_print_frag_list(f));
}
D1(printk(KERN_DEBUG "Filling non-frag hole from %d-%d\n", offset, offset+holesize));
memset(buf, 0, holesize);
@@ -192,7 +191,7 @@ int jffs2_read_inode_range(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
} else {
uint32_t readlen;
uint32_t fragofs; /* offset within the frag to start reading */
-
+
fragofs = offset - frag->ofs;
readlen = min(frag->size - fragofs, end - offset);
D1(printk(KERN_DEBUG "Reading %d-%d from node at 0x%08x (%d)\n",
diff --git a/fs/jffs2/readinode.c b/fs/jffs2/readinode.c
index 5b2a83599d73..5f0652df5d47 100644
--- a/fs/jffs2/readinode.c
+++ b/fs/jffs2/readinode.c
@@ -7,11 +7,12 @@
*
* For licensing information, see the file 'LICENCE' in this directory.
*
- * $Id: readinode.c,v 1.125 2005/07/10 13:13:55 dedekind Exp $
+ * $Id: readinode.c,v 1.143 2005/11/07 11:14:41 gleixner Exp $
*
*/
#include <linux/kernel.h>
+#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/fs.h>
#include <linux/crc32.h>
@@ -20,502 +21,631 @@
#include <linux/compiler.h>
#include "nodelist.h"
-static int jffs2_add_frag_to_fragtree(struct jffs2_sb_info *c, struct rb_root *list, struct jffs2_node_frag *newfrag);
-
-#if CONFIG_JFFS2_FS_DEBUG >= 2
-static void jffs2_print_fragtree(struct rb_root *list, int permitbug)
+/*
+ * Put a new tmp_dnode_info into the temporaty RB-tree, keeping the list in
+ * order of increasing version.
+ */
+static void jffs2_add_tn_to_tree(struct jffs2_tmp_dnode_info *tn, struct rb_root *list)
{
- struct jffs2_node_frag *this = frag_first(list);
- uint32_t lastofs = 0;
- int buggy = 0;
-
- while(this) {
- if (this->node)
- printk(KERN_DEBUG "frag %04x-%04x: 0x%08x(%d) on flash (*%p). left (%p), right (%p), parent (%p)\n",
- this->ofs, this->ofs+this->size, ref_offset(this->node->raw), ref_flags(this->node->raw),
- this, frag_left(this), frag_right(this), frag_parent(this));
- else
- printk(KERN_DEBUG "frag %04x-%04x: hole (*%p). left (%p} right (%p), parent (%p)\n", this->ofs,
- this->ofs+this->size, this, frag_left(this), frag_right(this), frag_parent(this));
- if (this->ofs != lastofs)
- buggy = 1;
- lastofs = this->ofs+this->size;
- this = frag_next(this);
+ struct rb_node **p = &list->rb_node;
+ struct rb_node * parent = NULL;
+ struct jffs2_tmp_dnode_info *this;
+
+ while (*p) {
+ parent = *p;
+ this = rb_entry(parent, struct jffs2_tmp_dnode_info, rb);
+
+ /* There may actually be a collision here, but it doesn't
+ actually matter. As long as the two nodes with the same
+ version are together, it's all fine. */
+ if (tn->version > this->version)
+ p = &(*p)->rb_left;
+ else
+ p = &(*p)->rb_right;
}
- if (buggy && !permitbug) {
- printk(KERN_CRIT "Frag tree got a hole in it\n");
- BUG();
+
+ rb_link_node(&tn->rb, parent, p);
+ rb_insert_color(&tn->rb, list);
+}
+
+static void jffs2_free_tmp_dnode_info_list(struct rb_root *list)
+{
+ struct rb_node *this;
+ struct jffs2_tmp_dnode_info *tn;
+
+ this = list->rb_node;
+
+ /* Now at bottom of tree */
+ while (this) {
+ if (this->rb_left)
+ this = this->rb_left;
+ else if (this->rb_right)
+ this = this->rb_right;
+ else {
+ tn = rb_entry(this, struct jffs2_tmp_dnode_info, rb);
+ jffs2_free_full_dnode(tn->fn);
+ jffs2_free_tmp_dnode_info(tn);
+
+ this = this->rb_parent;
+ if (!this)
+ break;
+
+ if (this->rb_left == &tn->rb)
+ this->rb_left = NULL;
+ else if (this->rb_right == &tn->rb)
+ this->rb_right = NULL;
+ else BUG();
+ }
}
+ list->rb_node = NULL;
}
-void jffs2_print_frag_list(struct jffs2_inode_info *f)
+static void jffs2_free_full_dirent_list(struct jffs2_full_dirent *fd)
{
- jffs2_print_fragtree(&f->fragtree, 0);
+ struct jffs2_full_dirent *next;
- if (f->metadata) {
- printk(KERN_DEBUG "metadata at 0x%08x\n", ref_offset(f->metadata->raw));
+ while (fd) {
+ next = fd->next;
+ jffs2_free_full_dirent(fd);
+ fd = next;
}
}
-#endif
-#if CONFIG_JFFS2_FS_DEBUG >= 1
-static int jffs2_sanitycheck_fragtree(struct jffs2_inode_info *f)
+/* Returns first valid node after 'ref'. May return 'ref' */
+static struct jffs2_raw_node_ref *jffs2_first_valid_node(struct jffs2_raw_node_ref *ref)
{
- struct jffs2_node_frag *frag;
- int bitched = 0;
-
- for (frag = frag_first(&f->fragtree); frag; frag = frag_next(frag)) {
+ while (ref && ref->next_in_ino) {
+ if (!ref_obsolete(ref))
+ return ref;
+ dbg_noderef("node at 0x%08x is obsoleted. Ignoring.\n", ref_offset(ref));
+ ref = ref->next_in_ino;
+ }
+ return NULL;
+}
- struct jffs2_full_dnode *fn = frag->node;
- if (!fn || !fn->raw)
- continue;
+/*
+ * Helper function for jffs2_get_inode_nodes().
+ * It is called every time an directory entry node is found.
+ *
+ * Returns: 0 on succes;
+ * 1 if the node should be marked obsolete;
+ * negative error code on failure.
+ */
+static inline int read_direntry(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *ref,
+ struct jffs2_raw_dirent *rd, uint32_t read, struct jffs2_full_dirent **fdp,
+ uint32_t *latest_mctime, uint32_t *mctime_ver)
+{
+ struct jffs2_full_dirent *fd;
+
+ /* The direntry nodes are checked during the flash scanning */
+ BUG_ON(ref_flags(ref) == REF_UNCHECKED);
+ /* Obsoleted. This cannot happen, surely? dwmw2 20020308 */
+ BUG_ON(ref_obsolete(ref));
+
+ /* Sanity check */
+ if (unlikely(PAD((rd->nsize + sizeof(*rd))) != PAD(je32_to_cpu(rd->totlen)))) {
+ JFFS2_ERROR("illegal nsize in node at %#08x: nsize %#02x, totlen %#04x\n",
+ ref_offset(ref), rd->nsize, je32_to_cpu(rd->totlen));
+ return 1;
+ }
- if (ref_flags(fn->raw) == REF_PRISTINE) {
+ fd = jffs2_alloc_full_dirent(rd->nsize + 1);
+ if (unlikely(!fd))
+ return -ENOMEM;
- if (fn->frags > 1) {
- printk(KERN_WARNING "REF_PRISTINE node at 0x%08x had %d frags. Tell dwmw2\n", ref_offset(fn->raw), fn->frags);
- bitched = 1;
- }
- /* A hole node which isn't multi-page should be garbage-collected
- and merged anyway, so we just check for the frag size here,
- rather than mucking around with actually reading the node
- and checking the compression type, which is the real way
- to tell a hole node. */
- if (frag->ofs & (PAGE_CACHE_SIZE-1) && frag_prev(frag) && frag_prev(frag)->size < PAGE_CACHE_SIZE && frag_prev(frag)->node) {
- printk(KERN_WARNING "REF_PRISTINE node at 0x%08x had a previous non-hole frag in the same page. Tell dwmw2\n",
- ref_offset(fn->raw));
- bitched = 1;
- }
+ fd->raw = ref;
+ fd->version = je32_to_cpu(rd->version);
+ fd->ino = je32_to_cpu(rd->ino);
+ fd->type = rd->type;
- if ((frag->ofs+frag->size) & (PAGE_CACHE_SIZE-1) && frag_next(frag) && frag_next(frag)->size < PAGE_CACHE_SIZE && frag_next(frag)->node) {
- printk(KERN_WARNING "REF_PRISTINE node at 0x%08x (%08x-%08x) had a following non-hole frag in the same page. Tell dwmw2\n",
- ref_offset(fn->raw), frag->ofs, frag->ofs+frag->size);
- bitched = 1;
- }
- }
+ /* Pick out the mctime of the latest dirent */
+ if(fd->version > *mctime_ver && je32_to_cpu(rd->mctime)) {
+ *mctime_ver = fd->version;
+ *latest_mctime = je32_to_cpu(rd->mctime);
}
-
- if (bitched) {
- struct jffs2_node_frag *thisfrag;
-
- printk(KERN_WARNING "Inode is #%u\n", f->inocache->ino);
- thisfrag = frag_first(&f->fragtree);
- while (thisfrag) {
- if (!thisfrag->node) {
- printk("Frag @0x%x-0x%x; node-less hole\n",
- thisfrag->ofs, thisfrag->size + thisfrag->ofs);
- } else if (!thisfrag->node->raw) {
- printk("Frag @0x%x-0x%x; raw-less hole\n",
- thisfrag->ofs, thisfrag->size + thisfrag->ofs);
- } else {
- printk("Frag @0x%x-0x%x; raw at 0x%08x(%d) (0x%x-0x%x)\n",
- thisfrag->ofs, thisfrag->size + thisfrag->ofs,
- ref_offset(thisfrag->node->raw), ref_flags(thisfrag->node->raw),
- thisfrag->node->ofs, thisfrag->node->ofs+thisfrag->node->size);
- }
- thisfrag = frag_next(thisfrag);
- }
- }
- return bitched;
-}
-#endif /* D1 */
-static void jffs2_obsolete_node_frag(struct jffs2_sb_info *c, struct jffs2_node_frag *this)
-{
- if (this->node) {
- this->node->frags--;
- if (!this->node->frags) {
- /* The node has no valid frags left. It's totally obsoleted */
- D2(printk(KERN_DEBUG "Marking old node @0x%08x (0x%04x-0x%04x) obsolete\n",
- ref_offset(this->node->raw), this->node->ofs, this->node->ofs+this->node->size));
- jffs2_mark_node_obsolete(c, this->node->raw);
- jffs2_free_full_dnode(this->node);
- } else {
- D2(printk(KERN_DEBUG "Marking old node @0x%08x (0x%04x-0x%04x) REF_NORMAL. frags is %d\n",
- ref_offset(this->node->raw), this->node->ofs, this->node->ofs+this->node->size,
- this->node->frags));
- mark_ref_normal(this->node->raw);
+ /*
+ * Copy as much of the name as possible from the raw
+ * dirent we've already read from the flash.
+ */
+ if (read > sizeof(*rd))
+ memcpy(&fd->name[0], &rd->name[0],
+ min_t(uint32_t, rd->nsize, (read - sizeof(*rd)) ));
+
+ /* Do we need to copy any more of the name directly from the flash? */
+ if (rd->nsize + sizeof(*rd) > read) {
+ /* FIXME: point() */
+ int err;
+ int already = read - sizeof(*rd);
+
+ err = jffs2_flash_read(c, (ref_offset(ref)) + read,
+ rd->nsize - already, &read, &fd->name[already]);
+ if (unlikely(read != rd->nsize - already) && likely(!err))
+ return -EIO;
+
+ if (unlikely(err)) {
+ JFFS2_ERROR("read remainder of name: error %d\n", err);
+ jffs2_free_full_dirent(fd);
+ return -EIO;
}
-
}
- jffs2_free_node_frag(this);
+
+ fd->nhash = full_name_hash(fd->name, rd->nsize);
+ fd->next = NULL;
+ fd->name[rd->nsize] = '\0';
+
+ /*
+ * Wheee. We now have a complete jffs2_full_dirent structure, with
+ * the name in it and everything. Link it into the list
+ */
+ jffs2_add_fd_to_list(c, fd, fdp);
+
+ return 0;
}
-/* Given an inode, probably with existing list of fragments, add the new node
- * to the fragment list.
+/*
+ * Helper function for jffs2_get_inode_nodes().
+ * It is called every time an inode node is found.
+ *
+ * Returns: 0 on succes;
+ * 1 if the node should be marked obsolete;
+ * negative error code on failure.
*/
-int jffs2_add_full_dnode_to_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, struct jffs2_full_dnode *fn)
+static inline int read_dnode(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *ref,
+ struct jffs2_raw_inode *rd, struct rb_root *tnp, int rdlen,
+ uint32_t *latest_mctime, uint32_t *mctime_ver)
{
- int ret;
- struct jffs2_node_frag *newfrag;
-
- D1(printk(KERN_DEBUG "jffs2_add_full_dnode_to_inode(ino #%u, f %p, fn %p)\n", f->inocache->ino, f, fn));
+ struct jffs2_tmp_dnode_info *tn;
+ uint32_t len, csize;
+ int ret = 1;
- if (unlikely(!fn->size))
- return 0;
+ /* Obsoleted. This cannot happen, surely? dwmw2 20020308 */
+ BUG_ON(ref_obsolete(ref));
- newfrag = jffs2_alloc_node_frag();
- if (unlikely(!newfrag))
+ tn = jffs2_alloc_tmp_dnode_info();
+ if (!tn) {
+ JFFS2_ERROR("failed to allocate tn (%d bytes).\n", sizeof(*tn));
return -ENOMEM;
+ }
- D2(printk(KERN_DEBUG "adding node %04x-%04x @0x%08x on flash, newfrag *%p\n",
- fn->ofs, fn->ofs+fn->size, ref_offset(fn->raw), newfrag));
-
- newfrag->ofs = fn->ofs;
- newfrag->size = fn->size;
- newfrag->node = fn;
- newfrag->node->frags = 1;
+ tn->partial_crc = 0;
+ csize = je32_to_cpu(rd->csize);
- ret = jffs2_add_frag_to_fragtree(c, &f->fragtree, newfrag);
- if (ret)
- return ret;
+ /* If we've never checked the CRCs on this node, check them now */
+ if (ref_flags(ref) == REF_UNCHECKED) {
+ uint32_t crc;
- /* If we now share a page with other nodes, mark either previous
- or next node REF_NORMAL, as appropriate. */
- if (newfrag->ofs & (PAGE_CACHE_SIZE-1)) {
- struct jffs2_node_frag *prev = frag_prev(newfrag);
+ crc = crc32(0, rd, sizeof(*rd) - 8);
+ if (unlikely(crc != je32_to_cpu(rd->node_crc))) {
+ JFFS2_NOTICE("header CRC failed on node at %#08x: read %#08x, calculated %#08x\n",
+ ref_offset(ref), je32_to_cpu(rd->node_crc), crc);
+ goto free_out;
+ }
- mark_ref_normal(fn->raw);
- /* If we don't start at zero there's _always_ a previous */
- if (prev->node)
- mark_ref_normal(prev->node->raw);
- }
+ /* Sanity checks */
+ if (unlikely(je32_to_cpu(rd->offset) > je32_to_cpu(rd->isize)) ||
+ unlikely(PAD(je32_to_cpu(rd->csize) + sizeof(*rd)) != PAD(je32_to_cpu(rd->totlen)))) {
+ JFFS2_WARNING("inode node header CRC is corrupted at %#08x\n", ref_offset(ref));
+ jffs2_dbg_dump_node(c, ref_offset(ref));
+ goto free_out;
+ }
- if ((newfrag->ofs+newfrag->size) & (PAGE_CACHE_SIZE-1)) {
- struct jffs2_node_frag *next = frag_next(newfrag);
-
- if (next) {
- mark_ref_normal(fn->raw);
- if (next->node)
- mark_ref_normal(next->node->raw);
+ if (jffs2_is_writebuffered(c) && csize != 0) {
+ /* At this point we are supposed to check the data CRC
+ * of our unchecked node. But thus far, we do not
+ * know whether the node is valid or obsolete. To
+ * figure this out, we need to walk all the nodes of
+ * the inode and build the inode fragtree. We don't
+ * want to spend time checking data of nodes which may
+ * later be found to be obsolete. So we put off the full
+ * data CRC checking until we have read all the inode
+ * nodes and have started building the fragtree.
+ *
+ * The fragtree is being built starting with nodes
+ * having the highest version number, so we'll be able
+ * to detect whether a node is valid (i.e., it is not
+ * overlapped by a node with higher version) or not.
+ * And we'll be able to check only those nodes, which
+ * are not obsolete.
+ *
+ * Of course, this optimization only makes sense in case
+ * of NAND flashes (or other flashes whith
+ * !jffs2_can_mark_obsolete()), since on NOR flashes
+ * nodes are marked obsolete physically.
+ *
+ * Since NAND flashes (or other flashes with
+ * jffs2_is_writebuffered(c)) are anyway read by
+ * fractions of c->wbuf_pagesize, and we have just read
+ * the node header, it is likely that the starting part
+ * of the node data is also read when we read the
+ * header. So we don't mind to check the CRC of the
+ * starting part of the data of the node now, and check
+ * the second part later (in jffs2_check_node_data()).
+ * Of course, we will not need to re-read and re-check
+ * the NAND page which we have just read. This is why we
+ * read the whole NAND page at jffs2_get_inode_nodes(),
+ * while we needed only the node header.
+ */
+ unsigned char *buf;
+
+ /* 'buf' will point to the start of data */
+ buf = (unsigned char *)rd + sizeof(*rd);
+ /* len will be the read data length */
+ len = min_t(uint32_t, rdlen - sizeof(*rd), csize);
+ tn->partial_crc = crc32(0, buf, len);
+
+ dbg_readinode("Calculates CRC (%#08x) for %d bytes, csize %d\n", tn->partial_crc, len, csize);
+
+ /* If we actually calculated the whole data CRC
+ * and it is wrong, drop the node. */
+ if (len >= csize && unlikely(tn->partial_crc != je32_to_cpu(rd->data_crc))) {
+ JFFS2_NOTICE("wrong data CRC in data node at 0x%08x: read %#08x, calculated %#08x.\n",
+ ref_offset(ref), tn->partial_crc, je32_to_cpu(rd->data_crc));
+ goto free_out;
+ }
+
+ } else if (csize == 0) {
+ /*
+ * We checked the header CRC. If the node has no data, adjust
+ * the space accounting now. For other nodes this will be done
+ * later either when the node is marked obsolete or when its
+ * data is checked.
+ */
+ struct jffs2_eraseblock *jeb;
+
+ dbg_readinode("the node has no data.\n");
+ jeb = &c->blocks[ref->flash_offset / c->sector_size];
+ len = ref_totlen(c, jeb, ref);
+
+ spin_lock(&c->erase_completion_lock);
+ jeb->used_size += len;
+ jeb->unchecked_size -= len;
+ c->used_size += len;
+ c->unchecked_size -= len;
+ ref->flash_offset = ref_offset(ref) | REF_NORMAL;
+ spin_unlock(&c->erase_completion_lock);
}
}
- D2(if (jffs2_sanitycheck_fragtree(f)) {
- printk(KERN_WARNING "Just added node %04x-%04x @0x%08x on flash, newfrag *%p\n",
- fn->ofs, fn->ofs+fn->size, ref_offset(fn->raw), newfrag);
- return 0;
- })
- D2(jffs2_print_frag_list(f));
+
+ tn->fn = jffs2_alloc_full_dnode();
+ if (!tn->fn) {
+ JFFS2_ERROR("alloc fn failed\n");
+ ret = -ENOMEM;
+ goto free_out;
+ }
+
+ tn->version = je32_to_cpu(rd->version);
+ tn->fn->ofs = je32_to_cpu(rd->offset);
+ tn->data_crc = je32_to_cpu(rd->data_crc);
+ tn->csize = csize;
+ tn->fn->raw = ref;
+
+ /* There was a bug where we wrote hole nodes out with
+ csize/dsize swapped. Deal with it */
+ if (rd->compr == JFFS2_COMPR_ZERO && !je32_to_cpu(rd->dsize) && csize)
+ tn->fn->size = csize;
+ else // normal case...
+ tn->fn->size = je32_to_cpu(rd->dsize);
+
+ dbg_readinode("dnode @%08x: ver %u, offset %#04x, dsize %#04x, csize %#04x\n",
+ ref_offset(ref), je32_to_cpu(rd->version), je32_to_cpu(rd->offset), je32_to_cpu(rd->dsize), csize);
+
+ jffs2_add_tn_to_tree(tn, tnp);
+
return 0;
+
+free_out:
+ jffs2_free_tmp_dnode_info(tn);
+ return ret;
}
-/* Doesn't set inode->i_size */
-static int jffs2_add_frag_to_fragtree(struct jffs2_sb_info *c, struct rb_root *list, struct jffs2_node_frag *newfrag)
+/*
+ * Helper function for jffs2_get_inode_nodes().
+ * It is called every time an unknown node is found.
+ *
+ * Returns: 0 on succes;
+ * 1 if the node should be marked obsolete;
+ * negative error code on failure.
+ */
+static inline int read_unknown(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *ref, struct jffs2_unknown_node *un)
{
- struct jffs2_node_frag *this;
- uint32_t lastend;
+ /* We don't mark unknown nodes as REF_UNCHECKED */
+ BUG_ON(ref_flags(ref) == REF_UNCHECKED);
- /* Skip all the nodes which are completed before this one starts */
- this = jffs2_lookup_node_frag(list, newfrag->node->ofs);
+ un->nodetype = cpu_to_je16(JFFS2_NODE_ACCURATE | je16_to_cpu(un->nodetype));
- if (this) {
- D2(printk(KERN_DEBUG "j_a_f_d_t_f: Lookup gave frag 0x%04x-0x%04x; phys 0x%08x (*%p)\n",
- this->ofs, this->ofs+this->size, this->node?(ref_offset(this->node->raw)):0xffffffff, this));
- lastend = this->ofs + this->size;
+ if (crc32(0, un, sizeof(struct jffs2_unknown_node) - 4) != je32_to_cpu(un->hdr_crc)) {
+ /* Hmmm. This should have been caught at scan time. */
+ JFFS2_NOTICE("node header CRC failed at %#08x. But it must have been OK earlier.\n", ref_offset(ref));
+ jffs2_dbg_dump_node(c, ref_offset(ref));
+ return 1;
} else {
- D2(printk(KERN_DEBUG "j_a_f_d_t_f: Lookup gave no frag\n"));
- lastend = 0;
- }
-
- /* See if we ran off the end of the list */
- if (lastend <= newfrag->ofs) {
- /* We did */
-
- /* Check if 'this' node was on the same page as the new node.
- If so, both 'this' and the new node get marked REF_NORMAL so
- the GC can take a look.
- */
- if (lastend && (lastend-1) >> PAGE_CACHE_SHIFT == newfrag->ofs >> PAGE_CACHE_SHIFT) {
- if (this->node)
- mark_ref_normal(this->node->raw);
- mark_ref_normal(newfrag->node->raw);
- }
+ switch(je16_to_cpu(un->nodetype) & JFFS2_COMPAT_MASK) {
- if (lastend < newfrag->node->ofs) {
- /* ... and we need to put a hole in before the new node */
- struct jffs2_node_frag *holefrag = jffs2_alloc_node_frag();
- if (!holefrag) {
- jffs2_free_node_frag(newfrag);
- return -ENOMEM;
- }
- holefrag->ofs = lastend;
- holefrag->size = newfrag->node->ofs - lastend;
- holefrag->node = NULL;
- if (this) {
- /* By definition, the 'this' node has no right-hand child,
- because there are no frags with offset greater than it.
- So that's where we want to put the hole */
- D2(printk(KERN_DEBUG "Adding hole frag (%p) on right of node at (%p)\n", holefrag, this));
- rb_link_node(&holefrag->rb, &this->rb, &this->rb.rb_right);
- } else {
- D2(printk(KERN_DEBUG "Adding hole frag (%p) at root of tree\n", holefrag));
- rb_link_node(&holefrag->rb, NULL, &list->rb_node);
- }
- rb_insert_color(&holefrag->rb, list);
- this = holefrag;
- }
- if (this) {
- /* By definition, the 'this' node has no right-hand child,
- because there are no frags with offset greater than it.
- So that's where we want to put the hole */
- D2(printk(KERN_DEBUG "Adding new frag (%p) on right of node at (%p)\n", newfrag, this));
- rb_link_node(&newfrag->rb, &this->rb, &this->rb.rb_right);
- } else {
- D2(printk(KERN_DEBUG "Adding new frag (%p) at root of tree\n", newfrag));
- rb_link_node(&newfrag->rb, NULL, &list->rb_node);
+ case JFFS2_FEATURE_INCOMPAT:
+ JFFS2_ERROR("unknown INCOMPAT nodetype %#04X at %#08x\n",
+ je16_to_cpu(un->nodetype), ref_offset(ref));
+ /* EEP */
+ BUG();
+ break;
+
+ case JFFS2_FEATURE_ROCOMPAT:
+ JFFS2_ERROR("unknown ROCOMPAT nodetype %#04X at %#08x\n",
+ je16_to_cpu(un->nodetype), ref_offset(ref));
+ BUG_ON(!(c->flags & JFFS2_SB_FLAG_RO));
+ break;
+
+ case JFFS2_FEATURE_RWCOMPAT_COPY:
+ JFFS2_NOTICE("unknown RWCOMPAT_COPY nodetype %#04X at %#08x\n",
+ je16_to_cpu(un->nodetype), ref_offset(ref));
+ break;
+
+ case JFFS2_FEATURE_RWCOMPAT_DELETE:
+ JFFS2_NOTICE("unknown RWCOMPAT_DELETE nodetype %#04X at %#08x\n",
+ je16_to_cpu(un->nodetype), ref_offset(ref));
+ return 1;
}
- rb_insert_color(&newfrag->rb, list);
- return 0;
}
- D2(printk(KERN_DEBUG "j_a_f_d_t_f: dealing with frag 0x%04x-0x%04x; phys 0x%08x (*%p)\n",
- this->ofs, this->ofs+this->size, this->node?(ref_offset(this->node->raw)):0xffffffff, this));
+ return 0;
+}
- /* OK. 'this' is pointing at the first frag that newfrag->ofs at least partially obsoletes,
- * - i.e. newfrag->ofs < this->ofs+this->size && newfrag->ofs >= this->ofs
- */
- if (newfrag->ofs > this->ofs) {
- /* This node isn't completely obsoleted. The start of it remains valid */
-
- /* Mark the new node and the partially covered node REF_NORMAL -- let
- the GC take a look at them */
- mark_ref_normal(newfrag->node->raw);
- if (this->node)
- mark_ref_normal(this->node->raw);
-
- if (this->ofs + this->size > newfrag->ofs + newfrag->size) {
- /* The new node splits 'this' frag into two */
- struct jffs2_node_frag *newfrag2 = jffs2_alloc_node_frag();
- if (!newfrag2) {
- jffs2_free_node_frag(newfrag);
- return -ENOMEM;
- }
- D2(printk(KERN_DEBUG "split old frag 0x%04x-0x%04x -->", this->ofs, this->ofs+this->size);
- if (this->node)
- printk("phys 0x%08x\n", ref_offset(this->node->raw));
- else
- printk("hole\n");
- )
-
- /* New second frag pointing to this's node */
- newfrag2->ofs = newfrag->ofs + newfrag->size;
- newfrag2->size = (this->ofs+this->size) - newfrag2->ofs;
- newfrag2->node = this->node;
- if (this->node)
- this->node->frags++;
-
- /* Adjust size of original 'this' */
- this->size = newfrag->ofs - this->ofs;
-
- /* Now, we know there's no node with offset
- greater than this->ofs but smaller than
- newfrag2->ofs or newfrag->ofs, for obvious
- reasons. So we can do a tree insert from
- 'this' to insert newfrag, and a tree insert
- from newfrag to insert newfrag2. */
- jffs2_fragtree_insert(newfrag, this);
- rb_insert_color(&newfrag->rb, list);
-
- jffs2_fragtree_insert(newfrag2, newfrag);
- rb_insert_color(&newfrag2->rb, list);
-
- return 0;
- }
- /* New node just reduces 'this' frag in size, doesn't split it */
- this->size = newfrag->ofs - this->ofs;
+/*
+ * Helper function for jffs2_get_inode_nodes().
+ * The function detects whether more data should be read and reads it if yes.
+ *
+ * Returns: 0 on succes;
+ * negative error code on failure.
+ */
+static int read_more(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *ref,
+ int right_size, int *rdlen, unsigned char *buf, unsigned char *bufstart)
+{
+ int right_len, err, len;
+ size_t retlen;
+ uint32_t offs;
- /* Again, we know it lives down here in the tree */
- jffs2_fragtree_insert(newfrag, this);
- rb_insert_color(&newfrag->rb, list);
- } else {
- /* New frag starts at the same point as 'this' used to. Replace
- it in the tree without doing a delete and insertion */
- D2(printk(KERN_DEBUG "Inserting newfrag (*%p),%d-%d in before 'this' (*%p),%d-%d\n",
- newfrag, newfrag->ofs, newfrag->ofs+newfrag->size,
- this, this->ofs, this->ofs+this->size));
-
- rb_replace_node(&this->rb, &newfrag->rb, list);
-
- if (newfrag->ofs + newfrag->size >= this->ofs+this->size) {
- D2(printk(KERN_DEBUG "Obsoleting node frag %p (%x-%x)\n", this, this->ofs, this->ofs+this->size));
- jffs2_obsolete_node_frag(c, this);
- } else {
- this->ofs += newfrag->size;
- this->size -= newfrag->size;
+ if (jffs2_is_writebuffered(c)) {
+ right_len = c->wbuf_pagesize - (bufstart - buf);
+ if (right_size + (int)(bufstart - buf) > c->wbuf_pagesize)
+ right_len += c->wbuf_pagesize;
+ } else
+ right_len = right_size;
- jffs2_fragtree_insert(this, newfrag);
- rb_insert_color(&this->rb, list);
- return 0;
- }
+ if (*rdlen == right_len)
+ return 0;
+
+ /* We need to read more data */
+ offs = ref_offset(ref) + *rdlen;
+ if (jffs2_is_writebuffered(c)) {
+ bufstart = buf + c->wbuf_pagesize;
+ len = c->wbuf_pagesize;
+ } else {
+ bufstart = buf + *rdlen;
+ len = right_size - *rdlen;
}
- /* OK, now we have newfrag added in the correct place in the tree, but
- frag_next(newfrag) may be a fragment which is overlapped by it
- */
- while ((this = frag_next(newfrag)) && newfrag->ofs + newfrag->size >= this->ofs + this->size) {
- /* 'this' frag is obsoleted completely. */
- D2(printk(KERN_DEBUG "Obsoleting node frag %p (%x-%x) and removing from tree\n", this, this->ofs, this->ofs+this->size));
- rb_erase(&this->rb, list);
- jffs2_obsolete_node_frag(c, this);
+
+ dbg_readinode("read more %d bytes\n", len);
+
+ err = jffs2_flash_read(c, offs, len, &retlen, bufstart);
+ if (err) {
+ JFFS2_ERROR("can not read %d bytes from 0x%08x, "
+ "error code: %d.\n", len, offs, err);
+ return err;
}
- /* Now we're pointing at the first frag which isn't totally obsoleted by
- the new frag */
- if (!this || newfrag->ofs + newfrag->size == this->ofs) {
- return 0;
+ if (retlen < len) {
+ JFFS2_ERROR("short read at %#08x: %d instead of %d.\n",
+ offs, retlen, len);
+ return -EIO;
}
- /* Still some overlap but we don't need to move it in the tree */
- this->size = (this->ofs + this->size) - (newfrag->ofs + newfrag->size);
- this->ofs = newfrag->ofs + newfrag->size;
- /* And mark them REF_NORMAL so the GC takes a look at them */
- if (this->node)
- mark_ref_normal(this->node->raw);
- mark_ref_normal(newfrag->node->raw);
+ *rdlen = right_len;
return 0;
}
-void jffs2_truncate_fraglist (struct jffs2_sb_info *c, struct rb_root *list, uint32_t size)
+/* Get tmp_dnode_info and full_dirent for all non-obsolete nodes associated
+ with this ino, returning the former in order of version */
+static int jffs2_get_inode_nodes(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
+ struct rb_root *tnp, struct jffs2_full_dirent **fdp,
+ uint32_t *highest_version, uint32_t *latest_mctime,
+ uint32_t *mctime_ver)
{
- struct jffs2_node_frag *frag = jffs2_lookup_node_frag(list, size);
+ struct jffs2_raw_node_ref *ref, *valid_ref;
+ struct rb_root ret_tn = RB_ROOT;
+ struct jffs2_full_dirent *ret_fd = NULL;
+ unsigned char *buf = NULL;
+ union jffs2_node_union *node;
+ size_t retlen;
+ int len, err;
+
+ *mctime_ver = 0;
+
+ dbg_readinode("ino #%u\n", f->inocache->ino);
+
+ if (jffs2_is_writebuffered(c)) {
+ /*
+ * If we have the write buffer, we assume the minimal I/O unit
+ * is c->wbuf_pagesize. We implement some optimizations which in
+ * this case and we need a temporary buffer of size =
+ * 2*c->wbuf_pagesize bytes (see comments in read_dnode()).
+ * Basically, we want to read not only the node header, but the
+ * whole wbuf (NAND page in case of NAND) or 2, if the node
+ * header overlaps the border between the 2 wbufs.
+ */
+ len = 2*c->wbuf_pagesize;
+ } else {
+ /*
+ * When there is no write buffer, the size of the temporary
+ * buffer is the size of the larges node header.
+ */
+ len = sizeof(union jffs2_node_union);
+ }
- D1(printk(KERN_DEBUG "Truncating fraglist to 0x%08x bytes\n", size));
+ /* FIXME: in case of NOR and available ->point() this
+ * needs to be fixed. */
+ buf = kmalloc(len, GFP_KERNEL);
+ if (!buf)
+ return -ENOMEM;
- /* We know frag->ofs <= size. That's what lookup does for us */
- if (frag && frag->ofs != size) {
- if (frag->ofs+frag->size >= size) {
- D1(printk(KERN_DEBUG "Truncating frag 0x%08x-0x%08x\n", frag->ofs, frag->ofs+frag->size));
- frag->size = size - frag->ofs;
+ spin_lock(&c->erase_completion_lock);
+ valid_ref = jffs2_first_valid_node(f->inocache->nodes);
+ if (!valid_ref && f->inocache->ino != 1)
+ JFFS2_WARNING("Eep. No valid nodes for ino #%u.\n", f->inocache->ino);
+ while (valid_ref) {
+ unsigned char *bufstart;
+
+ /* We can hold a pointer to a non-obsolete node without the spinlock,
+ but _obsolete_ nodes may disappear at any time, if the block
+ they're in gets erased. So if we mark 'ref' obsolete while we're
+ not holding the lock, it can go away immediately. For that reason,
+ we find the next valid node first, before processing 'ref'.
+ */
+ ref = valid_ref;
+ valid_ref = jffs2_first_valid_node(ref->next_in_ino);
+ spin_unlock(&c->erase_completion_lock);
+
+ cond_resched();
+
+ /*
+ * At this point we don't know the type of the node we're going
+ * to read, so we do not know the size of its header. In order
+ * to minimize the amount of flash IO we assume the node has
+ * size = JFFS2_MIN_NODE_HEADER.
+ */
+ if (jffs2_is_writebuffered(c)) {
+ /*
+ * We treat 'buf' as 2 adjacent wbufs. We want to
+ * adjust bufstart such as it points to the
+ * beginning of the node within this wbuf.
+ */
+ bufstart = buf + (ref_offset(ref) % c->wbuf_pagesize);
+ /* We will read either one wbuf or 2 wbufs. */
+ len = c->wbuf_pagesize - (bufstart - buf);
+ if (JFFS2_MIN_NODE_HEADER + (int)(bufstart - buf) > c->wbuf_pagesize) {
+ /* The header spans the border of the first wbuf */
+ len += c->wbuf_pagesize;
+ }
+ } else {
+ bufstart = buf;
+ len = JFFS2_MIN_NODE_HEADER;
}
- frag = frag_next(frag);
- }
- while (frag && frag->ofs >= size) {
- struct jffs2_node_frag *next = frag_next(frag);
- D1(printk(KERN_DEBUG "Removing frag 0x%08x-0x%08x\n", frag->ofs, frag->ofs+frag->size));
- frag_erase(frag, list);
- jffs2_obsolete_node_frag(c, frag);
- frag = next;
- }
-}
+ dbg_readinode("read %d bytes at %#08x(%d).\n", len, ref_offset(ref), ref_flags(ref));
-/* Scan the list of all nodes present for this ino, build map of versions, etc. */
+ /* FIXME: point() */
+ err = jffs2_flash_read(c, ref_offset(ref), len,
+ &retlen, bufstart);
+ if (err) {
+ JFFS2_ERROR("can not read %d bytes from 0x%08x, " "error code: %d.\n", len, ref_offset(ref), err);
+ goto free_out;
+ }
-static int jffs2_do_read_inode_internal(struct jffs2_sb_info *c,
- struct jffs2_inode_info *f,
- struct jffs2_raw_inode *latest_node);
+ if (retlen < len) {
+ JFFS2_ERROR("short read at %#08x: %d instead of %d.\n", ref_offset(ref), retlen, len);
+ err = -EIO;
+ goto free_out;
+ }
-int jffs2_do_read_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
- uint32_t ino, struct jffs2_raw_inode *latest_node)
-{
- D2(printk(KERN_DEBUG "jffs2_do_read_inode(): getting inocache\n"));
+ node = (union jffs2_node_union *)bufstart;
- retry_inocache:
- spin_lock(&c->inocache_lock);
- f->inocache = jffs2_get_ino_cache(c, ino);
+ switch (je16_to_cpu(node->u.nodetype)) {
- D2(printk(KERN_DEBUG "jffs2_do_read_inode(): Got inocache at %p\n", f->inocache));
+ case JFFS2_NODETYPE_DIRENT:
+
+ if (JFFS2_MIN_NODE_HEADER < sizeof(struct jffs2_raw_dirent)) {
+ err = read_more(c, ref, sizeof(struct jffs2_raw_dirent), &len, buf, bufstart);
+ if (unlikely(err))
+ goto free_out;
+ }
+
+ err = read_direntry(c, ref, &node->d, retlen, &ret_fd, latest_mctime, mctime_ver);
+ if (err == 1) {
+ jffs2_mark_node_obsolete(c, ref);
+ break;
+ } else if (unlikely(err))
+ goto free_out;
+
+ if (je32_to_cpu(node->d.version) > *highest_version)
+ *highest_version = je32_to_cpu(node->d.version);
- if (f->inocache) {
- /* Check its state. We may need to wait before we can use it */
- switch(f->inocache->state) {
- case INO_STATE_UNCHECKED:
- case INO_STATE_CHECKEDABSENT:
- f->inocache->state = INO_STATE_READING;
break;
-
- case INO_STATE_CHECKING:
- case INO_STATE_GC:
- /* If it's in either of these states, we need
- to wait for whoever's got it to finish and
- put it back. */
- D1(printk(KERN_DEBUG "jffs2_get_ino_cache_read waiting for ino #%u in state %d\n",
- ino, f->inocache->state));
- sleep_on_spinunlock(&c->inocache_wq, &c->inocache_lock);
- goto retry_inocache;
- case INO_STATE_READING:
- case INO_STATE_PRESENT:
- /* Eep. This should never happen. It can
- happen if Linux calls read_inode() again
- before clear_inode() has finished though. */
- printk(KERN_WARNING "Eep. Trying to read_inode #%u when it's already in state %d!\n", ino, f->inocache->state);
- /* Fail. That's probably better than allowing it to succeed */
- f->inocache = NULL;
+ case JFFS2_NODETYPE_INODE:
+
+ if (JFFS2_MIN_NODE_HEADER < sizeof(struct jffs2_raw_inode)) {
+ err = read_more(c, ref, sizeof(struct jffs2_raw_inode), &len, buf, bufstart);
+ if (unlikely(err))
+ goto free_out;
+ }
+
+ err = read_dnode(c, ref, &node->i, &ret_tn, len, latest_mctime, mctime_ver);
+ if (err == 1) {
+ jffs2_mark_node_obsolete(c, ref);
+ break;
+ } else if (unlikely(err))
+ goto free_out;
+
+ if (je32_to_cpu(node->i.version) > *highest_version)
+ *highest_version = je32_to_cpu(node->i.version);
+
break;
default:
- BUG();
- }
- }
- spin_unlock(&c->inocache_lock);
+ if (JFFS2_MIN_NODE_HEADER < sizeof(struct jffs2_unknown_node)) {
+ err = read_more(c, ref, sizeof(struct jffs2_unknown_node), &len, buf, bufstart);
+ if (unlikely(err))
+ goto free_out;
+ }
+
+ err = read_unknown(c, ref, &node->u);
+ if (err == 1) {
+ jffs2_mark_node_obsolete(c, ref);
+ break;
+ } else if (unlikely(err))
+ goto free_out;
- if (!f->inocache && ino == 1) {
- /* Special case - no root inode on medium */
- f->inocache = jffs2_alloc_inode_cache();
- if (!f->inocache) {
- printk(KERN_CRIT "jffs2_do_read_inode(): Cannot allocate inocache for root inode\n");
- return -ENOMEM;
}
- D1(printk(KERN_DEBUG "jffs2_do_read_inode(): Creating inocache for root inode\n"));
- memset(f->inocache, 0, sizeof(struct jffs2_inode_cache));
- f->inocache->ino = f->inocache->nlink = 1;
- f->inocache->nodes = (struct jffs2_raw_node_ref *)f->inocache;
- f->inocache->state = INO_STATE_READING;
- jffs2_add_ino_cache(c, f->inocache);
- }
- if (!f->inocache) {
- printk(KERN_WARNING "jffs2_do_read_inode() on nonexistent ino %u\n", ino);
- return -ENOENT;
+ spin_lock(&c->erase_completion_lock);
}
- return jffs2_do_read_inode_internal(c, f, latest_node);
-}
-
-int jffs2_do_crccheck_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic)
-{
- struct jffs2_raw_inode n;
- struct jffs2_inode_info *f = kmalloc(sizeof(*f), GFP_KERNEL);
- int ret;
-
- if (!f)
- return -ENOMEM;
+ spin_unlock(&c->erase_completion_lock);
+ *tnp = ret_tn;
+ *fdp = ret_fd;
+ kfree(buf);
- memset(f, 0, sizeof(*f));
- init_MUTEX_LOCKED(&f->sem);
- f->inocache = ic;
+ dbg_readinode("nodes of inode #%u were read, the highest version is %u, latest_mctime %u, mctime_ver %u.\n",
+ f->inocache->ino, *highest_version, *latest_mctime, *mctime_ver);
+ return 0;
- ret = jffs2_do_read_inode_internal(c, f, &n);
- if (!ret) {
- up(&f->sem);
- jffs2_do_clear_inode(c, f);
- }
- kfree (f);
- return ret;
+ free_out:
+ jffs2_free_tmp_dnode_info_list(&ret_tn);
+ jffs2_free_full_dirent_list(ret_fd);
+ kfree(buf);
+ return err;
}
-static int jffs2_do_read_inode_internal(struct jffs2_sb_info *c,
+static int jffs2_do_read_inode_internal(struct jffs2_sb_info *c,
struct jffs2_inode_info *f,
struct jffs2_raw_inode *latest_node)
{
- struct jffs2_tmp_dnode_info *tn = NULL;
+ struct jffs2_tmp_dnode_info *tn;
struct rb_root tn_list;
struct rb_node *rb, *repl_rb;
struct jffs2_full_dirent *fd_list;
- struct jffs2_full_dnode *fn = NULL;
+ struct jffs2_full_dnode *fn, *first_fn = NULL;
uint32_t crc;
uint32_t latest_mctime, mctime_ver;
- uint32_t mdata_ver = 0;
size_t retlen;
int ret;
- D1(printk(KERN_DEBUG "jffs2_do_read_inode_internal(): ino #%u nlink is %d\n", f->inocache->ino, f->inocache->nlink));
+ dbg_readinode("ino #%u nlink is %d\n", f->inocache->ino, f->inocache->nlink);
/* Grab all nodes relevant to this ino */
ret = jffs2_get_inode_nodes(c, f, &tn_list, &fd_list, &f->highest_version, &latest_mctime, &mctime_ver);
if (ret) {
- printk(KERN_CRIT "jffs2_get_inode_nodes() for ino %u returned %d\n", f->inocache->ino, ret);
+ JFFS2_ERROR("cannot read nodes for ino %u, returned error is %d\n", f->inocache->ino, ret);
if (f->inocache->state == INO_STATE_READING)
jffs2_set_inocache_state(c, f->inocache, INO_STATE_CHECKEDABSENT);
return ret;
@@ -525,42 +655,33 @@ static int jffs2_do_read_inode_internal(struct jffs2_sb_info *c,
rb = rb_first(&tn_list);
while (rb) {
+ cond_resched();
tn = rb_entry(rb, struct jffs2_tmp_dnode_info, rb);
fn = tn->fn;
-
- if (f->metadata) {
- if (likely(tn->version >= mdata_ver)) {
- D1(printk(KERN_DEBUG "Obsoleting old metadata at 0x%08x\n", ref_offset(f->metadata->raw)));
- jffs2_mark_node_obsolete(c, f->metadata->raw);
- jffs2_free_full_dnode(f->metadata);
- f->metadata = NULL;
-
- mdata_ver = 0;
- } else {
- /* This should never happen. */
- printk(KERN_WARNING "Er. New metadata at 0x%08x with ver %d is actually older than previous ver %d at 0x%08x\n",
- ref_offset(fn->raw), tn->version, mdata_ver, ref_offset(f->metadata->raw));
- jffs2_mark_node_obsolete(c, fn->raw);
- jffs2_free_full_dnode(fn);
- /* Fill in latest_node from the metadata, not this one we're about to free... */
- fn = f->metadata;
- goto next_tn;
- }
- }
+ ret = 1;
+ dbg_readinode("consider node ver %u, phys offset "
+ "%#08x(%d), range %u-%u.\n", tn->version,
+ ref_offset(fn->raw), ref_flags(fn->raw),
+ fn->ofs, fn->ofs + fn->size);
if (fn->size) {
- jffs2_add_full_dnode_to_inode(c, f, fn);
- } else {
- /* Zero-sized node at end of version list. Just a metadata update */
- D1(printk(KERN_DEBUG "metadata @%08x: ver %d\n", ref_offset(fn->raw), tn->version));
+ ret = jffs2_add_older_frag_to_fragtree(c, f, tn);
+ /* TODO: the error code isn't checked, check it */
+ jffs2_dbg_fragtree_paranoia_check_nolock(f);
+ BUG_ON(ret < 0);
+ if (!first_fn && ret == 0)
+ first_fn = fn;
+ } else if (!first_fn) {
+ first_fn = fn;
f->metadata = fn;
- mdata_ver = tn->version;
- }
- next_tn:
+ ret = 0; /* Prevent freeing the metadata update node */
+ } else
+ jffs2_mark_node_obsolete(c, fn->raw);
+
BUG_ON(rb->rb_left);
if (rb->rb_parent && rb->rb_parent->rb_left == rb) {
/* We were then left-hand child of our parent. We need
- to move our own right-hand child into our place. */
+ * to move our own right-hand child into our place. */
repl_rb = rb->rb_right;
if (repl_rb)
repl_rb->rb_parent = rb->rb_parent;
@@ -570,7 +691,7 @@ static int jffs2_do_read_inode_internal(struct jffs2_sb_info *c,
rb = rb_next(rb);
/* Remove the spent tn from the tree; don't bother rebalancing
- but put our right-hand child in our own place. */
+ * but put our right-hand child in our own place. */
if (tn->rb.rb_parent) {
if (tn->rb.rb_parent->rb_left == &tn->rb)
tn->rb.rb_parent->rb_left = repl_rb;
@@ -581,19 +702,27 @@ static int jffs2_do_read_inode_internal(struct jffs2_sb_info *c,
tn->rb.rb_right->rb_parent = NULL;
jffs2_free_tmp_dnode_info(tn);
+ if (ret) {
+ dbg_readinode("delete dnode %u-%u.\n",
+ fn->ofs, fn->ofs + fn->size);
+ jffs2_free_full_dnode(fn);
+ }
}
- D1(jffs2_sanitycheck_fragtree(f));
+ jffs2_dbg_fragtree_paranoia_check_nolock(f);
- if (!fn) {
+ BUG_ON(first_fn && ref_obsolete(first_fn->raw));
+
+ fn = first_fn;
+ if (unlikely(!first_fn)) {
/* No data nodes for this inode. */
if (f->inocache->ino != 1) {
- printk(KERN_WARNING "jffs2_do_read_inode(): No data nodes found for ino #%u\n", f->inocache->ino);
+ JFFS2_WARNING("no data nodes found for ino #%u\n", f->inocache->ino);
if (!fd_list) {
if (f->inocache->state == INO_STATE_READING)
jffs2_set_inocache_state(c, f->inocache, INO_STATE_CHECKEDABSENT);
return -EIO;
}
- printk(KERN_WARNING "jffs2_do_read_inode(): But it has children so we fake some modes for it\n");
+ JFFS2_NOTICE("but it has children so we fake some modes for it\n");
}
latest_node->mode = cpu_to_jemode(S_IFDIR|S_IRUGO|S_IWUSR|S_IXUGO);
latest_node->version = cpu_to_je32(0);
@@ -608,8 +737,8 @@ static int jffs2_do_read_inode_internal(struct jffs2_sb_info *c,
ret = jffs2_flash_read(c, ref_offset(fn->raw), sizeof(*latest_node), &retlen, (void *)latest_node);
if (ret || retlen != sizeof(*latest_node)) {
- printk(KERN_NOTICE "MTD read in jffs2_do_read_inode() failed: Returned %d, %zd of %zd bytes read\n",
- ret, retlen, sizeof(*latest_node));
+ JFFS2_ERROR("failed to read from flash: error %d, %zd of %zd bytes read\n",
+ ret, retlen, sizeof(*latest_node));
/* FIXME: If this fails, there seems to be a memory leak. Find it. */
up(&f->sem);
jffs2_do_clear_inode(c, f);
@@ -618,7 +747,8 @@ static int jffs2_do_read_inode_internal(struct jffs2_sb_info *c,
crc = crc32(0, latest_node, sizeof(*latest_node)-8);
if (crc != je32_to_cpu(latest_node->node_crc)) {
- printk(KERN_NOTICE "CRC failed for read_inode of inode %u at physical location 0x%x\n", f->inocache->ino, ref_offset(fn->raw));
+ JFFS2_ERROR("CRC failed for read_inode of inode %u at physical location 0x%x\n",
+ f->inocache->ino, ref_offset(fn->raw));
up(&f->sem);
jffs2_do_clear_inode(c, f);
return -EIO;
@@ -633,10 +763,10 @@ static int jffs2_do_read_inode_internal(struct jffs2_sb_info *c,
}
break;
-
+
case S_IFREG:
/* If it was a regular file, truncate it to the latest node's isize */
- jffs2_truncate_fraglist(c, &f->fragtree, je32_to_cpu(latest_node->isize));
+ jffs2_truncate_fragtree(c, &f->fragtree, je32_to_cpu(latest_node->isize));
break;
case S_IFLNK:
@@ -649,37 +779,33 @@ static int jffs2_do_read_inode_internal(struct jffs2_sb_info *c,
if (f->inocache->state != INO_STATE_CHECKING) {
/* Symlink's inode data is the target path. Read it and
- * keep in RAM to facilitate quick follow symlink operation.
- * We use f->dents field to store the target path, which
- * is somewhat ugly. */
- f->dents = kmalloc(je32_to_cpu(latest_node->csize) + 1, GFP_KERNEL);
- if (!f->dents) {
- printk(KERN_WARNING "Can't allocate %d bytes of memory "
- "for the symlink target path cache\n",
- je32_to_cpu(latest_node->csize));
+ * keep in RAM to facilitate quick follow symlink
+ * operation. */
+ f->target = kmalloc(je32_to_cpu(latest_node->csize) + 1, GFP_KERNEL);
+ if (!f->target) {
+ JFFS2_ERROR("can't allocate %d bytes of memory for the symlink target path cache\n", je32_to_cpu(latest_node->csize));
up(&f->sem);
jffs2_do_clear_inode(c, f);
return -ENOMEM;
}
-
+
ret = jffs2_flash_read(c, ref_offset(fn->raw) + sizeof(*latest_node),
- je32_to_cpu(latest_node->csize), &retlen, (char *)f->dents);
-
+ je32_to_cpu(latest_node->csize), &retlen, (char *)f->target);
+
if (ret || retlen != je32_to_cpu(latest_node->csize)) {
if (retlen != je32_to_cpu(latest_node->csize))
ret = -EIO;
- kfree(f->dents);
- f->dents = NULL;
+ kfree(f->target);
+ f->target = NULL;
up(&f->sem);
jffs2_do_clear_inode(c, f);
return -ret;
}
- ((char *)f->dents)[je32_to_cpu(latest_node->csize)] = '\0';
- D1(printk(KERN_DEBUG "jffs2_do_read_inode(): symlink's target '%s' cached\n",
- (char *)f->dents));
+ f->target[je32_to_cpu(latest_node->csize)] = '\0';
+ dbg_readinode("symlink's target '%s' cached\n", f->target);
}
-
+
/* fall through... */
case S_IFBLK:
@@ -687,14 +813,14 @@ static int jffs2_do_read_inode_internal(struct jffs2_sb_info *c,
/* Certain inode types should have only one data node, and it's
kept as the metadata node */
if (f->metadata) {
- printk(KERN_WARNING "Argh. Special inode #%u with mode 0%o had metadata node\n",
+ JFFS2_ERROR("Argh. Special inode #%u with mode 0%o had metadata node\n",
f->inocache->ino, jemode_to_cpu(latest_node->mode));
up(&f->sem);
jffs2_do_clear_inode(c, f);
return -EIO;
}
if (!frag_first(&f->fragtree)) {
- printk(KERN_WARNING "Argh. Special inode #%u with mode 0%o has no fragments\n",
+ JFFS2_ERROR("Argh. Special inode #%u with mode 0%o has no fragments\n",
f->inocache->ino, jemode_to_cpu(latest_node->mode));
up(&f->sem);
jffs2_do_clear_inode(c, f);
@@ -702,7 +828,7 @@ static int jffs2_do_read_inode_internal(struct jffs2_sb_info *c,
}
/* ASSERT: f->fraglist != NULL */
if (frag_next(frag_first(&f->fragtree))) {
- printk(KERN_WARNING "Argh. Special inode #%u with mode 0x%x had more than one node\n",
+ JFFS2_ERROR("Argh. Special inode #%u with mode 0x%x had more than one node\n",
f->inocache->ino, jemode_to_cpu(latest_node->mode));
/* FIXME: Deal with it - check crc32, check for duplicate node, check times and discard the older one */
up(&f->sem);
@@ -721,6 +847,93 @@ static int jffs2_do_read_inode_internal(struct jffs2_sb_info *c,
return 0;
}
+/* Scan the list of all nodes present for this ino, build map of versions, etc. */
+int jffs2_do_read_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
+ uint32_t ino, struct jffs2_raw_inode *latest_node)
+{
+ dbg_readinode("read inode #%u\n", ino);
+
+ retry_inocache:
+ spin_lock(&c->inocache_lock);
+ f->inocache = jffs2_get_ino_cache(c, ino);
+
+ if (f->inocache) {
+ /* Check its state. We may need to wait before we can use it */
+ switch(f->inocache->state) {
+ case INO_STATE_UNCHECKED:
+ case INO_STATE_CHECKEDABSENT:
+ f->inocache->state = INO_STATE_READING;
+ break;
+
+ case INO_STATE_CHECKING:
+ case INO_STATE_GC:
+ /* If it's in either of these states, we need
+ to wait for whoever's got it to finish and
+ put it back. */
+ dbg_readinode("waiting for ino #%u in state %d\n", ino, f->inocache->state);
+ sleep_on_spinunlock(&c->inocache_wq, &c->inocache_lock);
+ goto retry_inocache;
+
+ case INO_STATE_READING:
+ case INO_STATE_PRESENT:
+ /* Eep. This should never happen. It can
+ happen if Linux calls read_inode() again
+ before clear_inode() has finished though. */
+ JFFS2_ERROR("Eep. Trying to read_inode #%u when it's already in state %d!\n", ino, f->inocache->state);
+ /* Fail. That's probably better than allowing it to succeed */
+ f->inocache = NULL;
+ break;
+
+ default:
+ BUG();
+ }
+ }
+ spin_unlock(&c->inocache_lock);
+
+ if (!f->inocache && ino == 1) {
+ /* Special case - no root inode on medium */
+ f->inocache = jffs2_alloc_inode_cache();
+ if (!f->inocache) {
+ JFFS2_ERROR("cannot allocate inocache for root inode\n");
+ return -ENOMEM;
+ }
+ dbg_readinode("creating inocache for root inode\n");
+ memset(f->inocache, 0, sizeof(struct jffs2_inode_cache));
+ f->inocache->ino = f->inocache->nlink = 1;
+ f->inocache->nodes = (struct jffs2_raw_node_ref *)f->inocache;
+ f->inocache->state = INO_STATE_READING;
+ jffs2_add_ino_cache(c, f->inocache);
+ }
+ if (!f->inocache) {
+ JFFS2_ERROR("requestied to read an nonexistent ino %u\n", ino);
+ return -ENOENT;
+ }
+
+ return jffs2_do_read_inode_internal(c, f, latest_node);
+}
+
+int jffs2_do_crccheck_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic)
+{
+ struct jffs2_raw_inode n;
+ struct jffs2_inode_info *f = kmalloc(sizeof(*f), GFP_KERNEL);
+ int ret;
+
+ if (!f)
+ return -ENOMEM;
+
+ memset(f, 0, sizeof(*f));
+ init_MUTEX_LOCKED(&f->sem);
+ f->inocache = ic;
+
+ ret = jffs2_do_read_inode_internal(c, f, &n);
+ if (!ret) {
+ up(&f->sem);
+ jffs2_do_clear_inode(c, f);
+ }
+ kfree (f);
+ return ret;
+}
+
void jffs2_do_clear_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f)
{
struct jffs2_full_dirent *fd, *fds;
@@ -740,20 +953,16 @@ void jffs2_do_clear_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f)
jffs2_kill_fragtree(&f->fragtree, deleted?c:NULL);
- /* For symlink inodes we us f->dents to store the target path name */
- if (S_ISLNK(OFNI_EDONI_2SFFJ(f)->i_mode)) {
- if (f->dents) {
- kfree(f->dents);
- f->dents = NULL;
- }
- } else {
- fds = f->dents;
+ if (f->target) {
+ kfree(f->target);
+ f->target = NULL;
+ }
- while(fds) {
- fd = fds;
- fds = fd->next;
- jffs2_free_full_dirent(fd);
- }
+ fds = f->dents;
+ while(fds) {
+ fd = fds;
+ fds = fd->next;
+ jffs2_free_full_dirent(fd);
}
if (f->inocache && f->inocache->state != INO_STATE_CHECKING) {
diff --git a/fs/jffs2/scan.c b/fs/jffs2/scan.c
index b63160f83bab..0e7456ec99fd 100644
--- a/fs/jffs2/scan.c
+++ b/fs/jffs2/scan.c
@@ -7,7 +7,7 @@
*
* For licensing information, see the file 'LICENCE' in this directory.
*
- * $Id: scan.c,v 1.119 2005/02/17 17:51:13 dedekind Exp $
+ * $Id: scan.c,v 1.125 2005/09/30 13:59:13 dedekind Exp $
*
*/
#include <linux/kernel.h>
@@ -18,22 +18,11 @@
#include <linux/crc32.h>
#include <linux/compiler.h>
#include "nodelist.h"
+#include "summary.h"
+#include "debug.h"
#define DEFAULT_EMPTY_SCAN_SIZE 1024
-#define DIRTY_SPACE(x) do { typeof(x) _x = (x); \
- c->free_size -= _x; c->dirty_size += _x; \
- jeb->free_size -= _x ; jeb->dirty_size += _x; \
- }while(0)
-#define USED_SPACE(x) do { typeof(x) _x = (x); \
- c->free_size -= _x; c->used_size += _x; \
- jeb->free_size -= _x ; jeb->used_size += _x; \
- }while(0)
-#define UNCHECKED_SPACE(x) do { typeof(x) _x = (x); \
- c->free_size -= _x; c->unchecked_size += _x; \
- jeb->free_size -= _x ; jeb->unchecked_size += _x; \
- }while(0)
-
#define noisy_printk(noise, args...) do { \
if (*(noise)) { \
printk(KERN_NOTICE args); \
@@ -47,23 +36,16 @@
static uint32_t pseudo_random;
static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
- unsigned char *buf, uint32_t buf_size);
+ unsigned char *buf, uint32_t buf_size, struct jffs2_summary *s);
-/* These helper functions _must_ increase ofs and also do the dirty/used space accounting.
+/* These helper functions _must_ increase ofs and also do the dirty/used space accounting.
* Returning an error will abort the mount - bad checksums etc. should just mark the space
* as dirty.
*/
-static int jffs2_scan_inode_node(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
- struct jffs2_raw_inode *ri, uint32_t ofs);
+static int jffs2_scan_inode_node(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
+ struct jffs2_raw_inode *ri, uint32_t ofs, struct jffs2_summary *s);
static int jffs2_scan_dirent_node(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
- struct jffs2_raw_dirent *rd, uint32_t ofs);
-
-#define BLK_STATE_ALLFF 0
-#define BLK_STATE_CLEAN 1
-#define BLK_STATE_PARTDIRTY 2
-#define BLK_STATE_CLEANMARKER 3
-#define BLK_STATE_ALLDIRTY 4
-#define BLK_STATE_BADBLOCK 5
+ struct jffs2_raw_dirent *rd, uint32_t ofs, struct jffs2_summary *s);
static inline int min_free(struct jffs2_sb_info *c)
{
@@ -89,6 +71,7 @@ int jffs2_scan_medium(struct jffs2_sb_info *c)
uint32_t empty_blocks = 0, bad_blocks = 0;
unsigned char *flashbuf = NULL;
uint32_t buf_size = 0;
+ struct jffs2_summary *s = NULL; /* summary info collected by the scan process */
#ifndef __ECOS
size_t pointlen;
@@ -122,21 +105,34 @@ int jffs2_scan_medium(struct jffs2_sb_info *c)
return -ENOMEM;
}
+ if (jffs2_sum_active()) {
+ s = kmalloc(sizeof(struct jffs2_summary), GFP_KERNEL);
+ if (!s) {
+ JFFS2_WARNING("Can't allocate memory for summary\n");
+ return -ENOMEM;
+ }
+ memset(s, 0, sizeof(struct jffs2_summary));
+ }
+
for (i=0; i<c->nr_blocks; i++) {
struct jffs2_eraseblock *jeb = &c->blocks[i];
- ret = jffs2_scan_eraseblock(c, jeb, buf_size?flashbuf:(flashbuf+jeb->offset), buf_size);
+ /* reset summary info for next eraseblock scan */
+ jffs2_sum_reset_collected(s);
+
+ ret = jffs2_scan_eraseblock(c, jeb, buf_size?flashbuf:(flashbuf+jeb->offset),
+ buf_size, s);
if (ret < 0)
goto out;
- ACCT_PARANOIA_CHECK(jeb);
+ jffs2_dbg_acct_paranoia_check_nolock(c, jeb);
/* Now decide which list to put it on */
switch(ret) {
case BLK_STATE_ALLFF:
- /*
- * Empty block. Since we can't be sure it
+ /*
+ * Empty block. Since we can't be sure it
* was entirely erased, we just queue it for erase
* again. It will be marked as such when the erase
* is complete. Meanwhile we still count it as empty
@@ -162,18 +158,18 @@ int jffs2_scan_medium(struct jffs2_sb_info *c)
break;
case BLK_STATE_CLEAN:
- /* Full (or almost full) of clean data. Clean list */
- list_add(&jeb->list, &c->clean_list);
+ /* Full (or almost full) of clean data. Clean list */
+ list_add(&jeb->list, &c->clean_list);
break;
case BLK_STATE_PARTDIRTY:
- /* Some data, but not full. Dirty list. */
- /* We want to remember the block with most free space
- and stick it in the 'nextblock' position to start writing to it. */
- if (jeb->free_size > min_free(c) &&
- (!c->nextblock || c->nextblock->free_size < jeb->free_size)) {
- /* Better candidate for the next writes to go to */
- if (c->nextblock) {
+ /* Some data, but not full. Dirty list. */
+ /* We want to remember the block with most free space
+ and stick it in the 'nextblock' position to start writing to it. */
+ if (jeb->free_size > min_free(c) &&
+ (!c->nextblock || c->nextblock->free_size < jeb->free_size)) {
+ /* Better candidate for the next writes to go to */
+ if (c->nextblock) {
c->nextblock->dirty_size += c->nextblock->free_size + c->nextblock->wasted_size;
c->dirty_size += c->nextblock->free_size + c->nextblock->wasted_size;
c->free_size -= c->nextblock->free_size;
@@ -184,9 +180,14 @@ int jffs2_scan_medium(struct jffs2_sb_info *c)
} else {
list_add(&c->nextblock->list, &c->dirty_list);
}
+ /* deleting summary information of the old nextblock */
+ jffs2_sum_reset_collected(c->summary);
}
- c->nextblock = jeb;
- } else {
+ /* update collected summary infromation for the current nextblock */
+ jffs2_sum_move_collected(c, s);
+ D1(printk(KERN_DEBUG "jffs2_scan_medium(): new nextblock = 0x%08x\n", jeb->offset));
+ c->nextblock = jeb;
+ } else {
jeb->dirty_size += jeb->free_size + jeb->wasted_size;
c->dirty_size += jeb->free_size + jeb->wasted_size;
c->free_size -= jeb->free_size;
@@ -197,30 +198,33 @@ int jffs2_scan_medium(struct jffs2_sb_info *c)
} else {
list_add(&jeb->list, &c->dirty_list);
}
- }
+ }
break;
case BLK_STATE_ALLDIRTY:
/* Nothing valid - not even a clean marker. Needs erasing. */
- /* For now we just put it on the erasing list. We'll start the erases later */
+ /* For now we just put it on the erasing list. We'll start the erases later */
D1(printk(KERN_NOTICE "JFFS2: Erase block at 0x%08x is not formatted. It will be erased\n", jeb->offset));
- list_add(&jeb->list, &c->erase_pending_list);
+ list_add(&jeb->list, &c->erase_pending_list);
c->nr_erasing_blocks++;
break;
-
+
case BLK_STATE_BADBLOCK:
D1(printk(KERN_NOTICE "JFFS2: Block at 0x%08x is bad\n", jeb->offset));
- list_add(&jeb->list, &c->bad_list);
+ list_add(&jeb->list, &c->bad_list);
c->bad_size += c->sector_size;
c->free_size -= c->sector_size;
bad_blocks++;
break;
default:
printk(KERN_WARNING "jffs2_scan_medium(): unknown block state\n");
- BUG();
+ BUG();
}
}
-
+
+ if (jffs2_sum_active() && s)
+ kfree(s);
+
/* Nextblock dirty is always seen as wasted, because we cannot recycle it now */
if (c->nextblock && (c->nextblock->dirty_size)) {
c->nextblock->wasted_size += c->nextblock->dirty_size;
@@ -229,12 +233,12 @@ int jffs2_scan_medium(struct jffs2_sb_info *c)
c->nextblock->dirty_size = 0;
}
#ifdef CONFIG_JFFS2_FS_WRITEBUFFER
- if (!jffs2_can_mark_obsolete(c) && c->nextblock && (c->nextblock->free_size & (c->wbuf_pagesize-1))) {
- /* If we're going to start writing into a block which already
+ if (!jffs2_can_mark_obsolete(c) && c->nextblock && (c->nextblock->free_size % c->wbuf_pagesize)) {
+ /* If we're going to start writing into a block which already
contains data, and the end of the data isn't page-aligned,
skip a little and align it. */
- uint32_t skip = c->nextblock->free_size & (c->wbuf_pagesize-1);
+ uint32_t skip = c->nextblock->free_size % c->wbuf_pagesize;
D1(printk(KERN_DEBUG "jffs2_scan_medium(): Skipping %d bytes in nextblock to ensure page alignment\n",
skip));
@@ -246,7 +250,7 @@ int jffs2_scan_medium(struct jffs2_sb_info *c)
}
#endif
if (c->nr_erasing_blocks) {
- if ( !c->used_size && ((c->nr_free_blocks+empty_blocks+bad_blocks)!= c->nr_blocks || bad_blocks == c->nr_blocks) ) {
+ if ( !c->used_size && ((c->nr_free_blocks+empty_blocks+bad_blocks)!= c->nr_blocks || bad_blocks == c->nr_blocks) ) {
printk(KERN_NOTICE "Cowardly refusing to erase blocks on filesystem with no valid JFFS2 nodes\n");
printk(KERN_NOTICE "empty_blocks %d, bad_blocks %d, c->nr_blocks %d\n",empty_blocks,bad_blocks,c->nr_blocks);
ret = -EIO;
@@ -259,13 +263,13 @@ int jffs2_scan_medium(struct jffs2_sb_info *c)
if (buf_size)
kfree(flashbuf);
#ifndef __ECOS
- else
+ else
c->mtd->unpoint(c->mtd, flashbuf, 0, c->mtd->size);
#endif
return ret;
}
-static int jffs2_fill_scan_buf (struct jffs2_sb_info *c, unsigned char *buf,
+int jffs2_fill_scan_buf (struct jffs2_sb_info *c, void *buf,
uint32_t ofs, uint32_t len)
{
int ret;
@@ -286,14 +290,36 @@ static int jffs2_fill_scan_buf (struct jffs2_sb_info *c, unsigned char *buf,
return 0;
}
+int jffs2_scan_classify_jeb(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb)
+{
+ if ((jeb->used_size + jeb->unchecked_size) == PAD(c->cleanmarker_size) && !jeb->dirty_size
+ && (!jeb->first_node || !jeb->first_node->next_phys) )
+ return BLK_STATE_CLEANMARKER;
+
+ /* move blocks with max 4 byte dirty space to cleanlist */
+ else if (!ISDIRTY(c->sector_size - (jeb->used_size + jeb->unchecked_size))) {
+ c->dirty_size -= jeb->dirty_size;
+ c->wasted_size += jeb->dirty_size;
+ jeb->wasted_size += jeb->dirty_size;
+ jeb->dirty_size = 0;
+ return BLK_STATE_CLEAN;
+ } else if (jeb->used_size || jeb->unchecked_size)
+ return BLK_STATE_PARTDIRTY;
+ else
+ return BLK_STATE_ALLDIRTY;
+}
+
static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
- unsigned char *buf, uint32_t buf_size) {
+ unsigned char *buf, uint32_t buf_size, struct jffs2_summary *s) {
struct jffs2_unknown_node *node;
struct jffs2_unknown_node crcnode;
+ struct jffs2_sum_marker *sm;
uint32_t ofs, prevofs;
uint32_t hdr_crc, buf_ofs, buf_len;
int err;
int noise = 0;
+
+
#ifdef CONFIG_JFFS2_FS_WRITEBUFFER
int cleanmarkerfound = 0;
#endif
@@ -319,17 +345,53 @@ static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblo
}
}
#endif
+
+ if (jffs2_sum_active()) {
+ sm = kmalloc(sizeof(struct jffs2_sum_marker), GFP_KERNEL);
+ if (!sm) {
+ return -ENOMEM;
+ }
+
+ err = jffs2_fill_scan_buf(c, (unsigned char *) sm, jeb->offset + c->sector_size -
+ sizeof(struct jffs2_sum_marker), sizeof(struct jffs2_sum_marker));
+ if (err) {
+ kfree(sm);
+ return err;
+ }
+
+ if (je32_to_cpu(sm->magic) == JFFS2_SUM_MAGIC ) {
+ err = jffs2_sum_scan_sumnode(c, jeb, je32_to_cpu(sm->offset), &pseudo_random);
+ if (err) {
+ kfree(sm);
+ return err;
+ }
+ }
+
+ kfree(sm);
+
+ ofs = jeb->offset;
+ prevofs = jeb->offset - 1;
+ }
+
buf_ofs = jeb->offset;
if (!buf_size) {
buf_len = c->sector_size;
+
+ if (jffs2_sum_active()) {
+ /* must reread because of summary test */
+ err = jffs2_fill_scan_buf(c, buf, buf_ofs, buf_len);
+ if (err)
+ return err;
+ }
+
} else {
buf_len = EMPTY_SCAN_SIZE(c->sector_size);
err = jffs2_fill_scan_buf(c, buf, buf_ofs, buf_len);
if (err)
return err;
}
-
+
/* We temporarily use 'ofs' as a pointer into the buffer/jeb */
ofs = 0;
@@ -367,10 +429,12 @@ static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblo
noise = 10;
-scan_more:
+ dbg_summary("no summary found in jeb 0x%08x. Apply original scan.\n",jeb->offset);
+
+scan_more:
while(ofs < jeb->offset + c->sector_size) {
- D1(ACCT_PARANOIA_CHECK(jeb));
+ jffs2_dbg_acct_paranoia_check_nolock(c, jeb);
cond_resched();
@@ -432,7 +496,7 @@ scan_more:
/* If we're only checking the beginning of a block with a cleanmarker,
bail now */
- if (buf_ofs == jeb->offset && jeb->used_size == PAD(c->cleanmarker_size) &&
+ if (buf_ofs == jeb->offset && jeb->used_size == PAD(c->cleanmarker_size) &&
c->cleanmarker_size && !jeb->dirty_size && !jeb->first_node->next_phys) {
D1(printk(KERN_DEBUG "%d bytes at start of block seems clean... assuming all clean\n", EMPTY_SCAN_SIZE(c->sector_size)));
return BLK_STATE_CLEANMARKER;
@@ -441,7 +505,7 @@ scan_more:
/* See how much more there is to read in this eraseblock... */
buf_len = min_t(uint32_t, buf_size, jeb->offset + c->sector_size - ofs);
if (!buf_len) {
- /* No more to read. Break out of main loop without marking
+ /* No more to read. Break out of main loop without marking
this range of empty space as dirty (because it's not) */
D1(printk(KERN_DEBUG "Empty flash at %08x runs to end of block. Treating as free_space\n",
empty_start));
@@ -476,8 +540,8 @@ scan_more:
}
if (je16_to_cpu(node->magic) != JFFS2_MAGIC_BITMASK) {
/* OK. We're out of possibilities. Whinge and move on */
- noisy_printk(&noise, "jffs2_scan_eraseblock(): Magic bitmask 0x%04x not found at 0x%08x: 0x%04x instead\n",
- JFFS2_MAGIC_BITMASK, ofs,
+ noisy_printk(&noise, "jffs2_scan_eraseblock(): Magic bitmask 0x%04x not found at 0x%08x: 0x%04x instead\n",
+ JFFS2_MAGIC_BITMASK, ofs,
je16_to_cpu(node->magic));
DIRTY_SPACE(4);
ofs += 4;
@@ -492,7 +556,7 @@ scan_more:
if (hdr_crc != je32_to_cpu(node->hdr_crc)) {
noisy_printk(&noise, "jffs2_scan_eraseblock(): Node at 0x%08x {0x%04x, 0x%04x, 0x%08x) has invalid CRC 0x%08x (calculated 0x%08x)\n",
ofs, je16_to_cpu(node->magic),
- je16_to_cpu(node->nodetype),
+ je16_to_cpu(node->nodetype),
je32_to_cpu(node->totlen),
je32_to_cpu(node->hdr_crc),
hdr_crc);
@@ -501,7 +565,7 @@ scan_more:
continue;
}
- if (ofs + je32_to_cpu(node->totlen) >
+ if (ofs + je32_to_cpu(node->totlen) >
jeb->offset + c->sector_size) {
/* Eep. Node goes over the end of the erase block. */
printk(KERN_WARNING "Node at 0x%08x with length 0x%08x would run over the end of the erase block\n",
@@ -532,11 +596,11 @@ scan_more:
buf_ofs = ofs;
node = (void *)buf;
}
- err = jffs2_scan_inode_node(c, jeb, (void *)node, ofs);
+ err = jffs2_scan_inode_node(c, jeb, (void *)node, ofs, s);
if (err) return err;
ofs += PAD(je32_to_cpu(node->totlen));
break;
-
+
case JFFS2_NODETYPE_DIRENT:
if (buf_ofs + buf_len < ofs + je32_to_cpu(node->totlen)) {
buf_len = min_t(uint32_t, buf_size, jeb->offset + c->sector_size - ofs);
@@ -548,7 +612,7 @@ scan_more:
buf_ofs = ofs;
node = (void *)buf;
}
- err = jffs2_scan_dirent_node(c, jeb, (void *)node, ofs);
+ err = jffs2_scan_dirent_node(c, jeb, (void *)node, ofs, s);
if (err) return err;
ofs += PAD(je32_to_cpu(node->totlen));
break;
@@ -556,7 +620,7 @@ scan_more:
case JFFS2_NODETYPE_CLEANMARKER:
D1(printk(KERN_DEBUG "CLEANMARKER node found at 0x%08x\n", ofs));
if (je32_to_cpu(node->totlen) != c->cleanmarker_size) {
- printk(KERN_NOTICE "CLEANMARKER node found at 0x%08x has totlen 0x%x != normal 0x%x\n",
+ printk(KERN_NOTICE "CLEANMARKER node found at 0x%08x has totlen 0x%x != normal 0x%x\n",
ofs, je32_to_cpu(node->totlen), c->cleanmarker_size);
DIRTY_SPACE(PAD(sizeof(struct jffs2_unknown_node)));
ofs += PAD(sizeof(struct jffs2_unknown_node));
@@ -575,13 +639,15 @@ scan_more:
marker_ref->flash_offset = ofs | REF_NORMAL;
marker_ref->__totlen = c->cleanmarker_size;
jeb->first_node = jeb->last_node = marker_ref;
-
+
USED_SPACE(PAD(c->cleanmarker_size));
ofs += PAD(c->cleanmarker_size);
}
break;
case JFFS2_NODETYPE_PADDING:
+ if (jffs2_sum_active())
+ jffs2_sum_add_padding_mem(s, je32_to_cpu(node->totlen));
DIRTY_SPACE(PAD(je32_to_cpu(node->totlen)));
ofs += PAD(je32_to_cpu(node->totlen));
break;
@@ -616,8 +682,15 @@ scan_more:
}
}
+ if (jffs2_sum_active()) {
+ if (PAD(s->sum_size + JFFS2_SUMMARY_FRAME_SIZE) > jeb->free_size) {
+ dbg_summary("There is not enough space for "
+ "summary information, disabling for this jeb!\n");
+ jffs2_sum_disable_collecting(s);
+ }
+ }
- D1(printk(KERN_DEBUG "Block at 0x%08x: free 0x%08x, dirty 0x%08x, unchecked 0x%08x, used 0x%08x\n", jeb->offset,
+ D1(printk(KERN_DEBUG "Block at 0x%08x: free 0x%08x, dirty 0x%08x, unchecked 0x%08x, used 0x%08x\n", jeb->offset,
jeb->free_size, jeb->dirty_size, jeb->unchecked_size, jeb->used_size));
/* mark_node_obsolete can add to wasted !! */
@@ -628,24 +701,10 @@ scan_more:
jeb->wasted_size = 0;
}
- if ((jeb->used_size + jeb->unchecked_size) == PAD(c->cleanmarker_size) && !jeb->dirty_size
- && (!jeb->first_node || !jeb->first_node->next_phys) )
- return BLK_STATE_CLEANMARKER;
-
- /* move blocks with max 4 byte dirty space to cleanlist */
- else if (!ISDIRTY(c->sector_size - (jeb->used_size + jeb->unchecked_size))) {
- c->dirty_size -= jeb->dirty_size;
- c->wasted_size += jeb->dirty_size;
- jeb->wasted_size += jeb->dirty_size;
- jeb->dirty_size = 0;
- return BLK_STATE_CLEAN;
- } else if (jeb->used_size || jeb->unchecked_size)
- return BLK_STATE_PARTDIRTY;
- else
- return BLK_STATE_ALLDIRTY;
+ return jffs2_scan_classify_jeb(c, jeb);
}
-static struct jffs2_inode_cache *jffs2_scan_make_ino_cache(struct jffs2_sb_info *c, uint32_t ino)
+struct jffs2_inode_cache *jffs2_scan_make_ino_cache(struct jffs2_sb_info *c, uint32_t ino)
{
struct jffs2_inode_cache *ic;
@@ -671,8 +730,8 @@ static struct jffs2_inode_cache *jffs2_scan_make_ino_cache(struct jffs2_sb_info
return ic;
}
-static int jffs2_scan_inode_node(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
- struct jffs2_raw_inode *ri, uint32_t ofs)
+static int jffs2_scan_inode_node(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
+ struct jffs2_raw_inode *ri, uint32_t ofs, struct jffs2_summary *s)
{
struct jffs2_raw_node_ref *raw;
struct jffs2_inode_cache *ic;
@@ -681,11 +740,11 @@ static int jffs2_scan_inode_node(struct jffs2_sb_info *c, struct jffs2_erasebloc
D1(printk(KERN_DEBUG "jffs2_scan_inode_node(): Node at 0x%08x\n", ofs));
/* We do very little here now. Just check the ino# to which we should attribute
- this node; we can do all the CRC checking etc. later. There's a tradeoff here --
+ this node; we can do all the CRC checking etc. later. There's a tradeoff here --
we used to scan the flash once only, reading everything we want from it into
memory, then building all our in-core data structures and freeing the extra
information. Now we allow the first part of the mount to complete a lot quicker,
- but we have to go _back_ to the flash in order to finish the CRC checking, etc.
+ but we have to go _back_ to the flash in order to finish the CRC checking, etc.
Which means that the _full_ amount of time to get to proper write mode with GC
operational may actually be _longer_ than before. Sucks to be me. */
@@ -731,7 +790,7 @@ static int jffs2_scan_inode_node(struct jffs2_sb_info *c, struct jffs2_erasebloc
jeb->last_node->next_phys = raw;
jeb->last_node = raw;
- D1(printk(KERN_DEBUG "Node is ino #%u, version %d. Range 0x%x-0x%x\n",
+ D1(printk(KERN_DEBUG "Node is ino #%u, version %d. Range 0x%x-0x%x\n",
je32_to_cpu(ri->ino), je32_to_cpu(ri->version),
je32_to_cpu(ri->offset),
je32_to_cpu(ri->offset)+je32_to_cpu(ri->dsize)));
@@ -739,11 +798,16 @@ static int jffs2_scan_inode_node(struct jffs2_sb_info *c, struct jffs2_erasebloc
pseudo_random += je32_to_cpu(ri->version);
UNCHECKED_SPACE(PAD(je32_to_cpu(ri->totlen)));
+
+ if (jffs2_sum_active()) {
+ jffs2_sum_add_inode_mem(s, ri, ofs - jeb->offset);
+ }
+
return 0;
}
-static int jffs2_scan_dirent_node(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
- struct jffs2_raw_dirent *rd, uint32_t ofs)
+static int jffs2_scan_dirent_node(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
+ struct jffs2_raw_dirent *rd, uint32_t ofs, struct jffs2_summary *s)
{
struct jffs2_raw_node_ref *raw;
struct jffs2_full_dirent *fd;
@@ -776,7 +840,7 @@ static int jffs2_scan_dirent_node(struct jffs2_sb_info *c, struct jffs2_eraseblo
crc = crc32(0, fd->name, rd->nsize);
if (crc != je32_to_cpu(rd->name_crc)) {
printk(KERN_NOTICE "jffs2_scan_dirent_node(): Name CRC failed on node at 0x%08x: Read 0x%08x, calculated 0x%08x\n",
- ofs, je32_to_cpu(rd->name_crc), crc);
+ ofs, je32_to_cpu(rd->name_crc), crc);
D1(printk(KERN_NOTICE "Name for which CRC failed is (now) '%s', ino #%d\n", fd->name, je32_to_cpu(rd->ino)));
jffs2_free_full_dirent(fd);
/* FIXME: Why do we believe totlen? */
@@ -796,7 +860,7 @@ static int jffs2_scan_dirent_node(struct jffs2_sb_info *c, struct jffs2_eraseblo
jffs2_free_raw_node_ref(raw);
return -ENOMEM;
}
-
+
raw->__totlen = PAD(je32_to_cpu(rd->totlen));
raw->flash_offset = ofs | REF_PRISTINE;
raw->next_phys = NULL;
@@ -817,6 +881,10 @@ static int jffs2_scan_dirent_node(struct jffs2_sb_info *c, struct jffs2_eraseblo
USED_SPACE(PAD(je32_to_cpu(rd->totlen)));
jffs2_add_fd_to_list(c, fd, &ic->scan_dents);
+ if (jffs2_sum_active()) {
+ jffs2_sum_add_dirent_mem(s, rd, ofs - jeb->offset);
+ }
+
return 0;
}
@@ -852,76 +920,34 @@ void jffs2_rotate_lists(struct jffs2_sb_info *c)
x = count_list(&c->clean_list);
if (x) {
rotateby = pseudo_random % x;
- D1(printk(KERN_DEBUG "Rotating clean_list by %d\n", rotateby));
-
rotate_list((&c->clean_list), rotateby);
-
- D1(printk(KERN_DEBUG "Erase block at front of clean_list is at %08x\n",
- list_entry(c->clean_list.next, struct jffs2_eraseblock, list)->offset));
- } else {
- D1(printk(KERN_DEBUG "Not rotating empty clean_list\n"));
}
x = count_list(&c->very_dirty_list);
if (x) {
rotateby = pseudo_random % x;
- D1(printk(KERN_DEBUG "Rotating very_dirty_list by %d\n", rotateby));
-
rotate_list((&c->very_dirty_list), rotateby);
-
- D1(printk(KERN_DEBUG "Erase block at front of very_dirty_list is at %08x\n",
- list_entry(c->very_dirty_list.next, struct jffs2_eraseblock, list)->offset));
- } else {
- D1(printk(KERN_DEBUG "Not rotating empty very_dirty_list\n"));
}
x = count_list(&c->dirty_list);
if (x) {
rotateby = pseudo_random % x;
- D1(printk(KERN_DEBUG "Rotating dirty_list by %d\n", rotateby));
-
rotate_list((&c->dirty_list), rotateby);
-
- D1(printk(KERN_DEBUG "Erase block at front of dirty_list is at %08x\n",
- list_entry(c->dirty_list.next, struct jffs2_eraseblock, list)->offset));
- } else {
- D1(printk(KERN_DEBUG "Not rotating empty dirty_list\n"));
}
x = count_list(&c->erasable_list);
if (x) {
rotateby = pseudo_random % x;
- D1(printk(KERN_DEBUG "Rotating erasable_list by %d\n", rotateby));
-
rotate_list((&c->erasable_list), rotateby);
-
- D1(printk(KERN_DEBUG "Erase block at front of erasable_list is at %08x\n",
- list_entry(c->erasable_list.next, struct jffs2_eraseblock, list)->offset));
- } else {
- D1(printk(KERN_DEBUG "Not rotating empty erasable_list\n"));
}
if (c->nr_erasing_blocks) {
rotateby = pseudo_random % c->nr_erasing_blocks;
- D1(printk(KERN_DEBUG "Rotating erase_pending_list by %d\n", rotateby));
-
rotate_list((&c->erase_pending_list), rotateby);
-
- D1(printk(KERN_DEBUG "Erase block at front of erase_pending_list is at %08x\n",
- list_entry(c->erase_pending_list.next, struct jffs2_eraseblock, list)->offset));
- } else {
- D1(printk(KERN_DEBUG "Not rotating empty erase_pending_list\n"));
}
if (c->nr_free_blocks) {
rotateby = pseudo_random % c->nr_free_blocks;
- D1(printk(KERN_DEBUG "Rotating free_list by %d\n", rotateby));
-
rotate_list((&c->free_list), rotateby);
-
- D1(printk(KERN_DEBUG "Erase block at front of free_list is at %08x\n",
- list_entry(c->free_list.next, struct jffs2_eraseblock, list)->offset));
- } else {
- D1(printk(KERN_DEBUG "Not rotating empty free_list\n"));
}
}
diff --git a/fs/jffs2/summary.c b/fs/jffs2/summary.c
new file mode 100644
index 000000000000..fb9cec61fcf2
--- /dev/null
+++ b/fs/jffs2/summary.c
@@ -0,0 +1,730 @@
+/*
+ * JFFS2 -- Journalling Flash File System, Version 2.
+ *
+ * Copyright (C) 2004 Ferenc Havasi <havasi@inf.u-szeged.hu>,
+ * Zoltan Sogor <weth@inf.u-szeged.hu>,
+ * Patrik Kluba <pajko@halom.u-szeged.hu>,
+ * University of Szeged, Hungary
+ *
+ * For licensing information, see the file 'LICENCE' in this directory.
+ *
+ * $Id: summary.c,v 1.4 2005/09/26 11:37:21 havasi Exp $
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/mtd/mtd.h>
+#include <linux/pagemap.h>
+#include <linux/crc32.h>
+#include <linux/compiler.h>
+#include <linux/vmalloc.h>
+#include "nodelist.h"
+#include "debug.h"
+
+int jffs2_sum_init(struct jffs2_sb_info *c)
+{
+ c->summary = kmalloc(sizeof(struct jffs2_summary), GFP_KERNEL);
+
+ if (!c->summary) {
+ JFFS2_WARNING("Can't allocate memory for summary information!\n");
+ return -ENOMEM;
+ }
+
+ memset(c->summary, 0, sizeof(struct jffs2_summary));
+
+ c->summary->sum_buf = vmalloc(c->sector_size);
+
+ if (!c->summary->sum_buf) {
+ JFFS2_WARNING("Can't allocate buffer for writing out summary information!\n");
+ kfree(c->summary);
+ return -ENOMEM;
+ }
+
+ dbg_summary("returned succesfully\n");
+
+ return 0;
+}
+
+void jffs2_sum_exit(struct jffs2_sb_info *c)
+{
+ dbg_summary("called\n");
+
+ jffs2_sum_disable_collecting(c->summary);
+
+ vfree(c->summary->sum_buf);
+ c->summary->sum_buf = NULL;
+
+ kfree(c->summary);
+ c->summary = NULL;
+}
+
+static int jffs2_sum_add_mem(struct jffs2_summary *s, union jffs2_sum_mem *item)
+{
+ if (!s->sum_list_head)
+ s->sum_list_head = (union jffs2_sum_mem *) item;
+ if (s->sum_list_tail)
+ s->sum_list_tail->u.next = (union jffs2_sum_mem *) item;
+ s->sum_list_tail = (union jffs2_sum_mem *) item;
+
+ switch (je16_to_cpu(item->u.nodetype)) {
+ case JFFS2_NODETYPE_INODE:
+ s->sum_size += JFFS2_SUMMARY_INODE_SIZE;
+ s->sum_num++;
+ dbg_summary("inode (%u) added to summary\n",
+ je32_to_cpu(item->i.inode));
+ break;
+ case JFFS2_NODETYPE_DIRENT:
+ s->sum_size += JFFS2_SUMMARY_DIRENT_SIZE(item->d.nsize);
+ s->sum_num++;
+ dbg_summary("dirent (%u) added to summary\n",
+ je32_to_cpu(item->d.ino));
+ break;
+ default:
+ JFFS2_WARNING("UNKNOWN node type %u\n",
+ je16_to_cpu(item->u.nodetype));
+ return 1;
+ }
+ return 0;
+}
+
+
+/* The following 3 functions are called from scan.c to collect summary info for not closed jeb */
+
+int jffs2_sum_add_padding_mem(struct jffs2_summary *s, uint32_t size)
+{
+ dbg_summary("called with %u\n", size);
+ s->sum_padded += size;
+ return 0;
+}
+
+int jffs2_sum_add_inode_mem(struct jffs2_summary *s, struct jffs2_raw_inode *ri,
+ uint32_t ofs)
+{
+ struct jffs2_sum_inode_mem *temp = kmalloc(sizeof(struct jffs2_sum_inode_mem), GFP_KERNEL);
+
+ if (!temp)
+ return -ENOMEM;
+
+ temp->nodetype = ri->nodetype;
+ temp->inode = ri->ino;
+ temp->version = ri->version;
+ temp->offset = cpu_to_je32(ofs); /* relative offset from the begining of the jeb */
+ temp->totlen = ri->totlen;
+ temp->next = NULL;
+
+ return jffs2_sum_add_mem(s, (union jffs2_sum_mem *)temp);
+}
+
+int jffs2_sum_add_dirent_mem(struct jffs2_summary *s, struct jffs2_raw_dirent *rd,
+ uint32_t ofs)
+{
+ struct jffs2_sum_dirent_mem *temp =
+ kmalloc(sizeof(struct jffs2_sum_dirent_mem) + rd->nsize, GFP_KERNEL);
+
+ if (!temp)
+ return -ENOMEM;
+
+ temp->nodetype = rd->nodetype;
+ temp->totlen = rd->totlen;
+ temp->offset = cpu_to_je32(ofs); /* relative from the begining of the jeb */
+ temp->pino = rd->pino;
+ temp->version = rd->version;
+ temp->ino = rd->ino;
+ temp->nsize = rd->nsize;
+ temp->type = rd->type;
+ temp->next = NULL;
+
+ memcpy(temp->name, rd->name, rd->nsize);
+
+ return jffs2_sum_add_mem(s, (union jffs2_sum_mem *)temp);
+}
+
+/* Cleanup every collected summary information */
+
+static void jffs2_sum_clean_collected(struct jffs2_summary *s)
+{
+ union jffs2_sum_mem *temp;
+
+ if (!s->sum_list_head) {
+ dbg_summary("already empty\n");
+ }
+ while (s->sum_list_head) {
+ temp = s->sum_list_head;
+ s->sum_list_head = s->sum_list_head->u.next;
+ kfree(temp);
+ }
+ s->sum_list_tail = NULL;
+ s->sum_padded = 0;
+ s->sum_num = 0;
+}
+
+void jffs2_sum_reset_collected(struct jffs2_summary *s)
+{
+ dbg_summary("called\n");
+ jffs2_sum_clean_collected(s);
+ s->sum_size = 0;
+}
+
+void jffs2_sum_disable_collecting(struct jffs2_summary *s)
+{
+ dbg_summary("called\n");
+ jffs2_sum_clean_collected(s);
+ s->sum_size = JFFS2_SUMMARY_NOSUM_SIZE;
+}
+
+int jffs2_sum_is_disabled(struct jffs2_summary *s)
+{
+ return (s->sum_size == JFFS2_SUMMARY_NOSUM_SIZE);
+}
+
+/* Move the collected summary information into sb (called from scan.c) */
+
+void jffs2_sum_move_collected(struct jffs2_sb_info *c, struct jffs2_summary *s)
+{
+ dbg_summary("oldsize=0x%x oldnum=%u => newsize=0x%x newnum=%u\n",
+ c->summary->sum_size, c->summary->sum_num,
+ s->sum_size, s->sum_num);
+
+ c->summary->sum_size = s->sum_size;
+ c->summary->sum_num = s->sum_num;
+ c->summary->sum_padded = s->sum_padded;
+ c->summary->sum_list_head = s->sum_list_head;
+ c->summary->sum_list_tail = s->sum_list_tail;
+
+ s->sum_list_head = s->sum_list_tail = NULL;
+}
+
+/* Called from wbuf.c to collect writed node info */
+
+int jffs2_sum_add_kvec(struct jffs2_sb_info *c, const struct kvec *invecs,
+ unsigned long count, uint32_t ofs)
+{
+ union jffs2_node_union *node;
+ struct jffs2_eraseblock *jeb;
+
+ node = invecs[0].iov_base;
+ jeb = &c->blocks[ofs / c->sector_size];
+ ofs -= jeb->offset;
+
+ switch (je16_to_cpu(node->u.nodetype)) {
+ case JFFS2_NODETYPE_INODE: {
+ struct jffs2_sum_inode_mem *temp =
+ kmalloc(sizeof(struct jffs2_sum_inode_mem), GFP_KERNEL);
+
+ if (!temp)
+ goto no_mem;
+
+ temp->nodetype = node->i.nodetype;
+ temp->inode = node->i.ino;
+ temp->version = node->i.version;
+ temp->offset = cpu_to_je32(ofs);
+ temp->totlen = node->i.totlen;
+ temp->next = NULL;
+
+ return jffs2_sum_add_mem(c->summary, (union jffs2_sum_mem *)temp);
+ }
+
+ case JFFS2_NODETYPE_DIRENT: {
+ struct jffs2_sum_dirent_mem *temp =
+ kmalloc(sizeof(struct jffs2_sum_dirent_mem) + node->d.nsize, GFP_KERNEL);
+
+ if (!temp)
+ goto no_mem;
+
+ temp->nodetype = node->d.nodetype;
+ temp->totlen = node->d.totlen;
+ temp->offset = cpu_to_je32(ofs);
+ temp->pino = node->d.pino;
+ temp->version = node->d.version;
+ temp->ino = node->d.ino;
+ temp->nsize = node->d.nsize;
+ temp->type = node->d.type;
+ temp->next = NULL;
+
+ switch (count) {
+ case 1:
+ memcpy(temp->name,node->d.name,node->d.nsize);
+ break;
+
+ case 2:
+ memcpy(temp->name,invecs[1].iov_base,node->d.nsize);
+ break;
+
+ default:
+ BUG(); /* impossible count value */
+ break;
+ }
+
+ return jffs2_sum_add_mem(c->summary, (union jffs2_sum_mem *)temp);
+ }
+
+ case JFFS2_NODETYPE_PADDING:
+ dbg_summary("node PADDING\n");
+ c->summary->sum_padded += je32_to_cpu(node->u.totlen);
+ break;
+
+ case JFFS2_NODETYPE_CLEANMARKER:
+ dbg_summary("node CLEANMARKER\n");
+ break;
+
+ case JFFS2_NODETYPE_SUMMARY:
+ dbg_summary("node SUMMARY\n");
+ break;
+
+ default:
+ /* If you implement a new node type you should also implement
+ summary support for it or disable summary.
+ */
+ BUG();
+ break;
+ }
+
+ return 0;
+
+no_mem:
+ JFFS2_WARNING("MEMORY ALLOCATION ERROR!");
+ return -ENOMEM;
+}
+
+
+/* Process the stored summary information - helper function for jffs2_sum_scan_sumnode() */
+
+static int jffs2_sum_process_sum_data(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
+ struct jffs2_raw_summary *summary, uint32_t *pseudo_random)
+{
+ struct jffs2_raw_node_ref *raw;
+ struct jffs2_inode_cache *ic;
+ struct jffs2_full_dirent *fd;
+ void *sp;
+ int i, ino;
+
+ sp = summary->sum;
+
+ for (i=0; i<je32_to_cpu(summary->sum_num); i++) {
+ dbg_summary("processing summary index %d\n", i);
+
+ switch (je16_to_cpu(((struct jffs2_sum_unknown_flash *)sp)->nodetype)) {
+ case JFFS2_NODETYPE_INODE: {
+ struct jffs2_sum_inode_flash *spi;
+ spi = sp;
+
+ ino = je32_to_cpu(spi->inode);
+
+ dbg_summary("Inode at 0x%08x\n",
+ jeb->offset + je32_to_cpu(spi->offset));
+
+ raw = jffs2_alloc_raw_node_ref();
+ if (!raw) {
+ JFFS2_NOTICE("allocation of node reference failed\n");
+ kfree(summary);
+ return -ENOMEM;
+ }
+
+ ic = jffs2_scan_make_ino_cache(c, ino);
+ if (!ic) {
+ JFFS2_NOTICE("scan_make_ino_cache failed\n");
+ jffs2_free_raw_node_ref(raw);
+ kfree(summary);
+ return -ENOMEM;
+ }
+
+ raw->flash_offset = (jeb->offset + je32_to_cpu(spi->offset)) | REF_UNCHECKED;
+ raw->__totlen = PAD(je32_to_cpu(spi->totlen));
+ raw->next_phys = NULL;
+ raw->next_in_ino = ic->nodes;
+
+ ic->nodes = raw;
+ if (!jeb->first_node)
+ jeb->first_node = raw;
+ if (jeb->last_node)
+ jeb->last_node->next_phys = raw;
+ jeb->last_node = raw;
+ *pseudo_random += je32_to_cpu(spi->version);
+
+ UNCHECKED_SPACE(PAD(je32_to_cpu(spi->totlen)));
+
+ sp += JFFS2_SUMMARY_INODE_SIZE;
+
+ break;
+ }
+
+ case JFFS2_NODETYPE_DIRENT: {
+ struct jffs2_sum_dirent_flash *spd;
+ spd = sp;
+
+ dbg_summary("Dirent at 0x%08x\n",
+ jeb->offset + je32_to_cpu(spd->offset));
+
+ fd = jffs2_alloc_full_dirent(spd->nsize+1);
+ if (!fd) {
+ kfree(summary);
+ return -ENOMEM;
+ }
+
+ memcpy(&fd->name, spd->name, spd->nsize);
+ fd->name[spd->nsize] = 0;
+
+ raw = jffs2_alloc_raw_node_ref();
+ if (!raw) {
+ jffs2_free_full_dirent(fd);
+ JFFS2_NOTICE("allocation of node reference failed\n");
+ kfree(summary);
+ return -ENOMEM;
+ }
+
+ ic = jffs2_scan_make_ino_cache(c, je32_to_cpu(spd->pino));
+ if (!ic) {
+ jffs2_free_full_dirent(fd);
+ jffs2_free_raw_node_ref(raw);
+ kfree(summary);
+ return -ENOMEM;
+ }
+
+ raw->__totlen = PAD(je32_to_cpu(spd->totlen));
+ raw->flash_offset = (jeb->offset + je32_to_cpu(spd->offset)) | REF_PRISTINE;
+ raw->next_phys = NULL;
+ raw->next_in_ino = ic->nodes;
+ ic->nodes = raw;
+ if (!jeb->first_node)
+ jeb->first_node = raw;
+ if (jeb->last_node)
+ jeb->last_node->next_phys = raw;
+ jeb->last_node = raw;
+
+ fd->raw = raw;
+ fd->next = NULL;
+ fd->version = je32_to_cpu(spd->version);
+ fd->ino = je32_to_cpu(spd->ino);
+ fd->nhash = full_name_hash(fd->name, spd->nsize);
+ fd->type = spd->type;
+ USED_SPACE(PAD(je32_to_cpu(spd->totlen)));
+ jffs2_add_fd_to_list(c, fd, &ic->scan_dents);
+
+ *pseudo_random += je32_to_cpu(spd->version);
+
+ sp += JFFS2_SUMMARY_DIRENT_SIZE(spd->nsize);
+
+ break;
+ }
+
+ default : {
+ JFFS2_WARNING("Unsupported node type found in summary! Exiting...");
+ kfree(summary);
+ return -EIO;
+ }
+ }
+ }
+
+ kfree(summary);
+ return 0;
+}
+
+/* Process the summary node - called from jffs2_scan_eraseblock() */
+
+int jffs2_sum_scan_sumnode(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
+ uint32_t ofs, uint32_t *pseudo_random)
+{
+ struct jffs2_unknown_node crcnode;
+ struct jffs2_raw_node_ref *cache_ref;
+ struct jffs2_raw_summary *summary;
+ int ret, sumsize;
+ uint32_t crc;
+
+ sumsize = c->sector_size - ofs;
+ ofs += jeb->offset;
+
+ dbg_summary("summary found for 0x%08x at 0x%08x (0x%x bytes)\n",
+ jeb->offset, ofs, sumsize);
+
+ summary = kmalloc(sumsize, GFP_KERNEL);
+
+ if (!summary) {
+ return -ENOMEM;
+ }
+
+ ret = jffs2_fill_scan_buf(c, (unsigned char *)summary, ofs, sumsize);
+
+ if (ret) {
+ kfree(summary);
+ return ret;
+ }
+
+ /* OK, now check for node validity and CRC */
+ crcnode.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
+ crcnode.nodetype = cpu_to_je16(JFFS2_NODETYPE_SUMMARY);
+ crcnode.totlen = summary->totlen;
+ crc = crc32(0, &crcnode, sizeof(crcnode)-4);
+
+ if (je32_to_cpu(summary->hdr_crc) != crc) {
+ dbg_summary("Summary node header is corrupt (bad CRC or "
+ "no summary at all)\n");
+ goto crc_err;
+ }
+
+ if (je32_to_cpu(summary->totlen) != sumsize) {
+ dbg_summary("Summary node is corrupt (wrong erasesize?)\n");
+ goto crc_err;
+ }
+
+ crc = crc32(0, summary, sizeof(struct jffs2_raw_summary)-8);
+
+ if (je32_to_cpu(summary->node_crc) != crc) {
+ dbg_summary("Summary node is corrupt (bad CRC)\n");
+ goto crc_err;
+ }
+
+ crc = crc32(0, summary->sum, sumsize - sizeof(struct jffs2_raw_summary));
+
+ if (je32_to_cpu(summary->sum_crc) != crc) {
+ dbg_summary("Summary node data is corrupt (bad CRC)\n");
+ goto crc_err;
+ }
+
+ if ( je32_to_cpu(summary->cln_mkr) ) {
+
+ dbg_summary("Summary : CLEANMARKER node \n");
+
+ if (je32_to_cpu(summary->cln_mkr) != c->cleanmarker_size) {
+ dbg_summary("CLEANMARKER node has totlen 0x%x != normal 0x%x\n",
+ je32_to_cpu(summary->cln_mkr), c->cleanmarker_size);
+ UNCHECKED_SPACE(PAD(je32_to_cpu(summary->cln_mkr)));
+ } else if (jeb->first_node) {
+ dbg_summary("CLEANMARKER node not first node in block "
+ "(0x%08x)\n", jeb->offset);
+ UNCHECKED_SPACE(PAD(je32_to_cpu(summary->cln_mkr)));
+ } else {
+ struct jffs2_raw_node_ref *marker_ref = jffs2_alloc_raw_node_ref();
+
+ if (!marker_ref) {
+ JFFS2_NOTICE("Failed to allocate node ref for clean marker\n");
+ kfree(summary);
+ return -ENOMEM;
+ }
+
+ marker_ref->next_in_ino = NULL;
+ marker_ref->next_phys = NULL;
+ marker_ref->flash_offset = jeb->offset | REF_NORMAL;
+ marker_ref->__totlen = je32_to_cpu(summary->cln_mkr);
+ jeb->first_node = jeb->last_node = marker_ref;
+
+ USED_SPACE( PAD(je32_to_cpu(summary->cln_mkr)) );
+ }
+ }
+
+ if (je32_to_cpu(summary->padded)) {
+ DIRTY_SPACE(je32_to_cpu(summary->padded));
+ }
+
+ ret = jffs2_sum_process_sum_data(c, jeb, summary, pseudo_random);
+ if (ret)
+ return ret;
+
+ /* for PARANOIA_CHECK */
+ cache_ref = jffs2_alloc_raw_node_ref();
+
+ if (!cache_ref) {
+ JFFS2_NOTICE("Failed to allocate node ref for cache\n");
+ return -ENOMEM;
+ }
+
+ cache_ref->next_in_ino = NULL;
+ cache_ref->next_phys = NULL;
+ cache_ref->flash_offset = ofs | REF_NORMAL;
+ cache_ref->__totlen = sumsize;
+
+ if (!jeb->first_node)
+ jeb->first_node = cache_ref;
+ if (jeb->last_node)
+ jeb->last_node->next_phys = cache_ref;
+ jeb->last_node = cache_ref;
+
+ USED_SPACE(sumsize);
+
+ jeb->wasted_size += jeb->free_size;
+ c->wasted_size += jeb->free_size;
+ c->free_size -= jeb->free_size;
+ jeb->free_size = 0;
+
+ return jffs2_scan_classify_jeb(c, jeb);
+
+crc_err:
+ JFFS2_WARNING("Summary node crc error, skipping summary information.\n");
+
+ return 0;
+}
+
+/* Write summary data to flash - helper function for jffs2_sum_write_sumnode() */
+
+static int jffs2_sum_write_data(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
+ uint32_t infosize, uint32_t datasize, int padsize)
+{
+ struct jffs2_raw_summary isum;
+ union jffs2_sum_mem *temp;
+ struct jffs2_sum_marker *sm;
+ struct kvec vecs[2];
+ void *wpage;
+ int ret;
+ size_t retlen;
+
+ memset(c->summary->sum_buf, 0xff, datasize);
+ memset(&isum, 0, sizeof(isum));
+
+ isum.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
+ isum.nodetype = cpu_to_je16(JFFS2_NODETYPE_SUMMARY);
+ isum.totlen = cpu_to_je32(infosize);
+ isum.hdr_crc = cpu_to_je32(crc32(0, &isum, sizeof(struct jffs2_unknown_node) - 4));
+ isum.padded = cpu_to_je32(c->summary->sum_padded);
+ isum.cln_mkr = cpu_to_je32(c->cleanmarker_size);
+ isum.sum_num = cpu_to_je32(c->summary->sum_num);
+ wpage = c->summary->sum_buf;
+
+ while (c->summary->sum_num) {
+
+ switch (je16_to_cpu(c->summary->sum_list_head->u.nodetype)) {
+ case JFFS2_NODETYPE_INODE: {
+ struct jffs2_sum_inode_flash *sino_ptr = wpage;
+
+ sino_ptr->nodetype = c->summary->sum_list_head->i.nodetype;
+ sino_ptr->inode = c->summary->sum_list_head->i.inode;
+ sino_ptr->version = c->summary->sum_list_head->i.version;
+ sino_ptr->offset = c->summary->sum_list_head->i.offset;
+ sino_ptr->totlen = c->summary->sum_list_head->i.totlen;
+
+ wpage += JFFS2_SUMMARY_INODE_SIZE;
+
+ break;
+ }
+
+ case JFFS2_NODETYPE_DIRENT: {
+ struct jffs2_sum_dirent_flash *sdrnt_ptr = wpage;
+
+ sdrnt_ptr->nodetype = c->summary->sum_list_head->d.nodetype;
+ sdrnt_ptr->totlen = c->summary->sum_list_head->d.totlen;
+ sdrnt_ptr->offset = c->summary->sum_list_head->d.offset;
+ sdrnt_ptr->pino = c->summary->sum_list_head->d.pino;
+ sdrnt_ptr->version = c->summary->sum_list_head->d.version;
+ sdrnt_ptr->ino = c->summary->sum_list_head->d.ino;
+ sdrnt_ptr->nsize = c->summary->sum_list_head->d.nsize;
+ sdrnt_ptr->type = c->summary->sum_list_head->d.type;
+
+ memcpy(sdrnt_ptr->name, c->summary->sum_list_head->d.name,
+ c->summary->sum_list_head->d.nsize);
+
+ wpage += JFFS2_SUMMARY_DIRENT_SIZE(c->summary->sum_list_head->d.nsize);
+
+ break;
+ }
+
+ default : {
+ BUG(); /* unknown node in summary information */
+ }
+ }
+
+ temp = c->summary->sum_list_head;
+ c->summary->sum_list_head = c->summary->sum_list_head->u.next;
+ kfree(temp);
+
+ c->summary->sum_num--;
+ }
+
+ jffs2_sum_reset_collected(c->summary);
+
+ wpage += padsize;
+
+ sm = wpage;
+ sm->offset = cpu_to_je32(c->sector_size - jeb->free_size);
+ sm->magic = cpu_to_je32(JFFS2_SUM_MAGIC);
+
+ isum.sum_crc = cpu_to_je32(crc32(0, c->summary->sum_buf, datasize));
+ isum.node_crc = cpu_to_je32(crc32(0, &isum, sizeof(isum) - 8));
+
+ vecs[0].iov_base = &isum;
+ vecs[0].iov_len = sizeof(isum);
+ vecs[1].iov_base = c->summary->sum_buf;
+ vecs[1].iov_len = datasize;
+
+ dbg_summary("JFFS2: writing out data to flash to pos : 0x%08x\n",
+ jeb->offset + c->sector_size - jeb->free_size);
+
+ spin_unlock(&c->erase_completion_lock);
+ ret = jffs2_flash_writev(c, vecs, 2, jeb->offset + c->sector_size -
+ jeb->free_size, &retlen, 0);
+ spin_lock(&c->erase_completion_lock);
+
+
+ if (ret || (retlen != infosize)) {
+ JFFS2_WARNING("Write of %zd bytes at 0x%08x failed. returned %d, retlen %zd\n",
+ infosize, jeb->offset + c->sector_size - jeb->free_size, ret, retlen);
+
+ c->summary->sum_size = JFFS2_SUMMARY_NOSUM_SIZE;
+ WASTED_SPACE(infosize);
+
+ return 1;
+ }
+
+ return 0;
+}
+
+/* Write out summary information - called from jffs2_do_reserve_space */
+
+int jffs2_sum_write_sumnode(struct jffs2_sb_info *c)
+{
+ struct jffs2_raw_node_ref *summary_ref;
+ int datasize, infosize, padsize, ret;
+ struct jffs2_eraseblock *jeb;
+
+ dbg_summary("called\n");
+
+ jeb = c->nextblock;
+
+ if (!c->summary->sum_num || !c->summary->sum_list_head) {
+ JFFS2_WARNING("Empty summary info!!!\n");
+ BUG();
+ }
+
+ datasize = c->summary->sum_size + sizeof(struct jffs2_sum_marker);
+ infosize = sizeof(struct jffs2_raw_summary) + datasize;
+ padsize = jeb->free_size - infosize;
+ infosize += padsize;
+ datasize += padsize;
+
+ /* Is there enough space for summary? */
+ if (padsize < 0) {
+ /* don't try to write out summary for this jeb */
+ jffs2_sum_disable_collecting(c->summary);
+
+ JFFS2_WARNING("Not enough space for summary, padsize = %d\n", padsize);
+ return 0;
+ }
+
+ ret = jffs2_sum_write_data(c, jeb, infosize, datasize, padsize);
+ if (ret)
+ return 0; /* can't write out summary, block is marked as NOSUM_SIZE */
+
+ /* for ACCT_PARANOIA_CHECK */
+ spin_unlock(&c->erase_completion_lock);
+ summary_ref = jffs2_alloc_raw_node_ref();
+ spin_lock(&c->erase_completion_lock);
+
+ if (!summary_ref) {
+ JFFS2_NOTICE("Failed to allocate node ref for summary\n");
+ return -ENOMEM;
+ }
+
+ summary_ref->next_in_ino = NULL;
+ summary_ref->next_phys = NULL;
+ summary_ref->flash_offset = (jeb->offset + c->sector_size - jeb->free_size) | REF_NORMAL;
+ summary_ref->__totlen = infosize;
+
+ if (!jeb->first_node)
+ jeb->first_node = summary_ref;
+ if (jeb->last_node)
+ jeb->last_node->next_phys = summary_ref;
+ jeb->last_node = summary_ref;
+
+ USED_SPACE(infosize);
+
+ return 0;
+}
diff --git a/fs/jffs2/summary.h b/fs/jffs2/summary.h
new file mode 100644
index 000000000000..b7a678be1709
--- /dev/null
+++ b/fs/jffs2/summary.h
@@ -0,0 +1,183 @@
+/*
+ * JFFS2 -- Journalling Flash File System, Version 2.
+ *
+ * Copyright (C) 2004 Ferenc Havasi <havasi@inf.u-szeged.hu>,
+ * Zoltan Sogor <weth@inf.u-szeged.hu>,
+ * Patrik Kluba <pajko@halom.u-szeged.hu>,
+ * University of Szeged, Hungary
+ *
+ * For licensing information, see the file 'LICENCE' in this directory.
+ *
+ * $Id: summary.h,v 1.2 2005/09/26 11:37:21 havasi Exp $
+ *
+ */
+
+#ifndef JFFS2_SUMMARY_H
+#define JFFS2_SUMMARY_H
+
+#include <linux/uio.h>
+#include <linux/jffs2.h>
+
+#define DIRTY_SPACE(x) do { typeof(x) _x = (x); \
+ c->free_size -= _x; c->dirty_size += _x; \
+ jeb->free_size -= _x ; jeb->dirty_size += _x; \
+ }while(0)
+#define USED_SPACE(x) do { typeof(x) _x = (x); \
+ c->free_size -= _x; c->used_size += _x; \
+ jeb->free_size -= _x ; jeb->used_size += _x; \
+ }while(0)
+#define WASTED_SPACE(x) do { typeof(x) _x = (x); \
+ c->free_size -= _x; c->wasted_size += _x; \
+ jeb->free_size -= _x ; jeb->wasted_size += _x; \
+ }while(0)
+#define UNCHECKED_SPACE(x) do { typeof(x) _x = (x); \
+ c->free_size -= _x; c->unchecked_size += _x; \
+ jeb->free_size -= _x ; jeb->unchecked_size += _x; \
+ }while(0)
+
+#define BLK_STATE_ALLFF 0
+#define BLK_STATE_CLEAN 1
+#define BLK_STATE_PARTDIRTY 2
+#define BLK_STATE_CLEANMARKER 3
+#define BLK_STATE_ALLDIRTY 4
+#define BLK_STATE_BADBLOCK 5
+
+#define JFFS2_SUMMARY_NOSUM_SIZE 0xffffffff
+#define JFFS2_SUMMARY_INODE_SIZE (sizeof(struct jffs2_sum_inode_flash))
+#define JFFS2_SUMMARY_DIRENT_SIZE(x) (sizeof(struct jffs2_sum_dirent_flash) + (x))
+
+/* Summary structures used on flash */
+
+struct jffs2_sum_unknown_flash
+{
+ jint16_t nodetype; /* node type */
+};
+
+struct jffs2_sum_inode_flash
+{
+ jint16_t nodetype; /* node type */
+ jint32_t inode; /* inode number */
+ jint32_t version; /* inode version */
+ jint32_t offset; /* offset on jeb */
+ jint32_t totlen; /* record length */
+} __attribute__((packed));
+
+struct jffs2_sum_dirent_flash
+{
+ jint16_t nodetype; /* == JFFS_NODETYPE_DIRENT */
+ jint32_t totlen; /* record length */
+ jint32_t offset; /* offset on jeb */
+ jint32_t pino; /* parent inode */
+ jint32_t version; /* dirent version */
+ jint32_t ino; /* == zero for unlink */
+ uint8_t nsize; /* dirent name size */
+ uint8_t type; /* dirent type */
+ uint8_t name[0]; /* dirent name */
+} __attribute__((packed));
+
+union jffs2_sum_flash
+{
+ struct jffs2_sum_unknown_flash u;
+ struct jffs2_sum_inode_flash i;
+ struct jffs2_sum_dirent_flash d;
+};
+
+/* Summary structures used in the memory */
+
+struct jffs2_sum_unknown_mem
+{
+ union jffs2_sum_mem *next;
+ jint16_t nodetype; /* node type */
+};
+
+struct jffs2_sum_inode_mem
+{
+ union jffs2_sum_mem *next;
+ jint16_t nodetype; /* node type */
+ jint32_t inode; /* inode number */
+ jint32_t version; /* inode version */
+ jint32_t offset; /* offset on jeb */
+ jint32_t totlen; /* record length */
+} __attribute__((packed));
+
+struct jffs2_sum_dirent_mem
+{
+ union jffs2_sum_mem *next;
+ jint16_t nodetype; /* == JFFS_NODETYPE_DIRENT */
+ jint32_t totlen; /* record length */
+ jint32_t offset; /* ofset on jeb */
+ jint32_t pino; /* parent inode */
+ jint32_t version; /* dirent version */
+ jint32_t ino; /* == zero for unlink */
+ uint8_t nsize; /* dirent name size */
+ uint8_t type; /* dirent type */
+ uint8_t name[0]; /* dirent name */
+} __attribute__((packed));
+
+union jffs2_sum_mem
+{
+ struct jffs2_sum_unknown_mem u;
+ struct jffs2_sum_inode_mem i;
+ struct jffs2_sum_dirent_mem d;
+};
+
+/* Summary related information stored in superblock */
+
+struct jffs2_summary
+{
+ uint32_t sum_size; /* collected summary information for nextblock */
+ uint32_t sum_num;
+ uint32_t sum_padded;
+ union jffs2_sum_mem *sum_list_head;
+ union jffs2_sum_mem *sum_list_tail;
+
+ jint32_t *sum_buf; /* buffer for writing out summary */
+};
+
+/* Summary marker is stored at the end of every sumarized erase block */
+
+struct jffs2_sum_marker
+{
+ jint32_t offset; /* offset of the summary node in the jeb */
+ jint32_t magic; /* == JFFS2_SUM_MAGIC */
+};
+
+#define JFFS2_SUMMARY_FRAME_SIZE (sizeof(struct jffs2_raw_summary) + sizeof(struct jffs2_sum_marker))
+
+#ifdef CONFIG_JFFS2_SUMMARY /* SUMMARY SUPPORT ENABLED */
+
+#define jffs2_sum_active() (1)
+int jffs2_sum_init(struct jffs2_sb_info *c);
+void jffs2_sum_exit(struct jffs2_sb_info *c);
+void jffs2_sum_disable_collecting(struct jffs2_summary *s);
+int jffs2_sum_is_disabled(struct jffs2_summary *s);
+void jffs2_sum_reset_collected(struct jffs2_summary *s);
+void jffs2_sum_move_collected(struct jffs2_sb_info *c, struct jffs2_summary *s);
+int jffs2_sum_add_kvec(struct jffs2_sb_info *c, const struct kvec *invecs,
+ unsigned long count, uint32_t to);
+int jffs2_sum_write_sumnode(struct jffs2_sb_info *c);
+int jffs2_sum_add_padding_mem(struct jffs2_summary *s, uint32_t size);
+int jffs2_sum_add_inode_mem(struct jffs2_summary *s, struct jffs2_raw_inode *ri, uint32_t ofs);
+int jffs2_sum_add_dirent_mem(struct jffs2_summary *s, struct jffs2_raw_dirent *rd, uint32_t ofs);
+int jffs2_sum_scan_sumnode(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
+ uint32_t ofs, uint32_t *pseudo_random);
+
+#else /* SUMMARY DISABLED */
+
+#define jffs2_sum_active() (0)
+#define jffs2_sum_init(a) (0)
+#define jffs2_sum_exit(a)
+#define jffs2_sum_disable_collecting(a)
+#define jffs2_sum_is_disabled(a) (0)
+#define jffs2_sum_reset_collected(a)
+#define jffs2_sum_add_kvec(a,b,c,d) (0)
+#define jffs2_sum_move_collected(a,b)
+#define jffs2_sum_write_sumnode(a) (0)
+#define jffs2_sum_add_padding_mem(a,b)
+#define jffs2_sum_add_inode_mem(a,b,c)
+#define jffs2_sum_add_dirent_mem(a,b,c)
+#define jffs2_sum_scan_sumnode(a,b,c,d) (0)
+
+#endif /* CONFIG_JFFS2_SUMMARY */
+
+#endif /* JFFS2_SUMMARY_H */
diff --git a/fs/jffs2/super.c b/fs/jffs2/super.c
index aaf9475cfb6a..9e0b5458d9c0 100644
--- a/fs/jffs2/super.c
+++ b/fs/jffs2/super.c
@@ -7,7 +7,7 @@
*
* For licensing information, see the file 'LICENCE' in this directory.
*
- * $Id: super.c,v 1.107 2005/07/12 16:37:08 dedekind Exp $
+ * $Id: super.c,v 1.110 2005/11/07 11:14:42 gleixner Exp $
*
*/
@@ -62,7 +62,7 @@ static int jffs2_sync_fs(struct super_block *sb, int wait)
down(&c->alloc_sem);
jffs2_flush_wbuf_pad(c);
- up(&c->alloc_sem);
+ up(&c->alloc_sem);
return 0;
}
@@ -112,7 +112,7 @@ static int jffs2_sb_set(struct super_block *sb, void *data)
}
static struct super_block *jffs2_get_sb_mtd(struct file_system_type *fs_type,
- int flags, const char *dev_name,
+ int flags, const char *dev_name,
void *data, struct mtd_info *mtd)
{
struct super_block *sb;
@@ -172,7 +172,7 @@ static struct super_block *jffs2_get_sb_mtd(struct file_system_type *fs_type,
}
static struct super_block *jffs2_get_sb_mtdnr(struct file_system_type *fs_type,
- int flags, const char *dev_name,
+ int flags, const char *dev_name,
void *data, int mtdnr)
{
struct mtd_info *mtd;
@@ -201,7 +201,7 @@ static struct super_block *jffs2_get_sb(struct file_system_type *fs_type,
/* The preferred way of mounting in future; especially when
CONFIG_BLK_DEV is implemented - we specify the underlying
- MTD device by number or by name, so that we don't require
+ MTD device by number or by name, so that we don't require
block device support to be present in the kernel. */
/* FIXME: How to do the root fs this way? */
@@ -225,7 +225,7 @@ static struct super_block *jffs2_get_sb(struct file_system_type *fs_type,
} else if (isdigit(dev_name[3])) {
/* Mount by MTD device number name */
char *endptr;
-
+
mtdnr = simple_strtoul(dev_name+3, &endptr, 0);
if (!*endptr) {
/* It was a valid number */
@@ -235,7 +235,7 @@ static struct super_block *jffs2_get_sb(struct file_system_type *fs_type,
}
}
- /* Try the old way - the hack where we allowed users to mount
+ /* Try the old way - the hack where we allowed users to mount
/dev/mtdblock$(n) but didn't actually _use_ the blkdev */
err = path_lookup(dev_name, LOOKUP_FOLLOW, &nd);
@@ -282,9 +282,12 @@ static void jffs2_put_super (struct super_block *sb)
down(&c->alloc_sem);
jffs2_flush_wbuf_pad(c);
up(&c->alloc_sem);
+
+ jffs2_sum_exit(c);
+
jffs2_free_ino_caches(c);
jffs2_free_raw_node_refs(c);
- if (c->mtd->flags & MTD_NO_VIRTBLOCKS)
+ if (jffs2_blocks_use_vmalloc(c))
vfree(c->blocks);
else
kfree(c->blocks);
@@ -321,6 +324,9 @@ static int __init init_jffs2_fs(void)
#ifdef CONFIG_JFFS2_FS_WRITEBUFFER
" (NAND)"
#endif
+#ifdef CONFIG_JFFS2_SUMMARY
+ " (SUMMARY) "
+#endif
" (C) 2001-2003 Red Hat, Inc.\n");
jffs2_inode_cachep = kmem_cache_create("jffs2_i",
@@ -370,5 +376,5 @@ module_exit(exit_jffs2_fs);
MODULE_DESCRIPTION("The Journalling Flash File System, v2");
MODULE_AUTHOR("Red Hat, Inc.");
-MODULE_LICENSE("GPL"); // Actually dual-licensed, but it doesn't matter for
+MODULE_LICENSE("GPL"); // Actually dual-licensed, but it doesn't matter for
// the sake of this tag. It's Free Software.
diff --git a/fs/jffs2/symlink.c b/fs/jffs2/symlink.c
index 82ef484f5e12..d55754fe8925 100644
--- a/fs/jffs2/symlink.c
+++ b/fs/jffs2/symlink.c
@@ -7,7 +7,7 @@
*
* For licensing information, see the file 'LICENCE' in this directory.
*
- * $Id: symlink.c,v 1.16 2005/03/01 10:50:48 dedekind Exp $
+ * $Id: symlink.c,v 1.19 2005/11/07 11:14:42 gleixner Exp $
*
*/
@@ -21,7 +21,7 @@
static void *jffs2_follow_link(struct dentry *dentry, struct nameidata *nd);
struct inode_operations jffs2_symlink_inode_operations =
-{
+{
.readlink = generic_readlink,
.follow_link = jffs2_follow_link,
.setattr = jffs2_setattr
@@ -30,35 +30,33 @@ struct inode_operations jffs2_symlink_inode_operations =
static void *jffs2_follow_link(struct dentry *dentry, struct nameidata *nd)
{
struct jffs2_inode_info *f = JFFS2_INODE_INFO(dentry->d_inode);
- char *p = (char *)f->dents;
-
+ char *p = (char *)f->target;
+
/*
* We don't acquire the f->sem mutex here since the only data we
- * use is f->dents which in case of the symlink inode points to the
- * symlink's target path.
+ * use is f->target.
*
- * 1. If we are here the inode has already built and f->dents has
+ * 1. If we are here the inode has already built and f->target has
* to point to the target path.
- * 2. Nobody uses f->dents (if the inode is symlink's inode). The
- * exception is inode freeing function which frees f->dents. But
+ * 2. Nobody uses f->target (if the inode is symlink's inode). The
+ * exception is inode freeing function which frees f->target. But
* it can't be called while we are here and before VFS has
- * stopped using our f->dents string which we provide by means of
+ * stopped using our f->target string which we provide by means of
* nd_set_link() call.
*/
-
+
if (!p) {
printk(KERN_ERR "jffs2_follow_link(): can't find symlink taerget\n");
p = ERR_PTR(-EIO);
- } else {
- D1(printk(KERN_DEBUG "jffs2_follow_link(): target path is '%s'\n", (char *) f->dents));
}
+ D1(printk(KERN_DEBUG "jffs2_follow_link(): target path is '%s'\n", (char *) f->target));
nd_set_link(nd, p);
-
+
/*
- * We unlock the f->sem mutex but VFS will use the f->dents string. This is safe
- * since the only way that may cause f->dents to be changed is iput() operation.
- * But VFS will not use f->dents after iput() has been called.
+ * We will unlock the f->sem mutex but VFS will use the f->target string. This is safe
+ * since the only way that may cause f->target to be changed is iput() operation.
+ * But VFS will not use f->target after iput() has been called.
*/
return NULL;
}
diff --git a/fs/jffs2/wbuf.c b/fs/jffs2/wbuf.c
index 996d922e503e..4cebf0e57c46 100644
--- a/fs/jffs2/wbuf.c
+++ b/fs/jffs2/wbuf.c
@@ -9,7 +9,7 @@
*
* For licensing information, see the file 'LICENCE' in this directory.
*
- * $Id: wbuf.c,v 1.92 2005/04/05 12:51:54 dedekind Exp $
+ * $Id: wbuf.c,v 1.100 2005/09/30 13:59:13 dedekind Exp $
*
*/
@@ -18,6 +18,8 @@
#include <linux/mtd/mtd.h>
#include <linux/crc32.h>
#include <linux/mtd/nand.h>
+#include <linux/jiffies.h>
+
#include "nodelist.h"
/* For testing write failures */
@@ -28,12 +30,12 @@
static unsigned char *brokenbuf;
#endif
+#define PAGE_DIV(x) ( ((unsigned long)(x) / (unsigned long)(c->wbuf_pagesize)) * (unsigned long)(c->wbuf_pagesize) )
+#define PAGE_MOD(x) ( (unsigned long)(x) % (unsigned long)(c->wbuf_pagesize) )
+
/* max. erase failures before we mark a block bad */
#define MAX_ERASE_FAILURES 2
-/* two seconds timeout for timed wbuf-flushing */
-#define WBUF_FLUSH_TIMEOUT 2 * HZ
-
struct jffs2_inodirty {
uint32_t ino;
struct jffs2_inodirty *next;
@@ -137,7 +139,6 @@ static void jffs2_block_refile(struct jffs2_sb_info *c, struct jffs2_eraseblock
{
D1(printk("About to refile bad block at %08x\n", jeb->offset));
- D2(jffs2_dump_block_lists(c));
/* File the existing block on the bad_used_list.... */
if (c->nextblock == jeb)
c->nextblock = NULL;
@@ -154,7 +155,6 @@ static void jffs2_block_refile(struct jffs2_sb_info *c, struct jffs2_eraseblock
c->nr_erasing_blocks++;
jffs2_erase_pending_trigger(c);
}
- D2(jffs2_dump_block_lists(c));
/* Adjust its size counts accordingly */
c->wasted_size += jeb->free_size;
@@ -162,8 +162,9 @@ static void jffs2_block_refile(struct jffs2_sb_info *c, struct jffs2_eraseblock
jeb->wasted_size += jeb->free_size;
jeb->free_size = 0;
- ACCT_SANITY_CHECK(c,jeb);
- D1(ACCT_PARANOIA_CHECK(jeb));
+ jffs2_dbg_dump_block_lists_nolock(c);
+ jffs2_dbg_acct_sanity_check_nolock(c,jeb);
+ jffs2_dbg_acct_paranoia_check_nolock(c, jeb);
}
/* Recover from failure to write wbuf. Recover the nodes up to the
@@ -187,7 +188,7 @@ static void jffs2_wbuf_recover(struct jffs2_sb_info *c)
/* Find the first node to be recovered, by skipping over every
node which ends before the wbuf starts, or which is obsolete. */
first_raw = &jeb->first_node;
- while (*first_raw &&
+ while (*first_raw &&
(ref_obsolete(*first_raw) ||
(ref_offset(*first_raw)+ref_totlen(c, jeb, *first_raw)) < c->wbuf_ofs)) {
D1(printk(KERN_DEBUG "Skipping node at 0x%08x(%d)-0x%08x which is either before 0x%08x or obsolete\n",
@@ -236,7 +237,7 @@ static void jffs2_wbuf_recover(struct jffs2_sb_info *c)
ret = c->mtd->read_ecc(c->mtd, start, c->wbuf_ofs - start, &retlen, buf, NULL, c->oobinfo);
else
ret = c->mtd->read(c->mtd, start, c->wbuf_ofs - start, &retlen, buf);
-
+
if (ret == -EBADMSG && retlen == c->wbuf_ofs - start) {
/* ECC recovered */
ret = 0;
@@ -264,7 +265,7 @@ static void jffs2_wbuf_recover(struct jffs2_sb_info *c)
/* ... and get an allocation of space from a shiny new block instead */
- ret = jffs2_reserve_space_gc(c, end-start, &ofs, &len);
+ ret = jffs2_reserve_space_gc(c, end-start, &ofs, &len, JFFS2_SUMMARY_NOSUM_SIZE);
if (ret) {
printk(KERN_WARNING "Failed to allocate space for wbuf recovery. Data loss ensues.\n");
kfree(buf);
@@ -273,15 +274,15 @@ static void jffs2_wbuf_recover(struct jffs2_sb_info *c)
if (end-start >= c->wbuf_pagesize) {
/* Need to do another write immediately, but it's possible
that this is just because the wbuf itself is completely
- full, and there's nothing earlier read back from the
- flash. Hence 'buf' isn't necessarily what we're writing
+ full, and there's nothing earlier read back from the
+ flash. Hence 'buf' isn't necessarily what we're writing
from. */
unsigned char *rewrite_buf = buf?:c->wbuf;
uint32_t towrite = (end-start) - ((end-start)%c->wbuf_pagesize);
D1(printk(KERN_DEBUG "Write 0x%x bytes at 0x%08x in wbuf recover\n",
towrite, ofs));
-
+
#ifdef BREAKMEHEADER
static int breakme;
if (breakme++ == 20) {
@@ -325,8 +326,7 @@ static void jffs2_wbuf_recover(struct jffs2_sb_info *c)
c->wbuf_ofs = ofs + towrite;
memmove(c->wbuf, rewrite_buf + towrite, c->wbuf_len);
/* Don't muck about with c->wbuf_inodes. False positives are harmless. */
- if (buf)
- kfree(buf);
+ kfree(buf);
} else {
/* OK, now we're left with the dregs in whichever buffer we're using */
if (buf) {
@@ -390,11 +390,11 @@ static void jffs2_wbuf_recover(struct jffs2_sb_info *c)
else
jeb->last_node = container_of(first_raw, struct jffs2_raw_node_ref, next_phys);
- ACCT_SANITY_CHECK(c,jeb);
- D1(ACCT_PARANOIA_CHECK(jeb));
+ jffs2_dbg_acct_sanity_check_nolock(c, jeb);
+ jffs2_dbg_acct_paranoia_check_nolock(c, jeb);
- ACCT_SANITY_CHECK(c,new_jeb);
- D1(ACCT_PARANOIA_CHECK(new_jeb));
+ jffs2_dbg_acct_sanity_check_nolock(c, new_jeb);
+ jffs2_dbg_acct_paranoia_check_nolock(c, new_jeb);
spin_unlock(&c->erase_completion_lock);
@@ -433,15 +433,15 @@ static int __jffs2_flush_wbuf(struct jffs2_sb_info *c, int pad)
this happens, if we have a change to a new block,
or if fsync forces us to flush the writebuffer.
if we have a switch to next page, we will not have
- enough remaining space for this.
+ enough remaining space for this.
*/
- if (pad && !jffs2_dataflash(c)) {
+ if (pad ) {
c->wbuf_len = PAD(c->wbuf_len);
/* Pad with JFFS2_DIRTY_BITMASK initially. this helps out ECC'd NOR
with 8 byte page size */
memset(c->wbuf + c->wbuf_len, 0, c->wbuf_pagesize - c->wbuf_len);
-
+
if ( c->wbuf_len + sizeof(struct jffs2_unknown_node) < c->wbuf_pagesize) {
struct jffs2_unknown_node *padnode = (void *)(c->wbuf + c->wbuf_len);
padnode->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
@@ -452,7 +452,7 @@ static int __jffs2_flush_wbuf(struct jffs2_sb_info *c, int pad)
}
/* else jffs2_flash_writev has actually filled in the rest of the
buffer for us, and will deal with the node refs etc. later. */
-
+
#ifdef BREAKME
static int breakme;
if (breakme++ == 20) {
@@ -461,9 +461,9 @@ static int __jffs2_flush_wbuf(struct jffs2_sb_info *c, int pad)
c->mtd->write_ecc(c->mtd, c->wbuf_ofs, c->wbuf_pagesize,
&retlen, brokenbuf, NULL, c->oobinfo);
ret = -EIO;
- } else
+ } else
#endif
-
+
if (jffs2_cleanmarker_oob(c))
ret = c->mtd->write_ecc(c->mtd, c->wbuf_ofs, c->wbuf_pagesize, &retlen, c->wbuf, NULL, c->oobinfo);
else
@@ -486,7 +486,7 @@ static int __jffs2_flush_wbuf(struct jffs2_sb_info *c, int pad)
spin_lock(&c->erase_completion_lock);
/* Adjust free size of the block if we padded. */
- if (pad && !jffs2_dataflash(c)) {
+ if (pad) {
struct jffs2_eraseblock *jeb;
jeb = &c->blocks[c->wbuf_ofs / c->sector_size];
@@ -494,7 +494,7 @@ static int __jffs2_flush_wbuf(struct jffs2_sb_info *c, int pad)
D1(printk(KERN_DEBUG "jffs2_flush_wbuf() adjusting free_size of %sblock at %08x\n",
(jeb==c->nextblock)?"next":"", jeb->offset));
- /* wbuf_pagesize - wbuf_len is the amount of space that's to be
+ /* wbuf_pagesize - wbuf_len is the amount of space that's to be
padded. If there is less free space in the block than that,
something screwed up */
if (jeb->free_size < (c->wbuf_pagesize - c->wbuf_len)) {
@@ -522,9 +522,9 @@ static int __jffs2_flush_wbuf(struct jffs2_sb_info *c, int pad)
return 0;
}
-/* Trigger garbage collection to flush the write-buffer.
+/* Trigger garbage collection to flush the write-buffer.
If ino arg is zero, do it if _any_ real (i.e. not GC) writes are
- outstanding. If ino arg non-zero, do it only if a write for the
+ outstanding. If ino arg non-zero, do it only if a write for the
given inode is outstanding. */
int jffs2_flush_wbuf_gc(struct jffs2_sb_info *c, uint32_t ino)
{
@@ -603,15 +603,6 @@ int jffs2_flush_wbuf_pad(struct jffs2_sb_info *c)
return ret;
}
-
-#ifdef CONFIG_JFFS2_FS_WRITEBUFFER
-#define PAGE_DIV(x) ( ((unsigned long)(x) / (unsigned long)(c->wbuf_pagesize)) * (unsigned long)(c->wbuf_pagesize) )
-#define PAGE_MOD(x) ( (unsigned long)(x) % (unsigned long)(c->wbuf_pagesize) )
-#else
-#define PAGE_DIV(x) ( (x) & (~(c->wbuf_pagesize - 1)) )
-#define PAGE_MOD(x) ( (x) & (c->wbuf_pagesize - 1) )
-#endif
-
int jffs2_flash_writev(struct jffs2_sb_info *c, const struct kvec *invecs, unsigned long count, loff_t to, size_t *retlen, uint32_t ino)
{
struct kvec outvecs[3];
@@ -628,13 +619,13 @@ int jffs2_flash_writev(struct jffs2_sb_info *c, const struct kvec *invecs, unsig
/* If not NAND flash, don't bother */
if (!jffs2_is_writebuffered(c))
return jffs2_flash_direct_writev(c, invecs, count, to, retlen);
-
+
down_write(&c->wbuf_sem);
/* If wbuf_ofs is not initialized, set it to target address */
if (c->wbuf_ofs == 0xFFFFFFFF) {
c->wbuf_ofs = PAGE_DIV(to);
- c->wbuf_len = PAGE_MOD(to);
+ c->wbuf_len = PAGE_MOD(to);
memset(c->wbuf,0xff,c->wbuf_pagesize);
}
@@ -648,10 +639,10 @@ int jffs2_flash_writev(struct jffs2_sb_info *c, const struct kvec *invecs, unsig
memset(c->wbuf,0xff,c->wbuf_pagesize);
}
}
-
- /* Sanity checks on target address.
- It's permitted to write at PAD(c->wbuf_len+c->wbuf_ofs),
- and it's permitted to write at the beginning of a new
+
+ /* Sanity checks on target address.
+ It's permitted to write at PAD(c->wbuf_len+c->wbuf_ofs),
+ and it's permitted to write at the beginning of a new
erase block. Anything else, and you die.
New block starts at xxx000c (0-b = block header)
*/
@@ -669,8 +660,8 @@ int jffs2_flash_writev(struct jffs2_sb_info *c, const struct kvec *invecs, unsig
}
/* set pointer to new block */
c->wbuf_ofs = PAGE_DIV(to);
- c->wbuf_len = PAGE_MOD(to);
- }
+ c->wbuf_len = PAGE_MOD(to);
+ }
if (to != PAD(c->wbuf_ofs + c->wbuf_len)) {
/* We're not writing immediately after the writebuffer. Bad. */
@@ -690,21 +681,21 @@ int jffs2_flash_writev(struct jffs2_sb_info *c, const struct kvec *invecs, unsig
invec = 0;
outvec = 0;
- /* Fill writebuffer first, if already in use */
+ /* Fill writebuffer first, if already in use */
if (c->wbuf_len) {
uint32_t invec_ofs = 0;
- /* adjust alignment offset */
+ /* adjust alignment offset */
if (c->wbuf_len != PAGE_MOD(to)) {
c->wbuf_len = PAGE_MOD(to);
/* take care of alignment to next page */
if (!c->wbuf_len)
c->wbuf_len = c->wbuf_pagesize;
}
-
+
while(c->wbuf_len < c->wbuf_pagesize) {
uint32_t thislen;
-
+
if (invec == count)
goto alldone;
@@ -712,17 +703,17 @@ int jffs2_flash_writev(struct jffs2_sb_info *c, const struct kvec *invecs, unsig
if (thislen >= invecs[invec].iov_len)
thislen = invecs[invec].iov_len;
-
+
invec_ofs = thislen;
memcpy(c->wbuf + c->wbuf_len, invecs[invec].iov_base, thislen);
c->wbuf_len += thislen;
donelen += thislen;
/* Get next invec, if actual did not fill the buffer */
- if (c->wbuf_len < c->wbuf_pagesize)
+ if (c->wbuf_len < c->wbuf_pagesize)
invec++;
- }
-
+ }
+
/* write buffer is full, flush buffer */
ret = __jffs2_flush_wbuf(c, NOPAD);
if (ret) {
@@ -781,10 +772,10 @@ int jffs2_flash_writev(struct jffs2_sb_info *c, const struct kvec *invecs, unsig
/* We did cross a page boundary, so we write some now */
if (jffs2_cleanmarker_oob(c))
- ret = c->mtd->writev_ecc(c->mtd, outvecs, splitvec+1, outvec_to, &wbuf_retlen, NULL, c->oobinfo);
+ ret = c->mtd->writev_ecc(c->mtd, outvecs, splitvec+1, outvec_to, &wbuf_retlen, NULL, c->oobinfo);
else
ret = jffs2_flash_direct_writev(c, outvecs, splitvec+1, outvec_to, &wbuf_retlen);
-
+
if (ret < 0 || wbuf_retlen != PAGE_DIV(totlen)) {
/* At this point we have no problem,
c->wbuf is empty. However refile nextblock to avoid
@@ -801,7 +792,7 @@ int jffs2_flash_writev(struct jffs2_sb_info *c, const struct kvec *invecs, unsig
spin_unlock(&c->erase_completion_lock);
goto exit;
}
-
+
donelen += wbuf_retlen;
c->wbuf_ofs = PAGE_DIV(outvec_to) + PAGE_DIV(totlen);
@@ -835,11 +826,17 @@ int jffs2_flash_writev(struct jffs2_sb_info *c, const struct kvec *invecs, unsig
alldone:
*retlen = donelen;
+ if (jffs2_sum_active()) {
+ int res = jffs2_sum_add_kvec(c, invecs, count, (uint32_t) to);
+ if (res)
+ return res;
+ }
+
if (c->wbuf_len && ino)
jffs2_wbuf_dirties_inode(c, ino);
ret = 0;
-
+
exit:
up_write(&c->wbuf_sem);
return ret;
@@ -854,7 +851,7 @@ int jffs2_flash_write(struct jffs2_sb_info *c, loff_t ofs, size_t len, size_t *r
struct kvec vecs[1];
if (!jffs2_is_writebuffered(c))
- return c->mtd->write(c->mtd, ofs, len, retlen, buf);
+ return jffs2_flash_direct_write(c, ofs, len, retlen, buf);
vecs[0].iov_base = (unsigned char *) buf;
vecs[0].iov_len = len;
@@ -882,18 +879,18 @@ int jffs2_flash_read(struct jffs2_sb_info *c, loff_t ofs, size_t len, size_t *re
if ( (ret == -EBADMSG) && (*retlen == len) ) {
printk(KERN_WARNING "mtd->read(0x%zx bytes from 0x%llx) returned ECC error\n",
len, ofs);
- /*
- * We have the raw data without ECC correction in the buffer, maybe
+ /*
+ * We have the raw data without ECC correction in the buffer, maybe
* we are lucky and all data or parts are correct. We check the node.
* If data are corrupted node check will sort it out.
* We keep this block, it will fail on write or erase and the we
* mark it bad. Or should we do that now? But we should give him a chance.
- * Maybe we had a system crash or power loss before the ecc write or
+ * Maybe we had a system crash or power loss before the ecc write or
* a erase was completed.
* So we return success. :)
*/
ret = 0;
- }
+ }
/* if no writebuffer available or write buffer empty, return */
if (!c->wbuf_pagesize || !c->wbuf_len)
@@ -908,16 +905,16 @@ int jffs2_flash_read(struct jffs2_sb_info *c, loff_t ofs, size_t len, size_t *re
if (owbf > c->wbuf_len) /* is read beyond write buffer ? */
goto exit;
lwbf = c->wbuf_len - owbf; /* number of bytes to copy */
- if (lwbf > len)
+ if (lwbf > len)
lwbf = len;
- } else {
+ } else {
orbf = (c->wbuf_ofs - ofs); /* offset in read buffer */
if (orbf > len) /* is write beyond write buffer ? */
goto exit;
lwbf = len - orbf; /* number of bytes to copy */
- if (lwbf > c->wbuf_len)
+ if (lwbf > c->wbuf_len)
lwbf = c->wbuf_len;
- }
+ }
if (lwbf > 0)
memcpy(buf+orbf,c->wbuf+owbf,lwbf);
@@ -945,7 +942,7 @@ int jffs2_check_oob_empty( struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb
printk(KERN_NOTICE "jffs2_check_oob_empty(): allocation of temporary data buffer for oob check failed\n");
return -ENOMEM;
}
- /*
+ /*
* if mode = 0, we scan for a total empty oob area, else we have
* to take care of the cleanmarker in the first page of the block
*/
@@ -954,41 +951,41 @@ int jffs2_check_oob_empty( struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb
D1(printk(KERN_WARNING "jffs2_check_oob_empty(): Read OOB failed %d for block at %08x\n", ret, jeb->offset));
goto out;
}
-
+
if (retlen < len) {
D1(printk(KERN_WARNING "jffs2_check_oob_empty(): Read OOB return short read "
"(%zd bytes not %d) for block at %08x\n", retlen, len, jeb->offset));
ret = -EIO;
goto out;
}
-
+
/* Special check for first page */
for(i = 0; i < oob_size ; i++) {
/* Yeah, we know about the cleanmarker. */
- if (mode && i >= c->fsdata_pos &&
+ if (mode && i >= c->fsdata_pos &&
i < c->fsdata_pos + c->fsdata_len)
continue;
if (buf[i] != 0xFF) {
D2(printk(KERN_DEBUG "Found %02x at %x in OOB for %08x\n",
- buf[page+i], page+i, jeb->offset));
- ret = 1;
+ buf[i], i, jeb->offset));
+ ret = 1;
goto out;
}
}
- /* we know, we are aligned :) */
+ /* we know, we are aligned :) */
for (page = oob_size; page < len; page += sizeof(long)) {
unsigned long dat = *(unsigned long *)(&buf[page]);
if(dat != -1) {
- ret = 1;
+ ret = 1;
goto out;
}
}
out:
- kfree(buf);
-
+ kfree(buf);
+
return ret;
}
@@ -1070,7 +1067,7 @@ int jffs2_write_nand_cleanmarker(struct jffs2_sb_info *c, struct jffs2_erasebloc
n.totlen = cpu_to_je32(8);
ret = jffs2_flash_write_oob(c, jeb->offset + c->fsdata_pos, c->fsdata_len, &retlen, (unsigned char *)&n);
-
+
if (ret) {
D1(printk(KERN_WARNING "jffs2_write_nand_cleanmarker(): Write failed for block at %08x: error %d\n", jeb->offset, ret));
return ret;
@@ -1082,7 +1079,7 @@ int jffs2_write_nand_cleanmarker(struct jffs2_sb_info *c, struct jffs2_erasebloc
return 0;
}
-/*
+/*
* On NAND we try to mark this block bad. If the block was erased more
* than MAX_ERASE_FAILURES we mark it finaly bad.
* Don't care about failures. This block remains on the erase-pending
@@ -1103,7 +1100,7 @@ int jffs2_write_nand_badblock(struct jffs2_sb_info *c, struct jffs2_eraseblock *
D1(printk(KERN_WARNING "jffs2_write_nand_badblock(): Marking bad block at %08x\n", bad_offset));
ret = c->mtd->block_markbad(c->mtd, bad_offset);
-
+
if (ret) {
D1(printk(KERN_WARNING "jffs2_write_nand_badblock(): Write failed for block at %08x: error %d\n", jeb->offset, ret));
return ret;
@@ -1127,7 +1124,7 @@ static int jffs2_nand_set_oobinfo(struct jffs2_sb_info *c)
/* Do this only, if we have an oob buffer */
if (!c->mtd->oobsize)
return 0;
-
+
/* Cleanmarker is out-of-band, so inline size zero */
c->cleanmarker_size = 0;
@@ -1153,7 +1150,7 @@ static int jffs2_nand_set_oobinfo(struct jffs2_sb_info *c)
c->fsdata_len = NAND_JFFS2_OOB16_FSDALEN;
c->badblock_pos = 15;
break;
-
+
default:
D1(printk(KERN_DEBUG "JFFS2 on NAND. No autoplacment info found\n"));
return -EINVAL;
@@ -1170,7 +1167,7 @@ int jffs2_nand_flash_setup(struct jffs2_sb_info *c)
init_rwsem(&c->wbuf_sem);
c->wbuf_pagesize = c->mtd->oobblock;
c->wbuf_ofs = 0xFFFFFFFF;
-
+
c->wbuf = kmalloc(c->wbuf_pagesize, GFP_KERNEL);
if (!c->wbuf)
return -ENOMEM;
@@ -1196,17 +1193,41 @@ void jffs2_nand_flash_cleanup(struct jffs2_sb_info *c)
int jffs2_dataflash_setup(struct jffs2_sb_info *c) {
c->cleanmarker_size = 0; /* No cleanmarkers needed */
-
+
/* Initialize write buffer */
init_rwsem(&c->wbuf_sem);
- c->wbuf_pagesize = c->sector_size;
- c->wbuf_ofs = 0xFFFFFFFF;
+
+ c->wbuf_pagesize = c->mtd->erasesize;
+
+ /* Find a suitable c->sector_size
+ * - Not too much sectors
+ * - Sectors have to be at least 4 K + some bytes
+ * - All known dataflashes have erase sizes of 528 or 1056
+ * - we take at least 8 eraseblocks and want to have at least 8K size
+ * - The concatenation should be a power of 2
+ */
+
+ c->sector_size = 8 * c->mtd->erasesize;
+
+ while (c->sector_size < 8192) {
+ c->sector_size *= 2;
+ }
+
+ /* It may be necessary to adjust the flash size */
+ c->flash_size = c->mtd->size;
+
+ if ((c->flash_size % c->sector_size) != 0) {
+ c->flash_size = (c->flash_size / c->sector_size) * c->sector_size;
+ printk(KERN_WARNING "JFFS2 flash size adjusted to %dKiB\n", c->flash_size);
+ };
+
+ c->wbuf_ofs = 0xFFFFFFFF;
c->wbuf = kmalloc(c->wbuf_pagesize, GFP_KERNEL);
if (!c->wbuf)
return -ENOMEM;
- printk(KERN_INFO "JFFS2 write-buffering enabled (%i)\n", c->wbuf_pagesize);
+ printk(KERN_INFO "JFFS2 write-buffering enabled buffer (%d) erasesize (%d)\n", c->wbuf_pagesize, c->sector_size);
return 0;
}
@@ -1234,3 +1255,23 @@ int jffs2_nor_ecc_flash_setup(struct jffs2_sb_info *c) {
void jffs2_nor_ecc_flash_cleanup(struct jffs2_sb_info *c) {
kfree(c->wbuf);
}
+
+int jffs2_nor_wbuf_flash_setup(struct jffs2_sb_info *c) {
+ /* Cleanmarker currently occupies a whole programming region */
+ c->cleanmarker_size = MTD_PROGREGION_SIZE(c->mtd);
+
+ /* Initialize write buffer */
+ init_rwsem(&c->wbuf_sem);
+ c->wbuf_pagesize = MTD_PROGREGION_SIZE(c->mtd);
+ c->wbuf_ofs = 0xFFFFFFFF;
+
+ c->wbuf = kmalloc(c->wbuf_pagesize, GFP_KERNEL);
+ if (!c->wbuf)
+ return -ENOMEM;
+
+ return 0;
+}
+
+void jffs2_nor_wbuf_flash_cleanup(struct jffs2_sb_info *c) {
+ kfree(c->wbuf);
+}
diff --git a/fs/jffs2/write.c b/fs/jffs2/write.c
index 69100615d9ae..1342f0158e9b 100644
--- a/fs/jffs2/write.c
+++ b/fs/jffs2/write.c
@@ -7,7 +7,7 @@
*
* For licensing information, see the file 'LICENCE' in this directory.
*
- * $Id: write.c,v 1.92 2005/04/13 13:22:35 dwmw2 Exp $
+ * $Id: write.c,v 1.97 2005/11/07 11:14:42 gleixner Exp $
*
*/
@@ -54,35 +54,7 @@ int jffs2_do_new_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, uint
return 0;
}
-#if CONFIG_JFFS2_FS_DEBUG > 0
-static void writecheck(struct jffs2_sb_info *c, uint32_t ofs)
-{
- unsigned char buf[16];
- size_t retlen;
- int ret, i;
-
- ret = jffs2_flash_read(c, ofs, 16, &retlen, buf);
- if (ret || (retlen != 16)) {
- D1(printk(KERN_DEBUG "read failed or short in writecheck(). ret %d, retlen %zd\n", ret, retlen));
- return;
- }
- ret = 0;
- for (i=0; i<16; i++) {
- if (buf[i] != 0xff)
- ret = 1;
- }
- if (ret) {
- printk(KERN_WARNING "ARGH. About to write node to 0x%08x on flash, but there are data already there:\n", ofs);
- printk(KERN_WARNING "0x%08x: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
- ofs,
- buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7],
- buf[8], buf[9], buf[10], buf[11], buf[12], buf[13], buf[14], buf[15]);
- }
-}
-#endif
-
-
-/* jffs2_write_dnode - given a raw_inode, allocate a full_dnode for it,
+/* jffs2_write_dnode - given a raw_inode, allocate a full_dnode for it,
write it to the flash, link it into the existing inode/fragment list */
struct jffs2_full_dnode *jffs2_write_dnode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, struct jffs2_raw_inode *ri, const unsigned char *data, uint32_t datalen, uint32_t flash_ofs, int alloc_mode)
@@ -106,7 +78,7 @@ struct jffs2_full_dnode *jffs2_write_dnode(struct jffs2_sb_info *c, struct jffs2
vecs[1].iov_base = (unsigned char *)data;
vecs[1].iov_len = datalen;
- D1(writecheck(c, flash_ofs));
+ jffs2_dbg_prewrite_paranoia_check(c, flash_ofs, vecs[0].iov_len + vecs[1].iov_len);
if (je32_to_cpu(ri->totlen) != sizeof(*ri) + datalen) {
printk(KERN_WARNING "jffs2_write_dnode: ri->totlen (0x%08x) != sizeof(*ri) (0x%08zx) + datalen (0x%08x)\n", je32_to_cpu(ri->totlen), sizeof(*ri), datalen);
@@ -114,7 +86,7 @@ struct jffs2_full_dnode *jffs2_write_dnode(struct jffs2_sb_info *c, struct jffs2
raw = jffs2_alloc_raw_node_ref();
if (!raw)
return ERR_PTR(-ENOMEM);
-
+
fn = jffs2_alloc_full_dnode();
if (!fn) {
jffs2_free_raw_node_ref(raw);
@@ -138,7 +110,7 @@ struct jffs2_full_dnode *jffs2_write_dnode(struct jffs2_sb_info *c, struct jffs2
if ((alloc_mode!=ALLOC_GC) && (je32_to_cpu(ri->version) < f->highest_version)) {
BUG_ON(!retried);
D1(printk(KERN_DEBUG "jffs2_write_dnode : dnode_version %d, "
- "highest version %d -> updating dnode\n",
+ "highest version %d -> updating dnode\n",
je32_to_cpu(ri->version), f->highest_version));
ri->version = cpu_to_je32(++f->highest_version);
ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8));
@@ -148,7 +120,7 @@ struct jffs2_full_dnode *jffs2_write_dnode(struct jffs2_sb_info *c, struct jffs2
(alloc_mode==ALLOC_GC)?0:f->inocache->ino);
if (ret || (retlen != sizeof(*ri) + datalen)) {
- printk(KERN_NOTICE "Write of %zd bytes at 0x%08x failed. returned %d, retlen %zd\n",
+ printk(KERN_NOTICE "Write of %zd bytes at 0x%08x failed. returned %d, retlen %zd\n",
sizeof(*ri)+datalen, flash_ofs, ret, retlen);
/* Mark the space as dirtied */
@@ -156,10 +128,10 @@ struct jffs2_full_dnode *jffs2_write_dnode(struct jffs2_sb_info *c, struct jffs2
/* Doesn't belong to any inode */
raw->next_in_ino = NULL;
- /* Don't change raw->size to match retlen. We may have
+ /* Don't change raw->size to match retlen. We may have
written the node header already, and only the data will
seem corrupted, in which case the scan would skip over
- any node we write before the original intended end of
+ any node we write before the original intended end of
this node */
raw->flash_offset |= REF_OBSOLETE;
jffs2_add_physical_node_ref(c, raw);
@@ -176,26 +148,28 @@ struct jffs2_full_dnode *jffs2_write_dnode(struct jffs2_sb_info *c, struct jffs2
retried = 1;
D1(printk(KERN_DEBUG "Retrying failed write.\n"));
-
- ACCT_SANITY_CHECK(c,jeb);
- D1(ACCT_PARANOIA_CHECK(jeb));
+
+ jffs2_dbg_acct_sanity_check(c,jeb);
+ jffs2_dbg_acct_paranoia_check(c, jeb);
if (alloc_mode == ALLOC_GC) {
- ret = jffs2_reserve_space_gc(c, sizeof(*ri) + datalen, &flash_ofs, &dummy);
+ ret = jffs2_reserve_space_gc(c, sizeof(*ri) + datalen, &flash_ofs,
+ &dummy, JFFS2_SUMMARY_INODE_SIZE);
} else {
/* Locking pain */
up(&f->sem);
jffs2_complete_reservation(c);
-
- ret = jffs2_reserve_space(c, sizeof(*ri) + datalen, &flash_ofs, &dummy, alloc_mode);
+
+ ret = jffs2_reserve_space(c, sizeof(*ri) + datalen, &flash_ofs,
+ &dummy, alloc_mode, JFFS2_SUMMARY_INODE_SIZE);
down(&f->sem);
}
if (!ret) {
D1(printk(KERN_DEBUG "Allocated space at 0x%08x to retry failed write.\n", flash_ofs));
- ACCT_SANITY_CHECK(c,jeb);
- D1(ACCT_PARANOIA_CHECK(jeb));
+ jffs2_dbg_acct_sanity_check(c,jeb);
+ jffs2_dbg_acct_paranoia_check(c, jeb);
goto retry;
}
@@ -207,9 +181,9 @@ struct jffs2_full_dnode *jffs2_write_dnode(struct jffs2_sb_info *c, struct jffs2
return ERR_PTR(ret?ret:-EIO);
}
/* Mark the space used */
- /* If node covers at least a whole page, or if it starts at the
- beginning of a page and runs to the end of the file, or if
- it's a hole node, mark it REF_PRISTINE, else REF_NORMAL.
+ /* If node covers at least a whole page, or if it starts at the
+ beginning of a page and runs to the end of the file, or if
+ it's a hole node, mark it REF_PRISTINE, else REF_NORMAL.
*/
if ((je32_to_cpu(ri->dsize) >= PAGE_CACHE_SIZE) ||
( ((je32_to_cpu(ri->offset)&(PAGE_CACHE_SIZE-1))==0) &&
@@ -227,12 +201,12 @@ struct jffs2_full_dnode *jffs2_write_dnode(struct jffs2_sb_info *c, struct jffs2
spin_unlock(&c->erase_completion_lock);
D1(printk(KERN_DEBUG "jffs2_write_dnode wrote node at 0x%08x(%d) with dsize 0x%x, csize 0x%x, node_crc 0x%08x, data_crc 0x%08x, totlen 0x%08x\n",
- flash_ofs, ref_flags(raw), je32_to_cpu(ri->dsize),
+ flash_ofs, ref_flags(raw), je32_to_cpu(ri->dsize),
je32_to_cpu(ri->csize), je32_to_cpu(ri->node_crc),
je32_to_cpu(ri->data_crc), je32_to_cpu(ri->totlen)));
if (retried) {
- ACCT_SANITY_CHECK(c,NULL);
+ jffs2_dbg_acct_sanity_check(c,NULL);
}
return fn;
@@ -247,10 +221,9 @@ struct jffs2_full_dirent *jffs2_write_dirent(struct jffs2_sb_info *c, struct jff
int retried = 0;
int ret;
- D1(printk(KERN_DEBUG "jffs2_write_dirent(ino #%u, name at *0x%p \"%s\"->ino #%u, name_crc 0x%08x)\n",
+ D1(printk(KERN_DEBUG "jffs2_write_dirent(ino #%u, name at *0x%p \"%s\"->ino #%u, name_crc 0x%08x)\n",
je32_to_cpu(rd->pino), name, name, je32_to_cpu(rd->ino),
je32_to_cpu(rd->name_crc)));
- D1(writecheck(c, flash_ofs));
D1(if(je32_to_cpu(rd->hdr_crc) != crc32(0, rd, sizeof(struct jffs2_unknown_node)-4)) {
printk(KERN_CRIT "Eep. CRC not correct in jffs2_write_dirent()\n");
@@ -262,7 +235,9 @@ struct jffs2_full_dirent *jffs2_write_dirent(struct jffs2_sb_info *c, struct jff
vecs[0].iov_len = sizeof(*rd);
vecs[1].iov_base = (unsigned char *)name;
vecs[1].iov_len = namelen;
-
+
+ jffs2_dbg_prewrite_paranoia_check(c, flash_ofs, vecs[0].iov_len + vecs[1].iov_len);
+
raw = jffs2_alloc_raw_node_ref();
if (!raw)
@@ -301,7 +276,7 @@ struct jffs2_full_dirent *jffs2_write_dirent(struct jffs2_sb_info *c, struct jff
ret = jffs2_flash_writev(c, vecs, 2, flash_ofs, &retlen,
(alloc_mode==ALLOC_GC)?0:je32_to_cpu(rd->pino));
if (ret || (retlen != sizeof(*rd) + namelen)) {
- printk(KERN_NOTICE "Write of %zd bytes at 0x%08x failed. returned %d, retlen %zd\n",
+ printk(KERN_NOTICE "Write of %zd bytes at 0x%08x failed. returned %d, retlen %zd\n",
sizeof(*rd)+namelen, flash_ofs, ret, retlen);
/* Mark the space as dirtied */
if (retlen) {
@@ -322,24 +297,26 @@ struct jffs2_full_dirent *jffs2_write_dirent(struct jffs2_sb_info *c, struct jff
D1(printk(KERN_DEBUG "Retrying failed write.\n"));
- ACCT_SANITY_CHECK(c,jeb);
- D1(ACCT_PARANOIA_CHECK(jeb));
+ jffs2_dbg_acct_sanity_check(c,jeb);
+ jffs2_dbg_acct_paranoia_check(c, jeb);
if (alloc_mode == ALLOC_GC) {
- ret = jffs2_reserve_space_gc(c, sizeof(*rd) + namelen, &flash_ofs, &dummy);
+ ret = jffs2_reserve_space_gc(c, sizeof(*rd) + namelen, &flash_ofs,
+ &dummy, JFFS2_SUMMARY_DIRENT_SIZE(namelen));
} else {
/* Locking pain */
up(&f->sem);
jffs2_complete_reservation(c);
-
- ret = jffs2_reserve_space(c, sizeof(*rd) + namelen, &flash_ofs, &dummy, alloc_mode);
+
+ ret = jffs2_reserve_space(c, sizeof(*rd) + namelen, &flash_ofs,
+ &dummy, alloc_mode, JFFS2_SUMMARY_DIRENT_SIZE(namelen));
down(&f->sem);
}
if (!ret) {
D1(printk(KERN_DEBUG "Allocated space at 0x%08x to retry failed write.\n", flash_ofs));
- ACCT_SANITY_CHECK(c,jeb);
- D1(ACCT_PARANOIA_CHECK(jeb));
+ jffs2_dbg_acct_sanity_check(c,jeb);
+ jffs2_dbg_acct_paranoia_check(c, jeb);
goto retry;
}
D1(printk(KERN_DEBUG "Failed to allocate space to retry failed write: %d!\n", ret));
@@ -359,7 +336,7 @@ struct jffs2_full_dirent *jffs2_write_dirent(struct jffs2_sb_info *c, struct jff
spin_unlock(&c->erase_completion_lock);
if (retried) {
- ACCT_SANITY_CHECK(c,NULL);
+ jffs2_dbg_acct_sanity_check(c,NULL);
}
return fd;
@@ -369,7 +346,7 @@ struct jffs2_full_dirent *jffs2_write_dirent(struct jffs2_sb_info *c, struct jff
we don't have to go digging in struct inode or its equivalent. It should set:
mode, uid, gid, (starting)isize, atime, ctime, mtime */
int jffs2_write_inode_range(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
- struct jffs2_raw_inode *ri, unsigned char *buf,
+ struct jffs2_raw_inode *ri, unsigned char *buf,
uint32_t offset, uint32_t writelen, uint32_t *retlen)
{
int ret = 0;
@@ -377,7 +354,7 @@ int jffs2_write_inode_range(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
D1(printk(KERN_DEBUG "jffs2_write_inode_range(): Ino #%u, ofs 0x%x, len 0x%x\n",
f->inocache->ino, offset, writelen));
-
+
while(writelen) {
struct jffs2_full_dnode *fn;
unsigned char *comprbuf = NULL;
@@ -389,7 +366,8 @@ int jffs2_write_inode_range(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
retry:
D2(printk(KERN_DEBUG "jffs2_commit_write() loop: 0x%x to write to 0x%x\n", writelen, offset));
- ret = jffs2_reserve_space(c, sizeof(*ri) + JFFS2_MIN_DATA_LEN, &phys_ofs, &alloclen, ALLOC_NORMAL);
+ ret = jffs2_reserve_space(c, sizeof(*ri) + JFFS2_MIN_DATA_LEN, &phys_ofs,
+ &alloclen, ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE);
if (ret) {
D1(printk(KERN_DEBUG "jffs2_reserve_space returned %d\n", ret));
break;
@@ -473,10 +451,11 @@ int jffs2_do_create(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, str
uint32_t alloclen, phys_ofs;
int ret;
- /* Try to reserve enough space for both node and dirent.
- * Just the node will do for now, though
+ /* Try to reserve enough space for both node and dirent.
+ * Just the node will do for now, though
*/
- ret = jffs2_reserve_space(c, sizeof(*ri), &phys_ofs, &alloclen, ALLOC_NORMAL);
+ ret = jffs2_reserve_space(c, sizeof(*ri), &phys_ofs, &alloclen, ALLOC_NORMAL,
+ JFFS2_SUMMARY_INODE_SIZE);
D1(printk(KERN_DEBUG "jffs2_do_create(): reserved 0x%x bytes\n", alloclen));
if (ret) {
up(&f->sem);
@@ -498,15 +477,16 @@ int jffs2_do_create(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, str
jffs2_complete_reservation(c);
return PTR_ERR(fn);
}
- /* No data here. Only a metadata node, which will be
+ /* No data here. Only a metadata node, which will be
obsoleted by the first data write
*/
f->metadata = fn;
up(&f->sem);
jffs2_complete_reservation(c);
- ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen, ALLOC_NORMAL);
-
+ ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen,
+ ALLOC_NORMAL, JFFS2_SUMMARY_DIRENT_SIZE(namelen));
+
if (ret) {
/* Eep. */
D1(printk(KERN_DEBUG "jffs2_reserve_space() for dirent failed\n"));
@@ -539,9 +519,9 @@ int jffs2_do_create(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, str
fd = jffs2_write_dirent(c, dir_f, rd, name, namelen, phys_ofs, ALLOC_NORMAL);
jffs2_free_raw_dirent(rd);
-
+
if (IS_ERR(fd)) {
- /* dirent failed to write. Delete the inode normally
+ /* dirent failed to write. Delete the inode normally
as if it were the final unlink() */
jffs2_complete_reservation(c);
up(&dir_f->sem);
@@ -560,14 +540,15 @@ int jffs2_do_create(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, str
int jffs2_do_unlink(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f,
- const char *name, int namelen, struct jffs2_inode_info *dead_f)
+ const char *name, int namelen, struct jffs2_inode_info *dead_f,
+ uint32_t time)
{
struct jffs2_raw_dirent *rd;
struct jffs2_full_dirent *fd;
uint32_t alloclen, phys_ofs;
int ret;
- if (1 /* alternative branch needs testing */ ||
+ if (1 /* alternative branch needs testing */ ||
!jffs2_can_mark_obsolete(c)) {
/* We can't mark stuff obsolete on the medium. We need to write a deletion dirent */
@@ -575,7 +556,8 @@ int jffs2_do_unlink(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f,
if (!rd)
return -ENOMEM;
- ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen, ALLOC_DELETION);
+ ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen,
+ ALLOC_DELETION, JFFS2_SUMMARY_DIRENT_SIZE(namelen));
if (ret) {
jffs2_free_raw_dirent(rd);
return ret;
@@ -588,18 +570,18 @@ int jffs2_do_unlink(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f,
rd->nodetype = cpu_to_je16(JFFS2_NODETYPE_DIRENT);
rd->totlen = cpu_to_je32(sizeof(*rd) + namelen);
rd->hdr_crc = cpu_to_je32(crc32(0, rd, sizeof(struct jffs2_unknown_node)-4));
-
+
rd->pino = cpu_to_je32(dir_f->inocache->ino);
rd->version = cpu_to_je32(++dir_f->highest_version);
rd->ino = cpu_to_je32(0);
- rd->mctime = cpu_to_je32(get_seconds());
+ rd->mctime = cpu_to_je32(time);
rd->nsize = namelen;
rd->type = DT_UNKNOWN;
rd->node_crc = cpu_to_je32(crc32(0, rd, sizeof(*rd)-8));
rd->name_crc = cpu_to_je32(crc32(0, name, namelen));
fd = jffs2_write_dirent(c, dir_f, rd, name, namelen, phys_ofs, ALLOC_DELETION);
-
+
jffs2_free_raw_dirent(rd);
if (IS_ERR(fd)) {
@@ -618,7 +600,7 @@ int jffs2_do_unlink(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f,
down(&dir_f->sem);
while ((*prev) && (*prev)->nhash <= nhash) {
- if ((*prev)->nhash == nhash &&
+ if ((*prev)->nhash == nhash &&
!memcmp((*prev)->name, name, namelen) &&
!(*prev)->name[namelen]) {
struct jffs2_full_dirent *this = *prev;
@@ -639,7 +621,7 @@ int jffs2_do_unlink(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f,
/* dead_f is NULL if this was a rename not a real unlink */
/* Also catch the !f->inocache case, where there was a dirent
pointing to an inode which didn't exist. */
- if (dead_f && dead_f->inocache) {
+ if (dead_f && dead_f->inocache) {
down(&dead_f->sem);
@@ -647,9 +629,9 @@ int jffs2_do_unlink(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f,
while (dead_f->dents) {
/* There can be only deleted ones */
fd = dead_f->dents;
-
+
dead_f->dents = fd->next;
-
+
if (fd->ino) {
printk(KERN_WARNING "Deleting inode #%u with active dentry \"%s\"->ino #%u\n",
dead_f->inocache->ino, fd->name, fd->ino);
@@ -673,7 +655,7 @@ int jffs2_do_unlink(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f,
}
-int jffs2_do_link (struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, uint32_t ino, uint8_t type, const char *name, int namelen)
+int jffs2_do_link (struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, uint32_t ino, uint8_t type, const char *name, int namelen, uint32_t time)
{
struct jffs2_raw_dirent *rd;
struct jffs2_full_dirent *fd;
@@ -684,12 +666,13 @@ int jffs2_do_link (struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, uint
if (!rd)
return -ENOMEM;
- ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen, ALLOC_NORMAL);
+ ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen,
+ ALLOC_NORMAL, JFFS2_SUMMARY_DIRENT_SIZE(namelen));
if (ret) {
jffs2_free_raw_dirent(rd);
return ret;
}
-
+
down(&dir_f->sem);
/* Build a deletion node */
@@ -701,7 +684,7 @@ int jffs2_do_link (struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, uint
rd->pino = cpu_to_je32(dir_f->inocache->ino);
rd->version = cpu_to_je32(++dir_f->highest_version);
rd->ino = cpu_to_je32(ino);
- rd->mctime = cpu_to_je32(get_seconds());
+ rd->mctime = cpu_to_je32(time);
rd->nsize = namelen;
rd->type = type;
@@ -710,7 +693,7 @@ int jffs2_do_link (struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, uint
rd->name_crc = cpu_to_je32(crc32(0, name, namelen));
fd = jffs2_write_dirent(c, dir_f, rd, name, namelen, phys_ofs, ALLOC_NORMAL);
-
+
jffs2_free_raw_dirent(rd);
if (IS_ERR(fd)) {
diff --git a/fs/jffs2/writev.c b/fs/jffs2/writev.c
index f079f8388566..c638ae1008de 100644
--- a/fs/jffs2/writev.c
+++ b/fs/jffs2/writev.c
@@ -7,7 +7,7 @@
*
* For licensing information, see the file 'LICENCE' in this directory.
*
- * $Id: writev.c,v 1.6 2004/11/16 20:36:12 dwmw2 Exp $
+ * $Id: writev.c,v 1.8 2005/09/09 15:11:58 havasi Exp $
*
*/
@@ -42,9 +42,40 @@ static inline int mtd_fake_writev(struct mtd_info *mtd, const struct kvec *vecs,
int jffs2_flash_direct_writev(struct jffs2_sb_info *c, const struct kvec *vecs,
unsigned long count, loff_t to, size_t *retlen)
{
+ if (!jffs2_is_writebuffered(c)) {
+ if (jffs2_sum_active()) {
+ int res;
+ res = jffs2_sum_add_kvec(c, vecs, count, (uint32_t) to);
+ if (res) {
+ return res;
+ }
+ }
+ }
+
if (c->mtd->writev)
return c->mtd->writev(c->mtd, vecs, count, to, retlen);
- else
+ else {
return mtd_fake_writev(c->mtd, vecs, count, to, retlen);
+ }
}
+int jffs2_flash_direct_write(struct jffs2_sb_info *c, loff_t ofs, size_t len,
+ size_t *retlen, const u_char *buf)
+{
+ int ret;
+ ret = c->mtd->write(c->mtd, ofs, len, retlen, buf);
+
+ if (jffs2_sum_active()) {
+ struct kvec vecs[1];
+ int res;
+
+ vecs[0].iov_base = (unsigned char *) buf;
+ vecs[0].iov_len = len;
+
+ res = jffs2_sum_add_kvec(c, vecs, 1, (uint32_t) ofs);
+ if (res) {
+ return res;
+ }
+ }
+ return ret;
+}
diff --git a/fs/jfs/jfs_dmap.c b/fs/jfs/jfs_dmap.c
index eadf319bee22..68000a50ceb6 100644
--- a/fs/jfs/jfs_dmap.c
+++ b/fs/jfs/jfs_dmap.c
@@ -74,7 +74,7 @@
static void dbAllocBits(struct bmap * bmp, struct dmap * dp, s64 blkno,
int nblocks);
static void dbSplit(dmtree_t * tp, int leafno, int splitsz, int newval);
-static void dbBackSplit(dmtree_t * tp, int leafno);
+static int dbBackSplit(dmtree_t * tp, int leafno);
static int dbJoin(dmtree_t * tp, int leafno, int newval);
static void dbAdjTree(dmtree_t * tp, int leafno, int newval);
static int dbAdjCtl(struct bmap * bmp, s64 blkno, int newval, int alloc,
@@ -305,7 +305,6 @@ int dbSync(struct inode *ipbmap)
filemap_fdatawrite(ipbmap->i_mapping);
filemap_fdatawait(ipbmap->i_mapping);
- ipbmap->i_state |= I_DIRTY;
diWriteSpecial(ipbmap, 0);
return (0);
@@ -2467,7 +2466,9 @@ dbAdjCtl(struct bmap * bmp, s64 blkno, int newval, int alloc, int level)
* that it is at the front of a binary buddy system.
*/
if (oldval == NOFREE) {
- dbBackSplit((dmtree_t *) dcp, leafno);
+ rc = dbBackSplit((dmtree_t *) dcp, leafno);
+ if (rc)
+ return rc;
oldval = dcp->stree[ti];
}
dbSplit((dmtree_t *) dcp, leafno, dcp->budmin, newval);
@@ -2627,7 +2628,7 @@ static void dbSplit(dmtree_t * tp, int leafno, int splitsz, int newval)
*
* serialization: IREAD_LOCK(ipbmap) or IWRITE_LOCK(ipbmap) held on entry/exit;
*/
-static void dbBackSplit(dmtree_t * tp, int leafno)
+static int dbBackSplit(dmtree_t * tp, int leafno)
{
int budsz, bud, w, bsz, size;
int cursz;
@@ -2662,7 +2663,10 @@ static void dbBackSplit(dmtree_t * tp, int leafno)
*/
for (w = leafno, bsz = budsz;; bsz <<= 1,
w = (w < bud) ? w : bud) {
- assert(bsz < le32_to_cpu(tp->dmt_nleafs));
+ if (bsz >= le32_to_cpu(tp->dmt_nleafs)) {
+ jfs_err("JFS: block map error in dbBackSplit");
+ return -EIO;
+ }
/* determine the buddy.
*/
@@ -2681,7 +2685,11 @@ static void dbBackSplit(dmtree_t * tp, int leafno)
}
}
- assert(leaf[leafno] == size);
+ if (leaf[leafno] != size) {
+ jfs_err("JFS: wrong leaf value in dbBackSplit");
+ return -EIO;
+ }
+ return 0;
}
diff --git a/fs/jfs/jfs_imap.c b/fs/jfs/jfs_imap.c
index 4021d46da7e3..28201b194f53 100644
--- a/fs/jfs/jfs_imap.c
+++ b/fs/jfs/jfs_imap.c
@@ -57,6 +57,12 @@
#include "jfs_debug.h"
/*
+ * __mark_inode_dirty expects inodes to be hashed. Since we don't want
+ * special inodes in the fileset inode space, we hash them to a dummy head
+ */
+static HLIST_HEAD(aggregate_hash);
+
+/*
* imap locks
*/
/* iag free list lock */
@@ -491,6 +497,8 @@ struct inode *diReadSpecial(struct super_block *sb, ino_t inum, int secondary)
/* release the page */
release_metapage(mp);
+ hlist_add_head(&ip->i_hash, &aggregate_hash);
+
return (ip);
}
@@ -514,8 +522,6 @@ void diWriteSpecial(struct inode *ip, int secondary)
ino_t inum = ip->i_ino;
struct metapage *mp;
- ip->i_state &= ~I_DIRTY;
-
if (secondary)
address = addressPXD(&sbi->ait2) >> sbi->l2nbperpage;
else
diff --git a/fs/jfs/jfs_metapage.c b/fs/jfs/jfs_metapage.c
index 13d7e3f1feb4..8a53981f9f27 100644
--- a/fs/jfs/jfs_metapage.c
+++ b/fs/jfs/jfs_metapage.c
@@ -86,7 +86,7 @@ struct meta_anchor {
atomic_t io_count;
struct metapage *mp[MPS_PER_PAGE];
};
-#define mp_anchor(page) ((struct meta_anchor *)page->private)
+#define mp_anchor(page) ((struct meta_anchor *)page_private(page))
static inline struct metapage *page_to_mp(struct page *page, uint offset)
{
@@ -108,7 +108,7 @@ static inline int insert_metapage(struct page *page, struct metapage *mp)
if (!a)
return -ENOMEM;
memset(a, 0, sizeof(struct meta_anchor));
- page->private = (unsigned long)a;
+ set_page_private(page, (unsigned long)a);
SetPagePrivate(page);
kmap(page);
}
@@ -136,7 +136,7 @@ static inline void remove_metapage(struct page *page, struct metapage *mp)
a->mp[index] = NULL;
if (--a->mp_count == 0) {
kfree(a);
- page->private = 0;
+ set_page_private(page, 0);
ClearPagePrivate(page);
kunmap(page);
}
@@ -156,13 +156,13 @@ static inline void dec_io(struct page *page, void (*handler) (struct page *))
#else
static inline struct metapage *page_to_mp(struct page *page, uint offset)
{
- return PagePrivate(page) ? (struct metapage *)page->private : NULL;
+ return PagePrivate(page) ? (struct metapage *)page_private(page) : NULL;
}
static inline int insert_metapage(struct page *page, struct metapage *mp)
{
if (mp) {
- page->private = (unsigned long)mp;
+ set_page_private(page, (unsigned long)mp);
SetPagePrivate(page);
kmap(page);
}
@@ -171,7 +171,7 @@ static inline int insert_metapage(struct page *page, struct metapage *mp)
static inline void remove_metapage(struct page *page, struct metapage *mp)
{
- page->private = 0;
+ set_page_private(page, 0);
ClearPagePrivate(page);
kunmap(page);
}
@@ -198,7 +198,7 @@ static void init_once(void *foo, kmem_cache_t *cachep, unsigned long flags)
}
}
-static inline struct metapage *alloc_metapage(unsigned int gfp_mask)
+static inline struct metapage *alloc_metapage(gfp_t gfp_mask)
{
return mempool_alloc(metapage_mempool, gfp_mask);
}
@@ -395,6 +395,12 @@ static int metapage_writepage(struct page *page, struct writeback_control *wbc)
if (mp->nohomeok && !test_bit(META_forcewrite, &mp->flag)) {
redirty = 1;
+ /*
+ * Make sure this page isn't blocked indefinitely.
+ * If the journal isn't undergoing I/O, push it
+ */
+ if (mp->log && !(mp->log->cflag & logGC_PAGEOUT))
+ jfs_flush_journal(mp->log, 0);
continue;
}
@@ -534,7 +540,7 @@ add_failed:
return -EIO;
}
-static int metapage_releasepage(struct page *page, int gfp_mask)
+static int metapage_releasepage(struct page *page, gfp_t gfp_mask)
{
struct metapage *mp;
int busy = 0;
diff --git a/fs/jfs/jfs_txnmgr.c b/fs/jfs/jfs_txnmgr.c
index 9b71ed2674fe..b660c93c92de 100644
--- a/fs/jfs/jfs_txnmgr.c
+++ b/fs/jfs/jfs_txnmgr.c
@@ -2396,7 +2396,6 @@ static void txUpdateMap(struct tblock * tblk)
*/
if (tblk->xflag & COMMIT_CREATE) {
diUpdatePMap(ipimap, tblk->ino, FALSE, tblk);
- ipimap->i_state |= I_DIRTY;
/* update persistent block allocation map
* for the allocation of inode extent;
*/
@@ -2407,7 +2406,6 @@ static void txUpdateMap(struct tblock * tblk)
} else if (tblk->xflag & COMMIT_DELETE) {
ip = tblk->u.ip;
diUpdatePMap(ipimap, ip->i_ino, TRUE, tblk);
- ipimap->i_state |= I_DIRTY;
iput(ip);
}
}
diff --git a/fs/jfs/jfs_xtree.c b/fs/jfs/jfs_xtree.c
index a7fe2f2b969f..e72f4ebb6e9c 100644
--- a/fs/jfs/jfs_xtree.c
+++ b/fs/jfs/jfs_xtree.c
@@ -3516,16 +3516,10 @@ s64 xtTruncate(tid_t tid, struct inode *ip, s64 newsize, int flag)
/* process entries backward from last index */
index = le16_to_cpu(p->header.nextindex) - 1;
- if (p->header.flag & BT_INTERNAL)
- goto getChild;
-
- /*
- * leaf page
- */
- /* Since this is the rightmost leaf, and we may have already freed
- * a page that was formerly to the right, let's make sure that the
- * next pointer is zero.
+ /* Since this is the rightmost page at this level, and we may have
+ * already freed a page that was formerly to the right, let's make
+ * sure that the next pointer is zero.
*/
if (p->header.next) {
if (log)
@@ -3539,6 +3533,12 @@ s64 xtTruncate(tid_t tid, struct inode *ip, s64 newsize, int flag)
p->header.next = 0;
}
+ if (p->header.flag & BT_INTERNAL)
+ goto getChild;
+
+ /*
+ * leaf page
+ */
freed = 0;
/* does region covered by leaf page precede Teof ? */
diff --git a/fs/jfs/namei.c b/fs/jfs/namei.c
index 1abe7343f920..4abbe8604302 100644
--- a/fs/jfs/namei.c
+++ b/fs/jfs/namei.c
@@ -827,6 +827,7 @@ static int jfs_link(struct dentry *old_dentry,
/* update object inode */
ip->i_nlink++; /* for new link */
ip->i_ctime = CURRENT_TIME;
+ dir->i_ctime = dir->i_mtime = CURRENT_TIME;
mark_inode_dirty(dir);
atomic_inc(&ip->i_count);
@@ -1024,6 +1025,8 @@ static int jfs_symlink(struct inode *dip, struct dentry *dentry,
insert_inode_hash(ip);
mark_inode_dirty(ip);
+ dip->i_ctime = dip->i_mtime = CURRENT_TIME;
+ mark_inode_dirty(dip);
/*
* commit update of parent directory and link object
*/
diff --git a/fs/jfs/super.c b/fs/jfs/super.c
index 71bc34b96b2b..4226af3ea91b 100644
--- a/fs/jfs/super.c
+++ b/fs/jfs/super.c
@@ -442,6 +442,7 @@ static int jfs_fill_super(struct super_block *sb, void *data, int silent)
inode->i_nlink = 1;
inode->i_size = sb->s_bdev->bd_inode->i_size;
inode->i_mapping->a_ops = &jfs_metapage_aops;
+ insert_inode_hash(inode);
mapping_set_gfp_mask(inode->i_mapping, GFP_NOFS);
sbi->direct_inode = inode;
diff --git a/fs/lockd/clntproc.c b/fs/lockd/clntproc.c
index 87332f30141b..c5a33648e9fd 100644
--- a/fs/lockd/clntproc.c
+++ b/fs/lockd/clntproc.c
@@ -112,8 +112,7 @@ static struct nlm_lockowner *nlm_find_lockowner(struct nlm_host *host, fl_owner_
}
}
spin_unlock(&host->h_lock);
- if (new != NULL)
- kfree(new);
+ kfree(new);
return res;
}
diff --git a/fs/lockd/host.c b/fs/lockd/host.c
index 82c77df81c5f..c4c8601096e0 100644
--- a/fs/lockd/host.c
+++ b/fs/lockd/host.c
@@ -173,11 +173,10 @@ nlm_bind_host(struct nlm_host *host)
/* If we've already created an RPC client, check whether
* RPC rebind is required
- * Note: why keep rebinding if we're on a tcp connection?
*/
if ((clnt = host->h_rpcclnt) != NULL) {
xprt = clnt->cl_xprt;
- if (!xprt->stream && time_after_eq(jiffies, host->h_nextrebind)) {
+ if (time_after_eq(jiffies, host->h_nextrebind)) {
clnt->cl_port = 0;
host->h_nextrebind = jiffies + NLM_HOST_REBIND;
dprintk("lockd: next rebind in %ld jiffies\n",
@@ -189,7 +188,6 @@ nlm_bind_host(struct nlm_host *host)
goto forgetit;
xprt_set_timeout(&xprt->timeout, 5, nlmsvc_timeout);
- xprt->nocong = 1; /* No congestion control for NLM */
xprt->resvport = 1; /* NLM requires a reserved port */
/* Existing NLM servers accept AUTH_UNIX only */
diff --git a/fs/lockd/svcsubs.c b/fs/lockd/svcsubs.c
index de7536358c7c..62f4a385177f 100644
--- a/fs/lockd/svcsubs.c
+++ b/fs/lockd/svcsubs.c
@@ -30,6 +30,36 @@
static struct nlm_file * nlm_files[FILE_NRHASH];
static DECLARE_MUTEX(nlm_file_sema);
+#ifdef NFSD_DEBUG
+static inline void nlm_debug_print_fh(char *msg, struct nfs_fh *f)
+{
+ u32 *fhp = (u32*)f->data;
+
+ /* print the first 32 bytes of the fh */
+ dprintk("lockd: %s (%08x %08x %08x %08x %08x %08x %08x %08x)\n",
+ msg, fhp[0], fhp[1], fhp[2], fhp[3],
+ fhp[4], fhp[5], fhp[6], fhp[7]);
+}
+
+static inline void nlm_debug_print_file(char *msg, struct nlm_file *file)
+{
+ struct inode *inode = file->f_file->f_dentry->d_inode;
+
+ dprintk("lockd: %s %s/%ld\n",
+ msg, inode->i_sb->s_id, inode->i_ino);
+}
+#else
+static inline void nlm_debug_print_fh(char *msg, struct nfs_fh *f)
+{
+ return;
+}
+
+static inline void nlm_debug_print_file(char *msg, struct nlm_file *file)
+{
+ return;
+}
+#endif
+
static inline unsigned int file_hash(struct nfs_fh *f)
{
unsigned int tmp=0;
@@ -55,11 +85,8 @@ nlm_lookup_file(struct svc_rqst *rqstp, struct nlm_file **result,
struct nlm_file *file;
unsigned int hash;
u32 nfserr;
- u32 *fhp = (u32*)f->data;
-
- dprintk("lockd: nlm_file_lookup(%08x %08x %08x %08x %08x %08x)\n",
- fhp[0], fhp[1], fhp[2], fhp[3], fhp[4], fhp[5]);
+ nlm_debug_print_fh("nlm_file_lookup", f);
hash = file_hash(f);
@@ -70,8 +97,7 @@ nlm_lookup_file(struct svc_rqst *rqstp, struct nlm_file **result,
if (!nfs_compare_fh(&file->f_handle, f))
goto found;
- dprintk("lockd: creating file for (%08x %08x %08x %08x %08x %08x)\n",
- fhp[0], fhp[1], fhp[2], fhp[3], fhp[4], fhp[5]);
+ nlm_debug_print_fh("creating file for", f);
nfserr = nlm_lck_denied_nolocks;
file = (struct nlm_file *) kmalloc(sizeof(*file), GFP_KERNEL);
@@ -124,11 +150,10 @@ out_free:
static inline void
nlm_delete_file(struct nlm_file *file)
{
- struct inode *inode = file->f_file->f_dentry->d_inode;
struct nlm_file **fp, *f;
- dprintk("lockd: closing file %s/%ld\n",
- inode->i_sb->s_id, inode->i_ino);
+ nlm_debug_print_file("closing file", file);
+
fp = nlm_files + file->f_hash;
while ((f = *fp) != NULL) {
if (f == file) {
diff --git a/fs/locks.c b/fs/locks.c
index f7daa5f48949..a1e8b2248014 100644
--- a/fs/locks.c
+++ b/fs/locks.c
@@ -316,21 +316,22 @@ static int flock_to_posix_lock(struct file *filp, struct file_lock *fl,
/* POSIX-1996 leaves the case l->l_len < 0 undefined;
POSIX-2001 defines it. */
start += l->l_start;
- end = start + l->l_len - 1;
- if (l->l_len < 0) {
+ if (start < 0)
+ return -EINVAL;
+ fl->fl_end = OFFSET_MAX;
+ if (l->l_len > 0) {
+ end = start + l->l_len - 1;
+ fl->fl_end = end;
+ } else if (l->l_len < 0) {
end = start - 1;
+ fl->fl_end = end;
start += l->l_len;
+ if (start < 0)
+ return -EINVAL;
}
-
- if (start < 0)
- return -EINVAL;
- if (l->l_len > 0 && end < 0)
- return -EOVERFLOW;
-
fl->fl_start = start; /* we record the absolute position */
- fl->fl_end = end;
- if (l->l_len == 0)
- fl->fl_end = OFFSET_MAX;
+ if (fl->fl_end < fl->fl_start)
+ return -EOVERFLOW;
fl->fl_owner = current->files;
fl->fl_pid = current->tgid;
@@ -362,14 +363,21 @@ static int flock64_to_posix_lock(struct file *filp, struct file_lock *fl,
return -EINVAL;
}
- if (((start += l->l_start) < 0) || (l->l_len < 0))
+ start += l->l_start;
+ if (start < 0)
return -EINVAL;
- fl->fl_end = start + l->l_len - 1;
- if (l->l_len > 0 && fl->fl_end < 0)
- return -EOVERFLOW;
+ fl->fl_end = OFFSET_MAX;
+ if (l->l_len > 0) {
+ fl->fl_end = start + l->l_len - 1;
+ } else if (l->l_len < 0) {
+ fl->fl_end = start - 1;
+ start += l->l_len;
+ if (start < 0)
+ return -EINVAL;
+ }
fl->fl_start = start; /* we record the absolute position */
- if (l->l_len == 0)
- fl->fl_end = OFFSET_MAX;
+ if (fl->fl_end < fl->fl_start)
+ return -EOVERFLOW;
fl->fl_owner = current->files;
fl->fl_pid = current->tgid;
@@ -829,12 +837,16 @@ static int __posix_lock_file(struct inode *inode, struct file_lock *request)
/* Detect adjacent or overlapping regions (if same lock type)
*/
if (request->fl_type == fl->fl_type) {
+ /* In all comparisons of start vs end, use
+ * "start - 1" rather than "end + 1". If end
+ * is OFFSET_MAX, end + 1 will become negative.
+ */
if (fl->fl_end < request->fl_start - 1)
goto next_lock;
/* If the next lock in the list has entirely bigger
* addresses than the new one, insert the lock here.
*/
- if (fl->fl_start > request->fl_end + 1)
+ if (fl->fl_start - 1 > request->fl_end)
break;
/* If we come here, the new and old lock are of the
diff --git a/fs/mbcache.c b/fs/mbcache.c
index b002a088857d..0f1e4530670f 100644
--- a/fs/mbcache.c
+++ b/fs/mbcache.c
@@ -116,7 +116,7 @@ mb_cache_indexes(struct mb_cache *cache)
* What the mbcache registers as to get shrunk dynamically.
*/
-static int mb_cache_shrink_fn(int nr_to_scan, unsigned int gfp_mask);
+static int mb_cache_shrink_fn(int nr_to_scan, gfp_t gfp_mask);
static inline int
@@ -140,7 +140,7 @@ __mb_cache_entry_unhash(struct mb_cache_entry *ce)
static inline void
-__mb_cache_entry_forget(struct mb_cache_entry *ce, int gfp_mask)
+__mb_cache_entry_forget(struct mb_cache_entry *ce, gfp_t gfp_mask)
{
struct mb_cache *cache = ce->e_cache;
@@ -193,7 +193,7 @@ forget:
* Returns the number of objects which are present in the cache.
*/
static int
-mb_cache_shrink_fn(int nr_to_scan, unsigned int gfp_mask)
+mb_cache_shrink_fn(int nr_to_scan, gfp_t gfp_mask)
{
LIST_HEAD(free_list);
struct list_head *l, *ltmp;
@@ -301,8 +301,7 @@ fail:
if (cache) {
while (--m >= 0)
kfree(cache->c_indexes_hash[m]);
- if (cache->c_block_hash)
- kfree(cache->c_block_hash);
+ kfree(cache->c_block_hash);
kfree(cache);
}
return NULL;
diff --git a/fs/msdos/namei.c b/fs/msdos/namei.c
index 154f511c7245..626a367bcd81 100644
--- a/fs/msdos/namei.c
+++ b/fs/msdos/namei.c
@@ -454,10 +454,10 @@ static int do_msdos_rename(struct inode *old_dir, unsigned char *old_name,
{
struct buffer_head *dotdot_bh;
struct msdos_dir_entry *dotdot_de;
- loff_t dotdot_i_pos;
struct inode *old_inode, *new_inode;
struct fat_slot_info old_sinfo, sinfo;
struct timespec ts;
+ loff_t dotdot_i_pos, new_i_pos;
int err, old_attrs, is_dir, update_dotdot, corrupt = 0;
old_sinfo.bh = sinfo.bh = dotdot_bh = NULL;
@@ -516,28 +516,24 @@ static int do_msdos_rename(struct inode *old_dir, unsigned char *old_name,
if (new_inode) {
if (err)
goto out;
- if (MSDOS_I(new_inode)->i_pos != sinfo.i_pos) {
- /* WTF??? Cry and fail. */
- printk(KERN_WARNING "msdos_rename: fs corrupted\n");
- goto out;
- }
-
if (is_dir) {
err = fat_dir_empty(new_inode);
if (err)
goto out;
}
+ new_i_pos = MSDOS_I(new_inode)->i_pos;
fat_detach(new_inode);
} else {
err = msdos_add_entry(new_dir, new_name, is_dir, is_hid, 0,
&ts, &sinfo);
if (err)
goto out;
+ new_i_pos = sinfo.i_pos;
}
new_dir->i_version++;
fat_detach(old_inode);
- fat_attach(old_inode, sinfo.i_pos);
+ fat_attach(old_inode, new_i_pos);
if (is_hid)
MSDOS_I(old_inode)->i_attrs |= ATTR_HIDDEN;
else
@@ -604,7 +600,7 @@ error_inode:
fat_attach(old_inode, old_sinfo.i_pos);
MSDOS_I(old_inode)->i_attrs = old_attrs;
if (new_inode) {
- fat_attach(new_inode, sinfo.i_pos);
+ fat_attach(new_inode, new_i_pos);
if (corrupt)
corrupt |= fat_sync_inode(new_inode);
} else {
diff --git a/fs/namei.c b/fs/namei.c
index aa62dbda93ac..6dbbd42d8b95 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -28,6 +28,7 @@
#include <linux/syscalls.h>
#include <linux/mount.h>
#include <linux/audit.h>
+#include <linux/file.h>
#include <asm/namei.h>
#include <asm/uaccess.h>
@@ -255,6 +256,38 @@ int permission(struct inode *inode, int mask, struct nameidata *nd)
return security_inode_permission(inode, mask, nd);
}
+/**
+ * vfs_permission - check for access rights to a given path
+ * @nd: lookup result that describes the path
+ * @mask: right to check for (%MAY_READ, %MAY_WRITE, %MAY_EXEC)
+ *
+ * Used to check for read/write/execute permissions on a path.
+ * We use "fsuid" for this, letting us set arbitrary permissions
+ * for filesystem access without changing the "normal" uids which
+ * are used for other things.
+ */
+int vfs_permission(struct nameidata *nd, int mask)
+{
+ return permission(nd->dentry->d_inode, mask, nd);
+}
+
+/**
+ * file_permission - check for additional access rights to a given file
+ * @file: file to check access rights for
+ * @mask: right to check for (%MAY_READ, %MAY_WRITE, %MAY_EXEC)
+ *
+ * Used to check for read/write/execute permissions on an already opened
+ * file.
+ *
+ * Note:
+ * Do not use this function in new code. All access checks should
+ * be done using vfs_permission().
+ */
+int file_permission(struct file *file, int mask)
+{
+ return permission(file->f_dentry->d_inode, mask, NULL);
+}
+
/*
* get_write_access() gets write permission for a file.
* put_write_access() releases this write permission.
@@ -317,6 +350,18 @@ void path_release_on_umount(struct nameidata *nd)
mntput_no_expire(nd->mnt);
}
+/**
+ * release_open_intent - free up open intent resources
+ * @nd: pointer to nameidata
+ */
+void release_open_intent(struct nameidata *nd)
+{
+ if (nd->intent.open.file->f_dentry == NULL)
+ put_filp(nd->intent.open.file);
+ else
+ fput(nd->intent.open.file);
+}
+
/*
* Internal lookup() using the new generic dcache.
* SMP-safe
@@ -750,10 +795,10 @@ static fastcall int __link_path_walk(const char * name, struct nameidata *nd)
struct qstr this;
unsigned int c;
+ nd->flags |= LOOKUP_CONTINUE;
err = exec_permission_lite(inode, nd);
- if (err == -EAGAIN) {
- err = permission(inode, MAY_EXEC, nd);
- }
+ if (err == -EAGAIN)
+ err = vfs_permission(nd, MAY_EXEC);
if (err)
break;
@@ -802,7 +847,6 @@ static fastcall int __link_path_walk(const char * name, struct nameidata *nd)
if (err < 0)
break;
}
- nd->flags |= LOOKUP_CONTINUE;
/* This does the actual lookups.. */
err = do_lookup(nd, &this, &next);
if (err)
@@ -1052,6 +1096,71 @@ out:
return retval;
}
+static int __path_lookup_intent_open(const char *name, unsigned int lookup_flags,
+ struct nameidata *nd, int open_flags, int create_mode)
+{
+ struct file *filp = get_empty_filp();
+ int err;
+
+ if (filp == NULL)
+ return -ENFILE;
+ nd->intent.open.file = filp;
+ nd->intent.open.flags = open_flags;
+ nd->intent.open.create_mode = create_mode;
+ err = path_lookup(name, lookup_flags|LOOKUP_OPEN, nd);
+ if (IS_ERR(nd->intent.open.file)) {
+ if (err == 0) {
+ err = PTR_ERR(nd->intent.open.file);
+ path_release(nd);
+ }
+ } else if (err != 0)
+ release_open_intent(nd);
+ return err;
+}
+
+/**
+ * path_lookup_open - lookup a file path with open intent
+ * @name: pointer to file name
+ * @lookup_flags: lookup intent flags
+ * @nd: pointer to nameidata
+ * @open_flags: open intent flags
+ */
+int path_lookup_open(const char *name, unsigned int lookup_flags,
+ struct nameidata *nd, int open_flags)
+{
+ return __path_lookup_intent_open(name, lookup_flags, nd,
+ open_flags, 0);
+}
+
+/**
+ * path_lookup_create - lookup a file path with open + create intent
+ * @name: pointer to file name
+ * @lookup_flags: lookup intent flags
+ * @nd: pointer to nameidata
+ * @open_flags: open intent flags
+ * @create_mode: create intent flags
+ */
+static int path_lookup_create(const char *name, unsigned int lookup_flags,
+ struct nameidata *nd, int open_flags,
+ int create_mode)
+{
+ return __path_lookup_intent_open(name, lookup_flags|LOOKUP_CREATE, nd,
+ open_flags, create_mode);
+}
+
+int __user_path_lookup_open(const char __user *name, unsigned int lookup_flags,
+ struct nameidata *nd, int open_flags)
+{
+ char *tmp = getname(name);
+ int err = PTR_ERR(tmp);
+
+ if (!IS_ERR(tmp)) {
+ err = __path_lookup_intent_open(tmp, lookup_flags, nd, open_flags, 0);
+ putname(tmp);
+ }
+ return err;
+}
+
/*
* Restricted form of lookup. Doesn't follow links, single-component only,
* needs parent already locked. Doesn't follow mounts.
@@ -1096,9 +1205,9 @@ out:
return dentry;
}
-struct dentry * lookup_hash(struct qstr *name, struct dentry * base)
+struct dentry * lookup_hash(struct nameidata *nd)
{
- return __lookup_hash(name, base, NULL);
+ return __lookup_hash(&nd->last, nd->dentry, nd);
}
/* SMP-safe */
@@ -1122,7 +1231,7 @@ struct dentry * lookup_one_len(const char * name, struct dentry * base, int len)
}
this.hash = end_name_hash(hash);
- return lookup_hash(&this, base);
+ return __lookup_hash(&this, base, NULL);
access:
return ERR_PTR(-EACCES);
}
@@ -1234,9 +1343,6 @@ static inline int may_create(struct inode *dir, struct dentry *child,
}
/*
- * Special case: O_CREAT|O_EXCL implies O_NOFOLLOW for security
- * reasons.
- *
* O_DIRECTORY translates into forcing a directory lookup.
*/
static inline int lookup_flags(unsigned int f)
@@ -1246,9 +1352,6 @@ static inline int lookup_flags(unsigned int f)
if (f & O_NOFOLLOW)
retval &= ~LOOKUP_FOLLOW;
- if ((f & (O_CREAT|O_EXCL)) == (O_CREAT|O_EXCL))
- retval &= ~LOOKUP_FOLLOW;
-
if (f & O_DIRECTORY)
retval |= LOOKUP_DIRECTORY;
@@ -1336,7 +1439,7 @@ int may_open(struct nameidata *nd, int acc_mode, int flag)
if (S_ISDIR(inode->i_mode) && (flag & FMODE_WRITE))
return -EISDIR;
- error = permission(inode, acc_mode, nd);
+ error = vfs_permission(nd, acc_mode);
if (error)
return error;
@@ -1388,7 +1491,7 @@ int may_open(struct nameidata *nd, int acc_mode, int flag)
if (!error) {
DQUOT_INIT(inode);
- error = do_truncate(dentry, 0);
+ error = do_truncate(dentry, 0, NULL);
}
put_write_access(inode);
if (error)
@@ -1416,27 +1519,27 @@ int may_open(struct nameidata *nd, int acc_mode, int flag)
*/
int open_namei(const char * pathname, int flag, int mode, struct nameidata *nd)
{
- int acc_mode, error = 0;
+ int acc_mode, error;
struct path path;
struct dentry *dir;
int count = 0;
acc_mode = ACC_MODE(flag);
+ /* O_TRUNC implies we need access checks for write permissions */
+ if (flag & O_TRUNC)
+ acc_mode |= MAY_WRITE;
+
/* Allow the LSM permission hook to distinguish append
access from general write access. */
if (flag & O_APPEND)
acc_mode |= MAY_APPEND;
- /* Fill in the open() intent data */
- nd->intent.open.flags = flag;
- nd->intent.open.create_mode = mode;
-
/*
* The simplest case - just a plain lookup.
*/
if (!(flag & O_CREAT)) {
- error = path_lookup(pathname, lookup_flags(flag)|LOOKUP_OPEN, nd);
+ error = path_lookup_open(pathname, lookup_flags(flag), nd, flag);
if (error)
return error;
goto ok;
@@ -1445,7 +1548,7 @@ int open_namei(const char * pathname, int flag, int mode, struct nameidata *nd)
/*
* Create - we need to know the parent.
*/
- error = path_lookup(pathname, LOOKUP_PARENT|LOOKUP_OPEN|LOOKUP_CREATE, nd);
+ error = path_lookup_create(pathname, LOOKUP_PARENT, nd, flag, mode);
if (error)
return error;
@@ -1461,7 +1564,7 @@ int open_namei(const char * pathname, int flag, int mode, struct nameidata *nd)
dir = nd->dentry;
nd->flags &= ~LOOKUP_PARENT;
down(&dir->d_inode->i_sem);
- path.dentry = __lookup_hash(&nd->last, nd->dentry, nd);
+ path.dentry = lookup_hash(nd);
path.mnt = nd->mnt;
do_last:
@@ -1520,6 +1623,8 @@ ok:
exit_dput:
dput_path(&path, nd);
exit:
+ if (!IS_ERR(nd->intent.open.file))
+ release_open_intent(nd);
path_release(nd);
return error;
@@ -1561,7 +1666,7 @@ do_link:
}
dir = nd->dentry;
down(&dir->d_inode->i_sem);
- path.dentry = __lookup_hash(&nd->last, nd->dentry, nd);
+ path.dentry = lookup_hash(nd);
path.mnt = nd->mnt;
__putname(nd->last.name);
goto do_last;
@@ -1593,7 +1698,7 @@ struct dentry *lookup_create(struct nameidata *nd, int is_dir)
/*
* Do the final lookup.
*/
- dentry = lookup_hash(&nd->last, nd->dentry);
+ dentry = lookup_hash(nd);
if (IS_ERR(dentry))
goto fail;
@@ -1828,7 +1933,7 @@ asmlinkage long sys_rmdir(const char __user * pathname)
goto exit1;
}
down(&nd.dentry->d_inode->i_sem);
- dentry = lookup_hash(&nd.last, nd.dentry);
+ dentry = lookup_hash(&nd);
error = PTR_ERR(dentry);
if (!IS_ERR(dentry)) {
error = vfs_rmdir(nd.dentry->d_inode, dentry);
@@ -1897,7 +2002,7 @@ asmlinkage long sys_unlink(const char __user * pathname)
if (nd.last_type != LAST_NORM)
goto exit1;
down(&nd.dentry->d_inode->i_sem);
- dentry = lookup_hash(&nd.last, nd.dentry);
+ dentry = lookup_hash(&nd);
error = PTR_ERR(dentry);
if (!IS_ERR(dentry)) {
/* Why not before? Because we want correct error value */
@@ -2240,7 +2345,7 @@ static inline int do_rename(const char * oldname, const char * newname)
trap = lock_rename(new_dir, old_dir);
- old_dentry = lookup_hash(&oldnd.last, old_dir);
+ old_dentry = lookup_hash(&oldnd);
error = PTR_ERR(old_dentry);
if (IS_ERR(old_dentry))
goto exit3;
@@ -2260,7 +2365,7 @@ static inline int do_rename(const char * oldname, const char * newname)
error = -EINVAL;
if (old_dentry == trap)
goto exit4;
- new_dentry = lookup_hash(&newnd.last, new_dir);
+ new_dentry = lookup_hash(&newnd);
error = PTR_ERR(new_dentry);
if (IS_ERR(new_dentry))
goto exit4;
@@ -2463,6 +2568,8 @@ EXPORT_SYMBOL(path_lookup);
EXPORT_SYMBOL(path_release);
EXPORT_SYMBOL(path_walk);
EXPORT_SYMBOL(permission);
+EXPORT_SYMBOL(vfs_permission);
+EXPORT_SYMBOL(file_permission);
EXPORT_SYMBOL(unlock_rename);
EXPORT_SYMBOL(vfs_create);
EXPORT_SYMBOL(vfs_follow_link);
diff --git a/fs/namespace.c b/fs/namespace.c
index 2fa9fdf7d6f5..2019899f2ab8 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -24,6 +24,7 @@
#include <linux/mount.h>
#include <asm/uaccess.h>
#include <asm/unistd.h>
+#include "pnode.h"
extern int __init init_rootfs(void);
@@ -37,33 +38,39 @@ static inline int sysfs_init(void)
#endif
/* spinlock for vfsmount related operations, inplace of dcache_lock */
- __cacheline_aligned_in_smp DEFINE_SPINLOCK(vfsmount_lock);
+__cacheline_aligned_in_smp DEFINE_SPINLOCK(vfsmount_lock);
+
+static int event;
static struct list_head *mount_hashtable;
static int hash_mask __read_mostly, hash_bits __read_mostly;
-static kmem_cache_t *mnt_cache;
+static kmem_cache_t *mnt_cache;
+static struct rw_semaphore namespace_sem;
static inline unsigned long hash(struct vfsmount *mnt, struct dentry *dentry)
{
- unsigned long tmp = ((unsigned long) mnt / L1_CACHE_BYTES);
- tmp += ((unsigned long) dentry / L1_CACHE_BYTES);
+ unsigned long tmp = ((unsigned long)mnt / L1_CACHE_BYTES);
+ tmp += ((unsigned long)dentry / L1_CACHE_BYTES);
tmp = tmp + (tmp >> hash_bits);
return tmp & hash_mask;
}
struct vfsmount *alloc_vfsmnt(const char *name)
{
- struct vfsmount *mnt = kmem_cache_alloc(mnt_cache, GFP_KERNEL);
+ struct vfsmount *mnt = kmem_cache_alloc(mnt_cache, GFP_KERNEL);
if (mnt) {
memset(mnt, 0, sizeof(struct vfsmount));
- atomic_set(&mnt->mnt_count,1);
+ atomic_set(&mnt->mnt_count, 1);
INIT_LIST_HEAD(&mnt->mnt_hash);
INIT_LIST_HEAD(&mnt->mnt_child);
INIT_LIST_HEAD(&mnt->mnt_mounts);
INIT_LIST_HEAD(&mnt->mnt_list);
INIT_LIST_HEAD(&mnt->mnt_expire);
+ INIT_LIST_HEAD(&mnt->mnt_share);
+ INIT_LIST_HEAD(&mnt->mnt_slave_list);
+ INIT_LIST_HEAD(&mnt->mnt_slave);
if (name) {
- int size = strlen(name)+1;
+ int size = strlen(name) + 1;
char *newname = kmalloc(size, GFP_KERNEL);
if (newname) {
memcpy(newname, name, size);
@@ -81,36 +88,65 @@ void free_vfsmnt(struct vfsmount *mnt)
}
/*
- * Now, lookup_mnt increments the ref count before returning
- * the vfsmount struct.
+ * find the first or last mount at @dentry on vfsmount @mnt depending on
+ * @dir. If @dir is set return the first mount else return the last mount.
*/
-struct vfsmount *lookup_mnt(struct vfsmount *mnt, struct dentry *dentry)
+struct vfsmount *__lookup_mnt(struct vfsmount *mnt, struct dentry *dentry,
+ int dir)
{
- struct list_head * head = mount_hashtable + hash(mnt, dentry);
- struct list_head * tmp = head;
+ struct list_head *head = mount_hashtable + hash(mnt, dentry);
+ struct list_head *tmp = head;
struct vfsmount *p, *found = NULL;
- spin_lock(&vfsmount_lock);
for (;;) {
- tmp = tmp->next;
+ tmp = dir ? tmp->next : tmp->prev;
p = NULL;
if (tmp == head)
break;
p = list_entry(tmp, struct vfsmount, mnt_hash);
if (p->mnt_parent == mnt && p->mnt_mountpoint == dentry) {
- found = mntget(p);
+ found = p;
break;
}
}
- spin_unlock(&vfsmount_lock);
return found;
}
+/*
+ * lookup_mnt increments the ref count before returning
+ * the vfsmount struct.
+ */
+struct vfsmount *lookup_mnt(struct vfsmount *mnt, struct dentry *dentry)
+{
+ struct vfsmount *child_mnt;
+ spin_lock(&vfsmount_lock);
+ if ((child_mnt = __lookup_mnt(mnt, dentry, 1)))
+ mntget(child_mnt);
+ spin_unlock(&vfsmount_lock);
+ return child_mnt;
+}
+
static inline int check_mnt(struct vfsmount *mnt)
{
return mnt->mnt_namespace == current->namespace;
}
+static void touch_namespace(struct namespace *ns)
+{
+ if (ns) {
+ ns->event = ++event;
+ wake_up_interruptible(&ns->poll);
+ }
+}
+
+static void __touch_namespace(struct namespace *ns)
+{
+ if (ns && ns->event != event) {
+ ns->event = event;
+ wake_up_interruptible(&ns->poll);
+ }
+}
+
static void detach_mnt(struct vfsmount *mnt, struct nameidata *old_nd)
{
old_nd->dentry = mnt->mnt_mountpoint;
@@ -122,13 +158,43 @@ static void detach_mnt(struct vfsmount *mnt, struct nameidata *old_nd)
old_nd->dentry->d_mounted--;
}
+void mnt_set_mountpoint(struct vfsmount *mnt, struct dentry *dentry,
+ struct vfsmount *child_mnt)
+{
+ child_mnt->mnt_parent = mntget(mnt);
+ child_mnt->mnt_mountpoint = dget(dentry);
+ dentry->d_mounted++;
+}
+
static void attach_mnt(struct vfsmount *mnt, struct nameidata *nd)
{
- mnt->mnt_parent = mntget(nd->mnt);
- mnt->mnt_mountpoint = dget(nd->dentry);
- list_add(&mnt->mnt_hash, mount_hashtable+hash(nd->mnt, nd->dentry));
+ mnt_set_mountpoint(nd->mnt, nd->dentry, mnt);
+ list_add_tail(&mnt->mnt_hash, mount_hashtable +
+ hash(nd->mnt, nd->dentry));
list_add_tail(&mnt->mnt_child, &nd->mnt->mnt_mounts);
- nd->dentry->d_mounted++;
+}
+
+/*
+ * the caller must hold vfsmount_lock
+ */
+static void commit_tree(struct vfsmount *mnt)
+{
+ struct vfsmount *parent = mnt->mnt_parent;
+ struct vfsmount *m;
+ LIST_HEAD(head);
+ struct namespace *n = parent->mnt_namespace;
+
+ BUG_ON(parent == mnt);
+
+ list_add_tail(&head, &mnt->mnt_list);
+ list_for_each_entry(m, &head, mnt_list)
+ m->mnt_namespace = n;
+ list_splice(&head, n->list.prev);
+
+ list_add_tail(&mnt->mnt_hash, mount_hashtable +
+ hash(parent, mnt->mnt_mountpoint));
+ list_add_tail(&mnt->mnt_child, &parent->mnt_mounts);
+ touch_namespace(n);
}
static struct vfsmount *next_mnt(struct vfsmount *p, struct vfsmount *root)
@@ -147,8 +213,18 @@ static struct vfsmount *next_mnt(struct vfsmount *p, struct vfsmount *root)
return list_entry(next, struct vfsmount, mnt_child);
}
-static struct vfsmount *
-clone_mnt(struct vfsmount *old, struct dentry *root)
+static struct vfsmount *skip_mnt_tree(struct vfsmount *p)
+{
+ struct list_head *prev = p->mnt_mounts.prev;
+ while (prev != &p->mnt_mounts) {
+ p = list_entry(prev, struct vfsmount, mnt_child);
+ prev = p->mnt_mounts.prev;
+ }
+ return p;
+}
+
+static struct vfsmount *clone_mnt(struct vfsmount *old, struct dentry *root,
+ int flag)
{
struct super_block *sb = old->mnt_sb;
struct vfsmount *mnt = alloc_vfsmnt(old->mnt_devname);
@@ -160,19 +236,34 @@ clone_mnt(struct vfsmount *old, struct dentry *root)
mnt->mnt_root = dget(root);
mnt->mnt_mountpoint = mnt->mnt_root;
mnt->mnt_parent = mnt;
- mnt->mnt_namespace = current->namespace;
+
+ if (flag & CL_SLAVE) {
+ list_add(&mnt->mnt_slave, &old->mnt_slave_list);
+ mnt->mnt_master = old;
+ CLEAR_MNT_SHARED(mnt);
+ } else {
+ if ((flag & CL_PROPAGATION) || IS_MNT_SHARED(old))
+ list_add(&mnt->mnt_share, &old->mnt_share);
+ if (IS_MNT_SLAVE(old))
+ list_add(&mnt->mnt_slave, &old->mnt_slave);
+ mnt->mnt_master = old->mnt_master;
+ }
+ if (flag & CL_MAKE_SHARED)
+ set_mnt_shared(mnt);
/* stick the duplicate mount on the same expiry list
* as the original if that was on one */
- spin_lock(&vfsmount_lock);
- if (!list_empty(&old->mnt_expire))
- list_add(&mnt->mnt_expire, &old->mnt_expire);
- spin_unlock(&vfsmount_lock);
+ if (flag & CL_EXPIRE) {
+ spin_lock(&vfsmount_lock);
+ if (!list_empty(&old->mnt_expire))
+ list_add(&mnt->mnt_expire, &old->mnt_expire);
+ spin_unlock(&vfsmount_lock);
+ }
}
return mnt;
}
-void __mntput(struct vfsmount *mnt)
+static inline void __mntput(struct vfsmount *mnt)
{
struct super_block *sb = mnt->mnt_sb;
dput(mnt->mnt_root);
@@ -180,7 +271,46 @@ void __mntput(struct vfsmount *mnt)
deactivate_super(sb);
}
-EXPORT_SYMBOL(__mntput);
+void mntput_no_expire(struct vfsmount *mnt)
+{
+repeat:
+ if (atomic_dec_and_lock(&mnt->mnt_count, &vfsmount_lock)) {
+ if (likely(!mnt->mnt_pinned)) {
+ spin_unlock(&vfsmount_lock);
+ __mntput(mnt);
+ return;
+ }
+ atomic_add(mnt->mnt_pinned + 1, &mnt->mnt_count);
+ mnt->mnt_pinned = 0;
+ spin_unlock(&vfsmount_lock);
+ acct_auto_close_mnt(mnt);
+ security_sb_umount_close(mnt);
+ goto repeat;
+ }
+}
+
+EXPORT_SYMBOL(mntput_no_expire);
+
+void mnt_pin(struct vfsmount *mnt)
+{
+ spin_lock(&vfsmount_lock);
+ mnt->mnt_pinned++;
+ spin_unlock(&vfsmount_lock);
+}
+
+EXPORT_SYMBOL(mnt_pin);
+
+void mnt_unpin(struct vfsmount *mnt)
+{
+ spin_lock(&vfsmount_lock);
+ if (mnt->mnt_pinned) {
+ atomic_inc(&mnt->mnt_count);
+ mnt->mnt_pinned--;
+ }
+ spin_unlock(&vfsmount_lock);
+}
+
+EXPORT_SYMBOL(mnt_unpin);
/* iterator */
static void *m_start(struct seq_file *m, loff_t *pos)
@@ -189,7 +319,7 @@ static void *m_start(struct seq_file *m, loff_t *pos)
struct list_head *p;
loff_t l = *pos;
- down_read(&n->sem);
+ down_read(&namespace_sem);
list_for_each(p, &n->list)
if (!l--)
return list_entry(p, struct vfsmount, mnt_list);
@@ -201,13 +331,12 @@ static void *m_next(struct seq_file *m, void *v, loff_t *pos)
struct namespace *n = m->private;
struct list_head *p = ((struct vfsmount *)v)->mnt_list.next;
(*pos)++;
- return p==&n->list ? NULL : list_entry(p, struct vfsmount, mnt_list);
+ return p == &n->list ? NULL : list_entry(p, struct vfsmount, mnt_list);
}
static void m_stop(struct seq_file *m, void *v)
{
- struct namespace *n = m->private;
- up_read(&n->sem);
+ up_read(&namespace_sem);
}
static inline void mangle(struct seq_file *m, const char *s)
@@ -275,35 +404,14 @@ struct seq_operations mounts_op = {
*/
int may_umount_tree(struct vfsmount *mnt)
{
- struct list_head *next;
- struct vfsmount *this_parent = mnt;
- int actual_refs;
- int minimum_refs;
+ int actual_refs = 0;
+ int minimum_refs = 0;
+ struct vfsmount *p;
spin_lock(&vfsmount_lock);
- actual_refs = atomic_read(&mnt->mnt_count);
- minimum_refs = 2;
-repeat:
- next = this_parent->mnt_mounts.next;
-resume:
- while (next != &this_parent->mnt_mounts) {
- struct vfsmount *p = list_entry(next, struct vfsmount, mnt_child);
-
- next = next->next;
-
+ for (p = mnt; p; p = next_mnt(p, mnt)) {
actual_refs += atomic_read(&p->mnt_count);
minimum_refs += 2;
-
- if (!list_empty(&p->mnt_mounts)) {
- this_parent = p;
- goto repeat;
- }
- }
-
- if (this_parent != mnt) {
- next = this_parent->mnt_child.next;
- this_parent = this_parent->mnt_parent;
- goto resume;
}
spin_unlock(&vfsmount_lock);
@@ -330,45 +438,67 @@ EXPORT_SYMBOL(may_umount_tree);
*/
int may_umount(struct vfsmount *mnt)
{
- if (atomic_read(&mnt->mnt_count) > 2)
- return -EBUSY;
- return 0;
+ int ret = 0;
+ spin_lock(&vfsmount_lock);
+ if (propagate_mount_busy(mnt, 2))
+ ret = -EBUSY;
+ spin_unlock(&vfsmount_lock);
+ return ret;
}
EXPORT_SYMBOL(may_umount);
-static void umount_tree(struct vfsmount *mnt)
+void release_mounts(struct list_head *head)
+{
+ struct vfsmount *mnt;
+ while(!list_empty(head)) {
+ mnt = list_entry(head->next, struct vfsmount, mnt_hash);
+ list_del_init(&mnt->mnt_hash);
+ if (mnt->mnt_parent != mnt) {
+ struct dentry *dentry;
+ struct vfsmount *m;
+ spin_lock(&vfsmount_lock);
+ dentry = mnt->mnt_mountpoint;
+ m = mnt->mnt_parent;
+ mnt->mnt_mountpoint = mnt->mnt_root;
+ mnt->mnt_parent = mnt;
+ spin_unlock(&vfsmount_lock);
+ dput(dentry);
+ mntput(m);
+ }
+ mntput(mnt);
+ }
+}
+
+void umount_tree(struct vfsmount *mnt, int propagate, struct list_head *kill)
{
struct vfsmount *p;
- LIST_HEAD(kill);
for (p = mnt; p; p = next_mnt(p, mnt)) {
- list_del(&p->mnt_list);
- list_add(&p->mnt_list, &kill);
- p->mnt_namespace = NULL;
+ list_del(&p->mnt_hash);
+ list_add(&p->mnt_hash, kill);
}
- while (!list_empty(&kill)) {
- mnt = list_entry(kill.next, struct vfsmount, mnt_list);
- list_del_init(&mnt->mnt_list);
- list_del_init(&mnt->mnt_expire);
- if (mnt->mnt_parent == mnt) {
- spin_unlock(&vfsmount_lock);
- } else {
- struct nameidata old_nd;
- detach_mnt(mnt, &old_nd);
- spin_unlock(&vfsmount_lock);
- path_release(&old_nd);
- }
- mntput(mnt);
- spin_lock(&vfsmount_lock);
+ if (propagate)
+ propagate_umount(kill);
+
+ list_for_each_entry(p, kill, mnt_hash) {
+ list_del_init(&p->mnt_expire);
+ list_del_init(&p->mnt_list);
+ __touch_namespace(p->mnt_namespace);
+ p->mnt_namespace = NULL;
+ list_del_init(&p->mnt_child);
+ if (p->mnt_parent != p)
+ mnt->mnt_mountpoint->d_mounted--;
+ change_mnt_propagation(p, MS_PRIVATE);
}
}
static int do_umount(struct vfsmount *mnt, int flags)
{
- struct super_block * sb = mnt->mnt_sb;
+ struct super_block *sb = mnt->mnt_sb;
int retval;
+ LIST_HEAD(umount_list);
retval = security_sb_umount(mnt, flags);
if (retval)
@@ -403,7 +533,7 @@ static int do_umount(struct vfsmount *mnt, int flags)
*/
lock_kernel();
- if( (flags&MNT_FORCE) && sb->s_op->umount_begin)
+ if ((flags & MNT_FORCE) && sb->s_op->umount_begin)
sb->s_op->umount_begin(sb);
unlock_kernel();
@@ -432,29 +562,21 @@ static int do_umount(struct vfsmount *mnt, int flags)
return retval;
}
- down_write(&current->namespace->sem);
+ down_write(&namespace_sem);
spin_lock(&vfsmount_lock);
+ event++;
- if (atomic_read(&sb->s_active) == 1) {
- /* last instance - try to be smart */
- spin_unlock(&vfsmount_lock);
- lock_kernel();
- DQUOT_OFF(sb);
- acct_auto_close(sb);
- unlock_kernel();
- security_sb_umount_close(mnt);
- spin_lock(&vfsmount_lock);
- }
retval = -EBUSY;
- if (atomic_read(&mnt->mnt_count) == 2 || flags & MNT_DETACH) {
+ if (flags & MNT_DETACH || !propagate_mount_busy(mnt, 2)) {
if (!list_empty(&mnt->mnt_list))
- umount_tree(mnt);
+ umount_tree(mnt, 1, &umount_list);
retval = 0;
}
spin_unlock(&vfsmount_lock);
if (retval)
security_sb_umount_busy(mnt);
- up_write(&current->namespace->sem);
+ up_write(&namespace_sem);
+ release_mounts(&umount_list);
return retval;
}
@@ -494,12 +616,11 @@ out:
#ifdef __ARCH_WANT_SYS_OLDUMOUNT
/*
- * The 2.0 compatible umount. No flags.
+ * The 2.0 compatible umount. No flags.
*/
-
asmlinkage long sys_oldumount(char __user * name)
{
- return sys_umount(name,0);
+ return sys_umount(name, 0);
}
#endif
@@ -516,14 +637,13 @@ static int mount_is_safe(struct nameidata *nd)
if (current->uid != nd->dentry->d_inode->i_uid)
return -EPERM;
}
- if (permission(nd->dentry->d_inode, MAY_WRITE, nd))
+ if (vfs_permission(nd, MAY_WRITE))
return -EPERM;
return 0;
#endif
}
-static int
-lives_below_in_same_fs(struct dentry *d, struct dentry *dentry)
+static int lives_below_in_same_fs(struct dentry *d, struct dentry *dentry)
{
while (1) {
if (d == dentry)
@@ -534,12 +654,16 @@ lives_below_in_same_fs(struct dentry *d, struct dentry *dentry)
}
}
-static struct vfsmount *copy_tree(struct vfsmount *mnt, struct dentry *dentry)
+struct vfsmount *copy_tree(struct vfsmount *mnt, struct dentry *dentry,
+ int flag)
{
struct vfsmount *res, *p, *q, *r, *s;
struct nameidata nd;
- res = q = clone_mnt(mnt, dentry);
+ if (!(flag & CL_COPY_ALL) && IS_MNT_UNBINDABLE(mnt))
+ return NULL;
+
+ res = q = clone_mnt(mnt, dentry, flag);
if (!q)
goto Enomem;
q->mnt_mountpoint = mnt->mnt_mountpoint;
@@ -550,6 +674,10 @@ static struct vfsmount *copy_tree(struct vfsmount *mnt, struct dentry *dentry)
continue;
for (s = r; s; s = next_mnt(s, r)) {
+ if (!(flag & CL_COPY_ALL) && IS_MNT_UNBINDABLE(s)) {
+ s = skip_mnt_tree(s);
+ continue;
+ }
while (p != s->mnt_parent) {
p = p->mnt_parent;
q = q->mnt_parent;
@@ -557,7 +685,7 @@ static struct vfsmount *copy_tree(struct vfsmount *mnt, struct dentry *dentry)
p = s;
nd.mnt = q;
nd.dentry = p->mnt_mountpoint;
- q = clone_mnt(p, p->mnt_root);
+ q = clone_mnt(p, p->mnt_root, flag);
if (!q)
goto Enomem;
spin_lock(&vfsmount_lock);
@@ -567,15 +695,114 @@ static struct vfsmount *copy_tree(struct vfsmount *mnt, struct dentry *dentry)
}
}
return res;
- Enomem:
+Enomem:
if (res) {
+ LIST_HEAD(umount_list);
spin_lock(&vfsmount_lock);
- umount_tree(res);
+ umount_tree(res, 0, &umount_list);
spin_unlock(&vfsmount_lock);
+ release_mounts(&umount_list);
}
return NULL;
}
+/*
+ * @source_mnt : mount tree to be attached
+ * @nd : place the mount tree @source_mnt is attached
+ * @parent_nd : if non-null, detach the source_mnt from its parent and
+ * store the parent mount and mountpoint dentry.
+ * (done when source_mnt is moved)
+ *
+ * NOTE: in the table below explains the semantics when a source mount
+ * of a given type is attached to a destination mount of a given type.
+ * ---------------------------------------------------------------------------
+ * | BIND MOUNT OPERATION |
+ * |**************************************************************************
+ * | source-->| shared | private | slave | unbindable |
+ * | dest | | | | |
+ * | | | | | | |
+ * | v | | | | |
+ * |**************************************************************************
+ * | shared | shared (++) | shared (+) | shared(+++)| invalid |
+ * | | | | | |
+ * |non-shared| shared (+) | private | slave (*) | invalid |
+ * ***************************************************************************
+ * A bind operation clones the source mount and mounts the clone on the
+ * destination mount.
+ *
+ * (++) the cloned mount is propagated to all the mounts in the propagation
+ * tree of the destination mount and the cloned mount is added to
+ * the peer group of the source mount.
+ * (+) the cloned mount is created under the destination mount and is marked
+ * as shared. The cloned mount is added to the peer group of the source
+ * mount.
+ * (+++) the mount is propagated to all the mounts in the propagation tree
+ * of the destination mount and the cloned mount is made slave
+ * of the same master as that of the source mount. The cloned mount
+ * is marked as 'shared and slave'.
+ * (*) the cloned mount is made a slave of the same master as that of the
+ * source mount.
+ *
+ * ---------------------------------------------------------------------------
+ * | MOVE MOUNT OPERATION |
+ * |**************************************************************************
+ * | source-->| shared | private | slave | unbindable |
+ * | dest | | | | |
+ * | | | | | | |
+ * | v | | | | |
+ * |**************************************************************************
+ * | shared | shared (+) | shared (+) | shared(+++) | invalid |
+ * | | | | | |
+ * |non-shared| shared (+*) | private | slave (*) | unbindable |
+ * ***************************************************************************
+ *
+ * (+) the mount is moved to the destination. And is then propagated to
+ * all the mounts in the propagation tree of the destination mount.
+ * (+*) the mount is moved to the destination.
+ * (+++) the mount is moved to the destination and is then propagated to
+ * all the mounts belonging to the destination mount's propagation tree.
+ * the mount is marked as 'shared and slave'.
+ * (*) the mount continues to be a slave at the new location.
+ *
+ * if the source mount is a tree, the operations explained above is
+ * applied to each mount in the tree.
+ * Must be called without spinlocks held, since this function can sleep
+ * in allocations.
+ */
+static int attach_recursive_mnt(struct vfsmount *source_mnt,
+ struct nameidata *nd, struct nameidata *parent_nd)
+{
+ LIST_HEAD(tree_list);
+ struct vfsmount *dest_mnt = nd->mnt;
+ struct dentry *dest_dentry = nd->dentry;
+ struct vfsmount *child, *p;
+
+ if (propagate_mnt(dest_mnt, dest_dentry, source_mnt, &tree_list))
+ return -EINVAL;
+
+ if (IS_MNT_SHARED(dest_mnt)) {
+ for (p = source_mnt; p; p = next_mnt(p, source_mnt))
+ set_mnt_shared(p);
+ }
+
+ spin_lock(&vfsmount_lock);
+ if (parent_nd) {
+ detach_mnt(source_mnt, parent_nd);
+ attach_mnt(source_mnt, nd);
+ touch_namespace(current->namespace);
+ } else {
+ mnt_set_mountpoint(dest_mnt, dest_dentry, source_mnt);
+ commit_tree(source_mnt);
+ }
+
+ list_for_each_entry_safe(child, p, &tree_list, mnt_hash) {
+ list_del_init(&child->mnt_hash);
+ commit_tree(child);
+ }
+ spin_unlock(&vfsmount_lock);
+ return 0;
+}
+
static int graft_tree(struct vfsmount *mnt, struct nameidata *nd)
{
int err;
@@ -596,17 +823,8 @@ static int graft_tree(struct vfsmount *mnt, struct nameidata *nd)
goto out_unlock;
err = -ENOENT;
- spin_lock(&vfsmount_lock);
- if (IS_ROOT(nd->dentry) || !d_unhashed(nd->dentry)) {
- struct list_head head;
-
- attach_mnt(mnt, nd);
- list_add_tail(&head, &mnt->mnt_list);
- list_splice(&head, current->namespace->list.prev);
- mntget(mnt);
- err = 0;
- }
- spin_unlock(&vfsmount_lock);
+ if (IS_ROOT(nd->dentry) || !d_unhashed(nd->dentry))
+ err = attach_recursive_mnt(mnt, nd, NULL);
out_unlock:
up(&nd->dentry->d_inode->i_sem);
if (!err)
@@ -615,6 +833,27 @@ out_unlock:
}
/*
+ * recursively change the type of the mountpoint.
+ */
+static int do_change_type(struct nameidata *nd, int flag)
+{
+ struct vfsmount *m, *mnt = nd->mnt;
+ int recurse = flag & MS_REC;
+ int type = flag & ~MS_REC;
+
+ if (nd->dentry != nd->mnt->mnt_root)
+ return -EINVAL;
+
+ down_write(&namespace_sem);
+ spin_lock(&vfsmount_lock);
+ for (m = mnt; m; m = (recurse ? next_mnt(m, mnt) : NULL))
+ change_mnt_propagation(m, type);
+ spin_unlock(&vfsmount_lock);
+ up_write(&namespace_sem);
+ return 0;
+}
+
+/*
* do loopback mount.
*/
static int do_loopback(struct nameidata *nd, char *old_name, int recurse)
@@ -630,32 +869,34 @@ static int do_loopback(struct nameidata *nd, char *old_name, int recurse)
if (err)
return err;
- down_write(&current->namespace->sem);
+ down_write(&namespace_sem);
err = -EINVAL;
- if (check_mnt(nd->mnt) && (!recurse || check_mnt(old_nd.mnt))) {
- err = -ENOMEM;
- if (recurse)
- mnt = copy_tree(old_nd.mnt, old_nd.dentry);
- else
- mnt = clone_mnt(old_nd.mnt, old_nd.dentry);
- }
+ if (IS_MNT_UNBINDABLE(old_nd.mnt))
+ goto out;
- if (mnt) {
- /* stop bind mounts from expiring */
+ if (!check_mnt(nd->mnt) || !check_mnt(old_nd.mnt))
+ goto out;
+
+ err = -ENOMEM;
+ if (recurse)
+ mnt = copy_tree(old_nd.mnt, old_nd.dentry, 0);
+ else
+ mnt = clone_mnt(old_nd.mnt, old_nd.dentry, 0);
+
+ if (!mnt)
+ goto out;
+
+ err = graft_tree(mnt, nd);
+ if (err) {
+ LIST_HEAD(umount_list);
spin_lock(&vfsmount_lock);
- list_del_init(&mnt->mnt_expire);
+ umount_tree(mnt, 0, &umount_list);
spin_unlock(&vfsmount_lock);
-
- err = graft_tree(mnt, nd);
- if (err) {
- spin_lock(&vfsmount_lock);
- umount_tree(mnt);
- spin_unlock(&vfsmount_lock);
- } else
- mntput(mnt);
+ release_mounts(&umount_list);
}
- up_write(&current->namespace->sem);
+out:
+ up_write(&namespace_sem);
path_release(&old_nd);
return err;
}
@@ -665,12 +906,11 @@ static int do_loopback(struct nameidata *nd, char *old_name, int recurse)
* If you've mounted a non-root directory somewhere and want to do remount
* on it - tough luck.
*/
-
static int do_remount(struct nameidata *nd, int flags, int mnt_flags,
void *data)
{
int err;
- struct super_block * sb = nd->mnt->mnt_sb;
+ struct super_block *sb = nd->mnt->mnt_sb;
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
@@ -684,13 +924,23 @@ static int do_remount(struct nameidata *nd, int flags, int mnt_flags,
down_write(&sb->s_umount);
err = do_remount_sb(sb, flags, data, 0);
if (!err)
- nd->mnt->mnt_flags=mnt_flags;
+ nd->mnt->mnt_flags = mnt_flags;
up_write(&sb->s_umount);
if (!err)
security_sb_post_remount(nd->mnt, flags, data);
return err;
}
+static inline int tree_contains_unbindable(struct vfsmount *mnt)
+{
+ struct vfsmount *p;
+ for (p = mnt; p; p = next_mnt(p, mnt)) {
+ if (IS_MNT_UNBINDABLE(p))
+ return 1;
+ }
+ return 0;
+}
+
static int do_move_mount(struct nameidata *nd, char *old_name)
{
struct nameidata old_nd, parent_nd;
@@ -704,8 +954,8 @@ static int do_move_mount(struct nameidata *nd, char *old_name)
if (err)
return err;
- down_write(&current->namespace->sem);
- while(d_mountpoint(nd->dentry) && follow_down(&nd->mnt, &nd->dentry))
+ down_write(&namespace_sem);
+ while (d_mountpoint(nd->dentry) && follow_down(&nd->mnt, &nd->dentry))
;
err = -EINVAL;
if (!check_mnt(nd->mnt) || !check_mnt(old_nd.mnt))
@@ -716,39 +966,47 @@ static int do_move_mount(struct nameidata *nd, char *old_name)
if (IS_DEADDIR(nd->dentry->d_inode))
goto out1;
- spin_lock(&vfsmount_lock);
if (!IS_ROOT(nd->dentry) && d_unhashed(nd->dentry))
- goto out2;
+ goto out1;
err = -EINVAL;
if (old_nd.dentry != old_nd.mnt->mnt_root)
- goto out2;
+ goto out1;
if (old_nd.mnt == old_nd.mnt->mnt_parent)
- goto out2;
+ goto out1;
if (S_ISDIR(nd->dentry->d_inode->i_mode) !=
S_ISDIR(old_nd.dentry->d_inode->i_mode))
- goto out2;
-
+ goto out1;
+ /*
+ * Don't move a mount residing in a shared parent.
+ */
+ if (old_nd.mnt->mnt_parent && IS_MNT_SHARED(old_nd.mnt->mnt_parent))
+ goto out1;
+ /*
+ * Don't move a mount tree containing unbindable mounts to a destination
+ * mount which is shared.
+ */
+ if (IS_MNT_SHARED(nd->mnt) && tree_contains_unbindable(old_nd.mnt))
+ goto out1;
err = -ELOOP;
- for (p = nd->mnt; p->mnt_parent!=p; p = p->mnt_parent)
+ for (p = nd->mnt; p->mnt_parent != p; p = p->mnt_parent)
if (p == old_nd.mnt)
- goto out2;
- err = 0;
+ goto out1;
- detach_mnt(old_nd.mnt, &parent_nd);
- attach_mnt(old_nd.mnt, nd);
+ if ((err = attach_recursive_mnt(old_nd.mnt, nd, &parent_nd)))
+ goto out1;
+ spin_lock(&vfsmount_lock);
/* if the mount is moved, it should no longer be expire
* automatically */
list_del_init(&old_nd.mnt->mnt_expire);
-out2:
spin_unlock(&vfsmount_lock);
out1:
up(&nd->dentry->d_inode->i_sem);
out:
- up_write(&current->namespace->sem);
+ up_write(&namespace_sem);
if (!err)
path_release(&parent_nd);
path_release(&old_nd);
@@ -787,9 +1045,9 @@ int do_add_mount(struct vfsmount *newmnt, struct nameidata *nd,
{
int err;
- down_write(&current->namespace->sem);
+ down_write(&namespace_sem);
/* Something was mounted here while we slept */
- while(d_mountpoint(nd->dentry) && follow_down(&nd->mnt, &nd->dentry))
+ while (d_mountpoint(nd->dentry) && follow_down(&nd->mnt, &nd->dentry))
;
err = -EINVAL;
if (!check_mnt(nd->mnt))
@@ -806,25 +1064,28 @@ int do_add_mount(struct vfsmount *newmnt, struct nameidata *nd,
goto unlock;
newmnt->mnt_flags = mnt_flags;
- newmnt->mnt_namespace = current->namespace;
- err = graft_tree(newmnt, nd);
+ if ((err = graft_tree(newmnt, nd)))
+ goto unlock;
- if (err == 0 && fslist) {
+ if (fslist) {
/* add to the specified expiration list */
spin_lock(&vfsmount_lock);
list_add_tail(&newmnt->mnt_expire, fslist);
spin_unlock(&vfsmount_lock);
}
+ up_write(&namespace_sem);
+ return 0;
unlock:
- up_write(&current->namespace->sem);
+ up_write(&namespace_sem);
mntput(newmnt);
return err;
}
EXPORT_SYMBOL_GPL(do_add_mount);
-static void expire_mount(struct vfsmount *mnt, struct list_head *mounts)
+static void expire_mount(struct vfsmount *mnt, struct list_head *mounts,
+ struct list_head *umounts)
{
spin_lock(&vfsmount_lock);
@@ -841,27 +1102,13 @@ static void expire_mount(struct vfsmount *mnt, struct list_head *mounts)
* Check that it is still dead: the count should now be 2 - as
* contributed by the vfsmount parent and the mntget above
*/
- if (atomic_read(&mnt->mnt_count) == 2) {
- struct nameidata old_nd;
-
+ if (!propagate_mount_busy(mnt, 2)) {
/* delete from the namespace */
+ touch_namespace(mnt->mnt_namespace);
list_del_init(&mnt->mnt_list);
mnt->mnt_namespace = NULL;
- detach_mnt(mnt, &old_nd);
+ umount_tree(mnt, 1, umounts);
spin_unlock(&vfsmount_lock);
- path_release(&old_nd);
-
- /*
- * Now lay it to rest if this was the last ref on the superblock
- */
- if (atomic_read(&mnt->mnt_sb->s_active) == 1) {
- /* last instance - try to be smart */
- lock_kernel();
- DQUOT_OFF(mnt->mnt_sb);
- acct_auto_close(mnt->mnt_sb);
- unlock_kernel();
- }
- mntput(mnt);
} else {
/*
* Someone brought it back to life whilst we didn't have any
@@ -910,6 +1157,7 @@ void mark_mounts_for_expiry(struct list_head *mounts)
* - dispose of the corpse
*/
while (!list_empty(&graveyard)) {
+ LIST_HEAD(umounts);
mnt = list_entry(graveyard.next, struct vfsmount, mnt_expire);
list_del_init(&mnt->mnt_expire);
@@ -921,13 +1169,12 @@ void mark_mounts_for_expiry(struct list_head *mounts)
get_namespace(namespace);
spin_unlock(&vfsmount_lock);
- down_write(&namespace->sem);
- expire_mount(mnt, mounts);
- up_write(&namespace->sem);
-
+ down_write(&namespace_sem);
+ expire_mount(mnt, mounts, &umounts);
+ up_write(&namespace_sem);
+ release_mounts(&umounts);
mntput(mnt);
put_namespace(namespace);
-
spin_lock(&vfsmount_lock);
}
@@ -942,8 +1189,8 @@ EXPORT_SYMBOL_GPL(mark_mounts_for_expiry);
* Note that this function differs from copy_from_user() in that it will oops
* on bad values of `to', rather than returning a short copy.
*/
-static long
-exact_copy_from_user(void *to, const void __user *from, unsigned long n)
+static long exact_copy_from_user(void *to, const void __user * from,
+ unsigned long n)
{
char *t = to;
const char __user *f = from;
@@ -964,12 +1211,12 @@ exact_copy_from_user(void *to, const void __user *from, unsigned long n)
return n;
}
-int copy_mount_options(const void __user *data, unsigned long *where)
+int copy_mount_options(const void __user * data, unsigned long *where)
{
int i;
unsigned long page;
unsigned long size;
-
+
*where = 0;
if (!data)
return 0;
@@ -988,7 +1235,7 @@ int copy_mount_options(const void __user *data, unsigned long *where)
i = size - exact_copy_from_user((void *)page, data, size);
if (!i) {
- free_page(page);
+ free_page(page);
return -EFAULT;
}
if (i != PAGE_SIZE)
@@ -1011,7 +1258,7 @@ int copy_mount_options(const void __user *data, unsigned long *where)
* Therefore, if this magic number is present, it carries no information
* and must be discarded.
*/
-long do_mount(char * dev_name, char * dir_name, char *type_page,
+long do_mount(char *dev_name, char *dir_name, char *type_page,
unsigned long flags, void *data_page)
{
struct nameidata nd;
@@ -1039,7 +1286,7 @@ long do_mount(char * dev_name, char * dir_name, char *type_page,
mnt_flags |= MNT_NODEV;
if (flags & MS_NOEXEC)
mnt_flags |= MNT_NOEXEC;
- flags &= ~(MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_ACTIVE);
+ flags &= ~(MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_ACTIVE);
/* ... and get the mountpoint */
retval = path_lookup(dir_name, LOOKUP_FOLLOW, &nd);
@@ -1055,6 +1302,8 @@ long do_mount(char * dev_name, char * dir_name, char *type_page,
data_page);
else if (flags & MS_BIND)
retval = do_loopback(&nd, dev_name, flags & MS_REC);
+ else if (flags & (MS_SHARED | MS_PRIVATE | MS_SLAVE | MS_UNBINDABLE))
+ retval = do_change_type(&nd, flags);
else if (flags & MS_MOVE)
retval = do_move_mount(&nd, dev_name);
else
@@ -1091,14 +1340,16 @@ int copy_namespace(int flags, struct task_struct *tsk)
goto out;
atomic_set(&new_ns->count, 1);
- init_rwsem(&new_ns->sem);
INIT_LIST_HEAD(&new_ns->list);
+ init_waitqueue_head(&new_ns->poll);
+ new_ns->event = 0;
- down_write(&tsk->namespace->sem);
+ down_write(&namespace_sem);
/* First pass: copy the tree topology */
- new_ns->root = copy_tree(namespace->root, namespace->root->mnt_root);
+ new_ns->root = copy_tree(namespace->root, namespace->root->mnt_root,
+ CL_COPY_ALL | CL_EXPIRE);
if (!new_ns->root) {
- up_write(&tsk->namespace->sem);
+ up_write(&namespace_sem);
kfree(new_ns);
goto out;
}
@@ -1132,7 +1383,7 @@ int copy_namespace(int flags, struct task_struct *tsk)
p = next_mnt(p, namespace->root);
q = next_mnt(q, new_ns->root);
}
- up_write(&tsk->namespace->sem);
+ up_write(&namespace_sem);
tsk->namespace = new_ns;
@@ -1161,7 +1412,7 @@ asmlinkage long sys_mount(char __user * dev_name, char __user * dir_name,
unsigned long dev_page;
char *dir_page;
- retval = copy_mount_options (type, &type_page);
+ retval = copy_mount_options(type, &type_page);
if (retval < 0)
return retval;
@@ -1170,17 +1421,17 @@ asmlinkage long sys_mount(char __user * dev_name, char __user * dir_name,
if (IS_ERR(dir_page))
goto out1;
- retval = copy_mount_options (dev_name, &dev_page);
+ retval = copy_mount_options(dev_name, &dev_page);
if (retval < 0)
goto out2;
- retval = copy_mount_options (data, &data_page);
+ retval = copy_mount_options(data, &data_page);
if (retval < 0)
goto out3;
lock_kernel();
- retval = do_mount((char*)dev_page, dir_page, (char*)type_page,
- flags, (void*)data_page);
+ retval = do_mount((char *)dev_page, dir_page, (char *)type_page,
+ flags, (void *)data_page);
unlock_kernel();
free_page(data_page);
@@ -1249,9 +1500,11 @@ static void chroot_fs_refs(struct nameidata *old_nd, struct nameidata *new_nd)
if (fs) {
atomic_inc(&fs->count);
task_unlock(p);
- if (fs->root==old_nd->dentry&&fs->rootmnt==old_nd->mnt)
+ if (fs->root == old_nd->dentry
+ && fs->rootmnt == old_nd->mnt)
set_fs_root(fs, new_nd->mnt, new_nd->dentry);
- if (fs->pwd==old_nd->dentry&&fs->pwdmnt==old_nd->mnt)
+ if (fs->pwd == old_nd->dentry
+ && fs->pwdmnt == old_nd->mnt)
set_fs_pwd(fs, new_nd->mnt, new_nd->dentry);
put_fs_struct(fs);
} else
@@ -1281,8 +1534,8 @@ static void chroot_fs_refs(struct nameidata *old_nd, struct nameidata *new_nd)
* though, so you may need to say mount --bind /nfs/my_root /nfs/my_root
* first.
*/
-
-asmlinkage long sys_pivot_root(const char __user *new_root, const char __user *put_old)
+asmlinkage long sys_pivot_root(const char __user * new_root,
+ const char __user * put_old)
{
struct vfsmount *tmp;
struct nameidata new_nd, old_nd, parent_nd, root_parent, user_nd;
@@ -1293,14 +1546,15 @@ asmlinkage long sys_pivot_root(const char __user *new_root, const char __user *p
lock_kernel();
- error = __user_walk(new_root, LOOKUP_FOLLOW|LOOKUP_DIRECTORY, &new_nd);
+ error = __user_walk(new_root, LOOKUP_FOLLOW | LOOKUP_DIRECTORY,
+ &new_nd);
if (error)
goto out0;
error = -EINVAL;
if (!check_mnt(new_nd.mnt))
goto out1;
- error = __user_walk(put_old, LOOKUP_FOLLOW|LOOKUP_DIRECTORY, &old_nd);
+ error = __user_walk(put_old, LOOKUP_FOLLOW | LOOKUP_DIRECTORY, &old_nd);
if (error)
goto out1;
@@ -1314,9 +1568,13 @@ asmlinkage long sys_pivot_root(const char __user *new_root, const char __user *p
user_nd.mnt = mntget(current->fs->rootmnt);
user_nd.dentry = dget(current->fs->root);
read_unlock(&current->fs->lock);
- down_write(&current->namespace->sem);
+ down_write(&namespace_sem);
down(&old_nd.dentry->d_inode->i_sem);
error = -EINVAL;
+ if (IS_MNT_SHARED(old_nd.mnt) ||
+ IS_MNT_SHARED(new_nd.mnt->mnt_parent) ||
+ IS_MNT_SHARED(user_nd.mnt->mnt_parent))
+ goto out2;
if (!check_mnt(user_nd.mnt))
goto out2;
error = -ENOENT;
@@ -1356,6 +1614,7 @@ asmlinkage long sys_pivot_root(const char __user *new_root, const char __user *p
detach_mnt(user_nd.mnt, &root_parent);
attach_mnt(user_nd.mnt, &old_nd); /* mount old root on put_old */
attach_mnt(new_nd.mnt, &root_parent); /* mount new_root on / */
+ touch_namespace(current->namespace);
spin_unlock(&vfsmount_lock);
chroot_fs_refs(&user_nd, &new_nd);
security_sb_post_pivotroot(&user_nd, &new_nd);
@@ -1364,7 +1623,7 @@ asmlinkage long sys_pivot_root(const char __user *new_root, const char __user *p
path_release(&parent_nd);
out2:
up(&old_nd.dentry->d_inode->i_sem);
- up_write(&current->namespace->sem);
+ up_write(&namespace_sem);
path_release(&user_nd);
path_release(&old_nd);
out1:
@@ -1391,7 +1650,8 @@ static void __init init_mount_tree(void)
panic("Can't allocate initial namespace");
atomic_set(&namespace->count, 1);
INIT_LIST_HEAD(&namespace->list);
- init_rwsem(&namespace->sem);
+ init_waitqueue_head(&namespace->poll);
+ namespace->event = 0;
list_add(&mnt->mnt_list, &namespace->list);
namespace->root = mnt;
mnt->mnt_namespace = namespace;
@@ -1414,11 +1674,12 @@ void __init mnt_init(unsigned long mempages)
unsigned int nr_hash;
int i;
+ init_rwsem(&namespace_sem);
+
mnt_cache = kmem_cache_create("mnt_cache", sizeof(struct vfsmount),
- 0, SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL, NULL);
+ 0, SLAB_HWCACHE_ALIGN | SLAB_PANIC, NULL, NULL);
- mount_hashtable = (struct list_head *)
- __get_free_page(GFP_ATOMIC);
+ mount_hashtable = (struct list_head *)__get_free_page(GFP_ATOMIC);
if (!mount_hashtable)
panic("Failed to allocate mount hash table\n");
@@ -1440,7 +1701,7 @@ void __init mnt_init(unsigned long mempages)
* from the number of bits we can fit.
*/
nr_hash = 1UL << hash_bits;
- hash_mask = nr_hash-1;
+ hash_mask = nr_hash - 1;
printk("Mount-cache hash table entries: %d\n", nr_hash);
@@ -1460,12 +1721,14 @@ void __init mnt_init(unsigned long mempages)
void __put_namespace(struct namespace *namespace)
{
struct vfsmount *root = namespace->root;
+ LIST_HEAD(umount_list);
namespace->root = NULL;
spin_unlock(&vfsmount_lock);
- down_write(&namespace->sem);
+ down_write(&namespace_sem);
spin_lock(&vfsmount_lock);
- umount_tree(root);
+ umount_tree(root, 0, &umount_list);
spin_unlock(&vfsmount_lock);
- up_write(&namespace->sem);
+ up_write(&namespace_sem);
+ release_mounts(&umount_list);
kfree(namespace);
}
diff --git a/fs/ncpfs/ioctl.c b/fs/ncpfs/ioctl.c
index 88df79356a1f..fd3efdca5ae3 100644
--- a/fs/ncpfs/ioctl.c
+++ b/fs/ncpfs/ioctl.c
@@ -30,11 +30,13 @@
#define NCP_PACKET_SIZE_INTERNAL 65536
static int
-ncp_get_fs_info(struct ncp_server* server, struct inode* inode, struct ncp_fs_info __user *arg)
+ncp_get_fs_info(struct ncp_server * server, struct file *file,
+ struct ncp_fs_info __user *arg)
{
+ struct inode *inode = file->f_dentry->d_inode;
struct ncp_fs_info info;
- if ((permission(inode, MAY_WRITE, NULL) != 0)
+ if ((file_permission(file, MAY_WRITE) != 0)
&& (current->uid != server->m.mounted_uid)) {
return -EACCES;
}
@@ -58,11 +60,13 @@ ncp_get_fs_info(struct ncp_server* server, struct inode* inode, struct ncp_fs_in
}
static int
-ncp_get_fs_info_v2(struct ncp_server* server, struct inode* inode, struct ncp_fs_info_v2 __user * arg)
+ncp_get_fs_info_v2(struct ncp_server * server, struct file *file,
+ struct ncp_fs_info_v2 __user * arg)
{
+ struct inode *inode = file->f_dentry->d_inode;
struct ncp_fs_info_v2 info2;
- if ((permission(inode, MAY_WRITE, NULL) != 0)
+ if ((file_permission(file, MAY_WRITE) != 0)
&& (current->uid != server->m.mounted_uid)) {
return -EACCES;
}
@@ -190,7 +194,7 @@ int ncp_ioctl(struct inode *inode, struct file *filp,
switch (cmd) {
case NCP_IOC_NCPREQUEST:
- if ((permission(inode, MAY_WRITE, NULL) != 0)
+ if ((file_permission(filp, MAY_WRITE) != 0)
&& (current->uid != server->m.mounted_uid)) {
return -EACCES;
}
@@ -245,16 +249,16 @@ int ncp_ioctl(struct inode *inode, struct file *filp,
return ncp_conn_logged_in(inode->i_sb);
case NCP_IOC_GET_FS_INFO:
- return ncp_get_fs_info(server, inode, argp);
+ return ncp_get_fs_info(server, filp, argp);
case NCP_IOC_GET_FS_INFO_V2:
- return ncp_get_fs_info_v2(server, inode, argp);
+ return ncp_get_fs_info_v2(server, filp, argp);
case NCP_IOC_GETMOUNTUID2:
{
unsigned long tmp = server->m.mounted_uid;
- if ( (permission(inode, MAY_READ, NULL) != 0)
+ if ((file_permission(filp, MAY_READ) != 0)
&& (current->uid != server->m.mounted_uid))
{
return -EACCES;
@@ -268,7 +272,7 @@ int ncp_ioctl(struct inode *inode, struct file *filp,
{
struct ncp_setroot_ioctl sr;
- if ( (permission(inode, MAY_READ, NULL) != 0)
+ if ((file_permission(filp, MAY_READ) != 0)
&& (current->uid != server->m.mounted_uid))
{
return -EACCES;
@@ -343,7 +347,7 @@ int ncp_ioctl(struct inode *inode, struct file *filp,
#ifdef CONFIG_NCPFS_PACKET_SIGNING
case NCP_IOC_SIGN_INIT:
- if ((permission(inode, MAY_WRITE, NULL) != 0)
+ if ((file_permission(filp, MAY_WRITE) != 0)
&& (current->uid != server->m.mounted_uid))
{
return -EACCES;
@@ -366,7 +370,7 @@ int ncp_ioctl(struct inode *inode, struct file *filp,
return 0;
case NCP_IOC_SIGN_WANTED:
- if ( (permission(inode, MAY_READ, NULL) != 0)
+ if ((file_permission(filp, MAY_READ) != 0)
&& (current->uid != server->m.mounted_uid))
{
return -EACCES;
@@ -379,7 +383,7 @@ int ncp_ioctl(struct inode *inode, struct file *filp,
{
int newstate;
- if ( (permission(inode, MAY_WRITE, NULL) != 0)
+ if ((file_permission(filp, MAY_WRITE) != 0)
&& (current->uid != server->m.mounted_uid))
{
return -EACCES;
@@ -400,7 +404,7 @@ int ncp_ioctl(struct inode *inode, struct file *filp,
#ifdef CONFIG_NCPFS_IOCTL_LOCKING
case NCP_IOC_LOCKUNLOCK:
- if ( (permission(inode, MAY_WRITE, NULL) != 0)
+ if ((file_permission(filp, MAY_WRITE) != 0)
&& (current->uid != server->m.mounted_uid))
{
return -EACCES;
@@ -605,7 +609,7 @@ outrel:
#endif /* CONFIG_NCPFS_NLS */
case NCP_IOC_SETDENTRYTTL:
- if ((permission(inode, MAY_WRITE, NULL) != 0) &&
+ if ((file_permission(filp, MAY_WRITE) != 0) &&
(current->uid != server->m.mounted_uid))
return -EACCES;
{
@@ -635,7 +639,7 @@ outrel:
so we have this out of switch */
if (cmd == NCP_IOC_GETMOUNTUID) {
__kernel_uid_t uid = 0;
- if ((permission(inode, MAY_READ, NULL) != 0)
+ if ((file_permission(filp, MAY_READ) != 0)
&& (current->uid != server->m.mounted_uid)) {
return -EACCES;
}
diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c
index 4a36839f0bbd..618a327027b3 100644
--- a/fs/nfs/delegation.c
+++ b/fs/nfs/delegation.c
@@ -31,11 +31,42 @@ static void nfs_free_delegation(struct nfs_delegation *delegation)
kfree(delegation);
}
+static int nfs_delegation_claim_locks(struct nfs_open_context *ctx, struct nfs4_state *state)
+{
+ struct inode *inode = state->inode;
+ struct file_lock *fl;
+ int status;
+
+ for (fl = inode->i_flock; fl != 0; fl = fl->fl_next) {
+ if (!(fl->fl_flags & (FL_POSIX|FL_FLOCK)))
+ continue;
+ if ((struct nfs_open_context *)fl->fl_file->private_data != ctx)
+ continue;
+ status = nfs4_lock_delegation_recall(state, fl);
+ if (status >= 0)
+ continue;
+ switch (status) {
+ default:
+ printk(KERN_ERR "%s: unhandled error %d.\n",
+ __FUNCTION__, status);
+ case -NFS4ERR_EXPIRED:
+ /* kill_proc(fl->fl_pid, SIGLOST, 1); */
+ case -NFS4ERR_STALE_CLIENTID:
+ nfs4_schedule_state_recovery(NFS_SERVER(inode)->nfs4_state);
+ goto out_err;
+ }
+ }
+ return 0;
+out_err:
+ return status;
+}
+
static void nfs_delegation_claim_opens(struct inode *inode)
{
struct nfs_inode *nfsi = NFS_I(inode);
struct nfs_open_context *ctx;
struct nfs4_state *state;
+ int err;
again:
spin_lock(&inode->i_lock);
@@ -47,9 +78,12 @@ again:
continue;
get_nfs_open_context(ctx);
spin_unlock(&inode->i_lock);
- if (nfs4_open_delegation_recall(ctx->dentry, state) < 0)
- return;
+ err = nfs4_open_delegation_recall(ctx->dentry, state);
+ if (err >= 0)
+ err = nfs_delegation_claim_locks(ctx, state);
put_nfs_open_context(ctx);
+ if (err != 0)
+ return;
goto again;
}
spin_unlock(&inode->i_lock);
@@ -115,8 +149,7 @@ int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred, struct
}
}
spin_unlock(&clp->cl_lock);
- if (delegation != NULL)
- kfree(delegation);
+ kfree(delegation);
return status;
}
@@ -142,7 +175,7 @@ static void nfs_msync_inode(struct inode *inode)
/*
* Basic procedure for returning a delegation to the server
*/
-int nfs_inode_return_delegation(struct inode *inode)
+int __nfs_inode_return_delegation(struct inode *inode)
{
struct nfs4_client *clp = NFS_SERVER(inode)->nfs4_state;
struct nfs_inode *nfsi = NFS_I(inode);
diff --git a/fs/nfs/delegation.h b/fs/nfs/delegation.h
index 3f6c45a29d6a..2fcc30de924b 100644
--- a/fs/nfs/delegation.h
+++ b/fs/nfs/delegation.h
@@ -25,7 +25,7 @@ struct nfs_delegation {
int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred, struct nfs_openres *res);
void nfs_inode_reclaim_delegation(struct inode *inode, struct rpc_cred *cred, struct nfs_openres *res);
-int nfs_inode_return_delegation(struct inode *inode);
+int __nfs_inode_return_delegation(struct inode *inode);
int nfs_async_inode_return_delegation(struct inode *inode, const nfs4_stateid *stateid);
struct inode *nfs_delegation_find_inode(struct nfs4_client *clp, const struct nfs_fh *fhandle);
@@ -38,6 +38,7 @@ void nfs_delegation_reap_unclaimed(struct nfs4_client *clp);
/* NFSv4 delegation-related procedures */
int nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, const nfs4_stateid *stateid);
int nfs4_open_delegation_recall(struct dentry *dentry, struct nfs4_state *state);
+int nfs4_lock_delegation_recall(struct nfs4_state *state, struct file_lock *fl);
static inline int nfs_have_delegation(struct inode *inode, int flags)
{
@@ -47,11 +48,25 @@ static inline int nfs_have_delegation(struct inode *inode, int flags)
return 1;
return 0;
}
+
+static inline int nfs_inode_return_delegation(struct inode *inode)
+{
+ int err = 0;
+
+ if (NFS_I(inode)->delegation != NULL)
+ err = __nfs_inode_return_delegation(inode);
+ return err;
+}
#else
static inline int nfs_have_delegation(struct inode *inode, int flags)
{
return 0;
}
+
+static inline int nfs_inode_return_delegation(struct inode *inode)
+{
+ return 0;
+}
#endif
#endif
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index 2df639f143e8..7370583b61e5 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -532,6 +532,7 @@ static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
my_entry.eof = 0;
my_entry.fh = &fh;
my_entry.fattr = &fattr;
+ nfs_fattr_init(&fattr);
desc->entry = &my_entry;
while(!desc->entry->eof) {
@@ -565,8 +566,6 @@ static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
}
}
unlock_kernel();
- if (desc->error < 0)
- return desc->error;
if (res < 0)
return res;
return 0;
@@ -803,6 +802,7 @@ static int nfs_dentry_delete(struct dentry *dentry)
*/
static void nfs_dentry_iput(struct dentry *dentry, struct inode *inode)
{
+ nfs_inode_return_delegation(inode);
if (dentry->d_flags & DCACHE_NFSFS_RENAMED) {
lock_kernel();
inode->i_nlink--;
@@ -853,12 +853,6 @@ static struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, stru
dentry->d_op = NFS_PROTO(dir)->dentry_ops;
lock_kernel();
- /* Revalidate parent directory attribute cache */
- error = nfs_revalidate_inode(NFS_SERVER(dir), dir);
- if (error < 0) {
- res = ERR_PTR(error);
- goto out_unlock;
- }
/* If we're doing an exclusive create, optimize away the lookup */
if (nfs_is_exclusive_create(dir, nd))
@@ -916,7 +910,6 @@ static int is_atomic_open(struct inode *dir, struct nameidata *nd)
static struct dentry *nfs_atomic_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
{
struct dentry *res = NULL;
- struct inode *inode = NULL;
int error;
/* Check that we are indeed trying to open this file */
@@ -930,8 +923,10 @@ static struct dentry *nfs_atomic_lookup(struct inode *dir, struct dentry *dentry
dentry->d_op = NFS_PROTO(dir)->dentry_ops;
/* Let vfs_create() deal with O_EXCL */
- if (nd->intent.open.flags & O_EXCL)
- goto no_entry;
+ if (nd->intent.open.flags & O_EXCL) {
+ d_add(dentry, NULL);
+ goto out;
+ }
/* Open the file on the server */
lock_kernel();
@@ -945,32 +940,30 @@ static struct dentry *nfs_atomic_lookup(struct inode *dir, struct dentry *dentry
if (nd->intent.open.flags & O_CREAT) {
nfs_begin_data_update(dir);
- inode = nfs4_atomic_open(dir, dentry, nd);
+ res = nfs4_atomic_open(dir, dentry, nd);
nfs_end_data_update(dir);
} else
- inode = nfs4_atomic_open(dir, dentry, nd);
+ res = nfs4_atomic_open(dir, dentry, nd);
unlock_kernel();
- if (IS_ERR(inode)) {
- error = PTR_ERR(inode);
+ if (IS_ERR(res)) {
+ error = PTR_ERR(res);
switch (error) {
/* Make a negative dentry */
case -ENOENT:
- inode = NULL;
- break;
+ res = NULL;
+ goto out;
/* This turned out not to be a regular file */
+ case -EISDIR:
+ case -ENOTDIR:
+ goto no_open;
case -ELOOP:
if (!(nd->intent.open.flags & O_NOFOLLOW))
goto no_open;
- /* case -EISDIR: */
/* case -EINVAL: */
default:
- res = ERR_PTR(error);
goto out;
}
- }
-no_entry:
- res = d_add_unique(dentry, inode);
- if (res != NULL)
+ } else if (res != NULL)
dentry = res;
nfs_renew_times(dentry);
nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
@@ -1014,7 +1007,7 @@ static int nfs_open_revalidate(struct dentry *dentry, struct nameidata *nd)
*/
lock_kernel();
verifier = nfs_save_change_attribute(dir);
- ret = nfs4_open_revalidate(dir, dentry, openflags);
+ ret = nfs4_open_revalidate(dir, dentry, openflags, nd);
if (!ret)
nfs_set_verifier(dentry, verifier);
unlock_kernel();
@@ -1137,7 +1130,7 @@ static int nfs_create(struct inode *dir, struct dentry *dentry, int mode,
lock_kernel();
nfs_begin_data_update(dir);
- error = NFS_PROTO(dir)->create(dir, dentry, &attr, open_flags);
+ error = NFS_PROTO(dir)->create(dir, dentry, &attr, open_flags, nd);
nfs_end_data_update(dir);
if (error != 0)
goto out_err;
@@ -1264,6 +1257,9 @@ dentry->d_parent->d_name.name, dentry->d_name.name);
sprintf(silly, ".nfs%*.*lx",
i_inosize, i_inosize, dentry->d_inode->i_ino);
+ /* Return delegation in anticipation of the rename */
+ nfs_inode_return_delegation(dentry->d_inode);
+
sdentry = NULL;
do {
char *suffix = silly + slen - countersize;
@@ -1332,6 +1328,7 @@ static int nfs_safe_remove(struct dentry *dentry)
nfs_begin_data_update(dir);
if (inode != NULL) {
+ nfs_inode_return_delegation(inode);
nfs_begin_data_update(inode);
error = NFS_PROTO(dir)->remove(dir, &dentry->d_name);
/* The VFS may want to delete this inode */
@@ -1438,17 +1435,14 @@ nfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry)
old_dentry->d_parent->d_name.name, old_dentry->d_name.name,
dentry->d_parent->d_name.name, dentry->d_name.name);
- /*
- * Drop the dentry in advance to force a new lookup.
- * Since nfs_proc_link doesn't return a file handle,
- * we can't use the existing dentry.
- */
lock_kernel();
- d_drop(dentry);
-
nfs_begin_data_update(dir);
nfs_begin_data_update(inode);
error = NFS_PROTO(dir)->link(inode, dir, &dentry->d_name);
+ if (error == 0) {
+ atomic_inc(&inode->i_count);
+ d_instantiate(dentry, inode);
+ }
nfs_end_data_update(inode);
nfs_end_data_update(dir);
unlock_kernel();
@@ -1512,9 +1506,11 @@ static int nfs_rename(struct inode *old_dir, struct dentry *old_dentry,
*/
if (!new_inode)
goto go_ahead;
- if (S_ISDIR(new_inode->i_mode))
- goto out;
- else if (atomic_read(&new_dentry->d_count) > 2) {
+ if (S_ISDIR(new_inode->i_mode)) {
+ error = -EISDIR;
+ if (!S_ISDIR(old_inode->i_mode))
+ goto out;
+ } else if (atomic_read(&new_dentry->d_count) > 2) {
int err;
/* copy the target dentry's name */
dentry = d_alloc(new_dentry->d_parent,
@@ -1539,7 +1535,8 @@ static int nfs_rename(struct inode *old_dir, struct dentry *old_dentry,
#endif
goto out;
}
- }
+ } else
+ new_inode->i_nlink--;
go_ahead:
/*
@@ -1549,6 +1546,7 @@ go_ahead:
nfs_wb_all(old_inode);
shrink_dcache_parent(old_dentry);
}
+ nfs_inode_return_delegation(old_inode);
if (new_inode)
d_delete(new_dentry);
diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c
index 6537f2c4ae44..b497c71384e8 100644
--- a/fs/nfs/direct.c
+++ b/fs/nfs/direct.c
@@ -655,7 +655,6 @@ nfs_file_direct_read(struct kiocb *iocb, char __user *buf, size_t count, loff_t
struct file *file = iocb->ki_filp;
struct nfs_open_context *ctx =
(struct nfs_open_context *) file->private_data;
- struct dentry *dentry = file->f_dentry;
struct address_space *mapping = file->f_mapping;
struct inode *inode = mapping->host;
struct iovec iov = {
@@ -664,7 +663,8 @@ nfs_file_direct_read(struct kiocb *iocb, char __user *buf, size_t count, loff_t
};
dprintk("nfs: direct read(%s/%s, %lu@%lu)\n",
- dentry->d_parent->d_name.name, dentry->d_name.name,
+ file->f_dentry->d_parent->d_name.name,
+ file->f_dentry->d_name.name,
(unsigned long) count, (unsigned long) pos);
if (!is_sync_kiocb(iocb))
@@ -730,7 +730,6 @@ nfs_file_direct_write(struct kiocb *iocb, const char __user *buf, size_t count,
struct file *file = iocb->ki_filp;
struct nfs_open_context *ctx =
(struct nfs_open_context *) file->private_data;
- struct dentry *dentry = file->f_dentry;
struct address_space *mapping = file->f_mapping;
struct inode *inode = mapping->host;
struct iovec iov = {
@@ -739,8 +738,9 @@ nfs_file_direct_write(struct kiocb *iocb, const char __user *buf, size_t count,
};
dfprintk(VFS, "nfs: direct write(%s/%s(%ld), %lu@%lu)\n",
- dentry->d_parent->d_name.name, dentry->d_name.name,
- inode->i_ino, (unsigned long) count, (unsigned long) pos);
+ file->f_dentry->d_parent->d_name.name,
+ file->f_dentry->d_name.name, inode->i_ino,
+ (unsigned long) count, (unsigned long) pos);
if (!is_sync_kiocb(iocb))
goto out;
diff --git a/fs/nfs/file.c b/fs/nfs/file.c
index 6bdcfa95de94..57d3e77d97ee 100644
--- a/fs/nfs/file.c
+++ b/fs/nfs/file.c
@@ -205,8 +205,8 @@ nfs_file_flush(struct file *file)
if (!status) {
status = ctx->error;
ctx->error = 0;
- if (!status && !nfs_have_delegation(inode, FMODE_READ))
- __nfs_revalidate_inode(NFS_SERVER(inode), inode);
+ if (!status)
+ nfs_revalidate_inode(NFS_SERVER(inode), inode);
}
unlock_kernel();
return status;
@@ -376,22 +376,31 @@ out_swapfile:
static int do_getlk(struct file *filp, int cmd, struct file_lock *fl)
{
+ struct file_lock *cfl;
struct inode *inode = filp->f_mapping->host;
int status = 0;
lock_kernel();
- /* Use local locking if mounted with "-onolock" */
- if (!(NFS_SERVER(inode)->flags & NFS_MOUNT_NONLM))
- status = NFS_PROTO(inode)->lock(filp, cmd, fl);
- else {
- struct file_lock *cfl = posix_test_lock(filp, fl);
-
- fl->fl_type = F_UNLCK;
- if (cfl != NULL)
- memcpy(fl, cfl, sizeof(*fl));
+ /* Try local locking first */
+ cfl = posix_test_lock(filp, fl);
+ if (cfl != NULL) {
+ locks_copy_lock(fl, cfl);
+ goto out;
}
+
+ if (nfs_have_delegation(inode, FMODE_READ))
+ goto out_noconflict;
+
+ if (NFS_SERVER(inode)->flags & NFS_MOUNT_NONLM)
+ goto out_noconflict;
+
+ status = NFS_PROTO(inode)->lock(filp, cmd, fl);
+out:
unlock_kernel();
return status;
+out_noconflict:
+ fl->fl_type = F_UNLCK;
+ goto out;
}
static int do_vfs_lock(struct file *file, struct file_lock *fl)
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index d4eadeea128e..6391d8964214 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -358,6 +358,35 @@ out_no_root:
return no_root_error;
}
+static void nfs_init_timeout_values(struct rpc_timeout *to, int proto, unsigned int timeo, unsigned int retrans)
+{
+ to->to_initval = timeo * HZ / 10;
+ to->to_retries = retrans;
+ if (!to->to_retries)
+ to->to_retries = 2;
+
+ switch (proto) {
+ case IPPROTO_TCP:
+ if (!to->to_initval)
+ to->to_initval = 60 * HZ;
+ if (to->to_initval > NFS_MAX_TCP_TIMEOUT)
+ to->to_initval = NFS_MAX_TCP_TIMEOUT;
+ to->to_increment = to->to_initval;
+ to->to_maxval = to->to_initval + (to->to_increment * to->to_retries);
+ to->to_exponential = 0;
+ break;
+ case IPPROTO_UDP:
+ default:
+ if (!to->to_initval)
+ to->to_initval = 11 * HZ / 10;
+ if (to->to_initval > NFS_MAX_UDP_TIMEOUT)
+ to->to_initval = NFS_MAX_UDP_TIMEOUT;
+ to->to_maxval = NFS_MAX_UDP_TIMEOUT;
+ to->to_exponential = 1;
+ break;
+ }
+}
+
/*
* Create an RPC client handle.
*/
@@ -367,22 +396,12 @@ nfs_create_client(struct nfs_server *server, const struct nfs_mount_data *data)
struct rpc_timeout timeparms;
struct rpc_xprt *xprt = NULL;
struct rpc_clnt *clnt = NULL;
- int tcp = (data->flags & NFS_MOUNT_TCP);
+ int proto = (data->flags & NFS_MOUNT_TCP) ? IPPROTO_TCP : IPPROTO_UDP;
- /* Initialize timeout values */
- timeparms.to_initval = data->timeo * HZ / 10;
- timeparms.to_retries = data->retrans;
- timeparms.to_maxval = tcp ? RPC_MAX_TCP_TIMEOUT : RPC_MAX_UDP_TIMEOUT;
- timeparms.to_exponential = 1;
-
- if (!timeparms.to_initval)
- timeparms.to_initval = (tcp ? 600 : 11) * HZ / 10;
- if (!timeparms.to_retries)
- timeparms.to_retries = 5;
+ nfs_init_timeout_values(&timeparms, proto, data->timeo, data->retrans);
/* create transport and client */
- xprt = xprt_create_proto(tcp ? IPPROTO_TCP : IPPROTO_UDP,
- &server->addr, &timeparms);
+ xprt = xprt_create_proto(proto, &server->addr, &timeparms);
if (IS_ERR(xprt)) {
dprintk("%s: cannot create RPC transport. Error = %ld\n",
__FUNCTION__, PTR_ERR(xprt));
@@ -576,7 +595,6 @@ static int nfs_show_options(struct seq_file *m, struct vfsmount *mnt)
{ NFS_MOUNT_SOFT, ",soft", ",hard" },
{ NFS_MOUNT_INTR, ",intr", "" },
{ NFS_MOUNT_POSIX, ",posix", "" },
- { NFS_MOUNT_TCP, ",tcp", ",udp" },
{ NFS_MOUNT_NOCTO, ",nocto", "" },
{ NFS_MOUNT_NOAC, ",noac", "" },
{ NFS_MOUNT_NONLM, ",nolock", ",lock" },
@@ -585,6 +603,8 @@ static int nfs_show_options(struct seq_file *m, struct vfsmount *mnt)
};
struct proc_nfs_info *nfs_infop;
struct nfs_server *nfss = NFS_SB(mnt->mnt_sb);
+ char buf[12];
+ char *proto;
seq_printf(m, ",v%d", nfss->rpc_ops->version);
seq_printf(m, ",rsize=%d", nfss->rsize);
@@ -603,6 +623,18 @@ static int nfs_show_options(struct seq_file *m, struct vfsmount *mnt)
else
seq_puts(m, nfs_infop->nostr);
}
+ switch (nfss->client->cl_xprt->prot) {
+ case IPPROTO_TCP:
+ proto = "tcp";
+ break;
+ case IPPROTO_UDP:
+ proto = "udp";
+ break;
+ default:
+ snprintf(buf, sizeof(buf), "%u", nfss->client->cl_xprt->prot);
+ proto = buf;
+ }
+ seq_printf(m, ",proto=%s", proto);
seq_puts(m, ",addr=");
seq_escape(m, nfss->hostname, " \t\n\\");
return 0;
@@ -753,7 +785,8 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr)
else
init_special_inode(inode, inode->i_mode, fattr->rdev);
- nfsi->read_cache_jiffies = fattr->timestamp;
+ nfsi->read_cache_jiffies = fattr->time_start;
+ nfsi->last_updated = jiffies;
inode->i_atime = fattr->atime;
inode->i_mtime = fattr->mtime;
inode->i_ctime = fattr->ctime;
@@ -821,6 +854,11 @@ nfs_setattr(struct dentry *dentry, struct iattr *attr)
filemap_fdatawait(inode->i_mapping);
nfs_wb_all(inode);
}
+ /*
+ * Return any delegations if we're going to change ACLs
+ */
+ if ((attr->ia_valid & (ATTR_MODE|ATTR_UID|ATTR_GID)) != 0)
+ nfs_inode_return_delegation(inode);
error = NFS_PROTO(inode)->setattr(dentry, &fattr, attr);
if (error == 0)
nfs_refresh_inode(inode, &fattr);
@@ -971,13 +1009,18 @@ void nfs_file_set_open_context(struct file *filp, struct nfs_open_context *ctx)
spin_unlock(&inode->i_lock);
}
-struct nfs_open_context *nfs_find_open_context(struct inode *inode, int mode)
+/*
+ * Given an inode, search for an open context with the desired characteristics
+ */
+struct nfs_open_context *nfs_find_open_context(struct inode *inode, struct rpc_cred *cred, int mode)
{
struct nfs_inode *nfsi = NFS_I(inode);
struct nfs_open_context *pos, *ctx = NULL;
spin_lock(&inode->i_lock);
list_for_each_entry(pos, &nfsi->open_files, list) {
+ if (cred != NULL && pos->cred != cred)
+ continue;
if ((pos->mode & mode) == mode) {
ctx = get_nfs_open_context(pos);
break;
@@ -1019,15 +1062,11 @@ int nfs_open(struct inode *inode, struct file *filp)
ctx->mode = filp->f_mode;
nfs_file_set_open_context(filp, ctx);
put_nfs_open_context(ctx);
- if ((filp->f_mode & FMODE_WRITE) != 0)
- nfs_begin_data_update(inode);
return 0;
}
int nfs_release(struct inode *inode, struct file *filp)
{
- if ((filp->f_mode & FMODE_WRITE) != 0)
- nfs_end_data_update(inode);
nfs_file_clear_open_context(filp);
return 0;
}
@@ -1083,14 +1122,15 @@ __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode)
goto out;
}
+ spin_lock(&inode->i_lock);
status = nfs_update_inode(inode, &fattr, verifier);
if (status) {
+ spin_unlock(&inode->i_lock);
dfprintk(PAGECACHE, "nfs_revalidate_inode: (%s/%Ld) refresh failed, error=%d\n",
inode->i_sb->s_id,
(long long)NFS_FILEID(inode), status);
goto out;
}
- spin_lock(&inode->i_lock);
cache_validity = nfsi->cache_validity;
nfsi->cache_validity &= ~NFS_INO_REVAL_PAGECACHE;
@@ -1098,7 +1138,7 @@ __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode)
* We may need to keep the attributes marked as invalid if
* we raced with nfs_end_attr_update().
*/
- if (verifier == nfsi->cache_change_attribute)
+ if (time_after_eq(verifier, nfsi->cache_change_attribute))
nfsi->cache_validity &= ~(NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ATIME);
spin_unlock(&inode->i_lock);
@@ -1165,7 +1205,7 @@ void nfs_revalidate_mapping(struct inode *inode, struct address_space *mapping)
if (S_ISDIR(inode->i_mode)) {
memset(nfsi->cookieverf, 0, sizeof(nfsi->cookieverf));
/* This ensures we revalidate child dentries */
- nfsi->cache_change_attribute++;
+ nfsi->cache_change_attribute = jiffies;
}
spin_unlock(&inode->i_lock);
@@ -1197,20 +1237,19 @@ void nfs_end_data_update(struct inode *inode)
struct nfs_inode *nfsi = NFS_I(inode);
if (!nfs_have_delegation(inode, FMODE_READ)) {
- /* Mark the attribute cache for revalidation */
- spin_lock(&inode->i_lock);
- nfsi->cache_validity |= NFS_INO_INVALID_ATTR;
- /* Directories and symlinks: invalidate page cache too */
- if (S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode))
+ /* Directories and symlinks: invalidate page cache */
+ if (S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode)) {
+ spin_lock(&inode->i_lock);
nfsi->cache_validity |= NFS_INO_INVALID_DATA;
- spin_unlock(&inode->i_lock);
+ spin_unlock(&inode->i_lock);
+ }
}
- nfsi->cache_change_attribute ++;
+ nfsi->cache_change_attribute = jiffies;
atomic_dec(&nfsi->data_updates);
}
/**
- * nfs_refresh_inode - verify consistency of the inode attribute cache
+ * nfs_check_inode_attributes - verify consistency of the inode attribute cache
* @inode - pointer to inode
* @fattr - updated attributes
*
@@ -1218,13 +1257,12 @@ void nfs_end_data_update(struct inode *inode)
* so that fattr carries weak cache consistency data, then it may
* also update the ctime/mtime/change_attribute.
*/
-int nfs_refresh_inode(struct inode *inode, struct nfs_fattr *fattr)
+static int nfs_check_inode_attributes(struct inode *inode, struct nfs_fattr *fattr)
{
struct nfs_inode *nfsi = NFS_I(inode);
loff_t cur_size, new_isize;
int data_unstable;
- spin_lock(&inode->i_lock);
/* Are we in the process of updating data on the server? */
data_unstable = nfs_caches_unstable(inode);
@@ -1241,14 +1279,12 @@ int nfs_refresh_inode(struct inode *inode, struct nfs_fattr *fattr)
}
if ((fattr->valid & NFS_ATTR_FATTR) == 0) {
- spin_unlock(&inode->i_lock);
return 0;
}
/* Has the inode gone and changed behind our back? */
if (nfsi->fileid != fattr->fileid
|| (inode->i_mode & S_IFMT) != (fattr->mode & S_IFMT)) {
- spin_unlock(&inode->i_lock);
return -EIO;
}
@@ -1288,11 +1324,67 @@ int nfs_refresh_inode(struct inode *inode, struct nfs_fattr *fattr)
if (!timespec_equal(&inode->i_atime, &fattr->atime))
nfsi->cache_validity |= NFS_INO_INVALID_ATIME;
- nfsi->read_cache_jiffies = fattr->timestamp;
- spin_unlock(&inode->i_lock);
+ nfsi->read_cache_jiffies = fattr->time_start;
return 0;
}
+/**
+ * nfs_refresh_inode - try to update the inode attribute cache
+ * @inode - pointer to inode
+ * @fattr - updated attributes
+ *
+ * Check that an RPC call that returned attributes has not overlapped with
+ * other recent updates of the inode metadata, then decide whether it is
+ * safe to do a full update of the inode attributes, or whether just to
+ * call nfs_check_inode_attributes.
+ */
+int nfs_refresh_inode(struct inode *inode, struct nfs_fattr *fattr)
+{
+ struct nfs_inode *nfsi = NFS_I(inode);
+ int status;
+
+ if ((fattr->valid & NFS_ATTR_FATTR) == 0)
+ return 0;
+ spin_lock(&inode->i_lock);
+ nfsi->cache_validity &= ~NFS_INO_REVAL_PAGECACHE;
+ if (nfs_verify_change_attribute(inode, fattr->time_start))
+ nfsi->cache_validity &= ~(NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ATIME);
+ if (time_after(fattr->time_start, nfsi->last_updated))
+ status = nfs_update_inode(inode, fattr, fattr->time_start);
+ else
+ status = nfs_check_inode_attributes(inode, fattr);
+
+ spin_unlock(&inode->i_lock);
+ return status;
+}
+
+/**
+ * nfs_post_op_update_inode - try to update the inode attribute cache
+ * @inode - pointer to inode
+ * @fattr - updated attributes
+ *
+ * After an operation that has changed the inode metadata, mark the
+ * attribute cache as being invalid, then try to update it.
+ */
+int nfs_post_op_update_inode(struct inode *inode, struct nfs_fattr *fattr)
+{
+ struct nfs_inode *nfsi = NFS_I(inode);
+ int status = 0;
+
+ spin_lock(&inode->i_lock);
+ if (unlikely((fattr->valid & NFS_ATTR_FATTR) == 0)) {
+ nfsi->cache_validity |= NFS_INO_INVALID_ATTR | NFS_INO_INVALID_ACCESS;
+ goto out;
+ }
+ status = nfs_update_inode(inode, fattr, fattr->time_start);
+ if (time_after_eq(fattr->time_start, nfsi->cache_change_attribute))
+ nfsi->cache_validity &= ~(NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ATIME|NFS_INO_REVAL_PAGECACHE);
+ nfsi->cache_change_attribute = jiffies;
+out:
+ spin_unlock(&inode->i_lock);
+ return status;
+}
+
/*
* Many nfs protocol calls return the new file attributes after
* an operation. Here we update the inode to reflect the state
@@ -1328,20 +1420,17 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr, unsign
goto out_err;
}
- spin_lock(&inode->i_lock);
-
/*
* Make sure the inode's type hasn't changed.
*/
- if ((inode->i_mode & S_IFMT) != (fattr->mode & S_IFMT)) {
- spin_unlock(&inode->i_lock);
+ if ((inode->i_mode & S_IFMT) != (fattr->mode & S_IFMT))
goto out_changed;
- }
/*
* Update the read time so we don't revalidate too often.
*/
- nfsi->read_cache_jiffies = fattr->timestamp;
+ nfsi->read_cache_jiffies = fattr->time_start;
+ nfsi->last_updated = jiffies;
/* Are we racing with known updates of the metadata on the server? */
data_unstable = ! (nfs_verify_change_attribute(inode, verifier) ||
@@ -1354,7 +1443,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr, unsign
/* Do we perhaps have any outstanding writes? */
if (nfsi->npages == 0) {
/* No, but did we race with nfs_end_data_update()? */
- if (verifier == nfsi->cache_change_attribute) {
+ if (time_after_eq(verifier, nfsi->cache_change_attribute)) {
inode->i_size = new_isize;
invalid |= NFS_INO_INVALID_DATA;
}
@@ -1430,7 +1519,6 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr, unsign
if (!nfs_have_delegation(inode, FMODE_READ))
nfsi->cache_validity |= invalid;
- spin_unlock(&inode->i_lock);
return 0;
out_changed:
/*
@@ -1600,8 +1688,7 @@ static void nfs_kill_super(struct super_block *s)
rpciod_down(); /* release rpciod */
- if (server->hostname != NULL)
- kfree(server->hostname);
+ kfree(server->hostname);
kfree(server);
}
@@ -1639,8 +1726,7 @@ static void nfs4_clear_inode(struct inode *inode)
struct nfs_inode *nfsi = NFS_I(inode);
/* If we are holding a delegation, return it! */
- if (nfsi->delegation != NULL)
- nfs_inode_return_delegation(inode);
+ nfs_inode_return_delegation(inode);
/* First call standard NFS clear_inode() code */
nfs_clear_inode(inode);
/* Now clear out any remaining state */
@@ -1669,7 +1755,7 @@ static int nfs4_fill_super(struct super_block *sb, struct nfs4_mount_data *data,
struct rpc_clnt *clnt = NULL;
struct rpc_timeout timeparms;
rpc_authflavor_t authflavour;
- int proto, err = -EIO;
+ int err = -EIO;
sb->s_blocksize_bits = 0;
sb->s_blocksize = 0;
@@ -1687,30 +1773,8 @@ static int nfs4_fill_super(struct super_block *sb, struct nfs4_mount_data *data,
server->acdirmax = data->acdirmax*HZ;
server->rpc_ops = &nfs_v4_clientops;
- /* Initialize timeout values */
-
- timeparms.to_initval = data->timeo * HZ / 10;
- timeparms.to_retries = data->retrans;
- timeparms.to_exponential = 1;
- if (!timeparms.to_retries)
- timeparms.to_retries = 5;
- proto = data->proto;
- /* Which IP protocol do we use? */
- switch (proto) {
- case IPPROTO_TCP:
- timeparms.to_maxval = RPC_MAX_TCP_TIMEOUT;
- if (!timeparms.to_initval)
- timeparms.to_initval = 600 * HZ / 10;
- break;
- case IPPROTO_UDP:
- timeparms.to_maxval = RPC_MAX_UDP_TIMEOUT;
- if (!timeparms.to_initval)
- timeparms.to_initval = 11 * HZ / 10;
- break;
- default:
- return -EINVAL;
- }
+ nfs_init_timeout_values(&timeparms, data->proto, data->timeo, data->retrans);
clp = nfs4_get_client(&server->addr.sin_addr);
if (!clp) {
@@ -1735,7 +1799,7 @@ static int nfs4_fill_super(struct super_block *sb, struct nfs4_mount_data *data,
down_write(&clp->cl_sem);
if (IS_ERR(clp->cl_rpcclient)) {
- xprt = xprt_create_proto(proto, &server->addr, &timeparms);
+ xprt = xprt_create_proto(data->proto, &server->addr, &timeparms);
if (IS_ERR(xprt)) {
up_write(&clp->cl_sem);
err = PTR_ERR(xprt);
@@ -1843,8 +1907,7 @@ nfs_copy_user_string(char *dst, struct nfs_string *src, int maxlen)
return ERR_PTR(-ENOMEM);
}
if (copy_from_user(dst, src->data, maxlen)) {
- if (p != NULL)
- kfree(p);
+ kfree(p);
return ERR_PTR(-EFAULT);
}
dst[maxlen] = '\0';
@@ -1935,10 +1998,8 @@ static struct super_block *nfs4_get_sb(struct file_system_type *fs_type,
out_err:
s = (struct super_block *)p;
out_free:
- if (server->mnt_path)
- kfree(server->mnt_path);
- if (server->hostname)
- kfree(server->hostname);
+ kfree(server->mnt_path);
+ kfree(server->hostname);
kfree(server);
return s;
}
@@ -1958,8 +2019,7 @@ static void nfs4_kill_super(struct super_block *sb)
destroy_nfsv4_state(server);
- if (server->hostname != NULL)
- kfree(server->hostname);
+ kfree(server->hostname);
kfree(server);
}
diff --git a/fs/nfs/nfs2xdr.c b/fs/nfs/nfs2xdr.c
index d91b69044a4d..59049e864ca7 100644
--- a/fs/nfs/nfs2xdr.c
+++ b/fs/nfs/nfs2xdr.c
@@ -143,7 +143,6 @@ xdr_decode_fattr(u32 *p, struct nfs_fattr *fattr)
fattr->mode = (fattr->mode & ~S_IFMT) | S_IFIFO;
fattr->rdev = 0;
}
- fattr->timestamp = jiffies;
return p;
}
diff --git a/fs/nfs/nfs3proc.c b/fs/nfs/nfs3proc.c
index edc95514046d..92c870d19ccd 100644
--- a/fs/nfs/nfs3proc.c
+++ b/fs/nfs/nfs3proc.c
@@ -78,7 +78,7 @@ nfs3_proc_get_root(struct nfs_server *server, struct nfs_fh *fhandle,
int status;
dprintk("%s: call fsinfo\n", __FUNCTION__);
- info->fattr->valid = 0;
+ nfs_fattr_init(info->fattr);
status = rpc_call(server->client_sys, NFS3PROC_FSINFO, fhandle, info, 0);
dprintk("%s: reply fsinfo: %d\n", __FUNCTION__, status);
if (!(info->fattr->valid & NFS_ATTR_FATTR)) {
@@ -98,7 +98,7 @@ nfs3_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle,
int status;
dprintk("NFS call getattr\n");
- fattr->valid = 0;
+ nfs_fattr_init(fattr);
status = rpc_call(server->client, NFS3PROC_GETATTR,
fhandle, fattr, 0);
dprintk("NFS reply getattr: %d\n", status);
@@ -117,7 +117,7 @@ nfs3_proc_setattr(struct dentry *dentry, struct nfs_fattr *fattr,
int status;
dprintk("NFS call setattr\n");
- fattr->valid = 0;
+ nfs_fattr_init(fattr);
status = rpc_call(NFS_CLIENT(inode), NFS3PROC_SETATTR, &arg, fattr, 0);
if (status == 0)
nfs_setattr_update_inode(inode, sattr);
@@ -143,8 +143,8 @@ nfs3_proc_lookup(struct inode *dir, struct qstr *name,
int status;
dprintk("NFS call lookup %s\n", name->name);
- dir_attr.valid = 0;
- fattr->valid = 0;
+ nfs_fattr_init(&dir_attr);
+ nfs_fattr_init(fattr);
status = rpc_call(NFS_CLIENT(dir), NFS3PROC_LOOKUP, &arg, &res, 0);
if (status >= 0 && !(fattr->valid & NFS_ATTR_FATTR))
status = rpc_call(NFS_CLIENT(dir), NFS3PROC_GETATTR,
@@ -174,7 +174,6 @@ static int nfs3_proc_access(struct inode *inode, struct nfs_access_entry *entry)
int status;
dprintk("NFS call access\n");
- fattr.valid = 0;
if (mode & MAY_READ)
arg.access |= NFS3_ACCESS_READ;
@@ -189,6 +188,7 @@ static int nfs3_proc_access(struct inode *inode, struct nfs_access_entry *entry)
if (mode & MAY_EXEC)
arg.access |= NFS3_ACCESS_EXECUTE;
}
+ nfs_fattr_init(&fattr);
status = rpc_call_sync(NFS_CLIENT(inode), &msg, 0);
nfs_refresh_inode(inode, &fattr);
if (status == 0) {
@@ -217,7 +217,7 @@ static int nfs3_proc_readlink(struct inode *inode, struct page *page,
int status;
dprintk("NFS call readlink\n");
- fattr.valid = 0;
+ nfs_fattr_init(&fattr);
status = rpc_call(NFS_CLIENT(inode), NFS3PROC_READLINK,
&args, &fattr, 0);
nfs_refresh_inode(inode, &fattr);
@@ -240,7 +240,7 @@ static int nfs3_proc_read(struct nfs_read_data *rdata)
dprintk("NFS call read %d @ %Ld\n", rdata->args.count,
(long long) rdata->args.offset);
- fattr->valid = 0;
+ nfs_fattr_init(fattr);
status = rpc_call_sync(NFS_CLIENT(inode), &msg, flags);
if (status >= 0)
nfs_refresh_inode(inode, fattr);
@@ -263,10 +263,10 @@ static int nfs3_proc_write(struct nfs_write_data *wdata)
dprintk("NFS call write %d @ %Ld\n", wdata->args.count,
(long long) wdata->args.offset);
- fattr->valid = 0;
+ nfs_fattr_init(fattr);
status = rpc_call_sync(NFS_CLIENT(inode), &msg, rpcflags);
if (status >= 0)
- nfs_refresh_inode(inode, fattr);
+ nfs_post_op_update_inode(inode, fattr);
dprintk("NFS reply write: %d\n", status);
return status < 0? status : wdata->res.count;
}
@@ -285,10 +285,10 @@ static int nfs3_proc_commit(struct nfs_write_data *cdata)
dprintk("NFS call commit %d @ %Ld\n", cdata->args.count,
(long long) cdata->args.offset);
- fattr->valid = 0;
+ nfs_fattr_init(fattr);
status = rpc_call_sync(NFS_CLIENT(inode), &msg, 0);
if (status >= 0)
- nfs_refresh_inode(inode, fattr);
+ nfs_post_op_update_inode(inode, fattr);
dprintk("NFS reply commit: %d\n", status);
return status;
}
@@ -299,7 +299,7 @@ static int nfs3_proc_commit(struct nfs_write_data *cdata)
*/
static int
nfs3_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
- int flags)
+ int flags, struct nameidata *nd)
{
struct nfs_fh fhandle;
struct nfs_fattr fattr;
@@ -329,10 +329,10 @@ nfs3_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
sattr->ia_mode &= ~current->fs->umask;
again:
- dir_attr.valid = 0;
- fattr.valid = 0;
+ nfs_fattr_init(&dir_attr);
+ nfs_fattr_init(&fattr);
status = rpc_call(NFS_CLIENT(dir), NFS3PROC_CREATE, &arg, &res, 0);
- nfs_refresh_inode(dir, &dir_attr);
+ nfs_post_op_update_inode(dir, &dir_attr);
/* If the server doesn't support the exclusive creation semantics,
* try again with simple 'guarded' mode. */
@@ -401,9 +401,9 @@ nfs3_proc_remove(struct inode *dir, struct qstr *name)
int status;
dprintk("NFS call remove %s\n", name->name);
- dir_attr.valid = 0;
+ nfs_fattr_init(&dir_attr);
status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
- nfs_refresh_inode(dir, &dir_attr);
+ nfs_post_op_update_inode(dir, &dir_attr);
dprintk("NFS reply remove: %d\n", status);
return status;
}
@@ -422,7 +422,7 @@ nfs3_proc_unlink_setup(struct rpc_message *msg, struct dentry *dir, struct qstr
ptr->arg.fh = NFS_FH(dir->d_inode);
ptr->arg.name = name->name;
ptr->arg.len = name->len;
- ptr->res.valid = 0;
+ nfs_fattr_init(&ptr->res);
msg->rpc_proc = &nfs3_procedures[NFS3PROC_REMOVE];
msg->rpc_argp = &ptr->arg;
msg->rpc_resp = &ptr->res;
@@ -439,7 +439,7 @@ nfs3_proc_unlink_done(struct dentry *dir, struct rpc_task *task)
return 1;
if (msg->rpc_argp) {
dir_attr = (struct nfs_fattr*)msg->rpc_resp;
- nfs_refresh_inode(dir->d_inode, dir_attr);
+ nfs_post_op_update_inode(dir->d_inode, dir_attr);
kfree(msg->rpc_argp);
}
return 0;
@@ -465,11 +465,11 @@ nfs3_proc_rename(struct inode *old_dir, struct qstr *old_name,
int status;
dprintk("NFS call rename %s -> %s\n", old_name->name, new_name->name);
- old_dir_attr.valid = 0;
- new_dir_attr.valid = 0;
+ nfs_fattr_init(&old_dir_attr);
+ nfs_fattr_init(&new_dir_attr);
status = rpc_call(NFS_CLIENT(old_dir), NFS3PROC_RENAME, &arg, &res, 0);
- nfs_refresh_inode(old_dir, &old_dir_attr);
- nfs_refresh_inode(new_dir, &new_dir_attr);
+ nfs_post_op_update_inode(old_dir, &old_dir_attr);
+ nfs_post_op_update_inode(new_dir, &new_dir_attr);
dprintk("NFS reply rename: %d\n", status);
return status;
}
@@ -491,11 +491,11 @@ nfs3_proc_link(struct inode *inode, struct inode *dir, struct qstr *name)
int status;
dprintk("NFS call link %s\n", name->name);
- dir_attr.valid = 0;
- fattr.valid = 0;
+ nfs_fattr_init(&dir_attr);
+ nfs_fattr_init(&fattr);
status = rpc_call(NFS_CLIENT(inode), NFS3PROC_LINK, &arg, &res, 0);
- nfs_refresh_inode(dir, &dir_attr);
- nfs_refresh_inode(inode, &fattr);
+ nfs_post_op_update_inode(dir, &dir_attr);
+ nfs_post_op_update_inode(inode, &fattr);
dprintk("NFS reply link: %d\n", status);
return status;
}
@@ -524,10 +524,10 @@ nfs3_proc_symlink(struct inode *dir, struct qstr *name, struct qstr *path,
if (path->len > NFS3_MAXPATHLEN)
return -ENAMETOOLONG;
dprintk("NFS call symlink %s -> %s\n", name->name, path->name);
- dir_attr.valid = 0;
- fattr->valid = 0;
+ nfs_fattr_init(&dir_attr);
+ nfs_fattr_init(fattr);
status = rpc_call(NFS_CLIENT(dir), NFS3PROC_SYMLINK, &arg, &res, 0);
- nfs_refresh_inode(dir, &dir_attr);
+ nfs_post_op_update_inode(dir, &dir_attr);
dprintk("NFS reply symlink: %d\n", status);
return status;
}
@@ -552,13 +552,13 @@ nfs3_proc_mkdir(struct inode *dir, struct dentry *dentry, struct iattr *sattr)
int status;
dprintk("NFS call mkdir %s\n", dentry->d_name.name);
- dir_attr.valid = 0;
- fattr.valid = 0;
sattr->ia_mode &= ~current->fs->umask;
+ nfs_fattr_init(&dir_attr);
+ nfs_fattr_init(&fattr);
status = rpc_call(NFS_CLIENT(dir), NFS3PROC_MKDIR, &arg, &res, 0);
- nfs_refresh_inode(dir, &dir_attr);
+ nfs_post_op_update_inode(dir, &dir_attr);
if (status != 0)
goto out;
status = nfs_instantiate(dentry, &fhandle, &fattr);
@@ -582,9 +582,9 @@ nfs3_proc_rmdir(struct inode *dir, struct qstr *name)
int status;
dprintk("NFS call rmdir %s\n", name->name);
- dir_attr.valid = 0;
+ nfs_fattr_init(&dir_attr);
status = rpc_call(NFS_CLIENT(dir), NFS3PROC_RMDIR, &arg, &dir_attr, 0);
- nfs_refresh_inode(dir, &dir_attr);
+ nfs_post_op_update_inode(dir, &dir_attr);
dprintk("NFS reply rmdir: %d\n", status);
return status;
}
@@ -634,7 +634,7 @@ nfs3_proc_readdir(struct dentry *dentry, struct rpc_cred *cred,
dprintk("NFS call readdir%s %d\n",
plus? "plus" : "", (unsigned int) cookie);
- dir_attr.valid = 0;
+ nfs_fattr_init(&dir_attr);
status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
nfs_refresh_inode(dir, &dir_attr);
dprintk("NFS reply readdir: %d\n", status);
@@ -676,10 +676,10 @@ nfs3_proc_mknod(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
sattr->ia_mode &= ~current->fs->umask;
- dir_attr.valid = 0;
- fattr.valid = 0;
+ nfs_fattr_init(&dir_attr);
+ nfs_fattr_init(&fattr);
status = rpc_call(NFS_CLIENT(dir), NFS3PROC_MKNOD, &arg, &res, 0);
- nfs_refresh_inode(dir, &dir_attr);
+ nfs_post_op_update_inode(dir, &dir_attr);
if (status != 0)
goto out;
status = nfs_instantiate(dentry, &fh, &fattr);
@@ -698,7 +698,7 @@ nfs3_proc_statfs(struct nfs_server *server, struct nfs_fh *fhandle,
int status;
dprintk("NFS call fsstat\n");
- stat->fattr->valid = 0;
+ nfs_fattr_init(stat->fattr);
status = rpc_call(server->client, NFS3PROC_FSSTAT, fhandle, stat, 0);
dprintk("NFS reply statfs: %d\n", status);
return status;
@@ -711,7 +711,7 @@ nfs3_proc_fsinfo(struct nfs_server *server, struct nfs_fh *fhandle,
int status;
dprintk("NFS call fsinfo\n");
- info->fattr->valid = 0;
+ nfs_fattr_init(info->fattr);
status = rpc_call(server->client_sys, NFS3PROC_FSINFO, fhandle, info, 0);
dprintk("NFS reply fsinfo: %d\n", status);
return status;
@@ -724,7 +724,7 @@ nfs3_proc_pathconf(struct nfs_server *server, struct nfs_fh *fhandle,
int status;
dprintk("NFS call pathconf\n");
- info->fattr->valid = 0;
+ nfs_fattr_init(info->fattr);
status = rpc_call(server->client, NFS3PROC_PATHCONF, fhandle, info, 0);
dprintk("NFS reply pathconf: %d\n", status);
return status;
@@ -735,7 +735,7 @@ extern u32 *nfs3_decode_dirent(u32 *, struct nfs_entry *, int);
static void
nfs3_read_done(struct rpc_task *task)
{
- struct nfs_write_data *data = (struct nfs_write_data *) task->tk_calldata;
+ struct nfs_read_data *data = (struct nfs_read_data *) task->tk_calldata;
if (nfs3_async_handle_jukebox(task))
return;
@@ -775,7 +775,7 @@ nfs3_write_done(struct rpc_task *task)
return;
data = (struct nfs_write_data *)task->tk_calldata;
if (task->tk_status >= 0)
- nfs_refresh_inode(data->inode, data->res.fattr);
+ nfs_post_op_update_inode(data->inode, data->res.fattr);
nfs_writeback_done(task);
}
@@ -819,7 +819,7 @@ nfs3_commit_done(struct rpc_task *task)
return;
data = (struct nfs_write_data *)task->tk_calldata;
if (task->tk_status >= 0)
- nfs_refresh_inode(data->inode, data->res.fattr);
+ nfs_post_op_update_inode(data->inode, data->res.fattr);
nfs_commit_done(task);
}
diff --git a/fs/nfs/nfs3xdr.c b/fs/nfs/nfs3xdr.c
index db4a904810a4..0498bd36602c 100644
--- a/fs/nfs/nfs3xdr.c
+++ b/fs/nfs/nfs3xdr.c
@@ -174,7 +174,6 @@ xdr_decode_fattr(u32 *p, struct nfs_fattr *fattr)
/* Update the mode bits */
fattr->valid |= (NFS_ATTR_FATTR | NFS_ATTR_FATTR_V3);
- fattr->timestamp = jiffies;
return p;
}
diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h
index ec1a22d7b876..b7f262dcb6e3 100644
--- a/fs/nfs/nfs4_fs.h
+++ b/fs/nfs/nfs4_fs.h
@@ -93,25 +93,50 @@ struct nfs4_client {
};
/*
+ * struct rpc_sequence ensures that RPC calls are sent in the exact
+ * order that they appear on the list.
+ */
+struct rpc_sequence {
+ struct rpc_wait_queue wait; /* RPC call delay queue */
+ spinlock_t lock; /* Protects the list */
+ struct list_head list; /* Defines sequence of RPC calls */
+};
+
+#define NFS_SEQID_CONFIRMED 1
+struct nfs_seqid_counter {
+ struct rpc_sequence *sequence;
+ int flags;
+ u32 counter;
+};
+
+struct nfs_seqid {
+ struct nfs_seqid_counter *sequence;
+ struct list_head list;
+};
+
+static inline void nfs_confirm_seqid(struct nfs_seqid_counter *seqid, int status)
+{
+ if (seqid_mutating_err(-status))
+ seqid->flags |= NFS_SEQID_CONFIRMED;
+}
+
+/*
* NFS4 state_owners and lock_owners are simply labels for ordered
* sequences of RPC calls. Their sole purpose is to provide once-only
* semantics by allowing the server to identify replayed requests.
- *
- * The ->so_sema is held during all state_owner seqid-mutating operations:
- * OPEN, OPEN_DOWNGRADE, and CLOSE. Its purpose is to properly serialize
- * so_seqid.
*/
struct nfs4_state_owner {
+ spinlock_t so_lock;
struct list_head so_list; /* per-clientid list of state_owners */
struct nfs4_client *so_client;
u32 so_id; /* 32-bit identifier, unique */
- struct semaphore so_sema;
- u32 so_seqid; /* protected by so_sema */
atomic_t so_count;
struct rpc_cred *so_cred; /* Associated cred */
struct list_head so_states;
struct list_head so_delegations;
+ struct nfs_seqid_counter so_seqid;
+ struct rpc_sequence so_sequence;
};
/*
@@ -132,7 +157,7 @@ struct nfs4_lock_state {
fl_owner_t ls_owner; /* POSIX lock owner */
#define NFS_LOCK_INITIALIZED 1
int ls_flags;
- u32 ls_seqid;
+ struct nfs_seqid_counter ls_seqid;
u32 ls_id;
nfs4_stateid ls_stateid;
atomic_t ls_count;
@@ -153,7 +178,6 @@ struct nfs4_state {
struct inode *inode; /* Pointer to the inode */
unsigned long flags; /* Do we hold any locks? */
- struct semaphore lock_sema; /* Serializes file locking operations */
spinlock_t state_lock; /* Protects the lock_states list */
nfs4_stateid stateid;
@@ -190,9 +214,9 @@ extern int nfs4_proc_setclientid(struct nfs4_client *, u32, unsigned short);
extern int nfs4_proc_setclientid_confirm(struct nfs4_client *);
extern int nfs4_proc_async_renew(struct nfs4_client *);
extern int nfs4_proc_renew(struct nfs4_client *);
-extern int nfs4_do_close(struct inode *inode, struct nfs4_state *state, mode_t mode);
-extern struct inode *nfs4_atomic_open(struct inode *, struct dentry *, struct nameidata *);
-extern int nfs4_open_revalidate(struct inode *, struct dentry *, int);
+extern int nfs4_do_close(struct inode *inode, struct nfs4_state *state);
+extern struct dentry *nfs4_atomic_open(struct inode *, struct dentry *, struct nameidata *);
+extern int nfs4_open_revalidate(struct inode *, struct dentry *, int, struct nameidata *);
extern struct nfs4_state_recovery_ops nfs4_reboot_recovery_ops;
extern struct nfs4_state_recovery_ops nfs4_network_partition_recovery_ops;
@@ -223,13 +247,18 @@ extern void nfs4_drop_state_owner(struct nfs4_state_owner *);
extern struct nfs4_state * nfs4_get_open_state(struct inode *, struct nfs4_state_owner *);
extern void nfs4_put_open_state(struct nfs4_state *);
extern void nfs4_close_state(struct nfs4_state *, mode_t);
-extern struct nfs4_state *nfs4_find_state(struct inode *, struct rpc_cred *, mode_t mode);
-extern void nfs4_increment_seqid(int status, struct nfs4_state_owner *sp);
+extern void nfs4_state_set_mode_locked(struct nfs4_state *, mode_t);
extern void nfs4_schedule_state_recovery(struct nfs4_client *);
+extern void nfs4_put_lock_state(struct nfs4_lock_state *lsp);
extern int nfs4_set_lock_state(struct nfs4_state *state, struct file_lock *fl);
-extern void nfs4_increment_lock_seqid(int status, struct nfs4_lock_state *ls);
extern void nfs4_copy_stateid(nfs4_stateid *, struct nfs4_state *, fl_owner_t);
+extern struct nfs_seqid *nfs_alloc_seqid(struct nfs_seqid_counter *counter);
+extern int nfs_wait_on_sequence(struct nfs_seqid *seqid, struct rpc_task *task);
+extern void nfs_increment_open_seqid(int status, struct nfs_seqid *seqid);
+extern void nfs_increment_lock_seqid(int status, struct nfs_seqid *seqid);
+extern void nfs_free_seqid(struct nfs_seqid *seqid);
+
extern const nfs4_stateid zero_stateid;
/* nfs4xdr.c */
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 9701ca8c9428..21482b2518f6 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -47,6 +47,7 @@
#include <linux/nfs_page.h>
#include <linux/smp_lock.h>
#include <linux/namei.h>
+#include <linux/mount.h>
#include "nfs4_fs.h"
#include "delegation.h"
@@ -56,10 +57,11 @@
#define NFS4_POLL_RETRY_MIN (1*HZ)
#define NFS4_POLL_RETRY_MAX (15*HZ)
+static int _nfs4_proc_open_confirm(struct rpc_clnt *clnt, const struct nfs_fh *fh, struct nfs4_state_owner *sp, nfs4_stateid *stateid, struct nfs_seqid *seqid);
static int nfs4_do_fsinfo(struct nfs_server *, struct nfs_fh *, struct nfs_fsinfo *);
-static int nfs4_async_handle_error(struct rpc_task *, struct nfs_server *);
+static int nfs4_async_handle_error(struct rpc_task *, const struct nfs_server *);
static int _nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry);
-static int nfs4_handle_exception(struct nfs_server *server, int errorcode, struct nfs4_exception *exception);
+static int nfs4_handle_exception(const struct nfs_server *server, int errorcode, struct nfs4_exception *exception);
extern u32 *nfs4_decode_dirent(u32 *p, struct nfs_entry *entry, int plus);
extern struct rpc_procinfo nfs4_procedures[];
@@ -185,8 +187,26 @@ static void update_changeattr(struct inode *inode, struct nfs4_change_info *cinf
{
struct nfs_inode *nfsi = NFS_I(inode);
+ spin_lock(&inode->i_lock);
+ nfsi->cache_validity |= NFS_INO_INVALID_ATTR;
if (cinfo->before == nfsi->change_attr && cinfo->atomic)
nfsi->change_attr = cinfo->after;
+ spin_unlock(&inode->i_lock);
+}
+
+/* Helper for asynchronous RPC calls */
+static int nfs4_call_async(struct rpc_clnt *clnt, rpc_action tk_begin,
+ rpc_action tk_exit, void *calldata)
+{
+ struct rpc_task *task;
+
+ if (!(task = rpc_new_task(clnt, tk_exit, RPC_TASK_ASYNC)))
+ return -ENOMEM;
+
+ task->tk_calldata = calldata;
+ task->tk_action = tk_begin;
+ rpc_execute(task);
+ return 0;
}
static void update_open_stateid(struct nfs4_state *state, nfs4_stateid *stateid, int open_flags)
@@ -194,22 +214,22 @@ static void update_open_stateid(struct nfs4_state *state, nfs4_stateid *stateid,
struct inode *inode = state->inode;
open_flags &= (FMODE_READ|FMODE_WRITE);
- /* Protect against nfs4_find_state() */
+ /* Protect against nfs4_find_state_byowner() */
+ spin_lock(&state->owner->so_lock);
spin_lock(&inode->i_lock);
- state->state |= open_flags;
- /* NB! List reordering - see the reclaim code for why. */
- if ((open_flags & FMODE_WRITE) && 0 == state->nwriters++)
- list_move(&state->open_states, &state->owner->so_states);
+ memcpy(&state->stateid, stateid, sizeof(state->stateid));
+ if ((open_flags & FMODE_WRITE))
+ state->nwriters++;
if (open_flags & FMODE_READ)
state->nreaders++;
- memcpy(&state->stateid, stateid, sizeof(state->stateid));
+ nfs4_state_set_mode_locked(state, state->state | open_flags);
spin_unlock(&inode->i_lock);
+ spin_unlock(&state->owner->so_lock);
}
/*
* OPEN_RECLAIM:
* reclaim state on the server after a reboot.
- * Assumes caller is holding the sp->so_sem
*/
static int _nfs4_open_reclaim(struct nfs4_state_owner *sp, struct nfs4_state *state)
{
@@ -218,7 +238,6 @@ static int _nfs4_open_reclaim(struct nfs4_state_owner *sp, struct nfs4_state *st
struct nfs_delegation *delegation = NFS_I(inode)->delegation;
struct nfs_openargs o_arg = {
.fh = NFS_FH(inode),
- .seqid = sp->so_seqid,
.id = sp->so_id,
.open_flags = state->state,
.clientid = server->nfs4_state->cl_clientid,
@@ -245,8 +264,13 @@ static int _nfs4_open_reclaim(struct nfs4_state_owner *sp, struct nfs4_state *st
}
o_arg.u.delegation_type = delegation->type;
}
+ o_arg.seqid = nfs_alloc_seqid(&sp->so_seqid);
+ if (o_arg.seqid == NULL)
+ return -ENOMEM;
status = rpc_call_sync(server->client, &msg, RPC_TASK_NOINTR);
- nfs4_increment_seqid(status, sp);
+ /* Confirm the sequence as being established */
+ nfs_confirm_seqid(&sp->so_seqid, status);
+ nfs_increment_open_seqid(status, o_arg.seqid);
if (status == 0) {
memcpy(&state->stateid, &o_res.stateid, sizeof(state->stateid));
if (o_res.delegation_type != 0) {
@@ -256,6 +280,7 @@ static int _nfs4_open_reclaim(struct nfs4_state_owner *sp, struct nfs4_state *st
nfs_async_inode_return_delegation(inode, &o_res.stateid);
}
}
+ nfs_free_seqid(o_arg.seqid);
clear_bit(NFS_DELEGATED_STATE, &state->flags);
/* Ensure we update the inode attributes */
NFS_CACHEINV(inode);
@@ -302,23 +327,35 @@ static int _nfs4_open_delegation_recall(struct dentry *dentry, struct nfs4_state
};
int status = 0;
- down(&sp->so_sema);
if (!test_bit(NFS_DELEGATED_STATE, &state->flags))
goto out;
if (state->state == 0)
goto out;
- arg.seqid = sp->so_seqid;
+ arg.seqid = nfs_alloc_seqid(&sp->so_seqid);
+ status = -ENOMEM;
+ if (arg.seqid == NULL)
+ goto out;
arg.open_flags = state->state;
memcpy(arg.u.delegation.data, state->stateid.data, sizeof(arg.u.delegation.data));
status = rpc_call_sync(server->client, &msg, RPC_TASK_NOINTR);
- nfs4_increment_seqid(status, sp);
+ nfs_increment_open_seqid(status, arg.seqid);
+ if (status != 0)
+ goto out_free;
+ if(res.rflags & NFS4_OPEN_RESULT_CONFIRM) {
+ status = _nfs4_proc_open_confirm(server->client, NFS_FH(inode),
+ sp, &res.stateid, arg.seqid);
+ if (status != 0)
+ goto out_free;
+ }
+ nfs_confirm_seqid(&sp->so_seqid, 0);
if (status >= 0) {
memcpy(state->stateid.data, res.stateid.data,
sizeof(state->stateid.data));
clear_bit(NFS_DELEGATED_STATE, &state->flags);
}
+out_free:
+ nfs_free_seqid(arg.seqid);
out:
- up(&sp->so_sema);
dput(parent);
return status;
}
@@ -345,11 +382,11 @@ int nfs4_open_delegation_recall(struct dentry *dentry, struct nfs4_state *state)
return err;
}
-static inline int _nfs4_proc_open_confirm(struct rpc_clnt *clnt, const struct nfs_fh *fh, struct nfs4_state_owner *sp, nfs4_stateid *stateid)
+static int _nfs4_proc_open_confirm(struct rpc_clnt *clnt, const struct nfs_fh *fh, struct nfs4_state_owner *sp, nfs4_stateid *stateid, struct nfs_seqid *seqid)
{
struct nfs_open_confirmargs arg = {
.fh = fh,
- .seqid = sp->so_seqid,
+ .seqid = seqid,
.stateid = *stateid,
};
struct nfs_open_confirmres res;
@@ -362,7 +399,9 @@ static inline int _nfs4_proc_open_confirm(struct rpc_clnt *clnt, const struct nf
int status;
status = rpc_call_sync(clnt, &msg, RPC_TASK_NOINTR);
- nfs4_increment_seqid(status, sp);
+ /* Confirm the sequence as being established */
+ nfs_confirm_seqid(&sp->so_seqid, status);
+ nfs_increment_open_seqid(status, seqid);
if (status >= 0)
memcpy(stateid, &res.stateid, sizeof(*stateid));
return status;
@@ -380,21 +419,41 @@ static int _nfs4_proc_open(struct inode *dir, struct nfs4_state_owner *sp, stru
int status;
/* Update sequence id. The caller must serialize! */
- o_arg->seqid = sp->so_seqid;
o_arg->id = sp->so_id;
o_arg->clientid = sp->so_client->cl_clientid;
status = rpc_call_sync(server->client, &msg, RPC_TASK_NOINTR);
- nfs4_increment_seqid(status, sp);
+ if (status == 0) {
+ /* OPEN on anything except a regular file is disallowed in NFSv4 */
+ switch (o_res->f_attr->mode & S_IFMT) {
+ case S_IFREG:
+ break;
+ case S_IFLNK:
+ status = -ELOOP;
+ break;
+ case S_IFDIR:
+ status = -EISDIR;
+ break;
+ default:
+ status = -ENOTDIR;
+ }
+ }
+
+ nfs_increment_open_seqid(status, o_arg->seqid);
if (status != 0)
goto out;
- update_changeattr(dir, &o_res->cinfo);
+ if (o_arg->open_flags & O_CREAT) {
+ update_changeattr(dir, &o_res->cinfo);
+ nfs_post_op_update_inode(dir, o_res->dir_attr);
+ } else
+ nfs_refresh_inode(dir, o_res->dir_attr);
if(o_res->rflags & NFS4_OPEN_RESULT_CONFIRM) {
status = _nfs4_proc_open_confirm(server->client, &o_res->fh,
- sp, &o_res->stateid);
+ sp, &o_res->stateid, o_arg->seqid);
if (status != 0)
goto out;
}
+ nfs_confirm_seqid(&sp->so_seqid, 0);
if (!(o_res->f_attr->valid & NFS_ATTR_FATTR))
status = server->rpc_ops->getattr(server, &o_res->fh, o_res->f_attr);
out:
@@ -441,9 +500,7 @@ static int _nfs4_open_expired(struct nfs4_state_owner *sp, struct nfs4_state *st
struct inode *inode = state->inode;
struct nfs_server *server = NFS_SERVER(dir);
struct nfs_delegation *delegation = NFS_I(inode)->delegation;
- struct nfs_fattr f_attr = {
- .valid = 0,
- };
+ struct nfs_fattr f_attr, dir_attr;
struct nfs_openargs o_arg = {
.fh = NFS_FH(dir),
.open_flags = state->state,
@@ -453,6 +510,7 @@ static int _nfs4_open_expired(struct nfs4_state_owner *sp, struct nfs4_state *st
};
struct nfs_openres o_res = {
.f_attr = &f_attr,
+ .dir_attr = &dir_attr,
.server = server,
};
int status = 0;
@@ -465,6 +523,12 @@ static int _nfs4_open_expired(struct nfs4_state_owner *sp, struct nfs4_state *st
set_bit(NFS_DELEGATED_STATE, &state->flags);
goto out;
}
+ o_arg.seqid = nfs_alloc_seqid(&sp->so_seqid);
+ status = -ENOMEM;
+ if (o_arg.seqid == NULL)
+ goto out;
+ nfs_fattr_init(&f_attr);
+ nfs_fattr_init(&dir_attr);
status = _nfs4_proc_open(dir, sp, &o_arg, &o_res);
if (status != 0)
goto out_nodeleg;
@@ -490,6 +554,7 @@ static int _nfs4_open_expired(struct nfs4_state_owner *sp, struct nfs4_state *st
nfs_inode_reclaim_delegation(inode, sp->so_cred, &o_res);
}
out_nodeleg:
+ nfs_free_seqid(o_arg.seqid);
clear_bit(NFS_DELEGATED_STATE, &state->flags);
out:
dput(parent);
@@ -564,7 +629,6 @@ static int _nfs4_open_delegated(struct inode *inode, int flags, struct rpc_cred
dprintk("%s: nfs4_get_state_owner failed!\n", __FUNCTION__);
goto out_err;
}
- down(&sp->so_sema);
state = nfs4_get_open_state(inode, sp);
if (state == NULL)
goto out_err;
@@ -589,7 +653,6 @@ static int _nfs4_open_delegated(struct inode *inode, int flags, struct rpc_cred
set_bit(NFS_DELEGATED_STATE, &state->flags);
update_open_stateid(state, &delegation->stateid, open_flags);
out_ok:
- up(&sp->so_sema);
nfs4_put_state_owner(sp);
up_read(&nfsi->rwsem);
up_read(&clp->cl_sem);
@@ -600,11 +663,12 @@ out_err:
if (sp != NULL) {
if (state != NULL)
nfs4_put_open_state(state);
- up(&sp->so_sema);
nfs4_put_state_owner(sp);
}
up_read(&nfsi->rwsem);
up_read(&clp->cl_sem);
+ if (err != -EACCES)
+ nfs_inode_return_delegation(inode);
return err;
}
@@ -635,9 +699,7 @@ static int _nfs4_do_open(struct inode *dir, struct dentry *dentry, int flags, st
struct nfs4_client *clp = server->nfs4_state;
struct inode *inode = NULL;
int status;
- struct nfs_fattr f_attr = {
- .valid = 0,
- };
+ struct nfs_fattr f_attr, dir_attr;
struct nfs_openargs o_arg = {
.fh = NFS_FH(dir),
.open_flags = flags,
@@ -648,6 +710,7 @@ static int _nfs4_do_open(struct inode *dir, struct dentry *dentry, int flags, st
};
struct nfs_openres o_res = {
.f_attr = &f_attr,
+ .dir_attr = &dir_attr,
.server = server,
};
@@ -665,8 +728,12 @@ static int _nfs4_do_open(struct inode *dir, struct dentry *dentry, int flags, st
} else
o_arg.u.attrs = sattr;
/* Serialization for the sequence id */
- down(&sp->so_sema);
+ o_arg.seqid = nfs_alloc_seqid(&sp->so_seqid);
+ if (o_arg.seqid == NULL)
+ return -ENOMEM;
+ nfs_fattr_init(&f_attr);
+ nfs_fattr_init(&dir_attr);
status = _nfs4_proc_open(dir, sp, &o_arg, &o_res);
if (status != 0)
goto out_err;
@@ -681,7 +748,7 @@ static int _nfs4_do_open(struct inode *dir, struct dentry *dentry, int flags, st
update_open_stateid(state, &o_res.stateid, flags);
if (o_res.delegation_type != 0)
nfs_inode_set_delegation(inode, cred, &o_res);
- up(&sp->so_sema);
+ nfs_free_seqid(o_arg.seqid);
nfs4_put_state_owner(sp);
up_read(&clp->cl_sem);
*res = state;
@@ -690,7 +757,7 @@ out_err:
if (sp != NULL) {
if (state != NULL)
nfs4_put_open_state(state);
- up(&sp->so_sema);
+ nfs_free_seqid(o_arg.seqid);
nfs4_put_state_owner(sp);
}
/* Note: clp->cl_sem must be released before nfs4_put_open_state()! */
@@ -718,7 +785,7 @@ static struct nfs4_state *nfs4_do_open(struct inode *dir, struct dentry *dentry,
* It is actually a sign of a bug on the client or on the server.
*
* If we receive a BAD_SEQID error in the particular case of
- * doing an OPEN, we assume that nfs4_increment_seqid() will
+ * doing an OPEN, we assume that nfs_increment_open_seqid() will
* have unhashed the old state_owner for us, and that we can
* therefore safely retry using a new one. We should still warn
* the user though...
@@ -728,6 +795,16 @@ static struct nfs4_state *nfs4_do_open(struct inode *dir, struct dentry *dentry,
exception.retry = 1;
continue;
}
+ /*
+ * BAD_STATEID on OPEN means that the server cancelled our
+ * state before it received the OPEN_CONFIRM.
+ * Recover by retrying the request as per the discussion
+ * on Page 181 of RFC3530.
+ */
+ if (status == -NFS4ERR_BAD_STATEID) {
+ exception.retry = 1;
+ continue;
+ }
res = ERR_PTR(nfs4_handle_exception(NFS_SERVER(dir),
status, &exception));
} while (exception.retry);
@@ -755,7 +832,7 @@ static int _nfs4_do_setattr(struct nfs_server *server, struct nfs_fattr *fattr,
};
int status;
- fattr->valid = 0;
+ nfs_fattr_init(fattr);
if (state != NULL) {
msg.rpc_cred = state->owner->so_cred;
@@ -787,19 +864,30 @@ struct nfs4_closedata {
struct nfs4_state *state;
struct nfs_closeargs arg;
struct nfs_closeres res;
+ struct nfs_fattr fattr;
};
+static void nfs4_free_closedata(struct nfs4_closedata *calldata)
+{
+ struct nfs4_state *state = calldata->state;
+ struct nfs4_state_owner *sp = state->owner;
+
+ nfs4_put_open_state(calldata->state);
+ nfs_free_seqid(calldata->arg.seqid);
+ nfs4_put_state_owner(sp);
+ kfree(calldata);
+}
+
static void nfs4_close_done(struct rpc_task *task)
{
struct nfs4_closedata *calldata = (struct nfs4_closedata *)task->tk_calldata;
struct nfs4_state *state = calldata->state;
- struct nfs4_state_owner *sp = state->owner;
struct nfs_server *server = NFS_SERVER(calldata->inode);
/* hmm. we are done with the inode, and in the process of freeing
* the state_owner. we keep this around to process errors
*/
- nfs4_increment_seqid(task->tk_status, sp);
+ nfs_increment_open_seqid(task->tk_status, calldata->arg.seqid);
switch (task->tk_status) {
case 0:
memcpy(&state->stateid, &calldata->res.stateid,
@@ -807,7 +895,6 @@ static void nfs4_close_done(struct rpc_task *task)
break;
case -NFS4ERR_STALE_STATEID:
case -NFS4ERR_EXPIRED:
- state->state = calldata->arg.open_flags;
nfs4_schedule_state_recovery(server->nfs4_state);
break;
default:
@@ -816,25 +903,50 @@ static void nfs4_close_done(struct rpc_task *task)
return;
}
}
- state->state = calldata->arg.open_flags;
- nfs4_put_open_state(state);
- up(&sp->so_sema);
- nfs4_put_state_owner(sp);
- up_read(&server->nfs4_state->cl_sem);
- kfree(calldata);
+ nfs_refresh_inode(calldata->inode, calldata->res.fattr);
+ nfs4_free_closedata(calldata);
}
-static inline int nfs4_close_call(struct rpc_clnt *clnt, struct nfs4_closedata *calldata)
+static void nfs4_close_begin(struct rpc_task *task)
{
+ struct nfs4_closedata *calldata = (struct nfs4_closedata *)task->tk_calldata;
+ struct nfs4_state *state = calldata->state;
struct rpc_message msg = {
.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_CLOSE],
.rpc_argp = &calldata->arg,
.rpc_resp = &calldata->res,
- .rpc_cred = calldata->state->owner->so_cred,
+ .rpc_cred = state->owner->so_cred,
};
- if (calldata->arg.open_flags != 0)
+ int mode = 0, old_mode;
+ int status;
+
+ status = nfs_wait_on_sequence(calldata->arg.seqid, task);
+ if (status != 0)
+ return;
+ /* Recalculate the new open mode in case someone reopened the file
+ * while we were waiting in line to be scheduled.
+ */
+ spin_lock(&state->owner->so_lock);
+ spin_lock(&calldata->inode->i_lock);
+ mode = old_mode = state->state;
+ if (state->nreaders == 0)
+ mode &= ~FMODE_READ;
+ if (state->nwriters == 0)
+ mode &= ~FMODE_WRITE;
+ nfs4_state_set_mode_locked(state, mode);
+ spin_unlock(&calldata->inode->i_lock);
+ spin_unlock(&state->owner->so_lock);
+ if (mode == old_mode || test_bit(NFS_DELEGATED_STATE, &state->flags)) {
+ nfs4_free_closedata(calldata);
+ task->tk_exit = NULL;
+ rpc_exit(task, 0);
+ return;
+ }
+ nfs_fattr_init(calldata->res.fattr);
+ if (mode != 0)
msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_OPEN_DOWNGRADE];
- return rpc_call_async(clnt, &msg, 0, nfs4_close_done, calldata);
+ calldata->arg.open_flags = mode;
+ rpc_call_setup(task, &msg, 0);
}
/*
@@ -848,42 +960,59 @@ static inline int nfs4_close_call(struct rpc_clnt *clnt, struct nfs4_closedata *
*
* NOTE: Caller must be holding the sp->so_owner semaphore!
*/
-int nfs4_do_close(struct inode *inode, struct nfs4_state *state, mode_t mode)
+int nfs4_do_close(struct inode *inode, struct nfs4_state *state)
{
+ struct nfs_server *server = NFS_SERVER(inode);
struct nfs4_closedata *calldata;
- int status;
+ int status = -ENOMEM;
- /* Tell caller we're done */
- if (test_bit(NFS_DELEGATED_STATE, &state->flags)) {
- state->state = mode;
- return 0;
- }
- calldata = (struct nfs4_closedata *)kmalloc(sizeof(*calldata), GFP_KERNEL);
+ calldata = kmalloc(sizeof(*calldata), GFP_KERNEL);
if (calldata == NULL)
- return -ENOMEM;
+ goto out;
calldata->inode = inode;
calldata->state = state;
calldata->arg.fh = NFS_FH(inode);
+ calldata->arg.stateid = &state->stateid;
/* Serialization for the sequence id */
- calldata->arg.seqid = state->owner->so_seqid;
- calldata->arg.open_flags = mode;
- memcpy(&calldata->arg.stateid, &state->stateid,
- sizeof(calldata->arg.stateid));
- status = nfs4_close_call(NFS_SERVER(inode)->client, calldata);
- /*
- * Return -EINPROGRESS on success in order to indicate to the
- * caller that an asynchronous RPC call has been launched, and
- * that it will release the semaphores on completion.
- */
- return (status == 0) ? -EINPROGRESS : status;
+ calldata->arg.seqid = nfs_alloc_seqid(&state->owner->so_seqid);
+ if (calldata->arg.seqid == NULL)
+ goto out_free_calldata;
+ calldata->arg.bitmask = server->attr_bitmask;
+ calldata->res.fattr = &calldata->fattr;
+ calldata->res.server = server;
+
+ status = nfs4_call_async(server->client, nfs4_close_begin,
+ nfs4_close_done, calldata);
+ if (status == 0)
+ goto out;
+
+ nfs_free_seqid(calldata->arg.seqid);
+out_free_calldata:
+ kfree(calldata);
+out:
+ return status;
}
-struct inode *
+static void nfs4_intent_set_file(struct nameidata *nd, struct dentry *dentry, struct nfs4_state *state)
+{
+ struct file *filp;
+
+ filp = lookup_instantiate_filp(nd, dentry, NULL);
+ if (!IS_ERR(filp)) {
+ struct nfs_open_context *ctx;
+ ctx = (struct nfs_open_context *)filp->private_data;
+ ctx->state = state;
+ } else
+ nfs4_close_state(state, nd->intent.open.flags);
+}
+
+struct dentry *
nfs4_atomic_open(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
{
struct iattr attr;
struct rpc_cred *cred;
struct nfs4_state *state;
+ struct dentry *res;
if (nd->flags & LOOKUP_CREATE) {
attr.ia_mode = nd->intent.open.create_mode;
@@ -897,16 +1026,23 @@ nfs4_atomic_open(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
cred = rpcauth_lookupcred(NFS_SERVER(dir)->client->cl_auth, 0);
if (IS_ERR(cred))
- return (struct inode *)cred;
+ return (struct dentry *)cred;
state = nfs4_do_open(dir, dentry, nd->intent.open.flags, &attr, cred);
put_rpccred(cred);
- if (IS_ERR(state))
- return (struct inode *)state;
- return state->inode;
+ if (IS_ERR(state)) {
+ if (PTR_ERR(state) == -ENOENT)
+ d_add(dentry, NULL);
+ return (struct dentry *)state;
+ }
+ res = d_add_unique(dentry, state->inode);
+ if (res != NULL)
+ dentry = res;
+ nfs4_intent_set_file(nd, dentry, state);
+ return res;
}
int
-nfs4_open_revalidate(struct inode *dir, struct dentry *dentry, int openflags)
+nfs4_open_revalidate(struct inode *dir, struct dentry *dentry, int openflags, struct nameidata *nd)
{
struct rpc_cred *cred;
struct nfs4_state *state;
@@ -919,18 +1055,30 @@ nfs4_open_revalidate(struct inode *dir, struct dentry *dentry, int openflags)
if (IS_ERR(state))
state = nfs4_do_open(dir, dentry, openflags, NULL, cred);
put_rpccred(cred);
- if (state == ERR_PTR(-ENOENT) && dentry->d_inode == 0)
- return 1;
- if (IS_ERR(state))
- return 0;
+ if (IS_ERR(state)) {
+ switch (PTR_ERR(state)) {
+ case -EPERM:
+ case -EACCES:
+ case -EDQUOT:
+ case -ENOSPC:
+ case -EROFS:
+ lookup_instantiate_filp(nd, (struct dentry *)state, NULL);
+ return 1;
+ case -ENOENT:
+ if (dentry->d_inode == NULL)
+ return 1;
+ }
+ goto out_drop;
+ }
inode = state->inode;
+ iput(inode);
if (inode == dentry->d_inode) {
- iput(inode);
+ nfs4_intent_set_file(nd, dentry, state);
return 1;
}
- d_drop(dentry);
nfs4_close_state(state, openflags);
- iput(inode);
+out_drop:
+ d_drop(dentry);
return 0;
}
@@ -974,13 +1122,12 @@ static int nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fh
static int _nfs4_lookup_root(struct nfs_server *server, struct nfs_fh *fhandle,
struct nfs_fsinfo *info)
{
- struct nfs_fattr * fattr = info->fattr;
struct nfs4_lookup_root_arg args = {
.bitmask = nfs4_fattr_bitmap,
};
struct nfs4_lookup_res res = {
.server = server,
- .fattr = fattr,
+ .fattr = info->fattr,
.fh = fhandle,
};
struct rpc_message msg = {
@@ -988,7 +1135,7 @@ static int _nfs4_lookup_root(struct nfs_server *server, struct nfs_fh *fhandle,
.rpc_argp = &args,
.rpc_resp = &res,
};
- fattr->valid = 0;
+ nfs_fattr_init(info->fattr);
return rpc_call_sync(server->client, &msg, 0);
}
@@ -1051,7 +1198,7 @@ static int nfs4_proc_get_root(struct nfs_server *server, struct nfs_fh *fhandle,
q.len = p - q.name;
do {
- fattr->valid = 0;
+ nfs_fattr_init(fattr);
status = nfs4_handle_exception(server,
rpc_call_sync(server->client, &msg, 0),
&exception);
@@ -1088,7 +1235,7 @@ static int _nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle,
.rpc_resp = &res,
};
- fattr->valid = 0;
+ nfs_fattr_init(fattr);
return rpc_call_sync(server->client, &msg, 0);
}
@@ -1127,30 +1274,27 @@ nfs4_proc_setattr(struct dentry *dentry, struct nfs_fattr *fattr,
{
struct rpc_cred *cred;
struct inode *inode = dentry->d_inode;
- struct nfs4_state *state;
+ struct nfs_open_context *ctx;
+ struct nfs4_state *state = NULL;
int status;
- fattr->valid = 0;
+ nfs_fattr_init(fattr);
cred = rpcauth_lookupcred(NFS_SERVER(inode)->client->cl_auth, 0);
if (IS_ERR(cred))
return PTR_ERR(cred);
- /* Search for an existing WRITE delegation first */
- state = nfs4_open_delegated(inode, FMODE_WRITE, cred);
- if (!IS_ERR(state)) {
- /* NB: nfs4_open_delegated() bumps the inode->i_count */
- iput(inode);
- } else {
- /* Search for an existing open(O_WRITE) stateid */
- state = nfs4_find_state(inode, cred, FMODE_WRITE);
- }
+
+ /* Search for an existing open(O_WRITE) file */
+ ctx = nfs_find_open_context(inode, cred, FMODE_WRITE);
+ if (ctx != NULL)
+ state = ctx->state;
status = nfs4_do_setattr(NFS_SERVER(inode), fattr,
NFS_FH(inode), sattr, state);
if (status == 0)
nfs_setattr_update_inode(inode, sattr);
- if (state != NULL)
- nfs4_close_state(state, FMODE_WRITE);
+ if (ctx != NULL)
+ put_nfs_open_context(ctx);
put_rpccred(cred);
return status;
}
@@ -1176,7 +1320,7 @@ static int _nfs4_proc_lookup(struct inode *dir, struct qstr *name,
.rpc_resp = &res,
};
- fattr->valid = 0;
+ nfs_fattr_init(fattr);
dprintk("NFS call lookup %s\n", name->name);
status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
@@ -1325,7 +1469,7 @@ static int _nfs4_proc_read(struct nfs_read_data *rdata)
dprintk("NFS call read %d @ %Ld\n", rdata->args.count,
(long long) rdata->args.offset);
- fattr->valid = 0;
+ nfs_fattr_init(fattr);
status = rpc_call_sync(server->client, &msg, flags);
if (!status)
renew_lease(server, timestamp);
@@ -1362,7 +1506,7 @@ static int _nfs4_proc_write(struct nfs_write_data *wdata)
dprintk("NFS call write %d @ %Ld\n", wdata->args.count,
(long long) wdata->args.offset);
- fattr->valid = 0;
+ nfs_fattr_init(fattr);
status = rpc_call_sync(server->client, &msg, rpcflags);
dprintk("NFS reply write: %d\n", status);
return status;
@@ -1396,7 +1540,7 @@ static int _nfs4_proc_commit(struct nfs_write_data *cdata)
dprintk("NFS call commit %d @ %Ld\n", cdata->args.count,
(long long) cdata->args.offset);
- fattr->valid = 0;
+ nfs_fattr_init(fattr);
status = rpc_call_sync(server->client, &msg, 0);
dprintk("NFS reply commit: %d\n", status);
return status;
@@ -1431,7 +1575,7 @@ static int nfs4_proc_commit(struct nfs_write_data *cdata)
static int
nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
- int flags)
+ int flags, struct nameidata *nd)
{
struct nfs4_state *state;
struct rpc_cred *cred;
@@ -1453,24 +1597,30 @@ nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
struct nfs_fattr fattr;
status = nfs4_do_setattr(NFS_SERVER(dir), &fattr,
NFS_FH(state->inode), sattr, state);
- if (status == 0) {
+ if (status == 0)
nfs_setattr_update_inode(state->inode, sattr);
- goto out;
- }
- } else if (flags != 0)
- goto out;
- nfs4_close_state(state, flags);
+ }
+ if (status == 0 && nd != NULL && (nd->flags & LOOKUP_OPEN))
+ nfs4_intent_set_file(nd, dentry, state);
+ else
+ nfs4_close_state(state, flags);
out:
return status;
}
static int _nfs4_proc_remove(struct inode *dir, struct qstr *name)
{
+ struct nfs_server *server = NFS_SERVER(dir);
struct nfs4_remove_arg args = {
.fh = NFS_FH(dir),
.name = name,
+ .bitmask = server->attr_bitmask,
+ };
+ struct nfs_fattr dir_attr;
+ struct nfs4_remove_res res = {
+ .server = server,
+ .dir_attr = &dir_attr,
};
- struct nfs4_change_info res;
struct rpc_message msg = {
.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_REMOVE],
.rpc_argp = &args,
@@ -1478,9 +1628,12 @@ static int _nfs4_proc_remove(struct inode *dir, struct qstr *name)
};
int status;
- status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
- if (status == 0)
- update_changeattr(dir, &res);
+ nfs_fattr_init(res.dir_attr);
+ status = rpc_call_sync(server->client, &msg, 0);
+ if (status == 0) {
+ update_changeattr(dir, &res.cinfo);
+ nfs_post_op_update_inode(dir, res.dir_attr);
+ }
return status;
}
@@ -1498,12 +1651,14 @@ static int nfs4_proc_remove(struct inode *dir, struct qstr *name)
struct unlink_desc {
struct nfs4_remove_arg args;
- struct nfs4_change_info res;
+ struct nfs4_remove_res res;
+ struct nfs_fattr dir_attr;
};
static int nfs4_proc_unlink_setup(struct rpc_message *msg, struct dentry *dir,
struct qstr *name)
{
+ struct nfs_server *server = NFS_SERVER(dir->d_inode);
struct unlink_desc *up;
up = (struct unlink_desc *) kmalloc(sizeof(*up), GFP_KERNEL);
@@ -1512,6 +1667,9 @@ static int nfs4_proc_unlink_setup(struct rpc_message *msg, struct dentry *dir,
up->args.fh = NFS_FH(dir->d_inode);
up->args.name = name;
+ up->args.bitmask = server->attr_bitmask;
+ up->res.server = server;
+ up->res.dir_attr = &up->dir_attr;
msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_REMOVE];
msg->rpc_argp = &up->args;
@@ -1526,7 +1684,8 @@ static int nfs4_proc_unlink_done(struct dentry *dir, struct rpc_task *task)
if (msg->rpc_resp != NULL) {
up = container_of(msg->rpc_resp, struct unlink_desc, res);
- update_changeattr(dir->d_inode, &up->res);
+ update_changeattr(dir->d_inode, &up->res.cinfo);
+ nfs_post_op_update_inode(dir->d_inode, up->res.dir_attr);
kfree(up);
msg->rpc_resp = NULL;
msg->rpc_argp = NULL;
@@ -1537,13 +1696,20 @@ static int nfs4_proc_unlink_done(struct dentry *dir, struct rpc_task *task)
static int _nfs4_proc_rename(struct inode *old_dir, struct qstr *old_name,
struct inode *new_dir, struct qstr *new_name)
{
+ struct nfs_server *server = NFS_SERVER(old_dir);
struct nfs4_rename_arg arg = {
.old_dir = NFS_FH(old_dir),
.new_dir = NFS_FH(new_dir),
.old_name = old_name,
.new_name = new_name,
+ .bitmask = server->attr_bitmask,
+ };
+ struct nfs_fattr old_fattr, new_fattr;
+ struct nfs4_rename_res res = {
+ .server = server,
+ .old_fattr = &old_fattr,
+ .new_fattr = &new_fattr,
};
- struct nfs4_rename_res res = { };
struct rpc_message msg = {
.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_RENAME],
.rpc_argp = &arg,
@@ -1551,11 +1717,15 @@ static int _nfs4_proc_rename(struct inode *old_dir, struct qstr *old_name,
};
int status;
- status = rpc_call_sync(NFS_CLIENT(old_dir), &msg, 0);
+ nfs_fattr_init(res.old_fattr);
+ nfs_fattr_init(res.new_fattr);
+ status = rpc_call_sync(server->client, &msg, 0);
if (!status) {
update_changeattr(old_dir, &res.old_cinfo);
+ nfs_post_op_update_inode(old_dir, res.old_fattr);
update_changeattr(new_dir, &res.new_cinfo);
+ nfs_post_op_update_inode(new_dir, res.new_fattr);
}
return status;
}
@@ -1576,22 +1746,34 @@ static int nfs4_proc_rename(struct inode *old_dir, struct qstr *old_name,
static int _nfs4_proc_link(struct inode *inode, struct inode *dir, struct qstr *name)
{
+ struct nfs_server *server = NFS_SERVER(inode);
struct nfs4_link_arg arg = {
.fh = NFS_FH(inode),
.dir_fh = NFS_FH(dir),
.name = name,
+ .bitmask = server->attr_bitmask,
+ };
+ struct nfs_fattr fattr, dir_attr;
+ struct nfs4_link_res res = {
+ .server = server,
+ .fattr = &fattr,
+ .dir_attr = &dir_attr,
};
- struct nfs4_change_info cinfo = { };
struct rpc_message msg = {
.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_LINK],
.rpc_argp = &arg,
- .rpc_resp = &cinfo,
+ .rpc_resp = &res,
};
int status;
- status = rpc_call_sync(NFS_CLIENT(inode), &msg, 0);
- if (!status)
- update_changeattr(dir, &cinfo);
+ nfs_fattr_init(res.fattr);
+ nfs_fattr_init(res.dir_attr);
+ status = rpc_call_sync(server->client, &msg, 0);
+ if (!status) {
+ update_changeattr(dir, &res.cinfo);
+ nfs_post_op_update_inode(dir, res.dir_attr);
+ nfs_refresh_inode(inode, res.fattr);
+ }
return status;
}
@@ -1613,6 +1795,7 @@ static int _nfs4_proc_symlink(struct inode *dir, struct qstr *name,
struct nfs_fattr *fattr)
{
struct nfs_server *server = NFS_SERVER(dir);
+ struct nfs_fattr dir_fattr;
struct nfs4_create_arg arg = {
.dir_fh = NFS_FH(dir),
.server = server,
@@ -1625,6 +1808,7 @@ static int _nfs4_proc_symlink(struct inode *dir, struct qstr *name,
.server = server,
.fh = fhandle,
.fattr = fattr,
+ .dir_fattr = &dir_fattr,
};
struct rpc_message msg = {
.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_SYMLINK],
@@ -1636,11 +1820,13 @@ static int _nfs4_proc_symlink(struct inode *dir, struct qstr *name,
if (path->len > NFS4_MAXPATHLEN)
return -ENAMETOOLONG;
arg.u.symlink = path;
- fattr->valid = 0;
+ nfs_fattr_init(fattr);
+ nfs_fattr_init(&dir_fattr);
status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
if (!status)
update_changeattr(dir, &res.dir_cinfo);
+ nfs_post_op_update_inode(dir, res.dir_fattr);
return status;
}
@@ -1664,7 +1850,7 @@ static int _nfs4_proc_mkdir(struct inode *dir, struct dentry *dentry,
{
struct nfs_server *server = NFS_SERVER(dir);
struct nfs_fh fhandle;
- struct nfs_fattr fattr;
+ struct nfs_fattr fattr, dir_fattr;
struct nfs4_create_arg arg = {
.dir_fh = NFS_FH(dir),
.server = server,
@@ -1677,6 +1863,7 @@ static int _nfs4_proc_mkdir(struct inode *dir, struct dentry *dentry,
.server = server,
.fh = &fhandle,
.fattr = &fattr,
+ .dir_fattr = &dir_fattr,
};
struct rpc_message msg = {
.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_CREATE],
@@ -1685,11 +1872,13 @@ static int _nfs4_proc_mkdir(struct inode *dir, struct dentry *dentry,
};
int status;
- fattr.valid = 0;
+ nfs_fattr_init(&fattr);
+ nfs_fattr_init(&dir_fattr);
status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
if (!status) {
update_changeattr(dir, &res.dir_cinfo);
+ nfs_post_op_update_inode(dir, res.dir_fattr);
status = nfs_instantiate(dentry, &fhandle, &fattr);
}
return status;
@@ -1762,7 +1951,7 @@ static int _nfs4_proc_mknod(struct inode *dir, struct dentry *dentry,
{
struct nfs_server *server = NFS_SERVER(dir);
struct nfs_fh fh;
- struct nfs_fattr fattr;
+ struct nfs_fattr fattr, dir_fattr;
struct nfs4_create_arg arg = {
.dir_fh = NFS_FH(dir),
.server = server,
@@ -1774,6 +1963,7 @@ static int _nfs4_proc_mknod(struct inode *dir, struct dentry *dentry,
.server = server,
.fh = &fh,
.fattr = &fattr,
+ .dir_fattr = &dir_fattr,
};
struct rpc_message msg = {
.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_CREATE],
@@ -1783,7 +1973,8 @@ static int _nfs4_proc_mknod(struct inode *dir, struct dentry *dentry,
int status;
int mode = sattr->ia_mode;
- fattr.valid = 0;
+ nfs_fattr_init(&fattr);
+ nfs_fattr_init(&dir_fattr);
BUG_ON(!(sattr->ia_valid & ATTR_MODE));
BUG_ON(!S_ISFIFO(mode) && !S_ISBLK(mode) && !S_ISCHR(mode) && !S_ISSOCK(mode));
@@ -1805,6 +1996,7 @@ static int _nfs4_proc_mknod(struct inode *dir, struct dentry *dentry,
status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
if (status == 0) {
update_changeattr(dir, &res.dir_cinfo);
+ nfs_post_op_update_inode(dir, res.dir_fattr);
status = nfs_instantiate(dentry, &fh, &fattr);
}
return status;
@@ -1836,7 +2028,7 @@ static int _nfs4_proc_statfs(struct nfs_server *server, struct nfs_fh *fhandle,
.rpc_resp = fsstat,
};
- fsstat->fattr->valid = 0;
+ nfs_fattr_init(fsstat->fattr);
return rpc_call_sync(server->client, &msg, 0);
}
@@ -1883,7 +2075,7 @@ static int nfs4_do_fsinfo(struct nfs_server *server, struct nfs_fh *fhandle, str
static int nfs4_proc_fsinfo(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fsinfo *fsinfo)
{
- fsinfo->fattr->valid = 0;
+ nfs_fattr_init(fsinfo->fattr);
return nfs4_do_fsinfo(server, fhandle, fsinfo);
}
@@ -1906,7 +2098,7 @@ static int _nfs4_proc_pathconf(struct nfs_server *server, struct nfs_fh *fhandle
return 0;
}
- pathconf->fattr->valid = 0;
+ nfs_fattr_init(pathconf->fattr);
return rpc_call_sync(server->client, &msg, 0);
}
@@ -1973,8 +2165,10 @@ nfs4_write_done(struct rpc_task *task)
rpc_restart_call(task);
return;
}
- if (task->tk_status >= 0)
+ if (task->tk_status >= 0) {
renew_lease(NFS_SERVER(inode), data->timestamp);
+ nfs_post_op_update_inode(inode, data->res.fattr);
+ }
/* Call back common NFS writeback processing */
nfs_writeback_done(task);
}
@@ -1990,6 +2184,7 @@ nfs4_proc_write_setup(struct nfs_write_data *data, int how)
.rpc_cred = data->cred,
};
struct inode *inode = data->inode;
+ struct nfs_server *server = NFS_SERVER(inode);
int stable;
int flags;
@@ -2001,6 +2196,8 @@ nfs4_proc_write_setup(struct nfs_write_data *data, int how)
} else
stable = NFS_UNSTABLE;
data->args.stable = stable;
+ data->args.bitmask = server->attr_bitmask;
+ data->res.server = server;
data->timestamp = jiffies;
@@ -2022,6 +2219,8 @@ nfs4_commit_done(struct rpc_task *task)
rpc_restart_call(task);
return;
}
+ if (task->tk_status >= 0)
+ nfs_post_op_update_inode(inode, data->res.fattr);
/* Call back common NFS writeback processing */
nfs_commit_done(task);
}
@@ -2037,8 +2236,12 @@ nfs4_proc_commit_setup(struct nfs_write_data *data, int how)
.rpc_cred = data->cred,
};
struct inode *inode = data->inode;
+ struct nfs_server *server = NFS_SERVER(inode);
int flags;
+ data->args.bitmask = server->attr_bitmask;
+ data->res.server = server;
+
/* Set the initial flags for the task. */
flags = (how & FLUSH_SYNC) ? 0 : RPC_TASK_ASYNC;
@@ -2106,65 +2309,6 @@ nfs4_proc_renew(struct nfs4_client *clp)
return 0;
}
-/*
- * We will need to arrange for the VFS layer to provide an atomic open.
- * Until then, this open method is prone to inefficiency and race conditions
- * due to the lookup, potential create, and open VFS calls from sys_open()
- * placed on the wire.
- */
-static int
-nfs4_proc_file_open(struct inode *inode, struct file *filp)
-{
- struct dentry *dentry = filp->f_dentry;
- struct nfs_open_context *ctx;
- struct nfs4_state *state = NULL;
- struct rpc_cred *cred;
- int status = -ENOMEM;
-
- dprintk("nfs4_proc_file_open: starting on (%.*s/%.*s)\n",
- (int)dentry->d_parent->d_name.len,
- dentry->d_parent->d_name.name,
- (int)dentry->d_name.len, dentry->d_name.name);
-
-
- /* Find our open stateid */
- cred = rpcauth_lookupcred(NFS_SERVER(inode)->client->cl_auth, 0);
- if (IS_ERR(cred))
- return PTR_ERR(cred);
- ctx = alloc_nfs_open_context(dentry, cred);
- put_rpccred(cred);
- if (unlikely(ctx == NULL))
- return -ENOMEM;
- status = -EIO; /* ERACE actually */
- state = nfs4_find_state(inode, cred, filp->f_mode);
- if (unlikely(state == NULL))
- goto no_state;
- ctx->state = state;
- nfs4_close_state(state, filp->f_mode);
- ctx->mode = filp->f_mode;
- nfs_file_set_open_context(filp, ctx);
- put_nfs_open_context(ctx);
- if (filp->f_mode & FMODE_WRITE)
- nfs_begin_data_update(inode);
- return 0;
-no_state:
- printk(KERN_WARNING "NFS: v4 raced in function %s\n", __FUNCTION__);
- put_nfs_open_context(ctx);
- return status;
-}
-
-/*
- * Release our state
- */
-static int
-nfs4_proc_file_release(struct inode *inode, struct file *filp)
-{
- if (filp->f_mode & FMODE_WRITE)
- nfs_end_data_update(inode);
- nfs_file_clear_open_context(filp);
- return 0;
-}
-
static inline int nfs4_server_supports_acls(struct nfs_server *server)
{
return (server->caps & NFS_CAP_ACLS)
@@ -2285,7 +2429,7 @@ static inline ssize_t nfs4_get_acl_uncached(struct inode *inode, void *buf, size
return -ENOMEM;
args.acl_pages[0] = localpage;
args.acl_pgbase = 0;
- args.acl_len = PAGE_SIZE;
+ resp_len = args.acl_len = PAGE_SIZE;
} else {
resp_buf = buf;
buf_to_pages(buf, buflen, args.acl_pages, &args.acl_pgbase);
@@ -2345,6 +2489,7 @@ static int nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t buflen
if (!nfs4_server_supports_acls(server))
return -EOPNOTSUPP;
+ nfs_inode_return_delegation(inode);
buf_to_pages(buf, buflen, arg.acl_pages, &arg.acl_pgbase);
ret = rpc_call_sync(NFS_SERVER(inode)->client, &msg, 0);
if (ret == 0)
@@ -2353,7 +2498,7 @@ 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, struct nfs_server *server)
+nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server)
{
struct nfs4_client *clp = server->nfs4_state;
@@ -2431,7 +2576,7 @@ static int nfs4_delay(struct rpc_clnt *clnt, long *timeout)
/* This is the error handling routine for processes that are allowed
* to sleep.
*/
-int nfs4_handle_exception(struct nfs_server *server, int errorcode, struct nfs4_exception *exception)
+int nfs4_handle_exception(const struct nfs_server *server, int errorcode, struct nfs4_exception *exception)
{
struct nfs4_client *clp = server->nfs4_state;
int ret = errorcode;
@@ -2450,12 +2595,10 @@ int nfs4_handle_exception(struct nfs_server *server, int errorcode, struct nfs4_
case -NFS4ERR_GRACE:
case -NFS4ERR_DELAY:
ret = nfs4_delay(server->client, &exception->timeout);
- if (ret == 0)
- exception->retry = 1;
- break;
+ if (ret != 0)
+ break;
case -NFS4ERR_OLD_STATEID:
- if (ret == 0)
- exception->retry = 1;
+ exception->retry = 1;
}
/* We failed to handle the error */
return nfs4_map_errors(ret);
@@ -2632,7 +2775,6 @@ static int _nfs4_proc_getlk(struct nfs4_state *state, int cmd, struct file_lock
down_read(&clp->cl_sem);
nlo.clientid = clp->cl_clientid;
- down(&state->lock_sema);
status = nfs4_set_lock_state(state, request);
if (status != 0)
goto out;
@@ -2659,7 +2801,6 @@ static int _nfs4_proc_getlk(struct nfs4_state *state, int cmd, struct file_lock
status = 0;
}
out:
- up(&state->lock_sema);
up_read(&clp->cl_sem);
return status;
}
@@ -2696,79 +2837,153 @@ static int do_vfs_lock(struct file *file, struct file_lock *fl)
return res;
}
-static int _nfs4_proc_unlck(struct nfs4_state *state, int cmd, struct file_lock *request)
+struct nfs4_unlockdata {
+ struct nfs_lockargs arg;
+ struct nfs_locku_opargs luargs;
+ struct nfs_lockres res;
+ struct nfs4_lock_state *lsp;
+ struct nfs_open_context *ctx;
+ atomic_t refcount;
+ struct completion completion;
+};
+
+static void nfs4_locku_release_calldata(struct nfs4_unlockdata *calldata)
{
- struct inode *inode = state->inode;
- struct nfs_server *server = NFS_SERVER(inode);
- struct nfs4_client *clp = server->nfs4_state;
- struct nfs_lockargs arg = {
- .fh = NFS_FH(inode),
- .type = nfs4_lck_type(cmd, request),
- .offset = request->fl_start,
- .length = nfs4_lck_length(request),
- };
- struct nfs_lockres res = {
- .server = server,
- };
+ if (atomic_dec_and_test(&calldata->refcount)) {
+ nfs_free_seqid(calldata->luargs.seqid);
+ nfs4_put_lock_state(calldata->lsp);
+ put_nfs_open_context(calldata->ctx);
+ kfree(calldata);
+ }
+}
+
+static void nfs4_locku_complete(struct nfs4_unlockdata *calldata)
+{
+ complete(&calldata->completion);
+ nfs4_locku_release_calldata(calldata);
+}
+
+static void nfs4_locku_done(struct rpc_task *task)
+{
+ struct nfs4_unlockdata *calldata = (struct nfs4_unlockdata *)task->tk_calldata;
+
+ nfs_increment_lock_seqid(task->tk_status, calldata->luargs.seqid);
+ switch (task->tk_status) {
+ case 0:
+ memcpy(calldata->lsp->ls_stateid.data,
+ calldata->res.u.stateid.data,
+ sizeof(calldata->lsp->ls_stateid.data));
+ break;
+ case -NFS4ERR_STALE_STATEID:
+ case -NFS4ERR_EXPIRED:
+ nfs4_schedule_state_recovery(calldata->res.server->nfs4_state);
+ break;
+ default:
+ if (nfs4_async_handle_error(task, calldata->res.server) == -EAGAIN) {
+ rpc_restart_call(task);
+ return;
+ }
+ }
+ nfs4_locku_complete(calldata);
+}
+
+static void nfs4_locku_begin(struct rpc_task *task)
+{
+ struct nfs4_unlockdata *calldata = (struct nfs4_unlockdata *)task->tk_calldata;
struct rpc_message msg = {
.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_LOCKU],
- .rpc_argp = &arg,
- .rpc_resp = &res,
- .rpc_cred = state->owner->so_cred,
+ .rpc_argp = &calldata->arg,
+ .rpc_resp = &calldata->res,
+ .rpc_cred = calldata->lsp->ls_state->owner->so_cred,
};
+ int status;
+
+ status = nfs_wait_on_sequence(calldata->luargs.seqid, task);
+ if (status != 0)
+ return;
+ if ((calldata->lsp->ls_flags & NFS_LOCK_INITIALIZED) == 0) {
+ nfs4_locku_complete(calldata);
+ task->tk_exit = NULL;
+ rpc_exit(task, 0);
+ return;
+ }
+ rpc_call_setup(task, &msg, 0);
+}
+
+static int nfs4_proc_unlck(struct nfs4_state *state, int cmd, struct file_lock *request)
+{
+ struct nfs4_unlockdata *calldata;
+ struct inode *inode = state->inode;
+ struct nfs_server *server = NFS_SERVER(inode);
struct nfs4_lock_state *lsp;
- struct nfs_locku_opargs luargs;
int status;
-
- down_read(&clp->cl_sem);
- down(&state->lock_sema);
+
+ /* Is this a delegated lock? */
+ if (test_bit(NFS_DELEGATED_STATE, &state->flags))
+ return do_vfs_lock(request->fl_file, request);
+
status = nfs4_set_lock_state(state, request);
if (status != 0)
- goto out;
+ return status;
lsp = request->fl_u.nfs4_fl.owner;
/* We might have lost the locks! */
if ((lsp->ls_flags & NFS_LOCK_INITIALIZED) == 0)
- goto out;
- luargs.seqid = lsp->ls_seqid;
- memcpy(&luargs.stateid, &lsp->ls_stateid, sizeof(luargs.stateid));
- arg.u.locku = &luargs;
- status = rpc_call_sync(server->client, &msg, RPC_TASK_NOINTR);
- nfs4_increment_lock_seqid(status, lsp);
-
- if (status == 0)
- memcpy(&lsp->ls_stateid, &res.u.stateid,
- sizeof(lsp->ls_stateid));
-out:
- up(&state->lock_sema);
+ return 0;
+ calldata = kmalloc(sizeof(*calldata), GFP_KERNEL);
+ if (calldata == NULL)
+ return -ENOMEM;
+ calldata->luargs.seqid = nfs_alloc_seqid(&lsp->ls_seqid);
+ if (calldata->luargs.seqid == NULL) {
+ kfree(calldata);
+ return -ENOMEM;
+ }
+ calldata->luargs.stateid = &lsp->ls_stateid;
+ calldata->arg.fh = NFS_FH(inode);
+ calldata->arg.type = nfs4_lck_type(cmd, request);
+ calldata->arg.offset = request->fl_start;
+ calldata->arg.length = nfs4_lck_length(request);
+ calldata->arg.u.locku = &calldata->luargs;
+ calldata->res.server = server;
+ calldata->lsp = lsp;
+ atomic_inc(&lsp->ls_count);
+
+ /* Ensure we don't close file until we're done freeing locks! */
+ calldata->ctx = get_nfs_open_context((struct nfs_open_context*)request->fl_file->private_data);
+
+ atomic_set(&calldata->refcount, 2);
+ init_completion(&calldata->completion);
+
+ status = nfs4_call_async(NFS_SERVER(inode)->client, nfs4_locku_begin,
+ nfs4_locku_done, calldata);
if (status == 0)
- do_vfs_lock(request->fl_file, request);
- up_read(&clp->cl_sem);
+ wait_for_completion_interruptible(&calldata->completion);
+ do_vfs_lock(request->fl_file, request);
+ nfs4_locku_release_calldata(calldata);
return status;
}
-static int nfs4_proc_unlck(struct nfs4_state *state, int cmd, struct file_lock *request)
-{
- struct nfs4_exception exception = { };
- int err;
-
- do {
- err = nfs4_handle_exception(NFS_SERVER(state->inode),
- _nfs4_proc_unlck(state, cmd, request),
- &exception);
- } while (exception.retry);
- return err;
-}
-
static int _nfs4_do_setlk(struct nfs4_state *state, int cmd, struct file_lock *request, int reclaim)
{
struct inode *inode = state->inode;
struct nfs_server *server = NFS_SERVER(inode);
struct nfs4_lock_state *lsp = request->fl_u.nfs4_fl.owner;
+ struct nfs_lock_opargs largs = {
+ .lock_stateid = &lsp->ls_stateid,
+ .open_stateid = &state->stateid,
+ .lock_owner = {
+ .clientid = server->nfs4_state->cl_clientid,
+ .id = lsp->ls_id,
+ },
+ .reclaim = reclaim,
+ };
struct nfs_lockargs arg = {
.fh = NFS_FH(inode),
.type = nfs4_lck_type(cmd, request),
.offset = request->fl_start,
.length = nfs4_lck_length(request),
+ .u = {
+ .lock = &largs,
+ },
};
struct nfs_lockres res = {
.server = server,
@@ -2779,53 +2994,39 @@ static int _nfs4_do_setlk(struct nfs4_state *state, int cmd, struct file_lock *r
.rpc_resp = &res,
.rpc_cred = state->owner->so_cred,
};
- struct nfs_lock_opargs largs = {
- .reclaim = reclaim,
- .new_lock_owner = 0,
- };
- int status;
+ int status = -ENOMEM;
- if (!(lsp->ls_flags & NFS_LOCK_INITIALIZED)) {
+ largs.lock_seqid = nfs_alloc_seqid(&lsp->ls_seqid);
+ if (largs.lock_seqid == NULL)
+ return -ENOMEM;
+ if (!(lsp->ls_seqid.flags & NFS_SEQID_CONFIRMED)) {
struct nfs4_state_owner *owner = state->owner;
- struct nfs_open_to_lock otl = {
- .lock_owner = {
- .clientid = server->nfs4_state->cl_clientid,
- },
- };
-
- otl.lock_seqid = lsp->ls_seqid;
- otl.lock_owner.id = lsp->ls_id;
- memcpy(&otl.open_stateid, &state->stateid, sizeof(otl.open_stateid));
- largs.u.open_lock = &otl;
+
+ largs.open_seqid = nfs_alloc_seqid(&owner->so_seqid);
+ if (largs.open_seqid == NULL)
+ goto out;
largs.new_lock_owner = 1;
- arg.u.lock = &largs;
- down(&owner->so_sema);
- otl.open_seqid = owner->so_seqid;
status = rpc_call_sync(server->client, &msg, RPC_TASK_NOINTR);
- /* increment open_owner seqid on success, and
- * seqid mutating errors */
- nfs4_increment_seqid(status, owner);
- up(&owner->so_sema);
- if (status == 0) {
- lsp->ls_flags |= NFS_LOCK_INITIALIZED;
- lsp->ls_seqid++;
+ /* increment open seqid on success, and seqid mutating errors */
+ if (largs.new_lock_owner != 0) {
+ nfs_increment_open_seqid(status, largs.open_seqid);
+ if (status == 0)
+ nfs_confirm_seqid(&lsp->ls_seqid, 0);
}
- } else {
- struct nfs_exist_lock el = {
- .seqid = lsp->ls_seqid,
- };
- memcpy(&el.stateid, &lsp->ls_stateid, sizeof(el.stateid));
- largs.u.exist_lock = &el;
- arg.u.lock = &largs;
+ nfs_free_seqid(largs.open_seqid);
+ } else
status = rpc_call_sync(server->client, &msg, RPC_TASK_NOINTR);
- /* increment seqid on success, and * seqid mutating errors*/
- nfs4_increment_lock_seqid(status, lsp);
- }
+ /* increment lock seqid on success, and seqid mutating errors*/
+ nfs_increment_lock_seqid(status, largs.lock_seqid);
/* save the returned stateid. */
- if (status == 0)
- memcpy(&lsp->ls_stateid, &res.u.stateid, sizeof(nfs4_stateid));
- else if (status == -NFS4ERR_DENIED)
+ if (status == 0) {
+ memcpy(lsp->ls_stateid.data, res.u.stateid.data,
+ sizeof(lsp->ls_stateid.data));
+ lsp->ls_flags |= NFS_LOCK_INITIALIZED;
+ } else if (status == -NFS4ERR_DENIED)
status = -EAGAIN;
+out:
+ nfs_free_seqid(largs.lock_seqid);
return status;
}
@@ -2835,6 +3036,9 @@ static int nfs4_lock_reclaim(struct nfs4_state *state, struct file_lock *request
struct nfs4_exception exception = { };
int err;
+ /* Cache the lock if possible... */
+ if (test_bit(NFS_DELEGATED_STATE, &state->flags))
+ return 0;
do {
err = _nfs4_do_setlk(state, F_SETLK, request, 1);
if (err != -NFS4ERR_DELAY)
@@ -2850,6 +3054,9 @@ static int nfs4_lock_expired(struct nfs4_state *state, struct file_lock *request
struct nfs4_exception exception = { };
int err;
+ err = nfs4_set_lock_state(state, request);
+ if (err != 0)
+ return err;
do {
err = _nfs4_do_setlk(state, F_SETLK, request, 0);
if (err != -NFS4ERR_DELAY)
@@ -2865,17 +3072,25 @@ static int _nfs4_proc_setlk(struct nfs4_state *state, int cmd, struct file_lock
int status;
down_read(&clp->cl_sem);
- down(&state->lock_sema);
- status = nfs4_set_lock_state(state, request);
- if (status == 0)
- status = _nfs4_do_setlk(state, cmd, request, 0);
- up(&state->lock_sema);
- if (status == 0) {
- /* Note: we always want to sleep here! */
- request->fl_flags |= FL_SLEEP;
- if (do_vfs_lock(request->fl_file, request) < 0)
- printk(KERN_WARNING "%s: VFS is out of sync with lock manager!\n", __FUNCTION__);
+ /* Is this a delegated open? */
+ if (test_bit(NFS_DELEGATED_STATE, &state->flags)) {
+ /* Yes: cache locks! */
+ status = do_vfs_lock(request->fl_file, request);
+ /* ...but avoid races with delegation recall... */
+ if (status < 0 || test_bit(NFS_DELEGATED_STATE, &state->flags))
+ goto out;
}
+ status = nfs4_set_lock_state(state, request);
+ if (status != 0)
+ goto out;
+ status = _nfs4_do_setlk(state, cmd, request, 0);
+ if (status != 0)
+ goto out;
+ /* Note: we always want to sleep here! */
+ request->fl_flags |= FL_SLEEP;
+ if (do_vfs_lock(request->fl_file, request) < 0)
+ printk(KERN_WARNING "%s: VFS is out of sync with lock manager!\n", __FUNCTION__);
+out:
up_read(&clp->cl_sem);
return status;
}
@@ -2929,6 +3144,24 @@ nfs4_proc_lock(struct file *filp, int cmd, struct file_lock *request)
return status;
}
+int nfs4_lock_delegation_recall(struct nfs4_state *state, struct file_lock *fl)
+{
+ struct nfs_server *server = NFS_SERVER(state->inode);
+ struct nfs4_exception exception = { };
+ int err;
+
+ err = nfs4_set_lock_state(state, fl);
+ if (err != 0)
+ goto out;
+ do {
+ err = _nfs4_do_setlk(state, F_SETLK, fl, 0);
+ if (err != -NFS4ERR_DELAY)
+ break;
+ err = nfs4_handle_exception(server, err, &exception);
+ } while (exception.retry);
+out:
+ return err;
+}
#define XATTR_NAME_NFSV4_ACL "system.nfs4_acl"
@@ -3024,8 +3257,8 @@ struct nfs_rpc_ops nfs_v4_clientops = {
.read_setup = nfs4_proc_read_setup,
.write_setup = nfs4_proc_write_setup,
.commit_setup = nfs4_proc_commit_setup,
- .file_open = nfs4_proc_file_open,
- .file_release = nfs4_proc_file_release,
+ .file_open = nfs_open,
+ .file_release = nfs_release,
.lock = nfs4_proc_lock,
.clear_acl_cache = nfs4_zap_acl_attr,
};
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
index afe587d82f1e..0675f3215e0a 100644
--- a/fs/nfs/nfs4state.c
+++ b/fs/nfs/nfs4state.c
@@ -69,10 +69,8 @@ init_nfsv4_state(struct nfs_server *server)
void
destroy_nfsv4_state(struct nfs_server *server)
{
- if (server->mnt_path) {
- kfree(server->mnt_path);
- server->mnt_path = NULL;
- }
+ kfree(server->mnt_path);
+ server->mnt_path = NULL;
if (server->nfs4_state) {
nfs4_put_client(server->nfs4_state);
server->nfs4_state = NULL;
@@ -264,13 +262,16 @@ nfs4_alloc_state_owner(void)
{
struct nfs4_state_owner *sp;
- sp = kmalloc(sizeof(*sp),GFP_KERNEL);
+ sp = kzalloc(sizeof(*sp),GFP_KERNEL);
if (!sp)
return NULL;
- init_MUTEX(&sp->so_sema);
- sp->so_seqid = 0; /* arbitrary */
+ spin_lock_init(&sp->so_lock);
INIT_LIST_HEAD(&sp->so_states);
INIT_LIST_HEAD(&sp->so_delegations);
+ rpc_init_wait_queue(&sp->so_sequence.wait, "Seqid_waitqueue");
+ sp->so_seqid.sequence = &sp->so_sequence;
+ spin_lock_init(&sp->so_sequence.lock);
+ INIT_LIST_HEAD(&sp->so_sequence.list);
atomic_set(&sp->so_count, 1);
return sp;
}
@@ -308,8 +309,7 @@ struct nfs4_state_owner *nfs4_get_state_owner(struct nfs_server *server, struct
new = NULL;
}
spin_unlock(&clp->cl_lock);
- if (new)
- kfree(new);
+ kfree(new);
if (sp != NULL)
return sp;
put_rpccred(cred);
@@ -359,35 +359,25 @@ nfs4_alloc_open_state(void)
memset(state->stateid.data, 0, sizeof(state->stateid.data));
atomic_set(&state->count, 1);
INIT_LIST_HEAD(&state->lock_states);
- init_MUTEX(&state->lock_sema);
spin_lock_init(&state->state_lock);
return state;
}
-static struct nfs4_state *
-__nfs4_find_state(struct inode *inode, struct rpc_cred *cred, mode_t mode)
+void
+nfs4_state_set_mode_locked(struct nfs4_state *state, mode_t mode)
{
- struct nfs_inode *nfsi = NFS_I(inode);
- struct nfs4_state *state;
-
- mode &= (FMODE_READ|FMODE_WRITE);
- list_for_each_entry(state, &nfsi->open_states, inode_states) {
- if (state->owner->so_cred != cred)
- continue;
- if ((mode & FMODE_READ) != 0 && state->nreaders == 0)
- continue;
- if ((mode & FMODE_WRITE) != 0 && state->nwriters == 0)
- continue;
- if ((state->state & mode) != mode)
- continue;
- atomic_inc(&state->count);
- if (mode & FMODE_READ)
- state->nreaders++;
+ if (state->state == mode)
+ return;
+ /* NB! List reordering - see the reclaim code for why. */
+ if ((mode & FMODE_WRITE) != (state->state & FMODE_WRITE)) {
if (mode & FMODE_WRITE)
- state->nwriters++;
- return state;
+ list_move(&state->open_states, &state->owner->so_states);
+ else
+ list_move_tail(&state->open_states, &state->owner->so_states);
}
- return NULL;
+ if (mode == 0)
+ list_del_init(&state->inode_states);
+ state->state = mode;
}
static struct nfs4_state *
@@ -398,7 +388,7 @@ __nfs4_find_state_byowner(struct inode *inode, struct nfs4_state_owner *owner)
list_for_each_entry(state, &nfsi->open_states, inode_states) {
/* Is this in the process of being freed? */
- if (state->nreaders == 0 && state->nwriters == 0)
+ if (state->state == 0)
continue;
if (state->owner == owner) {
atomic_inc(&state->count);
@@ -408,17 +398,6 @@ __nfs4_find_state_byowner(struct inode *inode, struct nfs4_state_owner *owner)
return NULL;
}
-struct nfs4_state *
-nfs4_find_state(struct inode *inode, struct rpc_cred *cred, mode_t mode)
-{
- struct nfs4_state *state;
-
- spin_lock(&inode->i_lock);
- state = __nfs4_find_state(inode, cred, mode);
- spin_unlock(&inode->i_lock);
- return state;
-}
-
static void
nfs4_free_open_state(struct nfs4_state *state)
{
@@ -437,21 +416,23 @@ nfs4_get_open_state(struct inode *inode, struct nfs4_state_owner *owner)
if (state)
goto out;
new = nfs4_alloc_open_state();
+ spin_lock(&owner->so_lock);
spin_lock(&inode->i_lock);
state = __nfs4_find_state_byowner(inode, owner);
if (state == NULL && new != NULL) {
state = new;
- /* Caller *must* be holding owner->so_sem */
- /* Note: The reclaim code dictates that we add stateless
- * and read-only stateids to the end of the list */
- list_add_tail(&state->open_states, &owner->so_states);
state->owner = owner;
atomic_inc(&owner->so_count);
list_add(&state->inode_states, &nfsi->open_states);
state->inode = igrab(inode);
spin_unlock(&inode->i_lock);
+ /* Note: The reclaim code dictates that we add stateless
+ * and read-only stateids to the end of the list */
+ list_add_tail(&state->open_states, &owner->so_states);
+ spin_unlock(&owner->so_lock);
} else {
spin_unlock(&inode->i_lock);
+ spin_unlock(&owner->so_lock);
if (new)
nfs4_free_open_state(new);
}
@@ -461,68 +442,59 @@ out:
/*
* Beware! Caller must be holding exactly one
- * reference to clp->cl_sem and owner->so_sema!
+ * reference to clp->cl_sem!
*/
void nfs4_put_open_state(struct nfs4_state *state)
{
struct inode *inode = state->inode;
struct nfs4_state_owner *owner = state->owner;
- if (!atomic_dec_and_lock(&state->count, &inode->i_lock))
+ if (!atomic_dec_and_lock(&state->count, &owner->so_lock))
return;
+ spin_lock(&inode->i_lock);
if (!list_empty(&state->inode_states))
list_del(&state->inode_states);
- spin_unlock(&inode->i_lock);
list_del(&state->open_states);
+ spin_unlock(&inode->i_lock);
+ spin_unlock(&owner->so_lock);
iput(inode);
- BUG_ON (state->state != 0);
nfs4_free_open_state(state);
nfs4_put_state_owner(owner);
}
/*
- * Beware! Caller must be holding no references to clp->cl_sem!
- * of owner->so_sema!
+ * Close the current file.
*/
void nfs4_close_state(struct nfs4_state *state, mode_t mode)
{
struct inode *inode = state->inode;
struct nfs4_state_owner *owner = state->owner;
- struct nfs4_client *clp = owner->so_client;
- int newstate;
+ int oldstate, newstate = 0;
atomic_inc(&owner->so_count);
- down_read(&clp->cl_sem);
- down(&owner->so_sema);
/* Protect against nfs4_find_state() */
+ spin_lock(&owner->so_lock);
spin_lock(&inode->i_lock);
if (mode & FMODE_READ)
state->nreaders--;
if (mode & FMODE_WRITE)
state->nwriters--;
- if (state->nwriters == 0) {
- if (state->nreaders == 0)
- list_del_init(&state->inode_states);
- /* See reclaim code */
- list_move_tail(&state->open_states, &owner->so_states);
+ oldstate = newstate = state->state;
+ if (state->nreaders == 0)
+ newstate &= ~FMODE_READ;
+ if (state->nwriters == 0)
+ newstate &= ~FMODE_WRITE;
+ if (test_bit(NFS_DELEGATED_STATE, &state->flags)) {
+ nfs4_state_set_mode_locked(state, newstate);
+ oldstate = newstate;
}
spin_unlock(&inode->i_lock);
- newstate = 0;
- if (state->state != 0) {
- if (state->nreaders)
- newstate |= FMODE_READ;
- if (state->nwriters)
- newstate |= FMODE_WRITE;
- if (state->state == newstate)
- goto out;
- if (nfs4_do_close(inode, state, newstate) == -EINPROGRESS)
- return;
- }
-out:
+ spin_unlock(&owner->so_lock);
+
+ if (oldstate != newstate && nfs4_do_close(inode, state) == 0)
+ return;
nfs4_put_open_state(state);
- up(&owner->so_sema);
nfs4_put_state_owner(owner);
- up_read(&clp->cl_sem);
}
/*
@@ -546,19 +518,16 @@ __nfs4_find_lock_state(struct nfs4_state *state, fl_owner_t fl_owner)
* Return a compatible lock_state. If no initialized lock_state structure
* exists, return an uninitialized one.
*
- * The caller must be holding state->lock_sema
*/
static struct nfs4_lock_state *nfs4_alloc_lock_state(struct nfs4_state *state, fl_owner_t fl_owner)
{
struct nfs4_lock_state *lsp;
struct nfs4_client *clp = state->owner->so_client;
- lsp = kmalloc(sizeof(*lsp), GFP_KERNEL);
+ lsp = kzalloc(sizeof(*lsp), GFP_KERNEL);
if (lsp == NULL)
return NULL;
- lsp->ls_flags = 0;
- lsp->ls_seqid = 0; /* arbitrary */
- memset(lsp->ls_stateid.data, 0, sizeof(lsp->ls_stateid.data));
+ lsp->ls_seqid.sequence = &state->owner->so_sequence;
atomic_set(&lsp->ls_count, 1);
lsp->ls_owner = fl_owner;
spin_lock(&clp->cl_lock);
@@ -572,7 +541,7 @@ static struct nfs4_lock_state *nfs4_alloc_lock_state(struct nfs4_state *state, f
* Return a compatible lock_state. If no initialized lock_state structure
* exists, return an uninitialized one.
*
- * The caller must be holding state->lock_sema and clp->cl_sem
+ * The caller must be holding clp->cl_sem
*/
static struct nfs4_lock_state *nfs4_get_lock_state(struct nfs4_state *state, fl_owner_t owner)
{
@@ -605,7 +574,7 @@ static struct nfs4_lock_state *nfs4_get_lock_state(struct nfs4_state *state, fl_
* Release reference to lock_state, and free it if we see that
* it is no longer in use
*/
-static void nfs4_put_lock_state(struct nfs4_lock_state *lsp)
+void nfs4_put_lock_state(struct nfs4_lock_state *lsp)
{
struct nfs4_state *state;
@@ -673,29 +642,94 @@ void nfs4_copy_stateid(nfs4_stateid *dst, struct nfs4_state *state, fl_owner_t f
nfs4_put_lock_state(lsp);
}
-/*
-* Called with state->lock_sema and clp->cl_sem held.
-*/
-void nfs4_increment_lock_seqid(int status, struct nfs4_lock_state *lsp)
+struct nfs_seqid *nfs_alloc_seqid(struct nfs_seqid_counter *counter)
+{
+ struct nfs_seqid *new;
+
+ new = kmalloc(sizeof(*new), GFP_KERNEL);
+ if (new != NULL) {
+ new->sequence = counter;
+ INIT_LIST_HEAD(&new->list);
+ }
+ return new;
+}
+
+void nfs_free_seqid(struct nfs_seqid *seqid)
{
- if (status == NFS_OK || seqid_mutating_err(-status))
- lsp->ls_seqid++;
+ struct rpc_sequence *sequence = seqid->sequence->sequence;
+
+ if (!list_empty(&seqid->list)) {
+ spin_lock(&sequence->lock);
+ list_del(&seqid->list);
+ spin_unlock(&sequence->lock);
+ }
+ rpc_wake_up_next(&sequence->wait);
+ kfree(seqid);
}
/*
-* Called with sp->so_sema and clp->cl_sem held.
-*
-* Increment the seqid if the OPEN/OPEN_DOWNGRADE/CLOSE succeeded, or
-* failed with a seqid incrementing error -
-* see comments nfs_fs.h:seqid_mutating_error()
-*/
-void nfs4_increment_seqid(int status, struct nfs4_state_owner *sp)
-{
- if (status == NFS_OK || seqid_mutating_err(-status))
- sp->so_seqid++;
- /* If the server returns BAD_SEQID, unhash state_owner here */
- if (status == -NFS4ERR_BAD_SEQID)
+ * Increment the seqid if the OPEN/OPEN_DOWNGRADE/CLOSE succeeded, or
+ * failed with a seqid incrementing error -
+ * see comments nfs_fs.h:seqid_mutating_error()
+ */
+static inline void nfs_increment_seqid(int status, struct nfs_seqid *seqid)
+{
+ switch (status) {
+ case 0:
+ break;
+ case -NFS4ERR_BAD_SEQID:
+ case -NFS4ERR_STALE_CLIENTID:
+ case -NFS4ERR_STALE_STATEID:
+ case -NFS4ERR_BAD_STATEID:
+ case -NFS4ERR_BADXDR:
+ case -NFS4ERR_RESOURCE:
+ case -NFS4ERR_NOFILEHANDLE:
+ /* Non-seqid mutating errors */
+ return;
+ };
+ /*
+ * Note: no locking needed as we are guaranteed to be first
+ * on the sequence list
+ */
+ seqid->sequence->counter++;
+}
+
+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);
nfs4_drop_state_owner(sp);
+ }
+ return nfs_increment_seqid(status, seqid);
+}
+
+/*
+ * Increment the seqid if the LOCK/LOCKU succeeded, or
+ * failed with a seqid incrementing error -
+ * see comments nfs_fs.h:seqid_mutating_error()
+ */
+void nfs_increment_lock_seqid(int status, struct nfs_seqid *seqid)
+{
+ return nfs_increment_seqid(status, seqid);
+}
+
+int nfs_wait_on_sequence(struct nfs_seqid *seqid, struct rpc_task *task)
+{
+ struct rpc_sequence *sequence = seqid->sequence->sequence;
+ int status = 0;
+
+ if (sequence->list.next == &seqid->list)
+ goto out;
+ spin_lock(&sequence->lock);
+ if (!list_empty(&sequence->list)) {
+ rpc_sleep_on(&sequence->wait, task, NULL, NULL);
+ status = -EAGAIN;
+ } else
+ list_add(&seqid->list, &sequence->list);
+ spin_unlock(&sequence->lock);
+out:
+ return status;
}
static int reclaimer(void *);
@@ -747,7 +781,7 @@ static int nfs4_reclaim_locks(struct nfs4_state_recovery_ops *ops, struct nfs4_s
int status = 0;
for (fl = inode->i_flock; fl != 0; fl = fl->fl_next) {
- if (!(fl->fl_flags & FL_POSIX))
+ if (!(fl->fl_flags & (FL_POSIX|FL_FLOCK)))
continue;
if (((struct nfs_open_context *)fl->fl_file->private_data)->state != state)
continue;
@@ -762,7 +796,7 @@ static int nfs4_reclaim_locks(struct nfs4_state_recovery_ops *ops, struct nfs4_s
case -NFS4ERR_NO_GRACE:
case -NFS4ERR_RECLAIM_BAD:
case -NFS4ERR_RECLAIM_CONFLICT:
- /* kill_proc(fl->fl_owner, SIGLOST, 1); */
+ /* kill_proc(fl->fl_pid, SIGLOST, 1); */
break;
case -NFS4ERR_STALE_CLIENTID:
goto out_err;
@@ -791,8 +825,6 @@ static int nfs4_reclaim_open_state(struct nfs4_state_recovery_ops *ops, struct n
if (state->state == 0)
continue;
status = ops->recover_open(sp, state);
- list_for_each_entry(lock, &state->lock_states, ls_locks)
- lock->ls_flags &= ~NFS_LOCK_INITIALIZED;
if (status >= 0) {
status = nfs4_reclaim_locks(ops, state);
if (status < 0)
@@ -831,6 +863,28 @@ out_err:
return status;
}
+static void nfs4_state_mark_reclaim(struct nfs4_client *clp)
+{
+ struct nfs4_state_owner *sp;
+ struct nfs4_state *state;
+ struct nfs4_lock_state *lock;
+
+ /* Reset all sequence ids to zero */
+ list_for_each_entry(sp, &clp->cl_state_owners, so_list) {
+ sp->so_seqid.counter = 0;
+ sp->so_seqid.flags = 0;
+ spin_lock(&sp->so_lock);
+ list_for_each_entry(state, &sp->so_states, open_states) {
+ list_for_each_entry(lock, &state->lock_states, ls_locks) {
+ lock->ls_seqid.counter = 0;
+ lock->ls_seqid.flags = 0;
+ lock->ls_flags &= ~NFS_LOCK_INITIALIZED;
+ }
+ }
+ spin_unlock(&sp->so_lock);
+ }
+}
+
static int reclaimer(void *ptr)
{
struct reclaimer_args *args = (struct reclaimer_args *)ptr;
@@ -864,6 +918,7 @@ restart_loop:
default:
ops = &nfs4_network_partition_recovery_ops;
};
+ nfs4_state_mark_reclaim(clp);
status = __nfs4_init_client(clp);
if (status)
goto out_error;
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index 6c564ef9489e..fbbace8a30c4 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -95,6 +95,8 @@ static int nfs_stat_to_errno(int);
#define decode_getattr_maxsz (op_decode_hdr_maxsz + nfs4_fattr_maxsz)
#define encode_savefh_maxsz (op_encode_hdr_maxsz)
#define decode_savefh_maxsz (op_decode_hdr_maxsz)
+#define encode_restorefh_maxsz (op_encode_hdr_maxsz)
+#define decode_restorefh_maxsz (op_decode_hdr_maxsz)
#define encode_fsinfo_maxsz (op_encode_hdr_maxsz + 2)
#define decode_fsinfo_maxsz (op_decode_hdr_maxsz + 11)
#define encode_renew_maxsz (op_encode_hdr_maxsz + 3)
@@ -157,16 +159,20 @@ static int nfs_stat_to_errno(int);
op_decode_hdr_maxsz + 2)
#define NFS4_enc_write_sz (compound_encode_hdr_maxsz + \
encode_putfh_maxsz + \
- op_encode_hdr_maxsz + 8)
+ op_encode_hdr_maxsz + 8 + \
+ encode_getattr_maxsz)
#define NFS4_dec_write_sz (compound_decode_hdr_maxsz + \
decode_putfh_maxsz + \
- op_decode_hdr_maxsz + 4)
+ op_decode_hdr_maxsz + 4 + \
+ decode_getattr_maxsz)
#define NFS4_enc_commit_sz (compound_encode_hdr_maxsz + \
encode_putfh_maxsz + \
- op_encode_hdr_maxsz + 3)
+ op_encode_hdr_maxsz + 3 + \
+ encode_getattr_maxsz)
#define NFS4_dec_commit_sz (compound_decode_hdr_maxsz + \
decode_putfh_maxsz + \
- op_decode_hdr_maxsz + 2)
+ op_decode_hdr_maxsz + 2 + \
+ decode_getattr_maxsz)
#define NFS4_enc_open_sz (compound_encode_hdr_maxsz + \
encode_putfh_maxsz + \
op_encode_hdr_maxsz + \
@@ -196,17 +202,21 @@ static int nfs_stat_to_errno(int);
#define NFS4_enc_open_downgrade_sz \
(compound_encode_hdr_maxsz + \
encode_putfh_maxsz + \
- op_encode_hdr_maxsz + 7)
+ op_encode_hdr_maxsz + 7 + \
+ encode_getattr_maxsz)
#define NFS4_dec_open_downgrade_sz \
(compound_decode_hdr_maxsz + \
decode_putfh_maxsz + \
- op_decode_hdr_maxsz + 4)
+ op_decode_hdr_maxsz + 4 + \
+ decode_getattr_maxsz)
#define NFS4_enc_close_sz (compound_encode_hdr_maxsz + \
encode_putfh_maxsz + \
- op_encode_hdr_maxsz + 5)
+ op_encode_hdr_maxsz + 5 + \
+ encode_getattr_maxsz)
#define NFS4_dec_close_sz (compound_decode_hdr_maxsz + \
decode_putfh_maxsz + \
- op_decode_hdr_maxsz + 4)
+ op_decode_hdr_maxsz + 4 + \
+ decode_getattr_maxsz)
#define NFS4_enc_setattr_sz (compound_encode_hdr_maxsz + \
encode_putfh_maxsz + \
op_encode_hdr_maxsz + 4 + \
@@ -300,30 +310,44 @@ static int nfs_stat_to_errno(int);
decode_getfh_maxsz)
#define NFS4_enc_remove_sz (compound_encode_hdr_maxsz + \
encode_putfh_maxsz + \
- encode_remove_maxsz)
+ encode_remove_maxsz + \
+ encode_getattr_maxsz)
#define NFS4_dec_remove_sz (compound_decode_hdr_maxsz + \
decode_putfh_maxsz + \
- op_decode_hdr_maxsz + 5)
+ op_decode_hdr_maxsz + 5 + \
+ decode_getattr_maxsz)
#define NFS4_enc_rename_sz (compound_encode_hdr_maxsz + \
encode_putfh_maxsz + \
encode_savefh_maxsz + \
encode_putfh_maxsz + \
- encode_rename_maxsz)
+ encode_rename_maxsz + \
+ encode_getattr_maxsz + \
+ encode_restorefh_maxsz + \
+ encode_getattr_maxsz)
#define NFS4_dec_rename_sz (compound_decode_hdr_maxsz + \
decode_putfh_maxsz + \
decode_savefh_maxsz + \
decode_putfh_maxsz + \
- decode_rename_maxsz)
+ decode_rename_maxsz + \
+ decode_getattr_maxsz + \
+ decode_restorefh_maxsz + \
+ decode_getattr_maxsz)
#define NFS4_enc_link_sz (compound_encode_hdr_maxsz + \
encode_putfh_maxsz + \
encode_savefh_maxsz + \
encode_putfh_maxsz + \
- encode_link_maxsz)
+ encode_link_maxsz + \
+ decode_getattr_maxsz + \
+ encode_restorefh_maxsz + \
+ decode_getattr_maxsz)
#define NFS4_dec_link_sz (compound_decode_hdr_maxsz + \
decode_putfh_maxsz + \
decode_savefh_maxsz + \
decode_putfh_maxsz + \
- decode_link_maxsz)
+ decode_link_maxsz + \
+ decode_getattr_maxsz + \
+ decode_restorefh_maxsz + \
+ decode_getattr_maxsz)
#define NFS4_enc_symlink_sz (compound_encode_hdr_maxsz + \
encode_putfh_maxsz + \
encode_symlink_maxsz + \
@@ -336,14 +360,20 @@ static int nfs_stat_to_errno(int);
decode_getfh_maxsz)
#define NFS4_enc_create_sz (compound_encode_hdr_maxsz + \
encode_putfh_maxsz + \
+ encode_savefh_maxsz + \
encode_create_maxsz + \
+ encode_getfh_maxsz + \
encode_getattr_maxsz + \
- encode_getfh_maxsz)
+ encode_restorefh_maxsz + \
+ encode_getattr_maxsz)
#define NFS4_dec_create_sz (compound_decode_hdr_maxsz + \
decode_putfh_maxsz + \
+ decode_savefh_maxsz + \
decode_create_maxsz + \
+ decode_getfh_maxsz + \
decode_getattr_maxsz + \
- decode_getfh_maxsz)
+ decode_restorefh_maxsz + \
+ decode_getattr_maxsz)
#define NFS4_enc_pathconf_sz (compound_encode_hdr_maxsz + \
encode_putfh_maxsz + \
encode_getattr_maxsz)
@@ -602,10 +632,10 @@ static int encode_close(struct xdr_stream *xdr, const struct nfs_closeargs *arg)
{
uint32_t *p;
- RESERVE_SPACE(8+sizeof(arg->stateid.data));
+ RESERVE_SPACE(8+sizeof(arg->stateid->data));
WRITE32(OP_CLOSE);
- WRITE32(arg->seqid);
- WRITEMEM(arg->stateid.data, sizeof(arg->stateid.data));
+ WRITE32(arg->seqid->sequence->counter);
+ WRITEMEM(arg->stateid->data, sizeof(arg->stateid->data));
return 0;
}
@@ -729,22 +759,18 @@ static int encode_lock(struct xdr_stream *xdr, const struct nfs_lockargs *arg)
WRITE64(arg->length);
WRITE32(opargs->new_lock_owner);
if (opargs->new_lock_owner){
- struct nfs_open_to_lock *ol = opargs->u.open_lock;
-
RESERVE_SPACE(40);
- WRITE32(ol->open_seqid);
- WRITEMEM(&ol->open_stateid, sizeof(ol->open_stateid));
- WRITE32(ol->lock_seqid);
- WRITE64(ol->lock_owner.clientid);
+ WRITE32(opargs->open_seqid->sequence->counter);
+ WRITEMEM(opargs->open_stateid->data, sizeof(opargs->open_stateid->data));
+ WRITE32(opargs->lock_seqid->sequence->counter);
+ WRITE64(opargs->lock_owner.clientid);
WRITE32(4);
- WRITE32(ol->lock_owner.id);
+ WRITE32(opargs->lock_owner.id);
}
else {
- struct nfs_exist_lock *el = opargs->u.exist_lock;
-
RESERVE_SPACE(20);
- WRITEMEM(&el->stateid, sizeof(el->stateid));
- WRITE32(el->seqid);
+ WRITEMEM(opargs->lock_stateid->data, sizeof(opargs->lock_stateid->data));
+ WRITE32(opargs->lock_seqid->sequence->counter);
}
return 0;
@@ -775,8 +801,8 @@ static int encode_locku(struct xdr_stream *xdr, const struct nfs_lockargs *arg)
RESERVE_SPACE(44);
WRITE32(OP_LOCKU);
WRITE32(arg->type);
- WRITE32(opargs->seqid);
- WRITEMEM(&opargs->stateid, sizeof(opargs->stateid));
+ WRITE32(opargs->seqid->sequence->counter);
+ WRITEMEM(opargs->stateid->data, sizeof(opargs->stateid->data));
WRITE64(arg->offset);
WRITE64(arg->length);
@@ -826,7 +852,7 @@ static inline void encode_openhdr(struct xdr_stream *xdr, const struct nfs_opena
*/
RESERVE_SPACE(8);
WRITE32(OP_OPEN);
- WRITE32(arg->seqid);
+ WRITE32(arg->seqid->sequence->counter);
encode_share_access(xdr, arg->open_flags);
RESERVE_SPACE(16);
WRITE64(arg->clientid);
@@ -941,7 +967,7 @@ static int encode_open_confirm(struct xdr_stream *xdr, const struct nfs_open_con
RESERVE_SPACE(8+sizeof(arg->stateid.data));
WRITE32(OP_OPEN_CONFIRM);
WRITEMEM(arg->stateid.data, sizeof(arg->stateid.data));
- WRITE32(arg->seqid);
+ WRITE32(arg->seqid->sequence->counter);
return 0;
}
@@ -950,10 +976,10 @@ static int encode_open_downgrade(struct xdr_stream *xdr, const struct nfs_closea
{
uint32_t *p;
- RESERVE_SPACE(8+sizeof(arg->stateid.data));
+ RESERVE_SPACE(8+sizeof(arg->stateid->data));
WRITE32(OP_OPEN_DOWNGRADE);
- WRITEMEM(arg->stateid.data, sizeof(arg->stateid.data));
- WRITE32(arg->seqid);
+ WRITEMEM(arg->stateid->data, sizeof(arg->stateid->data));
+ WRITE32(arg->seqid->sequence->counter);
encode_share_access(xdr, arg->open_flags);
return 0;
}
@@ -1117,6 +1143,17 @@ static int encode_renew(struct xdr_stream *xdr, const struct nfs4_client *client
}
static int
+encode_restorefh(struct xdr_stream *xdr)
+{
+ uint32_t *p;
+
+ RESERVE_SPACE(4);
+ WRITE32(OP_RESTOREFH);
+
+ return 0;
+}
+
+static int
encode_setacl(struct xdr_stream *xdr, struct nfs_setaclargs *arg)
{
uint32_t *p;
@@ -1296,14 +1333,18 @@ static int nfs4_xdr_enc_remove(struct rpc_rqst *req, uint32_t *p, const struct n
{
struct xdr_stream xdr;
struct compound_hdr hdr = {
- .nops = 2,
+ .nops = 3,
};
int status;
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
encode_compound_hdr(&xdr, &hdr);
- if ((status = encode_putfh(&xdr, args->fh)) == 0)
- status = encode_remove(&xdr, args->name);
+ if ((status = encode_putfh(&xdr, args->fh)) != 0)
+ goto out;
+ if ((status = encode_remove(&xdr, args->name)) != 0)
+ goto out;
+ status = encode_getfattr(&xdr, args->bitmask);
+out:
return status;
}
@@ -1314,7 +1355,7 @@ static int nfs4_xdr_enc_rename(struct rpc_rqst *req, uint32_t *p, const struct n
{
struct xdr_stream xdr;
struct compound_hdr hdr = {
- .nops = 4,
+ .nops = 7,
};
int status;
@@ -1326,7 +1367,13 @@ static int nfs4_xdr_enc_rename(struct rpc_rqst *req, uint32_t *p, const struct n
goto out;
if ((status = encode_putfh(&xdr, args->new_dir)) != 0)
goto out;
- status = encode_rename(&xdr, args->old_name, args->new_name);
+ if ((status = encode_rename(&xdr, args->old_name, args->new_name)) != 0)
+ goto out;
+ if ((status = encode_getfattr(&xdr, args->bitmask)) != 0)
+ goto out;
+ if ((status = encode_restorefh(&xdr)) != 0)
+ goto out;
+ status = encode_getfattr(&xdr, args->bitmask);
out:
return status;
}
@@ -1338,7 +1385,7 @@ static int nfs4_xdr_enc_link(struct rpc_rqst *req, uint32_t *p, const struct nfs
{
struct xdr_stream xdr;
struct compound_hdr hdr = {
- .nops = 4,
+ .nops = 7,
};
int status;
@@ -1350,7 +1397,13 @@ static int nfs4_xdr_enc_link(struct rpc_rqst *req, uint32_t *p, const struct nfs
goto out;
if ((status = encode_putfh(&xdr, args->dir_fh)) != 0)
goto out;
- status = encode_link(&xdr, args->name);
+ if ((status = encode_link(&xdr, args->name)) != 0)
+ goto out;
+ if ((status = encode_getfattr(&xdr, args->bitmask)) != 0)
+ goto out;
+ if ((status = encode_restorefh(&xdr)) != 0)
+ goto out;
+ status = encode_getfattr(&xdr, args->bitmask);
out:
return status;
}
@@ -1362,7 +1415,7 @@ static int nfs4_xdr_enc_create(struct rpc_rqst *req, uint32_t *p, const struct n
{
struct xdr_stream xdr;
struct compound_hdr hdr = {
- .nops = 4,
+ .nops = 7,
};
int status;
@@ -1370,10 +1423,16 @@ static int nfs4_xdr_enc_create(struct rpc_rqst *req, uint32_t *p, const struct n
encode_compound_hdr(&xdr, &hdr);
if ((status = encode_putfh(&xdr, args->dir_fh)) != 0)
goto out;
+ if ((status = encode_savefh(&xdr)) != 0)
+ goto out;
if ((status = encode_create(&xdr, args)) != 0)
goto out;
if ((status = encode_getfh(&xdr)) != 0)
goto out;
+ if ((status = encode_getfattr(&xdr, args->bitmask)) != 0)
+ goto out;
+ if ((status = encode_restorefh(&xdr)) != 0)
+ goto out;
status = encode_getfattr(&xdr, args->bitmask);
out:
return status;
@@ -1412,7 +1471,7 @@ static int nfs4_xdr_enc_close(struct rpc_rqst *req, uint32_t *p, struct nfs_clos
{
struct xdr_stream xdr;
struct compound_hdr hdr = {
- .nops = 2,
+ .nops = 3,
};
int status;
@@ -1422,6 +1481,9 @@ static int nfs4_xdr_enc_close(struct rpc_rqst *req, uint32_t *p, struct nfs_clos
if(status)
goto out;
status = encode_close(&xdr, args);
+ if (status != 0)
+ goto out;
+ status = encode_getfattr(&xdr, args->bitmask);
out:
return status;
}
@@ -1433,15 +1495,21 @@ static int nfs4_xdr_enc_open(struct rpc_rqst *req, uint32_t *p, struct nfs_opena
{
struct xdr_stream xdr;
struct compound_hdr hdr = {
- .nops = 4,
+ .nops = 7,
};
int status;
+ status = nfs_wait_on_sequence(args->seqid, req->rq_task);
+ if (status != 0)
+ goto out;
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
encode_compound_hdr(&xdr, &hdr);
status = encode_putfh(&xdr, args->fh);
if (status)
goto out;
+ status = encode_savefh(&xdr);
+ if (status)
+ goto out;
status = encode_open(&xdr, args);
if (status)
goto out;
@@ -1449,6 +1517,12 @@ static int nfs4_xdr_enc_open(struct rpc_rqst *req, uint32_t *p, struct nfs_opena
if (status)
goto out;
status = encode_getfattr(&xdr, args->bitmask);
+ if (status)
+ goto out;
+ status = encode_restorefh(&xdr);
+ if (status)
+ goto out;
+ status = encode_getfattr(&xdr, args->bitmask);
out:
return status;
}
@@ -1464,6 +1538,9 @@ static int nfs4_xdr_enc_open_confirm(struct rpc_rqst *req, uint32_t *p, struct n
};
int status;
+ status = nfs_wait_on_sequence(args->seqid, req->rq_task);
+ if (status != 0)
+ goto out;
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
encode_compound_hdr(&xdr, &hdr);
status = encode_putfh(&xdr, args->fh);
@@ -1485,6 +1562,9 @@ static int nfs4_xdr_enc_open_noattr(struct rpc_rqst *req, uint32_t *p, struct nf
};
int status;
+ status = nfs_wait_on_sequence(args->seqid, req->rq_task);
+ if (status != 0)
+ goto out;
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
encode_compound_hdr(&xdr, &hdr);
status = encode_putfh(&xdr, args->fh);
@@ -1502,7 +1582,7 @@ static int nfs4_xdr_enc_open_downgrade(struct rpc_rqst *req, uint32_t *p, struct
{
struct xdr_stream xdr;
struct compound_hdr hdr = {
- .nops = 2,
+ .nops = 3,
};
int status;
@@ -1512,6 +1592,9 @@ static int nfs4_xdr_enc_open_downgrade(struct rpc_rqst *req, uint32_t *p, struct
if (status)
goto out;
status = encode_open_downgrade(&xdr, args);
+ if (status != 0)
+ goto out;
+ status = encode_getfattr(&xdr, args->bitmask);
out:
return status;
}
@@ -1525,8 +1608,15 @@ static int nfs4_xdr_enc_lock(struct rpc_rqst *req, uint32_t *p, struct nfs_locka
struct compound_hdr hdr = {
.nops = 2,
};
+ struct nfs_lock_opargs *opargs = args->u.lock;
int status;
+ status = nfs_wait_on_sequence(opargs->lock_seqid, req->rq_task);
+ if (status != 0)
+ goto out;
+ /* Do we need to do an open_to_lock_owner? */
+ if (opargs->lock_seqid->sequence->flags & NFS_SEQID_CONFIRMED)
+ opargs->new_lock_owner = 0;
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
encode_compound_hdr(&xdr, &hdr);
status = encode_putfh(&xdr, args->fh);
@@ -1713,7 +1803,7 @@ static int nfs4_xdr_enc_write(struct rpc_rqst *req, uint32_t *p, struct nfs_writ
{
struct xdr_stream xdr;
struct compound_hdr hdr = {
- .nops = 2,
+ .nops = 3,
};
int status;
@@ -1723,6 +1813,9 @@ static int nfs4_xdr_enc_write(struct rpc_rqst *req, uint32_t *p, struct nfs_writ
if (status)
goto out;
status = encode_write(&xdr, args);
+ if (status)
+ goto out;
+ status = encode_getfattr(&xdr, args->bitmask);
out:
return status;
}
@@ -1734,7 +1827,7 @@ static int nfs4_xdr_enc_commit(struct rpc_rqst *req, uint32_t *p, struct nfs_wri
{
struct xdr_stream xdr;
struct compound_hdr hdr = {
- .nops = 2,
+ .nops = 3,
};
int status;
@@ -1744,6 +1837,9 @@ static int nfs4_xdr_enc_commit(struct rpc_rqst *req, uint32_t *p, struct nfs_wri
if (status)
goto out;
status = encode_commit(&xdr, args);
+ if (status)
+ goto out;
+ status = encode_getfattr(&xdr, args->bitmask);
out:
return status;
}
@@ -2670,8 +2766,7 @@ static int decode_server_caps(struct xdr_stream *xdr, struct nfs4_server_caps_re
goto xdr_error;
status = verify_attr_len(xdr, savep, attrlen);
xdr_error:
- if (status != 0)
- printk(KERN_NOTICE "%s: xdr error %d!\n", __FUNCTION__, -status);
+ dprintk("%s: xdr returned %d!\n", __FUNCTION__, -status);
return status;
}
@@ -2704,8 +2799,7 @@ static int decode_statfs(struct xdr_stream *xdr, struct nfs_fsstat *fsstat)
status = verify_attr_len(xdr, savep, attrlen);
xdr_error:
- if (status != 0)
- printk(KERN_NOTICE "%s: xdr error %d!\n", __FUNCTION__, -status);
+ dprintk("%s: xdr returned %d!\n", __FUNCTION__, -status);
return status;
}
@@ -2730,8 +2824,7 @@ static int decode_pathconf(struct xdr_stream *xdr, struct nfs_pathconf *pathconf
status = verify_attr_len(xdr, savep, attrlen);
xdr_error:
- if (status != 0)
- printk(KERN_NOTICE "%s: xdr error %d!\n", __FUNCTION__, -status);
+ dprintk("%s: xdr returned %d!\n", __FUNCTION__, -status);
return status;
}
@@ -2787,13 +2880,10 @@ static int decode_getfattr(struct xdr_stream *xdr, struct nfs_fattr *fattr, cons
goto xdr_error;
if ((status = decode_attr_time_modify(xdr, bitmap, &fattr->mtime)) != 0)
goto xdr_error;
- if ((status = verify_attr_len(xdr, savep, attrlen)) == 0) {
+ if ((status = verify_attr_len(xdr, savep, attrlen)) == 0)
fattr->valid = NFS_ATTR_FATTR | NFS_ATTR_FATTR_V3 | NFS_ATTR_FATTR_V4;
- fattr->timestamp = jiffies;
- }
xdr_error:
- if (status != 0)
- printk(KERN_NOTICE "%s: xdr error %d!\n", __FUNCTION__, -status);
+ dprintk("%s: xdr returned %d\n", __FUNCTION__, -status);
return status;
}
@@ -2826,8 +2916,7 @@ static int decode_fsinfo(struct xdr_stream *xdr, struct nfs_fsinfo *fsinfo)
status = verify_attr_len(xdr, savep, attrlen);
xdr_error:
- if (status != 0)
- printk(KERN_NOTICE "%s: xdr error %d!\n", __FUNCTION__, -status);
+ dprintk("%s: xdr returned %d!\n", __FUNCTION__, -status);
return status;
}
@@ -2890,8 +2979,8 @@ static int decode_lock(struct xdr_stream *xdr, struct nfs_lockres *res)
status = decode_op_hdr(xdr, OP_LOCK);
if (status == 0) {
- READ_BUF(sizeof(nfs4_stateid));
- COPYMEM(&res->u.stateid, sizeof(res->u.stateid));
+ READ_BUF(sizeof(res->u.stateid.data));
+ COPYMEM(res->u.stateid.data, sizeof(res->u.stateid.data));
} else if (status == -NFS4ERR_DENIED)
return decode_lock_denied(xdr, &res->u.denied);
return status;
@@ -2913,8 +3002,8 @@ static int decode_locku(struct xdr_stream *xdr, struct nfs_lockres *res)
status = decode_op_hdr(xdr, OP_LOCKU);
if (status == 0) {
- READ_BUF(sizeof(nfs4_stateid));
- COPYMEM(&res->u.stateid, sizeof(res->u.stateid));
+ READ_BUF(sizeof(res->u.stateid.data));
+ COPYMEM(res->u.stateid.data, sizeof(res->u.stateid.data));
}
return status;
}
@@ -2994,7 +3083,7 @@ static int decode_open(struct xdr_stream *xdr, struct nfs_openres *res)
p += bmlen;
return decode_delegation(xdr, res);
xdr_error:
- printk(KERN_NOTICE "%s: xdr error!\n", __FUNCTION__);
+ dprintk("%s: Bitmap too large! Length = %u\n", __FUNCTION__, bmlen);
return -EIO;
}
@@ -3208,6 +3297,12 @@ static int decode_renew(struct xdr_stream *xdr)
return decode_op_hdr(xdr, OP_RENEW);
}
+static int
+decode_restorefh(struct xdr_stream *xdr)
+{
+ return decode_op_hdr(xdr, OP_RESTOREFH);
+}
+
static int decode_getacl(struct xdr_stream *xdr, struct rpc_rqst *req,
size_t *acl_len)
{
@@ -3243,7 +3338,8 @@ static int decode_getacl(struct xdr_stream *xdr, struct rpc_rqst *req,
if (attrlen <= *acl_len)
xdr_read_pages(xdr, attrlen);
*acl_len = attrlen;
- }
+ } else
+ status = -EOPNOTSUPP;
out:
return status;
@@ -3352,6 +3448,9 @@ static int nfs4_xdr_dec_open_downgrade(struct rpc_rqst *rqstp, uint32_t *p, stru
if (status)
goto out;
status = decode_open_downgrade(&xdr, res);
+ if (status != 0)
+ goto out;
+ decode_getfattr(&xdr, res->fattr, res->server);
out:
return status;
}
@@ -3424,7 +3523,7 @@ out:
/*
* Decode REMOVE response
*/
-static int nfs4_xdr_dec_remove(struct rpc_rqst *rqstp, uint32_t *p, struct nfs4_change_info *cinfo)
+static int nfs4_xdr_dec_remove(struct rpc_rqst *rqstp, uint32_t *p, struct nfs4_remove_res *res)
{
struct xdr_stream xdr;
struct compound_hdr hdr;
@@ -3433,8 +3532,11 @@ static int nfs4_xdr_dec_remove(struct rpc_rqst *rqstp, uint32_t *p, struct nfs4_
xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
if ((status = decode_compound_hdr(&xdr, &hdr)) != 0)
goto out;
- if ((status = decode_putfh(&xdr)) == 0)
- status = decode_remove(&xdr, cinfo);
+ if ((status = decode_putfh(&xdr)) != 0)
+ goto out;
+ if ((status = decode_remove(&xdr, &res->cinfo)) != 0)
+ goto out;
+ decode_getfattr(&xdr, res->dir_attr, res->server);
out:
return status;
}
@@ -3457,7 +3559,14 @@ static int nfs4_xdr_dec_rename(struct rpc_rqst *rqstp, uint32_t *p, struct nfs4_
goto out;
if ((status = decode_putfh(&xdr)) != 0)
goto out;
- status = decode_rename(&xdr, &res->old_cinfo, &res->new_cinfo);
+ if ((status = decode_rename(&xdr, &res->old_cinfo, &res->new_cinfo)) != 0)
+ goto out;
+ /* Current FH is target directory */
+ if (decode_getfattr(&xdr, res->new_fattr, res->server) != 0)
+ goto out;
+ if ((status = decode_restorefh(&xdr)) != 0)
+ goto out;
+ decode_getfattr(&xdr, res->old_fattr, res->server);
out:
return status;
}
@@ -3465,7 +3574,7 @@ out:
/*
* Decode LINK response
*/
-static int nfs4_xdr_dec_link(struct rpc_rqst *rqstp, uint32_t *p, struct nfs4_change_info *cinfo)
+static int nfs4_xdr_dec_link(struct rpc_rqst *rqstp, uint32_t *p, struct nfs4_link_res *res)
{
struct xdr_stream xdr;
struct compound_hdr hdr;
@@ -3480,7 +3589,17 @@ static int nfs4_xdr_dec_link(struct rpc_rqst *rqstp, uint32_t *p, struct nfs4_ch
goto out;
if ((status = decode_putfh(&xdr)) != 0)
goto out;
- status = decode_link(&xdr, cinfo);
+ if ((status = decode_link(&xdr, &res->cinfo)) != 0)
+ goto out;
+ /*
+ * Note order: OP_LINK leaves the directory as the current
+ * filehandle.
+ */
+ if (decode_getfattr(&xdr, res->dir_attr, res->server) != 0)
+ goto out;
+ if ((status = decode_restorefh(&xdr)) != 0)
+ goto out;
+ decode_getfattr(&xdr, res->fattr, res->server);
out:
return status;
}
@@ -3499,13 +3618,17 @@ static int nfs4_xdr_dec_create(struct rpc_rqst *rqstp, uint32_t *p, struct nfs4_
goto out;
if ((status = decode_putfh(&xdr)) != 0)
goto out;
+ if ((status = decode_savefh(&xdr)) != 0)
+ goto out;
if ((status = decode_create(&xdr,&res->dir_cinfo)) != 0)
goto out;
if ((status = decode_getfh(&xdr, res->fh)) != 0)
goto out;
- status = decode_getfattr(&xdr, res->fattr, res->server);
- if (status == NFS4ERR_DELAY)
- status = 0;
+ if (decode_getfattr(&xdr, res->fattr, res->server) != 0)
+ goto out;
+ if ((status = decode_restorefh(&xdr)) != 0)
+ goto out;
+ decode_getfattr(&xdr, res->dir_fattr, res->server);
out:
return status;
}
@@ -3623,6 +3746,15 @@ static int nfs4_xdr_dec_close(struct rpc_rqst *rqstp, uint32_t *p, struct nfs_cl
if (status)
goto out;
status = decode_close(&xdr, res);
+ if (status != 0)
+ goto out;
+ /*
+ * Note: Server may do delete on close for this file
+ * in which case the getattr call will fail with
+ * an ESTALE error. Shouldn't be a problem,
+ * though, since fattr->valid will remain unset.
+ */
+ decode_getfattr(&xdr, res->fattr, res->server);
out:
return status;
}
@@ -3643,15 +3775,20 @@ static int nfs4_xdr_dec_open(struct rpc_rqst *rqstp, uint32_t *p, struct nfs_ope
status = decode_putfh(&xdr);
if (status)
goto out;
+ status = decode_savefh(&xdr);
+ if (status)
+ goto out;
status = decode_open(&xdr, res);
if (status)
goto out;
status = decode_getfh(&xdr, &res->fh);
if (status)
goto out;
- status = decode_getfattr(&xdr, res->f_attr, res->server);
- if (status == NFS4ERR_DELAY)
- status = 0;
+ if (decode_getfattr(&xdr, res->f_attr, res->server) != 0)
+ goto out;
+ if ((status = decode_restorefh(&xdr)) != 0)
+ goto out;
+ decode_getfattr(&xdr, res->dir_attr, res->server);
out:
return status;
}
@@ -3869,6 +4006,9 @@ static int nfs4_xdr_dec_write(struct rpc_rqst *rqstp, uint32_t *p, struct nfs_wr
if (status)
goto out;
status = decode_write(&xdr, res);
+ if (status)
+ goto out;
+ decode_getfattr(&xdr, res->fattr, res->server);
if (!status)
status = res->count;
out:
@@ -3892,6 +4032,9 @@ static int nfs4_xdr_dec_commit(struct rpc_rqst *rqstp, uint32_t *p, struct nfs_w
if (status)
goto out;
status = decode_commit(&xdr, res);
+ if (status)
+ goto out;
+ decode_getfattr(&xdr, res->fattr, res->server);
out:
return status;
}
diff --git a/fs/nfs/proc.c b/fs/nfs/proc.c
index be23c3fb9260..a48a003242c0 100644
--- a/fs/nfs/proc.c
+++ b/fs/nfs/proc.c
@@ -61,7 +61,7 @@ nfs_proc_get_root(struct nfs_server *server, struct nfs_fh *fhandle,
int status;
dprintk("%s: call getattr\n", __FUNCTION__);
- fattr->valid = 0;
+ nfs_fattr_init(fattr);
status = rpc_call(server->client_sys, NFSPROC_GETATTR, fhandle, fattr, 0);
dprintk("%s: reply getattr: %d\n", __FUNCTION__, status);
if (status)
@@ -93,7 +93,7 @@ nfs_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle,
int status;
dprintk("NFS call getattr\n");
- fattr->valid = 0;
+ nfs_fattr_init(fattr);
status = rpc_call(server->client, NFSPROC_GETATTR,
fhandle, fattr, 0);
dprintk("NFS reply getattr: %d\n", status);
@@ -112,7 +112,7 @@ nfs_proc_setattr(struct dentry *dentry, struct nfs_fattr *fattr,
int status;
dprintk("NFS call setattr\n");
- fattr->valid = 0;
+ nfs_fattr_init(fattr);
status = rpc_call(NFS_CLIENT(inode), NFSPROC_SETATTR, &arg, fattr, 0);
if (status == 0)
nfs_setattr_update_inode(inode, sattr);
@@ -136,7 +136,7 @@ nfs_proc_lookup(struct inode *dir, struct qstr *name,
int status;
dprintk("NFS call lookup %s\n", name->name);
- fattr->valid = 0;
+ nfs_fattr_init(fattr);
status = rpc_call(NFS_CLIENT(dir), NFSPROC_LOOKUP, &arg, &res, 0);
dprintk("NFS reply lookup: %d\n", status);
return status;
@@ -174,7 +174,7 @@ static int nfs_proc_read(struct nfs_read_data *rdata)
dprintk("NFS call read %d @ %Ld\n", rdata->args.count,
(long long) rdata->args.offset);
- fattr->valid = 0;
+ nfs_fattr_init(fattr);
status = rpc_call_sync(NFS_CLIENT(inode), &msg, flags);
if (status >= 0) {
nfs_refresh_inode(inode, fattr);
@@ -203,10 +203,10 @@ static int nfs_proc_write(struct nfs_write_data *wdata)
dprintk("NFS call write %d @ %Ld\n", wdata->args.count,
(long long) wdata->args.offset);
- fattr->valid = 0;
+ nfs_fattr_init(fattr);
status = rpc_call_sync(NFS_CLIENT(inode), &msg, flags);
if (status >= 0) {
- nfs_refresh_inode(inode, fattr);
+ nfs_post_op_update_inode(inode, fattr);
wdata->res.count = wdata->args.count;
wdata->verf.committed = NFS_FILE_SYNC;
}
@@ -216,7 +216,7 @@ static int nfs_proc_write(struct nfs_write_data *wdata)
static int
nfs_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
- int flags)
+ int flags, struct nameidata *nd)
{
struct nfs_fh fhandle;
struct nfs_fattr fattr;
@@ -232,7 +232,7 @@ nfs_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
};
int status;
- fattr.valid = 0;
+ nfs_fattr_init(&fattr);
dprintk("NFS call create %s\n", dentry->d_name.name);
status = rpc_call(NFS_CLIENT(dir), NFSPROC_CREATE, &arg, &res, 0);
if (status == 0)
@@ -273,12 +273,13 @@ nfs_proc_mknod(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
sattr->ia_size = new_encode_dev(rdev);/* get out your barf bag */
}
- fattr.valid = 0;
+ nfs_fattr_init(&fattr);
status = rpc_call(NFS_CLIENT(dir), NFSPROC_CREATE, &arg, &res, 0);
+ nfs_mark_for_revalidate(dir);
if (status == -EINVAL && S_ISFIFO(mode)) {
sattr->ia_mode = mode;
- fattr.valid = 0;
+ nfs_fattr_init(&fattr);
status = rpc_call(NFS_CLIENT(dir), NFSPROC_CREATE, &arg, &res, 0);
}
if (status == 0)
@@ -305,6 +306,7 @@ nfs_proc_remove(struct inode *dir, struct qstr *name)
dprintk("NFS call remove %s\n", name->name);
status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
+ nfs_mark_for_revalidate(dir);
dprintk("NFS reply remove: %d\n", status);
return status;
@@ -331,8 +333,10 @@ nfs_proc_unlink_done(struct dentry *dir, struct rpc_task *task)
{
struct rpc_message *msg = &task->tk_msg;
- if (msg->rpc_argp)
+ if (msg->rpc_argp) {
+ nfs_mark_for_revalidate(dir->d_inode);
kfree(msg->rpc_argp);
+ }
return 0;
}
@@ -352,6 +356,8 @@ nfs_proc_rename(struct inode *old_dir, struct qstr *old_name,
dprintk("NFS call rename %s -> %s\n", old_name->name, new_name->name);
status = rpc_call(NFS_CLIENT(old_dir), NFSPROC_RENAME, &arg, NULL, 0);
+ nfs_mark_for_revalidate(old_dir);
+ nfs_mark_for_revalidate(new_dir);
dprintk("NFS reply rename: %d\n", status);
return status;
}
@@ -369,6 +375,7 @@ nfs_proc_link(struct inode *inode, struct inode *dir, struct qstr *name)
dprintk("NFS call link %s\n", name->name);
status = rpc_call(NFS_CLIENT(inode), NFSPROC_LINK, &arg, NULL, 0);
+ nfs_mark_for_revalidate(dir);
dprintk("NFS reply link: %d\n", status);
return status;
}
@@ -391,9 +398,10 @@ nfs_proc_symlink(struct inode *dir, struct qstr *name, struct qstr *path,
if (path->len > NFS2_MAXPATHLEN)
return -ENAMETOOLONG;
dprintk("NFS call symlink %s -> %s\n", name->name, path->name);
- fattr->valid = 0;
+ nfs_fattr_init(fattr);
fhandle->size = 0;
status = rpc_call(NFS_CLIENT(dir), NFSPROC_SYMLINK, &arg, NULL, 0);
+ nfs_mark_for_revalidate(dir);
dprintk("NFS reply symlink: %d\n", status);
return status;
}
@@ -416,8 +424,9 @@ nfs_proc_mkdir(struct inode *dir, struct dentry *dentry, struct iattr *sattr)
int status;
dprintk("NFS call mkdir %s\n", dentry->d_name.name);
- fattr.valid = 0;
+ nfs_fattr_init(&fattr);
status = rpc_call(NFS_CLIENT(dir), NFSPROC_MKDIR, &arg, &res, 0);
+ nfs_mark_for_revalidate(dir);
if (status == 0)
status = nfs_instantiate(dentry, &fhandle, &fattr);
dprintk("NFS reply mkdir: %d\n", status);
@@ -436,6 +445,7 @@ nfs_proc_rmdir(struct inode *dir, struct qstr *name)
dprintk("NFS call rmdir %s\n", name->name);
status = rpc_call(NFS_CLIENT(dir), NFSPROC_RMDIR, &arg, NULL, 0);
+ nfs_mark_for_revalidate(dir);
dprintk("NFS reply rmdir: %d\n", status);
return status;
}
@@ -484,7 +494,7 @@ nfs_proc_statfs(struct nfs_server *server, struct nfs_fh *fhandle,
int status;
dprintk("NFS call statfs\n");
- stat->fattr->valid = 0;
+ nfs_fattr_init(stat->fattr);
status = rpc_call(server->client, NFSPROC_STATFS, fhandle, &fsinfo, 0);
dprintk("NFS reply statfs: %d\n", status);
if (status)
@@ -507,7 +517,7 @@ nfs_proc_fsinfo(struct nfs_server *server, struct nfs_fh *fhandle,
int status;
dprintk("NFS call fsinfo\n");
- info->fattr->valid = 0;
+ nfs_fattr_init(info->fattr);
status = rpc_call(server->client, NFSPROC_STATFS, fhandle, &fsinfo, 0);
dprintk("NFS reply fsinfo: %d\n", status);
if (status)
@@ -579,7 +589,7 @@ nfs_write_done(struct rpc_task *task)
struct nfs_write_data *data = (struct nfs_write_data *) task->tk_calldata;
if (task->tk_status >= 0)
- nfs_refresh_inode(data->inode, data->res.fattr);
+ nfs_post_op_update_inode(data->inode, data->res.fattr);
nfs_writeback_done(task);
}
diff --git a/fs/nfs/read.c b/fs/nfs/read.c
index 9758ebd49905..5f20eafba8ec 100644
--- a/fs/nfs/read.c
+++ b/fs/nfs/read.c
@@ -215,6 +215,7 @@ static void nfs_read_rpcsetup(struct nfs_page *req, struct nfs_read_data *data,
data->res.fattr = &data->fattr;
data->res.count = count;
data->res.eof = 0;
+ nfs_fattr_init(&data->fattr);
NFS_PROTO(inode)->read_setup(data);
@@ -506,7 +507,7 @@ int nfs_readpage(struct file *file, struct page *page)
goto out_error;
if (file == NULL) {
- ctx = nfs_find_open_context(inode, FMODE_READ);
+ ctx = nfs_find_open_context(inode, NULL, FMODE_READ);
if (ctx == NULL)
return -EBADF;
} else
@@ -575,7 +576,7 @@ int nfs_readpages(struct file *filp, struct address_space *mapping,
nr_pages);
if (filp == NULL) {
- desc.ctx = nfs_find_open_context(inode, FMODE_READ);
+ desc.ctx = nfs_find_open_context(inode, NULL, FMODE_READ);
if (desc.ctx == NULL)
return -EBADF;
} else
diff --git a/fs/nfs/unlink.c b/fs/nfs/unlink.c
index f732541a3332..d639d172d568 100644
--- a/fs/nfs/unlink.c
+++ b/fs/nfs/unlink.c
@@ -52,8 +52,7 @@ nfs_put_unlinkdata(struct nfs_unlinkdata *data)
{
if (--data->count == 0) {
nfs_detach_unlinkdata(data);
- if (data->name.name != NULL)
- kfree(data->name.name);
+ kfree(data->name.name);
kfree(data);
}
}
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index 5130eda231d7..8f71e766cc5d 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -294,7 +294,7 @@ int nfs_writepage(struct page *page, struct writeback_control *wbc)
if (page->index >= end_index+1 || !offset)
goto out;
do_it:
- ctx = nfs_find_open_context(inode, FMODE_WRITE);
+ ctx = nfs_find_open_context(inode, NULL, FMODE_WRITE);
if (ctx == NULL) {
err = -EBADF;
goto out;
@@ -734,14 +734,14 @@ int nfs_updatepage(struct file *file, struct page *page,
unsigned int offset, unsigned int count)
{
struct nfs_open_context *ctx = (struct nfs_open_context *)file->private_data;
- struct dentry *dentry = file->f_dentry;
struct inode *inode = page->mapping->host;
struct nfs_page *req;
int status = 0;
dprintk("NFS: nfs_updatepage(%s/%s %d@%Ld)\n",
- dentry->d_parent->d_name.name, dentry->d_name.name,
- count, (long long)(page_offset(page) +offset));
+ file->f_dentry->d_parent->d_name.name,
+ file->f_dentry->d_name.name, count,
+ (long long)(page_offset(page) +offset));
if (IS_SYNC(inode)) {
status = nfs_writepage_sync(ctx, inode, page, offset, count, 0);
@@ -850,7 +850,6 @@ static void nfs_write_rpcsetup(struct nfs_page *req,
unsigned int count, unsigned int offset,
int how)
{
- struct rpc_task *task = &data->task;
struct inode *inode;
/* Set up the RPC argument and reply structs
@@ -870,6 +869,7 @@ static void nfs_write_rpcsetup(struct nfs_page *req,
data->res.fattr = &data->fattr;
data->res.count = count;
data->res.verf = &data->verf;
+ nfs_fattr_init(&data->fattr);
NFS_PROTO(inode)->write_setup(data, how);
@@ -880,7 +880,7 @@ static void nfs_write_rpcsetup(struct nfs_page *req,
data->task.tk_release = nfs_writedata_release;
dprintk("NFS: %4d initiated write call (req %s/%Ld, %u bytes @ offset %Lu)\n",
- task->tk_pid,
+ data->task.tk_pid,
inode->i_sb->s_id,
(long long)NFS_FILEID(inode),
count,
@@ -1216,7 +1216,6 @@ static void nfs_commit_release(struct rpc_task *task)
static void nfs_commit_rpcsetup(struct list_head *head,
struct nfs_write_data *data, int how)
{
- struct rpc_task *task = &data->task;
struct nfs_page *first;
struct inode *inode;
@@ -1237,6 +1236,7 @@ static void nfs_commit_rpcsetup(struct list_head *head,
data->res.count = 0;
data->res.fattr = &data->fattr;
data->res.verf = &data->verf;
+ nfs_fattr_init(&data->fattr);
NFS_PROTO(inode)->commit_setup(data, how);
@@ -1246,7 +1246,7 @@ static void nfs_commit_rpcsetup(struct list_head *head,
/* Release requests */
data->task.tk_release = nfs_commit_release;
- dprintk("NFS: %4d initiated commit call\n", task->tk_pid);
+ dprintk("NFS: %4d initiated commit call\n", data->task.tk_pid);
}
/*
diff --git a/fs/nfsd/export.c b/fs/nfsd/export.c
index 057aff745506..417ec02df44f 100644
--- a/fs/nfsd/export.c
+++ b/fs/nfsd/export.c
@@ -190,8 +190,7 @@ static int expkey_parse(struct cache_detail *cd, char *mesg, int mlen)
out:
if (dom)
auth_domain_put(dom);
- if (buf)
- kfree(buf);
+ kfree(buf);
return err;
}
@@ -428,8 +427,7 @@ static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen)
path_release(&nd);
if (dom)
auth_domain_put(dom);
- if (buf)
- kfree(buf);
+ kfree(buf);
return err;
}
diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c
index e0e134d6baba..9147b8524d05 100644
--- a/fs/nfsd/nfs3xdr.c
+++ b/fs/nfsd/nfs3xdr.c
@@ -366,7 +366,8 @@ nfs3svc_decode_writeargs(struct svc_rqst *rqstp, u32 *p,
len = args->len = ntohl(*p++);
hdr = (void*)p - rqstp->rq_arg.head[0].iov_base;
- if (rqstp->rq_arg.len < len + hdr)
+ if (rqstp->rq_arg.len < hdr ||
+ rqstp->rq_arg.len - hdr < len)
return 0;
args->vec[0].iov_base = (void*)p;
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 4c4146350236..dcd673186944 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -151,8 +151,7 @@ static u32 *read_buf(struct nfsd4_compoundargs *argp, int nbytes)
if (nbytes <= sizeof(argp->tmp))
p = argp->tmp;
else {
- if (argp->tmpp)
- kfree(argp->tmpp);
+ kfree(argp->tmpp);
p = argp->tmpp = kmalloc(nbytes, GFP_KERNEL);
if (!p)
return NULL;
@@ -2476,10 +2475,8 @@ void nfsd4_release_compoundargs(struct nfsd4_compoundargs *args)
kfree(args->ops);
args->ops = args->iops;
}
- if (args->tmpp) {
- kfree(args->tmpp);
- args->tmpp = NULL;
- }
+ kfree(args->tmpp);
+ args->tmpp = NULL;
while (args->to_free) {
struct tmpbuf *tb = args->to_free;
args->to_free = tb->next;
diff --git a/fs/nfsd/nfscache.c b/fs/nfsd/nfscache.c
index 119e4d4495b8..d852ebb538e3 100644
--- a/fs/nfsd/nfscache.c
+++ b/fs/nfsd/nfscache.c
@@ -93,8 +93,7 @@ nfsd_cache_shutdown(void)
cache_disabled = 1;
- if (hash_list)
- kfree (hash_list);
+ kfree (hash_list);
hash_list = NULL;
}
diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c
index 841c562991e8..a0871b3efeb7 100644
--- a/fs/nfsd/nfsctl.c
+++ b/fs/nfsd/nfsctl.c
@@ -23,6 +23,7 @@
#include <linux/seq_file.h>
#include <linux/pagemap.h>
#include <linux/init.h>
+#include <linux/string.h>
#include <linux/nfs.h>
#include <linux/nfsd_idmap.h>
@@ -35,6 +36,8 @@
#include <asm/uaccess.h>
+unsigned int nfsd_versbits = ~0;
+
/*
* We have a single directory with 9 nodes in it.
*/
@@ -50,8 +53,15 @@ enum {
NFSD_List,
NFSD_Fh,
NFSD_Threads,
+ NFSD_Versions,
+ /*
+ * The below MUST come last. Otherwise we leave a hole in nfsd_files[]
+ * with !CONFIG_NFSD_V4 and simple_fill_super() goes oops
+ */
+#ifdef CONFIG_NFSD_V4
NFSD_Leasetime,
NFSD_RecoveryDir,
+#endif
};
/*
@@ -66,8 +76,11 @@ static ssize_t write_getfd(struct file *file, char *buf, size_t size);
static ssize_t write_getfs(struct file *file, char *buf, size_t size);
static ssize_t write_filehandle(struct file *file, char *buf, size_t size);
static ssize_t write_threads(struct file *file, char *buf, size_t size);
+static ssize_t write_versions(struct file *file, char *buf, size_t size);
+#ifdef CONFIG_NFSD_V4
static ssize_t write_leasetime(struct file *file, char *buf, size_t size);
static ssize_t write_recoverydir(struct file *file, char *buf, size_t size);
+#endif
static ssize_t (*write_op[])(struct file *, char *, size_t) = {
[NFSD_Svc] = write_svc,
@@ -79,8 +92,11 @@ static ssize_t (*write_op[])(struct file *, char *, size_t) = {
[NFSD_Getfs] = write_getfs,
[NFSD_Fh] = write_filehandle,
[NFSD_Threads] = write_threads,
+ [NFSD_Versions] = write_versions,
+#ifdef CONFIG_NFSD_V4
[NFSD_Leasetime] = write_leasetime,
[NFSD_RecoveryDir] = write_recoverydir,
+#endif
};
static ssize_t nfsctl_transaction_write(struct file *file, const char __user *buf, size_t size, loff_t *pos)
@@ -104,9 +120,23 @@ static ssize_t nfsctl_transaction_write(struct file *file, const char __user *bu
return rv;
}
+static ssize_t nfsctl_transaction_read(struct file *file, char __user *buf, size_t size, loff_t *pos)
+{
+ if (! file->private_data) {
+ /* An attempt to read a transaction file without writing
+ * causes a 0-byte write so that the file can return
+ * state information
+ */
+ ssize_t rv = nfsctl_transaction_write(file, buf, 0, pos);
+ if (rv < 0)
+ return rv;
+ }
+ return simple_transaction_read(file, buf, size, pos);
+}
+
static struct file_operations transaction_ops = {
.write = nfsctl_transaction_write,
- .read = simple_transaction_read,
+ .read = nfsctl_transaction_read,
.release = simple_transaction_release,
};
@@ -329,6 +359,70 @@ static ssize_t write_threads(struct file *file, char *buf, size_t size)
return strlen(buf);
}
+static ssize_t write_versions(struct file *file, char *buf, size_t size)
+{
+ /*
+ * Format:
+ * [-/+]vers [-/+]vers ...
+ */
+ char *mesg = buf;
+ char *vers, sign;
+ int len, num;
+ ssize_t tlen = 0;
+ char *sep;
+
+ if (size>0) {
+ if (nfsd_serv)
+ return -EBUSY;
+ if (buf[size-1] != '\n')
+ return -EINVAL;
+ buf[size-1] = 0;
+
+ vers = mesg;
+ len = qword_get(&mesg, vers, size);
+ if (len <= 0) return -EINVAL;
+ do {
+ sign = *vers;
+ if (sign == '+' || sign == '-')
+ num = simple_strtol((vers+1), NULL, 0);
+ else
+ num = simple_strtol(vers, NULL, 0);
+ switch(num) {
+ case 2:
+ case 3:
+ case 4:
+ if (sign != '-')
+ NFSCTL_VERSET(nfsd_versbits, num);
+ else
+ NFSCTL_VERUNSET(nfsd_versbits, num);
+ break;
+ default:
+ return -EINVAL;
+ }
+ 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
+ */
+ if ((nfsd_versbits & NFSCTL_VERALL)==0)
+ nfsd_versbits = NFSCTL_VERALL;
+ }
+ /* Now write current state into reply buffer */
+ len = 0;
+ sep = "";
+ for (num=2 ; num <= 4 ; num++)
+ if (NFSCTL_VERISSET(NFSCTL_VERALL, num)) {
+ len += sprintf(buf+len, "%s%c%d", sep,
+ NFSCTL_VERISSET(nfsd_versbits, num)?'+':'-',
+ num);
+ sep = " ";
+ }
+ len += sprintf(buf+len, "\n");
+ return len;
+}
+
+#ifdef CONFIG_NFSD_V4
extern time_t nfs4_leasetime(void);
static ssize_t write_leasetime(struct file *file, char *buf, size_t size)
@@ -370,6 +464,7 @@ static ssize_t write_recoverydir(struct file *file, char *buf, size_t size)
status = nfs4_reset_recoverydir(recdir);
return strlen(buf);
}
+#endif
/*----------------------------------------------------------------------------*/
/*
@@ -389,6 +484,7 @@ static int nfsd_fill_super(struct super_block * sb, void * data, int silent)
[NFSD_List] = {"exports", &exports_operations, S_IRUGO},
[NFSD_Fh] = {"filehandle", &transaction_ops, S_IWUSR|S_IRUSR},
[NFSD_Threads] = {"threads", &transaction_ops, S_IWUSR|S_IRUSR},
+ [NFSD_Versions] = {"versions", &transaction_ops, S_IWUSR|S_IRUSR},
#ifdef CONFIG_NFSD_V4
[NFSD_Leasetime] = {"nfsv4leasetime", &transaction_ops, S_IWUSR|S_IRUSR},
[NFSD_RecoveryDir] = {"nfsv4recoverydir", &transaction_ops, S_IWUSR|S_IRUSR},
diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c
index 1697539a7171..89ed04696865 100644
--- a/fs/nfsd/nfssvc.c
+++ b/fs/nfsd/nfssvc.c
@@ -30,6 +30,7 @@
#include <linux/nfsd/nfsd.h>
#include <linux/nfsd/stats.h>
#include <linux/nfsd/cache.h>
+#include <linux/nfsd/syscall.h>
#include <linux/lockd/bind.h>
#include <linux/nfsacl.h>
@@ -52,7 +53,7 @@
extern struct svc_program nfsd_program;
static void nfsd(struct svc_rqst *rqstp);
struct timeval nfssvc_boot;
-static struct svc_serv *nfsd_serv;
+ struct svc_serv *nfsd_serv;
static atomic_t nfsd_busy;
static unsigned long nfsd_last_call;
static DEFINE_SPINLOCK(nfsd_call_lock);
@@ -63,6 +64,31 @@ struct nfsd_list {
};
static struct list_head nfsd_list = LIST_HEAD_INIT(nfsd_list);
+static struct svc_version * nfsd_version[] = {
+ [2] = &nfsd_version2,
+#if defined(CONFIG_NFSD_V3)
+ [3] = &nfsd_version3,
+#endif
+#if defined(CONFIG_NFSD_V4)
+ [4] = &nfsd_version4,
+#endif
+};
+
+#define NFSD_MINVERS 2
+#define NFSD_NRVERS (sizeof(nfsd_version)/sizeof(nfsd_version[0]))
+static struct svc_version *nfsd_versions[NFSD_NRVERS];
+
+struct svc_program nfsd_program = {
+ .pg_prog = NFS_PROGRAM, /* program number */
+ .pg_nvers = NFSD_NRVERS, /* nr of entries in nfsd_version */
+ .pg_vers = nfsd_versions, /* version table */
+ .pg_name = "nfsd", /* program name */
+ .pg_class = "nfsd", /* authentication class */
+ .pg_stats = &nfsd_svcstats, /* version table */
+ .pg_authenticate = &svc_set_client, /* export authentication */
+
+};
+
/*
* Maximum number of nfsd processes
*/
@@ -80,11 +106,12 @@ int
nfsd_svc(unsigned short port, int nrservs)
{
int error;
- int none_left;
+ int none_left, found_one, i;
struct list_head *victim;
lock_kernel();
- dprintk("nfsd: creating service\n");
+ dprintk("nfsd: creating service: vers 0x%x\n",
+ nfsd_versbits);
error = -EINVAL;
if (nrservs <= 0)
nrservs = 0;
@@ -99,6 +126,27 @@ nfsd_svc(unsigned short port, int nrservs)
if (error<0)
goto out;
if (!nfsd_serv) {
+ /*
+ * Use the nfsd_ctlbits to define which
+ * versions that will be advertised.
+ * If nfsd_ctlbits doesn't list any version,
+ * export them all.
+ */
+ found_one = 0;
+
+ for (i = NFSD_MINVERS; i < NFSD_NRVERS; i++) {
+ if (NFSCTL_VERISSET(nfsd_versbits, i)) {
+ nfsd_program.pg_vers[i] = nfsd_version[i];
+ found_one = 1;
+ } else
+ nfsd_program.pg_vers[i] = NULL;
+ }
+
+ if (!found_one) {
+ for (i = NFSD_MINVERS; i < NFSD_NRVERS; i++)
+ nfsd_program.pg_vers[i] = nfsd_version[i];
+ }
+
atomic_set(&nfsd_busy, 0);
error = -ENOMEM;
nfsd_serv = svc_create(&nfsd_program, NFSD_BUFSIZE);
@@ -379,6 +427,7 @@ static struct svc_program nfsd_acl_program = {
.pg_name = "nfsd",
.pg_class = "nfsd",
.pg_stats = &nfsd_acl_svcstats,
+ .pg_authenticate = &svc_set_client,
};
static struct svc_stat nfsd_acl_svcstats = {
@@ -389,28 +438,3 @@ static struct svc_stat nfsd_acl_svcstats = {
#else
#define nfsd_acl_program_p NULL
#endif /* defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL) */
-
-extern struct svc_version nfsd_version2, nfsd_version3, nfsd_version4;
-
-static struct svc_version * nfsd_version[] = {
- [2] = &nfsd_version2,
-#if defined(CONFIG_NFSD_V3)
- [3] = &nfsd_version3,
-#endif
-#if defined(CONFIG_NFSD_V4)
- [4] = &nfsd_version4,
-#endif
-};
-
-#define NFSD_NRVERS (sizeof(nfsd_version)/sizeof(nfsd_version[0]))
-struct svc_program nfsd_program = {
- .pg_next = nfsd_acl_program_p,
- .pg_prog = NFS_PROGRAM, /* program number */
- .pg_nvers = NFSD_NRVERS, /* nr of entries in nfsd_version */
- .pg_vers = nfsd_version, /* version table */
- .pg_name = "nfsd", /* program name */
- .pg_class = "nfsd", /* authentication class */
- .pg_stats = &nfsd_svcstats, /* version table */
- .pg_authenticate = &svc_set_client, /* export authentication */
-
-};
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index 4f2cd3d27566..af7c3c3074b0 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -254,12 +254,19 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap,
/* Get inode */
err = fh_verify(rqstp, fhp, ftype, accmode);
- if (err || !iap->ia_valid)
+ if (err)
goto out;
dentry = fhp->fh_dentry;
inode = dentry->d_inode;
+ /* Ignore any mode updates on symlinks */
+ if (S_ISLNK(inode->i_mode))
+ iap->ia_valid &= ~ATTR_MODE;
+
+ if (!iap->ia_valid)
+ goto out;
+
/* NFSv2 does not differentiate between "set-[ac]time-to-now"
* which only requires access, and "set-[ac]time-to-X" which
* requires ownership.
diff --git a/fs/ntfs/ChangeLog b/fs/ntfs/ChangeLog
index de58579a1d0e..50a7749cfca1 100644
--- a/fs/ntfs/ChangeLog
+++ b/fs/ntfs/ChangeLog
@@ -1,18 +1,15 @@
ToDo/Notes:
- Find and fix bugs.
- - In between ntfs_prepare/commit_write, need exclusion between
- simultaneous file extensions. This is given to us by holding i_sem
- on the inode. The only places in the kernel when a file is resized
- are prepare/commit write and truncate for both of which i_sem is
- held. Just have to be careful in readpage/writepage and all other
- helpers not running under i_sem that we play nice...
- Also need to be careful with initialized_size extention in
- ntfs_prepare_write. Basically, just be _very_ careful in this code...
- UPDATE: The only things that need to be checked are read/writepage
- which do not hold i_sem. Note writepage cannot change i_size but it
- needs to cope with a concurrent i_size change, just like readpage.
- Also both need to cope with concurrent changes to the other sizes,
- i.e. initialized/allocated/compressed size, as well.
+ - The only places in the kernel where a file is resized are
+ ntfs_file_write*() and ntfs_truncate() for both of which i_sem is
+ held. Just have to be careful in read-/writepage and other helpers
+ not running under i_sem that we play nice... Also need to be careful
+ with initialized_size extension in ntfs_file_write*() and writepage.
+ UPDATE: The only things that need to be checked are the compressed
+ write and the other attribute resize/write cases like index
+ attributes, etc. For now none of these are implemented so are safe.
+ - Implement filling in of holes in aops.c::ntfs_writepage() and its
+ helpers.
- Implement mft.c::sync_mft_mirror_umount(). We currently will just
leave the volume dirty on umount if the final iput(vol->mft_ino)
causes a write of any mirrored mft records due to the mft mirror
@@ -22,6 +19,68 @@ ToDo/Notes:
- Enable the code for setting the NT4 compatibility flag when we start
making NTFS 1.2 specific modifications.
+2.1.25 - (Almost) fully implement write(2) and truncate(2).
+
+ - Change ntfs_map_runlist_nolock(), ntfs_attr_find_vcn_nolock() and
+ {__,}ntfs_cluster_free() to also take an optional attribute search
+ context as argument. This allows calling these functions with the
+ mft record mapped. Update all callers.
+ - Fix potential deadlock in ntfs_mft_data_extend_allocation_nolock()
+ error handling by passing in the active search context when calling
+ ntfs_cluster_free().
+ - Change ntfs_cluster_alloc() to take an extra boolean parameter
+ specifying whether the cluster are being allocated to extend an
+ attribute or to fill a hole.
+ - Change ntfs_attr_make_non_resident() to call ntfs_cluster_alloc()
+ with @is_extension set to TRUE and remove the runlist terminator
+ fixup code as this is now done by ntfs_cluster_alloc().
+ - Change ntfs_attr_make_non_resident to take the attribute value size
+ as an extra parameter. This is needed since we need to know the size
+ before we can map the mft record and our callers always know it. The
+ reason we cannot simply read the size from the vfs inode i_size is
+ that this is not necessarily uptodate. This happens when
+ ntfs_attr_make_non_resident() is called in the ->truncate call path.
+ - Fix ntfs_attr_make_non_resident() to update the vfs inode i_blocks
+ which is zero for a resident attribute but should no longer be zero
+ once the attribute is non-resident as it then has real clusters
+ allocated.
+ - Add fs/ntfs/attrib.[hc]::ntfs_attr_extend_allocation(), a function to
+ extend the allocation of an attributes. Optionally, the data size,
+ but not the initialized size can be extended, too.
+ - Implement fs/ntfs/inode.[hc]::ntfs_truncate(). It only supports
+ uncompressed and unencrypted files and it never creates sparse files
+ at least for the moment (making a file sparse requires us to modify
+ its directory entries and we do not support directory operations at
+ the moment). Also, support for highly fragmented files, i.e. ones
+ whose data attribute is split across multiple extents, is severly
+ limited. When such a case is encountered, EOPNOTSUPP is returned.
+ - Enable ATTR_SIZE attribute changes in ntfs_setattr(). This completes
+ the initial implementation of file truncation. Now both open(2)ing
+ a file with the O_TRUNC flag and the {,f}truncate(2) system calls
+ will resize a file appropriately. The limitations are that only
+ uncompressed and unencrypted files are supported. Also, there is
+ only very limited support for highly fragmented files (the ones whose
+ $DATA attribute is split into multiple attribute extents).
+ - In attrib.c::ntfs_attr_set() call balance_dirty_pages_ratelimited()
+ and cond_resched() in the main loop as we could be dirtying a lot of
+ pages and this ensures we play nice with the VM and the system as a
+ whole.
+ - Implement file operations ->write, ->aio_write, ->writev for regular
+ files. This replaces the old use of generic_file_write(), et al and
+ the address space operations ->prepare_write and ->commit_write.
+ This means that both sparse and non-sparse (unencrypted and
+ uncompressed) files can now be extended using the normal write(2)
+ code path. There are two limitations at present and these are that
+ we never create sparse files and that we only have limited support
+ for highly fragmented files, i.e. ones whose data attribute is split
+ across multiple extents. When such a case is encountered,
+ EOPNOTSUPP is returned.
+ - $EA attributes can be both resident and non-resident.
+ - Use %z for size_t to fix compilation warnings. (Andrew Morton)
+ - Fix compilation warnings with gcc-4.0.2 on SUSE 10.0.
+ - Document extended attribute ($EA) NEED_EA flag. (Based on libntfs
+ patch by Yura Pakhuchiy.)
+
2.1.24 - Lots of bug fixes and support more clean journal states.
- Support journals ($LogFile) which have been modified by chkdsk. This
diff --git a/fs/ntfs/Makefile b/fs/ntfs/Makefile
index 894b2b876d35..d0d45d1c853a 100644
--- a/fs/ntfs/Makefile
+++ b/fs/ntfs/Makefile
@@ -6,7 +6,7 @@ ntfs-objs := aops.o attrib.o collate.o compress.o debug.o dir.o file.o \
index.o inode.o mft.o mst.o namei.o runlist.o super.o sysctl.o \
unistr.o upcase.o
-EXTRA_CFLAGS = -DNTFS_VERSION=\"2.1.24\"
+EXTRA_CFLAGS = -DNTFS_VERSION=\"2.1.25\"
ifeq ($(CONFIG_NTFS_DEBUG),y)
EXTRA_CFLAGS += -DDEBUG
diff --git a/fs/ntfs/aops.c b/fs/ntfs/aops.c
index 5e80c07c6a4d..1c0a4315876a 100644
--- a/fs/ntfs/aops.c
+++ b/fs/ntfs/aops.c
@@ -1391,8 +1391,7 @@ retry_writepage:
if (NInoEncrypted(ni)) {
unlock_page(page);
BUG_ON(ni->type != AT_DATA);
- ntfs_debug("Denying write access to encrypted "
- "file.");
+ ntfs_debug("Denying write access to encrypted file.");
return -EACCES;
}
/* Compressed data streams are handled in compress.c. */
@@ -1508,8 +1507,8 @@ retry_writepage:
/* Zero out of bounds area in the page cache page. */
memset(kaddr + attr_len, 0, PAGE_CACHE_SIZE - attr_len);
kunmap_atomic(kaddr, KM_USER0);
- flush_dcache_mft_record_page(ctx->ntfs_ino);
flush_dcache_page(page);
+ flush_dcache_mft_record_page(ctx->ntfs_ino);
/* We are done with the page. */
end_page_writeback(page);
/* Finally, mark the mft record dirty, so it gets written back. */
@@ -1542,830 +1541,6 @@ err_out:
return err;
}
-/**
- * ntfs_prepare_nonresident_write -
- *
- */
-static int ntfs_prepare_nonresident_write(struct page *page,
- unsigned from, unsigned to)
-{
- VCN vcn;
- LCN lcn;
- s64 initialized_size;
- loff_t i_size;
- sector_t block, ablock, iblock;
- struct inode *vi;
- ntfs_inode *ni;
- ntfs_volume *vol;
- runlist_element *rl;
- struct buffer_head *bh, *head, *wait[2], **wait_bh = wait;
- unsigned long flags;
- unsigned int vcn_ofs, block_start, block_end, blocksize;
- int err;
- BOOL is_retry;
- unsigned char blocksize_bits;
-
- vi = page->mapping->host;
- ni = NTFS_I(vi);
- vol = ni->vol;
-
- ntfs_debug("Entering for inode 0x%lx, attribute type 0x%x, page index "
- "0x%lx, from = %u, to = %u.", ni->mft_no, ni->type,
- page->index, from, to);
-
- BUG_ON(!NInoNonResident(ni));
-
- blocksize_bits = vi->i_blkbits;
- blocksize = 1 << blocksize_bits;
-
- /*
- * create_empty_buffers() will create uptodate/dirty buffers if the
- * page is uptodate/dirty.
- */
- if (!page_has_buffers(page))
- create_empty_buffers(page, blocksize, 0);
- bh = head = page_buffers(page);
- if (unlikely(!bh))
- return -ENOMEM;
-
- /* The first block in the page. */
- block = (s64)page->index << (PAGE_CACHE_SHIFT - blocksize_bits);
-
- read_lock_irqsave(&ni->size_lock, flags);
- /*
- * The first out of bounds block for the allocated size. No need to
- * round up as allocated_size is in multiples of cluster size and the
- * minimum cluster size is 512 bytes, which is equal to the smallest
- * blocksize.
- */
- ablock = ni->allocated_size >> blocksize_bits;
- i_size = i_size_read(vi);
- initialized_size = ni->initialized_size;
- read_unlock_irqrestore(&ni->size_lock, flags);
-
- /* The last (fully or partially) initialized block. */
- iblock = initialized_size >> blocksize_bits;
-
- /* Loop through all the buffers in the page. */
- block_start = 0;
- rl = NULL;
- err = 0;
- do {
- block_end = block_start + blocksize;
- /*
- * If buffer @bh is outside the write, just mark it uptodate
- * if the page is uptodate and continue with the next buffer.
- */
- if (block_end <= from || block_start >= to) {
- if (PageUptodate(page)) {
- if (!buffer_uptodate(bh))
- set_buffer_uptodate(bh);
- }
- continue;
- }
- /*
- * @bh is at least partially being written to.
- * Make sure it is not marked as new.
- */
- //if (buffer_new(bh))
- // clear_buffer_new(bh);
-
- if (block >= ablock) {
- // TODO: block is above allocated_size, need to
- // allocate it. Best done in one go to accommodate not
- // only block but all above blocks up to and including:
- // ((page->index << PAGE_CACHE_SHIFT) + to + blocksize
- // - 1) >> blobksize_bits. Obviously will need to round
- // up to next cluster boundary, too. This should be
- // done with a helper function, so it can be reused.
- ntfs_error(vol->sb, "Writing beyond allocated size "
- "is not supported yet. Sorry.");
- err = -EOPNOTSUPP;
- goto err_out;
- // Need to update ablock.
- // Need to set_buffer_new() on all block bhs that are
- // newly allocated.
- }
- /*
- * Now we have enough allocated size to fulfill the whole
- * request, i.e. block < ablock is true.
- */
- if (unlikely((block >= iblock) &&
- (initialized_size < i_size))) {
- /*
- * If this page is fully outside initialized size, zero
- * out all pages between the current initialized size
- * and the current page. Just use ntfs_readpage() to do
- * the zeroing transparently.
- */
- if (block > iblock) {
- // TODO:
- // For each page do:
- // - read_cache_page()
- // Again for each page do:
- // - wait_on_page_locked()
- // - Check (PageUptodate(page) &&
- // !PageError(page))
- // Update initialized size in the attribute and
- // in the inode.
- // Again, for each page do:
- // __set_page_dirty_buffers();
- // page_cache_release()
- // We don't need to wait on the writes.
- // Update iblock.
- }
- /*
- * The current page straddles initialized size. Zero
- * all non-uptodate buffers and set them uptodate (and
- * dirty?). Note, there aren't any non-uptodate buffers
- * if the page is uptodate.
- * FIXME: For an uptodate page, the buffers may need to
- * be written out because they were not initialized on
- * disk before.
- */
- if (!PageUptodate(page)) {
- // TODO:
- // Zero any non-uptodate buffers up to i_size.
- // Set them uptodate and dirty.
- }
- // TODO:
- // Update initialized size in the attribute and in the
- // inode (up to i_size).
- // Update iblock.
- // FIXME: This is inefficient. Try to batch the two
- // size changes to happen in one go.
- ntfs_error(vol->sb, "Writing beyond initialized size "
- "is not supported yet. Sorry.");
- err = -EOPNOTSUPP;
- goto err_out;
- // Do NOT set_buffer_new() BUT DO clear buffer range
- // outside write request range.
- // set_buffer_uptodate() on complete buffers as well as
- // set_buffer_dirty().
- }
-
- /* Need to map unmapped buffers. */
- if (!buffer_mapped(bh)) {
- /* Unmapped buffer. Need to map it. */
- bh->b_bdev = vol->sb->s_bdev;
-
- /* Convert block into corresponding vcn and offset. */
- vcn = (VCN)block << blocksize_bits >>
- vol->cluster_size_bits;
- vcn_ofs = ((VCN)block << blocksize_bits) &
- vol->cluster_size_mask;
-
- is_retry = FALSE;
- if (!rl) {
-lock_retry_remap:
- down_read(&ni->runlist.lock);
- rl = ni->runlist.rl;
- }
- if (likely(rl != NULL)) {
- /* Seek to element containing target vcn. */
- while (rl->length && rl[1].vcn <= vcn)
- rl++;
- lcn = ntfs_rl_vcn_to_lcn(rl, vcn);
- } else
- lcn = LCN_RL_NOT_MAPPED;
- if (unlikely(lcn < 0)) {
- /*
- * We extended the attribute allocation above.
- * If we hit an ENOENT here it means that the
- * allocation was insufficient which is a bug.
- */
- BUG_ON(lcn == LCN_ENOENT);
-
- /* It is a hole, need to instantiate it. */
- if (lcn == LCN_HOLE) {
- // TODO: Instantiate the hole.
- // clear_buffer_new(bh);
- // unmap_underlying_metadata(bh->b_bdev,
- // bh->b_blocknr);
- // For non-uptodate buffers, need to
- // zero out the region outside the
- // request in this bh or all bhs,
- // depending on what we implemented
- // above.
- // Need to flush_dcache_page().
- // Or could use set_buffer_new()
- // instead?
- ntfs_error(vol->sb, "Writing into "
- "sparse regions is "
- "not supported yet. "
- "Sorry.");
- err = -EOPNOTSUPP;
- if (!rl)
- up_read(&ni->runlist.lock);
- goto err_out;
- } else if (!is_retry &&
- lcn == LCN_RL_NOT_MAPPED) {
- is_retry = TRUE;
- /*
- * Attempt to map runlist, dropping
- * lock for the duration.
- */
- up_read(&ni->runlist.lock);
- err = ntfs_map_runlist(ni, vcn);
- if (likely(!err))
- goto lock_retry_remap;
- rl = NULL;
- } else if (!rl)
- up_read(&ni->runlist.lock);
- /*
- * Failed to map the buffer, even after
- * retrying.
- */
- if (!err)
- err = -EIO;
- bh->b_blocknr = -1;
- ntfs_error(vol->sb, "Failed to write to inode "
- "0x%lx, attribute type 0x%x, "
- "vcn 0x%llx, offset 0x%x "
- "because its location on disk "
- "could not be determined%s "
- "(error code %i).",
- ni->mft_no, ni->type,
- (unsigned long long)vcn,
- vcn_ofs, is_retry ? " even "
- "after retrying" : "", err);
- goto err_out;
- }
- /* We now have a successful remap, i.e. lcn >= 0. */
-
- /* Setup buffer head to correct block. */
- bh->b_blocknr = ((lcn << vol->cluster_size_bits)
- + vcn_ofs) >> blocksize_bits;
- set_buffer_mapped(bh);
-
- // FIXME: Something analogous to this is needed for
- // each newly allocated block, i.e. BH_New.
- // FIXME: Might need to take this out of the
- // if (!buffer_mapped(bh)) {}, depending on how we
- // implement things during the allocated_size and
- // initialized_size extension code above.
- if (buffer_new(bh)) {
- clear_buffer_new(bh);
- unmap_underlying_metadata(bh->b_bdev,
- bh->b_blocknr);
- if (PageUptodate(page)) {
- set_buffer_uptodate(bh);
- continue;
- }
- /*
- * Page is _not_ uptodate, zero surrounding
- * region. NOTE: This is how we decide if to
- * zero or not!
- */
- if (block_end > to || block_start < from) {
- void *kaddr;
-
- kaddr = kmap_atomic(page, KM_USER0);
- if (block_end > to)
- memset(kaddr + to, 0,
- block_end - to);
- if (block_start < from)
- memset(kaddr + block_start, 0,
- from -
- block_start);
- flush_dcache_page(page);
- kunmap_atomic(kaddr, KM_USER0);
- }
- continue;
- }
- }
- /* @bh is mapped, set it uptodate if the page is uptodate. */
- if (PageUptodate(page)) {
- if (!buffer_uptodate(bh))
- set_buffer_uptodate(bh);
- continue;
- }
- /*
- * The page is not uptodate. The buffer is mapped. If it is not
- * uptodate, and it is only partially being written to, we need
- * to read the buffer in before the write, i.e. right now.
- */
- if (!buffer_uptodate(bh) &&
- (block_start < from || block_end > to)) {
- ll_rw_block(READ, 1, &bh);
- *wait_bh++ = bh;
- }
- } while (block++, block_start = block_end,
- (bh = bh->b_this_page) != head);
-
- /* Release the lock if we took it. */
- if (rl) {
- up_read(&ni->runlist.lock);
- rl = NULL;
- }
-
- /* If we issued read requests, let them complete. */
- while (wait_bh > wait) {
- wait_on_buffer(*--wait_bh);
- if (!buffer_uptodate(*wait_bh))
- return -EIO;
- }
-
- ntfs_debug("Done.");
- return 0;
-err_out:
- /*
- * Zero out any newly allocated blocks to avoid exposing stale data.
- * If BH_New is set, we know that the block was newly allocated in the
- * above loop.
- * FIXME: What about initialized_size increments? Have we done all the
- * required zeroing above? If not this error handling is broken, and
- * in particular the if (block_end <= from) check is completely bogus.
- */
- bh = head;
- block_start = 0;
- is_retry = FALSE;
- do {
- block_end = block_start + blocksize;
- if (block_end <= from)
- continue;
- if (block_start >= to)
- break;
- if (buffer_new(bh)) {
- void *kaddr;
-
- clear_buffer_new(bh);
- kaddr = kmap_atomic(page, KM_USER0);
- memset(kaddr + block_start, 0, bh->b_size);
- kunmap_atomic(kaddr, KM_USER0);
- set_buffer_uptodate(bh);
- mark_buffer_dirty(bh);
- is_retry = TRUE;
- }
- } while (block_start = block_end, (bh = bh->b_this_page) != head);
- if (is_retry)
- flush_dcache_page(page);
- if (rl)
- up_read(&ni->runlist.lock);
- return err;
-}
-
-/**
- * ntfs_prepare_write - prepare a page for receiving data
- *
- * This is called from generic_file_write() with i_sem held on the inode
- * (@page->mapping->host). The @page is locked but not kmap()ped. The source
- * data has not yet been copied into the @page.
- *
- * Need to extend the attribute/fill in holes if necessary, create blocks and
- * make partially overwritten blocks uptodate,
- *
- * i_size is not to be modified yet.
- *
- * Return 0 on success or -errno on error.
- *
- * Should be using block_prepare_write() [support for sparse files] or
- * cont_prepare_write() [no support for sparse files]. Cannot do that due to
- * ntfs specifics but can look at them for implementation guidance.
- *
- * Note: In the range, @from is inclusive and @to is exclusive, i.e. @from is
- * the first byte in the page that will be written to and @to is the first byte
- * after the last byte that will be written to.
- */
-static int ntfs_prepare_write(struct file *file, struct page *page,
- unsigned from, unsigned to)
-{
- s64 new_size;
- loff_t i_size;
- struct inode *vi = page->mapping->host;
- ntfs_inode *base_ni = NULL, *ni = NTFS_I(vi);
- ntfs_volume *vol = ni->vol;
- ntfs_attr_search_ctx *ctx = NULL;
- MFT_RECORD *m = NULL;
- ATTR_RECORD *a;
- u8 *kaddr;
- u32 attr_len;
- int err;
-
- ntfs_debug("Entering for inode 0x%lx, attribute type 0x%x, page index "
- "0x%lx, from = %u, to = %u.", vi->i_ino, ni->type,
- page->index, from, to);
- BUG_ON(!PageLocked(page));
- BUG_ON(from > PAGE_CACHE_SIZE);
- BUG_ON(to > PAGE_CACHE_SIZE);
- BUG_ON(from > to);
- BUG_ON(NInoMstProtected(ni));
- /*
- * If a previous ntfs_truncate() failed, repeat it and abort if it
- * fails again.
- */
- if (unlikely(NInoTruncateFailed(ni))) {
- down_write(&vi->i_alloc_sem);
- err = ntfs_truncate(vi);
- up_write(&vi->i_alloc_sem);
- if (err || NInoTruncateFailed(ni)) {
- if (!err)
- err = -EIO;
- goto err_out;
- }
- }
- /* If the attribute is not resident, deal with it elsewhere. */
- if (NInoNonResident(ni)) {
- /*
- * Only unnamed $DATA attributes can be compressed, encrypted,
- * and/or sparse.
- */
- if (ni->type == AT_DATA && !ni->name_len) {
- /* If file is encrypted, deny access, just like NT4. */
- if (NInoEncrypted(ni)) {
- ntfs_debug("Denying write access to encrypted "
- "file.");
- return -EACCES;
- }
- /* Compressed data streams are handled in compress.c. */
- if (NInoCompressed(ni)) {
- // TODO: Implement and replace this check with
- // return ntfs_write_compressed_block(page);
- ntfs_error(vi->i_sb, "Writing to compressed "
- "files is not supported yet. "
- "Sorry.");
- return -EOPNOTSUPP;
- }
- // TODO: Implement and remove this check.
- if (NInoSparse(ni)) {
- ntfs_error(vi->i_sb, "Writing to sparse files "
- "is not supported yet. Sorry.");
- return -EOPNOTSUPP;
- }
- }
- /* Normal data stream. */
- return ntfs_prepare_nonresident_write(page, from, to);
- }
- /*
- * Attribute is resident, implying it is not compressed, encrypted, or
- * sparse.
- */
- BUG_ON(page_has_buffers(page));
- new_size = ((s64)page->index << PAGE_CACHE_SHIFT) + to;
- /* If we do not need to resize the attribute allocation we are done. */
- if (new_size <= i_size_read(vi))
- goto done;
- /* Map, pin, and lock the (base) mft record. */
- if (!NInoAttr(ni))
- base_ni = ni;
- else
- base_ni = ni->ext.base_ntfs_ino;
- m = map_mft_record(base_ni);
- if (IS_ERR(m)) {
- err = PTR_ERR(m);
- m = NULL;
- ctx = NULL;
- goto err_out;
- }
- ctx = ntfs_attr_get_search_ctx(base_ni, m);
- if (unlikely(!ctx)) {
- err = -ENOMEM;
- goto err_out;
- }
- err = ntfs_attr_lookup(ni->type, ni->name, ni->name_len,
- CASE_SENSITIVE, 0, NULL, 0, ctx);
- if (unlikely(err)) {
- if (err == -ENOENT)
- err = -EIO;
- goto err_out;
- }
- m = ctx->mrec;
- a = ctx->attr;
- /* The total length of the attribute value. */
- attr_len = le32_to_cpu(a->data.resident.value_length);
- /* Fix an eventual previous failure of ntfs_commit_write(). */
- i_size = i_size_read(vi);
- if (unlikely(attr_len > i_size)) {
- attr_len = i_size;
- a->data.resident.value_length = cpu_to_le32(attr_len);
- }
- /* If we do not need to resize the attribute allocation we are done. */
- if (new_size <= attr_len)
- goto done_unm;
- /* Check if new size is allowed in $AttrDef. */
- err = ntfs_attr_size_bounds_check(vol, ni->type, new_size);
- if (unlikely(err)) {
- if (err == -ERANGE) {
- ntfs_error(vol->sb, "Write would cause the inode "
- "0x%lx to exceed the maximum size for "
- "its attribute type (0x%x). Aborting "
- "write.", vi->i_ino,
- le32_to_cpu(ni->type));
- } else {
- ntfs_error(vol->sb, "Inode 0x%lx has unknown "
- "attribute type 0x%x. Aborting "
- "write.", vi->i_ino,
- le32_to_cpu(ni->type));
- err = -EIO;
- }
- goto err_out2;
- }
- /*
- * Extend the attribute record to be able to store the new attribute
- * size.
- */
- if (new_size >= vol->mft_record_size || ntfs_attr_record_resize(m, a,
- le16_to_cpu(a->data.resident.value_offset) +
- new_size)) {
- /* Not enough space in the mft record. */
- ntfs_error(vol->sb, "Not enough space in the mft record for "
- "the resized attribute value. This is not "
- "supported yet. Aborting write.");
- err = -EOPNOTSUPP;
- goto err_out2;
- }
- /*
- * We have enough space in the mft record to fit the write. This
- * implies the attribute is smaller than the mft record and hence the
- * attribute must be in a single page and hence page->index must be 0.
- */
- BUG_ON(page->index);
- /*
- * If the beginning of the write is past the old size, enlarge the
- * attribute value up to the beginning of the write and fill it with
- * zeroes.
- */
- if (from > attr_len) {
- memset((u8*)a + le16_to_cpu(a->data.resident.value_offset) +
- attr_len, 0, from - attr_len);
- a->data.resident.value_length = cpu_to_le32(from);
- /* Zero the corresponding area in the page as well. */
- if (PageUptodate(page)) {
- kaddr = kmap_atomic(page, KM_USER0);
- memset(kaddr + attr_len, 0, from - attr_len);
- kunmap_atomic(kaddr, KM_USER0);
- flush_dcache_page(page);
- }
- }
- flush_dcache_mft_record_page(ctx->ntfs_ino);
- mark_mft_record_dirty(ctx->ntfs_ino);
-done_unm:
- ntfs_attr_put_search_ctx(ctx);
- unmap_mft_record(base_ni);
- /*
- * Because resident attributes are handled by memcpy() to/from the
- * corresponding MFT record, and because this form of i/o is byte
- * aligned rather than block aligned, there is no need to bring the
- * page uptodate here as in the non-resident case where we need to
- * bring the buffers straddled by the write uptodate before
- * generic_file_write() does the copying from userspace.
- *
- * We thus defer the uptodate bringing of the page region outside the
- * region written to to ntfs_commit_write(), which makes the code
- * simpler and saves one atomic kmap which is good.
- */
-done:
- ntfs_debug("Done.");
- return 0;
-err_out:
- if (err == -ENOMEM)
- ntfs_warning(vi->i_sb, "Error allocating memory required to "
- "prepare the write.");
- else {
- ntfs_error(vi->i_sb, "Resident attribute prepare write failed "
- "with error %i.", err);
- NVolSetErrors(vol);
- make_bad_inode(vi);
- }
-err_out2:
- if (ctx)
- ntfs_attr_put_search_ctx(ctx);
- if (m)
- unmap_mft_record(base_ni);
- return err;
-}
-
-/**
- * ntfs_commit_nonresident_write -
- *
- */
-static int ntfs_commit_nonresident_write(struct page *page,
- unsigned from, unsigned to)
-{
- s64 pos = ((s64)page->index << PAGE_CACHE_SHIFT) + to;
- struct inode *vi = page->mapping->host;
- struct buffer_head *bh, *head;
- unsigned int block_start, block_end, blocksize;
- BOOL partial;
-
- ntfs_debug("Entering for inode 0x%lx, attribute type 0x%x, page index "
- "0x%lx, from = %u, to = %u.", vi->i_ino,
- NTFS_I(vi)->type, page->index, from, to);
- blocksize = 1 << vi->i_blkbits;
-
- // FIXME: We need a whole slew of special cases in here for compressed
- // files for example...
- // For now, we know ntfs_prepare_write() would have failed so we can't
- // get here in any of the cases which we have to special case, so we
- // are just a ripped off, unrolled generic_commit_write().
-
- bh = head = page_buffers(page);
- block_start = 0;
- partial = FALSE;
- do {
- block_end = block_start + blocksize;
- if (block_end <= from || block_start >= to) {
- if (!buffer_uptodate(bh))
- partial = TRUE;
- } else {
- set_buffer_uptodate(bh);
- mark_buffer_dirty(bh);
- }
- } while (block_start = block_end, (bh = bh->b_this_page) != head);
- /*
- * If this is a partial write which happened to make all buffers
- * uptodate then we can optimize away a bogus ->readpage() for the next
- * read(). Here we 'discover' whether the page went uptodate as a
- * result of this (potentially partial) write.
- */
- if (!partial)
- SetPageUptodate(page);
- /*
- * Not convinced about this at all. See disparity comment above. For
- * now we know ntfs_prepare_write() would have failed in the write
- * exceeds i_size case, so this will never trigger which is fine.
- */
- if (pos > i_size_read(vi)) {
- ntfs_error(vi->i_sb, "Writing beyond the existing file size is "
- "not supported yet. Sorry.");
- return -EOPNOTSUPP;
- // vi->i_size = pos;
- // mark_inode_dirty(vi);
- }
- ntfs_debug("Done.");
- return 0;
-}
-
-/**
- * ntfs_commit_write - commit the received data
- *
- * This is called from generic_file_write() with i_sem held on the inode
- * (@page->mapping->host). The @page is locked but not kmap()ped. The source
- * data has already been copied into the @page. ntfs_prepare_write() has been
- * called before the data copied and it returned success so we can take the
- * results of various BUG checks and some error handling for granted.
- *
- * Need to mark modified blocks dirty so they get written out later when
- * ntfs_writepage() is invoked by the VM.
- *
- * Return 0 on success or -errno on error.
- *
- * Should be using generic_commit_write(). This marks buffers uptodate and
- * dirty, sets the page uptodate if all buffers in the page are uptodate, and
- * updates i_size if the end of io is beyond i_size. In that case, it also
- * marks the inode dirty.
- *
- * Cannot use generic_commit_write() due to ntfs specialities but can look at
- * it for implementation guidance.
- *
- * If things have gone as outlined in ntfs_prepare_write(), then we do not
- * need to do any page content modifications here at all, except in the write
- * to resident attribute case, where we need to do the uptodate bringing here
- * which we combine with the copying into the mft record which means we save
- * one atomic kmap.
- */
-static int ntfs_commit_write(struct file *file, struct page *page,
- unsigned from, unsigned to)
-{
- struct inode *vi = page->mapping->host;
- ntfs_inode *base_ni, *ni = NTFS_I(vi);
- char *kaddr, *kattr;
- ntfs_attr_search_ctx *ctx;
- MFT_RECORD *m;
- ATTR_RECORD *a;
- u32 attr_len;
- int err;
-
- ntfs_debug("Entering for inode 0x%lx, attribute type 0x%x, page index "
- "0x%lx, from = %u, to = %u.", vi->i_ino, ni->type,
- page->index, from, to);
- /* If the attribute is not resident, deal with it elsewhere. */
- if (NInoNonResident(ni)) {
- /* Only unnamed $DATA attributes can be compressed/encrypted. */
- if (ni->type == AT_DATA && !ni->name_len) {
- /* Encrypted files need separate handling. */
- if (NInoEncrypted(ni)) {
- // We never get here at present!
- BUG();
- }
- /* Compressed data streams are handled in compress.c. */
- if (NInoCompressed(ni)) {
- // TODO: Implement this!
- // return ntfs_write_compressed_block(page);
- // We never get here at present!
- BUG();
- }
- }
- /* Normal data stream. */
- return ntfs_commit_nonresident_write(page, from, to);
- }
- /*
- * Attribute is resident, implying it is not compressed, encrypted, or
- * sparse.
- */
- if (!NInoAttr(ni))
- base_ni = ni;
- else
- base_ni = ni->ext.base_ntfs_ino;
- /* Map, pin, and lock the mft record. */
- m = map_mft_record(base_ni);
- if (IS_ERR(m)) {
- err = PTR_ERR(m);
- m = NULL;
- ctx = NULL;
- goto err_out;
- }
- ctx = ntfs_attr_get_search_ctx(base_ni, m);
- if (unlikely(!ctx)) {
- err = -ENOMEM;
- goto err_out;
- }
- err = ntfs_attr_lookup(ni->type, ni->name, ni->name_len,
- CASE_SENSITIVE, 0, NULL, 0, ctx);
- if (unlikely(err)) {
- if (err == -ENOENT)
- err = -EIO;
- goto err_out;
- }
- a = ctx->attr;
- /* The total length of the attribute value. */
- attr_len = le32_to_cpu(a->data.resident.value_length);
- BUG_ON(from > attr_len);
- kattr = (u8*)a + le16_to_cpu(a->data.resident.value_offset);
- kaddr = kmap_atomic(page, KM_USER0);
- /* Copy the received data from the page to the mft record. */
- memcpy(kattr + from, kaddr + from, to - from);
- /* Update the attribute length if necessary. */
- if (to > attr_len) {
- attr_len = to;
- a->data.resident.value_length = cpu_to_le32(attr_len);
- }
- /*
- * If the page is not uptodate, bring the out of bounds area(s)
- * uptodate by copying data from the mft record to the page.
- */
- if (!PageUptodate(page)) {
- if (from > 0)
- memcpy(kaddr, kattr, from);
- if (to < attr_len)
- memcpy(kaddr + to, kattr + to, attr_len - to);
- /* Zero the region outside the end of the attribute value. */
- if (attr_len < PAGE_CACHE_SIZE)
- memset(kaddr + attr_len, 0, PAGE_CACHE_SIZE - attr_len);
- /*
- * The probability of not having done any of the above is
- * extremely small, so we just flush unconditionally.
- */
- flush_dcache_page(page);
- SetPageUptodate(page);
- }
- kunmap_atomic(kaddr, KM_USER0);
- /* Update i_size if necessary. */
- if (i_size_read(vi) < attr_len) {
- unsigned long flags;
-
- write_lock_irqsave(&ni->size_lock, flags);
- ni->allocated_size = ni->initialized_size = attr_len;
- i_size_write(vi, attr_len);
- write_unlock_irqrestore(&ni->size_lock, flags);
- }
- /* Mark the mft record dirty, so it gets written back. */
- flush_dcache_mft_record_page(ctx->ntfs_ino);
- mark_mft_record_dirty(ctx->ntfs_ino);
- ntfs_attr_put_search_ctx(ctx);
- unmap_mft_record(base_ni);
- ntfs_debug("Done.");
- return 0;
-err_out:
- if (err == -ENOMEM) {
- ntfs_warning(vi->i_sb, "Error allocating memory required to "
- "commit the write.");
- if (PageUptodate(page)) {
- ntfs_warning(vi->i_sb, "Page is uptodate, setting "
- "dirty so the write will be retried "
- "later on by the VM.");
- /*
- * Put the page on mapping->dirty_pages, but leave its
- * buffers' dirty state as-is.
- */
- __set_page_dirty_nobuffers(page);
- err = 0;
- } else
- ntfs_error(vi->i_sb, "Page is not uptodate. Written "
- "data has been lost.");
- } else {
- ntfs_error(vi->i_sb, "Resident attribute commit write failed "
- "with error %i.", err);
- NVolSetErrors(ni->vol);
- make_bad_inode(vi);
- }
- if (ctx)
- ntfs_attr_put_search_ctx(ctx);
- if (m)
- unmap_mft_record(base_ni);
- return err;
-}
-
#endif /* NTFS_RW */
/**
@@ -2377,9 +1552,6 @@ struct address_space_operations ntfs_aops = {
disk request queue. */
#ifdef NTFS_RW
.writepage = ntfs_writepage, /* Write dirty page to disk. */
- .prepare_write = ntfs_prepare_write, /* Prepare page and buffers
- ready to receive data. */
- .commit_write = ntfs_commit_write, /* Commit received data. */
#endif /* NTFS_RW */
};
diff --git a/fs/ntfs/attrib.c b/fs/ntfs/attrib.c
index 3f9a4ff42ee5..eda056bac256 100644
--- a/fs/ntfs/attrib.c
+++ b/fs/ntfs/attrib.c
@@ -21,7 +21,9 @@
*/
#include <linux/buffer_head.h>
+#include <linux/sched.h>
#include <linux/swap.h>
+#include <linux/writeback.h>
#include "attrib.h"
#include "debug.h"
@@ -36,9 +38,27 @@
* ntfs_map_runlist_nolock - map (a part of) a runlist of an ntfs inode
* @ni: ntfs inode for which to map (part of) a runlist
* @vcn: map runlist part containing this vcn
+ * @ctx: active attribute search context if present or NULL if not
*
* Map the part of a runlist containing the @vcn of the ntfs inode @ni.
*
+ * If @ctx is specified, it is an active search context of @ni and its base mft
+ * record. This is needed when ntfs_map_runlist_nolock() encounters unmapped
+ * runlist fragments and allows their mapping. If you do not have the mft
+ * record mapped, you can specify @ctx as NULL and ntfs_map_runlist_nolock()
+ * will perform the necessary mapping and unmapping.
+ *
+ * Note, ntfs_map_runlist_nolock() saves the state of @ctx on entry and
+ * restores it before returning. Thus, @ctx will be left pointing to the same
+ * attribute on return as on entry. However, the actual pointers in @ctx may
+ * point to different memory locations on return, so you must remember to reset
+ * any cached pointers from the @ctx, i.e. after the call to
+ * ntfs_map_runlist_nolock(), you will probably want to do:
+ * m = ctx->mrec;
+ * a = ctx->attr;
+ * Assuming you cache ctx->attr in a variable @a of type ATTR_RECORD * and that
+ * you cache ctx->mrec in a variable @m of type MFT_RECORD *.
+ *
* Return 0 on success and -errno on error. There is one special error code
* which is not an error as such. This is -ENOENT. It means that @vcn is out
* of bounds of the runlist.
@@ -46,19 +66,32 @@
* Note the runlist can be NULL after this function returns if @vcn is zero and
* the attribute has zero allocated size, i.e. there simply is no runlist.
*
- * Locking: - The runlist must be locked for writing.
- * - This function modifies the runlist.
+ * WARNING: If @ctx is supplied, regardless of whether success or failure is
+ * returned, you need to check IS_ERR(@ctx->mrec) and if TRUE the @ctx
+ * is no longer valid, i.e. you need to either call
+ * ntfs_attr_reinit_search_ctx() or ntfs_attr_put_search_ctx() on it.
+ * In that case PTR_ERR(@ctx->mrec) will give you the error code for
+ * why the mapping of the old inode failed.
+ *
+ * Locking: - The runlist described by @ni must be locked for writing on entry
+ * and is locked on return. Note the runlist will be modified.
+ * - If @ctx is NULL, the base mft record of @ni must not be mapped on
+ * entry and it will be left unmapped on return.
+ * - If @ctx is not NULL, the base mft record must be mapped on entry
+ * and it will be left mapped on return.
*/
-int ntfs_map_runlist_nolock(ntfs_inode *ni, VCN vcn)
+int ntfs_map_runlist_nolock(ntfs_inode *ni, VCN vcn, ntfs_attr_search_ctx *ctx)
{
VCN end_vcn;
+ unsigned long flags;
ntfs_inode *base_ni;
MFT_RECORD *m;
ATTR_RECORD *a;
- ntfs_attr_search_ctx *ctx;
runlist_element *rl;
- unsigned long flags;
+ struct page *put_this_page = NULL;
int err = 0;
+ BOOL ctx_is_temporary, ctx_needs_reset;
+ ntfs_attr_search_ctx old_ctx = { NULL, };
ntfs_debug("Mapping runlist part containing vcn 0x%llx.",
(unsigned long long)vcn);
@@ -66,20 +99,77 @@ int ntfs_map_runlist_nolock(ntfs_inode *ni, VCN vcn)
base_ni = ni;
else
base_ni = ni->ext.base_ntfs_ino;
- m = map_mft_record(base_ni);
- if (IS_ERR(m))
- return PTR_ERR(m);
- ctx = ntfs_attr_get_search_ctx(base_ni, m);
- if (unlikely(!ctx)) {
- err = -ENOMEM;
- goto err_out;
+ if (!ctx) {
+ ctx_is_temporary = ctx_needs_reset = TRUE;
+ m = map_mft_record(base_ni);
+ if (IS_ERR(m))
+ return PTR_ERR(m);
+ ctx = ntfs_attr_get_search_ctx(base_ni, m);
+ if (unlikely(!ctx)) {
+ err = -ENOMEM;
+ goto err_out;
+ }
+ } else {
+ VCN allocated_size_vcn;
+
+ BUG_ON(IS_ERR(ctx->mrec));
+ a = ctx->attr;
+ BUG_ON(!a->non_resident);
+ ctx_is_temporary = FALSE;
+ end_vcn = sle64_to_cpu(a->data.non_resident.highest_vcn);
+ read_lock_irqsave(&ni->size_lock, flags);
+ allocated_size_vcn = ni->allocated_size >>
+ ni->vol->cluster_size_bits;
+ read_unlock_irqrestore(&ni->size_lock, flags);
+ if (!a->data.non_resident.lowest_vcn && end_vcn <= 0)
+ end_vcn = allocated_size_vcn - 1;
+ /*
+ * If we already have the attribute extent containing @vcn in
+ * @ctx, no need to look it up again. We slightly cheat in
+ * that if vcn exceeds the allocated size, we will refuse to
+ * map the runlist below, so there is definitely no need to get
+ * the right attribute extent.
+ */
+ if (vcn >= allocated_size_vcn || (a->type == ni->type &&
+ a->name_length == ni->name_len &&
+ !memcmp((u8*)a + le16_to_cpu(a->name_offset),
+ ni->name, ni->name_len) &&
+ sle64_to_cpu(a->data.non_resident.lowest_vcn)
+ <= vcn && end_vcn >= vcn))
+ ctx_needs_reset = FALSE;
+ else {
+ /* Save the old search context. */
+ old_ctx = *ctx;
+ /*
+ * If the currently mapped (extent) inode is not the
+ * base inode we will unmap it when we reinitialize the
+ * search context which means we need to get a
+ * reference to the page containing the mapped mft
+ * record so we do not accidentally drop changes to the
+ * mft record when it has not been marked dirty yet.
+ */
+ if (old_ctx.base_ntfs_ino && old_ctx.ntfs_ino !=
+ old_ctx.base_ntfs_ino) {
+ put_this_page = old_ctx.ntfs_ino->page;
+ page_cache_get(put_this_page);
+ }
+ /*
+ * Reinitialize the search context so we can lookup the
+ * needed attribute extent.
+ */
+ ntfs_attr_reinit_search_ctx(ctx);
+ ctx_needs_reset = TRUE;
+ }
}
- err = ntfs_attr_lookup(ni->type, ni->name, ni->name_len,
- CASE_SENSITIVE, vcn, NULL, 0, ctx);
- if (unlikely(err)) {
- if (err == -ENOENT)
- err = -EIO;
- goto err_out;
+ if (ctx_needs_reset) {
+ err = ntfs_attr_lookup(ni->type, ni->name, ni->name_len,
+ CASE_SENSITIVE, vcn, NULL, 0, ctx);
+ if (unlikely(err)) {
+ if (err == -ENOENT)
+ err = -EIO;
+ goto err_out;
+ }
+ BUG_ON(!ctx->attr->non_resident);
}
a = ctx->attr;
/*
@@ -89,11 +179,9 @@ int ntfs_map_runlist_nolock(ntfs_inode *ni, VCN vcn)
* ntfs_mapping_pairs_decompress() fails.
*/
end_vcn = sle64_to_cpu(a->data.non_resident.highest_vcn) + 1;
- if (unlikely(!a->data.non_resident.lowest_vcn && end_vcn <= 1)) {
- read_lock_irqsave(&ni->size_lock, flags);
- end_vcn = ni->allocated_size >> ni->vol->cluster_size_bits;
- read_unlock_irqrestore(&ni->size_lock, flags);
- }
+ if (!a->data.non_resident.lowest_vcn && end_vcn == 1)
+ end_vcn = sle64_to_cpu(a->data.non_resident.allocated_size) >>
+ ni->vol->cluster_size_bits;
if (unlikely(vcn >= end_vcn)) {
err = -ENOENT;
goto err_out;
@@ -104,9 +192,93 @@ int ntfs_map_runlist_nolock(ntfs_inode *ni, VCN vcn)
else
ni->runlist.rl = rl;
err_out:
- if (likely(ctx))
- ntfs_attr_put_search_ctx(ctx);
- unmap_mft_record(base_ni);
+ if (ctx_is_temporary) {
+ if (likely(ctx))
+ ntfs_attr_put_search_ctx(ctx);
+ unmap_mft_record(base_ni);
+ } else if (ctx_needs_reset) {
+ /*
+ * If there is no attribute list, restoring the search context
+ * is acomplished simply by copying the saved context back over
+ * the caller supplied context. If there is an attribute list,
+ * things are more complicated as we need to deal with mapping
+ * of mft records and resulting potential changes in pointers.
+ */
+ if (NInoAttrList(base_ni)) {
+ /*
+ * If the currently mapped (extent) inode is not the
+ * one we had before, we need to unmap it and map the
+ * old one.
+ */
+ if (ctx->ntfs_ino != old_ctx.ntfs_ino) {
+ /*
+ * If the currently mapped inode is not the
+ * base inode, unmap it.
+ */
+ if (ctx->base_ntfs_ino && ctx->ntfs_ino !=
+ ctx->base_ntfs_ino) {
+ unmap_extent_mft_record(ctx->ntfs_ino);
+ ctx->mrec = ctx->base_mrec;
+ BUG_ON(!ctx->mrec);
+ }
+ /*
+ * If the old mapped inode is not the base
+ * inode, map it.
+ */
+ if (old_ctx.base_ntfs_ino &&
+ old_ctx.ntfs_ino !=
+ old_ctx.base_ntfs_ino) {
+retry_map:
+ ctx->mrec = map_mft_record(
+ old_ctx.ntfs_ino);
+ /*
+ * Something bad has happened. If out
+ * of memory retry till it succeeds.
+ * Any other errors are fatal and we
+ * return the error code in ctx->mrec.
+ * Let the caller deal with it... We
+ * just need to fudge things so the
+ * caller can reinit and/or put the
+ * search context safely.
+ */
+ if (IS_ERR(ctx->mrec)) {
+ if (PTR_ERR(ctx->mrec) ==
+ -ENOMEM) {
+ schedule();
+ goto retry_map;
+ } else
+ old_ctx.ntfs_ino =
+ old_ctx.
+ base_ntfs_ino;
+ }
+ }
+ }
+ /* Update the changed pointers in the saved context. */
+ if (ctx->mrec != old_ctx.mrec) {
+ if (!IS_ERR(ctx->mrec))
+ old_ctx.attr = (ATTR_RECORD*)(
+ (u8*)ctx->mrec +
+ ((u8*)old_ctx.attr -
+ (u8*)old_ctx.mrec));
+ old_ctx.mrec = ctx->mrec;
+ }
+ }
+ /* Restore the search context to the saved one. */
+ *ctx = old_ctx;
+ /*
+ * We drop the reference on the page we took earlier. In the
+ * case that IS_ERR(ctx->mrec) is true this means we might lose
+ * some changes to the mft record that had been made between
+ * the last time it was marked dirty/written out and now. This
+ * at this stage is not a problem as the mapping error is fatal
+ * enough that the mft record cannot be written out anyway and
+ * the caller is very likely to shutdown the whole inode
+ * immediately and mark the volume dirty for chkdsk to pick up
+ * the pieces anyway.
+ */
+ if (put_this_page)
+ page_cache_release(put_this_page);
+ }
return err;
}
@@ -122,8 +294,8 @@ err_out:
* of bounds of the runlist.
*
* Locking: - The runlist must be unlocked on entry and is unlocked on return.
- * - This function takes the runlist lock for writing and modifies the
- * runlist.
+ * - This function takes the runlist lock for writing and may modify
+ * the runlist.
*/
int ntfs_map_runlist(ntfs_inode *ni, VCN vcn)
{
@@ -133,7 +305,7 @@ int ntfs_map_runlist(ntfs_inode *ni, VCN vcn)
/* Make sure someone else didn't do the work while we were sleeping. */
if (likely(ntfs_rl_vcn_to_lcn(ni->runlist.rl, vcn) <=
LCN_RL_NOT_MAPPED))
- err = ntfs_map_runlist_nolock(ni, vcn);
+ err = ntfs_map_runlist_nolock(ni, vcn, NULL);
up_write(&ni->runlist.lock);
return err;
}
@@ -212,7 +384,7 @@ retry_remap:
goto retry_remap;
}
}
- err = ntfs_map_runlist_nolock(ni, vcn);
+ err = ntfs_map_runlist_nolock(ni, vcn, NULL);
if (!write_locked) {
up_write(&ni->runlist.lock);
down_read(&ni->runlist.lock);
@@ -236,9 +408,9 @@ retry_remap:
/**
* ntfs_attr_find_vcn_nolock - find a vcn in the runlist of an ntfs inode
- * @ni: ntfs inode describing the runlist to search
- * @vcn: vcn to find
- * @write_locked: true if the runlist is locked for writing
+ * @ni: ntfs inode describing the runlist to search
+ * @vcn: vcn to find
+ * @ctx: active attribute search context if present or NULL if not
*
* Find the virtual cluster number @vcn in the runlist described by the ntfs
* inode @ni and return the address of the runlist element containing the @vcn.
@@ -246,9 +418,22 @@ retry_remap:
* If the @vcn is not mapped yet, the attempt is made to map the attribute
* extent containing the @vcn and the vcn to lcn conversion is retried.
*
- * If @write_locked is true the caller has locked the runlist for writing and
- * if false for reading.
- *
+ * If @ctx is specified, it is an active search context of @ni and its base mft
+ * record. This is needed when ntfs_attr_find_vcn_nolock() encounters unmapped
+ * runlist fragments and allows their mapping. If you do not have the mft
+ * record mapped, you can specify @ctx as NULL and ntfs_attr_find_vcn_nolock()
+ * will perform the necessary mapping and unmapping.
+ *
+ * Note, ntfs_attr_find_vcn_nolock() saves the state of @ctx on entry and
+ * restores it before returning. Thus, @ctx will be left pointing to the same
+ * attribute on return as on entry. However, the actual pointers in @ctx may
+ * point to different memory locations on return, so you must remember to reset
+ * any cached pointers from the @ctx, i.e. after the call to
+ * ntfs_attr_find_vcn_nolock(), you will probably want to do:
+ * m = ctx->mrec;
+ * a = ctx->attr;
+ * Assuming you cache ctx->attr in a variable @a of type ATTR_RECORD * and that
+ * you cache ctx->mrec in a variable @m of type MFT_RECORD *.
* Note you need to distinguish between the lcn of the returned runlist element
* being >= 0 and LCN_HOLE. In the later case you have to return zeroes on
* read and allocate clusters on write.
@@ -263,22 +448,31 @@ retry_remap:
* -ENOMEM - Not enough memory to map runlist.
* -EIO - Critical error (runlist/file is corrupt, i/o error, etc).
*
- * Locking: - The runlist must be locked on entry and is left locked on return.
- * - If @write_locked is FALSE, i.e. the runlist is locked for reading,
- * the lock may be dropped inside the function so you cannot rely on
- * the runlist still being the same when this function returns.
+ * WARNING: If @ctx is supplied, regardless of whether success or failure is
+ * returned, you need to check IS_ERR(@ctx->mrec) and if TRUE the @ctx
+ * is no longer valid, i.e. you need to either call
+ * ntfs_attr_reinit_search_ctx() or ntfs_attr_put_search_ctx() on it.
+ * In that case PTR_ERR(@ctx->mrec) will give you the error code for
+ * why the mapping of the old inode failed.
+ *
+ * Locking: - The runlist described by @ni must be locked for writing on entry
+ * and is locked on return. Note the runlist may be modified when
+ * needed runlist fragments need to be mapped.
+ * - If @ctx is NULL, the base mft record of @ni must not be mapped on
+ * entry and it will be left unmapped on return.
+ * - If @ctx is not NULL, the base mft record must be mapped on entry
+ * and it will be left mapped on return.
*/
runlist_element *ntfs_attr_find_vcn_nolock(ntfs_inode *ni, const VCN vcn,
- const BOOL write_locked)
+ ntfs_attr_search_ctx *ctx)
{
unsigned long flags;
runlist_element *rl;
int err = 0;
BOOL is_retry = FALSE;
- ntfs_debug("Entering for i_ino 0x%lx, vcn 0x%llx, %s_locked.",
- ni->mft_no, (unsigned long long)vcn,
- write_locked ? "write" : "read");
+ ntfs_debug("Entering for i_ino 0x%lx, vcn 0x%llx, with%s ctx.",
+ ni->mft_no, (unsigned long long)vcn, ctx ? "" : "out");
BUG_ON(!ni);
BUG_ON(!NInoNonResident(ni));
BUG_ON(vcn < 0);
@@ -312,33 +506,22 @@ retry_remap:
}
if (!err && !is_retry) {
/*
- * The @vcn is in an unmapped region, map the runlist and
- * retry.
+ * If the search context is invalid we cannot map the unmapped
+ * region.
*/
- if (!write_locked) {
- up_read(&ni->runlist.lock);
- down_write(&ni->runlist.lock);
- if (unlikely(ntfs_rl_vcn_to_lcn(ni->runlist.rl, vcn) !=
- LCN_RL_NOT_MAPPED)) {
- up_write(&ni->runlist.lock);
- down_read(&ni->runlist.lock);
+ if (IS_ERR(ctx->mrec))
+ err = PTR_ERR(ctx->mrec);
+ else {
+ /*
+ * The @vcn is in an unmapped region, map the runlist
+ * and retry.
+ */
+ err = ntfs_map_runlist_nolock(ni, vcn, ctx);
+ if (likely(!err)) {
+ is_retry = TRUE;
goto retry_remap;
}
}
- err = ntfs_map_runlist_nolock(ni, vcn);
- if (!write_locked) {
- up_write(&ni->runlist.lock);
- down_read(&ni->runlist.lock);
- }
- if (likely(!err)) {
- is_retry = TRUE;
- goto retry_remap;
- }
- /*
- * -EINVAL coming from a failed mapping attempt is equivalent
- * to i/o error for us as it should not happen in our code
- * paths.
- */
if (err == -EINVAL)
err = -EIO;
} else if (!err)
@@ -1011,6 +1194,7 @@ int ntfs_attr_lookup(const ATTR_TYPE type, const ntfschar *name,
ntfs_inode *base_ni;
ntfs_debug("Entering.");
+ BUG_ON(IS_ERR(ctx->mrec));
if (ctx->base_ntfs_ino)
base_ni = ctx->base_ntfs_ino;
else
@@ -1227,7 +1411,7 @@ int ntfs_attr_can_be_non_resident(const ntfs_volume *vol, const ATTR_TYPE type)
*/
int ntfs_attr_can_be_resident(const ntfs_volume *vol, const ATTR_TYPE type)
{
- if (type == AT_INDEX_ALLOCATION || type == AT_EA)
+ if (type == AT_INDEX_ALLOCATION)
return -EPERM;
return 0;
}
@@ -1319,10 +1503,17 @@ int ntfs_resident_attr_value_resize(MFT_RECORD *m, ATTR_RECORD *a,
/**
* ntfs_attr_make_non_resident - convert a resident to a non-resident attribute
* @ni: ntfs inode describing the attribute to convert
+ * @data_size: size of the resident data to copy to the non-resident attribute
*
* Convert the resident ntfs attribute described by the ntfs inode @ni to a
* non-resident one.
*
+ * @data_size must be equal to the attribute value size. This is needed since
+ * we need to know the size before we can map the mft record and our callers
+ * always know it. The reason we cannot simply read the size from the vfs
+ * inode i_size is that this is not necessarily uptodate. This happens when
+ * ntfs_attr_make_non_resident() is called in the ->truncate call path(s).
+ *
* Return 0 on success and -errno on error. The following error return codes
* are defined:
* -EPERM - The attribute is not allowed to be non-resident.
@@ -1343,7 +1534,7 @@ int ntfs_resident_attr_value_resize(MFT_RECORD *m, ATTR_RECORD *a,
*
* Locking: - The caller must hold i_sem on the inode.
*/
-int ntfs_attr_make_non_resident(ntfs_inode *ni)
+int ntfs_attr_make_non_resident(ntfs_inode *ni, const u32 data_size)
{
s64 new_size;
struct inode *vi = VFS_I(ni);
@@ -1381,11 +1572,9 @@ int ntfs_attr_make_non_resident(ntfs_inode *ni)
* The size needs to be aligned to a cluster boundary for allocation
* purposes.
*/
- new_size = (i_size_read(vi) + vol->cluster_size - 1) &
+ new_size = (data_size + vol->cluster_size - 1) &
~(vol->cluster_size - 1);
if (new_size > 0) {
- runlist_element *rl2;
-
/*
* Will need the page later and since the page lock nests
* outside all ntfs locks, we need to get the page now.
@@ -1396,7 +1585,7 @@ int ntfs_attr_make_non_resident(ntfs_inode *ni)
return -ENOMEM;
/* Start by allocating clusters to hold the attribute value. */
rl = ntfs_cluster_alloc(vol, 0, new_size >>
- vol->cluster_size_bits, -1, DATA_ZONE);
+ vol->cluster_size_bits, -1, DATA_ZONE, TRUE);
if (IS_ERR(rl)) {
err = PTR_ERR(rl);
ntfs_debug("Failed to allocate cluster%s, error code "
@@ -1405,12 +1594,6 @@ int ntfs_attr_make_non_resident(ntfs_inode *ni)
err);
goto page_err_out;
}
- /* Change the runlist terminator to LCN_ENOENT. */
- rl2 = rl;
- while (rl2->length)
- rl2++;
- BUG_ON(rl2->lcn != LCN_RL_NOT_MAPPED);
- rl2->lcn = LCN_ENOENT;
} else {
rl = NULL;
page = NULL;
@@ -1473,7 +1656,7 @@ int ntfs_attr_make_non_resident(ntfs_inode *ni)
* attribute value.
*/
attr_size = le32_to_cpu(a->data.resident.value_length);
- BUG_ON(attr_size != i_size_read(vi));
+ BUG_ON(attr_size != data_size);
if (page && !PageUptodate(page)) {
kaddr = kmap_atomic(page, KM_USER0);
memcpy(kaddr, (u8*)a +
@@ -1538,7 +1721,9 @@ int ntfs_attr_make_non_resident(ntfs_inode *ni)
ffs(ni->itype.compressed.block_size) - 1;
ni->itype.compressed.block_clusters = 1U <<
a->data.non_resident.compression_unit;
- }
+ vi->i_blocks = ni->itype.compressed.size >> 9;
+ } else
+ vi->i_blocks = ni->allocated_size >> 9;
write_unlock_irqrestore(&ni->size_lock, flags);
/*
* This needs to be last since the address space operations ->readpage
@@ -1652,6 +1837,640 @@ page_err_out:
}
/**
+ * ntfs_attr_extend_allocation - extend the allocated space of an attribute
+ * @ni: ntfs inode of the attribute whose allocation to extend
+ * @new_alloc_size: new size in bytes to which to extend the allocation to
+ * @new_data_size: new size in bytes to which to extend the data to
+ * @data_start: beginning of region which is required to be non-sparse
+ *
+ * Extend the allocated space of an attribute described by the ntfs inode @ni
+ * to @new_alloc_size bytes. If @data_start is -1, the whole extension may be
+ * implemented as a hole in the file (as long as both the volume and the ntfs
+ * inode @ni have sparse support enabled). If @data_start is >= 0, then the
+ * region between the old allocated size and @data_start - 1 may be made sparse
+ * but the regions between @data_start and @new_alloc_size must be backed by
+ * actual clusters.
+ *
+ * If @new_data_size is -1, it is ignored. If it is >= 0, then the data size
+ * of the attribute is extended to @new_data_size. Note that the i_size of the
+ * vfs inode is not updated. Only the data size in the base attribute record
+ * is updated. The caller has to update i_size separately if this is required.
+ * WARNING: It is a BUG() for @new_data_size to be smaller than the old data
+ * size as well as for @new_data_size to be greater than @new_alloc_size.
+ *
+ * For resident attributes this involves resizing the attribute record and if
+ * necessary moving it and/or other attributes into extent mft records and/or
+ * converting the attribute to a non-resident attribute which in turn involves
+ * extending the allocation of a non-resident attribute as described below.
+ *
+ * For non-resident attributes this involves allocating clusters in the data
+ * zone on the volume (except for regions that are being made sparse) and
+ * extending the run list to describe the allocated clusters as well as
+ * updating the mapping pairs array of the attribute. This in turn involves
+ * resizing the attribute record and if necessary moving it and/or other
+ * attributes into extent mft records and/or splitting the attribute record
+ * into multiple extent attribute records.
+ *
+ * Also, the attribute list attribute is updated if present and in some of the
+ * above cases (the ones where extent mft records/attributes come into play),
+ * an attribute list attribute is created if not already present.
+ *
+ * Return the new allocated size on success and -errno on error. In the case
+ * that an error is encountered but a partial extension at least up to
+ * @data_start (if present) is possible, the allocation is partially extended
+ * and this is returned. This means the caller must check the returned size to
+ * determine if the extension was partial. If @data_start is -1 then partial
+ * allocations are not performed.
+ *
+ * WARNING: Do not call ntfs_attr_extend_allocation() for $MFT/$DATA.
+ *
+ * Locking: This function takes the runlist lock of @ni for writing as well as
+ * locking the mft record of the base ntfs inode. These locks are maintained
+ * throughout execution of the function. These locks are required so that the
+ * attribute can be resized safely and so that it can for example be converted
+ * from resident to non-resident safely.
+ *
+ * TODO: At present attribute list attribute handling is not implemented.
+ *
+ * TODO: At present it is not safe to call this function for anything other
+ * than the $DATA attribute(s) of an uncompressed and unencrypted file.
+ */
+s64 ntfs_attr_extend_allocation(ntfs_inode *ni, s64 new_alloc_size,
+ const s64 new_data_size, const s64 data_start)
+{
+ VCN vcn;
+ s64 ll, allocated_size, start = data_start;
+ struct inode *vi = VFS_I(ni);
+ ntfs_volume *vol = ni->vol;
+ ntfs_inode *base_ni;
+ MFT_RECORD *m;
+ ATTR_RECORD *a;
+ ntfs_attr_search_ctx *ctx;
+ runlist_element *rl, *rl2;
+ unsigned long flags;
+ int err, mp_size;
+ u32 attr_len = 0; /* Silence stupid gcc warning. */
+ BOOL mp_rebuilt;
+
+#ifdef NTFS_DEBUG
+ read_lock_irqsave(&ni->size_lock, flags);
+ allocated_size = ni->allocated_size;
+ read_unlock_irqrestore(&ni->size_lock, flags);
+ ntfs_debug("Entering for i_ino 0x%lx, attribute type 0x%x, "
+ "old_allocated_size 0x%llx, "
+ "new_allocated_size 0x%llx, new_data_size 0x%llx, "
+ "data_start 0x%llx.", vi->i_ino,
+ (unsigned)le32_to_cpu(ni->type),
+ (unsigned long long)allocated_size,
+ (unsigned long long)new_alloc_size,
+ (unsigned long long)new_data_size,
+ (unsigned long long)start);
+#endif
+retry_extend:
+ /*
+ * For non-resident attributes, @start and @new_size need to be aligned
+ * to cluster boundaries for allocation purposes.
+ */
+ if (NInoNonResident(ni)) {
+ if (start > 0)
+ start &= ~(s64)vol->cluster_size_mask;
+ new_alloc_size = (new_alloc_size + vol->cluster_size - 1) &
+ ~(s64)vol->cluster_size_mask;
+ }
+ BUG_ON(new_data_size >= 0 && new_data_size > new_alloc_size);
+ /* Check if new size is allowed in $AttrDef. */
+ err = ntfs_attr_size_bounds_check(vol, ni->type, new_alloc_size);
+ if (unlikely(err)) {
+ /* Only emit errors when the write will fail completely. */
+ read_lock_irqsave(&ni->size_lock, flags);
+ allocated_size = ni->allocated_size;
+ read_unlock_irqrestore(&ni->size_lock, flags);
+ if (start < 0 || start >= allocated_size) {
+ if (err == -ERANGE) {
+ ntfs_error(vol->sb, "Cannot extend allocation "
+ "of inode 0x%lx, attribute "
+ "type 0x%x, because the new "
+ "allocation would exceed the "
+ "maximum allowed size for "
+ "this attribute type.",
+ vi->i_ino, (unsigned)
+ le32_to_cpu(ni->type));
+ } else {
+ ntfs_error(vol->sb, "Cannot extend allocation "
+ "of inode 0x%lx, attribute "
+ "type 0x%x, because this "
+ "attribute type is not "
+ "defined on the NTFS volume. "
+ "Possible corruption! You "
+ "should run chkdsk!",
+ vi->i_ino, (unsigned)
+ le32_to_cpu(ni->type));
+ }
+ }
+ /* Translate error code to be POSIX conformant for write(2). */
+ if (err == -ERANGE)
+ err = -EFBIG;
+ else
+ err = -EIO;
+ return err;
+ }
+ if (!NInoAttr(ni))
+ base_ni = ni;
+ else
+ base_ni = ni->ext.base_ntfs_ino;
+ /*
+ * We will be modifying both the runlist (if non-resident) and the mft
+ * record so lock them both down.
+ */
+ down_write(&ni->runlist.lock);
+ m = map_mft_record(base_ni);
+ if (IS_ERR(m)) {
+ err = PTR_ERR(m);
+ m = NULL;
+ ctx = NULL;
+ goto err_out;
+ }
+ ctx = ntfs_attr_get_search_ctx(base_ni, m);
+ if (unlikely(!ctx)) {
+ err = -ENOMEM;
+ goto err_out;
+ }
+ read_lock_irqsave(&ni->size_lock, flags);
+ allocated_size = ni->allocated_size;
+ read_unlock_irqrestore(&ni->size_lock, flags);
+ /*
+ * If non-resident, seek to the last extent. If resident, there is
+ * only one extent, so seek to that.
+ */
+ vcn = NInoNonResident(ni) ? allocated_size >> vol->cluster_size_bits :
+ 0;
+ /*
+ * Abort if someone did the work whilst we waited for the locks. If we
+ * just converted the attribute from resident to non-resident it is
+ * likely that exactly this has happened already. We cannot quite
+ * abort if we need to update the data size.
+ */
+ if (unlikely(new_alloc_size <= allocated_size)) {
+ ntfs_debug("Allocated size already exceeds requested size.");
+ new_alloc_size = allocated_size;
+ if (new_data_size < 0)
+ goto done;
+ /*
+ * We want the first attribute extent so that we can update the
+ * data size.
+ */
+ vcn = 0;
+ }
+ err = ntfs_attr_lookup(ni->type, ni->name, ni->name_len,
+ CASE_SENSITIVE, vcn, NULL, 0, ctx);
+ if (unlikely(err)) {
+ if (err == -ENOENT)
+ err = -EIO;
+ goto err_out;
+ }
+ m = ctx->mrec;
+ a = ctx->attr;
+ /* Use goto to reduce indentation. */
+ if (a->non_resident)
+ goto do_non_resident_extend;
+ BUG_ON(NInoNonResident(ni));
+ /* The total length of the attribute value. */
+ attr_len = le32_to_cpu(a->data.resident.value_length);
+ /*
+ * Extend the attribute record to be able to store the new attribute
+ * size. ntfs_attr_record_resize() will not do anything if the size is
+ * not changing.
+ */
+ if (new_alloc_size < vol->mft_record_size &&
+ !ntfs_attr_record_resize(m, a,
+ le16_to_cpu(a->data.resident.value_offset) +
+ new_alloc_size)) {
+ /* The resize succeeded! */
+ write_lock_irqsave(&ni->size_lock, flags);
+ ni->allocated_size = le32_to_cpu(a->length) -
+ le16_to_cpu(a->data.resident.value_offset);
+ write_unlock_irqrestore(&ni->size_lock, flags);
+ if (new_data_size >= 0) {
+ BUG_ON(new_data_size < attr_len);
+ a->data.resident.value_length =
+ cpu_to_le32((u32)new_data_size);
+ }
+ goto flush_done;
+ }
+ /*
+ * We have to drop all the locks so we can call
+ * ntfs_attr_make_non_resident(). This could be optimised by try-
+ * locking the first page cache page and only if that fails dropping
+ * the locks, locking the page, and redoing all the locking and
+ * lookups. While this would be a huge optimisation, it is not worth
+ * it as this is definitely a slow code path.
+ */
+ ntfs_attr_put_search_ctx(ctx);
+ unmap_mft_record(base_ni);
+ up_write(&ni->runlist.lock);
+ /*
+ * Not enough space in the mft record, try to make the attribute
+ * non-resident and if successful restart the extension process.
+ */
+ err = ntfs_attr_make_non_resident(ni, attr_len);
+ if (likely(!err))
+ goto retry_extend;
+ /*
+ * Could not make non-resident. If this is due to this not being
+ * permitted for this attribute type or there not being enough space,
+ * try to make other attributes non-resident. Otherwise fail.
+ */
+ if (unlikely(err != -EPERM && err != -ENOSPC)) {
+ /* Only emit errors when the write will fail completely. */
+ read_lock_irqsave(&ni->size_lock, flags);
+ allocated_size = ni->allocated_size;
+ read_unlock_irqrestore(&ni->size_lock, flags);
+ if (start < 0 || start >= allocated_size)
+ ntfs_error(vol->sb, "Cannot extend allocation of "
+ "inode 0x%lx, attribute type 0x%x, "
+ "because the conversion from resident "
+ "to non-resident attribute failed "
+ "with error code %i.", vi->i_ino,
+ (unsigned)le32_to_cpu(ni->type), err);
+ if (err != -ENOMEM)
+ err = -EIO;
+ goto conv_err_out;
+ }
+ /* TODO: Not implemented from here, abort. */
+ read_lock_irqsave(&ni->size_lock, flags);
+ allocated_size = ni->allocated_size;
+ read_unlock_irqrestore(&ni->size_lock, flags);
+ if (start < 0 || start >= allocated_size) {
+ if (err == -ENOSPC)
+ ntfs_error(vol->sb, "Not enough space in the mft "
+ "record/on disk for the non-resident "
+ "attribute value. This case is not "
+ "implemented yet.");
+ else /* if (err == -EPERM) */
+ ntfs_error(vol->sb, "This attribute type may not be "
+ "non-resident. This case is not "
+ "implemented yet.");
+ }
+ err = -EOPNOTSUPP;
+ goto conv_err_out;
+#if 0
+ // TODO: Attempt to make other attributes non-resident.
+ if (!err)
+ goto do_resident_extend;
+ /*
+ * Both the attribute list attribute and the standard information
+ * attribute must remain in the base inode. Thus, if this is one of
+ * these attributes, we have to try to move other attributes out into
+ * extent mft records instead.
+ */
+ if (ni->type == AT_ATTRIBUTE_LIST ||
+ ni->type == AT_STANDARD_INFORMATION) {
+ // TODO: Attempt to move other attributes into extent mft
+ // records.
+ err = -EOPNOTSUPP;
+ if (!err)
+ goto do_resident_extend;
+ goto err_out;
+ }
+ // TODO: Attempt to move this attribute to an extent mft record, but
+ // only if it is not already the only attribute in an mft record in
+ // which case there would be nothing to gain.
+ err = -EOPNOTSUPP;
+ if (!err)
+ goto do_resident_extend;
+ /* There is nothing we can do to make enough space. )-: */
+ goto err_out;
+#endif
+do_non_resident_extend:
+ BUG_ON(!NInoNonResident(ni));
+ if (new_alloc_size == allocated_size) {
+ BUG_ON(vcn);
+ goto alloc_done;
+ }
+ /*
+ * If the data starts after the end of the old allocation, this is a
+ * $DATA attribute and sparse attributes are enabled on the volume and
+ * for this inode, then create a sparse region between the old
+ * allocated size and the start of the data. Otherwise simply proceed
+ * with filling the whole space between the old allocated size and the
+ * new allocated size with clusters.
+ */
+ if ((start >= 0 && start <= allocated_size) || ni->type != AT_DATA ||
+ !NVolSparseEnabled(vol) || NInoSparseDisabled(ni))
+ goto skip_sparse;
+ // TODO: This is not implemented yet. We just fill in with real
+ // clusters for now...
+ ntfs_debug("Inserting holes is not-implemented yet. Falling back to "
+ "allocating real clusters instead.");
+skip_sparse:
+ rl = ni->runlist.rl;
+ if (likely(rl)) {
+ /* Seek to the end of the runlist. */
+ while (rl->length)
+ rl++;
+ }
+ /* If this attribute extent is not mapped, map it now. */
+ if (unlikely(!rl || rl->lcn == LCN_RL_NOT_MAPPED ||
+ (rl->lcn == LCN_ENOENT && rl > ni->runlist.rl &&
+ (rl-1)->lcn == LCN_RL_NOT_MAPPED))) {
+ if (!rl && !allocated_size)
+ goto first_alloc;
+ rl = ntfs_mapping_pairs_decompress(vol, a, ni->runlist.rl);
+ if (IS_ERR(rl)) {
+ err = PTR_ERR(rl);
+ if (start < 0 || start >= allocated_size)
+ ntfs_error(vol->sb, "Cannot extend allocation "
+ "of inode 0x%lx, attribute "
+ "type 0x%x, because the "
+ "mapping of a runlist "
+ "fragment failed with error "
+ "code %i.", vi->i_ino,
+ (unsigned)le32_to_cpu(ni->type),
+ err);
+ if (err != -ENOMEM)
+ err = -EIO;
+ goto err_out;
+ }
+ ni->runlist.rl = rl;
+ /* Seek to the end of the runlist. */
+ while (rl->length)
+ rl++;
+ }
+ /*
+ * We now know the runlist of the last extent is mapped and @rl is at
+ * the end of the runlist. We want to begin allocating clusters
+ * starting at the last allocated cluster to reduce fragmentation. If
+ * there are no valid LCNs in the attribute we let the cluster
+ * allocator choose the starting cluster.
+ */
+ /* If the last LCN is a hole or simillar seek back to last real LCN. */
+ while (rl->lcn < 0 && rl > ni->runlist.rl)
+ rl--;
+first_alloc:
+ // FIXME: Need to implement partial allocations so at least part of the
+ // write can be performed when start >= 0. (Needed for POSIX write(2)
+ // conformance.)
+ rl2 = ntfs_cluster_alloc(vol, allocated_size >> vol->cluster_size_bits,
+ (new_alloc_size - allocated_size) >>
+ vol->cluster_size_bits, (rl && (rl->lcn >= 0)) ?
+ rl->lcn + rl->length : -1, DATA_ZONE, TRUE);
+ if (IS_ERR(rl2)) {
+ err = PTR_ERR(rl2);
+ if (start < 0 || start >= allocated_size)
+ ntfs_error(vol->sb, "Cannot extend allocation of "
+ "inode 0x%lx, attribute type 0x%x, "
+ "because the allocation of clusters "
+ "failed with error code %i.", vi->i_ino,
+ (unsigned)le32_to_cpu(ni->type), err);
+ if (err != -ENOMEM && err != -ENOSPC)
+ err = -EIO;
+ goto err_out;
+ }
+ rl = ntfs_runlists_merge(ni->runlist.rl, rl2);
+ if (IS_ERR(rl)) {
+ err = PTR_ERR(rl);
+ if (start < 0 || start >= allocated_size)
+ ntfs_error(vol->sb, "Cannot extend allocation of "
+ "inode 0x%lx, attribute type 0x%x, "
+ "because the runlist merge failed "
+ "with error code %i.", vi->i_ino,
+ (unsigned)le32_to_cpu(ni->type), err);
+ if (err != -ENOMEM)
+ err = -EIO;
+ if (ntfs_cluster_free_from_rl(vol, rl2)) {
+ ntfs_error(vol->sb, "Failed to release allocated "
+ "cluster(s) in error code path. Run "
+ "chkdsk to recover the lost "
+ "cluster(s).");
+ NVolSetErrors(vol);
+ }
+ ntfs_free(rl2);
+ goto err_out;
+ }
+ ni->runlist.rl = rl;
+ ntfs_debug("Allocated 0x%llx clusters.", (long long)(new_alloc_size -
+ allocated_size) >> vol->cluster_size_bits);
+ /* Find the runlist element with which the attribute extent starts. */
+ ll = sle64_to_cpu(a->data.non_resident.lowest_vcn);
+ rl2 = ntfs_rl_find_vcn_nolock(rl, ll);
+ BUG_ON(!rl2);
+ BUG_ON(!rl2->length);
+ BUG_ON(rl2->lcn < LCN_HOLE);
+ mp_rebuilt = FALSE;
+ /* Get the size for the new mapping pairs array for this extent. */
+ mp_size = ntfs_get_size_for_mapping_pairs(vol, rl2, ll, -1);
+ if (unlikely(mp_size <= 0)) {
+ err = mp_size;
+ if (start < 0 || start >= allocated_size)
+ ntfs_error(vol->sb, "Cannot extend allocation of "
+ "inode 0x%lx, attribute type 0x%x, "
+ "because determining the size for the "
+ "mapping pairs failed with error code "
+ "%i.", vi->i_ino,
+ (unsigned)le32_to_cpu(ni->type), err);
+ err = -EIO;
+ goto undo_alloc;
+ }
+ /* Extend the attribute record to fit the bigger mapping pairs array. */
+ attr_len = le32_to_cpu(a->length);
+ err = ntfs_attr_record_resize(m, a, mp_size +
+ le16_to_cpu(a->data.non_resident.mapping_pairs_offset));
+ if (unlikely(err)) {
+ BUG_ON(err != -ENOSPC);
+ // TODO: Deal with this by moving this extent to a new mft
+ // record or by starting a new extent in a new mft record,
+ // possibly by extending this extent partially and filling it
+ // and creating a new extent for the remainder, or by making
+ // other attributes non-resident and/or by moving other
+ // attributes out of this mft record.
+ if (start < 0 || start >= allocated_size)
+ ntfs_error(vol->sb, "Not enough space in the mft "
+ "record for the extended attribute "
+ "record. This case is not "
+ "implemented yet.");
+ err = -EOPNOTSUPP;
+ goto undo_alloc;
+ }
+ mp_rebuilt = TRUE;
+ /* Generate the mapping pairs array directly into the attr record. */
+ err = ntfs_mapping_pairs_build(vol, (u8*)a +
+ le16_to_cpu(a->data.non_resident.mapping_pairs_offset),
+ mp_size, rl2, ll, -1, NULL);
+ if (unlikely(err)) {
+ if (start < 0 || start >= allocated_size)
+ ntfs_error(vol->sb, "Cannot extend allocation of "
+ "inode 0x%lx, attribute type 0x%x, "
+ "because building the mapping pairs "
+ "failed with error code %i.", vi->i_ino,
+ (unsigned)le32_to_cpu(ni->type), err);
+ err = -EIO;
+ goto undo_alloc;
+ }
+ /* Update the highest_vcn. */
+ a->data.non_resident.highest_vcn = cpu_to_sle64((new_alloc_size >>
+ vol->cluster_size_bits) - 1);
+ /*
+ * We now have extended the allocated size of the attribute. Reflect
+ * this in the ntfs_inode structure and the attribute record.
+ */
+ if (a->data.non_resident.lowest_vcn) {
+ /*
+ * We are not in the first attribute extent, switch to it, but
+ * first ensure the changes will make it to disk later.
+ */
+ flush_dcache_mft_record_page(ctx->ntfs_ino);
+ mark_mft_record_dirty(ctx->ntfs_ino);
+ ntfs_attr_reinit_search_ctx(ctx);
+ err = ntfs_attr_lookup(ni->type, ni->name, ni->name_len,
+ CASE_SENSITIVE, 0, NULL, 0, ctx);
+ if (unlikely(err))
+ goto restore_undo_alloc;
+ /* @m is not used any more so no need to set it. */
+ a = ctx->attr;
+ }
+ write_lock_irqsave(&ni->size_lock, flags);
+ ni->allocated_size = new_alloc_size;
+ a->data.non_resident.allocated_size = cpu_to_sle64(new_alloc_size);
+ /*
+ * FIXME: This would fail if @ni is a directory, $MFT, or an index,
+ * since those can have sparse/compressed set. For example can be
+ * set compressed even though it is not compressed itself and in that
+ * case the bit means that files are to be created compressed in the
+ * directory... At present this is ok as this code is only called for
+ * regular files, and only for their $DATA attribute(s).
+ * FIXME: The calculation is wrong if we created a hole above. For now
+ * it does not matter as we never create holes.
+ */
+ if (NInoSparse(ni) || NInoCompressed(ni)) {
+ ni->itype.compressed.size += new_alloc_size - allocated_size;
+ a->data.non_resident.compressed_size =
+ cpu_to_sle64(ni->itype.compressed.size);
+ vi->i_blocks = ni->itype.compressed.size >> 9;
+ } else
+ vi->i_blocks = new_alloc_size >> 9;
+ write_unlock_irqrestore(&ni->size_lock, flags);
+alloc_done:
+ if (new_data_size >= 0) {
+ BUG_ON(new_data_size <
+ sle64_to_cpu(a->data.non_resident.data_size));
+ a->data.non_resident.data_size = cpu_to_sle64(new_data_size);
+ }
+flush_done:
+ /* Ensure the changes make it to disk. */
+ flush_dcache_mft_record_page(ctx->ntfs_ino);
+ mark_mft_record_dirty(ctx->ntfs_ino);
+done:
+ ntfs_attr_put_search_ctx(ctx);
+ unmap_mft_record(base_ni);
+ up_write(&ni->runlist.lock);
+ ntfs_debug("Done, new_allocated_size 0x%llx.",
+ (unsigned long long)new_alloc_size);
+ return new_alloc_size;
+restore_undo_alloc:
+ if (start < 0 || start >= allocated_size)
+ ntfs_error(vol->sb, "Cannot complete extension of allocation "
+ "of inode 0x%lx, attribute type 0x%x, because "
+ "lookup of first attribute extent failed with "
+ "error code %i.", vi->i_ino,
+ (unsigned)le32_to_cpu(ni->type), err);
+ if (err == -ENOENT)
+ err = -EIO;
+ ntfs_attr_reinit_search_ctx(ctx);
+ if (ntfs_attr_lookup(ni->type, ni->name, ni->name_len, CASE_SENSITIVE,
+ allocated_size >> vol->cluster_size_bits, NULL, 0,
+ ctx)) {
+ ntfs_error(vol->sb, "Failed to find last attribute extent of "
+ "attribute in error code path. Run chkdsk to "
+ "recover.");
+ write_lock_irqsave(&ni->size_lock, flags);
+ ni->allocated_size = new_alloc_size;
+ /*
+ * FIXME: This would fail if @ni is a directory... See above.
+ * FIXME: The calculation is wrong if we created a hole above.
+ * For now it does not matter as we never create holes.
+ */
+ if (NInoSparse(ni) || NInoCompressed(ni)) {
+ ni->itype.compressed.size += new_alloc_size -
+ allocated_size;
+ vi->i_blocks = ni->itype.compressed.size >> 9;
+ } else
+ vi->i_blocks = new_alloc_size >> 9;
+ write_unlock_irqrestore(&ni->size_lock, flags);
+ ntfs_attr_put_search_ctx(ctx);
+ unmap_mft_record(base_ni);
+ up_write(&ni->runlist.lock);
+ /*
+ * The only thing that is now wrong is the allocated size of the
+ * base attribute extent which chkdsk should be able to fix.
+ */
+ NVolSetErrors(vol);
+ return err;
+ }
+ ctx->attr->data.non_resident.highest_vcn = cpu_to_sle64(
+ (allocated_size >> vol->cluster_size_bits) - 1);
+undo_alloc:
+ ll = allocated_size >> vol->cluster_size_bits;
+ if (ntfs_cluster_free(ni, ll, -1, ctx) < 0) {
+ ntfs_error(vol->sb, "Failed to release allocated cluster(s) "
+ "in error code path. Run chkdsk to recover "
+ "the lost cluster(s).");
+ NVolSetErrors(vol);
+ }
+ m = ctx->mrec;
+ a = ctx->attr;
+ /*
+ * If the runlist truncation fails and/or the search context is no
+ * longer valid, we cannot resize the attribute record or build the
+ * mapping pairs array thus we mark the inode bad so that no access to
+ * the freed clusters can happen.
+ */
+ if (ntfs_rl_truncate_nolock(vol, &ni->runlist, ll) || IS_ERR(m)) {
+ ntfs_error(vol->sb, "Failed to %s in error code path. Run "
+ "chkdsk to recover.", IS_ERR(m) ?
+ "restore attribute search context" :
+ "truncate attribute runlist");
+ make_bad_inode(vi);
+ make_bad_inode(VFS_I(base_ni));
+ NVolSetErrors(vol);
+ } else if (mp_rebuilt) {
+ if (ntfs_attr_record_resize(m, a, attr_len)) {
+ ntfs_error(vol->sb, "Failed to restore attribute "
+ "record in error code path. Run "
+ "chkdsk to recover.");
+ make_bad_inode(vi);
+ make_bad_inode(VFS_I(base_ni));
+ NVolSetErrors(vol);
+ } else /* if (success) */ {
+ if (ntfs_mapping_pairs_build(vol, (u8*)a + le16_to_cpu(
+ a->data.non_resident.
+ mapping_pairs_offset), attr_len -
+ le16_to_cpu(a->data.non_resident.
+ mapping_pairs_offset), rl2, ll, -1,
+ NULL)) {
+ ntfs_error(vol->sb, "Failed to restore "
+ "mapping pairs array in error "
+ "code path. Run chkdsk to "
+ "recover.");
+ make_bad_inode(vi);
+ make_bad_inode(VFS_I(base_ni));
+ NVolSetErrors(vol);
+ }
+ flush_dcache_mft_record_page(ctx->ntfs_ino);
+ mark_mft_record_dirty(ctx->ntfs_ino);
+ }
+ }
+err_out:
+ if (ctx)
+ ntfs_attr_put_search_ctx(ctx);
+ if (m)
+ unmap_mft_record(base_ni);
+ up_write(&ni->runlist.lock);
+conv_err_out:
+ ntfs_debug("Failed. Returning error code %i.", err);
+ return err;
+}
+
+/**
* ntfs_attr_set - fill (a part of) an attribute with a byte
* @ni: ntfs inode describing the attribute to fill
* @ofs: offset inside the attribute at which to start to fill
@@ -1773,6 +2592,8 @@ int ntfs_attr_set(ntfs_inode *ni, const s64 ofs, const s64 cnt, const u8 val)
/* Finally unlock and release the page. */
unlock_page(page);
page_cache_release(page);
+ balance_dirty_pages_ratelimited(mapping);
+ cond_resched();
}
/* If there is a last partial page, need to do it the slow way. */
if (end_ofs) {
diff --git a/fs/ntfs/attrib.h b/fs/ntfs/attrib.h
index 0618ed6fd7b3..9074886b44ba 100644
--- a/fs/ntfs/attrib.h
+++ b/fs/ntfs/attrib.h
@@ -60,14 +60,15 @@ typedef struct {
ATTR_RECORD *base_attr;
} ntfs_attr_search_ctx;
-extern int ntfs_map_runlist_nolock(ntfs_inode *ni, VCN vcn);
+extern int ntfs_map_runlist_nolock(ntfs_inode *ni, VCN vcn,
+ ntfs_attr_search_ctx *ctx);
extern int ntfs_map_runlist(ntfs_inode *ni, VCN vcn);
extern LCN ntfs_attr_vcn_to_lcn_nolock(ntfs_inode *ni, const VCN vcn,
const BOOL write_locked);
extern runlist_element *ntfs_attr_find_vcn_nolock(ntfs_inode *ni,
- const VCN vcn, const BOOL write_locked);
+ const VCN vcn, ntfs_attr_search_ctx *ctx);
int ntfs_attr_lookup(const ATTR_TYPE type, const ntfschar *name,
const u32 name_len, const IGNORE_CASE_BOOL ic,
@@ -102,7 +103,10 @@ extern int ntfs_attr_record_resize(MFT_RECORD *m, ATTR_RECORD *a, u32 new_size);
extern int ntfs_resident_attr_value_resize(MFT_RECORD *m, ATTR_RECORD *a,
const u32 new_size);
-extern int ntfs_attr_make_non_resident(ntfs_inode *ni);
+extern int ntfs_attr_make_non_resident(ntfs_inode *ni, const u32 data_size);
+
+extern s64 ntfs_attr_extend_allocation(ntfs_inode *ni, s64 new_alloc_size,
+ const s64 new_data_size, const s64 data_start);
extern int ntfs_attr_set(ntfs_inode *ni, const s64 ofs, const s64 cnt,
const u8 val);
diff --git a/fs/ntfs/file.c b/fs/ntfs/file.c
index be9fd1dd423d..727533891813 100644
--- a/fs/ntfs/file.c
+++ b/fs/ntfs/file.c
@@ -19,11 +19,24 @@
* Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include <linux/pagemap.h>
#include <linux/buffer_head.h>
+#include <linux/pagemap.h>
+#include <linux/pagevec.h>
+#include <linux/sched.h>
+#include <linux/swap.h>
+#include <linux/uio.h>
+#include <linux/writeback.h>
+#include <asm/page.h>
+#include <asm/uaccess.h>
+
+#include "attrib.h"
+#include "bitmap.h"
#include "inode.h"
#include "debug.h"
+#include "lcnalloc.h"
+#include "malloc.h"
+#include "mft.h"
#include "ntfs.h"
/**
@@ -56,6 +69,2185 @@ static int ntfs_file_open(struct inode *vi, struct file *filp)
#ifdef NTFS_RW
/**
+ * ntfs_attr_extend_initialized - extend the initialized size of an attribute
+ * @ni: ntfs inode of the attribute to extend
+ * @new_init_size: requested new initialized size in bytes
+ * @cached_page: store any allocated but unused page here
+ * @lru_pvec: lru-buffering pagevec of the caller
+ *
+ * Extend the initialized size of an attribute described by the ntfs inode @ni
+ * to @new_init_size bytes. This involves zeroing any non-sparse space between
+ * the old initialized size and @new_init_size both in the page cache and on
+ * disk (if relevant complete pages are already uptodate in the page cache then
+ * these are simply marked dirty).
+ *
+ * As a side-effect, the file size (vfs inode->i_size) may be incremented as,
+ * in the resident attribute case, it is tied to the initialized size and, in
+ * the non-resident attribute case, it may not fall below the initialized size.
+ *
+ * Note that if the attribute is resident, we do not need to touch the page
+ * cache at all. This is because if the page cache page is not uptodate we
+ * bring it uptodate later, when doing the write to the mft record since we
+ * then already have the page mapped. And if the page is uptodate, the
+ * non-initialized region will already have been zeroed when the page was
+ * brought uptodate and the region may in fact already have been overwritten
+ * with new data via mmap() based writes, so we cannot just zero it. And since
+ * POSIX specifies that the behaviour of resizing a file whilst it is mmap()ped
+ * is unspecified, we choose not to do zeroing and thus we do not need to touch
+ * the page at all. For a more detailed explanation see ntfs_truncate() in
+ * fs/ntfs/inode.c.
+ *
+ * @cached_page and @lru_pvec are just optimizations for dealing with multiple
+ * pages.
+ *
+ * Return 0 on success and -errno on error. In the case that an error is
+ * encountered it is possible that the initialized size will already have been
+ * incremented some way towards @new_init_size but it is guaranteed that if
+ * this is the case, the necessary zeroing will also have happened and that all
+ * metadata is self-consistent.
+ *
+ * Locking: i_sem on the vfs inode corrseponsind to the ntfs inode @ni must be
+ * held by the caller.
+ */
+static int ntfs_attr_extend_initialized(ntfs_inode *ni, const s64 new_init_size,
+ struct page **cached_page, struct pagevec *lru_pvec)
+{
+ s64 old_init_size;
+ loff_t old_i_size;
+ pgoff_t index, end_index;
+ unsigned long flags;
+ struct inode *vi = VFS_I(ni);
+ ntfs_inode *base_ni;
+ MFT_RECORD *m = NULL;
+ ATTR_RECORD *a;
+ ntfs_attr_search_ctx *ctx = NULL;
+ struct address_space *mapping;
+ struct page *page = NULL;
+ u8 *kattr;
+ int err;
+ u32 attr_len;
+
+ read_lock_irqsave(&ni->size_lock, flags);
+ old_init_size = ni->initialized_size;
+ old_i_size = i_size_read(vi);
+ BUG_ON(new_init_size > ni->allocated_size);
+ read_unlock_irqrestore(&ni->size_lock, flags);
+ ntfs_debug("Entering for i_ino 0x%lx, attribute type 0x%x, "
+ "old_initialized_size 0x%llx, "
+ "new_initialized_size 0x%llx, i_size 0x%llx.",
+ vi->i_ino, (unsigned)le32_to_cpu(ni->type),
+ (unsigned long long)old_init_size,
+ (unsigned long long)new_init_size, old_i_size);
+ if (!NInoAttr(ni))
+ base_ni = ni;
+ else
+ base_ni = ni->ext.base_ntfs_ino;
+ /* Use goto to reduce indentation and we need the label below anyway. */
+ if (NInoNonResident(ni))
+ goto do_non_resident_extend;
+ BUG_ON(old_init_size != old_i_size);
+ m = map_mft_record(base_ni);
+ if (IS_ERR(m)) {
+ err = PTR_ERR(m);
+ m = NULL;
+ goto err_out;
+ }
+ ctx = ntfs_attr_get_search_ctx(base_ni, m);
+ if (unlikely(!ctx)) {
+ err = -ENOMEM;
+ goto err_out;
+ }
+ err = ntfs_attr_lookup(ni->type, ni->name, ni->name_len,
+ CASE_SENSITIVE, 0, NULL, 0, ctx);
+ if (unlikely(err)) {
+ if (err == -ENOENT)
+ err = -EIO;
+ goto err_out;
+ }
+ m = ctx->mrec;
+ a = ctx->attr;
+ BUG_ON(a->non_resident);
+ /* The total length of the attribute value. */
+ attr_len = le32_to_cpu(a->data.resident.value_length);
+ BUG_ON(old_i_size != (loff_t)attr_len);
+ /*
+ * Do the zeroing in the mft record and update the attribute size in
+ * the mft record.
+ */
+ kattr = (u8*)a + le16_to_cpu(a->data.resident.value_offset);
+ memset(kattr + attr_len, 0, new_init_size - attr_len);
+ a->data.resident.value_length = cpu_to_le32((u32)new_init_size);
+ /* Finally, update the sizes in the vfs and ntfs inodes. */
+ write_lock_irqsave(&ni->size_lock, flags);
+ i_size_write(vi, new_init_size);
+ ni->initialized_size = new_init_size;
+ write_unlock_irqrestore(&ni->size_lock, flags);
+ goto done;
+do_non_resident_extend:
+ /*
+ * If the new initialized size @new_init_size exceeds the current file
+ * size (vfs inode->i_size), we need to extend the file size to the
+ * new initialized size.
+ */
+ if (new_init_size > old_i_size) {
+ m = map_mft_record(base_ni);
+ if (IS_ERR(m)) {
+ err = PTR_ERR(m);
+ m = NULL;
+ goto err_out;
+ }
+ ctx = ntfs_attr_get_search_ctx(base_ni, m);
+ if (unlikely(!ctx)) {
+ err = -ENOMEM;
+ goto err_out;
+ }
+ err = ntfs_attr_lookup(ni->type, ni->name, ni->name_len,
+ CASE_SENSITIVE, 0, NULL, 0, ctx);
+ if (unlikely(err)) {
+ if (err == -ENOENT)
+ err = -EIO;
+ goto err_out;
+ }
+ m = ctx->mrec;
+ a = ctx->attr;
+ BUG_ON(!a->non_resident);
+ BUG_ON(old_i_size != (loff_t)
+ sle64_to_cpu(a->data.non_resident.data_size));
+ a->data.non_resident.data_size = cpu_to_sle64(new_init_size);
+ flush_dcache_mft_record_page(ctx->ntfs_ino);
+ mark_mft_record_dirty(ctx->ntfs_ino);
+ /* Update the file size in the vfs inode. */
+ i_size_write(vi, new_init_size);
+ ntfs_attr_put_search_ctx(ctx);
+ ctx = NULL;
+ unmap_mft_record(base_ni);
+ m = NULL;
+ }
+ mapping = vi->i_mapping;
+ index = old_init_size >> PAGE_CACHE_SHIFT;
+ end_index = (new_init_size + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
+ do {
+ /*
+ * Read the page. If the page is not present, this will zero
+ * the uninitialized regions for us.
+ */
+ page = read_cache_page(mapping, index,
+ (filler_t*)mapping->a_ops->readpage, NULL);
+ if (IS_ERR(page)) {
+ err = PTR_ERR(page);
+ goto init_err_out;
+ }
+ wait_on_page_locked(page);
+ if (unlikely(!PageUptodate(page) || PageError(page))) {
+ page_cache_release(page);
+ err = -EIO;
+ goto init_err_out;
+ }
+ /*
+ * Update the initialized size in the ntfs inode. This is
+ * enough to make ntfs_writepage() work.
+ */
+ write_lock_irqsave(&ni->size_lock, flags);
+ ni->initialized_size = (index + 1) << PAGE_CACHE_SHIFT;
+ if (ni->initialized_size > new_init_size)
+ ni->initialized_size = new_init_size;
+ write_unlock_irqrestore(&ni->size_lock, flags);
+ /* Set the page dirty so it gets written out. */
+ set_page_dirty(page);
+ page_cache_release(page);
+ /*
+ * Play nice with the vm and the rest of the system. This is
+ * very much needed as we can potentially be modifying the
+ * initialised size from a very small value to a really huge
+ * value, e.g.
+ * f = open(somefile, O_TRUNC);
+ * truncate(f, 10GiB);
+ * seek(f, 10GiB);
+ * write(f, 1);
+ * And this would mean we would be marking dirty hundreds of
+ * thousands of pages or as in the above example more than
+ * two and a half million pages!
+ *
+ * TODO: For sparse pages could optimize this workload by using
+ * the FsMisc / MiscFs page bit as a "PageIsSparse" bit. This
+ * would be set in readpage for sparse pages and here we would
+ * not need to mark dirty any pages which have this bit set.
+ * The only caveat is that we have to clear the bit everywhere
+ * where we allocate any clusters that lie in the page or that
+ * contain the page.
+ *
+ * TODO: An even greater optimization would be for us to only
+ * call readpage() on pages which are not in sparse regions as
+ * determined from the runlist. This would greatly reduce the
+ * number of pages we read and make dirty in the case of sparse
+ * files.
+ */
+ balance_dirty_pages_ratelimited(mapping);
+ cond_resched();
+ } while (++index < end_index);
+ read_lock_irqsave(&ni->size_lock, flags);
+ BUG_ON(ni->initialized_size != new_init_size);
+ read_unlock_irqrestore(&ni->size_lock, flags);
+ /* Now bring in sync the initialized_size in the mft record. */
+ m = map_mft_record(base_ni);
+ if (IS_ERR(m)) {
+ err = PTR_ERR(m);
+ m = NULL;
+ goto init_err_out;
+ }
+ ctx = ntfs_attr_get_search_ctx(base_ni, m);
+ if (unlikely(!ctx)) {
+ err = -ENOMEM;
+ goto init_err_out;
+ }
+ err = ntfs_attr_lookup(ni->type, ni->name, ni->name_len,
+ CASE_SENSITIVE, 0, NULL, 0, ctx);
+ if (unlikely(err)) {
+ if (err == -ENOENT)
+ err = -EIO;
+ goto init_err_out;
+ }
+ m = ctx->mrec;
+ a = ctx->attr;
+ BUG_ON(!a->non_resident);
+ a->data.non_resident.initialized_size = cpu_to_sle64(new_init_size);
+done:
+ flush_dcache_mft_record_page(ctx->ntfs_ino);
+ mark_mft_record_dirty(ctx->ntfs_ino);
+ if (ctx)
+ ntfs_attr_put_search_ctx(ctx);
+ if (m)
+ unmap_mft_record(base_ni);
+ ntfs_debug("Done, initialized_size 0x%llx, i_size 0x%llx.",
+ (unsigned long long)new_init_size, i_size_read(vi));
+ return 0;
+init_err_out:
+ write_lock_irqsave(&ni->size_lock, flags);
+ ni->initialized_size = old_init_size;
+ write_unlock_irqrestore(&ni->size_lock, flags);
+err_out:
+ if (ctx)
+ ntfs_attr_put_search_ctx(ctx);
+ if (m)
+ unmap_mft_record(base_ni);
+ ntfs_debug("Failed. Returning error code %i.", err);
+ return err;
+}
+
+/**
+ * ntfs_fault_in_pages_readable -
+ *
+ * Fault a number of userspace pages into pagetables.
+ *
+ * Unlike include/linux/pagemap.h::fault_in_pages_readable(), this one copes
+ * with more than two userspace pages as well as handling the single page case
+ * elegantly.
+ *
+ * If you find this difficult to understand, then think of the while loop being
+ * the following code, except that we do without the integer variable ret:
+ *
+ * do {
+ * ret = __get_user(c, uaddr);
+ * uaddr += PAGE_SIZE;
+ * } while (!ret && uaddr < end);
+ *
+ * Note, the final __get_user() may well run out-of-bounds of the user buffer,
+ * but _not_ out-of-bounds of the page the user buffer belongs to, and since
+ * this is only a read and not a write, and since it is still in the same page,
+ * it should not matter and this makes the code much simpler.
+ */
+static inline void ntfs_fault_in_pages_readable(const char __user *uaddr,
+ int bytes)
+{
+ const char __user *end;
+ volatile char c;
+
+ /* Set @end to the first byte outside the last page we care about. */
+ end = (const char __user*)PAGE_ALIGN((ptrdiff_t __user)uaddr + bytes);
+
+ while (!__get_user(c, uaddr) && (uaddr += PAGE_SIZE, uaddr < end))
+ ;
+}
+
+/**
+ * ntfs_fault_in_pages_readable_iovec -
+ *
+ * Same as ntfs_fault_in_pages_readable() but operates on an array of iovecs.
+ */
+static inline void ntfs_fault_in_pages_readable_iovec(const struct iovec *iov,
+ size_t iov_ofs, int bytes)
+{
+ do {
+ const char __user *buf;
+ unsigned len;
+
+ buf = iov->iov_base + iov_ofs;
+ len = iov->iov_len - iov_ofs;
+ if (len > bytes)
+ len = bytes;
+ ntfs_fault_in_pages_readable(buf, len);
+ bytes -= len;
+ iov++;
+ iov_ofs = 0;
+ } while (bytes);
+}
+
+/**
+ * __ntfs_grab_cache_pages - obtain a number of locked pages
+ * @mapping: address space mapping from which to obtain page cache pages
+ * @index: starting index in @mapping at which to begin obtaining pages
+ * @nr_pages: number of page cache pages to obtain
+ * @pages: array of pages in which to return the obtained page cache pages
+ * @cached_page: allocated but as yet unused page
+ * @lru_pvec: lru-buffering pagevec of caller
+ *
+ * Obtain @nr_pages locked page cache pages from the mapping @maping and
+ * starting at index @index.
+ *
+ * If a page is newly created, increment its refcount and add it to the
+ * caller's lru-buffering pagevec @lru_pvec.
+ *
+ * This is the same as mm/filemap.c::__grab_cache_page(), except that @nr_pages
+ * are obtained at once instead of just one page and that 0 is returned on
+ * success and -errno on error.
+ *
+ * Note, the page locks are obtained in ascending page index order.
+ */
+static inline int __ntfs_grab_cache_pages(struct address_space *mapping,
+ pgoff_t index, const unsigned nr_pages, struct page **pages,
+ struct page **cached_page, struct pagevec *lru_pvec)
+{
+ int err, nr;
+
+ BUG_ON(!nr_pages);
+ err = nr = 0;
+ do {
+ pages[nr] = find_lock_page(mapping, index);
+ if (!pages[nr]) {
+ if (!*cached_page) {
+ *cached_page = page_cache_alloc(mapping);
+ if (unlikely(!*cached_page)) {
+ err = -ENOMEM;
+ goto err_out;
+ }
+ }
+ err = add_to_page_cache(*cached_page, mapping, index,
+ GFP_KERNEL);
+ if (unlikely(err)) {
+ if (err == -EEXIST)
+ continue;
+ goto err_out;
+ }
+ pages[nr] = *cached_page;
+ page_cache_get(*cached_page);
+ if (unlikely(!pagevec_add(lru_pvec, *cached_page)))
+ __pagevec_lru_add(lru_pvec);
+ *cached_page = NULL;
+ }
+ index++;
+ nr++;
+ } while (nr < nr_pages);
+out:
+ return err;
+err_out:
+ while (nr > 0) {
+ unlock_page(pages[--nr]);
+ page_cache_release(pages[nr]);
+ }
+ goto out;
+}
+
+static inline int ntfs_submit_bh_for_read(struct buffer_head *bh)
+{
+ lock_buffer(bh);
+ get_bh(bh);
+ bh->b_end_io = end_buffer_read_sync;
+ return submit_bh(READ, bh);
+}
+
+/**
+ * ntfs_prepare_pages_for_non_resident_write - prepare pages for receiving data
+ * @pages: array of destination pages
+ * @nr_pages: number of pages in @pages
+ * @pos: byte position in file at which the write begins
+ * @bytes: number of bytes to be written
+ *
+ * This is called for non-resident attributes from ntfs_file_buffered_write()
+ * with i_sem held on the inode (@pages[0]->mapping->host). There are
+ * @nr_pages pages in @pages which are locked but not kmap()ped. The source
+ * data has not yet been copied into the @pages.
+ *
+ * Need to fill any holes with actual clusters, allocate buffers if necessary,
+ * ensure all the buffers are mapped, and bring uptodate any buffers that are
+ * only partially being written to.
+ *
+ * If @nr_pages is greater than one, we are guaranteed that the cluster size is
+ * greater than PAGE_CACHE_SIZE, that all pages in @pages are entirely inside
+ * the same cluster and that they are the entirety of that cluster, and that
+ * the cluster is sparse, i.e. we need to allocate a cluster to fill the hole.
+ *
+ * i_size is not to be modified yet.
+ *
+ * Return 0 on success or -errno on error.
+ */
+static int ntfs_prepare_pages_for_non_resident_write(struct page **pages,
+ unsigned nr_pages, s64 pos, size_t bytes)
+{
+ VCN vcn, highest_vcn = 0, cpos, cend, bh_cpos, bh_cend;
+ LCN lcn;
+ s64 bh_pos, vcn_len, end, initialized_size;
+ sector_t lcn_block;
+ struct page *page;
+ struct inode *vi;
+ ntfs_inode *ni, *base_ni = NULL;
+ ntfs_volume *vol;
+ runlist_element *rl, *rl2;
+ struct buffer_head *bh, *head, *wait[2], **wait_bh = wait;
+ ntfs_attr_search_ctx *ctx = NULL;
+ MFT_RECORD *m = NULL;
+ ATTR_RECORD *a = NULL;
+ unsigned long flags;
+ u32 attr_rec_len = 0;
+ unsigned blocksize, u;
+ int err, mp_size;
+ BOOL rl_write_locked, was_hole, is_retry;
+ unsigned char blocksize_bits;
+ struct {
+ u8 runlist_merged:1;
+ u8 mft_attr_mapped:1;
+ u8 mp_rebuilt:1;
+ u8 attr_switched:1;
+ } status = { 0, 0, 0, 0 };
+
+ BUG_ON(!nr_pages);
+ BUG_ON(!pages);
+ BUG_ON(!*pages);
+ vi = pages[0]->mapping->host;
+ ni = NTFS_I(vi);
+ vol = ni->vol;
+ ntfs_debug("Entering for inode 0x%lx, attribute type 0x%x, start page "
+ "index 0x%lx, nr_pages 0x%x, pos 0x%llx, bytes 0x%zx.",
+ vi->i_ino, ni->type, pages[0]->index, nr_pages,
+ (long long)pos, bytes);
+ blocksize_bits = vi->i_blkbits;
+ blocksize = 1 << blocksize_bits;
+ u = 0;
+ do {
+ struct page *page = pages[u];
+ /*
+ * create_empty_buffers() will create uptodate/dirty buffers if
+ * the page is uptodate/dirty.
+ */
+ if (!page_has_buffers(page)) {
+ create_empty_buffers(page, blocksize, 0);
+ if (unlikely(!page_has_buffers(page)))
+ return -ENOMEM;
+ }
+ } while (++u < nr_pages);
+ rl_write_locked = FALSE;
+ rl = NULL;
+ err = 0;
+ vcn = lcn = -1;
+ vcn_len = 0;
+ lcn_block = -1;
+ was_hole = FALSE;
+ cpos = pos >> vol->cluster_size_bits;
+ end = pos + bytes;
+ cend = (end + vol->cluster_size - 1) >> vol->cluster_size_bits;
+ /*
+ * Loop over each page and for each page over each buffer. Use goto to
+ * reduce indentation.
+ */
+ u = 0;
+do_next_page:
+ page = pages[u];
+ bh_pos = (s64)page->index << PAGE_CACHE_SHIFT;
+ bh = head = page_buffers(page);
+ do {
+ VCN cdelta;
+ s64 bh_end;
+ unsigned bh_cofs;
+
+ /* Clear buffer_new on all buffers to reinitialise state. */
+ if (buffer_new(bh))
+ clear_buffer_new(bh);
+ bh_end = bh_pos + blocksize;
+ bh_cpos = bh_pos >> vol->cluster_size_bits;
+ bh_cofs = bh_pos & vol->cluster_size_mask;
+ if (buffer_mapped(bh)) {
+ /*
+ * The buffer is already mapped. If it is uptodate,
+ * ignore it.
+ */
+ if (buffer_uptodate(bh))
+ continue;
+ /*
+ * The buffer is not uptodate. If the page is uptodate
+ * set the buffer uptodate and otherwise ignore it.
+ */
+ if (PageUptodate(page)) {
+ set_buffer_uptodate(bh);
+ continue;
+ }
+ /*
+ * Neither the page nor the buffer are uptodate. If
+ * the buffer is only partially being written to, we
+ * need to read it in before the write, i.e. now.
+ */
+ if ((bh_pos < pos && bh_end > pos) ||
+ (bh_pos < end && bh_end > end)) {
+ /*
+ * If the buffer is fully or partially within
+ * the initialized size, do an actual read.
+ * Otherwise, simply zero the buffer.
+ */
+ read_lock_irqsave(&ni->size_lock, flags);
+ initialized_size = ni->initialized_size;
+ read_unlock_irqrestore(&ni->size_lock, flags);
+ if (bh_pos < initialized_size) {
+ ntfs_submit_bh_for_read(bh);
+ *wait_bh++ = bh;
+ } else {
+ u8 *kaddr = kmap_atomic(page, KM_USER0);
+ memset(kaddr + bh_offset(bh), 0,
+ blocksize);
+ kunmap_atomic(kaddr, KM_USER0);
+ flush_dcache_page(page);
+ set_buffer_uptodate(bh);
+ }
+ }
+ continue;
+ }
+ /* Unmapped buffer. Need to map it. */
+ bh->b_bdev = vol->sb->s_bdev;
+ /*
+ * If the current buffer is in the same clusters as the map
+ * cache, there is no need to check the runlist again. The
+ * map cache is made up of @vcn, which is the first cached file
+ * cluster, @vcn_len which is the number of cached file
+ * clusters, @lcn is the device cluster corresponding to @vcn,
+ * and @lcn_block is the block number corresponding to @lcn.
+ */
+ cdelta = bh_cpos - vcn;
+ if (likely(!cdelta || (cdelta > 0 && cdelta < vcn_len))) {
+map_buffer_cached:
+ BUG_ON(lcn < 0);
+ bh->b_blocknr = lcn_block +
+ (cdelta << (vol->cluster_size_bits -
+ blocksize_bits)) +
+ (bh_cofs >> blocksize_bits);
+ set_buffer_mapped(bh);
+ /*
+ * If the page is uptodate so is the buffer. If the
+ * buffer is fully outside the write, we ignore it if
+ * it was already allocated and we mark it dirty so it
+ * gets written out if we allocated it. On the other
+ * hand, if we allocated the buffer but we are not
+ * marking it dirty we set buffer_new so we can do
+ * error recovery.
+ */
+ if (PageUptodate(page)) {
+ if (!buffer_uptodate(bh))
+ set_buffer_uptodate(bh);
+ if (unlikely(was_hole)) {
+ /* We allocated the buffer. */
+ unmap_underlying_metadata(bh->b_bdev,
+ bh->b_blocknr);
+ if (bh_end <= pos || bh_pos >= end)
+ mark_buffer_dirty(bh);
+ else
+ set_buffer_new(bh);
+ }
+ continue;
+ }
+ /* Page is _not_ uptodate. */
+ if (likely(!was_hole)) {
+ /*
+ * Buffer was already allocated. If it is not
+ * uptodate and is only partially being written
+ * to, we need to read it in before the write,
+ * i.e. now.
+ */
+ if (!buffer_uptodate(bh) && bh_pos < end &&
+ bh_end > pos &&
+ (bh_pos < pos ||
+ bh_end > end)) {
+ /*
+ * If the buffer is fully or partially
+ * within the initialized size, do an
+ * actual read. Otherwise, simply zero
+ * the buffer.
+ */
+ read_lock_irqsave(&ni->size_lock,
+ flags);
+ initialized_size = ni->initialized_size;
+ read_unlock_irqrestore(&ni->size_lock,
+ flags);
+ if (bh_pos < initialized_size) {
+ ntfs_submit_bh_for_read(bh);
+ *wait_bh++ = bh;
+ } else {
+ u8 *kaddr = kmap_atomic(page,
+ KM_USER0);
+ memset(kaddr + bh_offset(bh),
+ 0, blocksize);
+ kunmap_atomic(kaddr, KM_USER0);
+ flush_dcache_page(page);
+ set_buffer_uptodate(bh);
+ }
+ }
+ continue;
+ }
+ /* We allocated the buffer. */
+ unmap_underlying_metadata(bh->b_bdev, bh->b_blocknr);
+ /*
+ * If the buffer is fully outside the write, zero it,
+ * set it uptodate, and mark it dirty so it gets
+ * written out. If it is partially being written to,
+ * zero region surrounding the write but leave it to
+ * commit write to do anything else. Finally, if the
+ * buffer is fully being overwritten, do nothing.
+ */
+ if (bh_end <= pos || bh_pos >= end) {
+ if (!buffer_uptodate(bh)) {
+ u8 *kaddr = kmap_atomic(page, KM_USER0);
+ memset(kaddr + bh_offset(bh), 0,
+ blocksize);
+ kunmap_atomic(kaddr, KM_USER0);
+ flush_dcache_page(page);
+ set_buffer_uptodate(bh);
+ }
+ mark_buffer_dirty(bh);
+ continue;
+ }
+ set_buffer_new(bh);
+ if (!buffer_uptodate(bh) &&
+ (bh_pos < pos || bh_end > end)) {
+ u8 *kaddr;
+ unsigned pofs;
+
+ kaddr = kmap_atomic(page, KM_USER0);
+ if (bh_pos < pos) {
+ pofs = bh_pos & ~PAGE_CACHE_MASK;
+ memset(kaddr + pofs, 0, pos - bh_pos);
+ }
+ if (bh_end > end) {
+ pofs = end & ~PAGE_CACHE_MASK;
+ memset(kaddr + pofs, 0, bh_end - end);
+ }
+ kunmap_atomic(kaddr, KM_USER0);
+ flush_dcache_page(page);
+ }
+ continue;
+ }
+ /*
+ * Slow path: this is the first buffer in the cluster. If it
+ * is outside allocated size and is not uptodate, zero it and
+ * set it uptodate.
+ */
+ read_lock_irqsave(&ni->size_lock, flags);
+ initialized_size = ni->allocated_size;
+ read_unlock_irqrestore(&ni->size_lock, flags);
+ if (bh_pos > initialized_size) {
+ if (PageUptodate(page)) {
+ if (!buffer_uptodate(bh))
+ set_buffer_uptodate(bh);
+ } else if (!buffer_uptodate(bh)) {
+ u8 *kaddr = kmap_atomic(page, KM_USER0);
+ memset(kaddr + bh_offset(bh), 0, blocksize);
+ kunmap_atomic(kaddr, KM_USER0);
+ flush_dcache_page(page);
+ set_buffer_uptodate(bh);
+ }
+ continue;
+ }
+ is_retry = FALSE;
+ if (!rl) {
+ down_read(&ni->runlist.lock);
+retry_remap:
+ rl = ni->runlist.rl;
+ }
+ if (likely(rl != NULL)) {
+ /* Seek to element containing target cluster. */
+ while (rl->length && rl[1].vcn <= bh_cpos)
+ rl++;
+ lcn = ntfs_rl_vcn_to_lcn(rl, bh_cpos);
+ if (likely(lcn >= 0)) {
+ /*
+ * Successful remap, setup the map cache and
+ * use that to deal with the buffer.
+ */
+ was_hole = FALSE;
+ vcn = bh_cpos;
+ vcn_len = rl[1].vcn - vcn;
+ lcn_block = lcn << (vol->cluster_size_bits -
+ blocksize_bits);
+ cdelta = 0;
+ /*
+ * If the number of remaining clusters touched
+ * by the write is smaller or equal to the
+ * number of cached clusters, unlock the
+ * runlist as the map cache will be used from
+ * now on.
+ */
+ if (likely(vcn + vcn_len >= cend)) {
+ if (rl_write_locked) {
+ up_write(&ni->runlist.lock);
+ rl_write_locked = FALSE;
+ } else
+ up_read(&ni->runlist.lock);
+ rl = NULL;
+ }
+ goto map_buffer_cached;
+ }
+ } else
+ lcn = LCN_RL_NOT_MAPPED;
+ /*
+ * If it is not a hole and not out of bounds, the runlist is
+ * probably unmapped so try to map it now.
+ */
+ if (unlikely(lcn != LCN_HOLE && lcn != LCN_ENOENT)) {
+ if (likely(!is_retry && lcn == LCN_RL_NOT_MAPPED)) {
+ /* Attempt to map runlist. */
+ if (!rl_write_locked) {
+ /*
+ * We need the runlist locked for
+ * writing, so if it is locked for
+ * reading relock it now and retry in
+ * case it changed whilst we dropped
+ * the lock.
+ */
+ up_read(&ni->runlist.lock);
+ down_write(&ni->runlist.lock);
+ rl_write_locked = TRUE;
+ goto retry_remap;
+ }
+ err = ntfs_map_runlist_nolock(ni, bh_cpos,
+ NULL);
+ if (likely(!err)) {
+ is_retry = TRUE;
+ goto retry_remap;
+ }
+ /*
+ * If @vcn is out of bounds, pretend @lcn is
+ * LCN_ENOENT. As long as the buffer is out
+ * of bounds this will work fine.
+ */
+ if (err == -ENOENT) {
+ lcn = LCN_ENOENT;
+ err = 0;
+ goto rl_not_mapped_enoent;
+ }
+ } else
+ err = -EIO;
+ /* Failed to map the buffer, even after retrying. */
+ bh->b_blocknr = -1;
+ ntfs_error(vol->sb, "Failed to write to inode 0x%lx, "
+ "attribute type 0x%x, vcn 0x%llx, "
+ "vcn offset 0x%x, because its "
+ "location on disk could not be "
+ "determined%s (error code %i).",
+ ni->mft_no, ni->type,
+ (unsigned long long)bh_cpos,
+ (unsigned)bh_pos &
+ vol->cluster_size_mask,
+ is_retry ? " even after retrying" : "",
+ err);
+ break;
+ }
+rl_not_mapped_enoent:
+ /*
+ * The buffer is in a hole or out of bounds. We need to fill
+ * the hole, unless the buffer is in a cluster which is not
+ * touched by the write, in which case we just leave the buffer
+ * unmapped. This can only happen when the cluster size is
+ * less than the page cache size.
+ */
+ if (unlikely(vol->cluster_size < PAGE_CACHE_SIZE)) {
+ bh_cend = (bh_end + vol->cluster_size - 1) >>
+ vol->cluster_size_bits;
+ if ((bh_cend <= cpos || bh_cpos >= cend)) {
+ bh->b_blocknr = -1;
+ /*
+ * If the buffer is uptodate we skip it. If it
+ * is not but the page is uptodate, we can set
+ * the buffer uptodate. If the page is not
+ * uptodate, we can clear the buffer and set it
+ * uptodate. Whether this is worthwhile is
+ * debatable and this could be removed.
+ */
+ if (PageUptodate(page)) {
+ if (!buffer_uptodate(bh))
+ set_buffer_uptodate(bh);
+ } else if (!buffer_uptodate(bh)) {
+ u8 *kaddr = kmap_atomic(page, KM_USER0);
+ memset(kaddr + bh_offset(bh), 0,
+ blocksize);
+ kunmap_atomic(kaddr, KM_USER0);
+ flush_dcache_page(page);
+ set_buffer_uptodate(bh);
+ }
+ continue;
+ }
+ }
+ /*
+ * Out of bounds buffer is invalid if it was not really out of
+ * bounds.
+ */
+ BUG_ON(lcn != LCN_HOLE);
+ /*
+ * We need the runlist locked for writing, so if it is locked
+ * for reading relock it now and retry in case it changed
+ * whilst we dropped the lock.
+ */
+ BUG_ON(!rl);
+ if (!rl_write_locked) {
+ up_read(&ni->runlist.lock);
+ down_write(&ni->runlist.lock);
+ rl_write_locked = TRUE;
+ goto retry_remap;
+ }
+ /* Find the previous last allocated cluster. */
+ BUG_ON(rl->lcn != LCN_HOLE);
+ lcn = -1;
+ rl2 = rl;
+ while (--rl2 >= ni->runlist.rl) {
+ if (rl2->lcn >= 0) {
+ lcn = rl2->lcn + rl2->length;
+ break;
+ }
+ }
+ rl2 = ntfs_cluster_alloc(vol, bh_cpos, 1, lcn, DATA_ZONE,
+ FALSE);
+ if (IS_ERR(rl2)) {
+ err = PTR_ERR(rl2);
+ ntfs_debug("Failed to allocate cluster, error code %i.",
+ err);
+ break;
+ }
+ lcn = rl2->lcn;
+ rl = ntfs_runlists_merge(ni->runlist.rl, rl2);
+ if (IS_ERR(rl)) {
+ err = PTR_ERR(rl);
+ if (err != -ENOMEM)
+ err = -EIO;
+ if (ntfs_cluster_free_from_rl(vol, rl2)) {
+ ntfs_error(vol->sb, "Failed to release "
+ "allocated cluster in error "
+ "code path. Run chkdsk to "
+ "recover the lost cluster.");
+ NVolSetErrors(vol);
+ }
+ ntfs_free(rl2);
+ break;
+ }
+ ni->runlist.rl = rl;
+ status.runlist_merged = 1;
+ ntfs_debug("Allocated cluster, lcn 0x%llx.", lcn);
+ /* Map and lock the mft record and get the attribute record. */
+ if (!NInoAttr(ni))
+ base_ni = ni;
+ else
+ base_ni = ni->ext.base_ntfs_ino;
+ m = map_mft_record(base_ni);
+ if (IS_ERR(m)) {
+ err = PTR_ERR(m);
+ break;
+ }
+ ctx = ntfs_attr_get_search_ctx(base_ni, m);
+ if (unlikely(!ctx)) {
+ err = -ENOMEM;
+ unmap_mft_record(base_ni);
+ break;
+ }
+ status.mft_attr_mapped = 1;
+ err = ntfs_attr_lookup(ni->type, ni->name, ni->name_len,
+ CASE_SENSITIVE, bh_cpos, NULL, 0, ctx);
+ if (unlikely(err)) {
+ if (err == -ENOENT)
+ err = -EIO;
+ break;
+ }
+ m = ctx->mrec;
+ a = ctx->attr;
+ /*
+ * Find the runlist element with which the attribute extent
+ * starts. Note, we cannot use the _attr_ version because we
+ * have mapped the mft record. That is ok because we know the
+ * runlist fragment must be mapped already to have ever gotten
+ * here, so we can just use the _rl_ version.
+ */
+ vcn = sle64_to_cpu(a->data.non_resident.lowest_vcn);
+ rl2 = ntfs_rl_find_vcn_nolock(rl, vcn);
+ BUG_ON(!rl2);
+ BUG_ON(!rl2->length);
+ BUG_ON(rl2->lcn < LCN_HOLE);
+ highest_vcn = sle64_to_cpu(a->data.non_resident.highest_vcn);
+ /*
+ * If @highest_vcn is zero, calculate the real highest_vcn
+ * (which can really be zero).
+ */
+ if (!highest_vcn)
+ highest_vcn = (sle64_to_cpu(
+ a->data.non_resident.allocated_size) >>
+ vol->cluster_size_bits) - 1;
+ /*
+ * Determine the size of the mapping pairs array for the new
+ * extent, i.e. the old extent with the hole filled.
+ */
+ mp_size = ntfs_get_size_for_mapping_pairs(vol, rl2, vcn,
+ highest_vcn);
+ if (unlikely(mp_size <= 0)) {
+ if (!(err = mp_size))
+ err = -EIO;
+ ntfs_debug("Failed to get size for mapping pairs "
+ "array, error code %i.", err);
+ break;
+ }
+ /*
+ * Resize the attribute record to fit the new mapping pairs
+ * array.
+ */
+ attr_rec_len = le32_to_cpu(a->length);
+ err = ntfs_attr_record_resize(m, a, mp_size + le16_to_cpu(
+ a->data.non_resident.mapping_pairs_offset));
+ if (unlikely(err)) {
+ BUG_ON(err != -ENOSPC);
+ // TODO: Deal with this by using the current attribute
+ // and fill it with as much of the mapping pairs
+ // array as possible. Then loop over each attribute
+ // extent rewriting the mapping pairs arrays as we go
+ // along and if when we reach the end we have not
+ // enough space, try to resize the last attribute
+ // extent and if even that fails, add a new attribute
+ // extent.
+ // We could also try to resize at each step in the hope
+ // that we will not need to rewrite every single extent.
+ // Note, we may need to decompress some extents to fill
+ // the runlist as we are walking the extents...
+ ntfs_error(vol->sb, "Not enough space in the mft "
+ "record for the extended attribute "
+ "record. This case is not "
+ "implemented yet.");
+ err = -EOPNOTSUPP;
+ break ;
+ }
+ status.mp_rebuilt = 1;
+ /*
+ * Generate the mapping pairs array directly into the attribute
+ * record.
+ */
+ err = ntfs_mapping_pairs_build(vol, (u8*)a + le16_to_cpu(
+ a->data.non_resident.mapping_pairs_offset),
+ mp_size, rl2, vcn, highest_vcn, NULL);
+ if (unlikely(err)) {
+ ntfs_error(vol->sb, "Cannot fill hole in inode 0x%lx, "
+ "attribute type 0x%x, because building "
+ "the mapping pairs failed with error "
+ "code %i.", vi->i_ino,
+ (unsigned)le32_to_cpu(ni->type), err);
+ err = -EIO;
+ break;
+ }
+ /* Update the highest_vcn but only if it was not set. */
+ if (unlikely(!a->data.non_resident.highest_vcn))
+ a->data.non_resident.highest_vcn =
+ cpu_to_sle64(highest_vcn);
+ /*
+ * If the attribute is sparse/compressed, update the compressed
+ * size in the ntfs_inode structure and the attribute record.
+ */
+ if (likely(NInoSparse(ni) || NInoCompressed(ni))) {
+ /*
+ * If we are not in the first attribute extent, switch
+ * to it, but first ensure the changes will make it to
+ * disk later.
+ */
+ if (a->data.non_resident.lowest_vcn) {
+ flush_dcache_mft_record_page(ctx->ntfs_ino);
+ mark_mft_record_dirty(ctx->ntfs_ino);
+ ntfs_attr_reinit_search_ctx(ctx);
+ err = ntfs_attr_lookup(ni->type, ni->name,
+ ni->name_len, CASE_SENSITIVE,
+ 0, NULL, 0, ctx);
+ if (unlikely(err)) {
+ status.attr_switched = 1;
+ break;
+ }
+ /* @m is not used any more so do not set it. */
+ a = ctx->attr;
+ }
+ write_lock_irqsave(&ni->size_lock, flags);
+ ni->itype.compressed.size += vol->cluster_size;
+ a->data.non_resident.compressed_size =
+ cpu_to_sle64(ni->itype.compressed.size);
+ write_unlock_irqrestore(&ni->size_lock, flags);
+ }
+ /* Ensure the changes make it to disk. */
+ flush_dcache_mft_record_page(ctx->ntfs_ino);
+ mark_mft_record_dirty(ctx->ntfs_ino);
+ ntfs_attr_put_search_ctx(ctx);
+ unmap_mft_record(base_ni);
+ /* Successfully filled the hole. */
+ status.runlist_merged = 0;
+ status.mft_attr_mapped = 0;
+ status.mp_rebuilt = 0;
+ /* Setup the map cache and use that to deal with the buffer. */
+ was_hole = TRUE;
+ vcn = bh_cpos;
+ vcn_len = 1;
+ lcn_block = lcn << (vol->cluster_size_bits - blocksize_bits);
+ cdelta = 0;
+ /*
+ * If the number of remaining clusters in the @pages is smaller
+ * or equal to the number of cached clusters, unlock the
+ * runlist as the map cache will be used from now on.
+ */
+ if (likely(vcn + vcn_len >= cend)) {
+ up_write(&ni->runlist.lock);
+ rl_write_locked = FALSE;
+ rl = NULL;
+ }
+ goto map_buffer_cached;
+ } while (bh_pos += blocksize, (bh = bh->b_this_page) != head);
+ /* If there are no errors, do the next page. */
+ if (likely(!err && ++u < nr_pages))
+ goto do_next_page;
+ /* If there are no errors, release the runlist lock if we took it. */
+ if (likely(!err)) {
+ if (unlikely(rl_write_locked)) {
+ up_write(&ni->runlist.lock);
+ rl_write_locked = FALSE;
+ } else if (unlikely(rl))
+ up_read(&ni->runlist.lock);
+ rl = NULL;
+ }
+ /* If we issued read requests, let them complete. */
+ read_lock_irqsave(&ni->size_lock, flags);
+ initialized_size = ni->initialized_size;
+ read_unlock_irqrestore(&ni->size_lock, flags);
+ while (wait_bh > wait) {
+ bh = *--wait_bh;
+ wait_on_buffer(bh);
+ if (likely(buffer_uptodate(bh))) {
+ page = bh->b_page;
+ bh_pos = ((s64)page->index << PAGE_CACHE_SHIFT) +
+ bh_offset(bh);
+ /*
+ * If the buffer overflows the initialized size, need
+ * to zero the overflowing region.
+ */
+ if (unlikely(bh_pos + blocksize > initialized_size)) {
+ u8 *kaddr;
+ int ofs = 0;
+
+ if (likely(bh_pos < initialized_size))
+ ofs = initialized_size - bh_pos;
+ kaddr = kmap_atomic(page, KM_USER0);
+ memset(kaddr + bh_offset(bh) + ofs, 0,
+ blocksize - ofs);
+ kunmap_atomic(kaddr, KM_USER0);
+ flush_dcache_page(page);
+ }
+ } else /* if (unlikely(!buffer_uptodate(bh))) */
+ err = -EIO;
+ }
+ if (likely(!err)) {
+ /* Clear buffer_new on all buffers. */
+ u = 0;
+ do {
+ bh = head = page_buffers(pages[u]);
+ do {
+ if (buffer_new(bh))
+ clear_buffer_new(bh);
+ } while ((bh = bh->b_this_page) != head);
+ } while (++u < nr_pages);
+ ntfs_debug("Done.");
+ return err;
+ }
+ if (status.attr_switched) {
+ /* Get back to the attribute extent we modified. */
+ ntfs_attr_reinit_search_ctx(ctx);
+ if (ntfs_attr_lookup(ni->type, ni->name, ni->name_len,
+ CASE_SENSITIVE, bh_cpos, NULL, 0, ctx)) {
+ ntfs_error(vol->sb, "Failed to find required "
+ "attribute extent of attribute in "
+ "error code path. Run chkdsk to "
+ "recover.");
+ write_lock_irqsave(&ni->size_lock, flags);
+ ni->itype.compressed.size += vol->cluster_size;
+ write_unlock_irqrestore(&ni->size_lock, flags);
+ flush_dcache_mft_record_page(ctx->ntfs_ino);
+ mark_mft_record_dirty(ctx->ntfs_ino);
+ /*
+ * The only thing that is now wrong is the compressed
+ * size of the base attribute extent which chkdsk
+ * should be able to fix.
+ */
+ NVolSetErrors(vol);
+ } else {
+ m = ctx->mrec;
+ a = ctx->attr;
+ status.attr_switched = 0;
+ }
+ }
+ /*
+ * If the runlist has been modified, need to restore it by punching a
+ * hole into it and we then need to deallocate the on-disk cluster as
+ * well. Note, we only modify the runlist if we are able to generate a
+ * new mapping pairs array, i.e. only when the mapped attribute extent
+ * is not switched.
+ */
+ if (status.runlist_merged && !status.attr_switched) {
+ BUG_ON(!rl_write_locked);
+ /* Make the file cluster we allocated sparse in the runlist. */
+ if (ntfs_rl_punch_nolock(vol, &ni->runlist, bh_cpos, 1)) {
+ ntfs_error(vol->sb, "Failed to punch hole into "
+ "attribute runlist in error code "
+ "path. Run chkdsk to recover the "
+ "lost cluster.");
+ make_bad_inode(vi);
+ make_bad_inode(VFS_I(base_ni));
+ NVolSetErrors(vol);
+ } else /* if (success) */ {
+ status.runlist_merged = 0;
+ /*
+ * Deallocate the on-disk cluster we allocated but only
+ * if we succeeded in punching its vcn out of the
+ * runlist.
+ */
+ down_write(&vol->lcnbmp_lock);
+ if (ntfs_bitmap_clear_bit(vol->lcnbmp_ino, lcn)) {
+ ntfs_error(vol->sb, "Failed to release "
+ "allocated cluster in error "
+ "code path. Run chkdsk to "
+ "recover the lost cluster.");
+ NVolSetErrors(vol);
+ }
+ up_write(&vol->lcnbmp_lock);
+ }
+ }
+ /*
+ * Resize the attribute record to its old size and rebuild the mapping
+ * pairs array. Note, we only can do this if the runlist has been
+ * restored to its old state which also implies that the mapped
+ * attribute extent is not switched.
+ */
+ if (status.mp_rebuilt && !status.runlist_merged) {
+ if (ntfs_attr_record_resize(m, a, attr_rec_len)) {
+ ntfs_error(vol->sb, "Failed to restore attribute "
+ "record in error code path. Run "
+ "chkdsk to recover.");
+ make_bad_inode(vi);
+ make_bad_inode(VFS_I(base_ni));
+ NVolSetErrors(vol);
+ } else /* if (success) */ {
+ if (ntfs_mapping_pairs_build(vol, (u8*)a +
+ le16_to_cpu(a->data.non_resident.
+ mapping_pairs_offset), attr_rec_len -
+ le16_to_cpu(a->data.non_resident.
+ mapping_pairs_offset), ni->runlist.rl,
+ vcn, highest_vcn, NULL)) {
+ ntfs_error(vol->sb, "Failed to restore "
+ "mapping pairs array in error "
+ "code path. Run chkdsk to "
+ "recover.");
+ make_bad_inode(vi);
+ make_bad_inode(VFS_I(base_ni));
+ NVolSetErrors(vol);
+ }
+ flush_dcache_mft_record_page(ctx->ntfs_ino);
+ mark_mft_record_dirty(ctx->ntfs_ino);
+ }
+ }
+ /* Release the mft record and the attribute. */
+ if (status.mft_attr_mapped) {
+ ntfs_attr_put_search_ctx(ctx);
+ unmap_mft_record(base_ni);
+ }
+ /* Release the runlist lock. */
+ if (rl_write_locked)
+ up_write(&ni->runlist.lock);
+ else if (rl)
+ up_read(&ni->runlist.lock);
+ /*
+ * Zero out any newly allocated blocks to avoid exposing stale data.
+ * If BH_New is set, we know that the block was newly allocated above
+ * and that it has not been fully zeroed and marked dirty yet.
+ */
+ nr_pages = u;
+ u = 0;
+ end = bh_cpos << vol->cluster_size_bits;
+ do {
+ page = pages[u];
+ bh = head = page_buffers(page);
+ do {
+ if (u == nr_pages &&
+ ((s64)page->index << PAGE_CACHE_SHIFT) +
+ bh_offset(bh) >= end)
+ break;
+ if (!buffer_new(bh))
+ continue;
+ clear_buffer_new(bh);
+ if (!buffer_uptodate(bh)) {
+ if (PageUptodate(page))
+ set_buffer_uptodate(bh);
+ else {
+ u8 *kaddr = kmap_atomic(page, KM_USER0);
+ memset(kaddr + bh_offset(bh), 0,
+ blocksize);
+ kunmap_atomic(kaddr, KM_USER0);
+ flush_dcache_page(page);
+ set_buffer_uptodate(bh);
+ }
+ }
+ mark_buffer_dirty(bh);
+ } while ((bh = bh->b_this_page) != head);
+ } while (++u <= nr_pages);
+ ntfs_error(vol->sb, "Failed. Returning error code %i.", err);
+ return err;
+}
+
+/*
+ * Copy as much as we can into the pages and return the number of bytes which
+ * were sucessfully copied. If a fault is encountered then clear the pages
+ * out to (ofs + bytes) and return the number of bytes which were copied.
+ */
+static inline size_t ntfs_copy_from_user(struct page **pages,
+ unsigned nr_pages, unsigned ofs, const char __user *buf,
+ size_t bytes)
+{
+ struct page **last_page = pages + nr_pages;
+ char *kaddr;
+ size_t total = 0;
+ unsigned len;
+ int left;
+
+ do {
+ len = PAGE_CACHE_SIZE - ofs;
+ if (len > bytes)
+ len = bytes;
+ kaddr = kmap_atomic(*pages, KM_USER0);
+ left = __copy_from_user_inatomic(kaddr + ofs, buf, len);
+ kunmap_atomic(kaddr, KM_USER0);
+ if (unlikely(left)) {
+ /* Do it the slow way. */
+ kaddr = kmap(*pages);
+ left = __copy_from_user(kaddr + ofs, buf, len);
+ kunmap(*pages);
+ if (unlikely(left))
+ goto err_out;
+ }
+ total += len;
+ bytes -= len;
+ if (!bytes)
+ break;
+ buf += len;
+ ofs = 0;
+ } while (++pages < last_page);
+out:
+ return total;
+err_out:
+ total += len - left;
+ /* Zero the rest of the target like __copy_from_user(). */
+ while (++pages < last_page) {
+ bytes -= len;
+ if (!bytes)
+ break;
+ len = PAGE_CACHE_SIZE;
+ if (len > bytes)
+ len = bytes;
+ kaddr = kmap_atomic(*pages, KM_USER0);
+ memset(kaddr, 0, len);
+ kunmap_atomic(kaddr, KM_USER0);
+ }
+ goto out;
+}
+
+static size_t __ntfs_copy_from_user_iovec(char *vaddr,
+ const struct iovec *iov, size_t iov_ofs, size_t bytes)
+{
+ size_t total = 0;
+
+ while (1) {
+ const char __user *buf = iov->iov_base + iov_ofs;
+ unsigned len;
+ size_t left;
+
+ len = iov->iov_len - iov_ofs;
+ if (len > bytes)
+ len = bytes;
+ left = __copy_from_user_inatomic(vaddr, buf, len);
+ total += len;
+ bytes -= len;
+ vaddr += len;
+ if (unlikely(left)) {
+ /*
+ * Zero the rest of the target like __copy_from_user().
+ */
+ memset(vaddr, 0, bytes);
+ total -= left;
+ break;
+ }
+ if (!bytes)
+ break;
+ iov++;
+ iov_ofs = 0;
+ }
+ return total;
+}
+
+static inline void ntfs_set_next_iovec(const struct iovec **iovp,
+ size_t *iov_ofsp, size_t bytes)
+{
+ const struct iovec *iov = *iovp;
+ size_t iov_ofs = *iov_ofsp;
+
+ while (bytes) {
+ unsigned len;
+
+ len = iov->iov_len - iov_ofs;
+ if (len > bytes)
+ len = bytes;
+ bytes -= len;
+ iov_ofs += len;
+ if (iov->iov_len == iov_ofs) {
+ iov++;
+ iov_ofs = 0;
+ }
+ }
+ *iovp = iov;
+ *iov_ofsp = iov_ofs;
+}
+
+/*
+ * This has the same side-effects and return value as ntfs_copy_from_user().
+ * The difference is that on a fault we need to memset the remainder of the
+ * pages (out to offset + bytes), to emulate ntfs_copy_from_user()'s
+ * single-segment behaviour.
+ *
+ * We call the same helper (__ntfs_copy_from_user_iovec()) both when atomic and
+ * when not atomic. This is ok because __ntfs_copy_from_user_iovec() calls
+ * __copy_from_user_inatomic() and it is ok to call this when non-atomic. In
+ * fact, the only difference between __copy_from_user_inatomic() and
+ * __copy_from_user() is that the latter calls might_sleep(). And on many
+ * architectures __copy_from_user_inatomic() is just defined to
+ * __copy_from_user() so it makes no difference at all on those architectures.
+ */
+static inline size_t ntfs_copy_from_user_iovec(struct page **pages,
+ unsigned nr_pages, unsigned ofs, const struct iovec **iov,
+ size_t *iov_ofs, size_t bytes)
+{
+ struct page **last_page = pages + nr_pages;
+ char *kaddr;
+ size_t copied, len, total = 0;
+
+ do {
+ len = PAGE_CACHE_SIZE - ofs;
+ if (len > bytes)
+ len = bytes;
+ kaddr = kmap_atomic(*pages, KM_USER0);
+ copied = __ntfs_copy_from_user_iovec(kaddr + ofs,
+ *iov, *iov_ofs, len);
+ kunmap_atomic(kaddr, KM_USER0);
+ if (unlikely(copied != len)) {
+ /* Do it the slow way. */
+ kaddr = kmap(*pages);
+ copied = __ntfs_copy_from_user_iovec(kaddr + ofs,
+ *iov, *iov_ofs, len);
+ kunmap(*pages);
+ if (unlikely(copied != len))
+ goto err_out;
+ }
+ total += len;
+ bytes -= len;
+ if (!bytes)
+ break;
+ ntfs_set_next_iovec(iov, iov_ofs, len);
+ ofs = 0;
+ } while (++pages < last_page);
+out:
+ return total;
+err_out:
+ total += copied;
+ /* Zero the rest of the target like __copy_from_user(). */
+ while (++pages < last_page) {
+ bytes -= len;
+ if (!bytes)
+ break;
+ len = PAGE_CACHE_SIZE;
+ if (len > bytes)
+ len = bytes;
+ kaddr = kmap_atomic(*pages, KM_USER0);
+ memset(kaddr, 0, len);
+ kunmap_atomic(kaddr, KM_USER0);
+ }
+ goto out;
+}
+
+static inline void ntfs_flush_dcache_pages(struct page **pages,
+ unsigned nr_pages)
+{
+ BUG_ON(!nr_pages);
+ do {
+ /*
+ * Warning: Do not do the decrement at the same time as the
+ * call because flush_dcache_page() is a NULL macro on i386
+ * and hence the decrement never happens.
+ */
+ flush_dcache_page(pages[nr_pages]);
+ } while (--nr_pages > 0);
+}
+
+/**
+ * ntfs_commit_pages_after_non_resident_write - commit the received data
+ * @pages: array of destination pages
+ * @nr_pages: number of pages in @pages
+ * @pos: byte position in file at which the write begins
+ * @bytes: number of bytes to be written
+ *
+ * See description of ntfs_commit_pages_after_write(), below.
+ */
+static inline int ntfs_commit_pages_after_non_resident_write(
+ struct page **pages, const unsigned nr_pages,
+ s64 pos, size_t bytes)
+{
+ s64 end, initialized_size;
+ struct inode *vi;
+ ntfs_inode *ni, *base_ni;
+ struct buffer_head *bh, *head;
+ ntfs_attr_search_ctx *ctx;
+ MFT_RECORD *m;
+ ATTR_RECORD *a;
+ unsigned long flags;
+ unsigned blocksize, u;
+ int err;
+
+ vi = pages[0]->mapping->host;
+ ni = NTFS_I(vi);
+ blocksize = 1 << vi->i_blkbits;
+ end = pos + bytes;
+ u = 0;
+ do {
+ s64 bh_pos;
+ struct page *page;
+ BOOL partial;
+
+ page = pages[u];
+ bh_pos = (s64)page->index << PAGE_CACHE_SHIFT;
+ bh = head = page_buffers(page);
+ partial = FALSE;
+ do {
+ s64 bh_end;
+
+ bh_end = bh_pos + blocksize;
+ if (bh_end <= pos || bh_pos >= end) {
+ if (!buffer_uptodate(bh))
+ partial = TRUE;
+ } else {
+ set_buffer_uptodate(bh);
+ mark_buffer_dirty(bh);
+ }
+ } while (bh_pos += blocksize, (bh = bh->b_this_page) != head);
+ /*
+ * If all buffers are now uptodate but the page is not, set the
+ * page uptodate.
+ */
+ if (!partial && !PageUptodate(page))
+ SetPageUptodate(page);
+ } while (++u < nr_pages);
+ /*
+ * Finally, if we do not need to update initialized_size or i_size we
+ * are finished.
+ */
+ read_lock_irqsave(&ni->size_lock, flags);
+ initialized_size = ni->initialized_size;
+ read_unlock_irqrestore(&ni->size_lock, flags);
+ if (end <= initialized_size) {
+ ntfs_debug("Done.");
+ return 0;
+ }
+ /*
+ * Update initialized_size/i_size as appropriate, both in the inode and
+ * the mft record.
+ */
+ if (!NInoAttr(ni))
+ base_ni = ni;
+ else
+ base_ni = ni->ext.base_ntfs_ino;
+ /* Map, pin, and lock the mft record. */
+ m = map_mft_record(base_ni);
+ if (IS_ERR(m)) {
+ err = PTR_ERR(m);
+ m = NULL;
+ ctx = NULL;
+ goto err_out;
+ }
+ BUG_ON(!NInoNonResident(ni));
+ ctx = ntfs_attr_get_search_ctx(base_ni, m);
+ if (unlikely(!ctx)) {
+ err = -ENOMEM;
+ goto err_out;
+ }
+ err = ntfs_attr_lookup(ni->type, ni->name, ni->name_len,
+ CASE_SENSITIVE, 0, NULL, 0, ctx);
+ if (unlikely(err)) {
+ if (err == -ENOENT)
+ err = -EIO;
+ goto err_out;
+ }
+ a = ctx->attr;
+ BUG_ON(!a->non_resident);
+ write_lock_irqsave(&ni->size_lock, flags);
+ BUG_ON(end > ni->allocated_size);
+ ni->initialized_size = end;
+ a->data.non_resident.initialized_size = cpu_to_sle64(end);
+ if (end > i_size_read(vi)) {
+ i_size_write(vi, end);
+ a->data.non_resident.data_size =
+ a->data.non_resident.initialized_size;
+ }
+ write_unlock_irqrestore(&ni->size_lock, flags);
+ /* Mark the mft record dirty, so it gets written back. */
+ flush_dcache_mft_record_page(ctx->ntfs_ino);
+ mark_mft_record_dirty(ctx->ntfs_ino);
+ ntfs_attr_put_search_ctx(ctx);
+ unmap_mft_record(base_ni);
+ ntfs_debug("Done.");
+ return 0;
+err_out:
+ if (ctx)
+ ntfs_attr_put_search_ctx(ctx);
+ if (m)
+ unmap_mft_record(base_ni);
+ ntfs_error(vi->i_sb, "Failed to update initialized_size/i_size (error "
+ "code %i).", err);
+ if (err != -ENOMEM) {
+ NVolSetErrors(ni->vol);
+ make_bad_inode(VFS_I(base_ni));
+ make_bad_inode(vi);
+ }
+ return err;
+}
+
+/**
+ * ntfs_commit_pages_after_write - commit the received data
+ * @pages: array of destination pages
+ * @nr_pages: number of pages in @pages
+ * @pos: byte position in file at which the write begins
+ * @bytes: number of bytes to be written
+ *
+ * This is called from ntfs_file_buffered_write() with i_sem held on the inode
+ * (@pages[0]->mapping->host). There are @nr_pages pages in @pages which are
+ * locked but not kmap()ped. The source data has already been copied into the
+ * @page. ntfs_prepare_pages_for_non_resident_write() has been called before
+ * the data was copied (for non-resident attributes only) and it returned
+ * success.
+ *
+ * Need to set uptodate and mark dirty all buffers within the boundary of the
+ * write. If all buffers in a page are uptodate we set the page uptodate, too.
+ *
+ * Setting the buffers dirty ensures that they get written out later when
+ * ntfs_writepage() is invoked by the VM.
+ *
+ * Finally, we need to update i_size and initialized_size as appropriate both
+ * in the inode and the mft record.
+ *
+ * This is modelled after fs/buffer.c::generic_commit_write(), which marks
+ * buffers uptodate and dirty, sets the page uptodate if all buffers in the
+ * page are uptodate, and updates i_size if the end of io is beyond i_size. In
+ * that case, it also marks the inode dirty.
+ *
+ * If things have gone as outlined in
+ * ntfs_prepare_pages_for_non_resident_write(), we do not need to do any page
+ * content modifications here for non-resident attributes. For resident
+ * attributes we need to do the uptodate bringing here which we combine with
+ * the copying into the mft record which means we save one atomic kmap.
+ *
+ * Return 0 on success or -errno on error.
+ */
+static int ntfs_commit_pages_after_write(struct page **pages,
+ const unsigned nr_pages, s64 pos, size_t bytes)
+{
+ s64 end, initialized_size;
+ loff_t i_size;
+ struct inode *vi;
+ ntfs_inode *ni, *base_ni;
+ struct page *page;
+ ntfs_attr_search_ctx *ctx;
+ MFT_RECORD *m;
+ ATTR_RECORD *a;
+ char *kattr, *kaddr;
+ unsigned long flags;
+ u32 attr_len;
+ int err;
+
+ BUG_ON(!nr_pages);
+ BUG_ON(!pages);
+ page = pages[0];
+ BUG_ON(!page);
+ vi = page->mapping->host;
+ ni = NTFS_I(vi);
+ ntfs_debug("Entering for inode 0x%lx, attribute type 0x%x, start page "
+ "index 0x%lx, nr_pages 0x%x, pos 0x%llx, bytes 0x%zx.",
+ vi->i_ino, ni->type, page->index, nr_pages,
+ (long long)pos, bytes);
+ if (NInoNonResident(ni))
+ return ntfs_commit_pages_after_non_resident_write(pages,
+ nr_pages, pos, bytes);
+ BUG_ON(nr_pages > 1);
+ /*
+ * Attribute is resident, implying it is not compressed, encrypted, or
+ * sparse.
+ */
+ if (!NInoAttr(ni))
+ base_ni = ni;
+ else
+ base_ni = ni->ext.base_ntfs_ino;
+ BUG_ON(NInoNonResident(ni));
+ /* Map, pin, and lock the mft record. */
+ m = map_mft_record(base_ni);
+ if (IS_ERR(m)) {
+ err = PTR_ERR(m);
+ m = NULL;
+ ctx = NULL;
+ goto err_out;
+ }
+ ctx = ntfs_attr_get_search_ctx(base_ni, m);
+ if (unlikely(!ctx)) {
+ err = -ENOMEM;
+ goto err_out;
+ }
+ err = ntfs_attr_lookup(ni->type, ni->name, ni->name_len,
+ CASE_SENSITIVE, 0, NULL, 0, ctx);
+ if (unlikely(err)) {
+ if (err == -ENOENT)
+ err = -EIO;
+ goto err_out;
+ }
+ a = ctx->attr;
+ BUG_ON(a->non_resident);
+ /* The total length of the attribute value. */
+ attr_len = le32_to_cpu(a->data.resident.value_length);
+ i_size = i_size_read(vi);
+ BUG_ON(attr_len != i_size);
+ BUG_ON(pos > attr_len);
+ end = pos + bytes;
+ BUG_ON(end > le32_to_cpu(a->length) -
+ le16_to_cpu(a->data.resident.value_offset));
+ kattr = (u8*)a + le16_to_cpu(a->data.resident.value_offset);
+ kaddr = kmap_atomic(page, KM_USER0);
+ /* Copy the received data from the page to the mft record. */
+ memcpy(kattr + pos, kaddr + pos, bytes);
+ /* Update the attribute length if necessary. */
+ if (end > attr_len) {
+ attr_len = end;
+ a->data.resident.value_length = cpu_to_le32(attr_len);
+ }
+ /*
+ * If the page is not uptodate, bring the out of bounds area(s)
+ * uptodate by copying data from the mft record to the page.
+ */
+ if (!PageUptodate(page)) {
+ if (pos > 0)
+ memcpy(kaddr, kattr, pos);
+ if (end < attr_len)
+ memcpy(kaddr + end, kattr + end, attr_len - end);
+ /* Zero the region outside the end of the attribute value. */
+ memset(kaddr + attr_len, 0, PAGE_CACHE_SIZE - attr_len);
+ flush_dcache_page(page);
+ SetPageUptodate(page);
+ }
+ kunmap_atomic(kaddr, KM_USER0);
+ /* Update initialized_size/i_size if necessary. */
+ read_lock_irqsave(&ni->size_lock, flags);
+ initialized_size = ni->initialized_size;
+ BUG_ON(end > ni->allocated_size);
+ read_unlock_irqrestore(&ni->size_lock, flags);
+ BUG_ON(initialized_size != i_size);
+ if (end > initialized_size) {
+ unsigned long flags;
+
+ write_lock_irqsave(&ni->size_lock, flags);
+ ni->initialized_size = end;
+ i_size_write(vi, end);
+ write_unlock_irqrestore(&ni->size_lock, flags);
+ }
+ /* Mark the mft record dirty, so it gets written back. */
+ flush_dcache_mft_record_page(ctx->ntfs_ino);
+ mark_mft_record_dirty(ctx->ntfs_ino);
+ ntfs_attr_put_search_ctx(ctx);
+ unmap_mft_record(base_ni);
+ ntfs_debug("Done.");
+ return 0;
+err_out:
+ if (err == -ENOMEM) {
+ ntfs_warning(vi->i_sb, "Error allocating memory required to "
+ "commit the write.");
+ if (PageUptodate(page)) {
+ ntfs_warning(vi->i_sb, "Page is uptodate, setting "
+ "dirty so the write will be retried "
+ "later on by the VM.");
+ /*
+ * Put the page on mapping->dirty_pages, but leave its
+ * buffers' dirty state as-is.
+ */
+ __set_page_dirty_nobuffers(page);
+ err = 0;
+ } else
+ ntfs_error(vi->i_sb, "Page is not uptodate. Written "
+ "data has been lost.");
+ } else {
+ ntfs_error(vi->i_sb, "Resident attribute commit write failed "
+ "with error %i.", err);
+ NVolSetErrors(ni->vol);
+ make_bad_inode(VFS_I(base_ni));
+ make_bad_inode(vi);
+ }
+ if (ctx)
+ ntfs_attr_put_search_ctx(ctx);
+ if (m)
+ unmap_mft_record(base_ni);
+ return err;
+}
+
+/**
+ * ntfs_file_buffered_write -
+ *
+ * Locking: The vfs is holding ->i_sem on the inode.
+ */
+static ssize_t ntfs_file_buffered_write(struct kiocb *iocb,
+ const struct iovec *iov, unsigned long nr_segs,
+ loff_t pos, loff_t *ppos, size_t count)
+{
+ struct file *file = iocb->ki_filp;
+ struct address_space *mapping = file->f_mapping;
+ struct inode *vi = mapping->host;
+ ntfs_inode *ni = NTFS_I(vi);
+ ntfs_volume *vol = ni->vol;
+ struct page *pages[NTFS_MAX_PAGES_PER_CLUSTER];
+ struct page *cached_page = NULL;
+ char __user *buf = NULL;
+ s64 end, ll;
+ VCN last_vcn;
+ LCN lcn;
+ unsigned long flags;
+ size_t bytes, iov_ofs = 0; /* Offset in the current iovec. */
+ ssize_t status, written;
+ unsigned nr_pages;
+ int err;
+ struct pagevec lru_pvec;
+
+ ntfs_debug("Entering for i_ino 0x%lx, attribute type 0x%x, "
+ "pos 0x%llx, count 0x%lx.",
+ vi->i_ino, (unsigned)le32_to_cpu(ni->type),
+ (unsigned long long)pos, (unsigned long)count);
+ if (unlikely(!count))
+ return 0;
+ BUG_ON(NInoMstProtected(ni));
+ /*
+ * If the attribute is not an index root and it is encrypted or
+ * compressed, we cannot write to it yet. Note we need to check for
+ * AT_INDEX_ALLOCATION since this is the type of both directory and
+ * index inodes.
+ */
+ if (ni->type != AT_INDEX_ALLOCATION) {
+ /* If file is encrypted, deny access, just like NT4. */
+ if (NInoEncrypted(ni)) {
+ /*
+ * Reminder for later: Encrypted files are _always_
+ * non-resident so that the content can always be
+ * encrypted.
+ */
+ ntfs_debug("Denying write access to encrypted file.");
+ return -EACCES;
+ }
+ if (NInoCompressed(ni)) {
+ /* Only unnamed $DATA attribute can be compressed. */
+ BUG_ON(ni->type != AT_DATA);
+ BUG_ON(ni->name_len);
+ /*
+ * Reminder for later: If resident, the data is not
+ * actually compressed. Only on the switch to non-
+ * resident does compression kick in. This is in
+ * contrast to encrypted files (see above).
+ */
+ ntfs_error(vi->i_sb, "Writing to compressed files is "
+ "not implemented yet. Sorry.");
+ return -EOPNOTSUPP;
+ }
+ }
+ /*
+ * If a previous ntfs_truncate() failed, repeat it and abort if it
+ * fails again.
+ */
+ if (unlikely(NInoTruncateFailed(ni))) {
+ down_write(&vi->i_alloc_sem);
+ err = ntfs_truncate(vi);
+ up_write(&vi->i_alloc_sem);
+ if (err || NInoTruncateFailed(ni)) {
+ if (!err)
+ err = -EIO;
+ ntfs_error(vol->sb, "Cannot perform write to inode "
+ "0x%lx, attribute type 0x%x, because "
+ "ntfs_truncate() failed (error code "
+ "%i).", vi->i_ino,
+ (unsigned)le32_to_cpu(ni->type), err);
+ return err;
+ }
+ }
+ /* The first byte after the write. */
+ end = pos + count;
+ /*
+ * If the write goes beyond the allocated size, extend the allocation
+ * to cover the whole of the write, rounded up to the nearest cluster.
+ */
+ read_lock_irqsave(&ni->size_lock, flags);
+ ll = ni->allocated_size;
+ read_unlock_irqrestore(&ni->size_lock, flags);
+ if (end > ll) {
+ /* Extend the allocation without changing the data size. */
+ ll = ntfs_attr_extend_allocation(ni, end, -1, pos);
+ if (likely(ll >= 0)) {
+ BUG_ON(pos >= ll);
+ /* If the extension was partial truncate the write. */
+ if (end > ll) {
+ ntfs_debug("Truncating write to inode 0x%lx, "
+ "attribute type 0x%x, because "
+ "the allocation was only "
+ "partially extended.",
+ vi->i_ino, (unsigned)
+ le32_to_cpu(ni->type));
+ end = ll;
+ count = ll - pos;
+ }
+ } else {
+ err = ll;
+ read_lock_irqsave(&ni->size_lock, flags);
+ ll = ni->allocated_size;
+ read_unlock_irqrestore(&ni->size_lock, flags);
+ /* Perform a partial write if possible or fail. */
+ if (pos < ll) {
+ ntfs_debug("Truncating write to inode 0x%lx, "
+ "attribute type 0x%x, because "
+ "extending the allocation "
+ "failed (error code %i).",
+ vi->i_ino, (unsigned)
+ le32_to_cpu(ni->type), err);
+ end = ll;
+ count = ll - pos;
+ } else {
+ ntfs_error(vol->sb, "Cannot perform write to "
+ "inode 0x%lx, attribute type "
+ "0x%x, because extending the "
+ "allocation failed (error "
+ "code %i).", vi->i_ino,
+ (unsigned)
+ le32_to_cpu(ni->type), err);
+ return err;
+ }
+ }
+ }
+ pagevec_init(&lru_pvec, 0);
+ written = 0;
+ /*
+ * If the write starts beyond the initialized size, extend it up to the
+ * beginning of the write and initialize all non-sparse space between
+ * the old initialized size and the new one. This automatically also
+ * increments the vfs inode->i_size to keep it above or equal to the
+ * initialized_size.
+ */
+ read_lock_irqsave(&ni->size_lock, flags);
+ ll = ni->initialized_size;
+ read_unlock_irqrestore(&ni->size_lock, flags);
+ if (pos > ll) {
+ err = ntfs_attr_extend_initialized(ni, pos, &cached_page,
+ &lru_pvec);
+ if (err < 0) {
+ ntfs_error(vol->sb, "Cannot perform write to inode "
+ "0x%lx, attribute type 0x%x, because "
+ "extending the initialized size "
+ "failed (error code %i).", vi->i_ino,
+ (unsigned)le32_to_cpu(ni->type), err);
+ status = err;
+ goto err_out;
+ }
+ }
+ /*
+ * Determine the number of pages per cluster for non-resident
+ * attributes.
+ */
+ nr_pages = 1;
+ if (vol->cluster_size > PAGE_CACHE_SIZE && NInoNonResident(ni))
+ nr_pages = vol->cluster_size >> PAGE_CACHE_SHIFT;
+ /* Finally, perform the actual write. */
+ last_vcn = -1;
+ if (likely(nr_segs == 1))
+ buf = iov->iov_base;
+ do {
+ VCN vcn;
+ pgoff_t idx, start_idx;
+ unsigned ofs, do_pages, u;
+ size_t copied;
+
+ start_idx = idx = pos >> PAGE_CACHE_SHIFT;
+ ofs = pos & ~PAGE_CACHE_MASK;
+ bytes = PAGE_CACHE_SIZE - ofs;
+ do_pages = 1;
+ if (nr_pages > 1) {
+ vcn = pos >> vol->cluster_size_bits;
+ if (vcn != last_vcn) {
+ last_vcn = vcn;
+ /*
+ * Get the lcn of the vcn the write is in. If
+ * it is a hole, need to lock down all pages in
+ * the cluster.
+ */
+ down_read(&ni->runlist.lock);
+ lcn = ntfs_attr_vcn_to_lcn_nolock(ni, pos >>
+ vol->cluster_size_bits, FALSE);
+ up_read(&ni->runlist.lock);
+ if (unlikely(lcn < LCN_HOLE)) {
+ status = -EIO;
+ if (lcn == LCN_ENOMEM)
+ status = -ENOMEM;
+ else
+ ntfs_error(vol->sb, "Cannot "
+ "perform write to "
+ "inode 0x%lx, "
+ "attribute type 0x%x, "
+ "because the attribute "
+ "is corrupt.",
+ vi->i_ino, (unsigned)
+ le32_to_cpu(ni->type));
+ break;
+ }
+ if (lcn == LCN_HOLE) {
+ start_idx = (pos & ~(s64)
+ vol->cluster_size_mask)
+ >> PAGE_CACHE_SHIFT;
+ bytes = vol->cluster_size - (pos &
+ vol->cluster_size_mask);
+ do_pages = nr_pages;
+ }
+ }
+ }
+ if (bytes > count)
+ bytes = count;
+ /*
+ * Bring in the user page(s) that we will copy from _first_.
+ * Otherwise there is a nasty deadlock on copying from the same
+ * page(s) as we are writing to, without it/them being marked
+ * up-to-date. Note, at present there is nothing to stop the
+ * pages being swapped out between us bringing them into memory
+ * and doing the actual copying.
+ */
+ if (likely(nr_segs == 1))
+ ntfs_fault_in_pages_readable(buf, bytes);
+ else
+ ntfs_fault_in_pages_readable_iovec(iov, iov_ofs, bytes);
+ /* Get and lock @do_pages starting at index @start_idx. */
+ status = __ntfs_grab_cache_pages(mapping, start_idx, do_pages,
+ pages, &cached_page, &lru_pvec);
+ if (unlikely(status))
+ break;
+ /*
+ * For non-resident attributes, we need to fill any holes with
+ * actual clusters and ensure all bufferes are mapped. We also
+ * need to bring uptodate any buffers that are only partially
+ * being written to.
+ */
+ if (NInoNonResident(ni)) {
+ status = ntfs_prepare_pages_for_non_resident_write(
+ pages, do_pages, pos, bytes);
+ if (unlikely(status)) {
+ loff_t i_size;
+
+ do {
+ unlock_page(pages[--do_pages]);
+ page_cache_release(pages[do_pages]);
+ } while (do_pages);
+ /*
+ * The write preparation may have instantiated
+ * allocated space outside i_size. Trim this
+ * off again. We can ignore any errors in this
+ * case as we will just be waisting a bit of
+ * allocated space, which is not a disaster.
+ */
+ i_size = i_size_read(vi);
+ if (pos + bytes > i_size)
+ vmtruncate(vi, i_size);
+ break;
+ }
+ }
+ u = (pos >> PAGE_CACHE_SHIFT) - pages[0]->index;
+ if (likely(nr_segs == 1)) {
+ copied = ntfs_copy_from_user(pages + u, do_pages - u,
+ ofs, buf, bytes);
+ buf += copied;
+ } else
+ copied = ntfs_copy_from_user_iovec(pages + u,
+ do_pages - u, ofs, &iov, &iov_ofs,
+ bytes);
+ ntfs_flush_dcache_pages(pages + u, do_pages - u);
+ status = ntfs_commit_pages_after_write(pages, do_pages, pos,
+ bytes);
+ if (likely(!status)) {
+ written += copied;
+ count -= copied;
+ pos += copied;
+ if (unlikely(copied != bytes))
+ status = -EFAULT;
+ }
+ do {
+ unlock_page(pages[--do_pages]);
+ mark_page_accessed(pages[do_pages]);
+ page_cache_release(pages[do_pages]);
+ } while (do_pages);
+ if (unlikely(status))
+ break;
+ balance_dirty_pages_ratelimited(mapping);
+ cond_resched();
+ } while (count);
+err_out:
+ *ppos = pos;
+ if (cached_page)
+ page_cache_release(cached_page);
+ /* For now, when the user asks for O_SYNC, we actually give O_DSYNC. */
+ if (likely(!status)) {
+ if (unlikely((file->f_flags & O_SYNC) || IS_SYNC(vi))) {
+ if (!mapping->a_ops->writepage || !is_sync_kiocb(iocb))
+ status = generic_osync_inode(vi, mapping,
+ OSYNC_METADATA|OSYNC_DATA);
+ }
+ }
+ pagevec_lru_add(&lru_pvec);
+ ntfs_debug("Done. Returning %s (written 0x%lx, status %li).",
+ written ? "written" : "status", (unsigned long)written,
+ (long)status);
+ return written ? written : status;
+}
+
+/**
+ * ntfs_file_aio_write_nolock -
+ */
+static ssize_t ntfs_file_aio_write_nolock(struct kiocb *iocb,
+ const struct iovec *iov, unsigned long nr_segs, loff_t *ppos)
+{
+ struct file *file = iocb->ki_filp;
+ struct address_space *mapping = file->f_mapping;
+ struct inode *inode = mapping->host;
+ loff_t pos;
+ unsigned long seg;
+ size_t count; /* after file limit checks */
+ ssize_t written, err;
+
+ count = 0;
+ for (seg = 0; seg < nr_segs; seg++) {
+ const struct iovec *iv = &iov[seg];
+ /*
+ * If any segment has a negative length, or the cumulative
+ * length ever wraps negative then return -EINVAL.
+ */
+ count += iv->iov_len;
+ if (unlikely((ssize_t)(count|iv->iov_len) < 0))
+ return -EINVAL;
+ if (access_ok(VERIFY_READ, iv->iov_base, iv->iov_len))
+ continue;
+ if (!seg)
+ return -EFAULT;
+ nr_segs = seg;
+ count -= iv->iov_len; /* This segment is no good */
+ break;
+ }
+ pos = *ppos;
+ vfs_check_frozen(inode->i_sb, SB_FREEZE_WRITE);
+ /* We can write back this queue in page reclaim. */
+ current->backing_dev_info = mapping->backing_dev_info;
+ written = 0;
+ err = generic_write_checks(file, &pos, &count, S_ISBLK(inode->i_mode));
+ if (err)
+ goto out;
+ if (!count)
+ goto out;
+ err = remove_suid(file->f_dentry);
+ if (err)
+ goto out;
+ inode_update_time(inode, 1);
+ written = ntfs_file_buffered_write(iocb, iov, nr_segs, pos, ppos,
+ count);
+out:
+ current->backing_dev_info = NULL;
+ return written ? written : err;
+}
+
+/**
+ * ntfs_file_aio_write -
+ */
+static ssize_t ntfs_file_aio_write(struct kiocb *iocb, const char __user *buf,
+ size_t count, loff_t pos)
+{
+ struct file *file = iocb->ki_filp;
+ struct address_space *mapping = file->f_mapping;
+ struct inode *inode = mapping->host;
+ ssize_t ret;
+ struct iovec local_iov = { .iov_base = (void __user *)buf,
+ .iov_len = count };
+
+ BUG_ON(iocb->ki_pos != pos);
+
+ down(&inode->i_sem);
+ ret = ntfs_file_aio_write_nolock(iocb, &local_iov, 1, &iocb->ki_pos);
+ up(&inode->i_sem);
+ if (ret > 0 && ((file->f_flags & O_SYNC) || IS_SYNC(inode))) {
+ int err = sync_page_range(inode, mapping, pos, ret);
+ if (err < 0)
+ ret = err;
+ }
+ return ret;
+}
+
+/**
+ * ntfs_file_writev -
+ *
+ * Basically the same as generic_file_writev() except that it ends up calling
+ * ntfs_file_aio_write_nolock() instead of __generic_file_aio_write_nolock().
+ */
+static ssize_t ntfs_file_writev(struct file *file, const struct iovec *iov,
+ unsigned long nr_segs, loff_t *ppos)
+{
+ struct address_space *mapping = file->f_mapping;
+ struct inode *inode = mapping->host;
+ struct kiocb kiocb;
+ ssize_t ret;
+
+ down(&inode->i_sem);
+ init_sync_kiocb(&kiocb, file);
+ ret = ntfs_file_aio_write_nolock(&kiocb, iov, nr_segs, ppos);
+ if (ret == -EIOCBQUEUED)
+ ret = wait_on_sync_kiocb(&kiocb);
+ up(&inode->i_sem);
+ if (ret > 0 && ((file->f_flags & O_SYNC) || IS_SYNC(inode))) {
+ int err = sync_page_range(inode, mapping, *ppos - ret, ret);
+ if (err < 0)
+ ret = err;
+ }
+ return ret;
+}
+
+/**
+ * ntfs_file_write - simple wrapper for ntfs_file_writev()
+ */
+static ssize_t ntfs_file_write(struct file *file, const char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ struct iovec local_iov = { .iov_base = (void __user *)buf,
+ .iov_len = count };
+
+ return ntfs_file_writev(file, &local_iov, 1, ppos);
+}
+
+/**
* ntfs_file_fsync - sync a file to disk
* @filp: file to be synced
* @dentry: dentry describing the file to sync
@@ -113,39 +2305,39 @@ static int ntfs_file_fsync(struct file *filp, struct dentry *dentry,
#endif /* NTFS_RW */
struct file_operations ntfs_file_ops = {
- .llseek = generic_file_llseek, /* Seek inside file. */
- .read = generic_file_read, /* Read from file. */
- .aio_read = generic_file_aio_read, /* Async read from file. */
- .readv = generic_file_readv, /* Read from file. */
+ .llseek = generic_file_llseek, /* Seek inside file. */
+ .read = generic_file_read, /* Read from file. */
+ .aio_read = generic_file_aio_read, /* Async read from file. */
+ .readv = generic_file_readv, /* Read from file. */
#ifdef NTFS_RW
- .write = generic_file_write, /* Write to file. */
- .aio_write = generic_file_aio_write, /* Async write to file. */
- .writev = generic_file_writev, /* Write to file. */
- /*.release = ,*/ /* Last file is closed. See
- fs/ext2/file.c::
- ext2_release_file() for
- how to use this to discard
- preallocated space for
- write opened files. */
- .fsync = ntfs_file_fsync, /* Sync a file to disk. */
- /*.aio_fsync = ,*/ /* Sync all outstanding async
- i/o operations on a
- kiocb. */
+ .write = ntfs_file_write, /* Write to file. */
+ .aio_write = ntfs_file_aio_write, /* Async write to file. */
+ .writev = ntfs_file_writev, /* Write to file. */
+ /*.release = ,*/ /* Last file is closed. See
+ fs/ext2/file.c::
+ ext2_release_file() for
+ how to use this to discard
+ preallocated space for
+ write opened files. */
+ .fsync = ntfs_file_fsync, /* Sync a file to disk. */
+ /*.aio_fsync = ,*/ /* Sync all outstanding async
+ i/o operations on a
+ kiocb. */
#endif /* NTFS_RW */
- /*.ioctl = ,*/ /* Perform function on the
- mounted filesystem. */
- .mmap = generic_file_mmap, /* Mmap file. */
- .open = ntfs_file_open, /* Open file. */
- .sendfile = generic_file_sendfile, /* Zero-copy data send with
- the data source being on
- the ntfs partition. We
- do not need to care about
- the data destination. */
- /*.sendpage = ,*/ /* Zero-copy data send with
- the data destination being
- on the ntfs partition. We
- do not need to care about
- the data source. */
+ /*.ioctl = ,*/ /* Perform function on the
+ mounted filesystem. */
+ .mmap = generic_file_mmap, /* Mmap file. */
+ .open = ntfs_file_open, /* Open file. */
+ .sendfile = generic_file_sendfile, /* Zero-copy data send with
+ the data source being on
+ the ntfs partition. We do
+ not need to care about the
+ data destination. */
+ /*.sendpage = ,*/ /* Zero-copy data send with
+ the data destination being
+ on the ntfs partition. We
+ do not need to care about
+ the data source. */
};
struct inode_operations ntfs_file_inode_ops = {
diff --git a/fs/ntfs/inode.c b/fs/ntfs/inode.c
index 7ec045131808..b24f4c4b2c5c 100644
--- a/fs/ntfs/inode.c
+++ b/fs/ntfs/inode.c
@@ -30,6 +30,7 @@
#include "debug.h"
#include "inode.h"
#include "attrib.h"
+#include "lcnalloc.h"
#include "malloc.h"
#include "mft.h"
#include "time.h"
@@ -2291,11 +2292,16 @@ int ntfs_show_options(struct seq_file *sf, struct vfsmount *mnt)
#ifdef NTFS_RW
+static const char *es = " Leaving inconsistent metadata. Unmount and run "
+ "chkdsk.";
+
/**
* ntfs_truncate - called when the i_size of an ntfs inode is changed
* @vi: inode for which the i_size was changed
*
- * We do not support i_size changes yet.
+ * We only support i_size changes for normal files at present, i.e. not
+ * compressed and not encrypted. This is enforced in ntfs_setattr(), see
+ * below.
*
* The kernel guarantees that @vi is a regular file (S_ISREG() is true) and
* that the change is allowed.
@@ -2306,80 +2312,499 @@ int ntfs_show_options(struct seq_file *sf, struct vfsmount *mnt)
* Returns 0 on success or -errno on error.
*
* Called with ->i_sem held. In all but one case ->i_alloc_sem is held for
- * writing. The only case where ->i_alloc_sem is not held is
+ * writing. The only case in the kernel where ->i_alloc_sem is not held is
* mm/filemap.c::generic_file_buffered_write() where vmtruncate() is called
- * with the current i_size as the offset which means that it is a noop as far
- * as ntfs_truncate() is concerned.
+ * with the current i_size as the offset. The analogous place in NTFS is in
+ * fs/ntfs/file.c::ntfs_file_buffered_write() where we call vmtruncate() again
+ * without holding ->i_alloc_sem.
*/
int ntfs_truncate(struct inode *vi)
{
- ntfs_inode *ni = NTFS_I(vi);
+ s64 new_size, old_size, nr_freed, new_alloc_size, old_alloc_size;
+ VCN highest_vcn;
+ unsigned long flags;
+ ntfs_inode *base_ni, *ni = NTFS_I(vi);
ntfs_volume *vol = ni->vol;
ntfs_attr_search_ctx *ctx;
MFT_RECORD *m;
ATTR_RECORD *a;
const char *te = " Leaving file length out of sync with i_size.";
- int err;
+ int err, mp_size, size_change, alloc_change;
+ u32 attr_len;
ntfs_debug("Entering for inode 0x%lx.", vi->i_ino);
BUG_ON(NInoAttr(ni));
+ BUG_ON(S_ISDIR(vi->i_mode));
+ BUG_ON(NInoMstProtected(ni));
BUG_ON(ni->nr_extents < 0);
- m = map_mft_record(ni);
+retry_truncate:
+ /*
+ * Lock the runlist for writing and map the mft record to ensure it is
+ * safe to mess with the attribute runlist and sizes.
+ */
+ down_write(&ni->runlist.lock);
+ if (!NInoAttr(ni))
+ base_ni = ni;
+ else
+ base_ni = ni->ext.base_ntfs_ino;
+ m = map_mft_record(base_ni);
if (IS_ERR(m)) {
err = PTR_ERR(m);
ntfs_error(vi->i_sb, "Failed to map mft record for inode 0x%lx "
"(error code %d).%s", vi->i_ino, err, te);
ctx = NULL;
m = NULL;
- goto err_out;
+ goto old_bad_out;
}
- ctx = ntfs_attr_get_search_ctx(ni, m);
+ ctx = ntfs_attr_get_search_ctx(base_ni, m);
if (unlikely(!ctx)) {
ntfs_error(vi->i_sb, "Failed to allocate a search context for "
"inode 0x%lx (not enough memory).%s",
vi->i_ino, te);
err = -ENOMEM;
- goto err_out;
+ goto old_bad_out;
}
err = ntfs_attr_lookup(ni->type, ni->name, ni->name_len,
CASE_SENSITIVE, 0, NULL, 0, ctx);
if (unlikely(err)) {
- if (err == -ENOENT)
+ if (err == -ENOENT) {
ntfs_error(vi->i_sb, "Open attribute is missing from "
"mft record. Inode 0x%lx is corrupt. "
- "Run chkdsk.", vi->i_ino);
- else
+ "Run chkdsk.%s", vi->i_ino, te);
+ err = -EIO;
+ } else
ntfs_error(vi->i_sb, "Failed to lookup attribute in "
- "inode 0x%lx (error code %d).",
- vi->i_ino, err);
- goto err_out;
+ "inode 0x%lx (error code %d).%s",
+ vi->i_ino, err, te);
+ goto old_bad_out;
}
+ m = ctx->mrec;
a = ctx->attr;
- /* If the size has not changed there is nothing to do. */
- if (ntfs_attr_size(a) == i_size_read(vi))
- goto done;
- // TODO: Implement the truncate...
- ntfs_error(vi->i_sb, "Inode size has changed but this is not "
- "implemented yet. Resetting inode size to old value. "
- " This is most likely a bug in the ntfs driver!");
- i_size_write(vi, ntfs_attr_size(a));
-done:
+ /*
+ * The i_size of the vfs inode is the new size for the attribute value.
+ */
+ new_size = i_size_read(vi);
+ /* The current size of the attribute value is the old size. */
+ old_size = ntfs_attr_size(a);
+ /* Calculate the new allocated size. */
+ if (NInoNonResident(ni))
+ new_alloc_size = (new_size + vol->cluster_size - 1) &
+ ~(s64)vol->cluster_size_mask;
+ else
+ new_alloc_size = (new_size + 7) & ~7;
+ /* The current allocated size is the old allocated size. */
+ read_lock_irqsave(&ni->size_lock, flags);
+ old_alloc_size = ni->allocated_size;
+ read_unlock_irqrestore(&ni->size_lock, flags);
+ /*
+ * The change in the file size. This will be 0 if no change, >0 if the
+ * size is growing, and <0 if the size is shrinking.
+ */
+ size_change = -1;
+ if (new_size - old_size >= 0) {
+ size_change = 1;
+ if (new_size == old_size)
+ size_change = 0;
+ }
+ /* As above for the allocated size. */
+ alloc_change = -1;
+ if (new_alloc_size - old_alloc_size >= 0) {
+ alloc_change = 1;
+ if (new_alloc_size == old_alloc_size)
+ alloc_change = 0;
+ }
+ /*
+ * If neither the size nor the allocation are being changed there is
+ * nothing to do.
+ */
+ if (!size_change && !alloc_change)
+ goto unm_done;
+ /* If the size is changing, check if new size is allowed in $AttrDef. */
+ if (size_change) {
+ err = ntfs_attr_size_bounds_check(vol, ni->type, new_size);
+ if (unlikely(err)) {
+ if (err == -ERANGE) {
+ ntfs_error(vol->sb, "Truncate would cause the "
+ "inode 0x%lx to %simum size "
+ "for its attribute type "
+ "(0x%x). Aborting truncate.",
+ vi->i_ino,
+ new_size > old_size ? "exceed "
+ "the max" : "go under the min",
+ le32_to_cpu(ni->type));
+ err = -EFBIG;
+ } else {
+ ntfs_error(vol->sb, "Inode 0x%lx has unknown "
+ "attribute type 0x%x. "
+ "Aborting truncate.",
+ vi->i_ino,
+ le32_to_cpu(ni->type));
+ err = -EIO;
+ }
+ /* Reset the vfs inode size to the old size. */
+ i_size_write(vi, old_size);
+ goto err_out;
+ }
+ }
+ if (NInoCompressed(ni) || NInoEncrypted(ni)) {
+ ntfs_warning(vi->i_sb, "Changes in inode size are not "
+ "supported yet for %s files, ignoring.",
+ NInoCompressed(ni) ? "compressed" :
+ "encrypted");
+ err = -EOPNOTSUPP;
+ goto bad_out;
+ }
+ if (a->non_resident)
+ goto do_non_resident_truncate;
+ BUG_ON(NInoNonResident(ni));
+ /* Resize the attribute record to best fit the new attribute size. */
+ if (new_size < vol->mft_record_size &&
+ !ntfs_resident_attr_value_resize(m, a, new_size)) {
+ unsigned long flags;
+
+ /* The resize succeeded! */
+ flush_dcache_mft_record_page(ctx->ntfs_ino);
+ mark_mft_record_dirty(ctx->ntfs_ino);
+ write_lock_irqsave(&ni->size_lock, flags);
+ /* Update the sizes in the ntfs inode and all is done. */
+ ni->allocated_size = le32_to_cpu(a->length) -
+ le16_to_cpu(a->data.resident.value_offset);
+ /*
+ * Note ntfs_resident_attr_value_resize() has already done any
+ * necessary data clearing in the attribute record. When the
+ * file is being shrunk vmtruncate() will already have cleared
+ * the top part of the last partial page, i.e. since this is
+ * the resident case this is the page with index 0. However,
+ * when the file is being expanded, the page cache page data
+ * between the old data_size, i.e. old_size, and the new_size
+ * has not been zeroed. Fortunately, we do not need to zero it
+ * either since on one hand it will either already be zero due
+ * to both readpage and writepage clearing partial page data
+ * beyond i_size in which case there is nothing to do or in the
+ * case of the file being mmap()ped at the same time, POSIX
+ * specifies that the behaviour is unspecified thus we do not
+ * have to do anything. This means that in our implementation
+ * in the rare case that the file is mmap()ped and a write
+ * occured into the mmap()ped region just beyond the file size
+ * and writepage has not yet been called to write out the page
+ * (which would clear the area beyond the file size) and we now
+ * extend the file size to incorporate this dirty region
+ * outside the file size, a write of the page would result in
+ * this data being written to disk instead of being cleared.
+ * Given both POSIX and the Linux mmap(2) man page specify that
+ * this corner case is undefined, we choose to leave it like
+ * that as this is much simpler for us as we cannot lock the
+ * relevant page now since we are holding too many ntfs locks
+ * which would result in a lock reversal deadlock.
+ */
+ ni->initialized_size = new_size;
+ write_unlock_irqrestore(&ni->size_lock, flags);
+ goto unm_done;
+ }
+ /* If the above resize failed, this must be an attribute extension. */
+ BUG_ON(size_change < 0);
+ /*
+ * We have to drop all the locks so we can call
+ * ntfs_attr_make_non_resident(). This could be optimised by try-
+ * locking the first page cache page and only if that fails dropping
+ * the locks, locking the page, and redoing all the locking and
+ * lookups. While this would be a huge optimisation, it is not worth
+ * it as this is definitely a slow code path as it only ever can happen
+ * once for any given file.
+ */
ntfs_attr_put_search_ctx(ctx);
- unmap_mft_record(ni);
- NInoClearTruncateFailed(ni);
- ntfs_debug("Done.");
- return 0;
-err_out:
- if (err != -ENOMEM) {
+ unmap_mft_record(base_ni);
+ up_write(&ni->runlist.lock);
+ /*
+ * Not enough space in the mft record, try to make the attribute
+ * non-resident and if successful restart the truncation process.
+ */
+ err = ntfs_attr_make_non_resident(ni, old_size);
+ if (likely(!err))
+ goto retry_truncate;
+ /*
+ * Could not make non-resident. If this is due to this not being
+ * permitted for this attribute type or there not being enough space,
+ * try to make other attributes non-resident. Otherwise fail.
+ */
+ if (unlikely(err != -EPERM && err != -ENOSPC)) {
+ ntfs_error(vol->sb, "Cannot truncate inode 0x%lx, attribute "
+ "type 0x%x, because the conversion from "
+ "resident to non-resident attribute failed "
+ "with error code %i.", vi->i_ino,
+ (unsigned)le32_to_cpu(ni->type), err);
+ if (err != -ENOMEM)
+ err = -EIO;
+ goto conv_err_out;
+ }
+ /* TODO: Not implemented from here, abort. */
+ if (err == -ENOSPC)
+ ntfs_error(vol->sb, "Not enough space in the mft record/on "
+ "disk for the non-resident attribute value. "
+ "This case is not implemented yet.");
+ else /* if (err == -EPERM) */
+ ntfs_error(vol->sb, "This attribute type may not be "
+ "non-resident. This case is not implemented "
+ "yet.");
+ err = -EOPNOTSUPP;
+ goto conv_err_out;
+#if 0
+ // TODO: Attempt to make other attributes non-resident.
+ if (!err)
+ goto do_resident_extend;
+ /*
+ * Both the attribute list attribute and the standard information
+ * attribute must remain in the base inode. Thus, if this is one of
+ * these attributes, we have to try to move other attributes out into
+ * extent mft records instead.
+ */
+ if (ni->type == AT_ATTRIBUTE_LIST ||
+ ni->type == AT_STANDARD_INFORMATION) {
+ // TODO: Attempt to move other attributes into extent mft
+ // records.
+ err = -EOPNOTSUPP;
+ if (!err)
+ goto do_resident_extend;
+ goto err_out;
+ }
+ // TODO: Attempt to move this attribute to an extent mft record, but
+ // only if it is not already the only attribute in an mft record in
+ // which case there would be nothing to gain.
+ err = -EOPNOTSUPP;
+ if (!err)
+ goto do_resident_extend;
+ /* There is nothing we can do to make enough space. )-: */
+ goto err_out;
+#endif
+do_non_resident_truncate:
+ BUG_ON(!NInoNonResident(ni));
+ if (alloc_change < 0) {
+ highest_vcn = sle64_to_cpu(a->data.non_resident.highest_vcn);
+ if (highest_vcn > 0 &&
+ old_alloc_size >> vol->cluster_size_bits >
+ highest_vcn + 1) {
+ /*
+ * This attribute has multiple extents. Not yet
+ * supported.
+ */
+ ntfs_error(vol->sb, "Cannot truncate inode 0x%lx, "
+ "attribute type 0x%x, because the "
+ "attribute is highly fragmented (it "
+ "consists of multiple extents) and "
+ "this case is not implemented yet.",
+ vi->i_ino,
+ (unsigned)le32_to_cpu(ni->type));
+ err = -EOPNOTSUPP;
+ goto bad_out;
+ }
+ }
+ /*
+ * If the size is shrinking, need to reduce the initialized_size and
+ * the data_size before reducing the allocation.
+ */
+ if (size_change < 0) {
+ /*
+ * Make the valid size smaller (i_size is already up-to-date).
+ */
+ write_lock_irqsave(&ni->size_lock, flags);
+ if (new_size < ni->initialized_size) {
+ ni->initialized_size = new_size;
+ a->data.non_resident.initialized_size =
+ cpu_to_sle64(new_size);
+ }
+ a->data.non_resident.data_size = cpu_to_sle64(new_size);
+ write_unlock_irqrestore(&ni->size_lock, flags);
+ flush_dcache_mft_record_page(ctx->ntfs_ino);
+ mark_mft_record_dirty(ctx->ntfs_ino);
+ /* If the allocated size is not changing, we are done. */
+ if (!alloc_change)
+ goto unm_done;
+ /*
+ * If the size is shrinking it makes no sense for the
+ * allocation to be growing.
+ */
+ BUG_ON(alloc_change > 0);
+ } else /* if (size_change >= 0) */ {
+ /*
+ * The file size is growing or staying the same but the
+ * allocation can be shrinking, growing or staying the same.
+ */
+ if (alloc_change > 0) {
+ /*
+ * We need to extend the allocation and possibly update
+ * the data size. If we are updating the data size,
+ * since we are not touching the initialized_size we do
+ * not need to worry about the actual data on disk.
+ * And as far as the page cache is concerned, there
+ * will be no pages beyond the old data size and any
+ * partial region in the last page between the old and
+ * new data size (or the end of the page if the new
+ * data size is outside the page) does not need to be
+ * modified as explained above for the resident
+ * attribute truncate case. To do this, we simply drop
+ * the locks we hold and leave all the work to our
+ * friendly helper ntfs_attr_extend_allocation().
+ */
+ ntfs_attr_put_search_ctx(ctx);
+ unmap_mft_record(base_ni);
+ up_write(&ni->runlist.lock);
+ err = ntfs_attr_extend_allocation(ni, new_size,
+ size_change > 0 ? new_size : -1, -1);
+ /*
+ * ntfs_attr_extend_allocation() will have done error
+ * output already.
+ */
+ goto done;
+ }
+ if (!alloc_change)
+ goto alloc_done;
+ }
+ /* alloc_change < 0 */
+ /* Free the clusters. */
+ nr_freed = ntfs_cluster_free(ni, new_alloc_size >>
+ vol->cluster_size_bits, -1, ctx);
+ m = ctx->mrec;
+ a = ctx->attr;
+ if (unlikely(nr_freed < 0)) {
+ ntfs_error(vol->sb, "Failed to release cluster(s) (error code "
+ "%lli). Unmount and run chkdsk to recover "
+ "the lost cluster(s).", (long long)nr_freed);
NVolSetErrors(vol);
+ nr_freed = 0;
+ }
+ /* Truncate the runlist. */
+ err = ntfs_rl_truncate_nolock(vol, &ni->runlist,
+ new_alloc_size >> vol->cluster_size_bits);
+ /*
+ * If the runlist truncation failed and/or the search context is no
+ * longer valid, we cannot resize the attribute record or build the
+ * mapping pairs array thus we mark the inode bad so that no access to
+ * the freed clusters can happen.
+ */
+ if (unlikely(err || IS_ERR(m))) {
+ ntfs_error(vol->sb, "Failed to %s (error code %li).%s",
+ IS_ERR(m) ?
+ "restore attribute search context" :
+ "truncate attribute runlist",
+ IS_ERR(m) ? PTR_ERR(m) : err, es);
+ err = -EIO;
+ goto bad_out;
+ }
+ /* Get the size for the shrunk mapping pairs array for the runlist. */
+ mp_size = ntfs_get_size_for_mapping_pairs(vol, ni->runlist.rl, 0, -1);
+ if (unlikely(mp_size <= 0)) {
+ ntfs_error(vol->sb, "Cannot shrink allocation of inode 0x%lx, "
+ "attribute type 0x%x, because determining the "
+ "size for the mapping pairs failed with error "
+ "code %i.%s", vi->i_ino,
+ (unsigned)le32_to_cpu(ni->type), mp_size, es);
+ err = -EIO;
+ goto bad_out;
+ }
+ /*
+ * Shrink the attribute record for the new mapping pairs array. Note,
+ * this cannot fail since we are making the attribute smaller thus by
+ * definition there is enough space to do so.
+ */
+ attr_len = le32_to_cpu(a->length);
+ err = ntfs_attr_record_resize(m, a, mp_size +
+ le16_to_cpu(a->data.non_resident.mapping_pairs_offset));
+ BUG_ON(err);
+ /*
+ * Generate the mapping pairs array directly into the attribute record.
+ */
+ err = ntfs_mapping_pairs_build(vol, (u8*)a +
+ le16_to_cpu(a->data.non_resident.mapping_pairs_offset),
+ mp_size, ni->runlist.rl, 0, -1, NULL);
+ if (unlikely(err)) {
+ ntfs_error(vol->sb, "Cannot shrink allocation of inode 0x%lx, "
+ "attribute type 0x%x, because building the "
+ "mapping pairs failed with error code %i.%s",
+ vi->i_ino, (unsigned)le32_to_cpu(ni->type),
+ err, es);
+ err = -EIO;
+ goto bad_out;
+ }
+ /* Update the allocated/compressed size as well as the highest vcn. */
+ a->data.non_resident.highest_vcn = cpu_to_sle64((new_alloc_size >>
+ vol->cluster_size_bits) - 1);
+ write_lock_irqsave(&ni->size_lock, flags);
+ ni->allocated_size = new_alloc_size;
+ a->data.non_resident.allocated_size = cpu_to_sle64(new_alloc_size);
+ if (NInoSparse(ni) || NInoCompressed(ni)) {
+ if (nr_freed) {
+ ni->itype.compressed.size -= nr_freed <<
+ vol->cluster_size_bits;
+ BUG_ON(ni->itype.compressed.size < 0);
+ a->data.non_resident.compressed_size = cpu_to_sle64(
+ ni->itype.compressed.size);
+ vi->i_blocks = ni->itype.compressed.size >> 9;
+ }
+ } else
+ vi->i_blocks = new_alloc_size >> 9;
+ write_unlock_irqrestore(&ni->size_lock, flags);
+ /*
+ * We have shrunk the allocation. If this is a shrinking truncate we
+ * have already dealt with the initialized_size and the data_size above
+ * and we are done. If the truncate is only changing the allocation
+ * and not the data_size, we are also done. If this is an extending
+ * truncate, need to extend the data_size now which is ensured by the
+ * fact that @size_change is positive.
+ */
+alloc_done:
+ /*
+ * If the size is growing, need to update it now. If it is shrinking,
+ * we have already updated it above (before the allocation change).
+ */
+ if (size_change > 0)
+ a->data.non_resident.data_size = cpu_to_sle64(new_size);
+ /* Ensure the modified mft record is written out. */
+ flush_dcache_mft_record_page(ctx->ntfs_ino);
+ mark_mft_record_dirty(ctx->ntfs_ino);
+unm_done:
+ ntfs_attr_put_search_ctx(ctx);
+ unmap_mft_record(base_ni);
+ up_write(&ni->runlist.lock);
+done:
+ /* Update the mtime and ctime on the base inode. */
+ inode_update_time(VFS_I(base_ni), 1);
+ if (likely(!err)) {
+ NInoClearTruncateFailed(ni);
+ ntfs_debug("Done.");
+ }
+ return err;
+old_bad_out:
+ old_size = -1;
+bad_out:
+ if (err != -ENOMEM && err != -EOPNOTSUPP) {
make_bad_inode(vi);
+ make_bad_inode(VFS_I(base_ni));
+ NVolSetErrors(vol);
}
+ if (err != -EOPNOTSUPP)
+ NInoSetTruncateFailed(ni);
+ else if (old_size >= 0)
+ i_size_write(vi, old_size);
+err_out:
if (ctx)
ntfs_attr_put_search_ctx(ctx);
if (m)
- unmap_mft_record(ni);
- NInoSetTruncateFailed(ni);
+ unmap_mft_record(base_ni);
+ up_write(&ni->runlist.lock);
+out:
+ ntfs_debug("Failed. Returning error code %i.", err);
return err;
+conv_err_out:
+ if (err != -ENOMEM && err != -EOPNOTSUPP) {
+ make_bad_inode(vi);
+ make_bad_inode(VFS_I(base_ni));
+ NVolSetErrors(vol);
+ }
+ if (err != -EOPNOTSUPP)
+ NInoSetTruncateFailed(ni);
+ else
+ i_size_write(vi, old_size);
+ goto out;
}
/**
@@ -2420,8 +2845,7 @@ int ntfs_setattr(struct dentry *dentry, struct iattr *attr)
err = inode_change_ok(vi, attr);
if (err)
- return err;
-
+ goto out;
/* We do not support NTFS ACLs yet. */
if (ia_valid & (ATTR_UID | ATTR_GID | ATTR_MODE)) {
ntfs_warning(vi->i_sb, "Changes in user/group/mode are not "
@@ -2429,14 +2853,22 @@ int ntfs_setattr(struct dentry *dentry, struct iattr *attr)
err = -EOPNOTSUPP;
goto out;
}
-
if (ia_valid & ATTR_SIZE) {
if (attr->ia_size != i_size_read(vi)) {
- ntfs_warning(vi->i_sb, "Changes in inode size are not "
- "supported yet, ignoring.");
- err = -EOPNOTSUPP;
- // TODO: Implement...
- // err = vmtruncate(vi, attr->ia_size);
+ ntfs_inode *ni = NTFS_I(vi);
+ /*
+ * FIXME: For now we do not support resizing of
+ * compressed or encrypted files yet.
+ */
+ if (NInoCompressed(ni) || NInoEncrypted(ni)) {
+ ntfs_warning(vi->i_sb, "Changes in inode size "
+ "are not supported yet for "
+ "%s files, ignoring.",
+ NInoCompressed(ni) ?
+ "compressed" : "encrypted");
+ err = -EOPNOTSUPP;
+ } else
+ err = vmtruncate(vi, attr->ia_size);
if (err || ia_valid == ATTR_SIZE)
goto out;
} else {
diff --git a/fs/ntfs/layout.h b/fs/ntfs/layout.h
index 5c248d404f05..f5678d5d7919 100644
--- a/fs/ntfs/layout.h
+++ b/fs/ntfs/layout.h
@@ -1021,10 +1021,17 @@ enum {
FILE_NAME_POSIX = 0x00,
/* This is the largest namespace. It is case sensitive and allows all
Unicode characters except for: '\0' and '/'. Beware that in
- WinNT/2k files which eg have the same name except for their case
- will not be distinguished by the standard utilities and thus a "del
- filename" will delete both "filename" and "fileName" without
- warning. */
+ WinNT/2k/2003 by default files which eg have the same name except
+ for their case will not be distinguished by the standard utilities
+ and thus a "del filename" will delete both "filename" and "fileName"
+ without warning. However if for example Services For Unix (SFU) are
+ installed and the case sensitive option was enabled at installation
+ time, then you can create/access/delete such files.
+ Note that even SFU places restrictions on the filenames beyond the
+ '\0' and '/' and in particular the following set of characters is
+ not allowed: '"', '/', '<', '>', '\'. All other characters,
+ including the ones no allowed in WIN32 namespace are allowed.
+ Tested with SFU 3.5 (this is now free) running on Windows XP. */
FILE_NAME_WIN32 = 0x01,
/* The standard WinNT/2k NTFS long filenames. Case insensitive. All
Unicode chars except: '\0', '"', '*', '/', ':', '<', '>', '?', '\',
@@ -2367,7 +2374,9 @@ typedef struct {
* Extended attribute flags (8-bit).
*/
enum {
- NEED_EA = 0x80
+ NEED_EA = 0x80 /* If set the file to which the EA belongs
+ cannot be interpreted without understanding
+ the associates extended attributes. */
} __attribute__ ((__packed__));
typedef u8 EA_FLAGS;
@@ -2375,20 +2384,20 @@ typedef u8 EA_FLAGS;
/*
* Attribute: Extended attribute (EA) (0xe0).
*
- * NOTE: Always non-resident. (Is this true?)
+ * NOTE: Can be resident or non-resident.
*
* Like the attribute list and the index buffer list, the EA attribute value is
* a sequence of EA_ATTR variable length records.
- *
- * FIXME: It appears weird that the EA name is not unicode. Is it true?
*/
typedef struct {
le32 next_entry_offset; /* Offset to the next EA_ATTR. */
EA_FLAGS flags; /* Flags describing the EA. */
- u8 ea_name_length; /* Length of the name of the EA in bytes. */
+ u8 ea_name_length; /* Length of the name of the EA in bytes
+ excluding the '\0' byte terminator. */
le16 ea_value_length; /* Byte size of the EA's value. */
- u8 ea_name[0]; /* Name of the EA. */
- u8 ea_value[0]; /* The value of the EA. Immediately follows
+ u8 ea_name[0]; /* Name of the EA. Note this is ASCII, not
+ Unicode and it is zero terminated. */
+ u8 ea_value[0]; /* The value of the EA. Immediately follows
the name. */
} __attribute__ ((__packed__)) EA_ATTR;
diff --git a/fs/ntfs/lcnalloc.c b/fs/ntfs/lcnalloc.c
index 5af3bf0b7eee..29cabf93d2d2 100644
--- a/fs/ntfs/lcnalloc.c
+++ b/fs/ntfs/lcnalloc.c
@@ -76,6 +76,7 @@ int ntfs_cluster_free_from_rl_nolock(ntfs_volume *vol,
* @count: number of clusters to allocate
* @start_lcn: starting lcn at which to allocate the clusters (or -1 if none)
* @zone: zone from which to allocate the clusters
+ * @is_extension: if TRUE, this is an attribute extension
*
* Allocate @count clusters preferably starting at cluster @start_lcn or at the
* current allocator position if @start_lcn is -1, on the mounted ntfs volume
@@ -86,6 +87,13 @@ int ntfs_cluster_free_from_rl_nolock(ntfs_volume *vol,
* @start_vcn specifies the vcn of the first allocated cluster. This makes
* merging the resulting runlist with the old runlist easier.
*
+ * If @is_extension is TRUE, the caller is allocating clusters to extend an
+ * attribute and if it is FALSE, the caller is allocating clusters to fill a
+ * hole in an attribute. Practically the difference is that if @is_extension
+ * is TRUE the returned runlist will be terminated with LCN_ENOENT and if
+ * @is_extension is FALSE the runlist will be terminated with
+ * LCN_RL_NOT_MAPPED.
+ *
* You need to check the return value with IS_ERR(). If this is false, the
* function was successful and the return value is a runlist describing the
* allocated cluster(s). If IS_ERR() is true, the function failed and
@@ -137,7 +145,8 @@ int ntfs_cluster_free_from_rl_nolock(ntfs_volume *vol,
*/
runlist_element *ntfs_cluster_alloc(ntfs_volume *vol, const VCN start_vcn,
const s64 count, const LCN start_lcn,
- const NTFS_CLUSTER_ALLOCATION_ZONES zone)
+ const NTFS_CLUSTER_ALLOCATION_ZONES zone,
+ const BOOL is_extension)
{
LCN zone_start, zone_end, bmp_pos, bmp_initial_pos, last_read_pos, lcn;
LCN prev_lcn = 0, prev_run_len = 0, mft_zone_size;
@@ -310,7 +319,7 @@ runlist_element *ntfs_cluster_alloc(ntfs_volume *vol, const VCN start_vcn,
continue;
}
bit = 1 << (lcn & 7);
- ntfs_debug("bit %i.", bit);
+ ntfs_debug("bit 0x%x.", bit);
/* If the bit is already set, go onto the next one. */
if (*byte & bit) {
lcn++;
@@ -729,7 +738,7 @@ out:
/* Add runlist terminator element. */
if (likely(rl)) {
rl[rlpos].vcn = rl[rlpos - 1].vcn + rl[rlpos - 1].length;
- rl[rlpos].lcn = LCN_RL_NOT_MAPPED;
+ rl[rlpos].lcn = is_extension ? LCN_ENOENT : LCN_RL_NOT_MAPPED;
rl[rlpos].length = 0;
}
if (likely(page && !IS_ERR(page))) {
@@ -782,6 +791,7 @@ out:
* @ni: ntfs inode whose runlist describes the clusters to free
* @start_vcn: vcn in the runlist of @ni at which to start freeing clusters
* @count: number of clusters to free or -1 for all clusters
+ * @ctx: active attribute search context if present or NULL if not
* @is_rollback: true if this is a rollback operation
*
* Free @count clusters starting at the cluster @start_vcn in the runlist
@@ -791,15 +801,39 @@ out:
* deallocated. Thus, to completely free all clusters in a runlist, use
* @start_vcn = 0 and @count = -1.
*
+ * If @ctx is specified, it is an active search context of @ni and its base mft
+ * record. This is needed when __ntfs_cluster_free() encounters unmapped
+ * runlist fragments and allows their mapping. If you do not have the mft
+ * record mapped, you can specify @ctx as NULL and __ntfs_cluster_free() will
+ * perform the necessary mapping and unmapping.
+ *
+ * Note, __ntfs_cluster_free() saves the state of @ctx on entry and restores it
+ * before returning. Thus, @ctx will be left pointing to the same attribute on
+ * return as on entry. However, the actual pointers in @ctx may point to
+ * different memory locations on return, so you must remember to reset any
+ * cached pointers from the @ctx, i.e. after the call to __ntfs_cluster_free(),
+ * you will probably want to do:
+ * m = ctx->mrec;
+ * a = ctx->attr;
+ * Assuming you cache ctx->attr in a variable @a of type ATTR_RECORD * and that
+ * you cache ctx->mrec in a variable @m of type MFT_RECORD *.
+ *
* @is_rollback should always be FALSE, it is for internal use to rollback
* errors. You probably want to use ntfs_cluster_free() instead.
*
- * Note, ntfs_cluster_free() does not modify the runlist at all, so the caller
- * has to deal with it later.
+ * Note, __ntfs_cluster_free() does not modify the runlist, so you have to
+ * remove from the runlist or mark sparse the freed runs later.
*
* Return the number of deallocated clusters (not counting sparse ones) on
* success and -errno on error.
*
+ * WARNING: If @ctx is supplied, regardless of whether success or failure is
+ * returned, you need to check IS_ERR(@ctx->mrec) and if TRUE the @ctx
+ * is no longer valid, i.e. you need to either call
+ * ntfs_attr_reinit_search_ctx() or ntfs_attr_put_search_ctx() on it.
+ * In that case PTR_ERR(@ctx->mrec) will give you the error code for
+ * why the mapping of the old inode failed.
+ *
* Locking: - The runlist described by @ni must be locked for writing on entry
* and is locked on return. Note the runlist may be modified when
* needed runlist fragments need to be mapped.
@@ -807,9 +841,13 @@ out:
* on return.
* - This function takes the volume lcn bitmap lock for writing and
* modifies the bitmap contents.
+ * - If @ctx is NULL, the base mft record of @ni must not be mapped on
+ * entry and it will be left unmapped on return.
+ * - If @ctx is not NULL, the base mft record must be mapped on entry
+ * and it will be left mapped on return.
*/
s64 __ntfs_cluster_free(ntfs_inode *ni, const VCN start_vcn, s64 count,
- const BOOL is_rollback)
+ ntfs_attr_search_ctx *ctx, const BOOL is_rollback)
{
s64 delta, to_free, total_freed, real_freed;
ntfs_volume *vol;
@@ -839,7 +877,7 @@ s64 __ntfs_cluster_free(ntfs_inode *ni, const VCN start_vcn, s64 count,
total_freed = real_freed = 0;
- rl = ntfs_attr_find_vcn_nolock(ni, start_vcn, TRUE);
+ rl = ntfs_attr_find_vcn_nolock(ni, start_vcn, ctx);
if (IS_ERR(rl)) {
if (!is_rollback)
ntfs_error(vol->sb, "Failed to find first runlist "
@@ -893,7 +931,7 @@ s64 __ntfs_cluster_free(ntfs_inode *ni, const VCN start_vcn, s64 count,
/* Attempt to map runlist. */
vcn = rl->vcn;
- rl = ntfs_attr_find_vcn_nolock(ni, vcn, TRUE);
+ rl = ntfs_attr_find_vcn_nolock(ni, vcn, ctx);
if (IS_ERR(rl)) {
err = PTR_ERR(rl);
if (!is_rollback)
@@ -961,7 +999,7 @@ err_out:
* If rollback fails, set the volume errors flag, emit an error
* message, and return the error code.
*/
- delta = __ntfs_cluster_free(ni, start_vcn, total_freed, TRUE);
+ delta = __ntfs_cluster_free(ni, start_vcn, total_freed, ctx, TRUE);
if (delta < 0) {
ntfs_error(vol->sb, "Failed to rollback (error %i). Leaving "
"inconsistent metadata! Unmount and run "
diff --git a/fs/ntfs/lcnalloc.h b/fs/ntfs/lcnalloc.h
index a6a8827882e7..72cbca7003b2 100644
--- a/fs/ntfs/lcnalloc.h
+++ b/fs/ntfs/lcnalloc.h
@@ -27,6 +27,7 @@
#include <linux/fs.h>
+#include "attrib.h"
#include "types.h"
#include "inode.h"
#include "runlist.h"
@@ -41,16 +42,18 @@ typedef enum {
extern runlist_element *ntfs_cluster_alloc(ntfs_volume *vol,
const VCN start_vcn, const s64 count, const LCN start_lcn,
- const NTFS_CLUSTER_ALLOCATION_ZONES zone);
+ const NTFS_CLUSTER_ALLOCATION_ZONES zone,
+ const BOOL is_extension);
extern s64 __ntfs_cluster_free(ntfs_inode *ni, const VCN start_vcn,
- s64 count, const BOOL is_rollback);
+ s64 count, ntfs_attr_search_ctx *ctx, const BOOL is_rollback);
/**
* ntfs_cluster_free - free clusters on an ntfs volume
* @ni: ntfs inode whose runlist describes the clusters to free
* @start_vcn: vcn in the runlist of @ni at which to start freeing clusters
* @count: number of clusters to free or -1 for all clusters
+ * @ctx: active attribute search context if present or NULL if not
*
* Free @count clusters starting at the cluster @start_vcn in the runlist
* described by the ntfs inode @ni.
@@ -59,12 +62,36 @@ extern s64 __ntfs_cluster_free(ntfs_inode *ni, const VCN start_vcn,
* deallocated. Thus, to completely free all clusters in a runlist, use
* @start_vcn = 0 and @count = -1.
*
- * Note, ntfs_cluster_free() does not modify the runlist at all, so the caller
- * has to deal with it later.
+ * If @ctx is specified, it is an active search context of @ni and its base mft
+ * record. This is needed when ntfs_cluster_free() encounters unmapped runlist
+ * fragments and allows their mapping. If you do not have the mft record
+ * mapped, you can specify @ctx as NULL and ntfs_cluster_free() will perform
+ * the necessary mapping and unmapping.
+ *
+ * Note, ntfs_cluster_free() saves the state of @ctx on entry and restores it
+ * before returning. Thus, @ctx will be left pointing to the same attribute on
+ * return as on entry. However, the actual pointers in @ctx may point to
+ * different memory locations on return, so you must remember to reset any
+ * cached pointers from the @ctx, i.e. after the call to ntfs_cluster_free(),
+ * you will probably want to do:
+ * m = ctx->mrec;
+ * a = ctx->attr;
+ * Assuming you cache ctx->attr in a variable @a of type ATTR_RECORD * and that
+ * you cache ctx->mrec in a variable @m of type MFT_RECORD *.
+ *
+ * Note, ntfs_cluster_free() does not modify the runlist, so you have to remove
+ * from the runlist or mark sparse the freed runs later.
*
* Return the number of deallocated clusters (not counting sparse ones) on
* success and -errno on error.
*
+ * WARNING: If @ctx is supplied, regardless of whether success or failure is
+ * returned, you need to check IS_ERR(@ctx->mrec) and if TRUE the @ctx
+ * is no longer valid, i.e. you need to either call
+ * ntfs_attr_reinit_search_ctx() or ntfs_attr_put_search_ctx() on it.
+ * In that case PTR_ERR(@ctx->mrec) will give you the error code for
+ * why the mapping of the old inode failed.
+ *
* Locking: - The runlist described by @ni must be locked for writing on entry
* and is locked on return. Note the runlist may be modified when
* needed runlist fragments need to be mapped.
@@ -72,11 +99,15 @@ extern s64 __ntfs_cluster_free(ntfs_inode *ni, const VCN start_vcn,
* on return.
* - This function takes the volume lcn bitmap lock for writing and
* modifies the bitmap contents.
+ * - If @ctx is NULL, the base mft record of @ni must not be mapped on
+ * entry and it will be left unmapped on return.
+ * - If @ctx is not NULL, the base mft record must be mapped on entry
+ * and it will be left mapped on return.
*/
static inline s64 ntfs_cluster_free(ntfs_inode *ni, const VCN start_vcn,
- s64 count)
+ s64 count, ntfs_attr_search_ctx *ctx)
{
- return __ntfs_cluster_free(ni, start_vcn, count, FALSE);
+ return __ntfs_cluster_free(ni, start_vcn, count, ctx, FALSE);
}
extern int ntfs_cluster_free_from_rl_nolock(ntfs_volume *vol,
diff --git a/fs/ntfs/malloc.h b/fs/ntfs/malloc.h
index 590887b943f5..e38e402e4103 100644
--- a/fs/ntfs/malloc.h
+++ b/fs/ntfs/malloc.h
@@ -39,8 +39,7 @@
* If there was insufficient memory to complete the request, return NULL.
* Depending on @gfp_mask the allocation may be guaranteed to succeed.
*/
-static inline void *__ntfs_malloc(unsigned long size,
- gfp_t gfp_mask)
+static inline void *__ntfs_malloc(unsigned long size, gfp_t gfp_mask)
{
if (likely(size <= PAGE_SIZE)) {
BUG_ON(!size);
diff --git a/fs/ntfs/mft.c b/fs/ntfs/mft.c
index b011369b5956..0c65cbb8c5cf 100644
--- a/fs/ntfs/mft.c
+++ b/fs/ntfs/mft.c
@@ -49,7 +49,8 @@ static inline MFT_RECORD *map_mft_record_page(ntfs_inode *ni)
ntfs_volume *vol = ni->vol;
struct inode *mft_vi = vol->mft_ino;
struct page *page;
- unsigned long index, ofs, end_index;
+ unsigned long index, end_index;
+ unsigned ofs;
BUG_ON(ni->page);
/*
@@ -1308,7 +1309,7 @@ static int ntfs_mft_bitmap_extend_allocation_nolock(ntfs_volume *vol)
ll = mftbmp_ni->allocated_size;
read_unlock_irqrestore(&mftbmp_ni->size_lock, flags);
rl = ntfs_attr_find_vcn_nolock(mftbmp_ni,
- (ll - 1) >> vol->cluster_size_bits, TRUE);
+ (ll - 1) >> vol->cluster_size_bits, NULL);
if (unlikely(IS_ERR(rl) || !rl->length || rl->lcn < 0)) {
up_write(&mftbmp_ni->runlist.lock);
ntfs_error(vol->sb, "Failed to determine last allocated "
@@ -1354,7 +1355,8 @@ static int ntfs_mft_bitmap_extend_allocation_nolock(ntfs_volume *vol)
up_write(&vol->lcnbmp_lock);
ntfs_unmap_page(page);
/* Allocate a cluster from the DATA_ZONE. */
- rl2 = ntfs_cluster_alloc(vol, rl[1].vcn, 1, lcn, DATA_ZONE);
+ rl2 = ntfs_cluster_alloc(vol, rl[1].vcn, 1, lcn, DATA_ZONE,
+ TRUE);
if (IS_ERR(rl2)) {
up_write(&mftbmp_ni->runlist.lock);
ntfs_error(vol->sb, "Failed to allocate a cluster for "
@@ -1738,7 +1740,7 @@ static int ntfs_mft_data_extend_allocation_nolock(ntfs_volume *vol)
ll = mft_ni->allocated_size;
read_unlock_irqrestore(&mft_ni->size_lock, flags);
rl = ntfs_attr_find_vcn_nolock(mft_ni,
- (ll - 1) >> vol->cluster_size_bits, TRUE);
+ (ll - 1) >> vol->cluster_size_bits, NULL);
if (unlikely(IS_ERR(rl) || !rl->length || rl->lcn < 0)) {
up_write(&mft_ni->runlist.lock);
ntfs_error(vol->sb, "Failed to determine last allocated "
@@ -1779,7 +1781,8 @@ static int ntfs_mft_data_extend_allocation_nolock(ntfs_volume *vol)
nr > min_nr ? "default" : "minimal", (long long)nr);
old_last_vcn = rl[1].vcn;
do {
- rl2 = ntfs_cluster_alloc(vol, old_last_vcn, nr, lcn, MFT_ZONE);
+ rl2 = ntfs_cluster_alloc(vol, old_last_vcn, nr, lcn, MFT_ZONE,
+ TRUE);
if (likely(!IS_ERR(rl2)))
break;
if (PTR_ERR(rl2) != -ENOSPC || nr == min_nr) {
@@ -1951,20 +1954,21 @@ restore_undo_alloc:
NVolSetErrors(vol);
return ret;
}
- a = ctx->attr;
- a->data.non_resident.highest_vcn = cpu_to_sle64(old_last_vcn - 1);
+ ctx->attr->data.non_resident.highest_vcn =
+ cpu_to_sle64(old_last_vcn - 1);
undo_alloc:
- if (ntfs_cluster_free(mft_ni, old_last_vcn, -1) < 0) {
+ if (ntfs_cluster_free(mft_ni, old_last_vcn, -1, ctx) < 0) {
ntfs_error(vol->sb, "Failed to free clusters from mft data "
"attribute.%s", es);
NVolSetErrors(vol);
}
+ a = ctx->attr;
if (ntfs_rl_truncate_nolock(vol, &mft_ni->runlist, old_last_vcn)) {
ntfs_error(vol->sb, "Failed to truncate mft data attribute "
"runlist.%s", es);
NVolSetErrors(vol);
}
- if (mp_rebuilt) {
+ if (mp_rebuilt && !IS_ERR(ctx->mrec)) {
if (ntfs_mapping_pairs_build(vol, (u8*)a + le16_to_cpu(
a->data.non_resident.mapping_pairs_offset),
old_alen - le16_to_cpu(
@@ -1981,6 +1985,10 @@ undo_alloc:
}
flush_dcache_mft_record_page(ctx->ntfs_ino);
mark_mft_record_dirty(ctx->ntfs_ino);
+ } else if (IS_ERR(ctx->mrec)) {
+ ntfs_error(vol->sb, "Failed to restore attribute search "
+ "context.%s", es);
+ NVolSetErrors(vol);
}
if (ctx)
ntfs_attr_put_search_ctx(ctx);
diff --git a/fs/ntfs/super.c b/fs/ntfs/super.c
index 453d0d51ea4b..6c16db9e1a8a 100644
--- a/fs/ntfs/super.c
+++ b/fs/ntfs/super.c
@@ -1447,7 +1447,7 @@ not_enabled:
if (unlikely(i_size_read(tmp_ino) < sizeof(USN_HEADER))) {
ntfs_error(vol->sb, "Found corrupt $UsnJrnl/$DATA/$Max "
"attribute (size is 0x%llx but should be at "
- "least 0x%x bytes).", i_size_read(tmp_ino),
+ "least 0x%zx bytes).", i_size_read(tmp_ino),
sizeof(USN_HEADER));
return FALSE;
}
diff --git a/fs/open.c b/fs/open.c
index f0d90cf0495c..f53a5b9ffb7d 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -194,7 +194,7 @@ out:
return error;
}
-int do_truncate(struct dentry *dentry, loff_t length)
+int do_truncate(struct dentry *dentry, loff_t length, struct file *filp)
{
int err;
struct iattr newattrs;
@@ -205,6 +205,10 @@ int do_truncate(struct dentry *dentry, loff_t length)
newattrs.ia_size = length;
newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME;
+ if (filp) {
+ newattrs.ia_file = filp;
+ newattrs.ia_valid |= ATTR_FILE;
+ }
down(&dentry->d_inode->i_sem);
err = notify_change(dentry, &newattrs);
@@ -236,7 +240,7 @@ static inline long do_sys_truncate(const char __user * path, loff_t length)
if (!S_ISREG(inode->i_mode))
goto dput_and_out;
- error = permission(inode,MAY_WRITE,&nd);
+ error = vfs_permission(&nd, MAY_WRITE);
if (error)
goto dput_and_out;
@@ -262,7 +266,7 @@ static inline long do_sys_truncate(const char __user * path, loff_t length)
error = locks_verify_truncate(inode, NULL, length);
if (!error) {
DQUOT_INIT(inode);
- error = do_truncate(nd.dentry, length);
+ error = do_truncate(nd.dentry, length, NULL);
}
put_write_access(inode);
@@ -314,7 +318,7 @@ static inline long do_sys_ftruncate(unsigned int fd, loff_t length, int small)
error = locks_verify_truncate(inode, file, length);
if (!error)
- error = do_truncate(dentry, length);
+ error = do_truncate(dentry, length, file);
out_putf:
fput(file);
out:
@@ -390,7 +394,7 @@ asmlinkage long sys_utime(char __user * filename, struct utimbuf __user * times)
goto dput_and_out;
if (current->fsuid != inode->i_uid &&
- (error = permission(inode,MAY_WRITE,&nd)) != 0)
+ (error = vfs_permission(&nd, MAY_WRITE)) != 0)
goto dput_and_out;
}
down(&inode->i_sem);
@@ -443,7 +447,7 @@ long do_utimes(char __user * filename, struct timeval * times)
goto dput_and_out;
if (current->fsuid != inode->i_uid &&
- (error = permission(inode,MAY_WRITE,&nd)) != 0)
+ (error = vfs_permission(&nd, MAY_WRITE)) != 0)
goto dput_and_out;
}
down(&inode->i_sem);
@@ -502,7 +506,7 @@ asmlinkage long sys_access(const char __user * filename, int mode)
res = __user_walk(filename, LOOKUP_FOLLOW|LOOKUP_ACCESS, &nd);
if (!res) {
- res = permission(nd.dentry->d_inode, mode, &nd);
+ res = vfs_permission(&nd, mode);
/* SuS v2 requires we report a read only fs too */
if(!res && (mode & S_IWOTH) && IS_RDONLY(nd.dentry->d_inode)
&& !special_file(nd.dentry->d_inode->i_mode))
@@ -526,7 +530,7 @@ asmlinkage long sys_chdir(const char __user * filename)
if (error)
goto out;
- error = permission(nd.dentry->d_inode,MAY_EXEC,&nd);
+ error = vfs_permission(&nd, MAY_EXEC);
if (error)
goto dput_and_out;
@@ -559,7 +563,7 @@ asmlinkage long sys_fchdir(unsigned int fd)
if (!S_ISDIR(inode->i_mode))
goto out_putf;
- error = permission(inode, MAY_EXEC, NULL);
+ error = file_permission(file, MAY_EXEC);
if (!error)
set_fs_pwd(current->fs, mnt, dentry);
out_putf:
@@ -577,7 +581,7 @@ asmlinkage long sys_chroot(const char __user * filename)
if (error)
goto out;
- error = permission(nd.dentry->d_inode,MAY_EXEC,&nd);
+ error = vfs_permission(&nd, MAY_EXEC);
if (error)
goto dput_and_out;
@@ -739,7 +743,8 @@ asmlinkage long sys_fchown(unsigned int fd, uid_t user, gid_t group)
}
static struct file *__dentry_open(struct dentry *dentry, struct vfsmount *mnt,
- int flags, struct file *f)
+ int flags, struct file *f,
+ int (*open)(struct inode *, struct file *))
{
struct inode *inode;
int error;
@@ -761,11 +766,14 @@ static struct file *__dentry_open(struct dentry *dentry, struct vfsmount *mnt,
f->f_op = fops_get(inode->i_fop);
file_move(f, &inode->i_sb->s_files);
- if (f->f_op && f->f_op->open) {
- error = f->f_op->open(inode,f);
+ if (!open && f->f_op)
+ open = f->f_op->open;
+ if (open) {
+ error = open(inode, f);
if (error)
goto cleanup_all;
}
+
f->f_flags &= ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC);
file_ra_state_init(&f->f_ra, f->f_mapping->host->i_mapping);
@@ -814,28 +822,79 @@ struct file *filp_open(const char * filename, int flags, int mode)
{
int namei_flags, error;
struct nameidata nd;
- struct file *f;
namei_flags = flags;
if ((namei_flags+1) & O_ACCMODE)
namei_flags++;
- if (namei_flags & O_TRUNC)
- namei_flags |= 2;
-
- error = -ENFILE;
- f = get_empty_filp();
- if (f == NULL)
- return ERR_PTR(error);
error = open_namei(filename, namei_flags, mode, &nd);
if (!error)
- return __dentry_open(nd.dentry, nd.mnt, flags, f);
+ return nameidata_to_filp(&nd, flags);
- put_filp(f);
return ERR_PTR(error);
}
EXPORT_SYMBOL(filp_open);
+/**
+ * lookup_instantiate_filp - instantiates the open intent filp
+ * @nd: pointer to nameidata
+ * @dentry: pointer to dentry
+ * @open: open callback
+ *
+ * Helper for filesystems that want to use lookup open intents and pass back
+ * a fully instantiated struct file to the caller.
+ * This function is meant to be called from within a filesystem's
+ * lookup method.
+ * Note that in case of error, nd->intent.open.file is destroyed, but the
+ * path information remains valid.
+ * If the open callback is set to NULL, then the standard f_op->open()
+ * filesystem callback is substituted.
+ */
+struct file *lookup_instantiate_filp(struct nameidata *nd, struct dentry *dentry,
+ int (*open)(struct inode *, struct file *))
+{
+ if (IS_ERR(nd->intent.open.file))
+ goto out;
+ if (IS_ERR(dentry))
+ goto out_err;
+ nd->intent.open.file = __dentry_open(dget(dentry), mntget(nd->mnt),
+ nd->intent.open.flags - 1,
+ nd->intent.open.file,
+ open);
+out:
+ return nd->intent.open.file;
+out_err:
+ release_open_intent(nd);
+ nd->intent.open.file = (struct file *)dentry;
+ goto out;
+}
+EXPORT_SYMBOL_GPL(lookup_instantiate_filp);
+
+/**
+ * nameidata_to_filp - convert a nameidata to an open filp.
+ * @nd: pointer to nameidata
+ * @flags: open flags
+ *
+ * Note that this function destroys the original nameidata
+ */
+struct file *nameidata_to_filp(struct nameidata *nd, int flags)
+{
+ struct file *filp;
+
+ /* Pick up the filp from the open intent */
+ filp = nd->intent.open.file;
+ /* Has the filesystem initialised the file for us? */
+ if (filp->f_dentry == NULL)
+ filp = __dentry_open(nd->dentry, nd->mnt, flags, filp, NULL);
+ else
+ path_release(nd);
+ return filp;
+}
+
+/*
+ * dentry_open() will have done dput(dentry) and mntput(mnt) if it returns an
+ * error.
+ */
struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags)
{
int error;
@@ -843,10 +902,13 @@ struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags)
error = -ENFILE;
f = get_empty_filp();
- if (f == NULL)
+ if (f == NULL) {
+ dput(dentry);
+ mntput(mnt);
return ERR_PTR(error);
+ }
- return __dentry_open(dentry, mnt, flags, f);
+ return __dentry_open(dentry, mnt, flags, f, NULL);
}
EXPORT_SYMBOL(dentry_open);
diff --git a/fs/openpromfs/inode.c b/fs/openpromfs/inode.c
index 1be11ce96b0f..aeb0106890e4 100644
--- a/fs/openpromfs/inode.c
+++ b/fs/openpromfs/inode.c
@@ -1088,8 +1088,7 @@ static void __exit exit_openprom_fs(void)
unregister_filesystem(&openprom_fs_type);
free_pages ((unsigned long)nodes, alloced);
for (i = 0; i < aliases_nodes; i++)
- if (alias_names [i])
- kfree (alias_names [i]);
+ kfree (alias_names [i]);
nodes = NULL;
}
diff --git a/fs/partitions/check.c b/fs/partitions/check.c
index 77e178f13162..8dc1822a7022 100644
--- a/fs/partitions/check.c
+++ b/fs/partitions/check.c
@@ -192,6 +192,7 @@ check_partition(struct gendisk *hd, struct block_device *bdev)
struct part_attribute {
struct attribute attr;
ssize_t (*show)(struct hd_struct *,char *);
+ ssize_t (*store)(struct hd_struct *,const char *, size_t);
};
static ssize_t
@@ -201,14 +202,33 @@ part_attr_show(struct kobject * kobj, struct attribute * attr, char * page)
struct part_attribute * part_attr = container_of(attr,struct part_attribute,attr);
ssize_t ret = 0;
if (part_attr->show)
- ret = part_attr->show(p,page);
+ ret = part_attr->show(p, page);
+ return ret;
+}
+static ssize_t
+part_attr_store(struct kobject * kobj, struct attribute * attr,
+ const char *page, size_t count)
+{
+ struct hd_struct * p = container_of(kobj,struct hd_struct,kobj);
+ struct part_attribute * part_attr = container_of(attr,struct part_attribute,attr);
+ ssize_t ret = 0;
+
+ if (part_attr->store)
+ ret = part_attr->store(p, page, count);
return ret;
}
static struct sysfs_ops part_sysfs_ops = {
.show = part_attr_show,
+ .store = part_attr_store,
};
+static ssize_t part_uevent_store(struct hd_struct * p,
+ const char *page, size_t count)
+{
+ kobject_hotplug(&p->kobj, KOBJ_ADD);
+ return count;
+}
static ssize_t part_dev_read(struct hd_struct * p, char *page)
{
struct gendisk *disk = container_of(p->kobj.parent,struct gendisk,kobj);
@@ -226,9 +246,13 @@ static ssize_t part_size_read(struct hd_struct * p, char *page)
static ssize_t part_stat_read(struct hd_struct * p, char *page)
{
return sprintf(page, "%8u %8llu %8u %8llu\n",
- p->reads, (unsigned long long)p->read_sectors,
- p->writes, (unsigned long long)p->write_sectors);
+ p->ios[0], (unsigned long long)p->sectors[0],
+ p->ios[1], (unsigned long long)p->sectors[1]);
}
+static struct part_attribute part_attr_uevent = {
+ .attr = {.name = "uevent", .mode = S_IWUSR },
+ .store = part_uevent_store
+};
static struct part_attribute part_attr_dev = {
.attr = {.name = "dev", .mode = S_IRUGO },
.show = part_dev_read
@@ -247,6 +271,7 @@ static struct part_attribute part_attr_stat = {
};
static struct attribute * default_attrs[] = {
+ &part_attr_uevent.attr,
&part_attr_dev.attr,
&part_attr_start.attr,
&part_attr_size.attr,
@@ -278,7 +303,8 @@ void delete_partition(struct gendisk *disk, int part)
disk->part[part-1] = NULL;
p->start_sect = 0;
p->nr_sects = 0;
- p->reads = p->writes = p->read_sectors = p->write_sectors = 0;
+ p->ios[0] = p->ios[1] = 0;
+ p->sectors[0] = p->sectors[1] = 0;
devfs_remove("%s/part%d", disk->devfs_name, part);
kobject_unregister(&p->kobj);
}
@@ -430,7 +456,7 @@ void del_gendisk(struct gendisk *disk)
disk->flags &= ~GENHD_FL_UP;
unlink_gendisk(disk);
disk_stat_set_all(disk, 0);
- disk->stamp = disk->stamp_idle = 0;
+ disk->stamp = 0;
devfs_remove_disk(disk);
diff --git a/fs/partitions/ibm.c b/fs/partitions/ibm.c
index d59dcbf2bd4a..6327bcb2d73d 100644
--- a/fs/partitions/ibm.c
+++ b/fs/partitions/ibm.c
@@ -29,7 +29,7 @@
* cyl-cyl-head-head structure
*/
static inline int
-cchh2blk (cchh_t *ptr, struct hd_geometry *geo) {
+cchh2blk (struct vtoc_cchh *ptr, struct hd_geometry *geo) {
return ptr->cc * geo->heads * geo->sectors +
ptr->hh * geo->sectors;
}
@@ -40,7 +40,7 @@ cchh2blk (cchh_t *ptr, struct hd_geometry *geo) {
* cyl-cyl-head-head-block structure
*/
static inline int
-cchhb2blk (cchhb_t *ptr, struct hd_geometry *geo) {
+cchhb2blk (struct vtoc_cchhb *ptr, struct hd_geometry *geo) {
return ptr->cc * geo->heads * geo->sectors +
ptr->hh * geo->sectors +
ptr->b;
@@ -56,7 +56,7 @@ ibm_partition(struct parsed_partitions *state, struct block_device *bdev)
struct hd_geometry *geo;
char type[5] = {0,};
char name[7] = {0,};
- volume_label_t *vlabel;
+ struct vtoc_volume_label *vlabel;
unsigned char *data;
Sector sect;
@@ -64,7 +64,8 @@ ibm_partition(struct parsed_partitions *state, struct block_device *bdev)
goto out_noinfo;
if ((geo = kmalloc(sizeof(struct hd_geometry), GFP_KERNEL)) == NULL)
goto out_nogeo;
- if ((vlabel = kmalloc(sizeof(volume_label_t), GFP_KERNEL)) == NULL)
+ if ((vlabel = kmalloc(sizeof(struct vtoc_volume_label),
+ GFP_KERNEL)) == NULL)
goto out_novlab;
if (ioctl_by_bdev(bdev, BIODASDINFO, (unsigned long)info) != 0 ||
@@ -86,7 +87,7 @@ ibm_partition(struct parsed_partitions *state, struct block_device *bdev)
strncpy(name, data + 8, 6);
else
strncpy(name, data + 4, 6);
- memcpy (vlabel, data, sizeof(volume_label_t));
+ memcpy (vlabel, data, sizeof(struct vtoc_volume_label));
put_dev_sector(sect);
EBCASC(type, 4);
@@ -129,9 +130,9 @@ ibm_partition(struct parsed_partitions *state, struct block_device *bdev)
counter = 0;
while ((data = read_dev_sector(bdev, blk*(blocksize/512),
&sect)) != NULL) {
- format1_label_t f1;
+ struct vtoc_format1_label f1;
- memcpy(&f1, data, sizeof(format1_label_t));
+ memcpy(&f1, data, sizeof(struct vtoc_format1_label));
put_dev_sector(sect);
/* skip FMT4 / FMT5 / FMT7 labels */
diff --git a/fs/pnode.c b/fs/pnode.c
new file mode 100644
index 000000000000..aeeec8ba8dd2
--- /dev/null
+++ b/fs/pnode.c
@@ -0,0 +1,305 @@
+/*
+ * linux/fs/pnode.c
+ *
+ * (C) Copyright IBM Corporation 2005.
+ * Released under GPL v2.
+ * Author : Ram Pai (linuxram@us.ibm.com)
+ *
+ */
+#include <linux/namespace.h>
+#include <linux/mount.h>
+#include <linux/fs.h>
+#include "pnode.h"
+
+/* return the next shared peer mount of @p */
+static inline struct vfsmount *next_peer(struct vfsmount *p)
+{
+ return list_entry(p->mnt_share.next, struct vfsmount, mnt_share);
+}
+
+static inline struct vfsmount *first_slave(struct vfsmount *p)
+{
+ return list_entry(p->mnt_slave_list.next, struct vfsmount, mnt_slave);
+}
+
+static inline struct vfsmount *next_slave(struct vfsmount *p)
+{
+ return list_entry(p->mnt_slave.next, struct vfsmount, mnt_slave);
+}
+
+static int do_make_slave(struct vfsmount *mnt)
+{
+ struct vfsmount *peer_mnt = mnt, *master = mnt->mnt_master;
+ struct vfsmount *slave_mnt;
+
+ /*
+ * slave 'mnt' to a peer mount that has the
+ * same root dentry. If none is available than
+ * slave it to anything that is available.
+ */
+ while ((peer_mnt = next_peer(peer_mnt)) != mnt &&
+ peer_mnt->mnt_root != mnt->mnt_root) ;
+
+ if (peer_mnt == mnt) {
+ peer_mnt = next_peer(mnt);
+ if (peer_mnt == mnt)
+ peer_mnt = NULL;
+ }
+ list_del_init(&mnt->mnt_share);
+
+ if (peer_mnt)
+ master = peer_mnt;
+
+ if (master) {
+ list_for_each_entry(slave_mnt, &mnt->mnt_slave_list, mnt_slave)
+ slave_mnt->mnt_master = master;
+ list_del(&mnt->mnt_slave);
+ list_add(&mnt->mnt_slave, &master->mnt_slave_list);
+ list_splice(&mnt->mnt_slave_list, master->mnt_slave_list.prev);
+ INIT_LIST_HEAD(&mnt->mnt_slave_list);
+ } else {
+ struct list_head *p = &mnt->mnt_slave_list;
+ while (!list_empty(p)) {
+ slave_mnt = list_entry(p->next,
+ struct vfsmount, mnt_slave);
+ list_del_init(&slave_mnt->mnt_slave);
+ slave_mnt->mnt_master = NULL;
+ }
+ }
+ mnt->mnt_master = master;
+ CLEAR_MNT_SHARED(mnt);
+ INIT_LIST_HEAD(&mnt->mnt_slave_list);
+ return 0;
+}
+
+void change_mnt_propagation(struct vfsmount *mnt, int type)
+{
+ if (type == MS_SHARED) {
+ set_mnt_shared(mnt);
+ return;
+ }
+ do_make_slave(mnt);
+ if (type != MS_SLAVE) {
+ list_del_init(&mnt->mnt_slave);
+ mnt->mnt_master = NULL;
+ if (type == MS_UNBINDABLE)
+ mnt->mnt_flags |= MNT_UNBINDABLE;
+ }
+}
+
+/*
+ * get the next mount in the propagation tree.
+ * @m: the mount seen last
+ * @origin: the original mount from where the tree walk initiated
+ */
+static struct vfsmount *propagation_next(struct vfsmount *m,
+ struct vfsmount *origin)
+{
+ /* are there any slaves of this mount? */
+ if (!IS_MNT_NEW(m) && !list_empty(&m->mnt_slave_list))
+ return first_slave(m);
+
+ while (1) {
+ struct vfsmount *next;
+ struct vfsmount *master = m->mnt_master;
+
+ if ( master == origin->mnt_master ) {
+ next = next_peer(m);
+ return ((next == origin) ? NULL : next);
+ } else if (m->mnt_slave.next != &master->mnt_slave_list)
+ return next_slave(m);
+
+ /* back at master */
+ m = master;
+ }
+}
+
+/*
+ * return the source mount to be used for cloning
+ *
+ * @dest the current destination mount
+ * @last_dest the last seen destination mount
+ * @last_src the last seen source mount
+ * @type return CL_SLAVE if the new mount has to be
+ * cloned as a slave.
+ */
+static struct vfsmount *get_source(struct vfsmount *dest,
+ struct vfsmount *last_dest,
+ struct vfsmount *last_src,
+ int *type)
+{
+ struct vfsmount *p_last_src = NULL;
+ struct vfsmount *p_last_dest = NULL;
+ *type = CL_PROPAGATION;;
+
+ if (IS_MNT_SHARED(dest))
+ *type |= CL_MAKE_SHARED;
+
+ while (last_dest != dest->mnt_master) {
+ p_last_dest = last_dest;
+ p_last_src = last_src;
+ last_dest = last_dest->mnt_master;
+ last_src = last_src->mnt_master;
+ }
+
+ if (p_last_dest) {
+ do {
+ p_last_dest = next_peer(p_last_dest);
+ } while (IS_MNT_NEW(p_last_dest));
+ }
+
+ if (dest != p_last_dest) {
+ *type |= CL_SLAVE;
+ return last_src;
+ } else
+ return p_last_src;
+}
+
+/*
+ * mount 'source_mnt' under the destination 'dest_mnt' at
+ * dentry 'dest_dentry'. And propagate that mount to
+ * all the peer and slave mounts of 'dest_mnt'.
+ * Link all the new mounts into a propagation tree headed at
+ * source_mnt. Also link all the new mounts using ->mnt_list
+ * headed at source_mnt's ->mnt_list
+ *
+ * @dest_mnt: destination mount.
+ * @dest_dentry: destination dentry.
+ * @source_mnt: source mount.
+ * @tree_list : list of heads of trees to be attached.
+ */
+int propagate_mnt(struct vfsmount *dest_mnt, struct dentry *dest_dentry,
+ struct vfsmount *source_mnt, struct list_head *tree_list)
+{
+ struct vfsmount *m, *child;
+ int ret = 0;
+ struct vfsmount *prev_dest_mnt = dest_mnt;
+ struct vfsmount *prev_src_mnt = source_mnt;
+ LIST_HEAD(tmp_list);
+ LIST_HEAD(umount_list);
+
+ for (m = propagation_next(dest_mnt, dest_mnt); m;
+ m = propagation_next(m, dest_mnt)) {
+ int type;
+ struct vfsmount *source;
+
+ if (IS_MNT_NEW(m))
+ continue;
+
+ source = get_source(m, prev_dest_mnt, prev_src_mnt, &type);
+
+ if (!(child = copy_tree(source, source->mnt_root, type))) {
+ ret = -ENOMEM;
+ list_splice(tree_list, tmp_list.prev);
+ goto out;
+ }
+
+ if (is_subdir(dest_dentry, m->mnt_root)) {
+ mnt_set_mountpoint(m, dest_dentry, child);
+ list_add_tail(&child->mnt_hash, tree_list);
+ } else {
+ /*
+ * This can happen if the parent mount was bind mounted
+ * on some subdirectory of a shared/slave mount.
+ */
+ list_add_tail(&child->mnt_hash, &tmp_list);
+ }
+ prev_dest_mnt = m;
+ prev_src_mnt = child;
+ }
+out:
+ spin_lock(&vfsmount_lock);
+ while (!list_empty(&tmp_list)) {
+ child = list_entry(tmp_list.next, struct vfsmount, mnt_hash);
+ list_del_init(&child->mnt_hash);
+ umount_tree(child, 0, &umount_list);
+ }
+ spin_unlock(&vfsmount_lock);
+ release_mounts(&umount_list);
+ return ret;
+}
+
+/*
+ * return true if the refcount is greater than count
+ */
+static inline int do_refcount_check(struct vfsmount *mnt, int count)
+{
+ int mycount = atomic_read(&mnt->mnt_count);
+ return (mycount > count);
+}
+
+/*
+ * check if the mount 'mnt' can be unmounted successfully.
+ * @mnt: the mount to be checked for unmount
+ * NOTE: unmounting 'mnt' would naturally propagate to all
+ * other mounts its parent propagates to.
+ * Check if any of these mounts that **do not have submounts**
+ * have more references than 'refcnt'. If so return busy.
+ */
+int propagate_mount_busy(struct vfsmount *mnt, int refcnt)
+{
+ struct vfsmount *m, *child;
+ struct vfsmount *parent = mnt->mnt_parent;
+ int ret = 0;
+
+ if (mnt == parent)
+ return do_refcount_check(mnt, refcnt);
+
+ /*
+ * quickly check if the current mount can be unmounted.
+ * If not, we don't have to go checking for all other
+ * mounts
+ */
+ if (!list_empty(&mnt->mnt_mounts) || do_refcount_check(mnt, refcnt))
+ return 1;
+
+ for (m = propagation_next(parent, parent); m;
+ m = propagation_next(m, parent)) {
+ child = __lookup_mnt(m, mnt->mnt_mountpoint, 0);
+ if (child && list_empty(&child->mnt_mounts) &&
+ (ret = do_refcount_check(child, 1)))
+ break;
+ }
+ return ret;
+}
+
+/*
+ * NOTE: unmounting 'mnt' naturally propagates to all other mounts its
+ * parent propagates to.
+ */
+static void __propagate_umount(struct vfsmount *mnt)
+{
+ struct vfsmount *parent = mnt->mnt_parent;
+ struct vfsmount *m;
+
+ BUG_ON(parent == mnt);
+
+ for (m = propagation_next(parent, parent); m;
+ m = propagation_next(m, parent)) {
+
+ struct vfsmount *child = __lookup_mnt(m,
+ mnt->mnt_mountpoint, 0);
+ /*
+ * umount the child only if the child has no
+ * other children
+ */
+ if (child && list_empty(&child->mnt_mounts)) {
+ list_del(&child->mnt_hash);
+ list_add_tail(&child->mnt_hash, &mnt->mnt_hash);
+ }
+ }
+}
+
+/*
+ * collect all mounts that receive propagation from the mount in @list,
+ * and return these additional mounts in the same list.
+ * @list: the list of mounts to be unmounted.
+ */
+int propagate_umount(struct list_head *list)
+{
+ struct vfsmount *mnt;
+
+ list_for_each_entry(mnt, list, mnt_hash)
+ __propagate_umount(mnt);
+ return 0;
+}
diff --git a/fs/pnode.h b/fs/pnode.h
new file mode 100644
index 000000000000..020e1bb60fdb
--- /dev/null
+++ b/fs/pnode.h
@@ -0,0 +1,37 @@
+/*
+ * linux/fs/pnode.h
+ *
+ * (C) Copyright IBM Corporation 2005.
+ * Released under GPL v2.
+ *
+ */
+#ifndef _LINUX_PNODE_H
+#define _LINUX_PNODE_H
+
+#include <linux/list.h>
+#include <linux/mount.h>
+
+#define IS_MNT_SHARED(mnt) (mnt->mnt_flags & MNT_SHARED)
+#define IS_MNT_SLAVE(mnt) (mnt->mnt_master)
+#define IS_MNT_NEW(mnt) (!mnt->mnt_namespace)
+#define CLEAR_MNT_SHARED(mnt) (mnt->mnt_flags &= ~MNT_SHARED)
+#define IS_MNT_UNBINDABLE(mnt) (mnt->mnt_flags & MNT_UNBINDABLE)
+
+#define CL_EXPIRE 0x01
+#define CL_SLAVE 0x02
+#define CL_COPY_ALL 0x04
+#define CL_MAKE_SHARED 0x08
+#define CL_PROPAGATION 0x10
+
+static inline void set_mnt_shared(struct vfsmount *mnt)
+{
+ mnt->mnt_flags &= ~MNT_PNODE_MASK;
+ mnt->mnt_flags |= MNT_SHARED;
+}
+
+void change_mnt_propagation(struct vfsmount *, int);
+int propagate_mnt(struct vfsmount *, struct dentry *, struct vfsmount *,
+ struct list_head *);
+int propagate_umount(struct list_head *);
+int propagate_mount_busy(struct vfsmount *, int);
+#endif /* _LINUX_PNODE_H */
diff --git a/fs/proc/array.c b/fs/proc/array.c
index d84eecacbeaf..3e1239e4b303 100644
--- a/fs/proc/array.c
+++ b/fs/proc/array.c
@@ -438,7 +438,7 @@ static int do_task_stat(struct task_struct *task, char * buffer, int whole)
jiffies_to_clock_t(it_real_value),
start_time,
vsize,
- mm ? get_mm_counter(mm, rss) : 0, /* you might want to shift this left 3 */
+ mm ? get_mm_rss(mm) : 0,
rsslim,
mm ? mm->start_code : 0,
mm ? mm->end_code : 0,
diff --git a/fs/proc/base.c b/fs/proc/base.c
index a170450aadb1..634355e16986 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -70,6 +70,7 @@
#include <linux/seccomp.h>
#include <linux/cpuset.h>
#include <linux/audit.h>
+#include <linux/poll.h>
#include "internal.h"
/*
@@ -660,26 +661,38 @@ static struct file_operations proc_smaps_operations = {
#endif
extern struct seq_operations mounts_op;
+struct proc_mounts {
+ struct seq_file m;
+ int event;
+};
+
static int mounts_open(struct inode *inode, struct file *file)
{
struct task_struct *task = proc_task(inode);
- int ret = seq_open(file, &mounts_op);
+ struct namespace *namespace;
+ struct proc_mounts *p;
+ int ret = -EINVAL;
- if (!ret) {
- struct seq_file *m = file->private_data;
- struct namespace *namespace;
- task_lock(task);
- namespace = task->namespace;
- if (namespace)
- get_namespace(namespace);
- task_unlock(task);
-
- if (namespace)
- m->private = namespace;
- else {
- seq_release(inode, file);
- ret = -EINVAL;
+ task_lock(task);
+ namespace = task->namespace;
+ if (namespace)
+ get_namespace(namespace);
+ task_unlock(task);
+
+ if (namespace) {
+ ret = -ENOMEM;
+ p = kmalloc(sizeof(struct proc_mounts), GFP_KERNEL);
+ if (p) {
+ file->private_data = &p->m;
+ ret = seq_open(file, &mounts_op);
+ if (!ret) {
+ p->m.private = namespace;
+ p->event = namespace->event;
+ return 0;
+ }
+ kfree(p);
}
+ put_namespace(namespace);
}
return ret;
}
@@ -692,11 +705,30 @@ static int mounts_release(struct inode *inode, struct file *file)
return seq_release(inode, file);
}
+static unsigned mounts_poll(struct file *file, poll_table *wait)
+{
+ struct proc_mounts *p = file->private_data;
+ struct namespace *ns = p->m.private;
+ unsigned res = 0;
+
+ poll_wait(file, &ns->poll, wait);
+
+ spin_lock(&vfsmount_lock);
+ if (p->event != ns->event) {
+ p->event = ns->event;
+ res = POLLERR;
+ }
+ spin_unlock(&vfsmount_lock);
+
+ return res;
+}
+
static struct file_operations proc_mounts_operations = {
.open = mounts_open,
.read = seq_read,
.llseek = seq_lseek,
.release = mounts_release,
+ .poll = mounts_poll,
};
#define PROC_BLOCK_SIZE (3*1024) /* 4K page size but our output routines use some slack for overruns */
diff --git a/fs/proc/generic.c b/fs/proc/generic.c
index 8a8c34461d48..b638fb500743 100644
--- a/fs/proc/generic.c
+++ b/fs/proc/generic.c
@@ -533,7 +533,7 @@ static void proc_kill_inodes(struct proc_dir_entry *de)
*/
file_list_lock();
list_for_each(p, &sb->s_files) {
- struct file * filp = list_entry(p, struct file, f_list);
+ struct file * filp = list_entry(p, struct file, f_u.fu_list);
struct dentry * dentry = filp->f_dentry;
struct inode * inode;
struct file_operations *fops;
diff --git a/fs/proc/inode.c b/fs/proc/inode.c
index effa6c0c467a..e6a818a93f3d 100644
--- a/fs/proc/inode.c
+++ b/fs/proc/inode.c
@@ -156,10 +156,13 @@ struct inode *proc_get_inode(struct super_block *sb, unsigned int ino,
WARN_ON(de && de->deleted);
+ if (de != NULL && !try_module_get(de->owner))
+ goto out_mod;
+
inode = iget(sb, ino);
if (!inode)
- goto out_fail;
-
+ goto out_ino;
+
PROC_I(inode)->pde = de;
if (de) {
if (de->mode) {
@@ -171,20 +174,20 @@ struct inode *proc_get_inode(struct super_block *sb, unsigned int ino,
inode->i_size = de->size;
if (de->nlink)
inode->i_nlink = de->nlink;
- if (!try_module_get(de->owner))
- goto out_fail;
if (de->proc_iops)
inode->i_op = de->proc_iops;
if (de->proc_fops)
inode->i_fop = de->proc_fops;
}
-out:
return inode;
-out_fail:
+out_ino:
+ if (de != NULL)
+ module_put(de->owner);
+out_mod:
de_put(de);
- goto out;
+ return NULL;
}
int proc_fill_super(struct super_block *s, void *data, int silent)
diff --git a/fs/proc/proc_devtree.c b/fs/proc/proc_devtree.c
index 6fd57f154197..fb117b74809e 100644
--- a/fs/proc/proc_devtree.c
+++ b/fs/proc/proc_devtree.c
@@ -49,6 +49,39 @@ static int property_read_proc(char *page, char **start, off_t off,
*/
/*
+ * Add a property to a node
+ */
+static struct proc_dir_entry *
+__proc_device_tree_add_prop(struct proc_dir_entry *de, struct property *pp)
+{
+ struct proc_dir_entry *ent;
+
+ /*
+ * Unfortunately proc_register puts each new entry
+ * at the beginning of the list. So we rearrange them.
+ */
+ ent = create_proc_read_entry(pp->name,
+ strncmp(pp->name, "security-", 9)
+ ? S_IRUGO : S_IRUSR, de,
+ property_read_proc, pp);
+ if (ent == NULL)
+ return NULL;
+
+ if (!strncmp(pp->name, "security-", 9))
+ ent->size = 0; /* don't leak number of password chars */
+ else
+ ent->size = pp->length;
+
+ return ent;
+}
+
+
+void proc_device_tree_add_prop(struct proc_dir_entry *pde, struct property *prop)
+{
+ __proc_device_tree_add_prop(pde, prop);
+}
+
+/*
* Process a node, adding entries for its children and its properties.
*/
void proc_device_tree_add_node(struct device_node *np,
@@ -57,11 +90,9 @@ void proc_device_tree_add_node(struct device_node *np,
struct property *pp;
struct proc_dir_entry *ent;
struct device_node *child;
- struct proc_dir_entry *list = NULL, **lastp;
const char *p;
set_node_proc_entry(np, de);
- lastp = &list;
for (child = NULL; (child = of_get_next_child(np, child));) {
p = strrchr(child->full_name, '/');
if (!p)
@@ -71,9 +102,6 @@ void proc_device_tree_add_node(struct device_node *np,
ent = proc_mkdir(p, de);
if (ent == 0)
break;
- *lastp = ent;
- ent->next = NULL;
- lastp = &ent->next;
proc_device_tree_add_node(child, ent);
}
of_node_put(child);
@@ -84,7 +112,7 @@ void proc_device_tree_add_node(struct device_node *np,
* properties are quite unimportant for us though, thus we
* simply "skip" them here, but we do have to check.
*/
- for (ent = list; ent != NULL; ent = ent->next)
+ for (ent = de->subdir; ent != NULL; ent = ent->next)
if (!strcmp(ent->name, pp->name))
break;
if (ent != NULL) {
@@ -94,25 +122,10 @@ void proc_device_tree_add_node(struct device_node *np,
continue;
}
- /*
- * Unfortunately proc_register puts each new entry
- * at the beginning of the list. So we rearrange them.
- */
- ent = create_proc_read_entry(pp->name,
- strncmp(pp->name, "security-", 9)
- ? S_IRUGO : S_IRUSR, de,
- property_read_proc, pp);
+ ent = __proc_device_tree_add_prop(de, pp);
if (ent == 0)
break;
- if (!strncmp(pp->name, "security-", 9))
- ent->size = 0; /* don't leak number of password chars */
- else
- ent->size = pp->length;
- ent->next = NULL;
- *lastp = ent;
- lastp = &ent->next;
}
- de->subdir = list;
}
/*
diff --git a/fs/proc/proc_misc.c b/fs/proc/proc_misc.c
index a3453555a94e..5b6b0b6038a7 100644
--- a/fs/proc/proc_misc.c
+++ b/fs/proc/proc_misc.c
@@ -629,12 +629,4 @@ void __init proc_misc_init(void)
if (entry)
entry->proc_fops = &proc_sysrq_trigger_operations;
#endif
-#ifdef CONFIG_PPC32
- {
- extern struct file_operations ppc_htab_operations;
- entry = create_proc_entry("ppc_htab", S_IRUGO|S_IWUSR, NULL);
- if (entry)
- entry->proc_fops = &ppc_htab_operations;
- }
-#endif
}
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
index c7ef3e48e35b..d2fa42006d8f 100644
--- a/fs/proc/task_mmu.c
+++ b/fs/proc/task_mmu.c
@@ -14,22 +14,41 @@
char *task_mem(struct mm_struct *mm, char *buffer)
{
unsigned long data, text, lib;
+ unsigned long hiwater_vm, total_vm, hiwater_rss, total_rss;
+
+ /*
+ * Note: to minimize their overhead, mm maintains hiwater_vm and
+ * hiwater_rss only when about to *lower* total_vm or rss. Any
+ * collector of these hiwater stats must therefore get total_vm
+ * and rss too, which will usually be the higher. Barriers? not
+ * worth the effort, such snapshots can always be inconsistent.
+ */
+ hiwater_vm = total_vm = mm->total_vm;
+ if (hiwater_vm < mm->hiwater_vm)
+ hiwater_vm = mm->hiwater_vm;
+ hiwater_rss = total_rss = get_mm_rss(mm);
+ if (hiwater_rss < mm->hiwater_rss)
+ hiwater_rss = mm->hiwater_rss;
data = mm->total_vm - mm->shared_vm - mm->stack_vm;
text = (PAGE_ALIGN(mm->end_code) - (mm->start_code & PAGE_MASK)) >> 10;
lib = (mm->exec_vm << (PAGE_SHIFT-10)) - text;
buffer += sprintf(buffer,
+ "VmPeak:\t%8lu kB\n"
"VmSize:\t%8lu kB\n"
"VmLck:\t%8lu kB\n"
+ "VmHWM:\t%8lu kB\n"
"VmRSS:\t%8lu kB\n"
"VmData:\t%8lu kB\n"
"VmStk:\t%8lu kB\n"
"VmExe:\t%8lu kB\n"
"VmLib:\t%8lu kB\n"
"VmPTE:\t%8lu kB\n",
- (mm->total_vm - mm->reserved_vm) << (PAGE_SHIFT-10),
+ hiwater_vm << (PAGE_SHIFT-10),
+ (total_vm - mm->reserved_vm) << (PAGE_SHIFT-10),
mm->locked_vm << (PAGE_SHIFT-10),
- get_mm_counter(mm, rss) << (PAGE_SHIFT-10),
+ hiwater_rss << (PAGE_SHIFT-10),
+ total_rss << (PAGE_SHIFT-10),
data << (PAGE_SHIFT-10),
mm->stack_vm << (PAGE_SHIFT-10), text, lib,
(PTRS_PER_PTE*sizeof(pte_t)*mm->nr_ptes) >> 10);
@@ -44,13 +63,11 @@ unsigned long task_vsize(struct mm_struct *mm)
int task_statm(struct mm_struct *mm, int *shared, int *text,
int *data, int *resident)
{
- int rss = get_mm_counter(mm, rss);
-
- *shared = rss - get_mm_counter(mm, anon_rss);
+ *shared = get_mm_counter(mm, file_rss);
*text = (PAGE_ALIGN(mm->end_code) - (mm->start_code & PAGE_MASK))
>> PAGE_SHIFT;
*data = mm->total_vm - mm->shared_vm;
- *resident = rss;
+ *resident = *shared + get_mm_counter(mm, anon_rss);
return mm->total_vm;
}
@@ -186,13 +203,14 @@ static void smaps_pte_range(struct vm_area_struct *vma, pmd_t *pmd,
struct mem_size_stats *mss)
{
pte_t *pte, ptent;
+ spinlock_t *ptl;
unsigned long pfn;
struct page *page;
- pte = pte_offset_map(pmd, addr);
+ pte = pte_offset_map_lock(vma->vm_mm, pmd, addr, &ptl);
do {
ptent = *pte;
- if (pte_none(ptent) || !pte_present(ptent))
+ if (!pte_present(ptent))
continue;
mss->resident += PAGE_SIZE;
@@ -213,8 +231,8 @@ static void smaps_pte_range(struct vm_area_struct *vma, pmd_t *pmd,
mss->private_clean += PAGE_SIZE;
}
} while (pte++, addr += PAGE_SIZE, addr != end);
- pte_unmap(pte - 1);
- cond_resched_lock(&vma->vm_mm->page_table_lock);
+ pte_unmap_unlock(pte - 1, ptl);
+ cond_resched();
}
static inline void smaps_pmd_range(struct vm_area_struct *vma, pud_t *pud,
@@ -268,17 +286,11 @@ static inline void smaps_pgd_range(struct vm_area_struct *vma,
static int show_smap(struct seq_file *m, void *v)
{
struct vm_area_struct *vma = v;
- struct mm_struct *mm = vma->vm_mm;
struct mem_size_stats mss;
memset(&mss, 0, sizeof mss);
-
- if (mm) {
- spin_lock(&mm->page_table_lock);
+ if (vma->vm_mm)
smaps_pgd_range(vma, vma->vm_start, vma->vm_end, &mss);
- spin_unlock(&mm->page_table_lock);
- }
-
return show_map_internal(m, v, &mss);
}
@@ -407,7 +419,6 @@ static struct numa_maps *get_numa_maps(const struct vm_area_struct *vma)
for_each_node(i)
md->node[i] =0;
- spin_lock(&mm->page_table_lock);
for (vaddr = vma->vm_start; vaddr < vma->vm_end; vaddr += PAGE_SIZE) {
page = follow_page(mm, vaddr, 0);
if (page) {
@@ -422,8 +433,8 @@ static struct numa_maps *get_numa_maps(const struct vm_area_struct *vma)
md->anon++;
md->node[page_to_nid(page)]++;
}
+ cond_resched();
}
- spin_unlock(&mm->page_table_lock);
return md;
}
@@ -469,7 +480,7 @@ static int show_numa_map(struct seq_file *m, void *v)
seq_printf(m, " interleave={");
first = 1;
for_each_node(n) {
- if (test_bit(n, pol->v.nodes)) {
+ if (node_isset(n, pol->v.nodes)) {
if (!first)
seq_putc(m,',');
else
diff --git a/fs/quota.c b/fs/quota.c
index f5d1cff55196..612e04db4b93 100644
--- a/fs/quota.c
+++ b/fs/quota.c
@@ -15,6 +15,7 @@
#include <linux/security.h>
#include <linux/syscalls.h>
#include <linux/buffer_head.h>
+#include <linux/quotaops.h>
/* Check validity of generic quotactl commands */
static int generic_quotactl_valid(struct super_block *sb, int type, int cmd, qid_t id)
@@ -118,6 +119,10 @@ static int xqm_quotactl_valid(struct super_block *sb, int type, int cmd, qid_t i
if (!sb->s_qcop->get_xquota)
return -ENOSYS;
break;
+ case Q_XQUOTASYNC:
+ if (!sb->s_qcop->quota_sync)
+ return -ENOSYS;
+ break;
default:
return -EINVAL;
}
@@ -128,7 +133,7 @@ static int xqm_quotactl_valid(struct super_block *sb, int type, int cmd, qid_t i
(type == XQM_GRPQUOTA && !in_egroup_p(id))) &&
!capable(CAP_SYS_ADMIN))
return -EPERM;
- } else if (cmd != Q_XGETQSTAT) {
+ } else if (cmd != Q_XGETQSTAT && cmd != Q_XQUOTASYNC) {
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
}
@@ -322,6 +327,8 @@ static int do_quotactl(struct super_block *sb, int type, int cmd, qid_t id, void
return -EFAULT;
return 0;
}
+ case Q_XQUOTASYNC:
+ return sb->s_qcop->quota_sync(sb, type);
/* We never reach here unless validity check is broken */
default:
BUG();
diff --git a/fs/reiserfs/file.c b/fs/reiserfs/file.c
index c20babd6216d..7892a865b58a 100644
--- a/fs/reiserfs/file.c
+++ b/fs/reiserfs/file.c
@@ -251,12 +251,12 @@ static int reiserfs_allocate_blocks_for_region(struct reiserfs_transaction_handl
blocks_to_allocate,
blocks_to_allocate);
if (res != CARRY_ON) {
- res = -ENOSPC;
+ res = res == QUOTA_EXCEEDED ? -EDQUOT : -ENOSPC;
pathrelse(&path);
goto error_exit;
}
} else {
- res = -ENOSPC;
+ res = res == QUOTA_EXCEEDED ? -EDQUOT : -ENOSPC;
pathrelse(&path);
goto error_exit;
}
diff --git a/fs/reiserfs/fix_node.c b/fs/reiserfs/fix_node.c
index 2706e2adffab..45829889dcdc 100644
--- a/fs/reiserfs/fix_node.c
+++ b/fs/reiserfs/fix_node.c
@@ -2022,7 +2022,7 @@ static int get_neighbors(struct tree_balance *p_s_tb, int n_h)
}
#ifdef CONFIG_REISERFS_CHECK
-void *reiserfs_kmalloc(size_t size, int flags, struct super_block *s)
+void *reiserfs_kmalloc(size_t size, gfp_t flags, struct super_block *s)
{
void *vp;
static size_t malloced;
diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c
index d76ee6c4f9b8..5f82352b97e1 100644
--- a/fs/reiserfs/inode.c
+++ b/fs/reiserfs/inode.c
@@ -2842,7 +2842,7 @@ static int reiserfs_set_page_dirty(struct page *page)
* even in -o notail mode, we can't be sure an old mount without -o notail
* didn't create files with tails.
*/
-static int reiserfs_releasepage(struct page *page, int unused_gfp_flags)
+static int reiserfs_releasepage(struct page *page, gfp_t unused_gfp_flags)
{
struct inode *inode = page->mapping->host;
struct reiserfs_journal *j = SB_JOURNAL(inode->i_sb);
diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c
index 44b02fc02ebe..42afb5bef111 100644
--- a/fs/reiserfs/super.c
+++ b/fs/reiserfs/super.c
@@ -1024,12 +1024,8 @@ static int reiserfs_parse_options(struct super_block *s, char *options, /* strin
strcpy(REISERFS_SB(s)->s_qf_names[qtype], arg);
*mount_options |= 1 << REISERFS_QUOTA;
} else {
- if (REISERFS_SB(s)->s_qf_names[qtype]) {
- kfree(REISERFS_SB(s)->
- s_qf_names[qtype]);
- REISERFS_SB(s)->s_qf_names[qtype] =
- NULL;
- }
+ kfree(REISERFS_SB(s)->s_qf_names[qtype]);
+ REISERFS_SB(s)->s_qf_names[qtype] = NULL;
}
}
if (c == 'f') {
@@ -1158,11 +1154,10 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg)
if (!reiserfs_parse_options
(s, arg, &mount_options, &blocks, NULL, &commit_max_age)) {
#ifdef CONFIG_QUOTA
- for (i = 0; i < MAXQUOTAS; i++)
- if (REISERFS_SB(s)->s_qf_names[i]) {
- kfree(REISERFS_SB(s)->s_qf_names[i]);
- REISERFS_SB(s)->s_qf_names[i] = NULL;
- }
+ for (i = 0; i < MAXQUOTAS; i++) {
+ kfree(REISERFS_SB(s)->s_qf_names[i]);
+ REISERFS_SB(s)->s_qf_names[i] = NULL;
+ }
#endif
return -EINVAL;
}
@@ -1940,13 +1935,11 @@ static int reiserfs_fill_super(struct super_block *s, void *data, int silent)
brelse(SB_BUFFER_WITH_SB(s));
#ifdef CONFIG_QUOTA
for (j = 0; j < MAXQUOTAS; j++) {
- if (sbi->s_qf_names[j])
- kfree(sbi->s_qf_names[j]);
+ kfree(sbi->s_qf_names[j]);
+ sbi->s_qf_names[j] = NULL;
}
#endif
- if (sbi != NULL) {
- kfree(sbi);
- }
+ kfree(sbi);
s->s_fs_info = NULL;
return errval;
diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c
index 87ac9dc8b381..72e120798677 100644
--- a/fs/reiserfs/xattr.c
+++ b/fs/reiserfs/xattr.c
@@ -453,7 +453,7 @@ static struct page *reiserfs_get_page(struct inode *dir, unsigned long n)
struct page *page;
/* We can deadlock if we try to free dentries,
and an unlink/rmdir has just occured - GFP_NOFS avoids this */
- mapping->flags = (mapping->flags & ~__GFP_BITS_MASK) | GFP_NOFS;
+ mapping_set_gfp_mask(mapping, GFP_NOFS);
page = read_cache_page(mapping, n,
(filler_t *) mapping->a_ops->readpage, NULL);
if (!IS_ERR(page)) {
diff --git a/fs/reiserfs/xattr_acl.c b/fs/reiserfs/xattr_acl.c
index 6703efa3c430..a47ac9aac8b2 100644
--- a/fs/reiserfs/xattr_acl.c
+++ b/fs/reiserfs/xattr_acl.c
@@ -296,8 +296,7 @@ reiserfs_set_acl(struct inode *inode, int type, struct posix_acl *acl)
}
}
- if (value)
- kfree(value);
+ kfree(value);
if (!error) {
/* Release the old one */
diff --git a/fs/seq_file.c b/fs/seq_file.c
index 38ef913767ff..7c40570b71dc 100644
--- a/fs/seq_file.c
+++ b/fs/seq_file.c
@@ -28,13 +28,17 @@
*/
int seq_open(struct file *file, struct seq_operations *op)
{
- struct seq_file *p = kmalloc(sizeof(*p), GFP_KERNEL);
- if (!p)
- return -ENOMEM;
+ struct seq_file *p = file->private_data;
+
+ if (!p) {
+ p = kmalloc(sizeof(*p), GFP_KERNEL);
+ if (!p)
+ return -ENOMEM;
+ file->private_data = p;
+ }
memset(p, 0, sizeof(*p));
sema_init(&p->sem, 1);
p->op = op;
- file->private_data = p;
/*
* Wrappers around seq_open(e.g. swaps_open) need to be
diff --git a/fs/smbfs/request.c b/fs/smbfs/request.c
index 2d85dd7415bb..a0f296d9928a 100644
--- a/fs/smbfs/request.c
+++ b/fs/smbfs/request.c
@@ -786,8 +786,7 @@ int smb_request_recv(struct smb_sb_info *server)
/* We should never be called with any of these states */
case SMB_RECV_END:
case SMB_RECV_REQUEST:
- server->rstate = SMB_RECV_END;
- break;
+ BUG();
}
if (result < 0) {
diff --git a/fs/smbfs/symlink.c b/fs/smbfs/symlink.c
index 0c64bc3a0127..cdc53c4fb381 100644
--- a/fs/smbfs/symlink.c
+++ b/fs/smbfs/symlink.c
@@ -45,7 +45,7 @@ static void *smb_follow_link(struct dentry *dentry, struct nameidata *nd)
int len = smb_proc_read_link(server_from_dentry(dentry),
dentry, link, PATH_MAX - 1);
if (len < 0) {
- putname(link);
+ __putname(link);
link = ERR_PTR(len);
} else {
link[len] = 0;
@@ -59,7 +59,7 @@ static void smb_put_link(struct dentry *dentry, struct nameidata *nd, void *p)
{
char *s = nd_get_link(nd);
if (!IS_ERR(s))
- putname(s);
+ __putname(s);
}
struct inode_operations smb_link_inode_operations =
diff --git a/fs/super.c b/fs/super.c
index 6e57ee252e14..6689dded3c84 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -171,6 +171,7 @@ void deactivate_super(struct super_block *s)
if (atomic_dec_and_lock(&s->s_active, &sb_lock)) {
s->s_count -= S_BIAS-1;
spin_unlock(&sb_lock);
+ DQUOT_OFF(s);
down_write(&s->s_umount);
fs->kill_sb(s);
put_filesystem(fs);
@@ -474,8 +475,6 @@ rescan:
return NULL;
}
-EXPORT_SYMBOL(user_get_super);
-
asmlinkage long sys_ustat(unsigned dev, struct ustat __user * ubuf)
{
struct super_block *s;
@@ -513,7 +512,7 @@ static void mark_files_ro(struct super_block *sb)
struct file *f;
file_list_lock();
- list_for_each_entry(f, &sb->s_files, f_list) {
+ list_for_each_entry(f, &sb->s_files, f_u.fu_list) {
if (S_ISREG(f->f_dentry->d_inode->i_mode) && file_count(f))
f->f_mode &= ~FMODE_WRITE;
}
diff --git a/fs/udf/file.c b/fs/udf/file.c
index bb40d63f328f..01f520c71dc1 100644
--- a/fs/udf/file.c
+++ b/fs/udf/file.c
@@ -186,7 +186,7 @@ int udf_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
{
int result = -EINVAL;
- if ( permission(inode, MAY_READ, NULL) != 0 )
+ if ( file_permission(filp, MAY_READ) != 0 )
{
udf_debug("no permission to access inode %lu\n",
inode->i_ino);
diff --git a/fs/udf/udf_sb.h b/fs/udf/udf_sb.h
index 0e54922daa09..663669810be6 100644
--- a/fs/udf/udf_sb.h
+++ b/fs/udf/udf_sb.h
@@ -39,8 +39,7 @@ static inline struct udf_sb_info *UDF_SB(struct super_block *sb)
{\
if (UDF_SB(X))\
{\
- if (UDF_SB_PARTMAPS(X))\
- kfree(UDF_SB_PARTMAPS(X));\
+ kfree(UDF_SB_PARTMAPS(X));\
UDF_SB_PARTMAPS(X) = NULL;\
}\
}
diff --git a/fs/ufs/super.c b/fs/ufs/super.c
index f036d694ba5a..54828ebcf1ba 100644
--- a/fs/ufs/super.c
+++ b/fs/ufs/super.c
@@ -472,13 +472,14 @@ static int ufs_read_cylinder_structures (struct super_block *sb) {
return 1;
failed:
- if (base) kfree (base);
+ kfree (base);
if (sbi->s_ucg) {
for (i = 0; i < uspi->s_ncg; i++)
- if (sbi->s_ucg[i]) brelse (sbi->s_ucg[i]);
+ if (sbi->s_ucg[i])
+ brelse (sbi->s_ucg[i]);
kfree (sbi->s_ucg);
for (i = 0; i < UFS_MAX_GROUP_LOADED; i++)
- if (sbi->s_ucpi[i]) kfree (sbi->s_ucpi[i]);
+ kfree (sbi->s_ucpi[i]);
}
UFSD(("EXIT (FAILED)\n"))
return 0;
@@ -981,9 +982,10 @@ magic_found:
dalloc_failed:
iput(inode);
failed:
- if (ubh) ubh_brelse_uspi (uspi);
- if (uspi) kfree (uspi);
- if (sbi) kfree(sbi);
+ if (ubh)
+ ubh_brelse_uspi (uspi);
+ kfree (uspi);
+ kfree(sbi);
sb->s_fs_info = NULL;
UFSD(("EXIT (FAILED)\n"))
return -EINVAL;
diff --git a/fs/vfat/namei.c b/fs/vfat/namei.c
index 1c6f6b57ef1c..ef46939c0c1a 100644
--- a/fs/vfat/namei.c
+++ b/fs/vfat/namei.c
@@ -621,8 +621,7 @@ static int vfat_build_slots(struct inode *dir, const unsigned char *name,
}
/* build the entry of long file name */
- for (cksum = i = 0; i < 11; i++)
- cksum = (((cksum&1)<<7)|((cksum&0xfe)>>1)) + msdos_name[i];
+ cksum = fat_checksum(msdos_name);
*nr_slots = usize / 13;
for (ps = slots, i = *nr_slots; i > 0; i--, ps++) {
@@ -888,10 +887,10 @@ static int vfat_rename(struct inode *old_dir, struct dentry *old_dentry,
{
struct buffer_head *dotdot_bh;
struct msdos_dir_entry *dotdot_de;
- loff_t dotdot_i_pos;
struct inode *old_inode, *new_inode;
struct fat_slot_info old_sinfo, sinfo;
struct timespec ts;
+ loff_t dotdot_i_pos, new_i_pos;
int err, is_dir, update_dotdot, corrupt = 0;
old_sinfo.bh = sinfo.bh = dotdot_bh = NULL;
@@ -914,31 +913,24 @@ static int vfat_rename(struct inode *old_dir, struct dentry *old_dentry,
ts = CURRENT_TIME_SEC;
if (new_inode) {
- err = vfat_find(new_dir, &new_dentry->d_name, &sinfo);
- if (err)
- goto out;
- if (MSDOS_I(new_inode)->i_pos != sinfo.i_pos) {
- /* WTF??? Cry and fail. */
- printk(KERN_WARNING "vfat_rename: fs corrupted\n");
- goto out;
- }
-
if (is_dir) {
err = fat_dir_empty(new_inode);
if (err)
goto out;
}
+ new_i_pos = MSDOS_I(new_inode)->i_pos;
fat_detach(new_inode);
} else {
err = vfat_add_entry(new_dir, &new_dentry->d_name, is_dir, 0,
&ts, &sinfo);
if (err)
goto out;
+ new_i_pos = sinfo.i_pos;
}
new_dir->i_version++;
fat_detach(old_inode);
- fat_attach(old_inode, sinfo.i_pos);
+ fat_attach(old_inode, new_i_pos);
if (IS_DIRSYNC(new_dir)) {
err = fat_sync_inode(old_inode);
if (err)
@@ -1002,7 +994,7 @@ error_inode:
fat_detach(old_inode);
fat_attach(old_inode, old_sinfo.i_pos);
if (new_inode) {
- fat_attach(new_inode, sinfo.i_pos);
+ fat_attach(new_inode, new_i_pos);
if (corrupt)
corrupt |= fat_sync_inode(new_inode);
} else {
diff --git a/fs/xattr.c b/fs/xattr.c
index 3f9c64bea151..a9db22557998 100644
--- a/fs/xattr.c
+++ b/fs/xattr.c
@@ -74,8 +74,7 @@ setxattr(struct dentry *d, char __user *name, void __user *value,
}
out:
up(&d->d_inode->i_sem);
- if (kvalue)
- kfree(kvalue);
+ kfree(kvalue);
return error;
}
@@ -143,7 +142,7 @@ getxattr(struct dentry *d, char __user *name, void __user *value, size_t size)
if (size) {
if (size > XATTR_SIZE_MAX)
size = XATTR_SIZE_MAX;
- kvalue = kmalloc(size, GFP_KERNEL);
+ kvalue = kzalloc(size, GFP_KERNEL);
if (!kvalue)
return -ENOMEM;
}
@@ -154,11 +153,15 @@ getxattr(struct dentry *d, char __user *name, void __user *value, size_t size)
error = -EOPNOTSUPP;
if (d->d_inode->i_op && d->d_inode->i_op->getxattr)
error = d->d_inode->i_op->getxattr(d, kname, kvalue, size);
- else if (!strncmp(kname, XATTR_SECURITY_PREFIX,
- sizeof XATTR_SECURITY_PREFIX - 1)) {
+
+ if (!strncmp(kname, XATTR_SECURITY_PREFIX,
+ sizeof XATTR_SECURITY_PREFIX - 1)) {
const char *suffix = kname + sizeof XATTR_SECURITY_PREFIX - 1;
- error = security_inode_getsecurity(d->d_inode, suffix, kvalue,
- size);
+ int rv = security_inode_getsecurity(d->d_inode, suffix, kvalue,
+ size, error);
+ /* Security module active: overwrite error value */
+ if (rv != -EOPNOTSUPP)
+ error = rv;
}
if (error > 0) {
if (size && copy_to_user(value, kvalue, error))
@@ -169,8 +172,7 @@ getxattr(struct dentry *d, char __user *name, void __user *value, size_t size)
error = -E2BIG;
}
out:
- if (kvalue)
- kfree(kvalue);
+ kfree(kvalue);
return error;
}
@@ -255,8 +257,7 @@ listxattr(struct dentry *d, char __user *list, size_t size)
error = -E2BIG;
}
out:
- if (klist)
- kfree(klist);
+ kfree(klist);
return error;
}
diff --git a/fs/xfs/Kconfig b/fs/xfs/Kconfig
index 8e8f32dabe53..bac27d66151d 100644
--- a/fs/xfs/Kconfig
+++ b/fs/xfs/Kconfig
@@ -24,7 +24,7 @@ config XFS_EXPORT
default y
config XFS_QUOTA
- tristate "XFS Quota support"
+ bool "XFS Quota support"
depends on XFS_FS
help
If you say Y here, you will be able to set limits for disk usage on
diff --git a/fs/xfs/Makefile-linux-2.6 b/fs/xfs/Makefile-linux-2.6
index d8c87fa21ad1..97bd4743b461 100644
--- a/fs/xfs/Makefile-linux-2.6
+++ b/fs/xfs/Makefile-linux-2.6
@@ -109,7 +109,6 @@ xfs-y += xfs_alloc.o \
xfs_dfrag.o \
xfs_log.o \
xfs_log_recover.o \
- xfs_macros.o \
xfs_mount.o \
xfs_rename.o \
xfs_trans.o \
diff --git a/fs/xfs/linux-2.6/kmem.c b/fs/xfs/linux-2.6/kmem.c
index d2653b589b1c..aba7fcf881a2 100644
--- a/fs/xfs/linux-2.6/kmem.c
+++ b/fs/xfs/linux-2.6/kmem.c
@@ -1,55 +1,38 @@
/*
- * Copyright (c) 2000-2004 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/vmalloc.h>
#include <linux/highmem.h>
#include <linux/swap.h>
#include <linux/blkdev.h>
-
#include "time.h"
#include "kmem.h"
#define MAX_VMALLOCS 6
#define MAX_SLAB_SIZE 0x20000
-
void *
-kmem_alloc(size_t size, gfp_t flags)
+kmem_alloc(size_t size, unsigned int __nocast flags)
{
- int retries = 0;
- unsigned int lflags = kmem_flags_convert(flags);
- void *ptr;
+ int retries = 0;
+ gfp_t lflags = kmem_flags_convert(flags);
+ void *ptr;
do {
if (size < MAX_SLAB_SIZE || retries > MAX_VMALLOCS)
@@ -67,7 +50,7 @@ kmem_alloc(size_t size, gfp_t flags)
}
void *
-kmem_zalloc(size_t size, gfp_t flags)
+kmem_zalloc(size_t size, unsigned int __nocast flags)
{
void *ptr;
@@ -90,7 +73,7 @@ kmem_free(void *ptr, size_t size)
void *
kmem_realloc(void *ptr, size_t newsize, size_t oldsize,
- gfp_t flags)
+ unsigned int __nocast flags)
{
void *new;
@@ -105,11 +88,11 @@ kmem_realloc(void *ptr, size_t newsize, size_t oldsize,
}
void *
-kmem_zone_alloc(kmem_zone_t *zone, gfp_t flags)
+kmem_zone_alloc(kmem_zone_t *zone, unsigned int __nocast flags)
{
- int retries = 0;
- unsigned int lflags = kmem_flags_convert(flags);
- void *ptr;
+ int retries = 0;
+ gfp_t lflags = kmem_flags_convert(flags);
+ void *ptr;
do {
ptr = kmem_cache_alloc(zone, lflags);
@@ -124,7 +107,7 @@ kmem_zone_alloc(kmem_zone_t *zone, gfp_t flags)
}
void *
-kmem_zone_zalloc(kmem_zone_t *zone, gfp_t flags)
+kmem_zone_zalloc(kmem_zone_t *zone, unsigned int __nocast flags)
{
void *ptr;
diff --git a/fs/xfs/linux-2.6/kmem.h b/fs/xfs/linux-2.6/kmem.h
index ee7010f085bc..c64a29cdfff3 100644
--- a/fs/xfs/linux-2.6/kmem.h
+++ b/fs/xfs/linux-2.6/kmem.h
@@ -1,33 +1,19 @@
/*
- * Copyright (c) 2000-2004 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __XFS_SUPPORT_KMEM_H__
#define __XFS_SUPPORT_KMEM_H__
@@ -44,8 +30,8 @@
#define KM_NOFS 0x0004u
#define KM_MAYFAIL 0x0008u
-#define kmem_zone kmem_cache_s
-#define kmem_zone_t kmem_cache_t
+#define kmem_zone kmem_cache
+#define kmem_zone_t struct kmem_cache
typedef unsigned long xfs_pflags_t;
@@ -81,9 +67,9 @@ typedef unsigned long xfs_pflags_t;
*(NSTATEP) = *(OSTATEP); \
} while (0)
-static __inline unsigned int kmem_flags_convert(gfp_t flags)
+static __inline gfp_t kmem_flags_convert(unsigned int __nocast flags)
{
- unsigned int lflags = __GFP_NOWARN; /* we'll report problems, if need be */
+ gfp_t lflags = __GFP_NOWARN; /* we'll report problems, if need be */
#ifdef DEBUG
if (unlikely(flags & ~(KM_SLEEP|KM_NOSLEEP|KM_NOFS|KM_MAYFAIL))) {
@@ -102,7 +88,7 @@ static __inline unsigned int kmem_flags_convert(gfp_t flags)
if (PFLAGS_TEST_FSTRANS() || (flags & KM_NOFS))
lflags &= ~__GFP_FS;
}
-
+
return lflags;
}
@@ -125,16 +111,16 @@ kmem_zone_destroy(kmem_zone_t *zone)
BUG();
}
-extern void *kmem_zone_zalloc(kmem_zone_t *, gfp_t);
-extern void *kmem_zone_alloc(kmem_zone_t *, gfp_t);
+extern void *kmem_zone_zalloc(kmem_zone_t *, unsigned int __nocast);
+extern void *kmem_zone_alloc(kmem_zone_t *, unsigned int __nocast);
-extern void *kmem_alloc(size_t, gfp_t);
-extern void *kmem_realloc(void *, size_t, size_t, gfp_t);
-extern void *kmem_zalloc(size_t, gfp_t);
-extern void kmem_free(void *, size_t);
+extern void *kmem_alloc(size_t, unsigned int __nocast);
+extern void *kmem_realloc(void *, size_t, size_t, unsigned int __nocast);
+extern void *kmem_zalloc(size_t, unsigned int __nocast);
+extern void kmem_free(void *, size_t);
typedef struct shrinker *kmem_shaker_t;
-typedef int (*kmem_shake_func_t)(int, unsigned int);
+typedef int (*kmem_shake_func_t)(int, gfp_t);
static __inline kmem_shaker_t
kmem_shake_register(kmem_shake_func_t sfunc)
@@ -149,7 +135,7 @@ kmem_shake_deregister(kmem_shaker_t shrinker)
}
static __inline int
-kmem_shake_allow(unsigned int gfp_mask)
+kmem_shake_allow(gfp_t gfp_mask)
{
return (gfp_mask & __GFP_WAIT);
}
diff --git a/fs/xfs/linux-2.6/mrlock.h b/fs/xfs/linux-2.6/mrlock.h
index d2c11a098ff2..16b44c3c2362 100644
--- a/fs/xfs/linux-2.6/mrlock.h
+++ b/fs/xfs/linux-2.6/mrlock.h
@@ -1,33 +1,19 @@
/*
- * Copyright (c) 2000-2004 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __XFS_SUPPORT_MRLOCK_H__
#define __XFS_SUPPORT_MRLOCK_H__
diff --git a/fs/xfs/linux-2.6/mutex.h b/fs/xfs/linux-2.6/mutex.h
index 0b296bb944cb..ce773d89a923 100644
--- a/fs/xfs/linux-2.6/mutex.h
+++ b/fs/xfs/linux-2.6/mutex.h
@@ -1,33 +1,19 @@
/*
- * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __XFS_SUPPORT_MUTEX_H__
#define __XFS_SUPPORT_MUTEX_H__
diff --git a/fs/xfs/linux-2.6/sema.h b/fs/xfs/linux-2.6/sema.h
index 30b67b4e1cbf..194a84490bd1 100644
--- a/fs/xfs/linux-2.6/sema.h
+++ b/fs/xfs/linux-2.6/sema.h
@@ -1,33 +1,19 @@
/*
- * Copyright (c) 2000-2002 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __XFS_SUPPORT_SEMA_H__
#define __XFS_SUPPORT_SEMA_H__
diff --git a/fs/xfs/linux-2.6/spin.h b/fs/xfs/linux-2.6/spin.h
index 0039504069a5..50a6191178f4 100644
--- a/fs/xfs/linux-2.6/spin.h
+++ b/fs/xfs/linux-2.6/spin.h
@@ -1,33 +1,19 @@
/*
- * Copyright (c) 2000-2002 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __XFS_SUPPORT_SPIN_H__
#define __XFS_SUPPORT_SPIN_H__
diff --git a/fs/xfs/linux-2.6/sv.h b/fs/xfs/linux-2.6/sv.h
index 821d3167e05b..9a8ad481b008 100644
--- a/fs/xfs/linux-2.6/sv.h
+++ b/fs/xfs/linux-2.6/sv.h
@@ -1,33 +1,19 @@
/*
- * Copyright (c) 2000-2002 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __XFS_SUPPORT_SV_H__
#define __XFS_SUPPORT_SV_H__
diff --git a/fs/xfs/linux-2.6/time.h b/fs/xfs/linux-2.6/time.h
index b0d2873ab274..387e695a184c 100644
--- a/fs/xfs/linux-2.6/time.h
+++ b/fs/xfs/linux-2.6/time.h
@@ -1,33 +1,19 @@
/*
- * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __XFS_SUPPORT_TIME_H__
#define __XFS_SUPPORT_TIME_H__
diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c
index c6c077978fe3..c6108971b4e6 100644
--- a/fs/xfs/linux-2.6/xfs_aops.c
+++ b/fs/xfs/linux-2.6/xfs_aops.c
@@ -1,39 +1,26 @@
/*
- * Copyright (c) 2000-2005 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-
#include "xfs.h"
-#include "xfs_inum.h"
+#include "xfs_bit.h"
#include "xfs_log.h"
+#include "xfs_inum.h"
#include "xfs_sb.h"
+#include "xfs_ag.h"
#include "xfs_dir.h"
#include "xfs_dir2.h"
#include "xfs_trans.h"
@@ -42,13 +29,13 @@
#include "xfs_bmap_btree.h"
#include "xfs_alloc_btree.h"
#include "xfs_ialloc_btree.h"
-#include "xfs_alloc.h"
-#include "xfs_btree.h"
-#include "xfs_attr_sf.h"
#include "xfs_dir_sf.h"
#include "xfs_dir2_sf.h"
+#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
#include "xfs_inode.h"
+#include "xfs_alloc.h"
+#include "xfs_btree.h"
#include "xfs_error.h"
#include "xfs_rw.h"
#include "xfs_iomap.h"
@@ -761,8 +748,9 @@ xfs_page_state_convert(
if (page->index >= end_index) {
if ((page->index >= end_index + 1) ||
!(i_size_read(inode) & (PAGE_CACHE_SIZE - 1))) {
- err = -EIO;
- goto error;
+ if (startio)
+ unlock_page(page);
+ return 0;
}
}
@@ -948,15 +936,18 @@ __linvfs_get_block(
{
vnode_t *vp = LINVFS_GET_VP(inode);
xfs_iomap_t iomap;
+ xfs_off_t offset;
+ ssize_t size;
int retpbbm = 1;
int error;
- ssize_t size;
- loff_t offset = (loff_t)iblock << inode->i_blkbits;
- if (blocks)
- size = blocks << inode->i_blkbits;
- else
+ if (blocks) {
+ offset = blocks << inode->i_blkbits; /* 64 bit goodness */
+ size = (ssize_t) min_t(xfs_off_t, offset, LONG_MAX);
+ } else {
size = 1 << inode->i_blkbits;
+ }
+ offset = (xfs_off_t)iblock << inode->i_blkbits;
VOP_BMAP(vp, offset, size,
create ? flags : BMAPI_READ, &iomap, &retpbbm, error);
@@ -967,8 +958,8 @@ __linvfs_get_block(
return 0;
if (iomap.iomap_bn != IOMAP_DADDR_NULL) {
- xfs_daddr_t bn;
- loff_t delta;
+ xfs_daddr_t bn;
+ xfs_off_t delta;
/* For unwritten extents do not report a disk address on
* the read case (treat as if we're reading into a hole).
@@ -1000,9 +991,8 @@ __linvfs_get_block(
*/
if (create &&
((!buffer_mapped(bh_result) && !buffer_uptodate(bh_result)) ||
- (offset >= i_size_read(inode)) || (iomap.iomap_flags & IOMAP_NEW))) {
+ (offset >= i_size_read(inode)) || (iomap.iomap_flags & IOMAP_NEW)))
set_buffer_new(bh_result);
- }
if (iomap.iomap_flags & IOMAP_DELAY) {
BUG_ON(direct);
@@ -1014,9 +1004,11 @@ __linvfs_get_block(
}
if (blocks) {
- bh_result->b_size = (ssize_t)min(
- (loff_t)(iomap.iomap_bsize - iomap.iomap_delta),
- (loff_t)(blocks << inode->i_blkbits));
+ ASSERT(iomap.iomap_bsize - iomap.iomap_delta > 0);
+ offset = min_t(xfs_off_t,
+ iomap.iomap_bsize - iomap.iomap_delta,
+ blocks << inode->i_blkbits);
+ bh_result->b_size = (u32) min_t(xfs_off_t, UINT_MAX, offset);
}
return 0;
@@ -1296,7 +1288,7 @@ linvfs_invalidate_page(
STATIC int
linvfs_release_page(
struct page *page,
- int gfp_mask)
+ gfp_t gfp_mask)
{
struct inode *inode = page->mapping->host;
int dirty, delalloc, unmapped, unwritten;
diff --git a/fs/xfs/linux-2.6/xfs_aops.h b/fs/xfs/linux-2.6/xfs_aops.h
index 2fa62974a04d..4720758a9ade 100644
--- a/fs/xfs/linux-2.6/xfs_aops.h
+++ b/fs/xfs/linux-2.6/xfs_aops.h
@@ -1,33 +1,19 @@
/*
- * Copyright (c) 2005 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __XFS_AOPS_H__
#define __XFS_AOPS_H__
diff --git a/fs/xfs/linux-2.6/xfs_buf.c b/fs/xfs/linux-2.6/xfs_buf.c
index e82cf72ac599..6fe21d2b8847 100644
--- a/fs/xfs/linux-2.6/xfs_buf.c
+++ b/fs/xfs/linux-2.6/xfs_buf.c
@@ -1,46 +1,20 @@
/*
- * Copyright (c) 2000-2005 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
- */
-
-/*
- * The xfs_buf.c code provides an abstract buffer cache model on top
- * of the Linux page cache. Cached metadata blocks for a file system
- * are hashed to the inode for the block device. xfs_buf.c assembles
- * buffers (xfs_buf_t) on demand to aggregate such cached pages for I/O.
- *
- * Written by Steve Lord, Jim Mostek, Russell Cattelan
- * and Rajagopal Ananthanarayanan ("ananth") at SGI.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-
#include <linux/stddef.h>
#include <linux/errno.h>
#include <linux/slab.h>
@@ -55,25 +29,16 @@
#include <linux/blkdev.h>
#include <linux/hash.h>
#include <linux/kthread.h>
-
#include "xfs_linux.h"
-/*
- * File wide globals
- */
-
STATIC kmem_cache_t *pagebuf_zone;
STATIC kmem_shaker_t pagebuf_shake;
-STATIC int xfsbufd_wakeup(int, unsigned int);
+STATIC int xfsbufd_wakeup(int, gfp_t);
STATIC void pagebuf_delwri_queue(xfs_buf_t *, int);
STATIC struct workqueue_struct *xfslogd_workqueue;
struct workqueue_struct *xfsdatad_workqueue;
-/*
- * Pagebuf debugging
- */
-
#ifdef PAGEBUF_TRACE
void
pagebuf_trace(
@@ -112,10 +77,6 @@ ktrace_t *pagebuf_trace_buf;
# define PB_GET_OWNER(pb) do { } while (0)
#endif
-/*
- * Pagebuf allocation / freeing.
- */
-
#define pb_to_gfp(flags) \
((((flags) & PBF_READ_AHEAD) ? __GFP_NORETRY : \
((flags) & PBF_DONT_BLOCK) ? GFP_NOFS : GFP_KERNEL) | __GFP_NOWARN)
@@ -123,7 +84,6 @@ ktrace_t *pagebuf_trace_buf;
#define pb_to_km(flags) \
(((flags) & PBF_DONT_BLOCK) ? KM_NOFS : KM_SLEEP)
-
#define pagebuf_allocate(flags) \
kmem_zone_alloc(pagebuf_zone, pb_to_km(flags))
#define pagebuf_deallocate(pb) \
@@ -181,8 +141,9 @@ set_page_region(
size_t offset,
size_t length)
{
- page->private |= page_region_mask(offset, length);
- if (page->private == ~0UL)
+ set_page_private(page,
+ page_private(page) | page_region_mask(offset, length));
+ if (page_private(page) == ~0UL)
SetPageUptodate(page);
}
@@ -194,7 +155,7 @@ test_page_region(
{
unsigned long mask = page_region_mask(offset, length);
- return (mask && (page->private & mask) == mask);
+ return (mask && (page_private(page) & mask) == mask);
}
/*
@@ -285,7 +246,7 @@ _pagebuf_initialize(
* most cases but may be reset (e.g. XFS recovery).
*/
pb->pb_buffer_length = pb->pb_count_desired = range_length;
- pb->pb_flags = flags | PBF_NONE;
+ pb->pb_flags = flags;
pb->pb_bn = XFS_BUF_DADDR_NULL;
atomic_set(&pb->pb_pin_count, 0);
init_waitqueue_head(&pb->pb_waiters);
@@ -383,7 +344,7 @@ _pagebuf_lookup_pages(
size_t blocksize = bp->pb_target->pbr_bsize;
size_t size = bp->pb_count_desired;
size_t nbytes, offset;
- int gfp_mask = pb_to_gfp(flags);
+ gfp_t gfp_mask = pb_to_gfp(flags);
unsigned short page_count, i;
pgoff_t first;
loff_t end;
@@ -457,14 +418,8 @@ _pagebuf_lookup_pages(
unlock_page(bp->pb_pages[i]);
}
- if (page_count) {
- /* if we have any uptodate pages, mark that in the buffer */
- bp->pb_flags &= ~PBF_NONE;
-
- /* if some pages aren't uptodate, mark that in the buffer */
- if (page_count != bp->pb_page_count)
- bp->pb_flags |= PBF_PARTIAL;
- }
+ if (page_count == bp->pb_page_count)
+ bp->pb_flags |= PBF_DONE;
PB_TRACE(bp, "lookup_pages", (long)page_count);
return error;
@@ -675,7 +630,7 @@ xfs_buf_read_flags(
pb = xfs_buf_get_flags(target, ioff, isize, flags);
if (pb) {
- if (PBF_NOT_DONE(pb)) {
+ if (!XFS_BUF_ISDONE(pb)) {
PB_TRACE(pb, "read", (unsigned long)flags);
XFS_STATS_INC(pb_get_read);
pagebuf_iostart(pb, flags);
@@ -812,7 +767,7 @@ pagebuf_get_no_daddr(
bp = pagebuf_allocate(0);
if (unlikely(bp == NULL))
goto fail;
- _pagebuf_initialize(bp, target, 0, len, PBF_FORCEIO);
+ _pagebuf_initialize(bp, target, 0, len, 0);
try_again:
data = kmem_alloc(malloc_len, KM_SLEEP | KM_MAYFAIL);
@@ -875,39 +830,18 @@ pagebuf_rele(
PB_TRACE(pb, "rele", pb->pb_relse);
- /*
- * pagebuf_lookup buffers are not hashed, not delayed write,
- * and don't have their own release routines. Special case.
- */
- if (unlikely(!hash)) {
- ASSERT(!pb->pb_relse);
- if (atomic_dec_and_test(&pb->pb_hold))
- xfs_buf_free(pb);
- return;
- }
-
if (atomic_dec_and_lock(&pb->pb_hold, &hash->bh_lock)) {
- int do_free = 1;
-
if (pb->pb_relse) {
atomic_inc(&pb->pb_hold);
spin_unlock(&hash->bh_lock);
(*(pb->pb_relse)) (pb);
- spin_lock(&hash->bh_lock);
- do_free = 0;
- }
-
- if (pb->pb_flags & PBF_FS_MANAGED) {
- do_free = 0;
- }
-
- if (do_free) {
- ASSERT((pb->pb_flags & (PBF_DELWRI|_PBF_DELWRI_Q)) == 0);
- list_del_init(&pb->pb_hash_list);
+ } else if (pb->pb_flags & PBF_FS_MANAGED) {
spin_unlock(&hash->bh_lock);
- pagebuf_free(pb);
} else {
+ ASSERT(!(pb->pb_flags & (PBF_DELWRI|_PBF_DELWRI_Q)));
+ list_del_init(&pb->pb_hash_list);
spin_unlock(&hash->bh_lock);
+ pagebuf_free(pb);
}
} else {
/*
@@ -1120,21 +1054,18 @@ pagebuf_iodone_work(
void
pagebuf_iodone(
xfs_buf_t *pb,
- int dataio,
int schedule)
{
pb->pb_flags &= ~(PBF_READ | PBF_WRITE);
- if (pb->pb_error == 0) {
- pb->pb_flags &= ~(PBF_PARTIAL | PBF_NONE);
- }
+ if (pb->pb_error == 0)
+ pb->pb_flags |= PBF_DONE;
PB_TRACE(pb, "iodone", pb->pb_iodone);
if ((pb->pb_iodone) || (pb->pb_flags & PBF_ASYNC)) {
if (schedule) {
INIT_WORK(&pb->pb_iodone_work, pagebuf_iodone_work, pb);
- queue_work(dataio ? xfsdatad_workqueue :
- xfslogd_workqueue, &pb->pb_iodone_work);
+ queue_work(xfslogd_workqueue, &pb->pb_iodone_work);
} else {
pagebuf_iodone_work(pb);
}
@@ -1234,7 +1165,7 @@ _pagebuf_iodone(
{
if (atomic_dec_and_test(&pb->pb_io_remaining) == 1) {
pb->pb_locked = 0;
- pagebuf_iodone(pb, (pb->pb_flags & PBF_FS_DATAIOD), schedule);
+ pagebuf_iodone(pb, schedule);
}
}
@@ -1303,6 +1234,11 @@ _pagebuf_ioapply(
rw = (pb->pb_flags & PBF_READ) ? READ : WRITE;
}
+ if (pb->pb_flags & PBF_ORDERED) {
+ ASSERT(!(pb->pb_flags & PBF_READ));
+ rw = WRITE_BARRIER;
+ }
+
/* Special code path for reading a sub page size pagebuf in --
* we populate up the whole page, and hence the other metadata
* in the same page. This optimization is only valid when the
@@ -1750,7 +1686,7 @@ STATIC int xfsbufd_force_sleep;
STATIC int
xfsbufd_wakeup(
int priority,
- unsigned int mask)
+ gfp_t mask)
{
if (xfsbufd_force_sleep)
return 0;
@@ -1780,8 +1716,8 @@ xfsbufd(
xfsbufd_force_sleep = 0;
}
- schedule_timeout_interruptible
- (xfs_buf_timer_centisecs * msecs_to_jiffies(10));
+ schedule_timeout_interruptible(
+ xfs_buf_timer_centisecs * msecs_to_jiffies(10));
age = xfs_buf_age_centisecs * msecs_to_jiffies(10);
spin_lock(&pbd_delwrite_lock);
@@ -1890,14 +1826,22 @@ xfs_flush_buftarg(
return pincount;
}
-STATIC int
-xfs_buf_daemons_start(void)
+int __init
+pagebuf_init(void)
{
int error = -ENOMEM;
+#ifdef PAGEBUF_TRACE
+ pagebuf_trace_buf = ktrace_alloc(PAGEBUF_TRACE_SIZE, KM_SLEEP);
+#endif
+
+ pagebuf_zone = kmem_zone_init(sizeof(xfs_buf_t), "xfs_buf");
+ if (!pagebuf_zone)
+ goto out_free_trace_buf;
+
xfslogd_workqueue = create_workqueue("xfslogd");
if (!xfslogd_workqueue)
- goto out;
+ goto out_free_buf_zone;
xfsdatad_workqueue = create_workqueue("xfsdatad");
if (!xfsdatad_workqueue)
@@ -1908,82 +1852,37 @@ xfs_buf_daemons_start(void)
error = PTR_ERR(xfsbufd_task);
goto out_destroy_xfsdatad_workqueue;
}
+
+ pagebuf_shake = kmem_shake_register(xfsbufd_wakeup);
+ if (!pagebuf_shake)
+ goto out_stop_xfsbufd;
+
return 0;
+ out_stop_xfsbufd:
+ kthread_stop(xfsbufd_task);
out_destroy_xfsdatad_workqueue:
destroy_workqueue(xfsdatad_workqueue);
out_destroy_xfslogd_workqueue:
destroy_workqueue(xfslogd_workqueue);
- out:
- return error;
-}
-
-/*
- * Note: do not mark as __exit, it is called from pagebuf_terminate.
- */
-STATIC void
-xfs_buf_daemons_stop(void)
-{
- kthread_stop(xfsbufd_task);
- destroy_workqueue(xfslogd_workqueue);
- destroy_workqueue(xfsdatad_workqueue);
-}
-
-/*
- * Initialization and Termination
- */
-
-int __init
-pagebuf_init(void)
-{
- int error = -ENOMEM;
-
- pagebuf_zone = kmem_zone_init(sizeof(xfs_buf_t), "xfs_buf");
- if (!pagebuf_zone)
- goto out;
-
-#ifdef PAGEBUF_TRACE
- pagebuf_trace_buf = ktrace_alloc(PAGEBUF_TRACE_SIZE, KM_SLEEP);
-#endif
-
- error = xfs_buf_daemons_start();
- if (error)
- goto out_free_buf_zone;
-
- pagebuf_shake = kmem_shake_register(xfsbufd_wakeup);
- if (!pagebuf_shake) {
- error = -ENOMEM;
- goto out_stop_daemons;
- }
-
- return 0;
-
- out_stop_daemons:
- xfs_buf_daemons_stop();
out_free_buf_zone:
+ kmem_zone_destroy(pagebuf_zone);
+ out_free_trace_buf:
#ifdef PAGEBUF_TRACE
ktrace_free(pagebuf_trace_buf);
#endif
- kmem_zone_destroy(pagebuf_zone);
- out:
return error;
}
-
-/*
- * pagebuf_terminate.
- *
- * Note: do not mark as __exit, this is also called from the __init code.
- */
void
pagebuf_terminate(void)
{
- xfs_buf_daemons_stop();
-
+ kmem_shake_deregister(pagebuf_shake);
+ kthread_stop(xfsbufd_task);
+ destroy_workqueue(xfsdatad_workqueue);
+ destroy_workqueue(xfslogd_workqueue);
+ kmem_zone_destroy(pagebuf_zone);
#ifdef PAGEBUF_TRACE
ktrace_free(pagebuf_trace_buf);
#endif
-
- kmem_zone_destroy(pagebuf_zone);
- kmem_shake_deregister(pagebuf_shake);
}
diff --git a/fs/xfs/linux-2.6/xfs_buf.h b/fs/xfs/linux-2.6/xfs_buf.h
index 67c19f799232..237a35b915d1 100644
--- a/fs/xfs/linux-2.6/xfs_buf.h
+++ b/fs/xfs/linux-2.6/xfs_buf.h
@@ -1,39 +1,20 @@
/*
- * Copyright (c) 2000-2004 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-
-/*
- * Written by Steve Lord, Jim Mostek, Russell Cattelan at SGI
- */
-
#ifndef __XFS_BUF_H__
#define __XFS_BUF_H__
@@ -69,15 +50,12 @@ typedef enum page_buf_flags_e { /* pb_flags values */
PBF_READ = (1 << 0), /* buffer intended for reading from device */
PBF_WRITE = (1 << 1), /* buffer intended for writing to device */
PBF_MAPPED = (1 << 2), /* buffer mapped (pb_addr valid) */
- PBF_PARTIAL = (1 << 3), /* buffer partially read */
PBF_ASYNC = (1 << 4), /* initiator will not wait for completion */
- PBF_NONE = (1 << 5), /* buffer not read at all */
+ PBF_DONE = (1 << 5), /* all pages in the buffer uptodate */
PBF_DELWRI = (1 << 6), /* buffer has dirty pages */
PBF_STALE = (1 << 7), /* buffer has been staled, do not find it */
PBF_FS_MANAGED = (1 << 8), /* filesystem controls freeing memory */
- PBF_FS_DATAIOD = (1 << 9), /* schedule IO completion on fs datad */
- PBF_FORCEIO = (1 << 10), /* ignore any cache state */
- PBF_FLUSH = (1 << 11), /* flush disk write cache */
+ PBF_ORDERED = (1 << 11), /* use ordered writes */
PBF_READ_AHEAD = (1 << 12), /* asynchronous read-ahead */
/* flags used only as arguments to access routines */
@@ -92,9 +70,6 @@ typedef enum page_buf_flags_e { /* pb_flags values */
_PBF_DELWRI_Q = (1 << 21), /* buffer on delwri queue */
} page_buf_flags_t;
-#define PBF_UPDATE (PBF_READ | PBF_WRITE)
-#define PBF_NOT_DONE(pb) (((pb)->pb_flags & (PBF_PARTIAL|PBF_NONE)) != 0)
-#define PBF_DONE(pb) (((pb)->pb_flags & (PBF_PARTIAL|PBF_NONE)) == 0)
typedef struct xfs_bufhash {
struct list_head bh_list;
@@ -258,7 +233,6 @@ extern void pagebuf_unlock( /* unlock buffer */
extern void pagebuf_iodone( /* mark buffer I/O complete */
xfs_buf_t *, /* buffer to mark */
- int, /* use data/log helper thread. */
int); /* run completion locally, or in
* a helper thread. */
@@ -378,21 +352,21 @@ extern void pagebuf_trace(
#define XFS_BUF_GETERROR(x) pagebuf_geterror(x)
#define XFS_BUF_ISERROR(x) (pagebuf_geterror(x)?1:0)
-#define XFS_BUF_DONE(x) ((x)->pb_flags &= ~(PBF_PARTIAL|PBF_NONE))
-#define XFS_BUF_UNDONE(x) ((x)->pb_flags |= PBF_PARTIAL|PBF_NONE)
-#define XFS_BUF_ISDONE(x) (!(PBF_NOT_DONE(x)))
+#define XFS_BUF_DONE(x) ((x)->pb_flags |= PBF_DONE)
+#define XFS_BUF_UNDONE(x) ((x)->pb_flags &= ~PBF_DONE)
+#define XFS_BUF_ISDONE(x) ((x)->pb_flags & PBF_DONE)
-#define XFS_BUF_BUSY(x) ((x)->pb_flags |= PBF_FORCEIO)
-#define XFS_BUF_UNBUSY(x) ((x)->pb_flags &= ~PBF_FORCEIO)
+#define XFS_BUF_BUSY(x) do { } while (0)
+#define XFS_BUF_UNBUSY(x) do { } while (0)
#define XFS_BUF_ISBUSY(x) (1)
#define XFS_BUF_ASYNC(x) ((x)->pb_flags |= PBF_ASYNC)
#define XFS_BUF_UNASYNC(x) ((x)->pb_flags &= ~PBF_ASYNC)
#define XFS_BUF_ISASYNC(x) ((x)->pb_flags & PBF_ASYNC)
-#define XFS_BUF_FLUSH(x) ((x)->pb_flags |= PBF_FLUSH)
-#define XFS_BUF_UNFLUSH(x) ((x)->pb_flags &= ~PBF_FLUSH)
-#define XFS_BUF_ISFLUSH(x) ((x)->pb_flags & PBF_FLUSH)
+#define XFS_BUF_ORDERED(x) ((x)->pb_flags |= PBF_ORDERED)
+#define XFS_BUF_UNORDERED(x) ((x)->pb_flags &= ~PBF_ORDERED)
+#define XFS_BUF_ISORDERED(x) ((x)->pb_flags & PBF_ORDERED)
#define XFS_BUF_SHUT(x) printk("XFS_BUF_SHUT not implemented yet\n")
#define XFS_BUF_UNSHUT(x) printk("XFS_BUF_UNSHUT not implemented yet\n")
@@ -412,9 +386,6 @@ extern void pagebuf_trace(
#define XFS_BUF_BP_ISMAPPED(bp) 1
-#define XFS_BUF_DATAIO(x) ((x)->pb_flags |= PBF_FS_DATAIOD)
-#define XFS_BUF_UNDATAIO(x) ((x)->pb_flags &= ~PBF_FS_DATAIOD)
-
#define XFS_BUF_IODONE_FUNC(buf) (buf)->pb_iodone
#define XFS_BUF_SET_IODONE_FUNC(buf, func) \
(buf)->pb_iodone = (func)
@@ -510,7 +481,7 @@ static inline void xfs_buf_relse(xfs_buf_t *bp)
pagebuf_trace(bp, id, NULL, (void *)__builtin_return_address(0))
#define xfs_biodone(pb) \
- pagebuf_iodone(pb, (pb->pb_flags & PBF_FS_DATAIOD), 0)
+ pagebuf_iodone(pb, 0)
#define xfs_biomove(pb, off, len, data, rw) \
pagebuf_iomove((pb), (off), (len), (data), \
diff --git a/fs/xfs/linux-2.6/xfs_cred.h b/fs/xfs/linux-2.6/xfs_cred.h
index 00c45849d41a..4af491024727 100644
--- a/fs/xfs/linux-2.6/xfs_cred.h
+++ b/fs/xfs/linux-2.6/xfs_cred.h
@@ -1,33 +1,19 @@
/*
- * Copyright (c) 2000-2002 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __XFS_CRED_H__
#define __XFS_CRED_H__
diff --git a/fs/xfs/linux-2.6/xfs_export.c b/fs/xfs/linux-2.6/xfs_export.c
index f372a1a5e168..80eb249f2fa0 100644
--- a/fs/xfs/linux-2.6/xfs_export.c
+++ b/fs/xfs/linux-2.6/xfs_export.c
@@ -1,35 +1,20 @@
/*
- * Copyright (c) 2004-2005 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2004-2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-
#include "xfs.h"
#include "xfs_types.h"
#include "xfs_dmapi.h"
@@ -41,7 +26,7 @@
#include "xfs_export.h"
/*
- * XFS encode and decodes the fileid portion of NFS filehandles
+ * XFS encodes and decodes the fileid portion of NFS filehandles
* itself instead of letting the generic NFS code do it. This
* allows filesystems with 64 bit inode numbers to be exported.
*
@@ -51,7 +36,6 @@
* remains in that code.
*/
-
STATIC struct dentry *
linvfs_decode_fh(
struct super_block *sb,
@@ -92,7 +76,7 @@ linvfs_decode_fh(
p = xfs_fileid_decode_fid2(p, &pfid, is64);
parent = &pfid;
}
-
+
fh = (__u32 *)&ifid;
return find_exported_dentry(sb, fh, parent, acceptable, context);
}
@@ -112,9 +96,8 @@ linvfs_encode_fh(
int is64 = 0;
#if XFS_BIG_INUMS
vfs_t *vfs = LINVFS_GET_VFS(inode->i_sb);
- xfs_mount_t *mp = XFS_VFSTOM(vfs);
-
- if (!(mp->m_flags & XFS_MOUNT_32BITINOOPT)) {
+
+ if (!(vfs->vfs_flag & VFS_32BITINODES)) {
/* filesystem may contain 64bit inode numbers */
is64 = XFS_FILEID_TYPE_64FLAG;
}
diff --git a/fs/xfs/linux-2.6/xfs_export.h b/fs/xfs/linux-2.6/xfs_export.h
index 60b2abac1c18..e5b0559700a4 100644
--- a/fs/xfs/linux-2.6/xfs_export.h
+++ b/fs/xfs/linux-2.6/xfs_export.h
@@ -1,33 +1,19 @@
/*
- * Copyright (c) 2005 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __XFS_EXPORT_H__
#define __XFS_EXPORT_H__
diff --git a/fs/xfs/linux-2.6/xfs_file.c b/fs/xfs/linux-2.6/xfs_file.c
index 3881622bcf08..06111d0bbae4 100644
--- a/fs/xfs/linux-2.6/xfs_file.c
+++ b/fs/xfs/linux-2.6/xfs_file.c
@@ -1,39 +1,26 @@
/*
- * Copyright (c) 2000-2005 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-
#include "xfs.h"
-#include "xfs_inum.h"
+#include "xfs_bit.h"
#include "xfs_log.h"
+#include "xfs_inum.h"
#include "xfs_sb.h"
+#include "xfs_ag.h"
#include "xfs_dir.h"
#include "xfs_dir2.h"
#include "xfs_trans.h"
diff --git a/fs/xfs/linux-2.6/xfs_fs_subr.c b/fs/xfs/linux-2.6/xfs_fs_subr.c
index 05ebd30ec96f..f89340c61bf2 100644
--- a/fs/xfs/linux-2.6/xfs_fs_subr.c
+++ b/fs/xfs/linux-2.6/xfs_fs_subr.c
@@ -1,33 +1,19 @@
/*
- * Copyright (c) 2000-2002 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "xfs.h"
@@ -117,6 +103,8 @@ fs_flush_pages(
if (VN_CACHED(vp)) {
filemap_fdatawrite(ip->i_mapping);
+ if (flags & XFS_B_ASYNC)
+ return 0;
filemap_fdatawait(ip->i_mapping);
}
diff --git a/fs/xfs/linux-2.6/xfs_fs_subr.h b/fs/xfs/linux-2.6/xfs_fs_subr.h
index 2db9ddbd4567..aee9ccdd18f7 100644
--- a/fs/xfs/linux-2.6/xfs_fs_subr.h
+++ b/fs/xfs/linux-2.6/xfs_fs_subr.h
@@ -1,48 +1,29 @@
/*
- * Copyright (c) 2000, 2002 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000,2002,2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
- */
-#ifndef __XFS_SUBR_H__
-#define __XFS_SUBR_H__
-
-/*
- * Utilities shared among file system implementations.
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#ifndef __XFS_FS_SUBR_H__
+#define __XFS_FS_SUBR_H__
struct cred;
-
-extern int fs_noerr(void);
-extern int fs_nosys(void);
-extern void fs_noval(void);
-extern void fs_tosspages(bhv_desc_t *, xfs_off_t, xfs_off_t, int);
-extern void fs_flushinval_pages(bhv_desc_t *, xfs_off_t, xfs_off_t, int);
-extern int fs_flush_pages(bhv_desc_t *, xfs_off_t, xfs_off_t, uint64_t, int);
+extern int fs_noerr(void);
+extern int fs_nosys(void);
+extern void fs_noval(void);
+extern void fs_tosspages(bhv_desc_t *, xfs_off_t, xfs_off_t, int);
+extern void fs_flushinval_pages(bhv_desc_t *, xfs_off_t, xfs_off_t, int);
+extern int fs_flush_pages(bhv_desc_t *, xfs_off_t, xfs_off_t, uint64_t, int);
#endif /* __XFS_FS_SUBR_H__ */
diff --git a/fs/xfs/linux-2.6/xfs_globals.c b/fs/xfs/linux-2.6/xfs_globals.c
index a6da5b4fd240..6e8085f34635 100644
--- a/fs/xfs/linux-2.6/xfs_globals.c
+++ b/fs/xfs/linux-2.6/xfs_globals.c
@@ -1,40 +1,20 @@
/*
- * Copyright (c) 2000-2004 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-
-/*
- * This file contains globals needed by XFS that were normally defined
- * somewhere else in IRIX.
- */
-
#include "xfs.h"
#include "xfs_cred.h"
#include "xfs_sysctl.h"
diff --git a/fs/xfs/linux-2.6/xfs_globals.h b/fs/xfs/linux-2.6/xfs_globals.h
index e81e2f38a853..e1a22bfcf865 100644
--- a/fs/xfs/linux-2.6/xfs_globals.h
+++ b/fs/xfs/linux-2.6/xfs_globals.h
@@ -1,42 +1,23 @@
/*
- * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __XFS_GLOBALS_H__
#define __XFS_GLOBALS_H__
-/*
- * This file declares globals needed by XFS that were normally defined
- * somewhere else in IRIX.
- */
-
extern uint64_t xfs_panic_mask; /* set to cause more panics */
extern unsigned long xfs_physmem;
extern struct cred *sys_cred;
diff --git a/fs/xfs/linux-2.6/xfs_ioctl.c b/fs/xfs/linux-2.6/xfs_ioctl.c
index 6a3326bcd8d0..b78b5eb9e96c 100644
--- a/fs/xfs/linux-2.6/xfs_ioctl.c
+++ b/fs/xfs/linux-2.6/xfs_ioctl.c
@@ -1,67 +1,52 @@
/*
- * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-
#include "xfs.h"
-
#include "xfs_fs.h"
-#include "xfs_inum.h"
+#include "xfs_bit.h"
#include "xfs_log.h"
+#include "xfs_inum.h"
#include "xfs_trans.h"
#include "xfs_sb.h"
+#include "xfs_ag.h"
#include "xfs_dir.h"
#include "xfs_dir2.h"
#include "xfs_alloc.h"
#include "xfs_dmapi.h"
#include "xfs_mount.h"
-#include "xfs_alloc_btree.h"
#include "xfs_bmap_btree.h"
+#include "xfs_alloc_btree.h"
#include "xfs_ialloc_btree.h"
-#include "xfs_btree.h"
-#include "xfs_ialloc.h"
-#include "xfs_attr_sf.h"
#include "xfs_dir_sf.h"
+#include "xfs_attr_sf.h"
#include "xfs_dir2_sf.h"
#include "xfs_dinode.h"
#include "xfs_inode.h"
-#include "xfs_bmap.h"
-#include "xfs_bit.h"
+#include "xfs_btree.h"
+#include "xfs_ialloc.h"
#include "xfs_rtalloc.h"
-#include "xfs_error.h"
#include "xfs_itable.h"
+#include "xfs_error.h"
#include "xfs_rw.h"
#include "xfs_acl.h"
#include "xfs_cap.h"
#include "xfs_mac.h"
#include "xfs_attr.h"
+#include "xfs_bmap.h"
#include "xfs_buf_item.h"
#include "xfs_utils.h"
#include "xfs_dfrag.h"
diff --git a/fs/xfs/linux-2.6/xfs_ioctl32.c b/fs/xfs/linux-2.6/xfs_ioctl32.c
index 4636b7f86f1f..c83ae15bb0e6 100644
--- a/fs/xfs/linux-2.6/xfs_ioctl32.c
+++ b/fs/xfs/linux-2.6/xfs_ioctl32.c
@@ -1,35 +1,20 @@
/*
- * Copyright (c) 2004-2005 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2004-2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-
#include <linux/config.h>
#include <linux/compat.h>
#include <linux/init.h>
@@ -39,7 +24,6 @@
#include <linux/types.h>
#include <linux/fs.h>
#include <asm/uaccess.h>
-
#include "xfs.h"
#include "xfs_types.h"
#include "xfs_fs.h"
diff --git a/fs/xfs/linux-2.6/xfs_ioctl32.h b/fs/xfs/linux-2.6/xfs_ioctl32.h
index c874793a1dc9..011c273bec50 100644
--- a/fs/xfs/linux-2.6/xfs_ioctl32.h
+++ b/fs/xfs/linux-2.6/xfs_ioctl32.h
@@ -1,34 +1,24 @@
/*
- * Copyright (c) 2004-2005 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2004-2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#ifndef __XFS_IOCTL32_H__
+#define __XFS_IOCTL32_H__
+
+extern long linvfs_compat_ioctl(struct file *, unsigned, unsigned long);
+extern long linvfs_compat_invis_ioctl(struct file *f, unsigned, unsigned long);
-long linvfs_compat_ioctl(struct file *f, unsigned cmd, unsigned long arg);
-long linvfs_compat_invis_ioctl(struct file *f, unsigned cmd, unsigned long arg);
+#endif /* __XFS_IOCTL32_H__ */
diff --git a/fs/xfs/linux-2.6/xfs_iops.c b/fs/xfs/linux-2.6/xfs_iops.c
index 77708a8c9f87..14215a7db59f 100644
--- a/fs/xfs/linux-2.6/xfs_iops.c
+++ b/fs/xfs/linux-2.6/xfs_iops.c
@@ -1,39 +1,25 @@
/*
- * Copyright (c) 2000-2004 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-
#include "xfs.h"
#include "xfs_fs.h"
-#include "xfs_inum.h"
+#include "xfs_bit.h"
#include "xfs_log.h"
+#include "xfs_inum.h"
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
@@ -43,18 +29,17 @@
#include "xfs_dmapi.h"
#include "xfs_quota.h"
#include "xfs_mount.h"
-#include "xfs_alloc_btree.h"
#include "xfs_bmap_btree.h"
+#include "xfs_alloc_btree.h"
#include "xfs_ialloc_btree.h"
-#include "xfs_btree.h"
-#include "xfs_ialloc.h"
-#include "xfs_attr_sf.h"
#include "xfs_dir_sf.h"
#include "xfs_dir2_sf.h"
+#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
#include "xfs_inode.h"
#include "xfs_bmap.h"
-#include "xfs_bit.h"
+#include "xfs_btree.h"
+#include "xfs_ialloc.h"
#include "xfs_rtalloc.h"
#include "xfs_error.h"
#include "xfs_itable.h"
@@ -69,6 +54,137 @@
#include <linux/xattr.h>
#include <linux/namei.h>
+/*
+ * Change the requested timestamp in the given inode.
+ * We don't lock across timestamp updates, and we don't log them but
+ * we do record the fact that there is dirty information in core.
+ *
+ * NOTE -- callers MUST combine XFS_ICHGTIME_MOD or XFS_ICHGTIME_CHG
+ * with XFS_ICHGTIME_ACC to be sure that access time
+ * update will take. Calling first with XFS_ICHGTIME_ACC
+ * and then XFS_ICHGTIME_MOD may fail to modify the access
+ * timestamp if the filesystem is mounted noacctm.
+ */
+void
+xfs_ichgtime(
+ xfs_inode_t *ip,
+ int flags)
+{
+ struct inode *inode = LINVFS_GET_IP(XFS_ITOV(ip));
+ timespec_t tv;
+
+ /*
+ * We're not supposed to change timestamps in readonly-mounted
+ * filesystems. Throw it away if anyone asks us.
+ */
+ if (unlikely(IS_RDONLY(inode)))
+ return;
+
+ /*
+ * Don't update access timestamps on reads if mounted "noatime".
+ * Throw it away if anyone asks us.
+ */
+ if (unlikely(
+ (ip->i_mount->m_flags & XFS_MOUNT_NOATIME || IS_NOATIME(inode)) &&
+ (flags & (XFS_ICHGTIME_ACC|XFS_ICHGTIME_MOD|XFS_ICHGTIME_CHG)) ==
+ XFS_ICHGTIME_ACC))
+ return;
+
+ nanotime(&tv);
+ if (flags & XFS_ICHGTIME_MOD) {
+ inode->i_mtime = tv;
+ ip->i_d.di_mtime.t_sec = (__int32_t)tv.tv_sec;
+ ip->i_d.di_mtime.t_nsec = (__int32_t)tv.tv_nsec;
+ }
+ if (flags & XFS_ICHGTIME_ACC) {
+ inode->i_atime = tv;
+ ip->i_d.di_atime.t_sec = (__int32_t)tv.tv_sec;
+ ip->i_d.di_atime.t_nsec = (__int32_t)tv.tv_nsec;
+ }
+ if (flags & XFS_ICHGTIME_CHG) {
+ inode->i_ctime = tv;
+ ip->i_d.di_ctime.t_sec = (__int32_t)tv.tv_sec;
+ ip->i_d.di_ctime.t_nsec = (__int32_t)tv.tv_nsec;
+ }
+
+ /*
+ * We update the i_update_core field _after_ changing
+ * the timestamps in order to coordinate properly with
+ * xfs_iflush() so that we don't lose timestamp updates.
+ * This keeps us from having to hold the inode lock
+ * while doing this. We use the SYNCHRONIZE macro to
+ * ensure that the compiler does not reorder the update
+ * of i_update_core above the timestamp updates above.
+ */
+ SYNCHRONIZE();
+ ip->i_update_core = 1;
+ if (!(inode->i_state & I_LOCK))
+ mark_inode_dirty_sync(inode);
+}
+
+/*
+ * Variant on the above which avoids querying the system clock
+ * in situations where we know the Linux inode timestamps have
+ * just been updated (and so we can update our inode cheaply).
+ * We also skip the readonly and noatime checks here, they are
+ * also catered for already.
+ */
+void
+xfs_ichgtime_fast(
+ xfs_inode_t *ip,
+ struct inode *inode,
+ int flags)
+{
+ timespec_t *tvp;
+
+ /*
+ * We're not supposed to change timestamps in readonly-mounted
+ * filesystems. Throw it away if anyone asks us.
+ */
+ if (unlikely(IS_RDONLY(inode)))
+ return;
+
+ /*
+ * Don't update access timestamps on reads if mounted "noatime".
+ * Throw it away if anyone asks us.
+ */
+ if (unlikely(
+ (ip->i_mount->m_flags & XFS_MOUNT_NOATIME || IS_NOATIME(inode)) &&
+ ((flags & (XFS_ICHGTIME_ACC|XFS_ICHGTIME_MOD|XFS_ICHGTIME_CHG)) ==
+ XFS_ICHGTIME_ACC)))
+ return;
+
+ if (flags & XFS_ICHGTIME_MOD) {
+ tvp = &inode->i_mtime;
+ ip->i_d.di_mtime.t_sec = (__int32_t)tvp->tv_sec;
+ ip->i_d.di_mtime.t_nsec = (__int32_t)tvp->tv_nsec;
+ }
+ if (flags & XFS_ICHGTIME_ACC) {
+ tvp = &inode->i_atime;
+ ip->i_d.di_atime.t_sec = (__int32_t)tvp->tv_sec;
+ ip->i_d.di_atime.t_nsec = (__int32_t)tvp->tv_nsec;
+ }
+ if (flags & XFS_ICHGTIME_CHG) {
+ tvp = &inode->i_ctime;
+ ip->i_d.di_ctime.t_sec = (__int32_t)tvp->tv_sec;
+ ip->i_d.di_ctime.t_nsec = (__int32_t)tvp->tv_nsec;
+ }
+
+ /*
+ * We update the i_update_core field _after_ changing
+ * the timestamps in order to coordinate properly with
+ * xfs_iflush() so that we don't lose timestamp updates.
+ * This keeps us from having to hold the inode lock
+ * while doing this. We use the SYNCHRONIZE macro to
+ * ensure that the compiler does not reorder the update
+ * of i_update_core above the timestamp updates above.
+ */
+ SYNCHRONIZE();
+ ip->i_update_core = 1;
+ if (!(inode->i_state & I_LOCK))
+ mark_inode_dirty_sync(inode);
+}
+
/*
* Pull the link count and size up from the xfs inode to the linux inode
diff --git a/fs/xfs/linux-2.6/xfs_iops.h b/fs/xfs/linux-2.6/xfs_iops.h
index 6a69a62c36b0..ee784b63acbf 100644
--- a/fs/xfs/linux-2.6/xfs_iops.h
+++ b/fs/xfs/linux-2.6/xfs_iops.h
@@ -1,33 +1,19 @@
/*
- * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __XFS_IOPS_H__
#define __XFS_IOPS_H__
@@ -48,4 +34,8 @@ extern void linvfs_unwritten_done(struct buffer_head *, int);
extern int xfs_ioctl(struct bhv_desc *, struct inode *, struct file *,
int, unsigned int, void __user *);
+struct xfs_inode;
+extern void xfs_ichgtime(struct xfs_inode *, int);
+extern void xfs_ichgtime_fast(struct xfs_inode *, struct inode *, int);
+
#endif /* __XFS_IOPS_H__ */
diff --git a/fs/xfs/linux-2.6/xfs_linux.h b/fs/xfs/linux-2.6/xfs_linux.h
index 68c5d885ed9c..d8e21ba0cccc 100644
--- a/fs/xfs/linux-2.6/xfs_linux.h
+++ b/fs/xfs/linux-2.6/xfs_linux.h
@@ -1,33 +1,19 @@
/*
- * Copyright (c) 2000-2004 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __XFS_LINUX__
#define __XFS_LINUX__
@@ -86,7 +72,6 @@
#include <linux/init.h>
#include <linux/list.h>
#include <linux/proc_fs.h>
-#include <linux/version.h>
#include <linux/sort.h>
#include <asm/page.h>
@@ -197,10 +182,6 @@ static inline void set_buffer_unwritten_io(struct buffer_head *bh)
/* bytes to clicks */
#define btoc(x) (((__psunsigned_t)(x)+(NBPC-1))>>BPCSHIFT)
-#ifndef CELL_CAPABLE
-#define FSC_NOTIFY_NAME_CHANGED(vp)
-#endif
-
#ifndef ENOATTR
#define ENOATTR ENODATA /* Attribute not found */
#endif
@@ -235,30 +216,18 @@ static inline void set_buffer_unwritten_io(struct buffer_head *bh)
#define Q_XSETPQLIM XQM_CMD(10) /* set projects disk limits */
#define Q_XGETPQUOTA XQM_CMD(11) /* get projects disk limits */
-/* IRIX uses a dynamic sizing algorithm (ndquot = 200 + numprocs*2) */
-/* we may well need to fine-tune this if it ever becomes an issue. */
-#define DQUOT_MAX_HEURISTIC 1024 /* NR_DQUOTS */
-#define ndquot DQUOT_MAX_HEURISTIC
-
-/* IRIX uses the current size of the name cache to guess a good value */
-/* - this isn't the same but is a good enough starting point for now. */
-#define DQUOT_HASH_HEURISTIC files_stat.nr_files
-
-/* IRIX inodes maintain the project ID also, zero this field on Linux */
-#define DEFAULT_PROJID 0
-#define dfltprid DEFAULT_PROJID
-
+#define dfltprid 0
#define MAXPATHLEN 1024
#define MIN(a,b) (min(a,b))
#define MAX(a,b) (max(a,b))
#define howmany(x, y) (((x)+((y)-1))/(y))
#define roundup(x, y) ((((x)+((y)-1))/(y))*(y))
-#define qsort(a,n,s,fn) sort(a,n,s,fn,NULL)
/*
* Various platform dependent calls that don't fit anywhere else
*/
+#define xfs_sort(a,n,s,fn) sort(a,n,s,fn,NULL)
#define xfs_stack_trace() dump_stack()
#define xfs_itruncate_data(ip, off) \
(-vmtruncate(LINVFS_GET_IP(XFS_ITOV(ip)), (off)))
diff --git a/fs/xfs/linux-2.6/xfs_lrw.c b/fs/xfs/linux-2.6/xfs_lrw.c
index 3b5fabe8dae9..279e9bc92aba 100644
--- a/fs/xfs/linux-2.6/xfs_lrw.c
+++ b/fs/xfs/linux-2.6/xfs_lrw.c
@@ -1,44 +1,25 @@
/*
- * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-/*
- * fs/xfs/linux/xfs_lrw.c (Linux Read Write stuff)
- *
- */
-
#include "xfs.h"
-
#include "xfs_fs.h"
-#include "xfs_inum.h"
+#include "xfs_bit.h"
#include "xfs_log.h"
+#include "xfs_inum.h"
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
@@ -48,18 +29,17 @@
#include "xfs_dmapi.h"
#include "xfs_quota.h"
#include "xfs_mount.h"
-#include "xfs_alloc_btree.h"
#include "xfs_bmap_btree.h"
+#include "xfs_alloc_btree.h"
#include "xfs_ialloc_btree.h"
-#include "xfs_btree.h"
-#include "xfs_ialloc.h"
-#include "xfs_attr_sf.h"
#include "xfs_dir_sf.h"
#include "xfs_dir2_sf.h"
+#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
#include "xfs_inode.h"
#include "xfs_bmap.h"
-#include "xfs_bit.h"
+#include "xfs_btree.h"
+#include "xfs_ialloc.h"
#include "xfs_rtalloc.h"
#include "xfs_error.h"
#include "xfs_itable.h"
@@ -302,7 +282,7 @@ xfs_read(
xfs_iunlock(ip, XFS_IOLOCK_SHARED);
if (likely(!(ioflags & IO_INVIS)))
- xfs_ichgtime(ip, XFS_ICHGTIME_ACC);
+ xfs_ichgtime_fast(ip, inode, XFS_ICHGTIME_ACC);
unlock_isem:
if (unlikely(ioflags & IO_ISDIRECT))
@@ -367,7 +347,7 @@ xfs_sendfile(
XFS_STATS_ADD(xs_read_bytes, ret);
if (likely(!(ioflags & IO_INVIS)))
- xfs_ichgtime(ip, XFS_ICHGTIME_ACC);
+ xfs_ichgtime_fast(ip, LINVFS_GET_IP(vp), XFS_ICHGTIME_ACC);
return ret;
}
@@ -732,15 +712,10 @@ start:
}
}
- /*
- * On Linux, generic_file_write updates the times even if
- * no data is copied in so long as the write had a size.
- *
- * We must update xfs' times since revalidate will overcopy xfs.
- */
- if (!(ioflags & IO_INVIS)) {
- xfs_ichgtime(xip, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
+ if (likely(!(ioflags & IO_INVIS))) {
inode_update_time(inode, 1);
+ xfs_ichgtime_fast(xip, inode,
+ XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
}
/*
diff --git a/fs/xfs/linux-2.6/xfs_lrw.h b/fs/xfs/linux-2.6/xfs_lrw.h
index 6294dcdb797c..38864a88d42d 100644
--- a/fs/xfs/linux-2.6/xfs_lrw.h
+++ b/fs/xfs/linux-2.6/xfs_lrw.h
@@ -1,33 +1,19 @@
/*
- * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __XFS_LRW_H__
#define __XFS_LRW_H__
@@ -107,9 +93,4 @@ extern ssize_t xfs_sendfile(struct bhv_desc *, struct file *,
extern int xfs_dev_is_read_only(struct xfs_mount *, char *);
-#define XFS_FSB_TO_DB_IO(io,fsb) \
- (((io)->io_flags & XFS_IOCORE_RT) ? \
- XFS_FSB_TO_BB((io)->io_mount, (fsb)) : \
- XFS_FSB_TO_DADDR((io)->io_mount, (fsb)))
-
#endif /* __XFS_LRW_H__ */
diff --git a/fs/xfs/linux-2.6/xfs_stats.c b/fs/xfs/linux-2.6/xfs_stats.c
index aaf5ddba47f3..6c40a74be7c8 100644
--- a/fs/xfs/linux-2.6/xfs_stats.c
+++ b/fs/xfs/linux-2.6/xfs_stats.c
@@ -1,35 +1,20 @@
/*
- * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-
#include "xfs.h"
#include <linux/proc_fs.h>
diff --git a/fs/xfs/linux-2.6/xfs_stats.h b/fs/xfs/linux-2.6/xfs_stats.h
index 3f756a6c3eb0..50027c4a5618 100644
--- a/fs/xfs/linux-2.6/xfs_stats.h
+++ b/fs/xfs/linux-2.6/xfs_stats.h
@@ -1,33 +1,19 @@
/*
- * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000,2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __XFS_STATS_H__
#define __XFS_STATS_H__
diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c
index 2302454d8d47..6116b5bf433e 100644
--- a/fs/xfs/linux-2.6/xfs_super.c
+++ b/fs/xfs/linux-2.6/xfs_super.c
@@ -1,60 +1,45 @@
/*
- * Copyright (c) 2000-2005 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-
#include "xfs.h"
-
-#include "xfs_inum.h"
+#include "xfs_bit.h"
#include "xfs_log.h"
#include "xfs_clnt.h"
+#include "xfs_inum.h"
#include "xfs_trans.h"
#include "xfs_sb.h"
+#include "xfs_ag.h"
#include "xfs_dir.h"
#include "xfs_dir2.h"
#include "xfs_alloc.h"
#include "xfs_dmapi.h"
#include "xfs_quota.h"
#include "xfs_mount.h"
-#include "xfs_alloc_btree.h"
#include "xfs_bmap_btree.h"
+#include "xfs_alloc_btree.h"
#include "xfs_ialloc_btree.h"
-#include "xfs_btree.h"
-#include "xfs_ialloc.h"
-#include "xfs_attr_sf.h"
#include "xfs_dir_sf.h"
#include "xfs_dir2_sf.h"
+#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
#include "xfs_inode.h"
+#include "xfs_btree.h"
+#include "xfs_ialloc.h"
#include "xfs_bmap.h"
-#include "xfs_bit.h"
#include "xfs_rtalloc.h"
#include "xfs_error.h"
#include "xfs_itable.h"
@@ -189,7 +174,7 @@ xfs_revalidate_inode(
break;
}
- inode->i_blksize = PAGE_CACHE_SIZE;
+ inode->i_blksize = xfs_preferred_iosize(mp);
inode->i_generation = ip->i_d.di_gen;
i_size_write(inode, ip->i_d.di_size);
inode->i_blocks =
@@ -278,6 +263,72 @@ xfs_blkdev_put(
close_bdev_excl(bdev);
}
+/*
+ * Try to write out the superblock using barriers.
+ */
+STATIC int
+xfs_barrier_test(
+ xfs_mount_t *mp)
+{
+ xfs_buf_t *sbp = xfs_getsb(mp, 0);
+ int error;
+
+ XFS_BUF_UNDONE(sbp);
+ XFS_BUF_UNREAD(sbp);
+ XFS_BUF_UNDELAYWRITE(sbp);
+ XFS_BUF_WRITE(sbp);
+ XFS_BUF_UNASYNC(sbp);
+ XFS_BUF_ORDERED(sbp);
+
+ xfsbdstrat(mp, sbp);
+ error = xfs_iowait(sbp);
+
+ /*
+ * Clear all the flags we set and possible error state in the
+ * buffer. We only did the write to try out whether barriers
+ * worked and shouldn't leave any traces in the superblock
+ * buffer.
+ */
+ XFS_BUF_DONE(sbp);
+ XFS_BUF_ERROR(sbp, 0);
+ XFS_BUF_UNORDERED(sbp);
+
+ xfs_buf_relse(sbp);
+ return error;
+}
+
+void
+xfs_mountfs_check_barriers(xfs_mount_t *mp)
+{
+ int error;
+
+ if (mp->m_logdev_targp != mp->m_ddev_targp) {
+ xfs_fs_cmn_err(CE_NOTE, mp,
+ "Disabling barriers, not supported with external log device");
+ mp->m_flags &= ~XFS_MOUNT_BARRIER;
+ }
+
+ if (mp->m_ddev_targp->pbr_bdev->bd_disk->queue->ordered ==
+ QUEUE_ORDERED_NONE) {
+ xfs_fs_cmn_err(CE_NOTE, mp,
+ "Disabling barriers, not supported by the underlying device");
+ mp->m_flags &= ~XFS_MOUNT_BARRIER;
+ }
+
+ error = xfs_barrier_test(mp);
+ if (error) {
+ xfs_fs_cmn_err(CE_NOTE, mp,
+ "Disabling barriers, trial barrier write failed");
+ mp->m_flags &= ~XFS_MOUNT_BARRIER;
+ }
+}
+
+void
+xfs_blkdev_issue_flush(
+ xfs_buftarg_t *buftarg)
+{
+ blkdev_issue_flush(buftarg->pbr_bdev, NULL);
+}
STATIC struct inode *
linvfs_alloc_inode(
@@ -701,6 +752,18 @@ linvfs_show_options(
}
STATIC int
+linvfs_quotasync(
+ struct super_block *sb,
+ int type)
+{
+ struct vfs *vfsp = LINVFS_GET_VFS(sb);
+ int error;
+
+ VFS_QUOTACTL(vfsp, Q_XQUOTASYNC, 0, (caddr_t)NULL, error);
+ return -error;
+}
+
+STATIC int
linvfs_getxstate(
struct super_block *sb,
struct fs_quota_stat *fqs)
@@ -868,6 +931,7 @@ STATIC struct super_operations linvfs_sops = {
};
STATIC struct quotactl_ops linvfs_qops = {
+ .quota_sync = linvfs_quotasync,
.get_xstate = linvfs_getxstate,
.set_xstate = linvfs_setxstate,
.get_xquota = linvfs_getxquota,
diff --git a/fs/xfs/linux-2.6/xfs_super.h b/fs/xfs/linux-2.6/xfs_super.h
index ec7e0035c731..df59408dca06 100644
--- a/fs/xfs/linux-2.6/xfs_super.h
+++ b/fs/xfs/linux-2.6/xfs_super.h
@@ -1,33 +1,19 @@
/*
- * Copyright (c) 2000-2004 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __XFS_SUPER_H__
#define __XFS_SUPER_H__
@@ -132,6 +118,7 @@ extern void xfs_flush_device(struct xfs_inode *);
extern int xfs_blkdev_get(struct xfs_mount *, const char *,
struct block_device **);
extern void xfs_blkdev_put(struct block_device *);
+extern void xfs_blkdev_issue_flush(struct xfs_buftarg *);
extern struct export_operations linvfs_export_ops;
diff --git a/fs/xfs/linux-2.6/xfs_sysctl.c b/fs/xfs/linux-2.6/xfs_sysctl.c
index 0dc010356f4d..a02564972420 100644
--- a/fs/xfs/linux-2.6/xfs_sysctl.c
+++ b/fs/xfs/linux-2.6/xfs_sysctl.c
@@ -1,44 +1,26 @@
/*
- * Copyright (c) 2001-2004 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2001-2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-
#include "xfs.h"
-#include "xfs_rw.h"
#include <linux/sysctl.h>
#include <linux/proc_fs.h>
-
static struct ctl_table_header *xfs_table_header;
-
#ifdef CONFIG_PROC_FS
STATIC int
xfs_stats_clear_proc_handler(
@@ -76,7 +58,7 @@ xfs_stats_clear_proc_handler(
STATIC ctl_table xfs_table[] = {
{XFS_RESTRICT_CHOWN, "restrict_chown", &xfs_params.restrict_chown.val,
sizeof(int), 0644, NULL, &proc_dointvec_minmax,
- &sysctl_intvec, NULL,
+ &sysctl_intvec, NULL,
&xfs_params.restrict_chown.min, &xfs_params.restrict_chown.max},
{XFS_SGID_INHERIT, "irix_sgid_inherit", &xfs_params.sgid_inherit.val,
@@ -86,22 +68,22 @@ STATIC ctl_table xfs_table[] = {
{XFS_SYMLINK_MODE, "irix_symlink_mode", &xfs_params.symlink_mode.val,
sizeof(int), 0644, NULL, &proc_dointvec_minmax,
- &sysctl_intvec, NULL,
+ &sysctl_intvec, NULL,
&xfs_params.symlink_mode.min, &xfs_params.symlink_mode.max},
{XFS_PANIC_MASK, "panic_mask", &xfs_params.panic_mask.val,
sizeof(int), 0644, NULL, &proc_dointvec_minmax,
- &sysctl_intvec, NULL,
+ &sysctl_intvec, NULL,
&xfs_params.panic_mask.min, &xfs_params.panic_mask.max},
{XFS_ERRLEVEL, "error_level", &xfs_params.error_level.val,
sizeof(int), 0644, NULL, &proc_dointvec_minmax,
- &sysctl_intvec, NULL,
+ &sysctl_intvec, NULL,
&xfs_params.error_level.min, &xfs_params.error_level.max},
{XFS_SYNCD_TIMER, "xfssyncd_centisecs", &xfs_params.syncd_timer.val,
sizeof(int), 0644, NULL, &proc_dointvec_minmax,
- &sysctl_intvec, NULL,
+ &sysctl_intvec, NULL,
&xfs_params.syncd_timer.min, &xfs_params.syncd_timer.max},
{XFS_INHERIT_SYNC, "inherit_sync", &xfs_params.inherit_sync.val,
@@ -118,7 +100,7 @@ STATIC ctl_table xfs_table[] = {
sizeof(int), 0644, NULL, &proc_dointvec_minmax,
&sysctl_intvec, NULL,
&xfs_params.inherit_noatim.min, &xfs_params.inherit_noatim.max},
-
+
{XFS_BUF_TIMER, "xfsbufd_centisecs", &xfs_params.xfs_buf_timer.val,
sizeof(int), 0644, NULL, &proc_dointvec_minmax,
&sysctl_intvec, NULL,
@@ -136,14 +118,14 @@ STATIC ctl_table xfs_table[] = {
{XFS_ROTORSTEP, "rotorstep", &xfs_params.rotorstep.val,
sizeof(int), 0644, NULL, &proc_dointvec_minmax,
- &sysctl_intvec, NULL,
+ &sysctl_intvec, NULL,
&xfs_params.rotorstep.min, &xfs_params.rotorstep.max},
/* please keep this the last entry */
#ifdef CONFIG_PROC_FS
{XFS_STATS_CLEAR, "stats_clear", &xfs_params.stats_clear.val,
sizeof(int), 0644, NULL, &xfs_stats_clear_proc_handler,
- &sysctl_intvec, NULL,
+ &sysctl_intvec, NULL,
&xfs_params.stats_clear.min, &xfs_params.stats_clear.max},
#endif /* CONFIG_PROC_FS */
diff --git a/fs/xfs/linux-2.6/xfs_sysctl.h b/fs/xfs/linux-2.6/xfs_sysctl.h
index a39a95020a58..bc8c11f13722 100644
--- a/fs/xfs/linux-2.6/xfs_sysctl.h
+++ b/fs/xfs/linux-2.6/xfs_sysctl.h
@@ -1,35 +1,20 @@
/*
- * Copyright (c) 2001-2004 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2001-2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-
#ifndef __XFS_SYSCTL_H__
#define __XFS_SYSCTL_H__
diff --git a/fs/xfs/linux-2.6/xfs_version.h b/fs/xfs/linux-2.6/xfs_version.h
index 96f96394417e..f8d279d7563a 100644
--- a/fs/xfs/linux-2.6/xfs_version.h
+++ b/fs/xfs/linux-2.6/xfs_version.h
@@ -1,34 +1,22 @@
/*
- * Copyright (c) 2001-2002 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2001-2002,2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#ifndef __XFS_VERSION_H__
+#define __XFS_VERSION_H__
/*
* Dummy file that can contain a timestamp to put into the
@@ -36,9 +24,6 @@
* running
*/
-#ifndef __XFS_VERSION_H__
-#define __XFS_VERSION_H__
-
#define XFS_VERSION_STRING "SGI XFS"
#endif /* __XFS_VERSION_H__ */
diff --git a/fs/xfs/linux-2.6/xfs_vfs.c b/fs/xfs/linux-2.6/xfs_vfs.c
index 34cc902ec119..c855d62e5344 100644
--- a/fs/xfs/linux-2.6/xfs_vfs.c
+++ b/fs/xfs/linux-2.6/xfs_vfs.c
@@ -1,38 +1,22 @@
/*
- * Copyright (c) 2000-2004 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-
#include "xfs.h"
#include "xfs_fs.h"
-#include "xfs_macros.h"
#include "xfs_inum.h"
#include "xfs_log.h"
#include "xfs_clnt.h"
diff --git a/fs/xfs/linux-2.6/xfs_vfs.h b/fs/xfs/linux-2.6/xfs_vfs.h
index f0ab574fb47a..57caf9eddee0 100644
--- a/fs/xfs/linux-2.6/xfs_vfs.h
+++ b/fs/xfs/linux-2.6/xfs_vfs.h
@@ -1,33 +1,19 @@
/*
- * Copyright (c) 2000-2004 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __XFS_VFS_H__
#define __XFS_VFS_H__
@@ -95,6 +81,7 @@ typedef enum {
#define VFS_RDONLY 0x0001 /* read-only vfs */
#define VFS_GRPID 0x0002 /* group-ID assigned from directory */
#define VFS_DMI 0x0004 /* filesystem has the DMI enabled */
+#define VFS_32BITINODES 0x0008 /* do not use inums above 32 bits */
#define VFS_END 0x0008 /* max flag */
#define SYNC_ATTR 0x0001 /* sync attributes */
diff --git a/fs/xfs/linux-2.6/xfs_vnode.c b/fs/xfs/linux-2.6/xfs_vnode.c
index 268f45bf6a9a..e9bbcb4d6243 100644
--- a/fs/xfs/linux-2.6/xfs_vnode.c
+++ b/fs/xfs/linux-2.6/xfs_vnode.c
@@ -1,38 +1,22 @@
/*
- * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-
#include "xfs.h"
-
uint64_t vn_generation; /* vnode generation number */
DEFINE_SPINLOCK(vnumber_lock);
@@ -44,7 +28,6 @@ DEFINE_SPINLOCK(vnumber_lock);
#define vptosync(v) (&vsync[((unsigned long)v) % NVSYNC])
STATIC wait_queue_head_t vsync[NVSYNC];
-
void
vn_init(void)
{
@@ -124,6 +107,7 @@ vn_revalidate_core(
inode->i_mtime = vap->va_mtime;
inode->i_ctime = vap->va_ctime;
inode->i_atime = vap->va_atime;
+ inode->i_blksize = vap->va_blocksize;
if (vap->va_xflags & XFS_XFLAG_IMMUTABLE)
inode->i_flags |= S_IMMUTABLE;
else
diff --git a/fs/xfs/linux-2.6/xfs_vnode.h b/fs/xfs/linux-2.6/xfs_vnode.h
index 35f306cebb87..f2bbb327c081 100644
--- a/fs/xfs/linux-2.6/xfs_vnode.h
+++ b/fs/xfs/linux-2.6/xfs_vnode.h
@@ -1,33 +1,19 @@
/*
- * Copyright (c) 2000-2005 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* Portions Copyright (c) 1989, 1993
* The Regents of the University of California. All rights reserved.
@@ -216,11 +202,12 @@ typedef void (*vop_rwunlock_t)(bhv_desc_t *, vrwlock_t);
typedef int (*vop_bmap_t)(bhv_desc_t *, xfs_off_t, ssize_t, int,
struct xfs_iomap *, int *);
typedef int (*vop_reclaim_t)(bhv_desc_t *);
-typedef int (*vop_attr_get_t)(bhv_desc_t *, char *, char *, int *, int,
- struct cred *);
-typedef int (*vop_attr_set_t)(bhv_desc_t *, char *, char *, int, int,
- struct cred *);
-typedef int (*vop_attr_remove_t)(bhv_desc_t *, char *, int, struct cred *);
+typedef int (*vop_attr_get_t)(bhv_desc_t *, const char *, char *, int *,
+ int, struct cred *);
+typedef int (*vop_attr_set_t)(bhv_desc_t *, const char *, char *, int,
+ int, struct cred *);
+typedef int (*vop_attr_remove_t)(bhv_desc_t *, const char *,
+ int, struct cred *);
typedef int (*vop_attr_list_t)(bhv_desc_t *, char *, int, int,
struct attrlist_cursor_kern *, struct cred *);
typedef void (*vop_link_removed_t)(bhv_desc_t *, vnode_t *, int);
@@ -566,13 +553,6 @@ static __inline__ void vn_flagclr(struct vnode *vp, uint flag)
}
/*
- * Update modify/access/change times on the vnode
- */
-#define VN_MTIMESET(vp, tvp) (LINVFS_GET_IP(vp)->i_mtime = *(tvp))
-#define VN_ATIMESET(vp, tvp) (LINVFS_GET_IP(vp)->i_atime = *(tvp))
-#define VN_CTIMESET(vp, tvp) (LINVFS_GET_IP(vp)->i_ctime = *(tvp))
-
-/*
* Dealing with bad inodes
*/
static inline void vn_mark_bad(struct vnode *vp)
@@ -603,6 +583,7 @@ static inline int VN_BAD(struct vnode *vp)
#define ATTR_LAZY 0x80 /* set/get attributes lazily */
#define ATTR_NONBLOCK 0x100 /* return EAGAIN if operation would block */
#define ATTR_NOLOCK 0x200 /* Don't grab any conflicting locks */
+#define ATTR_NOSIZETOK 0x400 /* Don't get the SIZE token */
/*
* Flags to VOP_FSYNC and VOP_RECLAIM.
diff --git a/fs/xfs/quota/Makefile b/fs/xfs/quota/Makefile
deleted file mode 100644
index 7a4f725b2824..000000000000
--- a/fs/xfs/quota/Makefile
+++ /dev/null
@@ -1 +0,0 @@
-include $(TOPDIR)/fs/xfs/quota/Makefile-linux-$(VERSION).$(PATCHLEVEL)
diff --git a/fs/xfs/quota/Makefile-linux-2.6 b/fs/xfs/quota/Makefile-linux-2.6
deleted file mode 100644
index 93e60e839355..000000000000
--- a/fs/xfs/quota/Makefile-linux-2.6
+++ /dev/null
@@ -1,53 +0,0 @@
-#
-# Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved.
-#
-# This program is free software; you can redistribute it and/or modify it
-# under the terms of version 2 of the GNU General Public License as
-# published by the Free Software Foundation.
-#
-# This program is distributed in the hope that it would be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-#
-# Further, this software is distributed without any warranty that it is
-# free of the rightful claim of any third person regarding infringement
-# or the like. Any license provided herein, whether implied or
-# otherwise, applies only to this software file. Patent licenses, if
-# any, provided herein do not apply to combinations of this program with
-# other software, or any other product whatsoever.
-#
-# You should have received a copy of the GNU General Public License along
-# with this program; if not, write the Free Software Foundation, Inc., 59
-# Temple Place - Suite 330, Boston MA 02111-1307, USA.
-#
-# Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
-# Mountain View, CA 94043, or:
-#
-# http://www.sgi.com
-#
-# For further information regarding this notice, see:
-#
-# http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
-#
-
-EXTRA_CFLAGS += -I $(TOPDIR)/fs/xfs -I $(TOPDIR)/fs/xfs/linux-2.6
-
-ifeq ($(CONFIG_XFS_DEBUG),y)
- EXTRA_CFLAGS += -g -DDEBUG
- #EXTRA_CFLAGS += -DQUOTADEBUG
-endif
-ifeq ($(CONFIG_XFS_TRACE),y)
- EXTRA_CFLAGS += -DXFS_DQUOT_TRACE
- EXTRA_CFLAGS += -DXFS_VNODE_TRACE
-endif
-
-xfs-$(CONFIG_XFS_QUOTA) += xfs_dquot.o \
- xfs_dquot_item.o \
- xfs_trans_dquot.o \
- xfs_qm_syscalls.o \
- xfs_qm_bhv.o \
- xfs_qm.o
-
-ifeq ($(CONFIG_XFS_QUOTA),y)
-xfs-$(CONFIG_PROC_FS) += xfs_qm_stats.o
-endif
diff --git a/fs/xfs/quota/xfs_dquot.c b/fs/xfs/quota/xfs_dquot.c
index e2e8d35fa4d0..00b5043dfa5a 100644
--- a/fs/xfs/quota/xfs_dquot.c
+++ b/fs/xfs/quota/xfs_dquot.c
@@ -1,39 +1,25 @@
/*
- * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2003 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-
#include "xfs.h"
#include "xfs_fs.h"
-#include "xfs_inum.h"
+#include "xfs_bit.h"
#include "xfs_log.h"
+#include "xfs_inum.h"
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
@@ -43,18 +29,17 @@
#include "xfs_dmapi.h"
#include "xfs_quota.h"
#include "xfs_mount.h"
-#include "xfs_alloc_btree.h"
#include "xfs_bmap_btree.h"
+#include "xfs_alloc_btree.h"
#include "xfs_ialloc_btree.h"
-#include "xfs_btree.h"
-#include "xfs_ialloc.h"
-#include "xfs_attr_sf.h"
#include "xfs_dir_sf.h"
#include "xfs_dir2_sf.h"
+#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
#include "xfs_inode.h"
+#include "xfs_btree.h"
+#include "xfs_ialloc.h"
#include "xfs_bmap.h"
-#include "xfs_bit.h"
#include "xfs_rtalloc.h"
#include "xfs_error.h"
#include "xfs_itable.h"
@@ -66,7 +51,6 @@
#include "xfs_buf_item.h"
#include "xfs_trans_space.h"
#include "xfs_trans_priv.h"
-
#include "xfs_qm.h"
@@ -112,7 +96,7 @@ xfs_qm_dqinit(
brandnewdquot = xfs_qm_dqalloc_incore(&dqp);
dqp->dq_flags = type;
- INT_SET(dqp->q_core.d_id, ARCH_CONVERT, id);
+ dqp->q_core.d_id = cpu_to_be32(id);
dqp->q_mount = mp;
/*
@@ -194,10 +178,10 @@ xfs_qm_dqinit_core(
/*
* Caller has zero'd the entire dquot 'chunk' already.
*/
- INT_SET(d->dd_diskdq.d_magic, ARCH_CONVERT, XFS_DQUOT_MAGIC);
- INT_SET(d->dd_diskdq.d_version, ARCH_CONVERT, XFS_DQUOT_VERSION);
- INT_SET(d->dd_diskdq.d_id, ARCH_CONVERT, id);
- INT_SET(d->dd_diskdq.d_flags, ARCH_CONVERT, type);
+ d->dd_diskdq.d_magic = cpu_to_be16(XFS_DQUOT_MAGIC);
+ d->dd_diskdq.d_version = XFS_DQUOT_VERSION;
+ d->dd_diskdq.d_id = cpu_to_be32(id);
+ d->dd_diskdq.d_flags = type;
}
@@ -227,19 +211,13 @@ __xfs_dqtrace_entry(
(void *)(__psint_t)dqp->q_nrefs,
(void *)(__psint_t)dqp->dq_flags,
(void *)(__psint_t)dqp->q_res_bcount,
- (void *)(__psint_t)INT_GET(dqp->q_core.d_bcount,
- ARCH_CONVERT),
- (void *)(__psint_t)INT_GET(dqp->q_core.d_icount,
- ARCH_CONVERT),
- (void *)(__psint_t)INT_GET(dqp->q_core.d_blk_hardlimit,
- ARCH_CONVERT),
- (void *)(__psint_t)INT_GET(dqp->q_core.d_blk_softlimit,
- ARCH_CONVERT),
- (void *)(__psint_t)INT_GET(dqp->q_core.d_ino_hardlimit,
- ARCH_CONVERT),
- (void *)(__psint_t)INT_GET(dqp->q_core.d_ino_softlimit,
- ARCH_CONVERT),
- (void *)(__psint_t)INT_GET(dqp->q_core.d_id, ARCH_CONVERT),
+ (void *)(__psint_t)be64_to_cpu(dqp->q_core.d_bcount),
+ (void *)(__psint_t)be64_to_cpu(dqp->q_core.d_icount),
+ (void *)(__psint_t)be64_to_cpu(dqp->q_core.d_blk_hardlimit),
+ (void *)(__psint_t)be64_to_cpu(dqp->q_core.d_blk_softlimit),
+ (void *)(__psint_t)be64_to_cpu(dqp->q_core.d_ino_hardlimit),
+ (void *)(__psint_t)be64_to_cpu(dqp->q_core.d_ino_softlimit),
+ (void *)(__psint_t)be32_to_cpu(dqp->q_core.d_id),
(void *)(__psint_t)current_pid(),
(void *)(__psint_t)ino,
(void *)(__psint_t)retaddr,
@@ -264,17 +242,17 @@ xfs_qm_adjust_dqlimits(
ASSERT(d->d_id);
if (q->qi_bsoftlimit && !d->d_blk_softlimit)
- INT_SET(d->d_blk_softlimit, ARCH_CONVERT, q->qi_bsoftlimit);
+ d->d_blk_softlimit = cpu_to_be64(q->qi_bsoftlimit);
if (q->qi_bhardlimit && !d->d_blk_hardlimit)
- INT_SET(d->d_blk_hardlimit, ARCH_CONVERT, q->qi_bhardlimit);
+ d->d_blk_hardlimit = cpu_to_be64(q->qi_bhardlimit);
if (q->qi_isoftlimit && !d->d_ino_softlimit)
- INT_SET(d->d_ino_softlimit, ARCH_CONVERT, q->qi_isoftlimit);
+ d->d_ino_softlimit = cpu_to_be64(q->qi_isoftlimit);
if (q->qi_ihardlimit && !d->d_ino_hardlimit)
- INT_SET(d->d_ino_hardlimit, ARCH_CONVERT, q->qi_ihardlimit);
+ d->d_ino_hardlimit = cpu_to_be64(q->qi_ihardlimit);
if (q->qi_rtbsoftlimit && !d->d_rtb_softlimit)
- INT_SET(d->d_rtb_softlimit, ARCH_CONVERT, q->qi_rtbsoftlimit);
+ d->d_rtb_softlimit = cpu_to_be64(q->qi_rtbsoftlimit);
if (q->qi_rtbhardlimit && !d->d_rtb_hardlimit)
- INT_SET(d->d_rtb_hardlimit, ARCH_CONVERT, q->qi_rtbhardlimit);
+ d->d_rtb_hardlimit = cpu_to_be64(q->qi_rtbhardlimit);
}
/*
@@ -298,81 +276,81 @@ xfs_qm_adjust_dqtimers(
ASSERT(d->d_id);
#ifdef QUOTADEBUG
- if (INT_GET(d->d_blk_hardlimit, ARCH_CONVERT))
- ASSERT(INT_GET(d->d_blk_softlimit, ARCH_CONVERT) <=
- INT_GET(d->d_blk_hardlimit, ARCH_CONVERT));
- if (INT_GET(d->d_ino_hardlimit, ARCH_CONVERT))
- ASSERT(INT_GET(d->d_ino_softlimit, ARCH_CONVERT) <=
- INT_GET(d->d_ino_hardlimit, ARCH_CONVERT));
- if (INT_GET(d->d_rtb_hardlimit, ARCH_CONVERT))
- ASSERT(INT_GET(d->d_rtb_softlimit, ARCH_CONVERT) <=
- INT_GET(d->d_rtb_hardlimit, ARCH_CONVERT));
+ if (d->d_blk_hardlimit)
+ ASSERT(be64_to_cpu(d->d_blk_softlimit) <=
+ be64_to_cpu(d->d_blk_hardlimit));
+ if (d->d_ino_hardlimit)
+ ASSERT(be64_to_cpu(d->d_ino_softlimit) <=
+ be64_to_cpu(d->d_ino_hardlimit));
+ if (d->d_rtb_hardlimit)
+ ASSERT(be64_to_cpu(d->d_rtb_softlimit) <=
+ be64_to_cpu(d->d_rtb_hardlimit));
#endif
if (!d->d_btimer) {
- if ((INT_GET(d->d_blk_softlimit, ARCH_CONVERT) &&
- (INT_GET(d->d_bcount, ARCH_CONVERT) >=
- INT_GET(d->d_blk_softlimit, ARCH_CONVERT))) ||
- (INT_GET(d->d_blk_hardlimit, ARCH_CONVERT) &&
- (INT_GET(d->d_bcount, ARCH_CONVERT) >=
- INT_GET(d->d_blk_hardlimit, ARCH_CONVERT)))) {
- INT_SET(d->d_btimer, ARCH_CONVERT,
- get_seconds() + XFS_QI_BTIMELIMIT(mp));
+ if ((d->d_blk_softlimit &&
+ (be64_to_cpu(d->d_bcount) >=
+ be64_to_cpu(d->d_blk_softlimit))) ||
+ (d->d_blk_hardlimit &&
+ (be64_to_cpu(d->d_bcount) >=
+ be64_to_cpu(d->d_blk_hardlimit)))) {
+ d->d_btimer = cpu_to_be32(get_seconds() +
+ XFS_QI_BTIMELIMIT(mp));
} else {
d->d_bwarns = 0;
}
} else {
if ((!d->d_blk_softlimit ||
- (INT_GET(d->d_bcount, ARCH_CONVERT) <
- INT_GET(d->d_blk_softlimit, ARCH_CONVERT))) &&
+ (be64_to_cpu(d->d_bcount) <
+ be64_to_cpu(d->d_blk_softlimit))) &&
(!d->d_blk_hardlimit ||
- (INT_GET(d->d_bcount, ARCH_CONVERT) <
- INT_GET(d->d_blk_hardlimit, ARCH_CONVERT)))) {
+ (be64_to_cpu(d->d_bcount) <
+ be64_to_cpu(d->d_blk_hardlimit)))) {
d->d_btimer = 0;
}
}
if (!d->d_itimer) {
- if ((INT_GET(d->d_ino_softlimit, ARCH_CONVERT) &&
- (INT_GET(d->d_icount, ARCH_CONVERT) >=
- INT_GET(d->d_ino_softlimit, ARCH_CONVERT))) ||
- (INT_GET(d->d_ino_hardlimit, ARCH_CONVERT) &&
- (INT_GET(d->d_icount, ARCH_CONVERT) >=
- INT_GET(d->d_ino_hardlimit, ARCH_CONVERT)))) {
- INT_SET(d->d_itimer, ARCH_CONVERT,
- get_seconds() + XFS_QI_ITIMELIMIT(mp));
+ if ((d->d_ino_softlimit &&
+ (be64_to_cpu(d->d_icount) >=
+ be64_to_cpu(d->d_ino_softlimit))) ||
+ (d->d_ino_hardlimit &&
+ (be64_to_cpu(d->d_icount) >=
+ be64_to_cpu(d->d_ino_hardlimit)))) {
+ d->d_itimer = cpu_to_be32(get_seconds() +
+ XFS_QI_ITIMELIMIT(mp));
} else {
d->d_iwarns = 0;
}
} else {
if ((!d->d_ino_softlimit ||
- (INT_GET(d->d_icount, ARCH_CONVERT) <
- INT_GET(d->d_ino_softlimit, ARCH_CONVERT))) &&
+ (be64_to_cpu(d->d_icount) <
+ be64_to_cpu(d->d_ino_softlimit))) &&
(!d->d_ino_hardlimit ||
- (INT_GET(d->d_icount, ARCH_CONVERT) <
- INT_GET(d->d_ino_hardlimit, ARCH_CONVERT)))) {
+ (be64_to_cpu(d->d_icount) <
+ be64_to_cpu(d->d_ino_hardlimit)))) {
d->d_itimer = 0;
}
}
if (!d->d_rtbtimer) {
- if ((INT_GET(d->d_rtb_softlimit, ARCH_CONVERT) &&
- (INT_GET(d->d_rtbcount, ARCH_CONVERT) >=
- INT_GET(d->d_rtb_softlimit, ARCH_CONVERT))) ||
- (INT_GET(d->d_rtb_hardlimit, ARCH_CONVERT) &&
- (INT_GET(d->d_rtbcount, ARCH_CONVERT) >=
- INT_GET(d->d_rtb_hardlimit, ARCH_CONVERT)))) {
- INT_SET(d->d_rtbtimer, ARCH_CONVERT,
- get_seconds() + XFS_QI_RTBTIMELIMIT(mp));
+ if ((d->d_rtb_softlimit &&
+ (be64_to_cpu(d->d_rtbcount) >=
+ be64_to_cpu(d->d_rtb_softlimit))) ||
+ (d->d_rtb_hardlimit &&
+ (be64_to_cpu(d->d_rtbcount) >=
+ be64_to_cpu(d->d_rtb_hardlimit)))) {
+ d->d_rtbtimer = cpu_to_be32(get_seconds() +
+ XFS_QI_RTBTIMELIMIT(mp));
} else {
d->d_rtbwarns = 0;
}
} else {
if ((!d->d_rtb_softlimit ||
- (INT_GET(d->d_rtbcount, ARCH_CONVERT) <
- INT_GET(d->d_rtb_softlimit, ARCH_CONVERT))) &&
+ (be64_to_cpu(d->d_rtbcount) <
+ be64_to_cpu(d->d_rtb_softlimit))) &&
(!d->d_rtb_hardlimit ||
- (INT_GET(d->d_rtbcount, ARCH_CONVERT) <
- INT_GET(d->d_rtb_hardlimit, ARCH_CONVERT)))) {
+ (be64_to_cpu(d->d_rtbcount) <
+ be64_to_cpu(d->d_rtb_hardlimit)))) {
d->d_rtbtimer = 0;
}
}
@@ -490,7 +468,7 @@ xfs_qm_dqalloc(
* Make a chunk of dquots out of this buffer and log
* the entire thing.
*/
- xfs_qm_init_dquot_blk(tp, mp, INT_GET(dqp->q_core.d_id, ARCH_CONVERT),
+ xfs_qm_init_dquot_blk(tp, mp, be32_to_cpu(dqp->q_core.d_id),
dqp->dq_flags & XFS_DQ_ALLTYPES, bp);
/*
@@ -554,7 +532,7 @@ xfs_qm_dqtobp(
xfs_trans_t *tp = (tpp ? *tpp : NULL);
mp = dqp->q_mount;
- id = INT_GET(dqp->q_core.d_id, ARCH_CONVERT);
+ id = be32_to_cpu(dqp->q_core.d_id);
nmaps = 1;
newdquot = B_FALSE;
@@ -563,8 +541,7 @@ xfs_qm_dqtobp(
*/
if (dqp->q_blkno == (xfs_daddr_t) 0) {
/* We use the id as an index */
- dqp->q_fileoffset = (xfs_fileoff_t) ((uint)id /
- XFS_QM_DQPERBLK(mp));
+ dqp->q_fileoffset = (xfs_fileoff_t)id / XFS_QM_DQPERBLK(mp);
nmaps = 1;
quotip = XFS_DQ_TO_QIP(dqp);
xfs_ilock(quotip, XFS_ILOCK_SHARED);
@@ -694,16 +671,16 @@ xfs_qm_dqread(
/* copy everything from disk dquot to the incore dquot */
memcpy(&dqp->q_core, ddqp, sizeof(xfs_disk_dquot_t));
- ASSERT(INT_GET(dqp->q_core.d_id, ARCH_CONVERT) == id);
+ ASSERT(be32_to_cpu(dqp->q_core.d_id) == id);
xfs_qm_dquot_logitem_init(dqp);
/*
* Reservation counters are defined as reservation plus current usage
* to avoid having to add everytime.
*/
- dqp->q_res_bcount = INT_GET(ddqp->d_bcount, ARCH_CONVERT);
- dqp->q_res_icount = INT_GET(ddqp->d_icount, ARCH_CONVERT);
- dqp->q_res_rtbcount = INT_GET(ddqp->d_rtbcount, ARCH_CONVERT);
+ dqp->q_res_bcount = be64_to_cpu(ddqp->d_bcount);
+ dqp->q_res_icount = be64_to_cpu(ddqp->d_icount);
+ dqp->q_res_rtbcount = be64_to_cpu(ddqp->d_rtbcount);
/* Mark the buf so that this will stay incore a little longer */
XFS_BUF_SET_VTYPE_REF(bp, B_FS_DQUOT, XFS_DQUOT_REF);
@@ -829,7 +806,7 @@ xfs_qm_dqlookup(
* dqlock to look at the id field of the dquot, since the
* id can't be modified without the hashlock anyway.
*/
- if (INT_GET(dqp->q_core.d_id, ARCH_CONVERT) == id && dqp->q_mount == mp) {
+ if (be32_to_cpu(dqp->q_core.d_id) == id && dqp->q_mount == mp) {
xfs_dqtrace_entry(dqp, "DQFOUND BY LOOKUP");
/*
* All in core dquots must be on the dqlist of mp
@@ -860,7 +837,7 @@ xfs_qm_dqlookup(
* id couldn't have changed; we had the hashlock all
* along
*/
- ASSERT(INT_GET(dqp->q_core.d_id, ARCH_CONVERT) == id);
+ ASSERT(be32_to_cpu(dqp->q_core.d_id) == id);
if (flist_locked) {
if (dqp->q_nrefs != 0) {
@@ -1282,7 +1259,7 @@ xfs_qm_dqflush(
return (error);
}
- if (xfs_qm_dqcheck(&dqp->q_core, INT_GET(ddqp->d_id, ARCH_CONVERT),
+ if (xfs_qm_dqcheck(&dqp->q_core, be32_to_cpu(ddqp->d_id),
0, XFS_QMOPT_DOWARN, "dqflush (incore copy)")) {
xfs_force_shutdown(dqp->q_mount, XFS_CORRUPT_INCORE);
return XFS_ERROR(EIO);
@@ -1435,8 +1412,8 @@ xfs_dqlock2(
{
if (d1 && d2) {
ASSERT(d1 != d2);
- if (INT_GET(d1->q_core.d_id, ARCH_CONVERT) >
- INT_GET(d2->q_core.d_id, ARCH_CONVERT)) {
+ if (be32_to_cpu(d1->q_core.d_id) >
+ be32_to_cpu(d2->q_core.d_id)) {
xfs_dqlock(d2);
xfs_dqlock(d1);
} else {
@@ -1558,33 +1535,33 @@ xfs_qm_dqprint(xfs_dquot_t *dqp)
{
cmn_err(CE_DEBUG, "-----------KERNEL DQUOT----------------");
cmn_err(CE_DEBUG, "---- dquotID = %d",
- (int)INT_GET(dqp->q_core.d_id, ARCH_CONVERT));
+ (int)be32_to_cpu(dqp->q_core.d_id));
cmn_err(CE_DEBUG, "---- type = %s", DQFLAGTO_TYPESTR(dqp));
cmn_err(CE_DEBUG, "---- fs = 0x%p", dqp->q_mount);
cmn_err(CE_DEBUG, "---- blkno = 0x%x", (int) dqp->q_blkno);
cmn_err(CE_DEBUG, "---- boffset = 0x%x", (int) dqp->q_bufoffset);
cmn_err(CE_DEBUG, "---- blkhlimit = %Lu (0x%x)",
- INT_GET(dqp->q_core.d_blk_hardlimit, ARCH_CONVERT),
- (int) INT_GET(dqp->q_core.d_blk_hardlimit, ARCH_CONVERT));
+ be64_to_cpu(dqp->q_core.d_blk_hardlimit),
+ (int)be64_to_cpu(dqp->q_core.d_blk_hardlimit));
cmn_err(CE_DEBUG, "---- blkslimit = %Lu (0x%x)",
- INT_GET(dqp->q_core.d_blk_softlimit, ARCH_CONVERT),
- (int)INT_GET(dqp->q_core.d_blk_softlimit, ARCH_CONVERT));
+ be64_to_cpu(dqp->q_core.d_blk_softlimit),
+ (int)be64_to_cpu(dqp->q_core.d_blk_softlimit));
cmn_err(CE_DEBUG, "---- inohlimit = %Lu (0x%x)",
- INT_GET(dqp->q_core.d_ino_hardlimit, ARCH_CONVERT),
- (int)INT_GET(dqp->q_core.d_ino_hardlimit, ARCH_CONVERT));
+ be64_to_cpu(dqp->q_core.d_ino_hardlimit),
+ (int)be64_to_cpu(dqp->q_core.d_ino_hardlimit));
cmn_err(CE_DEBUG, "---- inoslimit = %Lu (0x%x)",
- INT_GET(dqp->q_core.d_ino_softlimit, ARCH_CONVERT),
- (int)INT_GET(dqp->q_core.d_ino_softlimit, ARCH_CONVERT));
+ be64_to_cpu(dqp->q_core.d_ino_softlimit),
+ (int)be64_to_cpu(dqp->q_core.d_ino_softlimit));
cmn_err(CE_DEBUG, "---- bcount = %Lu (0x%x)",
- INT_GET(dqp->q_core.d_bcount, ARCH_CONVERT),
- (int)INT_GET(dqp->q_core.d_bcount, ARCH_CONVERT));
+ be64_to_cpu(dqp->q_core.d_bcount),
+ (int)be64_to_cpu(dqp->q_core.d_bcount));
cmn_err(CE_DEBUG, "---- icount = %Lu (0x%x)",
- INT_GET(dqp->q_core.d_icount, ARCH_CONVERT),
- (int)INT_GET(dqp->q_core.d_icount, ARCH_CONVERT));
+ be64_to_cpu(dqp->q_core.d_icount),
+ (int)be64_to_cpu(dqp->q_core.d_icount));
cmn_err(CE_DEBUG, "---- btimer = %d",
- (int)INT_GET(dqp->q_core.d_btimer, ARCH_CONVERT));
+ (int)be32_to_cpu(dqp->q_core.d_btimer));
cmn_err(CE_DEBUG, "---- itimer = %d",
- (int)INT_GET(dqp->q_core.d_itimer, ARCH_CONVERT));
+ (int)be32_to_cpu(dqp->q_core.d_itimer));
cmn_err(CE_DEBUG, "---------------------------");
}
#endif
diff --git a/fs/xfs/quota/xfs_dquot.h b/fs/xfs/quota/xfs_dquot.h
index 8ebc87176c78..c0c629663a5c 100644
--- a/fs/xfs/quota/xfs_dquot.h
+++ b/fs/xfs/quota/xfs_dquot.h
@@ -1,33 +1,19 @@
/*
- * Copyright (c) 2000-2005 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __XFS_DQUOT_H__
#define __XFS_DQUOT_H__
diff --git a/fs/xfs/quota/xfs_dquot_item.c b/fs/xfs/quota/xfs_dquot_item.c
index e74eaa7dd1bc..2f69822344e5 100644
--- a/fs/xfs/quota/xfs_dquot_item.c
+++ b/fs/xfs/quota/xfs_dquot_item.c
@@ -1,39 +1,25 @@
/*
- * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2003 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-
#include "xfs.h"
#include "xfs_fs.h"
-#include "xfs_inum.h"
+#include "xfs_bit.h"
#include "xfs_log.h"
+#include "xfs_inum.h"
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
@@ -43,18 +29,17 @@
#include "xfs_dmapi.h"
#include "xfs_quota.h"
#include "xfs_mount.h"
-#include "xfs_alloc_btree.h"
#include "xfs_bmap_btree.h"
+#include "xfs_alloc_btree.h"
#include "xfs_ialloc_btree.h"
-#include "xfs_btree.h"
-#include "xfs_ialloc.h"
-#include "xfs_attr_sf.h"
#include "xfs_dir_sf.h"
#include "xfs_dir2_sf.h"
+#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
#include "xfs_inode.h"
#include "xfs_bmap.h"
-#include "xfs_bit.h"
+#include "xfs_btree.h"
+#include "xfs_ialloc.h"
#include "xfs_rtalloc.h"
#include "xfs_error.h"
#include "xfs_itable.h"
@@ -65,10 +50,8 @@
#include "xfs_attr.h"
#include "xfs_buf_item.h"
#include "xfs_trans_priv.h"
-
#include "xfs_qm.h"
-
/*
* returns the number of iovecs needed to log the given dquot item.
*/
@@ -467,7 +450,7 @@ xfs_qm_dquot_logitem_init(
lp->qli_item.li_mountp = dqp->q_mount;
lp->qli_dquot = dqp;
lp->qli_format.qlf_type = XFS_LI_DQUOT;
- lp->qli_format.qlf_id = INT_GET(dqp->q_core.d_id, ARCH_CONVERT);
+ lp->qli_format.qlf_id = be32_to_cpu(dqp->q_core.d_id);
lp->qli_format.qlf_blkno = dqp->q_blkno;
lp->qli_format.qlf_len = 1;
/*
diff --git a/fs/xfs/quota/xfs_dquot_item.h b/fs/xfs/quota/xfs_dquot_item.h
index 9c6500dabcaa..5a632531f843 100644
--- a/fs/xfs/quota/xfs_dquot_item.h
+++ b/fs/xfs/quota/xfs_dquot_item.h
@@ -1,33 +1,19 @@
/*
- * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2003 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __XFS_DQUOT_ITEM_H__
#define __XFS_DQUOT_ITEM_H__
diff --git a/fs/xfs/quota/xfs_qm.c b/fs/xfs/quota/xfs_qm.c
index efde16e0a913..1aea42d71a64 100644
--- a/fs/xfs/quota/xfs_qm.c
+++ b/fs/xfs/quota/xfs_qm.c
@@ -1,39 +1,25 @@
/*
- * Copyright (c) 2000-2005 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-
#include "xfs.h"
#include "xfs_fs.h"
-#include "xfs_inum.h"
+#include "xfs_bit.h"
#include "xfs_log.h"
+#include "xfs_inum.h"
#include "xfs_clnt.h"
#include "xfs_trans.h"
#include "xfs_sb.h"
@@ -44,21 +30,20 @@
#include "xfs_dmapi.h"
#include "xfs_quota.h"
#include "xfs_mount.h"
-#include "xfs_alloc_btree.h"
#include "xfs_bmap_btree.h"
+#include "xfs_alloc_btree.h"
#include "xfs_ialloc_btree.h"
-#include "xfs_btree.h"
-#include "xfs_ialloc.h"
-#include "xfs_attr_sf.h"
#include "xfs_dir_sf.h"
#include "xfs_dir2_sf.h"
+#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
#include "xfs_inode.h"
-#include "xfs_bmap.h"
-#include "xfs_bit.h"
+#include "xfs_btree.h"
+#include "xfs_ialloc.h"
+#include "xfs_itable.h"
#include "xfs_rtalloc.h"
#include "xfs_error.h"
-#include "xfs_itable.h"
+#include "xfs_bmap.h"
#include "xfs_rw.h"
#include "xfs_acl.h"
#include "xfs_cap.h"
@@ -67,7 +52,6 @@
#include "xfs_buf_item.h"
#include "xfs_trans_space.h"
#include "xfs_utils.h"
-
#include "xfs_qm.h"
/*
@@ -76,8 +60,9 @@
* quota functionality, including maintaining the freelist and hash
* tables of dquots.
*/
-mutex_t xfs_Gqm_lock;
+mutex_t xfs_Gqm_lock;
struct xfs_qm *xfs_Gqm;
+uint ndquot;
kmem_zone_t *qm_dqzone;
kmem_zone_t *qm_dqtrxzone;
@@ -107,10 +92,10 @@ extern mutex_t qcheck_lock;
for (dqp = (l)->qh_next; dqp != NULL; dqp = dqp->NXT) { \
cmn_err(CE_DEBUG, " %d. \"%d (%s)\" " \
"bcnt = %d, icnt = %d, refs = %d", \
- ++i, (int) INT_GET(dqp->q_core.d_id, ARCH_CONVERT), \
+ ++i, (int) be32_to_cpu(dqp->q_core.d_id), \
DQFLAGTO_TYPESTR(dqp), \
- (int) INT_GET(dqp->q_core.d_bcount, ARCH_CONVERT), \
- (int) INT_GET(dqp->q_core.d_icount, ARCH_CONVERT), \
+ (int) be64_to_cpu(dqp->q_core.d_bcount), \
+ (int) be64_to_cpu(dqp->q_core.d_icount), \
(int) dqp->q_nrefs); } \
}
#else
@@ -124,25 +109,25 @@ extern mutex_t qcheck_lock;
STATIC struct xfs_qm *
xfs_Gqm_init(void)
{
- xfs_qm_t *xqm;
- int hsize, i;
-
- xqm = kmem_zalloc(sizeof(xfs_qm_t), KM_SLEEP);
- ASSERT(xqm);
+ xfs_dqhash_t *udqhash, *gdqhash;
+ xfs_qm_t *xqm;
+ uint i, hsize, flags = KM_SLEEP | KM_MAYFAIL;
/*
* Initialize the dquot hash tables.
*/
- hsize = (DQUOT_HASH_HEURISTIC < XFS_QM_NCSIZE_THRESHOLD) ?
- XFS_QM_HASHSIZE_LOW : XFS_QM_HASHSIZE_HIGH;
- xqm->qm_dqhashmask = hsize - 1;
+ hsize = XFS_QM_HASHSIZE_HIGH;
+ while (!(udqhash = kmem_zalloc(hsize * sizeof(xfs_dqhash_t), flags))) {
+ if ((hsize >>= 1) <= XFS_QM_HASHSIZE_LOW)
+ flags = KM_SLEEP;
+ }
+ gdqhash = kmem_zalloc(hsize * sizeof(xfs_dqhash_t), KM_SLEEP);
+ ndquot = hsize << 8;
- xqm->qm_usr_dqhtable = (xfs_dqhash_t *)kmem_zalloc(hsize *
- sizeof(xfs_dqhash_t),
- KM_SLEEP);
- xqm->qm_grp_dqhtable = (xfs_dqhash_t *)kmem_zalloc(hsize *
- sizeof(xfs_dqhash_t),
- KM_SLEEP);
+ xqm = kmem_zalloc(sizeof(xfs_qm_t), KM_SLEEP);
+ xqm->qm_dqhashmask = hsize - 1;
+ xqm->qm_usr_dqhtable = udqhash;
+ xqm->qm_grp_dqhtable = gdqhash;
ASSERT(xqm->qm_usr_dqhtable != NULL);
ASSERT(xqm->qm_grp_dqhtable != NULL);
@@ -743,7 +728,7 @@ xfs_qm_dqattach_one(
*/
if (udqhint &&
(dqp = udqhint->q_gdquot) &&
- (INT_GET(dqp->q_core.d_id, ARCH_CONVERT) == id)) {
+ (be32_to_cpu(dqp->q_core.d_id) == id)) {
ASSERT(XFS_DQ_IS_LOCKED(udqhint));
xfs_dqlock(dqp);
XFS_DQHOLD(dqp);
@@ -1213,42 +1198,24 @@ xfs_qm_init_quotainfo(
* a user or group before he or she can not perform any
* more writing. If it is zero, a default is used.
*/
- qinf->qi_btimelimit =
- INT_GET(ddqp->d_btimer, ARCH_CONVERT) ?
- INT_GET(ddqp->d_btimer, ARCH_CONVERT) :
- XFS_QM_BTIMELIMIT;
- qinf->qi_itimelimit =
- INT_GET(ddqp->d_itimer, ARCH_CONVERT) ?
- INT_GET(ddqp->d_itimer, ARCH_CONVERT) :
- XFS_QM_ITIMELIMIT;
- qinf->qi_rtbtimelimit =
- INT_GET(ddqp->d_rtbtimer, ARCH_CONVERT) ?
- INT_GET(ddqp->d_rtbtimer, ARCH_CONVERT) :
- XFS_QM_RTBTIMELIMIT;
- qinf->qi_bwarnlimit =
- INT_GET(ddqp->d_bwarns, ARCH_CONVERT) ?
- INT_GET(ddqp->d_bwarns, ARCH_CONVERT) :
- XFS_QM_BWARNLIMIT;
- qinf->qi_iwarnlimit =
- INT_GET(ddqp->d_iwarns, ARCH_CONVERT) ?
- INT_GET(ddqp->d_iwarns, ARCH_CONVERT) :
- XFS_QM_IWARNLIMIT;
- qinf->qi_rtbwarnlimit =
- INT_GET(ddqp->d_rtbwarns, ARCH_CONVERT) ?
- INT_GET(ddqp->d_rtbwarns, ARCH_CONVERT) :
- XFS_QM_RTBWARNLIMIT;
- qinf->qi_bhardlimit =
- INT_GET(ddqp->d_blk_hardlimit, ARCH_CONVERT);
- qinf->qi_bsoftlimit =
- INT_GET(ddqp->d_blk_softlimit, ARCH_CONVERT);
- qinf->qi_ihardlimit =
- INT_GET(ddqp->d_ino_hardlimit, ARCH_CONVERT);
- qinf->qi_isoftlimit =
- INT_GET(ddqp->d_ino_softlimit, ARCH_CONVERT);
- qinf->qi_rtbhardlimit =
- INT_GET(ddqp->d_rtb_hardlimit, ARCH_CONVERT);
- qinf->qi_rtbsoftlimit =
- INT_GET(ddqp->d_rtb_softlimit, ARCH_CONVERT);
+ qinf->qi_btimelimit = ddqp->d_btimer ?
+ be32_to_cpu(ddqp->d_btimer) : XFS_QM_BTIMELIMIT;
+ qinf->qi_itimelimit = ddqp->d_itimer ?
+ be32_to_cpu(ddqp->d_itimer) : XFS_QM_ITIMELIMIT;
+ qinf->qi_rtbtimelimit = ddqp->d_rtbtimer ?
+ be32_to_cpu(ddqp->d_rtbtimer) : XFS_QM_RTBTIMELIMIT;
+ qinf->qi_bwarnlimit = ddqp->d_bwarns ?
+ be16_to_cpu(ddqp->d_bwarns) : XFS_QM_BWARNLIMIT;
+ qinf->qi_iwarnlimit = ddqp->d_iwarns ?
+ be16_to_cpu(ddqp->d_iwarns) : XFS_QM_IWARNLIMIT;
+ qinf->qi_rtbwarnlimit = ddqp->d_rtbwarns ?
+ be16_to_cpu(ddqp->d_rtbwarns) : XFS_QM_RTBWARNLIMIT;
+ qinf->qi_bhardlimit = be64_to_cpu(ddqp->d_blk_hardlimit);
+ qinf->qi_bsoftlimit = be64_to_cpu(ddqp->d_blk_softlimit);
+ qinf->qi_ihardlimit = be64_to_cpu(ddqp->d_ino_hardlimit);
+ qinf->qi_isoftlimit = be64_to_cpu(ddqp->d_ino_softlimit);
+ qinf->qi_rtbhardlimit = be64_to_cpu(ddqp->d_rtb_hardlimit);
+ qinf->qi_rtbsoftlimit = be64_to_cpu(ddqp->d_rtb_softlimit);
/*
* We sent the XFS_QMOPT_DQSUSER flag to dqget because
@@ -1527,15 +1494,15 @@ xfs_qm_reset_dqcounts(
*/
(void) xfs_qm_dqcheck(ddq, id+j, type, XFS_QMOPT_DQREPAIR,
"xfs_quotacheck");
- INT_SET(ddq->d_bcount, ARCH_CONVERT, 0ULL);
- INT_SET(ddq->d_icount, ARCH_CONVERT, 0ULL);
- INT_SET(ddq->d_rtbcount, ARCH_CONVERT, 0ULL);
- INT_SET(ddq->d_btimer, ARCH_CONVERT, (time_t)0);
- INT_SET(ddq->d_itimer, ARCH_CONVERT, (time_t)0);
- INT_SET(ddq->d_rtbtimer, ARCH_CONVERT, (time_t)0);
- INT_SET(ddq->d_bwarns, ARCH_CONVERT, 0UL);
- INT_SET(ddq->d_iwarns, ARCH_CONVERT, 0UL);
- INT_SET(ddq->d_rtbwarns, ARCH_CONVERT, 0UL);
+ ddq->d_bcount = 0;
+ ddq->d_icount = 0;
+ ddq->d_rtbcount = 0;
+ ddq->d_btimer = 0;
+ ddq->d_itimer = 0;
+ ddq->d_rtbtimer = 0;
+ ddq->d_bwarns = 0;
+ ddq->d_iwarns = 0;
+ ddq->d_rtbwarns = 0;
ddq = (xfs_disk_dquot_t *) ((xfs_dqblk_t *)ddq + 1);
}
@@ -1708,14 +1675,14 @@ xfs_qm_quotacheck_dqadjust(
* Adjust the inode count and the block count to reflect this inode's
* resource usage.
*/
- INT_MOD(dqp->q_core.d_icount, ARCH_CONVERT, +1);
+ be64_add(&dqp->q_core.d_icount, 1);
dqp->q_res_icount++;
if (nblks) {
- INT_MOD(dqp->q_core.d_bcount, ARCH_CONVERT, nblks);
+ be64_add(&dqp->q_core.d_bcount, nblks);
dqp->q_res_bcount += nblks;
}
if (rtblks) {
- INT_MOD(dqp->q_core.d_rtbcount, ARCH_CONVERT, rtblks);
+ be64_add(&dqp->q_core.d_rtbcount, rtblks);
dqp->q_res_rtbcount += rtblks;
}
@@ -2202,7 +2169,7 @@ xfs_qm_shake_freelist(
xfs_dqtrace_entry(dqp, "DQSHAKE: UNLINKING");
#ifdef QUOTADEBUG
cmn_err(CE_DEBUG, "Shake 0x%p, ID 0x%x\n",
- dqp, INT_GET(dqp->q_core.d_id, ARCH_CONVERT));
+ dqp, be32_to_cpu(dqp->q_core.d_id));
#endif
ASSERT(dqp->q_nrefs == 0);
nextdqp = dqp->dq_flnext;
@@ -2670,7 +2637,7 @@ xfs_qm_vop_chown_reserve(
XFS_QMOPT_RES_RTBLKS : XFS_QMOPT_RES_REGBLKS;
if (XFS_IS_UQUOTA_ON(mp) && udqp &&
- ip->i_d.di_uid != (uid_t)INT_GET(udqp->q_core.d_id, ARCH_CONVERT)) {
+ ip->i_d.di_uid != (uid_t)be32_to_cpu(udqp->q_core.d_id)) {
delblksudq = udqp;
/*
* If there are delayed allocation blocks, then we have to
@@ -2683,10 +2650,10 @@ xfs_qm_vop_chown_reserve(
}
}
if (XFS_IS_OQUOTA_ON(ip->i_mount) && gdqp) {
- if ((XFS_IS_GQUOTA_ON(ip->i_mount) && ip->i_d.di_gid !=
- INT_GET(gdqp->q_core.d_id, ARCH_CONVERT)) ||
- (XFS_IS_PQUOTA_ON(ip->i_mount) && ip->i_d.di_projid !=
- INT_GET(gdqp->q_core.d_id, ARCH_CONVERT))) {
+ if ((XFS_IS_GQUOTA_ON(ip->i_mount) &&
+ ip->i_d.di_gid != be32_to_cpu(gdqp->q_core.d_id)) ||
+ (XFS_IS_PQUOTA_ON(ip->i_mount) &&
+ ip->i_d.di_projid != be32_to_cpu(gdqp->q_core.d_id))) {
delblksgdq = gdqp;
if (delblks) {
ASSERT(ip->i_gdquot);
@@ -2776,7 +2743,7 @@ xfs_qm_vop_dqattach_and_dqmod_newinode(
xfs_dqunlock(udqp);
ASSERT(ip->i_udquot == NULL);
ip->i_udquot = udqp;
- ASSERT(ip->i_d.di_uid == INT_GET(udqp->q_core.d_id, ARCH_CONVERT));
+ ASSERT(ip->i_d.di_uid == be32_to_cpu(udqp->q_core.d_id));
xfs_trans_mod_dquot(tp, udqp, XFS_TRANS_DQ_ICOUNT, 1);
}
if (gdqp) {
@@ -2785,7 +2752,7 @@ xfs_qm_vop_dqattach_and_dqmod_newinode(
xfs_dqunlock(gdqp);
ASSERT(ip->i_gdquot == NULL);
ip->i_gdquot = gdqp;
- ASSERT(ip->i_d.di_gid == INT_GET(gdqp->q_core.d_id, ARCH_CONVERT));
+ ASSERT(ip->i_d.di_gid == be32_to_cpu(gdqp->q_core.d_id));
xfs_trans_mod_dquot(tp, gdqp, XFS_TRANS_DQ_ICOUNT, 1);
}
}
diff --git a/fs/xfs/quota/xfs_qm.h b/fs/xfs/quota/xfs_qm.h
index 0b00b3c67015..12da259f2fcb 100644
--- a/fs/xfs/quota/xfs_qm.h
+++ b/fs/xfs/quota/xfs_qm.h
@@ -1,33 +1,19 @@
/*
- * Copyright (c) 2000-2005 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __XFS_QM_H__
#define __XFS_QM_H__
@@ -40,6 +26,7 @@
struct xfs_qm;
struct xfs_inode;
+extern uint ndquot;
extern mutex_t xfs_Gqm_lock;
extern struct xfs_qm *xfs_Gqm;
extern kmem_zone_t *qm_dqzone;
@@ -65,9 +52,8 @@ extern kmem_zone_t *qm_dqtrxzone;
/*
* Dquot hashtable constants/threshold values.
*/
-#define XFS_QM_NCSIZE_THRESHOLD 5000
-#define XFS_QM_HASHSIZE_LOW 32
-#define XFS_QM_HASHSIZE_HIGH 64
+#define XFS_QM_HASHSIZE_LOW (NBPP / sizeof(xfs_dqhash_t))
+#define XFS_QM_HASHSIZE_HIGH ((NBPP * 4) / sizeof(xfs_dqhash_t))
/*
* We output a cmn_err when quotachecking a quota file with more than
diff --git a/fs/xfs/quota/xfs_qm_bhv.c b/fs/xfs/quota/xfs_qm_bhv.c
index 8890a18a99d8..d9d2993de435 100644
--- a/fs/xfs/quota/xfs_qm_bhv.c
+++ b/fs/xfs/quota/xfs_qm_bhv.c
@@ -1,70 +1,55 @@
/*
- * Copyright (c) 2000-2005 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-
#include "xfs.h"
#include "xfs_fs.h"
-#include "xfs_inum.h"
+#include "xfs_bit.h"
#include "xfs_log.h"
+#include "xfs_inum.h"
#include "xfs_clnt.h"
#include "xfs_trans.h"
#include "xfs_sb.h"
+#include "xfs_ag.h"
#include "xfs_dir.h"
#include "xfs_dir2.h"
#include "xfs_alloc.h"
#include "xfs_dmapi.h"
#include "xfs_quota.h"
#include "xfs_mount.h"
-#include "xfs_alloc_btree.h"
#include "xfs_bmap_btree.h"
+#include "xfs_alloc_btree.h"
#include "xfs_ialloc_btree.h"
-#include "xfs_btree.h"
-#include "xfs_ialloc.h"
-#include "xfs_attr_sf.h"
#include "xfs_dir_sf.h"
#include "xfs_dir2_sf.h"
+#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
#include "xfs_inode.h"
+#include "xfs_ialloc.h"
+#include "xfs_itable.h"
+#include "xfs_btree.h"
#include "xfs_bmap.h"
-#include "xfs_bit.h"
#include "xfs_rtalloc.h"
#include "xfs_error.h"
-#include "xfs_itable.h"
#include "xfs_rw.h"
#include "xfs_acl.h"
#include "xfs_cap.h"
#include "xfs_mac.h"
#include "xfs_attr.h"
#include "xfs_buf_item.h"
-
#include "xfs_qm.h"
#define MNTOPT_QUOTA "quota" /* disk quotas (user) */
diff --git a/fs/xfs/quota/xfs_qm_stats.c b/fs/xfs/quota/xfs_qm_stats.c
index 29978e037fee..0570f7733550 100644
--- a/fs/xfs/quota/xfs_qm_stats.c
+++ b/fs/xfs/quota/xfs_qm_stats.c
@@ -1,69 +1,54 @@
/*
- * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2003 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-
#include "xfs.h"
#include "xfs_fs.h"
-#include "xfs_inum.h"
+#include "xfs_bit.h"
#include "xfs_log.h"
+#include "xfs_inum.h"
#include "xfs_trans.h"
#include "xfs_sb.h"
+#include "xfs_ag.h"
#include "xfs_dir.h"
#include "xfs_dir2.h"
#include "xfs_alloc.h"
#include "xfs_dmapi.h"
#include "xfs_quota.h"
#include "xfs_mount.h"
-#include "xfs_alloc_btree.h"
#include "xfs_bmap_btree.h"
+#include "xfs_alloc_btree.h"
#include "xfs_ialloc_btree.h"
-#include "xfs_btree.h"
-#include "xfs_ialloc.h"
-#include "xfs_attr_sf.h"
#include "xfs_dir_sf.h"
#include "xfs_dir2_sf.h"
+#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
#include "xfs_inode.h"
+#include "xfs_ialloc.h"
+#include "xfs_itable.h"
#include "xfs_bmap.h"
-#include "xfs_bit.h"
+#include "xfs_btree.h"
#include "xfs_rtalloc.h"
#include "xfs_error.h"
-#include "xfs_itable.h"
#include "xfs_rw.h"
#include "xfs_acl.h"
#include "xfs_cap.h"
#include "xfs_mac.h"
#include "xfs_attr.h"
#include "xfs_buf_item.h"
-
#include "xfs_qm.h"
struct xqmstats xqmstats;
diff --git a/fs/xfs/quota/xfs_qm_stats.h b/fs/xfs/quota/xfs_qm_stats.h
index 8093c5c284ec..a50ffabcf554 100644
--- a/fs/xfs/quota/xfs_qm_stats.h
+++ b/fs/xfs/quota/xfs_qm_stats.h
@@ -1,38 +1,23 @@
/*
- * Copyright (c) 2002 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2002 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __XFS_QM_STATS_H__
#define __XFS_QM_STATS_H__
-
#if defined(CONFIG_PROC_FS) && !defined(XFS_STATS_OFF)
/*
diff --git a/fs/xfs/quota/xfs_qm_syscalls.c b/fs/xfs/quota/xfs_qm_syscalls.c
index 15e02e8a9d4f..24690e1af659 100644
--- a/fs/xfs/quota/xfs_qm_syscalls.c
+++ b/fs/xfs/quota/xfs_qm_syscalls.c
@@ -1,62 +1,48 @@
/*
- * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-
#include "xfs.h"
#include "xfs_fs.h"
-#include "xfs_inum.h"
+#include "xfs_bit.h"
#include "xfs_log.h"
+#include "xfs_inum.h"
#include "xfs_trans.h"
#include "xfs_sb.h"
+#include "xfs_ag.h"
#include "xfs_dir.h"
#include "xfs_dir2.h"
#include "xfs_alloc.h"
#include "xfs_dmapi.h"
#include "xfs_quota.h"
#include "xfs_mount.h"
-#include "xfs_alloc_btree.h"
#include "xfs_bmap_btree.h"
+#include "xfs_alloc_btree.h"
#include "xfs_ialloc_btree.h"
-#include "xfs_btree.h"
-#include "xfs_ialloc.h"
-#include "xfs_attr_sf.h"
#include "xfs_dir_sf.h"
#include "xfs_dir2_sf.h"
+#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
#include "xfs_inode.h"
+#include "xfs_ialloc.h"
+#include "xfs_itable.h"
#include "xfs_bmap.h"
-#include "xfs_bit.h"
+#include "xfs_btree.h"
#include "xfs_rtalloc.h"
#include "xfs_error.h"
-#include "xfs_itable.h"
#include "xfs_rw.h"
#include "xfs_acl.h"
#include "xfs_cap.h"
@@ -64,7 +50,6 @@
#include "xfs_attr.h"
#include "xfs_buf_item.h"
#include "xfs_utils.h"
-
#include "xfs_qm.h"
#ifdef DEBUG
@@ -109,10 +94,7 @@ xfs_qm_quotactl(
vfsp = bhvtovfs(bdp);
mp = XFS_VFSTOM(vfsp);
- if (addr == NULL && cmd != Q_SYNC)
- return XFS_ERROR(EINVAL);
- if (id < 0 && cmd != Q_SYNC)
- return XFS_ERROR(EINVAL);
+ ASSERT(addr != NULL || cmd == Q_XQUOTASYNC);
/*
* The following commands are valid even when quotaoff.
@@ -122,7 +104,7 @@ xfs_qm_quotactl(
/*
* Truncate quota files. quota must be off.
*/
- if (XFS_IS_QUOTA_ON(mp) || addr == NULL)
+ if (XFS_IS_QUOTA_ON(mp))
return XFS_ERROR(EINVAL);
if (vfsp->vfs_flag & VFS_RDONLY)
return XFS_ERROR(EROFS);
@@ -140,8 +122,6 @@ xfs_qm_quotactl(
* QUOTAON - enabling quota enforcement.
* Quota accounting must be turned on at mount time.
*/
- if (addr == NULL)
- return XFS_ERROR(EINVAL);
if (vfsp->vfs_flag & VFS_RDONLY)
return XFS_ERROR(EROFS);
return (xfs_qm_scall_quotaon(mp,
@@ -152,6 +132,9 @@ xfs_qm_quotactl(
return XFS_ERROR(EROFS);
break;
+ case Q_XQUOTASYNC:
+ return (xfs_sync_inodes(mp, SYNC_DELWRI, 0, NULL));
+
default:
break;
}
@@ -655,13 +638,13 @@ xfs_qm_scall_setqlim(
*/
hard = (newlim->d_fieldmask & FS_DQ_BHARD) ?
(xfs_qcnt_t) XFS_BB_TO_FSB(mp, newlim->d_blk_hardlimit) :
- INT_GET(ddq->d_blk_hardlimit, ARCH_CONVERT);
+ be64_to_cpu(ddq->d_blk_hardlimit);
soft = (newlim->d_fieldmask & FS_DQ_BSOFT) ?
(xfs_qcnt_t) XFS_BB_TO_FSB(mp, newlim->d_blk_softlimit) :
- INT_GET(ddq->d_blk_softlimit, ARCH_CONVERT);
+ be64_to_cpu(ddq->d_blk_softlimit);
if (hard == 0 || hard >= soft) {
- INT_SET(ddq->d_blk_hardlimit, ARCH_CONVERT, hard);
- INT_SET(ddq->d_blk_softlimit, ARCH_CONVERT, soft);
+ ddq->d_blk_hardlimit = cpu_to_be64(hard);
+ ddq->d_blk_softlimit = cpu_to_be64(soft);
if (id == 0) {
mp->m_quotainfo->qi_bhardlimit = hard;
mp->m_quotainfo->qi_bsoftlimit = soft;
@@ -671,13 +654,13 @@ xfs_qm_scall_setqlim(
}
hard = (newlim->d_fieldmask & FS_DQ_RTBHARD) ?
(xfs_qcnt_t) XFS_BB_TO_FSB(mp, newlim->d_rtb_hardlimit) :
- INT_GET(ddq->d_rtb_hardlimit, ARCH_CONVERT);
+ be64_to_cpu(ddq->d_rtb_hardlimit);
soft = (newlim->d_fieldmask & FS_DQ_RTBSOFT) ?
(xfs_qcnt_t) XFS_BB_TO_FSB(mp, newlim->d_rtb_softlimit) :
- INT_GET(ddq->d_rtb_softlimit, ARCH_CONVERT);
+ be64_to_cpu(ddq->d_rtb_softlimit);
if (hard == 0 || hard >= soft) {
- INT_SET(ddq->d_rtb_hardlimit, ARCH_CONVERT, hard);
- INT_SET(ddq->d_rtb_softlimit, ARCH_CONVERT, soft);
+ ddq->d_rtb_hardlimit = cpu_to_be64(hard);
+ ddq->d_rtb_softlimit = cpu_to_be64(soft);
if (id == 0) {
mp->m_quotainfo->qi_rtbhardlimit = hard;
mp->m_quotainfo->qi_rtbsoftlimit = soft;
@@ -688,13 +671,13 @@ xfs_qm_scall_setqlim(
hard = (newlim->d_fieldmask & FS_DQ_IHARD) ?
(xfs_qcnt_t) newlim->d_ino_hardlimit :
- INT_GET(ddq->d_ino_hardlimit, ARCH_CONVERT);
+ be64_to_cpu(ddq->d_ino_hardlimit);
soft = (newlim->d_fieldmask & FS_DQ_ISOFT) ?
(xfs_qcnt_t) newlim->d_ino_softlimit :
- INT_GET(ddq->d_ino_softlimit, ARCH_CONVERT);
+ be64_to_cpu(ddq->d_ino_softlimit);
if (hard == 0 || hard >= soft) {
- INT_SET(ddq->d_ino_hardlimit, ARCH_CONVERT, hard);
- INT_SET(ddq->d_ino_softlimit, ARCH_CONVERT, soft);
+ ddq->d_ino_hardlimit = cpu_to_be64(hard);
+ ddq->d_ino_softlimit = cpu_to_be64(soft);
if (id == 0) {
mp->m_quotainfo->qi_ihardlimit = hard;
mp->m_quotainfo->qi_isoftlimit = soft;
@@ -707,11 +690,11 @@ xfs_qm_scall_setqlim(
* Update warnings counter(s) if requested
*/
if (newlim->d_fieldmask & FS_DQ_BWARNS)
- INT_SET(ddq->d_bwarns, ARCH_CONVERT, newlim->d_bwarns);
+ ddq->d_bwarns = cpu_to_be16(newlim->d_bwarns);
if (newlim->d_fieldmask & FS_DQ_IWARNS)
- INT_SET(ddq->d_iwarns, ARCH_CONVERT, newlim->d_iwarns);
+ ddq->d_iwarns = cpu_to_be16(newlim->d_iwarns);
if (newlim->d_fieldmask & FS_DQ_RTBWARNS)
- INT_SET(ddq->d_rtbwarns, ARCH_CONVERT, newlim->d_rtbwarns);
+ ddq->d_rtbwarns = cpu_to_be16(newlim->d_rtbwarns);
if (id == 0) {
/*
@@ -723,15 +706,15 @@ xfs_qm_scall_setqlim(
*/
if (newlim->d_fieldmask & FS_DQ_BTIMER) {
mp->m_quotainfo->qi_btimelimit = newlim->d_btimer;
- INT_SET(ddq->d_btimer, ARCH_CONVERT, newlim->d_btimer);
+ ddq->d_btimer = cpu_to_be32(newlim->d_btimer);
}
if (newlim->d_fieldmask & FS_DQ_ITIMER) {
mp->m_quotainfo->qi_itimelimit = newlim->d_itimer;
- INT_SET(ddq->d_itimer, ARCH_CONVERT, newlim->d_itimer);
+ ddq->d_itimer = cpu_to_be32(newlim->d_itimer);
}
if (newlim->d_fieldmask & FS_DQ_RTBTIMER) {
mp->m_quotainfo->qi_rtbtimelimit = newlim->d_rtbtimer;
- INT_SET(ddq->d_rtbtimer, ARCH_CONVERT, newlim->d_rtbtimer);
+ ddq->d_rtbtimer = cpu_to_be32(newlim->d_rtbtimer);
}
if (newlim->d_fieldmask & FS_DQ_BWARNS)
mp->m_quotainfo->qi_bwarnlimit = newlim->d_bwarns;
@@ -902,33 +885,27 @@ xfs_qm_export_dquot(
{
memset(dst, 0, sizeof(*dst));
dst->d_version = FS_DQUOT_VERSION; /* different from src->d_version */
- dst->d_flags =
- xfs_qm_export_qtype_flags(INT_GET(src->d_flags, ARCH_CONVERT));
- dst->d_id = INT_GET(src->d_id, ARCH_CONVERT);
- dst->d_blk_hardlimit = (__uint64_t)
- XFS_FSB_TO_BB(mp, INT_GET(src->d_blk_hardlimit, ARCH_CONVERT));
- dst->d_blk_softlimit = (__uint64_t)
- XFS_FSB_TO_BB(mp, INT_GET(src->d_blk_softlimit, ARCH_CONVERT));
- dst->d_ino_hardlimit = (__uint64_t)
- INT_GET(src->d_ino_hardlimit, ARCH_CONVERT);
- dst->d_ino_softlimit = (__uint64_t)
- INT_GET(src->d_ino_softlimit, ARCH_CONVERT);
- dst->d_bcount = (__uint64_t)
- XFS_FSB_TO_BB(mp, INT_GET(src->d_bcount, ARCH_CONVERT));
- dst->d_icount = (__uint64_t) INT_GET(src->d_icount, ARCH_CONVERT);
- dst->d_btimer = (__uint32_t) INT_GET(src->d_btimer, ARCH_CONVERT);
- dst->d_itimer = (__uint32_t) INT_GET(src->d_itimer, ARCH_CONVERT);
- dst->d_iwarns = INT_GET(src->d_iwarns, ARCH_CONVERT);
- dst->d_bwarns = INT_GET(src->d_bwarns, ARCH_CONVERT);
-
- dst->d_rtb_hardlimit = (__uint64_t)
- XFS_FSB_TO_BB(mp, INT_GET(src->d_rtb_hardlimit, ARCH_CONVERT));
- dst->d_rtb_softlimit = (__uint64_t)
- XFS_FSB_TO_BB(mp, INT_GET(src->d_rtb_softlimit, ARCH_CONVERT));
- dst->d_rtbcount = (__uint64_t)
- XFS_FSB_TO_BB(mp, INT_GET(src->d_rtbcount, ARCH_CONVERT));
- dst->d_rtbtimer = (__uint32_t) INT_GET(src->d_rtbtimer, ARCH_CONVERT);
- dst->d_rtbwarns = INT_GET(src->d_rtbwarns, ARCH_CONVERT);
+ dst->d_flags = xfs_qm_export_qtype_flags(src->d_flags);
+ dst->d_id = be32_to_cpu(src->d_id);
+ dst->d_blk_hardlimit =
+ XFS_FSB_TO_BB(mp, be64_to_cpu(src->d_blk_hardlimit));
+ dst->d_blk_softlimit =
+ XFS_FSB_TO_BB(mp, be64_to_cpu(src->d_blk_softlimit));
+ dst->d_ino_hardlimit = be64_to_cpu(src->d_ino_hardlimit);
+ dst->d_ino_softlimit = be64_to_cpu(src->d_ino_softlimit);
+ dst->d_bcount = XFS_FSB_TO_BB(mp, be64_to_cpu(src->d_bcount));
+ dst->d_icount = be64_to_cpu(src->d_icount);
+ dst->d_btimer = be32_to_cpu(src->d_btimer);
+ dst->d_itimer = be32_to_cpu(src->d_itimer);
+ dst->d_iwarns = be16_to_cpu(src->d_iwarns);
+ dst->d_bwarns = be16_to_cpu(src->d_bwarns);
+ dst->d_rtb_hardlimit =
+ XFS_FSB_TO_BB(mp, be64_to_cpu(src->d_rtb_hardlimit));
+ dst->d_rtb_softlimit =
+ XFS_FSB_TO_BB(mp, be64_to_cpu(src->d_rtb_softlimit));
+ dst->d_rtbcount = XFS_FSB_TO_BB(mp, be64_to_cpu(src->d_rtbcount));
+ dst->d_rtbtimer = be32_to_cpu(src->d_rtbtimer);
+ dst->d_rtbwarns = be16_to_cpu(src->d_rtbwarns);
/*
* Internally, we don't reset all the timers when quota enforcement
@@ -1222,10 +1199,10 @@ xfs_qm_dqtest_failed(
qmtest_nfails++;
if (error)
cmn_err(CE_DEBUG, "quotacheck failed id=%d, err=%d\nreason: %s",
- INT_GET(d->d_id, ARCH_CONVERT), error, reason);
+ d->d_id, error, reason);
else
cmn_err(CE_DEBUG, "quotacheck failed id=%d (%s) [%d != %d]",
- INT_GET(d->d_id, ARCH_CONVERT), reason, (int)a, (int)b);
+ d->d_id, reason, (int)a, (int)b);
xfs_qm_dqtest_print(d);
if (dqp)
xfs_qm_dqprint(dqp);
@@ -1237,21 +1214,21 @@ xfs_dqtest_cmp2(
xfs_dquot_t *dqp)
{
int err = 0;
- if (INT_GET(dqp->q_core.d_icount, ARCH_CONVERT) != d->d_icount) {
+ if (be64_to_cpu(dqp->q_core.d_icount) != d->d_icount) {
xfs_qm_dqtest_failed(d, dqp, "icount mismatch",
- INT_GET(dqp->q_core.d_icount, ARCH_CONVERT),
+ be64_to_cpu(dqp->q_core.d_icount),
d->d_icount, 0);
err++;
}
- if (INT_GET(dqp->q_core.d_bcount, ARCH_CONVERT) != d->d_bcount) {
+ if (be64_to_cpu(dqp->q_core.d_bcount) != d->d_bcount) {
xfs_qm_dqtest_failed(d, dqp, "bcount mismatch",
- INT_GET(dqp->q_core.d_bcount, ARCH_CONVERT),
+ be64_to_cpu(dqp->q_core.d_bcount),
d->d_bcount, 0);
err++;
}
- if (INT_GET(dqp->q_core.d_blk_softlimit, ARCH_CONVERT) &&
- INT_GET(dqp->q_core.d_bcount, ARCH_CONVERT) >=
- INT_GET(dqp->q_core.d_blk_softlimit, ARCH_CONVERT)) {
+ if (dqp->q_core.d_blk_softlimit &&
+ be64_to_cpu(dqp->q_core.d_bcount) >=
+ be64_to_cpu(dqp->q_core.d_blk_softlimit)) {
if (!dqp->q_core.d_btimer && dqp->q_core.d_id) {
cmn_err(CE_DEBUG,
"%d [%s] [0x%p] BLK TIMER NOT STARTED",
@@ -1259,9 +1236,9 @@ xfs_dqtest_cmp2(
err++;
}
}
- if (INT_GET(dqp->q_core.d_ino_softlimit, ARCH_CONVERT) &&
- INT_GET(dqp->q_core.d_icount, ARCH_CONVERT) >=
- INT_GET(dqp->q_core.d_ino_softlimit, ARCH_CONVERT)) {
+ if (dqp->q_core.d_ino_softlimit &&
+ be64_to_cpu(dqp->q_core.d_icount) >=
+ be64_to_cpu(dqp->q_core.d_ino_softlimit)) {
if (!dqp->q_core.d_itimer && dqp->q_core.d_id) {
cmn_err(CE_DEBUG,
"%d [%s] [0x%p] INO TIMER NOT STARTED",
diff --git a/fs/xfs/quota/xfs_quota_priv.h b/fs/xfs/quota/xfs_quota_priv.h
index bf413e70ec07..7a9f3beb818c 100644
--- a/fs/xfs/quota/xfs_quota_priv.h
+++ b/fs/xfs/quota/xfs_quota_priv.h
@@ -1,33 +1,19 @@
/*
- * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2003 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __XFS_QUOTA_PRIV_H__
#define __XFS_QUOTA_PRIV_H__
diff --git a/fs/xfs/quota/xfs_trans_dquot.c b/fs/xfs/quota/xfs_trans_dquot.c
index 3b99daf8a640..3290975d31f7 100644
--- a/fs/xfs/quota/xfs_trans_dquot.c
+++ b/fs/xfs/quota/xfs_trans_dquot.c
@@ -1,39 +1,25 @@
/*
- * Copyright (c) 2000-2002 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2002 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-
#include "xfs.h"
#include "xfs_fs.h"
-#include "xfs_inum.h"
+#include "xfs_bit.h"
#include "xfs_log.h"
+#include "xfs_inum.h"
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
@@ -43,21 +29,20 @@
#include "xfs_dmapi.h"
#include "xfs_quota.h"
#include "xfs_mount.h"
-#include "xfs_alloc_btree.h"
#include "xfs_bmap_btree.h"
+#include "xfs_alloc_btree.h"
#include "xfs_ialloc_btree.h"
-#include "xfs_btree.h"
-#include "xfs_ialloc.h"
#include "xfs_attr_sf.h"
#include "xfs_dir_sf.h"
#include "xfs_dir2_sf.h"
#include "xfs_dinode.h"
#include "xfs_inode.h"
+#include "xfs_ialloc.h"
+#include "xfs_itable.h"
+#include "xfs_btree.h"
#include "xfs_bmap.h"
-#include "xfs_bit.h"
#include "xfs_rtalloc.h"
#include "xfs_error.h"
-#include "xfs_itable.h"
#include "xfs_rw.h"
#include "xfs_acl.h"
#include "xfs_cap.h"
@@ -65,7 +50,6 @@
#include "xfs_attr.h"
#include "xfs_buf_item.h"
#include "xfs_trans_priv.h"
-
#include "xfs_qm.h"
STATIC void xfs_trans_alloc_dqinfo(xfs_trans_t *);
@@ -429,25 +413,25 @@ xfs_trans_apply_dquot_deltas(
qtrx->qt_delrtb_delta;
#ifdef QUOTADEBUG
if (totalbdelta < 0)
- ASSERT(INT_GET(d->d_bcount, ARCH_CONVERT) >=
+ ASSERT(be64_to_cpu(d->d_bcount) >=
(xfs_qcnt_t) -totalbdelta);
if (totalrtbdelta < 0)
- ASSERT(INT_GET(d->d_rtbcount, ARCH_CONVERT) >=
+ ASSERT(be64_to_cpu(d->d_rtbcount) >=
(xfs_qcnt_t) -totalrtbdelta);
if (qtrx->qt_icount_delta < 0)
- ASSERT(INT_GET(d->d_icount, ARCH_CONVERT) >=
+ ASSERT(be64_to_cpu(d->d_icount) >=
(xfs_qcnt_t) -qtrx->qt_icount_delta);
#endif
if (totalbdelta)
- INT_MOD(d->d_bcount, ARCH_CONVERT, (xfs_qcnt_t)totalbdelta);
+ be64_add(&d->d_bcount, (xfs_qcnt_t)totalbdelta);
if (qtrx->qt_icount_delta)
- INT_MOD(d->d_icount, ARCH_CONVERT, (xfs_qcnt_t)qtrx->qt_icount_delta);
+ be64_add(&d->d_icount, (xfs_qcnt_t)qtrx->qt_icount_delta);
if (totalrtbdelta)
- INT_MOD(d->d_rtbcount, ARCH_CONVERT, (xfs_qcnt_t)totalrtbdelta);
+ be64_add(&d->d_rtbcount, (xfs_qcnt_t)totalrtbdelta);
/*
* Get any default limits in use.
@@ -531,11 +515,11 @@ xfs_trans_apply_dquot_deltas(
}
ASSERT(dqp->q_res_bcount >=
- INT_GET(dqp->q_core.d_bcount, ARCH_CONVERT));
+ be64_to_cpu(dqp->q_core.d_bcount));
ASSERT(dqp->q_res_icount >=
- INT_GET(dqp->q_core.d_icount, ARCH_CONVERT));
+ be64_to_cpu(dqp->q_core.d_icount));
ASSERT(dqp->q_res_rtbcount >=
- INT_GET(dqp->q_core.d_rtbcount, ARCH_CONVERT));
+ be64_to_cpu(dqp->q_core.d_rtbcount));
}
/*
* Do the group quotas next
@@ -642,26 +626,26 @@ xfs_trans_dqresv(
}
ASSERT(XFS_DQ_IS_LOCKED(dqp));
if (flags & XFS_TRANS_DQ_RES_BLKS) {
- hardlimit = INT_GET(dqp->q_core.d_blk_hardlimit, ARCH_CONVERT);
+ hardlimit = be64_to_cpu(dqp->q_core.d_blk_hardlimit);
if (!hardlimit)
hardlimit = q->qi_bhardlimit;
- softlimit = INT_GET(dqp->q_core.d_blk_softlimit, ARCH_CONVERT);
+ softlimit = be64_to_cpu(dqp->q_core.d_blk_softlimit);
if (!softlimit)
softlimit = q->qi_bsoftlimit;
- timer = INT_GET(dqp->q_core.d_btimer, ARCH_CONVERT);
- warns = INT_GET(dqp->q_core.d_bwarns, ARCH_CONVERT);
+ timer = be32_to_cpu(dqp->q_core.d_btimer);
+ warns = be16_to_cpu(dqp->q_core.d_bwarns);
warnlimit = XFS_QI_BWARNLIMIT(dqp->q_mount);
resbcountp = &dqp->q_res_bcount;
} else {
ASSERT(flags & XFS_TRANS_DQ_RES_RTBLKS);
- hardlimit = INT_GET(dqp->q_core.d_rtb_hardlimit, ARCH_CONVERT);
+ hardlimit = be64_to_cpu(dqp->q_core.d_rtb_hardlimit);
if (!hardlimit)
hardlimit = q->qi_rtbhardlimit;
- softlimit = INT_GET(dqp->q_core.d_rtb_softlimit, ARCH_CONVERT);
+ softlimit = be64_to_cpu(dqp->q_core.d_rtb_softlimit);
if (!softlimit)
softlimit = q->qi_rtbsoftlimit;
- timer = INT_GET(dqp->q_core.d_rtbtimer, ARCH_CONVERT);
- warns = INT_GET(dqp->q_core.d_rtbwarns, ARCH_CONVERT);
+ timer = be32_to_cpu(dqp->q_core.d_rtbtimer);
+ warns = be16_to_cpu(dqp->q_core.d_rtbwarns);
warnlimit = XFS_QI_RTBWARNLIMIT(dqp->q_mount);
resbcountp = &dqp->q_res_rtbcount;
}
@@ -700,16 +684,14 @@ xfs_trans_dqresv(
}
}
if (ninos > 0) {
- count = INT_GET(dqp->q_core.d_icount, ARCH_CONVERT);
- timer = INT_GET(dqp->q_core.d_itimer, ARCH_CONVERT);
- warns = INT_GET(dqp->q_core.d_iwarns, ARCH_CONVERT);
+ count = be64_to_cpu(dqp->q_core.d_icount);
+ timer = be32_to_cpu(dqp->q_core.d_itimer);
+ warns = be16_to_cpu(dqp->q_core.d_iwarns);
warnlimit = XFS_QI_IWARNLIMIT(dqp->q_mount);
- hardlimit = INT_GET(dqp->q_core.d_ino_hardlimit,
- ARCH_CONVERT);
+ hardlimit = be64_to_cpu(dqp->q_core.d_ino_hardlimit);
if (!hardlimit)
hardlimit = q->qi_ihardlimit;
- softlimit = INT_GET(dqp->q_core.d_ino_softlimit,
- ARCH_CONVERT);
+ softlimit = be64_to_cpu(dqp->q_core.d_ino_softlimit);
if (!softlimit)
softlimit = q->qi_isoftlimit;
if (hardlimit > 0ULL && count >= hardlimit) {
@@ -756,9 +738,9 @@ xfs_trans_dqresv(
XFS_TRANS_DQ_RES_INOS,
ninos);
}
- ASSERT(dqp->q_res_bcount >= INT_GET(dqp->q_core.d_bcount, ARCH_CONVERT));
- ASSERT(dqp->q_res_rtbcount >= INT_GET(dqp->q_core.d_rtbcount, ARCH_CONVERT));
- ASSERT(dqp->q_res_icount >= INT_GET(dqp->q_core.d_icount, ARCH_CONVERT));
+ ASSERT(dqp->q_res_bcount >= be64_to_cpu(dqp->q_core.d_bcount));
+ ASSERT(dqp->q_res_rtbcount >= be64_to_cpu(dqp->q_core.d_rtbcount));
+ ASSERT(dqp->q_res_icount >= be64_to_cpu(dqp->q_core.d_icount));
error_return:
if (! (flags & XFS_QMOPT_DQLOCK)) {
diff --git a/fs/xfs/support/debug.c b/fs/xfs/support/debug.c
index 4e1a5ec22fa3..bb6dc91ea261 100644
--- a/fs/xfs/support/debug.c
+++ b/fs/xfs/support/debug.c
@@ -1,38 +1,22 @@
/*
- * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-
#include "debug.h"
#include "spin.h"
-
#include <asm/page.h>
#include <linux/sched.h>
#include <linux/kernel.h>
diff --git a/fs/xfs/support/debug.h b/fs/xfs/support/debug.h
index c5b9365a7e2a..aff558664c32 100644
--- a/fs/xfs/support/debug.h
+++ b/fs/xfs/support/debug.h
@@ -1,33 +1,19 @@
/*
- * Copyright (c) 2000-2004 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __XFS_SUPPORT_DEBUG_H__
#define __XFS_SUPPORT_DEBUG_H__
@@ -41,9 +27,10 @@
#define CE_ALERT 1 /* alert */
#define CE_PANIC 0 /* panic */
-extern void icmn_err(int, char *, va_list);
-/* PRINTFLIKE2 */
-extern void cmn_err(int, char *, ...);
+extern void icmn_err(int, char *, va_list)
+ __attribute__ ((format (printf, 2, 0)));
+extern void cmn_err(int, char *, ...)
+ __attribute__ ((format (printf, 2, 3)));
#ifndef STATIC
# define STATIC static
diff --git a/fs/xfs/support/ktrace.c b/fs/xfs/support/ktrace.c
index fa8394f9437d..841aa4c15b8a 100644
--- a/fs/xfs/support/ktrace.c
+++ b/fs/xfs/support/ktrace.c
@@ -1,35 +1,20 @@
/*
- * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-
#include <xfs.h>
static kmem_zone_t *ktrace_hdr_zone;
@@ -65,7 +50,7 @@ ktrace_uninit(void)
* number of entries.
*/
ktrace_t *
-ktrace_alloc(int nentries, int sleep)
+ktrace_alloc(int nentries, unsigned int __nocast sleep)
{
ktrace_t *ktp;
ktrace_entry_t *ktep;
diff --git a/fs/xfs/support/ktrace.h b/fs/xfs/support/ktrace.h
index 92d1a1a5d04b..0d73216287c0 100644
--- a/fs/xfs/support/ktrace.h
+++ b/fs/xfs/support/ktrace.h
@@ -1,33 +1,19 @@
/*
- * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __XFS_SUPPORT_KTRACE_H__
#define __XFS_SUPPORT_KTRACE_H__
@@ -66,7 +52,7 @@ typedef struct ktrace_snap {
extern void ktrace_init(int zentries);
extern void ktrace_uninit(void);
-extern ktrace_t *ktrace_alloc(int, int);
+extern ktrace_t *ktrace_alloc(int, unsigned int __nocast);
extern void ktrace_free(ktrace_t *);
extern void ktrace_enter(
diff --git a/fs/xfs/support/move.c b/fs/xfs/support/move.c
index 15b5194f16b2..caefa17b80fe 100644
--- a/fs/xfs/support/move.c
+++ b/fs/xfs/support/move.c
@@ -1,35 +1,20 @@
/*
- * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-
#include <xfs.h>
/* Read from kernel buffer at src to user/kernel buffer defined
diff --git a/fs/xfs/support/move.h b/fs/xfs/support/move.h
index 3d406dc1c89e..97a2498d2da3 100644
--- a/fs/xfs/support/move.h
+++ b/fs/xfs/support/move.h
@@ -1,34 +1,20 @@
/*
- * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
- *
* Portions Copyright (c) 1982, 1986, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
diff --git a/fs/xfs/support/qsort.c b/fs/xfs/support/qsort.c
deleted file mode 100644
index 1ec824140cf7..000000000000
--- a/fs/xfs/support/qsort.c
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * Copyright (c) 1992, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <linux/kernel.h>
-#include <linux/string.h>
-
-/*
- * Qsort routine from Bentley & McIlroy's "Engineering a Sort Function".
- */
-#define swapcode(TYPE, parmi, parmj, n) { \
- long i = (n) / sizeof (TYPE); \
- register TYPE *pi = (TYPE *) (parmi); \
- register TYPE *pj = (TYPE *) (parmj); \
- do { \
- register TYPE t = *pi; \
- *pi++ = *pj; \
- *pj++ = t; \
- } while (--i > 0); \
-}
-
-#define SWAPINIT(a, es) swaptype = ((char *)a - (char *)0) % sizeof(long) || \
- es % sizeof(long) ? 2 : es == sizeof(long)? 0 : 1;
-
-static __inline void
-swapfunc(char *a, char *b, int n, int swaptype)
-{
- if (swaptype <= 1)
- swapcode(long, a, b, n)
- else
- swapcode(char, a, b, n)
-}
-
-#define swap(a, b) \
- if (swaptype == 0) { \
- long t = *(long *)(a); \
- *(long *)(a) = *(long *)(b); \
- *(long *)(b) = t; \
- } else \
- swapfunc(a, b, es, swaptype)
-
-#define vecswap(a, b, n) if ((n) > 0) swapfunc(a, b, n, swaptype)
-
-static __inline char *
-med3(char *a, char *b, char *c, int (*cmp)(const void *, const void *))
-{
- return cmp(a, b) < 0 ?
- (cmp(b, c) < 0 ? b : (cmp(a, c) < 0 ? c : a ))
- :(cmp(b, c) > 0 ? b : (cmp(a, c) < 0 ? a : c ));
-}
-
-void
-qsort(void *aa, size_t n, size_t es, int (*cmp)(const void *, const void *))
-{
- char *pa, *pb, *pc, *pd, *pl, *pm, *pn;
- int d, r, swaptype, swap_cnt;
- register char *a = aa;
-
-loop: SWAPINIT(a, es);
- swap_cnt = 0;
- if (n < 7) {
- for (pm = (char *)a + es; pm < (char *) a + n * es; pm += es)
- for (pl = pm; pl > (char *) a && cmp(pl - es, pl) > 0;
- pl -= es)
- swap(pl, pl - es);
- return;
- }
- pm = (char *)a + (n / 2) * es;
- if (n > 7) {
- pl = (char *)a;
- pn = (char *)a + (n - 1) * es;
- if (n > 40) {
- d = (n / 8) * es;
- pl = med3(pl, pl + d, pl + 2 * d, cmp);
- pm = med3(pm - d, pm, pm + d, cmp);
- pn = med3(pn - 2 * d, pn - d, pn, cmp);
- }
- pm = med3(pl, pm, pn, cmp);
- }
- swap(a, pm);
- pa = pb = (char *)a + es;
-
- pc = pd = (char *)a + (n - 1) * es;
- for (;;) {
- while (pb <= pc && (r = cmp(pb, a)) <= 0) {
- if (r == 0) {
- swap_cnt = 1;
- swap(pa, pb);
- pa += es;
- }
- pb += es;
- }
- while (pb <= pc && (r = cmp(pc, a)) >= 0) {
- if (r == 0) {
- swap_cnt = 1;
- swap(pc, pd);
- pd -= es;
- }
- pc -= es;
- }
- if (pb > pc)
- break;
- swap(pb, pc);
- swap_cnt = 1;
- pb += es;
- pc -= es;
- }
- if (swap_cnt == 0) { /* Switch to insertion sort */
- for (pm = (char *) a + es; pm < (char *) a + n * es; pm += es)
- for (pl = pm; pl > (char *) a && cmp(pl - es, pl) > 0;
- pl -= es)
- swap(pl, pl - es);
- return;
- }
-
- pn = (char *)a + n * es;
- r = min(pa - (char *)a, pb - pa);
- vecswap(a, pb - r, r);
- r = min((long)(pd - pc), (long)(pn - pd - es));
- vecswap(pb, pn - r, r);
- if ((r = pb - pa) > es)
- qsort(a, r / es, es, cmp);
- if ((r = pd - pc) > es) {
- /* Iterate rather than recurse to save stack space */
- a = pn - r;
- n = r / es;
- goto loop;
- }
-/* qsort(pn - r, r / es, es, cmp);*/
-}
diff --git a/fs/xfs/support/qsort.h b/fs/xfs/support/qsort.h
deleted file mode 100644
index 94263106d716..000000000000
--- a/fs/xfs/support/qsort.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (c) 2000-2002 Silicon Graphics, Inc. All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
- */
-
-#ifndef QSORT_H
-#define QSORT_H
-
-extern void qsort (void *const pbase,
- size_t total_elems,
- size_t size,
- int (*cmp)(const void *, const void *));
-
-#endif
diff --git a/fs/xfs/support/uuid.c b/fs/xfs/support/uuid.c
index 81f40cfcb267..70ce40914c8a 100644
--- a/fs/xfs/support/uuid.c
+++ b/fs/xfs/support/uuid.c
@@ -1,35 +1,20 @@
/*
- * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-
#include <xfs.h>
static mutex_t uuid_monitor;
diff --git a/fs/xfs/support/uuid.h b/fs/xfs/support/uuid.h
index 5220ea58ba2b..b6f5922199ba 100644
--- a/fs/xfs/support/uuid.h
+++ b/fs/xfs/support/uuid.h
@@ -1,33 +1,19 @@
/*
- * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __XFS_SUPPORT_UUID_H__
#define __XFS_SUPPORT_UUID_H__
@@ -36,13 +22,13 @@ typedef struct {
unsigned char __u_bits[16];
} uuid_t;
-void uuid_init(void);
-void uuid_create_nil(uuid_t *uuid);
-int uuid_is_nil(uuid_t *uuid);
-int uuid_equal(uuid_t *uuid1, uuid_t *uuid2);
-void uuid_getnodeuniq(uuid_t *uuid, int fsid [2]);
-__uint64_t uuid_hash64(uuid_t *uuid);
-int uuid_table_insert(uuid_t *uuid);
-void uuid_table_remove(uuid_t *uuid);
+extern void uuid_init(void);
+extern void uuid_create_nil(uuid_t *uuid);
+extern int uuid_is_nil(uuid_t *uuid);
+extern int uuid_equal(uuid_t *uuid1, uuid_t *uuid2);
+extern void uuid_getnodeuniq(uuid_t *uuid, int fsid [2]);
+extern __uint64_t uuid_hash64(uuid_t *uuid);
+extern int uuid_table_insert(uuid_t *uuid);
+extern void uuid_table_remove(uuid_t *uuid);
#endif /* __XFS_SUPPORT_UUID_H__ */
diff --git a/fs/xfs/xfs.h b/fs/xfs/xfs.h
index 7e276dcaf4dc..1a48dbb902a7 100644
--- a/fs/xfs/xfs.h
+++ b/fs/xfs/xfs.h
@@ -1,40 +1,21 @@
/*
- * Copyright (c) 2000-2004 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __XFS_H__
#define __XFS_H__
-
#include <linux-2.6/xfs_linux.h>
-
-#include <xfs_fs.h>
-#include <xfs_macros.h>
-
#endif /* __XFS_H__ */
diff --git a/fs/xfs/xfs_acl.c b/fs/xfs/xfs_acl.c
index 92fd1d67f878..cc9c91b9e771 100644
--- a/fs/xfs/xfs_acl.c
+++ b/fs/xfs/xfs_acl.c
@@ -1,49 +1,37 @@
/*
- * Copyright (c) 2001-2002 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2001-2002,2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-
#include "xfs.h"
-
+#include "xfs_fs.h"
+#include "xfs_types.h"
+#include "xfs_bit.h"
#include "xfs_inum.h"
+#include "xfs_ag.h"
#include "xfs_dir.h"
#include "xfs_dir2.h"
-#include "xfs_alloc_btree.h"
#include "xfs_bmap_btree.h"
+#include "xfs_alloc_btree.h"
#include "xfs_ialloc_btree.h"
-#include "xfs_btree.h"
-#include "xfs_attr_sf.h"
#include "xfs_dir_sf.h"
#include "xfs_dir2_sf.h"
+#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
#include "xfs_inode.h"
+#include "xfs_btree.h"
#include "xfs_acl.h"
#include "xfs_mac.h"
#include "xfs_attr.h"
@@ -155,7 +143,7 @@ posix_acl_xattr_to_xfs(
}
/*
- * Comparison function called from qsort().
+ * Comparison function called from xfs_sort().
* Primary key is ae_tag, secondary key is ae_id.
*/
STATIC int
@@ -189,8 +177,8 @@ posix_acl_xfs_to_xattr(
return -ERANGE;
/* Need to sort src XFS ACL by <ae_tag,ae_id> */
- qsort(src->acl_entry, src->acl_cnt, sizeof(src->acl_entry[0]),
- xfs_acl_entry_compare);
+ xfs_sort(src->acl_entry, src->acl_cnt, sizeof(src->acl_entry[0]),
+ xfs_acl_entry_compare);
dest->a_version = cpu_to_le32(POSIX_ACL_XATTR_VERSION);
dest_entry = &dest->a_entries[0];
@@ -448,6 +436,7 @@ xfs_acl_access(
int seen_userobj = 0;
matched.ae_tag = 0; /* Invalid type */
+ matched.ae_perm = 0;
md >>= 6; /* Normalize the bits for comparison */
for (i = 0; i < fap->acl_cnt; i++) {
diff --git a/fs/xfs/xfs_acl.h b/fs/xfs/xfs_acl.h
index 0363eb46d357..f9315bc960cb 100644
--- a/fs/xfs/xfs_acl.h
+++ b/fs/xfs/xfs_acl.h
@@ -1,33 +1,19 @@
/*
- * Copyright (c) 2001-2004 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2001-2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __XFS_ACL_H__
#define __XFS_ACL_H__
diff --git a/fs/xfs/xfs_ag.h b/fs/xfs/xfs_ag.h
index 96b70f7fba39..a96e2ffce0cc 100644
--- a/fs/xfs/xfs_ag.h
+++ b/fs/xfs/xfs_ag.h
@@ -1,33 +1,19 @@
/*
- * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __XFS_AG_H__
#define __XFS_AG_H__
@@ -46,18 +32,9 @@ struct xfs_trans;
#define XFS_AGI_MAGIC 0x58414749 /* 'XAGI' */
#define XFS_AGF_VERSION 1
#define XFS_AGI_VERSION 1
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_AGF_GOOD_VERSION)
-int xfs_agf_good_version(unsigned v);
-#define XFS_AGF_GOOD_VERSION(v) xfs_agf_good_version(v)
-#else
-#define XFS_AGF_GOOD_VERSION(v) ((v) == XFS_AGF_VERSION)
-#endif
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_AGI_GOOD_VERSION)
-int xfs_agi_good_version(unsigned v);
-#define XFS_AGI_GOOD_VERSION(v) xfs_agi_good_version(v)
-#else
-#define XFS_AGI_GOOD_VERSION(v) ((v) == XFS_AGI_VERSION)
-#endif
+
+#define XFS_AGF_GOOD_VERSION(v) ((v) == XFS_AGF_VERSION)
+#define XFS_AGI_GOOD_VERSION(v) ((v) == XFS_AGI_VERSION)
/*
* Btree number 0 is bno, 1 is cnt. This value gives the size of the
@@ -71,27 +48,26 @@ int xfs_agi_good_version(unsigned v);
* are > 64k, our value cannot be confused for an EFS superblock's.
*/
-typedef struct xfs_agf
-{
+typedef struct xfs_agf {
/*
* Common allocation group header information
*/
- __uint32_t agf_magicnum; /* magic number == XFS_AGF_MAGIC */
- __uint32_t agf_versionnum; /* header version == XFS_AGF_VERSION */
- xfs_agnumber_t agf_seqno; /* sequence # starting from 0 */
- xfs_agblock_t agf_length; /* size in blocks of a.g. */
+ __be32 agf_magicnum; /* magic number == XFS_AGF_MAGIC */
+ __be32 agf_versionnum; /* header version == XFS_AGF_VERSION */
+ __be32 agf_seqno; /* sequence # starting from 0 */
+ __be32 agf_length; /* size in blocks of a.g. */
/*
* Freespace information
*/
- xfs_agblock_t agf_roots[XFS_BTNUM_AGF]; /* root blocks */
- __uint32_t agf_spare0; /* spare field */
- __uint32_t agf_levels[XFS_BTNUM_AGF]; /* btree levels */
- __uint32_t agf_spare1; /* spare field */
- __uint32_t agf_flfirst; /* first freelist block's index */
- __uint32_t agf_fllast; /* last freelist block's index */
- __uint32_t agf_flcount; /* count of blocks in freelist */
- xfs_extlen_t agf_freeblks; /* total free blocks */
- xfs_extlen_t agf_longest; /* longest free space */
+ __be32 agf_roots[XFS_BTNUM_AGF]; /* root blocks */
+ __be32 agf_spare0; /* spare field */
+ __be32 agf_levels[XFS_BTNUM_AGF]; /* btree levels */
+ __be32 agf_spare1; /* spare field */
+ __be32 agf_flfirst; /* first freelist block's index */
+ __be32 agf_fllast; /* last freelist block's index */
+ __be32 agf_flcount; /* count of blocks in freelist */
+ __be32 agf_freeblks; /* total free blocks */
+ __be32 agf_longest; /* longest free space */
} xfs_agf_t;
#define XFS_AGF_MAGICNUM 0x00000001
@@ -110,43 +86,39 @@ typedef struct xfs_agf
/* disk block (xfs_daddr_t) in the AG */
#define XFS_AGF_DADDR(mp) ((xfs_daddr_t)(1 << (mp)->m_sectbb_log))
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_AGF_BLOCK)
-xfs_agblock_t xfs_agf_block(struct xfs_mount *mp);
-#define XFS_AGF_BLOCK(mp) xfs_agf_block(mp)
-#else
-#define XFS_AGF_BLOCK(mp) XFS_HDR_BLOCK(mp, XFS_AGF_DADDR(mp))
-#endif
+#define XFS_AGF_BLOCK(mp) XFS_HDR_BLOCK(mp, XFS_AGF_DADDR(mp))
+#define XFS_BUF_TO_AGF(bp) ((xfs_agf_t *)XFS_BUF_PTR(bp))
+
/*
* Size of the unlinked inode hash table in the agi.
*/
#define XFS_AGI_UNLINKED_BUCKETS 64
-typedef struct xfs_agi
-{
+typedef struct xfs_agi {
/*
* Common allocation group header information
*/
- __uint32_t agi_magicnum; /* magic number == XFS_AGI_MAGIC */
- __uint32_t agi_versionnum; /* header version == XFS_AGI_VERSION */
- xfs_agnumber_t agi_seqno; /* sequence # starting from 0 */
- xfs_agblock_t agi_length; /* size in blocks of a.g. */
+ __be32 agi_magicnum; /* magic number == XFS_AGI_MAGIC */
+ __be32 agi_versionnum; /* header version == XFS_AGI_VERSION */
+ __be32 agi_seqno; /* sequence # starting from 0 */
+ __be32 agi_length; /* size in blocks of a.g. */
/*
* Inode information
* Inodes are mapped by interpreting the inode number, so no
* mapping data is needed here.
*/
- xfs_agino_t agi_count; /* count of allocated inodes */
- xfs_agblock_t agi_root; /* root of inode btree */
- __uint32_t agi_level; /* levels in inode btree */
- xfs_agino_t agi_freecount; /* number of free inodes */
- xfs_agino_t agi_newino; /* new inode just allocated */
- xfs_agino_t agi_dirino; /* last directory inode chunk */
+ __be32 agi_count; /* count of allocated inodes */
+ __be32 agi_root; /* root of inode btree */
+ __be32 agi_level; /* levels in inode btree */
+ __be32 agi_freecount; /* number of free inodes */
+ __be32 agi_newino; /* new inode just allocated */
+ __be32 agi_dirino; /* last directory inode chunk */
/*
* Hash table of inodes which have been unlinked but are
* still being referenced.
*/
- xfs_agino_t agi_unlinked[XFS_AGI_UNLINKED_BUCKETS];
+ __be32 agi_unlinked[XFS_AGI_UNLINKED_BUCKETS];
} xfs_agi_t;
#define XFS_AGI_MAGICNUM 0x00000001
@@ -165,25 +137,17 @@ typedef struct xfs_agi
/* disk block (xfs_daddr_t) in the AG */
#define XFS_AGI_DADDR(mp) ((xfs_daddr_t)(2 << (mp)->m_sectbb_log))
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_AGI_BLOCK)
-xfs_agblock_t xfs_agi_block(struct xfs_mount *mp);
-#define XFS_AGI_BLOCK(mp) xfs_agi_block(mp)
-#else
-#define XFS_AGI_BLOCK(mp) XFS_HDR_BLOCK(mp, XFS_AGI_DADDR(mp))
-#endif
+#define XFS_AGI_BLOCK(mp) XFS_HDR_BLOCK(mp, XFS_AGI_DADDR(mp))
+#define XFS_BUF_TO_AGI(bp) ((xfs_agi_t *)XFS_BUF_PTR(bp))
/*
* The third a.g. block contains the a.g. freelist, an array
* of block pointers to blocks owned by the allocation btree code.
*/
#define XFS_AGFL_DADDR(mp) ((xfs_daddr_t)(3 << (mp)->m_sectbb_log))
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_AGFL_BLOCK)
-xfs_agblock_t xfs_agfl_block(struct xfs_mount *mp);
-#define XFS_AGFL_BLOCK(mp) xfs_agfl_block(mp)
-#else
-#define XFS_AGFL_BLOCK(mp) XFS_HDR_BLOCK(mp, XFS_AGFL_DADDR(mp))
-#endif
+#define XFS_AGFL_BLOCK(mp) XFS_HDR_BLOCK(mp, XFS_AGFL_DADDR(mp))
#define XFS_AGFL_SIZE(mp) ((mp)->m_sb.sb_sectsize / sizeof(xfs_agblock_t))
+#define XFS_BUF_TO_AGFL(bp) ((xfs_agfl_t *)XFS_BUF_PTR(bp))
typedef struct xfs_agfl {
xfs_agblock_t agfl_bno[1]; /* actually XFS_AGFL_SIZE(mp) */
@@ -230,116 +194,38 @@ typedef struct xfs_perag
xfs_perag_busy_t *pagb_list; /* unstable blocks */
} xfs_perag_t;
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_AG_MAXLEVELS)
-int xfs_ag_maxlevels(struct xfs_mount *mp);
-#define XFS_AG_MAXLEVELS(mp) xfs_ag_maxlevels(mp)
-#else
-#define XFS_AG_MAXLEVELS(mp) ((mp)->m_ag_maxlevels)
-#endif
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_MIN_FREELIST)
-int xfs_min_freelist(xfs_agf_t *a, struct xfs_mount *mp);
-#define XFS_MIN_FREELIST(a,mp) xfs_min_freelist(a,mp)
-#else
-#define XFS_MIN_FREELIST(a,mp) \
- XFS_MIN_FREELIST_RAW( \
- INT_GET((a)->agf_levels[XFS_BTNUM_BNOi], ARCH_CONVERT), \
- INT_GET((a)->agf_levels[XFS_BTNUM_CNTi], ARCH_CONVERT), mp)
-#endif
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_MIN_FREELIST_PAG)
-int xfs_min_freelist_pag(xfs_perag_t *pag, struct xfs_mount *mp);
-#define XFS_MIN_FREELIST_PAG(pag,mp) xfs_min_freelist_pag(pag,mp)
-#else
-#define XFS_MIN_FREELIST_PAG(pag,mp) \
- XFS_MIN_FREELIST_RAW((uint_t)(pag)->pagf_levels[XFS_BTNUM_BNOi], \
- (uint_t)(pag)->pagf_levels[XFS_BTNUM_CNTi], mp)
-#endif
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_MIN_FREELIST_RAW)
-int xfs_min_freelist_raw(int bl, int cl, struct xfs_mount *mp);
-#define XFS_MIN_FREELIST_RAW(bl,cl,mp) xfs_min_freelist_raw(bl,cl,mp)
-#else
+#define XFS_AG_MAXLEVELS(mp) ((mp)->m_ag_maxlevels)
#define XFS_MIN_FREELIST_RAW(bl,cl,mp) \
- (MIN(bl + 1, XFS_AG_MAXLEVELS(mp)) + \
- MIN(cl + 1, XFS_AG_MAXLEVELS(mp)))
-#endif
+ (MIN(bl + 1, XFS_AG_MAXLEVELS(mp)) + MIN(cl + 1, XFS_AG_MAXLEVELS(mp)))
+#define XFS_MIN_FREELIST(a,mp) \
+ (XFS_MIN_FREELIST_RAW( \
+ be32_to_cpu((a)->agf_levels[XFS_BTNUM_BNOi]), \
+ be32_to_cpu((a)->agf_levels[XFS_BTNUM_CNTi]), mp))
+#define XFS_MIN_FREELIST_PAG(pag,mp) \
+ (XFS_MIN_FREELIST_RAW( \
+ (uint_t)(pag)->pagf_levels[XFS_BTNUM_BNOi], \
+ (uint_t)(pag)->pagf_levels[XFS_BTNUM_CNTi], mp))
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_AGB_TO_FSB)
-xfs_fsblock_t xfs_agb_to_fsb(struct xfs_mount *mp, xfs_agnumber_t agno,
- xfs_agblock_t agbno);
-#define XFS_AGB_TO_FSB(mp,agno,agbno) xfs_agb_to_fsb(mp,agno,agbno)
-#else
-#define XFS_AGB_TO_FSB(mp,agno,agbno) \
+#define XFS_AGB_TO_FSB(mp,agno,agbno) \
(((xfs_fsblock_t)(agno) << (mp)->m_sb.sb_agblklog) | (agbno))
-#endif
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_FSB_TO_AGNO)
-xfs_agnumber_t xfs_fsb_to_agno(struct xfs_mount *mp, xfs_fsblock_t fsbno);
-#define XFS_FSB_TO_AGNO(mp,fsbno) xfs_fsb_to_agno(mp,fsbno)
-#else
-#define XFS_FSB_TO_AGNO(mp,fsbno) \
+#define XFS_FSB_TO_AGNO(mp,fsbno) \
((xfs_agnumber_t)((fsbno) >> (mp)->m_sb.sb_agblklog))
-#endif
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_FSB_TO_AGBNO)
-xfs_agblock_t xfs_fsb_to_agbno(struct xfs_mount *mp, xfs_fsblock_t fsbno);
-#define XFS_FSB_TO_AGBNO(mp,fsbno) xfs_fsb_to_agbno(mp,fsbno)
-#else
-#define XFS_FSB_TO_AGBNO(mp,fsbno) \
+#define XFS_FSB_TO_AGBNO(mp,fsbno) \
((xfs_agblock_t)((fsbno) & XFS_MASK32LO((mp)->m_sb.sb_agblklog)))
-#endif
-
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_AGB_TO_DADDR)
-xfs_daddr_t xfs_agb_to_daddr(struct xfs_mount *mp, xfs_agnumber_t agno,
- xfs_agblock_t agbno);
-#define XFS_AGB_TO_DADDR(mp,agno,agbno) xfs_agb_to_daddr(mp,agno,agbno)
-#else
-#define XFS_AGB_TO_DADDR(mp,agno,agbno) \
- ((xfs_daddr_t)(XFS_FSB_TO_BB(mp, \
- (xfs_fsblock_t)(agno) * (mp)->m_sb.sb_agblocks + (agbno))))
-#endif
-/*
- * XFS_DADDR_TO_AGNO and XFS_DADDR_TO_AGBNO moved to xfs_mount.h
- * to avoid header file ordering change
- */
-
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_AG_DADDR)
-xfs_daddr_t xfs_ag_daddr(struct xfs_mount *mp, xfs_agnumber_t agno,
- xfs_daddr_t d);
-#define XFS_AG_DADDR(mp,agno,d) xfs_ag_daddr(mp,agno,d)
-#else
-#define XFS_AG_DADDR(mp,agno,d) (XFS_AGB_TO_DADDR(mp, agno, 0) + (d))
-#endif
-
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_BUF_TO_AGF)
-xfs_agf_t *xfs_buf_to_agf(struct xfs_buf *bp);
-#define XFS_BUF_TO_AGF(bp) xfs_buf_to_agf(bp)
-#else
-#define XFS_BUF_TO_AGF(bp) ((xfs_agf_t *)XFS_BUF_PTR(bp))
-#endif
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_BUF_TO_AGI)
-xfs_agi_t *xfs_buf_to_agi(struct xfs_buf *bp);
-#define XFS_BUF_TO_AGI(bp) xfs_buf_to_agi(bp)
-#else
-#define XFS_BUF_TO_AGI(bp) ((xfs_agi_t *)XFS_BUF_PTR(bp))
-#endif
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_BUF_TO_AGFL)
-xfs_agfl_t *xfs_buf_to_agfl(struct xfs_buf *bp);
-#define XFS_BUF_TO_AGFL(bp) xfs_buf_to_agfl(bp)
-#else
-#define XFS_BUF_TO_AGFL(bp) ((xfs_agfl_t *)XFS_BUF_PTR(bp))
-#endif
+#define XFS_AGB_TO_DADDR(mp,agno,agbno) \
+ ((xfs_daddr_t)XFS_FSB_TO_BB(mp, \
+ (xfs_fsblock_t)(agno) * (mp)->m_sb.sb_agblocks + (agbno)))
+#define XFS_AG_DADDR(mp,agno,d) (XFS_AGB_TO_DADDR(mp, agno, 0) + (d))
/*
* For checking for bad ranges of xfs_daddr_t's, covering multiple
* allocation groups or a single xfs_daddr_t that's a superblock copy.
*/
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_AG_CHECK_DADDR)
-void xfs_ag_check_daddr(struct xfs_mount *mp, xfs_daddr_t d, xfs_extlen_t len);
-#define XFS_AG_CHECK_DADDR(mp,d,len) xfs_ag_check_daddr(mp,d,len)
-#else
#define XFS_AG_CHECK_DADDR(mp,d,len) \
((len) == 1 ? \
ASSERT((d) == XFS_SB_DADDR || \
XFS_DADDR_TO_AGBNO(mp, d) != XFS_SB_DADDR) : \
ASSERT(XFS_DADDR_TO_AGNO(mp, d) == \
XFS_DADDR_TO_AGNO(mp, (d) + (len) - 1)))
-#endif
#endif /* __XFS_AG_H__ */
diff --git a/fs/xfs/xfs_alloc.c b/fs/xfs/xfs_alloc.c
index dcfe19703620..f4328e1e2a74 100644
--- a/fs/xfs/xfs_alloc.c
+++ b/fs/xfs/xfs_alloc.c
@@ -1,56 +1,44 @@
/*
- * Copyright (c) 2000-2002 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
- */
-
-/*
- * Free space allocation for XFS.
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "xfs.h"
-#include "xfs_macros.h"
+#include "xfs_fs.h"
#include "xfs_types.h"
-#include "xfs_inum.h"
+#include "xfs_bit.h"
#include "xfs_log.h"
+#include "xfs_inum.h"
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
#include "xfs_dir.h"
+#include "xfs_dir2.h"
#include "xfs_dmapi.h"
#include "xfs_mount.h"
-#include "xfs_alloc_btree.h"
#include "xfs_bmap_btree.h"
+#include "xfs_alloc_btree.h"
#include "xfs_ialloc_btree.h"
+#include "xfs_dir_sf.h"
+#include "xfs_dir2_sf.h"
+#include "xfs_attr_sf.h"
+#include "xfs_dinode.h"
+#include "xfs_inode.h"
#include "xfs_btree.h"
#include "xfs_ialloc.h"
#include "xfs_alloc.h"
-#include "xfs_bit.h"
#include "xfs_error.h"
@@ -243,8 +231,8 @@ xfs_alloc_fix_minleft(
if (args->minleft == 0)
return 1;
agf = XFS_BUF_TO_AGF(args->agbp);
- diff = INT_GET(agf->agf_freeblks, ARCH_CONVERT)
- + INT_GET(agf->agf_flcount, ARCH_CONVERT)
+ diff = be32_to_cpu(agf->agf_freeblks)
+ + be32_to_cpu(agf->agf_flcount)
- args->len - args->minleft;
if (diff >= 0)
return 1;
@@ -319,7 +307,8 @@ xfs_alloc_fixup_trees(
bnoblock = XFS_BUF_TO_ALLOC_BLOCK(bno_cur->bc_bufs[0]);
cntblock = XFS_BUF_TO_ALLOC_BLOCK(cnt_cur->bc_bufs[0]);
XFS_WANT_CORRUPTED_RETURN(
- INT_GET(bnoblock->bb_numrecs, ARCH_CONVERT) == INT_GET(cntblock->bb_numrecs, ARCH_CONVERT));
+ be16_to_cpu(bnoblock->bb_numrecs) ==
+ be16_to_cpu(cntblock->bb_numrecs));
}
}
#endif
@@ -505,21 +494,17 @@ xfs_alloc_trace_modagf(
(void *)str,
(void *)mp,
(void *)(__psint_t)flags,
- (void *)(__psunsigned_t)INT_GET(agf->agf_seqno, ARCH_CONVERT),
- (void *)(__psunsigned_t)INT_GET(agf->agf_length, ARCH_CONVERT),
- (void *)(__psunsigned_t)INT_GET(agf->agf_roots[XFS_BTNUM_BNO],
- ARCH_CONVERT),
- (void *)(__psunsigned_t)INT_GET(agf->agf_roots[XFS_BTNUM_CNT],
- ARCH_CONVERT),
- (void *)(__psunsigned_t)INT_GET(agf->agf_levels[XFS_BTNUM_BNO],
- ARCH_CONVERT),
- (void *)(__psunsigned_t)INT_GET(agf->agf_levels[XFS_BTNUM_CNT],
- ARCH_CONVERT),
- (void *)(__psunsigned_t)INT_GET(agf->agf_flfirst, ARCH_CONVERT),
- (void *)(__psunsigned_t)INT_GET(agf->agf_fllast, ARCH_CONVERT),
- (void *)(__psunsigned_t)INT_GET(agf->agf_flcount, ARCH_CONVERT),
- (void *)(__psunsigned_t)INT_GET(agf->agf_freeblks, ARCH_CONVERT),
- (void *)(__psunsigned_t)INT_GET(agf->agf_longest, ARCH_CONVERT));
+ (void *)(__psunsigned_t)be32_to_cpu(agf->agf_seqno),
+ (void *)(__psunsigned_t)be32_to_cpu(agf->agf_length),
+ (void *)(__psunsigned_t)be32_to_cpu(agf->agf_roots[XFS_BTNUM_BNO]),
+ (void *)(__psunsigned_t)be32_to_cpu(agf->agf_roots[XFS_BTNUM_CNT]),
+ (void *)(__psunsigned_t)be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNO]),
+ (void *)(__psunsigned_t)be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNT]),
+ (void *)(__psunsigned_t)be32_to_cpu(agf->agf_flfirst),
+ (void *)(__psunsigned_t)be32_to_cpu(agf->agf_fllast),
+ (void *)(__psunsigned_t)be32_to_cpu(agf->agf_flcount),
+ (void *)(__psunsigned_t)be32_to_cpu(agf->agf_freeblks),
+ (void *)(__psunsigned_t)be32_to_cpu(agf->agf_longest));
}
STATIC void
@@ -612,12 +597,12 @@ xfs_alloc_ag_vextent(
if (!(args->wasfromfl)) {
agf = XFS_BUF_TO_AGF(args->agbp);
- INT_MOD(agf->agf_freeblks, ARCH_CONVERT, -(args->len));
+ be32_add(&agf->agf_freeblks, -(args->len));
xfs_trans_agblocks_delta(args->tp,
-((long)(args->len)));
args->pag->pagf_freeblks -= args->len;
- ASSERT(INT_GET(agf->agf_freeblks, ARCH_CONVERT)
- <= INT_GET(agf->agf_length, ARCH_CONVERT));
+ ASSERT(be32_to_cpu(agf->agf_freeblks) <=
+ be32_to_cpu(agf->agf_length));
TRACE_MODAGF(NULL, agf, XFS_AGF_FREEBLKS);
xfs_alloc_log_agf(args->tp, args->agbp,
XFS_AGF_FREEBLKS);
@@ -723,8 +708,7 @@ xfs_alloc_ag_vextent_exact(
cnt_cur = xfs_btree_init_cursor(args->mp, args->tp, args->agbp,
args->agno, XFS_BTNUM_CNT, NULL, 0);
ASSERT(args->agbno + args->len <=
- INT_GET(XFS_BUF_TO_AGF(args->agbp)->agf_length,
- ARCH_CONVERT));
+ be32_to_cpu(XFS_BUF_TO_AGF(args->agbp)->agf_length));
if ((error = xfs_alloc_fixup_trees(cnt_cur, bno_cur, fbno, flen,
args->agbno, args->len, XFSA_FIXUP_BNO_OK))) {
xfs_btree_del_cursor(cnt_cur, XFS_BTREE_ERROR);
@@ -897,8 +881,7 @@ xfs_alloc_ag_vextent_near(
goto error0;
XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
ltend = ltbno + ltlen;
- ASSERT(ltend <= INT_GET(XFS_BUF_TO_AGF(args->agbp)->agf_length,
- ARCH_CONVERT));
+ ASSERT(ltend <= be32_to_cpu(XFS_BUF_TO_AGF(args->agbp)->agf_length));
args->len = blen;
if (!xfs_alloc_fix_minleft(args)) {
xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR);
@@ -1253,8 +1236,7 @@ xfs_alloc_ag_vextent_near(
ltlen, &ltnew);
ASSERT(ltnew >= ltbno);
ASSERT(ltnew + rlen <= ltend);
- ASSERT(ltnew + rlen <= INT_GET(XFS_BUF_TO_AGF(args->agbp)->agf_length,
- ARCH_CONVERT));
+ ASSERT(ltnew + rlen <= be32_to_cpu(XFS_BUF_TO_AGF(args->agbp)->agf_length));
args->agbno = ltnew;
if ((error = xfs_alloc_fixup_trees(cnt_cur, bno_cur_lt, ltbno, ltlen,
ltnew, rlen, XFSA_FIXUP_BNO_OK)))
@@ -1417,8 +1399,7 @@ xfs_alloc_ag_vextent_size(
args->agbno = rbno;
XFS_WANT_CORRUPTED_GOTO(
args->agbno + args->len <=
- INT_GET(XFS_BUF_TO_AGF(args->agbp)->agf_length,
- ARCH_CONVERT),
+ be32_to_cpu(XFS_BUF_TO_AGF(args->agbp)->agf_length),
error0);
TRACE_ALLOC("normal", args);
return 0;
@@ -1466,8 +1447,8 @@ xfs_alloc_ag_vextent_small(
* freelist.
*/
else if (args->minlen == 1 && args->alignment == 1 && !args->isfl &&
- (INT_GET(XFS_BUF_TO_AGF(args->agbp)->agf_flcount,
- ARCH_CONVERT) > args->minleft)) {
+ (be32_to_cpu(XFS_BUF_TO_AGF(args->agbp)->agf_flcount)
+ > args->minleft)) {
if ((error = xfs_alloc_get_freelist(args->tp, args->agbp, &fbno)))
goto error0;
if (fbno != NULLAGBLOCK) {
@@ -1482,8 +1463,7 @@ xfs_alloc_ag_vextent_small(
args->agbno = fbno;
XFS_WANT_CORRUPTED_GOTO(
args->agbno + args->len <=
- INT_GET(XFS_BUF_TO_AGF(args->agbp)->agf_length,
- ARCH_CONVERT),
+ be32_to_cpu(XFS_BUF_TO_AGF(args->agbp)->agf_length),
error0);
args->wasfromfl = 1;
TRACE_ALLOC("freelist", args);
@@ -1757,12 +1737,12 @@ xfs_free_ag_extent(
agf = XFS_BUF_TO_AGF(agbp);
pag = &mp->m_perag[agno];
- INT_MOD(agf->agf_freeblks, ARCH_CONVERT, len);
+ be32_add(&agf->agf_freeblks, len);
xfs_trans_agblocks_delta(tp, len);
pag->pagf_freeblks += len;
XFS_WANT_CORRUPTED_GOTO(
- INT_GET(agf->agf_freeblks, ARCH_CONVERT)
- <= INT_GET(agf->agf_length, ARCH_CONVERT),
+ be32_to_cpu(agf->agf_freeblks) <=
+ be32_to_cpu(agf->agf_length),
error0);
TRACE_MODAGF(NULL, agf, XFS_AGF_FREEBLKS);
xfs_alloc_log_agf(tp, agbp, XFS_AGF_FREEBLKS);
@@ -1909,18 +1889,18 @@ xfs_alloc_fix_freelist(
*/
agf = XFS_BUF_TO_AGF(agbp);
need = XFS_MIN_FREELIST(agf, mp);
- delta = need > INT_GET(agf->agf_flcount, ARCH_CONVERT) ?
- (need - INT_GET(agf->agf_flcount, ARCH_CONVERT)) : 0;
+ delta = need > be32_to_cpu(agf->agf_flcount) ?
+ (need - be32_to_cpu(agf->agf_flcount)) : 0;
/*
* If there isn't enough total or single-extent, reject it.
*/
- longest = INT_GET(agf->agf_longest, ARCH_CONVERT);
+ longest = be32_to_cpu(agf->agf_longest);
longest = (longest > delta) ? (longest - delta) :
- (INT_GET(agf->agf_flcount, ARCH_CONVERT) > 0 || longest > 0);
+ (be32_to_cpu(agf->agf_flcount) > 0 || longest > 0);
if (args->minlen + args->alignment + args->minalignslop - 1 > longest ||
(args->minleft &&
- (int)(INT_GET(agf->agf_freeblks, ARCH_CONVERT) +
- INT_GET(agf->agf_flcount, ARCH_CONVERT) - need - args->total) <
+ (int)(be32_to_cpu(agf->agf_freeblks) +
+ be32_to_cpu(agf->agf_flcount) - need - args->total) <
(int)args->minleft)) {
xfs_trans_brelse(tp, agbp);
args->agbp = NULL;
@@ -1929,7 +1909,7 @@ xfs_alloc_fix_freelist(
/*
* Make the freelist shorter if it's too long.
*/
- while (INT_GET(agf->agf_flcount, ARCH_CONVERT) > need) {
+ while (be32_to_cpu(agf->agf_flcount) > need) {
xfs_buf_t *bp;
if ((error = xfs_alloc_get_freelist(tp, agbp, &bno)))
@@ -1956,9 +1936,9 @@ xfs_alloc_fix_freelist(
/*
* Make the freelist longer if it's too short.
*/
- while (INT_GET(agf->agf_flcount, ARCH_CONVERT) < need) {
+ while (be32_to_cpu(agf->agf_flcount) < need) {
targs.agbno = 0;
- targs.maxlen = need - INT_GET(agf->agf_flcount, ARCH_CONVERT);
+ targs.maxlen = need - be32_to_cpu(agf->agf_flcount);
/*
* Allocate as many blocks as possible at once.
*/
@@ -2018,19 +1998,19 @@ xfs_alloc_get_freelist(
*/
mp = tp->t_mountp;
if ((error = xfs_alloc_read_agfl(mp, tp,
- INT_GET(agf->agf_seqno, ARCH_CONVERT), &agflbp)))
+ be32_to_cpu(agf->agf_seqno), &agflbp)))
return error;
agfl = XFS_BUF_TO_AGFL(agflbp);
/*
* Get the block number and update the data structures.
*/
- bno = INT_GET(agfl->agfl_bno[INT_GET(agf->agf_flfirst, ARCH_CONVERT)], ARCH_CONVERT);
- INT_MOD(agf->agf_flfirst, ARCH_CONVERT, 1);
+ bno = INT_GET(agfl->agfl_bno[be32_to_cpu(agf->agf_flfirst)], ARCH_CONVERT);
+ be32_add(&agf->agf_flfirst, 1);
xfs_trans_brelse(tp, agflbp);
- if (INT_GET(agf->agf_flfirst, ARCH_CONVERT) == XFS_AGFL_SIZE(mp))
+ if (be32_to_cpu(agf->agf_flfirst) == XFS_AGFL_SIZE(mp))
agf->agf_flfirst = 0;
- pag = &mp->m_perag[INT_GET(agf->agf_seqno, ARCH_CONVERT)];
- INT_MOD(agf->agf_flcount, ARCH_CONVERT, -1);
+ pag = &mp->m_perag[be32_to_cpu(agf->agf_seqno)];
+ be32_add(&agf->agf_flcount, -1);
xfs_trans_agflist_delta(tp, -1);
pag->pagf_flcount--;
TRACE_MODAGF(NULL, agf, XFS_AGF_FLFIRST | XFS_AGF_FLCOUNT);
@@ -2045,7 +2025,7 @@ xfs_alloc_get_freelist(
* the freeing transaction must be pushed to disk NOW by forcing
* to disk all iclogs up that transaction's LSN.
*/
- xfs_alloc_search_busy(tp, INT_GET(agf->agf_seqno, ARCH_CONVERT), bno, 1);
+ xfs_alloc_search_busy(tp, be32_to_cpu(agf->agf_seqno), bno, 1);
return 0;
}
@@ -2123,18 +2103,18 @@ xfs_alloc_put_freelist(
mp = tp->t_mountp;
if (!agflbp && (error = xfs_alloc_read_agfl(mp, tp,
- INT_GET(agf->agf_seqno, ARCH_CONVERT), &agflbp)))
+ be32_to_cpu(agf->agf_seqno), &agflbp)))
return error;
agfl = XFS_BUF_TO_AGFL(agflbp);
- INT_MOD(agf->agf_fllast, ARCH_CONVERT, 1);
- if (INT_GET(agf->agf_fllast, ARCH_CONVERT) == XFS_AGFL_SIZE(mp))
+ be32_add(&agf->agf_fllast, 1);
+ if (be32_to_cpu(agf->agf_fllast) == XFS_AGFL_SIZE(mp))
agf->agf_fllast = 0;
- pag = &mp->m_perag[INT_GET(agf->agf_seqno, ARCH_CONVERT)];
- INT_MOD(agf->agf_flcount, ARCH_CONVERT, 1);
+ pag = &mp->m_perag[be32_to_cpu(agf->agf_seqno)];
+ be32_add(&agf->agf_flcount, 1);
xfs_trans_agflist_delta(tp, 1);
pag->pagf_flcount++;
- ASSERT(INT_GET(agf->agf_flcount, ARCH_CONVERT) <= XFS_AGFL_SIZE(mp));
- blockp = &agfl->agfl_bno[INT_GET(agf->agf_fllast, ARCH_CONVERT)];
+ ASSERT(be32_to_cpu(agf->agf_flcount) <= XFS_AGFL_SIZE(mp));
+ blockp = &agfl->agfl_bno[be32_to_cpu(agf->agf_fllast)];
INT_SET(*blockp, ARCH_CONVERT, bno);
TRACE_MODAGF(NULL, agf, XFS_AGF_FLLAST | XFS_AGF_FLCOUNT);
xfs_alloc_log_agf(tp, agbp, XFS_AGF_FLLAST | XFS_AGF_FLCOUNT);
@@ -2181,14 +2161,12 @@ xfs_alloc_read_agf(
*/
agf = XFS_BUF_TO_AGF(bp);
agf_ok =
- INT_GET(agf->agf_magicnum, ARCH_CONVERT) == XFS_AGF_MAGIC &&
- XFS_AGF_GOOD_VERSION(
- INT_GET(agf->agf_versionnum, ARCH_CONVERT)) &&
- INT_GET(agf->agf_freeblks, ARCH_CONVERT) <=
- INT_GET(agf->agf_length, ARCH_CONVERT) &&
- INT_GET(agf->agf_flfirst, ARCH_CONVERT) < XFS_AGFL_SIZE(mp) &&
- INT_GET(agf->agf_fllast, ARCH_CONVERT) < XFS_AGFL_SIZE(mp) &&
- INT_GET(agf->agf_flcount, ARCH_CONVERT) <= XFS_AGFL_SIZE(mp);
+ be32_to_cpu(agf->agf_magicnum) == XFS_AGF_MAGIC &&
+ XFS_AGF_GOOD_VERSION(be32_to_cpu(agf->agf_versionnum)) &&
+ be32_to_cpu(agf->agf_freeblks) <= be32_to_cpu(agf->agf_length) &&
+ be32_to_cpu(agf->agf_flfirst) < XFS_AGFL_SIZE(mp) &&
+ be32_to_cpu(agf->agf_fllast) < XFS_AGFL_SIZE(mp) &&
+ be32_to_cpu(agf->agf_flcount) <= XFS_AGFL_SIZE(mp);
if (unlikely(XFS_TEST_ERROR(!agf_ok, mp, XFS_ERRTAG_ALLOC_READ_AGF,
XFS_RANDOM_ALLOC_READ_AGF))) {
XFS_CORRUPTION_ERROR("xfs_alloc_read_agf",
@@ -2198,13 +2176,13 @@ xfs_alloc_read_agf(
}
pag = &mp->m_perag[agno];
if (!pag->pagf_init) {
- pag->pagf_freeblks = INT_GET(agf->agf_freeblks, ARCH_CONVERT);
- pag->pagf_flcount = INT_GET(agf->agf_flcount, ARCH_CONVERT);
- pag->pagf_longest = INT_GET(agf->agf_longest, ARCH_CONVERT);
+ pag->pagf_freeblks = be32_to_cpu(agf->agf_freeblks);
+ pag->pagf_flcount = be32_to_cpu(agf->agf_flcount);
+ pag->pagf_longest = be32_to_cpu(agf->agf_longest);
pag->pagf_levels[XFS_BTNUM_BNOi] =
- INT_GET(agf->agf_levels[XFS_BTNUM_BNOi], ARCH_CONVERT);
+ be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNOi]);
pag->pagf_levels[XFS_BTNUM_CNTi] =
- INT_GET(agf->agf_levels[XFS_BTNUM_CNTi], ARCH_CONVERT);
+ be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNTi]);
spinlock_init(&pag->pagb_lock, "xfspagb");
pag->pagb_list = kmem_zalloc(XFS_PAGB_NUM_SLOTS *
sizeof(xfs_perag_busy_t), KM_SLEEP);
@@ -2212,13 +2190,13 @@ xfs_alloc_read_agf(
}
#ifdef DEBUG
else if (!XFS_FORCED_SHUTDOWN(mp)) {
- ASSERT(pag->pagf_freeblks == INT_GET(agf->agf_freeblks, ARCH_CONVERT));
- ASSERT(pag->pagf_flcount == INT_GET(agf->agf_flcount, ARCH_CONVERT));
- ASSERT(pag->pagf_longest == INT_GET(agf->agf_longest, ARCH_CONVERT));
+ ASSERT(pag->pagf_freeblks == be32_to_cpu(agf->agf_freeblks));
+ ASSERT(pag->pagf_flcount == be32_to_cpu(agf->agf_flcount));
+ ASSERT(pag->pagf_longest == be32_to_cpu(agf->agf_longest));
ASSERT(pag->pagf_levels[XFS_BTNUM_BNOi] ==
- INT_GET(agf->agf_levels[XFS_BTNUM_BNOi], ARCH_CONVERT));
+ be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNOi]));
ASSERT(pag->pagf_levels[XFS_BTNUM_CNTi] ==
- INT_GET(agf->agf_levels[XFS_BTNUM_CNTi], ARCH_CONVERT));
+ be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNTi]));
}
#endif
XFS_BUF_SET_VTYPE_REF(bp, B_FS_AGF, XFS_AGF_REF);
@@ -2467,7 +2445,7 @@ xfs_free_extent(
#ifdef DEBUG
ASSERT(args.agbp != NULL);
agf = XFS_BUF_TO_AGF(args.agbp);
- ASSERT(args.agbno + len <= INT_GET(agf->agf_length, ARCH_CONVERT));
+ ASSERT(args.agbno + len <= be32_to_cpu(agf->agf_length));
#endif
error = xfs_free_ag_extent(tp, args.agbp, args.agno, args.agbno,
len, 0);
diff --git a/fs/xfs/xfs_alloc.h b/fs/xfs/xfs_alloc.h
index 72329c86351c..3546dea27b7d 100644
--- a/fs/xfs/xfs_alloc.h
+++ b/fs/xfs/xfs_alloc.h
@@ -1,33 +1,19 @@
/*
- * Copyright (c) 2000-2002 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __XFS_ALLOC_H__
#define __XFS_ALLOC_H__
diff --git a/fs/xfs/xfs_alloc_btree.c b/fs/xfs/xfs_alloc_btree.c
index e0355a12d946..a1d92da86ccd 100644
--- a/fs/xfs/xfs_alloc_btree.c
+++ b/fs/xfs/xfs_alloc_btree.c
@@ -1,53 +1,41 @@
/*
- * Copyright (c) 2000-2001 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-
-/*
- * Free space allocation for XFS.
- */
-
#include "xfs.h"
-#include "xfs_macros.h"
+#include "xfs_fs.h"
#include "xfs_types.h"
-#include "xfs_inum.h"
+#include "xfs_bit.h"
#include "xfs_log.h"
+#include "xfs_inum.h"
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
#include "xfs_dir.h"
+#include "xfs_dir2.h"
#include "xfs_dmapi.h"
#include "xfs_mount.h"
+#include "xfs_bmap_btree.h"
#include "xfs_alloc_btree.h"
#include "xfs_ialloc_btree.h"
-#include "xfs_bmap_btree.h"
+#include "xfs_dir_sf.h"
+#include "xfs_dir2_sf.h"
+#include "xfs_attr_sf.h"
+#include "xfs_dinode.h"
+#include "xfs_inode.h"
#include "xfs_btree.h"
#include "xfs_ialloc.h"
#include "xfs_alloc.h"
@@ -129,7 +117,7 @@ xfs_alloc_delrec(
/*
* Fail if we're off the end of the block.
*/
- if (ptr > INT_GET(block->bb_numrecs, ARCH_CONVERT)) {
+ if (ptr > be16_to_cpu(block->bb_numrecs)) {
*stat = 0;
return 0;
}
@@ -143,18 +131,18 @@ xfs_alloc_delrec(
lkp = XFS_ALLOC_KEY_ADDR(block, 1, cur);
lpp = XFS_ALLOC_PTR_ADDR(block, 1, cur);
#ifdef DEBUG
- for (i = ptr; i < INT_GET(block->bb_numrecs, ARCH_CONVERT); i++) {
- if ((error = xfs_btree_check_sptr(cur, INT_GET(lpp[i], ARCH_CONVERT), level)))
+ for (i = ptr; i < be16_to_cpu(block->bb_numrecs); i++) {
+ if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(lpp[i]), level)))
return error;
}
#endif
- if (ptr < INT_GET(block->bb_numrecs, ARCH_CONVERT)) {
+ if (ptr < be16_to_cpu(block->bb_numrecs)) {
memmove(&lkp[ptr - 1], &lkp[ptr],
- (INT_GET(block->bb_numrecs, ARCH_CONVERT) - ptr) * sizeof(*lkp)); /* INT_: mem copy */
+ (be16_to_cpu(block->bb_numrecs) - ptr) * sizeof(*lkp));
memmove(&lpp[ptr - 1], &lpp[ptr],
- (INT_GET(block->bb_numrecs, ARCH_CONVERT) - ptr) * sizeof(*lpp)); /* INT_: mem copy */
- xfs_alloc_log_ptrs(cur, bp, ptr, INT_GET(block->bb_numrecs, ARCH_CONVERT) - 1);
- xfs_alloc_log_keys(cur, bp, ptr, INT_GET(block->bb_numrecs, ARCH_CONVERT) - 1);
+ (be16_to_cpu(block->bb_numrecs) - ptr) * sizeof(*lpp));
+ xfs_alloc_log_ptrs(cur, bp, ptr, be16_to_cpu(block->bb_numrecs) - 1);
+ xfs_alloc_log_keys(cur, bp, ptr, be16_to_cpu(block->bb_numrecs) - 1);
}
}
/*
@@ -163,25 +151,25 @@ xfs_alloc_delrec(
*/
else {
lrp = XFS_ALLOC_REC_ADDR(block, 1, cur);
- if (ptr < INT_GET(block->bb_numrecs, ARCH_CONVERT)) {
+ if (ptr < be16_to_cpu(block->bb_numrecs)) {
memmove(&lrp[ptr - 1], &lrp[ptr],
- (INT_GET(block->bb_numrecs, ARCH_CONVERT) - ptr) * sizeof(*lrp));
- xfs_alloc_log_recs(cur, bp, ptr, INT_GET(block->bb_numrecs, ARCH_CONVERT) - 1);
+ (be16_to_cpu(block->bb_numrecs) - ptr) * sizeof(*lrp));
+ xfs_alloc_log_recs(cur, bp, ptr, be16_to_cpu(block->bb_numrecs) - 1);
}
/*
* If it's the first record in the block, we'll need a key
* structure to pass up to the next level (updkey).
*/
if (ptr == 1) {
- key.ar_startblock = lrp->ar_startblock; /* INT_: direct copy */
- key.ar_blockcount = lrp->ar_blockcount; /* INT_: direct copy */
+ key.ar_startblock = lrp->ar_startblock;
+ key.ar_blockcount = lrp->ar_blockcount;
lkp = &key;
}
}
/*
* Decrement and log the number of entries in the block.
*/
- INT_MOD(block->bb_numrecs, ARCH_CONVERT, -1);
+ be16_add(&block->bb_numrecs, -1);
xfs_alloc_log_block(cur->bc_tp, bp, XFS_BB_NUMRECS);
/*
* See if the longest free extent in the allocation group was
@@ -194,24 +182,24 @@ xfs_alloc_delrec(
if (level == 0 &&
cur->bc_btnum == XFS_BTNUM_CNT &&
- INT_GET(block->bb_rightsib, ARCH_CONVERT) == NULLAGBLOCK &&
- ptr > INT_GET(block->bb_numrecs, ARCH_CONVERT)) {
- ASSERT(ptr == INT_GET(block->bb_numrecs, ARCH_CONVERT) + 1);
+ be32_to_cpu(block->bb_rightsib) == NULLAGBLOCK &&
+ ptr > be16_to_cpu(block->bb_numrecs)) {
+ ASSERT(ptr == be16_to_cpu(block->bb_numrecs) + 1);
/*
* There are still records in the block. Grab the size
* from the last one.
*/
- if (INT_GET(block->bb_numrecs, ARCH_CONVERT)) {
- rrp = XFS_ALLOC_REC_ADDR(block, INT_GET(block->bb_numrecs, ARCH_CONVERT), cur);
- INT_COPY(agf->agf_longest, rrp->ar_blockcount, ARCH_CONVERT);
+ if (be16_to_cpu(block->bb_numrecs)) {
+ rrp = XFS_ALLOC_REC_ADDR(block, be16_to_cpu(block->bb_numrecs), cur);
+ agf->agf_longest = rrp->ar_blockcount;
}
/*
* No free extents left.
*/
else
agf->agf_longest = 0;
- mp->m_perag[INT_GET(agf->agf_seqno, ARCH_CONVERT)].pagf_longest =
- INT_GET(agf->agf_longest, ARCH_CONVERT);
+ mp->m_perag[be32_to_cpu(agf->agf_seqno)].pagf_longest =
+ be32_to_cpu(agf->agf_longest);
xfs_alloc_log_agf(cur->bc_tp, cur->bc_private.a.agbp,
XFS_AGF_LONGEST);
}
@@ -225,15 +213,15 @@ xfs_alloc_delrec(
* and it's NOT the leaf level,
* then we can get rid of this level.
*/
- if (INT_GET(block->bb_numrecs, ARCH_CONVERT) == 1 && level > 0) {
+ if (be16_to_cpu(block->bb_numrecs) == 1 && level > 0) {
/*
* lpp is still set to the first pointer in the block.
* Make it the new root of the btree.
*/
- bno = INT_GET(agf->agf_roots[cur->bc_btnum], ARCH_CONVERT);
- INT_COPY(agf->agf_roots[cur->bc_btnum], *lpp, ARCH_CONVERT);
- INT_MOD(agf->agf_levels[cur->bc_btnum], ARCH_CONVERT, -1);
- mp->m_perag[INT_GET(agf->agf_seqno, ARCH_CONVERT)].pagf_levels[cur->bc_btnum]--;
+ bno = be32_to_cpu(agf->agf_roots[cur->bc_btnum]);
+ agf->agf_roots[cur->bc_btnum] = *lpp;
+ be32_add(&agf->agf_levels[cur->bc_btnum], -1);
+ mp->m_perag[be32_to_cpu(agf->agf_seqno)].pagf_levels[cur->bc_btnum]--;
/*
* Put this buffer/block on the ag's freelist.
*/
@@ -255,7 +243,7 @@ xfs_alloc_delrec(
* that freed the block.
*/
xfs_alloc_mark_busy(cur->bc_tp,
- INT_GET(agf->agf_seqno, ARCH_CONVERT), bno, 1);
+ be32_to_cpu(agf->agf_seqno), bno, 1);
xfs_trans_agbtree_delta(cur->bc_tp, -1);
xfs_alloc_log_agf(cur->bc_tp, cur->bc_private.a.agbp,
@@ -281,7 +269,7 @@ xfs_alloc_delrec(
* If the number of records remaining in the block is at least
* the minimum, we're done.
*/
- if (INT_GET(block->bb_numrecs, ARCH_CONVERT) >= XFS_ALLOC_BLOCK_MINRECS(level, cur)) {
+ if (be16_to_cpu(block->bb_numrecs) >= XFS_ALLOC_BLOCK_MINRECS(level, cur)) {
if (level > 0 && (error = xfs_alloc_decrement(cur, level, &i)))
return error;
*stat = 1;
@@ -292,8 +280,8 @@ xfs_alloc_delrec(
* tree balanced. Look at the left and right sibling blocks to
* see if we can re-balance by moving only one record.
*/
- rbno = INT_GET(block->bb_rightsib, ARCH_CONVERT);
- lbno = INT_GET(block->bb_leftsib, ARCH_CONVERT);
+ rbno = be32_to_cpu(block->bb_rightsib);
+ lbno = be32_to_cpu(block->bb_leftsib);
bno = NULLAGBLOCK;
ASSERT(rbno != NULLAGBLOCK || lbno != NULLAGBLOCK);
/*
@@ -330,18 +318,18 @@ xfs_alloc_delrec(
/*
* Grab the current block number, for future use.
*/
- bno = INT_GET(right->bb_leftsib, ARCH_CONVERT);
+ bno = be32_to_cpu(right->bb_leftsib);
/*
* If right block is full enough so that removing one entry
* won't make it too empty, and left-shifting an entry out
* of right to us works, we're done.
*/
- if (INT_GET(right->bb_numrecs, ARCH_CONVERT) - 1 >=
+ if (be16_to_cpu(right->bb_numrecs) - 1 >=
XFS_ALLOC_BLOCK_MINRECS(level, cur)) {
if ((error = xfs_alloc_lshift(tcur, level, &i)))
goto error0;
if (i) {
- ASSERT(INT_GET(block->bb_numrecs, ARCH_CONVERT) >=
+ ASSERT(be16_to_cpu(block->bb_numrecs) >=
XFS_ALLOC_BLOCK_MINRECS(level, cur));
xfs_btree_del_cursor(tcur,
XFS_BTREE_NOERROR);
@@ -358,7 +346,7 @@ xfs_alloc_delrec(
* future reference, and fix up the temp cursor to point
* to our block again (last record).
*/
- rrecs = INT_GET(right->bb_numrecs, ARCH_CONVERT);
+ rrecs = be16_to_cpu(right->bb_numrecs);
if (lbno != NULLAGBLOCK) {
i = xfs_btree_firstrec(tcur, level);
XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
@@ -394,18 +382,18 @@ xfs_alloc_delrec(
/*
* Grab the current block number, for future use.
*/
- bno = INT_GET(left->bb_rightsib, ARCH_CONVERT);
+ bno = be32_to_cpu(left->bb_rightsib);
/*
* If left block is full enough so that removing one entry
* won't make it too empty, and right-shifting an entry out
* of left to us works, we're done.
*/
- if (INT_GET(left->bb_numrecs, ARCH_CONVERT) - 1 >=
+ if (be16_to_cpu(left->bb_numrecs) - 1 >=
XFS_ALLOC_BLOCK_MINRECS(level, cur)) {
if ((error = xfs_alloc_rshift(tcur, level, &i)))
goto error0;
if (i) {
- ASSERT(INT_GET(block->bb_numrecs, ARCH_CONVERT) >=
+ ASSERT(be16_to_cpu(block->bb_numrecs) >=
XFS_ALLOC_BLOCK_MINRECS(level, cur));
xfs_btree_del_cursor(tcur,
XFS_BTREE_NOERROR);
@@ -419,7 +407,7 @@ xfs_alloc_delrec(
* Otherwise, grab the number of records in right for
* future reference.
*/
- lrecs = INT_GET(left->bb_numrecs, ARCH_CONVERT);
+ lrecs = be16_to_cpu(left->bb_numrecs);
}
/*
* Delete the temp cursor, we're done with it.
@@ -433,7 +421,7 @@ xfs_alloc_delrec(
* See if we can join with the left neighbor block.
*/
if (lbno != NULLAGBLOCK &&
- lrecs + INT_GET(block->bb_numrecs, ARCH_CONVERT) <= XFS_ALLOC_BLOCK_MAXRECS(level, cur)) {
+ lrecs + be16_to_cpu(block->bb_numrecs) <= XFS_ALLOC_BLOCK_MAXRECS(level, cur)) {
/*
* Set "right" to be the starting block,
* "left" to be the left neighbor.
@@ -453,7 +441,7 @@ xfs_alloc_delrec(
* If that won't work, see if we can join with the right neighbor block.
*/
else if (rbno != NULLAGBLOCK &&
- rrecs + INT_GET(block->bb_numrecs, ARCH_CONVERT) <=
+ rrecs + be16_to_cpu(block->bb_numrecs) <=
XFS_ALLOC_BLOCK_MAXRECS(level, cur)) {
/*
* Set "left" to be the starting block,
@@ -488,31 +476,34 @@ xfs_alloc_delrec(
/*
* It's a non-leaf. Move keys and pointers.
*/
- lkp = XFS_ALLOC_KEY_ADDR(left, INT_GET(left->bb_numrecs, ARCH_CONVERT) + 1, cur);
- lpp = XFS_ALLOC_PTR_ADDR(left, INT_GET(left->bb_numrecs, ARCH_CONVERT) + 1, cur);
+ lkp = XFS_ALLOC_KEY_ADDR(left, be16_to_cpu(left->bb_numrecs) + 1, cur);
+ lpp = XFS_ALLOC_PTR_ADDR(left, be16_to_cpu(left->bb_numrecs) + 1, cur);
rkp = XFS_ALLOC_KEY_ADDR(right, 1, cur);
rpp = XFS_ALLOC_PTR_ADDR(right, 1, cur);
#ifdef DEBUG
- for (i = 0; i < INT_GET(right->bb_numrecs, ARCH_CONVERT); i++) {
- if ((error = xfs_btree_check_sptr(cur, INT_GET(rpp[i], ARCH_CONVERT), level)))
+ for (i = 0; i < be16_to_cpu(right->bb_numrecs); i++) {
+ if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(rpp[i]), level)))
return error;
}
#endif
- memcpy(lkp, rkp, INT_GET(right->bb_numrecs, ARCH_CONVERT) * sizeof(*lkp)); /* INT_: structure copy */
- memcpy(lpp, rpp, INT_GET(right->bb_numrecs, ARCH_CONVERT) * sizeof(*lpp)); /* INT_: structure copy */
- xfs_alloc_log_keys(cur, lbp, INT_GET(left->bb_numrecs, ARCH_CONVERT) + 1,
- INT_GET(left->bb_numrecs, ARCH_CONVERT) + INT_GET(right->bb_numrecs, ARCH_CONVERT));
- xfs_alloc_log_ptrs(cur, lbp, INT_GET(left->bb_numrecs, ARCH_CONVERT) + 1,
- INT_GET(left->bb_numrecs, ARCH_CONVERT) + INT_GET(right->bb_numrecs, ARCH_CONVERT));
+ memcpy(lkp, rkp, be16_to_cpu(right->bb_numrecs) * sizeof(*lkp));
+ memcpy(lpp, rpp, be16_to_cpu(right->bb_numrecs) * sizeof(*lpp));
+ xfs_alloc_log_keys(cur, lbp, be16_to_cpu(left->bb_numrecs) + 1,
+ be16_to_cpu(left->bb_numrecs) +
+ be16_to_cpu(right->bb_numrecs));
+ xfs_alloc_log_ptrs(cur, lbp, be16_to_cpu(left->bb_numrecs) + 1,
+ be16_to_cpu(left->bb_numrecs) +
+ be16_to_cpu(right->bb_numrecs));
} else {
/*
* It's a leaf. Move records.
*/
- lrp = XFS_ALLOC_REC_ADDR(left, INT_GET(left->bb_numrecs, ARCH_CONVERT) + 1, cur);
+ lrp = XFS_ALLOC_REC_ADDR(left, be16_to_cpu(left->bb_numrecs) + 1, cur);
rrp = XFS_ALLOC_REC_ADDR(right, 1, cur);
- memcpy(lrp, rrp, INT_GET(right->bb_numrecs, ARCH_CONVERT) * sizeof(*lrp));
- xfs_alloc_log_recs(cur, lbp, INT_GET(left->bb_numrecs, ARCH_CONVERT) + 1,
- INT_GET(left->bb_numrecs, ARCH_CONVERT) + INT_GET(right->bb_numrecs, ARCH_CONVERT));
+ memcpy(lrp, rrp, be16_to_cpu(right->bb_numrecs) * sizeof(*lrp));
+ xfs_alloc_log_recs(cur, lbp, be16_to_cpu(left->bb_numrecs) + 1,
+ be16_to_cpu(left->bb_numrecs) +
+ be16_to_cpu(right->bb_numrecs));
}
/*
* If we joined with the left neighbor, set the buffer in the
@@ -520,7 +511,7 @@ xfs_alloc_delrec(
*/
if (bp != lbp) {
xfs_btree_setbuf(cur, level, lbp);
- cur->bc_ptrs[level] += INT_GET(left->bb_numrecs, ARCH_CONVERT);
+ cur->bc_ptrs[level] += be16_to_cpu(left->bb_numrecs);
}
/*
* If we joined with the right neighbor and there's a level above
@@ -532,28 +523,28 @@ xfs_alloc_delrec(
/*
* Fix up the number of records in the surviving block.
*/
- INT_MOD(left->bb_numrecs, ARCH_CONVERT, INT_GET(right->bb_numrecs, ARCH_CONVERT));
+ be16_add(&left->bb_numrecs, be16_to_cpu(right->bb_numrecs));
/*
* Fix up the right block pointer in the surviving block, and log it.
*/
- left->bb_rightsib = right->bb_rightsib; /* INT_: direct copy */
+ left->bb_rightsib = right->bb_rightsib;
xfs_alloc_log_block(cur->bc_tp, lbp, XFS_BB_NUMRECS | XFS_BB_RIGHTSIB);
/*
* If there is a right sibling now, make it point to the
* remaining block.
*/
- if (INT_GET(left->bb_rightsib, ARCH_CONVERT) != NULLAGBLOCK) {
+ if (be32_to_cpu(left->bb_rightsib) != NULLAGBLOCK) {
xfs_alloc_block_t *rrblock;
xfs_buf_t *rrbp;
if ((error = xfs_btree_read_bufs(mp, cur->bc_tp,
- cur->bc_private.a.agno, INT_GET(left->bb_rightsib, ARCH_CONVERT), 0,
+ cur->bc_private.a.agno, be32_to_cpu(left->bb_rightsib), 0,
&rrbp, XFS_ALLOC_BTREE_REF)))
return error;
rrblock = XFS_BUF_TO_ALLOC_BLOCK(rrbp);
if ((error = xfs_btree_check_sblock(cur, rrblock, level, rrbp)))
return error;
- INT_SET(rrblock->bb_leftsib, ARCH_CONVERT, lbno);
+ rrblock->bb_leftsib = cpu_to_be32(lbno);
xfs_alloc_log_block(cur->bc_tp, rrbp, XFS_BB_LEFTSIB);
}
/*
@@ -574,10 +565,9 @@ xfs_alloc_delrec(
* busy block is allocated, the iclog is pushed up to the
* LSN that freed the block.
*/
- xfs_alloc_mark_busy(cur->bc_tp,
- INT_GET(agf->agf_seqno, ARCH_CONVERT), bno, 1);
-
+ xfs_alloc_mark_busy(cur->bc_tp, be32_to_cpu(agf->agf_seqno), bno, 1);
xfs_trans_agbtree_delta(cur->bc_tp, -1);
+
/*
* Adjust the current level's cursor so that we're left referring
* to the right node, after we're done.
@@ -625,7 +615,15 @@ xfs_alloc_insrec(
int ptr; /* index in btree block for this rec */
xfs_alloc_rec_t *rp; /* pointer to btree records */
- ASSERT(INT_GET(recp->ar_blockcount, ARCH_CONVERT) > 0);
+ ASSERT(be32_to_cpu(recp->ar_blockcount) > 0);
+
+ /*
+ * GCC doesn't understand the (arguably complex) control flow in
+ * this function and complains about uninitialized structure fields
+ * without this.
+ */
+ memset(&nrec, 0, sizeof(nrec));
+
/*
* If we made it to the root level, allocate a new root block
* and we're done.
@@ -641,8 +639,8 @@ xfs_alloc_insrec(
/*
* Make a key out of the record data to be inserted, and save it.
*/
- key.ar_startblock = recp->ar_startblock; /* INT_: direct copy */
- key.ar_blockcount = recp->ar_blockcount; /* INT_: direct copy */
+ key.ar_startblock = recp->ar_startblock;
+ key.ar_blockcount = recp->ar_blockcount;
optr = ptr = cur->bc_ptrs[level];
/*
* If we're off the left edge, return failure.
@@ -663,7 +661,7 @@ xfs_alloc_insrec(
/*
* Check that the new entry is being inserted in the right place.
*/
- if (ptr <= INT_GET(block->bb_numrecs, ARCH_CONVERT)) {
+ if (ptr <= be16_to_cpu(block->bb_numrecs)) {
if (level == 0) {
rp = XFS_ALLOC_REC_ADDR(block, ptr, cur);
xfs_btree_check_rec(cur->bc_btnum, recp, rp);
@@ -679,7 +677,7 @@ xfs_alloc_insrec(
* If the block is full, we can't insert the new entry until we
* make the block un-full.
*/
- if (INT_GET(block->bb_numrecs, ARCH_CONVERT) == XFS_ALLOC_BLOCK_MAXRECS(level, cur)) {
+ if (be16_to_cpu(block->bb_numrecs) == XFS_ALLOC_BLOCK_MAXRECS(level, cur)) {
/*
* First, try shifting an entry to the right neighbor.
*/
@@ -716,8 +714,8 @@ xfs_alloc_insrec(
return error;
#endif
ptr = cur->bc_ptrs[level];
- nrec.ar_startblock = nkey.ar_startblock; /* INT_: direct copy */
- nrec.ar_blockcount = nkey.ar_blockcount; /* INT_: direct copy */
+ nrec.ar_startblock = nkey.ar_startblock;
+ nrec.ar_blockcount = nkey.ar_blockcount;
}
/*
* Otherwise the insert fails.
@@ -741,15 +739,15 @@ xfs_alloc_insrec(
kp = XFS_ALLOC_KEY_ADDR(block, 1, cur);
pp = XFS_ALLOC_PTR_ADDR(block, 1, cur);
#ifdef DEBUG
- for (i = INT_GET(block->bb_numrecs, ARCH_CONVERT); i >= ptr; i--) {
- if ((error = xfs_btree_check_sptr(cur, INT_GET(pp[i - 1], ARCH_CONVERT), level)))
+ for (i = be16_to_cpu(block->bb_numrecs); i >= ptr; i--) {
+ if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(pp[i - 1]), level)))
return error;
}
#endif
memmove(&kp[ptr], &kp[ptr - 1],
- (INT_GET(block->bb_numrecs, ARCH_CONVERT) - ptr + 1) * sizeof(*kp)); /* INT_: copy */
+ (be16_to_cpu(block->bb_numrecs) - ptr + 1) * sizeof(*kp));
memmove(&pp[ptr], &pp[ptr - 1],
- (INT_GET(block->bb_numrecs, ARCH_CONVERT) - ptr + 1) * sizeof(*pp)); /* INT_: copy */
+ (be16_to_cpu(block->bb_numrecs) - ptr + 1) * sizeof(*pp));
#ifdef DEBUG
if ((error = xfs_btree_check_sptr(cur, *bnop, level)))
return error;
@@ -758,12 +756,12 @@ xfs_alloc_insrec(
* Now stuff the new data in, bump numrecs and log the new data.
*/
kp[ptr - 1] = key;
- INT_SET(pp[ptr - 1], ARCH_CONVERT, *bnop);
- INT_MOD(block->bb_numrecs, ARCH_CONVERT, +1);
- xfs_alloc_log_keys(cur, bp, ptr, INT_GET(block->bb_numrecs, ARCH_CONVERT));
- xfs_alloc_log_ptrs(cur, bp, ptr, INT_GET(block->bb_numrecs, ARCH_CONVERT));
+ pp[ptr - 1] = cpu_to_be32(*bnop);
+ be16_add(&block->bb_numrecs, 1);
+ xfs_alloc_log_keys(cur, bp, ptr, be16_to_cpu(block->bb_numrecs));
+ xfs_alloc_log_ptrs(cur, bp, ptr, be16_to_cpu(block->bb_numrecs));
#ifdef DEBUG
- if (ptr < INT_GET(block->bb_numrecs, ARCH_CONVERT))
+ if (ptr < be16_to_cpu(block->bb_numrecs))
xfs_btree_check_key(cur->bc_btnum, kp + ptr - 1,
kp + ptr);
#endif
@@ -773,16 +771,16 @@ xfs_alloc_insrec(
*/
rp = XFS_ALLOC_REC_ADDR(block, 1, cur);
memmove(&rp[ptr], &rp[ptr - 1],
- (INT_GET(block->bb_numrecs, ARCH_CONVERT) - ptr + 1) * sizeof(*rp));
+ (be16_to_cpu(block->bb_numrecs) - ptr + 1) * sizeof(*rp));
/*
* Now stuff the new record in, bump numrecs
* and log the new data.
*/
rp[ptr - 1] = *recp; /* INT_: struct copy */
- INT_MOD(block->bb_numrecs, ARCH_CONVERT, +1);
- xfs_alloc_log_recs(cur, bp, ptr, INT_GET(block->bb_numrecs, ARCH_CONVERT));
+ be16_add(&block->bb_numrecs, 1);
+ xfs_alloc_log_recs(cur, bp, ptr, be16_to_cpu(block->bb_numrecs));
#ifdef DEBUG
- if (ptr < INT_GET(block->bb_numrecs, ARCH_CONVERT))
+ if (ptr < be16_to_cpu(block->bb_numrecs))
xfs_btree_check_rec(cur->bc_btnum, rp + ptr - 1,
rp + ptr);
#endif
@@ -804,16 +802,16 @@ xfs_alloc_insrec(
agf = XFS_BUF_TO_AGF(cur->bc_private.a.agbp);
if (level == 0 &&
cur->bc_btnum == XFS_BTNUM_CNT &&
- INT_GET(block->bb_rightsib, ARCH_CONVERT) == NULLAGBLOCK &&
- INT_GET(recp->ar_blockcount, ARCH_CONVERT) > INT_GET(agf->agf_longest, ARCH_CONVERT)) {
+ be32_to_cpu(block->bb_rightsib) == NULLAGBLOCK &&
+ be32_to_cpu(recp->ar_blockcount) > be32_to_cpu(agf->agf_longest)) {
/*
* If this is a leaf in the by-size btree and there
* is no right sibling block and this block is bigger
* than the previous longest block, update it.
*/
- INT_COPY(agf->agf_longest, recp->ar_blockcount, ARCH_CONVERT);
- cur->bc_mp->m_perag[INT_GET(agf->agf_seqno, ARCH_CONVERT)].pagf_longest
- = INT_GET(recp->ar_blockcount, ARCH_CONVERT);
+ agf->agf_longest = recp->ar_blockcount;
+ cur->bc_mp->m_perag[be32_to_cpu(agf->agf_seqno)].pagf_longest
+ = be32_to_cpu(recp->ar_blockcount);
xfs_alloc_log_agf(cur->bc_tp, cur->bc_private.a.agbp,
XFS_AGF_LONGEST);
}
@@ -923,8 +921,9 @@ xfs_alloc_log_recs(
agf = XFS_BUF_TO_AGF(cur->bc_private.a.agbp);
for (p = &rp[rfirst - 1]; p <= &rp[rlast - 1]; p++)
- ASSERT(INT_GET(p->ar_startblock, ARCH_CONVERT) + INT_GET(p->ar_blockcount, ARCH_CONVERT) <=
- INT_GET(agf->agf_length, ARCH_CONVERT));
+ ASSERT(be32_to_cpu(p->ar_startblock) +
+ be32_to_cpu(p->ar_blockcount) <=
+ be32_to_cpu(agf->agf_length));
}
#endif
first = (int)((xfs_caddr_t)&rp[rfirst - 1] - (xfs_caddr_t)block);
@@ -961,8 +960,8 @@ xfs_alloc_lookup(
xfs_agf_t *agf; /* a.g. freespace header */
agf = XFS_BUF_TO_AGF(cur->bc_private.a.agbp);
- agno = INT_GET(agf->agf_seqno, ARCH_CONVERT);
- agbno = INT_GET(agf->agf_roots[cur->bc_btnum], ARCH_CONVERT);
+ agno = be32_to_cpu(agf->agf_seqno);
+ agbno = be32_to_cpu(agf->agf_roots[cur->bc_btnum]);
}
/*
* Iterate over each level in the btree, starting at the root.
@@ -1029,7 +1028,7 @@ xfs_alloc_lookup(
* Set low and high entry numbers, 1-based.
*/
low = 1;
- if (!(high = INT_GET(block->bb_numrecs, ARCH_CONVERT))) {
+ if (!(high = be16_to_cpu(block->bb_numrecs))) {
/*
* If the block is empty, the tree must
* be an empty leaf.
@@ -1058,14 +1057,14 @@ xfs_alloc_lookup(
xfs_alloc_key_t *kkp;
kkp = kkbase + keyno - 1;
- startblock = INT_GET(kkp->ar_startblock, ARCH_CONVERT);
- blockcount = INT_GET(kkp->ar_blockcount, ARCH_CONVERT);
+ startblock = be32_to_cpu(kkp->ar_startblock);
+ blockcount = be32_to_cpu(kkp->ar_blockcount);
} else {
xfs_alloc_rec_t *krp;
krp = krbase + keyno - 1;
- startblock = INT_GET(krp->ar_startblock, ARCH_CONVERT);
- blockcount = INT_GET(krp->ar_blockcount, ARCH_CONVERT);
+ startblock = be32_to_cpu(krp->ar_startblock);
+ blockcount = be32_to_cpu(krp->ar_blockcount);
}
/*
* Compute difference to get next direction.
@@ -1105,7 +1104,7 @@ xfs_alloc_lookup(
*/
if (diff > 0 && --keyno < 1)
keyno = 1;
- agbno = INT_GET(*XFS_ALLOC_PTR_ADDR(block, keyno, cur), ARCH_CONVERT);
+ agbno = be32_to_cpu(*XFS_ALLOC_PTR_ADDR(block, keyno, cur));
#ifdef DEBUG
if ((error = xfs_btree_check_sptr(cur, agbno, level)))
return error;
@@ -1124,8 +1123,8 @@ xfs_alloc_lookup(
* not the last block, we're in the wrong block.
*/
if (dir == XFS_LOOKUP_GE &&
- keyno > INT_GET(block->bb_numrecs, ARCH_CONVERT) &&
- INT_GET(block->bb_rightsib, ARCH_CONVERT) != NULLAGBLOCK) {
+ keyno > be16_to_cpu(block->bb_numrecs) &&
+ be32_to_cpu(block->bb_rightsib) != NULLAGBLOCK) {
int i;
cur->bc_ptrs[0] = keyno;
@@ -1142,7 +1141,7 @@ xfs_alloc_lookup(
/*
* Return if we succeeded or not.
*/
- if (keyno == 0 || keyno > INT_GET(block->bb_numrecs, ARCH_CONVERT))
+ if (keyno == 0 || keyno > be16_to_cpu(block->bb_numrecs))
*stat = 0;
else
*stat = ((dir != XFS_LOOKUP_EQ) || (diff == 0));
@@ -1185,7 +1184,7 @@ xfs_alloc_lshift(
/*
* If we've got no left sibling then we can't shift an entry left.
*/
- if (INT_GET(right->bb_leftsib, ARCH_CONVERT) == NULLAGBLOCK) {
+ if (be32_to_cpu(right->bb_leftsib) == NULLAGBLOCK) {
*stat = 0;
return 0;
}
@@ -1201,8 +1200,8 @@ xfs_alloc_lshift(
* Set up the left neighbor as "left".
*/
if ((error = xfs_btree_read_bufs(cur->bc_mp, cur->bc_tp,
- cur->bc_private.a.agno, INT_GET(right->bb_leftsib, ARCH_CONVERT), 0, &lbp,
- XFS_ALLOC_BTREE_REF)))
+ cur->bc_private.a.agno, be32_to_cpu(right->bb_leftsib),
+ 0, &lbp, XFS_ALLOC_BTREE_REF)))
return error;
left = XFS_BUF_TO_ALLOC_BLOCK(lbp);
if ((error = xfs_btree_check_sblock(cur, left, level, lbp)))
@@ -1210,11 +1209,11 @@ xfs_alloc_lshift(
/*
* If it's full, it can't take another entry.
*/
- if (INT_GET(left->bb_numrecs, ARCH_CONVERT) == XFS_ALLOC_BLOCK_MAXRECS(level, cur)) {
+ if (be16_to_cpu(left->bb_numrecs) == XFS_ALLOC_BLOCK_MAXRECS(level, cur)) {
*stat = 0;
return 0;
}
- nrec = INT_GET(left->bb_numrecs, ARCH_CONVERT) + 1;
+ nrec = be16_to_cpu(left->bb_numrecs) + 1;
/*
* If non-leaf, copy a key and a ptr to the left block.
*/
@@ -1229,7 +1228,7 @@ xfs_alloc_lshift(
lpp = XFS_ALLOC_PTR_ADDR(left, nrec, cur);
rpp = XFS_ALLOC_PTR_ADDR(right, 1, cur);
#ifdef DEBUG
- if ((error = xfs_btree_check_sptr(cur, INT_GET(*rpp, ARCH_CONVERT), level)))
+ if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(*rpp), level)))
return error;
#endif
*lpp = *rpp; /* INT_: copy */
@@ -1251,30 +1250,30 @@ xfs_alloc_lshift(
/*
* Bump and log left's numrecs, decrement and log right's numrecs.
*/
- INT_MOD(left->bb_numrecs, ARCH_CONVERT, +1);
+ be16_add(&left->bb_numrecs, 1);
xfs_alloc_log_block(cur->bc_tp, lbp, XFS_BB_NUMRECS);
- INT_MOD(right->bb_numrecs, ARCH_CONVERT, -1);
+ be16_add(&right->bb_numrecs, -1);
xfs_alloc_log_block(cur->bc_tp, rbp, XFS_BB_NUMRECS);
/*
* Slide the contents of right down one entry.
*/
if (level > 0) {
#ifdef DEBUG
- for (i = 0; i < INT_GET(right->bb_numrecs, ARCH_CONVERT); i++) {
- if ((error = xfs_btree_check_sptr(cur, INT_GET(rpp[i + 1], ARCH_CONVERT),
+ for (i = 0; i < be16_to_cpu(right->bb_numrecs); i++) {
+ if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(rpp[i + 1]),
level)))
return error;
}
#endif
- memmove(rkp, rkp + 1, INT_GET(right->bb_numrecs, ARCH_CONVERT) * sizeof(*rkp));
- memmove(rpp, rpp + 1, INT_GET(right->bb_numrecs, ARCH_CONVERT) * sizeof(*rpp));
- xfs_alloc_log_keys(cur, rbp, 1, INT_GET(right->bb_numrecs, ARCH_CONVERT));
- xfs_alloc_log_ptrs(cur, rbp, 1, INT_GET(right->bb_numrecs, ARCH_CONVERT));
+ memmove(rkp, rkp + 1, be16_to_cpu(right->bb_numrecs) * sizeof(*rkp));
+ memmove(rpp, rpp + 1, be16_to_cpu(right->bb_numrecs) * sizeof(*rpp));
+ xfs_alloc_log_keys(cur, rbp, 1, be16_to_cpu(right->bb_numrecs));
+ xfs_alloc_log_ptrs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs));
} else {
- memmove(rrp, rrp + 1, INT_GET(right->bb_numrecs, ARCH_CONVERT) * sizeof(*rrp));
- xfs_alloc_log_recs(cur, rbp, 1, INT_GET(right->bb_numrecs, ARCH_CONVERT));
- key.ar_startblock = rrp->ar_startblock; /* INT_: direct copy */
- key.ar_blockcount = rrp->ar_blockcount; /* INT_: direct copy */
+ memmove(rrp, rrp + 1, be16_to_cpu(right->bb_numrecs) * sizeof(*rrp));
+ xfs_alloc_log_recs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs));
+ key.ar_startblock = rrp->ar_startblock;
+ key.ar_blockcount = rrp->ar_blockcount;
rkp = &key;
}
/*
@@ -1339,9 +1338,9 @@ xfs_alloc_newroot(
xfs_agnumber_t seqno;
agf = XFS_BUF_TO_AGF(cur->bc_private.a.agbp);
- INT_SET(agf->agf_roots[cur->bc_btnum], ARCH_CONVERT, nbno);
- INT_MOD(agf->agf_levels[cur->bc_btnum], ARCH_CONVERT, 1);
- seqno = INT_GET(agf->agf_seqno, ARCH_CONVERT);
+ agf->agf_roots[cur->bc_btnum] = cpu_to_be32(nbno);
+ be32_add(&agf->agf_levels[cur->bc_btnum], 1);
+ seqno = be32_to_cpu(agf->agf_seqno);
mp->m_perag[seqno].pagf_levels[cur->bc_btnum]++;
xfs_alloc_log_agf(cur->bc_tp, cur->bc_private.a.agbp,
XFS_AGF_ROOTS | XFS_AGF_LEVELS);
@@ -1358,12 +1357,12 @@ xfs_alloc_newroot(
if ((error = xfs_btree_check_sblock(cur, left, cur->bc_nlevels - 1, lbp)))
return error;
#endif
- if (INT_GET(left->bb_rightsib, ARCH_CONVERT) != NULLAGBLOCK) {
+ if (be32_to_cpu(left->bb_rightsib) != NULLAGBLOCK) {
/*
* Our block is left, pick up the right block.
*/
lbno = XFS_DADDR_TO_AGBNO(mp, XFS_BUF_ADDR(lbp));
- rbno = INT_GET(left->bb_rightsib, ARCH_CONVERT);
+ rbno = be32_to_cpu(left->bb_rightsib);
if ((error = xfs_btree_read_bufs(mp, cur->bc_tp,
cur->bc_private.a.agno, rbno, 0, &rbp,
XFS_ALLOC_BTREE_REF)))
@@ -1380,7 +1379,7 @@ xfs_alloc_newroot(
rbp = lbp;
right = left;
rbno = XFS_DADDR_TO_AGBNO(mp, XFS_BUF_ADDR(rbp));
- lbno = INT_GET(right->bb_leftsib, ARCH_CONVERT);
+ lbno = be32_to_cpu(right->bb_leftsib);
if ((error = xfs_btree_read_bufs(mp, cur->bc_tp,
cur->bc_private.a.agno, lbno, 0, &lbp,
XFS_ALLOC_BTREE_REF)))
@@ -1394,11 +1393,11 @@ xfs_alloc_newroot(
/*
* Fill in the new block's btree header and log it.
*/
- INT_SET(new->bb_magic, ARCH_CONVERT, xfs_magics[cur->bc_btnum]);
- INT_SET(new->bb_level, ARCH_CONVERT, (__uint16_t)cur->bc_nlevels);
- INT_SET(new->bb_numrecs, ARCH_CONVERT, 2);
- INT_SET(new->bb_leftsib, ARCH_CONVERT, NULLAGBLOCK);
- INT_SET(new->bb_rightsib, ARCH_CONVERT, NULLAGBLOCK);
+ new->bb_magic = cpu_to_be32(xfs_magics[cur->bc_btnum]);
+ new->bb_level = cpu_to_be16(cur->bc_nlevels);
+ new->bb_numrecs = cpu_to_be16(2);
+ new->bb_leftsib = cpu_to_be32(NULLAGBLOCK);
+ new->bb_rightsib = cpu_to_be32(NULLAGBLOCK);
xfs_alloc_log_block(cur->bc_tp, nbp, XFS_BB_ALL_BITS);
ASSERT(lbno != NULLAGBLOCK && rbno != NULLAGBLOCK);
/*
@@ -1408,18 +1407,18 @@ xfs_alloc_newroot(
xfs_alloc_key_t *kp; /* btree key pointer */
kp = XFS_ALLOC_KEY_ADDR(new, 1, cur);
- if (INT_GET(left->bb_level, ARCH_CONVERT) > 0) {
+ if (be16_to_cpu(left->bb_level) > 0) {
kp[0] = *XFS_ALLOC_KEY_ADDR(left, 1, cur); /* INT_: structure copy */
kp[1] = *XFS_ALLOC_KEY_ADDR(right, 1, cur);/* INT_: structure copy */
} else {
xfs_alloc_rec_t *rp; /* btree record pointer */
rp = XFS_ALLOC_REC_ADDR(left, 1, cur);
- kp[0].ar_startblock = rp->ar_startblock; /* INT_: direct copy */
- kp[0].ar_blockcount = rp->ar_blockcount; /* INT_: direct copy */
+ kp[0].ar_startblock = rp->ar_startblock;
+ kp[0].ar_blockcount = rp->ar_blockcount;
rp = XFS_ALLOC_REC_ADDR(right, 1, cur);
- kp[1].ar_startblock = rp->ar_startblock; /* INT_: direct copy */
- kp[1].ar_blockcount = rp->ar_blockcount; /* INT_: direct copy */
+ kp[1].ar_startblock = rp->ar_startblock;
+ kp[1].ar_blockcount = rp->ar_blockcount;
}
}
xfs_alloc_log_keys(cur, nbp, 1, 2);
@@ -1430,8 +1429,8 @@ xfs_alloc_newroot(
xfs_alloc_ptr_t *pp; /* btree address pointer */
pp = XFS_ALLOC_PTR_ADDR(new, 1, cur);
- INT_SET(pp[0], ARCH_CONVERT, lbno);
- INT_SET(pp[1], ARCH_CONVERT, rbno);
+ pp[0] = cpu_to_be32(lbno);
+ pp[1] = cpu_to_be32(rbno);
}
xfs_alloc_log_ptrs(cur, nbp, 1, 2);
/*
@@ -1476,7 +1475,7 @@ xfs_alloc_rshift(
/*
* If we've got no right sibling then we can't shift an entry right.
*/
- if (INT_GET(left->bb_rightsib, ARCH_CONVERT) == NULLAGBLOCK) {
+ if (be32_to_cpu(left->bb_rightsib) == NULLAGBLOCK) {
*stat = 0;
return 0;
}
@@ -1484,7 +1483,7 @@ xfs_alloc_rshift(
* If the cursor entry is the one that would be moved, don't
* do it... it's too complicated.
*/
- if (cur->bc_ptrs[level] >= INT_GET(left->bb_numrecs, ARCH_CONVERT)) {
+ if (cur->bc_ptrs[level] >= be16_to_cpu(left->bb_numrecs)) {
*stat = 0;
return 0;
}
@@ -1492,8 +1491,8 @@ xfs_alloc_rshift(
* Set up the right neighbor as "right".
*/
if ((error = xfs_btree_read_bufs(cur->bc_mp, cur->bc_tp,
- cur->bc_private.a.agno, INT_GET(left->bb_rightsib, ARCH_CONVERT), 0, &rbp,
- XFS_ALLOC_BTREE_REF)))
+ cur->bc_private.a.agno, be32_to_cpu(left->bb_rightsib),
+ 0, &rbp, XFS_ALLOC_BTREE_REF)))
return error;
right = XFS_BUF_TO_ALLOC_BLOCK(rbp);
if ((error = xfs_btree_check_sblock(cur, right, level, rbp)))
@@ -1501,7 +1500,7 @@ xfs_alloc_rshift(
/*
* If it's full, it can't take another entry.
*/
- if (INT_GET(right->bb_numrecs, ARCH_CONVERT) == XFS_ALLOC_BLOCK_MAXRECS(level, cur)) {
+ if (be16_to_cpu(right->bb_numrecs) == XFS_ALLOC_BLOCK_MAXRECS(level, cur)) {
*stat = 0;
return 0;
}
@@ -1514,47 +1513,47 @@ xfs_alloc_rshift(
xfs_alloc_ptr_t *lpp; /* address pointer for left block */
xfs_alloc_ptr_t *rpp; /* address pointer for right block */
- lkp = XFS_ALLOC_KEY_ADDR(left, INT_GET(left->bb_numrecs, ARCH_CONVERT), cur);
- lpp = XFS_ALLOC_PTR_ADDR(left, INT_GET(left->bb_numrecs, ARCH_CONVERT), cur);
+ lkp = XFS_ALLOC_KEY_ADDR(left, be16_to_cpu(left->bb_numrecs), cur);
+ lpp = XFS_ALLOC_PTR_ADDR(left, be16_to_cpu(left->bb_numrecs), cur);
rkp = XFS_ALLOC_KEY_ADDR(right, 1, cur);
rpp = XFS_ALLOC_PTR_ADDR(right, 1, cur);
#ifdef DEBUG
- for (i = INT_GET(right->bb_numrecs, ARCH_CONVERT) - 1; i >= 0; i--) {
- if ((error = xfs_btree_check_sptr(cur, INT_GET(rpp[i], ARCH_CONVERT), level)))
+ for (i = be16_to_cpu(right->bb_numrecs) - 1; i >= 0; i--) {
+ if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(rpp[i]), level)))
return error;
}
#endif
- memmove(rkp + 1, rkp, INT_GET(right->bb_numrecs, ARCH_CONVERT) * sizeof(*rkp));
- memmove(rpp + 1, rpp, INT_GET(right->bb_numrecs, ARCH_CONVERT) * sizeof(*rpp));
+ memmove(rkp + 1, rkp, be16_to_cpu(right->bb_numrecs) * sizeof(*rkp));
+ memmove(rpp + 1, rpp, be16_to_cpu(right->bb_numrecs) * sizeof(*rpp));
#ifdef DEBUG
- if ((error = xfs_btree_check_sptr(cur, INT_GET(*lpp, ARCH_CONVERT), level)))
+ if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(*lpp), level)))
return error;
#endif
*rkp = *lkp; /* INT_: copy */
*rpp = *lpp; /* INT_: copy */
- xfs_alloc_log_keys(cur, rbp, 1, INT_GET(right->bb_numrecs, ARCH_CONVERT) + 1);
- xfs_alloc_log_ptrs(cur, rbp, 1, INT_GET(right->bb_numrecs, ARCH_CONVERT) + 1);
+ xfs_alloc_log_keys(cur, rbp, 1, be16_to_cpu(right->bb_numrecs) + 1);
+ xfs_alloc_log_ptrs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs) + 1);
xfs_btree_check_key(cur->bc_btnum, rkp, rkp + 1);
} else {
xfs_alloc_rec_t *lrp; /* record pointer for left block */
xfs_alloc_rec_t *rrp; /* record pointer for right block */
- lrp = XFS_ALLOC_REC_ADDR(left, INT_GET(left->bb_numrecs, ARCH_CONVERT), cur);
+ lrp = XFS_ALLOC_REC_ADDR(left, be16_to_cpu(left->bb_numrecs), cur);
rrp = XFS_ALLOC_REC_ADDR(right, 1, cur);
- memmove(rrp + 1, rrp, INT_GET(right->bb_numrecs, ARCH_CONVERT) * sizeof(*rrp));
+ memmove(rrp + 1, rrp, be16_to_cpu(right->bb_numrecs) * sizeof(*rrp));
*rrp = *lrp;
- xfs_alloc_log_recs(cur, rbp, 1, INT_GET(right->bb_numrecs, ARCH_CONVERT) + 1);
- key.ar_startblock = rrp->ar_startblock; /* INT_: direct copy */
- key.ar_blockcount = rrp->ar_blockcount; /* INT_: direct copy */
+ xfs_alloc_log_recs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs) + 1);
+ key.ar_startblock = rrp->ar_startblock;
+ key.ar_blockcount = rrp->ar_blockcount;
rkp = &key;
xfs_btree_check_rec(cur->bc_btnum, rrp, rrp + 1);
}
/*
* Decrement and log left's numrecs, bump and log right's numrecs.
*/
- INT_MOD(left->bb_numrecs, ARCH_CONVERT, -1);
+ be16_add(&left->bb_numrecs, -1);
xfs_alloc_log_block(cur->bc_tp, lbp, XFS_BB_NUMRECS);
- INT_MOD(right->bb_numrecs, ARCH_CONVERT, +1);
+ be16_add(&right->bb_numrecs, 1);
xfs_alloc_log_block(cur->bc_tp, rbp, XFS_BB_NUMRECS);
/*
* Using a temporary cursor, update the parent key values of the
@@ -1627,17 +1626,17 @@ xfs_alloc_split(
/*
* Fill in the btree header for the new block.
*/
- INT_SET(right->bb_magic, ARCH_CONVERT, xfs_magics[cur->bc_btnum]);
- right->bb_level = left->bb_level; /* INT_: direct copy */
- INT_SET(right->bb_numrecs, ARCH_CONVERT, (__uint16_t)(INT_GET(left->bb_numrecs, ARCH_CONVERT) / 2));
+ right->bb_magic = cpu_to_be32(xfs_magics[cur->bc_btnum]);
+ right->bb_level = left->bb_level;
+ right->bb_numrecs = cpu_to_be16(be16_to_cpu(left->bb_numrecs) / 2);
/*
* Make sure that if there's an odd number of entries now, that
* each new block will have the same number of entries.
*/
- if ((INT_GET(left->bb_numrecs, ARCH_CONVERT) & 1) &&
- cur->bc_ptrs[level] <= INT_GET(right->bb_numrecs, ARCH_CONVERT) + 1)
- INT_MOD(right->bb_numrecs, ARCH_CONVERT, +1);
- i = INT_GET(left->bb_numrecs, ARCH_CONVERT) - INT_GET(right->bb_numrecs, ARCH_CONVERT) + 1;
+ if ((be16_to_cpu(left->bb_numrecs) & 1) &&
+ cur->bc_ptrs[level] <= be16_to_cpu(right->bb_numrecs) + 1)
+ be16_add(&right->bb_numrecs, 1);
+ i = be16_to_cpu(left->bb_numrecs) - be16_to_cpu(right->bb_numrecs) + 1;
/*
* For non-leaf blocks, copy keys and addresses over to the new block.
*/
@@ -1652,15 +1651,15 @@ xfs_alloc_split(
rkp = XFS_ALLOC_KEY_ADDR(right, 1, cur);
rpp = XFS_ALLOC_PTR_ADDR(right, 1, cur);
#ifdef DEBUG
- for (i = 0; i < INT_GET(right->bb_numrecs, ARCH_CONVERT); i++) {
- if ((error = xfs_btree_check_sptr(cur, INT_GET(lpp[i], ARCH_CONVERT), level)))
+ for (i = 0; i < be16_to_cpu(right->bb_numrecs); i++) {
+ if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(lpp[i]), level)))
return error;
}
#endif
- memcpy(rkp, lkp, INT_GET(right->bb_numrecs, ARCH_CONVERT) * sizeof(*rkp)); /* INT_: copy */
- memcpy(rpp, lpp, INT_GET(right->bb_numrecs, ARCH_CONVERT) * sizeof(*rpp)); /* INT_: copy */
- xfs_alloc_log_keys(cur, rbp, 1, INT_GET(right->bb_numrecs, ARCH_CONVERT));
- xfs_alloc_log_ptrs(cur, rbp, 1, INT_GET(right->bb_numrecs, ARCH_CONVERT));
+ memcpy(rkp, lkp, be16_to_cpu(right->bb_numrecs) * sizeof(*rkp));
+ memcpy(rpp, lpp, be16_to_cpu(right->bb_numrecs) * sizeof(*rpp));
+ xfs_alloc_log_keys(cur, rbp, 1, be16_to_cpu(right->bb_numrecs));
+ xfs_alloc_log_ptrs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs));
*keyp = *rkp;
}
/*
@@ -1672,38 +1671,38 @@ xfs_alloc_split(
lrp = XFS_ALLOC_REC_ADDR(left, i, cur);
rrp = XFS_ALLOC_REC_ADDR(right, 1, cur);
- memcpy(rrp, lrp, INT_GET(right->bb_numrecs, ARCH_CONVERT) * sizeof(*rrp));
- xfs_alloc_log_recs(cur, rbp, 1, INT_GET(right->bb_numrecs, ARCH_CONVERT));
- keyp->ar_startblock = rrp->ar_startblock; /* INT_: direct copy */
- keyp->ar_blockcount = rrp->ar_blockcount; /* INT_: direct copy */
+ memcpy(rrp, lrp, be16_to_cpu(right->bb_numrecs) * sizeof(*rrp));
+ xfs_alloc_log_recs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs));
+ keyp->ar_startblock = rrp->ar_startblock;
+ keyp->ar_blockcount = rrp->ar_blockcount;
}
/*
* Find the left block number by looking in the buffer.
* Adjust numrecs, sibling pointers.
*/
lbno = XFS_DADDR_TO_AGBNO(cur->bc_mp, XFS_BUF_ADDR(lbp));
- INT_MOD(left->bb_numrecs, ARCH_CONVERT, -(INT_GET(right->bb_numrecs, ARCH_CONVERT)));
- right->bb_rightsib = left->bb_rightsib; /* INT_: direct copy */
- INT_SET(left->bb_rightsib, ARCH_CONVERT, rbno);
- INT_SET(right->bb_leftsib, ARCH_CONVERT, lbno);
+ be16_add(&left->bb_numrecs, -(be16_to_cpu(right->bb_numrecs)));
+ right->bb_rightsib = left->bb_rightsib;
+ left->bb_rightsib = cpu_to_be32(rbno);
+ right->bb_leftsib = cpu_to_be32(lbno);
xfs_alloc_log_block(cur->bc_tp, rbp, XFS_BB_ALL_BITS);
xfs_alloc_log_block(cur->bc_tp, lbp, XFS_BB_NUMRECS | XFS_BB_RIGHTSIB);
/*
* If there's a block to the new block's right, make that block
* point back to right instead of to left.
*/
- if (INT_GET(right->bb_rightsib, ARCH_CONVERT) != NULLAGBLOCK) {
+ if (be32_to_cpu(right->bb_rightsib) != NULLAGBLOCK) {
xfs_alloc_block_t *rrblock; /* rr btree block */
xfs_buf_t *rrbp; /* buffer for rrblock */
if ((error = xfs_btree_read_bufs(cur->bc_mp, cur->bc_tp,
- cur->bc_private.a.agno, INT_GET(right->bb_rightsib, ARCH_CONVERT), 0,
+ cur->bc_private.a.agno, be32_to_cpu(right->bb_rightsib), 0,
&rrbp, XFS_ALLOC_BTREE_REF)))
return error;
rrblock = XFS_BUF_TO_ALLOC_BLOCK(rrbp);
if ((error = xfs_btree_check_sblock(cur, rrblock, level, rrbp)))
return error;
- INT_SET(rrblock->bb_leftsib, ARCH_CONVERT, rbno);
+ rrblock->bb_leftsib = cpu_to_be32(rbno);
xfs_alloc_log_block(cur->bc_tp, rrbp, XFS_BB_LEFTSIB);
}
/*
@@ -1711,9 +1710,9 @@ xfs_alloc_split(
* If it's just pointing past the last entry in left, then we'll
* insert there, so don't change anything in that case.
*/
- if (cur->bc_ptrs[level] > INT_GET(left->bb_numrecs, ARCH_CONVERT) + 1) {
+ if (cur->bc_ptrs[level] > be16_to_cpu(left->bb_numrecs) + 1) {
xfs_btree_setbuf(cur, level, rbp);
- cur->bc_ptrs[level] -= INT_GET(left->bb_numrecs, ARCH_CONVERT);
+ cur->bc_ptrs[level] -= be16_to_cpu(left->bb_numrecs);
}
/*
* If there are more levels, we'll need another cursor which refers to
@@ -1811,7 +1810,7 @@ xfs_alloc_decrement(
/*
* If we just went off the left edge of the tree, return failure.
*/
- if (INT_GET(block->bb_leftsib, ARCH_CONVERT) == NULLAGBLOCK) {
+ if (be32_to_cpu(block->bb_leftsib) == NULLAGBLOCK) {
*stat = 0;
return 0;
}
@@ -1840,7 +1839,7 @@ xfs_alloc_decrement(
xfs_agblock_t agbno; /* block number of btree block */
xfs_buf_t *bp; /* buffer pointer for block */
- agbno = INT_GET(*XFS_ALLOC_PTR_ADDR(block, cur->bc_ptrs[lev], cur), ARCH_CONVERT);
+ agbno = be32_to_cpu(*XFS_ALLOC_PTR_ADDR(block, cur->bc_ptrs[lev], cur));
if ((error = xfs_btree_read_bufs(cur->bc_mp, cur->bc_tp,
cur->bc_private.a.agno, agbno, 0, &bp,
XFS_ALLOC_BTREE_REF)))
@@ -1850,7 +1849,7 @@ xfs_alloc_decrement(
block = XFS_BUF_TO_ALLOC_BLOCK(bp);
if ((error = xfs_btree_check_sblock(cur, block, lev, bp)))
return error;
- cur->bc_ptrs[lev] = INT_GET(block->bb_numrecs, ARCH_CONVERT);
+ cur->bc_ptrs[lev] = be16_to_cpu(block->bb_numrecs);
}
*stat = 1;
return 0;
@@ -1917,7 +1916,7 @@ xfs_alloc_get_rec(
/*
* Off the right end or left end, return failure.
*/
- if (ptr > INT_GET(block->bb_numrecs, ARCH_CONVERT) || ptr <= 0) {
+ if (ptr > be16_to_cpu(block->bb_numrecs) || ptr <= 0) {
*stat = 0;
return 0;
}
@@ -1928,8 +1927,8 @@ xfs_alloc_get_rec(
xfs_alloc_rec_t *rec; /* record data */
rec = XFS_ALLOC_REC_ADDR(block, ptr, cur);
- *bno = INT_GET(rec->ar_startblock, ARCH_CONVERT);
- *len = INT_GET(rec->ar_blockcount, ARCH_CONVERT);
+ *bno = be32_to_cpu(rec->ar_startblock);
+ *len = be32_to_cpu(rec->ar_blockcount);
}
*stat = 1;
return 0;
@@ -1968,14 +1967,14 @@ xfs_alloc_increment(
* Increment the ptr at this level. If we're still in the block
* then we're done.
*/
- if (++cur->bc_ptrs[level] <= INT_GET(block->bb_numrecs, ARCH_CONVERT)) {
+ if (++cur->bc_ptrs[level] <= be16_to_cpu(block->bb_numrecs)) {
*stat = 1;
return 0;
}
/*
* If we just went off the right edge of the tree, return failure.
*/
- if (INT_GET(block->bb_rightsib, ARCH_CONVERT) == NULLAGBLOCK) {
+ if (be32_to_cpu(block->bb_rightsib) == NULLAGBLOCK) {
*stat = 0;
return 0;
}
@@ -1990,7 +1989,7 @@ xfs_alloc_increment(
if ((error = xfs_btree_check_sblock(cur, block, lev, bp)))
return error;
#endif
- if (++cur->bc_ptrs[lev] <= INT_GET(block->bb_numrecs, ARCH_CONVERT))
+ if (++cur->bc_ptrs[lev] <= be16_to_cpu(block->bb_numrecs))
break;
/*
* Read-ahead the right block, we're going to read it
@@ -2010,7 +2009,7 @@ xfs_alloc_increment(
lev > level; ) {
xfs_agblock_t agbno; /* block number of btree block */
- agbno = INT_GET(*XFS_ALLOC_PTR_ADDR(block, cur->bc_ptrs[lev], cur), ARCH_CONVERT);
+ agbno = be32_to_cpu(*XFS_ALLOC_PTR_ADDR(block, cur->bc_ptrs[lev], cur));
if ((error = xfs_btree_read_bufs(cur->bc_mp, cur->bc_tp,
cur->bc_private.a.agno, agbno, 0, &bp,
XFS_ALLOC_BTREE_REF)))
@@ -2045,8 +2044,8 @@ xfs_alloc_insert(
level = 0;
nbno = NULLAGBLOCK;
- INT_SET(nrec.ar_startblock, ARCH_CONVERT, cur->bc_rec.a.ar_startblock);
- INT_SET(nrec.ar_blockcount, ARCH_CONVERT, cur->bc_rec.a.ar_blockcount);
+ nrec.ar_startblock = cpu_to_be32(cur->bc_rec.a.ar_startblock);
+ nrec.ar_blockcount = cpu_to_be32(cur->bc_rec.a.ar_blockcount);
ncur = (xfs_btree_cur_t *)0;
pcur = cur;
/*
@@ -2167,8 +2166,8 @@ xfs_alloc_update(
/*
* Fill in the new contents and log them.
*/
- INT_SET(rp->ar_startblock, ARCH_CONVERT, bno);
- INT_SET(rp->ar_blockcount, ARCH_CONVERT, len);
+ rp->ar_startblock = cpu_to_be32(bno);
+ rp->ar_blockcount = cpu_to_be32(len);
xfs_alloc_log_recs(cur, cur->bc_bufs[0], ptr, ptr);
}
/*
@@ -2177,15 +2176,15 @@ xfs_alloc_update(
* extent in the a.g., which we cache in the a.g. freelist header.
*/
if (cur->bc_btnum == XFS_BTNUM_CNT &&
- INT_GET(block->bb_rightsib, ARCH_CONVERT) == NULLAGBLOCK &&
- ptr == INT_GET(block->bb_numrecs, ARCH_CONVERT)) {
+ be32_to_cpu(block->bb_rightsib) == NULLAGBLOCK &&
+ ptr == be16_to_cpu(block->bb_numrecs)) {
xfs_agf_t *agf; /* a.g. freespace header */
xfs_agnumber_t seqno;
agf = XFS_BUF_TO_AGF(cur->bc_private.a.agbp);
- seqno = INT_GET(agf->agf_seqno, ARCH_CONVERT);
+ seqno = be32_to_cpu(agf->agf_seqno);
cur->bc_mp->m_perag[seqno].pagf_longest = len;
- INT_SET(agf->agf_longest, ARCH_CONVERT, len);
+ agf->agf_longest = cpu_to_be32(len);
xfs_alloc_log_agf(cur->bc_tp, cur->bc_private.a.agbp,
XFS_AGF_LONGEST);
}
@@ -2195,8 +2194,8 @@ xfs_alloc_update(
if (ptr == 1) {
xfs_alloc_key_t key; /* key containing [bno, len] */
- INT_SET(key.ar_startblock, ARCH_CONVERT, bno);
- INT_SET(key.ar_blockcount, ARCH_CONVERT, len);
+ key.ar_startblock = cpu_to_be32(bno);
+ key.ar_blockcount = cpu_to_be32(len);
if ((error = xfs_alloc_updkey(cur, &key, 1)))
return error;
}
diff --git a/fs/xfs/xfs_alloc_btree.h b/fs/xfs/xfs_alloc_btree.h
index ed5161a572ef..bce81c7a4fdc 100644
--- a/fs/xfs/xfs_alloc_btree.h
+++ b/fs/xfs/xfs_alloc_btree.h
@@ -1,33 +1,19 @@
/*
- * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000,2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __XFS_ALLOC_BTREE_H__
#define __XFS_ALLOC_BTREE_H__
@@ -52,48 +38,29 @@ struct xfs_mount;
/*
* Data record/key structure
*/
-typedef struct xfs_alloc_rec
-{
+typedef struct xfs_alloc_rec {
+ __be32 ar_startblock; /* starting block number */
+ __be32 ar_blockcount; /* count of free blocks */
+} xfs_alloc_rec_t, xfs_alloc_key_t;
+
+typedef struct xfs_alloc_rec_incore {
xfs_agblock_t ar_startblock; /* starting block number */
xfs_extlen_t ar_blockcount; /* count of free blocks */
-} xfs_alloc_rec_t, xfs_alloc_key_t;
+} xfs_alloc_rec_incore_t;
-typedef xfs_agblock_t xfs_alloc_ptr_t; /* btree pointer type */
- /* btree block header type */
+/* btree pointer type */
+typedef __be32 xfs_alloc_ptr_t;
+/* btree block header type */
typedef struct xfs_btree_sblock xfs_alloc_block_t;
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_BUF_TO_ALLOC_BLOCK)
-xfs_alloc_block_t *xfs_buf_to_alloc_block(struct xfs_buf *bp);
-#define XFS_BUF_TO_ALLOC_BLOCK(bp) xfs_buf_to_alloc_block(bp)
-#else
-#define XFS_BUF_TO_ALLOC_BLOCK(bp) ((xfs_alloc_block_t *)(XFS_BUF_PTR(bp)))
-#endif
+#define XFS_BUF_TO_ALLOC_BLOCK(bp) ((xfs_alloc_block_t *)XFS_BUF_PTR(bp))
/*
* Real block structures have a size equal to the disk block size.
*/
-
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_ALLOC_BLOCK_SIZE)
-int xfs_alloc_block_size(int lev, struct xfs_btree_cur *cur);
-#define XFS_ALLOC_BLOCK_SIZE(lev,cur) xfs_alloc_block_size(lev,cur)
-#else
#define XFS_ALLOC_BLOCK_SIZE(lev,cur) (1 << (cur)->bc_blocklog)
-#endif
-
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_ALLOC_BLOCK_MAXRECS)
-int xfs_alloc_block_maxrecs(int lev, struct xfs_btree_cur *cur);
-#define XFS_ALLOC_BLOCK_MAXRECS(lev,cur) xfs_alloc_block_maxrecs(lev,cur)
-#else
-#define XFS_ALLOC_BLOCK_MAXRECS(lev,cur) \
- ((cur)->bc_mp->m_alloc_mxr[lev != 0])
-#endif
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_ALLOC_BLOCK_MINRECS)
-int xfs_alloc_block_minrecs(int lev, struct xfs_btree_cur *cur);
-#define XFS_ALLOC_BLOCK_MINRECS(lev,cur) xfs_alloc_block_minrecs(lev,cur)
-#else
-#define XFS_ALLOC_BLOCK_MINRECS(lev,cur) \
- ((cur)->bc_mp->m_alloc_mnr[lev != 0])
-#endif
+#define XFS_ALLOC_BLOCK_MAXRECS(lev,cur) ((cur)->bc_mp->m_alloc_mxr[lev != 0])
+#define XFS_ALLOC_BLOCK_MINRECS(lev,cur) ((cur)->bc_mp->m_alloc_mnr[lev != 0])
/*
* Minimum and maximum blocksize and sectorsize.
@@ -113,145 +80,80 @@ int xfs_alloc_block_minrecs(int lev, struct xfs_btree_cur *cur);
* Block numbers in the AG:
* SB is sector 0, AGF is sector 1, AGI is sector 2, AGFL is sector 3.
*/
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_BNO_BLOCK)
-xfs_agblock_t xfs_bno_block(struct xfs_mount *mp);
-#define XFS_BNO_BLOCK(mp) xfs_bno_block(mp)
-#else
#define XFS_BNO_BLOCK(mp) ((xfs_agblock_t)(XFS_AGFL_BLOCK(mp) + 1))
-#endif
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_CNT_BLOCK)
-xfs_agblock_t xfs_cnt_block(struct xfs_mount *mp);
-#define XFS_CNT_BLOCK(mp) xfs_cnt_block(mp)
-#else
#define XFS_CNT_BLOCK(mp) ((xfs_agblock_t)(XFS_BNO_BLOCK(mp) + 1))
-#endif
/*
* Record, key, and pointer address macros for btree blocks.
*/
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_ALLOC_REC_ADDR)
-xfs_alloc_rec_t *xfs_alloc_rec_addr(xfs_alloc_block_t *bb, int i,
- struct xfs_btree_cur *cur);
-#define XFS_ALLOC_REC_ADDR(bb,i,cur) xfs_alloc_rec_addr(bb,i,cur)
-#else
#define XFS_ALLOC_REC_ADDR(bb,i,cur) \
- XFS_BTREE_REC_ADDR(XFS_ALLOC_BLOCK_SIZE(0,cur), xfs_alloc, bb, i, \
- XFS_ALLOC_BLOCK_MAXRECS(0, cur))
-#endif
+ XFS_BTREE_REC_ADDR(XFS_ALLOC_BLOCK_SIZE(0,cur), xfs_alloc, \
+ bb, i, XFS_ALLOC_BLOCK_MAXRECS(0, cur))
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_ALLOC_KEY_ADDR)
-xfs_alloc_key_t *xfs_alloc_key_addr(xfs_alloc_block_t *bb, int i,
- struct xfs_btree_cur *cur);
-#define XFS_ALLOC_KEY_ADDR(bb,i,cur) xfs_alloc_key_addr(bb,i,cur)
-#else
#define XFS_ALLOC_KEY_ADDR(bb,i,cur) \
- XFS_BTREE_KEY_ADDR(XFS_ALLOC_BLOCK_SIZE(1,cur), xfs_alloc, bb, i, \
- XFS_ALLOC_BLOCK_MAXRECS(1, cur))
-#endif
+ XFS_BTREE_KEY_ADDR(XFS_ALLOC_BLOCK_SIZE(1,cur), xfs_alloc, \
+ bb, i, XFS_ALLOC_BLOCK_MAXRECS(1, cur))
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_ALLOC_PTR_ADDR)
-xfs_alloc_ptr_t *xfs_alloc_ptr_addr(xfs_alloc_block_t *bb, int i,
- struct xfs_btree_cur *cur);
-#define XFS_ALLOC_PTR_ADDR(bb,i,cur) xfs_alloc_ptr_addr(bb,i,cur)
-#else
#define XFS_ALLOC_PTR_ADDR(bb,i,cur) \
- XFS_BTREE_PTR_ADDR(XFS_ALLOC_BLOCK_SIZE(1,cur), xfs_alloc, bb, i, \
- XFS_ALLOC_BLOCK_MAXRECS(1, cur))
-#endif
-
-/*
- * Prototypes for externally visible routines.
- */
+ XFS_BTREE_PTR_ADDR(XFS_ALLOC_BLOCK_SIZE(1,cur), xfs_alloc, \
+ bb, i, XFS_ALLOC_BLOCK_MAXRECS(1, cur))
/*
* Decrement cursor by one record at the level.
* For nonzero levels the leaf-ward information is untouched.
*/
-int /* error */
-xfs_alloc_decrement(
- struct xfs_btree_cur *cur, /* btree cursor */
- int level, /* level in btree, 0 is leaf */
- int *stat); /* success/failure */
+extern int xfs_alloc_decrement(struct xfs_btree_cur *cur, int level, int *stat);
/*
* Delete the record pointed to by cur.
* The cursor refers to the place where the record was (could be inserted)
* when the operation returns.
*/
-int /* error */
-xfs_alloc_delete(
- struct xfs_btree_cur *cur, /* btree cursor */
- int *stat); /* success/failure */
+extern int xfs_alloc_delete(struct xfs_btree_cur *cur, int *stat);
/*
* Get the data from the pointed-to record.
*/
-int /* error */
-xfs_alloc_get_rec(
- struct xfs_btree_cur *cur, /* btree cursor */
- xfs_agblock_t *bno, /* output: starting block of extent */
- xfs_extlen_t *len, /* output: length of extent */
- int *stat); /* output: success/failure */
+extern int xfs_alloc_get_rec(struct xfs_btree_cur *cur, xfs_agblock_t *bno,
+ xfs_extlen_t *len, int *stat);
/*
* Increment cursor by one record at the level.
* For nonzero levels the leaf-ward information is untouched.
*/
-int /* error */
-xfs_alloc_increment(
- struct xfs_btree_cur *cur, /* btree cursor */
- int level, /* level in btree, 0 is leaf */
- int *stat); /* success/failure */
+extern int xfs_alloc_increment(struct xfs_btree_cur *cur, int level, int *stat);
/*
* Insert the current record at the point referenced by cur.
* The cursor may be inconsistent on return if splits have been done.
*/
-int /* error */
-xfs_alloc_insert(
- struct xfs_btree_cur *cur, /* btree cursor */
- int *stat); /* success/failure */
+extern int xfs_alloc_insert(struct xfs_btree_cur *cur, int *stat);
/*
* Lookup the record equal to [bno, len] in the btree given by cur.
*/
-int /* error */
-xfs_alloc_lookup_eq(
- struct xfs_btree_cur *cur, /* btree cursor */
- xfs_agblock_t bno, /* starting block of extent */
- xfs_extlen_t len, /* length of extent */
- int *stat); /* success/failure */
+extern int xfs_alloc_lookup_eq(struct xfs_btree_cur *cur, xfs_agblock_t bno,
+ xfs_extlen_t len, int *stat);
/*
* Lookup the first record greater than or equal to [bno, len]
* in the btree given by cur.
*/
-int /* error */
-xfs_alloc_lookup_ge(
- struct xfs_btree_cur *cur, /* btree cursor */
- xfs_agblock_t bno, /* starting block of extent */
- xfs_extlen_t len, /* length of extent */
- int *stat); /* success/failure */
+extern int xfs_alloc_lookup_ge(struct xfs_btree_cur *cur, xfs_agblock_t bno,
+ xfs_extlen_t len, int *stat);
/*
* Lookup the first record less than or equal to [bno, len]
* in the btree given by cur.
*/
-int /* error */
-xfs_alloc_lookup_le(
- struct xfs_btree_cur *cur, /* btree cursor */
- xfs_agblock_t bno, /* starting block of extent */
- xfs_extlen_t len, /* length of extent */
- int *stat); /* success/failure */
+extern int xfs_alloc_lookup_le(struct xfs_btree_cur *cur, xfs_agblock_t bno,
+ xfs_extlen_t len, int *stat);
/*
* Update the record referred to by cur, to the value given by [bno, len].
* This either works (return 0) or gets an EFSCORRUPTED error.
*/
-int /* error */
-xfs_alloc_update(
- struct xfs_btree_cur *cur, /* btree cursor */
- xfs_agblock_t bno, /* starting block of extent */
- xfs_extlen_t len); /* length of extent */
+extern int xfs_alloc_update(struct xfs_btree_cur *cur, xfs_agblock_t bno,
+ xfs_extlen_t len);
#endif /* __XFS_ALLOC_BTREE_H__ */
diff --git a/fs/xfs/xfs_arch.h b/fs/xfs/xfs_arch.h
index 5ab0dd885b1b..68e5051d8e24 100644
--- a/fs/xfs/xfs_arch.h
+++ b/fs/xfs/xfs_arch.h
@@ -1,33 +1,19 @@
/*
- * Copyright (c) 2000-2002 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __XFS_ARCH_H__
#define __XFS_ARCH_H__
@@ -168,6 +154,21 @@
} \
}
+static inline void be16_add(__be16 *a, __s16 b)
+{
+ *a = cpu_to_be16(be16_to_cpu(*a) + b);
+}
+
+static inline void be32_add(__be32 *a, __s32 b)
+{
+ *a = cpu_to_be32(be32_to_cpu(*a) + b);
+}
+
+static inline void be64_add(__be64 *a, __s64 b)
+{
+ *a = cpu_to_be64(be64_to_cpu(*a) + b);
+}
+
/*
* In directories inode numbers are stored as unaligned arrays of unsigned
* 8bit integers on disk.
diff --git a/fs/xfs/xfs_attr.c b/fs/xfs/xfs_attr.c
index a41ad3a5e554..5484eeb460c8 100644
--- a/fs/xfs/xfs_attr.c
+++ b/fs/xfs/xfs_attr.c
@@ -1,41 +1,26 @@
/*
- * Copyright (c) 2000-2004 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-
#include "xfs.h"
-
-#include "xfs_macros.h"
+#include "xfs_fs.h"
#include "xfs_types.h"
-#include "xfs_inum.h"
+#include "xfs_bit.h"
#include "xfs_log.h"
+#include "xfs_inum.h"
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
@@ -43,27 +28,26 @@
#include "xfs_dir2.h"
#include "xfs_dmapi.h"
#include "xfs_mount.h"
-#include "xfs_alloc_btree.h"
+#include "xfs_da_btree.h"
#include "xfs_bmap_btree.h"
+#include "xfs_alloc_btree.h"
#include "xfs_ialloc_btree.h"
-#include "xfs_alloc.h"
-#include "xfs_btree.h"
-#include "xfs_attr_sf.h"
#include "xfs_dir_sf.h"
#include "xfs_dir2_sf.h"
+#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
-#include "xfs_inode_item.h"
#include "xfs_inode.h"
+#include "xfs_alloc.h"
+#include "xfs_btree.h"
+#include "xfs_inode_item.h"
#include "xfs_bmap.h"
-#include "xfs_da_btree.h"
#include "xfs_attr.h"
#include "xfs_attr_leaf.h"
#include "xfs_error.h"
-#include "xfs_bit.h"
#include "xfs_quota.h"
-#include "xfs_rw.h"
#include "xfs_trans_space.h"
#include "xfs_acl.h"
+#include "xfs_rw.h"
/*
* xfs_attr.c
@@ -122,7 +106,7 @@ ktrace_t *xfs_attr_trace_buf;
*========================================================================*/
int
-xfs_attr_fetch(xfs_inode_t *ip, char *name, int namelen,
+xfs_attr_fetch(xfs_inode_t *ip, const char *name, int namelen,
char *value, int *valuelenp, int flags, struct cred *cred)
{
xfs_da_args_t args;
@@ -177,7 +161,7 @@ xfs_attr_fetch(xfs_inode_t *ip, char *name, int namelen,
}
int
-xfs_attr_get(bhv_desc_t *bdp, char *name, char *value, int *valuelenp,
+xfs_attr_get(bhv_desc_t *bdp, const char *name, char *value, int *valuelenp,
int flags, struct cred *cred)
{
xfs_inode_t *ip = XFS_BHVTOI(bdp);
@@ -200,40 +184,18 @@ xfs_attr_get(bhv_desc_t *bdp, char *name, char *value, int *valuelenp,
return(error);
}
-/*ARGSUSED*/
-int /* error */
-xfs_attr_set(bhv_desc_t *bdp, char *name, char *value, int valuelen, int flags,
- struct cred *cred)
+STATIC int
+xfs_attr_set_int(xfs_inode_t *dp, const char *name, int namelen,
+ char *value, int valuelen, int flags)
{
xfs_da_args_t args;
- xfs_inode_t *dp;
xfs_fsblock_t firstblock;
xfs_bmap_free_t flist;
int error, err2, committed;
int local, size;
uint nblks;
- xfs_mount_t *mp;
+ xfs_mount_t *mp = dp->i_mount;
int rsvd = (flags & ATTR_ROOT) != 0;
- int namelen;
-
- namelen = strlen(name);
- if (namelen >= MAXNAMELEN)
- return EFAULT; /* match IRIX behaviour */
-
- XFS_STATS_INC(xs_attr_set);
-
- dp = XFS_BHVTOI(bdp);
- mp = dp->i_mount;
- if (XFS_FORCED_SHUTDOWN(mp))
- return (EIO);
-
- xfs_ilock(dp, XFS_ILOCK_SHARED);
- if (!(flags & ATTR_SECURE) &&
- (error = xfs_iaccess(dp, S_IWUSR, cred))) {
- xfs_iunlock(dp, XFS_ILOCK_SHARED);
- return(XFS_ERROR(error));
- }
- xfs_iunlock(dp, XFS_ILOCK_SHARED);
/*
* Attach the dquots to the inode.
@@ -242,12 +204,18 @@ xfs_attr_set(bhv_desc_t *bdp, char *name, char *value, int valuelen, int flags,
return (error);
/*
+ * Determine space new attribute will use, and if it would be
+ * "local" or "remote" (note: local != inline).
+ */
+ size = xfs_attr_leaf_newentsize(namelen, valuelen,
+ mp->m_sb.sb_blocksize, &local);
+
+ /*
* If the inode doesn't have an attribute fork, add one.
* (inode must not be locked when we call this routine)
*/
if (XFS_IFORK_Q(dp) == 0) {
- error = xfs_bmap_add_attrfork(dp, rsvd);
- if (error)
+ if ((error = xfs_bmap_add_attrfork(dp, size, rsvd)))
return(error);
}
@@ -265,13 +233,9 @@ xfs_attr_set(bhv_desc_t *bdp, char *name, char *value, int valuelen, int flags,
args.firstblock = &firstblock;
args.flist = &flist;
args.whichfork = XFS_ATTR_FORK;
+ args.addname = 1;
args.oknoent = 1;
- /* Determine space new attribute will use, and if it will be inline
- * or out of line.
- */
- size = xfs_attr_leaf_newentsize(&args, mp->m_sb.sb_blocksize, &local);
-
nblks = XFS_DAENTER_SPACE_RES(mp, XFS_ATTR_FORK);
if (local) {
if (size > (mp->m_sb.sb_blocksize >> 1)) {
@@ -343,7 +307,7 @@ xfs_attr_set(bhv_desc_t *bdp, char *name, char *value, int valuelen, int flags,
* Build initial attribute list (if required).
*/
if (dp->i_d.di_aformat == XFS_DINODE_FMT_EXTENTS)
- (void)xfs_attr_shortform_create(&args);
+ xfs_attr_shortform_create(&args);
/*
* Try to add the attr to the attribute list in
@@ -456,32 +420,21 @@ out:
return(error);
}
-/*
- * Generic handler routine to remove a name from an attribute list.
- * Transitions attribute list from Btree to shortform as necessary.
- */
-/*ARGSUSED*/
-int /* error */
-xfs_attr_remove(bhv_desc_t *bdp, char *name, int flags, struct cred *cred)
+int
+xfs_attr_set(bhv_desc_t *bdp, const char *name, char *value, int valuelen, int flags,
+ struct cred *cred)
{
- xfs_da_args_t args;
- xfs_inode_t *dp;
- xfs_fsblock_t firstblock;
- xfs_bmap_free_t flist;
- int error;
- xfs_mount_t *mp;
- int namelen;
+ xfs_inode_t *dp;
+ int namelen, error;
- ASSERT(MAXNAMELEN-1<=0xff); /* length is stored in uint8 */
namelen = strlen(name);
- if (namelen>=MAXNAMELEN)
- return EFAULT; /* match irix behaviour */
+ if (namelen >= MAXNAMELEN)
+ return EFAULT; /* match IRIX behaviour */
- XFS_STATS_INC(xs_attr_remove);
+ XFS_STATS_INC(xs_attr_set);
dp = XFS_BHVTOI(bdp);
- mp = dp->i_mount;
- if (XFS_FORCED_SHUTDOWN(mp))
+ if (XFS_FORCED_SHUTDOWN(dp->i_mount))
return (EIO);
xfs_ilock(dp, XFS_ILOCK_SHARED);
@@ -489,14 +442,25 @@ xfs_attr_remove(bhv_desc_t *bdp, char *name, int flags, struct cred *cred)
(error = xfs_iaccess(dp, S_IWUSR, cred))) {
xfs_iunlock(dp, XFS_ILOCK_SHARED);
return(XFS_ERROR(error));
- } else if (XFS_IFORK_Q(dp) == 0 ||
- (dp->i_d.di_aformat == XFS_DINODE_FMT_EXTENTS &&
- dp->i_d.di_anextents == 0)) {
- xfs_iunlock(dp, XFS_ILOCK_SHARED);
- return(XFS_ERROR(ENOATTR));
}
xfs_iunlock(dp, XFS_ILOCK_SHARED);
+ return xfs_attr_set_int(dp, name, namelen, value, valuelen, flags);
+}
+
+/*
+ * Generic handler routine to remove a name from an attribute list.
+ * Transitions attribute list from Btree to shortform as necessary.
+ */
+STATIC int
+xfs_attr_remove_int(xfs_inode_t *dp, const char *name, int namelen, int flags)
+{
+ xfs_da_args_t args;
+ xfs_fsblock_t firstblock;
+ xfs_bmap_free_t flist;
+ int error;
+ xfs_mount_t *mp = dp->i_mount;
+
/*
* Fill in the arg structure for this request.
*/
@@ -544,7 +508,6 @@ xfs_attr_remove(bhv_desc_t *bdp, char *name, int flags, struct cred *cred)
XFS_ATTRRM_LOG_COUNT))) {
xfs_trans_cancel(args.trans, 0);
return(error);
-
}
xfs_ilock(dp, XFS_ILOCK_EXCL);
@@ -612,6 +575,38 @@ out:
return(error);
}
+int
+xfs_attr_remove(bhv_desc_t *bdp, const char *name, int flags, struct cred *cred)
+{
+ xfs_inode_t *dp;
+ int namelen, error;
+
+ namelen = strlen(name);
+ if (namelen >= MAXNAMELEN)
+ return EFAULT; /* match IRIX behaviour */
+
+ XFS_STATS_INC(xs_attr_remove);
+
+ dp = XFS_BHVTOI(bdp);
+ if (XFS_FORCED_SHUTDOWN(dp->i_mount))
+ return (EIO);
+
+ xfs_ilock(dp, XFS_ILOCK_SHARED);
+ if (!(flags & ATTR_SECURE) &&
+ (error = xfs_iaccess(dp, S_IWUSR, cred))) {
+ xfs_iunlock(dp, XFS_ILOCK_SHARED);
+ return(XFS_ERROR(error));
+ } else if (XFS_IFORK_Q(dp) == 0 ||
+ (dp->i_d.di_aformat == XFS_DINODE_FMT_EXTENTS &&
+ dp->i_d.di_anextents == 0)) {
+ xfs_iunlock(dp, XFS_ILOCK_SHARED);
+ return(XFS_ERROR(ENOATTR));
+ }
+ xfs_iunlock(dp, XFS_ILOCK_SHARED);
+
+ return xfs_attr_remove_int(dp, name, namelen, flags);
+}
+
/*
* Generate a list of extended attribute names and optionally
* also value lengths. Positive return value follows the XFS
@@ -811,7 +806,7 @@ out:
STATIC int
xfs_attr_shortform_addname(xfs_da_args_t *args)
{
- int newsize, retval;
+ int newsize, forkoff, retval;
retval = xfs_attr_shortform_lookup(args);
if ((args->flags & ATTR_REPLACE) && (retval == ENOATTR)) {
@@ -823,16 +818,18 @@ xfs_attr_shortform_addname(xfs_da_args_t *args)
ASSERT(retval == 0);
}
+ if (args->namelen >= XFS_ATTR_SF_ENTSIZE_MAX ||
+ args->valuelen >= XFS_ATTR_SF_ENTSIZE_MAX)
+ return(XFS_ERROR(ENOSPC));
+
newsize = XFS_ATTR_SF_TOTSIZE(args->dp);
newsize += XFS_ATTR_SF_ENTSIZE_BYNAME(args->namelen, args->valuelen);
- if ((newsize <= XFS_IFORK_ASIZE(args->dp)) &&
- (args->namelen < XFS_ATTR_SF_ENTSIZE_MAX) &&
- (args->valuelen < XFS_ATTR_SF_ENTSIZE_MAX)) {
- retval = xfs_attr_shortform_add(args);
- ASSERT(retval == 0);
- } else {
+
+ forkoff = xfs_attr_shortform_bytesfit(args->dp, newsize);
+ if (!forkoff)
return(XFS_ERROR(ENOSPC));
- }
+
+ xfs_attr_shortform_add(args, forkoff);
return(0);
}
@@ -852,7 +849,7 @@ xfs_attr_leaf_addname(xfs_da_args_t *args)
{
xfs_inode_t *dp;
xfs_dabuf_t *bp;
- int retval, error, committed;
+ int retval, error, committed, forkoff;
/*
* Read the (only) block in the attribute list in.
@@ -995,9 +992,9 @@ xfs_attr_leaf_addname(xfs_da_args_t *args)
/*
* If the result is small enough, shrink it all into the inode.
*/
- if (xfs_attr_shortform_allfit(bp, dp)) {
+ if ((forkoff = xfs_attr_shortform_allfit(bp, dp))) {
XFS_BMAP_INIT(args->flist, args->firstblock);
- error = xfs_attr_leaf_to_shortform(bp, args);
+ error = xfs_attr_leaf_to_shortform(bp, args, forkoff);
/* bp is gone due to xfs_da_shrink_inode */
if (!error) {
error = xfs_bmap_finish(&args->trans,
@@ -1049,8 +1046,7 @@ xfs_attr_leaf_removename(xfs_da_args_t *args)
{
xfs_inode_t *dp;
xfs_dabuf_t *bp;
- int committed;
- int error;
+ int error, committed, forkoff;
/*
* Remove the attribute.
@@ -1075,9 +1071,9 @@ xfs_attr_leaf_removename(xfs_da_args_t *args)
/*
* If the result is small enough, shrink it all into the inode.
*/
- if (xfs_attr_shortform_allfit(bp, dp)) {
+ if ((forkoff = xfs_attr_shortform_allfit(bp, dp))) {
XFS_BMAP_INIT(args->flist, args->firstblock);
- error = xfs_attr_leaf_to_shortform(bp, args);
+ error = xfs_attr_leaf_to_shortform(bp, args, forkoff);
/* bp is gone due to xfs_da_shrink_inode */
if (!error) {
error = xfs_bmap_finish(&args->trans, args->flist,
@@ -1448,7 +1444,7 @@ xfs_attr_node_removename(xfs_da_args_t *args)
xfs_da_state_blk_t *blk;
xfs_inode_t *dp;
xfs_dabuf_t *bp;
- int retval, error, committed;
+ int retval, error, committed, forkoff;
/*
* Tie a string around our finger to remind us where we are.
@@ -1569,9 +1565,9 @@ xfs_attr_node_removename(xfs_da_args_t *args)
bp->data)->hdr.info.magic, ARCH_CONVERT)
== XFS_ATTR_LEAF_MAGIC);
- if (xfs_attr_shortform_allfit(bp, dp)) {
+ if ((forkoff = xfs_attr_shortform_allfit(bp, dp))) {
XFS_BMAP_INIT(args->flist, args->firstblock);
- error = xfs_attr_leaf_to_shortform(bp, args);
+ error = xfs_attr_leaf_to_shortform(bp, args, forkoff);
/* bp is gone due to xfs_da_shrink_inode */
if (!error) {
error = xfs_bmap_finish(&args->trans,
diff --git a/fs/xfs/xfs_attr.h b/fs/xfs/xfs_attr.h
index 45ab1c542baf..b2c7b9fcded3 100644
--- a/fs/xfs/xfs_attr.h
+++ b/fs/xfs/xfs_attr.h
@@ -1,33 +1,19 @@
/*
- * Copyright (c) 2000, 2002-2003 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000,2002-2003,2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __XFS_ATTR_H__
#define __XFS_ATTR_H__
@@ -172,15 +158,15 @@ struct xfs_da_args;
/*
* Overall external interface routines.
*/
-int xfs_attr_get(bhv_desc_t *, char *, char *, int *, int, struct cred *);
-int xfs_attr_set(bhv_desc_t *, char *, char *, int, int, struct cred *);
-int xfs_attr_remove(bhv_desc_t *, char *, int, struct cred *);
+int xfs_attr_get(bhv_desc_t *, const char *, char *, int *, int, struct cred *);
+int xfs_attr_set(bhv_desc_t *, const char *, char *, int, int, struct cred *);
+int xfs_attr_remove(bhv_desc_t *, const char *, int, struct cred *);
int xfs_attr_list(bhv_desc_t *, char *, int, int,
struct attrlist_cursor_kern *, struct cred *);
int xfs_attr_inactive(struct xfs_inode *dp);
int xfs_attr_shortform_getvalue(struct xfs_da_args *);
-int xfs_attr_fetch(struct xfs_inode *, char *, int,
+int xfs_attr_fetch(struct xfs_inode *, const char *, int,
char *, int *, int, struct cred *);
#endif /* __XFS_ATTR_H__ */
diff --git a/fs/xfs/xfs_attr_leaf.c b/fs/xfs/xfs_attr_leaf.c
index 1cdd574c63a9..35e557b00db2 100644
--- a/fs/xfs/xfs_attr_leaf.c
+++ b/fs/xfs/xfs_attr_leaf.c
@@ -1,46 +1,26 @@
/*
- * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-/*
- * xfs_attr_leaf.c
- *
- * GROT: figure out how to recover gracefully when bmap returns ENOSPC.
- */
-
#include "xfs.h"
-
-#include "xfs_macros.h"
+#include "xfs_fs.h"
#include "xfs_types.h"
-#include "xfs_inum.h"
+#include "xfs_bit.h"
#include "xfs_log.h"
+#include "xfs_inum.h"
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
@@ -48,23 +28,22 @@
#include "xfs_dir2.h"
#include "xfs_dmapi.h"
#include "xfs_mount.h"
-#include "xfs_alloc_btree.h"
+#include "xfs_da_btree.h"
#include "xfs_bmap_btree.h"
+#include "xfs_alloc_btree.h"
#include "xfs_ialloc_btree.h"
#include "xfs_alloc.h"
#include "xfs_btree.h"
-#include "xfs_attr_sf.h"
#include "xfs_dir_sf.h"
#include "xfs_dir2_sf.h"
+#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
-#include "xfs_inode_item.h"
#include "xfs_inode.h"
+#include "xfs_inode_item.h"
#include "xfs_bmap.h"
-#include "xfs_da_btree.h"
#include "xfs_attr.h"
#include "xfs_attr_leaf.h"
#include "xfs_error.h"
-#include "xfs_bit.h"
/*
* xfs_attr_leaf.c
@@ -118,13 +97,82 @@ STATIC int xfs_attr_put_listent(xfs_attr_list_context_t *context,
/*========================================================================
- * External routines when dirsize < XFS_LITINO(mp).
+ * External routines when attribute fork size < XFS_LITINO(mp).
*========================================================================*/
/*
- * Create the initial contents of a shortform attribute list.
+ * Query whether the requested number of additional bytes of extended
+ * attribute space will be able to fit inline.
+ * Returns zero if not, else the di_forkoff fork offset to be used in the
+ * literal area for attribute data once the new bytes have been added.
+ *
+ * di_forkoff must be 8 byte aligned, hence is stored as a >>3 value;
+ * special case for dev/uuid inodes, they have fixed size data forks.
*/
int
+xfs_attr_shortform_bytesfit(xfs_inode_t *dp, int bytes)
+{
+ int offset;
+ int minforkoff; /* lower limit on valid forkoff locations */
+ int maxforkoff; /* upper limit on valid forkoff locations */
+ xfs_mount_t *mp = dp->i_mount;
+
+ offset = (XFS_LITINO(mp) - bytes) >> 3; /* rounded down */
+
+ switch (dp->i_d.di_format) {
+ case XFS_DINODE_FMT_DEV:
+ minforkoff = roundup(sizeof(xfs_dev_t), 8) >> 3;
+ return (offset >= minforkoff) ? minforkoff : 0;
+ case XFS_DINODE_FMT_UUID:
+ minforkoff = roundup(sizeof(uuid_t), 8) >> 3;
+ return (offset >= minforkoff) ? minforkoff : 0;
+ }
+
+ if (unlikely(mp->m_flags & XFS_MOUNT_COMPAT_ATTR)) {
+ if (bytes <= XFS_IFORK_ASIZE(dp))
+ return mp->m_attroffset >> 3;
+ return 0;
+ }
+
+ /* data fork btree root can have at least this many key/ptr pairs */
+ minforkoff = MAX(dp->i_df.if_bytes, XFS_BMDR_SPACE_CALC(MINDBTPTRS));
+ minforkoff = roundup(minforkoff, 8) >> 3;
+
+ /* attr fork btree root can have at least this many key/ptr pairs */
+ maxforkoff = XFS_LITINO(mp) - XFS_BMDR_SPACE_CALC(MINABTPTRS);
+ maxforkoff = maxforkoff >> 3; /* rounded down */
+
+ if (offset >= minforkoff && offset < maxforkoff)
+ return offset;
+ if (offset >= maxforkoff)
+ return maxforkoff;
+ return 0;
+}
+
+/*
+ * Switch on the ATTR2 superblock bit (implies also FEATURES2)
+ */
+STATIC void
+xfs_sbversion_add_attr2(xfs_mount_t *mp, xfs_trans_t *tp)
+{
+ unsigned long s;
+
+ if (!(mp->m_flags & XFS_MOUNT_COMPAT_ATTR) &&
+ !(XFS_SB_VERSION_HASATTR2(&mp->m_sb))) {
+ s = XFS_SB_LOCK(mp);
+ if (!XFS_SB_VERSION_HASATTR2(&mp->m_sb)) {
+ XFS_SB_VERSION_ADDATTR2(&mp->m_sb);
+ XFS_SB_UNLOCK(mp, s);
+ xfs_mod_sb(tp, XFS_SB_VERSIONNUM | XFS_SB_FEATURES2);
+ } else
+ XFS_SB_UNLOCK(mp, s);
+ }
+}
+
+/*
+ * Create the initial contents of a shortform attribute list.
+ */
+void
xfs_attr_shortform_create(xfs_da_args_t *args)
{
xfs_attr_sf_hdr_t *hdr;
@@ -148,29 +196,37 @@ xfs_attr_shortform_create(xfs_da_args_t *args)
hdr->count = 0;
INT_SET(hdr->totsize, ARCH_CONVERT, sizeof(*hdr));
xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE | XFS_ILOG_ADATA);
- return(0);
}
/*
* Add a name/value pair to the shortform attribute list.
* Overflow from the inode has already been checked for.
*/
-int
-xfs_attr_shortform_add(xfs_da_args_t *args)
+void
+xfs_attr_shortform_add(xfs_da_args_t *args, int forkoff)
{
xfs_attr_shortform_t *sf;
xfs_attr_sf_entry_t *sfe;
int i, offset, size;
+ xfs_mount_t *mp;
xfs_inode_t *dp;
xfs_ifork_t *ifp;
dp = args->dp;
+ mp = dp->i_mount;
+ dp->i_d.di_forkoff = forkoff;
+ dp->i_df.if_ext_max =
+ XFS_IFORK_DSIZE(dp) / (uint)sizeof(xfs_bmbt_rec_t);
+ dp->i_afp->if_ext_max =
+ XFS_IFORK_ASIZE(dp) / (uint)sizeof(xfs_bmbt_rec_t);
+
ifp = dp->i_afp;
ASSERT(ifp->if_flags & XFS_IFINLINE);
sf = (xfs_attr_shortform_t *)ifp->if_u1.if_data;
sfe = &sf->list[0];
for (i = 0; i < INT_GET(sf->hdr.count, ARCH_CONVERT);
sfe = XFS_ATTR_SF_NEXTENTRY(sfe), i++) {
+#ifdef DEBUG
if (sfe->namelen != args->namelen)
continue;
if (memcmp(args->name, sfe->nameval, args->namelen) != 0)
@@ -181,7 +237,8 @@ xfs_attr_shortform_add(xfs_da_args_t *args)
if (((args->flags & ATTR_ROOT) != 0) !=
((sfe->flags & XFS_ATTR_ROOT) != 0))
continue;
- return(XFS_ERROR(EEXIST));
+ ASSERT(0);
+#endif
}
offset = (char *)sfe - (char *)sf;
@@ -200,11 +257,11 @@ xfs_attr_shortform_add(xfs_da_args_t *args)
INT_MOD(sf->hdr.totsize, ARCH_CONVERT, size);
xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE | XFS_ILOG_ADATA);
- return(0);
+ xfs_sbversion_add_attr2(mp, args->trans);
}
/*
- * Remove a name from the shortform attribute list structure.
+ * Remove an attribute from the shortform attribute list structure.
*/
int
xfs_attr_shortform_remove(xfs_da_args_t *args)
@@ -212,17 +269,16 @@ xfs_attr_shortform_remove(xfs_da_args_t *args)
xfs_attr_shortform_t *sf;
xfs_attr_sf_entry_t *sfe;
int base, size=0, end, totsize, i;
+ xfs_mount_t *mp;
xfs_inode_t *dp;
- /*
- * Remove the attribute.
- */
dp = args->dp;
+ mp = dp->i_mount;
base = sizeof(xfs_attr_sf_hdr_t);
sf = (xfs_attr_shortform_t *)dp->i_afp->if_u1.if_data;
sfe = &sf->list[0];
- for (i = 0; i < INT_GET(sf->hdr.count, ARCH_CONVERT);
- sfe = XFS_ATTR_SF_NEXTENTRY(sfe),
+ end = INT_GET(sf->hdr.count, ARCH_CONVERT);
+ for (i = 0; i < end; sfe = XFS_ATTR_SF_NEXTENTRY(sfe),
base += size, i++) {
size = XFS_ATTR_SF_ENTSIZE(sfe);
if (sfe->namelen != args->namelen)
@@ -237,19 +293,51 @@ xfs_attr_shortform_remove(xfs_da_args_t *args)
continue;
break;
}
- if (i == INT_GET(sf->hdr.count, ARCH_CONVERT))
+ if (i == end)
return(XFS_ERROR(ENOATTR));
+ /*
+ * Fix up the attribute fork data, covering the hole
+ */
end = base + size;
totsize = INT_GET(sf->hdr.totsize, ARCH_CONVERT);
- if (end != totsize) {
- memmove(&((char *)sf)[base], &((char *)sf)[end],
- totsize - end);
- }
+ if (end != totsize)
+ memmove(&((char *)sf)[base], &((char *)sf)[end], totsize - end);
INT_MOD(sf->hdr.count, ARCH_CONVERT, -1);
INT_MOD(sf->hdr.totsize, ARCH_CONVERT, -size);
- xfs_idata_realloc(dp, -size, XFS_ATTR_FORK);
- xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE | XFS_ILOG_ADATA);
+
+ /*
+ * Fix up the start offset of the attribute fork
+ */
+ totsize -= size;
+ if (totsize == sizeof(xfs_attr_sf_hdr_t) && !args->addname) {
+ /*
+ * Last attribute now removed, revert to original
+ * inode format making all literal area available
+ * to the data fork once more.
+ */
+ xfs_idestroy_fork(dp, XFS_ATTR_FORK);
+ dp->i_d.di_forkoff = 0;
+ dp->i_d.di_aformat = XFS_DINODE_FMT_EXTENTS;
+ ASSERT(dp->i_d.di_anextents == 0);
+ ASSERT(dp->i_afp == NULL);
+ dp->i_df.if_ext_max =
+ XFS_IFORK_DSIZE(dp) / (uint)sizeof(xfs_bmbt_rec_t);
+ xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE);
+ } else {
+ xfs_idata_realloc(dp, -size, XFS_ATTR_FORK);
+ dp->i_d.di_forkoff = xfs_attr_shortform_bytesfit(dp, totsize);
+ ASSERT(dp->i_d.di_forkoff);
+ ASSERT(totsize > sizeof(xfs_attr_sf_hdr_t) || args->addname);
+ dp->i_afp->if_ext_max =
+ XFS_IFORK_ASIZE(dp) / (uint)sizeof(xfs_bmbt_rec_t);
+ dp->i_df.if_ext_max =
+ XFS_IFORK_DSIZE(dp) / (uint)sizeof(xfs_bmbt_rec_t);
+ xfs_trans_log_inode(args->trans, dp,
+ XFS_ILOG_CORE | XFS_ILOG_ADATA);
+ }
+
+ xfs_sbversion_add_attr2(mp, args->trans);
return(0);
}
@@ -561,7 +649,7 @@ xfs_attr_shortform_list(xfs_attr_list_context_t *context)
/*
* Sort the entries on hash then entno.
*/
- qsort(sbuf, nsbuf, sizeof(*sbuf), xfs_attr_shortform_compare);
+ xfs_sort(sbuf, nsbuf, sizeof(*sbuf), xfs_attr_shortform_compare);
/*
* Re-find our place IN THE SORTED LIST.
@@ -649,14 +737,16 @@ xfs_attr_shortform_allfit(xfs_dabuf_t *bp, xfs_inode_t *dp)
+ name_loc->namelen
+ INT_GET(name_loc->valuelen, ARCH_CONVERT);
}
- return( bytes < XFS_IFORK_ASIZE(dp) );
+ if (bytes == sizeof(struct xfs_attr_sf_hdr))
+ return(-1);
+ return(xfs_attr_shortform_bytesfit(dp, bytes));
}
/*
* Convert a leaf attribute list to shortform attribute list
*/
int
-xfs_attr_leaf_to_shortform(xfs_dabuf_t *bp, xfs_da_args_t *args)
+xfs_attr_leaf_to_shortform(xfs_dabuf_t *bp, xfs_da_args_t *args, int forkoff)
{
xfs_attr_leafblock_t *leaf;
xfs_attr_leaf_entry_t *entry;
@@ -683,9 +773,25 @@ xfs_attr_leaf_to_shortform(xfs_dabuf_t *bp, xfs_da_args_t *args)
error = xfs_da_shrink_inode(args, 0, bp);
if (error)
goto out;
- error = xfs_attr_shortform_create(args);
- if (error)
+
+ if (forkoff == -1) {
+ /*
+ * Last attribute was removed, revert to original
+ * inode format making all literal area available
+ * to the data fork once more.
+ */
+ xfs_idestroy_fork(dp, XFS_ATTR_FORK);
+ dp->i_d.di_forkoff = 0;
+ dp->i_d.di_aformat = XFS_DINODE_FMT_EXTENTS;
+ ASSERT(dp->i_d.di_anextents == 0);
+ ASSERT(dp->i_afp == NULL);
+ dp->i_df.if_ext_max =
+ XFS_IFORK_DSIZE(dp) / (uint)sizeof(xfs_bmbt_rec_t);
+ xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE);
goto out;
+ }
+
+ xfs_attr_shortform_create(args);
/*
* Copy the attributes
@@ -713,7 +819,7 @@ xfs_attr_leaf_to_shortform(xfs_dabuf_t *bp, xfs_da_args_t *args)
nargs.hashval = INT_GET(entry->hashval, ARCH_CONVERT);
nargs.flags = (entry->flags & XFS_ATTR_SECURE) ? ATTR_SECURE :
((entry->flags & XFS_ATTR_ROOT) ? ATTR_ROOT : 0);
- xfs_attr_shortform_add(&nargs);
+ xfs_attr_shortform_add(&nargs, forkoff);
}
error = 0;
@@ -898,7 +1004,7 @@ xfs_attr_leaf_add(xfs_dabuf_t *bp, xfs_da_args_t *args)
ASSERT((args->index >= 0)
&& (args->index <= INT_GET(leaf->hdr.count, ARCH_CONVERT)));
hdr = &leaf->hdr;
- entsize = xfs_attr_leaf_newentsize(args,
+ entsize = xfs_attr_leaf_newentsize(args->namelen, args->valuelen,
args->trans->t_mountp->m_sb.sb_blocksize, NULL);
/*
@@ -995,13 +1101,14 @@ xfs_attr_leaf_add_work(xfs_dabuf_t *bp, xfs_da_args_t *args, int mapindex)
mp = args->trans->t_mountp;
ASSERT(INT_GET(map->base, ARCH_CONVERT) < XFS_LBSIZE(mp));
ASSERT((INT_GET(map->base, ARCH_CONVERT) & 0x3) == 0);
- ASSERT(INT_GET(map->size, ARCH_CONVERT)
- >= xfs_attr_leaf_newentsize(args,
- mp->m_sb.sb_blocksize, NULL));
+ ASSERT(INT_GET(map->size, ARCH_CONVERT) >=
+ xfs_attr_leaf_newentsize(args->namelen, args->valuelen,
+ mp->m_sb.sb_blocksize, NULL));
ASSERT(INT_GET(map->size, ARCH_CONVERT) < XFS_LBSIZE(mp));
ASSERT((INT_GET(map->size, ARCH_CONVERT) & 0x3) == 0);
INT_MOD(map->size, ARCH_CONVERT,
- -xfs_attr_leaf_newentsize(args, mp->m_sb.sb_blocksize, &tmp));
+ -xfs_attr_leaf_newentsize(args->namelen, args->valuelen,
+ mp->m_sb.sb_blocksize, &tmp));
INT_SET(entry->nameidx, ARCH_CONVERT,
INT_GET(map->base, ARCH_CONVERT)
+ INT_GET(map->size, ARCH_CONVERT));
@@ -1357,8 +1464,10 @@ xfs_attr_leaf_figure_balance(xfs_da_state_t *state,
half = (max+1) * sizeof(*entry);
half += INT_GET(hdr1->usedbytes, ARCH_CONVERT)
+ INT_GET(hdr2->usedbytes, ARCH_CONVERT)
- + xfs_attr_leaf_newentsize(state->args,
- state->blocksize, NULL);
+ + xfs_attr_leaf_newentsize(
+ state->args->namelen,
+ state->args->valuelen,
+ state->blocksize, NULL);
half /= 2;
lastdelta = state->blocksize;
entry = &leaf1->entries[0];
@@ -1370,9 +1479,10 @@ xfs_attr_leaf_figure_balance(xfs_da_state_t *state,
*/
if (count == blk1->index) {
tmp = totallen + sizeof(*entry) +
- xfs_attr_leaf_newentsize(state->args,
- state->blocksize,
- NULL);
+ xfs_attr_leaf_newentsize(
+ state->args->namelen,
+ state->args->valuelen,
+ state->blocksize, NULL);
if (XFS_ATTR_ABS(half - tmp) > lastdelta)
break;
lastdelta = XFS_ATTR_ABS(half - tmp);
@@ -1408,9 +1518,10 @@ xfs_attr_leaf_figure_balance(xfs_da_state_t *state,
totallen -= count * sizeof(*entry);
if (foundit) {
totallen -= sizeof(*entry) +
- xfs_attr_leaf_newentsize(state->args,
- state->blocksize,
- NULL);
+ xfs_attr_leaf_newentsize(
+ state->args->namelen,
+ state->args->valuelen,
+ state->blocksize, NULL);
}
*countarg = count;
@@ -2253,17 +2364,17 @@ xfs_attr_leaf_entsize(xfs_attr_leafblock_t *leaf, int index)
* a "local" or a "remote" attribute.
*/
int
-xfs_attr_leaf_newentsize(xfs_da_args_t *args, int blocksize, int *local)
+xfs_attr_leaf_newentsize(int namelen, int valuelen, int blocksize, int *local)
{
int size;
- size = XFS_ATTR_LEAF_ENTSIZE_LOCAL(args->namelen, args->valuelen);
+ size = XFS_ATTR_LEAF_ENTSIZE_LOCAL(namelen, valuelen);
if (size < XFS_ATTR_LEAF_ENTSIZE_LOCAL_MAX(blocksize)) {
if (local) {
*local = 1;
}
} else {
- size = XFS_ATTR_LEAF_ENTSIZE_REMOTE(args->namelen);
+ size = XFS_ATTR_LEAF_ENTSIZE_REMOTE(namelen);
if (local) {
*local = 0;
}
diff --git a/fs/xfs/xfs_attr_leaf.h b/fs/xfs/xfs_attr_leaf.h
index 0a4cfad6df91..f6143ff251a0 100644
--- a/fs/xfs/xfs_attr_leaf.h
+++ b/fs/xfs/xfs_attr_leaf.h
@@ -1,33 +1,19 @@
/*
- * Copyright (c) 2000, 2002-2003 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000,2002-2003,2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __XFS_ATTR_LEAF_H__
#define __XFS_ATTR_LEAF_H__
@@ -146,65 +132,58 @@ typedef struct xfs_attr_leaf_name_remote xfs_attr_leaf_name_remote_t;
/*
* Cast typed pointers for "local" and "remote" name/value structs.
*/
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_ATTR_LEAF_NAME_REMOTE)
-xfs_attr_leaf_name_remote_t *
-xfs_attr_leaf_name_remote(xfs_attr_leafblock_t *leafp, int idx);
#define XFS_ATTR_LEAF_NAME_REMOTE(leafp,idx) \
xfs_attr_leaf_name_remote(leafp,idx)
-#else
-#define XFS_ATTR_LEAF_NAME_REMOTE(leafp,idx) /* remote name struct ptr */ \
- ((xfs_attr_leaf_name_remote_t *) \
- &((char *)(leafp))[ INT_GET((leafp)->entries[idx].nameidx, ARCH_CONVERT) ])
-#endif
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_ATTR_LEAF_NAME_LOCAL)
-xfs_attr_leaf_name_local_t *
-xfs_attr_leaf_name_local(xfs_attr_leafblock_t *leafp, int idx);
+static inline xfs_attr_leaf_name_remote_t *
+xfs_attr_leaf_name_remote(xfs_attr_leafblock_t *leafp, int idx)
+{
+ return (xfs_attr_leaf_name_remote_t *) &((char *)
+ (leafp))[INT_GET((leafp)->entries[idx].nameidx, ARCH_CONVERT)];
+}
+
#define XFS_ATTR_LEAF_NAME_LOCAL(leafp,idx) \
xfs_attr_leaf_name_local(leafp,idx)
-#else
-#define XFS_ATTR_LEAF_NAME_LOCAL(leafp,idx) /* local name struct ptr */ \
- ((xfs_attr_leaf_name_local_t *) \
- &((char *)(leafp))[ INT_GET((leafp)->entries[idx].nameidx, ARCH_CONVERT) ])
-#endif
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_ATTR_LEAF_NAME)
-char *xfs_attr_leaf_name(xfs_attr_leafblock_t *leafp, int idx);
+static inline xfs_attr_leaf_name_local_t *
+xfs_attr_leaf_name_local(xfs_attr_leafblock_t *leafp, int idx)
+{
+ return (xfs_attr_leaf_name_local_t *) &((char *)
+ (leafp))[INT_GET((leafp)->entries[idx].nameidx, ARCH_CONVERT)];
+}
+
#define XFS_ATTR_LEAF_NAME(leafp,idx) xfs_attr_leaf_name(leafp,idx)
-#else
-#define XFS_ATTR_LEAF_NAME(leafp,idx) /* generic name struct ptr */ \
- (&((char *)(leafp))[ INT_GET((leafp)->entries[idx].nameidx, ARCH_CONVERT) ])
-#endif
+static inline char *xfs_attr_leaf_name(xfs_attr_leafblock_t *leafp, int idx)
+{
+ return (&((char *)
+ (leafp))[INT_GET((leafp)->entries[idx].nameidx, ARCH_CONVERT)]);
+}
/*
* Calculate total bytes used (including trailing pad for alignment) for
* a "local" name/value structure, a "remote" name/value structure, and
* a pointer which might be either.
*/
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_ATTR_LEAF_ENTSIZE_REMOTE)
-int xfs_attr_leaf_entsize_remote(int nlen);
#define XFS_ATTR_LEAF_ENTSIZE_REMOTE(nlen) \
xfs_attr_leaf_entsize_remote(nlen)
-#else
-#define XFS_ATTR_LEAF_ENTSIZE_REMOTE(nlen) /* space for remote struct */ \
- (((uint)sizeof(xfs_attr_leaf_name_remote_t) - 1 + (nlen) + \
- XFS_ATTR_LEAF_NAME_ALIGN - 1) & ~(XFS_ATTR_LEAF_NAME_ALIGN - 1))
-#endif
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_ATTR_LEAF_ENTSIZE_LOCAL)
-int xfs_attr_leaf_entsize_local(int nlen, int vlen);
+static inline int xfs_attr_leaf_entsize_remote(int nlen)
+{
+ return ((uint)sizeof(xfs_attr_leaf_name_remote_t) - 1 + (nlen) + \
+ XFS_ATTR_LEAF_NAME_ALIGN - 1) & ~(XFS_ATTR_LEAF_NAME_ALIGN - 1);
+}
+
#define XFS_ATTR_LEAF_ENTSIZE_LOCAL(nlen,vlen) \
xfs_attr_leaf_entsize_local(nlen,vlen)
-#else
-#define XFS_ATTR_LEAF_ENTSIZE_LOCAL(nlen,vlen) /* space for local struct */ \
- (((uint)sizeof(xfs_attr_leaf_name_local_t) - 1 + (nlen) + (vlen) + \
- XFS_ATTR_LEAF_NAME_ALIGN - 1) & ~(XFS_ATTR_LEAF_NAME_ALIGN - 1))
-#endif
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_ATTR_LEAF_ENTSIZE_LOCAL_MAX)
-int xfs_attr_leaf_entsize_local_max(int bsize);
+static inline int xfs_attr_leaf_entsize_local(int nlen, int vlen)
+{
+ return ((uint)sizeof(xfs_attr_leaf_name_local_t) - 1 + (nlen) + (vlen) +
+ XFS_ATTR_LEAF_NAME_ALIGN - 1) & ~(XFS_ATTR_LEAF_NAME_ALIGN - 1);
+}
+
#define XFS_ATTR_LEAF_ENTSIZE_LOCAL_MAX(bsize) \
xfs_attr_leaf_entsize_local_max(bsize)
-#else
-#define XFS_ATTR_LEAF_ENTSIZE_LOCAL_MAX(bsize) /* max local struct size */ \
- (((bsize) >> 1) + ((bsize) >> 2))
-#endif
+static inline int xfs_attr_leaf_entsize_local_max(int bsize)
+{
+ return (((bsize) >> 1) + ((bsize) >> 2));
+}
/*========================================================================
@@ -237,23 +216,25 @@ typedef struct xfs_attr_inactive_list {
*========================================================================*/
/*
- * Internal routines when dirsize < XFS_LITINO(mp).
+ * Internal routines when attribute fork size < XFS_LITINO(mp).
*/
-int xfs_attr_shortform_create(struct xfs_da_args *args);
-int xfs_attr_shortform_add(struct xfs_da_args *add);
+void xfs_attr_shortform_create(struct xfs_da_args *args);
+void xfs_attr_shortform_add(struct xfs_da_args *args, int forkoff);
int xfs_attr_shortform_lookup(struct xfs_da_args *args);
int xfs_attr_shortform_getvalue(struct xfs_da_args *args);
int xfs_attr_shortform_to_leaf(struct xfs_da_args *args);
-int xfs_attr_shortform_remove(struct xfs_da_args *remove);
+int xfs_attr_shortform_remove(struct xfs_da_args *args);
int xfs_attr_shortform_list(struct xfs_attr_list_context *context);
int xfs_attr_shortform_allfit(struct xfs_dabuf *bp, struct xfs_inode *dp);
+int xfs_attr_shortform_bytesfit(xfs_inode_t *dp, int bytes);
+
/*
- * Internal routines when dirsize == XFS_LBSIZE(mp).
+ * Internal routines when attribute fork size == XFS_LBSIZE(mp).
*/
int xfs_attr_leaf_to_node(struct xfs_da_args *args);
int xfs_attr_leaf_to_shortform(struct xfs_dabuf *bp,
- struct xfs_da_args *args);
+ struct xfs_da_args *args, int forkoff);
int xfs_attr_leaf_clearflag(struct xfs_da_args *args);
int xfs_attr_leaf_setflag(struct xfs_da_args *args);
int xfs_attr_leaf_flipflags(xfs_da_args_t *args);
@@ -289,7 +270,7 @@ int xfs_attr_root_inactive(struct xfs_trans **trans, struct xfs_inode *dp);
xfs_dahash_t xfs_attr_leaf_lasthash(struct xfs_dabuf *bp, int *count);
int xfs_attr_leaf_order(struct xfs_dabuf *leaf1_bp,
struct xfs_dabuf *leaf2_bp);
-int xfs_attr_leaf_newentsize(struct xfs_da_args *args, int blocksize,
+int xfs_attr_leaf_newentsize(int namelen, int valuelen, int blocksize,
int *local);
int xfs_attr_rolltrans(struct xfs_trans **transp, struct xfs_inode *dp);
diff --git a/fs/xfs/xfs_attr_sf.h b/fs/xfs/xfs_attr_sf.h
index ef7d2942d306..ffed6ca81a52 100644
--- a/fs/xfs/xfs_attr_sf.h
+++ b/fs/xfs/xfs_attr_sf.h
@@ -1,33 +1,19 @@
/*
- * Copyright (c) 2000, 2002 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000,2002,2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __XFS_ATTR_SF_H__
#define __XFS_ATTR_SF_H__
@@ -71,38 +57,17 @@ typedef struct xfs_attr_sf_sort {
char *name; /* name value, pointer into buffer */
} xfs_attr_sf_sort_t;
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_ATTR_SF_ENTSIZE_BYNAME)
-int xfs_attr_sf_entsize_byname(int nlen, int vlen);
-#define XFS_ATTR_SF_ENTSIZE_BYNAME(nlen,vlen) \
- xfs_attr_sf_entsize_byname(nlen,vlen)
-#else
#define XFS_ATTR_SF_ENTSIZE_BYNAME(nlen,vlen) /* space name/value uses */ \
- ((int)sizeof(xfs_attr_sf_entry_t)-1 + (nlen)+(vlen))
-#endif
+ (((int)sizeof(xfs_attr_sf_entry_t)-1 + (nlen)+(vlen)))
#define XFS_ATTR_SF_ENTSIZE_MAX /* max space for name&value */ \
((1 << (NBBY*(int)sizeof(__uint8_t))) - 1)
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_ATTR_SF_ENTSIZE)
-int xfs_attr_sf_entsize(xfs_attr_sf_entry_t *sfep);
-#define XFS_ATTR_SF_ENTSIZE(sfep) xfs_attr_sf_entsize(sfep)
-#else
#define XFS_ATTR_SF_ENTSIZE(sfep) /* space an entry uses */ \
((int)sizeof(xfs_attr_sf_entry_t)-1 + (sfep)->namelen+(sfep)->valuelen)
-#endif
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_ATTR_SF_NEXTENTRY)
-xfs_attr_sf_entry_t *xfs_attr_sf_nextentry(xfs_attr_sf_entry_t *sfep);
-#define XFS_ATTR_SF_NEXTENTRY(sfep) xfs_attr_sf_nextentry(sfep)
-#else
#define XFS_ATTR_SF_NEXTENTRY(sfep) /* next entry in struct */ \
- ((xfs_attr_sf_entry_t *) \
- ((char *)(sfep) + XFS_ATTR_SF_ENTSIZE(sfep)))
-#endif
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_ATTR_SF_TOTSIZE)
-int xfs_attr_sf_totsize(struct xfs_inode *dp);
-#define XFS_ATTR_SF_TOTSIZE(dp) xfs_attr_sf_totsize(dp)
-#else
+ ((xfs_attr_sf_entry_t *)((char *)(sfep) + XFS_ATTR_SF_ENTSIZE(sfep)))
#define XFS_ATTR_SF_TOTSIZE(dp) /* total space in use */ \
- (INT_GET(((xfs_attr_shortform_t *)((dp)->i_afp->if_u1.if_data))->hdr.totsize, ARCH_CONVERT))
-#endif
+ (INT_GET(((xfs_attr_shortform_t *) \
+ ((dp)->i_afp->if_u1.if_data))->hdr.totsize, ARCH_CONVERT))
#if defined(XFS_ATTR_TRACE)
/*
diff --git a/fs/xfs/xfs_behavior.c b/fs/xfs/xfs_behavior.c
index 16088e175ecc..9880adae3938 100644
--- a/fs/xfs/xfs_behavior.c
+++ b/fs/xfs/xfs_behavior.c
@@ -1,34 +1,19 @@
/*
- * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "xfs.h"
diff --git a/fs/xfs/xfs_behavior.h b/fs/xfs/xfs_behavior.h
index d5ed5a843921..2cd89bb5ab10 100644
--- a/fs/xfs/xfs_behavior.h
+++ b/fs/xfs/xfs_behavior.h
@@ -1,33 +1,19 @@
/*
- * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __XFS_BEHAVIOR_H__
#define __XFS_BEHAVIOR_H__
diff --git a/fs/xfs/xfs_bit.c b/fs/xfs/xfs_bit.c
index 76c9ad3875ef..43be6a7e47c6 100644
--- a/fs/xfs/xfs_bit.c
+++ b/fs/xfs/xfs_bit.c
@@ -1,45 +1,29 @@
/*
- * Copyright (c) 2000-2004 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-
-/*
- * XFS bit manipulation routines, used in non-realtime code.
- */
-
#include "xfs.h"
#include "xfs_bit.h"
#include "xfs_log.h"
#include "xfs_trans.h"
#include "xfs_buf_item.h"
+/*
+ * XFS bit manipulation routines, used in non-realtime code.
+ */
#ifndef HAVE_ARCH_HIGHBIT
/*
diff --git a/fs/xfs/xfs_bit.h b/fs/xfs/xfs_bit.h
index 1e7f57ddf7a8..0bbe56817542 100644
--- a/fs/xfs/xfs_bit.h
+++ b/fs/xfs/xfs_bit.h
@@ -1,33 +1,19 @@
/*
- * Copyright (c) 2000, 2002 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000,2002,2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __XFS_BIT_H__
#define __XFS_BIT_H__
@@ -39,30 +25,26 @@
/*
* masks with n high/low bits set, 32-bit values & 64-bit values
*/
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_MASK32HI)
-__uint32_t xfs_mask32hi(int n);
#define XFS_MASK32HI(n) xfs_mask32hi(n)
-#else
-#define XFS_MASK32HI(n) ((__uint32_t)-1 << (32 - (n)))
-#endif
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_MASK64HI)
-__uint64_t xfs_mask64hi(int n);
+static inline __uint32_t xfs_mask32hi(int n)
+{
+ return (__uint32_t)-1 << (32 - (n));
+}
#define XFS_MASK64HI(n) xfs_mask64hi(n)
-#else
-#define XFS_MASK64HI(n) ((__uint64_t)-1 << (64 - (n)))
-#endif
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_MASK32LO)
-__uint32_t xfs_mask32lo(int n);
+static inline __uint64_t xfs_mask64hi(int n)
+{
+ return (__uint64_t)-1 << (64 - (n));
+}
#define XFS_MASK32LO(n) xfs_mask32lo(n)
-#else
-#define XFS_MASK32LO(n) (((__uint32_t)1 << (n)) - 1)
-#endif
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_MASK64LO)
-__uint64_t xfs_mask64lo(int n);
+static inline __uint32_t xfs_mask32lo(int n)
+{
+ return ((__uint32_t)1 << (n)) - 1;
+}
#define XFS_MASK64LO(n) xfs_mask64lo(n)
-#else
-#define XFS_MASK64LO(n) (((__uint64_t)1 << (n)) - 1)
-#endif
+static inline __uint64_t xfs_mask64lo(int n)
+{
+ return ((__uint64_t)1 << (n)) - 1;
+}
/* Get high bit set out of 32-bit argument, -1 if none set */
extern int xfs_highbit32(__uint32_t v);
diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c
index 3e76def1283d..e415a4698e9c 100644
--- a/fs/xfs/xfs_bmap.c
+++ b/fs/xfs/xfs_bmap.c
@@ -1,68 +1,53 @@
/*
- * Copyright (c) 2000-2004 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-
#include "xfs.h"
-
-#include "xfs_macros.h"
+#include "xfs_fs.h"
#include "xfs_types.h"
-#include "xfs_inum.h"
+#include "xfs_bit.h"
#include "xfs_log.h"
+#include "xfs_inum.h"
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
#include "xfs_dir.h"
#include "xfs_dir2.h"
-#include "xfs_dmapi.h"
-#include "xfs_mount.h"
-#include "xfs_alloc_btree.h"
+#include "xfs_da_btree.h"
#include "xfs_bmap_btree.h"
+#include "xfs_alloc_btree.h"
#include "xfs_ialloc_btree.h"
-#include "xfs_btree.h"
-#include "xfs_ialloc.h"
-#include "xfs_attr_sf.h"
#include "xfs_dir_sf.h"
#include "xfs_dir2_sf.h"
+#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
-#include "xfs_inode_item.h"
#include "xfs_inode.h"
+#include "xfs_btree.h"
+#include "xfs_dmapi.h"
+#include "xfs_mount.h"
+#include "xfs_ialloc.h"
#include "xfs_itable.h"
+#include "xfs_inode_item.h"
#include "xfs_extfree_item.h"
#include "xfs_alloc.h"
#include "xfs_bmap.h"
#include "xfs_rtalloc.h"
#include "xfs_error.h"
-#include "xfs_da_btree.h"
#include "xfs_dir_leaf.h"
-#include "xfs_bit.h"
+#include "xfs_attr_leaf.h"
#include "xfs_rw.h"
#include "xfs_quota.h"
#include "xfs_trans_space.h"
@@ -438,6 +423,12 @@ xfs_bmap_count_leaves(
int numrecs,
int *count);
+STATIC int
+xfs_bmap_disk_count_leaves(
+ xfs_bmbt_rec_t *frp,
+ int numrecs,
+ int *count);
+
/*
* Bmap internal routines.
*/
@@ -2772,8 +2763,8 @@ xfs_bmap_btree_to_extents(
ASSERT(ifp->if_flags & XFS_IFEXTENTS);
ASSERT(XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_BTREE);
rblock = ifp->if_broot;
- ASSERT(INT_GET(rblock->bb_level, ARCH_CONVERT) == 1);
- ASSERT(INT_GET(rblock->bb_numrecs, ARCH_CONVERT) == 1);
+ ASSERT(be16_to_cpu(rblock->bb_level) == 1);
+ ASSERT(be16_to_cpu(rblock->bb_numrecs) == 1);
ASSERT(XFS_BMAP_BROOT_MAXRECS(ifp->if_broot_bytes) == 1);
mp = ip->i_mount;
pp = XFS_BMAP_BROOT_PTR_ADDR(rblock, 1, ifp->if_broot_bytes);
@@ -3216,11 +3207,11 @@ xfs_bmap_extents_to_btree(
* Fill in the root.
*/
block = ifp->if_broot;
- INT_SET(block->bb_magic, ARCH_CONVERT, XFS_BMAP_MAGIC);
- INT_SET(block->bb_level, ARCH_CONVERT, 1);
- INT_SET(block->bb_numrecs, ARCH_CONVERT, 1);
- INT_SET(block->bb_leftsib, ARCH_CONVERT, NULLDFSBNO);
- INT_SET(block->bb_rightsib, ARCH_CONVERT, NULLDFSBNO);
+ block->bb_magic = cpu_to_be32(XFS_BMAP_MAGIC);
+ block->bb_level = cpu_to_be16(1);
+ block->bb_numrecs = cpu_to_be16(1);
+ block->bb_leftsib = cpu_to_be64(NULLDFSBNO);
+ block->bb_rightsib = cpu_to_be64(NULLDFSBNO);
/*
* Need a cursor. Can't allocate until bb_level is filled in.
*/
@@ -3273,10 +3264,10 @@ xfs_bmap_extents_to_btree(
* Fill in the child block.
*/
ablock = XFS_BUF_TO_BMBT_BLOCK(abp);
- INT_SET(ablock->bb_magic, ARCH_CONVERT, XFS_BMAP_MAGIC);
+ ablock->bb_magic = cpu_to_be32(XFS_BMAP_MAGIC);
ablock->bb_level = 0;
- INT_SET(ablock->bb_leftsib, ARCH_CONVERT, NULLDFSBNO);
- INT_SET(ablock->bb_rightsib, ARCH_CONVERT, NULLDFSBNO);
+ ablock->bb_leftsib = cpu_to_be64(NULLDFSBNO);
+ ablock->bb_rightsib = cpu_to_be64(NULLDFSBNO);
arp = XFS_BMAP_REC_IADDR(ablock, 1, cur);
nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
for (ep = ifp->if_u1.if_extents, cnt = i = 0; i < nextents; i++, ep++) {
@@ -3286,8 +3277,8 @@ xfs_bmap_extents_to_btree(
arp++; cnt++;
}
}
- INT_SET(ablock->bb_numrecs, ARCH_CONVERT, cnt);
- ASSERT(INT_GET(ablock->bb_numrecs, ARCH_CONVERT) == XFS_IFORK_NEXTENTS(ip, whichfork));
+ ASSERT(cnt == XFS_IFORK_NEXTENTS(ip, whichfork));
+ ablock->bb_numrecs = cpu_to_be16(cnt);
/*
* Fill in the root key and pointer.
*/
@@ -3301,7 +3292,7 @@ xfs_bmap_extents_to_btree(
* the root is at the right level.
*/
xfs_bmbt_log_block(cur, abp, XFS_BB_ALL_BITS);
- xfs_bmbt_log_recs(cur, abp, 1, INT_GET(ablock->bb_numrecs, ARCH_CONVERT));
+ xfs_bmbt_log_recs(cur, abp, 1, be16_to_cpu(ablock->bb_numrecs));
ASSERT(*curp == NULL);
*curp = cur;
*logflagsp = XFS_ILOG_CORE | XFS_ILOG_FBROOT(whichfork);
@@ -3337,6 +3328,29 @@ xfs_bmap_insert_exlist(
}
/*
+ * Helper routine to reset inode di_forkoff field when switching
+ * attribute fork from local to extent format - we reset it where
+ * possible to make space available for inline data fork extents.
+ */
+STATIC void
+xfs_bmap_forkoff_reset(
+ xfs_mount_t *mp,
+ xfs_inode_t *ip,
+ int whichfork)
+{
+ if (whichfork == XFS_ATTR_FORK &&
+ (ip->i_d.di_format != XFS_DINODE_FMT_DEV) &&
+ (ip->i_d.di_format != XFS_DINODE_FMT_UUID) &&
+ ((mp->m_attroffset >> 3) > ip->i_d.di_forkoff)) {
+ ip->i_d.di_forkoff = mp->m_attroffset >> 3;
+ ip->i_df.if_ext_max = XFS_IFORK_DSIZE(ip) /
+ (uint)sizeof(xfs_bmbt_rec_t);
+ ip->i_afp->if_ext_max = XFS_IFORK_ASIZE(ip) /
+ (uint)sizeof(xfs_bmbt_rec_t);
+ }
+}
+
+/*
* Convert a local file to an extents file.
* This code is out of bounds for data forks of regular files,
* since the file data needs to get logged so things will stay consistent.
@@ -3403,6 +3417,7 @@ xfs_bmap_local_to_extents(
memcpy((char *)XFS_BUF_PTR(bp), ifp->if_u1.if_data,
ifp->if_bytes);
xfs_trans_log_buf(tp, bp, 0, ifp->if_bytes - 1);
+ xfs_bmap_forkoff_reset(args.mp, ip, whichfork);
xfs_idata_realloc(ip, -ifp->if_bytes, whichfork);
xfs_iext_realloc(ip, 1, whichfork);
ep = ifp->if_u1.if_extents;
@@ -3413,8 +3428,10 @@ xfs_bmap_local_to_extents(
XFS_TRANS_MOD_DQUOT_BYINO(args.mp, tp, ip,
XFS_TRANS_DQ_BCOUNT, 1L);
flags |= XFS_ILOG_FEXT(whichfork);
- } else
+ } else {
ASSERT(XFS_IFORK_NEXTENTS(ip, whichfork) == 0);
+ xfs_bmap_forkoff_reset(ip->i_mount, ip, whichfork);
+ }
ifp->if_flags &= ~XFS_IFINLINE;
ifp->if_flags |= XFS_IFEXTENTS;
XFS_IFORK_FMT_SET(ip, whichfork, XFS_DINODE_FMT_EXTENTS);
@@ -3796,22 +3813,24 @@ xfs_bunmap_trace(
int /* error code */
xfs_bmap_add_attrfork(
xfs_inode_t *ip, /* incore inode pointer */
- int rsvd) /* OK to allocated reserved blocks in trans */
+ int size, /* space new attribute needs */
+ int rsvd) /* xact may use reserved blks */
{
- int blks; /* space reservation */
- int committed; /* xaction was committed */
- int error; /* error return value */
xfs_fsblock_t firstblock; /* 1st block/ag allocated */
xfs_bmap_free_t flist; /* freed extent list */
- int logflags; /* logging flags */
xfs_mount_t *mp; /* mount structure */
- unsigned long s; /* spinlock spl value */
xfs_trans_t *tp; /* transaction pointer */
+ unsigned long s; /* spinlock spl value */
+ int blks; /* space reservation */
+ int version = 1; /* superblock attr version */
+ int committed; /* xaction was committed */
+ int logflags; /* logging flags */
+ int error; /* error return value */
+ ASSERT(XFS_IFORK_Q(ip) == 0);
ASSERT(ip->i_df.if_ext_max ==
XFS_IFORK_DSIZE(ip) / (uint)sizeof(xfs_bmbt_rec_t));
- if (XFS_IFORK_Q(ip))
- return 0;
+
mp = ip->i_mount;
ASSERT(!XFS_NOT_DQATTACHED(mp, ip));
tp = xfs_trans_alloc(mp, XFS_TRANS_ADDAFORK);
@@ -3853,7 +3872,11 @@ xfs_bmap_add_attrfork(
case XFS_DINODE_FMT_LOCAL:
case XFS_DINODE_FMT_EXTENTS:
case XFS_DINODE_FMT_BTREE:
- ip->i_d.di_forkoff = mp->m_attroffset >> 3;
+ ip->i_d.di_forkoff = xfs_attr_shortform_bytesfit(ip, size);
+ if (!ip->i_d.di_forkoff)
+ ip->i_d.di_forkoff = mp->m_attroffset >> 3;
+ else if (!(mp->m_flags & XFS_MOUNT_COMPAT_ATTR))
+ version = 2;
break;
default:
ASSERT(0);
@@ -3890,12 +3913,22 @@ xfs_bmap_add_attrfork(
xfs_trans_log_inode(tp, ip, logflags);
if (error)
goto error2;
- if (!XFS_SB_VERSION_HASATTR(&mp->m_sb)) {
+ if (!XFS_SB_VERSION_HASATTR(&mp->m_sb) ||
+ (!XFS_SB_VERSION_HASATTR2(&mp->m_sb) && version == 2)) {
+ __int64_t sbfields = 0;
+
s = XFS_SB_LOCK(mp);
if (!XFS_SB_VERSION_HASATTR(&mp->m_sb)) {
XFS_SB_VERSION_ADDATTR(&mp->m_sb);
+ sbfields |= XFS_SB_VERSIONNUM;
+ }
+ if (!XFS_SB_VERSION_HASATTR2(&mp->m_sb) && version == 2) {
+ XFS_SB_VERSION_ADDATTR2(&mp->m_sb);
+ sbfields |= (XFS_SB_VERSIONNUM | XFS_SB_FEATURES2);
+ }
+ if (sbfields) {
XFS_SB_UNLOCK(mp, s);
- xfs_mod_sb(tp, XFS_SB_VERSIONNUM);
+ xfs_mod_sb(tp, sbfields);
} else
XFS_SB_UNLOCK(mp, s);
}
@@ -3988,13 +4021,19 @@ xfs_bmap_compute_maxlevels(
* (a signed 32-bit number, xfs_extnum_t), or by di_anextents
* (a signed 16-bit number, xfs_aextnum_t).
*/
- maxleafents = (whichfork == XFS_DATA_FORK) ? MAXEXTNUM : MAXAEXTNUM;
+ if (whichfork == XFS_DATA_FORK) {
+ maxleafents = MAXEXTNUM;
+ sz = (mp->m_flags & XFS_MOUNT_COMPAT_ATTR) ?
+ mp->m_attroffset : XFS_BMDR_SPACE_CALC(MINDBTPTRS);
+ } else {
+ maxleafents = MAXAEXTNUM;
+ sz = (mp->m_flags & XFS_MOUNT_COMPAT_ATTR) ?
+ mp->m_sb.sb_inodesize - mp->m_attroffset :
+ XFS_BMDR_SPACE_CALC(MINABTPTRS);
+ }
+ maxrootrecs = (int)XFS_BTREE_BLOCK_MAXRECS(sz, xfs_bmdr, 0);
minleafrecs = mp->m_bmap_dmnr[0];
minnoderecs = mp->m_bmap_dmnr[1];
- sz = (whichfork == XFS_DATA_FORK) ?
- mp->m_attroffset :
- mp->m_sb.sb_inodesize - mp->m_attroffset;
- maxrootrecs = (int)XFS_BTREE_BLOCK_MAXRECS(sz, xfs_bmdr, 0);
maxblocks = (maxleafents + minleafrecs - 1) / minleafrecs;
for (level = 1; maxblocks > 1; level++) {
if (maxblocks <= maxrootrecs)
@@ -4332,8 +4371,8 @@ xfs_bmap_read_extents(
/*
* Root level must use BMAP_BROOT_PTR_ADDR macro to get ptr out.
*/
- ASSERT(INT_GET(block->bb_level, ARCH_CONVERT) > 0);
- level = INT_GET(block->bb_level, ARCH_CONVERT);
+ level = be16_to_cpu(block->bb_level);
+ ASSERT(level > 0);
pp = XFS_BMAP_BROOT_PTR_ADDR(block, 1, ifp->if_broot_bytes);
ASSERT(INT_GET(*pp, ARCH_CONVERT) != NULLDFSBNO);
ASSERT(XFS_FSB_TO_AGNO(mp, INT_GET(*pp, ARCH_CONVERT)) < mp->m_sb.sb_agcount);
@@ -4376,7 +4415,7 @@ xfs_bmap_read_extents(
xfs_extnum_t num_recs;
- num_recs = INT_GET(block->bb_numrecs, ARCH_CONVERT);
+ num_recs = be16_to_cpu(block->bb_numrecs);
if (unlikely(i + num_recs > room)) {
ASSERT(i + num_recs <= room);
xfs_fs_cmn_err(CE_WARN, ip->i_mount,
@@ -4393,7 +4432,7 @@ xfs_bmap_read_extents(
/*
* Read-ahead the next leaf block, if any.
*/
- nextbno = INT_GET(block->bb_rightsib, ARCH_CONVERT);
+ nextbno = be64_to_cpu(block->bb_rightsib);
if (nextbno != NULLFSBLOCK)
xfs_btree_reada_bufl(mp, nextbno, 1);
/*
@@ -4650,7 +4689,7 @@ xfs_bmapi(
}
if (wr && *firstblock == NULLFSBLOCK) {
if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_BTREE)
- minleft = INT_GET(ifp->if_broot->bb_level, ARCH_CONVERT) + 1;
+ minleft = be16_to_cpu(ifp->if_broot->bb_level) + 1;
else
minleft = 1;
} else
@@ -5692,12 +5731,13 @@ xfs_getbmap(
out.bmv_offset = XFS_FSB_TO_BB(mp, map[i].br_startoff);
out.bmv_length = XFS_FSB_TO_BB(mp, map[i].br_blockcount);
ASSERT(map[i].br_startblock != DELAYSTARTBLOCK);
- if (prealloced &&
- map[i].br_startblock == HOLESTARTBLOCK &&
- out.bmv_offset + out.bmv_length == bmvend) {
- /*
- * came to hole at end of file
- */
+ if (map[i].br_startblock == HOLESTARTBLOCK &&
+ ((prealloced && out.bmv_offset + out.bmv_length == bmvend) ||
+ whichfork == XFS_ATTR_FORK )) {
+ /*
+ * came to hole at end of file or the end of
+ attribute fork
+ */
goto unlock_and_return;
} else {
out.bmv_block =
@@ -5927,10 +5967,10 @@ xfs_check_block(
xfs_bmbt_ptr_t *pp, *thispa; /* pointer to block address */
xfs_bmbt_key_t *prevp, *keyp;
- ASSERT(INT_GET(block->bb_level, ARCH_CONVERT) > 0);
+ ASSERT(be16_to_cpu(block->bb_level) > 0);
prevp = NULL;
- for( i = 1; i <= INT_GET(block->bb_numrecs, ARCH_CONVERT);i++) {
+ for( i = 1; i <= be16_to_cpu(block->bb_numrecs); i++) {
dmxr = mp->m_bmap_dmxr[0];
if (root) {
@@ -5955,7 +5995,7 @@ xfs_check_block(
pp = XFS_BTREE_PTR_ADDR(mp->m_sb.sb_blocksize,
xfs_bmbt, block, i, dmxr);
}
- for (j = i+1; j <= INT_GET(block->bb_numrecs, ARCH_CONVERT); j++) {
+ for (j = i+1; j <= be16_to_cpu(block->bb_numrecs); j++) {
if (root) {
thispa = XFS_BMAP_BROOT_PTR_ADDR(block, j, sz);
} else {
@@ -6008,8 +6048,8 @@ xfs_bmap_check_leaf_extents(
/*
* Root level must use BMAP_BROOT_PTR_ADDR macro to get ptr out.
*/
- ASSERT(INT_GET(block->bb_level, ARCH_CONVERT) > 0);
- level = INT_GET(block->bb_level, ARCH_CONVERT);
+ level = be16_to_cpu(block->bb_level);
+ ASSERT(level > 0);
xfs_check_block(block, mp, 1, ifp->if_broot_bytes);
pp = XFS_BMAP_BROOT_PTR_ADDR(block, 1, ifp->if_broot_bytes);
ASSERT(INT_GET(*pp, ARCH_CONVERT) != NULLDFSBNO);
@@ -6069,13 +6109,13 @@ xfs_bmap_check_leaf_extents(
xfs_extnum_t num_recs;
- num_recs = INT_GET(block->bb_numrecs, ARCH_CONVERT);
+ num_recs = be16_to_cpu(block->bb_numrecs);
/*
* Read-ahead the next leaf block, if any.
*/
- nextbno = INT_GET(block->bb_rightsib, ARCH_CONVERT);
+ nextbno = be64_to_cpu(block->bb_rightsib);
/*
* Check all the extents to make sure they are OK.
@@ -6131,7 +6171,7 @@ error0:
xfs_trans_brelse(NULL, bp);
error_norelse:
cmn_err(CE_WARN, "%s: BAD after btree leaves for %d extents",
- i, __FUNCTION__);
+ __FUNCTION__, i);
panic("%s: CORRUPTED BTREE OR SOMETHING", __FUNCTION__);
return;
}
@@ -6172,8 +6212,8 @@ xfs_bmap_count_blocks(
* Root level must use BMAP_BROOT_PTR_ADDR macro to get ptr out.
*/
block = ifp->if_broot;
- ASSERT(INT_GET(block->bb_level, ARCH_CONVERT) > 0);
- level = INT_GET(block->bb_level, ARCH_CONVERT);
+ level = be16_to_cpu(block->bb_level);
+ ASSERT(level > 0);
pp = XFS_BMAP_BROOT_PTR_ADDR(block, 1, ifp->if_broot_bytes);
ASSERT(INT_GET(*pp, ARCH_CONVERT) != NULLDFSBNO);
ASSERT(XFS_FSB_TO_AGNO(mp, INT_GET(*pp, ARCH_CONVERT)) < mp->m_sb.sb_agcount);
@@ -6218,14 +6258,14 @@ xfs_bmap_count_tree(
if (--level) {
/* Not at node above leafs, count this level of nodes */
- nextbno = INT_GET(block->bb_rightsib, ARCH_CONVERT);
+ nextbno = be64_to_cpu(block->bb_rightsib);
while (nextbno != NULLFSBLOCK) {
if ((error = xfs_btree_read_bufl(mp, tp, nextbno,
0, &nbp, XFS_BMAP_BTREE_REF)))
return error;
*count += 1;
nextblock = XFS_BUF_TO_BMBT_BLOCK(nbp);
- nextbno = INT_GET(nextblock->bb_rightsib, ARCH_CONVERT);
+ nextbno = be64_to_cpu(nextblock->bb_rightsib);
xfs_trans_brelse(tp, nbp);
}
@@ -6244,11 +6284,11 @@ xfs_bmap_count_tree(
} else {
/* count all level 1 nodes and their leaves */
for (;;) {
- nextbno = INT_GET(block->bb_rightsib, ARCH_CONVERT);
- numrecs = INT_GET(block->bb_numrecs, ARCH_CONVERT);
+ nextbno = be64_to_cpu(block->bb_rightsib);
+ numrecs = be16_to_cpu(block->bb_numrecs);
frp = XFS_BTREE_REC_ADDR(mp->m_sb.sb_blocksize,
xfs_bmbt, block, 1, mp->m_bmap_dmxr[0]);
- if (unlikely(xfs_bmap_count_leaves(frp, numrecs, count) < 0)) {
+ if (unlikely(xfs_bmap_disk_count_leaves(frp, numrecs, count) < 0)) {
xfs_trans_brelse(tp, bp);
XFS_ERROR_REPORT("xfs_bmap_count_tree(2)",
XFS_ERRLEVEL_LOW, mp);
@@ -6280,6 +6320,22 @@ xfs_bmap_count_leaves(
int b;
for ( b = 1; b <= numrecs; b++, frp++)
+ *count += xfs_bmbt_get_blockcount(frp);
+ return 0;
+}
+
+/*
+ * Count leaf blocks given a pointer to an extent list originally in btree format.
+ */
+int
+xfs_bmap_disk_count_leaves(
+ xfs_bmbt_rec_t *frp,
+ int numrecs,
+ int *count)
+{
+ int b;
+
+ for ( b = 1; b <= numrecs; b++, frp++)
*count += xfs_bmbt_disk_get_blockcount(frp);
return 0;
}
diff --git a/fs/xfs/xfs_bmap.h b/fs/xfs/xfs_bmap.h
index e6d22ec9b2e4..2e0717a01309 100644
--- a/fs/xfs/xfs_bmap.h
+++ b/fs/xfs/xfs_bmap.h
@@ -1,33 +1,19 @@
/*
- * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __XFS_BMAP_H__
#define __XFS_BMAP_H__
@@ -77,12 +63,11 @@ typedef struct xfs_bmap_free
/* combine contig. space */
#define XFS_BMAPI_CONTIG 0x400 /* must allocate only one extent */
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_BMAPI_AFLAG)
-int xfs_bmapi_aflag(int w);
#define XFS_BMAPI_AFLAG(w) xfs_bmapi_aflag(w)
-#else
-#define XFS_BMAPI_AFLAG(w) ((w) == XFS_ATTR_FORK ? XFS_BMAPI_ATTRFORK : 0)
-#endif
+static inline int xfs_bmapi_aflag(int w)
+{
+ return (w == XFS_ATTR_FORK ? XFS_BMAPI_ATTRFORK : 0);
+}
/*
* Special values for xfs_bmbt_irec_t br_startblock field.
@@ -90,14 +75,12 @@ int xfs_bmapi_aflag(int w);
#define DELAYSTARTBLOCK ((xfs_fsblock_t)-1LL)
#define HOLESTARTBLOCK ((xfs_fsblock_t)-2LL)
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_BMAP_INIT)
-void xfs_bmap_init(xfs_bmap_free_t *flp, xfs_fsblock_t *fbp);
#define XFS_BMAP_INIT(flp,fbp) xfs_bmap_init(flp,fbp)
-#else
-#define XFS_BMAP_INIT(flp,fbp) \
+static inline void xfs_bmap_init(xfs_bmap_free_t *flp, xfs_fsblock_t *fbp)
+{
((flp)->xbf_first = NULL, (flp)->xbf_count = 0, \
- (flp)->xbf_low = 0, *(fbp) = NULLFSBLOCK)
-#endif
+ (flp)->xbf_low = 0, *(fbp) = NULLFSBLOCK);
+}
/*
* Argument structure for xfs_bmap_alloc.
@@ -156,7 +139,8 @@ xfs_bmap_trace_exlist(
int /* error code */
xfs_bmap_add_attrfork(
struct xfs_inode *ip, /* incore inode pointer */
- int rsvd); /* flag for reserved block allocation */
+ int size, /* space needed for new attribute */
+ int rsvd); /* flag for reserved block allocation */
/*
* Add the extent to the list of extents to be free at transaction end.
diff --git a/fs/xfs/xfs_bmap_btree.c b/fs/xfs/xfs_bmap_btree.c
index 09a77b17565b..3f1383d160e8 100644
--- a/fs/xfs/xfs_bmap_btree.c
+++ b/fs/xfs/xfs_bmap_btree.c
@@ -1,41 +1,26 @@
/*
- * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-
#include "xfs.h"
-
-#include "xfs_macros.h"
+#include "xfs_fs.h"
#include "xfs_types.h"
-#include "xfs_inum.h"
+#include "xfs_bit.h"
#include "xfs_log.h"
+#include "xfs_inum.h"
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
@@ -43,20 +28,19 @@
#include "xfs_dir2.h"
#include "xfs_dmapi.h"
#include "xfs_mount.h"
-#include "xfs_alloc_btree.h"
#include "xfs_bmap_btree.h"
+#include "xfs_alloc_btree.h"
#include "xfs_ialloc_btree.h"
-#include "xfs_btree.h"
-#include "xfs_ialloc.h"
-#include "xfs_itable.h"
-#include "xfs_attr_sf.h"
#include "xfs_dir_sf.h"
#include "xfs_dir2_sf.h"
+#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
-#include "xfs_inode_item.h"
#include "xfs_inode.h"
+#include "xfs_inode_item.h"
#include "xfs_alloc.h"
-#include "xfs_bit.h"
+#include "xfs_btree.h"
+#include "xfs_ialloc.h"
+#include "xfs_itable.h"
#include "xfs_bmap.h"
#include "xfs_error.h"
#include "xfs_quota.h"
@@ -382,7 +366,7 @@ xfs_bmbt_delrec(
return 0;
}
block = xfs_bmbt_get_block(cur, level, &bp);
- numrecs = INT_GET(block->bb_numrecs, ARCH_CONVERT);
+ numrecs = be16_to_cpu(block->bb_numrecs);
#ifdef DEBUG
if ((error = xfs_btree_check_lblock(cur, block, level, bp))) {
XFS_BMBT_TRACE_CURSOR(cur, ERROR);
@@ -427,7 +411,7 @@ xfs_bmbt_delrec(
}
}
numrecs--;
- INT_SET(block->bb_numrecs, ARCH_CONVERT, numrecs);
+ block->bb_numrecs = cpu_to_be16(numrecs);
xfs_bmbt_log_block(cur, bp, XFS_BB_NUMRECS);
/*
* We're at the root level.
@@ -463,8 +447,8 @@ xfs_bmbt_delrec(
*stat = 1;
return 0;
}
- rbno = INT_GET(block->bb_rightsib, ARCH_CONVERT);
- lbno = INT_GET(block->bb_leftsib, ARCH_CONVERT);
+ rbno = be64_to_cpu(block->bb_rightsib);
+ lbno = be64_to_cpu(block->bb_leftsib);
/*
* One child of root, need to get a chance to copy its contents
* into the root and delete it. Can't go up to next level,
@@ -508,15 +492,15 @@ xfs_bmbt_delrec(
goto error0;
}
#endif
- bno = INT_GET(right->bb_leftsib, ARCH_CONVERT);
- if (INT_GET(right->bb_numrecs, ARCH_CONVERT) - 1 >=
+ bno = be64_to_cpu(right->bb_leftsib);
+ if (be16_to_cpu(right->bb_numrecs) - 1 >=
XFS_BMAP_BLOCK_IMINRECS(level, cur)) {
if ((error = xfs_bmbt_lshift(tcur, level, &i))) {
XFS_BMBT_TRACE_CURSOR(cur, ERROR);
goto error0;
}
if (i) {
- ASSERT(INT_GET(block->bb_numrecs, ARCH_CONVERT) >=
+ ASSERT(be16_to_cpu(block->bb_numrecs) >=
XFS_BMAP_BLOCK_IMINRECS(level, tcur));
xfs_btree_del_cursor(tcur, XFS_BTREE_NOERROR);
tcur = NULL;
@@ -533,7 +517,7 @@ xfs_bmbt_delrec(
return 0;
}
}
- rrecs = INT_GET(right->bb_numrecs, ARCH_CONVERT);
+ rrecs = be16_to_cpu(right->bb_numrecs);
if (lbno != NULLFSBLOCK) {
i = xfs_btree_firstrec(tcur, level);
XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
@@ -564,15 +548,15 @@ xfs_bmbt_delrec(
goto error0;
}
#endif
- bno = INT_GET(left->bb_rightsib, ARCH_CONVERT);
- if (INT_GET(left->bb_numrecs, ARCH_CONVERT) - 1 >=
+ bno = be64_to_cpu(left->bb_rightsib);
+ if (be16_to_cpu(left->bb_numrecs) - 1 >=
XFS_BMAP_BLOCK_IMINRECS(level, cur)) {
if ((error = xfs_bmbt_rshift(tcur, level, &i))) {
XFS_BMBT_TRACE_CURSOR(cur, ERROR);
goto error0;
}
if (i) {
- ASSERT(INT_GET(block->bb_numrecs, ARCH_CONVERT) >=
+ ASSERT(be16_to_cpu(block->bb_numrecs) >=
XFS_BMAP_BLOCK_IMINRECS(level, tcur));
xfs_btree_del_cursor(tcur, XFS_BTREE_NOERROR);
tcur = NULL;
@@ -583,14 +567,14 @@ xfs_bmbt_delrec(
return 0;
}
}
- lrecs = INT_GET(left->bb_numrecs, ARCH_CONVERT);
+ lrecs = be16_to_cpu(left->bb_numrecs);
}
xfs_btree_del_cursor(tcur, XFS_BTREE_NOERROR);
tcur = NULL;
mp = cur->bc_mp;
ASSERT(bno != NULLFSBLOCK);
if (lbno != NULLFSBLOCK &&
- lrecs + INT_GET(block->bb_numrecs, ARCH_CONVERT) <= XFS_BMAP_BLOCK_IMAXRECS(level, cur)) {
+ lrecs + be16_to_cpu(block->bb_numrecs) <= XFS_BMAP_BLOCK_IMAXRECS(level, cur)) {
rbno = bno;
right = block;
rbp = bp;
@@ -605,7 +589,7 @@ xfs_bmbt_delrec(
goto error0;
}
} else if (rbno != NULLFSBLOCK &&
- rrecs + INT_GET(block->bb_numrecs, ARCH_CONVERT) <=
+ rrecs + be16_to_cpu(block->bb_numrecs) <=
XFS_BMAP_BLOCK_IMAXRECS(level, cur)) {
lbno = bno;
left = block;
@@ -620,7 +604,7 @@ xfs_bmbt_delrec(
XFS_BMBT_TRACE_CURSOR(cur, ERROR);
goto error0;
}
- lrecs = INT_GET(left->bb_numrecs, ARCH_CONVERT);
+ lrecs = be16_to_cpu(left->bb_numrecs);
} else {
if (level > 0 && (error = xfs_bmbt_decrement(cur, level, &i))) {
XFS_BMBT_TRACE_CURSOR(cur, ERROR);
@@ -630,8 +614,8 @@ xfs_bmbt_delrec(
*stat = 1;
return 0;
}
- numlrecs = INT_GET(left->bb_numrecs, ARCH_CONVERT);
- numrrecs = INT_GET(right->bb_numrecs, ARCH_CONVERT);
+ numlrecs = be16_to_cpu(left->bb_numrecs);
+ numrrecs = be16_to_cpu(right->bb_numrecs);
if (level > 0) {
lkp = XFS_BMAP_KEY_IADDR(left, numlrecs + 1, cur);
lpp = XFS_BMAP_PTR_IADDR(left, numlrecs + 1, cur);
@@ -655,12 +639,12 @@ xfs_bmbt_delrec(
memcpy(lrp, rrp, numrrecs * sizeof(*lrp));
xfs_bmbt_log_recs(cur, lbp, numlrecs + 1, numlrecs + numrrecs);
}
- INT_MOD(left->bb_numrecs, ARCH_CONVERT, numrrecs);
- left->bb_rightsib = right->bb_rightsib; /* INT_: direct copy */
+ be16_add(&left->bb_numrecs, numrrecs);
+ left->bb_rightsib = right->bb_rightsib;
xfs_bmbt_log_block(cur, lbp, XFS_BB_RIGHTSIB | XFS_BB_NUMRECS);
- if (INT_GET(left->bb_rightsib, ARCH_CONVERT) != NULLDFSBNO) {
+ if (be64_to_cpu(left->bb_rightsib) != NULLDFSBNO) {
if ((error = xfs_btree_read_bufl(mp, cur->bc_tp,
- INT_GET(left->bb_rightsib, ARCH_CONVERT),
+ be64_to_cpu(left->bb_rightsib),
0, &rrbp, XFS_BMAP_BTREE_REF))) {
XFS_BMBT_TRACE_CURSOR(cur, ERROR);
goto error0;
@@ -670,7 +654,7 @@ xfs_bmbt_delrec(
XFS_BMBT_TRACE_CURSOR(cur, ERROR);
goto error0;
}
- INT_SET(rrblock->bb_leftsib, ARCH_CONVERT, lbno);
+ rrblock->bb_leftsib = cpu_to_be64(lbno);
xfs_bmbt_log_block(cur, rrbp, XFS_BB_LEFTSIB);
}
xfs_bmap_add_free(XFS_DADDR_TO_FSB(mp, XFS_BUF_ADDR(rbp)), 1,
@@ -727,7 +711,7 @@ xfs_bmbt_get_rec(
if ((error = xfs_btree_check_lblock(cur, block, 0, bp)))
return error;
#endif
- if (ptr > INT_GET(block->bb_numrecs, ARCH_CONVERT) || ptr <= 0) {
+ if (ptr > be16_to_cpu(block->bb_numrecs) || ptr <= 0) {
*stat = 0;
return 0;
}
@@ -788,7 +772,7 @@ xfs_bmbt_insrec(
}
XFS_STATS_INC(xs_bmbt_insrec);
block = xfs_bmbt_get_block(cur, level, &bp);
- numrecs = INT_GET(block->bb_numrecs, ARCH_CONVERT);
+ numrecs = be16_to_cpu(block->bb_numrecs);
#ifdef DEBUG
if ((error = xfs_btree_check_lblock(cur, block, level, bp))) {
XFS_BMBT_TRACE_CURSOR(cur, ERROR);
@@ -870,7 +854,7 @@ xfs_bmbt_insrec(
}
}
}
- numrecs = INT_GET(block->bb_numrecs, ARCH_CONVERT);
+ numrecs = be16_to_cpu(block->bb_numrecs);
if (level > 0) {
kp = XFS_BMAP_KEY_IADDR(block, 1, cur);
pp = XFS_BMAP_PTR_IADDR(block, 1, cur);
@@ -897,7 +881,7 @@ xfs_bmbt_insrec(
kp[ptr - 1] = key;
INT_SET(pp[ptr - 1], ARCH_CONVERT, *bnop);
numrecs++;
- INT_SET(block->bb_numrecs, ARCH_CONVERT, numrecs);
+ block->bb_numrecs = cpu_to_be16(numrecs);
xfs_bmbt_log_keys(cur, bp, ptr, numrecs);
xfs_bmbt_log_ptrs(cur, bp, ptr, numrecs);
} else {
@@ -906,7 +890,7 @@ xfs_bmbt_insrec(
(numrecs - ptr + 1) * sizeof(*rp));
rp[ptr - 1] = *recp;
numrecs++;
- INT_SET(block->bb_numrecs, ARCH_CONVERT, numrecs);
+ block->bb_numrecs = cpu_to_be16(numrecs);
xfs_bmbt_log_recs(cur, bp, ptr, numrecs);
}
xfs_bmbt_log_block(cur, bp, XFS_BB_NUMRECS);
@@ -971,7 +955,7 @@ xfs_bmbt_killroot(
/*
* Give up if the root has multiple children.
*/
- if (INT_GET(block->bb_numrecs, ARCH_CONVERT) != 1) {
+ if (be16_to_cpu(block->bb_numrecs) != 1) {
XFS_BMBT_TRACE_CURSOR(cur, EXIT);
return 0;
}
@@ -982,37 +966,37 @@ xfs_bmbt_killroot(
*/
cbp = cur->bc_bufs[level - 1];
cblock = XFS_BUF_TO_BMBT_BLOCK(cbp);
- if (INT_GET(cblock->bb_numrecs, ARCH_CONVERT) > XFS_BMAP_BLOCK_DMAXRECS(level, cur)) {
+ if (be16_to_cpu(cblock->bb_numrecs) > XFS_BMAP_BLOCK_DMAXRECS(level, cur)) {
XFS_BMBT_TRACE_CURSOR(cur, EXIT);
return 0;
}
- ASSERT(INT_GET(cblock->bb_leftsib, ARCH_CONVERT) == NULLDFSBNO);
- ASSERT(INT_GET(cblock->bb_rightsib, ARCH_CONVERT) == NULLDFSBNO);
+ ASSERT(be64_to_cpu(cblock->bb_leftsib) == NULLDFSBNO);
+ ASSERT(be64_to_cpu(cblock->bb_rightsib) == NULLDFSBNO);
ip = cur->bc_private.b.ip;
ifp = XFS_IFORK_PTR(ip, cur->bc_private.b.whichfork);
ASSERT(XFS_BMAP_BLOCK_IMAXRECS(level, cur) ==
XFS_BMAP_BROOT_MAXRECS(ifp->if_broot_bytes));
- i = (int)(INT_GET(cblock->bb_numrecs, ARCH_CONVERT) - XFS_BMAP_BLOCK_IMAXRECS(level, cur));
+ i = (int)(be16_to_cpu(cblock->bb_numrecs) - XFS_BMAP_BLOCK_IMAXRECS(level, cur));
if (i) {
xfs_iroot_realloc(ip, i, cur->bc_private.b.whichfork);
block = ifp->if_broot;
}
- INT_MOD(block->bb_numrecs, ARCH_CONVERT, i);
- ASSERT(INT_GET(block->bb_numrecs, ARCH_CONVERT) == INT_GET(cblock->bb_numrecs, ARCH_CONVERT));
+ be16_add(&block->bb_numrecs, i);
+ ASSERT(block->bb_numrecs == cblock->bb_numrecs);
kp = XFS_BMAP_KEY_IADDR(block, 1, cur);
ckp = XFS_BMAP_KEY_IADDR(cblock, 1, cur);
- memcpy(kp, ckp, INT_GET(block->bb_numrecs, ARCH_CONVERT) * sizeof(*kp));
+ memcpy(kp, ckp, be16_to_cpu(block->bb_numrecs) * sizeof(*kp));
pp = XFS_BMAP_PTR_IADDR(block, 1, cur);
cpp = XFS_BMAP_PTR_IADDR(cblock, 1, cur);
#ifdef DEBUG
- for (i = 0; i < INT_GET(cblock->bb_numrecs, ARCH_CONVERT); i++) {
+ for (i = 0; i < be16_to_cpu(cblock->bb_numrecs); i++) {
if ((error = xfs_btree_check_lptr(cur, INT_GET(cpp[i], ARCH_CONVERT), level - 1))) {
XFS_BMBT_TRACE_CURSOR(cur, ERROR);
return error;
}
}
#endif
- memcpy(pp, cpp, INT_GET(block->bb_numrecs, ARCH_CONVERT) * sizeof(*pp));
+ memcpy(pp, cpp, be16_to_cpu(block->bb_numrecs) * sizeof(*pp));
xfs_bmap_add_free(XFS_DADDR_TO_FSB(cur->bc_mp, XFS_BUF_ADDR(cbp)), 1,
cur->bc_private.b.flist, cur->bc_mp);
ip->i_d.di_nblocks--;
@@ -1020,7 +1004,7 @@ xfs_bmbt_killroot(
XFS_TRANS_DQ_BCOUNT, -1L);
xfs_trans_binval(cur->bc_tp, cbp);
cur->bc_bufs[level - 1] = NULL;
- INT_MOD(block->bb_level, ARCH_CONVERT, -1);
+ be16_add(&block->bb_level, -1);
xfs_trans_log_inode(cur->bc_tp, ip,
XFS_ILOG_CORE | XFS_ILOG_FBROOT(cur->bc_private.b.whichfork));
cur->bc_nlevels--;
@@ -1176,7 +1160,7 @@ xfs_bmbt_lookup(
else
krbase = XFS_BMAP_REC_IADDR(block, 1, cur);
low = 1;
- if (!(high = INT_GET(block->bb_numrecs, ARCH_CONVERT))) {
+ if (!(high = be16_to_cpu(block->bb_numrecs))) {
ASSERT(level == 0);
cur->bc_ptrs[0] = dir != XFS_LOOKUP_LE;
XFS_BMBT_TRACE_CURSOR(cur, EXIT);
@@ -1223,8 +1207,8 @@ xfs_bmbt_lookup(
* If ge search and we went off the end of the block, but it's
* not the last block, we're in the wrong block.
*/
- if (dir == XFS_LOOKUP_GE && keyno > INT_GET(block->bb_numrecs, ARCH_CONVERT) &&
- INT_GET(block->bb_rightsib, ARCH_CONVERT) != NULLDFSBNO) {
+ if (dir == XFS_LOOKUP_GE && keyno > be16_to_cpu(block->bb_numrecs) &&
+ be64_to_cpu(block->bb_rightsib) != NULLDFSBNO) {
cur->bc_ptrs[0] = keyno;
if ((error = xfs_bmbt_increment(cur, 0, &i))) {
XFS_BMBT_TRACE_CURSOR(cur, ERROR);
@@ -1239,7 +1223,7 @@ xfs_bmbt_lookup(
else if (dir == XFS_LOOKUP_LE && diff > 0)
keyno--;
cur->bc_ptrs[0] = keyno;
- if (keyno == 0 || keyno > INT_GET(block->bb_numrecs, ARCH_CONVERT)) {
+ if (keyno == 0 || keyno > be16_to_cpu(block->bb_numrecs)) {
XFS_BMBT_TRACE_CURSOR(cur, EXIT);
*stat = 0;
} else {
@@ -1296,7 +1280,7 @@ xfs_bmbt_lshift(
return error;
}
#endif
- if (INT_GET(right->bb_leftsib, ARCH_CONVERT) == NULLDFSBNO) {
+ if (be64_to_cpu(right->bb_leftsib) == NULLDFSBNO) {
XFS_BMBT_TRACE_CURSOR(cur, EXIT);
*stat = 0;
return 0;
@@ -1307,7 +1291,7 @@ xfs_bmbt_lshift(
return 0;
}
mp = cur->bc_mp;
- if ((error = xfs_btree_read_bufl(mp, cur->bc_tp, INT_GET(right->bb_leftsib, ARCH_CONVERT), 0,
+ if ((error = xfs_btree_read_bufl(mp, cur->bc_tp, be64_to_cpu(right->bb_leftsib), 0,
&lbp, XFS_BMAP_BTREE_REF))) {
XFS_BMBT_TRACE_CURSOR(cur, ERROR);
return error;
@@ -1317,12 +1301,12 @@ xfs_bmbt_lshift(
XFS_BMBT_TRACE_CURSOR(cur, ERROR);
return error;
}
- if (INT_GET(left->bb_numrecs, ARCH_CONVERT) == XFS_BMAP_BLOCK_IMAXRECS(level, cur)) {
+ if (be16_to_cpu(left->bb_numrecs) == XFS_BMAP_BLOCK_IMAXRECS(level, cur)) {
XFS_BMBT_TRACE_CURSOR(cur, EXIT);
*stat = 0;
return 0;
}
- lrecs = INT_GET(left->bb_numrecs, ARCH_CONVERT) + 1;
+ lrecs = be16_to_cpu(left->bb_numrecs) + 1;
if (level > 0) {
lkp = XFS_BMAP_KEY_IADDR(left, lrecs, cur);
rkp = XFS_BMAP_KEY_IADDR(right, 1, cur);
@@ -1344,7 +1328,7 @@ xfs_bmbt_lshift(
*lrp = *rrp;
xfs_bmbt_log_recs(cur, lbp, lrecs, lrecs);
}
- INT_SET(left->bb_numrecs, ARCH_CONVERT, lrecs);
+ left->bb_numrecs = cpu_to_be16(lrecs);
xfs_bmbt_log_block(cur, lbp, XFS_BB_NUMRECS);
#ifdef DEBUG
if (level > 0)
@@ -1352,8 +1336,8 @@ xfs_bmbt_lshift(
else
xfs_btree_check_rec(XFS_BTNUM_BMAP, lrp - 1, lrp);
#endif
- rrecs = INT_GET(right->bb_numrecs, ARCH_CONVERT) - 1;
- INT_SET(right->bb_numrecs, ARCH_CONVERT, rrecs);
+ rrecs = be16_to_cpu(right->bb_numrecs) - 1;
+ right->bb_numrecs = cpu_to_be16(rrecs);
xfs_bmbt_log_block(cur, rbp, XFS_BB_NUMRECS);
if (level > 0) {
#ifdef DEBUG
@@ -1430,18 +1414,18 @@ xfs_bmbt_rshift(
return error;
}
#endif
- if (INT_GET(left->bb_rightsib, ARCH_CONVERT) == NULLDFSBNO) {
+ if (be64_to_cpu(left->bb_rightsib) == NULLDFSBNO) {
XFS_BMBT_TRACE_CURSOR(cur, EXIT);
*stat = 0;
return 0;
}
- if (cur->bc_ptrs[level] >= INT_GET(left->bb_numrecs, ARCH_CONVERT)) {
+ if (cur->bc_ptrs[level] >= be16_to_cpu(left->bb_numrecs)) {
XFS_BMBT_TRACE_CURSOR(cur, EXIT);
*stat = 0;
return 0;
}
mp = cur->bc_mp;
- if ((error = xfs_btree_read_bufl(mp, cur->bc_tp, INT_GET(left->bb_rightsib, ARCH_CONVERT), 0,
+ if ((error = xfs_btree_read_bufl(mp, cur->bc_tp, be64_to_cpu(left->bb_rightsib), 0,
&rbp, XFS_BMAP_BTREE_REF))) {
XFS_BMBT_TRACE_CURSOR(cur, ERROR);
return error;
@@ -1451,26 +1435,26 @@ xfs_bmbt_rshift(
XFS_BMBT_TRACE_CURSOR(cur, ERROR);
return error;
}
- if (INT_GET(right->bb_numrecs, ARCH_CONVERT) == XFS_BMAP_BLOCK_IMAXRECS(level, cur)) {
+ if (be16_to_cpu(right->bb_numrecs) == XFS_BMAP_BLOCK_IMAXRECS(level, cur)) {
XFS_BMBT_TRACE_CURSOR(cur, EXIT);
*stat = 0;
return 0;
}
if (level > 0) {
- lkp = XFS_BMAP_KEY_IADDR(left, INT_GET(left->bb_numrecs, ARCH_CONVERT), cur);
- lpp = XFS_BMAP_PTR_IADDR(left, INT_GET(left->bb_numrecs, ARCH_CONVERT), cur);
+ lkp = XFS_BMAP_KEY_IADDR(left, be16_to_cpu(left->bb_numrecs), cur);
+ lpp = XFS_BMAP_PTR_IADDR(left, be16_to_cpu(left->bb_numrecs), cur);
rkp = XFS_BMAP_KEY_IADDR(right, 1, cur);
rpp = XFS_BMAP_PTR_IADDR(right, 1, cur);
#ifdef DEBUG
- for (i = INT_GET(right->bb_numrecs, ARCH_CONVERT) - 1; i >= 0; i--) {
+ for (i = be16_to_cpu(right->bb_numrecs) - 1; i >= 0; i--) {
if ((error = xfs_btree_check_lptr(cur, INT_GET(rpp[i], ARCH_CONVERT), level))) {
XFS_BMBT_TRACE_CURSOR(cur, ERROR);
return error;
}
}
#endif
- memmove(rkp + 1, rkp, INT_GET(right->bb_numrecs, ARCH_CONVERT) * sizeof(*rkp));
- memmove(rpp + 1, rpp, INT_GET(right->bb_numrecs, ARCH_CONVERT) * sizeof(*rpp));
+ memmove(rkp + 1, rkp, be16_to_cpu(right->bb_numrecs) * sizeof(*rkp));
+ memmove(rpp + 1, rpp, be16_to_cpu(right->bb_numrecs) * sizeof(*rpp));
#ifdef DEBUG
if ((error = xfs_btree_check_lptr(cur, INT_GET(*lpp, ARCH_CONVERT), level))) {
XFS_BMBT_TRACE_CURSOR(cur, ERROR);
@@ -1479,21 +1463,21 @@ xfs_bmbt_rshift(
#endif
*rkp = *lkp;
*rpp = *lpp; /* INT_: direct copy */
- xfs_bmbt_log_keys(cur, rbp, 1, INT_GET(right->bb_numrecs, ARCH_CONVERT) + 1);
- xfs_bmbt_log_ptrs(cur, rbp, 1, INT_GET(right->bb_numrecs, ARCH_CONVERT) + 1);
+ xfs_bmbt_log_keys(cur, rbp, 1, be16_to_cpu(right->bb_numrecs) + 1);
+ xfs_bmbt_log_ptrs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs) + 1);
} else {
- lrp = XFS_BMAP_REC_IADDR(left, INT_GET(left->bb_numrecs, ARCH_CONVERT), cur);
+ lrp = XFS_BMAP_REC_IADDR(left, be16_to_cpu(left->bb_numrecs), cur);
rrp = XFS_BMAP_REC_IADDR(right, 1, cur);
- memmove(rrp + 1, rrp, INT_GET(right->bb_numrecs, ARCH_CONVERT) * sizeof(*rrp));
+ memmove(rrp + 1, rrp, be16_to_cpu(right->bb_numrecs) * sizeof(*rrp));
*rrp = *lrp;
- xfs_bmbt_log_recs(cur, rbp, 1, INT_GET(right->bb_numrecs, ARCH_CONVERT) + 1);
+ xfs_bmbt_log_recs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs) + 1);
INT_SET(key.br_startoff, ARCH_CONVERT,
xfs_bmbt_disk_get_startoff(rrp));
rkp = &key;
}
- INT_MOD(left->bb_numrecs, ARCH_CONVERT, -1);
+ be16_add(&left->bb_numrecs, -1);
xfs_bmbt_log_block(cur, lbp, XFS_BB_NUMRECS);
- INT_MOD(right->bb_numrecs, ARCH_CONVERT, +1);
+ be16_add(&right->bb_numrecs, 1);
#ifdef DEBUG
if (level > 0)
xfs_btree_check_key(XFS_BTNUM_BMAP, rkp, rkp + 1);
@@ -1624,47 +1608,47 @@ xfs_bmbt_split(
return error;
}
#endif
- INT_SET(right->bb_magic, ARCH_CONVERT, XFS_BMAP_MAGIC);
- right->bb_level = left->bb_level; /* INT_: direct copy */
- INT_SET(right->bb_numrecs, ARCH_CONVERT, (__uint16_t)(INT_GET(left->bb_numrecs, ARCH_CONVERT) / 2));
- if ((INT_GET(left->bb_numrecs, ARCH_CONVERT) & 1) &&
- cur->bc_ptrs[level] <= INT_GET(right->bb_numrecs, ARCH_CONVERT) + 1)
- INT_MOD(right->bb_numrecs, ARCH_CONVERT, +1);
- i = INT_GET(left->bb_numrecs, ARCH_CONVERT) - INT_GET(right->bb_numrecs, ARCH_CONVERT) + 1;
+ right->bb_magic = cpu_to_be32(XFS_BMAP_MAGIC);
+ right->bb_level = left->bb_level;
+ right->bb_numrecs = cpu_to_be16(be16_to_cpu(left->bb_numrecs) / 2);
+ if ((be16_to_cpu(left->bb_numrecs) & 1) &&
+ cur->bc_ptrs[level] <= be16_to_cpu(right->bb_numrecs) + 1)
+ be16_add(&right->bb_numrecs, 1);
+ i = be16_to_cpu(left->bb_numrecs) - be16_to_cpu(right->bb_numrecs) + 1;
if (level > 0) {
lkp = XFS_BMAP_KEY_IADDR(left, i, cur);
lpp = XFS_BMAP_PTR_IADDR(left, i, cur);
rkp = XFS_BMAP_KEY_IADDR(right, 1, cur);
rpp = XFS_BMAP_PTR_IADDR(right, 1, cur);
#ifdef DEBUG
- for (i = 0; i < INT_GET(right->bb_numrecs, ARCH_CONVERT); i++) {
+ for (i = 0; i < be16_to_cpu(right->bb_numrecs); i++) {
if ((error = xfs_btree_check_lptr(cur, INT_GET(lpp[i], ARCH_CONVERT), level))) {
XFS_BMBT_TRACE_CURSOR(cur, ERROR);
return error;
}
}
#endif
- memcpy(rkp, lkp, INT_GET(right->bb_numrecs, ARCH_CONVERT) * sizeof(*rkp));
- memcpy(rpp, lpp, INT_GET(right->bb_numrecs, ARCH_CONVERT) * sizeof(*rpp));
- xfs_bmbt_log_keys(cur, rbp, 1, INT_GET(right->bb_numrecs, ARCH_CONVERT));
- xfs_bmbt_log_ptrs(cur, rbp, 1, INT_GET(right->bb_numrecs, ARCH_CONVERT));
+ memcpy(rkp, lkp, be16_to_cpu(right->bb_numrecs) * sizeof(*rkp));
+ memcpy(rpp, lpp, be16_to_cpu(right->bb_numrecs) * sizeof(*rpp));
+ xfs_bmbt_log_keys(cur, rbp, 1, be16_to_cpu(right->bb_numrecs));
+ xfs_bmbt_log_ptrs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs));
keyp->br_startoff = INT_GET(rkp->br_startoff, ARCH_CONVERT);
} else {
lrp = XFS_BMAP_REC_IADDR(left, i, cur);
rrp = XFS_BMAP_REC_IADDR(right, 1, cur);
- memcpy(rrp, lrp, INT_GET(right->bb_numrecs, ARCH_CONVERT) * sizeof(*rrp));
- xfs_bmbt_log_recs(cur, rbp, 1, INT_GET(right->bb_numrecs, ARCH_CONVERT));
+ memcpy(rrp, lrp, be16_to_cpu(right->bb_numrecs) * sizeof(*rrp));
+ xfs_bmbt_log_recs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs));
keyp->br_startoff = xfs_bmbt_disk_get_startoff(rrp);
}
- INT_MOD(left->bb_numrecs, ARCH_CONVERT, -(INT_GET(right->bb_numrecs, ARCH_CONVERT)));
- right->bb_rightsib = left->bb_rightsib; /* INT_: direct copy */
- INT_SET(left->bb_rightsib, ARCH_CONVERT, args.fsbno);
- INT_SET(right->bb_leftsib, ARCH_CONVERT, lbno);
+ be16_add(&left->bb_numrecs, -(be16_to_cpu(right->bb_numrecs)));
+ right->bb_rightsib = left->bb_rightsib;
+ left->bb_rightsib = cpu_to_be64(args.fsbno);
+ right->bb_leftsib = cpu_to_be64(lbno);
xfs_bmbt_log_block(cur, rbp, XFS_BB_ALL_BITS);
xfs_bmbt_log_block(cur, lbp, XFS_BB_NUMRECS | XFS_BB_RIGHTSIB);
- if (INT_GET(right->bb_rightsib, ARCH_CONVERT) != NULLDFSBNO) {
+ if (be64_to_cpu(right->bb_rightsib) != NULLDFSBNO) {
if ((error = xfs_btree_read_bufl(args.mp, args.tp,
- INT_GET(right->bb_rightsib, ARCH_CONVERT), 0, &rrbp,
+ be64_to_cpu(right->bb_rightsib), 0, &rrbp,
XFS_BMAP_BTREE_REF))) {
XFS_BMBT_TRACE_CURSOR(cur, ERROR);
return error;
@@ -1674,12 +1658,12 @@ xfs_bmbt_split(
XFS_BMBT_TRACE_CURSOR(cur, ERROR);
return error;
}
- INT_SET(rrblock->bb_leftsib, ARCH_CONVERT, args.fsbno);
+ rrblock->bb_leftsib = cpu_to_be64(args.fsbno);
xfs_bmbt_log_block(cur, rrbp, XFS_BB_LEFTSIB);
}
- if (cur->bc_ptrs[level] > INT_GET(left->bb_numrecs, ARCH_CONVERT) + 1) {
+ if (cur->bc_ptrs[level] > be16_to_cpu(left->bb_numrecs) + 1) {
xfs_btree_setbuf(cur, level, rbp);
- cur->bc_ptrs[level] -= INT_GET(left->bb_numrecs, ARCH_CONVERT);
+ cur->bc_ptrs[level] -= be16_to_cpu(left->bb_numrecs);
}
if (level + 1 < cur->bc_nlevels) {
if ((error = xfs_btree_dup_cursor(cur, curp))) {
@@ -1751,18 +1735,18 @@ xfs_bmdr_to_bmbt(
xfs_bmbt_key_t *tkp;
xfs_bmbt_ptr_t *tpp;
- INT_SET(rblock->bb_magic, ARCH_CONVERT, XFS_BMAP_MAGIC);
- rblock->bb_level = dblock->bb_level; /* both in on-disk format */
- ASSERT(INT_GET(rblock->bb_level, ARCH_CONVERT) > 0);
- rblock->bb_numrecs = dblock->bb_numrecs;/* both in on-disk format */
- INT_SET(rblock->bb_leftsib, ARCH_CONVERT, NULLDFSBNO);
- INT_SET(rblock->bb_rightsib, ARCH_CONVERT, NULLDFSBNO);
+ rblock->bb_magic = cpu_to_be32(XFS_BMAP_MAGIC);
+ rblock->bb_level = dblock->bb_level;
+ ASSERT(be16_to_cpu(rblock->bb_level) > 0);
+ rblock->bb_numrecs = dblock->bb_numrecs;
+ rblock->bb_leftsib = cpu_to_be64(NULLDFSBNO);
+ rblock->bb_rightsib = cpu_to_be64(NULLDFSBNO);
dmxr = (int)XFS_BTREE_BLOCK_MAXRECS(dblocklen, xfs_bmdr, 0);
fkp = XFS_BTREE_KEY_ADDR(dblocklen, xfs_bmdr, dblock, 1, dmxr);
tkp = XFS_BMAP_BROOT_KEY_ADDR(rblock, 1, rblocklen);
fpp = XFS_BTREE_PTR_ADDR(dblocklen, xfs_bmdr, dblock, 1, dmxr);
tpp = XFS_BMAP_BROOT_PTR_ADDR(rblock, 1, rblocklen);
- dmxr = INT_GET(dblock->bb_numrecs, ARCH_CONVERT);
+ dmxr = be16_to_cpu(dblock->bb_numrecs);
memcpy(tkp, fkp, sizeof(*fkp) * dmxr);
memcpy(tpp, fpp, sizeof(*fpp) * dmxr); /* INT_: direct copy */
}
@@ -1805,7 +1789,7 @@ xfs_bmbt_decrement(
return error;
}
#endif
- if (INT_GET(block->bb_leftsib, ARCH_CONVERT) == NULLDFSBNO) {
+ if (be64_to_cpu(block->bb_leftsib) == NULLDFSBNO) {
XFS_BMBT_TRACE_CURSOR(cur, EXIT);
*stat = 0;
return 0;
@@ -1837,7 +1821,7 @@ xfs_bmbt_decrement(
XFS_BMBT_TRACE_CURSOR(cur, ERROR);
return error;
}
- cur->bc_ptrs[lev] = INT_GET(block->bb_numrecs, ARCH_CONVERT);
+ cur->bc_ptrs[lev] = be16_to_cpu(block->bb_numrecs);
}
XFS_BMBT_TRACE_CURSOR(cur, EXIT);
*stat = 1;
@@ -2123,12 +2107,12 @@ xfs_bmbt_increment(
return error;
}
#endif
- if (++cur->bc_ptrs[level] <= INT_GET(block->bb_numrecs, ARCH_CONVERT)) {
+ if (++cur->bc_ptrs[level] <= be16_to_cpu(block->bb_numrecs)) {
XFS_BMBT_TRACE_CURSOR(cur, EXIT);
*stat = 1;
return 0;
}
- if (INT_GET(block->bb_rightsib, ARCH_CONVERT) == NULLDFSBNO) {
+ if (be64_to_cpu(block->bb_rightsib) == NULLDFSBNO) {
XFS_BMBT_TRACE_CURSOR(cur, EXIT);
*stat = 0;
return 0;
@@ -2141,7 +2125,7 @@ xfs_bmbt_increment(
return error;
}
#endif
- if (++cur->bc_ptrs[lev] <= INT_GET(block->bb_numrecs, ARCH_CONVERT))
+ if (++cur->bc_ptrs[lev] <= be16_to_cpu(block->bb_numrecs))
break;
if (lev < cur->bc_nlevels - 1)
xfs_btree_readahead(cur, lev, XFS_BTCUR_RIGHTRA);
@@ -2403,23 +2387,23 @@ xfs_bmbt_newroot(
bp = xfs_btree_get_bufl(args.mp, cur->bc_tp, args.fsbno, 0);
cblock = XFS_BUF_TO_BMBT_BLOCK(bp);
*cblock = *block;
- INT_MOD(block->bb_level, ARCH_CONVERT, +1);
- INT_SET(block->bb_numrecs, ARCH_CONVERT, 1);
+ be16_add(&block->bb_level, 1);
+ block->bb_numrecs = cpu_to_be16(1);
cur->bc_nlevels++;
cur->bc_ptrs[level + 1] = 1;
kp = XFS_BMAP_KEY_IADDR(block, 1, cur);
ckp = XFS_BMAP_KEY_IADDR(cblock, 1, cur);
- memcpy(ckp, kp, INT_GET(cblock->bb_numrecs, ARCH_CONVERT) * sizeof(*kp));
+ memcpy(ckp, kp, be16_to_cpu(cblock->bb_numrecs) * sizeof(*kp));
cpp = XFS_BMAP_PTR_IADDR(cblock, 1, cur);
#ifdef DEBUG
- for (i = 0; i < INT_GET(cblock->bb_numrecs, ARCH_CONVERT); i++) {
+ for (i = 0; i < be16_to_cpu(cblock->bb_numrecs); i++) {
if ((error = xfs_btree_check_lptr(cur, INT_GET(pp[i], ARCH_CONVERT), level))) {
XFS_BMBT_TRACE_CURSOR(cur, ERROR);
return error;
}
}
#endif
- memcpy(cpp, pp, INT_GET(cblock->bb_numrecs, ARCH_CONVERT) * sizeof(*pp));
+ memcpy(cpp, pp, be16_to_cpu(cblock->bb_numrecs) * sizeof(*pp));
#ifdef DEBUG
if ((error = xfs_btree_check_lptr(cur, (xfs_bmbt_ptr_t)args.fsbno,
level))) {
@@ -2428,7 +2412,7 @@ xfs_bmbt_newroot(
}
#endif
INT_SET(*pp, ARCH_CONVERT, args.fsbno);
- xfs_iroot_realloc(cur->bc_private.b.ip, 1 - INT_GET(cblock->bb_numrecs, ARCH_CONVERT),
+ xfs_iroot_realloc(cur->bc_private.b.ip, 1 - be16_to_cpu(cblock->bb_numrecs),
cur->bc_private.b.whichfork);
xfs_btree_setbuf(cur, level, bp);
/*
@@ -2436,8 +2420,8 @@ xfs_bmbt_newroot(
* the root is at the right level.
*/
xfs_bmbt_log_block(cur, bp, XFS_BB_ALL_BITS);
- xfs_bmbt_log_keys(cur, bp, 1, INT_GET(cblock->bb_numrecs, ARCH_CONVERT));
- xfs_bmbt_log_ptrs(cur, bp, 1, INT_GET(cblock->bb_numrecs, ARCH_CONVERT));
+ xfs_bmbt_log_keys(cur, bp, 1, be16_to_cpu(cblock->bb_numrecs));
+ xfs_bmbt_log_ptrs(cur, bp, 1, be16_to_cpu(cblock->bb_numrecs));
XFS_BMBT_TRACE_CURSOR(cur, EXIT);
*logflags |=
XFS_ILOG_CORE | XFS_ILOG_FBROOT(cur->bc_private.b.whichfork);
@@ -2705,18 +2689,18 @@ xfs_bmbt_to_bmdr(
xfs_bmbt_key_t *tkp;
xfs_bmbt_ptr_t *tpp;
- ASSERT(INT_GET(rblock->bb_magic, ARCH_CONVERT) == XFS_BMAP_MAGIC);
- ASSERT(INT_GET(rblock->bb_leftsib, ARCH_CONVERT) == NULLDFSBNO);
- ASSERT(INT_GET(rblock->bb_rightsib, ARCH_CONVERT) == NULLDFSBNO);
- ASSERT(INT_GET(rblock->bb_level, ARCH_CONVERT) > 0);
- dblock->bb_level = rblock->bb_level; /* both in on-disk format */
- dblock->bb_numrecs = rblock->bb_numrecs;/* both in on-disk format */
+ ASSERT(be32_to_cpu(rblock->bb_magic) == XFS_BMAP_MAGIC);
+ ASSERT(be64_to_cpu(rblock->bb_leftsib) == NULLDFSBNO);
+ ASSERT(be64_to_cpu(rblock->bb_rightsib) == NULLDFSBNO);
+ ASSERT(be16_to_cpu(rblock->bb_level) > 0);
+ dblock->bb_level = rblock->bb_level;
+ dblock->bb_numrecs = rblock->bb_numrecs;
dmxr = (int)XFS_BTREE_BLOCK_MAXRECS(dblocklen, xfs_bmdr, 0);
fkp = XFS_BMAP_BROOT_KEY_ADDR(rblock, 1, rblocklen);
tkp = XFS_BTREE_KEY_ADDR(dblocklen, xfs_bmdr, dblock, 1, dmxr);
fpp = XFS_BMAP_BROOT_PTR_ADDR(rblock, 1, rblocklen);
tpp = XFS_BTREE_PTR_ADDR(dblocklen, xfs_bmdr, dblock, 1, dmxr);
- dmxr = INT_GET(dblock->bb_numrecs, ARCH_CONVERT);
+ dmxr = be16_to_cpu(dblock->bb_numrecs);
memcpy(tkp, fkp, sizeof(*fkp) * dmxr);
memcpy(tpp, fpp, sizeof(*fpp) * dmxr); /* INT_: direct copy */
}
diff --git a/fs/xfs/xfs_bmap_btree.h b/fs/xfs/xfs_bmap_btree.h
index 2cf4fe45cbcb..e095a2d344ae 100644
--- a/fs/xfs/xfs_bmap_btree.h
+++ b/fs/xfs/xfs_bmap_btree.h
@@ -1,33 +1,19 @@
/*
- * Copyright (c) 2000,2002-2004 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000,2002-2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __XFS_BMAP_BTREE_H__
#define __XFS_BMAP_BTREE_H__
@@ -42,10 +28,9 @@ struct xfs_inode;
/*
* Bmap root header, on-disk form only.
*/
-typedef struct xfs_bmdr_block
-{
- __uint16_t bb_level; /* 0 is a leaf */
- __uint16_t bb_numrecs; /* current # of data records */
+typedef struct xfs_bmdr_block {
+ __be16 bb_level; /* 0 is a leaf */
+ __be16 bb_numrecs; /* current # of data records */
} xfs_bmdr_block_t;
/*
@@ -114,31 +99,31 @@ typedef xfs_bmbt_rec_64_t xfs_bmbt_rec_t, xfs_bmdr_rec_t;
(((((xfs_fsblock_t)1) << STARTBLOCKMASKBITS) - 1) << STARTBLOCKVALBITS)
#define DSTARTBLOCKMASK \
(((((xfs_dfsbno_t)1) << DSTARTBLOCKMASKBITS) - 1) << STARTBLOCKVALBITS)
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_ISNULLSTARTBLOCK)
-int isnullstartblock(xfs_fsblock_t x);
+
#define ISNULLSTARTBLOCK(x) isnullstartblock(x)
-#else
-#define ISNULLSTARTBLOCK(x) (((x) & STARTBLOCKMASK) == STARTBLOCKMASK)
-#endif
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_ISNULLDSTARTBLOCK)
-int isnulldstartblock(xfs_dfsbno_t x);
+static inline int isnullstartblock(xfs_fsblock_t x)
+{
+ return ((x) & STARTBLOCKMASK) == STARTBLOCKMASK;
+}
+
#define ISNULLDSTARTBLOCK(x) isnulldstartblock(x)
-#else
-#define ISNULLDSTARTBLOCK(x) (((x) & DSTARTBLOCKMASK) == DSTARTBLOCKMASK)
-#endif
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_NULLSTARTBLOCK)
-xfs_fsblock_t nullstartblock(int k);
+static inline int isnulldstartblock(xfs_dfsbno_t x)
+{
+ return ((x) & DSTARTBLOCKMASK) == DSTARTBLOCKMASK;
+}
+
#define NULLSTARTBLOCK(k) nullstartblock(k)
-#else
-#define NULLSTARTBLOCK(k) \
- ((ASSERT(k < (1 << STARTBLOCKVALBITS))), (STARTBLOCKMASK | (k)))
-#endif
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_STARTBLOCKVAL)
-xfs_filblks_t startblockval(xfs_fsblock_t x);
+static inline xfs_fsblock_t nullstartblock(int k)
+{
+ ASSERT(k < (1 << STARTBLOCKVALBITS));
+ return STARTBLOCKMASK | (k);
+}
+
#define STARTBLOCKVAL(x) startblockval(x)
-#else
-#define STARTBLOCKVAL(x) ((xfs_filblks_t)((x) & ~STARTBLOCKMASK))
-#endif
+static inline xfs_filblks_t startblockval(xfs_fsblock_t x)
+{
+ return (xfs_filblks_t)((x) & ~STARTBLOCKMASK);
+}
/*
* Possible extent formats.
@@ -159,14 +144,9 @@ typedef enum {
/*
* Extent state and extent format macros.
*/
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_EXTFMT_INODE )
-xfs_exntfmt_t xfs_extfmt_inode(struct xfs_inode *ip);
-#define XFS_EXTFMT_INODE(x) xfs_extfmt_inode(x)
-#else
-#define XFS_EXTFMT_INODE(x) \
- (XFS_SB_VERSION_HASEXTFLGBIT(&((x)->i_mount->m_sb)) ? \
- XFS_EXTFMT_HASSTATE : XFS_EXTFMT_NOSTATE)
-#endif
+#define XFS_EXTFMT_INODE(x) \
+ (XFS_SB_VERSION_HASEXTFLGBIT(&((x)->i_mount->m_sb)) ? \
+ XFS_EXTFMT_HASSTATE : XFS_EXTFMT_NOSTATE)
#define ISUNWRITTEN(x) ((x)->br_state == XFS_EXT_UNWRITTEN)
/*
@@ -192,248 +172,110 @@ typedef xfs_dfsbno_t xfs_bmbt_ptr_t, xfs_bmdr_ptr_t; /* btree pointer type */
/* btree block header type */
typedef struct xfs_btree_lblock xfs_bmbt_block_t;
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_BUF_TO_BMBT_BLOCK)
-xfs_bmbt_block_t *xfs_buf_to_bmbt_block(struct xfs_buf *bp);
-#define XFS_BUF_TO_BMBT_BLOCK(bp) xfs_buf_to_bmbt_block(bp)
-#else
-#define XFS_BUF_TO_BMBT_BLOCK(bp) ((xfs_bmbt_block_t *)(XFS_BUF_PTR(bp)))
-#endif
+#define XFS_BUF_TO_BMBT_BLOCK(bp) ((xfs_bmbt_block_t *)XFS_BUF_PTR(bp))
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_BMAP_RBLOCK_DSIZE)
-int xfs_bmap_rblock_dsize(int lev, struct xfs_btree_cur *cur);
-#define XFS_BMAP_RBLOCK_DSIZE(lev,cur) xfs_bmap_rblock_dsize(lev,cur)
-#else
-#define XFS_BMAP_RBLOCK_DSIZE(lev,cur) ((cur)->bc_private.b.forksize)
-#endif
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_BMAP_RBLOCK_ISIZE)
-int xfs_bmap_rblock_isize(int lev, struct xfs_btree_cur *cur);
-#define XFS_BMAP_RBLOCK_ISIZE(lev,cur) xfs_bmap_rblock_isize(lev,cur)
-#else
-#define XFS_BMAP_RBLOCK_ISIZE(lev,cur) \
+#define XFS_BMAP_IBLOCK_SIZE(lev,cur) (1 << (cur)->bc_blocklog)
+#define XFS_BMAP_RBLOCK_DSIZE(lev,cur) ((cur)->bc_private.b.forksize)
+#define XFS_BMAP_RBLOCK_ISIZE(lev,cur) \
((int)XFS_IFORK_PTR((cur)->bc_private.b.ip, \
- (cur)->bc_private.b.whichfork)->if_broot_bytes)
-#endif
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_BMAP_IBLOCK_SIZE)
-int xfs_bmap_iblock_size(int lev, struct xfs_btree_cur *cur);
-#define XFS_BMAP_IBLOCK_SIZE(lev,cur) xfs_bmap_iblock_size(lev,cur)
-#else
-#define XFS_BMAP_IBLOCK_SIZE(lev,cur) (1 << (cur)->bc_blocklog)
-#endif
+ (cur)->bc_private.b.whichfork)->if_broot_bytes)
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_BMAP_BLOCK_DSIZE)
-int xfs_bmap_block_dsize(int lev, struct xfs_btree_cur *cur);
-#define XFS_BMAP_BLOCK_DSIZE(lev,cur) xfs_bmap_block_dsize(lev,cur)
-#else
-#define XFS_BMAP_BLOCK_DSIZE(lev,cur) \
- ((lev) == (cur)->bc_nlevels - 1 ? \
- XFS_BMAP_RBLOCK_DSIZE(lev,cur) : \
- XFS_BMAP_IBLOCK_SIZE(lev,cur))
-#endif
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_BMAP_BLOCK_ISIZE)
-int xfs_bmap_block_isize(int lev, struct xfs_btree_cur *cur);
-#define XFS_BMAP_BLOCK_ISIZE(lev,cur) xfs_bmap_block_isize(lev,cur)
-#else
-#define XFS_BMAP_BLOCK_ISIZE(lev,cur) \
- ((lev) == (cur)->bc_nlevels - 1 ? \
- XFS_BMAP_RBLOCK_ISIZE(lev,cur) : \
- XFS_BMAP_IBLOCK_SIZE(lev,cur))
-#endif
+#define XFS_BMAP_BLOCK_DSIZE(lev,cur) \
+ (((lev) == (cur)->bc_nlevels - 1 ? \
+ XFS_BMAP_RBLOCK_DSIZE(lev,cur) : XFS_BMAP_IBLOCK_SIZE(lev,cur)))
+#define XFS_BMAP_BLOCK_ISIZE(lev,cur) \
+ (((lev) == (cur)->bc_nlevels - 1 ? \
+ XFS_BMAP_RBLOCK_ISIZE(lev,cur) : XFS_BMAP_IBLOCK_SIZE(lev,cur)))
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_BMAP_BLOCK_DMAXRECS)
-int xfs_bmap_block_dmaxrecs(int lev, struct xfs_btree_cur *cur);
-#define XFS_BMAP_BLOCK_DMAXRECS(lev,cur) xfs_bmap_block_dmaxrecs(lev,cur)
-#else
#define XFS_BMAP_BLOCK_DMAXRECS(lev,cur) \
- ((lev) == (cur)->bc_nlevels - 1 ? \
+ (((lev) == (cur)->bc_nlevels - 1 ? \
XFS_BTREE_BLOCK_MAXRECS(XFS_BMAP_RBLOCK_DSIZE(lev,cur), \
xfs_bmdr, (lev) == 0) : \
- ((cur)->bc_mp->m_bmap_dmxr[(lev) != 0]))
-#endif
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_BMAP_BLOCK_IMAXRECS)
-int xfs_bmap_block_imaxrecs(int lev, struct xfs_btree_cur *cur);
-#define XFS_BMAP_BLOCK_IMAXRECS(lev,cur) xfs_bmap_block_imaxrecs(lev,cur)
-#else
+ ((cur)->bc_mp->m_bmap_dmxr[(lev) != 0])))
#define XFS_BMAP_BLOCK_IMAXRECS(lev,cur) \
- ((lev) == (cur)->bc_nlevels - 1 ? \
- XFS_BTREE_BLOCK_MAXRECS(XFS_BMAP_RBLOCK_ISIZE(lev,cur), \
- xfs_bmbt, (lev) == 0) : \
- ((cur)->bc_mp->m_bmap_dmxr[(lev) != 0]))
-#endif
+ (((lev) == (cur)->bc_nlevels - 1 ? \
+ XFS_BTREE_BLOCK_MAXRECS(XFS_BMAP_RBLOCK_ISIZE(lev,cur),\
+ xfs_bmbt, (lev) == 0) : \
+ ((cur)->bc_mp->m_bmap_dmxr[(lev) != 0])))
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_BMAP_BLOCK_DMINRECS)
-int xfs_bmap_block_dminrecs(int lev, struct xfs_btree_cur *cur);
-#define XFS_BMAP_BLOCK_DMINRECS(lev,cur) xfs_bmap_block_dminrecs(lev,cur)
-#else
#define XFS_BMAP_BLOCK_DMINRECS(lev,cur) \
- ((lev) == (cur)->bc_nlevels - 1 ? \
- XFS_BTREE_BLOCK_MINRECS(XFS_BMAP_RBLOCK_DSIZE(lev,cur), \
- xfs_bmdr, (lev) == 0) : \
- ((cur)->bc_mp->m_bmap_dmnr[(lev) != 0]))
-#endif
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_BMAP_BLOCK_IMINRECS)
-int xfs_bmap_block_iminrecs(int lev, struct xfs_btree_cur *cur);
-#define XFS_BMAP_BLOCK_IMINRECS(lev,cur) xfs_bmap_block_iminrecs(lev,cur)
-#else
+ (((lev) == (cur)->bc_nlevels - 1 ? \
+ XFS_BTREE_BLOCK_MINRECS(XFS_BMAP_RBLOCK_DSIZE(lev,cur),\
+ xfs_bmdr, (lev) == 0) : \
+ ((cur)->bc_mp->m_bmap_dmnr[(lev) != 0])))
#define XFS_BMAP_BLOCK_IMINRECS(lev,cur) \
- ((lev) == (cur)->bc_nlevels - 1 ? \
- XFS_BTREE_BLOCK_MINRECS(XFS_BMAP_RBLOCK_ISIZE(lev,cur), \
- xfs_bmbt, (lev) == 0) : \
- ((cur)->bc_mp->m_bmap_dmnr[(lev) != 0]))
-#endif
-
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_BMAP_REC_DADDR)
-xfs_bmbt_rec_t *
-xfs_bmap_rec_daddr(xfs_bmbt_block_t *bb, int i, struct xfs_btree_cur *cur);
-#define XFS_BMAP_REC_DADDR(bb,i,cur) xfs_bmap_rec_daddr(bb,i,cur)
-#else
-#define XFS_BMAP_REC_DADDR(bb,i,cur) \
- XFS_BTREE_REC_ADDR(XFS_BMAP_BLOCK_DSIZE( \
- INT_GET((bb)->bb_level, ARCH_CONVERT), cur), \
- xfs_bmbt, bb, i, XFS_BMAP_BLOCK_DMAXRECS( \
- INT_GET((bb)->bb_level, ARCH_CONVERT), cur))
-#endif
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_BMAP_REC_IADDR)
-xfs_bmbt_rec_t *
-xfs_bmap_rec_iaddr(xfs_bmbt_block_t *bb, int i, struct xfs_btree_cur *cur);
-#define XFS_BMAP_REC_IADDR(bb,i,cur) xfs_bmap_rec_iaddr(bb,i,cur)
-#else
-#define XFS_BMAP_REC_IADDR(bb,i,cur) \
- XFS_BTREE_REC_ADDR(XFS_BMAP_BLOCK_ISIZE( \
- INT_GET((bb)->bb_level, ARCH_CONVERT), cur), \
- xfs_bmbt, bb, i, XFS_BMAP_BLOCK_IMAXRECS( \
- INT_GET((bb)->bb_level, ARCH_CONVERT), cur))
-#endif
-
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_BMAP_KEY_DADDR)
-xfs_bmbt_key_t *
-xfs_bmap_key_daddr(xfs_bmbt_block_t *bb, int i, struct xfs_btree_cur *cur);
-#define XFS_BMAP_KEY_DADDR(bb,i,cur) xfs_bmap_key_daddr(bb,i,cur)
-#else
-#define XFS_BMAP_KEY_DADDR(bb,i,cur) \
- XFS_BTREE_KEY_ADDR(XFS_BMAP_BLOCK_DSIZE( \
- INT_GET((bb)->bb_level, ARCH_CONVERT), cur), \
- xfs_bmbt, bb, i, XFS_BMAP_BLOCK_DMAXRECS( \
- INT_GET((bb)->bb_level, ARCH_CONVERT), cur))
-#endif
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_BMAP_KEY_IADDR)
-xfs_bmbt_key_t *
-xfs_bmap_key_iaddr(xfs_bmbt_block_t *bb, int i, struct xfs_btree_cur *cur);
-#define XFS_BMAP_KEY_IADDR(bb,i,cur) xfs_bmap_key_iaddr(bb,i,cur)
-#else
-#define XFS_BMAP_KEY_IADDR(bb,i,cur) \
- XFS_BTREE_KEY_ADDR(XFS_BMAP_BLOCK_ISIZE( \
- INT_GET((bb)->bb_level, ARCH_CONVERT), cur), \
- xfs_bmbt, bb, i, XFS_BMAP_BLOCK_IMAXRECS( \
- INT_GET((bb)->bb_level, ARCH_CONVERT), cur))
-#endif
-
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_BMAP_PTR_DADDR)
-xfs_bmbt_ptr_t *
-xfs_bmap_ptr_daddr(xfs_bmbt_block_t *bb, int i, struct xfs_btree_cur *cur);
-#define XFS_BMAP_PTR_DADDR(bb,i,cur) xfs_bmap_ptr_daddr(bb,i,cur)
-#else
-#define XFS_BMAP_PTR_DADDR(bb,i,cur) \
- XFS_BTREE_PTR_ADDR(XFS_BMAP_BLOCK_DSIZE( \
- INT_GET((bb)->bb_level, ARCH_CONVERT), cur), \
- xfs_bmbt, bb, i, XFS_BMAP_BLOCK_DMAXRECS( \
- INT_GET((bb)->bb_level, ARCH_CONVERT), cur))
-#endif
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_BMAP_PTR_IADDR)
-xfs_bmbt_ptr_t *
-xfs_bmap_ptr_iaddr(xfs_bmbt_block_t *bb, int i, struct xfs_btree_cur *cur);
-#define XFS_BMAP_PTR_IADDR(bb,i,cur) xfs_bmap_ptr_iaddr(bb,i,cur)
-#else
-#define XFS_BMAP_PTR_IADDR(bb,i,cur) \
- XFS_BTREE_PTR_ADDR(XFS_BMAP_BLOCK_ISIZE( \
- INT_GET((bb)->bb_level, ARCH_CONVERT), cur), \
- xfs_bmbt, bb, i, XFS_BMAP_BLOCK_IMAXRECS( \
- INT_GET((bb)->bb_level, ARCH_CONVERT), cur))
-#endif
+ (((lev) == (cur)->bc_nlevels - 1 ? \
+ XFS_BTREE_BLOCK_MINRECS(XFS_BMAP_RBLOCK_ISIZE(lev,cur),\
+ xfs_bmbt, (lev) == 0) : \
+ ((cur)->bc_mp->m_bmap_dmnr[(lev) != 0])))
+
+#define XFS_BMAP_REC_DADDR(bb,i,cur) \
+ (XFS_BTREE_REC_ADDR(XFS_BMAP_BLOCK_DSIZE( \
+ be16_to_cpu((bb)->bb_level), cur), \
+ xfs_bmbt, bb, i, XFS_BMAP_BLOCK_DMAXRECS( \
+ be16_to_cpu((bb)->bb_level), cur)))
+#define XFS_BMAP_REC_IADDR(bb,i,cur) \
+ (XFS_BTREE_REC_ADDR(XFS_BMAP_BLOCK_ISIZE( \
+ be16_to_cpu((bb)->bb_level), cur), \
+ xfs_bmbt, bb, i, XFS_BMAP_BLOCK_IMAXRECS( \
+ be16_to_cpu((bb)->bb_level), cur)))
+
+#define XFS_BMAP_KEY_DADDR(bb,i,cur) \
+ (XFS_BTREE_KEY_ADDR(XFS_BMAP_BLOCK_DSIZE( \
+ be16_to_cpu((bb)->bb_level), cur), \
+ xfs_bmbt, bb, i, XFS_BMAP_BLOCK_DMAXRECS( \
+ be16_to_cpu((bb)->bb_level), cur)))
+#define XFS_BMAP_KEY_IADDR(bb,i,cur) \
+ (XFS_BTREE_KEY_ADDR(XFS_BMAP_BLOCK_ISIZE( \
+ be16_to_cpu((bb)->bb_level), cur), \
+ xfs_bmbt, bb, i, XFS_BMAP_BLOCK_IMAXRECS( \
+ be16_to_cpu((bb)->bb_level), cur)))
+
+#define XFS_BMAP_PTR_DADDR(bb,i,cur) \
+ (XFS_BTREE_PTR_ADDR(XFS_BMAP_BLOCK_DSIZE( \
+ be16_to_cpu((bb)->bb_level), cur), \
+ xfs_bmbt, bb, i, XFS_BMAP_BLOCK_DMAXRECS( \
+ be16_to_cpu((bb)->bb_level), cur)))
+#define XFS_BMAP_PTR_IADDR(bb,i,cur) \
+ (XFS_BTREE_PTR_ADDR(XFS_BMAP_BLOCK_ISIZE( \
+ be16_to_cpu((bb)->bb_level), cur), \
+ xfs_bmbt, bb, i, XFS_BMAP_BLOCK_IMAXRECS( \
+ be16_to_cpu((bb)->bb_level), cur)))
/*
* These are to be used when we know the size of the block and
* we don't have a cursor.
*/
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_BMAP_BROOT_REC_ADDR)
-xfs_bmbt_rec_t *xfs_bmap_broot_rec_addr(xfs_bmbt_block_t *bb, int i, int sz);
-#define XFS_BMAP_BROOT_REC_ADDR(bb,i,sz) xfs_bmap_broot_rec_addr(bb,i,sz)
-#else
#define XFS_BMAP_BROOT_REC_ADDR(bb,i,sz) \
- XFS_BTREE_REC_ADDR(sz,xfs_bmbt,bb,i,XFS_BMAP_BROOT_MAXRECS(sz))
-#endif
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_BMAP_BROOT_KEY_ADDR)
-xfs_bmbt_key_t *xfs_bmap_broot_key_addr(xfs_bmbt_block_t *bb, int i, int sz);
-#define XFS_BMAP_BROOT_KEY_ADDR(bb,i,sz) xfs_bmap_broot_key_addr(bb,i,sz)
-#else
+ (XFS_BTREE_REC_ADDR(sz,xfs_bmbt,bb,i,XFS_BMAP_BROOT_MAXRECS(sz)))
#define XFS_BMAP_BROOT_KEY_ADDR(bb,i,sz) \
- XFS_BTREE_KEY_ADDR(sz,xfs_bmbt,bb,i,XFS_BMAP_BROOT_MAXRECS(sz))
-#endif
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_BMAP_BROOT_PTR_ADDR)
-xfs_bmbt_ptr_t *xfs_bmap_broot_ptr_addr(xfs_bmbt_block_t *bb, int i, int sz);
-#define XFS_BMAP_BROOT_PTR_ADDR(bb,i,sz) xfs_bmap_broot_ptr_addr(bb,i,sz)
-#else
+ (XFS_BTREE_KEY_ADDR(sz,xfs_bmbt,bb,i,XFS_BMAP_BROOT_MAXRECS(sz)))
#define XFS_BMAP_BROOT_PTR_ADDR(bb,i,sz) \
- XFS_BTREE_PTR_ADDR(sz,xfs_bmbt,bb,i,XFS_BMAP_BROOT_MAXRECS(sz))
-#endif
+ (XFS_BTREE_PTR_ADDR(sz,xfs_bmbt,bb,i,XFS_BMAP_BROOT_MAXRECS(sz)))
+
+#define XFS_BMAP_BROOT_NUMRECS(bb) be16_to_cpu((bb)->bb_numrecs)
+#define XFS_BMAP_BROOT_MAXRECS(sz) XFS_BTREE_BLOCK_MAXRECS(sz,xfs_bmbt,0)
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_BMAP_BROOT_NUMRECS)
-int xfs_bmap_broot_numrecs(xfs_bmdr_block_t *bb);
-#define XFS_BMAP_BROOT_NUMRECS(bb) xfs_bmap_broot_numrecs(bb)
-#else
-#define XFS_BMAP_BROOT_NUMRECS(bb) (INT_GET((bb)->bb_numrecs, ARCH_CONVERT))
-#endif
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_BMAP_BROOT_MAXRECS)
-int xfs_bmap_broot_maxrecs(int sz);
-#define XFS_BMAP_BROOT_MAXRECS(sz) xfs_bmap_broot_maxrecs(sz)
-#else
-#define XFS_BMAP_BROOT_MAXRECS(sz) XFS_BTREE_BLOCK_MAXRECS(sz,xfs_bmbt,0)
-#endif
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_BMAP_BROOT_SPACE_CALC)
-int xfs_bmap_broot_space_calc(int nrecs);
-#define XFS_BMAP_BROOT_SPACE_CALC(nrecs) xfs_bmap_broot_space_calc(nrecs)
-#else
#define XFS_BMAP_BROOT_SPACE_CALC(nrecs) \
- ((int)(sizeof(xfs_bmbt_block_t) + \
- ((nrecs) * (sizeof(xfs_bmbt_key_t) + sizeof(xfs_bmbt_ptr_t)))))
-#endif
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_BMAP_BROOT_SPACE)
-int xfs_bmap_broot_space(xfs_bmdr_block_t *bb);
-#define XFS_BMAP_BROOT_SPACE(bb) xfs_bmap_broot_space(bb)
-#else
+ (int)(sizeof(xfs_bmbt_block_t) + \
+ ((nrecs) * (sizeof(xfs_bmbt_key_t) + sizeof(xfs_bmbt_ptr_t))))
+
#define XFS_BMAP_BROOT_SPACE(bb) \
- XFS_BMAP_BROOT_SPACE_CALC(INT_GET((bb)->bb_numrecs, ARCH_CONVERT))
-#endif
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_BMDR_SPACE_CALC)
-int xfs_bmdr_space_calc(int nrecs);
-#define XFS_BMDR_SPACE_CALC(nrecs) xfs_bmdr_space_calc(nrecs)
-#else
-#define XFS_BMDR_SPACE_CALC(nrecs) \
- ((int)(sizeof(xfs_bmdr_block_t) + \
- ((nrecs) * (sizeof(xfs_bmbt_key_t) + sizeof(xfs_bmbt_ptr_t)))))
-#endif
+ (XFS_BMAP_BROOT_SPACE_CALC(be16_to_cpu((bb)->bb_numrecs)))
+#define XFS_BMDR_SPACE_CALC(nrecs) \
+ (int)(sizeof(xfs_bmdr_block_t) + \
+ ((nrecs) * (sizeof(xfs_bmbt_key_t) + sizeof(xfs_bmbt_ptr_t))))
/*
* Maximum number of bmap btree levels.
*/
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_BM_MAXLEVELS)
-int xfs_bm_maxlevels(struct xfs_mount *mp, int w);
-#define XFS_BM_MAXLEVELS(mp,w) xfs_bm_maxlevels(mp,w)
-#else
-#define XFS_BM_MAXLEVELS(mp,w) ((mp)->m_bm_maxlevels[w])
-#endif
+#define XFS_BM_MAXLEVELS(mp,w) ((mp)->m_bm_maxlevels[(w)])
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_BMAP_SANITY_CHECK)
-int xfs_bmap_sanity_check(struct xfs_mount *mp, xfs_bmbt_block_t *bb,
- int level);
-#define XFS_BMAP_SANITY_CHECK(mp,bb,level) \
- xfs_bmap_sanity_check(mp,bb,level)
-#else
-#define XFS_BMAP_SANITY_CHECK(mp,bb,level) \
- (INT_GET((bb)->bb_magic, ARCH_CONVERT) == XFS_BMAP_MAGIC && \
- INT_GET((bb)->bb_level, ARCH_CONVERT) == level && \
- INT_GET((bb)->bb_numrecs, ARCH_CONVERT) > 0 && \
- INT_GET((bb)->bb_numrecs, ARCH_CONVERT) <= (mp)->m_bmap_dmxr[(level) != 0])
-#endif
+#define XFS_BMAP_SANITY_CHECK(mp,bb,level) \
+ (be32_to_cpu((bb)->bb_magic) == XFS_BMAP_MAGIC && \
+ be16_to_cpu((bb)->bb_level) == level && \
+ be16_to_cpu((bb)->bb_numrecs) > 0 && \
+ be16_to_cpu((bb)->bb_numrecs) <= (mp)->m_bmap_dmxr[(level) != 0])
#ifdef __KERNEL__
@@ -459,234 +301,84 @@ extern ktrace_t *xfs_bmbt_trace_buf;
/*
* Prototypes for xfs_bmap.c to call.
*/
-
-void
-xfs_bmdr_to_bmbt(
- xfs_bmdr_block_t *,
- int,
- xfs_bmbt_block_t *,
- int);
-
-int
-xfs_bmbt_decrement(
- struct xfs_btree_cur *,
- int,
- int *);
-
-int
-xfs_bmbt_delete(
- struct xfs_btree_cur *,
- int *);
-
-void
-xfs_bmbt_get_all(
- xfs_bmbt_rec_t *r,
- xfs_bmbt_irec_t *s);
-
-xfs_bmbt_block_t *
-xfs_bmbt_get_block(
- struct xfs_btree_cur *cur,
- int level,
- struct xfs_buf **bpp);
-
-xfs_filblks_t
-xfs_bmbt_get_blockcount(
- xfs_bmbt_rec_t *r);
-
-xfs_fsblock_t
-xfs_bmbt_get_startblock(
- xfs_bmbt_rec_t *r);
-
-xfs_fileoff_t
-xfs_bmbt_get_startoff(
- xfs_bmbt_rec_t *r);
-
-xfs_exntst_t
-xfs_bmbt_get_state(
- xfs_bmbt_rec_t *r);
+extern void xfs_bmdr_to_bmbt(xfs_bmdr_block_t *, int, xfs_bmbt_block_t *, int);
+extern int xfs_bmbt_decrement(struct xfs_btree_cur *, int, int *);
+extern int xfs_bmbt_delete(struct xfs_btree_cur *, int *);
+extern void xfs_bmbt_get_all(xfs_bmbt_rec_t *r, xfs_bmbt_irec_t *s);
+extern xfs_bmbt_block_t *xfs_bmbt_get_block(struct xfs_btree_cur *cur,
+ int, struct xfs_buf **bpp);
+extern xfs_filblks_t xfs_bmbt_get_blockcount(xfs_bmbt_rec_t *r);
+extern xfs_fsblock_t xfs_bmbt_get_startblock(xfs_bmbt_rec_t *r);
+extern xfs_fileoff_t xfs_bmbt_get_startoff(xfs_bmbt_rec_t *r);
+extern xfs_exntst_t xfs_bmbt_get_state(xfs_bmbt_rec_t *r);
#ifndef XFS_NATIVE_HOST
-void
-xfs_bmbt_disk_get_all(
- xfs_bmbt_rec_t *r,
- xfs_bmbt_irec_t *s);
-
-xfs_exntst_t
-xfs_bmbt_disk_get_state(
- xfs_bmbt_rec_t *r);
-
-xfs_filblks_t
-xfs_bmbt_disk_get_blockcount(
- xfs_bmbt_rec_t *r);
-
-xfs_fsblock_t
-xfs_bmbt_disk_get_startblock(
- xfs_bmbt_rec_t *r);
-
-xfs_fileoff_t
-xfs_bmbt_disk_get_startoff(
- xfs_bmbt_rec_t *r);
-
-#else
-#define xfs_bmbt_disk_get_all(r, s) \
- xfs_bmbt_get_all(r, s)
-#define xfs_bmbt_disk_get_state(r) \
- xfs_bmbt_get_state(r)
-#define xfs_bmbt_disk_get_blockcount(r) \
- xfs_bmbt_get_blockcount(r)
-#define xfs_bmbt_disk_get_startblock(r) \
- xfs_bmbt_get_blockcount(r)
-#define xfs_bmbt_disk_get_startoff(r) \
- xfs_bmbt_get_startoff(r)
+extern void xfs_bmbt_disk_get_all(xfs_bmbt_rec_t *r, xfs_bmbt_irec_t *s);
+extern xfs_exntst_t xfs_bmbt_disk_get_state(xfs_bmbt_rec_t *r);
+extern xfs_filblks_t xfs_bmbt_disk_get_blockcount(xfs_bmbt_rec_t *r);
+extern xfs_fsblock_t xfs_bmbt_disk_get_startblock(xfs_bmbt_rec_t *r);
+extern xfs_fileoff_t xfs_bmbt_disk_get_startoff(xfs_bmbt_rec_t *r);
+#else
+#define xfs_bmbt_disk_get_all(r, s) xfs_bmbt_get_all(r, s)
+#define xfs_bmbt_disk_get_state(r) xfs_bmbt_get_state(r)
+#define xfs_bmbt_disk_get_blockcount(r) xfs_bmbt_get_blockcount(r)
+#define xfs_bmbt_disk_get_startblock(r) xfs_bmbt_get_blockcount(r)
+#define xfs_bmbt_disk_get_startoff(r) xfs_bmbt_get_startoff(r)
#endif /* XFS_NATIVE_HOST */
-int
-xfs_bmbt_increment(
- struct xfs_btree_cur *,
- int,
- int *);
-
-int
-xfs_bmbt_insert(
- struct xfs_btree_cur *,
- int *);
-
-void
-xfs_bmbt_log_block(
- struct xfs_btree_cur *,
- struct xfs_buf *,
- int);
-
-void
-xfs_bmbt_log_recs(
- struct xfs_btree_cur *,
- struct xfs_buf *,
- int,
- int);
-
-int
-xfs_bmbt_lookup_eq(
- struct xfs_btree_cur *,
- xfs_fileoff_t,
- xfs_fsblock_t,
- xfs_filblks_t,
- int *);
-
-int
-xfs_bmbt_lookup_ge(
- struct xfs_btree_cur *,
- xfs_fileoff_t,
- xfs_fsblock_t,
- xfs_filblks_t,
- int *);
+extern int xfs_bmbt_increment(struct xfs_btree_cur *, int, int *);
+extern int xfs_bmbt_insert(struct xfs_btree_cur *, int *);
+extern void xfs_bmbt_log_block(struct xfs_btree_cur *, struct xfs_buf *, int);
+extern void xfs_bmbt_log_recs(struct xfs_btree_cur *, struct xfs_buf *, int,
+ int);
+extern int xfs_bmbt_lookup_eq(struct xfs_btree_cur *, xfs_fileoff_t,
+ xfs_fsblock_t, xfs_filblks_t, int *);
+extern int xfs_bmbt_lookup_ge(struct xfs_btree_cur *, xfs_fileoff_t,
+ xfs_fsblock_t, xfs_filblks_t, int *);
/*
* Give the bmap btree a new root block. Copy the old broot contents
* down into a real block and make the broot point to it.
*/
-int /* error */
-xfs_bmbt_newroot(
- struct xfs_btree_cur *cur, /* btree cursor */
- int *logflags, /* logging flags for inode */
- int *stat); /* return status - 0 fail */
-
-void
-xfs_bmbt_set_all(
- xfs_bmbt_rec_t *r,
- xfs_bmbt_irec_t *s);
-
-void
-xfs_bmbt_set_allf(
- xfs_bmbt_rec_t *r,
- xfs_fileoff_t o,
- xfs_fsblock_t b,
- xfs_filblks_t c,
- xfs_exntst_t v);
-
-void
-xfs_bmbt_set_blockcount(
- xfs_bmbt_rec_t *r,
- xfs_filblks_t v);
-
-void
-xfs_bmbt_set_startblock(
- xfs_bmbt_rec_t *r,
- xfs_fsblock_t v);
-
-void
-xfs_bmbt_set_startoff(
- xfs_bmbt_rec_t *r,
- xfs_fileoff_t v);
-
-void
-xfs_bmbt_set_state(
- xfs_bmbt_rec_t *r,
- xfs_exntst_t v);
+extern int xfs_bmbt_newroot(struct xfs_btree_cur *cur, int *lflags, int *stat);
+
+extern void xfs_bmbt_set_all(xfs_bmbt_rec_t *r, xfs_bmbt_irec_t *s);
+extern void xfs_bmbt_set_allf(xfs_bmbt_rec_t *r, xfs_fileoff_t o,
+ xfs_fsblock_t b, xfs_filblks_t c, xfs_exntst_t v);
+extern void xfs_bmbt_set_blockcount(xfs_bmbt_rec_t *r, xfs_filblks_t v);
+extern void xfs_bmbt_set_startblock(xfs_bmbt_rec_t *r, xfs_fsblock_t v);
+extern void xfs_bmbt_set_startoff(xfs_bmbt_rec_t *r, xfs_fileoff_t v);
+extern void xfs_bmbt_set_state(xfs_bmbt_rec_t *r, xfs_exntst_t v);
#ifndef XFS_NATIVE_HOST
-void
-xfs_bmbt_disk_set_all(
- xfs_bmbt_rec_t *r,
- xfs_bmbt_irec_t *s);
-
-void
-xfs_bmbt_disk_set_allf(
- xfs_bmbt_rec_t *r,
- xfs_fileoff_t o,
- xfs_fsblock_t b,
- xfs_filblks_t c,
- xfs_exntst_t v);
+extern void xfs_bmbt_disk_set_all(xfs_bmbt_rec_t *r, xfs_bmbt_irec_t *s);
+extern void xfs_bmbt_disk_set_allf(xfs_bmbt_rec_t *r, xfs_fileoff_t o,
+ xfs_fsblock_t b, xfs_filblks_t c, xfs_exntst_t v);
#else
-#define xfs_bmbt_disk_set_all(r, s) \
- xfs_bmbt_set_all(r, s)
-#define xfs_bmbt_disk_set_allf(r, o, b, c, v) \
- xfs_bmbt_set_allf(r, o, b, c, v)
+#define xfs_bmbt_disk_set_all(r, s) xfs_bmbt_set_all(r, s)
+#define xfs_bmbt_disk_set_allf(r, o, b, c, v) xfs_bmbt_set_allf(r, o, b, c, v)
#endif /* XFS_NATIVE_HOST */
-void
-xfs_bmbt_to_bmdr(
- xfs_bmbt_block_t *,
- int,
- xfs_bmdr_block_t *,
- int);
-
-int
-xfs_bmbt_update(
- struct xfs_btree_cur *,
- xfs_fileoff_t,
- xfs_fsblock_t,
- xfs_filblks_t,
- xfs_exntst_t);
+extern void xfs_bmbt_to_bmdr(xfs_bmbt_block_t *, int, xfs_bmdr_block_t *, int);
+extern int xfs_bmbt_update(struct xfs_btree_cur *, xfs_fileoff_t,
+ xfs_fsblock_t, xfs_filblks_t, xfs_exntst_t);
#ifdef DEBUG
/*
* Get the data from the pointed-to record.
*/
-int
-xfs_bmbt_get_rec(
- struct xfs_btree_cur *,
- xfs_fileoff_t *,
- xfs_fsblock_t *,
- xfs_filblks_t *,
- xfs_exntst_t *,
- int *);
+extern int xfs_bmbt_get_rec(struct xfs_btree_cur *, xfs_fileoff_t *,
+ xfs_fsblock_t *, xfs_filblks_t *,
+ xfs_exntst_t *, int *);
#endif
-
/*
* Search an extent list for the extent which includes block
* bno.
*/
-xfs_bmbt_rec_t *
-xfs_bmap_do_search_extents(
- xfs_bmbt_rec_t *,
- xfs_extnum_t,
- xfs_extnum_t,
- xfs_fileoff_t,
- int *,
- xfs_extnum_t *,
- xfs_bmbt_irec_t *,
- xfs_bmbt_irec_t *);
+xfs_bmbt_rec_t *xfs_bmap_do_search_extents(xfs_bmbt_rec_t *,
+ xfs_extnum_t, xfs_extnum_t, xfs_fileoff_t, int *,
+ xfs_extnum_t *, xfs_bmbt_irec_t *, xfs_bmbt_irec_t *);
#endif /* __KERNEL__ */
diff --git a/fs/xfs/xfs_btree.c b/fs/xfs/xfs_btree.c
index 0cc63d657a14..52d5d095fc35 100644
--- a/fs/xfs/xfs_btree.c
+++ b/fs/xfs/xfs_btree.c
@@ -1,45 +1,26 @@
/*
- * Copyright (c) 2000-2002 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-
-/*
- * This file contains common code for the space manager's btree implementations.
- */
-
#include "xfs.h"
-
-#include "xfs_macros.h"
+#include "xfs_fs.h"
#include "xfs_types.h"
-#include "xfs_inum.h"
+#include "xfs_bit.h"
#include "xfs_log.h"
+#include "xfs_inum.h"
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
@@ -47,17 +28,16 @@
#include "xfs_dir2.h"
#include "xfs_dmapi.h"
#include "xfs_mount.h"
-#include "xfs_alloc_btree.h"
#include "xfs_bmap_btree.h"
+#include "xfs_alloc_btree.h"
#include "xfs_ialloc_btree.h"
-#include "xfs_btree.h"
-#include "xfs_ialloc.h"
-#include "xfs_attr_sf.h"
#include "xfs_dir_sf.h"
#include "xfs_dir2_sf.h"
+#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
#include "xfs_inode.h"
-#include "xfs_bit.h"
+#include "xfs_btree.h"
+#include "xfs_ialloc.h"
#include "xfs_error.h"
/*
@@ -110,11 +90,14 @@ xfs_btree_maxrecs(
switch (cur->bc_btnum) {
case XFS_BTNUM_BNO:
case XFS_BTNUM_CNT:
- return (int)XFS_ALLOC_BLOCK_MAXRECS(INT_GET(block->bb_h.bb_level, ARCH_CONVERT), cur);
+ return (int)XFS_ALLOC_BLOCK_MAXRECS(
+ be16_to_cpu(block->bb_h.bb_level), cur);
case XFS_BTNUM_BMAP:
- return (int)XFS_BMAP_BLOCK_IMAXRECS(INT_GET(block->bb_h.bb_level, ARCH_CONVERT), cur);
+ return (int)XFS_BMAP_BLOCK_IMAXRECS(
+ be16_to_cpu(block->bb_h.bb_level), cur);
case XFS_BTNUM_INO:
- return (int)XFS_INOBT_BLOCK_MAXRECS(INT_GET(block->bb_h.bb_level, ARCH_CONVERT), cur);
+ return (int)XFS_INOBT_BLOCK_MAXRECS(
+ be16_to_cpu(block->bb_h.bb_level), cur);
default:
ASSERT(0);
return 0;
@@ -160,7 +143,7 @@ xfs_btree_check_key(
k1 = ak1;
k2 = ak2;
- ASSERT(INT_GET(k1->ar_startblock, ARCH_CONVERT) < INT_GET(k2->ar_startblock, ARCH_CONVERT));
+ ASSERT(be32_to_cpu(k1->ar_startblock) < be32_to_cpu(k2->ar_startblock));
break;
}
case XFS_BTNUM_CNT: {
@@ -169,9 +152,9 @@ xfs_btree_check_key(
k1 = ak1;
k2 = ak2;
- ASSERT(INT_GET(k1->ar_blockcount, ARCH_CONVERT) < INT_GET(k2->ar_blockcount, ARCH_CONVERT) ||
- (INT_GET(k1->ar_blockcount, ARCH_CONVERT) == INT_GET(k2->ar_blockcount, ARCH_CONVERT) &&
- INT_GET(k1->ar_startblock, ARCH_CONVERT) < INT_GET(k2->ar_startblock, ARCH_CONVERT)));
+ ASSERT(be32_to_cpu(k1->ar_blockcount) < be32_to_cpu(k2->ar_blockcount) ||
+ (k1->ar_blockcount == k2->ar_blockcount &&
+ be32_to_cpu(k1->ar_startblock) < be32_to_cpu(k2->ar_startblock)));
break;
}
case XFS_BTNUM_BMAP: {
@@ -214,16 +197,16 @@ xfs_btree_check_lblock(
mp = cur->bc_mp;
lblock_ok =
- INT_GET(block->bb_magic, ARCH_CONVERT) == xfs_magics[cur->bc_btnum] &&
- INT_GET(block->bb_level, ARCH_CONVERT) == level &&
- INT_GET(block->bb_numrecs, ARCH_CONVERT) <=
+ be32_to_cpu(block->bb_magic) == xfs_magics[cur->bc_btnum] &&
+ be16_to_cpu(block->bb_level) == level &&
+ be16_to_cpu(block->bb_numrecs) <=
xfs_btree_maxrecs(cur, (xfs_btree_block_t *)block) &&
block->bb_leftsib &&
- (INT_GET(block->bb_leftsib, ARCH_CONVERT) == NULLDFSBNO ||
- XFS_FSB_SANITY_CHECK(mp, INT_GET(block->bb_leftsib, ARCH_CONVERT))) &&
+ (be64_to_cpu(block->bb_leftsib) == NULLDFSBNO ||
+ XFS_FSB_SANITY_CHECK(mp, be64_to_cpu(block->bb_leftsib))) &&
block->bb_rightsib &&
- (INT_GET(block->bb_rightsib, ARCH_CONVERT) == NULLDFSBNO ||
- XFS_FSB_SANITY_CHECK(mp, INT_GET(block->bb_rightsib, ARCH_CONVERT)));
+ (be64_to_cpu(block->bb_rightsib) == NULLDFSBNO ||
+ XFS_FSB_SANITY_CHECK(mp, be64_to_cpu(block->bb_rightsib)));
if (unlikely(XFS_TEST_ERROR(!lblock_ok, mp, XFS_ERRTAG_BTREE_CHECK_LBLOCK,
XFS_RANDOM_BTREE_CHECK_LBLOCK))) {
if (bp)
@@ -271,8 +254,9 @@ xfs_btree_check_rec(
r1 = ar1;
r2 = ar2;
- ASSERT(INT_GET(r1->ar_startblock, ARCH_CONVERT) + INT_GET(r1->ar_blockcount, ARCH_CONVERT) <=
- INT_GET(r2->ar_startblock, ARCH_CONVERT));
+ ASSERT(be32_to_cpu(r1->ar_startblock) +
+ be32_to_cpu(r1->ar_blockcount) <=
+ be32_to_cpu(r2->ar_startblock));
break;
}
case XFS_BTNUM_CNT: {
@@ -281,9 +265,9 @@ xfs_btree_check_rec(
r1 = ar1;
r2 = ar2;
- ASSERT(INT_GET(r1->ar_blockcount, ARCH_CONVERT) < INT_GET(r2->ar_blockcount, ARCH_CONVERT) ||
- (INT_GET(r1->ar_blockcount, ARCH_CONVERT) == INT_GET(r2->ar_blockcount, ARCH_CONVERT) &&
- INT_GET(r1->ar_startblock, ARCH_CONVERT) < INT_GET(r2->ar_startblock, ARCH_CONVERT)));
+ ASSERT(be32_to_cpu(r1->ar_blockcount) < be32_to_cpu(r2->ar_blockcount) ||
+ (r1->ar_blockcount == r2->ar_blockcount &&
+ be32_to_cpu(r1->ar_startblock) < be32_to_cpu(r2->ar_startblock)));
break;
}
case XFS_BTNUM_BMAP: {
@@ -331,17 +315,17 @@ xfs_btree_check_sblock(
agbp = cur->bc_private.a.agbp;
agf = XFS_BUF_TO_AGF(agbp);
- agflen = INT_GET(agf->agf_length, ARCH_CONVERT);
+ agflen = be32_to_cpu(agf->agf_length);
sblock_ok =
- INT_GET(block->bb_magic, ARCH_CONVERT) == xfs_magics[cur->bc_btnum] &&
- INT_GET(block->bb_level, ARCH_CONVERT) == level &&
- INT_GET(block->bb_numrecs, ARCH_CONVERT) <=
+ be32_to_cpu(block->bb_magic) == xfs_magics[cur->bc_btnum] &&
+ be16_to_cpu(block->bb_level) == level &&
+ be16_to_cpu(block->bb_numrecs) <=
xfs_btree_maxrecs(cur, (xfs_btree_block_t *)block) &&
- (INT_GET(block->bb_leftsib, ARCH_CONVERT) == NULLAGBLOCK ||
- INT_GET(block->bb_leftsib, ARCH_CONVERT) < agflen) &&
+ (be32_to_cpu(block->bb_leftsib) == NULLAGBLOCK ||
+ be32_to_cpu(block->bb_leftsib) < agflen) &&
block->bb_leftsib &&
- (INT_GET(block->bb_rightsib, ARCH_CONVERT) == NULLAGBLOCK ||
- INT_GET(block->bb_rightsib, ARCH_CONVERT) < agflen) &&
+ (be32_to_cpu(block->bb_rightsib) == NULLAGBLOCK ||
+ be32_to_cpu(block->bb_rightsib) < agflen) &&
block->bb_rightsib;
if (unlikely(XFS_TEST_ERROR(!sblock_ok, cur->bc_mp,
XFS_ERRTAG_BTREE_CHECK_SBLOCK,
@@ -372,7 +356,7 @@ xfs_btree_check_sptr(
XFS_WANT_CORRUPTED_RETURN(
level > 0 &&
ptr != NULLAGBLOCK && ptr != 0 &&
- ptr < INT_GET(agf->agf_length, ARCH_CONVERT));
+ ptr < be32_to_cpu(agf->agf_length));
return 0;
}
@@ -611,15 +595,15 @@ xfs_btree_init_cursor(
case XFS_BTNUM_BNO:
case XFS_BTNUM_CNT:
agf = XFS_BUF_TO_AGF(agbp);
- nlevels = INT_GET(agf->agf_levels[btnum], ARCH_CONVERT);
+ nlevels = be32_to_cpu(agf->agf_levels[btnum]);
break;
case XFS_BTNUM_BMAP:
ifp = XFS_IFORK_PTR(ip, whichfork);
- nlevels = INT_GET(ifp->if_broot->bb_level, ARCH_CONVERT) + 1;
+ nlevels = be16_to_cpu(ifp->if_broot->bb_level) + 1;
break;
case XFS_BTNUM_INO:
agi = XFS_BUF_TO_AGI(agbp);
- nlevels = INT_GET(agi->agi_level, ARCH_CONVERT);
+ nlevels = be32_to_cpu(agi->agi_level);
break;
default:
ASSERT(0);
@@ -683,9 +667,9 @@ xfs_btree_islastblock(
block = xfs_btree_get_block(cur, level, &bp);
xfs_btree_check_block(cur, block, level, bp);
if (XFS_BTREE_LONG_PTRS(cur->bc_btnum))
- return INT_GET(block->bb_u.l.bb_rightsib, ARCH_CONVERT) == NULLDFSBNO;
+ return be64_to_cpu(block->bb_u.l.bb_rightsib) == NULLDFSBNO;
else
- return INT_GET(block->bb_u.s.bb_rightsib, ARCH_CONVERT) == NULLAGBLOCK;
+ return be32_to_cpu(block->bb_u.s.bb_rightsib) == NULLAGBLOCK;
}
/*
@@ -713,7 +697,7 @@ xfs_btree_lastrec(
/*
* Set the ptr value to numrecs, that's the last record/key.
*/
- cur->bc_ptrs[level] = INT_GET(block->bb_h.bb_numrecs, ARCH_CONVERT);
+ cur->bc_ptrs[level] = be16_to_cpu(block->bb_h.bb_numrecs);
return 1;
}
@@ -883,38 +867,38 @@ xfs_btree_readahead_core(
case XFS_BTNUM_BNO:
case XFS_BTNUM_CNT:
a = XFS_BUF_TO_ALLOC_BLOCK(cur->bc_bufs[lev]);
- if ((lr & XFS_BTCUR_LEFTRA) && INT_GET(a->bb_leftsib, ARCH_CONVERT) != NULLAGBLOCK) {
+ if ((lr & XFS_BTCUR_LEFTRA) && be32_to_cpu(a->bb_leftsib) != NULLAGBLOCK) {
xfs_btree_reada_bufs(cur->bc_mp, cur->bc_private.a.agno,
- INT_GET(a->bb_leftsib, ARCH_CONVERT), 1);
+ be32_to_cpu(a->bb_leftsib), 1);
rval++;
}
- if ((lr & XFS_BTCUR_RIGHTRA) && INT_GET(a->bb_rightsib, ARCH_CONVERT) != NULLAGBLOCK) {
+ if ((lr & XFS_BTCUR_RIGHTRA) && be32_to_cpu(a->bb_rightsib) != NULLAGBLOCK) {
xfs_btree_reada_bufs(cur->bc_mp, cur->bc_private.a.agno,
- INT_GET(a->bb_rightsib, ARCH_CONVERT), 1);
+ be32_to_cpu(a->bb_rightsib), 1);
rval++;
}
break;
case XFS_BTNUM_BMAP:
b = XFS_BUF_TO_BMBT_BLOCK(cur->bc_bufs[lev]);
- if ((lr & XFS_BTCUR_LEFTRA) && INT_GET(b->bb_leftsib, ARCH_CONVERT) != NULLDFSBNO) {
- xfs_btree_reada_bufl(cur->bc_mp, INT_GET(b->bb_leftsib, ARCH_CONVERT), 1);
+ if ((lr & XFS_BTCUR_LEFTRA) && be64_to_cpu(b->bb_leftsib) != NULLDFSBNO) {
+ xfs_btree_reada_bufl(cur->bc_mp, be64_to_cpu(b->bb_leftsib), 1);
rval++;
}
- if ((lr & XFS_BTCUR_RIGHTRA) && INT_GET(b->bb_rightsib, ARCH_CONVERT) != NULLDFSBNO) {
- xfs_btree_reada_bufl(cur->bc_mp, INT_GET(b->bb_rightsib, ARCH_CONVERT), 1);
+ if ((lr & XFS_BTCUR_RIGHTRA) && be64_to_cpu(b->bb_rightsib) != NULLDFSBNO) {
+ xfs_btree_reada_bufl(cur->bc_mp, be64_to_cpu(b->bb_rightsib), 1);
rval++;
}
break;
case XFS_BTNUM_INO:
i = XFS_BUF_TO_INOBT_BLOCK(cur->bc_bufs[lev]);
- if ((lr & XFS_BTCUR_LEFTRA) && INT_GET(i->bb_leftsib, ARCH_CONVERT) != NULLAGBLOCK) {
+ if ((lr & XFS_BTCUR_LEFTRA) && be32_to_cpu(i->bb_leftsib) != NULLAGBLOCK) {
xfs_btree_reada_bufs(cur->bc_mp, cur->bc_private.i.agno,
- INT_GET(i->bb_leftsib, ARCH_CONVERT), 1);
+ be32_to_cpu(i->bb_leftsib), 1);
rval++;
}
- if ((lr & XFS_BTCUR_RIGHTRA) && INT_GET(i->bb_rightsib, ARCH_CONVERT) != NULLAGBLOCK) {
+ if ((lr & XFS_BTCUR_RIGHTRA) && be32_to_cpu(i->bb_rightsib) != NULLAGBLOCK) {
xfs_btree_reada_bufs(cur->bc_mp, cur->bc_private.i.agno,
- INT_GET(i->bb_rightsib, ARCH_CONVERT), 1);
+ be32_to_cpu(i->bb_rightsib), 1);
rval++;
}
break;
@@ -946,14 +930,14 @@ xfs_btree_setbuf(
return;
b = XFS_BUF_TO_BLOCK(bp);
if (XFS_BTREE_LONG_PTRS(cur->bc_btnum)) {
- if (INT_GET(b->bb_u.l.bb_leftsib, ARCH_CONVERT) == NULLDFSBNO)
+ if (be64_to_cpu(b->bb_u.l.bb_leftsib) == NULLDFSBNO)
cur->bc_ra[lev] |= XFS_BTCUR_LEFTRA;
- if (INT_GET(b->bb_u.l.bb_rightsib, ARCH_CONVERT) == NULLDFSBNO)
+ if (be64_to_cpu(b->bb_u.l.bb_rightsib) == NULLDFSBNO)
cur->bc_ra[lev] |= XFS_BTCUR_RIGHTRA;
} else {
- if (INT_GET(b->bb_u.s.bb_leftsib, ARCH_CONVERT) == NULLAGBLOCK)
+ if (be32_to_cpu(b->bb_u.s.bb_leftsib) == NULLAGBLOCK)
cur->bc_ra[lev] |= XFS_BTCUR_LEFTRA;
- if (INT_GET(b->bb_u.s.bb_rightsib, ARCH_CONVERT) == NULLAGBLOCK)
+ if (be32_to_cpu(b->bb_u.s.bb_rightsib) == NULLAGBLOCK)
cur->bc_ra[lev] |= XFS_BTCUR_RIGHTRA;
}
}
diff --git a/fs/xfs/xfs_btree.h b/fs/xfs/xfs_btree.h
index 09b4e1532a35..44f1bd98064a 100644
--- a/fs/xfs/xfs_btree.h
+++ b/fs/xfs/xfs_btree.h
@@ -1,33 +1,19 @@
/*
- * Copyright (c) 2000-2001 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __XFS_BTREE_H__
#define __XFS_BTREE_H__
@@ -53,25 +39,23 @@ struct xfs_trans;
/*
* Short form header: space allocation btrees.
*/
-typedef struct xfs_btree_sblock
-{
- __uint32_t bb_magic; /* magic number for block type */
- __uint16_t bb_level; /* 0 is a leaf */
- __uint16_t bb_numrecs; /* current # of data records */
- xfs_agblock_t bb_leftsib; /* left sibling block or NULLAGBLOCK */
- xfs_agblock_t bb_rightsib; /* right sibling block or NULLAGBLOCK */
+typedef struct xfs_btree_sblock {
+ __be32 bb_magic; /* magic number for block type */
+ __be16 bb_level; /* 0 is a leaf */
+ __be16 bb_numrecs; /* current # of data records */
+ __be32 bb_leftsib; /* left sibling block or NULLAGBLOCK */
+ __be32 bb_rightsib; /* right sibling block or NULLAGBLOCK */
} xfs_btree_sblock_t;
/*
* Long form header: bmap btrees.
*/
-typedef struct xfs_btree_lblock
-{
- __uint32_t bb_magic; /* magic number for block type */
- __uint16_t bb_level; /* 0 is a leaf */
- __uint16_t bb_numrecs; /* current # of data records */
- xfs_dfsbno_t bb_leftsib; /* left sibling block or NULLDFSBNO */
- xfs_dfsbno_t bb_rightsib; /* right sibling block or NULLDFSBNO */
+typedef struct xfs_btree_lblock {
+ __be32 bb_magic; /* magic number for block type */
+ __be16 bb_level; /* 0 is a leaf */
+ __be16 bb_numrecs; /* current # of data records */
+ __be64 bb_leftsib; /* left sibling block or NULLDFSBNO */
+ __be64 bb_rightsib; /* right sibling block or NULLDFSBNO */
} xfs_btree_lblock_t;
/*
@@ -79,24 +63,23 @@ typedef struct xfs_btree_lblock
*/
typedef struct xfs_btree_hdr
{
- __uint32_t bb_magic; /* magic number for block type */
- __uint16_t bb_level; /* 0 is a leaf */
- __uint16_t bb_numrecs; /* current # of data records */
+ __be32 bb_magic; /* magic number for block type */
+ __be16 bb_level; /* 0 is a leaf */
+ __be16 bb_numrecs; /* current # of data records */
} xfs_btree_hdr_t;
-typedef struct xfs_btree_block
-{
+typedef struct xfs_btree_block {
xfs_btree_hdr_t bb_h; /* header */
- union {
- struct {
- xfs_agblock_t bb_leftsib;
- xfs_agblock_t bb_rightsib;
- } s; /* short form pointers */
+ union {
+ struct {
+ __be32 bb_leftsib;
+ __be32 bb_rightsib;
+ } s; /* short form pointers */
struct {
- xfs_dfsbno_t bb_leftsib;
- xfs_dfsbno_t bb_rightsib;
- } l; /* long form pointers */
- } bb_u; /* rest */
+ __be64 bb_leftsib;
+ __be64 bb_rightsib;
+ } l; /* long form pointers */
+ } bb_u; /* rest */
} xfs_btree_block_t;
/*
@@ -113,12 +96,7 @@ typedef struct xfs_btree_block
/*
* Boolean to select which form of xfs_btree_block_t.bb_u to use.
*/
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_BTREE_LONG_PTRS)
-int xfs_btree_long_ptrs(xfs_btnum_t btnum);
-#define XFS_BTREE_LONG_PTRS(btnum) ((btnum) == XFS_BTNUM_BMAP)
-#else
#define XFS_BTREE_LONG_PTRS(btnum) ((btnum) == XFS_BTNUM_BMAP)
-#endif
/*
* Magic numbers for btree blocks.
@@ -165,7 +143,7 @@ typedef struct xfs_btree_cur
struct xfs_trans *bc_tp; /* transaction we're in, if any */
struct xfs_mount *bc_mp; /* file system mount struct */
union {
- xfs_alloc_rec_t a;
+ xfs_alloc_rec_incore_t a;
xfs_bmbt_irec_t b;
xfs_inobt_rec_t i;
} bc_rec; /* current insert/search record value */
@@ -205,24 +183,10 @@ typedef struct xfs_btree_cur
/*
* Convert from buffer to btree block header.
*/
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_BUF_TO_BLOCK)
-xfs_btree_block_t *xfs_buf_to_block(struct xfs_buf *bp);
-#define XFS_BUF_TO_BLOCK(bp) xfs_buf_to_block(bp)
-#else
-#define XFS_BUF_TO_BLOCK(bp) ((xfs_btree_block_t *)(XFS_BUF_PTR(bp)))
-#endif
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_BUF_TO_LBLOCK)
-xfs_btree_lblock_t *xfs_buf_to_lblock(struct xfs_buf *bp);
-#define XFS_BUF_TO_LBLOCK(bp) xfs_buf_to_lblock(bp)
-#else
-#define XFS_BUF_TO_LBLOCK(bp) ((xfs_btree_lblock_t *)(XFS_BUF_PTR(bp)))
-#endif
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_BUF_TO_SBLOCK)
-xfs_btree_sblock_t *xfs_buf_to_sblock(struct xfs_buf *bp);
-#define XFS_BUF_TO_SBLOCK(bp) xfs_buf_to_sblock(bp)
-#else
-#define XFS_BUF_TO_SBLOCK(bp) ((xfs_btree_sblock_t *)(XFS_BUF_PTR(bp)))
-#endif
+#define XFS_BUF_TO_BLOCK(bp) ((xfs_btree_block_t *)XFS_BUF_PTR(bp))
+#define XFS_BUF_TO_LBLOCK(bp) ((xfs_btree_lblock_t *)XFS_BUF_PTR(bp))
+#define XFS_BUF_TO_SBLOCK(bp) ((xfs_btree_sblock_t *)XFS_BUF_PTR(bp))
+
#ifdef __KERNEL__
@@ -477,106 +441,33 @@ xfs_btree_setbuf(
/*
* Min and max functions for extlen, agblock, fileoff, and filblks types.
*/
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_EXTLEN_MIN)
-xfs_extlen_t xfs_extlen_min(xfs_extlen_t a, xfs_extlen_t b);
-#define XFS_EXTLEN_MIN(a,b) xfs_extlen_min(a,b)
-#else
#define XFS_EXTLEN_MIN(a,b) \
((xfs_extlen_t)(a) < (xfs_extlen_t)(b) ? \
- (xfs_extlen_t)(a) : (xfs_extlen_t)(b))
-#endif
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_EXTLEN_MAX)
-xfs_extlen_t xfs_extlen_max(xfs_extlen_t a, xfs_extlen_t b);
-#define XFS_EXTLEN_MAX(a,b) xfs_extlen_max(a,b)
-#else
+ (xfs_extlen_t)(a) : (xfs_extlen_t)(b))
#define XFS_EXTLEN_MAX(a,b) \
((xfs_extlen_t)(a) > (xfs_extlen_t)(b) ? \
- (xfs_extlen_t)(a) : (xfs_extlen_t)(b))
-#endif
-
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_AGBLOCK_MIN)
-xfs_agblock_t xfs_agblock_min(xfs_agblock_t a, xfs_agblock_t b);
-#define XFS_AGBLOCK_MIN(a,b) xfs_agblock_min(a,b)
-#else
+ (xfs_extlen_t)(a) : (xfs_extlen_t)(b))
#define XFS_AGBLOCK_MIN(a,b) \
((xfs_agblock_t)(a) < (xfs_agblock_t)(b) ? \
- (xfs_agblock_t)(a) : (xfs_agblock_t)(b))
-#endif
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_AGBLOCK_MAX)
-xfs_agblock_t xfs_agblock_max(xfs_agblock_t a, xfs_agblock_t b);
-#define XFS_AGBLOCK_MAX(a,b) xfs_agblock_max(a,b)
-#else
+ (xfs_agblock_t)(a) : (xfs_agblock_t)(b))
#define XFS_AGBLOCK_MAX(a,b) \
((xfs_agblock_t)(a) > (xfs_agblock_t)(b) ? \
- (xfs_agblock_t)(a) : (xfs_agblock_t)(b))
-#endif
-
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_FILEOFF_MIN)
-xfs_fileoff_t xfs_fileoff_min(xfs_fileoff_t a, xfs_fileoff_t b);
-#define XFS_FILEOFF_MIN(a,b) xfs_fileoff_min(a,b)
-#else
+ (xfs_agblock_t)(a) : (xfs_agblock_t)(b))
#define XFS_FILEOFF_MIN(a,b) \
((xfs_fileoff_t)(a) < (xfs_fileoff_t)(b) ? \
- (xfs_fileoff_t)(a) : (xfs_fileoff_t)(b))
-#endif
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_FILEOFF_MAX)
-xfs_fileoff_t xfs_fileoff_max(xfs_fileoff_t a, xfs_fileoff_t b);
-#define XFS_FILEOFF_MAX(a,b) xfs_fileoff_max(a,b)
-#else
+ (xfs_fileoff_t)(a) : (xfs_fileoff_t)(b))
#define XFS_FILEOFF_MAX(a,b) \
((xfs_fileoff_t)(a) > (xfs_fileoff_t)(b) ? \
- (xfs_fileoff_t)(a) : (xfs_fileoff_t)(b))
-#endif
-
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_FILBLKS_MIN)
-xfs_filblks_t xfs_filblks_min(xfs_filblks_t a, xfs_filblks_t b);
-#define XFS_FILBLKS_MIN(a,b) xfs_filblks_min(a,b)
-#else
+ (xfs_fileoff_t)(a) : (xfs_fileoff_t)(b))
#define XFS_FILBLKS_MIN(a,b) \
((xfs_filblks_t)(a) < (xfs_filblks_t)(b) ? \
- (xfs_filblks_t)(a) : (xfs_filblks_t)(b))
-#endif
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_FILBLKS_MAX)
-xfs_filblks_t xfs_filblks_max(xfs_filblks_t a, xfs_filblks_t b);
-#define XFS_FILBLKS_MAX(a,b) xfs_filblks_max(a,b)
-#else
+ (xfs_filblks_t)(a) : (xfs_filblks_t)(b))
#define XFS_FILBLKS_MAX(a,b) \
((xfs_filblks_t)(a) > (xfs_filblks_t)(b) ? \
- (xfs_filblks_t)(a) : (xfs_filblks_t)(b))
-#endif
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_FSB_SANITY_CHECK)
-int xfs_fsb_sanity_check(struct xfs_mount *mp, xfs_fsblock_t fsb);
-#define XFS_FSB_SANITY_CHECK(mp,fsb) xfs_fsb_sanity_check(mp,fsb)
-#else
+ (xfs_filblks_t)(a) : (xfs_filblks_t)(b))
+
#define XFS_FSB_SANITY_CHECK(mp,fsb) \
(XFS_FSB_TO_AGNO(mp, fsb) < mp->m_sb.sb_agcount && \
- XFS_FSB_TO_AGBNO(mp, fsb) < mp->m_sb.sb_agblocks)
-#endif
-
-/*
- * Macros to set EFSCORRUPTED & return/branch.
- */
-#define XFS_WANT_CORRUPTED_GOTO(x,l) \
- { \
- int fs_is_ok = (x); \
- ASSERT(fs_is_ok); \
- if (unlikely(!fs_is_ok)) { \
- XFS_ERROR_REPORT("XFS_WANT_CORRUPTED_GOTO", \
- XFS_ERRLEVEL_LOW, NULL); \
- error = XFS_ERROR(EFSCORRUPTED); \
- goto l; \
- } \
- }
-
-#define XFS_WANT_CORRUPTED_RETURN(x) \
- { \
- int fs_is_ok = (x); \
- ASSERT(fs_is_ok); \
- if (unlikely(!fs_is_ok)) { \
- XFS_ERROR_REPORT("XFS_WANT_CORRUPTED_RETURN", \
- XFS_ERRLEVEL_LOW, NULL); \
- return XFS_ERROR(EFSCORRUPTED); \
- } \
- }
+ XFS_FSB_TO_AGBNO(mp, fsb) < mp->m_sb.sb_agblocks)
#endif /* __XFS_BTREE_H__ */
diff --git a/fs/xfs/xfs_buf_item.c b/fs/xfs/xfs_buf_item.c
index a264657acfd9..07e2324152b1 100644
--- a/fs/xfs/xfs_buf_item.c
+++ b/fs/xfs/xfs_buf_item.c
@@ -1,57 +1,33 @@
/*
- * Copyright (c) 2000-2004 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
- */
-
-/*
- * This file contains the implementation of the xfs_buf_log_item.
- * It contains the item operations used to manipulate the buf log
- * items as well as utility routines used by the buffer specific
- * transaction routines.
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-
#include "xfs.h"
-
-#include "xfs_macros.h"
+#include "xfs_fs.h"
#include "xfs_types.h"
-#include "xfs_inum.h"
+#include "xfs_bit.h"
#include "xfs_log.h"
+#include "xfs_inum.h"
#include "xfs_trans.h"
-#include "xfs_buf_item.h"
#include "xfs_sb.h"
#include "xfs_dir.h"
#include "xfs_dmapi.h"
#include "xfs_mount.h"
+#include "xfs_buf_item.h"
#include "xfs_trans_priv.h"
-#include "xfs_rw.h"
-#include "xfs_bit.h"
#include "xfs_error.h"
diff --git a/fs/xfs/xfs_buf_item.h b/fs/xfs/xfs_buf_item.h
index 01aed5f2d579..07c708c2b529 100644
--- a/fs/xfs/xfs_buf_item.h
+++ b/fs/xfs/xfs_buf_item.h
@@ -1,33 +1,19 @@
/*
- * Copyright (c) 2000-2001 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __XFS_BUF_ITEM_H__
#define __XFS_BUF_ITEM_H__
diff --git a/fs/xfs/xfs_cap.h b/fs/xfs/xfs_cap.h
index 2deac7303758..433ec537f9bd 100644
--- a/fs/xfs/xfs_cap.h
+++ b/fs/xfs/xfs_cap.h
@@ -1,33 +1,19 @@
/*
- * Copyright (c) 2000-2002 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __XFS_CAP_H__
#define __XFS_CAP_H__
diff --git a/fs/xfs/xfs_clnt.h b/fs/xfs/xfs_clnt.h
index b3215ffe0be8..328a528b926d 100644
--- a/fs/xfs/xfs_clnt.h
+++ b/fs/xfs/xfs_clnt.h
@@ -1,33 +1,19 @@
/*
- * Copyright (c) 2000-2005 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __XFS_CLNT_H__
#define __XFS_CLNT_H__
@@ -55,6 +41,7 @@
*/
struct xfs_mount_args {
int flags; /* flags -> see XFSMNT_... macros below */
+ int flags2; /* flags -> see XFSMNT2_... macros below */
int logbufs; /* Number of log buffers, -1 to default */
int logbufsize; /* Size of log buffers, -1 to default */
char fsname[MAXNAMELEN+1]; /* data device name */
@@ -68,9 +55,9 @@ struct xfs_mount_args {
};
/*
- * XFS mount option flags
+ * XFS mount option flags -- args->flags1
*/
-#define XFSMNT_CHKLOG 0x00000001 /* check log */
+#define XFSMNT_COMPAT_ATTR 0x00000001 /* do not use ATTR2 format */
#define XFSMNT_WSYNC 0x00000002 /* safe mode nfs mount
* compatible */
#define XFSMNT_INO64 0x00000004 /* move inode numbers up
@@ -91,7 +78,7 @@ struct xfs_mount_args {
#define XFSMNT_SHARED 0x00001000 /* shared XFS mount */
#define XFSMNT_IOSIZE 0x00002000 /* optimize for I/O size */
#define XFSMNT_OSYNCISOSYNC 0x00004000 /* o_sync is REALLY o_sync */
- /* (osyncisdsync is now default) */
+ /* (osyncisdsync is default) */
#define XFSMNT_32BITINODES 0x00200000 /* restrict inodes to 32
* bits of address space */
#define XFSMNT_GQUOTA 0x00400000 /* group quota accounting */
@@ -99,12 +86,19 @@ struct xfs_mount_args {
* enforcement */
#define XFSMNT_NOUUID 0x01000000 /* Ignore fs uuid */
#define XFSMNT_DMAPI 0x02000000 /* enable dmapi/xdsm */
-#define XFSMNT_NOLOGFLUSH 0x04000000 /* Don't flush for log blocks */
+#define XFSMNT_BARRIER 0x04000000 /* use write barriers */
#define XFSMNT_IDELETE 0x08000000 /* inode cluster delete */
#define XFSMNT_SWALLOC 0x10000000 /* turn on stripe width
* allocation */
#define XFSMNT_IHASHSIZE 0x20000000 /* inode hash table size */
#define XFSMNT_DIRSYNC 0x40000000 /* sync creat,link,unlink,rename
* symlink,mkdir,rmdir,mknod */
+#define XFSMNT_FLAGS2 0x80000000 /* more flags set in flags2 */
+
+/*
+ * XFS mount option flags -- args->flags2
+ */
+#define XFSMNT2_COMPAT_IOSIZE 0x00000001 /* don't report large preferred
+ * I/O size in stat(2) */
#endif /* __XFS_CLNT_H__ */
diff --git a/fs/xfs/xfs_da_btree.c b/fs/xfs/xfs_da_btree.c
index 8b792ddf2164..473671fa5c13 100644
--- a/fs/xfs/xfs_da_btree.c
+++ b/fs/xfs/xfs_da_btree.c
@@ -1,41 +1,26 @@
/*
- * Copyright (c) 2000-2004 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-
#include "xfs.h"
-
-#include "xfs_macros.h"
+#include "xfs_fs.h"
#include "xfs_types.h"
-#include "xfs_inum.h"
+#include "xfs_bit.h"
#include "xfs_log.h"
+#include "xfs_inum.h"
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
@@ -43,19 +28,19 @@
#include "xfs_dir2.h"
#include "xfs_dmapi.h"
#include "xfs_mount.h"
-#include "xfs_alloc_btree.h"
+#include "xfs_da_btree.h"
#include "xfs_bmap_btree.h"
+#include "xfs_alloc_btree.h"
#include "xfs_ialloc_btree.h"
-#include "xfs_alloc.h"
-#include "xfs_btree.h"
-#include "xfs_attr_sf.h"
#include "xfs_dir_sf.h"
#include "xfs_dir2_sf.h"
+#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
-#include "xfs_inode_item.h"
#include "xfs_inode.h"
+#include "xfs_inode_item.h"
+#include "xfs_alloc.h"
+#include "xfs_btree.h"
#include "xfs_bmap.h"
-#include "xfs_da_btree.h"
#include "xfs_attr.h"
#include "xfs_attr_leaf.h"
#include "xfs_dir_leaf.h"
@@ -64,7 +49,6 @@
#include "xfs_dir2_block.h"
#include "xfs_dir2_node.h"
#include "xfs_error.h"
-#include "xfs_bit.h"
/*
* xfs_da_btree.c
@@ -190,9 +174,6 @@ xfs_da_split(xfs_da_state_t *state)
*/
switch (oldblk->magic) {
case XFS_ATTR_LEAF_MAGIC:
-#ifndef __KERNEL__
- return(ENOTTY);
-#else
error = xfs_attr_leaf_split(state, oldblk, newblk);
if ((error != 0) && (error != ENOSPC)) {
return(error); /* GROT: attr is inconsistent */
@@ -218,7 +199,6 @@ xfs_da_split(xfs_da_state_t *state)
return(error); /* GROT: attr inconsistent */
addblk = newblk;
break;
-#endif
case XFS_DIR_LEAF_MAGIC:
ASSERT(XFS_DIR_IS_V1(state->mp));
error = xfs_dir_leaf_split(state, oldblk, newblk);
@@ -449,7 +429,8 @@ xfs_da_node_split(xfs_da_state_t *state, xfs_da_state_blk_t *oldblk,
/*
* With V2 the extra block is data or freespace.
*/
- useextra = state->extravalid && XFS_DIR_IS_V1(state->mp);
+ useextra = state->extravalid && (XFS_DIR_IS_V1(state->mp) ||
+ state->args->whichfork == XFS_ATTR_FORK);
newcount = 1 + useextra;
/*
* Do we have to split the node?
@@ -706,18 +687,12 @@ xfs_da_join(xfs_da_state_t *state)
*/
switch (drop_blk->magic) {
case XFS_ATTR_LEAF_MAGIC:
-#ifndef __KERNEL__
- error = ENOTTY;
-#else
error = xfs_attr_leaf_toosmall(state, &action);
-#endif
if (error)
return(error);
if (action == 0)
return(0);
-#ifdef __KERNEL__
xfs_attr_leaf_unbalance(state, drop_blk, save_blk);
-#endif
break;
case XFS_DIR_LEAF_MAGIC:
ASSERT(XFS_DIR_IS_V1(state->mp));
@@ -973,13 +948,11 @@ xfs_da_fixhashpath(xfs_da_state_t *state, xfs_da_state_path_t *path)
level = path->active-1;
blk = &path->blk[ level ];
switch (blk->magic) {
-#ifdef __KERNEL__
case XFS_ATTR_LEAF_MAGIC:
lasthash = xfs_attr_leaf_lasthash(blk->bp, &count);
if (count == 0)
return;
break;
-#endif
case XFS_DIR_LEAF_MAGIC:
ASSERT(XFS_DIR_IS_V1(state->mp));
lasthash = xfs_dir_leaf_lasthash(blk->bp, &count);
@@ -1220,12 +1193,10 @@ xfs_da_node_lookup_int(xfs_da_state_t *state, int *result)
blkno = INT_GET(btree->before, ARCH_CONVERT);
}
}
-#ifdef __KERNEL__
else if (INT_GET(curr->magic, ARCH_CONVERT) == XFS_ATTR_LEAF_MAGIC) {
blk->hashval = xfs_attr_leaf_lasthash(blk->bp, NULL);
break;
}
-#endif
else if (INT_GET(curr->magic, ARCH_CONVERT) == XFS_DIR_LEAF_MAGIC) {
blk->hashval = xfs_dir_leaf_lasthash(blk->bp, NULL);
break;
@@ -1252,13 +1223,11 @@ xfs_da_node_lookup_int(xfs_da_state_t *state, int *result)
retval = xfs_dir2_leafn_lookup_int(blk->bp, args,
&blk->index, state);
}
-#ifdef __KERNEL__
else if (blk->magic == XFS_ATTR_LEAF_MAGIC) {
retval = xfs_attr_leaf_lookup_int(blk->bp, args);
blk->index = args->index;
args->blkno = blk->blkno;
}
-#endif
if (((retval == ENOENT) || (retval == ENOATTR)) &&
(blk->hashval == args->hashval)) {
error = xfs_da_path_shift(state, &state->path, 1, 1,
@@ -1268,12 +1237,10 @@ xfs_da_node_lookup_int(xfs_da_state_t *state, int *result)
if (retval == 0) {
continue;
}
-#ifdef __KERNEL__
else if (blk->magic == XFS_ATTR_LEAF_MAGIC) {
/* path_shift() gives ENOENT */
retval = XFS_ERROR(ENOATTR);
}
-#endif
}
break;
}
@@ -1312,11 +1279,9 @@ xfs_da_blk_link(xfs_da_state_t *state, xfs_da_state_blk_t *old_blk,
ASSERT(old_blk->magic == new_blk->magic);
switch (old_blk->magic) {
-#ifdef __KERNEL__
case XFS_ATTR_LEAF_MAGIC:
before = xfs_attr_leaf_order(old_blk->bp, new_blk->bp);
break;
-#endif
case XFS_DIR_LEAF_MAGIC:
ASSERT(XFS_DIR_IS_V1(state->mp));
before = xfs_dir_leaf_order(old_blk->bp, new_blk->bp);
@@ -1587,12 +1552,10 @@ xfs_da_path_shift(xfs_da_state_t *state, xfs_da_state_path_t *path,
ASSERT(level == path->active-1);
blk->index = 0;
switch(blk->magic) {
-#ifdef __KERNEL__
case XFS_ATTR_LEAF_MAGIC:
blk->hashval = xfs_attr_leaf_lasthash(blk->bp,
NULL);
break;
-#endif
case XFS_DIR_LEAF_MAGIC:
ASSERT(XFS_DIR_IS_V1(state->mp));
blk->hashval = xfs_dir_leaf_lasthash(blk->bp,
@@ -1626,19 +1589,10 @@ xfs_da_path_shift(xfs_da_state_t *state, xfs_da_state_path_t *path,
* This is implemented with some source-level loop unrolling.
*/
xfs_dahash_t
-xfs_da_hashname(uchar_t *name, int namelen)
+xfs_da_hashname(const uchar_t *name, int namelen)
{
xfs_dahash_t hash;
-#ifdef SLOWVERSION
- /*
- * This is the old one-byte-at-a-time version.
- */
- for (hash = 0; namelen > 0; namelen--)
- hash = *name++ ^ rol32(hash, 7);
-
- return(hash);
-#else
/*
* Do four characters at a time as long as we can.
*/
@@ -1657,12 +1611,9 @@ xfs_da_hashname(uchar_t *name, int namelen)
return (name[0] << 7) ^ (name[1] << 0) ^ rol32(hash, 7 * 2);
case 1:
return (name[0] << 0) ^ rol32(hash, 7 * 1);
- case 0:
+ default: /* case 0: */
return hash;
}
- /* NOTREACHED */
-#endif
- return 0; /* keep gcc happy */
}
/*
@@ -2200,20 +2151,16 @@ xfs_da_do_buf(
error = bp ? XFS_BUF_GETERROR(bp) : XFS_ERROR(EIO);
break;
case 1:
-#ifndef __KERNEL__
case 2:
-#endif
bp = NULL;
error = xfs_trans_read_buf(mp, trans, mp->m_ddev_targp,
mappedbno, nmapped, 0, &bp);
break;
-#ifdef __KERNEL__
case 3:
xfs_baread(mp->m_ddev_targp, mappedbno, nmapped);
error = 0;
bp = NULL;
break;
-#endif
}
if (error) {
if (bp)
diff --git a/fs/xfs/xfs_da_btree.h b/fs/xfs/xfs_da_btree.h
index 3a9b9e809c60..41352113721a 100644
--- a/fs/xfs/xfs_da_btree.h
+++ b/fs/xfs/xfs_da_btree.h
@@ -1,33 +1,19 @@
/*
- * Copyright (c) 2000, 2002 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000,2002,2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __XFS_DA_BTREE_H__
#define __XFS_DA_BTREE_H__
@@ -92,72 +78,24 @@ typedef struct xfs_da_node_entry xfs_da_node_entry_t;
#define XFS_DA_MAXHASH ((xfs_dahash_t)-1) /* largest valid hash value */
-/*
- * Macros used by directory code to interface to the filesystem.
- */
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_LBSIZE)
-int xfs_lbsize(struct xfs_mount *mp);
-#define XFS_LBSIZE(mp) xfs_lbsize(mp)
-#else
-#define XFS_LBSIZE(mp) ((mp)->m_sb.sb_blocksize)
-#endif
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_LBLOG)
-int xfs_lblog(struct xfs_mount *mp);
-#define XFS_LBLOG(mp) xfs_lblog(mp)
-#else
-#define XFS_LBLOG(mp) ((mp)->m_sb.sb_blocklog)
-#endif
+#define XFS_LBSIZE(mp) (mp)->m_sb.sb_blocksize
+#define XFS_LBLOG(mp) (mp)->m_sb.sb_blocklog
-/*
- * Macros used by directory code to interface to the kernel
- */
-
-/*
- * Macros used to manipulate directory off_t's
- */
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_DA_MAKE_BNOENTRY)
-__uint32_t xfs_da_make_bnoentry(struct xfs_mount *mp, xfs_dablk_t bno,
- int entry);
#define XFS_DA_MAKE_BNOENTRY(mp,bno,entry) \
- xfs_da_make_bnoentry(mp,bno,entry)
-#else
-#define XFS_DA_MAKE_BNOENTRY(mp,bno,entry) \
(((bno) << (mp)->m_dircook_elog) | (entry))
-#endif
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_DA_MAKE_COOKIE)
-xfs_off_t xfs_da_make_cookie(struct xfs_mount *mp, xfs_dablk_t bno, int entry,
- xfs_dahash_t hash);
#define XFS_DA_MAKE_COOKIE(mp,bno,entry,hash) \
- xfs_da_make_cookie(mp,bno,entry,hash)
-#else
-#define XFS_DA_MAKE_COOKIE(mp,bno,entry,hash) \
(((xfs_off_t)XFS_DA_MAKE_BNOENTRY(mp, bno, entry) << 32) | (hash))
-#endif
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_DA_COOKIE_HASH)
-xfs_dahash_t xfs_da_cookie_hash(struct xfs_mount *mp, xfs_off_t cookie);
-#define XFS_DA_COOKIE_HASH(mp,cookie) xfs_da_cookie_hash(mp,cookie)
-#else
-#define XFS_DA_COOKIE_HASH(mp,cookie) ((xfs_dahash_t)(cookie))
-#endif
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_DA_COOKIE_BNO)
-xfs_dablk_t xfs_da_cookie_bno(struct xfs_mount *mp, xfs_off_t cookie);
-#define XFS_DA_COOKIE_BNO(mp,cookie) xfs_da_cookie_bno(mp,cookie)
-#else
-#define XFS_DA_COOKIE_BNO(mp,cookie) \
- (((xfs_off_t)(cookie) >> 31) == -1LL ? \
+#define XFS_DA_COOKIE_HASH(mp,cookie) ((xfs_dahash_t)cookie)
+#define XFS_DA_COOKIE_BNO(mp,cookie) \
+ ((((xfs_off_t)(cookie) >> 31) == -1LL ? \
(xfs_dablk_t)0 : \
- (xfs_dablk_t)((xfs_off_t)(cookie) >> ((mp)->m_dircook_elog + 32)))
-#endif
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_DA_COOKIE_ENTRY)
-int xfs_da_cookie_entry(struct xfs_mount *mp, xfs_off_t cookie);
-#define XFS_DA_COOKIE_ENTRY(mp,cookie) xfs_da_cookie_entry(mp,cookie)
-#else
-#define XFS_DA_COOKIE_ENTRY(mp,cookie) \
- (((xfs_off_t)(cookie) >> 31) == -1LL ? \
+ (xfs_dablk_t)((xfs_off_t)(cookie) >> \
+ ((mp)->m_dircook_elog + 32))))
+#define XFS_DA_COOKIE_ENTRY(mp,cookie) \
+ ((((xfs_off_t)(cookie) >> 31) == -1LL ? \
(xfs_dablk_t)0 : \
(xfs_dablk_t)(((xfs_off_t)(cookie) >> 32) & \
- ((1 << (mp)->m_dircook_elog) - 1)))
-#endif
+ ((1 << (mp)->m_dircook_elog) - 1))))
/*========================================================================
@@ -168,7 +106,7 @@ int xfs_da_cookie_entry(struct xfs_mount *mp, xfs_off_t cookie);
* Structure to ease passing around component names.
*/
typedef struct xfs_da_args {
- uchar_t *name; /* string (maybe not NULL terminated) */
+ const uchar_t *name; /* string (maybe not NULL terminated) */
int namelen; /* length of string (maybe no NULL) */
uchar_t *value; /* set of bytes (maybe contain NULLs) */
int valuelen; /* length of value */
@@ -314,7 +252,7 @@ xfs_daddr_t xfs_da_reada_buf(struct xfs_trans *trans, struct xfs_inode *dp,
int xfs_da_shrink_inode(xfs_da_args_t *args, xfs_dablk_t dead_blkno,
xfs_dabuf_t *dead_buf);
-uint xfs_da_hashname(uchar_t *name_string, int name_length);
+uint xfs_da_hashname(const uchar_t *name_string, int name_length);
uint xfs_da_log2_roundup(uint i);
xfs_da_state_t *xfs_da_state_alloc(void);
void xfs_da_state_free(xfs_da_state_t *state);
diff --git a/fs/xfs/xfs_dfrag.c b/fs/xfs/xfs_dfrag.c
index 681be5c93af5..070259a4254c 100644
--- a/fs/xfs/xfs_dfrag.c
+++ b/fs/xfs/xfs_dfrag.c
@@ -1,58 +1,44 @@
/*
- * Copyright (c) 2000-2002 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-
#include "xfs.h"
-#include "xfs_macros.h"
+#include "xfs_fs.h"
#include "xfs_types.h"
-#include "xfs_inum.h"
+#include "xfs_bit.h"
#include "xfs_log.h"
+#include "xfs_inum.h"
#include "xfs_trans.h"
#include "xfs_sb.h"
+#include "xfs_ag.h"
#include "xfs_dir.h"
#include "xfs_dir2.h"
#include "xfs_dmapi.h"
#include "xfs_mount.h"
-#include "xfs_ag.h"
-#include "xfs_alloc_btree.h"
#include "xfs_bmap_btree.h"
+#include "xfs_alloc_btree.h"
#include "xfs_ialloc_btree.h"
-#include "xfs_btree.h"
-#include "xfs_attr_sf.h"
#include "xfs_dir_sf.h"
#include "xfs_dir2_sf.h"
+#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
-#include "xfs_inode_item.h"
#include "xfs_inode.h"
+#include "xfs_inode_item.h"
#include "xfs_bmap.h"
+#include "xfs_btree.h"
#include "xfs_ialloc.h"
#include "xfs_itable.h"
#include "xfs_dfrag.h"
@@ -65,9 +51,9 @@
*/
int
xfs_swapext(
- xfs_swapext_t __user *sxp)
+ xfs_swapext_t __user *sxu)
{
- xfs_swapext_t sx;
+ xfs_swapext_t *sxp;
xfs_inode_t *ip=NULL, *tip=NULL, *ips[2];
xfs_trans_t *tp;
xfs_mount_t *mp;
@@ -76,20 +62,29 @@ xfs_swapext(
vnode_t *vp, *tvp;
bhv_desc_t *bdp, *tbdp;
vn_bhv_head_t *bhp, *tbhp;
- uint lock_flags=0;
+ static uint lock_flags = XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL;
int ilf_fields, tilf_fields;
int error = 0;
- xfs_ifork_t tempif, *ifp, *tifp;
+ xfs_ifork_t *tempifp, *ifp, *tifp;
__uint64_t tmp;
int aforkblks = 0;
int taforkblks = 0;
- int locked = 0;
+ char locked = 0;
- if (copy_from_user(&sx, sxp, sizeof(sx)))
- return XFS_ERROR(EFAULT);
+ sxp = kmem_alloc(sizeof(xfs_swapext_t), KM_MAYFAIL);
+ tempifp = kmem_alloc(sizeof(xfs_ifork_t), KM_MAYFAIL);
+ if (!sxp || !tempifp) {
+ error = XFS_ERROR(ENOMEM);
+ goto error0;
+ }
+
+ if (copy_from_user(sxp, sxu, sizeof(xfs_swapext_t))) {
+ error = XFS_ERROR(EFAULT);
+ goto error0;
+ }
/* Pull information for the target fd */
- if (((fp = fget((int)sx.sx_fdtarget)) == NULL) ||
+ if (((fp = fget((int)sxp->sx_fdtarget)) == NULL) ||
((vp = LINVFS_GET_VP(fp->f_dentry->d_inode)) == NULL)) {
error = XFS_ERROR(EINVAL);
goto error0;
@@ -104,7 +99,7 @@ xfs_swapext(
ip = XFS_BHVTOI(bdp);
}
- if (((tfp = fget((int)sx.sx_fdtmp)) == NULL) ||
+ if (((tfp = fget((int)sxp->sx_fdtmp)) == NULL) ||
((tvp = LINVFS_GET_VP(tfp->f_dentry->d_inode)) == NULL)) {
error = XFS_ERROR(EINVAL);
goto error0;
@@ -131,7 +126,7 @@ xfs_swapext(
mp = ip->i_mount;
- sbp = &sx.sx_stat;
+ sbp = &sxp->sx_stat;
if (XFS_FORCED_SHUTDOWN(mp)) {
error = XFS_ERROR(EIO);
@@ -148,7 +143,7 @@ xfs_swapext(
ips[0] = tip;
ips[1] = ip;
}
- lock_flags = XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL;
+
xfs_lock_inodes(ips, 2, 0, lock_flags);
/* Check permissions */
@@ -192,9 +187,9 @@ xfs_swapext(
}
/* Verify all data are being swapped */
- if (sx.sx_offset != 0 ||
- sx.sx_length != ip->i_d.di_size ||
- sx.sx_length != tip->i_d.di_size) {
+ if (sxp->sx_offset != 0 ||
+ sxp->sx_length != ip->i_d.di_size ||
+ sxp->sx_length != tip->i_d.di_size) {
error = XFS_ERROR(EFAULT);
goto error0;
}
@@ -255,7 +250,8 @@ xfs_swapext(
xfs_iunlock(ip, XFS_IOLOCK_EXCL);
xfs_iunlock(tip, XFS_IOLOCK_EXCL);
xfs_trans_cancel(tp, 0);
- return error;
+ locked = 0;
+ goto error0;
}
xfs_lock_inodes(ips, 2, 0, XFS_ILOCK_EXCL);
@@ -266,10 +262,8 @@ xfs_swapext(
(ip->i_d.di_aformat != XFS_DINODE_FMT_LOCAL)) {
error = xfs_bmap_count_blocks(tp, ip, XFS_ATTR_FORK, &aforkblks);
if (error) {
- xfs_iunlock(ip, lock_flags);
- xfs_iunlock(tip, lock_flags);
xfs_trans_cancel(tp, 0);
- return error;
+ goto error0;
}
}
if ( ((XFS_IFORK_Q(tip) != 0) && (tip->i_d.di_anextents > 0)) &&
@@ -277,10 +271,8 @@ xfs_swapext(
error = xfs_bmap_count_blocks(tp, tip, XFS_ATTR_FORK,
&taforkblks);
if (error) {
- xfs_iunlock(ip, lock_flags);
- xfs_iunlock(tip, lock_flags);
xfs_trans_cancel(tp, 0);
- return error;
+ goto error0;
}
}
@@ -289,9 +281,9 @@ xfs_swapext(
*/
ifp = &ip->i_df;
tifp = &tip->i_df;
- tempif = *ifp; /* struct copy */
- *ifp = *tifp; /* struct copy */
- *tifp = tempif; /* struct copy */
+ *tempifp = *ifp; /* struct copy */
+ *ifp = *tifp; /* struct copy */
+ *tifp = *tempifp; /* struct copy */
/*
* Fix the on-disk inode values
@@ -369,11 +361,7 @@ xfs_swapext(
}
error = xfs_trans_commit(tp, XFS_TRANS_SWAPEXT, NULL);
-
- fput(fp);
- fput(tfp);
-
- return error;
+ locked = 0;
error0:
if (locked) {
@@ -381,8 +369,15 @@ xfs_swapext(
xfs_iunlock(tip, lock_flags);
}
- if (fp != NULL) fput(fp);
- if (tfp != NULL) fput(tfp);
+ if (fp != NULL)
+ fput(fp);
+ if (tfp != NULL)
+ fput(tfp);
+
+ if (sxp != NULL)
+ kmem_free(sxp, sizeof(xfs_swapext_t));
+ if (tempifp != NULL)
+ kmem_free(tempifp, sizeof(xfs_ifork_t));
return error;
}
diff --git a/fs/xfs/xfs_dfrag.h b/fs/xfs/xfs_dfrag.h
index 904860594b8f..f678559abc45 100644
--- a/fs/xfs/xfs_dfrag.h
+++ b/fs/xfs/xfs_dfrag.h
@@ -1,33 +1,19 @@
/*
- * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000,2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __XFS_DFRAG_H__
#define __XFS_DFRAG_H__
diff --git a/fs/xfs/xfs_dinode.h b/fs/xfs/xfs_dinode.h
index f5c932b064e6..c5a0e537ff1a 100644
--- a/fs/xfs/xfs_dinode.h
+++ b/fs/xfs/xfs_dinode.h
@@ -1,33 +1,19 @@
/*
- * Copyright (c) 2000, 2002 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000,2002,2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __XFS_DINODE_H__
#define __XFS_DINODE_H__
@@ -37,13 +23,8 @@ struct xfs_mount;
#define XFS_DINODE_VERSION_1 1
#define XFS_DINODE_VERSION_2 2
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_DINODE_GOOD_VERSION)
-int xfs_dinode_good_version(int v);
-#define XFS_DINODE_GOOD_VERSION(v) xfs_dinode_good_version(v)
-#else
-#define XFS_DINODE_GOOD_VERSION(v) (((v) == XFS_DINODE_VERSION_1) || \
- ((v) == XFS_DINODE_VERSION_2))
-#endif
+#define XFS_DINODE_GOOD_VERSION(v) \
+ (((v) == XFS_DINODE_VERSION_1 || (v) == XFS_DINODE_VERSION_2))
#define XFS_DINODE_MAGIC 0x494e /* 'IN' */
/*
@@ -184,75 +165,30 @@ typedef enum xfs_dinode_fmt
/*
* Inode size for given fs.
*/
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_LITINO)
-int xfs_litino(struct xfs_mount *mp);
-#define XFS_LITINO(mp) xfs_litino(mp)
-#else
#define XFS_LITINO(mp) ((mp)->m_litino)
-#endif
#define XFS_BROOT_SIZE_ADJ \
(sizeof(xfs_bmbt_block_t) - sizeof(xfs_bmdr_block_t))
/*
- * Fork identifiers. Here so utilities can use them without including
- * xfs_inode.h.
- */
-#define XFS_DATA_FORK 0
-#define XFS_ATTR_FORK 1
-
-/*
* Inode data & attribute fork sizes, per inode.
*/
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_CFORK_Q)
-int xfs_cfork_q_disk(xfs_dinode_core_t *dcp);
-int xfs_cfork_q(xfs_dinode_core_t *dcp);
-#define XFS_CFORK_Q_DISK(dcp) xfs_cfork_q_disk(dcp)
-#define XFS_CFORK_Q(dcp) xfs_cfork_q(dcp)
-#else
-#define XFS_CFORK_Q_DISK(dcp) ((dcp)->di_forkoff != 0)
#define XFS_CFORK_Q(dcp) ((dcp)->di_forkoff != 0)
+#define XFS_CFORK_Q_DISK(dcp) ((dcp)->di_forkoff != 0)
-#endif
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_CFORK_BOFF)
-int xfs_cfork_boff_disk(xfs_dinode_core_t *dcp);
-int xfs_cfork_boff(xfs_dinode_core_t *dcp);
-#define XFS_CFORK_BOFF_DISK(dcp) xfs_cfork_boff_disk(dcp)
-#define XFS_CFORK_BOFF(dcp) xfs_cfork_boff(dcp)
-#else
-#define XFS_CFORK_BOFF_DISK(dcp) ((int)(INT_GET((dcp)->di_forkoff, ARCH_CONVERT) << 3))
#define XFS_CFORK_BOFF(dcp) ((int)((dcp)->di_forkoff << 3))
+#define XFS_CFORK_BOFF_DISK(dcp) \
+ ((int)(INT_GET((dcp)->di_forkoff, ARCH_CONVERT) << 3))
-#endif
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_CFORK_DSIZE)
-int xfs_cfork_dsize_disk(xfs_dinode_core_t *dcp, struct xfs_mount *mp);
-int xfs_cfork_dsize(xfs_dinode_core_t *dcp, struct xfs_mount *mp);
-#define XFS_CFORK_DSIZE_DISK(dcp,mp) xfs_cfork_dsize_disk(dcp,mp)
-#define XFS_CFORK_DSIZE(dcp,mp) xfs_cfork_dsize(dcp,mp)
-#else
#define XFS_CFORK_DSIZE_DISK(dcp,mp) \
(XFS_CFORK_Q_DISK(dcp) ? XFS_CFORK_BOFF_DISK(dcp) : XFS_LITINO(mp))
#define XFS_CFORK_DSIZE(dcp,mp) \
(XFS_CFORK_Q(dcp) ? XFS_CFORK_BOFF(dcp) : XFS_LITINO(mp))
-#endif
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_CFORK_ASIZE)
-int xfs_cfork_asize_disk(xfs_dinode_core_t *dcp, struct xfs_mount *mp);
-int xfs_cfork_asize(xfs_dinode_core_t *dcp, struct xfs_mount *mp);
-#define XFS_CFORK_ASIZE_DISK(dcp,mp) xfs_cfork_asize_disk(dcp,mp)
-#define XFS_CFORK_ASIZE(dcp,mp) xfs_cfork_asize(dcp,mp)
-#else
#define XFS_CFORK_ASIZE_DISK(dcp,mp) \
(XFS_CFORK_Q_DISK(dcp) ? XFS_LITINO(mp) - XFS_CFORK_BOFF_DISK(dcp) : 0)
#define XFS_CFORK_ASIZE(dcp,mp) \
(XFS_CFORK_Q(dcp) ? XFS_LITINO(mp) - XFS_CFORK_BOFF(dcp) : 0)
-#endif
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_CFORK_SIZE)
-int xfs_cfork_size_disk(xfs_dinode_core_t *dcp, struct xfs_mount *mp, int w);
-int xfs_cfork_size(xfs_dinode_core_t *dcp, struct xfs_mount *mp, int w);
-#define XFS_CFORK_SIZE_DISK(dcp,mp,w) xfs_cfork_size_disk(dcp,mp,w)
-#define XFS_CFORK_SIZE(dcp,mp,w) xfs_cfork_size(dcp,mp,w)
-#else
#define XFS_CFORK_SIZE_DISK(dcp,mp,w) \
((w) == XFS_DATA_FORK ? \
XFS_CFORK_DSIZE_DISK(dcp, mp) : \
@@ -261,93 +197,26 @@ int xfs_cfork_size(xfs_dinode_core_t *dcp, struct xfs_mount *mp, int w);
((w) == XFS_DATA_FORK ? \
XFS_CFORK_DSIZE(dcp, mp) : XFS_CFORK_ASIZE(dcp, mp))
-#endif
-
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_DFORK_DSIZE)
-int xfs_dfork_dsize(xfs_dinode_t *dip, struct xfs_mount *mp);
-#define XFS_DFORK_DSIZE(dip,mp) xfs_dfork_dsize(dip,mp)
-#else
-#define XFS_DFORK_DSIZE(dip,mp) XFS_CFORK_DSIZE_DISK(&(dip)->di_core, mp)
-
-#endif
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_DFORK_ASIZE)
-int xfs_dfork_asize(xfs_dinode_t *dip, struct xfs_mount *mp);
-#define XFS_DFORK_ASIZE(dip,mp) xfs_dfork_asize(dip,mp)
-#else
-#define XFS_DFORK_ASIZE(dip,mp) XFS_CFORK_ASIZE_DISK(&(dip)->di_core, mp)
+#define XFS_DFORK_DSIZE(dip,mp) \
+ XFS_CFORK_DSIZE_DISK(&(dip)->di_core, mp)
+#define XFS_DFORK_ASIZE(dip,mp) \
+ XFS_CFORK_ASIZE_DISK(&(dip)->di_core, mp)
+#define XFS_DFORK_SIZE(dip,mp,w) \
+ XFS_CFORK_SIZE_DISK(&(dip)->di_core, mp, w)
-#endif
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_DFORK_SIZE)
-int xfs_dfork_size(xfs_dinode_t *dip, struct xfs_mount *mp, int w);
-#define XFS_DFORK_SIZE(dip,mp,w) xfs_dfork_size(dip,mp,w)
-#else
-#define XFS_DFORK_SIZE(dip,mp,w) XFS_CFORK_SIZE_DISK(&(dip)->di_core, mp, w)
-
-#endif
-
-/*
- * Macros for accessing per-fork disk inode information.
- */
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_DFORK_Q)
-int xfs_dfork_q(xfs_dinode_t *dip);
-#define XFS_DFORK_Q(dip) xfs_dfork_q(dip)
-#else
#define XFS_DFORK_Q(dip) XFS_CFORK_Q_DISK(&(dip)->di_core)
-
-#endif
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_DFORK_BOFF)
-int xfs_dfork_boff(xfs_dinode_t *dip);
-#define XFS_DFORK_BOFF(dip) xfs_dfork_boff(dip)
-#else
#define XFS_DFORK_BOFF(dip) XFS_CFORK_BOFF_DISK(&(dip)->di_core)
-
-#endif
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_DFORK_DPTR)
-char *xfs_dfork_dptr(xfs_dinode_t *dip);
-#define XFS_DFORK_DPTR(dip) xfs_dfork_dptr(dip)
-#else
#define XFS_DFORK_DPTR(dip) ((dip)->di_u.di_c)
-
-#endif
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_DFORK_APTR)
-char *xfs_dfork_aptr(xfs_dinode_t *dip);
-#define XFS_DFORK_APTR(dip) xfs_dfork_aptr(dip)
-#else
-#define XFS_DFORK_APTR(dip) ((dip)->di_u.di_c + XFS_DFORK_BOFF(dip))
-
-#endif
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_DFORK_PTR)
-char *xfs_dfork_ptr(xfs_dinode_t *dip, int w);
-#define XFS_DFORK_PTR(dip,w) xfs_dfork_ptr(dip,w)
-#else
+#define XFS_DFORK_APTR(dip) \
+ ((dip)->di_u.di_c + XFS_DFORK_BOFF(dip))
#define XFS_DFORK_PTR(dip,w) \
((w) == XFS_DATA_FORK ? XFS_DFORK_DPTR(dip) : XFS_DFORK_APTR(dip))
-
-#endif
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_CFORK_FORMAT)
-int xfs_cfork_format(xfs_dinode_core_t *dcp, int w);
-#define XFS_CFORK_FORMAT(dcp,w) xfs_cfork_format(dcp,w)
-#else
-#define XFS_CFORK_FORMAT(dcp,w) \
+#define XFS_CFORK_FORMAT(dcp,w) \
((w) == XFS_DATA_FORK ? (dcp)->di_format : (dcp)->di_aformat)
-
-#endif
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_CFORK_FMT_SET)
-void xfs_cfork_fmt_set(xfs_dinode_core_t *dcp, int w, int n);
-#define XFS_CFORK_FMT_SET(dcp,w,n) xfs_cfork_fmt_set(dcp,w,n)
-#else
#define XFS_CFORK_FMT_SET(dcp,w,n) \
((w) == XFS_DATA_FORK ? \
- ((dcp)->di_format = (n)) : \
- ((dcp)->di_aformat = (n)))
+ ((dcp)->di_format = (n)) : ((dcp)->di_aformat = (n)))
-#endif
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_CFORK_NEXTENTS)
-int xfs_cfork_nextents_disk(xfs_dinode_core_t *dcp, int w);
-int xfs_cfork_nextents(xfs_dinode_core_t *dcp, int w);
-#define XFS_CFORK_NEXTENTS_DISK(dcp,w) xfs_cfork_nextents_disk(dcp,w)
-#define XFS_CFORK_NEXTENTS(dcp,w) xfs_cfork_nextents(dcp,w)
-#else
#define XFS_CFORK_NEXTENTS_DISK(dcp,w) \
((w) == XFS_DATA_FORK ? \
INT_GET((dcp)->di_nextents, ARCH_CONVERT) : \
@@ -355,31 +224,13 @@ int xfs_cfork_nextents(xfs_dinode_core_t *dcp, int w);
#define XFS_CFORK_NEXTENTS(dcp,w) \
((w) == XFS_DATA_FORK ? (dcp)->di_nextents : (dcp)->di_anextents)
-#endif
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_CFORK_NEXT_SET)
-void xfs_cfork_next_set(xfs_dinode_core_t *dcp, int w, int n);
-#define XFS_CFORK_NEXT_SET(dcp,w,n) xfs_cfork_next_set(dcp,w,n)
-#else
#define XFS_CFORK_NEXT_SET(dcp,w,n) \
((w) == XFS_DATA_FORK ? \
- ((dcp)->di_nextents = (n)) : \
- ((dcp)->di_anextents = (n)))
-
-#endif
+ ((dcp)->di_nextents = (n)) : ((dcp)->di_anextents = (n)))
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_DFORK_NEXTENTS)
-int xfs_dfork_nextents(xfs_dinode_t *dip, int w);
-#define XFS_DFORK_NEXTENTS(dip,w) xfs_dfork_nextents(dip,w)
-#else
#define XFS_DFORK_NEXTENTS(dip,w) XFS_CFORK_NEXTENTS_DISK(&(dip)->di_core, w)
-#endif
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_BUF_TO_DINODE)
-xfs_dinode_t *xfs_buf_to_dinode(struct xfs_buf *bp);
-#define XFS_BUF_TO_DINODE(bp) xfs_buf_to_dinode(bp)
-#else
-#define XFS_BUF_TO_DINODE(bp) ((xfs_dinode_t *)(XFS_BUF_PTR(bp)))
-#endif
+#define XFS_BUF_TO_DINODE(bp) ((xfs_dinode_t *)XFS_BUF_PTR(bp))
/*
* Values for di_flags
diff --git a/fs/xfs/xfs_dir.c b/fs/xfs/xfs_dir.c
index ba30bc7682f2..3dd30391f551 100644
--- a/fs/xfs/xfs_dir.c
+++ b/fs/xfs/xfs_dir.c
@@ -1,59 +1,43 @@
/*
- * Copyright (c) 2000-2001 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-
#include "xfs.h"
-
-#include "xfs_macros.h"
+#include "xfs_fs.h"
#include "xfs_types.h"
-#include "xfs_inum.h"
#include "xfs_log.h"
+#include "xfs_inum.h"
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_dir.h"
#include "xfs_dir2.h"
#include "xfs_dmapi.h"
#include "xfs_mount.h"
-#include "xfs_alloc_btree.h"
+#include "xfs_da_btree.h"
#include "xfs_bmap_btree.h"
+#include "xfs_alloc_btree.h"
#include "xfs_ialloc_btree.h"
#include "xfs_alloc.h"
#include "xfs_btree.h"
-#include "xfs_attr_sf.h"
#include "xfs_dir_sf.h"
#include "xfs_dir2_sf.h"
+#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
#include "xfs_inode.h"
#include "xfs_bmap.h"
-#include "xfs_da_btree.h"
#include "xfs_dir_leaf.h"
#include "xfs_error.h"
@@ -192,11 +176,23 @@ xfs_dir_mount(xfs_mount_t *mp)
uint shortcount, leafcount, count;
mp->m_dirversion = 1;
- shortcount = (mp->m_attroffset - (uint)sizeof(xfs_dir_sf_hdr_t)) /
- (uint)sizeof(xfs_dir_sf_entry_t);
- leafcount = (XFS_LBSIZE(mp) - (uint)sizeof(xfs_dir_leaf_hdr_t)) /
- ((uint)sizeof(xfs_dir_leaf_entry_t) +
- (uint)sizeof(xfs_dir_leaf_name_t));
+ if (mp->m_flags & XFS_MOUNT_COMPAT_ATTR) {
+ shortcount = (mp->m_attroffset -
+ (uint)sizeof(xfs_dir_sf_hdr_t)) /
+ (uint)sizeof(xfs_dir_sf_entry_t);
+ leafcount = (XFS_LBSIZE(mp) -
+ (uint)sizeof(xfs_dir_leaf_hdr_t)) /
+ ((uint)sizeof(xfs_dir_leaf_entry_t) +
+ (uint)sizeof(xfs_dir_leaf_name_t));
+ } else {
+ shortcount = (XFS_BMDR_SPACE_CALC(MINABTPTRS) -
+ (uint)sizeof(xfs_dir_sf_hdr_t)) /
+ (uint)sizeof(xfs_dir_sf_entry_t);
+ leafcount = (XFS_LBSIZE(mp) -
+ (uint)sizeof(xfs_dir_leaf_hdr_t)) /
+ ((uint)sizeof(xfs_dir_leaf_entry_t) +
+ (uint)sizeof(xfs_dir_leaf_name_t));
+ }
count = shortcount > leafcount ? shortcount : leafcount;
mp->m_dircook_elog = xfs_da_log2_roundup(count + 1);
ASSERT(mp->m_dircook_elog <= mp->m_sb.sb_blocklog);
diff --git a/fs/xfs/xfs_dir.h b/fs/xfs/xfs_dir.h
index 4dbc9f54cca5..488defe86ba6 100644
--- a/fs/xfs/xfs_dir.h
+++ b/fs/xfs/xfs_dir.h
@@ -1,33 +1,19 @@
/*
- * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000,2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __XFS_DIR_H__
#define __XFS_DIR_H__
diff --git a/fs/xfs/xfs_dir2.c b/fs/xfs/xfs_dir2.c
index 49fc0a3695ae..022c8398ab62 100644
--- a/fs/xfs/xfs_dir2.c
+++ b/fs/xfs/xfs_dir2.c
@@ -1,46 +1,26 @@
/*
- * Copyright (c) 2000-2001 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-
-/*
- * XFS v2 directory implmentation.
- * Top-level and utility routines.
- */
-
#include "xfs.h"
-
-#include "xfs_macros.h"
+#include "xfs_fs.h"
#include "xfs_types.h"
-#include "xfs_inum.h"
+#include "xfs_bit.h"
#include "xfs_log.h"
+#include "xfs_inum.h"
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
@@ -48,16 +28,16 @@
#include "xfs_dir2.h"
#include "xfs_dmapi.h"
#include "xfs_mount.h"
-#include "xfs_alloc_btree.h"
+#include "xfs_da_btree.h"
#include "xfs_bmap_btree.h"
-#include "xfs_attr_sf.h"
+#include "xfs_alloc_btree.h"
#include "xfs_dir_sf.h"
#include "xfs_dir2_sf.h"
+#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
-#include "xfs_inode_item.h"
#include "xfs_inode.h"
+#include "xfs_inode_item.h"
#include "xfs_bmap.h"
-#include "xfs_da_btree.h"
#include "xfs_dir_leaf.h"
#include "xfs_dir2_data.h"
#include "xfs_dir2_leaf.h"
@@ -65,7 +45,6 @@
#include "xfs_dir2_node.h"
#include "xfs_dir2_trace.h"
#include "xfs_error.h"
-#include "xfs_bit.h"
/*
* Declarations for interface routines.
diff --git a/fs/xfs/xfs_dir2.h b/fs/xfs/xfs_dir2.h
index 8f4fc7f23bcd..7e24ffeda9e1 100644
--- a/fs/xfs/xfs_dir2.h
+++ b/fs/xfs/xfs_dir2.h
@@ -1,33 +1,19 @@
/*
- * Copyright (c) 2000-2001 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __XFS_DIR2_H__
#define __XFS_DIR2_H__
diff --git a/fs/xfs/xfs_dir2_block.c b/fs/xfs/xfs_dir2_block.c
index bc4c40fcd479..31bc99faa704 100644
--- a/fs/xfs/xfs_dir2_block.c
+++ b/fs/xfs/xfs_dir2_block.c
@@ -1,61 +1,39 @@
/*
- * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-
-/*
- * xfs_dir2_block.c
- * XFS V2 directory implementation, single-block form.
- * See xfs_dir2_block.h for the format.
- */
-
#include "xfs.h"
-
-#include "xfs_macros.h"
+#include "xfs_fs.h"
#include "xfs_types.h"
-#include "xfs_inum.h"
#include "xfs_log.h"
+#include "xfs_inum.h"
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_dir.h"
#include "xfs_dir2.h"
#include "xfs_dmapi.h"
#include "xfs_mount.h"
+#include "xfs_da_btree.h"
#include "xfs_bmap_btree.h"
-#include "xfs_attr_sf.h"
#include "xfs_dir_sf.h"
#include "xfs_dir2_sf.h"
+#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
-#include "xfs_inode_item.h"
#include "xfs_inode.h"
-#include "xfs_da_btree.h"
+#include "xfs_inode_item.h"
#include "xfs_dir_leaf.h"
#include "xfs_dir2_data.h"
#include "xfs_dir2_leaf.h"
@@ -1234,7 +1212,7 @@ xfs_dir2_sf_to_block(
/*
* Sort the leaf entries by hash value.
*/
- qsort(blp, INT_GET(btp->count, ARCH_CONVERT), sizeof(*blp), xfs_dir2_block_sort);
+ xfs_sort(blp, INT_GET(btp->count, ARCH_CONVERT), sizeof(*blp), xfs_dir2_block_sort);
/*
* Log the leaf entry area and tail.
* Already logged the header in data_init, ignore needlog.
diff --git a/fs/xfs/xfs_dir2_block.h b/fs/xfs/xfs_dir2_block.h
index 5a578b84e246..a2e5cb98a838 100644
--- a/fs/xfs/xfs_dir2_block.h
+++ b/fs/xfs/xfs_dir2_block.h
@@ -1,33 +1,19 @@
/*
- * Copyright (c) 2000-2001 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __XFS_DIR2_BLOCK_H__
#define __XFS_DIR2_BLOCK_H__
@@ -74,53 +60,37 @@ typedef struct xfs_dir2_block {
/*
* Pointer to the leaf header embedded in a data block (1-block format)
*/
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_DIR2_BLOCK_TAIL_P)
-xfs_dir2_block_tail_t *
-xfs_dir2_block_tail_p(struct xfs_mount *mp, xfs_dir2_block_t *block);
#define XFS_DIR2_BLOCK_TAIL_P(mp,block) xfs_dir2_block_tail_p(mp,block)
-#else
-#define XFS_DIR2_BLOCK_TAIL_P(mp,block) \
- (((xfs_dir2_block_tail_t *)((char *)(block) + (mp)->m_dirblksize)) - 1)
-#endif
+static inline xfs_dir2_block_tail_t *
+xfs_dir2_block_tail_p(struct xfs_mount *mp, xfs_dir2_block_t *block)
+{
+ return (((xfs_dir2_block_tail_t *)
+ ((char *)(block) + (mp)->m_dirblksize)) - 1);
+}
/*
* Pointer to the leaf entries embedded in a data block (1-block format)
*/
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_DIR2_BLOCK_LEAF_P)
-struct xfs_dir2_leaf_entry *xfs_dir2_block_leaf_p(xfs_dir2_block_tail_t *btp);
-#define XFS_DIR2_BLOCK_LEAF_P(btp) \
- xfs_dir2_block_leaf_p(btp)
-#else
-#define XFS_DIR2_BLOCK_LEAF_P(btp) \
- (((struct xfs_dir2_leaf_entry *)(btp)) - INT_GET((btp)->count, ARCH_CONVERT))
-#endif
+#define XFS_DIR2_BLOCK_LEAF_P(btp) xfs_dir2_block_leaf_p(btp)
+static inline struct xfs_dir2_leaf_entry *
+xfs_dir2_block_leaf_p(xfs_dir2_block_tail_t *btp)
+{
+ return (((struct xfs_dir2_leaf_entry *)
+ (btp)) - INT_GET((btp)->count, ARCH_CONVERT));
+}
/*
* Function declarations.
*/
-
-extern int
- xfs_dir2_block_addname(struct xfs_da_args *args);
-
-extern int
- xfs_dir2_block_getdents(struct xfs_trans *tp, struct xfs_inode *dp,
- struct uio *uio, int *eofp, struct xfs_dirent *dbp,
- xfs_dir2_put_t put);
-
-extern int
- xfs_dir2_block_lookup(struct xfs_da_args *args);
-
-extern int
- xfs_dir2_block_removename(struct xfs_da_args *args);
-
-extern int
- xfs_dir2_block_replace(struct xfs_da_args *args);
-
-extern int
- xfs_dir2_leaf_to_block(struct xfs_da_args *args, struct xfs_dabuf *lbp,
- struct xfs_dabuf *dbp);
-
-extern int
- xfs_dir2_sf_to_block(struct xfs_da_args *args);
+extern int xfs_dir2_block_addname(struct xfs_da_args *args);
+extern int xfs_dir2_block_getdents(struct xfs_trans *tp, struct xfs_inode *dp,
+ struct uio *uio, int *eofp,
+ struct xfs_dirent *dbp, xfs_dir2_put_t put);
+extern int xfs_dir2_block_lookup(struct xfs_da_args *args);
+extern int xfs_dir2_block_removename(struct xfs_da_args *args);
+extern int xfs_dir2_block_replace(struct xfs_da_args *args);
+extern int xfs_dir2_leaf_to_block(struct xfs_da_args *args,
+ struct xfs_dabuf *lbp, struct xfs_dabuf *dbp);
+extern int xfs_dir2_sf_to_block(struct xfs_da_args *args);
#endif /* __XFS_DIR2_BLOCK_H__ */
diff --git a/fs/xfs/xfs_dir2_data.c b/fs/xfs/xfs_dir2_data.c
index a0aa0e44ff9d..5b7c47e2f14a 100644
--- a/fs/xfs/xfs_dir2_data.c
+++ b/fs/xfs/xfs_dir2_data.c
@@ -1,60 +1,38 @@
/*
- * Copyright (c) 2000-2002 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
- */
-
-/*
- * xfs_dir2_data.c
- * Core data block handling routines for XFS V2 directories.
- * See xfs_dir2_data.h for data structures.
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-
#include "xfs.h"
-
-#include "xfs_macros.h"
+#include "xfs_fs.h"
#include "xfs_types.h"
-#include "xfs_inum.h"
#include "xfs_log.h"
+#include "xfs_inum.h"
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_dir.h"
#include "xfs_dir2.h"
#include "xfs_dmapi.h"
#include "xfs_mount.h"
+#include "xfs_da_btree.h"
#include "xfs_bmap_btree.h"
-#include "xfs_attr_sf.h"
#include "xfs_dir_sf.h"
#include "xfs_dir2_sf.h"
+#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
#include "xfs_inode.h"
-#include "xfs_da_btree.h"
#include "xfs_dir_leaf.h"
#include "xfs_dir2_data.h"
#include "xfs_dir2_leaf.h"
diff --git a/fs/xfs/xfs_dir2_data.h b/fs/xfs/xfs_dir2_data.h
index 476cac920bf5..5e3a7f9ec735 100644
--- a/fs/xfs/xfs_dir2_data.h
+++ b/fs/xfs/xfs_dir2_data.h
@@ -1,33 +1,19 @@
/*
- * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000,2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __XFS_DIR2_DATA_H__
#define __XFS_DIR2_DATA_H__
@@ -137,88 +123,65 @@ typedef struct xfs_dir2_data {
/*
* Size of a data entry.
*/
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_DIR2_DATA_ENTSIZE)
-int xfs_dir2_data_entsize(int n);
#define XFS_DIR2_DATA_ENTSIZE(n) xfs_dir2_data_entsize(n)
-#else
-#define XFS_DIR2_DATA_ENTSIZE(n) \
- ((int)(roundup(offsetof(xfs_dir2_data_entry_t, name[0]) + (n) + \
- (uint)sizeof(xfs_dir2_data_off_t), XFS_DIR2_DATA_ALIGN)))
-#endif
+static inline int xfs_dir2_data_entsize(int n)
+{
+ return (int)roundup(offsetof(xfs_dir2_data_entry_t, name[0]) + (n) + \
+ (uint)sizeof(xfs_dir2_data_off_t), XFS_DIR2_DATA_ALIGN);
+}
/*
* Pointer to an entry's tag word.
*/
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_DIR2_DATA_ENTRY_TAG_P)
-xfs_dir2_data_off_t *xfs_dir2_data_entry_tag_p(xfs_dir2_data_entry_t *dep);
#define XFS_DIR2_DATA_ENTRY_TAG_P(dep) xfs_dir2_data_entry_tag_p(dep)
-#else
-#define XFS_DIR2_DATA_ENTRY_TAG_P(dep) \
- ((xfs_dir2_data_off_t *)\
- ((char *)(dep) + XFS_DIR2_DATA_ENTSIZE((dep)->namelen) - \
- (uint)sizeof(xfs_dir2_data_off_t)))
-#endif
+static inline xfs_dir2_data_off_t *
+xfs_dir2_data_entry_tag_p(xfs_dir2_data_entry_t *dep)
+{
+ return (xfs_dir2_data_off_t *) \
+ ((char *)(dep) + XFS_DIR2_DATA_ENTSIZE((dep)->namelen) - \
+ (uint)sizeof(xfs_dir2_data_off_t));
+}
/*
* Pointer to a freespace's tag word.
*/
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_DIR2_DATA_UNUSED_TAG_P)
-xfs_dir2_data_off_t *xfs_dir2_data_unused_tag_p(xfs_dir2_data_unused_t *dup);
#define XFS_DIR2_DATA_UNUSED_TAG_P(dup) \
xfs_dir2_data_unused_tag_p(dup)
-#else
-#define XFS_DIR2_DATA_UNUSED_TAG_P(dup) \
- ((xfs_dir2_data_off_t *)\
- ((char *)(dup) + INT_GET((dup)->length, ARCH_CONVERT) \
- - (uint)sizeof(xfs_dir2_data_off_t)))
-#endif
+static inline xfs_dir2_data_off_t *
+xfs_dir2_data_unused_tag_p(xfs_dir2_data_unused_t *dup)
+{
+ return (xfs_dir2_data_off_t *) \
+ ((char *)(dup) + INT_GET((dup)->length, ARCH_CONVERT) \
+ - (uint)sizeof(xfs_dir2_data_off_t));
+}
/*
* Function declarations.
*/
-
#ifdef DEBUG
-extern void
- xfs_dir2_data_check(struct xfs_inode *dp, struct xfs_dabuf *bp);
+extern void xfs_dir2_data_check(struct xfs_inode *dp, struct xfs_dabuf *bp);
#else
#define xfs_dir2_data_check(dp,bp)
#endif
-
-extern xfs_dir2_data_free_t *
- xfs_dir2_data_freefind(xfs_dir2_data_t *d,
- xfs_dir2_data_unused_t *dup);
-
-extern xfs_dir2_data_free_t *
- xfs_dir2_data_freeinsert(xfs_dir2_data_t *d,
- xfs_dir2_data_unused_t *dup, int *loghead);
-
-extern void
- xfs_dir2_data_freescan(struct xfs_mount *mp, xfs_dir2_data_t *d,
- int *loghead, char *aendp);
-
-extern int
- xfs_dir2_data_init(struct xfs_da_args *args, xfs_dir2_db_t blkno,
- struct xfs_dabuf **bpp);
-
-extern void
- xfs_dir2_data_log_entry(struct xfs_trans *tp, struct xfs_dabuf *bp,
+extern xfs_dir2_data_free_t *xfs_dir2_data_freefind(xfs_dir2_data_t *d,
+ xfs_dir2_data_unused_t *dup);
+extern xfs_dir2_data_free_t *xfs_dir2_data_freeinsert(xfs_dir2_data_t *d,
+ xfs_dir2_data_unused_t *dup, int *loghead);
+extern void xfs_dir2_data_freescan(struct xfs_mount *mp, xfs_dir2_data_t *d,
+ int *loghead, char *aendp);
+extern int xfs_dir2_data_init(struct xfs_da_args *args, xfs_dir2_db_t blkno,
+ struct xfs_dabuf **bpp);
+extern void xfs_dir2_data_log_entry(struct xfs_trans *tp, struct xfs_dabuf *bp,
xfs_dir2_data_entry_t *dep);
-
-extern void
- xfs_dir2_data_log_header(struct xfs_trans *tp, struct xfs_dabuf *bp);
-
-extern void
- xfs_dir2_data_log_unused(struct xfs_trans *tp, struct xfs_dabuf *bp,
- xfs_dir2_data_unused_t *dup);
-
-extern void
- xfs_dir2_data_make_free(struct xfs_trans *tp, struct xfs_dabuf *bp,
+extern void xfs_dir2_data_log_header(struct xfs_trans *tp,
+ struct xfs_dabuf *bp);
+extern void xfs_dir2_data_log_unused(struct xfs_trans *tp, struct xfs_dabuf *bp,
+ xfs_dir2_data_unused_t *dup);
+extern void xfs_dir2_data_make_free(struct xfs_trans *tp, struct xfs_dabuf *bp,
xfs_dir2_data_aoff_t offset,
xfs_dir2_data_aoff_t len, int *needlogp,
int *needscanp);
-
-extern void
- xfs_dir2_data_use_free(struct xfs_trans *tp, struct xfs_dabuf *bp,
+extern void xfs_dir2_data_use_free(struct xfs_trans *tp, struct xfs_dabuf *bp,
xfs_dir2_data_unused_t *dup,
xfs_dir2_data_aoff_t offset,
xfs_dir2_data_aoff_t len, int *needlogp,
diff --git a/fs/xfs/xfs_dir2_leaf.c b/fs/xfs/xfs_dir2_leaf.c
index 056f5283904b..d342b6b55239 100644
--- a/fs/xfs/xfs_dir2_leaf.c
+++ b/fs/xfs/xfs_dir2_leaf.c
@@ -1,49 +1,26 @@
/*
- * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
- */
-
-/*
- * xfs_dir2_leaf.c
- * XFS directory version 2 implementation - single leaf form
- * see xfs_dir2_leaf.h for data structures.
- * These directories have multiple XFS_DIR2_DATA blocks and one
- * XFS_DIR2_LEAF1 block containing the hash table and freespace map.
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-
#include "xfs.h"
-
-#include "xfs_macros.h"
+#include "xfs_fs.h"
#include "xfs_types.h"
-#include "xfs_inum.h"
+#include "xfs_bit.h"
#include "xfs_log.h"
+#include "xfs_inum.h"
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
@@ -51,6 +28,7 @@
#include "xfs_dir2.h"
#include "xfs_dmapi.h"
#include "xfs_mount.h"
+#include "xfs_da_btree.h"
#include "xfs_bmap_btree.h"
#include "xfs_attr_sf.h"
#include "xfs_dir_sf.h"
@@ -58,14 +36,12 @@
#include "xfs_dinode.h"
#include "xfs_inode.h"
#include "xfs_bmap.h"
-#include "xfs_da_btree.h"
#include "xfs_dir2_data.h"
#include "xfs_dir2_leaf.h"
#include "xfs_dir2_block.h"
#include "xfs_dir2_node.h"
#include "xfs_dir2_trace.h"
#include "xfs_error.h"
-#include "xfs_bit.h"
/*
* Local function declarations.
diff --git a/fs/xfs/xfs_dir2_leaf.h b/fs/xfs/xfs_dir2_leaf.h
index 3303cd6f4c00..1393993d61e9 100644
--- a/fs/xfs/xfs_dir2_leaf.h
+++ b/fs/xfs/xfs_dir2_leaf.h
@@ -1,41 +1,23 @@
/*
- * Copyright (c) 2000-2001 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __XFS_DIR2_LEAF_H__
#define __XFS_DIR2_LEAF_H__
-/*
- * Directory version 2, leaf block structures.
- */
-
struct uio;
struct xfs_dabuf;
struct xfs_da_args;
@@ -44,10 +26,6 @@ struct xfs_mount;
struct xfs_trans;
/*
- * Constants.
- */
-
-/*
* Offset of the leaf/node space. First block in this space
* is the btree root.
*/
@@ -57,10 +35,6 @@ struct xfs_trans;
XFS_DIR2_BYTE_TO_DB(mp, XFS_DIR2_LEAF_OFFSET)
/*
- * Types.
- */
-
-/*
* Offset in data space of a data entry.
*/
typedef __uint32_t xfs_dir2_dataptr_t;
@@ -68,10 +42,6 @@ typedef __uint32_t xfs_dir2_dataptr_t;
#define XFS_DIR2_NULL_DATAPTR ((xfs_dir2_dataptr_t)0)
/*
- * Structures.
- */
-
-/*
* Leaf block header.
*/
typedef struct xfs_dir2_leaf_hdr {
@@ -109,245 +79,193 @@ typedef struct xfs_dir2_leaf {
} xfs_dir2_leaf_t;
/*
- * Macros.
- * The DB blocks are logical directory block numbers, not filesystem blocks.
+ * DB blocks here are logical directory block numbers, not filesystem blocks.
*/
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_DIR2_MAX_LEAF_ENTS)
-int
-xfs_dir2_max_leaf_ents(struct xfs_mount *mp);
-#define XFS_DIR2_MAX_LEAF_ENTS(mp) \
- xfs_dir2_max_leaf_ents(mp)
-#else
-#define XFS_DIR2_MAX_LEAF_ENTS(mp) \
- ((int)(((mp)->m_dirblksize - (uint)sizeof(xfs_dir2_leaf_hdr_t)) / \
- (uint)sizeof(xfs_dir2_leaf_entry_t)))
-#endif
+#define XFS_DIR2_MAX_LEAF_ENTS(mp) xfs_dir2_max_leaf_ents(mp)
+static inline int xfs_dir2_max_leaf_ents(struct xfs_mount *mp)
+{
+ return (int)(((mp)->m_dirblksize - (uint)sizeof(xfs_dir2_leaf_hdr_t)) /
+ (uint)sizeof(xfs_dir2_leaf_entry_t));
+}
/*
* Get address of the bestcount field in the single-leaf block.
*/
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_DIR2_LEAF_TAIL_P)
-xfs_dir2_leaf_tail_t *
-xfs_dir2_leaf_tail_p(struct xfs_mount *mp, xfs_dir2_leaf_t *lp);
-#define XFS_DIR2_LEAF_TAIL_P(mp,lp) \
- xfs_dir2_leaf_tail_p(mp, lp)
-#else
-#define XFS_DIR2_LEAF_TAIL_P(mp,lp) \
- ((xfs_dir2_leaf_tail_t *)\
- ((char *)(lp) + (mp)->m_dirblksize - \
- (uint)sizeof(xfs_dir2_leaf_tail_t)))
-#endif
+#define XFS_DIR2_LEAF_TAIL_P(mp,lp) xfs_dir2_leaf_tail_p(mp, lp)
+static inline xfs_dir2_leaf_tail_t *
+xfs_dir2_leaf_tail_p(struct xfs_mount *mp, xfs_dir2_leaf_t *lp)
+{
+ return (xfs_dir2_leaf_tail_t *)
+ ((char *)(lp) + (mp)->m_dirblksize -
+ (uint)sizeof(xfs_dir2_leaf_tail_t));
+}
/*
* Get address of the bests array in the single-leaf block.
*/
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_DIR2_LEAF_BESTS_P)
-xfs_dir2_data_off_t *
-xfs_dir2_leaf_bests_p(xfs_dir2_leaf_tail_t *ltp);
#define XFS_DIR2_LEAF_BESTS_P(ltp) xfs_dir2_leaf_bests_p(ltp)
-#else
-#define XFS_DIR2_LEAF_BESTS_P(ltp) \
- ((xfs_dir2_data_off_t *)(ltp) - INT_GET((ltp)->bestcount, ARCH_CONVERT))
-#endif
+static inline xfs_dir2_data_off_t *
+xfs_dir2_leaf_bests_p(xfs_dir2_leaf_tail_t *ltp)
+{
+ return (xfs_dir2_data_off_t *)
+ (ltp) - INT_GET((ltp)->bestcount, ARCH_CONVERT);
+}
/*
* Convert dataptr to byte in file space
*/
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_DIR2_DATAPTR_TO_BYTE)
-xfs_dir2_off_t
-xfs_dir2_dataptr_to_byte(struct xfs_mount *mp, xfs_dir2_dataptr_t dp);
#define XFS_DIR2_DATAPTR_TO_BYTE(mp,dp) xfs_dir2_dataptr_to_byte(mp, dp)
-#else
-#define XFS_DIR2_DATAPTR_TO_BYTE(mp,dp) \
- ((xfs_dir2_off_t)(dp) << XFS_DIR2_DATA_ALIGN_LOG)
-#endif
+static inline xfs_dir2_off_t
+xfs_dir2_dataptr_to_byte(struct xfs_mount *mp, xfs_dir2_dataptr_t dp)
+{
+ return (xfs_dir2_off_t)(dp) << XFS_DIR2_DATA_ALIGN_LOG;
+}
/*
* Convert byte in file space to dataptr. It had better be aligned.
*/
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_DIR2_BYTE_TO_DATAPTR)
-xfs_dir2_dataptr_t
-xfs_dir2_byte_to_dataptr(struct xfs_mount *mp, xfs_dir2_off_t by);
#define XFS_DIR2_BYTE_TO_DATAPTR(mp,by) xfs_dir2_byte_to_dataptr(mp,by)
-#else
-#define XFS_DIR2_BYTE_TO_DATAPTR(mp,by) \
- ((xfs_dir2_dataptr_t)((by) >> XFS_DIR2_DATA_ALIGN_LOG))
-#endif
+static inline xfs_dir2_dataptr_t
+xfs_dir2_byte_to_dataptr(struct xfs_mount *mp, xfs_dir2_off_t by)
+{
+ return (xfs_dir2_dataptr_t)((by) >> XFS_DIR2_DATA_ALIGN_LOG);
+}
+
+/*
+ * Convert byte in space to (DB) block
+ */
+#define XFS_DIR2_BYTE_TO_DB(mp,by) xfs_dir2_byte_to_db(mp, by)
+static inline xfs_dir2_db_t
+xfs_dir2_byte_to_db(struct xfs_mount *mp, xfs_dir2_off_t by)
+{
+ return (xfs_dir2_db_t)((by) >> \
+ ((mp)->m_sb.sb_blocklog + (mp)->m_sb.sb_dirblklog));
+}
/*
* Convert dataptr to a block number
*/
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_DIR2_DATAPTR_TO_DB)
-xfs_dir2_db_t
-xfs_dir2_dataptr_to_db(struct xfs_mount *mp, xfs_dir2_dataptr_t dp);
#define XFS_DIR2_DATAPTR_TO_DB(mp,dp) xfs_dir2_dataptr_to_db(mp, dp)
-#else
-#define XFS_DIR2_DATAPTR_TO_DB(mp,dp) \
- XFS_DIR2_BYTE_TO_DB(mp, XFS_DIR2_DATAPTR_TO_BYTE(mp, dp))
-#endif
+static inline xfs_dir2_db_t
+xfs_dir2_dataptr_to_db(struct xfs_mount *mp, xfs_dir2_dataptr_t dp)
+{
+ return XFS_DIR2_BYTE_TO_DB(mp, XFS_DIR2_DATAPTR_TO_BYTE(mp, dp));
+}
+
+/*
+ * Convert byte in space to offset in a block
+ */
+#define XFS_DIR2_BYTE_TO_OFF(mp,by) xfs_dir2_byte_to_off(mp, by)
+static inline xfs_dir2_data_aoff_t
+xfs_dir2_byte_to_off(struct xfs_mount *mp, xfs_dir2_off_t by)
+{
+ return (xfs_dir2_data_aoff_t)((by) & \
+ ((1 << ((mp)->m_sb.sb_blocklog + (mp)->m_sb.sb_dirblklog)) - 1));
+}
/*
* Convert dataptr to a byte offset in a block
*/
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_DIR2_DATAPTR_TO_OFF)
-xfs_dir2_data_aoff_t
-xfs_dir2_dataptr_to_off(struct xfs_mount *mp, xfs_dir2_dataptr_t dp);
#define XFS_DIR2_DATAPTR_TO_OFF(mp,dp) xfs_dir2_dataptr_to_off(mp, dp)
-#else
-#define XFS_DIR2_DATAPTR_TO_OFF(mp,dp) \
- XFS_DIR2_BYTE_TO_OFF(mp, XFS_DIR2_DATAPTR_TO_BYTE(mp, dp))
-#endif
+static inline xfs_dir2_data_aoff_t
+xfs_dir2_dataptr_to_off(struct xfs_mount *mp, xfs_dir2_dataptr_t dp)
+{
+ return XFS_DIR2_BYTE_TO_OFF(mp, XFS_DIR2_DATAPTR_TO_BYTE(mp, dp));
+}
/*
* Convert block and offset to byte in space
*/
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_DIR2_DB_OFF_TO_BYTE)
-xfs_dir2_off_t
-xfs_dir2_db_off_to_byte(struct xfs_mount *mp, xfs_dir2_db_t db,
- xfs_dir2_data_aoff_t o);
#define XFS_DIR2_DB_OFF_TO_BYTE(mp,db,o) \
xfs_dir2_db_off_to_byte(mp, db, o)
-#else
-#define XFS_DIR2_DB_OFF_TO_BYTE(mp,db,o) \
- (((xfs_dir2_off_t)(db) << \
- ((mp)->m_sb.sb_blocklog + (mp)->m_sb.sb_dirblklog)) + (o))
-#endif
+static inline xfs_dir2_off_t
+xfs_dir2_db_off_to_byte(struct xfs_mount *mp, xfs_dir2_db_t db,
+ xfs_dir2_data_aoff_t o)
+{
+ return ((xfs_dir2_off_t)(db) << \
+ ((mp)->m_sb.sb_blocklog + (mp)->m_sb.sb_dirblklog)) + (o);
+}
/*
- * Convert byte in space to (DB) block
+ * Convert block (DB) to block (dablk)
*/
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_DIR2_BYTE_TO_DB)
-xfs_dir2_db_t xfs_dir2_byte_to_db(struct xfs_mount *mp, xfs_dir2_off_t by);
-#define XFS_DIR2_BYTE_TO_DB(mp,by) xfs_dir2_byte_to_db(mp, by)
-#else
-#define XFS_DIR2_BYTE_TO_DB(mp,by) \
- ((xfs_dir2_db_t)((by) >> \
- ((mp)->m_sb.sb_blocklog + (mp)->m_sb.sb_dirblklog)))
-#endif
+#define XFS_DIR2_DB_TO_DA(mp,db) xfs_dir2_db_to_da(mp, db)
+static inline xfs_dablk_t
+xfs_dir2_db_to_da(struct xfs_mount *mp, xfs_dir2_db_t db)
+{
+ return (xfs_dablk_t)((db) << (mp)->m_sb.sb_dirblklog);
+}
/*
* Convert byte in space to (DA) block
*/
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_DIR2_BYTE_TO_DA)
-xfs_dablk_t xfs_dir2_byte_to_da(struct xfs_mount *mp, xfs_dir2_off_t by);
#define XFS_DIR2_BYTE_TO_DA(mp,by) xfs_dir2_byte_to_da(mp, by)
-#else
-#define XFS_DIR2_BYTE_TO_DA(mp,by) \
- XFS_DIR2_DB_TO_DA(mp, XFS_DIR2_BYTE_TO_DB(mp, by))
-#endif
-
-/*
- * Convert byte in space to offset in a block
- */
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_DIR2_BYTE_TO_OFF)
-xfs_dir2_data_aoff_t
-xfs_dir2_byte_to_off(struct xfs_mount *mp, xfs_dir2_off_t by);
-#define XFS_DIR2_BYTE_TO_OFF(mp,by) xfs_dir2_byte_to_off(mp, by)
-#else
-#define XFS_DIR2_BYTE_TO_OFF(mp,by) \
- ((xfs_dir2_data_aoff_t)((by) & \
- ((1 << ((mp)->m_sb.sb_blocklog + \
- (mp)->m_sb.sb_dirblklog)) - 1)))
-#endif
+static inline xfs_dablk_t
+xfs_dir2_byte_to_da(struct xfs_mount *mp, xfs_dir2_off_t by)
+{
+ return XFS_DIR2_DB_TO_DA(mp, XFS_DIR2_BYTE_TO_DB(mp, by));
+}
/*
* Convert block and offset to dataptr
*/
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_DIR2_DB_OFF_TO_DATAPTR)
-xfs_dir2_dataptr_t
-xfs_dir2_db_off_to_dataptr(struct xfs_mount *mp, xfs_dir2_db_t db,
- xfs_dir2_data_aoff_t o);
#define XFS_DIR2_DB_OFF_TO_DATAPTR(mp,db,o) \
xfs_dir2_db_off_to_dataptr(mp, db, o)
-#else
-#define XFS_DIR2_DB_OFF_TO_DATAPTR(mp,db,o) \
- XFS_DIR2_BYTE_TO_DATAPTR(mp, XFS_DIR2_DB_OFF_TO_BYTE(mp, db, o))
-#endif
-
-/*
- * Convert block (DB) to block (dablk)
- */
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_DIR2_DB_TO_DA)
-xfs_dablk_t xfs_dir2_db_to_da(struct xfs_mount *mp, xfs_dir2_db_t db);
-#define XFS_DIR2_DB_TO_DA(mp,db) xfs_dir2_db_to_da(mp, db)
-#else
-#define XFS_DIR2_DB_TO_DA(mp,db) \
- ((xfs_dablk_t)((db) << (mp)->m_sb.sb_dirblklog))
-#endif
+static inline xfs_dir2_dataptr_t
+xfs_dir2_db_off_to_dataptr(struct xfs_mount *mp, xfs_dir2_db_t db,
+ xfs_dir2_data_aoff_t o)
+{
+ return XFS_DIR2_BYTE_TO_DATAPTR(mp, XFS_DIR2_DB_OFF_TO_BYTE(mp, db, o));
+}
/*
* Convert block (dablk) to block (DB)
*/
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_DIR2_DA_TO_DB)
-xfs_dir2_db_t xfs_dir2_da_to_db(struct xfs_mount *mp, xfs_dablk_t da);
#define XFS_DIR2_DA_TO_DB(mp,da) xfs_dir2_da_to_db(mp, da)
-#else
-#define XFS_DIR2_DA_TO_DB(mp,da) \
- ((xfs_dir2_db_t)((da) >> (mp)->m_sb.sb_dirblklog))
-#endif
+static inline xfs_dir2_db_t
+xfs_dir2_da_to_db(struct xfs_mount *mp, xfs_dablk_t da)
+{
+ return (xfs_dir2_db_t)((da) >> (mp)->m_sb.sb_dirblklog);
+}
/*
* Convert block (dablk) to byte offset in space
*/
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_DIR2_DA_TO_BYTE)
-xfs_dir2_off_t xfs_dir2_da_to_byte(struct xfs_mount *mp, xfs_dablk_t da);
#define XFS_DIR2_DA_TO_BYTE(mp,da) xfs_dir2_da_to_byte(mp, da)
-#else
-#define XFS_DIR2_DA_TO_BYTE(mp,da) \
- XFS_DIR2_DB_OFF_TO_BYTE(mp, XFS_DIR2_DA_TO_DB(mp, da), 0)
-#endif
+static inline xfs_dir2_off_t
+xfs_dir2_da_to_byte(struct xfs_mount *mp, xfs_dablk_t da)
+{
+ return XFS_DIR2_DB_OFF_TO_BYTE(mp, XFS_DIR2_DA_TO_DB(mp, da), 0);
+}
/*
* Function declarations.
*/
-
-extern int
- xfs_dir2_block_to_leaf(struct xfs_da_args *args, struct xfs_dabuf *dbp);
-
-extern int
- xfs_dir2_leaf_addname(struct xfs_da_args *args);
-
-extern void
- xfs_dir2_leaf_compact(struct xfs_da_args *args, struct xfs_dabuf *bp);
-
-extern void
- xfs_dir2_leaf_compact_x1(struct xfs_dabuf *bp, int *indexp,
- int *lowstalep, int *highstalep, int *lowlogp,
- int *highlogp);
-
-extern int
- xfs_dir2_leaf_getdents(struct xfs_trans *tp, struct xfs_inode *dp,
- struct uio *uio, int *eofp, struct xfs_dirent *dbp,
- xfs_dir2_put_t put);
-
-extern int
- xfs_dir2_leaf_init(struct xfs_da_args *args, xfs_dir2_db_t bno,
- struct xfs_dabuf **bpp, int magic);
-
-extern void
- xfs_dir2_leaf_log_ents(struct xfs_trans *tp, struct xfs_dabuf *bp,
- int first, int last);
-
-extern void
- xfs_dir2_leaf_log_header(struct xfs_trans *tp, struct xfs_dabuf *bp);
-
-extern int
- xfs_dir2_leaf_lookup(struct xfs_da_args *args);
-
-extern int
- xfs_dir2_leaf_removename(struct xfs_da_args *args);
-
-extern int
- xfs_dir2_leaf_replace(struct xfs_da_args *args);
-
-extern int
- xfs_dir2_leaf_search_hash(struct xfs_da_args *args,
- struct xfs_dabuf *lbp);
-extern int
- xfs_dir2_leaf_trim_data(struct xfs_da_args *args, struct xfs_dabuf *lbp, xfs_dir2_db_t db);
-
-extern int
- xfs_dir2_node_to_leaf(struct xfs_da_state *state);
+extern int xfs_dir2_block_to_leaf(struct xfs_da_args *args,
+ struct xfs_dabuf *dbp);
+extern int xfs_dir2_leaf_addname(struct xfs_da_args *args);
+extern void xfs_dir2_leaf_compact(struct xfs_da_args *args,
+ struct xfs_dabuf *bp);
+extern void xfs_dir2_leaf_compact_x1(struct xfs_dabuf *bp, int *indexp,
+ int *lowstalep, int *highstalep,
+ int *lowlogp, int *highlogp);
+extern int xfs_dir2_leaf_getdents(struct xfs_trans *tp, struct xfs_inode *dp,
+ struct uio *uio, int *eofp,
+ struct xfs_dirent *dbp, xfs_dir2_put_t put);
+extern int xfs_dir2_leaf_init(struct xfs_da_args *args, xfs_dir2_db_t bno,
+ struct xfs_dabuf **bpp, int magic);
+extern void xfs_dir2_leaf_log_ents(struct xfs_trans *tp, struct xfs_dabuf *bp,
+ int first, int last);
+extern void xfs_dir2_leaf_log_header(struct xfs_trans *tp,
+ struct xfs_dabuf *bp);
+extern int xfs_dir2_leaf_lookup(struct xfs_da_args *args);
+extern int xfs_dir2_leaf_removename(struct xfs_da_args *args);
+extern int xfs_dir2_leaf_replace(struct xfs_da_args *args);
+extern int xfs_dir2_leaf_search_hash(struct xfs_da_args *args,
+ struct xfs_dabuf *lbp);
+extern int xfs_dir2_leaf_trim_data(struct xfs_da_args *args,
+ struct xfs_dabuf *lbp, xfs_dir2_db_t db);
+extern int xfs_dir2_node_to_leaf(struct xfs_da_state *state);
#endif /* __XFS_DIR2_LEAF_H__ */
diff --git a/fs/xfs/xfs_dir2_node.c b/fs/xfs/xfs_dir2_node.c
index a7615d86bfb7..641f8633d254 100644
--- a/fs/xfs/xfs_dir2_node.c
+++ b/fs/xfs/xfs_dir2_node.c
@@ -1,61 +1,39 @@
/*
- * Copyright (c) 2000-2004 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
- */
-
-/*
- * xfs_dir2_node.c
- * XFS directory implementation, version 2, node form files
- * See data structures in xfs_dir2_node.h and xfs_da_btree.h.
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-
#include "xfs.h"
-
-#include "xfs_macros.h"
+#include "xfs_fs.h"
#include "xfs_types.h"
-#include "xfs_inum.h"
#include "xfs_log.h"
+#include "xfs_inum.h"
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_dir.h"
#include "xfs_dir2.h"
#include "xfs_dmapi.h"
#include "xfs_mount.h"
+#include "xfs_da_btree.h"
#include "xfs_bmap_btree.h"
-#include "xfs_attr_sf.h"
#include "xfs_dir_sf.h"
#include "xfs_dir2_sf.h"
+#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
#include "xfs_inode.h"
#include "xfs_bmap.h"
-#include "xfs_da_btree.h"
#include "xfs_dir2_data.h"
#include "xfs_dir2_leaf.h"
#include "xfs_dir2_block.h"
diff --git a/fs/xfs/xfs_dir2_node.h b/fs/xfs/xfs_dir2_node.h
index 96db420c7c5c..0ab8fbd59512 100644
--- a/fs/xfs/xfs_dir2_node.h
+++ b/fs/xfs/xfs_dir2_node.h
@@ -1,33 +1,19 @@
/*
- * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000,2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __XFS_DIR2_NODE_H__
#define __XFS_DIR2_NODE_H__
@@ -45,10 +31,6 @@ struct xfs_inode;
struct xfs_trans;
/*
- * Constants.
- */
-
-/*
* Offset of the freespace index.
*/
#define XFS_DIR2_FREE_SPACE 2
@@ -58,9 +40,6 @@ struct xfs_trans;
#define XFS_DIR2_FREE_MAGIC 0x58443246 /* XD2F */
-/*
- * Structures.
- */
typedef struct xfs_dir2_free_hdr {
__uint32_t magic; /* XFS_DIR2_FREE_MAGIC */
__int32_t firstdb; /* db of first entry */
@@ -73,87 +52,53 @@ typedef struct xfs_dir2_free {
xfs_dir2_data_off_t bests[1]; /* best free counts */
/* unused entries are -1 */
} xfs_dir2_free_t;
+
#define XFS_DIR2_MAX_FREE_BESTS(mp) \
(((mp)->m_dirblksize - (uint)sizeof(xfs_dir2_free_hdr_t)) / \
(uint)sizeof(xfs_dir2_data_off_t))
/*
- * Macros.
- */
-
-/*
* Convert data space db to the corresponding free db.
*/
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_DIR2_DB_TO_FDB)
-xfs_dir2_db_t
-xfs_dir2_db_to_fdb(struct xfs_mount *mp, xfs_dir2_db_t db);
#define XFS_DIR2_DB_TO_FDB(mp,db) xfs_dir2_db_to_fdb(mp, db)
-#else
-#define XFS_DIR2_DB_TO_FDB(mp,db) \
- (XFS_DIR2_FREE_FIRSTDB(mp) + (db) / XFS_DIR2_MAX_FREE_BESTS(mp))
-#endif
+static inline xfs_dir2_db_t
+xfs_dir2_db_to_fdb(struct xfs_mount *mp, xfs_dir2_db_t db)
+{
+ return (XFS_DIR2_FREE_FIRSTDB(mp) + (db) / XFS_DIR2_MAX_FREE_BESTS(mp));
+}
/*
* Convert data space db to the corresponding index in a free db.
*/
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_DIR2_DB_TO_FDINDEX)
-int
-xfs_dir2_db_to_fdindex(struct xfs_mount *mp, xfs_dir2_db_t db);
#define XFS_DIR2_DB_TO_FDINDEX(mp,db) xfs_dir2_db_to_fdindex(mp, db)
-#else
-#define XFS_DIR2_DB_TO_FDINDEX(mp,db) ((db) % XFS_DIR2_MAX_FREE_BESTS(mp))
-#endif
-
-/*
- * Functions.
- */
-
-extern void
- xfs_dir2_free_log_bests(struct xfs_trans *tp, struct xfs_dabuf *bp,
- int first, int last);
-
-extern int
- xfs_dir2_leaf_to_node(struct xfs_da_args *args, struct xfs_dabuf *lbp);
-
-extern xfs_dahash_t
- xfs_dir2_leafn_lasthash(struct xfs_dabuf *bp, int *count);
-
-extern int
- xfs_dir2_leafn_lookup_int(struct xfs_dabuf *bp,
- struct xfs_da_args *args, int *indexp,
- struct xfs_da_state *state);
-
-extern int
- xfs_dir2_leafn_order(struct xfs_dabuf *leaf1_bp,
- struct xfs_dabuf *leaf2_bp);
-
-extern int
- xfs_dir2_leafn_split(struct xfs_da_state *state,
- struct xfs_da_state_blk *oldblk,
- struct xfs_da_state_blk *newblk);
-
-extern int
- xfs_dir2_leafn_toosmall(struct xfs_da_state *state, int *action);
-
-extern void
- xfs_dir2_leafn_unbalance(struct xfs_da_state *state,
- struct xfs_da_state_blk *drop_blk,
- struct xfs_da_state_blk *save_blk);
-
-extern int
- xfs_dir2_node_addname(struct xfs_da_args *args);
-
-extern int
- xfs_dir2_node_lookup(struct xfs_da_args *args);
-
-extern int
- xfs_dir2_node_removename(struct xfs_da_args *args);
-
-extern int
- xfs_dir2_node_replace(struct xfs_da_args *args);
-
-extern int
- xfs_dir2_node_trim_free(struct xfs_da_args *args, xfs_fileoff_t fo,
- int *rvalp);
+static inline int
+xfs_dir2_db_to_fdindex(struct xfs_mount *mp, xfs_dir2_db_t db)
+{
+ return ((db) % XFS_DIR2_MAX_FREE_BESTS(mp));
+}
+
+extern void xfs_dir2_free_log_bests(struct xfs_trans *tp, struct xfs_dabuf *bp,
+ int first, int last);
+extern int xfs_dir2_leaf_to_node(struct xfs_da_args *args,
+ struct xfs_dabuf *lbp);
+extern xfs_dahash_t xfs_dir2_leafn_lasthash(struct xfs_dabuf *bp, int *count);
+extern int xfs_dir2_leafn_lookup_int(struct xfs_dabuf *bp,
+ struct xfs_da_args *args, int *indexp,
+ struct xfs_da_state *state);
+extern int xfs_dir2_leafn_order(struct xfs_dabuf *leaf1_bp,
+ struct xfs_dabuf *leaf2_bp);
+extern int xfs_dir2_leafn_split(struct xfs_da_state *state,
+ struct xfs_da_state_blk *oldblk,
+ struct xfs_da_state_blk *newblk);
+extern int xfs_dir2_leafn_toosmall(struct xfs_da_state *state, int *action);
+extern void xfs_dir2_leafn_unbalance(struct xfs_da_state *state,
+ struct xfs_da_state_blk *drop_blk,
+ struct xfs_da_state_blk *save_blk);
+extern int xfs_dir2_node_addname(struct xfs_da_args *args);
+extern int xfs_dir2_node_lookup(struct xfs_da_args *args);
+extern int xfs_dir2_node_removename(struct xfs_da_args *args);
+extern int xfs_dir2_node_replace(struct xfs_da_args *args);
+extern int xfs_dir2_node_trim_free(struct xfs_da_args *args, xfs_fileoff_t fo,
+ int *rvalp);
#endif /* __XFS_DIR2_NODE_H__ */
diff --git a/fs/xfs/xfs_dir2_sf.c b/fs/xfs/xfs_dir2_sf.c
index 6bbc61674411..ec8e7476c8b7 100644
--- a/fs/xfs/xfs_dir2_sf.c
+++ b/fs/xfs/xfs_dir2_sf.c
@@ -1,60 +1,39 @@
/*
- * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-
-/*
- * xfs_dir2_sf.c
- * Shortform directory implementation for v2 directories.
- */
-
#include "xfs.h"
-
-#include "xfs_macros.h"
+#include "xfs_fs.h"
#include "xfs_types.h"
-#include "xfs_inum.h"
#include "xfs_log.h"
+#include "xfs_inum.h"
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_dir.h"
#include "xfs_dir2.h"
#include "xfs_dmapi.h"
#include "xfs_mount.h"
+#include "xfs_da_btree.h"
#include "xfs_bmap_btree.h"
-#include "xfs_attr_sf.h"
#include "xfs_dir_sf.h"
#include "xfs_dir2_sf.h"
+#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
-#include "xfs_inode_item.h"
#include "xfs_inode.h"
-#include "xfs_da_btree.h"
+#include "xfs_inode_item.h"
#include "xfs_dir_leaf.h"
#include "xfs_error.h"
#include "xfs_dir2_data.h"
@@ -107,7 +86,7 @@ xfs_dir2_block_sfsize(
int isdotdot; /* entry is ".." */
xfs_mount_t *mp; /* mount structure pointer */
int namelen; /* total name bytes */
- xfs_ino_t parent; /* parent inode number */
+ xfs_ino_t parent = 0; /* parent inode number */
int size=0; /* total computed size */
mp = dp->i_mount;
@@ -298,11 +277,11 @@ xfs_dir2_sf_addname(
int incr_isize; /* total change in size */
int new_isize; /* di_size after adding name */
int objchange; /* changing to 8-byte inodes */
- xfs_dir2_data_aoff_t offset; /* offset for new entry */
+ xfs_dir2_data_aoff_t offset = 0; /* offset for new entry */
int old_isize; /* di_size before adding name */
int pick; /* which algorithm to use */
xfs_dir2_sf_t *sfp; /* shortform structure */
- xfs_dir2_sf_entry_t *sfep; /* shortform entry */
+ xfs_dir2_sf_entry_t *sfep = NULL; /* shortform entry */
xfs_dir2_trace_args("sf_addname", args);
ASSERT(xfs_dir2_sf_lookup(args) == ENOENT);
diff --git a/fs/xfs/xfs_dir2_sf.h b/fs/xfs/xfs_dir2_sf.h
index bac6f5a2a312..42f015b70018 100644
--- a/fs/xfs/xfs_dir2_sf.h
+++ b/fs/xfs/xfs_dir2_sf.h
@@ -1,33 +1,19 @@
/*
- * Copyright (c) 2000-2001 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __XFS_DIR2_SF_H__
#define __XFS_DIR2_SF_H__
@@ -104,140 +90,106 @@ typedef struct xfs_dir2_sf {
xfs_dir2_sf_entry_t list[1]; /* shortform entries */
} xfs_dir2_sf_t;
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_DIR2_SF_HDR_SIZE)
-int xfs_dir2_sf_hdr_size(int i8count);
#define XFS_DIR2_SF_HDR_SIZE(i8count) xfs_dir2_sf_hdr_size(i8count)
-#else
-#define XFS_DIR2_SF_HDR_SIZE(i8count) \
- ((uint)sizeof(xfs_dir2_sf_hdr_t) - \
- ((i8count) == 0) * \
- ((uint)sizeof(xfs_dir2_ino8_t) - (uint)sizeof(xfs_dir2_ino4_t)))
-#endif
-
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_DIR2_SF_INUMBERP)
-xfs_dir2_inou_t *xfs_dir2_sf_inumberp(xfs_dir2_sf_entry_t *sfep);
+static inline int xfs_dir2_sf_hdr_size(int i8count)
+{
+ return ((uint)sizeof(xfs_dir2_sf_hdr_t) - \
+ ((i8count) == 0) * \
+ ((uint)sizeof(xfs_dir2_ino8_t) - (uint)sizeof(xfs_dir2_ino4_t)));
+}
+
#define XFS_DIR2_SF_INUMBERP(sfep) xfs_dir2_sf_inumberp(sfep)
-#else
-#define XFS_DIR2_SF_INUMBERP(sfep) \
- ((xfs_dir2_inou_t *)&(sfep)->name[(sfep)->namelen])
-#endif
-
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_DIR2_SF_GET_INUMBER)
-xfs_intino_t xfs_dir2_sf_get_inumber(xfs_dir2_sf_t *sfp, xfs_dir2_inou_t *from);
-#define XFS_DIR2_SF_GET_INUMBER(sfp, from) \
- xfs_dir2_sf_get_inumber(sfp, from)
+static inline xfs_dir2_inou_t *xfs_dir2_sf_inumberp(xfs_dir2_sf_entry_t *sfep)
+{
+ return (xfs_dir2_inou_t *)&(sfep)->name[(sfep)->namelen];
+}
-#else
-#define XFS_DIR2_SF_GET_INUMBER(sfp, from) \
- ((sfp)->hdr.i8count == 0 ? \
+#define XFS_DIR2_SF_GET_INUMBER(sfp, from) \
+ xfs_dir2_sf_get_inumber(sfp, from)
+static inline xfs_intino_t
+xfs_dir2_sf_get_inumber(xfs_dir2_sf_t *sfp, xfs_dir2_inou_t *from)
+{
+ return ((sfp)->hdr.i8count == 0 ? \
(xfs_intino_t)XFS_GET_DIR_INO4((from)->i4) : \
- (xfs_intino_t)XFS_GET_DIR_INO8((from)->i8))
-#endif
+ (xfs_intino_t)XFS_GET_DIR_INO8((from)->i8));
+}
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_DIR2_SF_PUT_INUMBER)
-void xfs_dir2_sf_put_inumber(xfs_dir2_sf_t *sfp, xfs_ino_t *from,
- xfs_dir2_inou_t *to);
-#define XFS_DIR2_SF_PUT_INUMBER(sfp,from,to) \
+#define XFS_DIR2_SF_PUT_INUMBER(sfp,from,to) \
xfs_dir2_sf_put_inumber(sfp,from,to)
-#else
-#define XFS_DIR2_SF_PUT_INUMBER(sfp,from,to) \
- if ((sfp)->hdr.i8count == 0) { \
- XFS_PUT_DIR_INO4(*(from), (to)->i4); \
- } else { \
- XFS_PUT_DIR_INO8(*(from), (to)->i8); \
- }
-#endif
-
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_DIR2_SF_GET_OFFSET)
-xfs_dir2_data_aoff_t xfs_dir2_sf_get_offset(xfs_dir2_sf_entry_t *sfep);
+static inline void xfs_dir2_sf_put_inumber(xfs_dir2_sf_t *sfp, xfs_ino_t *from,
+ xfs_dir2_inou_t *to)
+{
+ if ((sfp)->hdr.i8count == 0)
+ XFS_PUT_DIR_INO4(*(from), (to)->i4);
+ else
+ XFS_PUT_DIR_INO8(*(from), (to)->i8);
+}
+
#define XFS_DIR2_SF_GET_OFFSET(sfep) \
xfs_dir2_sf_get_offset(sfep)
-#else
-#define XFS_DIR2_SF_GET_OFFSET(sfep) \
- INT_GET_UNALIGNED_16_BE(&(sfep)->offset.i)
-#endif
+static inline xfs_dir2_data_aoff_t
+xfs_dir2_sf_get_offset(xfs_dir2_sf_entry_t *sfep)
+{
+ return INT_GET_UNALIGNED_16_BE(&(sfep)->offset.i);
+}
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_DIR2_SF_PUT_OFFSET)
-void xfs_dir2_sf_put_offset(xfs_dir2_sf_entry_t *sfep,
- xfs_dir2_data_aoff_t off);
#define XFS_DIR2_SF_PUT_OFFSET(sfep,off) \
xfs_dir2_sf_put_offset(sfep,off)
-#else
-#define XFS_DIR2_SF_PUT_OFFSET(sfep,off) \
- INT_SET_UNALIGNED_16_BE(&(sfep)->offset.i,off)
-#endif
+static inline void
+xfs_dir2_sf_put_offset(xfs_dir2_sf_entry_t *sfep, xfs_dir2_data_aoff_t off)
+{
+ INT_SET_UNALIGNED_16_BE(&(sfep)->offset.i, off);
+}
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_DIR2_SF_ENTSIZE_BYNAME)
-int xfs_dir2_sf_entsize_byname(xfs_dir2_sf_t *sfp, int len);
#define XFS_DIR2_SF_ENTSIZE_BYNAME(sfp,len) \
xfs_dir2_sf_entsize_byname(sfp,len)
-#else
-#define XFS_DIR2_SF_ENTSIZE_BYNAME(sfp,len) /* space a name uses */ \
- ((uint)sizeof(xfs_dir2_sf_entry_t) - 1 + (len) - \
- ((sfp)->hdr.i8count == 0) * \
- ((uint)sizeof(xfs_dir2_ino8_t) - (uint)sizeof(xfs_dir2_ino4_t)))
-#endif
-
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_DIR2_SF_ENTSIZE_BYENTRY)
-int xfs_dir2_sf_entsize_byentry(xfs_dir2_sf_t *sfp, xfs_dir2_sf_entry_t *sfep);
+static inline int xfs_dir2_sf_entsize_byname(xfs_dir2_sf_t *sfp, int len)
+{
+ return ((uint)sizeof(xfs_dir2_sf_entry_t) - 1 + (len) - \
+ ((sfp)->hdr.i8count == 0) * \
+ ((uint)sizeof(xfs_dir2_ino8_t) - (uint)sizeof(xfs_dir2_ino4_t)));
+}
+
#define XFS_DIR2_SF_ENTSIZE_BYENTRY(sfp,sfep) \
xfs_dir2_sf_entsize_byentry(sfp,sfep)
-#else
-#define XFS_DIR2_SF_ENTSIZE_BYENTRY(sfp,sfep) /* space an entry uses */ \
- ((uint)sizeof(xfs_dir2_sf_entry_t) - 1 + (sfep)->namelen - \
- ((sfp)->hdr.i8count == 0) * \
- ((uint)sizeof(xfs_dir2_ino8_t) - (uint)sizeof(xfs_dir2_ino4_t)))
-#endif
-
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_DIR2_SF_FIRSTENTRY)
-xfs_dir2_sf_entry_t *xfs_dir2_sf_firstentry(xfs_dir2_sf_t *sfp);
+static inline int
+xfs_dir2_sf_entsize_byentry(xfs_dir2_sf_t *sfp, xfs_dir2_sf_entry_t *sfep)
+{
+ return ((uint)sizeof(xfs_dir2_sf_entry_t) - 1 + (sfep)->namelen - \
+ ((sfp)->hdr.i8count == 0) * \
+ ((uint)sizeof(xfs_dir2_ino8_t) - (uint)sizeof(xfs_dir2_ino4_t)));
+}
+
#define XFS_DIR2_SF_FIRSTENTRY(sfp) xfs_dir2_sf_firstentry(sfp)
-#else
-#define XFS_DIR2_SF_FIRSTENTRY(sfp) /* first entry in struct */ \
- ((xfs_dir2_sf_entry_t *) \
- ((char *)(sfp) + XFS_DIR2_SF_HDR_SIZE(sfp->hdr.i8count)))
-#endif
-
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_DIR2_SF_NEXTENTRY)
-xfs_dir2_sf_entry_t *xfs_dir2_sf_nextentry(xfs_dir2_sf_t *sfp,
- xfs_dir2_sf_entry_t *sfep);
-#define XFS_DIR2_SF_NEXTENTRY(sfp,sfep) xfs_dir2_sf_nextentry(sfp,sfep)
-#else
-#define XFS_DIR2_SF_NEXTENTRY(sfp,sfep) /* next entry in struct */ \
- ((xfs_dir2_sf_entry_t *) \
- ((char *)(sfep) + XFS_DIR2_SF_ENTSIZE_BYENTRY(sfp,sfep)))
-#endif
+static inline xfs_dir2_sf_entry_t *xfs_dir2_sf_firstentry(xfs_dir2_sf_t *sfp)
+{
+ return ((xfs_dir2_sf_entry_t *) \
+ ((char *)(sfp) + XFS_DIR2_SF_HDR_SIZE(sfp->hdr.i8count)));
+}
+
+#define XFS_DIR2_SF_NEXTENTRY(sfp,sfep) xfs_dir2_sf_nextentry(sfp,sfep)
+static inline xfs_dir2_sf_entry_t *
+xfs_dir2_sf_nextentry(xfs_dir2_sf_t *sfp, xfs_dir2_sf_entry_t *sfep)
+{
+ return ((xfs_dir2_sf_entry_t *) \
+ ((char *)(sfep) + XFS_DIR2_SF_ENTSIZE_BYENTRY(sfp,sfep)));
+}
/*
* Functions.
*/
-
-extern int
- xfs_dir2_block_sfsize(struct xfs_inode *dp,
- struct xfs_dir2_block *block,
- xfs_dir2_sf_hdr_t *sfhp);
-
-extern int
- xfs_dir2_block_to_sf(struct xfs_da_args *args, struct xfs_dabuf *bp,
- int size, xfs_dir2_sf_hdr_t *sfhp);
-
-extern int
- xfs_dir2_sf_addname(struct xfs_da_args *args);
-
-extern int
- xfs_dir2_sf_create(struct xfs_da_args *args, xfs_ino_t pino);
-
-extern int
- xfs_dir2_sf_getdents(struct xfs_inode *dp, struct uio *uio, int *eofp,
- struct xfs_dirent *dbp, xfs_dir2_put_t put);
-
-extern int
- xfs_dir2_sf_lookup(struct xfs_da_args *args);
-
-extern int
- xfs_dir2_sf_removename(struct xfs_da_args *args);
-
-extern int
- xfs_dir2_sf_replace(struct xfs_da_args *args);
+extern int xfs_dir2_block_sfsize(struct xfs_inode *dp,
+ struct xfs_dir2_block *block,
+ xfs_dir2_sf_hdr_t *sfhp);
+extern int xfs_dir2_block_to_sf(struct xfs_da_args *args, struct xfs_dabuf *bp,
+ int size, xfs_dir2_sf_hdr_t *sfhp);
+extern int xfs_dir2_sf_addname(struct xfs_da_args *args);
+extern int xfs_dir2_sf_create(struct xfs_da_args *args, xfs_ino_t pino);
+extern int xfs_dir2_sf_getdents(struct xfs_inode *dp, struct uio *uio,
+ int *eofp, struct xfs_dirent *dbp,
+ xfs_dir2_put_t put);
+extern int xfs_dir2_sf_lookup(struct xfs_da_args *args);
+extern int xfs_dir2_sf_removename(struct xfs_da_args *args);
+extern int xfs_dir2_sf_replace(struct xfs_da_args *args);
#endif /* __XFS_DIR2_SF_H__ */
diff --git a/fs/xfs/xfs_dir2_trace.c b/fs/xfs/xfs_dir2_trace.c
index 9d6417393140..c626943b4112 100644
--- a/fs/xfs/xfs_dir2_trace.c
+++ b/fs/xfs/xfs_dir2_trace.c
@@ -1,52 +1,33 @@
/*
- * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
- */
-
-/*
- * xfs_dir2_trace.c
- * Tracing for xfs v2 directories.
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "xfs.h"
-
+#include "xfs_fs.h"
#include "xfs_types.h"
#include "xfs_inum.h"
#include "xfs_dir.h"
#include "xfs_dir2.h"
+#include "xfs_da_btree.h"
#include "xfs_bmap_btree.h"
-#include "xfs_attr_sf.h"
#include "xfs_dir_sf.h"
#include "xfs_dir2_sf.h"
+#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
#include "xfs_inode.h"
-#include "xfs_da_btree.h"
#include "xfs_dir2_trace.h"
#ifdef XFS_DIR2_TRACE
diff --git a/fs/xfs/xfs_dir2_trace.h b/fs/xfs/xfs_dir2_trace.h
index 0a178bffa806..ca3c754f4822 100644
--- a/fs/xfs/xfs_dir2_trace.h
+++ b/fs/xfs/xfs_dir2_trace.h
@@ -1,33 +1,19 @@
/*
- * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000,2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __XFS_DIR2_TRACE_H__
#define __XFS_DIR2_TRACE_H__
diff --git a/fs/xfs/xfs_dir_leaf.c b/fs/xfs/xfs_dir_leaf.c
index c2ea6171fb0e..950df31efc46 100644
--- a/fs/xfs/xfs_dir_leaf.c
+++ b/fs/xfs/xfs_dir_leaf.c
@@ -1,66 +1,44 @@
/*
- * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-
-/*
- * xfs_dir_leaf.c
- *
- * GROT: figure out how to recover gracefully when bmap returns ENOSPC.
- */
-
#include "xfs.h"
-
-#include "xfs_macros.h"
+#include "xfs_fs.h"
#include "xfs_types.h"
-#include "xfs_inum.h"
#include "xfs_log.h"
+#include "xfs_inum.h"
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_dir.h"
#include "xfs_dir2.h"
#include "xfs_dmapi.h"
#include "xfs_mount.h"
-#include "xfs_alloc_btree.h"
+#include "xfs_da_btree.h"
#include "xfs_bmap_btree.h"
+#include "xfs_alloc_btree.h"
#include "xfs_ialloc_btree.h"
-#include "xfs_alloc.h"
-#include "xfs_btree.h"
-#include "xfs_attr_sf.h"
#include "xfs_dir_sf.h"
#include "xfs_dir2_sf.h"
+#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
-#include "xfs_inode_item.h"
#include "xfs_inode.h"
+#include "xfs_inode_item.h"
+#include "xfs_alloc.h"
+#include "xfs_btree.h"
#include "xfs_bmap.h"
-#include "xfs_da_btree.h"
#include "xfs_dir_leaf.h"
#include "xfs_error.h"
@@ -508,7 +486,7 @@ xfs_dir_shortform_getdents(xfs_inode_t *dp, uio_t *uio, int *eofp,
/*
* Sort the entries on hash then entno.
*/
- qsort(sbuf, nsbuf, sizeof(*sbuf), xfs_dir_shortform_compare);
+ xfs_sort(sbuf, nsbuf, sizeof(*sbuf), xfs_dir_shortform_compare);
/*
* Stuff in last entry.
*/
@@ -650,7 +628,7 @@ xfs_dir_leaf_to_shortform(xfs_da_args_t *iargs)
xfs_dir_leaf_name_t *namest;
xfs_da_args_t args;
xfs_inode_t *dp;
- xfs_ino_t parent;
+ xfs_ino_t parent = 0;
char *tmpbuffer;
int retval, i;
xfs_dabuf_t *bp;
diff --git a/fs/xfs/xfs_dir_leaf.h b/fs/xfs/xfs_dir_leaf.h
index 480bffc1f29f..ab6b09eef9ab 100644
--- a/fs/xfs/xfs_dir_leaf.h
+++ b/fs/xfs/xfs_dir_leaf.h
@@ -1,33 +1,19 @@
/*
- * Copyright (c) 2000-2001 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __XFS_DIR_LEAF_H__
#define __XFS_DIR_LEAF_H__
@@ -152,30 +138,26 @@ typedef struct xfs_dir_put_args
struct uio *uio; /* uio control structure */
} xfs_dir_put_args_t;
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_DIR_LEAF_ENTSIZE_BYNAME)
-int xfs_dir_leaf_entsize_byname(int len);
#define XFS_DIR_LEAF_ENTSIZE_BYNAME(len) xfs_dir_leaf_entsize_byname(len)
-#else
-#define XFS_DIR_LEAF_ENTSIZE_BYNAME(len) /* space a name will use */ \
- ((uint)sizeof(xfs_dir_leaf_name_t)-1 + len)
-#endif
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_DIR_LEAF_ENTSIZE_BYENTRY)
-int xfs_dir_leaf_entsize_byentry(xfs_dir_leaf_entry_t *entry);
+static inline int xfs_dir_leaf_entsize_byname(int len)
+{
+ return (uint)sizeof(xfs_dir_leaf_name_t)-1 + len;
+}
+
#define XFS_DIR_LEAF_ENTSIZE_BYENTRY(entry) \
xfs_dir_leaf_entsize_byentry(entry)
-#else
-#define XFS_DIR_LEAF_ENTSIZE_BYENTRY(entry) /* space an entry will use */ \
- ((uint)sizeof(xfs_dir_leaf_name_t)-1 + (entry)->namelen)
-#endif
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_DIR_LEAF_NAMESTRUCT)
-xfs_dir_leaf_name_t *
-xfs_dir_leaf_namestruct(xfs_dir_leafblock_t *leafp, int offset);
+static inline int xfs_dir_leaf_entsize_byentry(xfs_dir_leaf_entry_t *entry)
+{
+ return (uint)sizeof(xfs_dir_leaf_name_t)-1 + (entry)->namelen;
+}
+
#define XFS_DIR_LEAF_NAMESTRUCT(leafp,offset) \
xfs_dir_leaf_namestruct(leafp,offset)
-#else
-#define XFS_DIR_LEAF_NAMESTRUCT(leafp,offset) /* point to name struct */ \
- ((xfs_dir_leaf_name_t *)&((char *)(leafp))[offset])
-#endif
+static inline xfs_dir_leaf_name_t *
+xfs_dir_leaf_namestruct(xfs_dir_leafblock_t *leafp, int offset)
+{
+ return (xfs_dir_leaf_name_t *)&((char *)(leafp))[offset];
+}
/*========================================================================
* Function prototypes for the kernel.
@@ -190,7 +172,7 @@ int xfs_dir_shortform_lookup(struct xfs_da_args *args);
int xfs_dir_shortform_to_leaf(struct xfs_da_args *args);
int xfs_dir_shortform_removename(struct xfs_da_args *args);
int xfs_dir_shortform_getdents(struct xfs_inode *dp, struct uio *uio, int *eofp,
- struct xfs_dirent *dbp, xfs_dir_put_t put);
+ struct xfs_dirent *dbp, xfs_dir_put_t put);
int xfs_dir_shortform_replace(struct xfs_da_args *args);
/*
@@ -237,7 +219,6 @@ int xfs_dir_put_dirent64_direct(xfs_dir_put_args_t *pa);
int xfs_dir_put_dirent64_uio(xfs_dir_put_args_t *pa);
int xfs_dir_ino_validate(struct xfs_mount *mp, xfs_ino_t ino);
-
/*
* Global data.
*/
diff --git a/fs/xfs/xfs_dir_sf.h b/fs/xfs/xfs_dir_sf.h
index a61bcfc2a87d..fe44c6f4d560 100644
--- a/fs/xfs/xfs_dir_sf.h
+++ b/fs/xfs/xfs_dir_sf.h
@@ -1,33 +1,19 @@
/*
- * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000,2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __XFS_DIR_SF_H__
#define __XFS_DIR_SF_H__
@@ -76,49 +62,44 @@ typedef struct xfs_dir_sf_sort {
char *name; /* name value, pointer into buffer */
} xfs_dir_sf_sort_t;
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_DIR_SF_GET_DIRINO)
-void xfs_dir_sf_get_dirino(xfs_dir_ino_t *from, xfs_ino_t *to);
-#define XFS_DIR_SF_GET_DIRINO(from,to) xfs_dir_sf_get_dirino(from, to)
-#else
-#define XFS_DIR_SF_GET_DIRINO(from,to) (*(to) = XFS_GET_DIR_INO8(*from))
-#endif
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_DIR_SF_PUT_DIRINO)
-void xfs_dir_sf_put_dirino(xfs_ino_t *from, xfs_dir_ino_t *to);
-#define XFS_DIR_SF_PUT_DIRINO(from,to) xfs_dir_sf_put_dirino(from, to)
-#else
-#define XFS_DIR_SF_PUT_DIRINO(from,to) XFS_PUT_DIR_INO8(*(from), *(to))
-#endif
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_DIR_SF_ENTSIZE_BYNAME)
-int xfs_dir_sf_entsize_byname(int len);
-#define XFS_DIR_SF_ENTSIZE_BYNAME(len) xfs_dir_sf_entsize_byname(len)
-#else
-#define XFS_DIR_SF_ENTSIZE_BYNAME(len) /* space a name uses */ \
- ((uint)sizeof(xfs_dir_sf_entry_t)-1 + (len))
-#endif
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_DIR_SF_ENTSIZE_BYENTRY)
-int xfs_dir_sf_entsize_byentry(xfs_dir_sf_entry_t *sfep);
+#define XFS_DIR_SF_GET_DIRINO(from,to) xfs_dir_sf_get_dirino(from, to)
+static inline void xfs_dir_sf_get_dirino(xfs_dir_ino_t *from, xfs_ino_t *to)
+{
+ *(to) = XFS_GET_DIR_INO8(*from);
+}
+
+#define XFS_DIR_SF_PUT_DIRINO(from,to) xfs_dir_sf_put_dirino(from, to)
+static inline void xfs_dir_sf_put_dirino(xfs_ino_t *from, xfs_dir_ino_t *to)
+{
+ XFS_PUT_DIR_INO8(*(from), *(to));
+}
+
+#define XFS_DIR_SF_ENTSIZE_BYNAME(len) xfs_dir_sf_entsize_byname(len)
+static inline int xfs_dir_sf_entsize_byname(int len)
+{
+ return (uint)sizeof(xfs_dir_sf_entry_t)-1 + (len);
+}
+
#define XFS_DIR_SF_ENTSIZE_BYENTRY(sfep) xfs_dir_sf_entsize_byentry(sfep)
-#else
-#define XFS_DIR_SF_ENTSIZE_BYENTRY(sfep) /* space an entry uses */ \
- ((uint)sizeof(xfs_dir_sf_entry_t)-1 + (sfep)->namelen)
-#endif
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_DIR_SF_NEXTENTRY)
-xfs_dir_sf_entry_t *xfs_dir_sf_nextentry(xfs_dir_sf_entry_t *sfep);
+static inline int xfs_dir_sf_entsize_byentry(xfs_dir_sf_entry_t *sfep)
+{
+ return (uint)sizeof(xfs_dir_sf_entry_t)-1 + (sfep)->namelen;
+}
+
#define XFS_DIR_SF_NEXTENTRY(sfep) xfs_dir_sf_nextentry(sfep)
-#else
-#define XFS_DIR_SF_NEXTENTRY(sfep) /* next entry in struct */ \
- ((xfs_dir_sf_entry_t *) \
- ((char *)(sfep) + XFS_DIR_SF_ENTSIZE_BYENTRY(sfep)))
-#endif
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_DIR_SF_ALLFIT)
-int xfs_dir_sf_allfit(int count, int totallen);
+static inline xfs_dir_sf_entry_t *xfs_dir_sf_nextentry(xfs_dir_sf_entry_t *sfep)
+{
+ return (xfs_dir_sf_entry_t *) \
+ ((char *)(sfep) + XFS_DIR_SF_ENTSIZE_BYENTRY(sfep));
+}
+
#define XFS_DIR_SF_ALLFIT(count,totallen) \
xfs_dir_sf_allfit(count,totallen)
-#else
-#define XFS_DIR_SF_ALLFIT(count,totallen) /* will all entries fit? */ \
- ((uint)sizeof(xfs_dir_sf_hdr_t) + \
- ((uint)sizeof(xfs_dir_sf_entry_t)-1)*(count) + (totallen))
-#endif
+static inline int xfs_dir_sf_allfit(int count, int totallen)
+{
+ return ((uint)sizeof(xfs_dir_sf_hdr_t) + \
+ ((uint)sizeof(xfs_dir_sf_entry_t)-1)*(count) + (totallen));
+}
#if defined(XFS_DIR_TRACE)
diff --git a/fs/xfs/xfs_dmapi.h b/fs/xfs/xfs_dmapi.h
index 19e872856f6b..864bf6955689 100644
--- a/fs/xfs/xfs_dmapi.h
+++ b/fs/xfs/xfs_dmapi.h
@@ -1,37 +1,24 @@
/*
- * Copyright (c) 2000-2005 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __XFS_DMAPI_H__
#define __XFS_DMAPI_H__
+#include <linux/version.h>
/* Values used to define the on-disk version of dm_attrname_t. All
* on-disk attribute names start with the 8-byte string "SGI_DMI_".
*
diff --git a/fs/xfs/xfs_dmops.c b/fs/xfs/xfs_dmops.c
index cec54ba800eb..629795b3b3d5 100644
--- a/fs/xfs/xfs_dmops.c
+++ b/fs/xfs/xfs_dmops.c
@@ -1,40 +1,25 @@
/*
- * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "xfs.h"
-
-#include "xfs_macros.h"
+#include "xfs_fs.h"
#include "xfs_types.h"
-#include "xfs_inum.h"
#include "xfs_log.h"
+#include "xfs_inum.h"
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
diff --git a/fs/xfs/xfs_error.c b/fs/xfs/xfs_error.c
index dcd3fdd5c1f7..d7b6b5d16704 100644
--- a/fs/xfs/xfs_error.c
+++ b/fs/xfs/xfs_error.c
@@ -1,51 +1,35 @@
/*
- * Copyright (c) 2000-2001 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-
#include "xfs.h"
-
-#include "xfs_macros.h"
+#include "xfs_fs.h"
#include "xfs_types.h"
-#include "xfs_inum.h"
#include "xfs_log.h"
-#include "xfs_sb.h"
+#include "xfs_inum.h"
#include "xfs_trans.h"
+#include "xfs_sb.h"
#include "xfs_dir.h"
#include "xfs_dir2.h"
#include "xfs_dmapi.h"
#include "xfs_mount.h"
#include "xfs_bmap_btree.h"
-#include "xfs_attr_sf.h"
#include "xfs_dir_sf.h"
#include "xfs_dir2_sf.h"
+#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
#include "xfs_inode.h"
#include "xfs_utils.h"
diff --git a/fs/xfs/xfs_error.h b/fs/xfs/xfs_error.h
index 52ee2b90b5ed..06d8a8426c16 100644
--- a/fs/xfs/xfs_error.h
+++ b/fs/xfs/xfs_error.h
@@ -1,39 +1,25 @@
/*
- * Copyright (c) 2000-2002 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __XFS_ERROR_H__
#define __XFS_ERROR_H__
#define prdev(fmt,targ,args...) \
- printk("XFS: device %s- " fmt "\n", XFS_BUFTARG_NAME(targ), ## args)
+ printk("XFS: device %s - " fmt "\n", XFS_BUFTARG_NAME(targ), ## args)
#define XFS_ERECOVER 1 /* Failure to recover log */
#define XFS_ELOGSTAT 2 /* Failure to stat log in user space */
@@ -54,24 +40,10 @@ extern int xfs_error_trap(int);
struct xfs_mount;
-extern void
-xfs_error_report(
- char *tag,
- int level,
- struct xfs_mount *mp,
- char *fname,
- int linenum,
- inst_t *ra);
-
-extern void
-xfs_corruption_error(
- char *tag,
- int level,
- struct xfs_mount *mp,
- void *p,
- char *fname,
- int linenum,
- inst_t *ra);
+extern void xfs_error_report(char *tag, int level, struct xfs_mount *mp,
+ char *fname, int linenum, inst_t *ra);
+extern void xfs_corruption_error(char *tag, int level, struct xfs_mount *mp,
+ void *p, char *fname, int linenum, inst_t *ra);
#define XFS_ERROR_REPORT(e, lvl, mp) \
xfs_error_report(e, lvl, mp, __FILE__, __LINE__, __return_address)
@@ -84,6 +56,32 @@ xfs_corruption_error(
#define XFS_ERRLEVEL_HIGH 5
/*
+ * Macros to set EFSCORRUPTED & return/branch.
+ */
+#define XFS_WANT_CORRUPTED_GOTO(x,l) \
+ { \
+ int fs_is_ok = (x); \
+ ASSERT(fs_is_ok); \
+ if (unlikely(!fs_is_ok)) { \
+ XFS_ERROR_REPORT("XFS_WANT_CORRUPTED_GOTO", \
+ XFS_ERRLEVEL_LOW, NULL); \
+ error = XFS_ERROR(EFSCORRUPTED); \
+ goto l; \
+ } \
+ }
+
+#define XFS_WANT_CORRUPTED_RETURN(x) \
+ { \
+ int fs_is_ok = (x); \
+ ASSERT(fs_is_ok); \
+ if (unlikely(!fs_is_ok)) { \
+ XFS_ERROR_REPORT("XFS_WANT_CORRUPTED_RETURN", \
+ XFS_ERRLEVEL_LOW, NULL); \
+ return XFS_ERROR(EFSCORRUPTED); \
+ } \
+ }
+
+/*
* error injection tags - the labels can be anything you want
* but each tag should have its own unique number
*/
@@ -139,8 +137,8 @@ xfs_corruption_error(
#define XFS_RANDOM_BMAPIFORMAT XFS_RANDOM_DEFAULT
#if (defined(DEBUG) || defined(INDUCE_IO_ERROR))
-extern int xfs_error_test(int, int *, char *, int, char *, unsigned long);
-void xfs_error_test_init(void);
+extern int xfs_error_test(int, int *, char *, int, char *, unsigned long);
+extern void xfs_error_test_init(void);
#define XFS_NUM_INJECT_ERROR 10
@@ -156,12 +154,10 @@ void xfs_error_test_init(void);
(rf)))
#endif /* __ANSI_CPP__ */
-int xfs_errortag_add(int error_tag, xfs_mount_t *mp);
-int xfs_errortag_clear(int error_tag, xfs_mount_t *mp);
-
-int xfs_errortag_clearall(xfs_mount_t *mp);
-int xfs_errortag_clearall_umount(int64_t fsid, char *fsname,
- int loud);
+extern int xfs_errortag_add(int error_tag, xfs_mount_t *mp);
+extern int xfs_errortag_clear(int error_tag, xfs_mount_t *mp);
+extern int xfs_errortag_clearall(xfs_mount_t *mp);
+extern int xfs_errortag_clearall_umount(int64_t fsid, char *fsname, int loud);
#else
#define XFS_TEST_ERROR(expr, mp, tag, rf) (expr)
#define xfs_errortag_add(tag, mp) (ENOSYS)
@@ -185,9 +181,9 @@ int xfs_errortag_clearall_umount(int64_t fsid, char *fsname,
struct xfs_mount;
/* PRINTFLIKE4 */
-void xfs_cmn_err(int panic_tag, int level, struct xfs_mount *mp,
+extern void xfs_cmn_err(int panic_tag, int level, struct xfs_mount *mp,
char *fmt, ...);
/* PRINTFLIKE3 */
-void xfs_fs_cmn_err(int level, struct xfs_mount *mp, char *fmt, ...);
+extern void xfs_fs_cmn_err(int level, struct xfs_mount *mp, char *fmt, ...);
#endif /* __XFS_ERROR_H__ */
diff --git a/fs/xfs/xfs_extfree_item.c b/fs/xfs/xfs_extfree_item.c
index cc7d1494a45d..f19282ec8549 100644
--- a/fs/xfs/xfs_extfree_item.c
+++ b/fs/xfs/xfs_extfree_item.c
@@ -1,46 +1,25 @@
/*
- * Copyright (c) 2000-2001 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
- */
-
-/*
- * This file contains the implementation of the xfs_efi_log_item
- * and xfs_efd_log_item items.
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-
#include "xfs.h"
-
-#include "xfs_macros.h"
+#include "xfs_fs.h"
#include "xfs_types.h"
-#include "xfs_inum.h"
#include "xfs_log.h"
+#include "xfs_inum.h"
#include "xfs_trans.h"
#include "xfs_buf_item.h"
#include "xfs_sb.h"
diff --git a/fs/xfs/xfs_extfree_item.h b/fs/xfs/xfs_extfree_item.h
index d433bac9f59d..5bf681708fec 100644
--- a/fs/xfs/xfs_extfree_item.h
+++ b/fs/xfs/xfs_extfree_item.h
@@ -1,33 +1,19 @@
/*
- * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000,2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __XFS_EXTFREE_ITEM_H__
#define __XFS_EXTFREE_ITEM_H__
diff --git a/fs/xfs/xfs_fs.h b/fs/xfs/xfs_fs.h
index 095af0a5cff3..ba096f80f48d 100644
--- a/fs/xfs/xfs_fs.h
+++ b/fs/xfs/xfs_fs.h
@@ -1,34 +1,19 @@
/*
- * Copyright (c) 1995-2003 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 1995-2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2.1 of the GNU Lesser General Public License
- * as published by the Free Software Foundation.
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, write the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307,
- * USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __XFS_FS_H__
#define __XFS_FS_H__
@@ -251,6 +236,7 @@ typedef struct xfs_fsop_resblks {
#define XFS_FSOP_GEOM_FLAGS_DIRV2 0x0080 /* directory version 2 */
#define XFS_FSOP_GEOM_FLAGS_LOGV2 0x0100 /* log format version 2 */
#define XFS_FSOP_GEOM_FLAGS_SECTOR 0x0200 /* sector sizes >1BB */
+#define XFS_FSOP_GEOM_FLAGS_ATTR2 0x0400 /* inline attributes rework */
/*
diff --git a/fs/xfs/xfs_fsops.c b/fs/xfs/xfs_fsops.c
index ca535d613190..7ceabd0e2d9d 100644
--- a/fs/xfs/xfs_fsops.c
+++ b/fs/xfs/xfs_fsops.c
@@ -1,66 +1,51 @@
/*
- * Copyright (c) 2000-2002 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-
#include "xfs.h"
-#include "xfs_macros.h"
+#include "xfs_fs.h"
#include "xfs_types.h"
+#include "xfs_bit.h"
#include "xfs_inum.h"
#include "xfs_log.h"
#include "xfs_trans.h"
#include "xfs_sb.h"
+#include "xfs_ag.h"
#include "xfs_dir.h"
+#include "xfs_dir2.h"
#include "xfs_dmapi.h"
#include "xfs_mount.h"
-#include "xfs_ag.h"
-#include "xfs_alloc_btree.h"
#include "xfs_bmap_btree.h"
+#include "xfs_alloc_btree.h"
#include "xfs_ialloc_btree.h"
+#include "xfs_dir_sf.h"
+#include "xfs_dir2_sf.h"
+#include "xfs_attr_sf.h"
+#include "xfs_dinode.h"
+#include "xfs_inode.h"
+#include "xfs_inode_item.h"
#include "xfs_btree.h"
#include "xfs_error.h"
#include "xfs_alloc.h"
#include "xfs_ialloc.h"
#include "xfs_fsops.h"
#include "xfs_itable.h"
-#include "xfs_rw.h"
-#include "xfs_refcache.h"
#include "xfs_trans_space.h"
#include "xfs_rtalloc.h"
-#include "xfs_dir2.h"
-#include "xfs_attr_sf.h"
-#include "xfs_dir_sf.h"
-#include "xfs_dir2_sf.h"
-#include "xfs_dinode.h"
-#include "xfs_inode.h"
-#include "xfs_inode_item.h"
+#include "xfs_rw.h"
/*
* File system operations
@@ -110,7 +95,9 @@ xfs_fs_geometry(
(XFS_SB_VERSION_HASDIRV2(&mp->m_sb) ?
XFS_FSOP_GEOM_FLAGS_DIRV2 : 0) |
(XFS_SB_VERSION_HASSECTOR(&mp->m_sb) ?
- XFS_FSOP_GEOM_FLAGS_SECTOR : 0);
+ XFS_FSOP_GEOM_FLAGS_SECTOR : 0) |
+ (XFS_SB_VERSION_HASATTR2(&mp->m_sb) ?
+ XFS_FSOP_GEOM_FLAGS_ATTR2 : 0);
geo->logsectsize = XFS_SB_VERSION_HASSECTOR(&mp->m_sb) ?
mp->m_sb.sb_logsectsize : BBSIZE;
geo->rtsectsize = mp->m_sb.sb_blocksize;
@@ -184,7 +171,7 @@ xfs_growfs_data_private(
memset(&mp->m_perag[oagcount], 0,
(nagcount - oagcount) * sizeof(xfs_perag_t));
mp->m_flags |= XFS_MOUNT_32BITINODES;
- nagimax = xfs_initialize_perag(mp, nagcount);
+ nagimax = xfs_initialize_perag(XFS_MTOVFS(mp), mp, nagcount);
up_write(&mp->m_peraglock);
}
tp = xfs_trans_alloc(mp, XFS_TRANS_GROWFS);
@@ -204,28 +191,26 @@ xfs_growfs_data_private(
XFS_FSS_TO_BB(mp, 1), 0);
agf = XFS_BUF_TO_AGF(bp);
memset(agf, 0, mp->m_sb.sb_sectsize);
- INT_SET(agf->agf_magicnum, ARCH_CONVERT, XFS_AGF_MAGIC);
- INT_SET(agf->agf_versionnum, ARCH_CONVERT, XFS_AGF_VERSION);
- INT_SET(agf->agf_seqno, ARCH_CONVERT, agno);
+ agf->agf_magicnum = cpu_to_be32(XFS_AGF_MAGIC);
+ agf->agf_versionnum = cpu_to_be32(XFS_AGF_VERSION);
+ agf->agf_seqno = cpu_to_be32(agno);
if (agno == nagcount - 1)
agsize =
nb -
(agno * (xfs_rfsblock_t)mp->m_sb.sb_agblocks);
else
agsize = mp->m_sb.sb_agblocks;
- INT_SET(agf->agf_length, ARCH_CONVERT, agsize);
- INT_SET(agf->agf_roots[XFS_BTNUM_BNOi], ARCH_CONVERT,
- XFS_BNO_BLOCK(mp));
- INT_SET(agf->agf_roots[XFS_BTNUM_CNTi], ARCH_CONVERT,
- XFS_CNT_BLOCK(mp));
- INT_SET(agf->agf_levels[XFS_BTNUM_BNOi], ARCH_CONVERT, 1);
- INT_SET(agf->agf_levels[XFS_BTNUM_CNTi], ARCH_CONVERT, 1);
+ agf->agf_length = cpu_to_be32(agsize);
+ agf->agf_roots[XFS_BTNUM_BNOi] = cpu_to_be32(XFS_BNO_BLOCK(mp));
+ agf->agf_roots[XFS_BTNUM_CNTi] = cpu_to_be32(XFS_CNT_BLOCK(mp));
+ agf->agf_levels[XFS_BTNUM_BNOi] = cpu_to_be32(1);
+ agf->agf_levels[XFS_BTNUM_CNTi] = cpu_to_be32(1);
agf->agf_flfirst = 0;
- INT_SET(agf->agf_fllast, ARCH_CONVERT, XFS_AGFL_SIZE(mp) - 1);
+ agf->agf_fllast = cpu_to_be32(XFS_AGFL_SIZE(mp) - 1);
agf->agf_flcount = 0;
tmpsize = agsize - XFS_PREALLOC_BLOCKS(mp);
- INT_SET(agf->agf_freeblks, ARCH_CONVERT, tmpsize);
- INT_SET(agf->agf_longest, ARCH_CONVERT, tmpsize);
+ agf->agf_freeblks = cpu_to_be32(tmpsize);
+ agf->agf_longest = cpu_to_be32(tmpsize);
error = xfs_bwrite(mp, bp);
if (error) {
goto error0;
@@ -238,19 +223,18 @@ xfs_growfs_data_private(
XFS_FSS_TO_BB(mp, 1), 0);
agi = XFS_BUF_TO_AGI(bp);
memset(agi, 0, mp->m_sb.sb_sectsize);
- INT_SET(agi->agi_magicnum, ARCH_CONVERT, XFS_AGI_MAGIC);
- INT_SET(agi->agi_versionnum, ARCH_CONVERT, XFS_AGI_VERSION);
- INT_SET(agi->agi_seqno, ARCH_CONVERT, agno);
- INT_SET(agi->agi_length, ARCH_CONVERT, agsize);
+ agi->agi_magicnum = cpu_to_be32(XFS_AGI_MAGIC);
+ agi->agi_versionnum = cpu_to_be32(XFS_AGI_VERSION);
+ agi->agi_seqno = cpu_to_be32(agno);
+ agi->agi_length = cpu_to_be32(agsize);
agi->agi_count = 0;
- INT_SET(agi->agi_root, ARCH_CONVERT, XFS_IBT_BLOCK(mp));
- INT_SET(agi->agi_level, ARCH_CONVERT, 1);
+ agi->agi_root = cpu_to_be32(XFS_IBT_BLOCK(mp));
+ agi->agi_level = cpu_to_be32(1);
agi->agi_freecount = 0;
- INT_SET(agi->agi_newino, ARCH_CONVERT, NULLAGINO);
- INT_SET(agi->agi_dirino, ARCH_CONVERT, NULLAGINO);
+ agi->agi_newino = cpu_to_be32(NULLAGINO);
+ agi->agi_dirino = cpu_to_be32(NULLAGINO);
for (bucket = 0; bucket < XFS_AGI_UNLINKED_BUCKETS; bucket++)
- INT_SET(agi->agi_unlinked[bucket], ARCH_CONVERT,
- NULLAGINO);
+ agi->agi_unlinked[bucket] = cpu_to_be32(NULLAGINO);
error = xfs_bwrite(mp, bp);
if (error) {
goto error0;
@@ -263,17 +247,16 @@ xfs_growfs_data_private(
BTOBB(mp->m_sb.sb_blocksize), 0);
block = XFS_BUF_TO_SBLOCK(bp);
memset(block, 0, mp->m_sb.sb_blocksize);
- INT_SET(block->bb_magic, ARCH_CONVERT, XFS_ABTB_MAGIC);
+ block->bb_magic = cpu_to_be32(XFS_ABTB_MAGIC);
block->bb_level = 0;
- INT_SET(block->bb_numrecs, ARCH_CONVERT, 1);
- INT_SET(block->bb_leftsib, ARCH_CONVERT, NULLAGBLOCK);
- INT_SET(block->bb_rightsib, ARCH_CONVERT, NULLAGBLOCK);
+ block->bb_numrecs = cpu_to_be16(1);
+ block->bb_leftsib = cpu_to_be32(NULLAGBLOCK);
+ block->bb_rightsib = cpu_to_be32(NULLAGBLOCK);
arec = XFS_BTREE_REC_ADDR(mp->m_sb.sb_blocksize, xfs_alloc,
block, 1, mp->m_alloc_mxr[0]);
- INT_SET(arec->ar_startblock, ARCH_CONVERT,
- XFS_PREALLOC_BLOCKS(mp));
- INT_SET(arec->ar_blockcount, ARCH_CONVERT,
- agsize - INT_GET(arec->ar_startblock, ARCH_CONVERT));
+ arec->ar_startblock = cpu_to_be32(XFS_PREALLOC_BLOCKS(mp));
+ arec->ar_blockcount = cpu_to_be32(
+ agsize - be32_to_cpu(arec->ar_startblock));
error = xfs_bwrite(mp, bp);
if (error) {
goto error0;
@@ -286,18 +269,17 @@ xfs_growfs_data_private(
BTOBB(mp->m_sb.sb_blocksize), 0);
block = XFS_BUF_TO_SBLOCK(bp);
memset(block, 0, mp->m_sb.sb_blocksize);
- INT_SET(block->bb_magic, ARCH_CONVERT, XFS_ABTC_MAGIC);
+ block->bb_magic = cpu_to_be32(XFS_ABTC_MAGIC);
block->bb_level = 0;
- INT_SET(block->bb_numrecs, ARCH_CONVERT, 1);
- INT_SET(block->bb_leftsib, ARCH_CONVERT, NULLAGBLOCK);
- INT_SET(block->bb_rightsib, ARCH_CONVERT, NULLAGBLOCK);
+ block->bb_numrecs = cpu_to_be16(1);
+ block->bb_leftsib = cpu_to_be32(NULLAGBLOCK);
+ block->bb_rightsib = cpu_to_be32(NULLAGBLOCK);
arec = XFS_BTREE_REC_ADDR(mp->m_sb.sb_blocksize, xfs_alloc,
block, 1, mp->m_alloc_mxr[0]);
- INT_SET(arec->ar_startblock, ARCH_CONVERT,
- XFS_PREALLOC_BLOCKS(mp));
- INT_SET(arec->ar_blockcount, ARCH_CONVERT,
- agsize - INT_GET(arec->ar_startblock, ARCH_CONVERT));
- nfree += INT_GET(arec->ar_blockcount, ARCH_CONVERT);
+ arec->ar_startblock = cpu_to_be32(XFS_PREALLOC_BLOCKS(mp));
+ arec->ar_blockcount = cpu_to_be32(
+ agsize - be32_to_cpu(arec->ar_startblock));
+ nfree += be32_to_cpu(arec->ar_blockcount);
error = xfs_bwrite(mp, bp);
if (error) {
goto error0;
@@ -310,11 +292,11 @@ xfs_growfs_data_private(
BTOBB(mp->m_sb.sb_blocksize), 0);
block = XFS_BUF_TO_SBLOCK(bp);
memset(block, 0, mp->m_sb.sb_blocksize);
- INT_SET(block->bb_magic, ARCH_CONVERT, XFS_IBT_MAGIC);
+ block->bb_magic = cpu_to_be32(XFS_IBT_MAGIC);
block->bb_level = 0;
block->bb_numrecs = 0;
- INT_SET(block->bb_leftsib, ARCH_CONVERT, NULLAGBLOCK);
- INT_SET(block->bb_rightsib, ARCH_CONVERT, NULLAGBLOCK);
+ block->bb_leftsib = cpu_to_be32(NULLAGBLOCK);
+ block->bb_rightsib = cpu_to_be32(NULLAGBLOCK);
error = xfs_bwrite(mp, bp);
if (error) {
goto error0;
@@ -334,10 +316,9 @@ xfs_growfs_data_private(
}
ASSERT(bp);
agi = XFS_BUF_TO_AGI(bp);
- INT_MOD(agi->agi_length, ARCH_CONVERT, new);
+ be32_add(&agi->agi_length, new);
ASSERT(nagcount == oagcount ||
- INT_GET(agi->agi_length, ARCH_CONVERT) ==
- mp->m_sb.sb_agblocks);
+ be32_to_cpu(agi->agi_length) == mp->m_sb.sb_agblocks);
xfs_ialloc_log_agi(tp, bp, XFS_AGI_LENGTH);
/*
* Change agf length.
@@ -348,14 +329,14 @@ xfs_growfs_data_private(
}
ASSERT(bp);
agf = XFS_BUF_TO_AGF(bp);
- INT_MOD(agf->agf_length, ARCH_CONVERT, new);
- ASSERT(INT_GET(agf->agf_length, ARCH_CONVERT) ==
- INT_GET(agi->agi_length, ARCH_CONVERT));
+ be32_add(&agf->agf_length, new);
+ ASSERT(be32_to_cpu(agf->agf_length) ==
+ be32_to_cpu(agi->agi_length));
/*
* Free the new space.
*/
error = xfs_free_extent(tp, XFS_AGB_TO_FSB(mp, agno,
- INT_GET(agf->agf_length, ARCH_CONVERT) - new), new);
+ be32_to_cpu(agf->agf_length) - new), new);
if (error) {
goto error0;
}
diff --git a/fs/xfs/xfs_fsops.h b/fs/xfs/xfs_fsops.h
index b61486173a61..f32713f14f9a 100644
--- a/fs/xfs/xfs_fsops.h
+++ b/fs/xfs/xfs_fsops.h
@@ -1,67 +1,29 @@
/*
- * Copyright (c) 2000-2001 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __XFS_FSOPS_H__
#define __XFS_FSOPS_H__
-int
-xfs_fs_geometry(
- xfs_mount_t *mp,
- xfs_fsop_geom_t *geo,
- int new_version);
-
-int
-xfs_growfs_data(
- xfs_mount_t *mp,
- xfs_growfs_data_t *in);
-
-int
-xfs_growfs_log(
- xfs_mount_t *mp,
- xfs_growfs_log_t *in);
-
-int
-xfs_fs_counts(
- xfs_mount_t *mp,
- xfs_fsop_counts_t *cnt);
-
-int
-xfs_reserve_blocks(
- xfs_mount_t *mp,
- __uint64_t *inval,
- xfs_fsop_resblks_t *outval);
-
-int
-xfs_fs_goingdown(
- xfs_mount_t *mp,
- __uint32_t inflags);
+extern int xfs_fs_geometry(xfs_mount_t *mp, xfs_fsop_geom_t *geo, int nversion);
+extern int xfs_growfs_data(xfs_mount_t *mp, xfs_growfs_data_t *in);
+extern int xfs_growfs_log(xfs_mount_t *mp, xfs_growfs_log_t *in);
+extern int xfs_fs_counts(xfs_mount_t *mp, xfs_fsop_counts_t *cnt);
+extern int xfs_reserve_blocks(xfs_mount_t *mp, __uint64_t *inval,
+ xfs_fsop_resblks_t *outval);
+extern int xfs_fs_goingdown(xfs_mount_t *mp, __uint32_t inflags);
#endif /* __XFS_FSOPS_H__ */
diff --git a/fs/xfs/xfs_ialloc.c b/fs/xfs/xfs_ialloc.c
index ce5fee9eaec5..8f3fae1aa98a 100644
--- a/fs/xfs/xfs_ialloc.c
+++ b/fs/xfs/xfs_ialloc.c
@@ -1,41 +1,26 @@
/*
- * Copyright (c) 2000-2002 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-
#include "xfs.h"
-
-#include "xfs_macros.h"
+#include "xfs_fs.h"
#include "xfs_types.h"
-#include "xfs_inum.h"
+#include "xfs_bit.h"
#include "xfs_log.h"
+#include "xfs_inum.h"
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
@@ -43,18 +28,17 @@
#include "xfs_dir2.h"
#include "xfs_dmapi.h"
#include "xfs_mount.h"
-#include "xfs_alloc_btree.h"
#include "xfs_bmap_btree.h"
+#include "xfs_alloc_btree.h"
#include "xfs_ialloc_btree.h"
-#include "xfs_btree.h"
-#include "xfs_ialloc.h"
-#include "xfs_attr_sf.h"
#include "xfs_dir_sf.h"
#include "xfs_dir2_sf.h"
+#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
#include "xfs_inode.h"
+#include "xfs_btree.h"
+#include "xfs_ialloc.h"
#include "xfs_alloc.h"
-#include "xfs_bit.h"
#include "xfs_rtalloc.h"
#include "xfs_error.h"
#include "xfs_bmap.h"
@@ -194,8 +178,8 @@ xfs_ialloc_ag_alloc(
* Ideally they should be spaced out through the a.g.
* For now, just allocate blocks up front.
*/
- args.agbno = INT_GET(agi->agi_root, ARCH_CONVERT);
- args.fsbno = XFS_AGB_TO_FSB(args.mp, INT_GET(agi->agi_seqno, ARCH_CONVERT),
+ args.agbno = be32_to_cpu(agi->agi_root);
+ args.fsbno = XFS_AGB_TO_FSB(args.mp, be32_to_cpu(agi->agi_seqno),
args.agbno);
/*
* Allocate a fixed-size extent of inodes.
@@ -217,9 +201,9 @@ xfs_ialloc_ag_alloc(
*/
if (isaligned && args.fsbno == NULLFSBLOCK) {
args.type = XFS_ALLOCTYPE_NEAR_BNO;
- args.agbno = INT_GET(agi->agi_root, ARCH_CONVERT);
+ args.agbno = be32_to_cpu(agi->agi_root);
args.fsbno = XFS_AGB_TO_FSB(args.mp,
- INT_GET(agi->agi_seqno, ARCH_CONVERT), args.agbno);
+ be32_to_cpu(agi->agi_seqno), args.agbno);
if (XFS_SB_VERSION_HASALIGN(&args.mp->m_sb) &&
args.mp->m_sb.sb_inoalignmt >=
XFS_B_TO_FSBT(args.mp, XFS_INODE_CLUSTER_SIZE(args.mp)))
@@ -274,7 +258,7 @@ xfs_ialloc_ag_alloc(
/*
* Get the block.
*/
- d = XFS_AGB_TO_DADDR(args.mp, INT_GET(agi->agi_seqno, ARCH_CONVERT),
+ d = XFS_AGB_TO_DADDR(args.mp, be32_to_cpu(agi->agi_seqno),
args.agbno + (j * blks_per_cluster));
fbuf = xfs_trans_get_buf(tp, args.mp->m_ddev_targp, d,
args.mp->m_bsize * blks_per_cluster,
@@ -294,17 +278,17 @@ xfs_ialloc_ag_alloc(
}
xfs_trans_inode_alloc_buf(tp, fbuf);
}
- INT_MOD(agi->agi_count, ARCH_CONVERT, newlen);
- INT_MOD(agi->agi_freecount, ARCH_CONVERT, newlen);
+ be32_add(&agi->agi_count, newlen);
+ be32_add(&agi->agi_freecount, newlen);
down_read(&args.mp->m_peraglock);
- args.mp->m_perag[INT_GET(agi->agi_seqno, ARCH_CONVERT)].pagi_freecount += newlen;
+ args.mp->m_perag[be32_to_cpu(agi->agi_seqno)].pagi_freecount += newlen;
up_read(&args.mp->m_peraglock);
- INT_SET(agi->agi_newino, ARCH_CONVERT, newino);
+ agi->agi_newino = cpu_to_be32(newino);
/*
* Insert records describing the new inode chunk into the btree.
*/
cur = xfs_btree_init_cursor(args.mp, tp, agbp,
- INT_GET(agi->agi_seqno, ARCH_CONVERT),
+ be32_to_cpu(agi->agi_seqno),
XFS_BTNUM_INO, (xfs_inode_t *)0, 0);
for (thisino = newino;
thisino < newino + newlen;
@@ -544,7 +528,7 @@ xfs_dialloc(
return 0;
}
agi = XFS_BUF_TO_AGI(agbp);
- ASSERT(INT_GET(agi->agi_magicnum, ARCH_CONVERT) == XFS_AGI_MAGIC);
+ ASSERT(be32_to_cpu(agi->agi_magicnum) == XFS_AGI_MAGIC);
} else {
/*
* Continue where we left off before. In this case, we
@@ -552,12 +536,12 @@ xfs_dialloc(
*/
agbp = *IO_agbp;
agi = XFS_BUF_TO_AGI(agbp);
- ASSERT(INT_GET(agi->agi_magicnum, ARCH_CONVERT) == XFS_AGI_MAGIC);
- ASSERT(INT_GET(agi->agi_freecount, ARCH_CONVERT) > 0);
+ ASSERT(be32_to_cpu(agi->agi_magicnum) == XFS_AGI_MAGIC);
+ ASSERT(be32_to_cpu(agi->agi_freecount) > 0);
}
mp = tp->t_mountp;
agcount = mp->m_sb.sb_agcount;
- agno = INT_GET(agi->agi_seqno, ARCH_CONVERT);
+ agno = be32_to_cpu(agi->agi_seqno);
tagno = agno;
pagno = XFS_INO_TO_AGNO(mp, parent);
pagino = XFS_INO_TO_AGINO(mp, parent);
@@ -605,7 +589,7 @@ xfs_dialloc(
* can commit the current transaction and call
* us again where we left off.
*/
- ASSERT(INT_GET(agi->agi_freecount, ARCH_CONVERT) > 0);
+ ASSERT(be32_to_cpu(agi->agi_freecount) > 0);
*alloc_done = B_TRUE;
*IO_agbp = agbp;
*inop = NULLFSINO;
@@ -636,7 +620,7 @@ nextag:
if (error)
goto nextag;
agi = XFS_BUF_TO_AGI(agbp);
- ASSERT(INT_GET(agi->agi_magicnum, ARCH_CONVERT) == XFS_AGI_MAGIC);
+ ASSERT(be32_to_cpu(agi->agi_magicnum) == XFS_AGI_MAGIC);
}
/*
* Here with an allocation group that has a free inode.
@@ -645,14 +629,14 @@ nextag:
*/
agno = tagno;
*IO_agbp = NULL;
- cur = xfs_btree_init_cursor(mp, tp, agbp, INT_GET(agi->agi_seqno, ARCH_CONVERT),
+ cur = xfs_btree_init_cursor(mp, tp, agbp, be32_to_cpu(agi->agi_seqno),
XFS_BTNUM_INO, (xfs_inode_t *)0, 0);
/*
* If pagino is 0 (this is the root inode allocation) use newino.
* This must work because we've just allocated some.
*/
if (!pagino)
- pagino = INT_GET(agi->agi_newino, ARCH_CONVERT);
+ pagino = be32_to_cpu(agi->agi_newino);
#ifdef DEBUG
if (cur->bc_nlevels == 1) {
int freecount = 0;
@@ -670,7 +654,7 @@ nextag:
goto error0;
} while (i == 1);
- ASSERT(freecount == INT_GET(agi->agi_freecount, ARCH_CONVERT) ||
+ ASSERT(freecount == be32_to_cpu(agi->agi_freecount) ||
XFS_FORCED_SHUTDOWN(mp));
}
#endif
@@ -829,9 +813,9 @@ nextag:
* In a different a.g. from the parent.
* See if the most recently allocated block has any free.
*/
- else if (INT_GET(agi->agi_newino, ARCH_CONVERT) != NULLAGINO) {
+ else if (be32_to_cpu(agi->agi_newino) != NULLAGINO) {
if ((error = xfs_inobt_lookup_eq(cur,
- INT_GET(agi->agi_newino, ARCH_CONVERT), 0, 0, &i)))
+ be32_to_cpu(agi->agi_newino), 0, 0, &i)))
goto error0;
if (i == 1 &&
(error = xfs_inobt_get_rec(cur, &rec.ir_startino,
@@ -878,7 +862,7 @@ nextag:
if ((error = xfs_inobt_update(cur, rec.ir_startino, rec.ir_freecount,
rec.ir_free)))
goto error0;
- INT_MOD(agi->agi_freecount, ARCH_CONVERT, -1);
+ be32_add(&agi->agi_freecount, -1);
xfs_ialloc_log_agi(tp, agbp, XFS_AGI_FREECOUNT);
down_read(&mp->m_peraglock);
mp->m_perag[tagno].pagi_freecount--;
@@ -898,7 +882,7 @@ nextag:
if ((error = xfs_inobt_increment(cur, 0, &i)))
goto error0;
} while (i == 1);
- ASSERT(freecount == INT_GET(agi->agi_freecount, ARCH_CONVERT) ||
+ ASSERT(freecount == be32_to_cpu(agi->agi_freecount) ||
XFS_FORCED_SHUTDOWN(mp));
}
#endif
@@ -957,8 +941,11 @@ xfs_difree(
agino = XFS_INO_TO_AGINO(mp, inode);
if (inode != XFS_AGINO_TO_INO(mp, agno, agino)) {
cmn_err(CE_WARN,
- "xfs_difree: inode != XFS_AGINO_TO_INO() (%d != %d) on %s. Returning EINVAL.",
- inode, XFS_AGINO_TO_INO(mp, agno, agino), mp->m_fsname);
+ "xfs_difree: inode != XFS_AGINO_TO_INO() "
+ "(%llu != %llu) on %s. Returning EINVAL.",
+ (unsigned long long)inode,
+ (unsigned long long)XFS_AGINO_TO_INO(mp, agno, agino),
+ mp->m_fsname);
ASSERT(0);
return XFS_ERROR(EINVAL);
}
@@ -983,8 +970,8 @@ xfs_difree(
return error;
}
agi = XFS_BUF_TO_AGI(agbp);
- ASSERT(INT_GET(agi->agi_magicnum, ARCH_CONVERT) == XFS_AGI_MAGIC);
- ASSERT(agbno < INT_GET(agi->agi_length, ARCH_CONVERT));
+ ASSERT(be32_to_cpu(agi->agi_magicnum) == XFS_AGI_MAGIC);
+ ASSERT(agbno < be32_to_cpu(agi->agi_length));
/*
* Initialize the cursor.
*/
@@ -1006,7 +993,7 @@ xfs_difree(
goto error0;
}
} while (i == 1);
- ASSERT(freecount == INT_GET(agi->agi_freecount, ARCH_CONVERT) ||
+ ASSERT(freecount == be32_to_cpu(agi->agi_freecount) ||
XFS_FORCED_SHUTDOWN(mp));
}
#endif
@@ -1055,8 +1042,8 @@ xfs_difree(
* to be freed when the transaction is committed.
*/
ilen = XFS_IALLOC_INODES(mp);
- INT_MOD(agi->agi_count, ARCH_CONVERT, -ilen);
- INT_MOD(agi->agi_freecount, ARCH_CONVERT, -(ilen - 1));
+ be32_add(&agi->agi_count, -ilen);
+ be32_add(&agi->agi_freecount, -(ilen - 1));
xfs_ialloc_log_agi(tp, agbp, XFS_AGI_COUNT | XFS_AGI_FREECOUNT);
down_read(&mp->m_peraglock);
mp->m_perag[agno].pagi_freecount -= ilen - 1;
@@ -1085,7 +1072,7 @@ xfs_difree(
/*
* Change the inode free counts and log the ag/sb changes.
*/
- INT_MOD(agi->agi_freecount, ARCH_CONVERT, 1);
+ be32_add(&agi->agi_freecount, 1);
xfs_ialloc_log_agi(tp, agbp, XFS_AGI_FREECOUNT);
down_read(&mp->m_peraglock);
mp->m_perag[agno].pagi_freecount++;
@@ -1111,7 +1098,7 @@ xfs_difree(
goto error0;
}
} while (i == 1);
- ASSERT(freecount == INT_GET(agi->agi_freecount, ARCH_CONVERT) ||
+ ASSERT(freecount == be32_to_cpu(agi->agi_freecount) ||
XFS_FORCED_SHUTDOWN(mp));
}
#endif
@@ -1320,7 +1307,7 @@ xfs_ialloc_log_agi(
xfs_agi_t *agi; /* allocation group header */
agi = XFS_BUF_TO_AGI(bp);
- ASSERT(INT_GET(agi->agi_magicnum, ARCH_CONVERT) == XFS_AGI_MAGIC);
+ ASSERT(be32_to_cpu(agi->agi_magicnum) == XFS_AGI_MAGIC);
#endif
/*
* Compute byte offsets for the first and last fields.
@@ -1362,9 +1349,8 @@ xfs_ialloc_read_agi(
*/
agi = XFS_BUF_TO_AGI(bp);
agi_ok =
- INT_GET(agi->agi_magicnum, ARCH_CONVERT) == XFS_AGI_MAGIC &&
- XFS_AGI_GOOD_VERSION(
- INT_GET(agi->agi_versionnum, ARCH_CONVERT));
+ be32_to_cpu(agi->agi_magicnum) == XFS_AGI_MAGIC &&
+ XFS_AGI_GOOD_VERSION(be32_to_cpu(agi->agi_versionnum));
if (unlikely(XFS_TEST_ERROR(!agi_ok, mp, XFS_ERRTAG_IALLOC_READ_AGI,
XFS_RANDOM_IALLOC_READ_AGI))) {
XFS_CORRUPTION_ERROR("xfs_ialloc_read_agi", XFS_ERRLEVEL_LOW,
@@ -1374,16 +1360,15 @@ xfs_ialloc_read_agi(
}
pag = &mp->m_perag[agno];
if (!pag->pagi_init) {
- pag->pagi_freecount = INT_GET(agi->agi_freecount, ARCH_CONVERT);
+ pag->pagi_freecount = be32_to_cpu(agi->agi_freecount);
pag->pagi_init = 1;
} else {
/*
* It's possible for these to be out of sync if
* we are in the middle of a forced shutdown.
*/
- ASSERT(pag->pagi_freecount ==
- INT_GET(agi->agi_freecount, ARCH_CONVERT)
- || XFS_FORCED_SHUTDOWN(mp));
+ ASSERT(pag->pagi_freecount == be32_to_cpu(agi->agi_freecount) ||
+ XFS_FORCED_SHUTDOWN(mp));
}
#ifdef DEBUG
diff --git a/fs/xfs/xfs_ialloc.h b/fs/xfs/xfs_ialloc.h
index db6d0015cecf..7f5debe1acb6 100644
--- a/fs/xfs/xfs_ialloc.h
+++ b/fs/xfs/xfs_ialloc.h
@@ -1,33 +1,19 @@
/*
- * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000,2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __XFS_IALLOC_H__
#define __XFS_IALLOC_H__
@@ -40,18 +26,8 @@ struct xfs_trans;
/*
* Allocation parameters for inode allocation.
*/
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_IALLOC_INODES)
-int xfs_ialloc_inodes(struct xfs_mount *mp);
-#define XFS_IALLOC_INODES(mp) xfs_ialloc_inodes(mp)
-#else
-#define XFS_IALLOC_INODES(mp) ((mp)->m_ialloc_inos)
-#endif
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_IALLOC_BLOCKS)
-xfs_extlen_t xfs_ialloc_blocks(struct xfs_mount *mp);
-#define XFS_IALLOC_BLOCKS(mp) xfs_ialloc_blocks(mp)
-#else
-#define XFS_IALLOC_BLOCKS(mp) ((mp)->m_ialloc_blks)
-#endif
+#define XFS_IALLOC_INODES(mp) (mp)->m_ialloc_inos
+#define XFS_IALLOC_BLOCKS(mp) (mp)->m_ialloc_blks
/*
* For small block file systems, move inodes in clusters of this size.
@@ -67,31 +43,25 @@ xfs_extlen_t xfs_ialloc_blocks(struct xfs_mount *mp);
/*
* Make an inode pointer out of the buffer/offset.
*/
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_MAKE_IPTR)
-struct xfs_dinode *xfs_make_iptr(struct xfs_mount *mp, struct xfs_buf *b, int o);
#define XFS_MAKE_IPTR(mp,b,o) xfs_make_iptr(mp,b,o)
-#else
-#define XFS_MAKE_IPTR(mp,b,o) \
- ((xfs_dinode_t *)(xfs_buf_offset(b, (o) << (mp)->m_sb.sb_inodelog)))
-#endif
+static inline struct xfs_dinode *
+xfs_make_iptr(struct xfs_mount *mp, struct xfs_buf *b, int o)
+{
+ return (xfs_dinode_t *)
+ (xfs_buf_offset(b, o << (mp)->m_sb.sb_inodelog));
+}
/*
* Find a free (set) bit in the inode bitmask.
*/
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_IALLOC_FIND_FREE)
-int xfs_ialloc_find_free(xfs_inofree_t *fp);
#define XFS_IALLOC_FIND_FREE(fp) xfs_ialloc_find_free(fp)
-#else
-#define XFS_IALLOC_FIND_FREE(fp) xfs_lowbit64(*(fp))
-#endif
+static inline int xfs_ialloc_find_free(xfs_inofree_t *fp)
+{
+ return xfs_lowbit64(*fp);
+}
#ifdef __KERNEL__
-
-/*
- * Prototypes for visible xfs_ialloc.c routines.
- */
-
/*
* Allocate an inode on disk.
* Mode is used to tell whether the new inode will need space, and whether
diff --git a/fs/xfs/xfs_ialloc_btree.c b/fs/xfs/xfs_ialloc_btree.c
index 2d4daecec990..60c65683462d 100644
--- a/fs/xfs/xfs_ialloc_btree.c
+++ b/fs/xfs/xfs_ialloc_btree.c
@@ -1,63 +1,46 @@
/*
- * Copyright (c) 2000-2001 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-
#include "xfs.h"
-
-#include "xfs_macros.h"
+#include "xfs_fs.h"
#include "xfs_types.h"
-#include "xfs_inum.h"
+#include "xfs_bit.h"
#include "xfs_log.h"
+#include "xfs_inum.h"
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
#include "xfs_dir.h"
+#include "xfs_dir2.h"
#include "xfs_dmapi.h"
#include "xfs_mount.h"
-#include "xfs_alloc_btree.h"
#include "xfs_bmap_btree.h"
+#include "xfs_alloc_btree.h"
#include "xfs_ialloc_btree.h"
+#include "xfs_dir_sf.h"
+#include "xfs_dir2_sf.h"
+#include "xfs_attr_sf.h"
+#include "xfs_dinode.h"
+#include "xfs_inode.h"
#include "xfs_btree.h"
#include "xfs_ialloc.h"
#include "xfs_alloc.h"
#include "xfs_error.h"
-/*
- * Inode allocation management for XFS.
- */
-
-/*
- * Prototypes for internal functions.
- */
-
STATIC void xfs_inobt_log_block(xfs_trans_t *, xfs_buf_t *, int);
STATIC void xfs_inobt_log_keys(xfs_btree_cur_t *, xfs_buf_t *, int, int);
STATIC void xfs_inobt_log_ptrs(xfs_btree_cur_t *, xfs_buf_t *, int, int);
@@ -70,10 +53,6 @@ STATIC int xfs_inobt_split(xfs_btree_cur_t *, int, xfs_agblock_t *,
STATIC int xfs_inobt_updkey(xfs_btree_cur_t *, xfs_inobt_key_t *, int);
/*
- * Internal functions.
- */
-
-/*
* Single level of the xfs_inobt_delete record deletion routine.
* Delete record pointed to by cur/level.
* Remove the record from its block then rebalance the tree.
@@ -139,7 +118,7 @@ xfs_inobt_delrec(
* Fail if we're off the end of the block.
*/
- numrecs = INT_GET(block->bb_numrecs, ARCH_CONVERT);
+ numrecs = be16_to_cpu(block->bb_numrecs);
if (ptr > numrecs) {
*stat = 0;
return 0;
@@ -154,7 +133,7 @@ xfs_inobt_delrec(
pp = XFS_INOBT_PTR_ADDR(block, 1, cur);
#ifdef DEBUG
for (i = ptr; i < numrecs; i++) {
- if ((error = xfs_btree_check_sptr(cur, INT_GET(pp[i], ARCH_CONVERT), level)))
+ if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(pp[i]), level)))
return error;
}
#endif
@@ -191,7 +170,7 @@ xfs_inobt_delrec(
* Decrement and log the number of entries in the block.
*/
numrecs--;
- INT_SET(block->bb_numrecs, ARCH_CONVERT, numrecs);
+ block->bb_numrecs = cpu_to_be16(numrecs);
xfs_inobt_log_block(cur->bc_tp, bp, XFS_BB_NUMRECS);
/*
* Is this the root level? If so, we're almost done.
@@ -210,9 +189,9 @@ xfs_inobt_delrec(
* pp is still set to the first pointer in the block.
* Make it the new root of the btree.
*/
- bno = INT_GET(agi->agi_root, ARCH_CONVERT);
+ bno = be32_to_cpu(agi->agi_root);
agi->agi_root = *pp;
- INT_MOD(agi->agi_level, ARCH_CONVERT, -1);
+ be32_add(&agi->agi_level, -1);
/*
* Free the block.
*/
@@ -255,8 +234,8 @@ xfs_inobt_delrec(
* tree balanced. Look at the left and right sibling blocks to
* see if we can re-balance by moving only one record.
*/
- rbno = INT_GET(block->bb_rightsib, ARCH_CONVERT);
- lbno = INT_GET(block->bb_leftsib, ARCH_CONVERT);
+ rbno = be32_to_cpu(block->bb_rightsib);
+ lbno = be32_to_cpu(block->bb_leftsib);
bno = NULLAGBLOCK;
ASSERT(rbno != NULLAGBLOCK || lbno != NULLAGBLOCK);
/*
@@ -293,18 +272,18 @@ xfs_inobt_delrec(
/*
* Grab the current block number, for future use.
*/
- bno = INT_GET(right->bb_leftsib, ARCH_CONVERT);
+ bno = be32_to_cpu(right->bb_leftsib);
/*
* If right block is full enough so that removing one entry
* won't make it too empty, and left-shifting an entry out
* of right to us works, we're done.
*/
- if (INT_GET(right->bb_numrecs, ARCH_CONVERT) - 1 >=
+ if (be16_to_cpu(right->bb_numrecs) - 1 >=
XFS_INOBT_BLOCK_MINRECS(level, cur)) {
if ((error = xfs_inobt_lshift(tcur, level, &i)))
goto error0;
if (i) {
- ASSERT(INT_GET(block->bb_numrecs, ARCH_CONVERT) >=
+ ASSERT(be16_to_cpu(block->bb_numrecs) >=
XFS_INOBT_BLOCK_MINRECS(level, cur));
xfs_btree_del_cursor(tcur,
XFS_BTREE_NOERROR);
@@ -321,7 +300,7 @@ xfs_inobt_delrec(
* future reference, and fix up the temp cursor to point
* to our block again (last record).
*/
- rrecs = INT_GET(right->bb_numrecs, ARCH_CONVERT);
+ rrecs = be16_to_cpu(right->bb_numrecs);
if (lbno != NULLAGBLOCK) {
xfs_btree_firstrec(tcur, level);
if ((error = xfs_inobt_decrement(tcur, level, &i)))
@@ -353,18 +332,18 @@ xfs_inobt_delrec(
/*
* Grab the current block number, for future use.
*/
- bno = INT_GET(left->bb_rightsib, ARCH_CONVERT);
+ bno = be32_to_cpu(left->bb_rightsib);
/*
* If left block is full enough so that removing one entry
* won't make it too empty, and right-shifting an entry out
* of left to us works, we're done.
*/
- if (INT_GET(left->bb_numrecs, ARCH_CONVERT) - 1 >=
+ if (be16_to_cpu(left->bb_numrecs) - 1 >=
XFS_INOBT_BLOCK_MINRECS(level, cur)) {
if ((error = xfs_inobt_rshift(tcur, level, &i)))
goto error0;
if (i) {
- ASSERT(INT_GET(block->bb_numrecs, ARCH_CONVERT) >=
+ ASSERT(be16_to_cpu(block->bb_numrecs) >=
XFS_INOBT_BLOCK_MINRECS(level, cur));
xfs_btree_del_cursor(tcur,
XFS_BTREE_NOERROR);
@@ -378,7 +357,7 @@ xfs_inobt_delrec(
* Otherwise, grab the number of records in right for
* future reference.
*/
- lrecs = INT_GET(left->bb_numrecs, ARCH_CONVERT);
+ lrecs = be16_to_cpu(left->bb_numrecs);
}
/*
* Delete the temp cursor, we're done with it.
@@ -399,14 +378,14 @@ xfs_inobt_delrec(
*/
rbno = bno;
right = block;
- rrecs = INT_GET(right->bb_numrecs, ARCH_CONVERT);
+ rrecs = be16_to_cpu(right->bb_numrecs);
rbp = bp;
if ((error = xfs_btree_read_bufs(mp, cur->bc_tp,
cur->bc_private.i.agno, lbno, 0, &lbp,
XFS_INO_BTREE_REF)))
return error;
left = XFS_BUF_TO_INOBT_BLOCK(lbp);
- lrecs = INT_GET(left->bb_numrecs, ARCH_CONVERT);
+ lrecs = be16_to_cpu(left->bb_numrecs);
if ((error = xfs_btree_check_sblock(cur, left, level, lbp)))
return error;
}
@@ -421,14 +400,14 @@ xfs_inobt_delrec(
*/
lbno = bno;
left = block;
- lrecs = INT_GET(left->bb_numrecs, ARCH_CONVERT);
+ lrecs = be16_to_cpu(left->bb_numrecs);
lbp = bp;
if ((error = xfs_btree_read_bufs(mp, cur->bc_tp,
cur->bc_private.i.agno, rbno, 0, &rbp,
XFS_INO_BTREE_REF)))
return error;
right = XFS_BUF_TO_INOBT_BLOCK(rbp);
- rrecs = INT_GET(right->bb_numrecs, ARCH_CONVERT);
+ rrecs = be16_to_cpu(right->bb_numrecs);
if ((error = xfs_btree_check_sblock(cur, right, level, rbp)))
return error;
}
@@ -456,7 +435,7 @@ xfs_inobt_delrec(
rpp = XFS_INOBT_PTR_ADDR(right, 1, cur);
#ifdef DEBUG
for (i = 0; i < rrecs; i++) {
- if ((error = xfs_btree_check_sptr(cur, INT_GET(rpp[i], ARCH_CONVERT), level)))
+ if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(rpp[i]), level)))
return error;
}
#endif
@@ -492,7 +471,7 @@ xfs_inobt_delrec(
* Fix up the number of records in the surviving block.
*/
lrecs += rrecs;
- INT_SET(left->bb_numrecs, ARCH_CONVERT, lrecs);
+ left->bb_numrecs = cpu_to_be16(lrecs);
/*
* Fix up the right block pointer in the surviving block, and log it.
*/
@@ -502,18 +481,18 @@ xfs_inobt_delrec(
* If there is a right sibling now, make it point to the
* remaining block.
*/
- if (INT_GET(left->bb_rightsib, ARCH_CONVERT) != NULLAGBLOCK) {
+ if (be32_to_cpu(left->bb_rightsib) != NULLAGBLOCK) {
xfs_inobt_block_t *rrblock;
xfs_buf_t *rrbp;
if ((error = xfs_btree_read_bufs(mp, cur->bc_tp,
- cur->bc_private.i.agno, INT_GET(left->bb_rightsib, ARCH_CONVERT), 0,
+ cur->bc_private.i.agno, be32_to_cpu(left->bb_rightsib), 0,
&rrbp, XFS_INO_BTREE_REF)))
return error;
rrblock = XFS_BUF_TO_INOBT_BLOCK(rrbp);
if ((error = xfs_btree_check_sblock(cur, rrblock, level, rrbp)))
return error;
- INT_SET(rrblock->bb_leftsib, ARCH_CONVERT, lbno);
+ rrblock->bb_leftsib = cpu_to_be32(lbno);
xfs_inobt_log_block(cur->bc_tp, rrbp, XFS_BB_LEFTSIB);
}
/*
@@ -572,6 +551,13 @@ xfs_inobt_insrec(
xfs_inobt_rec_t *rp=NULL; /* pointer to btree records */
/*
+ * GCC doesn't understand the (arguably complex) control flow in
+ * this function and complains about uninitialized structure fields
+ * without this.
+ */
+ memset(&nrec, 0, sizeof(nrec));
+
+ /*
* If we made it to the root level, allocate a new root block
* and we're done.
*/
@@ -598,7 +584,7 @@ xfs_inobt_insrec(
*/
bp = cur->bc_bufs[level];
block = XFS_BUF_TO_INOBT_BLOCK(bp);
- numrecs = INT_GET(block->bb_numrecs, ARCH_CONVERT);
+ numrecs = be16_to_cpu(block->bb_numrecs);
#ifdef DEBUG
if ((error = xfs_btree_check_sblock(cur, block, level, bp)))
return error;
@@ -672,7 +658,7 @@ xfs_inobt_insrec(
* At this point we know there's room for our new entry in the block
* we're pointing at.
*/
- numrecs = INT_GET(block->bb_numrecs, ARCH_CONVERT);
+ numrecs = be16_to_cpu(block->bb_numrecs);
if (level > 0) {
/*
* It's a non-leaf entry. Make a hole for the new data
@@ -682,7 +668,7 @@ xfs_inobt_insrec(
pp = XFS_INOBT_PTR_ADDR(block, 1, cur);
#ifdef DEBUG
for (i = numrecs; i >= ptr; i--) {
- if ((error = xfs_btree_check_sptr(cur, INT_GET(pp[i - 1], ARCH_CONVERT), level)))
+ if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(pp[i - 1]), level)))
return error;
}
#endif
@@ -698,9 +684,9 @@ xfs_inobt_insrec(
return error;
#endif
kp[ptr - 1] = key; /* INT_: struct copy */
- INT_SET(pp[ptr - 1], ARCH_CONVERT, *bnop);
+ pp[ptr - 1] = cpu_to_be32(*bnop);
numrecs++;
- INT_SET(block->bb_numrecs, ARCH_CONVERT, numrecs);
+ block->bb_numrecs = cpu_to_be16(numrecs);
xfs_inobt_log_keys(cur, bp, ptr, numrecs);
xfs_inobt_log_ptrs(cur, bp, ptr, numrecs);
} else {
@@ -716,7 +702,7 @@ xfs_inobt_insrec(
*/
rp[ptr - 1] = *recp; /* INT_: struct copy */
numrecs++;
- INT_SET(block->bb_numrecs, ARCH_CONVERT, numrecs);
+ block->bb_numrecs = cpu_to_be16(numrecs);
xfs_inobt_log_recs(cur, bp, ptr, numrecs);
}
/*
@@ -871,8 +857,8 @@ xfs_inobt_lookup(
xfs_agi_t *agi; /* a.g. inode header */
agi = XFS_BUF_TO_AGI(cur->bc_private.i.agbp);
- agno = INT_GET(agi->agi_seqno, ARCH_CONVERT);
- agbno = INT_GET(agi->agi_root, ARCH_CONVERT);
+ agno = be32_to_cpu(agi->agi_seqno);
+ agbno = be32_to_cpu(agi->agi_root);
}
/*
* Iterate over each level in the btree, starting at the root.
@@ -939,7 +925,7 @@ xfs_inobt_lookup(
* Set low and high entry numbers, 1-based.
*/
low = 1;
- if (!(high = INT_GET(block->bb_numrecs, ARCH_CONVERT))) {
+ if (!(high = be16_to_cpu(block->bb_numrecs))) {
/*
* If the block is empty, the tree must
* be an empty leaf.
@@ -1006,7 +992,7 @@ xfs_inobt_lookup(
*/
if (diff > 0 && --keyno < 1)
keyno = 1;
- agbno = INT_GET(*XFS_INOBT_PTR_ADDR(block, keyno, cur), ARCH_CONVERT);
+ agbno = be32_to_cpu(*XFS_INOBT_PTR_ADDR(block, keyno, cur));
#ifdef DEBUG
if ((error = xfs_btree_check_sptr(cur, agbno, level)))
return error;
@@ -1025,8 +1011,8 @@ xfs_inobt_lookup(
* not the last block, we're in the wrong block.
*/
if (dir == XFS_LOOKUP_GE &&
- keyno > INT_GET(block->bb_numrecs, ARCH_CONVERT) &&
- INT_GET(block->bb_rightsib, ARCH_CONVERT) != NULLAGBLOCK) {
+ keyno > be16_to_cpu(block->bb_numrecs) &&
+ be32_to_cpu(block->bb_rightsib) != NULLAGBLOCK) {
int i;
cur->bc_ptrs[0] = keyno;
@@ -1043,7 +1029,7 @@ xfs_inobt_lookup(
/*
* Return if we succeeded or not.
*/
- if (keyno == 0 || keyno > INT_GET(block->bb_numrecs, ARCH_CONVERT))
+ if (keyno == 0 || keyno > be16_to_cpu(block->bb_numrecs))
*stat = 0;
else
*stat = ((dir != XFS_LOOKUP_EQ) || (diff == 0));
@@ -1089,7 +1075,7 @@ xfs_inobt_lshift(
/*
* If we've got no left sibling then we can't shift an entry left.
*/
- if (INT_GET(right->bb_leftsib, ARCH_CONVERT) == NULLAGBLOCK) {
+ if (be32_to_cpu(right->bb_leftsib) == NULLAGBLOCK) {
*stat = 0;
return 0;
}
@@ -1105,8 +1091,8 @@ xfs_inobt_lshift(
* Set up the left neighbor as "left".
*/
if ((error = xfs_btree_read_bufs(cur->bc_mp, cur->bc_tp,
- cur->bc_private.i.agno, INT_GET(right->bb_leftsib, ARCH_CONVERT), 0, &lbp,
- XFS_INO_BTREE_REF)))
+ cur->bc_private.i.agno, be32_to_cpu(right->bb_leftsib),
+ 0, &lbp, XFS_INO_BTREE_REF)))
return error;
left = XFS_BUF_TO_INOBT_BLOCK(lbp);
if ((error = xfs_btree_check_sblock(cur, left, level, lbp)))
@@ -1114,11 +1100,11 @@ xfs_inobt_lshift(
/*
* If it's full, it can't take another entry.
*/
- if (INT_GET(left->bb_numrecs, ARCH_CONVERT) == XFS_INOBT_BLOCK_MAXRECS(level, cur)) {
+ if (be16_to_cpu(left->bb_numrecs) == XFS_INOBT_BLOCK_MAXRECS(level, cur)) {
*stat = 0;
return 0;
}
- nrec = INT_GET(left->bb_numrecs, ARCH_CONVERT) + 1;
+ nrec = be16_to_cpu(left->bb_numrecs) + 1;
/*
* If non-leaf, copy a key and a ptr to the left block.
*/
@@ -1130,7 +1116,7 @@ xfs_inobt_lshift(
lpp = XFS_INOBT_PTR_ADDR(left, nrec, cur);
rpp = XFS_INOBT_PTR_ADDR(right, 1, cur);
#ifdef DEBUG
- if ((error = xfs_btree_check_sptr(cur, INT_GET(*rpp, ARCH_CONVERT), level)))
+ if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(*rpp), level)))
return error;
#endif
*lpp = *rpp; /* INT_: no-change copy */
@@ -1148,7 +1134,7 @@ xfs_inobt_lshift(
/*
* Bump and log left's numrecs, decrement and log right's numrecs.
*/
- INT_MOD(left->bb_numrecs, ARCH_CONVERT, +1);
+ be16_add(&left->bb_numrecs, 1);
xfs_inobt_log_block(cur->bc_tp, lbp, XFS_BB_NUMRECS);
#ifdef DEBUG
if (level > 0)
@@ -1156,26 +1142,26 @@ xfs_inobt_lshift(
else
xfs_btree_check_rec(cur->bc_btnum, lrp - 1, lrp);
#endif
- INT_MOD(right->bb_numrecs, ARCH_CONVERT, -1);
+ be16_add(&right->bb_numrecs, -1);
xfs_inobt_log_block(cur->bc_tp, rbp, XFS_BB_NUMRECS);
/*
* Slide the contents of right down one entry.
*/
if (level > 0) {
#ifdef DEBUG
- for (i = 0; i < INT_GET(right->bb_numrecs, ARCH_CONVERT); i++) {
- if ((error = xfs_btree_check_sptr(cur, INT_GET(rpp[i + 1], ARCH_CONVERT),
+ for (i = 0; i < be16_to_cpu(right->bb_numrecs); i++) {
+ if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(rpp[i + 1]),
level)))
return error;
}
#endif
- memmove(rkp, rkp + 1, INT_GET(right->bb_numrecs, ARCH_CONVERT) * sizeof(*rkp));
- memmove(rpp, rpp + 1, INT_GET(right->bb_numrecs, ARCH_CONVERT) * sizeof(*rpp));
- xfs_inobt_log_keys(cur, rbp, 1, INT_GET(right->bb_numrecs, ARCH_CONVERT));
- xfs_inobt_log_ptrs(cur, rbp, 1, INT_GET(right->bb_numrecs, ARCH_CONVERT));
+ memmove(rkp, rkp + 1, be16_to_cpu(right->bb_numrecs) * sizeof(*rkp));
+ memmove(rpp, rpp + 1, be16_to_cpu(right->bb_numrecs) * sizeof(*rpp));
+ xfs_inobt_log_keys(cur, rbp, 1, be16_to_cpu(right->bb_numrecs));
+ xfs_inobt_log_ptrs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs));
} else {
- memmove(rrp, rrp + 1, INT_GET(right->bb_numrecs, ARCH_CONVERT) * sizeof(*rrp));
- xfs_inobt_log_recs(cur, rbp, 1, INT_GET(right->bb_numrecs, ARCH_CONVERT));
+ memmove(rrp, rrp + 1, be16_to_cpu(right->bb_numrecs) * sizeof(*rrp));
+ xfs_inobt_log_recs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs));
key.ir_startino = rrp->ir_startino; /* INT_: direct copy */
rkp = &key;
}
@@ -1227,7 +1213,7 @@ xfs_inobt_newroot(
args.tp = cur->bc_tp;
args.mp = cur->bc_mp;
args.fsbno = XFS_AGB_TO_FSB(args.mp, cur->bc_private.i.agno,
- INT_GET(agi->agi_root, ARCH_CONVERT));
+ be32_to_cpu(agi->agi_root));
args.mod = args.minleft = args.alignment = args.total = args.wasdel =
args.isfl = args.userdata = args.minalignslop = 0;
args.minlen = args.maxlen = args.prod = 1;
@@ -1247,8 +1233,8 @@ xfs_inobt_newroot(
/*
* Set the root data in the a.g. inode structure.
*/
- INT_SET(agi->agi_root, ARCH_CONVERT, args.agbno);
- INT_MOD(agi->agi_level, ARCH_CONVERT, 1);
+ agi->agi_root = cpu_to_be32(args.agbno);
+ be32_add(&agi->agi_level, 1);
xfs_ialloc_log_agi(args.tp, cur->bc_private.i.agbp,
XFS_AGI_ROOT | XFS_AGI_LEVEL);
/*
@@ -1263,14 +1249,14 @@ xfs_inobt_newroot(
if ((error = xfs_btree_check_sblock(cur, block, cur->bc_nlevels - 1, bp)))
return error;
#endif
- if (INT_GET(block->bb_rightsib, ARCH_CONVERT) != NULLAGBLOCK) {
+ if (be32_to_cpu(block->bb_rightsib) != NULLAGBLOCK) {
/*
* Our block is left, pick up the right block.
*/
lbp = bp;
lbno = XFS_DADDR_TO_AGBNO(args.mp, XFS_BUF_ADDR(lbp));
left = block;
- rbno = INT_GET(left->bb_rightsib, ARCH_CONVERT);
+ rbno = be32_to_cpu(left->bb_rightsib);
if ((error = xfs_btree_read_bufs(args.mp, args.tp, args.agno,
rbno, 0, &rbp, XFS_INO_BTREE_REF)))
return error;
@@ -1287,7 +1273,7 @@ xfs_inobt_newroot(
rbp = bp;
rbno = XFS_DADDR_TO_AGBNO(args.mp, XFS_BUF_ADDR(rbp));
right = block;
- lbno = INT_GET(right->bb_leftsib, ARCH_CONVERT);
+ lbno = be32_to_cpu(right->bb_leftsib);
if ((error = xfs_btree_read_bufs(args.mp, args.tp, args.agno,
lbno, 0, &lbp, XFS_INO_BTREE_REF)))
return error;
@@ -1301,18 +1287,18 @@ xfs_inobt_newroot(
/*
* Fill in the new block's btree header and log it.
*/
- INT_SET(new->bb_magic, ARCH_CONVERT, xfs_magics[cur->bc_btnum]);
- INT_SET(new->bb_level, ARCH_CONVERT, (__uint16_t)cur->bc_nlevels);
- INT_SET(new->bb_numrecs, ARCH_CONVERT, 2);
- INT_SET(new->bb_leftsib, ARCH_CONVERT, NULLAGBLOCK);
- INT_SET(new->bb_rightsib, ARCH_CONVERT, NULLAGBLOCK);
+ new->bb_magic = cpu_to_be32(xfs_magics[cur->bc_btnum]);
+ new->bb_level = cpu_to_be16(cur->bc_nlevels);
+ new->bb_numrecs = cpu_to_be16(2);
+ new->bb_leftsib = cpu_to_be32(NULLAGBLOCK);
+ new->bb_rightsib = cpu_to_be32(NULLAGBLOCK);
xfs_inobt_log_block(args.tp, nbp, XFS_BB_ALL_BITS);
ASSERT(lbno != NULLAGBLOCK && rbno != NULLAGBLOCK);
/*
* Fill in the key data in the new root.
*/
kp = XFS_INOBT_KEY_ADDR(new, 1, cur);
- if (INT_GET(left->bb_level, ARCH_CONVERT) > 0) {
+ if (be16_to_cpu(left->bb_level) > 0) {
kp[0] = *XFS_INOBT_KEY_ADDR(left, 1, cur); /* INT_: struct copy */
kp[1] = *XFS_INOBT_KEY_ADDR(right, 1, cur); /* INT_: struct copy */
} else {
@@ -1326,8 +1312,8 @@ xfs_inobt_newroot(
* Fill in the pointer data in the new root.
*/
pp = XFS_INOBT_PTR_ADDR(new, 1, cur);
- INT_SET(pp[0], ARCH_CONVERT, lbno);
- INT_SET(pp[1], ARCH_CONVERT, rbno);
+ pp[0] = cpu_to_be32(lbno);
+ pp[1] = cpu_to_be32(rbno);
xfs_inobt_log_ptrs(cur, nbp, 1, 2);
/*
* Fix up the cursor.
@@ -1376,7 +1362,7 @@ xfs_inobt_rshift(
/*
* If we've got no right sibling then we can't shift an entry right.
*/
- if (INT_GET(left->bb_rightsib, ARCH_CONVERT) == NULLAGBLOCK) {
+ if (be32_to_cpu(left->bb_rightsib) == NULLAGBLOCK) {
*stat = 0;
return 0;
}
@@ -1384,7 +1370,7 @@ xfs_inobt_rshift(
* If the cursor entry is the one that would be moved, don't
* do it... it's too complicated.
*/
- if (cur->bc_ptrs[level] >= INT_GET(left->bb_numrecs, ARCH_CONVERT)) {
+ if (cur->bc_ptrs[level] >= be16_to_cpu(left->bb_numrecs)) {
*stat = 0;
return 0;
}
@@ -1392,8 +1378,8 @@ xfs_inobt_rshift(
* Set up the right neighbor as "right".
*/
if ((error = xfs_btree_read_bufs(cur->bc_mp, cur->bc_tp,
- cur->bc_private.i.agno, INT_GET(left->bb_rightsib, ARCH_CONVERT), 0, &rbp,
- XFS_INO_BTREE_REF)))
+ cur->bc_private.i.agno, be32_to_cpu(left->bb_rightsib),
+ 0, &rbp, XFS_INO_BTREE_REF)))
return error;
right = XFS_BUF_TO_INOBT_BLOCK(rbp);
if ((error = xfs_btree_check_sblock(cur, right, level, rbp)))
@@ -1401,7 +1387,7 @@ xfs_inobt_rshift(
/*
* If it's full, it can't take another entry.
*/
- if (INT_GET(right->bb_numrecs, ARCH_CONVERT) == XFS_INOBT_BLOCK_MAXRECS(level, cur)) {
+ if (be16_to_cpu(right->bb_numrecs) == XFS_INOBT_BLOCK_MAXRECS(level, cur)) {
*stat = 0;
return 0;
}
@@ -1410,41 +1396,41 @@ xfs_inobt_rshift(
* copy the last left block entry to the hole.
*/
if (level > 0) {
- lkp = XFS_INOBT_KEY_ADDR(left, INT_GET(left->bb_numrecs, ARCH_CONVERT), cur);
- lpp = XFS_INOBT_PTR_ADDR(left, INT_GET(left->bb_numrecs, ARCH_CONVERT), cur);
+ lkp = XFS_INOBT_KEY_ADDR(left, be16_to_cpu(left->bb_numrecs), cur);
+ lpp = XFS_INOBT_PTR_ADDR(left, be16_to_cpu(left->bb_numrecs), cur);
rkp = XFS_INOBT_KEY_ADDR(right, 1, cur);
rpp = XFS_INOBT_PTR_ADDR(right, 1, cur);
#ifdef DEBUG
- for (i = INT_GET(right->bb_numrecs, ARCH_CONVERT) - 1; i >= 0; i--) {
- if ((error = xfs_btree_check_sptr(cur, INT_GET(rpp[i], ARCH_CONVERT), level)))
+ for (i = be16_to_cpu(right->bb_numrecs) - 1; i >= 0; i--) {
+ if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(rpp[i]), level)))
return error;
}
#endif
- memmove(rkp + 1, rkp, INT_GET(right->bb_numrecs, ARCH_CONVERT) * sizeof(*rkp));
- memmove(rpp + 1, rpp, INT_GET(right->bb_numrecs, ARCH_CONVERT) * sizeof(*rpp));
+ memmove(rkp + 1, rkp, be16_to_cpu(right->bb_numrecs) * sizeof(*rkp));
+ memmove(rpp + 1, rpp, be16_to_cpu(right->bb_numrecs) * sizeof(*rpp));
#ifdef DEBUG
- if ((error = xfs_btree_check_sptr(cur, INT_GET(*lpp, ARCH_CONVERT), level)))
+ if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(*lpp), level)))
return error;
#endif
*rkp = *lkp; /* INT_: no change copy */
*rpp = *lpp; /* INT_: no change copy */
- xfs_inobt_log_keys(cur, rbp, 1, INT_GET(right->bb_numrecs, ARCH_CONVERT) + 1);
- xfs_inobt_log_ptrs(cur, rbp, 1, INT_GET(right->bb_numrecs, ARCH_CONVERT) + 1);
+ xfs_inobt_log_keys(cur, rbp, 1, be16_to_cpu(right->bb_numrecs) + 1);
+ xfs_inobt_log_ptrs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs) + 1);
} else {
- lrp = XFS_INOBT_REC_ADDR(left, INT_GET(left->bb_numrecs, ARCH_CONVERT), cur);
+ lrp = XFS_INOBT_REC_ADDR(left, be16_to_cpu(left->bb_numrecs), cur);
rrp = XFS_INOBT_REC_ADDR(right, 1, cur);
- memmove(rrp + 1, rrp, INT_GET(right->bb_numrecs, ARCH_CONVERT) * sizeof(*rrp));
+ memmove(rrp + 1, rrp, be16_to_cpu(right->bb_numrecs) * sizeof(*rrp));
*rrp = *lrp;
- xfs_inobt_log_recs(cur, rbp, 1, INT_GET(right->bb_numrecs, ARCH_CONVERT) + 1);
+ xfs_inobt_log_recs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs) + 1);
key.ir_startino = rrp->ir_startino; /* INT_: direct copy */
rkp = &key;
}
/*
* Decrement and log left's numrecs, bump and log right's numrecs.
*/
- INT_MOD(left->bb_numrecs, ARCH_CONVERT, -1);
+ be16_add(&left->bb_numrecs, -1);
xfs_inobt_log_block(cur->bc_tp, lbp, XFS_BB_NUMRECS);
- INT_MOD(right->bb_numrecs, ARCH_CONVERT, +1);
+ be16_add(&right->bb_numrecs, 1);
#ifdef DEBUG
if (level > 0)
xfs_btree_check_key(cur->bc_btnum, rkp, rkp + 1);
@@ -1536,17 +1522,17 @@ xfs_inobt_split(
/*
* Fill in the btree header for the new block.
*/
- INT_SET(right->bb_magic, ARCH_CONVERT, xfs_magics[cur->bc_btnum]);
- right->bb_level = left->bb_level; /* INT_: direct copy */
- INT_SET(right->bb_numrecs, ARCH_CONVERT, (__uint16_t)(INT_GET(left->bb_numrecs, ARCH_CONVERT) / 2));
+ right->bb_magic = cpu_to_be32(xfs_magics[cur->bc_btnum]);
+ right->bb_level = left->bb_level;
+ right->bb_numrecs = cpu_to_be16(be16_to_cpu(left->bb_numrecs) / 2);
/*
* Make sure that if there's an odd number of entries now, that
* each new block will have the same number of entries.
*/
- if ((INT_GET(left->bb_numrecs, ARCH_CONVERT) & 1) &&
- cur->bc_ptrs[level] <= INT_GET(right->bb_numrecs, ARCH_CONVERT) + 1)
- INT_MOD(right->bb_numrecs, ARCH_CONVERT, +1);
- i = INT_GET(left->bb_numrecs, ARCH_CONVERT) - INT_GET(right->bb_numrecs, ARCH_CONVERT) + 1;
+ if ((be16_to_cpu(left->bb_numrecs) & 1) &&
+ cur->bc_ptrs[level] <= be16_to_cpu(right->bb_numrecs) + 1)
+ be16_add(&right->bb_numrecs, 1);
+ i = be16_to_cpu(left->bb_numrecs) - be16_to_cpu(right->bb_numrecs) + 1;
/*
* For non-leaf blocks, copy keys and addresses over to the new block.
*/
@@ -1556,15 +1542,15 @@ xfs_inobt_split(
rkp = XFS_INOBT_KEY_ADDR(right, 1, cur);
rpp = XFS_INOBT_PTR_ADDR(right, 1, cur);
#ifdef DEBUG
- for (i = 0; i < INT_GET(right->bb_numrecs, ARCH_CONVERT); i++) {
- if ((error = xfs_btree_check_sptr(cur, INT_GET(lpp[i], ARCH_CONVERT), level)))
+ for (i = 0; i < be16_to_cpu(right->bb_numrecs); i++) {
+ if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(lpp[i]), level)))
return error;
}
#endif
- memcpy(rkp, lkp, INT_GET(right->bb_numrecs, ARCH_CONVERT) * sizeof(*rkp));
- memcpy(rpp, lpp, INT_GET(right->bb_numrecs, ARCH_CONVERT) * sizeof(*rpp));
- xfs_inobt_log_keys(cur, rbp, 1, INT_GET(right->bb_numrecs, ARCH_CONVERT));
- xfs_inobt_log_ptrs(cur, rbp, 1, INT_GET(right->bb_numrecs, ARCH_CONVERT));
+ memcpy(rkp, lkp, be16_to_cpu(right->bb_numrecs) * sizeof(*rkp));
+ memcpy(rpp, lpp, be16_to_cpu(right->bb_numrecs) * sizeof(*rpp));
+ xfs_inobt_log_keys(cur, rbp, 1, be16_to_cpu(right->bb_numrecs));
+ xfs_inobt_log_ptrs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs));
*keyp = *rkp;
}
/*
@@ -1573,36 +1559,36 @@ xfs_inobt_split(
else {
lrp = XFS_INOBT_REC_ADDR(left, i, cur);
rrp = XFS_INOBT_REC_ADDR(right, 1, cur);
- memcpy(rrp, lrp, INT_GET(right->bb_numrecs, ARCH_CONVERT) * sizeof(*rrp));
- xfs_inobt_log_recs(cur, rbp, 1, INT_GET(right->bb_numrecs, ARCH_CONVERT));
+ memcpy(rrp, lrp, be16_to_cpu(right->bb_numrecs) * sizeof(*rrp));
+ xfs_inobt_log_recs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs));
keyp->ir_startino = rrp->ir_startino; /* INT_: direct copy */
}
/*
* Find the left block number by looking in the buffer.
* Adjust numrecs, sibling pointers.
*/
- INT_MOD(left->bb_numrecs, ARCH_CONVERT, -(INT_GET(right->bb_numrecs, ARCH_CONVERT)));
- right->bb_rightsib = left->bb_rightsib; /* INT_: direct copy */
- INT_SET(left->bb_rightsib, ARCH_CONVERT, args.agbno);
- INT_SET(right->bb_leftsib, ARCH_CONVERT, lbno);
+ be16_add(&left->bb_numrecs, -(be16_to_cpu(right->bb_numrecs)));
+ right->bb_rightsib = left->bb_rightsib;
+ left->bb_rightsib = cpu_to_be32(args.agbno);
+ right->bb_leftsib = cpu_to_be32(lbno);
xfs_inobt_log_block(args.tp, rbp, XFS_BB_ALL_BITS);
xfs_inobt_log_block(args.tp, lbp, XFS_BB_NUMRECS | XFS_BB_RIGHTSIB);
/*
* If there's a block to the new block's right, make that block
* point back to right instead of to left.
*/
- if (INT_GET(right->bb_rightsib, ARCH_CONVERT) != NULLAGBLOCK) {
+ if (be32_to_cpu(right->bb_rightsib) != NULLAGBLOCK) {
xfs_inobt_block_t *rrblock; /* rr btree block */
xfs_buf_t *rrbp; /* buffer for rrblock */
if ((error = xfs_btree_read_bufs(args.mp, args.tp, args.agno,
- INT_GET(right->bb_rightsib, ARCH_CONVERT), 0, &rrbp,
+ be32_to_cpu(right->bb_rightsib), 0, &rrbp,
XFS_INO_BTREE_REF)))
return error;
rrblock = XFS_BUF_TO_INOBT_BLOCK(rrbp);
if ((error = xfs_btree_check_sblock(cur, rrblock, level, rrbp)))
return error;
- INT_SET(rrblock->bb_leftsib, ARCH_CONVERT, args.agbno);
+ rrblock->bb_leftsib = cpu_to_be32(args.agbno);
xfs_inobt_log_block(args.tp, rrbp, XFS_BB_LEFTSIB);
}
/*
@@ -1610,9 +1596,9 @@ xfs_inobt_split(
* If it's just pointing past the last entry in left, then we'll
* insert there, so don't change anything in that case.
*/
- if (cur->bc_ptrs[level] > INT_GET(left->bb_numrecs, ARCH_CONVERT) + 1) {
+ if (cur->bc_ptrs[level] > be16_to_cpu(left->bb_numrecs) + 1) {
xfs_btree_setbuf(cur, level, rbp);
- cur->bc_ptrs[level] -= INT_GET(left->bb_numrecs, ARCH_CONVERT);
+ cur->bc_ptrs[level] -= be16_to_cpu(left->bb_numrecs);
}
/*
* If there are more levels, we'll need another cursor which refers
@@ -1710,7 +1696,7 @@ xfs_inobt_decrement(
/*
* If we just went off the left edge of the tree, return failure.
*/
- if (INT_GET(block->bb_leftsib, ARCH_CONVERT) == NULLAGBLOCK) {
+ if (be32_to_cpu(block->bb_leftsib) == NULLAGBLOCK) {
*stat = 0;
return 0;
}
@@ -1739,7 +1725,7 @@ xfs_inobt_decrement(
xfs_agblock_t agbno; /* block number of btree block */
xfs_buf_t *bp; /* buffer containing btree block */
- agbno = INT_GET(*XFS_INOBT_PTR_ADDR(block, cur->bc_ptrs[lev], cur), ARCH_CONVERT);
+ agbno = be32_to_cpu(*XFS_INOBT_PTR_ADDR(block, cur->bc_ptrs[lev], cur));
if ((error = xfs_btree_read_bufs(cur->bc_mp, cur->bc_tp,
cur->bc_private.i.agno, agbno, 0, &bp,
XFS_INO_BTREE_REF)))
@@ -1749,7 +1735,7 @@ xfs_inobt_decrement(
block = XFS_BUF_TO_INOBT_BLOCK(bp);
if ((error = xfs_btree_check_sblock(cur, block, lev, bp)))
return error;
- cur->bc_ptrs[lev] = INT_GET(block->bb_numrecs, ARCH_CONVERT);
+ cur->bc_ptrs[lev] = be16_to_cpu(block->bb_numrecs);
}
*stat = 1;
return 0;
@@ -1821,7 +1807,7 @@ xfs_inobt_get_rec(
/*
* Off the right end or left end, return failure.
*/
- if (ptr > INT_GET(block->bb_numrecs, ARCH_CONVERT) || ptr <= 0) {
+ if (ptr > be16_to_cpu(block->bb_numrecs) || ptr <= 0) {
*stat = 0;
return 0;
}
@@ -1869,14 +1855,14 @@ xfs_inobt_increment(
* Increment the ptr at this level. If we're still in the block
* then we're done.
*/
- if (++cur->bc_ptrs[level] <= INT_GET(block->bb_numrecs, ARCH_CONVERT)) {
+ if (++cur->bc_ptrs[level] <= be16_to_cpu(block->bb_numrecs)) {
*stat = 1;
return 0;
}
/*
* If we just went off the right edge of the tree, return failure.
*/
- if (INT_GET(block->bb_rightsib, ARCH_CONVERT) == NULLAGBLOCK) {
+ if (be32_to_cpu(block->bb_rightsib) == NULLAGBLOCK) {
*stat = 0;
return 0;
}
@@ -1891,7 +1877,7 @@ xfs_inobt_increment(
if ((error = xfs_btree_check_sblock(cur, block, lev, bp)))
return error;
#endif
- if (++cur->bc_ptrs[lev] <= INT_GET(block->bb_numrecs, ARCH_CONVERT))
+ if (++cur->bc_ptrs[lev] <= be16_to_cpu(block->bb_numrecs))
break;
/*
* Read-ahead the right block, we're going to read it
@@ -1911,7 +1897,7 @@ xfs_inobt_increment(
lev > level; ) {
xfs_agblock_t agbno; /* block number of btree block */
- agbno = INT_GET(*XFS_INOBT_PTR_ADDR(block, cur->bc_ptrs[lev], cur), ARCH_CONVERT);
+ agbno = be32_to_cpu(*XFS_INOBT_PTR_ADDR(block, cur->bc_ptrs[lev], cur));
if ((error = xfs_btree_read_bufs(cur->bc_mp, cur->bc_tp,
cur->bc_private.i.agno, agbno, 0, &bp,
XFS_INO_BTREE_REF)))
diff --git a/fs/xfs/xfs_ialloc_btree.h b/fs/xfs/xfs_ialloc_btree.h
index 44be188674a6..ae3904cb1ee8 100644
--- a/fs/xfs/xfs_ialloc_btree.h
+++ b/fs/xfs/xfs_ialloc_btree.h
@@ -1,33 +1,19 @@
/*
- * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000,2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __XFS_IALLOC_BTREE_H__
#define __XFS_IALLOC_BTREE_H__
@@ -51,14 +37,12 @@ typedef __uint64_t xfs_inofree_t;
#define XFS_INODES_PER_CHUNK_LOG (XFS_NBBYLOG + 3)
#define XFS_INOBT_ALL_FREE ((xfs_inofree_t)-1)
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_INOBT_MASKN)
-xfs_inofree_t xfs_inobt_maskn(int i, int n);
#define XFS_INOBT_MASKN(i,n) xfs_inobt_maskn(i,n)
-#else
-#define XFS_INOBT_MASKN(i,n) \
- ((((n) >= XFS_INODES_PER_CHUNK ? \
- (xfs_inofree_t)0 : ((xfs_inofree_t)1 << (n))) - 1) << (i))
-#endif
+static inline xfs_inofree_t xfs_inobt_maskn(int i, int n)
+{
+ return (((n) >= XFS_INODES_PER_CHUNK ? \
+ (xfs_inofree_t)0 : ((xfs_inofree_t)1 << (n))) - 1) << (i);
+}
/*
* Data record structure
@@ -78,241 +62,116 @@ typedef struct xfs_inobt_key
xfs_agino_t ir_startino; /* starting inode number */
} xfs_inobt_key_t;
-typedef xfs_agblock_t xfs_inobt_ptr_t; /* btree pointer type */
- /* btree block header type */
+/* btree pointer type */
+typedef __be32 xfs_inobt_ptr_t;
+
+/* btree block header type */
typedef struct xfs_btree_sblock xfs_inobt_block_t;
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_BUF_TO_INOBT_BLOCK)
-xfs_inobt_block_t *xfs_buf_to_inobt_block(struct xfs_buf *bp);
-#define XFS_BUF_TO_INOBT_BLOCK(bp) xfs_buf_to_inobt_block(bp)
-#else
-#define XFS_BUF_TO_INOBT_BLOCK(bp) ((xfs_inobt_block_t *)(XFS_BUF_PTR(bp)))
-#endif
+#define XFS_BUF_TO_INOBT_BLOCK(bp) ((xfs_inobt_block_t *)XFS_BUF_PTR(bp))
/*
* Bit manipulations for ir_free.
*/
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_INOBT_MASK)
-xfs_inofree_t xfs_inobt_mask(int i);
-#define XFS_INOBT_MASK(i) xfs_inobt_mask(i)
-#else
#define XFS_INOBT_MASK(i) ((xfs_inofree_t)1 << (i))
-#endif
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_INOBT_IS_FREE)
-int xfs_inobt_is_free(xfs_inobt_rec_t *rp, int i);
-#define XFS_INOBT_IS_FREE(rp,i) xfs_inobt_is_free(rp,i)
-#define XFS_INOBT_IS_FREE_DISK(rp,i) xfs_inobt_is_free_disk(rp,i)
-#else
-#define XFS_INOBT_IS_FREE(rp,i) \
- (((rp)->ir_free & XFS_INOBT_MASK(i)) != 0)
-#define XFS_INOBT_IS_FREE_DISK(rp,i) \
- ((INT_GET((rp)->ir_free, ARCH_CONVERT) & XFS_INOBT_MASK(i)) != 0)
-#endif
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_INOBT_SET_FREE)
-void xfs_inobt_set_free(xfs_inobt_rec_t *rp, int i);
-#define XFS_INOBT_SET_FREE(rp,i) xfs_inobt_set_free(rp,i)
-#else
+#define XFS_INOBT_IS_FREE(rp,i) \
+ (((rp)->ir_free & XFS_INOBT_MASK(i)) != 0)
+#define XFS_INOBT_IS_FREE_DISK(rp,i) \
+ ((INT_GET((rp)->ir_free,ARCH_CONVERT) & XFS_INOBT_MASK(i)) != 0)
#define XFS_INOBT_SET_FREE(rp,i) ((rp)->ir_free |= XFS_INOBT_MASK(i))
-#endif
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_INOBT_CLR_FREE)
-void xfs_inobt_clr_free(xfs_inobt_rec_t *rp, int i);
-#define XFS_INOBT_CLR_FREE(rp,i) xfs_inobt_clr_free(rp,i)
-#else
#define XFS_INOBT_CLR_FREE(rp,i) ((rp)->ir_free &= ~XFS_INOBT_MASK(i))
-#endif
/*
* Real block structures have a size equal to the disk block size.
*/
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_INOBT_BLOCK_SIZE)
-int xfs_inobt_block_size(int lev, struct xfs_btree_cur *cur);
-#define XFS_INOBT_BLOCK_SIZE(lev,cur) xfs_inobt_block_size(lev,cur)
-#else
#define XFS_INOBT_BLOCK_SIZE(lev,cur) (1 << (cur)->bc_blocklog)
-#endif
-
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_INOBT_BLOCK_MAXRECS)
-int xfs_inobt_block_maxrecs(int lev, struct xfs_btree_cur *cur);
-#define XFS_INOBT_BLOCK_MAXRECS(lev,cur) xfs_inobt_block_maxrecs(lev,cur)
-#else
-#define XFS_INOBT_BLOCK_MAXRECS(lev,cur) \
- ((cur)->bc_mp->m_inobt_mxr[lev != 0])
-#endif
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_INOBT_BLOCK_MINRECS)
-int xfs_inobt_block_minrecs(int lev, struct xfs_btree_cur *cur);
-#define XFS_INOBT_BLOCK_MINRECS(lev,cur) xfs_inobt_block_minrecs(lev,cur)
-#else
-#define XFS_INOBT_BLOCK_MINRECS(lev,cur) \
- ((cur)->bc_mp->m_inobt_mnr[lev != 0])
-#endif
-
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_INOBT_IS_LAST_REC)
-int xfs_inobt_is_last_rec(struct xfs_btree_cur *cur);
-#define XFS_INOBT_IS_LAST_REC(cur) xfs_inobt_is_last_rec(cur)
-#else
+#define XFS_INOBT_BLOCK_MAXRECS(lev,cur) ((cur)->bc_mp->m_inobt_mxr[lev != 0])
+#define XFS_INOBT_BLOCK_MINRECS(lev,cur) ((cur)->bc_mp->m_inobt_mnr[lev != 0])
#define XFS_INOBT_IS_LAST_REC(cur) \
- ((cur)->bc_ptrs[0] == \
- INT_GET(XFS_BUF_TO_INOBT_BLOCK((cur)->bc_bufs[0])->bb_numrecs, ARCH_CONVERT))
-#endif
+ ((cur)->bc_ptrs[0] == be16_to_cpu(XFS_BUF_TO_INOBT_BLOCK((cur)->bc_bufs[0])->bb_numrecs))
/*
* Maximum number of inode btree levels.
*/
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_IN_MAXLEVELS)
-int xfs_in_maxlevels(struct xfs_mount *mp);
-#define XFS_IN_MAXLEVELS(mp) xfs_in_maxlevels(mp)
-#else
#define XFS_IN_MAXLEVELS(mp) ((mp)->m_in_maxlevels)
-#endif
/*
* block numbers in the AG.
*/
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_IBT_BLOCK)
-xfs_agblock_t xfs_ibt_block(struct xfs_mount *mp);
-#define XFS_IBT_BLOCK(mp) xfs_ibt_block(mp)
-#else
-#define XFS_IBT_BLOCK(mp) ((xfs_agblock_t)(XFS_CNT_BLOCK(mp) + 1))
-#endif
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_PREALLOC_BLOCKS)
-xfs_agblock_t xfs_prealloc_blocks(struct xfs_mount *mp);
-#define XFS_PREALLOC_BLOCKS(mp) xfs_prealloc_blocks(mp)
-#else
-#define XFS_PREALLOC_BLOCKS(mp) ((xfs_agblock_t)(XFS_IBT_BLOCK(mp) + 1))
-#endif
+#define XFS_IBT_BLOCK(mp) ((xfs_agblock_t)(XFS_CNT_BLOCK(mp) + 1))
+#define XFS_PREALLOC_BLOCKS(mp) ((xfs_agblock_t)(XFS_IBT_BLOCK(mp) + 1))
/*
* Record, key, and pointer address macros for btree blocks.
*/
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_INOBT_REC_ADDR)
-xfs_inobt_rec_t *
-xfs_inobt_rec_addr(xfs_inobt_block_t *bb, int i, struct xfs_btree_cur *cur);
-#define XFS_INOBT_REC_ADDR(bb,i,cur) xfs_inobt_rec_addr(bb,i,cur)
-#else
-#define XFS_INOBT_REC_ADDR(bb,i,cur) \
- XFS_BTREE_REC_ADDR(XFS_INOBT_BLOCK_SIZE(0,cur), xfs_inobt, bb, i, \
- XFS_INOBT_BLOCK_MAXRECS(0, cur))
-#endif
-
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_INOBT_KEY_ADDR)
-xfs_inobt_key_t *
-xfs_inobt_key_addr(xfs_inobt_block_t *bb, int i, struct xfs_btree_cur *cur);
-#define XFS_INOBT_KEY_ADDR(bb,i,cur) xfs_inobt_key_addr(bb,i,cur)
-#else
-#define XFS_INOBT_KEY_ADDR(bb,i,cur) \
- XFS_BTREE_KEY_ADDR(XFS_INOBT_BLOCK_SIZE(1,cur), xfs_inobt, bb, i, \
- XFS_INOBT_BLOCK_MAXRECS(1, cur))
-#endif
+#define XFS_INOBT_REC_ADDR(bb,i,cur) \
+ (XFS_BTREE_REC_ADDR(XFS_INOBT_BLOCK_SIZE(0,cur), xfs_inobt, bb, \
+ i, XFS_INOBT_BLOCK_MAXRECS(0, cur)))
+#define XFS_INOBT_KEY_ADDR(bb,i,cur) \
+ (XFS_BTREE_KEY_ADDR(XFS_INOBT_BLOCK_SIZE(1,cur), xfs_inobt, bb, \
+ i, XFS_INOBT_BLOCK_MAXRECS(1, cur)))
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_INOBT_PTR_ADDR)
-xfs_inobt_ptr_t *
-xfs_inobt_ptr_addr(xfs_inobt_block_t *bb, int i, struct xfs_btree_cur *cur);
-#define XFS_INOBT_PTR_ADDR(bb,i,cur) xfs_inobt_ptr_addr(bb,i,cur)
-#else
-#define XFS_INOBT_PTR_ADDR(bb,i,cur) \
- XFS_BTREE_PTR_ADDR(XFS_INOBT_BLOCK_SIZE(1,cur), xfs_inobt, bb, i, \
- XFS_INOBT_BLOCK_MAXRECS(1, cur))
-#endif
-
-/*
- * Prototypes for externally visible routines.
- */
+#define XFS_INOBT_PTR_ADDR(bb,i,cur) \
+ (XFS_BTREE_PTR_ADDR(XFS_INOBT_BLOCK_SIZE(1,cur), xfs_inobt, bb, \
+ i, XFS_INOBT_BLOCK_MAXRECS(1, cur)))
/*
* Decrement cursor by one record at the level.
* For nonzero levels the leaf-ward information is untouched.
*/
-int /* error */
-xfs_inobt_decrement(
- struct xfs_btree_cur *cur, /* btree cursor */
- int level, /* level in btree, 0 is leaf */
- int *stat); /* success/failure */
+extern int xfs_inobt_decrement(struct xfs_btree_cur *cur, int level, int *stat);
/*
* Delete the record pointed to by cur.
* The cursor refers to the place where the record was (could be inserted)
* when the operation returns.
*/
-int /* error */
-xfs_inobt_delete(
- struct xfs_btree_cur *cur, /* btree cursor */
- int *stat); /* success/failure */
+extern int xfs_inobt_delete(struct xfs_btree_cur *cur, int *stat);
/*
* Get the data from the pointed-to record.
*/
-int /* error */
-xfs_inobt_get_rec(
- struct xfs_btree_cur *cur, /* btree cursor */
- xfs_agino_t *ino, /* output: starting inode of chunk */
- __int32_t *fcnt, /* output: number of free inodes */
- xfs_inofree_t *free, /* output: free inode mask */
- int *stat); /* output: success/failure */
+extern int xfs_inobt_get_rec(struct xfs_btree_cur *cur, xfs_agino_t *ino,
+ __int32_t *fcnt, xfs_inofree_t *free, int *stat);
/*
* Increment cursor by one record at the level.
* For nonzero levels the leaf-ward information is untouched.
*/
-int /* error */
-xfs_inobt_increment(
- struct xfs_btree_cur *cur, /* btree cursor */
- int level, /* level in btree, 0 is leaf */
- int *stat); /* success/failure */
+extern int xfs_inobt_increment(struct xfs_btree_cur *cur, int level, int *stat);
/*
* Insert the current record at the point referenced by cur.
* The cursor may be inconsistent on return if splits have been done.
*/
-int /* error */
-xfs_inobt_insert(
- struct xfs_btree_cur *cur, /* btree cursor */
- int *stat); /* success/failure */
+extern int xfs_inobt_insert(struct xfs_btree_cur *cur, int *stat);
/*
* Lookup the record equal to ino in the btree given by cur.
*/
-int /* error */
-xfs_inobt_lookup_eq(
- struct xfs_btree_cur *cur, /* btree cursor */
- xfs_agino_t ino, /* starting inode of chunk */
- __int32_t fcnt, /* free inode count */
- xfs_inofree_t free, /* free inode mask */
- int *stat); /* success/failure */
+extern int xfs_inobt_lookup_eq(struct xfs_btree_cur *cur, xfs_agino_t ino,
+ __int32_t fcnt, xfs_inofree_t free, int *stat);
/*
* Lookup the first record greater than or equal to ino
* in the btree given by cur.
*/
-int /* error */
-xfs_inobt_lookup_ge(
- struct xfs_btree_cur *cur, /* btree cursor */
- xfs_agino_t ino, /* starting inode of chunk */
- __int32_t fcnt, /* free inode count */
- xfs_inofree_t free, /* free inode mask */
- int *stat); /* success/failure */
+extern int xfs_inobt_lookup_ge(struct xfs_btree_cur *cur, xfs_agino_t ino,
+ __int32_t fcnt, xfs_inofree_t free, int *stat);
/*
* Lookup the first record less than or equal to ino
* in the btree given by cur.
*/
-int /* error */
-xfs_inobt_lookup_le(
- struct xfs_btree_cur *cur, /* btree cursor */
- xfs_agino_t ino, /* starting inode of chunk */
- __int32_t fcnt, /* free inode count */
- xfs_inofree_t free, /* free inode mask */
- int *stat); /* success/failure */
+extern int xfs_inobt_lookup_le(struct xfs_btree_cur *cur, xfs_agino_t ino,
+ __int32_t fcnt, xfs_inofree_t free, int *stat);
/*
* Update the record referred to by cur, to the value given
* by [ino, fcnt, free].
* This either works (return 0) or gets an EFSCORRUPTED error.
*/
-int /* error */
-xfs_inobt_update(
- struct xfs_btree_cur *cur, /* btree cursor */
- xfs_agino_t ino, /* starting inode of chunk */
- __int32_t fcnt, /* free inode count */
- xfs_inofree_t free); /* free inode mask */
+extern int xfs_inobt_update(struct xfs_btree_cur *cur, xfs_agino_t ino,
+ __int32_t fcnt, xfs_inofree_t free);
#endif /* __XFS_IALLOC_BTREE_H__ */
diff --git a/fs/xfs/xfs_iget.c b/fs/xfs/xfs_iget.c
index 0d9ae8fb4138..fc19eedbd11b 100644
--- a/fs/xfs/xfs_iget.c
+++ b/fs/xfs/xfs_iget.c
@@ -1,43 +1,26 @@
/*
- * Copyright (c) 2000-2005 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-
-#include <linux/delay.h>
-
#include "xfs.h"
-
-#include "xfs_macros.h"
+#include "xfs_fs.h"
#include "xfs_types.h"
-#include "xfs_inum.h"
+#include "xfs_bit.h"
#include "xfs_log.h"
+#include "xfs_inum.h"
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
@@ -45,19 +28,18 @@
#include "xfs_dir2.h"
#include "xfs_dmapi.h"
#include "xfs_mount.h"
-#include "xfs_alloc_btree.h"
#include "xfs_bmap_btree.h"
+#include "xfs_alloc_btree.h"
#include "xfs_ialloc_btree.h"
-#include "xfs_btree.h"
-#include "xfs_ialloc.h"
-#include "xfs_attr_sf.h"
#include "xfs_dir_sf.h"
#include "xfs_dir2_sf.h"
+#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
#include "xfs_inode.h"
+#include "xfs_btree.h"
+#include "xfs_ialloc.h"
#include "xfs_quota.h"
#include "xfs_utils.h"
-#include "xfs_bit.h"
/*
* Initialize the inode hash table for the newly mounted file system.
diff --git a/fs/xfs/xfs_imap.h b/fs/xfs/xfs_imap.h
index e385064a066a..d36450003983 100644
--- a/fs/xfs/xfs_imap.h
+++ b/fs/xfs/xfs_imap.h
@@ -1,33 +1,19 @@
/*
- * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000,2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __XFS_IMAP_H__
#define __XFS_IMAP_H__
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
index db43308aae93..df0d4572d70a 100644
--- a/fs/xfs/xfs_inode.c
+++ b/fs/xfs/xfs_inode.c
@@ -1,40 +1,27 @@
/*
- * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-
#include "xfs.h"
-#include "xfs_macros.h"
+#include "xfs_fs.h"
#include "xfs_types.h"
-#include "xfs_inum.h"
+#include "xfs_bit.h"
#include "xfs_log.h"
+#include "xfs_inum.h"
+#include "xfs_imap.h"
#include "xfs_trans.h"
#include "xfs_trans_priv.h"
#include "xfs_sb.h"
@@ -43,24 +30,22 @@
#include "xfs_dir2.h"
#include "xfs_dmapi.h"
#include "xfs_mount.h"
-#include "xfs_alloc_btree.h"
#include "xfs_bmap_btree.h"
+#include "xfs_alloc_btree.h"
#include "xfs_ialloc_btree.h"
-#include "xfs_btree.h"
-#include "xfs_imap.h"
-#include "xfs_alloc.h"
-#include "xfs_ialloc.h"
-#include "xfs_attr_sf.h"
#include "xfs_dir_sf.h"
#include "xfs_dir2_sf.h"
+#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
-#include "xfs_inode_item.h"
#include "xfs_inode.h"
-#include "xfs_bmap.h"
#include "xfs_buf_item.h"
+#include "xfs_inode_item.h"
+#include "xfs_btree.h"
+#include "xfs_alloc.h"
+#include "xfs_ialloc.h"
+#include "xfs_bmap.h"
#include "xfs_rw.h"
#include "xfs_error.h"
-#include "xfs_bit.h"
#include "xfs_utils.h"
#include "xfs_dir2_trace.h"
#include "xfs_quota.h"
@@ -194,9 +179,10 @@ xfs_inotobp(
if ((imap.im_blkno + imap.im_len) >
XFS_FSB_TO_BB(mp, mp->m_sb.sb_dblocks)) {
cmn_err(CE_WARN,
- "xfs_inotobp: inode number (%d + %d) maps to a block outside the bounds "
+ "xfs_inotobp: inode number (%llu + %d) maps to a block outside the bounds "
"of the file system %s. Returning EINVAL.",
- imap.im_blkno, imap.im_len,mp->m_fsname);
+ (unsigned long long)imap.im_blkno,
+ imap.im_len, mp->m_fsname);
return XFS_ERROR(EINVAL);
}
@@ -1878,8 +1864,8 @@ xfs_iunlink(
*/
agi = XFS_BUF_TO_AGI(agibp);
agi_ok =
- INT_GET(agi->agi_magicnum, ARCH_CONVERT) == XFS_AGI_MAGIC &&
- XFS_AGI_GOOD_VERSION(INT_GET(agi->agi_versionnum, ARCH_CONVERT));
+ be32_to_cpu(agi->agi_magicnum) == XFS_AGI_MAGIC &&
+ XFS_AGI_GOOD_VERSION(be32_to_cpu(agi->agi_versionnum));
if (unlikely(XFS_TEST_ERROR(!agi_ok, mp, XFS_ERRTAG_IUNLINK,
XFS_RANDOM_IUNLINK))) {
XFS_CORRUPTION_ERROR("xfs_iunlink", XFS_ERRLEVEL_LOW, mp, agi);
@@ -1894,9 +1880,9 @@ xfs_iunlink(
ASSERT(agino != 0);
bucket_index = agino % XFS_AGI_UNLINKED_BUCKETS;
ASSERT(agi->agi_unlinked[bucket_index]);
- ASSERT(INT_GET(agi->agi_unlinked[bucket_index], ARCH_CONVERT) != agino);
+ ASSERT(be32_to_cpu(agi->agi_unlinked[bucket_index]) != agino);
- if (INT_GET(agi->agi_unlinked[bucket_index], ARCH_CONVERT) != NULLAGINO) {
+ if (be32_to_cpu(agi->agi_unlinked[bucket_index]) != NULLAGINO) {
/*
* There is already another inode in the bucket we need
* to add ourselves to. Add us at the front of the list.
@@ -1923,7 +1909,7 @@ xfs_iunlink(
* Point the bucket head pointer at the inode being inserted.
*/
ASSERT(agino != 0);
- INT_SET(agi->agi_unlinked[bucket_index], ARCH_CONVERT, agino);
+ agi->agi_unlinked[bucket_index] = cpu_to_be32(agino);
offset = offsetof(xfs_agi_t, agi_unlinked) +
(sizeof(xfs_agino_t) * bucket_index);
xfs_trans_log_buf(tp, agibp, offset,
@@ -1981,8 +1967,8 @@ xfs_iunlink_remove(
*/
agi = XFS_BUF_TO_AGI(agibp);
agi_ok =
- INT_GET(agi->agi_magicnum, ARCH_CONVERT) == XFS_AGI_MAGIC &&
- XFS_AGI_GOOD_VERSION(INT_GET(agi->agi_versionnum, ARCH_CONVERT));
+ be32_to_cpu(agi->agi_magicnum) == XFS_AGI_MAGIC &&
+ XFS_AGI_GOOD_VERSION(be32_to_cpu(agi->agi_versionnum));
if (unlikely(XFS_TEST_ERROR(!agi_ok, mp, XFS_ERRTAG_IUNLINK_REMOVE,
XFS_RANDOM_IUNLINK_REMOVE))) {
XFS_CORRUPTION_ERROR("xfs_iunlink_remove", XFS_ERRLEVEL_LOW,
@@ -2000,10 +1986,10 @@ xfs_iunlink_remove(
agino = XFS_INO_TO_AGINO(mp, ip->i_ino);
ASSERT(agino != 0);
bucket_index = agino % XFS_AGI_UNLINKED_BUCKETS;
- ASSERT(INT_GET(agi->agi_unlinked[bucket_index], ARCH_CONVERT) != NULLAGINO);
+ ASSERT(be32_to_cpu(agi->agi_unlinked[bucket_index]) != NULLAGINO);
ASSERT(agi->agi_unlinked[bucket_index]);
- if (INT_GET(agi->agi_unlinked[bucket_index], ARCH_CONVERT) == agino) {
+ if (be32_to_cpu(agi->agi_unlinked[bucket_index]) == agino) {
/*
* We're at the head of the list. Get the inode's
* on-disk buffer to see if there is anyone after us
@@ -2037,7 +2023,7 @@ xfs_iunlink_remove(
*/
ASSERT(next_agino != 0);
ASSERT(next_agino != agino);
- INT_SET(agi->agi_unlinked[bucket_index], ARCH_CONVERT, next_agino);
+ agi->agi_unlinked[bucket_index] = cpu_to_be32(next_agino);
offset = offsetof(xfs_agi_t, agi_unlinked) +
(sizeof(xfs_agino_t) * bucket_index);
xfs_trans_log_buf(tp, agibp, offset,
@@ -2046,7 +2032,7 @@ xfs_iunlink_remove(
/*
* We need to search the list for the inode being freed.
*/
- next_agino = INT_GET(agi->agi_unlinked[bucket_index], ARCH_CONVERT);
+ next_agino = be32_to_cpu(agi->agi_unlinked[bucket_index]);
last_ibp = NULL;
while (next_agino != agino) {
/*
@@ -3687,73 +3673,6 @@ xfs_iroundup(
return( 0 );
}
-/*
- * Change the requested timestamp in the given inode.
- * We don't lock across timestamp updates, and we don't log them but
- * we do record the fact that there is dirty information in core.
- *
- * NOTE -- callers MUST combine XFS_ICHGTIME_MOD or XFS_ICHGTIME_CHG
- * with XFS_ICHGTIME_ACC to be sure that access time
- * update will take. Calling first with XFS_ICHGTIME_ACC
- * and then XFS_ICHGTIME_MOD may fail to modify the access
- * timestamp if the filesystem is mounted noacctm.
- */
-void
-xfs_ichgtime(xfs_inode_t *ip,
- int flags)
-{
- timespec_t tv;
- vnode_t *vp = XFS_ITOV(ip);
- struct inode *inode = LINVFS_GET_IP(vp);
-
- /*
- * We're not supposed to change timestamps in readonly-mounted
- * filesystems. Throw it away if anyone asks us.
- */
- if (unlikely(vp->v_vfsp->vfs_flag & VFS_RDONLY))
- return;
-
- /*
- * Don't update access timestamps on reads if mounted "noatime"
- * Throw it away if anyone asks us.
- */
- if ((ip->i_mount->m_flags & XFS_MOUNT_NOATIME || IS_NOATIME(inode)) &&
- ((flags & (XFS_ICHGTIME_ACC|XFS_ICHGTIME_MOD|XFS_ICHGTIME_CHG))
- == XFS_ICHGTIME_ACC))
- return;
-
- nanotime(&tv);
- if (flags & XFS_ICHGTIME_MOD) {
- VN_MTIMESET(vp, &tv);
- ip->i_d.di_mtime.t_sec = (__int32_t)tv.tv_sec;
- ip->i_d.di_mtime.t_nsec = (__int32_t)tv.tv_nsec;
- }
- if (flags & XFS_ICHGTIME_ACC) {
- VN_ATIMESET(vp, &tv);
- ip->i_d.di_atime.t_sec = (__int32_t)tv.tv_sec;
- ip->i_d.di_atime.t_nsec = (__int32_t)tv.tv_nsec;
- }
- if (flags & XFS_ICHGTIME_CHG) {
- VN_CTIMESET(vp, &tv);
- ip->i_d.di_ctime.t_sec = (__int32_t)tv.tv_sec;
- ip->i_d.di_ctime.t_nsec = (__int32_t)tv.tv_nsec;
- }
-
- /*
- * We update the i_update_core field _after_ changing
- * the timestamps in order to coordinate properly with
- * xfs_iflush() so that we don't lose timestamp updates.
- * This keeps us from having to hold the inode lock
- * while doing this. We use the SYNCHRONIZE macro to
- * ensure that the compiler does not reorder the update
- * of i_update_core above the timestamp updates above.
- */
- SYNCHRONIZE();
- ip->i_update_core = 1;
- if (!(inode->i_state & I_LOCK))
- mark_inode_dirty_sync(inode);
-}
-
#ifdef XFS_ILOCK_TRACE
ktrace_t *xfs_ilock_trace_buf;
diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h
index 54d9e54c7c95..124d30e6143b 100644
--- a/fs/xfs/xfs_inode.h
+++ b/fs/xfs/xfs_inode.h
@@ -1,38 +1,30 @@
/*
- * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __XFS_INODE_H__
#define __XFS_INODE_H__
/*
+ * Fork identifiers.
+ */
+#define XFS_DATA_FORK 0
+#define XFS_ATTR_FORK 1
+
+/*
* File incore extent information, present for each of data & attr forks.
*/
#define XFS_INLINE_EXTS 2
@@ -107,24 +99,6 @@ extern void xfs_ilock_trace(struct xfs_inode *, int, unsigned int, inst_t *);
#define xfs_ilock_trace(i,n,f,ra)
#endif
-/*
- * This structure is used to communicate which extents of a file
- * were holes when a write started from xfs_write_file() to
- * xfs_strat_read(). This is necessary so that we can know which
- * blocks need to be zeroed when they are read in in xfs_strat_read()
- * if they weren\'t allocated when the buffer given to xfs_strat_read()
- * was mapped.
- *
- * We keep a list of these attached to the inode. The list is
- * protected by the inode lock and the fact that the io lock is
- * held exclusively by writers.
- */
-typedef struct xfs_gap {
- struct xfs_gap *xg_next;
- xfs_fileoff_t xg_offset_fsb;
- xfs_extlen_t xg_count_fsb;
-} xfs_gap_t;
-
typedef struct dm_attrs_s {
__uint32_t da_dmevmask; /* DMIG event mask */
__uint16_t da_dmstate; /* DMIG state info */
@@ -311,60 +285,16 @@ typedef struct xfs_inode {
/*
* Fork handling.
*/
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_IFORK_PTR)
-xfs_ifork_t *xfs_ifork_ptr(xfs_inode_t *ip, int w);
-#define XFS_IFORK_PTR(ip,w) xfs_ifork_ptr(ip,w)
-#else
-#define XFS_IFORK_PTR(ip,w) ((w) == XFS_DATA_FORK ? &(ip)->i_df : (ip)->i_afp)
-#endif
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_IFORK_Q)
-int xfs_ifork_q(xfs_inode_t *ip);
-#define XFS_IFORK_Q(ip) xfs_ifork_q(ip)
-#else
+#define XFS_IFORK_PTR(ip,w) \
+ ((w) == XFS_DATA_FORK ? &(ip)->i_df : (ip)->i_afp)
#define XFS_IFORK_Q(ip) XFS_CFORK_Q(&(ip)->i_d)
-#endif
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_IFORK_DSIZE)
-int xfs_ifork_dsize(xfs_inode_t *ip);
-#define XFS_IFORK_DSIZE(ip) xfs_ifork_dsize(ip)
-#else
#define XFS_IFORK_DSIZE(ip) XFS_CFORK_DSIZE(&ip->i_d, ip->i_mount)
-#endif
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_IFORK_ASIZE)
-int xfs_ifork_asize(xfs_inode_t *ip);
-#define XFS_IFORK_ASIZE(ip) xfs_ifork_asize(ip)
-#else
#define XFS_IFORK_ASIZE(ip) XFS_CFORK_ASIZE(&ip->i_d, ip->i_mount)
-#endif
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_IFORK_SIZE)
-int xfs_ifork_size(xfs_inode_t *ip, int w);
-#define XFS_IFORK_SIZE(ip,w) xfs_ifork_size(ip,w)
-#else
#define XFS_IFORK_SIZE(ip,w) XFS_CFORK_SIZE(&ip->i_d, ip->i_mount, w)
-#endif
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_IFORK_FORMAT)
-int xfs_ifork_format(xfs_inode_t *ip, int w);
-#define XFS_IFORK_FORMAT(ip,w) xfs_ifork_format(ip,w)
-#else
#define XFS_IFORK_FORMAT(ip,w) XFS_CFORK_FORMAT(&ip->i_d, w)
-#endif
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_IFORK_FMT_SET)
-void xfs_ifork_fmt_set(xfs_inode_t *ip, int w, int n);
-#define XFS_IFORK_FMT_SET(ip,w,n) xfs_ifork_fmt_set(ip,w,n)
-#else
#define XFS_IFORK_FMT_SET(ip,w,n) XFS_CFORK_FMT_SET(&ip->i_d, w, n)
-#endif
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_IFORK_NEXTENTS)
-int xfs_ifork_nextents(xfs_inode_t *ip, int w);
-#define XFS_IFORK_NEXTENTS(ip,w) xfs_ifork_nextents(ip,w)
-#else
#define XFS_IFORK_NEXTENTS(ip,w) XFS_CFORK_NEXTENTS(&ip->i_d, w)
-#endif
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_IFORK_NEXT_SET)
-void xfs_ifork_next_set(xfs_inode_t *ip, int w, int n);
-#define XFS_IFORK_NEXT_SET(ip,w,n) xfs_ifork_next_set(ip,w,n)
-#else
#define XFS_IFORK_NEXT_SET(ip,w,n) XFS_CFORK_NEXT_SET(&ip->i_d, w, n)
-#endif
#ifdef __KERNEL__
@@ -388,6 +318,7 @@ void xfs_ifork_next_set(xfs_inode_t *ip, int w, int n);
#define XFS_ILOCK_EXCL 0x004
#define XFS_ILOCK_SHARED 0x008
#define XFS_IUNLOCK_NONOTIFY 0x010
+/* XFS_IOLOCK_NESTED 0x020 */
#define XFS_EXTENT_TOKEN_RD 0x040
#define XFS_SIZE_TOKEN_RD 0x080
#define XFS_EXTSIZE_RD (XFS_EXTENT_TOKEN_RD|XFS_SIZE_TOKEN_RD)
@@ -395,7 +326,7 @@ void xfs_ifork_next_set(xfs_inode_t *ip, int w, int n);
#define XFS_EXTENT_TOKEN_WR (XFS_EXTENT_TOKEN_RD | XFS_WILLLEND)
#define XFS_SIZE_TOKEN_WR (XFS_SIZE_TOKEN_RD | XFS_WILLLEND)
#define XFS_EXTSIZE_WR (XFS_EXTSIZE_RD | XFS_WILLLEND)
-
+/* XFS_SIZE_TOKEN_WANT 0x200 */
#define XFS_LOCK_MASK \
(XFS_IOLOCK_EXCL | XFS_IOLOCK_SHARED | XFS_ILOCK_EXCL | \
@@ -417,28 +348,11 @@ void xfs_ifork_next_set(xfs_inode_t *ip, int w, int n);
#define XFS_ITRUNC_DEFINITE 0x1
#define XFS_ITRUNC_MAYBE 0x2
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_ITOV)
-struct vnode *xfs_itov(xfs_inode_t *ip);
-#define XFS_ITOV(ip) xfs_itov(ip)
-#else
#define XFS_ITOV(ip) BHV_TO_VNODE(XFS_ITOBHV(ip))
-#endif
#define XFS_ITOV_NULL(ip) BHV_TO_VNODE_NULL(XFS_ITOBHV(ip))
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_ITOBHV)
-struct bhv_desc *xfs_itobhv(xfs_inode_t *ip);
-#define XFS_ITOBHV(ip) xfs_itobhv(ip)
-#else
#define XFS_ITOBHV(ip) ((struct bhv_desc *)(&((ip)->i_bhv_desc)))
-#endif
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_BHVTOI)
-xfs_inode_t *xfs_bhvtoi(struct bhv_desc *bhvp);
-#define XFS_BHVTOI(bhvp) xfs_bhvtoi(bhvp)
-#else
-#define XFS_BHVTOI(bhvp) \
- ((xfs_inode_t *)((char *)(bhvp) - \
- (char *)&(((xfs_inode_t *)0)->i_bhv_desc)))
-#endif
-
+#define XFS_BHVTOI(bhvp) ((xfs_inode_t *)((char *)(bhvp) - \
+ (char *)&(((xfs_inode_t *)0)->i_bhv_desc)))
#define BHV_IS_XFS(bdp) (BHV_OPS(bdp) == &xfs_vnodeops)
/*
diff --git a/fs/xfs/xfs_inode_item.c b/fs/xfs/xfs_inode_item.c
index 50e2cadf9091..7f3363c621e1 100644
--- a/fs/xfs/xfs_inode_item.c
+++ b/fs/xfs/xfs_inode_item.c
@@ -1,66 +1,46 @@
/*
- * Copyright (c) 2000-2002 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
- */
-
-/*
- * This file contains the implementation of the xfs_inode_log_item.
- * It contains the item operations used to manipulate the inode log
- * items as well as utility routines used by the inode specific
- * transaction routines.
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "xfs.h"
-#include "xfs_macros.h"
+#include "xfs_fs.h"
#include "xfs_types.h"
-#include "xfs_inum.h"
+#include "xfs_bit.h"
#include "xfs_log.h"
+#include "xfs_inum.h"
#include "xfs_trans.h"
#include "xfs_buf_item.h"
#include "xfs_sb.h"
+#include "xfs_ag.h"
#include "xfs_dir.h"
#include "xfs_dir2.h"
#include "xfs_dmapi.h"
#include "xfs_mount.h"
#include "xfs_trans_priv.h"
-#include "xfs_ag.h"
-#include "xfs_alloc_btree.h"
#include "xfs_bmap_btree.h"
+#include "xfs_alloc_btree.h"
#include "xfs_ialloc_btree.h"
-#include "xfs_btree.h"
-#include "xfs_ialloc.h"
-#include "xfs_attr_sf.h"
#include "xfs_dir_sf.h"
#include "xfs_dir2_sf.h"
+#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
-#include "xfs_inode_item.h"
#include "xfs_inode.h"
+#include "xfs_inode_item.h"
+#include "xfs_btree.h"
+#include "xfs_ialloc.h"
#include "xfs_rw.h"
diff --git a/fs/xfs/xfs_inode_item.h b/fs/xfs/xfs_inode_item.h
index d8775e0d6291..c5dbf93b6661 100644
--- a/fs/xfs/xfs_inode_item.h
+++ b/fs/xfs/xfs_inode_item.h
@@ -1,33 +1,19 @@
/*
- * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000,2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __XFS_INODE_ITEM_H__
#define __XFS_INODE_ITEM_H__
@@ -159,38 +145,33 @@ typedef struct xfs_inode_log_item {
} xfs_inode_log_item_t;
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_ILOG_FDATA)
-int xfs_ilog_fdata(int w);
#define XFS_ILOG_FDATA(w) xfs_ilog_fdata(w)
-#else
-#define XFS_ILOG_FDATA(w) \
- ((w) == XFS_DATA_FORK ? XFS_ILOG_DDATA : XFS_ILOG_ADATA)
-#endif
+static inline int xfs_ilog_fdata(int w)
+{
+ return (w == XFS_DATA_FORK ? XFS_ILOG_DDATA : XFS_ILOG_ADATA);
+}
#endif /* __KERNEL__ */
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_ILOG_FBROOT)
-int xfs_ilog_fbroot(int w);
#define XFS_ILOG_FBROOT(w) xfs_ilog_fbroot(w)
-#else
-#define XFS_ILOG_FBROOT(w) \
- ((w) == XFS_DATA_FORK ? XFS_ILOG_DBROOT : XFS_ILOG_ABROOT)
-#endif
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_ILOG_FEXT)
-int xfs_ilog_fext(int w);
+static inline int xfs_ilog_fbroot(int w)
+{
+ return (w == XFS_DATA_FORK ? XFS_ILOG_DBROOT : XFS_ILOG_ABROOT);
+}
+
#define XFS_ILOG_FEXT(w) xfs_ilog_fext(w)
-#else
-#define XFS_ILOG_FEXT(w) \
- ((w) == XFS_DATA_FORK ? XFS_ILOG_DEXT : XFS_ILOG_AEXT)
-#endif
+static inline int xfs_ilog_fext(int w)
+{
+ return (w == XFS_DATA_FORK ? XFS_ILOG_DEXT : XFS_ILOG_AEXT);
+}
#ifdef __KERNEL__
-void xfs_inode_item_init(struct xfs_inode *, struct xfs_mount *);
-void xfs_inode_item_destroy(struct xfs_inode *);
-void xfs_iflush_done(struct xfs_buf *, xfs_inode_log_item_t *);
-void xfs_istale_done(struct xfs_buf *, xfs_inode_log_item_t *);
-void xfs_iflush_abort(struct xfs_inode *);
+extern void xfs_inode_item_init(struct xfs_inode *, struct xfs_mount *);
+extern void xfs_inode_item_destroy(struct xfs_inode *);
+extern void xfs_iflush_done(struct xfs_buf *, xfs_inode_log_item_t *);
+extern void xfs_istale_done(struct xfs_buf *, xfs_inode_log_item_t *);
+extern void xfs_iflush_abort(struct xfs_inode *);
#endif /* __KERNEL__ */
diff --git a/fs/xfs/xfs_inum.h b/fs/xfs/xfs_inum.h
index a3af2d5a6eb7..7a28191cb0de 100644
--- a/fs/xfs/xfs_inum.h
+++ b/fs/xfs/xfs_inum.h
@@ -1,33 +1,19 @@
/*
- * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __XFS_INUM_H__
#define __XFS_INUM_H__
@@ -58,109 +44,31 @@ typedef __uint32_t xfs_intino_t;
struct xfs_mount;
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_INO_MASK)
-__uint32_t xfs_ino_mask(int k);
-#define XFS_INO_MASK(k) xfs_ino_mask(k)
-#else
-#define XFS_INO_MASK(k) ((__uint32_t)((1ULL << (k)) - 1))
-#endif
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_INO_OFFSET_BITS)
-int xfs_ino_offset_bits(struct xfs_mount *mp);
-#define XFS_INO_OFFSET_BITS(mp) xfs_ino_offset_bits(mp)
-#else
-#define XFS_INO_OFFSET_BITS(mp) ((mp)->m_sb.sb_inopblog)
-#endif
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_INO_AGBNO_BITS)
-int xfs_ino_agbno_bits(struct xfs_mount *mp);
-#define XFS_INO_AGBNO_BITS(mp) xfs_ino_agbno_bits(mp)
-#else
-#define XFS_INO_AGBNO_BITS(mp) ((mp)->m_sb.sb_agblklog)
-#endif
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_INO_AGINO_BITS)
-int xfs_ino_agino_bits(struct xfs_mount *mp);
-#define XFS_INO_AGINO_BITS(mp) xfs_ino_agino_bits(mp)
-#else
-#define XFS_INO_AGINO_BITS(mp) ((mp)->m_agino_log)
-#endif
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_INO_AGNO_BITS)
-int xfs_ino_agno_bits(struct xfs_mount *mp);
-#define XFS_INO_AGNO_BITS(mp) xfs_ino_agno_bits(mp)
-#else
-#define XFS_INO_AGNO_BITS(mp) ((mp)->m_agno_log)
-#endif
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_INO_BITS)
-int xfs_ino_bits(struct xfs_mount *mp);
-#define XFS_INO_BITS(mp) xfs_ino_bits(mp)
-#else
-#define XFS_INO_BITS(mp) (XFS_INO_AGNO_BITS(mp) + XFS_INO_AGINO_BITS(mp))
-#endif
-
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_INO_TO_AGNO)
-xfs_agnumber_t xfs_ino_to_agno(struct xfs_mount *mp, xfs_ino_t i);
-#define XFS_INO_TO_AGNO(mp,i) xfs_ino_to_agno(mp,i)
-#else
-#define XFS_INO_TO_AGNO(mp,i) \
+#define XFS_INO_MASK(k) (__uint32_t)((1ULL << (k)) - 1)
+#define XFS_INO_OFFSET_BITS(mp) (mp)->m_sb.sb_inopblog
+#define XFS_INO_AGBNO_BITS(mp) (mp)->m_sb.sb_agblklog
+#define XFS_INO_AGINO_BITS(mp) (mp)->m_agino_log
+#define XFS_INO_AGNO_BITS(mp) (mp)->m_agno_log
+#define XFS_INO_BITS(mp) \
+ XFS_INO_AGNO_BITS(mp) + XFS_INO_AGINO_BITS(mp)
+#define XFS_INO_TO_AGNO(mp,i) \
((xfs_agnumber_t)((i) >> XFS_INO_AGINO_BITS(mp)))
-#endif
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_INO_TO_AGINO)
-xfs_agino_t xfs_ino_to_agino(struct xfs_mount *mp, xfs_ino_t i);
-#define XFS_INO_TO_AGINO(mp,i) xfs_ino_to_agino(mp,i)
-#else
-#define XFS_INO_TO_AGINO(mp,i) \
+#define XFS_INO_TO_AGINO(mp,i) \
((xfs_agino_t)(i) & XFS_INO_MASK(XFS_INO_AGINO_BITS(mp)))
-#endif
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_INO_TO_AGBNO)
-xfs_agblock_t xfs_ino_to_agbno(struct xfs_mount *mp, xfs_ino_t i);
-#define XFS_INO_TO_AGBNO(mp,i) xfs_ino_to_agbno(mp,i)
-#else
-#define XFS_INO_TO_AGBNO(mp,i) \
+#define XFS_INO_TO_AGBNO(mp,i) \
(((xfs_agblock_t)(i) >> XFS_INO_OFFSET_BITS(mp)) & \
- XFS_INO_MASK(XFS_INO_AGBNO_BITS(mp)))
-#endif
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_INO_TO_OFFSET)
-int xfs_ino_to_offset(struct xfs_mount *mp, xfs_ino_t i);
-#define XFS_INO_TO_OFFSET(mp,i) xfs_ino_to_offset(mp,i)
-#else
-#define XFS_INO_TO_OFFSET(mp,i) \
+ XFS_INO_MASK(XFS_INO_AGBNO_BITS(mp)))
+#define XFS_INO_TO_OFFSET(mp,i) \
((int)(i) & XFS_INO_MASK(XFS_INO_OFFSET_BITS(mp)))
-#endif
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_INO_TO_FSB)
-xfs_fsblock_t xfs_ino_to_fsb(struct xfs_mount *mp, xfs_ino_t i);
-#define XFS_INO_TO_FSB(mp,i) xfs_ino_to_fsb(mp,i)
-#else
-#define XFS_INO_TO_FSB(mp,i) \
+#define XFS_INO_TO_FSB(mp,i) \
XFS_AGB_TO_FSB(mp, XFS_INO_TO_AGNO(mp,i), XFS_INO_TO_AGBNO(mp,i))
-#endif
-
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_AGINO_TO_INO)
-xfs_ino_t
-xfs_agino_to_ino(struct xfs_mount *mp, xfs_agnumber_t a, xfs_agino_t i);
-#define XFS_AGINO_TO_INO(mp,a,i) xfs_agino_to_ino(mp,a,i)
-#else
#define XFS_AGINO_TO_INO(mp,a,i) \
(((xfs_ino_t)(a) << XFS_INO_AGINO_BITS(mp)) | (i))
-#endif
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_AGINO_TO_AGBNO)
-xfs_agblock_t xfs_agino_to_agbno(struct xfs_mount *mp, xfs_agino_t i);
-#define XFS_AGINO_TO_AGBNO(mp,i) xfs_agino_to_agbno(mp,i)
-#else
#define XFS_AGINO_TO_AGBNO(mp,i) ((i) >> XFS_INO_OFFSET_BITS(mp))
-#endif
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_AGINO_TO_OFFSET)
-int xfs_agino_to_offset(struct xfs_mount *mp, xfs_agino_t i);
-#define XFS_AGINO_TO_OFFSET(mp,i) xfs_agino_to_offset(mp,i)
-#else
#define XFS_AGINO_TO_OFFSET(mp,i) \
((i) & XFS_INO_MASK(XFS_INO_OFFSET_BITS(mp)))
-#endif
-
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_OFFBNO_TO_AGINO)
-xfs_agino_t xfs_offbno_to_agino(struct xfs_mount *mp, xfs_agblock_t b, int o);
-#define XFS_OFFBNO_TO_AGINO(mp,b,o) xfs_offbno_to_agino(mp,b,o)
-#else
#define XFS_OFFBNO_TO_AGINO(mp,b,o) \
((xfs_agino_t)(((b) << XFS_INO_OFFSET_BITS(mp)) | (o)))
-#endif
#if XFS_BIG_INUMS
#define XFS_MAXINUMBER ((xfs_ino_t)((1ULL << 56) - 1ULL))
diff --git a/fs/xfs/xfs_iocore.c b/fs/xfs/xfs_iocore.c
index 414ec496845f..a07815661a8c 100644
--- a/fs/xfs/xfs_iocore.c
+++ b/fs/xfs/xfs_iocore.c
@@ -1,40 +1,26 @@
/*
- * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-
#include "xfs.h"
-#include "xfs_macros.h"
+#include "xfs_fs.h"
#include "xfs_types.h"
-#include "xfs_inum.h"
+#include "xfs_bit.h"
#include "xfs_log.h"
+#include "xfs_inum.h"
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
@@ -42,22 +28,21 @@
#include "xfs_dir2.h"
#include "xfs_dmapi.h"
#include "xfs_mount.h"
-#include "xfs_alloc_btree.h"
#include "xfs_bmap_btree.h"
+#include "xfs_alloc_btree.h"
#include "xfs_ialloc_btree.h"
-#include "xfs_itable.h"
-#include "xfs_btree.h"
-#include "xfs_alloc.h"
-#include "xfs_ialloc.h"
-#include "xfs_attr_sf.h"
#include "xfs_dir_sf.h"
#include "xfs_dir2_sf.h"
+#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
-#include "xfs_inode_item.h"
#include "xfs_inode.h"
+#include "xfs_inode_item.h"
+#include "xfs_itable.h"
+#include "xfs_btree.h"
+#include "xfs_alloc.h"
+#include "xfs_ialloc.h"
#include "xfs_bmap.h"
#include "xfs_error.h"
-#include "xfs_bit.h"
#include "xfs_rw.h"
#include "xfs_quota.h"
#include "xfs_trans_space.h"
diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c
index d0f5be63cddb..45a77a3a6c07 100644
--- a/fs/xfs/xfs_iomap.c
+++ b/fs/xfs/xfs_iomap.c
@@ -1,40 +1,25 @@
/*
- * Copyright (c) 2000-2004 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-
#include "xfs.h"
-
#include "xfs_fs.h"
-#include "xfs_inum.h"
+#include "xfs_bit.h"
#include "xfs_log.h"
+#include "xfs_inum.h"
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
@@ -44,16 +29,16 @@
#include "xfs_dmapi.h"
#include "xfs_quota.h"
#include "xfs_mount.h"
-#include "xfs_alloc_btree.h"
#include "xfs_bmap_btree.h"
+#include "xfs_alloc_btree.h"
#include "xfs_ialloc_btree.h"
-#include "xfs_btree.h"
-#include "xfs_ialloc.h"
-#include "xfs_attr_sf.h"
#include "xfs_dir_sf.h"
#include "xfs_dir2_sf.h"
+#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
#include "xfs_inode.h"
+#include "xfs_ialloc.h"
+#include "xfs_btree.h"
#include "xfs_bmap.h"
#include "xfs_bit.h"
#include "xfs_rtalloc.h"
@@ -379,17 +364,15 @@ xfs_iomap_write_direct(
xfs_fileoff_t offset_fsb;
xfs_fileoff_t last_fsb;
xfs_filblks_t count_fsb;
- xfs_fsize_t isize;
xfs_fsblock_t firstfsb;
- int nimaps, maps;
+ int nimaps;
int error;
int bmapi_flag;
int quota_flag;
int rt;
xfs_trans_t *tp;
- xfs_bmbt_irec_t imap[XFS_WRITE_IMAPS], *imapp;
+ xfs_bmbt_irec_t imap;
xfs_bmap_free_t free_list;
- int aeof;
xfs_filblks_t qblocks, resblks;
int committed;
int resrtextents;
@@ -402,15 +385,6 @@ xfs_iomap_write_direct(
if (error)
return XFS_ERROR(error);
- maps = min(XFS_WRITE_IMAPS, *nmaps);
- nimaps = maps;
-
- isize = ip->i_d.di_size;
- aeof = (offset + count) > isize;
-
- if (io->io_new_size > isize)
- isize = io->io_new_size;
-
offset_fsb = XFS_B_TO_FSBT(mp, offset);
last_fsb = XFS_B_TO_FSB(mp, ((xfs_ufsize_t)(offset + count)));
count_fsb = last_fsb - offset_fsb;
@@ -479,9 +453,8 @@ xfs_iomap_write_direct(
*/
XFS_BMAP_INIT(&free_list, &firstfsb);
nimaps = 1;
- imapp = &imap[0];
error = xfs_bmapi(tp, ip, offset_fsb, count_fsb,
- bmapi_flag, &firstfsb, 0, imapp, &nimaps, &free_list);
+ bmapi_flag, &firstfsb, 0, &imap, &nimaps, &free_list);
if (error)
goto error0;
@@ -503,7 +476,7 @@ xfs_iomap_write_direct(
goto error_out;
}
- *ret_imap = imap[0];
+ *ret_imap = imap;
*nmaps = 1;
if ( !(io->io_flags & XFS_IOCORE_RT) && !ret_imap->br_startblock) {
cmn_err(CE_PANIC,"Access to block zero: fs <%s> inode: %lld "
diff --git a/fs/xfs/xfs_iomap.h b/fs/xfs/xfs_iomap.h
index 4daaa5212102..fcd6d63bb68b 100644
--- a/fs/xfs/xfs_iomap.h
+++ b/fs/xfs/xfs_iomap.h
@@ -1,33 +1,19 @@
/*
- * Copyright (c) 2003-2005 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2003-2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __XFS_IOMAP_H__
#define __XFS_IOMAP_H__
diff --git a/fs/xfs/xfs_itable.c b/fs/xfs/xfs_itable.c
index 8fbc8d378188..f63646ead816 100644
--- a/fs/xfs/xfs_itable.c
+++ b/fs/xfs/xfs_itable.c
@@ -1,59 +1,45 @@
/*
- * Copyright (c) 2000-2002 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-
#include "xfs.h"
-#include "xfs_macros.h"
+#include "xfs_fs.h"
#include "xfs_types.h"
-#include "xfs_inum.h"
+#include "xfs_bit.h"
#include "xfs_log.h"
+#include "xfs_inum.h"
#include "xfs_trans.h"
#include "xfs_sb.h"
+#include "xfs_ag.h"
#include "xfs_dir.h"
#include "xfs_dir2.h"
#include "xfs_dmapi.h"
#include "xfs_mount.h"
-#include "xfs_ag.h"
-#include "xfs_alloc_btree.h"
#include "xfs_bmap_btree.h"
+#include "xfs_alloc_btree.h"
#include "xfs_ialloc_btree.h"
-#include "xfs_btree.h"
-#include "xfs_attr_sf.h"
#include "xfs_dir_sf.h"
#include "xfs_dir2_sf.h"
+#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
#include "xfs_inode.h"
#include "xfs_ialloc.h"
#include "xfs_itable.h"
#include "xfs_error.h"
+#include "xfs_btree.h"
#ifndef HAVE_USERACC
#define useracc(ubuffer, size, flags, foo) (0)
@@ -462,7 +448,7 @@ xfs_bulkstat(
while (error) {
agino += XFS_INODES_PER_CHUNK;
if (XFS_AGINO_TO_AGBNO(mp, agino) >=
- INT_GET(agi->agi_length, ARCH_CONVERT))
+ be32_to_cpu(agi->agi_length))
break;
error = xfs_inobt_lookup_ge(cur, agino, 0, 0,
&tmp);
diff --git a/fs/xfs/xfs_itable.h b/fs/xfs/xfs_itable.h
index 2be9d1805ab2..047d834ed210 100644
--- a/fs/xfs/xfs_itable.h
+++ b/fs/xfs/xfs_itable.h
@@ -1,33 +1,18 @@
/*
* Copyright (c) 2000-2001 Silicon Graphics, Inc. All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __XFS_ITABLE_H__
#define __XFS_ITABLE_H__
diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c
index 54a6f1142403..29af51275ca9 100644
--- a/fs/xfs/xfs_log.c
+++ b/fs/xfs/xfs_log.c
@@ -1,58 +1,47 @@
/*
- * Copyright (c) 2000-2004 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-
-/*
- * High level interface routines for log manager
- */
-
#include "xfs.h"
-#include "xfs_macros.h"
+#include "xfs_fs.h"
#include "xfs_types.h"
-#include "xfs_inum.h"
-#include "xfs_ag.h"
-#include "xfs_sb.h"
+#include "xfs_bit.h"
#include "xfs_log.h"
+#include "xfs_inum.h"
#include "xfs_trans.h"
+#include "xfs_sb.h"
+#include "xfs_ag.h"
#include "xfs_dir.h"
+#include "xfs_dir2.h"
#include "xfs_dmapi.h"
#include "xfs_mount.h"
#include "xfs_error.h"
#include "xfs_log_priv.h"
#include "xfs_buf_item.h"
+#include "xfs_bmap_btree.h"
#include "xfs_alloc_btree.h"
+#include "xfs_ialloc_btree.h"
#include "xfs_log_recover.h"
-#include "xfs_bit.h"
-#include "xfs_rw.h"
#include "xfs_trans_priv.h"
+#include "xfs_dir_sf.h"
+#include "xfs_dir2_sf.h"
+#include "xfs_attr_sf.h"
+#include "xfs_dinode.h"
+#include "xfs_inode.h"
+#include "xfs_rw.h"
#define xlog_write_adv_cnt(ptr, len, off, bytes) \
@@ -93,8 +82,11 @@ STATIC int xlog_state_release_iclog(xlog_t *log,
STATIC void xlog_state_switch_iclogs(xlog_t *log,
xlog_in_core_t *iclog,
int eventual_size);
-STATIC int xlog_state_sync(xlog_t *log, xfs_lsn_t lsn, uint flags);
-STATIC int xlog_state_sync_all(xlog_t *log, uint flags);
+STATIC int xlog_state_sync(xlog_t *log,
+ xfs_lsn_t lsn,
+ uint flags,
+ int *log_flushed);
+STATIC int xlog_state_sync_all(xlog_t *log, uint flags, int *log_flushed);
STATIC void xlog_state_want_sync(xlog_t *log, xlog_in_core_t *iclog);
/* local functions to manipulate grant head */
@@ -119,8 +111,7 @@ STATIC xlog_ticket_t *xlog_ticket_get(xlog_t *log,
uint flags);
STATIC void xlog_ticket_put(xlog_t *log, xlog_ticket_t *ticket);
-/* local debug functions */
-#if defined(DEBUG) && !defined(XLOG_NOLOG)
+#if defined(DEBUG)
STATIC void xlog_verify_dest_ptr(xlog_t *log, __psint_t ptr);
STATIC void xlog_verify_grant_head(xlog_t *log, int equals);
STATIC void xlog_verify_iclog(xlog_t *log, xlog_in_core_t *iclog,
@@ -136,26 +127,7 @@ STATIC void xlog_verify_tail_lsn(xlog_t *log, xlog_in_core_t *iclog,
STATIC int xlog_iclogs_empty(xlog_t *log);
-#ifdef DEBUG
-int xlog_do_error = 0;
-int xlog_req_num = 0;
-int xlog_error_mod = 33;
-#endif
-
-#define XLOG_FORCED_SHUTDOWN(log) (log->l_flags & XLOG_IO_ERROR)
-
-/*
- * 0 => disable log manager
- * 1 => enable log manager
- * 2 => enable log manager and log debugging
- */
-#if defined(XLOG_NOLOG) || defined(DEBUG)
-int xlog_debug = 1;
-xfs_buftarg_t *xlog_target;
-#endif
-
#if defined(XFS_LOG_TRACE)
-
void
xlog_trace_loggrant(xlog_t *log, xlog_ticket_t *tic, xfs_caddr_t string)
{
@@ -191,31 +163,16 @@ xlog_trace_loggrant(xlog_t *log, xlog_ticket_t *tic, xfs_caddr_t string)
void
xlog_trace_iclog(xlog_in_core_t *iclog, uint state)
{
- pid_t pid;
-
- pid = current_pid();
-
if (!iclog->ic_trace)
iclog->ic_trace = ktrace_alloc(256, KM_SLEEP);
ktrace_enter(iclog->ic_trace,
(void *)((unsigned long)state),
- (void *)((unsigned long)pid),
- (void *)0,
- (void *)0,
- (void *)0,
- (void *)0,
- (void *)0,
- (void *)0,
- (void *)0,
- (void *)0,
- (void *)0,
- (void *)0,
- (void *)0,
- (void *)0,
- (void *)0,
- (void *)0);
+ (void *)((unsigned long)current_pid()),
+ (void *)NULL, (void *)NULL, (void *)NULL, (void *)NULL,
+ (void *)NULL, (void *)NULL, (void *)NULL, (void *)NULL,
+ (void *)NULL, (void *)NULL, (void *)NULL, (void *)NULL,
+ (void *)NULL, (void *)NULL);
}
-
#else
#define xlog_trace_loggrant(log,tic,string)
#define xlog_trace_iclog(iclog,state)
@@ -252,11 +209,6 @@ xfs_log_done(xfs_mount_t *mp,
xlog_ticket_t *ticket = (xfs_log_ticket_t) xtic;
xfs_lsn_t lsn = 0;
-#if defined(DEBUG) || defined(XLOG_NOLOG)
- if (!xlog_debug && xlog_target == log->l_targ)
- return 0;
-#endif
-
if (XLOG_FORCED_SHUTDOWN(log) ||
/*
* If nothing was ever written, don't write out commit record.
@@ -312,33 +264,28 @@ xfs_log_done(xfs_mount_t *mp,
* semaphore.
*/
int
-xfs_log_force(xfs_mount_t *mp,
- xfs_lsn_t lsn,
- uint flags)
+_xfs_log_force(
+ xfs_mount_t *mp,
+ xfs_lsn_t lsn,
+ uint flags,
+ int *log_flushed)
{
- int rval;
- xlog_t *log = mp->m_log;
+ xlog_t *log = mp->m_log;
+ int dummy;
-#if defined(DEBUG) || defined(XLOG_NOLOG)
- if (!xlog_debug && xlog_target == log->l_targ)
- return 0;
-#endif
+ if (!log_flushed)
+ log_flushed = &dummy;
ASSERT(flags & XFS_LOG_FORCE);
XFS_STATS_INC(xs_log_force);
- if ((log->l_flags & XLOG_IO_ERROR) == 0) {
- if (lsn == 0)
- rval = xlog_state_sync_all(log, flags);
- else
- rval = xlog_state_sync(log, lsn, flags);
- } else {
- rval = XFS_ERROR(EIO);
- }
-
- return rval;
-
+ if (log->l_flags & XLOG_IO_ERROR)
+ return XFS_ERROR(EIO);
+ if (lsn == 0)
+ return xlog_state_sync_all(log, flags, log_flushed);
+ else
+ return xlog_state_sync(log, lsn, flags, log_flushed);
} /* xfs_log_force */
/*
@@ -356,10 +303,6 @@ xfs_log_notify(xfs_mount_t *mp, /* mount of partition */
xlog_in_core_t *iclog = (xlog_in_core_t *)iclog_hndl;
int abortflg, spl;
-#if defined(DEBUG) || defined(XLOG_NOLOG)
- if (!xlog_debug && xlog_target == log->l_targ)
- return 0;
-#endif
cb->cb_next = NULL;
spl = LOG_LOCK(log);
abortflg = (iclog->ic_state & XLOG_STATE_IOERROR);
@@ -410,13 +353,8 @@ xfs_log_reserve(xfs_mount_t *mp,
{
xlog_t *log = mp->m_log;
xlog_ticket_t *internal_ticket;
- int retval;
+ int retval = 0;
-#if defined(DEBUG) || defined(XLOG_NOLOG)
- if (!xlog_debug && xlog_target == log->l_targ)
- return 0;
-#endif
- retval = 0;
ASSERT(client == XFS_TRANSACTION || client == XFS_LOG);
ASSERT((flags & XFS_LOG_NOSLEEP) == 0);
@@ -478,12 +416,6 @@ xfs_log_mount(xfs_mount_t *mp,
mp->m_log = xlog_alloc_log(mp, log_target, blk_offset, num_bblks);
-#if defined(DEBUG) || defined(XLOG_NOLOG)
- if (!xlog_debug) {
- cmn_err(CE_NOTE, "log dev: %s", XFS_BUFTARG_NAME(log_target));
- return 0;
- }
-#endif
/*
* skip log recovery on a norecovery mount. pretend it all
* just worked.
@@ -587,11 +519,6 @@ xfs_log_unmount_write(xfs_mount_t *mp)
__uint32_t pad2; /* may as well make it 64 bits */
} magic = { XLOG_UNMOUNT_TYPE, 0, 0 };
-#if defined(DEBUG) || defined(XLOG_NOLOG)
- if (!xlog_debug && xlog_target == log->l_targ)
- return 0;
-#endif
-
/*
* Don't write out unmount record on read-only mounts.
* Or, if we are doing a forced umount (typically because of IO errors).
@@ -718,12 +645,6 @@ xfs_log_write(xfs_mount_t * mp,
int error;
xlog_t *log = mp->m_log;
-#if defined(DEBUG) || defined(XLOG_NOLOG)
- if (!xlog_debug && xlog_target == log->l_targ) {
- *start_lsn = 0;
- return 0;
- }
-#endif
if (XLOG_FORCED_SHUTDOWN(log))
return XFS_ERROR(EIO);
@@ -743,11 +664,6 @@ xfs_log_move_tail(xfs_mount_t *mp,
int need_bytes, free_bytes, cycle, bytes;
SPLDECL(s);
-#if defined(DEBUG) || defined(XLOG_NOLOG)
- if (!xlog_debug && xlog_target == log->l_targ)
- return;
-#endif
- /* XXXsup tmp */
if (XLOG_FORCED_SHUTDOWN(log))
return;
ASSERT(!XFS_FORCED_SHUTDOWN(mp));
@@ -1034,51 +950,22 @@ xlog_get_iclog_buffer_size(xfs_mount_t *mp,
int size;
int xhdrs;
-#if defined(DEBUG) || defined(XLOG_NOLOG)
- /*
- * When logbufs == 0, someone has disabled the log from the FSTAB
- * file. This is not a documented feature. We need to set xlog_debug
- * to zero (this deactivates the log) and set xlog_target to the
- * appropriate device. Only one filesystem may be affected as such
- * since this is just a performance hack to test what we might be able
- * to get if the log were not present.
- */
- if (mp->m_logbufs == 0) {
- xlog_debug = 0;
- xlog_target = log->l_targ;
- log->l_iclog_bufs = XLOG_MIN_ICLOGS;
- } else
-#endif
- {
- /*
- * This is the normal path. If m_logbufs == -1, then the
- * admin has chosen to use the system defaults for logbuffers.
- */
- if (mp->m_logbufs == -1) {
- if (xfs_physmem <= btoc(128*1024*1024)) {
- log->l_iclog_bufs = XLOG_MIN_ICLOGS;
- } else if (xfs_physmem <= btoc(400*1024*1024)) {
- log->l_iclog_bufs = XLOG_MED_ICLOGS;
- } else {
- /* 256K with 32K bufs */
- log->l_iclog_bufs = XLOG_MAX_ICLOGS;
- }
- } else
- log->l_iclog_bufs = mp->m_logbufs;
-
-#if defined(DEBUG) || defined(XLOG_NOLOG)
- /* We are reactivating a filesystem after it was inactive */
- if (log->l_targ == xlog_target) {
- xlog_target = NULL;
- xlog_debug = 1;
+ if (mp->m_logbufs <= 0) {
+ if (xfs_physmem <= btoc(128*1024*1024)) {
+ log->l_iclog_bufs = XLOG_MIN_ICLOGS;
+ } else if (xfs_physmem <= btoc(400*1024*1024)) {
+ log->l_iclog_bufs = XLOG_MED_ICLOGS;
+ } else { /* 256K with 32K bufs */
+ log->l_iclog_bufs = XLOG_MAX_ICLOGS;
}
-#endif
+ } else {
+ log->l_iclog_bufs = mp->m_logbufs;
}
/*
* Buffer size passed in from mount system call.
*/
- if (mp->m_logbsize != -1) {
+ if (mp->m_logbsize > 0) {
size = log->l_iclog_size = mp->m_logbsize;
log->l_iclog_size_log = 0;
while (size != 1) {
@@ -1101,7 +988,7 @@ xlog_get_iclog_buffer_size(xfs_mount_t *mp,
log->l_iclog_hsize = BBSIZE;
log->l_iclog_heads = 1;
}
- return;
+ goto done;
}
/*
@@ -1128,7 +1015,7 @@ xlog_get_iclog_buffer_size(xfs_mount_t *mp,
if (mp->m_sb.sb_blocksize >= 16*1024) {
log->l_iclog_size = XLOG_BIG_RECORD_BSIZE;
log->l_iclog_size_log = XLOG_BIG_RECORD_BSHIFT;
- if (mp->m_logbufs == -1) {
+ if (mp->m_logbufs <= 0) {
switch (mp->m_sb.sb_blocksize) {
case 16*1024: /* 16 KB */
log->l_iclog_bufs = 3;
@@ -1145,6 +1032,12 @@ xlog_get_iclog_buffer_size(xfs_mount_t *mp,
}
}
}
+
+done: /* are we being asked to make the sizes selected above visible? */
+ if (mp->m_logbufs == 0)
+ mp->m_logbufs = log->l_iclog_bufs;
+ if (mp->m_logbsize == 0)
+ mp->m_logbsize = log->l_iclog_size;
} /* xlog_get_iclog_buffer_size */
@@ -1467,14 +1360,13 @@ xlog_sync(xlog_t *log,
XFS_BUF_BUSY(bp);
XFS_BUF_ASYNC(bp);
/*
- * Do a disk write cache flush for the log block.
- * This is a bit of a sledgehammer, it would be better
- * to use a tag barrier here that just prevents reordering.
+ * Do an ordered write for the log block.
+ *
* It may not be needed to flush the first split block in the log wrap
* case, but do it anyways to be safe -AK
*/
- if (!(log->l_mp->m_flags & XFS_MOUNT_NOLOGFLUSH))
- XFS_BUF_FLUSH(bp);
+ if (log->l_mp->m_flags & XFS_MOUNT_BARRIER)
+ XFS_BUF_ORDERED(bp);
ASSERT(XFS_BUF_ADDR(bp) <= log->l_logBBsize-1);
ASSERT(XFS_BUF_ADDR(bp) + BTOBB(count) <= log->l_logBBsize);
@@ -1505,8 +1397,8 @@ xlog_sync(xlog_t *log,
XFS_BUF_SET_FSPRIVATE(bp, iclog);
XFS_BUF_BUSY(bp);
XFS_BUF_ASYNC(bp);
- if (!(log->l_mp->m_flags & XFS_MOUNT_NOLOGFLUSH))
- XFS_BUF_FLUSH(bp);
+ if (log->l_mp->m_flags & XFS_MOUNT_BARRIER)
+ XFS_BUF_ORDERED(bp);
dptr = XFS_BUF_PTR(bp);
/*
* Bump the cycle numbers at the start of each block
@@ -2951,7 +2843,7 @@ xlog_state_switch_iclogs(xlog_t *log,
* not in the active nor dirty state.
*/
STATIC int
-xlog_state_sync_all(xlog_t *log, uint flags)
+xlog_state_sync_all(xlog_t *log, uint flags, int *log_flushed)
{
xlog_in_core_t *iclog;
xfs_lsn_t lsn;
@@ -3000,6 +2892,7 @@ xlog_state_sync_all(xlog_t *log, uint flags)
if (xlog_state_release_iclog(log, iclog))
return XFS_ERROR(EIO);
+ *log_flushed = 1;
s = LOG_LOCK(log);
if (INT_GET(iclog->ic_header.h_lsn, ARCH_CONVERT) == lsn &&
iclog->ic_state != XLOG_STATE_DIRTY)
@@ -3043,6 +2936,7 @@ maybe_sleep:
*/
if (iclog->ic_state & XLOG_STATE_IOERROR)
return XFS_ERROR(EIO);
+ *log_flushed = 1;
} else {
@@ -3068,7 +2962,8 @@ no_sleep:
int
xlog_state_sync(xlog_t *log,
xfs_lsn_t lsn,
- uint flags)
+ uint flags,
+ int *log_flushed)
{
xlog_in_core_t *iclog;
int already_slept = 0;
@@ -3120,6 +3015,7 @@ try_again:
XFS_STATS_INC(xs_log_force_sleep);
sv_wait(&iclog->ic_prev->ic_writesema, PSWP,
&log->l_icloglock, s);
+ *log_flushed = 1;
already_slept = 1;
goto try_again;
} else {
@@ -3128,6 +3024,7 @@ try_again:
LOG_UNLOCK(log, s);
if (xlog_state_release_iclog(log, iclog))
return XFS_ERROR(EIO);
+ *log_flushed = 1;
s = LOG_LOCK(log);
}
}
@@ -3152,6 +3049,7 @@ try_again:
*/
if (iclog->ic_state & XLOG_STATE_IOERROR)
return XFS_ERROR(EIO);
+ *log_flushed = 1;
} else { /* just return */
LOG_UNLOCK(log, s);
}
@@ -3392,7 +3290,7 @@ xlog_ticket_get(xlog_t *log,
*
******************************************************************************
*/
-#if defined(DEBUG) && !defined(XLOG_NOLOG)
+#if defined(DEBUG)
/*
* Make sure that the destination ptr is within the valid data region of
* one of the iclogs. This uses backup pointers stored in a different
@@ -3533,7 +3431,9 @@ xlog_verify_iclog(xlog_t *log,
}
}
if (clientid != XFS_TRANSACTION && clientid != XFS_LOG)
- cmn_err(CE_WARN, "xlog_verify_iclog: invalid clientid %d op 0x%p offset 0x%x", clientid, ophead, field_offset);
+ cmn_err(CE_WARN, "xlog_verify_iclog: "
+ "invalid clientid %d op 0x%p offset 0x%lx",
+ clientid, ophead, (unsigned long)field_offset);
/* check length */
field_offset = (__psint_t)
@@ -3554,7 +3454,7 @@ xlog_verify_iclog(xlog_t *log,
ptr += sizeof(xlog_op_header_t) + op_len;
}
} /* xlog_verify_iclog */
-#endif /* DEBUG && !XLOG_NOLOG */
+#endif
/*
* Mark all iclogs IOERROR. LOG_LOCK is held by the caller.
@@ -3604,6 +3504,7 @@ xfs_log_force_umount(
xlog_ticket_t *tic;
xlog_t *log;
int retval;
+ int dummy;
SPLDECL(s);
SPLDECL(s2);
@@ -3682,7 +3583,7 @@ xfs_log_force_umount(
* Force the incore logs to disk before shutting the
* log down completely.
*/
- xlog_state_sync_all(log, XFS_LOG_FORCE|XFS_LOG_SYNC);
+ xlog_state_sync_all(log, XFS_LOG_FORCE|XFS_LOG_SYNC, &dummy);
s2 = LOG_LOCK(log);
retval = xlog_state_ioerror(log);
LOG_UNLOCK(log, s2);
diff --git a/fs/xfs/xfs_log.h b/fs/xfs/xfs_log.h
index 18961119fc65..158829ca56f6 100644
--- a/fs/xfs/xfs_log.h
+++ b/fs/xfs/xfs_log.h
@@ -1,33 +1,19 @@
/*
- * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __XFS_LOG_H__
#define __XFS_LOG_H__
@@ -174,9 +160,12 @@ xfs_lsn_t xfs_log_done(struct xfs_mount *mp,
xfs_log_ticket_t ticket,
void **iclog,
uint flags);
-int xfs_log_force(struct xfs_mount *mp,
- xfs_lsn_t lsn,
- uint flags);
+int _xfs_log_force(struct xfs_mount *mp,
+ xfs_lsn_t lsn,
+ uint flags,
+ int *log_forced);
+#define xfs_log_force(mp, lsn, flags) \
+ _xfs_log_force(mp, lsn, flags, NULL);
int xfs_log_mount(struct xfs_mount *mp,
struct xfs_buftarg *log_target,
xfs_daddr_t start_block,
diff --git a/fs/xfs/xfs_log_priv.h b/fs/xfs/xfs_log_priv.h
index a884cea82fca..8f285149681f 100644
--- a/fs/xfs/xfs_log_priv.h
+++ b/fs/xfs/xfs_log_priv.h
@@ -1,33 +1,19 @@
/*
- * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __XFS_LOG_PRIV_H__
#define __XFS_LOG_PRIV_H__
@@ -35,6 +21,7 @@
struct xfs_buf;
struct ktrace;
struct log;
+struct xlog_ticket;
struct xfs_buf_cancel;
struct xfs_mount;
@@ -120,77 +107,6 @@ struct xfs_mount;
((i) >> 24)
#endif
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XLOG_GRANT_SUB_SPACE)
-void xlog_grant_sub_space(struct log *log, int bytes, int type);
-#define XLOG_GRANT_SUB_SPACE(log,bytes,type) \
- xlog_grant_sub_space(log,bytes,type)
-#else
-#define XLOG_GRANT_SUB_SPACE(log,bytes,type) \
- { \
- if (type == 'w') { \
- (log)->l_grant_write_bytes -= (bytes); \
- if ((log)->l_grant_write_bytes < 0) { \
- (log)->l_grant_write_bytes += (log)->l_logsize; \
- (log)->l_grant_write_cycle--; \
- } \
- } else { \
- (log)->l_grant_reserve_bytes -= (bytes); \
- if ((log)->l_grant_reserve_bytes < 0) { \
- (log)->l_grant_reserve_bytes += (log)->l_logsize;\
- (log)->l_grant_reserve_cycle--; \
- } \
- } \
- }
-#endif
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XLOG_GRANT_ADD_SPACE)
-void xlog_grant_add_space(struct log *log, int bytes, int type);
-#define XLOG_GRANT_ADD_SPACE(log,bytes,type) \
- xlog_grant_add_space(log,bytes,type)
-#else
-#define XLOG_GRANT_ADD_SPACE(log,bytes,type) \
- { \
- if (type == 'w') { \
- (log)->l_grant_write_bytes += (bytes); \
- if ((log)->l_grant_write_bytes > (log)->l_logsize) { \
- (log)->l_grant_write_bytes -= (log)->l_logsize; \
- (log)->l_grant_write_cycle++; \
- } \
- } else { \
- (log)->l_grant_reserve_bytes += (bytes); \
- if ((log)->l_grant_reserve_bytes > (log)->l_logsize) { \
- (log)->l_grant_reserve_bytes -= (log)->l_logsize;\
- (log)->l_grant_reserve_cycle++; \
- } \
- } \
- }
-#endif
-#define XLOG_INS_TICKETQ(q,tic) \
- { \
- if (q) { \
- (tic)->t_next = (q); \
- (tic)->t_prev = (q)->t_prev; \
- (q)->t_prev->t_next = (tic); \
- (q)->t_prev = (tic); \
- } else { \
- (tic)->t_prev = (tic)->t_next = (tic); \
- (q) = (tic); \
- } \
- (tic)->t_flags |= XLOG_TIC_IN_Q; \
- }
-#define XLOG_DEL_TICKETQ(q,tic) \
- { \
- if ((tic) == (tic)->t_next) { \
- (q) = NULL; \
- } else { \
- (q) = (tic)->t_next; \
- (tic)->t_next->t_prev = (tic)->t_prev; \
- (tic)->t_prev->t_next = (tic)->t_next; \
- } \
- (tic)->t_next = (tic)->t_prev = NULL; \
- (tic)->t_flags &= ~XLOG_TIC_IN_Q; \
- }
-
-
#define GRANT_LOCK(log) mutex_spinlock(&(log)->l_grant_lock)
#define GRANT_UNLOCK(log, s) mutex_spinunlock(&(log)->l_grant_lock, s)
#define LOG_LOCK(log) mutex_spinlock(&(log)->l_icloglock)
@@ -576,6 +492,77 @@ typedef struct log {
* alignment mask */
} xlog_t;
+#define XLOG_FORCED_SHUTDOWN(log) ((log)->l_flags & XLOG_IO_ERROR)
+
+#define XLOG_GRANT_SUB_SPACE(log,bytes,type) \
+ xlog_grant_sub_space(log,bytes,type)
+static inline void xlog_grant_sub_space(struct log *log, int bytes, int type)
+{
+ if (type == 'w') { \
+ (log)->l_grant_write_bytes -= (bytes); \
+ if ((log)->l_grant_write_bytes < 0) { \
+ (log)->l_grant_write_bytes += (log)->l_logsize; \
+ (log)->l_grant_write_cycle--; \
+ } \
+ } else { \
+ (log)->l_grant_reserve_bytes -= (bytes); \
+ if ((log)->l_grant_reserve_bytes < 0) { \
+ (log)->l_grant_reserve_bytes += (log)->l_logsize;\
+ (log)->l_grant_reserve_cycle--; \
+ } \
+ } \
+}
+
+#define XLOG_GRANT_ADD_SPACE(log,bytes,type) \
+ xlog_grant_add_space(log,bytes,type)
+static inline void
+xlog_grant_add_space(struct log *log, int bytes, int type)
+{
+ if (type == 'w') { \
+ (log)->l_grant_write_bytes += (bytes); \
+ if ((log)->l_grant_write_bytes > (log)->l_logsize) { \
+ (log)->l_grant_write_bytes -= (log)->l_logsize; \
+ (log)->l_grant_write_cycle++; \
+ } \
+ } else { \
+ (log)->l_grant_reserve_bytes += (bytes); \
+ if ((log)->l_grant_reserve_bytes > (log)->l_logsize) { \
+ (log)->l_grant_reserve_bytes -= (log)->l_logsize;\
+ (log)->l_grant_reserve_cycle++; \
+ } \
+ } \
+}
+
+#define XLOG_INS_TICKETQ(q, tic) xlog_ins_ticketq(q, tic)
+static inline void
+xlog_ins_ticketq(struct xlog_ticket *q, struct xlog_ticket *tic)
+{ \
+ if (q) { \
+ (tic)->t_next = (q); \
+ (tic)->t_prev = (q)->t_prev; \
+ (q)->t_prev->t_next = (tic); \
+ (q)->t_prev = (tic); \
+ } else { \
+ (tic)->t_prev = (tic)->t_next = (tic); \
+ (q) = (tic); \
+ } \
+ (tic)->t_flags |= XLOG_TIC_IN_Q; \
+}
+
+#define XLOG_DEL_TICKETQ(q, tic) xlog_del_ticketq(q, tic)
+static inline void
+xlog_del_ticketq(struct xlog_ticket *q, struct xlog_ticket *tic)
+{ \
+ if ((tic) == (tic)->t_next) { \
+ (q) = NULL; \
+ } else { \
+ (q) = (tic)->t_next; \
+ (tic)->t_next->t_prev = (tic)->t_prev; \
+ (tic)->t_prev->t_next = (tic)->t_next; \
+ } \
+ (tic)->t_next = (tic)->t_prev = NULL; \
+ (tic)->t_flags &= ~XLOG_TIC_IN_Q; \
+}
/* common routines */
extern xfs_lsn_t xlog_assign_tail_lsn(struct xfs_mount *mp);
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c
index 14faabaabf29..8ab7df768063 100644
--- a/fs/xfs/xfs_log_recover.c
+++ b/fs/xfs/xfs_log_recover.c
@@ -1,66 +1,51 @@
/*
- * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-
#include "xfs.h"
-#include "xfs_macros.h"
+#include "xfs_fs.h"
#include "xfs_types.h"
-#include "xfs_inum.h"
+#include "xfs_bit.h"
#include "xfs_log.h"
-#include "xfs_ag.h"
-#include "xfs_sb.h"
+#include "xfs_inum.h"
#include "xfs_trans.h"
+#include "xfs_sb.h"
+#include "xfs_ag.h"
#include "xfs_dir.h"
#include "xfs_dir2.h"
#include "xfs_dmapi.h"
#include "xfs_mount.h"
#include "xfs_error.h"
#include "xfs_bmap_btree.h"
-#include "xfs_alloc.h"
-#include "xfs_attr_sf.h"
+#include "xfs_alloc_btree.h"
+#include "xfs_ialloc_btree.h"
#include "xfs_dir_sf.h"
#include "xfs_dir2_sf.h"
+#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
-#include "xfs_imap.h"
-#include "xfs_inode_item.h"
#include "xfs_inode.h"
-#include "xfs_ialloc_btree.h"
+#include "xfs_inode_item.h"
+#include "xfs_imap.h"
+#include "xfs_alloc.h"
#include "xfs_ialloc.h"
#include "xfs_log_priv.h"
#include "xfs_buf_item.h"
-#include "xfs_alloc_btree.h"
#include "xfs_log_recover.h"
#include "xfs_extfree_item.h"
#include "xfs_trans_priv.h"
-#include "xfs_bit.h"
#include "xfs_quota.h"
#include "xfs_rw.h"
@@ -2013,79 +1998,74 @@ xfs_qm_dqcheck(
* This is all fine; things are still consistent, and we haven't lost
* any quota information. Just don't complain about bad dquot blks.
*/
- if (INT_GET(ddq->d_magic, ARCH_CONVERT) != XFS_DQUOT_MAGIC) {
+ if (be16_to_cpu(ddq->d_magic) != XFS_DQUOT_MAGIC) {
if (flags & XFS_QMOPT_DOWARN)
cmn_err(CE_ALERT,
"%s : XFS dquot ID 0x%x, magic 0x%x != 0x%x",
- str, id,
- INT_GET(ddq->d_magic, ARCH_CONVERT), XFS_DQUOT_MAGIC);
+ str, id, be16_to_cpu(ddq->d_magic), XFS_DQUOT_MAGIC);
errs++;
}
- if (INT_GET(ddq->d_version, ARCH_CONVERT) != XFS_DQUOT_VERSION) {
+ if (ddq->d_version != XFS_DQUOT_VERSION) {
if (flags & XFS_QMOPT_DOWARN)
cmn_err(CE_ALERT,
"%s : XFS dquot ID 0x%x, version 0x%x != 0x%x",
- str, id,
- INT_GET(ddq->d_magic, ARCH_CONVERT), XFS_DQUOT_VERSION);
+ str, id, ddq->d_version, XFS_DQUOT_VERSION);
errs++;
}
- if (INT_GET(ddq->d_flags, ARCH_CONVERT) != XFS_DQ_USER &&
- INT_GET(ddq->d_flags, ARCH_CONVERT) != XFS_DQ_PROJ &&
- INT_GET(ddq->d_flags, ARCH_CONVERT) != XFS_DQ_GROUP) {
+ if (ddq->d_flags != XFS_DQ_USER &&
+ ddq->d_flags != XFS_DQ_PROJ &&
+ ddq->d_flags != XFS_DQ_GROUP) {
if (flags & XFS_QMOPT_DOWARN)
cmn_err(CE_ALERT,
"%s : XFS dquot ID 0x%x, unknown flags 0x%x",
- str, id, INT_GET(ddq->d_flags, ARCH_CONVERT));
+ str, id, ddq->d_flags);
errs++;
}
- if (id != -1 && id != INT_GET(ddq->d_id, ARCH_CONVERT)) {
+ if (id != -1 && id != be32_to_cpu(ddq->d_id)) {
if (flags & XFS_QMOPT_DOWARN)
cmn_err(CE_ALERT,
"%s : ondisk-dquot 0x%p, ID mismatch: "
"0x%x expected, found id 0x%x",
- str, ddq, id, INT_GET(ddq->d_id, ARCH_CONVERT));
+ str, ddq, id, be32_to_cpu(ddq->d_id));
errs++;
}
if (!errs && ddq->d_id) {
- if (INT_GET(ddq->d_blk_softlimit, ARCH_CONVERT) &&
- INT_GET(ddq->d_bcount, ARCH_CONVERT) >=
- INT_GET(ddq->d_blk_softlimit, ARCH_CONVERT)) {
+ if (ddq->d_blk_softlimit &&
+ be64_to_cpu(ddq->d_bcount) >=
+ be64_to_cpu(ddq->d_blk_softlimit)) {
if (!ddq->d_btimer) {
if (flags & XFS_QMOPT_DOWARN)
cmn_err(CE_ALERT,
"%s : Dquot ID 0x%x (0x%p) "
"BLK TIMER NOT STARTED",
- str, (int)
- INT_GET(ddq->d_id, ARCH_CONVERT), ddq);
+ str, (int)be32_to_cpu(ddq->d_id), ddq);
errs++;
}
}
- if (INT_GET(ddq->d_ino_softlimit, ARCH_CONVERT) &&
- INT_GET(ddq->d_icount, ARCH_CONVERT) >=
- INT_GET(ddq->d_ino_softlimit, ARCH_CONVERT)) {
+ if (ddq->d_ino_softlimit &&
+ be64_to_cpu(ddq->d_icount) >=
+ be64_to_cpu(ddq->d_ino_softlimit)) {
if (!ddq->d_itimer) {
if (flags & XFS_QMOPT_DOWARN)
cmn_err(CE_ALERT,
"%s : Dquot ID 0x%x (0x%p) "
"INODE TIMER NOT STARTED",
- str, (int)
- INT_GET(ddq->d_id, ARCH_CONVERT), ddq);
+ str, (int)be32_to_cpu(ddq->d_id), ddq);
errs++;
}
}
- if (INT_GET(ddq->d_rtb_softlimit, ARCH_CONVERT) &&
- INT_GET(ddq->d_rtbcount, ARCH_CONVERT) >=
- INT_GET(ddq->d_rtb_softlimit, ARCH_CONVERT)) {
+ if (ddq->d_rtb_softlimit &&
+ be64_to_cpu(ddq->d_rtbcount) >=
+ be64_to_cpu(ddq->d_rtb_softlimit)) {
if (!ddq->d_rtbtimer) {
if (flags & XFS_QMOPT_DOWARN)
cmn_err(CE_ALERT,
"%s : Dquot ID 0x%x (0x%p) "
"RTBLK TIMER NOT STARTED",
- str, (int)
- INT_GET(ddq->d_id, ARCH_CONVERT), ddq);
+ str, (int)be32_to_cpu(ddq->d_id), ddq);
errs++;
}
}
@@ -2103,10 +2083,11 @@ xfs_qm_dqcheck(
ASSERT(id != -1);
ASSERT(flags & XFS_QMOPT_DQREPAIR);
memset(d, 0, sizeof(xfs_dqblk_t));
- INT_SET(d->dd_diskdq.d_magic, ARCH_CONVERT, XFS_DQUOT_MAGIC);
- INT_SET(d->dd_diskdq.d_version, ARCH_CONVERT, XFS_DQUOT_VERSION);
- INT_SET(d->dd_diskdq.d_id, ARCH_CONVERT, id);
- INT_SET(d->dd_diskdq.d_flags, ARCH_CONVERT, type);
+
+ d->dd_diskdq.d_magic = cpu_to_be16(XFS_DQUOT_MAGIC);
+ d->dd_diskdq.d_version = XFS_DQUOT_VERSION;
+ d->dd_diskdq.d_flags = type;
+ d->dd_diskdq.d_id = cpu_to_be32(id);
return errs;
}
@@ -2226,8 +2207,9 @@ xlog_recover_do_buffer_trans(
break;
default:
xfs_fs_cmn_err(CE_ALERT, log->l_mp,
- "xfs_log_recover: unknown buffer type 0x%x, dev %s",
- buf_f->blf_type, XFS_BUFTARG_NAME(log->l_targ));
+ "xfs_log_recover: unknown buffer type 0x%x, logdev %s",
+ buf_f->blf_type, log->l_mp->m_logname ?
+ log->l_mp->m_logname : "internal");
XFS_ERROR_REPORT("xlog_recover_do_buffer_trans",
XFS_ERRLEVEL_LOW, log->l_mp);
return XFS_ERROR(EFSCORRUPTED);
@@ -3178,13 +3160,12 @@ xlog_recover_clear_agi_bucket(
}
agi = XFS_BUF_TO_AGI(agibp);
- if (INT_GET(agi->agi_magicnum, ARCH_CONVERT) != XFS_AGI_MAGIC) {
+ if (be32_to_cpu(agi->agi_magicnum) != XFS_AGI_MAGIC) {
xfs_trans_cancel(tp, XFS_TRANS_ABORT);
return;
}
- ASSERT(INT_GET(agi->agi_magicnum, ARCH_CONVERT) == XFS_AGI_MAGIC);
- INT_SET(agi->agi_unlinked[bucket], ARCH_CONVERT, NULLAGINO);
+ agi->agi_unlinked[bucket] = cpu_to_be32(NULLAGINO);
offset = offsetof(xfs_agi_t, agi_unlinked) +
(sizeof(xfs_agino_t) * bucket);
xfs_trans_log_buf(tp, agibp, offset,
@@ -3243,12 +3224,11 @@ xlog_recover_process_iunlinks(
XFS_AG_DADDR(mp, agno, XFS_AGI_DADDR(mp)));
}
agi = XFS_BUF_TO_AGI(agibp);
- ASSERT(XFS_AGI_MAGIC ==
- INT_GET(agi->agi_magicnum, ARCH_CONVERT));
+ ASSERT(XFS_AGI_MAGIC == be32_to_cpu(agi->agi_magicnum));
for (bucket = 0; bucket < XFS_AGI_UNLINKED_BUCKETS; bucket++) {
- agino = INT_GET(agi->agi_unlinked[bucket], ARCH_CONVERT);
+ agino = be32_to_cpu(agi->agi_unlinked[bucket]);
while (agino != NULLAGINO) {
/*
@@ -3336,8 +3316,8 @@ xlog_recover_process_iunlinks(
XFS_AGI_DADDR(mp)));
}
agi = XFS_BUF_TO_AGI(agibp);
- ASSERT(XFS_AGI_MAGIC == INT_GET(
- agi->agi_magicnum, ARCH_CONVERT));
+ ASSERT(XFS_AGI_MAGIC == be32_to_cpu(
+ agi->agi_magicnum));
}
}
@@ -3938,8 +3918,9 @@ xlog_recover(
}
cmn_err(CE_NOTE,
- "Starting XFS recovery on filesystem: %s (dev: %s)",
- log->l_mp->m_fsname, XFS_BUFTARG_NAME(log->l_targ));
+ "Starting XFS recovery on filesystem: %s (logdev: %s)",
+ log->l_mp->m_fsname, log->l_mp->m_logname ?
+ log->l_mp->m_logname : "internal");
error = xlog_do_recover(log, head_blk, tail_blk);
log->l_flags |= XLOG_RECOVERY_NEEDED;
@@ -3987,8 +3968,9 @@ xlog_recover_finish(
xlog_recover_check_summary(log);
cmn_err(CE_NOTE,
- "Ending XFS recovery on filesystem: %s (dev: %s)",
- log->l_mp->m_fsname, XFS_BUFTARG_NAME(log->l_targ));
+ "Ending XFS recovery on filesystem: %s (logdev: %s)",
+ log->l_mp->m_fsname, log->l_mp->m_logname ?
+ log->l_mp->m_logname : "internal");
log->l_flags &= ~XLOG_RECOVERY_NEEDED;
} else {
cmn_err(CE_DEBUG,
@@ -4038,14 +4020,12 @@ xlog_recover_check_summary(
mp, agfbp, agfdaddr);
}
agfp = XFS_BUF_TO_AGF(agfbp);
- ASSERT(XFS_AGF_MAGIC ==
- INT_GET(agfp->agf_magicnum, ARCH_CONVERT));
- ASSERT(XFS_AGF_GOOD_VERSION(
- INT_GET(agfp->agf_versionnum, ARCH_CONVERT)));
- ASSERT(INT_GET(agfp->agf_seqno, ARCH_CONVERT) == agno);
-
- freeblks += INT_GET(agfp->agf_freeblks, ARCH_CONVERT) +
- INT_GET(agfp->agf_flcount, ARCH_CONVERT);
+ ASSERT(XFS_AGF_MAGIC == be32_to_cpu(agfp->agf_magicnum));
+ ASSERT(XFS_AGF_GOOD_VERSION(be32_to_cpu(agfp->agf_versionnum)));
+ ASSERT(be32_to_cpu(agfp->agf_seqno) == agno);
+
+ freeblks += be32_to_cpu(agfp->agf_freeblks) +
+ be32_to_cpu(agfp->agf_flcount);
xfs_buf_relse(agfbp);
agidaddr = XFS_AG_DADDR(mp, agno, XFS_AGI_DADDR(mp));
@@ -4056,14 +4036,12 @@ xlog_recover_check_summary(
mp, agibp, agidaddr);
}
agip = XFS_BUF_TO_AGI(agibp);
- ASSERT(XFS_AGI_MAGIC ==
- INT_GET(agip->agi_magicnum, ARCH_CONVERT));
- ASSERT(XFS_AGI_GOOD_VERSION(
- INT_GET(agip->agi_versionnum, ARCH_CONVERT)));
- ASSERT(INT_GET(agip->agi_seqno, ARCH_CONVERT) == agno);
-
- itotal += INT_GET(agip->agi_count, ARCH_CONVERT);
- ifree += INT_GET(agip->agi_freecount, ARCH_CONVERT);
+ ASSERT(XFS_AGI_MAGIC == be32_to_cpu(agip->agi_magicnum));
+ ASSERT(XFS_AGI_GOOD_VERSION(be32_to_cpu(agip->agi_versionnum)));
+ ASSERT(be32_to_cpu(agip->agi_seqno) == agno);
+
+ itotal += be32_to_cpu(agip->agi_count);
+ ifree += be32_to_cpu(agip->agi_freecount);
xfs_buf_relse(agibp);
}
diff --git a/fs/xfs/xfs_log_recover.h b/fs/xfs/xfs_log_recover.h
index 42158b442b55..b22545555301 100644
--- a/fs/xfs/xfs_log_recover.h
+++ b/fs/xfs/xfs_log_recover.h
@@ -1,33 +1,19 @@
/*
- * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000,2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __XFS_LOG_RECOVER_H__
#define __XFS_LOG_RECOVER_H__
diff --git a/fs/xfs/xfs_mac.h b/fs/xfs/xfs_mac.h
index 8d59aaffeb8e..18e0e98e03d0 100644
--- a/fs/xfs/xfs_mac.h
+++ b/fs/xfs/xfs_mac.h
@@ -1,33 +1,19 @@
/*
- * Copyright (c) 2001-2002 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2001-2002,2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __XFS_MAC_H__
#define __XFS_MAC_H__
diff --git a/fs/xfs/xfs_macros.c b/fs/xfs/xfs_macros.c
deleted file mode 100644
index 698c2cd62858..000000000000
--- a/fs/xfs/xfs_macros.c
+++ /dev/null
@@ -1,2141 +0,0 @@
-/*
- * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
- */
-
-#define XFS_MACRO_C
-
-#include "xfs.h"
-#include "xfs_macros.h"
-#include "xfs_types.h"
-#include "xfs_inum.h"
-#include "xfs_log.h"
-#include "xfs_trans.h"
-#include "xfs_sb.h"
-#include "xfs_ag.h"
-#include "xfs_dir.h"
-#include "xfs_dir2.h"
-#include "xfs_dmapi.h"
-#include "xfs_mount.h"
-#include "xfs_alloc_btree.h"
-#include "xfs_ialloc_btree.h"
-#include "xfs_bmap_btree.h"
-#include "xfs_btree.h"
-#include "xfs_attr_sf.h"
-#include "xfs_dir_sf.h"
-#include "xfs_dir2_sf.h"
-#include "xfs_dinode.h"
-#include "xfs_ialloc.h"
-#include "xfs_inode_item.h"
-#include "xfs_inode.h"
-#include "xfs_bmap.h"
-#include "xfs_rw.h"
-#include "xfs_log_priv.h"
-#include "xfs_da_btree.h"
-#include "xfs_attr_leaf.h"
-#include "xfs_dir_leaf.h"
-#include "xfs_dir2_data.h"
-#include "xfs_dir2_leaf.h"
-#include "xfs_dir2_block.h"
-#include "xfs_dir2_node.h"
-#include "xfs_bit.h"
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_ISNULLDSTARTBLOCK)
-int
-isnulldstartblock(xfs_dfsbno_t x)
-{
- return ISNULLDSTARTBLOCK(x);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_ISNULLSTARTBLOCK)
-int
-isnullstartblock(xfs_fsblock_t x)
-{
- return ISNULLSTARTBLOCK(x);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_NULLSTARTBLOCK)
-xfs_fsblock_t
-nullstartblock(int k)
-{
- return NULLSTARTBLOCK(k);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_STARTBLOCKVAL)
-xfs_filblks_t
-startblockval(xfs_fsblock_t x)
-{
- return STARTBLOCKVAL(x);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_AG_CHECK_DADDR)
-void
-xfs_ag_check_daddr(xfs_mount_t *mp, xfs_daddr_t d, xfs_extlen_t len)
-{
- XFS_AG_CHECK_DADDR(mp, d, len);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_AG_DADDR)
-xfs_daddr_t
-xfs_ag_daddr(xfs_mount_t *mp, xfs_agnumber_t agno, xfs_daddr_t d)
-{
- return XFS_AG_DADDR(mp, agno, d);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_AG_MAXLEVELS)
-int
-xfs_ag_maxlevels(xfs_mount_t *mp)
-{
- return XFS_AG_MAXLEVELS(mp);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_AGB_TO_DADDR)
-xfs_daddr_t
-xfs_agb_to_daddr(xfs_mount_t *mp, xfs_agnumber_t agno, xfs_agblock_t agbno)
-{
- return XFS_AGB_TO_DADDR(mp, agno, agbno);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_AGB_TO_FSB)
-xfs_fsblock_t
-xfs_agb_to_fsb(xfs_mount_t *mp, xfs_agnumber_t agno, xfs_agblock_t agbno)
-{
- return XFS_AGB_TO_FSB(mp, agno, agbno);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_AGBLOCK_MAX)
-xfs_agblock_t
-xfs_agblock_max(xfs_agblock_t a, xfs_agblock_t b)
-{
- return XFS_AGBLOCK_MAX(a, b);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_AGBLOCK_MIN)
-xfs_agblock_t
-xfs_agblock_min(xfs_agblock_t a, xfs_agblock_t b)
-{
- return XFS_AGBLOCK_MIN(a, b);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_AGF_BLOCK)
-xfs_agblock_t
-xfs_agf_block(xfs_mount_t *mp)
-{
- return XFS_AGF_BLOCK(mp);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_AGF_GOOD_VERSION)
-int
-xfs_agf_good_version(unsigned v)
-{
- return XFS_AGF_GOOD_VERSION(v);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_AGFL_BLOCK)
-xfs_agblock_t
-xfs_agfl_block(xfs_mount_t *mp)
-{
- return XFS_AGFL_BLOCK(mp);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_AGI_BLOCK)
-xfs_agblock_t
-xfs_agi_block(xfs_mount_t *mp)
-{
- return XFS_AGI_BLOCK(mp);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_AGI_GOOD_VERSION)
-int
-xfs_agi_good_version(unsigned v)
-{
- return XFS_AGI_GOOD_VERSION(v);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_AGINO_TO_AGBNO)
-xfs_agblock_t
-xfs_agino_to_agbno(xfs_mount_t *mp, xfs_agino_t i)
-{
- return XFS_AGINO_TO_AGBNO(mp, i);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_AGINO_TO_INO)
-xfs_ino_t
-xfs_agino_to_ino(xfs_mount_t *mp, xfs_agnumber_t a, xfs_agino_t i)
-{
- return XFS_AGINO_TO_INO(mp, a, i);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_AGINO_TO_OFFSET)
-int
-xfs_agino_to_offset(xfs_mount_t *mp, xfs_agino_t i)
-{
- return XFS_AGINO_TO_OFFSET(mp, i);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_ALLOC_BLOCK_MAXRECS)
-int
-xfs_alloc_block_maxrecs(int lev, xfs_btree_cur_t *cur)
-{
- return XFS_ALLOC_BLOCK_MAXRECS(lev, cur);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_ALLOC_BLOCK_MINRECS)
-int
-xfs_alloc_block_minrecs(int lev, xfs_btree_cur_t *cur)
-{
- return XFS_ALLOC_BLOCK_MINRECS(lev, cur);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_ALLOC_BLOCK_SIZE)
-/*ARGSUSED1*/
-int
-xfs_alloc_block_size(int lev, xfs_btree_cur_t *cur)
-{
- return XFS_ALLOC_BLOCK_SIZE(lev, cur);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_ALLOC_KEY_ADDR)
-/*ARGSUSED3*/
-xfs_alloc_key_t *
-xfs_alloc_key_addr(xfs_alloc_block_t *bb, int i, xfs_btree_cur_t *cur)
-{
- return XFS_ALLOC_KEY_ADDR(bb, i, cur);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_ALLOC_PTR_ADDR)
-xfs_alloc_ptr_t *
-xfs_alloc_ptr_addr(xfs_alloc_block_t *bb, int i, xfs_btree_cur_t *cur)
-{
- return XFS_ALLOC_PTR_ADDR(bb, i, cur);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_ALLOC_REC_ADDR)
-/*ARGSUSED3*/
-xfs_alloc_rec_t *
-xfs_alloc_rec_addr(xfs_alloc_block_t *bb, int i, xfs_btree_cur_t *cur)
-{
- return XFS_ALLOC_REC_ADDR(bb, i, cur);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_ATTR_LEAF_ENTSIZE_LOCAL)
-int
-xfs_attr_leaf_entsize_local(int nlen, int vlen)
-{
- return XFS_ATTR_LEAF_ENTSIZE_LOCAL(nlen, vlen);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_ATTR_LEAF_ENTSIZE_LOCAL_MAX)
-int
-xfs_attr_leaf_entsize_local_max(int bsize)
-{
- return XFS_ATTR_LEAF_ENTSIZE_LOCAL_MAX(bsize);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_ATTR_LEAF_ENTSIZE_REMOTE)
-int
-xfs_attr_leaf_entsize_remote(int nlen)
-{
- return XFS_ATTR_LEAF_ENTSIZE_REMOTE(nlen);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_ATTR_LEAF_NAME)
-char *
-xfs_attr_leaf_name(xfs_attr_leafblock_t *leafp, int idx)
-{
- return XFS_ATTR_LEAF_NAME(leafp, idx);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_ATTR_LEAF_NAME_LOCAL)
-xfs_attr_leaf_name_local_t *
-xfs_attr_leaf_name_local(xfs_attr_leafblock_t *leafp, int idx)
-{
- return XFS_ATTR_LEAF_NAME_LOCAL(leafp, idx);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_ATTR_LEAF_NAME_REMOTE)
-xfs_attr_leaf_name_remote_t *
-xfs_attr_leaf_name_remote(xfs_attr_leafblock_t *leafp, int idx)
-{
- return XFS_ATTR_LEAF_NAME_REMOTE(leafp, idx);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_ATTR_SF_ENTSIZE)
-int
-xfs_attr_sf_entsize(xfs_attr_sf_entry_t *sfep)
-{
- return XFS_ATTR_SF_ENTSIZE(sfep);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_ATTR_SF_ENTSIZE_BYNAME)
-int
-xfs_attr_sf_entsize_byname(int nlen, int vlen)
-{
- return XFS_ATTR_SF_ENTSIZE_BYNAME(nlen, vlen);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_ATTR_SF_NEXTENTRY)
-xfs_attr_sf_entry_t *
-xfs_attr_sf_nextentry(xfs_attr_sf_entry_t *sfep)
-{
- return XFS_ATTR_SF_NEXTENTRY(sfep);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_ATTR_SF_TOTSIZE)
-int
-xfs_attr_sf_totsize(xfs_inode_t *dp)
-{
- return XFS_ATTR_SF_TOTSIZE(dp);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_BHVTOI)
-xfs_inode_t *
-xfs_bhvtoi(bhv_desc_t *bhvp)
-{
- return XFS_BHVTOI(bhvp);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_BHVTOM)
-xfs_mount_t *
-xfs_bhvtom(bhv_desc_t *bdp)
-{
- return XFS_BHVTOM(bdp);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_VFSTOM)
-xfs_mount_t *
-xfs_vfstom(vfs_t *vfs)
-{
- return XFS_VFSTOM(vfs);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_BM_MAXLEVELS)
-int
-xfs_bm_maxlevels(xfs_mount_t *mp, int w)
-{
- return XFS_BM_MAXLEVELS(mp, w);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_BMAP_BLOCK_DMAXRECS)
-int
-xfs_bmap_block_dmaxrecs(int lev, xfs_btree_cur_t *cur)
-{
- return XFS_BMAP_BLOCK_DMAXRECS(lev, cur);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_BMAP_BLOCK_DMINRECS)
-int
-xfs_bmap_block_dminrecs(int lev, xfs_btree_cur_t *cur)
-{
- return XFS_BMAP_BLOCK_DMINRECS(lev, cur);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_BMAP_BLOCK_DSIZE)
-int
-xfs_bmap_block_dsize(int lev, xfs_btree_cur_t *cur)
-{
- return XFS_BMAP_BLOCK_DSIZE(lev, cur);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_BMAP_BLOCK_IMAXRECS)
-int
-xfs_bmap_block_imaxrecs(int lev, xfs_btree_cur_t *cur)
-{
- return XFS_BMAP_BLOCK_IMAXRECS(lev, cur);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_BMAP_BLOCK_IMINRECS)
-int
-xfs_bmap_block_iminrecs(int lev, xfs_btree_cur_t *cur)
-{
- return XFS_BMAP_BLOCK_IMINRECS(lev, cur);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_BMAP_BLOCK_ISIZE)
-int
-xfs_bmap_block_isize(int lev, xfs_btree_cur_t *cur)
-{
- return XFS_BMAP_BLOCK_ISIZE(lev, cur);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_BMAP_BROOT_KEY_ADDR)
-/*ARGSUSED3*/
-xfs_bmbt_key_t *
-xfs_bmap_broot_key_addr(xfs_bmbt_block_t *bb, int i, int sz)
-{
- return XFS_BMAP_BROOT_KEY_ADDR(bb, i, sz);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_BMAP_BROOT_MAXRECS)
-int
-xfs_bmap_broot_maxrecs(int sz)
-{
- return XFS_BMAP_BROOT_MAXRECS(sz);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_BMAP_BROOT_NUMRECS)
-int
-xfs_bmap_broot_numrecs(xfs_bmdr_block_t *bb)
-{
- return XFS_BMAP_BROOT_NUMRECS(bb);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_BMAP_BROOT_PTR_ADDR)
-xfs_bmbt_ptr_t *
-xfs_bmap_broot_ptr_addr(xfs_bmbt_block_t *bb, int i, int sz)
-{
- return XFS_BMAP_BROOT_PTR_ADDR(bb, i, sz);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_BMAP_BROOT_REC_ADDR)
-/*ARGSUSED3*/
-xfs_bmbt_rec_t *
-xfs_bmap_broot_rec_addr(xfs_bmbt_block_t *bb, int i, int sz)
-{
- return XFS_BMAP_BROOT_REC_ADDR(bb, i, sz);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_BMAP_BROOT_SPACE)
-int
-xfs_bmap_broot_space(xfs_bmdr_block_t *bb)
-{
- return XFS_BMAP_BROOT_SPACE(bb);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_BMAP_BROOT_SPACE_CALC)
-int
-xfs_bmap_broot_space_calc(int nrecs)
-{
- return XFS_BMAP_BROOT_SPACE_CALC(nrecs);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_BMAP_IBLOCK_SIZE)
-/*ARGSUSED1*/
-int
-xfs_bmap_iblock_size(int lev, xfs_btree_cur_t *cur)
-{
- return XFS_BMAP_IBLOCK_SIZE(lev, cur);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_BMAP_INIT)
-void
-xfs_bmap_init(xfs_bmap_free_t *flp, xfs_fsblock_t *fbp)
-{
- XFS_BMAP_INIT(flp, fbp);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_BMAP_KEY_DADDR)
-/*ARGSUSED3*/
-xfs_bmbt_key_t *
-xfs_bmap_key_daddr(xfs_bmbt_block_t *bb, int i, xfs_btree_cur_t *cur)
-{
- return XFS_BMAP_KEY_DADDR(bb, i, cur);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_BMAP_KEY_IADDR)
-/*ARGSUSED3*/
-xfs_bmbt_key_t *
-xfs_bmap_key_iaddr(xfs_bmbt_block_t *bb, int i, xfs_btree_cur_t *cur)
-{
- return XFS_BMAP_KEY_IADDR(bb, i, cur);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_BMAP_PTR_DADDR)
-xfs_bmbt_ptr_t *
-xfs_bmap_ptr_daddr(xfs_bmbt_block_t *bb, int i, xfs_btree_cur_t *cur)
-{
- return XFS_BMAP_PTR_DADDR(bb, i, cur);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_BMAP_PTR_IADDR)
-xfs_bmbt_ptr_t *
-xfs_bmap_ptr_iaddr(xfs_bmbt_block_t *bb, int i, xfs_btree_cur_t *cur)
-{
- return XFS_BMAP_PTR_IADDR(bb, i, cur);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_BMAP_RBLOCK_DSIZE)
-/*ARGSUSED1*/
-int
-xfs_bmap_rblock_dsize(int lev, xfs_btree_cur_t *cur)
-{
- return XFS_BMAP_RBLOCK_DSIZE(lev, cur);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_BMAP_RBLOCK_ISIZE)
-/*ARGSUSED1*/
-int
-xfs_bmap_rblock_isize(int lev, xfs_btree_cur_t *cur)
-{
- return XFS_BMAP_RBLOCK_ISIZE(lev, cur);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_BMAP_REC_DADDR)
-/*ARGSUSED3*/
-xfs_bmbt_rec_t *
-xfs_bmap_rec_daddr(xfs_bmbt_block_t *bb, int i, xfs_btree_cur_t *cur)
-{
- return XFS_BMAP_REC_DADDR(bb, i, cur);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_BMAP_REC_IADDR)
-/*ARGSUSED3*/
-xfs_bmbt_rec_t *
-xfs_bmap_rec_iaddr(xfs_bmbt_block_t *bb, int i, xfs_btree_cur_t *cur)
-{
- return XFS_BMAP_REC_IADDR(bb, i, cur);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_BMAP_SANITY_CHECK)
-int
-xfs_bmap_sanity_check(xfs_mount_t *mp, xfs_bmbt_block_t *bb, int level)
-{
- return XFS_BMAP_SANITY_CHECK(mp, bb, level);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_BMAPI_AFLAG)
-int
-xfs_bmapi_aflag(int w)
-{
- return XFS_BMAPI_AFLAG(w);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_BMDR_SPACE_CALC)
-int
-xfs_bmdr_space_calc(int nrecs)
-{
- return XFS_BMDR_SPACE_CALC(nrecs);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_BNO_BLOCK)
-xfs_agblock_t
-xfs_bno_block(xfs_mount_t *mp)
-{
- return XFS_BNO_BLOCK(mp);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_BTREE_LONG_PTRS)
-int
-xfs_btree_long_ptrs(xfs_btnum_t btnum)
-{
- return XFS_BTREE_LONG_PTRS(btnum);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_BUF_TO_AGF)
-xfs_agf_t *
-xfs_buf_to_agf(xfs_buf_t *bp)
-{
- return XFS_BUF_TO_AGF(bp);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_BUF_TO_AGFL)
-xfs_agfl_t *
-xfs_buf_to_agfl(xfs_buf_t *bp)
-{
- return XFS_BUF_TO_AGFL(bp);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_BUF_TO_AGI)
-xfs_agi_t *
-xfs_buf_to_agi(xfs_buf_t *bp)
-{
- return XFS_BUF_TO_AGI(bp);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_BUF_TO_ALLOC_BLOCK)
-xfs_alloc_block_t *
-xfs_buf_to_alloc_block(xfs_buf_t *bp)
-{
- return XFS_BUF_TO_ALLOC_BLOCK(bp);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_BUF_TO_BLOCK)
-xfs_btree_block_t *
-xfs_buf_to_block(xfs_buf_t *bp)
-{
- return XFS_BUF_TO_BLOCK(bp);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_BUF_TO_BMBT_BLOCK)
-xfs_bmbt_block_t *
-xfs_buf_to_bmbt_block(xfs_buf_t *bp)
-{
- return XFS_BUF_TO_BMBT_BLOCK(bp);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_BUF_TO_DINODE)
-xfs_dinode_t *
-xfs_buf_to_dinode(xfs_buf_t *bp)
-{
- return XFS_BUF_TO_DINODE(bp);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_BUF_TO_INOBT_BLOCK)
-xfs_inobt_block_t *
-xfs_buf_to_inobt_block(xfs_buf_t *bp)
-{
- return XFS_BUF_TO_INOBT_BLOCK(bp);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_BUF_TO_LBLOCK)
-xfs_btree_lblock_t *
-xfs_buf_to_lblock(xfs_buf_t *bp)
-{
- return XFS_BUF_TO_LBLOCK(bp);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_BUF_TO_SBLOCK)
-xfs_btree_sblock_t *
-xfs_buf_to_sblock(xfs_buf_t *bp)
-{
- return XFS_BUF_TO_SBLOCK(bp);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_BUF_TO_SBP)
-xfs_sb_t *
-xfs_buf_to_sbp(xfs_buf_t *bp)
-{
- return XFS_BUF_TO_SBP(bp);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_CFORK_ASIZE)
-int
-xfs_cfork_asize_disk(xfs_dinode_core_t *dcp, xfs_mount_t *mp)
-{
- return XFS_CFORK_ASIZE_DISK(dcp, mp);
-}
-int
-xfs_cfork_asize(xfs_dinode_core_t *dcp, xfs_mount_t *mp)
-{
- return XFS_CFORK_ASIZE(dcp, mp);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_CFORK_BOFF)
-int
-xfs_cfork_boff_disk(xfs_dinode_core_t *dcp)
-{
- return XFS_CFORK_BOFF_DISK(dcp);
-}
-int
-xfs_cfork_boff(xfs_dinode_core_t *dcp)
-{
- return XFS_CFORK_BOFF(dcp);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_CFORK_DSIZE)
-int
-xfs_cfork_dsize_disk(xfs_dinode_core_t *dcp, xfs_mount_t *mp)
-{
- return XFS_CFORK_DSIZE_DISK(dcp, mp);
-}
-int
-xfs_cfork_dsize(xfs_dinode_core_t *dcp, xfs_mount_t *mp)
-{
- return XFS_CFORK_DSIZE(dcp, mp);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_CFORK_FMT_SET)
-void
-xfs_cfork_fmt_set(xfs_dinode_core_t *dcp, int w, int n)
-{
- XFS_CFORK_FMT_SET(dcp, w, n);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_CFORK_FORMAT)
-int
-xfs_cfork_format(xfs_dinode_core_t *dcp, int w)
-{
- return XFS_CFORK_FORMAT(dcp, w);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_CFORK_NEXT_SET)
-void
-xfs_cfork_next_set(xfs_dinode_core_t *dcp, int w, int n)
-{
- XFS_CFORK_NEXT_SET(dcp, w, n);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_CFORK_NEXTENTS)
-int
-xfs_cfork_nextents_disk(xfs_dinode_core_t *dcp, int w)
-{
- return XFS_CFORK_NEXTENTS_DISK(dcp, w);
-}
-int
-xfs_cfork_nextents(xfs_dinode_core_t *dcp, int w)
-{
- return XFS_CFORK_NEXTENTS(dcp, w);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_CFORK_Q)
-int
-xfs_cfork_q_disk(xfs_dinode_core_t *dcp)
-{
- return XFS_CFORK_Q_DISK(dcp);
-}
-int
-xfs_cfork_q(xfs_dinode_core_t *dcp)
-{
- return XFS_CFORK_Q(dcp);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_CFORK_SIZE)
-int
-xfs_cfork_size_disk(xfs_dinode_core_t *dcp, xfs_mount_t *mp, int w)
-{
- return XFS_CFORK_SIZE_DISK(dcp, mp, w);
-}
-int
-xfs_cfork_size(xfs_dinode_core_t *dcp, xfs_mount_t *mp, int w)
-{
- return XFS_CFORK_SIZE(dcp, mp, w);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_CNT_BLOCK)
-xfs_agblock_t
-xfs_cnt_block(xfs_mount_t *mp)
-{
- return XFS_CNT_BLOCK(mp);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_DA_COOKIE_BNO)
-xfs_dablk_t
-xfs_da_cookie_bno(xfs_mount_t *mp, xfs_off_t cookie)
-{
- return XFS_DA_COOKIE_BNO(mp, cookie);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_DA_COOKIE_ENTRY)
-int
-xfs_da_cookie_entry(xfs_mount_t *mp, xfs_off_t cookie)
-{
- return XFS_DA_COOKIE_ENTRY(mp, cookie);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_DA_COOKIE_HASH)
-/*ARGSUSED1*/
-xfs_dahash_t
-xfs_da_cookie_hash(xfs_mount_t *mp, xfs_off_t cookie)
-{
- return XFS_DA_COOKIE_HASH(mp, cookie);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_DA_MAKE_BNOENTRY)
-__uint32_t
-xfs_da_make_bnoentry(xfs_mount_t *mp, xfs_dablk_t bno, int entry)
-{
- return XFS_DA_MAKE_BNOENTRY(mp, bno, entry);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_DA_MAKE_COOKIE)
-xfs_off_t
-xfs_da_make_cookie(xfs_mount_t *mp, xfs_dablk_t bno, int entry,
- xfs_dahash_t hash)
-{
- return XFS_DA_MAKE_COOKIE(mp, bno, entry, hash);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_DADDR_TO_AGBNO)
-xfs_agblock_t
-xfs_daddr_to_agbno(xfs_mount_t *mp, xfs_daddr_t d)
-{
- return XFS_DADDR_TO_AGBNO(mp, d);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_DADDR_TO_AGNO)
-xfs_agnumber_t
-xfs_daddr_to_agno(xfs_mount_t *mp, xfs_daddr_t d)
-{
- return XFS_DADDR_TO_AGNO(mp, d);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_DADDR_TO_FSB)
-xfs_fsblock_t
-xfs_daddr_to_fsb(xfs_mount_t *mp, xfs_daddr_t d)
-{
- return XFS_DADDR_TO_FSB(mp, d);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_DFORK_APTR)
-char *
-xfs_dfork_aptr(xfs_dinode_t *dip)
-{
- return XFS_DFORK_APTR(dip);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_DFORK_ASIZE)
-int
-xfs_dfork_asize(xfs_dinode_t *dip, xfs_mount_t *mp)
-{
- return XFS_DFORK_ASIZE(dip, mp);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_DFORK_BOFF)
-int
-xfs_dfork_boff(xfs_dinode_t *dip)
-{
- return XFS_DFORK_BOFF(dip);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_DFORK_DPTR)
-char *
-xfs_dfork_dptr(xfs_dinode_t *dip)
-{
- return XFS_DFORK_DPTR(dip);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_DFORK_DSIZE)
-int
-xfs_dfork_dsize(xfs_dinode_t *dip, xfs_mount_t *mp)
-{
- return XFS_DFORK_DSIZE(dip, mp);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_DFORK_NEXTENTS)
-int
-xfs_dfork_nextents(xfs_dinode_t *dip, int w)
-{
- return XFS_DFORK_NEXTENTS(dip, w);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_DFORK_PTR)
-char *
-xfs_dfork_ptr(xfs_dinode_t *dip, int w)
-{
- return XFS_DFORK_PTR(dip, w);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_DFORK_Q)
-int
-xfs_dfork_q(xfs_dinode_t *dip)
-{
- return XFS_DFORK_Q(dip);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_DFORK_SIZE)
-int
-xfs_dfork_size(xfs_dinode_t *dip, xfs_mount_t *mp, int w)
-{
- return XFS_DFORK_SIZE(dip, mp, w);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_DINODE_GOOD_VERSION)
-int
-xfs_dinode_good_version(int v)
-{
- return XFS_DINODE_GOOD_VERSION(v);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_DIR_LEAF_ENTSIZE_BYENTRY)
-int
-xfs_dir_leaf_entsize_byentry(xfs_dir_leaf_entry_t *entry)
-{
- return XFS_DIR_LEAF_ENTSIZE_BYENTRY(entry);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_DIR_LEAF_ENTSIZE_BYNAME)
-int
-xfs_dir_leaf_entsize_byname(int len)
-{
- return XFS_DIR_LEAF_ENTSIZE_BYNAME(len);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_DIR_LEAF_NAMESTRUCT)
-xfs_dir_leaf_name_t *
-xfs_dir_leaf_namestruct(xfs_dir_leafblock_t *leafp, int offset)
-{
- return XFS_DIR_LEAF_NAMESTRUCT(leafp, offset);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_DIR_SF_ALLFIT)
-int
-xfs_dir_sf_allfit(int count, int totallen)
-{
- return XFS_DIR_SF_ALLFIT(count, totallen);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_DIR_SF_ENTSIZE_BYENTRY)
-int
-xfs_dir_sf_entsize_byentry(xfs_dir_sf_entry_t *sfep)
-{
- return XFS_DIR_SF_ENTSIZE_BYENTRY(sfep);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_DIR_SF_ENTSIZE_BYNAME)
-int
-xfs_dir_sf_entsize_byname(int len)
-{
- return XFS_DIR_SF_ENTSIZE_BYNAME(len);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_DIR_SF_GET_DIRINO)
-void
-xfs_dir_sf_get_dirino(xfs_dir_ino_t *from, xfs_ino_t *to)
-{
- XFS_DIR_SF_GET_DIRINO(from, to);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_DIR_SF_NEXTENTRY)
-xfs_dir_sf_entry_t *
-xfs_dir_sf_nextentry(xfs_dir_sf_entry_t *sfep)
-{
- return XFS_DIR_SF_NEXTENTRY(sfep);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_DIR_SF_PUT_DIRINO)
-void
-xfs_dir_sf_put_dirino(xfs_ino_t *from, xfs_dir_ino_t *to)
-{
- XFS_DIR_SF_PUT_DIRINO(from, to);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_DIR2_BLOCK_LEAF_P)
-xfs_dir2_leaf_entry_t *
-xfs_dir2_block_leaf_p(xfs_dir2_block_tail_t *btp)
-{
- return XFS_DIR2_BLOCK_LEAF_P(btp);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_DIR2_BLOCK_TAIL_P)
-xfs_dir2_block_tail_t *
-xfs_dir2_block_tail_p(xfs_mount_t *mp, xfs_dir2_block_t *block)
-{
- return XFS_DIR2_BLOCK_TAIL_P(mp, block);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_DIR2_BYTE_TO_DA)
-xfs_dablk_t
-xfs_dir2_byte_to_da(xfs_mount_t *mp, xfs_dir2_off_t by)
-{
- return XFS_DIR2_BYTE_TO_DA(mp, by);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_DIR2_BYTE_TO_DATAPTR)
-/* ARGSUSED */
-xfs_dir2_dataptr_t
-xfs_dir2_byte_to_dataptr(xfs_mount_t *mp, xfs_dir2_off_t by)
-{
- return XFS_DIR2_BYTE_TO_DATAPTR(mp, by);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_DIR2_BYTE_TO_DB)
-xfs_dir2_db_t
-xfs_dir2_byte_to_db(xfs_mount_t *mp, xfs_dir2_off_t by)
-{
- return XFS_DIR2_BYTE_TO_DB(mp, by);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_DIR2_BYTE_TO_OFF)
-xfs_dir2_data_aoff_t
-xfs_dir2_byte_to_off(xfs_mount_t *mp, xfs_dir2_off_t by)
-{
- return XFS_DIR2_BYTE_TO_OFF(mp, by);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_DIR2_DA_TO_BYTE)
-xfs_dir2_off_t
-xfs_dir2_da_to_byte(xfs_mount_t *mp, xfs_dablk_t da)
-{
- return XFS_DIR2_DA_TO_BYTE(mp, da);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_DIR2_DA_TO_DB)
-xfs_dir2_db_t
-xfs_dir2_da_to_db(xfs_mount_t *mp, xfs_dablk_t da)
-{
- return XFS_DIR2_DA_TO_DB(mp, da);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_DIR2_DATA_ENTRY_TAG_P)
-xfs_dir2_data_off_t *
-xfs_dir2_data_entry_tag_p(xfs_dir2_data_entry_t *dep)
-{
- return XFS_DIR2_DATA_ENTRY_TAG_P(dep);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_DIR2_DATA_ENTSIZE)
-int
-xfs_dir2_data_entsize(int n)
-{
- return XFS_DIR2_DATA_ENTSIZE(n);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_DIR2_DATA_UNUSED_TAG_P)
-xfs_dir2_data_off_t *
-xfs_dir2_data_unused_tag_p(xfs_dir2_data_unused_t *dup)
-{
- return XFS_DIR2_DATA_UNUSED_TAG_P(dup);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_DIR2_DATAPTR_TO_BYTE)
-/* ARGSUSED */
-xfs_dir2_off_t
-xfs_dir2_dataptr_to_byte(xfs_mount_t *mp, xfs_dir2_dataptr_t dp)
-{
- return XFS_DIR2_DATAPTR_TO_BYTE(mp, dp);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_DIR2_DATAPTR_TO_DB)
-xfs_dir2_db_t
-xfs_dir2_dataptr_to_db(xfs_mount_t *mp, xfs_dir2_dataptr_t dp)
-{
- return XFS_DIR2_DATAPTR_TO_DB(mp, dp);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_DIR2_DATAPTR_TO_OFF)
-xfs_dir2_data_aoff_t
-xfs_dir2_dataptr_to_off(xfs_mount_t *mp, xfs_dir2_dataptr_t dp)
-{
- return XFS_DIR2_DATAPTR_TO_OFF(mp, dp);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_DIR2_DB_OFF_TO_BYTE)
-xfs_dir2_off_t
-xfs_dir2_db_off_to_byte(xfs_mount_t *mp, xfs_dir2_db_t db,
- xfs_dir2_data_aoff_t o)
-{
- return XFS_DIR2_DB_OFF_TO_BYTE(mp, db, o);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_DIR2_DB_OFF_TO_DATAPTR)
-xfs_dir2_dataptr_t
-xfs_dir2_db_off_to_dataptr(xfs_mount_t *mp, xfs_dir2_db_t db,
- xfs_dir2_data_aoff_t o)
-{
- return XFS_DIR2_DB_OFF_TO_DATAPTR(mp, db, o);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_DIR2_DB_TO_DA)
-xfs_dablk_t
-xfs_dir2_db_to_da(xfs_mount_t *mp, xfs_dir2_db_t db)
-{
- return XFS_DIR2_DB_TO_DA(mp, db);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_DIR2_DB_TO_FDB)
-xfs_dir2_db_t
-xfs_dir2_db_to_fdb(xfs_mount_t *mp, xfs_dir2_db_t db)
-{
- return XFS_DIR2_DB_TO_FDB(mp, db);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_DIR2_DB_TO_FDINDEX)
-int
-xfs_dir2_db_to_fdindex(xfs_mount_t *mp, xfs_dir2_db_t db)
-{
- return XFS_DIR2_DB_TO_FDINDEX(mp, db);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_DIR2_LEAF_BESTS_P)
-xfs_dir2_data_off_t *
-xfs_dir2_leaf_bests_p(xfs_dir2_leaf_tail_t *ltp)
-{
- return XFS_DIR2_LEAF_BESTS_P(ltp);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_DIR2_LEAF_TAIL_P)
-xfs_dir2_leaf_tail_t *
-xfs_dir2_leaf_tail_p(xfs_mount_t *mp, xfs_dir2_leaf_t *lp)
-{
- return XFS_DIR2_LEAF_TAIL_P(mp, lp);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_DIR2_MAX_LEAF_ENTS)
-int
-xfs_dir2_max_leaf_ents(xfs_mount_t *mp)
-{
- return XFS_DIR2_MAX_LEAF_ENTS(mp);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_DIR2_SF_ENTSIZE_BYENTRY)
-int
-xfs_dir2_sf_entsize_byentry(xfs_dir2_sf_t *sfp, xfs_dir2_sf_entry_t *sfep)
-{
- return XFS_DIR2_SF_ENTSIZE_BYENTRY(sfp, sfep);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_DIR2_SF_FIRSTENTRY)
-xfs_dir2_sf_entry_t *
-xfs_dir2_sf_firstentry(xfs_dir2_sf_t *sfp)
-{
- return XFS_DIR2_SF_FIRSTENTRY(sfp);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_DIR2_SF_ENTSIZE_BYNAME)
-int
-xfs_dir2_sf_entsize_byname(xfs_dir2_sf_t *sfp, int len)
-{
- return XFS_DIR2_SF_ENTSIZE_BYNAME(sfp, len);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_DIR2_SF_GET_INUMBER)
-xfs_intino_t
-xfs_dir2_sf_get_inumber(xfs_dir2_sf_t *sfp, xfs_dir2_inou_t *from)
-{
- return XFS_DIR2_SF_GET_INUMBER(sfp, from);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_DIR2_SF_GET_OFFSET)
-xfs_dir2_data_aoff_t
-xfs_dir2_sf_get_offset(xfs_dir2_sf_entry_t *sfep)
-{
- return XFS_DIR2_SF_GET_OFFSET(sfep);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_DIR2_SF_HDR_SIZE)
-int
-xfs_dir2_sf_hdr_size(int i8count)
-{
- return XFS_DIR2_SF_HDR_SIZE(i8count);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_DIR2_SF_INUMBERP)
-xfs_dir2_inou_t *
-xfs_dir2_sf_inumberp(xfs_dir2_sf_entry_t *sfep)
-{
- return XFS_DIR2_SF_INUMBERP(sfep);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_DIR2_SF_NEXTENTRY)
-xfs_dir2_sf_entry_t *
-xfs_dir2_sf_nextentry(xfs_dir2_sf_t *sfp, xfs_dir2_sf_entry_t *sfep)
-{
- return XFS_DIR2_SF_NEXTENTRY(sfp, sfep);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_DIR2_SF_PUT_INUMBER)
-void
-xfs_dir2_sf_put_inumber(xfs_dir2_sf_t *sfp, xfs_ino_t *from, xfs_dir2_inou_t *to)
-{
- XFS_DIR2_SF_PUT_INUMBER(sfp, from, to);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_DIR2_SF_PUT_OFFSET)
-void
-xfs_dir2_sf_put_offset(xfs_dir2_sf_entry_t *sfep, xfs_dir2_data_aoff_t off)
-{
- XFS_DIR2_SF_PUT_OFFSET(sfep, off);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_EXTFMT_INODE )
-xfs_exntfmt_t
-xfs_extfmt_inode(struct xfs_inode *ip)
-{
- return XFS_EXTFMT_INODE(ip);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_EXTLEN_MAX)
-xfs_extlen_t
-xfs_extlen_max(xfs_extlen_t a, xfs_extlen_t b)
-{
- return XFS_EXTLEN_MAX(a, b);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_EXTLEN_MIN)
-xfs_extlen_t
-xfs_extlen_min(xfs_extlen_t a, xfs_extlen_t b)
-{
- return XFS_EXTLEN_MIN(a, b);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_FILBLKS_MAX)
-xfs_filblks_t
-xfs_filblks_max(xfs_filblks_t a, xfs_filblks_t b)
-{
- return XFS_FILBLKS_MAX(a, b);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_FILBLKS_MIN)
-xfs_filblks_t
-xfs_filblks_min(xfs_filblks_t a, xfs_filblks_t b)
-{
- return XFS_FILBLKS_MIN(a, b);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_FILEOFF_MAX)
-xfs_fileoff_t
-xfs_fileoff_max(xfs_fileoff_t a, xfs_fileoff_t b)
-{
- return XFS_FILEOFF_MAX(a, b);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_FILEOFF_MIN)
-xfs_fileoff_t
-xfs_fileoff_min(xfs_fileoff_t a, xfs_fileoff_t b)
-{
- return XFS_FILEOFF_MIN(a, b);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_FSB_SANITY_CHECK)
-int
-xfs_fsb_sanity_check(xfs_mount_t *mp, xfs_fsblock_t fsbno)
-{
- return XFS_FSB_SANITY_CHECK(mp, fsbno);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_FSB_TO_AGBNO)
-xfs_agblock_t
-xfs_fsb_to_agbno(xfs_mount_t *mp, xfs_fsblock_t fsbno)
-{
- return XFS_FSB_TO_AGBNO(mp, fsbno);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_FSB_TO_AGNO)
-xfs_agnumber_t
-xfs_fsb_to_agno(xfs_mount_t *mp, xfs_fsblock_t fsbno)
-{
- return XFS_FSB_TO_AGNO(mp, fsbno);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_FSB_TO_DADDR)
-xfs_daddr_t
-xfs_fsb_to_daddr(xfs_mount_t *mp, xfs_fsblock_t fsbno)
-{
- return XFS_FSB_TO_DADDR(mp, fsbno);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_FSB_TO_DB)
-xfs_daddr_t
-xfs_fsb_to_db(xfs_inode_t *ip, xfs_fsblock_t fsb)
-{
- return XFS_FSB_TO_DB(ip, fsb);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_HDR_BLOCK)
-xfs_agblock_t
-xfs_hdr_block(xfs_mount_t *mp, xfs_daddr_t d)
-{
- return XFS_HDR_BLOCK(mp, d);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_IALLOC_BLOCKS)
-xfs_extlen_t
-xfs_ialloc_blocks(xfs_mount_t *mp)
-{
- return XFS_IALLOC_BLOCKS(mp);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_IALLOC_FIND_FREE)
-int
-xfs_ialloc_find_free(xfs_inofree_t *fp)
-{
- return XFS_IALLOC_FIND_FREE(fp);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_IALLOC_INODES)
-int
-xfs_ialloc_inodes(xfs_mount_t *mp)
-{
- return XFS_IALLOC_INODES(mp);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_IBT_BLOCK)
-xfs_agblock_t
-xfs_ibt_block(xfs_mount_t *mp)
-{
- return XFS_IBT_BLOCK(mp);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_IFORK_ASIZE)
-int
-xfs_ifork_asize(xfs_inode_t *ip)
-{
- return XFS_IFORK_ASIZE(ip);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_IFORK_DSIZE)
-int
-xfs_ifork_dsize(xfs_inode_t *ip)
-{
- return XFS_IFORK_DSIZE(ip);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_IFORK_FMT_SET)
-void
-xfs_ifork_fmt_set(xfs_inode_t *ip, int w, int n)
-{
- XFS_IFORK_FMT_SET(ip, w, n);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_IFORK_FORMAT)
-int
-xfs_ifork_format(xfs_inode_t *ip, int w)
-{
- return XFS_IFORK_FORMAT(ip, w);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_IFORK_NEXT_SET)
-void
-xfs_ifork_next_set(xfs_inode_t *ip, int w, int n)
-{
- XFS_IFORK_NEXT_SET(ip, w, n);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_IFORK_NEXTENTS)
-int
-xfs_ifork_nextents(xfs_inode_t *ip, int w)
-{
- return XFS_IFORK_NEXTENTS(ip, w);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_IFORK_PTR)
-xfs_ifork_t *
-xfs_ifork_ptr(xfs_inode_t *ip, int w)
-{
- return XFS_IFORK_PTR(ip, w);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_IFORK_Q)
-int
-xfs_ifork_q(xfs_inode_t *ip)
-{
- return XFS_IFORK_Q(ip);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_IFORK_SIZE)
-int
-xfs_ifork_size(xfs_inode_t *ip, int w)
-{
- return XFS_IFORK_SIZE(ip, w);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_ILOG_FBROOT)
-int
-xfs_ilog_fbroot(int w)
-{
- return XFS_ILOG_FBROOT(w);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_ILOG_FDATA)
-int
-xfs_ilog_fdata(int w)
-{
- return XFS_ILOG_FDATA(w);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_ILOG_FEXT)
-int
-xfs_ilog_fext(int w)
-{
- return XFS_ILOG_FEXT(w);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_IN_MAXLEVELS)
-int
-xfs_in_maxlevels(xfs_mount_t *mp)
-{
- return XFS_IN_MAXLEVELS(mp);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_INO_AGBNO_BITS)
-int
-xfs_ino_agbno_bits(xfs_mount_t *mp)
-{
- return XFS_INO_AGBNO_BITS(mp);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_INO_AGINO_BITS)
-int
-xfs_ino_agino_bits(xfs_mount_t *mp)
-{
- return XFS_INO_AGINO_BITS(mp);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_INO_AGNO_BITS)
-int
-xfs_ino_agno_bits(xfs_mount_t *mp)
-{
- return XFS_INO_AGNO_BITS(mp);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_INO_BITS)
-int
-xfs_ino_bits(xfs_mount_t *mp)
-{
- return XFS_INO_BITS(mp);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_INO_MASK)
-__uint32_t
-xfs_ino_mask(int k)
-{
- return XFS_INO_MASK(k);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_INO_OFFSET_BITS)
-int
-xfs_ino_offset_bits(xfs_mount_t *mp)
-{
- return XFS_INO_OFFSET_BITS(mp);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_INO_TO_AGBNO)
-xfs_agblock_t
-xfs_ino_to_agbno(xfs_mount_t *mp, xfs_ino_t i)
-{
- return XFS_INO_TO_AGBNO(mp, i);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_INO_TO_AGINO)
-xfs_agino_t
-xfs_ino_to_agino(xfs_mount_t *mp, xfs_ino_t i)
-{
- return XFS_INO_TO_AGINO(mp, i);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_INO_TO_AGNO)
-xfs_agnumber_t
-xfs_ino_to_agno(xfs_mount_t *mp, xfs_ino_t i)
-{
- return XFS_INO_TO_AGNO(mp, i);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_INO_TO_FSB)
-xfs_fsblock_t
-xfs_ino_to_fsb(xfs_mount_t *mp, xfs_ino_t i)
-{
- return XFS_INO_TO_FSB(mp, i);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_INO_TO_OFFSET)
-int
-xfs_ino_to_offset(xfs_mount_t *mp, xfs_ino_t i)
-{
- return XFS_INO_TO_OFFSET(mp, i);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_INOBT_BLOCK_MAXRECS)
-int
-xfs_inobt_block_maxrecs(int lev, xfs_btree_cur_t *cur)
-{
- return XFS_INOBT_BLOCK_MAXRECS(lev, cur);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_INOBT_BLOCK_MINRECS)
-int
-xfs_inobt_block_minrecs(int lev, xfs_btree_cur_t *cur)
-{
- return XFS_INOBT_BLOCK_MINRECS(lev, cur);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_INOBT_BLOCK_SIZE)
-/*ARGSUSED1*/
-int
-xfs_inobt_block_size(int lev, xfs_btree_cur_t *cur)
-{
- return XFS_INOBT_BLOCK_SIZE(lev, cur);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_INOBT_CLR_FREE)
-void
-xfs_inobt_clr_free(xfs_inobt_rec_t *rp, int i)
-{
- XFS_INOBT_CLR_FREE(rp, i);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_INOBT_IS_FREE)
-int
-xfs_inobt_is_free(xfs_inobt_rec_t *rp, int i)
-{
- return XFS_INOBT_IS_FREE(rp, i);
-}
-int
-xfs_inobt_is_free_disk(xfs_inobt_rec_t *rp, int i)
-{
- return XFS_INOBT_IS_FREE_DISK(rp, i);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_INOBT_IS_LAST_REC)
-int
-xfs_inobt_is_last_rec(xfs_btree_cur_t *cur)
-{
- return XFS_INOBT_IS_LAST_REC(cur);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_INOBT_KEY_ADDR)
-/*ARGSUSED3*/
-xfs_inobt_key_t *
-xfs_inobt_key_addr(xfs_inobt_block_t *bb, int i, xfs_btree_cur_t *cur)
-{
- return XFS_INOBT_KEY_ADDR(bb, i, cur);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_INOBT_MASK)
-xfs_inofree_t
-xfs_inobt_mask(int i)
-{
- return XFS_INOBT_MASK(i);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_INOBT_MASKN)
-xfs_inofree_t
-xfs_inobt_maskn(int i, int n)
-{
- return XFS_INOBT_MASKN(i, n);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_INOBT_PTR_ADDR)
-xfs_inobt_ptr_t *
-xfs_inobt_ptr_addr(xfs_inobt_block_t *bb, int i, xfs_btree_cur_t *cur)
-{
- return XFS_INOBT_PTR_ADDR(bb, i, cur);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_INOBT_REC_ADDR)
-/*ARGSUSED3*/
-xfs_inobt_rec_t *
-xfs_inobt_rec_addr(xfs_inobt_block_t *bb, int i, xfs_btree_cur_t *cur)
-{
- return XFS_INOBT_REC_ADDR(bb, i, cur);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_INOBT_SET_FREE)
-void
-xfs_inobt_set_free(xfs_inobt_rec_t *rp, int i)
-{
- XFS_INOBT_SET_FREE(rp, i);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_ITOBHV)
-bhv_desc_t *
-xfs_itobhv(xfs_inode_t *ip)
-{
- return XFS_ITOBHV(ip);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_ITOV)
-vnode_t *
-xfs_itov(xfs_inode_t *ip)
-{
- return XFS_ITOV(ip);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_LBLOG)
-int
-xfs_lblog(xfs_mount_t *mp)
-{
- return XFS_LBLOG(mp);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_LBSIZE)
-int
-xfs_lbsize(xfs_mount_t *mp)
-{
- return XFS_LBSIZE(mp);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_LIC_ALL_FREE)
-void
-xfs_lic_all_free(xfs_log_item_chunk_t *cp)
-{
- XFS_LIC_ALL_FREE(cp);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_LIC_ARE_ALL_FREE)
-int
-xfs_lic_are_all_free(xfs_log_item_chunk_t *cp)
-{
- return XFS_LIC_ARE_ALL_FREE(cp);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_LIC_CLAIM)
-void
-xfs_lic_claim(xfs_log_item_chunk_t *cp, int slot)
-{
- XFS_LIC_CLAIM(cp, slot);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_LIC_DESC_TO_CHUNK)
-xfs_log_item_chunk_t *
-xfs_lic_desc_to_chunk(xfs_log_item_desc_t *dp)
-{
- return XFS_LIC_DESC_TO_CHUNK(dp);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_LIC_DESC_TO_SLOT)
-int
-xfs_lic_desc_to_slot(xfs_log_item_desc_t *dp)
-{
- return XFS_LIC_DESC_TO_SLOT(dp);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_LIC_INIT)
-void
-xfs_lic_init(xfs_log_item_chunk_t *cp)
-{
- XFS_LIC_INIT(cp);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_LIC_INIT_SLOT)
-void
-xfs_lic_init_slot(xfs_log_item_chunk_t *cp, int slot)
-{
- XFS_LIC_INIT_SLOT(cp, slot);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_LIC_ISFREE)
-int
-xfs_lic_isfree(xfs_log_item_chunk_t *cp, int slot)
-{
- return XFS_LIC_ISFREE(cp, slot);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_LIC_RELSE)
-void
-xfs_lic_relse(xfs_log_item_chunk_t *cp, int slot)
-{
- XFS_LIC_RELSE(cp, slot);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_LIC_SLOT)
-xfs_log_item_desc_t *
-xfs_lic_slot(xfs_log_item_chunk_t *cp, int slot)
-{
- return XFS_LIC_SLOT(cp, slot);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_LIC_VACANCY)
-int
-xfs_lic_vacancy(xfs_log_item_chunk_t *cp)
-{
- return XFS_LIC_VACANCY(cp);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_LITINO)
-int
-xfs_litino(xfs_mount_t *mp)
-{
- return XFS_LITINO(mp);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_MAKE_IPTR)
-xfs_dinode_t *
-xfs_make_iptr(xfs_mount_t *mp, xfs_buf_t *b, int o)
-{
- return XFS_MAKE_IPTR(mp, b, o);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_MASK32HI)
-__uint32_t
-xfs_mask32hi(int n)
-{
- return XFS_MASK32HI(n);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_MASK32LO)
-__uint32_t
-xfs_mask32lo(int n)
-{
- return XFS_MASK32LO(n);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_MASK64HI)
-__uint64_t
-xfs_mask64hi(int n)
-{
- return XFS_MASK64HI(n);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_MASK64LO)
-__uint64_t
-xfs_mask64lo(int n)
-{
- return XFS_MASK64LO(n);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_MIN_FREELIST)
-int
-xfs_min_freelist(xfs_agf_t *a, xfs_mount_t *mp)
-{
- return XFS_MIN_FREELIST(a, mp);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_MIN_FREELIST_PAG)
-int
-xfs_min_freelist_pag(xfs_perag_t *pag, xfs_mount_t *mp)
-{
- return XFS_MIN_FREELIST_PAG(pag, mp);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_MIN_FREELIST_RAW)
-int
-xfs_min_freelist_raw(uint bl, uint cl, xfs_mount_t *mp)
-{
- return XFS_MIN_FREELIST_RAW(bl, cl, mp);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_MTOVFS)
-vfs_t *
-xfs_mtovfs(xfs_mount_t *mp)
-{
- return XFS_MTOVFS(mp);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_OFFBNO_TO_AGINO)
-xfs_agino_t
-xfs_offbno_to_agino(xfs_mount_t *mp, xfs_agblock_t b, int o)
-{
- return XFS_OFFBNO_TO_AGINO(mp, b, o);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_PREALLOC_BLOCKS)
-xfs_agblock_t
-xfs_prealloc_blocks(xfs_mount_t *mp)
-{
- return XFS_PREALLOC_BLOCKS(mp);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_SB_BLOCK)
-xfs_agblock_t
-xfs_sb_block(xfs_mount_t *mp)
-{
- return XFS_SB_BLOCK(mp);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_SB_GOOD_VERSION)
-int
-xfs_sb_good_version(xfs_sb_t *sbp)
-{
- return XFS_SB_GOOD_VERSION(sbp);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_SB_VERSION_ADDATTR)
-void
-xfs_sb_version_addattr(xfs_sb_t *sbp)
-{
- XFS_SB_VERSION_ADDATTR(sbp);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_SB_VERSION_ADDDALIGN)
-void
-xfs_sb_version_adddalign(xfs_sb_t *sbp)
-{
- XFS_SB_VERSION_ADDDALIGN(sbp);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_SB_VERSION_ADDNLINK)
-void
-xfs_sb_version_addnlink(xfs_sb_t *sbp)
-{
- XFS_SB_VERSION_ADDNLINK(sbp);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_SB_VERSION_ADDQUOTA)
-void
-xfs_sb_version_addquota(xfs_sb_t *sbp)
-{
- XFS_SB_VERSION_ADDQUOTA(sbp);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_SB_VERSION_ADDSHARED)
-void
-xfs_sb_version_addshared(xfs_sb_t *sbp)
-{
- XFS_SB_VERSION_ADDSHARED(sbp);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_SB_VERSION_HASALIGN)
-int
-xfs_sb_version_hasalign(xfs_sb_t *sbp)
-{
- return XFS_SB_VERSION_HASALIGN(sbp);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_SB_VERSION_HASATTR)
-int
-xfs_sb_version_hasattr(xfs_sb_t *sbp)
-{
- return XFS_SB_VERSION_HASATTR(sbp);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_SB_VERSION_HASDALIGN)
-int
-xfs_sb_version_hasdalign(xfs_sb_t *sbp)
-{
- return XFS_SB_VERSION_HASDALIGN(sbp);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_SB_VERSION_HASDIRV2)
-int
-xfs_sb_version_hasdirv2(xfs_sb_t *sbp)
-{
- return XFS_SB_VERSION_HASDIRV2(sbp);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_SB_VERSION_HASEXTFLGBIT)
-int
-xfs_sb_version_hasextflgbit(xfs_sb_t *sbp)
-{
- return XFS_SB_VERSION_HASEXTFLGBIT(sbp);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_SB_VERSION_HASNLINK)
-int
-xfs_sb_version_hasnlink(xfs_sb_t *sbp)
-{
- return XFS_SB_VERSION_HASNLINK(sbp);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_SB_VERSION_HASQUOTA)
-int
-xfs_sb_version_hasquota(xfs_sb_t *sbp)
-{
- return XFS_SB_VERSION_HASQUOTA(sbp);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_SB_VERSION_HASSHARED)
-int
-xfs_sb_version_hasshared(xfs_sb_t *sbp)
-{
- return XFS_SB_VERSION_HASSHARED(sbp);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_SB_VERSION_NUM)
-int
-xfs_sb_version_num(xfs_sb_t *sbp)
-{
- return XFS_SB_VERSION_NUM(sbp);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_SB_VERSION_SUBALIGN)
-void
-xfs_sb_version_subalign(xfs_sb_t *sbp)
-{
- XFS_SB_VERSION_SUBALIGN(sbp);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_SB_VERSION_SUBSHARED)
-void
-xfs_sb_version_subshared(xfs_sb_t *sbp)
-{
- XFS_SB_VERSION_SUBSHARED(sbp);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_SB_VERSION_HASLOGV2)
-int
-xfs_sb_version_haslogv2(xfs_sb_t *sbp)
-{
- return XFS_SB_VERSION_HASLOGV2(sbp);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_SB_VERSION_HASSECTOR)
-int
-xfs_sb_version_hassector(xfs_sb_t *sbp)
-{
- return XFS_SB_VERSION_HASSECTOR(sbp);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_SB_VERSION_TONEW)
-unsigned
-xfs_sb_version_tonew(unsigned v)
-{
- return XFS_SB_VERSION_TONEW(v);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_SB_VERSION_TOOLD)
-unsigned
-xfs_sb_version_toold(unsigned v)
-{
- return XFS_SB_VERSION_TOOLD(v);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XLOG_GRANT_ADD_SPACE)
-void
-xlog_grant_add_space(xlog_t *log, int bytes, int type)
-{
- XLOG_GRANT_ADD_SPACE(log, bytes, type);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XLOG_GRANT_SUB_SPACE)
-void
-xlog_grant_sub_space(xlog_t *log, int bytes, int type)
-{
- XLOG_GRANT_SUB_SPACE(log, bytes, type);
-}
-#endif
-
-#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_SB_VERSION_HASMOREBITS)
-int
-xfs_sb_version_hasmorebits(xfs_sb_t *sbp)
-{
- return XFS_SB_VERSION_HASMOREBITS(sbp);
-}
-#endif
-
diff --git a/fs/xfs/xfs_macros.h b/fs/xfs/xfs_macros.h
deleted file mode 100644
index 0a9307514a48..000000000000
--- a/fs/xfs/xfs_macros.h
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
- */
-#ifndef __XFS_MACROS_H__
-#define __XFS_MACROS_H__
-
-/*
- * Set for debug kernels and simulation
- * These replacements save space.
- * Used in xfs_macros.c.
- */
-#define XFS_WANT_SPACE_C \
- (!defined(_STANDALONE) && defined(DEBUG))
-
-/*
- * Set for debug simulation and kernel builds, but not for standalone.
- * These replacements do not save space.
- * Used in xfs_macros.c.
- */
-#define XFS_WANT_FUNCS_C \
- (!defined(_STANDALONE) && defined(DEBUG))
-
-/*
- * Corresponding names used in .h files.
- */
-#define XFS_WANT_SPACE (XFS_WANT_SPACE_C && !defined(XFS_MACRO_C))
-#define XFS_WANT_FUNCS (XFS_WANT_FUNCS_C && !defined(XFS_MACRO_C))
-
-/*
- * These are the macros that get turned into functions to save space.
- */
-#define XFSSO_NULLSTARTBLOCK 1
-#define XFSSO_XFS_AGB_TO_DADDR 1
-#define XFSSO_XFS_AGB_TO_FSB 1
-#define XFSSO_XFS_AGINO_TO_INO 1
-#define XFSSO_XFS_ALLOC_BLOCK_MINRECS 1
-#define XFSSO_XFS_ATTR_SF_NEXTENTRY 1
-#define XFSSO_XFS_BMAP_BLOCK_DMAXRECS 1
-#define XFSSO_XFS_BMAP_BLOCK_IMAXRECS 1
-#define XFSSO_XFS_BMAP_BLOCK_IMINRECS 1
-#define XFSSO_XFS_BMAP_INIT 1
-#define XFSSO_XFS_BMAP_PTR_IADDR 1
-#define XFSSO_XFS_BMAP_SANITY_CHECK 1
-#define XFSSO_XFS_BMAPI_AFLAG 1
-#define XFSSO_XFS_CFORK_SIZE 1
-#define XFSSO_XFS_DA_COOKIE_BNO 1
-#define XFSSO_XFS_DA_COOKIE_ENTRY 1
-#define XFSSO_XFS_DADDR_TO_AGBNO 1
-#define XFSSO_XFS_DADDR_TO_FSB 1
-#define XFSSO_XFS_DFORK_PTR 1
-#define XFSSO_XFS_DIR_SF_GET_DIRINO 1
-#define XFSSO_XFS_DIR_SF_NEXTENTRY 1
-#define XFSSO_XFS_DIR_SF_PUT_DIRINO 1
-#define XFSSO_XFS_FILBLKS_MIN 1
-#define XFSSO_XFS_FSB_SANITY_CHECK 1
-#define XFSSO_XFS_FSB_TO_DADDR 1
-#define XFSSO_XFS_FSB_TO_DB 1
-#define XFSSO_XFS_IALLOC_INODES 1
-#define XFSSO_XFS_IFORK_ASIZE 1
-#define XFSSO_XFS_IFORK_DSIZE 1
-#define XFSSO_XFS_IFORK_FORMAT 1
-#define XFSSO_XFS_IFORK_NEXT_SET 1
-#define XFSSO_XFS_IFORK_NEXTENTS 1
-#define XFSSO_XFS_IFORK_PTR 1
-#define XFSSO_XFS_ILOG_FBROOT 1
-#define XFSSO_XFS_ILOG_FEXT 1
-#define XFSSO_XFS_INO_MASK 1
-#define XFSSO_XFS_INO_TO_FSB 1
-#define XFSSO_XFS_INODE_CLEAR_READ_AHEAD 1
-#define XFSSO_XFS_MIN_FREELIST 1
-#define XFSSO_XFS_SB_GOOD_VERSION 1
-#define XFSSO_XFS_SB_VERSION_HASNLINK 1
-#define XFSSO_XLOG_GRANT_ADD_SPACE 1
-#define XFSSO_XLOG_GRANT_SUB_SPACE 1
-
-#endif /* __XFS_MACROS_H__ */
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c
index 82e1646e6243..541d5dd474be 100644
--- a/fs/xfs/xfs_mount.c
+++ b/fs/xfs/xfs_mount.c
@@ -1,40 +1,26 @@
/*
- * Copyright (c) 2000-2004 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-
#include "xfs.h"
-#include "xfs_macros.h"
+#include "xfs_fs.h"
#include "xfs_types.h"
-#include "xfs_inum.h"
+#include "xfs_bit.h"
#include "xfs_log.h"
+#include "xfs_inum.h"
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
@@ -42,21 +28,20 @@
#include "xfs_dir2.h"
#include "xfs_dmapi.h"
#include "xfs_mount.h"
-#include "xfs_alloc_btree.h"
#include "xfs_bmap_btree.h"
+#include "xfs_alloc_btree.h"
#include "xfs_ialloc_btree.h"
-#include "xfs_btree.h"
-#include "xfs_ialloc.h"
-#include "xfs_attr_sf.h"
#include "xfs_dir_sf.h"
#include "xfs_dir2_sf.h"
+#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
#include "xfs_inode.h"
+#include "xfs_btree.h"
+#include "xfs_ialloc.h"
#include "xfs_alloc.h"
#include "xfs_rtalloc.h"
#include "xfs_bmap.h"
#include "xfs_error.h"
-#include "xfs_bit.h"
#include "xfs_rw.h"
#include "xfs_quota.h"
#include "xfs_fsops.h"
@@ -180,6 +165,10 @@ xfs_mount_free(
if (mp->m_fsname != NULL)
kmem_free(mp->m_fsname, mp->m_fsname_len);
+ if (mp->m_rtname != NULL)
+ kmem_free(mp->m_rtname, strlen(mp->m_rtname) + 1);
+ if (mp->m_logname != NULL)
+ kmem_free(mp->m_logname, strlen(mp->m_logname) + 1);
if (remove_bhv) {
struct vfs *vfsp = XFS_MTOVFS(mp);
@@ -318,7 +307,7 @@ xfs_mount_validate_sb(
"XFS: Attempted to mount file system with blocksize %d bytes",
sbp->sb_blocksize);
cmn_err(CE_WARN,
- "XFS: Only page-sized (%d) or less blocksizes currently work.",
+ "XFS: Only page-sized (%ld) or less blocksizes currently work.",
PAGE_SIZE);
return XFS_ERROR(ENOSYS);
}
@@ -327,7 +316,10 @@ xfs_mount_validate_sb(
}
xfs_agnumber_t
-xfs_initialize_perag(xfs_mount_t *mp, xfs_agnumber_t agcount)
+xfs_initialize_perag(
+ struct vfs *vfs,
+ xfs_mount_t *mp,
+ xfs_agnumber_t agcount)
{
xfs_agnumber_t index, max_metadata;
xfs_perag_t *pag;
@@ -343,7 +335,7 @@ xfs_initialize_perag(xfs_mount_t *mp, xfs_agnumber_t agcount)
/* Clear the mount flag if no inode can overflow 32 bits
* on this filesystem, or if specifically requested..
*/
- if ((mp->m_flags & XFS_MOUNT_32BITINOOPT) && ino > max_inum) {
+ if ((vfs->vfs_flag & VFS_32BITINODES) && ino > max_inum) {
mp->m_flags |= XFS_MOUNT_32BITINODES;
} else {
mp->m_flags &= ~XFS_MOUNT_32BITINODES;
@@ -360,7 +352,7 @@ xfs_initialize_perag(xfs_mount_t *mp, xfs_agnumber_t agcount)
icount = sbp->sb_dblocks * sbp->sb_imax_pct;
do_div(icount, 100);
icount += sbp->sb_agblocks - 1;
- do_div(icount, mp->m_ialloc_blks);
+ do_div(icount, sbp->sb_agblocks);
max_metadata = icount;
} else {
max_metadata = agcount;
@@ -584,12 +576,13 @@ xfs_mount_common(xfs_mount_t *mp, xfs_sb_t *sbp)
ASSERT(sbp->sb_inodesize >= 256 && sbp->sb_inodesize <= 2048);
switch (sbp->sb_inodesize) {
case 256:
- mp->m_attroffset = XFS_LITINO(mp) - XFS_BMDR_SPACE_CALC(2);
+ mp->m_attroffset = XFS_LITINO(mp) -
+ XFS_BMDR_SPACE_CALC(MINABTPTRS);
break;
case 512:
case 1024:
case 2048:
- mp->m_attroffset = XFS_BMDR_SPACE_CALC(12);
+ mp->m_attroffset = XFS_BMDR_SPACE_CALC(6 * MINABTPTRS);
break;
default:
ASSERT(0);
@@ -954,7 +947,7 @@ xfs_mountfs(
mp->m_perag =
kmem_zalloc(sbp->sb_agcount * sizeof(xfs_perag_t), KM_SLEEP);
- mp->m_maxagi = xfs_initialize_perag(mp, sbp->sb_agcount);
+ mp->m_maxagi = xfs_initialize_perag(vfsp, mp, sbp->sb_agcount);
/*
* log's mount-time initialization. Perform 1st part recovery if needed
diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h
index 5affba38a577..08b2e0a5d807 100644
--- a/fs/xfs/xfs_mount.h
+++ b/fs/xfs/xfs_mount.h
@@ -1,38 +1,23 @@
/*
- * Copyright (c) 2000-2005 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __XFS_MOUNT_H__
#define __XFS_MOUNT_H__
-
typedef struct xfs_trans_reservations {
uint tr_write; /* extent alloc trans */
uint tr_itruncate; /* truncate trans */
@@ -57,7 +42,6 @@ typedef struct xfs_trans_reservations {
uint tr_growrtfree; /* grow realtime freeing */
} xfs_trans_reservations_t;
-
#ifndef __KERNEL__
/*
* Moved here from xfs_ag.h to avoid reordering header files
@@ -80,6 +64,9 @@ struct xfs_iocore;
struct xfs_bmbt_irec;
struct xfs_bmap_free;
+extern struct vfsops xfs_vfsops;
+extern struct vnodeops xfs_vnodeops;
+
#define AIL_LOCK_T lock_t
#define AIL_LOCKINIT(x,y) spinlock_init(x,y)
#define AIL_LOCK_DESTROY(x) spinlock_destroy(x)
@@ -292,6 +279,8 @@ typedef struct xfs_mount {
struct xfs_buf *m_sb_bp; /* buffer for superblock */
char *m_fsname; /* filesystem name */
int m_fsname_len; /* strlen of fs name */
+ char *m_rtname; /* realtime device name */
+ char *m_logname; /* external log device name */
int m_bsize; /* fs logical block size */
xfs_agnumber_t m_agfrotor; /* last ag where space found */
xfs_agnumber_t m_agirotor; /* last ag dir inode alloced */
@@ -344,7 +333,7 @@ typedef struct xfs_mount {
sema_t m_growlock; /* growfs mutex */
int m_fixedfsid[2]; /* unchanged for life of FS */
uint m_dmevmask; /* DMI events for this FS */
- uint m_flags; /* global mount flags */
+ __uint64_t m_flags; /* global mount flags */
uint m_attroffset; /* inode attribute offset */
uint m_dir_node_ents; /* #entries in a dir danode */
uint m_attr_node_ents; /* #entries in attr danode */
@@ -389,38 +378,41 @@ typedef struct xfs_mount {
/*
* Flags for m_flags.
*/
-#define XFS_MOUNT_WSYNC 0x00000001 /* for nfs - all metadata ops
+#define XFS_MOUNT_WSYNC (1ULL << 0) /* for nfs - all metadata ops
must be synchronous except
for space allocations */
-#define XFS_MOUNT_INO64 0x00000002
- /* 0x00000004 -- currently unused */
- /* 0x00000008 -- currently unused */
-#define XFS_MOUNT_FS_SHUTDOWN 0x00000010 /* atomic stop of all filesystem
+#define XFS_MOUNT_INO64 (1ULL << 1)
+ /* (1ULL << 2) -- currently unused */
+ /* (1ULL << 3) -- currently unused */
+#define XFS_MOUNT_FS_SHUTDOWN (1ULL << 4) /* atomic stop of all filesystem
operations, typically for
disk errors in metadata */
-#define XFS_MOUNT_NOATIME 0x00000020 /* don't modify inode access
+#define XFS_MOUNT_NOATIME (1ULL << 5) /* don't modify inode access
times on reads */
-#define XFS_MOUNT_RETERR 0x00000040 /* return alignment errors to
+#define XFS_MOUNT_RETERR (1ULL << 6) /* return alignment errors to
user */
-#define XFS_MOUNT_NOALIGN 0x00000080 /* turn off stripe alignment
+#define XFS_MOUNT_NOALIGN (1ULL << 7) /* turn off stripe alignment
allocations */
- /* 0x00000100 -- currently unused */
- /* 0x00000200 -- currently unused */
-#define XFS_MOUNT_NORECOVERY 0x00000400 /* no recovery - dirty fs */
-#define XFS_MOUNT_SHARED 0x00000800 /* shared mount */
-#define XFS_MOUNT_DFLT_IOSIZE 0x00001000 /* set default i/o size */
-#define XFS_MOUNT_OSYNCISOSYNC 0x00002000 /* o_sync is REALLY o_sync */
+#define XFS_MOUNT_COMPAT_ATTR (1ULL << 8) /* do not use attr2 format */
+ /* (1ULL << 9) -- currently unused */
+#define XFS_MOUNT_NORECOVERY (1ULL << 10) /* no recovery - dirty fs */
+#define XFS_MOUNT_SHARED (1ULL << 11) /* shared mount */
+#define XFS_MOUNT_DFLT_IOSIZE (1ULL << 12) /* set default i/o size */
+#define XFS_MOUNT_OSYNCISOSYNC (1ULL << 13) /* o_sync is REALLY o_sync */
/* osyncisdsync is now default*/
-#define XFS_MOUNT_32BITINODES 0x00004000 /* do not create inodes above
+#define XFS_MOUNT_32BITINODES (1ULL << 14) /* do not create inodes above
* 32 bits in size */
-#define XFS_MOUNT_32BITINOOPT 0x00008000 /* saved mount option state */
-#define XFS_MOUNT_NOUUID 0x00010000 /* ignore uuid during mount */
-#define XFS_MOUNT_NOLOGFLUSH 0x00020000
-#define XFS_MOUNT_IDELETE 0x00040000 /* delete empty inode clusters*/
-#define XFS_MOUNT_SWALLOC 0x00080000 /* turn on stripe width
+ /* (1ULL << 15) -- currently unused */
+#define XFS_MOUNT_NOUUID (1ULL << 16) /* ignore uuid during mount */
+#define XFS_MOUNT_BARRIER (1ULL << 17)
+#define XFS_MOUNT_IDELETE (1ULL << 18) /* delete empty inode clusters*/
+#define XFS_MOUNT_SWALLOC (1ULL << 19) /* turn on stripe width
* allocation */
-#define XFS_MOUNT_IHASHSIZE 0x00100000 /* inode hash table size */
-#define XFS_MOUNT_DIRSYNC 0x00200000 /* synchronous directory ops */
+#define XFS_MOUNT_IHASHSIZE (1ULL << 20) /* inode hash table size */
+#define XFS_MOUNT_DIRSYNC (1ULL << 21) /* synchronous directory ops */
+#define XFS_MOUNT_COMPAT_IOSIZE (1ULL << 22) /* don't report large preferred
+ * I/O size in stat() */
+
/*
* Default minimum read and write sizes.
@@ -442,6 +434,30 @@ typedef struct xfs_mount {
#define XFS_WSYNC_READIO_LOG 15 /* 32K */
#define XFS_WSYNC_WRITEIO_LOG 14 /* 16K */
+/*
+ * Allow large block sizes to be reported to userspace programs if the
+ * "largeio" mount option is used.
+ *
+ * If compatibility mode is specified, simply return the basic unit of caching
+ * so that we don't get inefficient read/modify/write I/O from user apps.
+ * Otherwise....
+ *
+ * If the underlying volume is a stripe, then return the stripe width in bytes
+ * as the recommended I/O size. It is not a stripe and we've set a default
+ * buffered I/O size, return that, otherwise return the compat default.
+ */
+static inline unsigned long
+xfs_preferred_iosize(xfs_mount_t *mp)
+{
+ if (mp->m_flags & XFS_MOUNT_COMPAT_IOSIZE)
+ return PAGE_CACHE_SIZE;
+ return (mp->m_swidth ?
+ (mp->m_swidth << mp->m_sb.sb_blocklog) :
+ ((mp->m_flags & XFS_MOUNT_DFLT_IOSIZE) ?
+ (1 << (int)MAX(mp->m_readio_log, mp->m_writeio_log)) :
+ PAGE_CACHE_SIZE));
+}
+
#define XFS_MAXIOFFSET(mp) ((mp)->m_maxioffset)
#define XFS_FORCED_SHUTDOWN(mp) ((mp)->m_flags & XFS_MOUNT_FS_SHUTDOWN)
@@ -474,57 +490,41 @@ typedef struct xfs_mount {
/*
* Macros for getting from mount to vfs and back.
*/
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_MTOVFS)
-struct vfs *xfs_mtovfs(xfs_mount_t *mp);
#define XFS_MTOVFS(mp) xfs_mtovfs(mp)
-#else
-#define XFS_MTOVFS(mp) (bhvtovfs(&(mp)->m_bhv))
-#endif
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_BHVTOM)
-xfs_mount_t *xfs_bhvtom(bhv_desc_t *bdp);
-#define XFS_BHVTOM(bdp) xfs_bhvtom(bdp)
-#else
-#define XFS_BHVTOM(bdp) ((xfs_mount_t *)BHV_PDATA(bdp))
-#endif
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_VFSTOM)
-xfs_mount_t *xfs_vfstom(vfs_t *vfs);
-#define XFS_VFSTOM(vfs) xfs_vfstom(vfs)
-#else
-#define XFS_VFSTOM(vfs) \
- (XFS_BHVTOM(bhv_lookup(VFS_BHVHEAD(vfs), &xfs_vfsops)))
-#endif
+static inline struct vfs *xfs_mtovfs(xfs_mount_t *mp)
+{
+ return bhvtovfs(&mp->m_bhv);
+}
+#define XFS_BHVTOM(bdp) xfs_bhvtom(bdp)
+static inline xfs_mount_t *xfs_bhvtom(bhv_desc_t *bdp)
+{
+ return (xfs_mount_t *)BHV_PDATA(bdp);
+}
-/*
- * Moved here from xfs_ag.h to avoid reordering header files
- */
+#define XFS_VFSTOM(vfs) xfs_vfstom(vfs)
+static inline xfs_mount_t *xfs_vfstom(vfs_t *vfs)
+{
+ return XFS_BHVTOM(bhv_lookup(VFS_BHVHEAD(vfs), &xfs_vfsops));
+}
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_DADDR_TO_AGNO)
-xfs_agnumber_t xfs_daddr_to_agno(struct xfs_mount *mp, xfs_daddr_t d);
#define XFS_DADDR_TO_AGNO(mp,d) xfs_daddr_to_agno(mp,d)
-#else
-
-static inline xfs_agnumber_t XFS_DADDR_TO_AGNO(xfs_mount_t *mp, xfs_daddr_t d)
+static inline xfs_agnumber_t
+xfs_daddr_to_agno(struct xfs_mount *mp, xfs_daddr_t d)
{
- d = XFS_BB_TO_FSBT(mp, d);
- do_div(d, mp->m_sb.sb_agblocks);
- return (xfs_agnumber_t) d;
+ xfs_daddr_t ld = XFS_BB_TO_FSBT(mp, d);
+ do_div(ld, mp->m_sb.sb_agblocks);
+ return (xfs_agnumber_t) ld;
}
-#endif
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_DADDR_TO_AGBNO)
-xfs_agblock_t xfs_daddr_to_agbno(struct xfs_mount *mp, xfs_daddr_t d);
#define XFS_DADDR_TO_AGBNO(mp,d) xfs_daddr_to_agbno(mp,d)
-#else
-
-static inline xfs_agblock_t XFS_DADDR_TO_AGBNO(xfs_mount_t *mp, xfs_daddr_t d)
+static inline xfs_agblock_t
+xfs_daddr_to_agbno(struct xfs_mount *mp, xfs_daddr_t d)
{
- d = XFS_BB_TO_FSBT(mp, d);
- return (xfs_agblock_t) do_div(d, mp->m_sb.sb_agblocks);
+ xfs_daddr_t ld = XFS_BB_TO_FSBT(mp, d);
+ return (xfs_agblock_t) do_div(ld, mp->m_sb.sb_agblocks);
}
-#endif
-
/*
* This structure is for use by the xfs_mod_incore_sb_batch() routine.
*/
@@ -542,6 +542,7 @@ extern xfs_mount_t *xfs_mount_init(void);
extern void xfs_mod_sb(xfs_trans_t *, __int64_t);
extern void xfs_mount_free(xfs_mount_t *mp, int remove_bhv);
extern int xfs_mountfs(struct vfs *, xfs_mount_t *mp, int);
+extern void xfs_mountfs_check_barriers(xfs_mount_t *mp);
extern int xfs_unmountfs(xfs_mount_t *, struct cred *);
extern void xfs_unmountfs_close(xfs_mount_t *, struct cred *);
@@ -555,12 +556,11 @@ extern int xfs_readsb(xfs_mount_t *mp);
extern void xfs_freesb(xfs_mount_t *);
extern void xfs_do_force_shutdown(bhv_desc_t *, int, char *, int);
extern int xfs_syncsub(xfs_mount_t *, int, int, int *);
-extern xfs_agnumber_t xfs_initialize_perag(xfs_mount_t *, xfs_agnumber_t);
+extern int xfs_sync_inodes(xfs_mount_t *, int, int, int *);
+extern xfs_agnumber_t xfs_initialize_perag(struct vfs *, xfs_mount_t *,
+ xfs_agnumber_t);
extern void xfs_xlatesb(void *, struct xfs_sb *, int, __int64_t);
-extern struct vfsops xfs_vfsops;
-extern struct vnodeops xfs_vnodeops;
-
extern struct xfs_dmops xfs_dmcore_stub;
extern struct xfs_qmops xfs_qmcore_stub;
extern struct xfs_ioops xfs_iocore_xfs;
diff --git a/fs/xfs/xfs_qmops.c b/fs/xfs/xfs_qmops.c
index a6cd6324e946..1408a32eef88 100644
--- a/fs/xfs/xfs_qmops.c
+++ b/fs/xfs/xfs_qmops.c
@@ -1,40 +1,25 @@
/*
- * Copyright (c) 2000-2005 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "xfs.h"
-
-#include "xfs_macros.h"
+#include "xfs_fs.h"
#include "xfs_types.h"
-#include "xfs_inum.h"
#include "xfs_log.h"
+#include "xfs_inum.h"
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
diff --git a/fs/xfs/xfs_quota.h b/fs/xfs/xfs_quota.h
index 32cb79752d5d..82a08baf437b 100644
--- a/fs/xfs/xfs_quota.h
+++ b/fs/xfs/xfs_quota.h
@@ -1,33 +1,19 @@
/*
- * Copyright (c) 2000-2005 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __XFS_QUOTA_H__
#define __XFS_QUOTA_H__
@@ -42,7 +28,7 @@
* uid_t and gid_t are hard-coded to 32 bits in the inode.
* Hence, an 'id' in a dquot is 32 bits..
*/
-typedef __int32_t xfs_dqid_t;
+typedef __uint32_t xfs_dqid_t;
/*
* Eventhough users may not have quota limits occupying all 64-bits,
@@ -59,28 +45,28 @@ typedef __uint16_t xfs_qwarncnt_t;
* to construct the on disk structure.
*/
typedef struct xfs_disk_dquot {
-/*16*/ u_int16_t d_magic; /* dquot magic = XFS_DQUOT_MAGIC */
-/*8 */ u_int8_t d_version; /* dquot version */
-/*8 */ u_int8_t d_flags; /* XFS_DQ_USER/PROJ/GROUP */
-/*32*/ xfs_dqid_t d_id; /* user,project,group id */
-/*64*/ xfs_qcnt_t d_blk_hardlimit;/* absolute limit on disk blks */
-/*64*/ xfs_qcnt_t d_blk_softlimit;/* preferred limit on disk blks */
-/*64*/ xfs_qcnt_t d_ino_hardlimit;/* maximum # allocated inodes */
-/*64*/ xfs_qcnt_t d_ino_softlimit;/* preferred inode limit */
-/*64*/ xfs_qcnt_t d_bcount; /* disk blocks owned by the user */
-/*64*/ xfs_qcnt_t d_icount; /* inodes owned by the user */
-/*32*/ __int32_t d_itimer; /* zero if within inode limits if not,
+ __be16 d_magic; /* dquot magic = XFS_DQUOT_MAGIC */
+ __u8 d_version; /* dquot version */
+ __u8 d_flags; /* XFS_DQ_USER/PROJ/GROUP */
+ __be32 d_id; /* user,project,group id */
+ __be64 d_blk_hardlimit;/* absolute limit on disk blks */
+ __be64 d_blk_softlimit;/* preferred limit on disk blks */
+ __be64 d_ino_hardlimit;/* maximum # allocated inodes */
+ __be64 d_ino_softlimit;/* preferred inode limit */
+ __be64 d_bcount; /* disk blocks owned by the user */
+ __be64 d_icount; /* inodes owned by the user */
+ __be32 d_itimer; /* zero if within inode limits if not,
this is when we refuse service */
-/*32*/ __int32_t d_btimer; /* similar to above; for disk blocks */
-/*16*/ xfs_qwarncnt_t d_iwarns; /* warnings issued wrt num inodes */
-/*16*/ xfs_qwarncnt_t d_bwarns; /* warnings issued wrt disk blocks */
-/*32*/ __int32_t d_pad0; /* 64 bit align */
-/*64*/ xfs_qcnt_t d_rtb_hardlimit;/* absolute limit on realtime blks */
-/*64*/ xfs_qcnt_t d_rtb_softlimit;/* preferred limit on RT disk blks */
-/*64*/ xfs_qcnt_t d_rtbcount; /* realtime blocks owned */
-/*32*/ __int32_t d_rtbtimer; /* similar to above; for RT disk blocks */
-/*16*/ xfs_qwarncnt_t d_rtbwarns; /* warnings issued wrt RT disk blocks */
-/*16*/ __uint16_t d_pad;
+ __be32 d_btimer; /* similar to above; for disk blocks */
+ __be16 d_iwarns; /* warnings issued wrt num inodes */
+ __be16 d_bwarns; /* warnings issued wrt disk blocks */
+ __be32 d_pad0; /* 64 bit align */
+ __be64 d_rtb_hardlimit;/* absolute limit on realtime blks */
+ __be64 d_rtb_softlimit;/* preferred limit on RT disk blks */
+ __be64 d_rtbcount; /* realtime blocks owned */
+ __be32 d_rtbtimer; /* similar to above; for RT disk blocks */
+ __be16 d_rtbwarns; /* warnings issued wrt RT disk blocks */
+ __be16 d_pad;
} xfs_disk_dquot_t;
/*
diff --git a/fs/xfs/xfs_refcache.h b/fs/xfs/xfs_refcache.h
index cd8ddfd35d69..2dec79edb510 100644
--- a/fs/xfs/xfs_refcache.h
+++ b/fs/xfs/xfs_refcache.h
@@ -1,33 +1,19 @@
/*
- * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __XFS_REFCACHE_H__
#define __XFS_REFCACHE_H__
diff --git a/fs/xfs/xfs_rename.c b/fs/xfs/xfs_rename.c
index 23b48ac1cb7e..4d4e8f4e768e 100644
--- a/fs/xfs/xfs_rename.c
+++ b/fs/xfs/xfs_rename.c
@@ -1,60 +1,45 @@
/*
- * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-
#include "xfs.h"
-#include "xfs_macros.h"
+#include "xfs_fs.h"
#include "xfs_types.h"
-#include "xfs_inum.h"
#include "xfs_log.h"
+#include "xfs_inum.h"
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_dir.h"
#include "xfs_dir2.h"
#include "xfs_dmapi.h"
#include "xfs_mount.h"
+#include "xfs_da_btree.h"
#include "xfs_bmap_btree.h"
-#include "xfs_attr_sf.h"
#include "xfs_dir_sf.h"
#include "xfs_dir2_sf.h"
+#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
-#include "xfs_inode_item.h"
#include "xfs_inode.h"
+#include "xfs_inode_item.h"
#include "xfs_bmap.h"
#include "xfs_error.h"
#include "xfs_quota.h"
#include "xfs_refcache.h"
#include "xfs_utils.h"
#include "xfs_trans_space.h"
-#include "xfs_da_btree.h"
#include "xfs_dir_leaf.h"
@@ -620,8 +605,6 @@ xfs_rename(
IRELE(target_ip);
}
- FSC_NOTIFY_NAME_CHANGED(XFS_ITOV(src_ip));
-
IRELE(src_ip);
/* Fall through to std_return with error = 0 or errno from
diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c
index 2c37822d1012..06fc061c50fc 100644
--- a/fs/xfs/xfs_rtalloc.c
+++ b/fs/xfs/xfs_rtalloc.c
@@ -1,44 +1,26 @@
/*
- * Copyright (c) 2000-2004 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-
-/*
- * Free realtime space allocation for XFS.
- */
-
#include "xfs.h"
-#include "xfs_macros.h"
+#include "xfs_fs.h"
#include "xfs_types.h"
-#include "xfs_inum.h"
+#include "xfs_bit.h"
#include "xfs_log.h"
+#include "xfs_inum.h"
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
@@ -46,19 +28,18 @@
#include "xfs_dir2.h"
#include "xfs_dmapi.h"
#include "xfs_mount.h"
-#include "xfs_alloc_btree.h"
#include "xfs_bmap_btree.h"
+#include "xfs_alloc_btree.h"
#include "xfs_ialloc_btree.h"
-#include "xfs_btree.h"
-#include "xfs_ialloc.h"
-#include "xfs_attr_sf.h"
#include "xfs_dir_sf.h"
#include "xfs_dir2_sf.h"
+#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
#include "xfs_inode.h"
+#include "xfs_btree.h"
+#include "xfs_ialloc.h"
#include "xfs_alloc.h"
#include "xfs_bmap.h"
-#include "xfs_bit.h"
#include "xfs_rtalloc.h"
#include "xfs_fsops.h"
#include "xfs_error.h"
diff --git a/fs/xfs/xfs_rtalloc.h b/fs/xfs/xfs_rtalloc.h
index e2710264c054..0e0b4d2ec202 100644
--- a/fs/xfs/xfs_rtalloc.h
+++ b/fs/xfs/xfs_rtalloc.h
@@ -1,33 +1,19 @@
/*
- * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __XFS_RTALLOC_H__
#define __XFS_RTALLOC_H__
diff --git a/fs/xfs/xfs_rw.c b/fs/xfs/xfs_rw.c
index d3ff7aef33ba..c4b20872f07d 100644
--- a/fs/xfs/xfs_rw.c
+++ b/fs/xfs/xfs_rw.c
@@ -1,40 +1,26 @@
/*
- * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-
#include "xfs.h"
-#include "xfs_macros.h"
+#include "xfs_fs.h"
#include "xfs_types.h"
-#include "xfs_inum.h"
+#include "xfs_bit.h"
#include "xfs_log.h"
+#include "xfs_inum.h"
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
@@ -42,20 +28,20 @@
#include "xfs_dir2.h"
#include "xfs_dmapi.h"
#include "xfs_mount.h"
-#include "xfs_alloc_btree.h"
#include "xfs_bmap_btree.h"
+#include "xfs_alloc_btree.h"
#include "xfs_ialloc_btree.h"
+#include "xfs_dir_sf.h"
+#include "xfs_dir2_sf.h"
+#include "xfs_attr_sf.h"
+#include "xfs_dinode.h"
+#include "xfs_inode.h"
+#include "xfs_inode_item.h"
#include "xfs_itable.h"
#include "xfs_btree.h"
#include "xfs_alloc.h"
#include "xfs_ialloc.h"
#include "xfs_attr.h"
-#include "xfs_attr_sf.h"
-#include "xfs_dir_sf.h"
-#include "xfs_dir2_sf.h"
-#include "xfs_dinode.h"
-#include "xfs_inode_item.h"
-#include "xfs_inode.h"
#include "xfs_bmap.h"
#include "xfs_acl.h"
#include "xfs_mac.h"
@@ -264,7 +250,7 @@ xfs_ioerror_alert(
{
cmn_err(CE_ALERT,
"I/O error in filesystem (\"%s\") meta-data dev %s block 0x%llx"
- " (\"%s\") error %d buf count %u",
+ " (\"%s\") error %d buf count %zd",
(!mp || !mp->m_fsname) ? "(fs name not set)" : mp->m_fsname,
XFS_BUFTARG_NAME(bp->pb_target),
(__uint64_t)blkno,
diff --git a/fs/xfs/xfs_rw.h b/fs/xfs/xfs_rw.h
index c8b10bf8f530..de85eefb7966 100644
--- a/fs/xfs/xfs_rw.h
+++ b/fs/xfs/xfs_rw.h
@@ -1,33 +1,19 @@
/*
- * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __XFS_RW_H__
#define __XFS_RW_H__
@@ -68,87 +54,44 @@ struct xfs_mount;
* file is a real time file or not, because the bmap code
* does.
*/
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_FSB_TO_DB)
-xfs_daddr_t xfs_fsb_to_db(struct xfs_inode *ip, xfs_fsblock_t fsb);
#define XFS_FSB_TO_DB(ip,fsb) xfs_fsb_to_db(ip,fsb)
-#else
-#define XFS_FSB_TO_DB(ip,fsb) \
- (((ip)->i_d.di_flags & XFS_DIFLAG_REALTIME) ? \
+static inline xfs_daddr_t
+xfs_fsb_to_db(struct xfs_inode *ip, xfs_fsblock_t fsb)
+{
+ return (((ip)->i_d.di_flags & XFS_DIFLAG_REALTIME) ? \
(xfs_daddr_t)XFS_FSB_TO_BB((ip)->i_mount, (fsb)) : \
- XFS_FSB_TO_DADDR((ip)->i_mount, (fsb)))
-#endif
-
-#define XFS_FSB_TO_DB_IO(io,fsb) \
- (((io)->io_flags & XFS_IOCORE_RT) ? \
+ XFS_FSB_TO_DADDR((ip)->i_mount, (fsb)));
+}
+#define XFS_FSB_TO_DB_IO(io,fsb) xfs_fsb_to_db_io(io,fsb)
+static inline xfs_daddr_t
+xfs_fsb_to_db_io(struct xfs_iocore *io, xfs_fsblock_t fsb)
+{
+ return (((io)->io_flags & XFS_IOCORE_RT) ? \
XFS_FSB_TO_BB((io)->io_mount, (fsb)) : \
- XFS_FSB_TO_DADDR((io)->io_mount, (fsb)))
+ XFS_FSB_TO_DADDR((io)->io_mount, (fsb)));
+}
/*
* Prototypes for functions in xfs_rw.c.
*/
-
-int
-xfs_write_clear_setuid(
- struct xfs_inode *ip);
-
-int
-xfs_bwrite(
- struct xfs_mount *mp,
- struct xfs_buf *bp);
-
-int
-xfs_bioerror(
- struct xfs_buf *b);
-
-int
-xfs_bioerror_relse(
- struct xfs_buf *b);
-
-int
-xfs_read_buf(
- struct xfs_mount *mp,
- xfs_buftarg_t *target,
- xfs_daddr_t blkno,
- int len,
- uint flags,
- struct xfs_buf **bpp);
-
-void
-xfs_ioerror_alert(
- char *func,
- struct xfs_mount *mp,
- xfs_buf_t *bp,
- xfs_daddr_t blkno);
-
+extern int xfs_write_clear_setuid(struct xfs_inode *ip);
+extern int xfs_bwrite(struct xfs_mount *mp, struct xfs_buf *bp);
+extern int xfs_bioerror(struct xfs_buf *bp);
+extern int xfs_bioerror_relse(struct xfs_buf *bp);
+extern int xfs_read_buf(struct xfs_mount *mp, xfs_buftarg_t *btp,
+ xfs_daddr_t blkno, int len, uint flags,
+ struct xfs_buf **bpp);
+extern void xfs_ioerror_alert(char *func, struct xfs_mount *mp,
+ xfs_buf_t *bp, xfs_daddr_t blkno);
/*
* Prototypes for functions in xfs_vnodeops.c.
*/
-
-int
-xfs_rwlock(
- bhv_desc_t *bdp,
- vrwlock_t write_lock);
-
-void
-xfs_rwunlock(
- bhv_desc_t *bdp,
- vrwlock_t write_lock);
-
-int
-xfs_change_file_space(
- bhv_desc_t *bdp,
- int cmd,
- xfs_flock64_t *bf,
- xfs_off_t offset,
- cred_t *credp,
- int flags);
-
-int
-xfs_set_dmattrs(
- bhv_desc_t *bdp,
- u_int evmask,
- u_int16_t state,
- cred_t *credp);
+extern int xfs_rwlock(bhv_desc_t *bdp, vrwlock_t write_lock);
+extern void xfs_rwunlock(bhv_desc_t *bdp, vrwlock_t write_lock);
+extern int xfs_change_file_space(bhv_desc_t *bdp, int cmd, xfs_flock64_t *bf,
+ xfs_off_t offset, cred_t *credp, int flags);
+extern int xfs_set_dmattrs(bhv_desc_t *bdp, u_int evmask, u_int16_t state,
+ cred_t *credp);
#endif /* __XFS_RW_H__ */
diff --git a/fs/xfs/xfs_sb.h b/fs/xfs/xfs_sb.h
index ad090a834ced..4a17d335f897 100644
--- a/fs/xfs/xfs_sb.h
+++ b/fs/xfs/xfs_sb.h
@@ -1,33 +1,19 @@
/*
- * Copyright (c) 2000-2001 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __XFS_SB_H__
#define __XFS_SB_H__
@@ -72,7 +58,8 @@ struct xfs_mount;
XFS_SB_VERSION_DALIGNBIT | \
XFS_SB_VERSION_SHAREDBIT | \
XFS_SB_VERSION_LOGV2BIT | \
- XFS_SB_VERSION_SECTORBIT)
+ XFS_SB_VERSION_SECTORBIT | \
+ XFS_SB_VERSION_MOREBITSBIT)
#define XFS_SB_VERSION_OKSASHBITS \
(XFS_SB_VERSION_NUMBITS | \
XFS_SB_VERSION_REALFBITS | \
@@ -103,12 +90,15 @@ struct xfs_mount;
*/
#define XFS_SB_VERSION2_REALFBITS 0x00ffffff /* Mask: features */
#define XFS_SB_VERSION2_RESERVED1BIT 0x00000001
+#define XFS_SB_VERSION2_RESERVED2BIT 0x00000002
+#define XFS_SB_VERSION2_RESERVED4BIT 0x00000004
+#define XFS_SB_VERSION2_ATTR2BIT 0x00000008 /* Inline attr rework */
#define XFS_SB_VERSION2_SASHFBITS 0xff000000 /* Mask: features that
require changing
PROM and SASH */
#define XFS_SB_VERSION2_OKREALFBITS \
- (0)
+ (XFS_SB_VERSION2_ATTR2BIT)
#define XFS_SB_VERSION2_OKSASHFBITS \
(0)
#define XFS_SB_VERSION2_OKREALBITS \
@@ -118,8 +108,7 @@ struct xfs_mount;
/*
* mkfs macro to set up sb_features2 word
*/
-#define XFS_SB_VERSION2_MKFS(xyz) \
- ((xyz) ? 0 : 0)
+#define XFS_SB_VERSION2_MKFS(resvd1, sbcntr) 0
typedef struct xfs_sb
{
@@ -176,7 +165,7 @@ typedef struct xfs_sb
__uint8_t sb_logsectlog; /* log2 of the log sector size */
__uint16_t sb_logsectsize; /* sector size for the log, bytes */
__uint32_t sb_logsunit; /* stripe unit size for the log */
- __uint32_t sb_features2; /* additonal feature bits */
+ __uint32_t sb_features2; /* additional feature bits */
} xfs_sb_t;
/*
@@ -216,12 +205,15 @@ typedef enum {
#define XFS_SB_SHARED_VN XFS_SB_MVAL(SHARED_VN)
#define XFS_SB_UNIT XFS_SB_MVAL(UNIT)
#define XFS_SB_WIDTH XFS_SB_MVAL(WIDTH)
+#define XFS_SB_FEATURES2 XFS_SB_MVAL(FEATURES2)
#define XFS_SB_NUM_BITS ((int)XFS_SBS_FIELDCOUNT)
#define XFS_SB_ALL_BITS ((1LL << XFS_SB_NUM_BITS) - 1)
#define XFS_SB_MOD_BITS \
(XFS_SB_UUID | XFS_SB_ROOTINO | XFS_SB_RBMINO | XFS_SB_RSUMINO | \
XFS_SB_VERSIONNUM | XFS_SB_UQUOTINO | XFS_SB_GQUOTINO | \
- XFS_SB_QFLAGS | XFS_SB_SHARED_VN | XFS_SB_UNIT | XFS_SB_WIDTH)
+ XFS_SB_QFLAGS | XFS_SB_SHARED_VN | XFS_SB_UNIT | XFS_SB_WIDTH | \
+ XFS_SB_FEATURES2)
+
/*
* Misc. Flags - warning - these will be cleared by xfs_repair unless
@@ -235,42 +227,33 @@ typedef enum {
*/
#define XFS_SB_MAX_SHARED_VN 0
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_SB_VERSION_NUM)
-int xfs_sb_version_num(xfs_sb_t *sbp);
-#define XFS_SB_VERSION_NUM(sbp) xfs_sb_version_num(sbp)
-#else
#define XFS_SB_VERSION_NUM(sbp) ((sbp)->sb_versionnum & XFS_SB_VERSION_NUMBITS)
-#endif
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_SB_GOOD_VERSION)
-int xfs_sb_good_version(xfs_sb_t *sbp);
#define XFS_SB_GOOD_VERSION(sbp) xfs_sb_good_version(sbp)
-#else
-#define XFS_SB_GOOD_VERSION_INT(sbp) \
- ((((sbp)->sb_versionnum >= XFS_SB_VERSION_1) && \
- ((sbp)->sb_versionnum <= XFS_SB_VERSION_3)) || \
- ((XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4) && \
- !(((sbp)->sb_versionnum & ~XFS_SB_VERSION_OKREALBITS) || \
- (((sbp)->sb_versionnum & XFS_SB_VERSION_MOREBITSBIT) && \
- ((sbp)->sb_features2 & ~XFS_SB_VERSION2_OKREALBITS)))
-
#ifdef __KERNEL__
-#define XFS_SB_GOOD_VERSION(sbp) \
- (XFS_SB_GOOD_VERSION_INT(sbp) && \
- (sbp)->sb_shared_vn <= XFS_SB_MAX_SHARED_VN) ))
+static inline int xfs_sb_good_version(xfs_sb_t *sbp)
+{
+ return (((sbp->sb_versionnum >= XFS_SB_VERSION_1) && \
+ (sbp->sb_versionnum <= XFS_SB_VERSION_3)) || \
+ ((XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4) && \
+ !((sbp->sb_versionnum & ~XFS_SB_VERSION_OKREALBITS) || \
+ ((sbp->sb_versionnum & XFS_SB_VERSION_MOREBITSBIT) && \
+ (sbp->sb_features2 & ~XFS_SB_VERSION2_OKREALBITS))) && \
+ (sbp->sb_shared_vn <= XFS_SB_MAX_SHARED_VN)));
+}
#else
-/*
- * extra 2 paren's here (( to unconfuse paren-matching editors
- * like vi because XFS_SB_GOOD_VERSION_INT is a partial expression
- * and the two XFS_SB_GOOD_VERSION's each 2 more close paren's to
- * complete the expression.
- */
-#define XFS_SB_GOOD_VERSION(sbp) \
- (XFS_SB_GOOD_VERSION_INT(sbp) && \
- (!((sbp)->sb_versionnum & XFS_SB_VERSION_SHAREDBIT) || \
- (sbp)->sb_shared_vn <= XFS_SB_MAX_SHARED_VN)) ))
+static inline int xfs_sb_good_version(xfs_sb_t *sbp)
+{
+ return (((sbp->sb_versionnum >= XFS_SB_VERSION_1) && \
+ (sbp->sb_versionnum <= XFS_SB_VERSION_3)) || \
+ ((XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4) && \
+ !((sbp->sb_versionnum & ~XFS_SB_VERSION_OKREALBITS) || \
+ ((sbp->sb_versionnum & XFS_SB_VERSION_MOREBITSBIT) && \
+ (sbp->sb_features2 & ~XFS_SB_VERSION2_OKREALBITS))) && \
+ (!(sbp->sb_versionnum & XFS_SB_VERSION_SHAREDBIT) || \
+ (sbp->sb_shared_vn <= XFS_SB_MAX_SHARED_VN))));
+}
#endif /* __KERNEL__ */
-#endif
#define XFS_SB_GOOD_SASH_VERSION(sbp) \
((((sbp)->sb_versionnum >= XFS_SB_VERSION_1) && \
@@ -278,275 +261,218 @@ int xfs_sb_good_version(xfs_sb_t *sbp);
((XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4) && \
!((sbp)->sb_versionnum & ~XFS_SB_VERSION_OKSASHBITS)))
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_SB_VERSION_TONEW)
-unsigned xfs_sb_version_tonew(unsigned v);
#define XFS_SB_VERSION_TONEW(v) xfs_sb_version_tonew(v)
-#else
-#define XFS_SB_VERSION_TONEW(v) \
- ((((v) == XFS_SB_VERSION_1) ? \
+static inline unsigned xfs_sb_version_tonew(unsigned v)
+{
+ return ((((v) == XFS_SB_VERSION_1) ? \
0 : \
(((v) == XFS_SB_VERSION_2) ? \
XFS_SB_VERSION_ATTRBIT : \
(XFS_SB_VERSION_ATTRBIT | XFS_SB_VERSION_NLINKBIT))) | \
- XFS_SB_VERSION_4)
-#endif
+ XFS_SB_VERSION_4);
+}
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_SB_VERSION_TOOLD)
-unsigned xfs_sb_version_toold(unsigned v);
#define XFS_SB_VERSION_TOOLD(v) xfs_sb_version_toold(v)
-#else
-#define XFS_SB_VERSION_TOOLD(v) \
- (((v) & (XFS_SB_VERSION_QUOTABIT | XFS_SB_VERSION_ALIGNBIT)) ? \
+static inline unsigned xfs_sb_version_toold(unsigned v)
+{
+ return (((v) & (XFS_SB_VERSION_QUOTABIT | XFS_SB_VERSION_ALIGNBIT)) ? \
0 : \
(((v) & XFS_SB_VERSION_NLINKBIT) ? \
XFS_SB_VERSION_3 : \
(((v) & XFS_SB_VERSION_ATTRBIT) ? \
XFS_SB_VERSION_2 : \
- XFS_SB_VERSION_1)))
-#endif
+ XFS_SB_VERSION_1)));
+}
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_SB_VERSION_HASATTR)
-int xfs_sb_version_hasattr(xfs_sb_t *sbp);
#define XFS_SB_VERSION_HASATTR(sbp) xfs_sb_version_hasattr(sbp)
-#else
-#define XFS_SB_VERSION_HASATTR(sbp) \
- (((sbp)->sb_versionnum == XFS_SB_VERSION_2) || \
- ((sbp)->sb_versionnum == XFS_SB_VERSION_3) || \
- ((XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4) && \
- ((sbp)->sb_versionnum & XFS_SB_VERSION_ATTRBIT)))
-#endif
+static inline int xfs_sb_version_hasattr(xfs_sb_t *sbp)
+{
+ return ((sbp)->sb_versionnum == XFS_SB_VERSION_2) || \
+ ((sbp)->sb_versionnum == XFS_SB_VERSION_3) || \
+ ((XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4) && \
+ ((sbp)->sb_versionnum & XFS_SB_VERSION_ATTRBIT));
+}
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_SB_VERSION_ADDATTR)
-void xfs_sb_version_addattr(xfs_sb_t *sbp);
#define XFS_SB_VERSION_ADDATTR(sbp) xfs_sb_version_addattr(sbp)
-#else
-#define XFS_SB_VERSION_ADDATTR(sbp) \
- ((sbp)->sb_versionnum = \
- (((sbp)->sb_versionnum == XFS_SB_VERSION_1) ? \
+static inline void xfs_sb_version_addattr(xfs_sb_t *sbp)
+{
+ (sbp)->sb_versionnum = (((sbp)->sb_versionnum == XFS_SB_VERSION_1) ? \
XFS_SB_VERSION_2 : \
((XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4) ? \
((sbp)->sb_versionnum | XFS_SB_VERSION_ATTRBIT) : \
- (XFS_SB_VERSION_4 | XFS_SB_VERSION_ATTRBIT))))
-#endif
+ (XFS_SB_VERSION_4 | XFS_SB_VERSION_ATTRBIT)));
+}
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_SB_VERSION_HASNLINK)
-int xfs_sb_version_hasnlink(xfs_sb_t *sbp);
#define XFS_SB_VERSION_HASNLINK(sbp) xfs_sb_version_hasnlink(sbp)
-#else
-#define XFS_SB_VERSION_HASNLINK(sbp) \
- (((sbp)->sb_versionnum == XFS_SB_VERSION_3) || \
- ((XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4) && \
- ((sbp)->sb_versionnum & XFS_SB_VERSION_NLINKBIT)))
-#endif
+static inline int xfs_sb_version_hasnlink(xfs_sb_t *sbp)
+{
+ return ((sbp)->sb_versionnum == XFS_SB_VERSION_3) || \
+ ((XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4) && \
+ ((sbp)->sb_versionnum & XFS_SB_VERSION_NLINKBIT));
+}
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_SB_VERSION_ADDNLINK)
-void xfs_sb_version_addnlink(xfs_sb_t *sbp);
#define XFS_SB_VERSION_ADDNLINK(sbp) xfs_sb_version_addnlink(sbp)
-#else
-#define XFS_SB_VERSION_ADDNLINK(sbp) \
- ((sbp)->sb_versionnum = \
- ((sbp)->sb_versionnum <= XFS_SB_VERSION_2 ? \
+static inline void xfs_sb_version_addnlink(xfs_sb_t *sbp)
+{
+ (sbp)->sb_versionnum = ((sbp)->sb_versionnum <= XFS_SB_VERSION_2 ? \
XFS_SB_VERSION_3 : \
- ((sbp)->sb_versionnum | XFS_SB_VERSION_NLINKBIT)))
-#endif
+ ((sbp)->sb_versionnum | XFS_SB_VERSION_NLINKBIT));
+}
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_SB_VERSION_HASQUOTA)
-int xfs_sb_version_hasquota(xfs_sb_t *sbp);
#define XFS_SB_VERSION_HASQUOTA(sbp) xfs_sb_version_hasquota(sbp)
-#else
-#define XFS_SB_VERSION_HASQUOTA(sbp) \
- ((XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4) && \
- ((sbp)->sb_versionnum & XFS_SB_VERSION_QUOTABIT))
-#endif
+static inline int xfs_sb_version_hasquota(xfs_sb_t *sbp)
+{
+ return (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4) && \
+ ((sbp)->sb_versionnum & XFS_SB_VERSION_QUOTABIT);
+}
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_SB_VERSION_ADDQUOTA)
-void xfs_sb_version_addquota(xfs_sb_t *sbp);
#define XFS_SB_VERSION_ADDQUOTA(sbp) xfs_sb_version_addquota(sbp)
-#else
-#define XFS_SB_VERSION_ADDQUOTA(sbp) \
- ((sbp)->sb_versionnum = \
- (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4 ? \
- ((sbp)->sb_versionnum | XFS_SB_VERSION_QUOTABIT) : \
- (XFS_SB_VERSION_TONEW((sbp)->sb_versionnum) | \
- XFS_SB_VERSION_QUOTABIT)))
-#endif
-
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_SB_VERSION_HASALIGN)
-int xfs_sb_version_hasalign(xfs_sb_t *sbp);
+static inline void xfs_sb_version_addquota(xfs_sb_t *sbp)
+{
+ (sbp)->sb_versionnum = \
+ (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4 ? \
+ ((sbp)->sb_versionnum | XFS_SB_VERSION_QUOTABIT) : \
+ (XFS_SB_VERSION_TONEW((sbp)->sb_versionnum) | \
+ XFS_SB_VERSION_QUOTABIT));
+}
+
#define XFS_SB_VERSION_HASALIGN(sbp) xfs_sb_version_hasalign(sbp)
-#else
-#define XFS_SB_VERSION_HASALIGN(sbp) \
- ((XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4) && \
- ((sbp)->sb_versionnum & XFS_SB_VERSION_ALIGNBIT))
-#endif
+static inline int xfs_sb_version_hasalign(xfs_sb_t *sbp)
+{
+ return (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4) && \
+ ((sbp)->sb_versionnum & XFS_SB_VERSION_ALIGNBIT);
+}
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_SB_VERSION_SUBALIGN)
-void xfs_sb_version_subalign(xfs_sb_t *sbp);
#define XFS_SB_VERSION_SUBALIGN(sbp) xfs_sb_version_subalign(sbp)
-#else
-#define XFS_SB_VERSION_SUBALIGN(sbp) \
- ((sbp)->sb_versionnum = \
- XFS_SB_VERSION_TOOLD((sbp)->sb_versionnum & ~XFS_SB_VERSION_ALIGNBIT))
-#endif
+static inline void xfs_sb_version_subalign(xfs_sb_t *sbp)
+{
+ (sbp)->sb_versionnum = \
+ XFS_SB_VERSION_TOOLD((sbp)->sb_versionnum & ~XFS_SB_VERSION_ALIGNBIT);
+}
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_SB_VERSION_HASDALIGN)
-int xfs_sb_version_hasdalign(xfs_sb_t *sbp);
#define XFS_SB_VERSION_HASDALIGN(sbp) xfs_sb_version_hasdalign(sbp)
-#else
-#define XFS_SB_VERSION_HASDALIGN(sbp) \
- ((XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4) && \
- ((sbp)->sb_versionnum & XFS_SB_VERSION_DALIGNBIT))
-#endif
+static inline int xfs_sb_version_hasdalign(xfs_sb_t *sbp)
+{
+ return (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4) && \
+ ((sbp)->sb_versionnum & XFS_SB_VERSION_DALIGNBIT);
+}
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_SB_VERSION_ADDDALIGN)
-int xfs_sb_version_adddalign(xfs_sb_t *sbp);
#define XFS_SB_VERSION_ADDDALIGN(sbp) xfs_sb_version_adddalign(sbp)
-#else
-#define XFS_SB_VERSION_ADDDALIGN(sbp) \
- ((sbp)->sb_versionnum = \
- ((sbp)->sb_versionnum | XFS_SB_VERSION_DALIGNBIT))
-#endif
+static inline int xfs_sb_version_adddalign(xfs_sb_t *sbp)
+{
+ return (sbp)->sb_versionnum = \
+ ((sbp)->sb_versionnum | XFS_SB_VERSION_DALIGNBIT);
+}
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_SB_VERSION_HASSHARED)
-int xfs_sb_version_hasshared(xfs_sb_t *sbp);
#define XFS_SB_VERSION_HASSHARED(sbp) xfs_sb_version_hasshared(sbp)
-#else
-#define XFS_SB_VERSION_HASSHARED(sbp) \
- ((XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4) && \
- ((sbp)->sb_versionnum & XFS_SB_VERSION_SHAREDBIT))
-#endif
+static inline int xfs_sb_version_hasshared(xfs_sb_t *sbp)
+{
+ return (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4) && \
+ ((sbp)->sb_versionnum & XFS_SB_VERSION_SHAREDBIT);
+}
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_SB_VERSION_ADDSHARED)
-int xfs_sb_version_addshared(xfs_sb_t *sbp);
#define XFS_SB_VERSION_ADDSHARED(sbp) xfs_sb_version_addshared(sbp)
-#else
-#define XFS_SB_VERSION_ADDSHARED(sbp) \
- ((sbp)->sb_versionnum = \
- ((sbp)->sb_versionnum | XFS_SB_VERSION_SHAREDBIT))
-#endif
+static inline int xfs_sb_version_addshared(xfs_sb_t *sbp)
+{
+ return (sbp)->sb_versionnum = \
+ ((sbp)->sb_versionnum | XFS_SB_VERSION_SHAREDBIT);
+}
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_SB_VERSION_SUBSHARED)
-int xfs_sb_version_subshared(xfs_sb_t *sbp);
#define XFS_SB_VERSION_SUBSHARED(sbp) xfs_sb_version_subshared(sbp)
-#else
-#define XFS_SB_VERSION_SUBSHARED(sbp) \
- ((sbp)->sb_versionnum = \
- ((sbp)->sb_versionnum & ~XFS_SB_VERSION_SHAREDBIT))
-#endif
+static inline int xfs_sb_version_subshared(xfs_sb_t *sbp)
+{
+ return (sbp)->sb_versionnum = \
+ ((sbp)->sb_versionnum & ~XFS_SB_VERSION_SHAREDBIT);
+}
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_SB_VERSION_HASDIRV2)
-int xfs_sb_version_hasdirv2(xfs_sb_t *sbp);
#define XFS_SB_VERSION_HASDIRV2(sbp) xfs_sb_version_hasdirv2(sbp)
-#else
-#define XFS_SB_VERSION_HASDIRV2(sbp) \
- ((XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4) && \
- ((sbp)->sb_versionnum & XFS_SB_VERSION_DIRV2BIT))
-#endif
+static inline int xfs_sb_version_hasdirv2(xfs_sb_t *sbp)
+{
+ return (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4) && \
+ ((sbp)->sb_versionnum & XFS_SB_VERSION_DIRV2BIT);
+}
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_SB_VERSION_HASLOGV2)
-int xfs_sb_version_haslogv2(xfs_sb_t *sbp);
#define XFS_SB_VERSION_HASLOGV2(sbp) xfs_sb_version_haslogv2(sbp)
-#else
-#define XFS_SB_VERSION_HASLOGV2(sbp) \
- ((XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4) && \
- ((sbp)->sb_versionnum & XFS_SB_VERSION_LOGV2BIT))
-#endif
+static inline int xfs_sb_version_haslogv2(xfs_sb_t *sbp)
+{
+ return (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4) && \
+ ((sbp)->sb_versionnum & XFS_SB_VERSION_LOGV2BIT);
+}
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_SB_VERSION_HASEXTFLGBIT)
-int xfs_sb_version_hasextflgbit(xfs_sb_t *sbp);
#define XFS_SB_VERSION_HASEXTFLGBIT(sbp) xfs_sb_version_hasextflgbit(sbp)
-#else
-#define XFS_SB_VERSION_HASEXTFLGBIT(sbp) \
- ((XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4) && \
- ((sbp)->sb_versionnum & XFS_SB_VERSION_EXTFLGBIT))
-#endif
+static inline int xfs_sb_version_hasextflgbit(xfs_sb_t *sbp)
+{
+ return (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4) && \
+ ((sbp)->sb_versionnum & XFS_SB_VERSION_EXTFLGBIT);
+}
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_SB_VERSION_ADDEXTFLGBIT)
-int xfs_sb_version_addextflgbit(xfs_sb_t *sbp);
#define XFS_SB_VERSION_ADDEXTFLGBIT(sbp) xfs_sb_version_addextflgbit(sbp)
-#else
-#define XFS_SB_VERSION_ADDEXTFLGBIT(sbp) \
- ((sbp)->sb_versionnum = \
- ((sbp)->sb_versionnum | XFS_SB_VERSION_EXTFLGBIT))
-#endif
+static inline int xfs_sb_version_addextflgbit(xfs_sb_t *sbp)
+{
+ return (sbp)->sb_versionnum = \
+ ((sbp)->sb_versionnum | XFS_SB_VERSION_EXTFLGBIT);
+}
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_SB_VERSION_SUBEXTFLGBIT)
-int xfs_sb_version_subextflgbit(xfs_sb_t *sbp);
#define XFS_SB_VERSION_SUBEXTFLGBIT(sbp) xfs_sb_version_subextflgbit(sbp)
-#else
-#define XFS_SB_VERSION_SUBEXTFLGBIT(sbp) \
- ((sbp)->sb_versionnum = \
- ((sbp)->sb_versionnum & ~XFS_SB_VERSION_EXTFLGBIT))
-#endif
+static inline int xfs_sb_version_subextflgbit(xfs_sb_t *sbp)
+{
+ return (sbp)->sb_versionnum = \
+ ((sbp)->sb_versionnum & ~XFS_SB_VERSION_EXTFLGBIT);
+}
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_SB_VERSION_HASSECTOR)
-int xfs_sb_version_hassector(xfs_sb_t *sbp);
#define XFS_SB_VERSION_HASSECTOR(sbp) xfs_sb_version_hassector(sbp)
-#else
-#define XFS_SB_VERSION_HASSECTOR(sbp) \
- ((XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4) && \
- ((sbp)->sb_versionnum & XFS_SB_VERSION_SECTORBIT))
-#endif
+static inline int xfs_sb_version_hassector(xfs_sb_t *sbp)
+{
+ return (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4) && \
+ ((sbp)->sb_versionnum & XFS_SB_VERSION_SECTORBIT);
+}
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_SB_VERSION_HASMOREBITSBIT)
-int xfs_sb_version_hasmorebits(xfs_sb_t *sbp);
#define XFS_SB_VERSION_HASMOREBITS(sbp) xfs_sb_version_hasmorebits(sbp)
-#else
-#define XFS_SB_VERSION_HASMOREBITS(sbp) \
- ((XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4) && \
- ((sbp)->sb_versionnum & XFS_SB_VERSION_MOREBITSBIT))
-#endif
+static inline int xfs_sb_version_hasmorebits(xfs_sb_t *sbp)
+{
+ return (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4) && \
+ ((sbp)->sb_versionnum & XFS_SB_VERSION_MOREBITSBIT);
+}
/*
* sb_features2 bit version macros.
*
- * For example, for a bit defined as XFS_SB_VERSION2_YBIT, has a macro:
+ * For example, for a bit defined as XFS_SB_VERSION2_FUNBIT, has a macro:
*
- * SB_VERSION_HASYBIT(xfs_sb_t *sbp)
+ * SB_VERSION_HASFUNBIT(xfs_sb_t *sbp)
* ((XFS_SB_VERSION_HASMOREBITS(sbp) &&
- * ((sbp)->sb_versionnum & XFS_SB_VERSION2_YBIT)
+ * ((sbp)->sb_features2 & XFS_SB_VERSION2_FUNBIT)
*/
+#define XFS_SB_VERSION_HASATTR2(sbp) xfs_sb_version_hasattr2(sbp)
+static inline int xfs_sb_version_hasattr2(xfs_sb_t *sbp)
+{
+ return (XFS_SB_VERSION_HASMOREBITS(sbp)) && \
+ ((sbp)->sb_features2 & XFS_SB_VERSION2_ATTR2BIT);
+}
+
+#define XFS_SB_VERSION_ADDATTR2(sbp) xfs_sb_version_addattr2(sbp)
+static inline void xfs_sb_version_addattr2(xfs_sb_t *sbp)
+{
+ ((sbp)->sb_versionnum = \
+ ((sbp)->sb_versionnum | XFS_SB_VERSION_MOREBITSBIT), \
+ ((sbp)->sb_features2 = \
+ ((sbp)->sb_features2 | XFS_SB_VERSION2_ATTR2BIT)));
+}
+
/*
* end of superblock version macros
*/
-#define XFS_SB_DADDR ((xfs_daddr_t)0) /* daddr in filesystem/ag */
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_SB_BLOCK)
-xfs_agblock_t xfs_sb_block(struct xfs_mount *mp);
-#define XFS_SB_BLOCK(mp) xfs_sb_block(mp)
-#else
+#define XFS_SB_DADDR ((xfs_daddr_t)0) /* daddr in filesystem/ag */
#define XFS_SB_BLOCK(mp) XFS_HDR_BLOCK(mp, XFS_SB_DADDR)
-#endif
-
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_HDR_BLOCK)
-xfs_agblock_t xfs_hdr_block(struct xfs_mount *mp, xfs_daddr_t d);
-#define XFS_HDR_BLOCK(mp,d) xfs_hdr_block(mp,d)
-#else
-#define XFS_HDR_BLOCK(mp,d) ((xfs_agblock_t)(XFS_BB_TO_FSBT(mp,d)))
-#endif
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_DADDR_TO_FSB)
-xfs_fsblock_t xfs_daddr_to_fsb(struct xfs_mount *mp, xfs_daddr_t d);
-#define XFS_DADDR_TO_FSB(mp,d) xfs_daddr_to_fsb(mp,d)
-#else
-#define XFS_DADDR_TO_FSB(mp,d) \
- XFS_AGB_TO_FSB(mp, XFS_DADDR_TO_AGNO(mp,d), XFS_DADDR_TO_AGBNO(mp,d))
-#endif
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_FSB_TO_DADDR)
-xfs_daddr_t xfs_fsb_to_daddr(struct xfs_mount *mp, xfs_fsblock_t fsbno);
-#define XFS_FSB_TO_DADDR(mp,fsbno) xfs_fsb_to_daddr(mp,fsbno)
-#else
-#define XFS_FSB_TO_DADDR(mp,fsbno) \
- XFS_AGB_TO_DADDR(mp, XFS_FSB_TO_AGNO(mp,fsbno), \
- XFS_FSB_TO_AGBNO(mp,fsbno))
-#endif
-
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_BUF_TO_SBP)
-xfs_sb_t *xfs_buf_to_sbp(struct xfs_buf *bp);
-#define XFS_BUF_TO_SBP(bp) xfs_buf_to_sbp(bp)
-#else
#define XFS_BUF_TO_SBP(bp) ((xfs_sb_t *)XFS_BUF_PTR(bp))
-#endif
+
+#define XFS_HDR_BLOCK(mp,d) ((xfs_agblock_t)XFS_BB_TO_FSBT(mp,d))
+#define XFS_DADDR_TO_FSB(mp,d) XFS_AGB_TO_FSB(mp, \
+ XFS_DADDR_TO_AGNO(mp,d), XFS_DADDR_TO_AGBNO(mp,d))
+#define XFS_FSB_TO_DADDR(mp,fsbno) XFS_AGB_TO_DADDR(mp, \
+ XFS_FSB_TO_AGNO(mp,fsbno), XFS_FSB_TO_AGBNO(mp,fsbno))
/*
* File system sector to basic block conversions.
diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c
index 92efe272b83d..279e043d7323 100644
--- a/fs/xfs/xfs_trans.c
+++ b/fs/xfs/xfs_trans.c
@@ -1,40 +1,26 @@
/*
- * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-
#include "xfs.h"
-#include "xfs_macros.h"
+#include "xfs_fs.h"
#include "xfs_types.h"
-#include "xfs_inum.h"
+#include "xfs_bit.h"
#include "xfs_log.h"
+#include "xfs_inum.h"
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
@@ -43,21 +29,21 @@
#include "xfs_dmapi.h"
#include "xfs_mount.h"
#include "xfs_error.h"
-#include "xfs_trans_priv.h"
-#include "xfs_alloc_btree.h"
+#include "xfs_da_btree.h"
#include "xfs_bmap_btree.h"
+#include "xfs_alloc_btree.h"
#include "xfs_ialloc_btree.h"
-#include "xfs_btree.h"
-#include "xfs_ialloc.h"
-#include "xfs_alloc.h"
-#include "xfs_attr_sf.h"
#include "xfs_dir_sf.h"
#include "xfs_dir2_sf.h"
+#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
#include "xfs_inode.h"
+#include "xfs_btree.h"
+#include "xfs_ialloc.h"
+#include "xfs_alloc.h"
#include "xfs_bmap.h"
-#include "xfs_da_btree.h"
#include "xfs_quota.h"
+#include "xfs_trans_priv.h"
#include "xfs_trans_space.h"
@@ -190,12 +176,8 @@ xfs_trans_dup(
XFS_LBC_INIT(&(ntp->t_busy));
ASSERT(tp->t_flags & XFS_TRANS_PERM_LOG_RES);
-
-#if defined(XLOG_NOLOG) || defined(DEBUG)
- ASSERT(!xlog_debug || tp->t_ticket != NULL);
-#else
ASSERT(tp->t_ticket != NULL);
-#endif
+
ntp->t_flags = XFS_TRANS_PERM_LOG_RES | (tp->t_flags & XFS_TRANS_RESERVE);
ntp->t_ticket = tp->t_ticket;
ntp->t_blk_res = tp->t_blk_res - tp->t_blk_res_used;
@@ -661,10 +643,11 @@ xfs_trans_unreserve_and_mod_sb(
*/
/*ARGSUSED*/
int
-xfs_trans_commit(
+_xfs_trans_commit(
xfs_trans_t *tp,
uint flags,
- xfs_lsn_t *commit_lsn_p)
+ xfs_lsn_t *commit_lsn_p,
+ int *log_flushed)
{
xfs_log_iovec_t *log_vector;
int nvec;
@@ -676,9 +659,6 @@ xfs_trans_commit(
int sync;
#define XFS_TRANS_LOGVEC_COUNT 16
xfs_log_iovec_t log_vector_fast[XFS_TRANS_LOGVEC_COUNT];
-#if defined(XLOG_NOLOG) || defined(DEBUG)
- static xfs_lsn_t trans_lsn = 1;
-#endif
void *commit_iclog;
int shutdown;
@@ -729,11 +709,7 @@ shut_us_down:
*commit_lsn_p = commit_lsn;
return (shutdown);
}
-#if defined(XLOG_NOLOG) || defined(DEBUG)
- ASSERT(!xlog_debug || tp->t_ticket != NULL);
-#else
ASSERT(tp->t_ticket != NULL);
-#endif
/*
* If we need to update the superblock, then do it now.
@@ -750,14 +726,10 @@ shut_us_down:
* by using a vector from the stack when it fits.
*/
nvec = xfs_trans_count_vecs(tp);
-
if (nvec == 0) {
xfs_force_shutdown(mp, XFS_LOG_IO_ERROR);
goto shut_us_down;
- }
-
-
- if (nvec <= XFS_TRANS_LOGVEC_COUNT) {
+ } else if (nvec <= XFS_TRANS_LOGVEC_COUNT) {
log_vector = log_vector_fast;
} else {
log_vector = (xfs_log_iovec_t *)kmem_alloc(nvec *
@@ -771,30 +743,14 @@ shut_us_down:
*/
xfs_trans_fill_vecs(tp, log_vector);
- /*
- * Ignore errors here. xfs_log_done would do the right thing.
- * We need to put the ticket, etc. away.
- */
- error = xfs_log_write(mp, log_vector, nvec, tp->t_ticket,
- &(tp->t_lsn));
+ error = xfs_log_write(mp, log_vector, nvec, tp->t_ticket, &(tp->t_lsn));
-#if defined(XLOG_NOLOG) || defined(DEBUG)
- if (xlog_debug) {
- commit_lsn = xfs_log_done(mp, tp->t_ticket,
- &commit_iclog, log_flags);
- } else {
- commit_lsn = 0;
- tp->t_lsn = trans_lsn++;
- }
-#else
/*
- * This is the regular case. At this point (after the call finishes),
- * the transaction is committed incore and could go out to disk at
- * any time. However, all the items associated with the transaction
- * are still locked and pinned in memory.
+ * The transaction is committed incore here, and can go out to disk
+ * at any time after this call. However, all the items associated
+ * with the transaction are still locked and pinned in memory.
*/
commit_lsn = xfs_log_done(mp, tp->t_ticket, &commit_iclog, log_flags);
-#endif
tp->t_commit_lsn = commit_lsn;
if (nvec > XFS_TRANS_LOGVEC_COUNT) {
@@ -893,9 +849,11 @@ shut_us_down:
* log out now and wait for it.
*/
if (sync) {
- if (!error)
- error = xfs_log_force(mp, commit_lsn,
- XFS_LOG_FORCE | XFS_LOG_SYNC);
+ if (!error) {
+ error = _xfs_log_force(mp, commit_lsn,
+ XFS_LOG_FORCE | XFS_LOG_SYNC,
+ log_flushed);
+ }
XFS_STATS_INC(xs_trans_sync);
} else {
XFS_STATS_INC(xs_trans_async);
diff --git a/fs/xfs/xfs_trans.h b/fs/xfs/xfs_trans.h
index a263aec8b3a6..a889963fdd14 100644
--- a/fs/xfs/xfs_trans.h
+++ b/fs/xfs/xfs_trans.h
@@ -1,33 +1,19 @@
/*
- * Copyright (c) 2000-2002 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __XFS_TRANS_H__
#define __XFS_TRANS_H__
@@ -135,19 +121,6 @@ typedef struct xfs_ail_entry {
struct xfs_log_item *ail_back; /* AIL back pointer */
} xfs_ail_entry_t;
-/*
- * This structure is passed as a parameter to xfs_trans_push_ail()
- * and is used to track the what LSN the waiting processes are
- * waiting to become unused.
- */
-typedef struct xfs_ail_ticket {
- xfs_lsn_t at_lsn; /* lsn waitin for */
- struct xfs_ail_ticket *at_forw; /* wait list ptr */
- struct xfs_ail_ticket *at_back; /* wait list ptr */
- sv_t at_sema; /* wait sema */
-} xfs_ail_ticket_t;
-
-
typedef struct xfs_log_item {
xfs_ail_entry_t li_ail; /* AIL pointers */
xfs_lsn_t li_lsn; /* last on-disk lsn */
@@ -247,68 +220,67 @@ typedef struct xfs_log_item_chunk {
* lic_unused to the right value (0 matches all free). The
* lic_descs.lid_index values are set up as each desc is allocated.
*/
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_LIC_INIT)
-void xfs_lic_init(xfs_log_item_chunk_t *cp);
#define XFS_LIC_INIT(cp) xfs_lic_init(cp)
-#else
-#define XFS_LIC_INIT(cp) ((cp)->lic_free = XFS_LIC_FREEMASK)
-#endif
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_LIC_INIT_SLOT)
-void xfs_lic_init_slot(xfs_log_item_chunk_t *cp, int slot);
+static inline void xfs_lic_init(xfs_log_item_chunk_t *cp)
+{
+ cp->lic_free = XFS_LIC_FREEMASK;
+}
+
#define XFS_LIC_INIT_SLOT(cp,slot) xfs_lic_init_slot(cp, slot)
-#else
-#define XFS_LIC_INIT_SLOT(cp,slot) \
- ((cp)->lic_descs[slot].lid_index = (unsigned char)(slot))
-#endif
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_LIC_VACANCY)
-int xfs_lic_vacancy(xfs_log_item_chunk_t *cp);
+static inline void xfs_lic_init_slot(xfs_log_item_chunk_t *cp, int slot)
+{
+ cp->lic_descs[slot].lid_index = (unsigned char)(slot);
+}
+
#define XFS_LIC_VACANCY(cp) xfs_lic_vacancy(cp)
-#else
-#define XFS_LIC_VACANCY(cp) (((cp)->lic_free) & XFS_LIC_FREEMASK)
-#endif
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_LIC_ALL_FREE)
-void xfs_lic_all_free(xfs_log_item_chunk_t *cp);
+static inline int xfs_lic_vacancy(xfs_log_item_chunk_t *cp)
+{
+ return cp->lic_free & XFS_LIC_FREEMASK;
+}
+
#define XFS_LIC_ALL_FREE(cp) xfs_lic_all_free(cp)
-#else
-#define XFS_LIC_ALL_FREE(cp) ((cp)->lic_free = XFS_LIC_FREEMASK)
-#endif
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_LIC_ARE_ALL_FREE)
-int xfs_lic_are_all_free(xfs_log_item_chunk_t *cp);
+static inline void xfs_lic_all_free(xfs_log_item_chunk_t *cp)
+{
+ cp->lic_free = XFS_LIC_FREEMASK;
+}
+
#define XFS_LIC_ARE_ALL_FREE(cp) xfs_lic_are_all_free(cp)
-#else
-#define XFS_LIC_ARE_ALL_FREE(cp) (((cp)->lic_free & XFS_LIC_FREEMASK) ==\
- XFS_LIC_FREEMASK)
-#endif
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_LIC_ISFREE)
-int xfs_lic_isfree(xfs_log_item_chunk_t *cp, int slot);
+static inline int xfs_lic_are_all_free(xfs_log_item_chunk_t *cp)
+{
+ return ((cp->lic_free & XFS_LIC_FREEMASK) == XFS_LIC_FREEMASK);
+}
+
#define XFS_LIC_ISFREE(cp,slot) xfs_lic_isfree(cp,slot)
-#else
-#define XFS_LIC_ISFREE(cp,slot) ((cp)->lic_free & (1 << (slot)))
-#endif
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_LIC_CLAIM)
-void xfs_lic_claim(xfs_log_item_chunk_t *cp, int slot);
+static inline int xfs_lic_isfree(xfs_log_item_chunk_t *cp, int slot)
+{
+ return (cp->lic_free & (1 << slot));
+}
+
#define XFS_LIC_CLAIM(cp,slot) xfs_lic_claim(cp,slot)
-#else
-#define XFS_LIC_CLAIM(cp,slot) ((cp)->lic_free &= ~(1 << (slot)))
-#endif
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_LIC_RELSE)
-void xfs_lic_relse(xfs_log_item_chunk_t *cp, int slot);
+static inline void xfs_lic_claim(xfs_log_item_chunk_t *cp, int slot)
+{
+ cp->lic_free &= ~(1 << slot);
+}
+
#define XFS_LIC_RELSE(cp,slot) xfs_lic_relse(cp,slot)
-#else
-#define XFS_LIC_RELSE(cp,slot) ((cp)->lic_free |= 1 << (slot))
-#endif
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_LIC_SLOT)
-xfs_log_item_desc_t *xfs_lic_slot(xfs_log_item_chunk_t *cp, int slot);
+static inline void xfs_lic_relse(xfs_log_item_chunk_t *cp, int slot)
+{
+ cp->lic_free |= 1 << slot;
+}
+
#define XFS_LIC_SLOT(cp,slot) xfs_lic_slot(cp,slot)
-#else
-#define XFS_LIC_SLOT(cp,slot) (&((cp)->lic_descs[slot]))
-#endif
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_LIC_DESC_TO_SLOT)
-int xfs_lic_desc_to_slot(xfs_log_item_desc_t *dp);
+static inline xfs_log_item_desc_t *
+xfs_lic_slot(xfs_log_item_chunk_t *cp, int slot)
+{
+ return &(cp->lic_descs[slot]);
+}
+
#define XFS_LIC_DESC_TO_SLOT(dp) xfs_lic_desc_to_slot(dp)
-#else
-#define XFS_LIC_DESC_TO_SLOT(dp) ((uint)((dp)->lid_index))
-#endif
+static inline int xfs_lic_desc_to_slot(xfs_log_item_desc_t *dp)
+{
+ return (uint)dp->lid_index;
+}
+
/*
* Calculate the address of a chunk given a descriptor pointer:
* dp - dp->lid_index give the address of the start of the lic_descs array.
@@ -316,15 +288,14 @@ int xfs_lic_desc_to_slot(xfs_log_item_desc_t *dp);
* All of this yields the address of the chunk, which is
* cast to a chunk pointer.
*/
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_LIC_DESC_TO_CHUNK)
-xfs_log_item_chunk_t *xfs_lic_desc_to_chunk(xfs_log_item_desc_t *dp);
#define XFS_LIC_DESC_TO_CHUNK(dp) xfs_lic_desc_to_chunk(dp)
-#else
-#define XFS_LIC_DESC_TO_CHUNK(dp) ((xfs_log_item_chunk_t*) \
- (((xfs_caddr_t)((dp) - (dp)->lid_index)) -\
- (xfs_caddr_t)(((xfs_log_item_chunk_t*) \
- 0)->lic_descs)))
-#endif
+static inline xfs_log_item_chunk_t *
+xfs_lic_desc_to_chunk(xfs_log_item_desc_t *dp)
+{
+ return (xfs_log_item_chunk_t*) \
+ (((xfs_caddr_t)((dp) - (dp)->lid_index)) - \
+ (xfs_caddr_t)(((xfs_log_item_chunk_t*)0)->lic_descs));
+}
#ifdef __KERNEL__
/*
@@ -341,7 +312,7 @@ typedef struct xfs_log_busy_slot {
#define XFS_LBC_NUM_SLOTS 31
typedef struct xfs_log_busy_chunk {
struct xfs_log_busy_chunk *lbc_next;
- uint lbc_free; /* bitmask of free slots */
+ uint lbc_free; /* free slots bitmask */
ushort lbc_unused; /* first unused */
xfs_log_busy_slot_t lbc_busy[XFS_LBC_NUM_SLOTS];
} xfs_log_busy_chunk_t;
@@ -1025,7 +996,12 @@ void xfs_trans_log_efd_extent(xfs_trans_t *,
struct xfs_efd_log_item *,
xfs_fsblock_t,
xfs_extlen_t);
-int xfs_trans_commit(xfs_trans_t *, uint flags, xfs_lsn_t *);
+int _xfs_trans_commit(xfs_trans_t *,
+ uint flags,
+ xfs_lsn_t *,
+ int *);
+#define xfs_trans_commit(tp, flags, lsn) \
+ _xfs_trans_commit(tp, flags, lsn, NULL)
void xfs_trans_cancel(xfs_trans_t *, int);
void xfs_trans_ail_init(struct xfs_mount *);
xfs_lsn_t xfs_trans_push_ail(struct xfs_mount *, xfs_lsn_t);
diff --git a/fs/xfs/xfs_trans_ail.c b/fs/xfs/xfs_trans_ail.c
index 2a71b4f91bfa..19ab24af1c1c 100644
--- a/fs/xfs/xfs_trans_ail.c
+++ b/fs/xfs/xfs_trans_ail.c
@@ -1,40 +1,25 @@
/*
- * Copyright (c) 2000-2002 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-
#include "xfs.h"
-#include "xfs_macros.h"
+#include "xfs_fs.h"
#include "xfs_types.h"
-#include "xfs_inum.h"
#include "xfs_log.h"
+#include "xfs_inum.h"
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_dir.h"
diff --git a/fs/xfs/xfs_trans_buf.c b/fs/xfs/xfs_trans_buf.c
index e733293dd7f4..c74c31ebc81c 100644
--- a/fs/xfs/xfs_trans_buf.c
+++ b/fs/xfs/xfs_trans_buf.c
@@ -1,47 +1,42 @@
/*
- * Copyright (c) 2000-2002 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-
#include "xfs.h"
-#include "xfs_macros.h"
+#include "xfs_fs.h"
#include "xfs_types.h"
-#include "xfs_inum.h"
+#include "xfs_bit.h"
#include "xfs_log.h"
+#include "xfs_inum.h"
#include "xfs_trans.h"
-#include "xfs_buf_item.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
#include "xfs_dir.h"
+#include "xfs_dir2.h"
#include "xfs_dmapi.h"
#include "xfs_mount.h"
+#include "xfs_bmap_btree.h"
+#include "xfs_alloc_btree.h"
+#include "xfs_ialloc_btree.h"
+#include "xfs_dir_sf.h"
+#include "xfs_dir2_sf.h"
+#include "xfs_attr_sf.h"
+#include "xfs_dinode.h"
+#include "xfs_inode.h"
+#include "xfs_buf_item.h"
#include "xfs_trans_priv.h"
#include "xfs_error.h"
#include "xfs_rw.h"
diff --git a/fs/xfs/xfs_trans_extfree.c b/fs/xfs/xfs_trans_extfree.c
index 93259a15f983..7d7d627f25df 100644
--- a/fs/xfs/xfs_trans_extfree.c
+++ b/fs/xfs/xfs_trans_extfree.c
@@ -1,40 +1,25 @@
/*
- * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000,2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-
#include "xfs.h"
-#include "xfs_macros.h"
+#include "xfs_fs.h"
#include "xfs_types.h"
-#include "xfs_inum.h"
#include "xfs_log.h"
+#include "xfs_inum.h"
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_dir.h"
diff --git a/fs/xfs/xfs_trans_inode.c b/fs/xfs/xfs_trans_inode.c
index 7e7631ca4979..e341409172d2 100644
--- a/fs/xfs/xfs_trans_inode.c
+++ b/fs/xfs/xfs_trans_inode.c
@@ -1,40 +1,26 @@
/*
- * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000,2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-
#include "xfs.h"
-#include "xfs_macros.h"
+#include "xfs_fs.h"
#include "xfs_types.h"
-#include "xfs_inum.h"
+#include "xfs_bit.h"
#include "xfs_log.h"
+#include "xfs_inum.h"
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
@@ -42,18 +28,18 @@
#include "xfs_dir2.h"
#include "xfs_dmapi.h"
#include "xfs_mount.h"
-#include "xfs_trans_priv.h"
-#include "xfs_alloc_btree.h"
#include "xfs_bmap_btree.h"
+#include "xfs_alloc_btree.h"
#include "xfs_ialloc_btree.h"
-#include "xfs_btree.h"
-#include "xfs_ialloc.h"
-#include "xfs_attr_sf.h"
#include "xfs_dir_sf.h"
#include "xfs_dir2_sf.h"
+#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
-#include "xfs_inode_item.h"
#include "xfs_inode.h"
+#include "xfs_btree.h"
+#include "xfs_ialloc.h"
+#include "xfs_trans_priv.h"
+#include "xfs_inode_item.h"
#ifdef XFS_TRANS_DEBUG
STATIC void
diff --git a/fs/xfs/xfs_trans_item.c b/fs/xfs/xfs_trans_item.c
index 1b8a756d80ed..486147ef0e3d 100644
--- a/fs/xfs/xfs_trans_item.c
+++ b/fs/xfs/xfs_trans_item.c
@@ -1,40 +1,25 @@
/*
- * Copyright (c) 2000-2002 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-
#include "xfs.h"
-#include "xfs_macros.h"
+#include "xfs_fs.h"
#include "xfs_types.h"
-#include "xfs_inum.h"
#include "xfs_log.h"
+#include "xfs_inum.h"
#include "xfs_trans.h"
STATIC int xfs_trans_unlock_chunk(xfs_log_item_chunk_t *,
diff --git a/fs/xfs/xfs_trans_priv.h b/fs/xfs/xfs_trans_priv.h
index d4dae7d06afc..13edab8a9e94 100644
--- a/fs/xfs/xfs_trans_priv.h
+++ b/fs/xfs/xfs_trans_priv.h
@@ -1,33 +1,19 @@
/*
- * Copyright (c) 2000, 2002 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000,2002,2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __XFS_TRANS_PRIV_H__
#define __XFS_TRANS_PRIV_H__
diff --git a/fs/xfs/xfs_trans_space.h b/fs/xfs/xfs_trans_space.h
index e91d173f4ed3..7fe3792b18df 100644
--- a/fs/xfs/xfs_trans_space.h
+++ b/fs/xfs/xfs_trans_space.h
@@ -1,33 +1,19 @@
/*
- * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000,2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __XFS_TRANS_SPACE_H__
#define __XFS_TRANS_SPACE_H__
diff --git a/fs/xfs/xfs_types.h b/fs/xfs/xfs_types.h
index 16f5371ce102..104f64a98790 100644
--- a/fs/xfs/xfs_types.h
+++ b/fs/xfs/xfs_types.h
@@ -1,33 +1,19 @@
/*
- * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __XFS_TYPES_H__
#define __XFS_TYPES_H__
@@ -154,6 +140,12 @@ typedef __uint8_t xfs_arch_t; /* architecture of an xfs fs */
#define MAXAEXTNUM ((xfs_aextnum_t)0x7fff) /* signed short */
/*
+ * Min numbers of data/attr fork btree root pointers.
+ */
+#define MINDBTPTRS 3
+#define MINABTPTRS 2
+
+/*
* MAXNAMELEN is the length (including the terminating null) of
* the longest permissible file (component) name.
*/
diff --git a/fs/xfs/xfs_utils.c b/fs/xfs/xfs_utils.c
index 11351f08d438..fefe1d60377f 100644
--- a/fs/xfs/xfs_utils.c
+++ b/fs/xfs/xfs_utils.c
@@ -1,53 +1,40 @@
/*
- * Copyright (c) 2000-2002 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-
#include "xfs.h"
-#include "xfs_macros.h"
+#include "xfs_fs.h"
#include "xfs_types.h"
-#include "xfs_inum.h"
+#include "xfs_bit.h"
#include "xfs_log.h"
+#include "xfs_inum.h"
#include "xfs_trans.h"
#include "xfs_sb.h"
+#include "xfs_ag.h"
#include "xfs_dir.h"
#include "xfs_dir2.h"
#include "xfs_dmapi.h"
#include "xfs_mount.h"
#include "xfs_bmap_btree.h"
-#include "xfs_attr_sf.h"
#include "xfs_dir_sf.h"
#include "xfs_dir2_sf.h"
+#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
-#include "xfs_inode_item.h"
#include "xfs_inode.h"
+#include "xfs_inode_item.h"
#include "xfs_bmap.h"
#include "xfs_error.h"
#include "xfs_quota.h"
diff --git a/fs/xfs/xfs_utils.h b/fs/xfs/xfs_utils.h
index 01d98b4b7af7..472661a3b6d8 100644
--- a/fs/xfs/xfs_utils.h
+++ b/fs/xfs/xfs_utils.h
@@ -1,33 +1,19 @@
/*
- * Copyright (c) 2000-2002 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __XFS_UTILS_H__
#define __XFS_UTILS_H__
diff --git a/fs/xfs/xfs_vfsops.c b/fs/xfs/xfs_vfsops.c
index f1a904e23ade..7bdbd991ab1c 100644
--- a/fs/xfs/xfs_vfsops.c
+++ b/fs/xfs/xfs_vfsops.c
@@ -1,74 +1,58 @@
/*
- * XFS filesystem operations.
+ * Copyright (c) 2000-2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * Copyright (c) 2000-2005 Silicon Graphics, Inc. All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-
#include "xfs.h"
-#include "xfs_macros.h"
+#include "xfs_fs.h"
#include "xfs_types.h"
-#include "xfs_inum.h"
+#include "xfs_bit.h"
#include "xfs_log.h"
+#include "xfs_inum.h"
#include "xfs_trans.h"
#include "xfs_sb.h"
+#include "xfs_ag.h"
#include "xfs_dir.h"
#include "xfs_dir2.h"
#include "xfs_dmapi.h"
#include "xfs_mount.h"
+#include "xfs_da_btree.h"
#include "xfs_bmap_btree.h"
#include "xfs_ialloc_btree.h"
#include "xfs_alloc_btree.h"
-#include "xfs_btree.h"
-#include "xfs_alloc.h"
-#include "xfs_ialloc.h"
-#include "xfs_attr_sf.h"
#include "xfs_dir_sf.h"
#include "xfs_dir2_sf.h"
+#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
-#include "xfs_inode_item.h"
#include "xfs_inode.h"
-#include "xfs_ag.h"
+#include "xfs_inode_item.h"
+#include "xfs_btree.h"
+#include "xfs_alloc.h"
+#include "xfs_ialloc.h"
+#include "xfs_quota.h"
#include "xfs_error.h"
#include "xfs_bmap.h"
-#include "xfs_da_btree.h"
#include "xfs_rw.h"
#include "xfs_refcache.h"
#include "xfs_buf_item.h"
-#include "xfs_extfree_item.h"
-#include "xfs_quota.h"
+#include "xfs_log_priv.h"
#include "xfs_dir2_trace.h"
+#include "xfs_extfree_item.h"
#include "xfs_acl.h"
#include "xfs_attr.h"
#include "xfs_clnt.h"
-#include "xfs_log_priv.h"
STATIC int xfs_sync(bhv_desc_t *, int, cred_t *);
@@ -230,9 +214,7 @@ xfs_start_flags(
}
if (ap->logbufs != -1 &&
-#if defined(DEBUG) || defined(XLOG_NOLOG)
ap->logbufs != 0 &&
-#endif
(ap->logbufs < XLOG_MIN_ICLOGS ||
ap->logbufs > XLOG_MAX_ICLOGS)) {
cmn_err(CE_WARN,
@@ -242,6 +224,7 @@ xfs_start_flags(
}
mp->m_logbufs = ap->logbufs;
if (ap->logbufsize != -1 &&
+ ap->logbufsize != 0 &&
ap->logbufsize != 16 * 1024 &&
ap->logbufsize != 32 * 1024 &&
ap->logbufsize != 64 * 1024 &&
@@ -257,6 +240,14 @@ xfs_start_flags(
mp->m_fsname_len = strlen(ap->fsname) + 1;
mp->m_fsname = kmem_alloc(mp->m_fsname_len, KM_SLEEP);
strcpy(mp->m_fsname, ap->fsname);
+ if (ap->rtname[0]) {
+ mp->m_rtname = kmem_alloc(strlen(ap->rtname) + 1, KM_SLEEP);
+ strcpy(mp->m_rtname, ap->rtname);
+ }
+ if (ap->logname[0]) {
+ mp->m_logname = kmem_alloc(strlen(ap->logname) + 1, KM_SLEEP);
+ strcpy(mp->m_logname, ap->logname);
+ }
if (ap->flags & XFSMNT_WSYNC)
mp->m_flags |= XFS_MOUNT_WSYNC;
@@ -268,21 +259,16 @@ xfs_start_flags(
#endif
if (ap->flags & XFSMNT_NOATIME)
mp->m_flags |= XFS_MOUNT_NOATIME;
-
if (ap->flags & XFSMNT_RETERR)
mp->m_flags |= XFS_MOUNT_RETERR;
-
if (ap->flags & XFSMNT_NOALIGN)
mp->m_flags |= XFS_MOUNT_NOALIGN;
-
if (ap->flags & XFSMNT_SWALLOC)
mp->m_flags |= XFS_MOUNT_SWALLOC;
-
if (ap->flags & XFSMNT_OSYNCISOSYNC)
mp->m_flags |= XFS_MOUNT_OSYNCISOSYNC;
-
if (ap->flags & XFSMNT_32BITINODES)
- mp->m_flags |= (XFS_MOUNT_32BITINODES | XFS_MOUNT_32BITINOOPT);
+ mp->m_flags |= XFS_MOUNT_32BITINODES;
if (ap->flags & XFSMNT_IOSIZE) {
if (ap->iosizelog > XFS_MAX_IO_LOG ||
@@ -300,12 +286,15 @@ xfs_start_flags(
if (ap->flags & XFSMNT_IHASHSIZE)
mp->m_flags |= XFS_MOUNT_IHASHSIZE;
-
if (ap->flags & XFSMNT_IDELETE)
mp->m_flags |= XFS_MOUNT_IDELETE;
-
if (ap->flags & XFSMNT_DIRSYNC)
mp->m_flags |= XFS_MOUNT_DIRSYNC;
+ if (ap->flags & XFSMNT_COMPAT_ATTR)
+ mp->m_flags |= XFS_MOUNT_COMPAT_ATTR;
+
+ if (ap->flags2 & XFSMNT2_COMPAT_IOSIZE)
+ mp->m_flags |= XFS_MOUNT_COMPAT_IOSIZE;
/*
* no recovery flag requires a read-only mount
@@ -321,8 +310,8 @@ xfs_start_flags(
if (ap->flags & XFSMNT_NOUUID)
mp->m_flags |= XFS_MOUNT_NOUUID;
- if (ap->flags & XFSMNT_NOLOGFLUSH)
- mp->m_flags |= XFS_MOUNT_NOLOGFLUSH;
+ if (ap->flags & XFSMNT_BARRIER)
+ mp->m_flags |= XFS_MOUNT_BARRIER;
return 0;
}
@@ -393,6 +382,10 @@ xfs_finish_flags(
return XFS_ERROR(EINVAL);
}
+ if (XFS_SB_VERSION_HASATTR2(&mp->m_sb)) {
+ mp->m_flags &= ~XFS_MOUNT_COMPAT_ATTR;
+ }
+
return 0;
}
@@ -512,8 +505,14 @@ xfs_mount(
goto error2;
error = XFS_IOINIT(vfsp, args, flags);
- if (!error)
- return 0;
+ if (error)
+ goto error2;
+
+ if ((args->flags & XFSMNT_BARRIER) &&
+ !(XFS_MTOVFS(mp)->vfs_flag & VFS_RDONLY))
+ xfs_mountfs_check_barriers(mp);
+ return 0;
+
error2:
if (mp->m_sb_bp)
xfs_freesb(mp);
@@ -656,19 +655,24 @@ xfs_mntupdate(
else
mp->m_flags &= ~XFS_MOUNT_NOATIME;
- if (!(vfsp->vfs_flag & VFS_RDONLY)) {
- VFS_SYNC(vfsp, SYNC_FSDATA|SYNC_BDFLUSH|SYNC_ATTR, NULL, error);
+ if ((vfsp->vfs_flag & VFS_RDONLY) &&
+ !(*flags & MS_RDONLY)) {
+ vfsp->vfs_flag &= ~VFS_RDONLY;
+
+ if (args->flags & XFSMNT_BARRIER)
+ xfs_mountfs_check_barriers(mp);
}
- if (*flags & MS_RDONLY) {
+ if (!(vfsp->vfs_flag & VFS_RDONLY) &&
+ (*flags & MS_RDONLY)) {
+ VFS_SYNC(vfsp, SYNC_FSDATA|SYNC_BDFLUSH|SYNC_ATTR, NULL, error);
+
xfs_quiesce_fs(mp);
/* Ok now write out an unmount record */
xfs_log_unmount_write(mp);
xfs_unmountfs_writesb(mp);
vfsp->vfs_flag |= VFS_RDONLY;
- } else {
- vfsp->vfs_flag &= ~VFS_RDONLY;
}
return 0;
@@ -892,7 +896,7 @@ xfs_sync(
* only available by calling this routine.
*
*/
-STATIC int
+int
xfs_sync_inodes(
xfs_mount_t *mp,
int flags,
@@ -976,7 +980,7 @@ xfs_sync_inodes(
ipointer = (xfs_iptr_t *)kmem_zalloc(sizeof(xfs_iptr_t), KM_SLEEP);
fflag = XFS_B_ASYNC; /* default is don't wait */
- if (flags & SYNC_BDFLUSH)
+ if (flags & (SYNC_BDFLUSH | SYNC_DELWRI))
fflag = XFS_B_DELWRI;
if (flags & SYNC_WAIT)
fflag = 0; /* synchronous overrides all */
@@ -1628,11 +1632,17 @@ xfs_vget(
#define MNTOPT_ALLOCSIZE "allocsize" /* preferred allocation size */
#define MNTOPT_IHASHSIZE "ihashsize" /* size of inode hash table */
#define MNTOPT_NORECOVERY "norecovery" /* don't run XFS recovery */
-#define MNTOPT_NOLOGFLUSH "nologflush" /* don't hard flush on log writes */
+#define MNTOPT_BARRIER "barrier" /* use writer barriers for log write and
+ * unwritten extent conversion */
#define MNTOPT_OSYNCISOSYNC "osyncisosync" /* o_sync is REALLY o_sync */
#define MNTOPT_64BITINODE "inode64" /* inodes can be allocated anywhere */
#define MNTOPT_IKEEP "ikeep" /* do not free empty inode clusters */
#define MNTOPT_NOIKEEP "noikeep" /* free empty inode clusters */
+#define MNTOPT_LARGEIO "largeio" /* report large I/O sizes in stat() */
+#define MNTOPT_NOLARGEIO "nolargeio" /* do not report large I/O sizes
+ * in stat(). */
+#define MNTOPT_ATTR2 "attr2" /* do use attr2 attribute format */
+#define MNTOPT_NOATTR2 "noattr2" /* do not use attr2 attribute format */
STATIC unsigned long
suffix_strtoul(const char *cp, char **endp, unsigned int base)
@@ -1669,12 +1679,15 @@ xfs_parseargs(
int dsunit, dswidth, vol_dsunit, vol_dswidth;
int iosize;
+ args->flags2 |= XFSMNT2_COMPAT_IOSIZE;
+ args->flags |= XFSMNT_COMPAT_ATTR;
+
#if 0 /* XXX: off by default, until some remaining issues ironed out */
args->flags |= XFSMNT_IDELETE; /* default to on */
#endif
if (!options)
- return 0;
+ goto done;
iosize = dsunit = dswidth = vol_dsunit = vol_dswidth = 0;
@@ -1791,12 +1804,20 @@ xfs_parseargs(
#endif
} else if (!strcmp(this_char, MNTOPT_NOUUID)) {
args->flags |= XFSMNT_NOUUID;
- } else if (!strcmp(this_char, MNTOPT_NOLOGFLUSH)) {
- args->flags |= XFSMNT_NOLOGFLUSH;
+ } else if (!strcmp(this_char, MNTOPT_BARRIER)) {
+ args->flags |= XFSMNT_BARRIER;
} else if (!strcmp(this_char, MNTOPT_IKEEP)) {
args->flags &= ~XFSMNT_IDELETE;
} else if (!strcmp(this_char, MNTOPT_NOIKEEP)) {
args->flags |= XFSMNT_IDELETE;
+ } else if (!strcmp(this_char, MNTOPT_LARGEIO)) {
+ args->flags2 &= ~XFSMNT2_COMPAT_IOSIZE;
+ } else if (!strcmp(this_char, MNTOPT_NOLARGEIO)) {
+ args->flags2 |= XFSMNT2_COMPAT_IOSIZE;
+ } else if (!strcmp(this_char, MNTOPT_ATTR2)) {
+ args->flags &= ~XFSMNT_COMPAT_ATTR;
+ } else if (!strcmp(this_char, MNTOPT_NOATTR2)) {
+ args->flags |= XFSMNT_COMPAT_ATTR;
} else if (!strcmp(this_char, "osyncisdsync")) {
/* no-op, this is now the default */
printk("XFS: osyncisdsync is now the default, option is deprecated.\n");
@@ -1846,6 +1867,11 @@ printk("XFS: irixsgid is now a sysctl(2) variable, option is deprecated.\n");
args->sunit = args->swidth = 0;
}
+done:
+ if (args->flags & XFSMNT_32BITINODES)
+ vfsp->vfs_flag |= VFS_32BITINODES;
+ if (args->flags2)
+ args->flags |= XFSMNT_FLAGS2;
return 0;
}
@@ -1866,7 +1892,7 @@ xfs_showargs(
{ XFS_MOUNT_NOUUID, "," MNTOPT_NOUUID },
{ XFS_MOUNT_NORECOVERY, "," MNTOPT_NORECOVERY },
{ XFS_MOUNT_OSYNCISOSYNC, "," MNTOPT_OSYNCISOSYNC },
- { XFS_MOUNT_NOLOGFLUSH, "," MNTOPT_NOLOGFLUSH },
+ { XFS_MOUNT_BARRIER, "," MNTOPT_BARRIER },
{ XFS_MOUNT_IDELETE, "," MNTOPT_NOIKEEP },
{ 0, NULL }
};
@@ -1883,21 +1909,20 @@ xfs_showargs(
seq_printf(m, "," MNTOPT_IHASHSIZE "=%d", mp->m_ihsize);
if (mp->m_flags & XFS_MOUNT_DFLT_IOSIZE)
- seq_printf(m, "," MNTOPT_ALLOCSIZE "=%d", 1<<mp->m_writeio_log);
+ seq_printf(m, "," MNTOPT_ALLOCSIZE "=%dk",
+ (int)(1 << mp->m_writeio_log) >> 10);
if (mp->m_logbufs > 0)
seq_printf(m, "," MNTOPT_LOGBUFS "=%d", mp->m_logbufs);
if (mp->m_logbsize > 0)
- seq_printf(m, "," MNTOPT_LOGBSIZE "=%d", mp->m_logbsize);
+ seq_printf(m, "," MNTOPT_LOGBSIZE "=%dk", mp->m_logbsize >> 10);
- if (mp->m_ddev_targp != mp->m_logdev_targp)
- seq_printf(m, "," MNTOPT_LOGDEV "=%s",
- XFS_BUFTARG_NAME(mp->m_logdev_targp));
+ if (mp->m_logname)
+ seq_printf(m, "," MNTOPT_LOGDEV "=%s", mp->m_logname);
- if (mp->m_rtdev_targp && mp->m_ddev_targp != mp->m_rtdev_targp)
- seq_printf(m, "," MNTOPT_RTDEV "=%s",
- XFS_BUFTARG_NAME(mp->m_rtdev_targp));
+ if (mp->m_rtname)
+ seq_printf(m, "," MNTOPT_RTDEV "=%s", mp->m_rtname);
if (mp->m_dalign > 0)
seq_printf(m, "," MNTOPT_SUNIT "=%d",
@@ -1907,7 +1932,13 @@ xfs_showargs(
seq_printf(m, "," MNTOPT_SWIDTH "=%d",
(int)XFS_FSB_TO_BB(mp, mp->m_swidth));
- if (!(mp->m_flags & XFS_MOUNT_32BITINOOPT))
+ if (!(mp->m_flags & XFS_MOUNT_COMPAT_ATTR))
+ seq_printf(m, "," MNTOPT_ATTR2);
+
+ if (!(mp->m_flags & XFS_MOUNT_COMPAT_IOSIZE))
+ seq_printf(m, "," MNTOPT_LARGEIO);
+
+ if (!(vfsp->vfs_flag & VFS_32BITINODES))
seq_printf(m, "," MNTOPT_64BITINODE);
if (vfsp->vfs_flag & VFS_GRPID)
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c
index 58bfe629b933..7c1f74531463 100644
--- a/fs/xfs/xfs_vnodeops.c
+++ b/fs/xfs/xfs_vnodeops.c
@@ -1,40 +1,26 @@
/*
- * Copyright (c) 2000-2005 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-
#include "xfs.h"
-#include "xfs_macros.h"
+#include "xfs_fs.h"
#include "xfs_types.h"
-#include "xfs_inum.h"
+#include "xfs_bit.h"
#include "xfs_log.h"
+#include "xfs_inum.h"
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
@@ -42,33 +28,32 @@
#include "xfs_dir2.h"
#include "xfs_dmapi.h"
#include "xfs_mount.h"
-#include "xfs_alloc_btree.h"
+#include "xfs_da_btree.h"
#include "xfs_bmap_btree.h"
+#include "xfs_alloc_btree.h"
#include "xfs_ialloc_btree.h"
-#include "xfs_itable.h"
-#include "xfs_btree.h"
-#include "xfs_ialloc.h"
-#include "xfs_alloc.h"
-#include "xfs_attr_sf.h"
#include "xfs_dir_sf.h"
#include "xfs_dir2_sf.h"
+#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
-#include "xfs_inode_item.h"
#include "xfs_inode.h"
+#include "xfs_inode_item.h"
+#include "xfs_dir_leaf.h"
+#include "xfs_itable.h"
+#include "xfs_btree.h"
+#include "xfs_ialloc.h"
+#include "xfs_alloc.h"
#include "xfs_bmap.h"
-#include "xfs_da_btree.h"
#include "xfs_attr.h"
#include "xfs_rw.h"
-#include "xfs_refcache.h"
#include "xfs_error.h"
-#include "xfs_bit.h"
-#include "xfs_rtalloc.h"
#include "xfs_quota.h"
#include "xfs_utils.h"
+#include "xfs_rtalloc.h"
+#include "xfs_refcache.h"
#include "xfs_trans_space.h"
-#include "xfs_dir_leaf.h"
-#include "xfs_mac.h"
#include "xfs_log_priv.h"
+#include "xfs_mac.h"
/*
@@ -181,40 +166,7 @@ xfs_getattr(
vap->va_rdev = 0;
if (!(ip->i_d.di_flags & XFS_DIFLAG_REALTIME)) {
-
-#if 0
- /* Large block sizes confuse various
- * user space programs, so letting the
- * stripe size through is not a good
- * idea for now.
- */
- vap->va_blocksize = mp->m_swidth ?
- /*
- * If the underlying volume is a stripe, then
- * return the stripe width in bytes as the
- * recommended I/O size.
- */
- (mp->m_swidth << mp->m_sb.sb_blocklog) :
- /*
- * Return the largest of the preferred buffer
- * sizes since doing small I/Os into larger
- * buffers causes buffers to be decommissioned.
- * The value returned is in bytes.
- */
- (1 << (int)MAX(mp->m_readio_log,
- mp->m_writeio_log));
-
-#else
- vap->va_blocksize =
- /*
- * Return the largest of the preferred buffer
- * sizes since doing small I/Os into larger
- * buffers causes buffers to be decommissioned.
- * The value returned is in bytes.
- */
- 1 << (int)MAX(mp->m_readio_log,
- mp->m_writeio_log);
-#endif
+ vap->va_blocksize = xfs_preferred_iosize(mp);
} else {
/*
@@ -581,8 +533,7 @@ xfs_setattr(
/*
* Can't change extent size if any extents are allocated.
*/
- if ((ip->i_d.di_nextents || ip->i_delayed_blks) &&
- (mask & XFS_AT_EXTSIZE) &&
+ if (ip->i_d.di_nextents && (mask & XFS_AT_EXTSIZE) &&
((ip->i_d.di_extsize << mp->m_sb.sb_blocklog) !=
vap->va_extsize) ) {
code = XFS_ERROR(EINVAL); /* EFBIG? */
@@ -610,7 +561,8 @@ xfs_setattr(
/*
* Can't change realtime flag if any extents are allocated.
*/
- if (ip->i_d.di_nextents && (mask & XFS_AT_XFLAGS) &&
+ if ((ip->i_d.di_nextents || ip->i_delayed_blks) &&
+ (mask & XFS_AT_XFLAGS) &&
(ip->i_d.di_flags & XFS_DIFLAG_REALTIME) !=
(vap->va_xflags & XFS_XFLAG_REALTIME)) {
code = XFS_ERROR(EINVAL); /* EFBIG? */
@@ -674,8 +626,10 @@ xfs_setattr(
*/
if (mask & XFS_AT_SIZE) {
code = 0;
- if (vap->va_size > ip->i_d.di_size)
+ if ((vap->va_size > ip->i_d.di_size) &&
+ (flags & ATTR_NOSIZETOK) == 0) {
code = xfs_igrow_start(ip, vap->va_size, credp);
+ }
xfs_iunlock(ip, XFS_ILOCK_EXCL);
if (!code)
code = xfs_itruncate_data(ip, vap->va_size);
@@ -1118,6 +1072,7 @@ xfs_fsync(
xfs_inode_t *ip;
xfs_trans_t *tp;
int error;
+ int log_flushed = 0, changed = 1;
vn_trace_entry(BHV_TO_VNODE(bdp),
__FUNCTION__, (inst_t *)__return_address);
@@ -1171,10 +1126,18 @@ xfs_fsync(
xfs_iunlock(ip, XFS_ILOCK_SHARED);
if (xfs_ipincount(ip)) {
- xfs_log_force(ip->i_mount, (xfs_lsn_t)0,
+ _xfs_log_force(ip->i_mount, (xfs_lsn_t)0,
XFS_LOG_FORCE |
((flag & FSYNC_WAIT)
- ? XFS_LOG_SYNC : 0));
+ ? XFS_LOG_SYNC : 0),
+ &log_flushed);
+ } else {
+ /*
+ * If the inode is not pinned and nothing
+ * has changed we don't need to flush the
+ * cache.
+ */
+ changed = 0;
}
error = 0;
} else {
@@ -1210,10 +1173,27 @@ xfs_fsync(
xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
if (flag & FSYNC_WAIT)
xfs_trans_set_sync(tp);
- error = xfs_trans_commit(tp, 0, NULL);
+ error = _xfs_trans_commit(tp, 0, NULL, &log_flushed);
xfs_iunlock(ip, XFS_ILOCK_EXCL);
}
+
+ if ((ip->i_mount->m_flags & XFS_MOUNT_BARRIER) && changed) {
+ /*
+ * If the log write didn't issue an ordered tag we need
+ * to flush the disk cache for the data device now.
+ */
+ if (!log_flushed)
+ xfs_blkdev_issue_flush(ip->i_mount->m_ddev_targp);
+
+ /*
+ * If this inode is on the RT dev we need to flush that
+ * cache aswell.
+ */
+ if (ip->i_d.di_flags & XFS_DIFLAG_REALTIME)
+ xfs_blkdev_issue_flush(ip->i_mount->m_rtdev_targp);
+ }
+
return error;
}
diff --git a/include/asm-alpha/barrier.h b/include/asm-alpha/barrier.h
index 229c83fe77cb..681ff581afa5 100644
--- a/include/asm-alpha/barrier.h
+++ b/include/asm-alpha/barrier.h
@@ -1,6 +1,8 @@
#ifndef __BARRIER_H
#define __BARRIER_H
+#include <asm/compiler.h>
+
#define mb() \
__asm__ __volatile__("mb": : :"memory")
diff --git a/include/asm-alpha/dma-mapping.h b/include/asm-alpha/dma-mapping.h
index c675f282d6ad..680f7ecbb28f 100644
--- a/include/asm-alpha/dma-mapping.h
+++ b/include/asm-alpha/dma-mapping.h
@@ -31,7 +31,7 @@
#else /* no PCI - no IOMMU. */
void *dma_alloc_coherent(struct device *dev, size_t size,
- dma_addr_t *dma_handle, int gfp);
+ dma_addr_t *dma_handle, gfp_t gfp);
int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
enum dma_data_direction direction);
diff --git a/include/asm-alpha/ide.h b/include/asm-alpha/ide.h
index 68934a25931f..6126afe27380 100644
--- a/include/asm-alpha/ide.h
+++ b/include/asm-alpha/ide.h
@@ -15,10 +15,6 @@
#include <linux/config.h>
-#ifndef MAX_HWIFS
-#define MAX_HWIFS CONFIG_IDE_MAX_HWIFS
-#endif
-
#define IDE_ARCH_OBSOLETE_DEFAULTS
static inline int ide_default_irq(unsigned long base)
diff --git a/include/asm-alpha/pgtable.h b/include/asm-alpha/pgtable.h
index 8393bf374b2b..a985cd29b6db 100644
--- a/include/asm-alpha/pgtable.h
+++ b/include/asm-alpha/pgtable.h
@@ -17,6 +17,9 @@
#include <asm/processor.h> /* For TASK_SIZE */
#include <asm/machvec.h>
+struct mm_struct;
+struct vm_area_struct;
+
/* Certain architectures need to do special things when PTEs
* within a page table are directly modified. Thus, the following
* hook is made available.
diff --git a/include/asm-alpha/ptrace.h b/include/asm-alpha/ptrace.h
index d462c5e14c13..072375c135b4 100644
--- a/include/asm-alpha/ptrace.h
+++ b/include/asm-alpha/ptrace.h
@@ -67,6 +67,9 @@ struct switch_stack {
};
#ifdef __KERNEL__
+
+#define __ARCH_SYS_PTRACE 1
+
#define user_mode(regs) (((regs)->ps & 8) != 0)
#define instruction_pointer(regs) ((regs)->pc)
#define profile_pc(regs) instruction_pointer(regs)
diff --git a/include/asm-alpha/rwsem.h b/include/asm-alpha/rwsem.h
index 8e058a67c9a4..fafdd4f7010a 100644
--- a/include/asm-alpha/rwsem.h
+++ b/include/asm-alpha/rwsem.h
@@ -262,5 +262,10 @@ static inline long rwsem_atomic_update(long val, struct rw_semaphore *sem)
#endif
}
+static inline int rwsem_is_locked(struct rw_semaphore *sem)
+{
+ return (sem->count != 0);
+}
+
#endif /* __KERNEL__ */
#endif /* _ALPHA_RWSEM_H */
diff --git a/include/asm-alpha/semaphore.h b/include/asm-alpha/semaphore.h
index eb2cbd97d404..1a6295f2c2d4 100644
--- a/include/asm-alpha/semaphore.h
+++ b/include/asm-alpha/semaphore.h
@@ -26,9 +26,6 @@ struct semaphore {
.wait = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait), \
}
-#define __MUTEX_INITIALIZER(name) \
- __SEMAPHORE_INITIALIZER(name,1)
-
#define __DECLARE_SEMAPHORE_GENERIC(name,count) \
struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
diff --git a/include/asm-arm/arch-aaec2000/aaec2000.h b/include/asm-arm/arch-aaec2000/aaec2000.h
index 0e9b7e18af05..002227924b9f 100644
--- a/include/asm-arm/arch-aaec2000/aaec2000.h
+++ b/include/asm-arm/arch-aaec2000/aaec2000.h
@@ -17,6 +17,16 @@
#error You must include hardware.h not this file
#endif /* __ASM_ARCH_HARDWARE_H */
+/* Chip selects */
+#define AAEC_CS0 0x00000000
+#define AAEC_CS1 0x10000000
+#define AAEC_CS2 0x20000000
+#define AAEC_CS3 0x30000000
+
+/* Flash */
+#define AAEC_FLASH_BASE AAEC_CS0
+#define AAEC_FLASH_SIZE SZ_64M
+
/* Interrupt controller */
#define IRQ_BASE __REG(0x80000500)
#define IRQ_INTSR __REG(0x80000500) /* Int Status Register */
@@ -148,4 +158,50 @@
#define POWER_STFCLR __REG(0x8000041c) /* NbFlg, RSTFlg, PFFlg, CLDFlg Clear */
#define POWER_CLKSET __REG(0x80000420) /* Clock Speed Control */
+/* GPIO Registers */
+#define AAEC_GPIO_PHYS 0x80000e00
+
+#define AAEC_GPIO_PADR __REG(AAEC_GPIO_PHYS + 0x00)
+#define AAEC_GPIO_PBDR __REG(AAEC_GPIO_PHYS + 0x04)
+#define AAEC_GPIO_PCDR __REG(AAEC_GPIO_PHYS + 0x08)
+#define AAEC_GPIO_PDDR __REG(AAEC_GPIO_PHYS + 0x0c)
+#define AAEC_GPIO_PADDR __REG(AAEC_GPIO_PHYS + 0x10)
+#define AAEC_GPIO_PBDDR __REG(AAEC_GPIO_PHYS + 0x14)
+#define AAEC_GPIO_PCDDR __REG(AAEC_GPIO_PHYS + 0x18)
+#define AAEC_GPIO_PDDDR __REG(AAEC_GPIO_PHYS + 0x1c)
+#define AAEC_GPIO_PEDR __REG(AAEC_GPIO_PHYS + 0x20)
+#define AAEC_GPIO_PEDDR __REG(AAEC_GPIO_PHYS + 0x24)
+#define AAEC_GPIO_KSCAN __REG(AAEC_GPIO_PHYS + 0x28)
+#define AAEC_GPIO_PINMUX __REG(AAEC_GPIO_PHYS + 0x2c)
+#define AAEC_GPIO_PFDR __REG(AAEC_GPIO_PHYS + 0x30)
+#define AAEC_GPIO_PFDDR __REG(AAEC_GPIO_PHYS + 0x34)
+#define AAEC_GPIO_PGDR __REG(AAEC_GPIO_PHYS + 0x38)
+#define AAEC_GPIO_PGDDR __REG(AAEC_GPIO_PHYS + 0x3c)
+#define AAEC_GPIO_PHDR __REG(AAEC_GPIO_PHYS + 0x40)
+#define AAEC_GPIO_PHDDR __REG(AAEC_GPIO_PHYS + 0x44)
+#define AAEC_GPIO_RAZ __REG(AAEC_GPIO_PHYS + 0x48)
+#define AAEC_GPIO_INTTYPE1 __REG(AAEC_GPIO_PHYS + 0x4c)
+#define AAEC_GPIO_INTTYPE2 __REG(AAEC_GPIO_PHYS + 0x50)
+#define AAEC_GPIO_FEOI __REG(AAEC_GPIO_PHYS + 0x54)
+#define AAEC_GPIO_INTEN __REG(AAEC_GPIO_PHYS + 0x58)
+#define AAEC_GPIO_INTSTATUS __REG(AAEC_GPIO_PHYS + 0x5c)
+#define AAEC_GPIO_RAWINTSTATUS __REG(AAEC_GPIO_PHYS + 0x60)
+#define AAEC_GPIO_DB __REG(AAEC_GPIO_PHYS + 0x64)
+#define AAEC_GPIO_PAPINDR __REG(AAEC_GPIO_PHYS + 0x68)
+#define AAEC_GPIO_PBPINDR __REG(AAEC_GPIO_PHYS + 0x6c)
+#define AAEC_GPIO_PCPINDR __REG(AAEC_GPIO_PHYS + 0x70)
+#define AAEC_GPIO_PDPINDR __REG(AAEC_GPIO_PHYS + 0x74)
+#define AAEC_GPIO_PEPINDR __REG(AAEC_GPIO_PHYS + 0x78)
+#define AAEC_GPIO_PFPINDR __REG(AAEC_GPIO_PHYS + 0x7c)
+#define AAEC_GPIO_PGPINDR __REG(AAEC_GPIO_PHYS + 0x80)
+#define AAEC_GPIO_PHPINDR __REG(AAEC_GPIO_PHYS + 0x84)
+
+#define AAEC_GPIO_PINMUX_PE0CON (1 << 0)
+#define AAEC_GPIO_PINMUX_PD0CON (1 << 1)
+#define AAEC_GPIO_PINMUX_CODECON (1 << 2)
+#define AAEC_GPIO_PINMUX_UART3CON (1 << 3)
+
+/* LCD Controller */
+#define AAEC_CLCD_PHYS 0x80003000
+
#endif /* __ARM_ARCH_AAEC2000_H */
diff --git a/include/asm-arm/arch-aaec2000/aaed2000.h b/include/asm-arm/arch-aaec2000/aaed2000.h
new file mode 100644
index 000000000000..bc76d2badb91
--- /dev/null
+++ b/include/asm-arm/arch-aaec2000/aaed2000.h
@@ -0,0 +1,40 @@
+/*
+ * linux/include/asm-arm/arch-aaec2000/aaed2000.h
+ *
+ * AAED-2000 specific bits definition
+ *
+ * Copyright (c) 2005 Nicolas Bellido Y Ortega
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ASM_ARCH_AAED2000_H
+#define __ASM_ARCH_AAED2000_H
+
+/* External GPIOs. */
+
+#define EXT_GPIO_PBASE AAEC_CS3
+#define EXT_GPIO_VBASE 0xf8100000
+#define EXT_GPIO_LENGTH 0x00001000
+
+#define __ext_gpio_p2v(x) ((x) - EXT_GPIO_PBASE + EXT_GPIO_VBASE)
+#define __ext_gpio_v2p(x) ((x) + EXT_GPIO_PBASE - EXT_GPIO_VBASE)
+
+#define __EXT_GPIO_REG(x) (*((volatile u32 *)__ext_gpio_p2v(x)))
+#define __EXT_GPIO_PREG(x) (__ext_gpio_v2p((u32)&(x)))
+
+#define AAED_EXT_GPIO __EXT_GPIO_REG(EXT_GPIO_PBASE)
+
+#define AAED_EGPIO_KBD_SCAN 0x00003fff /* Keyboard scan data */
+#define AAED_EGPIO_PWR_INT 0x00008fff /* Smart battery charger interrupt */
+#define AAED_EGPIO_SWITCHED 0x000f0000 /* DIP Switches */
+#define AAED_EGPIO_USB_VBUS 0x00400000 /* USB Vbus sense */
+#define AAED_EGPIO_LCD_PWR_EN 0x02000000 /* LCD and backlight PWR enable */
+#define AAED_EGPIO_nLED0 0x20000000 /* LED 0 */
+#define AAED_EGPIO_nLED1 0x20000000 /* LED 1 */
+#define AAED_EGPIO_nLED2 0x20000000 /* LED 2 */
+
+
+#endif /* __ARM_ARCH_AAED2000_H */
diff --git a/include/asm-arm/arch-aaec2000/hardware.h b/include/asm-arm/arch-aaec2000/hardware.h
index 4c37219e030e..153506fd06ed 100644
--- a/include/asm-arm/arch-aaec2000/hardware.h
+++ b/include/asm-arm/arch-aaec2000/hardware.h
@@ -11,7 +11,8 @@
#ifndef __ASM_ARCH_HARDWARE_H
#define __ASM_ARCH_HARDWARE_H
-#include <linux/config.h>
+#include <asm/sizes.h>
+#include <asm/arch/aaec2000.h>
/* The kernel is loaded at physical address 0xf8000000.
* We map the IO space a bit after
diff --git a/include/asm-arm/arch-aaec2000/io.h b/include/asm-arm/arch-aaec2000/io.h
index c58a8d10425a..8d67907fd4f0 100644
--- a/include/asm-arm/arch-aaec2000/io.h
+++ b/include/asm-arm/arch-aaec2000/io.h
@@ -6,6 +6,8 @@
#ifndef __ASM_ARM_ARCH_IO_H
#define __ASM_ARM_ARCH_IO_H
+#include <asm/hardware.h>
+
#define IO_SPACE_LIMIT 0xffffffff
/*
diff --git a/include/asm-arm/arch-aaec2000/memory.h b/include/asm-arm/arch-aaec2000/memory.h
index 79c90813bc3e..d8209f8911d6 100644
--- a/include/asm-arm/arch-aaec2000/memory.h
+++ b/include/asm-arm/arch-aaec2000/memory.h
@@ -13,7 +13,7 @@
#include <linux/config.h>
-#define PHYS_OFFSET (0xf0000000UL)
+#define PHYS_OFFSET UL(0xf0000000)
#define __virt_to_bus(x) __virt_to_phys(x)
#define __bus_to_virt(x) __phys_to_virt(x)
diff --git a/include/asm-arm/arch-cl7500/io.h b/include/asm-arm/arch-cl7500/io.h
index f0113bc75630..89a33287f4fe 100644
--- a/include/asm-arm/arch-cl7500/io.h
+++ b/include/asm-arm/arch-cl7500/io.h
@@ -10,6 +10,8 @@
#ifndef __ASM_ARM_ARCH_IO_H
#define __ASM_ARM_ARCH_IO_H
+#include <asm/hardware.h>
+
#define IO_SPACE_LIMIT 0xffffffff
/*
diff --git a/include/asm-arm/arch-cl7500/memory.h b/include/asm-arm/arch-cl7500/memory.h
index 9776bba8e585..34f40a6cec30 100644
--- a/include/asm-arm/arch-cl7500/memory.h
+++ b/include/asm-arm/arch-cl7500/memory.h
@@ -17,7 +17,7 @@
/*
* Physical DRAM offset.
*/
-#define PHYS_OFFSET (0x10000000UL)
+#define PHYS_OFFSET UL(0x10000000)
/*
* These are exactly the same on the RiscPC as the
diff --git a/include/asm-arm/arch-clps711x/io.h b/include/asm-arm/arch-clps711x/io.h
index 14d7e8da5453..62613b0e2d96 100644
--- a/include/asm-arm/arch-clps711x/io.h
+++ b/include/asm-arm/arch-clps711x/io.h
@@ -20,6 +20,8 @@
#ifndef __ASM_ARM_ARCH_IO_H
#define __ASM_ARM_ARCH_IO_H
+#include <asm/hardware.h>
+
#define IO_SPACE_LIMIT 0xffffffff
#define __io(a) ((void __iomem *)(a))
diff --git a/include/asm-arm/arch-clps711x/memory.h b/include/asm-arm/arch-clps711x/memory.h
index bd978947db42..61d8717406ce 100644
--- a/include/asm-arm/arch-clps711x/memory.h
+++ b/include/asm-arm/arch-clps711x/memory.h
@@ -25,7 +25,7 @@
/*
* Physical DRAM offset.
*/
-#define PHYS_OFFSET (0xc0000000UL)
+#define PHYS_OFFSET UL(0xc0000000)
/*
* Virtual view <-> DMA view memory address translations
diff --git a/include/asm-arm/arch-ebsa110/memory.h b/include/asm-arm/arch-ebsa110/memory.h
index 5a9493e12275..02f144520c10 100644
--- a/include/asm-arm/arch-ebsa110/memory.h
+++ b/include/asm-arm/arch-ebsa110/memory.h
@@ -19,7 +19,7 @@
/*
* Physical DRAM offset.
*/
-#define PHYS_OFFSET (0x00000000UL)
+#define PHYS_OFFSET UL(0x00000000)
/*
* We keep this 1:1 so that we don't interfere
diff --git a/include/asm-arm/arch-ebsa285/io.h b/include/asm-arm/arch-ebsa285/io.h
index 70576b17f922..776f9d377057 100644
--- a/include/asm-arm/arch-ebsa285/io.h
+++ b/include/asm-arm/arch-ebsa285/io.h
@@ -14,6 +14,8 @@
#ifndef __ASM_ARM_ARCH_IO_H
#define __ASM_ARM_ARCH_IO_H
+#include <asm/hardware.h>
+
#define IO_SPACE_LIMIT 0xffff
/*
diff --git a/include/asm-arm/arch-ebsa285/memory.h b/include/asm-arm/arch-ebsa285/memory.h
index d0466f9987d3..09e335cd687d 100644
--- a/include/asm-arm/arch-ebsa285/memory.h
+++ b/include/asm-arm/arch-ebsa285/memory.h
@@ -46,14 +46,14 @@ extern unsigned long __bus_to_virt(unsigned long);
#if defined(CONFIG_ARCH_FOOTBRIDGE)
/* Task size and page offset at 3GB */
-#define TASK_SIZE (0xbf000000UL)
-#define PAGE_OFFSET (0xc0000000UL)
+#define TASK_SIZE UL(0xbf000000)
+#define PAGE_OFFSET UL(0xc0000000)
#elif defined(CONFIG_ARCH_CO285)
/* Task size and page offset at 1.5GB */
-#define TASK_SIZE (0x5f000000UL)
-#define PAGE_OFFSET (0x60000000UL)
+#define TASK_SIZE UL(0x5f000000)
+#define PAGE_OFFSET UL(0x60000000)
#else
@@ -64,7 +64,7 @@ extern unsigned long __bus_to_virt(unsigned long);
/*
* Physical DRAM offset.
*/
-#define PHYS_OFFSET (0x00000000UL)
+#define PHYS_OFFSET UL(0x00000000)
/*
* This decides where the kernel will search for a free chunk of vm
diff --git a/include/asm-arm/arch-epxa10db/io.h b/include/asm-arm/arch-epxa10db/io.h
index 1f0afa257621..9fe100c9d6be 100644
--- a/include/asm-arm/arch-epxa10db/io.h
+++ b/include/asm-arm/arch-epxa10db/io.h
@@ -20,6 +20,8 @@
#ifndef __ASM_ARM_ARCH_IO_H
#define __ASM_ARM_ARCH_IO_H
+#include <asm/hardware.h>
+
#define IO_SPACE_LIMIT 0xffff
diff --git a/include/asm-arm/arch-epxa10db/memory.h b/include/asm-arm/arch-epxa10db/memory.h
index 3f86bf7f67f0..999541b6a9f5 100644
--- a/include/asm-arm/arch-epxa10db/memory.h
+++ b/include/asm-arm/arch-epxa10db/memory.h
@@ -23,7 +23,7 @@
/*
* Physical DRAM offset.
*/
-#define PHYS_OFFSET (0x00000000UL)
+#define PHYS_OFFSET UL(0x00000000)
/*
* Virtual view <-> DMA view memory address translations
diff --git a/include/asm-arm/arch-h720x/io.h b/include/asm-arm/arch-h720x/io.h
index 68814828c9a7..d3ccfd8172b7 100644
--- a/include/asm-arm/arch-h720x/io.h
+++ b/include/asm-arm/arch-h720x/io.h
@@ -14,7 +14,7 @@
#ifndef __ASM_ARM_ARCH_IO_H
#define __ASM_ARM_ARCH_IO_H
-#include <asm/arch/hardware.h>
+#include <asm/hardware.h>
#define IO_SPACE_LIMIT 0xffffffff
diff --git a/include/asm-arm/arch-h720x/memory.h b/include/asm-arm/arch-h720x/memory.h
index 5633447af268..4a1bfd78a0fe 100644
--- a/include/asm-arm/arch-h720x/memory.h
+++ b/include/asm-arm/arch-h720x/memory.h
@@ -11,7 +11,7 @@
* Page offset:
* ( 0xc0000000UL )
*/
-#define PHYS_OFFSET (0x40000000UL)
+#define PHYS_OFFSET UL(0x40000000)
/*
* Virtual view <-> DMA view memory address translations
diff --git a/include/asm-arm/arch-imx/io.h b/include/asm-arm/arch-imx/io.h
index 28a4cca6a4cb..b191cdd05576 100644
--- a/include/asm-arm/arch-imx/io.h
+++ b/include/asm-arm/arch-imx/io.h
@@ -20,6 +20,8 @@
#ifndef __ASM_ARM_ARCH_IO_H
#define __ASM_ARM_ARCH_IO_H
+#include <asm/hardware.h>
+
#define IO_SPACE_LIMIT 0xffffffff
#define __io(a) ((void __iomem *)(a))
diff --git a/include/asm-arm/arch-imx/memory.h b/include/asm-arm/arch-imx/memory.h
index 116a91fa14f1..d09ae32cd2f4 100644
--- a/include/asm-arm/arch-imx/memory.h
+++ b/include/asm-arm/arch-imx/memory.h
@@ -21,7 +21,7 @@
#ifndef __ASM_ARCH_MMU_H
#define __ASM_ARCH_MMU_H
-#define PHYS_OFFSET (0x08000000UL)
+#define PHYS_OFFSET UL(0x08000000)
/*
* Virtual view <-> DMA view memory address translations
diff --git a/include/asm-arm/arch-integrator/hardware.h b/include/asm-arm/arch-integrator/hardware.h
index be2716eeaa02..6f0947bc500d 100644
--- a/include/asm-arm/arch-integrator/hardware.h
+++ b/include/asm-arm/arch-integrator/hardware.h
@@ -33,15 +33,6 @@
#define IO_SIZE 0x0B000000 // How much?
#define IO_START INTEGRATOR_HDR_BASE // PA of IO
-/*
- * Similar to above, but for PCI addresses (memory, IO, Config and the
- * V3 chip itself). WARNING: this has to mirror definitions in platform.h
- */
-#define PCI_MEMORY_VADDR 0xe8000000
-#define PCI_CONFIG_VADDR 0xec000000
-#define PCI_V3_VADDR 0xed000000
-#define PCI_IO_VADDR 0xee000000
-
#define PCIO_BASE PCI_IO_VADDR
#define PCIMEM_BASE PCI_MEMORY_VADDR
diff --git a/include/asm-arm/arch-integrator/io.h b/include/asm-arm/arch-integrator/io.h
index fbea8be67d26..31f2deab51b0 100644
--- a/include/asm-arm/arch-integrator/io.h
+++ b/include/asm-arm/arch-integrator/io.h
@@ -22,6 +22,14 @@
#define IO_SPACE_LIMIT 0xffff
+/*
+ * WARNING: this has to mirror definitions in platform.h
+ */
+#define PCI_MEMORY_VADDR 0xe8000000
+#define PCI_CONFIG_VADDR 0xec000000
+#define PCI_V3_VADDR 0xed000000
+#define PCI_IO_VADDR 0xee000000
+
#define __io(a) ((void __iomem *)(PCI_IO_VADDR + (a)))
#define __mem_pci(a) (a)
#define __mem_isa(a) ((a) + PCI_MEMORY_VADDR)
diff --git a/include/asm-arm/arch-integrator/memory.h b/include/asm-arm/arch-integrator/memory.h
index 2087ea7d28a9..1ab56d783e7c 100644
--- a/include/asm-arm/arch-integrator/memory.h
+++ b/include/asm-arm/arch-integrator/memory.h
@@ -23,8 +23,8 @@
/*
* Physical DRAM offset.
*/
-#define PHYS_OFFSET (0x00000000UL)
-#define BUS_OFFSET (0x80000000UL)
+#define PHYS_OFFSET UL(0x00000000)
+#define BUS_OFFSET UL(0x80000000)
/*
* Virtual view <-> DMA view memory address translations
diff --git a/include/asm-arm/arch-iop3xx/io.h b/include/asm-arm/arch-iop3xx/io.h
index 2761dfd8694d..f39046a6ab14 100644
--- a/include/asm-arm/arch-iop3xx/io.h
+++ b/include/asm-arm/arch-iop3xx/io.h
@@ -11,6 +11,8 @@
#ifndef __ASM_ARM_ARCH_IO_H
#define __ASM_ARM_ARCH_IO_H
+#include <asm/hardware.h>
+
#define IO_SPACE_LIMIT 0xffffffff
#define __io(p) ((void __iomem *)(p))
diff --git a/include/asm-arm/arch-iop3xx/iop321.h b/include/asm-arm/arch-iop3xx/iop321.h
index 200621ff3690..f8df778a356f 100644
--- a/include/asm-arm/arch-iop3xx/iop321.h
+++ b/include/asm-arm/arch-iop3xx/iop321.h
@@ -40,7 +40,7 @@
#define IOP321_PCI_UPPER_IO_BA (IOP321_PCI_LOWER_IO_BA + IOP321_PCI_IO_WINDOW_SIZE - 1)
#define IOP321_PCI_IO_OFFSET (IOP321_PCI_LOWER_IO_VA - IOP321_PCI_LOWER_IO_BA)
-//#define IOP321_PCI_MEM_WINDOW_SIZE (~*IOP321_IALR1 + 1)
+/* #define IOP321_PCI_MEM_WINDOW_SIZE (~*IOP321_IALR1 + 1) */
#define IOP321_PCI_MEM_WINDOW_SIZE 0x04000000 /* 64M outbound window */
#define IOP321_PCI_LOWER_MEM_PA 0x80000000
#define IOP321_PCI_LOWER_MEM_BA (*IOP321_OMWTVR0)
diff --git a/include/asm-arm/arch-iop3xx/iop331.h b/include/asm-arm/arch-iop3xx/iop331.h
index 96adffd8bad2..fbf0cc11bdd9 100644
--- a/include/asm-arm/arch-iop3xx/iop331.h
+++ b/include/asm-arm/arch-iop3xx/iop331.h
@@ -42,7 +42,7 @@
/* this can be 128M if OMWTVR1 is set */
#define IOP331_PCI_MEM_WINDOW_SIZE 0x04000000 /* 64M outbound window */
-//#define IOP331_PCI_MEM_WINDOW_SIZE (~*IOP331_IALR1 + 1)
+/* #define IOP331_PCI_MEM_WINDOW_SIZE (~*IOP331_IALR1 + 1) */
#define IOP331_PCI_LOWER_MEM_PA 0x80000000
#define IOP331_PCI_LOWER_MEM_BA (*IOP331_OMWTVR0)
#define IOP331_PCI_UPPER_MEM_PA (IOP331_PCI_LOWER_MEM_PA + IOP331_PCI_MEM_WINDOW_SIZE - 1)
diff --git a/include/asm-arm/arch-iop3xx/memory.h b/include/asm-arm/arch-iop3xx/memory.h
index 45351f5cd904..bc62f4b13235 100644
--- a/include/asm-arm/arch-iop3xx/memory.h
+++ b/include/asm-arm/arch-iop3xx/memory.h
@@ -12,9 +12,9 @@
* Physical DRAM offset.
*/
#ifndef CONFIG_ARCH_IOP331
-#define PHYS_OFFSET (0xa0000000UL)
+#define PHYS_OFFSET UL(0xa0000000)
#else
-#define PHYS_OFFSET (0x00000000UL)
+#define PHYS_OFFSET UL(0x00000000)
#endif
/*
diff --git a/include/asm-arm/arch-ixp2000/enp2611.h b/include/asm-arm/arch-ixp2000/enp2611.h
index 31ae88674968..95128d9f5026 100644
--- a/include/asm-arm/arch-ixp2000/enp2611.h
+++ b/include/asm-arm/arch-ixp2000/enp2611.h
@@ -21,8 +21,20 @@
#ifndef __ENP2611_H
#define __ENP2611_H
-#define ENP2611_GPIO_SCL 0x07
-#define ENP2611_GPIO_SDA 0x06
+#define ENP2611_CALEB_PHYS_BASE 0xc5000000
+#define ENP2611_CALEB_VIRT_BASE 0xfe000000
+#define ENP2611_CALEB_SIZE 0x00100000
+
+#define ENP2611_PM3386_0_PHYS_BASE 0xc6000000
+#define ENP2611_PM3386_0_VIRT_BASE 0xfe100000
+#define ENP2611_PM3386_0_SIZE 0x00100000
+
+#define ENP2611_PM3386_1_PHYS_BASE 0xc6400000
+#define ENP2611_PM3386_1_VIRT_BASE 0xfe200000
+#define ENP2611_PM3386_1_SIZE 0x00100000
+
+#define ENP2611_GPIO_SCL 7
+#define ENP2611_GPIO_SDA 6
#endif
diff --git a/include/asm-arm/arch-ixp2000/io.h b/include/asm-arm/arch-ixp2000/io.h
index 3241cd6f0778..7fbcdf9931ee 100644
--- a/include/asm-arm/arch-ixp2000/io.h
+++ b/include/asm-arm/arch-ixp2000/io.h
@@ -15,6 +15,8 @@
#ifndef __ASM_ARM_ARCH_IO_H
#define __ASM_ARM_ARCH_IO_H
+#include <asm/hardware.h>
+
#define IO_SPACE_LIMIT 0xffffffff
#define __mem_pci(a) (a)
diff --git a/include/asm-arm/arch-ixp2000/irqs.h b/include/asm-arm/arch-ixp2000/irqs.h
index 0deb96c12adb..62f09c7ff420 100644
--- a/include/asm-arm/arch-ixp2000/irqs.h
+++ b/include/asm-arm/arch-ixp2000/irqs.h
@@ -67,12 +67,45 @@
#define IRQ_IXP2000_PCIA 40
#define IRQ_IXP2000_PCIB 41
-#define NR_IXP2000_IRQS 42
+/* Int sources from IRQ_ERROR_STATUS */
+#define IRQ_IXP2000_DRAM0_MIN_ERR 42
+#define IRQ_IXP2000_DRAM0_MAJ_ERR 43
+#define IRQ_IXP2000_DRAM1_MIN_ERR 44
+#define IRQ_IXP2000_DRAM1_MAJ_ERR 45
+#define IRQ_IXP2000_DRAM2_MIN_ERR 46
+#define IRQ_IXP2000_DRAM2_MAJ_ERR 47
+/* 48-57 reserved */
+#define IRQ_IXP2000_SRAM0_ERR 58
+#define IRQ_IXP2000_SRAM1_ERR 59
+#define IRQ_IXP2000_SRAM2_ERR 60
+#define IRQ_IXP2000_SRAM3_ERR 61
+/* 62-65 reserved */
+#define IRQ_IXP2000_MEDIA_ERR 66
+#define IRQ_IXP2000_PCI_ERR 67
+#define IRQ_IXP2000_SP_INT 68
+
+#define NR_IXP2000_IRQS 69
#define IXP2000_BOARD_IRQ(x) (NR_IXP2000_IRQS + (x))
#define IXP2000_BOARD_IRQ_MASK(irq) (1 << (irq - NR_IXP2000_IRQS))
+#define IXP2000_ERR_IRQ_MASK(irq) ( 1 << (irq - IRQ_IXP2000_DRAM0_MIN_ERR))
+#define IXP2000_VALID_ERR_IRQ_MASK (\
+ IXP2000_ERR_IRQ_MASK(IRQ_IXP2000_DRAM0_MIN_ERR) | \
+ IXP2000_ERR_IRQ_MASK(IRQ_IXP2000_DRAM0_MAJ_ERR) | \
+ IXP2000_ERR_IRQ_MASK(IRQ_IXP2000_DRAM1_MIN_ERR) | \
+ IXP2000_ERR_IRQ_MASK(IRQ_IXP2000_DRAM1_MAJ_ERR) | \
+ IXP2000_ERR_IRQ_MASK(IRQ_IXP2000_DRAM2_MIN_ERR) | \
+ IXP2000_ERR_IRQ_MASK(IRQ_IXP2000_DRAM2_MAJ_ERR) | \
+ IXP2000_ERR_IRQ_MASK(IRQ_IXP2000_SRAM0_ERR) | \
+ IXP2000_ERR_IRQ_MASK(IRQ_IXP2000_SRAM1_ERR) | \
+ IXP2000_ERR_IRQ_MASK(IRQ_IXP2000_SRAM2_ERR) | \
+ IXP2000_ERR_IRQ_MASK(IRQ_IXP2000_SRAM3_ERR) | \
+ IXP2000_ERR_IRQ_MASK(IRQ_IXP2000_MEDIA_ERR) | \
+ IXP2000_ERR_IRQ_MASK(IRQ_IXP2000_PCI_ERR) | \
+ IXP2000_ERR_IRQ_MASK(IRQ_IXP2000_SP_INT) )
+
/*
* This allows for all the on-chip sources plus up to 32 CPLD based
* IRQs. Should be more than enough.
diff --git a/include/asm-arm/arch-ixp2000/ixdp2x01.h b/include/asm-arm/arch-ixp2000/ixdp2x01.h
index b768009c3a51..c6d51426e98f 100644
--- a/include/asm-arm/arch-ixp2000/ixdp2x01.h
+++ b/include/asm-arm/arch-ixp2000/ixdp2x01.h
@@ -22,7 +22,7 @@
#define IXDP2X01_CPLD_REGION_SIZE 0x00100000
#define IXDP2X01_CPLD_VIRT_REG(reg) (volatile unsigned long*)(IXDP2X01_VIRT_CPLD_BASE | reg)
-#define IXDP2X01_CPLD_PHYS_REG(reg) (volatile u32*)(IXDP2X01_PHYS_CPLD_BASE | reg)
+#define IXDP2X01_CPLD_PHYS_REG(reg) (IXDP2X01_PHYS_CPLD_BASE | reg)
#define IXDP2X01_UART1_VIRT_BASE IXDP2X01_CPLD_VIRT_REG(0x40)
#define IXDP2X01_UART1_PHYS_BASE IXDP2X01_CPLD_PHYS_REG(0x40)
diff --git a/include/asm-arm/arch-ixp2000/ixp2000-regs.h b/include/asm-arm/arch-ixp2000/ixp2000-regs.h
index 32aece069869..fc5ac6aec4f2 100644
--- a/include/asm-arm/arch-ixp2000/ixp2000-regs.h
+++ b/include/asm-arm/arch-ixp2000/ixp2000-regs.h
@@ -59,14 +59,15 @@
#define IXP2000_CAP_SIZE 0x00100000
/*
- * Addresses for specific on-chip peripherals
+ * Addresses for specific on-chip peripherals.
*/
#define IXP2000_SLOWPORT_CSR_VIRT_BASE 0xfef80000
#define IXP2000_GLOBAL_REG_VIRT_BASE 0xfef04000
#define IXP2000_UART_PHYS_BASE 0xc0030000
#define IXP2000_UART_VIRT_BASE 0xfef30000
#define IXP2000_TIMER_VIRT_BASE 0xfef20000
-#define IXP2000_GPIO_VIRT_BASE 0Xfef10000
+#define IXP2000_UENGINE_CSR_VIRT_BASE 0xfef18000
+#define IXP2000_GPIO_VIRT_BASE 0xfef10000
/*
* Devices outside of the 0xc0000000 -> 0xc0100000 range. The virtual
@@ -252,7 +253,7 @@
#define IXP2000_PCI_XSCALE_INT_ENABLE IXP2000_PCI_CSR(0x15C)
#define IXP2000_PCICNTL_PNR (1<<17) /* PCI not Reset bit of PCI_CONTROL */
-#define IXP2000_PCICNTL_PCF (1<<28) /* PCI Centrolfunction bit */
+#define IXP2000_PCICNTL_PCF (1<<28) /* PCI Central function bit */
#define IXP2000_XSCALE_INT (1<<1) /* Interrupt from XScale to PCI */
/* These are from the IRQ register in the PCI ISR register */
@@ -392,4 +393,47 @@
#define WDT_RESET_ENABLE 0x01000000
+/*
+ * MSF registers. The IXP2400 and IXP2800 have somewhat different MSF
+ * units, but the registers that differ between the two don't overlap,
+ * so we can have one register list for both.
+ */
+#define IXP2000_MSF_REG(x) ((volatile unsigned long*)(IXP2000_MSF_VIRT_BASE + (x)))
+#define IXP2000_MSF_RX_CONTROL IXP2000_MSF_REG(0x0000)
+#define IXP2000_MSF_TX_CONTROL IXP2000_MSF_REG(0x0004)
+#define IXP2000_MSF_INTERRUPT_STATUS IXP2000_MSF_REG(0x0008)
+#define IXP2000_MSF_INTERRUPT_ENABLE IXP2000_MSF_REG(0x000c)
+#define IXP2000_MSF_CSIX_TYPE_MAP IXP2000_MSF_REG(0x0010)
+#define IXP2000_MSF_FC_EGRESS_STATUS IXP2000_MSF_REG(0x0014)
+#define IXP2000_MSF_FC_INGRESS_STATUS IXP2000_MSF_REG(0x0018)
+#define IXP2000_MSF_HWM_CONTROL IXP2000_MSF_REG(0x0024)
+#define IXP2000_MSF_FC_STATUS_OVERRIDE IXP2000_MSF_REG(0x0028)
+#define IXP2000_MSF_CLOCK_CONTROL IXP2000_MSF_REG(0x002c)
+#define IXP2000_MSF_RX_PORT_MAP IXP2000_MSF_REG(0x0040)
+#define IXP2000_MSF_RBUF_ELEMENT_DONE IXP2000_MSF_REG(0x0044)
+#define IXP2000_MSF_RX_MPHY_POLL_LIMIT IXP2000_MSF_REG(0x0048)
+#define IXP2000_MSF_RX_CALENDAR_LENGTH IXP2000_MSF_REG(0x0048)
+#define IXP2000_MSF_RX_THREAD_FREELIST_TIMEOUT_0 IXP2000_MSF_REG(0x0050)
+#define IXP2000_MSF_RX_THREAD_FREELIST_TIMEOUT_1 IXP2000_MSF_REG(0x0054)
+#define IXP2000_MSF_RX_THREAD_FREELIST_TIMEOUT_2 IXP2000_MSF_REG(0x0058)
+#define IXP2000_MSF_TX_SEQUENCE_0 IXP2000_MSF_REG(0x0060)
+#define IXP2000_MSF_TX_SEQUENCE_1 IXP2000_MSF_REG(0x0064)
+#define IXP2000_MSF_TX_SEQUENCE_2 IXP2000_MSF_REG(0x0068)
+#define IXP2000_MSF_TX_MPHY_POLL_LIMIT IXP2000_MSF_REG(0x0070)
+#define IXP2000_MSF_TX_CALENDAR_LENGTH IXP2000_MSF_REG(0x0070)
+#define IXP2000_MSF_RX_UP_CONTROL_0 IXP2000_MSF_REG(0x0080)
+#define IXP2000_MSF_RX_UP_CONTROL_1 IXP2000_MSF_REG(0x0084)
+#define IXP2000_MSF_RX_UP_CONTROL_2 IXP2000_MSF_REG(0x0088)
+#define IXP2000_MSF_RX_UP_CONTROL_3 IXP2000_MSF_REG(0x008c)
+#define IXP2000_MSF_TX_UP_CONTROL_0 IXP2000_MSF_REG(0x0090)
+#define IXP2000_MSF_TX_UP_CONTROL_1 IXP2000_MSF_REG(0x0094)
+#define IXP2000_MSF_TX_UP_CONTROL_2 IXP2000_MSF_REG(0x0098)
+#define IXP2000_MSF_TX_UP_CONTROL_3 IXP2000_MSF_REG(0x009c)
+#define IXP2000_MSF_TRAIN_DATA IXP2000_MSF_REG(0x00a0)
+#define IXP2000_MSF_TRAIN_CALENDAR IXP2000_MSF_REG(0x00a4)
+#define IXP2000_MSF_TRAIN_FLOW_CONTROL IXP2000_MSF_REG(0x00a8)
+#define IXP2000_MSF_TX_CALENDAR_0 IXP2000_MSF_REG(0x1000)
+#define IXP2000_MSF_RX_PORT_CALENDAR_STATUS IXP2000_MSF_REG(0x1400)
+
+
#endif /* _IXP2000_H_ */
diff --git a/include/asm-arm/arch-ixp2000/memory.h b/include/asm-arm/arch-ixp2000/memory.h
index d0f415c6dae9..21e1de51e3f6 100644
--- a/include/asm-arm/arch-ixp2000/memory.h
+++ b/include/asm-arm/arch-ixp2000/memory.h
@@ -13,7 +13,7 @@
#ifndef __ASM_ARCH_MEMORY_H
#define __ASM_ARCH_MEMORY_H
-#define PHYS_OFFSET (0x00000000UL)
+#define PHYS_OFFSET UL(0x00000000)
/*
* Virtual view <-> DMA view memory address translations
diff --git a/include/asm-arm/arch-ixp2000/platform.h b/include/asm-arm/arch-ixp2000/platform.h
index abdcf51bd283..a66317ab2071 100644
--- a/include/asm-arm/arch-ixp2000/platform.h
+++ b/include/asm-arm/arch-ixp2000/platform.h
@@ -15,40 +15,40 @@
#ifndef __ASSEMBLY__
+static inline unsigned long ixp2000_reg_read(volatile void *reg)
+{
+ return *((volatile unsigned long *)reg);
+}
+
+static inline void ixp2000_reg_write(volatile void *reg, unsigned long val)
+{
+ *((volatile unsigned long *)reg) = val;
+}
+
/*
- * The IXP2400 B0 silicon contains an erratum (#66) that causes writes
- * to on-chip I/O register to not complete fully. What this means is
- * that if you have a write to on-chip I/O followed by a back-to-back
- * read or write, the first write will happen twice. OR...if it's
- * not a back-to-back transaction, the read or write will generate
- * incorrect data.
- *
- * The official work around for this is to set the on-chip I/O regions
- * as XCB=101 and then force a read-back from the register.
+ * On the IXP2400, we can't use XCB=000 due to chip bugs. We use
+ * XCB=101 instead, but that makes all I/O accesses bufferable. This
+ * is not a problem in general, but we do have to be slightly more
+ * careful because I/O writes are no longer automatically flushed out
+ * of the write buffer.
*
+ * In cases where we want to make sure that a write has been flushed
+ * out of the write buffer before we proceed, for example when masking
+ * a device interrupt before re-enabling IRQs in CPSR, we can use this
+ * function, ixp2000_reg_wrb, which performs a write, a readback, and
+ * issues a dummy instruction dependent on the value of the readback
+ * (mov rX, rX) to make sure that the readback has completed before we
+ * continue.
*/
-#if defined(CONFIG_ARCH_ENP2611) || defined(CONFIG_ARCH_IXDP2400) || defined(CONFIG_ARCH_IXDP2401)
-
-#include <asm/system.h> /* Pickup local_irq_ functions */
-
-static inline void ixp2000_reg_write(volatile void *reg, unsigned long val)
+static inline void ixp2000_reg_wrb(volatile void *reg, unsigned long val)
{
unsigned long dummy;
- unsigned long flags;
- local_irq_save(flags);
*((volatile unsigned long *)reg) = val;
- barrier();
+
dummy = *((volatile unsigned long *)reg);
- local_irq_restore(flags);
-}
-#else
-static inline void ixp2000_reg_write(volatile void *reg, unsigned long val)
-{
- *((volatile unsigned long *)reg) = val;
+ __asm__ __volatile__("mov %0, %0" : "+r" (dummy));
}
-#endif /* IXDP2400 || IXDP2401 */
-#define ixp2000_reg_read(reg) (*((volatile unsigned long *)reg))
/*
* Boards may multiplex different devices on the 2nd channel of
diff --git a/include/asm-arm/arch-ixp2000/system.h b/include/asm-arm/arch-ixp2000/system.h
index 4f489cc0dfa5..ddbbb34b5f95 100644
--- a/include/asm-arm/arch-ixp2000/system.h
+++ b/include/asm-arm/arch-ixp2000/system.h
@@ -26,29 +26,24 @@ static inline void arch_reset(char mode)
* RedBoot bank.
*/
if (machine_is_ixdp2401()) {
- *IXDP2X01_CPLD_FLASH_REG = ((0 >> IXDP2X01_FLASH_WINDOW_BITS)
- | IXDP2X01_CPLD_FLASH_INTERN);
- *IXDP2X01_CPLD_RESET_REG = 0xffffffff;
+ ixp2000_reg_write(IXDP2X01_CPLD_FLASH_REG,
+ ((0 >> IXDP2X01_FLASH_WINDOW_BITS)
+ | IXDP2X01_CPLD_FLASH_INTERN));
+ ixp2000_reg_wrb(IXDP2X01_CPLD_RESET_REG, 0xffffffff);
}
/*
* On IXDP2801 we need to write this magic sequence to the CPLD
* to cause a complete reset of the CPU and all external devices
- * and moves the flash bank register back to 0.
+ * and move the flash bank register back to 0.
*/
if (machine_is_ixdp2801()) {
unsigned long reset_reg = *IXDP2X01_CPLD_RESET_REG;
+
reset_reg = 0x55AA0000 | (reset_reg & 0x0000FFFF);
- *IXDP2X01_CPLD_RESET_REG = reset_reg;
- mb();
- *IXDP2X01_CPLD_RESET_REG = 0x80000000;
+ ixp2000_reg_write(IXDP2X01_CPLD_RESET_REG, reset_reg);
+ ixp2000_reg_wrb(IXDP2X01_CPLD_RESET_REG, 0x80000000);
}
- /*
- * We do a reset all if we are PCI master. We could be a slave and we
- * don't want to do anything funky on the PCI bus.
- */
- if (*IXP2000_STRAP_OPTIONS & CFG_PCI_BOOT_HOST) {
- *(IXP2000_RESET0) |= (RSTALL);
- }
+ ixp2000_reg_wrb(IXP2000_RESET0, RSTALL);
}
diff --git a/include/asm-arm/arch-ixp2000/uengine.h b/include/asm-arm/arch-ixp2000/uengine.h
new file mode 100644
index 000000000000..b442d65c6593
--- /dev/null
+++ b/include/asm-arm/arch-ixp2000/uengine.h
@@ -0,0 +1,62 @@
+/*
+ * Generic library functions for the microengines found on the Intel
+ * IXP2000 series of network processors.
+ *
+ * Copyright (C) 2004, 2005 Lennert Buytenhek <buytenh@wantstofly.org>
+ * Dedicated to Marija Kulikova.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of the
+ * License, or (at your option) any later version.
+ */
+
+#ifndef __IXP2000_UENGINE_H
+#define __IXP2000_UENGINE_H
+
+extern u32 ixp2000_uengine_mask;
+
+struct ixp2000_uengine_code
+{
+ u32 cpu_model_bitmask;
+ u8 cpu_min_revision;
+ u8 cpu_max_revision;
+
+ u32 uengine_parameters;
+
+ struct ixp2000_reg_value {
+ int reg;
+ u32 value;
+ } *initial_reg_values;
+
+ int num_insns;
+ u8 *insns;
+};
+
+u32 ixp2000_uengine_csr_read(int uengine, int offset);
+void ixp2000_uengine_csr_write(int uengine, int offset, u32 value);
+void ixp2000_uengine_reset(u32 uengine_mask);
+void ixp2000_uengine_set_mode(int uengine, u32 mode);
+void ixp2000_uengine_load_microcode(int uengine, u8 *ucode, int insns);
+void ixp2000_uengine_init_context(int uengine, int context, int pc);
+void ixp2000_uengine_start_contexts(int uengine, u8 ctx_mask);
+void ixp2000_uengine_stop_contexts(int uengine, u8 ctx_mask);
+int ixp2000_uengine_load(int uengine, struct ixp2000_uengine_code *c);
+
+#define IXP2000_UENGINE_8_CONTEXTS 0x00000000
+#define IXP2000_UENGINE_4_CONTEXTS 0x80000000
+#define IXP2000_UENGINE_PRN_UPDATE_EVERY 0x40000000
+#define IXP2000_UENGINE_PRN_UPDATE_ON_ACCESS 0x00000000
+#define IXP2000_UENGINE_NN_FROM_SELF 0x00100000
+#define IXP2000_UENGINE_NN_FROM_PREVIOUS 0x00000000
+#define IXP2000_UENGINE_ASSERT_EMPTY_AT_3 0x000c0000
+#define IXP2000_UENGINE_ASSERT_EMPTY_AT_2 0x00080000
+#define IXP2000_UENGINE_ASSERT_EMPTY_AT_1 0x00040000
+#define IXP2000_UENGINE_ASSERT_EMPTY_AT_0 0x00000000
+#define IXP2000_UENGINE_LM_ADDR1_GLOBAL 0x00020000
+#define IXP2000_UENGINE_LM_ADDR1_PER_CONTEXT 0x00000000
+#define IXP2000_UENGINE_LM_ADDR0_GLOBAL 0x00010000
+#define IXP2000_UENGINE_LM_ADDR0_PER_CONTEXT 0x00000000
+
+
+#endif
diff --git a/include/asm-arm/arch-ixp4xx/hardware.h b/include/asm-arm/arch-ixp4xx/hardware.h
index 55d85eea8c1a..cfb413c845f7 100644
--- a/include/asm-arm/arch-ixp4xx/hardware.h
+++ b/include/asm-arm/arch-ixp4xx/hardware.h
@@ -44,5 +44,6 @@ extern unsigned int processor_id;
#include "ixdp425.h"
#include "coyote.h"
#include "prpmc1100.h"
+#include "nslu2.h"
#endif /* _ASM_ARCH_HARDWARE_H */
diff --git a/include/asm-arm/arch-ixp4xx/io.h b/include/asm-arm/arch-ixp4xx/io.h
index e350dcb544e8..688f7f90d93e 100644
--- a/include/asm-arm/arch-ixp4xx/io.h
+++ b/include/asm-arm/arch-ixp4xx/io.h
@@ -80,9 +80,9 @@ __ixp4xx_iounmap(void __iomem *addr)
#define __arch_ioremap(a, s, f, x) __ixp4xx_ioremap(a, s, f, x)
#define __arch_iounmap(a) __ixp4xx_iounmap(a)
-#define writeb(p, v) __ixp4xx_writeb(p, v)
-#define writew(p, v) __ixp4xx_writew(p, v)
-#define writel(p, v) __ixp4xx_writel(p, v)
+#define writeb(v, p) __ixp4xx_writeb(v, p)
+#define writew(v, p) __ixp4xx_writew(v, p)
+#define writel(v, p) __ixp4xx_writel(v, p)
#define writesb(p, v, l) __ixp4xx_writesb(p, v, l)
#define writesw(p, v, l) __ixp4xx_writesw(p, v, l)
@@ -97,8 +97,9 @@ __ixp4xx_iounmap(void __iomem *addr)
#define readsl(p, v, l) __ixp4xx_readsl(p, v, l)
static inline void
-__ixp4xx_writeb(u8 value, u32 addr)
+__ixp4xx_writeb(u8 value, volatile void __iomem *p)
{
+ u32 addr = (u32)p;
u32 n, byte_enables, data;
if (addr >= VMALLOC_START) {
@@ -113,15 +114,16 @@ __ixp4xx_writeb(u8 value, u32 addr)
}
static inline void
-__ixp4xx_writesb(u32 bus_addr, u8 *vaddr, int count)
+__ixp4xx_writesb(volatile void __iomem *bus_addr, const u8 *vaddr, int count)
{
while (count--)
writeb(*vaddr++, bus_addr);
}
static inline void
-__ixp4xx_writew(u16 value, u32 addr)
+__ixp4xx_writew(u16 value, volatile void __iomem *p)
{
+ u32 addr = (u32)p;
u32 n, byte_enables, data;
if (addr >= VMALLOC_START) {
@@ -136,15 +138,16 @@ __ixp4xx_writew(u16 value, u32 addr)
}
static inline void
-__ixp4xx_writesw(u32 bus_addr, u16 *vaddr, int count)
+__ixp4xx_writesw(volatile void __iomem *bus_addr, const u16 *vaddr, int count)
{
while (count--)
writew(*vaddr++, bus_addr);
}
static inline void
-__ixp4xx_writel(u32 value, u32 addr)
+__ixp4xx_writel(u32 value, volatile void __iomem *p)
{
+ u32 addr = (u32)p;
if (addr >= VMALLOC_START) {
__raw_writel(value, addr);
return;
@@ -154,15 +157,16 @@ __ixp4xx_writel(u32 value, u32 addr)
}
static inline void
-__ixp4xx_writesl(u32 bus_addr, u32 *vaddr, int count)
+__ixp4xx_writesl(volatile void __iomem *bus_addr, const u32 *vaddr, int count)
{
while (count--)
writel(*vaddr++, bus_addr);
}
static inline unsigned char
-__ixp4xx_readb(u32 addr)
+__ixp4xx_readb(const volatile void __iomem *p)
{
+ u32 addr = (u32)p;
u32 n, byte_enables, data;
if (addr >= VMALLOC_START)
@@ -177,15 +181,16 @@ __ixp4xx_readb(u32 addr)
}
static inline void
-__ixp4xx_readsb(u32 bus_addr, u8 *vaddr, u32 count)
+__ixp4xx_readsb(const volatile void __iomem *bus_addr, u8 *vaddr, u32 count)
{
while (count--)
*vaddr++ = readb(bus_addr);
}
static inline unsigned short
-__ixp4xx_readw(u32 addr)
+__ixp4xx_readw(const volatile void __iomem *p)
{
+ u32 addr = (u32)p;
u32 n, byte_enables, data;
if (addr >= VMALLOC_START)
@@ -200,15 +205,16 @@ __ixp4xx_readw(u32 addr)
}
static inline void
-__ixp4xx_readsw(u32 bus_addr, u16 *vaddr, u32 count)
+__ixp4xx_readsw(const volatile void __iomem *bus_addr, u16 *vaddr, u32 count)
{
while (count--)
*vaddr++ = readw(bus_addr);
}
static inline unsigned long
-__ixp4xx_readl(u32 addr)
+__ixp4xx_readl(const volatile void __iomem *p)
{
+ u32 addr = (u32)p;
u32 data;
if (addr >= VMALLOC_START)
@@ -221,7 +227,7 @@ __ixp4xx_readl(u32 addr)
}
static inline void
-__ixp4xx_readsl(u32 bus_addr, u32 *vaddr, u32 count)
+__ixp4xx_readsl(const volatile void __iomem *bus_addr, u32 *vaddr, u32 count)
{
while (count--)
*vaddr++ = readl(bus_addr);
@@ -239,7 +245,7 @@ __ixp4xx_readsl(u32 bus_addr, u32 *vaddr, u32 count)
eth_copy_and_sum((s),__mem_pci(c),(l),(b))
static inline int
-check_signature(unsigned long bus_addr, const unsigned char *signature,
+check_signature(const unsigned char __iomem *bus_addr, const unsigned char *signature,
int length)
{
int retval = 0;
@@ -389,7 +395,7 @@ __ixp4xx_insl(u32 io_addr, u32 *vaddr, u32 count)
#define __is_io_address(p) (((unsigned long)p >= PIO_OFFSET) && \
((unsigned long)p <= (PIO_MASK + PIO_OFFSET)))
static inline unsigned int
-__ixp4xx_ioread8(void __iomem *addr)
+__ixp4xx_ioread8(const void __iomem *addr)
{
unsigned long port = (unsigned long __force)addr;
if (__is_io_address(port))
@@ -398,12 +404,12 @@ __ixp4xx_ioread8(void __iomem *addr)
#ifndef CONFIG_IXP4XX_INDIRECT_PCI
return (unsigned int)__raw_readb(port);
#else
- return (unsigned int)__ixp4xx_readb(port);
+ return (unsigned int)__ixp4xx_readb(addr);
#endif
}
static inline void
-__ixp4xx_ioread8_rep(void __iomem *addr, void *vaddr, u32 count)
+__ixp4xx_ioread8_rep(const void __iomem *addr, void *vaddr, u32 count)
{
unsigned long port = (unsigned long __force)addr;
if (__is_io_address(port))
@@ -412,12 +418,12 @@ __ixp4xx_ioread8_rep(void __iomem *addr, void *vaddr, u32 count)
#ifndef CONFIG_IXP4XX_INDIRECT_PCI
__raw_readsb(addr, vaddr, count);
#else
- __ixp4xx_readsb(port, vaddr, count);
+ __ixp4xx_readsb(addr, vaddr, count);
#endif
}
static inline unsigned int
-__ixp4xx_ioread16(void __iomem *addr)
+__ixp4xx_ioread16(const void __iomem *addr)
{
unsigned long port = (unsigned long __force)addr;
if (__is_io_address(port))
@@ -426,12 +432,12 @@ __ixp4xx_ioread16(void __iomem *addr)
#ifndef CONFIG_IXP4XX_INDIRECT_PCI
return le16_to_cpu(__raw_readw((u32)port));
#else
- return (unsigned int)__ixp4xx_readw((u32)port);
+ return (unsigned int)__ixp4xx_readw(addr);
#endif
}
static inline void
-__ixp4xx_ioread16_rep(void __iomem *addr, void *vaddr, u32 count)
+__ixp4xx_ioread16_rep(const void __iomem *addr, void *vaddr, u32 count)
{
unsigned long port = (unsigned long __force)addr;
if (__is_io_address(port))
@@ -440,12 +446,12 @@ __ixp4xx_ioread16_rep(void __iomem *addr, void *vaddr, u32 count)
#ifndef CONFIG_IXP4XX_INDIRECT_PCI
__raw_readsw(addr, vaddr, count);
#else
- __ixp4xx_readsw(port, vaddr, count);
+ __ixp4xx_readsw(addr, vaddr, count);
#endif
}
static inline unsigned int
-__ixp4xx_ioread32(void __iomem *addr)
+__ixp4xx_ioread32(const void __iomem *addr)
{
unsigned long port = (unsigned long __force)addr;
if (__is_io_address(port))
@@ -454,13 +460,13 @@ __ixp4xx_ioread32(void __iomem *addr)
#ifndef CONFIG_IXP4XX_INDIRECT_PCI
return le32_to_cpu(__raw_readl((u32)port));
#else
- return (unsigned int)__ixp4xx_readl((u32)port);
+ return (unsigned int)__ixp4xx_readl(addr);
#endif
}
}
static inline void
-__ixp4xx_ioread32_rep(void __iomem *addr, void *vaddr, u32 count)
+__ixp4xx_ioread32_rep(const void __iomem *addr, void *vaddr, u32 count)
{
unsigned long port = (unsigned long __force)addr;
if (__is_io_address(port))
@@ -469,7 +475,7 @@ __ixp4xx_ioread32_rep(void __iomem *addr, void *vaddr, u32 count)
#ifndef CONFIG_IXP4XX_INDIRECT_PCI
__raw_readsl(addr, vaddr, count);
#else
- __ixp4xx_readsl(port, vaddr, count);
+ __ixp4xx_readsl(addr, vaddr, count);
#endif
}
@@ -483,7 +489,7 @@ __ixp4xx_iowrite8(u8 value, void __iomem *addr)
#ifndef CONFIG_IXP4XX_INDIRECT_PCI
__raw_writeb(value, port);
#else
- __ixp4xx_writeb(value, port);
+ __ixp4xx_writeb(value, addr);
#endif
}
@@ -497,7 +503,7 @@ __ixp4xx_iowrite8_rep(void __iomem *addr, const void *vaddr, u32 count)
#ifndef CONFIG_IXP4XX_INDIRECT_PCI
__raw_writesb(addr, vaddr, count);
#else
- __ixp4xx_writesb(port, vaddr, count);
+ __ixp4xx_writesb(addr, vaddr, count);
#endif
}
@@ -511,7 +517,7 @@ __ixp4xx_iowrite16(u16 value, void __iomem *addr)
#ifndef CONFIG_IXP4XX_INDIRECT_PCI
__raw_writew(cpu_to_le16(value), addr);
#else
- __ixp4xx_writew(value, port);
+ __ixp4xx_writew(value, addr);
#endif
}
@@ -525,7 +531,7 @@ __ixp4xx_iowrite16_rep(void __iomem *addr, const void *vaddr, u32 count)
#ifndef CONFIG_IXP4XX_INDIRECT_PCI
__raw_writesw(addr, vaddr, count);
#else
- __ixp4xx_writesw(port, vaddr, count);
+ __ixp4xx_writesw(addr, vaddr, count);
#endif
}
@@ -539,7 +545,7 @@ __ixp4xx_iowrite32(u32 value, void __iomem *addr)
#ifndef CONFIG_IXP4XX_INDIRECT_PCI
__raw_writel(cpu_to_le32(value), port);
#else
- __ixp4xx_writel(value, port);
+ __ixp4xx_writel(value, addr);
#endif
}
@@ -553,7 +559,7 @@ __ixp4xx_iowrite32_rep(void __iomem *addr, const void *vaddr, u32 count)
#ifndef CONFIG_IXP4XX_INDIRECT_PCI
__raw_writesl(addr, vaddr, count);
#else
- __ixp4xx_writesl(port, vaddr, count);
+ __ixp4xx_writesl(addr, vaddr, count);
#endif
}
diff --git a/include/asm-arm/arch-ixp4xx/irqs.h b/include/asm-arm/arch-ixp4xx/irqs.h
index ca808281c7f9..2cf4930372bc 100644
--- a/include/asm-arm/arch-ixp4xx/irqs.h
+++ b/include/asm-arm/arch-ixp4xx/irqs.h
@@ -93,4 +93,11 @@
#define IRQ_COYOTE_PCI_SLOT1 IRQ_IXP4XX_GPIO11
#define IRQ_COYOTE_IDE IRQ_IXP4XX_GPIO5
+/*
+ * NSLU2 board IRQs
+ */
+#define IRQ_NSLU2_PCI_INTA IRQ_IXP4XX_GPIO11
+#define IRQ_NSLU2_PCI_INTB IRQ_IXP4XX_GPIO10
+#define IRQ_NSLU2_PCI_INTC IRQ_IXP4XX_GPIO9
+
#endif
diff --git a/include/asm-arm/arch-ixp4xx/ixp4xx-regs.h b/include/asm-arm/arch-ixp4xx/ixp4xx-regs.h
index 004696a95bdb..2b149ed59149 100644
--- a/include/asm-arm/arch-ixp4xx/ixp4xx-regs.h
+++ b/include/asm-arm/arch-ixp4xx/ixp4xx-regs.h
@@ -36,11 +36,11 @@
*
* 0x6000000 0x00004000 ioremap'd QMgr
*
- * 0xC0000000 0x00001000 0xffbfe000 PCI CFG
+ * 0xC0000000 0x00001000 0xffbff000 PCI CFG
*
- * 0xC4000000 0x00001000 0xffbfd000 EXP CFG
+ * 0xC4000000 0x00001000 0xffbfe000 EXP CFG
*
- * 0xC8000000 0x0000C000 0xffbf2000 On-Chip Peripherals
+ * 0xC8000000 0x00013000 0xffbeb000 On-Chip Peripherals
*/
/*
@@ -52,22 +52,22 @@
* Expansion BUS Configuration registers
*/
#define IXP4XX_EXP_CFG_BASE_PHYS (0xC4000000)
-#define IXP4XX_EXP_CFG_BASE_VIRT (0xFFBFD000)
+#define IXP4XX_EXP_CFG_BASE_VIRT (0xFFBFE000)
#define IXP4XX_EXP_CFG_REGION_SIZE (0x00001000)
/*
* PCI Config registers
*/
#define IXP4XX_PCI_CFG_BASE_PHYS (0xC0000000)
-#define IXP4XX_PCI_CFG_BASE_VIRT (0xFFBFE000)
+#define IXP4XX_PCI_CFG_BASE_VIRT (0xFFBFF000)
#define IXP4XX_PCI_CFG_REGION_SIZE (0x00001000)
/*
* Peripheral space
*/
#define IXP4XX_PERIPHERAL_BASE_PHYS (0xC8000000)
-#define IXP4XX_PERIPHERAL_BASE_VIRT (0xFFBF2000)
-#define IXP4XX_PERIPHERAL_REGION_SIZE (0x0000C000)
+#define IXP4XX_PERIPHERAL_BASE_VIRT (0xFFBEB000)
+#define IXP4XX_PERIPHERAL_REGION_SIZE (0x00013000)
/*
* Debug UART
@@ -115,25 +115,48 @@
/*
* Peripheral Space Register Region Base Addresses
*/
-#define IXP4XX_UART1_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x0000)
-#define IXP4XX_UART2_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x1000)
-#define IXP4XX_PMU_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x2000)
-#define IXP4XX_INTC_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x3000)
-#define IXP4XX_GPIO_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x4000)
-#define IXP4XX_TIMER_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x5000)
-#define IXP4XX_EthA_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x9000)
-#define IXP4XX_EthB_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0xA000)
-#define IXP4XX_USB_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0xB000)
-
-#define IXP4XX_UART1_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x0000)
-#define IXP4XX_UART2_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x1000)
-#define IXP4XX_PMU_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x2000)
-#define IXP4XX_INTC_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x3000)
-#define IXP4XX_GPIO_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x4000)
-#define IXP4XX_TIMER_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x5000)
-#define IXP4XX_EthA_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x9000)
-#define IXP4XX_EthB_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0xA000)
-#define IXP4XX_USB_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0xB000)
+#define IXP4XX_UART1_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x0000)
+#define IXP4XX_UART2_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x1000)
+#define IXP4XX_PMU_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x2000)
+#define IXP4XX_INTC_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x3000)
+#define IXP4XX_GPIO_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x4000)
+#define IXP4XX_TIMER_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x5000)
+#define IXP4XX_NPEA_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x6000)
+#define IXP4XX_NPEB_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x7000)
+#define IXP4XX_NPEC_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x8000)
+#define IXP4XX_EthB_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x9000)
+#define IXP4XX_EthC_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0xA000)
+#define IXP4XX_USB_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0xB000)
+/* ixp46X only */
+#define IXP4XX_EthA_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0xC000)
+#define IXP4XX_EthB1_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0xD000)
+#define IXP4XX_EthB2_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0xE000)
+#define IXP4XX_EthB3_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0xF000)
+#define IXP4XX_TIMESYNC_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x10000)
+#define IXP4XX_I2C_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x11000)
+#define IXP4XX_SSP_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x12000)
+
+
+#define IXP4XX_UART1_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x0000)
+#define IXP4XX_UART2_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x1000)
+#define IXP4XX_PMU_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x2000)
+#define IXP4XX_INTC_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x3000)
+#define IXP4XX_GPIO_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x4000)
+#define IXP4XX_TIMER_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x5000)
+#define IXP4XX_NPEA_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_PHYS + 0x6000)
+#define IXP4XX_NPEB_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_PHYS + 0x7000)
+#define IXP4XX_NPEC_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_PHYS + 0x8000)
+#define IXP4XX_EthB_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x9000)
+#define IXP4XX_EthC_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0xA000)
+#define IXP4XX_USB_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0xB000)
+/* ixp46X only */
+#define IXP4XX_EthA_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0xC000)
+#define IXP4XX_EthB1_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0xD000)
+#define IXP4XX_EthB2_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0xE000)
+#define IXP4XX_EthB3_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0xF000)
+#define IXP4XX_TIMESYNC_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x10000)
+#define IXP4XX_I2C_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x11000)
+#define IXP4XX_SSP_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x12000)
/*
* Constants to make it easy to access Interrupt Controller registers
diff --git a/include/asm-arm/arch-ixp4xx/memory.h b/include/asm-arm/arch-ixp4xx/memory.h
index d348548b592b..e024d0a1a669 100644
--- a/include/asm-arm/arch-ixp4xx/memory.h
+++ b/include/asm-arm/arch-ixp4xx/memory.h
@@ -12,7 +12,7 @@
/*
* Physical DRAM offset.
*/
-#define PHYS_OFFSET (0x00000000UL)
+#define PHYS_OFFSET UL(0x00000000)
#ifndef __ASSEMBLY__
diff --git a/include/asm-arm/arch-ixp4xx/nslu2.h b/include/asm-arm/arch-ixp4xx/nslu2.h
new file mode 100644
index 000000000000..b8b347a559c7
--- /dev/null
+++ b/include/asm-arm/arch-ixp4xx/nslu2.h
@@ -0,0 +1,96 @@
+/*
+ * include/asm-arm/arch-ixp4xx/nslu2.h
+ *
+ * NSLU2 platform specific definitions
+ *
+ * Author: Mark Rakes <mrakes AT mac.com>
+ * Maintainers: http://www.nslu2-linux.org
+ *
+ * based on ixdp425.h:
+ * Copyright 2004 (c) MontaVista, Software, Inc.
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __ASM_ARCH_HARDWARE_H__
+#error "Do not include this directly, instead #include <asm/hardware.h>"
+#endif
+
+#define NSLU2_FLASH_BASE IXP4XX_EXP_BUS_CS0_BASE_PHYS
+#define NSLU2_FLASH_SIZE IXP4XX_EXP_BUS_CSX_REGION_SIZE
+
+#define NSLU2_SDA_PIN 7
+#define NSLU2_SCL_PIN 6
+
+/*
+ * NSLU2 PCI IRQs
+ */
+#define NSLU2_PCI_MAX_DEV 3
+#define NSLU2_PCI_IRQ_LINES 3
+
+
+/* PCI controller GPIO to IRQ pin mappings */
+#define NSLU2_PCI_INTA_PIN 11
+#define NSLU2_PCI_INTB_PIN 10
+#define NSLU2_PCI_INTC_PIN 9
+#define NSLU2_PCI_INTD_PIN 8
+
+
+/* NSLU2 Timer */
+#define NSLU2_FREQ 66000000
+#define NSLU2_CLOCK_TICK_RATE (((NSLU2_FREQ / HZ & ~IXP4XX_OST_RELOAD_MASK) + 1) * HZ)
+#define NSLU2_CLOCK_TICKS_PER_USEC ((NSLU2_CLOCK_TICK_RATE + USEC_PER_SEC/2) / USEC_PER_SEC)
+
+/* GPIO */
+
+#define NSLU2_GPIO0 0
+#define NSLU2_GPIO1 1
+#define NSLU2_GPIO2 2
+#define NSLU2_GPIO3 3
+#define NSLU2_GPIO4 4
+#define NSLU2_GPIO5 5
+#define NSLU2_GPIO6 6
+#define NSLU2_GPIO7 7
+#define NSLU2_GPIO8 8
+#define NSLU2_GPIO9 9
+#define NSLU2_GPIO10 10
+#define NSLU2_GPIO11 11
+#define NSLU2_GPIO12 12
+#define NSLU2_GPIO13 13
+#define NSLU2_GPIO14 14
+#define NSLU2_GPIO15 15
+
+/* Buttons */
+
+#define NSLU2_PB_GPIO NSLU2_GPIO5
+#define NSLU2_PO_GPIO NSLU2_GPIO8 /* power off */
+#define NSLU2_RB_GPIO NSLU2_GPIO12
+
+#define NSLU2_PB_IRQ IRQ_IXP4XX_GPIO5
+#define NSLU2_RB_IRQ IRQ_IXP4XX_GPIO12
+
+#define NSLU2_PB_BM (1L << NSLU2_PB_GPIO)
+#define NSLU2_PO_BM (1L << NSLU2_PO_GPIO)
+#define NSLU2_RB_BM (1L << NSLU2_RB_GPIO)
+
+/* Buzzer */
+
+#define NSLU2_GPIO_BUZZ 4
+#define NSLU2_BZ_BM (1L << NSLU2_GPIO_BUZZ)
+/* LEDs */
+
+#define NSLU2_LED_RED NSLU2_GPIO0
+#define NSLU2_LED_GRN NSLU2_GPIO1
+
+#define NSLU2_LED_RED_BM (1L << NSLU2_LED_RED)
+#define NSLU2_LED_GRN_BM (1L << NSLU2_LED_GRN)
+
+#define NSLU2_LED_DISK1 NSLU2_GPIO2
+#define NSLU2_LED_DISK2 NSLU2_GPIO3
+
+#define NSLU2_LED_DISK1_BM (1L << NSLU2_GPIO2)
+#define NSLU2_LED_DISK2_BM (1L << NSLU2_GPIO3)
+
+
diff --git a/include/asm-arm/arch-l7200/io.h b/include/asm-arm/arch-l7200/io.h
index fc012a39e2cb..cab8ad0adf09 100644
--- a/include/asm-arm/arch-l7200/io.h
+++ b/include/asm-arm/arch-l7200/io.h
@@ -10,7 +10,7 @@
#ifndef __ASM_ARM_ARCH_IO_H
#define __ASM_ARM_ARCH_IO_H
-#include <asm/arch/hardware.h>
+#include <asm/hardware.h>
#define IO_SPACE_LIMIT 0xffffffff
diff --git a/include/asm-arm/arch-l7200/memory.h b/include/asm-arm/arch-l7200/memory.h
index c5b9608cb137..9e50a171f78a 100644
--- a/include/asm-arm/arch-l7200/memory.h
+++ b/include/asm-arm/arch-l7200/memory.h
@@ -15,7 +15,7 @@
/*
* Physical DRAM offset on the L7200 SDB.
*/
-#define PHYS_OFFSET (0xf0000000UL)
+#define PHYS_OFFSET UL(0xf0000000)
#define __virt_to_bus(x) __virt_to_phys(x)
#define __bus_to_virt(x) __phys_to_virt(x)
diff --git a/include/asm-arm/arch-lh7a40x/io.h b/include/asm-arm/arch-lh7a40x/io.h
index c13bdd9add92..bbcd4335f441 100644
--- a/include/asm-arm/arch-lh7a40x/io.h
+++ b/include/asm-arm/arch-lh7a40x/io.h
@@ -11,6 +11,8 @@
#ifndef __ASM_ARCH_IO_H
#define __ASM_ARCH_IO_H
+#include <asm/hardware.h>
+
#define IO_SPACE_LIMIT 0xffffffff
/* No ISA or PCI bus on this machine. */
diff --git a/include/asm-arm/arch-lh7a40x/memory.h b/include/asm-arm/arch-lh7a40x/memory.h
index c650e6feb9d5..c92bcb837629 100644
--- a/include/asm-arm/arch-lh7a40x/memory.h
+++ b/include/asm-arm/arch-lh7a40x/memory.h
@@ -17,7 +17,7 @@
/*
* Physical DRAM offset.
*/
-#define PHYS_OFFSET (0xc0000000UL)
+#define PHYS_OFFSET UL(0xc0000000)
/*
* Virtual view <-> DMA view memory address translations
diff --git a/include/asm-arm/arch-omap/board-h4.h b/include/asm-arm/arch-omap/board-h4.h
index d64ee9211eed..33ea29a41654 100644
--- a/include/asm-arm/arch-omap/board-h4.h
+++ b/include/asm-arm/arch-omap/board-h4.h
@@ -34,5 +34,11 @@
#define OMAP24XX_ETHR_START 0x08000300
#define OMAP24XX_ETHR_GPIO_IRQ 92
+#define H4_CS0_BASE 0x04000000
+
+#define H4_CS0_BASE 0x04000000
+
+#define H4_CS0_BASE 0x04000000
+
#endif /* __ASM_ARCH_OMAP_H4_H */
diff --git a/include/asm-arm/arch-omap/board-innovator.h b/include/asm-arm/arch-omap/board-innovator.h
index 79574e0ed13d..b3cf33441f6e 100644
--- a/include/asm-arm/arch-omap/board-innovator.h
+++ b/include/asm-arm/arch-omap/board-innovator.h
@@ -26,7 +26,7 @@
#ifndef __ASM_ARCH_OMAP_INNOVATOR_H
#define __ASM_ARCH_OMAP_INNOVATOR_H
-#if defined (CONFIG_ARCH_OMAP1510)
+#if defined (CONFIG_ARCH_OMAP15XX)
#ifndef OMAP_SDRAM_DEVICE
#define OMAP_SDRAM_DEVICE D256M_1X16_4B
@@ -44,7 +44,7 @@ void fpga_write(unsigned char val, int reg);
unsigned char fpga_read(int reg);
#endif
-#endif /* CONFIG_ARCH_OMAP1510 */
+#endif /* CONFIG_ARCH_OMAP15XX */
#if defined (CONFIG_ARCH_OMAP16XX)
diff --git a/include/asm-arm/arch-omap/clock.h b/include/asm-arm/arch-omap/clock.h
new file mode 100644
index 000000000000..740c297eb11c
--- /dev/null
+++ b/include/asm-arm/arch-omap/clock.h
@@ -0,0 +1,91 @@
+/*
+ * linux/include/asm-arm/arch-omap/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
+ *
+ * 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 __ARCH_ARM_OMAP_CLOCK_H
+#define __ARCH_ARM_OMAP_CLOCK_H
+
+struct module;
+
+struct clk {
+ struct list_head node;
+ struct module *owner;
+ const char *name;
+ struct clk *parent;
+ unsigned long rate;
+ __u32 flags;
+ void __iomem *enable_reg;
+ __u8 enable_bit;
+ __u8 rate_offset;
+ __u8 src_offset;
+ __s8 usecount;
+ void (*recalc)(struct clk *);
+ int (*set_rate)(struct clk *, unsigned long);
+ long (*round_rate)(struct clk *, unsigned long);
+ void (*init)(struct clk *);
+ int (*enable)(struct clk *);
+ void (*disable)(struct clk *);
+};
+
+struct clk_functions {
+ int (*clk_enable)(struct clk *clk);
+ void (*clk_disable)(struct clk *clk);
+ int (*clk_use)(struct clk *clk);
+ void (*clk_unuse)(struct clk *clk);
+ long (*clk_round_rate)(struct clk *clk, unsigned long rate);
+ int (*clk_set_rate)(struct clk *clk, unsigned long rate);
+ int (*clk_set_parent)(struct clk *clk, struct clk *parent);
+ struct clk * (*clk_get_parent)(struct clk *clk);
+ void (*clk_allow_idle)(struct clk *clk);
+ void (*clk_deny_idle)(struct clk *clk);
+};
+
+extern unsigned int mpurate;
+extern struct list_head clocks;
+extern spinlock_t clockfw_lock;
+
+extern int clk_init(struct clk_functions * custom_clocks);
+extern int clk_register(struct clk *clk);
+extern void clk_unregister(struct clk *clk);
+extern void propagate_rate(struct clk *clk);
+extern void followparent_recalc(struct clk * clk);
+extern void clk_allow_idle(struct clk *clk);
+extern void clk_deny_idle(struct clk *clk);
+
+/* Clock flags */
+#define RATE_CKCTL (1 << 0) /* Main fixed ratio clocks */
+#define RATE_FIXED (1 << 1) /* Fixed clock rate */
+#define RATE_PROPAGATES (1 << 2) /* Program children too */
+#define VIRTUAL_CLOCK (1 << 3) /* Composite clock from table */
+#define ALWAYS_ENABLED (1 << 4) /* Clock cannot be disabled */
+#define ENABLE_REG_32BIT (1 << 5) /* Use 32-bit access */
+#define VIRTUAL_IO_ADDRESS (1 << 6) /* Clock in virtual address */
+#define CLOCK_IDLE_CONTROL (1 << 7)
+#define CLOCK_NO_IDLE_PARENT (1 << 8)
+#define DELAYED_APP (1 << 9) /* Delay application of clock */
+#define CONFIG_PARTICIPANT (1 << 10) /* Fundamental clock */
+#define CM_MPU_SEL1 (1 << 11) /* Domain divider/source */
+#define CM_DSP_SEL1 (1 << 12)
+#define CM_GFX_SEL1 (1 << 13)
+#define CM_MODEM_SEL1 (1 << 14)
+#define CM_CORE_SEL1 (1 << 15) /* Sets divider for many */
+#define CM_CORE_SEL2 (1 << 16) /* sets parent for GPT */
+#define CM_WKUP_SEL1 (1 << 17)
+#define CM_PLL_SEL1 (1 << 18)
+#define CM_PLL_SEL2 (1 << 19)
+#define CM_SYSCLKOUT_SEL1 (1 << 20)
+#define CLOCK_IN_OMAP730 (1 << 21)
+#define CLOCK_IN_OMAP1510 (1 << 22)
+#define CLOCK_IN_OMAP16XX (1 << 23)
+#define CLOCK_IN_OMAP242X (1 << 24)
+#define CLOCK_IN_OMAP243X (1 << 25)
+
+#endif
diff --git a/include/asm-arm/arch-omap/common.h b/include/asm-arm/arch-omap/common.h
index 2a676b4f13b5..08d58abd8218 100644
--- a/include/asm-arm/arch-omap/common.h
+++ b/include/asm-arm/arch-omap/common.h
@@ -31,6 +31,6 @@ struct sys_timer;
extern void omap_map_common_io(void);
extern struct sys_timer omap_timer;
-extern void omap_serial_init(int ports[]);
+extern void omap_serial_init(void);
#endif /* __ARCH_ARM_MACH_OMAP_COMMON_H */
diff --git a/include/asm-arm/arch-omap/cpu.h b/include/asm-arm/arch-omap/cpu.h
index 1119e2b53e72..ec7eb675d922 100644
--- a/include/asm-arm/arch-omap/cpu.h
+++ b/include/asm-arm/arch-omap/cpu.h
@@ -28,12 +28,7 @@
extern unsigned int system_rev;
-#define OMAP_DIE_ID_0 0xfffe1800
-#define OMAP_DIE_ID_1 0xfffe1804
-#define OMAP_PRODUCTION_ID_0 0xfffe2000
-#define OMAP_PRODUCTION_ID_1 0xfffe2004
-#define OMAP32_ID_0 0xfffed400
-#define OMAP32_ID_1 0xfffed404
+#define omap2_cpu_rev() ((system_rev >> 8) & 0x0f)
/*
* Test if multicore OMAP support is needed
@@ -50,7 +45,7 @@ extern unsigned int system_rev;
# define OMAP_NAME omap730
# endif
#endif
-#ifdef CONFIG_ARCH_OMAP1510
+#ifdef CONFIG_ARCH_OMAP15XX
# ifdef OMAP_NAME
# undef MULTI_OMAP1
# define MULTI_OMAP1
@@ -79,9 +74,11 @@ extern unsigned int system_rev;
* Macros to group OMAP into cpu classes.
* These can be used in most places.
* cpu_is_omap7xx(): True for OMAP730
- * cpu_is_omap15xx(): True for OMAP1510 and OMAP5910
+ * cpu_is_omap15xx(): True for OMAP1510, OMAP5910 and OMAP310
* cpu_is_omap16xx(): True for OMAP1610, OMAP5912 and OMAP1710
- * cpu_is_omap24xx(): True for OMAP2420
+ * cpu_is_omap24xx(): True for OMAP2420, OMAP2422, OMAP2423, OMAP2430
+ * cpu_is_omap242x(): True for OMAP2420, OMAP2422, OMAP2423
+ * cpu_is_omap243x(): True for OMAP2430
*/
#define GET_OMAP_CLASS (system_rev & 0xff)
@@ -91,22 +88,35 @@ static inline int is_omap ##class (void) \
return (GET_OMAP_CLASS == (id)) ? 1 : 0; \
}
+#define GET_OMAP_SUBCLASS ((system_rev >> 20) & 0x0fff)
+
+#define IS_OMAP_SUBCLASS(subclass, id) \
+static inline int is_omap ##subclass (void) \
+{ \
+ return (GET_OMAP_SUBCLASS == (id)) ? 1 : 0; \
+}
+
IS_OMAP_CLASS(7xx, 0x07)
IS_OMAP_CLASS(15xx, 0x15)
IS_OMAP_CLASS(16xx, 0x16)
IS_OMAP_CLASS(24xx, 0x24)
+IS_OMAP_SUBCLASS(242x, 0x242)
+IS_OMAP_SUBCLASS(243x, 0x243)
+
#define cpu_is_omap7xx() 0
#define cpu_is_omap15xx() 0
#define cpu_is_omap16xx() 0
#define cpu_is_omap24xx() 0
+#define cpu_is_omap242x() 0
+#define cpu_is_omap243x() 0
#if defined(MULTI_OMAP1)
# if defined(CONFIG_ARCH_OMAP730)
# undef cpu_is_omap7xx
# define cpu_is_omap7xx() is_omap7xx()
# endif
-# if defined(CONFIG_ARCH_OMAP1510)
+# if defined(CONFIG_ARCH_OMAP15XX)
# undef cpu_is_omap15xx
# define cpu_is_omap15xx() is_omap15xx()
# endif
@@ -119,7 +129,7 @@ IS_OMAP_CLASS(24xx, 0x24)
# undef cpu_is_omap7xx
# define cpu_is_omap7xx() 1
# endif
-# if defined(CONFIG_ARCH_OMAP1510)
+# if defined(CONFIG_ARCH_OMAP15XX)
# undef cpu_is_omap15xx
# define cpu_is_omap15xx() 1
# endif
@@ -129,13 +139,18 @@ IS_OMAP_CLASS(24xx, 0x24)
# endif
# if defined(CONFIG_ARCH_OMAP24XX)
# undef cpu_is_omap24xx
+# undef cpu_is_omap242x
+# undef cpu_is_omap243x
# define cpu_is_omap24xx() 1
+# define cpu_is_omap242x() is_omap242x()
+# define cpu_is_omap243x() is_omap243x()
# endif
#endif
/*
* Macros to detect individual cpu types.
* These are only rarely needed.
+ * cpu_is_omap330(): True for OMAP330
* cpu_is_omap730(): True for OMAP730
* cpu_is_omap1510(): True for OMAP1510
* cpu_is_omap1610(): True for OMAP1610
@@ -144,6 +159,9 @@ IS_OMAP_CLASS(24xx, 0x24)
* cpu_is_omap1621(): True for OMAP1621
* cpu_is_omap1710(): True for OMAP1710
* cpu_is_omap2420(): True for OMAP2420
+ * cpu_is_omap2422(): True for OMAP2422
+ * cpu_is_omap2423(): True for OMAP2423
+ * cpu_is_omap2430(): True for OMAP2430
*/
#define GET_OMAP_TYPE ((system_rev >> 16) & 0xffff)
@@ -153,6 +171,7 @@ static inline int is_omap ##type (void) \
return (GET_OMAP_TYPE == (id)) ? 1 : 0; \
}
+IS_OMAP_TYPE(310, 0x0310)
IS_OMAP_TYPE(730, 0x0730)
IS_OMAP_TYPE(1510, 0x1510)
IS_OMAP_TYPE(1610, 0x1610)
@@ -161,7 +180,11 @@ IS_OMAP_TYPE(5912, 0x1611)
IS_OMAP_TYPE(1621, 0x1621)
IS_OMAP_TYPE(1710, 0x1710)
IS_OMAP_TYPE(2420, 0x2420)
+IS_OMAP_TYPE(2422, 0x2422)
+IS_OMAP_TYPE(2423, 0x2423)
+IS_OMAP_TYPE(2430, 0x2430)
+#define cpu_is_omap310() 0
#define cpu_is_omap730() 0
#define cpu_is_omap1510() 0
#define cpu_is_omap1610() 0
@@ -170,31 +193,33 @@ IS_OMAP_TYPE(2420, 0x2420)
#define cpu_is_omap1621() 0
#define cpu_is_omap1710() 0
#define cpu_is_omap2420() 0
+#define cpu_is_omap2422() 0
+#define cpu_is_omap2423() 0
+#define cpu_is_omap2430() 0
#if defined(MULTI_OMAP1)
# if defined(CONFIG_ARCH_OMAP730)
# undef cpu_is_omap730
# define cpu_is_omap730() is_omap730()
# endif
-# if defined(CONFIG_ARCH_OMAP1510)
-# undef cpu_is_omap1510
-# define cpu_is_omap1510() is_omap1510()
-# endif
#else
# if defined(CONFIG_ARCH_OMAP730)
# undef cpu_is_omap730
# define cpu_is_omap730() 1
# endif
-# if defined(CONFIG_ARCH_OMAP1510)
-# undef cpu_is_omap1510
-# define cpu_is_omap1510() 1
-# endif
#endif
/*
* Whether we have MULTI_OMAP1 or not, we still need to distinguish
- * between 1611B/5912 and 1710.
+ * between 330 vs. 1510 and 1611B/5912 vs. 1710.
*/
+#if defined(CONFIG_ARCH_OMAP15XX)
+# undef cpu_is_omap310
+# undef cpu_is_omap1510
+# define cpu_is_omap310() is_omap310()
+# define cpu_is_omap1510() is_omap1510()
+#endif
+
#if defined(CONFIG_ARCH_OMAP16XX)
# undef cpu_is_omap1610
# undef cpu_is_omap1611
@@ -208,9 +233,20 @@ IS_OMAP_TYPE(2420, 0x2420)
# define cpu_is_omap1710() is_omap1710()
#endif
-#if defined(CONFIG_ARCH_OMAP2420)
-# undef cpu_is_omap2420
-# define cpu_is_omap2420() 1
+#if defined(CONFIG_ARCH_OMAP24XX)
+# undef cpu_is_omap2420
+# undef cpu_is_omap2422
+# undef cpu_is_omap2423
+# undef cpu_is_omap2430
+# define cpu_is_omap2420() is_omap2420()
+# define cpu_is_omap2422() is_omap2422()
+# define cpu_is_omap2423() is_omap2423()
+# define cpu_is_omap2430() is_omap2430()
#endif
+/* Macros to detect if we have OMAP1 or OMAP2 */
+#define cpu_class_is_omap1() (cpu_is_omap730() || cpu_is_omap15xx() || \
+ cpu_is_omap16xx())
+#define cpu_class_is_omap2() cpu_is_omap24xx()
+
#endif
diff --git a/include/asm-arm/arch-omap/dma.h b/include/asm-arm/arch-omap/dma.h
index 04ebef5c6e95..ccbcb580a5c1 100644
--- a/include/asm-arm/arch-omap/dma.h
+++ b/include/asm-arm/arch-omap/dma.h
@@ -22,9 +22,109 @@
#define __ASM_ARCH_DMA_H
#define MAX_DMA_ADDRESS 0xffffffff
+#define MAX_DMA_CHANNELS 0
+
+/* Hardware registers for omap1 */
+#define OMAP_DMA_BASE (0xfffed800)
+#define OMAP_DMA_GCR (OMAP_DMA_BASE + 0x400)
+#define OMAP_DMA_GSCR (OMAP_DMA_BASE + 0x404)
+#define OMAP_DMA_GRST (OMAP_DMA_BASE + 0x408)
+#define OMAP_DMA_HW_ID (OMAP_DMA_BASE + 0x442)
+#define OMAP_DMA_PCH2_ID (OMAP_DMA_BASE + 0x444)
+#define OMAP_DMA_PCH0_ID (OMAP_DMA_BASE + 0x446)
+#define OMAP_DMA_PCH1_ID (OMAP_DMA_BASE + 0x448)
+#define OMAP_DMA_PCHG_ID (OMAP_DMA_BASE + 0x44a)
+#define OMAP_DMA_PCHD_ID (OMAP_DMA_BASE + 0x44c)
+#define OMAP_DMA_CAPS_0_U (OMAP_DMA_BASE + 0x44e)
+#define OMAP_DMA_CAPS_0_L (OMAP_DMA_BASE + 0x450)
+#define OMAP_DMA_CAPS_1_U (OMAP_DMA_BASE + 0x452)
+#define OMAP_DMA_CAPS_1_L (OMAP_DMA_BASE + 0x454)
+#define OMAP_DMA_CAPS_2 (OMAP_DMA_BASE + 0x456)
+#define OMAP_DMA_CAPS_3 (OMAP_DMA_BASE + 0x458)
+#define OMAP_DMA_CAPS_4 (OMAP_DMA_BASE + 0x45a)
+#define OMAP_DMA_PCH2_SR (OMAP_DMA_BASE + 0x460)
+#define OMAP_DMA_PCH0_SR (OMAP_DMA_BASE + 0x480)
+#define OMAP_DMA_PCH1_SR (OMAP_DMA_BASE + 0x482)
+#define OMAP_DMA_PCHD_SR (OMAP_DMA_BASE + 0x4c0)
+
+/* Hardware registers for omap2 */
+#define OMAP24XX_DMA_BASE (L4_24XX_BASE + 0x56000)
+#define OMAP_DMA4_REVISION (OMAP24XX_DMA_BASE + 0x00)
+#define OMAP_DMA4_GCR_REG (OMAP24XX_DMA_BASE + 0x78)
+#define OMAP_DMA4_IRQSTATUS_L0 (OMAP24XX_DMA_BASE + 0x08)
+#define OMAP_DMA4_IRQSTATUS_L1 (OMAP24XX_DMA_BASE + 0x0c)
+#define OMAP_DMA4_IRQSTATUS_L2 (OMAP24XX_DMA_BASE + 0x10)
+#define OMAP_DMA4_IRQSTATUS_L3 (OMAP24XX_DMA_BASE + 0x14)
+#define OMAP_DMA4_IRQENABLE_L0 (OMAP24XX_DMA_BASE + 0x18)
+#define OMAP_DMA4_IRQENABLE_L1 (OMAP24XX_DMA_BASE + 0x1c)
+#define OMAP_DMA4_IRQENABLE_L2 (OMAP24XX_DMA_BASE + 0x20)
+#define OMAP_DMA4_IRQENABLE_L3 (OMAP24XX_DMA_BASE + 0x24)
+#define OMAP_DMA4_SYSSTATUS (OMAP24XX_DMA_BASE + 0x28)
+#define OMAP_DMA4_CAPS_0 (OMAP24XX_DMA_BASE + 0x64)
+#define OMAP_DMA4_CAPS_2 (OMAP24XX_DMA_BASE + 0x6c)
+#define OMAP_DMA4_CAPS_3 (OMAP24XX_DMA_BASE + 0x70)
+#define OMAP_DMA4_CAPS_4 (OMAP24XX_DMA_BASE + 0x74)
+
+#ifdef CONFIG_ARCH_OMAP1
#define OMAP_LOGICAL_DMA_CH_COUNT 17
+/* Common channel specific registers for omap1 */
+#define OMAP_DMA_CSDP_REG(n) __REG16(OMAP_DMA_BASE + 0x40 * (n) + 0x00)
+#define OMAP_DMA_CCR_REG(n) __REG16(OMAP_DMA_BASE + 0x40 * (n) + 0x02)
+#define OMAP_DMA_CICR_REG(n) __REG16(OMAP_DMA_BASE + 0x40 * (n) + 0x04)
+#define OMAP_DMA_CSR_REG(n) __REG16(OMAP_DMA_BASE + 0x40 * (n) + 0x06)
+#define OMAP_DMA_CEN_REG(n) __REG16(OMAP_DMA_BASE + 0x40 * (n) + 0x10)
+#define OMAP_DMA_CFN_REG(n) __REG16(OMAP_DMA_BASE + 0x40 * (n) + 0x12)
+#define OMAP_DMA_CSFI_REG(n) __REG16(OMAP_DMA_BASE + 0x40 * (n) + 0x14)
+#define OMAP_DMA_CSEI_REG(n) __REG16(OMAP_DMA_BASE + 0x40 * (n) + 0x16)
+#define OMAP_DMA_CSAC_REG(n) __REG16(OMAP_DMA_BASE + 0x40 * (n) + 0x18)
+#define OMAP_DMA_CDAC_REG(n) __REG16(OMAP_DMA_BASE + 0x40 * (n) + 0x1a)
+#define OMAP_DMA_CDEI_REG(n) __REG16(OMAP_DMA_BASE + 0x40 * (n) + 0x1c)
+#define OMAP_DMA_CDFI_REG(n) __REG16(OMAP_DMA_BASE + 0x40 * (n) + 0x1e)
+#define OMAP_DMA_CLNK_CTRL_REG(n) __REG16(OMAP_DMA_BASE + 0x40 * (n) + 0x28)
+
+#else
+
+#define OMAP_LOGICAL_DMA_CH_COUNT 32 /* REVISIT: Is this 32 + 2? */
+
+/* Common channel specific registers for omap2 */
+#define OMAP_DMA_CCR_REG(n) __REG32(OMAP24XX_DMA_BASE + 0x60 * (n) + 0x80)
+#define OMAP_DMA_CLNK_CTRL_REG(n) __REG32(OMAP24XX_DMA_BASE + 0x60 * (n) + 0x84)
+#define OMAP_DMA_CICR_REG(n) __REG32(OMAP24XX_DMA_BASE + 0x60 * (n) + 0x88)
+#define OMAP_DMA_CSR_REG(n) __REG32(OMAP24XX_DMA_BASE + 0x60 * (n) + 0x8c)
+#define OMAP_DMA_CSDP_REG(n) __REG32(OMAP24XX_DMA_BASE + 0x60 * (n) + 0x90)
+#define OMAP_DMA_CEN_REG(n) __REG32(OMAP24XX_DMA_BASE + 0x60 * (n) + 0x94)
+#define OMAP_DMA_CFN_REG(n) __REG32(OMAP24XX_DMA_BASE + 0x60 * (n) + 0x98)
+#define OMAP_DMA_CSEI_REG(n) __REG32(OMAP24XX_DMA_BASE + 0x60 * (n) + 0xa4)
+#define OMAP_DMA_CSFI_REG(n) __REG32(OMAP24XX_DMA_BASE + 0x60 * (n) + 0xa8)
+#define OMAP_DMA_CDEI_REG(n) __REG32(OMAP24XX_DMA_BASE + 0x60 * (n) + 0xac)
+#define OMAP_DMA_CDFI_REG(n) __REG32(OMAP24XX_DMA_BASE + 0x60 * (n) + 0xb0)
+#define OMAP_DMA_CSAC_REG(n) __REG32(OMAP24XX_DMA_BASE + 0x60 * (n) + 0xb4)
+#define OMAP_DMA_CDAC_REG(n) __REG32(OMAP24XX_DMA_BASE + 0x60 * (n) + 0xb8)
+
+#endif
+
+/* Channel specific registers only on omap1 */
+#define OMAP1_DMA_CSSA_L_REG(n) __REG16(OMAP_DMA_BASE + 0x40 * (n) + 0x08)
+#define OMAP1_DMA_CSSA_U_REG(n) __REG16(OMAP_DMA_BASE + 0x40 * (n) + 0x0a)
+#define OMAP1_DMA_CDSA_L_REG(n) __REG16(OMAP_DMA_BASE + 0x40 * (n) + 0x0c)
+#define OMAP1_DMA_CDSA_U_REG(n) __REG16(OMAP_DMA_BASE + 0x40 * (n) + 0x0e)
+#define OMAP1_DMA_COLOR_L_REG(n) __REG16(OMAP_DMA_BASE + 0x40 * (n) + 0x20)
+#define OMAP1_DMA_CCR2_REG(n) __REG16(OMAP_DMA_BASE + 0x40 * (n) + 0x24)
+#define OMAP1_DMA_COLOR_U_REG(n) __REG16(OMAP_DMA_BASE + 0x40 * (n) + 0x22)
+#define OMAP1_DMA_LCH_CTRL_REG(n) __REG16(OMAP_DMA_BASE + 0x40 * (n) + 0x2a)
+
+/* Channel specific registers only on omap2 */
+#define OMAP2_DMA_CSSA_REG(n) __REG32(OMAP24XX_DMA_BASE + 0x60 * (n) + 0x9c)
+#define OMAP2_DMA_CDSA_REG(n) __REG32(OMAP24XX_DMA_BASE + 0x60 * (n) + 0xa0)
+#define OMAP2_DMA_CCEN_REG(n) __REG32(OMAP24XX_DMA_BASE + 0x60 * (n) + 0xbc)
+#define OMAP2_DMA_CCFN_REG(n) __REG32(OMAP24XX_DMA_BASE + 0x60 * (n) + 0xc0)
+#define OMAP2_DMA_COLOR_REG(n) __REG32(OMAP24XX_DMA_BASE + 0x60 * (n) + 0xc4)
+
+/*----------------------------------------------------------------------------*/
+
+/* DMA channels for omap1 */
#define OMAP_DMA_NO_DEVICE 0
#define OMAP_DMA_MCSI1_TX 1
#define OMAP_DMA_MCSI1_RX 2
@@ -85,29 +185,72 @@
#define OMAP_DMA_MMC2_RX 55
#define OMAP_DMA_CRYPTO_DES_OUT 56
+/* DMA channels for 24xx */
+#define OMAP24XX_DMA_NO_DEVICE 0
+#define OMAP24XX_DMA_XTI_DMA 1 /* S_DMA_0 */
+#define OMAP24XX_DMA_EXT_NDMA_REQ0 2 /* S_DMA_1 */
+#define OMAP24XX_DMA_EXT_NDMA_REQ1 3 /* S_DMA_2 */
+#define OMAP24XX_DMA_GPMC 4 /* S_DMA_3 */
+#define OMAP24XX_DMA_GFX 5 /* S_DMA_4 */
+#define OMAP24XX_DMA_DSS 6 /* S_DMA_5 */
+#define OMAP24XX_DMA_VLYNQ_TX 7 /* S_DMA_6 */
+#define OMAP24XX_DMA_CWT 8 /* S_DMA_7 */
+#define OMAP24XX_DMA_AES_TX 9 /* S_DMA_8 */
+#define OMAP24XX_DMA_AES_RX 10 /* S_DMA_9 */
+#define OMAP24XX_DMA_DES_TX 11 /* S_DMA_10 */
+#define OMAP24XX_DMA_DES_RX 12 /* S_DMA_11 */
+#define OMAP24XX_DMA_SHA1MD5_RX 13 /* S_DMA_12 */
-#define OMAP_DMA_BASE (0xfffed800)
-#define OMAP_DMA_GCR (OMAP_DMA_BASE + 0x400)
-#define OMAP_DMA_GSCR (OMAP_DMA_BASE + 0x404)
-#define OMAP_DMA_GRST (OMAP_DMA_BASE + 0x408)
-#define OMAP_DMA_HW_ID (OMAP_DMA_BASE + 0x442)
-#define OMAP_DMA_PCH2_ID (OMAP_DMA_BASE + 0x444)
-#define OMAP_DMA_PCH0_ID (OMAP_DMA_BASE + 0x446)
-#define OMAP_DMA_PCH1_ID (OMAP_DMA_BASE + 0x448)
-#define OMAP_DMA_PCHG_ID (OMAP_DMA_BASE + 0x44a)
-#define OMAP_DMA_PCHD_ID (OMAP_DMA_BASE + 0x44c)
-#define OMAP_DMA_CAPS_0_U (OMAP_DMA_BASE + 0x44e)
-#define OMAP_DMA_CAPS_0_L (OMAP_DMA_BASE + 0x450)
-#define OMAP_DMA_CAPS_1_U (OMAP_DMA_BASE + 0x452)
-#define OMAP_DMA_CAPS_1_L (OMAP_DMA_BASE + 0x454)
-#define OMAP_DMA_CAPS_2 (OMAP_DMA_BASE + 0x456)
-#define OMAP_DMA_CAPS_3 (OMAP_DMA_BASE + 0x458)
-#define OMAP_DMA_CAPS_4 (OMAP_DMA_BASE + 0x45a)
-#define OMAP_DMA_PCH2_SR (OMAP_DMA_BASE + 0x460)
-#define OMAP_DMA_PCH0_SR (OMAP_DMA_BASE + 0x480)
-#define OMAP_DMA_PCH1_SR (OMAP_DMA_BASE + 0x482)
-#define OMAP_DMA_PCHD_SR (OMAP_DMA_BASE + 0x4c0)
+#define OMAP24XX_DMA_EAC_AC_RD 17 /* S_DMA_16 */
+#define OMAP24XX_DMA_EAC_AC_WR 18 /* S_DMA_17 */
+#define OMAP24XX_DMA_EAC_MD_UL_RD 19 /* S_DMA_18 */
+#define OMAP24XX_DMA_EAC_MD_UL_WR 20 /* S_DMA_19 */
+#define OMAP24XX_DMA_EAC_MD_DL_RD 21 /* S_DMA_20 */
+#define OMAP24XX_DMA_EAC_MD_DL_WR 22 /* S_DMA_21 */
+#define OMAP24XX_DMA_EAC_BT_UL_RD 23 /* S_DMA_22 */
+#define OMAP24XX_DMA_EAC_BT_UL_WR 24 /* S_DMA_23 */
+#define OMAP24XX_DMA_EAC_BT_DL_RD 25 /* S_DMA_24 */
+#define OMAP24XX_DMA_EAC_BT_DL_WR 26 /* S_DMA_25 */
+#define OMAP24XX_DMA_I2C1_TX 27 /* S_DMA_26 */
+#define OMAP24XX_DMA_I2C1_RX 28 /* S_DMA_27 */
+#define OMAP24XX_DMA_I2C2_TX 29 /* S_DMA_28 */
+#define OMAP24XX_DMA_I2C2_RX 30 /* S_DMA_29 */
+#define OMAP24XX_DMA_MCBSP1_TX 31 /* SDMA_30 */
+#define OMAP24XX_DMA_MCBSP1_RX 32 /* SDMA_31 */
+#define OMAP24XX_DMA_MCBSP2_TX 33 /* SDMA_32 */
+#define OMAP24XX_DMA_MCBSP2_RX 34 /* SDMA_33 */
+#define OMAP24XX_DMA_SPI1_TX0 35 /* SDMA_34 */
+#define OMAP24XX_DMA_SPI1_RX0 36 /* SDMA_35 */
+#define OMAP24XX_DMA_SPI1_TX1 37 /* SDMA_36 */
+#define OMAP24XX_DMA_SPI1_RX1 38 /* SDMA_37 */
+#define OMAP24XX_DMA_SPI1_TX2 39 /* SDMA_38 */
+#define OMAP24XX_DMA_SPI1_RX2 40 /* SDMA_39 */
+#define OMAP24XX_DMA_SPI1_TX3 41 /* SDMA_40 */
+#define OMAP24XX_DMA_SPI1_RX3 42 /* SDMA_41 */
+#define OMAP24XX_DMA_SPI2_TX0 43 /* SDMA_42 */
+#define OMAP24XX_DMA_SPI2_RX0 44 /* SDMA_43 */
+#define OMAP24XX_DMA_SPI2_TX1 45 /* SDMA_44 */
+#define OMAP24XX_DMA_SPI2_RX1 46 /* SDMA_45 */
+#define OMAP24XX_DMA_UART1_TX 49 /* SDMA_48 */
+#define OMAP24XX_DMA_UART1_RX 50 /* SDMA_49 */
+#define OMAP24XX_DMA_UART2_TX 51 /* SDMA_50 */
+#define OMAP24XX_DMA_UART2_RX 52 /* SDMA_51 */
+#define OMAP24XX_DMA_UART3_TX 53 /* SDMA_52 */
+#define OMAP24XX_DMA_UART3_RX 54 /* SDMA_53 */
+#define OMAP24XX_DMA_USB_W2FC_TX0 55 /* SDMA_54 */
+#define OMAP24XX_DMA_USB_W2FC_RX0 56 /* SDMA_55 */
+#define OMAP24XX_DMA_USB_W2FC_TX1 57 /* SDMA_56 */
+#define OMAP24XX_DMA_USB_W2FC_RX1 58 /* SDMA_57 */
+#define OMAP24XX_DMA_USB_W2FC_TX2 59 /* SDMA_58 */
+#define OMAP24XX_DMA_USB_W2FC_RX2 60 /* SDMA_59 */
+#define OMAP24XX_DMA_MMC1_TX 61 /* SDMA_60 */
+#define OMAP24XX_DMA_MMC1_RX 62 /* SDMA_61 */
+#define OMAP24XX_DMA_MS 63 /* SDMA_62 */
+
+/*----------------------------------------------------------------------------*/
+
+/* Hardware registers for LCD DMA */
#define OMAP1510_DMA_LCD_BASE (0xfffedb00)
#define OMAP1510_DMA_LCD_CTRL (OMAP1510_DMA_LCD_BASE + 0x00)
#define OMAP1510_DMA_LCD_TOP_F1_L (OMAP1510_DMA_LCD_BASE + 0x02)
@@ -116,7 +259,7 @@
#define OMAP1510_DMA_LCD_BOT_F1_U (OMAP1510_DMA_LCD_BASE + 0x08)
#define OMAP1610_DMA_LCD_BASE (0xfffee300)
-#define OMAP1610_DMA_LCD_CSDP (OMAP1610_DMA_LCD_BASE + 0xc0)
+#define OMAP1610_DMA_LCD_CSDP (OMAP1610_DMA_LCD_BASE + 0xc0)
#define OMAP1610_DMA_LCD_CCR (OMAP1610_DMA_LCD_BASE + 0xc2)
#define OMAP1610_DMA_LCD_CTRL (OMAP1610_DMA_LCD_BASE + 0xc4)
#define OMAP1610_DMA_LCD_TOP_B1_L (OMAP1610_DMA_LCD_BASE + 0xc8)
@@ -134,37 +277,18 @@
#define OMAP1610_DMA_LCD_LCH_CTRL (OMAP1610_DMA_LCD_BASE + 0xea)
#define OMAP1610_DMA_LCD_SRC_FI_B1_U (OMAP1610_DMA_LCD_BASE + 0xf4)
-
-/* Every LCh has its own set of the registers below */
-#define OMAP_DMA_CSDP(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x00)
-#define OMAP_DMA_CCR(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x02)
-#define OMAP_DMA_CICR(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x04)
-#define OMAP_DMA_CSR(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x06)
-#define OMAP_DMA_CSSA_L(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x08)
-#define OMAP_DMA_CSSA_U(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x0a)
-#define OMAP_DMA_CDSA_L(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x0c)
-#define OMAP_DMA_CDSA_U(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x0e)
-#define OMAP_DMA_CEN(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x10)
-#define OMAP_DMA_CFN(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x12)
-#define OMAP_DMA_CSFI(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x14)
-#define OMAP_DMA_CSEI(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x16)
-#define OMAP_DMA_CSAC(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x18)
-#define OMAP_DMA_CDAC(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x1a)
-#define OMAP_DMA_CDEI(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x1c)
-#define OMAP_DMA_CDFI(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x1e)
-#define OMAP_DMA_COLOR_L(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x20)
-#define OMAP_DMA_COLOR_U(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x22)
-#define OMAP_DMA_CCR2(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x24)
-#define OMAP_DMA_CLNK_CTRL(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x28)
-#define OMAP_DMA_LCH_CTRL(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x2a)
-
-#define OMAP_DMA_TOUT_IRQ (1 << 0)
+#define OMAP_DMA_TOUT_IRQ (1 << 0) /* Only on omap1 */
#define OMAP_DMA_DROP_IRQ (1 << 1)
#define OMAP_DMA_HALF_IRQ (1 << 2)
#define OMAP_DMA_FRAME_IRQ (1 << 3)
#define OMAP_DMA_LAST_IRQ (1 << 4)
#define OMAP_DMA_BLOCK_IRQ (1 << 5)
-#define OMAP_DMA_SYNC_IRQ (1 << 6)
+#define OMAP1_DMA_SYNC_IRQ (1 << 6)
+#define OMAP2_DMA_PKT_IRQ (1 << 7)
+#define OMAP2_DMA_TRANS_ERR_IRQ (1 << 8)
+#define OMAP2_DMA_SECURE_ERR_IRQ (1 << 9)
+#define OMAP2_DMA_SUPERVISOR_ERR_IRQ (1 << 10)
+#define OMAP2_DMA_MISALIGNED_ERR_IRQ (1 << 11)
#define OMAP_DMA_DATA_TYPE_S8 0x00
#define OMAP_DMA_DATA_TYPE_S16 0x01
@@ -194,6 +318,7 @@ enum {
OMAP_LCD_DMA_B2_BOTTOM
};
+/* REVISIT: Check if BURST_4 is really 1 (or 2) */
enum omap_dma_burst_mode {
OMAP_DMA_DATA_BURST_DIS = 0,
OMAP_DMA_DATA_BURST_4,
@@ -206,6 +331,31 @@ enum omap_dma_color_mode {
OMAP_DMA_TRANSPARENT_COPY
};
+struct omap_dma_channel_params {
+ int data_type; /* data type 8,16,32 */
+ int elem_count; /* number of elements in a frame */
+ int frame_count; /* number of frames in a element */
+
+ int src_port; /* Only on OMAP1 REVISIT: Is this needed? */
+ int src_amode; /* constant , post increment, indexed , double indexed */
+ int src_start; /* source address : physical */
+ int src_ei; /* source element index */
+ int src_fi; /* source frame index */
+
+ int dst_port; /* Only on OMAP1 REVISIT: Is this needed? */
+ int dst_amode; /* constant , post increment, indexed , double indexed */
+ int dst_start; /* source address : physical */
+ int dst_ei; /* source element index */
+ int dst_fi; /* source frame index */
+
+ int trigger; /* trigger attached if the channel is synchronized */
+ int sync_mode; /* sycn on element, frame , block or packet */
+ int src_or_dst_synch; /* source synch(1) or destination synch(0) */
+
+ int ie; /* interrupt enabled */
+};
+
+
extern void omap_set_dma_priority(int dst_port, int priority);
extern int omap_request_dma(int dev_id, const char *dev_name,
void (* callback)(int lch, u16 ch_status, void *data),
@@ -217,24 +367,30 @@ extern void omap_start_dma(int lch);
extern void omap_stop_dma(int lch);
extern void omap_set_dma_transfer_params(int lch, int data_type,
int elem_count, int frame_count,
- int sync_mode);
+ int sync_mode,
+ int dma_trigger, int src_or_dst_synch);
extern void omap_set_dma_color_mode(int lch, enum omap_dma_color_mode mode,
u32 color);
extern void omap_set_dma_src_params(int lch, int src_port, int src_amode,
- unsigned long src_start);
+ unsigned long src_start,
+ int src_ei, int src_fi);
extern void omap_set_dma_src_index(int lch, int eidx, int fidx);
extern void omap_set_dma_src_data_pack(int lch, int enable);
extern void omap_set_dma_src_burst_mode(int lch,
enum omap_dma_burst_mode burst_mode);
extern void omap_set_dma_dest_params(int lch, int dest_port, int dest_amode,
- unsigned long dest_start);
+ unsigned long dest_start,
+ int dst_ei, int dst_fi);
extern void omap_set_dma_dest_index(int lch, int eidx, int fidx);
extern void omap_set_dma_dest_data_pack(int lch, int enable);
extern void omap_set_dma_dest_burst_mode(int lch,
enum omap_dma_burst_mode burst_mode);
+extern void omap_set_dma_params(int lch,
+ struct omap_dma_channel_params * params);
+
extern void omap_dma_link_lch (int lch_head, int lch_queue);
extern void omap_dma_unlink_lch (int lch_head, int lch_queue);
@@ -244,9 +400,6 @@ extern int omap_get_dma_src_addr_counter(int lch);
extern void omap_clear_dma(int lch);
extern int omap_dma_running(void);
-/* Returns 1 if the DMA module is in OMAP1510-compatible mode, 0 otherwise */
-extern int omap_dma_in_1510_mode(void);
-
/* LCD DMA functions */
extern int omap_request_lcd_dma(void (* callback)(u16 status, void *data),
void *data);
diff --git a/include/asm-arm/arch-omap/entry-macro.S b/include/asm-arm/arch-omap/entry-macro.S
index 0d29b9c56a95..f8814a84910e 100644
--- a/include/asm-arm/arch-omap/entry-macro.S
+++ b/include/asm-arm/arch-omap/entry-macro.S
@@ -10,6 +10,20 @@
#if defined(CONFIG_ARCH_OMAP1)
+#if defined(CONFIG_ARCH_OMAP730) && \
+ (defined(CONFIG_ARCH_OMAP15XX) || defined(CONFIG_ARCH_OMAP16XX))
+#error "FIXME: OMAP730 doesn't support multiple-OMAP"
+#elif defined(CONFIG_ARCH_OMAP730)
+#define INT_IH2_IRQ INT_730_IH2_IRQ
+#elif defined(CONFIG_ARCH_OMAP15XX)
+#define INT_IH2_IRQ INT_1510_IH2_IRQ
+#elif defined(CONFIG_ARCH_OMAP16XX)
+#define INT_IH2_IRQ INT_1610_IH2_IRQ
+#else
+#warning "IH2 IRQ defaulted"
+#define INT_IH2_IRQ INT_1510_IH2_IRQ
+#endif
+
.macro disable_fiq
.endm
diff --git a/include/asm-arm/arch-omap/fpga.h b/include/asm-arm/arch-omap/fpga.h
index 676807dc50e1..6a883e0bdbb8 100644
--- a/include/asm-arm/arch-omap/fpga.h
+++ b/include/asm-arm/arch-omap/fpga.h
@@ -19,7 +19,7 @@
#ifndef __ASM_ARCH_OMAP_FPGA_H
#define __ASM_ARCH_OMAP_FPGA_H
-#if defined(CONFIG_MACH_OMAP_INNOVATOR) && defined(CONFIG_ARCH_OMAP1510)
+#if defined(CONFIG_MACH_OMAP_INNOVATOR) && defined(CONFIG_ARCH_OMAP15XX)
extern void omap1510_fpga_init_irq(void);
#else
#define omap1510_fpga_init_irq() (0)
@@ -77,6 +77,8 @@ struct h2p2_dbg_fpga {
#define H2P2_DBG_FPGA_LOAD_METER_SIZE 11
#define H2P2_DBG_FPGA_LOAD_METER_MASK ((1 << H2P2_DBG_FPGA_LOAD_METER_SIZE) - 1)
+#define H2P2_DBG_FPGA_P2_LED_TIMER (1 << 0)
+#define H2P2_DBG_FPGA_P2_LED_IDLE (1 << 1)
/*
* ---------------------------------------------------------------------------
diff --git a/include/asm-arm/arch-omap/gpio.h b/include/asm-arm/arch-omap/gpio.h
index 74cb2b93b700..1b3885741ac1 100644
--- a/include/asm-arm/arch-omap/gpio.h
+++ b/include/asm-arm/arch-omap/gpio.h
@@ -67,7 +67,7 @@
#define OMAP_GPIO_IRQ(nr) (OMAP_GPIO_IS_MPUIO(nr) ? \
IH_MPUIO_BASE + ((nr) & 0x0f) : \
- IH_GPIO_BASE + ((nr) & 0x3f))
+ IH_GPIO_BASE + (nr))
extern int omap_gpio_init(void); /* Call from board init only */
extern int omap_request_gpio(int gpio);
diff --git a/include/asm-arm/arch-omap/hardware.h b/include/asm-arm/arch-omap/hardware.h
index 60201e1dd6ad..5406b875c422 100644
--- a/include/asm-arm/arch-omap/hardware.h
+++ b/include/asm-arm/arch-omap/hardware.h
@@ -267,8 +267,6 @@
#define OMAP_LPG2_LCR (OMAP_LPG2_BASE + 0x00)
#define OMAP_LPG2_PMR (OMAP_LPG2_BASE + 0x04)
-#ifndef __ASSEMBLER__
-
/*
* ---------------------------------------------------------------------------
* Processor specific defines
@@ -277,13 +275,11 @@
#include "omap730.h"
#include "omap1510.h"
-
-#ifdef CONFIG_ARCH_OMAP24XX
#include "omap24xx.h"
-#endif
-
#include "omap16xx.h"
+#ifndef __ASSEMBLER__
+
/*
* ---------------------------------------------------------------------------
* Board specific defines
diff --git a/include/asm-arm/arch-omap/io.h b/include/asm-arm/arch-omap/io.h
index 11fbf629bf75..f5bcc9a1aed6 100644
--- a/include/asm-arm/arch-omap/io.h
+++ b/include/asm-arm/arch-omap/io.h
@@ -34,6 +34,8 @@
#ifndef __ASM_ARM_ARCH_IO_H
#define __ASM_ARM_ARCH_IO_H
+#include <asm/hardware.h>
+
#define IO_SPACE_LIMIT 0xffffffff
/*
@@ -50,23 +52,33 @@
* ----------------------------------------------------------------------------
*/
+#define PCIO_BASE 0
+
#if defined(CONFIG_ARCH_OMAP1)
+
#define IO_PHYS 0xFFFB0000
-#define IO_OFFSET -0x01000000 /* Virtual IO = 0xfefb0000 */
+#define IO_OFFSET 0x01000000 /* Virtual IO = 0xfefb0000 */
#define IO_SIZE 0x40000
+#define IO_VIRT (IO_PHYS - IO_OFFSET)
+#define IO_ADDRESS(pa) ((pa) - IO_OFFSET)
+#define io_p2v(pa) ((pa) - IO_OFFSET)
+#define io_v2p(va) ((va) + IO_OFFSET)
#elif defined(CONFIG_ARCH_OMAP2)
-#define IO_PHYS 0x48000000 /* L4 peripherals; other stuff has to be mapped *
- * manually. */
-#define IO_OFFSET 0x90000000 /* Virtual IO = 0xd8000000 */
-#define IO_SIZE 0x08000000
-#endif
-#define IO_VIRT (IO_PHYS + IO_OFFSET)
-#define IO_ADDRESS(x) ((x) + IO_OFFSET)
-#define PCIO_BASE 0
-#define io_p2v(x) ((x) + IO_OFFSET)
-#define io_v2p(x) ((x) - IO_OFFSET)
+/* We map both L3 and L4 on OMAP2 */
+#define L3_24XX_PHYS L3_24XX_BASE /* 0x68000000 */
+#define L3_24XX_VIRT 0xf8000000
+#define L3_24XX_SIZE SZ_1M /* 44kB of 128MB used, want 1MB sect */
+#define L4_24XX_PHYS L4_24XX_BASE /* 0x48000000 */
+#define L4_24XX_VIRT 0xd8000000
+#define L4_24XX_SIZE SZ_1M /* 1MB of 128MB used, want 1MB sect */
+#define IO_OFFSET 0x90000000
+#define IO_ADDRESS(pa) ((pa) + IO_OFFSET) /* Works for L3 and L4 */
+#define io_p2v(pa) ((pa) + IO_OFFSET) /* Works for L3 and L4 */
+#define io_v2p(va) ((va) - IO_OFFSET) /* Works for L3 and L4 */
+
+#endif
#ifndef __ASSEMBLER__
diff --git a/include/asm-arm/arch-omap/irqs.h b/include/asm-arm/arch-omap/irqs.h
index 74e108ccac16..9779686bdceb 100644
--- a/include/asm-arm/arch-omap/irqs.h
+++ b/include/asm-arm/arch-omap/irqs.h
@@ -22,8 +22,8 @@
* are different.
*/
-#ifndef __ASM_ARCH_OMAP1510_IRQS_H
-#define __ASM_ARCH_OMAP1510_IRQS_H
+#ifndef __ASM_ARCH_OMAP15XX_IRQS_H
+#define __ASM_ARCH_OMAP15XX_IRQS_H
/*
* IRQ numbers for interrupt handler 1
@@ -31,7 +31,6 @@
* NOTE: See also the OMAP-1510 and 1610 specific IRQ numbers below
*
*/
-#define INT_IH2_IRQ 0
#define INT_CAMERA 1
#define INT_FIQ 3
#define INT_RTDX 6
@@ -60,6 +59,7 @@
/*
* OMAP-1510 specific IRQ numbers for interrupt handler 1
*/
+#define INT_1510_IH2_IRQ 0
#define INT_1510_RES2 2
#define INT_1510_SPI_TX 4
#define INT_1510_SPI_RX 5
@@ -71,6 +71,7 @@
/*
* OMAP-1610 specific IRQ numbers for interrupt handler 1
*/
+#define INT_1610_IH2_IRQ 0
#define INT_1610_IH2_FIQ 2
#define INT_1610_McBSP2_TX 4
#define INT_1610_McBSP2_RX 5
@@ -231,6 +232,12 @@
#define INT_730_DMA_CH15 (62 + IH2_BASE)
#define INT_730_NAND (63 + IH2_BASE)
+#define INT_24XX_SYS_NIRQ 7
+#define INT_24XX_SDMA_IRQ0 12
+#define INT_24XX_SDMA_IRQ1 13
+#define INT_24XX_SDMA_IRQ2 14
+#define INT_24XX_SDMA_IRQ3 15
+#define INT_24XX_DSS_IRQ 25
#define INT_24XX_GPIO_BANK1 29
#define INT_24XX_GPIO_BANK2 30
#define INT_24XX_GPIO_BANK3 31
diff --git a/include/asm-arm/arch-omap/memory.h b/include/asm-arm/arch-omap/memory.h
index ef32d61eec7a..df50dd53e1dd 100644
--- a/include/asm-arm/arch-omap/memory.h
+++ b/include/asm-arm/arch-omap/memory.h
@@ -37,9 +37,9 @@
* Physical DRAM offset.
*/
#if defined(CONFIG_ARCH_OMAP1)
-#define PHYS_OFFSET (0x10000000UL)
+#define PHYS_OFFSET UL(0x10000000)
#elif defined(CONFIG_ARCH_OMAP2)
-#define PHYS_OFFSET (0x80000000UL)
+#define PHYS_OFFSET UL(0x80000000)
#endif
/*
@@ -61,12 +61,12 @@
* Note that the is_lbus_device() test is not very efficient on 1510
* because of the strncmp().
*/
-#ifdef CONFIG_ARCH_OMAP1510
+#ifdef CONFIG_ARCH_OMAP15XX
/*
* OMAP-1510 Local Bus address offset
*/
-#define OMAP1510_LB_OFFSET (0x30000000UL)
+#define OMAP1510_LB_OFFSET UL(0x30000000)
#define virt_to_lbus(x) ((x) - PAGE_OFFSET + OMAP1510_LB_OFFSET)
#define lbus_to_virt(x) ((x) - OMAP1510_LB_OFFSET + PAGE_OFFSET)
@@ -84,7 +84,7 @@
virt_to_lbus(addr) : \
__virt_to_bus(addr);})
-#endif /* CONFIG_ARCH_OMAP1510 */
+#endif /* CONFIG_ARCH_OMAP15XX */
#endif
diff --git a/include/asm-arm/arch-omap/menelaus.h b/include/asm-arm/arch-omap/menelaus.h
new file mode 100644
index 000000000000..46be8b8d6346
--- /dev/null
+++ b/include/asm-arm/arch-omap/menelaus.h
@@ -0,0 +1,22 @@
+/*
+ * linux/include/asm-arm/arch-omap/menelaus.h
+ *
+ * Functions to access Menelaus power management chip
+ */
+
+#ifndef __ASM_ARCH_MENELAUS_H
+#define __ASM_ARCH_MENELAUS_H
+
+extern void menelaus_mmc_register(void (*callback)(u8 card_mask),
+ unsigned long data);
+extern void menelaus_mmc_remove(void);
+extern void menelaus_mmc_opendrain(int enable);
+
+#if defined(CONFIG_ARCH_OMAP24XX) && defined(CONFIG_MENELAUS)
+#define omap_has_menelaus() 1
+#else
+#define omap_has_menelaus() 0
+#endif
+
+#endif
+
diff --git a/include/asm-arm/arch-omap/mux.h b/include/asm-arm/arch-omap/mux.h
index 1b1ad4105349..13415a9aab06 100644
--- a/include/asm-arm/arch-omap/mux.h
+++ b/include/asm-arm/arch-omap/mux.h
@@ -4,7 +4,7 @@
* Table of the Omap register configurations for the FUNC_MUX and
* PULL_DWN combinations.
*
- * Copyright (C) 2003 Nokia Corporation
+ * Copyright (C) 2003 - 2005 Nokia Corporation
*
* Written by Tony Lindgren <tony.lindgren@nokia.com>
*
@@ -58,6 +58,16 @@
.pu_pd_reg = PU_PD_SEL_##reg, \
.pu_pd_val = status,
+#define MUX_REG_730(reg, mode_offset, mode) .mux_reg_name = "OMAP730_IO_CONF_"#reg, \
+ .mux_reg = OMAP730_IO_CONF_##reg, \
+ .mask_offset = mode_offset, \
+ .mask = mode,
+
+#define PULL_REG_730(reg, bit, status) .pull_name = "OMAP730_IO_CONF_"#reg, \
+ .pull_reg = OMAP730_IO_CONF_##reg, \
+ .pull_bit = bit, \
+ .pull_val = status,
+
#else
#define MUX_REG(reg, mode_offset, mode) .mux_reg = FUNC_MUX_CTRL_##reg, \
@@ -71,6 +81,15 @@
#define PU_PD_REG(reg, status) .pu_pd_reg = PU_PD_SEL_##reg, \
.pu_pd_val = status,
+#define MUX_REG_730(reg, mode_offset, mode) \
+ .mux_reg = OMAP730_IO_CONF_##reg, \
+ .mask_offset = mode_offset, \
+ .mask = mode,
+
+#define PULL_REG_730(reg, bit, status) .pull_reg = OMAP730_IO_CONF_##reg, \
+ .pull_bit = bit, \
+ .pull_val = status,
+
#endif /* CONFIG_OMAP_MUX_DEBUG */
#define MUX_CFG(desc, mux_reg, mode_offset, mode, \
@@ -84,13 +103,44 @@
PU_PD_REG(pu_pd_reg, pu_pd_status) \
},
+
+/*
+ * OMAP730 has a slightly different config for the pin mux.
+ * - config regs are the OMAP730_IO_CONF_x regs (see omap730.h) regs and
+ * not the FUNC_MUX_CTRL_x regs from hardware.h
+ * - for pull-up/down, only has one enable bit which is is in the same register
+ * as mux config
+ */
+#define MUX_CFG_730(desc, mux_reg, mode_offset, mode, \
+ pull_reg, pull_bit, pull_status, \
+ pu_pd_reg, pu_pd_status, debug_status)\
+{ \
+ .name = desc, \
+ .debug = debug_status, \
+ MUX_REG_730(mux_reg, mode_offset, mode) \
+ PULL_REG_730(mux_reg, pull_bit, pull_status) \
+ PU_PD_REG(pu_pd_reg, pu_pd_status) \
+},
+
+#define MUX_CFG_24XX(desc, reg_offset, mode, \
+ pull_en, pull_mode, dbg) \
+{ \
+ .name = desc, \
+ .debug = dbg, \
+ .mux_reg = reg_offset, \
+ .mask = mode, \
+ .pull_val = pull_en, \
+ .pu_pd_val = pull_mode, \
+},
+
+
#define PULL_DISABLED 0
#define PULL_ENABLED 1
#define PULL_DOWN 0
#define PULL_UP 1
-typedef struct {
+struct pin_config {
char *name;
unsigned char busy;
unsigned char debug;
@@ -108,13 +158,23 @@ typedef struct {
const char *pu_pd_name;
const unsigned int pu_pd_reg;
const unsigned char pu_pd_val;
-} reg_cfg_set;
+};
-/*
- * Lookup table for FUNC_MUX and PULL_DWN register combinations for each
- * device. See also reg_cfg_table below for the register values.
- */
-typedef enum {
+enum omap730_index {
+ /* OMAP 730 keyboard */
+ E2_730_KBR0,
+ J7_730_KBR1,
+ E1_730_KBR2,
+ F3_730_KBR3,
+ D2_730_KBR4,
+ C2_730_KBC0,
+ D3_730_KBC1,
+ E4_730_KBC2,
+ F4_730_KBC3,
+ E3_730_KBC4,
+};
+
+enum omap1xxx_index {
/* UART1 (BT_UART_GATING)*/
UART1_TX = 0,
UART1_RTS,
@@ -331,245 +391,34 @@ typedef enum {
V10_1610_CF_IREQ,
W10_1610_CF_RESET,
W11_1610_CF_CD1,
-} reg_cfg_t;
+};
-#if defined(__MUX_C__) && defined(CONFIG_OMAP_MUX)
+enum omap24xx_index {
+ /* 24xx I2C */
+ M19_24XX_I2C1_SCL,
+ L15_24XX_I2C1_SDA,
+ J15_24XX_I2C2_SCL,
+ H19_24XX_I2C2_SDA,
-/*
- * Table of various FUNC_MUX and PULL_DWN combinations for each device.
- * See also reg_cfg_t above for the lookup table.
- */
-static const reg_cfg_set __initdata_or_module
-reg_cfg_table[] = {
-/*
- * description mux mode mux pull pull pull pu_pd pu dbg
- * reg offset mode reg bit ena reg
- */
-MUX_CFG("UART1_TX", 9, 21, 1, 2, 3, 0, NA, 0, 0)
-MUX_CFG("UART1_RTS", 9, 12, 1, 2, 0, 0, NA, 0, 0)
-
-/* UART2 (COM_UART_GATING), conflicts with USB2 */
-MUX_CFG("UART2_TX", C, 27, 1, 3, 3, 0, NA, 0, 0)
-MUX_CFG("UART2_RX", C, 18, 0, 3, 1, 1, NA, 0, 0)
-MUX_CFG("UART2_CTS", C, 21, 0, 3, 1, 1, NA, 0, 0)
-MUX_CFG("UART2_RTS", C, 24, 1, 3, 2, 0, NA, 0, 0)
-
-/* UART3 (GIGA_UART_GATING) */
-MUX_CFG("UART3_TX", 6, 0, 1, 0, 30, 0, NA, 0, 0)
-MUX_CFG("UART3_RX", 6, 3, 0, 0, 31, 1, NA, 0, 0)
-MUX_CFG("UART3_CTS", 5, 12, 2, 0, 24, 0, NA, 0, 0)
-MUX_CFG("UART3_RTS", 5, 15, 2, 0, 25, 0, NA, 0, 0)
-MUX_CFG("UART3_CLKREQ", 9, 27, 0, 2, 5, 0, NA, 0, 0)
-MUX_CFG("UART3_BCLK", A, 0, 0, 2, 6, 0, NA, 0, 0)
-MUX_CFG("Y15_1610_UART3_RTS", A, 0, 1, 2, 6, 0, NA, 0, 0)
-
-/* PWT & PWL, conflicts with UART3 */
-MUX_CFG("PWT", 6, 0, 2, 0, 30, 0, NA, 0, 0)
-MUX_CFG("PWL", 6, 3, 1, 0, 31, 1, NA, 0, 0)
-
-/* USB internal master generic */
-MUX_CFG("R18_USB_VBUS", 7, 9, 2, 1, 11, 0, NA, 0, 1)
-MUX_CFG("R18_1510_USB_GPIO0", 7, 9, 0, 1, 11, 1, NA, 0, 1)
-/* works around erratum: W4_USB_PUEN and W4_USB_PUDIS are switched! */
-MUX_CFG("W4_USB_PUEN", D, 3, 3, 3, 5, 1, NA, 0, 1)
-MUX_CFG("W4_USB_CLKO", D, 3, 1, 3, 5, 0, NA, 0, 1)
-MUX_CFG("W4_USB_HIGHZ", D, 3, 4, 3, 5, 0, 3, 0, 1)
-MUX_CFG("W4_GPIO58", D, 3, 7, 3, 5, 0, 3, 0, 1)
-
-/* USB1 master */
-MUX_CFG("USB1_SUSP", 8, 27, 2, 1, 27, 0, NA, 0, 1)
-MUX_CFG("USB1_SE0", 9, 0, 2, 1, 28, 0, NA, 0, 1)
-MUX_CFG("W13_1610_USB1_SE0", 9, 0, 4, 1, 28, 0, NA, 0, 1)
-MUX_CFG("USB1_TXEN", 9, 3, 2, 1, 29, 0, NA, 0, 1)
-MUX_CFG("USB1_TXD", 9, 24, 1, 2, 4, 0, NA, 0, 1)
-MUX_CFG("USB1_VP", A, 3, 1, 2, 7, 0, NA, 0, 1)
-MUX_CFG("USB1_VM", A, 6, 1, 2, 8, 0, NA, 0, 1)
-MUX_CFG("USB1_RCV", A, 9, 1, 2, 9, 0, NA, 0, 1)
-MUX_CFG("USB1_SPEED", A, 12, 2, 2, 10, 0, NA, 0, 1)
-MUX_CFG("R13_1610_USB1_SPEED", A, 12, 5, 2, 10, 0, NA, 0, 1)
-MUX_CFG("R13_1710_USB1_SEO", A, 12, 5, 2, 10, 0, NA, 0, 1)
-
-/* USB2 master */
-MUX_CFG("USB2_SUSP", B, 3, 1, 2, 17, 0, NA, 0, 1)
-MUX_CFG("USB2_VP", B, 6, 1, 2, 18, 0, NA, 0, 1)
-MUX_CFG("USB2_TXEN", B, 9, 1, 2, 19, 0, NA, 0, 1)
-MUX_CFG("USB2_VM", C, 18, 1, 3, 0, 0, NA, 0, 1)
-MUX_CFG("USB2_RCV", C, 21, 1, 3, 1, 0, NA, 0, 1)
-MUX_CFG("USB2_SE0", C, 24, 2, 3, 2, 0, NA, 0, 1)
-MUX_CFG("USB2_TXD", C, 27, 2, 3, 3, 0, NA, 0, 1)
-
-/* OMAP-1510 GPIO */
-MUX_CFG("R18_1510_GPIO0", 7, 9, 0, 1, 11, 1, 0, 0, 1)
-MUX_CFG("R19_1510_GPIO1", 7, 6, 0, 1, 10, 1, 0, 0, 1)
-MUX_CFG("M14_1510_GPIO2", 7, 3, 0, 1, 9, 1, 0, 0, 1)
-
-/* OMAP1610 GPIO */
-MUX_CFG("P18_1610_GPIO3", 7, 0, 0, 1, 8, 0, NA, 0, 1)
-MUX_CFG("Y15_1610_GPIO17", A, 0, 7, 2, 6, 0, NA, 0, 1)
-
-/* OMAP-1710 GPIO */
-MUX_CFG("R18_1710_GPIO0", 7, 9, 0, 1, 11, 1, 1, 1, 1)
-MUX_CFG("V2_1710_GPIO10", F, 27, 1, 4, 3, 1, 4, 1, 1)
-MUX_CFG("N21_1710_GPIO14", 6, 9, 0, 1, 1, 1, 1, 1, 1)
-MUX_CFG("W15_1710_GPIO40", 9, 27, 7, 2, 5, 1, 2, 1, 1)
-
-/* MPUIO */
-MUX_CFG("MPUIO2", 7, 18, 0, 1, 14, 1, NA, 0, 1)
-MUX_CFG("N15_1610_MPUIO2", 7, 18, 0, 1, 14, 1, 1, 0, 1)
-MUX_CFG("MPUIO4", 7, 15, 0, 1, 13, 1, NA, 0, 1)
-MUX_CFG("MPUIO5", 7, 12, 0, 1, 12, 1, NA, 0, 1)
-
-MUX_CFG("T20_1610_MPUIO5", 7, 12, 0, 1, 12, 0, 3, 0, 1)
-MUX_CFG("W11_1610_MPUIO6", 10, 15, 2, 3, 8, 0, 3, 0, 1)
-MUX_CFG("V10_1610_MPUIO7", A, 24, 2, 2, 14, 0, 2, 0, 1)
-MUX_CFG("W11_1610_MPUIO9", 10, 15, 1, 3, 8, 0, 3, 0, 1)
-MUX_CFG("V10_1610_MPUIO10", A, 24, 1, 2, 14, 0, 2, 0, 1)
-MUX_CFG("W10_1610_MPUIO11", A, 18, 2, 2, 11, 0, 2, 0, 1)
-MUX_CFG("E20_1610_MPUIO13", 3, 21, 1, 0, 7, 0, 0, 0, 1)
-MUX_CFG("U20_1610_MPUIO14", 9, 6, 6, 0, 30, 0, 0, 0, 1)
-MUX_CFG("E19_1610_MPUIO15", 3, 18, 1, 0, 6, 0, 0, 0, 1)
-
-/* MCBSP2 */
-MUX_CFG("MCBSP2_CLKR", C, 6, 0, 2, 27, 1, NA, 0, 1)
-MUX_CFG("MCBSP2_CLKX", C, 9, 0, 2, 29, 1, NA, 0, 1)
-MUX_CFG("MCBSP2_DR", C, 0, 0, 2, 26, 1, NA, 0, 1)
-MUX_CFG("MCBSP2_DX", C, 15, 0, 2, 31, 1, NA, 0, 1)
-MUX_CFG("MCBSP2_FSR", C, 12, 0, 2, 30, 1, NA, 0, 1)
-MUX_CFG("MCBSP2_FSX", C, 3, 0, 2, 27, 1, NA, 0, 1)
-
-/* MCBSP3 NOTE: Mode must 1 for clock */
-MUX_CFG("MCBSP3_CLKX", 9, 3, 1, 1, 29, 0, NA, 0, 1)
-
-/* Misc ballouts */
-MUX_CFG("BALLOUT_V8_ARMIO3", B, 18, 0, 2, 25, 1, NA, 0, 1)
-MUX_CFG("N20_HDQ", 6, 18, 1, 1, 4, 0, 1, 4, 0)
-
-/* OMAP-1610 MMC2 */
-MUX_CFG("W8_1610_MMC2_DAT0", B, 21, 6, 2, 23, 1, 2, 1, 1)
-MUX_CFG("V8_1610_MMC2_DAT1", B, 27, 6, 2, 25, 1, 2, 1, 1)
-MUX_CFG("W15_1610_MMC2_DAT2", 9, 12, 6, 2, 5, 1, 2, 1, 1)
-MUX_CFG("R10_1610_MMC2_DAT3", B, 18, 6, 2, 22, 1, 2, 1, 1)
-MUX_CFG("Y10_1610_MMC2_CLK", B, 3, 6, 2, 17, 0, 2, 0, 1)
-MUX_CFG("Y8_1610_MMC2_CMD", B, 24, 6, 2, 24, 1, 2, 1, 1)
-MUX_CFG("V9_1610_MMC2_CMDDIR", B, 12, 6, 2, 20, 0, 2, 1, 1)
-MUX_CFG("V5_1610_MMC2_DATDIR0", B, 15, 6, 2, 21, 0, 2, 1, 1)
-MUX_CFG("W19_1610_MMC2_DATDIR1", 8, 15, 6, 1, 23, 0, 1, 1, 1)
-MUX_CFG("R18_1610_MMC2_CLKIN", 7, 9, 6, 1, 11, 0, 1, 11, 1)
-
-/* OMAP-1610 External Trace Interface */
-MUX_CFG("M19_1610_ETM_PSTAT0", 5, 27, 1, 0, 29, 0, 0, 0, 1)
-MUX_CFG("L15_1610_ETM_PSTAT1", 5, 24, 1, 0, 28, 0, 0, 0, 1)
-MUX_CFG("L18_1610_ETM_PSTAT2", 5, 21, 1, 0, 27, 0, 0, 0, 1)
-MUX_CFG("L19_1610_ETM_D0", 5, 18, 1, 0, 26, 0, 0, 0, 1)
-MUX_CFG("J19_1610_ETM_D6", 5, 0, 1, 0, 20, 0, 0, 0, 1)
-MUX_CFG("J18_1610_ETM_D7", 5, 27, 1, 0, 19, 0, 0, 0, 1)
-
-/* OMAP16XX GPIO */
-MUX_CFG("P20_1610_GPIO4", 6, 27, 0, 1, 7, 0, 1, 1, 1)
-MUX_CFG("V9_1610_GPIO7", B, 12, 1, 2, 20, 0, 2, 1, 1)
-MUX_CFG("W8_1610_GPIO9", B, 21, 0, 2, 23, 0, 2, 1, 1)
-MUX_CFG("N20_1610_GPIO11", 6, 18, 0, 1, 4, 0, 1, 1, 1)
-MUX_CFG("N19_1610_GPIO13", 6, 12, 0, 1, 2, 0, 1, 1, 1)
-MUX_CFG("P10_1610_GPIO22", C, 0, 7, 2, 26, 0, 2, 1, 1)
-MUX_CFG("V5_1610_GPIO24", B, 15, 7, 2, 21, 0, 2, 1, 1)
-MUX_CFG("AA20_1610_GPIO_41", 9, 9, 7, 1, 31, 0, 1, 1, 1)
-MUX_CFG("W19_1610_GPIO48", 8, 15, 7, 1, 23, 1, 1, 0, 1)
-MUX_CFG("M7_1610_GPIO62", 10, 0, 0, 4, 24, 0, 4, 0, 1)
-MUX_CFG("V14_16XX_GPIO37", 9, 18, 7, 2, 2, 0, 2, 2, 0)
-MUX_CFG("R9_16XX_GPIO18", C, 18, 7, 3, 0, 0, 3, 0, 0)
-MUX_CFG("L14_16XX_GPIO49", 6, 3, 7, 0, 31, 0, 0, 31, 0)
-
-/* OMAP-1610 uWire */
-MUX_CFG("V19_1610_UWIRE_SCLK", 8, 6, 0, 1, 20, 0, 1, 1, 1)
-MUX_CFG("U18_1610_UWIRE_SDI", 8, 0, 0, 1, 18, 0, 1, 1, 1)
-MUX_CFG("W21_1610_UWIRE_SDO", 8, 3, 0, 1, 19, 0, 1, 1, 1)
-MUX_CFG("N14_1610_UWIRE_CS0", 8, 9, 1, 1, 21, 0, 1, 1, 1)
-MUX_CFG("P15_1610_UWIRE_CS3", 8, 12, 1, 1, 22, 0, 1, 1, 1)
-MUX_CFG("N15_1610_UWIRE_CS1", 7, 18, 2, 1, 14, 0, NA, 0, 1)
-
-/* OMAP-1610 Flash */
-MUX_CFG("L3_1610_FLASH_CS2B_OE",10, 6, 1, NA, 0, 0, NA, 0, 1)
-MUX_CFG("M8_1610_FLASH_CS2B_WE",10, 3, 1, NA, 0, 0, NA, 0, 1)
-
-/* First MMC interface, same on 1510, 1610 and 1710 */
-MUX_CFG("MMC_CMD", A, 27, 0, 2, 15, 1, 2, 1, 1)
-MUX_CFG("MMC_DAT1", A, 24, 0, 2, 14, 1, 2, 1, 1)
-MUX_CFG("MMC_DAT2", A, 18, 0, 2, 12, 1, 2, 1, 1)
-MUX_CFG("MMC_DAT0", B, 0, 0, 2, 16, 1, 2, 1, 1)
-MUX_CFG("MMC_CLK", A, 21, 0, NA, 0, 0, NA, 0, 1)
-MUX_CFG("MMC_DAT3", 10, 15, 0, 3, 8, 1, 3, 1, 1)
-MUX_CFG("M15_1710_MMC_CLKI", 6, 21, 2, 0, 0, 0, NA, 0, 1)
-MUX_CFG("P19_1710_MMC_CMDDIR", 6, 24, 6, 0, 0, 0, NA, 0, 1)
-MUX_CFG("P20_1710_MMC_DATDIR0", 6, 27, 5, 0, 0, 0, NA, 0, 1)
-
-/* OMAP-1610 USB0 alternate configuration */
-MUX_CFG("W9_USB0_TXEN", B, 9, 5, 2, 19, 0, 2, 0, 1)
-MUX_CFG("AA9_USB0_VP", B, 6, 5, 2, 18, 0, 2, 0, 1)
-MUX_CFG("Y5_USB0_RCV", C, 21, 5, 3, 1, 0, 1, 0, 1)
-MUX_CFG("R9_USB0_VM", C, 18, 5, 3, 0, 0, 3, 0, 1)
-MUX_CFG("V6_USB0_TXD", C, 27, 5, 3, 3, 0, 3, 0, 1)
-MUX_CFG("W5_USB0_SE0", C, 24, 5, 3, 2, 0, 3, 0, 1)
-MUX_CFG("V9_USB0_SPEED", B, 12, 5, 2, 20, 0, 2, 0, 1)
-MUX_CFG("Y10_USB0_SUSP", B, 3, 5, 2, 17, 0, 2, 0, 1)
-
-/* USB2 interface */
-MUX_CFG("W9_USB2_TXEN", B, 9, 1, NA, 0, 0, NA, 0, 1)
-MUX_CFG("AA9_USB2_VP", B, 6, 1, NA, 0, 0, NA, 0, 1)
-MUX_CFG("Y5_USB2_RCV", C, 21, 1, NA, 0, 0, NA, 0, 1)
-MUX_CFG("R9_USB2_VM", C, 18, 1, NA, 0, 0, NA, 0, 1)
-MUX_CFG("V6_USB2_TXD", C, 27, 2, NA, 0, 0, NA, 0, 1)
-MUX_CFG("W5_USB2_SE0", C, 24, 2, NA, 0, 0, NA, 0, 1)
-
-/* 16XX UART */
-MUX_CFG("R13_1610_UART1_TX", A, 12, 6, 2, 10, 0, 2, 10, 1)
-MUX_CFG("V14_16XX_UART1_RX", 9, 18, 0, 2, 2, 0, 2, 2, 1)
-MUX_CFG("R14_1610_UART1_CTS", 9, 15, 0, 2, 1, 0, 2, 1, 1)
-MUX_CFG("AA15_1610_UART1_RTS", 9, 12, 1, 2, 0, 0, 2, 0, 1)
-MUX_CFG("R9_16XX_UART2_RX", C, 18, 0, 3, 0, 0, 3, 0, 1)
-MUX_CFG("L14_16XX_UART3_RX", 6, 3, 0, 0, 31, 0, 0, 31, 1)
-
-/* I2C interface */
-MUX_CFG("I2C_SCL", 7, 24, 0, NA, 0, 0, NA, 0, 0)
-MUX_CFG("I2C_SDA", 7, 27, 0, NA, 0, 0, NA, 0, 0)
-
-/* Keypad */
-MUX_CFG("F18_1610_KBC0", 3, 15, 0, 0, 5, 1, 0, 0, 0)
-MUX_CFG("D20_1610_KBC1", 3, 12, 0, 0, 4, 1, 0, 0, 0)
-MUX_CFG("D19_1610_KBC2", 3, 9, 0, 0, 3, 1, 0, 0, 0)
-MUX_CFG("E18_1610_KBC3", 3, 6, 0, 0, 2, 1, 0, 0, 0)
-MUX_CFG("C21_1610_KBC4", 3, 3, 0, 0, 1, 1, 0, 0, 0)
-MUX_CFG("G18_1610_KBR0", 4, 0, 0, 0, 10, 1, 0, 1, 0)
-MUX_CFG("F19_1610_KBR1", 3, 27, 0, 0, 9, 1, 0, 1, 0)
-MUX_CFG("H14_1610_KBR2", 3, 24, 0, 0, 8, 1, 0, 1, 0)
-MUX_CFG("E20_1610_KBR3", 3, 21, 0, 0, 7, 1, 0, 1, 0)
-MUX_CFG("E19_1610_KBR4", 3, 18, 0, 0, 6, 1, 0, 1, 0)
-MUX_CFG("N19_1610_KBR5", 6, 12, 1, 1, 2, 1, 1, 1, 0)
-
-/* Power management */
-MUX_CFG("T20_1610_LOW_PWR", 7, 12, 1, NA, 0, 0, NA, 0, 0)
-
-/* MCLK Settings */
-MUX_CFG("V5_1710_MCLK_ON", B, 15, 0, NA, 0, 0, NA, 0, 0)
-MUX_CFG("V5_1710_MCLK_OFF", B, 15, 6, NA, 0, 0, NA, 0, 0)
-MUX_CFG("R10_1610_MCLK_ON", B, 18, 0, NA, 22, 0, NA, 1, 0)
-MUX_CFG("R10_1610_MCLK_OFF", B, 18, 6, 2, 22, 1, 2, 1, 1)
-
-/* CompactFlash controller, conflicts with MMC1 */
-MUX_CFG("P11_1610_CF_CD2", A, 27, 3, 2, 15, 1, 2, 1, 1)
-MUX_CFG("R11_1610_CF_IOIS16", B, 0, 3, 2, 16, 1, 2, 1, 1)
-MUX_CFG("V10_1610_CF_IREQ", A, 24, 3, 2, 14, 0, 2, 0, 1)
-MUX_CFG("W10_1610_CF_RESET", A, 18, 3, 2, 12, 1, 2, 1, 1)
-MUX_CFG("W11_1610_CF_CD1", 10, 15, 3, 3, 8, 1, 3, 1, 1)
-};
+ /* 24xx Menelaus interrupt */
+ W19_24XX_SYS_NIRQ,
-#endif /* __MUX_C__ */
+ /* 24xx GPIO */
+ Y20_24XX_GPIO60,
+ M15_24XX_GPIO92,
+};
#ifdef CONFIG_OMAP_MUX
/* setup pin muxing in Linux */
-extern int omap_cfg_reg(reg_cfg_t reg_cfg);
+extern int omap1_mux_init(void);
+extern int omap2_mux_init(void);
+extern int omap_mux_register(struct pin_config * pins, unsigned long size);
+extern int omap_cfg_reg(unsigned long reg_cfg);
#else
/* boot loader does it all (no warnings from CONFIG_OMAP_MUX_WARNINGS) */
-static inline int omap_cfg_reg(reg_cfg_t reg_cfg) { return 0; }
+static inline int omap1_mux_init(void) { return 0; }
+static inline int omap2_mux_init(void) { return 0; }
+static inline int omap_cfg_reg(unsigned long reg_cfg) { return 0; }
#endif
#endif
diff --git a/include/asm-arm/arch-omap/omap1510.h b/include/asm-arm/arch-omap/omap1510.h
index f086a3933906..c575d354850f 100644
--- a/include/asm-arm/arch-omap/omap1510.h
+++ b/include/asm-arm/arch-omap/omap1510.h
@@ -25,8 +25,8 @@
* 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#ifndef __ASM_ARCH_OMAP1510_H
-#define __ASM_ARCH_OMAP1510_H
+#ifndef __ASM_ARCH_OMAP15XX_H
+#define __ASM_ARCH_OMAP15XX_H
/*
* ----------------------------------------------------------------------------
@@ -44,5 +44,5 @@
#define OMAP1510_DSPREG_SIZE SZ_128K
#define OMAP1510_DSPREG_START 0xE1000000
-#endif /* __ASM_ARCH_OMAP1510_H */
+#endif /* __ASM_ARCH_OMAP15XX_H */
diff --git a/include/asm-arm/arch-omap/omap24xx.h b/include/asm-arm/arch-omap/omap24xx.h
index a9105466a417..6e59805fa654 100644
--- a/include/asm-arm/arch-omap/omap24xx.h
+++ b/include/asm-arm/arch-omap/omap24xx.h
@@ -1,15 +1,24 @@
#ifndef __ASM_ARCH_OMAP24XX_H
#define __ASM_ARCH_OMAP24XX_H
-#define OMAP24XX_L4_IO_BASE 0x48000000
+/*
+ * Please place only base defines here and put the rest in device
+ * specific headers. Note also that some of these defines are needed
+ * for omap1 to compile without adding ifdefs.
+ */
+
+#define L4_24XX_BASE 0x48000000
+#define L3_24XX_BASE 0x68000000
/* interrupt controller */
-#define OMAP24XX_IC_BASE (OMAP24XX_L4_IO_BASE + 0xfe000)
+#define OMAP24XX_IC_BASE (L4_24XX_BASE + 0xfe000)
#define VA_IC_BASE IO_ADDRESS(OMAP24XX_IC_BASE)
-
#define OMAP24XX_IVA_INTC_BASE 0x40000000
-
#define IRQ_SIR_IRQ 0x0040
+#define OMAP24XX_32KSYNCT_BASE (L4_24XX_BASE + 0x4000)
+#define OMAP24XX_PRCM_BASE (L4_24XX_BASE + 0x8000)
+#define OMAP24XX_SDRC_BASE (L3_24XX_BASE + 0x9000)
+
#endif /* __ASM_ARCH_OMAP24XX_H */
diff --git a/include/asm-arm/arch-omap/omapfb.h b/include/asm-arm/arch-omap/omapfb.h
new file mode 100644
index 000000000000..4ba2622cc142
--- /dev/null
+++ b/include/asm-arm/arch-omap/omapfb.h
@@ -0,0 +1,281 @@
+/*
+ * File: include/asm-arm/arch-omap/omapfb.h
+ *
+ * Framebuffer driver for TI OMAP boards
+ *
+ * Copyright (C) 2004 Nokia Corporation
+ * Author: Imre Deak <imre.deak@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by 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 __OMAPFB_H
+#define __OMAPFB_H
+
+/* IOCTL commands. */
+
+#define OMAP_IOW(num, dtype) _IOW('O', num, dtype)
+#define OMAP_IOR(num, dtype) _IOR('O', num, dtype)
+#define OMAP_IOWR(num, dtype) _IOWR('O', num, dtype)
+#define OMAP_IO(num) _IO('O', num)
+
+#define OMAPFB_MIRROR OMAP_IOW(31, int)
+#define OMAPFB_SYNC_GFX OMAP_IO(37)
+#define OMAPFB_VSYNC OMAP_IO(38)
+#define OMAPFB_SET_UPDATE_MODE OMAP_IOW(40, enum omapfb_update_mode)
+#define OMAPFB_GET_CAPS OMAP_IOR(42, unsigned long)
+#define OMAPFB_GET_UPDATE_MODE OMAP_IOW(43, enum omapfb_update_mode)
+#define OMAPFB_LCD_TEST OMAP_IOW(45, int)
+#define OMAPFB_CTRL_TEST OMAP_IOW(46, int)
+#define OMAPFB_UPDATE_WINDOW OMAP_IOW(47, struct omapfb_update_window)
+#define OMAPFB_SETUP_PLANE OMAP_IOW(48, struct omapfb_setup_plane)
+#define OMAPFB_ENABLE_PLANE OMAP_IOW(49, struct omapfb_enable_plane)
+#define OMAPFB_SET_COLOR_KEY OMAP_IOW(50, struct omapfb_color_key)
+
+#define OMAPFB_CAPS_GENERIC_MASK 0x00000fff
+#define OMAPFB_CAPS_LCDC_MASK 0x00fff000
+#define OMAPFB_CAPS_PANEL_MASK 0xff000000
+
+#define OMAPFB_CAPS_MANUAL_UPDATE 0x00001000
+#define OMAPFB_CAPS_SET_BACKLIGHT 0x01000000
+
+/* Values from DSP must map to lower 16-bits */
+#define OMAPFB_FORMAT_MASK 0x00ff
+#define OMAPFB_FORMAT_FLAG_DOUBLE 0x0100
+
+enum omapfb_color_format {
+ OMAPFB_COLOR_RGB565 = 0,
+ OMAPFB_COLOR_YUV422,
+ OMAPFB_COLOR_YUV420,
+ OMAPFB_COLOR_CLUT_8BPP,
+ OMAPFB_COLOR_CLUT_4BPP,
+ OMAPFB_COLOR_CLUT_2BPP,
+ OMAPFB_COLOR_CLUT_1BPP,
+};
+
+struct omapfb_update_window {
+ u32 x, y;
+ u32 width, height;
+ u32 format;
+};
+
+enum omapfb_plane {
+ OMAPFB_PLANE_GFX = 0,
+ OMAPFB_PLANE_VID1,
+ OMAPFB_PLANE_VID2,
+};
+
+enum omapfb_channel_out {
+ OMAPFB_CHANNEL_OUT_LCD = 0,
+ OMAPFB_CHANNEL_OUT_DIGIT,
+};
+
+struct omapfb_setup_plane {
+ u8 plane;
+ u8 channel_out;
+ u32 offset;
+ u32 pos_x, pos_y;
+ u32 width, height;
+ u32 color_mode;
+};
+
+struct omapfb_enable_plane {
+ u8 plane;
+ u8 enable;
+};
+
+enum omapfb_color_key_type {
+ OMAPFB_COLOR_KEY_DISABLED = 0,
+ OMAPFB_COLOR_KEY_GFX_DST,
+ OMAPFB_COLOR_KEY_VID_SRC,
+};
+
+struct omapfb_color_key {
+ u8 channel_out;
+ u32 background;
+ u32 trans_key;
+ u8 key_type;
+};
+
+enum omapfb_update_mode {
+ OMAPFB_UPDATE_DISABLED = 0,
+ OMAPFB_AUTO_UPDATE,
+ OMAPFB_MANUAL_UPDATE
+};
+
+#ifdef __KERNEL__
+
+#include <linux/completion.h>
+#include <linux/interrupt.h>
+#include <linux/fb.h>
+
+#define OMAP_LCDC_INV_VSYNC 0x0001
+#define OMAP_LCDC_INV_HSYNC 0x0002
+#define OMAP_LCDC_INV_PIX_CLOCK 0x0004
+#define OMAP_LCDC_INV_OUTPUT_EN 0x0008
+#define OMAP_LCDC_HSVS_RISING_EDGE 0x0010
+#define OMAP_LCDC_HSVS_OPPOSITE 0x0020
+
+#define OMAP_LCDC_SIGNAL_MASK 0x003f
+
+#define OMAP_LCDC_PANEL_TFT 0x0100
+
+#ifdef CONFIG_ARCH_OMAP1
+#define OMAPFB_PLANE_NUM 1
+#else
+#define OMAPFB_PLANE_NUM 3
+#endif
+
+struct omapfb_device;
+
+struct lcd_panel {
+ const char *name;
+ int config; /* TFT/STN, signal inversion */
+ int bpp; /* Pixel format in fb mem */
+ int data_lines; /* Lines on LCD HW interface */
+
+ int x_res, y_res;
+ int pixel_clock; /* In kHz */
+ int hsw; /* Horizontal synchronization
+ pulse width */
+ int hfp; /* Horizontal front porch */
+ int hbp; /* Horizontal back porch */
+ int vsw; /* Vertical synchronization
+ pulse width */
+ int vfp; /* Vertical front porch */
+ int vbp; /* Vertical back porch */
+ int acb; /* ac-bias pin frequency */
+ int pcd; /* pixel clock divider.
+ Obsolete use pixel_clock instead */
+
+ int (*init) (struct omapfb_device *fbdev);
+ void (*cleanup) (void);
+ int (*enable) (void);
+ void (*disable) (void);
+ unsigned long (*get_caps) (void);
+ int (*set_bklight_level)(unsigned int level);
+ unsigned int (*get_bklight_level)(void);
+ unsigned int (*get_bklight_max) (void);
+ int (*run_test) (int test_num);
+};
+
+struct omapfb_device;
+
+struct extif_timings {
+ int cs_on_time;
+ int cs_off_time;
+ int we_on_time;
+ int we_off_time;
+ int re_on_time;
+ int re_off_time;
+ int we_cycle_time;
+ int re_cycle_time;
+ int cs_pulse_width;
+ int access_time;
+};
+
+struct lcd_ctrl_extif {
+ int (*init) (void);
+ void (*cleanup) (void);
+ void (*set_timings) (const struct extif_timings *timings);
+ void (*write_command) (u32 cmd);
+ u32 (*read_data) (void);
+ void (*write_data) (u32 data);
+ void (*transfer_area) (int width, int height,
+ void (callback)(void * data), void *data);
+};
+
+struct lcd_ctrl {
+ const char *name;
+ void *data;
+
+ int (*init) (struct omapfb_device *fbdev,
+ int ext_mode, int req_vram_size);
+ void (*cleanup) (void);
+ void (*get_vram_layout)(unsigned long *size,
+ void **virt_base,
+ dma_addr_t *phys_base);
+ unsigned long (*get_caps) (void);
+ int (*set_update_mode)(enum omapfb_update_mode mode);
+ enum omapfb_update_mode (*get_update_mode)(void);
+ int (*setup_plane) (int plane, int channel_out,
+ unsigned long offset,
+ int screen_width,
+ int pos_x, int pos_y, int width,
+ int height, int color_mode);
+ int (*enable_plane) (int plane, int enable);
+ int (*update_window) (struct omapfb_update_window *win,
+ void (*callback)(void *),
+ void *callback_data);
+ void (*sync) (void);
+ void (*suspend) (void);
+ void (*resume) (void);
+ int (*run_test) (int test_num);
+ int (*setcolreg) (u_int regno, u16 red, u16 green,
+ u16 blue, u16 transp,
+ int update_hw_mem);
+ int (*set_color_key) (struct omapfb_color_key *ck);
+
+};
+
+enum omapfb_state {
+ OMAPFB_DISABLED = 0,
+ OMAPFB_SUSPENDED= 99,
+ OMAPFB_ACTIVE = 100
+};
+
+struct omapfb_device {
+ int state;
+ int ext_lcdc; /* Using external
+ LCD controller */
+ struct semaphore rqueue_sema;
+
+ void *vram_virt_base;
+ dma_addr_t vram_phys_base;
+ unsigned long vram_size;
+
+ int color_mode;
+ int palette_size;
+ int mirror;
+ u32 pseudo_palette[17];
+
+ struct lcd_panel *panel; /* LCD panel */
+ struct lcd_ctrl *ctrl; /* LCD controller */
+ struct lcd_ctrl *int_ctrl; /* internal LCD ctrl */
+ struct lcd_ctrl_extif *ext_if; /* LCD ctrl external
+ interface */
+ struct fb_info *fb_info;
+
+ struct device *dev;
+};
+
+extern struct lcd_panel h3_panel;
+extern struct lcd_panel h2_panel;
+extern struct lcd_panel p2_panel;
+extern struct lcd_panel osk_panel;
+extern struct lcd_panel innovator1610_panel;
+extern struct lcd_panel innovator1510_panel;
+
+#ifdef CONFIG_ARCH_OMAP1
+extern struct lcd_ctrl omap1_lcd_ctrl;
+#else
+extern struct lcd_ctrl omap2_disp_ctrl;
+#endif
+
+extern void omapfb_write_first_pixel(struct omapfb_device *fbdev, u16 pixval);
+
+#endif /* __KERNEL__ */
+
+#endif /* __OMAPFB_H */
diff --git a/include/asm-arm/arch-omap/pm.h b/include/asm-arm/arch-omap/pm.h
index fbd742d0c499..7c790425e363 100644
--- a/include/asm-arm/arch-omap/pm.h
+++ b/include/asm-arm/arch-omap/pm.h
@@ -98,7 +98,14 @@
#define OMAP1610_IDLECT3 0xfffece24
#define OMAP1610_IDLE_LOOP_REQUEST 0x0400
-#if !defined(CONFIG_ARCH_OMAP1510) && \
+#define OMAP730_IDLECT1_SLEEP_VAL 0x16c7
+#define OMAP730_IDLECT2_SLEEP_VAL 0x09c7
+#define OMAP730_IDLECT3_VAL 0x3f
+#define OMAP730_IDLECT3 0xfffece24
+#define OMAP730_IDLE_LOOP_REQUEST 0x0C00
+
+#if !defined(CONFIG_ARCH_OMAP730) && \
+ !defined(CONFIG_ARCH_OMAP15XX) && \
!defined(CONFIG_ARCH_OMAP16XX) && \
!defined(CONFIG_ARCH_OMAP24XX)
#error "Power management for this processor not implemented yet"
@@ -107,8 +114,10 @@
#ifndef __ASSEMBLER__
extern void omap_pm_idle(void);
extern void omap_pm_suspend(void);
+extern void omap730_cpu_suspend(unsigned short, unsigned short);
extern void omap1510_cpu_suspend(unsigned short, unsigned short);
extern void omap1610_cpu_suspend(unsigned short, unsigned short);
+extern void omap730_idle_loop_suspend(void);
extern void omap1510_idle_loop_suspend(void);
extern void omap1610_idle_loop_suspend(void);
@@ -118,6 +127,8 @@ extern void omap_serial_wake_trigger(int enable);
#define omap_serial_wake_trigger(x) {}
#endif /* CONFIG_OMAP_SERIAL_WAKE */
+extern unsigned int omap730_cpu_suspend_sz;
+extern unsigned int omap730_idle_loop_suspend_sz;
extern unsigned int omap1510_cpu_suspend_sz;
extern unsigned int omap1510_idle_loop_suspend_sz;
extern unsigned int omap1610_cpu_suspend_sz;
@@ -131,6 +142,10 @@ extern unsigned int omap1610_idle_loop_suspend_sz;
#define ULPD_RESTORE(x) omap_writew((ulpd_sleep_save[ULPD_SLEEP_SAVE_##x]), (x))
#define ULPD_SHOW(x) ulpd_sleep_save[ULPD_SLEEP_SAVE_##x]
+#define MPUI730_SAVE(x) mpui730_sleep_save[MPUI730_SLEEP_SAVE_##x] = omap_readl(x)
+#define MPUI730_RESTORE(x) omap_writel((mpui730_sleep_save[MPUI730_SLEEP_SAVE_##x]), (x))
+#define MPUI730_SHOW(x) mpui730_sleep_save[MPUI730_SLEEP_SAVE_##x]
+
#define MPUI1510_SAVE(x) mpui1510_sleep_save[MPUI1510_SLEEP_SAVE_##x] = omap_readl(x)
#define MPUI1510_RESTORE(x) omap_writel((mpui1510_sleep_save[MPUI1510_SLEEP_SAVE_##x]), (x))
#define MPUI1510_SHOW(x) mpui1510_sleep_save[MPUI1510_SLEEP_SAVE_##x]
@@ -188,13 +203,34 @@ enum mpui1510_save_state {
MPUI1510_SLEEP_SAVE_EMIFS_CONFIG,
MPUI1510_SLEEP_SAVE_OMAP_IH1_MIR,
MPUI1510_SLEEP_SAVE_OMAP_IH2_MIR,
-#if defined(CONFIG_ARCH_OMAP1510)
+#if defined(CONFIG_ARCH_OMAP15XX)
MPUI1510_SLEEP_SAVE_SIZE
#else
MPUI1510_SLEEP_SAVE_SIZE = 0
#endif
};
+enum mpui730_save_state {
+ MPUI730_SLEEP_SAVE_START = 0,
+ /*
+ * MPUI registers 32 bits
+ */
+ MPUI730_SLEEP_SAVE_MPUI_CTRL,
+ MPUI730_SLEEP_SAVE_MPUI_DSP_BOOT_CONFIG,
+ MPUI730_SLEEP_SAVE_MPUI_DSP_API_CONFIG,
+ MPUI730_SLEEP_SAVE_MPUI_DSP_STATUS,
+ MPUI730_SLEEP_SAVE_EMIFF_SDRAM_CONFIG,
+ MPUI730_SLEEP_SAVE_EMIFS_CONFIG,
+ MPUI730_SLEEP_SAVE_OMAP_IH1_MIR,
+ MPUI730_SLEEP_SAVE_OMAP_IH2_0_MIR,
+ MPUI730_SLEEP_SAVE_OMAP_IH2_1_MIR,
+#if defined(CONFIG_ARCH_OMAP730)
+ MPUI730_SLEEP_SAVE_SIZE
+#else
+ MPUI730_SLEEP_SAVE_SIZE = 0
+#endif
+};
+
enum mpui1610_save_state {
MPUI1610_SLEEP_SAVE_START = 0,
/*
diff --git a/include/asm-arm/arch-omap/prcm.h b/include/asm-arm/arch-omap/prcm.h
new file mode 100644
index 000000000000..7b48a5cbb15f
--- /dev/null
+++ b/include/asm-arm/arch-omap/prcm.h
@@ -0,0 +1,429 @@
+/*
+ * prcm.h - Access definations for use in OMAP24XX clock and power management
+ *
+ * Copyright (C) 2005 Texas Instruments, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License 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 __ASM_ARM_ARCH_DPM_PRCM_H
+#define __ASM_ARM_ARCH_DPM_PRCM_H
+
+/* SET_PERFORMANCE_LEVEL PARAMETERS */
+#define PRCM_HALF_SPEED 1
+#define PRCM_FULL_SPEED 2
+
+#ifndef __ASSEMBLER__
+
+#define PRCM_REG32(offset) __REG32(OMAP24XX_PRCM_BASE + (offset))
+
+#define PRCM_REVISION PRCM_REG32(0x000)
+#define PRCM_SYSCONFIG PRCM_REG32(0x010)
+#define PRCM_IRQSTATUS_MPU PRCM_REG32(0x018)
+#define PRCM_IRQENABLE_MPU PRCM_REG32(0x01C)
+#define PRCM_VOLTCTRL PRCM_REG32(0x050)
+#define PRCM_VOLTST PRCM_REG32(0x054)
+#define PRCM_CLKSRC_CTRL PRCM_REG32(0x060)
+#define PRCM_CLKOUT_CTRL PRCM_REG32(0x070)
+#define PRCM_CLKEMUL_CTRL PRCM_REG32(0x078)
+#define PRCM_CLKCFG_CTRL PRCM_REG32(0x080)
+#define PRCM_CLKCFG_STATUS PRCM_REG32(0x084)
+#define PRCM_VOLTSETUP PRCM_REG32(0x090)
+#define PRCM_CLKSSETUP PRCM_REG32(0x094)
+#define PRCM_POLCTRL PRCM_REG32(0x098)
+
+/* GENERAL PURPOSE */
+#define GENERAL_PURPOSE1 PRCM_REG32(0x0B0)
+#define GENERAL_PURPOSE2 PRCM_REG32(0x0B4)
+#define GENERAL_PURPOSE3 PRCM_REG32(0x0B8)
+#define GENERAL_PURPOSE4 PRCM_REG32(0x0BC)
+#define GENERAL_PURPOSE5 PRCM_REG32(0x0C0)
+#define GENERAL_PURPOSE6 PRCM_REG32(0x0C4)
+#define GENERAL_PURPOSE7 PRCM_REG32(0x0C8)
+#define GENERAL_PURPOSE8 PRCM_REG32(0x0CC)
+#define GENERAL_PURPOSE9 PRCM_REG32(0x0D0)
+#define GENERAL_PURPOSE10 PRCM_REG32(0x0D4)
+#define GENERAL_PURPOSE11 PRCM_REG32(0x0D8)
+#define GENERAL_PURPOSE12 PRCM_REG32(0x0DC)
+#define GENERAL_PURPOSE13 PRCM_REG32(0x0E0)
+#define GENERAL_PURPOSE14 PRCM_REG32(0x0E4)
+#define GENERAL_PURPOSE15 PRCM_REG32(0x0E8)
+#define GENERAL_PURPOSE16 PRCM_REG32(0x0EC)
+#define GENERAL_PURPOSE17 PRCM_REG32(0x0F0)
+#define GENERAL_PURPOSE18 PRCM_REG32(0x0F4)
+#define GENERAL_PURPOSE19 PRCM_REG32(0x0F8)
+#define GENERAL_PURPOSE20 PRCM_REG32(0x0FC)
+
+/* MPU */
+#define CM_CLKSEL_MPU PRCM_REG32(0x140)
+#define CM_CLKSTCTRL_MPU PRCM_REG32(0x148)
+#define RM_RSTST_MPU PRCM_REG32(0x158)
+#define PM_WKDEP_MPU PRCM_REG32(0x1C8)
+#define PM_EVGENCTRL_MPU PRCM_REG32(0x1D4)
+#define PM_EVEGENONTIM_MPU PRCM_REG32(0x1D8)
+#define PM_EVEGENOFFTIM_MPU PRCM_REG32(0x1DC)
+#define PM_PWSTCTRL_MPU PRCM_REG32(0x1E0)
+#define PM_PWSTST_MPU PRCM_REG32(0x1E4)
+
+/* CORE */
+#define CM_FCLKEN1_CORE PRCM_REG32(0x200)
+#define CM_FCLKEN2_CORE PRCM_REG32(0x204)
+#define CM_FCLKEN3_CORE PRCM_REG32(0x208)
+#define CM_ICLKEN1_CORE PRCM_REG32(0x210)
+#define CM_ICLKEN2_CORE PRCM_REG32(0x214)
+#define CM_ICLKEN3_CORE PRCM_REG32(0x218)
+#define CM_ICLKEN4_CORE PRCM_REG32(0x21C)
+#define CM_IDLEST1_CORE PRCM_REG32(0x220)
+#define CM_IDLEST2_CORE PRCM_REG32(0x224)
+#define CM_IDLEST3_CORE PRCM_REG32(0x228)
+#define CM_IDLEST4_CORE PRCM_REG32(0x22C)
+#define CM_AUTOIDLE1_CORE PRCM_REG32(0x230)
+#define CM_AUTOIDLE2_CORE PRCM_REG32(0x234)
+#define CM_AUTOIDLE3_CORE PRCM_REG32(0x238)
+#define CM_AUTOIDLE4_CORE PRCM_REG32(0x23C)
+#define CM_CLKSEL1_CORE PRCM_REG32(0x240)
+#define CM_CLKSEL2_CORE PRCM_REG32(0x244)
+#define CM_CLKSTCTRL_CORE PRCM_REG32(0x248)
+#define PM_WKEN1_CORE PRCM_REG32(0x2A0)
+#define PM_WKEN2_CORE PRCM_REG32(0x2A4)
+#define PM_WKST1_CORE PRCM_REG32(0x2B0)
+#define PM_WKST2_CORE PRCM_REG32(0x2B4)
+#define PM_WKDEP_CORE PRCM_REG32(0x2C8)
+#define PM_PWSTCTRL_CORE PRCM_REG32(0x2E0)
+#define PM_PWSTST_CORE PRCM_REG32(0x2E4)
+
+/* GFX */
+#define CM_FCLKEN_GFX PRCM_REG32(0x300)
+#define CM_ICLKEN_GFX PRCM_REG32(0x310)
+#define CM_IDLEST_GFX PRCM_REG32(0x320)
+#define CM_CLKSEL_GFX PRCM_REG32(0x340)
+#define CM_CLKSTCTRL_GFX PRCM_REG32(0x348)
+#define RM_RSTCTRL_GFX PRCM_REG32(0x350)
+#define RM_RSTST_GFX PRCM_REG32(0x358)
+#define PM_WKDEP_GFX PRCM_REG32(0x3C8)
+#define PM_PWSTCTRL_GFX PRCM_REG32(0x3E0)
+#define PM_PWSTST_GFX PRCM_REG32(0x3E4)
+
+/* WAKE-UP */
+#define CM_FCLKEN_WKUP PRCM_REG32(0x400)
+#define CM_ICLKEN_WKUP PRCM_REG32(0x410)
+#define CM_IDLEST_WKUP PRCM_REG32(0x420)
+#define CM_AUTOIDLE_WKUP PRCM_REG32(0x430)
+#define CM_CLKSEL_WKUP PRCM_REG32(0x440)
+#define RM_RSTCTRL_WKUP PRCM_REG32(0x450)
+#define RM_RSTTIME_WKUP PRCM_REG32(0x454)
+#define RM_RSTST_WKUP PRCM_REG32(0x458)
+#define PM_WKEN_WKUP PRCM_REG32(0x4A0)
+#define PM_WKST_WKUP PRCM_REG32(0x4B0)
+
+/* CLOCKS */
+#define CM_CLKEN_PLL PRCM_REG32(0x500)
+#define CM_IDLEST_CKGEN PRCM_REG32(0x520)
+#define CM_AUTOIDLE_PLL PRCM_REG32(0x530)
+#define CM_CLKSEL1_PLL PRCM_REG32(0x540)
+#define CM_CLKSEL2_PLL PRCM_REG32(0x544)
+
+/* DSP */
+#define CM_FCLKEN_DSP PRCM_REG32(0x800)
+#define CM_ICLKEN_DSP PRCM_REG32(0x810)
+#define CM_IDLEST_DSP PRCM_REG32(0x820)
+#define CM_AUTOIDLE_DSP PRCM_REG32(0x830)
+#define CM_CLKSEL_DSP PRCM_REG32(0x840)
+#define CM_CLKSTCTRL_DSP PRCM_REG32(0x848)
+#define RM_RSTCTRL_DSP PRCM_REG32(0x850)
+#define RM_RSTST_DSP PRCM_REG32(0x858)
+#define PM_WKEN_DSP PRCM_REG32(0x8A0)
+#define PM_WKDEP_DSP PRCM_REG32(0x8C8)
+#define PM_PWSTCTRL_DSP PRCM_REG32(0x8E0)
+#define PM_PWSTST_DSP PRCM_REG32(0x8E4)
+#define PRCM_IRQSTATUS_DSP PRCM_REG32(0x8F0)
+#define PRCM_IRQENABLE_DSP PRCM_REG32(0x8F4)
+
+/* IVA */
+#define PRCM_IRQSTATUS_IVA PRCM_REG32(0x8F8)
+#define PRCM_IRQENABLE_IVA PRCM_REG32(0x8FC)
+
+/* Modem on 2430 */
+#define CM_FCLKEN_MDM PRCM_REG32(0xC00)
+#define CM_ICLKEN_MDM PRCM_REG32(0xC10)
+#define CM_IDLEST_MDM PRCM_REG32(0xC20)
+#define CM_CLKSEL_MDM PRCM_REG32(0xC40)
+
+/* FIXME: Move to header for 2430 */
+#define DISP_BASE (OMAP24XX_L4_IO_BASE+0x50000)
+#define DISP_REG32(offset) __REG32(DISP_BASE + (offset))
+
+#define OMAP24XX_GPMC_BASE (L3_24XX_BASE + 0xa000)
+#define GPMC_BASE (OMAP24XX_GPMC_BASE)
+#define GPMC_REG32(offset) __REG32(GPMC_BASE + (offset))
+
+#define GPT1_BASE (OMAP24XX_GPT1)
+#define GPT1_REG32(offset) __REG32(GPT1_BASE + (offset))
+
+/* Misc sysconfig */
+#define DISPC_SYSCONFIG DISP_REG32(0x410)
+#define SPI_BASE (OMAP24XX_L4_IO_BASE+0x98000)
+#define MCSPI1_SYSCONFIG __REG32(SPI_BASE + 0x10)
+#define MCSPI2_SYSCONFIG __REG32(SPI_BASE+0x2000 + 0x10)
+
+//#define DSP_MMU_SYSCONFIG 0x5A000010
+#define CAMERA_MMU_SYSCONFIG __REG32(DISP_BASE+0x2C10)
+//#define IVA_MMU_SYSCONFIG 0x5D000010
+//#define DSP_DMA_SYSCONFIG 0x00FCC02C
+#define CAMERA_DMA_SYSCONFIG __REG32(DISP_BASE+0x282C)
+#define SYSTEM_DMA_SYSCONFIG __REG32(DISP_BASE+0x602C)
+#define GPMC_SYSCONFIG GPMC_REG32(0x010)
+#define MAILBOXES_SYSCONFIG __REG32(OMAP24XX_L4_IO_BASE+0x94010)
+#define UART1_SYSCONFIG __REG32(OMAP24XX_L4_IO_BASE+0x6A054)
+#define UART2_SYSCONFIG __REG32(OMAP24XX_L4_IO_BASE+0x6C054)
+#define UART3_SYSCONFIG __REG32(OMAP24XX_L4_IO_BASE+0x6E054)
+//#define IVA_SYSCONFIG 0x5C060010
+#define SDRC_SYSCONFIG __REG32(OMAP24XX_SDRC_BASE+0x10)
+#define SMS_SYSCONFIG __REG32(OMAP24XX_SMS_BASE+0x10)
+#define SSI_SYSCONFIG __REG32(DISP_BASE+0x8010)
+//#define VLYNQ_SYSCONFIG 0x67FFFE10
+
+/* rkw - good cannidates for PM_ to start what nm was trying */
+#define OMAP24XX_GPT2 (OMAP24XX_L4_IO_BASE+0x2A000)
+#define OMAP24XX_GPT3 (OMAP24XX_L4_IO_BASE+0x78000)
+#define OMAP24XX_GPT4 (OMAP24XX_L4_IO_BASE+0x7A000)
+#define OMAP24XX_GPT5 (OMAP24XX_L4_IO_BASE+0x7C000)
+#define OMAP24XX_GPT6 (OMAP24XX_L4_IO_BASE+0x7E000)
+#define OMAP24XX_GPT7 (OMAP24XX_L4_IO_BASE+0x80000)
+#define OMAP24XX_GPT8 (OMAP24XX_L4_IO_BASE+0x82000)
+#define OMAP24XX_GPT9 (OMAP24XX_L4_IO_BASE+0x84000)
+#define OMAP24XX_GPT10 (OMAP24XX_L4_IO_BASE+0x86000)
+#define OMAP24XX_GPT11 (OMAP24XX_L4_IO_BASE+0x88000)
+#define OMAP24XX_GPT12 (OMAP24XX_L4_IO_BASE+0x8A000)
+
+#define GPTIMER1_SYSCONFIG GPT1_REG32(0x010)
+#define GPTIMER2_SYSCONFIG __REG32(OMAP24XX_GPT2 + 0x10)
+#define GPTIMER3_SYSCONFIG __REG32(OMAP24XX_GPT3 + 0x10)
+#define GPTIMER4_SYSCONFIG __REG32(OMAP24XX_GPT4 + 0x10)
+#define GPTIMER5_SYSCONFIG __REG32(OMAP24XX_GPT5 + 0x10)
+#define GPTIMER6_SYSCONFIG __REG32(OMAP24XX_GPT6 + 0x10)
+#define GPTIMER7_SYSCONFIG __REG32(OMAP24XX_GPT7 + 0x10)
+#define GPTIMER8_SYSCONFIG __REG32(OMAP24XX_GPT8 + 0x10)
+#define GPTIMER9_SYSCONFIG __REG32(OMAP24XX_GPT9 + 0x10)
+#define GPTIMER10_SYSCONFIG __REG32(OMAP24XX_GPT10 + 0x10)
+#define GPTIMER11_SYSCONFIG __REG32(OMAP24XX_GPT11 + 0x10)
+#define GPTIMER12_SYSCONFIG __REG32(OMAP24XX_GPT12 + 0x10)
+
+#define GPIOX_BASE(X) (OMAP24XX_GPIO_BASE+(0x2000*((X)-1)))
+
+#define GPIO1_SYSCONFIG __REG32((GPIOX_BASE(1)+0x10))
+#define GPIO2_SYSCONFIG __REG32((GPIOX_BASE(2)+0x10))
+#define GPIO3_SYSCONFIG __REG32((GPIOX_BASE(3)+0x10))
+#define GPIO4_SYSCONFIG __REG32((GPIOX_BASE(4)+0x10))
+
+/* GP TIMER 1 */
+#define GPTIMER1_TISTAT GPT1_REG32(0x014)
+#define GPTIMER1_TISR GPT1_REG32(0x018)
+#define GPTIMER1_TIER GPT1_REG32(0x01C)
+#define GPTIMER1_TWER GPT1_REG32(0x020)
+#define GPTIMER1_TCLR GPT1_REG32(0x024)
+#define GPTIMER1_TCRR GPT1_REG32(0x028)
+#define GPTIMER1_TLDR GPT1_REG32(0x02C)
+#define GPTIMER1_TTGR GPT1_REG32(0x030)
+#define GPTIMER1_TWPS GPT1_REG32(0x034)
+#define GPTIMER1_TMAR GPT1_REG32(0x038)
+#define GPTIMER1_TCAR1 GPT1_REG32(0x03C)
+#define GPTIMER1_TSICR GPT1_REG32(0x040)
+#define GPTIMER1_TCAR2 GPT1_REG32(0x044)
+
+/* rkw -- base fix up please... */
+#define GPTIMER3_TISR __REG32(OMAP24XX_L4_IO_BASE+0x78018)
+
+/* SDRC */
+#define SDRC_DLLA_CTRL __REG32(OMAP24XX_SDRC_BASE+0x060)
+#define SDRC_DLLA_STATUS __REG32(OMAP24XX_SDRC_BASE+0x064)
+#define SDRC_DLLB_CTRL __REG32(OMAP24XX_SDRC_BASE+0x068)
+#define SDRC_DLLB_STATUS __REG32(OMAP24XX_SDRC_BASE+0x06C)
+#define SDRC_POWER __REG32(OMAP24XX_SDRC_BASE+0x070)
+#define SDRC_MR_0 __REG32(OMAP24XX_SDRC_BASE+0x084)
+
+/* GPIO 1 */
+#define GPIO1_BASE GPIOX_BASE(1)
+#define GPIO1_REG32(offset) __REG32(GPIO1_BASE + (offset))
+#define GPIO1_IRQENABLE1 GPIO1_REG32(0x01C)
+#define GPIO1_IRQSTATUS1 GPIO1_REG32(0x018)
+#define GPIO1_IRQENABLE2 GPIO1_REG32(0x02C)
+#define GPIO1_IRQSTATUS2 GPIO1_REG32(0x028)
+#define GPIO1_WAKEUPENABLE GPIO1_REG32(0x020)
+#define GPIO1_RISINGDETECT GPIO1_REG32(0x048)
+#define GPIO1_DATAIN GPIO1_REG32(0x038)
+#define GPIO1_OE GPIO1_REG32(0x034)
+#define GPIO1_DATAOUT GPIO1_REG32(0x03C)
+
+/* GPIO2 */
+#define GPIO2_BASE GPIOX_BASE(2)
+#define GPIO2_REG32(offset) __REG32(GPIO2_BASE + (offset))
+#define GPIO2_IRQENABLE1 GPIO2_REG32(0x01C)
+#define GPIO2_IRQSTATUS1 GPIO2_REG32(0x018)
+#define GPIO2_IRQENABLE2 GPIO2_REG32(0x02C)
+#define GPIO2_IRQSTATUS2 GPIO2_REG32(0x028)
+#define GPIO2_WAKEUPENABLE GPIO2_REG32(0x020)
+#define GPIO2_RISINGDETECT GPIO2_REG32(0x048)
+#define GPIO2_DATAIN GPIO2_REG32(0x038)
+#define GPIO2_OE GPIO2_REG32(0x034)
+#define GPIO2_DATAOUT GPIO2_REG32(0x03C)
+
+/* GPIO 3 */
+#define GPIO3_BASE GPIOX_BASE(3)
+#define GPIO3_REG32(offset) __REG32(GPIO3_BASE + (offset))
+#define GPIO3_IRQENABLE1 GPIO3_REG32(0x01C)
+#define GPIO3_IRQSTATUS1 GPIO3_REG32(0x018)
+#define GPIO3_IRQENABLE2 GPIO3_REG32(0x02C)
+#define GPIO3_IRQSTATUS2 GPIO3_REG32(0x028)
+#define GPIO3_WAKEUPENABLE GPIO3_REG32(0x020)
+#define GPIO3_RISINGDETECT GPIO3_REG32(0x048)
+#define GPIO3_FALLINGDETECT GPIO3_REG32(0x04C)
+#define GPIO3_DATAIN GPIO3_REG32(0x038)
+#define GPIO3_OE GPIO3_REG32(0x034)
+#define GPIO3_DATAOUT GPIO3_REG32(0x03C)
+#define GPIO3_DEBOUNCENABLE GPIO3_REG32(0x050)
+#define GPIO3_DEBOUNCINGTIME GPIO3_REG32(0x054)
+
+/* GPIO 4 */
+#define GPIO4_BASE GPIOX_BASE(4)
+#define GPIO4_REG32(offset) __REG32(GPIO4_BASE + (offset))
+#define GPIO4_IRQENABLE1 GPIO4_REG32(0x01C)
+#define GPIO4_IRQSTATUS1 GPIO4_REG32(0x018)
+#define GPIO4_IRQENABLE2 GPIO4_REG32(0x02C)
+#define GPIO4_IRQSTATUS2 GPIO4_REG32(0x028)
+#define GPIO4_WAKEUPENABLE GPIO4_REG32(0x020)
+#define GPIO4_RISINGDETECT GPIO4_REG32(0x048)
+#define GPIO4_FALLINGDETECT GPIO4_REG32(0x04C)
+#define GPIO4_DATAIN GPIO4_REG32(0x038)
+#define GPIO4_OE GPIO4_REG32(0x034)
+#define GPIO4_DATAOUT GPIO4_REG32(0x03C)
+#define GPIO4_DEBOUNCENABLE GPIO4_REG32(0x050)
+#define GPIO4_DEBOUNCINGTIME GPIO4_REG32(0x054)
+
+
+/* IO CONFIG */
+#define CONTROL_BASE (OMAP24XX_CTRL_BASE)
+#define CONTROL_REG32(offset) __REG32(CONTROL_BASE + (offset))
+
+#define CONTROL_PADCONF_SPI1_NCS2 CONTROL_REG32(0x104)
+#define CONTROL_PADCONF_SYS_XTALOUT CONTROL_REG32(0x134)
+#define CONTROL_PADCONF_UART1_RX CONTROL_REG32(0x0C8)
+#define CONTROL_PADCONF_MCBSP1_DX CONTROL_REG32(0x10C)
+#define CONTROL_PADCONF_GPMC_NCS4 CONTROL_REG32(0x090)
+#define CONTROL_PADCONF_DSS_D5 CONTROL_REG32(0x0B8)
+#define CONTROL_PADCONF_DSS_D9 CONTROL_REG32(0x0BC)
+#define CONTROL_PADCONF_DSS_D13 CONTROL_REG32(0x0C0)
+#define CONTROL_PADCONF_DSS_VSYNC CONTROL_REG32(0x0CC)
+
+/* CONTROL */
+#define CONTROL_DEVCONF CONTROL_REG32(0x274)
+
+/* INTERRUPT CONTROLLER */
+#define INTC_BASE (OMAP24XX_L4_IO_BASE+0xfe000)
+#define INTC_REG32(offset) __REG32(INTC_BASE + (offset))
+
+#define INTC1_U_BASE INTC_REG32(0x000)
+#define INTC_MIR0 INTC_REG32(0x084)
+#define INTC_MIR_SET0 INTC_REG32(0x08C)
+#define INTC_MIR_CLEAR0 INTC_REG32(0x088)
+#define INTC_ISR_CLEAR0 INTC_REG32(0x094)
+#define INTC_MIR1 INTC_REG32(0x0A4)
+#define INTC_MIR_SET1 INTC_REG32(0x0AC)
+#define INTC_MIR_CLEAR1 INTC_REG32(0x0A8)
+#define INTC_ISR_CLEAR1 INTC_REG32(0x0B4)
+#define INTC_MIR2 INTC_REG32(0x0C4)
+#define INTC_MIR_SET2 INTC_REG32(0x0CC)
+#define INTC_MIR_CLEAR2 INTC_REG32(0x0C8)
+#define INTC_ISR_CLEAR2 INTC_REG32(0x0D4)
+#define INTC_SIR_IRQ INTC_REG32(0x040)
+#define INTC_CONTROL INTC_REG32(0x048)
+#define INTC_ILR11 INTC_REG32(0x12C)
+#define INTC_ILR32 INTC_REG32(0x180)
+#define INTC_ILR37 INTC_REG32(0x194)
+#define INTC_SYSCONFIG INTC_REG32(0x010)
+
+/* RAM FIREWALL */
+#define RAMFW_BASE (0x68005000)
+#define RAMFW_REG32(offset) __REG32(RAMFW_BASE + (offset))
+
+#define RAMFW_REQINFOPERM0 RAMFW_REG32(0x048)
+#define RAMFW_READPERM0 RAMFW_REG32(0x050)
+#define RAMFW_WRITEPERM0 RAMFW_REG32(0x058)
+
+/* GPMC CS1 FPGA ON USER INTERFACE MODULE */
+//#define DEBUG_BOARD_LED_REGISTER 0x04000014
+
+/* GPMC CS0 */
+#define GPMC_CONFIG1_0 GPMC_REG32(0x060)
+#define GPMC_CONFIG2_0 GPMC_REG32(0x064)
+#define GPMC_CONFIG3_0 GPMC_REG32(0x068)
+#define GPMC_CONFIG4_0 GPMC_REG32(0x06C)
+#define GPMC_CONFIG5_0 GPMC_REG32(0x070)
+#define GPMC_CONFIG6_0 GPMC_REG32(0x074)
+#define GPMC_CONFIG7_0 GPMC_REG32(0x078)
+
+/* GPMC CS1 */
+#define GPMC_CONFIG1_1 GPMC_REG32(0x090)
+#define GPMC_CONFIG2_1 GPMC_REG32(0x094)
+#define GPMC_CONFIG3_1 GPMC_REG32(0x098)
+#define GPMC_CONFIG4_1 GPMC_REG32(0x09C)
+#define GPMC_CONFIG5_1 GPMC_REG32(0x0a0)
+#define GPMC_CONFIG6_1 GPMC_REG32(0x0a4)
+#define GPMC_CONFIG7_1 GPMC_REG32(0x0a8)
+
+/* DSS */
+#define DSS_CONTROL DISP_REG32(0x040)
+#define DISPC_CONTROL DISP_REG32(0x440)
+#define DISPC_SYSSTATUS DISP_REG32(0x414)
+#define DISPC_IRQSTATUS DISP_REG32(0x418)
+#define DISPC_IRQENABLE DISP_REG32(0x41C)
+#define DISPC_CONFIG DISP_REG32(0x444)
+#define DISPC_DEFAULT_COLOR0 DISP_REG32(0x44C)
+#define DISPC_DEFAULT_COLOR1 DISP_REG32(0x450)
+#define DISPC_TRANS_COLOR0 DISP_REG32(0x454)
+#define DISPC_TRANS_COLOR1 DISP_REG32(0x458)
+#define DISPC_LINE_NUMBER DISP_REG32(0x460)
+#define DISPC_TIMING_H DISP_REG32(0x464)
+#define DISPC_TIMING_V DISP_REG32(0x468)
+#define DISPC_POL_FREQ DISP_REG32(0x46C)
+#define DISPC_DIVISOR DISP_REG32(0x470)
+#define DISPC_SIZE_DIG DISP_REG32(0x478)
+#define DISPC_SIZE_LCD DISP_REG32(0x47C)
+#define DISPC_GFX_BA0 DISP_REG32(0x480)
+#define DISPC_GFX_BA1 DISP_REG32(0x484)
+#define DISPC_GFX_POSITION DISP_REG32(0x488)
+#define DISPC_GFX_SIZE DISP_REG32(0x48C)
+#define DISPC_GFX_ATTRIBUTES DISP_REG32(0x4A0)
+#define DISPC_GFX_FIFO_THRESHOLD DISP_REG32(0x4A4)
+#define DISPC_GFX_ROW_INC DISP_REG32(0x4AC)
+#define DISPC_GFX_PIXEL_INC DISP_REG32(0x4B0)
+#define DISPC_GFX_WINDOW_SKIP DISP_REG32(0x4B4)
+#define DISPC_GFX_TABLE_BA DISP_REG32(0x4B8)
+#define DISPC_DATA_CYCLE1 DISP_REG32(0x5D4)
+#define DISPC_DATA_CYCLE2 DISP_REG32(0x5D8)
+#define DISPC_DATA_CYCLE3 DISP_REG32(0x5DC)
+
+/* Wake up define for board */
+#define GPIO97 (1 << 1)
+#define GPIO88 (1 << 24)
+
+#endif /* __ASSEMBLER__ */
+
+#endif
+
+
+
+
+
diff --git a/include/asm-arm/arch-omap/sram.h b/include/asm-arm/arch-omap/sram.h
new file mode 100644
index 000000000000..e72ccbf0fe06
--- /dev/null
+++ b/include/asm-arm/arch-omap/sram.h
@@ -0,0 +1,38 @@
+/*
+ * linux/include/asm-arm/arch-omap/sram.h
+ *
+ * Interface for functions that need to be run in internal SRAM
+ *
+ * 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 __ARCH_ARM_OMAP_SRAM_H
+#define __ARCH_ARM_OMAP_SRAM_H
+
+extern void * omap_sram_push(void * start, unsigned long size);
+extern void omap_sram_reprogram_clock(u32 dpllctl, u32 ckctl);
+
+extern void omap2_sram_ddr_init(u32 *slow_dll_ctrl, u32 fast_dll_ctrl,
+ u32 base_cs, u32 force_unlock);
+extern void omap2_sram_reprogram_sdrc(u32 perf_level, u32 dll_val,
+ u32 mem_type);
+extern u32 omap2_set_prcm(u32 dpll_ctrl_val, u32 sdrc_rfr_val, int bypass);
+
+
+/* Do not use these */
+extern void sram_reprogram_clock(u32 ckctl, u32 dpllctl);
+extern unsigned long sram_reprogram_clock_sz;
+
+extern void sram_ddr_init(u32 *slow_dll_ctrl, u32 fast_dll_ctrl,
+ u32 base_cs, u32 force_unlock);
+extern unsigned long sram_ddr_init_sz;
+
+extern u32 sram_set_prcm(u32 dpll_ctrl_val, u32 sdrc_rfr_val, int bypass);
+extern unsigned long sram_set_prcm_sz;
+
+extern void sram_reprogram_sdrc(u32 perf_level, u32 dll_val, u32 mem_type);
+extern unsigned long sram_reprogram_sdrc_sz;
+
+#endif
diff --git a/include/asm-arm/arch-omap/system.h b/include/asm-arm/arch-omap/system.h
index ff37bc27e603..b43cdd2a3874 100644
--- a/include/asm-arm/arch-omap/system.h
+++ b/include/asm-arm/arch-omap/system.h
@@ -6,18 +6,21 @@
#define __ASM_ARCH_SYSTEM_H
#include <linux/config.h>
#include <asm/mach-types.h>
+#include <asm/hardware/clock.h>
#include <asm/arch/hardware.h>
-#include <asm/mach-types.h>
+#include <asm/arch/prcm.h>
+
+#ifndef CONFIG_MACH_VOICEBLUE
+#define voiceblue_reset() do {} while (0)
+#endif
static inline void arch_idle(void)
{
cpu_do_idle();
}
-static inline void arch_reset(char mode)
+static inline void omap1_arch_reset(char mode)
{
-
-#ifdef CONFIG_ARCH_OMAP16XX
/*
* Workaround for 5912/1611b bug mentioned in sprz209d.pdf p. 28
* "Global Software Reset Affects Traffic Controller Frequency".
@@ -27,13 +30,31 @@ static inline void arch_reset(char mode)
DPLL_CTL);
omap_writew(0x8, ARM_RSTCT1);
}
-#endif
-#ifdef CONFIG_MACH_VOICEBLUE
+
if (machine_is_voiceblue())
voiceblue_reset();
else
-#endif
omap_writew(1, ARM_RSTCT1);
}
+static inline void omap2_arch_reset(char mode)
+{
+ u32 rate;
+ struct clk *vclk, *sclk;
+
+ vclk = clk_get(NULL, "virt_prcm_set");
+ sclk = clk_get(NULL, "sys_ck");
+ rate = clk_get_rate(sclk);
+ clk_set_rate(vclk, rate); /* go to bypass for OMAP limitation */
+ RM_RSTCTRL_WKUP |= 2;
+}
+
+static inline void arch_reset(char mode)
+{
+ if (!cpu_is_omap24xx())
+ omap1_arch_reset(mode);
+ else
+ omap2_arch_reset(mode);
+}
+
#endif
diff --git a/include/asm-arm/arch-omap/timex.h b/include/asm-arm/arch-omap/timex.h
index b61ddb491e83..21f2e367185a 100644
--- a/include/asm-arm/arch-omap/timex.h
+++ b/include/asm-arm/arch-omap/timex.h
@@ -28,6 +28,14 @@
#if !defined(__ASM_ARCH_OMAP_TIMEX_H)
#define __ASM_ARCH_OMAP_TIMEX_H
+/*
+ * OMAP 32KHz timer updates time one jiffie at a time from a secondary timer,
+ * and that's why the CLOCK_TICK_RATE is not 32768.
+ */
+#ifdef CONFIG_OMAP_32K_TIMER
+#define CLOCK_TICK_RATE (CONFIG_OMAP_32K_TIMER_HZ)
+#else
#define CLOCK_TICK_RATE (HZ * 100000UL)
+#endif
#endif /* __ASM_ARCH_OMAP_TIMEX_H */
diff --git a/include/asm-arm/arch-omap/uncompress.h b/include/asm-arm/arch-omap/uncompress.h
index 3545c86859cc..c718264affbd 100644
--- a/include/asm-arm/arch-omap/uncompress.h
+++ b/include/asm-arm/arch-omap/uncompress.h
@@ -36,10 +36,14 @@ putstr(const char *s)
volatile u8 * uart = 0;
int shift = 2;
+#ifdef CONFIG_MACH_OMAP_PALMTE
+ return;
+#endif
+
#ifdef CONFIG_ARCH_OMAP
#ifdef CONFIG_OMAP_LL_DEBUG_UART3
uart = (volatile u8 *)(OMAP_UART3_BASE);
-#elif CONFIG_OMAP_LL_DEBUG_UART2
+#elif defined(CONFIG_OMAP_LL_DEBUG_UART2)
uart = (volatile u8 *)(OMAP_UART2_BASE);
#else
uart = (volatile u8 *)(OMAP_UART1_BASE);
diff --git a/include/asm-arm/arch-pxa/hardware.h b/include/asm-arm/arch-pxa/hardware.h
index cf35721cfa45..3e70bd95472c 100644
--- a/include/asm-arm/arch-pxa/hardware.h
+++ b/include/asm-arm/arch-pxa/hardware.h
@@ -44,12 +44,12 @@
#ifndef __ASSEMBLY__
-# define __REG(x) (*((volatile unsigned long *)io_p2v(x)))
+# define __REG(x) (*((volatile u32 *)io_p2v(x)))
/* With indexed regs we don't want to feed the index through io_p2v()
especially if it is a variable, otherwise horrible code will result. */
# define __REG2(x,y) \
- (*(volatile unsigned long *)((unsigned long)&__REG(x) + (y)))
+ (*(volatile u32 *)((u32)&__REG(x) + (y)))
# define __PREG(x) (io_v2p((u32)&(x)))
diff --git a/include/asm-arm/arch-pxa/io.h b/include/asm-arm/arch-pxa/io.h
index c3bdbe44e21f..eb2dd58d397f 100644
--- a/include/asm-arm/arch-pxa/io.h
+++ b/include/asm-arm/arch-pxa/io.h
@@ -6,6 +6,8 @@
#ifndef __ASM_ARM_ARCH_IO_H
#define __ASM_ARM_ARCH_IO_H
+#include <asm/hardware.h>
+
#define IO_SPACE_LIMIT 0xffffffff
/*
diff --git a/include/asm-arm/arch-pxa/irda.h b/include/asm-arm/arch-pxa/irda.h
new file mode 100644
index 000000000000..748406f384c2
--- /dev/null
+++ b/include/asm-arm/arch-pxa/irda.h
@@ -0,0 +1,17 @@
+#ifndef ASMARM_ARCH_IRDA_H
+#define ASMARM_ARCH_IRDA_H
+
+/* board specific transceiver capabilities */
+
+#define IR_OFF 1
+#define IR_SIRMODE 2
+#define IR_FIRMODE 4
+
+struct pxaficp_platform_data {
+ int transceiver_cap;
+ void (*transceiver_mode)(struct device *dev, int mode);
+};
+
+extern void pxa_set_ficp_info(struct pxaficp_platform_data *info);
+
+#endif
diff --git a/include/asm-arm/arch-pxa/memory.h b/include/asm-arm/arch-pxa/memory.h
index 58bad9748b5c..eaf6d43939e9 100644
--- a/include/asm-arm/arch-pxa/memory.h
+++ b/include/asm-arm/arch-pxa/memory.h
@@ -15,7 +15,7 @@
/*
* Physical DRAM offset.
*/
-#define PHYS_OFFSET (0xa0000000UL)
+#define PHYS_OFFSET UL(0xa0000000)
/*
* Virtual view <-> DMA view memory address translations
diff --git a/include/asm-arm/arch-pxa/pm.h b/include/asm-arm/arch-pxa/pm.h
new file mode 100644
index 000000000000..7a8a1cdf430d
--- /dev/null
+++ b/include/asm-arm/arch-pxa/pm.h
@@ -0,0 +1,12 @@
+/*
+ * Copyright (c) 2005 Richard Purdie
+ *
+ * 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.
+ *
+ */
+
+extern int pxa_pm_prepare(suspend_state_t state);
+extern int pxa_pm_enter(suspend_state_t state);
+extern int pxa_pm_finish(suspend_state_t state);
diff --git a/include/asm-arm/arch-pxa/pxa-regs.h b/include/asm-arm/arch-pxa/pxa-regs.h
index 3af7165ab0d7..a75a2470f4f5 100644
--- a/include/asm-arm/arch-pxa/pxa-regs.h
+++ b/include/asm-arm/arch-pxa/pxa-regs.h
@@ -326,6 +326,25 @@
#define STDLL __REG(0x40700000) /* Divisor Latch Low Register (DLAB = 1) (read/write) */
#define STDLH __REG(0x40700004) /* Divisor Latch High Register (DLAB = 1) (read/write) */
+/* Hardware UART (HWUART) */
+#define HWUART HWRBR
+#define HWRBR __REG(0x41600000) /* Receive Buffer Register (read only) */
+#define HWTHR __REG(0x41600000) /* Transmit Holding Register (write only) */
+#define HWIER __REG(0x41600004) /* Interrupt Enable Register (read/write) */
+#define HWIIR __REG(0x41600008) /* Interrupt ID Register (read only) */
+#define HWFCR __REG(0x41600008) /* FIFO Control Register (write only) */
+#define HWLCR __REG(0x4160000C) /* Line Control Register (read/write) */
+#define HWMCR __REG(0x41600010) /* Modem Control Register (read/write) */
+#define HWLSR __REG(0x41600014) /* Line Status Register (read only) */
+#define HWMSR __REG(0x41600018) /* Modem Status Register (read only) */
+#define HWSPR __REG(0x4160001C) /* Scratch Pad Register (read/write) */
+#define HWISR __REG(0x41600020) /* Infrared Selection Register (read/write) */
+#define HWFOR __REG(0x41600024) /* Receive FIFO Occupancy Register (read only) */
+#define HWABR __REG(0x41600028) /* Auto-Baud Control Register (read/write) */
+#define HWACR __REG(0x4160002C) /* Auto-Baud Count Register (read only) */
+#define HWDLL __REG(0x41600000) /* Divisor Latch Low Register (DLAB = 1) (read/write) */
+#define HWDLH __REG(0x41600004) /* Divisor Latch High Register (DLAB = 1) (read/write) */
+
#define IER_DMAE (1 << 7) /* DMA Requests Enable */
#define IER_UUE (1 << 6) /* UART Unit Enable */
#define IER_NRZE (1 << 5) /* NRZ coding Enable */
@@ -1013,14 +1032,12 @@
#define ICCR0_LBM (1 << 1) /* Loopback mode */
#define ICCR0_ITR (1 << 0) /* IrDA transmission */
-#ifdef CONFIG_PXA27x
#define ICCR2_RXP (1 << 3) /* Receive Pin Polarity select */
#define ICCR2_TXP (1 << 2) /* Transmit Pin Polarity select */
#define ICCR2_TRIG (3 << 0) /* Receive FIFO Trigger threshold */
#define ICCR2_TRIG_8 (0 << 0) /* >= 8 bytes */
#define ICCR2_TRIG_16 (1 << 0) /* >= 16 bytes */
#define ICCR2_TRIG_32 (2 << 0) /* >= 32 bytes */
-#endif
#ifdef CONFIG_PXA27x
#define ICSR0_EOC (1 << 6) /* DMA End of Descriptor Chain */
@@ -1250,9 +1267,13 @@
#define GPIO40_FFDTR 40 /* FFUART data terminal Ready */
#define GPIO41_FFRTS 41 /* FFUART request to send */
#define GPIO42_BTRXD 42 /* BTUART receive data */
+#define GPIO42_HWRXD 42 /* HWUART receive data */
#define GPIO43_BTTXD 43 /* BTUART transmit data */
+#define GPIO43_HWTXD 43 /* HWUART transmit data */
#define GPIO44_BTCTS 44 /* BTUART clear to send */
+#define GPIO44_HWCTS 44 /* HWUART clear to send */
#define GPIO45_BTRTS 45 /* BTUART request to send */
+#define GPIO45_HWRTS 45 /* HWUART request to send */
#define GPIO45_AC97_SYSCLK 45 /* AC97 System Clock */
#define GPIO46_ICPRXD 46 /* ICP receive data */
#define GPIO46_STRXD 46 /* STD_UART receive data */
@@ -1378,17 +1399,26 @@
#define GPIO40_FFDTR_MD (40 | GPIO_ALT_FN_2_OUT)
#define GPIO41_FFRTS_MD (41 | GPIO_ALT_FN_2_OUT)
#define GPIO42_BTRXD_MD (42 | GPIO_ALT_FN_1_IN)
+#define GPIO42_HWRXD_MD (42 | GPIO_ALT_FN_3_IN)
#define GPIO43_BTTXD_MD (43 | GPIO_ALT_FN_2_OUT)
+#define GPIO43_HWTXD_MD (43 | GPIO_ALT_FN_3_OUT)
#define GPIO44_BTCTS_MD (44 | GPIO_ALT_FN_1_IN)
+#define GPIO44_HWCTS_MD (44 | GPIO_ALT_FN_3_IN)
#define GPIO45_BTRTS_MD (45 | GPIO_ALT_FN_2_OUT)
+#define GPIO45_HWRTS_MD (45 | GPIO_ALT_FN_3_OUT)
#define GPIO45_SYSCLK_AC97_MD (45 | GPIO_ALT_FN_1_OUT)
#define GPIO46_ICPRXD_MD (46 | GPIO_ALT_FN_1_IN)
#define GPIO46_STRXD_MD (46 | GPIO_ALT_FN_2_IN)
#define GPIO47_ICPTXD_MD (47 | GPIO_ALT_FN_2_OUT)
#define GPIO47_STTXD_MD (47 | GPIO_ALT_FN_1_OUT)
#define GPIO48_nPOE_MD (48 | GPIO_ALT_FN_2_OUT)
+#define GPIO48_HWTXD_MD (48 | GPIO_ALT_FN_1_OUT)
+#define GPIO48_nPOE_MD (48 | GPIO_ALT_FN_2_OUT)
+#define GPIO49_HWRXD_MD (49 | GPIO_ALT_FN_1_IN)
#define GPIO49_nPWE_MD (49 | GPIO_ALT_FN_2_OUT)
#define GPIO50_nPIOR_MD (50 | GPIO_ALT_FN_2_OUT)
+#define GPIO50_HWCTS_MD (50 | GPIO_ALT_FN_1_IN)
+#define GPIO51_HWRTS_MD (51 | GPIO_ALT_FN_1_OUT)
#define GPIO51_nPIOW_MD (51 | GPIO_ALT_FN_2_OUT)
#define GPIO52_nPCE_1_MD (52 | GPIO_ALT_FN_2_OUT)
#define GPIO53_nPCE_2_MD (53 | GPIO_ALT_FN_2_OUT)
@@ -1763,6 +1793,7 @@
#define CKEN7_BTUART (1 << 7) /* BTUART Unit Clock Enable */
#define CKEN6_FFUART (1 << 6) /* FFUART Unit Clock Enable */
#define CKEN5_STUART (1 << 5) /* STUART Unit Clock Enable */
+#define CKEN4_HWUART (1 << 4) /* HWUART Unit Clock Enable */
#define CKEN4_SSP3 (1 << 4) /* SSP3 Unit Clock Enable */
#define CKEN3_SSP (1 << 3) /* SSP Unit Clock Enable */
#define CKEN3_SSP2 (1 << 3) /* SSP2 Unit Clock Enable */
@@ -2282,4 +2313,11 @@
#endif
+/* PWRMODE register M field values */
+
+#define PWRMODE_IDLE 0x1
+#define PWRMODE_STANDBY 0x2
+#define PWRMODE_SLEEP 0x3
+#define PWRMODE_DEEPSLEEP 0x7
+
#endif
diff --git a/include/asm-arm/arch-pxa/sharpsl.h b/include/asm-arm/arch-pxa/sharpsl.h
index 311f2bb5386a..0b43495d24b4 100644
--- a/include/asm-arm/arch-pxa/sharpsl.h
+++ b/include/asm-arm/arch-pxa/sharpsl.h
@@ -21,12 +21,18 @@ struct corgits_machinfo {
void (*wait_hsync)(void);
};
+
/*
* SharpSL Backlight
*/
-
struct corgibl_machinfo {
int max_intensity;
void (*set_bl_intensity)(int intensity);
};
+extern void corgibl_limit_intensity(int limit);
+
+/*
+ * SharpSL Battery/PM Driver
+ */
+extern void sharpsl_battery_kick(void);
diff --git a/include/asm-arm/arch-pxa/ssp.h b/include/asm-arm/arch-pxa/ssp.h
index 6ec67b018c09..949878c0d908 100644
--- a/include/asm-arm/arch-pxa/ssp.h
+++ b/include/asm-arm/arch-pxa/ssp.h
@@ -18,6 +18,11 @@
#ifndef SSP_H
#define SSP_H
+/*
+ * SSP initialisation flags
+ */
+#define SSP_NO_IRQ 0x1 /* don't register an irq handler in SSP driver */
+
struct ssp_state {
u32 cr0;
u32 cr1;
@@ -31,6 +36,7 @@ struct ssp_dev {
u32 flags;
u32 psp_flags;
u32 speed;
+ int irq;
};
int ssp_write_word(struct ssp_dev *dev, u32 data);
@@ -40,7 +46,7 @@ void ssp_enable(struct ssp_dev *dev);
void ssp_disable(struct ssp_dev *dev);
void ssp_save_state(struct ssp_dev *dev, struct ssp_state *ssp);
void ssp_restore_state(struct ssp_dev *dev, struct ssp_state *ssp);
-int ssp_init(struct ssp_dev *dev, u32 port);
+int ssp_init(struct ssp_dev *dev, u32 port, u32 init_flags);
int ssp_config(struct ssp_dev *dev, u32 mode, u32 flags, u32 psp_flags, u32 speed);
void ssp_exit(struct ssp_dev *dev);
diff --git a/include/asm-arm/arch-pxa/tosa.h b/include/asm-arm/arch-pxa/tosa.h
new file mode 100644
index 000000000000..c3364a2c4758
--- /dev/null
+++ b/include/asm-arm/arch-pxa/tosa.h
@@ -0,0 +1,166 @@
+/*
+ * Hardware specific definitions for Sharp SL-C6000x series of PDAs
+ *
+ * Copyright (c) 2005 Dirk Opfer
+ *
+ * Based on Sharp's 2.4 kernel patches
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+#ifndef _ASM_ARCH_TOSA_H_
+#define _ASM_ARCH_TOSA_H_ 1
+
+/* TOSA Chip selects */
+#define TOSA_LCDC_PHYS PXA_CS4_PHYS
+/* Internel Scoop */
+#define TOSA_CF_PHYS (PXA_CS2_PHYS + 0x00800000)
+/* Jacket Scoop */
+#define TOSA_SCOOP_PHYS (PXA_CS5_PHYS + 0x00800000)
+
+/*
+ * SCOOP2 internal GPIOs
+ */
+#define TOSA_SCOOP_PXA_VCORE1 SCOOP_GPCR_PA11
+#define TOSA_SCOOP_TC6393_REST_IN SCOOP_GPCR_PA12
+#define TOSA_SCOOP_IR_POWERDWN SCOOP_GPCR_PA13
+#define TOSA_SCOOP_SD_WP SCOOP_GPCR_PA14
+#define TOSA_SCOOP_PWR_ON SCOOP_GPCR_PA15
+#define TOSA_SCOOP_AUD_PWR_ON SCOOP_GPCR_PA16
+#define TOSA_SCOOP_BT_RESET SCOOP_GPCR_PA17
+#define TOSA_SCOOP_BT_PWR_EN SCOOP_GPCR_PA18
+#define TOSA_SCOOP_AC_IN_OL SCOOP_GPCR_PA19
+
+/* GPIO Direction 1 : output mode / 0:input mode */
+#define TOSA_SCOOP_IO_DIR ( TOSA_SCOOP_PXA_VCORE1 | TOSA_SCOOP_TC6393_REST_IN | \
+ TOSA_SCOOP_IR_POWERDWN | TOSA_SCOOP_PWR_ON | TOSA_SCOOP_AUD_PWR_ON |\
+ TOSA_SCOOP_BT_RESET | TOSA_SCOOP_BT_PWR_EN )
+/* GPIO out put level when init 1: Hi */
+#define TOSA_SCOOP_IO_OUT ( TOSA_SCOOP_TC6393_REST_IN )
+
+/*
+ * SCOOP2 jacket GPIOs
+ */
+#define TOSA_SCOOP_JC_BT_LED SCOOP_GPCR_PA11
+#define TOSA_SCOOP_JC_NOTE_LED SCOOP_GPCR_PA12
+#define TOSA_SCOOP_JC_CHRG_ERR_LED SCOOP_GPCR_PA13
+#define TOSA_SCOOP_JC_USB_PULLUP SCOOP_GPCR_PA14
+#define TOSA_SCOOP_JC_TC6393_SUSPEND SCOOP_GPCR_PA15
+#define TOSA_SCOOP_JC_TC3693_L3V_ON SCOOP_GPCR_PA16
+#define TOSA_SCOOP_JC_WLAN_DETECT SCOOP_GPCR_PA17
+#define TOSA_SCOOP_JC_WLAN_LED SCOOP_GPCR_PA18
+#define TOSA_SCOOP_JC_CARD_LIMIT_SEL SCOOP_GPCR_PA19
+
+/* GPIO Direction 1 : output mode / 0:input mode */
+#define TOSA_SCOOP_JC_IO_DIR ( TOSA_SCOOP_JC_BT_LED | TOSA_SCOOP_JC_NOTE_LED | \
+ TOSA_SCOOP_JC_CHRG_ERR_LED | TOSA_SCOOP_JC_USB_PULLUP | \
+ TOSA_SCOOP_JC_TC6393_SUSPEND | TOSA_SCOOP_JC_TC3693_L3V_ON | \
+ TOSA_SCOOP_JC_WLAN_LED | TOSA_SCOOP_JC_CARD_LIMIT_SEL )
+/* GPIO out put level when init 1: Hi */
+#define TOSA_SCOOP_JC_IO_OUT ( 0 )
+
+/*
+ * Timing Generator
+ */
+#define TG_PNLCTL 0x00
+#define TG_TPOSCTL 0x01
+#define TG_DUTYCTL 0x02
+#define TG_GPOSR 0x03
+#define TG_GPODR1 0x04
+#define TG_GPODR2 0x05
+#define TG_PINICTL 0x06
+#define TG_HPOSCTL 0x07
+
+/*
+ * LED
+ */
+#define TOSA_SCOOP_LED_BLUE TOSA_SCOOP_GPCR_PA11
+#define TOSA_SCOOP_LED_GREEN TOSA_SCOOP_GPCR_PA12
+#define TOSA_SCOOP_LED_ORANGE TOSA_SCOOP_GPCR_PA13
+#define TOSA_SCOOP_LED_WLAN TOSA_SCOOP_GPCR_PA18
+
+
+/*
+ * PXA GPIOs
+ */
+#define TOSA_GPIO_POWERON (0)
+#define TOSA_GPIO_RESET (1)
+#define TOSA_GPIO_AC_IN (2)
+#define TOSA_GPIO_RECORD_BTN (3)
+#define TOSA_GPIO_SYNC (4) /* Cradle SYNC Button */
+#define TOSA_GPIO_USB_IN (5)
+#define TOSA_GPIO_JACKET_DETECT (7)
+#define TOSA_GPIO_nSD_DETECT (9)
+#define TOSA_GPIO_nSD_INT (10)
+#define TOSA_GPIO_TC6393_CLK (11)
+#define TOSA_GPIO_BAT1_CRG (12)
+#define TOSA_GPIO_CF_CD (13)
+#define TOSA_GPIO_BAT0_CRG (14)
+#define TOSA_GPIO_TC6393_INT (15)
+#define TOSA_GPIO_BAT0_LOW (17)
+#define TOSA_GPIO_TC6393_RDY (18)
+#define TOSA_GPIO_ON_RESET (19)
+#define TOSA_GPIO_EAR_IN (20)
+#define TOSA_GPIO_CF_IRQ (21) /* CF slot0 Ready */
+#define TOSA_GPIO_ON_KEY (22)
+#define TOSA_GPIO_VGA_LINE (27)
+#define TOSA_GPIO_TP_INT (32) /* Touch Panel pen down interrupt */
+#define TOSA_GPIO_JC_CF_IRQ (36) /* CF slot1 Ready */
+#define TOSA_GPIO_BAT_LOCKED (38) /* Battery locked */
+#define TOSA_GPIO_TG_SPI_SCLK (81)
+#define TOSA_GPIO_TG_SPI_CS (82)
+#define TOSA_GPIO_TG_SPI_MOSI (83)
+#define TOSA_GPIO_BAT1_LOW (84)
+
+#define TOSA_GPIO_HP_IN GPIO_EAR_IN
+
+#define TOSA_GPIO_MAIN_BAT_LOW GPIO_BAT0_LOW
+
+#define TOSA_KEY_STROBE_NUM (11)
+#define TOSA_KEY_SENSE_NUM (7)
+
+#define TOSA_GPIO_HIGH_STROBE_BIT (0xfc000000)
+#define TOSA_GPIO_LOW_STROBE_BIT (0x0000001f)
+#define TOSA_GPIO_ALL_SENSE_BIT (0x00000fe0)
+#define TOSA_GPIO_ALL_SENSE_RSHIFT (5)
+#define TOSA_GPIO_STROBE_BIT(a) GPIO_bit(58+(a))
+#define TOSA_GPIO_SENSE_BIT(a) GPIO_bit(69+(a))
+#define TOSA_GAFR_HIGH_STROBE_BIT (0xfff00000)
+#define TOSA_GAFR_LOW_STROBE_BIT (0x000003ff)
+#define TOSA_GAFR_ALL_SENSE_BIT (0x00fffc00)
+#define TOSA_GPIO_KEY_SENSE(a) (69+(a))
+#define TOSA_GPIO_KEY_STROBE(a) (58+(a))
+
+/*
+ * Interrupts
+ */
+#define TOSA_IRQ_GPIO_WAKEUP IRQ_GPIO(TOSA_GPIO_WAKEUP)
+#define TOSA_IRQ_GPIO_AC_IN IRQ_GPIO(TOSA_GPIO_AC_IN)
+#define TOSA_IRQ_GPIO_RECORD_BTN IRQ_GPIO(TOSA_GPIO_RECORD_BTN)
+#define TOSA_IRQ_GPIO_SYNC IRQ_GPIO(TOSA_GPIO_SYNC)
+#define TOSA_IRQ_GPIO_USB_IN IRQ_GPIO(TOSA_GPIO_USB_IN)
+#define TOSA_IRQ_GPIO_JACKET_DETECT IRQ_GPIO(TOSA_GPIO_JACKET_DETECT)
+#define TOSA_IRQ_GPIO_nSD_INT IRQ_GPIO(TOSA_GPIO_nSD_INT)
+#define TOSA_IRQ_GPIO_nSD_DETECT IRQ_GPIO(TOSA_GPIO_nSD_DETECT)
+#define TOSA_IRQ_GPIO_BAT1_CRG IRQ_GPIO(TOSA_GPIO_BAT1_CRG)
+#define TOSA_IRQ_GPIO_CF_CD IRQ_GPIO(TOSA_GPIO_CF_CD)
+#define TOSA_IRQ_GPIO_BAT0_CRG IRQ_GPIO(TOSA_GPIO_BAT0_CRG)
+#define TOSA_IRQ_GPIO_TC6393_INT IRQ_GPIO(TOSA_GPIO_TC6393_INT)
+#define TOSA_IRQ_GPIO_BAT0_LOW IRQ_GPIO(TOSA_GPIO_BAT0_LOW)
+#define TOSA_IRQ_GPIO_EAR_IN IRQ_GPIO(TOSA_GPIO_EAR_IN)
+#define TOSA_IRQ_GPIO_CF_IRQ IRQ_GPIO(TOSA_GPIO_CF_IRQ)
+#define TOSA_IRQ_GPIO_ON_KEY IRQ_GPIO(TOSA_GPIO_ON_KEY)
+#define TOSA_IRQ_GPIO_VGA_LINE IRQ_GPIO(TOSA_GPIO_VGA_LINE)
+#define TOSA_IRQ_GPIO_TP_INT IRQ_GPIO(TOSA_GPIO_TP_INT)
+#define TOSA_IRQ_GPIO_JC_CF_IRQ IRQ_GPIO(TOSA_GPIO_JC_CF_IRQ)
+#define TOSA_IRQ_GPIO_BAT_LOCKED IRQ_GPIO(TOSA_GPIO_BAT_LOCKED)
+#define TOSA_IRQ_GPIO_BAT1_LOW IRQ_GPIO(TOSA_GPIO_BAT1_LOW)
+#define TOSA_IRQ_GPIO_KEY_SENSE(a) IRQ_GPIO(69+(a))
+
+#define TOSA_IRQ_GPIO_MAIN_BAT_LOW IRQ_GPIO(TOSA_GPIO_MAIN_BAT_LOW)
+
+extern struct platform_device tosascoop_jc_device;
+extern struct platform_device tosascoop_device;
+#endif /* _ASM_ARCH_TOSA_H_ */
diff --git a/include/asm-arm/arch-pxa/uncompress.h b/include/asm-arm/arch-pxa/uncompress.h
index 4428d3eb7432..fe38090444e0 100644
--- a/include/asm-arm/arch-pxa/uncompress.h
+++ b/include/asm-arm/arch-pxa/uncompress.h
@@ -12,6 +12,7 @@
#define FFUART ((volatile unsigned long *)0x40100000)
#define BTUART ((volatile unsigned long *)0x40200000)
#define STUART ((volatile unsigned long *)0x40700000)
+#define HWUART ((volatile unsigned long *)0x41600000)
#define UART FFUART
diff --git a/include/asm-arm/arch-realview/debug-macro.S b/include/asm-arm/arch-realview/debug-macro.S
new file mode 100644
index 000000000000..ed28bd012236
--- /dev/null
+++ b/include/asm-arm/arch-realview/debug-macro.S
@@ -0,0 +1,38 @@
+/* linux/include/asm-arm/arch-realview/debug-macro.S
+ *
+ * Debugging macro include header
+ *
+ * Copyright (C) 1994-1999 Russell King
+ * Moved from linux/arch/arm/kernel/debug.S by Ben Dooks
+ *
+ * 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 <asm/hardware/amba_serial.h>
+
+ .macro addruart,rx
+ mrc p15, 0, \rx, c1, c0
+ tst \rx, #1 @ MMU enabled?
+ moveq \rx, #0x10000000
+ movne \rx, #0xf1000000 @ virtual base
+ orr \rx, \rx, #0x00009000
+ .endm
+
+ .macro senduart,rd,rx
+ strb \rd, [\rx, #UART01x_DR]
+ .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/include/asm-ppc64/pmc.h b/include/asm-arm/arch-realview/dma.h
index d1d297dbccfe..744491a74bd9 100644
--- a/include/asm-ppc64/pmc.h
+++ b/include/asm-arm/arch-realview/dma.h
@@ -1,6 +1,8 @@
/*
- * pmc.h
- * Copyright (C) 2004 David Gibson, IBM Corporation
+ * linux/include/asm-arm/arch-realview/dma.h
+ *
+ * Copyright (C) 2003 ARM Limited.
+ * Copyright (C) 1997,1998 Russell King
*
* 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
@@ -14,18 +16,12 @@
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#ifndef _PPC64_PMC_H
-#define _PPC64_PMC_H
-
-#include <asm/ptrace.h>
-
-typedef void (*perf_irq_t)(struct pt_regs *);
-
-int reserve_pmc_hardware(perf_irq_t new_perf_irq);
-void release_pmc_hardware(void);
+#ifndef __ASM_ARCH_DMA_H
+#define __ASM_ARCH_DMA_H
-void power4_enable_pmcs(void);
+#define MAX_DMA_ADDRESS 0xffffffff
+#define MAX_DMA_CHANNELS 0
-#endif /* _PPC64_PMC_H */
+#endif /* _ASM_ARCH_DMA_H */
diff --git a/include/asm-arm/arch-realview/entry-macro.S b/include/asm-arm/arch-realview/entry-macro.S
new file mode 100644
index 000000000000..6288fad0dc41
--- /dev/null
+++ b/include/asm-arm/arch-realview/entry-macro.S
@@ -0,0 +1,74 @@
+/*
+ * include/asm-arm/arch-realview/entry-macro.S
+ *
+ * Low-level IRQ helper macros for RealView platforms
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <asm/hardware/gic.h>
+
+ .macro disable_fiq
+ .endm
+
+ /*
+ * The interrupt numbering scheme is defined in the
+ * interrupt controller spec. To wit:
+ *
+ * Interrupts 0-15 are IPI
+ * 16-28 are reserved
+ * 29-31 are local. We allow 30 to be used for the watchdog.
+ * 32-1020 are global
+ * 1021-1022 are reserved
+ * 1023 is "spurious" (no interrupt)
+ *
+ * For now, we ignore all local interrupts so only return an interrupt if it's
+ * between 30 and 1020. The test_for_ipi routine below will pick up on IPIs.
+ *
+ * A simple read from the controller will tell us the number of the highest
+ * priority enabled interrupt. We then just need to check whether it is in the
+ * valid range for an IRQ (30-1020 inclusive).
+ */
+
+ .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
+
+ ldr \base, =IO_ADDRESS(REALVIEW_GIC_CPU_BASE)
+ ldr \irqstat, [\base, #GIC_CPU_INTACK] /* bits 12-10 = src CPU, 9-0 = int # */
+
+ ldr \tmp, =1021
+
+ bic \irqnr, \irqstat, #0x1c00
+
+ cmp \irqnr, #29
+ cmpcc \irqnr, \irqnr
+ cmpne \irqnr, \tmp
+ cmpcs \irqnr, \irqnr
+
+ .endm
+
+ /* We assume that irqstat (the raw value of the IRQ acknowledge
+ * register) is preserved from the macro above.
+ * If there is an IPI, we immediately signal end of interrupt on the
+ * controller, since this requires the original irqstat value which
+ * we won't easily be able to recreate later.
+ */
+
+ .macro test_for_ipi, irqnr, irqstat, base, tmp
+ bic \irqnr, \irqstat, #0x1c00
+ cmp \irqnr, #16
+ strcc \irqstat, [\base, #GIC_CPU_EOI]
+ cmpcs \irqnr, \irqnr
+ .endm
+
+ /* As above, this assumes that irqstat and base are preserved.. */
+
+ .macro test_for_ltirq, irqnr, irqstat, base, tmp
+ bic \irqnr, \irqstat, #0x1c00
+ mov \tmp, #0
+ cmp \irqnr, #29
+ moveq \tmp, #1
+ streq \irqstat, [\base, #GIC_CPU_EOI]
+ cmp \tmp, #0
+ .endm
diff --git a/include/asm-arm/arch-realview/hardware.h b/include/asm-arm/arch-realview/hardware.h
new file mode 100644
index 000000000000..67879cdb6ef2
--- /dev/null
+++ b/include/asm-arm/arch-realview/hardware.h
@@ -0,0 +1,31 @@
+/*
+ * linux/include/asm-arm/arch-realview/hardware.h
+ *
+ * This file contains the hardware definitions of the RealView boards.
+ *
+ * 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
+ */
+#ifndef __ASM_ARCH_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H
+
+#include <asm/sizes.h>
+#include <asm/arch/platform.h>
+
+/* macro to get at IO space when running virtually */
+#define IO_ADDRESS(x) (((x) & 0x0fffffff) + (((x) >> 4) & 0x0f000000) + 0xf0000000)
+
+#endif
diff --git a/include/asm-arm/arch-realview/io.h b/include/asm-arm/arch-realview/io.h
new file mode 100644
index 000000000000..d444a68ac330
--- /dev/null
+++ b/include/asm-arm/arch-realview/io.h
@@ -0,0 +1,34 @@
+/*
+ * linux/include/asm-arm/arch-realview/io.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
+ */
+#ifndef __ASM_ARM_ARCH_IO_H
+#define __ASM_ARM_ARCH_IO_H
+
+#define IO_SPACE_LIMIT 0xffffffff
+
+static inline void __iomem *__io(unsigned long addr)
+{
+ return (void __iomem *)addr;
+}
+
+#define __io(a) __io(a)
+#define __mem_pci(a) (a)
+#define __mem_isa(a) (a)
+
+#endif
diff --git a/include/asm-arm/arch-realview/irqs.h b/include/asm-arm/arch-realview/irqs.h
new file mode 100644
index 000000000000..c16223c9588d
--- /dev/null
+++ b/include/asm-arm/arch-realview/irqs.h
@@ -0,0 +1,106 @@
+/*
+ * linux/include/asm-arm/arch-realview/irqs.h
+ *
+ * Copyright (C) 2003 ARM Limited
+ * Copyright (C) 2000 Deep Blue Solutions Ltd.
+ *
+ * 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 <asm/arch/platform.h>
+
+#define IRQ_LOCALTIMER 29
+#define IRQ_LOCALWDOG 30
+
+/*
+ * IRQ interrupts definitions are the same the INT definitions
+ * held within platform.h
+ */
+#define IRQ_GIC_START 32
+#define IRQ_WDOGINT (IRQ_GIC_START + INT_WDOGINT)
+#define IRQ_SOFTINT (IRQ_GIC_START + INT_SOFTINT)
+#define IRQ_COMMRx (IRQ_GIC_START + INT_COMMRx)
+#define IRQ_COMMTx (IRQ_GIC_START + INT_COMMTx)
+#define IRQ_TIMERINT0_1 (IRQ_GIC_START + INT_TIMERINT0_1)
+#define IRQ_TIMERINT2_3 (IRQ_GIC_START + INT_TIMERINT2_3)
+#define IRQ_GPIOINT0 (IRQ_GIC_START + INT_GPIOINT0)
+#define IRQ_GPIOINT1 (IRQ_GIC_START + INT_GPIOINT1)
+#define IRQ_GPIOINT2 (IRQ_GIC_START + INT_GPIOINT2)
+#define IRQ_GPIOINT3 (IRQ_GIC_START + INT_GPIOINT3)
+#define IRQ_RTCINT (IRQ_GIC_START + INT_RTCINT)
+#define IRQ_SSPINT (IRQ_GIC_START + INT_SSPINT)
+#define IRQ_UARTINT0 (IRQ_GIC_START + INT_UARTINT0)
+#define IRQ_UARTINT1 (IRQ_GIC_START + INT_UARTINT1)
+#define IRQ_UARTINT2 (IRQ_GIC_START + INT_UARTINT2)
+#define IRQ_UART3 (IRQ_GIC_START + INT_UARTINT3)
+#define IRQ_SCIINT (IRQ_GIC_START + INT_SCIINT)
+#define IRQ_CLCDINT (IRQ_GIC_START + INT_CLCDINT)
+#define IRQ_DMAINT (IRQ_GIC_START + INT_DMAINT)
+#define IRQ_PWRFAILINT (IRQ_GIC_START + INT_PWRFAILINT)
+#define IRQ_MBXINT (IRQ_GIC_START + INT_MBXINT)
+#define IRQ_GNDINT (IRQ_GIC_START + INT_GNDINT)
+#define IRQ_MMCI0B (IRQ_GIC_START + INT_MMCI0B)
+#define IRQ_MMCI1B (IRQ_GIC_START + INT_MMCI1B)
+#define IRQ_KMI0 (IRQ_GIC_START + INT_KMI0)
+#define IRQ_KMI1 (IRQ_GIC_START + INT_KMI1)
+#define IRQ_SCI3 (IRQ_GIC_START + INT_SCI3)
+#define IRQ_CLCD (IRQ_GIC_START + INT_CLCD)
+#define IRQ_TOUCH (IRQ_GIC_START + INT_TOUCH)
+#define IRQ_KEYPAD (IRQ_GIC_START + INT_KEYPAD)
+#define IRQ_DoC (IRQ_GIC_START + INT_DoC)
+#define IRQ_MMCI0A (IRQ_GIC_START + INT_MMCI0A)
+#define IRQ_MMCI1A (IRQ_GIC_START + INT_MMCI1A)
+#define IRQ_AACI (IRQ_GIC_START + INT_AACI)
+#define IRQ_ETH (IRQ_GIC_START + INT_ETH)
+#define IRQ_USB (IRQ_GIC_START + INT_USB)
+
+#define IRQMASK_WDOGINT INTMASK_WDOGINT
+#define IRQMASK_SOFTINT INTMASK_SOFTINT
+#define IRQMASK_COMMRx INTMASK_COMMRx
+#define IRQMASK_COMMTx INTMASK_COMMTx
+#define IRQMASK_TIMERINT0_1 INTMASK_TIMERINT0_1
+#define IRQMASK_TIMERINT2_3 INTMASK_TIMERINT2_3
+#define IRQMASK_GPIOINT0 INTMASK_GPIOINT0
+#define IRQMASK_GPIOINT1 INTMASK_GPIOINT1
+#define IRQMASK_GPIOINT2 INTMASK_GPIOINT2
+#define IRQMASK_GPIOINT3 INTMASK_GPIOINT3
+#define IRQMASK_RTCINT INTMASK_RTCINT
+#define IRQMASK_SSPINT INTMASK_SSPINT
+#define IRQMASK_UARTINT0 INTMASK_UARTINT0
+#define IRQMASK_UARTINT1 INTMASK_UARTINT1
+#define IRQMASK_UARTINT2 INTMASK_UARTINT2
+#define IRQMASK_SCIINT INTMASK_SCIINT
+#define IRQMASK_CLCDINT INTMASK_CLCDINT
+#define IRQMASK_DMAINT INTMASK_DMAINT
+#define IRQMASK_PWRFAILINT INTMASK_PWRFAILINT
+#define IRQMASK_MBXINT INTMASK_MBXINT
+#define IRQMASK_GNDINT INTMASK_GNDINT
+#define IRQMASK_MMCI0B INTMASK_MMCI0B
+#define IRQMASK_MMCI1B INTMASK_MMCI1B
+#define IRQMASK_KMI0 INTMASK_KMI0
+#define IRQMASK_KMI1 INTMASK_KMI1
+#define IRQMASK_SCI3 INTMASK_SCI3
+#define IRQMASK_UART3 INTMASK_UART3
+#define IRQMASK_CLCD INTMASK_CLCD
+#define IRQMASK_TOUCH INTMASK_TOUCH
+#define IRQMASK_KEYPAD INTMASK_KEYPAD
+#define IRQMASK_DoC INTMASK_DoC
+#define IRQMASK_MMCI0A INTMASK_MMCI0A
+#define IRQMASK_MMCI1A INTMASK_MMCI1A
+#define IRQMASK_AACI INTMASK_AACI
+#define IRQMASK_ETH INTMASK_ETH
+#define IRQMASK_USB INTMASK_USB
+
+#define NR_IRQS (IRQ_GIC_START + 64)
diff --git a/include/asm-arm/arch-realview/memory.h b/include/asm-arm/arch-realview/memory.h
new file mode 100644
index 000000000000..ed370abb638f
--- /dev/null
+++ b/include/asm-arm/arch-realview/memory.h
@@ -0,0 +1,38 @@
+/*
+ * linux/include/asm-arm/arch-realview/memory.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
+ */
+#ifndef __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+/*
+ * Physical DRAM offset.
+ */
+#define PHYS_OFFSET UL(0x00000000)
+
+/*
+ * Virtual view <-> DMA view memory address translations
+ * virt_to_bus: Used to translate the virtual address to an
+ * address suitable to be passed to set_dma_addr
+ * bus_to_virt: Used to convert an address for DMA operations
+ * to an address that the kernel can use.
+ */
+#define __virt_to_bus(x) ((x) - PAGE_OFFSET)
+#define __bus_to_virt(x) ((x) + PAGE_OFFSET)
+
+#endif
diff --git a/include/asm-arm/arch-realview/param.h b/include/asm-arm/arch-realview/param.h
new file mode 100644
index 000000000000..89b1235d32bd
--- /dev/null
+++ b/include/asm-arm/arch-realview/param.h
@@ -0,0 +1,19 @@
+/*
+ * linux/include/asm-arm/arch-realview/param.h
+ *
+ * Copyright (C) 2002 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
+ */
diff --git a/include/asm-arm/arch-realview/platform.h b/include/asm-arm/arch-realview/platform.h
new file mode 100644
index 000000000000..18d7c18b738c
--- /dev/null
+++ b/include/asm-arm/arch-realview/platform.h
@@ -0,0 +1,450 @@
+/*
+ * linux/include/asm-arm/arch-realview/platform.h
+ *
+ * Copyright (c) ARM Limited 2003. 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 __address_h
+#define __address_h 1
+
+/*
+ * Memory definitions
+ */
+#define REALVIEW_BOOT_ROM_LO 0x30000000 /* DoC Base (64Mb)...*/
+#define REALVIEW_BOOT_ROM_HI 0x30000000
+#define REALVIEW_BOOT_ROM_BASE REALVIEW_BOOT_ROM_HI /* Normal position */
+#define REALVIEW_BOOT_ROM_SIZE SZ_64M
+
+#define REALVIEW_SSRAM_BASE /* REALVIEW_SSMC_BASE ? */
+#define REALVIEW_SSRAM_SIZE SZ_2M
+
+#define REALVIEW_FLASH_BASE 0x40000000
+#define REALVIEW_FLASH_SIZE SZ_64M
+
+/*
+ * SDRAM
+ */
+#define REALVIEW_SDRAM_BASE 0x00000000
+
+/*
+ * Logic expansion modules
+ *
+ */
+
+
+/* ------------------------------------------------------------------------
+ * RealView Registers
+ * ------------------------------------------------------------------------
+ *
+ */
+#define REALVIEW_SYS_ID_OFFSET 0x00
+#define REALVIEW_SYS_SW_OFFSET 0x04
+#define REALVIEW_SYS_LED_OFFSET 0x08
+#define REALVIEW_SYS_OSC0_OFFSET 0x0C
+
+#define REALVIEW_SYS_OSC1_OFFSET 0x10
+#define REALVIEW_SYS_OSC2_OFFSET 0x14
+#define REALVIEW_SYS_OSC3_OFFSET 0x18
+#define REALVIEW_SYS_OSC4_OFFSET 0x1C /* OSC1 for RealView/AB */
+
+#define REALVIEW_SYS_LOCK_OFFSET 0x20
+#define REALVIEW_SYS_100HZ_OFFSET 0x24
+#define REALVIEW_SYS_CFGDATA1_OFFSET 0x28
+#define REALVIEW_SYS_CFGDATA2_OFFSET 0x2C
+#define REALVIEW_SYS_FLAGS_OFFSET 0x30
+#define REALVIEW_SYS_FLAGSSET_OFFSET 0x30
+#define REALVIEW_SYS_FLAGSCLR_OFFSET 0x34
+#define REALVIEW_SYS_NVFLAGS_OFFSET 0x38
+#define REALVIEW_SYS_NVFLAGSSET_OFFSET 0x38
+#define REALVIEW_SYS_NVFLAGSCLR_OFFSET 0x3C
+#define REALVIEW_SYS_RESETCTL_OFFSET 0x40
+#define REALVIEW_SYS_PCICTL_OFFSET 0x44
+#define REALVIEW_SYS_MCI_OFFSET 0x48
+#define REALVIEW_SYS_FLASH_OFFSET 0x4C
+#define REALVIEW_SYS_CLCD_OFFSET 0x50
+#define REALVIEW_SYS_CLCDSER_OFFSET 0x54
+#define REALVIEW_SYS_BOOTCS_OFFSET 0x58
+#define REALVIEW_SYS_24MHz_OFFSET 0x5C
+#define REALVIEW_SYS_MISC_OFFSET 0x60
+#define REALVIEW_SYS_IOSEL_OFFSET 0x70
+#define REALVIEW_SYS_TEST_OSC0_OFFSET 0x80
+#define REALVIEW_SYS_TEST_OSC1_OFFSET 0x84
+#define REALVIEW_SYS_TEST_OSC2_OFFSET 0x88
+#define REALVIEW_SYS_TEST_OSC3_OFFSET 0x8C
+#define REALVIEW_SYS_TEST_OSC4_OFFSET 0x90
+
+#define REALVIEW_SYS_BASE 0x10000000
+#define REALVIEW_SYS_ID (REALVIEW_SYS_BASE + REALVIEW_SYS_ID_OFFSET)
+#define REALVIEW_SYS_SW (REALVIEW_SYS_BASE + REALVIEW_SYS_SW_OFFSET)
+#define REALVIEW_SYS_LED (REALVIEW_SYS_BASE + REALVIEW_SYS_LED_OFFSET)
+#define REALVIEW_SYS_OSC0 (REALVIEW_SYS_BASE + REALVIEW_SYS_OSC0_OFFSET)
+#define REALVIEW_SYS_OSC1 (REALVIEW_SYS_BASE + REALVIEW_SYS_OSC1_OFFSET)
+
+#define REALVIEW_SYS_LOCK (REALVIEW_SYS_BASE + REALVIEW_SYS_LOCK_OFFSET)
+#define REALVIEW_SYS_100HZ (REALVIEW_SYS_BASE + REALVIEW_SYS_100HZ_OFFSET)
+#define REALVIEW_SYS_CFGDATA1 (REALVIEW_SYS_BASE + REALVIEW_SYS_CFGDATA1_OFFSET)
+#define REALVIEW_SYS_CFGDATA2 (REALVIEW_SYS_BASE + REALVIEW_SYS_CFGDATA2_OFFSET)
+#define REALVIEW_SYS_FLAGS (REALVIEW_SYS_BASE + REALVIEW_SYS_FLAGS_OFFSET)
+#define REALVIEW_SYS_FLAGSSET (REALVIEW_SYS_BASE + REALVIEW_SYS_FLAGSSET_OFFSET)
+#define REALVIEW_SYS_FLAGSCLR (REALVIEW_SYS_BASE + REALVIEW_SYS_FLAGSCLR_OFFSET)
+#define REALVIEW_SYS_NVFLAGS (REALVIEW_SYS_BASE + REALVIEW_SYS_NVFLAGS_OFFSET)
+#define REALVIEW_SYS_NVFLAGSSET (REALVIEW_SYS_BASE + REALVIEW_SYS_NVFLAGSSET_OFFSET)
+#define REALVIEW_SYS_NVFLAGSCLR (REALVIEW_SYS_BASE + REALVIEW_SYS_NVFLAGSCLR_OFFSET)
+#define REALVIEW_SYS_RESETCTL (REALVIEW_SYS_BASE + REALVIEW_SYS_RESETCTL_OFFSET)
+#define REALVIEW_SYS_PCICTL (REALVIEW_SYS_BASE + REALVIEW_SYS_PCICTL_OFFSET)
+#define REALVIEW_SYS_MCI (REALVIEW_SYS_BASE + REALVIEW_SYS_MCI_OFFSET)
+#define REALVIEW_SYS_FLASH (REALVIEW_SYS_BASE + REALVIEW_SYS_FLASH_OFFSET)
+#define REALVIEW_SYS_CLCD (REALVIEW_SYS_BASE + REALVIEW_SYS_CLCD_OFFSET)
+#define REALVIEW_SYS_CLCDSER (REALVIEW_SYS_BASE + REALVIEW_SYS_CLCDSER_OFFSET)
+#define REALVIEW_SYS_BOOTCS (REALVIEW_SYS_BASE + REALVIEW_SYS_BOOTCS_OFFSET)
+#define REALVIEW_SYS_24MHz (REALVIEW_SYS_BASE + REALVIEW_SYS_24MHz_OFFSET)
+#define REALVIEW_SYS_MISC (REALVIEW_SYS_BASE + REALVIEW_SYS_MISC_OFFSET)
+#define REALVIEW_SYS_IOSEL (REALVIEW_SYS_BASE + REALVIEW_SYS_IOSEL_OFFSET)
+#define REALVIEW_SYS_TEST_OSC0 (REALVIEW_SYS_BASE + REALVIEW_SYS_TEST_OSC0_OFFSET)
+#define REALVIEW_SYS_TEST_OSC1 (REALVIEW_SYS_BASE + REALVIEW_SYS_TEST_OSC1_OFFSET)
+#define REALVIEW_SYS_TEST_OSC2 (REALVIEW_SYS_BASE + REALVIEW_SYS_TEST_OSC2_OFFSET)
+#define REALVIEW_SYS_TEST_OSC3 (REALVIEW_SYS_BASE + REALVIEW_SYS_TEST_OSC3_OFFSET)
+#define REALVIEW_SYS_TEST_OSC4 (REALVIEW_SYS_BASE + REALVIEW_SYS_TEST_OSC4_OFFSET)
+
+/*
+ * Values for REALVIEW_SYS_RESET_CTRL
+ */
+#define REALVIEW_SYS_CTRL_RESET_CONFIGCLR 0x01
+#define REALVIEW_SYS_CTRL_RESET_CONFIGINIT 0x02
+#define REALVIEW_SYS_CTRL_RESET_DLLRESET 0x03
+#define REALVIEW_SYS_CTRL_RESET_PLLRESET 0x04
+#define REALVIEW_SYS_CTRL_RESET_POR 0x05
+#define REALVIEW_SYS_CTRL_RESET_DoC 0x06
+
+#define REALVIEW_SYS_CTRL_LED (1 << 0)
+
+
+/* ------------------------------------------------------------------------
+ * RealView control registers
+ * ------------------------------------------------------------------------
+ */
+
+/*
+ * REALVIEW_IDFIELD
+ *
+ * 31:24 = manufacturer (0x41 = ARM)
+ * 23:16 = architecture (0x08 = AHB system bus, ASB processor bus)
+ * 15:12 = FPGA (0x3 = XVC600 or XVC600E)
+ * 11:4 = build value
+ * 3:0 = revision number (0x1 = rev B (AHB))
+ */
+
+/*
+ * REALVIEW_SYS_LOCK
+ * control access to SYS_OSCx, SYS_CFGDATAx, SYS_RESETCTL,
+ * SYS_CLD, SYS_BOOTCS
+ */
+#define REALVIEW_SYS_LOCK_LOCKED (1 << 16)
+#define REALVIEW_SYS_LOCKVAL_MASK 0xFFFF /* write 0xA05F to enable write access */
+
+/*
+ * REALVIEW_SYS_FLASH
+ */
+#define REALVIEW_FLASHPROG_FLVPPEN (1 << 0) /* Enable writing to flash */
+
+/*
+ * REALVIEW_INTREG
+ * - used to acknowledge and control MMCI and UART interrupts
+ */
+#define REALVIEW_INTREG_WPROT 0x00 /* MMC protection status (no interrupt generated) */
+#define REALVIEW_INTREG_RI0 0x01 /* Ring indicator UART0 is asserted, */
+#define REALVIEW_INTREG_CARDIN 0x08 /* MMCI card in detect */
+ /* write 1 to acknowledge and clear */
+#define REALVIEW_INTREG_RI1 0x02 /* Ring indicator UART1 is asserted, */
+#define REALVIEW_INTREG_CARDINSERT 0x03 /* Signal insertion of MMC card */
+
+/*
+ * REALVIEW peripheral addresses
+ */
+#define REALVIEW_SCTL_BASE 0x10001000 /* System controller */
+#define REALVIEW_I2C_BASE 0x10002000 /* I2C control */
+ /* Reserved 0x10003000 */
+#define REALVIEW_AACI_BASE 0x10004000 /* Audio */
+#define REALVIEW_MMCI0_BASE 0x10005000 /* MMC interface */
+#define REALVIEW_KMI0_BASE 0x10006000 /* KMI interface */
+#define REALVIEW_KMI1_BASE 0x10007000 /* KMI 2nd interface */
+#define REALVIEW_CHAR_LCD_BASE 0x10008000 /* Character LCD */
+#define REALVIEW_UART0_BASE 0x10009000 /* UART 0 */
+#define REALVIEW_UART1_BASE 0x1000A000 /* UART 1 */
+#define REALVIEW_UART2_BASE 0x1000B000 /* UART 2 */
+#define REALVIEW_UART3_BASE 0x1000C000 /* UART 3 */
+#define REALVIEW_SSP_BASE 0x1000D000 /* Synchronous Serial Port */
+#define REALVIEW_SCI_BASE 0x1000E000 /* Smart card controller */
+ /* Reserved 0x1000F000 */
+#define REALVIEW_WATCHDOG_BASE 0x10010000 /* watchdog interface */
+#define REALVIEW_TIMER0_1_BASE 0x10011000 /* Timer 0 and 1 */
+#define REALVIEW_TIMER2_3_BASE 0x10012000 /* Timer 2 and 3 */
+#define REALVIEW_GPIO0_BASE 0x10013000 /* GPIO port 0 */
+#define REALVIEW_GPIO1_BASE 0x10014000 /* GPIO port 1 */
+#define REALVIEW_GPIO2_BASE 0x10015000 /* GPIO port 2 */
+ /* Reserved 0x10016000 */
+#define REALVIEW_RTC_BASE 0x10017000 /* Real Time Clock */
+#define REALVIEW_DMC_BASE 0x10018000 /* DMC configuration */
+#define REALVIEW_PCI_CORE_BASE 0x10019000 /* PCI configuration */
+ /* Reserved 0x1001A000 - 0x1001FFFF */
+#define REALVIEW_CLCD_BASE 0x10020000 /* CLCD */
+#define REALVIEW_DMAC_BASE 0x10030000 /* DMA controller */
+#ifndef CONFIG_REALVIEW_MPCORE
+#define REALVIEW_GIC_CPU_BASE 0x10040000 /* Generic interrupt controller CPU interface */
+#define REALVIEW_GIC_DIST_BASE 0x10041000 /* Generic interrupt controller distributor */
+#else
+#define REALVIEW_MPCORE_SCU_BASE 0x10100000 /* SCU registers */
+#define REALVIEW_GIC_CPU_BASE 0x10100100 /* Generic interrupt controller CPU interface */
+#define REALVIEW_TWD_BASE 0x10100700
+#define REALVIEW_TWD_SIZE 0x00000100
+#define REALVIEW_GIC_DIST_BASE 0x10101000 /* Generic interrupt controller distributor */
+#endif
+#define REALVIEW_SMC_BASE 0x10080000 /* SMC */
+ /* Reserved 0x10090000 - 0x100EFFFF */
+
+#define REALVIEW_ETH_BASE 0x4E000000 /* Ethernet */
+
+/* PCI space */
+#define REALVIEW_PCI_BASE 0x41000000 /* PCI Interface */
+#define REALVIEW_PCI_CFG_BASE 0x42000000
+#define REALVIEW_PCI_MEM_BASE0 0x44000000
+#define REALVIEW_PCI_MEM_BASE1 0x50000000
+#define REALVIEW_PCI_MEM_BASE2 0x60000000
+/* Sizes of above maps */
+#define REALVIEW_PCI_BASE_SIZE 0x01000000
+#define REALVIEW_PCI_CFG_BASE_SIZE 0x02000000
+#define REALVIEW_PCI_MEM_BASE0_SIZE 0x0c000000 /* 32Mb */
+#define REALVIEW_PCI_MEM_BASE1_SIZE 0x10000000 /* 256Mb */
+#define REALVIEW_PCI_MEM_BASE2_SIZE 0x10000000 /* 256Mb */
+
+#define REALVIEW_SDRAM67_BASE 0x70000000 /* SDRAM banks 6 and 7 */
+#define REALVIEW_LT_BASE 0x80000000 /* Logic Tile expansion */
+
+/*
+ * Disk on Chip
+ */
+#define REALVIEW_DOC_BASE 0x2C000000
+#define REALVIEW_DOC_SIZE (16 << 20)
+#define REALVIEW_DOC_PAGE_SIZE 512
+#define REALVIEW_DOC_TOTAL_PAGES (DOC_SIZE / PAGE_SIZE)
+
+#define ERASE_UNIT_PAGES 32
+#define START_PAGE 0x80
+
+/*
+ * LED settings, bits [7:0]
+ */
+#define REALVIEW_SYS_LED0 (1 << 0)
+#define REALVIEW_SYS_LED1 (1 << 1)
+#define REALVIEW_SYS_LED2 (1 << 2)
+#define REALVIEW_SYS_LED3 (1 << 3)
+#define REALVIEW_SYS_LED4 (1 << 4)
+#define REALVIEW_SYS_LED5 (1 << 5)
+#define REALVIEW_SYS_LED6 (1 << 6)
+#define REALVIEW_SYS_LED7 (1 << 7)
+
+#define ALL_LEDS 0xFF
+
+#define LED_BANK REALVIEW_SYS_LED
+
+/*
+ * Control registers
+ */
+#define REALVIEW_IDFIELD_OFFSET 0x0 /* RealView build information */
+#define REALVIEW_FLASHPROG_OFFSET 0x4 /* Flash devices */
+#define REALVIEW_INTREG_OFFSET 0x8 /* Interrupt control */
+#define REALVIEW_DECODE_OFFSET 0xC /* Fitted logic modules */
+
+/* ------------------------------------------------------------------------
+ * Interrupts - bit assignment (primary)
+ * ------------------------------------------------------------------------
+ */
+#ifndef CONFIG_REALVIEW_MPCORE
+#define INT_WDOGINT 0 /* Watchdog timer */
+#define INT_SOFTINT 1 /* Software interrupt */
+#define INT_COMMRx 2 /* Debug Comm Rx interrupt */
+#define INT_COMMTx 3 /* Debug Comm Tx interrupt */
+#define INT_TIMERINT0_1 4 /* Timer 0 and 1 */
+#define INT_TIMERINT2_3 5 /* Timer 2 and 3 */
+#define INT_GPIOINT0 6 /* GPIO 0 */
+#define INT_GPIOINT1 7 /* GPIO 1 */
+#define INT_GPIOINT2 8 /* GPIO 2 */
+/* 9 reserved */
+#define INT_RTCINT 10 /* Real Time Clock */
+#define INT_SSPINT 11 /* Synchronous Serial Port */
+#define INT_UARTINT0 12 /* UART 0 on development chip */
+#define INT_UARTINT1 13 /* UART 1 on development chip */
+#define INT_UARTINT2 14 /* UART 2 on development chip */
+#define INT_UARTINT3 15 /* UART 3 on development chip */
+#define INT_SCIINT 16 /* Smart Card Interface */
+#define INT_MMCI0A 17 /* Multimedia Card 0A */
+#define INT_MMCI0B 18 /* Multimedia Card 0B */
+#define INT_AACI 19 /* Audio Codec */
+#define INT_KMI0 20 /* Keyboard/Mouse port 0 */
+#define INT_KMI1 21 /* Keyboard/Mouse port 1 */
+#define INT_CHARLCD 22 /* Character LCD */
+#define INT_CLCDINT 23 /* CLCD controller */
+#define INT_DMAINT 24 /* DMA controller */
+#define INT_PWRFAILINT 25 /* Power failure */
+#define INT_PISMO 26
+#define INT_DoC 27 /* Disk on Chip memory controller */
+#define INT_ETH 28 /* Ethernet controller */
+#define INT_USB 29 /* USB controller */
+#define INT_TSPENINT 30 /* Touchscreen pen */
+#define INT_TSKPADINT 31 /* Touchscreen keypad */
+#else
+#define INT_AACI 0
+#define INT_TIMERINT0_1 1
+#define INT_TIMERINT2_3 2
+#define INT_USB 3
+#define INT_UARTINT0 4
+#define INT_UARTINT1 5
+#define INT_RTCINT 6
+#define INT_KMI0 7
+#define INT_KMI1 8
+#define INT_ETH 9
+#define INT_EB_IRQ1 10 /* main GIC */
+#define INT_EB_IRQ2 11 /* tile GIC */
+#define INT_EB_FIQ1 12 /* main GIC */
+#define INT_EB_FIQ2 13 /* tile GIC */
+#define INT_MMCI0A 14
+#define INT_MMCI0B 15
+
+#define INT_PMU_CPU0 17
+#define INT_PMU_CPU1 18
+#define INT_PMU_CPU2 19
+#define INT_PMU_CPU3 20
+#define INT_PMU_SCU0 21
+#define INT_PMU_SCU1 22
+#define INT_PMU_SCU2 23
+#define INT_PMU_SCU3 24
+#define INT_PMU_SCU4 25
+#define INT_PMU_SCU5 26
+#define INT_PMU_SCU6 27
+#define INT_PMU_SCU7 28
+
+#define INT_L220_EVENT 29
+#define INT_L220_SLAVE 30
+#define INT_L220_DECODE 31
+
+#define INT_UARTINT2 -1
+#define INT_UARTINT3 -1
+#define INT_CLCDINT -1
+#define INT_DMAINT -1
+#define INT_WDOGINT -1
+#define INT_GPIOINT0 -1
+#define INT_GPIOINT1 -1
+#define INT_GPIOINT2 -1
+#define INT_SCIINT -1
+#define INT_SSPINT -1
+#endif
+
+/*
+ * Interrupt bit positions
+ *
+ */
+#define INTMASK_WDOGINT (1 << INT_WDOGINT)
+#define INTMASK_SOFTINT (1 << INT_SOFTINT)
+#define INTMASK_COMMRx (1 << INT_COMMRx)
+#define INTMASK_COMMTx (1 << INT_COMMTx)
+#define INTMASK_TIMERINT0_1 (1 << INT_TIMERINT0_1)
+#define INTMASK_TIMERINT2_3 (1 << INT_TIMERINT2_3)
+#define INTMASK_GPIOINT0 (1 << INT_GPIOINT0)
+#define INTMASK_GPIOINT1 (1 << INT_GPIOINT1)
+#define INTMASK_GPIOINT2 (1 << INT_GPIOINT2)
+#define INTMASK_RTCINT (1 << INT_RTCINT)
+#define INTMASK_SSPINT (1 << INT_SSPINT)
+#define INTMASK_UARTINT0 (1 << INT_UARTINT0)
+#define INTMASK_UARTINT1 (1 << INT_UARTINT1)
+#define INTMASK_UARTINT2 (1 << INT_UARTINT2)
+#define INTMASK_UARTINT3 (1 << INT_UARTINT3)
+#define INTMASK_SCIINT (1 << INT_SCIINT)
+#define INTMASK_MMCI0A (1 << INT_MMCI0A)
+#define INTMASK_MMCI0B (1 << INT_MMCI0B)
+#define INTMASK_AACI (1 << INT_AACI)
+#define INTMASK_KMI0 (1 << INT_KMI0)
+#define INTMASK_KMI1 (1 << INT_KMI1)
+#define INTMASK_CHARLCD (1 << INT_CHARLCD)
+#define INTMASK_CLCDINT (1 << INT_CLCDINT)
+#define INTMASK_DMAINT (1 << INT_DMAINT)
+#define INTMASK_PWRFAILINT (1 << INT_PWRFAILINT)
+#define INTMASK_PISMO (1 << INT_PISMO)
+#define INTMASK_DoC (1 << INT_DoC)
+#define INTMASK_ETH (1 << INT_ETH)
+#define INTMASK_USB (1 << INT_USB)
+#define INTMASK_TSPENINT (1 << INT_TSPENINT)
+#define INTMASK_TSKPADINT (1 << INT_TSKPADINT)
+
+#define MAXIRQNUM 31
+#define MAXFIQNUM 31
+#define MAXSWINUM 31
+
+/*
+ * Application Flash
+ *
+ */
+#define FLASH_BASE REALVIEW_FLASH_BASE
+#define FLASH_SIZE REALVIEW_FLASH_SIZE
+#define FLASH_END (FLASH_BASE + FLASH_SIZE - 1)
+#define FLASH_BLOCK_SIZE SZ_128K
+
+/*
+ * Boot Flash
+ *
+ */
+#define EPROM_BASE REALVIEW_BOOT_ROM_HI
+#define EPROM_SIZE REALVIEW_BOOT_ROM_SIZE
+#define EPROM_END (EPROM_BASE + EPROM_SIZE - 1)
+
+/*
+ * Clean base - dummy
+ *
+ */
+#define CLEAN_BASE EPROM_BASE
+
+/*
+ * System controller bit assignment
+ */
+#define REALVIEW_REFCLK 0
+#define REALVIEW_TIMCLK 1
+
+#define REALVIEW_TIMER1_EnSel 15
+#define REALVIEW_TIMER2_EnSel 17
+#define REALVIEW_TIMER3_EnSel 19
+#define REALVIEW_TIMER4_EnSel 21
+
+
+#define MAX_TIMER 2
+#define MAX_PERIOD 699050
+#define TICKS_PER_uSEC 1
+
+/*
+ * These are useconds NOT ticks.
+ *
+ */
+#define mSEC_1 1000
+#define mSEC_5 (mSEC_1 * 5)
+#define mSEC_10 (mSEC_1 * 10)
+#define mSEC_25 (mSEC_1 * 25)
+#define SEC_1 (mSEC_1 * 1000)
+
+#define REALVIEW_CSR_BASE 0x10000000
+#define REALVIEW_CSR_SIZE 0x10000000
+
+#endif
+
+/* END */
diff --git a/include/asm-arm/arch-realview/smp.h b/include/asm-arm/arch-realview/smp.h
new file mode 100644
index 000000000000..fc87783e8e8b
--- /dev/null
+++ b/include/asm-arm/arch-realview/smp.h
@@ -0,0 +1,31 @@
+#ifndef ASMARM_ARCH_SMP_H
+#define ASMARM_ARCH_SMP_H
+
+#include <linux/config.h>
+
+#include <asm/hardware/gic.h>
+
+#define hard_smp_processor_id() \
+ ({ \
+ unsigned int cpunum; \
+ __asm__("mrc p15, 0, %0, c0, c0, 5" \
+ : "=r" (cpunum)); \
+ cpunum &= 0x0F; \
+ })
+
+/*
+ * We use IRQ1 as the IPI
+ */
+static inline void smp_cross_call(cpumask_t callmap)
+{
+ gic_raise_softirq(callmap, 1);
+}
+
+/*
+ * Do nothing on MPcore.
+ */
+static inline void smp_cross_call_done(cpumask_t callmap)
+{
+}
+
+#endif
diff --git a/include/asm-arm/arch-realview/system.h b/include/asm-arm/arch-realview/system.h
new file mode 100644
index 000000000000..9f8fcbca0869
--- /dev/null
+++ b/include/asm-arm/arch-realview/system.h
@@ -0,0 +1,51 @@
+/*
+ * linux/include/asm-arm/arch-realview/system.h
+ *
+ * Copyright (C) 2003 ARM Limited
+ * Copyright (C) 2000 Deep Blue Solutions Ltd
+ *
+ * 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 __ASM_ARCH_SYSTEM_H
+#define __ASM_ARCH_SYSTEM_H
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/arch/platform.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)
+{
+ unsigned int hdr_ctrl = (IO_ADDRESS(REALVIEW_SYS_BASE) + REALVIEW_SYS_RESETCTL_OFFSET);
+ unsigned int val;
+
+ /*
+ * To reset, we hit the on-board reset register
+ * in the system FPGA
+ */
+ val = __raw_readl(hdr_ctrl);
+ val |= REALVIEW_SYS_CTRL_RESET_CONFIGCLR;
+ __raw_writel(val, hdr_ctrl);
+}
+
+#endif
diff --git a/include/asm-arm/arch-realview/timex.h b/include/asm-arm/arch-realview/timex.h
new file mode 100644
index 000000000000..5b9d82d0a5e0
--- /dev/null
+++ b/include/asm-arm/arch-realview/timex.h
@@ -0,0 +1,23 @@
+/*
+ * linux/include/asm-arm/arch-realview/timex.h
+ *
+ * RealView architecture timex specifications
+ *
+ * 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 CLOCK_TICK_RATE (50000000 / 16)
diff --git a/include/asm-arm/arch-realview/uncompress.h b/include/asm-arm/arch-realview/uncompress.h
new file mode 100644
index 000000000000..b5e4d360665b
--- /dev/null
+++ b/include/asm-arm/arch-realview/uncompress.h
@@ -0,0 +1,54 @@
+/*
+ * linux/include/asm-arm/arch-realview/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
+ */
+#include <asm/hardware.h>
+
+#define AMBA_UART_DR (*(volatile unsigned char *) (REALVIEW_UART0_BASE + 0x00))
+#define AMBA_UART_LCRH (*(volatile unsigned char *) (REALVIEW_UART0_BASE + 0x2c))
+#define AMBA_UART_CR (*(volatile unsigned char *) (REALVIEW_UART0_BASE + 0x30))
+#define AMBA_UART_FR (*(volatile unsigned char *) (REALVIEW_UART0_BASE + 0x18))
+
+/*
+ * This does not append a newline
+ */
+static void putstr(const char *s)
+{
+ while (*s) {
+ while (AMBA_UART_FR & (1 << 5))
+ barrier();
+
+ AMBA_UART_DR = *s;
+
+ if (*s == '\n') {
+ while (AMBA_UART_FR & (1 << 5))
+ barrier();
+
+ AMBA_UART_DR = '\r';
+ }
+ s++;
+ }
+ while (AMBA_UART_FR & (1 << 3))
+ barrier();
+}
+
+/*
+ * nothing to do
+ */
+#define arch_decomp_setup()
+#define arch_decomp_wdog()
diff --git a/include/asm-arm/arch-realview/vmalloc.h b/include/asm-arm/arch-realview/vmalloc.h
new file mode 100644
index 000000000000..0ad49af186af
--- /dev/null
+++ b/include/asm-arm/arch-realview/vmalloc.h
@@ -0,0 +1,21 @@
+/*
+ * linux/include/asm-arm/arch-realview/vmalloc.h
+ *
+ * Copyright (C) 2003 ARM Limited
+ * Copyright (C) 2000 Russell King.
+ *
+ * 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 VMALLOC_END (PAGE_OFFSET + 0x18000000)
diff --git a/include/asm-arm/arch-rpc/io.h b/include/asm-arm/arch-rpc/io.h
index 24453c405a87..b4da08d7a336 100644
--- a/include/asm-arm/arch-rpc/io.h
+++ b/include/asm-arm/arch-rpc/io.h
@@ -13,6 +13,8 @@
#ifndef __ASM_ARM_ARCH_IO_H
#define __ASM_ARM_ARCH_IO_H
+#include <asm/hardware.h>
+
#define IO_SPACE_LIMIT 0xffffffff
/*
diff --git a/include/asm-arm/arch-rpc/memory.h b/include/asm-arm/arch-rpc/memory.h
index 33fc75cdead0..0592cb3f0c74 100644
--- a/include/asm-arm/arch-rpc/memory.h
+++ b/include/asm-arm/arch-rpc/memory.h
@@ -21,7 +21,7 @@
/*
* Physical DRAM offset.
*/
-#define PHYS_OFFSET (0x10000000UL)
+#define PHYS_OFFSET UL(0x10000000)
/*
* These are exactly the same on the RiscPC as the
diff --git a/include/asm-arm/arch-s3c2410/fb.h b/include/asm-arm/arch-s3c2410/fb.h
index ac57bc887d82..4790491ba9d0 100644
--- a/include/asm-arm/arch-s3c2410/fb.h
+++ b/include/asm-arm/arch-s3c2410/fb.h
@@ -13,6 +13,7 @@
* 07-Sep-2004 RTP Created file
* 03-Nov-2004 BJD Updated and minor cleanups
* 03-Aug-2005 RTP Renamed to fb.h
+ * 26-Oct-2005 BJD Changed name of platdata init
*/
#ifndef __ASM_ARM_FB_H
@@ -64,6 +65,6 @@ struct s3c2410fb_mach_info {
unsigned long lpcsel;
};
-void __init set_s3c2410fb_info(struct s3c2410fb_mach_info *hard_s3c2410fb_info);
+extern void __init s3c24xx_fb_set_platdata(struct s3c2410fb_mach_info *);
#endif /* __ASM_ARM_FB_H */
diff --git a/include/asm-arm/arch-s3c2410/io.h b/include/asm-arm/arch-s3c2410/io.h
index 4bf272ed9add..16fbc8afffd9 100644
--- a/include/asm-arm/arch-s3c2410/io.h
+++ b/include/asm-arm/arch-s3c2410/io.h
@@ -15,6 +15,8 @@
#ifndef __ASM_ARM_ARCH_IO_H
#define __ASM_ARM_ARCH_IO_H
+#include <asm/hardware.h>
+
#define IO_SPACE_LIMIT 0xffffffff
/*
diff --git a/include/asm-arm/arch-s3c2410/memory.h b/include/asm-arm/arch-s3c2410/memory.h
index 3380ab1d0749..6ab834a14c8e 100644
--- a/include/asm-arm/arch-s3c2410/memory.h
+++ b/include/asm-arm/arch-s3c2410/memory.h
@@ -28,9 +28,9 @@
* and at 0x0C000000 for S3C2400
*/
#ifdef CONFIG_CPU_S3C2400
-#define PHYS_OFFSET (0x0C000000UL)
+#define PHYS_OFFSET UL(0x0C000000)
#else
-#define PHYS_OFFSET (0x30000000UL)
+#define PHYS_OFFSET UL(0x30000000)
#endif
/*
diff --git a/include/asm-arm/arch-s3c2410/regs-gpio.h b/include/asm-arm/arch-s3c2410/regs-gpio.h
index 2053cbacffc3..cb33d57c146c 100644
--- a/include/asm-arm/arch-s3c2410/regs-gpio.h
+++ b/include/asm-arm/arch-s3c2410/regs-gpio.h
@@ -20,6 +20,7 @@
* 18-11-2004 BJD Added S3C2440 AC97 controls
* 10-Mar-2005 LCVR Changed S3C2410_VA to S3C24XX_VA
* 28-Mar-2005 LCVR Fixed definition of GPB10
+ * 26-Oct-2005 BJD Added generic configuration types
*/
@@ -43,6 +44,11 @@
/* general configuration options */
#define S3C2410_GPIO_LEAVE (0xFFFFFFFF)
+#define S3C2410_GPIO_INPUT (0xFFFFFFF0)
+#define S3C2410_GPIO_OUTPUT (0xFFFFFFF1)
+#define S3C2410_GPIO_IRQ (0xFFFFFFF2) /* not available for all */
+#define S3C2410_GPIO_SFN2 (0xFFFFFFF2) /* not available on A */
+#define S3C2410_GPIO_SFN3 (0xFFFFFFF3) /* not available on A */
/* configure GPIO ports A..G */
diff --git a/include/asm-arm/arch-s3c2410/regs-iis.h b/include/asm-arm/arch-s3c2410/regs-iis.h
index fdd62e8cd6cb..7fdde9b91cb4 100644
--- a/include/asm-arm/arch-s3c2410/regs-iis.h
+++ b/include/asm-arm/arch-s3c2410/regs-iis.h
@@ -55,6 +55,7 @@
#define S3C2410_IISMOD_16FS (0<<0)
#define S3C2410_IISMOD_32FS (1<<0)
#define S3C2410_IISMOD_48FS (2<<0)
+#define S3C2410_IISMOD_FS_MASK (3<<0)
#define S3C2410_IISPSR (0x08)
#define S3C2410_IISPSR_INTMASK (31<<5)
diff --git a/include/asm-arm/arch-s3c2410/uncompress.h b/include/asm-arm/arch-s3c2410/uncompress.h
index d7a4a8354fa9..ddd1578a7ee0 100644
--- a/include/asm-arm/arch-s3c2410/uncompress.h
+++ b/include/asm-arm/arch-s3c2410/uncompress.h
@@ -116,6 +116,8 @@ putstr(const char *ptr)
}
}
+#define __raw_writel(d,ad) do { *((volatile unsigned int *)(ad)) = (d); } while(0)
+
/* CONFIG_S3C2410_BOOT_WATCHDOG
*
* Simple boot-time watchdog setup, to reboot the system if there is
@@ -126,8 +128,6 @@ putstr(const char *ptr)
#define WDOG_COUNT (0xff00)
-#define __raw_writel(d,ad) do { *((volatile unsigned int *)(ad)) = (d); } while(0)
-
static inline void arch_decomp_wdog(void)
{
__raw_writel(WDOG_COUNT, S3C2410_WTCNT);
@@ -145,6 +145,24 @@ static void arch_decomp_wdog_start(void)
#define arch_decomp_wdog()
#endif
+#ifdef CONFIG_S3C2410_BOOT_ERROR_RESET
+
+static void arch_decomp_error(const char *x)
+{
+ putstr("\n\n");
+ putstr(x);
+ putstr("\n\n -- System resetting\n");
+
+ __raw_writel(0x4000, S3C2410_WTDAT);
+ __raw_writel(0x4000, S3C2410_WTCNT);
+ __raw_writel(S3C2410_WTCON_ENABLE | S3C2410_WTCON_DIV128 | S3C2410_WTCON_RSTEN | S3C2410_WTCON_PRESCALE(0x40), S3C2410_WTCON);
+
+ while(1);
+}
+
+#define arch_error arch_decomp_error
+#endif
+
static void error(char *err);
static void
diff --git a/include/asm-arm/arch-sa1100/hardware.h b/include/asm-arm/arch-sa1100/hardware.h
index 19c3b1e186bb..28711aaa4968 100644
--- a/include/asm-arm/arch-sa1100/hardware.h
+++ b/include/asm-arm/arch-sa1100/hardware.h
@@ -22,13 +22,6 @@
/*
- * We requires absolute addresses i.e. (PCMCIA_IO_0_BASE + 0x3f8) for
- * in*()/out*() macros to be usable for all cases.
- */
-#define PCIO_BASE 0
-
-
-/*
* SA1100 internal I/O mappings
*
* We have the following mapping:
diff --git a/include/asm-arm/arch-sa1100/io.h b/include/asm-arm/arch-sa1100/io.h
index 7d969ffbd3bb..9d4fe6cf205b 100644
--- a/include/asm-arm/arch-sa1100/io.h
+++ b/include/asm-arm/arch-sa1100/io.h
@@ -10,13 +10,19 @@
#ifndef __ASM_ARM_ARCH_IO_H
#define __ASM_ARM_ARCH_IO_H
+#include <asm/hardware.h>
+
#define IO_SPACE_LIMIT 0xffffffff
/*
* We don't actually have real ISA nor PCI buses, but there is so many
* drivers out there that might just work if we fake them...
*/
-#define __io(a) ((void __iomem *)(PCIO_BASE + (a)))
+static inline void __iomem *__io(unsigned long addr)
+{
+ return (void __iomem *)addr;
+}
+#define __io(a) __io(a)
#define __mem_pci(a) (a)
#define __mem_isa(a) (a)
diff --git a/include/asm-arm/arch-sa1100/memory.h b/include/asm-arm/arch-sa1100/memory.h
index 8743ff5c1b23..0fc555b4c912 100644
--- a/include/asm-arm/arch-sa1100/memory.h
+++ b/include/asm-arm/arch-sa1100/memory.h
@@ -13,7 +13,7 @@
/*
* Physical DRAM offset is 0xc0000000 on the SA1100
*/
-#define PHYS_OFFSET (0xc0000000UL)
+#define PHYS_OFFSET UL(0xc0000000)
#ifndef __ASSEMBLY__
diff --git a/include/asm-arm/arch-sa1100/system.h b/include/asm-arm/arch-sa1100/system.h
index 6f52118ba1a4..0f0612f79b2b 100644
--- a/include/asm-arm/arch-sa1100/system.h
+++ b/include/asm-arm/arch-sa1100/system.h
@@ -4,6 +4,7 @@
* Copyright (c) 1999 Nicolas Pitre <nico@cam.org>
*/
#include <linux/config.h>
+#include <asm/hardware.h>
static inline void arch_idle(void)
{
diff --git a/include/asm-arm/arch-shark/io.h b/include/asm-arm/arch-shark/io.h
index 5e6ed0038b2b..87ffa27f2962 100644
--- a/include/asm-arm/arch-shark/io.h
+++ b/include/asm-arm/arch-shark/io.h
@@ -11,6 +11,8 @@
#ifndef __ASM_ARM_ARCH_IO_H
#define __ASM_ARM_ARCH_IO_H
+#include <asm/hardware.h>
+
#define IO_SPACE_LIMIT 0xffffffff
/*
diff --git a/include/asm-arm/arch-shark/memory.h b/include/asm-arm/arch-shark/memory.h
index 8ff956d25463..95a29b4bc5d0 100644
--- a/include/asm-arm/arch-shark/memory.h
+++ b/include/asm-arm/arch-shark/memory.h
@@ -15,7 +15,7 @@
/*
* Physical DRAM offset.
*/
-#define PHYS_OFFSET (0x08000000UL)
+#define PHYS_OFFSET UL(0x08000000)
#ifndef __ASSEMBLY__
diff --git a/include/asm-arm/arch-versatile/memory.h b/include/asm-arm/arch-versatile/memory.h
index 7b8b7cc422fa..a9370976cc5e 100644
--- a/include/asm-arm/arch-versatile/memory.h
+++ b/include/asm-arm/arch-versatile/memory.h
@@ -23,7 +23,7 @@
/*
* Physical DRAM offset.
*/
-#define PHYS_OFFSET (0x00000000UL)
+#define PHYS_OFFSET UL(0x00000000)
/*
* Virtual view <-> DMA view memory address translations
diff --git a/include/asm-arm/assembler.h b/include/asm-arm/assembler.h
index 69a28f96bee2..f31ac92b6c7f 100644
--- a/include/asm-arm/assembler.h
+++ b/include/asm-arm/assembler.h
@@ -83,10 +83,13 @@
* Save the current IRQ state and disable IRQs. Note that this macro
* assumes FIQs are enabled, and that the processor is in SVC mode.
*/
- .macro save_and_disable_irqs, oldcpsr, temp
+ .macro save_and_disable_irqs, oldcpsr
mrs \oldcpsr, cpsr
- mov \temp, #PSR_I_BIT | MODE_SVC
- msr cpsr_c, \temp
+#if __LINUX_ARM_ARCH__ >= 6
+ cpsid i
+#else
+ msr cpsr_c, #PSR_I_BIT | MODE_SVC
+#endif
.endm
/*
diff --git a/include/asm-arm/cpu.h b/include/asm-arm/cpu.h
index fcbdd40cb667..751bc7462074 100644
--- a/include/asm-arm/cpu.h
+++ b/include/asm-arm/cpu.h
@@ -16,6 +16,7 @@
struct cpuinfo_arm {
struct cpu cpu;
#ifdef CONFIG_SMP
+ struct task_struct *idle;
unsigned int loops_per_jiffy;
#endif
};
diff --git a/include/asm-arm/dma-mapping.h b/include/asm-arm/dma-mapping.h
index d62ade4e4cbb..e3e8541ee63b 100644
--- a/include/asm-arm/dma-mapping.h
+++ b/include/asm-arm/dma-mapping.h
@@ -70,7 +70,7 @@ static inline int dma_mapping_error(dma_addr_t dma_addr)
* device-viewed address.
*/
extern void *
-dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *handle, int gfp);
+dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp);
/**
* dma_free_coherent - free memory allocated by dma_alloc_coherent
@@ -117,7 +117,7 @@ int dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
* device-viewed address.
*/
extern void *
-dma_alloc_writecombine(struct device *dev, size_t size, dma_addr_t *handle, int gfp);
+dma_alloc_writecombine(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp);
#define dma_free_writecombine(dev,size,cpu_addr,handle) \
dma_free_coherent(dev,size,cpu_addr,handle)
diff --git a/include/asm-arm/hardirq.h b/include/asm-arm/hardirq.h
index e5ccb6b8ff83..1cbb173bf5b1 100644
--- a/include/asm-arm/hardirq.h
+++ b/include/asm-arm/hardirq.h
@@ -8,6 +8,7 @@
typedef struct {
unsigned int __softirq_pending;
+ unsigned int local_timer_irqs;
} ____cacheline_aligned irq_cpustat_t;
#include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */
diff --git a/include/asm-arm/hardware/amba_clcd.h b/include/asm-arm/hardware/amba_clcd.h
index ce4cf5c1c05d..6b8d73dc1ab0 100644
--- a/include/asm-arm/hardware/amba_clcd.h
+++ b/include/asm-arm/hardware/amba_clcd.h
@@ -22,7 +22,7 @@
#define CLCD_UBAS 0x00000010
#define CLCD_LBAS 0x00000014
-#ifndef CONFIG_ARCH_VERSATILE
+#if !defined(CONFIG_ARCH_VERSATILE) && !defined(CONFIG_ARCH_REALVIEW)
#define CLCD_IENB 0x00000018
#define CLCD_CNTL 0x0000001c
#else
diff --git a/include/asm-arm/hardware/arm_scu.h b/include/asm-arm/hardware/arm_scu.h
new file mode 100644
index 000000000000..9903f60c84b7
--- /dev/null
+++ b/include/asm-arm/hardware/arm_scu.h
@@ -0,0 +1,13 @@
+#ifndef ASMARM_HARDWARE_ARM_SCU_H
+#define ASMARM_HARDWARE_ARM_SCU_H
+
+/*
+ * SCU registers
+ */
+#define SCU_CTRL 0x00
+#define SCU_CONFIG 0x04
+#define SCU_CPU_STATUS 0x08
+#define SCU_INVALIDATE 0x0c
+#define SCU_FPGA_REVISION 0x10
+
+#endif
diff --git a/include/asm-arm/hardware/scoop.h b/include/asm-arm/hardware/scoop.h
index a8f1013930e3..d37bf7443264 100644
--- a/include/asm-arm/hardware/scoop.h
+++ b/include/asm-arm/hardware/scoop.h
@@ -52,8 +52,14 @@ struct scoop_pcmcia_dev {
unsigned char keep_rd;
};
-extern int scoop_num;
-extern struct scoop_pcmcia_dev *scoop_devs;
+struct scoop_pcmcia_config {
+ struct scoop_pcmcia_dev *devs;
+ int num_devs;
+ void (*pcmcia_init)(void);
+ void (*power_ctrl)(struct device *scoop, unsigned short cpr, int nr);
+};
+
+extern struct scoop_pcmcia_config *platform_scoop_config;
void reset_scoop(struct device *dev);
unsigned short set_scoop_gpio(struct device *dev, unsigned short bit);
diff --git a/include/asm-arm/io.h b/include/asm-arm/io.h
index 5c4ae8f5dbb0..2e6799632f12 100644
--- a/include/asm-arm/io.h
+++ b/include/asm-arm/io.h
@@ -26,7 +26,6 @@
#include <linux/types.h>
#include <asm/byteorder.h>
#include <asm/memory.h>
-#include <asm/arch/hardware.h>
/*
* ISA I/O bus memory addresses are 1:1 with the physical address.
diff --git a/include/asm-arm/irq.h b/include/asm-arm/irq.h
index f97912fbb10f..59975ee43cf1 100644
--- a/include/asm-arm/irq.h
+++ b/include/asm-arm/irq.h
@@ -47,5 +47,6 @@ struct irqaction;
struct pt_regs;
int handle_IRQ_event(unsigned int, struct pt_regs *, struct irqaction *);
+extern void migrate_irqs(void);
#endif
diff --git a/include/asm-arm/mach/arch.h b/include/asm-arm/mach/arch.h
index 4fa95084a8c0..eb262e078c46 100644
--- a/include/asm-arm/mach/arch.h
+++ b/include/asm-arm/mach/arch.h
@@ -48,10 +48,11 @@ struct machine_desc {
* Set of macros to define architecture features. This is built into
* a table by the linker.
*/
-#define MACHINE_START(_type,_name) \
-const struct machine_desc __mach_desc_##_type \
+#define MACHINE_START(_type,_name) \
+static const struct machine_desc __mach_desc_##_type \
+ __attribute_used__ \
__attribute__((__section__(".arch.info.init"))) = { \
- .nr = MACH_TYPE_##_type, \
+ .nr = MACH_TYPE_##_type, \
.name = _name,
#define MACHINE_END \
diff --git a/include/asm-arm/mach/flash.h b/include/asm-arm/mach/flash.h
index a92887d4b2cb..05b029ef6371 100644
--- a/include/asm-arm/mach/flash.h
+++ b/include/asm-arm/mach/flash.h
@@ -11,22 +11,27 @@
#define ASMARM_MACH_FLASH_H
struct mtd_partition;
+struct mtd_info;
/*
* map_name: the map probe function name
+ * name: flash device name (eg, as used with mtdparts=)
* width: width of mapped device
* init: method called at driver/device initialisation
* exit: method called at driver/device removal
* set_vpp: method called to enable or disable VPP
+ * mmcontrol: method called to enable or disable Sync. Burst Read in OneNAND
* parts: optional array of mtd_partitions for static partitioning
* nr_parts: number of mtd_partitions for static partitoning
*/
struct flash_platform_data {
const char *map_name;
+ const char *name;
unsigned int width;
int (*init)(void);
void (*exit)(void);
void (*set_vpp)(int on);
+ void (*mmcontrol)(struct mtd_info *mtd, int sync_read);
struct mtd_partition *parts;
unsigned int nr_parts;
};
diff --git a/include/asm-arm/mach/map.h b/include/asm-arm/mach/map.h
index 9ac47cf8d2e4..b338936bde4f 100644
--- a/include/asm-arm/mach/map.h
+++ b/include/asm-arm/mach/map.h
@@ -11,7 +11,7 @@
*/
struct map_desc {
unsigned long virtual;
- unsigned long physical;
+ unsigned long pfn;
unsigned long length;
unsigned int type;
};
@@ -27,6 +27,9 @@ struct meminfo;
#define MT_ROM 6
#define MT_IXP2000_DEVICE 7
+#define __phys_to_pfn(paddr) ((paddr) >> PAGE_SHIFT)
+#define __pfn_to_phys(pfn) ((pfn) << PAGE_SHIFT)
+
extern void create_memmap_holes(struct meminfo *);
extern void memtable_init(struct meminfo *);
extern void iotable_init(struct map_desc *, int);
diff --git a/include/asm-arm/memory.h b/include/asm-arm/memory.h
index a8a933a775db..a547ee598c6c 100644
--- a/include/asm-arm/memory.h
+++ b/include/asm-arm/memory.h
@@ -12,6 +12,16 @@
#ifndef __ASM_ARM_MEMORY_H
#define __ASM_ARM_MEMORY_H
+/*
+ * Allow for constants defined here to be used from assembly code
+ * by prepending the UL suffix only with actual C code compilation.
+ */
+#ifndef __ASSEMBLY__
+#define UL(x) (x##UL)
+#else
+#define UL(x) (x)
+#endif
+
#include <linux/config.h>
#include <linux/compiler.h>
#include <asm/arch/memory.h>
@@ -21,20 +31,20 @@
* TASK_SIZE - the maximum size of a user space task.
* TASK_UNMAPPED_BASE - the lower boundary of the mmap VM area
*/
-#define TASK_SIZE (0xbf000000UL)
-#define TASK_UNMAPPED_BASE (0x40000000UL)
+#define TASK_SIZE UL(0xbf000000)
+#define TASK_UNMAPPED_BASE UL(0x40000000)
#endif
/*
* The maximum size of a 26-bit user space task.
*/
-#define TASK_SIZE_26 (0x04000000UL)
+#define TASK_SIZE_26 UL(0x04000000)
/*
* Page offset: 3GB
*/
#ifndef PAGE_OFFSET
-#define PAGE_OFFSET (0xc0000000UL)
+#define PAGE_OFFSET UL(0xc0000000)
#endif
/*
@@ -58,6 +68,13 @@
#error Top of user space clashes with start of module space
#endif
+/*
+ * The XIP kernel gets mapped at the bottom of the module vm area.
+ * Since we use sections to map it, this macro replaces the physical address
+ * with its virtual address while keeping offset from the base section.
+ */
+#define XIP_VIRT_ADDR(physaddr) (MODULE_START + ((physaddr) & 0x000fffff))
+
#ifndef __ASSEMBLY__
/*
diff --git a/include/asm-arm/mmu_context.h b/include/asm-arm/mmu_context.h
index 4af9c411c617..3d4b810d8c38 100644
--- a/include/asm-arm/mmu_context.h
+++ b/include/asm-arm/mmu_context.h
@@ -13,6 +13,7 @@
#ifndef __ASM_ARM_MMU_CONTEXT_H
#define __ASM_ARM_MMU_CONTEXT_H
+#include <asm/cacheflush.h>
#include <asm/proc-fns.h>
#if __LINUX_ARM_ARCH__ >= 6
@@ -86,7 +87,8 @@ switch_mm(struct mm_struct *prev, struct mm_struct *next,
cpu_set(cpu, next->cpu_vm_mask);
check_context(next);
cpu_switch_mm(next->pgd, next);
- cpu_clear(cpu, prev->cpu_vm_mask);
+ if (cache_is_vivt())
+ cpu_clear(cpu, prev->cpu_vm_mask);
}
}
diff --git a/include/asm-arm/pgtable.h b/include/asm-arm/pgtable.h
index 366bafbdfbb1..5a0d19b466b0 100644
--- a/include/asm-arm/pgtable.h
+++ b/include/asm-arm/pgtable.h
@@ -397,9 +397,6 @@ static inline pte_t *pmd_page_kernel(pmd_t pmd)
#define pgd_clear(pgdp) do { } while (0)
#define set_pgd(pgd,pgdp) do { } while (0)
-#define page_pte_prot(page,prot) mk_pte(page, prot)
-#define page_pte(page) mk_pte(page, __pgprot(0))
-
/* to find an entry in a page-table-directory */
#define pgd_index(addr) ((addr) >> PGDIR_SHIFT)
diff --git a/include/asm-arm/semaphore.h b/include/asm-arm/semaphore.h
index 60f33e6eb800..71ca7d412687 100644
--- a/include/asm-arm/semaphore.h
+++ b/include/asm-arm/semaphore.h
@@ -24,8 +24,6 @@ struct semaphore {
.wait = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait), \
}
-#define __MUTEX_INITIALIZER(name) __SEMAPHORE_INIT(name,1)
-
#define __DECLARE_SEMAPHORE_GENERIC(name,count) \
struct semaphore name = __SEMAPHORE_INIT(name,count)
diff --git a/include/asm-arm/smp.h b/include/asm-arm/smp.h
index dbb4d859c586..5a72e50ca9fc 100644
--- a/include/asm-arm/smp.h
+++ b/include/asm-arm/smp.h
@@ -37,6 +37,11 @@ struct seq_file;
extern void show_ipi_list(struct seq_file *p);
/*
+ * Called from assembly code, this handles an IPI.
+ */
+asmlinkage void do_IPI(struct pt_regs *regs);
+
+/*
* Move global data into per-processor storage.
*/
extern void smp_store_cpu_info(unsigned int cpuid);
@@ -47,12 +52,23 @@ extern void smp_store_cpu_info(unsigned int cpuid);
extern void smp_cross_call(cpumask_t callmap);
/*
+ * Broadcast a timer interrupt to the other CPUs.
+ */
+extern void smp_send_timer(void);
+
+/*
* Boot a secondary CPU, and assign it the specified idle task.
* This also gives us the initial stack to use for this CPU.
*/
extern int boot_secondary(unsigned int cpu, struct task_struct *);
/*
+ * Called from platform specific assembly code, this is the
+ * secondary CPU entry point.
+ */
+asmlinkage void secondary_start_kernel(void);
+
+/*
* Perform platform specific initialisation of the specified CPU.
*/
extern void platform_secondary_init(unsigned int cpu);
@@ -66,4 +82,52 @@ struct secondary_data {
};
extern struct secondary_data secondary_data;
+extern int __cpu_disable(void);
+extern int mach_cpu_disable(unsigned int cpu);
+
+extern void __cpu_die(unsigned int cpu);
+extern void cpu_die(void);
+
+extern void platform_cpu_die(unsigned int cpu);
+extern int platform_cpu_kill(unsigned int cpu);
+extern void platform_cpu_enable(unsigned int cpu);
+
+#ifdef CONFIG_LOCAL_TIMERS
+/*
+ * Setup a local timer interrupt for a CPU.
+ */
+extern void local_timer_setup(unsigned int cpu);
+
+/*
+ * Stop a local timer interrupt.
+ */
+extern void local_timer_stop(unsigned int cpu);
+
+/*
+ * Platform provides this to acknowledge a local timer IRQ
+ */
+extern int local_timer_ack(void);
+
+#else
+
+static inline void local_timer_setup(unsigned int cpu)
+{
+}
+
+static inline void local_timer_stop(unsigned int cpu)
+{
+}
+
+#endif
+
+/*
+ * show local interrupt info
+ */
+extern void show_local_irqs(struct seq_file *);
+
+/*
+ * Called from assembly, this is the local timer IRQ handler
+ */
+asmlinkage void do_local_timer(struct pt_regs *);
+
#endif /* ifndef __ASM_ARM_SMP_H */
diff --git a/include/asm-arm/spinlock.h b/include/asm-arm/spinlock.h
index cb4906b45555..6ed4f916b166 100644
--- a/include/asm-arm/spinlock.h
+++ b/include/asm-arm/spinlock.h
@@ -80,7 +80,7 @@ static inline void __raw_spin_unlock(raw_spinlock_t *lock)
*/
#define rwlock_is_locked(x) (*((volatile unsigned int *)(x)) != 0)
-static inline void __raw_write_lock(rwlock_t *rw)
+static inline void __raw_write_lock(raw_rwlock_t *rw)
{
unsigned long tmp;
@@ -97,7 +97,7 @@ static inline void __raw_write_lock(rwlock_t *rw)
smp_mb();
}
-static inline int __raw_write_trylock(rwlock_t *rw)
+static inline int __raw_write_trylock(raw_rwlock_t *rw)
{
unsigned long tmp;
@@ -157,7 +157,7 @@ static inline void __raw_read_lock(raw_rwlock_t *rw)
smp_mb();
}
-static inline void __raw_read_unlock(rwlock_t *rw)
+static inline void __raw_read_unlock(raw_rwlock_t *rw)
{
unsigned long tmp, tmp2;
diff --git a/include/asm-arm/tlb.h b/include/asm-arm/tlb.h
index 9bb325c54645..f49bfb78c221 100644
--- a/include/asm-arm/tlb.h
+++ b/include/asm-arm/tlb.h
@@ -27,11 +27,7 @@
*/
struct mmu_gather {
struct mm_struct *mm;
- unsigned int freed;
unsigned int fullmm;
-
- unsigned int flushes;
- unsigned int avoided_flushes;
};
DECLARE_PER_CPU(struct mmu_gather, mmu_gathers);
@@ -39,11 +35,9 @@ DECLARE_PER_CPU(struct mmu_gather, mmu_gathers);
static inline struct mmu_gather *
tlb_gather_mmu(struct mm_struct *mm, unsigned int full_mm_flush)
{
- int cpu = smp_processor_id();
- struct mmu_gather *tlb = &per_cpu(mmu_gathers, cpu);
+ struct mmu_gather *tlb = &get_cpu_var(mmu_gathers);
tlb->mm = mm;
- tlb->freed = 0;
tlb->fullmm = full_mm_flush;
return tlb;
@@ -52,24 +46,13 @@ tlb_gather_mmu(struct mm_struct *mm, unsigned int full_mm_flush)
static inline void
tlb_finish_mmu(struct mmu_gather *tlb, unsigned long start, unsigned long end)
{
- struct mm_struct *mm = tlb->mm;
- unsigned long freed = tlb->freed;
- int rss = get_mm_counter(mm, rss);
-
- if (rss < freed)
- freed = rss;
- add_mm_counter(mm, rss, -freed);
-
if (tlb->fullmm)
- flush_tlb_mm(mm);
+ flush_tlb_mm(tlb->mm);
/* keep the page table cache within bounds */
check_pgt_cache();
-}
-static inline unsigned int tlb_is_full_mm(struct mmu_gather *tlb)
-{
- return tlb->fullmm;
+ put_cpu_var(mmu_gathers);
}
#define tlb_remove_tlb_entry(tlb,ptep,address) do { } while (0)
diff --git a/include/asm-arm/unistd.h b/include/asm-arm/unistd.h
index c49df635a80f..d626e70faded 100644
--- a/include/asm-arm/unistd.h
+++ b/include/asm-arm/unistd.h
@@ -544,7 +544,6 @@ asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp,
asmlinkage int sys_fork(struct pt_regs *regs);
asmlinkage int sys_vfork(struct pt_regs *regs);
asmlinkage int sys_pipe(unsigned long *fildes);
-asmlinkage int sys_ptrace(long request, long pid, long addr, long data);
struct sigaction;
asmlinkage long sys_rt_sigaction(int sig,
const struct sigaction __user *act,
diff --git a/include/asm-arm26/pgtable.h b/include/asm-arm26/pgtable.h
index f602cf572411..a590250277f8 100644
--- a/include/asm-arm26/pgtable.h
+++ b/include/asm-arm26/pgtable.h
@@ -98,8 +98,6 @@ extern struct page *empty_zero_page;
#define pfn_pte(pfn,prot) (__pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot)))
#define pages_to_mb(x) ((x) >> (20 - PAGE_SHIFT))
#define mk_pte(page,prot) pfn_pte(page_to_pfn(page),prot)
-#define page_pte_prot(page,prot) mk_pte(page, prot)
-#define page_pte(page) mk_pte(page, __pgprot(0))
/*
* Terminology: PGD = Page Directory, PMD = Page Middle Directory,
diff --git a/include/asm-arm26/semaphore.h b/include/asm-arm26/semaphore.h
index c1b6a1edad92..ccf15e704109 100644
--- a/include/asm-arm26/semaphore.h
+++ b/include/asm-arm26/semaphore.h
@@ -25,9 +25,6 @@ struct semaphore {
.wait = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait), \
}
-#define __MUTEX_INITIALIZER(name) \
- __SEMAPHORE_INIT(name,1)
-
#define __DECLARE_SEMAPHORE_GENERIC(name,count) \
struct semaphore name = __SEMAPHORE_INIT(name,count)
diff --git a/include/asm-arm26/tlb.h b/include/asm-arm26/tlb.h
index 1316352a58f3..08ddd85b8d35 100644
--- a/include/asm-arm26/tlb.h
+++ b/include/asm-arm26/tlb.h
@@ -10,24 +10,20 @@
*/
struct mmu_gather {
struct mm_struct *mm;
- unsigned int freed;
- unsigned int fullmm;
-
- unsigned int flushes;
- unsigned int avoided_flushes;
+ unsigned int need_flush;
+ unsigned int fullmm;
};
-extern struct mmu_gather mmu_gathers[NR_CPUS];
+DECLARE_PER_CPU(struct mmu_gather, mmu_gathers);
static inline struct mmu_gather *
tlb_gather_mmu(struct mm_struct *mm, unsigned int full_mm_flush)
{
- int cpu = smp_processor_id();
- struct mmu_gather *tlb = &mmu_gathers[cpu];
+ struct mmu_gather *tlb = &get_cpu_var(mmu_gathers);
tlb->mm = mm;
- tlb->freed = 0;
- tlb->fullmm = full_mm_flush;
+ tlb->need_flush = 0;
+ tlb->fullmm = full_mm_flush;
return tlb;
}
@@ -35,30 +31,13 @@ tlb_gather_mmu(struct mm_struct *mm, unsigned int full_mm_flush)
static inline void
tlb_finish_mmu(struct mmu_gather *tlb, unsigned long start, unsigned long end)
{
- struct mm_struct *mm = tlb->mm;
- unsigned long freed = tlb->freed;
- int rss = get_mm_counter(mm, rss);
-
- if (rss < freed)
- freed = rss;
- add_mm_counter(mm, rss, -freed);
-
- if (freed) {
- flush_tlb_mm(mm);
- tlb->flushes++;
- } else {
- tlb->avoided_flushes++;
- }
+ if (tlb->need_flush)
+ flush_tlb_mm(tlb->mm);
/* keep the page table cache within bounds */
check_pgt_cache();
-}
-
-static inline unsigned int
-tlb_is_full_mm(struct mmu_gather *tlb)
-{
- return tlb->fullmm;
+ put_cpu_var(mmu_gathers);
}
#define tlb_remove_tlb_entry(tlb,ptep,address) do { } while (0)
@@ -71,7 +50,13 @@ tlb_is_full_mm(struct mmu_gather *tlb)
} while (0)
#define tlb_end_vma(tlb,vma) do { } while (0)
-#define tlb_remove_page(tlb,page) free_page_and_swap_cache(page)
+static inline void
+tlb_remove_page(struct mmu_gather *tlb, struct page *page)
+{
+ tlb->need_flush = 1;
+ free_page_and_swap_cache(page);
+}
+
#define pte_free_tlb(tlb,ptep) pte_free(ptep)
#define pmd_free_tlb(tlb,pmdp) pmd_free(pmdp)
diff --git a/include/asm-arm26/unistd.h b/include/asm-arm26/unistd.h
index dfa0b0c30aa3..be4c2fb9c049 100644
--- a/include/asm-arm26/unistd.h
+++ b/include/asm-arm26/unistd.h
@@ -480,7 +480,6 @@ asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp,
asmlinkage int sys_fork(struct pt_regs *regs);
asmlinkage int sys_vfork(struct pt_regs *regs);
asmlinkage int sys_pipe(unsigned long *fildes);
-asmlinkage int sys_ptrace(long request, long pid, long addr, long data);
struct sigaction;
asmlinkage long sys_rt_sigaction(int sig,
const struct sigaction __user *act,
diff --git a/include/asm-cris/arch-v10/byteorder.h b/include/asm-cris/arch-v10/byteorder.h
index e24465d1f40d..255b646b7fa8 100644
--- a/include/asm-cris/arch-v10/byteorder.h
+++ b/include/asm-cris/arch-v10/byteorder.h
@@ -9,14 +9,14 @@
* them together into ntohl etc.
*/
-extern __inline__ __attribute_const__ __u32 ___arch__swab32(__u32 x)
+static inline __attribute_const__ __u32 ___arch__swab32(__u32 x)
{
__asm__ ("swapwb %0" : "=r" (x) : "0" (x));
return(x);
}
-extern __inline__ __attribute_const__ __u16 ___arch__swab16(__u16 x)
+static inline __attribute_const__ __u16 ___arch__swab16(__u16 x)
{
__asm__ ("swapb %0" : "=r" (x) : "0" (x));
diff --git a/include/asm-cris/arch-v10/checksum.h b/include/asm-cris/arch-v10/checksum.h
index fde1d00aaa90..633f234f336b 100644
--- a/include/asm-cris/arch-v10/checksum.h
+++ b/include/asm-cris/arch-v10/checksum.h
@@ -8,7 +8,7 @@
* to split all of those into 16-bit components, then add.
*/
-extern inline unsigned int
+static inline unsigned int
csum_tcpudp_nofold(unsigned long saddr, unsigned long daddr, unsigned short len,
unsigned short proto, unsigned int sum)
{
diff --git a/include/asm-cris/arch-v10/delay.h b/include/asm-cris/arch-v10/delay.h
index cfedae0d2f53..39481f6e0c30 100644
--- a/include/asm-cris/arch-v10/delay.h
+++ b/include/asm-cris/arch-v10/delay.h
@@ -1,7 +1,7 @@
#ifndef _CRIS_ARCH_DELAY_H
#define _CRIS_ARCH_DELAY_H
-extern __inline__ void __delay(int loops)
+static inline void __delay(int loops)
{
__asm__ __volatile__ (
"move.d %0,$r9\n\t"
diff --git a/include/asm-cris/arch-v10/ide.h b/include/asm-cris/arch-v10/ide.h
index 8cf2d7cb22ac..78b301ed7b12 100644
--- a/include/asm-cris/arch-v10/ide.h
+++ b/include/asm-cris/arch-v10/ide.h
@@ -25,7 +25,7 @@
#define MAX_HWIFS 4
-extern __inline__ int ide_default_irq(unsigned long base)
+static inline int ide_default_irq(unsigned long base)
{
/* all IDE busses share the same IRQ, number 4.
* this has the side-effect that ide-probe.c will cluster our 4 interfaces
@@ -35,7 +35,7 @@ extern __inline__ int ide_default_irq(unsigned long base)
return 4;
}
-extern __inline__ unsigned long ide_default_io_base(int index)
+static inline unsigned long ide_default_io_base(int index)
{
/* we have no real I/O base address per interface, since all go through the
* same register. but in a bitfield in that register, we have the i/f number.
@@ -54,7 +54,7 @@ extern __inline__ unsigned long ide_default_io_base(int index)
* of the ide_default_io_base call above. ctrl_port will be 0, but that is don't care for us.
*/
-extern __inline__ void ide_init_hwif_ports(hw_regs_t *hw, unsigned long data_port, unsigned long ctrl_port, int *irq)
+static inline void ide_init_hwif_ports(hw_regs_t *hw, unsigned long data_port, unsigned long ctrl_port, int *irq)
{
int i;
@@ -77,7 +77,7 @@ extern __inline__ void ide_init_hwif_ports(hw_regs_t *hw, unsigned long data_por
hw->io_ports[IDE_IRQ_OFFSET] = 0;
}
-extern __inline__ void ide_init_default_hwifs(void)
+static inline void ide_init_default_hwifs(void)
{
hw_regs_t hw;
int index;
diff --git a/include/asm-cris/arch-v10/system.h b/include/asm-cris/arch-v10/system.h
index 6cc35642b8ab..1ac7b639b1b0 100644
--- a/include/asm-cris/arch-v10/system.h
+++ b/include/asm-cris/arch-v10/system.h
@@ -5,7 +5,7 @@
/* read the CPU version register */
-extern inline unsigned long rdvr(void) {
+static inline unsigned long rdvr(void) {
unsigned char vr;
__asm__ volatile ("move $vr,%0" : "=rm" (vr));
return vr;
@@ -15,7 +15,7 @@ extern inline unsigned long rdvr(void) {
/* read/write the user-mode stackpointer */
-extern inline unsigned long rdusp(void) {
+static inline unsigned long rdusp(void) {
unsigned long usp;
__asm__ __volatile__("move $usp,%0" : "=rm" (usp));
return usp;
@@ -26,13 +26,13 @@ extern inline unsigned long rdusp(void) {
/* read the current stackpointer */
-extern inline unsigned long rdsp(void) {
+static inline unsigned long rdsp(void) {
unsigned long sp;
__asm__ __volatile__("move.d $sp,%0" : "=rm" (sp));
return sp;
}
-extern inline unsigned long _get_base(char * addr)
+static inline unsigned long _get_base(char * addr)
{
return 0;
}
diff --git a/include/asm-cris/arch-v10/thread_info.h b/include/asm-cris/arch-v10/thread_info.h
index 357f5df0c907..218f4152d3e5 100644
--- a/include/asm-cris/arch-v10/thread_info.h
+++ b/include/asm-cris/arch-v10/thread_info.h
@@ -2,7 +2,7 @@
#define _ASM_ARCH_THREAD_INFO_H
/* how to get the thread information struct from C */
-extern inline struct thread_info *current_thread_info(void)
+static inline struct thread_info *current_thread_info(void)
{
struct thread_info *ti;
__asm__("and.d $sp,%0; ":"=r" (ti) : "0" (~8191UL));
diff --git a/include/asm-cris/arch-v10/timex.h b/include/asm-cris/arch-v10/timex.h
index ecfc553c06a5..e48447d94faf 100644
--- a/include/asm-cris/arch-v10/timex.h
+++ b/include/asm-cris/arch-v10/timex.h
@@ -22,7 +22,7 @@
unsigned long get_ns_in_jiffie(void);
-extern inline unsigned long get_us_in_jiffie_highres(void)
+static inline unsigned long get_us_in_jiffie_highres(void)
{
return get_ns_in_jiffie()/1000;
}
diff --git a/include/asm-cris/arch-v10/uaccess.h b/include/asm-cris/arch-v10/uaccess.h
index 787d2e60c83c..65b02d9b605a 100644
--- a/include/asm-cris/arch-v10/uaccess.h
+++ b/include/asm-cris/arch-v10/uaccess.h
@@ -87,7 +87,7 @@
* bytes copied if we hit a null byte
* (without the null byte)
*/
-extern inline long
+static inline long
__do_strncpy_from_user(char *dst, const char *src, long count)
{
long res;
@@ -602,7 +602,7 @@ __do_strncpy_from_user(char *dst, const char *src, long count)
* or 0 for error. Return a value greater than N if too long.
*/
-extern inline long
+static inline long
strnlen_user(const char *s, long n)
{
long res, tmp1;
diff --git a/include/asm-cris/arch-v32/bitops.h b/include/asm-cris/arch-v32/bitops.h
index e40a58d3b862..147689d6b624 100644
--- a/include/asm-cris/arch-v32/bitops.h
+++ b/include/asm-cris/arch-v32/bitops.h
@@ -8,7 +8,7 @@
* inverts all bits in the input.
*/
-extern inline unsigned long
+static inline unsigned long
cris_swapnwbrlz(unsigned long w)
{
unsigned long res;
@@ -20,7 +20,7 @@ cris_swapnwbrlz(unsigned long w)
return res;
}
-extern inline unsigned long
+static inline unsigned long
cris_swapwbrlz(unsigned long w)
{
unsigned long res;
@@ -36,7 +36,7 @@ cris_swapwbrlz(unsigned long w)
* Find First Zero in word. Undefined if no zero exist, so the caller should
* check against ~0 first.
*/
-extern inline unsigned long
+static inline unsigned long
ffz(unsigned long w)
{
return cris_swapnwbrlz(w);
@@ -46,7 +46,7 @@ ffz(unsigned long w)
* Find First Set bit in word. Undefined if no 1 exist, so the caller
* should check against 0 first.
*/
-extern inline unsigned long
+static inline unsigned long
__ffs(unsigned long w)
{
return cris_swapnwbrlz(~w);
@@ -55,7 +55,7 @@ __ffs(unsigned long w)
/*
* Find First Bit that is set.
*/
-extern inline unsigned long
+static inline unsigned long
kernel_ffs(unsigned long w)
{
return w ? cris_swapwbrlz (w) + 1 : 0;
diff --git a/include/asm-cris/arch-v32/byteorder.h b/include/asm-cris/arch-v32/byteorder.h
index 74846ee6cf99..6ef8fb4a35f2 100644
--- a/include/asm-cris/arch-v32/byteorder.h
+++ b/include/asm-cris/arch-v32/byteorder.h
@@ -3,14 +3,14 @@
#include <asm/types.h>
-extern __inline__ __const__ __u32
+static inline __const__ __u32
___arch__swab32(__u32 x)
{
__asm__ __volatile__ ("swapwb %0" : "=r" (x) : "0" (x));
return (x);
}
-extern __inline__ __const__ __u16
+static inline __const__ __u16
___arch__swab16(__u16 x)
{
__asm__ __volatile__ ("swapb %0" : "=r" (x) : "0" (x));
diff --git a/include/asm-cris/arch-v32/checksum.h b/include/asm-cris/arch-v32/checksum.h
index a1d6b2a6cc44..97ef89efea62 100644
--- a/include/asm-cris/arch-v32/checksum.h
+++ b/include/asm-cris/arch-v32/checksum.h
@@ -9,7 +9,7 @@
* checksum. Which means it would be necessary to split all those into
* 16-bit components and then add.
*/
-extern inline unsigned int
+static inline unsigned int
csum_tcpudp_nofold(unsigned long saddr, unsigned long daddr,
unsigned short len, unsigned short proto, unsigned int sum)
{
diff --git a/include/asm-cris/arch-v32/delay.h b/include/asm-cris/arch-v32/delay.h
index f36f7f760e89..b6e941e637de 100644
--- a/include/asm-cris/arch-v32/delay.h
+++ b/include/asm-cris/arch-v32/delay.h
@@ -1,7 +1,7 @@
#ifndef _ASM_CRIS_ARCH_DELAY_H
#define _ASM_CRIS_ARCH_DELAY_H
-extern __inline__ void
+static inline void
__delay(int loops)
{
__asm__ __volatile__ (
diff --git a/include/asm-cris/arch-v32/ide.h b/include/asm-cris/arch-v32/ide.h
index 24f5604f566a..6590f657500d 100644
--- a/include/asm-cris/arch-v32/ide.h
+++ b/include/asm-cris/arch-v32/ide.h
@@ -26,7 +26,7 @@
#define MAX_HWIFS 4
-extern __inline__ int ide_default_irq(unsigned long base)
+static inline int ide_default_irq(unsigned long base)
{
/* all IDE busses share the same IRQ,
* this has the side-effect that ide-probe.c will cluster our 4 interfaces
@@ -36,7 +36,7 @@ extern __inline__ int ide_default_irq(unsigned long base)
return ATA_INTR_VECT;
}
-extern __inline__ unsigned long ide_default_io_base(int index)
+static inline unsigned long ide_default_io_base(int index)
{
reg_ata_rw_ctrl2 ctrl2 = {.sel = index};
/* we have no real I/O base address per interface, since all go through the
diff --git a/include/asm-cris/arch-v32/io.h b/include/asm-cris/arch-v32/io.h
index 4c80263ec634..043c9ce5294e 100644
--- a/include/asm-cris/arch-v32/io.h
+++ b/include/asm-cris/arch-v32/io.h
@@ -35,7 +35,7 @@ extern struct crisv32_iopin crisv32_led2_red;
extern struct crisv32_iopin crisv32_led3_green;
extern struct crisv32_iopin crisv32_led3_red;
-extern inline void crisv32_io_set(struct crisv32_iopin* iopin,
+static inline void crisv32_io_set(struct crisv32_iopin* iopin,
int val)
{
if (val)
@@ -44,7 +44,7 @@ extern inline void crisv32_io_set(struct crisv32_iopin* iopin,
*iopin->port->data &= ~iopin->bit;
}
-extern inline void crisv32_io_set_dir(struct crisv32_iopin* iopin,
+static inline void crisv32_io_set_dir(struct crisv32_iopin* iopin,
enum crisv32_io_dir dir)
{
if (dir == crisv32_io_dir_in)
@@ -53,7 +53,7 @@ extern inline void crisv32_io_set_dir(struct crisv32_iopin* iopin,
*iopin->port->oe |= iopin->bit;
}
-extern inline int crisv32_io_rd(struct crisv32_iopin* iopin)
+static inline int crisv32_io_rd(struct crisv32_iopin* iopin)
{
return ((*iopin->port->data_in & iopin->bit) ? 1 : 0);
}
diff --git a/include/asm-cris/arch-v32/system.h b/include/asm-cris/arch-v32/system.h
index b9afbb95e0bb..a3d75d581e2f 100644
--- a/include/asm-cris/arch-v32/system.h
+++ b/include/asm-cris/arch-v32/system.h
@@ -4,7 +4,7 @@
#include <linux/config.h>
/* Read the CPU version register. */
-extern inline unsigned long rdvr(void)
+static inline unsigned long rdvr(void)
{
unsigned char vr;
@@ -15,7 +15,7 @@ extern inline unsigned long rdvr(void)
#define cris_machine_name "crisv32"
/* Read the user-mode stack pointer. */
-extern inline unsigned long rdusp(void)
+static inline unsigned long rdusp(void)
{
unsigned long usp;
@@ -24,7 +24,7 @@ extern inline unsigned long rdusp(void)
}
/* Read the current stack pointer. */
-extern inline unsigned long rdsp(void)
+static inline unsigned long rdsp(void)
{
unsigned long sp;
diff --git a/include/asm-cris/arch-v32/thread_info.h b/include/asm-cris/arch-v32/thread_info.h
index a7a182307da0..d6936956a3c6 100644
--- a/include/asm-cris/arch-v32/thread_info.h
+++ b/include/asm-cris/arch-v32/thread_info.h
@@ -2,7 +2,7 @@
#define _ASM_CRIS_ARCH_THREAD_INFO_H
/* Return a thread_info struct. */
-extern inline struct thread_info *current_thread_info(void)
+static inline struct thread_info *current_thread_info(void)
{
struct thread_info *ti;
diff --git a/include/asm-cris/arch-v32/timex.h b/include/asm-cris/arch-v32/timex.h
index 4d0fd23b21e9..5a4aa285d5fd 100644
--- a/include/asm-cris/arch-v32/timex.h
+++ b/include/asm-cris/arch-v32/timex.h
@@ -22,7 +22,7 @@
extern unsigned long get_ns_in_jiffie(void);
-extern inline unsigned long get_us_in_jiffie_highres(void)
+static inline unsigned long get_us_in_jiffie_highres(void)
{
return get_ns_in_jiffie() / 1000;
}
diff --git a/include/asm-cris/arch-v32/uaccess.h b/include/asm-cris/arch-v32/uaccess.h
index 055a0bdbe835..6b207f1b6622 100644
--- a/include/asm-cris/arch-v32/uaccess.h
+++ b/include/asm-cris/arch-v32/uaccess.h
@@ -93,7 +93,7 @@
* bytes copied if we hit a null byte
* (without the null byte)
*/
-extern inline long
+static inline long
__do_strncpy_from_user(char *dst, const char *src, long count)
{
long res;
@@ -695,7 +695,7 @@ __do_strncpy_from_user(char *dst, const char *src, long count)
* or 0 for error. Return a value greater than N if too long.
*/
-extern inline long
+static inline long
strnlen_user(const char *s, long n)
{
long res, tmp1;
diff --git a/include/asm-cris/atomic.h b/include/asm-cris/atomic.h
index 70605b09e8b7..8c2e78304523 100644
--- a/include/asm-cris/atomic.h
+++ b/include/asm-cris/atomic.h
@@ -20,7 +20,7 @@ typedef struct { volatile int counter; } atomic_t;
/* These should be written in asm but we do it in C for now. */
-extern __inline__ void atomic_add(int i, volatile atomic_t *v)
+static inline void atomic_add(int i, volatile atomic_t *v)
{
unsigned long flags;
cris_atomic_save(v, flags);
@@ -28,7 +28,7 @@ extern __inline__ void atomic_add(int i, volatile atomic_t *v)
cris_atomic_restore(v, flags);
}
-extern __inline__ void atomic_sub(int i, volatile atomic_t *v)
+static inline void atomic_sub(int i, volatile atomic_t *v)
{
unsigned long flags;
cris_atomic_save(v, flags);
@@ -36,7 +36,7 @@ extern __inline__ void atomic_sub(int i, volatile atomic_t *v)
cris_atomic_restore(v, flags);
}
-extern __inline__ int atomic_add_return(int i, volatile atomic_t *v)
+static inline int atomic_add_return(int i, volatile atomic_t *v)
{
unsigned long flags;
int retval;
@@ -48,7 +48,7 @@ extern __inline__ int atomic_add_return(int i, volatile atomic_t *v)
#define atomic_add_negative(a, v) (atomic_add_return((a), (v)) < 0)
-extern __inline__ int atomic_sub_return(int i, volatile atomic_t *v)
+static inline int atomic_sub_return(int i, volatile atomic_t *v)
{
unsigned long flags;
int retval;
@@ -58,7 +58,7 @@ extern __inline__ int atomic_sub_return(int i, volatile atomic_t *v)
return retval;
}
-extern __inline__ int atomic_sub_and_test(int i, volatile atomic_t *v)
+static inline int atomic_sub_and_test(int i, volatile atomic_t *v)
{
int retval;
unsigned long flags;
@@ -68,7 +68,7 @@ extern __inline__ int atomic_sub_and_test(int i, volatile atomic_t *v)
return retval;
}
-extern __inline__ void atomic_inc(volatile atomic_t *v)
+static inline void atomic_inc(volatile atomic_t *v)
{
unsigned long flags;
cris_atomic_save(v, flags);
@@ -76,7 +76,7 @@ extern __inline__ void atomic_inc(volatile atomic_t *v)
cris_atomic_restore(v, flags);
}
-extern __inline__ void atomic_dec(volatile atomic_t *v)
+static inline void atomic_dec(volatile atomic_t *v)
{
unsigned long flags;
cris_atomic_save(v, flags);
@@ -84,7 +84,7 @@ extern __inline__ void atomic_dec(volatile atomic_t *v)
cris_atomic_restore(v, flags);
}
-extern __inline__ int atomic_inc_return(volatile atomic_t *v)
+static inline int atomic_inc_return(volatile atomic_t *v)
{
unsigned long flags;
int retval;
@@ -94,7 +94,7 @@ extern __inline__ int atomic_inc_return(volatile atomic_t *v)
return retval;
}
-extern __inline__ int atomic_dec_return(volatile atomic_t *v)
+static inline int atomic_dec_return(volatile atomic_t *v)
{
unsigned long flags;
int retval;
@@ -103,7 +103,7 @@ extern __inline__ int atomic_dec_return(volatile atomic_t *v)
cris_atomic_restore(v, flags);
return retval;
}
-extern __inline__ int atomic_dec_and_test(volatile atomic_t *v)
+static inline int atomic_dec_and_test(volatile atomic_t *v)
{
int retval;
unsigned long flags;
@@ -113,7 +113,7 @@ extern __inline__ int atomic_dec_and_test(volatile atomic_t *v)
return retval;
}
-extern __inline__ int atomic_inc_and_test(volatile atomic_t *v)
+static inline int atomic_inc_and_test(volatile atomic_t *v)
{
int retval;
unsigned long flags;
diff --git a/include/asm-cris/bitops.h b/include/asm-cris/bitops.h
index e3da57f97964..1bddb3f3a289 100644
--- a/include/asm-cris/bitops.h
+++ b/include/asm-cris/bitops.h
@@ -89,7 +89,7 @@ struct __dummy { unsigned long a[100]; };
* It also implies a memory barrier.
*/
-extern inline int test_and_set_bit(int nr, volatile unsigned long *addr)
+static inline int test_and_set_bit(int nr, volatile unsigned long *addr)
{
unsigned int mask, retval;
unsigned long flags;
@@ -105,7 +105,7 @@ extern inline int test_and_set_bit(int nr, volatile unsigned long *addr)
return retval;
}
-extern inline int __test_and_set_bit(int nr, volatile unsigned long *addr)
+static inline int __test_and_set_bit(int nr, volatile unsigned long *addr)
{
unsigned int mask, retval;
unsigned int *adr = (unsigned int *)addr;
@@ -132,7 +132,7 @@ extern inline int __test_and_set_bit(int nr, volatile unsigned long *addr)
* It also implies a memory barrier.
*/
-extern inline int test_and_clear_bit(int nr, volatile unsigned long *addr)
+static inline int test_and_clear_bit(int nr, volatile unsigned long *addr)
{
unsigned int mask, retval;
unsigned long flags;
@@ -157,7 +157,7 @@ extern inline int test_and_clear_bit(int nr, volatile unsigned long *addr)
* but actually fail. You must protect multiple accesses with a lock.
*/
-extern inline int __test_and_clear_bit(int nr, volatile unsigned long *addr)
+static inline int __test_and_clear_bit(int nr, volatile unsigned long *addr)
{
unsigned int mask, retval;
unsigned int *adr = (unsigned int *)addr;
@@ -177,7 +177,7 @@ extern inline int __test_and_clear_bit(int nr, volatile unsigned long *addr)
* It also implies a memory barrier.
*/
-extern inline int test_and_change_bit(int nr, volatile unsigned long *addr)
+static inline int test_and_change_bit(int nr, volatile unsigned long *addr)
{
unsigned int mask, retval;
unsigned long flags;
@@ -193,7 +193,7 @@ extern inline int test_and_change_bit(int nr, volatile unsigned long *addr)
/* WARNING: non atomic and it can be reordered! */
-extern inline int __test_and_change_bit(int nr, volatile unsigned long *addr)
+static inline int __test_and_change_bit(int nr, volatile unsigned long *addr)
{
unsigned int mask, retval;
unsigned int *adr = (unsigned int *)addr;
@@ -214,7 +214,7 @@ extern inline int __test_and_change_bit(int nr, volatile unsigned long *addr)
* This routine doesn't need to be atomic.
*/
-extern inline int test_bit(int nr, const volatile unsigned long *addr)
+static inline int test_bit(int nr, const volatile unsigned long *addr)
{
unsigned int mask;
unsigned int *adr = (unsigned int *)addr;
@@ -258,7 +258,7 @@ extern inline int test_bit(int nr, const volatile unsigned long *addr)
* @offset: The bitnumber to start searching at
* @size: The maximum size to search
*/
-extern inline int find_next_zero_bit (const unsigned long * addr, int size, int offset)
+static inline int find_next_zero_bit (const unsigned long * addr, int size, int offset)
{
unsigned long *p = ((unsigned long *) addr) + (offset >> 5);
unsigned long result = offset & ~31UL;
@@ -366,7 +366,7 @@ found_middle:
#define minix_test_bit(nr,addr) test_bit(nr,addr)
#define minix_find_first_zero_bit(addr,size) find_first_zero_bit(addr,size)
-extern inline int sched_find_first_bit(const unsigned long *b)
+static inline int sched_find_first_bit(const unsigned long *b)
{
if (unlikely(b[0]))
return __ffs(b[0]);
diff --git a/include/asm-cris/checksum.h b/include/asm-cris/checksum.h
index 15ca8aec5c63..26a7719bbb84 100644
--- a/include/asm-cris/checksum.h
+++ b/include/asm-cris/checksum.h
@@ -34,7 +34,7 @@ unsigned int csum_partial_copy_nocheck(const char *src, char *dst,
* Fold a partial checksum into a word
*/
-extern inline unsigned int csum_fold(unsigned int sum)
+static inline unsigned int csum_fold(unsigned int sum)
{
/* the while loop is unnecessary really, it's always enough with two
iterations */
@@ -55,7 +55,7 @@ extern unsigned int csum_partial_copy_from_user(const char *src, char *dst,
*
*/
-extern inline unsigned short ip_fast_csum(unsigned char * iph,
+static inline unsigned short ip_fast_csum(unsigned char * iph,
unsigned int ihl)
{
return csum_fold(csum_partial(iph, ihl * 4, 0));
@@ -66,7 +66,7 @@ extern inline unsigned short ip_fast_csum(unsigned char * iph,
* returns a 16-bit checksum, already complemented
*/
-extern inline unsigned short int csum_tcpudp_magic(unsigned long saddr,
+static inline unsigned short int csum_tcpudp_magic(unsigned long saddr,
unsigned long daddr,
unsigned short len,
unsigned short proto,
@@ -80,7 +80,7 @@ extern inline unsigned short int csum_tcpudp_magic(unsigned long saddr,
* in icmp.c
*/
-extern inline unsigned short ip_compute_csum(unsigned char * buff, int len) {
+static inline unsigned short ip_compute_csum(unsigned char * buff, int len) {
return csum_fold (csum_partial(buff, len, 0));
}
diff --git a/include/asm-cris/current.h b/include/asm-cris/current.h
index dce69c99da39..5f5c0efd00be 100644
--- a/include/asm-cris/current.h
+++ b/include/asm-cris/current.h
@@ -5,7 +5,7 @@
struct task_struct;
-extern inline struct task_struct * get_current(void)
+static inline struct task_struct * get_current(void)
{
return current_thread_info()->task;
}
diff --git a/include/asm-cris/delay.h b/include/asm-cris/delay.h
index efc41aad4845..d3a397803719 100644
--- a/include/asm-cris/delay.h
+++ b/include/asm-cris/delay.h
@@ -13,7 +13,7 @@
extern unsigned long loops_per_usec; /* arch/cris/mm/init.c */
-extern __inline__ void udelay(unsigned long usecs)
+static inline void udelay(unsigned long usecs)
{
__delay(usecs * loops_per_usec);
}
diff --git a/include/asm-cris/dma-mapping.h b/include/asm-cris/dma-mapping.h
index 0b5c3fdaefe1..8eff51349ae7 100644
--- a/include/asm-cris/dma-mapping.h
+++ b/include/asm-cris/dma-mapping.h
@@ -15,14 +15,14 @@
#ifdef CONFIG_PCI
void *dma_alloc_coherent(struct device *dev, size_t size,
- dma_addr_t *dma_handle, int flag);
+ dma_addr_t *dma_handle, gfp_t flag);
void dma_free_coherent(struct device *dev, size_t size,
void *vaddr, dma_addr_t dma_handle);
#else
static inline void *
dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle,
- int flag)
+ gfp_t flag)
{
BUG();
return NULL;
diff --git a/include/asm-cris/io.h b/include/asm-cris/io.h
index 16e791b3c721..716c69bc58f8 100644
--- a/include/asm-cris/io.h
+++ b/include/asm-cris/io.h
@@ -23,12 +23,12 @@ extern struct cris_io_operations *cris_iops;
* Change virtual addresses to physical addresses and vv.
*/
-extern inline unsigned long virt_to_phys(volatile void * address)
+static inline unsigned long virt_to_phys(volatile void * address)
{
return __pa(address);
}
-extern inline void * phys_to_virt(unsigned long address)
+static inline void * phys_to_virt(unsigned long address)
{
return __va(address);
}
@@ -36,7 +36,7 @@ extern inline void * phys_to_virt(unsigned long address)
extern void __iomem * __ioremap(unsigned long offset, unsigned long size, unsigned long flags);
extern void __iomem * __ioremap_prot(unsigned long phys_addr, unsigned long size, pgprot_t prot);
-extern inline void __iomem * ioremap (unsigned long offset, unsigned long size)
+static inline void __iomem * ioremap (unsigned long offset, unsigned long size)
{
return __ioremap(offset, size, 0);
}
diff --git a/include/asm-cris/irq.h b/include/asm-cris/irq.h
index 4fab5c3b2e15..4b338792218b 100644
--- a/include/asm-cris/irq.h
+++ b/include/asm-cris/irq.h
@@ -8,7 +8,7 @@
#include <asm/arch/irq.h>
-extern __inline__ int irq_canonicalize(int irq)
+static inline int irq_canonicalize(int irq)
{
return irq;
}
diff --git a/include/asm-cris/pgalloc.h b/include/asm-cris/pgalloc.h
index a131776edf41..deaddfe79bbc 100644
--- a/include/asm-cris/pgalloc.h
+++ b/include/asm-cris/pgalloc.h
@@ -11,35 +11,35 @@
* Allocate and free page tables.
*/
-extern inline pgd_t *pgd_alloc (struct mm_struct *mm)
+static inline pgd_t *pgd_alloc (struct mm_struct *mm)
{
return (pgd_t *)get_zeroed_page(GFP_KERNEL);
}
-extern inline void pgd_free (pgd_t *pgd)
+static inline void pgd_free (pgd_t *pgd)
{
free_page((unsigned long)pgd);
}
-extern inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address)
+static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address)
{
pte_t *pte = (pte_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO);
return pte;
}
-extern inline struct page *pte_alloc_one(struct mm_struct *mm, unsigned long address)
+static inline struct page *pte_alloc_one(struct mm_struct *mm, unsigned long address)
{
struct page *pte;
pte = alloc_pages(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO, 0);
return pte;
}
-extern inline void pte_free_kernel(pte_t *pte)
+static inline void pte_free_kernel(pte_t *pte)
{
free_page((unsigned long)pte);
}
-extern inline void pte_free(struct page *pte)
+static inline void pte_free(struct page *pte)
{
__free_page(pte);
}
diff --git a/include/asm-cris/pgtable.h b/include/asm-cris/pgtable.h
index a9143bed99db..70a832514f62 100644
--- a/include/asm-cris/pgtable.h
+++ b/include/asm-cris/pgtable.h
@@ -112,44 +112,44 @@ extern unsigned long empty_zero_page;
* Undefined behaviour if not..
*/
-extern inline int pte_read(pte_t pte) { return pte_val(pte) & _PAGE_READ; }
-extern inline int pte_write(pte_t pte) { return pte_val(pte) & _PAGE_WRITE; }
-extern inline int pte_exec(pte_t pte) { return pte_val(pte) & _PAGE_READ; }
-extern inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_MODIFIED; }
-extern inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; }
-extern inline int pte_file(pte_t pte) { return pte_val(pte) & _PAGE_FILE; }
-
-extern inline pte_t pte_wrprotect(pte_t pte)
+static inline int pte_read(pte_t pte) { return pte_val(pte) & _PAGE_READ; }
+static inline int pte_write(pte_t pte) { return pte_val(pte) & _PAGE_WRITE; }
+static inline int pte_exec(pte_t pte) { return pte_val(pte) & _PAGE_READ; }
+static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_MODIFIED; }
+static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; }
+static inline int pte_file(pte_t pte) { return pte_val(pte) & _PAGE_FILE; }
+
+static inline pte_t pte_wrprotect(pte_t pte)
{
pte_val(pte) &= ~(_PAGE_WRITE | _PAGE_SILENT_WRITE);
return pte;
}
-extern inline pte_t pte_rdprotect(pte_t pte)
+static inline pte_t pte_rdprotect(pte_t pte)
{
pte_val(pte) &= ~(_PAGE_READ | _PAGE_SILENT_READ);
return pte;
}
-extern inline pte_t pte_exprotect(pte_t pte)
+static inline pte_t pte_exprotect(pte_t pte)
{
pte_val(pte) &= ~(_PAGE_READ | _PAGE_SILENT_READ);
return pte;
}
-extern inline pte_t pte_mkclean(pte_t pte)
+static inline pte_t pte_mkclean(pte_t pte)
{
pte_val(pte) &= ~(_PAGE_MODIFIED | _PAGE_SILENT_WRITE);
return pte;
}
-extern inline pte_t pte_mkold(pte_t pte)
+static inline pte_t pte_mkold(pte_t pte)
{
pte_val(pte) &= ~(_PAGE_ACCESSED | _PAGE_SILENT_READ);
return pte;
}
-extern inline pte_t pte_mkwrite(pte_t pte)
+static inline pte_t pte_mkwrite(pte_t pte)
{
pte_val(pte) |= _PAGE_WRITE;
if (pte_val(pte) & _PAGE_MODIFIED)
@@ -157,7 +157,7 @@ extern inline pte_t pte_mkwrite(pte_t pte)
return pte;
}
-extern inline pte_t pte_mkread(pte_t pte)
+static inline pte_t pte_mkread(pte_t pte)
{
pte_val(pte) |= _PAGE_READ;
if (pte_val(pte) & _PAGE_ACCESSED)
@@ -165,7 +165,7 @@ extern inline pte_t pte_mkread(pte_t pte)
return pte;
}
-extern inline pte_t pte_mkexec(pte_t pte)
+static inline pte_t pte_mkexec(pte_t pte)
{
pte_val(pte) |= _PAGE_READ;
if (pte_val(pte) & _PAGE_ACCESSED)
@@ -173,7 +173,7 @@ extern inline pte_t pte_mkexec(pte_t pte)
return pte;
}
-extern inline pte_t pte_mkdirty(pte_t pte)
+static inline pte_t pte_mkdirty(pte_t pte)
{
pte_val(pte) |= _PAGE_MODIFIED;
if (pte_val(pte) & _PAGE_WRITE)
@@ -181,7 +181,7 @@ extern inline pte_t pte_mkdirty(pte_t pte)
return pte;
}
-extern inline pte_t pte_mkyoung(pte_t pte)
+static inline pte_t pte_mkyoung(pte_t pte)
{
pte_val(pte) |= _PAGE_ACCESSED;
if (pte_val(pte) & _PAGE_READ)
@@ -205,7 +205,7 @@ extern inline pte_t pte_mkyoung(pte_t pte)
* addresses (the 0xc0xxxxxx's) goes as void *'s.
*/
-extern inline pte_t __mk_pte(void * page, pgprot_t pgprot)
+static inline pte_t __mk_pte(void * page, pgprot_t pgprot)
{
pte_t pte;
/* the PTE needs a physical address */
@@ -223,7 +223,7 @@ extern inline pte_t __mk_pte(void * page, pgprot_t pgprot)
__pte; \
})
-extern inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
+static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
{ pte_val(pte) = (pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot); return pte; }
@@ -232,7 +232,7 @@ extern inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
* pte_pagenr refers to the page-number counted starting from the virtual DRAM start
*/
-extern inline unsigned long __pte_page(pte_t pte)
+static inline unsigned long __pte_page(pte_t pte)
{
/* the PTE contains a physical address */
return (unsigned long)__va(pte_val(pte) & PAGE_MASK);
@@ -250,7 +250,7 @@ extern inline unsigned long __pte_page(pte_t pte)
* don't need the __pa and __va transformations.
*/
-extern inline void pmd_set(pmd_t * pmdp, pte_t * ptep)
+static inline void pmd_set(pmd_t * pmdp, pte_t * ptep)
{ pmd_val(*pmdp) = _PAGE_TABLE | (unsigned long) ptep; }
#define pmd_page(pmd) (pfn_to_page(pmd_val(pmd) >> PAGE_SHIFT))
@@ -260,7 +260,7 @@ extern inline void pmd_set(pmd_t * pmdp, pte_t * ptep)
#define pgd_index(address) (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD-1))
/* to find an entry in a page-table-directory */
-extern inline pgd_t * pgd_offset(struct mm_struct * mm, unsigned long address)
+static inline pgd_t * pgd_offset(struct mm_struct * mm, unsigned long address)
{
return mm->pgd + pgd_index(address);
}
@@ -296,7 +296,7 @@ extern pgd_t swapper_pg_dir[PTRS_PER_PGD]; /* defined in head.S */
*
* Actually I am not sure on what this could be used for.
*/
-extern inline void update_mmu_cache(struct vm_area_struct * vma,
+static inline void update_mmu_cache(struct vm_area_struct * vma,
unsigned long address, pte_t pte)
{
}
diff --git a/include/asm-cris/processor.h b/include/asm-cris/processor.h
index 0dc218117bd8..dce41009eeb0 100644
--- a/include/asm-cris/processor.h
+++ b/include/asm-cris/processor.h
@@ -16,6 +16,8 @@
#include <asm/ptrace.h>
#include <asm/arch/processor.h>
+struct task_struct;
+
/* This decides where the kernel will search for a free chunk of vm
* space during mmap's.
*/
@@ -45,7 +47,7 @@
#define current_regs() user_regs(current->thread_info)
-extern inline void prepare_to_copy(struct task_struct *tsk)
+static inline void prepare_to_copy(struct task_struct *tsk)
{
}
@@ -58,7 +60,7 @@ unsigned long get_wchan(struct task_struct *p);
extern unsigned long thread_saved_pc(struct task_struct *tsk);
/* Free all resources held by a thread. */
-extern inline void release_thread(struct task_struct *dead_task)
+static inline void release_thread(struct task_struct *dead_task)
{
/* Nothing needs to be done. */
}
diff --git a/include/asm-cris/semaphore.h b/include/asm-cris/semaphore.h
index 8ed7636ab311..53f548b791c1 100644
--- a/include/asm-cris/semaphore.h
+++ b/include/asm-cris/semaphore.h
@@ -18,8 +18,6 @@
* CRIS semaphores, implemented in C-only so far.
*/
-int printk(const char *fmt, ...);
-
struct semaphore {
atomic_t count;
atomic_t waking;
@@ -33,26 +31,23 @@ struct semaphore {
.wait = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \
}
-#define __MUTEX_INITIALIZER(name) \
- __SEMAPHORE_INITIALIZER(name,1)
-
#define __DECLARE_SEMAPHORE_GENERIC(name,count) \
struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
#define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1)
#define DECLARE_MUTEX_LOCKED(name) __DECLARE_SEMAPHORE_GENERIC(name,0)
-extern inline void sema_init(struct semaphore *sem, int val)
+static inline void sema_init(struct semaphore *sem, int val)
{
*sem = (struct semaphore)__SEMAPHORE_INITIALIZER((*sem),val);
}
-extern inline void init_MUTEX (struct semaphore *sem)
+static inline void init_MUTEX (struct semaphore *sem)
{
sema_init(sem, 1);
}
-extern inline void init_MUTEX_LOCKED (struct semaphore *sem)
+static inline void init_MUTEX_LOCKED (struct semaphore *sem)
{
sema_init(sem, 0);
}
@@ -64,7 +59,7 @@ extern void __up(struct semaphore * sem);
/* notice - we probably can do cli/sti here instead of saving */
-extern inline void down(struct semaphore * sem)
+static inline void down(struct semaphore * sem)
{
unsigned long flags;
int failed;
@@ -86,7 +81,7 @@ extern inline void down(struct semaphore * sem)
* returns negative for signalled and zero for semaphore acquired.
*/
-extern inline int down_interruptible(struct semaphore * sem)
+static inline int down_interruptible(struct semaphore * sem)
{
unsigned long flags;
int failed;
@@ -102,7 +97,7 @@ extern inline int down_interruptible(struct semaphore * sem)
return(failed);
}
-extern inline int down_trylock(struct semaphore * sem)
+static inline int down_trylock(struct semaphore * sem)
{
unsigned long flags;
int failed;
@@ -122,7 +117,7 @@ extern inline int down_trylock(struct semaphore * sem)
* The default case (no contention) will result in NO
* jumps for both down() and up().
*/
-extern inline void up(struct semaphore * sem)
+static inline void up(struct semaphore * sem)
{
unsigned long flags;
int wakeup;
diff --git a/include/asm-cris/system.h b/include/asm-cris/system.h
index e06739806d4e..d48670107a85 100644
--- a/include/asm-cris/system.h
+++ b/include/asm-cris/system.h
@@ -41,7 +41,7 @@ extern struct task_struct *resume(struct task_struct *prev, struct task_struct *
void disable_hlt(void);
void enable_hlt(void);
-extern inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size)
+static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size)
{
/* since Etrax doesn't have any atomic xchg instructions, we need to disable
irq's (if enabled) and do it with move.d's */
diff --git a/include/asm-cris/timex.h b/include/asm-cris/timex.h
index 3fb069a37717..b92e0e80fe86 100644
--- a/include/asm-cris/timex.h
+++ b/include/asm-cris/timex.h
@@ -16,7 +16,7 @@
typedef unsigned long long cycles_t;
-extern inline cycles_t get_cycles(void)
+static inline cycles_t get_cycles(void)
{
return 0;
}
diff --git a/include/asm-cris/tlbflush.h b/include/asm-cris/tlbflush.h
index 6ed7d9ae90db..c52238005b55 100644
--- a/include/asm-cris/tlbflush.h
+++ b/include/asm-cris/tlbflush.h
@@ -39,14 +39,14 @@ static inline void flush_tlb_range(struct vm_area_struct * vma, unsigned long st
flush_tlb_mm(vma->vm_mm);
}
-extern inline void flush_tlb_pgtables(struct mm_struct *mm,
+static inline void flush_tlb_pgtables(struct mm_struct *mm,
unsigned long start, unsigned long end)
{
/* CRIS does not keep any page table caches in TLB */
}
-extern inline void flush_tlb(void)
+static inline void flush_tlb(void)
{
flush_tlb_mm(current->mm);
}
diff --git a/include/asm-cris/uaccess.h b/include/asm-cris/uaccess.h
index 7d50086eb5ea..69d48a2dc8e1 100644
--- a/include/asm-cris/uaccess.h
+++ b/include/asm-cris/uaccess.h
@@ -213,7 +213,7 @@ extern unsigned long __copy_user(void *to, const void *from, unsigned long n);
extern unsigned long __copy_user_zeroing(void *to, const void *from, unsigned long n);
extern unsigned long __do_clear_user(void *to, unsigned long n);
-extern inline unsigned long
+static inline unsigned long
__generic_copy_to_user(void __user *to, const void *from, unsigned long n)
{
if (access_ok(VERIFY_WRITE, to, n))
@@ -221,7 +221,7 @@ __generic_copy_to_user(void __user *to, const void *from, unsigned long n)
return n;
}
-extern inline unsigned long
+static inline unsigned long
__generic_copy_from_user(void *to, const void __user *from, unsigned long n)
{
if (access_ok(VERIFY_READ, from, n))
@@ -229,7 +229,7 @@ __generic_copy_from_user(void *to, const void __user *from, unsigned long n)
return n;
}
-extern inline unsigned long
+static inline unsigned long
__generic_clear_user(void __user *to, unsigned long n)
{
if (access_ok(VERIFY_WRITE, to, n))
@@ -237,13 +237,13 @@ __generic_clear_user(void __user *to, unsigned long n)
return n;
}
-extern inline long
+static inline long
__strncpy_from_user(char *dst, const char __user *src, long count)
{
return __do_strncpy_from_user(dst, src, count);
}
-extern inline long
+static inline long
strncpy_from_user(char *dst, const char __user *src, long count)
{
long res = -EFAULT;
@@ -256,7 +256,7 @@ strncpy_from_user(char *dst, const char __user *src, long count)
/* Note that if these expand awfully if made into switch constructs, so
don't do that. */
-extern inline unsigned long
+static inline unsigned long
__constant_copy_from_user(void *to, const void __user *from, unsigned long n)
{
unsigned long ret = 0;
@@ -306,7 +306,7 @@ __constant_copy_from_user(void *to, const void __user *from, unsigned long n)
/* Ditto, don't make a switch out of this. */
-extern inline unsigned long
+static inline unsigned long
__constant_copy_to_user(void __user *to, const void *from, unsigned long n)
{
unsigned long ret = 0;
@@ -356,7 +356,7 @@ __constant_copy_to_user(void __user *to, const void *from, unsigned long n)
/* No switch, please. */
-extern inline unsigned long
+static inline unsigned long
__constant_clear_user(void __user *to, unsigned long n)
{
unsigned long ret = 0;
@@ -406,19 +406,19 @@ __constant_clear_user(void __user *to, unsigned long n)
* used in fast paths and have only a small space overhead.
*/
-extern inline unsigned long
+static inline unsigned long
__generic_copy_from_user_nocheck(void *to, const void *from, unsigned long n)
{
return __copy_user_zeroing(to,from,n);
}
-extern inline unsigned long
+static inline unsigned long
__generic_copy_to_user_nocheck(void *to, const void *from, unsigned long n)
{
return __copy_user(to,from,n);
}
-extern inline unsigned long
+static inline unsigned long
__generic_clear_user_nocheck(void *to, unsigned long n)
{
return __do_clear_user(to,n);
diff --git a/include/asm-cris/unistd.h b/include/asm-cris/unistd.h
index 28232ad2ff34..2627bbdf8a11 100644
--- a/include/asm-cris/unistd.h
+++ b/include/asm-cris/unistd.h
@@ -343,14 +343,14 @@
* some others too.
*/
#define __NR__exit __NR_exit
-extern inline _syscall0(pid_t,setsid)
-extern inline _syscall3(int,write,int,fd,const char *,buf,off_t,count)
-extern inline _syscall3(int,read,int,fd,char *,buf,off_t,count)
-extern inline _syscall3(off_t,lseek,int,fd,off_t,offset,int,count)
-extern inline _syscall1(int,dup,int,fd)
-extern inline _syscall3(int,execve,const char *,file,char **,argv,char **,envp)
-extern inline _syscall3(int,open,const char *,file,int,flag,int,mode)
-extern inline _syscall1(int,close,int,fd)
+static inline _syscall0(pid_t,setsid)
+static inline _syscall3(int,write,int,fd,const char *,buf,off_t,count)
+static inline _syscall3(int,read,int,fd,char *,buf,off_t,count)
+static inline _syscall3(off_t,lseek,int,fd,off_t,offset,int,count)
+static inline _syscall1(int,dup,int,fd)
+static inline _syscall3(int,execve,const char *,file,char **,argv,char **,envp)
+static inline _syscall3(int,open,const char *,file,int,flag,int,mode)
+static inline _syscall1(int,close,int,fd)
struct pt_regs;
asmlinkage long sys_mmap2(
@@ -367,7 +367,6 @@ asmlinkage int sys_fork(long r10, long r11, long r12, long r13,
asmlinkage int sys_vfork(long r10, long r11, long r12, long r13,
long mof, long srp, struct pt_regs *regs);
asmlinkage int sys_pipe(unsigned long __user *fildes);
-asmlinkage int sys_ptrace(long request, long pid, long addr, long data);
struct sigaction;
asmlinkage long sys_rt_sigaction(int sig,
const struct sigaction __user *act,
@@ -383,8 +382,8 @@ asmlinkage long sys_rt_sigaction(int sig,
#ifdef __KERNEL__
#define _exit kernel_syscall_exit
#endif
-extern inline _syscall1(int,_exit,int,exitcode)
-extern inline _syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options)
+static inline _syscall1(int,_exit,int,exitcode)
+static inline _syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options)
#endif
diff --git a/include/asm-frv/dma-mapping.h b/include/asm-frv/dma-mapping.h
index 0206ab35eae0..5003e017fd1e 100644
--- a/include/asm-frv/dma-mapping.h
+++ b/include/asm-frv/dma-mapping.h
@@ -13,7 +13,7 @@
extern unsigned long __nongprelbss dma_coherent_mem_start;
extern unsigned long __nongprelbss dma_coherent_mem_end;
-void *dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, int gfp);
+void *dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t gfp);
void dma_free_coherent(struct device *dev, size_t size, void *vaddr, dma_addr_t dma_handle);
/*
diff --git a/include/asm-frv/pci.h b/include/asm-frv/pci.h
index b4efe5e3591a..1168451c275f 100644
--- a/include/asm-frv/pci.h
+++ b/include/asm-frv/pci.h
@@ -32,7 +32,7 @@ extern void pcibios_set_master(struct pci_dev *dev);
extern void pcibios_penalize_isa_irq(int irq);
#ifdef CONFIG_MMU
-extern void *consistent_alloc(int gfp, size_t size, dma_addr_t *dma_handle);
+extern void *consistent_alloc(gfp_t gfp, size_t size, dma_addr_t *dma_handle);
extern void consistent_free(void *vaddr);
extern void consistent_sync(void *vaddr, size_t size, int direction);
extern void consistent_sync_page(struct page *page, unsigned long offset,
diff --git a/include/asm-frv/pgtable.h b/include/asm-frv/pgtable.h
index 473fb4bb6329..844666377dcb 100644
--- a/include/asm-frv/pgtable.h
+++ b/include/asm-frv/pgtable.h
@@ -26,6 +26,8 @@
#include <linux/slab.h>
#include <linux/list.h>
#include <linux/spinlock.h>
+struct mm_struct;
+struct vm_area_struct;
#endif
#ifndef __ASSEMBLY__
@@ -436,8 +438,6 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
return pte;
}
-#define page_pte(page) page_pte_prot((page), __pgprot(0))
-
/* to find an entry in a page-table-directory. */
#define pgd_index(address) (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD - 1))
#define pgd_index_k(addr) pgd_index(addr)
diff --git a/include/asm-frv/semaphore.h b/include/asm-frv/semaphore.h
index 393545630806..b18396288df1 100644
--- a/include/asm-frv/semaphore.h
+++ b/include/asm-frv/semaphore.h
@@ -47,9 +47,6 @@ struct semaphore {
#define __SEMAPHORE_INITIALIZER(name,count) \
{ count, SPIN_LOCK_UNLOCKED, LIST_HEAD_INIT((name).wait_list) __SEM_DEBUG_INIT(name) }
-#define __MUTEX_INITIALIZER(name) \
- __SEMAPHORE_INITIALIZER(name,1)
-
#define __DECLARE_SEMAPHORE_GENERIC(name,count) \
struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
diff --git a/include/asm-generic/4level-fixup.h b/include/asm-generic/4level-fixup.h
index c20ec257ecc0..68c6fea994d9 100644
--- a/include/asm-generic/4level-fixup.h
+++ b/include/asm-generic/4level-fixup.h
@@ -10,14 +10,9 @@
#define pud_t pgd_t
-#define pmd_alloc(mm, pud, address) \
-({ pmd_t *ret; \
- if (pgd_none(*pud)) \
- ret = __pmd_alloc(mm, pud, address); \
- else \
- ret = pmd_offset(pud, address); \
- ret; \
-})
+#define pmd_alloc(mm, pud, address) \
+ ((unlikely(pgd_none(*(pud))) && __pmd_alloc(mm, pud, address))? \
+ NULL: pmd_offset(pud, address))
#define pud_alloc(mm, pgd, address) (pgd)
#define pud_offset(pgd, start) (pgd)
diff --git a/include/asm-generic/dma-mapping-broken.h b/include/asm-generic/dma-mapping-broken.h
index fd9de9502dff..a7f1a55ce6b0 100644
--- a/include/asm-generic/dma-mapping-broken.h
+++ b/include/asm-generic/dma-mapping-broken.h
@@ -6,7 +6,7 @@
static inline void *
dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle,
- int flag)
+ gfp_t flag)
{
BUG();
return NULL;
diff --git a/include/asm-generic/pgtable.h b/include/asm-generic/pgtable.h
index ff28c8b31f58..358e4d309ceb 100644
--- a/include/asm-generic/pgtable.h
+++ b/include/asm-generic/pgtable.h
@@ -8,7 +8,7 @@
* - update the page tables
* - inform the TLB about the new one
*
- * We hold the mm semaphore for reading and vma->vm_mm->page_table_lock.
+ * We hold the mm semaphore for reading, and the pte lock.
*
* Note: the old pte is known to not be writable, so we don't need to
* worry about dirty bits etc getting lost.
@@ -128,6 +128,7 @@ do { \
#endif
#ifndef __HAVE_ARCH_PTEP_SET_WRPROTECT
+struct mm_struct;
static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long address, pte_t *ptep)
{
pte_t old_pte = *ptep;
diff --git a/include/asm-generic/tlb.h b/include/asm-generic/tlb.h
index 7d0298347ee7..cdd4145243cd 100644
--- a/include/asm-generic/tlb.h
+++ b/include/asm-generic/tlb.h
@@ -35,16 +35,13 @@
#endif
/* struct mmu_gather is an opaque type used by the mm code for passing around
- * any data needed by arch specific code for tlb_remove_page. This structure
- * can be per-CPU or per-MM as the page table lock is held for the duration of
- * TLB shootdown.
+ * any data needed by arch specific code for tlb_remove_page.
*/
struct mmu_gather {
struct mm_struct *mm;
unsigned int nr; /* set to ~0U means fast mode */
unsigned int need_flush;/* Really unmapped some ptes? */
unsigned int fullmm; /* non-zero means full mm flush */
- unsigned long freed;
struct page * pages[FREE_PTE_NR];
};
@@ -57,7 +54,7 @@ DECLARE_PER_CPU(struct mmu_gather, mmu_gathers);
static inline struct mmu_gather *
tlb_gather_mmu(struct mm_struct *mm, unsigned int full_mm_flush)
{
- struct mmu_gather *tlb = &per_cpu(mmu_gathers, smp_processor_id());
+ struct mmu_gather *tlb = &get_cpu_var(mmu_gathers);
tlb->mm = mm;
@@ -65,7 +62,6 @@ tlb_gather_mmu(struct mm_struct *mm, unsigned int full_mm_flush)
tlb->nr = num_online_cpus() > 1 ? 0U : ~0U;
tlb->fullmm = full_mm_flush;
- tlb->freed = 0;
return tlb;
}
@@ -85,28 +81,17 @@ tlb_flush_mmu(struct mmu_gather *tlb, unsigned long start, unsigned long end)
/* tlb_finish_mmu
* Called at the end of the shootdown operation to free up any resources
- * that were required. The page table lock is still held at this point.
+ * that were required.
*/
static inline void
tlb_finish_mmu(struct mmu_gather *tlb, unsigned long start, unsigned long end)
{
- int freed = tlb->freed;
- struct mm_struct *mm = tlb->mm;
- int rss = get_mm_counter(mm, rss);
-
- if (rss < freed)
- freed = rss;
- add_mm_counter(mm, rss, -freed);
tlb_flush_mmu(tlb, start, end);
/* keep the page table cache within bounds */
check_pgt_cache();
-}
-static inline unsigned int
-tlb_is_full_mm(struct mmu_gather *tlb)
-{
- return tlb->fullmm;
+ put_cpu_var(mmu_gathers);
}
/* tlb_remove_page
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
index a9c55490fb82..094d4917c1a9 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -35,6 +35,13 @@
VMLINUX_SYMBOL(__end_pci_fixups_enable) = .; \
} \
\
+ /* RapidIO route ops */ \
+ .rio_route : AT(ADDR(.rio_route) - LOAD_OFFSET) { \
+ VMLINUX_SYMBOL(__start_rio_route_ops) = .; \
+ *(.rio_route_ops) \
+ VMLINUX_SYMBOL(__end_rio_route_ops) = .; \
+ } \
+ \
/* Kernel symbol table: Normal symbols */ \
__ksymtab : AT(ADDR(__ksymtab) - LOAD_OFFSET) { \
VMLINUX_SYMBOL(__start___ksymtab) = .; \
diff --git a/include/asm-h8300/semaphore.h b/include/asm-h8300/semaphore.h
index fe6ef3774297..81bae2a99192 100644
--- a/include/asm-h8300/semaphore.h
+++ b/include/asm-h8300/semaphore.h
@@ -35,9 +35,6 @@ struct semaphore {
.wait = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \
}
-#define __MUTEX_INITIALIZER(name) \
- __SEMAPHORE_INITIALIZER(name,1)
-
#define __DECLARE_SEMAPHORE_GENERIC(name,count) \
struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
diff --git a/include/asm-h8300/unistd.h b/include/asm-h8300/unistd.h
index 56a6401886fa..56a4a5686c88 100644
--- a/include/asm-h8300/unistd.h
+++ b/include/asm-h8300/unistd.h
@@ -528,7 +528,6 @@ asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
asmlinkage int sys_execve(char *name, char **argv, char **envp,
int dummy, ...);
asmlinkage int sys_pipe(unsigned long *fildes);
-asmlinkage int sys_ptrace(long request, long pid, long addr, long data);
struct sigaction;
asmlinkage long sys_rt_sigaction(int sig,
const struct sigaction __user *act,
diff --git a/include/asm-i386/desc.h b/include/asm-i386/desc.h
index 6df1a53c190e..29b851a18c6e 100644
--- a/include/asm-i386/desc.h
+++ b/include/asm-i386/desc.h
@@ -17,6 +17,8 @@
extern struct desc_struct cpu_gdt_table[GDT_ENTRIES];
DECLARE_PER_CPU(struct desc_struct, cpu_gdt_table[GDT_ENTRIES]);
+#define get_cpu_gdt_table(_cpu) (per_cpu(cpu_gdt_table,_cpu))
+
DECLARE_PER_CPU(unsigned char, cpu_16bit_stack[CPU_16BIT_STACK_SIZE]);
struct Xgt_desc_struct {
@@ -60,7 +62,7 @@ __asm__ __volatile__ ("movw %w3,0(%2)\n\t" \
static inline void __set_tss_desc(unsigned int cpu, unsigned int entry, void *addr)
{
- _set_tssldt_desc(&per_cpu(cpu_gdt_table, cpu)[entry], (int)addr,
+ _set_tssldt_desc(&get_cpu_gdt_table(cpu)[entry], (int)addr,
offsetof(struct tss_struct, __cacheline_filler) - 1, 0x89);
}
@@ -68,7 +70,7 @@ static inline void __set_tss_desc(unsigned int cpu, unsigned int entry, void *ad
static inline void set_ldt_desc(unsigned int cpu, void *addr, unsigned int size)
{
- _set_tssldt_desc(&per_cpu(cpu_gdt_table, cpu)[GDT_ENTRY_LDT], (int)addr, ((size << 3)-1), 0x82);
+ _set_tssldt_desc(&get_cpu_gdt_table(cpu)[GDT_ENTRY_LDT], (int)addr, ((size << 3)-1), 0x82);
}
#define LDT_entry_a(info) \
@@ -109,7 +111,7 @@ static inline void write_ldt_entry(void *ldt, int entry, __u32 entry_a, __u32 en
static inline void load_TLS(struct thread_struct *t, unsigned int cpu)
{
-#define C(i) per_cpu(cpu_gdt_table, cpu)[GDT_ENTRY_TLS_MIN + i] = t->tls_array[i]
+#define C(i) get_cpu_gdt_table(cpu)[GDT_ENTRY_TLS_MIN + i] = t->tls_array[i]
C(0); C(1); C(2);
#undef C
}
diff --git a/include/asm-i386/elf.h b/include/asm-i386/elf.h
index fa11117d3cfa..4153d80e4d2b 100644
--- a/include/asm-i386/elf.h
+++ b/include/asm-i386/elf.h
@@ -119,6 +119,8 @@ typedef struct user_fxsr_struct elf_fpxregset_t;
*/
#define elf_read_implies_exec(ex, executable_stack) (executable_stack != EXSTACK_DISABLE_X)
+struct task_struct;
+
extern int dump_task_regs (struct task_struct *, elf_gregset_t *);
extern int dump_task_fpu (struct task_struct *, elf_fpregset_t *);
extern int dump_task_extended_fpu (struct task_struct *, struct user_fxsr_struct *);
diff --git a/include/asm-i386/ide.h b/include/asm-i386/ide.h
index 79dfab87135d..454440193eac 100644
--- a/include/asm-i386/ide.h
+++ b/include/asm-i386/ide.h
@@ -41,6 +41,12 @@ static __inline__ int ide_default_irq(unsigned long base)
static __inline__ unsigned long ide_default_io_base(int index)
{
+ /*
+ * If PCI is present then it is not safe to poke around
+ * the other legacy IDE ports. Only 0x1f0 and 0x170 are
+ * defined compatibility mode ports for PCI. A user can
+ * override this using ide= but we must default safe.
+ */
if (pci_find_device(PCI_ANY_ID, PCI_ANY_ID, NULL) == NULL) {
switch(index) {
case 2: return 0x1e8;
diff --git a/include/asm-i386/kprobes.h b/include/asm-i386/kprobes.h
index 8b6d3a90cd78..ca916a892877 100644
--- a/include/asm-i386/kprobes.h
+++ b/include/asm-i386/kprobes.h
@@ -49,6 +49,23 @@ struct arch_specific_insn {
kprobe_opcode_t insn[MAX_INSN_SIZE];
};
+struct prev_kprobe {
+ struct kprobe *kp;
+ unsigned long status;
+ unsigned long old_eflags;
+ unsigned long saved_eflags;
+};
+
+/* per-cpu kprobe control block */
+struct kprobe_ctlblk {
+ unsigned long kprobe_status;
+ unsigned long kprobe_old_eflags;
+ unsigned long kprobe_saved_eflags;
+ long *jprobe_saved_esp;
+ struct pt_regs jprobe_saved_regs;
+ kprobe_opcode_t jprobes_stack[MAX_STACK_SIZE];
+ struct prev_kprobe prev_kprobe;
+};
/* trap3/1 are intr gates for kprobes. So, restore the status of IF,
* if necessary, before executing the original int3/1 (trap) handler.
diff --git a/include/asm-i386/mach-es7000/mach_mpparse.h b/include/asm-i386/mach-es7000/mach_mpparse.h
index 28a84f6185a7..4a0637a3e208 100644
--- a/include/asm-i386/mach-es7000/mach_mpparse.h
+++ b/include/asm-i386/mach-es7000/mach_mpparse.h
@@ -16,7 +16,7 @@ static inline void mpc_oem_pci_bus(struct mpc_config_bus *m,
extern int parse_unisys_oem (char *oemptr);
extern int find_unisys_acpi_oem_table(unsigned long *oem_addr);
-extern void setup_unisys();
+extern void setup_unisys(void);
static inline int mps_oem_check(struct mp_config_table *mpc, char *oem,
char *productid)
diff --git a/include/asm-i386/mach-summit/mach_mpparse.h b/include/asm-i386/mach-summit/mach_mpparse.h
index 2b9e6d55bef1..1cce2b924a80 100644
--- a/include/asm-i386/mach-summit/mach_mpparse.h
+++ b/include/asm-i386/mach-summit/mach_mpparse.h
@@ -22,7 +22,6 @@ static inline void mpc_oem_pci_bus(struct mpc_config_bus *m,
{
}
-extern int usb_early_handoff;
static inline int mps_oem_check(struct mp_config_table *mpc, char *oem,
char *productid)
{
@@ -32,7 +31,6 @@ static inline int mps_oem_check(struct mp_config_table *mpc, char *oem,
|| !strncmp(productid, "RUTHLESS SMP", 12))){
use_cyclone = 1; /*enable cyclone-timer*/
setup_summit();
- usb_early_handoff = 1;
return 1;
}
return 0;
@@ -46,7 +44,6 @@ static inline int acpi_madt_oem_check(char *oem_id, char *oem_table_id)
|| !strncmp(oem_table_id, "EXA", 3))){
use_cyclone = 1; /*enable cyclone-timer*/
setup_summit();
- usb_early_handoff = 1;
return 1;
}
return 0;
diff --git a/include/asm-i386/mmzone.h b/include/asm-i386/mmzone.h
index 348fe3a4879d..620a90641ea8 100644
--- a/include/asm-i386/mmzone.h
+++ b/include/asm-i386/mmzone.h
@@ -88,12 +88,6 @@ static inline int pfn_to_nid(unsigned long pfn)
__pgdat->node_start_pfn + __pgdat->node_spanned_pages; \
})
-#define local_mapnr(kvaddr) \
-({ \
- unsigned long __pfn = __pa(kvaddr) >> PAGE_SHIFT; \
- (__pfn - node_start_pfn(pfn_to_nid(__pfn))); \
-})
-
/* XXX: FIXME -- wli */
#define kern_addr_valid(kaddr) (0)
diff --git a/include/asm-i386/msi.h b/include/asm-i386/msi.h
index b85393094c83..f041d4495faf 100644
--- a/include/asm-i386/msi.h
+++ b/include/asm-i386/msi.h
@@ -10,13 +10,6 @@
#include <mach_apic.h>
#define LAST_DEVICE_VECTOR 232
-#define MSI_DEST_MODE MSI_LOGICAL_MODE
-#define MSI_TARGET_CPU_SHIFT 12
-
-#ifdef CONFIG_SMP
-#define MSI_TARGET_CPU logical_smp_processor_id()
-#else
-#define MSI_TARGET_CPU cpu_to_logical_apicid(first_cpu(cpu_online_map))
-#endif
+#define MSI_TARGET_CPU_SHIFT 12
#endif /* ASM_MSI_H */
diff --git a/include/asm-i386/pgtable-2level.h b/include/asm-i386/pgtable-2level.h
index fa07bd6c7529..74ef721b534d 100644
--- a/include/asm-i386/pgtable-2level.h
+++ b/include/asm-i386/pgtable-2level.h
@@ -26,11 +26,6 @@
#define pfn_pte(pfn, prot) __pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot))
#define pfn_pmd(pfn, prot) __pmd(((pfn) << PAGE_SHIFT) | pgprot_val(prot))
-#define pmd_page(pmd) (pfn_to_page(pmd_val(pmd) >> PAGE_SHIFT))
-
-#define pmd_page_kernel(pmd) \
-((unsigned long) __va(pmd_val(pmd) & PAGE_MASK))
-
/*
* All present user pages are user-executable:
*/
diff --git a/include/asm-i386/pgtable-3level.h b/include/asm-i386/pgtable-3level.h
index 2e3f4a344a2d..f1a8b454920a 100644
--- a/include/asm-i386/pgtable-3level.h
+++ b/include/asm-i386/pgtable-3level.h
@@ -74,11 +74,6 @@ static inline void set_pte(pte_t *ptep, pte_t pte)
*/
static inline void pud_clear (pud_t * pud) { }
-#define pmd_page(pmd) (pfn_to_page(pmd_val(pmd) >> PAGE_SHIFT))
-
-#define pmd_page_kernel(pmd) \
-((unsigned long) __va(pmd_val(pmd) & PAGE_MASK))
-
#define pud_page(pud) \
((struct page *) __va(pud_val(pud) & PAGE_MASK))
diff --git a/include/asm-i386/pgtable.h b/include/asm-i386/pgtable.h
index d101ac414f07..088a945bf26b 100644
--- a/include/asm-i386/pgtable.h
+++ b/include/asm-i386/pgtable.h
@@ -25,6 +25,9 @@
#include <linux/list.h>
#include <linux/spinlock.h>
+struct mm_struct;
+struct vm_area_struct;
+
/*
* ZERO_PAGE is a global shared page that is always zero: used
* for zero-mapped memory areas etc..
@@ -203,7 +206,8 @@ extern unsigned long pg0[];
#define pte_present(x) ((x).pte_low & (_PAGE_PRESENT | _PAGE_PROTNONE))
#define pte_clear(mm,addr,xp) do { set_pte_at(mm, addr, xp, __pte(0)); } while (0)
-#define pmd_none(x) (!pmd_val(x))
+/* To avoid harmful races, pmd_none(x) should check only the lower when PAE */
+#define pmd_none(x) (!(unsigned long)pmd_val(x))
#define pmd_present(x) (pmd_val(x) & _PAGE_PRESENT)
#define pmd_clear(xp) do { set_pmd(xp, __pmd(0)); } while (0)
#define pmd_bad(x) ((pmd_val(x) & (~PAGE_MASK & ~_PAGE_USER)) != _KERNPG_TABLE)
@@ -322,8 +326,6 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
return pte;
}
-#define page_pte(page) page_pte_prot(page, __pgprot(0))
-
#define pmd_large(pmd) \
((pmd_val(pmd) & (_PAGE_PSE|_PAGE_PRESENT)) == (_PAGE_PSE|_PAGE_PRESENT))
@@ -368,6 +370,11 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
#define pte_offset_kernel(dir, address) \
((pte_t *) pmd_page_kernel(*(dir)) + pte_index(address))
+#define pmd_page(pmd) (pfn_to_page(pmd_val(pmd) >> PAGE_SHIFT))
+
+#define pmd_page_kernel(pmd) \
+ ((unsigned long) __va(pmd_val(pmd) & PAGE_MASK))
+
/*
* Helper function that returns the kernel pagetable entry controlling
* the virtual address 'address'. NULL means no pagetable entry present.
diff --git a/include/asm-i386/processor.h b/include/asm-i386/processor.h
index 0a4ec764377c..8c02b0318703 100644
--- a/include/asm-i386/processor.h
+++ b/include/asm-i386/processor.h
@@ -718,4 +718,10 @@ extern void mtrr_bp_init(void);
#define mtrr_bp_init() do {} while (0)
#endif
+#ifdef CONFIG_X86_MCE
+extern void mcheck_init(struct cpuinfo_x86 *c);
+#else
+#define mcheck_init(c) do {} while(0)
+#endif
+
#endif /* __ASM_I386_PROCESSOR_H */
diff --git a/include/asm-i386/rwsem.h b/include/asm-i386/rwsem.h
index 7625a675852f..be4ab859238e 100644
--- a/include/asm-i386/rwsem.h
+++ b/include/asm-i386/rwsem.h
@@ -284,5 +284,10 @@ LOCK_PREFIX "xadd %0,(%2)"
return tmp+delta;
}
+static inline int rwsem_is_locked(struct rw_semaphore *sem)
+{
+ return (sem->count != 0);
+}
+
#endif /* __KERNEL__ */
#endif /* _I386_RWSEM_H */
diff --git a/include/asm-i386/semaphore.h b/include/asm-i386/semaphore.h
index ea563da63e24..6a42b2142fd6 100644
--- a/include/asm-i386/semaphore.h
+++ b/include/asm-i386/semaphore.h
@@ -55,9 +55,6 @@ struct semaphore {
.wait = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \
}
-#define __MUTEX_INITIALIZER(name) \
- __SEMAPHORE_INITIALIZER(name,1)
-
#define __DECLARE_SEMAPHORE_GENERIC(name,count) \
struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
diff --git a/include/asm-i386/smp.h b/include/asm-i386/smp.h
index 13250199976d..61d3ab9db70c 100644
--- a/include/asm-i386/smp.h
+++ b/include/asm-i386/smp.h
@@ -45,6 +45,8 @@ extern void unlock_ipi_call_lock(void);
#define MAX_APICID 256
extern u8 x86_cpu_to_apicid[];
+#define cpu_physical_id(cpu) x86_cpu_to_apicid[cpu]
+
#ifdef CONFIG_HOTPLUG_CPU
extern void cpu_exit_clear(void);
extern void cpu_uninit(void);
@@ -92,6 +94,10 @@ extern int __cpu_disable(void);
extern void __cpu_die(unsigned int cpu);
#endif /* !__ASSEMBLY__ */
+#else /* CONFIG_SMP */
+
+#define cpu_physical_id(cpu) boot_cpu_physical_apicid
+
#define NO_PROC_ID 0xFF /* No processor magic marker */
#endif
diff --git a/include/asm-i386/system.h b/include/asm-i386/system.h
index acd5c26b69ba..97d52ac49e46 100644
--- a/include/asm-i386/system.h
+++ b/include/asm-i386/system.h
@@ -167,6 +167,8 @@ struct __xchg_dummy { unsigned long a[100]; };
#define __xg(x) ((struct __xchg_dummy *)(x))
+#ifdef CONFIG_X86_CMPXCHG64
+
/*
* The semantics of XCHGCMP8B are a bit strange, this is why
* there is a loop and the loading of %%eax and %%edx has to
@@ -221,6 +223,8 @@ static inline void __set_64bit_var (unsigned long long *ptr,
__set_64bit(ptr, (unsigned int)(value), (unsigned int)((value)>>32ULL) ) : \
__set_64bit(ptr, ll_low(value), ll_high(value)) )
+#endif
+
/*
* Note: no "lock" prefix even on SMP: xchg always implies lock anyway
* Note 2: xchg has side effect, so that attribute volatile is necessary,
@@ -259,7 +263,6 @@ static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int siz
#ifdef CONFIG_X86_CMPXCHG
#define __HAVE_ARCH_CMPXCHG 1
-#endif
static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
unsigned long new, int size)
@@ -275,13 +278,13 @@ static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
case 2:
__asm__ __volatile__(LOCK_PREFIX "cmpxchgw %w1,%2"
: "=a"(prev)
- : "q"(new), "m"(*__xg(ptr)), "0"(old)
+ : "r"(new), "m"(*__xg(ptr)), "0"(old)
: "memory");
return prev;
case 4:
__asm__ __volatile__(LOCK_PREFIX "cmpxchgl %1,%2"
: "=a"(prev)
- : "q"(new), "m"(*__xg(ptr)), "0"(old)
+ : "r"(new), "m"(*__xg(ptr)), "0"(old)
: "memory");
return prev;
}
@@ -291,6 +294,30 @@ static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
#define cmpxchg(ptr,o,n)\
((__typeof__(*(ptr)))__cmpxchg((ptr),(unsigned long)(o),\
(unsigned long)(n),sizeof(*(ptr))))
+
+#endif
+
+#ifdef CONFIG_X86_CMPXCHG64
+
+static inline unsigned long long __cmpxchg64(volatile void *ptr, unsigned long long old,
+ unsigned long long new)
+{
+ unsigned long long prev;
+ __asm__ __volatile__(LOCK_PREFIX "cmpxchg8b %3"
+ : "=A"(prev)
+ : "b"((unsigned long)new),
+ "c"((unsigned long)(new >> 32)),
+ "m"(*__xg(ptr)),
+ "0"(old)
+ : "memory");
+ return prev;
+}
+
+#define cmpxchg64(ptr,o,n)\
+ ((__typeof__(*(ptr)))__cmpxchg64((ptr),(unsigned long long)(o),\
+ (unsigned long long)(n)))
+
+#endif
#ifdef __KERNEL__
struct alt_instr {
diff --git a/include/asm-i386/unistd.h b/include/asm-i386/unistd.h
index fbaf90a3968c..0f92e78dfea1 100644
--- a/include/asm-i386/unistd.h
+++ b/include/asm-i386/unistd.h
@@ -448,7 +448,6 @@ asmlinkage int sys_clone(struct pt_regs regs);
asmlinkage int sys_fork(struct pt_regs regs);
asmlinkage int sys_vfork(struct pt_regs regs);
asmlinkage int sys_pipe(unsigned long __user *fildes);
-asmlinkage int sys_ptrace(long request, long pid, long addr, long data);
asmlinkage long sys_iopl(unsigned long unused);
struct sigaction;
asmlinkage long sys_rt_sigaction(int sig,
diff --git a/include/asm-ia64/dma-mapping.h b/include/asm-ia64/dma-mapping.h
index 6347c9845642..df67d40801de 100644
--- a/include/asm-ia64/dma-mapping.h
+++ b/include/asm-ia64/dma-mapping.h
@@ -48,12 +48,7 @@ dma_set_mask (struct device *dev, u64 mask)
return 0;
}
-static inline int
-dma_get_cache_alignment (void)
-{
- extern int ia64_max_cacheline_size;
- return ia64_max_cacheline_size;
-}
+extern int dma_get_cache_alignment(void);
static inline void
dma_cache_sync (void *vaddr, size_t size, enum dma_data_direction dir)
diff --git a/include/asm-ia64/kdebug.h b/include/asm-ia64/kdebug.h
index 4d376e1663f7..8b01a083dde6 100644
--- a/include/asm-ia64/kdebug.h
+++ b/include/asm-ia64/kdebug.h
@@ -22,6 +22,9 @@
* 2005-Apr Rusty Lynch <rusty.lynch@intel.com> and Anil S Keshavamurthy
* <anil.s.keshavamurthy@intel.com> adopted from
* include/asm-x86_64/kdebug.h
+ *
+ * 2005-Oct Keith Owens <kaos@sgi.com>. Expand notify_die to cover more
+ * events.
*/
#include <linux/notifier.h>
@@ -35,13 +38,36 @@ struct die_args {
int signr;
};
-int register_die_notifier(struct notifier_block *nb);
+extern int register_die_notifier(struct notifier_block *);
+extern int unregister_die_notifier(struct notifier_block *);
extern struct notifier_block *ia64die_chain;
enum die_val {
DIE_BREAK = 1,
- DIE_SS,
+ DIE_FAULT,
+ DIE_OOPS,
DIE_PAGE_FAULT,
+ DIE_MACHINE_HALT,
+ DIE_MACHINE_RESTART,
+ DIE_MCA_MONARCH_ENTER,
+ DIE_MCA_MONARCH_PROCESS,
+ DIE_MCA_MONARCH_LEAVE,
+ DIE_MCA_SLAVE_ENTER,
+ DIE_MCA_SLAVE_PROCESS,
+ DIE_MCA_SLAVE_LEAVE,
+ DIE_MCA_RENDZVOUS_ENTER,
+ DIE_MCA_RENDZVOUS_PROCESS,
+ DIE_MCA_RENDZVOUS_LEAVE,
+ DIE_INIT_MONARCH_ENTER,
+ DIE_INIT_MONARCH_PROCESS,
+ DIE_INIT_MONARCH_LEAVE,
+ DIE_INIT_SLAVE_ENTER,
+ DIE_INIT_SLAVE_PROCESS,
+ DIE_INIT_SLAVE_LEAVE,
+ DIE_KDEBUG_ENTER,
+ DIE_KDEBUG_LEAVE,
+ DIE_KDUMP_ENTER,
+ DIE_KDUMP_LEAVE,
};
static inline int notify_die(enum die_val val, char *str, struct pt_regs *regs,
diff --git a/include/asm-ia64/kprobes.h b/include/asm-ia64/kprobes.h
index 573a3574a24f..592abb000e29 100644
--- a/include/asm-ia64/kprobes.h
+++ b/include/asm-ia64/kprobes.h
@@ -26,6 +26,7 @@
*/
#include <linux/types.h>
#include <linux/ptrace.h>
+#include <linux/percpu.h>
#include <asm/break.h>
#define MAX_INSN_SIZE 16
@@ -62,6 +63,18 @@ typedef struct _bundle {
} quad1;
} __attribute__((__aligned__(16))) bundle_t;
+struct prev_kprobe {
+ struct kprobe *kp;
+ unsigned long status;
+};
+
+/* per-cpu kprobe control block */
+struct kprobe_ctlblk {
+ unsigned long kprobe_status;
+ struct pt_regs jprobe_saved_regs;
+ struct prev_kprobe prev_kprobe;
+};
+
#define JPROBE_ENTRY(pentry) (kprobe_opcode_t *)pentry
#define ARCH_SUPPORTS_KRETPROBES
diff --git a/include/asm-ia64/machvec.h b/include/asm-ia64/machvec.h
index 79e89a7db566..ca5ea994d688 100644
--- a/include/asm-ia64/machvec.h
+++ b/include/asm-ia64/machvec.h
@@ -26,7 +26,7 @@ typedef void ia64_mv_cpu_init_t (void);
typedef void ia64_mv_irq_init_t (void);
typedef void ia64_mv_send_ipi_t (int, int, int, int);
typedef void ia64_mv_timer_interrupt_t (int, void *, struct pt_regs *);
-typedef void ia64_mv_global_tlb_purge_t (unsigned long, unsigned long, unsigned long);
+typedef void ia64_mv_global_tlb_purge_t (struct mm_struct *, unsigned long, unsigned long, unsigned long);
typedef void ia64_mv_tlb_migrate_finish_t (struct mm_struct *);
typedef unsigned int ia64_mv_local_vector_to_irq (u8);
typedef char *ia64_mv_pci_get_legacy_mem_t (struct pci_bus *);
@@ -37,7 +37,7 @@ typedef int ia64_mv_pci_legacy_write_t (struct pci_bus *, u16 port, u32 val,
/* DMA-mapping interface: */
typedef void ia64_mv_dma_init (void);
-typedef void *ia64_mv_dma_alloc_coherent (struct device *, size_t, dma_addr_t *, int);
+typedef void *ia64_mv_dma_alloc_coherent (struct device *, size_t, dma_addr_t *, gfp_t);
typedef void ia64_mv_dma_free_coherent (struct device *, size_t, void *, dma_addr_t);
typedef dma_addr_t ia64_mv_dma_map_single (struct device *, void *, size_t, int);
typedef void ia64_mv_dma_unmap_single (struct device *, dma_addr_t, size_t, int);
diff --git a/include/asm-ia64/machvec_hpzx1.h b/include/asm-ia64/machvec_hpzx1.h
index daafe504c5f4..e90daf9ce340 100644
--- a/include/asm-ia64/machvec_hpzx1.h
+++ b/include/asm-ia64/machvec_hpzx1.h
@@ -1,8 +1,7 @@
#ifndef _ASM_IA64_MACHVEC_HPZX1_h
#define _ASM_IA64_MACHVEC_HPZX1_h
-extern ia64_mv_setup_t dig_setup;
-extern ia64_mv_setup_t sba_setup;
+extern ia64_mv_setup_t dig_setup;
extern ia64_mv_dma_alloc_coherent sba_alloc_coherent;
extern ia64_mv_dma_free_coherent sba_free_coherent;
extern ia64_mv_dma_map_single sba_map_single;
@@ -19,15 +18,15 @@ extern ia64_mv_dma_mapping_error sba_dma_mapping_error;
* platform's machvec structure. When compiling a non-generic kernel,
* the macros are used directly.
*/
-#define platform_name "hpzx1"
-#define platform_setup sba_setup
-#define platform_dma_init machvec_noop
-#define platform_dma_alloc_coherent sba_alloc_coherent
-#define platform_dma_free_coherent sba_free_coherent
-#define platform_dma_map_single sba_map_single
-#define platform_dma_unmap_single sba_unmap_single
-#define platform_dma_map_sg sba_map_sg
-#define platform_dma_unmap_sg sba_unmap_sg
+#define platform_name "hpzx1"
+#define platform_setup dig_setup
+#define platform_dma_init machvec_noop
+#define platform_dma_alloc_coherent sba_alloc_coherent
+#define platform_dma_free_coherent sba_free_coherent
+#define platform_dma_map_single sba_map_single
+#define platform_dma_unmap_single sba_unmap_single
+#define platform_dma_map_sg sba_map_sg
+#define platform_dma_unmap_sg sba_unmap_sg
#define platform_dma_sync_single_for_cpu machvec_dma_sync_single
#define platform_dma_sync_sg_for_cpu machvec_dma_sync_sg
#define platform_dma_sync_single_for_device machvec_dma_sync_single
diff --git a/include/asm-ia64/machvec_hpzx1_swiotlb.h b/include/asm-ia64/machvec_hpzx1_swiotlb.h
index 9924b1b00a6c..f00a34a148ff 100644
--- a/include/asm-ia64/machvec_hpzx1_swiotlb.h
+++ b/include/asm-ia64/machvec_hpzx1_swiotlb.h
@@ -2,7 +2,6 @@
#define _ASM_IA64_MACHVEC_HPZX1_SWIOTLB_h
extern ia64_mv_setup_t dig_setup;
-extern ia64_mv_dma_init hwsw_init;
extern ia64_mv_dma_alloc_coherent hwsw_alloc_coherent;
extern ia64_mv_dma_free_coherent hwsw_free_coherent;
extern ia64_mv_dma_map_single hwsw_map_single;
@@ -26,7 +25,7 @@ extern ia64_mv_dma_sync_sg_for_device hwsw_sync_sg_for_device;
#define platform_name "hpzx1_swiotlb"
#define platform_setup dig_setup
-#define platform_dma_init hwsw_init
+#define platform_dma_init machvec_noop
#define platform_dma_alloc_coherent hwsw_alloc_coherent
#define platform_dma_free_coherent hwsw_free_coherent
#define platform_dma_map_single hwsw_map_single
diff --git a/include/asm-ia64/meminit.h b/include/asm-ia64/meminit.h
index 1590dc65b30b..46501b01a5c5 100644
--- a/include/asm-ia64/meminit.h
+++ b/include/asm-ia64/meminit.h
@@ -16,10 +16,11 @@
* - initrd (optional)
* - command line string
* - kernel code & data
+ * - Kernel memory map built from EFI memory map
*
* More could be added if necessary
*/
-#define IA64_MAX_RSVD_REGIONS 5
+#define IA64_MAX_RSVD_REGIONS 6
struct rsvd_region {
unsigned long start; /* virtual address of beginning of element */
@@ -33,6 +34,7 @@ extern void find_memory (void);
extern void reserve_memory (void);
extern void find_initrd (void);
extern int filter_rsvd_memory (unsigned long start, unsigned long end, void *arg);
+extern void efi_memmap_init(unsigned long *, unsigned long *);
/*
* For rounding an address to the next IA64_GRANULE_SIZE or order
@@ -41,7 +43,7 @@ extern int filter_rsvd_memory (unsigned long start, unsigned long end, void *arg
#define GRANULEROUNDUP(n) (((n)+IA64_GRANULE_SIZE-1) & ~(IA64_GRANULE_SIZE-1))
#define ORDERROUNDDOWN(n) ((n) & ~((PAGE_SIZE<<MAX_ORDER)-1))
-#ifdef CONFIG_DISCONTIGMEM
+#ifdef CONFIG_NUMA
extern void call_pernode_memory (unsigned long start, unsigned long len, void *func);
#else
# define call_pernode_memory(start, len, func) (*func)(start, len, 0)
diff --git a/include/asm-ia64/mmu_context.h b/include/asm-ia64/mmu_context.h
index 8d6e72f7b08e..b5c65081a3aa 100644
--- a/include/asm-ia64/mmu_context.h
+++ b/include/asm-ia64/mmu_context.h
@@ -7,12 +7,13 @@
*/
/*
- * Routines to manage the allocation of task context numbers. Task context numbers are
- * used to reduce or eliminate the need to perform TLB flushes due to context switches.
- * Context numbers are implemented using ia-64 region ids. Since the IA-64 TLB does not
- * consider the region number when performing a TLB lookup, we need to assign a unique
- * region id to each region in a process. We use the least significant three bits in a
- * region id for this purpose.
+ * Routines to manage the allocation of task context numbers. Task context
+ * numbers are used to reduce or eliminate the need to perform TLB flushes
+ * due to context switches. Context numbers are implemented using ia-64
+ * region ids. Since the IA-64 TLB does not consider the region number when
+ * performing a TLB lookup, we need to assign a unique region id to each
+ * region in a process. We use the least significant three bits in aregion
+ * id for this purpose.
*/
#define IA64_REGION_ID_KERNEL 0 /* the kernel's region id (tlb.c depends on this being 0) */
@@ -32,13 +33,17 @@
struct ia64_ctx {
spinlock_t lock;
unsigned int next; /* next context number to use */
- unsigned int limit; /* next >= limit => must call wrap_mmu_context() */
- unsigned int max_ctx; /* max. context value supported by all CPUs */
+ unsigned int limit; /* available free range */
+ unsigned int max_ctx; /* max. context value supported by all CPUs */
+ /* call wrap_mmu_context when next >= max */
+ unsigned long *bitmap; /* bitmap size is max_ctx+1 */
+ unsigned long *flushmap;/* pending rid to be flushed */
};
extern struct ia64_ctx ia64_ctx;
DECLARE_PER_CPU(u8, ia64_need_tlb_flush);
+extern void mmu_context_init (void);
extern void wrap_mmu_context (struct mm_struct *mm);
static inline void
@@ -47,10 +52,10 @@ enter_lazy_tlb (struct mm_struct *mm, struct task_struct *tsk)
}
/*
- * When the context counter wraps around all TLBs need to be flushed because an old
- * context number might have been reused. This is signalled by the ia64_need_tlb_flush
- * per-CPU variable, which is checked in the routine below. Called by activate_mm().
- * <efocht@ess.nec.de>
+ * When the context counter wraps around all TLBs need to be flushed because
+ * an old context number might have been reused. This is signalled by the
+ * ia64_need_tlb_flush per-CPU variable, which is checked in the routine
+ * below. Called by activate_mm(). <efocht@ess.nec.de>
*/
static inline void
delayed_tlb_flush (void)
@@ -60,11 +65,9 @@ delayed_tlb_flush (void)
if (unlikely(__ia64_per_cpu_var(ia64_need_tlb_flush))) {
spin_lock_irqsave(&ia64_ctx.lock, flags);
- {
- if (__ia64_per_cpu_var(ia64_need_tlb_flush)) {
- local_flush_tlb_all();
- __ia64_per_cpu_var(ia64_need_tlb_flush) = 0;
- }
+ if (__ia64_per_cpu_var(ia64_need_tlb_flush)) {
+ local_flush_tlb_all();
+ __ia64_per_cpu_var(ia64_need_tlb_flush) = 0;
}
spin_unlock_irqrestore(&ia64_ctx.lock, flags);
}
@@ -76,20 +79,27 @@ get_mmu_context (struct mm_struct *mm)
unsigned long flags;
nv_mm_context_t context = mm->context;
- if (unlikely(!context)) {
- spin_lock_irqsave(&ia64_ctx.lock, flags);
- {
- /* re-check, now that we've got the lock: */
- context = mm->context;
- if (context == 0) {
- cpus_clear(mm->cpu_vm_mask);
- if (ia64_ctx.next >= ia64_ctx.limit)
- wrap_mmu_context(mm);
- mm->context = context = ia64_ctx.next++;
- }
+ if (likely(context))
+ goto out;
+
+ spin_lock_irqsave(&ia64_ctx.lock, flags);
+ /* re-check, now that we've got the lock: */
+ context = mm->context;
+ if (context == 0) {
+ cpus_clear(mm->cpu_vm_mask);
+ if (ia64_ctx.next >= ia64_ctx.limit) {
+ ia64_ctx.next = find_next_zero_bit(ia64_ctx.bitmap,
+ ia64_ctx.max_ctx, ia64_ctx.next);
+ ia64_ctx.limit = find_next_bit(ia64_ctx.bitmap,
+ ia64_ctx.max_ctx, ia64_ctx.next);
+ if (ia64_ctx.next >= ia64_ctx.max_ctx)
+ wrap_mmu_context(mm);
}
- spin_unlock_irqrestore(&ia64_ctx.lock, flags);
+ mm->context = context = ia64_ctx.next++;
+ __set_bit(context, ia64_ctx.bitmap);
}
+ spin_unlock_irqrestore(&ia64_ctx.lock, flags);
+out:
/*
* Ensure we're not starting to use "context" before any old
* uses of it are gone from our TLB.
@@ -100,8 +110,8 @@ get_mmu_context (struct mm_struct *mm)
}
/*
- * Initialize context number to some sane value. MM is guaranteed to be a brand-new
- * address-space, so no TLB flushing is needed, ever.
+ * Initialize context number to some sane value. MM is guaranteed to be a
+ * brand-new address-space, so no TLB flushing is needed, ever.
*/
static inline int
init_new_context (struct task_struct *p, struct mm_struct *mm)
@@ -162,7 +172,10 @@ activate_context (struct mm_struct *mm)
if (!cpu_isset(smp_processor_id(), mm->cpu_vm_mask))
cpu_set(smp_processor_id(), mm->cpu_vm_mask);
reload_context(context);
- /* in the unlikely event of a TLB-flush by another thread, redo the load: */
+ /*
+ * in the unlikely event of a TLB-flush by another thread,
+ * redo the load.
+ */
} while (unlikely(context != mm->context));
}
@@ -175,8 +188,8 @@ static inline void
activate_mm (struct mm_struct *prev, struct mm_struct *next)
{
/*
- * We may get interrupts here, but that's OK because interrupt handlers cannot
- * touch user-space.
+ * We may get interrupts here, but that's OK because interrupt
+ * handlers cannot touch user-space.
*/
ia64_set_kr(IA64_KR_PT_BASE, __pa(next->pgd));
activate_context(next);
diff --git a/include/asm-ia64/mmzone.h b/include/asm-ia64/mmzone.h
index d32f51e3d6c2..34efe88eb849 100644
--- a/include/asm-ia64/mmzone.h
+++ b/include/asm-ia64/mmzone.h
@@ -15,7 +15,7 @@
#include <asm/page.h>
#include <asm/meminit.h>
-#ifdef CONFIG_DISCONTIGMEM
+#ifdef CONFIG_NUMA
static inline int pfn_to_nid(unsigned long pfn)
{
@@ -31,6 +31,10 @@ static inline int pfn_to_nid(unsigned long pfn)
#endif
}
+#ifdef CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID
+extern int early_pfn_to_nid(unsigned long pfn);
+#endif
+
#ifdef CONFIG_IA64_DIG /* DIG systems are small */
# define MAX_PHYSNODE_ID 8
# define NR_NODE_MEMBLKS (MAX_NUMNODES * 8)
@@ -39,8 +43,8 @@ static inline int pfn_to_nid(unsigned long pfn)
# define NR_NODE_MEMBLKS (MAX_NUMNODES * 4)
#endif
-#else /* CONFIG_DISCONTIGMEM */
+#else /* CONFIG_NUMA */
# define NR_NODE_MEMBLKS (MAX_NUMNODES * 4)
-#endif /* CONFIG_DISCONTIGMEM */
+#endif /* CONFIG_NUMA */
#endif /* _ASM_IA64_MMZONE_H */
diff --git a/include/asm-ia64/msi.h b/include/asm-ia64/msi.h
index 60f2137f9278..97890f7762b3 100644
--- a/include/asm-ia64/msi.h
+++ b/include/asm-ia64/msi.h
@@ -12,9 +12,6 @@
static inline void set_intr_gate (int nr, void *func) {}
#define IO_APIC_VECTOR(irq) (irq)
#define ack_APIC_irq ia64_eoi
-#define cpu_mask_to_apicid(mask) cpu_physical_id(first_cpu(mask))
-#define MSI_DEST_MODE MSI_PHYSICAL_MODE
-#define MSI_TARGET_CPU ((ia64_getreg(_IA64_REG_CR_LID) >> 16) & 0xffff)
#define MSI_TARGET_CPU_SHIFT 4
#endif /* ASM_MSI_H */
diff --git a/include/asm-ia64/nodedata.h b/include/asm-ia64/nodedata.h
index 6b0f3ed89b7e..9978c7ce7549 100644
--- a/include/asm-ia64/nodedata.h
+++ b/include/asm-ia64/nodedata.h
@@ -17,7 +17,7 @@
#include <asm/percpu.h>
#include <asm/mmzone.h>
-#ifdef CONFIG_DISCONTIGMEM
+#ifdef CONFIG_NUMA
/*
* Node Data. One of these structures is located on each node of a NUMA system.
@@ -47,6 +47,6 @@ struct ia64_node_data {
*/
#define NODE_DATA(nid) (local_node_data->pg_data_ptrs[nid])
-#endif /* CONFIG_DISCONTIGMEM */
+#endif /* CONFIG_NUMA */
#endif /* _ASM_IA64_NODEDATA_H */
diff --git a/include/asm-ia64/page.h b/include/asm-ia64/page.h
index 9edffad8c28b..9d41548b7fef 100644
--- a/include/asm-ia64/page.h
+++ b/include/asm-ia64/page.h
@@ -102,15 +102,15 @@ do { \
#ifdef CONFIG_VIRTUAL_MEM_MAP
extern int ia64_pfn_valid (unsigned long pfn);
-#else
+#elif defined(CONFIG_FLATMEM)
# define ia64_pfn_valid(pfn) 1
#endif
-#ifndef CONFIG_DISCONTIGMEM
+#ifdef CONFIG_FLATMEM
# define pfn_valid(pfn) (((pfn) < max_mapnr) && ia64_pfn_valid(pfn))
# define page_to_pfn(page) ((unsigned long) (page - mem_map))
# define pfn_to_page(pfn) (mem_map + (pfn))
-#else
+#elif defined(CONFIG_DISCONTIGMEM)
extern struct page *vmem_map;
extern unsigned long max_low_pfn;
# define pfn_valid(pfn) (((pfn) < max_low_pfn) && ia64_pfn_valid(pfn))
@@ -120,6 +120,7 @@ extern unsigned long max_low_pfn;
#define page_to_phys(page) (page_to_pfn(page) << PAGE_SHIFT)
#define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)
+#define pfn_to_kaddr(pfn) __va((pfn) << PAGE_SHIFT)
typedef union ia64_va {
struct {
diff --git a/include/asm-ia64/pgtable.h b/include/asm-ia64/pgtable.h
index 3339c7b55a6f..c34ba80c1c31 100644
--- a/include/asm-ia64/pgtable.h
+++ b/include/asm-ia64/pgtable.h
@@ -127,6 +127,7 @@
# ifndef __ASSEMBLY__
+#include <linux/sched.h> /* for mm_struct */
#include <asm/bitops.h>
#include <asm/cacheflush.h>
#include <asm/mmu_context.h>
@@ -236,9 +237,6 @@ ia64_phys_addr_valid (unsigned long addr)
#define pte_modify(_pte, newprot) \
(__pte((pte_val(_pte) & ~_PAGE_CHG_MASK) | (pgprot_val(newprot) & _PAGE_CHG_MASK)))
-#define page_pte_prot(page,prot) mk_pte(page, prot)
-#define page_pte(page) page_pte_prot(page, __pgprot(0))
-
#define pte_none(pte) (!pte_val(pte))
#define pte_present(pte) (pte_val(pte) & (_PAGE_P | _PAGE_PROTNONE))
#define pte_clear(mm,addr,pte) (pte_val(*(pte)) = 0UL)
diff --git a/include/asm-ia64/ptrace.h b/include/asm-ia64/ptrace.h
index a79d1a7ecc77..2c703d6e0c86 100644
--- a/include/asm-ia64/ptrace.h
+++ b/include/asm-ia64/ptrace.h
@@ -229,6 +229,9 @@ struct switch_stack {
};
#ifdef __KERNEL__
+
+#define __ARCH_SYS_PTRACE 1
+
/*
* We use the ia64_psr(regs)->ri to determine which of the three
* instructions in bundle (16 bytes) took the sample. Generate
diff --git a/include/asm-ia64/rwsem.h b/include/asm-ia64/rwsem.h
index e18b5ab0cb75..1327c91ea39c 100644
--- a/include/asm-ia64/rwsem.h
+++ b/include/asm-ia64/rwsem.h
@@ -186,4 +186,9 @@ __downgrade_write (struct rw_semaphore *sem)
#define rwsem_atomic_add(delta, sem) atomic64_add(delta, (atomic64_t *)(&(sem)->count))
#define rwsem_atomic_update(delta, sem) atomic64_add_return(delta, (atomic64_t *)(&(sem)->count))
+static inline int rwsem_is_locked(struct rw_semaphore *sem)
+{
+ return (sem->count != 0);
+}
+
#endif /* _ASM_IA64_RWSEM_H */
diff --git a/include/asm-ia64/semaphore.h b/include/asm-ia64/semaphore.h
index 3a2f0f3f78f3..bb8906285fab 100644
--- a/include/asm-ia64/semaphore.h
+++ b/include/asm-ia64/semaphore.h
@@ -24,8 +24,6 @@ struct semaphore {
.wait = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \
}
-#define __MUTEX_INITIALIZER(name) __SEMAPHORE_INITIALIZER(name,1)
-
#define __DECLARE_SEMAPHORE_GENERIC(name,count) \
struct semaphore name = __SEMAPHORE_INITIALIZER(name, count)
diff --git a/include/asm-ia64/sn/arch.h b/include/asm-ia64/sn/arch.h
index ab827d298569..1a3831c04af6 100644
--- a/include/asm-ia64/sn/arch.h
+++ b/include/asm-ia64/sn/arch.h
@@ -18,6 +18,32 @@
#include <asm/sn/sn_cpuid.h>
/*
+ * This is the maximum number of NUMALINK nodes that can be part of a single
+ * SSI kernel. This number includes C-brick, M-bricks, and TIOs. Nodes in
+ * remote partitions are NOT included in this number.
+ * The number of compact nodes cannot exceed size of a coherency domain.
+ * The purpose of this define is to specify a node count that includes
+ * all C/M/TIO nodes in an SSI system.
+ *
+ * SGI system can currently support up to 256 C/M nodes plus additional TIO nodes.
+ *
+ * Note: ACPI20 has an architectural limit of 256 nodes. When we upgrade
+ * to ACPI3.0, this limit will be removed. The notion of "compact nodes"
+ * should be deleted and TIOs should be included in MAX_NUMNODES.
+ */
+#define MAX_COMPACT_NODES 512
+
+/*
+ * Maximum number of nodes in all partitions and in all coherency domains.
+ * This is the total number of nodes accessible in the numalink fabric. It
+ * includes all C & M bricks, plus all TIOs.
+ *
+ * This value is also the value of the maximum number of NASIDs in the numalink
+ * fabric.
+ */
+#define MAX_NUMALINK_NODES 16384
+
+/*
* The following defines attributes of the HUB chip. These attributes are
* frequently referenced. They are kept in the per-cpu data areas of each cpu.
* They are kept together in a struct to minimize cache misses.
@@ -41,15 +67,6 @@ DECLARE_PER_CPU(struct sn_hub_info_s, __sn_hub_info);
/*
- * This is the maximum number of nodes that can be part of a kernel.
- * Effectively, it's the maximum number of compact node ids (cnodeid_t).
- * This is not necessarily the same as MAX_NASIDS.
- */
-#define MAX_COMPACT_NODES 2048
-#define CPUS_PER_NODE 4
-
-
-/*
* Compact node ID to nasid mappings kept in the per-cpu data areas of each
* cpu.
*/
@@ -57,7 +74,6 @@ DECLARE_PER_CPU(short, __sn_cnodeid_to_nasid[MAX_NUMNODES]);
#define sn_cnodeid_to_nasid (&__get_cpu_var(__sn_cnodeid_to_nasid[0]))
-
extern u8 sn_partition_id;
extern u8 sn_system_size;
extern u8 sn_sharing_domain_size;
diff --git a/include/asm-ia64/sn/io.h b/include/asm-ia64/sn/io.h
index 42209733f6b1..41c73a735628 100644
--- a/include/asm-ia64/sn/io.h
+++ b/include/asm-ia64/sn/io.h
@@ -14,7 +14,7 @@
extern void * sn_io_addr(unsigned long port) __attribute_const__; /* Forward definition */
extern void __sn_mmiowb(void); /* Forward definition */
-extern int numionodes;
+extern int num_cnodes;
#define __sn_mf_a() ia64_mfa()
@@ -36,6 +36,15 @@ extern void sn_dma_flush(unsigned long);
#define __sn_readq_relaxed ___sn_readq_relaxed
/*
+ * Convenience macros for setting/clearing bits using the above accessors
+ */
+
+#define __sn_setq_relaxed(addr, val) \
+ writeq((__sn_readq_relaxed(addr) | (val)), (addr))
+#define __sn_clrq_relaxed(addr, val) \
+ writeq((__sn_readq_relaxed(addr) & ~(val)), (addr))
+
+/*
* The following routines are SN Platform specific, called when
* a reference is made to inX/outX set macros. SN Platform
* inX set of macros ensures that Posted DMA writes on the
diff --git a/include/asm-ia64/sn/klconfig.h b/include/asm-ia64/sn/klconfig.h
index 9f920c70a62a..bcbf209d63be 100644
--- a/include/asm-ia64/sn/klconfig.h
+++ b/include/asm-ia64/sn/klconfig.h
@@ -208,19 +208,6 @@ typedef struct lboard_s {
klconf_off_t brd_next_same; /* Next BOARD with same nasid */
} lboard_t;
-#define KLCF_NUM_COMPS(_brd) ((_brd)->brd_numcompts)
-#define NODE_OFFSET_TO_KLINFO(n,off) ((klinfo_t*) TO_NODE_CAC(n,off))
-#define KLCF_NEXT(_brd) \
- ((_brd)->brd_next_same ? \
- (NODE_OFFSET_TO_LBOARD((_brd)->brd_next_same_host, (_brd)->brd_next_same)): NULL)
-#define KLCF_NEXT_ANY(_brd) \
- ((_brd)->brd_next_any ? \
- (NODE_OFFSET_TO_LBOARD(NASID_GET(_brd), (_brd)->brd_next_any)): NULL)
-#define KLCF_COMP(_brd, _ndx) \
- ((((_brd)->brd_compts[(_ndx)]) == 0) ? 0 : \
- (NODE_OFFSET_TO_KLINFO(NASID_GET(_brd), (_brd)->brd_compts[(_ndx)])))
-
-
/*
* Generic info structure. This stores common info about a
* component.
@@ -249,24 +236,11 @@ typedef struct klinfo_s { /* Generic info */
} klinfo_t ;
-static inline lboard_t *find_lboard_any(lboard_t * start, unsigned char brd_type)
+static inline lboard_t *find_lboard_next(lboard_t * brd)
{
- /* Search all boards stored on this node. */
-
- while (start) {
- if (start->brd_type == brd_type)
- return start;
- start = KLCF_NEXT_ANY(start);
- }
- /* Didn't find it. */
- return (lboard_t *) NULL;
+ if (brd && brd->brd_next_any)
+ return NODE_OFFSET_TO_LBOARD(NASID_GET(brd), brd->brd_next_any);
+ return NULL;
}
-
-/* external declarations of Linux kernel functions. */
-
-extern lboard_t *root_lboard[];
-extern klinfo_t *find_component(lboard_t *brd, klinfo_t *kli, unsigned char type);
-extern klinfo_t *find_first_component(lboard_t *brd, unsigned char type);
-
#endif /* _ASM_IA64_SN_KLCONFIG_H */
diff --git a/include/asm-ia64/sn/l1.h b/include/asm-ia64/sn/l1.h
index 2e5f0aa38889..e3b819110d47 100644
--- a/include/asm-ia64/sn/l1.h
+++ b/include/asm-ia64/sn/l1.h
@@ -35,4 +35,16 @@
#define L1_BRICKTYPE_ATHENA 0x2b /* + */
#define L1_BRICKTYPE_DAYTONA 0x7a /* z */
+/* board type response codes */
+#define L1_BOARDTYPE_IP69 0x0100 /* CA */
+#define L1_BOARDTYPE_IP63 0x0200 /* CB */
+#define L1_BOARDTYPE_BASEIO 0x0300 /* IB */
+#define L1_BOARDTYPE_PCIE2SLOT 0x0400 /* IC */
+#define L1_BOARDTYPE_PCIX3SLOT 0x0500 /* ID */
+#define L1_BOARDTYPE_PCIXPCIE4SLOT 0x0600 /* IE */
+#define L1_BOARDTYPE_ABACUS 0x0700 /* AB */
+#define L1_BOARDTYPE_DAYTONA 0x0800 /* AD */
+#define L1_BOARDTYPE_INVAL (-1) /* invalid brick type */
+
+
#endif /* _ASM_IA64_SN_L1_H */
diff --git a/include/asm-ia64/sn/nodepda.h b/include/asm-ia64/sn/nodepda.h
index 47bb8100fd00..6f6d69e39ff5 100644
--- a/include/asm-ia64/sn/nodepda.h
+++ b/include/asm-ia64/sn/nodepda.h
@@ -55,7 +55,6 @@ struct nodepda_s {
*/
struct phys_cpuid phys_cpuid[NR_CPUS];
spinlock_t ptc_lock ____cacheline_aligned_in_smp;
- spinlock_t bist_lock;
};
typedef struct nodepda_s nodepda_t;
diff --git a/include/asm-ia64/sn/sn_cpuid.h b/include/asm-ia64/sn/sn_cpuid.h
index d2c1d34dcce4..749deb2ca6c1 100644
--- a/include/asm-ia64/sn/sn_cpuid.h
+++ b/include/asm-ia64/sn/sn_cpuid.h
@@ -105,7 +105,6 @@ extern short physical_node_map[]; /* indexed by nasid to get cnode */
#define cpuid_to_nasid(cpuid) (sn_nodepda->phys_cpuid[cpuid].nasid)
#define cpuid_to_subnode(cpuid) (sn_nodepda->phys_cpuid[cpuid].subnode)
#define cpuid_to_slice(cpuid) (sn_nodepda->phys_cpuid[cpuid].slice)
-#define cpuid_to_cnodeid(cpuid) (physical_node_map[cpuid_to_nasid(cpuid)])
/*
@@ -113,8 +112,6 @@ extern short physical_node_map[]; /* indexed by nasid to get cnode */
* of potentially large tables.
*/
extern int nasid_slice_to_cpuid(int, int);
-#define nasid_slice_to_cpu_physical_id(nasid, slice) \
- cpu_physical_id(nasid_slice_to_cpuid(nasid, slice))
/*
* cnodeid_to_nasid - convert a cnodeid to a NASID
diff --git a/include/asm-ia64/sn/sn_sal.h b/include/asm-ia64/sn/sn_sal.h
index fea35b33d4e4..3f7564dc0aa9 100644
--- a/include/asm-ia64/sn/sn_sal.h
+++ b/include/asm-ia64/sn/sn_sal.h
@@ -47,6 +47,7 @@
#define SN_SAL_CONSOLE_PUTB 0x02000028
#define SN_SAL_CONSOLE_XMIT_CHARS 0x0200002a
#define SN_SAL_CONSOLE_READC 0x0200002b
+#define SN_SAL_SYSCTL_OP 0x02000030
#define SN_SAL_SYSCTL_MODID_GET 0x02000031
#define SN_SAL_SYSCTL_GET 0x02000032
#define SN_SAL_SYSCTL_IOBRICK_MODULE_GET 0x02000033
@@ -67,7 +68,7 @@
#define SN_SAL_IOIF_INTERRUPT 0x0200004a
#define SN_SAL_HWPERF_OP 0x02000050 // lock
#define SN_SAL_IOIF_ERROR_INTERRUPT 0x02000051
-
+#define SN_SAL_IOIF_PCI_SAFE 0x02000052
#define SN_SAL_IOIF_SLOT_ENABLE 0x02000053
#define SN_SAL_IOIF_SLOT_DISABLE 0x02000054
#define SN_SAL_IOIF_GET_HUBDEV_INFO 0x02000055
@@ -101,6 +102,13 @@
#define SAL_INTR_FREE 2
/*
+ * operations available on the generic SN_SAL_SYSCTL_OP
+ * runtime service
+ */
+#define SAL_SYSCTL_OP_IOBOARD 0x0001 /* retrieve board type */
+#define SAL_SYSCTL_OP_TIO_JLCK_RST 0x0002 /* issue TIO clock reset */
+
+/*
* IRouter (i.e. generalized system controller) operations
*/
#define SAL_IROUTER_OPEN 0 /* open a subchannel */
@@ -198,26 +206,16 @@ ia64_sn_get_master_baseio_nasid(void)
return ret_stuff.v0;
}
-static inline char *
+static inline void *
ia64_sn_get_klconfig_addr(nasid_t nasid)
{
struct ia64_sal_retval ret_stuff;
- int cnodeid;
- cnodeid = nasid_to_cnodeid(nasid);
ret_stuff.status = 0;
ret_stuff.v0 = 0;
ret_stuff.v1 = 0;
ret_stuff.v2 = 0;
SAL_CALL(ret_stuff, SN_SAL_GET_KLCONFIG_ADDR, (u64)nasid, 0, 0, 0, 0, 0, 0);
-
- /*
- * We should panic if a valid cnode nasid does not produce
- * a klconfig address.
- */
- if (ret_stuff.status != 0) {
- panic("ia64_sn_get_klconfig_addr: Returned error %lx\n", ret_stuff.status);
- }
return ret_stuff.v0 ? __va(ret_stuff.v0) : NULL;
}
@@ -694,12 +692,10 @@ sn_change_memprotect(u64 paddr, u64 len, u64 perms, u64 *nasid_array)
unsigned long irq_flags;
cnodeid = nasid_to_cnodeid(get_node_number(paddr));
- // spin_lock(&NODEPDA(cnodeid)->bist_lock);
local_irq_save(irq_flags);
ia64_sal_oemcall_nolock(&ret_stuff, SN_SAL_MEMPROTECT, paddr, len,
(u64)nasid_array, perms, 0, 0, 0);
local_irq_restore(irq_flags);
- // spin_unlock(&NODEPDA(cnodeid)->bist_lock);
return ret_stuff.status;
}
#define SN_MEMPROT_ACCESS_CLASS_0 0x14a080
@@ -873,6 +869,41 @@ ia64_sn_sysctl_event_init(nasid_t nasid)
return (int) rv.v0;
}
+/*
+ * Ask the system controller on the specified nasid to reset
+ * the CX corelet clock. Only valid on TIO nodes.
+ */
+static inline int
+ia64_sn_sysctl_tio_clock_reset(nasid_t nasid)
+{
+ struct ia64_sal_retval rv;
+ SAL_CALL_REENTRANT(rv, SN_SAL_SYSCTL_OP, SAL_SYSCTL_OP_TIO_JLCK_RST,
+ nasid, 0, 0, 0, 0, 0);
+ if (rv.status != 0)
+ return (int)rv.status;
+ if (rv.v0 != 0)
+ return (int)rv.v0;
+
+ return 0;
+}
+
+/*
+ * Get the associated ioboard type for a given nasid.
+ */
+static inline int
+ia64_sn_sysctl_ioboard_get(nasid_t nasid)
+{
+ struct ia64_sal_retval rv;
+ SAL_CALL_REENTRANT(rv, SN_SAL_SYSCTL_OP, SAL_SYSCTL_OP_IOBOARD,
+ nasid, 0, 0, 0, 0, 0);
+ if (rv.v0 != 0)
+ return (int)rv.v0;
+ if (rv.v1 != 0)
+ return (int)rv.v1;
+
+ return 0;
+}
+
/**
* ia64_sn_get_fit_compt - read a FIT entry from the PROM header
* @nasid: NASID of node to read
diff --git a/include/asm-ia64/sn/tioca_provider.h b/include/asm-ia64/sn/tioca_provider.h
index 5ccec608d325..b532ef6148ed 100644
--- a/include/asm-ia64/sn/tioca_provider.h
+++ b/include/asm-ia64/sn/tioca_provider.h
@@ -182,11 +182,11 @@ tioca_tlbflush(struct tioca_kernel *tioca_kernel)
* touch every CL aligned GART entry.
*/
- ca_base->ca_control2 &= ~(CA_GART_MEM_PARAM);
- ca_base->ca_control2 |= CA_GART_FLUSH_TLB;
- ca_base->ca_control2 |=
- (0x2ull << CA_GART_MEM_PARAM_SHFT);
- tmp = ca_base->ca_control2;
+ __sn_clrq_relaxed(&ca_base->ca_control2, CA_GART_MEM_PARAM);
+ __sn_setq_relaxed(&ca_base->ca_control2, CA_GART_FLUSH_TLB);
+ __sn_setq_relaxed(&ca_base->ca_control2,
+ (0x2ull << CA_GART_MEM_PARAM_SHFT));
+ tmp = __sn_readq_relaxed(&ca_base->ca_control2);
}
return;
@@ -196,8 +196,8 @@ tioca_tlbflush(struct tioca_kernel *tioca_kernel)
* Gart in uncached mode ... need an explicit flush.
*/
- ca_base->ca_control2 |= CA_GART_FLUSH_TLB;
- tmp = ca_base->ca_control2;
+ __sn_setq_relaxed(&ca_base->ca_control2, CA_GART_FLUSH_TLB);
+ tmp = __sn_readq_relaxed(&ca_base->ca_control2);
}
extern uint32_t tioca_gart_found;
diff --git a/include/asm-ia64/sn/tiocx.h b/include/asm-ia64/sn/tiocx.h
index c5447a504509..5699e75e5024 100644
--- a/include/asm-ia64/sn/tiocx.h
+++ b/include/asm-ia64/sn/tiocx.h
@@ -19,6 +19,7 @@ struct cx_id_s {
struct cx_dev {
struct cx_id_s cx_id;
+ int bt; /* board/blade type */
void *soft; /* driver specific */
struct hubdev_info *hubdev;
struct device dev;
@@ -59,7 +60,7 @@ struct cx_drv {
extern struct sn_irq_info *tiocx_irq_alloc(nasid_t, int, int, nasid_t, int);
extern void tiocx_irq_free(struct sn_irq_info *);
extern int cx_device_unregister(struct cx_dev *);
-extern int cx_device_register(nasid_t, int, int, struct hubdev_info *);
+extern int cx_device_register(nasid_t, int, int, struct hubdev_info *, int);
extern int cx_driver_unregister(struct cx_drv *);
extern int cx_driver_register(struct cx_drv *);
extern uint64_t tiocx_dma_addr(uint64_t addr);
diff --git a/include/asm-ia64/sn/xp.h b/include/asm-ia64/sn/xp.h
index 1df1c9f61a65..49faf8f26430 100644
--- a/include/asm-ia64/sn/xp.h
+++ b/include/asm-ia64/sn/xp.h
@@ -49,7 +49,7 @@
* C-brick nasids, thus the need for bitmaps which don't account for
* odd-numbered (non C-brick) nasids.
*/
-#define XP_MAX_PHYSNODE_ID (MAX_PHYSNODE_ID / 2)
+#define XP_MAX_PHYSNODE_ID (MAX_NUMALINK_NODES / 2)
#define XP_NASID_MASK_BYTES ((XP_MAX_PHYSNODE_ID + 7) / 8)
#define XP_NASID_MASK_WORDS ((XP_MAX_PHYSNODE_ID + 63) / 64)
@@ -217,7 +217,17 @@ enum xpc_retval {
xpcInvalidPartid, /* 42: invalid partition ID */
xpcLocalPartid, /* 43: local partition ID */
- xpcUnknownReason /* 44: unknown reason -- must be last in list */
+ xpcOtherGoingDown, /* 44: other side going down, reason unknown */
+ xpcSystemGoingDown, /* 45: system is going down, reason unknown */
+ xpcSystemHalt, /* 46: system is being halted */
+ xpcSystemReboot, /* 47: system is being rebooted */
+ xpcSystemPoweroff, /* 48: system is being powered off */
+
+ xpcDisconnecting, /* 49: channel disconnecting (closing) */
+
+ xpcOpenCloseError, /* 50: channel open/close protocol error */
+
+ xpcUnknownReason /* 51: unknown reason -- must be last in list */
};
@@ -342,7 +352,7 @@ typedef void (*xpc_notify_func)(enum xpc_retval reason, partid_t partid,
*
* The 'func' field points to the function to call when aynchronous
* notification is required for such events as: a connection established/lost,
- * or an incomming message received, or an error condition encountered. A
+ * or an incoming message received, or an error condition encountered. A
* non-NULL 'func' field indicates that there is an active registration for
* the channel.
*/
diff --git a/include/asm-ia64/sparsemem.h b/include/asm-ia64/sparsemem.h
new file mode 100644
index 000000000000..67a7c40ec27f
--- /dev/null
+++ b/include/asm-ia64/sparsemem.h
@@ -0,0 +1,20 @@
+#ifndef _ASM_IA64_SPARSEMEM_H
+#define _ASM_IA64_SPARSEMEM_H
+
+#ifdef CONFIG_SPARSEMEM
+/*
+ * SECTION_SIZE_BITS 2^N: how big each section will be
+ * MAX_PHYSMEM_BITS 2^N: how much memory we can have in that space
+ */
+
+#define SECTION_SIZE_BITS (30)
+#define MAX_PHYSMEM_BITS (50)
+#ifdef CONFIG_FORCE_MAX_ZONEORDER
+#if ((CONFIG_FORCE_MAX_ZONEORDER - 1 + PAGE_SHIFT) > SECTION_SIZE_BITS)
+#undef SECTION_SIZE_BITS
+#define SECTION_SIZE_BITS (CONFIG_FORCE_MAX_ZONEORDER - 1 + PAGE_SHIFT)
+#endif
+#endif
+
+#endif /* CONFIG_SPARSEMEM */
+#endif /* _ASM_IA64_SPARSEMEM_H */
diff --git a/include/asm-ia64/tlb.h b/include/asm-ia64/tlb.h
index 3a9a6d1be75c..834370b9dea1 100644
--- a/include/asm-ia64/tlb.h
+++ b/include/asm-ia64/tlb.h
@@ -60,7 +60,6 @@ struct mmu_gather {
unsigned int nr; /* == ~0U => fast mode */
unsigned char fullmm; /* non-zero means full mm flush */
unsigned char need_flush; /* really unmapped some PTEs? */
- unsigned long freed; /* number of pages freed */
unsigned long start_addr;
unsigned long end_addr;
struct page *pages[FREE_PTE_NR];
@@ -129,7 +128,7 @@ ia64_tlb_flush_mmu (struct mmu_gather *tlb, unsigned long start, unsigned long e
static inline struct mmu_gather *
tlb_gather_mmu (struct mm_struct *mm, unsigned int full_mm_flush)
{
- struct mmu_gather *tlb = &__get_cpu_var(mmu_gathers);
+ struct mmu_gather *tlb = &get_cpu_var(mmu_gathers);
tlb->mm = mm;
/*
@@ -147,25 +146,17 @@ tlb_gather_mmu (struct mm_struct *mm, unsigned int full_mm_flush)
*/
tlb->nr = (num_online_cpus() == 1) ? ~0U : 0;
tlb->fullmm = full_mm_flush;
- tlb->freed = 0;
tlb->start_addr = ~0UL;
return tlb;
}
/*
* Called at the end of the shootdown operation to free up any resources that were
- * collected. The page table lock is still held at this point.
+ * collected.
*/
static inline void
tlb_finish_mmu (struct mmu_gather *tlb, unsigned long start, unsigned long end)
{
- unsigned long freed = tlb->freed;
- struct mm_struct *mm = tlb->mm;
- unsigned long rss = get_mm_counter(mm, rss);
-
- if (rss < freed)
- freed = rss;
- add_mm_counter(mm, rss, -freed);
/*
* Note: tlb->nr may be 0 at this point, so we can't rely on tlb->start_addr and
* tlb->end_addr.
@@ -174,12 +165,8 @@ tlb_finish_mmu (struct mmu_gather *tlb, unsigned long start, unsigned long end)
/* keep the page table cache within bounds */
check_pgt_cache();
-}
-static inline unsigned int
-tlb_is_full_mm(struct mmu_gather *tlb)
-{
- return tlb->fullmm;
+ put_cpu_var(mmu_gathers);
}
/*
diff --git a/include/asm-ia64/tlbflush.h b/include/asm-ia64/tlbflush.h
index b65c62702724..a35b323bae4c 100644
--- a/include/asm-ia64/tlbflush.h
+++ b/include/asm-ia64/tlbflush.h
@@ -51,6 +51,7 @@ flush_tlb_mm (struct mm_struct *mm)
if (!mm)
return;
+ set_bit(mm->context, ia64_ctx.flushmap);
mm->context = 0;
if (atomic_read(&mm->mm_users) == 0)
diff --git a/include/asm-ia64/unistd.h b/include/asm-ia64/unistd.h
index 3a0c69524656..6d96a67439be 100644
--- a/include/asm-ia64/unistd.h
+++ b/include/asm-ia64/unistd.h
@@ -383,8 +383,6 @@ struct sigaction;
long sys_execve(char __user *filename, char __user * __user *argv,
char __user * __user *envp, struct pt_regs *regs);
asmlinkage long sys_pipe(void);
-asmlinkage long sys_ptrace(long request, pid_t pid,
- unsigned long addr, unsigned long data);
asmlinkage long sys_rt_sigaction(int sig,
const struct sigaction __user *act,
struct sigaction __user *oact,
diff --git a/include/asm-m32r/dma-mapping.h b/include/asm-m32r/dma-mapping.h
index 3a2db28834b6..a7fa0302bda7 100644
--- a/include/asm-m32r/dma-mapping.h
+++ b/include/asm-m32r/dma-mapping.h
@@ -8,7 +8,7 @@
static inline void *
dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle,
- int flag)
+ gfp_t flag)
{
return (void *)NULL;
}
diff --git a/include/asm-m32r/mmzone.h b/include/asm-m32r/mmzone.h
index d58878ec899e..adc7970a77ec 100644
--- a/include/asm-m32r/mmzone.h
+++ b/include/asm-m32r/mmzone.h
@@ -21,12 +21,6 @@ extern struct pglist_data *node_data[];
__pgdat->node_start_pfn + __pgdat->node_spanned_pages - 1; \
})
-#define local_mapnr(kvaddr) \
-({ \
- unsigned long __pfn = __pa(kvaddr) >> PAGE_SHIFT; \
- (__pfn - node_start_pfn(pfn_to_nid(__pfn))); \
-})
-
#define pfn_to_page(pfn) \
({ \
unsigned long __pfn = pfn; \
diff --git a/include/asm-m32r/pgtable.h b/include/asm-m32r/pgtable.h
index 388e5ee9fa27..75740debcd01 100644
--- a/include/asm-m32r/pgtable.h
+++ b/include/asm-m32r/pgtable.h
@@ -27,6 +27,9 @@
#include <asm/bitops.h>
#include <asm/page.h>
+struct mm_struct;
+struct vm_area_struct;
+
extern pgd_t swapper_pg_dir[1024];
extern void paging_init(void);
@@ -324,8 +327,6 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
return pte;
}
-#define page_pte(page) page_pte_prot(page, __pgprot(0))
-
/*
* Conversion functions: convert a page and protection to a page entry,
* and a page entry and page directory to the page they refer to.
diff --git a/include/asm-m32r/ptrace.h b/include/asm-m32r/ptrace.h
index 976417126b2d..55cd7ecfde43 100644
--- a/include/asm-m32r/ptrace.h
+++ b/include/asm-m32r/ptrace.h
@@ -145,6 +145,9 @@ struct pt_regs {
#define PTRACE_O_TRACESYSGOOD 0x00000001
#ifdef __KERNEL__
+
+#define __ARCH_SYS_PTRACE 1
+
#if defined(CONFIG_ISA_M32R2) || defined(CONFIG_CHIP_VDEC2)
#define user_mode(regs) ((M32R_PSW_BPM & (regs)->psw) != 0)
#elif defined(CONFIG_ISA_M32R)
diff --git a/include/asm-m32r/semaphore.h b/include/asm-m32r/semaphore.h
index 53e3c60f21ec..bf447c52a0a1 100644
--- a/include/asm-m32r/semaphore.h
+++ b/include/asm-m32r/semaphore.h
@@ -32,9 +32,6 @@ struct semaphore {
.wait = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \
}
-#define __MUTEX_INITIALIZER(name) \
- __SEMAPHORE_INITIALIZER(name,1)
-
#define __DECLARE_SEMAPHORE_GENERIC(name,count) \
struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
diff --git a/include/asm-m32r/thread_info.h b/include/asm-m32r/thread_info.h
index 7a6be7727a92..0f589363f619 100644
--- a/include/asm-m32r/thread_info.h
+++ b/include/asm-m32r/thread_info.h
@@ -95,7 +95,7 @@ static inline struct thread_info *current_thread_info(void)
}
/* thread information allocation */
-#if CONFIG_DEBUG_STACK_USAGE
+#ifdef CONFIG_DEBUG_STACK_USAGE
#define alloc_thread_info(tsk) \
({ \
struct thread_info *ret; \
diff --git a/include/asm-m32r/unistd.h b/include/asm-m32r/unistd.h
index 8552d8f45ab1..ac399e1f7bc0 100644
--- a/include/asm-m32r/unistd.h
+++ b/include/asm-m32r/unistd.h
@@ -452,7 +452,6 @@ asmlinkage int sys_clone(struct pt_regs regs);
asmlinkage int sys_fork(struct pt_regs regs);
asmlinkage int sys_vfork(struct pt_regs regs);
asmlinkage int sys_pipe(unsigned long __user *fildes);
-asmlinkage int sys_ptrace(long request, long pid, long addr, long data);
struct sigaction;
asmlinkage long sys_rt_sigaction(int sig,
const struct sigaction __user *act,
diff --git a/include/asm-m68k/kbio.h b/include/asm-m68k/kbio.h
deleted file mode 100644
index e1fbf8fba3e8..000000000000
--- a/include/asm-m68k/kbio.h
+++ /dev/null
@@ -1 +0,0 @@
-#include <asm-sparc/kbio.h>
diff --git a/include/asm-m68k/semaphore.h b/include/asm-m68k/semaphore.h
index ab94cf3ed447..fd4c7cc3d3be 100644
--- a/include/asm-m68k/semaphore.h
+++ b/include/asm-m68k/semaphore.h
@@ -36,9 +36,6 @@ struct semaphore {
.wait = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \
}
-#define __MUTEX_INITIALIZER(name) \
- __SEMAPHORE_INITIALIZER(name,1)
-
#define __DECLARE_SEMAPHORE_GENERIC(name,count) \
struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
diff --git a/include/asm-m68k/sun3xflop.h b/include/asm-m68k/sun3xflop.h
index 1ed3b787ee05..fda1eccf10aa 100644
--- a/include/asm-m68k/sun3xflop.h
+++ b/include/asm-m68k/sun3xflop.h
@@ -27,10 +27,8 @@
/* We don't need no stinkin' I/O port allocation crap. */
#undef release_region
-#undef check_region
#undef request_region
#define release_region(X, Y) do { } while(0)
-#define check_region(X, Y) (0)
#define request_region(X, Y, Z) (1)
struct sun3xflop_private {
diff --git a/include/asm-m68k/unistd.h b/include/asm-m68k/unistd.h
index cbabde4f8a45..c2554bcd1747 100644
--- a/include/asm-m68k/unistd.h
+++ b/include/asm-m68k/unistd.h
@@ -444,7 +444,6 @@ asmlinkage long sys_mmap2(
unsigned long fd, unsigned long pgoff);
asmlinkage int sys_execve(char *name, char **argv, char **envp);
asmlinkage int sys_pipe(unsigned long *fildes);
-asmlinkage int sys_ptrace(long request, long pid, long addr, long data);
struct pt_regs;
struct sigaction;
asmlinkage long sys_rt_sigaction(int sig,
diff --git a/include/asm-m68k/vuid_event.h b/include/asm-m68k/vuid_event.h
deleted file mode 100644
index 52ecb521a395..000000000000
--- a/include/asm-m68k/vuid_event.h
+++ /dev/null
@@ -1,4 +0,0 @@
-#ifndef _M68K_VUID_EVENT_H
-#define _M68K_VUID_EVENT_H
-#include <asm-sparc/vuid_event.h>
-#endif
diff --git a/include/asm-m68knommu/anchor.h b/include/asm-m68knommu/anchor.h
index 75390e0b40c9..871c0d5cfc3d 100644
--- a/include/asm-m68knommu/anchor.h
+++ b/include/asm-m68knommu/anchor.h
@@ -14,7 +14,7 @@
/*
* Define basic addressing info.
*/
-#if defined(CONFIG_MOTOROLA) && defined(CONFIG_M5407)
+#if defined(CONFIG_M5407C3)
#define COMEM_BASE 0xFFFF0000 /* Base of CO-MEM address space */
#define COMEM_IRQ 25 /* IRQ of anchor part */
#else
@@ -96,7 +96,7 @@
* The PCI bus will be limited in what slots will actually be used.
* Define valid device numbers for different boards.
*/
-#if defined(CONFIG_MOTOROLA) && defined(CONFIG_M5407)
+#if defined(CONFIG_M5407C3)
#define COMEM_MINDEV 14 /* Minimum valid DEVICE */
#define COMEM_MAXDEV 14 /* Maximum valid DEVICE */
#define COMEM_BRIDGEDEV 15 /* Slot bridge is in */
diff --git a/include/asm-m68knommu/asm-offsets.h b/include/asm-m68knommu/asm-offsets.h
deleted file mode 100644
index 825f6e210f19..000000000000
--- a/include/asm-m68knommu/asm-offsets.h
+++ /dev/null
@@ -1,49 +0,0 @@
-#ifndef __ASM_OFFSETS_H__
-#define __ASM_OFFSETS_H__
-/*
- * DO NOT MODIFY.
- *
- * This file was generated by arch/m68knommu/Makefile
- *
- */
-
-#define TASK_STATE 0 /* offsetof(struct task_struct, state) */
-#define TASK_FLAGS 12 /* offsetof(struct task_struct, flags) */
-#define TASK_PTRACE 16 /* offsetof(struct task_struct, ptrace) */
-#define TASK_BLOCKED 922 /* offsetof(struct task_struct, blocked) */
-#define TASK_THREAD 772 /* offsetof(struct task_struct, thread) */
-#define TASK_THREAD_INFO 4 /* offsetof(struct task_struct, thread_info) */
-#define TASK_MM 92 /* offsetof(struct task_struct, mm) */
-#define TASK_ACTIVE_MM 96 /* offsetof(struct task_struct, active_mm) */
-#define CPUSTAT_SOFTIRQ_PENDING 0 /* offsetof(irq_cpustat_t, __softirq_pending) */
-#define THREAD_KSP 0 /* offsetof(struct thread_struct, ksp) */
-#define THREAD_USP 4 /* offsetof(struct thread_struct, usp) */
-#define THREAD_SR 8 /* offsetof(struct thread_struct, sr) */
-#define THREAD_FS 10 /* offsetof(struct thread_struct, fs) */
-#define THREAD_CRP 12 /* offsetof(struct thread_struct, crp) */
-#define THREAD_ESP0 20 /* offsetof(struct thread_struct, esp0) */
-#define THREAD_FPREG 24 /* offsetof(struct thread_struct, fp) */
-#define THREAD_FPCNTL 120 /* offsetof(struct thread_struct, fpcntl) */
-#define THREAD_FPSTATE 132 /* offsetof(struct thread_struct, fpstate) */
-#define PT_D0 32 /* offsetof(struct pt_regs, d0) */
-#define PT_ORIG_D0 36 /* offsetof(struct pt_regs, orig_d0) */
-#define PT_D1 0 /* offsetof(struct pt_regs, d1) */
-#define PT_D2 4 /* offsetof(struct pt_regs, d2) */
-#define PT_D3 8 /* offsetof(struct pt_regs, d3) */
-#define PT_D4 12 /* offsetof(struct pt_regs, d4) */
-#define PT_D5 16 /* offsetof(struct pt_regs, d5) */
-#define PT_A0 20 /* offsetof(struct pt_regs, a0) */
-#define PT_A1 24 /* offsetof(struct pt_regs, a1) */
-#define PT_A2 28 /* offsetof(struct pt_regs, a2) */
-#define PT_PC 48 /* offsetof(struct pt_regs, pc) */
-#define PT_SR 46 /* offsetof(struct pt_regs, sr) */
-#define PT_VECTOR 52 /* offsetof(struct pt_regs, pc) + 4 */
-#define STAT_IRQ 5140 /* offsetof(struct kernel_stat, irqs) */
-#define SIGSEGV 11 /* SIGSEGV */
-#define SEGV_MAPERR 196609 /* SEGV_MAPERR */
-#define SIGTRAP 5 /* SIGTRAP */
-#define TRAP_TRACE 196610 /* TRAP_TRACE */
-#define PT_PTRACED 1 /* PT_PTRACED */
-#define PT_DTRACE 2 /* PT_DTRACE */
-
-#endif
diff --git a/include/asm-m68knommu/atomic.h b/include/asm-m68knommu/atomic.h
index b1957fba083b..a83631ed8c8f 100644
--- a/include/asm-m68knommu/atomic.h
+++ b/include/asm-m68knommu/atomic.h
@@ -100,7 +100,7 @@ static __inline__ void atomic_set_mask(unsigned long mask, unsigned long *v)
#define smp_mb__before_atomic_inc() barrier()
#define smp_mb__after_atomic_inc() barrier()
-extern __inline__ int atomic_add_return(int i, atomic_t * v)
+static inline int atomic_add_return(int i, atomic_t * v)
{
unsigned long temp, flags;
@@ -115,7 +115,7 @@ extern __inline__ int atomic_add_return(int i, atomic_t * v)
#define atomic_add_negative(a, v) (atomic_add_return((a), (v)) < 0)
-extern __inline__ int atomic_sub_return(int i, atomic_t * v)
+static inline int atomic_sub_return(int i, atomic_t * v)
{
unsigned long temp, flags;
diff --git a/include/asm-m68knommu/cacheflush.h b/include/asm-m68knommu/cacheflush.h
index 026bbc9565b4..49925e91e89c 100644
--- a/include/asm-m68knommu/cacheflush.h
+++ b/include/asm-m68knommu/cacheflush.h
@@ -25,7 +25,7 @@
#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
memcpy(dst, src, len)
-extern inline void __flush_cache_all(void)
+static inline void __flush_cache_all(void)
{
#ifdef CONFIG_M5407
/*
@@ -64,7 +64,7 @@ extern inline void __flush_cache_all(void)
"nop\n\t"
: : : "d0" );
#endif /* CONFIG_M5272 */
-#if CONFIG_M5249
+#ifdef CONFIG_M5249
__asm__ __volatile__ (
"movel #0xa1000200, %%d0\n\t"
"movec %%d0, %%CACR\n\t"
diff --git a/include/asm-m68knommu/coldfire.h b/include/asm-m68knommu/coldfire.h
index 1df3f666a28e..6190f77b1e6c 100644
--- a/include/asm-m68knommu/coldfire.h
+++ b/include/asm-m68knommu/coldfire.h
@@ -20,9 +20,14 @@
*/
#define MCF_MBAR 0x10000000
#define MCF_MBAR2 0x80000000
+#if defined(CONFIG_M520x)
+#define MCF_IPSBAR 0xFC000000
+#else
#define MCF_IPSBAR 0x40000000
+#endif
-#if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x)
+#if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) || \
+ defined(CONFIG_M520x)
#undef MCF_MBAR
#define MCF_MBAR MCF_IPSBAR
#endif
@@ -78,7 +83,8 @@
* One some ColdFire family members the bus clock (used by internal
* peripherals) is not the same as the CPU clock.
*/
-#if defined(CONFIG_M523x) || defined(CONFIG_M5249) || defined(CONFIG_M527x)
+#if defined(CONFIG_M523x) || defined(CONFIG_M5249) || defined(CONFIG_M527x) || \
+ defined(CONFIG_M520x)
#define MCF_BUSCLK (MCF_CLK / 2)
#else
#define MCF_BUSCLK MCF_CLK
diff --git a/include/asm-m68knommu/delay.h b/include/asm-m68knommu/delay.h
index e3a976254672..04a20fd051cf 100644
--- a/include/asm-m68knommu/delay.h
+++ b/include/asm-m68knommu/delay.h
@@ -8,7 +8,7 @@
#include <asm/param.h>
-extern __inline__ void __delay(unsigned long loops)
+static inline void __delay(unsigned long loops)
{
#if defined(CONFIG_COLDFIRE)
/* The coldfire runs this loop at significantly different speeds
@@ -48,7 +48,7 @@ extern __inline__ void __delay(unsigned long loops)
extern unsigned long loops_per_jiffy;
-extern __inline__ void _udelay(unsigned long usecs)
+static inline void _udelay(unsigned long usecs)
{
#if defined(CONFIG_M68328) || defined(CONFIG_M68EZ328) || \
defined(CONFIG_M68VZ328) || defined(CONFIG_M68360) || \
diff --git a/include/asm-m68knommu/ide.h b/include/asm-m68knommu/ide.h
deleted file mode 100644
index b1cbf8bb9232..000000000000
--- a/include/asm-m68knommu/ide.h
+++ /dev/null
@@ -1,444 +0,0 @@
-/****************************************************************************/
-/*
- * linux/include/asm-m68knommu/ide.h
- *
- * Copyright (C) 1994-1996 Linus Torvalds & authors
- * Copyright (C) 2001 Lineo Inc., davidm@uclinux.org
- */
-/****************************************************************************/
-#ifndef _M68KNOMMU_IDE_H
-#define _M68KNOMMU_IDE_H
-
-#ifdef __KERNEL__
-/****************************************************************************/
-
-#include <linux/config.h>
-#include <linux/interrupt.h>
-
-#include <asm/setup.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-
-/****************************************************************************/
-/*
- * some coldfire specifics
- */
-
-#ifdef CONFIG_COLDFIRE
-#include <asm/coldfire.h>
-#include <asm/mcfsim.h>
-
-/*
- * Save some space, only have 1 interface
- */
-#define MAX_HWIFS 1 /* we only have one interface for now */
-
-#ifdef CONFIG_SECUREEDGEMP3
-#define MCFSIM_LOCALCS MCFSIM_CSCR4
-#else
-#define MCFSIM_LOCALCS MCFSIM_CSCR6
-#endif
-
-#endif /* CONFIG_COLDFIRE */
-
-/****************************************************************************/
-/*
- * Fix up things that may not have been provided
- */
-
-#ifndef MAX_HWIFS
-#define MAX_HWIFS 4 /* same as the other archs */
-#endif
-
-#undef SUPPORT_SLOW_DATA_PORTS
-#define SUPPORT_SLOW_DATA_PORTS 0
-
-#undef SUPPORT_VLB_SYNC
-#define SUPPORT_VLB_SYNC 0
-
-/* this definition is used only on startup .. */
-#undef HD_DATA
-#define HD_DATA NULL
-
-#define DBGIDE(fmt,a...)
-// #define DBGIDE(fmt,a...) printk(fmt, ##a)
-#define IDE_INLINE __inline__
-// #define IDE_INLINE
-
-/****************************************************************************/
-
-typedef union {
- unsigned all : 8; /* all of the bits together */
- struct {
- unsigned bit7 : 1; /* always 1 */
- unsigned lba : 1; /* using LBA instead of CHS */
- unsigned bit5 : 1; /* always 1 */
- unsigned unit : 1; /* drive select number, 0 or 1 */
- unsigned head : 4; /* always zeros here */
- } b;
-} select_t;
-
-/*
- * our list of ports/irq's for different boards
- */
-
-static struct m68k_ide_defaults {
- ide_ioreg_t base;
- int irq;
-} m68k_ide_defaults[MAX_HWIFS] = {
-#if defined(CONFIG_SECUREEDGEMP3)
- { ((ide_ioreg_t)0x30800000), 29 },
-#elif defined(CONFIG_eLIA)
- { ((ide_ioreg_t)0x30c00000), 29 },
-#else
- { ((ide_ioreg_t)0x0), 0 }
-#endif
-};
-
-/****************************************************************************/
-
-static IDE_INLINE int ide_default_irq(ide_ioreg_t base)
-{
- int i;
-
- for (i = 0; i < MAX_HWIFS; i++)
- if (m68k_ide_defaults[i].base == base)
- return(m68k_ide_defaults[i].irq);
- return 0;
-}
-
-static IDE_INLINE ide_ioreg_t ide_default_io_base(int index)
-{
- if (index >= 0 && index < MAX_HWIFS)
- return(m68k_ide_defaults[index].base);
- return 0;
-}
-
-
-/*
- * Set up a hw structure for a specified data port, control port and IRQ.
- * This should follow whatever the default interface uses.
- */
-static IDE_INLINE void ide_init_hwif_ports(
- hw_regs_t *hw,
- ide_ioreg_t data_port,
- ide_ioreg_t ctrl_port,
- int *irq)
-{
- ide_ioreg_t reg = data_port;
- int i;
-
- for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) {
- hw->io_ports[i] = reg;
- reg += 1;
- }
- if (ctrl_port) {
- hw->io_ports[IDE_CONTROL_OFFSET] = ctrl_port;
- } else {
- hw->io_ports[IDE_CONTROL_OFFSET] = data_port + 0xe;
- }
-}
-
-#define ide_init_default_irq(base) ide_default_irq(base)
-
-static IDE_INLINE int
-ide_request_irq(
- unsigned int irq,
- void (*handler)(int, void *, struct pt_regs *),
- unsigned long flags,
- const char *device,
- void *dev_id)
-{
-#ifdef CONFIG_COLDFIRE
- mcf_autovector(irq);
-#endif
- return(request_irq(irq, handler, flags, device, dev_id));
-}
-
-
-static IDE_INLINE void
-ide_free_irq(unsigned int irq, void *dev_id)
-{
- free_irq(irq, dev_id);
-}
-
-
-static IDE_INLINE int
-ide_check_region(ide_ioreg_t from, unsigned int extent)
-{
- return 0;
-}
-
-
-static IDE_INLINE void
-ide_request_region(ide_ioreg_t from, unsigned int extent, const char *name)
-{
-}
-
-
-static IDE_INLINE void
-ide_release_region(ide_ioreg_t from, unsigned int extent)
-{
-}
-
-
-static IDE_INLINE void
-ide_fix_driveid(struct hd_driveid *id)
-{
-#ifdef CONFIG_COLDFIRE
- int i, n;
- unsigned short *wp = (unsigned short *) id;
- int avoid[] = {49, 51, 52, 59, -1 }; /* do not swap these words */
-
- /* Need to byte swap shorts, but not char fields */
- for (i = n = 0; i < sizeof(*id) / sizeof(*wp); i++, wp++) {
- if (avoid[n] == i) {
- n++;
- continue;
- }
- *wp = ((*wp & 0xff) << 8) | ((*wp >> 8) & 0xff);
- }
- /* have to word swap the one 32 bit field */
- id->lba_capacity = ((id->lba_capacity & 0xffff) << 16) |
- ((id->lba_capacity >> 16) & 0xffff);
-#endif
-}
-
-
-static IDE_INLINE void
-ide_release_lock (int *ide_lock)
-{
-}
-
-
-static IDE_INLINE void
-ide_get_lock(
- int *ide_lock,
- void (*handler)(int, void *, struct pt_regs *),
- void *data)
-{
-}
-
-
-#define ide_ack_intr(hwif) \
- ((hwif)->hw.ack_intr ? (hwif)->hw.ack_intr(hwif) : 1)
-#define ide__sti() __sti()
-
-/****************************************************************************/
-/*
- * System specific IO requirements
- */
-
-#ifdef CONFIG_COLDFIRE
-
-#ifdef CONFIG_SECUREEDGEMP3
-
-/* Replace standard IO functions for funky mapping of MP3 board */
-#undef outb
-#undef outb_p
-#undef inb
-#undef inb_p
-
-#define outb(v, a) ide_outb(v, (unsigned long) (a))
-#define outb_p(v, a) ide_outb(v, (unsigned long) (a))
-#define inb(a) ide_inb((unsigned long) (a))
-#define inb_p(a) ide_inb((unsigned long) (a))
-
-#define ADDR8_PTR(addr) (((addr) & 0x1) ? (0x8000 + (addr) - 1) : (addr))
-#define ADDR16_PTR(addr) (addr)
-#define ADDR32_PTR(addr) (addr)
-#define SWAP8(w) ((((w) & 0xffff) << 8) | (((w) & 0xffff) >> 8))
-#define SWAP16(w) (w)
-#define SWAP32(w) (w)
-
-
-static IDE_INLINE void
-ide_outb(unsigned int val, unsigned int addr)
-{
- volatile unsigned short *rp;
-
- DBGIDE("%s(val=%x,addr=%x)\n", __FUNCTION__, val, addr);
- rp = (volatile unsigned short *) ADDR8_PTR(addr);
- *rp = SWAP8(val);
-}
-
-
-static IDE_INLINE int
-ide_inb(unsigned int addr)
-{
- volatile unsigned short *rp, val;
-
- DBGIDE("%s(addr=%x)\n", __FUNCTION__, addr);
- rp = (volatile unsigned short *) ADDR8_PTR(addr);
- val = *rp;
- return(SWAP8(val));
-}
-
-
-static IDE_INLINE void
-ide_outw(unsigned int val, unsigned int addr)
-{
- volatile unsigned short *rp;
-
- DBGIDE("%s(val=%x,addr=%x)\n", __FUNCTION__, val, addr);
- rp = (volatile unsigned short *) ADDR16_PTR(addr);
- *rp = SWAP16(val);
-}
-
-static IDE_INLINE void
-ide_outsw(unsigned int addr, const void *vbuf, unsigned long len)
-{
- volatile unsigned short *rp, val;
- unsigned short *buf;
-
- DBGIDE("%s(addr=%x,vbuf=%p,len=%x)\n", __FUNCTION__, addr, vbuf, len);
- buf = (unsigned short *) vbuf;
- rp = (volatile unsigned short *) ADDR16_PTR(addr);
- for (; (len > 0); len--) {
- val = *buf++;
- *rp = SWAP16(val);
- }
-}
-
-static IDE_INLINE int
-ide_inw(unsigned int addr)
-{
- volatile unsigned short *rp, val;
-
- DBGIDE("%s(addr=%x)\n", __FUNCTION__, addr);
- rp = (volatile unsigned short *) ADDR16_PTR(addr);
- val = *rp;
- return(SWAP16(val));
-}
-
-static IDE_INLINE void
-ide_insw(unsigned int addr, void *vbuf, unsigned long len)
-{
- volatile unsigned short *rp;
- unsigned short w, *buf;
-
- DBGIDE("%s(addr=%x,vbuf=%p,len=%x)\n", __FUNCTION__, addr, vbuf, len);
- buf = (unsigned short *) vbuf;
- rp = (volatile unsigned short *) ADDR16_PTR(addr);
- for (; (len > 0); len--) {
- w = *rp;
- *buf++ = SWAP16(w);
- }
-}
-
-static IDE_INLINE void
-ide_insl(unsigned int addr, void *vbuf, unsigned long len)
-{
- volatile unsigned long *rp;
- unsigned long w, *buf;
-
- DBGIDE("%s(addr=%x,vbuf=%p,len=%x)\n", __FUNCTION__, addr, vbuf, len);
- buf = (unsigned long *) vbuf;
- rp = (volatile unsigned long *) ADDR32_PTR(addr);
- for (; (len > 0); len--) {
- w = *rp;
- *buf++ = SWAP32(w);
- }
-}
-
-static IDE_INLINE void
-ide_outsl(unsigned int addr, const void *vbuf, unsigned long len)
-{
- volatile unsigned long *rp, val;
- unsigned long *buf;
-
- DBGIDE("%s(addr=%x,vbuf=%p,len=%x)\n", __FUNCTION__, addr, vbuf, len);
- buf = (unsigned long *) vbuf;
- rp = (volatile unsigned long *) ADDR32_PTR(addr);
- for (; (len > 0); len--) {
- val = *buf++;
- *rp = SWAP32(val);
- }
-}
-
-#elif CONFIG_eLIA
-
-/* 8/16 bit acesses are controlled by flicking bits in the CS register */
-#define ACCESS_MODE_16BIT() \
- *((volatile unsigned short *) (MCF_MBAR + MCFSIM_LOCALCS)) = 0x0080
-#define ACCESS_MODE_8BIT() \
- *((volatile unsigned short *) (MCF_MBAR + MCFSIM_LOCALCS)) = 0x0040
-
-
-static IDE_INLINE void
-ide_outw(unsigned int val, unsigned int addr)
-{
- ACCESS_MODE_16BIT();
- outw(val, addr);
- ACCESS_MODE_8BIT();
-}
-
-static IDE_INLINE void
-ide_outsw(unsigned int addr, const void *vbuf, unsigned long len)
-{
- ACCESS_MODE_16BIT();
- outsw(addr, vbuf, len);
- ACCESS_MODE_8BIT();
-}
-
-static IDE_INLINE int
-ide_inw(unsigned int addr)
-{
- int ret;
-
- ACCESS_MODE_16BIT();
- ret = inw(addr);
- ACCESS_MODE_8BIT();
- return(ret);
-}
-
-static IDE_INLINE void
-ide_insw(unsigned int addr, void *vbuf, unsigned long len)
-{
- ACCESS_MODE_16BIT();
- insw(addr, vbuf, len);
- ACCESS_MODE_8BIT();
-}
-
-static IDE_INLINE void
-ide_insl(unsigned int addr, void *vbuf, unsigned long len)
-{
- ACCESS_MODE_16BIT();
- insl(addr, vbuf, len);
- ACCESS_MODE_8BIT();
-}
-
-static IDE_INLINE void
-ide_outsl(unsigned int addr, const void *vbuf, unsigned long len)
-{
- ACCESS_MODE_16BIT();
- outsl(addr, vbuf, len);
- ACCESS_MODE_8BIT();
-}
-
-#endif /* CONFIG_SECUREEDGEMP3 */
-
-#undef outw
-#undef outw_p
-#undef outsw
-#undef inw
-#undef inw_p
-#undef insw
-#undef insl
-#undef outsl
-
-#define outw(v, a) ide_outw(v, (unsigned long) (a))
-#define outw_p(v, a) ide_outw(v, (unsigned long) (a))
-#define outsw(a, b, n) ide_outsw((unsigned long) (a), b, n)
-#define inw(a) ide_inw((unsigned long) (a))
-#define inw_p(a) ide_inw((unsigned long) (a))
-#define insw(a, b, n) ide_insw((unsigned long) (a), b, n)
-#define insl(a, b, n) ide_insl((unsigned long) (a), b, n)
-#define outsl(a, b, n) ide_outsl((unsigned long) (a), b, n)
-
-#endif CONFIG_COLDFIRE
-
-/****************************************************************************/
-#endif /* __KERNEL__ */
-#endif /* _M68KNOMMU_IDE_H */
-/****************************************************************************/
diff --git a/include/asm-m68knommu/io.h b/include/asm-m68knommu/io.h
index 30fade4149b8..e08f2ee4b4a2 100644
--- a/include/asm-m68knommu/io.h
+++ b/include/asm-m68knommu/io.h
@@ -147,19 +147,19 @@ static inline void io_insl(unsigned int addr, void *buf, int len)
extern void *__ioremap(unsigned long physaddr, unsigned long size, int cacheflag);
extern void __iounmap(void *addr, unsigned long size);
-extern inline void *ioremap(unsigned long physaddr, unsigned long size)
+static inline void *ioremap(unsigned long physaddr, unsigned long size)
{
return __ioremap(physaddr, size, IOMAP_NOCACHE_SER);
}
-extern inline void *ioremap_nocache(unsigned long physaddr, unsigned long size)
+static inline void *ioremap_nocache(unsigned long physaddr, unsigned long size)
{
return __ioremap(physaddr, size, IOMAP_NOCACHE_SER);
}
-extern inline void *ioremap_writethrough(unsigned long physaddr, unsigned long size)
+static inline void *ioremap_writethrough(unsigned long physaddr, unsigned long size)
{
return __ioremap(physaddr, size, IOMAP_WRITETHROUGH);
}
-extern inline void *ioremap_fullcache(unsigned long physaddr, unsigned long size)
+static inline void *ioremap_fullcache(unsigned long physaddr, unsigned long size)
{
return __ioremap(physaddr, size, IOMAP_FULL_CACHING);
}
diff --git a/include/asm-m68knommu/irq.h b/include/asm-m68knommu/irq.h
index 208ccd969e4b..a08fa9b958da 100644
--- a/include/asm-m68knommu/irq.h
+++ b/include/asm-m68knommu/irq.h
@@ -2,7 +2,6 @@
#define _M68K_IRQ_H_
#include <linux/config.h>
-#include <linux/interrupt.h>
#include <asm/ptrace.h>
#ifdef CONFIG_COLDFIRE
@@ -83,36 +82,6 @@ extern void (*mach_disable_irq)(unsigned int);
#endif /* CONFIG_M68360 */
/*
- * 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 *, struct pt_regs *);
- unsigned long flags;
- void *dev_id;
- const char *devname;
- struct irq_node *next;
-} irq_node_t;
-
-/*
- * This structure has only 4 elements for speed reasons
- */
-typedef struct irq_handler {
- irqreturn_t (*handler)(int, void *, struct pt_regs *);
- unsigned long flags;
- void *dev_id;
- const char *devname;
-} irq_handler_t;
-
-/* count of spurious interrupts */
-extern volatile unsigned int num_spurious;
-
-/*
- * This function returns a new irq_node_t
- */
-extern irq_node_t *new_irq_node(void);
-
-/*
* Some drivers want these entry points
*/
#define enable_irq(x) (mach_enable_irq ? (*mach_enable_irq)(x) : 0)
diff --git a/include/asm-m68knommu/irqnode.h b/include/asm-m68knommu/irqnode.h
new file mode 100644
index 000000000000..a2503dfc554c
--- /dev/null
+++ b/include/asm-m68knommu/irqnode.h
@@ -0,0 +1,36 @@
+#ifndef _M68K_IRQNODE_H_
+#define _M68K_IRQNODE_H_
+
+#include <linux/interrupt.h>
+
+/*
+ * 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 *, struct pt_regs *);
+ unsigned long flags;
+ void *dev_id;
+ const char *devname;
+ struct irq_node *next;
+} irq_node_t;
+
+/*
+ * This structure has only 4 elements for speed reasons
+ */
+typedef struct irq_handler {
+ irqreturn_t (*handler)(int, void *, struct pt_regs *);
+ unsigned long flags;
+ void *dev_id;
+ const char *devname;
+} irq_handler_t;
+
+/* count of spurious interrupts */
+extern volatile unsigned int num_spurious;
+
+/*
+ * This function returns a new irq_node_t
+ */
+extern irq_node_t *new_irq_node(void);
+
+#endif /* _M68K_IRQNODE_H_ */
diff --git a/include/asm-m68knommu/m520xsim.h b/include/asm-m68knommu/m520xsim.h
new file mode 100644
index 000000000000..6dc62869e62b
--- /dev/null
+++ b/include/asm-m68knommu/m520xsim.h
@@ -0,0 +1,54 @@
+/****************************************************************************/
+
+/*
+ * m520xsim.h -- ColdFire 5207/5208 System Integration Module support.
+ *
+ * (C) Copyright 2005, Intec Automation (mike@steroidmicros.com)
+ */
+
+/****************************************************************************/
+#ifndef m520xsim_h
+#define m520xsim_h
+/****************************************************************************/
+
+#include <linux/config.h>
+
+/*
+ * Define the 5282 SIM register set addresses.
+ */
+#define MCFICM_INTC0 0x48000 /* Base for Interrupt Ctrl 0 */
+#define MCFINTC_IPRH 0x00 /* Interrupt pending 32-63 */
+#define MCFINTC_IPRL 0x04 /* Interrupt pending 1-31 */
+#define MCFINTC_IMRH 0x08 /* Interrupt mask 32-63 */
+#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_ICR0 0x40 /* Base ICR register */
+
+#define MCFINT_VECBASE 64
+#define MCFINT_UART0 26 /* Interrupt number for UART0 */
+#define MCFINT_UART1 27 /* Interrupt number for UART1 */
+#define MCFINT_UART2 28 /* Interrupt number for UART2 */
+#define MCFINT_QSPI 31 /* Interrupt number for QSPI */
+#define MCFINT_PIT1 4 /* Interrupt number for PIT1 (PIT0 in processor) */
+
+
+#define MCF_GPIO_PAR_UART (0xA4036)
+#define MCF_GPIO_PAR_FECI2C (0xA4033)
+#define MCF_GPIO_PAR_FEC (0xA4038)
+
+#define MCF_GPIO_PAR_UART_PAR_URXD0 (0x0001)
+#define MCF_GPIO_PAR_UART_PAR_UTXD0 (0x0002)
+
+#define MCF_GPIO_PAR_UART_PAR_URXD1 (0x0040)
+#define MCF_GPIO_PAR_UART_PAR_UTXD1 (0x0080)
+
+#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)
+
+/****************************************************************************/
+#endif /* m520xsim_h */
diff --git a/include/asm-m68knommu/mcfcache.h b/include/asm-m68knommu/mcfcache.h
index b17cd920977f..9cb401421835 100644
--- a/include/asm-m68knommu/mcfcache.h
+++ b/include/asm-m68knommu/mcfcache.h
@@ -117,6 +117,20 @@
.endm
#endif /* CONFIG_M5407 */
+#if defined(CONFIG_M520x)
+.macro CACHE_ENABLE
+ move.l #0x01000000,%d0 /* invalidate whole cache */
+ movec %d0,%CACR
+ nop
+ move.l #0x0000c000,%d0 /* set SDRAM cached (write-thru) */
+ movec %d0,%ACR0
+ move.l #0x00000000,%d0 /* no other regions cached */
+ movec %d0,%ACR1
+ move.l #0x80400000,%d0 /* enable 8K instruction cache */
+ movec %d0,%CACR
+ nop
+.endm
+#endif /* CONFIG_M520x */
/****************************************************************************/
#endif /* __M68KNOMMU_MCFCACHE_H */
diff --git a/include/asm-m68knommu/mcfne.h b/include/asm-m68knommu/mcfne.h
index 045875651e4d..a71b1c8cb4f8 100644
--- a/include/asm-m68knommu/mcfne.h
+++ b/include/asm-m68knommu/mcfne.h
@@ -35,7 +35,7 @@
* Define the basic hardware resources of NE2000 boards.
*/
-#if defined(CONFIG_M5206) && defined(CONFIG_ARNEWSH)
+#if defined(CONFIG_ARN5206)
#define NE2000_ADDR 0x40000300
#define NE2000_ODDOFFSET 0x00010000
#define NE2000_IRQ_VECTOR 0xf0
@@ -44,7 +44,7 @@
#define NE2000_BYTE volatile unsigned short
#endif
-#if defined(CONFIG_M5206e) && defined(CONFIG_MOTOROLA)
+#if defined(CONFIG_M5206eC3)
#define NE2000_ADDR 0x40000300
#define NE2000_ODDOFFSET 0x00010000
#define NE2000_IRQ_VECTOR 0x1c
@@ -61,7 +61,7 @@
#define NE2000_BYTE volatile unsigned char
#endif
-#if defined(CONFIG_M5206e) && defined(CONFIG_CFV240)
+#if defined(CONFIG_CFV240)
#define NE2000_ADDR 0x40010000
#define NE2000_ADDR1 0x40010001
#define NE2000_ODDOFFSET 0x00000000
@@ -72,7 +72,7 @@
#define NE2000_BYTE volatile unsigned char
#endif
-#if defined(CONFIG_M5307) && defined(CONFIG_MOTOROLA)
+#if defined(CONFIG_M5307C3)
#define NE2000_ADDR 0x40000300
#define NE2000_ODDOFFSET 0x00010000
#define NE2000_IRQ_VECTOR 0x1b
@@ -114,7 +114,7 @@
#define RSWAP(w) (((w) << 8) | ((w) >> 8))
#endif
-#if defined(CONFIG_M5307) && defined(CONFIG_ARNEWSH)
+#if defined(CONFIG_ARN5307)
#define NE2000_ADDR 0xfe600300
#define NE2000_ODDOFFSET 0x00010000
#define NE2000_IRQ_VECTOR 0x1b
@@ -123,7 +123,7 @@
#define NE2000_BYTE volatile unsigned short
#endif
-#if defined(CONFIG_M5407)
+#if defined(CONFIG_M5407C3)
#define NE2000_ADDR 0x40000300
#define NE2000_ODDOFFSET 0x00010000
#define NE2000_IRQ_VECTOR 0x1b
@@ -264,7 +264,7 @@ void ne2000_outsw(unsigned int addr, const void *vbuf, unsigned long len)
* Minor differences between the different board types.
*/
-#if defined(CONFIG_M5206) && defined(CONFIG_ARNEWSH)
+#if defined(CONFIG_ARN5206)
void ne2000_irqsetup(int irq)
{
volatile unsigned char *icrp;
@@ -275,7 +275,7 @@ void ne2000_irqsetup(int irq)
}
#endif
-#if defined(CONFIG_M5206e) && defined(CONFIG_MOTOROLA)
+#if defined(CONFIG_M5206eC3)
void ne2000_irqsetup(int irq)
{
volatile unsigned char *icrp;
@@ -286,7 +286,7 @@ void ne2000_irqsetup(int irq)
}
#endif
-#if defined(CONFIG_M5206e) && defined(CONFIG_CFV240)
+#if defined(CONFIG_CFV240)
void ne2000_irqsetup(int irq)
{
volatile unsigned char *icrp;
diff --git a/include/asm-m68knommu/mcfpit.h b/include/asm-m68knommu/mcfpit.h
index 4cc2e9fd6ad0..a685f1b45401 100644
--- a/include/asm-m68knommu/mcfpit.h
+++ b/include/asm-m68knommu/mcfpit.h
@@ -14,13 +14,17 @@
#include <linux/config.h>
/*
- * Get address specific defines for the 5270/5271 and 5280/5282.
+ * Get address specific defines for the 5270/5271, 5280/5282, and 5208.
*/
+#if defined(CONFIG_M520x)
+#define MCFPIT_BASE1 0x00080000 /* Base address of TIMER1 */
+#define MCFPIT_BASE2 0x00084000 /* Base address of TIMER2 */
+#else
#define MCFPIT_BASE1 0x00150000 /* Base address of TIMER1 */
#define MCFPIT_BASE2 0x00160000 /* Base address of TIMER2 */
#define MCFPIT_BASE3 0x00170000 /* Base address of TIMER3 */
#define MCFPIT_BASE4 0x00180000 /* Base address of TIMER4 */
-
+#endif
/*
* Define the PIT timer register set addresses.
diff --git a/include/asm-m68knommu/mcfsim.h b/include/asm-m68knommu/mcfsim.h
index b0c7736f7a99..81d74a31dc43 100644
--- a/include/asm-m68knommu/mcfsim.h
+++ b/include/asm-m68knommu/mcfsim.h
@@ -22,6 +22,8 @@
#include <asm/m5204sim.h>
#elif defined(CONFIG_M5206) || defined(CONFIG_M5206e)
#include <asm/m5206sim.h>
+#elif defined(CONFIG_M520x)
+#include <asm/m520xsim.h>
#elif defined(CONFIG_M523x)
#include <asm/m523xsim.h>
#elif defined(CONFIG_M5249)
@@ -99,6 +101,19 @@
#define MCFSIM_IMR_MASKALL 0x3ffe /* All intr sources */
#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__
/*
diff --git a/include/asm-m68knommu/mcfuart.h b/include/asm-m68knommu/mcfuart.h
index 9c1210613bc7..b016fad83119 100644
--- a/include/asm-m68knommu/mcfuart.h
+++ b/include/asm-m68knommu/mcfuart.h
@@ -41,6 +41,10 @@
#define MCFUART_BASE1 0x1c0 /* Base address of UART1 */
#define MCFUART_BASE2 0x200 /* Base address of UART2 */
#endif
+#elif defined(CONFIG_M520x)
+#define MCFUART_BASE1 0x60000 /* Base address of UART1 */
+#define MCFUART_BASE2 0x64000 /* Base address of UART2 */
+#define MCFUART_BASE3 0x68000 /* Base address of UART2 */
#endif
diff --git a/include/asm-m68knommu/mcfwdebug.h b/include/asm-m68knommu/mcfwdebug.h
index c425dd568155..6ceae103596b 100644
--- a/include/asm-m68knommu/mcfwdebug.h
+++ b/include/asm-m68knommu/mcfwdebug.h
@@ -90,7 +90,7 @@
* that the debug module instructions (2 longs) must be long word aligned and
* some pointer fiddling is performed to ensure this.
*/
-extern inline void wdebug(int reg, unsigned long data) {
+static inline void wdebug(int reg, unsigned long data) {
unsigned short dbg_spc[6];
unsigned short *dbg;
diff --git a/include/asm-m68knommu/mmu_context.h b/include/asm-m68knommu/mmu_context.h
index 9bc0fd49b8aa..1e080eca9ca8 100644
--- a/include/asm-m68knommu/mmu_context.h
+++ b/include/asm-m68knommu/mmu_context.h
@@ -10,7 +10,7 @@ static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
{
}
-extern inline int
+static inline int
init_new_context(struct task_struct *tsk, struct mm_struct *mm)
{
// mm->context = virt_to_phys(mm->pgd);
@@ -25,7 +25,7 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, str
#define deactivate_mm(tsk,mm) do { } while (0)
-extern inline void activate_mm(struct mm_struct *prev_mm,
+static inline void activate_mm(struct mm_struct *prev_mm,
struct mm_struct *next_mm)
{
}
diff --git a/include/asm-m68knommu/processor.h b/include/asm-m68knommu/processor.h
index 85a054e758b1..ba393b1a023b 100644
--- a/include/asm-m68knommu/processor.h
+++ b/include/asm-m68knommu/processor.h
@@ -21,7 +21,7 @@
#include <asm/ptrace.h>
#include <asm/current.h>
-extern inline unsigned long rdusp(void)
+static inline unsigned long rdusp(void)
{
#ifdef CONFIG_COLDFIRE
extern unsigned int sw_usp;
@@ -33,7 +33,7 @@ extern inline unsigned long rdusp(void)
#endif
}
-extern inline void wrusp(unsigned long usp)
+static inline void wrusp(unsigned long usp)
{
#ifdef CONFIG_COLDFIRE
extern unsigned int sw_usp;
diff --git a/include/asm-m68knommu/semaphore.h b/include/asm-m68knommu/semaphore.h
index febe85add509..5cc1fdd86f50 100644
--- a/include/asm-m68knommu/semaphore.h
+++ b/include/asm-m68knommu/semaphore.h
@@ -35,16 +35,13 @@ struct semaphore {
.wait = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \
}
-#define __MUTEX_INITIALIZER(name) \
- __SEMAPHORE_INITIALIZER(name,1)
-
#define __DECLARE_SEMAPHORE_GENERIC(name,count) \
struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
#define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1)
#define DECLARE_MUTEX_LOCKED(name) __DECLARE_SEMAPHORE_GENERIC(name,0)
-extern inline void sema_init (struct semaphore *sem, int val)
+static inline void sema_init (struct semaphore *sem, int val)
{
*sem = (struct semaphore)__SEMAPHORE_INITIALIZER(*sem, val);
}
@@ -76,7 +73,7 @@ extern spinlock_t semaphore_wake_lock;
* "down_failed" is a special asm handler that calls the C
* routine that actually waits. See arch/m68k/lib/semaphore.S
*/
-extern inline void down(struct semaphore * sem)
+static inline void down(struct semaphore * sem)
{
might_sleep();
__asm__ __volatile__(
@@ -91,7 +88,7 @@ extern inline void down(struct semaphore * sem)
: "cc", "%a0", "%a1", "memory");
}
-extern inline int down_interruptible(struct semaphore * sem)
+static inline int down_interruptible(struct semaphore * sem)
{
int ret;
@@ -110,7 +107,7 @@ extern inline int down_interruptible(struct semaphore * sem)
return(ret);
}
-extern inline int down_trylock(struct semaphore * sem)
+static inline int down_trylock(struct semaphore * sem)
{
register struct semaphore *sem1 __asm__ ("%a1") = sem;
register int result __asm__ ("%d0");
@@ -138,7 +135,7 @@ extern inline int down_trylock(struct semaphore * sem)
* The default case (no contention) will result in NO
* jumps for both down() and up().
*/
-extern inline void up(struct semaphore * sem)
+static inline void up(struct semaphore * sem)
{
__asm__ __volatile__(
"| atomic up operation\n\t"
diff --git a/include/asm-m68knommu/system.h b/include/asm-m68knommu/system.h
index 53cbbad0f130..6338afc850ba 100644
--- a/include/asm-m68knommu/system.h
+++ b/include/asm-m68knommu/system.h
@@ -312,6 +312,19 @@ cmpxchg(volatile int *p, int old, int new)
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 short *)(MCF_IPSBAR + 0xA0000)); \
+ while(1) \
+ *reset |= 0x80; \
+})
#else
#define HARD_RESET_NOW() ({ \
asm(" \
diff --git a/include/asm-m68knommu/tlbflush.h b/include/asm-m68knommu/tlbflush.h
index bf7004e1afe0..de858db28b00 100644
--- a/include/asm-m68knommu/tlbflush.h
+++ b/include/asm-m68knommu/tlbflush.h
@@ -47,12 +47,12 @@ static inline void flush_tlb_range(struct mm_struct *mm,
BUG();
}
-extern inline void flush_tlb_kernel_page(unsigned long addr)
+static inline void flush_tlb_kernel_page(unsigned long addr)
{
BUG();
}
-extern inline void flush_tlb_pgtables(struct mm_struct *mm,
+static inline void flush_tlb_pgtables(struct mm_struct *mm,
unsigned long start, unsigned long end)
{
BUG();
diff --git a/include/asm-m68knommu/unistd.h b/include/asm-m68knommu/unistd.h
index 84b6fa14459f..5373988a7e51 100644
--- a/include/asm-m68knommu/unistd.h
+++ b/include/asm-m68knommu/unistd.h
@@ -504,7 +504,6 @@ asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
unsigned long fd, unsigned long pgoff);
asmlinkage int sys_execve(char *name, char **argv, char **envp);
asmlinkage int sys_pipe(unsigned long *fildes);
-asmlinkage int sys_ptrace(long request, long pid, long addr, long data);
struct pt_regs;
int sys_request_irq(unsigned int,
irqreturn_t (*)(int, void *, struct pt_regs *),
diff --git a/include/asm-mips/.gitignore b/include/asm-mips/.gitignore
new file mode 100644
index 000000000000..4ec57ad5bc3c
--- /dev/null
+++ b/include/asm-mips/.gitignore
@@ -0,0 +1 @@
+asm_offsets.h
diff --git a/include/asm-mips/abi.h b/include/asm-mips/abi.h
new file mode 100644
index 000000000000..2e7e651c3e3f
--- /dev/null
+++ b/include/asm-mips/abi.h
@@ -0,0 +1,25 @@
+/*
+ * 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 by Ralf Baechle
+ * Copyright (C) 2005 MIPS Technologies, Inc.
+ */
+#ifndef _ASM_ABI_H
+#define _ASM_ABI_H
+
+#include <asm/signal.h>
+#include <asm/siginfo.h>
+
+struct mips_abi {
+ int (* const do_signal)(sigset_t *oldset, struct pt_regs *regs);
+ int (* const setup_frame)(struct k_sigaction * ka,
+ struct pt_regs *regs, int signr,
+ sigset_t *set);
+ int (* const setup_rt_frame)(struct k_sigaction * ka,
+ struct pt_regs *regs, int signr,
+ sigset_t *set, siginfo_t *info);
+};
+
+#endif /* _ASM_ABI_H */
diff --git a/include/asm-mips/addrspace.h b/include/asm-mips/addrspace.h
index 7dc2619f5006..42520cc84b0f 100644
--- a/include/asm-mips/addrspace.h
+++ b/include/asm-mips/addrspace.h
@@ -20,10 +20,12 @@
#define _ATYPE_
#define _ATYPE32_
#define _ATYPE64_
+#define _LLCONST_(x) x
#else
#define _ATYPE_ __PTRDIFF_TYPE__
#define _ATYPE32_ int
#define _ATYPE64_ long long
+#define _LLCONST_(x) x ## LL
#endif
/*
@@ -45,8 +47,9 @@
/*
* Returns the physical address of a CKSEGx / XKPHYS address
*/
-#define CPHYSADDR(a) ((_ACAST32_ (a)) & 0x1fffffff)
-#define XPHYSADDR(a) ((_ACAST64_ (a)) & 0x000000ffffffffff)
+#define CPHYSADDR(a) ((_ACAST32_(a)) & 0x1fffffff)
+#define XPHYSADDR(a) ((_ACAST64_(a)) & \
+ _LLCONST_(0x000000ffffffffff))
#ifdef CONFIG_64BIT
@@ -55,14 +58,14 @@
* The compatibility segments use the full 64-bit sign extended value. Note
* the R8000 doesn't have them so don't reference these in generic MIPS code.
*/
-#define XKUSEG 0x0000000000000000
-#define XKSSEG 0x4000000000000000
-#define XKPHYS 0x8000000000000000
-#define XKSEG 0xc000000000000000
-#define CKSEG0 0xffffffff80000000
-#define CKSEG1 0xffffffffa0000000
-#define CKSSEG 0xffffffffc0000000
-#define CKSEG3 0xffffffffe0000000
+#define XKUSEG _LLCONST_(0x0000000000000000)
+#define XKSSEG _LLCONST_(0x4000000000000000)
+#define XKPHYS _LLCONST_(0x8000000000000000)
+#define XKSEG _LLCONST_(0xc000000000000000)
+#define CKSEG0 _LLCONST_(0xffffffff80000000)
+#define CKSEG1 _LLCONST_(0xffffffffa0000000)
+#define CKSSEG _LLCONST_(0xffffffffc0000000)
+#define CKSEG3 _LLCONST_(0xffffffffe0000000)
#define CKSEG0ADDR(a) (CPHYSADDR(a) | CKSEG0)
#define CKSEG1ADDR(a) (CPHYSADDR(a) | CKSEG1)
@@ -120,7 +123,8 @@
#define PHYS_TO_XKSEG_UNCACHED(p) PHYS_TO_XKPHYS(K_CALG_UNCACHED,(p))
#define PHYS_TO_XKSEG_CACHED(p) PHYS_TO_XKPHYS(K_CALG_COH_SHAREABLE,(p))
#define XKPHYS_TO_PHYS(p) ((p) & TO_PHYS_MASK)
-#define PHYS_TO_XKPHYS(cm,a) (0x8000000000000000 | ((cm)<<59) | (a))
+#define PHYS_TO_XKPHYS(cm,a) (_LLCONST_(0x8000000000000000) | \
+ ((cm)<<59) | (a))
#if defined (CONFIG_CPU_R4300) \
|| defined (CONFIG_CPU_R4X00) \
@@ -128,46 +132,56 @@
|| defined (CONFIG_CPU_NEVADA) \
|| defined (CONFIG_CPU_TX49XX) \
|| defined (CONFIG_CPU_MIPS64)
-#define KUSIZE 0x0000010000000000 /* 2^^40 */
-#define KUSIZE_64 0x0000010000000000 /* 2^^40 */
-#define K0SIZE 0x0000001000000000 /* 2^^36 */
-#define K1SIZE 0x0000001000000000 /* 2^^36 */
-#define K2SIZE 0x000000ff80000000
-#define KSEGSIZE 0x000000ff80000000 /* max syssegsz */
-#define TO_PHYS_MASK 0x0000000fffffffff /* 2^^36 - 1 */
+#define KUSIZE _LLCONST_(0x0000010000000000) /* 2^^40 */
+#define KUSIZE_64 _LLCONST_(0x0000010000000000) /* 2^^40 */
+#define K0SIZE _LLCONST_(0x0000001000000000) /* 2^^36 */
+#define K1SIZE _LLCONST_(0x0000001000000000) /* 2^^36 */
+#define K2SIZE _LLCONST_(0x000000ff80000000)
+#define KSEGSIZE _LLCONST_(0x000000ff80000000) /* max syssegsz */
+#define TO_PHYS_MASK _LLCONST_(0x0000000fffffffff) /* 2^^36 - 1 */
#endif
#if defined (CONFIG_CPU_R8000)
/* We keep KUSIZE consistent with R4000 for now (2^^40) instead of (2^^48) */
-#define KUSIZE 0x0000010000000000 /* 2^^40 */
-#define KUSIZE_64 0x0000010000000000 /* 2^^40 */
-#define K0SIZE 0x0000010000000000 /* 2^^40 */
-#define K1SIZE 0x0000010000000000 /* 2^^40 */
-#define K2SIZE 0x0001000000000000
-#define KSEGSIZE 0x0000010000000000 /* max syssegsz */
-#define TO_PHYS_MASK 0x000000ffffffffff /* 2^^40 - 1 */
+#define KUSIZE _LLCONST_(0x0000010000000000) /* 2^^40 */
+#define KUSIZE_64 _LLCONST_(0x0000010000000000) /* 2^^40 */
+#define K0SIZE _LLCONST_(0x0000010000000000) /* 2^^40 */
+#define K1SIZE _LLCONST_(0x0000010000000000) /* 2^^40 */
+#define K2SIZE _LLCONST_(0x0001000000000000)
+#define KSEGSIZE _LLCONST_(0x0000010000000000) /* max syssegsz */
+#define TO_PHYS_MASK _LLCONST_(0x000000ffffffffff) /* 2^^40 - 1 */
#endif
#if defined (CONFIG_CPU_R10000)
-#define KUSIZE 0x0000010000000000 /* 2^^40 */
-#define KUSIZE_64 0x0000010000000000 /* 2^^40 */
-#define K0SIZE 0x0000010000000000 /* 2^^40 */
-#define K1SIZE 0x0000010000000000 /* 2^^40 */
-#define K2SIZE 0x00000fff80000000
-#define KSEGSIZE 0x00000fff80000000 /* max syssegsz */
-#define TO_PHYS_MASK 0x000000ffffffffff /* 2^^40 - 1 */
+#define KUSIZE _LLCONST_(0x0000010000000000) /* 2^^40 */
+#define KUSIZE_64 _LLCONST_(0x0000010000000000) /* 2^^40 */
+#define K0SIZE _LLCONST_(0x0000010000000000) /* 2^^40 */
+#define K1SIZE _LLCONST_(0x0000010000000000) /* 2^^40 */
+#define K2SIZE _LLCONST_(0x00000fff80000000)
+#define KSEGSIZE _LLCONST_(0x00000fff80000000) /* max syssegsz */
+#define TO_PHYS_MASK _LLCONST_(0x000000ffffffffff) /* 2^^40 - 1 */
+#endif
+
+#if defined(CONFIG_CPU_SB1) || defined(CONFIG_CPU_SB1A)
+#define KUSIZE _LLCONST_(0x0000100000000000) /* 2^^44 */
+#define KUSIZE_64 _LLCONST_(0x0000100000000000) /* 2^^44 */
+#define K0SIZE _LLCONST_(0x0000100000000000) /* 2^^44 */
+#define K1SIZE _LLCONST_(0x0000100000000000) /* 2^^44 */
+#define K2SIZE _LLCONST_(0x0000ffff80000000)
+#define KSEGSIZE _LLCONST_(0x0000ffff80000000) /* max syssegsz */
+#define TO_PHYS_MASK _LLCONST_(0x00000fffffffffff) /* 2^^44 - 1 */
#endif
/*
* Further names for SGI source compatibility. These are stolen from
* IRIX's <sys/mips_addrspace.h>.
*/
-#define KUBASE 0
-#define KUSIZE_32 0x0000000080000000 /* KUSIZE
+#define KUBASE _LLCONST_(0)
+#define KUSIZE_32 _LLCONST_(0x0000000080000000) /* KUSIZE
for a 32 bit proc */
-#define K0BASE_EXL_WR 0xa800000000000000 /* exclusive on write */
-#define K0BASE_NONCOH 0x9800000000000000 /* noncoherent */
-#define K0BASE_EXL 0xa000000000000000 /* exclusive */
+#define K0BASE_EXL_WR _LLCONST_(0xa800000000000000) /* exclusive on write */
+#define K0BASE_NONCOH _LLCONST_(0x9800000000000000) /* noncoherent */
+#define K0BASE_EXL _LLCONST_(0xa000000000000000) /* exclusive */
#ifndef CONFIG_CPU_R8000
@@ -176,7 +190,7 @@
* in order to catch bugs in the source code.
*/
-#define COMPAT_K1BASE32 0xffffffffa0000000
+#define COMPAT_K1BASE32 _LLCONST_(0xffffffffa0000000)
#define PHYS_TO_COMPATK1(x) ((x) | COMPAT_K1BASE32) /* 32-bit compat k1 */
#endif
diff --git a/include/asm-mips/asm.h b/include/asm-mips/asm.h
index f53237772985..4b090f3142e0 100644
--- a/include/asm-mips/asm.h
+++ b/include/asm-mips/asm.h
@@ -107,6 +107,7 @@ symbol = value
/*
* Print formatted string
*/
+#ifdef CONFIG_PRINTK
#define PRINT(string) \
.set push; \
.set reorder; \
@@ -114,6 +115,9 @@ symbol = value
jal printk; \
.set pop; \
TEXT(string)
+#else
+#define PRINT(string)
+#endif
#define TEXT(msg) \
.pushsection .data; \
diff --git a/include/asm-mips/atomic.h b/include/asm-mips/atomic.h
index c0bd8d014e14..6202eb8a14b7 100644
--- a/include/asm-mips/atomic.h
+++ b/include/asm-mips/atomic.h
@@ -62,20 +62,24 @@ static __inline__ void atomic_add(int i, atomic_t * v)
unsigned long temp;
__asm__ __volatile__(
+ " .set mips3 \n"
"1: ll %0, %1 # atomic_add \n"
" addu %0, %2 \n"
" sc %0, %1 \n"
" beqzl %0, 1b \n"
+ " .set mips0 \n"
: "=&r" (temp), "=m" (v->counter)
: "Ir" (i), "m" (v->counter));
} else if (cpu_has_llsc) {
unsigned long temp;
__asm__ __volatile__(
+ " .set mips3 \n"
"1: ll %0, %1 # atomic_add \n"
" addu %0, %2 \n"
" sc %0, %1 \n"
" beqz %0, 1b \n"
+ " .set mips0 \n"
: "=&r" (temp), "=m" (v->counter)
: "Ir" (i), "m" (v->counter));
} else {
@@ -100,20 +104,24 @@ static __inline__ void atomic_sub(int i, atomic_t * v)
unsigned long temp;
__asm__ __volatile__(
+ " .set mips3 \n"
"1: ll %0, %1 # atomic_sub \n"
" subu %0, %2 \n"
" sc %0, %1 \n"
" beqzl %0, 1b \n"
+ " .set mips0 \n"
: "=&r" (temp), "=m" (v->counter)
: "Ir" (i), "m" (v->counter));
} else if (cpu_has_llsc) {
unsigned long temp;
__asm__ __volatile__(
+ " .set mips3 \n"
"1: ll %0, %1 # atomic_sub \n"
" subu %0, %2 \n"
" sc %0, %1 \n"
" beqz %0, 1b \n"
+ " .set mips0 \n"
: "=&r" (temp), "=m" (v->counter)
: "Ir" (i), "m" (v->counter));
} else {
@@ -136,12 +144,14 @@ static __inline__ int atomic_add_return(int i, atomic_t * v)
unsigned long temp;
__asm__ __volatile__(
+ " .set mips3 \n"
"1: ll %1, %2 # atomic_add_return \n"
" addu %0, %1, %3 \n"
" sc %0, %2 \n"
" beqzl %0, 1b \n"
" addu %0, %1, %3 \n"
" sync \n"
+ " .set mips0 \n"
: "=&r" (result), "=&r" (temp), "=m" (v->counter)
: "Ir" (i), "m" (v->counter)
: "memory");
@@ -149,12 +159,14 @@ static __inline__ int atomic_add_return(int i, atomic_t * v)
unsigned long temp;
__asm__ __volatile__(
+ " .set mips3 \n"
"1: ll %1, %2 # atomic_add_return \n"
" addu %0, %1, %3 \n"
" sc %0, %2 \n"
" beqz %0, 1b \n"
" addu %0, %1, %3 \n"
" sync \n"
+ " .set mips0 \n"
: "=&r" (result), "=&r" (temp), "=m" (v->counter)
: "Ir" (i), "m" (v->counter)
: "memory");
@@ -179,12 +191,14 @@ static __inline__ int atomic_sub_return(int i, atomic_t * v)
unsigned long temp;
__asm__ __volatile__(
+ " .set mips3 \n"
"1: ll %1, %2 # atomic_sub_return \n"
" subu %0, %1, %3 \n"
" sc %0, %2 \n"
" beqzl %0, 1b \n"
" subu %0, %1, %3 \n"
" sync \n"
+ " .set mips0 \n"
: "=&r" (result), "=&r" (temp), "=m" (v->counter)
: "Ir" (i), "m" (v->counter)
: "memory");
@@ -192,12 +206,14 @@ static __inline__ int atomic_sub_return(int i, atomic_t * v)
unsigned long temp;
__asm__ __volatile__(
+ " .set mips3 \n"
"1: ll %1, %2 # atomic_sub_return \n"
" subu %0, %1, %3 \n"
" sc %0, %2 \n"
" beqz %0, 1b \n"
" subu %0, %1, %3 \n"
" sync \n"
+ " .set mips0 \n"
: "=&r" (result), "=&r" (temp), "=m" (v->counter)
: "Ir" (i), "m" (v->counter)
: "memory");
@@ -229,6 +245,7 @@ static __inline__ int atomic_sub_if_positive(int i, atomic_t * v)
unsigned long temp;
__asm__ __volatile__(
+ " .set mips3 \n"
"1: ll %1, %2 # atomic_sub_if_positive\n"
" subu %0, %1, %3 \n"
" bltz %0, 1f \n"
@@ -236,6 +253,7 @@ static __inline__ int atomic_sub_if_positive(int i, atomic_t * v)
" beqzl %0, 1b \n"
" sync \n"
"1: \n"
+ " .set mips0 \n"
: "=&r" (result), "=&r" (temp), "=m" (v->counter)
: "Ir" (i), "m" (v->counter)
: "memory");
@@ -243,6 +261,7 @@ static __inline__ int atomic_sub_if_positive(int i, atomic_t * v)
unsigned long temp;
__asm__ __volatile__(
+ " .set mips3 \n"
"1: ll %1, %2 # atomic_sub_if_positive\n"
" subu %0, %1, %3 \n"
" bltz %0, 1f \n"
@@ -250,6 +269,7 @@ static __inline__ int atomic_sub_if_positive(int i, atomic_t * v)
" beqz %0, 1b \n"
" sync \n"
"1: \n"
+ " .set mips0 \n"
: "=&r" (result), "=&r" (temp), "=m" (v->counter)
: "Ir" (i), "m" (v->counter)
: "memory");
@@ -367,20 +387,24 @@ static __inline__ void atomic64_add(long i, atomic64_t * v)
unsigned long temp;
__asm__ __volatile__(
+ " .set mips3 \n"
"1: lld %0, %1 # atomic64_add \n"
" addu %0, %2 \n"
" scd %0, %1 \n"
" beqzl %0, 1b \n"
+ " .set mips0 \n"
: "=&r" (temp), "=m" (v->counter)
: "Ir" (i), "m" (v->counter));
} else if (cpu_has_llsc) {
unsigned long temp;
__asm__ __volatile__(
+ " .set mips3 \n"
"1: lld %0, %1 # atomic64_add \n"
" addu %0, %2 \n"
" scd %0, %1 \n"
" beqz %0, 1b \n"
+ " .set mips0 \n"
: "=&r" (temp), "=m" (v->counter)
: "Ir" (i), "m" (v->counter));
} else {
@@ -405,20 +429,24 @@ static __inline__ void atomic64_sub(long i, atomic64_t * v)
unsigned long temp;
__asm__ __volatile__(
+ " .set mips3 \n"
"1: lld %0, %1 # atomic64_sub \n"
" subu %0, %2 \n"
" scd %0, %1 \n"
" beqzl %0, 1b \n"
+ " .set mips0 \n"
: "=&r" (temp), "=m" (v->counter)
: "Ir" (i), "m" (v->counter));
} else if (cpu_has_llsc) {
unsigned long temp;
__asm__ __volatile__(
+ " .set mips3 \n"
"1: lld %0, %1 # atomic64_sub \n"
" subu %0, %2 \n"
" scd %0, %1 \n"
" beqz %0, 1b \n"
+ " .set mips0 \n"
: "=&r" (temp), "=m" (v->counter)
: "Ir" (i), "m" (v->counter));
} else {
@@ -441,12 +469,14 @@ static __inline__ long atomic64_add_return(long i, atomic64_t * v)
unsigned long temp;
__asm__ __volatile__(
+ " .set mips3 \n"
"1: lld %1, %2 # atomic64_add_return \n"
" addu %0, %1, %3 \n"
" scd %0, %2 \n"
" beqzl %0, 1b \n"
" addu %0, %1, %3 \n"
" sync \n"
+ " .set mips0 \n"
: "=&r" (result), "=&r" (temp), "=m" (v->counter)
: "Ir" (i), "m" (v->counter)
: "memory");
@@ -454,12 +484,14 @@ static __inline__ long atomic64_add_return(long i, atomic64_t * v)
unsigned long temp;
__asm__ __volatile__(
+ " .set mips3 \n"
"1: lld %1, %2 # atomic64_add_return \n"
" addu %0, %1, %3 \n"
" scd %0, %2 \n"
" beqz %0, 1b \n"
" addu %0, %1, %3 \n"
" sync \n"
+ " .set mips0 \n"
: "=&r" (result), "=&r" (temp), "=m" (v->counter)
: "Ir" (i), "m" (v->counter)
: "memory");
@@ -484,12 +516,14 @@ static __inline__ long atomic64_sub_return(long i, atomic64_t * v)
unsigned long temp;
__asm__ __volatile__(
+ " .set mips3 \n"
"1: lld %1, %2 # atomic64_sub_return \n"
" subu %0, %1, %3 \n"
" scd %0, %2 \n"
" beqzl %0, 1b \n"
" subu %0, %1, %3 \n"
" sync \n"
+ " .set mips0 \n"
: "=&r" (result), "=&r" (temp), "=m" (v->counter)
: "Ir" (i), "m" (v->counter)
: "memory");
@@ -497,12 +531,14 @@ static __inline__ long atomic64_sub_return(long i, atomic64_t * v)
unsigned long temp;
__asm__ __volatile__(
+ " .set mips3 \n"
"1: lld %1, %2 # atomic64_sub_return \n"
" subu %0, %1, %3 \n"
" scd %0, %2 \n"
" beqz %0, 1b \n"
" subu %0, %1, %3 \n"
" sync \n"
+ " .set mips0 \n"
: "=&r" (result), "=&r" (temp), "=m" (v->counter)
: "Ir" (i), "m" (v->counter)
: "memory");
@@ -534,6 +570,7 @@ static __inline__ long atomic64_sub_if_positive(long i, atomic64_t * v)
unsigned long temp;
__asm__ __volatile__(
+ " .set mips3 \n"
"1: lld %1, %2 # atomic64_sub_if_positive\n"
" dsubu %0, %1, %3 \n"
" bltz %0, 1f \n"
@@ -541,6 +578,7 @@ static __inline__ long atomic64_sub_if_positive(long i, atomic64_t * v)
" beqzl %0, 1b \n"
" sync \n"
"1: \n"
+ " .set mips0 \n"
: "=&r" (result), "=&r" (temp), "=m" (v->counter)
: "Ir" (i), "m" (v->counter)
: "memory");
@@ -548,6 +586,7 @@ static __inline__ long atomic64_sub_if_positive(long i, atomic64_t * v)
unsigned long temp;
__asm__ __volatile__(
+ " .set mips3 \n"
"1: lld %1, %2 # atomic64_sub_if_positive\n"
" dsubu %0, %1, %3 \n"
" bltz %0, 1f \n"
@@ -555,6 +594,7 @@ static __inline__ long atomic64_sub_if_positive(long i, atomic64_t * v)
" beqz %0, 1b \n"
" sync \n"
"1: \n"
+ " .set mips0 \n"
: "=&r" (result), "=&r" (temp), "=m" (v->counter)
: "Ir" (i), "m" (v->counter)
: "memory");
diff --git a/include/asm-mips/bitops.h b/include/asm-mips/bitops.h
index eb8d79dba11c..5496f9064a6a 100644
--- a/include/asm-mips/bitops.h
+++ b/include/asm-mips/bitops.h
@@ -12,20 +12,21 @@
#include <linux/config.h>
#include <linux/compiler.h>
#include <linux/types.h>
+#include <asm/bug.h>
#include <asm/byteorder.h> /* sigh ... */
#include <asm/cpu-features.h>
#if (_MIPS_SZLONG == 32)
#define SZLONG_LOG 5
#define SZLONG_MASK 31UL
-#define __LL "ll "
-#define __SC "sc "
+#define __LL "ll "
+#define __SC "sc "
#define cpu_to_lelongp(x) cpu_to_le32p((__u32 *) (x))
#elif (_MIPS_SZLONG == 64)
#define SZLONG_LOG 6
#define SZLONG_MASK 63UL
-#define __LL "lld "
-#define __SC "scd "
+#define __LL "lld "
+#define __SC "scd "
#define cpu_to_lelongp(x) cpu_to_le64p((__u64 *) (x))
#endif
@@ -72,18 +73,22 @@ static inline void set_bit(unsigned long nr, volatile unsigned long *addr)
if (cpu_has_llsc && R10000_LLSC_WAR) {
__asm__ __volatile__(
+ " .set mips3 \n"
"1: " __LL "%0, %1 # set_bit \n"
" or %0, %2 \n"
- " "__SC "%0, %1 \n"
+ " " __SC "%0, %1 \n"
" beqzl %0, 1b \n"
+ " .set mips0 \n"
: "=&r" (temp), "=m" (*m)
: "ir" (1UL << (nr & SZLONG_MASK)), "m" (*m));
} else if (cpu_has_llsc) {
__asm__ __volatile__(
+ " .set mips3 \n"
"1: " __LL "%0, %1 # set_bit \n"
" or %0, %2 \n"
- " "__SC "%0, %1 \n"
+ " " __SC "%0, %1 \n"
" beqz %0, 1b \n"
+ " .set mips0 \n"
: "=&r" (temp), "=m" (*m)
: "ir" (1UL << (nr & SZLONG_MASK)), "m" (*m));
} else {
@@ -132,18 +137,22 @@ static inline void clear_bit(unsigned long nr, volatile unsigned long *addr)
if (cpu_has_llsc && R10000_LLSC_WAR) {
__asm__ __volatile__(
+ " .set mips3 \n"
"1: " __LL "%0, %1 # clear_bit \n"
" and %0, %2 \n"
" " __SC "%0, %1 \n"
" beqzl %0, 1b \n"
+ " .set mips0 \n"
: "=&r" (temp), "=m" (*m)
: "ir" (~(1UL << (nr & SZLONG_MASK))), "m" (*m));
} else if (cpu_has_llsc) {
__asm__ __volatile__(
+ " .set mips3 \n"
"1: " __LL "%0, %1 # clear_bit \n"
" and %0, %2 \n"
" " __SC "%0, %1 \n"
" beqz %0, 1b \n"
+ " .set mips0 \n"
: "=&r" (temp), "=m" (*m)
: "ir" (~(1UL << (nr & SZLONG_MASK))), "m" (*m));
} else {
@@ -191,10 +200,12 @@ static inline void change_bit(unsigned long nr, volatile unsigned long *addr)
unsigned long temp;
__asm__ __volatile__(
+ " .set mips3 \n"
"1: " __LL "%0, %1 # change_bit \n"
" xor %0, %2 \n"
- " "__SC "%0, %1 \n"
+ " " __SC "%0, %1 \n"
" beqzl %0, 1b \n"
+ " .set mips0 \n"
: "=&r" (temp), "=m" (*m)
: "ir" (1UL << (nr & SZLONG_MASK)), "m" (*m));
} else if (cpu_has_llsc) {
@@ -202,10 +213,12 @@ static inline void change_bit(unsigned long nr, volatile unsigned long *addr)
unsigned long temp;
__asm__ __volatile__(
+ " .set mips3 \n"
"1: " __LL "%0, %1 # change_bit \n"
" xor %0, %2 \n"
- " "__SC "%0, %1 \n"
+ " " __SC "%0, %1 \n"
" beqz %0, 1b \n"
+ " .set mips0 \n"
: "=&r" (temp), "=m" (*m)
: "ir" (1UL << (nr & SZLONG_MASK)), "m" (*m));
} else {
@@ -253,14 +266,16 @@ static inline int test_and_set_bit(unsigned long nr,
unsigned long temp, res;
__asm__ __volatile__(
+ " .set mips3 \n"
"1: " __LL "%0, %1 # test_and_set_bit \n"
" or %2, %0, %3 \n"
" " __SC "%2, %1 \n"
" beqzl %2, 1b \n"
" and %2, %0, %3 \n"
#ifdef CONFIG_SMP
- "sync \n"
+ " sync \n"
#endif
+ " .set mips0 \n"
: "=&r" (temp), "=m" (*m), "=&r" (res)
: "r" (1UL << (nr & SZLONG_MASK)), "m" (*m)
: "memory");
@@ -271,16 +286,18 @@ static inline int test_and_set_bit(unsigned long nr,
unsigned long temp, res;
__asm__ __volatile__(
- " .set noreorder # test_and_set_bit \n"
- "1: " __LL "%0, %1 \n"
+ " .set push \n"
+ " .set noreorder \n"
+ " .set mips3 \n"
+ "1: " __LL "%0, %1 # test_and_set_bit \n"
" or %2, %0, %3 \n"
" " __SC "%2, %1 \n"
" beqz %2, 1b \n"
" and %2, %0, %3 \n"
#ifdef CONFIG_SMP
- "sync \n"
+ " sync \n"
#endif
- ".set\treorder"
+ " .set pop \n"
: "=&r" (temp), "=m" (*m), "=&r" (res)
: "r" (1UL << (nr & SZLONG_MASK)), "m" (*m)
: "memory");
@@ -343,15 +360,17 @@ static inline int test_and_clear_bit(unsigned long nr,
unsigned long temp, res;
__asm__ __volatile__(
+ " .set mips3 \n"
"1: " __LL "%0, %1 # test_and_clear_bit \n"
" or %2, %0, %3 \n"
" xor %2, %3 \n"
- __SC "%2, %1 \n"
+ " " __SC "%2, %1 \n"
" beqzl %2, 1b \n"
" and %2, %0, %3 \n"
#ifdef CONFIG_SMP
" sync \n"
#endif
+ " .set mips0 \n"
: "=&r" (temp), "=m" (*m), "=&r" (res)
: "r" (1UL << (nr & SZLONG_MASK)), "m" (*m)
: "memory");
@@ -362,17 +381,19 @@ static inline int test_and_clear_bit(unsigned long nr,
unsigned long temp, res;
__asm__ __volatile__(
- " .set noreorder # test_and_clear_bit \n"
- "1: " __LL "%0, %1 \n"
+ " .set push \n"
+ " .set noreorder \n"
+ " .set mips3 \n"
+ "1: " __LL "%0, %1 # test_and_clear_bit \n"
" or %2, %0, %3 \n"
" xor %2, %3 \n"
- __SC "%2, %1 \n"
+ " " __SC "%2, %1 \n"
" beqz %2, 1b \n"
" and %2, %0, %3 \n"
#ifdef CONFIG_SMP
" sync \n"
#endif
- " .set reorder \n"
+ " .set pop \n"
: "=&r" (temp), "=m" (*m), "=&r" (res)
: "r" (1UL << (nr & SZLONG_MASK)), "m" (*m)
: "memory");
@@ -435,14 +456,16 @@ static inline int test_and_change_bit(unsigned long nr,
unsigned long temp, res;
__asm__ __volatile__(
- "1: " __LL " %0, %1 # test_and_change_bit \n"
+ " .set mips3 \n"
+ "1: " __LL "%0, %1 # test_and_change_bit \n"
" xor %2, %0, %3 \n"
- " "__SC "%2, %1 \n"
+ " " __SC "%2, %1 \n"
" beqzl %2, 1b \n"
" and %2, %0, %3 \n"
#ifdef CONFIG_SMP
" sync \n"
#endif
+ " .set mips0 \n"
: "=&r" (temp), "=m" (*m), "=&r" (res)
: "r" (1UL << (nr & SZLONG_MASK)), "m" (*m)
: "memory");
@@ -453,16 +476,18 @@ static inline int test_and_change_bit(unsigned long nr,
unsigned long temp, res;
__asm__ __volatile__(
- " .set noreorder # test_and_change_bit \n"
- "1: " __LL " %0, %1 \n"
+ " .set push \n"
+ " .set noreorder \n"
+ " .set mips3 \n"
+ "1: " __LL "%0, %1 # test_and_change_bit \n"
" xor %2, %0, %3 \n"
- " "__SC "\t%2, %1 \n"
+ " " __SC "\t%2, %1 \n"
" beqz %2, 1b \n"
" and %2, %0, %3 \n"
#ifdef CONFIG_SMP
" sync \n"
#endif
- " .set reorder \n"
+ " .set pop \n"
: "=&r" (temp), "=m" (*m), "=&r" (res)
: "r" (1UL << (nr & SZLONG_MASK)), "m" (*m)
: "memory");
@@ -523,22 +548,60 @@ static inline int test_bit(unsigned long nr, const volatile unsigned long *addr)
}
/*
- * ffz - find first zero in word.
+ * Return the bit position (0..63) of the most significant 1 bit in a word
+ * Returns -1 if no 1 bit exists
+ */
+static inline int __ilog2(unsigned long x)
+{
+ int lz;
+
+ if (sizeof(x) == 4) {
+ __asm__ (
+ " .set push \n"
+ " .set mips32 \n"
+ " clz %0, %1 \n"
+ " .set pop \n"
+ : "=r" (lz)
+ : "r" (x));
+
+ return 31 - lz;
+ }
+
+ BUG_ON(sizeof(x) != 8);
+
+ __asm__ (
+ " .set push \n"
+ " .set mips64 \n"
+ " dclz %0, %1 \n"
+ " .set pop \n"
+ : "=r" (lz)
+ : "r" (x));
+
+ return 63 - lz;
+}
+
+/*
+ * __ffs - find first bit in word.
* @word: The word to search
*
- * Undefined if no zero exists, so code should check against ~0UL first.
+ * Returns 0..SZLONG-1
+ * Undefined if no bit exists, so code should check against 0 first.
*/
-static inline unsigned long ffz(unsigned long word)
+static inline unsigned long __ffs(unsigned long word)
{
+#if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64)
+ return __ilog2(word & -word);
+#else
int b = 0, s;
- word = ~word;
#ifdef CONFIG_32BIT
s = 16; if (word << 16 != 0) s = 0; b += s; word >>= s;
s = 8; if (word << 24 != 0) s = 0; b += s; word >>= s;
s = 4; if (word << 28 != 0) s = 0; b += s; word >>= s;
s = 2; if (word << 30 != 0) s = 0; b += s; word >>= s;
s = 1; if (word << 31 != 0) s = 0; b += s;
+
+ return b;
#endif
#ifdef CONFIG_64BIT
s = 32; if (word << 32 != 0) s = 0; b += s; word >>= s;
@@ -547,27 +610,92 @@ static inline unsigned long ffz(unsigned long word)
s = 4; if (word << 60 != 0) s = 0; b += s; word >>= s;
s = 2; if (word << 62 != 0) s = 0; b += s; word >>= s;
s = 1; if (word << 63 != 0) s = 0; b += s;
-#endif
return b;
+#endif
+#endif
}
/*
- * __ffs - find first bit in word.
+ * ffs - find first bit set.
* @word: The word to search
*
- * Undefined if no bit exists, so code should check against 0 first.
+ * Returns 1..SZLONG
+ * Returns 0 if no bit exists
*/
-static inline unsigned long __ffs(unsigned long word)
+
+static inline unsigned long ffs(unsigned long word)
{
- return ffz(~word);
+ if (!word)
+ return 0;
+
+ return __ffs(word) + 1;
}
/*
- * fls: find last bit set.
+ * ffz - find first zero in word.
+ * @word: The word to search
+ *
+ * Undefined if no zero exists, so code should check against ~0UL first.
+ */
+static inline unsigned long ffz(unsigned long word)
+{
+ return __ffs (~word);
+}
+
+/*
+ * flz - find last zero in word.
+ * @word: The word to search
+ *
+ * Returns 0..SZLONG-1
+ * Undefined if no zero exists, so code should check against ~0UL first.
+ */
+static inline unsigned long flz(unsigned long word)
+{
+#if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64)
+ return __ilog2(~word);
+#else
+#ifdef CONFIG_32BIT
+ int r = 31, s;
+ word = ~word;
+ s = 16; if ((word & 0xffff0000)) s = 0; r -= s; word <<= s;
+ s = 8; if ((word & 0xff000000)) s = 0; r -= s; word <<= s;
+ s = 4; if ((word & 0xf0000000)) s = 0; r -= s; word <<= s;
+ s = 2; if ((word & 0xc0000000)) s = 0; r -= s; word <<= s;
+ s = 1; if ((word & 0x80000000)) s = 0; r -= s;
+
+ return r;
+#endif
+#ifdef CONFIG_64BIT
+ int r = 63, s;
+ word = ~word;
+ s = 32; if ((word & 0xffffffff00000000UL)) s = 0; r -= s; word <<= s;
+ s = 16; if ((word & 0xffff000000000000UL)) s = 0; r -= s; word <<= s;
+ s = 8; if ((word & 0xff00000000000000UL)) s = 0; r -= s; word <<= s;
+ s = 4; if ((word & 0xf000000000000000UL)) s = 0; r -= s; word <<= s;
+ s = 2; if ((word & 0xc000000000000000UL)) s = 0; r -= s; word <<= s;
+ s = 1; if ((word & 0x8000000000000000UL)) s = 0; r -= s;
+
+ return r;
+#endif
+#endif
+}
+
+/*
+ * fls - find last bit set.
+ * @word: The word to search
+ *
+ * Returns 1..SZLONG
+ * Returns 0 if no bit exists
*/
+static inline unsigned long fls(unsigned long word)
+{
+ if (word == 0)
+ return 0;
+
+ return flz(~word) + 1;
+}
-#define fls(x) generic_fls(x)
/*
* find_next_zero_bit - find the first zero bit in a memory region
@@ -704,17 +832,6 @@ static inline int sched_find_first_bit(const unsigned long *b)
}
/*
- * ffs - find first bit set
- * @x: the word to search
- *
- * This is defined the same way as
- * the libc and compiler builtin ffs routines, therefore
- * differs in spirit from the above ffz (man ffs).
- */
-
-#define ffs(x) generic_ffs(x)
-
-/*
* hweightN - returns the hamming weight of a N-bit word
* @x: the word to weigh
*
diff --git a/include/asm-mips/bootinfo.h b/include/asm-mips/bootinfo.h
index b1e57d783604..14fc88f27226 100644
--- a/include/asm-mips/bootinfo.h
+++ b/include/asm-mips/bootinfo.h
@@ -77,6 +77,7 @@
#define MACH_SGI_IP27 1 /* Origin 200, Origin 2000, Onyx 2 */
#define MACH_SGI_IP28 2 /* Indigo2 Impact */
#define MACH_SGI_IP32 3 /* O2 */
+#define MACH_SGI_IP30 4 /* Octane, Octane2 */
/*
* Valid machtype for group COBALT
@@ -136,6 +137,7 @@
#define MACH_GROUP_PHILIPS 14
#define MACH_PHILIPS_NINO 0 /* Nino */
#define MACH_PHILIPS_VELO 1 /* Velo */
+#define MACH_PHILIPS_JBS 2 /* JBS */
/*
* Valid machtype for group Globespan
@@ -159,6 +161,7 @@
#define MACH_TOSHIBA_JMR3927 3 /* JMR-TX3927 CPU/IO board */
#define MACH_TOSHIBA_RBTX4927 4
#define MACH_TOSHIBA_RBTX4937 5
+#define MACH_TOSHIBA_RBTX4938 6
#define GROUP_TOSHIBA_NAMES { "Pallas", "TopasCE", "JMR", "JMR TX3927", \
"RBTX4927", "RBTX4937" }
@@ -177,6 +180,8 @@
#define MACH_MTX1 7 /* 4G MTX-1 Au1500-based board */
#define MACH_PB1550 8 /* Au1550-based eval board */
#define MACH_DB1550 9 /* Au1550-based eval board */
+#define MACH_PB1200 10 /* Au1200-based eval board */
+#define MACH_DB1200 11 /* Au1200-based eval board */
/*
* Valid machtype for group NEC_VR41XX
diff --git a/include/asm-mips/break.h b/include/asm-mips/break.h
index 2e6de788f207..25b980c91e7e 100644
--- a/include/asm-mips/break.h
+++ b/include/asm-mips/break.h
@@ -28,6 +28,7 @@
#define BRK_NORLD 10 /* No rld found - not used by Linux/MIPS */
#define _BRK_THREADBP 11 /* For threads, user bp (used by debuggers) */
#define BRK_BUG 512 /* Used by BUG() */
+#define BRK_KDB 513 /* Used in KDB_ENTER() */
#define BRK_MULOVF 1023 /* Multiply overflow */
#endif /* __ASM_BREAK_H */
diff --git a/include/asm-mips/bug.h b/include/asm-mips/bug.h
index 3f594b440abc..87d49a5bdc63 100644
--- a/include/asm-mips/bug.h
+++ b/include/asm-mips/bug.h
@@ -1,16 +1,21 @@
#ifndef __ASM_BUG_H
#define __ASM_BUG_H
-#include <asm/break.h>
+#include <linux/config.h>
#ifdef CONFIG_BUG
-#define HAVE_ARCH_BUG
+
+#include <asm/break.h>
+
#define BUG() \
do { \
__asm__ __volatile__("break %0" : : "i" (BRK_BUG)); \
} while (0)
+
+#define HAVE_ARCH_BUG
+
#endif
#include <asm-generic/bug.h>
-#endif
+#endif /* __ASM_BUG_H */
diff --git a/include/asm-mips/bugs.h b/include/asm-mips/bugs.h
index b14b961c2100..cb2ea7c15c7a 100644
--- a/include/asm-mips/bugs.h
+++ b/include/asm-mips/bugs.h
@@ -8,12 +8,18 @@
#define _ASM_BUGS_H
#include <linux/config.h>
+#include <linux/delay.h>
+#include <asm/cpu.h>
+#include <asm/cpu-info.h>
extern void check_bugs32(void);
extern void check_bugs64(void);
static inline void check_bugs(void)
{
+ unsigned int cpu = smp_processor_id();
+
+ cpu_data[cpu].udelay_val = loops_per_jiffy;
check_bugs32();
#ifdef CONFIG_64BIT
check_bugs64();
diff --git a/include/asm-mips/cache.h b/include/asm-mips/cache.h
index 4517bdf20953..1a5d1a669db3 100644
--- a/include/asm-mips/cache.h
+++ b/include/asm-mips/cache.h
@@ -10,6 +10,7 @@
#define _ASM_CACHE_H
#include <linux/config.h>
+#include <kmalloc.h>
#define L1_CACHE_SHIFT CONFIG_MIPS_L1_CACHE_SHIFT
#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
@@ -18,6 +19,4 @@
#define SMP_CACHE_SHIFT L1_CACHE_SHIFT
#define SMP_CACHE_BYTES L1_CACHE_BYTES
-#define ARCH_KMALLOC_MINALIGN 8
-
#endif /* _ASM_CACHE_H */
diff --git a/include/asm-mips/cacheflush.h b/include/asm-mips/cacheflush.h
index 635f1bfb403e..a18ba2edc0b6 100644
--- a/include/asm-mips/cacheflush.h
+++ b/include/asm-mips/cacheflush.h
@@ -49,17 +49,29 @@ static inline void flush_dcache_page(struct page *page)
extern void (*flush_icache_page)(struct vm_area_struct *vma,
struct page *page);
-extern void (*flush_icache_range)(unsigned long start, unsigned long end);
+extern void (*flush_icache_range)(unsigned long __user start,
+ unsigned long __user end);
#define flush_cache_vmap(start, end) flush_cache_all()
#define flush_cache_vunmap(start, end) flush_cache_all()
-#define copy_to_user_page(vma, page, vaddr, dst, src, len) \
-do { \
- memcpy(dst, (void *) src, len); \
- flush_icache_page(vma, page); \
-} while (0)
-#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
- memcpy(dst, src, len)
+static inline void copy_to_user_page(struct vm_area_struct *vma,
+ struct page *page, unsigned long vaddr, void *dst, const void *src,
+ unsigned long len)
+{
+ if (cpu_has_dc_aliases)
+ flush_cache_page(vma, vaddr, page_to_pfn(page));
+ memcpy(dst, src, len);
+ flush_icache_page(vma, page);
+}
+
+static inline void copy_from_user_page(struct vm_area_struct *vma,
+ struct page *page, unsigned long vaddr, void *dst, const void *src,
+ unsigned long len)
+{
+ if (cpu_has_dc_aliases)
+ flush_cache_page(vma, vaddr, page_to_pfn(page));
+ memcpy(dst, src, len);
+}
extern void (*flush_cache_sigtramp)(unsigned long addr);
extern void (*flush_icache_all)(void);
@@ -78,4 +90,7 @@ extern void (*flush_data_cache_page)(unsigned long addr);
#define ClearPageDcacheDirty(page) \
clear_bit(PG_dcache_dirty, &(page)->flags)
+/* Run kernel code uncached, useful for cache probing functions. */
+unsigned long __init run_uncached(void *func);
+
#endif /* _ASM_CACHEFLUSH_H */
diff --git a/include/asm-mips/checksum.h b/include/asm-mips/checksum.h
index c1ea5a8714f3..b09f8971e95d 100644
--- a/include/asm-mips/checksum.h
+++ b/include/asm-mips/checksum.h
@@ -34,8 +34,9 @@ unsigned int csum_partial(const unsigned char *buff, int len, unsigned int sum);
* this is a new version of the above that records errors it finds in *errp,
* but continues and zeros the rest of the buffer.
*/
-unsigned int csum_partial_copy_from_user(const unsigned char *src, unsigned char *dst, int len,
- unsigned int sum, int *errp);
+unsigned int csum_partial_copy_from_user(const unsigned char __user *src,
+ unsigned char *dst, int len,
+ unsigned int sum, int *errp);
/*
* Copy and checksum to user
@@ -70,14 +71,15 @@ unsigned int csum_partial_copy_nocheck(const unsigned char *src, unsigned char *
static inline unsigned short int csum_fold(unsigned int sum)
{
__asm__(
- ".set\tnoat\t\t\t# csum_fold\n\t"
- "sll\t$1,%0,16\n\t"
- "addu\t%0,$1\n\t"
- "sltu\t$1,%0,$1\n\t"
- "srl\t%0,%0,16\n\t"
- "addu\t%0,$1\n\t"
- "xori\t%0,0xffff\n\t"
- ".set\tat"
+ " .set push # csum_fold\n"
+ " .set noat \n"
+ " sll $1, %0, 16 \n"
+ " addu %0, $1 \n"
+ " sltu $1, %0, $1 \n"
+ " srl %0, %0, 16 \n"
+ " addu %0, $1 \n"
+ " xori %0, 0xffff \n"
+ " .set pop"
: "=r" (sum)
: "0" (sum));
@@ -127,29 +129,30 @@ static inline unsigned int csum_tcpudp_nofold(unsigned long saddr,
unsigned int sum)
{
__asm__(
- ".set\tnoat\t\t\t# csum_tcpudp_nofold\n\t"
+ " .set push # csum_tcpudp_nofold\n"
+ " .set noat \n"
#ifdef CONFIG_32BIT
- "addu\t%0, %2\n\t"
- "sltu\t$1, %0, %2\n\t"
- "addu\t%0, $1\n\t"
+ " addu %0, %2 \n"
+ " sltu $1, %0, %2 \n"
+ " addu %0, $1 \n"
- "addu\t%0, %3\n\t"
- "sltu\t$1, %0, %3\n\t"
- "addu\t%0, $1\n\t"
+ " addu %0, %3 \n"
+ " sltu $1, %0, %3 \n"
+ " addu %0, $1 \n"
- "addu\t%0, %4\n\t"
- "sltu\t$1, %0, %4\n\t"
- "addu\t%0, $1\n\t"
+ " addu %0, %4 \n"
+ " sltu $1, %0, %4 \n"
+ " addu %0, $1 \n"
#endif
#ifdef CONFIG_64BIT
- "daddu\t%0, %2\n\t"
- "daddu\t%0, %3\n\t"
- "daddu\t%0, %4\n\t"
- "dsll32\t$1, %0, 0\n\t"
- "daddu\t%0, $1\n\t"
- "dsrl32\t%0, %0, 0\n\t"
+ " daddu %0, %2 \n"
+ " daddu %0, %3 \n"
+ " daddu %0, %4 \n"
+ " dsll32 $1, %0, 0 \n"
+ " daddu %0, $1 \n"
+ " dsra32 %0, %0, 0 \n"
#endif
- ".set\tat"
+ " .set pop"
: "=r" (sum)
: "0" (daddr), "r"(saddr),
#ifdef __MIPSEL__
@@ -192,57 +195,57 @@ static __inline__ unsigned short int csum_ipv6_magic(struct in6_addr *saddr,
unsigned int sum)
{
__asm__(
- ".set\tpush\t\t\t# csum_ipv6_magic\n\t"
- ".set\tnoreorder\n\t"
- ".set\tnoat\n\t"
- "addu\t%0, %5\t\t\t# proto (long in network byte order)\n\t"
- "sltu\t$1, %0, %5\n\t"
- "addu\t%0, $1\n\t"
-
- "addu\t%0, %6\t\t\t# csum\n\t"
- "sltu\t$1, %0, %6\n\t"
- "lw\t%1, 0(%2)\t\t\t# four words source address\n\t"
- "addu\t%0, $1\n\t"
- "addu\t%0, %1\n\t"
- "sltu\t$1, %0, %1\n\t"
-
- "lw\t%1, 4(%2)\n\t"
- "addu\t%0, $1\n\t"
- "addu\t%0, %1\n\t"
- "sltu\t$1, %0, %1\n\t"
-
- "lw\t%1, 8(%2)\n\t"
- "addu\t%0, $1\n\t"
- "addu\t%0, %1\n\t"
- "sltu\t$1, %0, %1\n\t"
-
- "lw\t%1, 12(%2)\n\t"
- "addu\t%0, $1\n\t"
- "addu\t%0, %1\n\t"
- "sltu\t$1, %0, %1\n\t"
-
- "lw\t%1, 0(%3)\n\t"
- "addu\t%0, $1\n\t"
- "addu\t%0, %1\n\t"
- "sltu\t$1, %0, %1\n\t"
-
- "lw\t%1, 4(%3)\n\t"
- "addu\t%0, $1\n\t"
- "addu\t%0, %1\n\t"
- "sltu\t$1, %0, %1\n\t"
-
- "lw\t%1, 8(%3)\n\t"
- "addu\t%0, $1\n\t"
- "addu\t%0, %1\n\t"
- "sltu\t$1, %0, %1\n\t"
-
- "lw\t%1, 12(%3)\n\t"
- "addu\t%0, $1\n\t"
- "addu\t%0, %1\n\t"
- "sltu\t$1, %0, %1\n\t"
-
- "addu\t%0, $1\t\t\t# Add final carry\n\t"
- ".set\tpop"
+ " .set push # csum_ipv6_magic\n"
+ " .set noreorder \n"
+ " .set noat \n"
+ " addu %0, %5 # proto (long in network byte order)\n"
+ " sltu $1, %0, %5 \n"
+ " addu %0, $1 \n"
+
+ " addu %0, %6 # csum\n"
+ " sltu $1, %0, %6 \n"
+ " lw %1, 0(%2) # four words source address\n"
+ " addu %0, $1 \n"
+ " addu %0, %1 \n"
+ " sltu $1, %0, %1 \n"
+
+ " lw %1, 4(%2) \n"
+ " addu %0, $1 \n"
+ " addu %0, %1 \n"
+ " sltu $1, %0, %1 \n"
+
+ " lw %1, 8(%2) \n"
+ " addu %0, $1 \n"
+ " addu %0, %1 \n"
+ " sltu $1, %0, %1 \n"
+
+ " lw %1, 12(%2) \n"
+ " addu %0, $1 \n"
+ " addu %0, %1 \n"
+ " sltu $1, %0, %1 \n"
+
+ " lw %1, 0(%3) \n"
+ " addu %0, $1 \n"
+ " addu %0, %1 \n"
+ " sltu $1, %0, %1 \n"
+
+ " lw %1, 4(%3) \n"
+ " addu %0, $1 \n"
+ " addu %0, %1 \n"
+ " sltu $1, %0, %1 \n"
+
+ " lw %1, 8(%3) \n"
+ " addu %0, $1 \n"
+ " addu %0, %1 \n"
+ " sltu $1, %0, %1 \n"
+
+ " lw %1, 12(%3) \n"
+ " addu %0, $1 \n"
+ " addu %0, %1 \n"
+ " sltu $1, %0, %1 \n"
+
+ " addu %0, $1 # Add final carry\n"
+ " .set pop"
: "=r" (sum), "=r" (proto)
: "r" (saddr), "r" (daddr),
"0" (htonl(len)), "1" (htonl(proto)), "r" (sum));
diff --git a/include/asm-mips/cobalt/cobalt.h b/include/asm-mips/cobalt/cobalt.h
index ca1fbc0579fe..78e1df2095fb 100644
--- a/include/asm-mips/cobalt/cobalt.h
+++ b/include/asm-mips/cobalt/cobalt.h
@@ -19,18 +19,23 @@
* 9 - PCI
* 14 - IDE0
* 15 - IDE1
- *
+ */
+#define COBALT_QUBE_SLOT_IRQ 9
+
+/*
* CPU IRQs are 16 ... 23
*/
-#define COBALT_TIMER_IRQ 18
-#define COBALT_SCC_IRQ 19 /* pre-production has 85C30 */
-#define COBALT_RAQ_SCSI_IRQ 19
-#define COBALT_ETH0_IRQ 19
-#define COBALT_ETH1_IRQ 20
-#define COBALT_SERIAL_IRQ 21
-#define COBALT_SCSI_IRQ 21
-#define COBALT_VIA_IRQ 22 /* Chained to VIA ISA bridge */
-#define COBALT_QUBE_SLOT_IRQ 23
+#define COBALT_CPU_IRQ 16
+
+#define COBALT_GALILEO_IRQ (COBALT_CPU_IRQ + 2)
+#define COBALT_SCC_IRQ (COBALT_CPU_IRQ + 3) /* pre-production has 85C30 */
+#define COBALT_RAQ_SCSI_IRQ (COBALT_CPU_IRQ + 3)
+#define COBALT_ETH0_IRQ (COBALT_CPU_IRQ + 3)
+#define COBALT_QUBE1_ETH0_IRQ (COBALT_CPU_IRQ + 4)
+#define COBALT_ETH1_IRQ (COBALT_CPU_IRQ + 4)
+#define COBALT_SERIAL_IRQ (COBALT_CPU_IRQ + 5)
+#define COBALT_SCSI_IRQ (COBALT_CPU_IRQ + 5)
+#define COBALT_VIA_IRQ (COBALT_CPU_IRQ + 6) /* Chained to VIA ISA bridge */
/*
* PCI configuration space manifest constants. These are wired into
@@ -69,16 +74,21 @@
* Most of this really should go into a separate GT64111 header file.
*/
#define GT64111_IO_BASE 0x10000000UL
+#define GT64111_IO_END 0x11ffffffUL
+#define GT64111_MEM_BASE 0x12000000UL
+#define GT64111_MEM_END 0x13ffffffUL
#define GT64111_BASE 0x14000000UL
-#define GALILEO_REG(ofs) (KSEG0 + GT64111_BASE + (unsigned long)(ofs))
+#define GALILEO_REG(ofs) CKSEG1ADDR(GT64111_BASE + (unsigned long)(ofs))
#define GALILEO_INL(port) (*(volatile unsigned int *) GALILEO_REG(port))
#define GALILEO_OUTL(val, port) \
do { \
- *(volatile unsigned int *) GALILEO_REG(port) = (port); \
+ *(volatile unsigned int *) GALILEO_REG(port) = (val); \
} while (0)
-#define GALILEO_T0EXP 0x0100
+#define GALILEO_INTR_T0EXP (1 << 8)
+#define GALILEO_INTR_RETRY_CTR (1 << 20)
+
#define GALILEO_ENTC0 0x01
#define GALILEO_SELTC0 0x02
@@ -86,5 +96,21 @@ do { \
GALILEO_OUTL((0x80000000 | (PCI_SLOT (devfn) << 11) | \
(PCI_FUNC (devfn) << 8) | (where)), GT_PCI0_CFGADDR_OFS)
+#define COBALT_LED_PORT (*(volatile unsigned char *) CKSEG1ADDR(0x1c000000))
+# define COBALT_LED_BAR_LEFT (1 << 0) /* Qube */
+# define COBALT_LED_BAR_RIGHT (1 << 1) /* Qube */
+# define COBALT_LED_WEB (1 << 2) /* RaQ */
+# define COBALT_LED_POWER_OFF (1 << 3) /* RaQ */
+# define COBALT_LED_RESET 0x0f
+
+#define COBALT_KEY_PORT ((~*(volatile unsigned int *) CKSEG1ADDR(0x1d000000) >> 24) & COBALT_KEY_MASK)
+# define COBALT_KEY_CLEAR (1 << 1)
+# define COBALT_KEY_LEFT (1 << 2)
+# define COBALT_KEY_UP (1 << 3)
+# define COBALT_KEY_DOWN (1 << 4)
+# define COBALT_KEY_RIGHT (1 << 5)
+# define COBALT_KEY_ENTER (1 << 6)
+# define COBALT_KEY_SELECT (1 << 7)
+# define COBALT_KEY_MASK 0xfe
#endif /* __ASM_COBALT_H */
diff --git a/include/asm-mips/cobalt/mach-gt64120.h b/include/asm-mips/cobalt/mach-gt64120.h
new file mode 100644
index 000000000000..587fc4378f44
--- /dev/null
+++ b/include/asm-mips/cobalt/mach-gt64120.h
@@ -0,0 +1 @@
+/* there's something here ... in the dark */
diff --git a/include/asm-mips/compat.h b/include/asm-mips/compat.h
index 2c084cd4bc0a..35d2604fe69c 100644
--- a/include/asm-mips/compat.h
+++ b/include/asm-mips/compat.h
@@ -15,10 +15,10 @@ typedef s32 compat_clock_t;
typedef s32 compat_suseconds_t;
typedef s32 compat_pid_t;
-typedef u32 __compat_uid_t;
-typedef u32 __compat_gid_t;
-typedef u32 __compat_uid32_t;
-typedef u32 __compat_gid32_t;
+typedef s32 __compat_uid_t;
+typedef s32 __compat_gid_t;
+typedef __compat_uid_t __compat_uid32_t;
+typedef __compat_gid_t __compat_gid32_t;
typedef u32 compat_mode_t;
typedef u32 compat_ino_t;
typedef u32 compat_dev_t;
@@ -54,8 +54,8 @@ struct compat_stat {
compat_ino_t st_ino;
compat_mode_t st_mode;
compat_nlink_t st_nlink;
- __compat_uid32_t st_uid;
- __compat_gid32_t st_gid;
+ __compat_uid_t st_uid;
+ __compat_gid_t st_gid;
compat_dev_t st_rdev;
s32 st_pad2[2];
compat_off_t st_size;
diff --git a/include/asm-mips/cpu-features.h b/include/asm-mips/cpu-features.h
index 9a2de642eee6..03627cfb3e45 100644
--- a/include/asm-mips/cpu-features.h
+++ b/include/asm-mips/cpu-features.h
@@ -4,6 +4,7 @@
* for more details.
*
* Copyright (C) 2003, 2004 Ralf Baechle
+ * Copyright (C) 2004 Maciej W. Rozycki
*/
#ifndef __ASM_CPU_FEATURES_H
#define __ASM_CPU_FEATURES_H
@@ -24,8 +25,19 @@
#ifndef cpu_has_4kex
#define cpu_has_4kex (cpu_data[0].options & MIPS_CPU_4KEX)
#endif
-#ifndef cpu_has_4ktlb
-#define cpu_has_4ktlb (cpu_data[0].options & MIPS_CPU_4KTLB)
+#ifndef cpu_has_3k_cache
+#define cpu_has_3k_cache (cpu_data[0].options & MIPS_CPU_3K_CACHE)
+#endif
+#define cpu_has_6k_cache 0
+#define cpu_has_8k_cache 0
+#ifndef cpu_has_4k_cache
+#define cpu_has_4k_cache (cpu_data[0].options & MIPS_CPU_4K_CACHE)
+#endif
+#ifndef cpu_has_tx39_cache
+#define cpu_has_tx39_cache (cpu_data[0].options & MIPS_CPU_TX39_CACHE)
+#endif
+#ifndef cpu_has_sb1_cache
+#define cpu_has_sb1_cache (cpu_data[0].options & MIPS_CPU_SB1_CACHE)
#endif
#ifndef cpu_has_fpu
#define cpu_has_fpu (cpu_data[0].options & MIPS_CPU_FPU)
@@ -39,9 +51,6 @@
#ifndef cpu_has_watch
#define cpu_has_watch (cpu_data[0].options & MIPS_CPU_WATCH)
#endif
-#ifndef cpu_has_mips16
-#define cpu_has_mips16 (cpu_data[0].options & MIPS_CPU_MIPS16)
-#endif
#ifndef cpu_has_divec
#define cpu_has_divec (cpu_data[0].options & MIPS_CPU_DIVEC)
#endif
@@ -66,6 +75,18 @@
#ifndef cpu_has_llsc
#define cpu_has_llsc (cpu_data[0].options & MIPS_CPU_LLSC)
#endif
+#ifndef cpu_has_mips16
+#define cpu_has_mips16 (cpu_data[0].ases & MIPS_ASE_MIPS16)
+#endif
+#ifndef cpu_has_mdmx
+#define cpu_has_mdmx (cpu_data[0].ases & MIPS_ASE_MDMX)
+#endif
+#ifndef cpu_has_mips3d
+#define cpu_has_mips3d (cpu_data[0].ases & MIPS_ASE_MIPS3D)
+#endif
+#ifndef cpu_has_smartmips
+#define cpu_has_smartmips (cpu_data[0].ases & MIPS_ASE_SMARTMIPS)
+#endif
#ifndef cpu_has_vtag_icache
#define cpu_has_vtag_icache (cpu_data[0].icache.flags & MIPS_CACHE_VTAG)
#endif
@@ -95,15 +116,16 @@
#endif
#endif
-/*
- * Certain CPUs may throw bizarre exceptions if not the whole cacheline
- * contains valid instructions. For these we ensure proper alignment of
- * signal trampolines and pad them to the size of a full cache lines with
- * nops. This is also used in structure definitions so can't be a test macro
- * like the others.
- */
-#ifndef PLAT_TRAMPOLINE_STUFF_LINE
-#define PLAT_TRAMPOLINE_STUFF_LINE 0UL
+#ifndef cpu_has_dsp
+#define cpu_has_dsp (cpu_data[0].ases & MIPS_ASE_DSP)
+#endif
+
+#ifdef CONFIG_MIPS_MT
+#ifndef cpu_has_mipsmt
+# define cpu_has_mipsmt (cpu_data[0].ases & MIPS_ASE_MIPSMT)
+#endif
+#else
+# define cpu_has_mipsmt 0
#endif
#ifdef CONFIG_32BIT
@@ -142,6 +164,22 @@
# endif
#endif
+#ifdef CONFIG_CPU_MIPSR2
+# if defined(CONFIG_CPU_MIPSR2_IRQ_VI) && !defined(cpu_has_vint)
+# define cpu_has_vint (cpu_data[0].options & MIPS_CPU_VINT)
+# else
+# define cpu_has_vint 0
+# endif
+# if defined(CONFIG_CPU_MIPSR2_IRQ_EI) && !defined(cpu_has_veic)
+# define cpu_has_veic (cpu_data[0].options & MIPS_CPU_VEIC)
+# else
+# define cpu_has_veic 0
+# endif
+#else
+# define cpu_has_vint 0
+# define cpu_has_veic 0
+#endif
+
#ifndef cpu_has_subset_pcaches
#define cpu_has_subset_pcaches (cpu_data[0].options & MIPS_CPU_SUBSET_CACHES)
#endif
diff --git a/include/asm-mips/cpu-info.h b/include/asm-mips/cpu-info.h
index 20a35b15a31d..d5cf519f8fcc 100644
--- a/include/asm-mips/cpu-info.h
+++ b/include/asm-mips/cpu-info.h
@@ -7,6 +7,7 @@
* Copyright (C) 1995, 1996, 1997, 1998, 1999, 2001, 2002, 2003 Ralf Baechle
* Copyright (C) 1996 Paul M. Antoine
* Copyright (C) 1999, 2000 Silicon Graphics, Inc.
+ * Copyright (C) 2004 Maciej W. Rozycki
*/
#ifndef __ASM_CPU_INFO_H
#define __ASM_CPU_INFO_H
@@ -61,6 +62,7 @@ struct cpuinfo_mips {
* Capability and feature descriptor structure for MIPS CPU
*/
unsigned long options;
+ unsigned long ases;
unsigned int processor_id;
unsigned int fpu_id;
unsigned int cputype;
diff --git a/include/asm-mips/cpu.h b/include/asm-mips/cpu.h
index dec060b49556..48eac296060f 100644
--- a/include/asm-mips/cpu.h
+++ b/include/asm-mips/cpu.h
@@ -3,6 +3,7 @@
* various MIPS cpu types.
*
* Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ * Copyright (C) 2004 Maciej W. Rozycki
*/
#ifndef _ASM_CPU_H
#define _ASM_CPU_H
@@ -22,12 +23,17 @@
spec.
*/
-#define PRID_COMP_LEGACY 0x000000
-#define PRID_COMP_MIPS 0x010000
-#define PRID_COMP_BROADCOM 0x020000
-#define PRID_COMP_ALCHEMY 0x030000
-#define PRID_COMP_SIBYTE 0x040000
-#define PRID_COMP_SANDCRAFT 0x050000
+#define PRID_COMP_LEGACY 0x000000
+#define PRID_COMP_MIPS 0x010000
+#define PRID_COMP_BROADCOM 0x020000
+#define PRID_COMP_ALCHEMY 0x030000
+#define PRID_COMP_SIBYTE 0x040000
+#define PRID_COMP_SANDCRAFT 0x050000
+#define PRID_COMP_PHILIPS 0x060000
+#define PRID_COMP_TOSHIBA 0x070000
+#define PRID_COMP_LSI 0x080000
+#define PRID_COMP_LEXRA 0x0b0000
+
/*
* Assigned values for the product ID register. In order to detect a
@@ -46,6 +52,7 @@
#define PRID_IMP_VR41XX 0x0c00
#define PRID_IMP_R12000 0x0e00
#define PRID_IMP_R8000 0x1000
+#define PRID_IMP_PR4450 0x1200
#define PRID_IMP_R4600 0x2000
#define PRID_IMP_R4700 0x2100
#define PRID_IMP_TX39 0x2200
@@ -60,6 +67,13 @@
#define PRID_IMP_RM9000 0x3400
#define PRID_IMP_R5432 0x5400
#define PRID_IMP_R5500 0x5500
+
+#define PRID_IMP_UNKNOWN 0xff00
+
+/*
+ * These are the PRID's for when 23:16 == PRID_COMP_MIPS
+ */
+
#define PRID_IMP_4KC 0x8000
#define PRID_IMP_5KC 0x8100
#define PRID_IMP_20KC 0x8200
@@ -71,14 +85,15 @@
#define PRID_IMP_4KEMPR2 0x9100
#define PRID_IMP_4KSD 0x9200
#define PRID_IMP_24K 0x9300
-
-#define PRID_IMP_UNKNOWN 0xff00
+#define PRID_IMP_34K 0x9500
+#define PRID_IMP_24KE 0x9600
/*
* These are the PRID's for when 23:16 == PRID_COMP_SIBYTE
*/
#define PRID_IMP_SB1 0x0100
+#define PRID_IMP_SB1A 0x1100
/*
* These are the PRID's for when 23:16 == PRID_COMP_SANDCRAFT
@@ -177,7 +192,11 @@
#define CPU_VR4133 56
#define CPU_AU1550 57
#define CPU_24K 58
-#define CPU_LAST 58
+#define CPU_AU1200 59
+#define CPU_34K 60
+#define CPU_PR4450 61
+#define CPU_SB1A 62
+#define CPU_LAST 62
/*
* ISA Level encodings
@@ -200,23 +219,37 @@
* CPU Option encodings
*/
#define MIPS_CPU_TLB 0x00000001 /* CPU has TLB */
-/* Leave a spare bit for variant MMU types... */
-#define MIPS_CPU_4KEX 0x00000004 /* "R4K" exception model */
-#define MIPS_CPU_4KTLB 0x00000008 /* "R4K" TLB handler */
-#define MIPS_CPU_FPU 0x00000010 /* CPU has FPU */
-#define MIPS_CPU_32FPR 0x00000020 /* 32 dbl. prec. FP registers */
-#define MIPS_CPU_COUNTER 0x00000040 /* Cycle count/compare */
-#define MIPS_CPU_WATCH 0x00000080 /* watchpoint registers */
-#define MIPS_CPU_MIPS16 0x00000100 /* code compression */
-#define MIPS_CPU_DIVEC 0x00000200 /* dedicated interrupt vector */
-#define MIPS_CPU_VCE 0x00000400 /* virt. coherence conflict possible */
-#define MIPS_CPU_CACHE_CDEX_P 0x00000800 /* Create_Dirty_Exclusive CACHE op */
-#define MIPS_CPU_CACHE_CDEX_S 0x00001000 /* ... same for seconary cache ... */
-#define MIPS_CPU_MCHECK 0x00002000 /* Machine check exception */
-#define MIPS_CPU_EJTAG 0x00004000 /* EJTAG exception */
-#define MIPS_CPU_NOFPUEX 0x00008000 /* no FPU exception */
-#define MIPS_CPU_LLSC 0x00010000 /* CPU has ll/sc instructions */
-#define MIPS_CPU_SUBSET_CACHES 0x00020000 /* P-cache subset enforced */
-#define MIPS_CPU_PREFETCH 0x00040000 /* CPU has usable prefetch */
+#define MIPS_CPU_4KEX 0x00000002 /* "R4K" exception model */
+#define MIPS_CPU_3K_CACHE 0x00000004 /* R3000-style caches */
+#define MIPS_CPU_4K_CACHE 0x00000008 /* R4000-style caches */
+#define MIPS_CPU_TX39_CACHE 0x00000010 /* TX3900-style caches */
+#define MIPS_CPU_SB1_CACHE 0x00000020 /* SB1-style caches */
+#define MIPS_CPU_FPU 0x00000040 /* CPU has FPU */
+#define MIPS_CPU_32FPR 0x00000080 /* 32 dbl. prec. FP registers */
+#define MIPS_CPU_COUNTER 0x00000100 /* Cycle count/compare */
+#define MIPS_CPU_WATCH 0x00000200 /* watchpoint registers */
+#define MIPS_CPU_DIVEC 0x00000400 /* dedicated interrupt vector */
+#define MIPS_CPU_VCE 0x00000800 /* virt. coherence conflict possible */
+#define MIPS_CPU_CACHE_CDEX_P 0x00001000 /* Create_Dirty_Exclusive CACHE op */
+#define MIPS_CPU_CACHE_CDEX_S 0x00002000 /* ... same for seconary cache ... */
+#define MIPS_CPU_MCHECK 0x00004000 /* Machine check exception */
+#define MIPS_CPU_EJTAG 0x00008000 /* EJTAG exception */
+#define MIPS_CPU_NOFPUEX 0x00010000 /* no FPU exception */
+#define MIPS_CPU_LLSC 0x00020000 /* CPU has ll/sc instructions */
+#define MIPS_CPU_SUBSET_CACHES 0x00040000 /* P-cache subset enforced */
+#define MIPS_CPU_PREFETCH 0x00080000 /* CPU has usable prefetch */
+#define MIPS_CPU_VINT 0x00100000 /* CPU supports MIPSR2 vectored interrupts */
+#define MIPS_CPU_VEIC 0x00200000 /* CPU supports MIPSR2 external interrupt controller mode */
+
+/*
+ * CPU ASE encodings
+ */
+#define MIPS_ASE_MIPS16 0x00000001 /* code compression */
+#define MIPS_ASE_MDMX 0x00000002 /* MIPS digital media extension */
+#define MIPS_ASE_MIPS3D 0x00000004 /* MIPS-3D */
+#define MIPS_ASE_SMARTMIPS 0x00000008 /* SmartMIPS */
+#define MIPS_ASE_DSP 0x00000010 /* Signal Processing ASE */
+#define MIPS_ASE_MIPSMT 0x00000020 /* CPU supports MIPS MT */
+
#endif /* _ASM_CPU_H */
diff --git a/include/asm-mips/dec/ecc.h b/include/asm-mips/dec/ecc.h
index 724908b0bf13..19495a490e72 100644
--- a/include/asm-mips/dec/ecc.h
+++ b/include/asm-mips/dec/ecc.h
@@ -49,7 +49,8 @@ struct pt_regs;
extern void dec_ecc_be_init(void);
extern int dec_ecc_be_handler(struct pt_regs *regs, int is_fixup);
-extern irqreturn_t dec_ecc_be_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+extern irqreturn_t dec_ecc_be_interrupt(int irq, void *dev_id,
+ struct pt_regs *regs);
#endif
#endif /* __ASM_MIPS_DEC_ECC_H */
diff --git a/include/asm-mips/dec/ioasic_addrs.h b/include/asm-mips/dec/ioasic_addrs.h
index 5e18a7510592..4cbc1f8a1129 100644
--- a/include/asm-mips/dec/ioasic_addrs.h
+++ b/include/asm-mips/dec/ioasic_addrs.h
@@ -45,7 +45,8 @@
/*
- * Offsets for I/O ASIC registers (relative to (system_base + IOASIC_IOCTL)).
+ * Offsets for I/O ASIC registers
+ * (relative to (dec_kn_slot_base + IOASIC_IOCTL)).
*/
/* all systems */
#define IO_REG_SCSI_DMA_P 0x00 /* SCSI DMA Pointer */
diff --git a/include/asm-mips/dec/kn01.h b/include/asm-mips/dec/kn01.h
index 946943502f83..eb522aa1e226 100644
--- a/include/asm-mips/dec/kn01.h
+++ b/include/asm-mips/dec/kn01.h
@@ -8,14 +8,12 @@
*
* Copyright (C) 1995,1996 by Paul M. Antoine, some code and definitions
* are by courtesy of Chris Fraser.
- * Copyright (C) 2002, 2003 Maciej W. Rozycki
+ * Copyright (C) 2002, 2003, 2005 Maciej W. Rozycki
*/
#ifndef __ASM_MIPS_DEC_KN01_H
#define __ASM_MIPS_DEC_KN01_H
-#include <asm/addrspace.h>
-
-#define KN01_SLOT_BASE KSEG1ADDR(0x10000000)
+#define KN01_SLOT_BASE 0x10000000
#define KN01_SLOT_SIZE 0x01000000
/*
@@ -41,17 +39,9 @@
/*
- * Some port addresses...
- */
-#define KN01_LANCE_BASE (KN01_SLOT_BASE + KN01_LANCE) /* 0xB8000000 */
-#define KN01_DZ11_BASE (KN01_SLOT_BASE + KN01_DZ11) /* 0xBC000000 */
-#define KN01_RTC_BASE (KN01_SLOT_BASE + KN01_RTC) /* 0xBD000000 */
-
-
-/*
* Frame buffer memory address.
*/
-#define KN01_VFB_MEM KSEG1ADDR(0x0fc00000)
+#define KN01_VFB_MEM 0x0fc00000
/*
* CPU interrupt bits.
@@ -80,4 +70,22 @@
#define KN01_CSR_VRGTRB (1<<0) /* red DAC voltage over blue (r/o) */
#define KN01_CSR_LEDS (0xff<<0) /* ~diagnostic LEDs (w/o) */
+
+#ifndef __ASSEMBLY__
+
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+#include <linux/types.h>
+
+struct pt_regs;
+
+extern u16 cached_kn01_csr;
+extern spinlock_t kn01_lock;
+
+extern void dec_kn01_be_init(void);
+extern int dec_kn01_be_handler(struct pt_regs *regs, int is_fixup);
+extern irqreturn_t dec_kn01_be_interrupt(int irq, void *dev_id,
+ struct pt_regs *regs);
+#endif
+
#endif /* __ASM_MIPS_DEC_KN01_H */
diff --git a/include/asm-mips/dec/kn02.h b/include/asm-mips/dec/kn02.h
index f797f7045920..8319ad77b250 100644
--- a/include/asm-mips/dec/kn02.h
+++ b/include/asm-mips/dec/kn02.h
@@ -8,21 +8,12 @@
*
* Copyright (C) 1995,1996 by Paul M. Antoine, some code and definitions
* are by courtesy of Chris Fraser.
- * Copyright (C) 2002, 2003 Maciej W. Rozycki
+ * Copyright (C) 2002, 2003, 2005 Maciej W. Rozycki
*/
#ifndef __ASM_MIPS_DEC_KN02_H
#define __ASM_MIPS_DEC_KN02_H
-#ifndef __ASSEMBLY__
-#include <linux/spinlock.h>
-#include <linux/types.h>
-#endif
-
-#include <asm/addrspace.h>
-#include <asm/dec/ecc.h>
-
-
-#define KN02_SLOT_BASE KSEG1ADDR(0x1fc00000)
+#define KN02_SLOT_BASE 0x1fc00000
#define KN02_SLOT_SIZE 0x00080000
/*
@@ -39,22 +30,14 @@
/*
- * Some port addresses...
- */
-#define KN02_DZ11_BASE (KN02_SLOT_BASE + KN02_DZ11) /* DZ11 */
-#define KN02_RTC_BASE (KN02_SLOT_BASE + KN02_RTC) /* RTC */
-#define KN02_CSR_BASE (KN02_SLOT_BASE + KN02_CSR) /* CSR */
-
-
-/*
* System Control & Status Register bits.
*/
#define KN02_CSR_RES_28 (0xf<<28) /* unused */
#define KN02_CSR_PSU (1<<27) /* power supply unit warning */
#define KN02_CSR_NVRAM (1<<26) /* ~NVRAM clear jumper */
#define KN02_CSR_REFEVEN (1<<25) /* mem refresh bank toggle */
-#define KN03_CSR_NRMOD (1<<24) /* ~NRMOD manufact. jumper */
-#define KN03_CSR_IOINTEN (0xff<<16) /* IRQ mask bits */
+#define KN02_CSR_NRMOD (1<<24) /* ~NRMOD manufact. jumper */
+#define KN02_CSR_IOINTEN (0xff<<16) /* IRQ mask bits */
#define KN02_CSR_DIAGCHK (1<<15) /* diagn/norml ECC reads */
#define KN02_CSR_DIAGGEN (1<<14) /* diagn/norml ECC writes */
#define KN02_CSR_CORRECT (1<<13) /* ECC correct/check */
@@ -63,8 +46,8 @@
#define KN02_CSR_BNK32M (1<<10) /* 32M/8M stride */
#define KN02_CSR_DIAGDN (1<<9) /* DIAGDN manufact. jumper */
#define KN02_CSR_BAUD38 (1<<8) /* DZ11 38/19kbps ext. rate */
-#define KN03_CSR_IOINT (0xff<<0) /* IRQ status bits (r/o) */
-#define KN03_CSR_LEDS (0xff<<0) /* ~diagnostic LEDs (w/o) */
+#define KN02_CSR_IOINT (0xff<<0) /* IRQ status bits (r/o) */
+#define KN02_CSR_LEDS (0xff<<0) /* ~diagnostic LEDs (w/o) */
/*
@@ -98,6 +81,10 @@
#ifndef __ASSEMBLY__
+
+#include <linux/spinlock.h>
+#include <linux/types.h>
+
extern u32 cached_kn02_csr;
extern spinlock_t kn02_lock;
extern void init_kn02_irqs(int base);
diff --git a/include/asm-mips/dec/kn02xa.h b/include/asm-mips/dec/kn02xa.h
index 648c4dcbba1d..a25f3d7da7f7 100644
--- a/include/asm-mips/dec/kn02xa.h
+++ b/include/asm-mips/dec/kn02xa.h
@@ -9,7 +9,7 @@
*
* Copyright (C) 1995,1996 by Paul M. Antoine, some code and definitions
* are by courtesy of Chris Fraser.
- * Copyright (C) 2000, 2002, 2003 Maciej W. Rozycki
+ * Copyright (C) 2000, 2002, 2003, 2005 Maciej W. Rozycki
*
* These are addresses which have to be known early in the boot process.
* For other addresses refer to tc.h, ioasic_addrs.h and friends.
@@ -17,31 +17,23 @@
#ifndef __ASM_MIPS_DEC_KN02XA_H
#define __ASM_MIPS_DEC_KN02XA_H
-#include <asm/addrspace.h>
#include <asm/dec/ioasic_addrs.h>
-#define KN02XA_SLOT_BASE KSEG1ADDR(0x1c000000)
-
-/*
- * Some port addresses...
- */
-#define KN02XA_IOASIC_BASE (KN02XA_SLOT_BASE + IOASIC_IOCTL) /* I/O ASIC */
-#define KN02XA_RTC_BASE (KN02XA_SLOT_BASE + IOASIC_TOY) /* RTC */
-
+#define KN02XA_SLOT_BASE 0x1c000000
/*
* Memory control ASIC registers.
*/
-#define KN02XA_MER KSEG1ADDR(0x0c400000) /* memory error register */
-#define KN02XA_MSR KSEG1ADDR(0x0c800000) /* memory size register */
+#define KN02XA_MER 0x0c400000 /* memory error register */
+#define KN02XA_MSR 0x0c800000 /* memory size register */
/*
* CPU control ASIC registers.
*/
-#define KN02XA_MEM_CONF KSEG1ADDR(0x0e000000) /* write timeout config */
-#define KN02XA_EAR KSEG1ADDR(0x0e000004) /* error address register */
-#define KN02XA_BOOT0 KSEG1ADDR(0x0e000008) /* boot 0 register */
-#define KN02XA_MEM_INTR KSEG1ADDR(0x0e00000c) /* write err IRQ stat & ack */
+#define KN02XA_MEM_CONF 0x0e000000 /* write timeout config */
+#define KN02XA_EAR 0x0e000004 /* error address register */
+#define KN02XA_BOOT0 0x0e000008 /* boot 0 register */
+#define KN02XA_MEM_INTR 0x0e00000c /* write err IRQ stat & ack */
/*
* Memory Error Register bits, common definitions.
@@ -52,8 +44,13 @@
#define KN02XA_MER_PAGERR (1<<16) /* 2k page boundary error */
#define KN02XA_MER_TRANSERR (1<<15) /* transfer length error */
#define KN02XA_MER_PARDIS (1<<14) /* parity error disable */
-#define KN02XA_MER_RES_12 (0x3<<12) /* unused */
-#define KN02XA_MER_BYTERR (0xf<<8) /* byte lane error bitmask */
+#define KN02XA_MER_SIZE (1<<13) /* r/o mirror of MSR_SIZE */
+#define KN02XA_MER_RES_12 (1<<12) /* unused */
+#define KN02XA_MER_BYTERR (0xf<<8) /* byte lane error bitmask: */
+#define KN02XA_MER_BYTERR_3 (0x8<<8) /* byte lane #3 */
+#define KN02XA_MER_BYTERR_2 (0x4<<8) /* byte lane #2 */
+#define KN02XA_MER_BYTERR_1 (0x2<<8) /* byte lane #1 */
+#define KN02XA_MER_BYTERR_0 (0x1<<8) /* byte lane #0 */
#define KN02XA_MER_RES_0 (0xff<<0) /* unused */
/*
@@ -72,4 +69,17 @@
#define KN02XA_EAR_ADDRESS (0x7ffffff<<2) /* address involved */
#define KN02XA_EAR_RES_0 (0x3<<0) /* unused */
+
+#ifndef __ASSEMBLY__
+
+#include <linux/interrupt.h>
+
+struct pt_regs;
+
+extern void dec_kn02xa_be_init(void);
+extern int dec_kn02xa_be_handler(struct pt_regs *regs, int is_fixup);
+extern irqreturn_t dec_kn02xa_be_interrupt(int irq, void *dev_id,
+ struct pt_regs *regs);
+#endif
+
#endif /* __ASM_MIPS_DEC_KN02XA_H */
diff --git a/include/asm-mips/dec/kn03.h b/include/asm-mips/dec/kn03.h
index 676abd17c6a4..edede923ffb8 100644
--- a/include/asm-mips/dec/kn03.h
+++ b/include/asm-mips/dec/kn03.h
@@ -10,24 +10,15 @@
*
* Copyright (C) 1995,1996 by Paul M. Antoine, some code and definitions
* are by courtesy of Chris Fraser.
- * Copyright (C) 2000, 2002, 2003 Maciej W. Rozycki
+ * Copyright (C) 2000, 2002, 2003, 2005 Maciej W. Rozycki
*/
#ifndef __ASM_MIPS_DEC_KN03_H
#define __ASM_MIPS_DEC_KN03_H
-#include <asm/addrspace.h>
#include <asm/dec/ecc.h>
#include <asm/dec/ioasic_addrs.h>
-#define KN03_SLOT_BASE KSEG1ADDR(0x1f800000)
-
-/*
- * Some port addresses...
- */
-#define KN03_IOASIC_BASE (KN03_SLOT_BASE + IOASIC_IOCTL) /* I/O ASIC */
-#define KN03_RTC_BASE (KN03_SLOT_BASE + IOASIC_TOY) /* RTC */
-#define KN03_MCR_BASE (KN03_SLOT_BASE + IOASIC_MCR) /* MCR */
-
+#define KN03_SLOT_BASE 0x1f800000
/*
* CPU interrupt bits.
diff --git a/include/asm-mips/dec/kn05.h b/include/asm-mips/dec/kn05.h
index b120362b8f13..15fe8f881e60 100644
--- a/include/asm-mips/dec/kn05.h
+++ b/include/asm-mips/dec/kn05.h
@@ -1,10 +1,12 @@
/*
* include/asm-mips/dec/kn05.h
*
- * DECstation 5000/260 (4max+ or KN05) and DECsystem 5900/260
+ * DECstation/DECsystem 5000/260 (4max+ or KN05), 5000/150 (4min
+ * or KN04-BA), Personal DECstation/DECsystem 5000/50 (4maxine or
+ * KN04-CA) and DECsystem 5900/260 (KN05) R4k CPU card MB ASIC
* definitions.
*
- * Copyright (C) 2002, 2003 Maciej W. Rozycki
+ * Copyright (C) 2002, 2003, 2005 Maciej W. Rozycki
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -13,8 +15,8 @@
*
* WARNING! All this information is pure guesswork based on the
* ROM. It is provided here in hope it will give someone some
- * food for thought. No documentation for the KN05 module has
- * been located so far.
+ * food for thought. No documentation for the KN05 nor the KN04
+ * module has been located so far.
*/
#ifndef __ASM_MIPS_DEC_KN05_H
#define __ASM_MIPS_DEC_KN05_H
@@ -24,48 +26,50 @@
/*
* The oncard MB (Memory Buffer) ASIC provides an additional address
* decoder. Certain address ranges within the "high" 16 slots are
- * passed to the I/O ASIC's decoder like with the KN03. Others are
- * handled locally. "Low" slots are always passed.
+ * passed to the I/O ASIC's decoder like with the KN03 or KN02-BA/CA.
+ * Others are handled locally. "Low" slots are always passed.
*/
-#define KN05_MB_ROM (16*IOASIC_SLOT_SIZE) /* KN05 card ROM */
-#define KN05_IOCTL (17*IOASIC_SLOT_SIZE) /* I/O ASIC */
-#define KN05_ESAR (18*IOASIC_SLOT_SIZE) /* LANCE MAC address chip */
-#define KN05_LANCE (19*IOASIC_SLOT_SIZE) /* LANCE Ethernet */
-#define KN05_MB_INT (20*IOASIC_SLOT_SIZE) /* MB interrupt register */
-#define KN05_MB_EA (21*IOASIC_SLOT_SIZE) /* MB error address? */
-#define KN05_MB_EC (22*IOASIC_SLOT_SIZE) /* MB error ??? */
-#define KN05_MB_CSR (23*IOASIC_SLOT_SIZE) /* MB control & status */
-#define KN05_RES_24 (24*IOASIC_SLOT_SIZE) /* unused? */
-#define KN05_RES_25 (25*IOASIC_SLOT_SIZE) /* unused? */
-#define KN05_RES_26 (26*IOASIC_SLOT_SIZE) /* unused? */
-#define KN05_RES_27 (27*IOASIC_SLOT_SIZE) /* unused? */
-#define KN05_SCSI (28*IOASIC_SLOT_SIZE) /* ASC SCSI */
-#define KN05_RES_29 (29*IOASIC_SLOT_SIZE) /* unused? */
-#define KN05_RES_30 (30*IOASIC_SLOT_SIZE) /* unused? */
-#define KN05_RES_31 (31*IOASIC_SLOT_SIZE) /* unused? */
+#define KN4K_SLOT_BASE 0x1fc00000
+
+#define KN4K_MB_ROM (0*IOASIC_SLOT_SIZE) /* KN05/KN04 card ROM */
+#define KN4K_IOCTL (1*IOASIC_SLOT_SIZE) /* I/O ASIC */
+#define KN4K_ESAR (2*IOASIC_SLOT_SIZE) /* LANCE MAC address chip */
+#define KN4K_LANCE (3*IOASIC_SLOT_SIZE) /* LANCE Ethernet */
+#define KN4K_MB_INT (4*IOASIC_SLOT_SIZE) /* MB interrupt register */
+#define KN4K_MB_EA (5*IOASIC_SLOT_SIZE) /* MB error address? */
+#define KN4K_MB_EC (6*IOASIC_SLOT_SIZE) /* MB error ??? */
+#define KN4K_MB_CSR (7*IOASIC_SLOT_SIZE) /* MB control & status */
+#define KN4K_RES_08 (8*IOASIC_SLOT_SIZE) /* unused? */
+#define KN4K_RES_09 (9*IOASIC_SLOT_SIZE) /* unused? */
+#define KN4K_RES_10 (10*IOASIC_SLOT_SIZE) /* unused? */
+#define KN4K_RES_11 (11*IOASIC_SLOT_SIZE) /* unused? */
+#define KN4K_SCSI (12*IOASIC_SLOT_SIZE) /* ASC SCSI */
+#define KN4K_RES_13 (13*IOASIC_SLOT_SIZE) /* unused? */
+#define KN4K_RES_14 (14*IOASIC_SLOT_SIZE) /* unused? */
+#define KN4K_RES_15 (15*IOASIC_SLOT_SIZE) /* unused? */
/*
* Bits for the MB interrupt register.
* The register appears read-only.
*/
-#define KN05_MB_INT_TC (1<<0) /* TURBOchannel? */
-#define KN05_MB_INT_RTC (1<<1) /* RTC? */
-#define KN05_MB_INT_MT (1<<3) /* ??? */
+#define KN4K_MB_INT_TC (1<<0) /* TURBOchannel? */
+#define KN4K_MB_INT_RTC (1<<1) /* RTC? */
+#define KN4K_MB_INT_MT (1<<3) /* ??? */
/*
* Bits for the MB control & status register.
* Set to 0x00bf8001 on my system by the ROM.
*/
-#define KN05_MB_CSR_PF (1<<0) /* PreFetching enable? */
-#define KN05_MB_CSR_F (1<<1) /* ??? */
-#define KN05_MB_CSR_ECC (0xff<<2) /* ??? */
-#define KN05_MB_CSR_OD (1<<10) /* ??? */
-#define KN05_MB_CSR_CP (1<<11) /* ??? */
-#define KN05_MB_CSR_UNC (1<<12) /* ??? */
-#define KN05_MB_CSR_IM (1<<13) /* ??? */
-#define KN05_MB_CSR_NC (1<<14) /* ??? */
-#define KN05_MB_CSR_EE (1<<15) /* (bus) Exception Enable? */
-#define KN05_MB_CSR_MSK (0x1f<<16) /* ??? */
-#define KN05_MB_CSR_FW (1<<21) /* ??? */
+#define KN4K_MB_CSR_PF (1<<0) /* PreFetching enable? */
+#define KN4K_MB_CSR_F (1<<1) /* ??? */
+#define KN4K_MB_CSR_ECC (0xff<<2) /* ??? */
+#define KN4K_MB_CSR_OD (1<<10) /* ??? */
+#define KN4K_MB_CSR_CP (1<<11) /* ??? */
+#define KN4K_MB_CSR_UNC (1<<12) /* ??? */
+#define KN4K_MB_CSR_IM (1<<13) /* ??? */
+#define KN4K_MB_CSR_NC (1<<14) /* ??? */
+#define KN4K_MB_CSR_EE (1<<15) /* (bus) Exception Enable? */
+#define KN4K_MB_CSR_MSK (0x1f<<16) /* ??? */
+#define KN4K_MB_CSR_FW (1<<21) /* ??? */
#endif /* __ASM_MIPS_DEC_KN05_H */
diff --git a/include/asm-mips/dec/prom.h b/include/asm-mips/dec/prom.h
index a05d6d3395fe..1384dd0964b9 100644
--- a/include/asm-mips/dec/prom.h
+++ b/include/asm-mips/dec/prom.h
@@ -24,7 +24,7 @@
* PMAX/3MAX PROM entry points for DS2100/3100's and DS5000/2xx's.
* Many of these will work for MIPSen as well!
*/
-#define VEC_RESET (u64 *)KSEG1ADDR(0x1fc00000)
+#define VEC_RESET (u64 *)CKSEG1ADDR(0x1fc00000)
/* Prom base address */
#define PMAX_PROM_ENTRY(x) (VEC_RESET + (x)) /* Prom jump table */
@@ -111,19 +111,21 @@ extern int (*__pmax_close)(int);
* On MIPS64 we have to call PROM functions via a helper
* dispatcher to accomodate ABI incompatibilities.
*/
-#define __DEC_PROM_O32 __attribute__((alias("call_o32")))
-
-int _rex_bootinit(int (*)(void)) __DEC_PROM_O32;
-int _rex_bootread(int (*)(void)) __DEC_PROM_O32;
-int _rex_getbitmap(int (*)(memmap *), memmap *) __DEC_PROM_O32;
-unsigned long *_rex_slot_address(unsigned long *(*)(int), int) __DEC_PROM_O32;
-void *_rex_gettcinfo(void *(*)(void)) __DEC_PROM_O32;
-int _rex_getsysid(int (*)(void)) __DEC_PROM_O32;
-void _rex_clear_cache(void (*)(void)) __DEC_PROM_O32;
-
-int _prom_getchar(int (*)(void)) __DEC_PROM_O32;
-char *_prom_getenv(char *(*)(char *), char *) __DEC_PROM_O32;
-int _prom_printf(int (*)(char *, ...), char *, ...) __DEC_PROM_O32;
+#define __DEC_PROM_O32(fun, arg) fun arg __asm__(#fun); \
+ __asm__(#fun " = call_o32")
+
+int __DEC_PROM_O32(_rex_bootinit, (int (*)(void)));
+int __DEC_PROM_O32(_rex_bootread, (int (*)(void)));
+int __DEC_PROM_O32(_rex_getbitmap, (int (*)(memmap *), memmap *));
+unsigned long *__DEC_PROM_O32(_rex_slot_address,
+ (unsigned long *(*)(int), int));
+void *__DEC_PROM_O32(_rex_gettcinfo, (void *(*)(void)));
+int __DEC_PROM_O32(_rex_getsysid, (int (*)(void)));
+void __DEC_PROM_O32(_rex_clear_cache, (void (*)(void)));
+
+int __DEC_PROM_O32(_prom_getchar, (int (*)(void)));
+char *__DEC_PROM_O32(_prom_getenv, (char *(*)(char *), char *));
+int __DEC_PROM_O32(_prom_printf, (int (*)(char *, ...), char *, ...));
#define rex_bootinit() _rex_bootinit(__rex_bootinit)
diff --git a/include/asm-mips/dec/system.h b/include/asm-mips/dec/system.h
new file mode 100644
index 000000000000..78af51fbc797
--- /dev/null
+++ b/include/asm-mips/dec/system.h
@@ -0,0 +1,18 @@
+/*
+ * include/asm-mips/dec/system.h
+ *
+ * Generic DECstation/DECsystem bits.
+ *
+ * Copyright (C) 2005 Maciej W. Rozycki
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#ifndef __ASM_DEC_SYSTEM_H
+#define __ASM_DEC_SYSTEM_H
+
+extern unsigned long dec_kn_slot_base, dec_kn_slot_size;
+
+#endif /* __ASM_DEC_SYSTEM_H */
diff --git a/include/asm-mips/dec/tc.h b/include/asm-mips/dec/tc.h
index d7bba43f863a..9cb51f24d42c 100644
--- a/include/asm-mips/dec/tc.h
+++ b/include/asm-mips/dec/tc.h
@@ -7,10 +7,8 @@
*
* Copyright (c) 1998 Harald Koerfgen
*/
-#ifndef ASM_TC_H
-#define ASM_TC_H
-
-extern unsigned long system_base;
+#ifndef __ASM_DEC_TC_H
+#define __ASM_DEC_TC_H
/*
* Search for a TURBOchannel Option Module
@@ -36,8 +34,8 @@ extern unsigned long get_tc_base_addr(int);
*/
extern unsigned long get_tc_irq_nr(int);
/*
- * Return TURBOchannel clock frequency in hz
+ * Return TURBOchannel clock frequency in Hz
*/
extern unsigned long get_tc_speed(void);
-#endif
+#endif /* __ASM_DEC_TC_H */
diff --git a/include/asm-mips/delay.h b/include/asm-mips/delay.h
index a606dbee0412..48d00cccdafa 100644
--- a/include/asm-mips/delay.h
+++ b/include/asm-mips/delay.h
@@ -12,11 +12,9 @@
#include <linux/config.h>
#include <linux/param.h>
-
+#include <linux/smp.h>
#include <asm/compiler.h>
-extern unsigned long loops_per_jiffy;
-
static inline void __delay(unsigned long loops)
{
if (sizeof(long) == 4)
@@ -82,12 +80,17 @@ static inline void __udelay(unsigned long usecs, unsigned long lpj)
__delay(usecs);
}
-#ifdef CONFIG_SMP
#define __udelay_val cpu_data[smp_processor_id()].udelay_val
-#else
-#define __udelay_val loops_per_jiffy
-#endif
#define udelay(usecs) __udelay((usecs),__udelay_val)
+/* make sure "usecs *= ..." in udelay do not overflow. */
+#if HZ >= 1000
+#define MAX_UDELAY_MS 1
+#elif HZ <= 200
+#define MAX_UDELAY_MS 5
+#else
+#define MAX_UDELAY_MS (1000 / HZ)
+#endif
+
#endif /* _ASM_DELAY_H */
diff --git a/include/asm-mips/dma-mapping.h b/include/asm-mips/dma-mapping.h
index af28dc88930b..43288634c38a 100644
--- a/include/asm-mips/dma-mapping.h
+++ b/include/asm-mips/dma-mapping.h
@@ -5,13 +5,13 @@
#include <asm/cache.h>
void *dma_alloc_noncoherent(struct device *dev, size_t size,
- dma_addr_t *dma_handle, int flag);
+ dma_addr_t *dma_handle, gfp_t flag);
void dma_free_noncoherent(struct device *dev, size_t size,
void *vaddr, dma_addr_t dma_handle);
void *dma_alloc_coherent(struct device *dev, size_t size,
- dma_addr_t *dma_handle, int flag);
+ dma_addr_t *dma_handle, gfp_t flag);
void dma_free_coherent(struct device *dev, size_t size,
void *vaddr, dma_addr_t dma_handle);
diff --git a/include/asm-mips/dsp.h b/include/asm-mips/dsp.h
new file mode 100644
index 000000000000..50f556bb4978
--- /dev/null
+++ b/include/asm-mips/dsp.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2005 Mips Technologies
+ * Author: Chris Dearman, chris@mips.com derived from fpu.h
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+#ifndef _ASM_DSP_H
+#define _ASM_DSP_H
+
+#include <asm/cpu.h>
+#include <asm/cpu-features.h>
+#include <asm/hazards.h>
+#include <asm/mipsregs.h>
+
+#define DSP_DEFAULT 0x00000000
+#define DSP_MASK 0x1f
+
+#define __enable_dsp_hazard() \
+do { \
+ asm("_ehb"); \
+} while (0)
+
+static inline void __init_dsp(void)
+{
+ mthi1(0);
+ mtlo1(0);
+ mthi2(0);
+ mtlo2(0);
+ mthi3(0);
+ mtlo3(0);
+ wrdsp(DSP_DEFAULT, DSP_MASK);
+}
+
+static inline void init_dsp(void)
+{
+ if (cpu_has_dsp)
+ __init_dsp();
+}
+
+#define __save_dsp(tsk) \
+do { \
+ tsk->thread.dsp.dspr[0] = mfhi1(); \
+ tsk->thread.dsp.dspr[1] = mflo1(); \
+ tsk->thread.dsp.dspr[2] = mfhi2(); \
+ tsk->thread.dsp.dspr[3] = mflo2(); \
+ tsk->thread.dsp.dspr[4] = mfhi3(); \
+ tsk->thread.dsp.dspr[5] = mflo3(); \
+} while (0)
+
+#define save_dsp(tsk) \
+do { \
+ if (cpu_has_dsp) \
+ __save_dsp(tsk); \
+} while (0)
+
+#define __restore_dsp(tsk) \
+do { \
+ mthi1(tsk->thread.dsp.dspr[0]); \
+ mtlo1(tsk->thread.dsp.dspr[1]); \
+ mthi2(tsk->thread.dsp.dspr[2]); \
+ mtlo2(tsk->thread.dsp.dspr[3]); \
+ mthi3(tsk->thread.dsp.dspr[4]); \
+ mtlo3(tsk->thread.dsp.dspr[5]); \
+} while (0)
+
+#define restore_dsp(tsk) \
+do { \
+ if (cpu_has_dsp) \
+ __restore_dsp(tsk); \
+} while (0)
+
+#define __get_dsp_regs(tsk) \
+({ \
+ if (tsk == current) \
+ __save_dsp(current); \
+ \
+ tsk->thread.dsp.dspr; \
+})
+
+#endif /* _ASM_DSP_H */
diff --git a/include/asm-mips/elf.h b/include/asm-mips/elf.h
index e48811440015..d2c9a25f8459 100644
--- a/include/asm-mips/elf.h
+++ b/include/asm-mips/elf.h
@@ -2,6 +2,8 @@
* 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.
+ *
+ * Much of this is taken from binutils and GNU libc ...
*/
#ifndef _ASM_ELF_H
#define _ASM_ELF_H
@@ -17,6 +19,8 @@
#define EF_MIPS_ARCH_5 0x40000000 /* -mips5 code. */
#define EF_MIPS_ARCH_32 0x50000000 /* MIPS32 code. */
#define EF_MIPS_ARCH_64 0x60000000 /* MIPS64 code. */
+#define EF_MIPS_ARCH_32R2 0x70000000 /* MIPS32 R2 code. */
+#define EF_MIPS_ARCH_64R2 0x80000000 /* MIPS64 R2 code. */
/* The ABI of a file. */
#define EF_MIPS_ABI_O32 0x00001000 /* O32 ABI. */
@@ -105,7 +109,11 @@
#define R_MIPS_LOVENDOR 100
#define R_MIPS_HIVENDOR 127
-#define SHN_MIPS_ACCOMON 0xff00
+#define SHN_MIPS_ACCOMON 0xff00 /* Allocated common symbols */
+#define SHN_MIPS_TEXT 0xff01 /* Allocated test symbols. */
+#define SHN_MIPS_DATA 0xff02 /* Allocated data symbols. */
+#define SHN_MIPS_SCOMMON 0xff03 /* Small common symbols */
+#define SHN_MIPS_SUNDEFINED 0xff04 /* Small undefined symbols */
#define SHT_MIPS_LIST 0x70000000
#define SHT_MIPS_CONFLICT 0x70000002
@@ -193,50 +201,94 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
#ifdef __KERNEL__
+struct mips_abi;
+
+extern struct mips_abi mips_abi;
+extern struct mips_abi mips_abi_32;
+extern struct mips_abi mips_abi_n32;
+
#ifdef CONFIG_32BIT
-#define SET_PERSONALITY(ex, ibcs2) \
-do { \
- if (ibcs2) \
- set_personality(PER_SVR4); \
- set_personality(PER_LINUX); \
+#define SET_PERSONALITY(ex, ibcs2) \
+do { \
+ if (ibcs2) \
+ set_personality(PER_SVR4); \
+ set_personality(PER_LINUX); \
+ \
+ current->thread.abi = &mips_abi; \
} while (0)
#endif /* CONFIG_32BIT */
#ifdef CONFIG_64BIT
-#define SET_PERSONALITY(ex, ibcs2) \
-do { current->thread.mflags &= ~MF_ABI_MASK; \
- if ((ex).e_ident[EI_CLASS] == ELFCLASS32) { \
- if ((((ex).e_flags & EF_MIPS_ABI2) != 0) && \
- ((ex).e_flags & EF_MIPS_ABI) == 0) \
- current->thread.mflags |= MF_N32; \
- else \
- current->thread.mflags |= MF_O32; \
- } else \
- current->thread.mflags |= MF_N64; \
- if (ibcs2) \
- set_personality(PER_SVR4); \
- else if (current->personality != PER_LINUX32) \
- set_personality(PER_LINUX); \
+#ifdef CONFIG_MIPS32_N32
+#define __SET_PERSONALITY32_N32() \
+ do { \
+ current->thread.mflags |= MF_N32; \
+ current->thread.abi = &mips_abi_n32; \
+ } while (0)
+#else
+#define __SET_PERSONALITY32_N32() \
+ do { } while (0)
+#endif
+
+#ifdef CONFIG_MIPS32_O32
+#define __SET_PERSONALITY32_O32() \
+ do { \
+ current->thread.mflags |= MF_O32; \
+ current->thread.abi = &mips_abi_32; \
+ } while (0)
+#else
+#define __SET_PERSONALITY32_O32() \
+ do { } while (0)
+#endif
+
+#ifdef CONFIG_MIPS32_COMPAT
+#define __SET_PERSONALITY32(ex) \
+do { \
+ if ((((ex).e_flags & EF_MIPS_ABI2) != 0) && \
+ ((ex).e_flags & EF_MIPS_ABI) == 0) \
+ __SET_PERSONALITY32_N32(); \
+ else \
+ __SET_PERSONALITY32_O32(); \
+} while (0)
+#else
+#define __SET_PERSONALITY32(ex) do { } while (0)
+#endif
+
+#define SET_PERSONALITY(ex, ibcs2) \
+do { \
+ current->thread.mflags &= ~MF_ABI_MASK; \
+ if ((ex).e_ident[EI_CLASS] == ELFCLASS32) \
+ __SET_PERSONALITY32(ex); \
+ else { \
+ current->thread.mflags |= MF_N64; \
+ current->thread.abi = &mips_abi; \
+ } \
+ \
+ if (ibcs2) \
+ set_personality(PER_SVR4); \
+ else if (current->personality != PER_LINUX32) \
+ set_personality(PER_LINUX); \
} while (0)
#endif /* CONFIG_64BIT */
+struct task_struct;
+
extern void dump_regs(elf_greg_t *, struct pt_regs *regs);
+extern int dump_task_regs (struct task_struct *, elf_gregset_t *);
extern int dump_task_fpu(struct task_struct *, elf_fpregset_t *);
#define ELF_CORE_COPY_REGS(elf_regs, regs) \
dump_regs((elf_greg_t *)&(elf_regs), regs);
+#define ELF_CORE_COPY_TASK_REGS(tsk, elf_regs) dump_task_regs(tsk, elf_regs)
#define ELF_CORE_COPY_FPREGS(tsk, elf_fpregs) \
dump_task_fpu(tsk, elf_fpregs)
#endif /* __KERNEL__ */
-/* This one accepts IRIX binaries. */
-#define irix_elf_check_arch(hdr) ((hdr)->e_flags & RHF_SGI_ONLY)
-
#define USE_ELF_CORE_DUMP
#define ELF_EXEC_PAGESIZE PAGE_SIZE
diff --git a/include/asm-mips/fcntl.h b/include/asm-mips/fcntl.h
index 06c5d13faf66..43d047a9a6af 100644
--- a/include/asm-mips/fcntl.h
+++ b/include/asm-mips/fcntl.h
@@ -3,11 +3,13 @@
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
- * Copyright (C) 1995, 96, 97, 98, 99, 2003 Ralf Baechle
+ * Copyright (C) 1995, 96, 97, 98, 99, 2003, 05 Ralf Baechle
*/
#ifndef _ASM_FCNTL_H
#define _ASM_FCNTL_H
+#include <linux/config.h>
+
#define O_APPEND 0x0008
#define O_SYNC 0x0010
#define O_NONBLOCK 0x0080
@@ -40,13 +42,13 @@
* contain all the same fields as struct flock.
*/
-#ifndef __mips64
+#ifdef CONFIG_32BIT
struct flock {
short l_type;
short l_whence;
- __kernel_off_t l_start;
- __kernel_off_t l_len;
+ off_t l_start;
+ off_t l_len;
long l_sysid;
__kernel_pid_t l_pid;
long pad[4];
@@ -54,13 +56,8 @@ struct flock {
#define HAVE_ARCH_STRUCT_FLOCK
-#endif
+#endif /* CONFIG_32BIT */
#include <asm-generic/fcntl.h>
-typedef struct flock flock_t;
-#ifndef __mips64
-typedef struct flock64 flock64_t;
-#endif
-
#endif /* _ASM_FCNTL_H */
diff --git a/include/asm-mips/fixmap.h b/include/asm-mips/fixmap.h
index 26b6a90a690b..73a3028dd9f9 100644
--- a/include/asm-mips/fixmap.h
+++ b/include/asm-mips/fixmap.h
@@ -107,4 +107,11 @@ static inline unsigned long virt_to_fix(const unsigned long vaddr)
return __virt_to_fix(vaddr);
}
+/*
+ * Called from pgtable_init()
+ */
+extern void fixrange_init(unsigned long start, unsigned long end,
+ pgd_t *pgd_base);
+
+
#endif
diff --git a/include/asm-mips/fpu.h b/include/asm-mips/fpu.h
index ea24e733b1bc..9c828b1f8218 100644
--- a/include/asm-mips/fpu.h
+++ b/include/asm-mips/fpu.h
@@ -80,9 +80,14 @@ do { \
#define clear_fpu_owner() clear_thread_flag(TIF_USEDFPU)
+static inline int __is_fpu_owner(void)
+{
+ return test_thread_flag(TIF_USEDFPU);
+}
+
static inline int is_fpu_owner(void)
{
- return cpu_has_fpu && test_thread_flag(TIF_USEDFPU);
+ return cpu_has_fpu && __is_fpu_owner();
}
static inline void own_fpu(void)
@@ -127,7 +132,7 @@ static inline void restore_fp(struct task_struct *tsk)
static inline fpureg_t *get_fpu_regs(struct task_struct *tsk)
{
if (cpu_has_fpu) {
- if ((tsk == current) && is_fpu_owner())
+ if ((tsk == current) && __is_fpu_owner())
_save_fp(current);
return tsk->thread.fpu.hard.fpr;
}
diff --git a/include/asm-mips/fpu_emulator.h b/include/asm-mips/fpu_emulator.h
index 46972ae2b95d..16cb4d11dd0b 100644
--- a/include/asm-mips/fpu_emulator.h
+++ b/include/asm-mips/fpu_emulator.h
@@ -23,16 +23,15 @@
#ifndef _ASM_FPU_EMULATOR_H
#define _ASM_FPU_EMULATOR_H
-struct mips_fpu_emulator_private {
- unsigned int eir;
- struct {
- unsigned int emulated;
- unsigned int loads;
- unsigned int stores;
- unsigned int cp1ops;
- unsigned int cp1xops;
- unsigned int errors;
- } stats;
+struct mips_fpu_emulator_stats {
+ unsigned int emulated;
+ unsigned int loads;
+ unsigned int stores;
+ unsigned int cp1ops;
+ unsigned int cp1xops;
+ unsigned int errors;
};
+extern struct mips_fpu_emulator_stats fpuemustats;
+
#endif /* _ASM_FPU_EMULATOR_H */
diff --git a/include/asm-mips/futex.h b/include/asm-mips/futex.h
index 9feff4ce1424..2454c44a8f54 100644
--- a/include/asm-mips/futex.h
+++ b/include/asm-mips/futex.h
@@ -3,10 +3,45 @@
#ifdef __KERNEL__
+#include <linux/config.h>
#include <linux/futex.h>
#include <asm/errno.h>
#include <asm/uaccess.h>
+#ifdef CONFIG_SMP
+#define __FUTEX_SMP_SYNC " sync \n"
+#else
+#define __FUTEX_SMP_SYNC
+#endif
+
+#define __futex_atomic_op(insn, ret, oldval, uaddr, oparg) \
+{ \
+ __asm__ __volatile__( \
+ " .set push \n" \
+ " .set noat \n" \
+ " .set mips3 \n" \
+ "1: ll %1, (%3) # __futex_atomic_op1 \n" \
+ " .set mips0 \n" \
+ " " insn " \n" \
+ " .set mips3 \n" \
+ "2: sc $1, (%3) \n" \
+ " beqzl $1, 1b \n" \
+ __FUTEX_SMP_SYNC \
+ "3: \n" \
+ " .set pop \n" \
+ " .set mips0 \n" \
+ " .section .fixup,\"ax\" \n" \
+ "4: li %0, %5 \n" \
+ " j 2b \n" \
+ " .previous \n" \
+ " .section __ex_table,\"a\" \n" \
+ " "__UA_ADDR "\t1b, 4b \n" \
+ " "__UA_ADDR "\t2b, 4b \n" \
+ " .previous \n" \
+ : "=r" (ret), "=r" (oldval) \
+ : "0" (0), "r" (uaddr), "Jr" (oparg), "i" (-EFAULT)); \
+}
+
static inline int
futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
{
@@ -25,10 +60,25 @@ futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
switch (op) {
case FUTEX_OP_SET:
+ __futex_atomic_op("move $1, %z4", ret, oldval, uaddr, oparg);
+ break;
+
case FUTEX_OP_ADD:
+ __futex_atomic_op("addu $1, %1, %z4",
+ ret, oldval, uaddr, oparg);
+ break;
case FUTEX_OP_OR:
+ __futex_atomic_op("or $1, %1, %z4",
+ ret, oldval, uaddr, oparg);
+ break;
case FUTEX_OP_ANDN:
+ __futex_atomic_op("and $1, %1, %z4",
+ ret, oldval, uaddr, ~oparg);
+ break;
case FUTEX_OP_XOR:
+ __futex_atomic_op("xor $1, %1, %z4",
+ ret, oldval, uaddr, oparg);
+ break;
default:
ret = -ENOSYS;
}
diff --git a/include/asm-mips/hazards.h b/include/asm-mips/hazards.h
index f524eaccd5f1..7517189e469f 100644
--- a/include/asm-mips/hazards.h
+++ b/include/asm-mips/hazards.h
@@ -74,7 +74,8 @@
#define irq_disable_hazard
_ehb
-#elif defined(CONFIG_CPU_R10000) || defined(CONFIG_CPU_RM9000)
+#elif defined(CONFIG_CPU_R10000) || defined(CONFIG_CPU_RM9000) || \
+ defined(CONFIG_CPU_SB1)
/*
* R10000 rocks - all hazards handled in hardware, so this becomes a nobrainer.
@@ -107,6 +108,7 @@ __asm__(
" .endm \n\t");
#ifdef CONFIG_CPU_RM9000
+
/*
* RM9000 hazards. When the JTLB is updated by tlbwi or tlbwr, a subsequent
* use of the JTLB for instructions should not occur for 4 cpu cycles and use
@@ -124,6 +126,9 @@ __asm__(
".set\tmips32\n\t" \
"_ssnop; _ssnop; _ssnop; _ssnop\n\t" \
".set\tmips0")
+
+#define back_to_back_c0_hazard() do { } while (0)
+
#else
/*
@@ -144,15 +149,13 @@ __asm__(
#endif
/*
- * mtc0->mfc0 hazard
- * The 24K has a 2 cycle mtc0/mfc0 execution hazard.
- * It is a MIPS32R2 processor so ehb will clear the hazard.
+ * Interrupt enable/disable hazards
+ * Some processors have hazards when modifying
+ * the status register to change the interrupt state
*/
#ifdef CONFIG_CPU_MIPSR2
-/*
- * Use a macro for ehb unless explicit support for MIPSR2 is enabled
- */
+
__asm__(
" .macro\tirq_enable_hazard \n\t"
" _ehb \n\t"
@@ -160,17 +163,26 @@ __asm__(
" \n\t"
" .macro\tirq_disable_hazard \n\t"
" _ehb \n\t"
+ " .endm \n\t"
+ " \n\t"
+ " .macro\tback_to_back_c0_hazard \n\t"
+ " _ehb \n\t"
" .endm");
#define irq_enable_hazard() \
__asm__ __volatile__( \
- "_ehb\t\t\t\t# irq_enable_hazard")
+ "irq_enable_hazard")
#define irq_disable_hazard() \
__asm__ __volatile__( \
- "_ehb\t\t\t\t# irq_disable_hazard")
+ "irq_disable_hazard")
+
+#define back_to_back_c0_hazard() \
+ __asm__ __volatile__( \
+ "back_to_back_c0_hazard")
-#elif defined(CONFIG_CPU_R10000) || defined(CONFIG_CPU_RM9000)
+#elif defined(CONFIG_CPU_R10000) || defined(CONFIG_CPU_RM9000) || \
+ defined(CONFIG_CPU_SB1)
/*
* R10000 rocks - all hazards handled in hardware, so this becomes a nobrainer.
@@ -186,6 +198,8 @@ __asm__(
#define irq_enable_hazard() do { } while (0)
#define irq_disable_hazard() do { } while (0)
+#define back_to_back_c0_hazard() do { } while (0)
+
#else
/*
@@ -208,10 +222,32 @@ __asm__(
#define irq_enable_hazard() do { } while (0)
#define irq_disable_hazard() \
__asm__ __volatile__( \
- "_ssnop; _ssnop; _ssnop;\t\t# irq_disable_hazard")
+ "irq_disable_hazard")
+
+#define back_to_back_c0_hazard() \
+ __asm__ __volatile__( \
+ " .set noreorder \n" \
+ " nop; nop; nop \n" \
+ " .set reorder \n")
#endif
+#ifdef CONFIG_CPU_MIPSR2
+#define instruction_hazard() \
+do { \
+__label__ __next; \
+ __asm__ __volatile__( \
+ " jr.hb %0 \n" \
+ : \
+ : "r" (&&__next)); \
+__next: \
+ ; \
+} while (0)
+
+#else
+#define instruction_hazard() do { } while (0)
+#endif
+
#endif /* __ASSEMBLY__ */
#endif /* _ASM_HAZARDS_H */
diff --git a/include/asm-mips/highmem.h b/include/asm-mips/highmem.h
index f49930d947d4..8cf598402492 100644
--- a/include/asm-mips/highmem.h
+++ b/include/asm-mips/highmem.h
@@ -75,6 +75,7 @@ static inline void *kmap_atomic(struct page *page, enum km_type type)
}
static inline void kunmap_atomic(void *kvaddr, enum km_type type) { }
+#define kmap_atomic_pfn(pfn, idx) page_address(pfn_to_page(pfn))
#define kmap_atomic_to_page(ptr) virt_to_page(ptr)
@@ -86,6 +87,7 @@ extern void *__kmap(struct page *page);
extern void __kunmap(struct page *page);
extern void *__kmap_atomic(struct page *page, enum km_type type);
extern void __kunmap_atomic(void *kvaddr, enum km_type type);
+extern void *kmap_atomic_pfn(unsigned long pfn, enum km_type type);
extern struct page *__kmap_atomic_to_page(void *ptr);
#define kmap __kmap
diff --git a/include/asm-mips/inst.h b/include/asm-mips/inst.h
index 6ad517241768..e0745f4ff624 100644
--- a/include/asm-mips/inst.h
+++ b/include/asm-mips/inst.h
@@ -28,7 +28,7 @@ enum major_op {
sdl_op, sdr_op, swr_op, cache_op,
ll_op, lwc1_op, lwc2_op, pref_op,
lld_op, ldc1_op, ldc2_op, ld_op,
- sc_op, swc1_op, swc2_op, major_3b_op, /* Opcode 0x3b is unused */
+ sc_op, swc1_op, swc2_op, rdhwr_op,
scd_op, sdc1_op, sdc2_op, sd_op
};
@@ -62,10 +62,10 @@ enum rt_op {
spimi_op, unused_rt_op_0x05, unused_rt_op_0x06, unused_rt_op_0x07,
tgei_op, tgeiu_op, tlti_op, tltiu_op,
teqi_op, unused_0x0d_rt_op, tnei_op, unused_0x0f_rt_op,
- bltzal_op, bgezal_op, bltzall_op, bgezall_op
- /*
- * The others (0x14 - 0x1f) are unused.
- */
+ bltzal_op, bgezal_op, bltzall_op, bgezall_op,
+ rt_op_0x14, rt_op_0x15, rt_op_0x16, rt_op_0x17,
+ rt_op_0x18, rt_op_0x19, rt_op_0x1a, rt_op_0x1b,
+ bposge32_op, rt_op_0x1d, rt_op_0x1e, rt_op_0x1f
};
/*
diff --git a/include/asm-mips/interrupt.h b/include/asm-mips/interrupt.h
index e8357f5379fa..a5735761f5e5 100644
--- a/include/asm-mips/interrupt.h
+++ b/include/asm-mips/interrupt.h
@@ -11,20 +11,25 @@
#ifndef _ASM_INTERRUPT_H
#define _ASM_INTERRUPT_H
+#include <linux/config.h>
#include <asm/hazards.h>
__asm__ (
- ".macro\tlocal_irq_enable\n\t"
- ".set\tpush\n\t"
- ".set\treorder\n\t"
- ".set\tnoat\n\t"
- "mfc0\t$1,$12\n\t"
- "ori\t$1,0x1f\n\t"
- "xori\t$1,0x1e\n\t"
- "mtc0\t$1,$12\n\t"
- "irq_enable_hazard\n\t"
- ".set\tpop\n\t"
- ".endm");
+ " .macro local_irq_enable \n"
+ " .set push \n"
+ " .set reorder \n"
+ " .set noat \n"
+#ifdef CONFIG_CPU_MIPSR2
+ " ei \n"
+#else
+ " mfc0 $1,$12 \n"
+ " ori $1,0x1f \n"
+ " xori $1,0x1e \n"
+ " mtc0 $1,$12 \n"
+#endif
+ " irq_enable_hazard \n"
+ " .set pop \n"
+ " .endm");
static inline void local_irq_enable(void)
{
@@ -43,17 +48,21 @@ static inline void local_irq_enable(void)
* no nops at all.
*/
__asm__ (
- ".macro\tlocal_irq_disable\n\t"
- ".set\tpush\n\t"
- ".set\tnoat\n\t"
- "mfc0\t$1,$12\n\t"
- "ori\t$1,1\n\t"
- "xori\t$1,1\n\t"
- ".set\tnoreorder\n\t"
- "mtc0\t$1,$12\n\t"
- "irq_disable_hazard\n\t"
- ".set\tpop\n\t"
- ".endm");
+ " .macro local_irq_disable\n"
+ " .set push \n"
+ " .set noat \n"
+#ifdef CONFIG_CPU_MIPSR2
+ " di \n"
+#else
+ " mfc0 $1,$12 \n"
+ " ori $1,1 \n"
+ " xori $1,1 \n"
+ " .set noreorder \n"
+ " mtc0 $1,$12 \n"
+#endif
+ " irq_disable_hazard \n"
+ " .set pop \n"
+ " .endm \n");
static inline void local_irq_disable(void)
{
@@ -65,12 +74,12 @@ static inline void local_irq_disable(void)
}
__asm__ (
- ".macro\tlocal_save_flags flags\n\t"
- ".set\tpush\n\t"
- ".set\treorder\n\t"
- "mfc0\t\\flags, $12\n\t"
- ".set\tpop\n\t"
- ".endm");
+ " .macro local_save_flags flags \n"
+ " .set push \n"
+ " .set reorder \n"
+ " mfc0 \\flags, $12 \n"
+ " .set pop \n"
+ " .endm \n");
#define local_save_flags(x) \
__asm__ __volatile__( \
@@ -78,18 +87,22 @@ __asm__ __volatile__( \
: "=r" (x))
__asm__ (
- ".macro\tlocal_irq_save result\n\t"
- ".set\tpush\n\t"
- ".set\treorder\n\t"
- ".set\tnoat\n\t"
- "mfc0\t\\result, $12\n\t"
- "ori\t$1, \\result, 1\n\t"
- "xori\t$1, 1\n\t"
- ".set\tnoreorder\n\t"
- "mtc0\t$1, $12\n\t"
- "irq_disable_hazard\n\t"
- ".set\tpop\n\t"
- ".endm");
+ " .macro local_irq_save result \n"
+ " .set push \n"
+ " .set reorder \n"
+ " .set noat \n"
+#ifdef CONFIG_CPU_MIPSR2
+ " di \\result \n"
+#else
+ " mfc0 \\result, $12 \n"
+ " ori $1, \\result, 1 \n"
+ " xori $1, 1 \n"
+ " .set noreorder \n"
+ " mtc0 $1, $12 \n"
+#endif
+ " irq_disable_hazard \n"
+ " .set pop \n"
+ " .endm \n");
#define local_irq_save(x) \
__asm__ __volatile__( \
@@ -99,19 +112,37 @@ __asm__ __volatile__( \
: "memory")
__asm__ (
- ".macro\tlocal_irq_restore flags\n\t"
- ".set\tnoreorder\n\t"
- ".set\tnoat\n\t"
- "mfc0\t$1, $12\n\t"
- "andi\t\\flags, 1\n\t"
- "ori\t$1, 1\n\t"
- "xori\t$1, 1\n\t"
- "or\t\\flags, $1\n\t"
- "mtc0\t\\flags, $12\n\t"
- "irq_disable_hazard\n\t"
- ".set\tat\n\t"
- ".set\treorder\n\t"
- ".endm");
+ " .macro local_irq_restore flags \n"
+ " .set noreorder \n"
+ " .set noat \n"
+#if defined(CONFIG_CPU_MIPSR2) && defined(CONFIG_IRQ_CPU)
+ /*
+ * Slow, but doesn't suffer from a relativly unlikely race
+ * condition we're having since days 1.
+ */
+ " beqz \\flags, 1f \n"
+ " di \n"
+ " ei \n"
+ "1: \n"
+#elif defined(CONFIG_CPU_MIPSR2)
+ /*
+ * Fast, dangerous. Life is fun, life is good.
+ */
+ " mfc0 $1, $12 \n"
+ " ins $1, \\flags, 0, 1 \n"
+ " mtc0 $1, $12 \n"
+#else
+ " mfc0 $1, $12 \n"
+ " andi \\flags, 1 \n"
+ " ori $1, 1 \n"
+ " xori $1, 1 \n"
+ " or \\flags, $1 \n"
+ " mtc0 \\flags, $12 \n"
+#endif
+ " irq_disable_hazard \n"
+ " .set at \n"
+ " .set reorder \n"
+ " .endm \n");
#define local_irq_restore(flags) \
do { \
diff --git a/include/asm-mips/inventory.h b/include/asm-mips/inventory.h
index 4cd36fe98173..92d90f75a636 100644
--- a/include/asm-mips/inventory.h
+++ b/include/asm-mips/inventory.h
@@ -4,6 +4,8 @@
#ifndef __ASM_INVENTORY_H
#define __ASM_INVENTORY_H
+#include <linux/compiler.h>
+
typedef struct inventory_s {
struct inventory_s *inv_next;
int inv_class;
@@ -14,7 +16,9 @@ typedef struct inventory_s {
} inventory_t;
extern int inventory_items;
-void add_to_inventory (int class, int type, int controller, int unit, int state);
-int dump_inventory_to_user (void *userbuf, int size);
+
+extern void add_to_inventory (int class, int type, int controller, int unit, int state);
+extern int dump_inventory_to_user (void __user *userbuf, int size);
+extern int __init init_inventory(void);
#endif /* __ASM_INVENTORY_H */
diff --git a/include/asm-mips/io.h b/include/asm-mips/io.h
index 039845f2e6b0..3061870b7f6c 100644
--- a/include/asm-mips/io.h
+++ b/include/asm-mips/io.h
@@ -25,7 +25,9 @@
#include <asm/page.h>
#include <asm/pgtable-bits.h>
#include <asm/processor.h>
+#include <asm/string.h>
+#include <ioremap.h>
#include <mangle-port.h>
/*
@@ -34,7 +36,7 @@
#undef CONF_SLOWDOWN_IO
/*
- * Raw operations are never swapped in software. Otoh values that raw
+ * Raw operations are never swapped in software. OTOH values that raw
* operations are working on may or may not have been swapped by the bus
* hardware. An example use would be for flash memory that's used for
* execute in place.
@@ -43,45 +45,53 @@
# define __raw_ioswabw(x) (x)
# define __raw_ioswabl(x) (x)
# define __raw_ioswabq(x) (x)
+# define ____raw_ioswabq(x) (x)
/*
* Sane hardware offers swapping of PCI/ISA I/O space accesses in hardware;
* less sane hardware forces software to fiddle with this...
+ *
+ * Regardless, if the host bus endianness mismatches that of PCI/ISA, then
+ * you can't have the numerical value of data and byte addresses within
+ * multibyte quantities both preserved at the same time. Hence two
+ * variations of functions: non-prefixed ones that preserve the value
+ * and prefixed ones that preserve byte addresses. The latters are
+ * typically used for moving raw data between a peripheral and memory (cf.
+ * string I/O functions), hence the "mem_" prefix.
*/
#if defined(CONFIG_SWAP_IO_SPACE)
# define ioswabb(x) (x)
+# define mem_ioswabb(x) (x)
# ifdef CONFIG_SGI_IP22
/*
* IP22 seems braindead enough to swap 16bits values in hardware, but
* not 32bits. Go figure... Can't tell without documentation.
*/
# define ioswabw(x) (x)
+# define mem_ioswabw(x) le16_to_cpu(x)
# else
# define ioswabw(x) le16_to_cpu(x)
+# define mem_ioswabw(x) (x)
# endif
# define ioswabl(x) le32_to_cpu(x)
+# define mem_ioswabl(x) (x)
# define ioswabq(x) le64_to_cpu(x)
+# define mem_ioswabq(x) (x)
#else
# define ioswabb(x) (x)
+# define mem_ioswabb(x) (x)
# define ioswabw(x) (x)
+# define mem_ioswabw(x) cpu_to_le16(x)
# define ioswabl(x) (x)
+# define mem_ioswabl(x) cpu_to_le32(x)
# define ioswabq(x) (x)
+# define mem_ioswabq(x) cpu_to_le32(x)
#endif
-/*
- * Native bus accesses never swapped.
- */
-#define bus_ioswabb(x) (x)
-#define bus_ioswabw(x) (x)
-#define bus_ioswabl(x) (x)
-#define bus_ioswabq(x) (x)
-
-#define __bus_ioswabq bus_ioswabq
-
#define IO_SPACE_LIMIT 0xffff
/*
@@ -194,12 +204,14 @@ extern unsigned long isa_slot_offset;
*/
#define page_to_phys(page) ((dma_addr_t)page_to_pfn(page) << PAGE_SHIFT)
-extern void * __ioremap(phys_t offset, phys_t size, unsigned long flags);
+extern void __iomem * __ioremap(phys_t offset, phys_t size, unsigned long flags);
extern void __iounmap(volatile void __iomem *addr);
-static inline void * __ioremap_mode(phys_t offset, unsigned long size,
+static inline void __iomem * __ioremap_mode(phys_t offset, unsigned long size,
unsigned long flags)
{
+#define __IS_LOW512(addr) (!((phys_t)(addr) & (phys_t) ~0x1fffffffULL))
+
if (cpu_has_64bit_addresses) {
u64 base = UNCAC_BASE;
@@ -209,10 +221,30 @@ static inline void * __ioremap_mode(phys_t offset, unsigned long size,
*/
if (flags == _CACHE_UNCACHED)
base = (u64) IO_BASE;
- return (void *) (unsigned long) (base + offset);
+ return (void __iomem *) (unsigned long) (base + offset);
+ } else if (__builtin_constant_p(offset) &&
+ __builtin_constant_p(size) && __builtin_constant_p(flags)) {
+ phys_t phys_addr, last_addr;
+
+ phys_addr = fixup_bigphys_addr(offset, size);
+
+ /* Don't allow wraparound or zero size. */
+ last_addr = phys_addr + size - 1;
+ if (!size || last_addr < phys_addr)
+ return NULL;
+
+ /*
+ * Map uncached objects in the low 512MB of address
+ * space using KSEG1.
+ */
+ if (__IS_LOW512(phys_addr) && __IS_LOW512(last_addr) &&
+ flags == _CACHE_UNCACHED)
+ return (void __iomem *)CKSEG1ADDR(phys_addr);
}
return __ioremap(offset, size, flags);
+
+#undef __IS_LOW512
}
/*
@@ -264,12 +296,16 @@ static inline void * __ioremap_mode(phys_t offset, unsigned long size,
static inline void iounmap(volatile void __iomem *addr)
{
- if (cpu_has_64bit_addresses)
+#define __IS_KSEG1(addr) (((unsigned long)(addr) & ~0x1fffffffUL) == CKSEG1)
+
+ if (cpu_has_64bit_addresses ||
+ (__builtin_constant_p(addr) && __IS_KSEG1(addr)))
return;
__iounmap(addr);
-}
+#undef __IS_KSEG1
+}
#define __BUILD_MEMORY_SINGLE(pfx, bwlq, type, irq) \
\
@@ -319,7 +355,8 @@ static inline type pfx##read##bwlq(volatile void __iomem *mem) \
else if (cpu_has_64bits) { \
unsigned long __flags; \
\
- local_irq_save(__flags); \
+ if (irq) \
+ local_irq_save(__flags); \
__asm__ __volatile__( \
".set mips3" "\t\t# __readq" "\n\t" \
"ld %L0, %1" "\n\t" \
@@ -328,7 +365,8 @@ static inline type pfx##read##bwlq(volatile void __iomem *mem) \
".set mips0" "\n" \
: "=r" (__val) \
: "m" (*__mem)); \
- local_irq_restore(__flags); \
+ if (irq) \
+ local_irq_restore(__flags); \
} else { \
__val = 0; \
BUG(); \
@@ -349,11 +387,11 @@ static inline void pfx##out##bwlq##p(type val, unsigned long port) \
\
__val = pfx##ioswab##bwlq(val); \
\
- if (sizeof(type) != sizeof(u64)) { \
- *__addr = __val; \
- slow; \
- } else \
- BUILD_BUG(); \
+ /* Really, we want this to be atomic */ \
+ BUILD_BUG_ON(sizeof(type) > sizeof(unsigned long)); \
+ \
+ *__addr = __val; \
+ slow; \
} \
\
static inline type pfx##in##bwlq##p(unsigned long port) \
@@ -364,13 +402,10 @@ static inline type pfx##in##bwlq##p(unsigned long port) \
port = __swizzle_addr_##bwlq(port); \
__addr = (void *)(mips_io_port_base + port); \
\
- if (sizeof(type) != sizeof(u64)) { \
- __val = *__addr; \
- slow; \
- } else { \
- __val = 0; \
- BUILD_BUG(); \
- } \
+ BUILD_BUG_ON(sizeof(type) > sizeof(unsigned long)); \
+ \
+ __val = *__addr; \
+ slow; \
\
return pfx##ioswab##bwlq(__val); \
}
@@ -379,27 +414,35 @@ static inline type pfx##in##bwlq##p(unsigned long port) \
\
__BUILD_MEMORY_SINGLE(bus, bwlq, type, 1)
-#define __BUILD_IOPORT_PFX(bus, bwlq, type) \
- \
-__BUILD_IOPORT_SINGLE(bus, bwlq, type, ,) \
-__BUILD_IOPORT_SINGLE(bus, bwlq, type, _p, SLOW_DOWN_IO)
-
-#define BUILDIO(bwlq, type) \
+#define BUILDIO_MEM(bwlq, type) \
\
-__BUILD_MEMORY_PFX(, bwlq, type) \
__BUILD_MEMORY_PFX(__raw_, bwlq, type) \
-__BUILD_MEMORY_PFX(bus_, bwlq, type) \
-__BUILD_IOPORT_PFX(, bwlq, type) \
-__BUILD_IOPORT_PFX(__raw_, bwlq, type)
+__BUILD_MEMORY_PFX(, bwlq, type) \
+__BUILD_MEMORY_PFX(mem_, bwlq, type) \
+
+BUILDIO_MEM(b, u8)
+BUILDIO_MEM(w, u16)
+BUILDIO_MEM(l, u32)
+BUILDIO_MEM(q, u64)
+
+#define __BUILD_IOPORT_PFX(bus, bwlq, type) \
+ __BUILD_IOPORT_SINGLE(bus, bwlq, type, ,) \
+ __BUILD_IOPORT_SINGLE(bus, bwlq, type, _p, SLOW_DOWN_IO)
+
+#define BUILDIO_IOPORT(bwlq, type) \
+ __BUILD_IOPORT_PFX(, bwlq, type) \
+ __BUILD_IOPORT_PFX(mem_, bwlq, type)
+
+BUILDIO_IOPORT(b, u8)
+BUILDIO_IOPORT(w, u16)
+BUILDIO_IOPORT(l, u32)
+#ifdef CONFIG_64BIT
+BUILDIO_IOPORT(q, u64)
+#endif
#define __BUILDIO(bwlq, type) \
\
-__BUILD_MEMORY_SINGLE(__bus_, bwlq, type, 0)
-
-BUILDIO(b, u8)
-BUILDIO(w, u16)
-BUILDIO(l, u32)
-BUILDIO(q, u64)
+__BUILD_MEMORY_SINGLE(____raw_, bwlq, type, 0)
__BUILDIO(q, u64)
@@ -422,7 +465,7 @@ static inline void writes##bwlq(volatile void __iomem *mem, void *addr, \
volatile type *__addr = addr; \
\
while (count--) { \
- __raw_write##bwlq(*__addr, mem); \
+ mem_write##bwlq(*__addr, mem); \
__addr++; \
} \
} \
@@ -433,20 +476,20 @@ static inline void reads##bwlq(volatile void __iomem *mem, void *addr, \
volatile type *__addr = addr; \
\
while (count--) { \
- *__addr = __raw_read##bwlq(mem); \
+ *__addr = mem_read##bwlq(mem); \
__addr++; \
} \
}
#define __BUILD_IOPORT_STRING(bwlq, type) \
\
-static inline void outs##bwlq(unsigned long port, void *addr, \
+static inline void outs##bwlq(unsigned long port, const void *addr, \
unsigned int count) \
{ \
- volatile type *__addr = addr; \
+ const volatile type *__addr = addr; \
\
while (count--) { \
- __raw_out##bwlq(*__addr, port); \
+ mem_out##bwlq(*__addr, port); \
__addr++; \
} \
} \
@@ -457,7 +500,7 @@ static inline void ins##bwlq(unsigned long port, void *addr, \
volatile type *__addr = addr; \
\
while (count--) { \
- *__addr = __raw_in##bwlq(port); \
+ *__addr = mem_in##bwlq(port); \
__addr++; \
} \
}
@@ -470,15 +513,26 @@ __BUILD_IOPORT_STRING(bwlq, type)
BUILDSTRING(b, u8)
BUILDSTRING(w, u16)
BUILDSTRING(l, u32)
+#ifdef CONFIG_64BIT
BUILDSTRING(q, u64)
+#endif
/* Depends on MIPS II instruction set */
#define mmiowb() asm volatile ("sync" ::: "memory")
-#define memset_io(a,b,c) memset((void *)(a),(b),(c))
-#define memcpy_fromio(a,b,c) memcpy((a),(void *)(b),(c))
-#define memcpy_toio(a,b,c) memcpy((void *)(a),(b),(c))
+static inline void memset_io(volatile void __iomem *addr, unsigned char val, int count)
+{
+ memset((void __force *) addr, val, count);
+}
+static inline void memcpy_fromio(void *dst, const volatile void __iomem *src, int count)
+{
+ memcpy(dst, (void __force *) src, count);
+}
+static inline void memcpy_toio(volatile void __iomem *dst, const void *src, int count)
+{
+ memcpy((void __force *) dst, src, count);
+}
/*
* Memory Mapped I/O
diff --git a/include/asm-mips/ip32/mace.h b/include/asm-mips/ip32/mace.h
index 432011b16c26..5bdc51d85b6c 100644
--- a/include/asm-mips/ip32/mace.h
+++ b/include/asm-mips/ip32/mace.h
@@ -147,6 +147,29 @@ struct mace_audio {
} chan[3];
};
+
+/* register definitions for parallel port DMA */
+struct mace_parport {
+/* 0 - do nothing, 1 - pulse terminal count to the device after buffer is drained */
+#define MACEPAR_CONTEXT_LASTFLAG BIT(63)
+/* Should not cross 4K page boundary */
+#define MACEPAR_CONTEXT_DATALEN_MASK 0xfff00000000
+/* Can be arbitrarily aligned on any byte boundary on output, 64 byte aligned on input */
+#define MACEPAR_CONTEXT_BASEADDR_MASK 0xffffffff
+ volatile u64 context_a;
+ volatile u64 context_b;
+#define MACEPAR_CTLSTAT_DIRECTION BIT(0) /* 0 - mem->device, 1 - device->mem */
+#define MACEPAR_CTLSTAT_ENABLE BIT(1) /* 0 - channel frozen, 1 - channel enabled */
+#define MACEPAR_CTLSTAT_RESET BIT(2) /* 0 - channel active, 1 - complete channel reset */
+#define MACEPAR_CTLSTAT_CTXB_VALID BIT(3)
+#define MACEPAR_CTLSTAT_CTXA_VALID BIT(4)
+ volatile u64 cntlstat; /* Control/Status register */
+#define MACEPAR_DIAG_CTXINUSE BIT(1)
+#define MACEPAR_DIAG_DMACTIVE BIT(2) /* 1 - Dma engine is enabled and processing something */
+#define MACEPAR_DIAG_CTRMASK 0x3ffc /* Counter of bytes left */
+ volatile u64 diagnostic; /* RO: diagnostic register */
+};
+
/* ISA Control and DMA registers */
struct mace_isactrl {
volatile unsigned long ringbase;
@@ -199,6 +222,7 @@ struct mace_isactrl {
volatile unsigned long _pad[0x2000/8 - 4];
volatile unsigned long dp_ram[0x400];
+ struct mace_parport parport;
};
/* Keyboard & Mouse registers
@@ -277,7 +301,7 @@ struct mace_perif {
*/
/* Parallel port */
-struct mace_parallel { /* later... */
+struct mace_parallel {
};
struct mace_ecp1284 { /* later... */
diff --git a/include/asm-mips/irq.h b/include/asm-mips/irq.h
index 3f2470e9e678..8a342ccb34a8 100644
--- a/include/asm-mips/irq.h
+++ b/include/asm-mips/irq.h
@@ -24,11 +24,9 @@ static inline int irq_canonicalize(int irq)
struct pt_regs;
-#ifdef CONFIG_PREEMPT
-
extern asmlinkage unsigned int do_IRQ(unsigned int irq, struct pt_regs *regs);
-#else
+#ifdef CONFIG_PREEMPT
/*
* do_IRQ handles all normal device IRQ's (the special
diff --git a/include/asm-mips/jmr3927/jmr3927.h b/include/asm-mips/jmr3927/jmr3927.h
index 86df317b4078..baf412967afa 100644
--- a/include/asm-mips/jmr3927/jmr3927.h
+++ b/include/asm-mips/jmr3927/jmr3927.h
@@ -202,20 +202,6 @@ static inline int jmr3927_have_isac(void)
#endif /* !__ASSEMBLY__ */
/*
- * UART defines for serial.h
- */
-
-/* use Pre-scaler T0 (1/2) */
-#define JMR3927_BASE_BAUD (JMR3927_IMCLK / 2 / 16)
-
-#define UART0_ADDR 0xfffef300
-#define UART1_ADDR 0xfffef400
-#define UART0_INT JMR3927_IRQ_IRC_SIO0
-#define UART1_INT JMR3927_IRQ_IRC_SIO1
-#define UART0_FLAGS ASYNC_BOOT_AUTOCONF
-#define UART1_FLAGS 0
-
-/*
* IRQ mappings
*/
diff --git a/include/asm-mips/mach-au1x00/au1000.h b/include/asm-mips/mach-au1x00/au1000.h
index 148bae2fa7d3..8327ec341c18 100644
--- a/include/asm-mips/mach-au1x00/au1000.h
+++ b/include/asm-mips/mach-au1x00/au1000.h
@@ -60,59 +60,36 @@ void static inline au_sync_delay(int ms)
mdelay(ms);
}
-void static inline au_writeb(u8 val, int reg)
+void static inline au_writeb(u8 val, unsigned long reg)
{
*(volatile u8 *)(reg) = val;
}
-void static inline au_writew(u16 val, int reg)
+void static inline au_writew(u16 val, unsigned long reg)
{
*(volatile u16 *)(reg) = val;
}
-void static inline au_writel(u32 val, int reg)
+void static inline au_writel(u32 val, unsigned long reg)
{
*(volatile u32 *)(reg) = val;
}
-static inline u8 au_readb(unsigned long port)
+static inline u8 au_readb(unsigned long reg)
{
- return (*(volatile u8 *)port);
+ return (*(volatile u8 *)reg);
}
-static inline u16 au_readw(unsigned long port)
+static inline u16 au_readw(unsigned long reg)
{
- return (*(volatile u16 *)port);
+ return (*(volatile u16 *)reg);
}
-static inline u32 au_readl(unsigned long port)
+static inline u32 au_readl(unsigned long reg)
{
- return (*(volatile u32 *)port);
+ return (*(volatile u32 *)reg);
}
-/* These next three functions should be a generic part of the MIPS
- * kernel (with the 'au_' removed from the name) and selected for
- * processors that support the instructions.
- * Taken from PPC tree. -- Dan
- */
-/* Return the bit position of the most significant 1 bit in a word */
-static __inline__ int __ilog2(unsigned int x)
-{
- int lz;
-
- asm volatile (
- ".set\tnoreorder\n\t"
- ".set\tnoat\n\t"
- ".set\tmips32\n\t"
- "clz\t%0,%1\n\t"
- ".set\tmips0\n\t"
- ".set\tat\n\t"
- ".set\treorder"
- : "=r" (lz)
- : "r" (x));
-
- return 31 - lz;
-}
static __inline__ int au_ffz(unsigned int x)
{
@@ -162,28 +139,293 @@ extern au1xxx_irq_map_t au1xxx_irq_map[];
#define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5)
#endif
-/* SDRAM Controller */
+/*
+ * SDRAM Register Offsets
+ */
#if defined(CONFIG_SOC_AU1000) || defined(CONFIG_SOC_AU1500) || defined(CONFIG_SOC_AU1100)
-#define MEM_SDMODE0 0xB4000000
-#define MEM_SDMODE1 0xB4000004
-#define MEM_SDMODE2 0xB4000008
+#define MEM_SDMODE0 (0x0000)
+#define MEM_SDMODE1 (0x0004)
+#define MEM_SDMODE2 (0x0008)
+#define MEM_SDADDR0 (0x000C)
+#define MEM_SDADDR1 (0x0010)
+#define MEM_SDADDR2 (0x0014)
+#define MEM_SDREFCFG (0x0018)
+#define MEM_SDPRECMD (0x001C)
+#define MEM_SDAUTOREF (0x0020)
+#define MEM_SDWRMD0 (0x0024)
+#define MEM_SDWRMD1 (0x0028)
+#define MEM_SDWRMD2 (0x002C)
+#define MEM_SDSLEEP (0x0030)
+#define MEM_SDSMCKE (0x0034)
-#define MEM_SDADDR0 0xB400000C
-#define MEM_SDADDR1 0xB4000010
-#define MEM_SDADDR2 0xB4000014
+/*
+ * MEM_SDMODE register content definitions
+ */
+#define MEM_SDMODE_F (1<<22)
+#define MEM_SDMODE_SR (1<<21)
+#define MEM_SDMODE_BS (1<<20)
+#define MEM_SDMODE_RS (3<<18)
+#define MEM_SDMODE_CS (7<<15)
+#define MEM_SDMODE_TRAS (15<<11)
+#define MEM_SDMODE_TMRD (3<<9)
+#define MEM_SDMODE_TWR (3<<7)
+#define MEM_SDMODE_TRP (3<<5)
+#define MEM_SDMODE_TRCD (3<<3)
+#define MEM_SDMODE_TCL (7<<0)
+
+#define MEM_SDMODE_BS_2Bank (0<<20)
+#define MEM_SDMODE_BS_4Bank (1<<20)
+#define MEM_SDMODE_RS_11Row (0<<18)
+#define MEM_SDMODE_RS_12Row (1<<18)
+#define MEM_SDMODE_RS_13Row (2<<18)
+#define MEM_SDMODE_RS_N(N) ((N)<<18)
+#define MEM_SDMODE_CS_7Col (0<<15)
+#define MEM_SDMODE_CS_8Col (1<<15)
+#define MEM_SDMODE_CS_9Col (2<<15)
+#define MEM_SDMODE_CS_10Col (3<<15)
+#define MEM_SDMODE_CS_11Col (4<<15)
+#define MEM_SDMODE_CS_N(N) ((N)<<15)
+#define MEM_SDMODE_TRAS_N(N) ((N)<<11)
+#define MEM_SDMODE_TMRD_N(N) ((N)<<9)
+#define MEM_SDMODE_TWR_N(N) ((N)<<7)
+#define MEM_SDMODE_TRP_N(N) ((N)<<5)
+#define MEM_SDMODE_TRCD_N(N) ((N)<<3)
+#define MEM_SDMODE_TCL_N(N) ((N)<<0)
-#define MEM_SDREFCFG 0xB4000018
-#define MEM_SDPRECMD 0xB400001C
-#define MEM_SDAUTOREF 0xB4000020
+/*
+ * MEM_SDADDR register contents definitions
+ */
+#define MEM_SDADDR_E (1<<20)
+#define MEM_SDADDR_CSBA (0x03FF<<10)
+#define MEM_SDADDR_CSMASK (0x03FF<<0)
+#define MEM_SDADDR_CSBA_N(N) ((N)&(0x03FF<<22)>>12)
+#define MEM_SDADDR_CSMASK_N(N) ((N)&(0x03FF<<22)>>22)
+
+/*
+ * MEM_SDREFCFG register content definitions
+ */
+#define MEM_SDREFCFG_TRC (15<<28)
+#define MEM_SDREFCFG_TRPM (3<<26)
+#define MEM_SDREFCFG_E (1<<25)
+#define MEM_SDREFCFG_RE (0x1ffffff<<0)
+#define MEM_SDREFCFG_TRC_N(N) ((N)<<MEM_SDREFCFG_TRC)
+#define MEM_SDREFCFG_TRPM_N(N) ((N)<<MEM_SDREFCFG_TRPM)
+#define MEM_SDREFCFG_REF_N(N) (N)
+#endif
-#define MEM_SDWRMD0 0xB4000024
-#define MEM_SDWRMD1 0xB4000028
-#define MEM_SDWRMD2 0xB400002C
+/***********************************************************************/
-#define MEM_SDSLEEP 0xB4000030
-#define MEM_SDSMCKE 0xB4000034
+/*
+ * Au1550 SDRAM Register Offsets
+ */
+
+/***********************************************************************/
+
+#if defined(CONFIG_SOC_AU1550) || defined(CONFIG_SOC_AU1200)
+#define MEM_SDMODE0 (0x0800)
+#define MEM_SDMODE1 (0x0808)
+#define MEM_SDMODE2 (0x0810)
+#define MEM_SDADDR0 (0x0820)
+#define MEM_SDADDR1 (0x0828)
+#define MEM_SDADDR2 (0x0830)
+#define MEM_SDCONFIGA (0x0840)
+#define MEM_SDCONFIGB (0x0848)
+#define MEM_SDSTAT (0x0850)
+#define MEM_SDERRADDR (0x0858)
+#define MEM_SDSTRIDE0 (0x0860)
+#define MEM_SDSTRIDE1 (0x0868)
+#define MEM_SDSTRIDE2 (0x0870)
+#define MEM_SDWRMD0 (0x0880)
+#define MEM_SDWRMD1 (0x0888)
+#define MEM_SDWRMD2 (0x0890)
+#define MEM_SDPRECMD (0x08C0)
+#define MEM_SDAUTOREF (0x08C8)
+#define MEM_SDSREF (0x08D0)
+#define MEM_SDSLEEP MEM_SDSREF
+
+#endif
+
+/*
+ * Physical base addresses for integrated peripherals
+ */
+
+#ifdef CONFIG_SOC_AU1000
+#define MEM_PHYS_ADDR 0x14000000
+#define STATIC_MEM_PHYS_ADDR 0x14001000
+#define DMA0_PHYS_ADDR 0x14002000
+#define DMA1_PHYS_ADDR 0x14002100
+#define DMA2_PHYS_ADDR 0x14002200
+#define DMA3_PHYS_ADDR 0x14002300
+#define DMA4_PHYS_ADDR 0x14002400
+#define DMA5_PHYS_ADDR 0x14002500
+#define DMA6_PHYS_ADDR 0x14002600
+#define DMA7_PHYS_ADDR 0x14002700
+#define IC0_PHYS_ADDR 0x10400000
+#define IC1_PHYS_ADDR 0x11800000
+#define AC97_PHYS_ADDR 0x10000000
+#define USBH_PHYS_ADDR 0x10100000
+#define USBD_PHYS_ADDR 0x10200000
+#define IRDA_PHYS_ADDR 0x10300000
+#define MAC0_PHYS_ADDR 0x10500000
+#define MAC1_PHYS_ADDR 0x10510000
+#define MACEN_PHYS_ADDR 0x10520000
+#define MACDMA0_PHYS_ADDR 0x14004000
+#define MACDMA1_PHYS_ADDR 0x14004200
+#define I2S_PHYS_ADDR 0x11000000
+#define UART0_PHYS_ADDR 0x11100000
+#define UART1_PHYS_ADDR 0x11200000
+#define UART2_PHYS_ADDR 0x11300000
+#define UART3_PHYS_ADDR 0x11400000
+#define SSI0_PHYS_ADDR 0x11600000
+#define SSI1_PHYS_ADDR 0x11680000
+#define SYS_PHYS_ADDR 0x11900000
+#define PCMCIA_IO_PHYS_ADDR 0xF00000000ULL
+#define PCMCIA_ATTR_PHYS_ADDR 0xF40000000ULL
+#define PCMCIA_MEM_PHYS_ADDR 0xF80000000ULL
#endif
+/********************************************************************/
+
+#ifdef CONFIG_SOC_AU1500
+#define MEM_PHYS_ADDR 0x14000000
+#define STATIC_MEM_PHYS_ADDR 0x14001000
+#define DMA0_PHYS_ADDR 0x14002000
+#define DMA1_PHYS_ADDR 0x14002100
+#define DMA2_PHYS_ADDR 0x14002200
+#define DMA3_PHYS_ADDR 0x14002300
+#define DMA4_PHYS_ADDR 0x14002400
+#define DMA5_PHYS_ADDR 0x14002500
+#define DMA6_PHYS_ADDR 0x14002600
+#define DMA7_PHYS_ADDR 0x14002700
+#define IC0_PHYS_ADDR 0x10400000
+#define IC1_PHYS_ADDR 0x11800000
+#define AC97_PHYS_ADDR 0x10000000
+#define USBH_PHYS_ADDR 0x10100000
+#define USBD_PHYS_ADDR 0x10200000
+#define PCI_PHYS_ADDR 0x14005000
+#define MAC0_PHYS_ADDR 0x11500000
+#define MAC1_PHYS_ADDR 0x11510000
+#define MACEN_PHYS_ADDR 0x11520000
+#define MACDMA0_PHYS_ADDR 0x14004000
+#define MACDMA1_PHYS_ADDR 0x14004200
+#define I2S_PHYS_ADDR 0x11000000
+#define UART0_PHYS_ADDR 0x11100000
+#define UART3_PHYS_ADDR 0x11400000
+#define GPIO2_PHYS_ADDR 0x11700000
+#define SYS_PHYS_ADDR 0x11900000
+#define PCI_MEM_PHYS_ADDR 0x400000000ULL
+#define PCI_IO_PHYS_ADDR 0x500000000ULL
+#define PCI_CONFIG0_PHYS_ADDR 0x600000000ULL
+#define PCI_CONFIG1_PHYS_ADDR 0x680000000ULL
+#define PCMCIA_IO_PHYS_ADDR 0xF00000000ULL
+#define PCMCIA_ATTR_PHYS_ADDR 0xF40000000ULL
+#define PCMCIA_MEM_PHYS_ADDR 0xF80000000ULL
+#endif
+
+/********************************************************************/
+
+#ifdef CONFIG_SOC_AU1100
+#define MEM_PHYS_ADDR 0x14000000
+#define STATIC_MEM_PHYS_ADDR 0x14001000
+#define DMA0_PHYS_ADDR 0x14002000
+#define DMA1_PHYS_ADDR 0x14002100
+#define DMA2_PHYS_ADDR 0x14002200
+#define DMA3_PHYS_ADDR 0x14002300
+#define DMA4_PHYS_ADDR 0x14002400
+#define DMA5_PHYS_ADDR 0x14002500
+#define DMA6_PHYS_ADDR 0x14002600
+#define DMA7_PHYS_ADDR 0x14002700
+#define IC0_PHYS_ADDR 0x10400000
+#define SD0_PHYS_ADDR 0x10600000
+#define SD1_PHYS_ADDR 0x10680000
+#define IC1_PHYS_ADDR 0x11800000
+#define AC97_PHYS_ADDR 0x10000000
+#define USBH_PHYS_ADDR 0x10100000
+#define USBD_PHYS_ADDR 0x10200000
+#define IRDA_PHYS_ADDR 0x10300000
+#define MAC0_PHYS_ADDR 0x10500000
+#define MACEN_PHYS_ADDR 0x10520000
+#define MACDMA0_PHYS_ADDR 0x14004000
+#define MACDMA1_PHYS_ADDR 0x14004200
+#define I2S_PHYS_ADDR 0x11000000
+#define UART0_PHYS_ADDR 0x11100000
+#define UART1_PHYS_ADDR 0x11200000
+#define UART3_PHYS_ADDR 0x11400000
+#define SSI0_PHYS_ADDR 0x11600000
+#define SSI1_PHYS_ADDR 0x11680000
+#define GPIO2_PHYS_ADDR 0x11700000
+#define SYS_PHYS_ADDR 0x11900000
+#define LCD_PHYS_ADDR 0x15000000
+#define PCMCIA_IO_PHYS_ADDR 0xF00000000ULL
+#define PCMCIA_ATTR_PHYS_ADDR 0xF40000000ULL
+#define PCMCIA_MEM_PHYS_ADDR 0xF80000000ULL
+#endif
+
+/***********************************************************************/
+
+#ifdef CONFIG_SOC_AU1550
+#define MEM_PHYS_ADDR 0x14000000
+#define STATIC_MEM_PHYS_ADDR 0x14001000
+#define IC0_PHYS_ADDR 0x10400000
+#define IC1_PHYS_ADDR 0x11800000
+#define USBH_PHYS_ADDR 0x14020000
+#define USBD_PHYS_ADDR 0x10200000
+#define PCI_PHYS_ADDR 0x14005000
+#define MAC0_PHYS_ADDR 0x10500000
+#define MAC1_PHYS_ADDR 0x10510000
+#define MACEN_PHYS_ADDR 0x10520000
+#define MACDMA0_PHYS_ADDR 0x14004000
+#define MACDMA1_PHYS_ADDR 0x14004200
+#define UART0_PHYS_ADDR 0x11100000
+#define UART1_PHYS_ADDR 0x11200000
+#define UART3_PHYS_ADDR 0x11400000
+#define GPIO2_PHYS_ADDR 0x11700000
+#define SYS_PHYS_ADDR 0x11900000
+#define DDMA_PHYS_ADDR 0x14002000
+#define PE_PHYS_ADDR 0x14008000
+#define PSC0_PHYS_ADDR 0x11A00000
+#define PSC1_PHYS_ADDR 0x11B00000
+#define PSC2_PHYS_ADDR 0x10A00000
+#define PSC3_PHYS_ADDR 0x10B00000
+#define PCI_MEM_PHYS_ADDR 0x400000000ULL
+#define PCI_IO_PHYS_ADDR 0x500000000ULL
+#define PCI_CONFIG0_PHYS_ADDR 0x600000000ULL
+#define PCI_CONFIG1_PHYS_ADDR 0x680000000ULL
+#define PCMCIA_IO_PHYS_ADDR 0xF00000000ULL
+#define PCMCIA_ATTR_PHYS_ADDR 0xF40000000ULL
+#define PCMCIA_MEM_PHYS_ADDR 0xF80000000ULL
+#endif
+
+/***********************************************************************/
+
+#ifdef CONFIG_SOC_AU1200
+#define MEM_PHYS_ADDR 0x14000000
+#define STATIC_MEM_PHYS_ADDR 0x14001000
+#define AES_PHYS_ADDR 0x10300000
+#define CIM_PHYS_ADDR 0x14004000
+#define IC0_PHYS_ADDR 0x10400000
+#define IC1_PHYS_ADDR 0x11800000
+#define USBM_PHYS_ADDR 0x14020000
+#define USBH_PHYS_ADDR 0x14020100
+#define UART0_PHYS_ADDR 0x11100000
+#define UART1_PHYS_ADDR 0x11200000
+#define GPIO2_PHYS_ADDR 0x11700000
+#define SYS_PHYS_ADDR 0x11900000
+#define DDMA_PHYS_ADDR 0x14002000
+#define PSC0_PHYS_ADDR 0x11A00000
+#define PSC1_PHYS_ADDR 0x11B00000
+#define SD0_PHYS_ADDR 0x10600000
+#define SD1_PHYS_ADDR 0x10680000
+#define LCD_PHYS_ADDR 0x15000000
+#define SWCNT_PHYS_ADDR 0x1110010C
+#define MAEFE_PHYS_ADDR 0x14012000
+#define MAEBE_PHYS_ADDR 0x14010000
+#define PCMCIA_IO_PHYS_ADDR 0xF00000000ULL
+#define PCMCIA_ATTR_PHYS_ADDR 0xF40000000ULL
+#define PCMCIA_MEM_PHYS_ADDR 0xF80000000ULL
+#endif
+
+
/* Static Bus Controller */
#define MEM_STCFG0 0xB4001000
#define MEM_STTIME0 0xB4001004
@@ -369,7 +611,7 @@ extern au1xxx_irq_map_t au1xxx_irq_map[];
#define AU1000_MAC0_ENABLE 0xB0520000
#define AU1000_MAC1_ENABLE 0xB0520004
#define NUM_ETH_INTERFACES 2
-#endif // CONFIG_SOC_AU1000
+#endif /* CONFIG_SOC_AU1000 */
/* Au1500 */
#ifdef CONFIG_SOC_AU1500
@@ -429,6 +671,12 @@ extern au1xxx_irq_map_t au1xxx_irq_map[];
#define AU1500_GPIO_207 62
#define AU1500_GPIO_208_215 63
+/* shortcuts */
+#define INTA AU1000_PCI_INTA
+#define INTB AU1000_PCI_INTB
+#define INTC AU1000_PCI_INTC
+#define INTD AU1000_PCI_INTD
+
#define UART0_ADDR 0xB1100000
#define UART3_ADDR 0xB1400000
@@ -440,7 +688,7 @@ extern au1xxx_irq_map_t au1xxx_irq_map[];
#define AU1500_MAC0_ENABLE 0xB1520000
#define AU1500_MAC1_ENABLE 0xB1520004
#define NUM_ETH_INTERFACES 2
-#endif // CONFIG_SOC_AU1500
+#endif /* CONFIG_SOC_AU1500 */
/* Au1100 */
#ifdef CONFIG_SOC_AU1100
@@ -485,6 +733,22 @@ extern au1xxx_irq_map_t au1xxx_irq_map[];
#define AU1000_GPIO_13 45
#define AU1000_GPIO_14 46
#define AU1000_GPIO_15 47
+#define AU1000_GPIO_16 48
+#define AU1000_GPIO_17 49
+#define AU1000_GPIO_18 50
+#define AU1000_GPIO_19 51
+#define AU1000_GPIO_20 52
+#define AU1000_GPIO_21 53
+#define AU1000_GPIO_22 54
+#define AU1000_GPIO_23 55
+#define AU1000_GPIO_24 56
+#define AU1000_GPIO_25 57
+#define AU1000_GPIO_26 58
+#define AU1000_GPIO_27 59
+#define AU1000_GPIO_28 60
+#define AU1000_GPIO_29 61
+#define AU1000_GPIO_30 62
+#define AU1000_GPIO_31 63
#define UART0_ADDR 0xB1100000
#define UART1_ADDR 0xB1200000
@@ -496,7 +760,7 @@ extern au1xxx_irq_map_t au1xxx_irq_map[];
#define AU1100_ETH0_BASE 0xB0500000
#define AU1100_MAC0_ENABLE 0xB0520000
#define NUM_ETH_INTERFACES 1
-#endif // CONFIG_SOC_AU1100
+#endif /* CONFIG_SOC_AU1100 */
#ifdef CONFIG_SOC_AU1550
#define AU1550_UART0_INT 0
@@ -513,14 +777,14 @@ extern au1xxx_irq_map_t au1xxx_irq_map[];
#define AU1550_PSC1_INT 11
#define AU1550_PSC2_INT 12
#define AU1550_PSC3_INT 13
-#define AU1550_TOY_INT 14
-#define AU1550_TOY_MATCH0_INT 15
-#define AU1550_TOY_MATCH1_INT 16
-#define AU1550_TOY_MATCH2_INT 17
-#define AU1550_RTC_INT 18
-#define AU1550_RTC_MATCH0_INT 19
-#define AU1550_RTC_MATCH1_INT 20
-#define AU1550_RTC_MATCH2_INT 21
+#define AU1000_TOY_INT 14
+#define AU1000_TOY_MATCH0_INT 15
+#define AU1000_TOY_MATCH1_INT 16
+#define AU1000_TOY_MATCH2_INT 17
+#define AU1000_RTC_INT 18
+#define AU1000_RTC_MATCH0_INT 19
+#define AU1000_RTC_MATCH1_INT 20
+#define AU1000_RTC_MATCH2_INT 21
#define AU1550_NAND_INT 23
#define AU1550_USB_DEV_REQ_INT 24
#define AU1550_USB_DEV_SUS_INT 25
@@ -563,6 +827,12 @@ extern au1xxx_irq_map_t au1xxx_irq_map[];
#define AU1500_GPIO_207 62
#define AU1500_GPIO_208_218 63 // Logical or of GPIO208:218
+/* shortcuts */
+#define INTA AU1550_PCI_INTA
+#define INTB AU1550_PCI_INTB
+#define INTC AU1550_PCI_INTC
+#define INTD AU1550_PCI_INTD
+
#define UART0_ADDR 0xB1100000
#define UART1_ADDR 0xB1200000
#define UART3_ADDR 0xB1400000
@@ -575,7 +845,7 @@ extern au1xxx_irq_map_t au1xxx_irq_map[];
#define AU1550_MAC0_ENABLE 0xB0520000
#define AU1550_MAC1_ENABLE 0xB0520004
#define NUM_ETH_INTERFACES 2
-#endif // CONFIG_SOC_AU1550
+#endif /* CONFIG_SOC_AU1550 */
#ifdef CONFIG_SOC_AU1200
#define AU1200_UART0_INT 0
@@ -592,14 +862,14 @@ extern au1xxx_irq_map_t au1xxx_irq_map[];
#define AU1200_PSC1_INT 11
#define AU1200_AES_INT 12
#define AU1200_CAMERA_INT 13
-#define AU1200_TOY_INT 14
-#define AU1200_TOY_MATCH0_INT 15
-#define AU1200_TOY_MATCH1_INT 16
-#define AU1200_TOY_MATCH2_INT 17
-#define AU1200_RTC_INT 18
-#define AU1200_RTC_MATCH0_INT 19
-#define AU1200_RTC_MATCH1_INT 20
-#define AU1200_RTC_MATCH2_INT 21
+#define AU1000_TOY_INT 14
+#define AU1000_TOY_MATCH0_INT 15
+#define AU1000_TOY_MATCH1_INT 16
+#define AU1000_TOY_MATCH2_INT 17
+#define AU1000_RTC_INT 18
+#define AU1000_RTC_MATCH0_INT 19
+#define AU1000_RTC_MATCH1_INT 20
+#define AU1000_RTC_MATCH2_INT 21
#define AU1200_NAND_INT 23
#define AU1200_GPIO_204 24
#define AU1200_GPIO_205 25
@@ -607,6 +877,7 @@ extern au1xxx_irq_map_t au1xxx_irq_map[];
#define AU1200_GPIO_207 27
#define AU1200_GPIO_208_215 28 // Logical OR of 208:215
#define AU1200_USB_INT 29
+#define AU1000_USB_HOST_INT AU1200_USB_INT
#define AU1200_LCD_INT 30
#define AU1200_MAE_BOTH_INT 31
#define AU1000_GPIO_0 32
@@ -645,20 +916,36 @@ extern au1xxx_irq_map_t au1xxx_irq_map[];
#define UART0_ADDR 0xB1100000
#define UART1_ADDR 0xB1200000
-#define USB_OHCI_BASE 0x14020000 // phys addr for ioremap
-#define USB_HOST_CONFIG 0xB4027ffc
-
-// these are here for prototyping on au1550 (do not exist on au1200)
-#define AU1200_ETH0_BASE 0xB0500000
-#define AU1200_ETH1_BASE 0xB0510000
-#define AU1200_MAC0_ENABLE 0xB0520000
-#define AU1200_MAC1_ENABLE 0xB0520004
-#define NUM_ETH_INTERFACES 2
-#endif // CONFIG_SOC_AU1200
+#define USB_UOC_BASE 0x14020020
+#define USB_UOC_LEN 0x20
+#define USB_OHCI_BASE 0x14020100
+#define USB_OHCI_LEN 0x100
+#define USB_EHCI_BASE 0x14020200
+#define USB_EHCI_LEN 0x100
+#define USB_UDC_BASE 0x14022000
+#define USB_UDC_LEN 0x2000
+#define USB_MSR_BASE 0xB4020000
+#define USB_MSR_MCFG 4
+#define USBMSRMCFG_OMEMEN 0
+#define USBMSRMCFG_OBMEN 1
+#define USBMSRMCFG_EMEMEN 2
+#define USBMSRMCFG_EBMEN 3
+#define USBMSRMCFG_DMEMEN 4
+#define USBMSRMCFG_DBMEN 5
+#define USBMSRMCFG_GMEMEN 6
+#define USBMSRMCFG_OHCCLKEN 16
+#define USBMSRMCFG_EHCCLKEN 17
+#define USBMSRMCFG_UDCCLKEN 18
+#define USBMSRMCFG_PHYPLLEN 19
+#define USBMSRMCFG_RDCOMB 30
+#define USBMSRMCFG_PFEN 31
+
+#endif /* CONFIG_SOC_AU1200 */
#define AU1000_LAST_INTC0_INT 31
+#define AU1000_LAST_INTC1_INT 63
#define AU1000_MAX_INTR 63
-
+#define INTX 0xFF /* not valid */
/* Programmable Counters 0 and 1 */
#define SYS_BASE 0xB1900000
@@ -730,6 +1017,8 @@ extern au1xxx_irq_map_t au1xxx_irq_map[];
#define I2S_CONTROL_D (1<<1)
#define I2S_CONTROL_CE (1<<0)
+#ifndef CONFIG_SOC_AU1200
+
/* USB Host Controller */
#define USB_OHCI_LEN 0x00100000
@@ -775,6 +1064,8 @@ extern au1xxx_irq_map_t au1xxx_irq_map[];
#define USBDEV_ENABLE (1<<1)
#define USBDEV_CE (1<<0)
+#endif /* !CONFIG_SOC_AU1200 */
+
/* Ethernet Controllers */
/* 4 byte offsets from AU1000_ETH_BASE */
@@ -1173,6 +1464,37 @@ extern au1xxx_irq_map_t au1xxx_irq_map[];
#define SYS_PF_PSC1_S1 (1 << 1)
#define SYS_PF_MUST_BE_SET ((1 << 5) | (1 << 2))
+/* Au1200 Only */
+#ifdef CONFIG_SOC_AU1200
+#define SYS_PINFUNC_DMA (1<<31)
+#define SYS_PINFUNC_S0A (1<<30)
+#define SYS_PINFUNC_S1A (1<<29)
+#define SYS_PINFUNC_LP0 (1<<28)
+#define SYS_PINFUNC_LP1 (1<<27)
+#define SYS_PINFUNC_LD16 (1<<26)
+#define SYS_PINFUNC_LD8 (1<<25)
+#define SYS_PINFUNC_LD1 (1<<24)
+#define SYS_PINFUNC_LD0 (1<<23)
+#define SYS_PINFUNC_P1A (3<<21)
+#define SYS_PINFUNC_P1B (1<<20)
+#define SYS_PINFUNC_FS3 (1<<19)
+#define SYS_PINFUNC_P0A (3<<17)
+#define SYS_PINFUNC_CS (1<<16)
+#define SYS_PINFUNC_CIM (1<<15)
+#define SYS_PINFUNC_P1C (1<<14)
+#define SYS_PINFUNC_U1T (1<<12)
+#define SYS_PINFUNC_U1R (1<<11)
+#define SYS_PINFUNC_EX1 (1<<10)
+#define SYS_PINFUNC_EX0 (1<<9)
+#define SYS_PINFUNC_U0R (1<<8)
+#define SYS_PINFUNC_MC (1<<7)
+#define SYS_PINFUNC_S0B (1<<6)
+#define SYS_PINFUNC_S0C (1<<5)
+#define SYS_PINFUNC_P0B (1<<4)
+#define SYS_PINFUNC_U0T (1<<3)
+#define SYS_PINFUNC_S1B (1<<2)
+#endif
+
#define SYS_TRIOUTRD 0xB1900100
#define SYS_TRIOUTCLR 0xB1900100
#define SYS_OUTPUTRD 0xB1900108
@@ -1239,6 +1561,12 @@ extern au1xxx_irq_map_t au1xxx_irq_map[];
#define SYS_CS_MI2_MASK (0x7<<SYS_CS_MI2_BIT)
#define SYS_CS_DI2 (1<<16)
#define SYS_CS_CI2 (1<<15)
+#ifdef CONFIG_SOC_AU1100
+ #define SYS_CS_ML_BIT 7
+ #define SYS_CS_ML_MASK (0x7<<SYS_CS_ML_BIT)
+ #define SYS_CS_DL (1<<6)
+ #define SYS_CS_CL (1<<5)
+#else
#define SYS_CS_MUH_BIT 12
#define SYS_CS_MUH_MASK (0x7<<SYS_CS_MUH_BIT)
#define SYS_CS_DUH (1<<11)
@@ -1247,6 +1575,7 @@ extern au1xxx_irq_map_t au1xxx_irq_map[];
#define SYS_CS_MUD_MASK (0x7<<SYS_CS_MUD_BIT)
#define SYS_CS_DUD (1<<6)
#define SYS_CS_CUD (1<<5)
+#endif
#define SYS_CS_MIR_BIT 2
#define SYS_CS_MIR_MASK (0x7<<SYS_CS_MIR_BIT)
#define SYS_CS_DIR (1<<1)
@@ -1300,7 +1629,6 @@ extern au1xxx_irq_map_t au1xxx_irq_map[];
#define SD1_XMIT_FIFO 0xB0680000
#define SD1_RECV_FIFO 0xB0680004
-
#if defined (CONFIG_SOC_AU1500) || defined(CONFIG_SOC_AU1550)
/* Au1500 PCI Controller */
#define Au1500_CFG_BASE 0xB4005000 // virtual, kseg0 addr
@@ -1363,36 +1691,77 @@ extern au1xxx_irq_map_t au1xxx_irq_map[];
_ctl_; })
-#else /* Au1000 and Au1100 */
+#else /* Au1000 and Au1100 and Au1200 */
/* don't allow any legacy ports probing */
-#define IOPORT_RESOURCE_START 0x10000000;
+#define IOPORT_RESOURCE_START 0x10000000
#define IOPORT_RESOURCE_END 0xffffffff
#define IOMEM_RESOURCE_START 0x10000000
#define IOMEM_RESOURCE_END 0xffffffff
-#ifdef CONFIG_MIPS_PB1000
-#define PCI_IO_START 0x10000000
-#define PCI_IO_END 0x1000ffff
-#define PCI_MEM_START 0x18000000
-#define PCI_MEM_END 0x18ffffff
-#define PCI_FIRST_DEVFN 0
-#define PCI_LAST_DEVFN 1
-#else
-/* no PCI bus controller */
#define PCI_IO_START 0
#define PCI_IO_END 0
#define PCI_MEM_START 0
#define PCI_MEM_END 0
#define PCI_FIRST_DEVFN 0
#define PCI_LAST_DEVFN 0
-#endif
#endif
+#ifndef _LANGUAGE_ASSEMBLY
+typedef volatile struct
+{
+ /* 0x0000 */ u32 toytrim;
+ /* 0x0004 */ u32 toywrite;
+ /* 0x0008 */ u32 toymatch0;
+ /* 0x000C */ u32 toymatch1;
+ /* 0x0010 */ u32 toymatch2;
+ /* 0x0014 */ u32 cntrctrl;
+ /* 0x0018 */ u32 scratch0;
+ /* 0x001C */ u32 scratch1;
+ /* 0x0020 */ u32 freqctrl0;
+ /* 0x0024 */ u32 freqctrl1;
+ /* 0x0028 */ u32 clksrc;
+ /* 0x002C */ u32 pinfunc;
+ /* 0x0030 */ u32 reserved0;
+ /* 0x0034 */ u32 wakemsk;
+ /* 0x0038 */ u32 endian;
+ /* 0x003C */ u32 powerctrl;
+ /* 0x0040 */ u32 toyread;
+ /* 0x0044 */ u32 rtctrim;
+ /* 0x0048 */ u32 rtcwrite;
+ /* 0x004C */ u32 rtcmatch0;
+ /* 0x0050 */ u32 rtcmatch1;
+ /* 0x0054 */ u32 rtcmatch2;
+ /* 0x0058 */ u32 rtcread;
+ /* 0x005C */ u32 wakesrc;
+ /* 0x0060 */ u32 cpupll;
+ /* 0x0064 */ u32 auxpll;
+ /* 0x0068 */ u32 reserved1;
+ /* 0x006C */ u32 reserved2;
+ /* 0x0070 */ u32 reserved3;
+ /* 0x0074 */ u32 reserved4;
+ /* 0x0078 */ u32 slppwr;
+ /* 0x007C */ u32 sleep;
+ /* 0x0080 */ u32 reserved5[32];
+ /* 0x0100 */ u32 trioutrd;
+#define trioutclr trioutrd
+ /* 0x0104 */ u32 reserved6;
+ /* 0x0108 */ u32 outputrd;
+#define outputset outputrd
+ /* 0x010C */ u32 outputclr;
+ /* 0x0110 */ u32 pinstaterd;
+#define pininputen pinstaterd
+
+} AU1X00_SYS;
+
+static AU1X00_SYS* const sys = (AU1X00_SYS *)SYS_BASE;
+
+#endif
/* Processor information base on prid.
* Copied from PowerPC.
*/
+#ifndef _LANGUAGE_ASSEMBLY
struct cpu_spec {
/* CPU is matched via (PRID & prid_mask) == prid_value */
unsigned int prid_mask;
@@ -1406,3 +1775,6 @@ struct cpu_spec {
extern struct cpu_spec cpu_specs[];
extern struct cpu_spec *cur_cpu_spec[];
#endif
+
+#endif
+
diff --git a/include/asm-mips/mach-au1x00/au1xxx.h b/include/asm-mips/mach-au1x00/au1xxx.h
new file mode 100644
index 000000000000..b7b46dd9b929
--- /dev/null
+++ b/include/asm-mips/mach-au1x00/au1xxx.h
@@ -0,0 +1,44 @@
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef _AU1XXX_H_
+#define _AU1XXX_H_
+
+#include <linux/config.h>
+
+#include <asm/mach-au1x00/au1000.h>
+
+#if defined(CONFIG_MIPS_DB1000) || defined(CONFIG_MIPS_DB1100) || defined(CONFIG_MIPS_DB1500) || defined(CONFIG_MIPS_DB1550)
+#include <asm/mach-db1x00/db1x00.h>
+
+#elif defined(CONFIG_MIPS_PB1550)
+#include <asm/mach-pb1x00/pb1550.h>
+
+#elif defined(CONFIG_MIPS_PB1200)
+#include <asm/mach-pb1x00/pb1200.h>
+
+#elif defined(CONFIG_MIPS_DB1200)
+#include <asm/mach-db1x00/db1200.h>
+
+#endif
+
+#endif /* _AU1XXX_H_ */
diff --git a/include/asm-mips/mach-au1x00/au1xxx_dbdma.h b/include/asm-mips/mach-au1x00/au1xxx_dbdma.h
index d5eb88cd7d51..b327bcd3fee1 100644
--- a/include/asm-mips/mach-au1x00/au1xxx_dbdma.h
+++ b/include/asm-mips/mach-au1x00/au1xxx_dbdma.h
@@ -45,7 +45,7 @@
#define DDMA_GLOBAL_BASE 0xb4003000
#define DDMA_CHANNEL_BASE 0xb4002000
-typedef struct dbdma_global {
+typedef volatile struct dbdma_global {
u32 ddma_config;
u32 ddma_intstat;
u32 ddma_throttle;
@@ -62,7 +62,7 @@ typedef struct dbdma_global {
/* The structure of a DMA Channel.
*/
-typedef struct au1xxx_dma_channel {
+typedef volatile struct au1xxx_dma_channel {
u32 ddma_cfg; /* See below */
u32 ddma_desptr; /* 32-byte aligned pointer to descriptor */
u32 ddma_statptr; /* word aligned pointer to status word */
@@ -98,7 +98,7 @@ typedef struct au1xxx_dma_channel {
/* "Standard" DDMA Descriptor.
* Must be 32-byte aligned.
*/
-typedef struct au1xxx_ddma_desc {
+typedef volatile struct au1xxx_ddma_desc {
u32 dscr_cmd0; /* See below */
u32 dscr_cmd1; /* See below */
u32 dscr_source0; /* source phys address */
@@ -107,6 +107,12 @@ typedef struct au1xxx_ddma_desc {
u32 dscr_dest1; /* See below */
u32 dscr_stat; /* completion status */
u32 dscr_nxtptr; /* Next descriptor pointer (mostly) */
+ /* First 32bytes are HW specific!!!
+ Lets have some SW data following.. make sure its 32bytes
+ */
+ u32 sw_status;
+ u32 sw_context;
+ u32 sw_reserved[6];
} au1x_ddma_desc_t;
#define DSCR_CMD0_V (1 << 31) /* Descriptor valid */
@@ -125,8 +131,11 @@ typedef struct au1xxx_ddma_desc {
#define DSCR_CMD0_CV (0x1 << 2) /* Clear Valid when done */
#define DSCR_CMD0_ST_MASK (0x3 << 0) /* Status instruction */
+#define SW_STATUS_INUSE (1<<0)
+
/* Command 0 device IDs.
*/
+#ifdef CONFIG_SOC_AU1550
#define DSCR_CMD0_UART0_TX 0
#define DSCR_CMD0_UART0_RX 1
#define DSCR_CMD0_UART3_TX 2
@@ -155,9 +164,45 @@ typedef struct au1xxx_ddma_desc {
#define DSCR_CMD0_MAC0_TX 25
#define DSCR_CMD0_MAC1_RX 26
#define DSCR_CMD0_MAC1_TX 27
+#endif /* CONFIG_SOC_AU1550 */
+
+#ifdef CONFIG_SOC_AU1200
+#define DSCR_CMD0_UART0_TX 0
+#define DSCR_CMD0_UART0_RX 1
+#define DSCR_CMD0_UART1_TX 2
+#define DSCR_CMD0_UART1_RX 3
+#define DSCR_CMD0_DMA_REQ0 4
+#define DSCR_CMD0_DMA_REQ1 5
+#define DSCR_CMD0_MAE_BE 6
+#define DSCR_CMD0_MAE_FE 7
+#define DSCR_CMD0_SDMS_TX0 8
+#define DSCR_CMD0_SDMS_RX0 9
+#define DSCR_CMD0_SDMS_TX1 10
+#define DSCR_CMD0_SDMS_RX1 11
+#define DSCR_CMD0_AES_TX 13
+#define DSCR_CMD0_AES_RX 12
+#define DSCR_CMD0_PSC0_TX 14
+#define DSCR_CMD0_PSC0_RX 15
+#define DSCR_CMD0_PSC1_TX 16
+#define DSCR_CMD0_PSC1_RX 17
+#define DSCR_CMD0_CIM_RXA 18
+#define DSCR_CMD0_CIM_RXB 19
+#define DSCR_CMD0_CIM_RXC 20
+#define DSCR_CMD0_MAE_BOTH 21
+#define DSCR_CMD0_LCD 22
+#define DSCR_CMD0_NAND_FLASH 23
+#define DSCR_CMD0_PSC0_SYNC 24
+#define DSCR_CMD0_PSC1_SYNC 25
+#define DSCR_CMD0_CIM_SYNC 26
+#endif /* CONFIG_SOC_AU1200 */
+
#define DSCR_CMD0_THROTTLE 30
#define DSCR_CMD0_ALWAYS 31
#define DSCR_NDEV_IDS 32
+/* THis macro is used to find/create custom device types */
+#define DSCR_DEV2CUSTOM_ID(x,d) (((((x)&0xFFFF)<<8)|0x32000000)|((d)&0xFF))
+#define DSCR_CUSTOM2DEV_ID(x) ((x)&0xFF)
+
#define DSCR_CMD0_SID(x) (((x) & 0x1f) << 25)
#define DSCR_CMD0_DID(x) (((x) & 0x1f) << 20)
@@ -246,6 +291,43 @@ typedef struct au1xxx_ddma_desc {
*/
#define NUM_DBDMA_CHANS 16
+/*
+ * Ddma API definitions
+ * FIXME: may not fit to this header file
+ */
+typedef struct dbdma_device_table {
+ u32 dev_id;
+ u32 dev_flags;
+ u32 dev_tsize;
+ u32 dev_devwidth;
+ u32 dev_physaddr; /* If FIFO */
+ u32 dev_intlevel;
+ u32 dev_intpolarity;
+} dbdev_tab_t;
+
+
+typedef struct dbdma_chan_config {
+ spinlock_t lock;
+
+ u32 chan_flags;
+ u32 chan_index;
+ dbdev_tab_t *chan_src;
+ dbdev_tab_t *chan_dest;
+ au1x_dma_chan_t *chan_ptr;
+ au1x_ddma_desc_t *chan_desc_base;
+ au1x_ddma_desc_t *get_ptr, *put_ptr, *cur_ptr;
+ void *chan_callparam;
+ void (*chan_callback)(int, void *, struct pt_regs *);
+} chan_tab_t;
+
+#define DEV_FLAGS_INUSE (1 << 0)
+#define DEV_FLAGS_ANYUSE (1 << 1)
+#define DEV_FLAGS_OUT (1 << 2)
+#define DEV_FLAGS_IN (1 << 3)
+#define DEV_FLAGS_BURSTABLE (1 << 4)
+#define DEV_FLAGS_SYNC (1 << 5)
+/* end Ddma API definitions */
+
/* External functions for drivers to use.
*/
/* Use this to allocate a dbdma channel. The device ids are one of the
@@ -258,18 +340,6 @@ u32 au1xxx_dbdma_chan_alloc(u32 srcid, u32 destid,
#define DBDMA_MEM_CHAN DSCR_CMD0_ALWAYS
-/* ACK! These should be in a board specific description file.
-*/
-#ifdef CONFIG_MIPS_PB1550
-#define DBDMA_AC97_TX_CHAN DSCR_CMD0_PSC1_TX
-#define DBDMA_AC97_RX_CHAN DSCR_CMD0_PSC1_RX
-#endif
-#ifdef CONFIG_MIPS_DB1550
-#define DBDMA_AC97_TX_CHAN DSCR_CMD0_PSC1_TX
-#define DBDMA_AC97_RX_CHAN DSCR_CMD0_PSC1_RX
-#endif
-
-
/* Set the device width of a in/out fifo.
*/
u32 au1xxx_dbdma_set_devwidth(u32 chanid, int bits);
@@ -280,8 +350,8 @@ u32 au1xxx_dbdma_ring_alloc(u32 chanid, int entries);
/* Put buffers on source/destination descriptors.
*/
-u32 au1xxx_dbdma_put_source(u32 chanid, void *buf, int nbytes);
-u32 au1xxx_dbdma_put_dest(u32 chanid, void *buf, int nbytes);
+u32 _au1xxx_dbdma_put_source(u32 chanid, void *buf, int nbytes, u32 flags);
+u32 _au1xxx_dbdma_put_dest(u32 chanid, void *buf, int nbytes, u32 flags);
/* Get a buffer from the destination descriptor.
*/
@@ -295,5 +365,29 @@ u32 au1xxx_get_dma_residue(u32 chanid);
void au1xxx_dbdma_chan_free(u32 chanid);
void au1xxx_dbdma_dump(u32 chanid);
+u32 au1xxx_dbdma_put_dscr(u32 chanid, au1x_ddma_desc_t *dscr );
+
+u32 au1xxx_ddma_add_device( dbdev_tab_t *dev );
+void * au1xxx_ddma_get_nextptr_virt(au1x_ddma_desc_t *dp);
+
+/*
+ Some compatibilty macros --
+ Needed to make changes to API without breaking existing drivers
+*/
+#define au1xxx_dbdma_put_source(chanid,buf,nbytes)_au1xxx_dbdma_put_source(chanid, buf, nbytes, DDMA_FLAGS_IE)
+#define au1xxx_dbdma_put_source_flags(chanid,buf,nbytes,flags) _au1xxx_dbdma_put_source(chanid, buf, nbytes, flags)
+#define put_source_flags(chanid,buf,nbytes,flags) au1xxx_dbdma_put_source_flags(chanid,buf,nbytes,flags)
+
+
+#define au1xxx_dbdma_put_dest(chanid,buf,nbytes) _au1xxx_dbdma_put_dest(chanid, buf, nbytes, DDMA_FLAGS_IE)
+#define au1xxx_dbdma_put_dest_flags(chanid,buf,nbytes,flags) _au1xxx_dbdma_put_dest(chanid, buf, nbytes, flags)
+#define put_dest_flags(chanid,buf,nbytes,flags) au1xxx_dbdma_put_dest_flags(chanid,buf,nbytes,flags)
+
+/*
+ * Flags for the put_source/put_dest functions.
+ */
+#define DDMA_FLAGS_IE (1<<0)
+#define DDMA_FLAGS_NOIE (1<<1)
+
#endif /* _LANGUAGE_ASSEMBLY */
#endif /* _AU1000_DBDMA_H_ */
diff --git a/include/asm-mips/mach-au1x00/au1xxx_gpio.h b/include/asm-mips/mach-au1x00/au1xxx_gpio.h
new file mode 100644
index 000000000000..27911e054ffc
--- /dev/null
+++ b/include/asm-mips/mach-au1x00/au1xxx_gpio.h
@@ -0,0 +1,20 @@
+#ifndef __AU1XXX_GPIO_H
+#define __AU1XXX_GPIO_H
+
+void au1xxx_gpio1_set_inputs(void);
+void au1xxx_gpio_tristate(int signal);
+void au1xxx_gpio_write(int signal, int value);
+int au1xxx_gpio_read(int signal);
+
+typedef volatile struct
+{
+ u32 dir;
+ u32 reserved;
+ u32 output;
+ u32 pinstate;
+ u32 inten;
+ u32 enable;
+
+} AU1X00_GPIO2;
+
+#endif //__AU1XXX_GPIO_H
diff --git a/include/asm-mips/mach-au1x00/au1xxx_ide.h b/include/asm-mips/mach-au1x00/au1xxx_ide.h
new file mode 100644
index 000000000000..33d275c3b84c
--- /dev/null
+++ b/include/asm-mips/mach-au1x00/au1xxx_ide.h
@@ -0,0 +1,301 @@
+/*
+ * include/asm-mips/mach-au1x00/au1xxx_ide.h version 01.30.00 Aug. 02 2005
+ *
+ * BRIEF MODULE DESCRIPTION
+ * AMD Alchemy Au1xxx IDE interface routines over the Static Bus
+ *
+ * Copyright (c) 2003-2005 AMD, Personal Connectivity Solutions
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation; either version 2 of the License, or (at your option) any later
+ * version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Note: for more information, please refer "AMD Alchemy Au1200/Au1550 IDE
+ * Interface and Linux Device Driver" Application Note.
+ */
+#include <linux/config.h>
+
+#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
+ #define DMA_WAIT_TIMEOUT 100
+ #define NUM_DESCRIPTORS PRD_ENTRIES
+#else /* CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA */
+ #define NUM_DESCRIPTORS 2
+#endif
+
+#ifndef AU1XXX_ATA_RQSIZE
+ #define AU1XXX_ATA_RQSIZE 128
+#endif
+
+/* Disable Burstable-Support for DBDMA */
+#ifndef CONFIG_BLK_DEV_IDE_AU1XXX_BURSTABLE_ON
+ #define CONFIG_BLK_DEV_IDE_AU1XXX_BURSTABLE_ON 0
+#endif
+
+#ifdef CONFIG_PM
+/*
+* This will enable the device to be powered up when write() or read()
+* is called. If this is not defined, the driver will return -EBUSY.
+*/
+#define WAKE_ON_ACCESS 1
+
+typedef struct
+{
+ spinlock_t lock; /* Used to block on state transitions */
+ au1xxx_power_dev_t *dev; /* Power Managers device structure */
+ unsigned stopped; /* USed to signaling device is stopped */
+} pm_state;
+#endif
+
+
+typedef struct
+{
+ u32 tx_dev_id, rx_dev_id, target_dev_id;
+ u32 tx_chan, rx_chan;
+ void *tx_desc_head, *rx_desc_head;
+ ide_hwif_t *hwif;
+#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
+ ide_drive_t *drive;
+ u8 white_list, black_list;
+ struct dbdma_cmd *dma_table_cpu;
+ dma_addr_t dma_table_dma;
+ struct scatterlist *sg_table;
+ int sg_nents;
+ int sg_dma_direction;
+#endif
+ struct device *dev;
+ int irq;
+ u32 regbase;
+#ifdef CONFIG_PM
+ pm_state pm;
+#endif
+} _auide_hwif;
+
+#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
+struct drive_list_entry {
+ const char * id_model;
+ const char * id_firmware;
+};
+
+/* HD white list */
+static const struct drive_list_entry dma_white_list [] = {
+/*
+ * Hitachi
+ */
+ { "HITACHI_DK14FA-20" , "ALL" },
+ { "HTS726060M9AT00" , "ALL" },
+/*
+ * Maxtor
+ */
+ { "Maxtor 6E040L0" , "ALL" },
+ { "Maxtor 6Y080P0" , "ALL" },
+ { "Maxtor 6Y160P0" , "ALL" },
+/*
+ * Seagate
+ */
+ { "ST3120026A" , "ALL" },
+ { "ST320014A" , "ALL" },
+ { "ST94011A" , "ALL" },
+ { "ST340016A" , "ALL" },
+/*
+ * Western Digital
+ */
+ { "WDC WD400UE-00HCT0" , "ALL" },
+ { "WDC WD400JB-00JJC0" , "ALL" },
+ { NULL , NULL }
+};
+
+/* HD black list */
+static const struct drive_list_entry dma_black_list [] = {
+/*
+ * Western Digital
+ */
+ { "WDC WD100EB-00CGH0" , "ALL" },
+ { "WDC WD200BB-00AUA1" , "ALL" },
+ { "WDC AC24300L" , "ALL" },
+ { NULL , NULL }
+};
+#endif
+
+/* function prototyping */
+u8 auide_inb(unsigned long port);
+u16 auide_inw(unsigned long port);
+u32 auide_inl(unsigned long port);
+void auide_insw(unsigned long port, void *addr, u32 count);
+void auide_insl(unsigned long port, void *addr, u32 count);
+void auide_outb(u8 addr, unsigned long port);
+void auide_outbsync(ide_drive_t *drive, u8 addr, unsigned long port);
+void auide_outw(u16 addr, unsigned long port);
+void auide_outl(u32 addr, unsigned long port);
+void auide_outsw(unsigned long port, void *addr, u32 count);
+void auide_outsl(unsigned long port, void *addr, u32 count);
+static void auide_tune_drive(ide_drive_t *drive, byte pio);
+static int auide_tune_chipset (ide_drive_t *drive, u8 speed);
+static int auide_ddma_init( _auide_hwif *auide );
+static void auide_setup_ports(hw_regs_t *hw, _auide_hwif *ahwif);
+int __init auide_probe(void);
+
+#ifdef CONFIG_PM
+ int au1200ide_pm_callback( au1xxx_power_dev_t *dev,
+ au1xxx_request_t request, void *data);
+ static int au1xxxide_pm_standby( au1xxx_power_dev_t *dev );
+ static int au1xxxide_pm_sleep( au1xxx_power_dev_t *dev );
+ static int au1xxxide_pm_resume( au1xxx_power_dev_t *dev );
+ static int au1xxxide_pm_getstatus( au1xxx_power_dev_t *dev );
+ static int au1xxxide_pm_access( au1xxx_power_dev_t *dev );
+ static int au1xxxide_pm_idle( au1xxx_power_dev_t *dev );
+ static int au1xxxide_pm_cleanup( au1xxx_power_dev_t *dev );
+#endif
+
+
+/*
+ * Multi-Word DMA + DbDMA functions
+ */
+#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
+
+ static int in_drive_list(struct hd_driveid *id,
+ const struct drive_list_entry *drive_table);
+ static int auide_build_sglist(ide_drive_t *drive, struct request *rq);
+ static int auide_build_dmatable(ide_drive_t *drive);
+ static int auide_dma_end(ide_drive_t *drive);
+ static void auide_dma_start(ide_drive_t *drive );
+ ide_startstop_t auide_dma_intr (ide_drive_t *drive);
+ static void auide_dma_exec_cmd(ide_drive_t *drive, u8 command);
+ static int auide_dma_setup(ide_drive_t *drive);
+ static int auide_dma_check(ide_drive_t *drive);
+ static int auide_dma_test_irq(ide_drive_t *drive);
+ static int auide_dma_host_off(ide_drive_t *drive);
+ static int auide_dma_host_on(ide_drive_t *drive);
+ static int auide_dma_lostirq(ide_drive_t *drive);
+ static int auide_dma_on(ide_drive_t *drive);
+ static void auide_ddma_tx_callback(int irq, void *param,
+ struct pt_regs *regs);
+ static void auide_ddma_rx_callback(int irq, void *param,
+ struct pt_regs *regs);
+ static int auide_dma_off_quietly(ide_drive_t *drive);
+ static int auide_dma_timeout(ide_drive_t *drive);
+
+#endif /* end CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA */
+
+/*******************************************************************************
+* PIO Mode timing calculation : *
+* *
+* Static Bus Spec ATA Spec *
+* Tcsoe = t1 *
+* Toecs = t9 *
+* Twcs = t9 *
+* Tcsh = t2i | t2 *
+* Tcsoff = t2i | t2 *
+* Twp = t2 *
+* Tcsw = t1 *
+* Tpm = 0 *
+* Ta = t1+t2 *
+*******************************************************************************/
+
+#define TCSOE_MASK (0x07<<29)
+#define TOECS_MASK (0x07<<26)
+#define TWCS_MASK (0x07<<28)
+#define TCSH_MASK (0x0F<<24)
+#define TCSOFF_MASK (0x07<<20)
+#define TWP_MASK (0x3F<<14)
+#define TCSW_MASK (0x0F<<10)
+#define TPM_MASK (0x0F<<6)
+#define TA_MASK (0x3F<<0)
+#define TS_MASK (1<<8)
+
+/* Timing parameters PIO mode 0 */
+#define SBC_IDE_PIO0_TCSOE (0x04<<29)
+#define SBC_IDE_PIO0_TOECS (0x01<<26)
+#define SBC_IDE_PIO0_TWCS (0x02<<28)
+#define SBC_IDE_PIO0_TCSH (0x08<<24)
+#define SBC_IDE_PIO0_TCSOFF (0x07<<20)
+#define SBC_IDE_PIO0_TWP (0x10<<14)
+#define SBC_IDE_PIO0_TCSW (0x04<<10)
+#define SBC_IDE_PIO0_TPM (0x0<<6)
+#define SBC_IDE_PIO0_TA (0x15<<0)
+/* Timing parameters PIO mode 1 */
+#define SBC_IDE_PIO1_TCSOE (0x03<<29)
+#define SBC_IDE_PIO1_TOECS (0x01<<26)
+#define SBC_IDE_PIO1_TWCS (0x01<<28)
+#define SBC_IDE_PIO1_TCSH (0x06<<24)
+#define SBC_IDE_PIO1_TCSOFF (0x06<<20)
+#define SBC_IDE_PIO1_TWP (0x08<<14)
+#define SBC_IDE_PIO1_TCSW (0x03<<10)
+#define SBC_IDE_PIO1_TPM (0x00<<6)
+#define SBC_IDE_PIO1_TA (0x0B<<0)
+/* Timing parameters PIO mode 2 */
+#define SBC_IDE_PIO2_TCSOE (0x05<<29)
+#define SBC_IDE_PIO2_TOECS (0x01<<26)
+#define SBC_IDE_PIO2_TWCS (0x01<<28)
+#define SBC_IDE_PIO2_TCSH (0x07<<24)
+#define SBC_IDE_PIO2_TCSOFF (0x07<<20)
+#define SBC_IDE_PIO2_TWP (0x1F<<14)
+#define SBC_IDE_PIO2_TCSW (0x05<<10)
+#define SBC_IDE_PIO2_TPM (0x00<<6)
+#define SBC_IDE_PIO2_TA (0x22<<0)
+/* Timing parameters PIO mode 3 */
+#define SBC_IDE_PIO3_TCSOE (0x05<<29)
+#define SBC_IDE_PIO3_TOECS (0x01<<26)
+#define SBC_IDE_PIO3_TWCS (0x01<<28)
+#define SBC_IDE_PIO3_TCSH (0x0D<<24)
+#define SBC_IDE_PIO3_TCSOFF (0x0D<<20)
+#define SBC_IDE_PIO3_TWP (0x15<<14)
+#define SBC_IDE_PIO3_TCSW (0x05<<10)
+#define SBC_IDE_PIO3_TPM (0x00<<6)
+#define SBC_IDE_PIO3_TA (0x1A<<0)
+/* Timing parameters PIO mode 4 */
+#define SBC_IDE_PIO4_TCSOE (0x04<<29)
+#define SBC_IDE_PIO4_TOECS (0x01<<26)
+#define SBC_IDE_PIO4_TWCS (0x01<<28)
+#define SBC_IDE_PIO4_TCSH (0x04<<24)
+#define SBC_IDE_PIO4_TCSOFF (0x04<<20)
+#define SBC_IDE_PIO4_TWP (0x0D<<14)
+#define SBC_IDE_PIO4_TCSW (0x03<<10)
+#define SBC_IDE_PIO4_TPM (0x00<<6)
+#define SBC_IDE_PIO4_TA (0x12<<0)
+/* Timing parameters MDMA mode 0 */
+#define SBC_IDE_MDMA0_TCSOE (0x03<<29)
+#define SBC_IDE_MDMA0_TOECS (0x01<<26)
+#define SBC_IDE_MDMA0_TWCS (0x01<<28)
+#define SBC_IDE_MDMA0_TCSH (0x07<<24)
+#define SBC_IDE_MDMA0_TCSOFF (0x07<<20)
+#define SBC_IDE_MDMA0_TWP (0x0C<<14)
+#define SBC_IDE_MDMA0_TCSW (0x03<<10)
+#define SBC_IDE_MDMA0_TPM (0x00<<6)
+#define SBC_IDE_MDMA0_TA (0x0F<<0)
+/* Timing parameters MDMA mode 1 */
+#define SBC_IDE_MDMA1_TCSOE (0x05<<29)
+#define SBC_IDE_MDMA1_TOECS (0x01<<26)
+#define SBC_IDE_MDMA1_TWCS (0x01<<28)
+#define SBC_IDE_MDMA1_TCSH (0x05<<24)
+#define SBC_IDE_MDMA1_TCSOFF (0x05<<20)
+#define SBC_IDE_MDMA1_TWP (0x0F<<14)
+#define SBC_IDE_MDMA1_TCSW (0x05<<10)
+#define SBC_IDE_MDMA1_TPM (0x00<<6)
+#define SBC_IDE_MDMA1_TA (0x15<<0)
+/* Timing parameters MDMA mode 2 */
+#define SBC_IDE_MDMA2_TCSOE (0x04<<29)
+#define SBC_IDE_MDMA2_TOECS (0x01<<26)
+#define SBC_IDE_MDMA2_TWCS (0x01<<28)
+#define SBC_IDE_MDMA2_TCSH (0x04<<24)
+#define SBC_IDE_MDMA2_TCSOFF (0x04<<20)
+#define SBC_IDE_MDMA2_TWP (0x0D<<14)
+#define SBC_IDE_MDMA2_TCSW (0x04<<10)
+#define SBC_IDE_MDMA2_TPM (0x00<<6)
+#define SBC_IDE_MDMA2_TA (0x12<<0)
+
diff --git a/include/asm-mips/mach-au1x00/au1xxx_psc.h b/include/asm-mips/mach-au1x00/au1xxx_psc.h
index 283519dfdec4..8e5fb3c7da4d 100644
--- a/include/asm-mips/mach-au1x00/au1xxx_psc.h
+++ b/include/asm-mips/mach-au1x00/au1xxx_psc.h
@@ -33,6 +33,8 @@
#ifndef _AU1000_PSC_H_
#define _AU1000_PSC_H_
+#include <linux/config.h>
+
/* The PSC base addresses. */
#ifdef CONFIG_SOC_AU1550
#define PSC0_BASE_ADDR 0xb1a00000
diff --git a/include/asm-mips/mach-au1x00/ioremap.h b/include/asm-mips/mach-au1x00/ioremap.h
new file mode 100644
index 000000000000..d3ec6274575a
--- /dev/null
+++ b/include/asm-mips/mach-au1x00/ioremap.h
@@ -0,0 +1,32 @@
+/*
+ * include/asm-mips/mach-au1x00/ioremap.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#ifndef __ASM_MACH_AU1X00_IOREMAP_H
+#define __ASM_MACH_AU1X00_IOREMAP_H
+
+#include <linux/config.h>
+#include <linux/types.h>
+
+#ifdef CONFIG_64BIT_PHYS_ADDR
+extern phys_t __fixup_bigphys_addr(phys_t, phys_t);
+#else
+static inline phys_t __fixup_bigphys_addr(phys_t phys_addr, phys_t size)
+{
+ return phys_addr;
+}
+#endif
+
+/*
+ * Allow physical addresses to be fixed up to help 36-bit peripherals.
+ */
+static inline phys_t fixup_bigphys_addr(phys_t phys_addr, phys_t size)
+{
+ return __fixup_bigphys_addr(phys_addr, size);
+}
+
+#endif /* __ASM_MACH_AU1X00_IOREMAP_H */
diff --git a/include/asm-mips/mach-db1x00/db1200.h b/include/asm-mips/mach-db1x00/db1200.h
new file mode 100644
index 000000000000..5d894376fc1a
--- /dev/null
+++ b/include/asm-mips/mach-db1x00/db1200.h
@@ -0,0 +1,224 @@
+/*
+ * AMD Alchemy DB1200 Referrence Board
+ * Board Registers defines.
+ *
+ * ########################################################################
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ *
+ *
+ */
+#ifndef __ASM_DB1200_H
+#define __ASM_DB1200_H
+
+#include <linux/types.h>
+
+// This is defined in au1000.h with bogus value
+#undef AU1X00_EXTERNAL_INT
+
+#define DBDMA_AC97_TX_CHAN DSCR_CMD0_PSC1_TX
+#define DBDMA_AC97_RX_CHAN DSCR_CMD0_PSC1_RX
+#define DBDMA_I2S_TX_CHAN DSCR_CMD0_PSC1_TX
+#define DBDMA_I2S_RX_CHAN DSCR_CMD0_PSC1_RX
+
+/* SPI and SMB are muxed on the Pb1200 board.
+ Refer to board documentation.
+ */
+#define SPI_PSC_BASE PSC0_BASE_ADDR
+#define SMBUS_PSC_BASE PSC0_BASE_ADDR
+/* AC97 and I2S are muxed on the Pb1200 board.
+ Refer to board documentation.
+ */
+#define AC97_PSC_BASE PSC1_BASE_ADDR
+#define I2S_PSC_BASE PSC1_BASE_ADDR
+
+#define BCSR_KSEG1_ADDR 0xB9800000
+
+typedef volatile struct
+{
+ /*00*/ u16 whoami;
+ u16 reserved0;
+ /*04*/ u16 status;
+ u16 reserved1;
+ /*08*/ u16 switches;
+ u16 reserved2;
+ /*0C*/ u16 resets;
+ u16 reserved3;
+
+ /*10*/ u16 pcmcia;
+ u16 reserved4;
+ /*14*/ u16 board;
+ u16 reserved5;
+ /*18*/ u16 disk_leds;
+ u16 reserved6;
+ /*1C*/ u16 system;
+ u16 reserved7;
+
+ /*20*/ u16 intclr;
+ u16 reserved8;
+ /*24*/ u16 intset;
+ u16 reserved9;
+ /*28*/ u16 intclr_mask;
+ u16 reserved10;
+ /*2C*/ u16 intset_mask;
+ u16 reserved11;
+
+ /*30*/ u16 sig_status;
+ u16 reserved12;
+ /*34*/ u16 int_status;
+ u16 reserved13;
+ /*38*/ u16 reserved14;
+ u16 reserved15;
+ /*3C*/ u16 reserved16;
+ u16 reserved17;
+
+} BCSR;
+
+static BCSR * const bcsr = (BCSR *)BCSR_KSEG1_ADDR;
+
+/*
+ * Register bit definitions for the BCSRs
+ */
+#define BCSR_WHOAMI_DCID 0x000F
+#define BCSR_WHOAMI_CPLD 0x00F0
+#define BCSR_WHOAMI_BOARD 0x0F00
+
+#define BCSR_STATUS_PCMCIA0VS 0x0003
+#define BCSR_STATUS_PCMCIA1VS 0x000C
+#define BCSR_STATUS_SWAPBOOT 0x0040
+#define BCSR_STATUS_FLASHBUSY 0x0100
+#define BCSR_STATUS_IDECBLID 0x0200
+#define BCSR_STATUS_SD0WP 0x0400
+#define BCSR_STATUS_U0RXD 0x1000
+#define BCSR_STATUS_U1RXD 0x2000
+
+#define BCSR_SWITCHES_OCTAL 0x00FF
+#define BCSR_SWITCHES_DIP_1 0x0080
+#define BCSR_SWITCHES_DIP_2 0x0040
+#define BCSR_SWITCHES_DIP_3 0x0020
+#define BCSR_SWITCHES_DIP_4 0x0010
+#define BCSR_SWITCHES_DIP_5 0x0008
+#define BCSR_SWITCHES_DIP_6 0x0004
+#define BCSR_SWITCHES_DIP_7 0x0002
+#define BCSR_SWITCHES_DIP_8 0x0001
+#define BCSR_SWITCHES_ROTARY 0x0F00
+
+#define BCSR_RESETS_ETH 0x0001
+#define BCSR_RESETS_CAMERA 0x0002
+#define BCSR_RESETS_DC 0x0004
+#define BCSR_RESETS_IDE 0x0008
+#define BCSR_RESETS_TV 0x0010
+/* not resets but in the same register */
+#define BCSR_RESETS_PWMR1mUX 0x0800
+#define BCSR_RESETS_PCS0MUX 0x1000
+#define BCSR_RESETS_PCS1MUX 0x2000
+#define BCSR_RESETS_SPISEL 0x4000
+
+#define BCSR_PCMCIA_PC0VPP 0x0003
+#define BCSR_PCMCIA_PC0VCC 0x000C
+#define BCSR_PCMCIA_PC0DRVEN 0x0010
+#define BCSR_PCMCIA_PC0RST 0x0080
+#define BCSR_PCMCIA_PC1VPP 0x0300
+#define BCSR_PCMCIA_PC1VCC 0x0C00
+#define BCSR_PCMCIA_PC1DRVEN 0x1000
+#define BCSR_PCMCIA_PC1RST 0x8000
+
+#define BCSR_BOARD_LCDVEE 0x0001
+#define BCSR_BOARD_LCDVDD 0x0002
+#define BCSR_BOARD_LCDBL 0x0004
+#define BCSR_BOARD_CAMSNAP 0x0010
+#define BCSR_BOARD_CAMPWR 0x0020
+#define BCSR_BOARD_SD0PWR 0x0040
+
+#define BCSR_LEDS_DECIMALS 0x0003
+#define BCSR_LEDS_LED0 0x0100
+#define BCSR_LEDS_LED1 0x0200
+#define BCSR_LEDS_LED2 0x0400
+#define BCSR_LEDS_LED3 0x0800
+
+#define BCSR_SYSTEM_POWEROFF 0x4000
+#define BCSR_SYSTEM_RESET 0x8000
+
+/* Bit positions for the different interrupt sources */
+#define BCSR_INT_IDE 0x0001
+#define BCSR_INT_ETH 0x0002
+#define BCSR_INT_PC0 0x0004
+#define BCSR_INT_PC0STSCHG 0x0008
+#define BCSR_INT_PC1 0x0010
+#define BCSR_INT_PC1STSCHG 0x0020
+#define BCSR_INT_DC 0x0040
+#define BCSR_INT_FLASHBUSY 0x0080
+#define BCSR_INT_PC0INSERT 0x0100
+#define BCSR_INT_PC0EJECT 0x0200
+#define BCSR_INT_PC1INSERT 0x0400
+#define BCSR_INT_PC1EJECT 0x0800
+#define BCSR_INT_SD0INSERT 0x1000
+#define BCSR_INT_SD0EJECT 0x2000
+
+#define AU1XXX_SMC91111_PHYS_ADDR (0x19000300)
+#define AU1XXX_SMC91111_IRQ DB1200_ETH_INT
+
+#define AU1XXX_ATA_PHYS_ADDR (0x18800000)
+#define AU1XXX_ATA_PHYS_LEN (0x100)
+#define AU1XXX_ATA_REG_OFFSET (5)
+#define AU1XXX_ATA_INT DB1200_IDE_INT
+#define AU1XXX_ATA_DDMA_REQ DSCR_CMD0_DMA_REQ1;
+#define AU1XXX_ATA_RQSIZE 128
+
+#define NAND_PHYS_ADDR 0x20000000
+
+/*
+ * External Interrupts for Pb1200 as of 8/6/2004.
+ * Bit positions in the CPLD registers can be calculated by taking
+ * the interrupt define and subtracting the DB1200_INT_BEGIN value.
+ * *example: IDE bis pos is = 64 - 64
+ ETH bit pos is = 65 - 64
+ */
+#define DB1200_INT_BEGIN (AU1000_LAST_INTC1_INT + 1)
+#define DB1200_IDE_INT (DB1200_INT_BEGIN + 0)
+#define DB1200_ETH_INT (DB1200_INT_BEGIN + 1)
+#define DB1200_PC0_INT (DB1200_INT_BEGIN + 2)
+#define DB1200_PC0_STSCHG_INT (DB1200_INT_BEGIN + 3)
+#define DB1200_PC1_INT (DB1200_INT_BEGIN + 4)
+#define DB1200_PC1_STSCHG_INT (DB1200_INT_BEGIN + 5)
+#define DB1200_DC_INT (DB1200_INT_BEGIN + 6)
+#define DB1200_FLASHBUSY_INT (DB1200_INT_BEGIN + 7)
+#define DB1200_PC0_INSERT_INT (DB1200_INT_BEGIN + 8)
+#define DB1200_PC0_EJECT_INT (DB1200_INT_BEGIN + 9)
+#define DB1200_PC1_INSERT_INT (DB1200_INT_BEGIN + 10)
+#define DB1200_PC1_EJECT_INT (DB1200_INT_BEGIN + 11)
+#define DB1200_SD0_INSERT_INT (DB1200_INT_BEGIN + 12)
+#define DB1200_SD0_EJECT_INT (DB1200_INT_BEGIN + 13)
+
+#define DB1200_INT_END (DB1200_INT_BEGIN + 15)
+
+/* For drivers/pcmcia/au1000_db1x00.c */
+
+/* PCMCIA Db1x00 specific defines */
+
+#define PCMCIA_MAX_SOCK 1
+#define PCMCIA_NUM_SOCKS (PCMCIA_MAX_SOCK+1)
+
+/* VPP/VCC */
+#define SET_VCC_VPP(VCC, VPP, SLOT)\
+ ((((VCC)<<2) | ((VPP)<<0)) << ((SLOT)*8))
+
+#define BOARD_PC0_INT DB1200_PC0_INT
+#define BOARD_PC1_INT DB1200_PC1_INT
+#define BOARD_CARD_INSERTED(SOCKET) bcsr->sig_status & (1<<(8+(2*SOCKET)))
+
+#endif /* __ASM_DB1200_H */
+
diff --git a/include/asm-mips/mach-dec/mc146818rtc.h b/include/asm-mips/mach-dec/mc146818rtc.h
index a326f451253b..6d37a5675803 100644
--- a/include/asm-mips/mach-dec/mc146818rtc.h
+++ b/include/asm-mips/mach-dec/mc146818rtc.h
@@ -3,7 +3,7 @@
*
* Copyright (C) 1998, 2001 by Ralf Baechle
* Copyright (C) 1998 by Harald Koerfgen
- * Copyright (C) 2002 Maciej W. Rozycki
+ * Copyright (C) 2002, 2005 Maciej W. Rozycki
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -14,23 +14,18 @@
#define __ASM_MIPS_DEC_RTC_DEC_H
#include <linux/types.h>
-
#include <asm/addrspace.h>
+#include <asm/dec/system.h>
extern volatile u8 *dec_rtc_base;
-extern unsigned long dec_kn_slot_size;
-#define RTC_PORT(x) CPHYSADDR(dec_rtc_base)
+#define RTC_PORT(x) CPHYSADDR((long)dec_rtc_base)
#define RTC_IO_EXTENT dec_kn_slot_size
#define RTC_IOMAPPED 0
#undef RTC_IRQ
#define RTC_DEC_YEAR 0x3f /* Where we store the real year on DECs. */
-#include <linux/mc146818rtc.h>
-#include <linux/module.h>
-#include <linux/types.h>
-
static inline unsigned char CMOS_READ(unsigned long addr)
{
return dec_rtc_base[addr * 4];
diff --git a/include/asm-mips/mach-generic/cpu-feature-overrides.h b/include/asm-mips/mach-generic/cpu-feature-overrides.h
index 0aecfd08e39a..7c185bb06f13 100644
--- a/include/asm-mips/mach-generic/cpu-feature-overrides.h
+++ b/include/asm-mips/mach-generic/cpu-feature-overrides.h
@@ -8,6 +8,6 @@
#ifndef __ASM_MACH_GENERIC_CPU_FEATURE_OVERRIDES_H
#define __ASM_MACH_GENERIC_CPU_FEATURE_OVERRIDES_H
-/* Intensionally empty file ... */
+/* Intentionally empty file ... */
#endif /* __ASM_MACH_GENERIC_CPU_FEATURE_OVERRIDES_H */
diff --git a/include/asm-mips/mach-generic/ide.h b/include/asm-mips/mach-generic/ide.h
index cb2edd018ad6..550979a9ea9d 100644
--- a/include/asm-mips/mach-generic/ide.h
+++ b/include/asm-mips/mach-generic/ide.h
@@ -18,6 +18,7 @@
#include <linux/config.h>
#include <linux/pci.h>
#include <linux/stddef.h>
+#include <asm/processor.h>
#ifndef MAX_HWIFS
# ifdef CONFIG_BLK_DEV_IDEPCI
@@ -104,15 +105,75 @@ static __inline__ unsigned long ide_default_io_base(int index)
/* MIPS port and memory-mapped I/O string operations. */
-#define __ide_insw insw
-#define __ide_insl insl
-#define __ide_outsw outsw
-#define __ide_outsl outsl
+static inline void __ide_flush_dcache_range(unsigned long addr, unsigned long size)
+{
+ if (cpu_has_dc_aliases) {
+ unsigned long end = addr + size;
+ for (; addr < end; addr += PAGE_SIZE)
+ flush_dcache_page(virt_to_page(addr));
+ }
+}
+
+static inline void __ide_insw(unsigned long port, void *addr,
+ unsigned int count)
+{
+ insw(port, addr, count);
+ __ide_flush_dcache_range((unsigned long)addr, count * 2);
+}
+
+static inline void __ide_insl(unsigned long port, void *addr, unsigned int count)
+{
+ insl(port, addr, count);
+ __ide_flush_dcache_range((unsigned long)addr, count * 4);
+}
+
+static inline void __ide_outsw(unsigned long port, const void *addr,
+ unsigned long count)
+{
+ outsw(port, addr, count);
+ __ide_flush_dcache_range((unsigned long)addr, count * 2);
+}
+
+static inline void __ide_outsl(unsigned long port, const void *addr,
+ unsigned long count)
+{
+ outsl(port, addr, count);
+ __ide_flush_dcache_range((unsigned long)addr, count * 4);
+}
+
+static inline void __ide_mm_insw(void __iomem *port, void *addr, u32 count)
+{
+ readsw(port, addr, count);
+ __ide_flush_dcache_range((unsigned long)addr, count * 2);
+}
+
+static inline void __ide_mm_insl(void __iomem *port, void *addr, u32 count)
+{
+ readsl(port, addr, count);
+ __ide_flush_dcache_range((unsigned long)addr, count * 4);
+}
+
+static inline void __ide_mm_outsw(void __iomem *port, void *addr, u32 count)
+{
+ writesw(port, addr, count);
+ __ide_flush_dcache_range((unsigned long)addr, count * 2);
+}
+
+static inline void __ide_mm_outsl(void __iomem * port, void *addr, u32 count)
+{
+ writesl(port, addr, count);
+ __ide_flush_dcache_range((unsigned long)addr, count * 4);
+}
-#define __ide_mm_insw readsw
-#define __ide_mm_insl readsl
-#define __ide_mm_outsw writesw
-#define __ide_mm_outsl writesl
+/* ide_insw calls insw, not __ide_insw. Why? */
+#undef insw
+#undef insl
+#undef outsw
+#undef outsl
+#define insw(port, addr, count) __ide_insw(port, addr, count)
+#define insl(port, addr, count) __ide_insl(port, addr, count)
+#define outsw(port, addr, count) __ide_outsw(port, addr, count)
+#define outsl(port, addr, count) __ide_outsl(port, addr, count)
#endif /* __KERNEL__ */
diff --git a/include/asm-mips/mach-generic/ioremap.h b/include/asm-mips/mach-generic/ioremap.h
new file mode 100644
index 000000000000..9b64ff6e485d
--- /dev/null
+++ b/include/asm-mips/mach-generic/ioremap.h
@@ -0,0 +1,23 @@
+/*
+ * include/asm-mips/mach-generic/ioremap.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#ifndef __ASM_MACH_GENERIC_IOREMAP_H
+#define __ASM_MACH_GENERIC_IOREMAP_H
+
+#include <linux/types.h>
+
+/*
+ * Allow physical addresses to be fixed up to help peripherals located
+ * outside the low 32-bit range -- generic pass-through version.
+ */
+static inline phys_t fixup_bigphys_addr(phys_t phys_addr, phys_t size)
+{
+ return phys_addr;
+}
+
+#endif /* __ASM_MACH_GENERIC_IOREMAP_H */
diff --git a/include/asm-mips/mach-generic/kernel-entry-init.h b/include/asm-mips/mach-generic/kernel-entry-init.h
new file mode 100644
index 000000000000..7e66505fa574
--- /dev/null
+++ b/include/asm-mips/mach-generic/kernel-entry-init.h
@@ -0,0 +1,25 @@
+/*
+ * 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 Embedded Alley Solutions, Inc
+ * Copyright (C) 2005 Ralf Baechle (ralf@linux-mips.org)
+ */
+#ifndef __ASM_MACH_GENERIC_KERNEL_ENTRY_H
+#define __ASM_MACH_GENERIC_KERNEL_ENTRY_H
+
+/* Intentionally empty macro, used in head.S. Override in
+ * arch/mips/mach-xxx/kernel-entry-init.h when necessary.
+ */
+.macro kernel_entry_setup
+.endm
+
+/*
+ * Do SMP slave processor setup necessary before we can savely execute C code.
+ */
+ .macro smp_slave_setup
+ .endm
+
+
+#endif /* __ASM_MACH_GENERIC_KERNEL_ENTRY_H */
diff --git a/include/asm-mips/mach-generic/kmalloc.h b/include/asm-mips/mach-generic/kmalloc.h
new file mode 100644
index 000000000000..373d66dee9d7
--- /dev/null
+++ b/include/asm-mips/mach-generic/kmalloc.h
@@ -0,0 +1,13 @@
+#ifndef __ASM_MACH_GENERIC_KMALLOC_H
+#define __ASM_MACH_GENERIC_KMALLOC_H
+
+#include <linux/config.h>
+
+#ifndef CONFIG_DMA_COHERENT
+/*
+ * Total overkill for most systems but need as a safe default.
+ */
+#define ARCH_KMALLOC_MINALIGN 128
+#endif
+
+#endif /* __ASM_MACH_GENERIC_KMALLOC_H */
diff --git a/include/asm-mips/mach-generic/spaces.h b/include/asm-mips/mach-generic/spaces.h
index 5a2c1efb4eb7..b849d8dd7e78 100644
--- a/include/asm-mips/mach-generic/spaces.h
+++ b/include/asm-mips/mach-generic/spaces.h
@@ -55,13 +55,13 @@
#endif
#ifdef CONFIG_DMA_NONCOHERENT
-#define CAC_BASE 0x9800000000000000
+#define CAC_BASE 0x9800000000000000UL
#else
-#define CAC_BASE 0xa800000000000000
+#define CAC_BASE 0xa800000000000000UL
#endif
-#define IO_BASE 0x9000000000000000
-#define UNCAC_BASE 0x9000000000000000
-#define MAP_BASE 0xc000000000000000
+#define IO_BASE 0x9000000000000000UL
+#define UNCAC_BASE 0x9000000000000000UL
+#define MAP_BASE 0xc000000000000000UL
#define TO_PHYS(x) ( ((x) & TO_PHYS_MASK))
#define TO_CAC(x) (CAC_BASE | ((x) & TO_PHYS_MASK))
diff --git a/include/asm-mips/mach-ip22/cpu-feature-overrides.h b/include/asm-mips/mach-ip22/cpu-feature-overrides.h
index 3c8896d9b133..ab9714668177 100644
--- a/include/asm-mips/mach-ip22/cpu-feature-overrides.h
+++ b/include/asm-mips/mach-ip22/cpu-feature-overrides.h
@@ -11,6 +11,12 @@
/*
* IP22 with a variety of processors so we can't use defaults for everything.
*/
+#define cpu_has_tlb 1
+#define cpu_has_4kex 1
+#define cpu_has_4kcache 1
+#define cpu_has_fpu 1
+#define cpu_has_32fpr 1
+#define cpu_has_counter 1
#define cpu_has_mips16 0
#define cpu_has_divec 0
#define cpu_has_cache_cdex_p 1
@@ -23,6 +29,8 @@
#define cpu_has_dc_aliases (PAGE_SIZE < 0x4000)
#define cpu_has_ic_fills_f_dc 0
+#define cpu_has_dsp 0
+
#define cpu_has_nofpuex 0
#define cpu_has_64bits 1
diff --git a/include/asm-mips/mach-ip22/spaces.h b/include/asm-mips/mach-ip22/spaces.h
index e96166f27c49..8385f716798d 100644
--- a/include/asm-mips/mach-ip22/spaces.h
+++ b/include/asm-mips/mach-ip22/spaces.h
@@ -44,7 +44,7 @@
#define CAC_BASE 0xffffffff80000000
#define IO_BASE 0xffffffffa0000000
#define UNCAC_BASE 0xffffffffa0000000
-#define MAP_BASE 0xffffffffc0000000
+#define MAP_BASE 0xc000000000000000
#define TO_PHYS(x) ( ((x) & TO_PHYS_MASK))
#define TO_CAC(x) (CAC_BASE | ((x) & TO_PHYS_MASK))
diff --git a/include/asm-mips/mach-ip27/cpu-feature-overrides.h b/include/asm-mips/mach-ip27/cpu-feature-overrides.h
index fe96d7358517..4c8a90051fd0 100644
--- a/include/asm-mips/mach-ip27/cpu-feature-overrides.h
+++ b/include/asm-mips/mach-ip27/cpu-feature-overrides.h
@@ -25,6 +25,7 @@
#define cpu_has_vtag_icache 0
#define cpu_has_dc_aliases 0
#define cpu_has_ic_fills_f_dc 0
+#define cpu_has_dsp 0
#define cpu_icache_snoops_remote_store 1
#define cpu_has_nofpuex 0
diff --git a/include/asm-mips/mach-ip27/kernel-entry-init.h b/include/asm-mips/mach-ip27/kernel-entry-init.h
new file mode 100644
index 000000000000..c1a10314b317
--- /dev/null
+++ b/include/asm-mips/mach-ip27/kernel-entry-init.h
@@ -0,0 +1,52 @@
+/*
+ * 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) 2000 Silicon Graphics, Inc.
+ * Copyright (C) 2005 Ralf Baechle <ralf@linux-mips.org>
+ */
+#ifndef __ASM_MACH_IP27_KERNEL_ENTRY_H
+#define __ASM_MACH_IP27_KERNEL_ENTRY_H
+
+#include <asm/sn/addrs.h>
+#include <asm/sn/sn0/hubni.h>
+#include <asm/sn/klkernvars.h>
+
+/*
+ * Returns the local nasid into res.
+ */
+ .macro GET_NASID_ASM res
+ dli \res, LOCAL_HUB_ADDR(NI_STATUS_REV_ID)
+ ld \res, (\res)
+ and \res, NSRI_NODEID_MASK
+ dsrl \res, NSRI_NODEID_SHFT
+ .endm
+
+/*
+ * Intentionally empty macro, used in head.S. Override in
+ * arch/mips/mach-xxx/kernel-entry-init.h when necessary.
+ */
+ .macro kernel_entry_setup
+ GET_NASID_ASM t1
+ move t2, t1 # text and data are here
+ MAPPED_KERNEL_SETUP_TLB
+ .endm
+
+/*
+ * Do SMP slave processor setup necessary before we can savely execute C code.
+ */
+ .macro smp_slave_setup
+ GET_NASID_ASM t1
+ dli t0, KLDIR_OFFSET + (KLI_KERN_VARS * KLDIR_ENT_SIZE) + \
+ KLDIR_OFF_POINTER + CAC_BASE
+ dsll t1, NASID_SHFT
+ or t0, t0, t1
+ ld t0, 0(t0) # t0 points to kern_vars struct
+ lh t1, KV_RO_NASID_OFFSET(t0)
+ lh t2, KV_RW_NASID_OFFSET(t0)
+ MAPPED_KERNEL_SETUP_TLB
+ ARC64_TWIDDLE_PC
+ .endm
+
+#endif /* __ASM_MACH_IP27_KERNEL_ENTRY_H */
diff --git a/include/asm-mips/mach-ip27/kmalloc.h b/include/asm-mips/mach-ip27/kmalloc.h
new file mode 100644
index 000000000000..426bd049b2d7
--- /dev/null
+++ b/include/asm-mips/mach-ip27/kmalloc.h
@@ -0,0 +1,8 @@
+#ifndef __ASM_MACH_IP27_KMALLOC_H
+#define __ASM_MACH_IP27_KMALLOC_H
+
+/*
+ * All happy, no need to define ARCH_KMALLOC_MINALIGN
+ */
+
+#endif /* __ASM_MACH_IP27_KMALLOC_H */
diff --git a/include/asm-mips/mach-ip27/mmzone.h b/include/asm-mips/mach-ip27/mmzone.h
index d3f566362e9d..986a3b9b59a7 100644
--- a/include/asm-mips/mach-ip27/mmzone.h
+++ b/include/asm-mips/mach-ip27/mmzone.h
@@ -10,7 +10,6 @@
#define LEVELS_PER_SLICE 128
struct slice_data {
- unsigned long irq_alloc_mask[2];
unsigned long irq_enable_mask[2];
int level_to_irq[LEVELS_PER_SLICE];
};
@@ -20,6 +19,7 @@ struct hub_data {
DECLARE_BITMAP(h_bigwin_used, HUB_NUM_BIG_WINDOW);
cpumask_t h_cpus;
unsigned long slice_map;
+ unsigned long irq_alloc_mask[2];
struct slice_data slice[2];
};
diff --git a/include/asm-mips/mach-ip27/spaces.h b/include/asm-mips/mach-ip27/spaces.h
index e3b3fe32eeb1..45e61785ef42 100644
--- a/include/asm-mips/mach-ip27/spaces.h
+++ b/include/asm-mips/mach-ip27/spaces.h
@@ -20,6 +20,7 @@
#define IO_BASE 0x9200000000000000
#define MSPEC_BASE 0x9400000000000000
#define UNCAC_BASE 0x9600000000000000
+#define MAP_BASE 0xc000000000000000
#define TO_PHYS(x) ( ((x) & TO_PHYS_MASK))
#define TO_CAC(x) (CAC_BASE | ((x) & TO_PHYS_MASK))
diff --git a/include/asm-mips/mach-ip27/topology.h b/include/asm-mips/mach-ip27/topology.h
index a70a81257c3d..82141c711c33 100644
--- a/include/asm-mips/mach-ip27/topology.h
+++ b/include/asm-mips/mach-ip27/topology.h
@@ -9,6 +9,9 @@
#define parent_node(node) (node)
#define node_to_cpumask(node) (hub_data(node)->h_cpus)
#define node_to_first_cpu(node) (first_cpu(node_to_cpumask(node)))
+struct pci_bus;
+extern int pcibus_to_node(struct pci_bus *);
+
#define pcibus_to_cpumask(bus) (cpu_online_map)
extern unsigned char __node_distances[MAX_COMPACT_NODES][MAX_COMPACT_NODES];
diff --git a/include/asm-mips/mach-ip32/cpu-feature-overrides.h b/include/asm-mips/mach-ip32/cpu-feature-overrides.h
index 04713973c6c3..ab37fc1842ba 100644
--- a/include/asm-mips/mach-ip32/cpu-feature-overrides.h
+++ b/include/asm-mips/mach-ip32/cpu-feature-overrides.h
@@ -37,5 +37,6 @@
#define cpu_has_ejtag 0
#define cpu_has_vtag_icache 0
#define cpu_has_ic_fills_f_dc 0
+#define cpu_has_dsp 0
#endif /* __ASM_MACH_IP32_CPU_FEATURE_OVERRIDES_H */
diff --git a/include/asm-mips/mach-ip32/kmalloc.h b/include/asm-mips/mach-ip32/kmalloc.h
new file mode 100644
index 000000000000..9d2d4d9ac036
--- /dev/null
+++ b/include/asm-mips/mach-ip32/kmalloc.h
@@ -0,0 +1,12 @@
+#ifndef __ASM_MACH_IP32_KMALLOC_H
+#define __ASM_MACH_IP32_KMALLOC_H
+
+#include <linux/config.h>
+
+#if defined(CONFIG_CPU_R5000) || defined (CONFIG_CPU_RM7000)
+#define ARCH_KMALLOC_MINALIGN 32
+#else
+#define ARCH_KMALLOC_MINALIGN 128
+#endif
+
+#endif /* __ASM_MACH_IP32_KMALLOC_H */
diff --git a/include/asm-mips/mach-ip32/spaces.h b/include/asm-mips/mach-ip32/spaces.h
index c7839f85c68d..44abe5c02389 100644
--- a/include/asm-mips/mach-ip32/spaces.h
+++ b/include/asm-mips/mach-ip32/spaces.h
@@ -19,10 +19,10 @@
#define HIGHMEM_START (1UL << 59UL)
#endif
-#define CAC_BASE 0x9800000000000000
-#define IO_BASE 0x9000000000000000
-#define UNCAC_BASE 0x9000000000000000
-#define MAP_BASE 0xc000000000000000
+#define CAC_BASE 0x9800000000000000UL
+#define IO_BASE 0x9000000000000000UL
+#define UNCAC_BASE 0x9000000000000000UL
+#define MAP_BASE 0xc000000000000000UL
#define TO_PHYS(x) ( ((x) & TO_PHYS_MASK))
#define TO_CAC(x) (CAC_BASE | ((x) & TO_PHYS_MASK))
diff --git a/include/asm-mips/mach-ja/cpu-feature-overrides.h b/include/asm-mips/mach-ja/cpu-feature-overrides.h
index ca57e7db98bb..a0fde405d4c4 100644
--- a/include/asm-mips/mach-ja/cpu-feature-overrides.h
+++ b/include/asm-mips/mach-ja/cpu-feature-overrides.h
@@ -25,6 +25,7 @@
#define cpu_has_vtag_icache 0
#define cpu_has_dc_aliases 0
#define cpu_has_ic_fills_f_dc 0
+#define cpu_has_dsp 0
#define cpu_icache_snoops_remote_store 0
#define cpu_has_nofpuex 0
@@ -36,10 +37,4 @@
#define cpu_icache_line_size() 32
#define cpu_scache_line_size() 32
-/*
- * On the RM9000 we need to ensure that I-cache lines being fetches only
- * contain valid instructions are funny things will happen.
- */
-#define PLAT_TRAMPOLINE_STUFF_LINE 32UL
-
#endif /* __ASM_MACH_JA_CPU_FEATURE_OVERRIDES_H */
diff --git a/include/asm-mips/mach-mips/cpu-feature-overrides.h b/include/asm-mips/mach-mips/cpu-feature-overrides.h
index 6f51be571bf0..9f92aed17754 100644
--- a/include/asm-mips/mach-mips/cpu-feature-overrides.h
+++ b/include/asm-mips/mach-mips/cpu-feature-overrides.h
@@ -17,7 +17,7 @@
#ifdef CONFIG_CPU_MIPS32
#define cpu_has_tlb 1
#define cpu_has_4kex 1
-#define cpu_has_4ktlb 1
+#define cpu_has_4kcache 1
/* #define cpu_has_fpu ? */
/* #define cpu_has_32fpr ? */
#define cpu_has_counter 1
@@ -37,12 +37,13 @@
/* #define cpu_has_64bits ? */
/* #define cpu_has_64bit_zero_reg ? */
/* #define cpu_has_subset_pcaches ? */
+#define cpu_icache_snoops_remote_store 1
#endif
#ifdef CONFIG_CPU_MIPS64
#define cpu_has_tlb 1
#define cpu_has_4kex 1
-#define cpu_has_4ktlb 1
+#define cpu_has_4kcache 1
/* #define cpu_has_fpu ? */
/* #define cpu_has_32fpr ? */
#define cpu_has_counter 1
@@ -62,6 +63,7 @@
/* #define cpu_has_64bits ? */
/* #define cpu_has_64bit_zero_reg ? */
/* #define cpu_has_subset_pcaches ? */
+#define cpu_icache_snoops_remote_store 1
#endif
#endif /* __ASM_MACH_MIPS_CPU_FEATURE_OVERRIDES_H */
diff --git a/include/asm-mips/mach-mips/irq.h b/include/asm-mips/mach-mips/irq.h
new file mode 100644
index 000000000000..f8579696ca54
--- /dev/null
+++ b/include/asm-mips/mach-mips/irq.h
@@ -0,0 +1,14 @@
+#ifndef __ASM_MACH_MIPS_IRQ_H
+#define __ASM_MACH_MIPS_IRQ_H
+
+#include <linux/config.h>
+
+#define NR_IRQS 256
+
+#ifdef CONFIG_SMP
+
+#define ARCH_HAS_IRQ_PER_CPU
+
+#endif
+
+#endif /* __ASM_MACH_MIPS_IRQ_H */
diff --git a/include/asm-mips/mach-ocelot3/cpu-feature-overrides.h b/include/asm-mips/mach-ocelot3/cpu-feature-overrides.h
index 7473512384bc..825c5f674dfc 100644
--- a/include/asm-mips/mach-ocelot3/cpu-feature-overrides.h
+++ b/include/asm-mips/mach-ocelot3/cpu-feature-overrides.h
@@ -28,6 +28,7 @@
#define cpu_has_vtag_icache 0
#define cpu_has_dc_aliases 0
#define cpu_has_ic_fills_f_dc 0
+#define cpu_has_dsp 0
#define cpu_icache_snoops_remote_store 0
#define cpu_has_nofpuex 0
@@ -39,10 +40,4 @@
#define cpu_icache_line_size() 32
#define cpu_scache_line_size() 32
-/*
- * On the RM9000 we need to ensure that I-cache lines being fetches only
- * contain valid instructions are funny things will happen.
- */
-#define PLAT_TRAMPOLINE_STUFF_LINE 32UL
-
#endif /* __ASM_MACH_JA_CPU_FEATURE_OVERRIDES_H */
diff --git a/include/asm-mips/mach-pb1x00/pb1200.h b/include/asm-mips/mach-pb1x00/pb1200.h
new file mode 100644
index 000000000000..9a3088b19bf3
--- /dev/null
+++ b/include/asm-mips/mach-pb1x00/pb1200.h
@@ -0,0 +1,252 @@
+/*
+ * AMD Alchemy PB1200 Referrence Board
+ * Board Registers defines.
+ *
+ * ########################################################################
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ *
+ *
+ */
+#ifndef __ASM_PB1200_H
+#define __ASM_PB1200_H
+
+#include <linux/types.h>
+
+// This is defined in au1000.h with bogus value
+#undef AU1X00_EXTERNAL_INT
+
+#define DBDMA_AC97_TX_CHAN DSCR_CMD0_PSC1_TX
+#define DBDMA_AC97_RX_CHAN DSCR_CMD0_PSC1_RX
+#define DBDMA_I2S_TX_CHAN DSCR_CMD0_PSC1_TX
+#define DBDMA_I2S_RX_CHAN DSCR_CMD0_PSC1_RX
+
+/* SPI and SMB are muxed on the Pb1200 board.
+ Refer to board documentation.
+ */
+#define SPI_PSC_BASE PSC0_BASE_ADDR
+#define SMBUS_PSC_BASE PSC0_BASE_ADDR
+/* AC97 and I2S are muxed on the Pb1200 board.
+ Refer to board documentation.
+ */
+#define AC97_PSC_BASE PSC1_BASE_ADDR
+#define I2S_PSC_BASE PSC1_BASE_ADDR
+
+#define BCSR_KSEG1_ADDR 0xAD800000
+
+typedef volatile struct
+{
+ /*00*/ u16 whoami;
+ u16 reserved0;
+ /*04*/ u16 status;
+ u16 reserved1;
+ /*08*/ u16 switches;
+ u16 reserved2;
+ /*0C*/ u16 resets;
+ u16 reserved3;
+
+ /*10*/ u16 pcmcia;
+ u16 reserved4;
+ /*14*/ u16 board;
+ u16 reserved5;
+ /*18*/ u16 disk_leds;
+ u16 reserved6;
+ /*1C*/ u16 system;
+ u16 reserved7;
+
+ /*20*/ u16 intclr;
+ u16 reserved8;
+ /*24*/ u16 intset;
+ u16 reserved9;
+ /*28*/ u16 intclr_mask;
+ u16 reserved10;
+ /*2C*/ u16 intset_mask;
+ u16 reserved11;
+
+ /*30*/ u16 sig_status;
+ u16 reserved12;
+ /*34*/ u16 int_status;
+ u16 reserved13;
+ /*38*/ u16 reserved14;
+ u16 reserved15;
+ /*3C*/ u16 reserved16;
+ u16 reserved17;
+
+} BCSR;
+
+static BCSR * const bcsr = (BCSR *)BCSR_KSEG1_ADDR;
+
+/*
+ * Register bit definitions for the BCSRs
+ */
+#define BCSR_WHOAMI_DCID 0x000F
+#define BCSR_WHOAMI_CPLD 0x00F0
+#define BCSR_WHOAMI_BOARD 0x0F00
+
+#define BCSR_STATUS_PCMCIA0VS 0x0003
+#define BCSR_STATUS_PCMCIA1VS 0x000C
+#define BCSR_STATUS_SWAPBOOT 0x0040
+#define BCSR_STATUS_FLASHBUSY 0x0100
+#define BCSR_STATUS_IDECBLID 0x0200
+#define BCSR_STATUS_SD0WP 0x0400
+#define BCSR_STATUS_SD1WP 0x0800
+#define BCSR_STATUS_U0RXD 0x1000
+#define BCSR_STATUS_U1RXD 0x2000
+
+#define BCSR_SWITCHES_OCTAL 0x00FF
+#define BCSR_SWITCHES_DIP_1 0x0080
+#define BCSR_SWITCHES_DIP_2 0x0040
+#define BCSR_SWITCHES_DIP_3 0x0020
+#define BCSR_SWITCHES_DIP_4 0x0010
+#define BCSR_SWITCHES_DIP_5 0x0008
+#define BCSR_SWITCHES_DIP_6 0x0004
+#define BCSR_SWITCHES_DIP_7 0x0002
+#define BCSR_SWITCHES_DIP_8 0x0001
+#define BCSR_SWITCHES_ROTARY 0x0F00
+
+#define BCSR_RESETS_ETH 0x0001
+#define BCSR_RESETS_CAMERA 0x0002
+#define BCSR_RESETS_DC 0x0004
+#define BCSR_RESETS_IDE 0x0008
+/* not resets but in the same register */
+#define BCSR_RESETS_WSCFSM 0x0800
+#define BCSR_RESETS_PCS0MUX 0x1000
+#define BCSR_RESETS_PCS1MUX 0x2000
+#define BCSR_RESETS_SPISEL 0x4000
+#define BCSR_RESETS_SD1MUX 0x8000
+
+#define BCSR_PCMCIA_PC0VPP 0x0003
+#define BCSR_PCMCIA_PC0VCC 0x000C
+#define BCSR_PCMCIA_PC0DRVEN 0x0010
+#define BCSR_PCMCIA_PC0RST 0x0080
+#define BCSR_PCMCIA_PC1VPP 0x0300
+#define BCSR_PCMCIA_PC1VCC 0x0C00
+#define BCSR_PCMCIA_PC1DRVEN 0x1000
+#define BCSR_PCMCIA_PC1RST 0x8000
+
+#define BCSR_BOARD_LCDVEE 0x0001
+#define BCSR_BOARD_LCDVDD 0x0002
+#define BCSR_BOARD_LCDBL 0x0004
+#define BCSR_BOARD_CAMSNAP 0x0010
+#define BCSR_BOARD_CAMPWR 0x0020
+#define BCSR_BOARD_SD0PWR 0x0040
+#define BCSR_BOARD_SD1PWR 0x0080
+
+#define BCSR_LEDS_DECIMALS 0x00FF
+#define BCSR_LEDS_LED0 0x0100
+#define BCSR_LEDS_LED1 0x0200
+#define BCSR_LEDS_LED2 0x0400
+#define BCSR_LEDS_LED3 0x0800
+
+#define BCSR_SYSTEM_VDDI 0x001F
+#define BCSR_SYSTEM_POWEROFF 0x4000
+#define BCSR_SYSTEM_RESET 0x8000
+
+/* Bit positions for the different interrupt sources */
+#define BCSR_INT_IDE 0x0001
+#define BCSR_INT_ETH 0x0002
+#define BCSR_INT_PC0 0x0004
+#define BCSR_INT_PC0STSCHG 0x0008
+#define BCSR_INT_PC1 0x0010
+#define BCSR_INT_PC1STSCHG 0x0020
+#define BCSR_INT_DC 0x0040
+#define BCSR_INT_FLASHBUSY 0x0080
+#define BCSR_INT_PC0INSERT 0x0100
+#define BCSR_INT_PC0EJECT 0x0200
+#define BCSR_INT_PC1INSERT 0x0400
+#define BCSR_INT_PC1EJECT 0x0800
+#define BCSR_INT_SD0INSERT 0x1000
+#define BCSR_INT_SD0EJECT 0x2000
+#define BCSR_INT_SD1INSERT 0x4000
+#define BCSR_INT_SD1EJECT 0x8000
+
+/* PCMCIA Db1x00 specific defines */
+#define PCMCIA_MAX_SOCK 1
+#define PCMCIA_NUM_SOCKS (PCMCIA_MAX_SOCK+1)
+
+/* VPP/VCC */
+#define SET_VCC_VPP(VCC, VPP, SLOT)\
+ ((((VCC)<<2) | ((VPP)<<0)) << ((SLOT)*8))
+
+#define AU1XXX_SMC91111_PHYS_ADDR (0x0D000300)
+#define AU1XXX_SMC91111_IRQ PB1200_ETH_INT
+
+#define AU1XXX_ATA_PHYS_ADDR (0x0C800000)
+#define AU1XXX_ATA_PHYS_LEN (0x100)
+#define AU1XXX_ATA_REG_OFFSET (5)
+#define AU1XXX_ATA_INT PB1200_IDE_INT
+#define AU1XXX_ATA_DDMA_REQ DSCR_CMD0_DMA_REQ1;
+#define AU1XXX_ATA_RQSIZE 128
+
+#define NAND_PHYS_ADDR 0x1C000000
+
+/* Timing values as described in databook, * ns value stripped of
+ * lower 2 bits.
+ * These defines are here rather than an SOC1200 generic file because
+ * the parts chosen on another board may be different and may require
+ * different timings.
+ */
+#define NAND_T_H (18 >> 2)
+#define NAND_T_PUL (30 >> 2)
+#define NAND_T_SU (30 >> 2)
+#define NAND_T_WH (30 >> 2)
+
+/* Bitfield shift amounts */
+#define NAND_T_H_SHIFT 0
+#define NAND_T_PUL_SHIFT 4
+#define NAND_T_SU_SHIFT 8
+#define NAND_T_WH_SHIFT 12
+
+#define NAND_TIMING ((NAND_T_H & 0xF) << NAND_T_H_SHIFT) | \
+ ((NAND_T_PUL & 0xF) << NAND_T_PUL_SHIFT) | \
+ ((NAND_T_SU & 0xF) << NAND_T_SU_SHIFT) | \
+ ((NAND_T_WH & 0xF) << NAND_T_WH_SHIFT)
+
+
+/*
+ * External Interrupts for Pb1200 as of 8/6/2004.
+ * Bit positions in the CPLD registers can be calculated by taking
+ * the interrupt define and subtracting the PB1200_INT_BEGIN value.
+ * *example: IDE bis pos is = 64 - 64
+ ETH bit pos is = 65 - 64
+ */
+#define PB1200_INT_BEGIN (AU1000_LAST_INTC1_INT + 1)
+#define PB1200_IDE_INT (PB1200_INT_BEGIN + 0)
+#define PB1200_ETH_INT (PB1200_INT_BEGIN + 1)
+#define PB1200_PC0_INT (PB1200_INT_BEGIN + 2)
+#define PB1200_PC0_STSCHG_INT (PB1200_INT_BEGIN + 3)
+#define PB1200_PC1_INT (PB1200_INT_BEGIN + 4)
+#define PB1200_PC1_STSCHG_INT (PB1200_INT_BEGIN + 5)
+#define PB1200_DC_INT (PB1200_INT_BEGIN + 6)
+#define PB1200_FLASHBUSY_INT (PB1200_INT_BEGIN + 7)
+#define PB1200_PC0_INSERT_INT (PB1200_INT_BEGIN + 8)
+#define PB1200_PC0_EJECT_INT (PB1200_INT_BEGIN + 9)
+#define PB1200_PC1_INSERT_INT (PB1200_INT_BEGIN + 10)
+#define PB1200_PC1_EJECT_INT (PB1200_INT_BEGIN + 11)
+#define PB1200_SD0_INSERT_INT (PB1200_INT_BEGIN + 12)
+#define PB1200_SD0_EJECT_INT (PB1200_INT_BEGIN + 13)
+#define PB1200_SD1_INSERT_INT (PB1200_INT_BEGIN + 14)
+#define PB1200_SD1_EJECT_INT (PB1200_INT_BEGIN + 15)
+
+#define PB1200_INT_END (PB1200_INT_BEGIN + 15)
+
+/* For drivers/pcmcia/au1000_db1x00.c */
+#define BOARD_PC0_INT PB1200_PC0_INT
+#define BOARD_PC1_INT PB1200_PC1_INT
+#define BOARD_CARD_INSERTED(SOCKET) bcsr->sig_status & (1<<(8+(2*SOCKET)))
+
+#endif /* __ASM_PB1200_H */
+
diff --git a/include/asm-mips/mach-pnx8550/cm.h b/include/asm-mips/mach-pnx8550/cm.h
new file mode 100644
index 000000000000..bb0a56c7d011
--- /dev/null
+++ b/include/asm-mips/mach-pnx8550/cm.h
@@ -0,0 +1,43 @@
+/*
+ *
+ * BRIEF MODULE DESCRIPTION
+ * Clock module specific definitions
+ *
+ * Author: source@mvista.com
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ */
+
+#ifndef __PNX8550_CM_H
+#define __PNX8550_CM_H
+
+#define PNX8550_CM_BASE 0xBBE47000
+
+#define PNX8550_CM_PLL0_CTL *(volatile unsigned long *)(PNX8550_CM_BASE + 0x000)
+#define PNX8550_CM_PLL1_CTL *(volatile unsigned long *)(PNX8550_CM_BASE + 0x004)
+#define PNX8550_CM_PLL2_CTL *(volatile unsigned long *)(PNX8550_CM_BASE + 0x008)
+#define PNX8550_CM_PLL3_CTL *(volatile unsigned long *)(PNX8550_CM_BASE + 0x00C)
+
+// Table not complete.....
+
+#define PNX8550_CM_PLL_BLOCKED_MASK 0x80000000
+#define PNX8550_CM_PLL_LOCK_MASK 0x40000000
+#define PNX8550_CM_PLL_CURRENT_ADJ_MASK 0x3c000000
+#define PNX8550_CM_PLL_N_MASK 0x01ff0000
+#define PNX8550_CM_PLL_M_MASK 0x00003f00
+#define PNX8550_CM_PLL_P_MASK 0x0000000c
+#define PNX8550_CM_PLL_PD_MASK 0x00000002
+
+
+#endif
diff --git a/include/asm-mips/mach-pnx8550/glb.h b/include/asm-mips/mach-pnx8550/glb.h
new file mode 100644
index 000000000000..07aa85e609bc
--- /dev/null
+++ b/include/asm-mips/mach-pnx8550/glb.h
@@ -0,0 +1,86 @@
+/*
+ *
+ * BRIEF MODULE DESCRIPTION
+ * PNX8550 global definitions
+ *
+ * Author: source@mvista.com
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ */
+
+#ifndef __PNX8550_GLB_H
+#define __PNX8550_GLB_H
+
+#define PNX8550_GLB1_BASE 0xBBE63000
+#define PNX8550_GLB2_BASE 0xBBE4d000
+#define PNX8550_RESET_BASE 0xBBE60000
+
+/* PCI Inta Output Enable Registers */
+#define PNX8550_GLB2_ENAB_INTA_O *(volatile unsigned long *)(PNX8550_GLB2_BASE + 0x050)
+
+/* Bit 1:Enable DAC Powerdown
+ 0:DACs are enabled and are working normally
+ 1:DACs are powerdown
+*/
+#define PNX8550_GLB_DAC_PD 0x2
+/* Bit 0:Enable of PCI inta output
+ 0 = Disable PCI inta output
+ 1 = Enable PCI inta output
+*/
+#define PNX8550_GLB_ENABLE_INTA_O 0x1
+
+/* PCI Direct Mappings */
+#define PNX8550_PCIMEM 0x12000000
+#define PNX8550_PCIMEM_SIZE 0x08000000
+#define PNX8550_PCIIO 0x1c000000
+#define PNX8550_PCIIO_SIZE 0x02000000 /* 32M */
+
+#define PNX8550_PORT_BASE KSEG1
+
+// GPIO def
+#define PNX8550_GPIO_BASE 0x1Be00000
+
+#define PNX8550_GPIO_DIRQ0 (PNX8550_GPIO_BASE + 0x104500)
+#define PNX8550_GPIO_MC1 (PNX8550_GPIO_BASE + 0x104004)
+#define PNX8550_GPIO_MC_31_BIT 30
+#define PNX8550_GPIO_MC_30_BIT 28
+#define PNX8550_GPIO_MC_29_BIT 26
+#define PNX8550_GPIO_MC_28_BIT 24
+#define PNX8550_GPIO_MC_27_BIT 22
+#define PNX8550_GPIO_MC_26_BIT 20
+#define PNX8550_GPIO_MC_25_BIT 18
+#define PNX8550_GPIO_MC_24_BIT 16
+#define PNX8550_GPIO_MC_23_BIT 14
+#define PNX8550_GPIO_MC_22_BIT 12
+#define PNX8550_GPIO_MC_21_BIT 10
+#define PNX8550_GPIO_MC_20_BIT 8
+#define PNX8550_GPIO_MC_19_BIT 6
+#define PNX8550_GPIO_MC_18_BIT 4
+#define PNX8550_GPIO_MC_17_BIT 2
+#define PNX8550_GPIO_MC_16_BIT 0
+
+#define PNX8550_GPIO_MODE_PRIMOP 0x1
+#define PNX8550_GPIO_MODE_NO_OPENDR 0x2
+#define PNX8550_GPIO_MODE_OPENDR 0x3
+
+// RESET module
+#define PNX8550_RST_CTL *(volatile unsigned long *)(PNX8550_RESET_BASE + 0x0)
+#define PNX8550_RST_CAUSE *(volatile unsigned long *)(PNX8550_RESET_BASE + 0x4)
+#define PNX8550_RST_EN_WATCHDOG *(volatile unsigned long *)(PNX8550_RESET_BASE + 0x8)
+
+#define PNX8550_RST_REL_MIPS_RST_N 0x8
+#define PNX8550_RST_DO_SW_RST 0x4
+#define PNX8550_RST_REL_SYS_RST_OUT 0x2
+#define PNX8550_RST_ASSERT_SYS_RST_OUT 0x1
+#endif
diff --git a/include/asm-mips/mach-pnx8550/int.h b/include/asm-mips/mach-pnx8550/int.h
new file mode 100644
index 000000000000..0e0668b524f4
--- /dev/null
+++ b/include/asm-mips/mach-pnx8550/int.h
@@ -0,0 +1,140 @@
+/*
+ *
+ * BRIEF MODULE DESCRIPTION
+ * Interrupt specific definitions
+ *
+ * Author: source@mvista.com
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ */
+
+#ifndef __PNX8550_INT_H
+#define __PNX8550_INT_H
+
+#define PNX8550_GIC_BASE 0xBBE3E000
+
+#define PNX8550_GIC_PRIMASK_0 *(volatile unsigned long *)(PNX8550_GIC_BASE + 0x000)
+#define PNX8550_GIC_PRIMASK_1 *(volatile unsigned long *)(PNX8550_GIC_BASE + 0x004)
+#define PNX8550_GIC_VECTOR_0 *(volatile unsigned long *)(PNX8550_GIC_BASE + 0x100)
+#define PNX8550_GIC_VECTOR_1 *(volatile unsigned long *)(PNX8550_GIC_BASE + 0x104)
+#define PNX8550_GIC_PEND_1_31 *(volatile unsigned long *)(PNX8550_GIC_BASE + 0x200)
+#define PNX8550_GIC_PEND_32_63 *(volatile unsigned long *)(PNX8550_GIC_BASE + 0x204)
+#define PNX8550_GIC_PEND_64_70 *(volatile unsigned long *)(PNX8550_GIC_BASE + 0x208)
+#define PNX8550_GIC_FEATURES *(volatile unsigned long *)(PNX8550_GIC_BASE + 0x300)
+#define PNX8550_GIC_REQ(x) *(volatile unsigned long *)(PNX8550_GIC_BASE + 0x400 + (x)*4)
+#define PNX8550_GIC_MOD_ID *(volatile unsigned long *)(PNX8550_GIC_BASE + 0xFFC)
+
+// cp0 is two software + six hw exceptions
+#define PNX8550_INT_CP0_TOTINT 8
+#define PNX8550_INT_CP0_MIN 0
+#define PNX8550_INT_CP0_MAX (PNX8550_INT_CP0_MIN + PNX8550_INT_CP0_TOTINT - 1)
+
+#define MIPS_CPU_GIC_IRQ 2
+#define MIPS_CPU_TIMER_IRQ 7
+
+// GIC are 71 exceptions connected to cp0's first hardware exception
+#define PNX8550_INT_GIC_TOTINT 71
+#define PNX8550_INT_GIC_MIN (PNX8550_INT_CP0_MAX+1)
+#define PNX8550_INT_GIC_MAX (PNX8550_INT_GIC_MIN + PNX8550_INT_GIC_TOTINT - 1)
+
+#define PNX8550_INT_UNDEF (PNX8550_INT_GIC_MIN+0)
+#define PNX8550_INT_IPC_TARGET0_MIPS (PNX8550_INT_GIC_MIN+1)
+#define PNX8550_INT_IPC_TARGET1_TM32_1 (PNX8550_INT_GIC_MIN+2)
+#define PNX8550_INT_IPC_TARGET1_TM32_2 (PNX8550_INT_GIC_MIN+3)
+#define PNX8550_INT_RESERVED_4 (PNX8550_INT_GIC_MIN+4)
+#define PNX8550_INT_USB (PNX8550_INT_GIC_MIN+5)
+#define PNX8550_INT_GPIO_EQ1 (PNX8550_INT_GIC_MIN+6)
+#define PNX8550_INT_GPIO_EQ2 (PNX8550_INT_GIC_MIN+7)
+#define PNX8550_INT_GPIO_EQ3 (PNX8550_INT_GIC_MIN+8)
+#define PNX8550_INT_GPIO_EQ4 (PNX8550_INT_GIC_MIN+9)
+
+#define PNX8550_INT_GPIO_EQ5 (PNX8550_INT_GIC_MIN+10)
+#define PNX8550_INT_GPIO_EQ6 (PNX8550_INT_GIC_MIN+11)
+#define PNX8550_INT_RESERVED_12 (PNX8550_INT_GIC_MIN+12)
+#define PNX8550_INT_QVCP1 (PNX8550_INT_GIC_MIN+13)
+#define PNX8550_INT_QVCP2 (PNX8550_INT_GIC_MIN+14)
+#define PNX8550_INT_I2C1 (PNX8550_INT_GIC_MIN+15)
+#define PNX8550_INT_I2C2 (PNX8550_INT_GIC_MIN+16)
+#define PNX8550_INT_ISO_UART1 (PNX8550_INT_GIC_MIN+17)
+#define PNX8550_INT_ISO_UART2 (PNX8550_INT_GIC_MIN+18)
+#define PNX8550_INT_UART1 (PNX8550_INT_GIC_MIN+19)
+
+#define PNX8550_INT_UART2 (PNX8550_INT_GIC_MIN+20)
+#define PNX8550_INT_QNTR (PNX8550_INT_GIC_MIN+21)
+#define PNX8550_INT_RESERVED22 (PNX8550_INT_GIC_MIN+22)
+#define PNX8550_INT_T_DSC (PNX8550_INT_GIC_MIN+23)
+#define PNX8550_INT_M_DSC (PNX8550_INT_GIC_MIN+24)
+#define PNX8550_INT_RESERVED25 (PNX8550_INT_GIC_MIN+25)
+#define PNX8550_INT_2D_DRAW_ENG (PNX8550_INT_GIC_MIN+26)
+#define PNX8550_INT_MEM_BASED_SCALAR1 (PNX8550_INT_GIC_MIN+27)
+#define PNX8550_INT_VIDEO_MPEG (PNX8550_INT_GIC_MIN+28)
+#define PNX8550_INT_VIDEO_INPUT_P1 (PNX8550_INT_GIC_MIN+29)
+
+#define PNX8550_INT_VIDEO_INPUT_P2 (PNX8550_INT_GIC_MIN+30)
+#define PNX8550_INT_SPDI1 (PNX8550_INT_GIC_MIN+31)
+#define PNX8550_INT_SPDO (PNX8550_INT_GIC_MIN+32)
+#define PNX8550_INT_AUDIO_INPUT1 (PNX8550_INT_GIC_MIN+33)
+#define PNX8550_INT_AUDIO_OUTPUT1 (PNX8550_INT_GIC_MIN+34)
+#define PNX8550_INT_AUDIO_INPUT2 (PNX8550_INT_GIC_MIN+35)
+#define PNX8550_INT_AUDIO_OUTPUT2 (PNX8550_INT_GIC_MIN+36)
+#define PNX8550_INT_MEMBASED_SCALAR2 (PNX8550_INT_GIC_MIN+37)
+#define PNX8550_INT_VPK (PNX8550_INT_GIC_MIN+38)
+#define PNX8550_INT_MPEG1_MIPS (PNX8550_INT_GIC_MIN+39)
+
+#define PNX8550_INT_MPEG1_TM (PNX8550_INT_GIC_MIN+40)
+#define PNX8550_INT_MPEG2_MIPS (PNX8550_INT_GIC_MIN+41)
+#define PNX8550_INT_MPEG2_TM (PNX8550_INT_GIC_MIN+42)
+#define PNX8550_INT_TS_DMA (PNX8550_INT_GIC_MIN+43)
+#define PNX8550_INT_EDMA (PNX8550_INT_GIC_MIN+44)
+#define PNX8550_INT_TM_DEBUG1 (PNX8550_INT_GIC_MIN+45)
+#define PNX8550_INT_TM_DEBUG2 (PNX8550_INT_GIC_MIN+46)
+#define PNX8550_INT_PCI_INTA (PNX8550_INT_GIC_MIN+47)
+#define PNX8550_INT_CLOCK_MODULE (PNX8550_INT_GIC_MIN+48)
+#define PNX8550_INT_PCI_XIO_INTA_PCI (PNX8550_INT_GIC_MIN+49)
+
+#define PNX8550_INT_PCI_XIO_INTB_DMA (PNX8550_INT_GIC_MIN+50)
+#define PNX8550_INT_PCI_XIO_INTC_GPPM (PNX8550_INT_GIC_MIN+51)
+#define PNX8550_INT_PCI_XIO_INTD_GPXIO (PNX8550_INT_GIC_MIN+52)
+#define PNX8550_INT_DVD_CSS (PNX8550_INT_GIC_MIN+53)
+#define PNX8550_INT_VLD (PNX8550_INT_GIC_MIN+54)
+#define PNX8550_INT_GPIO_TSU_7_0 (PNX8550_INT_GIC_MIN+55)
+#define PNX8550_INT_GPIO_TSU_15_8 (PNX8550_INT_GIC_MIN+56)
+#define PNX8550_INT_GPIO_CTU_IR (PNX8550_INT_GIC_MIN+57)
+#define PNX8550_INT_GPIO0 (PNX8550_INT_GIC_MIN+58)
+#define PNX8550_INT_GPIO1 (PNX8550_INT_GIC_MIN+59)
+
+#define PNX8550_INT_GPIO2 (PNX8550_INT_GIC_MIN+60)
+#define PNX8550_INT_GPIO3 (PNX8550_INT_GIC_MIN+61)
+#define PNX8550_INT_GPIO4 (PNX8550_INT_GIC_MIN+62)
+#define PNX8550_INT_GPIO5 (PNX8550_INT_GIC_MIN+63)
+#define PNX8550_INT_GPIO6 (PNX8550_INT_GIC_MIN+64)
+#define PNX8550_INT_GPIO7 (PNX8550_INT_GIC_MIN+65)
+#define PNX8550_INT_PMAN_SECURITY (PNX8550_INT_GIC_MIN+66)
+#define PNX8550_INT_I2C3 (PNX8550_INT_GIC_MIN+67)
+#define PNX8550_INT_RESERVED_68 (PNX8550_INT_GIC_MIN+68)
+#define PNX8550_INT_SPDI2 (PNX8550_INT_GIC_MIN+69)
+
+#define PNX8550_INT_I2C4 (PNX8550_INT_GIC_MIN+70)
+
+// Timer are 3 exceptions connected to cp0's 7th hardware exception
+#define PNX8550_INT_TIMER_TOTINT 3
+#define PNX8550_INT_TIMER_MIN (PNX8550_INT_GIC_MAX+1)
+#define PNX8550_INT_TIMER_MAX (PNX8550_INT_TIMER_MIN + PNX8550_INT_TIMER_TOTINT - 1)
+
+#define PNX8550_INT_TIMER1 (PNX8550_INT_TIMER_MIN+0)
+#define PNX8550_INT_TIMER2 (PNX8550_INT_TIMER_MIN+1)
+#define PNX8550_INT_TIMER3 (PNX8550_INT_TIMER_MIN+2)
+#define PNX8550_INT_WATCHDOG PNX8550_INT_TIMER3
+
+#endif
diff --git a/include/asm-mips/mach-pnx8550/kernel-entry-init.h b/include/asm-mips/mach-pnx8550/kernel-entry-init.h
new file mode 100644
index 000000000000..57102fa9da51
--- /dev/null
+++ b/include/asm-mips/mach-pnx8550/kernel-entry-init.h
@@ -0,0 +1,262 @@
+/*
+ * 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 Embedded Alley Solutions, Inc
+ */
+#ifndef __ASM_MACH_KERNEL_ENTRY_INIT_H
+#define __ASM_MACH_KERNEL_ENTRY_INIT_H
+
+#include <asm/cacheops.h>
+#include <asm/addrspace.h>
+
+#define CO_CONFIGPR_VALID 0x3F1F41FF /* valid bits to write to ConfigPR */
+#define HAZARD_CP0 nop; nop; nop; nop; nop; nop; nop; nop; nop; nop; nop; nop;
+#define CACHE_OPC 0xBC000000 /* MIPS cache instruction opcode */
+#define ICACHE_LINE_SIZE 32 /* Instruction cache line size bytes */
+#define DCACHE_LINE_SIZE 32 /* Data cache line size in bytes */
+
+#define ICACHE_SET_COUNT 256 /* Instruction cache set count */
+#define DCACHE_SET_COUNT 128 /* Data cache set count */
+
+#define ICACHE_SET_SIZE (ICACHE_SET_COUNT * ICACHE_LINE_SIZE)
+#define DCACHE_SET_SIZE (DCACHE_SET_COUNT * DCACHE_LINE_SIZE)
+
+ .macro kernel_entry_setup
+ .set push
+ .set noreorder
+ /*
+ * PNX8550 entry point, when running a non compressed
+ * kernel. When loading a zImage, the head.S code in
+ * arch/mips/zboot/pnx8550 will init the caches and,
+ * decompress the kernel, and branch to kernel_entry.
+ */
+cache_begin: li t0, (1<<28)
+ mtc0 t0, CP0_STATUS /* cp0 usable */
+ HAZARD_CP0
+
+ mtc0 zero, CP0_CAUSE
+ HAZARD_CP0
+
+
+ /* Set static virtual to phys address translation and TLB disabled */
+ mfc0 t0, CP0_CONFIG, 7
+ HAZARD_CP0
+
+ and t0,~((1<<19) | (1<<20)) /* TLB/MAP cleared */
+ mtc0 t0, CP0_CONFIG, 7
+ HAZARD_CP0
+
+ /* CPU boots with kseg0 cache algo set to 0x2 -- uncached */
+
+ init_icache
+ nop
+ init_dcache
+ nop
+
+ cachePr4450ICReset
+ nop
+
+ cachePr4450DCReset
+ nop
+
+ /* read ConfigPR into t0 */
+ mfc0 t0, CP0_CONFIG, 7
+ HAZARD_CP0
+
+ /* enable the TLB */
+ or t0, (1<<19)
+
+ /* disable the ICACHE: at least 10x slower */
+ /* or t0, (1<<26) */
+
+ /* disable the DCACHE; CONFIG_CPU_HAS_LLSC should not be set */
+ /* or t0, (1<<27) */
+
+ and t0, CO_CONFIGPR_VALID
+
+ /* enable TLB. */
+ mtc0 t0, CP0_CONFIG, 7
+ HAZARD_CP0
+cache_end:
+ /* Setup CMEM_0 to MMIO address space, 2MB */
+ lui t0, 0x1BE0
+ addi t0, t0, 0x3
+ mtc0 $8, $22, 4
+ nop
+
+ /* Setup CMEM_1, 128MB */
+ lui t0, 0x1000
+ addi t0, t0, 0xf
+ mtc0 $8, $22, 5
+ nop
+
+
+ /* Setup CMEM_2, 32MB */
+ lui t0, 0x1C00
+ addi t0, t0, 0xb
+ mtc0 $8, $22, 6
+ nop
+
+ /* Setup CMEM_3, 0MB */
+ lui t0, 0x0
+ addi t0, t0, 0x0
+ mtc0 $8, $22, 7
+ nop
+
+ /* Enable cache */
+ mfc0 t0, CP0_CONFIG
+ HAZARD_CP0
+ and t0, t0, 0xFFFFFFF8
+ or t0, t0, 3
+ mtc0 t0, CP0_CONFIG
+ HAZARD_CP0
+ .set pop
+ .endm
+
+ .macro init_icache
+ .set push
+ .set noreorder
+
+ /* Get Cache Configuration */
+ mfc0 t3, CP0_CONFIG, 1
+ HAZARD_CP0
+
+ /* get cache Line size */
+
+ srl t1, t3, 19 /* C0_CONFIGPR_IL_SHIFT */
+ andi t1, t1, 0x7 /* C0_CONFIGPR_IL_MASK */
+ beq t1, zero, pr4450_instr_cache_invalidated /* if zero instruction cache is absent */
+ nop
+ addiu t0, t1, 1
+ ori t1, zero, 1
+ sllv t1, t1, t0
+
+ /* get max cache Index */
+ srl t2, t3, 22 /* C0_CONFIGPR_IS_SHIFT */
+ andi t2, t2, 0x7 /* C0_CONFIGPR_IS_MASK */
+ addiu t0, t2, 6
+ ori t2, zero, 1
+ sllv t2, t2, t0
+
+ /* get max cache way */
+ srl t3, t3, 16 /* C0_CONFIGPR_IA_SHIFT */
+ andi t3, t3, 0x7 /* C0_CONFIGPR_IA_MASK */
+ addiu t3, t3, 1
+
+ /* total no of cache lines */
+ multu t2, t3 /* max index * max way */
+ mflo t2
+ addiu t2, t2, -1
+
+ move t0, zero
+pr4450_next_instruction_cache_set:
+ cache Index_Invalidate_I, 0(t0)
+ addu t0, t0, t1 /* add bytes in a line */
+ bne t2, zero, pr4450_next_instruction_cache_set
+ addiu t2, t2, -1 /* reduce no of lines to invalidate by one */
+pr4450_instr_cache_invalidated:
+ .set pop
+ .endm
+
+ .macro init_dcache
+ .set push
+ .set noreorder
+ move t1, zero
+
+ /* Store Tag Information */
+ mtc0 zero, CP0_TAGLO, 0
+ HAZARD_CP0
+
+ mtc0 zero, CP0_TAGHI, 0
+ HAZARD_CP0
+
+ /* Cache size is 16384 = 512 lines x 32 bytes per line */
+ or t2, zero, (128*4)-1 /* 512 lines */
+ /* Invalidate all lines */
+2:
+ cache Index_Store_Tag_D, 0(t1)
+ addiu t2, t2, -1
+ bne t2, zero, 2b
+ addiu t1, t1, 32 /* 32 bytes in a line */
+ .set pop
+ .endm
+
+ .macro cachePr4450ICReset
+ .set push
+ .set noreorder
+
+ /* Save CP0 status reg on entry; */
+ /* disable interrupts during cache reset */
+ mfc0 t0, CP0_STATUS /* T0 = interrupt status on entry */
+ HAZARD_CP0
+
+ mtc0 zero, CP0_STATUS /* disable CPU interrupts */
+ HAZARD_CP0
+
+ or t1, zero, zero /* T1 = starting cache index (0) */
+ ori t2, zero, (256 - 1) /* T2 = inst cache set cnt - 1 */
+
+ icache_invd_loop:
+ /* 9 == register t1 */
+ .word (CACHE_OPC | (9 << 21) | (Index_Invalidate_I << 16) | \
+ (0 * ICACHE_SET_SIZE)) /* invalidate inst cache WAY0 */
+ .word (CACHE_OPC | (9 << 21) | (Index_Invalidate_I << 16) | \
+ (1 * ICACHE_SET_SIZE)) /* invalidate inst cache WAY1 */
+
+ addiu t1, t1, ICACHE_LINE_SIZE /* T1 = next cache line index */
+ bne t2, zero, icache_invd_loop /* T2 = 0 if all sets invalidated */
+ addiu t2, t2, -1 /* decrement T2 set cnt (delay slot) */
+
+ /* Initialize the latches in the instruction cache tag */
+ /* that drive the way selection tri-state bus drivers, by doing a */
+ /* dummy load while the instruction cache is still disabled. */
+ /* TODO: Is this needed ? */
+ la t1, KSEG0 /* T1 = cached memory base address */
+ lw zero, 0x0000(t1) /* (dummy read of first memory word) */
+
+ mtc0 t0, CP0_STATUS /* restore interrupt status on entry */
+ HAZARD_CP0
+ .set pop
+ .endm
+
+ .macro cachePr4450DCReset
+ .set push
+ .set noreorder
+ mfc0 t0, CP0_STATUS /* T0 = interrupt status on entry */
+ HAZARD_CP0
+ mtc0 zero, CP0_STATUS /* disable CPU interrupts */
+ HAZARD_CP0
+
+ /* Writeback/invalidate entire data cache sets/ways/lines */
+ or t1, zero, zero /* T1 = starting cache index (0) */
+ ori t2, zero, (DCACHE_SET_COUNT - 1) /* T2 = data cache set cnt - 1 */
+
+ dcache_wbinvd_loop:
+ /* 9 == register t1 */
+ .word (CACHE_OPC | (9 << 21) | (Index_Writeback_Inv_D << 16) | \
+ (0 * DCACHE_SET_SIZE)) /* writeback/invalidate WAY0 */
+ .word (CACHE_OPC | (9 << 21) | (Index_Writeback_Inv_D << 16) | \
+ (1 * DCACHE_SET_SIZE)) /* writeback/invalidate WAY1 */
+ .word (CACHE_OPC | (9 << 21) | (Index_Writeback_Inv_D << 16) | \
+ (2 * DCACHE_SET_SIZE)) /* writeback/invalidate WAY2 */
+ .word (CACHE_OPC | (9 << 21) | (Index_Writeback_Inv_D << 16) | \
+ (3 * DCACHE_SET_SIZE)) /* writeback/invalidate WAY3 */
+
+ addiu t1, t1, DCACHE_LINE_SIZE /* T1 = next data cache line index */
+ bne t2, zero, dcache_wbinvd_loop /* T2 = 0 when wbinvd entire cache */
+ addiu t2, t2, -1 /* decrement T2 set cnt (delay slot) */
+
+ /* Initialize the latches in the data cache tag that drive the way
+ selection tri-state bus drivers, by doing a dummy load while the
+ data cache is still in the disabled mode. TODO: Is this needed ? */
+ la t1, KSEG0 /* T1 = cached memory base address */
+ lw zero, 0x0000(t1) /* (dummy read of first memory word) */
+
+ mtc0 t0, CP0_STATUS /* restore interrupt status on entry */
+ HAZARD_CP0
+ .set pop
+ .endm
+
+#endif /* __ASM_MACH_KERNEL_ENTRY_INIT_H */
diff --git a/include/asm-mips/mach-pnx8550/nand.h b/include/asm-mips/mach-pnx8550/nand.h
new file mode 100644
index 000000000000..aefbc514ab09
--- /dev/null
+++ b/include/asm-mips/mach-pnx8550/nand.h
@@ -0,0 +1,121 @@
+#ifndef __PNX8550_NAND_H
+#define __PNX8550_NAND_H
+
+#define PNX8550_NAND_BASE_ADDR 0x10000000
+#define PNX8550_PCIXIO_BASE 0xBBE40000
+
+#define PNX8550_DMA_EXT_ADDR *(volatile unsigned long *)(PNX8550_PCIXIO_BASE + 0x800)
+#define PNX8550_DMA_INT_ADDR *(volatile unsigned long *)(PNX8550_PCIXIO_BASE + 0x804)
+#define PNX8550_DMA_TRANS_SIZE *(volatile unsigned long *)(PNX8550_PCIXIO_BASE + 0x808)
+#define PNX8550_DMA_CTRL *(volatile unsigned long *)(PNX8550_PCIXIO_BASE + 0x80c)
+#define PNX8550_XIO_SEL0 *(volatile unsigned long *)(PNX8550_PCIXIO_BASE + 0x814)
+#define PNX8550_GPXIO_ADDR *(volatile unsigned long *)(PNX8550_PCIXIO_BASE + 0x820)
+#define PNX8550_GPXIO_WR *(volatile unsigned long *)(PNX8550_PCIXIO_BASE + 0x824)
+#define PNX8550_GPXIO_RD *(volatile unsigned long *)(PNX8550_PCIXIO_BASE + 0x828)
+#define PNX8550_GPXIO_CTRL *(volatile unsigned long *)(PNX8550_PCIXIO_BASE + 0x82C)
+#define PNX8550_XIO_FLASH_CTRL *(volatile unsigned long *)(PNX8550_PCIXIO_BASE + 0x830)
+#define PNX8550_GPXIO_INT_STATUS *(volatile unsigned long *)(PNX8550_PCIXIO_BASE + 0xfb0)
+#define PNX8550_GPXIO_INT_ENABLE *(volatile unsigned long *)(PNX8550_PCIXIO_BASE + 0xfb4)
+#define PNX8550_GPXIO_INT_CLEAR *(volatile unsigned long *)(PNX8550_PCIXIO_BASE + 0xfb8)
+#define PNX8550_DMA_INT_STATUS *(volatile unsigned long *)(PNX8550_PCIXIO_BASE + 0xfd0)
+#define PNX8550_DMA_INT_ENABLE *(volatile unsigned long *)(PNX8550_PCIXIO_BASE + 0xfd4)
+#define PNX8550_DMA_INT_CLEAR *(volatile unsigned long *)(PNX8550_PCIXIO_BASE + 0xfd8)
+
+#define PNX8550_XIO_SEL0_EN_16BIT 0x00800000
+#define PNX8550_XIO_SEL0_USE_ACK 0x00400000
+#define PNX8550_XIO_SEL0_REN_HIGH 0x00100000
+#define PNX8550_XIO_SEL0_REN_LOW 0x00040000
+#define PNX8550_XIO_SEL0_WEN_HIGH 0x00010000
+#define PNX8550_XIO_SEL0_WEN_LOW 0x00004000
+#define PNX8550_XIO_SEL0_WAIT 0x00000200
+#define PNX8550_XIO_SEL0_OFFSET 0x00000020
+#define PNX8550_XIO_SEL0_TYPE_68360 0x00000000
+#define PNX8550_XIO_SEL0_TYPE_NOR 0x00000008
+#define PNX8550_XIO_SEL0_TYPE_NAND 0x00000010
+#define PNX8550_XIO_SEL0_TYPE_IDE 0x00000018
+#define PNX8550_XIO_SEL0_SIZE_8MB 0x00000000
+#define PNX8550_XIO_SEL0_SIZE_16MB 0x00000002
+#define PNX8550_XIO_SEL0_SIZE_32MB 0x00000004
+#define PNX8550_XIO_SEL0_SIZE_64MB 0x00000006
+#define PNX8550_XIO_SEL0_ENAB 0x00000001
+
+#define PNX8550_SEL0_DEFAULT ((PNX8550_XIO_SEL0_EN_16BIT) | \
+ (PNX8550_XIO_SEL0_REN_HIGH*0)| \
+ (PNX8550_XIO_SEL0_REN_LOW*2) | \
+ (PNX8550_XIO_SEL0_WEN_HIGH*0)| \
+ (PNX8550_XIO_SEL0_WEN_LOW*2) | \
+ (PNX8550_XIO_SEL0_WAIT*4) | \
+ (PNX8550_XIO_SEL0_OFFSET*0) | \
+ (PNX8550_XIO_SEL0_TYPE_NAND) | \
+ (PNX8550_XIO_SEL0_SIZE_32MB) | \
+ (PNX8550_XIO_SEL0_ENAB))
+
+#define PNX8550_GPXIO_PENDING 0x00000200
+#define PNX8550_GPXIO_DONE 0x00000100
+#define PNX8550_GPXIO_CLR_DONE 0x00000080
+#define PNX8550_GPXIO_INIT 0x00000040
+#define PNX8550_GPXIO_READ_CMD 0x00000010
+#define PNX8550_GPXIO_BEN 0x0000000F
+
+#define PNX8550_XIO_FLASH_64MB 0x00200000
+#define PNX8550_XIO_FLASH_INC_DATA 0x00100000
+#define PNX8550_XIO_FLASH_CMD_PH 0x000C0000
+#define PNX8550_XIO_FLASH_CMD_PH2 0x00080000
+#define PNX8550_XIO_FLASH_CMD_PH1 0x00040000
+#define PNX8550_XIO_FLASH_CMD_PH0 0x00000000
+#define PNX8550_XIO_FLASH_ADR_PH 0x00030000
+#define PNX8550_XIO_FLASH_ADR_PH3 0x00030000
+#define PNX8550_XIO_FLASH_ADR_PH2 0x00020000
+#define PNX8550_XIO_FLASH_ADR_PH1 0x00010000
+#define PNX8550_XIO_FLASH_ADR_PH0 0x00000000
+#define PNX8550_XIO_FLASH_CMD_B(x) ((x<<8) & 0x0000FF00)
+#define PNX8550_XIO_FLASH_CMD_A(x) (x & 0x000000FF)
+
+#define PNX8550_XIO_INT_ACK 0x00004000
+#define PNX8550_XIO_INT_COMPL 0x00002000
+#define PNX8550_XIO_INT_NONSUP 0x00000200
+#define PNX8550_XIO_INT_ABORT 0x00000004
+
+#define PNX8550_DMA_CTRL_SINGLE_DATA 0x00000400
+#define PNX8550_DMA_CTRL_SND2XIO 0x00000200
+#define PNX8550_DMA_CTRL_FIX_ADDR 0x00000100
+#define PNX8550_DMA_CTRL_BURST_8 0x00000000
+#define PNX8550_DMA_CTRL_BURST_16 0x00000020
+#define PNX8550_DMA_CTRL_BURST_32 0x00000040
+#define PNX8550_DMA_CTRL_BURST_64 0x00000060
+#define PNX8550_DMA_CTRL_BURST_128 0x00000080
+#define PNX8550_DMA_CTRL_BURST_256 0x000000A0
+#define PNX8550_DMA_CTRL_BURST_512 0x000000C0
+#define PNX8550_DMA_CTRL_BURST_NORES 0x000000E0
+#define PNX8550_DMA_CTRL_INIT_DMA 0x00000010
+#define PNX8550_DMA_CTRL_CMD_TYPE 0x0000000F
+
+/* see PCI system arch, page 100 for the full list: */
+#define PNX8550_DMA_CTRL_PCI_CMD_READ 0x00000006
+#define PNX8550_DMA_CTRL_PCI_CMD_WRITE 0x00000007
+
+#define PNX8550_DMA_INT_STAT_ACK_DONE (1<<14)
+#define PNX8550_DMA_INT_STAT_DMA_DONE (1<<12)
+#define PNX8550_DMA_INT_STAT_DMA_ERR (1<<9)
+#define PNX8550_DMA_INT_STAT_PERR5 (1<<5)
+#define PNX8550_DMA_INT_STAT_PERR4 (1<<4)
+#define PNX8550_DMA_INT_STAT_M_ABORT (1<<2)
+#define PNX8550_DMA_INT_STAT_T_ABORT (1<<1)
+
+#define PNX8550_DMA_INT_EN_ACK_DONE (1<<14)
+#define PNX8550_DMA_INT_EN_DMA_DONE (1<<12)
+#define PNX8550_DMA_INT_EN_DMA_ERR (1<<9)
+#define PNX8550_DMA_INT_EN_PERR5 (1<<5)
+#define PNX8550_DMA_INT_EN_PERR4 (1<<4)
+#define PNX8550_DMA_INT_EN_M_ABORT (1<<2)
+#define PNX8550_DMA_INT_EN_T_ABORT (1<<1)
+
+#define PNX8550_DMA_INT_CLR_ACK_DONE (1<<14)
+#define PNX8550_DMA_INT_CLR_DMA_DONE (1<<12)
+#define PNX8550_DMA_INT_CLR_DMA_ERR (1<<9)
+#define PNX8550_DMA_INT_CLR_PERR5 (1<<5)
+#define PNX8550_DMA_INT_CLR_PERR4 (1<<4)
+#define PNX8550_DMA_INT_CLR_M_ABORT (1<<2)
+#define PNX8550_DMA_INT_CLR_T_ABORT (1<<1)
+
+#endif
diff --git a/include/asm-mips/mach-pnx8550/pci.h b/include/asm-mips/mach-pnx8550/pci.h
new file mode 100644
index 000000000000..b921508d701b
--- /dev/null
+++ b/include/asm-mips/mach-pnx8550/pci.h
@@ -0,0 +1,185 @@
+/*
+ *
+ * BRIEF MODULE DESCRIPTION
+ * PCI specific definitions
+ *
+ * Author: source@mvista.com
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ */
+
+#ifndef __PNX8550_PCI_H
+#define __PNX8550_PCI_H
+
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#define PCI_ACCESS_READ 0
+#define PCI_ACCESS_WRITE 1
+
+#define PCI_CMD_IOR 0x20
+#define PCI_CMD_IOW 0x30
+#define PCI_CMD_CONFIG_READ 0xa0
+#define PCI_CMD_CONFIG_WRITE 0xb0
+
+#define PCI_IO_TIMEOUT 1000
+#define PCI_IO_RETRY 5
+/* Timeout for IO and CFG accesses.
+ This is in 1/1024 th of a jiffie(=10ms)
+ i.e. approx 10us */
+#define PCI_IO_JIFFIES_TIMEOUT 40
+#define PCI_IO_JIFFIES_SHIFT 10
+
+#define PCI_BYTE_ENABLE_MASK 0x0000000f
+#define PCI_CFG_BUS_SHIFT 16
+#define PCI_CFG_FUNC_SHIFT 8
+#define PCI_CFG_REG_SHIFT 2
+
+#define PCI_BASE 0x1be00000
+#define PCI_SETUP 0x00040010
+#define PCI_DIS_REQGNT (1<<30)
+#define PCI_DIS_REQGNTA (1<<29)
+#define PCI_DIS_REQGNTB (1<<28)
+#define PCI_D2_SUPPORT (1<<27)
+#define PCI_D1_SUPPORT (1<<26)
+#define PCI_EN_TA (1<<24)
+#define PCI_EN_PCI2MMI (1<<23)
+#define PCI_EN_XIO (1<<22)
+#define PCI_BASE18_PREF (1<<21)
+#define SIZE_16M 0x3
+#define SIZE_32M 0x4
+#define SIZE_64M 0x5
+#define SIZE_128M 0x6
+#define PCI_SETUP_BASE18_SIZE(X) (X<<18)
+#define PCI_SETUP_BASE18_EN (1<<17)
+#define PCI_SETUP_BASE14_PREF (1<<16)
+#define PCI_SETUP_BASE14_SIZE(X) (X<<12)
+#define PCI_SETUP_BASE14_EN (1<<11)
+#define PCI_SETUP_BASE10_PREF (1<<10)
+#define PCI_SETUP_BASE10_SIZE(X) (X<<7)
+#define PCI_SETUP_CFGMANAGE_EN (1<<1)
+#define PCI_SETUP_PCIARB_EN (1<<0)
+
+#define PCI_CTRL 0x040014
+#define PCI_SWPB_DCS_PCI (1<<16)
+#define PCI_SWPB_PCI_PCI (1<<15)
+#define PCI_SWPB_PCI_DCS (1<<14)
+#define PCI_REG_WR_POST (1<<13)
+#define PCI_XIO_WR_POST (1<<12)
+#define PCI_PCI2_WR_POST (1<<13)
+#define PCI_PCI1_WR_POST (1<<12)
+#define PCI_SERR_SEEN (1<<11)
+#define PCI_B10_SPEC_RD (1<<6)
+#define PCI_B14_SPEC_RD (1<<5)
+#define PCI_B18_SPEC_RD (1<<4)
+#define PCI_B10_NOSUBWORD (1<<3)
+#define PCI_B14_NOSUBWORD (1<<2)
+#define PCI_B18_NOSUBWORD (1<<1)
+#define PCI_RETRY_TMREN (1<<0)
+
+#define PCI_BASE1_LO 0x040018
+#define PCI_BASE1_HI 0x04001C
+#define PCI_BASE2_LO 0x040020
+#define PCI_BASE2_HI 0x040024
+#define PCI_RDLIFETIM 0x040028
+#define PCI_GPPM_ADDR 0x04002C
+#define PCI_GPPM_WDAT 0x040030
+#define PCI_GPPM_RDAT 0x040034
+#define PCI_GPPM_CTRL 0x040038
+#define GPPM_DONE (1<<10)
+#define INIT_PCI_CYCLE (1<<9)
+#define GPPM_CMD(X) (((X)&0xf)<<4)
+#define GPPM_BYTEEN(X) ((X)&0xf)
+#define PCI_UNLOCKREG 0x04003C
+#define UNLOCK_SSID(X) (((X)&0xff)<<8)
+#define UNLOCK_SETUP(X) (((X)&0xff)<<0)
+#define UNLOCK_MAGIC 0xCA
+#define PCI_DEV_VEND_ID 0x040040
+#define DEVICE_ID(X) (((X)>>16)&0xffff)
+#define VENDOR_ID(X) (((X)&0xffff))
+#define PCI_CFG_CMDSTAT 0x040044
+#define PCI_CFG_STATUS(X) (((X)>>16)&0xffff)
+#define PCI_CFG_COMMAND(X) ((X)&0xffff)
+#define PCI_CLASS_REV 0x040048
+#define PCI_CLASSCODE(X) (((X)>>8)&0xffffff)
+#define PCI_REVID(X) ((X)&0xff)
+#define PCI_LAT_TMR 0x04004c
+#define PCI_BASE10 0x040050
+#define PCI_BASE14 0x040054
+#define PCI_BASE18 0x040058
+#define PCI_SUBSYS_ID 0x04006c
+#define PCI_CAP_PTR 0x040074
+#define PCI_CFG_MISC 0x04007c
+#define PCI_PMC 0x040080
+#define PCI_PWR_STATE 0x040084
+#define PCI_IO 0x040088
+#define PCI_SLVTUNING 0x04008C
+#define PCI_DMATUNING 0x040090
+#define PCI_DMAEADDR 0x040800
+#define PCI_DMAIADDR 0x040804
+#define PCI_DMALEN 0x040808
+#define PCI_DMACTRL 0x04080C
+#define PCI_XIOCTRL 0x040810
+#define PCI_SEL0PROF 0x040814
+#define PCI_SEL1PROF 0x040818
+#define PCI_SEL2PROF 0x04081C
+#define PCI_GPXIOADDR 0x040820
+#define PCI_NANDCTRLS 0x400830
+#define PCI_SEL3PROF 0x040834
+#define PCI_SEL4PROF 0x040838
+#define PCI_GPXIO_STAT 0x040FB0
+#define PCI_GPXIO_IMASK 0x040FB4
+#define PCI_GPXIO_ICLR 0x040FB8
+#define PCI_GPXIO_ISET 0x040FBC
+#define PCI_GPPM_STATUS 0x040FC0
+#define GPPM_DONE (1<<10)
+#define GPPM_ERR (1<<9)
+#define GPPM_MPAR_ERR (1<<8)
+#define GPPM_PAR_ERR (1<<7)
+#define GPPM_R_MABORT (1<<2)
+#define GPPM_R_TABORT (1<<1)
+#define PCI_GPPM_IMASK 0x040FC4
+#define PCI_GPPM_ICLR 0x040FC8
+#define PCI_GPPM_ISET 0x040FCC
+#define PCI_DMA_STATUS 0x040FD0
+#define PCI_DMA_IMASK 0x040FD4
+#define PCI_DMA_ICLR 0x040FD8
+#define PCI_DMA_ISET 0x040FDC
+#define PCI_ISTATUS 0x040FE0
+#define PCI_IMASK 0x040FE4
+#define PCI_ICLR 0x040FE8
+#define PCI_ISET 0x040FEC
+#define PCI_MOD_ID 0x040FFC
+
+/*
+ * PCI configuration cycle AD bus definition
+ */
+/* Type 0 */
+#define PCI_CFG_TYPE0_REG_SHF 0
+#define PCI_CFG_TYPE0_FUNC_SHF 8
+
+/* Type 1 */
+#define PCI_CFG_TYPE1_REG_SHF 0
+#define PCI_CFG_TYPE1_FUNC_SHF 8
+#define PCI_CFG_TYPE1_DEV_SHF 11
+#define PCI_CFG_TYPE1_BUS_SHF 16
+
+/*
+ * Ethernet device DP83816 definition
+ */
+#define DP83816_IRQ_ETHER 66
+
+#endif
diff --git a/include/asm-mips/mach-pnx8550/uart.h b/include/asm-mips/mach-pnx8550/uart.h
new file mode 100644
index 000000000000..e32b9a23d70e
--- /dev/null
+++ b/include/asm-mips/mach-pnx8550/uart.h
@@ -0,0 +1,16 @@
+#ifndef __IP3106_UART_H
+#define __IP3106_UART_H
+
+#include <int.h>
+
+/* early macros for kgdb use. fixme: clean this up */
+
+#define UART_BASE 0xbbe4a000 /* PNX8550 */
+
+#define PNX8550_UART_PORT0 (UART_BASE)
+#define PNX8550_UART_PORT1 (UART_BASE + 0x1000)
+
+#define PNX8550_UART_INT(x) (PNX8550_INT_GIC_MIN+19+x)
+#define IRQ_TO_UART(x) (x-PNX8550_INT_GIC_MIN-19)
+
+#endif
diff --git a/include/asm-mips/mach-pnx8550/usb.h b/include/asm-mips/mach-pnx8550/usb.h
new file mode 100644
index 000000000000..483b7fc65d41
--- /dev/null
+++ b/include/asm-mips/mach-pnx8550/usb.h
@@ -0,0 +1,32 @@
+/*
+ *
+ * BRIEF MODULE DESCRIPTION
+ * USB specific definitions
+ *
+ * Author: source@mvista.com
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ */
+
+#ifndef __PNX8550_USB_H
+#define __PNX8550_USB_H
+
+/*
+ * USB Host controller
+ */
+
+#define PNX8550_USB_OHCI_OP_BASE 0x1be48000
+#define PNX8550_USB_OHCI_OP_LEN 0x1000
+
+#endif
diff --git a/include/asm-mips/mach-rm200/cpu-feature-overrides.h b/include/asm-mips/mach-rm200/cpu-feature-overrides.h
index f48736032b2a..79f9b064c864 100644
--- a/include/asm-mips/mach-rm200/cpu-feature-overrides.h
+++ b/include/asm-mips/mach-rm200/cpu-feature-overrides.h
@@ -14,7 +14,7 @@
#define cpu_has_tlb 1
#define cpu_has_4kex 1
-#define cpu_has_4ktlb 1
+#define cpu_has_4kcache 1
#define cpu_has_fpu 1
#define cpu_has_32fpr 1
#define cpu_has_counter 1
@@ -31,6 +31,7 @@
#define cpu_has_vtag_icache 0
#define cpu_has_dc_aliases (PAGE_SIZE < 0x4000)
#define cpu_has_ic_fills_f_dc 0
+#define cpu_has_dsp 0
#define cpu_has_nofpuex 0
#define cpu_has_64bits 1
diff --git a/include/asm-mips/mach-sibyte/cpu-feature-overrides.h b/include/asm-mips/mach-sibyte/cpu-feature-overrides.h
index a3a2cc6014b2..193a666cd131 100644
--- a/include/asm-mips/mach-sibyte/cpu-feature-overrides.h
+++ b/include/asm-mips/mach-sibyte/cpu-feature-overrides.h
@@ -25,6 +25,7 @@
#define cpu_has_vtag_icache 1
#define cpu_has_dc_aliases 0
#define cpu_has_ic_fills_f_dc 0
+#define cpu_has_dsp 0
#define cpu_icache_snoops_remote_store 0
#define cpu_has_nofpuex 0
diff --git a/include/asm-mips/mach-sim/cpu-feature-overrides.h b/include/asm-mips/mach-sim/cpu-feature-overrides.h
new file mode 100644
index 000000000000..cadbe8eda79c
--- /dev/null
+++ b/include/asm-mips/mach-sim/cpu-feature-overrides.h
@@ -0,0 +1,66 @@
+/*
+ * 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) 2003, 2004 Chris Dearman
+ */
+#ifndef __ASM_MACH_SIM_CPU_FEATURE_OVERRIDES_H
+#define __ASM_MACH_SIM_CPU_FEATURE_OVERRIDES_H
+
+#include <linux/config.h>
+
+/*
+ * CPU feature overrides for MIPS boards
+ */
+#ifdef CONFIG_CPU_MIPS32
+#define cpu_has_tlb 1
+#define cpu_has_4kex 1
+#define cpu_has_4kcache 1
+#define cpu_has_fpu 0
+/* #define cpu_has_32fpr ? */
+#define cpu_has_counter 1
+/* #define cpu_has_watch ? */
+#define cpu_has_divec 1
+#define cpu_has_vce 0
+/* #define cpu_has_cache_cdex_p ? */
+/* #define cpu_has_cache_cdex_s ? */
+/* #define cpu_has_prefetch ? */
+#define cpu_has_mcheck 1
+/* #define cpu_has_ejtag ? */
+#define cpu_has_llsc 1
+/* #define cpu_has_vtag_icache ? */
+/* #define cpu_has_dc_aliases ? */
+/* #define cpu_has_ic_fills_f_dc ? */
+#define cpu_has_nofpuex 0
+/* #define cpu_has_64bits ? */
+/* #define cpu_has_64bit_zero_reg ? */
+/* #define cpu_has_subset_pcaches ? */
+#endif
+
+#ifdef CONFIG_CPU_MIPS64
+#define cpu_has_tlb 1
+#define cpu_has_4kex 1
+#define cpu_has_4kcache 1
+/* #define cpu_has_fpu ? */
+/* #define cpu_has_32fpr ? */
+#define cpu_has_counter 1
+/* #define cpu_has_watch ? */
+#define cpu_has_divec 1
+#define cpu_has_vce 0
+/* #define cpu_has_cache_cdex_p ? */
+/* #define cpu_has_cache_cdex_s ? */
+/* #define cpu_has_prefetch ? */
+#define cpu_has_mcheck 1
+/* #define cpu_has_ejtag ? */
+#define cpu_has_llsc 1
+/* #define cpu_has_vtag_icache ? */
+/* #define cpu_has_dc_aliases ? */
+/* #define cpu_has_ic_fills_f_dc ? */
+#define cpu_has_nofpuex 0
+/* #define cpu_has_64bits ? */
+/* #define cpu_has_64bit_zero_reg ? */
+/* #define cpu_has_subset_pcaches ? */
+#endif
+
+#endif /* __ASM_MACH_MIPS_CPU_FEATURE_OVERRIDES_H */
diff --git a/include/asm-mips/mach-yosemite/cpu-feature-overrides.h b/include/asm-mips/mach-yosemite/cpu-feature-overrides.h
index 58603e3daca6..463d051f4683 100644
--- a/include/asm-mips/mach-yosemite/cpu-feature-overrides.h
+++ b/include/asm-mips/mach-yosemite/cpu-feature-overrides.h
@@ -25,6 +25,7 @@
#define cpu_has_vtag_icache 0
#define cpu_has_dc_aliases 0
#define cpu_has_ic_fills_f_dc 0
+#define cpu_has_dsp 0
#define cpu_icache_snoops_remote_store 0
#define cpu_has_nofpuex 0
@@ -36,10 +37,4 @@
#define cpu_icache_line_size() 32
#define cpu_scache_line_size() 32
-/*
- * On the RM9000 we need to ensure that I-cache lines being fetches only
- * contain valid instructions are funny things will happen.
- */
-#define PLAT_TRAMPOLINE_STUFF_LINE 32UL
-
#endif /* __ASM_MACH_YOSEMITE_CPU_FEATURE_OVERRIDES_H */
diff --git a/include/asm-mips/mc146818-time.h b/include/asm-mips/mc146818-time.h
index a2c2d2c24303..47214861093b 100644
--- a/include/asm-mips/mc146818-time.h
+++ b/include/asm-mips/mc146818-time.h
@@ -33,7 +33,9 @@ static inline int mc146818_set_rtc_mmss(unsigned long nowtime)
int real_seconds, real_minutes, cmos_minutes;
unsigned char save_control, save_freq_select;
int retval = 0;
+ unsigned long flags;
+ spin_lock_irqsave(&rtc_lock, flags);
save_control = CMOS_READ(RTC_CONTROL); /* tell the clock it's being set */
CMOS_WRITE((save_control|RTC_SET), RTC_CONTROL);
@@ -79,14 +81,30 @@ static inline int mc146818_set_rtc_mmss(unsigned long nowtime)
*/
CMOS_WRITE(save_control, RTC_CONTROL);
CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT);
+ spin_unlock_irqrestore(&rtc_lock, flags);
return retval;
}
+/*
+ * Returns true if a clock update is in progress
+ */
+static inline unsigned char rtc_is_updating(void)
+{
+ unsigned char uip;
+ unsigned long flags;
+
+ spin_lock_irqsave(&rtc_lock, flags);
+ uip = (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP);
+ spin_unlock_irqrestore(&rtc_lock, flags);
+ return uip;
+}
+
static inline unsigned long mc146818_get_cmos_time(void)
{
unsigned int year, mon, day, hour, min, sec;
int i;
+ unsigned long flags;
/*
* The Linux interpretation of the CMOS clock register contents:
@@ -97,12 +115,13 @@ static inline unsigned long mc146818_get_cmos_time(void)
/* read RTC exactly on falling edge of update flag */
for (i = 0 ; i < 1000000 ; i++) /* may take up to 1 second... */
- if (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP)
+ if (rtc_is_updating())
break;
for (i = 0 ; i < 1000000 ; i++) /* must try at least 2.228 ms */
- if (!(CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP))
+ if (!rtc_is_updating())
break;
+ spin_lock_irqsave(&rtc_lock, flags);
do { /* Isn't this overkill ? UIP above should guarantee consistency */
sec = CMOS_READ(RTC_SECONDS);
min = CMOS_READ(RTC_MINUTES);
@@ -120,6 +139,7 @@ static inline unsigned long mc146818_get_cmos_time(void)
BCD_TO_BIN(mon);
BCD_TO_BIN(year);
}
+ spin_unlock_irqrestore(&rtc_lock, flags);
year = mc146818_decode_year(year);
return mktime(year, mon, day, hour, min, sec);
diff --git a/include/asm-mips/mips-boards/generic.h b/include/asm-mips/mips-boards/generic.h
index 65d1d16eab16..25b6ffc26623 100644
--- a/include/asm-mips/mips-boards/generic.h
+++ b/include/asm-mips/mips-boards/generic.h
@@ -66,6 +66,7 @@
#define MIPS_REVISION_CORID_CORE_EMUL 6
#define MIPS_REVISION_CORID_CORE_FPGA2 7
#define MIPS_REVISION_CORID_CORE_FPGAR2 8
+#define MIPS_REVISION_CORID_CORE_FPGA3 9
/**** Artificial corid defines ****/
/*
@@ -79,4 +80,10 @@
extern unsigned int mips_revision_corid;
+#ifdef CONFIG_PCI
+extern void mips_pcibios_init(void);
+#else
+#define mips_pcibios_init() do { } while (0)
+#endif
+
#endif /* __ASM_MIPS_BOARDS_GENERIC_H */
diff --git a/include/asm-mips/mips-boards/maltaint.h b/include/asm-mips/mips-boards/maltaint.h
index 376181882e81..da6cc2fbbc78 100644
--- a/include/asm-mips/mips-boards/maltaint.h
+++ b/include/asm-mips/mips-boards/maltaint.h
@@ -25,9 +25,63 @@
#ifndef _MIPS_MALTAINT_H
#define _MIPS_MALTAINT_H
-/* Number of IRQ supported on hw interrupt 0. */
-#define MALTAINT_END 16
+/*
+ * Interrupts 0..15 are used for Malta ISA compatible interrupts
+ */
+#define MALTA_INT_BASE 0
+
+/*
+ * Interrupts 16..23 are used for Malta CPU interrupts (nonEIC mode)
+ */
+#define MIPSCPU_INT_BASE 16
+
+/* CPU interrupt offsets */
+#define MIPSCPU_INT_SW0 0
+#define MIPSCPU_INT_SW1 1
+#define MIPSCPU_INT_MB0 2
+#define MIPSCPU_INT_I8259A MIPSCPU_INT_MB0
+#define MIPSCPU_INT_MB1 3
+#define MIPSCPU_INT_SMI MIPSCPU_INT_MB1
+#define MIPSCPU_INT_MB2 4
+#define MIPSCPU_INT_MB3 5
+#define MIPSCPU_INT_COREHI MIPSCPU_INT_MB3
+#define MIPSCPU_INT_MB4 6
+#define MIPSCPU_INT_CORELO MIPSCPU_INT_MB4
+#define MIPSCPU_INT_CPUCTR 7
+
+/*
+ * Interrupts 64..127 are used for Soc-it Classic interrupts
+ */
+#define MSC01C_INT_BASE 64
+
+/* SOC-it Classic interrupt offsets */
+#define MSC01C_INT_TMR 0
+#define MSC01C_INT_PCI 1
+
+/*
+ * Interrupts 64..127 are used for Soc-it EIC interrupts
+ */
+#define MSC01E_INT_BASE 64
+
+/* SOC-it EIC interrupt offsets */
+#define MSC01E_INT_SW0 1
+#define MSC01E_INT_SW1 2
+#define MSC01E_INT_MB0 3
+#define MSC01E_INT_I8259A MSC01E_INT_MB0
+#define MSC01E_INT_MB1 4
+#define MSC01E_INT_SMI MSC01E_INT_MB1
+#define MSC01E_INT_MB2 5
+#define MSC01E_INT_MB3 6
+#define MSC01E_INT_COREHI MSC01E_INT_MB3
+#define MSC01E_INT_MB4 7
+#define MSC01E_INT_CORELO MSC01E_INT_MB4
+#define MSC01E_INT_TMR 8
+#define MSC01E_INT_PCI 9
+#define MSC01E_INT_PERFCTR 10
+#define MSC01E_INT_CPUCTR 11
+#ifndef __ASSEMBLY__
extern void maltaint_init(void);
+#endif
#endif /* !(_MIPS_MALTAINT_H) */
diff --git a/include/asm-mips/mips-boards/msc01_pci.h b/include/asm-mips/mips-boards/msc01_pci.h
index 6b2a87a38f4b..8eaefb837b9d 100644
--- a/include/asm-mips/mips-boards/msc01_pci.h
+++ b/include/asm-mips/mips-boards/msc01_pci.h
@@ -1,8 +1,9 @@
/*
* PCI Register definitions for the MIPS System Controller.
*
- * Carsten Langgaard, carstenl@mips.com
- * Copyright (C) 2002 MIPS Technologies, Inc. All rights reserved.
+ * Copyright (C) 2002, 2005 MIPS Technologies, Inc. All rights reserved.
+ * Authors: Carsten Langgaard <carstenl@mips.com>
+ * Maciej W. Rozycki <macro@mips.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
@@ -29,22 +30,22 @@
#define MSC01_PCI_CFGADDR_OFS 0x0610
#define MSC01_PCI_CFGDATA_OFS 0x0618
#define MSC01_PCI_IACK_OFS 0x0620
-#define MSC01_PCI_HEAD0_OFS 0x2000 /* DevID, VendorID */
-#define MSC01_PCI_HEAD1_OFS 0x2008 /* Status, Command */
-#define MSC01_PCI_HEAD2_OFS 0x2010 /* Class code, RevID */
-#define MSC01_PCI_HEAD3_OFS 0x2018 /* bist, header, latency */
-#define MSC01_PCI_HEAD4_OFS 0x2020 /* BAR 0 */
-#define MSC01_PCI_HEAD5_OFS 0x2028 /* BAR 1 */
-#define MSC01_PCI_HEAD6_OFS 0x2030 /* BAR 2 */
-#define MSC01_PCI_HEAD7_OFS 0x2038 /* BAR 3 */
-#define MSC01_PCI_HEAD8_OFS 0x2040 /* BAR 4 */
-#define MSC01_PCI_HEAD9_OFS 0x2048 /* BAR 5 */
-#define MSC01_PCI_HEAD10_OFS 0x2050 /* CardBus CIS Ptr */
-#define MSC01_PCI_HEAD11_OFS 0x2058 /* SubSystem ID, -VendorID */
-#define MSC01_PCI_HEAD12_OFS 0x2060 /* ROM BAR */
-#define MSC01_PCI_HEAD13_OFS 0x2068 /* Capabilities ptr */
-#define MSC01_PCI_HEAD14_OFS 0x2070 /* reserved */
-#define MSC01_PCI_HEAD15_OFS 0x2078 /* Maxl, ming, intpin, int */
+#define MSC01_PCI_HEAD0_OFS 0x2000 /* DevID, VendorID */
+#define MSC01_PCI_HEAD1_OFS 0x2008 /* Status, Command */
+#define MSC01_PCI_HEAD2_OFS 0x2010 /* Class code, RevID */
+#define MSC01_PCI_HEAD3_OFS 0x2018 /* bist, header, latency */
+#define MSC01_PCI_HEAD4_OFS 0x2020 /* BAR 0 */
+#define MSC01_PCI_HEAD5_OFS 0x2028 /* BAR 1 */
+#define MSC01_PCI_HEAD6_OFS 0x2030 /* BAR 2 */
+#define MSC01_PCI_HEAD7_OFS 0x2038 /* BAR 3 */
+#define MSC01_PCI_HEAD8_OFS 0x2040 /* BAR 4 */
+#define MSC01_PCI_HEAD9_OFS 0x2048 /* BAR 5 */
+#define MSC01_PCI_HEAD10_OFS 0x2050 /* CardBus CIS Ptr */
+#define MSC01_PCI_HEAD11_OFS 0x2058 /* SubSystem ID, -VendorID */
+#define MSC01_PCI_HEAD12_OFS 0x2060 /* ROM BAR */
+#define MSC01_PCI_HEAD13_OFS 0x2068 /* Capabilities ptr */
+#define MSC01_PCI_HEAD14_OFS 0x2070 /* reserved */
+#define MSC01_PCI_HEAD15_OFS 0x2078 /* Maxl, ming, intpin, int */
#define MSC01_PCI_BAR0_OFS 0x2220
#define MSC01_PCI_CFG_OFS 0x2380
#define MSC01_PCI_SWAP_OFS 0x2388
@@ -86,73 +87,73 @@
#define MSC01_PCI_P2SCMAPL_MAP_SHF 24
#define MSC01_PCI_P2SCMAPL_MAP_MSK 0xff000000
-#define MSC01_PCI_INTCFG_RST_SHF 10
-#define MSC01_PCI_INTCFG_RST_MSK 0x00000400
-#define MSC01_PCI_INTCFG_RST_BIT 0x00000400
-#define MSC01_PCI_INTCFG_MWE_SHF 9
-#define MSC01_PCI_INTCFG_MWE_MSK 0x00000200
-#define MSC01_PCI_INTCFG_MWE_BIT 0x00000200
-#define MSC01_PCI_INTCFG_DTO_SHF 8
-#define MSC01_PCI_INTCFG_DTO_MSK 0x00000100
-#define MSC01_PCI_INTCFG_DTO_BIT 0x00000100
-#define MSC01_PCI_INTCFG_MA_SHF 7
-#define MSC01_PCI_INTCFG_MA_MSK 0x00000080
-#define MSC01_PCI_INTCFG_MA_BIT 0x00000080
-#define MSC01_PCI_INTCFG_TA_SHF 6
-#define MSC01_PCI_INTCFG_TA_MSK 0x00000040
-#define MSC01_PCI_INTCFG_TA_BIT 0x00000040
-#define MSC01_PCI_INTCFG_RTY_SHF 5
-#define MSC01_PCI_INTCFG_RTY_MSK 0x00000020
-#define MSC01_PCI_INTCFG_RTY_BIT 0x00000020
-#define MSC01_PCI_INTCFG_MWP_SHF 4
-#define MSC01_PCI_INTCFG_MWP_MSK 0x00000010
-#define MSC01_PCI_INTCFG_MWP_BIT 0x00000010
-#define MSC01_PCI_INTCFG_MRP_SHF 3
-#define MSC01_PCI_INTCFG_MRP_MSK 0x00000008
-#define MSC01_PCI_INTCFG_MRP_BIT 0x00000008
-#define MSC01_PCI_INTCFG_SWP_SHF 2
-#define MSC01_PCI_INTCFG_SWP_MSK 0x00000004
-#define MSC01_PCI_INTCFG_SWP_BIT 0x00000004
-#define MSC01_PCI_INTCFG_SRP_SHF 1
-#define MSC01_PCI_INTCFG_SRP_MSK 0x00000002
-#define MSC01_PCI_INTCFG_SRP_BIT 0x00000002
-#define MSC01_PCI_INTCFG_SE_SHF 0
-#define MSC01_PCI_INTCFG_SE_MSK 0x00000001
-#define MSC01_PCI_INTCFG_SE_BIT 0x00000001
+#define MSC01_PCI_INTCFG_RST_SHF 10
+#define MSC01_PCI_INTCFG_RST_MSK 0x00000400
+#define MSC01_PCI_INTCFG_RST_BIT 0x00000400
+#define MSC01_PCI_INTCFG_MWE_SHF 9
+#define MSC01_PCI_INTCFG_MWE_MSK 0x00000200
+#define MSC01_PCI_INTCFG_MWE_BIT 0x00000200
+#define MSC01_PCI_INTCFG_DTO_SHF 8
+#define MSC01_PCI_INTCFG_DTO_MSK 0x00000100
+#define MSC01_PCI_INTCFG_DTO_BIT 0x00000100
+#define MSC01_PCI_INTCFG_MA_SHF 7
+#define MSC01_PCI_INTCFG_MA_MSK 0x00000080
+#define MSC01_PCI_INTCFG_MA_BIT 0x00000080
+#define MSC01_PCI_INTCFG_TA_SHF 6
+#define MSC01_PCI_INTCFG_TA_MSK 0x00000040
+#define MSC01_PCI_INTCFG_TA_BIT 0x00000040
+#define MSC01_PCI_INTCFG_RTY_SHF 5
+#define MSC01_PCI_INTCFG_RTY_MSK 0x00000020
+#define MSC01_PCI_INTCFG_RTY_BIT 0x00000020
+#define MSC01_PCI_INTCFG_MWP_SHF 4
+#define MSC01_PCI_INTCFG_MWP_MSK 0x00000010
+#define MSC01_PCI_INTCFG_MWP_BIT 0x00000010
+#define MSC01_PCI_INTCFG_MRP_SHF 3
+#define MSC01_PCI_INTCFG_MRP_MSK 0x00000008
+#define MSC01_PCI_INTCFG_MRP_BIT 0x00000008
+#define MSC01_PCI_INTCFG_SWP_SHF 2
+#define MSC01_PCI_INTCFG_SWP_MSK 0x00000004
+#define MSC01_PCI_INTCFG_SWP_BIT 0x00000004
+#define MSC01_PCI_INTCFG_SRP_SHF 1
+#define MSC01_PCI_INTCFG_SRP_MSK 0x00000002
+#define MSC01_PCI_INTCFG_SRP_BIT 0x00000002
+#define MSC01_PCI_INTCFG_SE_SHF 0
+#define MSC01_PCI_INTCFG_SE_MSK 0x00000001
+#define MSC01_PCI_INTCFG_SE_BIT 0x00000001
-#define MSC01_PCI_INTSTAT_RST_SHF 10
-#define MSC01_PCI_INTSTAT_RST_MSK 0x00000400
-#define MSC01_PCI_INTSTAT_RST_BIT 0x00000400
-#define MSC01_PCI_INTSTAT_MWE_SHF 9
-#define MSC01_PCI_INTSTAT_MWE_MSK 0x00000200
-#define MSC01_PCI_INTSTAT_MWE_BIT 0x00000200
-#define MSC01_PCI_INTSTAT_DTO_SHF 8
-#define MSC01_PCI_INTSTAT_DTO_MSK 0x00000100
-#define MSC01_PCI_INTSTAT_DTO_BIT 0x00000100
-#define MSC01_PCI_INTSTAT_MA_SHF 7
-#define MSC01_PCI_INTSTAT_MA_MSK 0x00000080
-#define MSC01_PCI_INTSTAT_MA_BIT 0x00000080
-#define MSC01_PCI_INTSTAT_TA_SHF 6
-#define MSC01_PCI_INTSTAT_TA_MSK 0x00000040
-#define MSC01_PCI_INTSTAT_TA_BIT 0x00000040
-#define MSC01_PCI_INTSTAT_RTY_SHF 5
-#define MSC01_PCI_INTSTAT_RTY_MSK 0x00000020
-#define MSC01_PCI_INTSTAT_RTY_BIT 0x00000020
-#define MSC01_PCI_INTSTAT_MWP_SHF 4
-#define MSC01_PCI_INTSTAT_MWP_MSK 0x00000010
-#define MSC01_PCI_INTSTAT_MWP_BIT 0x00000010
-#define MSC01_PCI_INTSTAT_MRP_SHF 3
-#define MSC01_PCI_INTSTAT_MRP_MSK 0x00000008
-#define MSC01_PCI_INTSTAT_MRP_BIT 0x00000008
-#define MSC01_PCI_INTSTAT_SWP_SHF 2
-#define MSC01_PCI_INTSTAT_SWP_MSK 0x00000004
-#define MSC01_PCI_INTSTAT_SWP_BIT 0x00000004
-#define MSC01_PCI_INTSTAT_SRP_SHF 1
-#define MSC01_PCI_INTSTAT_SRP_MSK 0x00000002
-#define MSC01_PCI_INTSTAT_SRP_BIT 0x00000002
-#define MSC01_PCI_INTSTAT_SE_SHF 0
-#define MSC01_PCI_INTSTAT_SE_MSK 0x00000001
-#define MSC01_PCI_INTSTAT_SE_BIT 0x00000001
+#define MSC01_PCI_INTSTAT_RST_SHF 10
+#define MSC01_PCI_INTSTAT_RST_MSK 0x00000400
+#define MSC01_PCI_INTSTAT_RST_BIT 0x00000400
+#define MSC01_PCI_INTSTAT_MWE_SHF 9
+#define MSC01_PCI_INTSTAT_MWE_MSK 0x00000200
+#define MSC01_PCI_INTSTAT_MWE_BIT 0x00000200
+#define MSC01_PCI_INTSTAT_DTO_SHF 8
+#define MSC01_PCI_INTSTAT_DTO_MSK 0x00000100
+#define MSC01_PCI_INTSTAT_DTO_BIT 0x00000100
+#define MSC01_PCI_INTSTAT_MA_SHF 7
+#define MSC01_PCI_INTSTAT_MA_MSK 0x00000080
+#define MSC01_PCI_INTSTAT_MA_BIT 0x00000080
+#define MSC01_PCI_INTSTAT_TA_SHF 6
+#define MSC01_PCI_INTSTAT_TA_MSK 0x00000040
+#define MSC01_PCI_INTSTAT_TA_BIT 0x00000040
+#define MSC01_PCI_INTSTAT_RTY_SHF 5
+#define MSC01_PCI_INTSTAT_RTY_MSK 0x00000020
+#define MSC01_PCI_INTSTAT_RTY_BIT 0x00000020
+#define MSC01_PCI_INTSTAT_MWP_SHF 4
+#define MSC01_PCI_INTSTAT_MWP_MSK 0x00000010
+#define MSC01_PCI_INTSTAT_MWP_BIT 0x00000010
+#define MSC01_PCI_INTSTAT_MRP_SHF 3
+#define MSC01_PCI_INTSTAT_MRP_MSK 0x00000008
+#define MSC01_PCI_INTSTAT_MRP_BIT 0x00000008
+#define MSC01_PCI_INTSTAT_SWP_SHF 2
+#define MSC01_PCI_INTSTAT_SWP_MSK 0x00000004
+#define MSC01_PCI_INTSTAT_SWP_BIT 0x00000004
+#define MSC01_PCI_INTSTAT_SRP_SHF 1
+#define MSC01_PCI_INTSTAT_SRP_MSK 0x00000002
+#define MSC01_PCI_INTSTAT_SRP_BIT 0x00000002
+#define MSC01_PCI_INTSTAT_SE_SHF 0
+#define MSC01_PCI_INTSTAT_SE_MSK 0x00000001
+#define MSC01_PCI_INTSTAT_SE_BIT 0x00000001
#define MSC01_PCI_CFGADDR_BNUM_SHF 16
#define MSC01_PCI_CFGADDR_BNUM_MSK 0x00ff0000
@@ -167,29 +168,29 @@
#define MSC01_PCI_CFGDATA_DATA_MSK 0xffffffff
/* The defines below are ONLY valid for a MEM bar! */
-#define MSC01_PCI_BAR0_SIZE_SHF 4
-#define MSC01_PCI_BAR0_SIZE_MSK 0xfffffff0
-#define MSC01_PCI_BAR0_P_SHF 3
-#define MSC01_PCI_BAR0_P_MSK 0x00000008
-#define MSC01_PCI_BAR0_P_BIT MSC01_PCI_BAR0_P_MSK
-#define MSC01_PCI_BAR0_D_SHF 1
-#define MSC01_PCI_BAR0_D_MSK 0x00000006
-#define MSC01_PCI_BAR0_T_SHF 0
-#define MSC01_PCI_BAR0_T_MSK 0x00000001
-#define MSC01_PCI_BAR0_T_BIT MSC01_PCI_BAR0_T_MSK
+#define MSC01_PCI_BAR0_SIZE_SHF 4
+#define MSC01_PCI_BAR0_SIZE_MSK 0xfffffff0
+#define MSC01_PCI_BAR0_P_SHF 3
+#define MSC01_PCI_BAR0_P_MSK 0x00000008
+#define MSC01_PCI_BAR0_P_BIT MSC01_PCI_BAR0_P_MSK
+#define MSC01_PCI_BAR0_D_SHF 1
+#define MSC01_PCI_BAR0_D_MSK 0x00000006
+#define MSC01_PCI_BAR0_T_SHF 0
+#define MSC01_PCI_BAR0_T_MSK 0x00000001
+#define MSC01_PCI_BAR0_T_BIT MSC01_PCI_BAR0_T_MSK
-#define MSC01_PCI_CFG_RA_SHF 17
-#define MSC01_PCI_CFG_RA_MSK 0x00020000
-#define MSC01_PCI_CFG_RA_BIT MSC01_PCI_CFG_RA_MSK
-#define MSC01_PCI_CFG_G_SHF 16
-#define MSC01_PCI_CFG_G_MSK 0x00010000
-#define MSC01_PCI_CFG_G_BIT MSC01_PCI_CFG_G_MSK
-#define MSC01_PCI_CFG_EN_SHF 15
-#define MSC01_PCI_CFG_EN_MSK 0x00008000
-#define MSC01_PCI_CFG_EN_BIT MSC01_PCI_CFG_EN_MSK
-#define MSC01_PCI_CFG_MAXRTRY_SHF 0
-#define MSC01_PCI_CFG_MAXRTRY_MSK 0x000000ff
+#define MSC01_PCI_CFG_RA_SHF 17
+#define MSC01_PCI_CFG_RA_MSK 0x00020000
+#define MSC01_PCI_CFG_RA_BIT MSC01_PCI_CFG_RA_MSK
+#define MSC01_PCI_CFG_G_SHF 16
+#define MSC01_PCI_CFG_G_MSK 0x00010000
+#define MSC01_PCI_CFG_G_BIT MSC01_PCI_CFG_G_MSK
+#define MSC01_PCI_CFG_EN_SHF 15
+#define MSC01_PCI_CFG_EN_MSK 0x00008000
+#define MSC01_PCI_CFG_EN_BIT MSC01_PCI_CFG_EN_MSK
+#define MSC01_PCI_CFG_MAXRTRY_SHF 0
+#define MSC01_PCI_CFG_MAXRTRY_MSK 0x00000fff
#define MSC01_PCI_SWAP_IO_SHF 18
#define MSC01_PCI_SWAP_IO_MSK 0x000c0000
@@ -206,7 +207,7 @@
* FIXME - are these macros specific to Malta and co or to the MSC? If the
* latter, they should be moved elsewhere.
*/
-#define MIPS_MSC01_PCI_REG_BASE 0x1bd00000
+#define MIPS_MSC01_PCI_REG_BASE 0x1bd00000
extern unsigned long _pcictrl_msc;
@@ -219,19 +220,19 @@ extern unsigned long _pcictrl_msc;
* Registers absolute addresses
*/
-#define MSC01_PCI_ID (MSC01_PCI_REG_BASE + MSC01_PCI_ID_OFS)
-#define MSC01_PCI_SC2PMBASL (MSC01_PCI_REG_BASE + MSC01_PCI_SC2PMBASL_OFS)
-#define MSC01_PCI_SC2PMMSKL (MSC01_PCI_REG_BASE + MSC01_PCI_SC2PMMSKL_OFS)
-#define MSC01_PCI_SC2PMMAPL (MSC01_PCI_REG_BASE + MSC01_PCI_SC2PMMAPL_OFS)
-#define MSC01_PCI_SC2PIOBASL (MSC01_PCI_REG_BASE + MSC01_PCI_SC2PIOBASL_OFS)
-#define MSC01_PCI_SC2PIOMSKL (MSC01_PCI_REG_BASE + MSC01_PCI_SC2PIOMSKL_OFS)
-#define MSC01_PCI_SC2PIOMAPL (MSC01_PCI_REG_BASE + MSC01_PCI_SC2PIOMAPL_OFS)
-#define MSC01_PCI_P2SCMSKL (MSC01_PCI_REG_BASE + MSC01_PCI_P2SCMSKL_OFS)
-#define MSC01_PCI_P2SCMAPL (MSC01_PCI_REG_BASE + MSC01_PCI_P2SCMAPL_OFS)
-#define MSC01_PCI_INTCFG (MSC01_PCI_REG_BASE + MSC01_PCI_INTCFG_OFS)
-#define MSC01_PCI_INTSTAT (MSC01_PCI_REG_BASE + MSC01_PCI_INTSTAT_OFS)
-#define MSC01_PCI_CFGADDR (MSC01_PCI_REG_BASE + MSC01_PCI_CFGADDR_OFS)
-#define MSC01_PCI_CFGDATA (MSC01_PCI_REG_BASE + MSC01_PCI_CFGDATA_OFS)
+#define MSC01_PCI_ID (MSC01_PCI_REG_BASE + MSC01_PCI_ID_OFS)
+#define MSC01_PCI_SC2PMBASL (MSC01_PCI_REG_BASE + MSC01_PCI_SC2PMBASL_OFS)
+#define MSC01_PCI_SC2PMMSKL (MSC01_PCI_REG_BASE + MSC01_PCI_SC2PMMSKL_OFS)
+#define MSC01_PCI_SC2PMMAPL (MSC01_PCI_REG_BASE + MSC01_PCI_SC2PMMAPL_OFS)
+#define MSC01_PCI_SC2PIOBASL (MSC01_PCI_REG_BASE + MSC01_PCI_SC2PIOBASL_OFS)
+#define MSC01_PCI_SC2PIOMSKL (MSC01_PCI_REG_BASE + MSC01_PCI_SC2PIOMSKL_OFS)
+#define MSC01_PCI_SC2PIOMAPL (MSC01_PCI_REG_BASE + MSC01_PCI_SC2PIOMAPL_OFS)
+#define MSC01_PCI_P2SCMSKL (MSC01_PCI_REG_BASE + MSC01_PCI_P2SCMSKL_OFS)
+#define MSC01_PCI_P2SCMAPL (MSC01_PCI_REG_BASE + MSC01_PCI_P2SCMAPL_OFS)
+#define MSC01_PCI_INTCFG (MSC01_PCI_REG_BASE + MSC01_PCI_INTCFG_OFS)
+#define MSC01_PCI_INTSTAT (MSC01_PCI_REG_BASE + MSC01_PCI_INTSTAT_OFS)
+#define MSC01_PCI_CFGADDR (MSC01_PCI_REG_BASE + MSC01_PCI_CFGADDR_OFS)
+#define MSC01_PCI_CFGDATA (MSC01_PCI_REG_BASE + MSC01_PCI_CFGDATA_OFS)
#define MSC01_PCI_IACK (MSC01_PCI_REG_BASE + MSC01_PCI_IACK_OFS)
#define MSC01_PCI_HEAD0 (MSC01_PCI_REG_BASE + MSC01_PCI_HEAD0_OFS)
#define MSC01_PCI_HEAD1 (MSC01_PCI_REG_BASE + MSC01_PCI_HEAD1_OFS)
@@ -248,7 +249,7 @@ extern unsigned long _pcictrl_msc;
#define MSC01_PCI_HEAD12 (MSC01_PCI_REG_BASE + MSC01_PCI_HEAD11_OFS)
#define MSC01_PCI_HEAD13 (MSC01_PCI_REG_BASE + MSC01_PCI_HEAD11_OFS)
#define MSC01_PCI_HEAD14 (MSC01_PCI_REG_BASE + MSC01_PCI_HEAD11_OFS)
-#define MSC01_PCI_HEAD15 (MSC01_PCI_REG_BASE + MSC01_PCI_HEAD11_OFS)
+#define MSC01_PCI_HEAD15 (MSC01_PCI_REG_BASE + MSC01_PCI_HEAD11_OFS)
#define MSC01_PCI_BAR0 (MSC01_PCI_REG_BASE + MSC01_PCI_BAR0_OFS)
#define MSC01_PCI_CFG (MSC01_PCI_REG_BASE + MSC01_PCI_CFG_OFS)
#define MSC01_PCI_SWAP (MSC01_PCI_REG_BASE + MSC01_PCI_SWAP_OFS)
diff --git a/include/asm-mips/mips-boards/sim.h b/include/asm-mips/mips-boards/sim.h
new file mode 100644
index 000000000000..acb7c2331d98
--- /dev/null
+++ b/include/asm-mips/mips-boards/sim.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2005 MIPS Technologies, Inc. All rights reserved.
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ */
+
+#ifndef _ASM_MIPS_BOARDS_SIM_H
+#define _ASM_MIPS_BOARDS_SIM_H
+
+#define STATS_ON 1
+#define STATS_OFF 2
+#define STATS_CLEAR 3
+#define STATS_DUMP 4
+#define TRACE_ON 5
+#define TRACE_OFF 6
+
+
+#define simcfg(code) \
+({ \
+ __asm__ __volatile__( \
+ "sltiu $0,$0, %0" \
+ ::"i"(code) \
+ ); \
+})
+
+
+
+#endif
diff --git a/include/asm-mips/mips-boards/simint.h b/include/asm-mips/mips-boards/simint.h
new file mode 100644
index 000000000000..4952e0b3bf11
--- /dev/null
+++ b/include/asm-mips/mips-boards/simint.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2005 MIPS Technologies, Inc. All rights reserved.
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ */
+#ifndef _MIPS_SIMINT_H
+#define _MIPS_SIMINT_H
+
+
+#define SIM_INT_BASE 0
+#define MIPSCPU_INT_MB0 2
+#define MIPSCPU_INT_BASE 16
+#define MIPS_CPU_TIMER_IRQ 7
+
+
+#define MIPSCPU_INT_CPUCTR 7
+
+#define MSC01E_INT_BASE 64
+
+#define MIPSCPU_INT_CPUCTR 7
+#define MSC01E_INT_CPUCTR 11
+
+#endif
diff --git a/include/asm-mips/mipsmtregs.h b/include/asm-mips/mipsmtregs.h
new file mode 100644
index 000000000000..a669c0702c66
--- /dev/null
+++ b/include/asm-mips/mipsmtregs.h
@@ -0,0 +1,391 @@
+/*
+ * MT regs definitions, follows on from mipsregs.h
+ * Copyright (C) 2004 - 2005 MIPS Technologies, Inc. All rights reserved.
+ * Elizabeth Clarke et. al.
+ *
+ */
+#ifndef _ASM_MIPSMTREGS_H
+#define _ASM_MIPSMTREGS_H
+
+#include <asm/mipsregs.h>
+#include <asm/war.h>
+
+#ifndef __ASSEMBLY__
+
+/*
+ * C macros
+ */
+
+#define read_c0_mvpcontrol() __read_32bit_c0_register($0, 1)
+#define write_c0_mvpcontrol(val) __write_32bit_c0_register($0, 1, val)
+
+#define read_c0_mvpconf0() __read_32bit_c0_register($0, 2)
+#define read_c0_mvpconf1() __read_32bit_c0_register($0, 3)
+
+#define read_c0_vpecontrol() __read_32bit_c0_register($1, 1)
+#define write_c0_vpecontrol(val) __write_32bit_c0_register($1, 1, val)
+
+#define read_c0_vpeconf0() __read_32bit_c0_register($1, 2)
+#define write_c0_vpeconf0(val) __write_32bit_c0_register($1, 2, val)
+
+#define read_c0_tcstatus() __read_32bit_c0_register($2, 1)
+#define write_c0_tcstatus(val) __write_32bit_c0_register($2, 1, val)
+
+#define read_c0_tcbind() __read_32bit_c0_register($2, 2)
+
+#define read_c0_tccontext() __read_32bit_c0_register($2, 5)
+#define write_c0_tccontext(val) __write_32bit_c0_register($2, 5, val)
+
+#else /* Assembly */
+/*
+ * Macros for use in assembly language code
+ */
+
+#define CP0_MVPCONTROL $0,1
+#define CP0_MVPCONF0 $0,2
+#define CP0_MVPCONF1 $0,3
+#define CP0_VPECONTROL $1,1
+#define CP0_VPECONF0 $1,2
+#define CP0_VPECONF1 $1,3
+#define CP0_YQMASK $1,4
+#define CP0_VPESCHEDULE $1,5
+#define CP0_VPESCHEFBK $1,6
+#define CP0_TCSTATUS $2,1
+#define CP0_TCBIND $2,2
+#define CP0_TCRESTART $2,3
+#define CP0_TCHALT $2,4
+#define CP0_TCCONTEXT $2,5
+#define CP0_TCSCHEDULE $2,6
+#define CP0_TCSCHEFBK $2,7
+#define CP0_SRSCONF0 $6,1
+#define CP0_SRSCONF1 $6,2
+#define CP0_SRSCONF2 $6,3
+#define CP0_SRSCONF3 $6,4
+#define CP0_SRSCONF4 $6,5
+
+#endif
+
+/* MVPControl fields */
+#define MVPCONTROL_EVP (_ULCAST_(1))
+
+#define MVPCONTROL_VPC_SHIFT 1
+#define MVPCONTROL_VPC (_ULCAST_(1) << MVPCONTROL_VPC_SHIFT)
+
+#define MVPCONTROL_STLB_SHIFT 2
+#define MVPCONTROL_STLB (_ULCAST_(1) << MVPCONTROL_STLB_SHIFT)
+
+
+/* MVPConf0 fields */
+#define MVPCONF0_PTC_SHIFT 0
+#define MVPCONF0_PTC ( _ULCAST_(0xff))
+#define MVPCONF0_PVPE_SHIFT 10
+#define MVPCONF0_PVPE ( _ULCAST_(0xf) << MVPCONF0_PVPE_SHIFT)
+#define MVPCONF0_TCA_SHIFT 15
+#define MVPCONF0_TCA ( _ULCAST_(1) << MVPCONF0_TCA_SHIFT)
+#define MVPCONF0_PTLBE_SHIFT 16
+#define MVPCONF0_PTLBE (_ULCAST_(0x3ff) << MVPCONF0_PTLBE_SHIFT)
+#define MVPCONF0_TLBS_SHIFT 29
+#define MVPCONF0_TLBS (_ULCAST_(1) << MVPCONF0_TLBS_SHIFT)
+#define MVPCONF0_M_SHIFT 31
+#define MVPCONF0_M (_ULCAST_(0x1) << MVPCONF0_M_SHIFT)
+
+
+/* config3 fields */
+#define CONFIG3_MT_SHIFT 2
+#define CONFIG3_MT (_ULCAST_(1) << CONFIG3_MT_SHIFT)
+
+
+/* VPEControl fields (per VPE) */
+#define VPECONTROL_TARGTC (_ULCAST_(0xff))
+
+#define VPECONTROL_TE_SHIFT 15
+#define VPECONTROL_TE (_ULCAST_(1) << VPECONTROL_TE_SHIFT)
+#define VPECONTROL_EXCPT_SHIFT 16
+#define VPECONTROL_EXCPT (_ULCAST_(0x7) << VPECONTROL_EXCPT_SHIFT)
+
+/* Thread Exception Codes for EXCPT field */
+#define THREX_TU 0
+#define THREX_TO 1
+#define THREX_IYQ 2
+#define THREX_GSX 3
+#define THREX_YSCH 4
+#define THREX_GSSCH 5
+
+#define VPECONTROL_GSI_SHIFT 20
+#define VPECONTROL_GSI (_ULCAST_(1) << VPECONTROL_GSI_SHIFT)
+#define VPECONTROL_YSI_SHIFT 21
+#define VPECONTROL_YSI (_ULCAST_(1) << VPECONTROL_YSI_SHIFT)
+
+/* VPEConf0 fields (per VPE) */
+#define VPECONF0_VPA_SHIFT 0
+#define VPECONF0_VPA (_ULCAST_(1) << VPECONF0_VPA_SHIFT)
+#define VPECONF0_MVP_SHIFT 1
+#define VPECONF0_MVP (_ULCAST_(1) << VPECONF0_MVP_SHIFT)
+#define VPECONF0_XTC_SHIFT 21
+#define VPECONF0_XTC (_ULCAST_(0xff) << VPECONF0_XTC_SHIFT)
+
+/* TCStatus fields (per TC) */
+#define TCSTATUS_TASID (_ULCAST_(0xff))
+#define TCSTATUS_IXMT_SHIFT 10
+#define TCSTATUS_IXMT (_ULCAST_(1) << TCSTATUS_IXMT_SHIFT)
+#define TCSTATUS_TKSU_SHIFT 11
+#define TCSTATUS_TKSU (_ULCAST_(3) << TCSTATUS_TKSU_SHIFT)
+#define TCSTATUS_A_SHIFT 13
+#define TCSTATUS_A (_ULCAST_(1) << TCSTATUS_A_SHIFT)
+#define TCSTATUS_DA_SHIFT 15
+#define TCSTATUS_DA (_ULCAST_(1) << TCSTATUS_DA_SHIFT)
+#define TCSTATUS_DT_SHIFT 20
+#define TCSTATUS_DT (_ULCAST_(1) << TCSTATUS_DT_SHIFT)
+#define TCSTATUS_TDS_SHIFT 21
+#define TCSTATUS_TDS (_ULCAST_(1) << TCSTATUS_TDS_SHIFT)
+#define TCSTATUS_TSST_SHIFT 22
+#define TCSTATUS_TSST (_ULCAST_(1) << TCSTATUS_TSST_SHIFT)
+#define TCSTATUS_RNST_SHIFT 23
+#define TCSTATUS_RNST (_ULCAST_(3) << TCSTATUS_RNST_SHIFT)
+/* Codes for RNST */
+#define TC_RUNNING 0
+#define TC_WAITING 1
+#define TC_YIELDING 2
+#define TC_GATED 3
+
+#define TCSTATUS_TMX_SHIFT 27
+#define TCSTATUS_TMX (_ULCAST_(1) << TCSTATUS_TMX_SHIFT)
+/* TCStatus TCU bits can use same definitions/offsets as CU bits in Status */
+
+/* TCBind */
+#define TCBIND_CURVPE_SHIFT 0
+#define TCBIND_CURVPE (_ULCAST_(0xf))
+
+#define TCBIND_CURTC_SHIFT 21
+
+#define TCBIND_CURTC (_ULCAST_(0xff) << TCBIND_CURTC_SHIFT)
+
+/* TCHalt */
+#define TCHALT_H (_ULCAST_(1))
+
+#ifndef __ASSEMBLY__
+
+extern void mips_mt_regdump(void);
+
+static inline unsigned int dvpe(void)
+{
+ int res = 0;
+
+ __asm__ __volatile__(
+ " .set push \n"
+ " .set noreorder \n"
+ " .set noat \n"
+ " .set mips32r2 \n"
+ " .word 0x41610001 # dvpe $1 \n"
+ " move %0, $1 \n"
+ " ehb \n"
+ " .set pop \n"
+ : "=r" (res));
+
+ instruction_hazard();
+
+ return res;
+}
+
+static inline void __raw_evpe(void)
+{
+ __asm__ __volatile__(
+ " .set push \n"
+ " .set noreorder \n"
+ " .set noat \n"
+ " .set mips32r2 \n"
+ " .word 0x41600021 # evpe \n"
+ " ehb \n"
+ " .set pop \n");
+}
+
+/* Enable multiMT if previous suggested it should be.
+ EMT_ENABLE to force */
+
+#define EVPE_ENABLE MVPCONTROL_EVP
+
+static inline void evpe(int previous)
+{
+ if ((previous & MVPCONTROL_EVP))
+ __raw_evpe();
+}
+
+static inline unsigned int dmt(void)
+{
+ int res;
+
+ __asm__ __volatile__(
+ " .set push \n"
+ " .set mips32r2 \n"
+ " .set noat \n"
+ " .word 0x41610BC1 # dmt $1 \n"
+ " ehb \n"
+ " move %0, $1 \n"
+ " .set pop \n"
+ : "=r" (res));
+
+ instruction_hazard();
+
+ return res;
+}
+
+static inline void __raw_emt(void)
+{
+ __asm__ __volatile__(
+ " .set noreorder \n"
+ " .set mips32r2 \n"
+ " emt \n"
+ " ehb \n"
+ " .set mips0 \n"
+ " .set reorder");
+}
+
+/* enable multiVPE if previous suggested it should be.
+ EVPE_ENABLE to force */
+
+#define EMT_ENABLE VPECONTROL_TE
+
+static inline void emt(int previous)
+{
+ if ((previous & EMT_ENABLE))
+ __raw_emt();
+}
+
+static inline void ehb(void)
+{
+ __asm__ __volatile__(
+ " .set mips32r2 \n"
+ " ehb \n"
+ " .set mips0 \n");
+}
+
+#define mftc0(rt,sel) \
+({ \
+ unsigned long __res; \
+ \
+ __asm__ __volatile__( \
+ " .set push \n" \
+ " .set mips32r2 \n" \
+ " .set noat \n" \
+ " # mftc0 $1, $" #rt ", " #sel " \n" \
+ " .word 0x41000800 | (" #rt " << 16) | " #sel " \n" \
+ " move %0, $1 \n" \
+ " .set pop \n" \
+ : "=r" (__res)); \
+ \
+ __res; \
+})
+
+#define mftgpr(rt) \
+({ \
+ unsigned long __res; \
+ \
+ __asm__ __volatile__( \
+ " .set push \n" \
+ " .set mips32r2 \n" \
+ " mftgpr %0," #rt " \n" \
+ " .set pop \n" \
+ : "=r" (__res)); \
+ \
+ __res; \
+})
+
+#define mftr(rt,u,sel) \
+({ \
+ unsigned long __res; \
+ \
+ __asm__ __volatile__( \
+ ".set noat\n\t" \
+ "mftr\t%0, " #rt ", " #u ", " #sel "\n\t" \
+ ".set at\n\t" \
+ : "=r" (__res)); \
+ \
+ __res; \
+})
+
+#define mttgpr(rd,v) \
+do { \
+ __asm__ __volatile__( \
+ " .set push \n" \
+ " .set mips32r2 \n" \
+ " .set noat \n" \
+ " move $1, %0 \n" \
+ " # mttgpr $1, " #rd " \n" \
+ " .word 0x41810020 | (" #rd " << 11) \n" \
+ " .set pop \n" \
+ : : "r" (v)); \
+} while (0)
+
+#define mttc0(rd,sel,v) \
+({ \
+ __asm__ __volatile__( \
+ " .set push \n" \
+ " .set mips32r2 \n" \
+ " .set noat \n" \
+ " move $1, %0 \n" \
+ " # mttc0 %0," #rd ", " #sel " \n" \
+ " .word 0x41810000 | (" #rd " << 11) | " #sel " \n" \
+ " .set pop \n" \
+ : \
+ : "r" (v)); \
+})
+
+
+#define mttr(rd,u,sel,v) \
+({ \
+ __asm__ __volatile__( \
+ "mttr %0," #rd ", " #u ", " #sel \
+ : : "r" (v)); \
+})
+
+
+#define settc(tc) \
+do { \
+ write_c0_vpecontrol((read_c0_vpecontrol()&~VPECONTROL_TARGTC) | (tc)); \
+ ehb(); \
+} while (0)
+
+
+/* you *must* set the target tc (settc) before trying to use these */
+#define read_vpe_c0_vpecontrol() mftc0(1, 1)
+#define write_vpe_c0_vpecontrol(val) mttc0(1, 1, val)
+#define read_vpe_c0_vpeconf0() mftc0(1, 2)
+#define write_vpe_c0_vpeconf0(val) mttc0(1, 2, val)
+#define read_vpe_c0_status() mftc0(12, 0)
+#define write_vpe_c0_status(val) mttc0(12, 0, val)
+#define read_vpe_c0_cause() mftc0(13, 0)
+#define write_vpe_c0_cause(val) mttc0(13, 0, val)
+#define read_vpe_c0_config() mftc0(16, 0)
+#define write_vpe_c0_config(val) mttc0(16, 0, val)
+#define read_vpe_c0_config1() mftc0(16, 1)
+#define write_vpe_c0_config1(val) mttc0(16, 1, val)
+#define read_vpe_c0_config7() mftc0(16, 7)
+#define write_vpe_c0_config7(val) mttc0(16, 7, val)
+#define read_vpe_c0_ebase() mftc0(15,1)
+#define write_vpe_c0_ebase(val) mttc0(15, 1, val)
+#define write_vpe_c0_compare(val) mttc0(11, 0, val)
+
+
+/* TC */
+#define read_tc_c0_tcstatus() mftc0(2, 1)
+#define write_tc_c0_tcstatus(val) mttc0(2,1,val)
+#define read_tc_c0_tcbind() mftc0(2, 2)
+#define write_tc_c0_tcbind(val) mttc0(2,2,val)
+#define read_tc_c0_tcrestart() mftc0(2, 3)
+#define write_tc_c0_tcrestart(val) mttc0(2,3,val)
+#define read_tc_c0_tchalt() mftc0(2, 4)
+#define write_tc_c0_tchalt(val) mttc0(2,4,val)
+#define read_tc_c0_tccontext() mftc0(2, 5)
+#define write_tc_c0_tccontext(val) mttc0(2,5,val)
+
+/* GPR */
+#define read_tc_gpr_sp() mftgpr(29)
+#define write_tc_gpr_sp(val) mttgpr(29, val)
+#define read_tc_gpr_gp() mftgpr(28)
+#define write_tc_gpr_gp(val) mttgpr(28, val)
+
+__BUILD_SET_C0(mvpcontrol)
+
+#endif /* Not __ASSEMBLY__ */
+
+#endif
diff --git a/include/asm-mips/mipsregs.h b/include/asm-mips/mipsregs.h
index 2197aa4ce456..80370e0a5589 100644
--- a/include/asm-mips/mipsregs.h
+++ b/include/asm-mips/mipsregs.h
@@ -8,7 +8,7 @@
* Modified for further R[236]000 support by Paul M. Antoine, 1996.
* Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
* Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved.
- * Copyright (C) 2003 Maciej W. Rozycki
+ * Copyright (C) 2003, 2004 Maciej W. Rozycki
*/
#ifndef _ASM_MIPSREGS_H
#define _ASM_MIPSREGS_H
@@ -96,6 +96,16 @@
#define CP0_S1_INTCONTROL $20
/*
+ * Coprocessor 0 Set 2 register names
+ */
+#define CP0_S2_SRSCTL $12 /* MIPSR2 */
+
+/*
+ * Coprocessor 0 Set 3 register names
+ */
+#define CP0_S3_SRSMAP $12 /* MIPSR2 */
+
+/*
* TX39 Series
*/
#define CP0_TX39_CACHE $7
@@ -281,6 +291,11 @@
#define ST0_DL (_ULCAST_(1) << 24)
/*
+ * Enable the MIPS DSP ASE
+ */
+#define ST0_MX 0x01000000
+
+/*
* Bitfields in the TX39 family CP0 Configuration Register 3
*/
#define TX39_CONF_ICS_SHIFT 19
@@ -433,6 +448,14 @@
#define R5K_CONF_SE (_ULCAST_(1) << 12)
#define R5K_CONF_SS (_ULCAST_(3) << 20)
+/* Bits specific to the RM7000. */
+#define RM7K_CONF_SE (_ULCAST_(1) << 3)
+#define RM7K_CONF_TE (_ULCAST_(1) << 12)
+#define RM7K_CONF_CLK (_ULCAST_(1) << 16)
+#define RM7K_CONF_TC (_ULCAST_(1) << 17)
+#define RM7K_CONF_SI (_ULCAST_(3) << 20)
+#define RM7K_CONF_SC (_ULCAST_(1) << 31)
+
/* Bits specific to the R10000. */
#define R10K_CONF_DN (_ULCAST_(3) << 3)
#define R10K_CONF_CT (_ULCAST_(1) << 5)
@@ -475,6 +498,53 @@
#define MIPS_CONF_M (_ULCAST_(1) << 31)
/*
+ * Bits in the MIPS32/64 PRA coprocessor 0 config registers 1 and above.
+ */
+#define MIPS_CONF1_FP (_ULCAST_(1) << 0)
+#define MIPS_CONF1_EP (_ULCAST_(1) << 1)
+#define MIPS_CONF1_CA (_ULCAST_(1) << 2)
+#define MIPS_CONF1_WR (_ULCAST_(1) << 3)
+#define MIPS_CONF1_PC (_ULCAST_(1) << 4)
+#define MIPS_CONF1_MD (_ULCAST_(1) << 5)
+#define MIPS_CONF1_C2 (_ULCAST_(1) << 6)
+#define MIPS_CONF1_DA (_ULCAST_(7) << 7)
+#define MIPS_CONF1_DL (_ULCAST_(7) << 10)
+#define MIPS_CONF1_DS (_ULCAST_(7) << 13)
+#define MIPS_CONF1_IA (_ULCAST_(7) << 16)
+#define MIPS_CONF1_IL (_ULCAST_(7) << 19)
+#define MIPS_CONF1_IS (_ULCAST_(7) << 22)
+#define MIPS_CONF1_TLBS (_ULCAST_(63)<< 25)
+
+#define MIPS_CONF2_SA (_ULCAST_(15)<< 0)
+#define MIPS_CONF2_SL (_ULCAST_(15)<< 4)
+#define MIPS_CONF2_SS (_ULCAST_(15)<< 8)
+#define MIPS_CONF2_SU (_ULCAST_(15)<< 12)
+#define MIPS_CONF2_TA (_ULCAST_(15)<< 16)
+#define MIPS_CONF2_TL (_ULCAST_(15)<< 20)
+#define MIPS_CONF2_TS (_ULCAST_(15)<< 24)
+#define MIPS_CONF2_TU (_ULCAST_(7) << 28)
+
+#define MIPS_CONF3_TL (_ULCAST_(1) << 0)
+#define MIPS_CONF3_SM (_ULCAST_(1) << 1)
+#define MIPS_CONF3_MT (_ULCAST_(1) << 2)
+#define MIPS_CONF3_SP (_ULCAST_(1) << 4)
+#define MIPS_CONF3_VINT (_ULCAST_(1) << 5)
+#define MIPS_CONF3_VEIC (_ULCAST_(1) << 6)
+#define MIPS_CONF3_LPA (_ULCAST_(1) << 7)
+#define MIPS_CONF3_DSP (_ULCAST_(1) << 10)
+
+/*
+ * Bits in the MIPS32/64 coprocessor 1 (FPU) revision register.
+ */
+#define MIPS_FPIR_S (_ULCAST_(1) << 16)
+#define MIPS_FPIR_D (_ULCAST_(1) << 17)
+#define MIPS_FPIR_PS (_ULCAST_(1) << 18)
+#define MIPS_FPIR_3D (_ULCAST_(1) << 19)
+#define MIPS_FPIR_W (_ULCAST_(1) << 20)
+#define MIPS_FPIR_L (_ULCAST_(1) << 21)
+#define MIPS_FPIR_F64 (_ULCAST_(1) << 22)
+
+/*
* R10000 performance counter definitions.
*
* FIXME: The R10000 performance counter opens a nice way to implement CPU
@@ -621,13 +691,13 @@ do { \
if (sel == 0) \
__asm__ __volatile__( \
"mtc0\t%z0, " #register "\n\t" \
- : : "Jr" ((unsigned int)value)); \
+ : : "Jr" ((unsigned int)(value))); \
else \
__asm__ __volatile__( \
".set\tmips32\n\t" \
"mtc0\t%z0, " #register ", " #sel "\n\t" \
".set\tmips0" \
- : : "Jr" ((unsigned int)value)); \
+ : : "Jr" ((unsigned int)(value))); \
} while (0)
#define __write_64bit_c0_register(register, sel, value) \
@@ -676,7 +746,7 @@ do { \
do { \
__asm__ __volatile__( \
"ctc0\t%z0, " #register "\n\t" \
- : : "Jr" ((unsigned int)value)); \
+ : : "Jr" ((unsigned int)(value))); \
} while (0)
/*
@@ -769,12 +839,24 @@ do { \
#define read_c0_count() __read_32bit_c0_register($9, 0)
#define write_c0_count(val) __write_32bit_c0_register($9, 0, val)
+#define read_c0_count2() __read_32bit_c0_register($9, 6) /* pnx8550 */
+#define write_c0_count2(val) __write_32bit_c0_register($9, 6, val)
+
+#define read_c0_count3() __read_32bit_c0_register($9, 7) /* pnx8550 */
+#define write_c0_count3(val) __write_32bit_c0_register($9, 7, val)
+
#define read_c0_entryhi() __read_ulong_c0_register($10, 0)
#define write_c0_entryhi(val) __write_ulong_c0_register($10, 0, val)
#define read_c0_compare() __read_32bit_c0_register($11, 0)
#define write_c0_compare(val) __write_32bit_c0_register($11, 0, val)
+#define read_c0_compare2() __read_32bit_c0_register($11, 6) /* pnx8550 */
+#define write_c0_compare2(val) __write_32bit_c0_register($11, 6, val)
+
+#define read_c0_compare3() __read_32bit_c0_register($11, 7) /* pnx8550 */
+#define write_c0_compare3(val) __write_32bit_c0_register($11, 7, val)
+
#define read_c0_status() __read_32bit_c0_register($12, 0)
#define write_c0_status(val) __write_32bit_c0_register($12, 0, val)
@@ -790,10 +872,18 @@ do { \
#define read_c0_config1() __read_32bit_c0_register($16, 1)
#define read_c0_config2() __read_32bit_c0_register($16, 2)
#define read_c0_config3() __read_32bit_c0_register($16, 3)
+#define read_c0_config4() __read_32bit_c0_register($16, 4)
+#define read_c0_config5() __read_32bit_c0_register($16, 5)
+#define read_c0_config6() __read_32bit_c0_register($16, 6)
+#define read_c0_config7() __read_32bit_c0_register($16, 7)
#define write_c0_config(val) __write_32bit_c0_register($16, 0, val)
#define write_c0_config1(val) __write_32bit_c0_register($16, 1, val)
#define write_c0_config2(val) __write_32bit_c0_register($16, 2, val)
#define write_c0_config3(val) __write_32bit_c0_register($16, 3, val)
+#define write_c0_config4(val) __write_32bit_c0_register($16, 4, val)
+#define write_c0_config5(val) __write_32bit_c0_register($16, 5, val)
+#define write_c0_config6(val) __write_32bit_c0_register($16, 6, val)
+#define write_c0_config7(val) __write_32bit_c0_register($16, 7, val)
/*
* The WatchLo register. There may be upto 8 of them.
@@ -917,6 +1007,22 @@ do { \
#define read_c0_errorepc() __read_ulong_c0_register($30, 0)
#define write_c0_errorepc(val) __write_ulong_c0_register($30, 0, val)
+/* MIPSR2 */
+#define read_c0_hwrena() __read_32bit_c0_register($7,0)
+#define write_c0_hwrena(val) __write_32bit_c0_register($7, 0, val)
+
+#define read_c0_intctl() __read_32bit_c0_register($12, 1)
+#define write_c0_intctl(val) __write_32bit_c0_register($12, 1, val)
+
+#define read_c0_srsctl() __read_32bit_c0_register($12, 2)
+#define write_c0_srsctl(val) __write_32bit_c0_register($12, 2, val)
+
+#define read_c0_srsmap() __read_32bit_c0_register($12, 3)
+#define write_c0_srsmap(val) __write_32bit_c0_register($12, 3, val)
+
+#define read_c0_ebase() __read_32bit_c0_register($15,1)
+#define write_c0_ebase(val) __write_32bit_c0_register($15, 1, val)
+
/*
* Macros to access the floating point coprocessor control registers
*/
@@ -930,6 +1036,284 @@ do { \
: "=r" (__res)); \
__res;})
+#define rddsp(mask) \
+({ \
+ unsigned int __res; \
+ \
+ __asm__ __volatile__( \
+ " .set push \n" \
+ " .set noat \n" \
+ " # rddsp $1, %x1 \n" \
+ " .word 0x7c000cb8 | (%x1 << 16) \n" \
+ " move %0, $1 \n" \
+ " .set pop \n" \
+ : "=r" (__res) \
+ : "i" (mask)); \
+ __res; \
+})
+
+#define wrdsp(val, mask) \
+do { \
+ __asm__ __volatile__( \
+ " .set push \n" \
+ " .set noat \n" \
+ " move $1, %0 \n" \
+ " # wrdsp $1, %x1 \n" \
+ " .word 0x7c2004f8 | (%x1 << 15) \n" \
+ " .set pop \n" \
+ : \
+ : "r" (val), "i" (mask)); \
+} while (0)
+
+#if 0 /* Need DSP ASE capable assembler ... */
+#define mflo0() ({ long mflo0; __asm__("mflo %0, $ac0" : "=r" (mflo0)); mflo0;})
+#define mflo1() ({ long mflo1; __asm__("mflo %0, $ac1" : "=r" (mflo1)); mflo1;})
+#define mflo2() ({ long mflo2; __asm__("mflo %0, $ac2" : "=r" (mflo2)); mflo2;})
+#define mflo3() ({ long mflo3; __asm__("mflo %0, $ac3" : "=r" (mflo3)); mflo3;})
+
+#define mfhi0() ({ long mfhi0; __asm__("mfhi %0, $ac0" : "=r" (mfhi0)); mfhi0;})
+#define mfhi1() ({ long mfhi1; __asm__("mfhi %0, $ac1" : "=r" (mfhi1)); mfhi1;})
+#define mfhi2() ({ long mfhi2; __asm__("mfhi %0, $ac2" : "=r" (mfhi2)); mfhi2;})
+#define mfhi3() ({ long mfhi3; __asm__("mfhi %0, $ac3" : "=r" (mfhi3)); mfhi3;})
+
+#define mtlo0(x) __asm__("mtlo %0, $ac0" ::"r" (x))
+#define mtlo1(x) __asm__("mtlo %0, $ac1" ::"r" (x))
+#define mtlo2(x) __asm__("mtlo %0, $ac2" ::"r" (x))
+#define mtlo3(x) __asm__("mtlo %0, $ac3" ::"r" (x))
+
+#define mthi0(x) __asm__("mthi %0, $ac0" ::"r" (x))
+#define mthi1(x) __asm__("mthi %0, $ac1" ::"r" (x))
+#define mthi2(x) __asm__("mthi %0, $ac2" ::"r" (x))
+#define mthi3(x) __asm__("mthi %0, $ac3" ::"r" (x))
+
+#else
+
+#define mfhi0() \
+({ \
+ unsigned long __treg; \
+ \
+ __asm__ __volatile__( \
+ " .set push \n" \
+ " .set noat \n" \
+ " # mfhi %0, $ac0 \n" \
+ " .word 0x00000810 \n" \
+ " move %0, $1 \n" \
+ " .set pop \n" \
+ : "=r" (__treg)); \
+ __treg; \
+})
+
+#define mfhi1() \
+({ \
+ unsigned long __treg; \
+ \
+ __asm__ __volatile__( \
+ " .set push \n" \
+ " .set noat \n" \
+ " # mfhi %0, $ac1 \n" \
+ " .word 0x00200810 \n" \
+ " move %0, $1 \n" \
+ " .set pop \n" \
+ : "=r" (__treg)); \
+ __treg; \
+})
+
+#define mfhi2() \
+({ \
+ unsigned long __treg; \
+ \
+ __asm__ __volatile__( \
+ " .set push \n" \
+ " .set noat \n" \
+ " # mfhi %0, $ac2 \n" \
+ " .word 0x00400810 \n" \
+ " move %0, $1 \n" \
+ " .set pop \n" \
+ : "=r" (__treg)); \
+ __treg; \
+})
+
+#define mfhi3() \
+({ \
+ unsigned long __treg; \
+ \
+ __asm__ __volatile__( \
+ " .set push \n" \
+ " .set noat \n" \
+ " # mfhi %0, $ac3 \n" \
+ " .word 0x00600810 \n" \
+ " move %0, $1 \n" \
+ " .set pop \n" \
+ : "=r" (__treg)); \
+ __treg; \
+})
+
+#define mflo0() \
+({ \
+ unsigned long __treg; \
+ \
+ __asm__ __volatile__( \
+ " .set push \n" \
+ " .set noat \n" \
+ " # mflo %0, $ac0 \n" \
+ " .word 0x00000812 \n" \
+ " move %0, $1 \n" \
+ " .set pop \n" \
+ : "=r" (__treg)); \
+ __treg; \
+})
+
+#define mflo1() \
+({ \
+ unsigned long __treg; \
+ \
+ __asm__ __volatile__( \
+ " .set push \n" \
+ " .set noat \n" \
+ " # mflo %0, $ac1 \n" \
+ " .word 0x00200812 \n" \
+ " move %0, $1 \n" \
+ " .set pop \n" \
+ : "=r" (__treg)); \
+ __treg; \
+})
+
+#define mflo2() \
+({ \
+ unsigned long __treg; \
+ \
+ __asm__ __volatile__( \
+ " .set push \n" \
+ " .set noat \n" \
+ " # mflo %0, $ac2 \n" \
+ " .word 0x00400812 \n" \
+ " move %0, $1 \n" \
+ " .set pop \n" \
+ : "=r" (__treg)); \
+ __treg; \
+})
+
+#define mflo3() \
+({ \
+ unsigned long __treg; \
+ \
+ __asm__ __volatile__( \
+ " .set push \n" \
+ " .set noat \n" \
+ " # mflo %0, $ac3 \n" \
+ " .word 0x00600812 \n" \
+ " move %0, $1 \n" \
+ " .set pop \n" \
+ : "=r" (__treg)); \
+ __treg; \
+})
+
+#define mthi0(x) \
+do { \
+ __asm__ __volatile__( \
+ " .set push \n" \
+ " .set noat \n" \
+ " move $1, %0 \n" \
+ " # mthi $1, $ac0 \n" \
+ " .word 0x00200011 \n" \
+ " .set pop \n" \
+ : \
+ : "r" (x)); \
+} while (0)
+
+#define mthi1(x) \
+do { \
+ __asm__ __volatile__( \
+ " .set push \n" \
+ " .set noat \n" \
+ " move $1, %0 \n" \
+ " # mthi $1, $ac1 \n" \
+ " .word 0x00200811 \n" \
+ " .set pop \n" \
+ : \
+ : "r" (x)); \
+} while (0)
+
+#define mthi2(x) \
+do { \
+ __asm__ __volatile__( \
+ " .set push \n" \
+ " .set noat \n" \
+ " move $1, %0 \n" \
+ " # mthi $1, $ac2 \n" \
+ " .word 0x00201011 \n" \
+ " .set pop \n" \
+ : \
+ : "r" (x)); \
+} while (0)
+
+#define mthi3(x) \
+do { \
+ __asm__ __volatile__( \
+ " .set push \n" \
+ " .set noat \n" \
+ " move $1, %0 \n" \
+ " # mthi $1, $ac3 \n" \
+ " .word 0x00201811 \n" \
+ " .set pop \n" \
+ : \
+ : "r" (x)); \
+} while (0)
+
+#define mtlo0(x) \
+do { \
+ __asm__ __volatile__( \
+ " .set push \n" \
+ " .set noat \n" \
+ " move $1, %0 \n" \
+ " # mtlo $1, $ac0 \n" \
+ " .word 0x00200013 \n" \
+ " .set pop \n" \
+ : \
+ : "r" (x)); \
+} while (0)
+
+#define mtlo1(x) \
+do { \
+ __asm__ __volatile__( \
+ " .set push \n" \
+ " .set noat \n" \
+ " move $1, %0 \n" \
+ " # mtlo $1, $ac1 \n" \
+ " .word 0x00200813 \n" \
+ " .set pop \n" \
+ : \
+ : "r" (x)); \
+} while (0)
+
+#define mtlo2(x) \
+do { \
+ __asm__ __volatile__( \
+ " .set push \n" \
+ " .set noat \n" \
+ " move $1, %0 \n" \
+ " # mtlo $1, $ac2 \n" \
+ " .word 0x00201013 \n" \
+ " .set pop \n" \
+ : \
+ : "r" (x)); \
+} while (0)
+
+#define mtlo3(x) \
+do { \
+ __asm__ __volatile__( \
+ " .set push \n" \
+ " .set noat \n" \
+ " move $1, %0 \n" \
+ " # mtlo $1, $ac3 \n" \
+ " .word 0x00201813 \n" \
+ " .set pop \n" \
+ : \
+ : "r" (x)); \
+} while (0)
+
+#endif
+
/*
* TLB operations.
*
@@ -1012,6 +1396,8 @@ __BUILD_SET_C0(status)
__BUILD_SET_C0(cause)
__BUILD_SET_C0(config)
__BUILD_SET_C0(intcontrol)
+__BUILD_SET_C0(intctl)
+__BUILD_SET_C0(srsmap)
#endif /* !__ASSEMBLY__ */
diff --git a/include/asm-mips/mmu_context.h b/include/asm-mips/mmu_context.h
index 45cd72d172e8..19cdf7642e66 100644
--- a/include/asm-mips/mmu_context.h
+++ b/include/asm-mips/mmu_context.h
@@ -30,7 +30,7 @@ extern unsigned long pgd_current[];
#ifdef CONFIG_32BIT
#define TLBMISS_HANDLER_SETUP() \
- write_c0_context((unsigned long) smp_processor_id() << 23); \
+ write_c0_context((unsigned long) smp_processor_id() << 25); \
TLBMISS_HANDLER_SETUP_PGD(swapper_pg_dir)
#endif
#if defined(CONFIG_64BIT) && !defined(CONFIG_BUILD_ELF64)
@@ -40,7 +40,7 @@ extern unsigned long pgd_current[];
#endif
#if defined(CONFIG_64BIT) && defined(CONFIG_BUILD_ELF64)
#define TLBMISS_HANDLER_SETUP() \
- write_c0_context((unsigned long) smp_processor_id() << 23); \
+ write_c0_context((unsigned long) smp_processor_id() << 26); \
TLBMISS_HANDLER_SETUP_PGD(swapper_pg_dir)
#endif
diff --git a/include/asm-mips/mmzone.h b/include/asm-mips/mmzone.h
index d721143dbd47..011caebac369 100644
--- a/include/asm-mips/mmzone.h
+++ b/include/asm-mips/mmzone.h
@@ -5,6 +5,7 @@
#ifndef _ASM_MMZONE_H_
#define _ASM_MMZONE_H_
+#include <linux/config.h>
#include <asm/page.h>
#include <mmzone.h>
diff --git a/include/asm-mips/module.h b/include/asm-mips/module.h
index 0be58b2aeb9f..2af496c78c12 100644
--- a/include/asm-mips/module.h
+++ b/include/asm-mips/module.h
@@ -14,15 +14,23 @@ struct mod_arch_specific {
typedef uint8_t Elf64_Byte; /* Type for a 8-bit quantity. */
-typedef struct
-{
- Elf64_Addr r_offset; /* Address of relocation. */
- Elf64_Word r_sym; /* Symbol index. */
- Elf64_Byte r_ssym; /* Special symbol. */
- Elf64_Byte r_type3; /* Third relocation. */
- Elf64_Byte r_type2; /* Second relocation. */
- Elf64_Byte r_type; /* First relocation. */
- Elf64_Sxword r_addend; /* Addend. */
+typedef struct {
+ Elf64_Addr r_offset; /* Address of relocation. */
+ Elf64_Word r_sym; /* Symbol index. */
+ Elf64_Byte r_ssym; /* Special symbol. */
+ Elf64_Byte r_type3; /* Third relocation. */
+ Elf64_Byte r_type2; /* Second relocation. */
+ Elf64_Byte r_type; /* First relocation. */
+} Elf64_Mips_Rel;
+
+typedef struct {
+ Elf64_Addr r_offset; /* Address of relocation. */
+ Elf64_Word r_sym; /* Symbol index. */
+ Elf64_Byte r_ssym; /* Special symbol. */
+ Elf64_Byte r_type3; /* Third relocation. */
+ Elf64_Byte r_type2; /* Second relocation. */
+ Elf64_Byte r_type; /* First relocation. */
+ Elf64_Sxword r_addend; /* Addend. */
} Elf64_Mips_Rela;
#ifdef CONFIG_32BIT
@@ -30,6 +38,13 @@ typedef struct
#define Elf_Shdr Elf32_Shdr
#define Elf_Sym Elf32_Sym
#define Elf_Ehdr Elf32_Ehdr
+#define Elf_Addr Elf32_Addr
+
+#define Elf_Mips_Rel Elf32_Rel
+#define Elf_Mips_Rela Elf32_Rela
+
+#define ELF_MIPS_R_SYM(rel) ELF32_R_SYM(rel.r_info)
+#define ELF_MIPS_R_TYPE(rel) ELF32_R_TYPE(rel.r_info)
#endif
@@ -38,6 +53,13 @@ typedef struct
#define Elf_Shdr Elf64_Shdr
#define Elf_Sym Elf64_Sym
#define Elf_Ehdr Elf64_Ehdr
+#define Elf_Addr Elf64_Addr
+
+#define Elf_Mips_Rel Elf64_Mips_Rel
+#define Elf_Mips_Rela Elf64_Mips_Rela
+
+#define ELF_MIPS_R_SYM(rel) (rel.r_sym)
+#define ELF_MIPS_R_TYPE(rel) (rel.r_type)
#endif
@@ -53,4 +75,54 @@ search_module_dbetables(unsigned long addr)
}
#endif
+#ifdef CONFIG_CPU_MIPS32_R1
+#define MODULE_PROC_FAMILY "MIPS32_R1 "
+#elif defined CONFIG_CPU_MIPS32_R2
+#define MODULE_PROC_FAMILY "MIPS32_R2 "
+#elif defined CONFIG_CPU_MIPS64_R1
+#define MODULE_PROC_FAMILY "MIPS64_R1 "
+#elif defined CONFIG_CPU_MIPS64_R2
+#define MODULE_PROC_FAMILY "MIPS64_R2 "
+#elif defined CONFIG_CPU_R3000
+#define MODULE_PROC_FAMILY "R3000 "
+#elif defined CONFIG_CPU_TX39XX
+#define MODULE_PROC_FAMILY "TX39XX "
+#elif defined CONFIG_CPU_VR41XX
+#define MODULE_PROC_FAMILY "VR41XX "
+#elif defined CONFIG_CPU_R4300
+#define MODULE_PROC_FAMILY "R4300 "
+#elif defined CONFIG_CPU_R4X00
+#define MODULE_PROC_FAMILY "R4X00 "
+#elif defined CONFIG_CPU_TX49XX
+#define MODULE_PROC_FAMILY "TX49XX "
+#elif defined CONFIG_CPU_R5000
+#define MODULE_PROC_FAMILY "R5000 "
+#elif defined CONFIG_CPU_R5432
+#define MODULE_PROC_FAMILY "R5432 "
+#elif defined CONFIG_CPU_R6000
+#define MODULE_PROC_FAMILY "R6000 "
+#elif defined CONFIG_CPU_NEVADA
+#define MODULE_PROC_FAMILY "NEVADA "
+#elif defined CONFIG_CPU_R8000
+#define MODULE_PROC_FAMILY "R8000 "
+#elif defined CONFIG_CPU_R10000
+#define MODULE_PROC_FAMILY "R10000 "
+#elif defined CONFIG_CPU_RM7000
+#define MODULE_PROC_FAMILY "RM7000 "
+#elif defined CONFIG_CPU_RM9000
+#define MODULE_PROC_FAMILY "RM9000 "
+#elif defined CONFIG_CPU_SB1
+#define MODULE_PROC_FAMILY "SB1 "
+#else
+#error MODULE_PROC_FAMILY undefined for your processor configuration
+#endif
+
+#ifdef CONFIG_32BIT
+#define MODULE_KERNEL_TYPE "32BIT "
+#elif defined CONFIG_64BIT
+#define MODULE_KERNEL_TYPE "64BIT "
+#endif
+
+#define MODULE_ARCH_VERMAGIC MODULE_PROC_FAMILY MODULE_KERNEL_TYPE
+
#endif /* _ASM_MODULE_H */
diff --git a/include/asm-mips/paccess.h b/include/asm-mips/paccess.h
index 309bc3099f68..46f2d23d2697 100644
--- a/include/asm-mips/paccess.h
+++ b/include/asm-mips/paccess.h
@@ -52,7 +52,7 @@ struct __large_pstruct { unsigned long buf[100]; };
})
#define __get_dbe_asm(insn) \
-({ \
+{ \
__asm__ __volatile__( \
"1:\t" insn "\t%1,%2\n\t" \
"move\t%0,$0\n" \
@@ -67,7 +67,7 @@ struct __large_pstruct { unsigned long buf[100]; };
".previous" \
:"=r" (__gu_err), "=r" (__gu_val) \
:"o" (__mp(__gu_addr)), "i" (-EFAULT)); \
-})
+}
extern void __get_dbe_unknown(void);
@@ -90,7 +90,7 @@ extern void __get_dbe_unknown(void);
})
#define __put_dbe_asm(insn) \
-({ \
+{ \
__asm__ __volatile__( \
"1:\t" insn "\t%1,%2\n\t" \
"move\t%0,$0\n" \
@@ -104,7 +104,7 @@ extern void __get_dbe_unknown(void);
".previous" \
: "=r" (__pu_err) \
: "r" (__pu_val), "o" (__mp(__pu_addr)), "i" (-EFAULT)); \
-})
+}
extern void __put_dbe_unknown(void);
diff --git a/include/asm-mips/page.h b/include/asm-mips/page.h
index 652b6d67a571..ee25a779bf49 100644
--- a/include/asm-mips/page.h
+++ b/include/asm-mips/page.h
@@ -87,22 +87,48 @@ static inline void copy_user_page(void *vto, void *vfrom, unsigned long vaddr,
typedef struct { unsigned long pte; } pte_t;
#define pte_val(x) ((x).pte)
#endif
+#define __pte(x) ((pte_t) { (x) } )
-typedef struct { unsigned long pmd; } pmd_t;
-typedef struct { unsigned long pgd; } pgd_t;
-typedef struct { unsigned long pgprot; } pgprot_t;
+/*
+ * For 3-level pagetables we defines these ourselves, for 2-level the
+ * definitions are supplied by <asm-generic/pgtable-nopmd.h>.
+ */
+#ifdef CONFIG_64BIT
+typedef struct { unsigned long pmd; } pmd_t;
#define pmd_val(x) ((x).pmd)
-#define pgd_val(x) ((x).pgd)
-#define pgprot_val(x) ((x).pgprot)
+#define __pmd(x) ((pmd_t) { (x) } )
-#define ptep_buddy(x) ((pte_t *)((unsigned long)(x) ^ sizeof(pte_t)))
+#endif
-#define __pte(x) ((pte_t) { (x) } )
-#define __pmd(x) ((pmd_t) { (x) } )
+/*
+ * Right now we don't support 4-level pagetables, so all pud-related
+ * definitions come from <asm-generic/pgtable-nopud.h>.
+ */
+
+/*
+ * Finall the top of the hierarchy, the pgd
+ */
+typedef struct { unsigned long pgd; } pgd_t;
+#define pgd_val(x) ((x).pgd)
#define __pgd(x) ((pgd_t) { (x) } )
+
+/*
+ * Manipulate page protection bits
+ */
+typedef struct { unsigned long pgprot; } pgprot_t;
+#define pgprot_val(x) ((x).pgprot)
#define __pgprot(x) ((pgprot_t) { (x) } )
+/*
+ * On R4000-style MMUs where a TLB entry is mapping a adjacent even / odd
+ * pair of pages we only have a single global bit per pair of pages. When
+ * writing to the TLB make sure we always have the bit set for both pages
+ * or none. This macro is used to access the `buddy' of the pte we're just
+ * working on.
+ */
+#define ptep_buddy(x) ((pte_t *)((unsigned long)(x) ^ sizeof(pte_t)))
+
#endif /* !__ASSEMBLY__ */
/* to align the pointer to the (next) page boundary */
diff --git a/include/asm-mips/pci.h b/include/asm-mips/pci.h
index c9a00ca1c012..6c9ad8171a77 100644
--- a/include/asm-mips/pci.h
+++ b/include/asm-mips/pci.h
@@ -40,6 +40,11 @@ struct pci_controller {
unsigned int need_domain_info;
int iommu;
+
+ /* Optional access methods for reading/writing the bus number
+ of the PCI controller */
+ int (*get_busno)(void);
+ void (*set_busno)(int busno);
};
/*
@@ -142,8 +147,22 @@ static inline void pci_dma_burst_advice(struct pci_dev *pdev,
extern void pcibios_resource_to_bus(struct pci_dev *dev,
struct pci_bus_region *region, struct resource *res);
-extern void pcibios_bus_to_resource(struct pci_dev *dev,
- struct resource *res, struct pci_bus_region *region);
+
+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;
+
+ if (res->flags & IORESOURCE_IO)
+ root = &ioport_resource;
+ if (res->flags & IORESOURCE_MEM)
+ root = &iomem_resource;
+
+ return root;
+}
#ifdef CONFIG_PCI_DOMAINS
@@ -169,17 +188,4 @@ static inline void pcibios_add_platform_entries(struct pci_dev *dev)
/* Do platform specific device initialization at pci_enable_device() time */
extern int pcibios_plat_dev_init(struct pci_dev *dev);
-static inline struct resource *
-pcibios_select_root(struct pci_dev *pdev, struct resource *res)
-{
- struct resource *root = NULL;
-
- if (res->flags & IORESOURCE_IO)
- root = &ioport_resource;
- if (res->flags & IORESOURCE_MEM)
- root = &iomem_resource;
-
- return root;
-}
-
#endif /* _ASM_PCI_H */
diff --git a/include/asm-mips/pgalloc.h b/include/asm-mips/pgalloc.h
index ce57288d43bd..fe1df572318b 100644
--- a/include/asm-mips/pgalloc.h
+++ b/include/asm-mips/pgalloc.h
@@ -26,10 +26,22 @@ static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd,
}
/*
+ * Initialize a new pmd table with invalid pointers.
+ */
+extern void pmd_init(unsigned long page, unsigned long pagetable);
+
+#ifdef CONFIG_64BIT
+
+static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd)
+{
+ set_pud(pud, __pud((unsigned long)pmd));
+}
+#endif
+
+/*
* Initialize a new pgd / pmd table with invalid pointers.
*/
extern void pgd_init(unsigned long page);
-extern void pmd_init(unsigned long page, unsigned long pagetable);
static inline pgd_t *pgd_alloc(struct mm_struct *mm)
{
@@ -86,21 +98,18 @@ static inline void pte_free(struct page *pte)
#define __pte_free_tlb(tlb,pte) tlb_remove_page((tlb),(pte))
#ifdef CONFIG_32BIT
-#define pgd_populate(mm, pmd, pte) BUG()
/*
* allocating and freeing a pmd is trivial: the 1-entry pmd is
* inside the pgd, so has no extra memory associated with it.
*/
-#define pmd_alloc_one(mm, addr) ({ BUG(); ((pmd_t *)2); })
#define pmd_free(x) do { } while (0)
#define __pmd_free_tlb(tlb,x) do { } while (0)
+
#endif
#ifdef CONFIG_64BIT
-#define pgd_populate(mm, pgd, pmd) set_pgd(pgd, __pgd(pmd))
-
static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address)
{
pmd_t *pmd;
diff --git a/include/asm-mips/pgtable-32.h b/include/asm-mips/pgtable-32.h
index 7fec93b76da9..0cff64ce0fb8 100644
--- a/include/asm-mips/pgtable-32.h
+++ b/include/asm-mips/pgtable-32.h
@@ -17,6 +17,8 @@
#include <asm/cachectl.h>
#include <asm/fixmap.h>
+#include <asm-generic/pgtable-nopmd.h>
+
/*
* - add_wired_entry() add a fixed TLB entry, and move wired register
*/
@@ -41,42 +43,38 @@ extern int add_temporary_entry(unsigned long entrylo0, unsigned long entrylo1,
* works even with the cache aliasing problem the R4k and above have.
*/
-/* PMD_SHIFT determines the size of the area a second-level page table can map */
+/* PGDIR_SHIFT determines what a third-level page table entry can map */
#ifdef CONFIG_64BIT_PHYS_ADDR
-#define PMD_SHIFT 21
+#define PGDIR_SHIFT 21
#else
-#define PMD_SHIFT 22
+#define PGDIR_SHIFT 22
#endif
-#define PMD_SIZE (1UL << PMD_SHIFT)
-#define PMD_MASK (~(PMD_SIZE-1))
-
-/* PGDIR_SHIFT determines what a third-level page table entry can map */
-#define PGDIR_SHIFT PMD_SHIFT
#define PGDIR_SIZE (1UL << PGDIR_SHIFT)
#define PGDIR_MASK (~(PGDIR_SIZE-1))
/*
* Entries per page directory level: we use two-level, so
- * we don't really have any PMD directory physically.
+ * we don't really have any PUD/PMD directory physically.
*/
#ifdef CONFIG_64BIT_PHYS_ADDR
#define PGD_ORDER 1
-#define PMD_ORDER 0
+#define PUD_ORDER aieeee_attempt_to_allocate_pud
+#define PMD_ORDER 1
#define PTE_ORDER 0
#else
#define PGD_ORDER 0
-#define PMD_ORDER 0
+#define PUD_ORDER aieeee_attempt_to_allocate_pud
+#define PMD_ORDER 1
#define PTE_ORDER 0
#endif
#define PTRS_PER_PGD ((PAGE_SIZE << PGD_ORDER) / sizeof(pgd_t))
-#define PTRS_PER_PMD 1
#define PTRS_PER_PTE ((PAGE_SIZE << PTE_ORDER) / sizeof(pte_t))
#define USER_PTRS_PER_PGD (0x80000000UL/PGDIR_SIZE)
#define FIRST_USER_ADDRESS 0
-#define VMALLOC_START KSEG2
+#define VMALLOC_START MAP_BASE
#ifdef CONFIG_HIGHMEM
# define VMALLOC_END (PKMAP_BASE-2*PAGE_SIZE)
@@ -91,8 +89,6 @@ extern int add_temporary_entry(unsigned long entrylo0, unsigned long entrylo1,
#define pte_ERROR(e) \
printk("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, pte_val(e))
#endif
-#define pmd_ERROR(e) \
- printk("%s:%d: bad pmd %08lx.\n", __FILE__, __LINE__, pmd_val(e))
#define pgd_ERROR(e) \
printk("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, pgd_val(e))
@@ -120,17 +116,7 @@ static inline void pmd_clear(pmd_t *pmdp)
pmd_val(*pmdp) = ((unsigned long) invalid_pte_table);
}
-/*
- * The "pgd_xxx()" functions here are trivial for a folded two-level
- * setup: the pgd is never bad, and a pmd always exists (as it's folded
- * into the pgd entry)
- */
-static inline int pgd_none(pgd_t pgd) { return 0; }
-static inline int pgd_bad(pgd_t pgd) { return 0; }
-static inline int pgd_present(pgd_t pgd) { return 1; }
-static inline void pgd_clear(pgd_t *pgdp) { }
-
-#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32)
+#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32_R1)
#define pte_page(x) pfn_to_page(pte_pfn(x))
#define pte_pfn(x) ((unsigned long)((x).pte_high >> 6))
static inline pte_t
@@ -151,27 +137,22 @@ pfn_pte(unsigned long pfn, pgprot_t prot)
#define pfn_pte(pfn, prot) __pte(((pfn) << (PAGE_SHIFT + 2)) | pgprot_val(prot))
#else
#define pte_pfn(x) ((unsigned long)((x).pte >> PAGE_SHIFT))
-#define pfn_pte(pfn, prot) __pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot))
+#define pfn_pte(pfn, prot) __pte(((unsigned long long)(pfn) << PAGE_SHIFT) | pgprot_val(prot))
#endif
-#endif /* defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32) */
+#endif /* defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32_R1) */
#define __pgd_offset(address) pgd_index(address)
+#define __pud_offset(address) (((address) >> PUD_SHIFT) & (PTRS_PER_PUD-1))
#define __pmd_offset(address) (((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1))
/* to find an entry in a kernel page-table-directory */
#define pgd_offset_k(address) pgd_offset(&init_mm, address)
-#define pgd_index(address) ((address) >> PGDIR_SHIFT)
+#define pgd_index(address) (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD-1))
/* to find an entry in a page-table-directory */
#define pgd_offset(mm,addr) ((mm)->pgd + pgd_index(addr))
-/* Find an entry in the second-level page table.. */
-static inline pmd_t *pmd_offset(pgd_t *dir, unsigned long address)
-{
- return (pmd_t *) dir;
-}
-
/* Find an entry in the third-level page table.. */
#define __pte_offset(address) \
(((address) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
@@ -221,7 +202,7 @@ static inline pmd_t *pmd_offset(pgd_t *dir, unsigned long address)
*/
#define PTE_FILE_MAX_BITS 27
-#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32)
+#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32_R1)
/* fixme */
#define pte_to_pgoff(_pte) (((_pte).pte_high >> 6) + ((_pte).pte_high & 0x3f))
#define pgoff_to_pte(off) \
diff --git a/include/asm-mips/pgtable-64.h b/include/asm-mips/pgtable-64.h
index 1011e0635f56..82166b254b27 100644
--- a/include/asm-mips/pgtable-64.h
+++ b/include/asm-mips/pgtable-64.h
@@ -16,13 +16,15 @@
#include <asm/page.h>
#include <asm/cachectl.h>
+#include <asm-generic/pgtable-nopud.h>
+
/*
* Each address space has 2 4K pages as its page directory, giving 1024
* (== PTRS_PER_PGD) 8 byte pointers to pmd tables. Each pmd table is a
- * pair of 4K pages, giving 1024 (== PTRS_PER_PMD) 8 byte pointers to
- * page tables. Each page table is a single 4K page, giving 512 (==
- * PTRS_PER_PTE) 8 byte ptes. Each pgde is initialized to point to
- * invalid_pmd_table, each pmde is initialized to point to
+ * single 4K page, giving 512 (== PTRS_PER_PMD) 8 byte pointers to page
+ * tables. Each page table is also a single 4K page, giving 512 (==
+ * PTRS_PER_PTE) 8 byte ptes. Each pud entry is initialized to point to
+ * invalid_pmd_table, each pmd entry is initialized to point to
* invalid_pte_table, each pte is initialized to 0. When memory is low,
* and a pmd table or a page table allocation fails, empty_bad_pmd_table
* and empty_bad_page_table is returned back to higher layer code, so
@@ -36,17 +38,17 @@
*/
/* PMD_SHIFT determines the size of the area a second-level page table can map */
-#define PMD_SHIFT (PAGE_SHIFT + (PAGE_SHIFT - 3))
+#define PMD_SHIFT (PAGE_SHIFT + (PAGE_SHIFT + PTE_ORDER - 3))
#define PMD_SIZE (1UL << PMD_SHIFT)
#define PMD_MASK (~(PMD_SIZE-1))
/* PGDIR_SHIFT determines what a third-level page table entry can map */
-#define PGDIR_SHIFT (PMD_SHIFT + (PAGE_SHIFT + 1 - 3))
+#define PGDIR_SHIFT (PMD_SHIFT + (PAGE_SHIFT + PMD_ORDER - 3))
#define PGDIR_SIZE (1UL << PGDIR_SHIFT)
#define PGDIR_MASK (~(PGDIR_SIZE-1))
/*
- * For 4kB page size we use a 3 level page tree and a 8kB pmd and pgds which
+ * For 4kB page size we use a 3 level page tree and an 8kB pud, which
* permits us mapping 40 bits of virtual address space.
*
* We used to implement 41 bits by having an order 1 pmd level but that seemed
@@ -57,7 +59,7 @@
* two levels would be easy to implement.
*
* For 16kB page size we use a 2 level page tree which permits a total of
- * 36 bits of virtual address space. We could add a third leve. but it seems
+ * 36 bits of virtual address space. We could add a third level but it seems
* like at the moment there's no need for this.
*
* For 64kB page size we use a 2 level page table tree for a total of 42 bits
@@ -65,21 +67,25 @@
*/
#ifdef CONFIG_PAGE_SIZE_4KB
#define PGD_ORDER 1
+#define PUD_ORDER aieeee_attempt_to_allocate_pud
#define PMD_ORDER 0
#define PTE_ORDER 0
#endif
#ifdef CONFIG_PAGE_SIZE_8KB
#define PGD_ORDER 0
+#define PUD_ORDER aieeee_attempt_to_allocate_pud
#define PMD_ORDER 0
#define PTE_ORDER 0
#endif
#ifdef CONFIG_PAGE_SIZE_16KB
#define PGD_ORDER 0
+#define PUD_ORDER aieeee_attempt_to_allocate_pud
#define PMD_ORDER 0
#define PTE_ORDER 0
#endif
#ifdef CONFIG_PAGE_SIZE_64KB
#define PGD_ORDER 0
+#define PUD_ORDER aieeee_attempt_to_allocate_pud
#define PMD_ORDER 0
#define PTE_ORDER 0
#endif
@@ -91,7 +97,7 @@
#define USER_PTRS_PER_PGD (TASK_SIZE / PGDIR_SIZE)
#define FIRST_USER_ADDRESS 0
-#define VMALLOC_START XKSEG
+#define VMALLOC_START MAP_BASE
#define VMALLOC_END \
(VMALLOC_START + PTRS_PER_PGD * PTRS_PER_PMD * PTRS_PER_PTE * PAGE_SIZE)
@@ -102,13 +108,13 @@
#define pgd_ERROR(e) \
printk("%s:%d: bad pgd %016lx.\n", __FILE__, __LINE__, pgd_val(e))
-extern pte_t invalid_pte_table[PAGE_SIZE/sizeof(pte_t)];
-extern pte_t empty_bad_page_table[PAGE_SIZE/sizeof(pte_t)];
-extern pmd_t invalid_pmd_table[2*PAGE_SIZE/sizeof(pmd_t)];
-extern pmd_t empty_bad_pmd_table[2*PAGE_SIZE/sizeof(pmd_t)];
+extern pte_t invalid_pte_table[PTRS_PER_PTE];
+extern pte_t empty_bad_page_table[PTRS_PER_PTE];
+extern pmd_t invalid_pmd_table[PTRS_PER_PMD];
+extern pmd_t empty_bad_pmd_table[PTRS_PER_PMD];
/*
- * Empty pmd entries point to the invalid_pte_table.
+ * Empty pgd/pmd entries point to the invalid_pte_table.
*/
static inline int pmd_none(pmd_t pmd)
{
@@ -128,26 +134,30 @@ static inline void pmd_clear(pmd_t *pmdp)
}
/*
- * Empty pgd entries point to the invalid_pmd_table.
+ * Empty pud entries point to the invalid_pmd_table.
*/
-static inline int pgd_none(pgd_t pgd)
+static inline int pud_none(pud_t pud)
{
- return pgd_val(pgd) == (unsigned long) invalid_pmd_table;
+ return pud_val(pud) == (unsigned long) invalid_pmd_table;
}
-#define pgd_bad(pgd) (pgd_val(pgd) &~ PAGE_MASK)
+static inline int pud_bad(pud_t pud)
+{
+ return pud_val(pud) & ~PAGE_MASK;
+}
-static inline int pgd_present(pgd_t pgd)
+static inline int pud_present(pud_t pud)
{
- return pgd_val(pgd) != (unsigned long) invalid_pmd_table;
+ return pud_val(pud) != (unsigned long) invalid_pmd_table;
}
-static inline void pgd_clear(pgd_t *pgdp)
+static inline void pud_clear(pud_t *pudp)
{
- pgd_val(*pgdp) = ((unsigned long) invalid_pmd_table);
+ pud_val(*pudp) = ((unsigned long) invalid_pmd_table);
}
-#define pte_page(x) pfn_to_page((unsigned long)((pte_val(x) >> PAGE_SHIFT)))
+#define pte_page(x) pfn_to_page(pte_pfn(x))
+
#ifdef CONFIG_CPU_VR41XX
#define pte_pfn(x) ((unsigned long)((x).pte >> (PAGE_SHIFT + 2)))
#define pfn_pte(pfn, prot) __pte(((pfn) << (PAGE_SHIFT + 2)) | pgprot_val(prot))
@@ -157,26 +167,27 @@ static inline void pgd_clear(pgd_t *pgdp)
#endif
#define __pgd_offset(address) pgd_index(address)
-#define page_pte(page) page_pte_prot(page, __pgprot(0))
+#define __pud_offset(address) (((address) >> PUD_SHIFT) & (PTRS_PER_PUD-1))
+#define __pmd_offset(address) pmd_index(address)
/* to find an entry in a kernel page-table-directory */
#define pgd_offset_k(address) pgd_offset(&init_mm, 0)
-#define pgd_index(address) ((address) >> PGDIR_SHIFT)
+#define pgd_index(address) (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD-1))
+#define pmd_index(address) (((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1))
/* to find an entry in a page-table-directory */
#define pgd_offset(mm,addr) ((mm)->pgd + pgd_index(addr))
-static inline unsigned long pgd_page(pgd_t pgd)
+static inline unsigned long pud_page(pud_t pud)
{
- return pgd_val(pgd);
+ return pud_val(pud);
}
/* Find an entry in the second-level page table.. */
-static inline pmd_t *pmd_offset(pgd_t * dir, unsigned long address)
+static inline pmd_t *pmd_offset(pud_t * pud, unsigned long address)
{
- return (pmd_t *) pgd_page(*dir) +
- ((address >> PMD_SHIFT) & (PTRS_PER_PMD - 1));
+ return (pmd_t *) pud_page(*pud) + pmd_index(address);
}
/* Find an entry in the third-level page table.. */
diff --git a/include/asm-mips/pgtable-bits.h b/include/asm-mips/pgtable-bits.h
index 3aad751ccd5f..01e76e932e3f 100644
--- a/include/asm-mips/pgtable-bits.h
+++ b/include/asm-mips/pgtable-bits.h
@@ -33,7 +33,7 @@
* unpredictable things. The code (when it is written) to deal with
* this problem will be in the update_mmu_cache() code for the r4k.
*/
-#if defined(CONFIG_CPU_MIPS32) && defined(CONFIG_64BIT_PHYS_ADDR)
+#if defined(CONFIG_CPU_MIPS32_R1) && defined(CONFIG_64BIT_PHYS_ADDR)
#define _PAGE_PRESENT (1<<6) /* implemented in software */
#define _PAGE_READ (1<<7) /* implemented in software */
@@ -123,7 +123,7 @@
#endif
#endif
-#endif /* defined(CONFIG_CPU_MIPS32) && defined(CONFIG_64BIT_PHYS_ADDR) */
+#endif /* defined(CONFIG_CPU_MIPS32_R1) && defined(CONFIG_64BIT_PHYS_ADDR) */
#define __READABLE (_PAGE_READ | _PAGE_SILENT_READ | _PAGE_ACCESSED)
#define __WRITEABLE (_PAGE_WRITE | _PAGE_SILENT_WRITE | _PAGE_MODIFIED)
@@ -140,7 +140,7 @@
#define PAGE_CACHABLE_DEFAULT _CACHE_CACHABLE_COW
#endif
-#if defined(CONFIG_CPU_MIPS32) && defined(CONFIG_64BIT_PHYS_ADDR)
+#if defined(CONFIG_CPU_MIPS32_R1) && defined(CONFIG_64BIT_PHYS_ADDR)
#define CONF_CM_DEFAULT (PAGE_CACHABLE_DEFAULT >> 3)
#else
#define CONF_CM_DEFAULT (PAGE_CACHABLE_DEFAULT >> 9)
diff --git a/include/asm-mips/pgtable.h b/include/asm-mips/pgtable.h
index eaf5d9b3a0e1..702a28fa7a34 100644
--- a/include/asm-mips/pgtable.h
+++ b/include/asm-mips/pgtable.h
@@ -8,8 +8,6 @@
#ifndef _ASM_PGTABLE_H
#define _ASM_PGTABLE_H
-#include <asm-generic/4level-fixup.h>
-
#include <linux/config.h>
#ifdef CONFIG_32BIT
#include <asm/pgtable-32.h>
@@ -18,8 +16,12 @@
#include <asm/pgtable-64.h>
#endif
+#include <asm/io.h>
#include <asm/pgtable-bits.h>
+struct mm_struct;
+struct vm_area_struct;
+
#define PAGE_NONE __pgprot(_PAGE_PRESENT | _CACHE_CACHABLE_NONCOHERENT)
#define PAGE_SHARED __pgprot(_PAGE_PRESENT | _PAGE_READ | _PAGE_WRITE | \
PAGE_CACHABLE_DEFAULT)
@@ -76,7 +78,6 @@ extern void paging_init(void);
* Conversion functions: convert a page and protection to a page entry,
* and a page entry and page directory to the page they refer to.
*/
-#define page_pte(page) page_pte_prot(page, __pgprot(0))
#define pmd_phys(pmd) (pmd_val(pmd) - PAGE_OFFSET)
#define pmd_page(pmd) (pfn_to_page(pmd_phys(pmd) >> PAGE_SHIFT))
#define pmd_page_kernel(pmd) pmd_val(pmd)
@@ -84,7 +85,7 @@ extern void paging_init(void);
#define pte_none(pte) (!(pte_val(pte) & ~_PAGE_GLOBAL))
#define pte_present(pte) (pte_val(pte) & _PAGE_PRESENT)
-#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32)
+#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32_R1)
static inline void set_pte(pte_t *ptep, pte_t pte)
{
ptep->pte_high = pte.pte_high;
@@ -148,11 +149,18 @@ static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *pt
#endif
/*
- * (pmds are folded into pgds so this doesn't get actually called,
+ * (pmds are folded into puds so this doesn't get actually called,
* but the define is needed for a generic inline function.)
*/
#define set_pmd(pmdptr, pmdval) do { *(pmdptr) = (pmdval); } while(0)
-#define set_pgd(pgdptr, pgdval) do { *(pgdptr) = (pgdval); } while(0)
+
+#ifdef CONFIG_64BIT
+/*
+ * (puds are folded into pgds so this doesn't get actually called,
+ * but the define is needed for a generic inline function.)
+ */
+#define set_pud(pudptr, pudval) do { *(pudptr) = (pudval); } while(0)
+#endif
#define PGD_T_LOG2 ffz(~sizeof(pgd_t))
#define PMD_T_LOG2 ffz(~sizeof(pmd_t))
@@ -165,7 +173,7 @@ extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
* Undefined behaviour if not..
*/
static inline int pte_user(pte_t pte) { BUG(); return 0; }
-#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32)
+#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32_R1)
static inline int pte_read(pte_t pte) { return (pte).pte_low & _PAGE_READ; }
static inline int pte_write(pte_t pte) { return (pte).pte_low & _PAGE_WRITE; }
static inline int pte_dirty(pte_t pte) { return (pte).pte_low & _PAGE_MODIFIED; }
@@ -324,7 +332,7 @@ static inline pgprot_t pgprot_noncached(pgprot_t _prot)
*/
#define mk_pte(page, pgprot) pfn_pte(page_to_pfn(page), (pgprot))
-#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32)
+#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32_R1)
static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
{
pte.pte_low &= _PAGE_CHG_MASK;
@@ -357,7 +365,6 @@ static inline void update_mmu_cache(struct vm_area_struct *vma,
#endif
#ifdef CONFIG_64BIT_PHYS_ADDR
-extern phys_t fixup_bigphys_addr(phys_t phys_addr, phys_t size);
extern int remap_pfn_range(struct vm_area_struct *vma, unsigned long from, unsigned long pfn, unsigned long size, pgprot_t prot);
static inline int io_remap_pfn_range(struct vm_area_struct *vma,
@@ -367,7 +374,7 @@ static inline int io_remap_pfn_range(struct vm_area_struct *vma,
pgprot_t prot)
{
phys_t phys_addr_high = fixup_bigphys_addr(pfn << PAGE_SHIFT, size);
- return remap_pfn_range(vma, vaddr, pfn, size, prot);
+ return remap_pfn_range(vma, vaddr, phys_addr_high >> PAGE_SHIFT, size, prot);
}
#else
#define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \
diff --git a/include/asm-mips/processor.h b/include/asm-mips/processor.h
index d6466aa09fb7..f1980c6c3bcc 100644
--- a/include/asm-mips/processor.h
+++ b/include/asm-mips/processor.h
@@ -96,12 +96,26 @@ union mips_fpu_union {
{{0,},} \
}
+#define NUM_DSP_REGS 6
+
+typedef __u32 dspreg_t;
+
+struct mips_dsp_state {
+ dspreg_t dspr[NUM_DSP_REGS];
+ unsigned int dspcontrol;
+ unsigned short used_dsp;
+};
+
+#define INIT_DSP {{0,},}
+
typedef struct {
unsigned long seg;
} mm_segment_t;
#define ARCH_MIN_TASKALIGN 8
+struct mips_abi;
+
/*
* If you change thread_struct remember to change the #defines below too!
*/
@@ -117,6 +131,9 @@ struct thread_struct {
/* Saved fpu/fpu emulator stuff. */
union mips_fpu_union fpu;
+ /* Saved state of the DSP ASE, if available. */
+ struct mips_dsp_state dsp;
+
/* Other stuff associated with the thread. */
unsigned long cp0_badvaddr; /* Last user fault */
unsigned long cp0_baduaddr; /* Last kernel fault accessing USEG */
@@ -129,6 +146,7 @@ struct thread_struct {
unsigned long mflags;
unsigned long irix_trampoline; /* Wheee... */
unsigned long irix_oldctx;
+ struct mips_abi *abi;
};
#define MF_ABI_MASK (MF_32BIT_REGS | MF_32BIT_ADDR)
@@ -151,6 +169,10 @@ struct thread_struct {
*/ \
INIT_FPU, \
/* \
+ * saved dsp/dsp emulator stuff \
+ */ \
+ INIT_DSP, \
+ /* \
* Other stuff associated with the process \
*/ \
0, 0, 0, 0, \
diff --git a/include/asm-mips/ptrace.h b/include/asm-mips/ptrace.h
index 2b5c624c3d4f..95c5839ac465 100644
--- a/include/asm-mips/ptrace.h
+++ b/include/asm-mips/ptrace.h
@@ -22,6 +22,8 @@
#define MMLO 68
#define FPC_CSR 69
#define FPC_EIR 70
+#define DSP_BASE 71 /* 3 more hi / lo register pairs */
+#define DSP_CONTROL 77
/*
* This struct defines the way the registers are stored on the stack during a
@@ -38,18 +40,18 @@ struct pt_regs {
/* Saved special registers. */
unsigned long cp0_status;
- unsigned long lo;
unsigned long hi;
+ unsigned long lo;
unsigned long cp0_badvaddr;
unsigned long cp0_cause;
unsigned long cp0_epc;
};
/* Arbitrarily choose the same ptrace numbers as used by the Sparc code. */
-/* #define PTRACE_GETREGS 12 */
-/* #define PTRACE_SETREGS 13 */
-/* #define PTRACE_GETFPREGS 14 */
-/* #define PTRACE_SETFPREGS 15 */
+#define PTRACE_GETREGS 12
+#define PTRACE_SETREGS 13
+#define PTRACE_GETFPREGS 14
+#define PTRACE_SETFPREGS 15
/* #define PTRACE_GETFPXREGS 18 */
/* #define PTRACE_SETFPXREGS 19 */
@@ -58,6 +60,13 @@ struct pt_regs {
#define PTRACE_GET_THREAD_AREA 25
#define PTRACE_SET_THREAD_AREA 26
+/* Calls to trace a 64bit program from a 32bit program. */
+#define PTRACE_PEEKTEXT_3264 0xc0
+#define PTRACE_PEEKDATA_3264 0xc1
+#define PTRACE_POKETEXT_3264 0xc2
+#define PTRACE_POKEDATA_3264 0xc3
+#define PTRACE_GET_THREAD_AREA_3264 0xc4
+
#ifdef __KERNEL__
#include <linux/linkage.h>
diff --git a/include/asm-mips/r4kcache.h b/include/asm-mips/r4kcache.h
index 5bea49feec66..a5ea9d828aee 100644
--- a/include/asm-mips/r4kcache.h
+++ b/include/asm-mips/r4kcache.h
@@ -21,7 +21,7 @@
*
* - The MIPS32 and MIPS64 specs permit an implementation to directly derive
* the index bits from the virtual address. This breaks with tradition
- * set by the R4000. To keep unpleassant surprises from happening we pick
+ * set by the R4000. To keep unpleasant surprises from happening we pick
* an address in KSEG0 / CKSEG0.
* - We need a properly sign extended address for 64-bit code. To get away
* without ifdefs we let the compiler do it by a type cast.
@@ -30,11 +30,11 @@
#define cache_op(op,addr) \
__asm__ __volatile__( \
+ " .set push \n" \
" .set noreorder \n" \
" .set mips3\n\t \n" \
" cache %0, %1 \n" \
- " .set mips0 \n" \
- " .set reorder" \
+ " .set pop \n" \
: \
: "i" (op), "m" (*(unsigned char *)(addr)))
@@ -84,14 +84,14 @@ static inline void flush_scache_line(unsigned long addr)
static inline void protected_flush_icache_line(unsigned long addr)
{
__asm__ __volatile__(
- ".set noreorder\n\t"
- ".set mips3\n"
- "1:\tcache %0,(%1)\n"
- "2:\t.set mips0\n\t"
- ".set reorder\n\t"
- ".section\t__ex_table,\"a\"\n\t"
- STR(PTR)"\t1b,2b\n\t"
- ".previous"
+ " .set push \n"
+ " .set noreorder \n"
+ " .set mips3 \n"
+ "1: cache %0, (%1) \n"
+ "2: .set pop \n"
+ " .section __ex_table,\"a\" \n"
+ " "STR(PTR)" 1b, 2b \n"
+ " .previous"
:
: "i" (Hit_Invalidate_I), "r" (addr));
}
@@ -100,19 +100,19 @@ static inline void protected_flush_icache_line(unsigned long addr)
* R10000 / R12000 hazard - these processors don't support the Hit_Writeback_D
* cacheop so we use Hit_Writeback_Inv_D which is supported by all R4000-style
* caches. We're talking about one cacheline unnecessarily getting invalidated
- * here so the penaltiy isn't overly hard.
+ * here so the penalty isn't overly hard.
*/
static inline void protected_writeback_dcache_line(unsigned long addr)
{
__asm__ __volatile__(
- ".set noreorder\n\t"
- ".set mips3\n"
- "1:\tcache %0,(%1)\n"
- "2:\t.set mips0\n\t"
- ".set reorder\n\t"
- ".section\t__ex_table,\"a\"\n\t"
- STR(PTR)"\t1b,2b\n\t"
- ".previous"
+ " .set push \n"
+ " .set noreorder \n"
+ " .set mips3 \n"
+ "1: cache %0, (%1) \n"
+ "2: .set pop \n"
+ " .section __ex_table,\"a\" \n"
+ " "STR(PTR)" 1b, 2b \n"
+ " .previous"
:
: "i" (Hit_Writeback_Inv_D), "r" (addr));
}
@@ -120,14 +120,14 @@ static inline void protected_writeback_dcache_line(unsigned long addr)
static inline void protected_writeback_scache_line(unsigned long addr)
{
__asm__ __volatile__(
- ".set noreorder\n\t"
- ".set mips3\n"
- "1:\tcache %0,(%1)\n"
- "2:\t.set mips0\n\t"
- ".set reorder\n\t"
- ".section\t__ex_table,\"a\"\n\t"
- STR(PTR)"\t1b,2b\n\t"
- ".previous"
+ " .set push \n"
+ " .set noreorder \n"
+ " .set mips3 \n"
+ "1: cache %0, (%1) \n"
+ "2: .set pop \n"
+ " .section __ex_table,\"a\" \n"
+ " "STR(PTR)" 1b, 2b \n"
+ " .previous"
:
: "i" (Hit_Writeback_Inv_SD), "r" (addr));
}
@@ -142,6 +142,7 @@ static inline void invalidate_tcache_page(unsigned long addr)
#define cache16_unroll32(base,op) \
__asm__ __volatile__( \
+ " .set push \n" \
" .set noreorder \n" \
" .set mips3 \n" \
" cache %1, 0x000(%0); cache %1, 0x010(%0) \n" \
@@ -160,8 +161,7 @@ static inline void invalidate_tcache_page(unsigned long addr)
" cache %1, 0x1a0(%0); cache %1, 0x1b0(%0) \n" \
" cache %1, 0x1c0(%0); cache %1, 0x1d0(%0) \n" \
" cache %1, 0x1e0(%0); cache %1, 0x1f0(%0) \n" \
- " .set mips0 \n" \
- " .set reorder \n" \
+ " .set pop \n" \
: \
: "r" (base), \
"i" (op));
@@ -285,6 +285,7 @@ static inline void blast_scache16_page_indexed(unsigned long page)
#define cache32_unroll32(base,op) \
__asm__ __volatile__( \
+ " .set push \n" \
" .set noreorder \n" \
" .set mips3 \n" \
" cache %1, 0x000(%0); cache %1, 0x020(%0) \n" \
@@ -303,8 +304,7 @@ static inline void blast_scache16_page_indexed(unsigned long page)
" cache %1, 0x340(%0); cache %1, 0x360(%0) \n" \
" cache %1, 0x380(%0); cache %1, 0x3a0(%0) \n" \
" cache %1, 0x3c0(%0); cache %1, 0x3e0(%0) \n" \
- " .set mips0 \n" \
- " .set reorder \n" \
+ " .set pop \n" \
: \
: "r" (base), \
"i" (op));
@@ -428,6 +428,7 @@ static inline void blast_scache32_page_indexed(unsigned long page)
#define cache64_unroll32(base,op) \
__asm__ __volatile__( \
+ " .set push \n" \
" .set noreorder \n" \
" .set mips3 \n" \
" cache %1, 0x000(%0); cache %1, 0x040(%0) \n" \
@@ -446,8 +447,7 @@ static inline void blast_scache32_page_indexed(unsigned long page)
" cache %1, 0x680(%0); cache %1, 0x6c0(%0) \n" \
" cache %1, 0x700(%0); cache %1, 0x740(%0) \n" \
" cache %1, 0x780(%0); cache %1, 0x7c0(%0) \n" \
- " .set mips0 \n" \
- " .set reorder \n" \
+ " .set pop \n" \
: \
: "r" (base), \
"i" (op));
@@ -532,6 +532,7 @@ static inline void blast_scache64_page_indexed(unsigned long page)
#define cache128_unroll32(base,op) \
__asm__ __volatile__( \
+ " .set push \n" \
" .set noreorder \n" \
" .set mips3 \n" \
" cache %1, 0x000(%0); cache %1, 0x080(%0) \n" \
@@ -550,8 +551,7 @@ static inline void blast_scache64_page_indexed(unsigned long page)
" cache %1, 0xd00(%0); cache %1, 0xd80(%0) \n" \
" cache %1, 0xe00(%0); cache %1, 0xe80(%0) \n" \
" cache %1, 0xf00(%0); cache %1, 0xf80(%0) \n" \
- " .set mips0 \n" \
- " .set reorder \n" \
+ " .set pop \n" \
: \
: "r" (base), \
"i" (op));
diff --git a/include/asm-mips/rtc.h b/include/asm-mips/rtc.h
index 3c4b637fd925..a2abc4572b63 100644
--- a/include/asm-mips/rtc.h
+++ b/include/asm-mips/rtc.h
@@ -15,6 +15,7 @@
#ifdef __KERNEL__
#include <linux/rtc.h>
+#include <asm/time.h>
#define RTC_PIE 0x40 /* periodic interrupt enable */
#define RTC_AIE 0x20 /* alarm interrupt enable */
@@ -27,11 +28,46 @@
#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 */
-unsigned int get_rtc_time(struct rtc_time *time);
-int set_rtc_time(struct rtc_time *time);
-unsigned int get_rtc_ss(void);
-int get_rtc_pll(struct rtc_pll_info *pll);
-int set_rtc_pll(struct rtc_pll_info *pll);
+static inline unsigned int get_rtc_time(struct rtc_time *time)
+{
+ unsigned long nowtime;
+ nowtime = rtc_get_time();
+ to_tm(nowtime, time);
+ time->tm_year -= 1900;
+
+ return RTC_24H;
+}
+
+static inline int set_rtc_time(struct rtc_time *time)
+{
+ unsigned long nowtime;
+ int ret;
+
+ nowtime = mktime(time->tm_year+1900, time->tm_mon+1,
+ time->tm_mday, time->tm_hour, time->tm_min,
+ time->tm_sec);
+ ret = rtc_set_time(nowtime);
+
+ return ret;
+}
+
+static inline unsigned int get_rtc_ss(void)
+{
+ struct rtc_time h;
+
+ get_rtc_time(&h);
+ return h.tm_sec;
+}
+
+static inline int get_rtc_pll(struct rtc_pll_info *pll)
+{
+ return -EINVAL;
+}
+
+static inline int set_rtc_pll(struct rtc_pll_info *pll)
+{
+ return -EINVAL;
+}
#endif
#endif
diff --git a/include/asm-mips/rtlx.h b/include/asm-mips/rtlx.h
new file mode 100644
index 000000000000..1298c3fdf6c9
--- /dev/null
+++ b/include/asm-mips/rtlx.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2004, 2005 MIPS Technologies, Inc. All rights reserved.
+ *
+ */
+
+#ifndef _RTLX_H
+#define _RTLX_H_
+
+#define LX_NODE_BASE 10
+
+#define MIPSCPU_INT_BASE 16
+#define MIPS_CPU_RTLX_IRQ 0
+
+#define RTLX_VERSION 1
+#define RTLX_xID 0x12345600
+#define RTLX_ID (RTLX_xID | RTLX_VERSION)
+#define RTLX_CHANNELS 8
+
+#define RTLX_BUFFER_SIZE 1024
+
+/*
+ * lx_state bits
+ */
+#define RTLX_STATE_OPENED 1UL
+
+/* each channel supports read and write.
+ linux (vpe0) reads lx_buffer and writes rt_buffer
+ SP (vpe1) reads rt_buffer and writes lx_buffer
+*/
+struct rtlx_channel {
+ unsigned long lx_state;
+
+ int buffer_size;
+
+ /* read and write indexes per buffer */
+ int rt_write, rt_read;
+ char *rt_buffer;
+
+ int lx_write, lx_read;
+ char *lx_buffer;
+
+ void *queues;
+
+};
+
+struct rtlx_info {
+ unsigned long id;
+
+ struct rtlx_channel channel[RTLX_CHANNELS];
+};
+
+#endif /* _RTLX_H_ */
diff --git a/include/asm-mips/semaphore.h b/include/asm-mips/semaphore.h
index c2c97dec661b..3d6aa7c7ea81 100644
--- a/include/asm-mips/semaphore.h
+++ b/include/asm-mips/semaphore.h
@@ -45,9 +45,6 @@ struct semaphore {
.wait = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \
}
-#define __MUTEX_INITIALIZER(name) \
- __SEMAPHORE_INITIALIZER(name, 1)
-
#define __DECLARE_SEMAPHORE_GENERIC(name, count) \
struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
diff --git a/include/asm-mips/serial.h b/include/asm-mips/serial.h
index 4eed8e2acdc3..e796d75f027e 100644
--- a/include/asm-mips/serial.h
+++ b/include/asm-mips/serial.h
@@ -52,16 +52,6 @@
#define JAZZ_SERIAL_PORT_DEFNS
#endif
-#ifdef CONFIG_MIPS_COBALT
-#include <asm/cobalt/cobalt.h>
-#define COBALT_BASE_BAUD (18432000 / 16)
-#define COBALT_SERIAL_PORT_DEFNS \
- /* UART CLK PORT IRQ FLAGS */ \
- { 0, COBALT_BASE_BAUD, 0xc800000, COBALT_SERIAL_IRQ, STD_COM_FLAGS }, /* ttyS0 */
-#else
-#define COBALT_SERIAL_PORT_DEFNS
-#endif
-
/*
* Both Galileo boards have the same UART mappings.
*/
@@ -113,17 +103,6 @@
#define IVR_SERIAL_PORT_DEFNS
#endif
-#ifdef CONFIG_TOSHIBA_JMR3927
-#include <asm/jmr3927/jmr3927.h>
-#define TXX927_SERIAL_PORT_DEFNS \
- { .baud_base = JMR3927_BASE_BAUD, .port = UART0_ADDR, .irq = UART0_INT, \
- .flags = UART0_FLAGS, .type = 1 }, \
- { .baud_base = JMR3927_BASE_BAUD, .port = UART1_ADDR, .irq = UART1_INT, \
- .flags = UART1_FLAGS, .type = 1 },
-#else
-#define TXX927_SERIAL_PORT_DEFNS
-#endif
-
#ifdef CONFIG_SERIAL_AU1X00
#include <asm/mach-au1x00/au1000.h>
#ifdef CONFIG_SOC_AU1000
@@ -227,9 +206,9 @@
#define JAGUAR_ATX_SERIAL1_BASE 0xfd000023L
#define _JAGUAR_ATX_SERIAL_INIT(int, base) \
- { baud_base: JAGUAR_ATX_BASE_BAUD, irq: int, \
- flags: (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST), \
- iomem_base: (u8 *) base, iomem_reg_shift: 2, \
+ { .baud_base = JAGUAR_ATX_BASE_BAUD, irq: int, \
+ .flags = (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST), \
+ .iomem_base = (u8 *) base, iomem_reg_shift: 2, \
io_type: SERIAL_IO_MEM }
#define MOMENCO_JAGUAR_ATX_SERIAL_PORT_DEFNS \
_JAGUAR_ATX_SERIAL_INIT(JAGUAR_ATX_SERIAL1_IRQ, JAGUAR_ATX_SERIAL1_BASE)
@@ -243,9 +222,9 @@
#define OCELOT_3_SERIAL_BASE (signed)0xfd000020
#define _OCELOT_3_SERIAL_INIT(int, base) \
- { baud_base: OCELOT_3_BASE_BAUD, irq: int, \
- flags: STD_COM_FLAGS, \
- iomem_base: (u8 *) base, iomem_reg_shift: 2, \
+ { .baud_base = OCELOT_3_BASE_BAUD, irq: int, \
+ .flags = STD_COM_FLAGS, \
+ .iomem_base = (u8 *) base, iomem_reg_shift: 2, \
io_type: SERIAL_IO_MEM }
#define MOMENCO_OCELOT_3_SERIAL_PORT_DEFNS \
@@ -342,7 +321,6 @@
#endif /* CONFIG_SGI_IP32 */
#define SERIAL_PORT_DFNS \
- COBALT_SERIAL_PORT_DEFNS \
DDB5477_SERIAL_PORT_DEFNS \
EV96100_SERIAL_PORT_DEFNS \
IP32_SERIAL_PORT_DEFNS \
@@ -354,7 +332,6 @@
MOMENCO_OCELOT_C_SERIAL_PORT_DEFNS \
MOMENCO_OCELOT_SERIAL_PORT_DEFNS \
MOMENCO_OCELOT_3_SERIAL_PORT_DEFNS \
- TXX927_SERIAL_PORT_DEFNS \
AU1000_SERIAL_PORT_DEFNS
#endif /* _ASM_SERIAL_H */
diff --git a/include/asm-mips/sgi/hpc3.h b/include/asm-mips/sgi/hpc3.h
index ac3dfc7af5b0..fcec52bafb25 100644
--- a/include/asm-mips/sgi/hpc3.h
+++ b/include/asm-mips/sgi/hpc3.h
@@ -128,26 +128,26 @@ struct hpc3_ethregs {
volatile u32 rx_gfptr; /* current GIO fifo ptr */
volatile u32 rx_dfptr; /* current device fifo ptr */
u32 _unused1; /* padding */
- volatile u32 rx_reset; /* reset register */
-#define HPC3_ERXRST_CRESET 0x1 /* Reset dma channel and external controller */
-#define HPC3_ERXRST_CLRIRQ 0x2 /* Clear channel interrupt */
-#define HPC3_ERXRST_LBACK 0x4 /* Enable diagnostic loopback mode of Seeq8003 */
-
- volatile u32 rx_dconfig; /* DMA configuration register */
-#define HPC3_ERXDCFG_D1 0x0000f /* Cycles to spend in D1 state for PIO */
-#define HPC3_ERXDCFG_D2 0x000f0 /* Cycles to spend in D2 state for PIO */
-#define HPC3_ERXDCFG_D3 0x00f00 /* Cycles to spend in D3 state for PIO */
-#define HPC3_ERXDCFG_WCTRL 0x01000 /* Enable writes of desc into ex ctrl port */
-#define HPC3_ERXDCFG_FRXDC 0x02000 /* Clear eop stat bits upon rxdc, hw seeq fix */
-#define HPC3_ERXDCFG_FEOP 0x04000 /* Bad packet marker timeout enable */
-#define HPC3_ERXDCFG_FIRQ 0x08000 /* Another bad packet timeout enable */
-#define HPC3_ERXDCFG_PTO 0x30000 /* Programmed timeout value for above two */
-
- volatile u32 rx_pconfig; /* PIO configuration register */
-#define HPC3_ERXPCFG_P1 0x000f /* Cycles to spend in P1 state for PIO */
-#define HPC3_ERXPCFG_P2 0x00f0 /* Cycles to spend in P2 state for PIO */
-#define HPC3_ERXPCFG_P3 0x0f00 /* Cycles to spend in P3 state for PIO */
-#define HPC3_ERXPCFG_TST 0x1000 /* Diagnistic ram test feature bit */
+ volatile u32 reset; /* reset register */
+#define HPC3_ERST_CRESET 0x1 /* Reset dma channel and external controller */
+#define HPC3_ERST_CLRIRQ 0x2 /* Clear channel interrupt */
+#define HPC3_ERST_LBACK 0x4 /* Enable diagnostic loopback mode of Seeq8003 */
+
+ volatile u32 dconfig; /* DMA configuration register */
+#define HPC3_EDCFG_D1 0x0000f /* Cycles to spend in D1 state for PIO */
+#define HPC3_EDCFG_D2 0x000f0 /* Cycles to spend in D2 state for PIO */
+#define HPC3_EDCFG_D3 0x00f00 /* Cycles to spend in D3 state for PIO */
+#define HPC3_EDCFG_WCTRL 0x01000 /* Enable writes of desc into ex ctrl port */
+#define HPC3_EDCFG_FRXDC 0x02000 /* Clear eop stat bits upon rxdc, hw seeq fix */
+#define HPC3_EDCFG_FEOP 0x04000 /* Bad packet marker timeout enable */
+#define HPC3_EDCFG_FIRQ 0x08000 /* Another bad packet timeout enable */
+#define HPC3_EDCFG_PTO 0x30000 /* Programmed timeout value for above two */
+
+ volatile u32 pconfig; /* PIO configuration register */
+#define HPC3_EPCFG_P1 0x000f /* Cycles to spend in P1 state for PIO */
+#define HPC3_EPCFG_P2 0x00f0 /* Cycles to spend in P2 state for PIO */
+#define HPC3_EPCFG_P3 0x0f00 /* Cycles to spend in P3 state for PIO */
+#define HPC3_EPCFG_TST 0x1000 /* Diagnistic ram test feature bit */
u32 _unused2[0x1000/4 - 8]; /* padding */
diff --git a/include/asm-mips/sibyte/bcm1480_int.h b/include/asm-mips/sibyte/bcm1480_int.h
new file mode 100644
index 000000000000..42d4cf00efd3
--- /dev/null
+++ b/include/asm-mips/sibyte/bcm1480_int.h
@@ -0,0 +1,310 @@
+/* *********************************************************************
+ * BCM1280/BCM1480 Board Support Package
+ *
+ * Interrupt Mapper definitions File: bcm1480_int.h
+ *
+ * This module contains constants for manipulating the
+ * BCM1255/BCM1280/BCM1455/BCM1480's interrupt mapper and
+ * definitions for the interrupt sources.
+ *
+ * BCM1480 specification level: 1X55_1X80-UM100-D4 (11/24/03)
+ *
+ *********************************************************************
+ *
+ * Copyright 2000,2001,2002,2003
+ * Broadcom Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ ********************************************************************* */
+
+
+#ifndef _BCM1480_INT_H
+#define _BCM1480_INT_H
+
+#include "sb1250_defs.h"
+
+/* *********************************************************************
+ * Interrupt Mapper Constants
+ ********************************************************************* */
+
+/*
+ * The interrupt mapper deals with 128-bit logical registers that are
+ * implemented as pairs of 64-bit registers, with the "low" 64 bits in
+ * a register that has an address 0x1000 higher(!) than the
+ * corresponding "high" register.
+ *
+ * For appropriate registers, bit 0 of the "high" register is a
+ * cascade bit that summarizes (as a bit-OR) the 64 bits of the "low"
+ * register.
+ */
+
+/*
+ * This entire file uses _BCM1480_ in all the symbols because it is
+ * entirely BCM1480 specific.
+ */
+
+/*
+ * Interrupt sources (Table 22)
+ */
+
+#define K_BCM1480_INT_SOURCES 128
+
+#define _BCM1480_INT_HIGH(k) (k)
+#define _BCM1480_INT_LOW(k) ((k)+64)
+
+#define K_BCM1480_INT_ADDR_TRAP _BCM1480_INT_HIGH(1)
+#define K_BCM1480_INT_GPIO_0 _BCM1480_INT_HIGH(4)
+#define K_BCM1480_INT_GPIO_1 _BCM1480_INT_HIGH(5)
+#define K_BCM1480_INT_GPIO_2 _BCM1480_INT_HIGH(6)
+#define K_BCM1480_INT_GPIO_3 _BCM1480_INT_HIGH(7)
+#define K_BCM1480_INT_PCI_INTA _BCM1480_INT_HIGH(8)
+#define K_BCM1480_INT_PCI_INTB _BCM1480_INT_HIGH(9)
+#define K_BCM1480_INT_PCI_INTC _BCM1480_INT_HIGH(10)
+#define K_BCM1480_INT_PCI_INTD _BCM1480_INT_HIGH(11)
+#define K_BCM1480_INT_CYCLE_CP0 _BCM1480_INT_HIGH(12)
+#define K_BCM1480_INT_CYCLE_CP1 _BCM1480_INT_HIGH(13)
+#define K_BCM1480_INT_CYCLE_CP2 _BCM1480_INT_HIGH(14)
+#define K_BCM1480_INT_CYCLE_CP3 _BCM1480_INT_HIGH(15)
+#define K_BCM1480_INT_TIMER_0 _BCM1480_INT_HIGH(20)
+#define K_BCM1480_INT_TIMER_1 _BCM1480_INT_HIGH(21)
+#define K_BCM1480_INT_TIMER_2 _BCM1480_INT_HIGH(22)
+#define K_BCM1480_INT_TIMER_3 _BCM1480_INT_HIGH(23)
+#define K_BCM1480_INT_DM_CH_0 _BCM1480_INT_HIGH(28)
+#define K_BCM1480_INT_DM_CH_1 _BCM1480_INT_HIGH(29)
+#define K_BCM1480_INT_DM_CH_2 _BCM1480_INT_HIGH(30)
+#define K_BCM1480_INT_DM_CH_3 _BCM1480_INT_HIGH(31)
+#define K_BCM1480_INT_MAC_0 _BCM1480_INT_HIGH(36)
+#define K_BCM1480_INT_MAC_0_CH1 _BCM1480_INT_HIGH(37)
+#define K_BCM1480_INT_MAC_1 _BCM1480_INT_HIGH(38)
+#define K_BCM1480_INT_MAC_1_CH1 _BCM1480_INT_HIGH(39)
+#define K_BCM1480_INT_MAC_2 _BCM1480_INT_HIGH(40)
+#define K_BCM1480_INT_MAC_2_CH1 _BCM1480_INT_HIGH(41)
+#define K_BCM1480_INT_MAC_3 _BCM1480_INT_HIGH(42)
+#define K_BCM1480_INT_MAC_3_CH1 _BCM1480_INT_HIGH(43)
+#define K_BCM1480_INT_PMI_LOW _BCM1480_INT_HIGH(52)
+#define K_BCM1480_INT_PMI_HIGH _BCM1480_INT_HIGH(53)
+#define K_BCM1480_INT_PMO_LOW _BCM1480_INT_HIGH(54)
+#define K_BCM1480_INT_PMO_HIGH _BCM1480_INT_HIGH(55)
+#define K_BCM1480_INT_MBOX_0_0 _BCM1480_INT_HIGH(56)
+#define K_BCM1480_INT_MBOX_0_1 _BCM1480_INT_HIGH(57)
+#define K_BCM1480_INT_MBOX_0_2 _BCM1480_INT_HIGH(58)
+#define K_BCM1480_INT_MBOX_0_3 _BCM1480_INT_HIGH(59)
+#define K_BCM1480_INT_MBOX_1_0 _BCM1480_INT_HIGH(60)
+#define K_BCM1480_INT_MBOX_1_1 _BCM1480_INT_HIGH(61)
+#define K_BCM1480_INT_MBOX_1_2 _BCM1480_INT_HIGH(62)
+#define K_BCM1480_INT_MBOX_1_3 _BCM1480_INT_HIGH(63)
+
+#define K_BCM1480_INT_BAD_ECC _BCM1480_INT_LOW(1)
+#define K_BCM1480_INT_COR_ECC _BCM1480_INT_LOW(2)
+#define K_BCM1480_INT_IO_BUS _BCM1480_INT_LOW(3)
+#define K_BCM1480_INT_PERF_CNT _BCM1480_INT_LOW(4)
+#define K_BCM1480_INT_SW_PERF_CNT _BCM1480_INT_LOW(5)
+#define K_BCM1480_INT_TRACE_FREEZE _BCM1480_INT_LOW(6)
+#define K_BCM1480_INT_SW_TRACE_FREEZE _BCM1480_INT_LOW(7)
+#define K_BCM1480_INT_WATCHDOG_TIMER_0 _BCM1480_INT_LOW(8)
+#define K_BCM1480_INT_WATCHDOG_TIMER_1 _BCM1480_INT_LOW(9)
+#define K_BCM1480_INT_WATCHDOG_TIMER_2 _BCM1480_INT_LOW(10)
+#define K_BCM1480_INT_WATCHDOG_TIMER_3 _BCM1480_INT_LOW(11)
+#define K_BCM1480_INT_PCI_ERROR _BCM1480_INT_LOW(16)
+#define K_BCM1480_INT_PCI_RESET _BCM1480_INT_LOW(17)
+#define K_BCM1480_INT_NODE_CONTROLLER _BCM1480_INT_LOW(18)
+#define K_BCM1480_INT_HOST_BRIDGE _BCM1480_INT_LOW(19)
+#define K_BCM1480_INT_PORT_0_FATAL _BCM1480_INT_LOW(20)
+#define K_BCM1480_INT_PORT_0_NONFATAL _BCM1480_INT_LOW(21)
+#define K_BCM1480_INT_PORT_1_FATAL _BCM1480_INT_LOW(22)
+#define K_BCM1480_INT_PORT_1_NONFATAL _BCM1480_INT_LOW(23)
+#define K_BCM1480_INT_PORT_2_FATAL _BCM1480_INT_LOW(24)
+#define K_BCM1480_INT_PORT_2_NONFATAL _BCM1480_INT_LOW(25)
+#define K_BCM1480_INT_LDT_SMI _BCM1480_INT_LOW(32)
+#define K_BCM1480_INT_LDT_NMI _BCM1480_INT_LOW(33)
+#define K_BCM1480_INT_LDT_INIT _BCM1480_INT_LOW(34)
+#define K_BCM1480_INT_LDT_STARTUP _BCM1480_INT_LOW(35)
+#define K_BCM1480_INT_LDT_EXT _BCM1480_INT_LOW(36)
+#define K_BCM1480_INT_SMB_0 _BCM1480_INT_LOW(40)
+#define K_BCM1480_INT_SMB_1 _BCM1480_INT_LOW(41)
+#define K_BCM1480_INT_PCMCIA _BCM1480_INT_LOW(42)
+#define K_BCM1480_INT_UART_0 _BCM1480_INT_LOW(44)
+#define K_BCM1480_INT_UART_1 _BCM1480_INT_LOW(45)
+#define K_BCM1480_INT_UART_2 _BCM1480_INT_LOW(46)
+#define K_BCM1480_INT_UART_3 _BCM1480_INT_LOW(47)
+#define K_BCM1480_INT_GPIO_4 _BCM1480_INT_LOW(52)
+#define K_BCM1480_INT_GPIO_5 _BCM1480_INT_LOW(53)
+#define K_BCM1480_INT_GPIO_6 _BCM1480_INT_LOW(54)
+#define K_BCM1480_INT_GPIO_7 _BCM1480_INT_LOW(55)
+#define K_BCM1480_INT_GPIO_8 _BCM1480_INT_LOW(56)
+#define K_BCM1480_INT_GPIO_9 _BCM1480_INT_LOW(57)
+#define K_BCM1480_INT_GPIO_10 _BCM1480_INT_LOW(58)
+#define K_BCM1480_INT_GPIO_11 _BCM1480_INT_LOW(59)
+#define K_BCM1480_INT_GPIO_12 _BCM1480_INT_LOW(60)
+#define K_BCM1480_INT_GPIO_13 _BCM1480_INT_LOW(61)
+#define K_BCM1480_INT_GPIO_14 _BCM1480_INT_LOW(62)
+#define K_BCM1480_INT_GPIO_15 _BCM1480_INT_LOW(63)
+
+/*
+ * Mask values for each interrupt
+ */
+
+#define _BCM1480_INT_MASK1(n) _SB_MAKEMASK1(((n) & 0x3F))
+#define _BCM1480_INT_OFFSET(n) (((n) & 0x40) << 6)
+
+#define M_BCM1480_INT_CASCADE _BCM1480_INT_MASK1(_BCM1480_INT_HIGH(0))
+
+#define M_BCM1480_INT_ADDR_TRAP _BCM1480_INT_MASK1(K_BCM1480_INT_ADDR_TRAP)
+#define M_BCM1480_INT_GPIO_0 _BCM1480_INT_MASK1(K_BCM1480_INT_GPIO_0)
+#define M_BCM1480_INT_GPIO_1 _BCM1480_INT_MASK1(K_BCM1480_INT_GPIO_1)
+#define M_BCM1480_INT_GPIO_2 _BCM1480_INT_MASK1(K_BCM1480_INT_GPIO_2)
+#define M_BCM1480_INT_GPIO_3 _BCM1480_INT_MASK1(K_BCM1480_INT_GPIO_3)
+#define M_BCM1480_INT_PCI_INTA _BCM1480_INT_MASK1(K_BCM1480_INT_PCI_INTA)
+#define M_BCM1480_INT_PCI_INTB _BCM1480_INT_MASK1(K_BCM1480_INT_PCI_INTB)
+#define M_BCM1480_INT_PCI_INTC _BCM1480_INT_MASK1(K_BCM1480_INT_PCI_INTC)
+#define M_BCM1480_INT_PCI_INTD _BCM1480_INT_MASK1(K_BCM1480_INT_PCI_INTD)
+#define M_BCM1480_INT_CYCLE_CP0 _BCM1480_INT_MASK1(K_BCM1480_INT_CYCLE_CP0)
+#define M_BCM1480_INT_CYCLE_CP1 _BCM1480_INT_MASK1(K_BCM1480_INT_CYCLE_CP1)
+#define M_BCM1480_INT_CYCLE_CP2 _BCM1480_INT_MASK1(K_BCM1480_INT_CYCLE_CP2)
+#define M_BCM1480_INT_CYCLE_CP3 _BCM1480_INT_MASK1(K_BCM1480_INT_CYCLE_CP3)
+#define M_BCM1480_INT_TIMER_0 _BCM1480_INT_MASK1(K_BCM1480_INT_TIMER_0)
+#define M_BCM1480_INT_TIMER_1 _BCM1480_INT_MASK1(K_BCM1480_INT_TIMER_1)
+#define M_BCM1480_INT_TIMER_2 _BCM1480_INT_MASK1(K_BCM1480_INT_TIMER_2)
+#define M_BCM1480_INT_TIMER_3 _BCM1480_INT_MASK1(K_BCM1480_INT_TIMER_3)
+#define M_BCM1480_INT_DM_CH_0 _BCM1480_INT_MASK1(K_BCM1480_INT_DM_CH_0)
+#define M_BCM1480_INT_DM_CH_1 _BCM1480_INT_MASK1(K_BCM1480_INT_DM_CH_1)
+#define M_BCM1480_INT_DM_CH_2 _BCM1480_INT_MASK1(K_BCM1480_INT_DM_CH_2)
+#define M_BCM1480_INT_DM_CH_3 _BCM1480_INT_MASK1(K_BCM1480_INT_DM_CH_3)
+#define M_BCM1480_INT_MAC_0 _BCM1480_INT_MASK1(K_BCM1480_INT_MAC_0)
+#define M_BCM1480_INT_MAC_0_CH1 _BCM1480_INT_MASK1(K_BCM1480_INT_MAC_0_CH1)
+#define M_BCM1480_INT_MAC_1 _BCM1480_INT_MASK1(K_BCM1480_INT_MAC_1)
+#define M_BCM1480_INT_MAC_1_CH1 _BCM1480_INT_MASK1(K_BCM1480_INT_MAC_1_CH1)
+#define M_BCM1480_INT_MAC_2 _BCM1480_INT_MASK1(K_BCM1480_INT_MAC_2)
+#define M_BCM1480_INT_MAC_2_CH1 _BCM1480_INT_MASK1(K_BCM1480_INT_MAC_2_CH1)
+#define M_BCM1480_INT_MAC_3 _BCM1480_INT_MASK1(K_BCM1480_INT_MAC_3)
+#define M_BCM1480_INT_MAC_3_CH1 _BCM1480_INT_MASK1(K_BCM1480_INT_MAC_3_CH1)
+#define M_BCM1480_INT_PMI_LOW _BCM1480_INT_MASK1(K_BCM1480_INT_PMI_LOW)
+#define M_BCM1480_INT_PMI_HIGH _BCM1480_INT_MASK1(K_BCM1480_INT_PMI_HIGH)
+#define M_BCM1480_INT_PMO_LOW _BCM1480_INT_MASK1(K_BCM1480_INT_PMO_LOW)
+#define M_BCM1480_INT_PMO_HIGH _BCM1480_INT_MASK1(K_BCM1480_INT_PMO_HIGH)
+#define M_BCM1480_INT_MBOX_0_0 _BCM1480_INT_MASK1(K_BCM1480_INT_MBOX_0_0)
+#define M_BCM1480_INT_MBOX_0_1 _BCM1480_INT_MASK1(K_BCM1480_INT_MBOX_0_1)
+#define M_BCM1480_INT_MBOX_0_2 _BCM1480_INT_MASK1(K_BCM1480_INT_MBOX_0_2)
+#define M_BCM1480_INT_MBOX_0_3 _BCM1480_INT_MASK1(K_BCM1480_INT_MBOX_0_3)
+#define M_BCM1480_INT_MBOX_1_0 _BCM1480_INT_MASK1(K_BCM1480_INT_MBOX_1_0)
+#define M_BCM1480_INT_MBOX_1_1 _BCM1480_INT_MASK1(K_BCM1480_INT_MBOX_1_1)
+#define M_BCM1480_INT_MBOX_1_2 _BCM1480_INT_MASK1(K_BCM1480_INT_MBOX_1_2)
+#define M_BCM1480_INT_MBOX_1_3 _BCM1480_INT_MASK1(K_BCM1480_INT_MBOX_1_3)
+#define M_BCM1480_INT_BAD_ECC _BCM1480_INT_MASK1(K_BCM1480_INT_BAD_ECC)
+#define M_BCM1480_INT_COR_ECC _BCM1480_INT_MASK1(K_BCM1480_INT_COR_ECC)
+#define M_BCM1480_INT_IO_BUS _BCM1480_INT_MASK1(K_BCM1480_INT_IO_BUS)
+#define M_BCM1480_INT_PERF_CNT _BCM1480_INT_MASK1(K_BCM1480_INT_PERF_CNT)
+#define M_BCM1480_INT_SW_PERF_CNT _BCM1480_INT_MASK1(K_BCM1480_INT_SW_PERF_CNT)
+#define M_BCM1480_INT_TRACE_FREEZE _BCM1480_INT_MASK1(K_BCM1480_INT_TRACE_FREEZE)
+#define M_BCM1480_INT_SW_TRACE_FREEZE _BCM1480_INT_MASK1(K_BCM1480_INT_SW_TRACE_FREEZE)
+#define M_BCM1480_INT_WATCHDOG_TIMER_0 _BCM1480_INT_MASK1(K_BCM1480_INT_WATCHDOG_TIMER_0)
+#define M_BCM1480_INT_WATCHDOG_TIMER_1 _BCM1480_INT_MASK1(K_BCM1480_INT_WATCHDOG_TIMER_1)
+#define M_BCM1480_INT_WATCHDOG_TIMER_2 _BCM1480_INT_MASK1(K_BCM1480_INT_WATCHDOG_TIMER_2)
+#define M_BCM1480_INT_WATCHDOG_TIMER_3 _BCM1480_INT_MASK1(K_BCM1480_INT_WATCHDOG_TIMER_3)
+#define M_BCM1480_INT_PCI_ERROR _BCM1480_INT_MASK1(K_BCM1480_INT_PCI_ERROR)
+#define M_BCM1480_INT_PCI_RESET _BCM1480_INT_MASK1(K_BCM1480_INT_PCI_RESET)
+#define M_BCM1480_INT_NODE_CONTROLLER _BCM1480_INT_MASK1(K_BCM1480_INT_NODE_CONTROLLER)
+#define M_BCM1480_INT_HOST_BRIDGE _BCM1480_INT_MASK1(K_BCM1480_INT_HOST_BRIDGE)
+#define M_BCM1480_INT_PORT_0_FATAL _BCM1480_INT_MASK1(K_BCM1480_INT_PORT_0_FATAL)
+#define M_BCM1480_INT_PORT_0_NONFATAL _BCM1480_INT_MASK1(K_BCM1480_INT_PORT_0_NONFATAL)
+#define M_BCM1480_INT_PORT_1_FATAL _BCM1480_INT_MASK1(K_BCM1480_INT_PORT_1_FATAL)
+#define M_BCM1480_INT_PORT_1_NONFATAL _BCM1480_INT_MASK1(K_BCM1480_INT_PORT_1_NONFATAL)
+#define M_BCM1480_INT_PORT_2_FATAL _BCM1480_INT_MASK1(K_BCM1480_INT_PORT_2_FATAL)
+#define M_BCM1480_INT_PORT_2_NONFATAL _BCM1480_INT_MASK1(K_BCM1480_INT_PORT_2_NONFATAL)
+#define M_BCM1480_INT_LDT_SMI _BCM1480_INT_MASK1(K_BCM1480_INT_LDT_SMI)
+#define M_BCM1480_INT_LDT_NMI _BCM1480_INT_MASK1(K_BCM1480_INT_LDT_NMI)
+#define M_BCM1480_INT_LDT_INIT _BCM1480_INT_MASK1(K_BCM1480_INT_LDT_INIT)
+#define M_BCM1480_INT_LDT_STARTUP _BCM1480_INT_MASK1(K_BCM1480_INT_LDT_STARTUP)
+#define M_BCM1480_INT_LDT_EXT _BCM1480_INT_MASK1(K_BCM1480_INT_LDT_EXT)
+#define M_BCM1480_INT_SMB_0 _BCM1480_INT_MASK1(K_BCM1480_INT_SMB_0)
+#define M_BCM1480_INT_SMB_1 _BCM1480_INT_MASK1(K_BCM1480_INT_SMB_1)
+#define M_BCM1480_INT_PCMCIA _BCM1480_INT_MASK1(K_BCM1480_INT_PCMCIA)
+#define M_BCM1480_INT_UART_0 _BCM1480_INT_MASK1(K_BCM1480_INT_UART_0)
+#define M_BCM1480_INT_UART_1 _BCM1480_INT_MASK1(K_BCM1480_INT_UART_1)
+#define M_BCM1480_INT_UART_2 _BCM1480_INT_MASK1(K_BCM1480_INT_UART_2)
+#define M_BCM1480_INT_UART_3 _BCM1480_INT_MASK1(K_BCM1480_INT_UART_3)
+#define M_BCM1480_INT_GPIO_4 _BCM1480_INT_MASK1(K_BCM1480_INT_GPIO_4)
+#define M_BCM1480_INT_GPIO_5 _BCM1480_INT_MASK1(K_BCM1480_INT_GPIO_5)
+#define M_BCM1480_INT_GPIO_6 _BCM1480_INT_MASK1(K_BCM1480_INT_GPIO_6)
+#define M_BCM1480_INT_GPIO_7 _BCM1480_INT_MASK1(K_BCM1480_INT_GPIO_7)
+#define M_BCM1480_INT_GPIO_8 _BCM1480_INT_MASK1(K_BCM1480_INT_GPIO_8)
+#define M_BCM1480_INT_GPIO_9 _BCM1480_INT_MASK1(K_BCM1480_INT_GPIO_9)
+#define M_BCM1480_INT_GPIO_10 _BCM1480_INT_MASK1(K_BCM1480_INT_GPIO_10)
+#define M_BCM1480_INT_GPIO_11 _BCM1480_INT_MASK1(K_BCM1480_INT_GPIO_11)
+#define M_BCM1480_INT_GPIO_12 _BCM1480_INT_MASK1(K_BCM1480_INT_GPIO_12)
+#define M_BCM1480_INT_GPIO_13 _BCM1480_INT_MASK1(K_BCM1480_INT_GPIO_13)
+#define M_BCM1480_INT_GPIO_14 _BCM1480_INT_MASK1(K_BCM1480_INT_GPIO_14)
+#define M_BCM1480_INT_GPIO_15 _BCM1480_INT_MASK1(K_BCM1480_INT_GPIO_15)
+
+/*
+ * Interrupt mappings (Table 18)
+ */
+
+#define K_BCM1480_INT_MAP_I0 0 /* interrupt pins on processor */
+#define K_BCM1480_INT_MAP_I1 1
+#define K_BCM1480_INT_MAP_I2 2
+#define K_BCM1480_INT_MAP_I3 3
+#define K_BCM1480_INT_MAP_I4 4
+#define K_BCM1480_INT_MAP_I5 5
+#define K_BCM1480_INT_MAP_NMI 6 /* nonmaskable */
+#define K_BCM1480_INT_MAP_DINT 7 /* debug interrupt */
+
+/*
+ * Interrupt LDT Set Register (Table 19)
+ */
+
+#define S_BCM1480_INT_HT_INTMSG 0
+#define M_BCM1480_INT_HT_INTMSG _SB_MAKEMASK(3,S_BCM1480_INT_HT_INTMSG)
+#define V_BCM1480_INT_HT_INTMSG(x) _SB_MAKEVALUE(x,S_BCM1480_INT_HT_INTMSG)
+#define G_BCM1480_INT_HT_INTMSG(x) _SB_GETVALUE(x,S_BCM1480_INT_HT_INTMSG,M_BCM1480_INT_HT_INTMSG)
+
+#define K_BCM1480_INT_HT_INTMSG_FIXED 0
+#define K_BCM1480_INT_HT_INTMSG_ARBITRATED 1
+#define K_BCM1480_INT_HT_INTMSG_SMI 2
+#define K_BCM1480_INT_HT_INTMSG_NMI 3
+#define K_BCM1480_INT_HT_INTMSG_INIT 4
+#define K_BCM1480_INT_HT_INTMSG_STARTUP 5
+#define K_BCM1480_INT_HT_INTMSG_EXTINT 6
+#define K_BCM1480_INT_HT_INTMSG_RESERVED 7
+
+#define M_BCM1480_INT_HT_TRIGGERMODE _SB_MAKEMASK1(3)
+#define V_BCM1480_INT_HT_EDGETRIGGER 0
+#define V_BCM1480_INT_HT_LEVELTRIGGER M_BCM1480_INT_HT_TRIGGERMODE
+
+#define M_BCM1480_INT_HT_DESTMODE _SB_MAKEMASK1(4)
+#define V_BCM1480_INT_HT_PHYSICALDEST 0
+#define V_BCM1480_INT_HT_LOGICALDEST M_BCM1480_INT_HT_DESTMODE
+
+#define S_BCM1480_INT_HT_INTDEST 5
+#define M_BCM1480_INT_HT_INTDEST _SB_MAKEMASK(8,S_BCM1480_INT_HT_INTDEST)
+#define V_BCM1480_INT_HT_INTDEST(x) _SB_MAKEVALUE(x,S_BCM1480_INT_HT_INTDEST)
+#define G_BCM1480_INT_HT_INTDEST(x) _SB_GETVALUE(x,S_BCM1480_INT_HT_INTDEST,M_BCM1480_INT_HT_INTDEST)
+
+#define S_BCM1480_INT_HT_VECTOR 13
+#define M_BCM1480_INT_HT_VECTOR _SB_MAKEMASK(8,S_BCM1480_INT_HT_VECTOR)
+#define V_BCM1480_INT_HT_VECTOR(x) _SB_MAKEVALUE(x,S_BCM1480_INT_HT_VECTOR)
+#define G_BCM1480_INT_HT_VECTOR(x) _SB_GETVALUE(x,S_BCM1480_INT_HT_VECTOR,M_BCM1480_INT_HT_VECTOR)
+
+/*
+ * Vector prefix (Table 4-7)
+ */
+
+#define M_BCM1480_HTVECT_RAISE_INTLDT_HIGH 0x00
+#define M_BCM1480_HTVECT_RAISE_MBOX_0 0x40
+#define M_BCM1480_HTVECT_RAISE_INTLDT_LO 0x80
+#define M_BCM1480_HTVECT_RAISE_MBOX_1 0xC0
+
+#endif /* _BCM1480_INT_H */
diff --git a/include/asm-mips/sibyte/bcm1480_l2c.h b/include/asm-mips/sibyte/bcm1480_l2c.h
new file mode 100644
index 000000000000..886b099565e6
--- /dev/null
+++ b/include/asm-mips/sibyte/bcm1480_l2c.h
@@ -0,0 +1,176 @@
+/* *********************************************************************
+ * BCM1280/BCM1480 Board Support Package
+ *
+ * L2 Cache constants and macros File: bcm1480_l2c.h
+ *
+ * This module contains constants useful for manipulating the
+ * level 2 cache.
+ *
+ * BCM1400 specification level: 1280-UM100-D2 (11/14/03)
+ *
+ *********************************************************************
+ *
+ * Copyright 2000,2001,2002,2003
+ * Broadcom Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ ********************************************************************* */
+
+
+#ifndef _BCM1480_L2C_H
+#define _BCM1480_L2C_H
+
+#include "sb1250_defs.h"
+
+/*
+ * Format of level 2 cache management address (Table 55)
+ */
+
+#define S_BCM1480_L2C_MGMT_INDEX 5
+#define M_BCM1480_L2C_MGMT_INDEX _SB_MAKEMASK(12,S_BCM1480_L2C_MGMT_INDEX)
+#define V_BCM1480_L2C_MGMT_INDEX(x) _SB_MAKEVALUE(x,S_BCM1480_L2C_MGMT_INDEX)
+#define G_BCM1480_L2C_MGMT_INDEX(x) _SB_GETVALUE(x,S_BCM1480_L2C_MGMT_INDEX,M_BCM1480_L2C_MGMT_INDEX)
+
+#define S_BCM1480_L2C_MGMT_WAY 17
+#define M_BCM1480_L2C_MGMT_WAY _SB_MAKEMASK(3,S_BCM1480_L2C_MGMT_WAY)
+#define V_BCM1480_L2C_MGMT_WAY(x) _SB_MAKEVALUE(x,S_BCM1480_L2C_MGMT_WAY)
+#define G_BCM1480_L2C_MGMT_WAY(x) _SB_GETVALUE(x,S_BCM1480_L2C_MGMT_WAY,M_BCM1480_L2C_MGMT_WAY)
+
+#define M_BCM1480_L2C_MGMT_DIRTY _SB_MAKEMASK1(20)
+#define M_BCM1480_L2C_MGMT_VALID _SB_MAKEMASK1(21)
+
+#define S_BCM1480_L2C_MGMT_ECC_DIAG 22
+#define M_BCM1480_L2C_MGMT_ECC_DIAG _SB_MAKEMASK(2,S_BCM1480_L2C_MGMT_ECC_DIAG)
+#define V_BCM1480_L2C_MGMT_ECC_DIAG(x) _SB_MAKEVALUE(x,S_BCM1480_L2C_MGMT_ECC_DIAG)
+#define G_BCM1480_L2C_MGMT_ECC_DIAG(x) _SB_GETVALUE(x,S_BCM1480_L2C_MGMT_ECC_DIAG,M_BCM1480_L2C_MGMT_ECC_DIAG)
+
+#define A_BCM1480_L2C_MGMT_TAG_BASE 0x00D0000000
+
+#define BCM1480_L2C_ENTRIES_PER_WAY 4096
+#define BCM1480_L2C_NUM_WAYS 8
+
+
+/*
+ * Level 2 Cache Tag register (Table 59)
+ */
+
+#define S_BCM1480_L2C_TAG_MBZ 0
+#define M_BCM1480_L2C_TAG_MBZ _SB_MAKEMASK(5,S_BCM1480_L2C_TAG_MBZ)
+
+#define S_BCM1480_L2C_TAG_INDEX 5
+#define M_BCM1480_L2C_TAG_INDEX _SB_MAKEMASK(12,S_BCM1480_L2C_TAG_INDEX)
+#define V_BCM1480_L2C_TAG_INDEX(x) _SB_MAKEVALUE(x,S_BCM1480_L2C_TAG_INDEX)
+#define G_BCM1480_L2C_TAG_INDEX(x) _SB_GETVALUE(x,S_BCM1480_L2C_TAG_INDEX,M_BCM1480_L2C_TAG_INDEX)
+
+/* Note that index bit 16 is also tag bit 40 */
+#define S_BCM1480_L2C_TAG_TAG 17
+#define M_BCM1480_L2C_TAG_TAG _SB_MAKEMASK(23,S_BCM1480_L2C_TAG_TAG)
+#define V_BCM1480_L2C_TAG_TAG(x) _SB_MAKEVALUE(x,S_BCM1480_L2C_TAG_TAG)
+#define G_BCM1480_L2C_TAG_TAG(x) _SB_GETVALUE(x,S_BCM1480_L2C_TAG_TAG,M_BCM1480_L2C_TAG_TAG)
+
+#define S_BCM1480_L2C_TAG_ECC 40
+#define M_BCM1480_L2C_TAG_ECC _SB_MAKEMASK(6,S_BCM1480_L2C_TAG_ECC)
+#define V_BCM1480_L2C_TAG_ECC(x) _SB_MAKEVALUE(x,S_BCM1480_L2C_TAG_ECC)
+#define G_BCM1480_L2C_TAG_ECC(x) _SB_GETVALUE(x,S_BCM1480_L2C_TAG_ECC,M_BCM1480_L2C_TAG_ECC)
+
+#define S_BCM1480_L2C_TAG_WAY 46
+#define M_BCM1480_L2C_TAG_WAY _SB_MAKEMASK(3,S_BCM1480_L2C_TAG_WAY)
+#define V_BCM1480_L2C_TAG_WAY(x) _SB_MAKEVALUE(x,S_BCM1480_L2C_TAG_WAY)
+#define G_BCM1480_L2C_TAG_WAY(x) _SB_GETVALUE(x,S_BCM1480_L2C_TAG_WAY,M_BCM1480_L2C_TAG_WAY)
+
+#define M_BCM1480_L2C_TAG_DIRTY _SB_MAKEMASK1(49)
+#define M_BCM1480_L2C_TAG_VALID _SB_MAKEMASK1(50)
+
+#define S_BCM1480_L2C_DATA_ECC 51
+#define M_BCM1480_L2C_DATA_ECC _SB_MAKEMASK(10,S_BCM1480_L2C_DATA_ECC)
+#define V_BCM1480_L2C_DATA_ECC(x) _SB_MAKEVALUE(x,S_BCM1480_L2C_DATA_ECC)
+#define G_BCM1480_L2C_DATA_ECC(x) _SB_GETVALUE(x,S_BCM1480_L2C_DATA_ECC,M_BCM1480_L2C_DATA_ECC)
+
+
+/*
+ * L2 Misc0 Value Register (Table 60)
+ */
+
+#define S_BCM1480_L2C_MISC0_WAY_REMOTE 0
+#define M_BCM1480_L2C_MISC0_WAY_REMOTE _SB_MAKEMASK(8,S_BCM1480_L2C_MISC0_WAY_REMOTE)
+#define G_BCM1480_L2C_MISC0_WAY_REMOTE(x) _SB_GETVALUE(x,S_BCM1480_L2C_MISC0_WAY_REMOTE,M_BCM1480_L2C_MISC0_WAY_REMOTE)
+
+#define S_BCM1480_L2C_MISC0_WAY_LOCAL 8
+#define M_BCM1480_L2C_MISC0_WAY_LOCAL _SB_MAKEMASK(8,S_BCM1480_L2C_MISC0_WAY_LOCAL)
+#define G_BCM1480_L2C_MISC0_WAY_LOCAL(x) _SB_GETVALUE(x,S_BCM1480_L2C_MISC0_WAY_LOCAL,M_BCM1480_L2C_MISC0_WAY_LOCAL)
+
+#define S_BCM1480_L2C_MISC0_WAY_ENABLE 16
+#define M_BCM1480_L2C_MISC0_WAY_ENABLE _SB_MAKEMASK(8,S_BCM1480_L2C_MISC0_WAY_ENABLE)
+#define G_BCM1480_L2C_MISC0_WAY_ENABLE(x) _SB_GETVALUE(x,S_BCM1480_L2C_MISC0_WAY_ENABLE,M_BCM1480_L2C_MISC0_WAY_ENABLE)
+
+#define S_BCM1480_L2C_MISC0_CACHE_DISABLE 24
+#define M_BCM1480_L2C_MISC0_CACHE_DISABLE _SB_MAKEMASK(2,S_BCM1480_L2C_MISC0_CACHE_DISABLE)
+#define G_BCM1480_L2C_MISC0_CACHE_DISABLE(x) _SB_GETVALUE(x,S_BCM1480_L2C_MISC0_CACHE_DISABLE,M_BCM1480_L2C_MISC0_CACHE_DISABLE)
+
+#define S_BCM1480_L2C_MISC0_CACHE_QUAD 26
+#define M_BCM1480_L2C_MISC0_CACHE_QUAD _SB_MAKEMASK(2,S_BCM1480_L2C_MISC0_CACHE_QUAD)
+#define G_BCM1480_L2C_MISC0_CACHE_QUAD(x) _SB_GETVALUE(x,S_BCM1480_L2C_MISC0_CACHE_QUAD,M_BCM1480_L2C_MISC0_CACHE_QUAD)
+
+#define S_BCM1480_L2C_MISC0_MC_PRIORITY 30
+#define M_BCM1480_L2C_MISC0_MC_PRIORITY _SB_MAKEMASK1(S_BCM1480_L2C_MISC0_MC_PRIORITY)
+
+#define S_BCM1480_L2C_MISC0_ECC_CLEANUP 31
+#define M_BCM1480_L2C_MISC0_ECC_CLEANUP _SB_MAKEMASK1(S_BCM1480_L2C_MISC0_ECC_CLEANUP)
+
+
+/*
+ * L2 Misc1 Value Register (Table 60)
+ */
+
+#define S_BCM1480_L2C_MISC1_WAY_AGENT_0 0
+#define M_BCM1480_L2C_MISC1_WAY_AGENT_0 _SB_MAKEMASK(8,S_BCM1480_L2C_MISC1_WAY_AGENT_0)
+#define G_BCM1480_L2C_MISC1_WAY_AGENT_0(x) _SB_GETVALUE(x,S_BCM1480_L2C_MISC1_WAY_AGENT_0,M_BCM1480_L2C_MISC1_WAY_AGENT_0)
+
+#define S_BCM1480_L2C_MISC1_WAY_AGENT_1 8
+#define M_BCM1480_L2C_MISC1_WAY_AGENT_1 _SB_MAKEMASK(8,S_BCM1480_L2C_MISC1_WAY_AGENT_1)
+#define G_BCM1480_L2C_MISC1_WAY_AGENT_1(x) _SB_GETVALUE(x,S_BCM1480_L2C_MISC1_WAY_AGENT_1,M_BCM1480_L2C_MISC1_WAY_AGENT_1)
+
+#define S_BCM1480_L2C_MISC1_WAY_AGENT_2 16
+#define M_BCM1480_L2C_MISC1_WAY_AGENT_2 _SB_MAKEMASK(8,S_BCM1480_L2C_MISC1_WAY_AGENT_2)
+#define G_BCM1480_L2C_MISC1_WAY_AGENT_2(x) _SB_GETVALUE(x,S_BCM1480_L2C_MISC1_WAY_AGENT_2,M_BCM1480_L2C_MISC1_WAY_AGENT_2)
+
+#define S_BCM1480_L2C_MISC1_WAY_AGENT_3 24
+#define M_BCM1480_L2C_MISC1_WAY_AGENT_3 _SB_MAKEMASK(8,S_BCM1480_L2C_MISC1_WAY_AGENT_3)
+#define G_BCM1480_L2C_MISC1_WAY_AGENT_3(x) _SB_GETVALUE(x,S_BCM1480_L2C_MISC1_WAY_AGENT_3,M_BCM1480_L2C_MISC1_WAY_AGENT_3)
+
+#define S_BCM1480_L2C_MISC1_WAY_AGENT_4 32
+#define M_BCM1480_L2C_MISC1_WAY_AGENT_4 _SB_MAKEMASK(8,S_BCM1480_L2C_MISC1_WAY_AGENT_4)
+#define G_BCM1480_L2C_MISC1_WAY_AGENT_4(x) _SB_GETVALUE(x,S_BCM1480_L2C_MISC1_WAY_AGENT_4,M_BCM1480_L2C_MISC1_WAY_AGENT_4)
+
+
+/*
+ * L2 Misc2 Value Register (Table 60)
+ */
+
+#define S_BCM1480_L2C_MISC2_WAY_AGENT_8 0
+#define M_BCM1480_L2C_MISC2_WAY_AGENT_8 _SB_MAKEMASK(8,S_BCM1480_L2C_MISC2_WAY_AGENT_8)
+#define G_BCM1480_L2C_MISC2_WAY_AGENT_8(x) _SB_GETVALUE(x,S_BCM1480_L2C_MISC2_WAY_AGENT_8,M_BCM1480_L2C_MISC2_WAY_AGENT_8)
+
+#define S_BCM1480_L2C_MISC2_WAY_AGENT_9 8
+#define M_BCM1480_L2C_MISC2_WAY_AGENT_9 _SB_MAKEMASK(8,S_BCM1480_L2C_MISC2_WAY_AGENT_9)
+#define G_BCM1480_L2C_MISC2_WAY_AGENT_9(x) _SB_GETVALUE(x,S_BCM1480_L2C_MISC2_WAY_AGENT_9,M_BCM1480_L2C_MISC2_WAY_AGENT_9)
+
+#define S_BCM1480_L2C_MISC2_WAY_AGENT_A 16
+#define M_BCM1480_L2C_MISC2_WAY_AGENT_A _SB_MAKEMASK(8,S_BCM1480_L2C_MISC2_WAY_AGENT_A)
+#define G_BCM1480_L2C_MISC2_WAY_AGENT_A(x) _SB_GETVALUE(x,S_BCM1480_L2C_MISC2_WAY_AGENT_A,M_BCM1480_L2C_MISC2_WAY_AGENT_A)
+
+
+#endif /* _BCM1480_L2C_H */
diff --git a/include/asm-mips/sibyte/bcm1480_mc.h b/include/asm-mips/sibyte/bcm1480_mc.h
new file mode 100644
index 000000000000..6bdc941afc91
--- /dev/null
+++ b/include/asm-mips/sibyte/bcm1480_mc.h
@@ -0,0 +1,962 @@
+/* *********************************************************************
+ * BCM1280/BCM1480 Board Support Package
+ *
+ * Memory Controller constants File: bcm1480_mc.h
+ *
+ * This module contains constants and macros useful for
+ * programming the memory controller.
+ *
+ * BCM1400 specification level: 1280-UM100-D1 (11/14/03 Review Copy)
+ *
+ *********************************************************************
+ *
+ * Copyright 2000,2001,2002,2003
+ * Broadcom Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ ********************************************************************* */
+
+
+#ifndef _BCM1480_MC_H
+#define _BCM1480_MC_H
+
+#include "sb1250_defs.h"
+
+/*
+ * Memory Channel Configuration Register (Table 81)
+ */
+
+#define S_BCM1480_MC_INTLV0 0
+#define M_BCM1480_MC_INTLV0 _SB_MAKEMASK(6,S_BCM1480_MC_INTLV0)
+#define V_BCM1480_MC_INTLV0(x) _SB_MAKEVALUE(x,S_BCM1480_MC_INTLV0)
+#define G_BCM1480_MC_INTLV0(x) _SB_GETVALUE(x,S_BCM1480_MC_INTLV0,M_BCM1480_MC_INTLV0)
+#define V_BCM1480_MC_INTLV0_DEFAULT V_BCM1480_MC_INTLV0(0)
+
+#define S_BCM1480_MC_INTLV1 8
+#define M_BCM1480_MC_INTLV1 _SB_MAKEMASK(6,S_BCM1480_MC_INTLV1)
+#define V_BCM1480_MC_INTLV1(x) _SB_MAKEVALUE(x,S_BCM1480_MC_INTLV1)
+#define G_BCM1480_MC_INTLV1(x) _SB_GETVALUE(x,S_BCM1480_MC_INTLV1,M_BCM1480_MC_INTLV1)
+#define V_BCM1480_MC_INTLV1_DEFAULT V_BCM1480_MC_INTLV1(0)
+
+#define S_BCM1480_MC_INTLV2 16
+#define M_BCM1480_MC_INTLV2 _SB_MAKEMASK(6,S_BCM1480_MC_INTLV2)
+#define V_BCM1480_MC_INTLV2(x) _SB_MAKEVALUE(x,S_BCM1480_MC_INTLV2)
+#define G_BCM1480_MC_INTLV2(x) _SB_GETVALUE(x,S_BCM1480_MC_INTLV2,M_BCM1480_MC_INTLV2)
+#define V_BCM1480_MC_INTLV2_DEFAULT V_BCM1480_MC_INTLV2(0)
+
+#define S_BCM1480_MC_CS_MODE 32
+#define M_BCM1480_MC_CS_MODE _SB_MAKEMASK(8,S_BCM1480_MC_CS_MODE)
+#define V_BCM1480_MC_CS_MODE(x) _SB_MAKEVALUE(x,S_BCM1480_MC_CS_MODE)
+#define G_BCM1480_MC_CS_MODE(x) _SB_GETVALUE(x,S_BCM1480_MC_CS_MODE,M_BCM1480_MC_CS_MODE)
+#define V_BCM1480_MC_CS_MODE_DEFAULT V_BCM1480_MC_CS_MODE(0)
+
+#define V_BCM1480_MC_CONFIG_DEFAULT (V_BCM1480_MC_INTLV0_DEFAULT | \
+ V_BCM1480_MC_INTLV1_DEFAULT | \
+ V_BCM1480_MC_INTLV2_DEFAULT | \
+ V_BCM1480_MC_CS_MODE_DEFAULT)
+
+#define K_BCM1480_MC_CS01_MODE 0x03
+#define K_BCM1480_MC_CS02_MODE 0x05
+#define K_BCM1480_MC_CS0123_MODE 0x0F
+#define K_BCM1480_MC_CS0246_MODE 0x55
+#define K_BCM1480_MC_CS0145_MODE 0x33
+#define K_BCM1480_MC_CS0167_MODE 0xC3
+#define K_BCM1480_MC_CSFULL_MODE 0xFF
+
+/*
+ * Chip Select Start Address Register (Table 82)
+ */
+
+#define S_BCM1480_MC_CS0_START 0
+#define M_BCM1480_MC_CS0_START _SB_MAKEMASK(12,S_BCM1480_MC_CS0_START)
+#define V_BCM1480_MC_CS0_START(x) _SB_MAKEVALUE(x,S_BCM1480_MC_CS0_START)
+#define G_BCM1480_MC_CS0_START(x) _SB_GETVALUE(x,S_BCM1480_MC_CS0_START,M_BCM1480_MC_CS0_START)
+
+#define S_BCM1480_MC_CS1_START 16
+#define M_BCM1480_MC_CS1_START _SB_MAKEMASK(12,S_BCM1480_MC_CS1_START)
+#define V_BCM1480_MC_CS1_START(x) _SB_MAKEVALUE(x,S_BCM1480_MC_CS1_START)
+#define G_BCM1480_MC_CS1_START(x) _SB_GETVALUE(x,S_BCM1480_MC_CS1_START,M_BCM1480_MC_CS1_START)
+
+#define S_BCM1480_MC_CS2_START 32
+#define M_BCM1480_MC_CS2_START _SB_MAKEMASK(12,S_BCM1480_MC_CS2_START)
+#define V_BCM1480_MC_CS2_START(x) _SB_MAKEVALUE(x,S_BCM1480_MC_CS2_START)
+#define G_BCM1480_MC_CS2_START(x) _SB_GETVALUE(x,S_BCM1480_MC_CS2_START,M_BCM1480_MC_CS2_START)
+
+#define S_BCM1480_MC_CS3_START 48
+#define M_BCM1480_MC_CS3_START _SB_MAKEMASK(12,S_BCM1480_MC_CS3_START)
+#define V_BCM1480_MC_CS3_START(x) _SB_MAKEVALUE(x,S_BCM1480_MC_CS3_START)
+#define G_BCM1480_MC_CS3_START(x) _SB_GETVALUE(x,S_BCM1480_MC_CS3_START,M_BCM1480_MC_CS3_START)
+
+/*
+ * Chip Select End Address Register (Table 83)
+ */
+
+#define S_BCM1480_MC_CS0_END 0
+#define M_BCM1480_MC_CS0_END _SB_MAKEMASK(12,S_BCM1480_MC_CS0_END)
+#define V_BCM1480_MC_CS0_END(x) _SB_MAKEVALUE(x,S_BCM1480_MC_CS0_END)
+#define G_BCM1480_MC_CS0_END(x) _SB_GETVALUE(x,S_BCM1480_MC_CS0_END,M_BCM1480_MC_CS0_END)
+
+#define S_BCM1480_MC_CS1_END 16
+#define M_BCM1480_MC_CS1_END _SB_MAKEMASK(12,S_BCM1480_MC_CS1_END)
+#define V_BCM1480_MC_CS1_END(x) _SB_MAKEVALUE(x,S_BCM1480_MC_CS1_END)
+#define G_BCM1480_MC_CS1_END(x) _SB_GETVALUE(x,S_BCM1480_MC_CS1_END,M_BCM1480_MC_CS1_END)
+
+#define S_BCM1480_MC_CS2_END 32
+#define M_BCM1480_MC_CS2_END _SB_MAKEMASK(12,S_BCM1480_MC_CS2_END)
+#define V_BCM1480_MC_CS2_END(x) _SB_MAKEVALUE(x,S_BCM1480_MC_CS2_END)
+#define G_BCM1480_MC_CS2_END(x) _SB_GETVALUE(x,S_BCM1480_MC_CS2_END,M_BCM1480_MC_CS2_END)
+
+#define S_BCM1480_MC_CS3_END 48
+#define M_BCM1480_MC_CS3_END _SB_MAKEMASK(12,S_BCM1480_MC_CS3_END)
+#define V_BCM1480_MC_CS3_END(x) _SB_MAKEVALUE(x,S_BCM1480_MC_CS3_END)
+#define G_BCM1480_MC_CS3_END(x) _SB_GETVALUE(x,S_BCM1480_MC_CS3_END,M_BCM1480_MC_CS3_END)
+
+/*
+ * Row Address Bit Select Register 0 (Table 84)
+ */
+
+#define S_BCM1480_MC_ROW00 0
+#define M_BCM1480_MC_ROW00 _SB_MAKEMASK(6,S_BCM1480_MC_ROW00)
+#define V_BCM1480_MC_ROW00(x) _SB_MAKEVALUE(x,S_BCM1480_MC_ROW00)
+#define G_BCM1480_MC_ROW00(x) _SB_GETVALUE(x,S_BCM1480_MC_ROW00,M_BCM1480_MC_ROW00)
+
+#define S_BCM1480_MC_ROW01 8
+#define M_BCM1480_MC_ROW01 _SB_MAKEMASK(6,S_BCM1480_MC_ROW01)
+#define V_BCM1480_MC_ROW01(x) _SB_MAKEVALUE(x,S_BCM1480_MC_ROW01)
+#define G_BCM1480_MC_ROW01(x) _SB_GETVALUE(x,S_BCM1480_MC_ROW01,M_BCM1480_MC_ROW01)
+
+#define S_BCM1480_MC_ROW02 16
+#define M_BCM1480_MC_ROW02 _SB_MAKEMASK(6,S_BCM1480_MC_ROW02)
+#define V_BCM1480_MC_ROW02(x) _SB_MAKEVALUE(x,S_BCM1480_MC_ROW02)
+#define G_BCM1480_MC_ROW02(x) _SB_GETVALUE(x,S_BCM1480_MC_ROW02,M_BCM1480_MC_ROW02)
+
+#define S_BCM1480_MC_ROW03 24
+#define M_BCM1480_MC_ROW03 _SB_MAKEMASK(6,S_BCM1480_MC_ROW03)
+#define V_BCM1480_MC_ROW03(x) _SB_MAKEVALUE(x,S_BCM1480_MC_ROW03)
+#define G_BCM1480_MC_ROW03(x) _SB_GETVALUE(x,S_BCM1480_MC_ROW03,M_BCM1480_MC_ROW03)
+
+#define S_BCM1480_MC_ROW04 32
+#define M_BCM1480_MC_ROW04 _SB_MAKEMASK(6,S_BCM1480_MC_ROW04)
+#define V_BCM1480_MC_ROW04(x) _SB_MAKEVALUE(x,S_BCM1480_MC_ROW04)
+#define G_BCM1480_MC_ROW04(x) _SB_GETVALUE(x,S_BCM1480_MC_ROW04,M_BCM1480_MC_ROW04)
+
+#define S_BCM1480_MC_ROW05 40
+#define M_BCM1480_MC_ROW05 _SB_MAKEMASK(6,S_BCM1480_MC_ROW05)
+#define V_BCM1480_MC_ROW05(x) _SB_MAKEVALUE(x,S_BCM1480_MC_ROW05)
+#define G_BCM1480_MC_ROW05(x) _SB_GETVALUE(x,S_BCM1480_MC_ROW05,M_BCM1480_MC_ROW05)
+
+#define S_BCM1480_MC_ROW06 48
+#define M_BCM1480_MC_ROW06 _SB_MAKEMASK(6,S_BCM1480_MC_ROW06)
+#define V_BCM1480_MC_ROW06(x) _SB_MAKEVALUE(x,S_BCM1480_MC_ROW06)
+#define G_BCM1480_MC_ROW06(x) _SB_GETVALUE(x,S_BCM1480_MC_ROW06,M_BCM1480_MC_ROW06)
+
+#define S_BCM1480_MC_ROW07 56
+#define M_BCM1480_MC_ROW07 _SB_MAKEMASK(6,S_BCM1480_MC_ROW07)
+#define V_BCM1480_MC_ROW07(x) _SB_MAKEVALUE(x,S_BCM1480_MC_ROW07)
+#define G_BCM1480_MC_ROW07(x) _SB_GETVALUE(x,S_BCM1480_MC_ROW07,M_BCM1480_MC_ROW07)
+
+/*
+ * Row Address Bit Select Register 1 (Table 85)
+ */
+
+#define S_BCM1480_MC_ROW08 0
+#define M_BCM1480_MC_ROW08 _SB_MAKEMASK(6,S_BCM1480_MC_ROW08)
+#define V_BCM1480_MC_ROW08(x) _SB_MAKEVALUE(x,S_BCM1480_MC_ROW08)
+#define G_BCM1480_MC_ROW08(x) _SB_GETVALUE(x,S_BCM1480_MC_ROW08,M_BCM1480_MC_ROW08)
+
+#define S_BCM1480_MC_ROW09 8
+#define M_BCM1480_MC_ROW09 _SB_MAKEMASK(6,S_BCM1480_MC_ROW09)
+#define V_BCM1480_MC_ROW09(x) _SB_MAKEVALUE(x,S_BCM1480_MC_ROW09)
+#define G_BCM1480_MC_ROW09(x) _SB_GETVALUE(x,S_BCM1480_MC_ROW09,M_BCM1480_MC_ROW09)
+
+#define S_BCM1480_MC_ROW10 16
+#define M_BCM1480_MC_ROW10 _SB_MAKEMASK(6,S_BCM1480_MC_ROW10)
+#define V_BCM1480_MC_ROW10(x) _SB_MAKEVALUE(x,S_BCM1480_MC_ROW10)
+#define G_BCM1480_MC_ROW10(x) _SB_GETVALUE(x,S_BCM1480_MC_ROW10,M_BCM1480_MC_ROW10)
+
+#define S_BCM1480_MC_ROW11 24
+#define M_BCM1480_MC_ROW11 _SB_MAKEMASK(6,S_BCM1480_MC_ROW11)
+#define V_BCM1480_MC_ROW11(x) _SB_MAKEVALUE(x,S_BCM1480_MC_ROW11)
+#define G_BCM1480_MC_ROW11(x) _SB_GETVALUE(x,S_BCM1480_MC_ROW11,M_BCM1480_MC_ROW11)
+
+#define S_BCM1480_MC_ROW12 32
+#define M_BCM1480_MC_ROW12 _SB_MAKEMASK(6,S_BCM1480_MC_ROW12)
+#define V_BCM1480_MC_ROW12(x) _SB_MAKEVALUE(x,S_BCM1480_MC_ROW12)
+#define G_BCM1480_MC_ROW12(x) _SB_GETVALUE(x,S_BCM1480_MC_ROW12,M_BCM1480_MC_ROW12)
+
+#define S_BCM1480_MC_ROW13 40
+#define M_BCM1480_MC_ROW13 _SB_MAKEMASK(6,S_BCM1480_MC_ROW13)
+#define V_BCM1480_MC_ROW13(x) _SB_MAKEVALUE(x,S_BCM1480_MC_ROW13)
+#define G_BCM1480_MC_ROW13(x) _SB_GETVALUE(x,S_BCM1480_MC_ROW13,M_BCM1480_MC_ROW13)
+
+#define S_BCM1480_MC_ROW14 48
+#define M_BCM1480_MC_ROW14 _SB_MAKEMASK(6,S_BCM1480_MC_ROW14)
+#define V_BCM1480_MC_ROW14(x) _SB_MAKEVALUE(x,S_BCM1480_MC_ROW14)
+#define G_BCM1480_MC_ROW14(x) _SB_GETVALUE(x,S_BCM1480_MC_ROW14,M_BCM1480_MC_ROW14)
+
+#define K_BCM1480_MC_ROWX_BIT_SPACING 8
+
+/*
+ * Column Address Bit Select Register 0 (Table 86)
+ */
+
+#define S_BCM1480_MC_COL00 0
+#define M_BCM1480_MC_COL00 _SB_MAKEMASK(6,S_BCM1480_MC_COL00)
+#define V_BCM1480_MC_COL00(x) _SB_MAKEVALUE(x,S_BCM1480_MC_COL00)
+#define G_BCM1480_MC_COL00(x) _SB_GETVALUE(x,S_BCM1480_MC_COL00,M_BCM1480_MC_COL00)
+
+#define S_BCM1480_MC_COL01 8
+#define M_BCM1480_MC_COL01 _SB_MAKEMASK(6,S_BCM1480_MC_COL01)
+#define V_BCM1480_MC_COL01(x) _SB_MAKEVALUE(x,S_BCM1480_MC_COL01)
+#define G_BCM1480_MC_COL01(x) _SB_GETVALUE(x,S_BCM1480_MC_COL01,M_BCM1480_MC_COL01)
+
+#define S_BCM1480_MC_COL02 16
+#define M_BCM1480_MC_COL02 _SB_MAKEMASK(6,S_BCM1480_MC_COL02)
+#define V_BCM1480_MC_COL02(x) _SB_MAKEVALUE(x,S_BCM1480_MC_COL02)
+#define G_BCM1480_MC_COL02(x) _SB_GETVALUE(x,S_BCM1480_MC_COL02,M_BCM1480_MC_COL02)
+
+#define S_BCM1480_MC_COL03 24
+#define M_BCM1480_MC_COL03 _SB_MAKEMASK(6,S_BCM1480_MC_COL03)
+#define V_BCM1480_MC_COL03(x) _SB_MAKEVALUE(x,S_BCM1480_MC_COL03)
+#define G_BCM1480_MC_COL03(x) _SB_GETVALUE(x,S_BCM1480_MC_COL03,M_BCM1480_MC_COL03)
+
+#define S_BCM1480_MC_COL04 32
+#define M_BCM1480_MC_COL04 _SB_MAKEMASK(6,S_BCM1480_MC_COL04)
+#define V_BCM1480_MC_COL04(x) _SB_MAKEVALUE(x,S_BCM1480_MC_COL04)
+#define G_BCM1480_MC_COL04(x) _SB_GETVALUE(x,S_BCM1480_MC_COL04,M_BCM1480_MC_COL04)
+
+#define S_BCM1480_MC_COL05 40
+#define M_BCM1480_MC_COL05 _SB_MAKEMASK(6,S_BCM1480_MC_COL05)
+#define V_BCM1480_MC_COL05(x) _SB_MAKEVALUE(x,S_BCM1480_MC_COL05)
+#define G_BCM1480_MC_COL05(x) _SB_GETVALUE(x,S_BCM1480_MC_COL05,M_BCM1480_MC_COL05)
+
+#define S_BCM1480_MC_COL06 48
+#define M_BCM1480_MC_COL06 _SB_MAKEMASK(6,S_BCM1480_MC_COL06)
+#define V_BCM1480_MC_COL06(x) _SB_MAKEVALUE(x,S_BCM1480_MC_COL06)
+#define G_BCM1480_MC_COL06(x) _SB_GETVALUE(x,S_BCM1480_MC_COL06,M_BCM1480_MC_COL06)
+
+#define S_BCM1480_MC_COL07 56
+#define M_BCM1480_MC_COL07 _SB_MAKEMASK(6,S_BCM1480_MC_COL07)
+#define V_BCM1480_MC_COL07(x) _SB_MAKEVALUE(x,S_BCM1480_MC_COL07)
+#define G_BCM1480_MC_COL07(x) _SB_GETVALUE(x,S_BCM1480_MC_COL07,M_BCM1480_MC_COL07)
+
+/*
+ * Column Address Bit Select Register 1 (Table 87)
+ */
+
+#define S_BCM1480_MC_COL08 0
+#define M_BCM1480_MC_COL08 _SB_MAKEMASK(6,S_BCM1480_MC_COL08)
+#define V_BCM1480_MC_COL08(x) _SB_MAKEVALUE(x,S_BCM1480_MC_COL08)
+#define G_BCM1480_MC_COL08(x) _SB_GETVALUE(x,S_BCM1480_MC_COL08,M_BCM1480_MC_COL08)
+
+#define S_BCM1480_MC_COL09 8
+#define M_BCM1480_MC_COL09 _SB_MAKEMASK(6,S_BCM1480_MC_COL09)
+#define V_BCM1480_MC_COL09(x) _SB_MAKEVALUE(x,S_BCM1480_MC_COL09)
+#define G_BCM1480_MC_COL09(x) _SB_GETVALUE(x,S_BCM1480_MC_COL09,M_BCM1480_MC_COL09)
+
+#define S_BCM1480_MC_COL10 16 /* not a valid position, must be prog as 0 */
+
+#define S_BCM1480_MC_COL11 24
+#define M_BCM1480_MC_COL11 _SB_MAKEMASK(6,S_BCM1480_MC_COL11)
+#define V_BCM1480_MC_COL11(x) _SB_MAKEVALUE(x,S_BCM1480_MC_COL11)
+#define G_BCM1480_MC_COL11(x) _SB_GETVALUE(x,S_BCM1480_MC_COL11,M_BCM1480_MC_COL11)
+
+#define S_BCM1480_MC_COL12 32
+#define M_BCM1480_MC_COL12 _SB_MAKEMASK(6,S_BCM1480_MC_COL12)
+#define V_BCM1480_MC_COL12(x) _SB_MAKEVALUE(x,S_BCM1480_MC_COL12)
+#define G_BCM1480_MC_COL12(x) _SB_GETVALUE(x,S_BCM1480_MC_COL12,M_BCM1480_MC_COL12)
+
+#define S_BCM1480_MC_COL13 40
+#define M_BCM1480_MC_COL13 _SB_MAKEMASK(6,S_BCM1480_MC_COL13)
+#define V_BCM1480_MC_COL13(x) _SB_MAKEVALUE(x,S_BCM1480_MC_COL13)
+#define G_BCM1480_MC_COL13(x) _SB_GETVALUE(x,S_BCM1480_MC_COL13,M_BCM1480_MC_COL13)
+
+#define S_BCM1480_MC_COL14 48
+#define M_BCM1480_MC_COL14 _SB_MAKEMASK(6,S_BCM1480_MC_COL14)
+#define V_BCM1480_MC_COL14(x) _SB_MAKEVALUE(x,S_BCM1480_MC_COL14)
+#define G_BCM1480_MC_COL14(x) _SB_GETVALUE(x,S_BCM1480_MC_COL14,M_BCM1480_MC_COL14)
+
+#define K_BCM1480_MC_COLX_BIT_SPACING 8
+
+/*
+ * CS0 and CS1 Bank Address Bit Select Register (Table 88)
+ */
+
+#define S_BCM1480_MC_CS01_BANK0 0
+#define M_BCM1480_MC_CS01_BANK0 _SB_MAKEMASK(6,S_BCM1480_MC_CS01_BANK0)
+#define V_BCM1480_MC_CS01_BANK0(x) _SB_MAKEVALUE(x,S_BCM1480_MC_CS01_BANK0)
+#define G_BCM1480_MC_CS01_BANK0(x) _SB_GETVALUE(x,S_BCM1480_MC_CS01_BANK0,M_BCM1480_MC_CS01_BANK0)
+
+#define S_BCM1480_MC_CS01_BANK1 8
+#define M_BCM1480_MC_CS01_BANK1 _SB_MAKEMASK(6,S_BCM1480_MC_CS01_BANK1)
+#define V_BCM1480_MC_CS01_BANK1(x) _SB_MAKEVALUE(x,S_BCM1480_MC_CS01_BANK1)
+#define G_BCM1480_MC_CS01_BANK1(x) _SB_GETVALUE(x,S_BCM1480_MC_CS01_BANK1,M_BCM1480_MC_CS01_BANK1)
+
+#define S_BCM1480_MC_CS01_BANK2 16
+#define M_BCM1480_MC_CS01_BANK2 _SB_MAKEMASK(6,S_BCM1480_MC_CS01_BANK2)
+#define V_BCM1480_MC_CS01_BANK2(x) _SB_MAKEVALUE(x,S_BCM1480_MC_CS01_BANK2)
+#define G_BCM1480_MC_CS01_BANK2(x) _SB_GETVALUE(x,S_BCM1480_MC_CS01_BANK2,M_BCM1480_MC_CS01_BANK2)
+
+/*
+ * CS2 and CS3 Bank Address Bit Select Register (Table 89)
+ */
+
+#define S_BCM1480_MC_CS23_BANK0 0
+#define M_BCM1480_MC_CS23_BANK0 _SB_MAKEMASK(6,S_BCM1480_MC_CS23_BANK0)
+#define V_BCM1480_MC_CS23_BANK0(x) _SB_MAKEVALUE(x,S_BCM1480_MC_CS23_BANK0)
+#define G_BCM1480_MC_CS23_BANK0(x) _SB_GETVALUE(x,S_BCM1480_MC_CS23_BANK0,M_BCM1480_MC_CS23_BANK0)
+
+#define S_BCM1480_MC_CS23_BANK1 8
+#define M_BCM1480_MC_CS23_BANK1 _SB_MAKEMASK(6,S_BCM1480_MC_CS23_BANK1)
+#define V_BCM1480_MC_CS23_BANK1(x) _SB_MAKEVALUE(x,S_BCM1480_MC_CS23_BANK1)
+#define G_BCM1480_MC_CS23_BANK1(x) _SB_GETVALUE(x,S_BCM1480_MC_CS23_BANK1,M_BCM1480_MC_CS23_BANK1)
+
+#define S_BCM1480_MC_CS23_BANK2 16
+#define M_BCM1480_MC_CS23_BANK2 _SB_MAKEMASK(6,S_BCM1480_MC_CS23_BANK2)
+#define V_BCM1480_MC_CS23_BANK2(x) _SB_MAKEVALUE(x,S_BCM1480_MC_CS23_BANK2)
+#define G_BCM1480_MC_CS23_BANK2(x) _SB_GETVALUE(x,S_BCM1480_MC_CS23_BANK2,M_BCM1480_MC_CS23_BANK2)
+
+#define K_BCM1480_MC_CSXX_BANKX_BIT_SPACING 8
+
+/*
+ * DRAM Command Register (Table 90)
+ */
+
+#define S_BCM1480_MC_COMMAND 0
+#define M_BCM1480_MC_COMMAND _SB_MAKEMASK(4,S_BCM1480_MC_COMMAND)
+#define V_BCM1480_MC_COMMAND(x) _SB_MAKEVALUE(x,S_BCM1480_MC_COMMAND)
+#define G_BCM1480_MC_COMMAND(x) _SB_GETVALUE(x,S_BCM1480_MC_COMMAND,M_BCM1480_MC_COMMAND)
+
+#define K_BCM1480_MC_COMMAND_EMRS 0
+#define K_BCM1480_MC_COMMAND_MRS 1
+#define K_BCM1480_MC_COMMAND_PRE 2
+#define K_BCM1480_MC_COMMAND_AR 3
+#define K_BCM1480_MC_COMMAND_SETRFSH 4
+#define K_BCM1480_MC_COMMAND_CLRRFSH 5
+#define K_BCM1480_MC_COMMAND_SETPWRDN 6
+#define K_BCM1480_MC_COMMAND_CLRPWRDN 7
+
+#if SIBYTE_HDR_FEATURE(1480, PASS2)
+#define K_BCM1480_MC_COMMAND_EMRS2 8
+#define K_BCM1480_MC_COMMAND_EMRS3 9
+#define K_BCM1480_MC_COMMAND_ENABLE_MCLK 10
+#define K_BCM1480_MC_COMMAND_DISABLE_MCLK 11
+#endif
+
+#define V_BCM1480_MC_COMMAND_EMRS V_BCM1480_MC_COMMAND(K_BCM1480_MC_COMMAND_EMRS)
+#define V_BCM1480_MC_COMMAND_MRS V_BCM1480_MC_COMMAND(K_BCM1480_MC_COMMAND_MRS)
+#define V_BCM1480_MC_COMMAND_PRE V_BCM1480_MC_COMMAND(K_BCM1480_MC_COMMAND_PRE)
+#define V_BCM1480_MC_COMMAND_AR V_BCM1480_MC_COMMAND(K_BCM1480_MC_COMMAND_AR)
+#define V_BCM1480_MC_COMMAND_SETRFSH V_BCM1480_MC_COMMAND(K_BCM1480_MC_COMMAND_SETRFSH)
+#define V_BCM1480_MC_COMMAND_CLRRFSH V_BCM1480_MC_COMMAND(K_BCM1480_MC_COMMAND_CLRRFSH)
+#define V_BCM1480_MC_COMMAND_SETPWRDN V_BCM1480_MC_COMMAND(K_BCM1480_MC_COMMAND_SETPWRDN)
+#define V_BCM1480_MC_COMMAND_CLRPWRDN V_BCM1480_MC_COMMAND(K_BCM1480_MC_COMMAND_CLRPWRDN)
+
+#if SIBYTE_HDR_FEATURE(1480, PASS2)
+#define V_BCM1480_MC_COMMAND_EMRS2 V_BCM1480_MC_COMMAND(K_BCM1480_MC_COMMAND_EMRS2)
+#define V_BCM1480_MC_COMMAND_EMRS3 V_BCM1480_MC_COMMAND(K_BCM1480_MC_COMMAND_EMRS3)
+#define V_BCM1480_MC_COMMAND_ENABLE_MCLK V_BCM1480_MC_COMMAND(K_BCM1480_MC_COMMAND_ENABLE_MCLK)
+#define V_BCM1480_MC_COMMAND_DISABLE_MCLK V_BCM1480_MC_COMMAND(K_BCM1480_MC_COMMAND_DISABLE_MCLK)
+#endif
+
+#define S_BCM1480_MC_CS0 4
+#define M_BCM1480_MC_CS0 _SB_MAKEMASK1(4)
+#define M_BCM1480_MC_CS1 _SB_MAKEMASK1(5)
+#define M_BCM1480_MC_CS2 _SB_MAKEMASK1(6)
+#define M_BCM1480_MC_CS3 _SB_MAKEMASK1(7)
+#define M_BCM1480_MC_CS4 _SB_MAKEMASK1(8)
+#define M_BCM1480_MC_CS5 _SB_MAKEMASK1(9)
+#define M_BCM1480_MC_CS6 _SB_MAKEMASK1(10)
+#define M_BCM1480_MC_CS7 _SB_MAKEMASK1(11)
+
+#define M_BCM1480_MC_CMD_ACTIVE _SB_MAKEMASK1(16)
+
+/*
+ * DRAM Mode Register (Table 91)
+ */
+
+#define S_BCM1480_MC_EMODE 0
+#define M_BCM1480_MC_EMODE _SB_MAKEMASK(15,S_BCM1480_MC_EMODE)
+#define V_BCM1480_MC_EMODE(x) _SB_MAKEVALUE(x,S_BCM1480_MC_EMODE)
+#define G_BCM1480_MC_EMODE(x) _SB_GETVALUE(x,S_BCM1480_MC_EMODE,M_BCM1480_MC_EMODE)
+#define V_BCM1480_MC_EMODE_DEFAULT V_BCM1480_MC_EMODE(0)
+
+#define S_BCM1480_MC_MODE 16
+#define M_BCM1480_MC_MODE _SB_MAKEMASK(15,S_BCM1480_MC_MODE)
+#define V_BCM1480_MC_MODE(x) _SB_MAKEVALUE(x,S_BCM1480_MC_MODE)
+#define G_BCM1480_MC_MODE(x) _SB_GETVALUE(x,S_BCM1480_MC_MODE,M_BCM1480_MC_MODE)
+#define V_BCM1480_MC_MODE_DEFAULT V_BCM1480_MC_MODE(0)
+
+#define S_BCM1480_MC_DRAM_TYPE 32
+#define M_BCM1480_MC_DRAM_TYPE _SB_MAKEMASK(4,S_BCM1480_MC_DRAM_TYPE)
+#define V_BCM1480_MC_DRAM_TYPE(x) _SB_MAKEVALUE(x,S_BCM1480_MC_DRAM_TYPE)
+#define G_BCM1480_MC_DRAM_TYPE(x) _SB_GETVALUE(x,S_BCM1480_MC_DRAM_TYPE,M_BCM1480_MC_DRAM_TYPE)
+
+#define K_BCM1480_MC_DRAM_TYPE_JEDEC 0
+#define K_BCM1480_MC_DRAM_TYPE_FCRAM 1
+
+#if SIBYTE_HDR_FEATURE(1480, PASS2)
+#define K_BCM1480_MC_DRAM_TYPE_DDR2 2
+#endif
+
+#define V_BCM1480_MC_DRAM_TYPE_JEDEC V_BCM1480_MC_DRAM_TYPE(K_BCM1480_MC_DRAM_TYPE_JEDEC)
+#define V_BCM1480_MC_DRAM_TYPE_FCRAM V_BCM1480_MC_DRAM_TYPE(K_BCM1480_MC_DRAM_TYPE_FCRAM)
+
+#if SIBYTE_HDR_FEATURE(1480, PASS2)
+#define V_BCM1480_MC_DRAM_TYPE_DDR2 V_BCM1480_MC_DRAM_TYPE(K_BCM1480_MC_DRAM_TYPE_DDR2)
+#endif
+
+#define M_BCM1480_MC_GANGED _SB_MAKEMASK1(36)
+#define M_BCM1480_MC_BY9_INTF _SB_MAKEMASK1(37)
+#define M_BCM1480_MC_FORCE_ECC64 _SB_MAKEMASK1(38)
+#define M_BCM1480_MC_ECC_DISABLE _SB_MAKEMASK1(39)
+
+#define S_BCM1480_MC_PG_POLICY 40
+#define M_BCM1480_MC_PG_POLICY _SB_MAKEMASK(2,S_BCM1480_MC_PG_POLICY)
+#define V_BCM1480_MC_PG_POLICY(x) _SB_MAKEVALUE(x,S_BCM1480_MC_PG_POLICY)
+#define G_BCM1480_MC_PG_POLICY(x) _SB_GETVALUE(x,S_BCM1480_MC_PG_POLICY,M_BCM1480_MC_PG_POLICY)
+
+#define K_BCM1480_MC_PG_POLICY_CLOSED 0
+#define K_BCM1480_MC_PG_POLICY_CAS_TIME_CHK 1
+
+#define V_BCM1480_MC_PG_POLICY_CLOSED V_BCM1480_MC_PG_POLICY(K_BCM1480_MC_PG_POLICY_CLOSED)
+#define V_BCM1480_MC_PG_POLICY_CAS_TIME_CHK V_BCM1480_MC_PG_POLICY(K_BCM1480_MC_PG_POLICY_CAS_TIME_CHK)
+
+#if SIBYTE_HDR_FEATURE(1480, PASS2)
+#define M_BCM1480_MC_2T_CMD _SB_MAKEMASK1(42)
+#define M_BCM1480_MC_ECC_COR_DIS _SB_MAKEMASK1(43)
+#endif
+
+#define V_BCM1480_MC_DRAMMODE_DEFAULT V_BCM1480_MC_EMODE_DEFAULT | V_BCM1480_MC_MODE_DEFAULT | V_BCM1480_MC_DRAM_TYPE_JEDEC | \
+ V_BCM1480_MC_PG_POLICY(K_BCM1480_MC_PG_POLICY_CAS_TIME_CHK)
+
+/*
+ * Memory Clock Configuration Register (Table 92)
+ */
+
+#define S_BCM1480_MC_CLK_RATIO 0
+#define M_BCM1480_MC_CLK_RATIO _SB_MAKEMASK(6,S_BCM1480_MC_CLK_RATIO)
+#define V_BCM1480_MC_CLK_RATIO(x) _SB_MAKEVALUE(x,S_BCM1480_MC_CLK_RATIO)
+#define G_BCM1480_MC_CLK_RATIO(x) _SB_GETVALUE(x,S_BCM1480_MC_CLK_RATIO,M_BCM1480_MC_CLK_RATIO)
+
+#define V_BCM1480_MC_CLK_RATIO_DEFAULT V_BCM1480_MC_CLK_RATIO(10)
+
+#define S_BCM1480_MC_REF_RATE 8
+#define M_BCM1480_MC_REF_RATE _SB_MAKEMASK(8,S_BCM1480_MC_REF_RATE)
+#define V_BCM1480_MC_REF_RATE(x) _SB_MAKEVALUE(x,S_BCM1480_MC_REF_RATE)
+#define G_BCM1480_MC_REF_RATE(x) _SB_GETVALUE(x,S_BCM1480_MC_REF_RATE,M_BCM1480_MC_REF_RATE)
+
+#define K_BCM1480_MC_REF_RATE_100MHz 0x31
+#define K_BCM1480_MC_REF_RATE_200MHz 0x62
+#define K_BCM1480_MC_REF_RATE_400MHz 0xC4
+
+#define V_BCM1480_MC_REF_RATE_100MHz V_BCM1480_MC_REF_RATE(K_BCM1480_MC_REF_RATE_100MHz)
+#define V_BCM1480_MC_REF_RATE_200MHz V_BCM1480_MC_REF_RATE(K_BCM1480_MC_REF_RATE_200MHz)
+#define V_BCM1480_MC_REF_RATE_400MHz V_BCM1480_MC_REF_RATE(K_BCM1480_MC_REF_RATE_400MHz)
+#define V_BCM1480_MC_REF_RATE_DEFAULT V_BCM1480_MC_REF_RATE_400MHz
+
+#if SIBYTE_HDR_FEATURE(1480, PASS2)
+#define M_BCM1480_MC_AUTO_REF_DIS _SB_MAKEMASK1(16)
+#endif
+
+/*
+ * ODT Register (Table 99)
+ */
+
+#if SIBYTE_HDR_FEATURE(1480, PASS2)
+#define M_BCM1480_MC_RD_ODT0_CS0 _SB_MAKEMASK1(0)
+#define M_BCM1480_MC_RD_ODT0_CS2 _SB_MAKEMASK1(1)
+#define M_BCM1480_MC_RD_ODT0_CS4 _SB_MAKEMASK1(2)
+#define M_BCM1480_MC_RD_ODT0_CS6 _SB_MAKEMASK1(3)
+#define M_BCM1480_MC_WR_ODT0_CS0 _SB_MAKEMASK1(4)
+#define M_BCM1480_MC_WR_ODT0_CS2 _SB_MAKEMASK1(5)
+#define M_BCM1480_MC_WR_ODT0_CS4 _SB_MAKEMASK1(6)
+#define M_BCM1480_MC_WR_ODT0_CS6 _SB_MAKEMASK1(7)
+#define M_BCM1480_MC_RD_ODT2_CS0 _SB_MAKEMASK1(8)
+#define M_BCM1480_MC_RD_ODT2_CS2 _SB_MAKEMASK1(9)
+#define M_BCM1480_MC_RD_ODT2_CS4 _SB_MAKEMASK1(10)
+#define M_BCM1480_MC_RD_ODT2_CS6 _SB_MAKEMASK1(11)
+#define M_BCM1480_MC_WR_ODT2_CS0 _SB_MAKEMASK1(12)
+#define M_BCM1480_MC_WR_ODT2_CS2 _SB_MAKEMASK1(13)
+#define M_BCM1480_MC_WR_ODT2_CS4 _SB_MAKEMASK1(14)
+#define M_BCM1480_MC_WR_ODT2_CS6 _SB_MAKEMASK1(15)
+#define M_BCM1480_MC_RD_ODT4_CS0 _SB_MAKEMASK1(16)
+#define M_BCM1480_MC_RD_ODT4_CS2 _SB_MAKEMASK1(17)
+#define M_BCM1480_MC_RD_ODT4_CS4 _SB_MAKEMASK1(18)
+#define M_BCM1480_MC_RD_ODT4_CS6 _SB_MAKEMASK1(19)
+#define M_BCM1480_MC_WR_ODT4_CS0 _SB_MAKEMASK1(20)
+#define M_BCM1480_MC_WR_ODT4_CS2 _SB_MAKEMASK1(21)
+#define M_BCM1480_MC_WR_ODT4_CS4 _SB_MAKEMASK1(22)
+#define M_BCM1480_MC_WR_ODT4_CS6 _SB_MAKEMASK1(23)
+#define M_BCM1480_MC_RD_ODT6_CS0 _SB_MAKEMASK1(24)
+#define M_BCM1480_MC_RD_ODT6_CS2 _SB_MAKEMASK1(25)
+#define M_BCM1480_MC_RD_ODT6_CS4 _SB_MAKEMASK1(26)
+#define M_BCM1480_MC_RD_ODT6_CS6 _SB_MAKEMASK1(27)
+#define M_BCM1480_MC_WR_ODT6_CS0 _SB_MAKEMASK1(28)
+#define M_BCM1480_MC_WR_ODT6_CS2 _SB_MAKEMASK1(29)
+#define M_BCM1480_MC_WR_ODT6_CS4 _SB_MAKEMASK1(30)
+#define M_BCM1480_MC_WR_ODT6_CS6 _SB_MAKEMASK1(31)
+
+#define M_BCM1480_MC_CS_ODD_ODT_EN _SB_MAKEMASK1(32)
+#endif
+
+/*
+ * Memory DLL Configuration Register (Table 93)
+ */
+
+#define S_BCM1480_MC_ADDR_COARSE_ADJ 0
+#define M_BCM1480_MC_ADDR_COARSE_ADJ _SB_MAKEMASK(6,S_BCM1480_MC_ADDR_COARSE_ADJ)
+#define V_BCM1480_MC_ADDR_COARSE_ADJ(x) _SB_MAKEVALUE(x,S_BCM1480_MC_ADDR_COARSE_ADJ)
+#define G_BCM1480_MC_ADDR_COARSE_ADJ(x) _SB_GETVALUE(x,S_BCM1480_MC_ADDR_COARSE_ADJ,M_BCM1480_MC_ADDR_COARSE_ADJ)
+#define V_BCM1480_MC_ADDR_COARSE_ADJ_DEFAULT V_BCM1480_MC_ADDR_COARSE_ADJ(0x0)
+
+#if SIBYTE_HDR_FEATURE(1480, PASS2)
+#define S_BCM1480_MC_ADDR_FREQ_RANGE 8
+#define M_BCM1480_MC_ADDR_FREQ_RANGE _SB_MAKEMASK(4,S_BCM1480_MC_ADDR_FREQ_RANGE)
+#define V_BCM1480_MC_ADDR_FREQ_RANGE(x) _SB_MAKEVALUE(x,S_BCM1480_MC_ADDR_FREQ_RANGE)
+#define G_BCM1480_MC_ADDR_FREQ_RANGE(x) _SB_GETVALUE(x,S_BCM1480_MC_ADDR_FREQ_RANGE,M_BCM1480_MC_ADDR_FREQ_RANGE)
+#define V_BCM1480_MC_ADDR_FREQ_RANGE_DEFAULT V_BCM1480_MC_ADDR_FREQ_RANGE(0x4)
+#endif
+
+#define S_BCM1480_MC_ADDR_FINE_ADJ 8
+#define M_BCM1480_MC_ADDR_FINE_ADJ _SB_MAKEMASK(4,S_BCM1480_MC_ADDR_FINE_ADJ)
+#define V_BCM1480_MC_ADDR_FINE_ADJ(x) _SB_MAKEVALUE(x,S_BCM1480_MC_ADDR_FINE_ADJ)
+#define G_BCM1480_MC_ADDR_FINE_ADJ(x) _SB_GETVALUE(x,S_BCM1480_MC_ADDR_FINE_ADJ,M_BCM1480_MC_ADDR_FINE_ADJ)
+#define V_BCM1480_MC_ADDR_FINE_ADJ_DEFAULT V_BCM1480_MC_ADDR_FINE_ADJ(0x8)
+
+#define S_BCM1480_MC_DQI_COARSE_ADJ 16
+#define M_BCM1480_MC_DQI_COARSE_ADJ _SB_MAKEMASK(6,S_BCM1480_MC_DQI_COARSE_ADJ)
+#define V_BCM1480_MC_DQI_COARSE_ADJ(x) _SB_MAKEVALUE(x,S_BCM1480_MC_DQI_COARSE_ADJ)
+#define G_BCM1480_MC_DQI_COARSE_ADJ(x) _SB_GETVALUE(x,S_BCM1480_MC_DQI_COARSE_ADJ,M_BCM1480_MC_DQI_COARSE_ADJ)
+#define V_BCM1480_MC_DQI_COARSE_ADJ_DEFAULT V_BCM1480_MC_DQI_COARSE_ADJ(0x0)
+
+#if SIBYTE_HDR_FEATURE(1480, PASS2)
+#define S_BCM1480_MC_DQI_FREQ_RANGE 24
+#define M_BCM1480_MC_DQI_FREQ_RANGE _SB_MAKEMASK(4,S_BCM1480_MC_DQI_FREQ_RANGE)
+#define V_BCM1480_MC_DQI_FREQ_RANGE(x) _SB_MAKEVALUE(x,S_BCM1480_MC_DQI_FREQ_RANGE)
+#define G_BCM1480_MC_DQI_FREQ_RANGE(x) _SB_GETVALUE(x,S_BCM1480_MC_DQI_FREQ_RANGE,M_BCM1480_MC_DQI_FREQ_RANGE)
+#define V_BCM1480_MC_DQI_FREQ_RANGE_DEFAULT V_BCM1480_MC_DQI_FREQ_RANGE(0x4)
+#endif
+
+#define S_BCM1480_MC_DQI_FINE_ADJ 24
+#define M_BCM1480_MC_DQI_FINE_ADJ _SB_MAKEMASK(4,S_BCM1480_MC_DQI_FINE_ADJ)
+#define V_BCM1480_MC_DQI_FINE_ADJ(x) _SB_MAKEVALUE(x,S_BCM1480_MC_DQI_FINE_ADJ)
+#define G_BCM1480_MC_DQI_FINE_ADJ(x) _SB_GETVALUE(x,S_BCM1480_MC_DQI_FINE_ADJ,M_BCM1480_MC_DQI_FINE_ADJ)
+#define V_BCM1480_MC_DQI_FINE_ADJ_DEFAULT V_BCM1480_MC_DQI_FINE_ADJ(0x8)
+
+#define S_BCM1480_MC_DQO_COARSE_ADJ 32
+#define M_BCM1480_MC_DQO_COARSE_ADJ _SB_MAKEMASK(6,S_BCM1480_MC_DQO_COARSE_ADJ)
+#define V_BCM1480_MC_DQO_COARSE_ADJ(x) _SB_MAKEVALUE(x,S_BCM1480_MC_DQO_COARSE_ADJ)
+#define G_BCM1480_MC_DQO_COARSE_ADJ(x) _SB_GETVALUE(x,S_BCM1480_MC_DQO_COARSE_ADJ,M_BCM1480_MC_DQO_COARSE_ADJ)
+#define V_BCM1480_MC_DQO_COARSE_ADJ_DEFAULT V_BCM1480_MC_DQO_COARSE_ADJ(0x0)
+
+#if SIBYTE_HDR_FEATURE(1480, PASS2)
+#define S_BCM1480_MC_DQO_FREQ_RANGE 40
+#define M_BCM1480_MC_DQO_FREQ_RANGE _SB_MAKEMASK(4,S_BCM1480_MC_DQO_FREQ_RANGE)
+#define V_BCM1480_MC_DQO_FREQ_RANGE(x) _SB_MAKEVALUE(x,S_BCM1480_MC_DQO_FREQ_RANGE)
+#define G_BCM1480_MC_DQO_FREQ_RANGE(x) _SB_GETVALUE(x,S_BCM1480_MC_DQO_FREQ_RANGE,M_BCM1480_MC_DQO_FREQ_RANGE)
+#define V_BCM1480_MC_DQO_FREQ_RANGE_DEFAULT V_BCM1480_MC_DQO_FREQ_RANGE(0x4)
+#endif
+
+#define S_BCM1480_MC_DQO_FINE_ADJ 40
+#define M_BCM1480_MC_DQO_FINE_ADJ _SB_MAKEMASK(4,S_BCM1480_MC_DQO_FINE_ADJ)
+#define V_BCM1480_MC_DQO_FINE_ADJ(x) _SB_MAKEVALUE(x,S_BCM1480_MC_DQO_FINE_ADJ)
+#define G_BCM1480_MC_DQO_FINE_ADJ(x) _SB_GETVALUE(x,S_BCM1480_MC_DQO_FINE_ADJ,M_BCM1480_MC_DQO_FINE_ADJ)
+#define V_BCM1480_MC_DQO_FINE_ADJ_DEFAULT V_BCM1480_MC_DQO_FINE_ADJ(0x8)
+
+#if SIBYTE_HDR_FEATURE(1480, PASS2)
+#define S_BCM1480_MC_DLL_PDSEL 44
+#define M_BCM1480_MC_DLL_PDSEL _SB_MAKEMASK(2,S_BCM1480_MC_DLL_PDSEL)
+#define V_BCM1480_MC_DLL_PDSEL(x) _SB_MAKEVALUE(x,S_BCM1480_MC_DLL_PDSEL)
+#define G_BCM1480_MC_DLL_PDSEL(x) _SB_GETVALUE(x,S_BCM1480_MC_DLL_PDSEL,M_BCM1480_MC_DLL_PDSEL)
+#define V_BCM1480_MC_DLL_DEFAULT_PDSEL V_BCM1480_MC_DLL_PDSEL(0x0)
+
+#define M_BCM1480_MC_DLL_REGBYPASS _SB_MAKEMASK1(46)
+#define M_BCM1480_MC_DQO_SHIFT _SB_MAKEMASK1(47)
+#endif
+
+#define S_BCM1480_MC_DLL_DEFAULT 48
+#define M_BCM1480_MC_DLL_DEFAULT _SB_MAKEMASK(6,S_BCM1480_MC_DLL_DEFAULT)
+#define V_BCM1480_MC_DLL_DEFAULT(x) _SB_MAKEVALUE(x,S_BCM1480_MC_DLL_DEFAULT)
+#define G_BCM1480_MC_DLL_DEFAULT(x) _SB_GETVALUE(x,S_BCM1480_MC_DLL_DEFAULT,M_BCM1480_MC_DLL_DEFAULT)
+#define V_BCM1480_MC_DLL_DEFAULT_DEFAULT V_BCM1480_MC_DLL_DEFAULT(0x10)
+
+#if SIBYTE_HDR_FEATURE(1480, PASS2)
+#define S_BCM1480_MC_DLL_REGCTRL 54
+#define M_BCM1480_MC_DLL_REGCTRL _SB_MAKEMASK(2,S_BCM1480_MC_DLL_REGCTRL)
+#define V_BCM1480_MC_DLL_REGCTRL(x) _SB_MAKEVALUE(x,S_BCM1480_MC_DLL_REGCTRL)
+#define G_BCM1480_MC_DLL_REGCTRL(x) _SB_GETVALUE(x,S_BCM1480_MC_DLL_REGCTRL,M_BCM1480_MC_DLL_REGCTRL)
+#define V_BCM1480_MC_DLL_DEFAULT_REGCTRL V_BCM1480_MC_DLL_REGCTRL(0x0)
+#endif
+
+#if SIBYTE_HDR_FEATURE(1480, PASS2)
+#define S_BCM1480_MC_DLL_FREQ_RANGE 56
+#define M_BCM1480_MC_DLL_FREQ_RANGE _SB_MAKEMASK(4,S_BCM1480_MC_DLL_FREQ_RANGE)
+#define V_BCM1480_MC_DLL_FREQ_RANGE(x) _SB_MAKEVALUE(x,S_BCM1480_MC_DLL_FREQ_RANGE)
+#define G_BCM1480_MC_DLL_FREQ_RANGE(x) _SB_GETVALUE(x,S_BCM1480_MC_DLL_FREQ_RANGE,M_BCM1480_MC_DLL_FREQ_RANGE)
+#define V_BCM1480_MC_DLL_FREQ_RANGE_DEFAULT V_BCM1480_MC_DLL_FREQ_RANGE(0x4)
+#endif
+
+#define S_BCM1480_MC_DLL_STEP_SIZE 56
+#define M_BCM1480_MC_DLL_STEP_SIZE _SB_MAKEMASK(4,S_BCM1480_MC_DLL_STEP_SIZE)
+#define V_BCM1480_MC_DLL_STEP_SIZE(x) _SB_MAKEVALUE(x,S_BCM1480_MC_DLL_STEP_SIZE)
+#define G_BCM1480_MC_DLL_STEP_SIZE(x) _SB_GETVALUE(x,S_BCM1480_MC_DLL_STEP_SIZE,M_BCM1480_MC_DLL_STEP_SIZE)
+#define V_BCM1480_MC_DLL_STEP_SIZE_DEFAULT V_BCM1480_MC_DLL_STEP_SIZE(0x8)
+
+#if SIBYTE_HDR_FEATURE(1480, PASS2)
+#define S_BCM1480_MC_DLL_BGCTRL 60
+#define M_BCM1480_MC_DLL_BGCTRL _SB_MAKEMASK(2,S_BCM1480_MC_DLL_BGCTRL)
+#define V_BCM1480_MC_DLL_BGCTRL(x) _SB_MAKEVALUE(x,S_BCM1480_MC_DLL_BGCTRL)
+#define G_BCM1480_MC_DLL_BGCTRL(x) _SB_GETVALUE(x,S_BCM1480_MC_DLL_BGCTRL,M_BCM1480_MC_DLL_BGCTRL)
+#define V_BCM1480_MC_DLL_DEFAULT_BGCTRL V_BCM1480_MC_DLL_BGCTRL(0x0)
+#endif
+
+#define M_BCM1480_MC_DLL_BYPASS _SB_MAKEMASK1(63)
+
+/*
+ * Memory Drive Configuration Register (Table 94)
+ */
+
+#define S_BCM1480_MC_RTT_BYP_PULLDOWN 0
+#define M_BCM1480_MC_RTT_BYP_PULLDOWN _SB_MAKEMASK(3,S_BCM1480_MC_RTT_BYP_PULLDOWN)
+#define V_BCM1480_MC_RTT_BYP_PULLDOWN(x) _SB_MAKEVALUE(x,S_BCM1480_MC_RTT_BYP_PULLDOWN)
+#define G_BCM1480_MC_RTT_BYP_PULLDOWN(x) _SB_GETVALUE(x,S_BCM1480_MC_RTT_BYP_PULLDOWN,M_BCM1480_MC_RTT_BYP_PULLDOWN)
+
+#define S_BCM1480_MC_RTT_BYP_PULLUP 6
+#define M_BCM1480_MC_RTT_BYP_PULLUP _SB_MAKEMASK(3,S_BCM1480_MC_RTT_BYP_PULLUP)
+#define V_BCM1480_MC_RTT_BYP_PULLUP(x) _SB_MAKEVALUE(x,S_BCM1480_MC_RTT_BYP_PULLUP)
+#define G_BCM1480_MC_RTT_BYP_PULLUP(x) _SB_GETVALUE(x,S_BCM1480_MC_RTT_BYP_PULLUP,M_BCM1480_MC_RTT_BYP_PULLUP)
+
+#define M_BCM1480_MC_RTT_BYPASS _SB_MAKEMASK1(8)
+#define M_BCM1480_MC_RTT_COMP_MOV_AVG _SB_MAKEMASK1(9)
+
+#define S_BCM1480_MC_PVT_BYP_C1_PULLDOWN 10
+#define M_BCM1480_MC_PVT_BYP_C1_PULLDOWN _SB_MAKEMASK(4,S_BCM1480_MC_PVT_BYP_C1_PULLDOWN)
+#define V_BCM1480_MC_PVT_BYP_C1_PULLDOWN(x) _SB_MAKEVALUE(x,S_BCM1480_MC_PVT_BYP_C1_PULLDOWN)
+#define G_BCM1480_MC_PVT_BYP_C1_PULLDOWN(x) _SB_GETVALUE(x,S_BCM1480_MC_PVT_BYP_C1_PULLDOWN,M_BCM1480_MC_PVT_BYP_C1_PULLDOWN)
+
+#define S_BCM1480_MC_PVT_BYP_C1_PULLUP 15
+#define M_BCM1480_MC_PVT_BYP_C1_PULLUP _SB_MAKEMASK(4,S_BCM1480_MC_PVT_BYP_C1_PULLUP)
+#define V_BCM1480_MC_PVT_BYP_C1_PULLUP(x) _SB_MAKEVALUE(x,S_BCM1480_MC_PVT_BYP_C1_PULLUP)
+#define G_BCM1480_MC_PVT_BYP_C1_PULLUP(x) _SB_GETVALUE(x,S_BCM1480_MC_PVT_BYP_C1_PULLUP,M_BCM1480_MC_PVT_BYP_C1_PULLUP)
+
+#define S_BCM1480_MC_PVT_BYP_C2_PULLDOWN 20
+#define M_BCM1480_MC_PVT_BYP_C2_PULLDOWN _SB_MAKEMASK(4,S_BCM1480_MC_PVT_BYP_C2_PULLDOWN)
+#define V_BCM1480_MC_PVT_BYP_C2_PULLDOWN(x) _SB_MAKEVALUE(x,S_BCM1480_MC_PVT_BYP_C2_PULLDOWN)
+#define G_BCM1480_MC_PVT_BYP_C2_PULLDOWN(x) _SB_GETVALUE(x,S_BCM1480_MC_PVT_BYP_C2_PULLDOWN,M_BCM1480_MC_PVT_BYP_C2_PULLDOWN)
+
+#define S_BCM1480_MC_PVT_BYP_C2_PULLUP 25
+#define M_BCM1480_MC_PVT_BYP_C2_PULLUP _SB_MAKEMASK(4,S_BCM1480_MC_PVT_BYP_C2_PULLUP)
+#define V_BCM1480_MC_PVT_BYP_C2_PULLUP(x) _SB_MAKEVALUE(x,S_BCM1480_MC_PVT_BYP_C2_PULLUP)
+#define G_BCM1480_MC_PVT_BYP_C2_PULLUP(x) _SB_GETVALUE(x,S_BCM1480_MC_PVT_BYP_C2_PULLUP,M_BCM1480_MC_PVT_BYP_C2_PULLUP)
+
+#define M_BCM1480_MC_PVT_BYPASS _SB_MAKEMASK1(30)
+#define M_BCM1480_MC_PVT_COMP_MOV_AVG _SB_MAKEMASK1(31)
+
+#define M_BCM1480_MC_CLK_CLASS _SB_MAKEMASK1(34)
+#define M_BCM1480_MC_DATA_CLASS _SB_MAKEMASK1(35)
+#define M_BCM1480_MC_ADDR_CLASS _SB_MAKEMASK1(36)
+
+#define M_BCM1480_MC_DQ_ODT_75 _SB_MAKEMASK1(37)
+#define M_BCM1480_MC_DQ_ODT_150 _SB_MAKEMASK1(38)
+#define M_BCM1480_MC_DQS_ODT_75 _SB_MAKEMASK1(39)
+#define M_BCM1480_MC_DQS_ODT_150 _SB_MAKEMASK1(40)
+#define M_BCM1480_MC_DQS_DIFF _SB_MAKEMASK1(41)
+
+/*
+ * ECC Test Data Register (Table 95)
+ */
+
+#define S_BCM1480_MC_DATA_INVERT 0
+#define M_DATA_ECC_INVERT _SB_MAKEMASK(64,S_BCM1480_MC_ECC_INVERT)
+
+/*
+ * ECC Test ECC Register (Table 96)
+ */
+
+#define S_BCM1480_MC_ECC_INVERT 0
+#define M_BCM1480_MC_ECC_INVERT _SB_MAKEMASK(8,S_BCM1480_MC_ECC_INVERT)
+
+/*
+ * SDRAM Timing Register (Table 97)
+ */
+
+#define S_BCM1480_MC_tRCD 0
+#define M_BCM1480_MC_tRCD _SB_MAKEMASK(4,S_BCM1480_MC_tRCD)
+#define V_BCM1480_MC_tRCD(x) _SB_MAKEVALUE(x,S_BCM1480_MC_tRCD)
+#define G_BCM1480_MC_tRCD(x) _SB_GETVALUE(x,S_BCM1480_MC_tRCD,M_BCM1480_MC_tRCD)
+#define K_BCM1480_MC_tRCD_DEFAULT 3
+#define V_BCM1480_MC_tRCD_DEFAULT V_BCM1480_MC_tRCD(K_BCM1480_MC_tRCD_DEFAULT)
+
+#define S_BCM1480_MC_tCL 4
+#define M_BCM1480_MC_tCL _SB_MAKEMASK(4,S_BCM1480_MC_tCL)
+#define V_BCM1480_MC_tCL(x) _SB_MAKEVALUE(x,S_BCM1480_MC_tCL)
+#define G_BCM1480_MC_tCL(x) _SB_GETVALUE(x,S_BCM1480_MC_tCL,M_BCM1480_MC_tCL)
+#define K_BCM1480_MC_tCL_DEFAULT 2
+#define V_BCM1480_MC_tCL_DEFAULT V_BCM1480_MC_tCL(K_BCM1480_MC_tCL_DEFAULT)
+
+#define M_BCM1480_MC_tCrDh _SB_MAKEMASK1(8)
+
+#define S_BCM1480_MC_tWR 9
+#define M_BCM1480_MC_tWR _SB_MAKEMASK(3,S_BCM1480_MC_tWR)
+#define V_BCM1480_MC_tWR(x) _SB_MAKEVALUE(x,S_BCM1480_MC_tWR)
+#define G_BCM1480_MC_tWR(x) _SB_GETVALUE(x,S_BCM1480_MC_tWR,M_BCM1480_MC_tWR)
+#define K_BCM1480_MC_tWR_DEFAULT 2
+#define V_BCM1480_MC_tWR_DEFAULT V_BCM1480_MC_tWR(K_BCM1480_MC_tWR_DEFAULT)
+
+#define S_BCM1480_MC_tCwD 12
+#define M_BCM1480_MC_tCwD _SB_MAKEMASK(4,S_BCM1480_MC_tCwD)
+#define V_BCM1480_MC_tCwD(x) _SB_MAKEVALUE(x,S_BCM1480_MC_tCwD)
+#define G_BCM1480_MC_tCwD(x) _SB_GETVALUE(x,S_BCM1480_MC_tCwD,M_BCM1480_MC_tCwD)
+#define K_BCM1480_MC_tCwD_DEFAULT 1
+#define V_BCM1480_MC_tCwD_DEFAULT V_BCM1480_MC_tCwD(K_BCM1480_MC_tCwD_DEFAULT)
+
+#define S_BCM1480_MC_tRP 16
+#define M_BCM1480_MC_tRP _SB_MAKEMASK(4,S_BCM1480_MC_tRP)
+#define V_BCM1480_MC_tRP(x) _SB_MAKEVALUE(x,S_BCM1480_MC_tRP)
+#define G_BCM1480_MC_tRP(x) _SB_GETVALUE(x,S_BCM1480_MC_tRP,M_BCM1480_MC_tRP)
+#define K_BCM1480_MC_tRP_DEFAULT 4
+#define V_BCM1480_MC_tRP_DEFAULT V_BCM1480_MC_tRP(K_BCM1480_MC_tRP_DEFAULT)
+
+#define S_BCM1480_MC_tRRD 20
+#define M_BCM1480_MC_tRRD _SB_MAKEMASK(4,S_BCM1480_MC_tRRD)
+#define V_BCM1480_MC_tRRD(x) _SB_MAKEVALUE(x,S_BCM1480_MC_tRRD)
+#define G_BCM1480_MC_tRRD(x) _SB_GETVALUE(x,S_BCM1480_MC_tRRD,M_BCM1480_MC_tRRD)
+#define K_BCM1480_MC_tRRD_DEFAULT 2
+#define V_BCM1480_MC_tRRD_DEFAULT V_BCM1480_MC_tRRD(K_BCM1480_MC_tRRD_DEFAULT)
+
+#define S_BCM1480_MC_tRCw 24
+#define M_BCM1480_MC_tRCw _SB_MAKEMASK(5,S_BCM1480_MC_tRCw)
+#define V_BCM1480_MC_tRCw(x) _SB_MAKEVALUE(x,S_BCM1480_MC_tRCw)
+#define G_BCM1480_MC_tRCw(x) _SB_GETVALUE(x,S_BCM1480_MC_tRCw,M_BCM1480_MC_tRCw)
+#define K_BCM1480_MC_tRCw_DEFAULT 10
+#define V_BCM1480_MC_tRCw_DEFAULT V_BCM1480_MC_tRCw(K_BCM1480_MC_tRCw_DEFAULT)
+
+#define S_BCM1480_MC_tRCr 32
+#define M_BCM1480_MC_tRCr _SB_MAKEMASK(5,S_BCM1480_MC_tRCr)
+#define V_BCM1480_MC_tRCr(x) _SB_MAKEVALUE(x,S_BCM1480_MC_tRCr)
+#define G_BCM1480_MC_tRCr(x) _SB_GETVALUE(x,S_BCM1480_MC_tRCr,M_BCM1480_MC_tRCr)
+#define K_BCM1480_MC_tRCr_DEFAULT 9
+#define V_BCM1480_MC_tRCr_DEFAULT V_BCM1480_MC_tRCr(K_BCM1480_MC_tRCr_DEFAULT)
+
+#if SIBYTE_HDR_FEATURE(1480, PASS2)
+#define S_BCM1480_MC_tFAW 40
+#define M_BCM1480_MC_tFAW _SB_MAKEMASK(6,S_BCM1480_MC_tFAW)
+#define V_BCM1480_MC_tFAW(x) _SB_MAKEVALUE(x,S_BCM1480_MC_tFAW)
+#define G_BCM1480_MC_tFAW(x) _SB_GETVALUE(x,S_BCM1480_MC_tFAW,M_BCM1480_MC_tFAW)
+#define K_BCM1480_MC_tFAW_DEFAULT 0
+#define V_BCM1480_MC_tFAW_DEFAULT V_BCM1480_MC_tFAW(K_BCM1480_MC_tFAW_DEFAULT)
+#endif
+
+#define S_BCM1480_MC_tRFC 48
+#define M_BCM1480_MC_tRFC _SB_MAKEMASK(7,S_BCM1480_MC_tRFC)
+#define V_BCM1480_MC_tRFC(x) _SB_MAKEVALUE(x,S_BCM1480_MC_tRFC)
+#define G_BCM1480_MC_tRFC(x) _SB_GETVALUE(x,S_BCM1480_MC_tRFC,M_BCM1480_MC_tRFC)
+#define K_BCM1480_MC_tRFC_DEFAULT 12
+#define V_BCM1480_MC_tRFC_DEFAULT V_BCM1480_MC_tRFC(K_BCM1480_MC_tRFC_DEFAULT)
+
+#define S_BCM1480_MC_tFIFO 56
+#define M_BCM1480_MC_tFIFO _SB_MAKEMASK(2,S_BCM1480_MC_tFIFO)
+#define V_BCM1480_MC_tFIFO(x) _SB_MAKEVALUE(x,S_BCM1480_MC_tFIFO)
+#define G_BCM1480_MC_tFIFO(x) _SB_GETVALUE(x,S_BCM1480_MC_tFIFO,M_BCM1480_MC_tFIFO)
+#define K_BCM1480_MC_tFIFO_DEFAULT 0
+#define V_BCM1480_MC_tFIFO_DEFAULT V_BCM1480_MC_tFIFO(K_BCM1480_MC_tFIFO_DEFAULT)
+
+#define S_BCM1480_MC_tW2R 58
+#define M_BCM1480_MC_tW2R _SB_MAKEMASK(2,S_BCM1480_MC_tW2R)
+#define V_BCM1480_MC_tW2R(x) _SB_MAKEVALUE(x,S_BCM1480_MC_tW2R)
+#define G_BCM1480_MC_tW2R(x) _SB_GETVALUE(x,S_BCM1480_MC_tW2R,M_BCM1480_MC_tW2R)
+#define K_BCM1480_MC_tW2R_DEFAULT 1
+#define V_BCM1480_MC_tW2R_DEFAULT V_BCM1480_MC_tW2R(K_BCM1480_MC_tW2R_DEFAULT)
+
+#define S_BCM1480_MC_tR2W 60
+#define M_BCM1480_MC_tR2W _SB_MAKEMASK(2,S_BCM1480_MC_tR2W)
+#define V_BCM1480_MC_tR2W(x) _SB_MAKEVALUE(x,S_BCM1480_MC_tR2W)
+#define G_BCM1480_MC_tR2W(x) _SB_GETVALUE(x,S_BCM1480_MC_tR2W,M_BCM1480_MC_tR2W)
+#define K_BCM1480_MC_tR2W_DEFAULT 0
+#define V_BCM1480_MC_tR2W_DEFAULT V_BCM1480_MC_tR2W(K_BCM1480_MC_tR2W_DEFAULT)
+
+#define M_BCM1480_MC_tR2R _SB_MAKEMASK1(62)
+
+#define V_BCM1480_MC_TIMING_DEFAULT (M_BCM1480_MC_tR2R | \
+ V_BCM1480_MC_tFIFO_DEFAULT | \
+ V_BCM1480_MC_tR2W_DEFAULT | \
+ V_BCM1480_MC_tW2R_DEFAULT | \
+ V_BCM1480_MC_tRFC_DEFAULT | \
+ V_BCM1480_MC_tRCr_DEFAULT | \
+ V_BCM1480_MC_tRCw_DEFAULT | \
+ V_BCM1480_MC_tRRD_DEFAULT | \
+ V_BCM1480_MC_tRP_DEFAULT | \
+ V_BCM1480_MC_tCwD_DEFAULT | \
+ V_BCM1480_MC_tWR_DEFAULT | \
+ M_BCM1480_MC_tCrDh | \
+ V_BCM1480_MC_tCL_DEFAULT | \
+ V_BCM1480_MC_tRCD_DEFAULT)
+
+/*
+ * SDRAM Timing Register 2
+ */
+
+#if SIBYTE_HDR_FEATURE(1480, PASS2)
+
+#define S_BCM1480_MC_tAL 0
+#define M_BCM1480_MC_tAL _SB_MAKEMASK(4,S_BCM1480_MC_tAL)
+#define V_BCM1480_MC_tAL(x) _SB_MAKEVALUE(x,S_BCM1480_MC_tAL)
+#define G_BCM1480_MC_tAL(x) _SB_GETVALUE(x,S_BCM1480_MC_tAL,M_BCM1480_MC_tAL)
+#define K_BCM1480_MC_tAL_DEFAULT 0
+#define V_BCM1480_MC_tAL_DEFAULT V_BCM1480_MC_tAL(K_BCM1480_MC_tAL_DEFAULT)
+
+#define S_BCM1480_MC_tRTP 4
+#define M_BCM1480_MC_tRTP _SB_MAKEMASK(3,S_BCM1480_MC_tRTP)
+#define V_BCM1480_MC_tRTP(x) _SB_MAKEVALUE(x,S_BCM1480_MC_tRTP)
+#define G_BCM1480_MC_tRTP(x) _SB_GETVALUE(x,S_BCM1480_MC_tRTP,M_BCM1480_MC_tRTP)
+#define K_BCM1480_MC_tRTP_DEFAULT 2
+#define V_BCM1480_MC_tRTP_DEFAULT V_BCM1480_MC_tRTP(K_BCM1480_MC_tRTP_DEFAULT)
+
+#define S_BCM1480_MC_tW2W 8
+#define M_BCM1480_MC_tW2W _SB_MAKEMASK(2,S_BCM1480_MC_tW2W)
+#define V_BCM1480_MC_tW2W(x) _SB_MAKEVALUE(x,S_BCM1480_MC_tW2W)
+#define G_BCM1480_MC_tW2W(x) _SB_GETVALUE(x,S_BCM1480_MC_tW2W,M_BCM1480_MC_tW2W)
+#define K_BCM1480_MC_tW2W_DEFAULT 0
+#define V_BCM1480_MC_tW2W_DEFAULT V_BCM1480_MC_tW2W(K_BCM1480_MC_tW2W_DEFAULT)
+
+#define S_BCM1480_MC_tRAP 12
+#define M_BCM1480_MC_tRAP _SB_MAKEMASK(4,S_BCM1480_MC_tRAP)
+#define V_BCM1480_MC_tRAP(x) _SB_MAKEVALUE(x,S_BCM1480_MC_tRAP)
+#define G_BCM1480_MC_tRAP(x) _SB_GETVALUE(x,S_BCM1480_MC_tRAP,M_BCM1480_MC_tRAP)
+#define K_BCM1480_MC_tRAP_DEFAULT 0
+#define V_BCM1480_MC_tRAP_DEFAULT V_BCM1480_MC_tRAP(K_BCM1480_MC_tRAP_DEFAULT)
+
+#endif
+
+
+
+/*
+ * Global Registers: single instances per BCM1480
+ */
+
+/*
+ * Global Configuration Register (Table 99)
+ */
+
+#define S_BCM1480_MC_BLK_SET_MARK 8
+#define M_BCM1480_MC_BLK_SET_MARK _SB_MAKEMASK(4,S_BCM1480_MC_BLK_SET_MARK)
+#define V_BCM1480_MC_BLK_SET_MARK(x) _SB_MAKEVALUE(x,S_BCM1480_MC_BLK_SET_MARK)
+#define G_BCM1480_MC_BLK_SET_MARK(x) _SB_GETVALUE(x,S_BCM1480_MC_BLK_SET_MARK,M_BCM1480_MC_BLK_SET_MARK)
+
+#define S_BCM1480_MC_BLK_CLR_MARK 12
+#define M_BCM1480_MC_BLK_CLR_MARK _SB_MAKEMASK(4,S_BCM1480_MC_BLK_CLR_MARK)
+#define V_BCM1480_MC_BLK_CLR_MARK(x) _SB_MAKEVALUE(x,S_BCM1480_MC_BLK_CLR_MARK)
+#define G_BCM1480_MC_BLK_CLR_MARK(x) _SB_GETVALUE(x,S_BCM1480_MC_BLK_CLR_MARK,M_BCM1480_MC_BLK_CLR_MARK)
+
+#define M_BCM1480_MC_PKT_PRIORITY _SB_MAKEMASK1(16)
+
+#define S_BCM1480_MC_MAX_AGE 20
+#define M_BCM1480_MC_MAX_AGE _SB_MAKEMASK(4,S_BCM1480_MC_MAX_AGE)
+#define V_BCM1480_MC_MAX_AGE(x) _SB_MAKEVALUE(x,S_BCM1480_MC_MAX_AGE)
+#define G_BCM1480_MC_MAX_AGE(x) _SB_GETVALUE(x,S_BCM1480_MC_MAX_AGE,M_BCM1480_MC_MAX_AGE)
+
+#define M_BCM1480_MC_BERR_DISABLE _SB_MAKEMASK1(29)
+#define M_BCM1480_MC_FORCE_SEQ _SB_MAKEMASK1(30)
+#define M_BCM1480_MC_VGEN _SB_MAKEMASK1(32)
+
+#define S_BCM1480_MC_SLEW 33
+#define M_BCM1480_MC_SLEW _SB_MAKEMASK(2,S_BCM1480_MC_SLEW)
+#define V_BCM1480_MC_SLEW(x) _SB_MAKEVALUE(x,S_BCM1480_MC_SLEW)
+#define G_BCM1480_MC_SLEW(x) _SB_GETVALUE(x,S_BCM1480_MC_SLEW,M_BCM1480_MC_SLEW)
+
+#define M_BCM1480_MC_SSTL_VOLTAGE _SB_MAKEMASK1(35)
+
+/*
+ * Global Channel Interleave Register (Table 100)
+ */
+
+#define S_BCM1480_MC_INTLV0 0
+#define M_BCM1480_MC_INTLV0 _SB_MAKEMASK(6,S_BCM1480_MC_INTLV0)
+#define V_BCM1480_MC_INTLV0(x) _SB_MAKEVALUE(x,S_BCM1480_MC_INTLV0)
+#define G_BCM1480_MC_INTLV0(x) _SB_GETVALUE(x,S_BCM1480_MC_INTLV0,M_BCM1480_MC_INTLV0)
+
+#define S_BCM1480_MC_INTLV1 8
+#define M_BCM1480_MC_INTLV1 _SB_MAKEMASK(6,S_BCM1480_MC_INTLV1)
+#define V_BCM1480_MC_INTLV1(x) _SB_MAKEVALUE(x,S_BCM1480_MC_INTLV1)
+#define G_BCM1480_MC_INTLV1(x) _SB_GETVALUE(x,S_BCM1480_MC_INTLV1,M_BCM1480_MC_INTLV1)
+
+#define S_BCM1480_MC_INTLV_MODE 16
+#define M_BCM1480_MC_INTLV_MODE _SB_MAKEMASK(3,S_BCM1480_MC_INTLV_MODE)
+#define V_BCM1480_MC_INTLV_MODE(x) _SB_MAKEVALUE(x,S_BCM1480_MC_INTLV_MODE)
+#define G_BCM1480_MC_INTLV_MODE(x) _SB_GETVALUE(x,S_BCM1480_MC_INTLV_MODE,M_BCM1480_MC_INTLV_MODE)
+
+#define K_BCM1480_MC_INTLV_MODE_NONE 0x0
+#define K_BCM1480_MC_INTLV_MODE_01 0x1
+#define K_BCM1480_MC_INTLV_MODE_23 0x2
+#define K_BCM1480_MC_INTLV_MODE_01_23 0x3
+#define K_BCM1480_MC_INTLV_MODE_0123 0x4
+
+#define V_BCM1480_MC_INTLV_MODE_NONE V_BCM1480_MC_INTLV_MODE(K_BCM1480_MC_INTLV_MODE_NONE)
+#define V_BCM1480_MC_INTLV_MODE_01 V_BCM1480_MC_INTLV_MODE(K_BCM1480_MC_INTLV_MODE_01)
+#define V_BCM1480_MC_INTLV_MODE_23 V_BCM1480_MC_INTLV_MODE(K_BCM1480_MC_INTLV_MODE_23)
+#define V_BCM1480_MC_INTLV_MODE_01_23 V_BCM1480_MC_INTLV_MODE(K_BCM1480_MC_INTLV_MODE_01_23)
+#define V_BCM1480_MC_INTLV_MODE_0123 V_BCM1480_MC_INTLV_MODE(K_BCM1480_MC_INTLV_MODE_0123)
+
+/*
+ * ECC Status Register
+ */
+
+#define S_BCM1480_MC_ECC_ERR_ADDR 0
+#define M_BCM1480_MC_ECC_ERR_ADDR _SB_MAKEMASK(37,S_BCM1480_MC_ECC_ERR_ADDR)
+#define V_BCM1480_MC_ECC_ERR_ADDR(x) _SB_MAKEVALUE(x,S_BCM1480_MC_ECC_ERR_ADDR)
+#define G_BCM1480_MC_ECC_ERR_ADDR(x) _SB_GETVALUE(x,S_BCM1480_MC_ECC_ERR_ADDR,M_BCM1480_MC_ECC_ERR_ADDR)
+
+#if SIBYTE_HDR_FEATURE(1480, PASS2)
+#define M_BCM1480_MC_ECC_ERR_RMW _SB_MAKEMASK1(60)
+#endif
+
+#define M_BCM1480_MC_ECC_MULT_ERR_DET _SB_MAKEMASK1(61)
+#define M_BCM1480_MC_ECC_UERR_DET _SB_MAKEMASK1(62)
+#define M_BCM1480_MC_ECC_CERR_DET _SB_MAKEMASK1(63)
+
+/*
+ * Global ECC Address Register (Table 102)
+ */
+
+#define S_BCM1480_MC_ECC_CORR_ADDR 0
+#define M_BCM1480_MC_ECC_CORR_ADDR _SB_MAKEMASK(37,S_BCM1480_MC_ECC_CORR_ADDR)
+#define V_BCM1480_MC_ECC_CORR_ADDR(x) _SB_MAKEVALUE(x,S_BCM1480_MC_ECC_CORR_ADDR)
+#define G_BCM1480_MC_ECC_CORR_ADDR(x) _SB_GETVALUE(x,S_BCM1480_MC_ECC_CORR_ADDR,M_BCM1480_MC_ECC_CORR_ADDR)
+
+/*
+ * Global ECC Correction Register (Table 103)
+ */
+
+#define S_BCM1480_MC_ECC_CORRECT 0
+#define M_BCM1480_MC_ECC_CORRECT _SB_MAKEMASK(64,S_BCM1480_MC_ECC_CORRECT)
+#define V_BCM1480_MC_ECC_CORRECT(x) _SB_MAKEVALUE(x,S_BCM1480_MC_ECC_CORRECT)
+#define G_BCM1480_MC_ECC_CORRECT(x) _SB_GETVALUE(x,S_BCM1480_MC_ECC_CORRECT,M_BCM1480_MC_ECC_CORRECT)
+
+/*
+ * Global ECC Performance Counters Control Register (Table 104)
+ */
+
+#define S_BCM1480_MC_CHANNEL_SELECT 0
+#define M_BCM1480_MC_CHANNEL_SELECT _SB_MAKEMASK(4,S_BCM1480_MC_CHANNEL_SELECT)
+#define V_BCM1480_MC_CHANNEL_SELECT(x) _SB_MAKEVALUE(x,S_BCM1480_MC_CHANNEL_SELECT)
+#define G_BCM1480_MC_CHANNEL_SELECT(x) _SB_GETVALUE(x,S_BCM1480_MC_CHANNEL_SELECT,M_BCM1480_MC_CHANNEL_SELECT)
+#define K_BCM1480_MC_CHANNEL_SELECT_0 0x1
+#define K_BCM1480_MC_CHANNEL_SELECT_1 0x2
+#define K_BCM1480_MC_CHANNEL_SELECT_2 0x4
+#define K_BCM1480_MC_CHANNEL_SELECT_3 0x8
+
+#endif /* _BCM1480_MC_H */
diff --git a/include/asm-mips/sibyte/bcm1480_regs.h b/include/asm-mips/sibyte/bcm1480_regs.h
new file mode 100644
index 000000000000..c2dd2fe3047c
--- /dev/null
+++ b/include/asm-mips/sibyte/bcm1480_regs.h
@@ -0,0 +1,869 @@
+/* *********************************************************************
+ * BCM1255/BCM1280/BCM1455/BCM1480 Board Support Package
+ *
+ * Register Definitions File: bcm1480_regs.h
+ *
+ * This module contains the addresses of the on-chip peripherals
+ * on the BCM1280 and BCM1480.
+ *
+ * BCM1480 specification level: 1X55_1X80-UM100-D4 (11/24/03)
+ *
+ *********************************************************************
+ *
+ * Copyright 2000,2001,2002,2003
+ * Broadcom Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ ********************************************************************* */
+
+#ifndef _BCM1480_REGS_H
+#define _BCM1480_REGS_H
+
+#include "sb1250_defs.h"
+
+/* *********************************************************************
+ * Pull in the BCM1250's registers since a great deal of the 1480's
+ * functions are the same as the BCM1250.
+ ********************************************************************* */
+
+#include "sb1250_regs.h"
+
+
+/* *********************************************************************
+ * Some general notes:
+ *
+ * Register addresses are grouped by function and follow the order
+ * of the User Manual.
+ *
+ * For the most part, when there is more than one peripheral
+ * of the same type on the SOC, the constants below will be
+ * offsets from the base of each peripheral. For example,
+ * the MAC registers are described as offsets from the first
+ * MAC register, and there will be a MAC_REGISTER() macro
+ * to calculate the base address of a given MAC.
+ *
+ * The information in this file is based on the BCM1X55/BCM1X80
+ * User Manual, Document 1X55_1X80-UM100-R, 22/12/03.
+ *
+ * This file is basically a "what's new" header file. Since the
+ * BCM1250 and the new BCM1480 (and derivatives) share many common
+ * features, this file contains only what's new or changed from
+ * the 1250. (above, you can see that we include the 1250 symbols
+ * to get the base functionality).
+ *
+ * In software, be sure to use the correct symbols, particularly
+ * for blocks that are different between the two chip families.
+ * All BCM1480-specific symbols have _BCM1480_ in their names,
+ * and all BCM1250-specific and "base" functions that are common in
+ * both chips have no special names (this is for compatibility with
+ * older include files). Therefore, if you're working with the
+ * SCD, which is very different on each chip, A_SCD_xxx implies
+ * the BCM1250 version and A_BCM1480_SCD_xxx implies the BCM1480
+ * version.
+ ********************************************************************* */
+
+
+/* *********************************************************************
+ * Memory Controller Registers (Section 6)
+ ********************************************************************* */
+
+#define A_BCM1480_MC_BASE_0 0x0010050000
+#define A_BCM1480_MC_BASE_1 0x0010051000
+#define A_BCM1480_MC_BASE_2 0x0010052000
+#define A_BCM1480_MC_BASE_3 0x0010053000
+#define BCM1480_MC_REGISTER_SPACING 0x1000
+
+#define A_BCM1480_MC_BASE(ctlid) (A_BCM1480_MC_BASE_0+(ctlid)*BCM1480_MC_REGISTER_SPACING)
+#define A_BCM1480_MC_REGISTER(ctlid,reg) (A_BCM1480_MC_BASE(ctlid)+(reg))
+
+#define R_BCM1480_MC_CONFIG 0x0000000100
+#define R_BCM1480_MC_CS_START 0x0000000120
+#define R_BCM1480_MC_CS_END 0x0000000140
+#define S_BCM1480_MC_CS_STARTEND 24
+
+#define R_BCM1480_MC_CS01_ROW0 0x0000000180
+#define R_BCM1480_MC_CS01_ROW1 0x00000001A0
+#define R_BCM1480_MC_CS23_ROW0 0x0000000200
+#define R_BCM1480_MC_CS23_ROW1 0x0000000220
+#define R_BCM1480_MC_CS01_COL0 0x0000000280
+#define R_BCM1480_MC_CS01_COL1 0x00000002A0
+#define R_BCM1480_MC_CS23_COL0 0x0000000300
+#define R_BCM1480_MC_CS23_COL1 0x0000000320
+
+#define R_BCM1480_MC_CSX_BASE 0x0000000180
+#define R_BCM1480_MC_CSX_ROW0 0x0000000000 /* relative to CSX_BASE */
+#define R_BCM1480_MC_CSX_ROW1 0x0000000020 /* relative to CSX_BASE */
+#define R_BCM1480_MC_CSX_COL0 0x0000000100 /* relative to CSX_BASE */
+#define R_BCM1480_MC_CSX_COL1 0x0000000120 /* relative to CSX_BASE */
+#define BCM1480_MC_CSX_SPACING 0x0000000080 /* CS23 relative to CS01 */
+
+#define R_BCM1480_MC_CS01_BA 0x0000000380
+#define R_BCM1480_MC_CS23_BA 0x00000003A0
+#define R_BCM1480_MC_DRAMCMD 0x0000000400
+#define R_BCM1480_MC_DRAMMODE 0x0000000420
+#define R_BCM1480_MC_CLOCK_CFG 0x0000000440
+#define R_BCM1480_MC_MCLK_CFG R_BCM1480_MC_CLOCK_CFG
+#define R_BCM1480_MC_TEST_DATA 0x0000000480
+#define R_BCM1480_MC_TEST_ECC 0x00000004A0
+#define R_BCM1480_MC_TIMING1 0x00000004C0
+#define R_BCM1480_MC_TIMING2 0x00000004E0
+#define R_BCM1480_MC_DLL_CFG 0x0000000500
+#define R_BCM1480_MC_DRIVE_CFG 0x0000000520
+
+#if SIBYTE_HDR_FEATURE(1480, PASS2)
+#define R_BCM1480_MC_ODT 0x0000000460
+#define R_BCM1480_MC_ECC_STATUS 0x0000000540
+#endif
+
+/* Global registers (single instance) */
+#define A_BCM1480_MC_GLB_CONFIG 0x0010054100
+#define A_BCM1480_MC_GLB_INTLV 0x0010054120
+#define A_BCM1480_MC_GLB_ECC_STATUS 0x0010054140
+#define A_BCM1480_MC_GLB_ECC_ADDR 0x0010054160
+#define A_BCM1480_MC_GLB_ECC_CORRECT 0x0010054180
+#define A_BCM1480_MC_GLB_PERF_CNT_CONTROL 0x00100541A0
+
+/* *********************************************************************
+ * L2 Cache Control Registers (Section 5)
+ ********************************************************************* */
+
+#define A_BCM1480_L2_BASE 0x0010040000
+
+#define A_BCM1480_L2_READ_TAG 0x0010040018
+#define A_BCM1480_L2_ECC_TAG 0x0010040038
+#define A_BCM1480_L2_MISC0_VALUE 0x0010040058
+#define A_BCM1480_L2_MISC1_VALUE 0x0010040078
+#define A_BCM1480_L2_MISC2_VALUE 0x0010040098
+#define A_BCM1480_L2_MISC_CONFIG 0x0010040040 /* x040 */
+#define A_BCM1480_L2_CACHE_DISABLE 0x0010040060 /* x060 */
+#define A_BCM1480_L2_MAKECACHEDISABLE(x) (A_BCM1480_L2_CACHE_DISABLE | (((x)&0xF) << 12))
+#define A_BCM1480_L2_WAY_ENABLE_3_0 0x0010040080 /* x080 */
+#define A_BCM1480_L2_WAY_ENABLE_7_4 0x00100400A0 /* x0A0 */
+#define A_BCM1480_L2_MAKE_WAY_ENABLE_LO(x) (A_BCM1480_L2_WAY_ENABLE_3_0 | (((x)&0xF) << 12))
+#define A_BCM1480_L2_MAKE_WAY_ENABLE_HI(x) (A_BCM1480_L2_WAY_ENABLE_7_4 | (((x)&0xF) << 12))
+#define A_BCM1480_L2_MAKE_WAY_DISABLE_LO(x) (A_BCM1480_L2_WAY_ENABLE_3_0 | (((~x)&0xF) << 12))
+#define A_BCM1480_L2_MAKE_WAY_DISABLE_HI(x) (A_BCM1480_L2_WAY_ENABLE_7_4 | (((~x)&0xF) << 12))
+#define A_BCM1480_L2_WAY_LOCAL_3_0 0x0010040100 /* x100 */
+#define A_BCM1480_L2_WAY_LOCAL_7_4 0x0010040120 /* x120 */
+#define A_BCM1480_L2_WAY_REMOTE_3_0 0x0010040140 /* x140 */
+#define A_BCM1480_L2_WAY_REMOTE_7_4 0x0010040160 /* x160 */
+#define A_BCM1480_L2_WAY_AGENT_3_0 0x00100400C0 /* xxC0 */
+#define A_BCM1480_L2_WAY_AGENT_7_4 0x00100400E0 /* xxE0 */
+#define A_BCM1480_L2_WAY_ENABLE(A, banks) (A | (((~(banks))&0x0F) << 8))
+#define A_BCM1480_L2_BANK_BASE 0x00D0300000
+#define A_BCM1480_L2_BANK_ADDRESS(b) (A_BCM1480_L2_BANK_BASE | (((b)&0x7)<<17))
+#define A_BCM1480_L2_MGMT_TAG_BASE 0x00D0000000
+
+
+/* *********************************************************************
+ * PCI-X Interface Registers (Section 7)
+ ********************************************************************* */
+
+#define A_BCM1480_PCI_BASE 0x0010061400
+
+#define A_BCM1480_PCI_RESET 0x0010061400
+#define A_BCM1480_PCI_DLL 0x0010061500
+
+#define A_BCM1480_PCI_TYPE00_HEADER 0x002E000000
+
+/* *********************************************************************
+ * Ethernet MAC Registers (Section 11) and DMA Registers (Section 10.6)
+ ********************************************************************* */
+
+/* No register changes with Rev.C BCM1250, but one additional MAC */
+
+#define A_BCM1480_MAC_BASE_2 0x0010066000
+
+#ifndef A_MAC_BASE_2
+#define A_MAC_BASE_2 A_BCM1480_MAC_BASE_2
+#endif
+
+#define A_BCM1480_MAC_BASE_3 0x0010067000
+#define A_MAC_BASE_3 A_BCM1480_MAC_BASE_3
+
+#define R_BCM1480_MAC_DMA_OODPKTLOST 0x00000038
+
+#ifndef R_MAC_DMA_OODPKTLOST
+#define R_MAC_DMA_OODPKTLOST R_BCM1480_MAC_DMA_OODPKTLOST
+#endif
+
+
+/* *********************************************************************
+ * DUART Registers (Section 14)
+ ********************************************************************* */
+
+/* No significant differences from BCM1250, two DUARTs */
+
+/* Conventions, per user manual:
+ * DUART generic, channels A,B,C,D
+ * DUART0 implementing channels A,B
+ * DUART1 inplementing channels C,D
+ */
+
+#define BCM1480_DUART_NUM_PORTS 4
+
+#define A_BCM1480_DUART0 0x0010060000
+#define A_BCM1480_DUART1 0x0010060400
+#define A_BCM1480_DUART(chan) ((((chan)&2) == 0)? A_BCM1480_DUART0 : A_BCM1480_DUART1)
+
+#define BCM1480_DUART_CHANREG_SPACING 0x100
+#define A_BCM1480_DUART_CHANREG(chan,reg) (A_BCM1480_DUART(chan) \
+ + BCM1480_DUART_CHANREG_SPACING*((chan)&1) \
+ + (reg))
+#define R_BCM1480_DUART_CHANREG(chan,reg) (BCM1480_DUART_CHANREG_SPACING*((chan)&1) + (reg))
+
+#define R_BCM1480_DUART_IMRREG(chan) (R_DUART_IMR_A + ((chan)&1)*DUART_IMRISR_SPACING)
+#define R_BCM1480_DUART_ISRREG(chan) (R_DUART_ISR_A + ((chan)&1)*DUART_IMRISR_SPACING)
+
+#define A_BCM1480_DUART_IMRREG(chan) (A_BCM1480_DUART(chan) + R_BCM1480_DUART_IMRREG(chan))
+#define A_BCM1480_DUART_ISRREG(chan) (A_BCM1480_DUART(chan) + R_BCM1480_DUART_ISRREG(chan))
+
+/*
+ * These constants are the absolute addresses.
+ */
+
+#define A_BCM1480_DUART_MODE_REG_1_C 0x0010060400
+#define A_BCM1480_DUART_MODE_REG_2_C 0x0010060410
+#define A_BCM1480_DUART_STATUS_C 0x0010060420
+#define A_BCM1480_DUART_CLK_SEL_C 0x0010060430
+#define A_BCM1480_DUART_FULL_CTL_C 0x0010060440
+#define A_BCM1480_DUART_CMD_C 0x0010060450
+#define A_BCM1480_DUART_RX_HOLD_C 0x0010060460
+#define A_BCM1480_DUART_TX_HOLD_C 0x0010060470
+#define A_BCM1480_DUART_OPCR_C 0x0010060480
+#define A_BCM1480_DUART_AUX_CTRL_C 0x0010060490
+
+#define A_BCM1480_DUART_MODE_REG_1_D 0x0010060500
+#define A_BCM1480_DUART_MODE_REG_2_D 0x0010060510
+#define A_BCM1480_DUART_STATUS_D 0x0010060520
+#define A_BCM1480_DUART_CLK_SEL_D 0x0010060530
+#define A_BCM1480_DUART_FULL_CTL_D 0x0010060540
+#define A_BCM1480_DUART_CMD_D 0x0010060550
+#define A_BCM1480_DUART_RX_HOLD_D 0x0010060560
+#define A_BCM1480_DUART_TX_HOLD_D 0x0010060570
+#define A_BCM1480_DUART_OPCR_D 0x0010060580
+#define A_BCM1480_DUART_AUX_CTRL_D 0x0010060590
+
+#define A_BCM1480_DUART_INPORT_CHNG_CD 0x0010060600
+#define A_BCM1480_DUART_AUX_CTRL_CD 0x0010060610
+#define A_BCM1480_DUART_ISR_C 0x0010060620
+#define A_BCM1480_DUART_IMR_C 0x0010060630
+#define A_BCM1480_DUART_ISR_D 0x0010060640
+#define A_BCM1480_DUART_IMR_D 0x0010060650
+#define A_BCM1480_DUART_OUT_PORT_CD 0x0010060660
+#define A_BCM1480_DUART_OPCR_CD 0x0010060670
+#define A_BCM1480_DUART_IN_PORT_CD 0x0010060680
+#define A_BCM1480_DUART_ISR_CD 0x0010060690
+#define A_BCM1480_DUART_IMR_CD 0x00100606A0
+#define A_BCM1480_DUART_SET_OPR_CD 0x00100606B0
+#define A_BCM1480_DUART_CLEAR_OPR_CD 0x00100606C0
+#define A_BCM1480_DUART_INPORT_CHNG_C 0x00100606D0
+#define A_BCM1480_DUART_INPORT_CHNG_D 0x00100606E0
+
+
+/* *********************************************************************
+ * Generic Bus Registers (Section 15) and PCMCIA Registers (Section 16)
+ ********************************************************************* */
+
+#define A_BCM1480_IO_PCMCIA_CFG_B 0x0010061A58
+#define A_BCM1480_IO_PCMCIA_STATUS_B 0x0010061A68
+
+/* *********************************************************************
+ * GPIO Registers (Section 17)
+ ********************************************************************* */
+
+/* One additional GPIO register, placed _before_ the BCM1250's GPIO block base */
+
+#define A_BCM1480_GPIO_INT_ADD_TYPE 0x0010061A78
+#define R_BCM1480_GPIO_INT_ADD_TYPE (-8)
+
+#define A_GPIO_INT_ADD_TYPE A_BCM1480_GPIO_INT_ADD_TYPE
+#define R_GPIO_INT_ADD_TYPE R_BCM1480_GPIO_INT_ADD_TYPE
+
+/* *********************************************************************
+ * SMBus Registers (Section 18)
+ ********************************************************************* */
+
+/* No changes from BCM1250 */
+
+/* *********************************************************************
+ * Timer Registers (Sections 4.6)
+ ********************************************************************* */
+
+/* BCM1480 has two additional watchdogs */
+
+/* Watchdog timers */
+
+#define A_BCM1480_SCD_WDOG_2 0x0010022050
+#define A_BCM1480_SCD_WDOG_3 0x0010022150
+
+#define BCM1480_SCD_NUM_WDOGS 4
+
+#define A_BCM1480_SCD_WDOG_BASE(w) (A_BCM1480_SCD_WDOG_0+((w)&2)*0x1000 + ((w)&1)*0x100)
+#define A_BCM1480_SCD_WDOG_REGISTER(w,r) (A_BCM1480_SCD_WDOG_BASE(w) + (r))
+
+#define A_BCM1480_SCD_WDOG_INIT_2 0x0010022050
+#define A_BCM1480_SCD_WDOG_CNT_2 0x0010022058
+#define A_BCM1480_SCD_WDOG_CFG_2 0x0010022060
+
+#define A_BCM1480_SCD_WDOG_INIT_3 0x0010022150
+#define A_BCM1480_SCD_WDOG_CNT_3 0x0010022158
+#define A_BCM1480_SCD_WDOG_CFG_3 0x0010022160
+
+/* BCM1480 has two additional compare registers */
+
+#define A_BCM1480_SCD_ZBBUS_CYCLE_COUNT A_SCD_ZBBUS_CYCLE_COUNT
+#define A_BCM1480_SCD_ZBBUS_CYCLE_CP_BASE 0x0010020C00
+#define A_BCM1480_SCD_ZBBUS_CYCLE_CP0 A_SCD_ZBBUS_CYCLE_CP0
+#define A_BCM1480_SCD_ZBBUS_CYCLE_CP1 A_SCD_ZBBUS_CYCLE_CP1
+#define A_BCM1480_SCD_ZBBUS_CYCLE_CP2 0x0010020C10
+#define A_BCM1480_SCD_ZBBUS_CYCLE_CP3 0x0010020C18
+
+/* *********************************************************************
+ * System Control Registers (Section 4.2)
+ ********************************************************************* */
+
+/* Scratch register in different place */
+
+#define A_BCM1480_SCD_SCRATCH 0x100200A0
+
+/* *********************************************************************
+ * System Address Trap Registers (Section 4.9)
+ ********************************************************************* */
+
+/* No changes from BCM1250 */
+
+/* *********************************************************************
+ * System Interrupt Mapper Registers (Sections 4.3-4.5)
+ ********************************************************************* */
+
+#define A_BCM1480_IMR_CPU0_BASE 0x0010020000
+#define A_BCM1480_IMR_CPU1_BASE 0x0010022000
+#define A_BCM1480_IMR_CPU2_BASE 0x0010024000
+#define A_BCM1480_IMR_CPU3_BASE 0x0010026000
+#define BCM1480_IMR_REGISTER_SPACING 0x2000
+#define BCM1480_IMR_REGISTER_SPACING_SHIFT 13
+
+#define A_BCM1480_IMR_MAPPER(cpu) (A_BCM1480_IMR_CPU0_BASE+(cpu)*BCM1480_IMR_REGISTER_SPACING)
+#define A_BCM1480_IMR_REGISTER(cpu,reg) (A_BCM1480_IMR_MAPPER(cpu)+(reg))
+
+/* Most IMR registers are 128 bits, implemented as non-contiguous
+ 64-bit registers high (_H) and low (_L) */
+#define BCM1480_IMR_HL_SPACING 0x1000
+
+#define R_BCM1480_IMR_INTERRUPT_DIAG_H 0x0010
+#define R_BCM1480_IMR_LDT_INTERRUPT_H 0x0018
+#define R_BCM1480_IMR_LDT_INTERRUPT_CLR_H 0x0020
+#define R_BCM1480_IMR_INTERRUPT_MASK_H 0x0028
+#define R_BCM1480_IMR_INTERRUPT_TRACE_H 0x0038
+#define R_BCM1480_IMR_INTERRUPT_SOURCE_STATUS_H 0x0040
+#define R_BCM1480_IMR_LDT_INTERRUPT_SET 0x0048
+#define R_BCM1480_IMR_MAILBOX_0_CPU 0x00C0
+#define R_BCM1480_IMR_MAILBOX_0_SET_CPU 0x00C8
+#define R_BCM1480_IMR_MAILBOX_0_CLR_CPU 0x00D0
+#define R_BCM1480_IMR_MAILBOX_1_CPU 0x00E0
+#define R_BCM1480_IMR_MAILBOX_1_SET_CPU 0x00E8
+#define R_BCM1480_IMR_MAILBOX_1_CLR_CPU 0x00F0
+#define R_BCM1480_IMR_INTERRUPT_STATUS_BASE_H 0x0100
+#define BCM1480_IMR_INTERRUPT_STATUS_COUNT 8
+#define R_BCM1480_IMR_INTERRUPT_MAP_BASE_H 0x0200
+#define BCM1480_IMR_INTERRUPT_MAP_COUNT 64
+
+#define R_BCM1480_IMR_INTERRUPT_DIAG_L 0x1010
+#define R_BCM1480_IMR_LDT_INTERRUPT_L 0x1018
+#define R_BCM1480_IMR_LDT_INTERRUPT_CLR_L 0x1020
+#define R_BCM1480_IMR_INTERRUPT_MASK_L 0x1028
+#define R_BCM1480_IMR_INTERRUPT_TRACE_L 0x1038
+#define R_BCM1480_IMR_INTERRUPT_SOURCE_STATUS_L 0x1040
+#define R_BCM1480_IMR_INTERRUPT_STATUS_BASE_L 0x1100
+#define R_BCM1480_IMR_INTERRUPT_MAP_BASE_L 0x1200
+
+#define A_BCM1480_IMR_ALIAS_MAILBOX_CPU0_BASE 0x0010028000
+#define A_BCM1480_IMR_ALIAS_MAILBOX_CPU1_BASE 0x0010028100
+#define A_BCM1480_IMR_ALIAS_MAILBOX_CPU2_BASE 0x0010028200
+#define A_BCM1480_IMR_ALIAS_MAILBOX_CPU3_BASE 0x0010028300
+#define BCM1480_IMR_ALIAS_MAILBOX_SPACING 0100
+
+#define A_BCM1480_IMR_ALIAS_MAILBOX(cpu) (A_BCM1480_IMR_ALIAS_MAILBOX_CPU0_BASE + \
+ (cpu)*BCM1480_IMR_ALIAS_MAILBOX_SPACING)
+#define A_BCM1480_IMR_ALIAS_MAILBOX_REGISTER(cpu,reg) (A_BCM1480_IMR_ALIAS_MAILBOX(cpu)+(reg))
+
+#define R_BCM1480_IMR_ALIAS_MAILBOX_0 0x0000 /* 0x0x0 */
+#define R_BCM1480_IMR_ALIAS_MAILBOX_0_SET 0x0008 /* 0x0x8 */
+
+/* *********************************************************************
+ * System Performance Counter Registers (Section 4.7)
+ ********************************************************************* */
+
+/* BCM1480 has four more performance counter registers, and two control
+ registers. */
+
+#define A_BCM1480_SCD_PERF_CNT_BASE 0x00100204C0
+
+#define A_BCM1480_SCD_PERF_CNT_CFG0 0x00100204C0
+#define A_BCM1480_SCD_PERF_CNT_CFG_0 A_BCM1480_SCD_PERF_CNT_CFG0
+#define A_BCM1480_SCD_PERF_CNT_CFG1 0x00100204C8
+#define A_BCM1480_SCD_PERF_CNT_CFG_1 A_BCM1480_SCD_PERF_CNT_CFG1
+
+#define A_BCM1480_SCD_PERF_CNT_0 A_SCD_PERF_CNT_0
+#define A_BCM1480_SCD_PERF_CNT_1 A_SCD_PERF_CNT_1
+#define A_BCM1480_SCD_PERF_CNT_2 A_SCD_PERF_CNT_2
+#define A_BCM1480_SCD_PERF_CNT_3 A_SCD_PERF_CNT_3
+
+#define A_BCM1480_SCD_PERF_CNT_4 0x00100204F0
+#define A_BCM1480_SCD_PERF_CNT_5 0x00100204F8
+#define A_BCM1480_SCD_PERF_CNT_6 0x0010020500
+#define A_BCM1480_SCD_PERF_CNT_7 0x0010020508
+
+/* *********************************************************************
+ * System Bus Watcher Registers (Section 4.8)
+ ********************************************************************* */
+
+
+/* Same as 1250 except BUS_ERR_STATUS_DEBUG is in a different place. */
+
+#define A_BCM1480_BUS_ERR_STATUS_DEBUG 0x00100208D8
+
+/* *********************************************************************
+ * System Debug Controller Registers (Section 19)
+ ********************************************************************* */
+
+/* Same as 1250 */
+
+/* *********************************************************************
+ * System Trace Unit Registers (Sections 4.10)
+ ********************************************************************* */
+
+/* Same as 1250 */
+
+/* *********************************************************************
+ * Data Mover DMA Registers (Section 10.7)
+ ********************************************************************* */
+
+/* Same as 1250 */
+
+
+/* *********************************************************************
+ * HyperTransport Interface Registers (Section 8)
+ ********************************************************************* */
+
+#define BCM1480_HT_NUM_PORTS 3
+#define BCM1480_HT_PORT_SPACING 0x800
+#define A_BCM1480_HT_PORT_HEADER(x) (A_BCM1480_HT_PORT0_HEADER + ((x)*BCM1480_HT_PORT_SPACING))
+
+#define A_BCM1480_HT_PORT0_HEADER 0x00FE000000
+#define A_BCM1480_HT_PORT1_HEADER 0x00FE000800
+#define A_BCM1480_HT_PORT2_HEADER 0x00FE001000
+#define A_BCM1480_HT_TYPE00_HEADER 0x00FE002000
+
+
+/* *********************************************************************
+ * Node Controller Registers (Section 9)
+ ********************************************************************* */
+
+#define A_BCM1480_NC_BASE 0x00DFBD0000
+
+#define A_BCM1480_NC_RLD_FIELD 0x00DFBD0000
+#define A_BCM1480_NC_RLD_TRIGGER 0x00DFBD0020
+#define A_BCM1480_NC_RLD_BAD_ERROR 0x00DFBD0040
+#define A_BCM1480_NC_RLD_COR_ERROR 0x00DFBD0060
+#define A_BCM1480_NC_RLD_ECC_STATUS 0x00DFBD0080
+#define A_BCM1480_NC_RLD_WAY_ENABLE 0x00DFBD00A0
+#define A_BCM1480_NC_RLD_RANDOM_LFSR 0x00DFBD00C0
+
+#define A_BCM1480_NC_INTERRUPT_STATUS 0x00DFBD00E0
+#define A_BCM1480_NC_INTERRUPT_ENABLE 0x00DFBD0100
+#define A_BCM1480_NC_TIMEOUT_COUNTER 0x00DFBD0120
+#define A_BCM1480_NC_TIMEOUT_COUNTER_SEL 0x00DFBD0140
+
+#define A_BCM1480_NC_CREDIT_STATUS_REG0 0x00DFBD0200
+#define A_BCM1480_NC_CREDIT_STATUS_REG1 0x00DFBD0220
+#define A_BCM1480_NC_CREDIT_STATUS_REG2 0x00DFBD0240
+#define A_BCM1480_NC_CREDIT_STATUS_REG3 0x00DFBD0260
+#define A_BCM1480_NC_CREDIT_STATUS_REG4 0x00DFBD0280
+#define A_BCM1480_NC_CREDIT_STATUS_REG5 0x00DFBD02A0
+#define A_BCM1480_NC_CREDIT_STATUS_REG6 0x00DFBD02C0
+#define A_BCM1480_NC_CREDIT_STATUS_REG7 0x00DFBD02E0
+#define A_BCM1480_NC_CREDIT_STATUS_REG8 0x00DFBD0300
+#define A_BCM1480_NC_CREDIT_STATUS_REG9 0x00DFBD0320
+#define A_BCM1480_NC_CREDIT_STATUS_REG10 0x00DFBE0000
+#define A_BCM1480_NC_CREDIT_STATUS_REG11 0x00DFBE0020
+#define A_BCM1480_NC_CREDIT_STATUS_REG12 0x00DFBE0040
+
+#define A_BCM1480_NC_SR_TIMEOUT_COUNTER 0x00DFBE0060
+#define A_BCM1480_NC_SR_TIMEOUT_COUNTER_SEL 0x00DFBE0080
+
+
+/* *********************************************************************
+ * H&R Block Configuration Registers (Section 12.4)
+ ********************************************************************* */
+
+#define A_BCM1480_HR_BASE_0 0x00DF820000
+#define A_BCM1480_HR_BASE_1 0x00DF8A0000
+#define A_BCM1480_HR_BASE_2 0x00DF920000
+#define BCM1480_HR_REGISTER_SPACING 0x80000
+
+#define A_BCM1480_HR_BASE(idx) (A_BCM1480_HR_BASE_0 + ((idx)*BCM1480_HR_REGISTER_SPACING))
+#define A_BCM1480_HR_REGISTER(idx,reg) (A_BCM1480_HR_BASE(idx) + (reg))
+
+#define R_BCM1480_HR_CFG 0x0000000000
+
+#define R_BCM1480_HR_MAPPING 0x0000010010
+
+#define BCM1480_HR_RULE_SPACING 0x0000000010
+#define BCM1480_HR_NUM_RULES 16
+#define BCM1480_HR_OP_OFFSET 0x0000000100
+#define BCM1480_HR_TYPE_OFFSET 0x0000000108
+#define R_BCM1480_HR_RULE_OP(idx) (BCM1480_HR_OP_OFFSET + ((idx)*BCM1480_HR_RULE_SPACING))
+#define R_BCM1480_HR_RULE_TYPE(idx) (BCM1480_HR_TYPE_OFFSET + ((idx)*BCM1480_HR_RULE_SPACING))
+
+#define BCM1480_HR_LEAF_SPACING 0x0000000010
+#define BCM1480_HR_NUM_LEAVES 10
+#define BCM1480_HR_LEAF_OFFSET 0x0000000300
+#define R_BCM1480_HR_HA_LEAF0(idx) (BCM1480_HR_LEAF_OFFSET + ((idx)*BCM1480_HR_LEAF_SPACING))
+
+#define R_BCM1480_HR_EX_LEAF0 0x00000003A0
+
+#define BCM1480_HR_PATH_SPACING 0x0000000010
+#define BCM1480_HR_NUM_PATHS 16
+#define BCM1480_HR_PATH_OFFSET 0x0000000600
+#define R_BCM1480_HR_PATH(idx) (BCM1480_HR_PATH_OFFSET + ((idx)*BCM1480_HR_PATH_SPACING))
+
+#define R_BCM1480_HR_PATH_DEFAULT 0x0000000700
+
+#define BCM1480_HR_ROUTE_SPACING 8
+#define BCM1480_HR_NUM_ROUTES 512
+#define BCM1480_HR_ROUTE_OFFSET 0x0000001000
+#define R_BCM1480_HR_RT_WORD(idx) (BCM1480_HR_ROUTE_OFFSET + ((idx)*BCM1480_HR_ROUTE_SPACING))
+
+
+/* checked to here - ehs */
+/* *********************************************************************
+ * Packet Manager DMA Registers (Section 12.5)
+ ********************************************************************* */
+
+#define A_BCM1480_PM_BASE 0x0010056000
+
+#define A_BCM1480_PMI_LCL_0 0x0010058000
+#define A_BCM1480_PMO_LCL_0 0x001005C000
+#define A_BCM1480_PMI_OFFSET_0 (A_BCM1480_PMI_LCL_0 - A_BCM1480_PM_BASE)
+#define A_BCM1480_PMO_OFFSET_0 (A_BCM1480_PMO_LCL_0 - A_BCM1480_PM_BASE)
+
+#define BCM1480_PM_LCL_REGISTER_SPACING 0x100
+#define BCM1480_PM_NUM_CHANNELS 32
+
+#define A_BCM1480_PMI_LCL_BASE(idx) (A_BCM1480_PMI_LCL_0 + ((idx)*BCM1480_PM_LCL_REGISTER_SPACING))
+#define A_BCM1480_PMI_LCL_REGISTER(idx,reg) (A_BCM1480_PMI_LCL_BASE(idx) + (reg))
+#define A_BCM1480_PMO_LCL_BASE(idx) (A_BCM1480_PMO_LCL_0 + ((idx)*BCM1480_PM_LCL_REGISTER_SPACING))
+#define A_BCM1480_PMO_LCL_REGISTER(idx,reg) (A_BCM1480_PMO_LCL_BASE(idx) + (reg))
+
+#define BCM1480_PM_INT_PACKING 8
+#define BCM1480_PM_INT_FUNCTION_SPACING 0x40
+#define BCM1480_PM_INT_NUM_FUNCTIONS 3
+
+/*
+ * DMA channel registers relative to A_BCM1480_PMI_LCL_BASE(n) and A_BCM1480_PMO_LCL_BASE(n)
+ */
+
+#define R_BCM1480_PM_BASE_SIZE 0x0000000000
+#define R_BCM1480_PM_CNT 0x0000000008
+#define R_BCM1480_PM_PFCNT 0x0000000010
+#define R_BCM1480_PM_LAST 0x0000000018
+#define R_BCM1480_PM_PFINDX 0x0000000020
+#define R_BCM1480_PM_INT_WMK 0x0000000028
+#define R_BCM1480_PM_CONFIG0 0x0000000030
+#define R_BCM1480_PM_LOCALDEBUG 0x0000000078
+#define R_BCM1480_PM_CACHEABILITY 0x0000000080 /* PMI only */
+#define R_BCM1480_PM_INT_CNFG 0x0000000088
+#define R_BCM1480_PM_DESC_MERGE_TIMER 0x0000000090
+#define R_BCM1480_PM_LOCALDEBUG_PIB 0x00000000F8 /* PMI only */
+#define R_BCM1480_PM_LOCALDEBUG_POB 0x00000000F8 /* PMO only */
+
+/*
+ * Global Registers (Not Channelized)
+ */
+
+#define A_BCM1480_PMI_GLB_0 0x0010056000
+#define A_BCM1480_PMO_GLB_0 0x0010057000
+
+/*
+ * PM to TX Mapping Register relative to A_BCM1480_PMI_GLB_0 and A_BCM1480_PMO_GLB_0
+ */
+
+#define R_BCM1480_PM_PMO_MAPPING 0x00000008C8 /* PMO only */
+
+#define A_BCM1480_PM_PMO_MAPPING (A_BCM1480_PMO_GLB_0 + R_BCM1480_PM_PMO_MAPPING)
+
+/*
+ * Interrupt mapping registers
+ */
+
+
+#define A_BCM1480_PMI_INT_0 0x0010056800
+#define A_BCM1480_PMI_INT(q) (A_BCM1480_PMI_INT_0 + ((q>>8)<<8))
+#define A_BCM1480_PMI_INT_OFFSET_0 (A_BCM1480_PMI_INT_0 - A_BCM1480_PM_BASE)
+#define A_BCM1480_PMO_INT_0 0x0010057800
+#define A_BCM1480_PMO_INT(q) (A_BCM1480_PMO_INT_0 + ((q>>8)<<8))
+#define A_BCM1480_PMO_INT_OFFSET_0 (A_BCM1480_PMO_INT_0 - A_BCM1480_PM_BASE)
+
+/*
+ * Interrupt registers relative to A_BCM1480_PMI_INT_0 and A_BCM1480_PMO_INT_0
+ */
+
+#define R_BCM1480_PM_INT_ST 0x0000000000
+#define R_BCM1480_PM_INT_MSK 0x0000000040
+#define R_BCM1480_PM_INT_CLR 0x0000000080
+#define R_BCM1480_PM_MRGD_INT 0x00000000C0
+
+/*
+ * Debug registers (global)
+ */
+
+#define A_BCM1480_PM_GLOBALDEBUGMODE_PMI 0x0010056000
+#define A_BCM1480_PM_GLOBALDEBUG_PID 0x00100567F8
+#define A_BCM1480_PM_GLOBALDEBUG_PIB 0x0010056FF8
+#define A_BCM1480_PM_GLOBALDEBUGMODE_PMO 0x0010057000
+#define A_BCM1480_PM_GLOBALDEBUG_POD 0x00100577F8
+#define A_BCM1480_PM_GLOBALDEBUG_POB 0x0010057FF8
+
+/* *********************************************************************
+ * Switch performance counters
+ ********************************************************************* */
+
+#define A_BCM1480_SWPERF_CFG 0xdfb91800
+#define A_BCM1480_SWPERF_CNT0 0xdfb91880
+#define A_BCM1480_SWPERF_CNT1 0xdfb91888
+#define A_BCM1480_SWPERF_CNT2 0xdfb91890
+#define A_BCM1480_SWPERF_CNT3 0xdfb91898
+
+
+/* *********************************************************************
+ * Switch Trace Unit
+ ********************************************************************* */
+
+#define A_BCM1480_SWTRC_MATCH_CONTROL_0 0xDFB91000
+#define A_BCM1480_SWTRC_MATCH_DATA_VALUE_0 0xDFB91100
+#define A_BCM1480_SWTRC_MATCH_DATA_MASK_0 0xDFB91108
+#define A_BCM1480_SWTRC_MATCH_TAG_VALUE_0 0xDFB91200
+#define A_BCM1480_SWTRC_MATCH_TAG_MAKS_0 0xDFB91208
+#define A_BCM1480_SWTRC_EVENT_0 0xDFB91300
+#define A_BCM1480_SWTRC_SEQUENCE_0 0xDFB91400
+
+#define A_BCM1480_SWTRC_CFG 0xDFB91500
+#define A_BCM1480_SWTRC_READ 0xDFB91508
+
+#define A_BCM1480_SWDEBUG_SCHEDSTOP 0xDFB92000
+
+#define A_BCM1480_SWTRC_MATCH_CONTROL(x) (A_BCM1480_SWTRC_MATCH_CONTROL_0 + ((x)*8))
+#define A_BCM1480_SWTRC_EVENT(x) (A_BCM1480_SWTRC_EVENT_0 + ((x)*8))
+#define A_BCM1480_SWTRC_SEQUENCE(x) (A_BCM1480_SWTRC_SEQUENCE_0 + ((x)*8))
+
+#define A_BCM1480_SWTRC_MATCH_DATA_VALUE(x) (A_BCM1480_SWTRC_MATCH_DATA_VALUE_0 + ((x)*16))
+#define A_BCM1480_SWTRC_MATCH_DATA_MASK(x) (A_BCM1480_SWTRC_MATCH_DATA_MASK_0 + ((x)*16))
+#define A_BCM1480_SWTRC_MATCH_TAG_VALUE(x) (A_BCM1480_SWTRC_MATCH_TAG_VALUE_0 + ((x)*16))
+#define A_BCM1480_SWTRC_MATCH_TAG_MASK(x) (A_BCM1480_SWTRC_MATCH_TAG_MASK_0 + ((x)*16))
+
+
+
+/* *********************************************************************
+ * High-Speed Port Registers (Section 13)
+ ********************************************************************* */
+
+#define A_BCM1480_HSP_BASE_0 0x00DF810000
+#define A_BCM1480_HSP_BASE_1 0x00DF890000
+#define A_BCM1480_HSP_BASE_2 0x00DF910000
+#define BCM1480_HSP_REGISTER_SPACING 0x80000
+
+#define A_BCM1480_HSP_BASE(idx) (A_BCM1480_HSP_BASE_0 + ((idx)*BCM1480_HSP_REGISTER_SPACING))
+#define A_BCM1480_HSP_REGISTER(idx,reg) (A_BCM1480_HSP_BASE(idx) + (reg))
+
+#define R_BCM1480_HSP_RX_SPI4_CFG_0 0x0000000000
+#define R_BCM1480_HSP_RX_SPI4_CFG_1 0x0000000008
+#define R_BCM1480_HSP_RX_SPI4_DESKEW_OVERRIDE 0x0000000010
+#define R_BCM1480_HSP_RX_SPI4_DESKEW_DATAPATH 0x0000000018
+#define R_BCM1480_HSP_RX_SPI4_PORT_INT_EN 0x0000000020
+#define R_BCM1480_HSP_RX_SPI4_PORT_INT_STATUS 0x0000000028
+
+#define R_BCM1480_HSP_RX_SPI4_CALENDAR_0 0x0000000200
+#define R_BCM1480_HSP_RX_SPI4_CALENDAR_1 0x0000000208
+
+#define R_BCM1480_HSP_RX_PLL_CNFG 0x0000000800
+#define R_BCM1480_HSP_RX_CALIBRATION 0x0000000808
+#define R_BCM1480_HSP_RX_TEST 0x0000000810
+#define R_BCM1480_HSP_RX_DIAG_DETAILS 0x0000000818
+#define R_BCM1480_HSP_RX_DIAG_CRC_0 0x0000000820
+#define R_BCM1480_HSP_RX_DIAG_CRC_1 0x0000000828
+#define R_BCM1480_HSP_RX_DIAG_HTCMD 0x0000000830
+#define R_BCM1480_HSP_RX_DIAG_PKTCTL 0x0000000838
+
+#define R_BCM1480_HSP_RX_VIS_FLCTRL_COUNTER 0x0000000870
+
+#define R_BCM1480_HSP_RX_PKT_RAMALLOC_0 0x0000020020
+#define R_BCM1480_HSP_RX_PKT_RAMALLOC_1 0x0000020028
+#define R_BCM1480_HSP_RX_PKT_RAMALLOC_2 0x0000020030
+#define R_BCM1480_HSP_RX_PKT_RAMALLOC_3 0x0000020038
+#define R_BCM1480_HSP_RX_PKT_RAMALLOC_4 0x0000020040
+#define R_BCM1480_HSP_RX_PKT_RAMALLOC_5 0x0000020048
+#define R_BCM1480_HSP_RX_PKT_RAMALLOC_6 0x0000020050
+#define R_BCM1480_HSP_RX_PKT_RAMALLOC_7 0x0000020058
+#define R_BCM1480_HSP_RX_PKT_RAMALLOC(idx) (R_BCM1480_HSP_RX_PKT_RAMALLOC_0 + 8*(idx))
+
+/* XXX Following registers were shuffled. Renamed/renumbered per errata. */
+#define R_BCM1480_HSP_RX_HT_RAMALLOC_0 0x0000020078
+#define R_BCM1480_HSP_RX_HT_RAMALLOC_1 0x0000020080
+#define R_BCM1480_HSP_RX_HT_RAMALLOC_2 0x0000020088
+#define R_BCM1480_HSP_RX_HT_RAMALLOC_3 0x0000020090
+#define R_BCM1480_HSP_RX_HT_RAMALLOC_4 0x0000020098
+#define R_BCM1480_HSP_RX_HT_RAMALLOC_5 0x00000200A0
+
+#define R_BCM1480_HSP_RX_SPI_WATERMARK_0 0x00000200B0
+#define R_BCM1480_HSP_RX_SPI_WATERMARK_1 0x00000200B8
+#define R_BCM1480_HSP_RX_SPI_WATERMARK_2 0x00000200C0
+#define R_BCM1480_HSP_RX_SPI_WATERMARK_3 0x00000200C8
+#define R_BCM1480_HSP_RX_SPI_WATERMARK_4 0x00000200D0
+#define R_BCM1480_HSP_RX_SPI_WATERMARK_5 0x00000200D8
+#define R_BCM1480_HSP_RX_SPI_WATERMARK_6 0x00000200E0
+#define R_BCM1480_HSP_RX_SPI_WATERMARK_7 0x00000200E8
+#define R_BCM1480_HSP_RX_SPI_WATERMARK(idx) (R_BCM1480_HSP_RX_SPI_WATERMARK_0 + 8*(idx))
+
+#define R_BCM1480_HSP_RX_VIS_CMDQ_0 0x00000200F0
+#define R_BCM1480_HSP_RX_VIS_CMDQ_1 0x00000200F8
+#define R_BCM1480_HSP_RX_VIS_CMDQ_2 0x0000020100
+#define R_BCM1480_HSP_RX_RAM_READCTL 0x0000020108
+#define R_BCM1480_HSP_RX_RAM_READWINDOW 0x0000020110
+#define R_BCM1480_HSP_RX_RF_READCTL 0x0000020118
+#define R_BCM1480_HSP_RX_RF_READWINDOW 0x0000020120
+
+#define R_BCM1480_HSP_TX_SPI4_CFG_0 0x0000040000
+#define R_BCM1480_HSP_TX_SPI4_CFG_1 0x0000040008
+#define R_BCM1480_HSP_TX_SPI4_TRAINING_FMT 0x0000040010
+
+#define R_BCM1480_HSP_TX_PKT_RAMALLOC_0 0x0000040020
+#define R_BCM1480_HSP_TX_PKT_RAMALLOC_1 0x0000040028
+#define R_BCM1480_HSP_TX_PKT_RAMALLOC_2 0x0000040030
+#define R_BCM1480_HSP_TX_PKT_RAMALLOC_3 0x0000040038
+#define R_BCM1480_HSP_TX_PKT_RAMALLOC_4 0x0000040040
+#define R_BCM1480_HSP_TX_PKT_RAMALLOC_5 0x0000040048
+#define R_BCM1480_HSP_TX_PKT_RAMALLOC_6 0x0000040050
+#define R_BCM1480_HSP_TX_PKT_RAMALLOC_7 0x0000040058
+#define R_BCM1480_HSP_TX_PKT_RAMALLOC(idx) (R_BCM1480_HSP_TX_PKT_RAMALLOC_0 + 8*(idx))
+#define R_BCM1480_HSP_TX_NPC_RAMALLOC 0x0000040078
+#define R_BCM1480_HSP_TX_RSP_RAMALLOC 0x0000040080
+#define R_BCM1480_HSP_TX_PC_RAMALLOC 0x0000040088
+#define R_BCM1480_HSP_TX_HTCC_RAMALLOC_0 0x0000040090
+#define R_BCM1480_HSP_TX_HTCC_RAMALLOC_1 0x0000040098
+#define R_BCM1480_HSP_TX_HTCC_RAMALLOC_2 0x00000400A0
+
+#define R_BCM1480_HSP_TX_PKT_RXPHITCNT_0 0x00000400B0
+#define R_BCM1480_HSP_TX_PKT_RXPHITCNT_1 0x00000400B8
+#define R_BCM1480_HSP_TX_PKT_RXPHITCNT_2 0x00000400C0
+#define R_BCM1480_HSP_TX_PKT_RXPHITCNT_3 0x00000400C8
+#define R_BCM1480_HSP_TX_PKT_RXPHITCNT(idx) (R_BCM1480_HSP_TX_PKT_RXPHITCNT_0 + 8*(idx))
+#define R_BCM1480_HSP_TX_HTIO_RXPHITCNT 0x00000400D0
+#define R_BCM1480_HSP_TX_HTCC_RXPHITCNT 0x00000400D8
+
+#define R_BCM1480_HSP_TX_PKT_TXPHITCNT_0 0x00000400E0
+#define R_BCM1480_HSP_TX_PKT_TXPHITCNT_1 0x00000400E8
+#define R_BCM1480_HSP_TX_PKT_TXPHITCNT_2 0x00000400F0
+#define R_BCM1480_HSP_TX_PKT_TXPHITCNT_3 0x00000400F8
+#define R_BCM1480_HSP_TX_PKT_TXPHITCNT(idx) (R_BCM1480_HSP_TX_PKT_TXPHITCNT_0 + 8*(idx))
+#define R_BCM1480_HSP_TX_HTIO_TXPHITCNT 0x0000040100
+#define R_BCM1480_HSP_TX_HTCC_TXPHITCNT 0x0000040108
+
+#define R_BCM1480_HSP_TX_SPI4_CALENDAR_0 0x0000040200
+#define R_BCM1480_HSP_TX_SPI4_CALENDAR_1 0x0000040208
+
+#define R_BCM1480_HSP_TX_PLL_CNFG 0x0000040800
+#define R_BCM1480_HSP_TX_CALIBRATION 0x0000040808
+#define R_BCM1480_HSP_TX_TEST 0x0000040810
+
+#define R_BCM1480_HSP_TX_VIS_CMDQ_0 0x0000040840
+#define R_BCM1480_HSP_TX_VIS_CMDQ_1 0x0000040848
+#define R_BCM1480_HSP_TX_VIS_CMDQ_2 0x0000040850
+#define R_BCM1480_HSP_TX_RAM_READCTL 0x0000040860
+#define R_BCM1480_HSP_TX_RAM_READWINDOW 0x0000040868
+#define R_BCM1480_HSP_TX_RF_READCTL 0x0000040870
+#define R_BCM1480_HSP_TX_RF_READWINDOW 0x0000040878
+
+#define R_BCM1480_HSP_TX_SPI4_PORT_INT_STATUS 0x0000040880
+#define R_BCM1480_HSP_TX_SPI4_PORT_INT_EN 0x0000040888
+
+#define R_BCM1480_HSP_TX_NEXT_ADDR_BASE 0x000040400
+#define R_BCM1480_HSP_TX_NEXT_ADDR_REGISTER(x) (R_BCM1480_HSP_TX_NEXT_ADDR_BASE+ 8*(x))
+
+
+
+/* *********************************************************************
+ * Physical Address Map (Table 10 and Figure 7)
+ ********************************************************************* */
+
+#define A_BCM1480_PHYS_MEMORY_0 _SB_MAKE64(0x0000000000)
+#define A_BCM1480_PHYS_MEMORY_SIZE _SB_MAKE64((256*1024*1024))
+#define A_BCM1480_PHYS_SYSTEM_CTL _SB_MAKE64(0x0010000000)
+#define A_BCM1480_PHYS_IO_SYSTEM _SB_MAKE64(0x0010060000)
+#define A_BCM1480_PHYS_GENBUS _SB_MAKE64(0x0010090000)
+#define A_BCM1480_PHYS_GENBUS_END _SB_MAKE64(0x0028000000)
+#define A_BCM1480_PHYS_PCI_MISC_MATCH_BYTES _SB_MAKE64(0x0028000000)
+#define A_BCM1480_PHYS_PCI_IACK_MATCH_BYTES _SB_MAKE64(0x0029000000)
+#define A_BCM1480_PHYS_PCI_IO_MATCH_BYTES _SB_MAKE64(0x002C000000)
+#define A_BCM1480_PHYS_PCI_CFG_MATCH_BYTES _SB_MAKE64(0x002E000000)
+#define A_BCM1480_PHYS_PCI_OMAP_MATCH_BYTES _SB_MAKE64(0x002F000000)
+#define A_BCM1480_PHYS_PCI_MEM_MATCH_BYTES _SB_MAKE64(0x0030000000)
+#define A_BCM1480_PHYS_HT_MEM_MATCH_BYTES _SB_MAKE64(0x0040000000)
+#define A_BCM1480_PHYS_HT_MEM_MATCH_BITS _SB_MAKE64(0x0060000000)
+#define A_BCM1480_PHYS_MEMORY_1 _SB_MAKE64(0x0080000000)
+#define A_BCM1480_PHYS_MEMORY_2 _SB_MAKE64(0x0090000000)
+#define A_BCM1480_PHYS_PCI_MISC_MATCH_BITS _SB_MAKE64(0x00A8000000)
+#define A_BCM1480_PHYS_PCI_IACK_MATCH_BITS _SB_MAKE64(0x00A9000000)
+#define A_BCM1480_PHYS_PCI_IO_MATCH_BITS _SB_MAKE64(0x00AC000000)
+#define A_BCM1480_PHYS_PCI_CFG_MATCH_BITS _SB_MAKE64(0x00AE000000)
+#define A_BCM1480_PHYS_PCI_OMAP_MATCH_BITS _SB_MAKE64(0x00AF000000)
+#define A_BCM1480_PHYS_PCI_MEM_MATCH_BITS _SB_MAKE64(0x00B0000000)
+#define A_BCM1480_PHYS_MEMORY_3 _SB_MAKE64(0x00C0000000)
+#define A_BCM1480_PHYS_L2_CACHE_TEST _SB_MAKE64(0x00D0000000)
+#define A_BCM1480_PHYS_HT_SPECIAL_MATCH_BYTES _SB_MAKE64(0x00D8000000)
+#define A_BCM1480_PHYS_HT_IO_MATCH_BYTES _SB_MAKE64(0x00DC000000)
+#define A_BCM1480_PHYS_HT_CFG_MATCH_BYTES _SB_MAKE64(0x00DE000000)
+#define A_BCM1480_PHYS_HS_SUBSYS _SB_MAKE64(0x00DF000000)
+#define A_BCM1480_PHYS_HT_SPECIAL_MATCH_BITS _SB_MAKE64(0x00F8000000)
+#define A_BCM1480_PHYS_HT_IO_MATCH_BITS _SB_MAKE64(0x00FC000000)
+#define A_BCM1480_PHYS_HT_CFG_MATCH_BITS _SB_MAKE64(0x00FE000000)
+#define A_BCM1480_PHYS_MEMORY_EXP _SB_MAKE64(0x0100000000)
+#define A_BCM1480_PHYS_MEMORY_EXP_SIZE _SB_MAKE64((508*1024*1024*1024))
+#define A_BCM1480_PHYS_PCI_UPPER _SB_MAKE64(0x1000000000)
+#define A_BCM1480_PHYS_HT_UPPER_MATCH_BYTES _SB_MAKE64(0x2000000000)
+#define A_BCM1480_PHYS_HT_UPPER_MATCH_BITS _SB_MAKE64(0x3000000000)
+#define A_BCM1480_PHYS_HT_NODE_ALIAS _SB_MAKE64(0x4000000000)
+#define A_BCM1480_PHYS_HT_FULLACCESS _SB_MAKE64(0xF000000000)
+
+
+/* *********************************************************************
+ * L2 Cache as RAM (Table 54)
+ ********************************************************************* */
+
+#define A_BCM1480_PHYS_L2CACHE_WAY_SIZE _SB_MAKE64(0x0000020000)
+#define BCM1480_PHYS_L2CACHE_NUM_WAYS 8
+#define A_BCM1480_PHYS_L2CACHE_TOTAL_SIZE _SB_MAKE64(0x0000100000)
+#define A_BCM1480_PHYS_L2CACHE_WAY0 _SB_MAKE64(0x00D0300000)
+#define A_BCM1480_PHYS_L2CACHE_WAY1 _SB_MAKE64(0x00D0320000)
+#define A_BCM1480_PHYS_L2CACHE_WAY2 _SB_MAKE64(0x00D0340000)
+#define A_BCM1480_PHYS_L2CACHE_WAY3 _SB_MAKE64(0x00D0360000)
+#define A_BCM1480_PHYS_L2CACHE_WAY4 _SB_MAKE64(0x00D0380000)
+#define A_BCM1480_PHYS_L2CACHE_WAY5 _SB_MAKE64(0x00D03A0000)
+#define A_BCM1480_PHYS_L2CACHE_WAY6 _SB_MAKE64(0x00D03C0000)
+#define A_BCM1480_PHYS_L2CACHE_WAY7 _SB_MAKE64(0x00D03E0000)
+
+#endif /* _BCM1480_REGS_H */
diff --git a/include/asm-mips/sibyte/bcm1480_scd.h b/include/asm-mips/sibyte/bcm1480_scd.h
new file mode 100644
index 000000000000..648bed96780f
--- /dev/null
+++ b/include/asm-mips/sibyte/bcm1480_scd.h
@@ -0,0 +1,436 @@
+/* *********************************************************************
+ * BCM1280/BCM1400 Board Support Package
+ *
+ * SCD Constants and Macros File: bcm1480_scd.h
+ *
+ * This module contains constants and macros useful for
+ * manipulating the System Control and Debug module.
+ *
+ * BCM1400 specification level: 1X55_1X80-UM100-R (12/18/03)
+ *
+ *********************************************************************
+ *
+ * Copyright 2000,2001,2002,2003
+ * Broadcom Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ ********************************************************************* */
+
+#ifndef _BCM1480_SCD_H
+#define _BCM1480_SCD_H
+
+#include "sb1250_defs.h"
+
+/* *********************************************************************
+ * Pull in the BCM1250's SCD since lots of stuff is the same.
+ ********************************************************************* */
+
+#include "sb1250_scd.h"
+
+/* *********************************************************************
+ * Some general notes:
+ *
+ * This file is basically a "what's new" header file. Since the
+ * BCM1250 and the new BCM1480 (and derivatives) share many common
+ * features, this file contains only what's new or changed from
+ * the 1250. (above, you can see that we include the 1250 symbols
+ * to get the base functionality).
+ *
+ * In software, be sure to use the correct symbols, particularly
+ * for blocks that are different between the two chip families.
+ * All BCM1480-specific symbols have _BCM1480_ in their names,
+ * and all BCM1250-specific and "base" functions that are common in
+ * both chips have no special names (this is for compatibility with
+ * older include files). Therefore, if you're working with the
+ * SCD, which is very different on each chip, A_SCD_xxx implies
+ * the BCM1250 version and A_BCM1480_SCD_xxx implies the BCM1480
+ * version.
+ ********************************************************************* */
+
+/* *********************************************************************
+ * System control/debug registers
+ ********************************************************************* */
+
+/*
+ * System Identification and Revision Register (Table 12)
+ * Register: SCD_SYSTEM_REVISION
+ * This register is field compatible with the 1250.
+ */
+
+/*
+ * New part definitions
+ */
+
+#define K_SYS_PART_BCM1480 0x1406
+#define K_SYS_PART_BCM1280 0x1206
+#define K_SYS_PART_BCM1455 0x1407
+#define K_SYS_PART_BCM1255 0x1257
+
+/*
+ * Manufacturing Information Register (Table 14)
+ * Register: SCD_SYSTEM_MANUF
+ */
+
+/*
+ * System Configuration Register (Table 15)
+ * Register: SCD_SYSTEM_CFG
+ * Entire register is different from 1250, all new constants below
+ */
+
+#define M_BCM1480_SYS_RESERVED0 _SB_MAKEMASK1(0)
+#define M_BCM1480_SYS_HT_MINRSTCNT _SB_MAKEMASK1(1)
+#define M_BCM1480_SYS_RESERVED2 _SB_MAKEMASK1(2)
+#define M_BCM1480_SYS_RESERVED3 _SB_MAKEMASK1(3)
+#define M_BCM1480_SYS_RESERVED4 _SB_MAKEMASK1(4)
+#define M_BCM1480_SYS_IOB_DIV _SB_MAKEMASK1(5)
+
+#define S_BCM1480_SYS_PLL_DIV _SB_MAKE64(6)
+#define M_BCM1480_SYS_PLL_DIV _SB_MAKEMASK(5,S_BCM1480_SYS_PLL_DIV)
+#define V_BCM1480_SYS_PLL_DIV(x) _SB_MAKEVALUE(x,S_BCM1480_SYS_PLL_DIV)
+#define G_BCM1480_SYS_PLL_DIV(x) _SB_GETVALUE(x,S_BCM1480_SYS_PLL_DIV,M_BCM1480_SYS_PLL_DIV)
+
+#define S_BCM1480_SYS_SW_DIV _SB_MAKE64(11)
+#define M_BCM1480_SYS_SW_DIV _SB_MAKEMASK(5,S_BCM1480_SYS_SW_DIV)
+#define V_BCM1480_SYS_SW_DIV(x) _SB_MAKEVALUE(x,S_BCM1480_SYS_SW_DIV)
+#define G_BCM1480_SYS_SW_DIV(x) _SB_GETVALUE(x,S_BCM1480_SYS_SW_DIV,M_BCM1480_SYS_SW_DIV)
+
+#define M_BCM1480_SYS_PCMCIA_ENABLE _SB_MAKEMASK1(16)
+#define M_BCM1480_SYS_DUART1_ENABLE _SB_MAKEMASK1(17)
+
+#define S_BCM1480_SYS_BOOT_MODE _SB_MAKE64(18)
+#define M_BCM1480_SYS_BOOT_MODE _SB_MAKEMASK(2,S_BCM1480_SYS_BOOT_MODE)
+#define V_BCM1480_SYS_BOOT_MODE(x) _SB_MAKEVALUE(x,S_BCM1480_SYS_BOOT_MODE)
+#define G_BCM1480_SYS_BOOT_MODE(x) _SB_GETVALUE(x,S_BCM1480_SYS_BOOT_MODE,M_BCM1480_SYS_BOOT_MODE)
+#define K_BCM1480_SYS_BOOT_MODE_ROM32 0
+#define K_BCM1480_SYS_BOOT_MODE_ROM8 1
+#define K_BCM1480_SYS_BOOT_MODE_SMBUS_SMALL 2
+#define K_BCM1480_SYS_BOOT_MODE_SMBUS_BIG 3
+#define M_BCM1480_SYS_BOOT_MODE_SMBUS _SB_MAKEMASK1(19)
+
+#define M_BCM1480_SYS_PCI_HOST _SB_MAKEMASK1(20)
+#define M_BCM1480_SYS_PCI_ARBITER _SB_MAKEMASK1(21)
+#define M_BCM1480_SYS_BIG_ENDIAN _SB_MAKEMASK1(22)
+#define M_BCM1480_SYS_GENCLK_EN _SB_MAKEMASK1(23)
+#define M_BCM1480_SYS_GEN_PARITY_EN _SB_MAKEMASK1(24)
+#define M_BCM1480_SYS_RESERVED25 _SB_MAKEMASK1(25)
+
+#define S_BCM1480_SYS_CONFIG 26
+#define M_BCM1480_SYS_CONFIG _SB_MAKEMASK(6,S_BCM1480_SYS_CONFIG)
+#define V_BCM1480_SYS_CONFIG(x) _SB_MAKEVALUE(x,S_BCM1480_SYS_CONFIG)
+#define G_BCM1480_SYS_CONFIG(x) _SB_GETVALUE(x,S_BCM1480_SYS_CONFIG,M_BCM1480_SYS_CONFIG)
+
+#define M_BCM1480_SYS_RESERVED32 _SB_MAKEMASK(32,15)
+
+#define S_BCM1480_SYS_NODEID 47
+#define M_BCM1480_SYS_NODEID _SB_MAKEMASK(4,S_BCM1480_SYS_NODEID)
+#define V_BCM1480_SYS_NODEID(x) _SB_MAKEVALUE(x,S_BCM1480_SYS_NODEID)
+#define G_BCM1480_SYS_NODEID(x) _SB_GETVALUE(x,S_BCM1480_SYS_NODEID,M_BCM1480_SYS_NODEID)
+
+#define M_BCM1480_SYS_CCNUMA_EN _SB_MAKEMASK1(51)
+#define M_BCM1480_SYS_CPU_RESET_0 _SB_MAKEMASK1(52)
+#define M_BCM1480_SYS_CPU_RESET_1 _SB_MAKEMASK1(53)
+#define M_BCM1480_SYS_CPU_RESET_2 _SB_MAKEMASK1(54)
+#define M_BCM1480_SYS_CPU_RESET_3 _SB_MAKEMASK1(55)
+#define S_BCM1480_SYS_DISABLECPU0 56
+#define M_BCM1480_SYS_DISABLECPU0 _SB_MAKEMASK1(S_BCM1480_SYS_DISABLECPU0)
+#define S_BCM1480_SYS_DISABLECPU1 57
+#define M_BCM1480_SYS_DISABLECPU1 _SB_MAKEMASK1(S_BCM1480_SYS_DISABLECPU1)
+#define S_BCM1480_SYS_DISABLECPU2 58
+#define M_BCM1480_SYS_DISABLECPU2 _SB_MAKEMASK1(S_BCM1480_SYS_DISABLECPU2)
+#define S_BCM1480_SYS_DISABLECPU3 59
+#define M_BCM1480_SYS_DISABLECPU3 _SB_MAKEMASK1(S_BCM1480_SYS_DISABLECPU3)
+
+#define M_BCM1480_SYS_SB_SOFTRES _SB_MAKEMASK1(60)
+#define M_BCM1480_SYS_EXT_RESET _SB_MAKEMASK1(61)
+#define M_BCM1480_SYS_SYSTEM_RESET _SB_MAKEMASK1(62)
+#define M_BCM1480_SYS_SW_FLAG _SB_MAKEMASK1(63)
+
+/*
+ * Scratch Register (Table 16)
+ * Register: SCD_SYSTEM_SCRATCH
+ * Same as BCM1250
+ */
+
+
+/*
+ * Mailbox Registers (Table 17)
+ * Registers: SCD_MBOX_{0,1}_CPU_x
+ * Same as BCM1250
+ */
+
+
+/*
+ * See bcm1480_int.h for interrupt mapper registers.
+ */
+
+
+/*
+ * Watchdog Timer Initial Count Registers (Table 23)
+ * Registers: SCD_WDOG_INIT_CNT_x
+ *
+ * The watchdogs are almost the same as the 1250, except
+ * the configuration register has more bits to control the
+ * other CPUs.
+ */
+
+
+/*
+ * Watchdog Timer Configuration Registers (Table 25)
+ * Registers: SCD_WDOG_CFG_x
+ */
+
+#define M_BCM1480_SCD_WDOG_ENABLE _SB_MAKEMASK1(0)
+
+#define S_BCM1480_SCD_WDOG_RESET_TYPE 2
+#define M_BCM1480_SCD_WDOG_RESET_TYPE _SB_MAKEMASK(5,S_BCM1480_SCD_WDOG_RESET_TYPE)
+#define V_BCM1480_SCD_WDOG_RESET_TYPE(x) _SB_MAKEVALUE(x,S_BCM1480_SCD_WDOG_RESET_TYPE)
+#define G_BCM1480_SCD_WDOG_RESET_TYPE(x) _SB_GETVALUE(x,S_BCM1480_SCD_WDOG_RESET_TYPE,M_BCM1480_SCD_WDOG_RESET_TYPE)
+
+#define K_BCM1480_SCD_WDOG_RESET_FULL 0 /* actually, (x & 1) == 0 */
+#define K_BCM1480_SCD_WDOG_RESET_SOFT 1
+#define K_BCM1480_SCD_WDOG_RESET_CPU0 3
+#define K_BCM1480_SCD_WDOG_RESET_CPU1 5
+#define K_BCM1480_SCD_WDOG_RESET_CPU2 9
+#define K_BCM1480_SCD_WDOG_RESET_CPU3 17
+#define K_BCM1480_SCD_WDOG_RESET_ALL_CPUS 31
+
+
+#define M_BCM1480_SCD_WDOG_HAS_RESET _SB_MAKEMASK1(8)
+
+/*
+ * General Timer Initial Count Registers (Table 26)
+ * Registers: SCD_TIMER_INIT_x
+ *
+ * The timer registers are the same as the BCM1250
+ */
+
+
+/*
+ * ZBbus Count Register (Table 29)
+ * Register: ZBBUS_CYCLE_COUNT
+ *
+ * Same as BCM1250
+ */
+
+/*
+ * ZBbus Compare Registers (Table 30)
+ * Registers: ZBBUS_CYCLE_CPx
+ *
+ * Same as BCM1250
+ */
+
+
+/*
+ * System Performance Counter Configuration Register (Table 31)
+ * Register: PERF_CNT_CFG_0
+ *
+ * Since the clear/enable bits are moved compared to the
+ * 1250 and there are more fields, this register will be BCM1480 specific.
+ */
+
+#define S_BCM1480_SPC_CFG_SRC0 0
+#define M_BCM1480_SPC_CFG_SRC0 _SB_MAKEMASK(8,S_BCM1480_SPC_CFG_SRC0)
+#define V_BCM1480_SPC_CFG_SRC0(x) _SB_MAKEVALUE(x,S_BCM1480_SPC_CFG_SRC0)
+#define G_BCM1480_SPC_CFG_SRC0(x) _SB_GETVALUE(x,S_BCM1480_SPC_CFG_SRC0,M_BCM1480_SPC_CFG_SRC0)
+
+#define S_BCM1480_SPC_CFG_SRC1 8
+#define M_BCM1480_SPC_CFG_SRC1 _SB_MAKEMASK(8,S_BCM1480_SPC_CFG_SRC1)
+#define V_BCM1480_SPC_CFG_SRC1(x) _SB_MAKEVALUE(x,S_BCM1480_SPC_CFG_SRC1)
+#define G_BCM1480_SPC_CFG_SRC1(x) _SB_GETVALUE(x,S_BCM1480_SPC_CFG_SRC1,M_BCM1480_SPC_CFG_SRC1)
+
+#define S_BCM1480_SPC_CFG_SRC2 16
+#define M_BCM1480_SPC_CFG_SRC2 _SB_MAKEMASK(8,S_BCM1480_SPC_CFG_SRC2)
+#define V_BCM1480_SPC_CFG_SRC2(x) _SB_MAKEVALUE(x,S_BCM1480_SPC_CFG_SRC2)
+#define G_BCM1480_SPC_CFG_SRC2(x) _SB_GETVALUE(x,S_BCM1480_SPC_CFG_SRC2,M_BCM1480_SPC_CFG_SRC2)
+
+#define S_BCM1480_SPC_CFG_SRC3 24
+#define M_BCM1480_SPC_CFG_SRC3 _SB_MAKEMASK(8,S_BCM1480_SPC_CFG_SRC3)
+#define V_BCM1480_SPC_CFG_SRC3(x) _SB_MAKEVALUE(x,S_BCM1480_SPC_CFG_SRC3)
+#define G_BCM1480_SPC_CFG_SRC3(x) _SB_GETVALUE(x,S_BCM1480_SPC_CFG_SRC3,M_BCM1480_SPC_CFG_SRC3)
+
+#define S_BCM1480_SPC_CFG_SRC4 32
+#define M_BCM1480_SPC_CFG_SRC4 _SB_MAKEMASK(8,S_BCM1480_SPC_CFG_SRC4)
+#define V_BCM1480_SPC_CFG_SRC4(x) _SB_MAKEVALUE(x,S_BCM1480_SPC_CFG_SRC4)
+#define G_BCM1480_SPC_CFG_SRC4(x) _SB_GETVALUE(x,S_BCM1480_SPC_CFG_SRC4,M_BCM1480_SPC_CFG_SRC4)
+
+#define S_BCM1480_SPC_CFG_SRC5 40
+#define M_BCM1480_SPC_CFG_SRC5 _SB_MAKEMASK(8,S_BCM1480_SPC_CFG_SRC5)
+#define V_BCM1480_SPC_CFG_SRC5(x) _SB_MAKEVALUE(x,S_BCM1480_SPC_CFG_SRC5)
+#define G_BCM1480_SPC_CFG_SRC5(x) _SB_GETVALUE(x,S_BCM1480_SPC_CFG_SRC5,M_BCM1480_SPC_CFG_SRC5)
+
+#define S_BCM1480_SPC_CFG_SRC6 48
+#define M_BCM1480_SPC_CFG_SRC6 _SB_MAKEMASK(8,S_BCM1480_SPC_CFG_SRC6)
+#define V_BCM1480_SPC_CFG_SRC6(x) _SB_MAKEVALUE(x,S_BCM1480_SPC_CFG_SRC6)
+#define G_BCM1480_SPC_CFG_SRC6(x) _SB_GETVALUE(x,S_BCM1480_SPC_CFG_SRC6,M_BCM1480_SPC_CFG_SRC6)
+
+#define S_BCM1480_SPC_CFG_SRC7 56
+#define M_BCM1480_SPC_CFG_SRC7 _SB_MAKEMASK(8,S_BCM1480_SPC_CFG_SRC7)
+#define V_BCM1480_SPC_CFG_SRC7(x) _SB_MAKEVALUE(x,S_BCM1480_SPC_CFG_SRC7)
+#define G_BCM1480_SPC_CFG_SRC7(x) _SB_GETVALUE(x,S_BCM1480_SPC_CFG_SRC7,M_BCM1480_SPC_CFG_SRC7)
+
+/*
+ * System Performance Counter Control Register (Table 32)
+ * Register: PERF_CNT_CFG_1
+ * BCM1480 specific
+ */
+
+#define M_BCM1480_SPC_CFG_CLEAR _SB_MAKEMASK1(0)
+#define M_BCM1480_SPC_CFG_ENABLE _SB_MAKEMASK1(1)
+
+/*
+ * System Performance Counters (Table 33)
+ * Registers: PERF_CNT_x
+ */
+
+#define S_BCM1480_SPC_CNT_COUNT 0
+#define M_BCM1480_SPC_CNT_COUNT _SB_MAKEMASK(40,S_BCM1480_SPC_CNT_COUNT)
+#define V_BCM1480_SPC_CNT_COUNT(x) _SB_MAKEVALUE(x,S_BCM1480_SPC_CNT_COUNT)
+#define G_BCM1480_SPC_CNT_COUNT(x) _SB_GETVALUE(x,S_BCM1480_SPC_CNT_COUNT,M_BCM1480_SPC_CNT_COUNT)
+
+#define M_BCM1480_SPC_CNT_OFLOW _SB_MAKEMASK1(40)
+
+
+/*
+ * Bus Watcher Error Status Register (Tables 36, 37)
+ * Registers: BUS_ERR_STATUS, BUS_ERR_STATUS_DEBUG
+ * Same as BCM1250.
+ */
+
+/*
+ * Bus Watcher Error Data Registers (Table 38)
+ * Registers: BUS_ERR_DATA_x
+ * Same as BCM1250.
+ */
+
+/*
+ * Bus Watcher L2 ECC Counter Register (Table 39)
+ * Register: BUS_L2_ERRORS
+ * Same as BCM1250.
+ */
+
+
+/*
+ * Bus Watcher Memory and I/O Error Counter Register (Table 40)
+ * Register: BUS_MEM_IO_ERRORS
+ * Same as BCM1250.
+ */
+
+
+/*
+ * Address Trap Registers
+ *
+ * Register layout same as BCM1250, almost. The bus agents
+ * are different, and the address trap configuration bits are
+ * slightly different.
+ */
+
+#define M_BCM1480_ATRAP_INDEX _SB_MAKEMASK(4,0)
+#define M_BCM1480_ATRAP_ADDRESS _SB_MAKEMASK(40,0)
+
+#define S_BCM1480_ATRAP_CFG_CNT 0
+#define M_BCM1480_ATRAP_CFG_CNT _SB_MAKEMASK(3,S_BCM1480_ATRAP_CFG_CNT)
+#define V_BCM1480_ATRAP_CFG_CNT(x) _SB_MAKEVALUE(x,S_BCM1480_ATRAP_CFG_CNT)
+#define G_BCM1480_ATRAP_CFG_CNT(x) _SB_GETVALUE(x,S_BCM1480_ATRAP_CFG_CNT,M_BCM1480_ATRAP_CFG_CNT)
+
+#define M_BCM1480_ATRAP_CFG_WRITE _SB_MAKEMASK1(3)
+#define M_BCM1480_ATRAP_CFG_ALL _SB_MAKEMASK1(4)
+#define M_BCM1480_ATRAP_CFG_INV _SB_MAKEMASK1(5)
+#define M_BCM1480_ATRAP_CFG_USESRC _SB_MAKEMASK1(6)
+#define M_BCM1480_ATRAP_CFG_SRCINV _SB_MAKEMASK1(7)
+
+#define S_BCM1480_ATRAP_CFG_AGENTID 8
+#define M_BCM1480_ATRAP_CFG_AGENTID _SB_MAKEMASK(4,S_BCM1480_ATRAP_CFG_AGENTID)
+#define V_BCM1480_ATRAP_CFG_AGENTID(x) _SB_MAKEVALUE(x,S_BCM1480_ATRAP_CFG_AGENTID)
+#define G_BCM1480_ATRAP_CFG_AGENTID(x) _SB_GETVALUE(x,S_BCM1480_ATRAP_CFG_AGENTID,M_BCM1480_ATRAP_CFG_AGENTID)
+
+
+#define K_BCM1480_BUS_AGENT_CPU0 0
+#define K_BCM1480_BUS_AGENT_CPU1 1
+#define K_BCM1480_BUS_AGENT_NC 2
+#define K_BCM1480_BUS_AGENT_IOB 3
+#define K_BCM1480_BUS_AGENT_SCD 4
+#define K_BCM1480_BUS_AGENT_L2C 6
+#define K_BCM1480_BUS_AGENT_MC 7
+#define K_BCM1480_BUS_AGENT_CPU2 8
+#define K_BCM1480_BUS_AGENT_CPU3 9
+#define K_BCM1480_BUS_AGENT_PM 10
+
+#define S_BCM1480_ATRAP_CFG_CATTR 12
+#define M_BCM1480_ATRAP_CFG_CATTR _SB_MAKEMASK(2,S_BCM1480_ATRAP_CFG_CATTR)
+#define V_BCM1480_ATRAP_CFG_CATTR(x) _SB_MAKEVALUE(x,S_BCM1480_ATRAP_CFG_CATTR)
+#define G_BCM1480_ATRAP_CFG_CATTR(x) _SB_GETVALUE(x,S_BCM1480_ATRAP_CFG_CATTR,M_BCM1480_ATRAP_CFG_CATTR)
+
+#define K_BCM1480_ATRAP_CFG_CATTR_IGNORE 0
+#define K_BCM1480_ATRAP_CFG_CATTR_UNC 1
+#define K_BCM1480_ATRAP_CFG_CATTR_NONCOH 2
+#define K_BCM1480_ATRAP_CFG_CATTR_COHERENT 3
+
+#define M_BCM1480_ATRAP_CFG_CATTRINV _SB_MAKEMASK1(14)
+
+
+/*
+ * Trace Event Registers (Table 47)
+ * Same as BCM1250.
+ */
+
+/*
+ * Trace Sequence Control Registers (Table 48)
+ * Registers: TRACE_SEQUENCE_x
+ *
+ * Same as BCM1250 except for two new fields.
+ */
+
+
+#define M_BCM1480_SCD_TRSEQ_TID_MATCH_EN _SB_MAKEMASK1(25)
+
+#define S_BCM1480_SCD_TRSEQ_SWFUNC 26
+#define M_BCM1480_SCD_TRSEQ_SWFUNC _SB_MAKEMASK(2,S_BCM1480_SCD_TRSEQ_SWFUNC)
+#define V_BCM1480_SCD_TRSEQ_SWFUNC(x) _SB_MAKEVALUE(x,S_BCM1480_SCD_TRSEQ_SWFUNC)
+#define G_BCM1480_SCD_TRSEQ_SWFUNC(x) _SB_GETVALUE(x,S_BCM1480_SCD_TRSEQ_SWFUNC,M_BCM1480_SCD_TRSEQ_SWFUNC)
+
+/*
+ * Trace Control Register (Table 49)
+ * Register: TRACE_CFG
+ *
+ * Bits 0..8 are the same as the BCM1250, rest are different.
+ * Entire register is redefined below.
+ */
+
+#define M_BCM1480_SCD_TRACE_CFG_RESET _SB_MAKEMASK1(0)
+#define M_BCM1480_SCD_TRACE_CFG_START_READ _SB_MAKEMASK1(1)
+#define M_BCM1480_SCD_TRACE_CFG_START _SB_MAKEMASK1(2)
+#define M_BCM1480_SCD_TRACE_CFG_STOP _SB_MAKEMASK1(3)
+#define M_BCM1480_SCD_TRACE_CFG_FREEZE _SB_MAKEMASK1(4)
+#define M_BCM1480_SCD_TRACE_CFG_FREEZE_FULL _SB_MAKEMASK1(5)
+#define M_BCM1480_SCD_TRACE_CFG_DEBUG_FULL _SB_MAKEMASK1(6)
+#define M_BCM1480_SCD_TRACE_CFG_FULL _SB_MAKEMASK1(7)
+#define M_BCM1480_SCD_TRACE_CFG_FORCE_CNT _SB_MAKEMASK1(8)
+
+#define S_BCM1480_SCD_TRACE_CFG_MODE 16
+#define M_BCM1480_SCD_TRACE_CFG_MODE _SB_MAKEMASK(2,S_BCM1480_SCD_TRACE_CFG_MODE)
+#define V_BCM1480_SCD_TRACE_CFG_MODE(x) _SB_MAKEVALUE(x,S_BCM1480_SCD_TRACE_CFG_MODE)
+#define G_BCM1480_SCD_TRACE_CFG_MODE(x) _SB_GETVALUE(x,S_BCM1480_SCD_TRACE_CFG_MODE,M_BCM1480_SCD_TRACE_CFG_MODE)
+
+#define K_BCM1480_SCD_TRACE_CFG_MODE_BLOCKERS 0
+#define K_BCM1480_SCD_TRACE_CFG_MODE_BYTEEN_INT 1
+#define K_BCM1480_SCD_TRACE_CFG_MODE_FLOW_ID 2
+
+#define S_BCM1480_SCD_TRACE_CFG_CUR_ADDR 24
+#define M_BCM1480_SCD_TRACE_CFG_CUR_ADDR _SB_MAKEMASK(8,S_BCM1480_SCD_TRACE_CFG_CUR_ADDR)
+#define V_BCM1480_SCD_TRACE_CFG_CUR_ADDR(x) _SB_MAKEVALUE(x,S_BCM1480_SCD_TRACE_CFG_CUR_ADDR)
+#define G_BCM1480_SCD_TRACE_CFG_CUR_ADDR(x) _SB_GETVALUE(x,S_BCM1480_SCD_TRACE_CFG_CUR_ADDR,M_BCM1480_SCD_TRACE_CFG_CUR_ADDR)
+
+#endif /* _BCM1480_SCD_H */
diff --git a/include/asm-mips/sibyte/bigsur.h b/include/asm-mips/sibyte/bigsur.h
new file mode 100644
index 000000000000..ebefe797fc1d
--- /dev/null
+++ b/include/asm-mips/sibyte/bigsur.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2000,2001,2002,2003,2004 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; 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 __ASM_SIBYTE_BIGSUR_H
+#define __ASM_SIBYTE_BIGSUR_H
+
+#include <asm/sibyte/sb1250.h>
+#include <asm/sibyte/bcm1480_int.h>
+
+#ifdef CONFIG_SIBYTE_BIGSUR
+#define SIBYTE_BOARD_NAME "BCM91x80A/B (BigSur)"
+#define SIBYTE_HAVE_PCMCIA 1
+#define SIBYTE_HAVE_IDE 1
+#endif
+
+/* Generic bus chip selects */
+#define LEDS_CS 3
+#define LEDS_PHYS 0x100a0000
+
+#ifdef SIBYTE_HAVE_IDE
+#define IDE_CS 4
+#define IDE_PHYS 0x100b0000
+#define K_GPIO_GB_IDE 4
+#define K_INT_GB_IDE (K_INT_GPIO_0 + K_GPIO_GB_IDE)
+#endif
+
+#ifdef SIBYTE_HAVE_PCMCIA
+#define PCMCIA_CS 6
+#define PCMCIA_PHYS 0x11000000
+#define K_GPIO_PC_READY 9
+#define K_INT_PC_READY (K_INT_GPIO_0 + K_GPIO_PC_READY)
+#endif
+
+#endif /* __ASM_SIBYTE_BIGSUR_H */
+
diff --git a/include/asm-mips/sibyte/board.h b/include/asm-mips/sibyte/board.h
index d7b11b6c7c32..900edcbeec37 100644
--- a/include/asm-mips/sibyte/board.h
+++ b/include/asm-mips/sibyte/board.h
@@ -21,8 +21,6 @@
#include <linux/config.h>
-#ifdef CONFIG_SIBYTE_BOARD
-
#if defined(CONFIG_SIBYTE_SWARM) || defined(CONFIG_SIBYTE_PTSWARM) || \
defined(CONFIG_SIBYTE_CRHONE) || defined(CONFIG_SIBYTE_CRHINE) || \
defined(CONFIG_SIBYTE_LITTLESUR)
@@ -37,6 +35,10 @@
#include <asm/sibyte/carmel.h>
#endif
+#ifdef CONFIG_SIBYTE_BIGSUR
+#include <asm/sibyte/bigsur.h>
+#endif
+
#ifdef __ASSEMBLY__
#ifdef LEDS_PHYS
@@ -54,16 +56,6 @@
#define setleds(t0,t1,c0,c1,c2,c3)
#endif /* LEDS_PHYS */
-#else
-
-#ifdef LEDS_PHYS
-extern void setleds(char *str);
-#else
-#define setleds(s) do { } while (0)
-#endif /* LEDS_PHYS */
-
#endif /* __ASSEMBLY__ */
-#endif /* CONFIG_SIBYTE_BOARD */
-
#endif /* _SIBYTE_BOARD_H */
diff --git a/include/asm-mips/sibyte/sb1250.h b/include/asm-mips/sibyte/sb1250.h
index d62da4e2dd36..a474c29cd701 100644
--- a/include/asm-mips/sibyte/sb1250.h
+++ b/include/asm-mips/sibyte/sb1250.h
@@ -27,6 +27,9 @@
#define SB1250_NR_IRQS 64
+#define BCM1480_NR_IRQS 128
+#define BCM1480_NR_IRQS_HALF 64
+
#define SB1250_DUART_MINOR_BASE 64
#ifndef __ASSEMBLY__
@@ -35,6 +38,7 @@
/* For revision/pass information */
#include <asm/sibyte/sb1250_scd.h>
+#include <asm/sibyte/bcm1480_scd.h>
extern unsigned int sb1_pass;
extern unsigned int soc_pass;
extern unsigned int soc_type;
@@ -46,6 +50,13 @@ extern unsigned long sb1250_gettimeoffset(void);
extern void sb1250_mask_irq(int cpu, int irq);
extern void sb1250_unmask_irq(int cpu, int irq);
extern void sb1250_smp_finish(void);
+
+extern void bcm1480_time_init(void);
+extern unsigned long bcm1480_gettimeoffset(void);
+extern void bcm1480_mask_irq(int cpu, int irq);
+extern void bcm1480_unmask_irq(int cpu, int irq);
+extern void bcm1480_smp_finish(void);
+
extern void prom_printf(char *fmt, ...);
#define AT_spin \
@@ -58,6 +69,6 @@ extern void prom_printf(char *fmt, ...);
#endif
-#define IOADDR(a) (IO_BASE + (a))
+#define IOADDR(a) ((volatile void __iomem *)(IO_BASE + (a)))
#endif
diff --git a/include/asm-mips/sibyte/sb1250_defs.h b/include/asm-mips/sibyte/sb1250_defs.h
index 40ef97c76c8b..335dbaf1d831 100644
--- a/include/asm-mips/sibyte/sb1250_defs.h
+++ b/include/asm-mips/sibyte/sb1250_defs.h
@@ -8,8 +8,6 @@
*
* SB1250 specification level: User's manual 1/02/02
*
- * Author: Mitch Lichtenberg
- *
*********************************************************************
*
* Copyright 2000,2001,2002,2003
@@ -97,13 +95,17 @@
* ordering, so be careful when adding support for new minor revs.
********************************************************************* */
-#define SIBYTE_HDR_FMASK_1250_ALL 0x00000ff
-#define SIBYTE_HDR_FMASK_1250_PASS1 0x0000001
-#define SIBYTE_HDR_FMASK_1250_PASS2 0x0000002
-#define SIBYTE_HDR_FMASK_1250_PASS3 0x0000004
+#define SIBYTE_HDR_FMASK_1250_ALL 0x000000ff
+#define SIBYTE_HDR_FMASK_1250_PASS1 0x00000001
+#define SIBYTE_HDR_FMASK_1250_PASS2 0x00000002
+#define SIBYTE_HDR_FMASK_1250_PASS3 0x00000004
+
+#define SIBYTE_HDR_FMASK_112x_ALL 0x00000f00
+#define SIBYTE_HDR_FMASK_112x_PASS1 0x00000100
-#define SIBYTE_HDR_FMASK_112x_ALL 0x0000f00
-#define SIBYTE_HDR_FMASK_112x_PASS1 0x0000100
+#define SIBYTE_HDR_FMASK_1480_ALL 0x0000f000
+#define SIBYTE_HDR_FMASK_1480_PASS1 0x00001000
+#define SIBYTE_HDR_FMASK_1480_PASS2 0x00002000
/* Bit mask for chip/revision. (use _ALL for all revisions of a chip). */
#define SIBYTE_HDR_FMASK(chip, pass) \
@@ -111,8 +113,17 @@
#define SIBYTE_HDR_FMASK_ALLREVS(chip) \
(SIBYTE_HDR_FMASK_ ## chip ## _ALL)
+/* Default constant value for all chips, all revisions */
#define SIBYTE_HDR_FMASK_ALL \
+ (SIBYTE_HDR_FMASK_1250_ALL | SIBYTE_HDR_FMASK_112x_ALL \
+ | SIBYTE_HDR_FMASK_1480_ALL)
+
+/* This one is used for the "original" BCM1250/BCM112x chips. We use this
+ to weed out constants and macros that do not exist on later chips like
+ the BCM1480 */
+#define SIBYTE_HDR_FMASK_1250_112x_ALL \
(SIBYTE_HDR_FMASK_1250_ALL | SIBYTE_HDR_FMASK_112x_ALL)
+#define SIBYTE_HDR_FMASK_1250_112x SIBYTE_HDR_FMASK_1250_112x_ALL
#ifndef SIBYTE_HDR_FEATURES
#define SIBYTE_HDR_FEATURES SIBYTE_HDR_FMASK_ALL
@@ -133,6 +144,12 @@
#define SIBYTE_HDR_FEATURE_CHIP(chip) \
(!! (SIBYTE_HDR_FMASK_ALLREVS(chip) & SIBYTE_HDR_FEATURES))
+/* True for all versions of the BCM1250 and BCM1125, but not true for
+ anything else */
+#define SIBYTE_HDR_FEATURE_1250_112x \
+ (SIBYTE_HDR_FEATURE_CHIP(1250) || SIBYTE_HDR_FEATURE_CHIP(112x))
+/* (!! (SIBYTE_HDR_FEATURES & SIBYHTE_HDR_FMASK_1250_112x)) */
+
/* True if header features enabled for that rev or later, inclusive. */
#define SIBYTE_HDR_FEATURE(chip, pass) \
(!! ((SIBYTE_HDR_FMASK(chip, pass) \
diff --git a/include/asm-mips/sibyte/sb1250_dma.h b/include/asm-mips/sibyte/sb1250_dma.h
index 3cdb48f50ed0..e6145f524fbd 100644
--- a/include/asm-mips/sibyte/sb1250_dma.h
+++ b/include/asm-mips/sibyte/sb1250_dma.h
@@ -7,9 +7,8 @@
* programming the SB1250's DMA controllers, both the data mover
* and the Ethernet DMA.
*
- * SB1250 specification level: User's manual 1/02/02
- *
- * Author: Mitch Lichtenberg
+ * SB1250 specification level: User's manual 10/21/02
+ * BCM1280 specification level: User's manual 11/24/03
*
*********************************************************************
*
@@ -58,17 +57,17 @@
#define M_DMA_RESERVED1 _SB_MAKEMASK1(2)
#define S_DMA_DESC_TYPE _SB_MAKE64(1)
-#define M_DMA_DESC_TYPE _SB_MAKE64(2,S_DMA_DESC_TYPE)
+#define M_DMA_DESC_TYPE _SB_MAKEMASK(2,S_DMA_DESC_TYPE)
#define V_DMA_DESC_TYPE(x) _SB_MAKEVALUE(x,S_DMA_DESC_TYPE)
#define G_DMA_DESC_TYPE(x) _SB_GETVALUE(x,S_DMA_DESC_TYPE,M_DMA_DESC_TYPE)
#define K_DMA_DESC_TYPE_RING_AL 0
#define K_DMA_DESC_TYPE_CHAIN_AL 1
-#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1)
+#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1) || SIBYTE_HDR_FEATURE_CHIP(1480)
#define K_DMA_DESC_TYPE_RING_UAL_WI 2
#define K_DMA_DESC_TYPE_RING_UAL_RMW 3
-#endif /* 1250 PASS3 || 112x PASS1 */
+#endif /* 1250 PASS3 || 112x PASS1 || 1480 */
#define M_DMA_EOP_INT_EN _SB_MAKEMASK1(3)
#define M_DMA_HWM_INT_EN _SB_MAKEMASK1(4)
@@ -111,11 +110,11 @@
#define M_DMA_NO_DSCR_UPDT _SB_MAKEMASK1(4)
#define M_DMA_L2CA _SB_MAKEMASK1(5)
-#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1)
+#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1) || SIBYTE_HDR_FEATURE_CHIP(1480)
#define M_DMA_RX_XTRA_STATUS _SB_MAKEMASK1(6)
#define M_DMA_TX_CPU_PAUSE _SB_MAKEMASK1(6)
#define M_DMA_TX_FC_PAUSE_EN _SB_MAKEMASK1(7)
-#endif /* 1250 PASS3 || 112x PASS1 */
+#endif /* 1250 PASS3 || 112x PASS1 || 1480 */
#define M_DMA_MBZ1 _SB_MAKEMASK(6,15)
@@ -165,14 +164,14 @@
#define S_DMA_CURDSCR_COUNT _SB_MAKE64(40)
#define M_DMA_CURDSCR_COUNT _SB_MAKEMASK(16,S_DMA_CURDSCR_COUNT)
-#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1)
+#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1) || SIBYTE_HDR_FEATURE_CHIP(1480)
#define M_DMA_TX_CH_PAUSE_ON _SB_MAKEMASK1(56)
-#endif /* 1250 PASS3 || 112x PASS1 */
+#endif /* 1250 PASS3 || 112x PASS1 || 1480 */
/*
* Receive Packet Drop Registers
*/
-#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1)
+#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1) || SIBYTE_HDR_FEATURE_CHIP(1480)
#define S_DMA_OODLOST_RX _SB_MAKE64(0)
#define M_DMA_OODLOST_RX _SB_MAKEMASK(16,S_DMA_OODLOST_RX)
#define G_DMA_OODLOST_RX(x) _SB_GETVALUE(x,S_DMA_OODLOST_RX,M_DMA_OODLOST_RX)
@@ -180,7 +179,7 @@
#define S_DMA_EOP_COUNT_RX _SB_MAKE64(16)
#define M_DMA_EOP_COUNT_RX _SB_MAKEMASK(8,S_DMA_EOP_COUNT_RX)
#define G_DMA_EOP_COUNT_RX(x) _SB_GETVALUE(x,S_DMA_EOP_COUNT_RX,M_DMA_EOP_COUNT_RX)
-#endif /* 1250 PASS3 || 112x PASS1 */
+#endif /* 1250 PASS3 || 112x PASS1 || 1480 */
/* *********************************************************************
* DMA Descriptors
@@ -201,21 +200,21 @@
#define M_DMA_DSCRA_A_ADDR_OFFSET (M_DMA_DSCRA_OFFSET | M_DMA_DSCRA_A_ADDR)
-#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1)
+#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1) || SIBYTE_HDR_FEATURE_CHIP(1480)
#define S_DMA_DSCRA_A_ADDR_UA _SB_MAKE64(0)
#define M_DMA_DSCRA_A_ADDR_UA _SB_MAKEMASK(40,S_DMA_DSCRA_A_ADDR_UA)
-#endif /* 1250 PASS3 || 112x PASS1 */
+#endif /* 1250 PASS3 || 112x PASS1 || 1480 */
#define S_DMA_DSCRA_A_SIZE _SB_MAKE64(40)
#define M_DMA_DSCRA_A_SIZE _SB_MAKEMASK(9,S_DMA_DSCRA_A_SIZE)
#define V_DMA_DSCRA_A_SIZE(x) _SB_MAKEVALUE(x,S_DMA_DSCRA_A_SIZE)
#define G_DMA_DSCRA_A_SIZE(x) _SB_GETVALUE(x,S_DMA_DSCRA_A_SIZE,M_DMA_DSCRA_A_SIZE)
-#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1)
+#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1) || SIBYTE_HDR_FEATURE_CHIP(1480)
#define S_DMA_DSCRA_DSCR_CNT _SB_MAKE64(40)
#define M_DMA_DSCRA_DSCR_CNT _SB_MAKEMASK(8,S_DMA_DSCRA_DSCR_CNT)
#define G_DMA_DSCRA_DSCR_CNT(x) _SB_GETVALUE(x,S_DMA_DSCRA_DSCR_CNT,M_DMA_DSCRA_DSCR_CNT)
-#endif /* 1250 PASS3 || 112x PASS1 */
+#endif /* 1250 PASS3 || 112x PASS1 || 1480 */
#define M_DMA_DSCRA_INTERRUPT _SB_MAKEMASK1(49)
#define M_DMA_DSCRA_OFFSETB _SB_MAKEMASK1(50)
@@ -235,12 +234,12 @@
#define V_DMA_DSCRB_OPTIONS(x) _SB_MAKEVALUE(x,S_DMA_DSCRB_OPTIONS)
#define G_DMA_DSCRB_OPTIONS(x) _SB_GETVALUE(x,S_DMA_DSCRB_OPTIONS,M_DMA_DSCRB_OPTIONS)
-#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1)
+#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1) || SIBYTE_HDR_FEATURE_CHIP(1480)
#define S_DMA_DSCRB_A_SIZE _SB_MAKE64(8)
#define M_DMA_DSCRB_A_SIZE _SB_MAKEMASK(14,S_DMA_DSCRB_A_SIZE)
#define V_DMA_DSCRB_A_SIZE(x) _SB_MAKEVALUE(x,S_DMA_DSCRB_A_SIZE)
#define G_DMA_DSCRB_A_SIZE(x) _SB_GETVALUE(x,S_DMA_DSCRB_A_SIZE,M_DMA_DSCRB_A_SIZE)
-#endif /* 1250 PASS3 || 112x PASS1 */
+#endif /* 1250 PASS3 || 112x PASS1 || 1480 */
#define R_DMA_DSCRB_ADDR _SB_MAKE64(0x10)
@@ -255,12 +254,12 @@
#define M_DMA_DSCRB_B_VALID _SB_MAKEMASK1(49)
-#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1)
+#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1) || SIBYTE_HDR_FEATURE_CHIP(1480)
#define S_DMA_DSCRB_PKT_SIZE_MSB _SB_MAKE64(48)
#define M_DMA_DSCRB_PKT_SIZE_MSB _SB_MAKEMASK(2,S_DMA_DSCRB_PKT_SIZE_MSB)
#define V_DMA_DSCRB_PKT_SIZE_MSB(x) _SB_MAKEVALUE(x,S_DMA_DSCRB_PKT_SIZE_MSB)
#define G_DMA_DSCRB_PKT_SIZE_MSB(x) _SB_GETVALUE(x,S_DMA_DSCRB_PKT_SIZE_MSB,M_DMA_DSCRB_PKT_SIZE_MSB)
-#endif /* 1250 PASS3 || 112x PASS1 */
+#endif /* 1250 PASS3 || 112x PASS1 || 1480 */
#define S_DMA_DSCRB_PKT_SIZE _SB_MAKE64(50)
#define M_DMA_DSCRB_PKT_SIZE _SB_MAKEMASK(14,S_DMA_DSCRB_PKT_SIZE)
@@ -282,15 +281,16 @@
#define M_DMA_ETHRX_BADIP4CS _SB_MAKEMASK1(51)
#define M_DMA_ETHRX_DSCRERR _SB_MAKEMASK1(52)
-#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1)
-/* Note: BADTCPCS is actually in DSCR_B options field */
+#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) || SIBYTE_HDR_FEATURE_CHIP(1480)
+/* Note: This bit is in the DSCR_B options field */
#define M_DMA_ETHRX_BADTCPCS _SB_MAKEMASK1(0)
-#endif /* 1250 PASS2 || 112x PASS1 */
+#endif /* 1250 PASS2 || 112x PASS1 || 1480 */
-#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1)
+#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1) || SIBYTE_HDR_FEATURE_CHIP(1480)
+/* Note: These bits are in the DSCR_B options field */
#define M_DMA_ETH_VLAN_FLAG _SB_MAKEMASK1(1)
#define M_DMA_ETH_CRC_FLAG _SB_MAKEMASK1(2)
-#endif /* 1250 PASS3 || 112x PASS1 */
+#endif /* 1250 PASS3 || 112x PASS1 || 1480 */
#define S_DMA_ETHRX_RXCH 53
#define M_DMA_ETHRX_RXCH _SB_MAKEMASK(2,S_DMA_ETHRX_RXCH)
@@ -438,7 +438,7 @@
M_DM_CUR_DSCR_DSCR_COUNT)
-#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1)
+#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1) || SIBYTE_HDR_FEATURE_CHIP(1480)
/*
* Data Mover Channel Partial Result Registers
* Register: DM_PARTIAL_0
@@ -459,10 +459,10 @@
M_DM_PARTIAL_TCPCS_PARTIAL)
#define M_DM_PARTIAL_ODD_BYTE _SB_MAKEMASK1(48)
-#endif /* 1250 PASS3 || 112x PASS1 */
+#endif /* 1250 PASS3 || 112x PASS1 || 1480 */
-#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1)
+#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1) || SIBYTE_HDR_FEATURE_CHIP(1480)
/*
* Data Mover CRC Definition Registers
* Register: CRC_DEF_0
@@ -479,10 +479,10 @@
#define V_CRC_DEF_CRC_POLY(r) _SB_MAKEVALUE(r,S_CRC_DEF_CRC_POLY)
#define G_CRC_DEF_CRC_POLY(r) _SB_GETVALUE(r,S_CRC_DEF_CRC_POLY,\
M_CRC_DEF_CRC_POLY)
-#endif /* 1250 PASS3 || 112x PASS1 */
+#endif /* 1250 PASS3 || 112x PASS1 || 1480 */
-#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1)
+#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1) || SIBYTE_HDR_FEATURE_CHIP(1480)
/*
* Data Mover CRC/Checksum Definition Registers
* Register: CTCP_DEF_0
@@ -511,7 +511,7 @@
#define K_CTCP_DEF_CRC_WIDTH_1 2
#define M_CTCP_DEF_CRC_BIT_ORDER _SB_MAKEMASK1(50)
-#endif /* 1250 PASS3 || 112x PASS1 */
+#endif /* 1250 PASS3 || 112x PASS1 || 1480 */
/*
@@ -560,12 +560,12 @@
#define M_DM_DSCRA_L2C_DEST _SB_MAKEMASK1(50)
#define M_DM_DSCRA_L2C_SRC _SB_MAKEMASK1(51)
-#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1)
+#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) || SIBYTE_HDR_FEATURE_CHIP(1480)
#define M_DM_DSCRA_RD_BKOFF _SB_MAKEMASK1(52)
#define M_DM_DSCRA_WR_BKOFF _SB_MAKEMASK1(53)
-#endif /* 1250 PASS2 || 112x PASS1 */
+#endif /* 1250 PASS2 || 112x PASS1 || 1480 */
-#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1)
+#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1) || SIBYTE_HDR_FEATURE_CHIP(1480)
#define M_DM_DSCRA_TCPCS_EN _SB_MAKEMASK1(54)
#define M_DM_DSCRA_TCPCS_RES _SB_MAKEMASK1(55)
#define M_DM_DSCRA_TCPCS_AP _SB_MAKEMASK1(56)
@@ -574,7 +574,7 @@
#define M_DM_DSCRA_CRC_AP _SB_MAKEMASK1(59)
#define M_DM_DSCRA_CRC_DFN _SB_MAKEMASK1(60)
#define M_DM_DSCRA_CRC_XBIT _SB_MAKEMASK1(61)
-#endif /* 1250 PASS3 || 112x PASS1 */
+#endif /* 1250 PASS3 || 112x PASS1 || 1480 */
#define M_DM_DSCRA_RESERVED2 _SB_MAKEMASK(3,61)
diff --git a/include/asm-mips/sibyte/sb1250_genbus.h b/include/asm-mips/sibyte/sb1250_genbus.h
index f1f509f295c4..1b5cbc5c6454 100644
--- a/include/asm-mips/sibyte/sb1250_genbus.h
+++ b/include/asm-mips/sibyte/sb1250_genbus.h
@@ -6,9 +6,8 @@
* This module contains constants and macros useful for
* manipulating the SB1250's Generic Bus interface
*
- * SB1250 specification level: User's manual 1/02/02
- *
- * Author: Mitch Lichtenberg
+ * SB1250 specification level: User's manual 10/21/02
+ * BCM1280 specification level: User's Manual 11/14/03
*
*********************************************************************
*
@@ -51,19 +50,21 @@
#define M_IO_WIDTH_SEL _SB_MAKEMASK(2,S_IO_WIDTH_SEL)
#define K_IO_WIDTH_SEL_1 0
#define K_IO_WIDTH_SEL_2 1
-#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1)
+#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) \
+ || SIBYTE_HDR_FEATURE_CHIP(1480)
#define K_IO_WIDTH_SEL_1L 2
-#endif /* 1250 PASS2 || 112x PASS1 */
+#endif /* 1250 PASS2 || 112x PASS1 || 1480 */
#define K_IO_WIDTH_SEL_4 3
#define V_IO_WIDTH_SEL(x) _SB_MAKEVALUE(x,S_IO_WIDTH_SEL)
#define G_IO_WIDTH_SEL(x) _SB_GETVALUE(x,S_IO_WIDTH_SEL,M_IO_WIDTH_SEL)
#define S_IO_PARITY_ENA 4
#define M_IO_PARITY_ENA _SB_MAKEMASK1(S_IO_PARITY_ENA)
-#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1)
+#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) \
+ || SIBYTE_HDR_FEATURE_CHIP(1480)
#define S_IO_BURST_EN 5
#define M_IO_BURST_EN _SB_MAKEMASK1(S_IO_BURST_EN)
-#endif /* 1250 PASS2 || 112x PASS1 */
+#endif /* 1250 PASS2 || 112x PASS1 || 1480 */
#define S_IO_PARITY_ODD 6
#define M_IO_PARITY_ODD _SB_MAKEMASK1(S_IO_PARITY_ODD)
#define S_IO_NONMUX 7
@@ -96,8 +97,11 @@
#define S_IO_ADDRBASE 16 /* # bits to shift addr for this reg */
+#define M_IO_BLK_CACHE _SB_MAKEMASK1(15)
+
+
/*
- * Generic Bus Region 0 Timing Registers (Table 11-7)
+ * Generic Bus Timing 0 Registers (Table 11-7)
*/
#define S_IO_ALE_WIDTH 0
@@ -105,21 +109,23 @@
#define V_IO_ALE_WIDTH(x) _SB_MAKEVALUE(x,S_IO_ALE_WIDTH)
#define G_IO_ALE_WIDTH(x) _SB_GETVALUE(x,S_IO_ALE_WIDTH,M_IO_ALE_WIDTH)
-#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1)
+#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) \
+ || SIBYTE_HDR_FEATURE_CHIP(1480)
#define M_IO_EARLY_CS _SB_MAKEMASK1(3)
-#endif /* 1250 PASS2 || 112x PASS1 */
+#endif /* 1250 PASS2 || 112x PASS1 || 1480 */
#define S_IO_ALE_TO_CS 4
#define M_IO_ALE_TO_CS _SB_MAKEMASK(2,S_IO_ALE_TO_CS)
#define V_IO_ALE_TO_CS(x) _SB_MAKEVALUE(x,S_IO_ALE_TO_CS)
#define G_IO_ALE_TO_CS(x) _SB_GETVALUE(x,S_IO_ALE_TO_CS,M_IO_ALE_TO_CS)
-#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1)
+#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) \
+ || SIBYTE_HDR_FEATURE_CHIP(1480)
#define S_IO_BURST_WIDTH _SB_MAKE64(6)
#define M_IO_BURST_WIDTH _SB_MAKEMASK(2,S_IO_BURST_WIDTH)
#define V_IO_BURST_WIDTH(x) _SB_MAKEVALUE(x,S_IO_BURST_WIDTH)
#define G_IO_BURST_WIDTH(x) _SB_GETVALUE(x,S_IO_BURST_WIDTH,M_IO_BURST_WIDTH)
-#endif /* 1250 PASS2 || 112x PASS1 */
+#endif /* 1250 PASS2 || 112x PASS1 || 1480 */
#define S_IO_CS_WIDTH 8
#define M_IO_CS_WIDTH _SB_MAKEMASK(5,S_IO_CS_WIDTH)
@@ -141,9 +147,10 @@
#define V_IO_ALE_TO_WRITE(x) _SB_MAKEVALUE(x,S_IO_ALE_TO_WRITE)
#define G_IO_ALE_TO_WRITE(x) _SB_GETVALUE(x,S_IO_ALE_TO_WRITE,M_IO_ALE_TO_WRITE)
-#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1)
+#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) \
+ || SIBYTE_HDR_FEATURE_CHIP(1480)
#define M_IO_RDY_SYNC _SB_MAKEMASK1(3)
-#endif /* 1250 PASS2 || 112x PASS1 */
+#endif /* 1250 PASS2 || 112x PASS1 || 1480 */
#define S_IO_WRITE_WIDTH 4
#define M_IO_WRITE_WIDTH _SB_MAKEMASK(4,S_IO_WRITE_WIDTH)
@@ -183,9 +190,127 @@
#define M_IO_TIMEOUT_INT _SB_MAKEMASK1(10)
#define M_IO_ILL_ADDR_INT _SB_MAKEMASK1(11)
#define M_IO_MULT_CS_INT _SB_MAKEMASK1(12)
-#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1)
+#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) || SIBYTE_HDR_FEATURE_CHIP(1480)
#define M_IO_COH_ERR _SB_MAKEMASK1(14)
-#endif /* 1250 PASS2 || 112x PASS1 */
+#endif /* 1250 PASS2 || 112x PASS1 || 1480 */
+
+
+/*
+ * Generic Bus Output Drive Control Register 0 (Table 14-18)
+ */
+
+#define S_IO_SLEW0 0
+#define M_IO_SLEW0 _SB_MAKEMASK(2,S_IO_SLEW0)
+#define V_IO_SLEW0(x) _SB_MAKEVALUE(x,S_IO_SLEW0)
+#define G_IO_SLEW0(x) _SB_GETVALUE(x,S_IO_SLEW0,M_IO_SLEW0)
+
+#define S_IO_DRV_A 2
+#define M_IO_DRV_A _SB_MAKEMASK(2,S_IO_DRV_A)
+#define V_IO_DRV_A(x) _SB_MAKEVALUE(x,S_IO_DRV_A)
+#define G_IO_DRV_A(x) _SB_GETVALUE(x,S_IO_DRV_A,M_IO_DRV_A)
+
+#define S_IO_DRV_B 6
+#define M_IO_DRV_B _SB_MAKEMASK(2,S_IO_DRV_B)
+#define V_IO_DRV_B(x) _SB_MAKEVALUE(x,S_IO_DRV_B)
+#define G_IO_DRV_B(x) _SB_GETVALUE(x,S_IO_DRV_B,M_IO_DRV_B)
+
+#define S_IO_DRV_C 10
+#define M_IO_DRV_C _SB_MAKEMASK(2,S_IO_DRV_C)
+#define V_IO_DRV_C(x) _SB_MAKEVALUE(x,S_IO_DRV_C)
+#define G_IO_DRV_C(x) _SB_GETVALUE(x,S_IO_DRV_C,M_IO_DRV_C)
+
+#define S_IO_DRV_D 14
+#define M_IO_DRV_D _SB_MAKEMASK(2,S_IO_DRV_D)
+#define V_IO_DRV_D(x) _SB_MAKEVALUE(x,S_IO_DRV_D)
+#define G_IO_DRV_D(x) _SB_GETVALUE(x,S_IO_DRV_D,M_IO_DRV_D)
+
+/*
+ * Generic Bus Output Drive Control Register 1 (Table 14-19)
+ */
+
+#define S_IO_DRV_E 2
+#define M_IO_DRV_E _SB_MAKEMASK(2,S_IO_DRV_E)
+#define V_IO_DRV_E(x) _SB_MAKEVALUE(x,S_IO_DRV_E)
+#define G_IO_DRV_E(x) _SB_GETVALUE(x,S_IO_DRV_E,M_IO_DRV_E)
+
+#define S_IO_DRV_F 6
+#define M_IO_DRV_F _SB_MAKEMASK(2,S_IO_DRV_F)
+#define V_IO_DRV_F(x) _SB_MAKEVALUE(x,S_IO_DRV_F)
+#define G_IO_DRV_F(x) _SB_GETVALUE(x,S_IO_DRV_F,M_IO_DRV_F)
+
+#define S_IO_SLEW1 8
+#define M_IO_SLEW1 _SB_MAKEMASK(2,S_IO_SLEW1)
+#define V_IO_SLEW1(x) _SB_MAKEVALUE(x,S_IO_SLEW1)
+#define G_IO_SLEW1(x) _SB_GETVALUE(x,S_IO_SLEW1,M_IO_SLEW1)
+
+#define S_IO_DRV_G 10
+#define M_IO_DRV_G _SB_MAKEMASK(2,S_IO_DRV_G)
+#define V_IO_DRV_G(x) _SB_MAKEVALUE(x,S_IO_DRV_G)
+#define G_IO_DRV_G(x) _SB_GETVALUE(x,S_IO_DRV_G,M_IO_DRV_G)
+
+#define S_IO_SLEW2 12
+#define M_IO_SLEW2 _SB_MAKEMASK(2,S_IO_SLEW2)
+#define V_IO_SLEW2(x) _SB_MAKEVALUE(x,S_IO_SLEW2)
+#define G_IO_SLEW2(x) _SB_GETVALUE(x,S_IO_SLEW2,M_IO_SLEW2)
+
+#define S_IO_DRV_H 14
+#define M_IO_DRV_H _SB_MAKEMASK(2,S_IO_DRV_H)
+#define V_IO_DRV_H(x) _SB_MAKEVALUE(x,S_IO_DRV_H)
+#define G_IO_DRV_H(x) _SB_GETVALUE(x,S_IO_DRV_H,M_IO_DRV_H)
+
+/*
+ * Generic Bus Output Drive Control Register 2 (Table 14-20)
+ */
+
+#define S_IO_DRV_J 2
+#define M_IO_DRV_J _SB_MAKEMASK(2,S_IO_DRV_J)
+#define V_IO_DRV_J(x) _SB_MAKEVALUE(x,S_IO_DRV_J)
+#define G_IO_DRV_J(x) _SB_GETVALUE(x,S_IO_DRV_J,M_IO_DRV_J)
+
+#define S_IO_DRV_K 6
+#define M_IO_DRV_K _SB_MAKEMASK(2,S_IO_DRV_K)
+#define V_IO_DRV_K(x) _SB_MAKEVALUE(x,S_IO_DRV_K)
+#define G_IO_DRV_K(x) _SB_GETVALUE(x,S_IO_DRV_K,M_IO_DRV_K)
+
+#define S_IO_DRV_L 10
+#define M_IO_DRV_L _SB_MAKEMASK(2,S_IO_DRV_L)
+#define V_IO_DRV_L(x) _SB_MAKEVALUE(x,S_IO_DRV_L)
+#define G_IO_DRV_L(x) _SB_GETVALUE(x,S_IO_DRV_L,M_IO_DRV_L)
+
+#define S_IO_DRV_M 14
+#define M_IO_DRV_M _SB_MAKEMASK(2,S_IO_DRV_M)
+#define V_IO_DRV_M(x) _SB_MAKEVALUE(x,S_IO_DRV_M)
+#define G_IO_DRV_M(x) _SB_GETVALUE(x,S_IO_DRV_M,M_IO_DRV_M)
+
+/*
+ * Generic Bus Output Drive Control Register 3 (Table 14-21)
+ */
+
+#define S_IO_SLEW3 0
+#define M_IO_SLEW3 _SB_MAKEMASK(2,S_IO_SLEW3)
+#define V_IO_SLEW3(x) _SB_MAKEVALUE(x,S_IO_SLEW3)
+#define G_IO_SLEW3(x) _SB_GETVALUE(x,S_IO_SLEW3,M_IO_SLEW3)
+
+#define S_IO_DRV_N 2
+#define M_IO_DRV_N _SB_MAKEMASK(2,S_IO_DRV_N)
+#define V_IO_DRV_N(x) _SB_MAKEVALUE(x,S_IO_DRV_N)
+#define G_IO_DRV_N(x) _SB_GETVALUE(x,S_IO_DRV_N,M_IO_DRV_N)
+
+#define S_IO_DRV_P 6
+#define M_IO_DRV_P _SB_MAKEMASK(2,S_IO_DRV_P)
+#define V_IO_DRV_P(x) _SB_MAKEVALUE(x,S_IO_DRV_P)
+#define G_IO_DRV_P(x) _SB_GETVALUE(x,S_IO_DRV_P,M_IO_DRV_P)
+
+#define S_IO_DRV_Q 10
+#define M_IO_DRV_Q _SB_MAKEMASK(2,S_IO_DRV_Q)
+#define V_IO_DRV_Q(x) _SB_MAKEVALUE(x,S_IO_DRV_Q)
+#define G_IO_DRV_Q(x) _SB_GETVALUE(x,S_IO_DRV_Q,M_IO_DRV_Q)
+
+#define S_IO_DRV_R 14
+#define M_IO_DRV_R _SB_MAKEMASK(2,S_IO_DRV_R)
+#define V_IO_DRV_R(x) _SB_MAKEVALUE(x,S_IO_DRV_R)
+#define G_IO_DRV_R(x) _SB_GETVALUE(x,S_IO_DRV_R,M_IO_DRV_R)
+
/*
* PCMCIA configuration register (Table 12-6)
@@ -202,6 +327,22 @@
#define M_PCMCIA_CFG_RDYMASK _SB_MAKEMASK1(8)
#define M_PCMCIA_CFG_PWRCTL _SB_MAKEMASK1(9)
+#if SIBYTE_HDR_FEATURE_CHIP(1480)
+#define S_PCMCIA_MODE 16
+#define M_PCMCIA_MODE _SB_MAKEMASK(3,S_PCMCIA_MODE)
+#define V_PCMCIA_MODE(x) _SB_MAKEVALUE(x,S_PCMCIA_MODE)
+#define G_PCMCIA_MODE(x) _SB_GETVALUE(x,S_PCMCIA_MODE,M_PCMCIA_MODE)
+
+#define K_PCMCIA_MODE_PCMA_NOB 0 /* standard PCMCIA "A", no "B" */
+#define K_PCMCIA_MODE_IDEA_NOB 1 /* IDE "A", no "B" */
+#define K_PCMCIA_MODE_PCMIOA_NOB 2 /* PCMCIA with I/O "A", no "B" */
+#define K_PCMCIA_MODE_PCMA_PCMB 4 /* standard PCMCIA "A", standard PCMCIA "B" */
+#define K_PCMCIA_MODE_IDEA_PCMB 5 /* IDE "A", standard PCMCIA "B" */
+#define K_PCMCIA_MODE_PCMA_IDEB 6 /* standard PCMCIA "A", IDE "B" */
+#define K_PCMCIA_MODE_IDEA_IDEB 7 /* IDE "A", IDE "B" */
+#endif
+
+
/*
* PCMCIA status register (Table 12-7)
*/
@@ -272,5 +413,62 @@
#define V_GPIO_INTR_TYPE14(x) _SB_MAKEVALUE(x,S_GPIO_INTR_TYPE14)
#define G_GPIO_INTR_TYPE14(x) _SB_GETVALUE(x,S_GPIO_INTR_TYPE14,M_GPIO_INTR_TYPE14)
+#if SIBYTE_HDR_FEATURE_CHIP(1480)
+
+/*
+ * GPIO Interrupt Additional Type Register
+ */
+
+#define K_GPIO_INTR_BOTHEDGE 0
+#define K_GPIO_INTR_RISEEDGE 1
+#define K_GPIO_INTR_UNPRED1 2
+#define K_GPIO_INTR_UNPRED2 3
+
+#define S_GPIO_INTR_ATYPEX(n) (((n)/2)*2)
+#define M_GPIO_INTR_ATYPEX(n) _SB_MAKEMASK(2,S_GPIO_INTR_ATYPEX(n))
+#define V_GPIO_INTR_ATYPEX(n,x) _SB_MAKEVALUE(x,S_GPIO_INTR_ATYPEX(n))
+#define G_GPIO_INTR_ATYPEX(n,x) _SB_GETVALUE(x,S_GPIO_INTR_ATYPEX(n),M_GPIO_INTR_ATYPEX(n))
+
+#define S_GPIO_INTR_ATYPE0 0
+#define M_GPIO_INTR_ATYPE0 _SB_MAKEMASK(2,S_GPIO_INTR_ATYPE0)
+#define V_GPIO_INTR_ATYPE0(x) _SB_MAKEVALUE(x,S_GPIO_INTR_ATYPE0)
+#define G_GPIO_INTR_ATYPE0(x) _SB_GETVALUE(x,S_GPIO_INTR_ATYPE0,M_GPIO_INTR_ATYPE0)
+
+#define S_GPIO_INTR_ATYPE2 2
+#define M_GPIO_INTR_ATYPE2 _SB_MAKEMASK(2,S_GPIO_INTR_ATYPE2)
+#define V_GPIO_INTR_ATYPE2(x) _SB_MAKEVALUE(x,S_GPIO_INTR_ATYPE2)
+#define G_GPIO_INTR_ATYPE2(x) _SB_GETVALUE(x,S_GPIO_INTR_ATYPE2,M_GPIO_INTR_ATYPE2)
+
+#define S_GPIO_INTR_ATYPE4 4
+#define M_GPIO_INTR_ATYPE4 _SB_MAKEMASK(2,S_GPIO_INTR_ATYPE4)
+#define V_GPIO_INTR_ATYPE4(x) _SB_MAKEVALUE(x,S_GPIO_INTR_ATYPE4)
+#define G_GPIO_INTR_ATYPE4(x) _SB_GETVALUE(x,S_GPIO_INTR_ATYPE4,M_GPIO_INTR_ATYPE4)
+
+#define S_GPIO_INTR_ATYPE6 6
+#define M_GPIO_INTR_ATYPE6 _SB_MAKEMASK(2,S_GPIO_INTR_ATYPE6)
+#define V_GPIO_INTR_ATYPE6(x) _SB_MAKEVALUE(x,S_GPIO_INTR_ATYPE6)
+#define G_GPIO_INTR_ATYPE6(x) _SB_GETVALUE(x,S_GPIO_INTR_ATYPE6,M_GPIO_INTR_ATYPE6)
+
+#define S_GPIO_INTR_ATYPE8 8
+#define M_GPIO_INTR_ATYPE8 _SB_MAKEMASK(2,S_GPIO_INTR_ATYPE8)
+#define V_GPIO_INTR_ATYPE8(x) _SB_MAKEVALUE(x,S_GPIO_INTR_ATYPE8)
+#define G_GPIO_INTR_ATYPE8(x) _SB_GETVALUE(x,S_GPIO_INTR_ATYPE8,M_GPIO_INTR_ATYPE8)
+
+#define S_GPIO_INTR_ATYPE10 10
+#define M_GPIO_INTR_ATYPE10 _SB_MAKEMASK(2,S_GPIO_INTR_ATYPE10)
+#define V_GPIO_INTR_ATYPE10(x) _SB_MAKEVALUE(x,S_GPIO_INTR_ATYPE10)
+#define G_GPIO_INTR_ATYPE10(x) _SB_GETVALUE(x,S_GPIO_INTR_ATYPE10,M_GPIO_INTR_ATYPE10)
+
+#define S_GPIO_INTR_ATYPE12 12
+#define M_GPIO_INTR_ATYPE12 _SB_MAKEMASK(2,S_GPIO_INTR_ATYPE12)
+#define V_GPIO_INTR_ATYPE12(x) _SB_MAKEVALUE(x,S_GPIO_INTR_ATYPE12)
+#define G_GPIO_INTR_ATYPE12(x) _SB_GETVALUE(x,S_GPIO_INTR_ATYPE12,M_GPIO_INTR_ATYPE12)
+
+#define S_GPIO_INTR_ATYPE14 14
+#define M_GPIO_INTR_ATYPE14 _SB_MAKEMASK(2,S_GPIO_INTR_ATYPE14)
+#define V_GPIO_INTR_ATYPE14(x) _SB_MAKEVALUE(x,S_GPIO_INTR_ATYPE14)
+#define G_GPIO_INTR_ATYPE14(x) _SB_GETVALUE(x,S_GPIO_INTR_ATYPE14,M_GPIO_INTR_ATYPE14)
+#endif
+
#endif
diff --git a/include/asm-mips/sibyte/sb1250_int.h b/include/asm-mips/sibyte/sb1250_int.h
index e173e2ea4c98..05c7b39f1b02 100644
--- a/include/asm-mips/sibyte/sb1250_int.h
+++ b/include/asm-mips/sibyte/sb1250_int.h
@@ -8,8 +8,6 @@
*
* SB1250 specification level: User's manual 1/02/02
*
- * Author: Mitch Lichtenberg
- *
*********************************************************************
*
* Copyright 2000,2001,2002,2003
@@ -47,6 +45,10 @@
* First, the interrupt numbers.
*/
+#if SIBYTE_HDR_FEATURE_1250_112x
+
+#define K_INT_SOURCES 64
+
#define K_INT_WATCHDOG_TIMER_0 0
#define K_INT_WATCHDOG_TIMER_1 1
#define K_INT_TIMER_0 2
@@ -244,4 +246,6 @@
#define M_LDTVECT_RAISEMBOX 0x40
+#endif /* 1250/112x */
+
#endif
diff --git a/include/asm-mips/sibyte/sb1250_l2c.h b/include/asm-mips/sibyte/sb1250_l2c.h
index 8afe8e01581b..842f205094af 100644
--- a/include/asm-mips/sibyte/sb1250_l2c.h
+++ b/include/asm-mips/sibyte/sb1250_l2c.h
@@ -8,8 +8,6 @@
*
* SB1250 specification level: User's manual 1/02/02
*
- * Author: Mitch Lichtenberg
- *
*********************************************************************
*
* Copyright 2000,2001,2002,2003
@@ -89,8 +87,13 @@
#define V_L2C_MGMT_WAY(x) _SB_MAKEVALUE(x,S_L2C_MGMT_WAY)
#define G_L2C_MGMT_WAY(x) _SB_GETVALUE(x,S_L2C_MGMT_WAY,M_L2C_MGMT_WAY)
-#define S_L2C_MGMT_TAG 21
-#define M_L2C_MGMT_TAG _SB_MAKEMASK(6,S_L2C_MGMT_TAG)
+#define S_L2C_MGMT_ECC_DIAG 21
+#define M_L2C_MGMT_ECC_DIAG _SB_MAKEMASK(2,S_L2C_MGMT_ECC_DIAG)
+#define V_L2C_MGMT_ECC_DIAG(x) _SB_MAKEVALUE(x,S_L2C_MGMT_ECC_DIAG)
+#define G_L2C_MGMT_ECC_DIAG(x) _SB_GETVALUE(x,S_L2C_MGMT_ECC_DIAG,M_L2C_MGMT_ECC_DIAG)
+
+#define S_L2C_MGMT_TAG 23
+#define M_L2C_MGMT_TAG _SB_MAKEMASK(4,S_L2C_MGMT_TAG)
#define V_L2C_MGMT_TAG(x) _SB_MAKEVALUE(x,S_L2C_MGMT_TAG)
#define G_L2C_MGMT_TAG(x) _SB_GETVALUE(x,S_L2C_MGMT_TAG,M_L2C_MGMT_TAG)
diff --git a/include/asm-mips/sibyte/sb1250_ldt.h b/include/asm-mips/sibyte/sb1250_ldt.h
index f2617ded0a8f..7092535d1108 100644
--- a/include/asm-mips/sibyte/sb1250_ldt.h
+++ b/include/asm-mips/sibyte/sb1250_ldt.h
@@ -8,8 +8,6 @@
*
* SB1250 specification level: User's manual 1/02/02
*
- * Author: Mitch Lichtenberg
- *
*********************************************************************
*
* Copyright 2000,2001,2002,2003
diff --git a/include/asm-mips/sibyte/sb1250_mac.h b/include/asm-mips/sibyte/sb1250_mac.h
index 18e74e43f4a2..adfc688fa559 100644
--- a/include/asm-mips/sibyte/sb1250_mac.h
+++ b/include/asm-mips/sibyte/sb1250_mac.h
@@ -8,8 +8,6 @@
*
* SB1250 specification level: User's manual 1/02/02
*
- * Author: Mitch Lichtenberg
- *
*********************************************************************
*
* Copyright 2000,2001,2002,2003
@@ -81,7 +79,10 @@
#define M_MAC_RESERVED1 _SB_MAKEMASK(8,9)
#define M_MAC_AP_STAT_EN _SB_MAKEMASK1(17)
-#define M_MAC_RESERVED2 _SB_MAKEMASK1(18)
+
+#if SIBYTE_HDR_FEATURE_CHIP(1480)
+#define M_MAC_TIMESTAMP _SB_MAKEMASK1(18)
+#endif
#define M_MAC_DRP_ERRPKT_EN _SB_MAKEMASK1(19)
#define M_MAC_DRP_FCSERRPKT_EN _SB_MAKEMASK1(20)
#define M_MAC_DRP_CODEERRPKT_EN _SB_MAKEMASK1(21)
@@ -132,9 +133,9 @@
#define M_MAC_RX_CH_SEL_MSB _SB_MAKEMASK1(44)
#endif /* 1250 PASS2 || 112x PASS1 */
-#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1)
+#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1) || SIBYTE_HDR_FEATURE_CHIP(1480)
#define M_MAC_SPLIT_CH_SEL _SB_MAKEMASK1(45)
-#endif /* 1250 PASS3 || 112x PASS1 */
+#endif /* 1250 PASS3 || 112x PASS1 || 1480 */
#define S_MAC_BYPASS_IFG _SB_MAKE64(46)
#define M_MAC_BYPASS_IFG _SB_MAKEMASK(8,S_MAC_BYPASS_IFG)
@@ -176,10 +177,22 @@
#define M_MAC_PORT_RESET _SB_MAKEMASK1(8)
+#if (SIBYTE_HDR_FEATURE_CHIP(1250) || SIBYTE_HDR_FEATURE_CHIP(112x))
#define M_MAC_RX_ENABLE _SB_MAKEMASK1(10)
#define M_MAC_TX_ENABLE _SB_MAKEMASK1(11)
#define M_MAC_BYP_RX_ENABLE _SB_MAKEMASK1(12)
#define M_MAC_BYP_TX_ENABLE _SB_MAKEMASK1(13)
+#endif
+
+/*
+ * MAC reset information register (1280/1255)
+ */
+#if SIBYTE_HDR_FEATURE_CHIP(1480)
+#define M_MAC_RX_CH0_PAUSE_ON _SB_MAKEMASK1(8)
+#define M_MAC_RX_CH1_PAUSE_ON _SB_MAKEMASK1(16)
+#define M_MAC_TX_CH0_PAUSE_ON _SB_MAKEMASK1(24)
+#define M_MAC_TX_CH1_PAUSE_ON _SB_MAKEMASK1(32)
+#endif
/*
* MAC DMA Control Register
@@ -267,12 +280,12 @@
#define V_MAC_IFG_RX(x) _SB_MAKEVALUE(x,S_MAC_IFG_RX)
#define G_MAC_IFG_RX(x) _SB_GETVALUE(x,S_MAC_IFG_RX,M_MAC_IFG_RX)
-#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1)
+#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1) || SIBYTE_HDR_FEATURE_CHIP(1480)
#define S_MAC_PRE_LEN _SB_MAKE64(0)
#define M_MAC_PRE_LEN _SB_MAKEMASK(6,S_MAC_PRE_LEN)
#define V_MAC_PRE_LEN(x) _SB_MAKEVALUE(x,S_MAC_PRE_LEN)
#define G_MAC_PRE_LEN(x) _SB_GETVALUE(x,S_MAC_PRE_LEN,M_MAC_PRE_LEN)
-#endif /* 1250 PASS3 || 112x PASS1 */
+#endif /* 1250 PASS3 || 112x PASS1 || 1480 */
#define S_MAC_IFG_TX _SB_MAKE64(6)
#define M_MAC_IFG_TX _SB_MAKEMASK(6,S_MAC_IFG_TX)
@@ -458,9 +471,9 @@
#define V_MAC_COUNTER_ADDR(x) _SB_MAKEVALUE(x,S_MAC_COUNTER_ADDR)
#define G_MAC_COUNTER_ADDR(x) _SB_GETVALUE(x,S_MAC_COUNTER_ADDR,M_MAC_COUNTER_ADDR)
-#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1)
+#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1) || SIBYTE_HDR_FEATURE_CHIP(1480)
#define M_MAC_TX_PAUSE_ON _SB_MAKEMASK1(52)
-#endif /* 1250 PASS3 || 112x PASS1 */
+#endif /* 1250 PASS3 || 112x PASS1 || 1480 */
/*
* MAC Fifo Pointer Registers (Table 9-19) [Debug register]
@@ -594,7 +607,7 @@
#define V_MAC_IPHDR_OFFSET(x) _SB_MAKEVALUE(x,S_MAC_IPHDR_OFFSET)
#define G_MAC_IPHDR_OFFSET(x) _SB_GETVALUE(x,S_MAC_IPHDR_OFFSET,M_MAC_IPHDR_OFFSET)
-#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1)
+#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1) || SIBYTE_HDR_FEATURE_CHIP(1480)
#define S_MAC_RX_CRC_OFFSET _SB_MAKE64(16)
#define M_MAC_RX_CRC_OFFSET _SB_MAKEMASK(8,S_MAC_RX_CRC_OFFSET)
#define V_MAC_RX_CRC_OFFSET(x) _SB_MAKEVALUE(x,S_MAC_RX_CRC_OFFSET)
@@ -612,7 +625,7 @@
#define M_MAC_RX_CH_MSN_SEL _SB_MAKEMASK(8,S_MAC_RX_CH_MSN_SEL)
#define V_MAC_RX_CH_MSN_SEL(x) _SB_MAKEVALUE(x,S_MAC_RX_CH_MSN_SEL)
#define G_MAC_RX_CH_MSN_SEL(x) _SB_GETVALUE(x,S_MAC_RX_CH_MSN_SEL,M_MAC_RX_CH_MSN_SEL)
-#endif /* 1250 PASS3 || 112x PASS1 */
+#endif /* 1250 PASS3 || 112x PASS1 || 1480 */
/*
* MAC Receive Channel Select Registers (Table 9-25)
diff --git a/include/asm-mips/sibyte/sb1250_mc.h b/include/asm-mips/sibyte/sb1250_mc.h
index 1dd41c927996..26e421498c97 100644
--- a/include/asm-mips/sibyte/sb1250_mc.h
+++ b/include/asm-mips/sibyte/sb1250_mc.h
@@ -8,8 +8,6 @@
*
* SB1250 specification level: User's manual 1/02/02
*
- * Author: Mitch Lichtenberg
- *
*********************************************************************
*
* Copyright 2000,2001,2002,2003
@@ -324,6 +322,10 @@
#define K_MC_tRFC_DEFAULT 12
#define V_MC_tRFC_DEFAULT V_MC_tRFC(K_MC_tRFC_DEFAULT)
+#if SIBYTE_HDR_FEATURE(1250, PASS3)
+#define M_MC_tRFC_PLUS16 _SB_MAKEMASK1(51) /* 1250C3 and later. */
+#endif
+
#define S_MC_tCwCr 40
#define M_MC_tCwCr _SB_MAKEMASK(4,S_MC_tCwCr)
#define V_MC_tCwCr(x) _SB_MAKEVALUE(x,S_MC_tCwCr)
diff --git a/include/asm-mips/sibyte/sb1250_regs.h b/include/asm-mips/sibyte/sb1250_regs.h
index 9db80cd13a79..bab3a4580a36 100644
--- a/include/asm-mips/sibyte/sb1250_regs.h
+++ b/include/asm-mips/sibyte/sb1250_regs.h
@@ -8,8 +8,6 @@
*
* SB1250 specification level: 01/02/2002
*
- * Author: Mitch Lichtenberg
- *
*********************************************************************
*
* Copyright 2000,2001,2002,2003
@@ -61,6 +59,8 @@
* XXX: can't remove MC base 0 if 112x, since it's used by other macros,
* since there is one reg there (but it could get its addr/offset constant).
*/
+
+#if SIBYTE_HDR_FEATURE_1250_112x /* This MC only on 1250 & 112x */
#define A_MC_BASE_0 0x0010051000
#define A_MC_BASE_1 0x0010052000
#define MC_REGISTER_SPACING 0x1000
@@ -101,10 +101,14 @@
#define R_MC_TEST_ECC 0x0000000420
#define R_MC_MCLK_CFG 0x0000000500
+#endif /* 1250 & 112x */
+
/* *********************************************************************
* L2 Cache Control Registers
********************************************************************* */
+#if SIBYTE_HDR_FEATURE_1250_112x /* This L2C only on 1250/112x */
+
#define A_L2_READ_TAG 0x0010040018
#define A_L2_ECC_TAG 0x0010040038
#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1)
@@ -125,13 +129,16 @@
#define A_L2_READ_ADDRESS A_L2_READ_TAG
#define A_L2_EEC_ADDRESS A_L2_ECC_TAG
+#endif
/* *********************************************************************
* PCI Interface Registers
********************************************************************* */
+#if SIBYTE_HDR_FEATURE_1250_112x /* This PCI/HT only on 1250/112x */
#define A_PCI_TYPE00_HEADER 0x00DE000000
#define A_PCI_TYPE01_HEADER 0x00DE000800
+#endif
/* *********************************************************************
@@ -264,15 +271,15 @@
********************************************************************* */
+#if SIBYTE_HDR_FEATURE_1250_112x /* This MC only on 1250 & 112x */
#define R_DUART_NUM_PORTS 2
#define A_DUART 0x0010060000
-#define A_DUART_REG(r)
-
#define DUART_CHANREG_SPACING 0x100
#define A_DUART_CHANREG(chan,reg) (A_DUART + DUART_CHANREG_SPACING*(chan) + (reg))
#define R_DUART_CHANREG(chan,reg) (DUART_CHANREG_SPACING*(chan) + (reg))
+#endif /* 1250 & 112x */
#define R_DUART_MODE_REG_1 0x100
#define R_DUART_MODE_REG_2 0x110
@@ -307,11 +314,13 @@
#define DUART_IMRISR_SPACING 0x20
+#if SIBYTE_HDR_FEATURE_1250_112x /* This MC only on 1250 & 112x */
#define R_DUART_IMRREG(chan) (R_DUART_IMR_A + (chan)*DUART_IMRISR_SPACING)
#define R_DUART_ISRREG(chan) (R_DUART_ISR_A + (chan)*DUART_IMRISR_SPACING)
#define A_DUART_IMRREG(chan) (A_DUART + R_DUART_IMRREG(chan))
#define A_DUART_ISRREG(chan) (A_DUART + R_DUART_ISRREG(chan))
+#endif /* 1250 & 112x */
@@ -368,6 +377,8 @@
********************************************************************* */
+#if SIBYTE_HDR_FEATURE_1250_112x /* sync serial only on 1250/112x */
+
#define A_SER_BASE_0 0x0010060400
#define A_SER_BASE_1 0x0010060800
#define SER_SPACING 0x400
@@ -457,6 +468,8 @@
#define R_SER_RMON_RX_ERRORS 0x000001F0
#define R_SER_RMON_RX_BADADDR 0x000001F8
+#endif /* 1250/112x */
+
/* *********************************************************************
* Generic Bus Registers
********************************************************************* */
@@ -634,12 +647,13 @@
#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1)
#define A_SCD_SCRATCH 0x0010020C10
+#endif /* 1250 PASS2 || 112x PASS1 */
+#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) || SIBYTE_HDR_FEATURE_CHIP(1480)
#define A_SCD_ZBBUS_CYCLE_COUNT 0x0010030000
#define A_SCD_ZBBUS_CYCLE_CP0 0x0010020C00
#define A_SCD_ZBBUS_CYCLE_CP1 0x0010020C08
-#endif /* 1250 PASS2 || 112x PASS1 */
-
+#endif
/* *********************************************************************
* System Control Registers
@@ -667,15 +681,16 @@
#define A_ADDR_TRAP_CFG_1 0x0010020448
#define A_ADDR_TRAP_CFG_2 0x0010020450
#define A_ADDR_TRAP_CFG_3 0x0010020458
-#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1)
+#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) || SIBYTE_HDR_FEATURE_CHIP(1480)
#define A_ADDR_TRAP_REG_DEBUG 0x0010020460
-#endif /* 1250 PASS2 || 112x PASS1 */
+#endif /* 1250 PASS2 || 112x PASS1 || 1480 */
/* *********************************************************************
* System Interrupt Mapper Registers
********************************************************************* */
+#if SIBYTE_HDR_FEATURE_1250_112x
#define A_IMR_CPU0_BASE 0x0010020000
#define A_IMR_CPU1_BASE 0x0010022000
#define IMR_REGISTER_SPACING 0x2000
@@ -700,6 +715,7 @@
#define R_IMR_INTERRUPT_STATUS_COUNT 7
#define R_IMR_INTERRUPT_MAP_BASE 0x0200
#define R_IMR_INTERRUPT_MAP_COUNT 64
+#endif /* 1250/112x */
/* *********************************************************************
* System Performance Counter Registers
@@ -718,6 +734,7 @@
#define A_SCD_BUS_ERR_STATUS 0x0010020880
#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1)
#define A_SCD_BUS_ERR_STATUS_DEBUG 0x00100208D0
+#define A_BUS_ERR_STATUS_DEBUG 0x00100208D0
#endif /* 1250 PASS2 || 112x PASS1 */
#define A_BUS_ERR_DATA_0 0x00100208A0
#define A_BUS_ERR_DATA_1 0x00100208A8
@@ -798,6 +815,7 @@
* Physical Address Map
********************************************************************* */
+#if SIBYTE_HDR_FEATURE_1250_112x
#define A_PHYS_MEMORY_0 _SB_MAKE64(0x0000000000)
#define A_PHYS_MEMORY_SIZE _SB_MAKE64((256*1024*1024))
#define A_PHYS_SYSTEM_CTL _SB_MAKE64(0x0010000000)
@@ -831,6 +849,7 @@
#define A_PHYS_L2CACHE_WAY1 _SB_MAKE64(0x00D01A0000)
#define A_PHYS_L2CACHE_WAY2 _SB_MAKE64(0x00D01C0000)
#define A_PHYS_L2CACHE_WAY3 _SB_MAKE64(0x00D01E0000)
+#endif
#endif
diff --git a/include/asm-mips/sibyte/sb1250_scd.h b/include/asm-mips/sibyte/sb1250_scd.h
index dbbd682fb47e..a667bc14a7cd 100644
--- a/include/asm-mips/sibyte/sb1250_scd.h
+++ b/include/asm-mips/sibyte/sb1250_scd.h
@@ -8,8 +8,6 @@
*
* SB1250 specification level: User's manual 1/02/02
*
- * Author: Mitch Lichtenberg
- *
*********************************************************************
*
* Copyright 2000,2001,2002,2003
@@ -51,26 +49,70 @@
#define V_SYS_REVISION(x) _SB_MAKEVALUE(x,S_SYS_REVISION)
#define G_SYS_REVISION(x) _SB_GETVALUE(x,S_SYS_REVISION,M_SYS_REVISION)
-#if SIBYTE_HDR_FEATURE_CHIP(1250)
-#define K_SYS_REVISION_BCM1250_PASS1 1
-#define K_SYS_REVISION_BCM1250_PASS2 3
-#define K_SYS_REVISION_BCM1250_A10 11
-#define K_SYS_REVISION_BCM1250_PASS2_2 16
-#define K_SYS_REVISION_BCM1250_B2 17
-#define K_SYS_REVISION_BCM1250_PASS3 32
-#define K_SYS_REVISION_BCM1250_C1 33
+#define K_SYS_REVISION_BCM1250_PASS1 0x01
+
+#define K_SYS_REVISION_BCM1250_PASS2 0x03
+#define K_SYS_REVISION_BCM1250_A1 0x03 /* Pass 2.0 WB */
+#define K_SYS_REVISION_BCM1250_A2 0x04 /* Pass 2.0 FC */
+#define K_SYS_REVISION_BCM1250_A3 0x05 /* Pass 2.1 FC */
+#define K_SYS_REVISION_BCM1250_A4 0x06 /* Pass 2.1 WB */
+#define K_SYS_REVISION_BCM1250_A6 0x07 /* OR 0x04 (A2) w/WID != 0 */
+#define K_SYS_REVISION_BCM1250_A8 0x0b /* A8/A10 */
+#define K_SYS_REVISION_BCM1250_A9 0x08
+#define K_SYS_REVISION_BCM1250_A10 K_SYS_REVISION_BCM1250_A8
+#define K_SYS_REVISION_BCM1250_PASS2_2 0x10
+#define K_SYS_REVISION_BCM1250_B0 K_SYS_REVISION_BCM1250_B1
+#define K_SYS_REVISION_BCM1250_B1 0x10
+#define K_SYS_REVISION_BCM1250_B2 0x11
+
+#define K_SYS_REVISION_BCM1250_C0 0x20
+#define K_SYS_REVISION_BCM1250_C1 0x21
+#define K_SYS_REVISION_BCM1250_C2 0x22
+#define K_SYS_REVISION_BCM1250_C3 0x23
+
+#if SIBYTE_HDR_FEATURE_CHIP(1250)
/* XXX: discourage people from using these constants. */
#define K_SYS_REVISION_PASS1 K_SYS_REVISION_BCM1250_PASS1
#define K_SYS_REVISION_PASS2 K_SYS_REVISION_BCM1250_PASS2
#define K_SYS_REVISION_PASS2_2 K_SYS_REVISION_BCM1250_PASS2_2
#define K_SYS_REVISION_PASS3 K_SYS_REVISION_BCM1250_PASS3
+#define K_SYS_REVISION_BCM1250_PASS3 K_SYS_REVISION_BCM1250_C0
#endif /* 1250 */
-#if SIBYTE_HDR_FEATURE_CHIP(112x)
-#define K_SYS_REVISION_BCM112x_A1 32
-#define K_SYS_REVISION_BCM112x_A2 33
-#endif /* 112x */
+#define K_SYS_REVISION_BCM112x_A1 0x20
+#define K_SYS_REVISION_BCM112x_A2 0x21
+#define K_SYS_REVISION_BCM112x_A3 0x22
+#define K_SYS_REVISION_BCM112x_A4 0x23
+
+#define K_SYS_REVISION_BCM1480_S0 0x01
+#define K_SYS_REVISION_BCM1480_A1 0x02
+#define K_SYS_REVISION_BCM1480_A2 0x03
+#define K_SYS_REVISION_BCM1480_A3 0x04
+#define K_SYS_REVISION_BCM1480_B0 0x11
+
+/*Cache size - 23:20 of revision register*/
+#define S_SYS_L2C_SIZE _SB_MAKE64(20)
+#define M_SYS_L2C_SIZE _SB_MAKEMASK(4,S_SYS_L2C_SIZE)
+#define V_SYS_L2C_SIZE(x) _SB_MAKEVALUE(x,S_SYS_L2C_SIZE)
+#define G_SYS_L2C_SIZE(x) _SB_GETVALUE(x,S_SYS_L2C_SIZE,M_SYS_L2C_SIZE)
+
+#define K_SYS_L2C_SIZE_1MB 0
+#define K_SYS_L2C_SIZE_512KB 5
+#define K_SYS_L2C_SIZE_256KB 2
+#define K_SYS_L2C_SIZE_128KB 1
+
+#define K_SYS_L2C_SIZE_BCM1250 K_SYS_L2C_SIZE_512KB
+#define K_SYS_L2C_SIZE_BCM1125 K_SYS_L2C_SIZE_256KB
+#define K_SYS_L2C_SIZE_BCM1122 K_SYS_L2C_SIZE_128KB
+
+
+/* Number of CPU cores, bits 27:24 of revision register*/
+#define S_SYS_NUM_CPUS _SB_MAKE64(24)
+#define M_SYS_NUM_CPUS _SB_MAKEMASK(4,S_SYS_NUM_CPUS)
+#define V_SYS_NUM_CPUS(x) _SB_MAKEVALUE(x,S_SYS_NUM_CPUS)
+#define G_SYS_NUM_CPUS(x) _SB_GETVALUE(x,S_SYS_NUM_CPUS,M_SYS_NUM_CPUS)
+
/* XXX: discourage people from using these constants. */
#define S_SYS_PART _SB_MAKE64(16)
@@ -83,6 +125,8 @@
#define K_SYS_PART_BCM1120 0x1121
#define K_SYS_PART_BCM1125 0x1123
#define K_SYS_PART_BCM1125H 0x1124
+#define K_SYS_PART_BCM1122 0x1113
+
/* The "peripheral set" (SOC type) is the low 4 bits of the "part" field. */
#define S_SYS_SOC_TYPE _SB_MAKE64(16)
@@ -96,6 +140,8 @@
#define K_SYS_SOC_TYPE_BCM1125 0x3
#define K_SYS_SOC_TYPE_BCM1125H 0x4
#define K_SYS_SOC_TYPE_BCM1250_ALT2 0x5 /* 1250pass2 w/ 1/2 L2. */
+#define K_SYS_SOC_TYPE_BCM1x80 0x6
+#define K_SYS_SOC_TYPE_BCM1x55 0x7
/*
* Calculate correct SOC type given a copy of system revision register.
@@ -127,10 +173,12 @@
#define V_SYS_WID(x) _SB_MAKEVALUE(x,S_SYS_WID)
#define G_SYS_WID(x) _SB_GETVALUE(x,S_SYS_WID,M_SYS_WID)
-/* System Manufacturing Register
-* Register: SCD_SYSTEM_MANUF
-*/
+/*
+ * System Manufacturing Register
+ * Register: SCD_SYSTEM_MANUF
+ */
+#if SIBYTE_HDR_FEATURE_1250_112x
/* Wafer ID: bits 31:0 */
#define S_SYS_WAFERID1_200 _SB_MAKE64(0)
#define M_SYS_WAFERID1_200 _SB_MAKEMASK(32,S_SYS_WAFERID1_200)
@@ -139,8 +187,8 @@
#define S_SYS_BIN _SB_MAKE64(32)
#define M_SYS_BIN _SB_MAKEMASK(4,S_SYS_BIN)
-#define V_SYS_BIN _SB_MAKEVALUE(x,S_SYS_BIN)
-#define G_SYS_BIN _SB_GETVALUE(x,S_SYS_BIN,M_SYS_BIN)
+#define V_SYS_BIN(x) _SB_MAKEVALUE(x,S_SYS_BIN)
+#define G_SYS_BIN(x) _SB_GETVALUE(x,S_SYS_BIN,M_SYS_BIN)
/* Wafer ID: bits 39:36 */
#define S_SYS_WAFERID2_200 _SB_MAKE64(36)
@@ -163,12 +211,14 @@
#define M_SYS_YPOS _SB_MAKEMASK(6,S_SYS_YPOS)
#define V_SYS_YPOS(x) _SB_MAKEVALUE(x,S_SYS_YPOS)
#define G_SYS_YPOS(x) _SB_GETVALUE(x,S_SYS_YPOS,M_SYS_YPOS)
+#endif
/*
* System Config Register (Table 4-2)
* Register: SCD_SYSTEM_CFG
*/
+#if SIBYTE_HDR_FEATURE_1250_112x
#define M_SYS_LDT_PLL_BYP _SB_MAKEMASK1(3)
#define M_SYS_PCI_SYNC_TEST_MODE _SB_MAKEMASK1(4)
#define M_SYS_IOB0_DIV _SB_MAKEMASK1(5)
@@ -253,6 +303,8 @@
#define M_SYS_SW_FLAG _SB_MAKEMASK1(63)
#endif /* 1250 PASS2 || 112x PASS1 */
+#endif
+
/*
* Mailbox Registers (Table 4-3)
@@ -326,6 +378,7 @@
* System Performance Counters
*/
+#if SIBYTE_HDR_FEATURE_1250_112x
#define S_SPC_CFG_SRC0 0
#define M_SPC_CFG_SRC0 _SB_MAKEMASK(8,S_SPC_CFG_SRC0)
#define V_SPC_CFG_SRC0(x) _SB_MAKEVALUE(x,S_SPC_CFG_SRC0)
@@ -348,6 +401,7 @@
#define M_SPC_CFG_CLEAR _SB_MAKEMASK1(32)
#define M_SPC_CFG_ENABLE _SB_MAKEMASK1(33)
+#endif
/*
@@ -412,6 +466,7 @@
* Address Trap Registers
*/
+#if SIBYTE_HDR_FEATURE_1250_112x
#define M_ATRAP_INDEX _SB_MAKEMASK(4,0)
#define M_ATRAP_ADDRESS _SB_MAKEMASK(40,0)
@@ -436,7 +491,6 @@
#define K_BUS_AGENT_IOB0 2
#define K_BUS_AGENT_IOB1 3
#define K_BUS_AGENT_SCD 4
-#define K_BUS_AGENT_RESERVED 5
#define K_BUS_AGENT_L2C 6
#define K_BUS_AGENT_MC 7
@@ -454,10 +508,14 @@
#define K_ATRAP_CFG_CATTR_NOTNONCOH 6
#define K_ATRAP_CFG_CATTR_NOTCOHERENT 7
+#endif /* 1250/112x */
+
/*
* Trace Buffer Config register
*/
+#if SIBYTE_HDR_FEATURE_1250_112x
+
#define M_SCD_TRACE_CFG_RESET _SB_MAKEMASK1(0)
#define M_SCD_TRACE_CFG_START_READ _SB_MAKEMASK1(1)
#define M_SCD_TRACE_CFG_START _SB_MAKEMASK1(2)
@@ -475,6 +533,8 @@
#define V_SCD_TRACE_CFG_CUR_ADDR(x) _SB_MAKEVALUE(x,S_SCD_TRACE_CFG_CUR_ADDR)
#define G_SCD_TRACE_CFG_CUR_ADDR(x) _SB_GETVALUE(x,S_SCD_TRACE_CFG_CUR_ADDR,M_SCD_TRACE_CFG_CUR_ADDR)
+#endif /* 1250/112x */
+
/*
* Trace Event registers
*/
@@ -578,5 +638,7 @@
#define M_SCD_TRSEQ_DEBUGPIN _SB_MAKEMASK1(20)
#define M_SCD_TRSEQ_DEBUGCPU _SB_MAKEMASK1(21)
#define M_SCD_TRSEQ_CLEARUSE _SB_MAKEMASK1(22)
+#define M_SCD_TRSEQ_ALLD_A _SB_MAKEMASK1(23)
+#define M_SCD_TRSEQ_ALL_A _SB_MAKEMASK1(24)
#endif
diff --git a/include/asm-mips/sibyte/sb1250_smbus.h b/include/asm-mips/sibyte/sb1250_smbus.h
index 335c53e92936..279a912213cd 100644
--- a/include/asm-mips/sibyte/sb1250_smbus.h
+++ b/include/asm-mips/sibyte/sb1250_smbus.h
@@ -6,9 +6,8 @@
* This module contains constants and macros useful for
* manipulating the SB1250's SMbus devices.
*
- * SB1250 specification level: 01/02/2002
- *
- * Author: Mitch Lichtenberg
+ * SB1250 specification level: 10/21/02
+ * BCM1280 specification level: 11/24/03
*
*********************************************************************
*
@@ -47,6 +46,7 @@
#define K_SMB_FREQ_400KHZ 0x1F
#define K_SMB_FREQ_100KHZ 0x7D
+#define K_SMB_FREQ_10KHZ 1250
#define S_SMB_CMD 0
#define M_SMB_CMD _SB_MAKEMASK(8,S_SMB_CMD)
@@ -58,7 +58,11 @@
#define M_SMB_ERR_INTR _SB_MAKEMASK1(0)
#define M_SMB_FINISH_INTR _SB_MAKEMASK1(1)
-#define M_SMB_DATA_OUT _SB_MAKEMASK1(4)
+
+#define S_SMB_DATA_OUT 4
+#define M_SMB_DATA_OUT _SB_MAKEMASK1(S_SMB_DATA_OUT)
+#define V_SMB_DATA_OUT(x) _SB_MAKEVALUE(x,S_SMB_DATA_OUT)
+
#define M_SMB_DATA_DIR _SB_MAKEMASK1(5)
#define M_SMB_DATA_DIR_OUTPUT M_SMB_DATA_DIR
#define M_SMB_CLK_OUT _SB_MAKEMASK1(6)
@@ -71,8 +75,23 @@
#define M_SMB_BUSY _SB_MAKEMASK1(0)
#define M_SMB_ERROR _SB_MAKEMASK1(1)
#define M_SMB_ERROR_TYPE _SB_MAKEMASK1(2)
-#define M_SMB_REF _SB_MAKEMASK1(6)
-#define M_SMB_DATA_IN _SB_MAKEMASK1(7)
+
+#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1) || SIBYTE_HDR_FEATURE_CHIP(1480)
+#define S_SMB_SCL_IN 5
+#define M_SMB_SCL_IN _SB_MAKEMASK1(S_SMB_SCL_IN)
+#define V_SMB_SCL_IN(x) _SB_MAKEVALUE(x,S_SMB_SCL_IN)
+#define G_SMB_SCL_IN(x) _SB_GETVALUE(x,S_SMB_SCL_IN,M_SMB_SCL_IN)
+#endif /* 1250 PASS3 || 112x PASS1 || 1480 */
+
+#define S_SMB_REF 6
+#define M_SMB_REF _SB_MAKEMASK1(S_SMB_REF)
+#define V_SMB_REF(x) _SB_MAKEVALUE(x,S_SMB_REF)
+#define G_SMB_REF(x) _SB_GETVALUE(x,S_SMB_REF,M_SMB_REF)
+
+#define S_SMB_DATA_IN 7
+#define M_SMB_DATA_IN _SB_MAKEMASK1(S_SMB_DATA_IN)
+#define V_SMB_DATA_IN(x) _SB_MAKEVALUE(x,S_SMB_DATA_IN)
+#define G_SMB_DATA_IN(x) _SB_GETVALUE(x,S_SMB_DATA_IN,M_SMB_DATA_IN)
/*
* SMBus Start/Command registers (Table 14-9)
@@ -132,16 +151,14 @@
#define V_SPEC_MB(x) _SB_MAKEVALUE(x,S_SPEC_PEC)
-#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1)
+#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) || SIBYTE_HDR_FEATURE_CHIP(1480)
#define S_SMB_CMDH 8
-#define M_SMB_CMDH _SB_MAKEMASK(8,S_SMBH_CMD)
-#define V_SMB_CMDH(x) _SB_MAKEVALUE(x,S_SMBH_CMD)
+#define M_SMB_CMDH _SB_MAKEMASK(8,S_SMB_CMDH)
+#define V_SMB_CMDH(x) _SB_MAKEVALUE(x,S_SMB_CMDH)
#define M_SMB_EXTEND _SB_MAKEMASK1(14)
-#define M_SMB_DIR _SB_MAKEMASK1(13)
-
#define S_SMB_DFMT 8
#define M_SMB_DFMT _SB_MAKEMASK(3,S_SMB_DFMT)
#define V_SMB_DFMT(x) _SB_MAKEVALUE(x,S_SMB_DFMT)
@@ -165,6 +182,23 @@
#define V_SMB_DFMT_CMD5BYTE V_SMB_DFMT(K_SMB_DFMT_CMD5BYTE)
#define V_SMB_DFMT_RESERVED V_SMB_DFMT(K_SMB_DFMT_RESERVED)
-#endif /* 1250 PASS2 || 112x PASS1 */
+#define S_SMB_AFMT 11
+#define M_SMB_AFMT _SB_MAKEMASK(2,S_SMB_AFMT)
+#define V_SMB_AFMT(x) _SB_MAKEVALUE(x,S_SMB_AFMT)
+#define G_SMB_AFMT(x) _SB_GETVALUE(x,S_SMB_AFMT,M_SMB_AFMT)
+
+#define K_SMB_AFMT_NONE 0
+#define K_SMB_AFMT_ADDR 1
+#define K_SMB_AFMT_ADDR_CMD1BYTE 2
+#define K_SMB_AFMT_ADDR_CMD2BYTE 3
+
+#define V_SMB_AFMT_NONE V_SMB_AFMT(K_SMB_AFMT_NONE)
+#define V_SMB_AFMT_ADDR V_SMB_AFMT(K_SMB_AFMT_ADDR)
+#define V_SMB_AFMT_ADDR_CMD1BYTE V_SMB_AFMT(K_SMB_AFMT_ADDR_CMD1BYTE)
+#define V_SMB_AFMT_ADDR_CMD2BYTE V_SMB_AFMT(K_SMB_AFMT_ADDR_CMD2BYTE)
+
+#define M_SMB_DIR _SB_MAKEMASK1(13)
+
+#endif /* 1250 PASS2 || 112x PASS1 || 1480 */
#endif
diff --git a/include/asm-mips/sibyte/sb1250_syncser.h b/include/asm-mips/sibyte/sb1250_syncser.h
index fa2760d38b8b..dd154ac505d8 100644
--- a/include/asm-mips/sibyte/sb1250_syncser.h
+++ b/include/asm-mips/sibyte/sb1250_syncser.h
@@ -8,8 +8,6 @@
*
* SB1250 specification level: User's manual 1/02/02
*
- * Author: Mitch Lichtenberg
- *
*********************************************************************
*
* Copyright 2000,2001,2002,2003
diff --git a/include/asm-mips/sibyte/sb1250_uart.h b/include/asm-mips/sibyte/sb1250_uart.h
index 923ea4f44e0f..e87045e62bf0 100644
--- a/include/asm-mips/sibyte/sb1250_uart.h
+++ b/include/asm-mips/sibyte/sb1250_uart.h
@@ -8,8 +8,6 @@
*
* SB1250 specification level: User's manual 1/02/02
*
- * Author: Mitch Lichtenberg
- *
*********************************************************************
*
* Copyright 2000,2001,2002,2003
@@ -240,7 +238,12 @@
*/
#define M_DUART_ISR_TX_A _SB_MAKEMASK1(0)
-#define M_DUART_ISR_RX_A _SB_MAKEMASK1(1)
+
+#define S_DUART_ISR_RX_A 1
+#define M_DUART_ISR_RX_A _SB_MAKEMASK1(S_DUART_ISR_RX_A)
+#define V_DUART_ISR_RX_A(x) _SB_MAKEVALUE(x,S_DUART_ISR_RX_A)
+#define G_DUART_ISR_RX_A(x) _SB_GETVALUE(x,S_DUART_ISR_RX_A,M_DUART_ISR_RX_A)
+
#define M_DUART_ISR_BRK_A _SB_MAKEMASK1(2)
#define M_DUART_ISR_IN_A _SB_MAKEMASK1(3)
#define M_DUART_ISR_TX_B _SB_MAKEMASK1(4)
@@ -331,7 +334,7 @@
#define M_DUART_OUT_PIN_CLR(chan) \
(chan == 0 ? M_DUART_OUT_PIN_CLR0 : M_DUART_OUT_PIN_CLR1)
-#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1)
+#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) || SIBYTE_HDR_FEATURE_CHIP(1480)
/*
* Full Interrupt Control Register
*/
@@ -345,7 +348,7 @@
#define M_DUART_INT_TIME _SB_MAKEMASK(4,S_DUART_INT_TIME)
#define V_DUART_INT_TIME(x) _SB_MAKEVALUE(x,S_DUART_INT_TIME)
#define G_DUART_INT_TIME(x) _SB_GETVALUE(x,S_DUART_INT_TIME,M_DUART_INT_TIME)
-#endif /* 1250 PASS2 || 112x PASS1 */
+#endif /* 1250 PASS2 || 112x PASS1 || 1480 */
/* ********************************************************************** */
diff --git a/include/asm-mips/sibyte/swarm.h b/include/asm-mips/sibyte/swarm.h
index 97fa0494c30c..06e1d528e03a 100644
--- a/include/asm-mips/sibyte/swarm.h
+++ b/include/asm-mips/sibyte/swarm.h
@@ -34,7 +34,7 @@
#define SIBYTE_DEFAULT_CONSOLE "ttyS0,115200"
#endif
#ifdef CONFIG_SIBYTE_LITTLESUR
-#define SIBYTE_BOARD_NAME "BCM1250C2 (LittleSur)"
+#define SIBYTE_BOARD_NAME "BCM91250C2 (LittleSur)"
#define SIBYTE_HAVE_PCMCIA 0
#define SIBYTE_HAVE_IDE 1
#define SIBYTE_DEFAULT_CONSOLE "cfe0"
diff --git a/include/asm-mips/sigcontext.h b/include/asm-mips/sigcontext.h
index f7fbebaa0744..8edabb0be23f 100644
--- a/include/asm-mips/sigcontext.h
+++ b/include/asm-mips/sigcontext.h
@@ -27,14 +27,15 @@ struct sigcontext {
unsigned int sc_fpc_csr;
unsigned int sc_fpc_eir; /* Unused */
unsigned int sc_used_math;
- unsigned int sc_ssflags; /* Unused */
+ unsigned int sc_dsp; /* dsp status, was sc_ssflags */
unsigned long long sc_mdhi;
unsigned long long sc_mdlo;
-
- unsigned int sc_cause; /* Unused */
- unsigned int sc_badvaddr; /* Unused */
-
- unsigned long sc_sigset[4]; /* kernel's sigset_t */
+ unsigned long sc_hi1; /* Was sc_cause */
+ unsigned long sc_lo1; /* Was sc_badvaddr */
+ unsigned long sc_hi2; /* Was sc_sigset[4] */
+ unsigned long sc_lo2;
+ unsigned long sc_hi3;
+ unsigned long sc_lo3;
};
#endif /* _MIPS_SIM == _MIPS_SIM_ABI32 */
@@ -48,19 +49,19 @@ struct sigcontext {
* Warning: this structure illdefined with sc_badvaddr being just an unsigned
* int so it was changed to unsigned long in 2.6.0-test1. This may break
* binary compatibility - no prisoners.
+ * DSP ASE in 2.6.12-rc4. Turn sc_mdhi and sc_mdlo into an array of four
+ * entries, add sc_dsp and sc_reserved for padding. No prisoners.
*/
struct sigcontext {
unsigned long sc_regs[32];
unsigned long sc_fpregs[32];
- unsigned long sc_mdhi;
- unsigned long sc_mdlo;
+ unsigned long sc_hi[4];
+ unsigned long sc_lo[4];
unsigned long sc_pc;
- unsigned long sc_badvaddr;
- unsigned int sc_status;
unsigned int sc_fpc_csr;
- unsigned int sc_fpc_eir;
unsigned int sc_used_math;
- unsigned int sc_cause;
+ unsigned int sc_dsp;
+ unsigned int sc_reserved;
};
#ifdef __KERNEL__
@@ -68,23 +69,24 @@ struct sigcontext {
#include <linux/posix_types.h>
struct sigcontext32 {
- __u32 sc_regmask; /* Unused */
- __u32 sc_status;
- __u64 sc_pc;
- __u64 sc_regs[32];
- __u64 sc_fpregs[32];
- __u32 sc_ownedfp; /* Unused */
- __u32 sc_fpc_csr;
- __u32 sc_fpc_eir; /* Unused */
- __u32 sc_used_math;
- __u32 sc_ssflags; /* Unused */
- __u64 sc_mdhi;
- __u64 sc_mdlo;
-
- __u32 sc_cause; /* Unused */
- __u32 sc_badvaddr; /* Unused */
-
- __u32 sc_sigset[4]; /* kernel's sigset_t */
+ __u32 sc_regmask; /* Unused */
+ __u32 sc_status;
+ __u64 sc_pc;
+ __u64 sc_regs[32];
+ __u64 sc_fpregs[32];
+ __u32 sc_ownedfp; /* Unused */
+ __u32 sc_fpc_csr;
+ __u32 sc_fpc_eir; /* Unused */
+ __u32 sc_used_math;
+ __u32 sc_dsp; /* dsp status, was sc_ssflags */
+ __u64 sc_mdhi;
+ __u64 sc_mdlo;
+ __u32 sc_hi1; /* Was sc_cause */
+ __u32 sc_lo1; /* Was sc_badvaddr */
+ __u32 sc_hi2; /* Was sc_sigset[4] */
+ __u32 sc_lo2;
+ __u32 sc_hi3;
+ __u32 sc_lo3;
};
#endif /* __KERNEL__ */
diff --git a/include/asm-mips/siginfo.h b/include/asm-mips/siginfo.h
index 698becab5a9e..2ba313d94a78 100644
--- a/include/asm-mips/siginfo.h
+++ b/include/asm-mips/siginfo.h
@@ -11,6 +11,7 @@
#include <linux/config.h>
+#define __ARCH_SIGEV_PREAMBLE_SIZE (sizeof(long) + 2*sizeof(int))
#undef __ARCH_SI_TRAPNO /* exception code needs to fill this ... */
#define HAVE_ARCH_SIGINFO_T
diff --git a/include/asm-mips/signal.h b/include/asm-mips/signal.h
index f2c470f1d369..8ca539e80d87 100644
--- a/include/asm-mips/signal.h
+++ b/include/asm-mips/signal.h
@@ -98,12 +98,39 @@ typedef unsigned long old_sigset_t; /* at least 32 bits */
#define MINSIGSTKSZ 2048
#define SIGSTKSZ 8192
+#ifdef __KERNEL__
+
+/*
+ * These values of sa_flags are used only by the kernel as part of the
+ * irq handling routines.
+ *
+ * SA_INTERRUPT is also used by the irq handling routines.
+ * SA_SHIRQ flag is for shared interrupt support on PCI and EISA.
+ */
+#define SA_SAMPLE_RANDOM SA_RESTART
+
+#ifdef CONFIG_TRAD_SIGNALS
+#define sig_uses_siginfo(ka) ((ka)->sa.sa_flags & SA_SIGINFO)
+#else
+#define sig_uses_siginfo(ka) (1)
+#endif
+
+#endif /* __KERNEL__ */
+
#define SIG_BLOCK 1 /* for blocking signals */
#define SIG_UNBLOCK 2 /* for unblocking signals */
#define SIG_SETMASK 3 /* for setting the signal mask */
#define SIG_SETMASK32 256 /* Goodie from SGI for BSD compatibility:
set only the low 32 bit of the sigset. */
-#include <asm-generic/signal.h>
+
+/* Type of a signal handler. */
+typedef void __signalfn_t(int);
+typedef __signalfn_t __user *__sighandler_t;
+
+/* Fake signal functions */
+#define SIG_DFL ((__sighandler_t)0) /* default signal handling */
+#define SIG_IGN ((__sighandler_t)1) /* ignore signal */
+#define SIG_ERR ((__sighandler_t)-1) /* error return from signal */
struct sigaction {
unsigned int sa_flags;
diff --git a/include/asm-mips/sn/sn0/arch.h b/include/asm-mips/sn/sn0/arch.h
index 0e00dd474afc..fb78773a5efe 100644
--- a/include/asm-mips/sn/sn0/arch.h
+++ b/include/asm-mips/sn/sn0/arch.h
@@ -74,13 +74,8 @@
#define MAX_MEM_SLOTS 32 /* max slots per node */
#endif /* defined(N_MODE) */
-#if SABLE_RTL
-#define SLOT_SHIFT (28)
-#define SLOT_MIN_MEM_SIZE (16*1024*1024)
-#else
#define SLOT_SHIFT (27)
#define SLOT_MIN_MEM_SIZE (32*1024*1024)
-#endif
#define CPUS_PER_NODE 2 /* CPUs on a single hub */
#define CPUS_PER_NODE_SHFT 1 /* Bits to shift in the node number */
diff --git a/include/asm-mips/socket.h b/include/asm-mips/socket.h
index 753b6620e6fa..0bb31e5aaca6 100644
--- a/include/asm-mips/socket.h
+++ b/include/asm-mips/socket.h
@@ -37,8 +37,6 @@ To add: #define SO_REUSEPORT 0x0200 /* Allow local address and port reuse. */
#define SO_ERROR 0x1007 /* get error status and clear */
#define SO_SNDBUF 0x1001 /* Send buffer size. */
#define SO_RCVBUF 0x1002 /* Receive buffer. */
-#define SO_SNDBUFFORCE 0x100a
-#define SO_RCVBUFFORCE 0x100b
#define SO_SNDLOWAT 0x1003 /* send low-water mark */
#define SO_RCVLOWAT 0x1004 /* receive low-water mark */
#define SO_SNDTIMEO 0x1005 /* send timeout */
@@ -69,6 +67,8 @@ To add: #define SO_REUSEPORT 0x0200 /* Allow local address and port reuse. */
#define SCM_TIMESTAMP SO_TIMESTAMP
#define SO_PEERSEC 30
+#define SO_SNDBUFFORCE 31
+#define SO_RCVBUFFORCE 33
#ifdef __KERNEL__
@@ -92,6 +92,7 @@ enum sock_type {
SOCK_RAW = 3,
SOCK_RDM = 4,
SOCK_SEQPACKET = 5,
+ SOCK_DCCP = 6,
SOCK_PACKET = 10,
};
diff --git a/include/asm-mips/spinlock.h b/include/asm-mips/spinlock.h
index 4d0135b11156..669b8e349ff2 100644
--- a/include/asm-mips/spinlock.h
+++ b/include/asm-mips/spinlock.h
@@ -9,17 +9,16 @@
#ifndef _ASM_SPINLOCK_H
#define _ASM_SPINLOCK_H
-#include <linux/config.h>
#include <asm/war.h>
/*
* Your basic SMP spinlocks, allowing only a single CPU anywhere
*/
-#define __raw_spin_is_locked(x) ((x)->lock != 0)
+#define __raw_spin_is_locked(x) ((x)->lock != 0)
#define __raw_spin_lock_flags(lock, flags) __raw_spin_lock(lock)
#define __raw_spin_unlock_wait(x) \
- do { cpu_relax(); } while ((x)->lock)
+ do { cpu_relax(); } while ((x)->lock)
/*
* Simple spin lock operations. There are two variants, one clears IRQ's
@@ -119,6 +118,18 @@ static inline unsigned int __raw_spin_trylock(raw_spinlock_t *lock)
* read-locks.
*/
+/*
+ * read_can_lock - would read_trylock() succeed?
+ * @lock: the rwlock in question.
+ */
+#define __raw_read_can_lock(rw) ((rw)->lock >= 0)
+
+/*
+ * write_can_lock - would write_trylock() succeed?
+ * @lock: the rwlock in question.
+ */
+#define __raw_write_can_lock(rw) (!(rw)->lock)
+
static inline void __raw_read_lock(raw_rwlock_t *rw)
{
unsigned int tmp;
@@ -197,8 +208,7 @@ static inline void __raw_write_lock(raw_rwlock_t *rw)
" lui %1, 0x8000 \n"
" sc %1, %0 \n"
" beqzl %1, 1b \n"
- " nop \n"
- " sync \n"
+ " sync \n"
" .set reorder \n"
: "=m" (rw->lock), "=&r" (tmp)
: "m" (rw->lock)
@@ -211,8 +221,7 @@ static inline void __raw_write_lock(raw_rwlock_t *rw)
" lui %1, 0x8000 \n"
" sc %1, %0 \n"
" beqz %1, 1b \n"
- " nop \n"
- " sync \n"
+ " sync \n"
" .set reorder \n"
: "=m" (rw->lock), "=&r" (tmp)
: "m" (rw->lock)
@@ -246,8 +255,7 @@ static inline int __raw_write_trylock(raw_rwlock_t *rw)
" lui %1, 0x8000 \n"
" sc %1, %0 \n"
" beqzl %1, 1b \n"
- " nop \n"
- " sync \n"
+ " sync \n"
" li %2, 1 \n"
" .set reorder \n"
"2: \n"
diff --git a/include/asm-mips/stackframe.h b/include/asm-mips/stackframe.h
index 7b5e64600bc8..a8919dcc93c8 100644
--- a/include/asm-mips/stackframe.h
+++ b/include/asm-mips/stackframe.h
@@ -60,7 +60,6 @@
mfc0 k0, CP0_CONTEXT
lui k1, %hi(kernelsp)
srl k0, k0, 23
- sll k0, k0, 2
addu k1, k0
LONG_L k1, %lo(kernelsp)(k1)
#endif
@@ -76,9 +75,14 @@
#endif
#if defined(CONFIG_64BIT) && defined(CONFIG_BUILD_ELF64)
MFC0 k1, CP0_CONTEXT
+ lui k0, %highest(kernelsp)
dsrl k1, 23
- dsll k1, k1, 3
- LONG_L k1, kernelsp(k1)
+ daddiu k0, %higher(kernelsp)
+ dsll k0, k0, 16
+ daddiu k0, %hi(kernelsp)
+ dsll k0, k0, 16
+ daddu k1, k1, k0
+ LONG_L k1, %lo(kernelsp)(k1)
#endif
.endm
@@ -86,25 +90,28 @@
#ifdef CONFIG_32BIT
mfc0 \temp, CP0_CONTEXT
srl \temp, 23
- sll \temp, 2
- LONG_S \stackp, kernelsp(\temp)
#endif
#if defined(CONFIG_64BIT) && !defined(CONFIG_BUILD_ELF64)
lw \temp, TI_CPU(gp)
dsll \temp, 3
- lui \temp2, %hi(kernelsp)
- daddu \temp, \temp2
- LONG_S \stackp, %lo(kernelsp)(\temp)
#endif
#if defined(CONFIG_64BIT) && defined(CONFIG_BUILD_ELF64)
- lw \temp, TI_CPU(gp)
- dsll \temp, 3
- LONG_S \stackp, kernelsp(\temp)
+ MFC0 \temp, CP0_CONTEXT
+ dsrl \temp, 23
#endif
+ LONG_S \stackp, kernelsp(\temp)
.endm
#else
.macro get_saved_sp /* Uniprocessor variation */
+#if defined(CONFIG_64BIT) && defined(CONFIG_BUILD_ELF64)
+ lui k1, %highest(kernelsp)
+ daddiu k1, %higher(kernelsp)
+ dsll k1, k1, 16
+ daddiu k1, %hi(kernelsp)
+ dsll k1, k1, 16
+#else
lui k1, %hi(kernelsp)
+#endif
LONG_L k1, %lo(kernelsp)(k1)
.endm
diff --git a/include/asm-mips/system.h b/include/asm-mips/system.h
index 6663efd49b27..330c4e497af3 100644
--- a/include/asm-mips/system.h
+++ b/include/asm-mips/system.h
@@ -17,6 +17,7 @@
#include <asm/addrspace.h>
#include <asm/cpu-features.h>
+#include <asm/dsp.h>
#include <asm/ptrace.h>
#include <asm/war.h>
#include <asm/interrupt.h>
@@ -70,7 +71,7 @@
* does not enforce ordering, since there is no data dependency between
* the read of "a" and the read of "b". Therefore, on some CPUs, such
* as Alpha, "y" could be set to 3 and "x" to 0. Use rmb()
- * in cases like thiswhere there are no data dependencies.
+ * in cases like this where there are no data dependencies.
*/
#define read_barrier_depends() do { } while(0)
@@ -154,15 +155,15 @@ extern asmlinkage void *resume(void *last, void *next, void *next_ti);
struct task_struct;
-#define switch_to(prev,next,last) \
-do { \
- (last) = resume(prev, next, next->thread_info); \
+#define switch_to(prev,next,last) \
+do { \
+ if (cpu_has_dsp) \
+ __save_dsp(prev); \
+ (last) = resume(prev, next, next->thread_info); \
+ if (cpu_has_dsp) \
+ __restore_dsp(current); \
} while(0)
-#define ROT_IN_PIECES \
- " .set noreorder \n" \
- " .set reorder \n"
-
static inline unsigned long __xchg_u32(volatile int * m, unsigned int val)
{
__u32 retval;
@@ -171,14 +172,17 @@ static inline unsigned long __xchg_u32(volatile int * m, unsigned int val)
unsigned long dummy;
__asm__ __volatile__(
+ " .set mips3 \n"
"1: ll %0, %3 # xchg_u32 \n"
+ " .set mips0 \n"
" move %2, %z4 \n"
+ " .set mips3 \n"
" sc %2, %1 \n"
" beqzl %2, 1b \n"
- ROT_IN_PIECES
#ifdef CONFIG_SMP
" sync \n"
#endif
+ " .set mips0 \n"
: "=&r" (retval), "=m" (*m), "=&r" (dummy)
: "R" (*m), "Jr" (val)
: "memory");
@@ -186,13 +190,17 @@ static inline unsigned long __xchg_u32(volatile int * m, unsigned int val)
unsigned long dummy;
__asm__ __volatile__(
+ " .set mips3 \n"
"1: ll %0, %3 # xchg_u32 \n"
+ " .set mips0 \n"
" move %2, %z4 \n"
+ " .set mips3 \n"
" sc %2, %1 \n"
" beqz %2, 1b \n"
#ifdef CONFIG_SMP
" sync \n"
#endif
+ " .set mips0 \n"
: "=&r" (retval), "=m" (*m), "=&r" (dummy)
: "R" (*m), "Jr" (val)
: "memory");
@@ -217,14 +225,15 @@ static inline __u64 __xchg_u64(volatile __u64 * m, __u64 val)
unsigned long dummy;
__asm__ __volatile__(
+ " .set mips3 \n"
"1: lld %0, %3 # xchg_u64 \n"
" move %2, %z4 \n"
" scd %2, %1 \n"
" beqzl %2, 1b \n"
- ROT_IN_PIECES
#ifdef CONFIG_SMP
" sync \n"
#endif
+ " .set mips0 \n"
: "=&r" (retval), "=m" (*m), "=&r" (dummy)
: "R" (*m), "Jr" (val)
: "memory");
@@ -232,6 +241,7 @@ static inline __u64 __xchg_u64(volatile __u64 * m, __u64 val)
unsigned long dummy;
__asm__ __volatile__(
+ " .set mips3 \n"
"1: lld %0, %3 # xchg_u64 \n"
" move %2, %z4 \n"
" scd %2, %1 \n"
@@ -239,6 +249,7 @@ static inline __u64 __xchg_u64(volatile __u64 * m, __u64 val)
#ifdef CONFIG_SMP
" sync \n"
#endif
+ " .set mips0 \n"
: "=&r" (retval), "=m" (*m), "=&r" (dummy)
: "R" (*m), "Jr" (val)
: "memory");
@@ -286,34 +297,41 @@ static inline unsigned long __cmpxchg_u32(volatile int * m, unsigned long old,
if (cpu_has_llsc && R10000_LLSC_WAR) {
__asm__ __volatile__(
+ " .set push \n"
" .set noat \n"
+ " .set mips3 \n"
"1: ll %0, %2 # __cmpxchg_u32 \n"
" bne %0, %z3, 2f \n"
+ " .set mips0 \n"
" move $1, %z4 \n"
+ " .set mips3 \n"
" sc $1, %1 \n"
" beqzl $1, 1b \n"
- ROT_IN_PIECES
#ifdef CONFIG_SMP
" sync \n"
#endif
"2: \n"
- " .set at \n"
+ " .set pop \n"
: "=&r" (retval), "=m" (*m)
: "R" (*m), "Jr" (old), "Jr" (new)
: "memory");
} else if (cpu_has_llsc) {
__asm__ __volatile__(
+ " .set push \n"
" .set noat \n"
+ " .set mips3 \n"
"1: ll %0, %2 # __cmpxchg_u32 \n"
" bne %0, %z3, 2f \n"
+ " .set mips0 \n"
" move $1, %z4 \n"
+ " .set mips3 \n"
" sc $1, %1 \n"
" beqz $1, 1b \n"
#ifdef CONFIG_SMP
" sync \n"
#endif
"2: \n"
- " .set at \n"
+ " .set pop \n"
: "=&r" (retval), "=m" (*m)
: "R" (*m), "Jr" (old), "Jr" (new)
: "memory");
@@ -338,24 +356,27 @@ static inline unsigned long __cmpxchg_u64(volatile int * m, unsigned long old,
if (cpu_has_llsc) {
__asm__ __volatile__(
+ " .set push \n"
" .set noat \n"
+ " .set mips3 \n"
"1: lld %0, %2 # __cmpxchg_u64 \n"
" bne %0, %z3, 2f \n"
" move $1, %z4 \n"
" scd $1, %1 \n"
" beqzl $1, 1b \n"
- ROT_IN_PIECES
#ifdef CONFIG_SMP
" sync \n"
#endif
"2: \n"
- " .set at \n"
+ " .set pop \n"
: "=&r" (retval), "=m" (*m)
: "R" (*m), "Jr" (old), "Jr" (new)
: "memory");
} else if (cpu_has_llsc) {
__asm__ __volatile__(
+ " .set push \n"
" .set noat \n"
+ " .set mips3 \n"
"1: lld %0, %2 # __cmpxchg_u64 \n"
" bne %0, %z3, 2f \n"
" move $1, %z4 \n"
@@ -365,7 +386,7 @@ static inline unsigned long __cmpxchg_u64(volatile int * m, unsigned long old,
" sync \n"
#endif
"2: \n"
- " .set at \n"
+ " .set pop \n"
: "=&r" (retval), "=m" (*m)
: "R" (*m), "Jr" (old), "Jr" (new)
: "memory");
@@ -406,18 +427,20 @@ static inline unsigned long __cmpxchg(volatile void * ptr, unsigned long old,
#define cmpxchg(ptr,old,new) ((__typeof__(*(ptr)))__cmpxchg((ptr), (unsigned long)(old), (unsigned long)(new),sizeof(*(ptr))))
+extern void set_handler (unsigned long offset, void *addr, unsigned long len);
+extern void set_uncached_handler (unsigned long offset, void *addr, unsigned long len);
+extern void *set_vi_handler (int n, void *addr);
+extern void *set_vi_srs_handler (int n, void *addr, int regset);
extern void *set_except_vector(int n, void *addr);
extern void per_cpu_trap_init(void);
-extern NORET_TYPE void __die(const char *, struct pt_regs *, const char *file,
- const char *func, unsigned long line);
-extern void __die_if_kernel(const char *, struct pt_regs *, const char *file,
- const char *func, unsigned long line);
+extern NORET_TYPE void die(const char *, struct pt_regs *);
-#define die(msg, regs) \
- __die(msg, regs, __FILE__ ":", __FUNCTION__, __LINE__)
-#define die_if_kernel(msg, regs) \
- __die_if_kernel(msg, regs, __FILE__ ":", __FUNCTION__, __LINE__)
+static inline void die_if_kernel(const char *str, struct pt_regs *regs)
+{
+ if (unlikely(!user_mode(regs)))
+ die(str, regs);
+}
extern int stop_a_enabled;
diff --git a/include/asm-mips/thread_info.h b/include/asm-mips/thread_info.h
index a70cb0854c8a..e6c24472e03f 100644
--- a/include/asm-mips/thread_info.h
+++ b/include/asm-mips/thread_info.h
@@ -26,6 +26,7 @@ struct thread_info {
struct task_struct *task; /* main task structure */
struct exec_domain *exec_domain; /* execution domain */
unsigned long flags; /* low level flags */
+ unsigned long tp_value; /* thread pointer */
__u32 cpu; /* current CPU */
int preempt_count; /* 0 => preemptable, <0 => BUG */
@@ -114,6 +115,7 @@ register struct thread_info *__current_thread_info __asm__("$28");
#define TIF_SIGPENDING 2 /* signal pending */
#define TIF_NEED_RESCHED 3 /* rescheduling necessary */
#define TIF_SYSCALL_AUDIT 4 /* syscall auditing active */
+#define TIF_SECCOMP 5 /* 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 */
#define TIF_MEMDIE 18
@@ -124,13 +126,14 @@ register struct thread_info *__current_thread_info __asm__("$28");
#define _TIF_SIGPENDING (1<<TIF_SIGPENDING)
#define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED)
#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_WORK_MASK 0x0000ffef /* work to do on
- interrupt/exception return */
-#define _TIF_ALLWORK_MASK 0x8000ffff /* work to do on any return to
- u-space */
+/* work to do on interrupt/exception return */
+#define _TIF_WORK_MASK (0x0000ffef & ~_TIF_SECCOMP)
+/* work to do on any return to u-space */
+#define _TIF_ALLWORK_MASK (0x8000ffff & ~_TIF_SECCOMP)
#endif /* __KERNEL__ */
diff --git a/include/asm-mips/time.h b/include/asm-mips/time.h
index e22a20665871..9cc3564cc2c9 100644
--- a/include/asm-mips/time.h
+++ b/include/asm-mips/time.h
@@ -20,6 +20,9 @@
#include <linux/linkage.h>
#include <linux/ptrace.h>
#include <linux/rtc.h>
+#include <linux/spinlock.h>
+
+extern spinlock_t rtc_lock;
/*
* RTC ops. By default, they point to no-RTC functions.
diff --git a/include/asm-mips/traps.h b/include/asm-mips/traps.h
index 179012263007..d02e019b0127 100644
--- a/include/asm-mips/traps.h
+++ b/include/asm-mips/traps.h
@@ -21,4 +21,7 @@
extern void (*board_be_init)(void);
extern int (*board_be_handler)(struct pt_regs *regs, int is_fixup);
+extern void (*board_nmi_handler_setup)(void);
+extern void (*board_ejtag_handler_setup)(void);
+
#endif /* _ASM_TRAPS_H */
diff --git a/include/asm-mips/tx4938/rbtx4938.h b/include/asm-mips/tx4938/rbtx4938.h
new file mode 100644
index 000000000000..0fbedafdcea8
--- /dev/null
+++ b/include/asm-mips/tx4938/rbtx4938.h
@@ -0,0 +1,207 @@
+/*
+ * linux/include/asm-mips/tx4938/rbtx4938.h
+ * Definitions for TX4937/TX4938
+ *
+ * 2003-2005 (c) MontaVista Software, Inc. This file is licensed under the
+ * terms of the GNU General Public License version 2. This program is
+ * licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ *
+ * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com)
+ */
+#ifndef __ASM_TX_BOARDS_RBTX4938_H
+#define __ASM_TX_BOARDS_RBTX4938_H
+
+#include <asm/addrspace.h>
+#include <asm/tx4938/tx4938.h>
+
+/* CS */
+#define RBTX4938_CE0 0x1c000000 /* 64M */
+#define RBTX4938_CE2 0x17f00000 /* 1M */
+
+/* Address map */
+#define RBTX4938_FPGA_REG_ADDR (KSEG1 + RBTX4938_CE2 + 0x00000000)
+#define RBTX4938_FPGA_REV_ADDR (KSEG1 + RBTX4938_CE2 + 0x00000002)
+#define RBTX4938_CONFIG1_ADDR (KSEG1 + RBTX4938_CE2 + 0x00000004)
+#define RBTX4938_CONFIG2_ADDR (KSEG1 + RBTX4938_CE2 + 0x00000006)
+#define RBTX4938_CONFIG3_ADDR (KSEG1 + RBTX4938_CE2 + 0x00000008)
+#define RBTX4938_LED_ADDR (KSEG1 + RBTX4938_CE2 + 0x00001000)
+#define RBTX4938_DIPSW_ADDR (KSEG1 + RBTX4938_CE2 + 0x00001002)
+#define RBTX4938_BDIPSW_ADDR (KSEG1 + RBTX4938_CE2 + 0x00001004)
+#define RBTX4938_IMASK_ADDR (KSEG1 + RBTX4938_CE2 + 0x00002000)
+#define RBTX4938_IMASK2_ADDR (KSEG1 + RBTX4938_CE2 + 0x00002002)
+#define RBTX4938_INTPOL_ADDR (KSEG1 + RBTX4938_CE2 + 0x00002004)
+#define RBTX4938_ISTAT_ADDR (KSEG1 + RBTX4938_CE2 + 0x00002006)
+#define RBTX4938_ISTAT2_ADDR (KSEG1 + RBTX4938_CE2 + 0x00002008)
+#define RBTX4938_IMSTAT_ADDR (KSEG1 + RBTX4938_CE2 + 0x0000200a)
+#define RBTX4938_IMSTAT2_ADDR (KSEG1 + RBTX4938_CE2 + 0x0000200c)
+#define RBTX4938_SOFTINT_ADDR (KSEG1 + RBTX4938_CE2 + 0x00003000)
+#define RBTX4938_PIOSEL_ADDR (KSEG1 + RBTX4938_CE2 + 0x00005000)
+#define RBTX4938_SPICS_ADDR (KSEG1 + RBTX4938_CE2 + 0x00005002)
+#define RBTX4938_SFPWR_ADDR (KSEG1 + RBTX4938_CE2 + 0x00005008)
+#define RBTX4938_SFVOL_ADDR (KSEG1 + RBTX4938_CE2 + 0x0000500a)
+#define RBTX4938_SOFTRESET_ADDR (KSEG1 + RBTX4938_CE2 + 0x00007000)
+#define RBTX4938_SOFTRESETLOCK_ADDR (KSEG1 + RBTX4938_CE2 + 0x00007002)
+#define RBTX4938_PCIRESET_ADDR (KSEG1 + RBTX4938_CE2 + 0x00007004)
+#define RBTX4938_ETHER_BASE (KSEG1 + RBTX4938_CE2 + 0x00020000)
+
+/* Ethernet port address (Jumperless Mode (W12:Open)) */
+#define RBTX4938_ETHER_ADDR (RBTX4938_ETHER_BASE + 0x280)
+
+/* bits for ISTAT/IMASK/IMSTAT */
+#define RBTX4938_INTB_PCID 0
+#define RBTX4938_INTB_PCIC 1
+#define RBTX4938_INTB_PCIB 2
+#define RBTX4938_INTB_PCIA 3
+#define RBTX4938_INTB_RTC 4
+#define RBTX4938_INTB_ATA 5
+#define RBTX4938_INTB_MODEM 6
+#define RBTX4938_INTB_SWINT 7
+#define RBTX4938_INTF_PCID (1 << RBTX4938_INTB_PCID)
+#define RBTX4938_INTF_PCIC (1 << RBTX4938_INTB_PCIC)
+#define RBTX4938_INTF_PCIB (1 << RBTX4938_INTB_PCIB)
+#define RBTX4938_INTF_PCIA (1 << RBTX4938_INTB_PCIA)
+#define RBTX4938_INTF_RTC (1 << RBTX4938_INTB_RTC)
+#define RBTX4938_INTF_ATA (1 << RBTX4938_INTB_ATA)
+#define RBTX4938_INTF_MODEM (1 << RBTX4938_INTB_MODEM)
+#define RBTX4938_INTF_SWINT (1 << RBTX4938_INTB_SWINT)
+
+#define rbtx4938_fpga_rev_ptr \
+ ((volatile unsigned char *)RBTX4938_FPGA_REV_ADDR)
+#define rbtx4938_led_ptr \
+ ((volatile unsigned char *)RBTX4938_LED_ADDR)
+#define rbtx4938_dipsw_ptr \
+ ((volatile unsigned char *)RBTX4938_DIPSW_ADDR)
+#define rbtx4938_bdipsw_ptr \
+ ((volatile unsigned char *)RBTX4938_BDIPSW_ADDR)
+#define rbtx4938_imask_ptr \
+ ((volatile unsigned char *)RBTX4938_IMASK_ADDR)
+#define rbtx4938_imask2_ptr \
+ ((volatile unsigned char *)RBTX4938_IMASK2_ADDR)
+#define rbtx4938_intpol_ptr \
+ ((volatile unsigned char *)RBTX4938_INTPOL_ADDR)
+#define rbtx4938_istat_ptr \
+ ((volatile unsigned char *)RBTX4938_ISTAT_ADDR)
+#define rbtx4938_istat2_ptr \
+ ((volatile unsigned char *)RBTX4938_ISTAT2_ADDR)
+#define rbtx4938_imstat_ptr \
+ ((volatile unsigned char *)RBTX4938_IMSTAT_ADDR)
+#define rbtx4938_imstat2_ptr \
+ ((volatile unsigned char *)RBTX4938_IMSTAT2_ADDR)
+#define rbtx4938_softint_ptr \
+ ((volatile unsigned char *)RBTX4938_SOFTINT_ADDR)
+#define rbtx4938_piosel_ptr \
+ ((volatile unsigned char *)RBTX4938_PIOSEL_ADDR)
+#define rbtx4938_spics_ptr \
+ ((volatile unsigned char *)RBTX4938_SPICS_ADDR)
+#define rbtx4938_sfpwr_ptr \
+ ((volatile unsigned char *)RBTX4938_SFPWR_ADDR)
+#define rbtx4938_sfvol_ptr \
+ ((volatile unsigned char *)RBTX4938_SFVOL_ADDR)
+#define rbtx4938_softreset_ptr \
+ ((volatile unsigned char *)RBTX4938_SOFTRESET_ADDR)
+#define rbtx4938_softresetlock_ptr \
+ ((volatile unsigned char *)RBTX4938_SOFTRESETLOCK_ADDR)
+#define rbtx4938_pcireset_ptr \
+ ((volatile unsigned char *)RBTX4938_PCIRESET_ADDR)
+
+/* SPI */
+#define RBTX4938_SEEPROM1_CHIPID 0
+#define RBTX4938_SEEPROM2_CHIPID 1
+#define RBTX4938_SEEPROM3_CHIPID 2
+#define RBTX4938_SRTC_CHIPID 3
+
+/*
+ * IRQ mappings
+ */
+
+#define RBTX4938_SOFT_INT0 0 /* not used */
+#define RBTX4938_SOFT_INT1 1 /* not used */
+#define RBTX4938_IRC_INT 2
+#define RBTX4938_TIMER_INT 7
+
+/* These are the virtual IRQ numbers, we divide all IRQ's into
+ * 'spaces', the 'space' determines where and how to enable/disable
+ * that particular IRQ on an RBTX4938 machine. Add new 'spaces' as new
+ * IRQ hardware is supported.
+ */
+#define RBTX4938_NR_IRQ_LOCAL 8
+#define RBTX4938_NR_IRQ_IRC 32 /* On-Chip IRC */
+#define RBTX4938_NR_IRQ_IOC 8
+
+#define MI8259_IRQ_ISA_RAW_BEG 0 /* optional backplane i8259 */
+#define MI8259_IRQ_ISA_RAW_END 15
+#define TX4938_IRQ_CP0_RAW_BEG 0 /* tx4938 cpu built-in cp0 */
+#define TX4938_IRQ_CP0_RAW_END 7
+#define TX4938_IRQ_PIC_RAW_BEG 0 /* tx4938 cpu build-in pic */
+#define TX4938_IRQ_PIC_RAW_END 31
+
+#define MI8259_IRQ_ISA_BEG MI8259_IRQ_ISA_RAW_BEG /* 0 */
+#define MI8259_IRQ_ISA_END MI8259_IRQ_ISA_RAW_END /* 15 */
+
+#define TX4938_IRQ_CP0_BEG ((MI8259_IRQ_ISA_END+1)+TX4938_IRQ_CP0_RAW_BEG) /* 16 */
+#define TX4938_IRQ_CP0_END ((MI8259_IRQ_ISA_END+1)+TX4938_IRQ_CP0_RAW_END) /* 23 */
+
+#define TX4938_IRQ_PIC_BEG ((TX4938_IRQ_CP0_END+1)+TX4938_IRQ_PIC_RAW_BEG) /* 24 */
+#define TX4938_IRQ_PIC_END ((TX4938_IRQ_CP0_END+1)+TX4938_IRQ_PIC_RAW_END) /* 55 */
+#define TX4938_IRQ_NEST_EXT_ON_PIC (TX4938_IRQ_PIC_BEG+2)
+#define TX4938_IRQ_NEST_PIC_ON_CP0 (TX4938_IRQ_CP0_BEG+2)
+#define TX4938_IRQ_USER0 (TX4938_IRQ_CP0_BEG+0)
+#define TX4938_IRQ_USER1 (TX4938_IRQ_CP0_BEG+1)
+#define TX4938_IRQ_CPU_TIMER (TX4938_IRQ_CP0_BEG+7)
+
+#define TOSHIBA_RBTX4938_IRQ_IOC_RAW_BEG 0
+#define TOSHIBA_RBTX4938_IRQ_IOC_RAW_END 7
+
+#define TOSHIBA_RBTX4938_IRQ_IOC_BEG ((TX4938_IRQ_PIC_END+1)+TOSHIBA_RBTX4938_IRQ_IOC_RAW_BEG) /* 56 */
+#define TOSHIBA_RBTX4938_IRQ_IOC_END ((TX4938_IRQ_PIC_END+1)+TOSHIBA_RBTX4938_IRQ_IOC_RAW_END) /* 63 */
+#define RBTX4938_IRQ_LOCAL TX4938_IRQ_CP0_BEG
+#define RBTX4938_IRQ_IRC (RBTX4938_IRQ_LOCAL + RBTX4938_NR_IRQ_LOCAL)
+#define RBTX4938_IRQ_IOC (RBTX4938_IRQ_IRC + RBTX4938_NR_IRQ_IRC)
+#define RBTX4938_IRQ_END (RBTX4938_IRQ_IOC + RBTX4938_NR_IRQ_IOC)
+
+#define RBTX4938_IRQ_LOCAL_SOFT0 (RBTX4938_IRQ_LOCAL + RBTX4938_SOFT_INT0)
+#define RBTX4938_IRQ_LOCAL_SOFT1 (RBTX4938_IRQ_LOCAL + RBTX4938_SOFT_INT1)
+#define RBTX4938_IRQ_LOCAL_IRC (RBTX4938_IRQ_LOCAL + RBTX4938_IRC_INT)
+#define RBTX4938_IRQ_LOCAL_TIMER (RBTX4938_IRQ_LOCAL + RBTX4938_TIMER_INT)
+#define RBTX4938_IRQ_IRC_ECCERR (RBTX4938_IRQ_IRC + TX4938_IR_ECCERR)
+#define RBTX4938_IRQ_IRC_WTOERR (RBTX4938_IRQ_IRC + TX4938_IR_WTOERR)
+#define RBTX4938_IRQ_IRC_INT(n) (RBTX4938_IRQ_IRC + TX4938_IR_INT(n))
+#define RBTX4938_IRQ_IRC_SIO(n) (RBTX4938_IRQ_IRC + TX4938_IR_SIO(n))
+#define RBTX4938_IRQ_IRC_DMA(ch,n) (RBTX4938_IRQ_IRC + TX4938_IR_DMA(ch,n))
+#define RBTX4938_IRQ_IRC_PIO (RBTX4938_IRQ_IRC + TX4938_IR_PIO)
+#define RBTX4938_IRQ_IRC_PDMAC (RBTX4938_IRQ_IRC + TX4938_IR_PDMAC)
+#define RBTX4938_IRQ_IRC_PCIC (RBTX4938_IRQ_IRC + TX4938_IR_PCIC)
+#define RBTX4938_IRQ_IRC_TMR(n) (RBTX4938_IRQ_IRC + TX4938_IR_TMR(n))
+#define RBTX4938_IRQ_IRC_NDFMC (RBTX4938_IRQ_IRC + TX4938_IR_NDFMC)
+#define RBTX4938_IRQ_IRC_PCIERR (RBTX4938_IRQ_IRC + TX4938_IR_PCIERR)
+#define RBTX4938_IRQ_IRC_PCIPME (RBTX4938_IRQ_IRC + TX4938_IR_PCIPME)
+#define RBTX4938_IRQ_IRC_ACLC (RBTX4938_IRQ_IRC + TX4938_IR_ACLC)
+#define RBTX4938_IRQ_IRC_ACLCPME (RBTX4938_IRQ_IRC + TX4938_IR_ACLCPME)
+#define RBTX4938_IRQ_IRC_PCIC1 (RBTX4938_IRQ_IRC + TX4938_IR_PCIC1)
+#define RBTX4938_IRQ_IRC_SPI (RBTX4938_IRQ_IRC + TX4938_IR_SPI)
+#define RBTX4938_IRQ_IOC_PCID (RBTX4938_IRQ_IOC + RBTX4938_INTB_PCID)
+#define RBTX4938_IRQ_IOC_PCIC (RBTX4938_IRQ_IOC + RBTX4938_INTB_PCIC)
+#define RBTX4938_IRQ_IOC_PCIB (RBTX4938_IRQ_IOC + RBTX4938_INTB_PCIB)
+#define RBTX4938_IRQ_IOC_PCIA (RBTX4938_IRQ_IOC + RBTX4938_INTB_PCIA)
+#define RBTX4938_IRQ_IOC_RTC (RBTX4938_IRQ_IOC + RBTX4938_INTB_RTC)
+#define RBTX4938_IRQ_IOC_ATA (RBTX4938_IRQ_IOC + RBTX4938_INTB_ATA)
+#define RBTX4938_IRQ_IOC_MODEM (RBTX4938_IRQ_IOC + RBTX4938_INTB_MODEM)
+#define RBTX4938_IRQ_IOC_SWINT (RBTX4938_IRQ_IOC + RBTX4938_INTB_SWINT)
+
+
+/* IOC (PCI, etc) */
+#define RBTX4938_IRQ_IOCINT (TX4938_IRQ_NEST_EXT_ON_PIC)
+/* Onboard 10M Ether */
+#define RBTX4938_IRQ_ETHER (TX4938_IRQ_NEST_EXT_ON_PIC + 1)
+
+#define RBTX4938_RTL_8019_BASE (RBTX4938_ETHER_ADDR - mips_io_port_base)
+#define RBTX4938_RTL_8019_IRQ (RBTX4938_IRQ_ETHER)
+
+/* IRCR : Int. Control */
+#define TX4938_IRCR_LOW 0x00000000
+#define TX4938_IRCR_HIGH 0x00000001
+#define TX4938_IRCR_DOWN 0x00000002
+#define TX4938_IRCR_UP 0x00000003
+
+#endif /* __ASM_TX_BOARDS_RBTX4938_H */
diff --git a/include/asm-mips/tx4938/spi.h b/include/asm-mips/tx4938/spi.h
new file mode 100644
index 000000000000..0dbbab820a5a
--- /dev/null
+++ b/include/asm-mips/tx4938/spi.h
@@ -0,0 +1,74 @@
+/*
+ * linux/include/asm-mips/tx4938/spi.h
+ * Definitions for TX4937/TX4938 SPI
+ *
+ * Copyright (C) 2000-2001 Toshiba Corporation
+ *
+ * 2003-2005 (c) MontaVista Software, Inc. This file is licensed under the
+ * terms of the GNU General Public License version 2. This program is
+ * licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ *
+ * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com)
+ */
+#ifndef __ASM_TX_BOARDS_TX4938_SPI_H
+#define __ASM_TX_BOARDS_TX4938_SPI_H
+
+/* SPI */
+struct spi_dev_desc {
+ unsigned int baud;
+ unsigned short tcss, tcsh, tcsr; /* CS setup/hold/recovery time */
+ unsigned int byteorder:1; /* 0:LSB-First, 1:MSB-First */
+ unsigned int polarity:1; /* 0:High-Active */
+ unsigned int phase:1; /* 0:Sample-Then-Shift */
+};
+
+extern void txx9_spi_init(unsigned long base, int (*cs_func)(int chipid, int on)) __init;
+extern void txx9_spi_irqinit(int irc_irq) __init;
+extern int txx9_spi_io(int chipid, struct spi_dev_desc *desc,
+ unsigned char **inbufs, unsigned int *incounts,
+ unsigned char **outbufs, unsigned int *outcounts,
+ int cansleep);
+extern int spi_eeprom_write_enable(int chipid, int enable);
+extern int spi_eeprom_read_status(int chipid);
+extern int spi_eeprom_read(int chipid, int address, unsigned char *buf, int len);
+extern int spi_eeprom_write(int chipid, int address, unsigned char *buf, int len);
+extern void spi_eeprom_proc_create(struct proc_dir_entry *dir, int chipid) __init;
+
+#define TXX9_IMCLK (txx9_gbus_clock / 2)
+
+/*
+* SPI
+*/
+
+/* SPMCR : SPI Master Control */
+#define TXx9_SPMCR_OPMODE 0xc0
+#define TXx9_SPMCR_CONFIG 0x40
+#define TXx9_SPMCR_ACTIVE 0x80
+#define TXx9_SPMCR_SPSTP 0x02
+#define TXx9_SPMCR_BCLR 0x01
+
+/* SPCR0 : SPI Status */
+#define TXx9_SPCR0_TXIFL_MASK 0xc000
+#define TXx9_SPCR0_RXIFL_MASK 0x3000
+#define TXx9_SPCR0_SIDIE 0x0800
+#define TXx9_SPCR0_SOEIE 0x0400
+#define TXx9_SPCR0_RBSIE 0x0200
+#define TXx9_SPCR0_TBSIE 0x0100
+#define TXx9_SPCR0_IFSPSE 0x0010
+#define TXx9_SPCR0_SBOS 0x0004
+#define TXx9_SPCR0_SPHA 0x0002
+#define TXx9_SPCR0_SPOL 0x0001
+
+/* SPSR : SPI Status */
+#define TXx9_SPSR_TBSI 0x8000
+#define TXx9_SPSR_RBSI 0x4000
+#define TXx9_SPSR_TBS_MASK 0x3800
+#define TXx9_SPSR_RBS_MASK 0x0700
+#define TXx9_SPSR_SPOE 0x0080
+#define TXx9_SPSR_IFSD 0x0008
+#define TXx9_SPSR_SIDLE 0x0004
+#define TXx9_SPSR_STRDY 0x0002
+#define TXx9_SPSR_SRRDY 0x0001
+
+#endif /* __ASM_TX_BOARDS_TX4938_SPI_H */
diff --git a/include/asm-mips/tx4938/tx4938.h b/include/asm-mips/tx4938/tx4938.h
new file mode 100644
index 000000000000..e25b1a0975cb
--- /dev/null
+++ b/include/asm-mips/tx4938/tx4938.h
@@ -0,0 +1,706 @@
+/*
+ * linux/include/asm-mips/tx4938/tx4938.h
+ * Definitions for TX4937/TX4938
+ * Copyright (C) 2000-2001 Toshiba Corporation
+ *
+ * 2003-2005 (c) MontaVista Software, Inc. This file is licensed under the
+ * terms of the GNU General Public License version 2. This program is
+ * licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ *
+ * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com)
+ */
+#ifndef __ASM_TX_BOARDS_TX4938_H
+#define __ASM_TX_BOARDS_TX4938_H
+
+#include <asm/tx4938/tx4938_mips.h>
+
+#define tx4938_read_nfmc(addr) (*(volatile unsigned int *)(addr))
+#define tx4938_write_nfmc(b,addr) (*(volatile unsigned int *)(addr)) = (b)
+
+#define TX4938_NR_IRQ_LOCAL TX4938_IRQ_PIC_BEG
+
+#define TX4938_IRQ_IRC_PCIC (TX4938_NR_IRQ_LOCAL + TX4938_IR_PCIC)
+#define TX4938_IRQ_IRC_PCIERR (TX4938_NR_IRQ_LOCAL + TX4938_IR_PCIERR)
+
+#define TX4938_PCIIO_0 0x10000000
+#define TX4938_PCIIO_1 0x01010000
+#define TX4938_PCIMEM_0 0x08000000
+#define TX4938_PCIMEM_1 0x11000000
+
+#define TX4938_PCIIO_SIZE_0 0x01000000
+#define TX4938_PCIIO_SIZE_1 0x00010000
+#define TX4938_PCIMEM_SIZE_0 0x08000000
+#define TX4938_PCIMEM_SIZE_1 0x00010000
+
+#define TX4938_REG_BASE 0xff1f0000 /* == TX4937_REG_BASE */
+#define TX4938_REG_SIZE 0x00010000 /* == TX4937_REG_SIZE */
+
+/* NDFMC, SRAMC, PCIC1, SPIC: TX4938 only */
+#define TX4938_NDFMC_REG (TX4938_REG_BASE + 0x5000)
+#define TX4938_SRAMC_REG (TX4938_REG_BASE + 0x6000)
+#define TX4938_PCIC1_REG (TX4938_REG_BASE + 0x7000)
+#define TX4938_SDRAMC_REG (TX4938_REG_BASE + 0x8000)
+#define TX4938_EBUSC_REG (TX4938_REG_BASE + 0x9000)
+#define TX4938_DMA_REG(ch) (TX4938_REG_BASE + 0xb000 + (ch) * 0x800)
+#define TX4938_PCIC_REG (TX4938_REG_BASE + 0xd000)
+#define TX4938_CCFG_REG (TX4938_REG_BASE + 0xe000)
+#define TX4938_NR_TMR 3
+#define TX4938_TMR_REG(ch) ((TX4938_REG_BASE + 0xf000) + (ch) * 0x100)
+#define TX4938_NR_SIO 2
+#define TX4938_SIO_REG(ch) ((TX4938_REG_BASE + 0xf300) + (ch) * 0x100)
+#define TX4938_PIO_REG (TX4938_REG_BASE + 0xf500)
+#define TX4938_IRC_REG (TX4938_REG_BASE + 0xf600)
+#define TX4938_ACLC_REG (TX4938_REG_BASE + 0xf700)
+#define TX4938_SPI_REG (TX4938_REG_BASE + 0xf800)
+
+#ifndef _LANGUAGE_ASSEMBLY
+#include <asm/byteorder.h>
+
+#define TX4938_MKA(x) ((u32)( ((u32)(TX4938_REG_BASE)) | ((u32)(x)) ))
+
+#define TX4938_RD08( reg ) (*(vu08*)(reg))
+#define TX4938_WR08( reg, val ) ((*(vu08*)(reg))=(val))
+
+#define TX4938_RD16( reg ) (*(vu16*)(reg))
+#define TX4938_WR16( reg, val ) ((*(vu16*)(reg))=(val))
+
+#define TX4938_RD32( reg ) (*(vu32*)(reg))
+#define TX4938_WR32( reg, val ) ((*(vu32*)(reg))=(val))
+
+#define TX4938_RD64( reg ) (*(vu64*)(reg))
+#define TX4938_WR64( reg, val ) ((*(vu64*)(reg))=(val))
+
+#define TX4938_RD( reg ) TX4938_RD32( reg )
+#define TX4938_WR( reg, val ) TX4938_WR32( reg, val )
+
+#endif /* !__ASSEMBLY__ */
+
+#ifdef __ASSEMBLY__
+#define _CONST64(c) c
+#else
+#define _CONST64(c) c##ull
+
+#include <asm/byteorder.h>
+
+#ifdef __BIG_ENDIAN
+#define endian_def_l2(e1,e2) \
+ volatile unsigned long e1,e2
+#define endian_def_s2(e1,e2) \
+ volatile unsigned short e1,e2
+#define endian_def_sb2(e1,e2,e3) \
+ volatile unsigned short e1;volatile unsigned char e2,e3
+#define endian_def_b2s(e1,e2,e3) \
+ volatile unsigned char e1,e2;volatile unsigned short e3
+#define endian_def_b4(e1,e2,e3,e4) \
+ volatile unsigned char e1,e2,e3,e4
+#else
+#define endian_def_l2(e1,e2) \
+ volatile unsigned long e2,e1
+#define endian_def_s2(e1,e2) \
+ volatile unsigned short e2,e1
+#define endian_def_sb2(e1,e2,e3) \
+ volatile unsigned char e3,e2;volatile unsigned short e1
+#define endian_def_b2s(e1,e2,e3) \
+ volatile unsigned short e3;volatile unsigned char e2,e1
+#define endian_def_b4(e1,e2,e3,e4) \
+ volatile unsigned char e4,e3,e2,e1
+#endif
+
+
+struct tx4938_sdramc_reg {
+ volatile unsigned long long cr[4];
+ volatile unsigned long long unused0[4];
+ volatile unsigned long long tr;
+ volatile unsigned long long unused1[2];
+ volatile unsigned long long cmd;
+ volatile unsigned long long sfcmd;
+};
+
+struct tx4938_ebusc_reg {
+ volatile unsigned long long cr[8];
+};
+
+struct tx4938_dma_reg {
+ struct tx4938_dma_ch_reg {
+ volatile unsigned long long cha;
+ volatile unsigned long long sar;
+ volatile unsigned long long dar;
+ endian_def_l2(unused0, cntr);
+ endian_def_l2(unused1, sair);
+ endian_def_l2(unused2, dair);
+ endian_def_l2(unused3, ccr);
+ endian_def_l2(unused4, csr);
+ } ch[4];
+ volatile unsigned long long dbr[8];
+ volatile unsigned long long tdhr;
+ volatile unsigned long long midr;
+ endian_def_l2(unused0, mcr);
+};
+
+struct tx4938_pcic_reg {
+ volatile unsigned long pciid;
+ volatile unsigned long pcistatus;
+ volatile unsigned long pciccrev;
+ volatile unsigned long pcicfg1;
+ volatile unsigned long p2gm0plbase; /* +10 */
+ volatile unsigned long p2gm0pubase;
+ volatile unsigned long p2gm1plbase;
+ volatile unsigned long p2gm1pubase;
+ volatile unsigned long p2gm2pbase; /* +20 */
+ volatile unsigned long p2giopbase;
+ volatile unsigned long unused0;
+ volatile unsigned long pcisid;
+ volatile unsigned long unused1; /* +30 */
+ volatile unsigned long pcicapptr;
+ volatile unsigned long unused2;
+ volatile unsigned long pcicfg2;
+ volatile unsigned long g2ptocnt; /* +40 */
+ volatile unsigned long unused3[15];
+ volatile unsigned long g2pstatus; /* +80 */
+ volatile unsigned long g2pmask;
+ volatile unsigned long pcisstatus;
+ volatile unsigned long pcimask;
+ volatile unsigned long p2gcfg; /* +90 */
+ volatile unsigned long p2gstatus;
+ volatile unsigned long p2gmask;
+ volatile unsigned long p2gccmd;
+ volatile unsigned long unused4[24]; /* +a0 */
+ volatile unsigned long pbareqport; /* +100 */
+ volatile unsigned long pbacfg;
+ volatile unsigned long pbastatus;
+ volatile unsigned long pbamask;
+ volatile unsigned long pbabm; /* +110 */
+ volatile unsigned long pbacreq;
+ volatile unsigned long pbacgnt;
+ volatile unsigned long pbacstate;
+ volatile unsigned long long g2pmgbase[3]; /* +120 */
+ volatile unsigned long long g2piogbase;
+ volatile unsigned long g2pmmask[3]; /* +140 */
+ volatile unsigned long g2piomask;
+ volatile unsigned long long g2pmpbase[3]; /* +150 */
+ volatile unsigned long long g2piopbase;
+ volatile unsigned long pciccfg; /* +170 */
+ volatile unsigned long pcicstatus;
+ volatile unsigned long pcicmask;
+ volatile unsigned long unused5;
+ volatile unsigned long long p2gmgbase[3]; /* +180 */
+ volatile unsigned long long p2giogbase;
+ volatile unsigned long g2pcfgadrs; /* +1a0 */
+ volatile unsigned long g2pcfgdata;
+ volatile unsigned long unused6[8];
+ volatile unsigned long g2pintack;
+ volatile unsigned long g2pspc;
+ volatile unsigned long unused7[12]; /* +1d0 */
+ volatile unsigned long long pdmca; /* +200 */
+ volatile unsigned long long pdmga;
+ volatile unsigned long long pdmpa;
+ volatile unsigned long long pdmctr;
+ volatile unsigned long long pdmcfg; /* +220 */
+ volatile unsigned long long pdmsts;
+};
+
+struct tx4938_aclc_reg {
+ volatile unsigned long acctlen;
+ volatile unsigned long acctldis;
+ volatile unsigned long acregacc;
+ volatile unsigned long unused0;
+ volatile unsigned long acintsts;
+ volatile unsigned long acintmsts;
+ volatile unsigned long acinten;
+ volatile unsigned long acintdis;
+ volatile unsigned long acsemaph;
+ volatile unsigned long unused1[7];
+ volatile unsigned long acgpidat;
+ volatile unsigned long acgpodat;
+ volatile unsigned long acslten;
+ volatile unsigned long acsltdis;
+ volatile unsigned long acfifosts;
+ volatile unsigned long unused2[11];
+ volatile unsigned long acdmasts;
+ volatile unsigned long acdmasel;
+ volatile unsigned long unused3[6];
+ volatile unsigned long acaudodat;
+ volatile unsigned long acsurrdat;
+ volatile unsigned long accentdat;
+ volatile unsigned long aclfedat;
+ volatile unsigned long acaudiat;
+ volatile unsigned long unused4;
+ volatile unsigned long acmodoat;
+ volatile unsigned long acmodidat;
+ volatile unsigned long unused5[15];
+ volatile unsigned long acrevid;
+};
+
+
+struct tx4938_tmr_reg {
+ volatile unsigned long tcr;
+ volatile unsigned long tisr;
+ volatile unsigned long cpra;
+ volatile unsigned long cprb;
+ volatile unsigned long itmr;
+ volatile unsigned long unused0[3];
+ volatile unsigned long ccdr;
+ volatile unsigned long unused1[3];
+ volatile unsigned long pgmr;
+ volatile unsigned long unused2[3];
+ volatile unsigned long wtmr;
+ volatile unsigned long unused3[43];
+ volatile unsigned long trr;
+};
+
+struct tx4938_sio_reg {
+ volatile unsigned long lcr;
+ volatile unsigned long dicr;
+ volatile unsigned long disr;
+ volatile unsigned long cisr;
+ volatile unsigned long fcr;
+ volatile unsigned long flcr;
+ volatile unsigned long bgr;
+ volatile unsigned long tfifo;
+ volatile unsigned long rfifo;
+};
+
+struct tx4938_pio_reg {
+ volatile unsigned long dout;
+ volatile unsigned long din;
+ volatile unsigned long dir;
+ volatile unsigned long od;
+ volatile unsigned long flag[2];
+ volatile unsigned long pol;
+ volatile unsigned long intc;
+ volatile unsigned long maskcpu;
+ volatile unsigned long maskext;
+};
+struct tx4938_irc_reg {
+ volatile unsigned long cer;
+ volatile unsigned long cr[2];
+ volatile unsigned long unused0;
+ volatile unsigned long ilr[8];
+ volatile unsigned long unused1[4];
+ volatile unsigned long imr;
+ volatile unsigned long unused2[7];
+ volatile unsigned long scr;
+ volatile unsigned long unused3[7];
+ volatile unsigned long ssr;
+ volatile unsigned long unused4[7];
+ volatile unsigned long csr;
+};
+
+struct tx4938_ndfmc_reg {
+ endian_def_l2(unused0, dtr);
+ endian_def_l2(unused1, mcr);
+ endian_def_l2(unused2, sr);
+ endian_def_l2(unused3, isr);
+ endian_def_l2(unused4, imr);
+ endian_def_l2(unused5, spr);
+ endian_def_l2(unused6, rstr);
+};
+
+struct tx4938_spi_reg {
+ volatile unsigned long mcr;
+ volatile unsigned long cr0;
+ volatile unsigned long cr1;
+ volatile unsigned long fs;
+ volatile unsigned long unused1;
+ volatile unsigned long sr;
+ volatile unsigned long dr;
+ volatile unsigned long unused2;
+};
+
+struct tx4938_sramc_reg {
+ volatile unsigned long long cr;
+};
+
+struct tx4938_ccfg_reg {
+ volatile unsigned long long ccfg;
+ volatile unsigned long long crir;
+ volatile unsigned long long pcfg;
+ volatile unsigned long long tear;
+ volatile unsigned long long clkctr;
+ volatile unsigned long long unused0;
+ volatile unsigned long long garbc;
+ volatile unsigned long long unused1;
+ volatile unsigned long long unused2;
+ volatile unsigned long long ramp;
+ volatile unsigned long long unused3;
+ volatile unsigned long long jmpadr;
+};
+
+#undef endian_def_l2
+#undef endian_def_s2
+#undef endian_def_sb2
+#undef endian_def_b2s
+#undef endian_def_b4
+
+#endif /* __ASSEMBLY__ */
+
+/*
+ * NDFMC
+ */
+
+/* NDFMCR : NDFMC Mode Control */
+#define TX4938_NDFMCR_WE 0x80
+#define TX4938_NDFMCR_ECC_ALL 0x60
+#define TX4938_NDFMCR_ECC_RESET 0x60
+#define TX4938_NDFMCR_ECC_READ 0x40
+#define TX4938_NDFMCR_ECC_ON 0x20
+#define TX4938_NDFMCR_ECC_OFF 0x00
+#define TX4938_NDFMCR_CE 0x10
+#define TX4938_NDFMCR_BSPRT 0x04
+#define TX4938_NDFMCR_ALE 0x02
+#define TX4938_NDFMCR_CLE 0x01
+
+/* NDFMCR : NDFMC Status */
+#define TX4938_NDFSR_BUSY 0x80
+
+/* NDFMCR : NDFMC Reset */
+#define TX4938_NDFRSTR_RST 0x01
+
+/*
+ * IRC
+ */
+
+#define TX4938_IR_ECCERR 0
+#define TX4938_IR_WTOERR 1
+#define TX4938_NUM_IR_INT 6
+#define TX4938_IR_INT(n) (2 + (n))
+#define TX4938_NUM_IR_SIO 2
+#define TX4938_IR_SIO(n) (8 + (n))
+#define TX4938_NUM_IR_DMA 4
+#define TX4938_IR_DMA(ch,n) ((ch ? 27 : 10) + (n)) /* 10-13,27-30 */
+#define TX4938_IR_PIO 14
+#define TX4938_IR_PDMAC 15
+#define TX4938_IR_PCIC 16
+#define TX4938_NUM_IR_TMR 3
+#define TX4938_IR_TMR(n) (17 + (n))
+#define TX4938_IR_NDFMC 21
+#define TX4938_IR_PCIERR 22
+#define TX4938_IR_PCIPME 23
+#define TX4938_IR_ACLC 24
+#define TX4938_IR_ACLCPME 25
+#define TX4938_IR_PCIC1 26
+#define TX4938_IR_SPI 31
+#define TX4938_NUM_IR 32
+/* multiplex */
+#define TX4938_IR_ETH0 TX4938_IR_INT(4)
+#define TX4938_IR_ETH1 TX4938_IR_INT(3)
+
+/*
+ * CCFG
+ */
+/* CCFG : Chip Configuration */
+#define TX4938_CCFG_WDRST _CONST64(0x0000020000000000)
+#define TX4938_CCFG_WDREXEN _CONST64(0x0000010000000000)
+#define TX4938_CCFG_BCFG_MASK _CONST64(0x000000ff00000000)
+#define TX4938_CCFG_TINTDIS 0x01000000
+#define TX4938_CCFG_PCI66 0x00800000
+#define TX4938_CCFG_PCIMODE 0x00400000
+#define TX4938_CCFG_PCI1_66 0x00200000
+#define TX4938_CCFG_DIVMODE_MASK 0x001e0000
+#define TX4938_CCFG_DIVMODE_2 (0x4 << 17)
+#define TX4938_CCFG_DIVMODE_2_5 (0xf << 17)
+#define TX4938_CCFG_DIVMODE_3 (0x5 << 17)
+#define TX4938_CCFG_DIVMODE_4 (0x6 << 17)
+#define TX4938_CCFG_DIVMODE_4_5 (0xd << 17)
+#define TX4938_CCFG_DIVMODE_8 (0x0 << 17)
+#define TX4938_CCFG_DIVMODE_10 (0xb << 17)
+#define TX4938_CCFG_DIVMODE_12 (0x1 << 17)
+#define TX4938_CCFG_DIVMODE_16 (0x2 << 17)
+#define TX4938_CCFG_DIVMODE_18 (0x9 << 17)
+#define TX4938_CCFG_BEOW 0x00010000
+#define TX4938_CCFG_WR 0x00008000
+#define TX4938_CCFG_TOE 0x00004000
+#define TX4938_CCFG_PCIXARB 0x00002000
+#define TX4938_CCFG_PCIDIVMODE_MASK 0x00001c00
+#define TX4938_CCFG_PCIDIVMODE_4 (0x1 << 10)
+#define TX4938_CCFG_PCIDIVMODE_4_5 (0x3 << 10)
+#define TX4938_CCFG_PCIDIVMODE_5 (0x5 << 10)
+#define TX4938_CCFG_PCIDIVMODE_5_5 (0x7 << 10)
+#define TX4938_CCFG_PCIDIVMODE_8 (0x0 << 10)
+#define TX4938_CCFG_PCIDIVMODE_9 (0x2 << 10)
+#define TX4938_CCFG_PCIDIVMODE_10 (0x4 << 10)
+#define TX4938_CCFG_PCIDIVMODE_11 (0x6 << 10)
+#define TX4938_CCFG_PCI1DMD 0x00000100
+#define TX4938_CCFG_SYSSP_MASK 0x000000c0
+#define TX4938_CCFG_ENDIAN 0x00000004
+#define TX4938_CCFG_HALT 0x00000002
+#define TX4938_CCFG_ACEHOLD 0x00000001
+
+/* PCFG : Pin Configuration */
+#define TX4938_PCFG_ETH0_SEL _CONST64(0x8000000000000000)
+#define TX4938_PCFG_ETH1_SEL _CONST64(0x4000000000000000)
+#define TX4938_PCFG_ATA_SEL _CONST64(0x2000000000000000)
+#define TX4938_PCFG_ISA_SEL _CONST64(0x1000000000000000)
+#define TX4938_PCFG_SPI_SEL _CONST64(0x0800000000000000)
+#define TX4938_PCFG_NDF_SEL _CONST64(0x0400000000000000)
+#define TX4938_PCFG_SDCLKDLY_MASK 0x30000000
+#define TX4938_PCFG_SDCLKDLY(d) ((d)<<28)
+#define TX4938_PCFG_SYSCLKEN 0x08000000
+#define TX4938_PCFG_SDCLKEN_ALL 0x07800000
+#define TX4938_PCFG_SDCLKEN(ch) (0x00800000<<(ch))
+#define TX4938_PCFG_PCICLKEN_ALL 0x003f0000
+#define TX4938_PCFG_PCICLKEN(ch) (0x00010000<<(ch))
+#define TX4938_PCFG_SEL2 0x00000200
+#define TX4938_PCFG_SEL1 0x00000100
+#define TX4938_PCFG_DMASEL_ALL 0x0000000f
+#define TX4938_PCFG_DMASEL0_DRQ0 0x00000000
+#define TX4938_PCFG_DMASEL0_SIO1 0x00000001
+#define TX4938_PCFG_DMASEL1_DRQ1 0x00000000
+#define TX4938_PCFG_DMASEL1_SIO1 0x00000002
+#define TX4938_PCFG_DMASEL2_DRQ2 0x00000000
+#define TX4938_PCFG_DMASEL2_SIO0 0x00000004
+#define TX4938_PCFG_DMASEL3_DRQ3 0x00000000
+#define TX4938_PCFG_DMASEL3_SIO0 0x00000008
+
+/* CLKCTR : Clock Control */
+#define TX4938_CLKCTR_NDFCKD _CONST64(0x0001000000000000)
+#define TX4938_CLKCTR_NDFRST _CONST64(0x0000000100000000)
+#define TX4938_CLKCTR_ETH1CKD 0x80000000
+#define TX4938_CLKCTR_ETH0CKD 0x40000000
+#define TX4938_CLKCTR_SPICKD 0x20000000
+#define TX4938_CLKCTR_SRAMCKD 0x10000000
+#define TX4938_CLKCTR_PCIC1CKD 0x08000000
+#define TX4938_CLKCTR_DMA1CKD 0x04000000
+#define TX4938_CLKCTR_ACLCKD 0x02000000
+#define TX4938_CLKCTR_PIOCKD 0x01000000
+#define TX4938_CLKCTR_DMACKD 0x00800000
+#define TX4938_CLKCTR_PCICKD 0x00400000
+#define TX4938_CLKCTR_TM0CKD 0x00100000
+#define TX4938_CLKCTR_TM1CKD 0x00080000
+#define TX4938_CLKCTR_TM2CKD 0x00040000
+#define TX4938_CLKCTR_SIO0CKD 0x00020000
+#define TX4938_CLKCTR_SIO1CKD 0x00010000
+#define TX4938_CLKCTR_ETH1RST 0x00008000
+#define TX4938_CLKCTR_ETH0RST 0x00004000
+#define TX4938_CLKCTR_SPIRST 0x00002000
+#define TX4938_CLKCTR_SRAMRST 0x00001000
+#define TX4938_CLKCTR_PCIC1RST 0x00000800
+#define TX4938_CLKCTR_DMA1RST 0x00000400
+#define TX4938_CLKCTR_ACLRST 0x00000200
+#define TX4938_CLKCTR_PIORST 0x00000100
+#define TX4938_CLKCTR_DMARST 0x00000080
+#define TX4938_CLKCTR_PCIRST 0x00000040
+#define TX4938_CLKCTR_TM0RST 0x00000010
+#define TX4938_CLKCTR_TM1RST 0x00000008
+#define TX4938_CLKCTR_TM2RST 0x00000004
+#define TX4938_CLKCTR_SIO0RST 0x00000002
+#define TX4938_CLKCTR_SIO1RST 0x00000001
+
+/* bits for G2PSTATUS/G2PMASK */
+#define TX4938_PCIC_G2PSTATUS_ALL 0x00000003
+#define TX4938_PCIC_G2PSTATUS_TTOE 0x00000002
+#define TX4938_PCIC_G2PSTATUS_RTOE 0x00000001
+
+/* bits for PCIMASK (see also PCI_STATUS_XXX in linux/pci.h */
+#define TX4938_PCIC_PCISTATUS_ALL 0x0000f900
+
+/* bits for PBACFG */
+#define TX4938_PCIC_PBACFG_FIXPA 0x00000008
+#define TX4938_PCIC_PBACFG_RPBA 0x00000004
+#define TX4938_PCIC_PBACFG_PBAEN 0x00000002
+#define TX4938_PCIC_PBACFG_BMCEN 0x00000001
+
+/* bits for G2PMnGBASE */
+#define TX4938_PCIC_G2PMnGBASE_BSDIS _CONST64(0x0000002000000000)
+#define TX4938_PCIC_G2PMnGBASE_ECHG _CONST64(0x0000001000000000)
+
+/* bits for G2PIOGBASE */
+#define TX4938_PCIC_G2PIOGBASE_BSDIS _CONST64(0x0000002000000000)
+#define TX4938_PCIC_G2PIOGBASE_ECHG _CONST64(0x0000001000000000)
+
+/* bits for PCICSTATUS/PCICMASK */
+#define TX4938_PCIC_PCICSTATUS_ALL 0x000007b8
+#define TX4938_PCIC_PCICSTATUS_PME 0x00000400
+#define TX4938_PCIC_PCICSTATUS_TLB 0x00000200
+#define TX4938_PCIC_PCICSTATUS_NIB 0x00000100
+#define TX4938_PCIC_PCICSTATUS_ZIB 0x00000080
+#define TX4938_PCIC_PCICSTATUS_PERR 0x00000020
+#define TX4938_PCIC_PCICSTATUS_SERR 0x00000010
+#define TX4938_PCIC_PCICSTATUS_GBE 0x00000008
+#define TX4938_PCIC_PCICSTATUS_IWB 0x00000002
+#define TX4938_PCIC_PCICSTATUS_E2PDONE 0x00000001
+
+/* bits for PCICCFG */
+#define TX4938_PCIC_PCICCFG_GBWC_MASK 0x0fff0000
+#define TX4938_PCIC_PCICCFG_HRST 0x00000800
+#define TX4938_PCIC_PCICCFG_SRST 0x00000400
+#define TX4938_PCIC_PCICCFG_IRBER 0x00000200
+#define TX4938_PCIC_PCICCFG_G2PMEN(ch) (0x00000100>>(ch))
+#define TX4938_PCIC_PCICCFG_G2PM0EN 0x00000100
+#define TX4938_PCIC_PCICCFG_G2PM1EN 0x00000080
+#define TX4938_PCIC_PCICCFG_G2PM2EN 0x00000040
+#define TX4938_PCIC_PCICCFG_G2PIOEN 0x00000020
+#define TX4938_PCIC_PCICCFG_TCAR 0x00000010
+#define TX4938_PCIC_PCICCFG_ICAEN 0x00000008
+
+/* bits for P2GMnGBASE */
+#define TX4938_PCIC_P2GMnGBASE_TMEMEN _CONST64(0x0000004000000000)
+#define TX4938_PCIC_P2GMnGBASE_TBSDIS _CONST64(0x0000002000000000)
+#define TX4938_PCIC_P2GMnGBASE_TECHG _CONST64(0x0000001000000000)
+
+/* bits for P2GIOGBASE */
+#define TX4938_PCIC_P2GIOGBASE_TIOEN _CONST64(0x0000004000000000)
+#define TX4938_PCIC_P2GIOGBASE_TBSDIS _CONST64(0x0000002000000000)
+#define TX4938_PCIC_P2GIOGBASE_TECHG _CONST64(0x0000001000000000)
+
+#define TX4938_PCIC_IDSEL_AD_TO_SLOT(ad) ((ad) - 11)
+#define TX4938_PCIC_MAX_DEVNU TX4938_PCIC_IDSEL_AD_TO_SLOT(32)
+
+/* bits for PDMCFG */
+#define TX4938_PCIC_PDMCFG_RSTFIFO 0x00200000
+#define TX4938_PCIC_PDMCFG_EXFER 0x00100000
+#define TX4938_PCIC_PDMCFG_REQDLY_MASK 0x00003800
+#define TX4938_PCIC_PDMCFG_REQDLY_NONE (0 << 11)
+#define TX4938_PCIC_PDMCFG_REQDLY_16 (1 << 11)
+#define TX4938_PCIC_PDMCFG_REQDLY_32 (2 << 11)
+#define TX4938_PCIC_PDMCFG_REQDLY_64 (3 << 11)
+#define TX4938_PCIC_PDMCFG_REQDLY_128 (4 << 11)
+#define TX4938_PCIC_PDMCFG_REQDLY_256 (5 << 11)
+#define TX4938_PCIC_PDMCFG_REQDLY_512 (6 << 11)
+#define TX4938_PCIC_PDMCFG_REQDLY_1024 (7 << 11)
+#define TX4938_PCIC_PDMCFG_ERRIE 0x00000400
+#define TX4938_PCIC_PDMCFG_NCCMPIE 0x00000200
+#define TX4938_PCIC_PDMCFG_NTCMPIE 0x00000100
+#define TX4938_PCIC_PDMCFG_CHNEN 0x00000080
+#define TX4938_PCIC_PDMCFG_XFRACT 0x00000040
+#define TX4938_PCIC_PDMCFG_BSWAP 0x00000020
+#define TX4938_PCIC_PDMCFG_XFRSIZE_MASK 0x0000000c
+#define TX4938_PCIC_PDMCFG_XFRSIZE_1DW 0x00000000
+#define TX4938_PCIC_PDMCFG_XFRSIZE_1QW 0x00000004
+#define TX4938_PCIC_PDMCFG_XFRSIZE_4QW 0x00000008
+#define TX4938_PCIC_PDMCFG_XFRDIRC 0x00000002
+#define TX4938_PCIC_PDMCFG_CHRST 0x00000001
+
+/* bits for PDMSTS */
+#define TX4938_PCIC_PDMSTS_REQCNT_MASK 0x3f000000
+#define TX4938_PCIC_PDMSTS_FIFOCNT_MASK 0x00f00000
+#define TX4938_PCIC_PDMSTS_FIFOWP_MASK 0x000c0000
+#define TX4938_PCIC_PDMSTS_FIFORP_MASK 0x00030000
+#define TX4938_PCIC_PDMSTS_ERRINT 0x00000800
+#define TX4938_PCIC_PDMSTS_DONEINT 0x00000400
+#define TX4938_PCIC_PDMSTS_CHNEN 0x00000200
+#define TX4938_PCIC_PDMSTS_XFRACT 0x00000100
+#define TX4938_PCIC_PDMSTS_ACCMP 0x00000080
+#define TX4938_PCIC_PDMSTS_NCCMP 0x00000040
+#define TX4938_PCIC_PDMSTS_NTCMP 0x00000020
+#define TX4938_PCIC_PDMSTS_CFGERR 0x00000008
+#define TX4938_PCIC_PDMSTS_PCIERR 0x00000004
+#define TX4938_PCIC_PDMSTS_CHNERR 0x00000002
+#define TX4938_PCIC_PDMSTS_DATAERR 0x00000001
+#define TX4938_PCIC_PDMSTS_ALL_CMP 0x000000e0
+#define TX4938_PCIC_PDMSTS_ALL_ERR 0x0000000f
+
+/*
+ * DMA
+ */
+/* bits for MCR */
+#define TX4938_DMA_MCR_EIS(ch) (0x10000000<<(ch))
+#define TX4938_DMA_MCR_DIS(ch) (0x01000000<<(ch))
+#define TX4938_DMA_MCR_RSFIF 0x00000080
+#define TX4938_DMA_MCR_FIFUM(ch) (0x00000008<<(ch))
+#define TX4938_DMA_MCR_RPRT 0x00000002
+#define TX4938_DMA_MCR_MSTEN 0x00000001
+
+/* bits for CCRn */
+#define TX4938_DMA_CCR_IMMCHN 0x20000000
+#define TX4938_DMA_CCR_USEXFSZ 0x10000000
+#define TX4938_DMA_CCR_LE 0x08000000
+#define TX4938_DMA_CCR_DBINH 0x04000000
+#define TX4938_DMA_CCR_SBINH 0x02000000
+#define TX4938_DMA_CCR_CHRST 0x01000000
+#define TX4938_DMA_CCR_RVBYTE 0x00800000
+#define TX4938_DMA_CCR_ACKPOL 0x00400000
+#define TX4938_DMA_CCR_REQPL 0x00200000
+#define TX4938_DMA_CCR_EGREQ 0x00100000
+#define TX4938_DMA_CCR_CHDN 0x00080000
+#define TX4938_DMA_CCR_DNCTL 0x00060000
+#define TX4938_DMA_CCR_EXTRQ 0x00010000
+#define TX4938_DMA_CCR_INTRQD 0x0000e000
+#define TX4938_DMA_CCR_INTENE 0x00001000
+#define TX4938_DMA_CCR_INTENC 0x00000800
+#define TX4938_DMA_CCR_INTENT 0x00000400
+#define TX4938_DMA_CCR_CHNEN 0x00000200
+#define TX4938_DMA_CCR_XFACT 0x00000100
+#define TX4938_DMA_CCR_SMPCHN 0x00000020
+#define TX4938_DMA_CCR_XFSZ(order) (((order) << 2) & 0x0000001c)
+#define TX4938_DMA_CCR_XFSZ_1W TX4938_DMA_CCR_XFSZ(2)
+#define TX4938_DMA_CCR_XFSZ_2W TX4938_DMA_CCR_XFSZ(3)
+#define TX4938_DMA_CCR_XFSZ_4W TX4938_DMA_CCR_XFSZ(4)
+#define TX4938_DMA_CCR_XFSZ_8W TX4938_DMA_CCR_XFSZ(5)
+#define TX4938_DMA_CCR_XFSZ_16W TX4938_DMA_CCR_XFSZ(6)
+#define TX4938_DMA_CCR_XFSZ_32W TX4938_DMA_CCR_XFSZ(7)
+#define TX4938_DMA_CCR_MEMIO 0x00000002
+#define TX4938_DMA_CCR_SNGAD 0x00000001
+
+/* bits for CSRn */
+#define TX4938_DMA_CSR_CHNEN 0x00000400
+#define TX4938_DMA_CSR_STLXFER 0x00000200
+#define TX4938_DMA_CSR_CHNACT 0x00000100
+#define TX4938_DMA_CSR_ABCHC 0x00000080
+#define TX4938_DMA_CSR_NCHNC 0x00000040
+#define TX4938_DMA_CSR_NTRNFC 0x00000020
+#define TX4938_DMA_CSR_EXTDN 0x00000010
+#define TX4938_DMA_CSR_CFERR 0x00000008
+#define TX4938_DMA_CSR_CHERR 0x00000004
+#define TX4938_DMA_CSR_DESERR 0x00000002
+#define TX4938_DMA_CSR_SORERR 0x00000001
+
+/* TX4938 Interrupt Controller (32-bit registers) */
+#define TX4938_IRC_BASE 0xf510
+#define TX4938_IRC_IRFLAG0 0xf510
+#define TX4938_IRC_IRFLAG1 0xf514
+#define TX4938_IRC_IRPOL 0xf518
+#define TX4938_IRC_IRRCNT 0xf51c
+#define TX4938_IRC_IRMASKINT 0xf520
+#define TX4938_IRC_IRMASKEXT 0xf524
+#define TX4938_IRC_IRDEN 0xf600
+#define TX4938_IRC_IRDM0 0xf604
+#define TX4938_IRC_IRDM1 0xf608
+#define TX4938_IRC_IRLVL0 0xf610
+#define TX4938_IRC_IRLVL1 0xf614
+#define TX4938_IRC_IRLVL2 0xf618
+#define TX4938_IRC_IRLVL3 0xf61c
+#define TX4938_IRC_IRLVL4 0xf620
+#define TX4938_IRC_IRLVL5 0xf624
+#define TX4938_IRC_IRLVL6 0xf628
+#define TX4938_IRC_IRLVL7 0xf62c
+#define TX4938_IRC_IRMSK 0xf640
+#define TX4938_IRC_IREDC 0xf660
+#define TX4938_IRC_IRPND 0xf680
+#define TX4938_IRC_IRCS 0xf6a0
+#define TX4938_IRC_LIMIT 0xf6ff
+
+
+#ifndef __ASSEMBLY__
+
+#define tx4938_sdramcptr ((struct tx4938_sdramc_reg *)TX4938_SDRAMC_REG)
+#define tx4938_ebuscptr ((struct tx4938_ebusc_reg *)TX4938_EBUSC_REG)
+#define tx4938_dmaptr(ch) ((struct tx4938_dma_reg *)TX4938_DMA_REG(ch))
+#define tx4938_ndfmcptr ((struct tx4938_ndfmc_reg *)TX4938_NDFMC_REG)
+#define tx4938_ircptr ((struct tx4938_irc_reg *)TX4938_IRC_REG)
+#define tx4938_pcicptr ((struct tx4938_pcic_reg *)TX4938_PCIC_REG)
+#define tx4938_pcic1ptr ((struct tx4938_pcic_reg *)TX4938_PCIC1_REG)
+#define tx4938_ccfgptr ((struct tx4938_ccfg_reg *)TX4938_CCFG_REG)
+#define tx4938_tmrptr(ch) ((struct tx4938_tmr_reg *)TX4938_TMR_REG(ch))
+#define tx4938_sioptr(ch) ((struct tx4938_sio_reg *)TX4938_SIO_REG(ch))
+#define tx4938_pioptr ((struct tx4938_pio_reg *)TX4938_PIO_REG)
+#define tx4938_aclcptr ((struct tx4938_aclc_reg *)TX4938_ACLC_REG)
+#define tx4938_spiptr ((struct tx4938_spi_reg *)TX4938_SPI_REG)
+#define tx4938_sramcptr ((struct tx4938_sramc_reg *)TX4938_SRAMC_REG)
+
+
+#define TX4938_REV_MAJ_MIN() ((unsigned long)tx4938_ccfgptr->crir & 0x00ff)
+#define TX4938_REV_PCODE() ((unsigned long)tx4938_ccfgptr->crir >> 16)
+
+#define TX4938_SDRAMC_BA(ch) ((tx4938_sdramcptr->cr[ch] >> 49) << 21)
+#define TX4938_SDRAMC_SIZE(ch) (((tx4938_sdramcptr->cr[ch] >> 33) + 1) << 21)
+
+#define TX4938_EBUSC_BA(ch) ((tx4938_ebuscptr->cr[ch] >> 48) << 20)
+#define TX4938_EBUSC_SIZE(ch) \
+ (0x00100000 << ((unsigned long)(tx4938_ebuscptr->cr[ch] >> 8) & 0xf))
+
+
+#endif /* !__ASSEMBLY__ */
+
+#endif
diff --git a/include/asm-mips/tx4938/tx4938_mips.h b/include/asm-mips/tx4938/tx4938_mips.h
new file mode 100644
index 000000000000..cf89b205f103
--- /dev/null
+++ b/include/asm-mips/tx4938/tx4938_mips.h
@@ -0,0 +1,54 @@
+/*
+ * linux/include/asm-mips/tx4938/tx4938_bitmask.h
+ * Generic bitmask definitions
+ *
+ * 2003-2005 (c) MontaVista Software, Inc. This file is licensed under the
+ * terms of the GNU General Public License version 2. This program is
+ * licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ *
+ * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com)
+ */
+
+#ifndef TX4938_TX4938_MIPS_H
+#define TX4938_TX4938_MIPS_H
+#ifndef __ASSEMBLY__
+
+#define reg_rd08(r) ((u8 )(*((vu8 *)(r))))
+#define reg_rd16(r) ((u16)(*((vu16*)(r))))
+#define reg_rd32(r) ((u32)(*((vu32*)(r))))
+#define reg_rd64(r) ((u64)(*((vu64*)(r))))
+
+#define reg_wr08(r,v) ((*((vu8 *)(r)))=((u8 )(v)))
+#define reg_wr16(r,v) ((*((vu16*)(r)))=((u16)(v)))
+#define reg_wr32(r,v) ((*((vu32*)(r)))=((u32)(v)))
+#define reg_wr64(r,v) ((*((vu64*)(r)))=((u64)(v)))
+
+typedef volatile __signed char vs8;
+typedef volatile unsigned char vu8;
+
+typedef volatile __signed short vs16;
+typedef volatile unsigned short vu16;
+
+typedef volatile __signed int vs32;
+typedef volatile unsigned int vu32;
+
+typedef s8 s08;
+typedef vs8 vs08;
+
+typedef u8 u08;
+typedef vu8 vu08;
+
+#if (_MIPS_SZLONG == 64)
+
+typedef volatile __signed__ long vs64;
+typedef volatile unsigned long vu64;
+
+#else
+
+typedef volatile __signed__ long long vs64;
+typedef volatile unsigned long long vu64;
+
+#endif
+#endif
+#endif
diff --git a/include/asm-mips/uaccess.h b/include/asm-mips/uaccess.h
index 5c2c98329012..41bb96bb2120 100644
--- a/include/asm-mips/uaccess.h
+++ b/include/asm-mips/uaccess.h
@@ -196,63 +196,55 @@
__get_user_nocheck((x),(ptr),sizeof(*(ptr)))
struct __large_struct { unsigned long buf[100]; };
-#define __m(x) (*(struct __large_struct *)(x))
+#define __m(x) (*(struct __large_struct __user *)(x))
/*
* Yuck. We need two variants, one for 64bit operation and one
* for 32 bit mode and old iron.
*/
#ifdef __mips64
-#define __GET_USER_DW(__gu_err) __get_user_asm("ld", __gu_err)
+#define __GET_USER_DW(ptr) __get_user_asm("ld", ptr)
#else
-#define __GET_USER_DW(__gu_err) __get_user_asm_ll32(__gu_err)
+#define __GET_USER_DW(ptr) __get_user_asm_ll32(ptr)
#endif
#define __get_user_nocheck(x,ptr,size) \
({ \
- __typeof(*(ptr)) __gu_val = 0; \
- long __gu_addr; \
+ __typeof(*(ptr)) __gu_val = (__typeof(*(ptr))) 0; \
long __gu_err = 0; \
\
- might_sleep(); \
- __gu_addr = (long) (ptr); \
switch (size) { \
- case 1: __get_user_asm("lb", __gu_err); break; \
- case 2: __get_user_asm("lh", __gu_err); break; \
- case 4: __get_user_asm("lw", __gu_err); break; \
- case 8: __GET_USER_DW(__gu_err); break; \
+ case 1: __get_user_asm("lb", ptr); break; \
+ case 2: __get_user_asm("lh", ptr); break; \
+ case 4: __get_user_asm("lw", ptr); break; \
+ case 8: __GET_USER_DW(ptr); break; \
default: __get_user_unknown(); break; \
} \
- x = (__typeof__(*(ptr))) __gu_val; \
+ (x) = (__typeof__(*(ptr))) __gu_val; \
__gu_err; \
})
#define __get_user_check(x,ptr,size) \
({ \
+ const __typeof__(*(ptr)) __user * __gu_addr = (ptr); \
__typeof__(*(ptr)) __gu_val = 0; \
- long __gu_addr; \
- long __gu_err; \
- \
- might_sleep(); \
- __gu_addr = (long) (ptr); \
- __gu_err = access_ok(VERIFY_READ, (void *) __gu_addr, size) \
- ? 0 : -EFAULT; \
+ long __gu_err = -EFAULT; \
\
- if (likely(!__gu_err)) { \
+ if (likely(access_ok(VERIFY_READ, __gu_addr, size))) { \
switch (size) { \
- case 1: __get_user_asm("lb", __gu_err); break; \
- case 2: __get_user_asm("lh", __gu_err); break; \
- case 4: __get_user_asm("lw", __gu_err); break; \
- case 8: __GET_USER_DW(__gu_err); break; \
+ case 1: __get_user_asm("lb", __gu_addr); break; \
+ case 2: __get_user_asm("lh", __gu_addr); break; \
+ case 4: __get_user_asm("lw", __gu_addr); break; \
+ case 8: __GET_USER_DW(__gu_addr); break; \
default: __get_user_unknown(); break; \
} \
} \
- x = (__typeof__(*(ptr))) __gu_val; \
+ (x) = (__typeof__(*(ptr))) __gu_val; \
__gu_err; \
})
-#define __get_user_asm(insn,__gu_err) \
-({ \
+#define __get_user_asm(insn, addr) \
+{ \
__asm__ __volatile__( \
"1: " insn " %1, %3 \n" \
"2: \n" \
@@ -264,20 +256,20 @@ struct __large_struct { unsigned long buf[100]; };
" "__UA_ADDR "\t1b, 3b \n" \
" .previous \n" \
: "=r" (__gu_err), "=r" (__gu_val) \
- : "0" (__gu_err), "o" (__m(__gu_addr)), "i" (-EFAULT)); \
-})
+ : "0" (0), "o" (__m(addr)), "i" (-EFAULT)); \
+}
/*
* Get a long long 64 using 32 bit registers.
*/
-#define __get_user_asm_ll32(__gu_err) \
-({ \
+#define __get_user_asm_ll32(addr) \
+{ \
__asm__ __volatile__( \
- "1: lw %1, %3 \n" \
- "2: lw %D1, %4 \n" \
+ "1: lw %1, (%3) \n" \
+ "2: lw %D1, 4(%3) \n" \
" move %0, $0 \n" \
"3: .section .fixup,\"ax\" \n" \
- "4: li %0, %5 \n" \
+ "4: li %0, %4 \n" \
" move %1, $0 \n" \
" move %D1, $0 \n" \
" j 3b \n" \
@@ -287,9 +279,8 @@ struct __large_struct { unsigned long buf[100]; };
" " __UA_ADDR " 2b, 4b \n" \
" .previous \n" \
: "=r" (__gu_err), "=&r" (__gu_val) \
- : "0" (__gu_err), "o" (__m(__gu_addr)), \
- "o" (__m(__gu_addr + 4)), "i" (-EFAULT)); \
-})
+ : "0" (0), "r" (addr), "i" (-EFAULT)); \
+}
extern void __get_user_unknown(void);
@@ -298,25 +289,22 @@ extern void __get_user_unknown(void);
* for 32 bit mode and old iron.
*/
#ifdef __mips64
-#define __PUT_USER_DW(__pu_val) __put_user_asm("sd", __pu_val)
+#define __PUT_USER_DW(ptr) __put_user_asm("sd", ptr)
#else
-#define __PUT_USER_DW(__pu_val) __put_user_asm_ll32(__pu_val)
+#define __PUT_USER_DW(ptr) __put_user_asm_ll32(ptr)
#endif
#define __put_user_nocheck(x,ptr,size) \
({ \
__typeof__(*(ptr)) __pu_val; \
- long __pu_addr; \
long __pu_err = 0; \
\
- might_sleep(); \
__pu_val = (x); \
- __pu_addr = (long) (ptr); \
switch (size) { \
- case 1: __put_user_asm("sb", __pu_val); break; \
- case 2: __put_user_asm("sh", __pu_val); break; \
- case 4: __put_user_asm("sw", __pu_val); break; \
- case 8: __PUT_USER_DW(__pu_val); break; \
+ case 1: __put_user_asm("sb", ptr); break; \
+ case 2: __put_user_asm("sh", ptr); break; \
+ case 4: __put_user_asm("sw", ptr); break; \
+ case 8: __PUT_USER_DW(ptr); break; \
default: __put_user_unknown(); break; \
} \
__pu_err; \
@@ -324,30 +312,24 @@ extern void __get_user_unknown(void);
#define __put_user_check(x,ptr,size) \
({ \
- __typeof__(*(ptr)) __pu_val; \
- long __pu_addr; \
- long __pu_err; \
+ __typeof__(*(ptr)) __user *__pu_addr = (ptr); \
+ __typeof__(*(ptr)) __pu_val = (x); \
+ long __pu_err = -EFAULT; \
\
- might_sleep(); \
- __pu_val = (x); \
- __pu_addr = (long) (ptr); \
- __pu_err = access_ok(VERIFY_WRITE, (void *) __pu_addr, size) \
- ? 0 : -EFAULT; \
- \
- if (likely(!__pu_err)) { \
+ if (likely(access_ok(VERIFY_WRITE, __pu_addr, size))) { \
switch (size) { \
- case 1: __put_user_asm("sb", __pu_val); break; \
- case 2: __put_user_asm("sh", __pu_val); break; \
- case 4: __put_user_asm("sw", __pu_val); break; \
- case 8: __PUT_USER_DW(__pu_val); break; \
+ case 1: __put_user_asm("sb", __pu_addr); break; \
+ case 2: __put_user_asm("sh", __pu_addr); break; \
+ case 4: __put_user_asm("sw", __pu_addr); break; \
+ case 8: __PUT_USER_DW(__pu_addr); break; \
default: __put_user_unknown(); break; \
} \
} \
__pu_err; \
})
-#define __put_user_asm(insn, __pu_val) \
-({ \
+#define __put_user_asm(insn, ptr) \
+{ \
__asm__ __volatile__( \
"1: " insn " %z2, %3 # __put_user_asm\n" \
"2: \n" \
@@ -359,18 +341,18 @@ extern void __get_user_unknown(void);
" " __UA_ADDR " 1b, 3b \n" \
" .previous \n" \
: "=r" (__pu_err) \
- : "0" (__pu_err), "Jr" (__pu_val), "o" (__m(__pu_addr)), \
+ : "0" (0), "Jr" (__pu_val), "o" (__m(ptr)), \
"i" (-EFAULT)); \
-})
+}
-#define __put_user_asm_ll32(__pu_val) \
-({ \
+#define __put_user_asm_ll32(ptr) \
+{ \
__asm__ __volatile__( \
- "1: sw %2, %3 # __put_user_asm_ll32 \n" \
- "2: sw %D2, %4 \n" \
+ "1: sw %2, (%3) # __put_user_asm_ll32 \n" \
+ "2: sw %D2, 4(%3) \n" \
"3: \n" \
" .section .fixup,\"ax\" \n" \
- "4: li %0, %5 \n" \
+ "4: li %0, %4 \n" \
" j 3b \n" \
" .previous \n" \
" .section __ex_table,\"a\" \n" \
@@ -378,9 +360,9 @@ extern void __get_user_unknown(void);
" " __UA_ADDR " 2b, 4b \n" \
" .previous" \
: "=r" (__pu_err) \
- : "0" (__pu_err), "r" (__pu_val), "o" (__m(__pu_addr)), \
- "o" (__m(__pu_addr + 4)), "i" (-EFAULT)); \
-})
+ : "0" (0), "r" (__pu_val), "r" (ptr), \
+ "i" (-EFAULT)); \
+}
extern void __put_user_unknown(void);
@@ -403,7 +385,7 @@ extern size_t __copy_user(void *__to, const void *__from, size_t __n);
#define __invoke_copy_to_user(to,from,n) \
({ \
- register void *__cu_to_r __asm__ ("$4"); \
+ register void __user *__cu_to_r __asm__ ("$4"); \
register const void *__cu_from_r __asm__ ("$5"); \
register long __cu_len_r __asm__ ("$6"); \
\
@@ -435,7 +417,7 @@ extern size_t __copy_user(void *__to, const void *__from, size_t __n);
*/
#define __copy_to_user(to,from,n) \
({ \
- void *__cu_to; \
+ void __user *__cu_to; \
const void *__cu_from; \
long __cu_len; \
\
@@ -465,7 +447,7 @@ extern size_t __copy_user(void *__to, const void *__from, size_t __n);
*/
#define copy_to_user(to,from,n) \
({ \
- void *__cu_to; \
+ void __user *__cu_to; \
const void *__cu_from; \
long __cu_len; \
\
@@ -482,7 +464,7 @@ extern size_t __copy_user(void *__to, const void *__from, size_t __n);
#define __invoke_copy_from_user(to,from,n) \
({ \
register void *__cu_to_r __asm__ ("$4"); \
- register const void *__cu_from_r __asm__ ("$5"); \
+ register const void __user *__cu_from_r __asm__ ("$5"); \
register long __cu_len_r __asm__ ("$6"); \
\
__cu_to_r = (to); \
@@ -521,7 +503,7 @@ extern size_t __copy_user(void *__to, const void *__from, size_t __n);
#define __copy_from_user(to,from,n) \
({ \
void *__cu_to; \
- const void *__cu_from; \
+ const void __user *__cu_from; \
long __cu_len; \
\
might_sleep(); \
@@ -552,7 +534,7 @@ extern size_t __copy_user(void *__to, const void *__from, size_t __n);
#define copy_from_user(to,from,n) \
({ \
void *__cu_to; \
- const void *__cu_from; \
+ const void __user *__cu_from; \
long __cu_len; \
\
might_sleep(); \
@@ -569,8 +551,8 @@ extern size_t __copy_user(void *__to, const void *__from, size_t __n);
#define copy_in_user(to,from,n) \
({ \
- void *__cu_to; \
- const void *__cu_from; \
+ void __user *__cu_to; \
+ const void __user *__cu_from; \
long __cu_len; \
\
might_sleep(); \
@@ -596,7 +578,7 @@ extern size_t __copy_user(void *__to, const void *__from, size_t __n);
* On success, this will be zero.
*/
static inline __kernel_size_t
-__clear_user(void *addr, __kernel_size_t size)
+__clear_user(void __user *addr, __kernel_size_t size)
{
__kernel_size_t res;
@@ -616,7 +598,7 @@ __clear_user(void *addr, __kernel_size_t size)
#define clear_user(addr,n) \
({ \
- void * __cl_addr = (addr); \
+ void __user * __cl_addr = (addr); \
unsigned long __cl_size = (n); \
if (__cl_size && access_ok(VERIFY_WRITE, \
((unsigned long)(__cl_addr)), __cl_size)) \
@@ -645,7 +627,7 @@ __clear_user(void *addr, __kernel_size_t size)
* and returns @count.
*/
static inline long
-__strncpy_from_user(char *__to, const char *__from, long __len)
+__strncpy_from_user(char *__to, const char __user *__from, long __len)
{
long res;
@@ -682,7 +664,7 @@ __strncpy_from_user(char *__to, const char *__from, long __len)
* and returns @count.
*/
static inline long
-strncpy_from_user(char *__to, const char *__from, long __len)
+strncpy_from_user(char *__to, const char __user *__from, long __len)
{
long res;
@@ -701,7 +683,7 @@ strncpy_from_user(char *__to, const char *__from, long __len)
}
/* Returns: 0 if bad, string length+1 (memory size) of string if ok */
-static inline long __strlen_user(const char *s)
+static inline long __strlen_user(const char __user *s)
{
long res;
@@ -731,7 +713,7 @@ static inline long __strlen_user(const char *s)
* If there is a limit on the length of a valid string, you may wish to
* consider using strnlen_user() instead.
*/
-static inline long strlen_user(const char *s)
+static inline long strlen_user(const char __user *s)
{
long res;
@@ -748,7 +730,7 @@ static inline long strlen_user(const char *s)
}
/* Returns: 0 if bad, string length+1 (memory size) of string if ok */
-static inline long __strnlen_user(const char *s, long n)
+static inline long __strnlen_user(const char __user *s, long n)
{
long res;
@@ -779,7 +761,7 @@ static inline long __strnlen_user(const char *s, long n)
* If there is a limit on the length of a valid string, you may wish to
* consider using strnlen_user() instead.
*/
-static inline long strnlen_user(const char *s, long n)
+static inline long strnlen_user(const char __user *s, long n)
{
long res;
diff --git a/include/asm-mips/unistd.h b/include/asm-mips/unistd.h
index ad4d48056307..89ea8b60e945 100644
--- a/include/asm-mips/unistd.h
+++ b/include/asm-mips/unistd.h
@@ -303,16 +303,21 @@
#define __NR_add_key (__NR_Linux + 280)
#define __NR_request_key (__NR_Linux + 281)
#define __NR_keyctl (__NR_Linux + 282)
+#define __NR_set_thread_area (__NR_Linux + 283)
+#define __NR_inotify_init (__NR_Linux + 284)
+#define __NR_inotify_add_watch (__NR_Linux + 285)
+#define __NR_inotify_rm_watch (__NR_Linux + 286)
+
/*
* Offset of the last Linux o32 flavoured syscall
*/
-#define __NR_Linux_syscalls 282
+#define __NR_Linux_syscalls 286
#endif /* _MIPS_SIM == _MIPS_SIM_ABI32 */
#define __NR_O32_Linux 4000
-#define __NR_O32_Linux_syscalls 282
+#define __NR_O32_Linux_syscalls 283
#if _MIPS_SIM == _MIPS_SIM_ABI64
@@ -562,16 +567,20 @@
#define __NR_add_key (__NR_Linux + 239)
#define __NR_request_key (__NR_Linux + 240)
#define __NR_keyctl (__NR_Linux + 241)
+#define __NR_set_thread_area (__NR_Linux + 242)
+#define __NR_inotify_init (__NR_Linux + 243)
+#define __NR_inotify_add_watch (__NR_Linux + 244)
+#define __NR_inotify_rm_watch (__NR_Linux + 245)
/*
* Offset of the last Linux 64-bit flavoured syscall
*/
-#define __NR_Linux_syscalls 241
+#define __NR_Linux_syscalls 245
#endif /* _MIPS_SIM == _MIPS_SIM_ABI64 */
#define __NR_64_Linux 5000
-#define __NR_64_Linux_syscalls 241
+#define __NR_64_Linux_syscalls 242
#if _MIPS_SIM == _MIPS_SIM_NABI32
@@ -825,16 +834,20 @@
#define __NR_add_key (__NR_Linux + 243)
#define __NR_request_key (__NR_Linux + 244)
#define __NR_keyctl (__NR_Linux + 245)
+#define __NR_set_thread_area (__NR_Linux + 246)
+#define __NR_inotify_init (__NR_Linux + 247)
+#define __NR_inotify_add_watch (__NR_Linux + 248)
+#define __NR_inotify_rm_watch (__NR_Linux + 249)
/*
* Offset of the last N32 flavoured syscall
*/
-#define __NR_Linux_syscalls 245
+#define __NR_Linux_syscalls 249
#endif /* _MIPS_SIM == _MIPS_SIM_NABI32 */
#define __NR_N32_Linux 6000
-#define __NR_N32_Linux_syscalls 245
+#define __NR_N32_Linux_syscalls 246
#ifndef __ASSEMBLY__
@@ -1164,7 +1177,6 @@ asmlinkage long sys_mmap2(
unsigned long fd, unsigned long pgoff);
asmlinkage int sys_execve(nabi_no_regargs struct pt_regs regs);
asmlinkage int sys_pipe(nabi_no_regargs struct pt_regs regs);
-asmlinkage int sys_ptrace(long request, long pid, long addr, long data);
struct sigaction;
asmlinkage long sys_rt_sigaction(int sig,
const struct sigaction __user *act,
diff --git a/include/asm-mips/vga.h b/include/asm-mips/vga.h
index 6b35cf054c79..ca5cec97e167 100644
--- a/include/asm-mips/vga.h
+++ b/include/asm-mips/vga.h
@@ -6,6 +6,8 @@
#ifndef _ASM_VGA_H
#define _ASM_VGA_H
+#include <asm/byteorder.h>
+
/*
* On the PC, we can just recalculate addresses and then
* access the videoram directly without any black magic.
@@ -16,4 +18,27 @@
#define vga_readb(x) (*(x))
#define vga_writeb(x,y) (*(y) = (x))
+#define VT_BUF_HAVE_RW
+/*
+ * These are only needed for supporting VGA or MDA text mode, which use little
+ * endian byte ordering.
+ * In other cases, we can optimize by using native byte ordering and
+ * <linux/vt_buffer.h> has already done the right job for us.
+ */
+
+static inline void scr_writew(u16 val, volatile u16 *addr)
+{
+ *addr = cpu_to_le16(val);
+}
+
+static inline u16 scr_readw(volatile const u16 *addr)
+{
+ return le16_to_cpu(*addr);
+}
+
+#define scr_memcpyw(d, s, c) memcpy(d, s, c)
+#define scr_memmovew(d, s, c) memmove(d, s, c)
+#define VT_BUF_HAVE_MEMCPYW
+#define VT_BUF_HAVE_MEMMOVEW
+
#endif /* _ASM_VGA_H */
diff --git a/include/asm-mips/war.h b/include/asm-mips/war.h
index 04ee53b34c2e..ad374bd3f130 100644
--- a/include/asm-mips/war.h
+++ b/include/asm-mips/war.h
@@ -177,6 +177,17 @@
#endif
/*
+ * The RM9000 has a bug (though PMC-Sierra opposes it being called that)
+ * where invalid instructions in the same I-cache line worth of instructions
+ * being fetched may case spurious exceptions.
+ */
+#if defined(CONFIG_MOMENCO_JAGUAR_ATX) || defined(CONFIG_MOMENCO_OCELOT_3) || \
+ defined(CONFIG_PMC_YOSEMITE)
+#define ICACHE_REFILLS_WORKAROUND_WAR 1
+#endif
+
+
+/*
* ON the R10000 upto version 2.6 (not sure about 2.7) there is a bug that
* may cause ll / sc and lld / scd sequences to execute non-atomically.
*/
@@ -187,6 +198,9 @@
/*
* Workarounds default to off
*/
+#ifndef ICACHE_REFILLS_WORKAROUND_WAR
+#define ICACHE_REFILLS_WORKAROUND_WAR 0
+#endif
#ifndef R4600_V1_INDEX_ICACHEOP_WAR
#define R4600_V1_INDEX_ICACHEOP_WAR 0
#endif
diff --git a/include/asm-parisc/assembly.h b/include/asm-parisc/assembly.h
index 30b023411fef..3ce3440d1b0c 100644
--- a/include/asm-parisc/assembly.h
+++ b/include/asm-parisc/assembly.h
@@ -21,7 +21,9 @@
#ifndef _PARISC_ASSEMBLY_H
#define _PARISC_ASSEMBLY_H
-#ifdef __LP64__
+#define CALLEE_FLOAT_FRAME_SIZE 80
+
+#ifdef CONFIG_64BIT
#define LDREG ldd
#define STREG std
#define LDREGX ldd,s
@@ -30,8 +32,8 @@
#define SHRREG shrd
#define RP_OFFSET 16
#define FRAME_SIZE 128
-#define CALLEE_SAVE_FRAME_SIZE 144
-#else
+#define CALLEE_REG_FRAME_SIZE 144
+#else /* CONFIG_64BIT */
#define LDREG ldw
#define STREG stw
#define LDREGX ldwx,s
@@ -40,9 +42,11 @@
#define SHRREG shr
#define RP_OFFSET 20
#define FRAME_SIZE 64
-#define CALLEE_SAVE_FRAME_SIZE 128
+#define CALLEE_REG_FRAME_SIZE 128
#endif
+#define CALLEE_SAVE_FRAME_SIZE (CALLEE_REG_FRAME_SIZE + CALLEE_FLOAT_FRAME_SIZE)
+
#ifdef CONFIG_PA20
#define BL b,l
# ifdef CONFIG_64BIT
@@ -300,9 +304,35 @@
fldd,mb -8(\regs), %fr0
.endm
+ .macro callee_save_float
+ fstd,ma %fr12, 8(%r30)
+ fstd,ma %fr13, 8(%r30)
+ fstd,ma %fr14, 8(%r30)
+ fstd,ma %fr15, 8(%r30)
+ fstd,ma %fr16, 8(%r30)
+ fstd,ma %fr17, 8(%r30)
+ fstd,ma %fr18, 8(%r30)
+ fstd,ma %fr19, 8(%r30)
+ fstd,ma %fr20, 8(%r30)
+ fstd,ma %fr21, 8(%r30)
+ .endm
+
+ .macro callee_rest_float
+ fldd,mb -8(%r30), %fr21
+ fldd,mb -8(%r30), %fr20
+ fldd,mb -8(%r30), %fr19
+ fldd,mb -8(%r30), %fr18
+ fldd,mb -8(%r30), %fr17
+ fldd,mb -8(%r30), %fr16
+ fldd,mb -8(%r30), %fr15
+ fldd,mb -8(%r30), %fr14
+ fldd,mb -8(%r30), %fr13
+ fldd,mb -8(%r30), %fr12
+ .endm
+
#ifdef __LP64__
.macro callee_save
- std,ma %r3, CALLEE_SAVE_FRAME_SIZE(%r30)
+ std,ma %r3, CALLEE_REG_FRAME_SIZE(%r30)
mfctl %cr27, %r3
std %r4, -136(%r30)
std %r5, -128(%r30)
@@ -340,13 +370,13 @@
ldd -128(%r30), %r5
ldd -136(%r30), %r4
mtctl %r3, %cr27
- ldd,mb -CALLEE_SAVE_FRAME_SIZE(%r30), %r3
+ ldd,mb -CALLEE_REG_FRAME_SIZE(%r30), %r3
.endm
#else /* ! __LP64__ */
.macro callee_save
- stw,ma %r3, CALLEE_SAVE_FRAME_SIZE(%r30)
+ stw,ma %r3, CALLEE_REG_FRAME_SIZE(%r30)
mfctl %cr27, %r3
stw %r4, -124(%r30)
stw %r5, -120(%r30)
@@ -384,7 +414,7 @@
ldw -120(%r30), %r5
ldw -124(%r30), %r4
mtctl %r3, %cr27
- ldw,mb -CALLEE_SAVE_FRAME_SIZE(%r30), %r3
+ ldw,mb -CALLEE_REG_FRAME_SIZE(%r30), %r3
.endm
#endif /* ! __LP64__ */
@@ -450,5 +480,30 @@
REST_CR (%cr22, PT_PSW (\regs))
.endm
+
+ /* First step to create a "relied upon translation"
+ * See PA 2.0 Arch. page F-4 and F-5.
+ *
+ * The ssm was originally necessary due to a "PCxT bug".
+ * But someone decided it needed to be added to the architecture
+ * and this "feature" went into rev3 of PA-RISC 1.1 Arch Manual.
+ * It's been carried forward into PA 2.0 Arch as well. :^(
+ *
+ * "ssm 0,%r0" is a NOP with side effects (prefetch barrier).
+ * rsm/ssm prevents the ifetch unit from speculatively fetching
+ * instructions past this line in the code stream.
+ * PA 2.0 processor will single step all insn in the same QUAD (4 insn).
+ */
+ .macro pcxt_ssm_bug
+ rsm PSW_SM_I,%r0
+ nop /* 1 */
+ nop /* 2 */
+ nop /* 3 */
+ nop /* 4 */
+ nop /* 5 */
+ nop /* 6 */
+ nop /* 7 */
+ .endm
+
#endif /* __ASSEMBLY__ */
#endif
diff --git a/include/asm-parisc/bitops.h b/include/asm-parisc/bitops.h
index af7db694b22d..55b98c67fd82 100644
--- a/include/asm-parisc/bitops.h
+++ b/include/asm-parisc/bitops.h
@@ -2,7 +2,7 @@
#define _PARISC_BITOPS_H
#include <linux/compiler.h>
-#include <asm/spinlock.h>
+#include <asm/types.h> /* for BITS_PER_LONG/SHIFT_PER_LONG */
#include <asm/byteorder.h>
#include <asm/atomic.h>
@@ -12,193 +12,157 @@
* to include/asm-i386/bitops.h or kerneldoc
*/
-#ifdef __LP64__
-# define SHIFT_PER_LONG 6
-#ifndef BITS_PER_LONG
-# define BITS_PER_LONG 64
-#endif
-#else
-# define SHIFT_PER_LONG 5
-#ifndef BITS_PER_LONG
-# define BITS_PER_LONG 32
-#endif
-#endif
-
-#define CHOP_SHIFTCOUNT(x) ((x) & (BITS_PER_LONG - 1))
+#define CHOP_SHIFTCOUNT(x) (((unsigned long) (x)) & (BITS_PER_LONG - 1))
#define smp_mb__before_clear_bit() smp_mb()
#define smp_mb__after_clear_bit() smp_mb()
-static __inline__ void set_bit(int nr, volatile unsigned long * address)
+/* See http://marc.theaimsgroup.com/?t=108826637900003 for discussion
+ * on use of volatile and __*_bit() (set/clear/change):
+ * *_bit() want use of volatile.
+ * __*_bit() are "relaxed" and don't use spinlock or volatile.
+ */
+
+static __inline__ void set_bit(int nr, volatile unsigned long * addr)
{
- unsigned long mask;
- unsigned long *addr = (unsigned long *) address;
+ unsigned long mask = 1UL << CHOP_SHIFTCOUNT(nr);
unsigned long flags;
addr += (nr >> SHIFT_PER_LONG);
- mask = 1L << CHOP_SHIFTCOUNT(nr);
_atomic_spin_lock_irqsave(addr, flags);
*addr |= mask;
_atomic_spin_unlock_irqrestore(addr, flags);
}
-static __inline__ void __set_bit(int nr, volatile unsigned long * address)
+static __inline__ void __set_bit(unsigned long nr, volatile unsigned long * addr)
{
- unsigned long mask;
- unsigned long *addr = (unsigned long *) address;
+ unsigned long *m = (unsigned long *) addr + (nr >> SHIFT_PER_LONG);
- addr += (nr >> SHIFT_PER_LONG);
- mask = 1L << CHOP_SHIFTCOUNT(nr);
- *addr |= mask;
+ *m |= 1UL << CHOP_SHIFTCOUNT(nr);
}
-static __inline__ void clear_bit(int nr, volatile unsigned long * address)
+static __inline__ void clear_bit(int nr, volatile unsigned long * addr)
{
- unsigned long mask;
- unsigned long *addr = (unsigned long *) address;
+ unsigned long mask = ~(1UL << CHOP_SHIFTCOUNT(nr));
unsigned long flags;
addr += (nr >> SHIFT_PER_LONG);
- mask = 1L << CHOP_SHIFTCOUNT(nr);
_atomic_spin_lock_irqsave(addr, flags);
- *addr &= ~mask;
+ *addr &= mask;
_atomic_spin_unlock_irqrestore(addr, flags);
}
-static __inline__ void __clear_bit(unsigned long nr, volatile unsigned long * address)
+static __inline__ void __clear_bit(unsigned long nr, volatile unsigned long * addr)
{
- unsigned long mask;
- unsigned long *addr = (unsigned long *) address;
+ unsigned long *m = (unsigned long *) addr + (nr >> SHIFT_PER_LONG);
- addr += (nr >> SHIFT_PER_LONG);
- mask = 1L << CHOP_SHIFTCOUNT(nr);
- *addr &= ~mask;
+ *m &= ~(1UL << CHOP_SHIFTCOUNT(nr));
}
-static __inline__ void change_bit(int nr, volatile unsigned long * address)
+static __inline__ void change_bit(int nr, volatile unsigned long * addr)
{
- unsigned long mask;
- unsigned long *addr = (unsigned long *) address;
+ unsigned long mask = 1UL << CHOP_SHIFTCOUNT(nr);
unsigned long flags;
addr += (nr >> SHIFT_PER_LONG);
- mask = 1L << CHOP_SHIFTCOUNT(nr);
_atomic_spin_lock_irqsave(addr, flags);
*addr ^= mask;
_atomic_spin_unlock_irqrestore(addr, flags);
}
-static __inline__ void __change_bit(int nr, volatile unsigned long * address)
+static __inline__ void __change_bit(unsigned long nr, volatile unsigned long * addr)
{
- unsigned long mask;
- unsigned long *addr = (unsigned long *) address;
+ unsigned long *m = (unsigned long *) addr + (nr >> SHIFT_PER_LONG);
- addr += (nr >> SHIFT_PER_LONG);
- mask = 1L << CHOP_SHIFTCOUNT(nr);
- *addr ^= mask;
+ *m ^= 1UL << CHOP_SHIFTCOUNT(nr);
}
-static __inline__ int test_and_set_bit(int nr, volatile unsigned long * address)
+static __inline__ int test_and_set_bit(int nr, volatile unsigned long * addr)
{
- unsigned long mask;
- unsigned long *addr = (unsigned long *) address;
- int oldbit;
+ unsigned long mask = 1UL << CHOP_SHIFTCOUNT(nr);
+ unsigned long oldbit;
unsigned long flags;
addr += (nr >> SHIFT_PER_LONG);
- mask = 1L << CHOP_SHIFTCOUNT(nr);
_atomic_spin_lock_irqsave(addr, flags);
- oldbit = (*addr & mask) ? 1 : 0;
- *addr |= mask;
+ oldbit = *addr;
+ *addr = oldbit | mask;
_atomic_spin_unlock_irqrestore(addr, flags);
- return oldbit;
+ return (oldbit & mask) ? 1 : 0;
}
static __inline__ int __test_and_set_bit(int nr, volatile unsigned long * address)
{
- unsigned long mask;
- unsigned long *addr = (unsigned long *) address;
- int oldbit;
+ unsigned long mask = 1UL << CHOP_SHIFTCOUNT(nr);
+ unsigned long oldbit;
+ unsigned long *addr = (unsigned long *)address + (nr >> SHIFT_PER_LONG);
- addr += (nr >> SHIFT_PER_LONG);
- mask = 1L << CHOP_SHIFTCOUNT(nr);
- oldbit = (*addr & mask) ? 1 : 0;
- *addr |= mask;
+ oldbit = *addr;
+ *addr = oldbit | mask;
- return oldbit;
+ return (oldbit & mask) ? 1 : 0;
}
-static __inline__ int test_and_clear_bit(int nr, volatile unsigned long * address)
+static __inline__ int test_and_clear_bit(int nr, volatile unsigned long * addr)
{
- unsigned long mask;
- unsigned long *addr = (unsigned long *) address;
- int oldbit;
+ unsigned long mask = 1UL << CHOP_SHIFTCOUNT(nr);
+ unsigned long oldbit;
unsigned long flags;
addr += (nr >> SHIFT_PER_LONG);
- mask = 1L << CHOP_SHIFTCOUNT(nr);
_atomic_spin_lock_irqsave(addr, flags);
- oldbit = (*addr & mask) ? 1 : 0;
- *addr &= ~mask;
+ oldbit = *addr;
+ *addr = oldbit & ~mask;
_atomic_spin_unlock_irqrestore(addr, flags);
- return oldbit;
+ return (oldbit & mask) ? 1 : 0;
}
static __inline__ int __test_and_clear_bit(int nr, volatile unsigned long * address)
{
- unsigned long mask;
- unsigned long *addr = (unsigned long *) address;
- int oldbit;
+ unsigned long mask = 1UL << CHOP_SHIFTCOUNT(nr);
+ unsigned long *addr = (unsigned long *)address + (nr >> SHIFT_PER_LONG);
+ unsigned long oldbit;
- addr += (nr >> SHIFT_PER_LONG);
- mask = 1L << CHOP_SHIFTCOUNT(nr);
- oldbit = (*addr & mask) ? 1 : 0;
- *addr &= ~mask;
+ oldbit = *addr;
+ *addr = oldbit & ~mask;
- return oldbit;
+ return (oldbit & mask) ? 1 : 0;
}
-static __inline__ int test_and_change_bit(int nr, volatile unsigned long * address)
+static __inline__ int test_and_change_bit(int nr, volatile unsigned long * addr)
{
- unsigned long mask;
- unsigned long *addr = (unsigned long *) address;
- int oldbit;
+ unsigned long mask = 1UL << CHOP_SHIFTCOUNT(nr);
+ unsigned long oldbit;
unsigned long flags;
addr += (nr >> SHIFT_PER_LONG);
- mask = 1L << CHOP_SHIFTCOUNT(nr);
_atomic_spin_lock_irqsave(addr, flags);
- oldbit = (*addr & mask) ? 1 : 0;
- *addr ^= mask;
+ oldbit = *addr;
+ *addr = oldbit ^ mask;
_atomic_spin_unlock_irqrestore(addr, flags);
- return oldbit;
+ return (oldbit & mask) ? 1 : 0;
}
static __inline__ int __test_and_change_bit(int nr, volatile unsigned long * address)
{
- unsigned long mask;
- unsigned long *addr = (unsigned long *) address;
- int oldbit;
+ unsigned long mask = 1UL << CHOP_SHIFTCOUNT(nr);
+ unsigned long *addr = (unsigned long *)address + (nr >> SHIFT_PER_LONG);
+ unsigned long oldbit;
- addr += (nr >> SHIFT_PER_LONG);
- mask = 1L << CHOP_SHIFTCOUNT(nr);
- oldbit = (*addr & mask) ? 1 : 0;
- *addr ^= mask;
+ oldbit = *addr;
+ *addr = oldbit ^ mask;
- return oldbit;
+ return (oldbit & mask) ? 1 : 0;
}
static __inline__ int test_bit(int nr, const volatile unsigned long *address)
{
- unsigned long mask;
- const unsigned long *addr = (const unsigned long *)address;
-
- addr += (nr >> SHIFT_PER_LONG);
- mask = 1L << CHOP_SHIFTCOUNT(nr);
+ unsigned long mask = 1UL << CHOP_SHIFTCOUNT(nr);
+ const unsigned long *addr = (const unsigned long *)address + (nr >> SHIFT_PER_LONG);
return !!(*addr & mask);
}
@@ -229,7 +193,7 @@ static __inline__ unsigned long __ffs(unsigned long x)
unsigned long ret;
__asm__(
-#if BITS_PER_LONG > 32
+#ifdef __LP64__
" ldi 63,%1\n"
" extrd,u,*<> %0,63,32,%%r0\n"
" extrd,u,*TR %0,31,32,%0\n" /* move top 32-bits down */
@@ -304,14 +268,7 @@ static __inline__ int fls(int x)
* hweightN: returns the hamming weight (i.e. the number
* of bits set) of a N-bit word
*/
-#define hweight64(x) \
-({ \
- unsigned long __x = (x); \
- unsigned int __w; \
- __w = generic_hweight32((unsigned int) __x); \
- __w += generic_hweight32((unsigned int) (__x>>32)); \
- __w; \
-})
+#define hweight64(x) generic_hweight64(x)
#define hweight32(x) generic_hweight32(x)
#define hweight16(x) generic_hweight16(x)
#define hweight8(x) generic_hweight8(x)
@@ -324,7 +281,13 @@ static __inline__ int fls(int x)
*/
static inline int sched_find_first_bit(const unsigned long *b)
{
-#ifndef __LP64__
+#ifdef __LP64__
+ if (unlikely(b[0]))
+ return __ffs(b[0]);
+ if (unlikely(b[1]))
+ return __ffs(b[1]) + 64;
+ return __ffs(b[2]) + 128;
+#else
if (unlikely(b[0]))
return __ffs(b[0]);
if (unlikely(b[1]))
@@ -334,14 +297,6 @@ static inline int sched_find_first_bit(const unsigned long *b)
if (b[3])
return __ffs(b[3]) + 96;
return __ffs(b[4]) + 128;
-#else
- if (unlikely(b[0]))
- return __ffs(b[0]);
- if (unlikely(((unsigned int)b[1])))
- return __ffs(b[1]) + 64;
- if (b[1] >> 32)
- return __ffs(b[1] >> 32) + 96;
- return __ffs(b[2]) + 128;
#endif
}
@@ -391,7 +346,7 @@ found_middle:
static __inline__ unsigned long find_next_bit(const unsigned long *addr, unsigned long size, unsigned long offset)
{
- const unsigned long *p = addr + (offset >> 6);
+ const unsigned long *p = addr + (offset >> SHIFT_PER_LONG);
unsigned long result = offset & ~(BITS_PER_LONG-1);
unsigned long tmp;
@@ -445,71 +400,90 @@ found_middle:
* test_and_{set,clear}_bit guarantee atomicity without
* disabling interrupts.
*/
-#ifdef __LP64__
-#define ext2_set_bit(nr, addr) __test_and_set_bit((nr) ^ 0x38, (unsigned long *)addr)
-#define ext2_set_bit_atomic(l,nr,addr) test_and_set_bit((nr) ^ 0x38, (unsigned long *)addr)
-#define ext2_clear_bit(nr, addr) __test_and_clear_bit((nr) ^ 0x38, (unsigned long *)addr)
-#define ext2_clear_bit_atomic(l,nr,addr) test_and_clear_bit((nr) ^ 0x38, (unsigned long *)addr)
-#else
-#define ext2_set_bit(nr, addr) __test_and_set_bit((nr) ^ 0x18, (unsigned long *)addr)
-#define ext2_set_bit_atomic(l,nr,addr) test_and_set_bit((nr) ^ 0x18, (unsigned long *)addr)
-#define ext2_clear_bit(nr, addr) __test_and_clear_bit((nr) ^ 0x18, (unsigned long *)addr)
-#define ext2_clear_bit_atomic(l,nr,addr) test_and_clear_bit((nr) ^ 0x18, (unsigned long *)addr)
-#endif
-#endif /* __KERNEL__ */
+/* '3' is bits per byte */
+#define LE_BYTE_ADDR ((sizeof(unsigned long) - 1) << 3)
-static __inline__ int ext2_test_bit(int nr, __const__ void * addr)
-{
- __const__ unsigned char *ADDR = (__const__ unsigned char *) addr;
+#define ext2_test_bit(nr, addr) \
+ test_bit((nr) ^ LE_BYTE_ADDR, (unsigned long *)addr)
+#define ext2_set_bit(nr, addr) \
+ __test_and_set_bit((nr) ^ LE_BYTE_ADDR, (unsigned long *)addr)
+#define ext2_clear_bit(nr, addr) \
+ __test_and_clear_bit((nr) ^ LE_BYTE_ADDR, (unsigned long *)addr)
- return (ADDR[nr >> 3] >> (nr & 7)) & 1;
-}
+#define ext2_set_bit_atomic(l,nr,addr) \
+ test_and_set_bit((nr) ^ LE_BYTE_ADDR, (unsigned long *)addr)
+#define ext2_clear_bit_atomic(l,nr,addr) \
+ test_and_clear_bit( (nr) ^ LE_BYTE_ADDR, (unsigned long *)addr)
+
+#endif /* __KERNEL__ */
-/*
- * This implementation of ext2_find_{first,next}_zero_bit was stolen from
- * Linus' asm-alpha/bitops.h and modified for a big-endian machine.
- */
#define ext2_find_first_zero_bit(addr, size) \
- ext2_find_next_zero_bit((addr), (size), 0)
+ ext2_find_next_zero_bit((addr), (size), 0)
-extern __inline__ unsigned long ext2_find_next_zero_bit(void *addr,
- unsigned long size, unsigned long offset)
+/* include/linux/byteorder does not support "unsigned long" type */
+static inline unsigned long ext2_swabp(unsigned long * x)
{
- unsigned int *p = ((unsigned int *) addr) + (offset >> 5);
- unsigned int result = offset & ~31UL;
- unsigned int tmp;
+#ifdef __LP64__
+ return (unsigned long) __swab64p((u64 *) x);
+#else
+ return (unsigned long) __swab32p((u32 *) x);
+#endif
+}
+
+/* include/linux/byteorder doesn't support "unsigned long" type */
+static inline unsigned long ext2_swab(unsigned long y)
+{
+#ifdef __LP64__
+ return (unsigned long) __swab64((u64) y);
+#else
+ return (unsigned long) __swab32((u32) y);
+#endif
+}
+
+static __inline__ unsigned long ext2_find_next_zero_bit(void *addr, unsigned long size, unsigned long offset)
+{
+ unsigned long *p = (unsigned long *) addr + (offset >> SHIFT_PER_LONG);
+ unsigned long result = offset & ~(BITS_PER_LONG - 1);
+ unsigned long tmp;
if (offset >= size)
return size;
size -= result;
- offset &= 31UL;
+ offset &= (BITS_PER_LONG - 1UL);
if (offset) {
- tmp = cpu_to_le32p(p++);
- tmp |= ~0UL >> (32-offset);
- if (size < 32)
+ tmp = ext2_swabp(p++);
+ tmp |= (~0UL >> (BITS_PER_LONG - offset));
+ if (size < BITS_PER_LONG)
goto found_first;
- if (tmp != ~0U)
+ if (~tmp)
goto found_middle;
- size -= 32;
- result += 32;
+ size -= BITS_PER_LONG;
+ result += BITS_PER_LONG;
}
- while (size >= 32) {
- if ((tmp = cpu_to_le32p(p++)) != ~0U)
- goto found_middle;
- result += 32;
- size -= 32;
+
+ while (size & ~(BITS_PER_LONG - 1)) {
+ if (~(tmp = *(p++)))
+ goto found_middle_swap;
+ result += BITS_PER_LONG;
+ size -= BITS_PER_LONG;
}
if (!size)
return result;
- tmp = cpu_to_le32p(p);
+ tmp = ext2_swabp(p);
found_first:
- tmp |= ~0U << size;
+ tmp |= ~0UL << size;
+ if (tmp == ~0UL) /* Are any bits zero? */
+ return result + size; /* Nope. Skip ffz */
found_middle:
return result + ffz(tmp);
+
+found_middle_swap:
+ return result + ffz(ext2_swab(tmp));
}
+
/* Bitmap functions for the minix filesystem. */
#define minix_test_and_set_bit(nr,addr) ext2_set_bit(nr,addr)
#define minix_set_bit(nr,addr) ((void)ext2_set_bit(nr,addr))
diff --git a/include/asm-parisc/cacheflush.h b/include/asm-parisc/cacheflush.h
index aa592d8c0e39..1bc3c83ee74b 100644
--- a/include/asm-parisc/cacheflush.h
+++ b/include/asm-parisc/cacheflush.h
@@ -100,30 +100,34 @@ static inline void flush_cache_range(struct vm_area_struct *vma,
/* Simple function to work out if we have an existing address translation
* for a user space vma. */
-static inline pte_t *__translation_exists(struct mm_struct *mm,
- unsigned long addr)
+static inline int translation_exists(struct vm_area_struct *vma,
+ unsigned long addr, unsigned long pfn)
{
- pgd_t *pgd = pgd_offset(mm, addr);
+ pgd_t *pgd = pgd_offset(vma->vm_mm, addr);
pmd_t *pmd;
- pte_t *pte;
+ pte_t pte;
if(pgd_none(*pgd))
- return NULL;
+ return 0;
pmd = pmd_offset(pgd, addr);
if(pmd_none(*pmd) || pmd_bad(*pmd))
- return NULL;
+ return 0;
- pte = pte_offset_map(pmd, addr);
+ /* We cannot take the pte lock here: flush_cache_page is usually
+ * called with pte lock already held. Whereas flush_dcache_page
+ * takes flush_dcache_mmap_lock, which is lower in the hierarchy:
+ * the vma itself is secure, but the pte might come or go racily.
+ */
+ pte = *pte_offset_map(pmd, addr);
+ /* But pte_unmap() does nothing on this architecture */
- /* The PA flush mappings show up as pte_none, but they're
- * valid none the less */
- if(pte_none(*pte) && ((pte_val(*pte) & _PAGE_FLUSH) == 0))
- return NULL;
- return pte;
-}
-#define translation_exists(vma, addr) __translation_exists((vma)->vm_mm, addr)
+ /* Filter out coincidental file entries and swap entries */
+ if (!(pte_val(pte) & (_PAGE_FLUSH|_PAGE_PRESENT)))
+ return 0;
+ return pte_pfn(pte) == pfn;
+}
/* Private function to flush a page from the cache of a non-current
* process. cr25 contains the Page Directory of the current user
@@ -175,9 +179,8 @@ flush_cache_page(struct vm_area_struct *vma, unsigned long vmaddr, unsigned long
{
BUG_ON(!vma->vm_mm->context);
- if(likely(translation_exists(vma, vmaddr)))
+ if (likely(translation_exists(vma, vmaddr, pfn)))
__flush_cache_page(vma, vmaddr);
}
#endif
-
diff --git a/include/asm-parisc/dma-mapping.h b/include/asm-parisc/dma-mapping.h
index 4db84f969e9e..74d4ac6f2151 100644
--- a/include/asm-parisc/dma-mapping.h
+++ b/include/asm-parisc/dma-mapping.h
@@ -9,8 +9,8 @@
/* See Documentation/DMA-mapping.txt */
struct hppa_dma_ops {
int (*dma_supported)(struct device *dev, u64 mask);
- void *(*alloc_consistent)(struct device *dev, size_t size, dma_addr_t *iova, int flag);
- void *(*alloc_noncoherent)(struct device *dev, size_t size, dma_addr_t *iova, int flag);
+ void *(*alloc_consistent)(struct device *dev, size_t size, dma_addr_t *iova, gfp_t flag);
+ void *(*alloc_noncoherent)(struct device *dev, size_t size, dma_addr_t *iova, gfp_t flag);
void (*free_consistent)(struct device *dev, size_t size, void *vaddr, dma_addr_t iova);
dma_addr_t (*map_single)(struct device *dev, void *addr, size_t size, enum dma_data_direction direction);
void (*unmap_single)(struct device *dev, dma_addr_t iova, size_t size, enum dma_data_direction direction);
@@ -49,14 +49,14 @@ extern struct hppa_dma_ops *hppa_dma_ops;
static inline void *
dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle,
- int flag)
+ gfp_t flag)
{
return hppa_dma_ops->alloc_consistent(dev, size, dma_handle, flag);
}
static inline void *
dma_alloc_noncoherent(struct device *dev, size_t size, dma_addr_t *dma_handle,
- int flag)
+ gfp_t flag)
{
return hppa_dma_ops->alloc_noncoherent(dev, size, dma_handle, flag);
}
diff --git a/include/asm-parisc/errno.h b/include/asm-parisc/errno.h
index 08464c405471..e2f3ddc796be 100644
--- a/include/asm-parisc/errno.h
+++ b/include/asm-parisc/errno.h
@@ -114,6 +114,7 @@
#define ENOTSUP 252 /* Function not implemented (POSIX.4 / HPUX) */
#define ECANCELLED 253 /* aio request was canceled before complete (POSIX.4 / HPUX) */
+#define ECANCELED ECANCELLED /* SuSv3 and Solaris wants one 'L' */
/* for robust mutexes */
#define EOWNERDEAD 254 /* Owner died */
diff --git a/include/asm-parisc/grfioctl.h b/include/asm-parisc/grfioctl.h
index d3cfc0168fb1..6a910311b56b 100644
--- a/include/asm-parisc/grfioctl.h
+++ b/include/asm-parisc/grfioctl.h
@@ -69,6 +69,8 @@
#define CRT_ID_TVRX S9000_ID_98765 /* TVRX (gto/falcon) */
#define CRT_ID_ARTIST S9000_ID_ARTIST /* Artist */
#define CRT_ID_SUMMIT 0x2FC1066B /* Summit FX2, FX4, FX6 ... */
+#define CRT_ID_LEGO 0x35ACDA30 /* Lego FX5, FX10 ... */
+#define CRT_ID_PINNACLE 0x35ACDA16 /* Pinnacle FXe */
/* structure for ioctl(GCDESCRIBE) */
diff --git a/include/asm-parisc/ide.h b/include/asm-parisc/ide.h
index 3243cf2cd227..b27bf7aeb256 100644
--- a/include/asm-parisc/ide.h
+++ b/include/asm-parisc/ide.h
@@ -22,7 +22,6 @@
#define ide_request_irq(irq,hand,flg,dev,id) request_irq((irq),(hand),(flg),(dev),(id))
#define ide_free_irq(irq,dev_id) free_irq((irq), (dev_id))
-#define ide_check_region(from,extent) check_region((from), (extent))
#define ide_request_region(from,extent,name) request_region((from), (extent), (name))
#define ide_release_region(from,extent) release_region((from), (extent))
/* Generic I/O and MEMIO string operations. */
diff --git a/include/asm-parisc/led.h b/include/asm-parisc/led.h
index 1ac8ab6c580d..efadfd543ec6 100644
--- a/include/asm-parisc/led.h
+++ b/include/asm-parisc/led.h
@@ -23,9 +23,6 @@
#define LED_CMD_REG_NONE 0 /* NULL == no addr for the cmd register */
-/* led tasklet struct */
-extern struct tasklet_struct led_tasklet;
-
/* register_led_driver() */
int __init register_led_driver(int model, unsigned long cmd_reg, unsigned long data_reg);
diff --git a/include/asm-parisc/mmzone.h b/include/asm-parisc/mmzone.h
index 595d3dce120a..ae039f4fd711 100644
--- a/include/asm-parisc/mmzone.h
+++ b/include/asm-parisc/mmzone.h
@@ -27,12 +27,6 @@ extern struct node_map_data node_data[];
})
#define node_localnr(pfn, nid) ((pfn) - node_start_pfn(nid))
-#define local_mapnr(kvaddr) \
-({ \
- unsigned long __pfn = __pa(kvaddr) >> PAGE_SHIFT; \
- (__pfn - node_start_pfn(pfn_to_nid(__pfn))); \
-})
-
#define pfn_to_page(pfn) \
({ \
unsigned long __pfn = (pfn); \
diff --git a/include/asm-parisc/parisc-device.h b/include/asm-parisc/parisc-device.h
index ef69ab4b17a9..1d247e32a608 100644
--- a/include/asm-parisc/parisc-device.h
+++ b/include/asm-parisc/parisc-device.h
@@ -1,7 +1,7 @@
#include <linux/device.h>
struct parisc_device {
- unsigned long hpa; /* Hard Physical Address */
+ struct resource hpa; /* Hard Physical Address */
struct parisc_device_id id;
struct parisc_driver *driver; /* Driver for this device */
char name[80]; /* The hardware description */
@@ -39,6 +39,11 @@ struct parisc_driver {
#define to_parisc_driver(d) container_of(d, struct parisc_driver, drv)
#define parisc_parent(d) to_parisc_device(d->dev.parent)
+static inline char *parisc_pathname(struct parisc_device *d)
+{
+ return d->dev.bus_id;
+}
+
static inline void
parisc_set_drvdata(struct parisc_device *d, void *p)
{
diff --git a/include/asm-parisc/pci.h b/include/asm-parisc/pci.h
index d0b761f690b5..fa39d07d49e9 100644
--- a/include/asm-parisc/pci.h
+++ b/include/asm-parisc/pci.h
@@ -69,7 +69,7 @@ struct pci_hba_data {
#define PCI_PORT_HBA(a) ((a) >> HBA_PORT_SPACE_BITS)
#define PCI_PORT_ADDR(a) ((a) & (HBA_PORT_SPACE_SIZE - 1))
-#if CONFIG_64BIT
+#ifdef CONFIG_64BIT
#define PCI_F_EXTEND 0xffffffff00000000UL
#define PCI_IS_LMMIO(hba,a) pci_is_lmmio(hba,a)
diff --git a/include/asm-parisc/pgtable.h b/include/asm-parisc/pgtable.h
index 820c6e712cd7..b4554711c3e7 100644
--- a/include/asm-parisc/pgtable.h
+++ b/include/asm-parisc/pgtable.h
@@ -12,6 +12,7 @@
*/
#include <linux/spinlock.h>
+#include <linux/mm.h> /* for vm_area_struct */
#include <asm/processor.h>
#include <asm/cache.h>
#include <asm/bitops.h>
@@ -418,7 +419,6 @@ extern void paging_init (void);
#define PG_dcache_dirty PG_arch_1
-struct vm_area_struct; /* forward declaration (include/linux/mm.h) */
extern void update_mmu_cache(struct vm_area_struct *, unsigned long, pte_t);
/* Encode and de-code a swap entry */
@@ -464,6 +464,7 @@ static inline int ptep_test_and_clear_dirty(struct vm_area_struct *vma, unsigned
extern spinlock_t pa_dbit_lock;
+struct mm_struct;
static inline pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
{
pte_t old_pte;
@@ -501,6 +502,8 @@ static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr,
#define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \
remap_pfn_range(vma, vaddr, pfn, size, prot)
+#define pgprot_noncached(prot) __pgprot(pgprot_val(prot) | _PAGE_NO_CACHE)
+
#define MK_IOSPACE_PFN(space, pfn) (pfn)
#define GET_IOSPACE(pfn) 0
#define GET_PFN(pfn) (pfn)
diff --git a/include/asm-parisc/processor.h b/include/asm-parisc/processor.h
index a9dfadd05658..aae40e8c3aa8 100644
--- a/include/asm-parisc/processor.h
+++ b/include/asm-parisc/processor.h
@@ -122,8 +122,27 @@ struct thread_struct {
};
/* Thread struct flags. */
+#define PARISC_UAC_NOPRINT (1UL << 0) /* see prctl and unaligned.c */
+#define PARISC_UAC_SIGBUS (1UL << 1)
#define PARISC_KERNEL_DEATH (1UL << 31) /* see die_if_kernel()... */
+#define PARISC_UAC_SHIFT 0
+#define PARISC_UAC_MASK (PARISC_UAC_NOPRINT|PARISC_UAC_SIGBUS)
+
+#define SET_UNALIGN_CTL(task,value) \
+ ({ \
+ (task)->thread.flags = (((task)->thread.flags & ~PARISC_UAC_MASK) \
+ | (((value) << PARISC_UAC_SHIFT) & \
+ PARISC_UAC_MASK)); \
+ 0; \
+ })
+
+#define GET_UNALIGN_CTL(task,addr) \
+ ({ \
+ put_user(((task)->thread.flags & PARISC_UAC_MASK) \
+ >> PARISC_UAC_SHIFT, (int __user *) (addr)); \
+ })
+
#define INIT_THREAD { \
regs: { gr: { 0, }, \
fr: { 0, }, \
diff --git a/include/asm-parisc/psw.h b/include/asm-parisc/psw.h
index 51323029f377..4334d6ca2add 100644
--- a/include/asm-parisc/psw.h
+++ b/include/asm-parisc/psw.h
@@ -1,4 +1,7 @@
#ifndef _PARISC_PSW_H
+
+#include <linux/config.h>
+
#define PSW_I 0x00000001
#define PSW_D 0x00000002
#define PSW_P 0x00000004
@@ -9,6 +12,16 @@
#define PSW_G 0x00000040 /* PA1.x only */
#define PSW_O 0x00000080 /* PA2.0 only */
+/* ssm/rsm instructions number PSW_W and PSW_E differently */
+#define PSW_SM_I PSW_I /* Enable External Interrupts */
+#define PSW_SM_D PSW_D
+#define PSW_SM_P PSW_P
+#define PSW_SM_Q PSW_Q /* Enable Interrupt State Collection */
+#define PSW_SM_R PSW_R /* Enable Recover Counter Trap */
+#define PSW_SM_W 0x200 /* PA2.0 only : Enable Wide Mode */
+
+#define PSW_SM_QUIET PSW_SM_R+PSW_SM_Q+PSW_SM_P+PSW_SM_D+PSW_SM_I
+
#define PSW_CB 0x0000ff00
#define PSW_M 0x00010000
@@ -30,33 +43,21 @@
#define PSW_Z 0x40000000 /* PA1.x only */
#define PSW_Y 0x80000000 /* PA1.x only */
-#ifdef __LP64__
-#define PSW_HI_CB 0x000000ff /* PA2.0 only */
+#ifdef CONFIG_64BIT
+# define PSW_HI_CB 0x000000ff /* PA2.0 only */
#endif
-/* PSW bits to be used with ssm/rsm */
-#define PSW_SM_I 0x1
-#define PSW_SM_D 0x2
-#define PSW_SM_P 0x4
-#define PSW_SM_Q 0x8
-#define PSW_SM_R 0x10
-#define PSW_SM_F 0x20
-#define PSW_SM_G 0x40
-#define PSW_SM_O 0x80
-#define PSW_SM_E 0x100
-#define PSW_SM_W 0x200
-
-#ifdef __LP64__
-# define USER_PSW (PSW_C | PSW_Q | PSW_P | PSW_D | PSW_I)
-# define KERNEL_PSW (PSW_W | PSW_C | PSW_Q | PSW_P | PSW_D)
-# define REAL_MODE_PSW (PSW_W | PSW_Q)
-# define USER_PSW_MASK (PSW_W | PSW_T | PSW_N | PSW_X | PSW_B | PSW_V | PSW_CB)
-# define USER_PSW_HI_MASK (PSW_HI_CB)
-#else
-# define USER_PSW (PSW_C | PSW_Q | PSW_P | PSW_D | PSW_I)
-# define KERNEL_PSW (PSW_C | PSW_Q | PSW_P | PSW_D)
-# define REAL_MODE_PSW (PSW_Q)
-# define USER_PSW_MASK (PSW_T | PSW_N | PSW_X | PSW_B | PSW_V | PSW_CB)
+#ifdef CONFIG_64BIT
+# define USER_PSW_HI_MASK PSW_HI_CB
+# define WIDE_PSW PSW_W
+#else
+# define WIDE_PSW 0
#endif
+/* Used when setting up for rfi */
+#define KERNEL_PSW (WIDE_PSW | PSW_C | PSW_Q | PSW_P | PSW_D)
+#define REAL_MODE_PSW (WIDE_PSW | PSW_Q)
+#define USER_PSW_MASK (WIDE_PSW | PSW_T | PSW_N | PSW_X | PSW_B | PSW_V | PSW_CB)
+#define USER_PSW (PSW_C | PSW_Q | PSW_P | PSW_D | PSW_I)
+
#endif
diff --git a/include/asm-parisc/ptrace.h b/include/asm-parisc/ptrace.h
index 3f428aa371a4..93f990e418f1 100644
--- a/include/asm-parisc/ptrace.h
+++ b/include/asm-parisc/ptrace.h
@@ -49,7 +49,7 @@ struct pt_regs {
#define user_mode(regs) (((regs)->iaoq[0] & 3) ? 1 : 0)
#define user_space(regs) (((regs)->iasq[1] != 0) ? 1 : 0)
#define instruction_pointer(regs) ((regs)->iaoq[0] & ~3)
-#define profile_pc(regs) instruction_pointer(regs)
+unsigned long profile_pc(struct pt_regs *);
extern void show_regs(struct pt_regs *);
#endif
diff --git a/include/asm-parisc/semaphore.h b/include/asm-parisc/semaphore.h
index f78bb2e34538..c9ee41cd0707 100644
--- a/include/asm-parisc/semaphore.h
+++ b/include/asm-parisc/semaphore.h
@@ -49,9 +49,6 @@ struct semaphore {
.wait = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \
}
-#define __MUTEX_INITIALIZER(name) \
- __SEMAPHORE_INITIALIZER(name,1)
-
#define __DECLARE_SEMAPHORE_GENERIC(name,count) \
struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
diff --git a/include/asm-parisc/spinlock.h b/include/asm-parisc/spinlock.h
index 43eaa6e742e0..7c3f406a746a 100644
--- a/include/asm-parisc/spinlock.h
+++ b/include/asm-parisc/spinlock.h
@@ -5,11 +5,6 @@
#include <asm/processor.h>
#include <asm/spinlock_types.h>
-/* Note that PA-RISC has to use `1' to mean unlocked and `0' to mean locked
- * since it only has load-and-zero. Moreover, at least on some PA processors,
- * the semaphore address has to be 16-byte aligned.
- */
-
static inline int __raw_spin_is_locked(raw_spinlock_t *x)
{
volatile unsigned int *a = __ldcw_align(x);
diff --git a/include/asm-parisc/spinlock_types.h b/include/asm-parisc/spinlock_types.h
index 785bba822fbf..d6b479bdb886 100644
--- a/include/asm-parisc/spinlock_types.h
+++ b/include/asm-parisc/spinlock_types.h
@@ -6,11 +6,15 @@
#endif
typedef struct {
+#ifdef CONFIG_PA20
+ volatile unsigned int slock;
+# define __RAW_SPIN_LOCK_UNLOCKED { 1 }
+#else
volatile unsigned int lock[4];
+# define __RAW_SPIN_LOCK_UNLOCKED { { 1, 1, 1, 1 } }
+#endif
} raw_spinlock_t;
-#define __RAW_SPIN_LOCK_UNLOCKED { { 1, 1, 1, 1 } }
-
typedef struct {
raw_spinlock_t lock;
volatile int counter;
diff --git a/include/asm-parisc/system.h b/include/asm-parisc/system.h
index 26ff844a21c1..f3928d3a80cb 100644
--- a/include/asm-parisc/system.h
+++ b/include/asm-parisc/system.h
@@ -138,13 +138,7 @@ static inline void set_eiem(unsigned long val)
#define set_wmb(var, value) do { var = value; wmb(); } while (0)
-/* LDCW, the only atomic read-write operation PA-RISC has. *sigh*. */
-#define __ldcw(a) ({ \
- unsigned __ret; \
- __asm__ __volatile__("ldcw 0(%1),%0" : "=r" (__ret) : "r" (a)); \
- __ret; \
-})
-
+#ifndef CONFIG_PA20
/* Because kmalloc only guarantees 8-byte alignment for kmalloc'd data,
and GCC only guarantees 8-byte alignment for stack locals, we can't
be assured of 16-byte alignment for atomic lock data even if we
@@ -152,37 +146,41 @@ static inline void set_eiem(unsigned long val)
we use a struct containing an array of four ints for the atomic lock
type and dynamically select the 16-byte aligned int from the array
for the semaphore. */
+
#define __PA_LDCW_ALIGNMENT 16
#define __ldcw_align(a) ({ \
unsigned long __ret = (unsigned long) &(a)->lock[0]; \
__ret = (__ret + __PA_LDCW_ALIGNMENT - 1) & ~(__PA_LDCW_ALIGNMENT - 1); \
(volatile unsigned int *) __ret; \
})
+#define LDCW "ldcw"
-#ifdef CONFIG_SMP
-# define __lock_aligned __attribute__((__section__(".data.lock_aligned")))
-#endif
+#else /*CONFIG_PA20*/
+/* From: "Jim Hull" <jim.hull of hp.com>
+ I've attached a summary of the change, but basically, for PA 2.0, as
+ long as the ",CO" (coherent operation) completer is specified, then the
+ 16-byte alignment requirement for ldcw and ldcd is relaxed, and instead
+ they only require "natural" alignment (4-byte for ldcw, 8-byte for
+ ldcd). */
-#define KERNEL_START (0x10100000 - 0x1000)
+#define __PA_LDCW_ALIGNMENT 4
+#define __ldcw_align(a) ((volatile unsigned int *)a)
+#define LDCW "ldcw,co"
-/* This is for the serialisation of PxTLB broadcasts. At least on the
- * N class systems, only one PxTLB inter processor broadcast can be
- * active at any one time on the Merced bus. This tlb purge
- * synchronisation is fairly lightweight and harmless so we activate
- * it on all SMP systems not just the N class. */
-#ifdef CONFIG_SMP
-extern spinlock_t pa_tlb_lock;
+#endif /*!CONFIG_PA20*/
-#define purge_tlb_start(x) spin_lock(&pa_tlb_lock)
-#define purge_tlb_end(x) spin_unlock(&pa_tlb_lock)
-
-#else
-
-#define purge_tlb_start(x) do { } while(0)
-#define purge_tlb_end(x) do { } while (0)
+/* LDCW, the only atomic read-write operation PA-RISC has. *sigh*. */
+#define __ldcw(a) ({ \
+ unsigned __ret; \
+ __asm__ __volatile__(LDCW " 0(%1),%0" : "=r" (__ret) : "r" (a)); \
+ __ret; \
+})
+#ifdef CONFIG_SMP
+# define __lock_aligned __attribute__((__section__(".data.lock_aligned")))
#endif
+#define KERNEL_START (0x10100000 - 0x1000)
#define arch_align_stack(x) (x)
#endif
diff --git a/include/asm-parisc/tlbflush.h b/include/asm-parisc/tlbflush.h
index eb27b78930e8..e97aa8d1eff5 100644
--- a/include/asm-parisc/tlbflush.h
+++ b/include/asm-parisc/tlbflush.h
@@ -7,6 +7,26 @@
#include <linux/mm.h>
#include <asm/mmu_context.h>
+
+/* This is for the serialisation of PxTLB broadcasts. At least on the
+ * N class systems, only one PxTLB inter processor broadcast can be
+ * active at any one time on the Merced bus. This tlb purge
+ * synchronisation is fairly lightweight and harmless so we activate
+ * it on all SMP systems not just the N class. */
+#ifdef CONFIG_SMP
+extern spinlock_t pa_tlb_lock;
+
+#define purge_tlb_start(x) spin_lock(&pa_tlb_lock)
+#define purge_tlb_end(x) spin_unlock(&pa_tlb_lock)
+
+#else
+
+#define purge_tlb_start(x) do { } while(0)
+#define purge_tlb_end(x) do { } while (0)
+
+#endif
+
+
extern void flush_tlb_all(void);
/*
@@ -64,29 +84,27 @@ static inline void flush_tlb_range(struct vm_area_struct *vma,
{
unsigned long npages;
-
npages = ((end - (start & PAGE_MASK)) + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
- if (npages >= 512) /* XXX arbitrary, should be tuned */
+ if (npages >= 512) /* 2MB of space: arbitrary, should be tuned */
flush_tlb_all();
else {
-
+ preempt_disable();
mtsp(vma->vm_mm->context,1);
+ purge_tlb_start();
if (split_tlb) {
- purge_tlb_start();
while (npages--) {
pdtlb(start);
pitlb(start);
start += PAGE_SIZE;
}
- purge_tlb_end();
} else {
- purge_tlb_start();
while (npages--) {
pdtlb(start);
start += PAGE_SIZE;
}
- purge_tlb_end();
+ preempt_enable();
}
+ purge_tlb_end();
}
}
diff --git a/include/asm-parisc/types.h b/include/asm-parisc/types.h
index d21b9d0d63ea..34fdce361a5a 100644
--- a/include/asm-parisc/types.h
+++ b/include/asm-parisc/types.h
@@ -33,8 +33,10 @@ typedef unsigned long long __u64;
#ifdef __LP64__
#define BITS_PER_LONG 64
+#define SHIFT_PER_LONG 6
#else
#define BITS_PER_LONG 32
+#define SHIFT_PER_LONG 5
#endif
#ifndef __ASSEMBLY__
diff --git a/include/asm-parisc/unistd.h b/include/asm-parisc/unistd.h
index 6a9f0cadff58..80b7b98c70a1 100644
--- a/include/asm-parisc/unistd.h
+++ b/include/asm-parisc/unistd.h
@@ -687,8 +687,8 @@
#define __NR_shmget (__NR_Linux + 194)
#define __NR_shmctl (__NR_Linux + 195)
-#define __NR_getpmsg (__NR_Linux + 196) /* some people actually want streams */
-#define __NR_putpmsg (__NR_Linux + 197) /* some people actually want streams */
+#define __NR_getpmsg (__NR_Linux + 196) /* Somebody *wants* streams? */
+#define __NR_putpmsg (__NR_Linux + 197)
#define __NR_lstat64 (__NR_Linux + 198)
#define __NR_truncate64 (__NR_Linux + 199)
@@ -755,8 +755,14 @@
#define __NR_mbind (__NR_Linux + 260)
#define __NR_get_mempolicy (__NR_Linux + 261)
#define __NR_set_mempolicy (__NR_Linux + 262)
+#define __NR_vserver (__NR_Linux + 263)
+#define __NR_add_key (__NR_Linux + 264)
+#define __NR_request_key (__NR_Linux + 265)
+#define __NR_keyctl (__NR_Linux + 266)
+#define __NR_ioprio_set (__NR_Linux + 267)
+#define __NR_ioprio_get (__NR_Linux + 268)
-#define __NR_Linux_syscalls 263
+#define __NR_Linux_syscalls 269
#define HPUX_GATEWAY_ADDR 0xC0000004
#define LINUX_GATEWAY_ADDR 0x100
@@ -807,10 +813,10 @@
#define K_INLINE_SYSCALL(name, nr, args...) ({ \
long __sys_res; \
{ \
- register unsigned long __res asm("r28"); \
+ register unsigned long __res __asm__("r28"); \
K_LOAD_ARGS_##nr(args) \
/* FIXME: HACK stw/ldw r19 around syscall */ \
- asm volatile( \
+ __asm__ volatile( \
K_STW_ASM_PIC \
" ble 0x100(%%sr2, %%r0)\n" \
" ldi %1, %%r20\n" \
@@ -1005,7 +1011,6 @@ int sys_clone(unsigned long clone_flags, unsigned long usp,
struct pt_regs *regs);
int sys_vfork(struct pt_regs *regs);
int sys_pipe(int *fildes);
-long sys_ptrace(long request, pid_t pid, long addr, long data);
struct sigaction;
asmlinkage long sys_rt_sigaction(int sig,
const struct sigaction __user *act,
diff --git a/include/asm-ppc64/a.out.h b/include/asm-powerpc/a.out.h
index 3871e252a6f1..c7393a977364 100644
--- a/include/asm-ppc64/a.out.h
+++ b/include/asm-powerpc/a.out.h
@@ -1,14 +1,5 @@
-#ifndef __PPC64_A_OUT_H__
-#define __PPC64_A_OUT_H__
-
-/*
- * c 2001 PPC 64 Team, IBM Corp
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
+#ifndef _ASM_POWERPC_A_OUT_H
+#define _ASM_POWERPC_A_OUT_H
struct exec
{
@@ -27,6 +18,7 @@ struct exec
#define N_SYMSIZE(a) ((a).a_syms)
#ifdef __KERNEL__
+#ifdef __powerpc64__
#define STACK_TOP_USER64 TASK_SIZE_USER64
#define STACK_TOP_USER32 TASK_SIZE_USER32
@@ -34,6 +26,11 @@ struct exec
#define STACK_TOP (test_thread_flag(TIF_32BIT) ? \
STACK_TOP_USER32 : STACK_TOP_USER64)
+#else /* __powerpc64__ */
+
+#define STACK_TOP TASK_SIZE
+
+#endif /* __powerpc64__ */
#endif /* __KERNEL__ */
-#endif /* __PPC64_A_OUT_H__ */
+#endif /* _ASM_POWERPC_A_OUT_H */
diff --git a/include/asm-ppc64/abs_addr.h b/include/asm-powerpc/abs_addr.h
index 84c24d4cdb71..18415108fc56 100644
--- a/include/asm-ppc64/abs_addr.h
+++ b/include/asm-powerpc/abs_addr.h
@@ -1,5 +1,5 @@
-#ifndef _ABS_ADDR_H
-#define _ABS_ADDR_H
+#ifndef _ASM_POWERPC_ABS_ADDR_H
+#define _ASM_POWERPC_ABS_ADDR_H
#include <linux/config.h>
@@ -63,4 +63,11 @@ static inline unsigned long phys_to_abs(unsigned long pa)
#define virt_to_abs(va) phys_to_abs(__pa(va))
#define abs_to_virt(aa) __va(aa)
-#endif /* _ABS_ADDR_H */
+/*
+ * Converts Virtual Address to Real Address for
+ * Legacy iSeries Hypervisor calls
+ */
+#define iseries_hv_addr(virtaddr) \
+ (0x8000000000000000 | virt_to_abs(virtaddr))
+
+#endif /* _ASM_POWERPC_ABS_ADDR_H */
diff --git a/include/asm-powerpc/asm-compat.h b/include/asm-powerpc/asm-compat.h
new file mode 100644
index 000000000000..8b133efc9f79
--- /dev/null
+++ b/include/asm-powerpc/asm-compat.h
@@ -0,0 +1,55 @@
+#ifndef _ASM_POWERPC_ASM_COMPAT_H
+#define _ASM_POWERPC_ASM_COMPAT_H
+
+#include <linux/config.h>
+#include <asm/types.h>
+
+#ifdef __ASSEMBLY__
+# define stringify_in_c(...) __VA_ARGS__
+# define ASM_CONST(x) x
+#else
+/* This version of stringify will deal with commas... */
+# define __stringify_in_c(...) #__VA_ARGS__
+# define stringify_in_c(...) __stringify_in_c(__VA_ARGS__) " "
+# define __ASM_CONST(x) x##UL
+# define ASM_CONST(x) __ASM_CONST(x)
+#endif
+
+#ifdef __powerpc64__
+
+/* operations for longs and pointers */
+#define PPC_LL stringify_in_c(ld)
+#define PPC_STL stringify_in_c(std)
+#define PPC_LCMPI stringify_in_c(cmpdi)
+#define PPC_LONG stringify_in_c(.llong)
+#define PPC_TLNEI stringify_in_c(tdnei)
+#define PPC_LLARX stringify_in_c(ldarx)
+#define PPC_STLCX stringify_in_c(stdcx.)
+#define PPC_CNTLZL stringify_in_c(cntlzd)
+
+#else /* 32-bit */
+
+/* operations for longs and pointers */
+#define PPC_LL stringify_in_c(lwz)
+#define PPC_STL stringify_in_c(stw)
+#define PPC_LCMPI stringify_in_c(cmpwi)
+#define PPC_LONG stringify_in_c(.long)
+#define PPC_TLNEI stringify_in_c(twnei)
+#define PPC_LLARX stringify_in_c(lwarx)
+#define PPC_STLCX stringify_in_c(stwcx.)
+#define PPC_CNTLZL stringify_in_c(cntlzw)
+
+#endif
+
+#ifdef CONFIG_IBM405_ERR77
+/* Erratum #77 on the 405 means we need a sync or dcbt before every
+ * stwcx. The old ATOMIC_SYNC_FIX covered some but not all of this.
+ */
+#define PPC405_ERR77(ra,rb) stringify_in_c(dcbt ra, rb;)
+#define PPC405_ERR77_SYNC stringify_in_c(sync;)
+#else
+#define PPC405_ERR77(ra,rb)
+#define PPC405_ERR77_SYNC
+#endif
+
+#endif /* _ASM_POWERPC_ASM_COMPAT_H */
diff --git a/include/asm-powerpc/atomic.h b/include/asm-powerpc/atomic.h
new file mode 100644
index 000000000000..9c0b372a46e1
--- /dev/null
+++ b/include/asm-powerpc/atomic.h
@@ -0,0 +1,379 @@
+#ifndef _ASM_POWERPC_ATOMIC_H_
+#define _ASM_POWERPC_ATOMIC_H_
+
+/*
+ * PowerPC atomic operations
+ */
+
+typedef struct { volatile int counter; } atomic_t;
+
+#ifdef __KERNEL__
+#include <asm/synch.h>
+#include <asm/asm-compat.h>
+
+#define ATOMIC_INIT(i) { (i) }
+
+#define atomic_read(v) ((v)->counter)
+#define atomic_set(v,i) (((v)->counter) = (i))
+
+static __inline__ void atomic_add(int a, atomic_t *v)
+{
+ int t;
+
+ __asm__ __volatile__(
+"1: lwarx %0,0,%3 # atomic_add\n\
+ add %0,%2,%0\n"
+ PPC405_ERR77(0,%3)
+" stwcx. %0,0,%3 \n\
+ bne- 1b"
+ : "=&r" (t), "=m" (v->counter)
+ : "r" (a), "r" (&v->counter), "m" (v->counter)
+ : "cc");
+}
+
+static __inline__ int atomic_add_return(int a, atomic_t *v)
+{
+ int t;
+
+ __asm__ __volatile__(
+ EIEIO_ON_SMP
+"1: lwarx %0,0,%2 # atomic_add_return\n\
+ add %0,%1,%0\n"
+ PPC405_ERR77(0,%2)
+" stwcx. %0,0,%2 \n\
+ bne- 1b"
+ ISYNC_ON_SMP
+ : "=&r" (t)
+ : "r" (a), "r" (&v->counter)
+ : "cc", "memory");
+
+ return t;
+}
+
+#define atomic_add_negative(a, v) (atomic_add_return((a), (v)) < 0)
+
+static __inline__ void atomic_sub(int a, atomic_t *v)
+{
+ int t;
+
+ __asm__ __volatile__(
+"1: lwarx %0,0,%3 # atomic_sub\n\
+ subf %0,%2,%0\n"
+ PPC405_ERR77(0,%3)
+" stwcx. %0,0,%3 \n\
+ bne- 1b"
+ : "=&r" (t), "=m" (v->counter)
+ : "r" (a), "r" (&v->counter), "m" (v->counter)
+ : "cc");
+}
+
+static __inline__ int atomic_sub_return(int a, atomic_t *v)
+{
+ int t;
+
+ __asm__ __volatile__(
+ EIEIO_ON_SMP
+"1: lwarx %0,0,%2 # atomic_sub_return\n\
+ subf %0,%1,%0\n"
+ PPC405_ERR77(0,%2)
+" stwcx. %0,0,%2 \n\
+ bne- 1b"
+ ISYNC_ON_SMP
+ : "=&r" (t)
+ : "r" (a), "r" (&v->counter)
+ : "cc", "memory");
+
+ return t;
+}
+
+static __inline__ void atomic_inc(atomic_t *v)
+{
+ int t;
+
+ __asm__ __volatile__(
+"1: lwarx %0,0,%2 # atomic_inc\n\
+ addic %0,%0,1\n"
+ PPC405_ERR77(0,%2)
+" stwcx. %0,0,%2 \n\
+ bne- 1b"
+ : "=&r" (t), "=m" (v->counter)
+ : "r" (&v->counter), "m" (v->counter)
+ : "cc");
+}
+
+static __inline__ int atomic_inc_return(atomic_t *v)
+{
+ int t;
+
+ __asm__ __volatile__(
+ EIEIO_ON_SMP
+"1: lwarx %0,0,%1 # atomic_inc_return\n\
+ addic %0,%0,1\n"
+ PPC405_ERR77(0,%1)
+" stwcx. %0,0,%1 \n\
+ bne- 1b"
+ ISYNC_ON_SMP
+ : "=&r" (t)
+ : "r" (&v->counter)
+ : "cc", "memory");
+
+ return t;
+}
+
+/*
+ * atomic_inc_and_test - increment and test
+ * @v: pointer of type atomic_t
+ *
+ * Atomically increments @v by 1
+ * and returns true if the result is zero, or false for all
+ * other cases.
+ */
+#define atomic_inc_and_test(v) (atomic_inc_return(v) == 0)
+
+static __inline__ void atomic_dec(atomic_t *v)
+{
+ int t;
+
+ __asm__ __volatile__(
+"1: lwarx %0,0,%2 # atomic_dec\n\
+ addic %0,%0,-1\n"
+ PPC405_ERR77(0,%2)\
+" stwcx. %0,0,%2\n\
+ bne- 1b"
+ : "=&r" (t), "=m" (v->counter)
+ : "r" (&v->counter), "m" (v->counter)
+ : "cc");
+}
+
+static __inline__ int atomic_dec_return(atomic_t *v)
+{
+ int t;
+
+ __asm__ __volatile__(
+ EIEIO_ON_SMP
+"1: lwarx %0,0,%1 # atomic_dec_return\n\
+ addic %0,%0,-1\n"
+ PPC405_ERR77(0,%1)
+" stwcx. %0,0,%1\n\
+ bne- 1b"
+ ISYNC_ON_SMP
+ : "=&r" (t)
+ : "r" (&v->counter)
+ : "cc", "memory");
+
+ return t;
+}
+
+#define atomic_sub_and_test(a, v) (atomic_sub_return((a), (v)) == 0)
+#define atomic_dec_and_test(v) (atomic_dec_return((v)) == 0)
+
+/*
+ * Atomically test *v and decrement if it is greater than 0.
+ * The function returns the old value of *v minus 1.
+ */
+static __inline__ int atomic_dec_if_positive(atomic_t *v)
+{
+ int t;
+
+ __asm__ __volatile__(
+ EIEIO_ON_SMP
+"1: lwarx %0,0,%1 # atomic_dec_if_positive\n\
+ addic. %0,%0,-1\n\
+ blt- 2f\n"
+ PPC405_ERR77(0,%1)
+" stwcx. %0,0,%1\n\
+ bne- 1b"
+ ISYNC_ON_SMP
+ "\n\
+2:" : "=&r" (t)
+ : "r" (&v->counter)
+ : "cc", "memory");
+
+ return t;
+}
+
+#define smp_mb__before_atomic_dec() smp_mb()
+#define smp_mb__after_atomic_dec() smp_mb()
+#define smp_mb__before_atomic_inc() smp_mb()
+#define smp_mb__after_atomic_inc() smp_mb()
+
+#ifdef __powerpc64__
+
+typedef struct { volatile long counter; } atomic64_t;
+
+#define ATOMIC64_INIT(i) { (i) }
+
+#define atomic64_read(v) ((v)->counter)
+#define atomic64_set(v,i) (((v)->counter) = (i))
+
+static __inline__ void atomic64_add(long a, atomic64_t *v)
+{
+ long t;
+
+ __asm__ __volatile__(
+"1: ldarx %0,0,%3 # atomic64_add\n\
+ add %0,%2,%0\n\
+ stdcx. %0,0,%3 \n\
+ bne- 1b"
+ : "=&r" (t), "=m" (v->counter)
+ : "r" (a), "r" (&v->counter), "m" (v->counter)
+ : "cc");
+}
+
+static __inline__ long atomic64_add_return(long a, atomic64_t *v)
+{
+ long t;
+
+ __asm__ __volatile__(
+ EIEIO_ON_SMP
+"1: ldarx %0,0,%2 # atomic64_add_return\n\
+ add %0,%1,%0\n\
+ stdcx. %0,0,%2 \n\
+ bne- 1b"
+ ISYNC_ON_SMP
+ : "=&r" (t)
+ : "r" (a), "r" (&v->counter)
+ : "cc", "memory");
+
+ return t;
+}
+
+#define atomic64_add_negative(a, v) (atomic64_add_return((a), (v)) < 0)
+
+static __inline__ void atomic64_sub(long a, atomic64_t *v)
+{
+ long t;
+
+ __asm__ __volatile__(
+"1: ldarx %0,0,%3 # atomic64_sub\n\
+ subf %0,%2,%0\n\
+ stdcx. %0,0,%3 \n\
+ bne- 1b"
+ : "=&r" (t), "=m" (v->counter)
+ : "r" (a), "r" (&v->counter), "m" (v->counter)
+ : "cc");
+}
+
+static __inline__ long atomic64_sub_return(long a, atomic64_t *v)
+{
+ long t;
+
+ __asm__ __volatile__(
+ EIEIO_ON_SMP
+"1: ldarx %0,0,%2 # atomic64_sub_return\n\
+ subf %0,%1,%0\n\
+ stdcx. %0,0,%2 \n\
+ bne- 1b"
+ ISYNC_ON_SMP
+ : "=&r" (t)
+ : "r" (a), "r" (&v->counter)
+ : "cc", "memory");
+
+ return t;
+}
+
+static __inline__ void atomic64_inc(atomic64_t *v)
+{
+ long t;
+
+ __asm__ __volatile__(
+"1: ldarx %0,0,%2 # atomic64_inc\n\
+ addic %0,%0,1\n\
+ stdcx. %0,0,%2 \n\
+ bne- 1b"
+ : "=&r" (t), "=m" (v->counter)
+ : "r" (&v->counter), "m" (v->counter)
+ : "cc");
+}
+
+static __inline__ long atomic64_inc_return(atomic64_t *v)
+{
+ long t;
+
+ __asm__ __volatile__(
+ EIEIO_ON_SMP
+"1: ldarx %0,0,%1 # atomic64_inc_return\n\
+ addic %0,%0,1\n\
+ stdcx. %0,0,%1 \n\
+ bne- 1b"
+ ISYNC_ON_SMP
+ : "=&r" (t)
+ : "r" (&v->counter)
+ : "cc", "memory");
+
+ return t;
+}
+
+/*
+ * atomic64_inc_and_test - increment and test
+ * @v: pointer of type atomic64_t
+ *
+ * Atomically increments @v by 1
+ * and returns true if the result is zero, or false for all
+ * other cases.
+ */
+#define atomic64_inc_and_test(v) (atomic64_inc_return(v) == 0)
+
+static __inline__ void atomic64_dec(atomic64_t *v)
+{
+ long t;
+
+ __asm__ __volatile__(
+"1: ldarx %0,0,%2 # atomic64_dec\n\
+ addic %0,%0,-1\n\
+ stdcx. %0,0,%2\n\
+ bne- 1b"
+ : "=&r" (t), "=m" (v->counter)
+ : "r" (&v->counter), "m" (v->counter)
+ : "cc");
+}
+
+static __inline__ long atomic64_dec_return(atomic64_t *v)
+{
+ long t;
+
+ __asm__ __volatile__(
+ EIEIO_ON_SMP
+"1: ldarx %0,0,%1 # atomic64_dec_return\n\
+ addic %0,%0,-1\n\
+ stdcx. %0,0,%1\n\
+ bne- 1b"
+ ISYNC_ON_SMP
+ : "=&r" (t)
+ : "r" (&v->counter)
+ : "cc", "memory");
+
+ return t;
+}
+
+#define atomic64_sub_and_test(a, v) (atomic64_sub_return((a), (v)) == 0)
+#define atomic64_dec_and_test(v) (atomic64_dec_return((v)) == 0)
+
+/*
+ * Atomically test *v and decrement if it is greater than 0.
+ * The function returns the old value of *v minus 1.
+ */
+static __inline__ long atomic64_dec_if_positive(atomic64_t *v)
+{
+ long t;
+
+ __asm__ __volatile__(
+ EIEIO_ON_SMP
+"1: ldarx %0,0,%1 # atomic64_dec_if_positive\n\
+ addic. %0,%0,-1\n\
+ blt- 2f\n\
+ stdcx. %0,0,%1\n\
+ bne- 1b"
+ ISYNC_ON_SMP
+ "\n\
+2:" : "=&r" (t)
+ : "r" (&v->counter)
+ : "cc", "memory");
+
+ return t;
+}
+
+#endif /* __powerpc64__ */
+
+#endif /* __KERNEL__ */
+#endif /* _ASM_POWERPC_ATOMIC_H_ */
diff --git a/include/asm-ppc64/auxvec.h b/include/asm-powerpc/auxvec.h
index ac6381a106e1..79d8c4732309 100644
--- a/include/asm-ppc64/auxvec.h
+++ b/include/asm-powerpc/auxvec.h
@@ -1,5 +1,5 @@
-#ifndef __PPC64_AUXVEC_H
-#define __PPC64_AUXVEC_H
+#ifndef _ASM_POWERPC_AUXVEC_H
+#define _ASM_POWERPC_AUXVEC_H
/*
* We need to put in some extra aux table entries to tell glibc what
@@ -14,6 +14,8 @@
/* The vDSO location. We have to use the same value as x86 for glibc's
* sake :-)
*/
+#ifdef __powerpc64__
#define AT_SYSINFO_EHDR 33
+#endif
-#endif /* __PPC64_AUXVEC_H */
+#endif
diff --git a/include/asm-ppc/backlight.h b/include/asm-powerpc/backlight.h
index 3a1c3dede2a0..1ba1f27a0b63 100644
--- a/include/asm-ppc/backlight.h
+++ b/include/asm-powerpc/backlight.h
@@ -1,12 +1,13 @@
/*
* Routines for handling backlight control on PowerBooks
*
- * For now, implementation resides in arch/ppc/kernel/pmac_support.c
+ * For now, implementation resides in
+ * arch/powerpc/platforms/powermac/pmac_support.c
*
*/
+#ifndef __ASM_POWERPC_BACKLIGHT_H
+#define __ASM_POWERPC_BACKLIGHT_H
#ifdef __KERNEL__
-#ifndef __ASM_PPC_BACKLIGHT_H
-#define __ASM_PPC_BACKLIGHT_H
/* Abstract values */
#define BACKLIGHT_OFF 0
@@ -26,5 +27,5 @@ extern int get_backlight_enable(void);
extern int set_backlight_level(int level);
extern int get_backlight_level(void);
-#endif
#endif /* __KERNEL__ */
+#endif
diff --git a/include/asm-powerpc/bitops.h b/include/asm-powerpc/bitops.h
new file mode 100644
index 000000000000..5727229b0444
--- /dev/null
+++ b/include/asm-powerpc/bitops.h
@@ -0,0 +1,428 @@
+/*
+ * PowerPC atomic bit operations.
+ *
+ * Merged version by David Gibson <david@gibson.dropbear.id.au>.
+ * Based on ppc64 versions by: Dave Engebretsen, Todd Inglett, Don
+ * Reed, Pat McCarthy, Peter Bergner, Anton Blanchard. They
+ * originally took it from the ppc32 code.
+ *
+ * Within a word, bits are numbered LSB first. Lot's of places make
+ * this assumption by directly testing bits with (val & (1<<nr)).
+ * This can cause confusion for large (> 1 word) bitmaps on a
+ * big-endian system because, unlike little endian, the number of each
+ * bit depends on the word size.
+ *
+ * The bitop functions are defined to work on unsigned longs, so for a
+ * ppc64 system the bits end up numbered:
+ * |63..............0|127............64|191...........128|255...........196|
+ * and on ppc32:
+ * |31.....0|63....31|95....64|127...96|159..128|191..160|223..192|255..224|
+ *
+ * There are a few little-endian macros used mostly for filesystem
+ * bitmaps, these work on similar bit arrays layouts, but
+ * byte-oriented:
+ * |7...0|15...8|23...16|31...24|39...32|47...40|55...48|63...56|
+ *
+ * The main difference is that bit 3-5 (64b) or 3-4 (32b) in the bit
+ * number field needs to be reversed compared to the big-endian bit
+ * fields. This can be achieved by XOR with 0x38 (64b) or 0x18 (32b).
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_POWERPC_BITOPS_H
+#define _ASM_POWERPC_BITOPS_H
+
+#ifdef __KERNEL__
+
+#include <linux/compiler.h>
+#include <asm/atomic.h>
+#include <asm/asm-compat.h>
+#include <asm/synch.h>
+
+/*
+ * clear_bit doesn't imply a memory barrier
+ */
+#define smp_mb__before_clear_bit() smp_mb()
+#define smp_mb__after_clear_bit() smp_mb()
+
+#define BITOP_MASK(nr) (1UL << ((nr) % BITS_PER_LONG))
+#define BITOP_WORD(nr) ((nr) / BITS_PER_LONG)
+#define BITOP_LE_SWIZZLE ((BITS_PER_LONG-1) & ~0x7)
+
+static __inline__ void set_bit(int nr, volatile unsigned long *addr)
+{
+ unsigned long old;
+ unsigned long mask = BITOP_MASK(nr);
+ unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
+
+ __asm__ __volatile__(
+"1:" PPC_LLARX "%0,0,%3 # set_bit\n"
+ "or %0,%0,%2\n"
+ PPC405_ERR77(0,%3)
+ PPC_STLCX "%0,0,%3\n"
+ "bne- 1b"
+ : "=&r"(old), "=m"(*p)
+ : "r"(mask), "r"(p), "m"(*p)
+ : "cc" );
+}
+
+static __inline__ void clear_bit(int nr, volatile unsigned long *addr)
+{
+ unsigned long old;
+ unsigned long mask = BITOP_MASK(nr);
+ unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
+
+ __asm__ __volatile__(
+"1:" PPC_LLARX "%0,0,%3 # clear_bit\n"
+ "andc %0,%0,%2\n"
+ PPC405_ERR77(0,%3)
+ PPC_STLCX "%0,0,%3\n"
+ "bne- 1b"
+ : "=&r"(old), "=m"(*p)
+ : "r"(mask), "r"(p), "m"(*p)
+ : "cc" );
+}
+
+static __inline__ void change_bit(int nr, volatile unsigned long *addr)
+{
+ unsigned long old;
+ unsigned long mask = BITOP_MASK(nr);
+ unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
+
+ __asm__ __volatile__(
+"1:" PPC_LLARX "%0,0,%3 # change_bit\n"
+ "xor %0,%0,%2\n"
+ PPC405_ERR77(0,%3)
+ PPC_STLCX "%0,0,%3\n"
+ "bne- 1b"
+ : "=&r"(old), "=m"(*p)
+ : "r"(mask), "r"(p), "m"(*p)
+ : "cc" );
+}
+
+static __inline__ int test_and_set_bit(unsigned long nr,
+ volatile unsigned long *addr)
+{
+ unsigned long old, t;
+ unsigned long mask = BITOP_MASK(nr);
+ unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
+
+ __asm__ __volatile__(
+ EIEIO_ON_SMP
+"1:" PPC_LLARX "%0,0,%3 # test_and_set_bit\n"
+ "or %1,%0,%2 \n"
+ PPC405_ERR77(0,%3)
+ PPC_STLCX "%1,0,%3 \n"
+ "bne- 1b"
+ ISYNC_ON_SMP
+ : "=&r" (old), "=&r" (t)
+ : "r" (mask), "r" (p)
+ : "cc", "memory");
+
+ return (old & mask) != 0;
+}
+
+static __inline__ int test_and_clear_bit(unsigned long nr,
+ volatile unsigned long *addr)
+{
+ unsigned long old, t;
+ unsigned long mask = BITOP_MASK(nr);
+ unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
+
+ __asm__ __volatile__(
+ EIEIO_ON_SMP
+"1:" PPC_LLARX "%0,0,%3 # test_and_clear_bit\n"
+ "andc %1,%0,%2 \n"
+ PPC405_ERR77(0,%3)
+ PPC_STLCX "%1,0,%3 \n"
+ "bne- 1b"
+ ISYNC_ON_SMP
+ : "=&r" (old), "=&r" (t)
+ : "r" (mask), "r" (p)
+ : "cc", "memory");
+
+ return (old & mask) != 0;
+}
+
+static __inline__ int test_and_change_bit(unsigned long nr,
+ volatile unsigned long *addr)
+{
+ unsigned long old, t;
+ unsigned long mask = BITOP_MASK(nr);
+ unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
+
+ __asm__ __volatile__(
+ EIEIO_ON_SMP
+"1:" PPC_LLARX "%0,0,%3 # test_and_change_bit\n"
+ "xor %1,%0,%2 \n"
+ PPC405_ERR77(0,%3)
+ PPC_STLCX "%1,0,%3 \n"
+ "bne- 1b"
+ ISYNC_ON_SMP
+ : "=&r" (old), "=&r" (t)
+ : "r" (mask), "r" (p)
+ : "cc", "memory");
+
+ return (old & mask) != 0;
+}
+
+static __inline__ void set_bits(unsigned long mask, unsigned long *addr)
+{
+ unsigned long old;
+
+ __asm__ __volatile__(
+"1:" PPC_LLARX "%0,0,%3 # set_bits\n"
+ "or %0,%0,%2\n"
+ PPC_STLCX "%0,0,%3\n"
+ "bne- 1b"
+ : "=&r" (old), "=m" (*addr)
+ : "r" (mask), "r" (addr), "m" (*addr)
+ : "cc");
+}
+
+/* Non-atomic versions */
+static __inline__ int test_bit(unsigned long nr,
+ __const__ volatile unsigned long *addr)
+{
+ return 1UL & (addr[BITOP_WORD(nr)] >> (nr & (BITS_PER_LONG-1)));
+}
+
+static __inline__ void __set_bit(unsigned long nr,
+ volatile unsigned long *addr)
+{
+ unsigned long mask = BITOP_MASK(nr);
+ unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
+
+ *p |= mask;
+}
+
+static __inline__ void __clear_bit(unsigned long nr,
+ volatile unsigned long *addr)
+{
+ unsigned long mask = BITOP_MASK(nr);
+ unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
+
+ *p &= ~mask;
+}
+
+static __inline__ void __change_bit(unsigned long nr,
+ volatile unsigned long *addr)
+{
+ unsigned long mask = BITOP_MASK(nr);
+ unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
+
+ *p ^= mask;
+}
+
+static __inline__ int __test_and_set_bit(unsigned long nr,
+ volatile unsigned long *addr)
+{
+ unsigned long mask = BITOP_MASK(nr);
+ unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
+ unsigned long old = *p;
+
+ *p = old | mask;
+ return (old & mask) != 0;
+}
+
+static __inline__ int __test_and_clear_bit(unsigned long nr,
+ volatile unsigned long *addr)
+{
+ unsigned long mask = BITOP_MASK(nr);
+ unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
+ unsigned long old = *p;
+
+ *p = old & ~mask;
+ return (old & mask) != 0;
+}
+
+static __inline__ int __test_and_change_bit(unsigned long nr,
+ volatile unsigned long *addr)
+{
+ unsigned long mask = BITOP_MASK(nr);
+ unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
+ unsigned long old = *p;
+
+ *p = old ^ mask;
+ return (old & mask) != 0;
+}
+
+/*
+ * Return the zero-based bit position (LE, not IBM bit numbering) of
+ * the most significant 1-bit in a double word.
+ */
+static __inline__ int __ilog2(unsigned long x)
+{
+ int lz;
+
+ asm (PPC_CNTLZL "%0,%1" : "=r" (lz) : "r" (x));
+ return BITS_PER_LONG - 1 - lz;
+}
+
+/*
+ * Determines the bit position of the least significant 0 bit in the
+ * specified double word. The returned bit position will be
+ * zero-based, starting from the right side (63/31 - 0).
+ */
+static __inline__ unsigned long ffz(unsigned long x)
+{
+ /* no zero exists anywhere in the 8 byte area. */
+ if ((x = ~x) == 0)
+ return BITS_PER_LONG;
+
+ /*
+ * Calculate the bit position of the least signficant '1' bit in x
+ * (since x has been changed this will actually be the least signficant
+ * '0' bit in * the original x). Note: (x & -x) gives us a mask that
+ * is the least significant * (RIGHT-most) 1-bit of the value in x.
+ */
+ return __ilog2(x & -x);
+}
+
+static __inline__ int __ffs(unsigned long x)
+{
+ return __ilog2(x & -x);
+}
+
+/*
+ * ffs: find first bit set. This is defined the same way as
+ * the libc and compiler builtin ffs routines, therefore
+ * differs in spirit from the above ffz (man ffs).
+ */
+static __inline__ int ffs(int x)
+{
+ unsigned long i = (unsigned long)x;
+ return __ilog2(i & -i) + 1;
+}
+
+/*
+ * fls: find last (most-significant) bit set.
+ * Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32.
+ */
+static __inline__ int fls(unsigned int x)
+{
+ int lz;
+
+ asm ("cntlzw %0,%1" : "=r" (lz) : "r" (x));
+ return 32 - lz;
+}
+
+/*
+ * hweightN: returns the hamming weight (i.e. the number
+ * of bits set) of a N-bit word
+ */
+#define hweight64(x) generic_hweight64(x)
+#define hweight32(x) generic_hweight32(x)
+#define hweight16(x) generic_hweight16(x)
+#define hweight8(x) generic_hweight8(x)
+
+#define find_first_zero_bit(addr, size) find_next_zero_bit((addr), (size), 0)
+unsigned long find_next_zero_bit(const unsigned long *addr,
+ unsigned long size, unsigned long offset);
+/**
+ * find_first_bit - find the first set bit in a memory region
+ * @addr: The address to start the search at
+ * @size: The maximum size to search
+ *
+ * Returns the bit-number of the first set bit, not the number of the byte
+ * containing a bit.
+ */
+#define find_first_bit(addr, size) find_next_bit((addr), (size), 0)
+unsigned long find_next_bit(const unsigned long *addr,
+ unsigned long size, unsigned long offset);
+
+/* Little-endian versions */
+
+static __inline__ int test_le_bit(unsigned long nr,
+ __const__ unsigned long *addr)
+{
+ __const__ unsigned char *tmp = (__const__ unsigned char *) addr;
+ return (tmp[nr >> 3] >> (nr & 7)) & 1;
+}
+
+#define __set_le_bit(nr, addr) \
+ __set_bit((nr) ^ BITOP_LE_SWIZZLE, (addr))
+#define __clear_le_bit(nr, addr) \
+ __clear_bit((nr) ^ BITOP_LE_SWIZZLE, (addr))
+
+#define test_and_set_le_bit(nr, addr) \
+ test_and_set_bit((nr) ^ BITOP_LE_SWIZZLE, (addr))
+#define test_and_clear_le_bit(nr, addr) \
+ test_and_clear_bit((nr) ^ BITOP_LE_SWIZZLE, (addr))
+
+#define __test_and_set_le_bit(nr, addr) \
+ __test_and_set_bit((nr) ^ BITOP_LE_SWIZZLE, (addr))
+#define __test_and_clear_le_bit(nr, addr) \
+ __test_and_clear_bit((nr) ^ BITOP_LE_SWIZZLE, (addr))
+
+#define find_first_zero_le_bit(addr, size) find_next_zero_le_bit((addr), (size), 0)
+unsigned long find_next_zero_le_bit(const unsigned long *addr,
+ unsigned long size, unsigned long offset);
+
+/* Bitmap functions for the ext2 filesystem */
+
+#define ext2_set_bit(nr,addr) \
+ __test_and_set_le_bit((nr), (unsigned long*)addr)
+#define ext2_clear_bit(nr, addr) \
+ __test_and_clear_le_bit((nr), (unsigned long*)addr)
+
+#define ext2_set_bit_atomic(lock, nr, addr) \
+ test_and_set_le_bit((nr), (unsigned long*)addr)
+#define ext2_clear_bit_atomic(lock, nr, addr) \
+ test_and_clear_le_bit((nr), (unsigned long*)addr)
+
+#define ext2_test_bit(nr, addr) test_le_bit((nr),(unsigned long*)addr)
+
+#define ext2_find_first_zero_bit(addr, size) \
+ find_first_zero_le_bit((unsigned long*)addr, size)
+#define ext2_find_next_zero_bit(addr, size, off) \
+ find_next_zero_le_bit((unsigned long*)addr, size, off)
+
+/* Bitmap functions for the minix filesystem. */
+
+#define minix_test_and_set_bit(nr,addr) \
+ __test_and_set_le_bit(nr, (unsigned long *)addr)
+#define minix_set_bit(nr,addr) \
+ __set_le_bit(nr, (unsigned long *)addr)
+#define minix_test_and_clear_bit(nr,addr) \
+ __test_and_clear_le_bit(nr, (unsigned long *)addr)
+#define minix_test_bit(nr,addr) \
+ test_le_bit(nr, (unsigned long *)addr)
+
+#define minix_find_first_zero_bit(addr,size) \
+ find_first_zero_le_bit((unsigned long *)addr, size)
+
+/*
+ * Every architecture must define this function. It's the fastest
+ * way of searching a 140-bit bitmap where the first 100 bits are
+ * unlikely to be set. It's guaranteed that at least one of the 140
+ * bits is cleared.
+ */
+static inline int sched_find_first_bit(const unsigned long *b)
+{
+#ifdef CONFIG_PPC64
+ if (unlikely(b[0]))
+ return __ffs(b[0]);
+ if (unlikely(b[1]))
+ return __ffs(b[1]) + 64;
+ return __ffs(b[2]) + 128;
+#else
+ if (unlikely(b[0]))
+ return __ffs(b[0]);
+ if (unlikely(b[1]))
+ return __ffs(b[1]) + 32;
+ if (unlikely(b[2]))
+ return __ffs(b[2]) + 64;
+ if (b[3])
+ return __ffs(b[3]) + 96;
+ return __ffs(b[4]) + 128;
+#endif
+}
+
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_POWERPC_BITOPS_H */
diff --git a/include/asm-ppc64/bug.h b/include/asm-powerpc/bug.h
index 160178278861..b001ecb3cd99 100644
--- a/include/asm-ppc64/bug.h
+++ b/include/asm-powerpc/bug.h
@@ -1,6 +1,7 @@
-#ifndef _PPC64_BUG_H
-#define _PPC64_BUG_H
+#ifndef _ASM_POWERPC_BUG_H
+#define _ASM_POWERPC_BUG_H
+#include <asm/asm-compat.h>
/*
* Define an illegal instr to trap on the bug.
* We don't use 0 because that marks the end of a function
@@ -31,29 +32,29 @@ struct bug_entry *find_bug(unsigned long bugaddr);
#define BUG() do { \
__asm__ __volatile__( \
"1: twi 31,0,0\n" \
- ".section __bug_table,\"a\"\n\t" \
- " .llong 1b,%0,%1,%2\n" \
+ ".section __bug_table,\"a\"\n" \
+ "\t"PPC_LONG" 1b,%0,%1,%2\n" \
".previous" \
: : "i" (__LINE__), "i" (__FILE__), "i" (__FUNCTION__)); \
} while (0)
#define BUG_ON(x) do { \
__asm__ __volatile__( \
- "1: tdnei %0,0\n" \
- ".section __bug_table,\"a\"\n\t" \
- " .llong 1b,%1,%2,%3\n" \
+ "1: "PPC_TLNEI" %0,0\n" \
+ ".section __bug_table,\"a\"\n" \
+ "\t"PPC_LONG" 1b,%1,%2,%3\n" \
".previous" \
- : : "r" ((long long)(x)), "i" (__LINE__), \
+ : : "r" ((long)(x)), "i" (__LINE__), \
"i" (__FILE__), "i" (__FUNCTION__)); \
} while (0)
#define WARN_ON(x) do { \
__asm__ __volatile__( \
- "1: tdnei %0,0\n" \
- ".section __bug_table,\"a\"\n\t" \
- " .llong 1b,%1,%2,%3\n" \
+ "1: "PPC_TLNEI" %0,0\n" \
+ ".section __bug_table,\"a\"\n" \
+ "\t"PPC_LONG" 1b,%1,%2,%3\n" \
".previous" \
- : : "r" ((long long)(x)), \
+ : : "r" ((long)(x)), \
"i" (__LINE__ + BUG_WARNING_TRAP), \
"i" (__FILE__), "i" (__FUNCTION__)); \
} while (0)
@@ -61,9 +62,9 @@ struct bug_entry *find_bug(unsigned long bugaddr);
#define HAVE_ARCH_BUG
#define HAVE_ARCH_BUG_ON
#define HAVE_ARCH_WARN_ON
-#endif
-#endif
+#endif /* CONFIG_BUG */
+#endif /* __ASSEMBLY __ */
#include <asm-generic/bug.h>
-#endif
+#endif /* _ASM_POWERPC_BUG_H */
diff --git a/include/asm-ppc64/byteorder.h b/include/asm-powerpc/byteorder.h
index 8b57da62b674..b37752214a16 100644
--- a/include/asm-ppc64/byteorder.h
+++ b/include/asm-powerpc/byteorder.h
@@ -1,5 +1,5 @@
-#ifndef _PPC64_BYTEORDER_H
-#define _PPC64_BYTEORDER_H
+#ifndef _ASM_POWERPC_BYTEORDER_H
+#define _ASM_POWERPC_BYTEORDER_H
/*
* This program is free software; you can redistribute it and/or
@@ -77,10 +77,13 @@ static __inline__ __attribute_const__ __u32 ___arch__swab32(__u32 value)
#ifndef __STRICT_ANSI__
#define __BYTEORDER_HAS_U64__
-#endif
+#ifndef __powerpc64__
+#define __SWAB_64_THRU_32__
+#endif /* __powerpc64__ */
+#endif /* __STRICT_ANSI__ */
#endif /* __GNUC__ */
#include <linux/byteorder/big_endian.h>
-#endif /* _PPC64_BYTEORDER_H */
+#endif /* _ASM_POWERPC_BYTEORDER_H */
diff --git a/include/asm-powerpc/cache.h b/include/asm-powerpc/cache.h
new file mode 100644
index 000000000000..26ce502e76e8
--- /dev/null
+++ b/include/asm-powerpc/cache.h
@@ -0,0 +1,40 @@
+#ifndef _ASM_POWERPC_CACHE_H
+#define _ASM_POWERPC_CACHE_H
+
+#ifdef __KERNEL__
+
+#include <linux/config.h>
+
+/* bytes per L1 cache line */
+#if defined(CONFIG_8xx) || defined(CONFIG_403GCX)
+#define L1_CACHE_SHIFT 4
+#define MAX_COPY_PREFETCH 1
+#elif defined(CONFIG_PPC32)
+#define L1_CACHE_SHIFT 5
+#define MAX_COPY_PREFETCH 4
+#else /* CONFIG_PPC64 */
+#define L1_CACHE_SHIFT 7
+#endif
+
+#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
+
+#define SMP_CACHE_BYTES L1_CACHE_BYTES
+#define L1_CACHE_SHIFT_MAX 7 /* largest L1 which this arch supports */
+
+#if defined(__powerpc64__) && !defined(__ASSEMBLY__)
+struct ppc64_caches {
+ u32 dsize; /* L1 d-cache size */
+ u32 dline_size; /* L1 d-cache line size */
+ u32 log_dline_size;
+ u32 dlines_per_page;
+ u32 isize; /* L1 i-cache size */
+ u32 iline_size; /* L1 i-cache line size */
+ u32 log_iline_size;
+ u32 ilines_per_page;
+};
+
+extern struct ppc64_caches ppc64_caches;
+#endif /* __powerpc64__ && ! __ASSEMBLY__ */
+
+#endif /* __KERNEL__ */
+#endif /* _ASM_POWERPC_CACHE_H */
diff --git a/include/asm-ppc64/cacheflush.h b/include/asm-powerpc/cacheflush.h
index ffbc08be8e52..8a740c88d93d 100644
--- a/include/asm-ppc64/cacheflush.h
+++ b/include/asm-powerpc/cacheflush.h
@@ -1,13 +1,20 @@
-#ifndef _PPC64_CACHEFLUSH_H
-#define _PPC64_CACHEFLUSH_H
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#ifndef _ASM_POWERPC_CACHEFLUSH_H
+#define _ASM_POWERPC_CACHEFLUSH_H
+
+#ifdef __KERNEL__
#include <linux/mm.h>
#include <asm/cputable.h>
/*
- * No cache flushing is required when address mappings are
- * changed, because the caches on PowerPCs are physically
- * addressed.
+ * No cache flushing is required when address mappings are changed,
+ * because the caches on PowerPCs are physically addressed.
*/
#define flush_cache_all() do { } while (0)
#define flush_cache_mm(mm) do { } while (0)
@@ -22,27 +29,40 @@ extern void flush_dcache_page(struct page *page);
#define flush_dcache_mmap_unlock(mapping) do { } while (0)
extern void __flush_icache_range(unsigned long, unsigned long);
+static inline void flush_icache_range(unsigned long start, unsigned long stop)
+{
+ if (!cpu_has_feature(CPU_FTR_COHERENT_ICACHE))
+ __flush_icache_range(start, stop);
+}
+
extern void flush_icache_user_range(struct vm_area_struct *vma,
struct page *page, unsigned long addr,
int len);
+extern void __flush_dcache_icache(void *page_va);
+extern void flush_dcache_icache_page(struct page *page);
+#if defined(CONFIG_PPC32) && !defined(CONFIG_BOOKE)
+extern void __flush_dcache_icache_phys(unsigned long physaddr);
+#endif /* CONFIG_PPC32 && !CONFIG_BOOKE */
extern void flush_dcache_range(unsigned long start, unsigned long stop);
-extern void flush_dcache_phys_range(unsigned long start, unsigned long stop);
+#ifdef CONFIG_PPC32
+extern void clean_dcache_range(unsigned long start, unsigned long stop);
+extern void invalidate_dcache_range(unsigned long start, unsigned long stop);
+#endif /* CONFIG_PPC32 */
+#ifdef CONFIG_PPC64
extern void flush_inval_dcache_range(unsigned long start, unsigned long stop);
+extern void flush_dcache_phys_range(unsigned long start, unsigned long stop);
+#endif
#define copy_to_user_page(vma, page, vaddr, dst, src, len) \
-do { memcpy(dst, src, len); \
- flush_icache_user_range(vma, page, vaddr, len); \
-} while (0)
+ do { \
+ memcpy(dst, src, len); \
+ flush_icache_user_range(vma, page, vaddr, len); \
+ } while (0)
#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
memcpy(dst, src, len)
-extern void __flush_dcache_icache(void *page_va);
-static inline void flush_icache_range(unsigned long start, unsigned long stop)
-{
- if (!cpu_has_feature(CPU_FTR_COHERENT_ICACHE))
- __flush_icache_range(start, stop);
-}
+#endif /* __KERNEL__ */
-#endif /* _PPC64_CACHEFLUSH_H */
+#endif /* _ASM_POWERPC_CACHEFLUSH_H */
diff --git a/include/asm-ppc64/checksum.h b/include/asm-powerpc/checksum.h
index d22d4469de43..d8354d8a49ce 100644
--- a/include/asm-ppc64/checksum.h
+++ b/include/asm-powerpc/checksum.h
@@ -1,5 +1,5 @@
-#ifndef _PPC64_CHECKSUM_H
-#define _PPC64_CHECKSUM_H
+#ifndef _ASM_POWERPC_CHECKSUM_H
+#define _ASM_POWERPC_CHECKSUM_H
/*
* This program is free software; you can redistribute it and/or
@@ -41,8 +41,14 @@ extern unsigned int csum_partial(const unsigned char * buff, int len,
unsigned int sum);
/*
- * the same as csum_partial, but copies from src to dst while it
- * checksums
+ * Computes the checksum of a memory block at src, length len,
+ * and adds in "sum" (32-bit), while copying the block to dst.
+ * If an access exception occurs on src or dst, it stores -EFAULT
+ * to *src_err or *dst_err respectively (if that pointer is not
+ * NULL), and, for an error on src, zeroes the rest of dst.
+ *
+ * Like csum_partial, this must be called with even lengths,
+ * except for the last fragment.
*/
extern unsigned int csum_partial_copy_generic(const char *src, char *dst,
int len, unsigned int sum,
@@ -51,12 +57,18 @@ extern unsigned int csum_partial_copy_generic(const char *src, char *dst,
* the same as csum_partial, but copies from src to dst while it
* checksums.
*/
-
unsigned int csum_partial_copy_nocheck(const char *src,
char *dst,
int len,
unsigned int sum);
+#define csum_partial_copy_from_user(src, dst, len, sum, errp) \
+ csum_partial_copy_generic((src), (dst), (len), (sum), (errp), NULL)
+
+#define csum_partial_copy_nocheck(src, dst, len, sum) \
+ csum_partial_copy_generic((src), (dst), (len), (sum), NULL, NULL)
+
+
/*
* turns a 32-bit partial checksum (e.g. from csum_partial) into a
* 1's complement 16-bit checksum.
@@ -83,12 +95,7 @@ static inline unsigned short ip_compute_csum(unsigned char * buff, int len)
return csum_fold(csum_partial(buff, len, 0));
}
-#define csum_partial_copy_from_user(src, dst, len, sum, errp) \
- csum_partial_copy_generic((src), (dst), (len), (sum), (errp), NULL)
-
-#define csum_partial_copy_nocheck(src, dst, len, sum) \
- csum_partial_copy_generic((src), (dst), (len), (sum), NULL, NULL)
-
+#ifdef __powerpc64__
static inline u32 csum_tcpudp_nofold(u32 saddr,
u32 daddr,
unsigned short len,
@@ -103,5 +110,23 @@ static inline u32 csum_tcpudp_nofold(u32 saddr,
s += (s >> 32);
return (u32) s;
}
+#else
+static inline unsigned long csum_tcpudp_nofold(unsigned long saddr,
+ unsigned long daddr,
+ unsigned short len,
+ unsigned short proto,
+ unsigned int sum)
+{
+ __asm__("\n\
+ addc %0,%0,%1 \n\
+ adde %0,%0,%2 \n\
+ adde %0,%0,%3 \n\
+ addze %0,%0 \n\
+ "
+ : "=r" (sum)
+ : "r" (daddr), "r"(saddr), "r"((proto<<16)+len), "0"(sum));
+ return sum;
+}
#endif
+#endif
diff --git a/include/asm-ppc64/compat.h b/include/asm-powerpc/compat.h
index 6ec62cd2d1d1..4db4360c4d4a 100644
--- a/include/asm-ppc64/compat.h
+++ b/include/asm-powerpc/compat.h
@@ -1,5 +1,5 @@
-#ifndef _ASM_PPC64_COMPAT_H
-#define _ASM_PPC64_COMPAT_H
+#ifndef _ASM_POWERPC_COMPAT_H
+#define _ASM_POWERPC_COMPAT_H
/*
* Architecture specific compatibility types
*/
@@ -49,7 +49,7 @@ struct compat_stat {
compat_dev_t st_dev;
compat_ino_t st_ino;
compat_mode_t st_mode;
- compat_nlink_t st_nlink;
+ compat_nlink_t st_nlink;
__compat_uid32_t st_uid;
__compat_gid32_t st_gid;
compat_dev_t st_rdev;
@@ -202,4 +202,4 @@ struct compat_shmid64_ds {
compat_ulong_t __unused6;
};
-#endif /* _ASM_PPC64_COMPAT_H */
+#endif /* _ASM_POWERPC_COMPAT_H */
diff --git a/include/asm-powerpc/cputable.h b/include/asm-powerpc/cputable.h
new file mode 100644
index 000000000000..04e2726002cf
--- /dev/null
+++ b/include/asm-powerpc/cputable.h
@@ -0,0 +1,434 @@
+#ifndef __ASM_POWERPC_CPUTABLE_H
+#define __ASM_POWERPC_CPUTABLE_H
+
+#include <linux/config.h>
+#include <asm/asm-compat.h>
+
+#define PPC_FEATURE_32 0x80000000
+#define PPC_FEATURE_64 0x40000000
+#define PPC_FEATURE_601_INSTR 0x20000000
+#define PPC_FEATURE_HAS_ALTIVEC 0x10000000
+#define PPC_FEATURE_HAS_FPU 0x08000000
+#define PPC_FEATURE_HAS_MMU 0x04000000
+#define PPC_FEATURE_HAS_4xxMAC 0x02000000
+#define PPC_FEATURE_UNIFIED_CACHE 0x01000000
+#define PPC_FEATURE_HAS_SPE 0x00800000
+#define PPC_FEATURE_HAS_EFP_SINGLE 0x00400000
+#define PPC_FEATURE_HAS_EFP_DOUBLE 0x00200000
+#define PPC_FEATURE_NO_TB 0x00100000
+#define PPC_FEATURE_POWER4 0x00080000
+#define PPC_FEATURE_POWER5 0x00040000
+#define PPC_FEATURE_POWER5_PLUS 0x00020000
+#define PPC_FEATURE_CELL 0x00010000
+
+#ifdef __KERNEL__
+#ifndef __ASSEMBLY__
+
+/* This structure can grow, it's real size is used by head.S code
+ * via the mkdefs mechanism.
+ */
+struct cpu_spec;
+struct op_powerpc_model;
+
+typedef void (*cpu_setup_t)(unsigned long offset, struct cpu_spec* spec);
+
+struct cpu_spec {
+ /* CPU is matched via (PVR & pvr_mask) == pvr_value */
+ unsigned int pvr_mask;
+ unsigned int pvr_value;
+
+ char *cpu_name;
+ unsigned long cpu_features; /* Kernel features */
+ unsigned int cpu_user_features; /* Userland features */
+
+ /* cache line sizes */
+ unsigned int icache_bsize;
+ unsigned int dcache_bsize;
+
+ /* number of performance monitor counters */
+ unsigned int num_pmcs;
+
+ /* this is called to initialize various CPU bits like L1 cache,
+ * BHT, SPD, etc... from head.S before branching to identify_machine
+ */
+ cpu_setup_t cpu_setup;
+
+ /* Used by oprofile userspace to select the right counters */
+ char *oprofile_cpu_type;
+
+ /* Processor specific oprofile operations */
+ struct op_powerpc_model *oprofile_model;
+};
+
+extern struct cpu_spec *cur_cpu_spec;
+
+extern void identify_cpu(unsigned long offset, unsigned long cpu);
+extern void do_cpu_ftr_fixups(unsigned long offset);
+
+#endif /* __ASSEMBLY__ */
+
+/* CPU kernel features */
+
+/* Retain the 32b definitions all use bottom half of word */
+#define CPU_FTR_SPLIT_ID_CACHE ASM_CONST(0x0000000000000001)
+#define CPU_FTR_L2CR ASM_CONST(0x0000000000000002)
+#define CPU_FTR_SPEC7450 ASM_CONST(0x0000000000000004)
+#define CPU_FTR_ALTIVEC ASM_CONST(0x0000000000000008)
+#define CPU_FTR_TAU ASM_CONST(0x0000000000000010)
+#define CPU_FTR_CAN_DOZE ASM_CONST(0x0000000000000020)
+#define CPU_FTR_USE_TB ASM_CONST(0x0000000000000040)
+#define CPU_FTR_604_PERF_MON ASM_CONST(0x0000000000000080)
+#define CPU_FTR_601 ASM_CONST(0x0000000000000100)
+#define CPU_FTR_HPTE_TABLE ASM_CONST(0x0000000000000200)
+#define CPU_FTR_CAN_NAP ASM_CONST(0x0000000000000400)
+#define CPU_FTR_L3CR ASM_CONST(0x0000000000000800)
+#define CPU_FTR_L3_DISABLE_NAP ASM_CONST(0x0000000000001000)
+#define CPU_FTR_NAP_DISABLE_L2_PR ASM_CONST(0x0000000000002000)
+#define CPU_FTR_DUAL_PLL_750FX ASM_CONST(0x0000000000004000)
+#define CPU_FTR_NO_DPM ASM_CONST(0x0000000000008000)
+#define CPU_FTR_HAS_HIGH_BATS ASM_CONST(0x0000000000010000)
+#define CPU_FTR_NEED_COHERENT ASM_CONST(0x0000000000020000)
+#define CPU_FTR_NO_BTIC ASM_CONST(0x0000000000040000)
+#define CPU_FTR_BIG_PHYS ASM_CONST(0x0000000000080000)
+
+#ifdef __powerpc64__
+/* Add the 64b processor unique features in the top half of the word */
+#define CPU_FTR_SLB ASM_CONST(0x0000000100000000)
+#define CPU_FTR_16M_PAGE ASM_CONST(0x0000000200000000)
+#define CPU_FTR_TLBIEL ASM_CONST(0x0000000400000000)
+#define CPU_FTR_NOEXECUTE ASM_CONST(0x0000000800000000)
+#define CPU_FTR_NODSISRALIGN ASM_CONST(0x0000001000000000)
+#define CPU_FTR_IABR ASM_CONST(0x0000002000000000)
+#define CPU_FTR_MMCRA ASM_CONST(0x0000004000000000)
+#define CPU_FTR_CTRL ASM_CONST(0x0000008000000000)
+#define CPU_FTR_SMT ASM_CONST(0x0000010000000000)
+#define CPU_FTR_COHERENT_ICACHE ASM_CONST(0x0000020000000000)
+#define CPU_FTR_LOCKLESS_TLBIE ASM_CONST(0x0000040000000000)
+#define CPU_FTR_MMCRA_SIHV ASM_CONST(0x0000080000000000)
+#define CPU_FTR_CI_LARGE_PAGE ASM_CONST(0x0000100000000000)
+#else
+/* ensure on 32b processors the flags are available for compiling but
+ * don't do anything */
+#define CPU_FTR_SLB ASM_CONST(0x0)
+#define CPU_FTR_16M_PAGE ASM_CONST(0x0)
+#define CPU_FTR_TLBIEL ASM_CONST(0x0)
+#define CPU_FTR_NOEXECUTE ASM_CONST(0x0)
+#define CPU_FTR_NODSISRALIGN ASM_CONST(0x0)
+#define CPU_FTR_IABR ASM_CONST(0x0)
+#define CPU_FTR_MMCRA ASM_CONST(0x0)
+#define CPU_FTR_CTRL ASM_CONST(0x0)
+#define CPU_FTR_SMT ASM_CONST(0x0)
+#define CPU_FTR_COHERENT_ICACHE ASM_CONST(0x0)
+#define CPU_FTR_LOCKLESS_TLBIE ASM_CONST(0x0)
+#define CPU_FTR_MMCRA_SIHV ASM_CONST(0x0)
+#define CPU_FTR_CI_LARGE_PAGE ASM_CONST(0x0)
+#endif
+
+#ifndef __ASSEMBLY__
+
+#define CPU_FTR_PPCAS_ARCH_V2_BASE (CPU_FTR_SLB | \
+ CPU_FTR_TLBIEL | CPU_FTR_NOEXECUTE | \
+ CPU_FTR_NODSISRALIGN | CPU_FTR_CTRL)
+
+/* iSeries doesn't support large pages */
+#ifdef CONFIG_PPC_ISERIES
+#define CPU_FTR_PPCAS_ARCH_V2 (CPU_FTR_PPCAS_ARCH_V2_BASE)
+#else
+#define CPU_FTR_PPCAS_ARCH_V2 (CPU_FTR_PPCAS_ARCH_V2_BASE | CPU_FTR_16M_PAGE)
+#endif /* CONFIG_PPC_ISERIES */
+
+/* We only set the altivec features if the kernel was compiled with altivec
+ * support
+ */
+#ifdef CONFIG_ALTIVEC
+#define CPU_FTR_ALTIVEC_COMP CPU_FTR_ALTIVEC
+#define PPC_FEATURE_HAS_ALTIVEC_COMP PPC_FEATURE_HAS_ALTIVEC
+#else
+#define CPU_FTR_ALTIVEC_COMP 0
+#define PPC_FEATURE_HAS_ALTIVEC_COMP 0
+#endif
+
+/* We need to mark all pages as being coherent if we're SMP or we
+ * have a 74[45]x and an MPC107 host bridge.
+ */
+#if defined(CONFIG_SMP) || defined(CONFIG_MPC10X_BRIDGE)
+#define CPU_FTR_COMMON CPU_FTR_NEED_COHERENT
+#else
+#define CPU_FTR_COMMON 0
+#endif
+
+/* The powersave features NAP & DOZE seems to confuse BDI when
+ debugging. So if a BDI is used, disable theses
+ */
+#ifndef CONFIG_BDI_SWITCH
+#define CPU_FTR_MAYBE_CAN_DOZE CPU_FTR_CAN_DOZE
+#define CPU_FTR_MAYBE_CAN_NAP CPU_FTR_CAN_NAP
+#else
+#define CPU_FTR_MAYBE_CAN_DOZE 0
+#define CPU_FTR_MAYBE_CAN_NAP 0
+#endif
+
+#define CLASSIC_PPC (!defined(CONFIG_8xx) && !defined(CONFIG_4xx) && \
+ !defined(CONFIG_POWER3) && !defined(CONFIG_POWER4) && \
+ !defined(CONFIG_BOOKE))
+
+enum {
+ CPU_FTRS_PPC601 = CPU_FTR_COMMON | CPU_FTR_601 | CPU_FTR_HPTE_TABLE,
+ CPU_FTRS_603 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE |
+ CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB |
+ CPU_FTR_MAYBE_CAN_NAP,
+ CPU_FTRS_604 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE |
+ CPU_FTR_USE_TB | CPU_FTR_604_PERF_MON | CPU_FTR_HPTE_TABLE,
+ CPU_FTRS_740_NOTAU = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE |
+ CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB | CPU_FTR_L2CR |
+ CPU_FTR_HPTE_TABLE | CPU_FTR_MAYBE_CAN_NAP,
+ CPU_FTRS_740 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE |
+ CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB | CPU_FTR_L2CR |
+ CPU_FTR_TAU | CPU_FTR_HPTE_TABLE | CPU_FTR_MAYBE_CAN_NAP,
+ CPU_FTRS_750 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE |
+ CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB | CPU_FTR_L2CR |
+ CPU_FTR_TAU | CPU_FTR_HPTE_TABLE | CPU_FTR_MAYBE_CAN_NAP,
+ CPU_FTRS_750FX1 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE |
+ CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB | CPU_FTR_L2CR |
+ CPU_FTR_TAU | CPU_FTR_HPTE_TABLE | CPU_FTR_MAYBE_CAN_NAP |
+ CPU_FTR_DUAL_PLL_750FX | CPU_FTR_NO_DPM,
+ CPU_FTRS_750FX2 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE |
+ CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB | CPU_FTR_L2CR |
+ CPU_FTR_TAU | CPU_FTR_HPTE_TABLE | CPU_FTR_MAYBE_CAN_NAP |
+ CPU_FTR_NO_DPM,
+ CPU_FTRS_750FX = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE |
+ CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB | CPU_FTR_L2CR |
+ CPU_FTR_TAU | CPU_FTR_HPTE_TABLE | CPU_FTR_MAYBE_CAN_NAP |
+ CPU_FTR_DUAL_PLL_750FX | CPU_FTR_HAS_HIGH_BATS,
+ CPU_FTRS_750GX = CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_MAYBE_CAN_DOZE |
+ CPU_FTR_USE_TB | CPU_FTR_L2CR | CPU_FTR_TAU |
+ CPU_FTR_HPTE_TABLE | CPU_FTR_MAYBE_CAN_NAP |
+ CPU_FTR_DUAL_PLL_750FX | CPU_FTR_HAS_HIGH_BATS,
+ CPU_FTRS_7400_NOTAU = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE |
+ CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB | CPU_FTR_L2CR |
+ CPU_FTR_ALTIVEC_COMP | CPU_FTR_HPTE_TABLE |
+ CPU_FTR_MAYBE_CAN_NAP,
+ CPU_FTRS_7400 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE |
+ CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB | CPU_FTR_L2CR |
+ CPU_FTR_TAU | CPU_FTR_ALTIVEC_COMP | CPU_FTR_HPTE_TABLE |
+ CPU_FTR_MAYBE_CAN_NAP,
+ CPU_FTRS_7450_20 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE |
+ CPU_FTR_USE_TB | CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP |
+ CPU_FTR_L3CR | CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 |
+ CPU_FTR_NEED_COHERENT,
+ CPU_FTRS_7450_21 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE |
+ CPU_FTR_USE_TB |
+ CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP |
+ CPU_FTR_L3CR | CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 |
+ CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_L3_DISABLE_NAP |
+ CPU_FTR_NEED_COHERENT,
+ CPU_FTRS_7450_23 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE |
+ CPU_FTR_USE_TB |
+ CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP |
+ CPU_FTR_L3CR | CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 |
+ CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_NEED_COHERENT,
+ CPU_FTRS_7455_1 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE |
+ CPU_FTR_USE_TB |
+ CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | CPU_FTR_L3CR |
+ CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 | CPU_FTR_HAS_HIGH_BATS |
+ CPU_FTR_NEED_COHERENT,
+ CPU_FTRS_7455_20 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE |
+ CPU_FTR_USE_TB |
+ CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP |
+ CPU_FTR_L3CR | CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 |
+ CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_L3_DISABLE_NAP |
+ CPU_FTR_NEED_COHERENT | CPU_FTR_HAS_HIGH_BATS,
+ CPU_FTRS_7455 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE |
+ CPU_FTR_USE_TB |
+ CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP |
+ CPU_FTR_L3CR | CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 |
+ CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_HAS_HIGH_BATS |
+ CPU_FTR_NEED_COHERENT,
+ CPU_FTRS_7447_10 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE |
+ CPU_FTR_USE_TB |
+ CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP |
+ CPU_FTR_L3CR | CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 |
+ CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_HAS_HIGH_BATS |
+ CPU_FTR_NEED_COHERENT | CPU_FTR_NO_BTIC,
+ CPU_FTRS_7447 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE |
+ CPU_FTR_USE_TB |
+ CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP |
+ CPU_FTR_L3CR | CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 |
+ CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_HAS_HIGH_BATS |
+ CPU_FTR_NEED_COHERENT,
+ CPU_FTRS_7447A = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE |
+ CPU_FTR_USE_TB |
+ CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP |
+ CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 |
+ CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_HAS_HIGH_BATS |
+ CPU_FTR_NEED_COHERENT,
+ CPU_FTRS_82XX = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE |
+ CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB,
+ CPU_FTRS_G2_LE = CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_MAYBE_CAN_DOZE |
+ CPU_FTR_USE_TB | CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_HAS_HIGH_BATS,
+ CPU_FTRS_E300 = CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_MAYBE_CAN_DOZE |
+ CPU_FTR_USE_TB | CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_HAS_HIGH_BATS,
+ CPU_FTRS_CLASSIC32 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE |
+ CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE,
+ CPU_FTRS_POWER3_32 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE |
+ CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE,
+ CPU_FTRS_POWER4_32 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE |
+ CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE,
+ CPU_FTRS_970_32 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE |
+ CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | CPU_FTR_ALTIVEC_COMP |
+ CPU_FTR_MAYBE_CAN_NAP,
+ CPU_FTRS_8XX = CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB,
+ CPU_FTRS_40X = CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB,
+ CPU_FTRS_44X = CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB,
+ CPU_FTRS_E200 = CPU_FTR_USE_TB,
+ CPU_FTRS_E500 = CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB,
+ CPU_FTRS_E500_2 = CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB |
+ CPU_FTR_BIG_PHYS,
+ CPU_FTRS_GENERIC_32 = CPU_FTR_COMMON,
+#ifdef __powerpc64__
+ CPU_FTRS_POWER3 = CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB |
+ CPU_FTR_HPTE_TABLE | CPU_FTR_IABR,
+ CPU_FTRS_RS64 = CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB |
+ CPU_FTR_HPTE_TABLE | CPU_FTR_IABR |
+ CPU_FTR_MMCRA | CPU_FTR_CTRL,
+ CPU_FTRS_POWER4 = CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB |
+ CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_MMCRA,
+ CPU_FTRS_PPC970 = CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB |
+ CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 |
+ CPU_FTR_ALTIVEC_COMP | CPU_FTR_CAN_NAP | CPU_FTR_MMCRA,
+ CPU_FTRS_POWER5 = CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB |
+ CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 |
+ CPU_FTR_MMCRA | CPU_FTR_SMT |
+ CPU_FTR_COHERENT_ICACHE | CPU_FTR_LOCKLESS_TLBIE |
+ CPU_FTR_MMCRA_SIHV,
+ CPU_FTRS_CELL = CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB |
+ CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 |
+ CPU_FTR_ALTIVEC_COMP | CPU_FTR_MMCRA | CPU_FTR_SMT,
+ CPU_FTRS_COMPATIBLE = CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB |
+ CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2,
+#endif
+
+ CPU_FTRS_POSSIBLE =
+#if CLASSIC_PPC
+ CPU_FTRS_PPC601 | CPU_FTRS_603 | CPU_FTRS_604 | CPU_FTRS_740_NOTAU |
+ CPU_FTRS_740 | CPU_FTRS_750 | CPU_FTRS_750FX1 |
+ CPU_FTRS_750FX2 | CPU_FTRS_750FX | CPU_FTRS_750GX |
+ CPU_FTRS_7400_NOTAU | CPU_FTRS_7400 | CPU_FTRS_7450_20 |
+ CPU_FTRS_7450_21 | CPU_FTRS_7450_23 | CPU_FTRS_7455_1 |
+ CPU_FTRS_7455_20 | CPU_FTRS_7455 | CPU_FTRS_7447_10 |
+ CPU_FTRS_7447 | CPU_FTRS_7447A | CPU_FTRS_82XX |
+ CPU_FTRS_G2_LE | CPU_FTRS_E300 | CPU_FTRS_CLASSIC32 |
+#else
+ CPU_FTRS_GENERIC_32 |
+#endif
+#ifdef CONFIG_PPC64BRIDGE
+ CPU_FTRS_POWER3_32 |
+#endif
+#ifdef CONFIG_POWER4
+ CPU_FTRS_POWER4_32 | CPU_FTRS_970_32 |
+#endif
+#ifdef CONFIG_8xx
+ CPU_FTRS_8XX |
+#endif
+#ifdef CONFIG_40x
+ CPU_FTRS_40X |
+#endif
+#ifdef CONFIG_44x
+ CPU_FTRS_44X |
+#endif
+#ifdef CONFIG_E200
+ CPU_FTRS_E200 |
+#endif
+#ifdef CONFIG_E500
+ CPU_FTRS_E500 | CPU_FTRS_E500_2 |
+#endif
+#ifdef __powerpc64__
+ CPU_FTRS_POWER3 | CPU_FTRS_RS64 | CPU_FTRS_POWER4 |
+ CPU_FTRS_PPC970 | CPU_FTRS_POWER5 | CPU_FTRS_CELL |
+ CPU_FTR_CI_LARGE_PAGE |
+#endif
+ 0,
+
+ CPU_FTRS_ALWAYS =
+#if CLASSIC_PPC
+ CPU_FTRS_PPC601 & CPU_FTRS_603 & CPU_FTRS_604 & CPU_FTRS_740_NOTAU &
+ CPU_FTRS_740 & CPU_FTRS_750 & CPU_FTRS_750FX1 &
+ CPU_FTRS_750FX2 & CPU_FTRS_750FX & CPU_FTRS_750GX &
+ CPU_FTRS_7400_NOTAU & CPU_FTRS_7400 & CPU_FTRS_7450_20 &
+ CPU_FTRS_7450_21 & CPU_FTRS_7450_23 & CPU_FTRS_7455_1 &
+ CPU_FTRS_7455_20 & CPU_FTRS_7455 & CPU_FTRS_7447_10 &
+ CPU_FTRS_7447 & CPU_FTRS_7447A & CPU_FTRS_82XX &
+ CPU_FTRS_G2_LE & CPU_FTRS_E300 & CPU_FTRS_CLASSIC32 &
+#else
+ CPU_FTRS_GENERIC_32 &
+#endif
+#ifdef CONFIG_PPC64BRIDGE
+ CPU_FTRS_POWER3_32 &
+#endif
+#ifdef CONFIG_POWER4
+ CPU_FTRS_POWER4_32 & CPU_FTRS_970_32 &
+#endif
+#ifdef CONFIG_8xx
+ CPU_FTRS_8XX &
+#endif
+#ifdef CONFIG_40x
+ CPU_FTRS_40X &
+#endif
+#ifdef CONFIG_44x
+ CPU_FTRS_44X &
+#endif
+#ifdef CONFIG_E200
+ CPU_FTRS_E200 &
+#endif
+#ifdef CONFIG_E500
+ CPU_FTRS_E500 & CPU_FTRS_E500_2 &
+#endif
+#ifdef __powerpc64__
+ CPU_FTRS_POWER3 & CPU_FTRS_RS64 & CPU_FTRS_POWER4 &
+ CPU_FTRS_PPC970 & CPU_FTRS_POWER5 & CPU_FTRS_CELL &
+#endif
+ CPU_FTRS_POSSIBLE,
+};
+
+static inline int cpu_has_feature(unsigned long feature)
+{
+ return (CPU_FTRS_ALWAYS & feature) ||
+ (CPU_FTRS_POSSIBLE
+ & cur_cpu_spec->cpu_features
+ & feature);
+}
+
+#endif /* !__ASSEMBLY__ */
+
+#ifdef __ASSEMBLY__
+
+#define BEGIN_FTR_SECTION 98:
+
+#ifndef __powerpc64__
+#define END_FTR_SECTION(msk, val) \
+99: \
+ .section __ftr_fixup,"a"; \
+ .align 2; \
+ .long msk; \
+ .long val; \
+ .long 98b; \
+ .long 99b; \
+ .previous
+#else /* __powerpc64__ */
+#define END_FTR_SECTION(msk, val) \
+99: \
+ .section __ftr_fixup,"a"; \
+ .align 3; \
+ .llong msk; \
+ .llong val; \
+ .llong 98b; \
+ .llong 99b; \
+ .previous
+#endif /* __powerpc64__ */
+
+#define END_FTR_SECTION_IFSET(msk) END_FTR_SECTION((msk), (msk))
+#define END_FTR_SECTION_IFCLR(msk) END_FTR_SECTION((msk), 0)
+#endif /* __ASSEMBLY__ */
+
+#endif /* __KERNEL__ */
+#endif /* __ASM_POWERPC_CPUTABLE_H */
diff --git a/include/asm-powerpc/current.h b/include/asm-powerpc/current.h
new file mode 100644
index 000000000000..82cd4a9ca99a
--- /dev/null
+++ b/include/asm-powerpc/current.h
@@ -0,0 +1,27 @@
+#ifndef _ASM_POWERPC_CURRENT_H
+#define _ASM_POWERPC_CURRENT_H
+
+/*
+ * 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.
+ */
+
+struct task_struct;
+
+#ifdef __powerpc64__
+#include <asm/paca.h>
+
+#define current (get_paca()->__current)
+
+#else
+
+/*
+ * We keep `current' in r2 for speed.
+ */
+register struct task_struct *current asm ("r2");
+
+#endif
+
+#endif /* _ASM_POWERPC_CURRENT_H */
diff --git a/include/asm-ppc/dbdma.h b/include/asm-powerpc/dbdma.h
index 8973565f95d3..8973565f95d3 100644
--- a/include/asm-ppc/dbdma.h
+++ b/include/asm-powerpc/dbdma.h
diff --git a/include/asm-ppc/dma.h b/include/asm-powerpc/dma.h
index cc8e5cd8c9d2..926378d2cd94 100644
--- a/include/asm-ppc/dma.h
+++ b/include/asm-powerpc/dma.h
@@ -1,18 +1,14 @@
+#ifndef _ASM_POWERPC_DMA_H
+#define _ASM_POWERPC_DMA_H
+
/*
- * include/asm-ppc/dma.h: Defines for using and allocating dma channels.
+ * Defines for using and allocating dma channels.
* Written by Hennus Bergman, 1992.
* High DMA channel support & info by Hannu Savolainen
* and John Boyd, Nov. 1992.
* Changes for ppc sound by Christoph Nadig
*/
-#ifdef __KERNEL__
-
-#include <linux/config.h>
-#include <asm/io.h>
-#include <linux/spinlock.h>
-#include <asm/system.h>
-
/*
* Note: Adapted for PowerPC by Gary Thomas
* Modified by Cort Dougan <cort@cs.nmt.edu>
@@ -25,8 +21,10 @@
* with a grain of salt.
*/
-#ifndef _ASM_DMA_H
-#define _ASM_DMA_H
+#include <linux/config.h>
+#include <asm/io.h>
+#include <linux/spinlock.h>
+#include <asm/system.h>
#ifndef MAX_DMA_CHANNELS
#define MAX_DMA_CHANNELS 8
@@ -34,11 +32,9 @@
/* The maximum address that we can perform a DMA transfer to on this platform */
/* Doesn't really apply... */
-#define MAX_DMA_ADDRESS 0xFFFFFFFF
+#define MAX_DMA_ADDRESS (~0UL)
-/* in arch/ppc/kernel/setup.c -- Cort */
-extern unsigned long DMA_MODE_WRITE, DMA_MODE_READ;
-extern unsigned long ISA_DMA_THRESHOLD;
+#if !defined(CONFIG_PPC_ISERIES) || defined(CONFIG_PCI)
#ifdef HAVE_REALLY_SLOW_DMA_CONTROLLER
#define dma_outb outb_p
@@ -171,7 +167,18 @@ extern long ppc_cs4232_dma, ppc_cs4232_dma2;
#define DMA1_EXT_REG 0x40B
#define DMA2_EXT_REG 0x4D6
+#ifndef __powerpc64__
+ /* in arch/ppc/kernel/setup.c -- Cort */
+ extern unsigned int DMA_MODE_WRITE;
+ extern unsigned int DMA_MODE_READ;
+ extern unsigned long ISA_DMA_THRESHOLD;
+#else
+ #define DMA_MODE_READ 0x44 /* I/O to memory, no autoinit, increment, single mode */
+ #define DMA_MODE_WRITE 0x48 /* memory to I/O, no autoinit, increment, single mode */
+#endif
+
#define DMA_MODE_CASCADE 0xC0 /* pass thru DREQ->HRQ, DACK<-HLDA only */
+
#define DMA_AUTOINIT 0x10
extern spinlock_t dma_spin_lock;
@@ -200,8 +207,9 @@ static __inline__ void enable_dma(unsigned int dmanr)
if (dmanr <= 3) {
dma_outb(dmanr, DMA1_MASK_REG);
dma_outb(ucDmaCmd, DMA1_CMD_REG); /* Enable group */
- } else
+ } else {
dma_outb(dmanr & 3, DMA2_MASK_REG);
+ }
}
static __inline__ void disable_dma(unsigned int dmanr)
@@ -290,19 +298,26 @@ static __inline__ void set_dma_page(unsigned int dmanr, int pagenr)
static __inline__ void set_dma_addr(unsigned int dmanr, unsigned int phys)
{
if (dmanr <= 3) {
- dma_outb(phys & 0xff, ((dmanr & 3) << 1) + IO_DMA1_BASE);
- dma_outb((phys >> 8) & 0xff, ((dmanr & 3) << 1) + IO_DMA1_BASE);
+ dma_outb(phys & 0xff,
+ ((dmanr & 3) << 1) + IO_DMA1_BASE);
+ dma_outb((phys >> 8) & 0xff,
+ ((dmanr & 3) << 1) + IO_DMA1_BASE);
} else if (dmanr == SND_DMA1 || dmanr == SND_DMA2) {
- dma_outb(phys & 0xff, ((dmanr & 3) << 2) + IO_DMA2_BASE);
- dma_outb((phys >> 8) & 0xff, ((dmanr & 3) << 2) + IO_DMA2_BASE);
+ dma_outb(phys & 0xff,
+ ((dmanr & 3) << 2) + IO_DMA2_BASE);
+ dma_outb((phys >> 8) & 0xff,
+ ((dmanr & 3) << 2) + IO_DMA2_BASE);
dma_outb((dmanr & 3), DMA2_EXT_REG);
} else {
- dma_outb((phys >> 1) & 0xff, ((dmanr & 3) << 2) + IO_DMA2_BASE);
- dma_outb((phys >> 9) & 0xff, ((dmanr & 3) << 2) + IO_DMA2_BASE);
+ dma_outb((phys >> 1) & 0xff,
+ ((dmanr & 3) << 2) + IO_DMA2_BASE);
+ dma_outb((phys >> 9) & 0xff,
+ ((dmanr & 3) << 2) + IO_DMA2_BASE);
}
set_dma_page(dmanr, phys >> 16);
}
+
/* Set transfer size (max 64k for DMA1..3, 128k for DMA5..7) for
* a specific DMA channel.
* You must ensure the parameters are valid.
@@ -315,21 +330,24 @@ static __inline__ void set_dma_count(unsigned int dmanr, unsigned int count)
{
count--;
if (dmanr <= 3) {
- dma_outb(count & 0xff, ((dmanr & 3) << 1) + 1 + IO_DMA1_BASE);
- dma_outb((count >> 8) & 0xff, ((dmanr & 3) << 1) + 1 +
- IO_DMA1_BASE);
+ dma_outb(count & 0xff,
+ ((dmanr & 3) << 1) + 1 + IO_DMA1_BASE);
+ dma_outb((count >> 8) & 0xff,
+ ((dmanr & 3) << 1) + 1 + IO_DMA1_BASE);
} else if (dmanr == SND_DMA1 || dmanr == SND_DMA2) {
- dma_outb(count & 0xff, ((dmanr & 3) << 2) + 2 + IO_DMA2_BASE);
- dma_outb((count >> 8) & 0xff, ((dmanr & 3) << 2) + 2 +
- IO_DMA2_BASE);
+ dma_outb(count & 0xff,
+ ((dmanr & 3) << 2) + 2 + IO_DMA2_BASE);
+ dma_outb((count >> 8) & 0xff,
+ ((dmanr & 3) << 2) + 2 + IO_DMA2_BASE);
} else {
- dma_outb((count >> 1) & 0xff, ((dmanr & 3) << 2) + 2 +
- IO_DMA2_BASE);
- dma_outb((count >> 9) & 0xff, ((dmanr & 3) << 2) + 2 +
- IO_DMA2_BASE);
+ dma_outb((count >> 1) & 0xff,
+ ((dmanr & 3) << 2) + 2 + IO_DMA2_BASE);
+ dma_outb((count >> 9) & 0xff,
+ ((dmanr & 3) << 2) + 2 + IO_DMA2_BASE);
}
}
+
/* 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.
@@ -340,8 +358,8 @@ static __inline__ void set_dma_count(unsigned int dmanr, unsigned int count)
*/
static __inline__ int get_dma_residue(unsigned int dmanr)
{
- unsigned int io_port = (dmanr <= 3) ?
- ((dmanr & 3) << 1) + 1 + IO_DMA1_BASE
+ unsigned int io_port = (dmanr <= 3)
+ ? ((dmanr & 3) << 1) + 1 + IO_DMA1_BASE
: ((dmanr & 3) << 2) + 2 + IO_DMA2_BASE;
/* using short to get 16-bit wrap around */
@@ -352,7 +370,6 @@ static __inline__ int get_dma_residue(unsigned int dmanr)
return (dmanr <= 3 || dmanr == SND_DMA1 || dmanr == SND_DMA2)
? count : (count << 1);
-
}
/* These are in kernel/dma.c: */
@@ -367,5 +384,7 @@ extern int isa_dma_bridge_buggy;
#else
#define isa_dma_bridge_buggy (0)
#endif
-#endif /* _ASM_DMA_H */
-#endif /* __KERNEL__ */
+
+#endif /* !defined(CONFIG_PPC_ISERIES) || defined(CONFIG_PCI) */
+
+#endif /* _ASM_POWERPC_DMA_H */
diff --git a/include/asm-powerpc/eeh_event.h b/include/asm-powerpc/eeh_event.h
new file mode 100644
index 000000000000..d168a30b3866
--- /dev/null
+++ b/include/asm-powerpc/eeh_event.h
@@ -0,0 +1,52 @@
+/*
+ * eeh_event.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Copyright (c) 2005 Linas Vepstas <linas@linas.org>
+ */
+
+#ifndef ASM_PPC64_EEH_EVENT_H
+#define ASM_PPC64_EEH_EVENT_H
+
+/** EEH event -- structure holding pci controller data that describes
+ * a change in the isolation status of a PCI slot. A pointer
+ * to this struct is passed as the data pointer in a notify callback.
+ */
+struct eeh_event {
+ struct list_head list;
+ struct device_node *dn; /* struct device node */
+ struct pci_dev *dev; /* affected device */
+ int state;
+ int time_unavail; /* milliseconds until device might be available */
+};
+
+/**
+ * eeh_send_failure_event - generate a PCI error event
+ * @dev pci device
+ *
+ * This routine builds a PCI error event which will be delivered
+ * to all listeners on the peh_notifier_chain.
+ *
+ * This routine can be called within an interrupt context;
+ * the actual event will be delivered in a normal context
+ * (from a workqueue).
+ */
+int eeh_send_failure_event (struct device_node *dn,
+ struct pci_dev *dev,
+ int reset_state,
+ int time_unavail);
+
+#endif /* ASM_PPC64_EEH_EVENT_H */
diff --git a/include/asm-ppc64/elf.h b/include/asm-powerpc/elf.h
index c919a89343db..feac3458d71f 100644
--- a/include/asm-ppc64/elf.h
+++ b/include/asm-powerpc/elf.h
@@ -1,10 +1,13 @@
-#ifndef __PPC64_ELF_H
-#define __PPC64_ELF_H
+#ifndef _ASM_POWERPC_ELF_H
+#define _ASM_POWERPC_ELF_H
+#include <linux/sched.h> /* for task_struct */
#include <asm/types.h>
#include <asm/ptrace.h>
#include <asm/cputable.h>
#include <asm/auxvec.h>
+#include <asm/page.h>
+#include <asm/string.h>
/* PowerPC relocations defined by the ABIs */
#define R_PPC_NONE 0
@@ -75,7 +78,7 @@
#define R_PPC_GOT_DTPREL16_HI 93 /* half16* (sym+add)@got@dtprel@h */
#define R_PPC_GOT_DTPREL16_HA 94 /* half16* (sym+add)@got@dtprel@ha */
-/* Keep this the last entry. */
+/* keep this the last entry. */
#define R_PPC_NUM 95
/*
@@ -90,8 +93,6 @@
#define ELF_NGREG 48 /* includes nip, msr, lr, etc. */
#define ELF_NFPREG 33 /* includes fpscr */
-#define ELF_NVRREG32 33 /* includes vscr & vrsave stuffed together */
-#define ELF_NVRREG 34 /* includes vscr & vrsave in split vectors */
typedef unsigned long elf_greg_t64;
typedef elf_greg_t64 elf_gregset_t64[ELF_NGREG];
@@ -100,8 +101,21 @@ typedef unsigned int elf_greg_t32;
typedef elf_greg_t32 elf_gregset_t32[ELF_NGREG];
/*
- * These are used to set parameters in the core dumps.
+ * ELF_ARCH, CLASS, and DATA are used to set parameters in the core dumps.
*/
+#ifdef __powerpc64__
+# define ELF_NVRREG32 33 /* includes vscr & vrsave stuffed together */
+# define ELF_NVRREG 34 /* includes vscr & vrsave in split vectors */
+# define ELF_GREG_TYPE elf_greg_t64
+#else
+# define ELF_NEVRREG 34 /* includes acc (as 2) */
+# define ELF_NVRREG 33 /* includes vscr */
+# define ELF_GREG_TYPE elf_greg_t32
+# define ELF_ARCH EM_PPC
+# define ELF_CLASS ELFCLASS32
+# define ELF_DATA ELFDATA2MSB
+#endif /* __powerpc64__ */
+
#ifndef ELF_ARCH
# define ELF_ARCH EM_PPC64
# define ELF_CLASS ELFCLASS64
@@ -114,8 +128,9 @@ typedef elf_greg_t32 elf_gregset_t32[ELF_NGREG];
typedef elf_greg_t32 elf_greg_t;
typedef elf_gregset_t32 elf_gregset_t;
# define elf_addr_t u32
-#endif
+#endif /* ELF_ARCH */
+/* Floating point registers */
typedef double elf_fpreg_t;
typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
@@ -125,7 +140,9 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
* The entry with index 32 contains the vscr as the last word (offset 12)
* within the quadword. This allows the vscr to be stored as either a
* quadword (since it must be copied via a vector register to/from storage)
- * or as a word. The entry with index 33 contains the vrsave as the first
+ * or as a word.
+ *
+ * 64-bit kernel notes: The entry at index 33 contains the vrsave as the first
* word (offset 0) within the quadword.
*
* This definition of the VMX state is compatible with the current PPC32
@@ -138,7 +155,9 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
*/
typedef __vector128 elf_vrreg_t;
typedef elf_vrreg_t elf_vrregset_t[ELF_NVRREG];
+#ifdef __powerpc64__
typedef elf_vrreg_t elf_vrregset_t32[ELF_NVRREG32];
+#endif
/*
* This is used to ensure we don't load something for the wrong architecture.
@@ -146,7 +165,7 @@ typedef elf_vrreg_t elf_vrregset_t32[ELF_NVRREG32];
#define elf_check_arch(x) ((x)->e_machine == ELF_ARCH)
#define USE_ELF_CORE_DUMP
-#define ELF_EXEC_PAGESIZE 4096
+#define ELF_EXEC_PAGESIZE PAGE_SIZE
/* This is the location that an ET_DYN program is loaded if exec'ed. Typical
use of this is to invoke "./ld.so someprog" to test out a new version of
@@ -158,26 +177,34 @@ typedef elf_vrreg_t elf_vrregset_t32[ELF_NVRREG32];
#ifdef __KERNEL__
/* Common routine for both 32-bit and 64-bit processes */
-static inline void ppc64_elf_core_copy_regs(elf_gregset_t elf_regs,
+static inline void ppc_elf_core_copy_regs(elf_gregset_t elf_regs,
struct pt_regs *regs)
{
- int i;
- int gprs = sizeof(struct pt_regs)/sizeof(elf_greg_t64);
-
- if (gprs > ELF_NGREG)
- gprs = ELF_NGREG;
-
- for (i=0; i < gprs; i++)
- elf_regs[i] = (elf_greg_t)((elf_greg_t64 *)regs)[i];
+ int i, nregs;
+
+ memset((void *)elf_regs, 0, sizeof(elf_gregset_t));
+
+ /* Our registers are always unsigned longs, whether we're a 32 bit
+ * process or 64 bit, on either a 64 bit or 32 bit kernel.
+ * Don't use ELF_GREG_TYPE here. */
+ nregs = sizeof(struct pt_regs) / sizeof(unsigned long);
+ if (nregs > ELF_NGREG)
+ nregs = ELF_NGREG;
+
+ for (i = 0; i < nregs; i++) {
+ /* This will correctly truncate 64 bit registers to 32 bits
+ * for a 32 bit process on a 64 bit kernel. */
+ elf_regs[i] = (elf_greg_t)((ELF_GREG_TYPE *)regs)[i];
+ }
}
-#define ELF_CORE_COPY_REGS(gregs, regs) ppc64_elf_core_copy_regs(gregs, regs);
+#define ELF_CORE_COPY_REGS(gregs, regs) ppc_elf_core_copy_regs(gregs, regs);
static inline int dump_task_regs(struct task_struct *tsk,
elf_gregset_t *elf_regs)
{
struct pt_regs *regs = tsk->thread.regs;
if (regs)
- ppc64_elf_core_copy_regs(*elf_regs, regs);
+ ppc_elf_core_copy_regs(*elf_regs, regs);
return 1;
}
@@ -186,15 +213,17 @@ static inline int dump_task_regs(struct task_struct *tsk,
extern int dump_task_fpu(struct task_struct *, elf_fpregset_t *);
#define ELF_CORE_COPY_FPREGS(tsk, elf_fpregs) dump_task_fpu(tsk, elf_fpregs)
-/* XXX Should we define the XFPREGS using altivec ??? */
-
-#endif
+#endif /* __KERNEL__ */
-/* This yields a mask that user programs can use to figure out what
+/* ELF_HWCAP yields a mask that user programs can use to figure out what
instruction set this cpu supports. This could be done in userspace,
but it's not easy, and we've already done it here. */
-
-#define ELF_HWCAP (cur_cpu_spec->cpu_user_features)
+# define ELF_HWCAP (cur_cpu_spec->cpu_user_features)
+#ifdef __powerpc64__
+# define ELF_PLAT_INIT(_r, load_addr) do { \
+ _r->gpr[2] = load_addr; \
+} while (0)
+#endif /* __powerpc64__ */
/* This yields a string that ld.so will use to load implementation
specific libraries for optimization. This is more specific in
@@ -205,14 +234,10 @@ extern int dump_task_fpu(struct task_struct *, elf_fpregset_t *);
#define ELF_PLATFORM (NULL)
-#define ELF_PLAT_INIT(_r, load_addr) do { \
- memset(_r->gpr, 0, sizeof(_r->gpr)); \
- _r->ctr = _r->link = _r->xer = _r->ccr = 0; \
- _r->gpr[2] = load_addr; \
-} while (0)
-
#ifdef __KERNEL__
-#define SET_PERSONALITY(ex, ibcs2) \
+
+#ifdef __powerpc64__
+# define SET_PERSONALITY(ex, ibcs2) \
do { \
unsigned long new_flags = 0; \
if ((ex).e_ident[EI_CLASS] == ELFCLASS32) \
@@ -225,7 +250,6 @@ do { \
if (personality(current->personality) != PER_LINUX32) \
set_personality(PER_LINUX); \
} while (0)
-
/*
* An executable for which elf_read_implies_exec() returns TRUE will
* have the READ_IMPLIES_EXEC personality flag set automatically. This
@@ -233,19 +257,26 @@ do { \
* the 64bit ABI has never had these issues dont enable the workaround
* even if we have an executable stack.
*/
-#define elf_read_implies_exec(ex, exec_stk) (test_thread_flag(TIF_32BIT) ? \
+# define elf_read_implies_exec(ex, exec_stk) (test_thread_flag(TIF_32BIT) ? \
(exec_stk != EXSTACK_DISABLE_X) : 0)
+#else
+# define SET_PERSONALITY(ex, ibcs2) set_personality((ibcs2)?PER_SVR4:PER_LINUX)
+#endif /* __powerpc64__ */
-#endif
+#endif /* __KERNEL__ */
extern int dcache_bsize;
extern int icache_bsize;
extern int ucache_bsize;
-/* We do have an arch_setup_additional_pages for vDSO matters */
-#define ARCH_HAS_SETUP_ADDITIONAL_PAGES
+#ifdef __powerpc64__
struct linux_binprm;
+#define ARCH_HAS_SETUP_ADDITIONAL_PAGES /* vDSO has arch_setup_additional_pages */
extern int arch_setup_additional_pages(struct linux_binprm *bprm, int executable_stack);
+#define VDSO_AUX_ENT(a,b) NEW_AUX_ENT(a,b);
+#else
+#define VDSO_AUX_ENT(a,b)
+#endif /* __powerpc64__ */
/*
* The requirements here are:
@@ -265,9 +296,8 @@ do { \
NEW_AUX_ENT(AT_DCACHEBSIZE, dcache_bsize); \
NEW_AUX_ENT(AT_ICACHEBSIZE, icache_bsize); \
NEW_AUX_ENT(AT_UCACHEBSIZE, ucache_bsize); \
- /* vDSO base */ \
- NEW_AUX_ENT(AT_SYSINFO_EHDR, current->thread.vdso_base); \
- } while (0)
+ VDSO_AUX_ENT(AT_SYSINFO_EHDR, current->thread.vdso_base) \
+} while (0)
/* PowerPC64 relocations defined by the ABIs */
#define R_PPC64_NONE R_PPC_NONE
@@ -384,4 +414,4 @@ do { \
/* Keep this the last entry. */
#define R_PPC64_NUM 107
-#endif /* __PPC64_ELF_H */
+#endif /* _ASM_POWERPC_ELF_H */
diff --git a/include/asm-ppc64/firmware.h b/include/asm-powerpc/firmware.h
index 22bb85cf60af..12fabbcb04f0 100644
--- a/include/asm-ppc64/firmware.h
+++ b/include/asm-powerpc/firmware.h
@@ -1,8 +1,4 @@
/*
- * include/asm-ppc64/firmware.h
- *
- * Extracted from include/asm-ppc64/cputable.h
- *
* Copyright (C) 2001 Ben. Herrenschmidt (benh@kernel.crashing.org)
*
* Modifications for ppc64:
@@ -13,8 +9,8 @@
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
-#ifndef __ASM_PPC_FIRMWARE_H
-#define __ASM_PPC_FIRMWARE_H
+#ifndef __ASM_POWERPC_FIRMWARE_H
+#define __ASM_POWERPC_FIRMWARE_H
#ifdef __KERNEL__
@@ -47,6 +43,7 @@
#define FW_FEATURE_ISERIES (1UL<<21)
enum {
+#ifdef CONFIG_PPC64
FW_FEATURE_PSERIES_POSSIBLE = FW_FEATURE_PFT | FW_FEATURE_TCE |
FW_FEATURE_SPRG0 | FW_FEATURE_DABR | FW_FEATURE_COPY |
FW_FEATURE_ASR | FW_FEATURE_DEBUG | FW_FEATURE_TERM |
@@ -74,6 +71,11 @@ enum {
FW_FEATURE_ISERIES_ALWAYS &
#endif
FW_FEATURE_POSSIBLE,
+
+#else /* CONFIG_PPC64 */
+ FW_FEATURE_POSSIBLE = 0,
+ FW_FEATURE_ALWAYS = 0,
+#endif
};
/* This is used to identify firmware features which are available
@@ -98,4 +100,4 @@ extern firmware_feature_t firmware_features_table[];
#endif /* __ASSEMBLY__ */
#endif /* __KERNEL__ */
-#endif /* __ASM_PPC_FIRMWARE_H */
+#endif /* __ASM_POWERPC_FIRMWARE_H */
diff --git a/include/asm-ppc64/futex.h b/include/asm-powerpc/futex.h
index cb2640b3a408..f0319d50b129 100644
--- a/include/asm-ppc64/futex.h
+++ b/include/asm-powerpc/futex.h
@@ -1,34 +1,36 @@
-#ifndef _ASM_FUTEX_H
-#define _ASM_FUTEX_H
+#ifndef _ASM_POWERPC_FUTEX_H
+#define _ASM_POWERPC_FUTEX_H
#ifdef __KERNEL__
#include <linux/futex.h>
#include <asm/errno.h>
-#include <asm/memory.h>
+#include <asm/synch.h>
#include <asm/uaccess.h>
+#include <asm/asm-compat.h>
#define __futex_atomic_op(insn, ret, oldval, uaddr, oparg) \
- __asm__ __volatile (SYNC_ON_SMP \
-"1: lwarx %0,0,%2\n" \
- insn \
-"2: stwcx. %1,0,%2\n\
- bne- 1b\n\
- li %1,0\n\
-3: .section .fixup,\"ax\"\n\
-4: li %1,%3\n\
- b 3b\n\
- .previous\n\
- .section __ex_table,\"a\"\n\
- .align 3\n\
- .llong 1b,4b,2b,4b\n\
- .previous" \
- : "=&r" (oldval), "=&r" (ret) \
- : "b" (uaddr), "i" (-EFAULT), "1" (oparg) \
+ __asm__ __volatile ( \
+ SYNC_ON_SMP \
+"1: lwarx %0,0,%2\n" \
+ insn \
+ PPC405_ERR77(0, %2) \
+"2: stwcx. %1,0,%2\n" \
+ "bne- 1b\n" \
+ "li %1,0\n" \
+"3: .section .fixup,\"ax\"\n" \
+"4: li %1,%3\n" \
+ "b 3b\n" \
+ ".previous\n" \
+ ".section __ex_table,\"a\"\n" \
+ ".align 3\n" \
+ PPC_LONG "1b,4b,2b,4b\n" \
+ ".previous" \
+ : "=&r" (oldval), "=&r" (ret) \
+ : "b" (uaddr), "i" (-EFAULT), "1" (oparg) \
: "cr0", "memory")
-static inline int
-futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
+static inline int futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
{
int op = (encoded_op >> 28) & 7;
int cmp = (encoded_op >> 24) & 15;
@@ -79,5 +81,5 @@ futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
return ret;
}
-#endif
-#endif
+#endif /* __KERNEL__ */
+#endif /* _ASM_POWERPC_FUTEX_H */
diff --git a/include/asm-powerpc/grackle.h b/include/asm-powerpc/grackle.h
new file mode 100644
index 000000000000..563c7a5e64c9
--- /dev/null
+++ b/include/asm-powerpc/grackle.h
@@ -0,0 +1,7 @@
+/*
+ * Functions for setting up and using a MPC106 northbridge
+ */
+
+#include <asm/pci-bridge.h>
+
+extern void setup_grackle(struct pci_controller *hose);
diff --git a/include/asm-ppc/hardirq.h b/include/asm-powerpc/hardirq.h
index 94f1411b1a93..3b3e3b49ec12 100644
--- a/include/asm-ppc/hardirq.h
+++ b/include/asm-powerpc/hardirq.h
@@ -1,11 +1,8 @@
-#ifdef __KERNEL__
-#ifndef __ASM_HARDIRQ_H
-#define __ASM_HARDIRQ_H
+#ifndef _ASM_POWERPC_HARDIRQ_H
+#define _ASM_POWERPC_HARDIRQ_H
-#include <linux/config.h>
-#include <linux/cache.h>
-#include <linux/smp_lock.h>
#include <asm/irq.h>
+#include <asm/bug.h>
/* The __last_jiffy_stamp field is needed to ensure that no decrementer
* interrupt is lost on SMP machines. Since on most CPUs it is in the same
@@ -13,7 +10,7 @@
* for uniformity.
*/
typedef struct {
- unsigned long __softirq_pending; /* set_bit is used on this */
+ unsigned int __softirq_pending; /* set_bit is used on this */
unsigned int __last_jiffy_stamp;
} ____cacheline_aligned irq_cpustat_t;
@@ -27,5 +24,4 @@ static inline void ack_bad_irq(int irq)
BUG();
}
-#endif /* __ASM_HARDIRQ_H */
-#endif /* __KERNEL__ */
+#endif /* _ASM_POWERPC_HARDIRQ_H */
diff --git a/include/asm-ppc/heathrow.h b/include/asm-powerpc/heathrow.h
index 22ac179856b9..22ac179856b9 100644
--- a/include/asm-ppc/heathrow.h
+++ b/include/asm-powerpc/heathrow.h
diff --git a/include/asm-ppc64/hvcall.h b/include/asm-powerpc/hvcall.h
index ab7c3cf24888..d36da61dbc53 100644
--- a/include/asm-ppc64/hvcall.h
+++ b/include/asm-powerpc/hvcall.h
@@ -1,5 +1,5 @@
-#ifndef _PPC64_HVCALL_H
-#define _PPC64_HVCALL_H
+#ifndef _ASM_POWERPC_HVCALL_H
+#define _ASM_POWERPC_HVCALL_H
#define HVSC .long 0x44000022
@@ -138,7 +138,7 @@ long plpar_hcall(unsigned long opcode,
*/
long plpar_hcall_norets(unsigned long opcode, ...);
-/*
+/*
* Special hcall interface for ibmveth support.
* Takes 8 input parms. Returns a rc and stores the
* R4 return value in *out1.
@@ -153,11 +153,11 @@ long plpar_hcall_8arg_2ret(unsigned long opcode,
unsigned long arg7,
unsigned long arg8,
unsigned long *out1);
-
+
/* plpar_hcall_4out()
*
- * same as plpar_hcall except with 4 output arguments.
- *
+ * same as plpar_hcall except with 4 output arguments.
+ *
*/
long plpar_hcall_4out(unsigned long opcode,
unsigned long arg1,
@@ -170,4 +170,4 @@ long plpar_hcall_4out(unsigned long opcode,
unsigned long *out4);
#endif /* __ASSEMBLY__ */
-#endif /* _PPC64_HVCALL_H */
+#endif /* _ASM_POWERPC_HVCALL_H */
diff --git a/include/asm-ppc64/hw_irq.h b/include/asm-powerpc/hw_irq.h
index baea40e695ec..26b89d859c56 100644
--- a/include/asm-ppc64/hw_irq.h
+++ b/include/asm-powerpc/hw_irq.h
@@ -1,23 +1,17 @@
/*
* Copyright (C) 1999 Cort Dougan <cort@cs.nmt.edu>
- *
- * Use inline IRQs where possible - Anton Blanchard <anton@au.ibm.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
*/
+#ifndef _ASM_POWERPC_HW_IRQ_H
+#define _ASM_POWERPC_HW_IRQ_H
+
#ifdef __KERNEL__
-#ifndef _PPC64_HW_IRQ_H
-#define _PPC64_HW_IRQ_H
#include <linux/config.h>
#include <linux/errno.h>
-#include <asm/irq.h>
+#include <asm/ptrace.h>
+#include <asm/processor.h>
-int timer_interrupt(struct pt_regs *);
-extern void ppc_irq_dispatch_handler(struct pt_regs *regs, int irq);
+extern void timer_interrupt(struct pt_regs *);
#ifdef CONFIG_PPC_ISERIES
@@ -33,45 +27,60 @@ extern void local_irq_restore(unsigned long);
#else
-#define local_save_flags(flags) ((flags) = mfmsr())
+#if defined(CONFIG_BOOKE)
+#define SET_MSR_EE(x) mtmsr(x)
+#define local_irq_restore(flags) __asm__ __volatile__("wrtee %0" : : "r" (flags) : "memory")
+#elif defined(__powerpc64__)
+#define SET_MSR_EE(x) __mtmsrd(x, 1)
#define local_irq_restore(flags) do { \
__asm__ __volatile__("": : :"memory"); \
__mtmsrd((flags), 1); \
} while(0)
+#else
+#define SET_MSR_EE(x) mtmsr(x)
+#define local_irq_restore(flags) mtmsr(flags)
+#endif
static inline void local_irq_disable(void)
{
+#ifdef CONFIG_BOOKE
+ __asm__ __volatile__("wrteei 0": : :"memory");
+#else
unsigned long msr;
- msr = mfmsr();
- __mtmsrd(msr & ~MSR_EE, 1);
__asm__ __volatile__("": : :"memory");
+ msr = mfmsr();
+ SET_MSR_EE(msr & ~MSR_EE);
+#endif
}
static inline void local_irq_enable(void)
{
+#ifdef CONFIG_BOOKE
+ __asm__ __volatile__("wrteei 1": : :"memory");
+#else
unsigned long msr;
__asm__ __volatile__("": : :"memory");
msr = mfmsr();
- __mtmsrd(msr | MSR_EE, 1);
+ SET_MSR_EE(msr | MSR_EE);
+#endif
}
-static inline void __do_save_and_cli(unsigned long *flags)
+static inline void local_irq_save_ptr(unsigned long *flags)
{
unsigned long msr;
msr = mfmsr();
*flags = msr;
- __mtmsrd(msr & ~MSR_EE, 1);
+#ifdef CONFIG_BOOKE
+ __asm__ __volatile__("wrteei 0": : :"memory");
+#else
+ SET_MSR_EE(msr & ~MSR_EE);
+#endif
__asm__ __volatile__("": : :"memory");
}
-#define local_irq_save(flags) __do_save_and_cli(&flags)
-
-#define irqs_disabled() \
-({ \
- unsigned long flags; \
- local_save_flags(flags); \
- !(flags & MSR_EE); \
-})
+#define local_save_flags(flags) ((flags) = mfmsr())
+#define local_irq_save(flags) local_irq_save_ptr(&flags)
+#define irqs_disabled() ((mfmsr() & MSR_EE) == 0)
#endif /* CONFIG_PPC_ISERIES */
@@ -99,6 +108,6 @@ static inline void __do_save_and_cli(unsigned long *flags)
*/
struct hw_interrupt_type;
static inline void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i) {}
-
-#endif /* _PPC64_HW_IRQ_H */
-#endif /* __KERNEL__ */
+
+#endif /* __KERNEL__ */
+#endif /* _ASM_POWERPC_HW_IRQ_H */
diff --git a/include/asm-powerpc/i8259.h b/include/asm-powerpc/i8259.h
new file mode 100644
index 000000000000..fc4bfee124d7
--- /dev/null
+++ b/include/asm-powerpc/i8259.h
@@ -0,0 +1,12 @@
+#ifndef _ASM_POWERPC_I8259_H
+#define _ASM_POWERPC_I8259_H
+
+#include <linux/irq.h>
+
+extern struct hw_interrupt_type i8259_pic;
+
+extern void i8259_init(unsigned long intack_addr, int offset);
+extern int i8259_irq(struct pt_regs *regs);
+extern int i8259_irq_cascade(struct pt_regs *regs, void *unused);
+
+#endif /* _ASM_POWERPC_I8259_H */
diff --git a/include/asm-ppc/ide.h b/include/asm-powerpc/ide.h
index 7d6e6599fac4..da5f640480cf 100644
--- a/include/asm-ppc/ide.h
+++ b/include/asm-powerpc/ide.h
@@ -1,24 +1,27 @@
/*
- * linux/include/asm-ppc/ide.h
+ * Copyright (C) 1994-1996 Linus Torvalds & authors
*
- * Copyright (C) 1994-1996 Linus Torvalds & authors */
-
-/*
- * This file contains the ppc architecture specific IDE code.
+ * This file contains the powerpc architecture specific IDE code.
*/
-
-#ifndef __ASMPPC_IDE_H
-#define __ASMPPC_IDE_H
+#ifndef _ASM_POWERPC_IDE_H
+#define _ASM_POWERPC_IDE_H
#ifdef __KERNEL__
+#ifndef __powerpc64__
#include <linux/sched.h>
#include <asm/mpc8xx.h>
+#endif
#ifndef MAX_HWIFS
+#ifdef __powerpc64__
+#define MAX_HWIFS 10
+#else
#define MAX_HWIFS 8
#endif
+#endif
+#ifndef __powerpc64__
#include <linux/config.h>
#include <linux/hdreg.h>
#include <linux/ioport.h>
@@ -59,9 +62,6 @@ static __inline__ unsigned long ide_default_io_base(int index)
return 0;
}
-#define IDE_ARCH_OBSOLETE_INIT
-#define ide_default_io_ctl(base) ((base) + 0x206) /* obsolete */
-
#ifdef CONFIG_PCI
#define ide_init_default_irq(base) (0)
#else
@@ -73,6 +73,11 @@ static __inline__ unsigned long ide_default_io_base(int index)
#define ide_ack_intr(hwif) (hwif->hw.ack_intr ? hwif->hw.ack_intr(hwif) : 1)
#endif
+#endif /* __powerpc64__ */
+
+#define IDE_ARCH_OBSOLETE_INIT
+#define ide_default_io_ctl(base) ((base) + 0x206) /* obsolete */
+
#endif /* __KERNEL__ */
-#endif /* __ASMPPC_IDE_H */
+#endif /* _ASM_POWERPC_IDE_H */
diff --git a/include/asm-powerpc/ioctls.h b/include/asm-powerpc/ioctls.h
index 5b94ff489b8b..279a6229584b 100644
--- a/include/asm-powerpc/ioctls.h
+++ b/include/asm-powerpc/ioctls.h
@@ -62,6 +62,9 @@
# define TIOCM_DSR 0x100
# define TIOCM_CD TIOCM_CAR
# define TIOCM_RI TIOCM_RNG
+#define TIOCM_OUT1 0x2000
+#define TIOCM_OUT2 0x4000
+#define TIOCM_LOOP 0x8000
#define TIOCGSOFTCAR 0x5419
#define TIOCSSOFTCAR 0x541A
diff --git a/include/asm-ppc64/iommu.h b/include/asm-powerpc/iommu.h
index c2f3b6e8a42f..6a35e6570ccd 100644
--- a/include/asm-ppc64/iommu.h
+++ b/include/asm-powerpc/iommu.h
@@ -1,5 +1,4 @@
/*
- * iommu.h
* Copyright (C) 2001 Mike Corrigan & Dave Engebretsen, IBM Corporation
* Rewrite, cleanup:
* Copyright (C) 2004 Olof Johansson <olof@austin.ibm.com>, IBM Corporation
@@ -22,6 +21,7 @@
#ifndef _ASM_IOMMU_H
#define _ASM_IOMMU_H
+#include <linux/config.h>
#include <asm/types.h>
#include <linux/spinlock.h>
#include <linux/device.h>
@@ -29,44 +29,11 @@
/*
* IOMAP_MAX_ORDER defines the largest contiguous block
- * of dma (tce) space we can get. IOMAP_MAX_ORDER = 13
+ * of dma space we can get. IOMAP_MAX_ORDER = 13
* allows up to 2**12 pages (4096 * 4096) = 16 MB
*/
#define IOMAP_MAX_ORDER 13
-/*
- * Tces come in two formats, one for the virtual bus and a different
- * format for PCI
- */
-#define TCE_VB 0
-#define TCE_PCI 1
-
-/* tce_entry
- * Used by pSeries (SMP) and iSeries/pSeries LPAR, but there it's
- * abstracted so layout is irrelevant.
- */
-union tce_entry {
- unsigned long te_word;
- struct {
- unsigned int tb_cacheBits :6; /* Cache hash bits - not used */
- unsigned int tb_rsvd :6;
- unsigned long tb_rpn :40; /* Real page number */
- unsigned int tb_valid :1; /* Tce is valid (vb only) */
- unsigned int tb_allio :1; /* Tce is valid for all lps (vb only) */
- unsigned int tb_lpindex :8; /* LpIndex for user of TCE (vb only) */
- unsigned int tb_pciwr :1; /* Write allowed (pci only) */
- unsigned int tb_rdwr :1; /* Read allowed (pci), Write allowed (vb) */
- } te_bits;
-#define te_cacheBits te_bits.tb_cacheBits
-#define te_rpn te_bits.tb_rpn
-#define te_valid te_bits.tb_valid
-#define te_allio te_bits.tb_allio
-#define te_lpindex te_bits.tb_lpindex
-#define te_pciwr te_bits.tb_pciwr
-#define te_rdwr te_bits.tb_rdwr
-};
-
-
struct iommu_table {
unsigned long it_busno; /* Bus number this table belongs to */
unsigned long it_size; /* Size of iommu table in entries */
@@ -83,6 +50,7 @@ struct iommu_table {
};
struct scatterlist;
+struct device_node;
#ifdef CONFIG_PPC_MULTIPLATFORM
@@ -104,9 +72,13 @@ extern void iommu_devnode_init_pSeries(struct device_node *dn);
#ifdef CONFIG_PPC_ISERIES
-struct iSeries_Device_Node;
/* Creates table for an individual device node */
-extern void iommu_devnode_init_iSeries(struct iSeries_Device_Node *dn);
+extern void iommu_devnode_init_iSeries(struct device_node *dn);
+/* Get table parameters from HV */
+extern void iommu_table_getparms_iSeries(unsigned long busno,
+ unsigned char slotno,
+ unsigned char virtbus,
+ struct iommu_table* tbl);
#endif /* CONFIG_PPC_ISERIES */
diff --git a/include/asm-powerpc/ipcbuf.h b/include/asm-powerpc/ipcbuf.h
new file mode 100644
index 000000000000..2c3e1d94db1d
--- /dev/null
+++ b/include/asm-powerpc/ipcbuf.h
@@ -0,0 +1,34 @@
+#ifndef _ASM_POWERPC_IPCBUF_H
+#define _ASM_POWERPC_IPCBUF_H
+
+/*
+ * The ipc64_perm structure for the powerpc is identical to
+ * kern_ipc_perm as we have always had 32-bit UIDs and GIDs in the
+ * kernel. Note extra padding because this structure is passed back
+ * and forth between kernel and user space. Pad space is left for:
+ * - 1 32-bit value to fill up for 8-byte alignment
+ * - 2 miscellaneous 64-bit values
+ *
+ * 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/types.h>
+
+struct ipc64_perm
+{
+ __kernel_key_t key;
+ __kernel_uid_t uid;
+ __kernel_gid_t gid;
+ __kernel_uid_t cuid;
+ __kernel_gid_t cgid;
+ __kernel_mode_t mode;
+ unsigned int seq;
+ unsigned int __pad1;
+ unsigned long long __unused1;
+ unsigned long long __unused2;
+};
+
+#endif /* _ASM_POWERPC_IPCBUF_H */
diff --git a/include/asm-ppc/irq.h b/include/asm-powerpc/irq.h
index bd9674807f05..c9fbcede0ef9 100644
--- a/include/asm-ppc/irq.h
+++ b/include/asm-powerpc/irq.h
@@ -1,11 +1,23 @@
#ifdef __KERNEL__
-#ifndef _ASM_IRQ_H
-#define _ASM_IRQ_H
+#ifndef _ASM_POWERPC_IRQ_H
+#define _ASM_POWERPC_IRQ_H
+
+/*
+ * 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/config.h>
-#include <asm/machdep.h> /* ppc_md */
+#include <linux/threads.h>
+
+#include <asm/types.h>
#include <asm/atomic.h>
+/* this number is used when no interrupt has been assigned */
+#define NO_IRQ (-1)
+
/*
* These constants are used for passing information about interrupt
* signal polarity and level/edge sensing to the low-level PIC chip
@@ -24,6 +36,50 @@
*/
#define ARCH_HAS_IRQ_PER_CPU
+#define get_irq_desc(irq) (&irq_desc[(irq)])
+
+/* Define a way to iterate across irqs. */
+#define for_each_irq(i) \
+ for ((i) = 0; (i) < NR_IRQS; ++(i))
+
+#ifdef CONFIG_PPC64
+
+/*
+ * Maximum number of interrupt sources that we can handle.
+ */
+#define NR_IRQS 512
+
+/* Interrupt numbers are virtual in case they are sparsely
+ * distributed by the hardware.
+ */
+extern unsigned int virt_irq_to_real_map[NR_IRQS];
+
+/* Create a mapping for a real_irq if it doesn't already exist.
+ * Return the virtual irq as a convenience.
+ */
+int virt_irq_create_mapping(unsigned int real_irq);
+void virt_irq_init(void);
+
+static inline unsigned int virt_irq_to_real(unsigned int virt_irq)
+{
+ return virt_irq_to_real_map[virt_irq];
+}
+
+extern unsigned int real_irq_to_virt_slowpath(unsigned int real_irq);
+
+/*
+ * List of interrupt controllers.
+ */
+#define IC_INVALID 0
+#define IC_OPEN_PIC 1
+#define IC_PPC_XIC 2
+#define IC_CELL_PIC 3
+#define IC_ISERIES 4
+
+extern u64 ppc64_interrupt_controller;
+
+#else /* 32-bit */
+
#if defined(CONFIG_40x)
#include <asm/ibm4xx.h>
@@ -66,11 +122,6 @@
#define NR_UIC_IRQS UIC_WIDTH
#define NR_IRQS ((NR_UIC_IRQS * NR_UICS) + NR_BOARD_IRQS)
#endif
-static __inline__ int
-irq_canonicalize(int irq)
-{
- return (irq);
-}
#elif defined(CONFIG_44x)
#include <asm/ibm44x.h>
@@ -78,12 +129,6 @@ irq_canonicalize(int irq)
#define NR_UIC_IRQS 32
#define NR_IRQS ((NR_UIC_IRQS * NR_UICS) + NR_BOARD_IRQS)
-static __inline__ int
-irq_canonicalize(int irq)
-{
- return (irq);
-}
-
#elif defined(CONFIG_8xx)
/* Now include the board configuration specific associations.
@@ -170,20 +215,9 @@ irq_canonicalize(int irq)
*/
#define mk_int_int_mask(IL) (1 << (7 - (IL/2)))
-/* always the same on 8xx -- Cort */
-static __inline__ int irq_canonicalize(int irq)
-{
- return irq;
-}
-
#elif defined(CONFIG_83xx)
#include <asm/mpc83xx.h>
-static __inline__ int irq_canonicalize(int irq)
-{
- return irq;
-}
-
#define NR_IRQS (NR_IPIC_INTS)
#elif defined(CONFIG_85xx)
@@ -307,17 +341,13 @@ static __inline__ int irq_canonicalize(int irq)
#define SIU_INT_PC1 ((uint)0x3e+CPM_IRQ_OFFSET)
#define SIU_INT_PC0 ((uint)0x3f+CPM_IRQ_OFFSET)
-static __inline__ int irq_canonicalize(int irq)
-{
- return irq;
-}
-
#else /* CONFIG_40x + CONFIG_8xx */
/*
* this is the # irq's for all ppc arch's (pmac/chrp/prep)
* so it is the max of them all
*/
#define NR_IRQS 256
+#define __DO_IRQ_CANON 1
#ifndef CONFIG_8260
@@ -394,25 +424,80 @@ static __inline__ int irq_canonicalize(int irq)
#endif /* CONFIG_8260 */
+#endif
+
+#define NR_MASK_WORDS ((NR_IRQS + 31) / 32)
+/* pedantic: these are long because they are used with set_bit --RR */
+extern unsigned long ppc_cached_irq_mask[NR_MASK_WORDS];
+extern atomic_t ppc_n_lost_interrupts;
+
+#define virt_irq_create_mapping(x) (x)
+
+#endif
+
/*
- * This gets called from serial.c, which is now used on
- * powermacs as well as prep/chrp boxes.
- * Prep and chrp both have cascaded 8259 PICs.
+ * Because many systems have two overlapping names spaces for
+ * interrupts (ISA and XICS for example), and the ISA interrupts
+ * have historically not been easy to renumber, we allow ISA
+ * interrupts to take values 0 - 15, and shift up the remaining
+ * interrupts by 0x10.
*/
+#define NUM_ISA_INTERRUPTS 0x10
+extern int __irq_offset_value;
+
+static inline int irq_offset_up(int irq)
+{
+ return(irq + __irq_offset_value);
+}
+
+static inline int irq_offset_down(int irq)
+{
+ return(irq - __irq_offset_value);
+}
+
+static inline int irq_offset_value(void)
+{
+ return __irq_offset_value;
+}
+
+#ifdef __DO_IRQ_CANON
+extern int ppc_do_canonicalize_irqs;
+#else
+#define ppc_do_canonicalize_irqs 0
+#endif
+
static __inline__ int irq_canonicalize(int irq)
{
- if (ppc_md.irq_canonicalize)
- return ppc_md.irq_canonicalize(irq);
+ if (ppc_do_canonicalize_irqs && irq == 2)
+ irq = 9;
return irq;
}
-#endif
+extern int distribute_irqs;
-#define NR_MASK_WORDS ((NR_IRQS + 31) / 32)
-/* pedantic: these are long because they are used with set_bit --RR */
-extern unsigned long ppc_cached_irq_mask[NR_MASK_WORDS];
-extern unsigned long ppc_lost_interrupts[NR_MASK_WORDS];
-extern atomic_t ppc_n_lost_interrupts;
+struct irqaction;
+struct pt_regs;
+
+#ifdef CONFIG_IRQSTACKS
+/*
+ * Per-cpu stacks for handling hard and soft interrupts.
+ */
+extern struct thread_info *hardirq_ctx[NR_CPUS];
+extern struct thread_info *softirq_ctx[NR_CPUS];
+
+extern void irq_ctx_init(void);
+extern void call_do_softirq(struct thread_info *tp);
+extern int call___do_IRQ(int irq, struct pt_regs *regs,
+ struct thread_info *tp);
+
+#define __ARCH_HAS_DO_SOFTIRQ
+
+#else
+#define irq_ctx_init()
+
+#endif /* CONFIG_IRQSTACKS */
+
+extern void do_IRQ(struct pt_regs *regs);
#endif /* _ASM_IRQ_H */
#endif /* __KERNEL__ */
diff --git a/include/asm-ppc64/iSeries/HvCall.h b/include/asm-powerpc/iseries/hv_call.h
index c3f19475c0d9..e9f831c9a5e5 100644
--- a/include/asm-ppc64/iSeries/HvCall.h
+++ b/include/asm-powerpc/iseries/hv_call.h
@@ -20,11 +20,11 @@
* This file contains the "hypervisor call" interface which is used to
* drive the hypervisor from the OS.
*/
-#ifndef _HVCALL_H
-#define _HVCALL_H
+#ifndef _ASM_POWERPC_ISERIES_HV_CALL_H
+#define _ASM_POWERPC_ISERIES_HV_CALL_H
-#include <asm/iSeries/HvCallSc.h>
-#include <asm/iSeries/HvTypes.h>
+#include <asm/iseries/hv_call_sc.h>
+#include <asm/iseries/hv_types.h>
#include <asm/paca.h>
/* Type of yield for HvCallBaseYieldProcessor */
@@ -110,4 +110,4 @@ static inline void HvCall_sendIPI(struct paca_struct *targetPaca)
HvCall1(HvCallBaseSendIPI, targetPaca->paca_index);
}
-#endif /* _HVCALL_H */
+#endif /* _ASM_POWERPC_ISERIES_HV_CALL_H */
diff --git a/include/asm-ppc64/iSeries/HvCallEvent.h b/include/asm-powerpc/iseries/hv_call_event.h
index 5d9a327d0122..46763a30590a 100644
--- a/include/asm-ppc64/iSeries/HvCallEvent.h
+++ b/include/asm-powerpc/iseries/hv_call_event.h
@@ -20,11 +20,11 @@
* This file contains the "hypervisor call" interface which is used to
* drive the hypervisor from the OS.
*/
-#ifndef _HVCALLEVENT_H
-#define _HVCALLEVENT_H
+#ifndef _ASM_POWERPC_ISERIES_HV_CALL_EVENT_H
+#define _ASM_POWERPC_ISERIES_HV_CALL_EVENT_H
-#include <asm/iSeries/HvCallSc.h>
-#include <asm/iSeries/HvTypes.h>
+#include <asm/iseries/hv_call_sc.h>
+#include <asm/iseries/hv_types.h>
#include <asm/abs_addr.h>
struct HvLpEvent;
@@ -250,4 +250,4 @@ static inline HvLpDma_Rc HvCallEvent_dmaToSp(void *local, u32 remote,
return HvCall4(HvCallEventDmaToSp, abs_addr, remote, length, dir);
}
-#endif /* _HVCALLEVENT_H */
+#endif /* _ASM_POWERPC_ISERIES_HV_CALL_EVENT_H */
diff --git a/include/asm-ppc64/iSeries/HvCallSc.h b/include/asm-powerpc/iseries/hv_call_sc.h
index a62cef3822f9..dec7e9d9ab78 100644
--- a/include/asm-ppc64/iSeries/HvCallSc.h
+++ b/include/asm-powerpc/iseries/hv_call_sc.h
@@ -16,8 +16,8 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#ifndef _HVCALLSC_H
-#define _HVCALLSC_H
+#ifndef _ASM_POWERPC_ISERIES_HV_CALL_SC_H
+#define _ASM_POWERPC_ISERIES_HV_CALL_SC_H
#include <linux/types.h>
@@ -48,4 +48,4 @@ extern u64 HvCall5Ret16(u64, void *, u64, u64, u64, u64, u64);
extern u64 HvCall6Ret16(u64, void *, u64, u64, u64, u64, u64, u64);
extern u64 HvCall7Ret16(u64, void *, u64, u64 ,u64 ,u64 ,u64 ,u64 ,u64);
-#endif /* _HVCALLSC_H */
+#endif /* _ASM_POWERPC_ISERIES_HV_CALL_SC_H */
diff --git a/include/asm-ppc64/iSeries/HvCallXm.h b/include/asm-powerpc/iseries/hv_call_xm.h
index 8b9ba608daaf..ca9202cb01ed 100644
--- a/include/asm-ppc64/iSeries/HvCallXm.h
+++ b/include/asm-powerpc/iseries/hv_call_xm.h
@@ -2,11 +2,11 @@
* This file contains the "hypervisor call" interface which is used to
* drive the hypervisor from SLIC.
*/
-#ifndef _HVCALLXM_H
-#define _HVCALLXM_H
+#ifndef _ASM_POWERPC_ISERIES_HV_CALL_XM_H
+#define _ASM_POWERPC_ISERIES_HV_CALL_XM_H
-#include <asm/iSeries/HvCallSc.h>
-#include <asm/iSeries/HvTypes.h>
+#include <asm/iseries/hv_call_sc.h>
+#include <asm/iseries/hv_types.h>
#define HvCallXmGetTceTableParms HvCallXm + 0
#define HvCallXmTestBus HvCallXm + 1
@@ -75,4 +75,4 @@ static inline u64 HvCallXm_loadTod(void)
return HvCall0(HvCallXmLoadTod);
}
-#endif /* _HVCALLXM_H */
+#endif /* _ASM_POWERPC_ISERIES_HV_CALL_XM_H */
diff --git a/include/asm-ppc64/iSeries/HvLpConfig.h b/include/asm-powerpc/iseries/hv_lp_config.h
index f1cf1e70ca3c..bc00f036bca0 100644
--- a/include/asm-ppc64/iSeries/HvLpConfig.h
+++ b/include/asm-powerpc/iseries/hv_lp_config.h
@@ -16,17 +16,17 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#ifndef _HVLPCONFIG_H
-#define _HVLPCONFIG_H
+#ifndef _ASM_POWERPC_ISERIES_HV_LP_CONFIG_H
+#define _ASM_POWERPC_ISERIES_HV_LP_CONFIG_H
/*
* This file contains the interface to the LPAR configuration data
* to determine which resources should be allocated to each partition.
*/
-#include <asm/iSeries/HvCallSc.h>
-#include <asm/iSeries/HvTypes.h>
-#include <asm/iSeries/ItLpNaca.h>
+#include <asm/iseries/hv_call_sc.h>
+#include <asm/iseries/hv_types.h>
+#include <asm/iseries/it_lp_naca.h>
enum {
HvCallCfg_Cur = 0,
@@ -135,4 +135,4 @@ static inline HvLpIndex HvLpConfig_getHostingLpIndex(HvLpIndex lp)
return HvCall1(HvCallCfgGetHostingLpIndex, lp);
}
-#endif /* _HVLPCONFIG_H */
+#endif /* _ASM_POWERPC_ISERIES_HV_LP_CONFIG_H */
diff --git a/include/asm-ppc64/iSeries/HvLpEvent.h b/include/asm-powerpc/iseries/hv_lp_event.h
index 865000de79b6..499ab1ad0185 100644
--- a/include/asm-ppc64/iSeries/HvLpEvent.h
+++ b/include/asm-powerpc/iseries/hv_lp_event.h
@@ -19,13 +19,13 @@
/* This file contains the class for HV events in the system. */
-#ifndef _HVLPEVENT_H
-#define _HVLPEVENT_H
+#ifndef _ASM_POWERPC_ISERIES_HV_LP_EVENT_H
+#define _ASM_POWERPC_ISERIES_HV_LP_EVENT_H
#include <asm/types.h>
#include <asm/ptrace.h>
-#include <asm/iSeries/HvTypes.h>
-#include <asm/iSeries/HvCallEvent.h>
+#include <asm/iseries/hv_types.h>
+#include <asm/iseries/hv_call_event.h>
/*
* HvLpEvent is the structure for Lp Event messages passed between
@@ -139,4 +139,4 @@ extern int HvLpEvent_closePath(HvLpEvent_Type eventType, HvLpIndex lpIndex);
#define HvLpDma_Rc_InvalidAddress 4
#define HvLpDma_Rc_InvalidLength 5
-#endif /* _HVLPEVENT_H */
+#endif /* _ASM_POWERPC_ISERIES_HV_LP_EVENT_H */
diff --git a/include/asm-ppc64/iSeries/HvTypes.h b/include/asm-powerpc/iseries/hv_types.h
index b1ef2b4cb3e3..c38f7e3d01dc 100644
--- a/include/asm-ppc64/iSeries/HvTypes.h
+++ b/include/asm-powerpc/iseries/hv_types.h
@@ -16,8 +16,8 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#ifndef _HVTYPES_H
-#define _HVTYPES_H
+#ifndef _ASM_POWERPC_ISERIES_HV_TYPES_H
+#define _ASM_POWERPC_ISERIES_HV_TYPES_H
/*
* General typedefs for the hypervisor.
@@ -110,4 +110,4 @@ struct HvLpBufferList {
u64 len;
};
-#endif /* _HVTYPES_H */
+#endif /* _ASM_POWERPC_ISERIES_HV_TYPES_H */
diff --git a/include/asm-ppc64/iSeries/iSeries_io.h b/include/asm-powerpc/iseries/iseries_io.h
index 9f79413342b3..56b2113ff0f5 100644
--- a/include/asm-ppc64/iSeries/iSeries_io.h
+++ b/include/asm-powerpc/iseries/iseries_io.h
@@ -1,5 +1,5 @@
-#ifndef _ISERIES_IO_H
-#define _ISERIES_IO_H
+#ifndef _ASM_POWERPC_ISERIES_ISERIES_IO_H
+#define _ASM_POWERPC_ISERIES_ISERIES_IO_H
#include <linux/config.h>
@@ -46,4 +46,4 @@ extern void iSeries_memcpy_fromio(void *dest,
const volatile void __iomem *source, size_t n);
#endif /* CONFIG_PPC_ISERIES */
-#endif /* _ISERIES_IO_H */
+#endif /* _ASM_POWERPC_ISERIES_ISERIES_IO_H */
diff --git a/include/asm-ppc64/iSeries/ItExtVpdPanel.h b/include/asm-powerpc/iseries/it_exp_vpd_panel.h
index 4c546a8802b4..66a17a230c52 100644
--- a/include/asm-ppc64/iSeries/ItExtVpdPanel.h
+++ b/include/asm-powerpc/iseries/it_exp_vpd_panel.h
@@ -16,8 +16,8 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#ifndef _ITEXTVPDPANEL_H
-#define _ITEXTVPDPANEL_H
+#ifndef _ASM_POWERPC_ISERIES_IT_EXT_VPD_PANEL_H
+#define _ASM_POWERPC_ISERIES_IT_EXT_VPD_PANEL_H
/*
* This struct maps the panel information
@@ -49,4 +49,4 @@ struct ItExtVpdPanel {
extern struct ItExtVpdPanel xItExtVpdPanel;
-#endif /* _ITEXTVPDPANEL_H */
+#endif /* _ASM_POWERPC_ISERIES_IT_EXT_VPD_PANEL_H */
diff --git a/include/asm-ppc64/iSeries/ItLpNaca.h b/include/asm-powerpc/iseries/it_lp_naca.h
index 225d0176779d..c3ef1de45d82 100644
--- a/include/asm-ppc64/iSeries/ItLpNaca.h
+++ b/include/asm-powerpc/iseries/it_lp_naca.h
@@ -16,8 +16,8 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#ifndef _ITLPNACA_H
-#define _ITLPNACA_H
+#ifndef _ASM_POWERPC_ISERIES_IT_LP_NACA_H
+#define _ASM_POWERPC_ISERIES_IT_LP_NACA_H
#include <linux/types.h>
@@ -77,4 +77,4 @@ struct ItLpNaca {
extern struct ItLpNaca itLpNaca;
-#endif /* _ITLPNACA_H */
+#endif /* _ASM_POWERPC_ISERIES_IT_LP_NACA_H */
diff --git a/include/asm-ppc64/iSeries/ItLpQueue.h b/include/asm-powerpc/iseries/it_lp_queue.h
index 69b26ad74135..a60d03afbf95 100644
--- a/include/asm-ppc64/iSeries/ItLpQueue.h
+++ b/include/asm-powerpc/iseries/it_lp_queue.h
@@ -16,8 +16,8 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#ifndef _ITLPQUEUE_H
-#define _ITLPQUEUE_H
+#ifndef _ASM_POWERPC_ISERIES_IT_LP_QUEUE_H
+#define _ASM_POWERPC_ISERIES_IT_LP_QUEUE_H
/*
* This control block defines the simple LP queue structure that is
@@ -78,4 +78,4 @@ extern int hvlpevent_is_pending(void);
extern void process_hvlpevents(struct pt_regs *);
extern void setup_hvlpevent_queue(void);
-#endif /* _ITLPQUEUE_H */
+#endif /* _ASM_POWERPC_ISERIES_IT_LP_QUEUE_H */
diff --git a/include/asm-ppc64/iSeries/ItLpRegSave.h b/include/asm-powerpc/iseries/it_lp_reg_save.h
index 1b3087e76205..288044b702de 100644
--- a/include/asm-ppc64/iSeries/ItLpRegSave.h
+++ b/include/asm-powerpc/iseries/it_lp_reg_save.h
@@ -16,8 +16,8 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#ifndef _ITLPREGSAVE_H
-#define _ITLPREGSAVE_H
+#ifndef _ASM_POWERPC_ISERIES_IT_LP_REG_SAVE_H
+#define _ASM_POWERPC_ISERIES_IT_LP_REG_SAVE_H
/*
* This control block contains the data that is shared between PLIC
diff --git a/include/asm-ppc64/iSeries/LparMap.h b/include/asm-powerpc/iseries/lpar_map.h
index a6840b186d03..84fc321615bf 100644
--- a/include/asm-ppc64/iSeries/LparMap.h
+++ b/include/asm-powerpc/iseries/lpar_map.h
@@ -16,8 +16,8 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#ifndef _LPARMAP_H
-#define _LPARMAP_H
+#ifndef _ASM_POWERPC_ISERIES_LPAR_MAP_H
+#define _ASM_POWERPC_ISERIES_LPAR_MAP_H
#ifndef __ASSEMBLY__
@@ -80,4 +80,4 @@ extern const struct LparMap xLparMap;
/* the fixed address where the LparMap exists */
#define LPARMAP_PHYS 0x7000
-#endif /* _LPARMAP_H */
+#endif /* _ASM_POWERPC_ISERIES_LPAR_MAP_H */
diff --git a/include/asm-ppc64/iSeries/mf.h b/include/asm-powerpc/iseries/mf.h
index 7e6a0d936999..e7bd57a03fb1 100644
--- a/include/asm-ppc64/iSeries/mf.h
+++ b/include/asm-powerpc/iseries/mf.h
@@ -23,13 +23,13 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#ifndef _ASM_PPC64_ISERIES_MF_H
-#define _ASM_PPC64_ISERIES_MF_H
+#ifndef _ASM_POWERPC_ISERIES_MF_H
+#define _ASM_POWERPC_ISERIES_MF_H
#include <linux/types.h>
-#include <asm/iSeries/HvTypes.h>
-#include <asm/iSeries/HvCallEvent.h>
+#include <asm/iseries/hv_types.h>
+#include <asm/iseries/hv_call_event.h>
struct rtc_time;
@@ -54,4 +54,4 @@ extern int mf_get_rtc(struct rtc_time *tm);
extern int mf_get_boot_rtc(struct rtc_time *tm);
extern int mf_set_rtc(struct rtc_time *tm);
-#endif /* _ASM_PPC64_ISERIES_MF_H */
+#endif /* _ASM_POWERPC_ISERIES_MF_H */
diff --git a/include/asm-ppc64/iSeries/vio.h b/include/asm-powerpc/iseries/vio.h
index 6c05e6257f53..7e3a469420dd 100644
--- a/include/asm-ppc64/iSeries/vio.h
+++ b/include/asm-powerpc/iseries/vio.h
@@ -38,11 +38,11 @@
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
-#ifndef _ISERIES_VIO_H
-#define _ISERIES_VIO_H
+#ifndef _ASM_POWERPC_ISERIES_VIO_H
+#define _ASM_POWERPC_ISERIES_VIO_H
-#include <asm/iSeries/HvTypes.h>
-#include <asm/iSeries/HvLpEvent.h>
+#include <asm/iseries/hv_types.h>
+#include <asm/iseries/hv_lp_event.h>
/*
* iSeries virtual I/O events use the subtype field in
@@ -127,4 +127,4 @@ struct device;
extern struct device *iSeries_vio_dev;
-#endif /* _ISERIES_VIO_H */
+#endif /* _ASM_POWERPC_ISERIES_VIO_H */
diff --git a/include/asm-ppc64/kdebug.h b/include/asm-powerpc/kdebug.h
index d383d161cf8d..9dcbac674811 100644
--- a/include/asm-ppc64/kdebug.h
+++ b/include/asm-powerpc/kdebug.h
@@ -1,5 +1,5 @@
-#ifndef _PPC64_KDEBUG_H
-#define _PPC64_KDEBUG_H 1
+#ifndef _ASM_POWERPC_KDEBUG_H
+#define _ASM_POWERPC_KDEBUG_H
/* nearly identical to x86_64/i386 code */
@@ -21,7 +21,7 @@ struct die_args {
then free.
*/
int register_die_notifier(struct notifier_block *nb);
-extern struct notifier_block *ppc64_die_chain;
+extern struct notifier_block *powerpc_die_chain;
/* Grossly misnamed. */
enum die_val {
@@ -30,14 +30,13 @@ enum die_val {
DIE_DABR_MATCH,
DIE_BPT,
DIE_SSTEP,
- DIE_GPF,
DIE_PAGE_FAULT,
};
static inline int notify_die(enum die_val val,char *str,struct pt_regs *regs,long err,int trap, int sig)
{
struct die_args args = { .regs=regs, .str=str, .err=err, .trapnr=trap,.signr=sig };
- return notifier_call_chain(&ppc64_die_chain, val, &args);
+ return notifier_call_chain(&powerpc_die_chain, val, &args);
}
-#endif
+#endif /* _ASM_POWERPC_KDEBUG_H */
diff --git a/include/asm-powerpc/kexec.h b/include/asm-powerpc/kexec.h
new file mode 100644
index 000000000000..062ab9ba68eb
--- /dev/null
+++ b/include/asm-powerpc/kexec.h
@@ -0,0 +1,49 @@
+#ifndef _ASM_POWERPC_KEXEC_H
+#define _ASM_POWERPC_KEXEC_H
+
+/*
+ * Maximum page that is mapped directly into kernel memory.
+ * XXX: Since we copy virt we can use any page we allocate
+ */
+#define KEXEC_SOURCE_MEMORY_LIMIT (-1UL)
+
+/*
+ * Maximum address we can reach in physical address mode.
+ * XXX: I want to allow initrd in highmem. Otherwise set to rmo on LPAR.
+ */
+#define KEXEC_DESTINATION_MEMORY_LIMIT (-1UL)
+
+/* Maximum address we can use for the control code buffer */
+#ifdef __powerpc64__
+#define KEXEC_CONTROL_MEMORY_LIMIT (-1UL)
+#else
+/* TASK_SIZE, probably left over from use_mm ?? */
+#define KEXEC_CONTROL_MEMORY_LIMIT TASK_SIZE
+#endif
+
+#define KEXEC_CONTROL_CODE_SIZE 4096
+
+/* The native architecture */
+#ifdef __powerpc64__
+#define KEXEC_ARCH KEXEC_ARCH_PPC64
+#else
+#define KEXEC_ARCH KEXEC_ARCH_PPC
+#endif
+
+#ifndef __ASSEMBLY__
+
+#define MAX_NOTE_BYTES 1024
+typedef u32 note_buf_t[MAX_NOTE_BYTES / sizeof(u32)];
+
+extern note_buf_t crash_notes[];
+
+#ifdef __powerpc64__
+extern void kexec_smp_wait(void); /* get and clear naca physid, wait for
+ master to copy new code to 0 */
+#else
+struct kimage;
+extern void machine_kexec_simple(struct kimage *image);
+#endif
+
+#endif /* ! __ASSEMBLY__ */
+#endif /* _ASM_POWERPC_KEXEC_H */
diff --git a/include/asm-ppc/keylargo.h b/include/asm-powerpc/keylargo.h
index a669a3f0f5a2..a669a3f0f5a2 100644
--- a/include/asm-ppc/keylargo.h
+++ b/include/asm-powerpc/keylargo.h
diff --git a/include/asm-powerpc/kmap_types.h b/include/asm-powerpc/kmap_types.h
new file mode 100644
index 000000000000..b6bac6f61c16
--- /dev/null
+++ b/include/asm-powerpc/kmap_types.h
@@ -0,0 +1,33 @@
+#ifndef _ASM_POWERPC_KMAP_TYPES_H
+#define _ASM_POWERPC_KMAP_TYPES_H
+
+#ifdef __KERNEL__
+
+/*
+ * 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.
+ */
+
+enum km_type {
+ KM_BOUNCE_READ,
+ KM_SKB_SUNRPC_DATA,
+ KM_SKB_DATA_SOFTIRQ,
+ KM_USER0,
+ KM_USER1,
+ KM_BIO_SRC_IRQ,
+ KM_BIO_DST_IRQ,
+ KM_PTE0,
+ KM_PTE1,
+ KM_IRQ0,
+ KM_IRQ1,
+ KM_SOFTIRQ0,
+ KM_SOFTIRQ1,
+ KM_PPC_SYNC_PAGE,
+ KM_PPC_SYNC_ICACHE,
+ KM_TYPE_NR
+};
+
+#endif /* __KERNEL__ */
+#endif /* _ASM_POWERPC_KMAP_TYPES_H */
diff --git a/include/asm-ppc64/kprobes.h b/include/asm-powerpc/kprobes.h
index d9129d2b038e..6cd0a3bfa280 100644
--- a/include/asm-ppc64/kprobes.h
+++ b/include/asm-powerpc/kprobes.h
@@ -1,8 +1,7 @@
-#ifndef _ASM_KPROBES_H
-#define _ASM_KPROBES_H
+#ifndef _ASM_POWERPC_KPROBES_H
+#define _ASM_POWERPC_KPROBES_H
/*
* Kernel Probes (KProbes)
- * include/asm-ppc64/kprobes.h
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -28,6 +27,7 @@
*/
#include <linux/types.h>
#include <linux/ptrace.h>
+#include <linux/percpu.h>
struct pt_regs;
@@ -54,6 +54,20 @@ struct arch_specific_insn {
kprobe_opcode_t *insn;
};
+struct prev_kprobe {
+ struct kprobe *kp;
+ unsigned long status;
+ unsigned long saved_msr;
+};
+
+/* per-cpu kprobe control block */
+struct kprobe_ctlblk {
+ unsigned long kprobe_status;
+ unsigned long kprobe_saved_msr;
+ struct pt_regs jprobe_saved_regs;
+ struct prev_kprobe prev_kprobe;
+};
+
#ifdef CONFIG_KPROBES
extern int kprobe_exceptions_notify(struct notifier_block *self,
unsigned long val, void *data);
@@ -64,4 +78,4 @@ static inline int kprobe_exceptions_notify(struct notifier_block *self,
return 0;
}
#endif
-#endif /* _ASM_KPROBES_H */
+#endif /* _ASM_POWERPC_KPROBES_H */
diff --git a/include/asm-ppc64/lmb.h b/include/asm-powerpc/lmb.h
index de91e034bd98..ea0afe343545 100644
--- a/include/asm-ppc64/lmb.h
+++ b/include/asm-powerpc/lmb.h
@@ -50,7 +50,7 @@ extern unsigned long __init lmb_alloc_base(unsigned long, unsigned long,
extern unsigned long __init lmb_phys_mem_size(void);
extern unsigned long __init lmb_end_of_DRAM(void);
extern unsigned long __init lmb_abs_to_phys(unsigned long);
-extern void __init lmb_enforce_memory_limit(void);
+extern void __init lmb_enforce_memory_limit(unsigned long);
extern void lmb_dump_all(void);
diff --git a/include/asm-ppc64/lppaca.h b/include/asm-powerpc/lppaca.h
index 9e2a6c0649a0..c1bedab1515b 100644
--- a/include/asm-ppc64/lppaca.h
+++ b/include/asm-powerpc/lppaca.h
@@ -16,8 +16,8 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#ifndef _ASM_LPPACA_H
-#define _ASM_LPPACA_H
+#ifndef _ASM_POWERPC_LPPACA_H
+#define _ASM_POWERPC_LPPACA_H
//=============================================================================
//
@@ -28,8 +28,7 @@
//----------------------------------------------------------------------------
#include <asm/types.h>
-struct lppaca
-{
+struct lppaca {
//=============================================================================
// CACHE_LINE_1 0x0000 - 0x007F Contains read-only data
// NOTE: The xDynXyz fields are fields that will be dynamically changed by
@@ -129,4 +128,4 @@ struct lppaca
u8 pmc_save_area[256]; // PMC interrupt Area x00-xFF
};
-#endif /* _ASM_LPPACA_H */
+#endif /* _ASM_POWERPC_LPPACA_H */
diff --git a/include/asm-ppc64/machdep.h b/include/asm-powerpc/machdep.h
index 8027160ec96d..5670f0cd6143 100644
--- a/include/asm-ppc64/machdep.h
+++ b/include/asm-powerpc/machdep.h
@@ -1,6 +1,6 @@
+#ifndef _ASM_POWERPC_MACHDEP_H
+#define _ASM_POWERPC_MACHDEP_H
#ifdef __KERNEL__
-#ifndef _PPC64_MACHDEP_H
-#define _PPC64_MACHDEP_H
/*
* This program is free software; you can redistribute it and/or
@@ -16,6 +16,11 @@
#include <asm/setup.h>
+/* We export this macro for external modules like Alsa to know if
+ * ppc_md.feature_call is implemented or not
+ */
+#define CONFIG_PPC_HAS_FEATURE_CALLS
+
struct pt_regs;
struct pci_bus;
struct device_node;
@@ -39,26 +44,28 @@ struct smp_ops_t {
#endif
struct machdep_calls {
+#ifdef CONFIG_PPC64
void (*hpte_invalidate)(unsigned long slot,
unsigned long va,
- int large,
+ int psize,
int local);
long (*hpte_updatepp)(unsigned long slot,
unsigned long newpp,
unsigned long va,
- int large,
+ int pize,
int local);
void (*hpte_updateboltedpp)(unsigned long newpp,
- unsigned long ea);
+ unsigned long ea,
+ int psize);
long (*hpte_insert)(unsigned long hpte_group,
unsigned long va,
unsigned long prpn,
+ unsigned long rflags,
unsigned long vflags,
- unsigned long rflags);
+ int psize);
long (*hpte_remove)(unsigned long hpte_group);
- void (*flush_hash_range)(unsigned long context,
- unsigned long number,
- int local);
+ void (*flush_hash_range)(unsigned long number, int local);
+
/* special for kexec, to be called in real mode, linar mapping is
* destroyed as well */
void (*hpte_clear_all)(void);
@@ -75,18 +82,21 @@ struct machdep_calls {
void (*iommu_dev_setup)(struct pci_dev *dev);
void (*iommu_bus_setup)(struct pci_bus *bus);
void (*irq_bus_setup)(struct pci_bus *bus);
+#endif
int (*probe)(int platform);
void (*setup_arch)(void);
void (*init_early)(void);
/* Optional, may be NULL. */
- void (*get_cpuinfo)(struct seq_file *m);
+ void (*show_cpuinfo)(struct seq_file *m);
+ void (*show_percpuinfo)(struct seq_file *m, int i);
void (*init_IRQ)(void);
int (*get_irq)(struct pt_regs *);
void (*cpu_irq_down)(int secondary);
/* PCI stuff */
+ /* Called after scanning the bus, before allocating resources */
void (*pcibios_fixup)(void);
int (*pci_probe_mode)(struct pci_bus *);
@@ -96,9 +106,13 @@ struct machdep_calls {
void (*panic)(char *str);
void (*cpu_die)(void);
+ long (*time_init)(void); /* Optional, may be NULL */
+
int (*set_rtc_time)(struct rtc_time *);
void (*get_rtc_time)(struct rtc_time *);
- void (*get_boot_time)(struct rtc_time *);
+ unsigned long (*get_boot_time)(void);
+ unsigned char (*rtc_read_val)(int addr);
+ void (*rtc_write_val)(int addr, unsigned char val);
void (*calibrate_decr)(void);
@@ -107,10 +121,12 @@ struct machdep_calls {
/* Interface for platform error logging */
void (*log_error)(char *buf, unsigned int err_type, int fatal);
+ unsigned char (*nvram_read_val)(int addr);
+ void (*nvram_write_val)(int addr, unsigned char val);
ssize_t (*nvram_write)(char *buf, size_t count, loff_t *index);
ssize_t (*nvram_read)(char *buf, size_t count, loff_t *index);
ssize_t (*nvram_size)(void);
- int (*nvram_sync)(void);
+ void (*nvram_sync)(void);
/* Exception handlers */
void (*system_reset_exception)(struct pt_regs *regs);
@@ -130,19 +146,100 @@ struct machdep_calls {
/* Get access protection for /dev/mem */
pgprot_t (*phys_mem_access_prot)(struct file *file,
- unsigned long offset,
+ unsigned long pfn,
unsigned long size,
pgprot_t vma_prot);
/* Idle loop for this platform, leave empty for default idle loop */
- int (*idle_loop)(void);
+ void (*idle_loop)(void);
- /* Function to enable pmcs for this platform, called once per cpu. */
+ /* Function to enable performance monitor counters for this
+ platform, called once per cpu. */
void (*enable_pmcs)(void);
+
+ /* Set DABR for this platform, leave empty for default implemenation */
+ int (*set_dabr)(unsigned long dabr);
+
+#ifdef CONFIG_PPC32 /* XXX for now */
+ /* A general init function, called by ppc_init in init/main.c.
+ May be NULL. */
+ void (*init)(void);
+
+ void (*idle)(void);
+ void (*power_save)(void);
+
+ void (*heartbeat)(void);
+ unsigned long heartbeat_reset;
+ unsigned long heartbeat_count;
+
+ void (*setup_io_mappings)(void);
+
+ void (*early_serial_map)(void);
+ void (*kgdb_map_scc)(void);
+
+ /*
+ * optional PCI "hooks"
+ */
+
+ /* Called after PPC generic resource fixup to perform
+ machine specific fixups */
+ void (*pcibios_fixup_resources)(struct pci_dev *);
+
+ /* Called for each PCI bus in the system when it's probed */
+ void (*pcibios_fixup_bus)(struct pci_bus *);
+
+ /* Called when pci_enable_device() is called (initial=0) or
+ * when a device with no assigned resource is found (initial=1).
+ * Returns 0 to allow assignment/enabling of the device. */
+ int (*pcibios_enable_device_hook)(struct pci_dev *, int initial);
+
+ /* For interrupt routing */
+ unsigned char (*pci_swizzle)(struct pci_dev *, unsigned char *);
+ int (*pci_map_irq)(struct pci_dev *, unsigned char, unsigned char);
+
+ /* Called in indirect_* to avoid touching devices */
+ int (*pci_exclude_device)(unsigned char, unsigned char);
+
+ /* Called at then very end of pcibios_init() */
+ void (*pcibios_after_init)(void);
+
+ /* this is for modules, since _machine can be a define -- Cort */
+ int ppc_machine;
+
+#ifdef CONFIG_KEXEC
+ /* Called to shutdown machine specific hardware not already controlled
+ * by other drivers.
+ * XXX Should we move this one out of kexec scope?
+ */
+ void (*machine_shutdown)(void);
+
+ /* Called to do the minimal shutdown needed to run a kexec'd kernel
+ * to run successfully.
+ * XXX Should we move this one out of kexec scope?
+ */
+ void (*machine_crash_shutdown)(void);
+
+ /* Called to do what every setup is needed on image and the
+ * reboot code buffer. Returns 0 on success.
+ * Provide your own (maybe dummy) implementation if your platform
+ * claims to support kexec.
+ */
+ int (*machine_kexec_prepare)(struct kimage *image);
+
+ /* Called to handle any machine specific cleanup on image */
+ void (*machine_kexec_cleanup)(struct kimage *image);
+
+ /* Called to perform the _real_ kexec.
+ * Do NOT allocate memory or fail here. We are past the point of
+ * no return.
+ */
+ void (*machine_kexec)(struct kimage *image);
+#endif /* CONFIG_KEXEC */
+#endif /* CONFIG_PPC32 */
};
-extern int default_idle(void);
-extern int native_idle(void);
+extern void default_idle(void);
+extern void native_idle(void);
extern struct machdep_calls ppc_md;
extern char cmd_line[COMMAND_LINE_SIZE];
@@ -162,6 +259,13 @@ extern sys_ctrler_t sys_ctrler;
#endif /* CONFIG_PPC_PMAC */
+extern void setup_pci_ptrs(void);
+
+#ifdef CONFIG_SMP
+/* Poor default implementations */
+extern void __devinit smp_generic_give_timebase(void);
+extern void __devinit smp_generic_take_timebase(void);
+#endif /* CONFIG_SMP */
/* Functions to produce codes on the leds.
@@ -181,5 +285,5 @@ static inline void log_error(char *buf, unsigned int err_type, int fatal)
ppc_md.log_error(buf, err_type, fatal);
}
-#endif /* _PPC64_MACHDEP_H */
#endif /* __KERNEL__ */
+#endif /* _ASM_POWERPC_MACHDEP_H */
diff --git a/include/asm-ppc/macio.h b/include/asm-powerpc/macio.h
index b553dd4b139e..b553dd4b139e 100644
--- a/include/asm-ppc/macio.h
+++ b/include/asm-powerpc/macio.h
diff --git a/include/asm-ppc/mediabay.h b/include/asm-powerpc/mediabay.h
index 9daa3252d7b6..9daa3252d7b6 100644
--- a/include/asm-ppc/mediabay.h
+++ b/include/asm-powerpc/mediabay.h
diff --git a/arch/ppc64/kernel/mpic.h b/include/asm-powerpc/mpic.h
index ca78a7f10528..7083d1f74260 100644
--- a/arch/ppc64/kernel/mpic.h
+++ b/include/asm-powerpc/mpic.h
@@ -1,3 +1,6 @@
+#ifndef _ASM_POWERPC_MPIC_H
+#define _ASM_POWERPC_MPIC_H
+
#include <linux/irq.h>
/*
@@ -258,12 +261,21 @@ extern void mpic_setup_this_cpu(void);
/* Clean up for kexec (or cpu offline or ...) */
extern void mpic_teardown_this_cpu(int secondary);
+/* Get the current cpu priority for this cpu (0..15) */
+extern int mpic_cpu_get_priority(void);
+
+/* Set the current cpu priority for this cpu */
+extern void mpic_cpu_set_priority(int prio);
+
/* Request IPIs on primary mpic */
extern void mpic_request_ipis(void);
/* Send an IPI (non offseted number 0..3) */
extern void mpic_send_ipi(unsigned int ipi_no, unsigned int cpu_mask);
+/* Send a message (IPI) to a given target (cpu number or MSG_*) */
+void smp_mpic_message_pass(int target, int msg);
+
/* Fetch interrupt from a given mpic */
extern int mpic_get_one_irq(struct mpic *mpic, struct pt_regs *regs);
/* This one gets to the primary mpic */
@@ -271,3 +283,5 @@ extern int mpic_get_irq(struct pt_regs *regs);
/* global mpic for pSeries */
extern struct mpic *pSeries_mpic;
+
+#endif /* _ASM_POWERPC_MPIC_H */
diff --git a/include/asm-powerpc/numnodes.h b/include/asm-powerpc/numnodes.h
new file mode 100644
index 000000000000..795533aca095
--- /dev/null
+++ b/include/asm-powerpc/numnodes.h
@@ -0,0 +1,7 @@
+#ifndef _ASM_POWERPC_MAX_NUMNODES_H
+#define _ASM_POWERPC_MAX_NUMNODES_H
+
+/* Max 16 Nodes */
+#define NODES_SHIFT 4
+
+#endif /* _ASM_POWERPC_MAX_NUMNODES_H */
diff --git a/include/asm-ppc/of_device.h b/include/asm-powerpc/of_device.h
index 575bce418f80..ddb16aae0bd6 100644
--- a/include/asm-ppc/of_device.h
+++ b/include/asm-powerpc/of_device.h
@@ -1,5 +1,5 @@
-#ifndef __OF_DEVICE_H__
-#define __OF_DEVICE_H__
+#ifndef _ASM_POWERPC_OF_DEVICE_H
+#define _ASM_POWERPC_OF_DEVICE_H
#include <linux/device.h>
#include <linux/mod_devicetable.h>
@@ -61,5 +61,4 @@ extern struct of_device *of_platform_device_create(struct device_node *np,
struct device *parent);
extern void of_release_dev(struct device *dev);
-#endif /* __OF_DEVICE_H__ */
-
+#endif /* _ASM_POWERPC_OF_DEVICE_H */
diff --git a/include/asm-ppc/ohare.h b/include/asm-powerpc/ohare.h
index 023b59772231..023b59772231 100644
--- a/include/asm-ppc/ohare.h
+++ b/include/asm-powerpc/ohare.h
diff --git a/include/asm-ppc64/oprofile_impl.h b/include/asm-powerpc/oprofile_impl.h
index b04f1dfb1421..8013cd273ced 100644
--- a/include/asm-ppc64/oprofile_impl.h
+++ b/include/asm-powerpc/oprofile_impl.h
@@ -9,39 +9,49 @@
* 2 of the License, or (at your option) any later version.
*/
-#ifndef OP_IMPL_H
-#define OP_IMPL_H 1
+#ifndef _ASM_POWERPC_OPROFILE_IMPL_H
+#define _ASM_POWERPC_OPROFILE_IMPL_H
#define OP_MAX_COUNTER 8
/* Per-counter configuration as set via oprofilefs. */
struct op_counter_config {
+#ifdef __powerpc64__
unsigned long valid;
+#endif
unsigned long enabled;
unsigned long event;
unsigned long count;
unsigned long kernel;
+#ifdef __powerpc64__
/* We dont support per counter user/kernel selection */
+#endif
unsigned long user;
unsigned long unit_mask;
};
/* System-wide configuration as set via oprofilefs. */
struct op_system_config {
+#ifdef __powerpc64__
unsigned long mmcr0;
unsigned long mmcr1;
unsigned long mmcra;
+#endif
unsigned long enable_kernel;
unsigned long enable_user;
+#ifdef __powerpc64__
unsigned long backtrace_spinlocks;
+#endif
};
/* Per-arch configuration */
-struct op_ppc64_model {
+struct op_powerpc_model {
void (*reg_setup) (struct op_counter_config *,
struct op_system_config *,
int num_counters);
+#ifdef __powerpc64__
void (*cpu_setup) (void *);
+#endif
void (*start) (struct op_counter_config *);
void (*stop) (void);
void (*handle_interrupt) (struct pt_regs *,
@@ -49,8 +59,9 @@ struct op_ppc64_model {
int num_counters;
};
-extern struct op_ppc64_model op_model_rs64;
-extern struct op_ppc64_model op_model_power4;
+#ifdef __powerpc64__
+extern struct op_powerpc_model op_model_rs64;
+extern struct op_powerpc_model op_model_power4;
static inline unsigned int ctr_read(unsigned int i)
{
@@ -107,5 +118,6 @@ static inline void ctr_write(unsigned int i, unsigned int val)
break;
}
}
+#endif /* __powerpc64__ */
-#endif
+#endif /* _ASM_POWERPC_OPROFILE_IMPL_H */
diff --git a/include/asm-ppc64/pSeries_reconfig.h b/include/asm-powerpc/pSeries_reconfig.h
index c0db1ea7f7d1..c0db1ea7f7d1 100644
--- a/include/asm-ppc64/pSeries_reconfig.h
+++ b/include/asm-powerpc/pSeries_reconfig.h
diff --git a/include/asm-ppc64/paca.h b/include/asm-powerpc/paca.h
index 2f0f36f73d38..92c765c35bd0 100644
--- a/include/asm-ppc64/paca.h
+++ b/include/asm-powerpc/paca.h
@@ -1,11 +1,8 @@
-#ifndef _PPC64_PACA_H
-#define _PPC64_PACA_H
-
/*
- * include/asm-ppc64/paca.h
+ * include/asm-powerpc/paca.h
*
- * This control block defines the PACA which defines the processor
- * specific data for each logical processor on the system.
+ * This control block defines the PACA which defines the processor
+ * specific data for each logical processor on the system.
* There are some pointers defined that are utilized by PLIC.
*
* C 2001 PPC 64 Team, IBM Corp
@@ -14,12 +11,14 @@
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
- */
+ */
+#ifndef _ASM_POWERPC_PACA_H
+#define _ASM_POWERPC_PACA_H
#include <linux/config.h>
#include <asm/types.h>
#include <asm/lppaca.h>
-#include <asm/iSeries/ItLpRegSave.h>
+#include <asm/iseries/it_lp_reg_save.h>
#include <asm/mmu.h>
register struct paca_struct *local_paca asm("r13");
@@ -72,10 +71,15 @@ struct paca_struct {
/*
* Now, starting in cacheline 2, the exception save areas
*/
- u64 exgen[8] __attribute__((aligned(0x80))); /* used for most interrupts/exceptions */
- u64 exmc[8]; /* used for machine checks */
- u64 exslb[8]; /* used for SLB/segment table misses
- * on the linear mapping */
+ /* used for most interrupts/exceptions */
+ u64 exgen[10] __attribute__((aligned(0x80)));
+ u64 exmc[10]; /* used for machine checks */
+ u64 exslb[10]; /* used for SLB/segment table misses
+ * on the linear mapping */
+#ifdef CONFIG_PPC_64K_PAGES
+ pgd_t *pgdir;
+#endif /* CONFIG_PPC_64K_PAGES */
+
mm_context_t context;
u16 slb_cache[SLB_CACHE_ENTRIES];
u16 slb_cache_ptr;
@@ -113,4 +117,4 @@ struct paca_struct {
extern struct paca_struct paca[];
-#endif /* _PPC64_PACA_H */
+#endif /* _ASM_POWERPC_PACA_H */
diff --git a/include/asm-ppc/parport.h b/include/asm-powerpc/parport.h
index 11f96d3de5b6..d86b410a6f8b 100644
--- a/include/asm-ppc/parport.h
+++ b/include/asm-powerpc/parport.h
@@ -6,8 +6,8 @@
* This file should only be included by drivers/parport/parport_pc.c.
*/
-#ifndef _ASM_PPC_PARPORT_H
-#define _ASM_PPC_PARPORT_H
+#ifndef _ASM_POWERPC_PARPORT_H
+#define _ASM_POWERPC_PARPORT_H
static int __devinit parport_pc_find_isa_ports (int autoirq, int autodma);
static int __devinit parport_pc_find_nonpci_ports (int autoirq, int autodma)
@@ -15,4 +15,4 @@ static int __devinit parport_pc_find_nonpci_ports (int autoirq, int autodma)
return parport_pc_find_isa_ports (autoirq, autodma);
}
-#endif /* !(_ASM_PPC_PARPORT_H) */
+#endif /* !(_ASM_POWERPC_PARPORT_H) */
diff --git a/include/asm-ppc/pmac_feature.h b/include/asm-powerpc/pmac_feature.h
index e9683bcff19b..e9683bcff19b 100644
--- a/include/asm-ppc/pmac_feature.h
+++ b/include/asm-powerpc/pmac_feature.h
diff --git a/include/asm-ppc/pmac_low_i2c.h b/include/asm-powerpc/pmac_low_i2c.h
index 809a5963d5e7..809a5963d5e7 100644
--- a/include/asm-ppc/pmac_low_i2c.h
+++ b/include/asm-powerpc/pmac_low_i2c.h
diff --git a/include/asm-powerpc/pmc.h b/include/asm-powerpc/pmc.h
new file mode 100644
index 000000000000..5f41f3a2b293
--- /dev/null
+++ b/include/asm-powerpc/pmc.h
@@ -0,0 +1,47 @@
+/*
+ * pmc.h
+ * Copyright (C) 2004 David Gibson, IBM 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 _POWERPC_PMC_H
+#define _POWERPC_PMC_H
+
+#include <asm/ptrace.h>
+
+typedef void (*perf_irq_t)(struct pt_regs *);
+extern perf_irq_t perf_irq;
+
+int reserve_pmc_hardware(perf_irq_t new_perf_irq);
+void release_pmc_hardware(void);
+
+#ifdef CONFIG_PPC64
+void power4_enable_pmcs(void);
+#endif
+
+#ifdef CONFIG_FSL_BOOKE
+void init_pmc_stop(int ctr);
+void set_pmc_event(int ctr, int event);
+void set_pmc_user_kernel(int ctr, int user, int kernel);
+void set_pmc_marked(int ctr, int mark0, int mark1);
+void pmc_start_ctr(int ctr, int enable);
+void pmc_start_ctrs(int enable);
+void pmc_stop_ctrs(void);
+void dump_pmcs(void);
+
+extern struct op_powerpc_model op_model_fsl_booke;
+#endif
+
+#endif /* _POWERPC_PMC_H */
diff --git a/include/asm-ppc64/posix_types.h b/include/asm-powerpc/posix_types.h
index 516de7201b5d..c6391077224f 100644
--- a/include/asm-ppc64/posix_types.h
+++ b/include/asm-powerpc/posix_types.h
@@ -1,44 +1,54 @@
-#ifndef _PPC64_POSIX_TYPES_H
-#define _PPC64_POSIX_TYPES_H
+#ifndef _ASM_POWERPC_POSIX_TYPES_H
+#define _ASM_POWERPC_POSIX_TYPES_H
/*
* This file is generally used by user-level software, so you need to
* be a little careful about namespace pollution etc. Also, we cannot
* assume GCC is being used.
- *
- * 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.
*/
typedef unsigned long __kernel_ino_t;
-typedef unsigned long __kernel_nlink_t;
typedef unsigned int __kernel_mode_t;
typedef long __kernel_off_t;
-typedef long long __kernel_loff_t;
typedef int __kernel_pid_t;
-typedef int __kernel_ipc_pid_t;
typedef unsigned int __kernel_uid_t;
typedef unsigned int __kernel_gid_t;
-typedef unsigned long __kernel_size_t;
-typedef long __kernel_ssize_t;
typedef long __kernel_ptrdiff_t;
typedef long __kernel_time_t;
+typedef long __kernel_clock_t;
typedef int __kernel_timer_t;
typedef int __kernel_clockid_t;
typedef long __kernel_suseconds_t;
-typedef long __kernel_clock_t;
typedef int __kernel_daddr_t;
typedef char * __kernel_caddr_t;
typedef unsigned short __kernel_uid16_t;
typedef unsigned short __kernel_gid16_t;
typedef unsigned int __kernel_uid32_t;
typedef unsigned int __kernel_gid32_t;
-
typedef unsigned int __kernel_old_uid_t;
typedef unsigned int __kernel_old_gid_t;
+
+#ifdef __powerpc64__
+typedef unsigned long __kernel_nlink_t;
+typedef int __kernel_ipc_pid_t;
+typedef unsigned long __kernel_size_t;
+typedef long __kernel_ssize_t;
typedef unsigned long __kernel_old_dev_t;
+#else
+typedef unsigned short __kernel_nlink_t;
+typedef short __kernel_ipc_pid_t;
+typedef unsigned int __kernel_size_t;
+typedef int __kernel_ssize_t;
+typedef unsigned int __kernel_old_dev_t;
+#endif
+
+#ifdef __powerpc64__
+typedef long long __kernel_loff_t;
+#else
+#ifdef __GNUC__
+typedef long long __kernel_loff_t;
+#endif
+#endif
typedef struct {
int val[2];
@@ -116,4 +126,4 @@ static __inline__ void __FD_ZERO(__kernel_fd_set *p)
#endif /* defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) */
#endif /* __GNUC__ */
-#endif /* _PPC64_POSIX_TYPES_H */
+#endif /* _ASM_POWERPC_POSIX_TYPES_H */
diff --git a/include/asm-powerpc/ppc-pci.h b/include/asm-powerpc/ppc-pci.h
new file mode 100644
index 000000000000..9896fade98a7
--- /dev/null
+++ b/include/asm-powerpc/ppc-pci.h
@@ -0,0 +1,99 @@
+/*
+ * c 2001 PPC 64 Team, IBM Corp
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#ifndef _ASM_POWERPC_PPC_PCI_H
+#define _ASM_POWERPC_PPC_PCI_H
+
+#include <linux/pci.h>
+#include <asm/pci-bridge.h>
+
+extern unsigned long isa_io_base;
+
+extern void pci_setup_pci_controller(struct pci_controller *hose);
+extern void pci_setup_phb_io(struct pci_controller *hose, int primary);
+extern void pci_setup_phb_io_dynamic(struct pci_controller *hose, int primary);
+
+
+extern struct list_head hose_list;
+extern int global_phb_number;
+
+extern unsigned long find_and_init_phbs(void);
+
+extern struct pci_dev *ppc64_isabridge_dev; /* may be NULL if no ISA bus */
+
+/** Bus Unit ID macros; get low and hi 32-bits of the 64-bit BUID */
+#define BUID_HI(buid) ((buid) >> 32)
+#define BUID_LO(buid) ((buid) & 0xffffffff)
+
+/* PCI device_node operations */
+struct device_node;
+typedef void *(*traverse_func)(struct device_node *me, void *data);
+void *traverse_pci_devices(struct device_node *start, traverse_func pre,
+ void *data);
+
+void pci_devs_phb_init(void);
+void pci_devs_phb_init_dynamic(struct pci_controller *phb);
+void __devinit scan_phb(struct pci_controller *hose);
+
+/* From rtas_pci.h */
+void init_pci_config_tokens (void);
+unsigned long get_phb_buid (struct device_node *);
+
+/* From pSeries_pci.h */
+extern void pSeries_final_fixup(void);
+extern void pSeries_irq_bus_setup(struct pci_bus *bus);
+
+extern unsigned long pci_probe_only;
+extern unsigned long pci_assign_all_buses;
+extern int pci_read_irq_line(struct pci_dev *pci_dev);
+
+/* ---- EEH internal-use-only related routines ---- */
+#ifdef CONFIG_EEH
+/**
+ * rtas_set_slot_reset -- unfreeze a frozen slot
+ *
+ * Clear the EEH-frozen condition on a slot. This routine
+ * does this by asserting the PCI #RST line for 1/8th of
+ * a second; this routine will sleep while the adapter is
+ * being reset.
+ */
+void rtas_set_slot_reset (struct pci_dn *);
+
+/**
+ * eeh_restore_bars - Restore device configuration info.
+ *
+ * A reset of a PCI device will clear out its config space.
+ * This routines will restore the config space for this
+ * device, and is children, to values previously obtained
+ * from the firmware.
+ */
+void eeh_restore_bars(struct pci_dn *);
+
+/**
+ * rtas_configure_bridge -- firmware initialization of pci bridge
+ *
+ * Ask the firmware to configure all PCI bridges devices
+ * located behind the indicated node. Required after a
+ * pci device reset. Does essentially the same hing as
+ * eeh_restore_bars, but for brdges, and lets firmware
+ * do the work.
+ */
+void rtas_configure_bridge(struct pci_dn *);
+
+int rtas_write_config(struct pci_dn *, int where, int size, u32 val);
+
+/**
+ * mark and clear slots: find "partition endpoint" PE and set or
+ * clear the flags for each subnode of the PE.
+ */
+void eeh_mark_slot (struct device_node *dn, int mode_flag);
+void eeh_clear_slot (struct device_node *dn, int mode_flag);
+
+#endif
+
+#endif /* _ASM_POWERPC_PPC_PCI_H */
diff --git a/include/asm-ppc/ppc_asm.h b/include/asm-powerpc/ppc_asm.h
index bb53e2def363..c27baa0563fe 100644
--- a/include/asm-ppc/ppc_asm.h
+++ b/include/asm-powerpc/ppc_asm.h
@@ -1,38 +1,47 @@
/*
- * include/asm-ppc/ppc_asm.h
- *
- * Definitions used by various bits of low-level assembly code on PowerPC.
- *
* Copyright (C) 1995-1999 Gary Thomas, Paul Mackerras, Cort Dougan.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
*/
+#ifndef _ASM_POWERPC_PPC_ASM_H
+#define _ASM_POWERPC_PPC_ASM_H
+#include <linux/stringify.h>
#include <linux/config.h>
+#include <asm/asm-compat.h>
+
+#ifndef __ASSEMBLY__
+#error __FILE__ should only be used in assembler files
+#else
+
+#define SZL (BITS_PER_LONG/8)
/*
* Macros for storing registers into and loading registers from
* exception frames.
*/
+#ifdef __powerpc64__
+#define SAVE_GPR(n, base) std n,GPR0+8*(n)(base)
+#define REST_GPR(n, base) ld n,GPR0+8*(n)(base)
+#define SAVE_NVGPRS(base) SAVE_8GPRS(14, base); SAVE_10GPRS(22, base)
+#define REST_NVGPRS(base) REST_8GPRS(14, base); REST_10GPRS(22, base)
+#else
#define SAVE_GPR(n, base) stw n,GPR0+4*(n)(base)
+#define REST_GPR(n, base) lwz n,GPR0+4*(n)(base)
+#define SAVE_NVGPRS(base) SAVE_GPR(13, base); SAVE_8GPRS(14, base); \
+ SAVE_10GPRS(22, base)
+#define REST_NVGPRS(base) REST_GPR(13, base); REST_8GPRS(14, base); \
+ REST_10GPRS(22, base)
+#endif
+
+
#define SAVE_2GPRS(n, base) SAVE_GPR(n, base); SAVE_GPR(n+1, base)
#define SAVE_4GPRS(n, base) SAVE_2GPRS(n, base); SAVE_2GPRS(n+2, base)
#define SAVE_8GPRS(n, base) SAVE_4GPRS(n, base); SAVE_4GPRS(n+4, base)
#define SAVE_10GPRS(n, base) SAVE_8GPRS(n, base); SAVE_2GPRS(n+8, base)
-#define REST_GPR(n, base) lwz n,GPR0+4*(n)(base)
#define REST_2GPRS(n, base) REST_GPR(n, base); REST_GPR(n+1, base)
#define REST_4GPRS(n, base) REST_2GPRS(n, base); REST_2GPRS(n+2, base)
#define REST_8GPRS(n, base) REST_4GPRS(n, base); REST_4GPRS(n+4, base)
#define REST_10GPRS(n, base) REST_8GPRS(n, base); REST_2GPRS(n+8, base)
-#define SAVE_NVGPRS(base) SAVE_GPR(13, base); SAVE_8GPRS(14, base); \
- SAVE_10GPRS(22, base)
-#define REST_NVGPRS(base) REST_GPR(13, base); REST_8GPRS(14, base); \
- REST_10GPRS(22, base)
-
#define SAVE_FPR(n, base) stfd n,THREAD_FPR0+8*(n)(base)
#define SAVE_2FPRS(n, base) SAVE_FPR(n, base); SAVE_FPR(n+1, base)
#define SAVE_4FPRS(n, base) SAVE_2FPRS(n, base); SAVE_2FPRS(n+2, base)
@@ -47,32 +56,158 @@
#define REST_32FPRS(n, base) REST_16FPRS(n, base); REST_16FPRS(n+16, base)
#define SAVE_VR(n,b,base) li b,THREAD_VR0+(16*(n)); stvx n,b,base
-#define SAVE_2VR(n,b,base) SAVE_VR(n,b,base); SAVE_VR(n+1,b,base)
-#define SAVE_4VR(n,b,base) SAVE_2VR(n,b,base); SAVE_2VR(n+2,b,base)
-#define SAVE_8VR(n,b,base) SAVE_4VR(n,b,base); SAVE_4VR(n+4,b,base)
-#define SAVE_16VR(n,b,base) SAVE_8VR(n,b,base); SAVE_8VR(n+8,b,base)
-#define SAVE_32VR(n,b,base) SAVE_16VR(n,b,base); SAVE_16VR(n+16,b,base)
+#define SAVE_2VRS(n,b,base) SAVE_VR(n,b,base); SAVE_VR(n+1,b,base)
+#define SAVE_4VRS(n,b,base) SAVE_2VRS(n,b,base); SAVE_2VRS(n+2,b,base)
+#define SAVE_8VRS(n,b,base) SAVE_4VRS(n,b,base); SAVE_4VRS(n+4,b,base)
+#define SAVE_16VRS(n,b,base) SAVE_8VRS(n,b,base); SAVE_8VRS(n+8,b,base)
+#define SAVE_32VRS(n,b,base) SAVE_16VRS(n,b,base); SAVE_16VRS(n+16,b,base)
#define REST_VR(n,b,base) li b,THREAD_VR0+(16*(n)); lvx n,b,base
-#define REST_2VR(n,b,base) REST_VR(n,b,base); REST_VR(n+1,b,base)
-#define REST_4VR(n,b,base) REST_2VR(n,b,base); REST_2VR(n+2,b,base)
-#define REST_8VR(n,b,base) REST_4VR(n,b,base); REST_4VR(n+4,b,base)
-#define REST_16VR(n,b,base) REST_8VR(n,b,base); REST_8VR(n+8,b,base)
-#define REST_32VR(n,b,base) REST_16VR(n,b,base); REST_16VR(n+16,b,base)
+#define REST_2VRS(n,b,base) REST_VR(n,b,base); REST_VR(n+1,b,base)
+#define REST_4VRS(n,b,base) REST_2VRS(n,b,base); REST_2VRS(n+2,b,base)
+#define REST_8VRS(n,b,base) REST_4VRS(n,b,base); REST_4VRS(n+4,b,base)
+#define REST_16VRS(n,b,base) REST_8VRS(n,b,base); REST_8VRS(n+8,b,base)
+#define REST_32VRS(n,b,base) REST_16VRS(n,b,base); REST_16VRS(n+16,b,base)
#define SAVE_EVR(n,s,base) evmergehi s,s,n; stw s,THREAD_EVR0+4*(n)(base)
-#define SAVE_2EVR(n,s,base) SAVE_EVR(n,s,base); SAVE_EVR(n+1,s,base)
-#define SAVE_4EVR(n,s,base) SAVE_2EVR(n,s,base); SAVE_2EVR(n+2,s,base)
-#define SAVE_8EVR(n,s,base) SAVE_4EVR(n,s,base); SAVE_4EVR(n+4,s,base)
-#define SAVE_16EVR(n,s,base) SAVE_8EVR(n,s,base); SAVE_8EVR(n+8,s,base)
-#define SAVE_32EVR(n,s,base) SAVE_16EVR(n,s,base); SAVE_16EVR(n+16,s,base)
-
+#define SAVE_2EVRS(n,s,base) SAVE_EVR(n,s,base); SAVE_EVR(n+1,s,base)
+#define SAVE_4EVRS(n,s,base) SAVE_2EVRS(n,s,base); SAVE_2EVRS(n+2,s,base)
+#define SAVE_8EVRS(n,s,base) SAVE_4EVRS(n,s,base); SAVE_4EVRS(n+4,s,base)
+#define SAVE_16EVRS(n,s,base) SAVE_8EVRS(n,s,base); SAVE_8EVRS(n+8,s,base)
+#define SAVE_32EVRS(n,s,base) SAVE_16EVRS(n,s,base); SAVE_16EVRS(n+16,s,base)
#define REST_EVR(n,s,base) lwz s,THREAD_EVR0+4*(n)(base); evmergelo n,s,n
-#define REST_2EVR(n,s,base) REST_EVR(n,s,base); REST_EVR(n+1,s,base)
-#define REST_4EVR(n,s,base) REST_2EVR(n,s,base); REST_2EVR(n+2,s,base)
-#define REST_8EVR(n,s,base) REST_4EVR(n,s,base); REST_4EVR(n+4,s,base)
-#define REST_16EVR(n,s,base) REST_8EVR(n,s,base); REST_8EVR(n+8,s,base)
-#define REST_32EVR(n,s,base) REST_16EVR(n,s,base); REST_16EVR(n+16,s,base)
+#define REST_2EVRS(n,s,base) REST_EVR(n,s,base); REST_EVR(n+1,s,base)
+#define REST_4EVRS(n,s,base) REST_2EVRS(n,s,base); REST_2EVRS(n+2,s,base)
+#define REST_8EVRS(n,s,base) REST_4EVRS(n,s,base); REST_4EVRS(n+4,s,base)
+#define REST_16EVRS(n,s,base) REST_8EVRS(n,s,base); REST_8EVRS(n+8,s,base)
+#define REST_32EVRS(n,s,base) REST_16EVRS(n,s,base); REST_16EVRS(n+16,s,base)
+
+/* Macros to adjust thread priority for hardware multithreading */
+#define HMT_VERY_LOW or 31,31,31 # very low priority
+#define HMT_LOW or 1,1,1
+#define HMT_MEDIUM_LOW or 6,6,6 # medium low priority
+#define HMT_MEDIUM or 2,2,2
+#define HMT_MEDIUM_HIGH or 5,5,5 # medium high priority
+#define HMT_HIGH or 3,3,3
+
+/* handle instructions that older assemblers may not know */
+#define RFCI .long 0x4c000066 /* rfci instruction */
+#define RFDI .long 0x4c00004e /* rfdi instruction */
+#define RFMCI .long 0x4c00004c /* rfmci instruction */
+
+#ifdef CONFIG_PPC64
+
+#define XGLUE(a,b) a##b
+#define GLUE(a,b) XGLUE(a,b)
+
+#define _GLOBAL(name) \
+ .section ".text"; \
+ .align 2 ; \
+ .globl name; \
+ .globl GLUE(.,name); \
+ .section ".opd","aw"; \
+name: \
+ .quad GLUE(.,name); \
+ .quad .TOC.@tocbase; \
+ .quad 0; \
+ .previous; \
+ .type GLUE(.,name),@function; \
+GLUE(.,name):
+
+#define _KPROBE(name) \
+ .section ".kprobes.text","a"; \
+ .align 2 ; \
+ .globl name; \
+ .globl GLUE(.,name); \
+ .section ".opd","aw"; \
+name: \
+ .quad GLUE(.,name); \
+ .quad .TOC.@tocbase; \
+ .quad 0; \
+ .previous; \
+ .type GLUE(.,name),@function; \
+GLUE(.,name):
+
+#define _STATIC(name) \
+ .section ".text"; \
+ .align 2 ; \
+ .section ".opd","aw"; \
+name: \
+ .quad GLUE(.,name); \
+ .quad .TOC.@tocbase; \
+ .quad 0; \
+ .previous; \
+ .type GLUE(.,name),@function; \
+GLUE(.,name):
+
+#else /* 32-bit */
+
+#define _GLOBAL(n) \
+ .text; \
+ .stabs __stringify(n:F-1),N_FUN,0,0,n;\
+ .globl n; \
+n:
+
+#define _KPROBE(n) \
+ .section ".kprobes.text","a"; \
+ .globl n; \
+n:
+
+#endif
+
+/*
+ * LOADADDR( rn, name )
+ * loads the address of 'name' into 'rn'
+ *
+ * LOADBASE( rn, name )
+ * loads the address (possibly without the low 16 bits) of 'name' into 'rn'
+ * suitable for base+disp addressing
+ */
+#ifdef __powerpc64__
+#define LOADADDR(rn,name) \
+ lis rn,name##@highest; \
+ ori rn,rn,name##@higher; \
+ rldicr rn,rn,32,31; \
+ oris rn,rn,name##@h; \
+ ori rn,rn,name##@l
+
+#define LOADBASE(rn,name) \
+ ld rn,name@got(r2)
+
+#define OFF(name) 0
+
+#define SET_REG_TO_CONST(reg, value) \
+ lis reg,(((value)>>48)&0xFFFF); \
+ ori reg,reg,(((value)>>32)&0xFFFF); \
+ rldicr reg,reg,32,31; \
+ oris reg,reg,(((value)>>16)&0xFFFF); \
+ ori reg,reg,((value)&0xFFFF);
+
+#define SET_REG_TO_LABEL(reg, label) \
+ lis reg,(label)@highest; \
+ ori reg,reg,(label)@higher; \
+ rldicr reg,reg,32,31; \
+ oris reg,reg,(label)@h; \
+ ori reg,reg,(label)@l;
+
+/* offsets for stack frame layout */
+#define LRSAVE 16
+
+#else /* 32-bit */
+#define LOADADDR(rn,name) \
+ lis rn,name@ha; \
+ addi rn,rn,name@l
+
+#define LOADBASE(rn,name) \
+ lis rn,name@ha
+#define OFF(name) name@l
+
+/* offsets for stack frame layout */
+#define LRSAVE 4
+
+#endif
+
+/* various errata or part fixups */
#ifdef CONFIG_PPC601_SYNC_FIX
#define SYNC \
BEGIN_FTR_SECTION \
@@ -93,6 +228,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_601)
#define ISYNC_601
#endif
+
#ifndef CONFIG_SMP
#define TLBSYNC
#else /* CONFIG_SMP */
@@ -104,6 +240,7 @@ BEGIN_FTR_SECTION \
END_FTR_SECTION_IFCLR(CPU_FTR_601)
#endif
+
/*
* This instruction is not implemented on the PPC 603 or 601; however, on
* the 403GCX and 405GP tlbia IS defined and tlbie is not.
@@ -121,18 +258,43 @@ END_FTR_SECTION_IFCLR(CPU_FTR_601)
bdnz 0b
#endif
-#ifdef CONFIG_BOOKE
+
+#ifdef CONFIG_IBM440EP_ERR42
+#define PPC440EP_ERR42 isync
+#else
+#define PPC440EP_ERR42
+#endif
+
+
+#if defined(CONFIG_BOOKE)
+#define toreal(rd)
+#define fromreal(rd)
+
#define tophys(rd,rs) \
addis rd,rs,0
#define tovirt(rd,rs) \
addis rd,rs,0
-#else /* CONFIG_BOOKE */
+#elif defined(CONFIG_PPC64)
+#define toreal(rd) /* we can access c000... in real mode */
+#define fromreal(rd)
+
+#define tophys(rd,rs) \
+ clrldi rd,rs,2
+
+#define tovirt(rd,rs) \
+ rotldi rd,rs,16; \
+ ori rd,rd,((KERNELBASE>>48)&0xFFFF);\
+ rotldi rd,rd,48
+#else
/*
* On APUS (Amiga PowerPC cpu upgrade board), we don't know the
* physical base address of RAM at compile time.
*/
+#define toreal(rd) tophys(rd,rd)
+#define fromreal(rd) tovirt(rd,rd)
+
#define tophys(rd,rs) \
0: addis rd,rs,-KERNELBASE@h; \
.section ".vtop_fixup","aw"; \
@@ -146,22 +308,11 @@ END_FTR_SECTION_IFCLR(CPU_FTR_601)
.align 1; \
.long 0b; \
.previous
-#endif /* CONFIG_BOOKE */
+#endif
-/*
- * On 64-bit cpus, we use the rfid instruction instead of rfi, but
- * we then have to make sure we preserve the top 32 bits except for
- * the 64-bit mode bit, which we clear.
- */
-#ifdef CONFIG_PPC64BRIDGE
-#define FIX_SRR1(ra, rb) \
- mr rb,ra; \
- mfmsr ra; \
- clrldi ra,ra,1; /* turn off 64-bit mode */ \
- rldimi ra,rb,0,32
-#define RFI .long 0x4c000024 /* rfid instruction */
-#define MTMSRD(r) .long (0x7c000164 + ((r) << 21)) /* mtmsrd */
-#define CLR_TOP32(r) rlwinm (r),(r),0,0,31 /* clear top 32 bits */
+#ifdef CONFIG_PPC64
+#define RFI rfid
+#define MTMSRD(r) mtmsrd r
#else
#define FIX_SRR1(ra, rb)
@@ -172,24 +323,6 @@ END_FTR_SECTION_IFCLR(CPU_FTR_601)
#endif
#define MTMSRD(r) mtmsr r
#define CLR_TOP32(r)
-#endif /* CONFIG_PPC64BRIDGE */
-
-#define RFCI .long 0x4c000066 /* rfci instruction */
-#define RFDI .long 0x4c00004e /* rfdi instruction */
-#define RFMCI .long 0x4c00004c /* rfmci instruction */
-
-#ifdef CONFIG_IBM405_ERR77
-#define PPC405_ERR77(ra,rb) dcbt ra, rb;
-#define PPC405_ERR77_SYNC sync;
-#else
-#define PPC405_ERR77(ra,rb)
-#define PPC405_ERR77_SYNC
-#endif
-
-#ifdef CONFIG_IBM440EP_ERR42
-#define PPC440EP_ERR42 isync
-#else
-#define PPC440EP_ERR42
#endif
/* The boring bits... */
@@ -277,6 +410,8 @@ END_FTR_SECTION_IFCLR(CPU_FTR_601)
#define fr30 30
#define fr31 31
+/* AltiVec Registers (VPRs) */
+
#define vr0 0
#define vr1 1
#define vr2 2
@@ -310,6 +445,8 @@ END_FTR_SECTION_IFCLR(CPU_FTR_601)
#define vr30 30
#define vr31 31
+/* SPE Registers (EVPRs) */
+
#define evr0 0
#define evr1 1
#define evr2 2
@@ -348,3 +485,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_601)
#define N_RSYM 64
#define N_SLINE 68
#define N_SO 100
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* _ASM_POWERPC_PPC_ASM_H */
diff --git a/include/asm-powerpc/processor.h b/include/asm-powerpc/processor.h
new file mode 100644
index 000000000000..f6f186b56b0f
--- /dev/null
+++ b/include/asm-powerpc/processor.h
@@ -0,0 +1,287 @@
+#ifndef _ASM_POWERPC_PROCESSOR_H
+#define _ASM_POWERPC_PROCESSOR_H
+
+/*
+ * Copyright (C) 2001 PPC 64 Team, IBM Corp
+ *
+ * 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/config.h>
+#include <asm/reg.h>
+
+#ifndef __ASSEMBLY__
+#include <linux/compiler.h>
+#include <asm/ptrace.h>
+#include <asm/types.h>
+
+/* We do _not_ want to define new machine types at all, those must die
+ * in favor of using the device-tree
+ * -- BenH.
+ */
+
+/* Platforms codes (to be obsoleted) */
+#define PLATFORM_PSERIES 0x0100
+#define PLATFORM_PSERIES_LPAR 0x0101
+#define PLATFORM_ISERIES_LPAR 0x0201
+#define PLATFORM_LPAR 0x0001
+#define PLATFORM_POWERMAC 0x0400
+#define PLATFORM_MAPLE 0x0500
+#define PLATFORM_PREP 0x0600
+#define PLATFORM_CHRP 0x0700
+#define PLATFORM_CELL 0x1000
+
+/* Compat platform codes for 32 bits */
+#define _MACH_prep PLATFORM_PREP
+#define _MACH_Pmac PLATFORM_POWERMAC
+#define _MACH_chrp PLATFORM_CHRP
+
+/* PREP sub-platform types see residual.h for these */
+#define _PREP_Motorola 0x01 /* motorola prep */
+#define _PREP_Firm 0x02 /* firmworks prep */
+#define _PREP_IBM 0x00 /* ibm prep */
+#define _PREP_Bull 0x03 /* bull prep */
+
+/* CHRP sub-platform types. These are arbitrary */
+#define _CHRP_Motorola 0x04 /* motorola chrp, the cobra */
+#define _CHRP_IBM 0x05 /* IBM chrp, the longtrail and longtrail 2 */
+#define _CHRP_Pegasos 0x06 /* Genesi/bplan's Pegasos and Pegasos2 */
+
+#define platform_is_pseries() (_machine == PLATFORM_PSERIES || \
+ _machine == PLATFORM_PSERIES_LPAR)
+#define platform_is_lpar() (!!(_machine & PLATFORM_LPAR))
+
+#if defined(CONFIG_PPC_MULTIPLATFORM)
+extern int _machine;
+
+#ifdef CONFIG_PPC32
+
+/* what kind of prep workstation we are */
+extern int _prep_type;
+extern int _chrp_type;
+
+/*
+ * This is used to identify the board type from a given PReP board
+ * vendor. Board revision is also made available. This will be moved
+ * elsewhere soon
+ */
+extern unsigned char ucSystemType;
+extern unsigned char ucBoardRev;
+extern unsigned char ucBoardRevMaj, ucBoardRevMin;
+
+#endif /* CONFIG_PPC32 */
+
+#elif defined(CONFIG_PPC_ISERIES)
+/*
+ * iSeries is soon to become MULTIPLATFORM hopefully ...
+ */
+#define _machine PLATFORM_ISERIES_LPAR
+#else
+#define _machine 0
+#endif /* CONFIG_PPC_MULTIPLATFORM */
+
+/*
+ * Default implementation of macro that returns current
+ * instruction pointer ("program counter").
+ */
+#define current_text_addr() ({ __label__ _l; _l: &&_l;})
+
+/* Macros for adjusting thread priority (hardware multi-threading) */
+#define HMT_very_low() asm volatile("or 31,31,31 # very low priority")
+#define HMT_low() asm volatile("or 1,1,1 # low priority")
+#define HMT_medium_low() asm volatile("or 6,6,6 # medium low priority")
+#define HMT_medium() asm volatile("or 2,2,2 # medium priority")
+#define HMT_medium_high() asm volatile("or 5,5,5 # medium high priority")
+#define HMT_high() asm volatile("or 3,3,3 # high priority")
+
+#ifdef __KERNEL__
+
+extern int have_of;
+
+struct task_struct;
+void start_thread(struct pt_regs *regs, unsigned long fdptr, unsigned long sp);
+void release_thread(struct task_struct *);
+
+/* Prepare to copy thread state - unlazy all lazy status */
+extern void prepare_to_copy(struct task_struct *tsk);
+
+/* Create a new kernel thread. */
+extern long kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
+
+/* Lazy FPU handling on uni-processor */
+extern struct task_struct *last_task_used_math;
+extern struct task_struct *last_task_used_altivec;
+extern struct task_struct *last_task_used_spe;
+
+#ifdef CONFIG_PPC32
+#define TASK_SIZE (CONFIG_TASK_SIZE)
+
+/* This decides where the kernel will search for a free chunk of vm
+ * space during mmap's.
+ */
+#define TASK_UNMAPPED_BASE (TASK_SIZE / 8 * 3)
+#endif
+
+#ifdef CONFIG_PPC64
+/* 64-bit user address space is 44-bits (16TB user VM) */
+#define TASK_SIZE_USER64 (0x0000100000000000UL)
+
+/*
+ * 32-bit user address space is 4GB - 1 page
+ * (this 1 page is needed so referencing of 0xFFFFFFFF generates EFAULT
+ */
+#define TASK_SIZE_USER32 (0x0000000100000000UL - (1*PAGE_SIZE))
+
+#define TASK_SIZE (test_thread_flag(TIF_32BIT) ? \
+ TASK_SIZE_USER32 : TASK_SIZE_USER64)
+
+/* This decides where the kernel will search for a free chunk of vm
+ * space during mmap's.
+ */
+#define TASK_UNMAPPED_BASE_USER32 (PAGE_ALIGN(TASK_SIZE_USER32 / 4))
+#define TASK_UNMAPPED_BASE_USER64 (PAGE_ALIGN(TASK_SIZE_USER64 / 4))
+
+#define TASK_UNMAPPED_BASE ((test_thread_flag(TIF_32BIT)) ? \
+ TASK_UNMAPPED_BASE_USER32 : TASK_UNMAPPED_BASE_USER64 )
+#endif
+
+typedef struct {
+ unsigned long seg;
+} mm_segment_t;
+
+struct thread_struct {
+ unsigned long ksp; /* Kernel stack pointer */
+#ifdef CONFIG_PPC64
+ unsigned long ksp_vsid;
+#endif
+ struct pt_regs *regs; /* Pointer to saved register state */
+ mm_segment_t fs; /* for get_fs() validation */
+#ifdef CONFIG_PPC32
+ void *pgdir; /* root of page-table tree */
+ signed long last_syscall;
+#endif
+#if defined(CONFIG_4xx) || defined (CONFIG_BOOKE)
+ unsigned long dbcr0; /* debug control register values */
+ unsigned long dbcr1;
+#endif
+ double fpr[32]; /* Complete floating point set */
+ struct { /* fpr ... fpscr must be contiguous */
+
+ unsigned int pad;
+ unsigned int val; /* Floating point status */
+ } fpscr;
+ int fpexc_mode; /* floating-point exception mode */
+#ifdef CONFIG_PPC64
+ unsigned long start_tb; /* Start purr when proc switched in */
+ unsigned long accum_tb; /* Total accumilated purr for process */
+ unsigned long vdso_base; /* base of the vDSO library */
+#endif
+ unsigned long dabr; /* Data address breakpoint register */
+#ifdef CONFIG_ALTIVEC
+ /* Complete AltiVec register set */
+ vector128 vr[32] __attribute((aligned(16)));
+ /* AltiVec status */
+ vector128 vscr __attribute((aligned(16)));
+ unsigned long vrsave;
+ int used_vr; /* set if process has used altivec */
+#endif /* CONFIG_ALTIVEC */
+#ifdef CONFIG_SPE
+ unsigned long evr[32]; /* upper 32-bits of SPE regs */
+ u64 acc; /* Accumulator */
+ unsigned long spefscr; /* SPE & eFP status */
+ int used_spe; /* set if process has used spe */
+#endif /* CONFIG_SPE */
+};
+
+#define ARCH_MIN_TASKALIGN 16
+
+#define INIT_SP (sizeof(init_stack) + (unsigned long) &init_stack)
+
+
+#ifdef CONFIG_PPC32
+#define INIT_THREAD { \
+ .ksp = INIT_SP, \
+ .fs = KERNEL_DS, \
+ .pgdir = swapper_pg_dir, \
+ .fpexc_mode = MSR_FE0 | MSR_FE1, \
+}
+#else
+#define INIT_THREAD { \
+ .ksp = INIT_SP, \
+ .regs = (struct pt_regs *)INIT_SP - 1, /* XXX bogus, I think */ \
+ .fs = KERNEL_DS, \
+ .fpr = {0}, \
+ .fpscr = { .val = 0, }, \
+ .fpexc_mode = MSR_FE0|MSR_FE1, \
+}
+#endif
+
+/*
+ * Return saved PC of a blocked thread. For now, this is the "user" PC
+ */
+#define thread_saved_pc(tsk) \
+ ((tsk)->thread.regs? (tsk)->thread.regs->nip: 0)
+
+unsigned long get_wchan(struct task_struct *p);
+
+#define KSTK_EIP(tsk) ((tsk)->thread.regs? (tsk)->thread.regs->nip: 0)
+#define KSTK_ESP(tsk) ((tsk)->thread.regs? (tsk)->thread.regs->gpr[1]: 0)
+
+/* Get/set floating-point exception mode */
+#define GET_FPEXC_CTL(tsk, adr) get_fpexc_mode((tsk), (adr))
+#define SET_FPEXC_CTL(tsk, val) set_fpexc_mode((tsk), (val))
+
+extern int get_fpexc_mode(struct task_struct *tsk, unsigned long adr);
+extern int set_fpexc_mode(struct task_struct *tsk, unsigned int val);
+
+static inline unsigned int __unpack_fe01(unsigned long msr_bits)
+{
+ return ((msr_bits & MSR_FE0) >> 10) | ((msr_bits & MSR_FE1) >> 8);
+}
+
+static inline unsigned long __pack_fe01(unsigned int fpmode)
+{
+ return ((fpmode << 10) & MSR_FE0) | ((fpmode << 8) & MSR_FE1);
+}
+
+#ifdef CONFIG_PPC64
+#define cpu_relax() do { HMT_low(); HMT_medium(); barrier(); } while (0)
+#else
+#define cpu_relax() barrier()
+#endif
+
+/*
+ * Prefetch macros.
+ */
+#define ARCH_HAS_PREFETCH
+#define ARCH_HAS_PREFETCHW
+#define ARCH_HAS_SPINLOCK_PREFETCH
+
+static inline void prefetch(const void *x)
+{
+ if (unlikely(!x))
+ return;
+
+ __asm__ __volatile__ ("dcbt 0,%0" : : "r" (x));
+}
+
+static inline void prefetchw(const void *x)
+{
+ if (unlikely(!x))
+ return;
+
+ __asm__ __volatile__ ("dcbtst 0,%0" : : "r" (x));
+}
+
+#define spin_lock_prefetch(x) prefetchw(x)
+
+#ifdef CONFIG_PPC64
+#define HAVE_ARCH_PICK_MMAP_LAYOUT
+#endif
+
+#endif /* __KERNEL__ */
+#endif /* __ASSEMBLY__ */
+#endif /* _ASM_POWERPC_PROCESSOR_H */
diff --git a/include/asm-powerpc/prom.h b/include/asm-powerpc/prom.h
new file mode 100644
index 000000000000..f999df1c5c90
--- /dev/null
+++ b/include/asm-powerpc/prom.h
@@ -0,0 +1,227 @@
+#ifndef _POWERPC_PROM_H
+#define _POWERPC_PROM_H
+#ifdef __KERNEL__
+
+/*
+ * Definitions for talking to the Open Firmware PROM on
+ * Power Macintosh computers.
+ *
+ * Copyright (C) 1996-2005 Paul Mackerras.
+ *
+ * Updates for PPC64 by Peter Bergner & David Engebretsen, IBM Corp.
+ *
+ * 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/config.h>
+#include <linux/types.h>
+#include <linux/proc_fs.h>
+#include <asm/atomic.h>
+
+/* Definitions used by the flattened device tree */
+#define OF_DT_HEADER 0xd00dfeed /* marker */
+#define OF_DT_BEGIN_NODE 0x1 /* Start of node, full name */
+#define OF_DT_END_NODE 0x2 /* End node */
+#define OF_DT_PROP 0x3 /* Property: name off, size,
+ * content */
+#define OF_DT_NOP 0x4 /* nop */
+#define OF_DT_END 0x9
+
+#define OF_DT_VERSION 0x10
+
+/*
+ * This is what gets passed to the kernel by prom_init or kexec
+ *
+ * The dt struct contains the device tree structure, full pathes and
+ * property contents. The dt strings contain a separate block with just
+ * the strings for the property names, and is fully page aligned and
+ * self contained in a page, so that it can be kept around by the kernel,
+ * each property name appears only once in this page (cheap compression)
+ *
+ * the mem_rsvmap contains a map of reserved ranges of physical memory,
+ * passing it here instead of in the device-tree itself greatly simplifies
+ * the job of everybody. It's just a list of u64 pairs (base/size) that
+ * ends when size is 0
+ */
+struct boot_param_header
+{
+ u32 magic; /* magic word OF_DT_HEADER */
+ u32 totalsize; /* total size of DT block */
+ u32 off_dt_struct; /* offset to structure */
+ u32 off_dt_strings; /* offset to strings */
+ u32 off_mem_rsvmap; /* offset to memory reserve map */
+ u32 version; /* format version */
+ u32 last_comp_version; /* last compatible version */
+ /* version 2 fields below */
+ u32 boot_cpuid_phys; /* Physical CPU id we're booting on */
+ /* version 3 fields below */
+ u32 dt_strings_size; /* size of the DT strings block */
+};
+
+
+
+typedef u32 phandle;
+typedef u32 ihandle;
+
+struct address_range {
+ unsigned long space;
+ unsigned long address;
+ unsigned long size;
+};
+
+struct interrupt_info {
+ int line;
+ int sense; /* +ve/-ve logic, edge or level, etc. */
+};
+
+struct pci_address {
+ u32 a_hi;
+ u32 a_mid;
+ u32 a_lo;
+};
+
+struct isa_address {
+ u32 a_hi;
+ u32 a_lo;
+};
+
+struct isa_range {
+ struct isa_address isa_addr;
+ struct pci_address pci_addr;
+ unsigned int size;
+};
+
+struct reg_property {
+ unsigned long address;
+ unsigned long size;
+};
+
+struct reg_property32 {
+ unsigned int address;
+ unsigned int size;
+};
+
+struct reg_property64 {
+ u64 address;
+ u64 size;
+};
+
+struct property {
+ char *name;
+ int length;
+ unsigned char *value;
+ struct property *next;
+};
+
+struct device_node {
+ char *name;
+ char *type;
+ phandle node;
+ phandle linux_phandle;
+ int n_addrs;
+ struct address_range *addrs;
+ int n_intrs;
+ struct interrupt_info *intrs;
+ char *full_name;
+
+ struct property *properties;
+ struct device_node *parent;
+ struct device_node *child;
+ struct device_node *sibling;
+ struct device_node *next; /* next device of same type */
+ struct device_node *allnext; /* next in list of all nodes */
+ struct proc_dir_entry *pde; /* this node's proc directory */
+ struct kref kref;
+ unsigned long _flags;
+ void *data;
+};
+
+extern struct device_node *of_chosen;
+
+/* flag descriptions */
+#define OF_DYNAMIC 1 /* node and properties were allocated via kmalloc */
+
+#define OF_IS_DYNAMIC(x) test_bit(OF_DYNAMIC, &x->_flags)
+#define OF_MARK_DYNAMIC(x) set_bit(OF_DYNAMIC, &x->_flags)
+
+#define HAVE_ARCH_DEVTREE_FIXUPS
+
+static inline void set_node_proc_entry(struct device_node *dn, struct proc_dir_entry *de)
+{
+ dn->pde = de;
+}
+
+
+/* OBSOLETE: Old style node lookup */
+extern struct device_node *find_devices(const char *name);
+extern struct device_node *find_type_devices(const char *type);
+extern struct device_node *find_path_device(const char *path);
+extern struct device_node *find_compatible_devices(const char *type,
+ const char *compat);
+extern struct device_node *find_all_nodes(void);
+
+/* New style node lookup */
+extern struct device_node *of_find_node_by_name(struct device_node *from,
+ const char *name);
+extern struct device_node *of_find_node_by_type(struct device_node *from,
+ const char *type);
+extern struct device_node *of_find_compatible_node(struct device_node *from,
+ const char *type, const char *compat);
+extern struct device_node *of_find_node_by_path(const char *path);
+extern struct device_node *of_find_node_by_phandle(phandle handle);
+extern struct device_node *of_find_all_nodes(struct device_node *prev);
+extern struct device_node *of_get_parent(const struct device_node *node);
+extern struct device_node *of_get_next_child(const struct device_node *node,
+ struct device_node *prev);
+extern struct device_node *of_node_get(struct device_node *node);
+extern void of_node_put(struct device_node *node);
+
+/* For scanning the flat device-tree at boot time */
+int __init of_scan_flat_dt(int (*it)(unsigned long node,
+ const char *uname, int depth,
+ void *data),
+ void *data);
+void* __init of_get_flat_dt_prop(unsigned long node, const char *name,
+ unsigned long *size);
+
+/* For updating the device tree at runtime */
+extern void of_attach_node(struct device_node *);
+extern void of_detach_node(const struct device_node *);
+
+/* Other Prototypes */
+extern void finish_device_tree(void);
+extern void unflatten_device_tree(void);
+extern void early_init_devtree(void *);
+extern int device_is_compatible(struct device_node *device, const char *);
+extern int machine_is_compatible(const char *compat);
+extern unsigned char *get_property(struct device_node *node, const char *name,
+ int *lenp);
+extern void print_properties(struct device_node *node);
+extern int prom_n_addr_cells(struct device_node* np);
+extern int prom_n_size_cells(struct device_node* np);
+extern int prom_n_intr_cells(struct device_node* np);
+extern void prom_get_irq_senses(unsigned char *senses, int off, int max);
+extern int prom_add_property(struct device_node* np, struct property* prop);
+
+#ifdef CONFIG_PPC32
+/*
+ * PCI <-> OF matching functions
+ * (XXX should these be here?)
+ */
+struct pci_bus;
+struct pci_dev;
+extern int pci_device_from_OF_node(struct device_node *node,
+ u8* bus, u8* devfn);
+extern struct device_node* pci_busdev_to_OF_node(struct pci_bus *, int);
+extern struct device_node* pci_device_to_OF_node(struct pci_dev *);
+extern void pci_create_OF_bus_map(void);
+#endif
+
+extern struct resource *request_OF_resource(struct device_node* node,
+ int index, const char* name_postfix);
+extern int release_OF_resource(struct device_node* node, int index);
+
+#endif /* __KERNEL__ */
+#endif /* _POWERPC_PROM_H */
diff --git a/include/asm-ppc64/ptrace.h b/include/asm-powerpc/ptrace.h
index 3a55377f1fd3..1f7ecdb0b6ce 100644
--- a/include/asm-ppc64/ptrace.h
+++ b/include/asm-powerpc/ptrace.h
@@ -1,5 +1,5 @@
-#ifndef _PPC64_PTRACE_H
-#define _PPC64_PTRACE_H
+#ifndef _ASM_POWERPC_PTRACE_H
+#define _ASM_POWERPC_PTRACE_H
/*
* Copyright (C) 2001 PPC64 Team, IBM Corp
@@ -16,7 +16,7 @@
* that the overall structure is a multiple of 16 bytes in length.
*
* Note that the offsets of the fields in this struct correspond with
- * the PT_* values below. This simplifies arch/ppc64/kernel/ptrace.c.
+ * the PT_* values below. This simplifies arch/powerpc/kernel/ptrace.c.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -30,70 +30,96 @@ struct pt_regs {
unsigned long gpr[32];
unsigned long nip;
unsigned long msr;
- unsigned long orig_gpr3; /* Used for restarting system calls */
+ unsigned long orig_gpr3; /* Used for restarting system calls */
unsigned long ctr;
unsigned long link;
unsigned long xer;
unsigned long ccr;
- unsigned long softe; /* Soft enabled/disabled */
- unsigned long trap; /* Reason for being here */
- unsigned long dar; /* Fault registers */
- unsigned long dsisr;
- unsigned long result; /* Result of a system call */
+#ifdef __powerpc64__
+ unsigned long softe; /* Soft enabled/disabled */
+#else
+ unsigned long mq; /* 601 only (not used at present) */
+ /* Used on APUS to hold IPL value. */
+#endif
+ unsigned long trap; /* Reason for being here */
+ /* N.B. for critical exceptions on 4xx, the dar and dsisr
+ fields are overloaded to hold srr0 and srr1. */
+ unsigned long dar; /* Fault registers */
+ unsigned long dsisr; /* on 4xx/Book-E used for ESR */
+ unsigned long result; /* Result of a system call */
};
-struct pt_regs32 {
- unsigned int gpr[32];
- unsigned int nip;
- unsigned int msr;
- unsigned int orig_gpr3; /* Used for restarting system calls */
- unsigned int ctr;
- unsigned int link;
- unsigned int xer;
- unsigned int ccr;
- unsigned int mq; /* 601 only (not used at present) */
- unsigned int trap; /* Reason for being here */
- unsigned int dar; /* Fault registers */
- unsigned int dsisr;
- unsigned int result; /* Result of a system call */
-};
+#endif /* __ASSEMBLY__ */
#ifdef __KERNEL__
-#define instruction_pointer(regs) ((regs)->nip)
+#ifdef __powerpc64__
+
+#define STACK_FRAME_OVERHEAD 112 /* size of minimum stack frame */
+
+/* Size of dummy stack frame allocated when calling signal handler. */
+#define __SIGNAL_FRAMESIZE 128
+#define __SIGNAL_FRAMESIZE32 64
+
+#else /* __powerpc64__ */
+
+#define STACK_FRAME_OVERHEAD 16 /* size of minimum stack frame */
+
+/* Size of stack frame allocated when calling signal handler. */
+#define __SIGNAL_FRAMESIZE 64
+
+#endif /* __powerpc64__ */
+#ifndef __ASSEMBLY__
+
+#define instruction_pointer(regs) ((regs)->nip)
#ifdef CONFIG_SMP
extern unsigned long profile_pc(struct pt_regs *regs);
#else
#define profile_pc(regs) instruction_pointer(regs)
#endif
+#ifdef __powerpc64__
#define user_mode(regs) ((((regs)->msr) >> MSR_PR_LG) & 0x1)
+#else
+#define user_mode(regs) (((regs)->msr & MSR_PR) != 0)
+#endif
#define force_successful_syscall_return() \
- (current_thread_info()->syscall_noerror = 1)
+ do { \
+ current_thread_info()->syscall_noerror = 1; \
+ } while(0)
/*
* We use the least-significant bit of the trap field to indicate
* whether we have saved the full set of registers, or only a
* partial set. A 1 there means the partial set.
+ * On 4xx we use the next bit to indicate whether the exception
+ * is a critical exception (1 means it is).
*/
#define FULL_REGS(regs) (((regs)->trap & 1) == 0)
+#ifndef __powerpc64__
+#define IS_CRITICAL_EXC(regs) (((regs)->trap & 2) == 0)
+#endif /* ! __powerpc64__ */
#define TRAP(regs) ((regs)->trap & ~0xF)
+#ifdef __powerpc64__
#define CHECK_FULL_REGS(regs) BUG_ON(regs->trap & 1)
-
-#endif /* __KERNEL__ */
+#else
+#define CHECK_FULL_REGS(regs) \
+do { \
+ if ((regs)->trap & 1) \
+ printk(KERN_CRIT "%s: partial register set\n", __FUNCTION__); \
+} while (0)
+#endif /* __powerpc64__ */
#endif /* __ASSEMBLY__ */
-#define STACK_FRAME_OVERHEAD 112 /* size of minimum stack frame */
-
-/* Size of dummy stack frame allocated when calling signal handler. */
-#define __SIGNAL_FRAMESIZE 128
-#define __SIGNAL_FRAMESIZE32 64
+#endif /* __KERNEL__ */
/*
* Offsets used by 'ptrace' system call interface.
+ * These can't be changed without breaking binary compatibility
+ * with MkLinux, etc.
*/
#define PT_R0 0
#define PT_R1 1
@@ -137,18 +163,25 @@ extern unsigned long profile_pc(struct pt_regs *regs);
#define PT_LNK 36
#define PT_XER 37
#define PT_CCR 38
+#ifndef __powerpc64__
+#define PT_MQ 39
+#else
#define PT_SOFTE 39
#define PT_TRAP 40
#define PT_DAR 41
#define PT_DSISR 42
#define PT_RESULT 43
+#endif
-#define PT_FPR0 48
+#define PT_FPR0 48 /* each FP reg occupies 2 slots in this space */
+
+#ifndef __powerpc64__
+
+#define PT_FPR31 (PT_FPR0 + 2*31)
+#define PT_FPSCR (PT_FPR0 + 2*32 + 1)
+
+#else /* __powerpc64__ */
-/*
- * Kernel and userspace will both use this PT_FPSCR value. 32-bit apps will
- * have visibility to the asm-ppc/ptrace.h header instead of this one.
- */
#define PT_FPSCR (PT_FPR0 + 32) /* each FP reg occupies 1 slot in 64-bit space */
#ifdef __KERNEL__
@@ -165,29 +198,29 @@ extern unsigned long profile_pc(struct pt_regs *regs);
#define PT_VRSAVE_32 (PT_VR0 + 33*4)
#endif
+#endif /* __powerpc64__ */
+
/*
- * Get/set all the altivec registers vr0..vr31, vscr, vrsave, in one go.
- * The transfer totals 34 quadword. Quadwords 0-31 contain the
- * corresponding vector registers. Quadword 32 contains the vscr as the
- * last word (offset 12) within that quadword. Quadword 33 contains the
+ * Get/set all the altivec registers vr0..vr31, vscr, vrsave, in one go.
+ * The transfer totals 34 quadword. Quadwords 0-31 contain the
+ * corresponding vector registers. Quadword 32 contains the vscr as the
+ * last word (offset 12) within that quadword. Quadword 33 contains the
* vrsave as the first word (offset 0) within the quadword.
*
- * This definition of the VMX state is compatible with the current PPC32
- * ptrace interface. This allows signal handling and ptrace to use the same
- * structures. This also simplifies the implementation of a bi-arch
+ * This definition of the VMX state is compatible with the current PPC32
+ * ptrace interface. This allows signal handling and ptrace to use the same
+ * structures. This also simplifies the implementation of a bi-arch
* (combined (32- and 64-bit) gdb.
*/
#define PTRACE_GETVRREGS 18
#define PTRACE_SETVRREGS 19
-/*
- * While we dont have 64bit book E processors, we need to reserve the
- * relevant ptrace calls for 32bit compatibility.
- */
-#if 0
-#define PTRACE_GETEVRREGS 20
-#define PTRACE_SETEVRREGS 21
-#endif
+#ifndef __powerpc64__
+/* Get/set all the upper 32-bits of the SPE registers, accumulator, and
+ * spefscr, in one go */
+#define PTRACE_GETEVRREGS 20
+#define PTRACE_SETEVRREGS 21
+#endif /* __powerpc64__ */
/*
* Get or set a debug register. The first 16 are DABR registers and the
@@ -196,6 +229,7 @@ extern unsigned long profile_pc(struct pt_regs *regs);
#define PTRACE_GET_DEBUGREG 25
#define PTRACE_SET_DEBUGREG 26
+#ifdef __powerpc64__
/* Additional PTRACE requests implemented on PowerPC. */
#define PPC_PTRACE_GETREGS 0x99 /* Get GPRs 0 - 31 */
#define PPC_PTRACE_SETREGS 0x98 /* Set GPRs 0 - 31 */
@@ -209,5 +243,6 @@ extern unsigned long profile_pc(struct pt_regs *regs);
#define PPC_PTRACE_POKEDATA_3264 0x92
#define PPC_PTRACE_PEEKUSR_3264 0x91
#define PPC_PTRACE_POKEUSR_3264 0x90
+#endif /* __powerpc64__ */
-#endif /* _PPC64_PTRACE_H */
+#endif /* _ASM_POWERPC_PTRACE_H */
diff --git a/include/asm-ppc/reg.h b/include/asm-powerpc/reg.h
index 73c33e3ef9c6..eb392d038ed7 100644
--- a/include/asm-ppc/reg.h
+++ b/include/asm-powerpc/reg.h
@@ -6,53 +6,111 @@
* Implementations of the PowerPC Architecture (a.k.a. Green Book) here.
*/
+#ifndef _ASM_POWERPC_REG_H
+#define _ASM_POWERPC_REG_H
#ifdef __KERNEL__
-#ifndef __ASM_PPC_REGS_H__
-#define __ASM_PPC_REGS_H__
#include <linux/stringify.h>
+#include <asm/cputable.h>
/* Pickup Book E specific registers. */
#if defined(CONFIG_BOOKE) || defined(CONFIG_40x)
#include <asm/reg_booke.h>
+#endif /* CONFIG_BOOKE || CONFIG_40x */
+
+#ifdef CONFIG_8xx
+#include <asm/reg_8xx.h>
+#endif /* CONFIG_8xx */
+
+#define MSR_SF_LG 63 /* Enable 64 bit mode */
+#define MSR_ISF_LG 61 /* Interrupt 64b mode valid on 630 */
+#define MSR_HV_LG 60 /* Hypervisor state */
+#define MSR_VEC_LG 25 /* Enable AltiVec */
+#define MSR_POW_LG 18 /* Enable Power Management */
+#define MSR_WE_LG 18 /* Wait State Enable */
+#define MSR_TGPR_LG 17 /* TLB Update registers in use */
+#define MSR_CE_LG 17 /* Critical Interrupt Enable */
+#define MSR_ILE_LG 16 /* Interrupt Little Endian */
+#define MSR_EE_LG 15 /* External Interrupt Enable */
+#define MSR_PR_LG 14 /* Problem State / Privilege Level */
+#define MSR_FP_LG 13 /* Floating Point enable */
+#define MSR_ME_LG 12 /* Machine Check Enable */
+#define MSR_FE0_LG 11 /* Floating Exception mode 0 */
+#define MSR_SE_LG 10 /* Single Step */
+#define MSR_BE_LG 9 /* Branch Trace */
+#define MSR_DE_LG 9 /* Debug Exception Enable */
+#define MSR_FE1_LG 8 /* Floating Exception mode 1 */
+#define MSR_IP_LG 6 /* Exception prefix 0x000/0xFFF */
+#define MSR_IR_LG 5 /* Instruction Relocate */
+#define MSR_DR_LG 4 /* Data Relocate */
+#define MSR_PE_LG 3 /* Protection Enable */
+#define MSR_PX_LG 2 /* Protection Exclusive Mode */
+#define MSR_PMM_LG 2 /* Performance monitor */
+#define MSR_RI_LG 1 /* Recoverable Exception */
+#define MSR_LE_LG 0 /* Little Endian */
+
+#ifdef __ASSEMBLY__
+#define __MASK(X) (1<<(X))
+#else
+#define __MASK(X) (1UL<<(X))
+#endif
+
+#ifdef CONFIG_PPC64
+#define MSR_SF __MASK(MSR_SF_LG) /* Enable 64 bit mode */
+#define MSR_ISF __MASK(MSR_ISF_LG) /* Interrupt 64b mode valid on 630 */
+#define MSR_HV __MASK(MSR_HV_LG) /* Hypervisor state */
+#else
+/* so tests for these bits fail on 32-bit */
+#define MSR_SF 0
+#define MSR_ISF 0
+#define MSR_HV 0
+#endif
+
+#define MSR_VEC __MASK(MSR_VEC_LG) /* Enable AltiVec */
+#define MSR_POW __MASK(MSR_POW_LG) /* Enable Power Management */
+#define MSR_WE __MASK(MSR_WE_LG) /* Wait State Enable */
+#define MSR_TGPR __MASK(MSR_TGPR_LG) /* TLB Update registers in use */
+#define MSR_CE __MASK(MSR_CE_LG) /* Critical Interrupt Enable */
+#define MSR_ILE __MASK(MSR_ILE_LG) /* Interrupt Little Endian */
+#define MSR_EE __MASK(MSR_EE_LG) /* External Interrupt Enable */
+#define MSR_PR __MASK(MSR_PR_LG) /* Problem State / Privilege Level */
+#define MSR_FP __MASK(MSR_FP_LG) /* Floating Point enable */
+#define MSR_ME __MASK(MSR_ME_LG) /* Machine Check Enable */
+#define MSR_FE0 __MASK(MSR_FE0_LG) /* Floating Exception mode 0 */
+#define MSR_SE __MASK(MSR_SE_LG) /* Single Step */
+#define MSR_BE __MASK(MSR_BE_LG) /* Branch Trace */
+#define MSR_DE __MASK(MSR_DE_LG) /* Debug Exception Enable */
+#define MSR_FE1 __MASK(MSR_FE1_LG) /* Floating Exception mode 1 */
+#define MSR_IP __MASK(MSR_IP_LG) /* Exception prefix 0x000/0xFFF */
+#define MSR_IR __MASK(MSR_IR_LG) /* Instruction Relocate */
+#define MSR_DR __MASK(MSR_DR_LG) /* Data Relocate */
+#define MSR_PE __MASK(MSR_PE_LG) /* Protection Enable */
+#define MSR_PX __MASK(MSR_PX_LG) /* Protection Exclusive Mode */
+#ifndef MSR_PMM
+#define MSR_PMM __MASK(MSR_PMM_LG) /* Performance monitor */
#endif
+#define MSR_RI __MASK(MSR_RI_LG) /* Recoverable Exception */
+#define MSR_LE __MASK(MSR_LE_LG) /* Little Endian */
-/* Machine State Register (MSR) Fields */
-#define MSR_SF (1<<63)
-#define MSR_ISF (1<<61)
-#define MSR_VEC (1<<25) /* Enable AltiVec */
-#define MSR_POW (1<<18) /* Enable Power Management */
-#define MSR_WE (1<<18) /* Wait State Enable */
-#define MSR_TGPR (1<<17) /* TLB Update registers in use */
-#define MSR_CE (1<<17) /* Critical Interrupt Enable */
-#define MSR_ILE (1<<16) /* Interrupt Little Endian */
-#define MSR_EE (1<<15) /* External Interrupt Enable */
-#define MSR_PR (1<<14) /* Problem State / Privilege Level */
-#define MSR_FP (1<<13) /* Floating Point enable */
-#define MSR_ME (1<<12) /* Machine Check Enable */
-#define MSR_FE0 (1<<11) /* Floating Exception mode 0 */
-#define MSR_SE (1<<10) /* Single Step */
-#define MSR_BE (1<<9) /* Branch Trace */
-#define MSR_DE (1<<9) /* Debug Exception Enable */
-#define MSR_FE1 (1<<8) /* Floating Exception mode 1 */
-#define MSR_IP (1<<6) /* Exception prefix 0x000/0xFFF */
-#define MSR_IR (1<<5) /* Instruction Relocate */
-#define MSR_DR (1<<4) /* Data Relocate */
-#define MSR_PE (1<<3) /* Protection Enable */
-#define MSR_PX (1<<2) /* Protection Exclusive Mode */
-#define MSR_RI (1<<1) /* Recoverable Exception */
-#define MSR_LE (1<<0) /* Little Endian */
+#ifdef CONFIG_PPC64
+#define MSR_ MSR_ME | MSR_RI | MSR_IR | MSR_DR | MSR_ISF
+#define MSR_KERNEL MSR_ | MSR_SF | MSR_HV
+#define MSR_USER32 MSR_ | MSR_PR | MSR_EE
+#define MSR_USER64 MSR_USER32 | MSR_SF
+
+#else /* 32-bit */
/* Default MSR for kernel mode. */
+#ifndef MSR_KERNEL /* reg_booke.h also defines this */
#ifdef CONFIG_APUS_FAST_EXCEPT
#define MSR_KERNEL (MSR_ME|MSR_IP|MSR_RI|MSR_IR|MSR_DR)
-#endif
-
-#ifndef MSR_KERNEL
+#else
#define MSR_KERNEL (MSR_ME|MSR_RI|MSR_IR|MSR_DR)
#endif
+#endif
#define MSR_USER (MSR_KERNEL|MSR_PR|MSR_EE)
+#endif
/* Floating Point Status and Control Register (FPSCR) Fields */
#define FPSCR_FX 0x80000000 /* FPU exception summary */
@@ -60,7 +118,7 @@
#define FPSCR_VX 0x20000000 /* Invalid operation summary */
#define FPSCR_OX 0x10000000 /* Overflow exception summary */
#define FPSCR_UX 0x08000000 /* Underflow exception summary */
-#define FPSCR_ZX 0x04000000 /* Zero-devide exception summary */
+#define FPSCR_ZX 0x04000000 /* Zero-divide exception summary */
#define FPSCR_XX 0x02000000 /* Inexact exception summary */
#define FPSCR_VXSNAN 0x01000000 /* Invalid op for SNaN */
#define FPSCR_VXISI 0x00800000 /* Invalid op for Inv - Inv */
@@ -85,8 +143,18 @@
/* Special Purpose Registers (SPRNs)*/
#define SPRN_CTR 0x009 /* Count Register */
+#define SPRN_CTRLF 0x088
+#define SPRN_CTRLT 0x098
+#define CTRL_RUNLATCH 0x1
#define SPRN_DABR 0x3F5 /* Data Address Breakpoint Register */
+#define DABR_TRANSLATION (1UL << 2)
#define SPRN_DAR 0x013 /* Data Address Register */
+#define SPRN_DSISR 0x012 /* Data Storage Interrupt Status Register */
+#define DSISR_NOHPTE 0x40000000 /* no translation found */
+#define DSISR_PROTFAULT 0x08000000 /* protection fault */
+#define DSISR_ISSTORE 0x02000000 /* access was a store */
+#define DSISR_DABRMATCH 0x00400000 /* hit data breakpoint */
+#define DSISR_NOSEGMENT 0x00200000 /* STAB/SLB miss */
#define SPRN_TBRL 0x10C /* Time Base Read Lower Register (user, R/O) */
#define SPRN_TBRU 0x10D /* Time Base Read Upper Register (user, R/O) */
#define SPRN_TBWL 0x11C /* Time Base Lower Register (super, R/W) */
@@ -131,7 +199,6 @@
#define DER_EBRKE 0x00000002 /* External Breakpoint Interrupt */
#define DER_DPIE 0x00000001 /* Dev. Port Nonmaskable Request */
#define SPRN_DMISS 0x3D0 /* Data TLB Miss Register */
-#define SPRN_DSISR 0x012 /* Data Storage Interrupt Status Register */
#define SPRN_EAR 0x11A /* External Address Register */
#define SPRN_HASH1 0x3D2 /* Primary Hash Address Register */
#define SPRN_HASH2 0x3D3 /* Secondary Hash Address Resgister */
@@ -187,6 +254,16 @@
#define SPRN_IABR 0x3F2 /* Instruction Address Breakpoint Register */
#define SPRN_HID4 0x3F4 /* 970 HID4 */
#define SPRN_HID5 0x3F6 /* 970 HID5 */
+#define SPRN_HID6 0x3F9 /* BE HID 6 */
+#define HID6_LB (0x0F<<12) /* Concurrent Large Page Modes */
+#define HID6_DLP (1<<20) /* Disable all large page modes (4K only) */
+#define SPRN_TSCR 0x399 /* Thread switch control on BE */
+#define SPRN_TTR 0x39A /* Thread switch timeout on BE */
+#define TSCR_DEC_ENABLE 0x200000 /* Decrementer Interrupt */
+#define TSCR_EE_ENABLE 0x100000 /* External Interrupt */
+#define TSCR_EE_BOOST 0x080000 /* External Interrupt Boost */
+#define SPRN_TSC 0x3FD /* Thread switch control on others */
+#define SPRN_TST 0x3FC /* Thread switch timeout on others */
#if !defined(SPRN_IAC1) && !defined(SPRN_IAC2)
#define SPRN_IAC1 0x3F4 /* Instruction Address Compare 1 */
#define SPRN_IAC2 0x3F5 /* Instruction Address Compare 2 */
@@ -270,26 +347,23 @@
#define L3CR_L3DO 0x00000040 /* L3 data only mode */
#define L3CR_PMEN 0x00000004 /* L3 private memory enable */
#define L3CR_PMSIZ 0x00000001 /* L3 private memory size */
+
#define SPRN_MSSCR0 0x3f6 /* Memory Subsystem Control Register 0 */
#define SPRN_MSSSR0 0x3f7 /* Memory Subsystem Status Register 1 */
#define SPRN_LDSTCR 0x3f8 /* Load/Store control register */
#define SPRN_LDSTDB 0x3f4 /* */
#define SPRN_LR 0x008 /* Link Register */
-#define SPRN_MMCR0 0x3B8 /* Monitor Mode Control Register 0 */
-#define SPRN_MMCR1 0x3BC /* Monitor Mode Control Register 1 */
#ifndef SPRN_PIR
#define SPRN_PIR 0x3FF /* Processor Identification Register */
#endif
-#define SPRN_PMC1 0x3B9 /* Performance Counter Register 1 */
-#define SPRN_PMC2 0x3BA /* Performance Counter Register 2 */
-#define SPRN_PMC3 0x3BD /* Performance Counter Register 3 */
-#define SPRN_PMC4 0x3BE /* Performance Counter Register 4 */
#define SPRN_PTEHI 0x3D5 /* 981 7450 PTE HI word (S/W TLB load) */
#define SPRN_PTELO 0x3D6 /* 982 7450 PTE LO word (S/W TLB load) */
+#define SPRN_PURR 0x135 /* Processor Utilization of Resources Reg */
#define SPRN_PVR 0x11F /* Processor Version Register */
#define SPRN_RPA 0x3D6 /* Required Physical Address Register */
#define SPRN_SDA 0x3BF /* Sampled Data Address Register */
#define SPRN_SDR1 0x019 /* MMU Hash Base Register */
+#define SPRN_ASR 0x118 /* Address Space Register */
#define SPRN_SIA 0x3BB /* Sampled Instruction Address Register */
#define SPRN_SPRG0 0x110 /* Special Purpose Register General 0 */
#define SPRN_SPRG1 0x111 /* Special Purpose Register General 1 */
@@ -327,6 +401,55 @@
#define SPRN_VRSAVE 0x100 /* Vector Register Save Register */
#define SPRN_XER 0x001 /* Fixed Point Exception Register */
+#define SPRN_SCOMC 0x114 /* SCOM Access Control */
+#define SPRN_SCOMD 0x115 /* SCOM Access DATA */
+
+/* Performance monitor SPRs */
+#ifdef CONFIG_PPC64
+#define SPRN_MMCR0 795
+#define MMCR0_FC 0x80000000UL /* freeze counters */
+#define MMCR0_FCS 0x40000000UL /* freeze in supervisor state */
+#define MMCR0_KERNEL_DISABLE MMCR0_FCS
+#define MMCR0_FCP 0x20000000UL /* freeze in problem state */
+#define MMCR0_PROBLEM_DISABLE MMCR0_FCP
+#define MMCR0_FCM1 0x10000000UL /* freeze counters while MSR mark = 1 */
+#define MMCR0_FCM0 0x08000000UL /* freeze counters while MSR mark = 0 */
+#define MMCR0_PMXE 0x04000000UL /* performance monitor exception enable */
+#define MMCR0_FCECE 0x02000000UL /* freeze ctrs on enabled cond or event */
+#define MMCR0_TBEE 0x00400000UL /* time base exception enable */
+#define MMCR0_PMC1CE 0x00008000UL /* PMC1 count enable*/
+#define MMCR0_PMCjCE 0x00004000UL /* PMCj count enable*/
+#define MMCR0_TRIGGER 0x00002000UL /* TRIGGER enable */
+#define MMCR0_PMAO 0x00000080UL /* performance monitor alert has occurred, set to 0 after handling exception */
+#define MMCR0_SHRFC 0x00000040UL /* SHRre freeze conditions between threads */
+#define MMCR0_FCTI 0x00000008UL /* freeze counters in tags inactive mode */
+#define MMCR0_FCTA 0x00000004UL /* freeze counters in tags active mode */
+#define MMCR0_FCWAIT 0x00000002UL /* freeze counter in WAIT state */
+#define MMCR0_FCHV 0x00000001UL /* freeze conditions in hypervisor mode */
+#define SPRN_MMCR1 798
+#define SPRN_MMCRA 0x312
+#define MMCRA_SIHV 0x10000000UL /* state of MSR HV when SIAR set */
+#define MMCRA_SIPR 0x08000000UL /* state of MSR PR when SIAR set */
+#define MMCRA_SAMPLE_ENABLE 0x00000001UL /* enable sampling */
+#define SPRN_PMC1 787
+#define SPRN_PMC2 788
+#define SPRN_PMC3 789
+#define SPRN_PMC4 790
+#define SPRN_PMC5 791
+#define SPRN_PMC6 792
+#define SPRN_PMC7 793
+#define SPRN_PMC8 794
+#define SPRN_SIAR 780
+#define SPRN_SDAR 781
+
+#else /* 32-bit */
+#define SPRN_MMCR0 0x3B8 /* Monitor Mode Control Register 0 */
+#define SPRN_MMCR1 0x3BC /* Monitor Mode Control Register 1 */
+#define SPRN_PMC1 0x3B9 /* Performance Counter Register 1 */
+#define SPRN_PMC2 0x3BA /* Performance Counter Register 2 */
+#define SPRN_PMC3 0x3BD /* Performance Counter Register 3 */
+#define SPRN_PMC4 0x3BE /* Performance Counter Register 4 */
+
/* Bit definitions for MMCR0 and PMC1 / PMC2. */
#define MMCR0_PMC1_CYCLES (1 << 7)
#define MMCR0_PMC1_ICACHEMISS (5 << 7)
@@ -336,14 +459,15 @@
#define MMCR0_PMC2_ITLB 0x7
#define MMCR0_PMC2_LOADMISSTIME 0x5
#define MMCR0_PMXE (1 << 26)
-
-/* Processor Version Register */
+#endif
/* Processor Version Register (PVR) field extraction */
#define PVR_VER(pvr) (((pvr) >> 16) & 0xFFFF) /* Version field */
#define PVR_REV(pvr) (((pvr) >> 0) & 0xFFFF) /* Revison field */
+#define __is_processor(pv) (PVR_VER(mfspr(SPRN_PVR)) == (pv))
+
/*
* IBM has further subdivided the standard PowerPC 16-bit version and
* revision subfields of the PVR for the PowerPC 403s into the following:
@@ -399,42 +523,103 @@
#define PVR_8245 0x80811014
#define PVR_8260 PVR_8240
-#if 0
-/* Segment Registers */
-#define SR0 0
-#define SR1 1
-#define SR2 2
-#define SR3 3
-#define SR4 4
-#define SR5 5
-#define SR6 6
-#define SR7 7
-#define SR8 8
-#define SR9 9
-#define SR10 10
-#define SR11 11
-#define SR12 12
-#define SR13 13
-#define SR14 14
-#define SR15 15
-#endif
+/* 64-bit processors */
+/* XXX the prefix should be PVR_, we'll do a global sweep to fix it one day */
+#define PV_NORTHSTAR 0x0033
+#define PV_PULSAR 0x0034
+#define PV_POWER4 0x0035
+#define PV_ICESTAR 0x0036
+#define PV_SSTAR 0x0037
+#define PV_POWER4p 0x0038
+#define PV_970 0x0039
+#define PV_POWER5 0x003A
+#define PV_POWER5p 0x003B
+#define PV_970FX 0x003C
+#define PV_630 0x0040
+#define PV_630p 0x0041
+#define PV_970MP 0x0044
+#define PV_BE 0x0070
+
+/*
+ * Number of entries in the SLB. If this ever changes we should handle
+ * it with a use a cpu feature fixup.
+ */
+#define SLB_NUM_ENTRIES 64
/* Macros for setting and retrieving special purpose registers */
#ifndef __ASSEMBLY__
-#define mfmsr() ({unsigned int rval; \
+#define mfmsr() ({unsigned long rval; \
asm volatile("mfmsr %0" : "=r" (rval)); rval;})
+#ifdef CONFIG_PPC64
+#define __mtmsrd(v, l) asm volatile("mtmsrd %0," __stringify(l) \
+ : : "r" (v))
+#define mtmsrd(v) __mtmsrd((v), 0)
+#define mtmsr(v) mtmsrd(v)
+#else
#define mtmsr(v) asm volatile("mtmsr %0" : : "r" (v))
+#endif
-#define mfspr(rn) ({unsigned int rval; \
+#define mfspr(rn) ({unsigned long rval; \
asm volatile("mfspr %0," __stringify(rn) \
: "=r" (rval)); rval;})
#define mtspr(rn, v) asm volatile("mtspr " __stringify(rn) ",%0" : : "r" (v))
+#define mftb() ({unsigned long rval; \
+ asm volatile("mftb %0" : "=r" (rval)); rval;})
+#define mftbl() ({unsigned long rval; \
+ asm volatile("mftbl %0" : "=r" (rval)); rval;})
+
+#define mttbl(v) asm volatile("mttbl %0":: "r"(v))
+#define mttbu(v) asm volatile("mttbu %0":: "r"(v))
+
+#ifdef CONFIG_PPC32
#define mfsrin(v) ({unsigned int rval; \
asm volatile("mfsrin %0,%1" : "=r" (rval) : "r" (v)); \
rval;})
+#endif
#define proc_trap() asm volatile("trap")
+
+#ifdef CONFIG_PPC64
+static inline void ppc64_runlatch_on(void)
+{
+ unsigned long ctrl;
+
+ if (cpu_has_feature(CPU_FTR_CTRL)) {
+ ctrl = mfspr(SPRN_CTRLF);
+ ctrl |= CTRL_RUNLATCH;
+ mtspr(SPRN_CTRLT, ctrl);
+ }
+}
+
+static inline void ppc64_runlatch_off(void)
+{
+ unsigned long ctrl;
+
+ if (cpu_has_feature(CPU_FTR_CTRL)) {
+ ctrl = mfspr(SPRN_CTRLF);
+ ctrl &= ~CTRL_RUNLATCH;
+ mtspr(SPRN_CTRLT, ctrl);
+ }
+}
+
+extern unsigned long scom970_read(unsigned int address);
+extern void scom970_write(unsigned int address, unsigned long value);
+
+#endif /* CONFIG_PPC64 */
+
+#define __get_SP() ({unsigned long sp; \
+ asm volatile("mr %0,1": "=r" (sp)); sp;})
+
+#else /* __ASSEMBLY__ */
+
+#define RUNLATCH_ON(REG) \
+BEGIN_FTR_SECTION \
+ mfspr (REG),SPRN_CTRLF; \
+ ori (REG),(REG),CTRL_RUNLATCH; \
+ mtspr SPRN_CTRLT,(REG); \
+END_FTR_SECTION_IFSET(CPU_FTR_CTRL)
+
#endif /* __ASSEMBLY__ */
-#endif /* __ASM_PPC_REGS_H__ */
#endif /* __KERNEL__ */
+#endif /* _ASM_POWERPC_REG_H */
diff --git a/include/asm-powerpc/reg_8xx.h b/include/asm-powerpc/reg_8xx.h
new file mode 100644
index 000000000000..e8ea346b21d3
--- /dev/null
+++ b/include/asm-powerpc/reg_8xx.h
@@ -0,0 +1,42 @@
+/*
+ * Contains register definitions common to PowerPC 8xx CPUs. Notice
+ */
+#ifndef _ASM_POWERPC_REG_8xx_H
+#define _ASM_POWERPC_REG_8xx_H
+
+/* Cache control on the MPC8xx is provided through some additional
+ * special purpose registers.
+ */
+#define SPRN_IC_CST 560 /* Instruction cache control/status */
+#define SPRN_IC_ADR 561 /* Address needed for some commands */
+#define SPRN_IC_DAT 562 /* Read-only data register */
+#define SPRN_DC_CST 568 /* Data cache control/status */
+#define SPRN_DC_ADR 569 /* Address needed for some commands */
+#define SPRN_DC_DAT 570 /* Read-only data register */
+
+/* Commands. Only the first few are available to the instruction cache.
+*/
+#define IDC_ENABLE 0x02000000 /* Cache enable */
+#define IDC_DISABLE 0x04000000 /* Cache disable */
+#define IDC_LDLCK 0x06000000 /* Load and lock */
+#define IDC_UNLINE 0x08000000 /* Unlock line */
+#define IDC_UNALL 0x0a000000 /* Unlock all */
+#define IDC_INVALL 0x0c000000 /* Invalidate all */
+
+#define DC_FLINE 0x0e000000 /* Flush data cache line */
+#define DC_SFWT 0x01000000 /* Set forced writethrough mode */
+#define DC_CFWT 0x03000000 /* Clear forced writethrough mode */
+#define DC_SLES 0x05000000 /* Set little endian swap mode */
+#define DC_CLES 0x07000000 /* Clear little endian swap mode */
+
+/* Status.
+*/
+#define IDC_ENABLED 0x80000000 /* Cache is enabled */
+#define IDC_CERR1 0x00200000 /* Cache error 1 */
+#define IDC_CERR2 0x00100000 /* Cache error 2 */
+#define IDC_CERR3 0x00080000 /* Cache error 3 */
+
+#define DC_DFWT 0x40000000 /* Data cache is forced write through */
+#define DC_LES 0x20000000 /* Caches are little endian mode */
+
+#endif /* _ASM_POWERPC_REG_8xx_H */
diff --git a/include/asm-ppc64/rtas.h b/include/asm-powerpc/rtas.h
index e7d1b5222802..d1bb611ea626 100644
--- a/include/asm-ppc64/rtas.h
+++ b/include/asm-powerpc/rtas.h
@@ -1,5 +1,5 @@
-#ifndef _PPC64_RTAS_H
-#define _PPC64_RTAS_H
+#ifndef _POWERPC_RTAS_H
+#define _POWERPC_RTAS_H
#include <linux/spinlock.h>
#include <asm/page.h>
@@ -149,28 +149,11 @@ struct rtas_error_log {
unsigned char buffer[1];
};
-struct flash_block {
- char *data;
- unsigned long length;
-};
-
-/* This struct is very similar but not identical to
- * that needed by the rtas flash update.
- * All we need to do for rtas is rewrite num_blocks
- * into a version/length and translate the pointers
- * to absolute.
+/*
+ * This can be set by the rtas_flash module so that it can get called
+ * as the absolutely last thing before the kernel terminates.
*/
-#define FLASH_BLOCKS_PER_NODE ((PAGE_SIZE - 16) / sizeof(struct flash_block))
-struct flash_block_list {
- unsigned long num_blocks;
- struct flash_block_list *next;
- struct flash_block blocks[FLASH_BLOCKS_PER_NODE];
-};
-struct flash_block_list_header { /* just the header of flash_block_list */
- unsigned long num_blocks;
- struct flash_block_list *next;
-};
-extern struct flash_block_list_header rtas_firmware_flash_list;
+extern void (*rtas_flash_term_hook)(int);
extern struct rtas_t rtas;
@@ -190,7 +173,7 @@ extern void rtas_progress(char *s, unsigned short hex);
extern void rtas_initialize(void);
struct rtc_time;
-extern void rtas_get_boot_time(struct rtc_time *rtc_time);
+extern unsigned long rtas_get_boot_time(void);
extern void rtas_get_rtc_time(struct rtc_time *rtc_time);
extern int rtas_set_rtc_time(struct rtc_time *rtc_time);
@@ -246,4 +229,4 @@ extern unsigned long rtas_rmo_buf;
#define GLOBAL_INTERRUPT_QUEUE 9005
-#endif /* _PPC64_RTAS_H */
+#endif /* _POWERPC_RTAS_H */
diff --git a/include/asm-powerpc/rtc.h b/include/asm-powerpc/rtc.h
new file mode 100644
index 000000000000..f5802926b6c0
--- /dev/null
+++ b/include/asm-powerpc/rtc.h
@@ -0,0 +1,78 @@
+/*
+ * Real-time clock definitions and interfaces
+ *
+ * Author: Tom Rini <trini@mvista.com>
+ *
+ * 2002 (c) MontaVista, Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ *
+ * Based on:
+ * include/asm-m68k/rtc.h
+ *
+ * Copyright Richard Zidlicky
+ * implementation details for genrtc/q40rtc driver
+ *
+ * And the old drivers/macintosh/rtc.c which was heavily based on:
+ * Linux/SPARC Real Time Clock Driver
+ * Copyright (C) 1996 Thomas K. Dyas (tdyas@eden.rutgers.edu)
+ *
+ * With additional work by Paul Mackerras and Franz Sirl.
+ */
+
+#ifndef __ASM_POWERPC_RTC_H__
+#define __ASM_POWERPC_RTC_H__
+
+#ifdef __KERNEL__
+
+#include <linux/rtc.h>
+
+#include <asm/machdep.h>
+#include <asm/time.h>
+
+#define RTC_PIE 0x40 /* periodic interrupt enable */
+#define RTC_AIE 0x20 /* alarm interrupt enable */
+#define RTC_UIE 0x10 /* update-finished interrupt enable */
+
+/* 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 */
+
+static inline unsigned int get_rtc_time(struct rtc_time *time)
+{
+ if (ppc_md.get_rtc_time)
+ ppc_md.get_rtc_time(time);
+ return RTC_24H;
+}
+
+/* Set the current date and time in the real time clock. */
+static inline int set_rtc_time(struct rtc_time *time)
+{
+ if (ppc_md.set_rtc_time)
+ return ppc_md.set_rtc_time(time);
+ return -EINVAL;
+}
+
+static inline unsigned int get_rtc_ss(void)
+{
+ struct rtc_time h;
+
+ get_rtc_time(&h);
+ return h.tm_sec;
+}
+
+static inline int get_rtc_pll(struct rtc_pll_info *pll)
+{
+ return -EINVAL;
+}
+static inline int set_rtc_pll(struct rtc_pll_info *pll)
+{
+ return -EINVAL;
+}
+
+#endif /* __KERNEL__ */
+#endif /* __ASM_POWERPC_RTC_H__ */
diff --git a/include/asm-ppc64/rwsem.h b/include/asm-powerpc/rwsem.h
index bd5c2f093575..79bae4933b73 100644
--- a/include/asm-ppc64/rwsem.h
+++ b/include/asm-powerpc/rwsem.h
@@ -1,18 +1,14 @@
+#ifndef _ASM_POWERPC_RWSEM_H
+#define _ASM_POWERPC_RWSEM_H
+
+#ifdef __KERNEL__
+
/*
* include/asm-ppc64/rwsem.h: R/W semaphores for PPC using the stuff
* in lib/rwsem.c. Adapted largely from include/asm-i386/rwsem.h
* by Paul Mackerras <paulus@samba.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.
*/
-#ifndef _PPC64_RWSEM_H
-#define _PPC64_RWSEM_H
-
-#ifdef __KERNEL__
#include <linux/list.h>
#include <linux/spinlock.h>
#include <asm/atomic.h>
@@ -163,5 +159,10 @@ static inline int rwsem_atomic_update(int delta, struct rw_semaphore *sem)
return atomic_add_return(delta, (atomic_t *)(&sem->count));
}
-#endif /* __KERNEL__ */
-#endif /* _PPC_RWSEM_XADD_H */
+static inline int rwsem_is_locked(struct rw_semaphore *sem)
+{
+ return (sem->count != 0);
+}
+
+#endif /* __KERNEL__ */
+#endif /* _ASM_POWERPC_RWSEM_H */
diff --git a/include/asm-ppc64/scatterlist.h b/include/asm-powerpc/scatterlist.h
index cecce6c6dfbb..8c992d1491d4 100644
--- a/include/asm-ppc64/scatterlist.h
+++ b/include/asm-powerpc/scatterlist.h
@@ -1,6 +1,5 @@
-#ifndef _PPC64_SCATTERLIST_H
-#define _PPC64_SCATTERLIST_H
-
+#ifndef _ASM_POWERPC_SCATTERLIST_H
+#define _ASM_POWERPC_SCATTERLIST_H
/*
* Copyright (C) 2001 PPC64 Team, IBM Corp
*
@@ -10,6 +9,7 @@
* 2 of the License, or (at your option) any later version.
*/
+#ifdef __KERNEL__
#include <linux/types.h>
#include <asm/dma.h>
@@ -19,13 +19,27 @@ struct scatterlist {
unsigned int length;
/* For TCE support */
- u32 dma_address;
+ dma_addr_t dma_address;
u32 dma_length;
};
+/*
+ * These macros should be used after a dma_map_sg call has been done
+ * to get bus addresses of each of the SG entries and their lengths.
+ * You should only work with the number of sg entries pci_map_sg
+ * returns, or alternatively stop on the first sg_dma_len(sg) which
+ * is 0.
+ */
#define sg_dma_address(sg) ((sg)->dma_address)
+#ifdef __powerpc64__
#define sg_dma_len(sg) ((sg)->dma_length)
+#else
+#define sg_dma_len(sg) ((sg)->length)
+#endif
+#ifdef __powerpc64__
#define ISA_DMA_THRESHOLD (~0UL)
+#endif
-#endif /* !(_PPC64_SCATTERLIST_H) */
+#endif /* __KERNEL__ */
+#endif /* _ASM_POWERPC_SCATTERLIST_H */
diff --git a/include/asm-ppc64/seccomp.h b/include/asm-powerpc/seccomp.h
index c130c334bda1..1e1cfe12882b 100644
--- a/include/asm-ppc64/seccomp.h
+++ b/include/asm-powerpc/seccomp.h
@@ -1,11 +1,6 @@
-#ifndef _ASM_SECCOMP_H
-
-#include <linux/thread_info.h> /* already defines TIF_32BIT */
-
-#ifndef TIF_32BIT
-#error "unexpected TIF_32BIT on ppc64"
-#endif
+#ifndef _ASM_POWERPC_SECCOMP_H
+#include <linux/thread_info.h>
#include <linux/unistd.h>
#define __NR_seccomp_read __NR_read
@@ -18,4 +13,4 @@
#define __NR_seccomp_exit_32 __NR_exit
#define __NR_seccomp_sigreturn_32 __NR_sigreturn
-#endif /* _ASM_SECCOMP_H */
+#endif /* _ASM_POWERPC_SECCOMP_H */
diff --git a/include/asm-ppc64/sections.h b/include/asm-powerpc/sections.h
index 308ca6f5ced2..47be2ac2a925 100644
--- a/include/asm-ppc64/sections.h
+++ b/include/asm-powerpc/sections.h
@@ -1,22 +1,11 @@
-#ifndef _PPC64_SECTIONS_H
-#define _PPC64_SECTIONS_H
-
-extern char _end[];
+#ifndef _ASM_POWERPC_SECTIONS_H
+#define _ASM_POWERPC_SECTIONS_H
#include <asm-generic/sections.h>
-#define __pmac
-#define __pmacdata
-
-#define __prep
-#define __prepdata
-
-#define __chrp
-#define __chrpdata
-
-#define __openfirmware
-#define __openfirmwaredata
+#ifdef __powerpc64__
+extern char _end[];
static inline int in_kernel_text(unsigned long addr)
{
@@ -27,3 +16,5 @@ static inline int in_kernel_text(unsigned long addr)
}
#endif
+
+#endif /* _ASM_POWERPC_SECTIONS_H */
diff --git a/include/asm-ppc64/semaphore.h b/include/asm-powerpc/semaphore.h
index aefe7753ea41..57369d2cadef 100644
--- a/include/asm-ppc64/semaphore.h
+++ b/include/asm-powerpc/semaphore.h
@@ -1,5 +1,5 @@
-#ifndef _PPC64_SEMAPHORE_H
-#define _PPC64_SEMAPHORE_H
+#ifndef _ASM_POWERPC_SEMAPHORE_H
+#define _ASM_POWERPC_SEMAPHORE_H
/*
* Remove spinlock-based RW semaphores; RW semaphore definitions are
@@ -31,9 +31,6 @@ struct semaphore {
.wait = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \
}
-#define __MUTEX_INITIALIZER(name) \
- __SEMAPHORE_INITIALIZER(name, 1)
-
#define __DECLARE_SEMAPHORE_GENERIC(name, count) \
struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
@@ -95,4 +92,4 @@ static inline void up(struct semaphore * sem)
#endif /* __KERNEL__ */
-#endif /* !(_PPC64_SEMAPHORE_H) */
+#endif /* _ASM_POWERPC_SEMAPHORE_H */
diff --git a/include/asm-ppc64/sigcontext.h b/include/asm-powerpc/sigcontext.h
index 6f8aee768c5e..165d630e1cf3 100644
--- a/include/asm-ppc64/sigcontext.h
+++ b/include/asm-powerpc/sigcontext.h
@@ -1,5 +1,5 @@
-#ifndef _ASM_PPC64_SIGCONTEXT_H
-#define _ASM_PPC64_SIGCONTEXT_H
+#ifndef _ASM_POWERPC_SIGCONTEXT_H
+#define _ASM_POWERPC_SIGCONTEXT_H
/*
* This program is free software; you can redistribute it and/or
@@ -9,39 +9,44 @@
*/
#include <linux/compiler.h>
#include <asm/ptrace.h>
+#ifdef __powerpc64__
#include <asm/elf.h>
-
+#endif
struct sigcontext {
unsigned long _unused[4];
int signal;
+#ifdef __powerpc64__
int _pad0;
+#endif
unsigned long handler;
unsigned long oldmask;
struct pt_regs __user *regs;
+#ifdef __powerpc64__
elf_gregset_t gp_regs;
elf_fpregset_t fp_regs;
/*
- * To maintain compatibility with current implementations the sigcontext is
- * extended by appending a pointer (v_regs) to a quadword type (elf_vrreg_t)
- * followed by an unstructured (vmx_reserve) field of 69 doublewords. This
- * allows the array of vector registers to be quadword aligned independent of
- * the alignment of the containing sigcontext or ucontext. It is the
- * responsibility of the code setting the sigcontext to set this pointer to
- * either NULL (if this processor does not support the VMX feature) or the
+ * To maintain compatibility with current implementations the sigcontext is
+ * extended by appending a pointer (v_regs) to a quadword type (elf_vrreg_t)
+ * followed by an unstructured (vmx_reserve) field of 69 doublewords. This
+ * allows the array of vector registers to be quadword aligned independent of
+ * the alignment of the containing sigcontext or ucontext. It is the
+ * responsibility of the code setting the sigcontext to set this pointer to
+ * either NULL (if this processor does not support the VMX feature) or the
* address of the first quadword within the allocated (vmx_reserve) area.
*
- * The pointer (v_regs) of vector type (elf_vrreg_t) is type compatible with
- * an array of 34 quadword entries (elf_vrregset_t). The entries with
- * indexes 0-31 contain the corresponding vector registers. The entry with
- * index 32 contains the vscr as the last word (offset 12) within the
- * quadword. This allows the vscr to be stored as either a quadword (since
- * it must be copied via a vector register to/from storage) or as a word.
- * The entry with index 33 contains the vrsave as the first word (offset 0)
+ * The pointer (v_regs) of vector type (elf_vrreg_t) is type compatible with
+ * an array of 34 quadword entries (elf_vrregset_t). The entries with
+ * indexes 0-31 contain the corresponding vector registers. The entry with
+ * index 32 contains the vscr as the last word (offset 12) within the
+ * quadword. This allows the vscr to be stored as either a quadword (since
+ * it must be copied via a vector register to/from storage) or as a word.
+ * The entry with index 33 contains the vrsave as the first word (offset 0)
* within the quadword.
*/
elf_vrreg_t __user *v_regs;
long vmx_reserve[ELF_NVRREG+ELF_NVRREG+1];
+#endif
};
-#endif /* _ASM_PPC64_SIGCONTEXT_H */
+#endif /* _ASM_POWERPC_SIGCONTEXT_H */
diff --git a/include/asm-ppc/signal.h b/include/asm-powerpc/signal.h
index caf6ede3710f..694c8d2dab87 100644
--- a/include/asm-ppc/signal.h
+++ b/include/asm-powerpc/signal.h
@@ -1,18 +1,11 @@
-#ifndef _ASMPPC_SIGNAL_H
-#define _ASMPPC_SIGNAL_H
+#ifndef _ASM_POWERPC_SIGNAL_H
+#define _ASM_POWERPC_SIGNAL_H
-#ifdef __KERNEL__
#include <linux/types.h>
-#endif /* __KERNEL__ */
-
-/* Avoid too many header ordering problems. */
-struct siginfo;
-
-/* Most things should be clean enough to redefine this at will, if care
- is taken to make libc match. */
+#include <linux/config.h>
#define _NSIG 64
-#define _NSIG_BPW 32
+#define _NSIG_BPW BITS_PER_LONG
#define _NSIG_WORDS (_NSIG / _NSIG_BPW)
typedef unsigned long old_sigset_t; /* at least 32 bits */
@@ -77,19 +70,19 @@ typedef struct {
* SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single
* Unix names RESETHAND and NODEFER respectively.
*/
-#define SA_NOCLDSTOP 0x00000001
-#define SA_NOCLDWAIT 0x00000002
-#define SA_SIGINFO 0x00000004
-#define SA_ONSTACK 0x08000000
-#define SA_RESTART 0x10000000
-#define SA_NODEFER 0x40000000
-#define SA_RESETHAND 0x80000000
+#define SA_NOCLDSTOP 0x00000001U
+#define SA_NOCLDWAIT 0x00000002U
+#define SA_SIGINFO 0x00000004U
+#define SA_ONSTACK 0x08000000U
+#define SA_RESTART 0x10000000U
+#define SA_NODEFER 0x40000000U
+#define SA_RESETHAND 0x80000000U
#define SA_NOMASK SA_NODEFER
#define SA_ONESHOT SA_RESETHAND
-#define SA_INTERRUPT 0x20000000 /* dummy -- ignored */
+#define SA_INTERRUPT 0x20000000u /* dummy -- ignored */
-#define SA_RESTORER 0x04000000
+#define SA_RESTORER 0x04000000U
/*
* sigaltstack controls
@@ -127,10 +120,13 @@ typedef struct sigaltstack {
} stack_t;
#ifdef __KERNEL__
-#include <asm/sigcontext.h>
+struct pt_regs;
+extern int do_signal(sigset_t *oldset, struct pt_regs *regs);
+extern int do_signal32(sigset_t *oldset, struct pt_regs *regs);
#define ptrace_signal_deliver(regs, cookie) do { } while (0)
#endif /* __KERNEL__ */
+#ifndef __powerpc64__
/*
* These are parameters to dbg_sigreturn syscall. They enable or
* disable certain debugging things that can be done from signal
@@ -149,5 +145,6 @@ struct sig_dbg_op {
/* Enable or disable branch tracing. The value sets the state. */
#define SIG_DBG_BRANCH_TRACING 2
+#endif /* ! __powerpc64__ */
-#endif
+#endif /* _ASM_POWERPC_SIGNAL_H */
diff --git a/include/asm-ppc64/smp.h b/include/asm-powerpc/smp.h
index d86f742e9a21..98581e5a8279 100644
--- a/include/asm-ppc64/smp.h
+++ b/include/asm-powerpc/smp.h
@@ -1,5 +1,5 @@
/*
- * smp.h: PPC64 specific SMP code.
+ * smp.h: PowerPC-specific SMP code.
*
* Original was a copy of sparc smp.h. Now heavily modified
* for PPC.
@@ -13,9 +13,9 @@
* 2 of the License, or (at your option) any later version.
*/
+#ifndef _ASM_POWERPC_SMP_H
+#define _ASM_POWERPC_SMP_H
#ifdef __KERNEL__
-#ifndef _PPC64_SMP_H
-#define _PPC64_SMP_H
#include <linux/config.h>
#include <linux/threads.h>
@@ -24,7 +24,9 @@
#ifndef __ASSEMBLY__
+#ifdef CONFIG_PPC64
#include <asm/paca.h>
+#endif
extern int boot_cpuid;
extern int boot_cpuid_phys;
@@ -45,8 +47,19 @@ void generic_cpu_die(unsigned int cpu);
void generic_mach_cpu_die(void);
#endif
+#ifdef CONFIG_PPC64
#define raw_smp_processor_id() (get_paca()->paca_index)
#define hard_smp_processor_id() (get_paca()->hw_cpu_id)
+#else
+/* 32-bit */
+extern int smp_hw_index[];
+
+#define raw_smp_processor_id() (current_thread_info()->cpu)
+#define hard_smp_processor_id() (smp_hw_index[smp_processor_id()])
+#define get_hard_smp_processor_id(cpu) (smp_hw_index[(cpu)])
+#define set_hard_smp_processor_id(cpu, phys)\
+ (smp_hw_index[(cpu)] = (phys))
+#endif
extern cpumask_t cpu_sibling_map[NR_CPUS];
@@ -64,20 +77,37 @@ extern cpumask_t cpu_sibling_map[NR_CPUS];
void smp_init_iSeries(void);
void smp_init_pSeries(void);
+void smp_init_cell(void);
+void smp_setup_cpu_maps(void);
extern int __cpu_disable(void);
extern void __cpu_die(unsigned int cpu);
+
+#else
+/* for UP */
+#define smp_setup_cpu_maps()
+
#endif /* CONFIG_SMP */
+#ifdef CONFIG_PPC64
#define get_hard_smp_processor_id(CPU) (paca[(CPU)].hw_cpu_id)
#define set_hard_smp_processor_id(CPU, VAL) \
do { (paca[(CPU)].hw_cpu_id = (VAL)); } while (0)
+extern void smp_release_cpus(void);
+
+#else
+/* 32-bit */
+#ifndef CONFIG_SMP
+#define get_hard_smp_processor_id(cpu) boot_cpuid_phys
+#define set_hard_smp_processor_id(cpu, phys)
+#endif
+#endif
+
extern int smt_enabled_at_boot;
extern int smp_mpic_probe(void);
extern void smp_mpic_setup_cpu(int cpu);
-extern void smp_mpic_message_pass(int target, int msg);
extern void smp_generic_kick_cpu(int nr);
extern void smp_generic_give_timebase(void);
@@ -85,15 +115,7 @@ extern void smp_generic_take_timebase(void);
extern struct smp_ops_t *smp_ops;
-#ifdef CONFIG_PPC_PSERIES
-void vpa_init(int cpu);
-#else
-static inline void vpa_init(int cpu)
-{
-}
-#endif /* CONFIG_PPC_PSERIES */
-
#endif /* __ASSEMBLY__ */
-#endif /* !(_PPC64_SMP_H) */
#endif /* __KERNEL__ */
+#endif /* _ASM_POWERPC_SMP_H) */
diff --git a/include/asm-ppc64/smu.h b/include/asm-powerpc/smu.h
index dee8eefe47bc..76c29a9784dd 100644
--- a/include/asm-ppc64/smu.h
+++ b/include/asm-powerpc/smu.h
@@ -20,16 +20,52 @@
/*
* Partition info commands
*
- * I do not know what those are for at this point
+ * These commands are used to retreive the sdb-partition-XX datas from
+ * the SMU. The lenght is always 2. First byte is the subcommand code
+ * and second byte is the partition ID.
+ *
+ * The reply is 6 bytes:
+ *
+ * - 0..1 : partition address
+ * - 2 : a byte containing the partition ID
+ * - 3 : length (maybe other bits are rest of header ?)
+ *
+ * The data must then be obtained with calls to another command:
+ * SMU_CMD_MISC_ee_GET_DATABLOCK_REC (described below).
*/
#define SMU_CMD_PARTITION_COMMAND 0x3e
+#define SMU_CMD_PARTITION_LATEST 0x01
+#define SMU_CMD_PARTITION_BASE 0x02
+#define SMU_CMD_PARTITION_UPDATE 0x03
/*
* Fan control
*
- * This is a "mux" for fan control commands, first byte is the
- * "sub" command.
+ * This is a "mux" for fan control commands. The command seem to
+ * act differently based on the number of arguments. With 1 byte
+ * of argument, this seem to be queries for fans status, setpoint,
+ * etc..., while with 0xe arguments, we will set the fans speeds.
+ *
+ * Queries (1 byte arg):
+ * ---------------------
+ *
+ * arg=0x01: read RPM fans status
+ * arg=0x02: read RPM fans setpoint
+ * arg=0x11: read PWM fans status
+ * arg=0x12: read PWM fans setpoint
+ *
+ * the "status" queries return the current speed while the "setpoint" ones
+ * return the programmed/target speed. It _seems_ that the result is a bit
+ * mask in the first byte of active/available fans, followed by 6 words (16
+ * bits) containing the requested speed.
+ *
+ * Setpoint (14 bytes arg):
+ * ------------------------
+ *
+ * first arg byte is 0 for RPM fans and 0x10 for PWM. Second arg byte is the
+ * mask of fans affected by the command. Followed by 6 words containing the
+ * setpoint value for selected fans in the mask (or 0 if mask value is 0)
*/
#define SMU_CMD_FAN_COMMAND 0x4a
@@ -144,7 +180,11 @@
* - lenght 8 ("VSLEWxyz") has 3 additional bytes appended, and is
* used to set the voltage slewing point. The SMU replies with "DONE"
* I yet have to figure out their exact meaning of those 3 bytes in
- * both cases.
+ * both cases. They seem to be:
+ * x = processor mask
+ * y = op. point index
+ * z = processor freq. step index
+ * I haven't yet decyphered result codes
*
*/
#define SMU_CMD_POWER_COMMAND 0xaa
@@ -152,6 +192,14 @@
#define SMU_CMD_POWER_SHUTDOWN "SHUTDOWN"
#define SMU_CMD_POWER_VOLTAGE_SLEW "VSLEW"
+/*
+ * Read ADC sensors
+ *
+ * This command takes one byte of parameter: the sensor ID (or "reg"
+ * value in the device-tree) and returns a 16 bits value
+ */
+#define SMU_CMD_READ_ADC 0xd8
+
/* Misc commands
*
* This command seem to be a grab bag of various things
@@ -172,6 +220,25 @@
* Misc commands
*
* This command seem to be a grab bag of various things
+ *
+ * SMU_CMD_MISC_ee_GET_DATABLOCK_REC is used, among others, to
+ * transfer blocks of data from the SMU. So far, I've decrypted it's
+ * usage to retreive partition data. In order to do that, you have to
+ * break your transfer in "chunks" since that command cannot transfer
+ * more than a chunk at a time. The chunk size used by OF is 0xe bytes,
+ * but it seems that the darwin driver will let you do 0x1e bytes if
+ * your "PMU" version is >= 0x30. You can get the "PMU" version apparently
+ * either in the last 16 bits of property "smu-version-pmu" or as the 16
+ * bytes at offset 1 of "smu-version-info"
+ *
+ * For each chunk, the command takes 7 bytes of arguments:
+ * byte 0: subcommand code (0x02)
+ * byte 1: 0x04 (always, I don't know what it means, maybe the address
+ * space to use or some other nicety. It's hard coded in OF)
+ * byte 2..5: SMU address of the chunk (big endian 32 bits)
+ * byte 6: size to transfer (up to max chunk size)
+ *
+ * The data is returned directly
*/
#define SMU_CMD_MISC_ee_COMMAND 0xee
#define SMU_CMD_MISC_ee_GET_DATABLOCK_REC 0x02
@@ -333,6 +400,128 @@ extern int smu_queue_i2c(struct smu_i2c_cmd *cmd);
#endif /* __KERNEL__ */
+
+/*
+ * - SMU "sdb" partitions informations -
+ */
+
+
+/*
+ * Partition header format
+ */
+struct smu_sdbp_header {
+ __u8 id;
+ __u8 len;
+ __u8 version;
+ __u8 flags;
+};
+
+
+ /*
+ * demangle 16 and 32 bits integer in some SMU partitions
+ * (currently, afaik, this concerns only the FVT partition
+ * (0x12)
+ */
+#define SMU_U16_MIX(x) le16_to_cpu(x);
+#define SMU_U32_MIX(x) ((((x) & 0xff00ff00u) >> 8)|(((x) & 0x00ff00ffu) << 8))
+
+
+/* This is the definition of the SMU sdb-partition-0x12 table (called
+ * CPU F/V/T operating points in Darwin). The definition for all those
+ * SMU tables should be moved to some separate file
+ */
+#define SMU_SDB_FVT_ID 0x12
+
+struct smu_sdbp_fvt {
+ __u32 sysclk; /* Base SysClk frequency in Hz for
+ * this operating point. Value need to
+ * be unmixed with SMU_U32_MIX()
+ */
+ __u8 pad;
+ __u8 maxtemp; /* Max temp. supported by this
+ * operating point
+ */
+
+ __u16 volts[3]; /* CPU core voltage for the 3
+ * PowerTune modes, a mode with
+ * 0V = not supported. Value need
+ * to be unmixed with SMU_U16_MIX()
+ */
+};
+
+/* This partition contains voltage & current sensor calibration
+ * informations
+ */
+#define SMU_SDB_CPUVCP_ID 0x21
+
+struct smu_sdbp_cpuvcp {
+ __u16 volt_scale; /* u4.12 fixed point */
+ __s16 volt_offset; /* s4.12 fixed point */
+ __u16 curr_scale; /* u4.12 fixed point */
+ __s16 curr_offset; /* s4.12 fixed point */
+ __s32 power_quads[3]; /* s4.28 fixed point */
+};
+
+/* This partition contains CPU thermal diode calibration
+ */
+#define SMU_SDB_CPUDIODE_ID 0x18
+
+struct smu_sdbp_cpudiode {
+ __u16 m_value; /* u1.15 fixed point */
+ __s16 b_value; /* s10.6 fixed point */
+
+};
+
+/* This partition contains Slots power calibration
+ */
+#define SMU_SDB_SLOTSPOW_ID 0x78
+
+struct smu_sdbp_slotspow {
+ __u16 pow_scale; /* u4.12 fixed point */
+ __s16 pow_offset; /* s4.12 fixed point */
+};
+
+/* This partition contains machine specific version information about
+ * the sensor/control layout
+ */
+#define SMU_SDB_SENSORTREE_ID 0x25
+
+struct smu_sdbp_sensortree {
+ u8 model_id;
+ u8 unknown[3];
+};
+
+/* This partition contains CPU thermal control PID informations. So far
+ * only single CPU machines have been seen with an SMU, so we assume this
+ * carries only informations for those
+ */
+#define SMU_SDB_CPUPIDDATA_ID 0x17
+
+struct smu_sdbp_cpupiddata {
+ u8 unknown1;
+ u8 target_temp_delta;
+ u8 unknown2;
+ u8 history_len;
+ s16 power_adj;
+ u16 max_power;
+ s32 gp,gr,gd;
+};
+
+
+/* Other partitions without known structures */
+#define SMU_SDB_DEBUG_SWITCHES_ID 0x05
+
+#ifdef __KERNEL__
+/*
+ * This returns the pointer to an SMU "sdb" partition data or NULL
+ * if not found. The data format is described below
+ */
+extern struct smu_sdbp_header *smu_get_sdb_partition(int id,
+ unsigned int *size);
+
+#endif /* __KERNEL__ */
+
+
/*
* - Userland interface -
*/
@@ -365,8 +554,10 @@ struct smu_user_cmd_hdr
__u32 cmdtype;
#define SMU_CMDTYPE_SMU 0 /* SMU command */
#define SMU_CMDTYPE_WANTS_EVENTS 1 /* switch fd to events mode */
+#define SMU_CMDTYPE_GET_PARTITION 2 /* retreive an sdb partition */
__u8 cmd; /* SMU command byte */
+ __u8 pad[3]; /* padding */
__u32 data_len; /* Lenght of data following */
};
diff --git a/include/asm-ppc64/sparsemem.h b/include/asm-powerpc/sparsemem.h
index c5bd47e57f17..58d2aab416f8 100644
--- a/include/asm-ppc64/sparsemem.h
+++ b/include/asm-powerpc/sparsemem.h
@@ -1,5 +1,5 @@
-#ifndef _ASM_PPC64_SPARSEMEM_H
-#define _ASM_PPC64_SPARSEMEM_H 1
+#ifndef _ASM_POWERPC_SPARSEMEM_H
+#define _ASM_POWERPC_SPARSEMEM_H 1
#ifdef CONFIG_SPARSEMEM
/*
@@ -11,6 +11,10 @@
#define MAX_PHYSADDR_BITS 38
#define MAX_PHYSMEM_BITS 36
+#ifdef CONFIG_MEMORY_HOTPLUG
+extern void create_section_mapping(unsigned long start, unsigned long end);
+#endif /* CONFIG_MEMORY_HOTPLUG */
+
#endif /* CONFIG_SPARSEMEM */
-#endif /* _ASM_PPC64_SPARSEMEM_H */
+#endif /* _ASM_POWERPC_SPARSEMEM_H */
diff --git a/include/asm-ppc64/spinlock_types.h b/include/asm-powerpc/spinlock_types.h
index a37c8eabb9f2..74236c9f05b1 100644
--- a/include/asm-ppc64/spinlock_types.h
+++ b/include/asm-powerpc/spinlock_types.h
@@ -1,5 +1,5 @@
-#ifndef __ASM_SPINLOCK_TYPES_H
-#define __ASM_SPINLOCK_TYPES_H
+#ifndef _ASM_POWERPC_SPINLOCK_TYPES_H
+#define _ASM_POWERPC_SPINLOCK_TYPES_H
#ifndef __LINUX_SPINLOCK_TYPES_H
# error "please don't include this file directly"
diff --git a/include/asm-ppc64/sstep.h b/include/asm-powerpc/sstep.h
index 4a68db50ee6f..630a9889c07c 100644
--- a/include/asm-ppc64/sstep.h
+++ b/include/asm-powerpc/sstep.h
@@ -16,8 +16,10 @@ struct pt_regs;
* we don't allow putting a breakpoint on an mtmsrd instruction.
* Similarly we don't allow breakpoints on rfid instructions.
* These macros tell us if an instruction is a mtmsrd or rfid.
+ * Note that IS_MTMSRD returns true for both an mtmsr (32-bit)
+ * and an mtmsrd (64-bit).
*/
-#define IS_MTMSRD(instr) (((instr) & 0xfc0007fe) == 0x7c000164)
+#define IS_MTMSRD(instr) (((instr) & 0xfc0007be) == 0x7c000124)
#define IS_RFID(instr) (((instr) & 0xfc0007fe) == 0x4c000024)
/* Emulate instructions that cause a transfer of control. */
diff --git a/include/asm-powerpc/stat.h b/include/asm-powerpc/stat.h
new file mode 100644
index 000000000000..e4edc510b530
--- /dev/null
+++ b/include/asm-powerpc/stat.h
@@ -0,0 +1,81 @@
+#ifndef _ASM_POWERPC_STAT_H
+#define _ASM_POWERPC_STAT_H
+/*
+ * 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/types.h>
+
+#define STAT_HAVE_NSEC 1
+
+#ifndef __powerpc64__
+struct __old_kernel_stat {
+ unsigned short st_dev;
+ unsigned short st_ino;
+ unsigned short st_mode;
+ unsigned short st_nlink;
+ unsigned short st_uid;
+ unsigned short st_gid;
+ unsigned short st_rdev;
+ unsigned long st_size;
+ unsigned long st_atime;
+ unsigned long st_mtime;
+ unsigned long st_ctime;
+};
+#endif /* !__powerpc64__ */
+
+struct stat {
+ unsigned long st_dev;
+ ino_t st_ino;
+#ifdef __powerpc64__
+ nlink_t st_nlink;
+ mode_t st_mode;
+#else
+ mode_t st_mode;
+ nlink_t st_nlink;
+#endif
+ uid_t st_uid;
+ gid_t st_gid;
+ unsigned long st_rdev;
+ off_t st_size;
+ unsigned long st_blksize;
+ unsigned long st_blocks;
+ unsigned long st_atime;
+ unsigned long st_atime_nsec;
+ unsigned long st_mtime;
+ unsigned long st_mtime_nsec;
+ unsigned long st_ctime;
+ unsigned long st_ctime_nsec;
+ unsigned long __unused4;
+ unsigned long __unused5;
+#ifdef __powerpc64__
+ unsigned long __unused6;
+#endif
+};
+
+/* This matches struct stat64 in glibc2.1. Only used for 32 bit. */
+struct stat64 {
+ unsigned long long st_dev; /* Device. */
+ unsigned long long st_ino; /* File serial number. */
+ unsigned int st_mode; /* File mode. */
+ unsigned int st_nlink; /* Link count. */
+ unsigned int st_uid; /* User ID of the file's owner. */
+ unsigned int st_gid; /* Group ID of the file's group. */
+ unsigned long long st_rdev; /* Device number, if device. */
+ unsigned short __pad2;
+ long long st_size; /* Size of file, in bytes. */
+ int st_blksize; /* Optimal block size for I/O. */
+ long long st_blocks; /* Number 512-byte blocks allocated. */
+ int st_atime; /* Time of last access. */
+ unsigned int st_atime_nsec;
+ int st_mtime; /* Time of last modification. */
+ unsigned int st_mtime_nsec;
+ int st_ctime; /* Time of last status change. */
+ unsigned int st_ctime_nsec;
+ unsigned int __unused4;
+ unsigned int __unused5;
+};
+
+#endif /* _ASM_POWERPC_STAT_H */
diff --git a/include/asm-ppc64/statfs.h b/include/asm-powerpc/statfs.h
index 3c985e5246a7..67024026c10d 100644
--- a/include/asm-ppc64/statfs.h
+++ b/include/asm-powerpc/statfs.h
@@ -1,12 +1,11 @@
-#ifndef _PPC64_STATFS_H
-#define _PPC64_STATFS_H
+#ifndef _ASM_POWERPC_STATFS_H
+#define _ASM_POWERPC_STATFS_H
-/*
- * 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.
- */
+/* For ppc32 we just use the generic definitions, not so simple on ppc64 */
+
+#ifndef __powerpc64__
+#include <asm-generic/statfs.h>
+#else
#ifndef __KERNEL_STRICT_NAMES
#include <linux/types.h>
@@ -57,5 +56,5 @@ struct compat_statfs64 {
__u32 f_frsize;
__u32 f_spare[5];
};
-
-#endif /* _PPC64_STATFS_H */
+#endif /* ! __powerpc64__ */
+#endif
diff --git a/include/asm-powerpc/synch.h b/include/asm-powerpc/synch.h
new file mode 100644
index 000000000000..4660c0394a77
--- /dev/null
+++ b/include/asm-powerpc/synch.h
@@ -0,0 +1,51 @@
+#ifndef _ASM_POWERPC_SYNCH_H
+#define _ASM_POWERPC_SYNCH_H
+
+#include <linux/config.h>
+
+#ifdef __powerpc64__
+#define __SUBARCH_HAS_LWSYNC
+#endif
+
+#ifdef __SUBARCH_HAS_LWSYNC
+# define LWSYNC lwsync
+#else
+# define LWSYNC sync
+#endif
+
+
+/*
+ * Arguably the bitops and *xchg operations don't imply any memory barrier
+ * or SMP ordering, but in fact a lot of drivers expect them to imply
+ * both, since they do on x86 cpus.
+ */
+#ifdef CONFIG_SMP
+#define EIEIO_ON_SMP "eieio\n"
+#define ISYNC_ON_SMP "\n\tisync"
+#define SYNC_ON_SMP __stringify(LWSYNC) "\n"
+#else
+#define EIEIO_ON_SMP
+#define ISYNC_ON_SMP
+#define SYNC_ON_SMP
+#endif
+
+static inline void eieio(void)
+{
+ __asm__ __volatile__ ("eieio" : : : "memory");
+}
+
+static inline void isync(void)
+{
+ __asm__ __volatile__ ("isync" : : : "memory");
+}
+
+#ifdef CONFIG_SMP
+#define eieio_on_smp() eieio()
+#define isync_on_smp() isync()
+#else
+#define eieio_on_smp() __asm__ __volatile__("": : :"memory")
+#define isync_on_smp() __asm__ __volatile__("": : :"memory")
+#endif
+
+#endif /* _ASM_POWERPC_SYNCH_H */
+
diff --git a/include/asm-powerpc/system.h b/include/asm-powerpc/system.h
new file mode 100644
index 000000000000..5341b75c75cb
--- /dev/null
+++ b/include/asm-powerpc/system.h
@@ -0,0 +1,411 @@
+/*
+ * Copyright (C) 1999 Cort Dougan <cort@cs.nmt.edu>
+ */
+#ifndef _ASM_POWERPC_SYSTEM_H
+#define _ASM_POWERPC_SYSTEM_H
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+
+#include <asm/hw_irq.h>
+#include <asm/atomic.h>
+
+/*
+ * Memory barrier.
+ * The sync instruction guarantees that all memory accesses initiated
+ * by this processor have been performed (with respect to all other
+ * mechanisms that access memory). The eieio instruction is a barrier
+ * providing an ordering (separately) for (a) cacheable stores and (b)
+ * loads and stores to non-cacheable memory (e.g. I/O devices).
+ *
+ * mb() prevents loads and stores being reordered across this point.
+ * rmb() prevents loads being reordered across this point.
+ * wmb() prevents stores being reordered across this point.
+ * read_barrier_depends() prevents data-dependent loads being reordered
+ * across this point (nop on PPC).
+ *
+ * We have to use the sync instructions for mb(), since lwsync doesn't
+ * order loads with respect to previous stores. Lwsync is fine for
+ * rmb(), though. Note that lwsync is interpreted as sync by
+ * 32-bit and older 64-bit CPUs.
+ *
+ * For wmb(), we use sync since wmb is used in drivers to order
+ * stores to system memory with respect to writes to the device.
+ * However, smp_wmb() can be a lighter-weight eieio barrier on
+ * SMP since it is only used to order updates to system memory.
+ */
+#define mb() __asm__ __volatile__ ("sync" : : : "memory")
+#define rmb() __asm__ __volatile__ ("lwsync" : : : "memory")
+#define wmb() __asm__ __volatile__ ("sync" : : : "memory")
+#define read_barrier_depends() do { } while(0)
+
+#define set_mb(var, value) do { var = value; mb(); } while (0)
+#define set_wmb(var, value) do { var = value; wmb(); } while (0)
+
+#ifdef CONFIG_SMP
+#define smp_mb() mb()
+#define smp_rmb() rmb()
+#define smp_wmb() __asm__ __volatile__ ("eieio" : : : "memory")
+#define smp_read_barrier_depends() read_barrier_depends()
+#else
+#define smp_mb() barrier()
+#define smp_rmb() barrier()
+#define smp_wmb() barrier()
+#define smp_read_barrier_depends() do { } while(0)
+#endif /* CONFIG_SMP */
+
+#ifdef __KERNEL__
+struct task_struct;
+struct pt_regs;
+
+#ifdef CONFIG_DEBUGGER
+
+extern int (*__debugger)(struct pt_regs *regs);
+extern int (*__debugger_ipi)(struct pt_regs *regs);
+extern int (*__debugger_bpt)(struct pt_regs *regs);
+extern int (*__debugger_sstep)(struct pt_regs *regs);
+extern int (*__debugger_iabr_match)(struct pt_regs *regs);
+extern int (*__debugger_dabr_match)(struct pt_regs *regs);
+extern int (*__debugger_fault_handler)(struct pt_regs *regs);
+
+#define DEBUGGER_BOILERPLATE(__NAME) \
+static inline int __NAME(struct pt_regs *regs) \
+{ \
+ if (unlikely(__ ## __NAME)) \
+ return __ ## __NAME(regs); \
+ return 0; \
+}
+
+DEBUGGER_BOILERPLATE(debugger)
+DEBUGGER_BOILERPLATE(debugger_ipi)
+DEBUGGER_BOILERPLATE(debugger_bpt)
+DEBUGGER_BOILERPLATE(debugger_sstep)
+DEBUGGER_BOILERPLATE(debugger_iabr_match)
+DEBUGGER_BOILERPLATE(debugger_dabr_match)
+DEBUGGER_BOILERPLATE(debugger_fault_handler)
+
+#ifdef CONFIG_XMON
+extern void xmon_init(int enable);
+#endif
+
+#else
+static inline int debugger(struct pt_regs *regs) { return 0; }
+static inline int debugger_ipi(struct pt_regs *regs) { return 0; }
+static inline int debugger_bpt(struct pt_regs *regs) { return 0; }
+static inline int debugger_sstep(struct pt_regs *regs) { return 0; }
+static inline int debugger_iabr_match(struct pt_regs *regs) { return 0; }
+static inline int debugger_dabr_match(struct pt_regs *regs) { return 0; }
+static inline int debugger_fault_handler(struct pt_regs *regs) { return 0; }
+#endif
+
+extern int set_dabr(unsigned long dabr);
+extern void print_backtrace(unsigned long *);
+extern void show_regs(struct pt_regs * regs);
+extern void flush_instruction_cache(void);
+extern void hard_reset_now(void);
+extern void poweroff_now(void);
+
+#ifdef CONFIG_6xx
+extern long _get_L2CR(void);
+extern long _get_L3CR(void);
+extern void _set_L2CR(unsigned long);
+extern void _set_L3CR(unsigned long);
+#else
+#define _get_L2CR() 0L
+#define _get_L3CR() 0L
+#define _set_L2CR(val) do { } while(0)
+#define _set_L3CR(val) do { } while(0)
+#endif
+
+extern void via_cuda_init(void);
+extern void read_rtc_time(void);
+extern void pmac_find_display(void);
+extern void giveup_fpu(struct task_struct *);
+extern void disable_kernel_fp(void);
+extern void enable_kernel_fp(void);
+extern void flush_fp_to_thread(struct task_struct *);
+extern void enable_kernel_altivec(void);
+extern void giveup_altivec(struct task_struct *);
+extern void load_up_altivec(struct task_struct *);
+extern int emulate_altivec(struct pt_regs *);
+extern void giveup_spe(struct task_struct *);
+extern void load_up_spe(struct task_struct *);
+extern int fix_alignment(struct pt_regs *);
+extern void cvt_fd(float *from, double *to, struct thread_struct *thread);
+extern void cvt_df(double *from, float *to, struct thread_struct *thread);
+
+#ifdef CONFIG_ALTIVEC
+extern void flush_altivec_to_thread(struct task_struct *);
+#else
+static inline void flush_altivec_to_thread(struct task_struct *t)
+{
+}
+#endif
+
+#ifdef CONFIG_SPE
+extern void flush_spe_to_thread(struct task_struct *);
+#else
+static inline void flush_spe_to_thread(struct task_struct *t)
+{
+}
+#endif
+
+extern int call_rtas(const char *, int, int, unsigned long *, ...);
+extern void cacheable_memzero(void *p, unsigned int nb);
+extern void *cacheable_memcpy(void *, const void *, unsigned int);
+extern int do_page_fault(struct pt_regs *, unsigned long, unsigned long);
+extern void bad_page_fault(struct pt_regs *, unsigned long, int);
+extern int die(const char *, struct pt_regs *, long);
+extern void _exception(int, struct pt_regs *, int, unsigned long);
+#ifdef CONFIG_BOOKE_WDT
+extern u32 booke_wdt_enabled;
+extern u32 booke_wdt_period;
+#endif /* CONFIG_BOOKE_WDT */
+
+/* EBCDIC -> ASCII conversion for [0-9A-Z] on iSeries */
+extern unsigned char e2a(unsigned char);
+
+struct device_node;
+extern void note_scsi_host(struct device_node *, void *);
+
+extern struct task_struct *__switch_to(struct task_struct *,
+ struct task_struct *);
+#define switch_to(prev, next, last) ((last) = __switch_to((prev), (next)))
+
+struct thread_struct;
+extern struct task_struct *_switch(struct thread_struct *prev,
+ struct thread_struct *next);
+
+extern unsigned int rtas_data;
+extern int mem_init_done; /* set on boot once kmalloc can be called */
+extern unsigned long memory_limit;
+extern unsigned long klimit;
+
+extern int powersave_nap; /* set if nap mode can be used in idle loop */
+
+/*
+ * Atomic exchange
+ *
+ * Changes the memory location '*ptr' to be val and returns
+ * the previous value stored there.
+ */
+static __inline__ unsigned long
+__xchg_u32(volatile void *p, unsigned long val)
+{
+ unsigned long prev;
+
+ __asm__ __volatile__(
+ EIEIO_ON_SMP
+"1: lwarx %0,0,%2 \n"
+ PPC405_ERR77(0,%2)
+" stwcx. %3,0,%2 \n\
+ bne- 1b"
+ ISYNC_ON_SMP
+ : "=&r" (prev), "=m" (*(volatile unsigned int *)p)
+ : "r" (p), "r" (val), "m" (*(volatile unsigned int *)p)
+ : "cc", "memory");
+
+ return prev;
+}
+
+#ifdef CONFIG_PPC64
+static __inline__ unsigned long
+__xchg_u64(volatile void *p, unsigned long val)
+{
+ unsigned long prev;
+
+ __asm__ __volatile__(
+ EIEIO_ON_SMP
+"1: ldarx %0,0,%2 \n"
+ PPC405_ERR77(0,%2)
+" stdcx. %3,0,%2 \n\
+ bne- 1b"
+ ISYNC_ON_SMP
+ : "=&r" (prev), "=m" (*(volatile unsigned long *)p)
+ : "r" (p), "r" (val), "m" (*(volatile unsigned long *)p)
+ : "cc", "memory");
+
+ return prev;
+}
+#endif
+
+/*
+ * This function doesn't exist, so you'll get a linker error
+ * if something tries to do an invalid xchg().
+ */
+extern void __xchg_called_with_bad_pointer(void);
+
+static __inline__ unsigned long
+__xchg(volatile void *ptr, unsigned long x, unsigned int size)
+{
+ switch (size) {
+ case 4:
+ return __xchg_u32(ptr, x);
+#ifdef CONFIG_PPC64
+ case 8:
+ return __xchg_u64(ptr, x);
+#endif
+ }
+ __xchg_called_with_bad_pointer();
+ return x;
+}
+
+#define xchg(ptr,x) \
+ ({ \
+ __typeof__(*(ptr)) _x_ = (x); \
+ (__typeof__(*(ptr))) __xchg((ptr), (unsigned long)_x_, sizeof(*(ptr))); \
+ })
+
+#define tas(ptr) (xchg((ptr),1))
+
+/*
+ * Compare and exchange - if *p == old, set it to new,
+ * and return the old value of *p.
+ */
+#define __HAVE_ARCH_CMPXCHG 1
+
+static __inline__ unsigned long
+__cmpxchg_u32(volatile unsigned int *p, unsigned long old, unsigned long new)
+{
+ unsigned int prev;
+
+ __asm__ __volatile__ (
+ EIEIO_ON_SMP
+"1: lwarx %0,0,%2 # __cmpxchg_u32\n\
+ cmpw 0,%0,%3\n\
+ bne- 2f\n"
+ PPC405_ERR77(0,%2)
+" stwcx. %4,0,%2\n\
+ bne- 1b"
+ ISYNC_ON_SMP
+ "\n\
+2:"
+ : "=&r" (prev), "=m" (*p)
+ : "r" (p), "r" (old), "r" (new), "m" (*p)
+ : "cc", "memory");
+
+ return prev;
+}
+
+#ifdef CONFIG_PPC64
+static __inline__ unsigned long
+__cmpxchg_u64(volatile unsigned long *p, unsigned long old, unsigned long new)
+{
+ unsigned long prev;
+
+ __asm__ __volatile__ (
+ EIEIO_ON_SMP
+"1: ldarx %0,0,%2 # __cmpxchg_u64\n\
+ cmpd 0,%0,%3\n\
+ bne- 2f\n\
+ stdcx. %4,0,%2\n\
+ bne- 1b"
+ ISYNC_ON_SMP
+ "\n\
+2:"
+ : "=&r" (prev), "=m" (*p)
+ : "r" (p), "r" (old), "r" (new), "m" (*p)
+ : "cc", "memory");
+
+ return prev;
+}
+#endif
+
+/* This function doesn't exist, so you'll get a linker error
+ if something tries to do an invalid cmpxchg(). */
+extern void __cmpxchg_called_with_bad_pointer(void);
+
+static __inline__ unsigned long
+__cmpxchg(volatile void *ptr, unsigned long old, unsigned long new,
+ unsigned int size)
+{
+ switch (size) {
+ case 4:
+ return __cmpxchg_u32(ptr, old, new);
+#ifdef CONFIG_PPC64
+ case 8:
+ return __cmpxchg_u64(ptr, old, new);
+#endif
+ }
+ __cmpxchg_called_with_bad_pointer();
+ return old;
+}
+
+#define cmpxchg(ptr,o,n) \
+ ({ \
+ __typeof__(*(ptr)) _o_ = (o); \
+ __typeof__(*(ptr)) _n_ = (n); \
+ (__typeof__(*(ptr))) __cmpxchg((ptr), (unsigned long)_o_, \
+ (unsigned long)_n_, sizeof(*(ptr))); \
+ })
+
+#ifdef CONFIG_PPC64
+/*
+ * We handle most unaligned accesses in hardware. On the other hand
+ * unaligned DMA can be very expensive on some ppc64 IO chips (it does
+ * powers of 2 writes until it reaches sufficient alignment).
+ *
+ * Based on this we disable the IP header alignment in network drivers.
+ */
+#define NET_IP_ALIGN 0
+#endif
+
+#define arch_align_stack(x) (x)
+
+/* Used in very early kernel initialization. */
+extern unsigned long reloc_offset(void);
+extern unsigned long add_reloc_offset(unsigned long);
+extern void reloc_got2(unsigned long);
+
+#define PTRRELOC(x) ((typeof(x)) add_reloc_offset((unsigned long)(x)))
+
+static inline void create_instruction(unsigned long addr, unsigned int instr)
+{
+ unsigned int *p;
+ p = (unsigned int *)addr;
+ *p = instr;
+ asm ("dcbst 0, %0; sync; icbi 0,%0; sync; isync" : : "r" (p));
+}
+
+/* Flags for create_branch:
+ * "b" == create_branch(addr, target, 0);
+ * "ba" == create_branch(addr, target, BRANCH_ABSOLUTE);
+ * "bl" == create_branch(addr, target, BRANCH_SET_LINK);
+ * "bla" == create_branch(addr, target, BRANCH_ABSOLUTE | BRANCH_SET_LINK);
+ */
+#define BRANCH_SET_LINK 0x1
+#define BRANCH_ABSOLUTE 0x2
+
+static inline void create_branch(unsigned long addr,
+ unsigned long target, int flags)
+{
+ unsigned int instruction;
+
+ if (! (flags & BRANCH_ABSOLUTE))
+ target = target - addr;
+
+ /* Mask out the flags and target, so they don't step on each other. */
+ instruction = 0x48000000 | (flags & 0x3) | (target & 0x03FFFFFC);
+
+ create_instruction(addr, instruction);
+}
+
+static inline void create_function_call(unsigned long addr, void * func)
+{
+ unsigned long func_addr;
+
+#ifdef CONFIG_PPC64
+ /*
+ * On PPC64 the function pointer actually points to the function's
+ * descriptor. The first entry in the descriptor is the address
+ * of the function text.
+ */
+ func_addr = *(unsigned long *)func;
+#else
+ func_addr = (unsigned long)func;
+#endif
+ create_branch(addr, func_addr, BRANCH_SET_LINK);
+}
+
+#endif /* __KERNEL__ */
+#endif /* _ASM_POWERPC_SYSTEM_H */
diff --git a/include/asm-ppc64/systemcfg.h b/include/asm-powerpc/systemcfg.h
index 9b86b53129aa..36b5cbe466f1 100644
--- a/include/asm-ppc64/systemcfg.h
+++ b/include/asm-powerpc/systemcfg.h
@@ -1,7 +1,7 @@
#ifndef _SYSTEMCFG_H
#define _SYSTEMCFG_H
-/*
+/*
* Copyright (C) 2002 Peter Bergner <bergner@vnet.ibm.com>, IBM
*
* This program is free software; you can redistribute it and/or
@@ -12,7 +12,7 @@
/* Change Activity:
* 2002/09/30 : bergner : Created
- * End Change Activity
+ * End Change Activity
*/
/*
@@ -56,7 +56,7 @@ struct systemcfg {
};
#ifdef __KERNEL__
-extern struct systemcfg *systemcfg;
+extern struct systemcfg *_systemcfg; /* to be renamed */
#endif
#endif /* __ASSEMBLY__ */
diff --git a/include/asm-powerpc/tce.h b/include/asm-powerpc/tce.h
new file mode 100644
index 000000000000..d099d5200f9b
--- /dev/null
+++ b/include/asm-powerpc/tce.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2001 Mike Corrigan & Dave Engebretsen, IBM Corporation
+ * Rewrite, cleanup:
+ * Copyright (C) 2004 Olof Johansson <olof@austin.ibm.com>, IBM 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 _ASM_POWERPC_TCE_H
+#define _ASM_POWERPC_TCE_H
+
+/*
+ * Tces come in two formats, one for the virtual bus and a different
+ * format for PCI
+ */
+#define TCE_VB 0
+#define TCE_PCI 1
+
+/* TCE page size is 4096 bytes (1 << 12) */
+
+#define TCE_SHIFT 12
+#define TCE_PAGE_SIZE (1 << TCE_SHIFT)
+#define TCE_PAGE_FACTOR (PAGE_SHIFT - TCE_SHIFT)
+
+
+/* tce_entry
+ * Used by pSeries (SMP) and iSeries/pSeries LPAR, but there it's
+ * abstracted so layout is irrelevant.
+ */
+union tce_entry {
+ unsigned long te_word;
+ struct {
+ unsigned int tb_cacheBits :6; /* Cache hash bits - not used */
+ unsigned int tb_rsvd :6;
+ unsigned long tb_rpn :40; /* Real page number */
+ unsigned int tb_valid :1; /* Tce is valid (vb only) */
+ unsigned int tb_allio :1; /* Tce is valid for all lps (vb only) */
+ unsigned int tb_lpindex :8; /* LpIndex for user of TCE (vb only) */
+ unsigned int tb_pciwr :1; /* Write allowed (pci only) */
+ unsigned int tb_rdwr :1; /* Read allowed (pci), Write allowed (vb) */
+ } te_bits;
+#define te_cacheBits te_bits.tb_cacheBits
+#define te_rpn te_bits.tb_rpn
+#define te_valid te_bits.tb_valid
+#define te_allio te_bits.tb_allio
+#define te_lpindex te_bits.tb_lpindex
+#define te_pciwr te_bits.tb_pciwr
+#define te_rdwr te_bits.tb_rdwr
+};
+
+
+#endif /* _ASM_POWERPC_TCE_H */
diff --git a/include/asm-powerpc/termios.h b/include/asm-powerpc/termios.h
index c5b8e5358f83..7f80a019b6a0 100644
--- a/include/asm-powerpc/termios.h
+++ b/include/asm-powerpc/termios.h
@@ -94,142 +94,9 @@ struct termio {
#define INIT_C_CC "\003\034\177\025\004\001\000\000\000\000\027\022\032\021\023\026\025"
#endif
-#define FIOCLEX _IO('f', 1)
-#define FIONCLEX _IO('f', 2)
-#define FIOASYNC _IOW('f', 125, int)
-#define FIONBIO _IOW('f', 126, int)
-#define FIONREAD _IOR('f', 127, int)
-#define TIOCINQ FIONREAD
-
-#define TIOCGETP _IOR('t', 8, struct sgttyb)
-#define TIOCSETP _IOW('t', 9, struct sgttyb)
-#define TIOCSETN _IOW('t', 10, struct sgttyb) /* TIOCSETP wo flush */
-
-#define TIOCSETC _IOW('t', 17, struct tchars)
-#define TIOCGETC _IOR('t', 18, struct tchars)
-#define TCGETS _IOR('t', 19, struct termios)
-#define TCSETS _IOW('t', 20, struct termios)
-#define TCSETSW _IOW('t', 21, struct termios)
-#define TCSETSF _IOW('t', 22, struct termios)
-
-#define TCGETA _IOR('t', 23, struct termio)
-#define TCSETA _IOW('t', 24, struct termio)
-#define TCSETAW _IOW('t', 25, struct termio)
-#define TCSETAF _IOW('t', 28, struct termio)
-
-#define TCSBRK _IO('t', 29)
-#define TCXONC _IO('t', 30)
-#define TCFLSH _IO('t', 31)
-
-#define TIOCSWINSZ _IOW('t', 103, struct winsize)
-#define TIOCGWINSZ _IOR('t', 104, struct winsize)
-#define TIOCSTART _IO('t', 110) /* start output, like ^Q */
-#define TIOCSTOP _IO('t', 111) /* stop output, like ^S */
-#define TIOCOUTQ _IOR('t', 115, int) /* output queue size */
-
-#define TIOCGLTC _IOR('t', 116, struct ltchars)
-#define TIOCSLTC _IOW('t', 117, struct ltchars)
-#define TIOCSPGRP _IOW('t', 118, int)
-#define TIOCGPGRP _IOR('t', 119, int)
-
-#define TIOCEXCL 0x540C
-#define TIOCNXCL 0x540D
-#define TIOCSCTTY 0x540E
-
-#define TIOCSTI 0x5412
-#define TIOCMGET 0x5415
-#define TIOCMBIS 0x5416
-#define TIOCMBIC 0x5417
-#define TIOCMSET 0x5418
-#define TIOCGSOFTCAR 0x5419
-#define TIOCSSOFTCAR 0x541A
-#define TIOCLINUX 0x541C
-#define TIOCCONS 0x541D
-#define TIOCGSERIAL 0x541E
-#define TIOCSSERIAL 0x541F
-#define TIOCPKT 0x5420
-
-#define TIOCNOTTY 0x5422
-#define TIOCSETD 0x5423
-#define TIOCGETD 0x5424
-#define TCSBRKP 0x5425 /* Needed for POSIX tcsendbreak() */
-
-#define TIOCSERCONFIG 0x5453
-#define TIOCSERGWILD 0x5454
-#define TIOCSERSWILD 0x5455
-#define TIOCGLCKTRMIOS 0x5456
-#define TIOCSLCKTRMIOS 0x5457
-#define TIOCSERGSTRUCT 0x5458 /* For debugging only */
-#define TIOCSERGETLSR 0x5459 /* Get line status register */
-#define TIOCSERGETMULTI 0x545A /* Get multiport config */
-#define TIOCSERSETMULTI 0x545B /* Set multiport config */
-
-#define TIOCMIWAIT 0x545C /* wait for a change on serial input line(s) */
-#define TIOCGICOUNT 0x545D /* read serial port inline interrupt counts */
-
-/* Used for packet mode */
-#define TIOCPKT_DATA 0
-#define TIOCPKT_FLUSHREAD 1
-#define TIOCPKT_FLUSHWRITE 2
-#define TIOCPKT_STOP 4
-#define TIOCPKT_START 8
-#define TIOCPKT_NOSTOP 16
-#define TIOCPKT_DOSTOP 32
-
-/* modem lines */
-#define TIOCM_LE 0x001
-#define TIOCM_DTR 0x002
-#define TIOCM_RTS 0x004
-#define TIOCM_ST 0x008
-#define TIOCM_SR 0x010
-#define TIOCM_CTS 0x020
-#define TIOCM_CAR 0x040
-#define TIOCM_RNG 0x080
-#define TIOCM_DSR 0x100
-#define TIOCM_CD TIOCM_CAR
-#define TIOCM_RI TIOCM_RNG
-#define TIOCM_OUT1 0x2000
-#define TIOCM_OUT2 0x4000
-#define TIOCM_LOOP 0x8000
-
-/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
-#define TIOCSER_TEMT 0x01 /* Transmitter physically empty */
-
#ifdef __KERNEL__
-/*
- * Translate a "termio" structure into a "termios". Ugh.
- */
-#define SET_LOW_TERMIOS_BITS(termios, termio, x) { \
- unsigned short __tmp; \
- get_user(__tmp,&(termio)->x); \
- (termios)->x = (0xffff0000 & (termios)->x) | __tmp; \
-}
-
-#define user_termio_to_kernel_termios(termios, termio) \
-({ \
- SET_LOW_TERMIOS_BITS(termios, termio, c_iflag); \
- SET_LOW_TERMIOS_BITS(termios, termio, c_oflag); \
- SET_LOW_TERMIOS_BITS(termios, termio, c_cflag); \
- SET_LOW_TERMIOS_BITS(termios, termio, c_lflag); \
- copy_from_user((termios)->c_cc, (termio)->c_cc, NCC); \
-})
-
-/*
- * Translate a "termios" structure into a "termio". Ugh.
- */
-#define kernel_termios_to_user_termio(termio, termios) \
-({ \
- put_user((termios)->c_iflag, &(termio)->c_iflag); \
- put_user((termios)->c_oflag, &(termio)->c_oflag); \
- put_user((termios)->c_cflag, &(termio)->c_cflag); \
- put_user((termios)->c_lflag, &(termio)->c_lflag); \
- put_user((termios)->c_line, &(termio)->c_line); \
- copy_to_user((termio)->c_cc, (termios)->c_cc, NCC); \
-})
-
-#define user_termios_to_kernel_termios(k, u) copy_from_user(k, u, sizeof(struct termios))
-#define kernel_termios_to_user_termios(u, k) copy_to_user(u, k, sizeof(struct termios))
+#include <asm-generic/termios.h>
#endif /* __KERNEL__ */
diff --git a/include/asm-ppc64/thread_info.h b/include/asm-powerpc/thread_info.h
index 0494df6fca74..e525f49bd179 100644
--- a/include/asm-ppc64/thread_info.h
+++ b/include/asm-powerpc/thread_info.h
@@ -1,15 +1,25 @@
-/* thread_info.h: PPC low-level thread information
+/* thread_info.h: PowerPC low-level thread information
* adapted from the i386 version by Paul Mackerras
*
* Copyright (C) 2002 David Howells (dhowells@redhat.com)
* - Incorporating suggestions made by Linus Torvalds and Dave Miller
*/
-#ifndef _ASM_THREAD_INFO_H
-#define _ASM_THREAD_INFO_H
+#ifndef _ASM_POWERPC_THREAD_INFO_H
+#define _ASM_POWERPC_THREAD_INFO_H
#ifdef __KERNEL__
+/* We have 8k stacks on ppc32 and 16k on ppc64 */
+
+#ifdef CONFIG_PPC64
+#define THREAD_SHIFT 14
+#else
+#define THREAD_SHIFT 13
+#endif
+
+#define THREAD_SIZE (1 << THREAD_SHIFT)
+
#ifndef __ASSEMBLY__
#include <linux/config.h>
#include <linux/cache.h>
@@ -24,7 +34,8 @@ struct thread_info {
struct task_struct *task; /* main task structure */
struct exec_domain *exec_domain; /* execution domain */
int cpu; /* cpu we're on */
- int preempt_count; /* 0 => preemptable, <0 => BUG */
+ int preempt_count; /* 0 => preemptable,
+ <0 => BUG */
struct restart_block restart_block;
/* set by force_successful_syscall_return */
unsigned char syscall_noerror;
@@ -54,32 +65,42 @@ struct thread_info {
/* thread information allocation */
-#define THREAD_ORDER 2
-#define THREAD_SIZE (PAGE_SIZE << THREAD_ORDER)
-#define THREAD_SHIFT (PAGE_SHIFT + THREAD_ORDER)
+#if THREAD_SHIFT >= PAGE_SHIFT
+
+#define THREAD_ORDER (THREAD_SHIFT - PAGE_SHIFT)
+
#ifdef CONFIG_DEBUG_STACK_USAGE
-#define alloc_thread_info(tsk) \
- ({ \
- struct thread_info *ret; \
- \
- ret = kmalloc(THREAD_SIZE, GFP_KERNEL); \
- if (ret) \
- memset(ret, 0, THREAD_SIZE); \
- ret; \
- })
+#define alloc_thread_info(tsk) \
+ ((struct thread_info *)__get_free_pages(GFP_KERNEL | \
+ __GFP_ZERO, THREAD_ORDER))
#else
-#define alloc_thread_info(tsk) kmalloc(THREAD_SIZE, GFP_KERNEL)
+#define alloc_thread_info(tsk) \
+ ((struct thread_info *)__get_free_pages(GFP_KERNEL, THREAD_ORDER))
+#endif
+#define free_thread_info(ti) free_pages((unsigned long)ti, THREAD_ORDER)
+
+#else /* THREAD_SHIFT < PAGE_SHIFT */
+
+#ifdef CONFIG_DEBUG_STACK_USAGE
+#define alloc_thread_info(tsk) kzalloc(THREAD_SIZE, GFP_KERNEL)
+#else
+#define alloc_thread_info(tsk) kmalloc(THREAD_SIZE, GFP_KERNEL)
#endif
#define free_thread_info(ti) kfree(ti)
+
+#endif /* THREAD_SHIFT < PAGE_SHIFT */
+
#define get_thread_info(ti) get_task_struct((ti)->task)
#define put_thread_info(ti) put_task_struct((ti)->task)
/* how to get the thread information struct from C */
static inline struct thread_info *current_thread_info(void)
{
- struct thread_info *ti;
- __asm__("clrrdi %0,1,%1" : "=r"(ti) : "i" (THREAD_SHIFT));
- return ti;
+ register unsigned long sp asm("r1");
+
+ /* gcc4, at least, is smart enough to turn this into a single
+ * rlwinm for ppc32 and clrrdi for ppc64 */
+ return (struct thread_info *)(sp & ~(THREAD_SIZE-1));
}
#endif /* __ASSEMBLY__ */
@@ -122,4 +143,4 @@ static inline struct thread_info *current_thread_info(void)
#endif /* __KERNEL__ */
-#endif /* _ASM_THREAD_INFO_H */
+#endif /* _ASM_POWERPC_THREAD_INFO_H */
diff --git a/include/asm-powerpc/time.h b/include/asm-powerpc/time.h
new file mode 100644
index 000000000000..d9b86a17271b
--- /dev/null
+++ b/include/asm-powerpc/time.h
@@ -0,0 +1,226 @@
+/*
+ * Common time prototypes and such for all ppc machines.
+ *
+ * Written by Cort Dougan (cort@cs.nmt.edu) to merge
+ * Paul Mackerras' version and mine for PReP and Pmac.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef __POWERPC_TIME_H
+#define __POWERPC_TIME_H
+
+#ifdef __KERNEL__
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/percpu.h>
+
+#include <asm/processor.h>
+#ifdef CONFIG_PPC64
+#include <asm/paca.h>
+#include <asm/iseries/hv_call.h>
+#endif
+
+/* time.c */
+extern unsigned long tb_ticks_per_jiffy;
+extern unsigned long tb_ticks_per_usec;
+extern unsigned long tb_ticks_per_sec;
+extern u64 tb_to_xs;
+extern unsigned tb_to_us;
+extern unsigned long tb_last_stamp;
+extern u64 tb_last_jiffy;
+
+DECLARE_PER_CPU(unsigned long, last_jiffy);
+
+struct rtc_time;
+extern void to_tm(int tim, struct rtc_time * tm);
+extern time_t last_rtc_update;
+
+extern void generic_calibrate_decr(void);
+extern void wakeup_decrementer(void);
+
+/* Some sane defaults: 125 MHz timebase, 1GHz processor */
+extern unsigned long ppc_proc_freq;
+#define DEFAULT_PROC_FREQ (DEFAULT_TB_FREQ * 8)
+extern unsigned long ppc_tb_freq;
+#define DEFAULT_TB_FREQ 125000000UL
+
+/*
+ * By putting all of this stuff into a single struct we
+ * reduce the number of cache lines touched by do_gettimeofday.
+ * Both by collecting all of the data in one cache line and
+ * by touching only one TOC entry on ppc64.
+ */
+struct gettimeofday_vars {
+ u64 tb_to_xs;
+ u64 stamp_xsec;
+ u64 tb_orig_stamp;
+};
+
+struct gettimeofday_struct {
+ unsigned long tb_ticks_per_sec;
+ struct gettimeofday_vars vars[2];
+ struct gettimeofday_vars * volatile varp;
+ unsigned var_idx;
+ unsigned tb_to_us;
+};
+
+struct div_result {
+ u64 result_high;
+ u64 result_low;
+};
+
+/* Accessor functions for the timebase (RTC on 601) registers. */
+/* If one day CONFIG_POWER is added just define __USE_RTC as 1 */
+#ifdef CONFIG_6xx
+#define __USE_RTC() (!cpu_has_feature(CPU_FTR_USE_TB))
+#else
+#define __USE_RTC() 0
+#endif
+
+/* On ppc64 this gets us the whole timebase; on ppc32 just the lower half */
+static inline unsigned long get_tbl(void)
+{
+ unsigned long tbl;
+
+#if defined(CONFIG_403GCX)
+ asm volatile("mfspr %0, 0x3dd" : "=r" (tbl));
+#else
+ asm volatile("mftb %0" : "=r" (tbl));
+#endif
+ return tbl;
+}
+
+static inline unsigned int get_tbu(void)
+{
+ unsigned int tbu;
+
+#if defined(CONFIG_403GCX)
+ asm volatile("mfspr %0, 0x3dc" : "=r" (tbu));
+#else
+ asm volatile("mftbu %0" : "=r" (tbu));
+#endif
+ return tbu;
+}
+
+static inline unsigned int get_rtcl(void)
+{
+ unsigned int rtcl;
+
+ asm volatile("mfrtcl %0" : "=r" (rtcl));
+ return rtcl;
+}
+
+static inline u64 get_rtc(void)
+{
+ unsigned int hi, lo, hi2;
+
+ do {
+ asm volatile("mfrtcu %0; mfrtcl %1; mfrtcu %2"
+ : "=r" (hi), "=r" (lo), "=r" (hi2));
+ } while (hi2 != hi);
+ return (u64)hi * 1000000000 + lo;
+}
+
+#ifdef CONFIG_PPC64
+static inline u64 get_tb(void)
+{
+ return mftb();
+}
+#else
+static inline u64 get_tb(void)
+{
+ unsigned int tbhi, tblo, tbhi2;
+
+ do {
+ tbhi = get_tbu();
+ tblo = get_tbl();
+ tbhi2 = get_tbu();
+ } while (tbhi != tbhi2);
+
+ return ((u64)tbhi << 32) | tblo;
+}
+#endif
+
+static inline void set_tb(unsigned int upper, unsigned int lower)
+{
+ mtspr(SPRN_TBWL, 0);
+ mtspr(SPRN_TBWU, upper);
+ mtspr(SPRN_TBWL, lower);
+}
+
+/* Accessor functions for the decrementer register.
+ * The 4xx doesn't even have a decrementer. I tried to use the
+ * generic timer interrupt code, which seems OK, with the 4xx PIT
+ * in auto-reload mode. The problem is PIT stops counting when it
+ * hits zero. If it would wrap, we could use it just like a decrementer.
+ */
+static inline unsigned int get_dec(void)
+{
+#if defined(CONFIG_40x)
+ return (mfspr(SPRN_PIT));
+#else
+ return (mfspr(SPRN_DEC));
+#endif
+}
+
+static inline void set_dec(int val)
+{
+#if defined(CONFIG_40x)
+ return; /* Have to let it auto-reload */
+#elif defined(CONFIG_8xx_CPU6)
+ set_dec_cpu6(val);
+#else
+#ifdef CONFIG_PPC_ISERIES
+ struct paca_struct *lpaca = get_paca();
+ int cur_dec;
+
+ if (lpaca->lppaca.shared_proc) {
+ lpaca->lppaca.virtual_decr = val;
+ cur_dec = get_dec();
+ if (cur_dec > val)
+ HvCall_setVirtualDecr();
+ } else
+#endif
+ mtspr(SPRN_DEC, val);
+#endif /* not 40x or 8xx_CPU6 */
+}
+
+static inline unsigned long tb_ticks_since(unsigned long tstamp)
+{
+ if (__USE_RTC()) {
+ int delta = get_rtcl() - (unsigned int) tstamp;
+ return delta < 0 ? delta + 1000000000 : delta;
+ }
+ return get_tbl() - tstamp;
+}
+
+#define mulhwu(x,y) \
+({unsigned z; asm ("mulhwu %0,%1,%2" : "=r" (z) : "r" (x), "r" (y)); z;})
+
+#ifdef CONFIG_PPC64
+#define mulhdu(x,y) \
+({unsigned long z; asm ("mulhdu %0,%1,%2" : "=r" (z) : "r" (x), "r" (y)); z;})
+#else
+extern u64 mulhdu(u64, u64);
+#endif
+
+extern void smp_space_timers(unsigned int);
+
+extern unsigned mulhwu_scale_factor(unsigned, unsigned);
+extern void div128_by_32(u64 dividend_high, u64 dividend_low,
+ unsigned divisor, struct div_result *dr);
+
+/* Used to store Processor Utilization register (purr) values */
+
+struct cpu_usage {
+ u64 current_tb; /* Holds the current purr register values */
+};
+
+DECLARE_PER_CPU(struct cpu_usage, cpu_usage_array);
+
+#endif /* __KERNEL__ */
+#endif /* __PPC64_TIME_H */
diff --git a/include/asm-ppc/tlb.h b/include/asm-powerpc/tlb.h
index 2c142c5d8584..56659f121779 100644
--- a/include/asm-ppc/tlb.h
+++ b/include/asm-powerpc/tlb.h
@@ -1,6 +1,7 @@
/*
- * TLB shootdown specifics for PPC
+ * TLB shootdown specifics for powerpc
*
+ * Copyright (C) 2002 Anton Blanchard, IBM Corp.
* Copyright (C) 2002 Paul Mackerras, IBM Corp.
*
* This program is free software; you can redistribute it and/or
@@ -8,29 +9,53 @@
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
-#ifndef _PPC_TLB_H
-#define _PPC_TLB_H
+#ifndef _ASM_POWERPC_TLB_H
+#define _ASM_POWERPC_TLB_H
#include <linux/config.h>
+#ifndef __powerpc64__
#include <asm/pgtable.h>
+#endif
#include <asm/pgalloc.h>
#include <asm/tlbflush.h>
+#ifndef __powerpc64__
#include <asm/page.h>
#include <asm/mmu.h>
-
-#ifdef CONFIG_PPC_STD_MMU
-/* Classic PPC with hash-table based MMU... */
+#endif
struct mmu_gather;
+
+#define tlb_start_vma(tlb, vma) do { } while (0)
+#define tlb_end_vma(tlb, vma) do { } while (0)
+
+#if !defined(CONFIG_PPC_STD_MMU)
+
+#define tlb_flush(tlb) flush_tlb_mm((tlb)->mm)
+
+#elif defined(__powerpc64__)
+
+extern void pte_free_finish(void);
+
+static inline void tlb_flush(struct mmu_gather *tlb)
+{
+ flush_tlb_pending();
+ pte_free_finish();
+}
+
+#else
+
extern void tlb_flush(struct mmu_gather *tlb);
+#endif
+
/* Get the generic bits... */
#include <asm-generic/tlb.h>
-/* Nothing needed here in fact... */
-#define tlb_start_vma(tlb, vma) do { } while (0)
-#define tlb_end_vma(tlb, vma) do { } while (0)
+#if !defined(CONFIG_PPC_STD_MMU) || defined(__powerpc64__)
+
+#define __tlb_remove_tlb_entry(tlb, pte, address) do { } while (0)
+#else
extern void flush_hash_entry(struct mm_struct *mm, pte_t *ptep,
unsigned long address);
@@ -41,17 +66,5 @@ static inline void __tlb_remove_tlb_entry(struct mmu_gather *tlb, pte_t *ptep,
flush_hash_entry(tlb->mm, ptep, address);
}
-#else
-/* Embedded PPC with software-loaded TLB, very simple... */
-
-#define tlb_start_vma(tlb, vma) do { } while (0)
-#define tlb_end_vma(tlb, vma) do { } while (0)
-#define __tlb_remove_tlb_entry(tlb, pte, address) do { } while (0)
-#define tlb_flush(tlb) flush_tlb_mm((tlb)->mm)
-
-/* Get the generic bits... */
-#include <asm-generic/tlb.h>
-
-#endif /* CONFIG_PPC_STD_MMU */
-
-#endif /* __PPC_TLB_H */
+#endif
+#endif /* __ASM_POWERPC_TLB_H */
diff --git a/include/asm-powerpc/tlbflush.h b/include/asm-powerpc/tlbflush.h
new file mode 100644
index 000000000000..a2998eee37bb
--- /dev/null
+++ b/include/asm-powerpc/tlbflush.h
@@ -0,0 +1,147 @@
+#ifndef _ASM_POWERPC_TLBFLUSH_H
+#define _ASM_POWERPC_TLBFLUSH_H
+/*
+ * TLB flushing:
+ *
+ * - flush_tlb_mm(mm) flushes the specified mm context TLB's
+ * - flush_tlb_page(vma, vmaddr) flushes one page
+ * - flush_tlb_page_nohash(vma, vmaddr) flushes one page if SW loaded TLB
+ * - flush_tlb_range(vma, start, end) flushes a range of pages
+ * - flush_tlb_kernel_range(start, end) flushes a range of kernel pages
+ * - flush_tlb_pgtables(mm, start, end) flushes a range of page tables
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#ifdef __KERNEL__
+
+#include <linux/config.h>
+
+struct mm_struct;
+
+#ifdef CONFIG_PPC64
+
+#include <linux/percpu.h>
+#include <asm/page.h>
+
+#define PPC64_TLB_BATCH_NR 192
+
+struct ppc64_tlb_batch {
+ unsigned long index;
+ struct mm_struct *mm;
+ real_pte_t pte[PPC64_TLB_BATCH_NR];
+ unsigned long vaddr[PPC64_TLB_BATCH_NR];
+ unsigned int psize;
+};
+DECLARE_PER_CPU(struct ppc64_tlb_batch, ppc64_tlb_batch);
+
+extern void __flush_tlb_pending(struct ppc64_tlb_batch *batch);
+
+static inline void flush_tlb_pending(void)
+{
+ struct ppc64_tlb_batch *batch = &get_cpu_var(ppc64_tlb_batch);
+
+ if (batch->index)
+ __flush_tlb_pending(batch);
+ put_cpu_var(ppc64_tlb_batch);
+}
+
+extern void flush_hash_page(unsigned long va, real_pte_t pte, int psize,
+ int local);
+extern void flush_hash_range(unsigned long number, int local);
+
+#else /* CONFIG_PPC64 */
+
+#include <linux/mm.h>
+
+extern void _tlbie(unsigned long address);
+extern void _tlbia(void);
+
+/*
+ * TODO: (CONFIG_FSL_BOOKE) determine if flush_tlb_range &
+ * flush_tlb_kernel_range are best implemented as tlbia vs
+ * specific tlbie's
+ */
+
+#if (defined(CONFIG_4xx) && !defined(CONFIG_44x)) || defined(CONFIG_8xx)
+#define flush_tlb_pending() asm volatile ("tlbia; sync" : : : "memory")
+#elif defined(CONFIG_4xx) || defined(CONFIG_FSL_BOOKE)
+#define flush_tlb_pending() _tlbia()
+#endif
+
+/*
+ * This gets called at the end of handling a page fault, when
+ * the kernel has put a new PTE into the page table for the process.
+ * We use it to ensure coherency between the i-cache and d-cache
+ * for the page which has just been mapped in.
+ * On machines which use an MMU hash table, we use this to put a
+ * corresponding HPTE into the hash table ahead of time, instead of
+ * waiting for the inevitable extra hash-table miss exception.
+ */
+extern void update_mmu_cache(struct vm_area_struct *, unsigned long, pte_t);
+
+#endif /* CONFIG_PPC64 */
+
+#if defined(CONFIG_PPC64) || defined(CONFIG_4xx) || \
+ defined(CONFIG_FSL_BOOKE) || defined(CONFIG_8xx)
+
+static inline void flush_tlb_mm(struct mm_struct *mm)
+{
+ flush_tlb_pending();
+}
+
+static inline void flush_tlb_page(struct vm_area_struct *vma,
+ unsigned long vmaddr)
+{
+#ifdef CONFIG_PPC64
+ flush_tlb_pending();
+#else
+ _tlbie(vmaddr);
+#endif
+}
+
+static inline void flush_tlb_page_nohash(struct vm_area_struct *vma,
+ unsigned long vmaddr)
+{
+#ifndef CONFIG_PPC64
+ _tlbie(vmaddr);
+#endif
+}
+
+static inline void flush_tlb_range(struct vm_area_struct *vma,
+ unsigned long start, unsigned long end)
+{
+ flush_tlb_pending();
+}
+
+static inline void flush_tlb_kernel_range(unsigned long start,
+ unsigned long end)
+{
+ flush_tlb_pending();
+}
+
+#else /* 6xx, 7xx, 7xxx cpus */
+
+extern void flush_tlb_mm(struct mm_struct *mm);
+extern void flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr);
+extern void flush_tlb_page_nohash(struct vm_area_struct *vma, unsigned long addr);
+extern void flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
+ unsigned long end);
+extern void flush_tlb_kernel_range(unsigned long start, unsigned long end);
+
+#endif
+
+/*
+ * This is called in munmap when we have freed up some page-table
+ * pages. We don't need to do anything here, there's nothing special
+ * about our page-table pages. -- paulus
+ */
+static inline void flush_tlb_pgtables(struct mm_struct *mm,
+ unsigned long start, unsigned long end)
+{
+}
+
+#endif /*__KERNEL__ */
+#endif /* _ASM_POWERPC_TLBFLUSH_H */
diff --git a/include/asm-ppc64/types.h b/include/asm-powerpc/types.h
index bf294c1761b2..ec3c2ee8bf86 100644
--- a/include/asm-ppc64/types.h
+++ b/include/asm-powerpc/types.h
@@ -1,5 +1,5 @@
-#ifndef _PPC64_TYPES_H
-#define _PPC64_TYPES_H
+#ifndef _ASM_POWERPC_TYPES_H
+#define _ASM_POWERPC_TYPES_H
#ifndef __ASSEMBLY__
@@ -16,7 +16,11 @@
* 2 of the License, or (at your option) any later version.
*/
+#ifdef __powerpc64__
typedef unsigned int umode_t;
+#else
+typedef unsigned short umode_t;
+#endif
/*
* __xx is ok: it doesn't pollute the POSIX namespace. Use these in the
@@ -32,8 +36,15 @@ typedef unsigned short __u16;
typedef __signed__ int __s32;
typedef unsigned int __u32;
+#ifdef __powerpc64__
typedef __signed__ long __s64;
typedef unsigned long __u64;
+#else
+#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
+typedef __signed__ long long __s64;
+typedef unsigned long long __u64;
+#endif
+#endif /* __powerpc64__ */
typedef struct {
__u32 u[4];
@@ -45,10 +56,16 @@ typedef struct {
/*
* These aren't exported outside the kernel to avoid name space clashes
*/
+#ifdef __powerpc64__
#define BITS_PER_LONG 64
+#else
+#define BITS_PER_LONG 32
+#endif
#ifndef __ASSEMBLY__
+#include <linux/config.h>
+
typedef signed char s8;
typedef unsigned char u8;
@@ -58,12 +75,21 @@ typedef unsigned short u16;
typedef signed int s32;
typedef unsigned int u32;
+#ifdef __powerpc64__
typedef signed long s64;
typedef unsigned long u64;
+#else
+typedef signed long long s64;
+typedef unsigned long long u64;
+#endif
typedef __vector128 vector128;
+#ifdef __powerpc64__
+typedef u64 dma_addr_t;
+#else
typedef u32 dma_addr_t;
+#endif
typedef u64 dma64_addr_t;
typedef struct {
@@ -72,8 +98,13 @@ typedef struct {
unsigned long env;
} func_descr_t;
+#ifdef CONFIG_LBD
+typedef u64 sector_t;
+#define HAVE_SECTOR_T
+#endif
+
#endif /* __ASSEMBLY__ */
#endif /* __KERNEL__ */
-#endif /* _PPC64_TYPES_H */
+#endif /* _ASM_POWERPC_TYPES_H */
diff --git a/include/asm-powerpc/uaccess.h b/include/asm-powerpc/uaccess.h
new file mode 100644
index 000000000000..3872e924cdd6
--- /dev/null
+++ b/include/asm-powerpc/uaccess.h
@@ -0,0 +1,464 @@
+#ifndef _ARCH_POWERPC_UACCESS_H
+#define _ARCH_POWERPC_UACCESS_H
+
+#ifdef __KERNEL__
+#ifndef __ASSEMBLY__
+
+#include <linux/sched.h>
+#include <linux/errno.h>
+#include <asm/processor.h>
+
+#define VERIFY_READ 0
+#define VERIFY_WRITE 1
+
+/*
+ * The fs value determines whether argument validity checking should be
+ * performed or not. If get_fs() == USER_DS, checking is performed, with
+ * get_fs() == KERNEL_DS, checking is bypassed.
+ *
+ * For historical reasons, these macros are grossly misnamed.
+ *
+ * The fs/ds values are now the highest legal address in the "segment".
+ * This simplifies the checking in the routines below.
+ */
+
+#define MAKE_MM_SEG(s) ((mm_segment_t) { (s) })
+
+#define KERNEL_DS MAKE_MM_SEG(~0UL)
+#ifdef __powerpc64__
+/* We use TASK_SIZE_USER64 as TASK_SIZE is not constant */
+#define USER_DS MAKE_MM_SEG(TASK_SIZE_USER64 - 1)
+#else
+#define USER_DS MAKE_MM_SEG(TASK_SIZE - 1)
+#endif
+
+#define get_ds() (KERNEL_DS)
+#define get_fs() (current->thread.fs)
+#define set_fs(val) (current->thread.fs = (val))
+
+#define segment_eq(a, b) ((a).seg == (b).seg)
+
+#ifdef __powerpc64__
+/*
+ * This check is sufficient because there is a large enough
+ * gap between user addresses and the kernel addresses
+ */
+#define __access_ok(addr, size, segment) \
+ (((addr) <= (segment).seg) && ((size) <= (segment).seg))
+
+#else
+
+#define __access_ok(addr, size, segment) \
+ (((addr) <= (segment).seg) && \
+ (((size) == 0) || (((size) - 1) <= ((segment).seg - (addr)))))
+
+#endif
+
+#define access_ok(type, addr, size) \
+ (__chk_user_ptr(addr), \
+ __access_ok((__force unsigned long)(addr), (size), get_fs()))
+
+/*
+ * The exception table consists of pairs of addresses: the first is the
+ * address of an instruction that is allowed to fault, and the second is
+ * the address at which the program should continue. No registers are
+ * modified, so it is entirely up to the continuation code to figure out
+ * what to do.
+ *
+ * All the routines below use bits of fixup code that are out of line
+ * with the main instruction path. This means when everything is well,
+ * we don't even have to jump over them. Further, they do not intrude
+ * on our cache or tlb entries.
+ */
+
+struct exception_table_entry {
+ unsigned long insn;
+ unsigned long fixup;
+};
+
+/*
+ * These are the main single-value transfer routines. They automatically
+ * use the right size if we just have the right pointer type.
+ *
+ * This gets kind of ugly. We want to return _two_ values in "get_user()"
+ * and yet we don't want to do any pointers, because that is too much
+ * of a performance impact. Thus we have a few rather ugly macros here,
+ * and hide all the ugliness from the user.
+ *
+ * The "__xxx" versions of the user access functions are versions that
+ * do not verify the address space, that must have been done previously
+ * with a separate "access_ok()" call (this is used when we do multiple
+ * accesses to the same area of user memory).
+ *
+ * As we use the same address space for kernel and user data on the
+ * PowerPC, we can just do these as direct assignments. (Of course, the
+ * exception handling means that it's no longer "just"...)
+ *
+ * The "user64" versions of the user access functions are versions that
+ * allow access of 64-bit data. The "get_user" functions do not
+ * properly handle 64-bit data because the value gets down cast to a long.
+ * The "put_user" functions already handle 64-bit data properly but we add
+ * "user64" versions for completeness
+ */
+#define get_user(x, ptr) \
+ __get_user_check((x), (ptr), sizeof(*(ptr)))
+#define put_user(x, ptr) \
+ __put_user_check((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)))
+
+#define __get_user(x, ptr) \
+ __get_user_nocheck((x), (ptr), sizeof(*(ptr)))
+#define __put_user(x, ptr) \
+ __put_user_nocheck((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)))
+#ifndef __powerpc64__
+#define __get_user64(x, ptr) \
+ __get_user64_nocheck((x), (ptr), sizeof(*(ptr)))
+#define __put_user64(x, ptr) __put_user(x, ptr)
+#endif
+
+#define __get_user_unaligned __get_user
+#define __put_user_unaligned __put_user
+
+extern long __put_user_bad(void);
+
+/*
+ * We don't tell gcc that we are accessing memory, but this is OK
+ * because we do not write to any memory gcc knows about, so there
+ * are no aliasing issues.
+ */
+#define __put_user_asm(x, addr, err, op) \
+ __asm__ __volatile__( \
+ "1: " op " %1,0(%2) # put_user\n" \
+ "2:\n" \
+ ".section .fixup,\"ax\"\n" \
+ "3: li %0,%3\n" \
+ " b 2b\n" \
+ ".previous\n" \
+ ".section __ex_table,\"a\"\n" \
+ " .balign %5\n" \
+ PPC_LONG "1b,3b\n" \
+ ".previous" \
+ : "=r" (err) \
+ : "r" (x), "b" (addr), "i" (-EFAULT), "0" (err),\
+ "i"(sizeof(unsigned long)))
+
+#ifdef __powerpc64__
+#define __put_user_asm2(x, ptr, retval) \
+ __put_user_asm(x, ptr, retval, "std")
+#else /* __powerpc64__ */
+#define __put_user_asm2(x, addr, err) \
+ __asm__ __volatile__( \
+ "1: stw %1,0(%2)\n" \
+ "2: stw %1+1,4(%2)\n" \
+ "3:\n" \
+ ".section .fixup,\"ax\"\n" \
+ "4: li %0,%3\n" \
+ " b 3b\n" \
+ ".previous\n" \
+ ".section __ex_table,\"a\"\n" \
+ " .balign %5\n" \
+ PPC_LONG "1b,4b\n" \
+ PPC_LONG "2b,4b\n" \
+ ".previous" \
+ : "=r" (err) \
+ : "r" (x), "b" (addr), "i" (-EFAULT), "0" (err),\
+ "i"(sizeof(unsigned long)))
+#endif /* __powerpc64__ */
+
+#define __put_user_size(x, ptr, size, retval) \
+do { \
+ retval = 0; \
+ switch (size) { \
+ case 1: __put_user_asm(x, ptr, retval, "stb"); break; \
+ case 2: __put_user_asm(x, ptr, retval, "sth"); break; \
+ case 4: __put_user_asm(x, ptr, retval, "stw"); break; \
+ case 8: __put_user_asm2(x, ptr, retval); break; \
+ default: __put_user_bad(); \
+ } \
+} while (0)
+
+#define __put_user_nocheck(x, ptr, size) \
+({ \
+ long __pu_err; \
+ might_sleep(); \
+ __chk_user_ptr(ptr); \
+ __put_user_size((x), (ptr), (size), __pu_err); \
+ __pu_err; \
+})
+
+#define __put_user_check(x, ptr, size) \
+({ \
+ long __pu_err = -EFAULT; \
+ __typeof__(*(ptr)) __user *__pu_addr = (ptr); \
+ might_sleep(); \
+ if (access_ok(VERIFY_WRITE, __pu_addr, size)) \
+ __put_user_size((x), __pu_addr, (size), __pu_err); \
+ __pu_err; \
+})
+
+extern long __get_user_bad(void);
+
+#define __get_user_asm(x, addr, err, op) \
+ __asm__ __volatile__( \
+ "1: "op" %1,0(%2) # get_user\n" \
+ "2:\n" \
+ ".section .fixup,\"ax\"\n" \
+ "3: li %0,%3\n" \
+ " li %1,0\n" \
+ " b 2b\n" \
+ ".previous\n" \
+ ".section __ex_table,\"a\"\n" \
+ " .balign %5\n" \
+ PPC_LONG "1b,3b\n" \
+ ".previous" \
+ : "=r" (err), "=r" (x) \
+ : "b" (addr), "i" (-EFAULT), "0" (err), \
+ "i"(sizeof(unsigned long)))
+
+#ifdef __powerpc64__
+#define __get_user_asm2(x, addr, err) \
+ __get_user_asm(x, addr, err, "ld")
+#else /* __powerpc64__ */
+#define __get_user_asm2(x, addr, err) \
+ __asm__ __volatile__( \
+ "1: lwz %1,0(%2)\n" \
+ "2: lwz %1+1,4(%2)\n" \
+ "3:\n" \
+ ".section .fixup,\"ax\"\n" \
+ "4: li %0,%3\n" \
+ " li %1,0\n" \
+ " li %1+1,0\n" \
+ " b 3b\n" \
+ ".previous\n" \
+ ".section __ex_table,\"a\"\n" \
+ " .balign %5\n" \
+ PPC_LONG "1b,4b\n" \
+ PPC_LONG "2b,4b\n" \
+ ".previous" \
+ : "=r" (err), "=&r" (x) \
+ : "b" (addr), "i" (-EFAULT), "0" (err), \
+ "i"(sizeof(unsigned long)))
+#endif /* __powerpc64__ */
+
+#define __get_user_size(x, ptr, size, retval) \
+do { \
+ retval = 0; \
+ __chk_user_ptr(ptr); \
+ if (size > sizeof(x)) \
+ (x) = __get_user_bad(); \
+ switch (size) { \
+ case 1: __get_user_asm(x, ptr, retval, "lbz"); break; \
+ case 2: __get_user_asm(x, ptr, retval, "lhz"); break; \
+ case 4: __get_user_asm(x, ptr, retval, "lwz"); break; \
+ case 8: __get_user_asm2(x, ptr, retval); break; \
+ default: (x) = __get_user_bad(); \
+ } \
+} while (0)
+
+#define __get_user_nocheck(x, ptr, size) \
+({ \
+ long __gu_err; \
+ unsigned long __gu_val; \
+ __chk_user_ptr(ptr); \
+ might_sleep(); \
+ __get_user_size(__gu_val, (ptr), (size), __gu_err); \
+ (x) = (__typeof__(*(ptr)))__gu_val; \
+ __gu_err; \
+})
+
+#ifndef __powerpc64__
+#define __get_user64_nocheck(x, ptr, size) \
+({ \
+ long __gu_err; \
+ long long __gu_val; \
+ __chk_user_ptr(ptr); \
+ might_sleep(); \
+ __get_user_size(__gu_val, (ptr), (size), __gu_err); \
+ (x) = (__typeof__(*(ptr)))__gu_val; \
+ __gu_err; \
+})
+#endif /* __powerpc64__ */
+
+#define __get_user_check(x, ptr, size) \
+({ \
+ long __gu_err = -EFAULT; \
+ unsigned long __gu_val = 0; \
+ const __typeof__(*(ptr)) __user *__gu_addr = (ptr); \
+ might_sleep(); \
+ if (access_ok(VERIFY_READ, __gu_addr, (size))) \
+ __get_user_size(__gu_val, __gu_addr, (size), __gu_err); \
+ (x) = (__typeof__(*(ptr)))__gu_val; \
+ __gu_err; \
+})
+
+/* more complex routines */
+
+extern unsigned long __copy_tofrom_user(void __user *to,
+ const void __user *from, unsigned long size);
+
+#ifndef __powerpc64__
+
+extern inline unsigned long copy_from_user(void *to,
+ const void __user *from, unsigned long n)
+{
+ unsigned long over;
+
+ if (access_ok(VERIFY_READ, from, n))
+ return __copy_tofrom_user((__force void __user *)to, from, n);
+ if ((unsigned long)from < TASK_SIZE) {
+ over = (unsigned long)from + n - TASK_SIZE;
+ return __copy_tofrom_user((__force void __user *)to, from,
+ n - over) + over;
+ }
+ return n;
+}
+
+extern inline unsigned long copy_to_user(void __user *to,
+ const void *from, unsigned long n)
+{
+ unsigned long over;
+
+ if (access_ok(VERIFY_WRITE, to, n))
+ return __copy_tofrom_user(to, (__force void __user *)from, n);
+ if ((unsigned long)to < TASK_SIZE) {
+ over = (unsigned long)to + n - TASK_SIZE;
+ return __copy_tofrom_user(to, (__force void __user *)from,
+ n - over) + over;
+ }
+ return n;
+}
+
+#else /* __powerpc64__ */
+
+#define __copy_in_user(to, from, size) \
+ __copy_tofrom_user((to), (from), (size))
+
+extern unsigned long copy_from_user(void *to, const void __user *from,
+ unsigned long n);
+extern unsigned long copy_to_user(void __user *to, const void *from,
+ unsigned long n);
+extern unsigned long copy_in_user(void __user *to, const void __user *from,
+ unsigned long n);
+
+#endif /* __powerpc64__ */
+
+static inline unsigned long __copy_from_user_inatomic(void *to,
+ const void __user *from, unsigned long n)
+{
+ if (__builtin_constant_p(n) && (n <= 8)) {
+ unsigned long ret;
+
+ switch (n) {
+ case 1:
+ __get_user_size(*(u8 *)to, from, 1, ret);
+ break;
+ case 2:
+ __get_user_size(*(u16 *)to, from, 2, ret);
+ break;
+ case 4:
+ __get_user_size(*(u32 *)to, from, 4, ret);
+ break;
+ case 8:
+ __get_user_size(*(u64 *)to, from, 8, ret);
+ break;
+ }
+ if (ret == 0)
+ return 0;
+ }
+ return __copy_tofrom_user((__force void __user *)to, from, n);
+}
+
+static inline unsigned long __copy_to_user_inatomic(void __user *to,
+ const void *from, unsigned long n)
+{
+ if (__builtin_constant_p(n) && (n <= 8)) {
+ unsigned long ret;
+
+ switch (n) {
+ case 1:
+ __put_user_size(*(u8 *)from, (u8 __user *)to, 1, ret);
+ break;
+ case 2:
+ __put_user_size(*(u16 *)from, (u16 __user *)to, 2, ret);
+ break;
+ case 4:
+ __put_user_size(*(u32 *)from, (u32 __user *)to, 4, ret);
+ break;
+ case 8:
+ __put_user_size(*(u64 *)from, (u64 __user *)to, 8, ret);
+ break;
+ }
+ if (ret == 0)
+ return 0;
+ }
+ return __copy_tofrom_user(to, (__force const void __user *)from, n);
+}
+
+static inline unsigned long __copy_from_user(void *to,
+ const void __user *from, unsigned long size)
+{
+ might_sleep();
+ return __copy_from_user_inatomic(to, from, size);
+}
+
+static inline unsigned long __copy_to_user(void __user *to,
+ const void *from, unsigned long size)
+{
+ might_sleep();
+ return __copy_to_user_inatomic(to, from, size);
+}
+
+extern unsigned long __clear_user(void __user *addr, unsigned long size);
+
+static inline unsigned long clear_user(void __user *addr, unsigned long size)
+{
+ might_sleep();
+ if (likely(access_ok(VERIFY_WRITE, addr, size)))
+ return __clear_user(addr, size);
+ if ((unsigned long)addr < TASK_SIZE) {
+ unsigned long over = (unsigned long)addr + size - TASK_SIZE;
+ return __clear_user(addr, size - over) + over;
+ }
+ return size;
+}
+
+extern int __strncpy_from_user(char *dst, const char __user *src, long count);
+
+static inline long strncpy_from_user(char *dst, const char __user *src,
+ long count)
+{
+ might_sleep();
+ if (likely(access_ok(VERIFY_READ, src, 1)))
+ return __strncpy_from_user(dst, src, count);
+ return -EFAULT;
+}
+
+/*
+ * Return the size of a string (including the ending 0)
+ *
+ * Return 0 for error
+ */
+extern int __strnlen_user(const char __user *str, long len, unsigned long top);
+
+/*
+ * Returns the length of the string at str (including the null byte),
+ * or 0 if we hit a page we can't access,
+ * or something > len if we didn't find a null byte.
+ *
+ * The `top' parameter to __strnlen_user is to make sure that
+ * we can never overflow from the user area into kernel space.
+ */
+static inline int strnlen_user(const char __user *str, long len)
+{
+ unsigned long top = current->thread.fs.seg;
+
+ if ((unsigned long)str > top)
+ return 0;
+ return __strnlen_user(str, len, top);
+}
+
+#define strlen_user(str) strnlen_user((str), 0x7ffffffe)
+
+#endif /* __ASSEMBLY__ */
+#endif /* __KERNEL__ */
+
+#endif /* _ARCH_POWERPC_UACCESS_H */
diff --git a/include/asm-powerpc/ucontext.h b/include/asm-powerpc/ucontext.h
new file mode 100644
index 000000000000..d9a4ddf0cc86
--- /dev/null
+++ b/include/asm-powerpc/ucontext.h
@@ -0,0 +1,40 @@
+#ifndef _ASM_POWERPC_UCONTEXT_H
+#define _ASM_POWERPC_UCONTEXT_H
+
+#ifdef __powerpc64__
+#include <asm/sigcontext.h>
+#else
+#include <asm/elf.h>
+#endif
+#include <asm/signal.h>
+
+#ifndef __powerpc64__
+struct mcontext {
+ elf_gregset_t mc_gregs;
+ elf_fpregset_t mc_fregs;
+ unsigned long mc_pad[2];
+ elf_vrregset_t mc_vregs __attribute__((__aligned__(16)));
+};
+#endif
+
+struct ucontext {
+ unsigned long uc_flags;
+ struct ucontext __user *uc_link;
+ stack_t uc_stack;
+#ifndef __powerpc64__
+ int uc_pad[7];
+ struct mcontext __user *uc_regs;/* points to uc_mcontext field */
+#endif
+ sigset_t uc_sigmask;
+ /* glibc has 1024-bit signal masks, ours are 64-bit */
+#ifdef __powerpc64__
+ sigset_t __unused[15]; /* Allow for uc_sigmask growth */
+ struct sigcontext uc_mcontext; /* last for extensibility */
+#else
+ int uc_maskext[30];
+ int uc_pad2[3];
+ struct mcontext uc_mcontext;
+#endif
+};
+
+#endif /* _ASM_POWERPC_UCONTEXT_H */
diff --git a/include/asm-ppc/uninorth.h b/include/asm-powerpc/uninorth.h
index f737732c3861..f737732c3861 100644
--- a/include/asm-ppc/uninorth.h
+++ b/include/asm-powerpc/uninorth.h
diff --git a/include/asm-ppc/unistd.h b/include/asm-powerpc/unistd.h
index 3173ab3d2eb9..0991dfceef1d 100644
--- a/include/asm-ppc/unistd.h
+++ b/include/asm-powerpc/unistd.h
@@ -3,7 +3,13 @@
/*
* This file contains the system call numbers.
+ *
+ * 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.
*/
+
#define __NR_restart_syscall 0
#define __NR_exit 1
#define __NR_fork 2
@@ -196,19 +202,23 @@
#define __NR_vfork 189
#define __NR_ugetrlimit 190 /* SuS compliant getrlimit */
#define __NR_readahead 191
+#ifndef __powerpc64__ /* these are 32-bit only */
#define __NR_mmap2 192
#define __NR_truncate64 193
#define __NR_ftruncate64 194
#define __NR_stat64 195
#define __NR_lstat64 196
#define __NR_fstat64 197
+#endif
#define __NR_pciconfig_read 198
#define __NR_pciconfig_write 199
#define __NR_pciconfig_iobase 200
#define __NR_multiplexer 201
#define __NR_getdents64 202
#define __NR_pivot_root 203
+#ifndef __powerpc64__
#define __NR_fcntl64 204
+#endif
#define __NR_madvise 205
#define __NR_mincore 206
#define __NR_gettid 207
@@ -230,7 +240,9 @@
#define __NR_sched_getaffinity 223
/* 224 currently unused */
#define __NR_tuxcall 225
+#ifndef __powerpc64__
#define __NR_sendfile64 226
+#endif
#define __NR_io_setup 227
#define __NR_io_destroy 228
#define __NR_io_getevents 229
@@ -258,14 +270,16 @@
#define __NR_utimes 251
#define __NR_statfs64 252
#define __NR_fstatfs64 253
+#ifndef __powerpc64__
#define __NR_fadvise64_64 254
+#endif
#define __NR_rtas 255
#define __NR_sys_debug_setcontext 256
/* Number 257 is reserved for vserver */
/* 258 currently unused */
-/* Number 259 is reserved for new sys_mbind */
-/* Number 260 is reserved for new sys_get_mempolicy */
-/* Number 261 is reserved for new sys_set_mempolicy */
+#define __NR_mbind 259
+#define __NR_get_mempolicy 260
+#define __NR_set_mempolicy 261
#define __NR_mq_open 262
#define __NR_mq_unlink 263
#define __NR_mq_timedsend 264
@@ -285,7 +299,12 @@
#define __NR_syscalls 278
-#define __NR(n) #n
+#ifdef __KERNEL__
+#define __NR__exit __NR_exit
+#define NR_syscalls __NR_syscalls
+#endif
+
+#ifndef __ASSEMBLY__
/* On powerpc a system call basically clobbers the same registers like a
* function call, with the exception of LR (which is needed for the
@@ -389,7 +408,6 @@ type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5) \
{ \
__syscall_nr(5, type, name, arg1, arg2, arg3, arg4, arg5); \
}
-
#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5,type6,arg6) \
type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6) \
{ \
@@ -398,12 +416,13 @@ type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6
#ifdef __KERNEL__
-#define __NR__exit __NR_exit
-#define NR_syscalls __NR_syscalls
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/compiler.h>
+#include <linux/linkage.h>
#define __ARCH_WANT_IPC_PARSE_VERSION
#define __ARCH_WANT_OLD_READDIR
-#define __ARCH_WANT_OLD_STAT
#define __ARCH_WANT_STAT64
#define __ARCH_WANT_SYS_ALARM
#define __ARCH_WANT_SYS_GETHOSTNAME
@@ -423,23 +442,17 @@ type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6
#define __ARCH_WANT_SYS_SIGPENDING
#define __ARCH_WANT_SYS_SIGPROCMASK
#define __ARCH_WANT_SYS_RT_SIGACTION
-
-/*
- * Forking from kernel space will result in the child getting a new,
- * empty kernel stack area. Thus the child cannot access automatic
- * variables set in the parent unless they are in registers, and the
- * procedure where the fork was done cannot return to its caller in
- * the child.
- */
-
-#ifdef __KERNEL_SYSCALLS__
-
-#include <linux/compiler.h>
-#include <linux/types.h>
+#ifdef CONFIG_PPC32
+#define __ARCH_WANT_OLD_STAT
+#endif
+#ifdef CONFIG_PPC64
+#define __ARCH_WANT_COMPAT_SYS_TIME
+#endif
/*
* System call prototypes.
*/
+#ifdef __KERNEL_SYSCALLS__
extern pid_t setsid(void);
extern int write(int fd, const char *buf, off_t count);
extern int read(int fd, char *buf, off_t count);
@@ -449,10 +462,13 @@ extern int execve(const char *file, char **argv, char **envp);
extern int open(const char *file, int flag, int mode);
extern int close(int fd);
extern pid_t waitpid(pid_t pid, int *wait_stat, int options);
+#endif /* __KERNEL_SYSCALLS__ */
-unsigned long sys_mmap(unsigned long addr, size_t len,
- unsigned long prot, unsigned long flags,
- unsigned long fd, off_t offset);
+/*
+ * Functions that implement syscalls.
+ */
+unsigned long sys_mmap(unsigned long addr, size_t len, unsigned long prot,
+ unsigned long flags, unsigned long fd, off_t offset);
unsigned long sys_mmap2(unsigned long addr, size_t len,
unsigned long prot, unsigned long flags,
unsigned long fd, unsigned long pgoff);
@@ -461,22 +477,18 @@ int sys_execve(unsigned long a0, unsigned long a1, unsigned long a2,
unsigned long a3, unsigned long a4, unsigned long a5,
struct pt_regs *regs);
int sys_clone(unsigned long clone_flags, unsigned long usp,
- int __user *parent_tidp, void __user *child_threadptr,
- int __user *child_tidp, int p6,
- struct pt_regs *regs);
-int sys_fork(int p1, int p2, int p3, int p4, int p5, int p6,
+ int __user *parent_tidp, void __user *child_threadptr,
+ int __user *child_tidp, int p6, struct pt_regs *regs);
+int sys_fork(unsigned long p1, unsigned long p2, unsigned long p3,
+ unsigned long p4, unsigned long p5, unsigned long p6,
struct pt_regs *regs);
-int sys_vfork(int p1, int p2, int p3, int p4, int p5, int p6,
+int sys_vfork(unsigned long p1, unsigned long p2, unsigned long p3,
+ unsigned long p4, unsigned long p5, unsigned long p6,
struct pt_regs *regs);
int sys_pipe(int __user *fildes);
-int sys_ptrace(long request, long pid, long addr, long data);
struct sigaction;
-long sys_rt_sigaction(int sig,
- const struct sigaction __user *act,
- struct sigaction __user *oact,
- size_t sigsetsize);
-
-#endif /* __KERNEL_SYSCALLS__ */
+long sys_rt_sigaction(int sig, const struct sigaction __user *act,
+ struct sigaction __user *oact, size_t sigsetsize);
/*
* "Conditional" syscalls
@@ -484,10 +496,14 @@ long sys_rt_sigaction(int sig,
* What we want is __attribute__((weak,alias("sys_ni_syscall"))),
* but it doesn't work on all toolchains, so we just do it by hand
*/
-#ifndef cond_syscall
+#ifdef CONFIG_PPC32
#define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall")
+#else
+#define cond_syscall(x) asm(".weak\t." #x "\n\t.set\t." #x ",.sys_ni_syscall")
#endif
-#endif /* __KERNEL__ */
+#endif /* __KERNEL__ */
+
+#endif /* __ASSEMBLY__ */
#endif /* _ASM_PPC_UNISTD_H_ */
diff --git a/include/asm-ppc64/vga.h b/include/asm-powerpc/vga.h
index c09849743f45..f8d350aabf1a 100644
--- a/include/asm-ppc64/vga.h
+++ b/include/asm-powerpc/vga.h
@@ -1,16 +1,14 @@
+#ifndef _ASM_POWERPC_VGA_H_
+#define _ASM_POWERPC_VGA_H_
+
+#ifdef __KERNEL__
+
/*
* Access to VGA videoram
*
* (c) 1998 Martin Mares <mj@ucw.cz>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
*/
-#ifndef _LINUX_ASM_VGA_H_
-#define _LINUX_ASM_VGA_H_
#include <asm/io.h>
@@ -42,9 +40,15 @@ static inline u16 scr_readw(volatile const u16 *addr)
#endif /* !CONFIG_VGA_CONSOLE && !CONFIG_MDA_CONSOLE */
extern unsigned long vgacon_remap_base;
+
+#ifdef __powerpc64__
#define VGA_MAP_MEM(x) ((unsigned long) ioremap((x), 0))
+#else
+#define VGA_MAP_MEM(x) (x + vgacon_remap_base)
+#endif
#define vga_readb(x) (*(x))
#define vga_writeb(x,y) (*(y) = (x))
-#endif
+#endif /* __KERNEL__ */
+#endif /* _ASM_POWERPC_VGA_H_ */
diff --git a/include/asm-ppc64/vio.h b/include/asm-powerpc/vio.h
index 03f1b95f433b..e0ccf108277c 100644
--- a/include/asm-ppc64/vio.h
+++ b/include/asm-powerpc/vio.h
@@ -1,18 +1,18 @@
/*
* IBM PowerPC Virtual I/O Infrastructure Support.
*
- * Copyright (c) 2003 IBM Corp.
- * Dave Engebretsen engebret@us.ibm.com
- * Santiago Leon santil@us.ibm.com
+ * Copyright (c) 2003 IBM Corp.
+ * Dave Engebretsen engebret@us.ibm.com
+ * Santiago Leon santil@us.ibm.com
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
*/
-#ifndef _ASM_VIO_H
-#define _ASM_VIO_H
+#ifndef _ASM_POWERPC_VIO_H
+#define _ASM_POWERPC_VIO_H
#include <linux/config.h>
#include <linux/init.h>
@@ -55,10 +55,10 @@ struct vio_dev {
struct vio_driver {
struct list_head node;
- char *name;
const struct vio_device_id *id_table;
int (*probe)(struct vio_dev *dev, const struct vio_device_id *id);
int (*remove)(struct vio_dev *dev);
+ void (*shutdown)(struct vio_dev *dev);
unsigned long driver_data;
struct device_driver driver;
};
@@ -103,4 +103,4 @@ static inline struct vio_dev *to_vio_dev(struct device *dev)
return container_of(dev, struct vio_dev, dev);
}
-#endif /* _ASM_VIO_H */
+#endif /* _ASM_POWERPC_VIO_H */
diff --git a/include/asm-powerpc/xmon.h b/include/asm-powerpc/xmon.h
new file mode 100644
index 000000000000..43f7129984c7
--- /dev/null
+++ b/include/asm-powerpc/xmon.h
@@ -0,0 +1,12 @@
+#ifndef __PPC_XMON_H
+#define __PPC_XMON_H
+#ifdef __KERNEL__
+
+struct pt_regs;
+
+extern int xmon(struct pt_regs *excp);
+extern void xmon_printf(const char *fmt, ...);
+extern void xmon_init(int);
+
+#endif
+#endif
diff --git a/include/asm-ppc/a.out.h b/include/asm-ppc/a.out.h
deleted file mode 100644
index 8979a94c4a81..000000000000
--- a/include/asm-ppc/a.out.h
+++ /dev/null
@@ -1,26 +0,0 @@
-#ifndef __PPC_A_OUT_H__
-#define __PPC_A_OUT_H__
-
-/* grabbed from the intel stuff */
-#define STACK_TOP TASK_SIZE
-
-
-struct exec
-{
- unsigned long a_info; /* Use macros N_MAGIC, etc for access */
- unsigned a_text; /* length of text, in bytes */
- unsigned a_data; /* length of data, in bytes */
- unsigned a_bss; /* length of uninitialized data area for file, in bytes */
- unsigned a_syms; /* length of symbol table data in file, in bytes */
- unsigned a_entry; /* start address */
- unsigned a_trsize; /* length of relocation info for text, in bytes */
- unsigned a_drsize; /* length of relocation info for data, in bytes */
-};
-
-
-#define N_TRSIZE(a) ((a).a_trsize)
-#define N_DRSIZE(a) ((a).a_drsize)
-#define N_SYMSIZE(a) ((a).a_syms)
-
-
-#endif
diff --git a/include/asm-ppc/atomic.h b/include/asm-ppc/atomic.h
deleted file mode 100644
index eeafd505836e..000000000000
--- a/include/asm-ppc/atomic.h
+++ /dev/null
@@ -1,214 +0,0 @@
-/*
- * PowerPC atomic operations
- */
-
-#ifndef _ASM_PPC_ATOMIC_H_
-#define _ASM_PPC_ATOMIC_H_
-
-typedef struct { volatile int counter; } atomic_t;
-
-#ifdef __KERNEL__
-
-#define ATOMIC_INIT(i) { (i) }
-
-#define atomic_read(v) ((v)->counter)
-#define atomic_set(v,i) (((v)->counter) = (i))
-
-extern void atomic_clear_mask(unsigned long mask, unsigned long *addr);
-
-#ifdef CONFIG_SMP
-#define SMP_SYNC "sync"
-#define SMP_ISYNC "\n\tisync"
-#else
-#define SMP_SYNC ""
-#define SMP_ISYNC
-#endif
-
-/* Erratum #77 on the 405 means we need a sync or dcbt before every stwcx.
- * The old ATOMIC_SYNC_FIX covered some but not all of this.
- */
-#ifdef CONFIG_IBM405_ERR77
-#define PPC405_ERR77(ra,rb) "dcbt " #ra "," #rb ";"
-#else
-#define PPC405_ERR77(ra,rb)
-#endif
-
-static __inline__ void atomic_add(int a, atomic_t *v)
-{
- int t;
-
- __asm__ __volatile__(
-"1: lwarx %0,0,%3 # atomic_add\n\
- add %0,%2,%0\n"
- PPC405_ERR77(0,%3)
-" stwcx. %0,0,%3 \n\
- bne- 1b"
- : "=&r" (t), "=m" (v->counter)
- : "r" (a), "r" (&v->counter), "m" (v->counter)
- : "cc");
-}
-
-static __inline__ int atomic_add_return(int a, atomic_t *v)
-{
- int t;
-
- __asm__ __volatile__(
-"1: lwarx %0,0,%2 # atomic_add_return\n\
- add %0,%1,%0\n"
- PPC405_ERR77(0,%2)
-" stwcx. %0,0,%2 \n\
- bne- 1b"
- SMP_ISYNC
- : "=&r" (t)
- : "r" (a), "r" (&v->counter)
- : "cc", "memory");
-
- return t;
-}
-
-#define atomic_add_negative(a, v) (atomic_add_return((a), (v)) < 0)
-
-static __inline__ void atomic_sub(int a, atomic_t *v)
-{
- int t;
-
- __asm__ __volatile__(
-"1: lwarx %0,0,%3 # atomic_sub\n\
- subf %0,%2,%0\n"
- PPC405_ERR77(0,%3)
-" stwcx. %0,0,%3 \n\
- bne- 1b"
- : "=&r" (t), "=m" (v->counter)
- : "r" (a), "r" (&v->counter), "m" (v->counter)
- : "cc");
-}
-
-static __inline__ int atomic_sub_return(int a, atomic_t *v)
-{
- int t;
-
- __asm__ __volatile__(
-"1: lwarx %0,0,%2 # atomic_sub_return\n\
- subf %0,%1,%0\n"
- PPC405_ERR77(0,%2)
-" stwcx. %0,0,%2 \n\
- bne- 1b"
- SMP_ISYNC
- : "=&r" (t)
- : "r" (a), "r" (&v->counter)
- : "cc", "memory");
-
- return t;
-}
-
-static __inline__ void atomic_inc(atomic_t *v)
-{
- int t;
-
- __asm__ __volatile__(
-"1: lwarx %0,0,%2 # atomic_inc\n\
- addic %0,%0,1\n"
- PPC405_ERR77(0,%2)
-" stwcx. %0,0,%2 \n\
- bne- 1b"
- : "=&r" (t), "=m" (v->counter)
- : "r" (&v->counter), "m" (v->counter)
- : "cc");
-}
-
-static __inline__ int atomic_inc_return(atomic_t *v)
-{
- int t;
-
- __asm__ __volatile__(
-"1: lwarx %0,0,%1 # atomic_inc_return\n\
- addic %0,%0,1\n"
- PPC405_ERR77(0,%1)
-" stwcx. %0,0,%1 \n\
- bne- 1b"
- SMP_ISYNC
- : "=&r" (t)
- : "r" (&v->counter)
- : "cc", "memory");
-
- return t;
-}
-
-/*
- * atomic_inc_and_test - increment and test
- * @v: pointer of type atomic_t
- *
- * Atomically increments @v by 1
- * and returns true if the result is zero, or false for all
- * other cases.
- */
-#define atomic_inc_and_test(v) (atomic_inc_return(v) == 0)
-
-static __inline__ void atomic_dec(atomic_t *v)
-{
- int t;
-
- __asm__ __volatile__(
-"1: lwarx %0,0,%2 # atomic_dec\n\
- addic %0,%0,-1\n"
- PPC405_ERR77(0,%2)\
-" stwcx. %0,0,%2\n\
- bne- 1b"
- : "=&r" (t), "=m" (v->counter)
- : "r" (&v->counter), "m" (v->counter)
- : "cc");
-}
-
-static __inline__ int atomic_dec_return(atomic_t *v)
-{
- int t;
-
- __asm__ __volatile__(
-"1: lwarx %0,0,%1 # atomic_dec_return\n\
- addic %0,%0,-1\n"
- PPC405_ERR77(0,%1)
-" stwcx. %0,0,%1\n\
- bne- 1b"
- SMP_ISYNC
- : "=&r" (t)
- : "r" (&v->counter)
- : "cc", "memory");
-
- return t;
-}
-
-#define atomic_sub_and_test(a, v) (atomic_sub_return((a), (v)) == 0)
-#define atomic_dec_and_test(v) (atomic_dec_return((v)) == 0)
-
-/*
- * Atomically test *v and decrement if it is greater than 0.
- * The function returns the old value of *v minus 1.
- */
-static __inline__ int atomic_dec_if_positive(atomic_t *v)
-{
- int t;
-
- __asm__ __volatile__(
-"1: lwarx %0,0,%1 # atomic_dec_if_positive\n\
- addic. %0,%0,-1\n\
- blt- 2f\n"
- PPC405_ERR77(0,%1)
-" stwcx. %0,0,%1\n\
- bne- 1b"
- SMP_ISYNC
- "\n\
-2:" : "=&r" (t)
- : "r" (&v->counter)
- : "cc", "memory");
-
- return t;
-}
-
-#define __MB __asm__ __volatile__ (SMP_SYNC : : : "memory")
-#define smp_mb__before_atomic_dec() __MB
-#define smp_mb__after_atomic_dec() __MB
-#define smp_mb__before_atomic_inc() __MB
-#define smp_mb__after_atomic_inc() __MB
-
-#endif /* __KERNEL__ */
-#endif /* _ASM_PPC_ATOMIC_H_ */
diff --git a/include/asm-ppc/auxvec.h b/include/asm-ppc/auxvec.h
deleted file mode 100644
index 172358df29c8..000000000000
--- a/include/asm-ppc/auxvec.h
+++ /dev/null
@@ -1,14 +0,0 @@
-#ifndef __PPC_AUXVEC_H
-#define __PPC_AUXVEC_H
-
-/*
- * We need to put in some extra aux table entries to tell glibc what
- * the cache block size is, so it can use the dcbz instruction safely.
- */
-#define AT_DCACHEBSIZE 19
-#define AT_ICACHEBSIZE 20
-#define AT_UCACHEBSIZE 21
-/* A special ignored type value for PPC, for glibc compatibility. */
-#define AT_IGNOREPPC 22
-
-#endif
diff --git a/include/asm-ppc/bitops.h b/include/asm-ppc/bitops.h
deleted file mode 100644
index e30f536fd830..000000000000
--- a/include/asm-ppc/bitops.h
+++ /dev/null
@@ -1,460 +0,0 @@
-/*
- * bitops.h: Bit string operations on the ppc
- */
-
-#ifdef __KERNEL__
-#ifndef _PPC_BITOPS_H
-#define _PPC_BITOPS_H
-
-#include <linux/config.h>
-#include <linux/compiler.h>
-#include <asm/byteorder.h>
-#include <asm/atomic.h>
-
-/*
- * The test_and_*_bit operations are taken to imply a memory barrier
- * on SMP systems.
- */
-#ifdef CONFIG_SMP
-#define SMP_WMB "eieio\n"
-#define SMP_MB "\nsync"
-#else
-#define SMP_WMB
-#define SMP_MB
-#endif /* CONFIG_SMP */
-
-static __inline__ void set_bit(int nr, volatile unsigned long * addr)
-{
- unsigned long old;
- unsigned long mask = 1 << (nr & 0x1f);
- unsigned long *p = ((unsigned long *)addr) + (nr >> 5);
-
- __asm__ __volatile__("\n\
-1: lwarx %0,0,%3 \n\
- or %0,%0,%2 \n"
- PPC405_ERR77(0,%3)
-" stwcx. %0,0,%3 \n\
- bne- 1b"
- : "=&r" (old), "=m" (*p)
- : "r" (mask), "r" (p), "m" (*p)
- : "cc" );
-}
-
-/*
- * non-atomic version
- */
-static __inline__ void __set_bit(int nr, volatile unsigned long *addr)
-{
- unsigned long mask = 1 << (nr & 0x1f);
- unsigned long *p = ((unsigned long *)addr) + (nr >> 5);
-
- *p |= mask;
-}
-
-/*
- * clear_bit doesn't imply a memory barrier
- */
-#define smp_mb__before_clear_bit() smp_mb()
-#define smp_mb__after_clear_bit() smp_mb()
-
-static __inline__ void clear_bit(int nr, volatile unsigned long *addr)
-{
- unsigned long old;
- unsigned long mask = 1 << (nr & 0x1f);
- unsigned long *p = ((unsigned long *)addr) + (nr >> 5);
-
- __asm__ __volatile__("\n\
-1: lwarx %0,0,%3 \n\
- andc %0,%0,%2 \n"
- PPC405_ERR77(0,%3)
-" stwcx. %0,0,%3 \n\
- bne- 1b"
- : "=&r" (old), "=m" (*p)
- : "r" (mask), "r" (p), "m" (*p)
- : "cc");
-}
-
-/*
- * non-atomic version
- */
-static __inline__ void __clear_bit(int nr, volatile unsigned long *addr)
-{
- unsigned long mask = 1 << (nr & 0x1f);
- unsigned long *p = ((unsigned long *)addr) + (nr >> 5);
-
- *p &= ~mask;
-}
-
-static __inline__ void change_bit(int nr, volatile unsigned long *addr)
-{
- unsigned long old;
- unsigned long mask = 1 << (nr & 0x1f);
- unsigned long *p = ((unsigned long *)addr) + (nr >> 5);
-
- __asm__ __volatile__("\n\
-1: lwarx %0,0,%3 \n\
- xor %0,%0,%2 \n"
- PPC405_ERR77(0,%3)
-" stwcx. %0,0,%3 \n\
- bne- 1b"
- : "=&r" (old), "=m" (*p)
- : "r" (mask), "r" (p), "m" (*p)
- : "cc");
-}
-
-/*
- * non-atomic version
- */
-static __inline__ void __change_bit(int nr, volatile unsigned long *addr)
-{
- unsigned long mask = 1 << (nr & 0x1f);
- unsigned long *p = ((unsigned long *)addr) + (nr >> 5);
-
- *p ^= mask;
-}
-
-/*
- * test_and_*_bit do imply a memory barrier (?)
- */
-static __inline__ int test_and_set_bit(int nr, volatile unsigned long *addr)
-{
- unsigned int old, t;
- unsigned int mask = 1 << (nr & 0x1f);
- volatile unsigned int *p = ((volatile unsigned int *)addr) + (nr >> 5);
-
- __asm__ __volatile__(SMP_WMB "\n\
-1: lwarx %0,0,%4 \n\
- or %1,%0,%3 \n"
- PPC405_ERR77(0,%4)
-" stwcx. %1,0,%4 \n\
- bne 1b"
- SMP_MB
- : "=&r" (old), "=&r" (t), "=m" (*p)
- : "r" (mask), "r" (p), "m" (*p)
- : "cc", "memory");
-
- return (old & mask) != 0;
-}
-
-/*
- * non-atomic version
- */
-static __inline__ int __test_and_set_bit(int nr, volatile unsigned long *addr)
-{
- unsigned long mask = 1 << (nr & 0x1f);
- unsigned long *p = ((unsigned long *)addr) + (nr >> 5);
- unsigned long old = *p;
-
- *p = old | mask;
- return (old & mask) != 0;
-}
-
-static __inline__ int test_and_clear_bit(int nr, volatile unsigned long *addr)
-{
- unsigned int old, t;
- unsigned int mask = 1 << (nr & 0x1f);
- volatile unsigned int *p = ((volatile unsigned int *)addr) + (nr >> 5);
-
- __asm__ __volatile__(SMP_WMB "\n\
-1: lwarx %0,0,%4 \n\
- andc %1,%0,%3 \n"
- PPC405_ERR77(0,%4)
-" stwcx. %1,0,%4 \n\
- bne 1b"
- SMP_MB
- : "=&r" (old), "=&r" (t), "=m" (*p)
- : "r" (mask), "r" (p), "m" (*p)
- : "cc", "memory");
-
- return (old & mask) != 0;
-}
-
-/*
- * non-atomic version
- */
-static __inline__ int __test_and_clear_bit(int nr, volatile unsigned long *addr)
-{
- unsigned long mask = 1 << (nr & 0x1f);
- unsigned long *p = ((unsigned long *)addr) + (nr >> 5);
- unsigned long old = *p;
-
- *p = old & ~mask;
- return (old & mask) != 0;
-}
-
-static __inline__ int test_and_change_bit(int nr, volatile unsigned long *addr)
-{
- unsigned int old, t;
- unsigned int mask = 1 << (nr & 0x1f);
- volatile unsigned int *p = ((volatile unsigned int *)addr) + (nr >> 5);
-
- __asm__ __volatile__(SMP_WMB "\n\
-1: lwarx %0,0,%4 \n\
- xor %1,%0,%3 \n"
- PPC405_ERR77(0,%4)
-" stwcx. %1,0,%4 \n\
- bne 1b"
- SMP_MB
- : "=&r" (old), "=&r" (t), "=m" (*p)
- : "r" (mask), "r" (p), "m" (*p)
- : "cc", "memory");
-
- return (old & mask) != 0;
-}
-
-/*
- * non-atomic version
- */
-static __inline__ int __test_and_change_bit(int nr, volatile unsigned long *addr)
-{
- unsigned long mask = 1 << (nr & 0x1f);
- unsigned long *p = ((unsigned long *)addr) + (nr >> 5);
- unsigned long old = *p;
-
- *p = old ^ mask;
- return (old & mask) != 0;
-}
-
-static __inline__ int test_bit(int nr, __const__ volatile unsigned long *addr)
-{
- return ((addr[nr >> 5] >> (nr & 0x1f)) & 1) != 0;
-}
-
-/* Return the bit position of the most significant 1 bit in a word */
-static __inline__ int __ilog2(unsigned long x)
-{
- int lz;
-
- asm ("cntlzw %0,%1" : "=r" (lz) : "r" (x));
- return 31 - lz;
-}
-
-static __inline__ int ffz(unsigned long x)
-{
- if ((x = ~x) == 0)
- return 32;
- return __ilog2(x & -x);
-}
-
-static inline int __ffs(unsigned long x)
-{
- return __ilog2(x & -x);
-}
-
-/*
- * ffs: find first bit set. This is defined the same way as
- * the libc and compiler builtin ffs routines, therefore
- * differs in spirit from the above ffz (man ffs).
- */
-static __inline__ int ffs(int x)
-{
- return __ilog2(x & -x) + 1;
-}
-
-/*
- * fls: find last (most-significant) bit set.
- * Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32.
- */
-static __inline__ int fls(unsigned int x)
-{
- int lz;
-
- asm ("cntlzw %0,%1" : "=r" (lz) : "r" (x));
- return 32 - lz;
-}
-
-/*
- * hweightN: returns the hamming weight (i.e. the number
- * of bits set) of a N-bit word
- */
-
-#define hweight32(x) generic_hweight32(x)
-#define hweight16(x) generic_hweight16(x)
-#define hweight8(x) generic_hweight8(x)
-
-/*
- * Find the first bit set in a 140-bit bitmap.
- * The first 100 bits are unlikely to be set.
- */
-static inline int sched_find_first_bit(const unsigned long *b)
-{
- if (unlikely(b[0]))
- return __ffs(b[0]);
- if (unlikely(b[1]))
- return __ffs(b[1]) + 32;
- if (unlikely(b[2]))
- return __ffs(b[2]) + 64;
- if (b[3])
- return __ffs(b[3]) + 96;
- return __ffs(b[4]) + 128;
-}
-
-/**
- * find_next_bit - find the next set bit in a memory region
- * @addr: The address to base the search on
- * @offset: The bitnumber to start searching at
- * @size: The maximum size to search
- */
-static __inline__ unsigned long find_next_bit(const unsigned long *addr,
- unsigned long size, unsigned long offset)
-{
- unsigned int *p = ((unsigned int *) addr) + (offset >> 5);
- unsigned int result = offset & ~31UL;
- unsigned int tmp;
-
- if (offset >= size)
- return size;
- size -= result;
- offset &= 31UL;
- if (offset) {
- tmp = *p++;
- tmp &= ~0UL << offset;
- if (size < 32)
- goto found_first;
- if (tmp)
- goto found_middle;
- size -= 32;
- result += 32;
- }
- while (size >= 32) {
- if ((tmp = *p++) != 0)
- goto found_middle;
- result += 32;
- size -= 32;
- }
- if (!size)
- return result;
- tmp = *p;
-
-found_first:
- tmp &= ~0UL >> (32 - size);
- if (tmp == 0UL) /* Are any bits set? */
- return result + size; /* Nope. */
-found_middle:
- return result + __ffs(tmp);
-}
-
-/**
- * find_first_bit - find the first set bit in a memory region
- * @addr: The address to start the search at
- * @size: The maximum size to search
- *
- * Returns the bit-number of the first set bit, not the number of the byte
- * containing a bit.
- */
-#define find_first_bit(addr, size) \
- find_next_bit((addr), (size), 0)
-
-/*
- * This implementation of find_{first,next}_zero_bit was stolen from
- * Linus' asm-alpha/bitops.h.
- */
-#define find_first_zero_bit(addr, size) \
- find_next_zero_bit((addr), (size), 0)
-
-static __inline__ unsigned long find_next_zero_bit(const unsigned long *addr,
- unsigned long size, unsigned long offset)
-{
- unsigned int * p = ((unsigned int *) addr) + (offset >> 5);
- unsigned int result = offset & ~31UL;
- unsigned int tmp;
-
- if (offset >= size)
- return size;
- size -= result;
- offset &= 31UL;
- if (offset) {
- tmp = *p++;
- tmp |= ~0UL >> (32-offset);
- if (size < 32)
- goto found_first;
- if (tmp != ~0U)
- goto found_middle;
- size -= 32;
- result += 32;
- }
- while (size >= 32) {
- if ((tmp = *p++) != ~0U)
- goto found_middle;
- result += 32;
- size -= 32;
- }
- if (!size)
- return result;
- tmp = *p;
-found_first:
- tmp |= ~0UL << size;
- if (tmp == ~0UL) /* Are any bits zero? */
- return result + size; /* Nope. */
-found_middle:
- return result + ffz(tmp);
-}
-
-
-#define ext2_set_bit(nr, addr) __test_and_set_bit((nr) ^ 0x18, (unsigned long *)(addr))
-#define ext2_set_bit_atomic(lock, nr, addr) test_and_set_bit((nr) ^ 0x18, (unsigned long *)(addr))
-#define ext2_clear_bit(nr, addr) __test_and_clear_bit((nr) ^ 0x18, (unsigned long *)(addr))
-#define ext2_clear_bit_atomic(lock, nr, addr) test_and_clear_bit((nr) ^ 0x18, (unsigned long *)(addr))
-
-static __inline__ int ext2_test_bit(int nr, __const__ void * addr)
-{
- __const__ unsigned char *ADDR = (__const__ unsigned char *) addr;
-
- return (ADDR[nr >> 3] >> (nr & 7)) & 1;
-}
-
-/*
- * This implementation of ext2_find_{first,next}_zero_bit was stolen from
- * Linus' asm-alpha/bitops.h and modified for a big-endian machine.
- */
-
-#define ext2_find_first_zero_bit(addr, size) \
- ext2_find_next_zero_bit((addr), (size), 0)
-
-static __inline__ unsigned long ext2_find_next_zero_bit(const void *addr,
- unsigned long size, unsigned long offset)
-{
- unsigned int *p = ((unsigned int *) addr) + (offset >> 5);
- unsigned int result = offset & ~31UL;
- unsigned int tmp;
-
- if (offset >= size)
- return size;
- size -= result;
- offset &= 31UL;
- if (offset) {
- tmp = cpu_to_le32p(p++);
- tmp |= ~0UL >> (32-offset);
- if (size < 32)
- goto found_first;
- if (tmp != ~0U)
- goto found_middle;
- size -= 32;
- result += 32;
- }
- while (size >= 32) {
- if ((tmp = cpu_to_le32p(p++)) != ~0U)
- goto found_middle;
- result += 32;
- size -= 32;
- }
- if (!size)
- return result;
- tmp = cpu_to_le32p(p);
-found_first:
- tmp |= ~0U << size;
- if (tmp == ~0UL) /* Are any bits zero? */
- return result + size; /* Nope. */
-found_middle:
- return result + ffz(tmp);
-}
-
-/* Bitmap functions for the minix filesystem. */
-#define minix_test_and_set_bit(nr,addr) ext2_set_bit(nr,addr)
-#define minix_set_bit(nr,addr) ((void)ext2_set_bit(nr,addr))
-#define minix_test_and_clear_bit(nr,addr) ext2_clear_bit(nr,addr)
-#define minix_test_bit(nr,addr) ext2_test_bit(nr,addr)
-#define minix_find_first_zero_bit(addr,size) ext2_find_first_zero_bit(addr,size)
-
-#endif /* _PPC_BITOPS_H */
-#endif /* __KERNEL__ */
diff --git a/include/asm-ppc/btext.h b/include/asm-ppc/btext.h
index 36c7640d00f2..ccaefabe0bf5 100644
--- a/include/asm-ppc/btext.h
+++ b/include/asm-ppc/btext.h
@@ -17,18 +17,18 @@ extern unsigned long disp_BAT[2];
extern boot_infos_t disp_bi;
extern int boot_text_mapped;
-void btext_init(boot_infos_t *bi);
-void btext_welcome(void);
-void btext_prepare_BAT(void);
-void btext_setup_display(int width, int height, int depth, int pitch,
- unsigned long address);
-void map_boot_text(void);
-void btext_update_display(unsigned long phys, int width, int height,
- int depth, int pitch);
+extern void init_boot_display(void);
+extern void btext_welcome(void);
+extern void btext_prepare_BAT(void);
+extern void btext_setup_display(int width, int height, int depth, int pitch,
+ unsigned long address);
+extern void map_boot_text(void);
+extern void btext_update_display(unsigned long phys, int width, int height,
+ int depth, int pitch);
-void btext_drawchar(char c);
-void btext_drawstring(const char *str);
-void btext_drawhex(unsigned long v);
+extern void btext_drawchar(char c);
+extern void btext_drawstring(const char *str);
+extern void btext_drawhex(unsigned long v);
#endif /* __KERNEL__ */
#endif /* __PPC_BTEXT_H */
diff --git a/include/asm-ppc/bug.h b/include/asm-ppc/bug.h
deleted file mode 100644
index 8b34fd682b0d..000000000000
--- a/include/asm-ppc/bug.h
+++ /dev/null
@@ -1,58 +0,0 @@
-#ifndef _PPC_BUG_H
-#define _PPC_BUG_H
-
-struct bug_entry {
- unsigned long bug_addr;
- int line;
- const char *file;
- const char *function;
-};
-
-/*
- * If this bit is set in the line number it means that the trap
- * is for WARN_ON rather than BUG or BUG_ON.
- */
-#define BUG_WARNING_TRAP 0x1000000
-
-#ifdef CONFIG_BUG
-#define BUG() do { \
- __asm__ __volatile__( \
- "1: twi 31,0,0\n" \
- ".section __bug_table,\"a\"\n\t" \
- " .long 1b,%0,%1,%2\n" \
- ".previous" \
- : : "i" (__LINE__), "i" (__FILE__), "i" (__FUNCTION__)); \
-} while (0)
-
-#define BUG_ON(x) do { \
- if (!__builtin_constant_p(x) || (x)) { \
- __asm__ __volatile__( \
- "1: twnei %0,0\n" \
- ".section __bug_table,\"a\"\n\t" \
- " .long 1b,%1,%2,%3\n" \
- ".previous" \
- : : "r" (x), "i" (__LINE__), "i" (__FILE__), \
- "i" (__FUNCTION__)); \
- } \
-} while (0)
-
-#define WARN_ON(x) do { \
- if (!__builtin_constant_p(x) || (x)) { \
- __asm__ __volatile__( \
- "1: twnei %0,0\n" \
- ".section __bug_table,\"a\"\n\t" \
- " .long 1b,%1,%2,%3\n" \
- ".previous" \
- : : "r" (x), "i" (__LINE__ + BUG_WARNING_TRAP), \
- "i" (__FILE__), "i" (__FUNCTION__)); \
- } \
-} while (0)
-
-#define HAVE_ARCH_BUG
-#define HAVE_ARCH_BUG_ON
-#define HAVE_ARCH_WARN_ON
-#endif
-
-#include <asm-generic/bug.h>
-
-#endif
diff --git a/include/asm-ppc/byteorder.h b/include/asm-ppc/byteorder.h
deleted file mode 100644
index c63c81ec7968..000000000000
--- a/include/asm-ppc/byteorder.h
+++ /dev/null
@@ -1,76 +0,0 @@
-#ifndef _PPC_BYTEORDER_H
-#define _PPC_BYTEORDER_H
-
-#include <asm/types.h>
-#include <linux/compiler.h>
-
-#ifdef __GNUC__
-#ifdef __KERNEL__
-
-extern __inline__ unsigned ld_le16(const volatile unsigned short *addr)
-{
- unsigned val;
-
- __asm__ __volatile__ ("lhbrx %0,0,%1" : "=r" (val) : "r" (addr), "m" (*addr));
- return val;
-}
-
-extern __inline__ void st_le16(volatile unsigned short *addr, const unsigned val)
-{
- __asm__ __volatile__ ("sthbrx %1,0,%2" : "=m" (*addr) : "r" (val), "r" (addr));
-}
-
-extern __inline__ unsigned ld_le32(const volatile unsigned *addr)
-{
- unsigned val;
-
- __asm__ __volatile__ ("lwbrx %0,0,%1" : "=r" (val) : "r" (addr), "m" (*addr));
- return val;
-}
-
-extern __inline__ void st_le32(volatile unsigned *addr, const unsigned val)
-{
- __asm__ __volatile__ ("stwbrx %1,0,%2" : "=m" (*addr) : "r" (val), "r" (addr));
-}
-
-static __inline__ __attribute_const__ __u16 ___arch__swab16(__u16 value)
-{
- __u16 result;
-
- __asm__("rlwimi %0,%2,8,16,23" : "=&r" (result) : "0" (value >> 8), "r" (value));
- return result;
-}
-
-static __inline__ __attribute_const__ __u32 ___arch__swab32(__u32 value)
-{
- __u32 result;
-
- __asm__("rlwimi %0,%2,24,16,23" : "=&r" (result) : "0" (value>>24), "r" (value));
- __asm__("rlwimi %0,%2,8,8,15" : "=&r" (result) : "0" (result), "r" (value));
- __asm__("rlwimi %0,%2,24,0,7" : "=&r" (result) : "0" (result), "r" (value));
-
- return result;
-}
-#define __arch__swab32(x) ___arch__swab32(x)
-#define __arch__swab16(x) ___arch__swab16(x)
-
-/* The same, but returns converted value from the location pointer by addr. */
-#define __arch__swab16p(addr) ld_le16(addr)
-#define __arch__swab32p(addr) ld_le32(addr)
-
-/* The same, but do the conversion in situ, ie. put the value back to addr. */
-#define __arch__swab16s(addr) st_le16(addr,*addr)
-#define __arch__swab32s(addr) st_le32(addr,*addr)
-
-#endif /* __KERNEL__ */
-
-#if !defined(__STRICT_ANSI__) || defined(__KERNEL__)
-# define __BYTEORDER_HAS_U64__
-# define __SWAB_64_THRU_32__
-#endif
-
-#endif /* __GNUC__ */
-
-#include <linux/byteorder/big_endian.h>
-
-#endif /* _PPC_BYTEORDER_H */
diff --git a/include/asm-ppc/cache.h b/include/asm-ppc/cache.h
deleted file mode 100644
index 38f2f1be4a87..000000000000
--- a/include/asm-ppc/cache.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * include/asm-ppc/cache.h
- */
-#ifdef __KERNEL__
-#ifndef __ARCH_PPC_CACHE_H
-#define __ARCH_PPC_CACHE_H
-
-#include <linux/config.h>
-
-/* bytes per L1 cache line */
-#if defined(CONFIG_8xx) || defined(CONFIG_403GCX)
-#define L1_CACHE_LINE_SIZE 16
-#define LG_L1_CACHE_LINE_SIZE 4
-#define MAX_COPY_PREFETCH 1
-#elif defined(CONFIG_PPC64BRIDGE)
-#define L1_CACHE_LINE_SIZE 128
-#define LG_L1_CACHE_LINE_SIZE 7
-#define MAX_COPY_PREFETCH 1
-#else
-#define L1_CACHE_LINE_SIZE 32
-#define LG_L1_CACHE_LINE_SIZE 5
-#define MAX_COPY_PREFETCH 4
-#endif
-
-#define L1_CACHE_BYTES L1_CACHE_LINE_SIZE
-#define L1_CACHE_SHIFT LG_L1_CACHE_LINE_SIZE
-#define SMP_CACHE_BYTES L1_CACHE_BYTES
-#define L1_CACHE_SHIFT_MAX 7 /* largest L1 which this arch supports */
-
-#define L1_CACHE_ALIGN(x) (((x)+(L1_CACHE_BYTES-1))&~(L1_CACHE_BYTES-1))
-#define L1_CACHE_PAGES 8
-
-#ifndef __ASSEMBLY__
-extern void clean_dcache_range(unsigned long start, unsigned long stop);
-extern void flush_dcache_range(unsigned long start, unsigned long stop);
-extern void invalidate_dcache_range(unsigned long start, unsigned long stop);
-extern void flush_dcache_all(void);
-#endif /* __ASSEMBLY__ */
-
-/* prep registers for L2 */
-#define CACHECRBA 0x80000823 /* Cache configuration register address */
-#define L2CACHE_MASK 0x03 /* Mask for 2 L2 Cache bits */
-#define L2CACHE_512KB 0x00 /* 512KB */
-#define L2CACHE_256KB 0x01 /* 256KB */
-#define L2CACHE_1MB 0x02 /* 1MB */
-#define L2CACHE_NONE 0x03 /* NONE */
-#define L2CACHE_PARITY 0x08 /* Mask for L2 Cache Parity Protected bit */
-
-#ifdef CONFIG_8xx
-/* Cache control on the MPC8xx is provided through some additional
- * special purpose registers.
- */
-#define SPRN_IC_CST 560 /* Instruction cache control/status */
-#define SPRN_IC_ADR 561 /* Address needed for some commands */
-#define SPRN_IC_DAT 562 /* Read-only data register */
-#define SPRN_DC_CST 568 /* Data cache control/status */
-#define SPRN_DC_ADR 569 /* Address needed for some commands */
-#define SPRN_DC_DAT 570 /* Read-only data register */
-
-/* Commands. Only the first few are available to the instruction cache.
-*/
-#define IDC_ENABLE 0x02000000 /* Cache enable */
-#define IDC_DISABLE 0x04000000 /* Cache disable */
-#define IDC_LDLCK 0x06000000 /* Load and lock */
-#define IDC_UNLINE 0x08000000 /* Unlock line */
-#define IDC_UNALL 0x0a000000 /* Unlock all */
-#define IDC_INVALL 0x0c000000 /* Invalidate all */
-
-#define DC_FLINE 0x0e000000 /* Flush data cache line */
-#define DC_SFWT 0x01000000 /* Set forced writethrough mode */
-#define DC_CFWT 0x03000000 /* Clear forced writethrough mode */
-#define DC_SLES 0x05000000 /* Set little endian swap mode */
-#define DC_CLES 0x07000000 /* Clear little endian swap mode */
-
-/* Status.
-*/
-#define IDC_ENABLED 0x80000000 /* Cache is enabled */
-#define IDC_CERR1 0x00200000 /* Cache error 1 */
-#define IDC_CERR2 0x00100000 /* Cache error 2 */
-#define IDC_CERR3 0x00080000 /* Cache error 3 */
-
-#define DC_DFWT 0x40000000 /* Data cache is forced write through */
-#define DC_LES 0x20000000 /* Caches are little endian mode */
-#endif /* CONFIG_8xx */
-
-#endif
-#endif /* __KERNEL__ */
diff --git a/include/asm-ppc/cacheflush.h b/include/asm-ppc/cacheflush.h
deleted file mode 100644
index 6a243efb3317..000000000000
--- a/include/asm-ppc/cacheflush.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * include/asm-ppc/cacheflush.h
- *
- * 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 _PPC_CACHEFLUSH_H
-#define _PPC_CACHEFLUSH_H
-
-#include <linux/mm.h>
-
-/*
- * No cache flushing is required when address mappings are
- * changed, because the caches on PowerPCs are physically
- * addressed. -- paulus
- * Also, when SMP we use the coherency (M) bit of the
- * BATs and PTEs. -- Cort
- */
-#define flush_cache_all() do { } while (0)
-#define flush_cache_mm(mm) do { } while (0)
-#define flush_cache_range(vma, a, b) do { } while (0)
-#define flush_cache_page(vma, p, pfn) do { } while (0)
-#define flush_icache_page(vma, page) do { } while (0)
-#define flush_cache_vmap(start, end) do { } while (0)
-#define flush_cache_vunmap(start, end) do { } while (0)
-
-extern void flush_dcache_page(struct page *page);
-#define flush_dcache_mmap_lock(mapping) do { } while (0)
-#define flush_dcache_mmap_unlock(mapping) do { } while (0)
-
-extern void flush_icache_range(unsigned long, unsigned long);
-extern void flush_icache_user_range(struct vm_area_struct *vma,
- struct page *page, unsigned long addr, int len);
-
-#define copy_to_user_page(vma, page, vaddr, dst, src, len) \
-do { memcpy(dst, src, len); \
- flush_icache_user_range(vma, page, vaddr, len); \
-} while (0)
-#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
- memcpy(dst, src, len)
-
-extern void __flush_dcache_icache(void *page_va);
-extern void __flush_dcache_icache_phys(unsigned long physaddr);
-extern void flush_dcache_icache_page(struct page *page);
-#endif /* _PPC_CACHEFLUSH_H */
-#endif /* __KERNEL__ */
diff --git a/include/asm-ppc/checksum.h b/include/asm-ppc/checksum.h
deleted file mode 100644
index cf953a92c7ab..000000000000
--- a/include/asm-ppc/checksum.h
+++ /dev/null
@@ -1,107 +0,0 @@
-#ifdef __KERNEL__
-#ifndef _PPC_CHECKSUM_H
-#define _PPC_CHECKSUM_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
- */
-extern unsigned int csum_partial(const unsigned char * buff, int len,
- unsigned int sum);
-
-/*
- * Computes the checksum of a memory block at src, length len,
- * and adds in "sum" (32-bit), while copying the block to dst.
- * If an access exception occurs on src or dst, it stores -EFAULT
- * to *src_err or *dst_err respectively (if that pointer is not
- * NULL), and, for an error on src, zeroes the rest of dst.
- *
- * Like csum_partial, this must be called with even lengths,
- * except for the last fragment.
- */
-extern unsigned int csum_partial_copy_generic(const char *src, char *dst,
- int len, unsigned int sum,
- int *src_err, int *dst_err);
-
-#define csum_partial_copy_from_user(src, dst, len, sum, errp) \
- csum_partial_copy_generic((__force void *)(src), (dst), (len), (sum), (errp), NULL)
-
-/* FIXME: this needs to be written to really do no check -- Cort */
-#define csum_partial_copy_nocheck(src, dst, len, sum) \
- csum_partial_copy_generic((src), (dst), (len), (sum), NULL, NULL)
-
-/*
- * turns a 32-bit partial checksum (e.g. from csum_partial) into a
- * 1's complement 16-bit checksum.
- */
-static inline unsigned int csum_fold(unsigned int sum)
-{
- unsigned int tmp;
-
- /* swap the two 16-bit halves of sum */
- __asm__("rlwinm %0,%1,16,0,31" : "=r" (tmp) : "r" (sum));
- /* if there is a carry from adding the two 16-bit halves,
- it will carry from the lower half into the upper half,
- giving us the correct sum in the upper half. */
- sum = ~(sum + tmp) >> 16;
- return sum;
-}
-
-/*
- * this routine is used for miscellaneous IP-like checksums, mainly
- * in icmp.c
- */
-static inline unsigned short ip_compute_csum(unsigned char * buff, int len)
-{
- return csum_fold(csum_partial(buff, len, 0));
-}
-
-/*
- * FIXME: I swiped this one from the sparc and made minor modifications.
- * It may not be correct. -- Cort
- */
-static inline unsigned long csum_tcpudp_nofold(unsigned long saddr,
- unsigned long daddr,
- unsigned short len,
- unsigned short proto,
- unsigned int sum)
-{
- __asm__("\n\
- addc %0,%0,%1 \n\
- adde %0,%0,%2 \n\
- adde %0,%0,%3 \n\
- addze %0,%0 \n\
- "
- : "=r" (sum)
- : "r" (daddr), "r"(saddr), "r"((proto<<16)+len), "0"(sum));
- return sum;
-}
-
-/*
- * This is a version of ip_compute_csum() optimized for IP headers,
- * which always checksum on 4 octet boundaries. ihl is the number
- * of 32-bit words and is always >= 5.
- */
-extern unsigned short ip_fast_csum(unsigned char * iph, unsigned int ihl);
-
-/*
- * computes the checksum of the TCP/UDP pseudo-header
- * returns a 16-bit checksum, already complemented
- */
-extern unsigned short csum_tcpudp_magic(unsigned long saddr,
- unsigned long daddr,
- unsigned short len,
- unsigned short proto,
- unsigned int sum);
-
-#endif
-#endif /* __KERNEL__ */
diff --git a/include/asm-ppc/commproc.h b/include/asm-ppc/commproc.h
index 5bbb8e2c1c6d..973e60908234 100644
--- a/include/asm-ppc/commproc.h
+++ b/include/asm-ppc/commproc.h
@@ -83,6 +83,8 @@ extern uint m8xx_cpm_hostalloc(uint size);
extern int m8xx_cpm_hostfree(uint start);
extern void m8xx_cpm_hostdump(void);
+extern void cpm_load_patch(volatile immap_t *immr);
+
/* Buffer descriptors used by many of the CPM protocols.
*/
typedef struct cpm_buf_desc {
diff --git a/include/asm-ppc/cpm2.h b/include/asm-ppc/cpm2.h
index 9483d4bfacf7..43d2ebbc7748 100644
--- a/include/asm-ppc/cpm2.h
+++ b/include/asm-ppc/cpm2.h
@@ -1087,6 +1087,9 @@ typedef struct im_idma {
#define SCCR_PCIDF_MSK 0x00000078 /* PCI division factor */
#define SCCR_PCIDF_SHIFT 3
+#ifndef CPM_IMMR_OFFSET
+#define CPM_IMMR_OFFSET 0x101a8
+#endif
#endif /* __CPM2__ */
#endif /* __KERNEL__ */
diff --git a/include/asm-ppc/cputable.h b/include/asm-ppc/cputable.h
deleted file mode 100644
index e17c492c870b..000000000000
--- a/include/asm-ppc/cputable.h
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * include/asm-ppc/cputable.h
- *
- * Copyright (C) 2001 Ben. Herrenschmidt (benh@kernel.crashing.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.
- */
-
-#ifndef __ASM_PPC_CPUTABLE_H
-#define __ASM_PPC_CPUTABLE_H
-
-/* Exposed to userland CPU features */
-#define PPC_FEATURE_32 0x80000000
-#define PPC_FEATURE_64 0x40000000
-#define PPC_FEATURE_601_INSTR 0x20000000
-#define PPC_FEATURE_HAS_ALTIVEC 0x10000000
-#define PPC_FEATURE_HAS_FPU 0x08000000
-#define PPC_FEATURE_HAS_MMU 0x04000000
-#define PPC_FEATURE_HAS_4xxMAC 0x02000000
-#define PPC_FEATURE_UNIFIED_CACHE 0x01000000
-#define PPC_FEATURE_HAS_SPE 0x00800000
-#define PPC_FEATURE_HAS_EFP_SINGLE 0x00400000
-#define PPC_FEATURE_HAS_EFP_DOUBLE 0x00200000
-#define PPC_FEATURE_NO_TB 0x00100000
-
-#ifdef __KERNEL__
-
-#ifndef __ASSEMBLY__
-
-/* This structure can grow, it's real size is used by head.S code
- * via the mkdefs mecanism.
- */
-struct cpu_spec;
-
-typedef void (*cpu_setup_t)(unsigned long offset, int cpu_nr, struct cpu_spec* spec);
-
-struct cpu_spec {
- /* CPU is matched via (PVR & pvr_mask) == pvr_value */
- unsigned int pvr_mask;
- unsigned int pvr_value;
-
- char *cpu_name;
- unsigned int cpu_features; /* Kernel features */
- unsigned int cpu_user_features; /* Userland features */
-
- /* cache line sizes */
- unsigned int icache_bsize;
- unsigned int dcache_bsize;
-
- /* number of performance monitor counters */
- unsigned int num_pmcs;
-
- /* this is called to initialize various CPU bits like L1 cache,
- * BHT, SPD, etc... from head.S before branching to identify_machine
- */
- cpu_setup_t cpu_setup;
-};
-
-extern struct cpu_spec cpu_specs[];
-extern struct cpu_spec *cur_cpu_spec[];
-
-static inline unsigned int cpu_has_feature(unsigned int feature)
-{
- return cur_cpu_spec[0]->cpu_features & feature;
-}
-
-#endif /* __ASSEMBLY__ */
-
-/* CPU kernel features */
-#define CPU_FTR_SPLIT_ID_CACHE 0x00000001
-#define CPU_FTR_L2CR 0x00000002
-#define CPU_FTR_SPEC7450 0x00000004
-#define CPU_FTR_ALTIVEC 0x00000008
-#define CPU_FTR_TAU 0x00000010
-#define CPU_FTR_CAN_DOZE 0x00000020
-#define CPU_FTR_USE_TB 0x00000040
-#define CPU_FTR_604_PERF_MON 0x00000080
-#define CPU_FTR_601 0x00000100
-#define CPU_FTR_HPTE_TABLE 0x00000200
-#define CPU_FTR_CAN_NAP 0x00000400
-#define CPU_FTR_L3CR 0x00000800
-#define CPU_FTR_L3_DISABLE_NAP 0x00001000
-#define CPU_FTR_NAP_DISABLE_L2_PR 0x00002000
-#define CPU_FTR_DUAL_PLL_750FX 0x00004000
-#define CPU_FTR_NO_DPM 0x00008000
-#define CPU_FTR_HAS_HIGH_BATS 0x00010000
-#define CPU_FTR_NEED_COHERENT 0x00020000
-#define CPU_FTR_NO_BTIC 0x00040000
-#define CPU_FTR_BIG_PHYS 0x00080000
-
-#ifdef __ASSEMBLY__
-
-#define BEGIN_FTR_SECTION 98:
-
-#define END_FTR_SECTION(msk, val) \
-99: \
- .section __ftr_fixup,"a"; \
- .align 2; \
- .long msk; \
- .long val; \
- .long 98b; \
- .long 99b; \
- .previous
-
-#else
-
-#define BEGIN_FTR_SECTION "98:\n"
-#define END_FTR_SECTION(msk, val) \
-"99:\n" \
-" .section __ftr_fixup,\"a\";\n" \
-" .align 2;\n" \
-" .long "#msk";\n" \
-" .long "#val";\n" \
-" .long 98b;\n" \
-" .long 99b;\n" \
-" .previous\n"
-
-
-#endif /* __ASSEMBLY__ */
-
-#define END_FTR_SECTION_IFSET(msk) END_FTR_SECTION((msk), (msk))
-#define END_FTR_SECTION_IFCLR(msk) END_FTR_SECTION((msk), 0)
-
-#endif /* __ASM_PPC_CPUTABLE_H */
-#endif /* __KERNEL__ */
-
diff --git a/include/asm-ppc/current.h b/include/asm-ppc/current.h
deleted file mode 100644
index 8d41501ba10d..000000000000
--- a/include/asm-ppc/current.h
+++ /dev/null
@@ -1,11 +0,0 @@
-#ifdef __KERNEL__
-#ifndef _PPC_CURRENT_H
-#define _PPC_CURRENT_H
-
-/*
- * We keep `current' in r2 for speed.
- */
-register struct task_struct *current asm ("r2");
-
-#endif /* !(_PPC_CURRENT_H) */
-#endif /* __KERNEL__ */
diff --git a/include/asm-ppc/dma-mapping.h b/include/asm-ppc/dma-mapping.h
index 061bfcac1bf1..6e9635114433 100644
--- a/include/asm-ppc/dma-mapping.h
+++ b/include/asm-ppc/dma-mapping.h
@@ -19,7 +19,7 @@
* allocate the space "normally" and use the cache management functions
* to ensure it is consistent.
*/
-extern void *__dma_alloc_coherent(size_t size, dma_addr_t *handle, int gfp);
+extern void *__dma_alloc_coherent(size_t size, dma_addr_t *handle, gfp_t gfp);
extern void __dma_free_coherent(size_t size, void *vaddr);
extern void __dma_sync(void *vaddr, size_t size, int direction);
extern void __dma_sync_page(struct page *page, unsigned long offset,
diff --git a/include/asm-ppc/elf.h b/include/asm-ppc/elf.h
deleted file mode 100644
index c25cc35e6ab5..000000000000
--- a/include/asm-ppc/elf.h
+++ /dev/null
@@ -1,151 +0,0 @@
-#ifndef __PPC_ELF_H
-#define __PPC_ELF_H
-
-/*
- * ELF register definitions..
- */
-#include <asm/types.h>
-#include <asm/ptrace.h>
-#include <asm/cputable.h>
-#include <asm/auxvec.h>
-
-/* PowerPC relocations defined by the ABIs */
-#define R_PPC_NONE 0
-#define R_PPC_ADDR32 1 /* 32bit absolute address */
-#define R_PPC_ADDR24 2 /* 26bit address, 2 bits ignored. */
-#define R_PPC_ADDR16 3 /* 16bit absolute address */
-#define R_PPC_ADDR16_LO 4 /* lower 16bit of absolute address */
-#define R_PPC_ADDR16_HI 5 /* high 16bit of absolute address */
-#define R_PPC_ADDR16_HA 6 /* adjusted high 16bit */
-#define R_PPC_ADDR14 7 /* 16bit address, 2 bits ignored */
-#define R_PPC_ADDR14_BRTAKEN 8
-#define R_PPC_ADDR14_BRNTAKEN 9
-#define R_PPC_REL24 10 /* PC relative 26 bit */
-#define R_PPC_REL14 11 /* PC relative 16 bit */
-#define R_PPC_REL14_BRTAKEN 12
-#define R_PPC_REL14_BRNTAKEN 13
-#define R_PPC_GOT16 14
-#define R_PPC_GOT16_LO 15
-#define R_PPC_GOT16_HI 16
-#define R_PPC_GOT16_HA 17
-#define R_PPC_PLTREL24 18
-#define R_PPC_COPY 19
-#define R_PPC_GLOB_DAT 20
-#define R_PPC_JMP_SLOT 21
-#define R_PPC_RELATIVE 22
-#define R_PPC_LOCAL24PC 23
-#define R_PPC_UADDR32 24
-#define R_PPC_UADDR16 25
-#define R_PPC_REL32 26
-#define R_PPC_PLT32 27
-#define R_PPC_PLTREL32 28
-#define R_PPC_PLT16_LO 29
-#define R_PPC_PLT16_HI 30
-#define R_PPC_PLT16_HA 31
-#define R_PPC_SDAREL16 32
-#define R_PPC_SECTOFF 33
-#define R_PPC_SECTOFF_LO 34
-#define R_PPC_SECTOFF_HI 35
-#define R_PPC_SECTOFF_HA 36
-/* Keep this the last entry. */
-#define R_PPC_NUM 37
-
-#define ELF_NGREG 48 /* includes nip, msr, lr, etc. */
-#define ELF_NFPREG 33 /* includes fpscr */
-#define ELF_NVRREG 33 /* includes vscr */
-#define ELF_NEVRREG 34 /* includes acc (as 2) */
-
-/*
- * These are used to set parameters in the core dumps.
- */
-#define ELF_ARCH EM_PPC
-#define ELF_CLASS ELFCLASS32
-#define ELF_DATA ELFDATA2MSB
-
-/* General registers */
-typedef unsigned long elf_greg_t;
-typedef elf_greg_t elf_gregset_t[ELF_NGREG];
-
-/* Floating point registers */
-typedef double elf_fpreg_t;
-typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
-
-/* Altivec registers */
-typedef __vector128 elf_vrreg_t;
-typedef elf_vrreg_t elf_vrregset_t[ELF_NVRREG];
-
-#ifdef __KERNEL__
-
-struct task_struct;
-
-/*
- * This is used to ensure we don't load something for the wrong architecture.
- */
-
-#define elf_check_arch(x) ((x)->e_machine == EM_PPC)
-
-/* This is the location that an ET_DYN program is loaded if exec'ed. Typical
- use of this is to invoke "./ld.so someprog" to test out a new version of
- the loader. We need to make sure that it is out of the way of the program
- that it will "exec", and that there is sufficient room for the brk. */
-
-#define ELF_ET_DYN_BASE (0x08000000)
-
-#define USE_ELF_CORE_DUMP
-#define ELF_EXEC_PAGESIZE 4096
-
-#define ELF_CORE_COPY_REGS(gregs, regs) \
- memcpy((gregs), (regs), sizeof(struct pt_regs)); \
- memset((char *)(gregs) + sizeof(struct pt_regs), 0, \
- sizeof(elf_gregset_t) - sizeof(struct pt_regs));
-
-#define ELF_CORE_COPY_TASK_REGS(t, elfregs) \
- ((t)->thread.regs? \
- ({ ELF_CORE_COPY_REGS((elfregs), (t)->thread.regs); 1; }): 0)
-
-extern int dump_task_fpu(struct task_struct *t, elf_fpregset_t *fpu);
-#define ELF_CORE_COPY_FPREGS(t, fpu) dump_task_fpu((t), (fpu))
-
-/* This yields a mask that user programs can use to figure out what
- instruction set this cpu supports. This could be done in userspace,
- but it's not easy, and we've already done it here. */
-
-#define ELF_HWCAP (cur_cpu_spec[0]->cpu_user_features)
-
-/* This yields a string that ld.so will use to load implementation
- specific libraries for optimization. This is more specific in
- intent than poking at uname or /proc/cpuinfo.
-
- For the moment, we have only optimizations for the Intel generations,
- but that could change... */
-
-#define ELF_PLATFORM (NULL)
-
-#define SET_PERSONALITY(ex, ibcs2) set_personality((ibcs2)?PER_SVR4:PER_LINUX)
-
-extern int dcache_bsize;
-extern int icache_bsize;
-extern int ucache_bsize;
-
-/*
- * The requirements here are:
- * - keep the final alignment of sp (sp & 0xf)
- * - make sure the 32-bit value at the first 16 byte aligned position of
- * AUXV is greater than 16 for glibc compatibility.
- * AT_IGNOREPPC is used for that.
- * - for compatibility with glibc ARCH_DLINFO must always be defined on PPC,
- * even if DLINFO_ARCH_ITEMS goes to zero or is undefined.
- */
-#define ARCH_DLINFO \
-do { \
- /* Handle glibc compatibility. */ \
- NEW_AUX_ENT(AT_IGNOREPPC, AT_IGNOREPPC); \
- NEW_AUX_ENT(AT_IGNOREPPC, AT_IGNOREPPC); \
- /* Cache size items */ \
- NEW_AUX_ENT(AT_DCACHEBSIZE, dcache_bsize); \
- NEW_AUX_ENT(AT_ICACHEBSIZE, icache_bsize); \
- NEW_AUX_ENT(AT_UCACHEBSIZE, ucache_bsize); \
- } while (0)
-
-#endif /* __KERNEL__ */
-#endif
diff --git a/include/asm-ppc/futex.h b/include/asm-ppc/futex.h
deleted file mode 100644
index 9feff4ce1424..000000000000
--- a/include/asm-ppc/futex.h
+++ /dev/null
@@ -1,53 +0,0 @@
-#ifndef _ASM_FUTEX_H
-#define _ASM_FUTEX_H
-
-#ifdef __KERNEL__
-
-#include <linux/futex.h>
-#include <asm/errno.h>
-#include <asm/uaccess.h>
-
-static inline int
-futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
-{
- int op = (encoded_op >> 28) & 7;
- int cmp = (encoded_op >> 24) & 15;
- int oparg = (encoded_op << 8) >> 20;
- int cmparg = (encoded_op << 20) >> 20;
- int oldval = 0, ret;
- if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
- oparg = 1 << oparg;
-
- if (! access_ok (VERIFY_WRITE, uaddr, sizeof(int)))
- return -EFAULT;
-
- inc_preempt_count();
-
- switch (op) {
- case FUTEX_OP_SET:
- case FUTEX_OP_ADD:
- case FUTEX_OP_OR:
- case FUTEX_OP_ANDN:
- case FUTEX_OP_XOR:
- default:
- ret = -ENOSYS;
- }
-
- dec_preempt_count();
-
- if (!ret) {
- switch (cmp) {
- case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break;
- case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break;
- case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break;
- case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break;
- case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break;
- case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break;
- default: ret = -ENOSYS;
- }
- }
- return ret;
-}
-
-#endif
-#endif
diff --git a/include/asm-ppc/hw_irq.h b/include/asm-ppc/hw_irq.h
deleted file mode 100644
index 47dc7990fb26..000000000000
--- a/include/asm-ppc/hw_irq.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (C) 1999 Cort Dougan <cort@cs.nmt.edu>
- */
-#ifdef __KERNEL__
-#ifndef _PPC_HW_IRQ_H
-#define _PPC_HW_IRQ_H
-
-#include <asm/ptrace.h>
-#include <asm/reg.h>
-
-extern void timer_interrupt(struct pt_regs *);
-
-#define INLINE_IRQS
-
-#define irqs_disabled() ((mfmsr() & MSR_EE) == 0)
-
-#ifdef INLINE_IRQS
-
-static inline void local_irq_disable(void)
-{
- unsigned long msr;
- msr = mfmsr();
- mtmsr(msr & ~MSR_EE);
- __asm__ __volatile__("": : :"memory");
-}
-
-static inline void local_irq_enable(void)
-{
- unsigned long msr;
- __asm__ __volatile__("": : :"memory");
- msr = mfmsr();
- mtmsr(msr | MSR_EE);
-}
-
-static inline void local_irq_save_ptr(unsigned long *flags)
-{
- unsigned long msr;
- msr = mfmsr();
- *flags = msr;
- mtmsr(msr & ~MSR_EE);
- __asm__ __volatile__("": : :"memory");
-}
-
-#define local_save_flags(flags) ((flags) = mfmsr())
-#define local_irq_save(flags) local_irq_save_ptr(&flags)
-#define local_irq_restore(flags) mtmsr(flags)
-
-#else
-
-extern void local_irq_enable(void);
-extern void local_irq_disable(void);
-extern void local_irq_restore(unsigned long);
-extern void local_save_flags_ptr(unsigned long *);
-
-#define local_save_flags(flags) local_save_flags_ptr(&flags)
-#define local_irq_save(flags) ({local_save_flags(flags);local_irq_disable();})
-
-#endif
-
-extern void do_lost_interrupts(unsigned long);
-
-#define mask_irq(irq) ({if (irq_desc[irq].handler && irq_desc[irq].handler->disable) irq_desc[irq].handler->disable(irq);})
-#define unmask_irq(irq) ({if (irq_desc[irq].handler && irq_desc[irq].handler->enable) irq_desc[irq].handler->enable(irq);})
-#define ack_irq(irq) ({if (irq_desc[irq].handler && irq_desc[irq].handler->ack) irq_desc[irq].handler->ack(irq);})
-
-/* Should we handle this via lost interrupts and IPIs or should we don't care like
- * we do now ? --BenH.
- */
-struct hw_interrupt_type;
-static inline void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i) {}
-
-
-#endif /* _PPC_HW_IRQ_H */
-#endif /* __KERNEL__ */
diff --git a/include/asm-ppc/i8259.h b/include/asm-ppc/i8259.h
deleted file mode 100644
index 091b71295de4..000000000000
--- a/include/asm-ppc/i8259.h
+++ /dev/null
@@ -1,11 +0,0 @@
-#ifndef _PPC_KERNEL_i8259_H
-#define _PPC_KERNEL_i8259_H
-
-#include <linux/irq.h>
-
-extern struct hw_interrupt_type i8259_pic;
-
-extern void i8259_init(long intack_addr);
-extern int i8259_irq(struct pt_regs *regs);
-
-#endif /* _PPC_KERNEL_i8259_H */
diff --git a/include/asm-ppc/ibm44x.h b/include/asm-ppc/ibm44x.h
index e5374be86aef..f835066fb3ca 100644
--- a/include/asm-ppc/ibm44x.h
+++ b/include/asm-ppc/ibm44x.h
@@ -34,12 +34,20 @@
/* Lowest TLB slot consumed by the default pinned TLBs */
#define PPC44x_LOW_SLOT 63
-/* LS 32-bits of UART0 physical address location for early serial text debug */
+/*
+ * Least significant 32-bits and extended real page number (ERPN) of
+ * UART0 physical address location for early serial text debug
+ */
#if defined(CONFIG_440SP)
+#define UART0_PHYS_ERPN 1
+#define UART0_PHYS_IO_BASE 0xf0000200
+#elif defined(CONFIG_440SPE)
+#define UART0_PHYS_ERPN 4
#define UART0_PHYS_IO_BASE 0xf0000200
#elif defined(CONFIG_440EP)
#define UART0_PHYS_IO_BASE 0xe0000000
#else
+#define UART0_PHYS_ERPN 1
#define UART0_PHYS_IO_BASE 0x40000200
#endif
@@ -56,6 +64,11 @@
#define PPC44x_PCICFG_PAGE 0x0000000900000000ULL
#define PPC44x_PCIIO_PAGE PPC44x_PCICFG_PAGE
#define PPC44x_PCIMEM_PAGE 0x0000000a00000000ULL
+#elif defined(CONFIG_440SPE)
+#define PPC44x_IO_PAGE 0x0000000400000000ULL
+#define PPC44x_PCICFG_PAGE 0x0000000c00000000ULL
+#define PPC44x_PCIIO_PAGE PPC44x_PCICFG_PAGE
+#define PPC44x_PCIMEM_PAGE 0x0000000d00000000ULL
#elif defined(CONFIG_440EP)
#define PPC44x_IO_PAGE 0x0000000000000000ULL
#define PPC44x_PCICFG_PAGE 0x0000000000000000ULL
@@ -71,7 +84,7 @@
/*
* 36-bit trap ranges
*/
-#if defined(CONFIG_440SP)
+#if defined(CONFIG_440SP) || defined(CONFIG_440SPE)
#define PPC44x_IO_LO 0xf0000000UL
#define PPC44x_IO_HI 0xf0000fffUL
#define PPC44x_PCI0CFG_LO 0x0ec00000UL
@@ -109,7 +122,7 @@
*/
-/* CPRs (440GX and 440SP) */
+/* CPRs (440GX and 440SP/440SPe) */
#define DCRN_CPR_CONFIG_ADDR 0xc
#define DCRN_CPR_CONFIG_DATA 0xd
@@ -130,7 +143,7 @@
mtdcr(DCRN_CPR_CONFIG_ADDR, offset); \
mtdcr(DCRN_CPR_CONFIG_DATA, data);})
-/* SDRs (440GX and 440SP) */
+/* SDRs (440GX and 440SP/440SPe) */
#define DCRN_SDR_CONFIG_ADDR 0xe
#define DCRN_SDR_CONFIG_DATA 0xf
#define DCRN_SDR_PFC0 0x4100
@@ -180,7 +193,7 @@
mtdcr(DCRN_SDR_CONFIG_ADDR, offset); \
mtdcr(DCRN_SDR_CONFIG_DATA,data);})
-/* DMA (excluding 440SP) */
+/* DMA (excluding 440SP/440SPe) */
#define DCRN_DMA0_BASE 0x100
#define DCRN_DMA1_BASE 0x108
#define DCRN_DMA2_BASE 0x110
@@ -200,12 +213,20 @@
/* UIC */
#define DCRN_UIC0_BASE 0xc0
#define DCRN_UIC1_BASE 0xd0
-#define DCRN_UIC2_BASE 0x210
-#define DCRN_UICB_BASE 0x200
#define UIC0 DCRN_UIC0_BASE
#define UIC1 DCRN_UIC1_BASE
+
+#ifdef CONFIG_440SPE
+#define DCRN_UIC2_BASE 0xe0
+#define DCRN_UIC3_BASE 0xf0
+#define UIC2 DCRN_UIC2_BASE
+#define UIC3 DCRN_UIC3_BASE
+#else
+#define DCRN_UIC2_BASE 0x210
+#define DCRN_UICB_BASE 0x200
#define UIC2 DCRN_UIC2_BASE
#define UICB DCRN_UICB_BASE
+#endif
#define DCRN_UIC_SR(base) (base + 0x0)
#define DCRN_UIC_ER(base) (base + 0x2)
@@ -218,6 +239,12 @@
#define UIC0_UIC1NC 0x00000002
+#ifdef CONFIG_440SPE
+#define UIC0_UIC1NC 0x00000002
+#define UIC0_UIC2NC 0x00200000
+#define UIC0_UIC3NC 0x00008000
+#endif
+
#define UICB_UIC0NC 0x40000000
#define UICB_UIC1NC 0x10000000
#define UICB_UIC2NC 0x04000000
@@ -297,6 +324,23 @@
#define MALOBISR_CH0 0x80000000 /* EOB channel 1 bit */
#define MALOBISR_CH2 0x40000000 /* EOB channel 2 bit */
+#if defined(CONFIG_440SP) || defined(CONFIG_440SPE)
+/* 440SP/440SPe PLB Arbiter DCRs */
+#define DCRN_PLB_REVID 0x080 /* PLB Revision ID */
+#define DCRN_PLB_CCR 0x088 /* PLB Crossbar Control */
+
+#define DCRN_PLB0_ACR 0x081 /* PLB Arbiter Control */
+#define DCRN_PLB0_BESRL 0x082 /* PLB Error Status */
+#define DCRN_PLB0_BESRH 0x083 /* PLB Error Status */
+#define DCRN_PLB0_BEARL 0x084 /* PLB Error Address Low */
+#define DCRN_PLB0_BEARH 0x085 /* PLB Error Address High */
+
+#define DCRN_PLB1_ACR 0x089 /* PLB Arbiter Control */
+#define DCRN_PLB1_BESRL 0x08a /* PLB Error Status */
+#define DCRN_PLB1_BESRH 0x08b /* PLB Error Status */
+#define DCRN_PLB1_BEARL 0x08c /* PLB Error Address Low */
+#define DCRN_PLB1_BEARH 0x08d /* PLB Error Address High */
+#else
/* 440GP/GX PLB Arbiter DCRs */
#define DCRN_PLB0_REVID 0x082 /* PLB Arbiter Revision ID */
#define DCRN_PLB0_ACR 0x083 /* PLB Arbiter Control */
@@ -304,6 +348,7 @@
#define DCRN_PLB0_BEARL 0x086 /* PLB Error Address Low */
#define DCRN_PLB0_BEAR DCRN_PLB0_BEARL /* 40x compatibility */
#define DCRN_PLB0_BEARH 0x087 /* PLB Error Address High */
+#endif
/* 440GP/GX PLB to OPB bridge DCRs */
#define DCRN_POB0_BESR0 0x090
@@ -407,9 +452,13 @@
#define PPC44x_MEM_SIZE_1G 0x40000000
#define PPC44x_MEM_SIZE_2G 0x80000000
-/* 440SP memory controller DCRs */
+/* 440SP/440SPe memory controller DCRs */
#define DCRN_MQ0_BS0BAS 0x40
-#define DCRN_MQ0_BS1BAS 0x41
+#if defined(CONFIG_440SP)
+#define MQ0_NUM_BANKS 2
+#elif defined(CONFIG_440SPE)
+#define MQ0_NUM_BANKS 4
+#endif
#define MQ0_CONFIG_SIZE_MASK 0x0000fff0
#define MQ0_CONFIG_SIZE_8M 0x0000ffc0
@@ -421,8 +470,9 @@
#define MQ0_CONFIG_SIZE_512M 0x0000f000
#define MQ0_CONFIG_SIZE_1G 0x0000e000
#define MQ0_CONFIG_SIZE_2G 0x0000c000
+#define MQ0_CONFIG_SIZE_4G 0x00008000
-/* Internal SRAM Controller 440GX/440SP */
+/* Internal SRAM Controller 440GX/440SP/440SPe */
#define DCRN_SRAM0_BASE 0x000
#define DCRN_SRAM0_SB0CR (DCRN_SRAM0_BASE + 0x020)
@@ -446,7 +496,7 @@
#define DCRN_SRAM0_DPC (DCRN_SRAM0_BASE + 0x02a)
#define SRAM_DPC_ENABLE 0x80000000
-/* L2 Cache Controller 440GX/440SP */
+/* L2 Cache Controller 440GX/440SP/440SPe */
#define DCRN_L2C0_CFG 0x030
#define L2C_CFG_L2M 0x80000000
#define L2C_CFG_ICU 0x40000000
@@ -610,8 +660,10 @@
#define IIC_CLOCK 50
#undef NR_UICS
-#ifdef CONFIG_440GX
+#if defined(CONFIG_440GX)
#define NR_UICS 3
+#elif defined(CONFIG_440SPE)
+#define NR_UICS 4
#else
#define NR_UICS 2
#endif
diff --git a/include/asm-ppc/ibm4xx.h b/include/asm-ppc/ibm4xx.h
index e992369cb8e9..6c28ae7807f4 100644
--- a/include/asm-ppc/ibm4xx.h
+++ b/include/asm-ppc/ibm4xx.h
@@ -97,6 +97,10 @@ void ppc4xx_init(unsigned long r3, unsigned long r4, unsigned long r5,
#include <platforms/4xx/luan.h>
#endif
+#if defined(CONFIG_YUCCA)
+#include <platforms/4xx/yucca.h>
+#endif
+
#if defined(CONFIG_OCOTEA)
#include <platforms/4xx/ocotea.h>
#endif
diff --git a/include/asm-ppc/ibm_ocp.h b/include/asm-ppc/ibm_ocp.h
index 6f10a25bd628..9c21de1ff4ed 100644
--- a/include/asm-ppc/ibm_ocp.h
+++ b/include/asm-ppc/ibm_ocp.h
@@ -131,9 +131,22 @@ static inline void ibm_ocp_set_emac(int start, int end)
/* Copy MAC addresses to EMAC additions */
for (i=start; i<=end; i++) {
def = ocp_get_one_device(OCP_VENDOR_IBM, OCP_FUNC_EMAC, i);
- memcpy(((struct ocp_func_emac_data *)def->additions)->mac_addr,
- &__res.bi_enetaddr[i],
- 6);
+ if (i == 0)
+ memcpy(((struct ocp_func_emac_data *)def->additions)->mac_addr,
+ __res.bi_enetaddr, 6);
+#if defined(CONFIG_405EP) || defined(CONFIG_44x)
+ else if (i == 1)
+ memcpy(((struct ocp_func_emac_data *)def->additions)->mac_addr,
+ __res.bi_enet1addr, 6);
+#endif
+#if defined(CONFIG_440GX)
+ else if (i == 2)
+ memcpy(((struct ocp_func_emac_data *)def->additions)->mac_addr,
+ __res.bi_enet2addr, 6);
+ else if (i == 3)
+ memcpy(((struct ocp_func_emac_data *)def->additions)->mac_addr,
+ __res.bi_enet3addr, 6);
+#endif
}
}
#endif
diff --git a/include/asm-ppc/io.h b/include/asm-ppc/io.h
index 94d83998a759..2bfdf9c98459 100644
--- a/include/asm-ppc/io.h
+++ b/include/asm-ppc/io.h
@@ -8,6 +8,7 @@
#include <asm/page.h>
#include <asm/byteorder.h>
+#include <asm/synch.h>
#include <asm/mmu.h>
#define SIO_CONFIG_RA 0x398
@@ -236,9 +237,9 @@ static inline void __raw_writel(__u32 b, volatile void __iomem *addr)
#define outsl(port, buf, nl) _outsl_ns((port)+___IO_BASE, (buf), (nl))
/*
- * On powermacs, we will get a machine check exception if we
- * try to read data from a non-existent I/O port. Because the
- * machine check is an asynchronous exception, it isn't
+ * On powermacs and 8xx we will get a machine check exception
+ * if we try to read data from a non-existent I/O port. Because
+ * the machine check is an asynchronous exception, it isn't
* well-defined which instruction SRR0 will point to when the
* exception occurs.
* With the sequence below (twi; isync; nop), we have found that
@@ -257,7 +258,7 @@ extern __inline__ unsigned int name(unsigned int port) \
{ \
unsigned int x; \
__asm__ __volatile__( \
- op " %0,0,%1\n" \
+ "0:" op " %0,0,%1\n" \
"1: twi 0,%0,0\n" \
"2: isync\n" \
"3: nop\n" \
@@ -268,6 +269,7 @@ extern __inline__ unsigned int name(unsigned int port) \
".previous\n" \
".section __ex_table,\"a\"\n" \
" .align 2\n" \
+ " .long 0b,5b\n" \
" .long 1b,5b\n" \
" .long 2b,5b\n" \
" .long 3b,5b\n" \
@@ -281,11 +283,12 @@ extern __inline__ unsigned int name(unsigned int port) \
extern __inline__ void name(unsigned int val, unsigned int port) \
{ \
__asm__ __volatile__( \
- op " %0,0,%1\n" \
+ "0:" op " %0,0,%1\n" \
"1: sync\n" \
"2:\n" \
".section __ex_table,\"a\"\n" \
" .align 2\n" \
+ " .long 0b,2b\n" \
" .long 1b,2b\n" \
".previous" \
: : "r" (val), "r" (port + ___IO_BASE)); \
@@ -440,16 +443,6 @@ extern inline void * phys_to_virt(unsigned long address)
#define page_to_phys(page) (page_to_pfn(page) << PAGE_SHIFT)
#define page_to_bus(page) (page_to_phys(page) + PCI_DRAM_OFFSET)
-/*
- * Enforce In-order Execution of I/O:
- * Acts as a barrier to ensure all previous I/O accesses have
- * completed before any further ones are issued.
- */
-extern inline void eieio(void)
-{
- __asm__ __volatile__ ("eieio" : : : "memory");
-}
-
/* Enforce in-order execution of data I/O.
* No distinction between read/write on PPC; use eieio for all three.
*/
diff --git a/include/asm-ppc/ipcbuf.h b/include/asm-ppc/ipcbuf.h
deleted file mode 100644
index fab6752c7480..000000000000
--- a/include/asm-ppc/ipcbuf.h
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef __PPC_IPCBUF_H__
-#define __PPC_IPCBUF_H__
-
-/*
- * The ipc64_perm structure for PPC architecture.
- * Note extra padding because this structure is passed back and forth
- * between kernel and user space.
- *
- * Pad space is left for:
- * - 1 32-bit value to fill up for 8-byte alignment
- * - 2 miscellaneous 64-bit values (so that this structure matches
- * PPC64 ipc64_perm)
- */
-
-struct ipc64_perm
-{
- __kernel_key_t key;
- __kernel_uid_t uid;
- __kernel_gid_t gid;
- __kernel_uid_t cuid;
- __kernel_gid_t cgid;
- __kernel_mode_t mode;
- unsigned long seq;
- unsigned int __pad2;
- unsigned long long __unused1;
- unsigned long long __unused2;
-};
-
-#endif /* __PPC_IPCBUF_H__ */
diff --git a/include/asm-ppc/kexec.h b/include/asm-ppc/kexec.h
deleted file mode 100644
index 6d2aa0aa4642..000000000000
--- a/include/asm-ppc/kexec.h
+++ /dev/null
@@ -1,40 +0,0 @@
-#ifndef _PPC_KEXEC_H
-#define _PPC_KEXEC_H
-
-#ifdef CONFIG_KEXEC
-
-/*
- * KEXEC_SOURCE_MEMORY_LIMIT maximum page get_free_page can return.
- * I.e. Maximum page that is mapped directly into kernel memory,
- * and kmap is not required.
- *
- * Someone correct me if FIXADDR_START - PAGEOFFSET is not the correct
- * calculation for the amount of memory directly mappable into the
- * kernel memory space.
- */
-
-/* Maximum physical address we can use pages from */
-#define KEXEC_SOURCE_MEMORY_LIMIT (-1UL)
-/* Maximum address we can reach in physical address mode */
-#define KEXEC_DESTINATION_MEMORY_LIMIT (-1UL)
-/* Maximum address we can use for the control code buffer */
-#define KEXEC_CONTROL_MEMORY_LIMIT TASK_SIZE
-
-#define KEXEC_CONTROL_CODE_SIZE 4096
-
-/* The native architecture */
-#define KEXEC_ARCH KEXEC_ARCH_PPC
-
-#ifndef __ASSEMBLY__
-
-extern void *crash_notes;
-
-struct kimage;
-
-extern void machine_kexec_simple(struct kimage *image);
-
-#endif /* __ASSEMBLY__ */
-
-#endif /* CONFIG_KEXEC */
-
-#endif /* _PPC_KEXEC_H */
diff --git a/include/asm-ppc/kgdb.h b/include/asm-ppc/kgdb.h
index 1d3c927ce626..b617dac82969 100644
--- a/include/asm-ppc/kgdb.h
+++ b/include/asm-ppc/kgdb.h
@@ -31,7 +31,7 @@ extern void breakpoint(void);
/* For taking exceptions
* these are defined in traps.c
*/
-extern void (*debugger)(struct pt_regs *regs);
+extern int (*debugger)(struct pt_regs *regs);
extern int (*debugger_bpt)(struct pt_regs *regs);
extern int (*debugger_sstep)(struct pt_regs *regs);
extern int (*debugger_iabr_match)(struct pt_regs *regs);
diff --git a/include/asm-ppc/kmap_types.h b/include/asm-ppc/kmap_types.h
deleted file mode 100644
index 6d6fc78731e5..000000000000
--- a/include/asm-ppc/kmap_types.h
+++ /dev/null
@@ -1,25 +0,0 @@
-#ifdef __KERNEL__
-#ifndef _ASM_KMAP_TYPES_H
-#define _ASM_KMAP_TYPES_H
-
-enum km_type {
- KM_BOUNCE_READ,
- KM_SKB_SUNRPC_DATA,
- KM_SKB_DATA_SOFTIRQ,
- KM_USER0,
- KM_USER1,
- KM_BIO_SRC_IRQ,
- KM_BIO_DST_IRQ,
- KM_PTE0,
- KM_PTE1,
- KM_IRQ0,
- KM_IRQ1,
- KM_SOFTIRQ0,
- KM_SOFTIRQ1,
- KM_PPC_SYNC_PAGE,
- KM_PPC_SYNC_ICACHE,
- KM_TYPE_NR
-};
-
-#endif
-#endif /* __KERNEL__ */
diff --git a/include/asm-ppc/machdep.h b/include/asm-ppc/machdep.h
index 1d4ab70a56f3..f01255bd1dc3 100644
--- a/include/asm-ppc/machdep.h
+++ b/include/asm-ppc/machdep.h
@@ -98,7 +98,7 @@ struct machdep_calls {
/* Get access protection for /dev/mem */
pgprot_t (*phys_mem_access_prot)(struct file *file,
- unsigned long offset,
+ unsigned long pfn,
unsigned long size,
pgprot_t vma_prot);
@@ -167,7 +167,7 @@ extern sys_ctrler_t sys_ctrler;
#ifdef CONFIG_SMP
struct smp_ops_t {
- void (*message_pass)(int target, int msg, unsigned long data, int wait);
+ void (*message_pass)(int target, int msg);
int (*probe)(void);
void (*kick_cpu)(int nr);
void (*setup_cpu)(int nr);
diff --git a/include/asm-ppc/mmu_context.h b/include/asm-ppc/mmu_context.h
index afe26ffc2e2d..4f152cca13c1 100644
--- a/include/asm-ppc/mmu_context.h
+++ b/include/asm-ppc/mmu_context.h
@@ -164,13 +164,11 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
struct task_struct *tsk)
{
#ifdef CONFIG_ALTIVEC
- asm volatile (
- BEGIN_FTR_SECTION
- "dssall;\n"
+ if (cpu_has_feature(CPU_FTR_ALTIVEC))
+ asm volatile ("dssall;\n"
#ifndef CONFIG_POWER4
"sync;\n" /* G4 needs a sync here, G5 apparently not */
#endif
- END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
: : );
#endif /* CONFIG_ALTIVEC */
diff --git a/include/asm-ppc/mpc8260.h b/include/asm-ppc/mpc8260.h
index 9694eca16e92..321452695039 100644
--- a/include/asm-ppc/mpc8260.h
+++ b/include/asm-ppc/mpc8260.h
@@ -92,6 +92,10 @@ enum ppc_sys_devices {
extern unsigned char __res[];
#endif
+#ifndef BOARD_CHIP_NAME
+#define BOARD_CHIP_NAME ""
+#endif
+
#endif /* CONFIG_8260 */
#endif /* !__ASM_PPC_MPC8260_H__ */
#endif /* __KERNEL__ */
diff --git a/include/asm-ppc/mpc83xx.h b/include/asm-ppc/mpc83xx.h
index bb1b0576c947..ce212201db2a 100644
--- a/include/asm-ppc/mpc83xx.h
+++ b/include/asm-ppc/mpc83xx.h
@@ -107,6 +107,7 @@ enum ppc_sys_devices {
MPC83xx_SEC2,
MPC83xx_USB2_DR,
MPC83xx_USB2_MPH,
+ MPC83xx_MDIO,
};
#endif /* CONFIG_83xx */
diff --git a/include/asm-ppc/mpc85xx.h b/include/asm-ppc/mpc85xx.h
index 516984ee14b5..d98db980cd49 100644
--- a/include/asm-ppc/mpc85xx.h
+++ b/include/asm-ppc/mpc85xx.h
@@ -67,6 +67,8 @@ extern unsigned char __res[];
#define MPC85xx_DMA3_SIZE (0x00080)
#define MPC85xx_ENET1_OFFSET (0x24000)
#define MPC85xx_ENET1_SIZE (0x01000)
+#define MPC85xx_MIIM_OFFSET (0x24520)
+#define MPC85xx_MIIM_SIZE (0x00018)
#define MPC85xx_ENET2_OFFSET (0x25000)
#define MPC85xx_ENET2_SIZE (0x01000)
#define MPC85xx_ENET3_OFFSET (0x26000)
@@ -132,6 +134,7 @@ enum ppc_sys_devices {
MPC85xx_eTSEC3,
MPC85xx_eTSEC4,
MPC85xx_IIC2,
+ MPC85xx_MDIO,
};
/* Internal interrupts are all Level Sensitive, and Positive Polarity */
diff --git a/include/asm-ppc/mpc8xx.h b/include/asm-ppc/mpc8xx.h
index 208a2e11daee..46f159cf589e 100644
--- a/include/asm-ppc/mpc8xx.h
+++ b/include/asm-ppc/mpc8xx.h
@@ -113,6 +113,10 @@ enum ppc_sys_devices {
MPC8xx_CPM_USB,
};
+#ifndef BOARD_CHIP_NAME
+#define BOARD_CHIP_NAME ""
+#endif
+
#endif /* !__ASSEMBLY__ */
#endif /* CONFIG_8xx */
#endif /* __CONFIG_8xx_DEFS */
diff --git a/include/asm-ppc/mv64x60.h b/include/asm-ppc/mv64x60.h
index ee2f9188cc64..4f2405b83612 100644
--- a/include/asm-ppc/mv64x60.h
+++ b/include/asm-ppc/mv64x60.h
@@ -27,6 +27,8 @@
#include <asm/pci-bridge.h>
#include <asm/mv64x60_defs.h>
+struct platform_device;
+
extern u8 mv64x60_pci_exclude_bridge;
extern spinlock_t mv64x60_lock;
diff --git a/include/asm-ppc/open_pic.h b/include/asm-ppc/open_pic.h
index 7848aa610c05..ec2f46629ca2 100644
--- a/include/asm-ppc/open_pic.h
+++ b/include/asm-ppc/open_pic.h
@@ -58,8 +58,7 @@ extern int openpic_get_irq(struct pt_regs *regs);
extern void openpic_reset_processor_phys(u_int cpumask);
extern void openpic_setup_ISU(int isu_num, unsigned long addr);
extern void openpic_cause_IPI(u_int ipi, cpumask_t cpumask);
-extern void smp_openpic_message_pass(int target, int msg, unsigned long data,
- int wait);
+extern void smp_openpic_message_pass(int target, int msg);
extern void openpic_set_k2_cascade(int irq);
extern void openpic_set_priority(u_int pri);
extern u_int openpic_get_priority(void);
diff --git a/include/asm-ppc/page.h b/include/asm-ppc/page.h
index 4789dc024240..fc44f7ca62d7 100644
--- a/include/asm-ppc/page.h
+++ b/include/asm-ppc/page.h
@@ -34,6 +34,17 @@ typedef unsigned long pte_basic_t;
#define PTE_FMT "%.8lx"
#endif
+/* align addr on a size boundary - adjust address up/down if needed */
+#define _ALIGN_UP(addr,size) (((addr)+((size)-1))&(~((size)-1)))
+#define _ALIGN_DOWN(addr,size) ((addr)&(~((size)-1)))
+
+/* align addr on a size boundary - adjust address up if needed */
+#define _ALIGN(addr,size) _ALIGN_UP(addr,size)
+
+/* to align the pointer to the (next) page boundary */
+#define PAGE_ALIGN(addr) _ALIGN(addr, PAGE_SIZE)
+
+
#undef STRICT_MM_TYPECHECKS
#ifdef STRICT_MM_TYPECHECKS
@@ -76,13 +87,6 @@ typedef unsigned long pgprot_t;
#endif
-
-/* align addr on a size boundary - adjust address up if needed -- Cort */
-#define _ALIGN(addr,size) (((addr)+(size)-1)&(~((size)-1)))
-
-/* to align the pointer to the (next) page boundary */
-#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK)
-
struct page;
extern void clear_pages(void *page, int order);
static inline void clear_page(void *page) { clear_pages(page, 0); }
diff --git a/include/asm-ppc/pci-bridge.h b/include/asm-ppc/pci-bridge.h
index ffa423456c2b..e58c78f90a5a 100644
--- a/include/asm-ppc/pci-bridge.h
+++ b/include/asm-ppc/pci-bridge.h
@@ -79,6 +79,11 @@ struct pci_controller {
struct resource mem_space;
};
+static inline struct pci_controller *pci_bus_to_host(struct pci_bus *bus)
+{
+ return bus->sysdata;
+}
+
/* These are used for config access before all the PCI probing
has been done. */
int early_read_config_byte(struct pci_controller *hose, int bus, int dev_fn,
diff --git a/include/asm-ppc/pci.h b/include/asm-ppc/pci.h
index 9dd06cd40096..61434edbad7b 100644
--- a/include/asm-ppc/pci.h
+++ b/include/asm-ppc/pci.h
@@ -24,9 +24,9 @@ struct pci_dev;
* Set this to 1 if you want the kernel to re-assign all PCI
* bus numbers
*/
-extern int pci_assign_all_busses;
+extern int pci_assign_all_buses;
-#define pcibios_assign_all_busses() (pci_assign_all_busses)
+#define pcibios_assign_all_busses() (pci_assign_all_buses)
#define pcibios_scan_all_fns(a, b) 0
#define PCIBIOS_MIN_IO 0x1000
@@ -126,7 +126,7 @@ extern void pcibios_add_platform_entries(struct pci_dev *dev);
struct file;
extern pgprot_t pci_phys_mem_access_prot(struct file *file,
- unsigned long offset,
+ unsigned long pfn,
unsigned long size,
pgprot_t prot);
diff --git a/include/asm-ppc/perfmon.h b/include/asm-ppc/perfmon.h
deleted file mode 100644
index 5e7a89c47b5b..000000000000
--- a/include/asm-ppc/perfmon.h
+++ /dev/null
@@ -1,22 +0,0 @@
-#ifndef __PERFMON_H
-#define __PERFMON_H
-
-extern void (*perf_irq)(struct pt_regs *);
-
-int request_perfmon_irq(void (*handler)(struct pt_regs *));
-void free_perfmon_irq(void);
-
-#ifdef CONFIG_FSL_BOOKE
-void init_pmc_stop(int ctr);
-void set_pmc_event(int ctr, int event);
-void set_pmc_user_kernel(int ctr, int user, int kernel);
-void set_pmc_marked(int ctr, int mark0, int mark1);
-void pmc_start_ctr(int ctr, int enable);
-void pmc_start_ctrs(int enable);
-void pmc_stop_ctrs(void);
-void dump_pmcs(void);
-
-extern struct op_ppc32_model op_model_fsl_booke;
-#endif
-
-#endif /* __PERFMON_H */
diff --git a/include/asm-ppc/pgtable.h b/include/asm-ppc/pgtable.h
index eee601bb9ada..6d1c39e8a6af 100644
--- a/include/asm-ppc/pgtable.h
+++ b/include/asm-ppc/pgtable.h
@@ -12,6 +12,7 @@
#include <asm/processor.h> /* For TASK_SIZE */
#include <asm/mmu.h>
#include <asm/page.h>
+struct mm_struct;
extern unsigned long va_to_phys(unsigned long address);
extern pte_t *va_to_pte(unsigned long address);
@@ -705,7 +706,7 @@ static inline void __ptep_set_access_flags(pte_t *ptep, pte_t entry, int dirty)
#define pgprot_noncached(prot) (__pgprot(pgprot_val(prot) | _PAGE_NO_CACHE | _PAGE_GUARDED))
struct file;
-extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long addr,
+extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
unsigned long size, pgprot_t vma_prot);
#define __HAVE_PHYS_MEM_ACCESS_PROT
diff --git a/include/asm-ppc/posix_types.h b/include/asm-ppc/posix_types.h
deleted file mode 100644
index a14a82abe8d2..000000000000
--- a/include/asm-ppc/posix_types.h
+++ /dev/null
@@ -1,111 +0,0 @@
-#ifndef _PPC_POSIX_TYPES_H
-#define _PPC_POSIX_TYPES_H
-
-/*
- * This file is generally used by user-level software, so you need to
- * be a little careful about namespace pollution etc. Also, we cannot
- * assume GCC is being used.
- */
-
-typedef unsigned long __kernel_ino_t;
-typedef unsigned int __kernel_mode_t;
-typedef unsigned short __kernel_nlink_t;
-typedef long __kernel_off_t;
-typedef int __kernel_pid_t;
-typedef unsigned int __kernel_uid_t;
-typedef unsigned int __kernel_gid_t;
-typedef unsigned int __kernel_size_t;
-typedef int __kernel_ssize_t;
-typedef long __kernel_ptrdiff_t;
-typedef long __kernel_time_t;
-typedef long __kernel_suseconds_t;
-typedef long __kernel_clock_t;
-typedef int __kernel_timer_t;
-typedef int __kernel_clockid_t;
-typedef int __kernel_daddr_t;
-typedef char * __kernel_caddr_t;
-typedef short __kernel_ipc_pid_t;
-typedef unsigned short __kernel_uid16_t;
-typedef unsigned short __kernel_gid16_t;
-typedef unsigned int __kernel_uid32_t;
-typedef unsigned int __kernel_gid32_t;
-
-typedef unsigned int __kernel_old_uid_t;
-typedef unsigned int __kernel_old_gid_t;
-typedef unsigned int __kernel_old_dev_t;
-
-#ifdef __GNUC__
-typedef long long __kernel_loff_t;
-#endif
-
-typedef struct {
- int val[2];
-} __kernel_fsid_t;
-
-#ifndef __GNUC__
-
-#define __FD_SET(d, set) ((set)->fds_bits[__FDELT(d)] |= __FDMASK(d))
-#define __FD_CLR(d, set) ((set)->fds_bits[__FDELT(d)] &= ~__FDMASK(d))
-#define __FD_ISSET(d, set) ((set)->fds_bits[__FDELT(d)] & __FDMASK(d))
-#define __FD_ZERO(set) \
- ((void) memset ((__ptr_t) (set), 0, sizeof (__kernel_fd_set)))
-
-#else /* __GNUC__ */
-
-#if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) \
- || (__GLIBC__ == 2 && __GLIBC_MINOR__ == 0)
-/* With GNU C, use inline functions instead so args are evaluated only once: */
-
-#undef __FD_SET
-static __inline__ void __FD_SET(unsigned long fd, __kernel_fd_set *fdsetp)
-{
- unsigned long _tmp = fd / __NFDBITS;
- unsigned long _rem = fd % __NFDBITS;
- fdsetp->fds_bits[_tmp] |= (1UL<<_rem);
-}
-
-#undef __FD_CLR
-static __inline__ void __FD_CLR(unsigned long fd, __kernel_fd_set *fdsetp)
-{
- unsigned long _tmp = fd / __NFDBITS;
- unsigned long _rem = fd % __NFDBITS;
- fdsetp->fds_bits[_tmp] &= ~(1UL<<_rem);
-}
-
-#undef __FD_ISSET
-static __inline__ int __FD_ISSET(unsigned long fd, __kernel_fd_set *p)
-{
- unsigned long _tmp = fd / __NFDBITS;
- unsigned long _rem = fd % __NFDBITS;
- return (p->fds_bits[_tmp] & (1UL<<_rem)) != 0;
-}
-
-/*
- * This will unroll the loop for the normal constant case (8 ints,
- * for a 256-bit fd_set)
- */
-#undef __FD_ZERO
-static __inline__ void __FD_ZERO(__kernel_fd_set *p)
-{
- unsigned int *tmp = (unsigned int *)p->fds_bits;
- int i;
-
- if (__builtin_constant_p(__FDSET_LONGS)) {
- switch (__FDSET_LONGS) {
- case 8:
- tmp[0] = 0; tmp[1] = 0; tmp[2] = 0; tmp[3] = 0;
- tmp[4] = 0; tmp[5] = 0; tmp[6] = 0; tmp[7] = 0;
- return;
- }
- }
- i = __FDSET_LONGS;
- while (i) {
- i--;
- *tmp = 0;
- tmp++;
- }
-}
-
-#endif /* defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) */
-#endif /* __GNUC__ */
-#endif /* _PPC_POSIX_TYPES_H */
diff --git a/include/asm-ppc/ppc_sys.h b/include/asm-ppc/ppc_sys.h
index 549f44843c5e..bba5305c29ed 100644
--- a/include/asm-ppc/ppc_sys.h
+++ b/include/asm-ppc/ppc_sys.h
@@ -18,7 +18,7 @@
#define __ASM_PPC_SYS_H
#include <linux/init.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <linux/types.h>
#if defined(CONFIG_8260)
diff --git a/include/asm-ppc/ppcboot.h b/include/asm-ppc/ppcboot.h
index fe24e4520208..6b7b63f71daa 100644
--- a/include/asm-ppc/ppcboot.h
+++ b/include/asm-ppc/ppcboot.h
@@ -73,8 +73,8 @@ typedef struct bd_info {
#if defined(CONFIG_HYMOD)
hymod_conf_t bi_hymod_conf; /* hymod configuration information */
#endif
-#if defined(CONFIG_EVB64260) || defined(CONFIG_44x) || defined(CONFIG_85xx) ||\
- defined(CONFIG_83xx)
+#if defined(CONFIG_EVB64260) || defined(CONFIG_405EP) || defined(CONFIG_44x) || \
+ defined(CONFIG_85xx) || defined(CONFIG_83xx)
/* second onboard ethernet port */
unsigned char bi_enet1addr[6];
#endif
@@ -96,5 +96,7 @@ typedef struct bd_info {
#endif
} bd_t;
+#define bi_tbfreq bi_intfreq
+
#endif /* __ASSEMBLY__ */
#endif /* __ASM_PPCBOOT_H__ */
diff --git a/include/asm-ppc/processor.h b/include/asm-ppc/processor.h
deleted file mode 100644
index b05b5d9cae20..000000000000
--- a/include/asm-ppc/processor.h
+++ /dev/null
@@ -1,201 +0,0 @@
-#ifdef __KERNEL__
-#ifndef __ASM_PPC_PROCESSOR_H
-#define __ASM_PPC_PROCESSOR_H
-
-/*
- * Default implementation of macro that returns current
- * instruction pointer ("program counter").
- */
-#define current_text_addr() ({ __label__ _l; _l: &&_l;})
-
-#include <linux/config.h>
-#include <linux/stringify.h>
-
-#include <asm/ptrace.h>
-#include <asm/types.h>
-#include <asm/mpc8xx.h>
-#include <asm/reg.h>
-
-/* We only need to define a new _MACH_xxx for machines which are part of
- * a configuration which supports more than one type of different machine.
- * This is currently limited to CONFIG_PPC_MULTIPLATFORM and CHRP/PReP/PMac.
- * -- Tom
- */
-#define _MACH_prep 0x00000001
-#define _MACH_Pmac 0x00000002 /* pmac or pmac clone (non-chrp) */
-#define _MACH_chrp 0x00000004 /* chrp machine */
-
-/* see residual.h for these */
-#define _PREP_Motorola 0x01 /* motorola prep */
-#define _PREP_Firm 0x02 /* firmworks prep */
-#define _PREP_IBM 0x00 /* ibm prep */
-#define _PREP_Bull 0x03 /* bull prep */
-
-/* these are arbitrary */
-#define _CHRP_Motorola 0x04 /* motorola chrp, the cobra */
-#define _CHRP_IBM 0x05 /* IBM chrp, the longtrail and longtrail 2 */
-#define _CHRP_Pegasos 0x06 /* Genesi/bplan's Pegasos and Pegasos2 */
-
-#define _GLOBAL(n)\
- .stabs __stringify(n:F-1),N_FUN,0,0,n;\
- .globl n;\
-n:
-
-/*
- * this is the minimum allowable io space due to the location
- * of the io areas on prep (first one at 0x80000000) but
- * as soon as I get around to remapping the io areas with the BATs
- * to match the mac we can raise this. -- Cort
- */
-#define TASK_SIZE (CONFIG_TASK_SIZE)
-
-#ifndef __ASSEMBLY__
-#ifdef CONFIG_PPC_MULTIPLATFORM
-extern int _machine;
-
-/* what kind of prep workstation we are */
-extern int _prep_type;
-extern int _chrp_type;
-
-/*
- * This is used to identify the board type from a given PReP board
- * vendor. Board revision is also made available.
- */
-extern unsigned char ucSystemType;
-extern unsigned char ucBoardRev;
-extern unsigned char ucBoardRevMaj, ucBoardRevMin;
-#else
-#define _machine 0
-#endif /* CONFIG_PPC_MULTIPLATFORM */
-
-struct task_struct;
-void start_thread(struct pt_regs *regs, unsigned long nip, unsigned long sp);
-void release_thread(struct task_struct *);
-
-/* Prepare to copy thread state - unlazy all lazy status */
-extern void prepare_to_copy(struct task_struct *tsk);
-
-/*
- * Create a new kernel thread.
- */
-extern long kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
-
-/* Lazy FPU handling on uni-processor */
-extern struct task_struct *last_task_used_math;
-extern struct task_struct *last_task_used_altivec;
-extern struct task_struct *last_task_used_spe;
-
-/* This decides where the kernel will search for a free chunk of vm
- * space during mmap's.
- */
-#define TASK_UNMAPPED_BASE (TASK_SIZE / 8 * 3)
-
-typedef struct {
- unsigned long seg;
-} mm_segment_t;
-
-struct thread_struct {
- unsigned long ksp; /* Kernel stack pointer */
- struct pt_regs *regs; /* Pointer to saved register state */
- mm_segment_t fs; /* for get_fs() validation */
- void *pgdir; /* root of page-table tree */
- int fpexc_mode; /* floating-point exception mode */
- signed long last_syscall;
-#if defined(CONFIG_4xx) || defined (CONFIG_BOOKE)
- unsigned long dbcr0; /* debug control register values */
- unsigned long dbcr1;
-#endif
- double fpr[32]; /* Complete floating point set */
- unsigned long fpscr_pad; /* fpr ... fpscr must be contiguous */
- unsigned long fpscr; /* Floating point status */
-#ifdef CONFIG_ALTIVEC
- /* Complete AltiVec register set */
- vector128 vr[32] __attribute((aligned(16)));
- /* AltiVec status */
- vector128 vscr __attribute((aligned(16)));
- unsigned long vrsave;
- int used_vr; /* set if process has used altivec */
-#endif /* CONFIG_ALTIVEC */
-#ifdef CONFIG_SPE
- unsigned long evr[32]; /* upper 32-bits of SPE regs */
- u64 acc; /* Accumulator */
- unsigned long spefscr; /* SPE & eFP status */
- int used_spe; /* set if process has used spe */
-#endif /* CONFIG_SPE */
-};
-
-#define ARCH_MIN_TASKALIGN 16
-
-#define INIT_SP (sizeof(init_stack) + (unsigned long) &init_stack)
-
-#define INIT_THREAD { \
- .ksp = INIT_SP, \
- .fs = KERNEL_DS, \
- .pgdir = swapper_pg_dir, \
- .fpexc_mode = MSR_FE0 | MSR_FE1, \
-}
-
-/*
- * Return saved PC of a blocked thread. For now, this is the "user" PC
- */
-#define thread_saved_pc(tsk) \
- ((tsk)->thread.regs? (tsk)->thread.regs->nip: 0)
-
-unsigned long get_wchan(struct task_struct *p);
-
-#define KSTK_EIP(tsk) ((tsk)->thread.regs? (tsk)->thread.regs->nip: 0)
-#define KSTK_ESP(tsk) ((tsk)->thread.regs? (tsk)->thread.regs->gpr[1]: 0)
-
-/* Get/set floating-point exception mode */
-#define GET_FPEXC_CTL(tsk, adr) get_fpexc_mode((tsk), (adr))
-#define SET_FPEXC_CTL(tsk, val) set_fpexc_mode((tsk), (val))
-
-extern int get_fpexc_mode(struct task_struct *tsk, unsigned long adr);
-extern int set_fpexc_mode(struct task_struct *tsk, unsigned int val);
-
-static inline unsigned int __unpack_fe01(unsigned int msr_bits)
-{
- return ((msr_bits & MSR_FE0) >> 10) | ((msr_bits & MSR_FE1) >> 8);
-}
-
-static inline unsigned int __pack_fe01(unsigned int fpmode)
-{
- return ((fpmode << 10) & MSR_FE0) | ((fpmode << 8) & MSR_FE1);
-}
-
-/* in process.c - for early bootup debug -- Cort */
-int ll_printk(const char *, ...);
-void ll_puts(const char *);
-
-/* In misc.c */
-void _nmask_and_or_msr(unsigned long nmask, unsigned long or_val);
-
-#define have_of (_machine == _MACH_chrp || _machine == _MACH_Pmac)
-
-#define cpu_relax() barrier()
-
-/*
- * Prefetch macros.
- */
-#define ARCH_HAS_PREFETCH
-#define ARCH_HAS_PREFETCHW
-#define ARCH_HAS_SPINLOCK_PREFETCH
-
-extern inline void prefetch(const void *x)
-{
- __asm__ __volatile__ ("dcbt 0,%0" : : "r" (x));
-}
-
-extern inline void prefetchw(const void *x)
-{
- __asm__ __volatile__ ("dcbtst 0,%0" : : "r" (x));
-}
-
-#define spin_lock_prefetch(x) prefetchw(x)
-
-extern int emulate_altivec(struct pt_regs *regs);
-
-#endif /* !__ASSEMBLY__ */
-
-#endif /* __ASM_PPC_PROCESSOR_H */
-#endif /* __KERNEL__ */
diff --git a/include/asm-ppc/prom.h b/include/asm-ppc/prom.h
index 75c0637acdc8..3e39827ed566 100644
--- a/include/asm-ppc/prom.h
+++ b/include/asm-ppc/prom.h
@@ -93,7 +93,7 @@ extern int device_is_compatible(struct device_node *device, const char *);
extern int machine_is_compatible(const char *compat);
extern unsigned char *get_property(struct device_node *node, const char *name,
int *lenp);
-extern void prom_add_property(struct device_node* np, struct property* prop);
+extern int prom_add_property(struct device_node* np, struct property* prop);
extern void prom_get_irq_senses(unsigned char *, int, int);
extern int prom_n_addr_cells(struct device_node* np);
extern int prom_n_size_cells(struct device_node* np);
diff --git a/include/asm-ppc/ptrace.h b/include/asm-ppc/ptrace.h
deleted file mode 100644
index 7043c164b537..000000000000
--- a/include/asm-ppc/ptrace.h
+++ /dev/null
@@ -1,152 +0,0 @@
-#ifndef _PPC_PTRACE_H
-#define _PPC_PTRACE_H
-
-/*
- * This struct defines the way the registers are stored on the
- * kernel stack during a system call or other kernel entry.
- *
- * this should only contain volatile regs
- * since we can keep non-volatile in the thread_struct
- * should set this up when only volatiles are saved
- * by intr code.
- *
- * Since this is going on the stack, *CARE MUST BE TAKEN* to insure
- * that the overall structure is a multiple of 16 bytes in length.
- *
- * Note that the offsets of the fields in this struct correspond with
- * the PT_* values below. This simplifies arch/ppc/kernel/ptrace.c.
- */
-
-#ifndef __ASSEMBLY__
-struct pt_regs {
- unsigned long gpr[32];
- unsigned long nip;
- unsigned long msr;
- unsigned long orig_gpr3; /* Used for restarting system calls */
- unsigned long ctr;
- unsigned long link;
- unsigned long xer;
- unsigned long ccr;
- unsigned long mq; /* 601 only (not used at present) */
- /* Used on APUS to hold IPL value. */
- unsigned long trap; /* Reason for being here */
- /* N.B. for critical exceptions on 4xx, the dar and dsisr
- fields are overloaded to hold srr0 and srr1. */
- unsigned long dar; /* Fault registers */
- unsigned long dsisr; /* on 4xx/Book-E used for ESR */
- unsigned long result; /* Result of a system call */
-};
-
-#endif /* __ASSEMBLY__ */
-
-#ifdef __KERNEL__
-#define STACK_FRAME_OVERHEAD 16 /* size of minimum stack frame */
-
-/* Size of stack frame allocated when calling signal handler. */
-#define __SIGNAL_FRAMESIZE 64
-
-#ifndef __ASSEMBLY__
-#define instruction_pointer(regs) ((regs)->nip)
-#ifdef CONFIG_SMP
-extern unsigned long profile_pc(struct pt_regs *regs);
-#else
-#define profile_pc(regs) instruction_pointer(regs)
-#endif
-
-#define user_mode(regs) (((regs)->msr & MSR_PR) != 0)
-
-#define force_successful_syscall_return() \
- do { \
- current_thread_info()->local_flags |= _TIFL_FORCE_NOERROR; \
- } while(0)
-
-/*
- * We use the least-significant bit of the trap field to indicate
- * whether we have saved the full set of registers, or only a
- * partial set. A 1 there means the partial set.
- * On 4xx we use the next bit to indicate whether the exception
- * is a critical exception (1 means it is).
- */
-#define FULL_REGS(regs) (((regs)->trap & 1) == 0)
-#define IS_CRITICAL_EXC(regs) (((regs)->trap & 2) == 0)
-#define TRAP(regs) ((regs)->trap & ~0xF)
-
-#define CHECK_FULL_REGS(regs) \
-do { \
- if ((regs)->trap & 1) \
- printk(KERN_CRIT "%s: partial register set\n", __FUNCTION__); \
-} while (0)
-#endif /* __ASSEMBLY__ */
-
-#endif /* __KERNEL__ */
-
-/*
- * Offsets used by 'ptrace' system call interface.
- * These can't be changed without breaking binary compatibility
- * with MkLinux, etc.
- */
-#define PT_R0 0
-#define PT_R1 1
-#define PT_R2 2
-#define PT_R3 3
-#define PT_R4 4
-#define PT_R5 5
-#define PT_R6 6
-#define PT_R7 7
-#define PT_R8 8
-#define PT_R9 9
-#define PT_R10 10
-#define PT_R11 11
-#define PT_R12 12
-#define PT_R13 13
-#define PT_R14 14
-#define PT_R15 15
-#define PT_R16 16
-#define PT_R17 17
-#define PT_R18 18
-#define PT_R19 19
-#define PT_R20 20
-#define PT_R21 21
-#define PT_R22 22
-#define PT_R23 23
-#define PT_R24 24
-#define PT_R25 25
-#define PT_R26 26
-#define PT_R27 27
-#define PT_R28 28
-#define PT_R29 29
-#define PT_R30 30
-#define PT_R31 31
-
-#define PT_NIP 32
-#define PT_MSR 33
-#ifdef __KERNEL__
-#define PT_ORIG_R3 34
-#endif
-#define PT_CTR 35
-#define PT_LNK 36
-#define PT_XER 37
-#define PT_CCR 38
-#define PT_MQ 39
-
-#define PT_FPR0 48 /* each FP reg occupies 2 slots in this space */
-#define PT_FPR31 (PT_FPR0 + 2*31)
-#define PT_FPSCR (PT_FPR0 + 2*32 + 1)
-
-/* Get/set all the altivec registers vr0..vr31, vscr, vrsave, in one go */
-#define PTRACE_GETVRREGS 18
-#define PTRACE_SETVRREGS 19
-
-/* Get/set all the upper 32-bits of the SPE registers, accumulator, and
- * spefscr, in one go */
-#define PTRACE_GETEVRREGS 20
-#define PTRACE_SETEVRREGS 21
-
-/*
- * Get or set a debug register. The first 16 are DABR registers and the
- * second 16 are IABR registers.
- */
-#define PTRACE_GET_DEBUGREG 25
-#define PTRACE_SET_DEBUGREG 26
-
-#endif
diff --git a/include/asm-ppc/rio.h b/include/asm-ppc/rio.h
new file mode 100644
index 000000000000..0018bf80cb25
--- /dev/null
+++ b/include/asm-ppc/rio.h
@@ -0,0 +1,18 @@
+/*
+ * RapidIO architecture support
+ *
+ * Copyright 2005 MontaVista Software, Inc.
+ * Matt Porter <mporter@kernel.crashing.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.
+ */
+
+#ifndef ASM_PPC_RIO_H
+#define ASM_PPC_RIO_H
+
+extern void platform_rio_init(void);
+
+#endif /* ASM_PPC_RIO_H */
diff --git a/include/asm-ppc/rwsem.h b/include/asm-ppc/rwsem.h
deleted file mode 100644
index 3e738f483c11..000000000000
--- a/include/asm-ppc/rwsem.h
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- * include/asm-ppc/rwsem.h: R/W semaphores for PPC using the stuff
- * in lib/rwsem.c. Adapted largely from include/asm-i386/rwsem.h
- * by Paul Mackerras <paulus@samba.org>.
- */
-
-#ifndef _PPC_RWSEM_H
-#define _PPC_RWSEM_H
-
-#ifdef __KERNEL__
-#include <linux/list.h>
-#include <linux/spinlock.h>
-#include <asm/atomic.h>
-#include <asm/system.h>
-
-/*
- * the semaphore definition
- */
-struct rw_semaphore {
- /* XXX this should be able to be an atomic_t -- paulus */
- signed long count;
-#define RWSEM_UNLOCKED_VALUE 0x00000000
-#define RWSEM_ACTIVE_BIAS 0x00000001
-#define RWSEM_ACTIVE_MASK 0x0000ffff
-#define RWSEM_WAITING_BIAS (-0x00010000)
-#define RWSEM_ACTIVE_READ_BIAS RWSEM_ACTIVE_BIAS
-#define RWSEM_ACTIVE_WRITE_BIAS (RWSEM_WAITING_BIAS + RWSEM_ACTIVE_BIAS)
- spinlock_t wait_lock;
- struct list_head wait_list;
-#if RWSEM_DEBUG
- int debug;
-#endif
-};
-
-/*
- * initialisation
- */
-#if RWSEM_DEBUG
-#define __RWSEM_DEBUG_INIT , 0
-#else
-#define __RWSEM_DEBUG_INIT /* */
-#endif
-
-#define __RWSEM_INITIALIZER(name) \
- { RWSEM_UNLOCKED_VALUE, SPIN_LOCK_UNLOCKED, \
- LIST_HEAD_INIT((name).wait_list) \
- __RWSEM_DEBUG_INIT }
-
-#define DECLARE_RWSEM(name) \
- struct rw_semaphore name = __RWSEM_INITIALIZER(name)
-
-extern struct rw_semaphore *rwsem_down_read_failed(struct rw_semaphore *sem);
-extern struct rw_semaphore *rwsem_down_write_failed(struct rw_semaphore *sem);
-extern struct rw_semaphore *rwsem_wake(struct rw_semaphore *sem);
-extern struct rw_semaphore *rwsem_downgrade_wake(struct rw_semaphore *sem);
-
-static inline void init_rwsem(struct rw_semaphore *sem)
-{
- sem->count = RWSEM_UNLOCKED_VALUE;
- spin_lock_init(&sem->wait_lock);
- INIT_LIST_HEAD(&sem->wait_list);
-#if RWSEM_DEBUG
- sem->debug = 0;
-#endif
-}
-
-/*
- * lock for reading
- */
-static inline void __down_read(struct rw_semaphore *sem)
-{
- if (atomic_inc_return((atomic_t *)(&sem->count)) > 0)
- smp_wmb();
- else
- rwsem_down_read_failed(sem);
-}
-
-static inline int __down_read_trylock(struct rw_semaphore *sem)
-{
- int tmp;
-
- while ((tmp = sem->count) >= 0) {
- if (tmp == cmpxchg(&sem->count, tmp,
- tmp + RWSEM_ACTIVE_READ_BIAS)) {
- smp_wmb();
- return 1;
- }
- }
- return 0;
-}
-
-/*
- * lock for writing
- */
-static inline void __down_write(struct rw_semaphore *sem)
-{
- int tmp;
-
- tmp = atomic_add_return(RWSEM_ACTIVE_WRITE_BIAS,
- (atomic_t *)(&sem->count));
- if (tmp == RWSEM_ACTIVE_WRITE_BIAS)
- smp_wmb();
- else
- rwsem_down_write_failed(sem);
-}
-
-static inline int __down_write_trylock(struct rw_semaphore *sem)
-{
- int tmp;
-
- tmp = cmpxchg(&sem->count, RWSEM_UNLOCKED_VALUE,
- RWSEM_ACTIVE_WRITE_BIAS);
- smp_wmb();
- return tmp == RWSEM_UNLOCKED_VALUE;
-}
-
-/*
- * unlock after reading
- */
-static inline void __up_read(struct rw_semaphore *sem)
-{
- int tmp;
-
- smp_wmb();
- tmp = atomic_dec_return((atomic_t *)(&sem->count));
- if (tmp < -1 && (tmp & RWSEM_ACTIVE_MASK) == 0)
- rwsem_wake(sem);
-}
-
-/*
- * unlock after writing
- */
-static inline void __up_write(struct rw_semaphore *sem)
-{
- smp_wmb();
- if (atomic_sub_return(RWSEM_ACTIVE_WRITE_BIAS,
- (atomic_t *)(&sem->count)) < 0)
- rwsem_wake(sem);
-}
-
-/*
- * implement atomic add functionality
- */
-static inline void rwsem_atomic_add(int delta, struct rw_semaphore *sem)
-{
- atomic_add(delta, (atomic_t *)(&sem->count));
-}
-
-/*
- * downgrade write lock to read lock
- */
-static inline void __downgrade_write(struct rw_semaphore *sem)
-{
- int tmp;
-
- smp_wmb();
- tmp = atomic_add_return(-RWSEM_WAITING_BIAS, (atomic_t *)(&sem->count));
- if (tmp < 0)
- rwsem_downgrade_wake(sem);
-}
-
-/*
- * implement exchange and add functionality
- */
-static inline int rwsem_atomic_update(int delta, struct rw_semaphore *sem)
-{
- smp_mb();
- return atomic_add_return(delta, (atomic_t *)(&sem->count));
-}
-
-#endif /* __KERNEL__ */
-#endif /* _PPC_RWSEM_XADD_H */
diff --git a/include/asm-ppc/scatterlist.h b/include/asm-ppc/scatterlist.h
deleted file mode 100644
index f21f18f56548..000000000000
--- a/include/asm-ppc/scatterlist.h
+++ /dev/null
@@ -1,25 +0,0 @@
-#ifdef __KERNEL__
-#ifndef _PPC_SCATTERLIST_H
-#define _PPC_SCATTERLIST_H
-
-#include <asm/dma.h>
-
-struct scatterlist {
- struct page *page;
- unsigned int offset;
- dma_addr_t dma_address;
- unsigned int length;
-};
-
-/*
- * These macros should be used after a pci_map_sg call has been done
- * to get bus addresses of each of the SG entries and their lengths.
- * You should only work with the number of sg entries pci_map_sg
- * returns, or alternatively stop on the first sg_dma_len(sg) which
- * is 0.
- */
-#define sg_dma_address(sg) ((sg)->dma_address)
-#define sg_dma_len(sg) ((sg)->length)
-
-#endif /* !(_PPC_SCATTERLIST_H) */
-#endif /* __KERNEL__ */
diff --git a/include/asm-ppc/seccomp.h b/include/asm-ppc/seccomp.h
deleted file mode 100644
index 666c4da96d87..000000000000
--- a/include/asm-ppc/seccomp.h
+++ /dev/null
@@ -1,10 +0,0 @@
-#ifndef _ASM_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_rt_sigreturn
-
-#endif /* _ASM_SECCOMP_H */
diff --git a/include/asm-ppc/sections.h b/include/asm-ppc/sections.h
deleted file mode 100644
index ba8f43ac9bf3..000000000000
--- a/include/asm-ppc/sections.h
+++ /dev/null
@@ -1,33 +0,0 @@
-#ifdef __KERNEL__
-#ifndef _PPC_SECTIONS_H
-#define _PPC_SECTIONS_H
-
-#include <asm-generic/sections.h>
-
-#define __pmac __attribute__ ((__section__ (".pmac.text")))
-#define __pmacdata __attribute__ ((__section__ (".pmac.data")))
-#define __pmacfunc(__argpmac) \
- __argpmac __pmac; \
- __argpmac
-
-#define __prep __attribute__ ((__section__ (".prep.text")))
-#define __prepdata __attribute__ ((__section__ (".prep.data")))
-#define __prepfunc(__argprep) \
- __argprep __prep; \
- __argprep
-
-#define __chrp __attribute__ ((__section__ (".chrp.text")))
-#define __chrpdata __attribute__ ((__section__ (".chrp.data")))
-#define __chrpfunc(__argchrp) \
- __argchrp __chrp; \
- __argchrp
-
-/* this is actually just common chrp/pmac code, not OF code -- Cort */
-#define __openfirmware __attribute__ ((__section__ (".openfirmware.text")))
-#define __openfirmwaredata __attribute__ ((__section__ (".openfirmware.data")))
-#define __openfirmwarefunc(__argopenfirmware) \
- __argopenfirmware __openfirmware; \
- __argopenfirmware
-
-#endif /* _PPC_SECTIONS_H */
-#endif /* __KERNEL__ */
diff --git a/include/asm-ppc/semaphore.h b/include/asm-ppc/semaphore.h
deleted file mode 100644
index 89e6e73be08c..000000000000
--- a/include/asm-ppc/semaphore.h
+++ /dev/null
@@ -1,111 +0,0 @@
-#ifndef _PPC_SEMAPHORE_H
-#define _PPC_SEMAPHORE_H
-
-/*
- * Swiped from asm-sparc/semaphore.h and modified
- * -- Cort (cort@cs.nmt.edu)
- *
- * Stole some rw spinlock-based semaphore stuff from asm-alpha/semaphore.h
- * -- Ani Joshi (ajoshi@unixbox.com)
- *
- * Remove spinlock-based RW semaphores; RW semaphore definitions are
- * now in rwsem.h and we use the generic lib/rwsem.c implementation.
- * Rework semaphores to use atomic_dec_if_positive.
- * -- Paul Mackerras (paulus@samba.org)
- */
-
-#ifdef __KERNEL__
-
-#include <asm/atomic.h>
-#include <asm/system.h>
-#include <linux/wait.h>
-#include <linux/rwsem.h>
-
-struct semaphore {
- /*
- * Note that any negative value of count is equivalent to 0,
- * but additionally indicates that some process(es) might be
- * sleeping on `wait'.
- */
- atomic_t count;
- wait_queue_head_t wait;
-};
-
-#define __SEMAPHORE_INITIALIZER(name, n) \
-{ \
- .count = ATOMIC_INIT(n), \
- .wait = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \
-}
-
-#define __MUTEX_INITIALIZER(name) \
- __SEMAPHORE_INITIALIZER(name, 1)
-
-#define __DECLARE_SEMAPHORE_GENERIC(name, count) \
- struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
-
-#define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name, 1)
-#define DECLARE_MUTEX_LOCKED(name) __DECLARE_SEMAPHORE_GENERIC(name, 0)
-
-static inline void sema_init (struct semaphore *sem, int val)
-{
- atomic_set(&sem->count, val);
- init_waitqueue_head(&sem->wait);
-}
-
-static inline void init_MUTEX (struct semaphore *sem)
-{
- sema_init(sem, 1);
-}
-
-static inline void init_MUTEX_LOCKED (struct semaphore *sem)
-{
- sema_init(sem, 0);
-}
-
-extern void __down(struct semaphore * sem);
-extern int __down_interruptible(struct semaphore * sem);
-extern void __up(struct semaphore * sem);
-
-extern inline void down(struct semaphore * sem)
-{
- might_sleep();
-
- /*
- * Try to get the semaphore, take the slow path if we fail.
- */
- if (atomic_dec_return(&sem->count) < 0)
- __down(sem);
- smp_wmb();
-}
-
-extern inline int down_interruptible(struct semaphore * sem)
-{
- int ret = 0;
-
- might_sleep();
-
- if (atomic_dec_return(&sem->count) < 0)
- ret = __down_interruptible(sem);
- smp_wmb();
- return ret;
-}
-
-extern inline int down_trylock(struct semaphore * sem)
-{
- int ret;
-
- ret = atomic_dec_if_positive(&sem->count) < 0;
- smp_wmb();
- return ret;
-}
-
-extern inline void up(struct semaphore * sem)
-{
- smp_wmb();
- if (atomic_inc_return(&sem->count) <= 0)
- __up(sem);
-}
-
-#endif /* __KERNEL__ */
-
-#endif /* !(_PPC_SEMAPHORE_H) */
diff --git a/include/asm-ppc/sigcontext.h b/include/asm-ppc/sigcontext.h
deleted file mode 100644
index b7a417e0a921..000000000000
--- a/include/asm-ppc/sigcontext.h
+++ /dev/null
@@ -1,15 +0,0 @@
-#ifndef _ASM_PPC_SIGCONTEXT_H
-#define _ASM_PPC_SIGCONTEXT_H
-
-#include <asm/ptrace.h>
-#include <linux/compiler.h>
-
-struct sigcontext {
- unsigned long _unused[4];
- int signal;
- unsigned long handler;
- unsigned long oldmask;
- struct pt_regs __user *regs;
-};
-
-#endif
diff --git a/include/asm-ppc/smp.h b/include/asm-ppc/smp.h
index 829481c0a9dc..30e9268a888c 100644
--- a/include/asm-ppc/smp.h
+++ b/include/asm-ppc/smp.h
@@ -35,6 +35,7 @@ extern cpumask_t cpu_possible_map;
extern unsigned long smp_proc_in_lock[];
extern volatile unsigned long cpu_callin_map[];
extern int smp_tb_synchronized;
+extern struct smp_ops_t *smp_ops;
extern void smp_send_tlb_invalidate(int);
extern void smp_send_xmon_break(int cpu);
@@ -45,32 +46,31 @@ extern int __cpu_disable(void);
extern void __cpu_die(unsigned int cpu);
extern void cpu_die(void) __attribute__((noreturn));
-#define NO_PROC_ID 0xFF /* No processor magic marker */
-#define PROC_CHANGE_PENALTY 20
-
#define raw_smp_processor_id() (current_thread_info()->cpu)
extern int __cpu_up(unsigned int cpu);
extern int smp_hw_index[];
-#define hard_smp_processor_id() (smp_hw_index[smp_processor_id()])
-
-struct klock_info_struct {
- unsigned long kernel_flag;
- unsigned char akp;
-};
-
-extern struct klock_info_struct klock_info;
-#define KLOCK_HELD 0xffffffff
-#define KLOCK_CLEAR 0x0
-
+#define hard_smp_processor_id() (smp_hw_index[smp_processor_id()])
+#define get_hard_smp_processor_id(cpu) (smp_hw_index[(cpu)])
+#define set_hard_smp_processor_id(cpu, phys)\
+ (smp_hw_index[(cpu)] = (phys))
+
#endif /* __ASSEMBLY__ */
#else /* !(CONFIG_SMP) */
static inline void cpu_die(void) { }
+#define get_hard_smp_processor_id(cpu) 0
+#define set_hard_smp_processor_id(cpu, phys)
+#define hard_smp_processor_id() 0
#endif /* !(CONFIG_SMP) */
+#ifndef __ASSEMBLY__
+extern int boot_cpuid;
+extern int boot_cpuid_phys;
+#endif
+
#endif /* !(_PPC_SMP_H) */
#endif /* __KERNEL__ */
diff --git a/include/asm-ppc/spinlock.h b/include/asm-ppc/spinlock.h
index 20edcf2a6e0c..5c64b75f0295 100644
--- a/include/asm-ppc/spinlock.h
+++ b/include/asm-ppc/spinlock.h
@@ -9,7 +9,7 @@
* (the type definitions are in asm/raw_spinlock_types.h)
*/
-#define __raw_spin_is_locked(x) ((x)->lock != 0)
+#define __raw_spin_is_locked(x) ((x)->slock != 0)
#define __raw_spin_unlock_wait(lock) \
do { while (__raw_spin_is_locked(lock)) cpu_relax(); } while (0)
#define __raw_spin_lock_flags(lock, flags) __raw_spin_lock(lock)
@@ -31,17 +31,17 @@ static inline void __raw_spin_lock(raw_spinlock_t *lock)
bne- 2b\n\
isync"
: "=&r"(tmp)
- : "r"(&lock->lock), "r"(1)
+ : "r"(&lock->slock), "r"(1)
: "cr0", "memory");
}
static inline void __raw_spin_unlock(raw_spinlock_t *lock)
{
__asm__ __volatile__("eieio # __raw_spin_unlock": : :"memory");
- lock->lock = 0;
+ lock->slock = 0;
}
-#define __raw_spin_trylock(l) (!test_and_set_bit(0,&(l)->lock))
+#define __raw_spin_trylock(l) (!test_and_set_bit(0,(volatile unsigned long *)(&(l)->slock)))
/*
* Read-write spinlocks, allowing multiple readers
diff --git a/include/asm-ppc/spinlock_types.h b/include/asm-ppc/spinlock_types.h
deleted file mode 100644
index 7919ccc75b8a..000000000000
--- a/include/asm-ppc/spinlock_types.h
+++ /dev/null
@@ -1,20 +0,0 @@
-#ifndef __ASM_SPINLOCK_TYPES_H
-#define __ASM_SPINLOCK_TYPES_H
-
-#ifndef __LINUX_SPINLOCK_TYPES_H
-# error "please don't include this file directly"
-#endif
-
-typedef struct {
- volatile unsigned long lock;
-} raw_spinlock_t;
-
-#define __RAW_SPIN_LOCK_UNLOCKED { 0 }
-
-typedef struct {
- volatile signed int lock;
-} raw_rwlock_t;
-
-#define __RAW_RW_LOCK_UNLOCKED { 0 }
-
-#endif
diff --git a/include/asm-ppc/stat.h b/include/asm-ppc/stat.h
deleted file mode 100644
index cadb34298496..000000000000
--- a/include/asm-ppc/stat.h
+++ /dev/null
@@ -1,69 +0,0 @@
-#ifndef _PPC_STAT_H
-#define _PPC_STAT_H
-
-#ifdef __KERNEL__
-#include <linux/types.h>
-#endif /* __KERNEL__ */
-
-struct __old_kernel_stat {
- unsigned short st_dev;
- unsigned short st_ino;
- unsigned short st_mode;
- unsigned short st_nlink;
- unsigned short st_uid;
- unsigned short st_gid;
- unsigned short st_rdev;
- unsigned long st_size;
- unsigned long st_atime;
- unsigned long st_mtime;
- unsigned long st_ctime;
-};
-
-#define STAT_HAVE_NSEC 1
-
-struct stat {
- unsigned st_dev;
- ino_t st_ino;
- mode_t st_mode;
- nlink_t st_nlink;
- uid_t st_uid;
- gid_t st_gid;
- unsigned st_rdev;
- off_t st_size;
- unsigned long st_blksize;
- unsigned long st_blocks;
- unsigned long st_atime;
- unsigned long st_atime_nsec;
- unsigned long st_mtime;
- unsigned long st_mtime_nsec;
- unsigned long st_ctime;
- unsigned long st_ctime_nsec;
- unsigned long __unused4;
- unsigned long __unused5;
-};
-
-/* This matches struct stat64 in glibc2.1.
- */
-struct stat64 {
- unsigned long long st_dev; /* Device. */
- unsigned long long st_ino; /* File serial number. */
- unsigned int st_mode; /* File mode. */
- unsigned int st_nlink; /* Link count. */
- unsigned int st_uid; /* User ID of the file's owner. */
- unsigned int st_gid; /* Group ID of the file's group. */
- unsigned long long st_rdev; /* Device number, if device. */
- unsigned short int __pad2;
- long long st_size; /* Size of file, in bytes. */
- long st_blksize; /* Optimal block size for I/O. */
-
- long long st_blocks; /* Number 512-byte blocks allocated. */
- long st_atime; /* Time of last access. */
- unsigned long st_atime_nsec;
- long st_mtime; /* Time of last modification. */
- unsigned long int st_mtime_nsec;
- long st_ctime; /* Time of last status change. */
- unsigned long int st_ctime_nsec;
- unsigned long int __unused4;
- unsigned long int __unused5;
-};
-#endif
diff --git a/include/asm-ppc/statfs.h b/include/asm-ppc/statfs.h
deleted file mode 100644
index 807c69954a1b..000000000000
--- a/include/asm-ppc/statfs.h
+++ /dev/null
@@ -1,8 +0,0 @@
-#ifndef _PPC_STATFS_H
-#define _PPC_STATFS_H
-
-#include <asm-generic/statfs.h>
-#endif
-
-
-
diff --git a/include/asm-ppc/system.h b/include/asm-ppc/system.h
index d754ab570fe0..bd99cb53a19f 100644
--- a/include/asm-ppc/system.h
+++ b/include/asm-ppc/system.h
@@ -70,25 +70,47 @@ extern void _set_L3CR(unsigned long);
#endif
extern void via_cuda_init(void);
extern void pmac_nvram_init(void);
+extern void chrp_nvram_init(void);
extern void read_rtc_time(void);
extern void pmac_find_display(void);
extern void giveup_fpu(struct task_struct *);
extern void enable_kernel_fp(void);
+extern void flush_fp_to_thread(struct task_struct *);
extern void enable_kernel_altivec(void);
extern void giveup_altivec(struct task_struct *);
extern void load_up_altivec(struct task_struct *);
+extern int emulate_altivec(struct pt_regs *);
extern void giveup_spe(struct task_struct *);
extern void load_up_spe(struct task_struct *);
extern int fix_alignment(struct pt_regs *);
-extern void cvt_fd(float *from, double *to, unsigned long *fpscr);
-extern void cvt_df(double *from, float *to, unsigned long *fpscr);
+extern void cvt_fd(float *from, double *to, struct thread_struct *thread);
+extern void cvt_df(double *from, float *to, struct thread_struct *thread);
+
+#ifdef CONFIG_ALTIVEC
+extern void flush_altivec_to_thread(struct task_struct *);
+#else
+static inline void flush_altivec_to_thread(struct task_struct *t)
+{
+}
+#endif
+
+#ifdef CONFIG_SPE
+extern void flush_spe_to_thread(struct task_struct *);
+#else
+static inline void flush_spe_to_thread(struct task_struct *t)
+{
+}
+#endif
+
extern int call_rtas(const char *, int, int, unsigned long *, ...);
extern void cacheable_memzero(void *p, unsigned int nb);
extern void *cacheable_memcpy(void *, const void *, unsigned int);
extern int do_page_fault(struct pt_regs *, unsigned long, unsigned long);
extern void bad_page_fault(struct pt_regs *, unsigned long, int);
-extern void die(const char *, struct pt_regs *, long);
+extern int die(const char *, struct pt_regs *, long);
extern void _exception(int, struct pt_regs *, int, unsigned long);
+void _nmask_and_or_msr(unsigned long nmask, unsigned long or_val);
+
#ifdef CONFIG_BOOKE_WDT
extern u32 booke_wdt_enabled;
extern u32 booke_wdt_period;
diff --git a/include/asm-ppc/thread_info.h b/include/asm-ppc/thread_info.h
deleted file mode 100644
index 27903db42efc..000000000000
--- a/include/asm-ppc/thread_info.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/* thread_info.h: PPC low-level thread information
- * adapted from the i386 version by Paul Mackerras
- *
- * Copyright (C) 2002 David Howells (dhowells@redhat.com)
- * - Incorporating suggestions made by Linus Torvalds and Dave Miller
- */
-
-#ifndef _ASM_THREAD_INFO_H
-#define _ASM_THREAD_INFO_H
-
-#ifdef __KERNEL__
-#ifndef __ASSEMBLY__
-/*
- * low level task data.
- * If you change this, change the TI_* offsets below to match.
- */
-struct thread_info {
- struct task_struct *task; /* main task structure */
- struct exec_domain *exec_domain; /* execution domain */
- unsigned long flags; /* low level flags */
- unsigned long local_flags; /* non-racy flags */
- int cpu; /* cpu we're on */
- int preempt_count; /* 0 => preemptable,
- <0 => BUG */
- struct restart_block restart_block;
-};
-
-#define INIT_THREAD_INFO(tsk) \
-{ \
- .task = &tsk, \
- .exec_domain = &default_exec_domain, \
- .flags = 0, \
- .local_flags = 0, \
- .cpu = 0, \
- .preempt_count = 1, \
- .restart_block = { \
- .fn = do_no_restart_syscall, \
- }, \
-}
-
-#define init_thread_info (init_thread_union.thread_info)
-#define init_stack (init_thread_union.stack)
-
-/*
- * macros/functions for gaining access to the thread information structure
- */
-
-/* how to get the thread information struct from C */
-static inline struct thread_info *current_thread_info(void)
-{
- struct thread_info *ti;
- __asm__("rlwinm %0,1,0,0,18" : "=r"(ti));
- return ti;
-}
-
-/* thread information allocation */
-#define alloc_thread_info(tsk) ((struct thread_info *) \
- __get_free_pages(GFP_KERNEL, 1))
-#define free_thread_info(ti) free_pages((unsigned long) (ti), 1)
-#define get_thread_info(ti) get_task_struct((ti)->task)
-#define put_thread_info(ti) put_task_struct((ti)->task)
-#endif /* __ASSEMBLY__ */
-
-/*
- * Size of kernel stack for each process.
- */
-#define THREAD_SIZE 8192 /* 2 pages */
-
-#define PREEMPT_ACTIVE 0x10000000
-
-/*
- * thread information flag bit numbers
- */
-#define TIF_SYSCALL_TRACE 0 /* syscall trace active */
-#define TIF_NOTIFY_RESUME 1 /* resumption notification requested */
-#define TIF_SIGPENDING 2 /* signal pending */
-#define TIF_NEED_RESCHED 3 /* rescheduling necessary */
-#define TIF_POLLING_NRFLAG 4 /* true if poll_idle() is polling
- TIF_NEED_RESCHED */
-#define TIF_MEMDIE 5
-#define TIF_SYSCALL_AUDIT 6 /* syscall auditing active */
-#define TIF_SECCOMP 7 /* secure computing */
-
-/* as above, but as bit values */
-#define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE)
-#define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME)
-#define _TIF_SIGPENDING (1<<TIF_SIGPENDING)
-#define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED)
-#define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG)
-#define _TIF_SYSCALL_AUDIT (1<<TIF_SYSCALL_AUDIT)
-#define _TIF_SECCOMP (1<<TIF_SECCOMP)
-
-#define _TIF_SYSCALL_T_OR_A (_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP)
-
-/*
- * Non racy (local) flags bit numbers
- */
-#define TIFL_FORCE_NOERROR 0 /* don't return error from current
- syscall even if result < 0 */
-
-/* as above, but as bit values */
-#define _TIFL_FORCE_NOERROR (1<<TIFL_FORCE_NOERROR)
-
-
-#endif /* __KERNEL__ */
-
-#endif /* _ASM_THREAD_INFO_H */
diff --git a/include/asm-ppc/tlbflush.h b/include/asm-ppc/tlbflush.h
deleted file mode 100644
index 9afee4ffc835..000000000000
--- a/include/asm-ppc/tlbflush.h
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * include/asm-ppc/tlbflush.h
- *
- * 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 _PPC_TLBFLUSH_H
-#define _PPC_TLBFLUSH_H
-
-#include <linux/config.h>
-#include <linux/mm.h>
-
-extern void _tlbie(unsigned long address);
-extern void _tlbia(void);
-
-#if defined(CONFIG_4xx)
-
-#ifndef CONFIG_44x
-#define __tlbia() asm volatile ("sync; tlbia; isync" : : : "memory")
-#else
-#define __tlbia _tlbia
-#endif
-
-static inline void flush_tlb_mm(struct mm_struct *mm)
- { __tlbia(); }
-static inline void flush_tlb_page(struct vm_area_struct *vma,
- unsigned long vmaddr)
- { _tlbie(vmaddr); }
-static inline void flush_tlb_page_nohash(struct vm_area_struct *vma,
- unsigned long vmaddr)
- { _tlbie(vmaddr); }
-static inline void flush_tlb_range(struct vm_area_struct *vma,
- unsigned long start, unsigned long end)
- { __tlbia(); }
-static inline void flush_tlb_kernel_range(unsigned long start,
- unsigned long end)
- { __tlbia(); }
-
-#elif defined(CONFIG_FSL_BOOKE)
-
-/* TODO: determine if flush_tlb_range & flush_tlb_kernel_range
- * are best implemented as tlbia vs specific tlbie's */
-
-#define __tlbia() _tlbia()
-
-static inline void flush_tlb_mm(struct mm_struct *mm)
- { __tlbia(); }
-static inline void flush_tlb_page(struct vm_area_struct *vma,
- unsigned long vmaddr)
- { _tlbie(vmaddr); }
-static inline void flush_tlb_page_nohash(struct vm_area_struct *vma,
- unsigned long vmaddr)
- { _tlbie(vmaddr); }
-static inline void flush_tlb_range(struct vm_area_struct *vma,
- unsigned long start, unsigned long end)
- { __tlbia(); }
-static inline void flush_tlb_kernel_range(unsigned long start,
- unsigned long end)
- { __tlbia(); }
-
-#elif defined(CONFIG_8xx)
-#define __tlbia() asm volatile ("tlbia; sync" : : : "memory")
-
-static inline void flush_tlb_mm(struct mm_struct *mm)
- { __tlbia(); }
-static inline void flush_tlb_page(struct vm_area_struct *vma,
- unsigned long vmaddr)
- { _tlbie(vmaddr); }
-static inline void flush_tlb_page_nohash(struct vm_area_struct *vma,
- unsigned long vmaddr)
- { _tlbie(vmaddr); }
-static inline void flush_tlb_range(struct vm_area_struct *vma,
- unsigned long start, unsigned long end)
- { __tlbia(); }
-static inline void flush_tlb_kernel_range(unsigned long start,
- unsigned long end)
- { __tlbia(); }
-
-#else /* 6xx, 7xx, 7xxx cpus */
-struct mm_struct;
-struct vm_area_struct;
-extern void flush_tlb_mm(struct mm_struct *mm);
-extern void flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr);
-extern void flush_tlb_page_nohash(struct vm_area_struct *vma, unsigned long addr);
-extern void flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
- unsigned long end);
-extern void flush_tlb_kernel_range(unsigned long start, unsigned long end);
-#endif
-
-/*
- * This is called in munmap when we have freed up some page-table
- * pages. We don't need to do anything here, there's nothing special
- * about our page-table pages. -- paulus
- */
-static inline void flush_tlb_pgtables(struct mm_struct *mm,
- unsigned long start, unsigned long end)
-{
-}
-
-/*
- * This gets called at the end of handling a page fault, when
- * the kernel has put a new PTE into the page table for the process.
- * We use it to ensure coherency between the i-cache and d-cache
- * for the page which has just been mapped in.
- * On machines which use an MMU hash table, we use this to put a
- * corresponding HPTE into the hash table ahead of time, instead of
- * waiting for the inevitable extra hash-table miss exception.
- */
-extern void update_mmu_cache(struct vm_area_struct *, unsigned long, pte_t);
-
-#endif /* _PPC_TLBFLUSH_H */
-#endif /*__KERNEL__ */
diff --git a/include/asm-ppc/types.h b/include/asm-ppc/types.h
deleted file mode 100644
index 77dc24d7d2ad..000000000000
--- a/include/asm-ppc/types.h
+++ /dev/null
@@ -1,69 +0,0 @@
-#ifndef _PPC_TYPES_H
-#define _PPC_TYPES_H
-
-#ifndef __ASSEMBLY__
-
-typedef __signed__ char __s8;
-typedef unsigned char __u8;
-
-typedef __signed__ short __s16;
-typedef unsigned short __u16;
-
-typedef __signed__ int __s32;
-typedef unsigned int __u32;
-
-#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
-typedef __signed__ long long __s64;
-typedef unsigned long long __u64;
-#endif
-
-typedef struct {
- __u32 u[4];
-} __vector128;
-
-/*
- * XXX allowed outside of __KERNEL__ for now, until glibc gets
- * a proper set of asm headers of its own. -- paulus
- */
-typedef unsigned short umode_t;
-
-#endif /* __ASSEMBLY__ */
-
-#ifdef __KERNEL__
-/*
- * These aren't exported outside the kernel to avoid name space clashes
- */
-#define BITS_PER_LONG 32
-
-#ifndef __ASSEMBLY__
-
-#include <linux/config.h>
-
-typedef signed char s8;
-typedef unsigned char u8;
-
-typedef signed short s16;
-typedef unsigned short u16;
-
-typedef signed int s32;
-typedef unsigned int u32;
-
-typedef signed long long s64;
-typedef unsigned long long u64;
-
-typedef __vector128 vector128;
-
-/* DMA addresses are 32-bits wide */
-typedef u32 dma_addr_t;
-typedef u64 dma64_addr_t;
-
-#ifdef CONFIG_LBD
-typedef u64 sector_t;
-#define HAVE_SECTOR_T
-#endif
-
-#endif /* __ASSEMBLY__ */
-
-#endif /* __KERNEL__ */
-
-#endif
diff --git a/include/asm-ppc/uaccess.h b/include/asm-ppc/uaccess.h
deleted file mode 100644
index 63f56224da8c..000000000000
--- a/include/asm-ppc/uaccess.h
+++ /dev/null
@@ -1,393 +0,0 @@
-#ifdef __KERNEL__
-#ifndef _PPC_UACCESS_H
-#define _PPC_UACCESS_H
-
-#ifndef __ASSEMBLY__
-#include <linux/sched.h>
-#include <linux/errno.h>
-#include <asm/processor.h>
-
-#define VERIFY_READ 0
-#define VERIFY_WRITE 1
-
-/*
- * The fs value determines whether argument validity checking should be
- * performed or not. If get_fs() == USER_DS, checking is performed, with
- * get_fs() == KERNEL_DS, checking is bypassed.
- *
- * For historical reasons, these macros are grossly misnamed.
- *
- * The fs/ds values are now the highest legal address in the "segment".
- * This simplifies the checking in the routines below.
- */
-
-#define KERNEL_DS ((mm_segment_t) { ~0UL })
-#define USER_DS ((mm_segment_t) { TASK_SIZE - 1 })
-
-#define get_ds() (KERNEL_DS)
-#define get_fs() (current->thread.fs)
-#define set_fs(val) (current->thread.fs = (val))
-
-#define segment_eq(a,b) ((a).seg == (b).seg)
-
-#define __access_ok(addr,size) \
- ((addr) <= current->thread.fs.seg \
- && ((size) == 0 || (size) - 1 <= current->thread.fs.seg - (addr)))
-
-#define access_ok(type, addr, size) \
- (__chk_user_ptr(addr),__access_ok((unsigned long)(addr),(size)))
-
-/*
- * The exception table consists of pairs of addresses: the first is the
- * address of an instruction that is allowed to fault, and the second is
- * the address at which the program should continue. No registers are
- * modified, so it is entirely up to the continuation code to figure out
- * what to do.
- *
- * All the routines below use bits of fixup code that are out of line
- * with the main instruction path. This means when everything is well,
- * we don't even have to jump over them. Further, they do not intrude
- * on our cache or tlb entries.
- */
-
-struct exception_table_entry
-{
- unsigned long insn, fixup;
-};
-
-/*
- * These are the main single-value transfer routines. They automatically
- * use the right size if we just have the right pointer type.
- *
- * This gets kind of ugly. We want to return _two_ values in "get_user()"
- * and yet we don't want to do any pointers, because that is too much
- * of a performance impact. Thus we have a few rather ugly macros here,
- * and hide all the ugliness from the user.
- *
- * The "__xxx" versions of the user access functions are versions that
- * do not verify the address space, that must have been done previously
- * with a separate "access_ok()" call (this is used when we do multiple
- * accesses to the same area of user memory).
- *
- * As we use the same address space for kernel and user data on the
- * PowerPC, we can just do these as direct assignments. (Of course, the
- * exception handling means that it's no longer "just"...)
- *
- * The "user64" versions of the user access functions are versions that
- * allow access of 64-bit data. The "get_user" functions do not
- * properly handle 64-bit data because the value gets down cast to a long.
- * The "put_user" functions already handle 64-bit data properly but we add
- * "user64" versions for completeness
- */
-#define get_user(x,ptr) \
- __get_user_check((x),(ptr),sizeof(*(ptr)))
-#define get_user64(x,ptr) \
- __get_user64_check((x),(ptr),sizeof(*(ptr)))
-#define put_user(x,ptr) \
- __put_user_check((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr)))
-#define put_user64(x,ptr) put_user(x,ptr)
-
-#define __get_user(x,ptr) \
- __get_user_nocheck((x),(ptr),sizeof(*(ptr)))
-#define __get_user64(x,ptr) \
- __get_user64_nocheck((x),(ptr),sizeof(*(ptr)))
-#define __put_user(x,ptr) \
- __put_user_nocheck((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr)))
-#define __put_user64(x,ptr) __put_user(x,ptr)
-
-extern long __put_user_bad(void);
-
-#define __put_user_nocheck(x,ptr,size) \
-({ \
- long __pu_err; \
- __chk_user_ptr(ptr); \
- __put_user_size((x),(ptr),(size),__pu_err); \
- __pu_err; \
-})
-
-#define __put_user_check(x,ptr,size) \
-({ \
- long __pu_err = -EFAULT; \
- __typeof__(*(ptr)) __user *__pu_addr = (ptr); \
- if (access_ok(VERIFY_WRITE,__pu_addr,size)) \
- __put_user_size((x),__pu_addr,(size),__pu_err); \
- __pu_err; \
-})
-
-#define __put_user_size(x,ptr,size,retval) \
-do { \
- retval = 0; \
- switch (size) { \
- case 1: \
- __put_user_asm(x, ptr, retval, "stb"); \
- break; \
- case 2: \
- __put_user_asm(x, ptr, retval, "sth"); \
- break; \
- case 4: \
- __put_user_asm(x, ptr, retval, "stw"); \
- break; \
- case 8: \
- __put_user_asm2(x, ptr, retval); \
- break; \
- default: \
- __put_user_bad(); \
- } \
-} while (0)
-
-/*
- * We don't tell gcc that we are accessing memory, but this is OK
- * because we do not write to any memory gcc knows about, so there
- * are no aliasing issues.
- */
-#define __put_user_asm(x, addr, err, op) \
- __asm__ __volatile__( \
- "1: "op" %1,0(%2)\n" \
- "2:\n" \
- ".section .fixup,\"ax\"\n" \
- "3: li %0,%3\n" \
- " b 2b\n" \
- ".previous\n" \
- ".section __ex_table,\"a\"\n" \
- " .align 2\n" \
- " .long 1b,3b\n" \
- ".previous" \
- : "=r" (err) \
- : "r" (x), "b" (addr), "i" (-EFAULT), "0" (err))
-
-#define __put_user_asm2(x, addr, err) \
- __asm__ __volatile__( \
- "1: stw %1,0(%2)\n" \
- "2: stw %1+1,4(%2)\n" \
- "3:\n" \
- ".section .fixup,\"ax\"\n" \
- "4: li %0,%3\n" \
- " b 3b\n" \
- ".previous\n" \
- ".section __ex_table,\"a\"\n" \
- " .align 2\n" \
- " .long 1b,4b\n" \
- " .long 2b,4b\n" \
- ".previous" \
- : "=r" (err) \
- : "r" (x), "b" (addr), "i" (-EFAULT), "0" (err))
-
-#define __get_user_nocheck(x, ptr, size) \
-({ \
- long __gu_err; \
- unsigned long __gu_val; \
- __chk_user_ptr(ptr); \
- __get_user_size(__gu_val, (ptr), (size), __gu_err); \
- (x) = (__typeof__(*(ptr)))__gu_val; \
- __gu_err; \
-})
-
-#define __get_user64_nocheck(x, ptr, size) \
-({ \
- long __gu_err; \
- long long __gu_val; \
- __chk_user_ptr(ptr); \
- __get_user_size64(__gu_val, (ptr), (size), __gu_err); \
- (x) = (__typeof__(*(ptr)))__gu_val; \
- __gu_err; \
-})
-
-#define __get_user_check(x, ptr, size) \
-({ \
- long __gu_err = -EFAULT; \
- unsigned long __gu_val = 0; \
- const __typeof__(*(ptr)) __user *__gu_addr = (ptr); \
- if (access_ok(VERIFY_READ, __gu_addr, (size))) \
- __get_user_size(__gu_val, __gu_addr, (size), __gu_err); \
- (x) = (__typeof__(*(ptr)))__gu_val; \
- __gu_err; \
-})
-
-#define __get_user64_check(x, ptr, size) \
-({ \
- long __gu_err = -EFAULT; \
- long long __gu_val = 0; \
- const __typeof__(*(ptr)) __user *__gu_addr = (ptr); \
- if (access_ok(VERIFY_READ, __gu_addr, (size))) \
- __get_user_size64(__gu_val, __gu_addr, (size), __gu_err); \
- (x) = (__typeof__(*(ptr)))__gu_val; \
- __gu_err; \
-})
-
-extern long __get_user_bad(void);
-
-#define __get_user_size(x, ptr, size, retval) \
-do { \
- retval = 0; \
- switch (size) { \
- case 1: \
- __get_user_asm(x, ptr, retval, "lbz"); \
- break; \
- case 2: \
- __get_user_asm(x, ptr, retval, "lhz"); \
- break; \
- case 4: \
- __get_user_asm(x, ptr, retval, "lwz"); \
- break; \
- default: \
- x = __get_user_bad(); \
- } \
-} while (0)
-
-#define __get_user_size64(x, ptr, size, retval) \
-do { \
- retval = 0; \
- switch (size) { \
- case 1: \
- __get_user_asm(x, ptr, retval, "lbz"); \
- break; \
- case 2: \
- __get_user_asm(x, ptr, retval, "lhz"); \
- break; \
- case 4: \
- __get_user_asm(x, ptr, retval, "lwz"); \
- break; \
- case 8: \
- __get_user_asm2(x, ptr, retval); \
- break; \
- default: \
- x = __get_user_bad(); \
- } \
-} while (0)
-
-#define __get_user_asm(x, addr, err, op) \
- __asm__ __volatile__( \
- "1: "op" %1,0(%2)\n" \
- "2:\n" \
- ".section .fixup,\"ax\"\n" \
- "3: li %0,%3\n" \
- " li %1,0\n" \
- " b 2b\n" \
- ".previous\n" \
- ".section __ex_table,\"a\"\n" \
- " .align 2\n" \
- " .long 1b,3b\n" \
- ".previous" \
- : "=r"(err), "=r"(x) \
- : "b"(addr), "i"(-EFAULT), "0"(err))
-
-#define __get_user_asm2(x, addr, err) \
- __asm__ __volatile__( \
- "1: lwz %1,0(%2)\n" \
- "2: lwz %1+1,4(%2)\n" \
- "3:\n" \
- ".section .fixup,\"ax\"\n" \
- "4: li %0,%3\n" \
- " li %1,0\n" \
- " li %1+1,0\n" \
- " b 3b\n" \
- ".previous\n" \
- ".section __ex_table,\"a\"\n" \
- " .align 2\n" \
- " .long 1b,4b\n" \
- " .long 2b,4b\n" \
- ".previous" \
- : "=r"(err), "=&r"(x) \
- : "b"(addr), "i"(-EFAULT), "0"(err))
-
-/* more complex routines */
-
-extern int __copy_tofrom_user(void __user *to, const void __user *from,
- unsigned long size);
-
-extern inline unsigned long
-copy_from_user(void *to, const void __user *from, unsigned long n)
-{
- unsigned long over;
-
- if (access_ok(VERIFY_READ, from, n))
- return __copy_tofrom_user((__force void __user *)to, from, n);
- if ((unsigned long)from < TASK_SIZE) {
- over = (unsigned long)from + n - TASK_SIZE;
- return __copy_tofrom_user((__force void __user *)to, from, n - over) + over;
- }
- return n;
-}
-
-extern inline unsigned long
-copy_to_user(void __user *to, const void *from, unsigned long n)
-{
- unsigned long over;
-
- if (access_ok(VERIFY_WRITE, to, n))
- return __copy_tofrom_user(to, (__force void __user *) from, n);
- if ((unsigned long)to < TASK_SIZE) {
- over = (unsigned long)to + n - TASK_SIZE;
- return __copy_tofrom_user(to, (__force void __user *) from, n - over) + over;
- }
- return n;
-}
-
-static inline unsigned long __copy_from_user(void *to, const void __user *from, unsigned long size)
-{
- return __copy_tofrom_user((__force void __user *)to, from, size);
-}
-
-static inline unsigned long __copy_to_user(void __user *to, const void *from, unsigned long size)
-{
- return __copy_tofrom_user(to, (__force void __user *)from, size);
-}
-
-#define __copy_to_user_inatomic __copy_to_user
-#define __copy_from_user_inatomic __copy_from_user
-
-extern unsigned long __clear_user(void __user *addr, unsigned long size);
-
-extern inline unsigned long
-clear_user(void __user *addr, unsigned long size)
-{
- if (access_ok(VERIFY_WRITE, addr, size))
- return __clear_user(addr, size);
- if ((unsigned long)addr < TASK_SIZE) {
- unsigned long over = (unsigned long)addr + size - TASK_SIZE;
- return __clear_user(addr, size - over) + over;
- }
- return size;
-}
-
-extern int __strncpy_from_user(char *dst, const char __user *src, long count);
-
-extern inline long
-strncpy_from_user(char *dst, const char __user *src, long count)
-{
- if (access_ok(VERIFY_READ, src, 1))
- return __strncpy_from_user(dst, src, count);
- return -EFAULT;
-}
-
-/*
- * Return the size of a string (including the ending 0)
- *
- * Return 0 for error
- */
-
-extern int __strnlen_user(const char __user *str, long len, unsigned long top);
-
-/*
- * Returns the length of the string at str (including the null byte),
- * or 0 if we hit a page we can't access,
- * or something > len if we didn't find a null byte.
- *
- * The `top' parameter to __strnlen_user is to make sure that
- * we can never overflow from the user area into kernel space.
- */
-extern __inline__ int strnlen_user(const char __user *str, long len)
-{
- unsigned long top = current->thread.fs.seg;
-
- if ((unsigned long)str > top)
- return 0;
- return __strnlen_user(str, len, top);
-}
-
-#define strlen_user(str) strnlen_user((str), 0x7ffffffe)
-
-#endif /* __ASSEMBLY__ */
-
-#endif /* _PPC_UACCESS_H */
-#endif /* __KERNEL__ */
diff --git a/include/asm-ppc/ucontext.h b/include/asm-ppc/ucontext.h
deleted file mode 100644
index 664bc984d51f..000000000000
--- a/include/asm-ppc/ucontext.h
+++ /dev/null
@@ -1,27 +0,0 @@
-#ifndef _ASMPPC_UCONTEXT_H
-#define _ASMPPC_UCONTEXT_H
-
-#include <asm/elf.h>
-#include <asm/signal.h>
-
-struct mcontext {
- elf_gregset_t mc_gregs;
- elf_fpregset_t mc_fregs;
- unsigned long mc_pad[2];
- elf_vrregset_t mc_vregs __attribute__((__aligned__(16)));
-};
-
-struct ucontext {
- unsigned long uc_flags;
- struct ucontext __user *uc_link;
- stack_t uc_stack;
- int uc_pad[7];
- struct mcontext __user *uc_regs;/* points to uc_mcontext field */
- sigset_t uc_sigmask;
- /* glibc has 1024-bit signal masks, ours are 64-bit */
- int uc_maskext[30];
- int uc_pad2[3];
- struct mcontext uc_mcontext;
-};
-
-#endif /* !_ASMPPC_UCONTEXT_H */
diff --git a/include/asm-ppc/vga.h b/include/asm-ppc/vga.h
deleted file mode 100644
index c5864734e3e1..000000000000
--- a/include/asm-ppc/vga.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Access to VGA videoram
- *
- * (c) 1998 Martin Mares <mj@ucw.cz>
- */
-
-#ifdef __KERNEL__
-#ifndef _LINUX_ASM_VGA_H_
-#define _LINUX_ASM_VGA_H_
-
-#include <asm/io.h>
-
-#include <linux/config.h>
-
-#if defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_MDA_CONSOLE)
-
-#define VT_BUF_HAVE_RW
-/*
- * These are only needed for supporting VGA or MDA text mode, which use little
- * endian byte ordering.
- * In other cases, we can optimize by using native byte ordering and
- * <linux/vt_buffer.h> has already done the right job for us.
- */
-
-extern inline void scr_writew(u16 val, volatile u16 *addr)
-{
- st_le16(addr, val);
-}
-
-extern inline u16 scr_readw(volatile const u16 *addr)
-{
- return ld_le16(addr);
-}
-
-#define VT_BUF_HAVE_MEMCPYW
-#define scr_memcpyw memcpy
-
-#endif /* !CONFIG_VGA_CONSOLE && !CONFIG_MDA_CONSOLE */
-
-extern unsigned long vgacon_remap_base;
-#define VGA_MAP_MEM(x) (x + vgacon_remap_base)
-#define vga_readb(x) (*(x))
-#define vga_writeb(x,y) (*(y) = (x))
-
-#endif
-#endif /* __KERNEL__ */
diff --git a/include/asm-ppc/xmon.h b/include/asm-ppc/xmon.h
deleted file mode 100644
index 042b83e6680d..000000000000
--- a/include/asm-ppc/xmon.h
+++ /dev/null
@@ -1,17 +0,0 @@
-#ifndef __PPC_XMON_H
-#define __PPC_XMON_H
-#ifdef __KERNEL__
-
-struct pt_regs;
-
-extern void xmon(struct pt_regs *excp);
-extern void xmon_printf(const char *fmt, ...);
-extern void xmon_map_scc(void);
-extern int xmon_bpt(struct pt_regs *regs);
-extern int xmon_sstep(struct pt_regs *regs);
-extern int xmon_iabr_match(struct pt_regs *regs);
-extern int xmon_dabr_match(struct pt_regs *regs);
-extern void (*xmon_fault_handler)(struct pt_regs *regs);
-
-#endif
-#endif
diff --git a/include/asm-ppc64/atomic.h b/include/asm-ppc64/atomic.h
deleted file mode 100644
index 0e5f25e83bc0..000000000000
--- a/include/asm-ppc64/atomic.h
+++ /dev/null
@@ -1,197 +0,0 @@
-/*
- * PowerPC64 atomic operations
- *
- * Copyright (C) 2001 Paul Mackerras <paulus@au.ibm.com>, IBM
- * Copyright (C) 2001 Anton Blanchard <anton@au.ibm.com>, IBM
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-
-#ifndef _ASM_PPC64_ATOMIC_H_
-#define _ASM_PPC64_ATOMIC_H_
-
-#include <asm/memory.h>
-
-typedef struct { volatile int counter; } atomic_t;
-
-#define ATOMIC_INIT(i) { (i) }
-
-#define atomic_read(v) ((v)->counter)
-#define atomic_set(v,i) (((v)->counter) = (i))
-
-static __inline__ void atomic_add(int a, atomic_t *v)
-{
- int t;
-
- __asm__ __volatile__(
-"1: lwarx %0,0,%3 # atomic_add\n\
- add %0,%2,%0\n\
- stwcx. %0,0,%3\n\
- bne- 1b"
- : "=&r" (t), "=m" (v->counter)
- : "r" (a), "r" (&v->counter), "m" (v->counter)
- : "cc");
-}
-
-static __inline__ int atomic_add_return(int a, atomic_t *v)
-{
- int t;
-
- __asm__ __volatile__(
- EIEIO_ON_SMP
-"1: lwarx %0,0,%2 # atomic_add_return\n\
- add %0,%1,%0\n\
- stwcx. %0,0,%2\n\
- bne- 1b"
- ISYNC_ON_SMP
- : "=&r" (t)
- : "r" (a), "r" (&v->counter)
- : "cc", "memory");
-
- return t;
-}
-
-#define atomic_add_negative(a, v) (atomic_add_return((a), (v)) < 0)
-
-static __inline__ void atomic_sub(int a, atomic_t *v)
-{
- int t;
-
- __asm__ __volatile__(
-"1: lwarx %0,0,%3 # atomic_sub\n\
- subf %0,%2,%0\n\
- stwcx. %0,0,%3\n\
- bne- 1b"
- : "=&r" (t), "=m" (v->counter)
- : "r" (a), "r" (&v->counter), "m" (v->counter)
- : "cc");
-}
-
-static __inline__ int atomic_sub_return(int a, atomic_t *v)
-{
- int t;
-
- __asm__ __volatile__(
- EIEIO_ON_SMP
-"1: lwarx %0,0,%2 # atomic_sub_return\n\
- subf %0,%1,%0\n\
- stwcx. %0,0,%2\n\
- bne- 1b"
- ISYNC_ON_SMP
- : "=&r" (t)
- : "r" (a), "r" (&v->counter)
- : "cc", "memory");
-
- return t;
-}
-
-static __inline__ void atomic_inc(atomic_t *v)
-{
- int t;
-
- __asm__ __volatile__(
-"1: lwarx %0,0,%2 # atomic_inc\n\
- addic %0,%0,1\n\
- stwcx. %0,0,%2\n\
- bne- 1b"
- : "=&r" (t), "=m" (v->counter)
- : "r" (&v->counter), "m" (v->counter)
- : "cc");
-}
-
-static __inline__ int atomic_inc_return(atomic_t *v)
-{
- int t;
-
- __asm__ __volatile__(
- EIEIO_ON_SMP
-"1: lwarx %0,0,%1 # atomic_inc_return\n\
- addic %0,%0,1\n\
- stwcx. %0,0,%1\n\
- bne- 1b"
- ISYNC_ON_SMP
- : "=&r" (t)
- : "r" (&v->counter)
- : "cc", "memory");
-
- return t;
-}
-
-/*
- * atomic_inc_and_test - increment and test
- * @v: pointer of type atomic_t
- *
- * Atomically increments @v by 1
- * and returns true if the result is zero, or false for all
- * other cases.
- */
-#define atomic_inc_and_test(v) (atomic_inc_return(v) == 0)
-
-static __inline__ void atomic_dec(atomic_t *v)
-{
- int t;
-
- __asm__ __volatile__(
-"1: lwarx %0,0,%2 # atomic_dec\n\
- addic %0,%0,-1\n\
- stwcx. %0,0,%2\n\
- bne- 1b"
- : "=&r" (t), "=m" (v->counter)
- : "r" (&v->counter), "m" (v->counter)
- : "cc");
-}
-
-static __inline__ int atomic_dec_return(atomic_t *v)
-{
- int t;
-
- __asm__ __volatile__(
- EIEIO_ON_SMP
-"1: lwarx %0,0,%1 # atomic_dec_return\n\
- addic %0,%0,-1\n\
- stwcx. %0,0,%1\n\
- bne- 1b"
- ISYNC_ON_SMP
- : "=&r" (t)
- : "r" (&v->counter)
- : "cc", "memory");
-
- return t;
-}
-
-#define atomic_sub_and_test(a, v) (atomic_sub_return((a), (v)) == 0)
-#define atomic_dec_and_test(v) (atomic_dec_return((v)) == 0)
-
-/*
- * Atomically test *v and decrement if it is greater than 0.
- * The function returns the old value of *v minus 1.
- */
-static __inline__ int atomic_dec_if_positive(atomic_t *v)
-{
- int t;
-
- __asm__ __volatile__(
- EIEIO_ON_SMP
-"1: lwarx %0,0,%1 # atomic_dec_if_positive\n\
- addic. %0,%0,-1\n\
- blt- 2f\n\
- stwcx. %0,0,%1\n\
- bne- 1b"
- ISYNC_ON_SMP
- "\n\
-2:" : "=&r" (t)
- : "r" (&v->counter)
- : "cc", "memory");
-
- return t;
-}
-
-#define smp_mb__before_atomic_dec() smp_mb()
-#define smp_mb__after_atomic_dec() smp_mb()
-#define smp_mb__before_atomic_inc() smp_mb()
-#define smp_mb__after_atomic_inc() smp_mb()
-
-#endif /* _ASM_PPC64_ATOMIC_H_ */
diff --git a/include/asm-ppc64/bitops.h b/include/asm-ppc64/bitops.h
deleted file mode 100644
index a0f831224f96..000000000000
--- a/include/asm-ppc64/bitops.h
+++ /dev/null
@@ -1,360 +0,0 @@
-/*
- * PowerPC64 atomic bit operations.
- * Dave Engebretsen, Todd Inglett, Don Reed, Pat McCarthy, Peter Bergner,
- * Anton Blanchard
- *
- * Originally taken from the 32b PPC code. Modified to use 64b values for
- * the various counters & memory references.
- *
- * Bitops are odd when viewed on big-endian systems. They were designed
- * on little endian so the size of the bitset doesn't matter (low order bytes
- * come first) as long as the bit in question is valid.
- *
- * Bits are "tested" often using the C expression (val & (1<<nr)) so we do
- * our best to stay compatible with that. The assumption is that val will
- * be unsigned long for such tests. As such, we assume the bits are stored
- * as an array of unsigned long (the usual case is a single unsigned long,
- * of course). Here's an example bitset with bit numbering:
- *
- * |63..........0|127........64|195.......128|255.......196|
- *
- * This leads to a problem. If an int, short or char is passed as a bitset
- * it will be a bad memory reference since we want to store in chunks
- * of unsigned long (64 bits here) size.
- *
- * There are a few little-endian macros used mostly for filesystem bitmaps,
- * these work on similar bit arrays layouts, but byte-oriented:
- *
- * |7...0|15...8|23...16|31...24|39...32|47...40|55...48|63...56|
- *
- * The main difference is that bit 3-5 in the bit number field needs to be
- * reversed compared to the big-endian bit fields. This can be achieved
- * by XOR with 0b111000 (0x38).
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-
-#ifndef _PPC64_BITOPS_H
-#define _PPC64_BITOPS_H
-
-#ifdef __KERNEL__
-
-#include <asm/memory.h>
-
-/*
- * clear_bit doesn't imply a memory barrier
- */
-#define smp_mb__before_clear_bit() smp_mb()
-#define smp_mb__after_clear_bit() smp_mb()
-
-static __inline__ int test_bit(unsigned long nr, __const__ volatile unsigned long *addr)
-{
- return (1UL & (addr[nr >> 6] >> (nr & 63)));
-}
-
-static __inline__ void set_bit(unsigned long nr, volatile unsigned long *addr)
-{
- unsigned long old;
- unsigned long mask = 1UL << (nr & 0x3f);
- unsigned long *p = ((unsigned long *)addr) + (nr >> 6);
-
- __asm__ __volatile__(
-"1: ldarx %0,0,%3 # set_bit\n\
- or %0,%0,%2\n\
- stdcx. %0,0,%3\n\
- bne- 1b"
- : "=&r" (old), "=m" (*p)
- : "r" (mask), "r" (p), "m" (*p)
- : "cc");
-}
-
-static __inline__ void clear_bit(unsigned long nr, volatile unsigned long *addr)
-{
- unsigned long old;
- unsigned long mask = 1UL << (nr & 0x3f);
- unsigned long *p = ((unsigned long *)addr) + (nr >> 6);
-
- __asm__ __volatile__(
-"1: ldarx %0,0,%3 # clear_bit\n\
- andc %0,%0,%2\n\
- stdcx. %0,0,%3\n\
- bne- 1b"
- : "=&r" (old), "=m" (*p)
- : "r" (mask), "r" (p), "m" (*p)
- : "cc");
-}
-
-static __inline__ void change_bit(unsigned long nr, volatile unsigned long *addr)
-{
- unsigned long old;
- unsigned long mask = 1UL << (nr & 0x3f);
- unsigned long *p = ((unsigned long *)addr) + (nr >> 6);
-
- __asm__ __volatile__(
-"1: ldarx %0,0,%3 # change_bit\n\
- xor %0,%0,%2\n\
- stdcx. %0,0,%3\n\
- bne- 1b"
- : "=&r" (old), "=m" (*p)
- : "r" (mask), "r" (p), "m" (*p)
- : "cc");
-}
-
-static __inline__ int test_and_set_bit(unsigned long nr, volatile unsigned long *addr)
-{
- unsigned long old, t;
- unsigned long mask = 1UL << (nr & 0x3f);
- unsigned long *p = ((unsigned long *)addr) + (nr >> 6);
-
- __asm__ __volatile__(
- EIEIO_ON_SMP
-"1: ldarx %0,0,%3 # test_and_set_bit\n\
- or %1,%0,%2 \n\
- stdcx. %1,0,%3 \n\
- bne- 1b"
- ISYNC_ON_SMP
- : "=&r" (old), "=&r" (t)
- : "r" (mask), "r" (p)
- : "cc", "memory");
-
- return (old & mask) != 0;
-}
-
-static __inline__ int test_and_clear_bit(unsigned long nr, volatile unsigned long *addr)
-{
- unsigned long old, t;
- unsigned long mask = 1UL << (nr & 0x3f);
- unsigned long *p = ((unsigned long *)addr) + (nr >> 6);
-
- __asm__ __volatile__(
- EIEIO_ON_SMP
-"1: ldarx %0,0,%3 # test_and_clear_bit\n\
- andc %1,%0,%2\n\
- stdcx. %1,0,%3\n\
- bne- 1b"
- ISYNC_ON_SMP
- : "=&r" (old), "=&r" (t)
- : "r" (mask), "r" (p)
- : "cc", "memory");
-
- return (old & mask) != 0;
-}
-
-static __inline__ int test_and_change_bit(unsigned long nr, volatile unsigned long *addr)
-{
- unsigned long old, t;
- unsigned long mask = 1UL << (nr & 0x3f);
- unsigned long *p = ((unsigned long *)addr) + (nr >> 6);
-
- __asm__ __volatile__(
- EIEIO_ON_SMP
-"1: ldarx %0,0,%3 # test_and_change_bit\n\
- xor %1,%0,%2\n\
- stdcx. %1,0,%3\n\
- bne- 1b"
- ISYNC_ON_SMP
- : "=&r" (old), "=&r" (t)
- : "r" (mask), "r" (p)
- : "cc", "memory");
-
- return (old & mask) != 0;
-}
-
-static __inline__ void set_bits(unsigned long mask, unsigned long *addr)
-{
- unsigned long old;
-
- __asm__ __volatile__(
-"1: ldarx %0,0,%3 # set_bit\n\
- or %0,%0,%2\n\
- stdcx. %0,0,%3\n\
- bne- 1b"
- : "=&r" (old), "=m" (*addr)
- : "r" (mask), "r" (addr), "m" (*addr)
- : "cc");
-}
-
-/*
- * non-atomic versions
- */
-static __inline__ void __set_bit(unsigned long nr, volatile unsigned long *addr)
-{
- unsigned long mask = 1UL << (nr & 0x3f);
- unsigned long *p = ((unsigned long *)addr) + (nr >> 6);
-
- *p |= mask;
-}
-
-static __inline__ void __clear_bit(unsigned long nr, volatile unsigned long *addr)
-{
- unsigned long mask = 1UL << (nr & 0x3f);
- unsigned long *p = ((unsigned long *)addr) + (nr >> 6);
-
- *p &= ~mask;
-}
-
-static __inline__ void __change_bit(unsigned long nr, volatile unsigned long *addr)
-{
- unsigned long mask = 1UL << (nr & 0x3f);
- unsigned long *p = ((unsigned long *)addr) + (nr >> 6);
-
- *p ^= mask;
-}
-
-static __inline__ int __test_and_set_bit(unsigned long nr, volatile unsigned long *addr)
-{
- unsigned long mask = 1UL << (nr & 0x3f);
- unsigned long *p = ((unsigned long *)addr) + (nr >> 6);
- unsigned long old = *p;
-
- *p = old | mask;
- return (old & mask) != 0;
-}
-
-static __inline__ int __test_and_clear_bit(unsigned long nr, volatile unsigned long *addr)
-{
- unsigned long mask = 1UL << (nr & 0x3f);
- unsigned long *p = ((unsigned long *)addr) + (nr >> 6);
- unsigned long old = *p;
-
- *p = old & ~mask;
- return (old & mask) != 0;
-}
-
-static __inline__ int __test_and_change_bit(unsigned long nr, volatile unsigned long *addr)
-{
- unsigned long mask = 1UL << (nr & 0x3f);
- unsigned long *p = ((unsigned long *)addr) + (nr >> 6);
- unsigned long old = *p;
-
- *p = old ^ mask;
- return (old & mask) != 0;
-}
-
-/*
- * Return the zero-based bit position (from RIGHT TO LEFT, 63 -> 0) of the
- * most significant (left-most) 1-bit in a double word.
- */
-static __inline__ int __ilog2(unsigned long x)
-{
- int lz;
-
- asm ("cntlzd %0,%1" : "=r" (lz) : "r" (x));
- return 63 - lz;
-}
-
-/*
- * Determines the bit position of the least significant (rightmost) 0 bit
- * in the specified double word. The returned bit position will be zero-based,
- * starting from the right side (63 - 0).
- */
-static __inline__ unsigned long ffz(unsigned long x)
-{
- /* no zero exists anywhere in the 8 byte area. */
- if ((x = ~x) == 0)
- return 64;
-
- /*
- * Calculate the bit position of the least signficant '1' bit in x
- * (since x has been changed this will actually be the least signficant
- * '0' bit in * the original x). Note: (x & -x) gives us a mask that
- * is the least significant * (RIGHT-most) 1-bit of the value in x.
- */
- return __ilog2(x & -x);
-}
-
-static __inline__ int __ffs(unsigned long x)
-{
- return __ilog2(x & -x);
-}
-
-/*
- * ffs: find first bit set. This is defined the same way as
- * the libc and compiler builtin ffs routines, therefore
- * differs in spirit from the above ffz (man ffs).
- */
-static __inline__ int ffs(int x)
-{
- unsigned long i = (unsigned long)x;
- return __ilog2(i & -i) + 1;
-}
-
-/*
- * fls: find last (most-significant) bit set.
- * Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32.
- */
-#define fls(x) generic_fls(x)
-
-/*
- * hweightN: returns the hamming weight (i.e. the number
- * of bits set) of a N-bit word
- */
-#define hweight64(x) generic_hweight64(x)
-#define hweight32(x) generic_hweight32(x)
-#define hweight16(x) generic_hweight16(x)
-#define hweight8(x) generic_hweight8(x)
-
-extern unsigned long find_next_zero_bit(const unsigned long *addr, unsigned long size, unsigned long offset);
-#define find_first_zero_bit(addr, size) \
- find_next_zero_bit((addr), (size), 0)
-
-extern unsigned long find_next_bit(const unsigned long *addr, unsigned long size, unsigned long offset);
-#define find_first_bit(addr, size) \
- find_next_bit((addr), (size), 0)
-
-extern unsigned long find_next_zero_le_bit(const unsigned long *addr, unsigned long size, unsigned long offset);
-#define find_first_zero_le_bit(addr, size) \
- find_next_zero_le_bit((addr), (size), 0)
-
-static __inline__ int test_le_bit(unsigned long nr, __const__ unsigned long * addr)
-{
- __const__ unsigned char *ADDR = (__const__ unsigned char *) addr;
- return (ADDR[nr >> 3] >> (nr & 7)) & 1;
-}
-
-#define test_and_clear_le_bit(nr, addr) \
- test_and_clear_bit((nr) ^ 0x38, (addr))
-#define test_and_set_le_bit(nr, addr) \
- test_and_set_bit((nr) ^ 0x38, (addr))
-
-/*
- * non-atomic versions
- */
-
-#define __set_le_bit(nr, addr) \
- __set_bit((nr) ^ 0x38, (addr))
-#define __clear_le_bit(nr, addr) \
- __clear_bit((nr) ^ 0x38, (addr))
-#define __test_and_clear_le_bit(nr, addr) \
- __test_and_clear_bit((nr) ^ 0x38, (addr))
-#define __test_and_set_le_bit(nr, addr) \
- __test_and_set_bit((nr) ^ 0x38, (addr))
-
-#define ext2_set_bit(nr,addr) \
- __test_and_set_le_bit((nr), (unsigned long*)addr)
-#define ext2_clear_bit(nr, addr) \
- __test_and_clear_le_bit((nr), (unsigned long*)addr)
-
-#define ext2_set_bit_atomic(lock, nr, addr) \
- test_and_set_le_bit((nr), (unsigned long*)addr)
-#define ext2_clear_bit_atomic(lock, nr, addr) \
- test_and_clear_le_bit((nr), (unsigned long*)addr)
-
-
-#define ext2_test_bit(nr, addr) test_le_bit((nr),(unsigned long*)addr)
-#define ext2_find_first_zero_bit(addr, size) \
- find_first_zero_le_bit((unsigned long*)addr, size)
-#define ext2_find_next_zero_bit(addr, size, off) \
- find_next_zero_le_bit((unsigned long*)addr, size, off)
-
-#define minix_test_and_set_bit(nr,addr) test_and_set_bit(nr,addr)
-#define minix_set_bit(nr,addr) set_bit(nr,addr)
-#define minix_test_and_clear_bit(nr,addr) test_and_clear_bit(nr,addr)
-#define minix_test_bit(nr,addr) test_bit(nr,addr)
-#define minix_find_first_zero_bit(addr,size) find_first_zero_bit(addr,size)
-
-#endif /* __KERNEL__ */
-#endif /* _PPC64_BITOPS_H */
diff --git a/include/asm-ppc64/bootinfo.h b/include/asm-ppc64/bootinfo.h
deleted file mode 100644
index f55e7cb48f46..000000000000
--- a/include/asm-ppc64/bootinfo.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Non-machine dependent bootinfo structure. Basic idea
- * borrowed from the m68k.
- *
- * Copyright (C) 1999 Cort Dougan <cort@ppc.kernel.org>
- * Copyright (c) 2001 PPC64 Team, IBM Corp
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-
-
-#ifndef _PPC64_BOOTINFO_H
-#define _PPC64_BOOTINFO_H
-
-#include <asm/types.h>
-
-/* We use a u32 for the type of the fields since they're written by
- * the bootloader which is a 32-bit process and read by the kernel
- * which is a 64-bit process. This way they can both agree on the
- * size of the type.
- */
-typedef u32 bi_rec_field;
-
-struct bi_record {
- bi_rec_field tag; /* tag ID */
- bi_rec_field size; /* size of record (in bytes) */
- bi_rec_field data[0]; /* data */
-};
-
-#define BI_FIRST 0x1010 /* first record - marker */
-#define BI_LAST 0x1011 /* last record - marker */
-#define BI_CMD_LINE 0x1012
-#define BI_BOOTLOADER_ID 0x1013
-#define BI_INITRD 0x1014
-#define BI_SYSMAP 0x1015
-#define BI_MACHTYPE 0x1016
-
-static __inline__ struct bi_record * bi_rec_init(unsigned long addr)
-{
- struct bi_record *bi_recs;
- bi_recs = (struct bi_record *)_ALIGN(addr, PAGE_SIZE);
- bi_recs->size = 0;
- return bi_recs;
-}
-
-static __inline__ struct bi_record * bi_rec_alloc(struct bi_record *rec,
- unsigned long args)
-{
- rec = (struct bi_record *)((unsigned long)rec + rec->size);
- rec->size = sizeof(struct bi_record) + args*sizeof(bi_rec_field);
- return rec;
-}
-
-static __inline__ struct bi_record * bi_rec_alloc_bytes(struct bi_record *rec,
- unsigned long bytes)
-{
- rec = (struct bi_record *)((unsigned long)rec + rec->size);
- rec->size = sizeof(struct bi_record) + bytes;
- return rec;
-}
-
-static __inline__ struct bi_record * bi_rec_next(struct bi_record *rec)
-{
- return (struct bi_record *)((unsigned long)rec + rec->size);
-}
-
-#endif /* _PPC64_BOOTINFO_H */
diff --git a/include/asm-ppc64/btext.h b/include/asm-ppc64/btext.h
index 67aef0cc72c0..71cce36bc630 100644
--- a/include/asm-ppc64/btext.h
+++ b/include/asm-ppc64/btext.h
@@ -15,6 +15,7 @@ extern int boot_text_mapped;
extern int btext_initialize(struct device_node *np);
extern void map_boot_text(void);
+extern void init_boot_display(void);
extern void btext_update_display(unsigned long phys, int width, int height,
int depth, int pitch);
diff --git a/include/asm-ppc64/cache.h b/include/asm-ppc64/cache.h
deleted file mode 100644
index 92140a7efbd1..000000000000
--- a/include/asm-ppc64/cache.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-#ifndef __ARCH_PPC64_CACHE_H
-#define __ARCH_PPC64_CACHE_H
-
-#include <asm/types.h>
-
-/* bytes per L1 cache line */
-#define L1_CACHE_SHIFT 7
-#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
-
-#define SMP_CACHE_BYTES L1_CACHE_BYTES
-#define L1_CACHE_SHIFT_MAX 7 /* largest L1 which this arch supports */
-
-#ifndef __ASSEMBLY__
-
-struct ppc64_caches {
- u32 dsize; /* L1 d-cache size */
- u32 dline_size; /* L1 d-cache line size */
- u32 log_dline_size;
- u32 dlines_per_page;
- u32 isize; /* L1 i-cache size */
- u32 iline_size; /* L1 i-cache line size */
- u32 log_iline_size;
- u32 ilines_per_page;
-};
-
-extern struct ppc64_caches ppc64_caches;
-
-#endif
-
-#endif
diff --git a/include/asm-ppc64/cputable.h b/include/asm-ppc64/cputable.h
deleted file mode 100644
index acc9b4d6c168..000000000000
--- a/include/asm-ppc64/cputable.h
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * include/asm-ppc64/cputable.h
- *
- * Copyright (C) 2001 Ben. Herrenschmidt (benh@kernel.crashing.org)
- *
- * Modifications for ppc64:
- * Copyright (C) 2003 Dave Engebretsen <engebret@us.ibm.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-
-#ifndef __ASM_PPC_CPUTABLE_H
-#define __ASM_PPC_CPUTABLE_H
-
-#include <linux/config.h>
-#include <asm/page.h> /* for ASM_CONST */
-
-/* Exposed to userland CPU features - Must match ppc32 definitions */
-#define PPC_FEATURE_32 0x80000000
-#define PPC_FEATURE_64 0x40000000
-#define PPC_FEATURE_601_INSTR 0x20000000
-#define PPC_FEATURE_HAS_ALTIVEC 0x10000000
-#define PPC_FEATURE_HAS_FPU 0x08000000
-#define PPC_FEATURE_HAS_MMU 0x04000000
-#define PPC_FEATURE_HAS_4xxMAC 0x02000000
-#define PPC_FEATURE_UNIFIED_CACHE 0x01000000
-
-#ifdef __KERNEL__
-
-#ifndef __ASSEMBLY__
-
-/* This structure can grow, it's real size is used by head.S code
- * via the mkdefs mechanism.
- */
-struct cpu_spec;
-struct op_ppc64_model;
-
-typedef void (*cpu_setup_t)(unsigned long offset, struct cpu_spec* spec);
-
-struct cpu_spec {
- /* CPU is matched via (PVR & pvr_mask) == pvr_value */
- unsigned int pvr_mask;
- unsigned int pvr_value;
-
- char *cpu_name;
- unsigned long cpu_features; /* Kernel features */
- unsigned int cpu_user_features; /* Userland features */
-
- /* cache line sizes */
- unsigned int icache_bsize;
- unsigned int dcache_bsize;
-
- /* number of performance monitor counters */
- unsigned int num_pmcs;
-
- /* this is called to initialize various CPU bits like L1 cache,
- * BHT, SPD, etc... from head.S before branching to identify_machine
- */
- cpu_setup_t cpu_setup;
-
- /* Used by oprofile userspace to select the right counters */
- char *oprofile_cpu_type;
-
- /* Processor specific oprofile operations */
- struct op_ppc64_model *oprofile_model;
-};
-
-extern struct cpu_spec cpu_specs[];
-extern struct cpu_spec *cur_cpu_spec;
-
-static inline unsigned long cpu_has_feature(unsigned long feature)
-{
- return cur_cpu_spec->cpu_features & feature;
-}
-
-#endif /* __ASSEMBLY__ */
-
-/* CPU kernel features */
-
-/* Retain the 32b definitions for the time being - use bottom half of word */
-#define CPU_FTR_SPLIT_ID_CACHE ASM_CONST(0x0000000000000001)
-#define CPU_FTR_L2CR ASM_CONST(0x0000000000000002)
-#define CPU_FTR_SPEC7450 ASM_CONST(0x0000000000000004)
-#define CPU_FTR_ALTIVEC ASM_CONST(0x0000000000000008)
-#define CPU_FTR_TAU ASM_CONST(0x0000000000000010)
-#define CPU_FTR_CAN_DOZE ASM_CONST(0x0000000000000020)
-#define CPU_FTR_USE_TB ASM_CONST(0x0000000000000040)
-#define CPU_FTR_604_PERF_MON ASM_CONST(0x0000000000000080)
-#define CPU_FTR_601 ASM_CONST(0x0000000000000100)
-#define CPU_FTR_HPTE_TABLE ASM_CONST(0x0000000000000200)
-#define CPU_FTR_CAN_NAP ASM_CONST(0x0000000000000400)
-#define CPU_FTR_L3CR ASM_CONST(0x0000000000000800)
-#define CPU_FTR_L3_DISABLE_NAP ASM_CONST(0x0000000000001000)
-#define CPU_FTR_NAP_DISABLE_L2_PR ASM_CONST(0x0000000000002000)
-#define CPU_FTR_DUAL_PLL_750FX ASM_CONST(0x0000000000004000)
-
-/* Add the 64b processor unique features in the top half of the word */
-#define CPU_FTR_SLB ASM_CONST(0x0000000100000000)
-#define CPU_FTR_16M_PAGE ASM_CONST(0x0000000200000000)
-#define CPU_FTR_TLBIEL ASM_CONST(0x0000000400000000)
-#define CPU_FTR_NOEXECUTE ASM_CONST(0x0000000800000000)
-#define CPU_FTR_NODSISRALIGN ASM_CONST(0x0000001000000000)
-#define CPU_FTR_IABR ASM_CONST(0x0000002000000000)
-#define CPU_FTR_MMCRA ASM_CONST(0x0000004000000000)
-/* unused ASM_CONST(0x0000008000000000) */
-#define CPU_FTR_SMT ASM_CONST(0x0000010000000000)
-#define CPU_FTR_COHERENT_ICACHE ASM_CONST(0x0000020000000000)
-#define CPU_FTR_LOCKLESS_TLBIE ASM_CONST(0x0000040000000000)
-#define CPU_FTR_MMCRA_SIHV ASM_CONST(0x0000080000000000)
-#define CPU_FTR_CTRL ASM_CONST(0x0000100000000000)
-
-#ifndef __ASSEMBLY__
-
-#define COMMON_USER_PPC64 (PPC_FEATURE_32 | PPC_FEATURE_64 | \
- PPC_FEATURE_HAS_FPU | PPC_FEATURE_HAS_MMU)
-
-#define CPU_FTR_PPCAS_ARCH_V2_BASE (CPU_FTR_SLB | \
- CPU_FTR_TLBIEL | CPU_FTR_NOEXECUTE | \
- CPU_FTR_NODSISRALIGN | CPU_FTR_CTRL)
-
-/* iSeries doesn't support large pages */
-#ifdef CONFIG_PPC_ISERIES
-#define CPU_FTR_PPCAS_ARCH_V2 (CPU_FTR_PPCAS_ARCH_V2_BASE)
-#else
-#define CPU_FTR_PPCAS_ARCH_V2 (CPU_FTR_PPCAS_ARCH_V2_BASE | CPU_FTR_16M_PAGE)
-#endif /* CONFIG_PPC_ISERIES */
-
-#endif /* __ASSEMBLY */
-
-#ifdef __ASSEMBLY__
-
-#define BEGIN_FTR_SECTION 98:
-
-#define END_FTR_SECTION(msk, val) \
-99: \
- .section __ftr_fixup,"a"; \
- .align 3; \
- .llong msk; \
- .llong val; \
- .llong 98b; \
- .llong 99b; \
- .previous
-
-#else
-
-#define BEGIN_FTR_SECTION "98:\n"
-#define END_FTR_SECTION(msk, val) \
-"99:\n" \
-" .section __ftr_fixup,\"a\";\n" \
-" .align 3;\n" \
-" .llong "#msk";\n" \
-" .llong "#val";\n" \
-" .llong 98b;\n" \
-" .llong 99b;\n" \
-" .previous\n"
-
-#endif /* __ASSEMBLY__ */
-
-#define END_FTR_SECTION_IFSET(msk) END_FTR_SECTION((msk), (msk))
-#define END_FTR_SECTION_IFCLR(msk) END_FTR_SECTION((msk), 0)
-
-#endif /* __ASM_PPC_CPUTABLE_H */
-#endif /* __KERNEL__ */
-
diff --git a/include/asm-ppc64/current.h b/include/asm-ppc64/current.h
deleted file mode 100644
index 52ddc60c8b65..000000000000
--- a/include/asm-ppc64/current.h
+++ /dev/null
@@ -1,16 +0,0 @@
-#ifndef _PPC64_CURRENT_H
-#define _PPC64_CURRENT_H
-
-#include <asm/paca.h>
-
-/*
- * 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.
- */
-
-#define get_current() (get_paca()->__current)
-#define current get_current()
-
-#endif /* !(_PPC64_CURRENT_H) */
diff --git a/include/asm-ppc64/dbdma.h b/include/asm-ppc64/dbdma.h
deleted file mode 100644
index f2d5d5dc3377..000000000000
--- a/include/asm-ppc64/dbdma.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include <asm-ppc/dbdma.h>
-
diff --git a/include/asm-ppc64/dma.h b/include/asm-ppc64/dma.h
deleted file mode 100644
index dfd1f69059ba..000000000000
--- a/include/asm-ppc64/dma.h
+++ /dev/null
@@ -1,329 +0,0 @@
-/*
- * linux/include/asm/dma.h: Defines for using and allocating dma channels.
- * Written by Hennus Bergman, 1992.
- * High DMA channel support & info by Hannu Savolainen
- * and John Boyd, Nov. 1992.
- * Changes for ppc sound by Christoph Nadig
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-
-#ifndef _ASM_DMA_H
-#define _ASM_DMA_H
-
-#include <linux/config.h>
-#include <asm/io.h>
-#include <linux/spinlock.h>
-#include <asm/system.h>
-
-#ifndef MAX_DMA_CHANNELS
-#define MAX_DMA_CHANNELS 8
-#endif
-
-/* The maximum address that we can perform a DMA transfer to on this platform */
-/* Doesn't really apply... */
-#define MAX_DMA_ADDRESS (~0UL)
-
-#if !defined(CONFIG_PPC_ISERIES) || defined(CONFIG_PCI)
-
-#define dma_outb outb
-#define dma_inb inb
-
-/*
- * NOTES about DMA transfers:
- *
- * controller 1: channels 0-3, byte operations, ports 00-1F
- * controller 2: channels 4-7, word operations, ports C0-DF
- *
- * - ALL registers are 8 bits only, regardless of transfer size
- * - channel 4 is not used - cascades 1 into 2.
- * - channels 0-3 are byte - addresses/counts are for physical bytes
- * - channels 5-7 are word - addresses/counts are for physical words
- * - transfers must not cross physical 64K (0-3) or 128K (5-7) boundaries
- * - transfer count loaded to registers is 1 less than actual count
- * - controller 2 offsets are all even (2x offsets for controller 1)
- * - page registers for 5-7 don't use data bit 0, represent 128K pages
- * - page registers for 0-3 use bit 0, represent 64K pages
- *
- * On PReP, DMA transfers are limited to the lower 16MB of _physical_ memory.
- * On CHRP, the W83C553F (and VLSI Tollgate?) support full 32 bit addressing.
- * Note that addresses loaded into registers must be _physical_ addresses,
- * not logical addresses (which may differ if paging is active).
- *
- * Address mapping for channels 0-3:
- *
- * A23 ... A16 A15 ... A8 A7 ... A0 (Physical addresses)
- * | ... | | ... | | ... |
- * | ... | | ... | | ... |
- * | ... | | ... | | ... |
- * P7 ... P0 A7 ... A0 A7 ... A0
- * | Page | Addr MSB | Addr LSB | (DMA registers)
- *
- * Address mapping for channels 5-7:
- *
- * A23 ... A17 A16 A15 ... A9 A8 A7 ... A1 A0 (Physical addresses)
- * | ... | \ \ ... \ \ \ ... \ \
- * | ... | \ \ ... \ \ \ ... \ (not used)
- * | ... | \ \ ... \ \ \ ... \
- * P7 ... P1 (0) A7 A6 ... A0 A7 A6 ... A0
- * | Page | Addr MSB | Addr LSB | (DMA registers)
- *
- * Again, channels 5-7 transfer _physical_ words (16 bits), so addresses
- * and counts _must_ be word-aligned (the lowest address bit is _ignored_ at
- * the hardware level, so odd-byte transfers aren't possible).
- *
- * Transfer count (_not # bytes_) is limited to 64K, represented as actual
- * count - 1 : 64K => 0xFFFF, 1 => 0x0000. Thus, count is always 1 or more,
- * and up to 128K bytes may be transferred on channels 5-7 in one operation.
- *
- */
-
-/* 8237 DMA controllers */
-#define IO_DMA1_BASE 0x00 /* 8 bit slave DMA, channels 0..3 */
-#define IO_DMA2_BASE 0xC0 /* 16 bit master DMA, ch 4(=slave input)..7 */
-
-/* DMA controller registers */
-#define DMA1_CMD_REG 0x08 /* command register (w) */
-#define DMA1_STAT_REG 0x08 /* status register (r) */
-#define DMA1_REQ_REG 0x09 /* request register (w) */
-#define DMA1_MASK_REG 0x0A /* single-channel mask (w) */
-#define DMA1_MODE_REG 0x0B /* mode register (w) */
-#define DMA1_CLEAR_FF_REG 0x0C /* clear pointer flip-flop (w) */
-#define DMA1_TEMP_REG 0x0D /* Temporary Register (r) */
-#define DMA1_RESET_REG 0x0D /* Master Clear (w) */
-#define DMA1_CLR_MASK_REG 0x0E /* Clear Mask */
-#define DMA1_MASK_ALL_REG 0x0F /* all-channels mask (w) */
-
-#define DMA2_CMD_REG 0xD0 /* command register (w) */
-#define DMA2_STAT_REG 0xD0 /* status register (r) */
-#define DMA2_REQ_REG 0xD2 /* request register (w) */
-#define DMA2_MASK_REG 0xD4 /* single-channel mask (w) */
-#define DMA2_MODE_REG 0xD6 /* mode register (w) */
-#define DMA2_CLEAR_FF_REG 0xD8 /* clear pointer flip-flop (w) */
-#define DMA2_TEMP_REG 0xDA /* Temporary Register (r) */
-#define DMA2_RESET_REG 0xDA /* Master Clear (w) */
-#define DMA2_CLR_MASK_REG 0xDC /* Clear Mask */
-#define DMA2_MASK_ALL_REG 0xDE /* all-channels mask (w) */
-
-#define DMA_ADDR_0 0x00 /* DMA address registers */
-#define DMA_ADDR_1 0x02
-#define DMA_ADDR_2 0x04
-#define DMA_ADDR_3 0x06
-#define DMA_ADDR_4 0xC0
-#define DMA_ADDR_5 0xC4
-#define DMA_ADDR_6 0xC8
-#define DMA_ADDR_7 0xCC
-
-#define DMA_CNT_0 0x01 /* DMA count registers */
-#define DMA_CNT_1 0x03
-#define DMA_CNT_2 0x05
-#define DMA_CNT_3 0x07
-#define DMA_CNT_4 0xC2
-#define DMA_CNT_5 0xC6
-#define DMA_CNT_6 0xCA
-#define DMA_CNT_7 0xCE
-
-#define DMA_LO_PAGE_0 0x87 /* DMA page registers */
-#define DMA_LO_PAGE_1 0x83
-#define DMA_LO_PAGE_2 0x81
-#define DMA_LO_PAGE_3 0x82
-#define DMA_LO_PAGE_5 0x8B
-#define DMA_LO_PAGE_6 0x89
-#define DMA_LO_PAGE_7 0x8A
-
-#define DMA_HI_PAGE_0 0x487 /* DMA page registers */
-#define DMA_HI_PAGE_1 0x483
-#define DMA_HI_PAGE_2 0x481
-#define DMA_HI_PAGE_3 0x482
-#define DMA_HI_PAGE_5 0x48B
-#define DMA_HI_PAGE_6 0x489
-#define DMA_HI_PAGE_7 0x48A
-
-#define DMA1_EXT_REG 0x40B
-#define DMA2_EXT_REG 0x4D6
-
-#define DMA_MODE_READ 0x44 /* I/O to memory, no autoinit, increment, single mode */
-#define DMA_MODE_WRITE 0x48 /* memory to I/O, no autoinit, increment, single mode */
-#define DMA_MODE_CASCADE 0xC0 /* pass thru DREQ->HRQ, DACK<-HLDA only */
-
-#define DMA_AUTOINIT 0x10
-
-extern spinlock_t dma_spin_lock;
-
-static __inline__ unsigned long claim_dma_lock(void)
-{
- unsigned long flags;
- spin_lock_irqsave(&dma_spin_lock, flags);
- return flags;
-}
-
-static __inline__ void release_dma_lock(unsigned long flags)
-{
- spin_unlock_irqrestore(&dma_spin_lock, flags);
-}
-
-/* enable/disable a specific DMA channel */
-static __inline__ void enable_dma(unsigned int dmanr)
-{
- unsigned char ucDmaCmd=0x00;
-
- if (dmanr != 4)
- {
- dma_outb(0, DMA2_MASK_REG); /* This may not be enabled */
- dma_outb(ucDmaCmd, DMA2_CMD_REG); /* Enable group */
- }
- if (dmanr<=3)
- {
- dma_outb(dmanr, DMA1_MASK_REG);
- dma_outb(ucDmaCmd, DMA1_CMD_REG); /* Enable group */
- } else
- {
- dma_outb(dmanr & 3, DMA2_MASK_REG);
- }
-}
-
-static __inline__ void disable_dma(unsigned int dmanr)
-{
- if (dmanr<=3)
- dma_outb(dmanr | 4, DMA1_MASK_REG);
- else
- dma_outb((dmanr & 3) | 4, DMA2_MASK_REG);
-}
-
-/* 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! ---
- */
-static __inline__ void clear_dma_ff(unsigned int dmanr)
-{
- if (dmanr<=3)
- dma_outb(0, DMA1_CLEAR_FF_REG);
- else
- dma_outb(0, DMA2_CLEAR_FF_REG);
-}
-
-/* set mode (above) for a specific DMA channel */
-static __inline__ void set_dma_mode(unsigned int dmanr, char mode)
-{
- if (dmanr<=3)
- dma_outb(mode | dmanr, DMA1_MODE_REG);
- else
- dma_outb(mode | (dmanr&3), DMA2_MODE_REG);
-}
-
-/* Set only the page register bits of the transfer address.
- * This is used for successive transfers when we know the contents of
- * the lower 16 bits of the DMA current address register, but a 64k boundary
- * may have been crossed.
- */
-static __inline__ void set_dma_page(unsigned int dmanr, int pagenr)
-{
- switch(dmanr) {
- case 0:
- dma_outb(pagenr, DMA_LO_PAGE_0);
- dma_outb(pagenr>>8, DMA_HI_PAGE_0);
- break;
- case 1:
- dma_outb(pagenr, DMA_LO_PAGE_1);
- dma_outb(pagenr>>8, DMA_HI_PAGE_1);
- break;
- case 2:
- dma_outb(pagenr, DMA_LO_PAGE_2);
- dma_outb(pagenr>>8, DMA_HI_PAGE_2);
- break;
- case 3:
- dma_outb(pagenr, DMA_LO_PAGE_3);
- dma_outb(pagenr>>8, DMA_HI_PAGE_3);
- break;
- case 5:
- dma_outb(pagenr & 0xfe, DMA_LO_PAGE_5);
- dma_outb(pagenr>>8, DMA_HI_PAGE_5);
- break;
- case 6:
- dma_outb(pagenr & 0xfe, DMA_LO_PAGE_6);
- dma_outb(pagenr>>8, DMA_HI_PAGE_6);
- break;
- case 7:
- dma_outb(pagenr & 0xfe, DMA_LO_PAGE_7);
- dma_outb(pagenr>>8, DMA_HI_PAGE_7);
- break;
- }
-}
-
-
-/* Set transfer address & page bits for specific DMA channel.
- * Assumes dma flipflop is clear.
- */
-static __inline__ void set_dma_addr(unsigned int dmanr, unsigned int phys)
-{
- if (dmanr <= 3) {
- dma_outb( phys & 0xff, ((dmanr&3)<<1) + IO_DMA1_BASE );
- dma_outb( (phys>>8) & 0xff, ((dmanr&3)<<1) + IO_DMA1_BASE );
- } else {
- dma_outb( (phys>>1) & 0xff, ((dmanr&3)<<2) + IO_DMA2_BASE );
- dma_outb( (phys>>9) & 0xff, ((dmanr&3)<<2) + IO_DMA2_BASE );
- }
- set_dma_page(dmanr, phys>>16);
-}
-
-
-/* Set transfer size (max 64k for DMA1..3, 128k for DMA5..7) for
- * a specific DMA channel.
- * You must ensure the parameters are valid.
- * NOTE: from a manual: "the number of transfers is one more
- * than the initial word count"! This is taken into account.
- * Assumes dma flip-flop is clear.
- * NOTE 2: "count" represents _bytes_ and must be even for channels 5-7.
- */
-static __inline__ void set_dma_count(unsigned int dmanr, unsigned int count)
-{
- count--;
- if (dmanr <= 3) {
- dma_outb( count & 0xff, ((dmanr&3)<<1) + 1 + IO_DMA1_BASE );
- dma_outb( (count>>8) & 0xff, ((dmanr&3)<<1) + 1 + IO_DMA1_BASE );
- } else {
- dma_outb( (count>>1) & 0xff, ((dmanr&3)<<2) + 2 + IO_DMA2_BASE );
- dma_outb( (count>>9) & 0xff, ((dmanr&3)<<2) + 2 + IO_DMA2_BASE );
- }
-}
-
-
-/* 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.
- * If called before the channel has been used, it may return 1.
- * Otherwise, it returns the number of _bytes_ left to transfer.
- *
- * Assumes DMA flip-flop is clear.
- */
-static __inline__ int get_dma_residue(unsigned int dmanr)
-{
- unsigned int io_port = (dmanr<=3)? ((dmanr&3)<<1) + 1 + IO_DMA1_BASE
- : ((dmanr&3)<<2) + 2 + IO_DMA2_BASE;
-
- /* using short to get 16-bit wrap around */
- unsigned short count;
-
- count = 1 + dma_inb(io_port);
- count += dma_inb(io_port) << 8;
-
- return (dmanr <= 3)? count : (count<<1);
-}
-
-/* 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 */
-
-#ifdef CONFIG_PCI
-extern int isa_dma_bridge_buggy;
-#else
-#define isa_dma_bridge_buggy (0)
-#endif
-#endif /* !defined(CONFIG_PPC_ISERIES) || defined(CONFIG_PCI) */
-#endif /* _ASM_DMA_H */
diff --git a/include/asm-ppc64/eeh.h b/include/asm-ppc64/eeh.h
index 40c8eb57493e..89f26ab31908 100644
--- a/include/asm-ppc64/eeh.h
+++ b/include/asm-ppc64/eeh.h
@@ -1,4 +1,4 @@
-/*
+/*
* eeh.h
* Copyright (C) 2001 Dave Engebretsen & Todd Inglett IBM Corporation.
*
@@ -6,12 +6,12 @@
* 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
@@ -27,8 +27,6 @@
struct pci_dev;
struct device_node;
-struct device_node;
-struct notifier_block;
#ifdef CONFIG_EEH
@@ -37,6 +35,10 @@ struct notifier_block;
#define EEH_MODE_NOCHECK (1<<1)
#define EEH_MODE_ISOLATED (1<<2)
+/* Max number of EEH freezes allowed before we consider the device
+ * to be permanently disabled. */
+#define EEH_MAX_ALLOWED_FREEZES 5
+
void __init eeh_init(void);
unsigned long eeh_check_failure(const volatile void __iomem *token,
unsigned long val);
@@ -59,36 +61,14 @@ void eeh_add_device_late(struct pci_dev *);
* eeh_remove_device - undo EEH setup for the indicated pci device
* @dev: pci device to be removed
*
- * This routine should be when a device is removed from a running
- * system (e.g. by hotplug or dlpar).
+ * This routine should be called when a device is removed from
+ * a running system (e.g. by hotplug or dlpar). It unregisters
+ * the PCI device from the EEH subsystem. I/O errors affecting
+ * this device will no longer be detected after this call; thus,
+ * i/o errors affecting this slot may leave this device unusable.
*/
void eeh_remove_device(struct pci_dev *);
-#define EEH_DISABLE 0
-#define EEH_ENABLE 1
-#define EEH_RELEASE_LOADSTORE 2
-#define EEH_RELEASE_DMA 3
-
-/**
- * Notifier event flags.
- */
-#define EEH_NOTIFY_FREEZE 1
-
-/** EEH event -- structure holding pci slot data that describes
- * a change in the isolation status of a PCI slot. A pointer
- * to this struct is passed as the data pointer in a notify callback.
- */
-struct eeh_event {
- struct list_head list;
- struct pci_dev *dev;
- struct device_node *dn;
- int reset_state;
-};
-
-/** Register to find out about EEH events. */
-int eeh_register_notifier(struct notifier_block *nb);
-int eeh_unregister_notifier(struct notifier_block *nb);
-
/**
* EEH_POSSIBLE_ERROR() -- test for possible MMIO failure.
*
@@ -129,7 +109,7 @@ static inline void eeh_remove_device(struct pci_dev *dev) { }
#define EEH_IO_ERROR_VALUE(size) (-1UL)
#endif /* CONFIG_EEH */
-/*
+/*
* MMIO read/write operations with EEH support.
*/
static inline u8 eeh_readb(const volatile void __iomem *addr)
diff --git a/include/asm-ppc64/hardirq.h b/include/asm-ppc64/hardirq.h
deleted file mode 100644
index 4ee72bb1fd48..000000000000
--- a/include/asm-ppc64/hardirq.h
+++ /dev/null
@@ -1,27 +0,0 @@
-#ifndef __ASM_HARDIRQ_H
-#define __ASM_HARDIRQ_H
-
-/*
- * 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/config.h>
-#include <linux/cache.h>
-#include <linux/preempt.h>
-
-typedef struct {
- unsigned int __softirq_pending;
-} ____cacheline_aligned irq_cpustat_t;
-
-#include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */
-
-static inline void ack_bad_irq(int irq)
-{
- printk(KERN_CRIT "illegal vector %d received!\n", irq);
- BUG();
-}
-
-#endif /* __ASM_HARDIRQ_H */
diff --git a/include/asm-ppc64/ide.h b/include/asm-ppc64/ide.h
deleted file mode 100644
index 0aae1c590c0e..000000000000
--- a/include/asm-ppc64/ide.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * linux/include/asm-ppc/ide.h
- *
- * Copyright (C) 1994-1996 Linus Torvalds & authors
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-
-/*
- * This file contains the ppc64 architecture specific IDE code.
- */
-
-#ifndef __ASMPPC64_IDE_H
-#define __ASMPPC64_IDE_H
-
-#ifdef __KERNEL__
-
-#ifndef MAX_HWIFS
-# define MAX_HWIFS 10
-#endif
-
-#define IDE_ARCH_OBSOLETE_INIT
-#define ide_default_io_ctl(base) ((base) + 0x206) /* obsolete */
-
-#endif /* __KERNEL__ */
-
-#endif /* __ASMPPC64_IDE_H */
diff --git a/include/asm-ppc64/io.h b/include/asm-ppc64/io.h
index 59c958aea4db..77fc07c3c6bd 100644
--- a/include/asm-ppc64/io.h
+++ b/include/asm-ppc64/io.h
@@ -13,9 +13,9 @@
#include <asm/page.h>
#include <asm/byteorder.h>
#ifdef CONFIG_PPC_ISERIES
-#include <asm/iSeries/iSeries_io.h>
+#include <asm/iseries/iseries_io.h>
#endif
-#include <asm/memory.h>
+#include <asm/synch.h>
#include <asm/delay.h>
#include <asm-generic/iomap.h>
diff --git a/include/asm-ppc64/ipcbuf.h b/include/asm-ppc64/ipcbuf.h
deleted file mode 100644
index fa393c8342af..000000000000
--- a/include/asm-ppc64/ipcbuf.h
+++ /dev/null
@@ -1,28 +0,0 @@
-#ifndef __PPC64_IPCBUF_H__
-#define __PPC64_IPCBUF_H__
-
-/*
- * The ipc64_perm structure for the PPC is identical to kern_ipc_perm
- * as we have always had 32-bit UIDs and GIDs in the kernel.
- *
- * 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.
- */
-
-struct ipc64_perm
-{
- __kernel_key_t key;
- __kernel_uid_t uid;
- __kernel_gid_t gid;
- __kernel_uid_t cuid;
- __kernel_gid_t cgid;
- __kernel_mode_t mode;
- unsigned int seq;
- unsigned int __pad1;
- unsigned long __unused1;
- unsigned long __unused2;
-};
-
-#endif /* __PPC64_IPCBUF_H__ */
diff --git a/include/asm-ppc64/irq.h b/include/asm-ppc64/irq.h
deleted file mode 100644
index 99782afb4cde..000000000000
--- a/include/asm-ppc64/irq.h
+++ /dev/null
@@ -1,120 +0,0 @@
-#ifdef __KERNEL__
-#ifndef _ASM_IRQ_H
-#define _ASM_IRQ_H
-
-/*
- * 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/config.h>
-#include <linux/threads.h>
-
-/*
- * Maximum number of interrupt sources that we can handle.
- */
-#define NR_IRQS 512
-
-/* this number is used when no interrupt has been assigned */
-#define NO_IRQ (-1)
-
-/*
- * These constants are used for passing information about interrupt
- * signal polarity and level/edge sensing to the low-level PIC chip
- * drivers.
- */
-#define IRQ_SENSE_MASK 0x1
-#define IRQ_SENSE_LEVEL 0x1 /* interrupt on active level */
-#define IRQ_SENSE_EDGE 0x0 /* interrupt triggered by edge */
-
-#define IRQ_POLARITY_MASK 0x2
-#define IRQ_POLARITY_POSITIVE 0x2 /* high level or low->high edge */
-#define IRQ_POLARITY_NEGATIVE 0x0 /* low level or high->low edge */
-
-/*
- * IRQ line status macro IRQ_PER_CPU is used
- */
-#define ARCH_HAS_IRQ_PER_CPU
-
-#define get_irq_desc(irq) (&irq_desc[(irq)])
-
-/* Define a way to iterate across irqs. */
-#define for_each_irq(i) \
- for ((i) = 0; (i) < NR_IRQS; ++(i))
-
-/* Interrupt numbers are virtual in case they are sparsely
- * distributed by the hardware.
- */
-extern unsigned int virt_irq_to_real_map[NR_IRQS];
-
-/* Create a mapping for a real_irq if it doesn't already exist.
- * Return the virtual irq as a convenience.
- */
-int virt_irq_create_mapping(unsigned int real_irq);
-void virt_irq_init(void);
-
-static inline unsigned int virt_irq_to_real(unsigned int virt_irq)
-{
- return virt_irq_to_real_map[virt_irq];
-}
-
-extern unsigned int real_irq_to_virt_slowpath(unsigned int real_irq);
-
-/*
- * Because many systems have two overlapping names spaces for
- * interrupts (ISA and XICS for example), and the ISA interrupts
- * have historically not been easy to renumber, we allow ISA
- * interrupts to take values 0 - 15, and shift up the remaining
- * interrupts by 0x10.
- */
-#define NUM_ISA_INTERRUPTS 0x10
-extern int __irq_offset_value;
-
-static inline int irq_offset_up(int irq)
-{
- return(irq + __irq_offset_value);
-}
-
-static inline int irq_offset_down(int irq)
-{
- return(irq - __irq_offset_value);
-}
-
-static inline int irq_offset_value(void)
-{
- return __irq_offset_value;
-}
-
-static __inline__ int irq_canonicalize(int irq)
-{
- return irq;
-}
-
-extern int distribute_irqs;
-
-struct irqaction;
-struct pt_regs;
-
-#ifdef CONFIG_IRQSTACKS
-/*
- * Per-cpu stacks for handling hard and soft interrupts.
- */
-extern struct thread_info *hardirq_ctx[NR_CPUS];
-extern struct thread_info *softirq_ctx[NR_CPUS];
-
-extern void irq_ctx_init(void);
-extern void call_do_softirq(struct thread_info *tp);
-extern int call_handle_IRQ_event(int irq, struct pt_regs *regs,
- struct irqaction *action, struct thread_info *tp);
-
-#define __ARCH_HAS_DO_SOFTIRQ
-
-#else
-#define irq_ctx_init()
-
-#endif /* CONFIG_IRQSTACKS */
-
-#endif /* _ASM_IRQ_H */
-#endif /* __KERNEL__ */
diff --git a/include/asm-ppc64/kexec.h b/include/asm-ppc64/kexec.h
deleted file mode 100644
index 511908afaeeb..000000000000
--- a/include/asm-ppc64/kexec.h
+++ /dev/null
@@ -1,41 +0,0 @@
-#ifndef _PPC64_KEXEC_H
-#define _PPC64_KEXEC_H
-
-/*
- * KEXEC_SOURCE_MEMORY_LIMIT maximum page get_free_page can return.
- * I.e. Maximum page that is mapped directly into kernel memory,
- * and kmap is not required.
- */
-
-/* Maximum physical address we can use pages from */
-/* XXX: since we copy virt we can use any page we allocate */
-#define KEXEC_SOURCE_MEMORY_LIMIT (-1UL)
-
-/* Maximum address we can reach in physical address mode */
-/* XXX: I want to allow initrd in highmem. otherwise set to rmo on lpar */
-#define KEXEC_DESTINATION_MEMORY_LIMIT (-1UL)
-
-/* Maximum address we can use for the control code buffer */
-/* XXX: unused today, ppc32 uses TASK_SIZE, probably left over from use_mm */
-#define KEXEC_CONTROL_MEMORY_LIMIT (-1UL)
-
-/* XXX: today we don't use this at all, althogh we have a static stack */
-#define KEXEC_CONTROL_CODE_SIZE 4096
-
-/* The native architecture */
-#define KEXEC_ARCH KEXEC_ARCH_PPC64
-
-#define MAX_NOTE_BYTES 1024
-
-#ifndef __ASSEMBLY__
-
-typedef u32 note_buf_t[MAX_NOTE_BYTES/4];
-
-extern note_buf_t crash_notes[];
-
-extern void kexec_smp_wait(void); /* get and clear naca physid, wait for
- master to copy new code to 0 */
-
-#endif /* __ASSEMBLY__ */
-#endif /* _PPC_KEXEC_H */
-
diff --git a/include/asm-ppc64/keylargo.h b/include/asm-ppc64/keylargo.h
deleted file mode 100644
index 4d78e3d0314c..000000000000
--- a/include/asm-ppc64/keylargo.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include <asm-ppc/keylargo.h>
-
diff --git a/include/asm-ppc64/kmap_types.h b/include/asm-ppc64/kmap_types.h
deleted file mode 100644
index fd1574648223..000000000000
--- a/include/asm-ppc64/kmap_types.h
+++ /dev/null
@@ -1,23 +0,0 @@
-#ifdef __KERNEL__
-#ifndef _ASM_KMAP_TYPES_H
-#define _ASM_KMAP_TYPES_H
-
-enum km_type {
- KM_BOUNCE_READ,
- KM_SKB_SUNRPC_DATA,
- KM_SKB_DATA_SOFTIRQ,
- KM_USER0,
- KM_USER1,
- KM_BIO_SRC_IRQ,
- KM_BIO_DST_IRQ,
- KM_PTE0,
- KM_PTE1,
- KM_IRQ0,
- KM_IRQ1,
- KM_SOFTIRQ0,
- KM_SOFTIRQ1,
- KM_TYPE_NR
-};
-
-#endif
-#endif /* __KERNEL__ */
diff --git a/include/asm-ppc64/macio.h b/include/asm-ppc64/macio.h
deleted file mode 100644
index a3028b364f70..000000000000
--- a/include/asm-ppc64/macio.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include <asm-ppc/macio.h>
-
diff --git a/include/asm-ppc64/memory.h b/include/asm-ppc64/memory.h
deleted file mode 100644
index af53ffb55726..000000000000
--- a/include/asm-ppc64/memory.h
+++ /dev/null
@@ -1,61 +0,0 @@
-#ifndef _ASM_PPC64_MEMORY_H_
-#define _ASM_PPC64_MEMORY_H_
-
-/*
- * 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/config.h>
-
-/*
- * Arguably the bitops and *xchg operations don't imply any memory barrier
- * or SMP ordering, but in fact a lot of drivers expect them to imply
- * both, since they do on x86 cpus.
- */
-#ifdef CONFIG_SMP
-#define EIEIO_ON_SMP "eieio\n"
-#define ISYNC_ON_SMP "\n\tisync"
-#define SYNC_ON_SMP "lwsync\n\t"
-#else
-#define EIEIO_ON_SMP
-#define ISYNC_ON_SMP
-#define SYNC_ON_SMP
-#endif
-
-static inline void eieio(void)
-{
- __asm__ __volatile__ ("eieio" : : : "memory");
-}
-
-static inline void isync(void)
-{
- __asm__ __volatile__ ("isync" : : : "memory");
-}
-
-#ifdef CONFIG_SMP
-#define eieio_on_smp() eieio()
-#define isync_on_smp() isync()
-#else
-#define eieio_on_smp() __asm__ __volatile__("": : :"memory")
-#define isync_on_smp() __asm__ __volatile__("": : :"memory")
-#endif
-
-/* Macros for adjusting thread priority (hardware multi-threading) */
-#define HMT_very_low() asm volatile("or 31,31,31 # very low priority")
-#define HMT_low() asm volatile("or 1,1,1 # low priority")
-#define HMT_medium_low() asm volatile("or 6,6,6 # medium low priority")
-#define HMT_medium() asm volatile("or 2,2,2 # medium priority")
-#define HMT_medium_high() asm volatile("or 5,5,5 # medium high priority")
-#define HMT_high() asm volatile("or 3,3,3 # high priority")
-
-#define HMT_VERY_LOW "\tor 31,31,31 # very low priority\n"
-#define HMT_LOW "\tor 1,1,1 # low priority\n"
-#define HMT_MEDIUM_LOW "\tor 6,6,6 # medium low priority\n"
-#define HMT_MEDIUM "\tor 2,2,2 # medium priority\n"
-#define HMT_MEDIUM_HIGH "\tor 5,5,5 # medium high priority\n"
-#define HMT_HIGH "\tor 3,3,3 # high priority\n"
-
-#endif
diff --git a/include/asm-ppc64/mmu.h b/include/asm-ppc64/mmu.h
index 7bc42eb087ad..1a7e0afa2dc6 100644
--- a/include/asm-ppc64/mmu.h
+++ b/include/asm-ppc64/mmu.h
@@ -14,6 +14,7 @@
#define _PPC64_MMU_H_
#include <linux/config.h>
+#include <asm/asm-compat.h>
#include <asm/page.h>
/*
@@ -29,7 +30,7 @@
/* Location of cpu0's segment table */
#define STAB0_PAGE 0x6
-#define STAB0_PHYS_ADDR (STAB0_PAGE<<PAGE_SHIFT)
+#define STAB0_PHYS_ADDR (STAB0_PAGE<<12)
#ifndef __ASSEMBLY__
extern char initial_stab[];
@@ -47,13 +48,21 @@ extern char initial_stab[];
/* Bits in the SLB VSID word */
#define SLB_VSID_SHIFT 12
+#define SLB_VSID_B ASM_CONST(0xc000000000000000)
+#define SLB_VSID_B_256M ASM_CONST(0x0000000000000000)
+#define SLB_VSID_B_1T ASM_CONST(0x4000000000000000)
#define SLB_VSID_KS ASM_CONST(0x0000000000000800)
#define SLB_VSID_KP ASM_CONST(0x0000000000000400)
#define SLB_VSID_N ASM_CONST(0x0000000000000200) /* no-execute */
-#define SLB_VSID_L ASM_CONST(0x0000000000000100) /* largepage */
+#define SLB_VSID_L ASM_CONST(0x0000000000000100)
#define SLB_VSID_C ASM_CONST(0x0000000000000080) /* class */
-#define SLB_VSID_LS ASM_CONST(0x0000000000000070) /* size of largepage */
-
+#define SLB_VSID_LP ASM_CONST(0x0000000000000030)
+#define SLB_VSID_LP_00 ASM_CONST(0x0000000000000000)
+#define SLB_VSID_LP_01 ASM_CONST(0x0000000000000010)
+#define SLB_VSID_LP_10 ASM_CONST(0x0000000000000020)
+#define SLB_VSID_LP_11 ASM_CONST(0x0000000000000030)
+#define SLB_VSID_LLP (SLB_VSID_L|SLB_VSID_LP)
+
#define SLB_VSID_KERNEL (SLB_VSID_KP)
#define SLB_VSID_USER (SLB_VSID_KP|SLB_VSID_KS|SLB_VSID_C)
@@ -68,6 +77,7 @@ extern char initial_stab[];
#define HPTE_V_AVPN_SHIFT 7
#define HPTE_V_AVPN ASM_CONST(0xffffffffffffff80)
#define HPTE_V_AVPN_VAL(x) (((x) & HPTE_V_AVPN) >> HPTE_V_AVPN_SHIFT)
+#define HPTE_V_COMPARE(x,y) (!(((x) ^ (y)) & HPTE_V_AVPN))
#define HPTE_V_BOLTED ASM_CONST(0x0000000000000010)
#define HPTE_V_LOCK ASM_CONST(0x0000000000000008)
#define HPTE_V_LARGE ASM_CONST(0x0000000000000004)
@@ -80,6 +90,7 @@ extern char initial_stab[];
#define HPTE_R_RPN ASM_CONST(0x3ffffffffffff000)
#define HPTE_R_FLAGS ASM_CONST(0x00000000000003ff)
#define HPTE_R_PP ASM_CONST(0x0000000000000003)
+#define HPTE_R_N ASM_CONST(0x0000000000000004)
/* Values for PP (assumes Ks=0, Kp=1) */
/* pp0 will always be 0 for linux */
@@ -98,114 +109,146 @@ typedef struct {
extern hpte_t *htab_address;
extern unsigned long htab_hash_mask;
-static inline unsigned long hpt_hash(unsigned long vpn, int large)
+/*
+ * Page size definition
+ *
+ * shift : is the "PAGE_SHIFT" value for that page size
+ * sllp : is a bit mask with the value of SLB L || LP to be or'ed
+ * directly to a slbmte "vsid" value
+ * penc : is the HPTE encoding mask for the "LP" field:
+ *
+ */
+struct mmu_psize_def
{
- unsigned long vsid;
- unsigned long page;
-
- if (large) {
- vsid = vpn >> 4;
- page = vpn & 0xf;
- } else {
- vsid = vpn >> 16;
- page = vpn & 0xffff;
- }
+ unsigned int shift; /* number of bits */
+ unsigned int penc; /* HPTE encoding */
+ unsigned int tlbiel; /* tlbiel supported for that page size */
+ unsigned long avpnm; /* bits to mask out in AVPN in the HPTE */
+ unsigned long sllp; /* SLB L||LP (exact mask to use in slbmte) */
+};
- return (vsid & 0x7fffffffffUL) ^ page;
-}
-
-static inline void __tlbie(unsigned long va, int large)
-{
- /* clear top 16 bits, non SLS segment */
- va &= ~(0xffffULL << 48);
-
- if (large) {
- va &= HPAGE_MASK;
- asm volatile("tlbie %0,1" : : "r"(va) : "memory");
- } else {
- va &= PAGE_MASK;
- asm volatile("tlbie %0,0" : : "r"(va) : "memory");
- }
-}
+#endif /* __ASSEMBLY__ */
-static inline void tlbie(unsigned long va, int large)
-{
- asm volatile("ptesync": : :"memory");
- __tlbie(va, large);
- asm volatile("eieio; tlbsync; ptesync": : :"memory");
-}
+/*
+ * The kernel use the constants below to index in the page sizes array.
+ * The use of fixed constants for this purpose is better for performances
+ * of the low level hash refill handlers.
+ *
+ * A non supported page size has a "shift" field set to 0
+ *
+ * Any new page size being implemented can get a new entry in here. Whether
+ * the kernel will use it or not is a different matter though. The actual page
+ * size used by hugetlbfs is not defined here and may be made variable
+ */
-static inline void __tlbiel(unsigned long va)
-{
- /* clear top 16 bits, non SLS segment */
- va &= ~(0xffffULL << 48);
- va &= PAGE_MASK;
-
- /*
- * Thanks to Alan Modra we are now able to use machine specific
- * assembly instructions (like tlbiel) by using the gas -many flag.
- * However we have to support older toolchains so for the moment
- * we hardwire it.
- */
-#if 0
- asm volatile("tlbiel %0" : : "r"(va) : "memory");
-#else
- asm volatile(".long 0x7c000224 | (%0 << 11)" : : "r"(va) : "memory");
-#endif
-}
+#define MMU_PAGE_4K 0 /* 4K */
+#define MMU_PAGE_64K 1 /* 64K */
+#define MMU_PAGE_64K_AP 2 /* 64K Admixed (in a 4K segment) */
+#define MMU_PAGE_1M 3 /* 1M */
+#define MMU_PAGE_16M 4 /* 16M */
+#define MMU_PAGE_16G 5 /* 16G */
+#define MMU_PAGE_COUNT 6
-static inline void tlbiel(unsigned long va)
-{
- asm volatile("ptesync": : :"memory");
- __tlbiel(va);
- asm volatile("ptesync": : :"memory");
-}
+#ifndef __ASSEMBLY__
-static inline unsigned long slot2va(unsigned long hpte_v, unsigned long slot)
-{
- unsigned long avpn = HPTE_V_AVPN_VAL(hpte_v);
- unsigned long va;
+/*
+ * The current system page sizes
+ */
+extern struct mmu_psize_def mmu_psize_defs[MMU_PAGE_COUNT];
+extern int mmu_linear_psize;
+extern int mmu_virtual_psize;
- va = avpn << 23;
+#ifdef CONFIG_HUGETLB_PAGE
+/*
+ * The page size index of the huge pages for use by hugetlbfs
+ */
+extern int mmu_huge_psize;
- if (! (hpte_v & HPTE_V_LARGE)) {
- unsigned long vpi, pteg;
+#endif /* CONFIG_HUGETLB_PAGE */
- pteg = slot / HPTES_PER_GROUP;
- if (hpte_v & HPTE_V_SECONDARY)
- pteg = ~pteg;
+/*
+ * This function sets the AVPN and L fields of the HPTE appropriately
+ * for the page size
+ */
+static inline unsigned long hpte_encode_v(unsigned long va, int psize)
+{
+ unsigned long v =
+ v = (va >> 23) & ~(mmu_psize_defs[psize].avpnm);
+ v <<= HPTE_V_AVPN_SHIFT;
+ if (psize != MMU_PAGE_4K)
+ v |= HPTE_V_LARGE;
+ return v;
+}
- vpi = ((va >> 28) ^ pteg) & htab_hash_mask;
+/*
+ * This function sets the ARPN, and LP fields of the HPTE appropriately
+ * for the page size. We assume the pa is already "clean" that is properly
+ * aligned for the requested page size
+ */
+static inline unsigned long hpte_encode_r(unsigned long pa, int psize)
+{
+ unsigned long r;
- va |= vpi << PAGE_SHIFT;
+ /* A 4K page needs no special encoding */
+ if (psize == MMU_PAGE_4K)
+ return pa & HPTE_R_RPN;
+ else {
+ unsigned int penc = mmu_psize_defs[psize].penc;
+ unsigned int shift = mmu_psize_defs[psize].shift;
+ return (pa & ~((1ul << shift) - 1)) | (penc << 12);
}
-
- return va;
+ return r;
}
/*
- * Handle a fault by adding an HPTE. If the address can't be determined
- * to be valid via Linux page tables, return 1. If handled return 0
+ * This hashes a virtual address for a 256Mb segment only for now
*/
-extern int __hash_page(unsigned long ea, unsigned long access,
- unsigned long vsid, pte_t *ptep, unsigned long trap,
- int local);
+
+static inline unsigned long hpt_hash(unsigned long va, unsigned int shift)
+{
+ return ((va >> 28) & 0x7fffffffffUL) ^ ((va & 0x0fffffffUL) >> shift);
+}
+
+extern int __hash_page_4K(unsigned long ea, unsigned long access,
+ unsigned long vsid, pte_t *ptep, unsigned long trap,
+ unsigned int local);
+extern int __hash_page_64K(unsigned long ea, unsigned long access,
+ unsigned long vsid, pte_t *ptep, unsigned long trap,
+ unsigned int local);
+struct mm_struct;
+extern int hash_huge_page(struct mm_struct *mm, unsigned long access,
+ unsigned long ea, unsigned long vsid, int local);
extern void htab_finish_init(void);
+extern int htab_bolt_mapping(unsigned long vstart, unsigned long vend,
+ unsigned long pstart, unsigned long mode,
+ int psize);
+extern void htab_initialize(void);
+extern void htab_initialize_secondary(void);
extern void hpte_init_native(void);
extern void hpte_init_lpar(void);
extern void hpte_init_iSeries(void);
+extern void mm_init_ppc64(void);
extern long pSeries_lpar_hpte_insert(unsigned long hpte_group,
unsigned long va, unsigned long prpn,
- unsigned long vflags,
- unsigned long rflags);
-extern long native_hpte_insert(unsigned long hpte_group, unsigned long va,
- unsigned long prpn,
- unsigned long vflags, unsigned long rflags);
+ unsigned long rflags,
+ unsigned long vflags, int psize);
+
+extern long native_hpte_insert(unsigned long hpte_group,
+ unsigned long va, unsigned long prpn,
+ unsigned long rflags,
+ unsigned long vflags, int psize);
+
+extern long iSeries_hpte_insert(unsigned long hpte_group,
+ unsigned long va, unsigned long prpn,
+ unsigned long rflags,
+ unsigned long vflags, int psize);
extern void stabs_alloc(void);
+extern void slb_initialize(void);
+extern void stab_initialize(unsigned long stab);
#endif /* __ASSEMBLY__ */
diff --git a/include/asm-ppc64/mmu_context.h b/include/asm-ppc64/mmu_context.h
index 77a743402db4..4f512e9fa6b8 100644
--- a/include/asm-ppc64/mmu_context.h
+++ b/include/asm-ppc64/mmu_context.h
@@ -17,22 +17,15 @@
*/
/*
- * Every architecture must define this function. It's the fastest
- * way of searching a 140-bit bitmap where the first 100 bits are
- * unlikely to be set. It's guaranteed that at least one of the 140
- * bits is cleared.
+ * Getting into a kernel thread, there is no valid user segment, mark
+ * paca->pgdir NULL so that SLB miss on user addresses will fault
*/
-static inline int sched_find_first_bit(unsigned long *b)
-{
- if (unlikely(b[0]))
- return __ffs(b[0]);
- if (unlikely(b[1]))
- return __ffs(b[1]) + 64;
- return __ffs(b[2]) + 128;
-}
-
-static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
+static inline void enter_lazy_tlb(struct mm_struct *mm,
+ struct task_struct *tsk)
{
+#ifdef CONFIG_PPC_64K_PAGES
+ get_paca()->pgdir = NULL;
+#endif /* CONFIG_PPC_64K_PAGES */
}
#define NO_CONTEXT 0
@@ -55,8 +48,13 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
cpu_set(smp_processor_id(), next->cpu_vm_mask);
/* No need to flush userspace segments if the mm doesnt change */
+#ifdef CONFIG_PPC_64K_PAGES
+ if (prev == next && get_paca()->pgdir == next->pgd)
+ return;
+#else
if (prev == next)
return;
+#endif /* CONFIG_PPC_64K_PAGES */
#ifdef CONFIG_ALTIVEC
if (cpu_has_feature(CPU_FTR_ALTIVEC))
diff --git a/include/asm-ppc64/mmzone.h b/include/asm-ppc64/mmzone.h
index ed473f4b0152..15e777ce0f4a 100644
--- a/include/asm-ppc64/mmzone.h
+++ b/include/asm-ppc64/mmzone.h
@@ -33,6 +33,9 @@ extern int numa_cpu_lookup_table[];
extern char *numa_memory_lookup_table;
extern cpumask_t numa_cpumask_lookup_table[];
extern int nr_cpus_in_node[];
+#ifdef CONFIG_MEMORY_HOTPLUG
+extern unsigned long max_pfn;
+#endif
/* 16MB regions */
#define MEMORY_INCREMENT_SHIFT 24
@@ -45,6 +48,11 @@ static inline int pa_to_nid(unsigned long pa)
{
int nid;
+#ifdef CONFIG_MEMORY_HOTPLUG
+ /* kludge hot added sections default to node 0 */
+ if (pa >= (max_pfn << PAGE_SHIFT))
+ return 0;
+#endif
nid = numa_memory_lookup_table[pa >> MEMORY_INCREMENT_SHIFT];
#ifdef DEBUG_NUMA
@@ -67,9 +75,6 @@ static inline int pa_to_nid(unsigned long pa)
#define node_start_pfn(nid) (NODE_DATA(nid)->node_start_pfn)
#define node_end_pfn(nid) (NODE_DATA(nid)->node_end_pfn)
-#define local_mapnr(kvaddr) \
- ( (__pa(kvaddr) >> PAGE_SHIFT) - node_start_pfn(kvaddr_to_nid(kvaddr))
-
#ifdef CONFIG_DISCONTIGMEM
/*
diff --git a/include/asm-ppc64/numnodes.h b/include/asm-ppc64/numnodes.h
deleted file mode 100644
index 75ae0b906708..000000000000
--- a/include/asm-ppc64/numnodes.h
+++ /dev/null
@@ -1,7 +0,0 @@
-#ifndef _ASM_MAX_NUMNODES_H
-#define _ASM_MAX_NUMNODES_H
-
-/* Max 16 Nodes */
-#define NODES_SHIFT 4
-
-#endif /* _ASM_MAX_NUMNODES_H */
diff --git a/include/asm-ppc64/nvram.h b/include/asm-ppc64/nvram.h
index dfaa21566c9a..def47d720d3d 100644
--- a/include/asm-ppc64/nvram.h
+++ b/include/asm-ppc64/nvram.h
@@ -70,7 +70,7 @@ extern struct nvram_partition *nvram_find_partition(int sig, const char *name);
extern int pSeries_nvram_init(void);
extern int pmac_nvram_init(void);
-extern int bpa_nvram_init(void);
+extern int mmio_nvram_init(void);
/* PowerMac specific nvram stuffs */
diff --git a/include/asm-ppc64/of_device.h b/include/asm-ppc64/of_device.h
deleted file mode 100644
index 7bc136e22590..000000000000
--- a/include/asm-ppc64/of_device.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include <asm-ppc/of_device.h>
-
diff --git a/include/asm-ppc64/page.h b/include/asm-ppc64/page.h
index a15422bcf30d..e32f1187aa29 100644
--- a/include/asm-ppc64/page.h
+++ b/include/asm-ppc64/page.h
@@ -11,40 +11,61 @@
*/
#include <linux/config.h>
+#include <asm/asm-compat.h>
-#ifdef __ASSEMBLY__
- #define ASM_CONST(x) x
+/*
+ * We support either 4k or 64k software page size. When using 64k pages
+ * however, wether we are really supporting 64k pages in HW or not is
+ * irrelevant to those definitions. We always define HW_PAGE_SHIFT to 12
+ * as use of 64k pages remains a linux kernel specific, every notion of
+ * page number shared with the firmware, TCEs, iommu, etc... still assumes
+ * a page size of 4096.
+ */
+#ifdef CONFIG_PPC_64K_PAGES
+#define PAGE_SHIFT 16
#else
- #define __ASM_CONST(x) x##UL
- #define ASM_CONST(x) __ASM_CONST(x)
+#define PAGE_SHIFT 12
#endif
-/* PAGE_SHIFT determines the page size */
-#define PAGE_SHIFT 12
-#define PAGE_SIZE (ASM_CONST(1) << PAGE_SHIFT)
-#define PAGE_MASK (~(PAGE_SIZE-1))
+#define PAGE_SIZE (ASM_CONST(1) << PAGE_SHIFT)
+#define PAGE_MASK (~(PAGE_SIZE-1))
-#define SID_SHIFT 28
-#define SID_MASK 0xfffffffffUL
-#define ESID_MASK 0xfffffffff0000000UL
-#define GET_ESID(x) (((x) >> SID_SHIFT) & SID_MASK)
+/* HW_PAGE_SHIFT is always 4k pages */
+#define HW_PAGE_SHIFT 12
+#define HW_PAGE_SIZE (ASM_CONST(1) << HW_PAGE_SHIFT)
+#define HW_PAGE_MASK (~(HW_PAGE_SIZE-1))
-#define HPAGE_SHIFT 24
-#define HPAGE_SIZE ((1UL) << HPAGE_SHIFT)
-#define HPAGE_MASK (~(HPAGE_SIZE - 1))
+/* PAGE_FACTOR is the number of bits factor between PAGE_SHIFT and
+ * HW_PAGE_SHIFT, that is 4k pages
+ */
+#define PAGE_FACTOR (PAGE_SHIFT - HW_PAGE_SHIFT)
-#ifdef CONFIG_HUGETLB_PAGE
+/* Segment size */
+#define SID_SHIFT 28
+#define SID_MASK 0xfffffffffUL
+#define ESID_MASK 0xfffffffff0000000UL
+#define GET_ESID(x) (((x) >> SID_SHIFT) & SID_MASK)
+
+/* Large pages size */
+#ifndef __ASSEMBLY__
+extern unsigned int HPAGE_SHIFT;
+#define HPAGE_SIZE ((1UL) << HPAGE_SHIFT)
+#define HPAGE_MASK (~(HPAGE_SIZE - 1))
#define HUGETLB_PAGE_ORDER (HPAGE_SHIFT - PAGE_SHIFT)
+#endif /* __ASSEMBLY__ */
+
+#ifdef CONFIG_HUGETLB_PAGE
+
#define HTLB_AREA_SHIFT 40
#define HTLB_AREA_SIZE (1UL << HTLB_AREA_SHIFT)
#define GET_HTLB_AREA(x) ((x) >> HTLB_AREA_SHIFT)
-#define LOW_ESID_MASK(addr, len) (((1U << (GET_ESID(addr+len-1)+1)) \
- - (1U << GET_ESID(addr))) & 0xffff)
-#define HTLB_AREA_MASK(addr, len) (((1U << (GET_HTLB_AREA(addr+len-1)+1)) \
- - (1U << GET_HTLB_AREA(addr))) & 0xffff)
+#define LOW_ESID_MASK(addr, len) (((1U << (GET_ESID(addr+len-1)+1)) \
+ - (1U << GET_ESID(addr))) & 0xffff)
+#define HTLB_AREA_MASK(addr, len) (((1U << (GET_HTLB_AREA(addr+len-1)+1)) \
+ - (1U << GET_HTLB_AREA(addr))) & 0xffff)
#define ARCH_HAS_HUGEPAGE_ONLY_RANGE
#define ARCH_HAS_PREPARE_HUGEPAGE_RANGE
@@ -120,7 +141,25 @@ static __inline__ void clear_page(void *addr)
: "ctr", "memory");
}
-extern void copy_page(void *to, void *from);
+extern void copy_4K_page(void *to, void *from);
+
+#ifdef CONFIG_PPC_64K_PAGES
+static inline void copy_page(void *to, void *from)
+{
+ unsigned int i;
+ for (i=0; i < (1 << (PAGE_SHIFT - 12)); i++) {
+ copy_4K_page(to, from);
+ to += 4096;
+ from += 4096;
+ }
+}
+#else /* CONFIG_PPC_64K_PAGES */
+static inline void copy_page(void *to, void *from)
+{
+ copy_4K_page(to, from);
+}
+#endif /* CONFIG_PPC_64K_PAGES */
+
struct page;
extern void clear_user_page(void *page, unsigned long vaddr, struct page *pg);
extern void copy_user_page(void *to, void *from, unsigned long vaddr, struct page *p);
@@ -130,43 +169,75 @@ extern void copy_user_page(void *to, void *from, unsigned long vaddr, struct pag
* These are used to make use of C type-checking.
* Entries in the pte table are 64b, while entries in the pgd & pmd are 32b.
*/
-typedef struct { unsigned long pte; } pte_t;
-typedef struct { unsigned long pmd; } pmd_t;
-typedef struct { unsigned long pud; } pud_t;
-typedef struct { unsigned long pgd; } pgd_t;
-typedef struct { unsigned long pgprot; } pgprot_t;
+/* PTE level */
+typedef struct { unsigned long pte; } pte_t;
#define pte_val(x) ((x).pte)
-#define pmd_val(x) ((x).pmd)
-#define pud_val(x) ((x).pud)
-#define pgd_val(x) ((x).pgd)
-#define pgprot_val(x) ((x).pgprot)
-
#define __pte(x) ((pte_t) { (x) })
+
+/* 64k pages additionally define a bigger "real PTE" type that gathers
+ * the "second half" part of the PTE for pseudo 64k pages
+ */
+#ifdef CONFIG_PPC_64K_PAGES
+typedef struct { pte_t pte; unsigned long hidx; } real_pte_t;
+#else
+typedef struct { pte_t pte; } real_pte_t;
+#endif
+
+/* PMD level */
+typedef struct { unsigned long pmd; } pmd_t;
+#define pmd_val(x) ((x).pmd)
#define __pmd(x) ((pmd_t) { (x) })
+
+/* PUD level exusts only on 4k pages */
+#ifndef CONFIG_PPC_64K_PAGES
+typedef struct { unsigned long pud; } pud_t;
+#define pud_val(x) ((x).pud)
#define __pud(x) ((pud_t) { (x) })
+#endif
+
+/* PGD level */
+typedef struct { unsigned long pgd; } pgd_t;
+#define pgd_val(x) ((x).pgd)
#define __pgd(x) ((pgd_t) { (x) })
+
+/* Page protection bits */
+typedef struct { unsigned long pgprot; } pgprot_t;
+#define pgprot_val(x) ((x).pgprot)
#define __pgprot(x) ((pgprot_t) { (x) })
#else
+
/*
* .. while these make it easier on the compiler
*/
-typedef unsigned long pte_t;
-typedef unsigned long pmd_t;
-typedef unsigned long pud_t;
-typedef unsigned long pgd_t;
-typedef unsigned long pgprot_t;
+typedef unsigned long pte_t;
#define pte_val(x) (x)
+#define __pte(x) (x)
+
+#ifdef CONFIG_PPC_64K_PAGES
+typedef struct { pte_t pte; unsigned long hidx; } real_pte_t;
+#else
+typedef unsigned long real_pte_t;
+#endif
+
+
+typedef unsigned long pmd_t;
#define pmd_val(x) (x)
+#define __pmd(x) (x)
+
+#ifndef CONFIG_PPC_64K_PAGES
+typedef unsigned long pud_t;
#define pud_val(x) (x)
+#define __pud(x) (x)
+#endif
+
+typedef unsigned long pgd_t;
#define pgd_val(x) (x)
#define pgprot_val(x) (x)
-#define __pte(x) (x)
-#define __pmd(x) (x)
-#define __pud(x) (x)
+typedef unsigned long pgprot_t;
#define __pgd(x) (x)
#define __pgprot(x) (x)
diff --git a/include/asm-ppc64/parport.h b/include/asm-ppc64/parport.h
deleted file mode 100644
index 2f8874c581cc..000000000000
--- a/include/asm-ppc64/parport.h
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- * parport.h: platform-specific PC-style parport initialisation
- *
- * Copyright (C) 1999, 2000 Tim Waugh <tim@cyberelk.demon.co.uk>
- *
- * This file should only be included by drivers/parport/parport_pc.c.
- */
-
-#ifndef _ASM_PPC64_PARPORT_H
-#define _ASM_PPC64_PARPORT_H
-
-static int __devinit parport_pc_find_isa_ports (int autoirq, int autodma);
-static int __devinit parport_pc_find_nonpci_ports (int autoirq, int autodma)
-{
- return parport_pc_find_isa_ports (autoirq, autodma);
-}
-
-#endif /* !(_ASM_PPC_PARPORT_H) */
diff --git a/include/asm-ppc64/pci-bridge.h b/include/asm-ppc64/pci-bridge.h
index d8991389ab39..efbdaece0cf0 100644
--- a/include/asm-ppc64/pci-bridge.h
+++ b/include/asm-ppc64/pci-bridge.h
@@ -2,7 +2,9 @@
#ifndef _ASM_PCI_BRIDGE_H
#define _ASM_PCI_BRIDGE_H
+#include <linux/config.h>
#include <linux/pci.h>
+#include <linux/list.h>
/*
* This program is free software; you can redistribute it and/or
@@ -34,7 +36,7 @@ struct pci_controller {
struct pci_ops *ops;
volatile unsigned int __iomem *cfg_addr;
- volatile unsigned char __iomem *cfg_data;
+ volatile void __iomem *cfg_data;
/* Currently, we limit ourselves to 1 IO range and 3 mem
* ranges since the common pci_bus structure can't handle more
@@ -61,7 +63,6 @@ struct pci_dn {
int devfn; /* for pci devices */
int eeh_mode; /* See eeh.h for possible EEH_MODEs */
int eeh_config_addr;
- int eeh_capable; /* from firmware */
int eeh_check_count; /* # times driver ignored error */
int eeh_freeze_count; /* # times this device froze up. */
int eeh_is_bridge; /* device is pci-to-pci bridge */
@@ -71,6 +72,12 @@ struct pci_dn {
struct iommu_table *iommu_table; /* for phb's or bridges */
struct pci_dev *pcidev; /* back-pointer to the pci device */
struct device_node *node; /* back-pointer to the device_node */
+#ifdef CONFIG_PPC_ISERIES
+ struct list_head Device_List;
+ int Irq; /* Assigned IRQ */
+ int Flags; /* Possible flags(disable/bist)*/
+ u8 LogicalSlot; /* Hv Slot Index for Tces */
+#endif
u32 config_space[16]; /* saved PCI config space */
};
@@ -96,6 +103,16 @@ static inline struct device_node *pci_device_to_OF_node(struct pci_dev *dev)
return fetch_dev_dn(dev);
}
+static inline int pci_device_from_OF_node(struct device_node *np,
+ u8 *bus, u8 *devfn)
+{
+ if (!PCI_DN(np))
+ return -ENODEV;
+ *bus = PCI_DN(np)->busno;
+ *devfn = PCI_DN(np)->devfn;
+ return 0;
+}
+
static inline struct device_node *pci_bus_to_OF_node(struct pci_bus *bus)
{
if (bus->self)
@@ -105,7 +122,7 @@ static inline struct device_node *pci_bus_to_OF_node(struct pci_bus *bus)
}
extern void pci_process_bridge_OF_ranges(struct pci_controller *hose,
- struct device_node *dev);
+ struct device_node *dev, int primary);
extern int pcibios_remove_root_bus(struct pci_controller *phb);
diff --git a/include/asm-ppc64/pci.h b/include/asm-ppc64/pci.h
index a88bbfc26967..fafdf885a3cc 100644
--- a/include/asm-ppc64/pci.h
+++ b/include/asm-ppc64/pci.h
@@ -162,13 +162,21 @@ pcibios_fixup_device_resources(struct pci_dev *dev, struct pci_bus *bus);
extern struct pci_controller *init_phb_dynamic(struct device_node *dn);
+extern struct pci_dev *of_create_pci_dev(struct device_node *node,
+ struct pci_bus *bus, int devfn);
+
+extern void of_scan_pci_bridge(struct device_node *node,
+ struct pci_dev *dev);
+
+extern void of_scan_bus(struct device_node *node, struct pci_bus *bus);
+
extern int pci_read_irq_line(struct pci_dev *dev);
extern void pcibios_add_platform_entries(struct pci_dev *dev);
struct file;
extern pgprot_t pci_phys_mem_access_prot(struct file *file,
- unsigned long offset,
+ unsigned long pfn,
unsigned long size,
pgprot_t prot);
diff --git a/include/asm-ppc64/pgalloc.h b/include/asm-ppc64/pgalloc.h
index 26bc49c1108d..dcf3622d1946 100644
--- a/include/asm-ppc64/pgalloc.h
+++ b/include/asm-ppc64/pgalloc.h
@@ -8,10 +8,16 @@
extern kmem_cache_t *pgtable_cache[];
+#ifdef CONFIG_PPC_64K_PAGES
+#define PTE_CACHE_NUM 0
+#define PMD_CACHE_NUM 1
+#define PGD_CACHE_NUM 2
+#else
#define PTE_CACHE_NUM 0
#define PMD_CACHE_NUM 1
#define PUD_CACHE_NUM 1
#define PGD_CACHE_NUM 0
+#endif
/*
* This program is free software; you can redistribute it and/or
@@ -30,6 +36,8 @@ static inline void pgd_free(pgd_t *pgd)
kmem_cache_free(pgtable_cache[PGD_CACHE_NUM], pgd);
}
+#ifndef CONFIG_PPC_64K_PAGES
+
#define pgd_populate(MM, PGD, PUD) pgd_set(PGD, PUD)
static inline pud_t *pud_alloc_one(struct mm_struct *mm, unsigned long addr)
@@ -43,7 +51,30 @@ static inline void pud_free(pud_t *pud)
kmem_cache_free(pgtable_cache[PUD_CACHE_NUM], pud);
}
-#define pud_populate(MM, PUD, PMD) pud_set(PUD, PMD)
+static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd)
+{
+ pud_set(pud, (unsigned long)pmd);
+}
+
+#define pmd_populate(mm, pmd, pte_page) \
+ pmd_populate_kernel(mm, pmd, page_address(pte_page))
+#define pmd_populate_kernel(mm, pmd, pte) pmd_set(pmd, (unsigned long)(pte))
+
+
+#else /* CONFIG_PPC_64K_PAGES */
+
+#define pud_populate(mm, pud, pmd) pud_set(pud, (unsigned long)pmd)
+
+static inline void pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd,
+ pte_t *pte)
+{
+ pmd_set(pmd, (unsigned long)pte);
+}
+
+#define pmd_populate(mm, pmd, pte_page) \
+ pmd_populate_kernel(mm, pmd, page_address(pte_page))
+
+#endif /* CONFIG_PPC_64K_PAGES */
static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long addr)
{
@@ -56,17 +87,15 @@ static inline void pmd_free(pmd_t *pmd)
kmem_cache_free(pgtable_cache[PMD_CACHE_NUM], pmd);
}
-#define pmd_populate_kernel(mm, pmd, pte) pmd_set(pmd, pte)
-#define pmd_populate(mm, pmd, pte_page) \
- pmd_populate_kernel(mm, pmd, page_address(pte_page))
-
-static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address)
+static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
+ unsigned long address)
{
return kmem_cache_alloc(pgtable_cache[PTE_CACHE_NUM],
GFP_KERNEL|__GFP_REPEAT);
}
-static inline struct page *pte_alloc_one(struct mm_struct *mm, unsigned long address)
+static inline struct page *pte_alloc_one(struct mm_struct *mm,
+ unsigned long address)
{
return virt_to_page(pte_alloc_one_kernel(mm, address));
}
@@ -103,7 +132,7 @@ static inline void pgtable_free(pgtable_free_t pgf)
kmem_cache_free(pgtable_cache[cachenum], p);
}
-void pgtable_free_tlb(struct mmu_gather *tlb, pgtable_free_t pgf);
+extern void pgtable_free_tlb(struct mmu_gather *tlb, pgtable_free_t pgf);
#define __pte_free_tlb(tlb, ptepage) \
pgtable_free_tlb(tlb, pgtable_free_cache(page_address(ptepage), \
@@ -111,9 +140,11 @@ void pgtable_free_tlb(struct mmu_gather *tlb, pgtable_free_t pgf);
#define __pmd_free_tlb(tlb, pmd) \
pgtable_free_tlb(tlb, pgtable_free_cache(pmd, \
PMD_CACHE_NUM, PMD_TABLE_SIZE-1))
+#ifndef CONFIG_PPC_64K_PAGES
#define __pud_free_tlb(tlb, pmd) \
pgtable_free_tlb(tlb, pgtable_free_cache(pud, \
PUD_CACHE_NUM, PUD_TABLE_SIZE-1))
+#endif /* CONFIG_PPC_64K_PAGES */
#define check_pgt_cache() do { } while (0)
diff --git a/include/asm-ppc64/pgtable-4k.h b/include/asm-ppc64/pgtable-4k.h
new file mode 100644
index 000000000000..e9590c06ad92
--- /dev/null
+++ b/include/asm-ppc64/pgtable-4k.h
@@ -0,0 +1,91 @@
+/*
+ * Entries per page directory level. The PTE level must use a 64b record
+ * for each page table entry. The PMD and PGD level use a 32b record for
+ * each entry by assuming that each entry is page aligned.
+ */
+#define PTE_INDEX_SIZE 9
+#define PMD_INDEX_SIZE 7
+#define PUD_INDEX_SIZE 7
+#define PGD_INDEX_SIZE 9
+
+#define PTE_TABLE_SIZE (sizeof(pte_t) << PTE_INDEX_SIZE)
+#define PMD_TABLE_SIZE (sizeof(pmd_t) << PMD_INDEX_SIZE)
+#define PUD_TABLE_SIZE (sizeof(pud_t) << PUD_INDEX_SIZE)
+#define PGD_TABLE_SIZE (sizeof(pgd_t) << PGD_INDEX_SIZE)
+
+#define PTRS_PER_PTE (1 << PTE_INDEX_SIZE)
+#define PTRS_PER_PMD (1 << PMD_INDEX_SIZE)
+#define PTRS_PER_PUD (1 << PMD_INDEX_SIZE)
+#define PTRS_PER_PGD (1 << PGD_INDEX_SIZE)
+
+/* PMD_SHIFT determines what a second-level page table entry can map */
+#define PMD_SHIFT (PAGE_SHIFT + PTE_INDEX_SIZE)
+#define PMD_SIZE (1UL << PMD_SHIFT)
+#define PMD_MASK (~(PMD_SIZE-1))
+
+/* With 4k base page size, hugepage PTEs go at the PMD level */
+#define MIN_HUGEPTE_SHIFT PMD_SHIFT
+
+/* PUD_SHIFT determines what a third-level page table entry can map */
+#define PUD_SHIFT (PMD_SHIFT + PMD_INDEX_SIZE)
+#define PUD_SIZE (1UL << PUD_SHIFT)
+#define PUD_MASK (~(PUD_SIZE-1))
+
+/* PGDIR_SHIFT determines what a fourth-level page table entry can map */
+#define PGDIR_SHIFT (PUD_SHIFT + PUD_INDEX_SIZE)
+#define PGDIR_SIZE (1UL << PGDIR_SHIFT)
+#define PGDIR_MASK (~(PGDIR_SIZE-1))
+
+/* PTE bits */
+#define _PAGE_SECONDARY 0x8000 /* software: HPTE is in secondary group */
+#define _PAGE_GROUP_IX 0x7000 /* software: HPTE index within group */
+#define _PAGE_F_SECOND _PAGE_SECONDARY
+#define _PAGE_F_GIX _PAGE_GROUP_IX
+
+/* PTE flags to conserve for HPTE identification */
+#define _PAGE_HPTEFLAGS (_PAGE_BUSY | _PAGE_HASHPTE | \
+ _PAGE_SECONDARY | _PAGE_GROUP_IX)
+
+/* PAGE_MASK gives the right answer below, but only by accident */
+/* It should be preserving the high 48 bits and then specifically */
+/* preserving _PAGE_SECONDARY | _PAGE_GROUP_IX */
+#define _PAGE_CHG_MASK (PAGE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY | \
+ _PAGE_HPTEFLAGS)
+
+/* Bits to mask out from a PMD to get to the PTE page */
+#define PMD_MASKED_BITS 0
+/* Bits to mask out from a PUD to get to the PMD page */
+#define PUD_MASKED_BITS 0
+/* Bits to mask out from a PGD to get to the PUD page */
+#define PGD_MASKED_BITS 0
+
+/* shift to put page number into pte */
+#define PTE_RPN_SHIFT (17)
+
+#define __real_pte(e,p) ((real_pte_t)(e))
+#define __rpte_to_pte(r) (r)
+#define __rpte_to_hidx(r,index) (pte_val((r)) >> 12)
+
+#define pte_iterate_hashed_subpages(rpte, psize, va, index, shift) \
+ do { \
+ index = 0; \
+ shift = mmu_psize_defs[psize].shift; \
+
+#define pte_iterate_hashed_end() } while(0)
+
+/*
+ * 4-level page tables related bits
+ */
+
+#define pgd_none(pgd) (!pgd_val(pgd))
+#define pgd_bad(pgd) (pgd_val(pgd) == 0)
+#define pgd_present(pgd) (pgd_val(pgd) != 0)
+#define pgd_clear(pgdp) (pgd_val(*(pgdp)) = 0)
+#define pgd_page(pgd) (pgd_val(pgd) & ~PGD_MASKED_BITS)
+
+#define pud_offset(pgdp, addr) \
+ (((pud_t *) pgd_page(*(pgdp))) + \
+ (((addr) >> PUD_SHIFT) & (PTRS_PER_PUD - 1)))
+
+#define pud_ERROR(e) \
+ printk("%s:%d: bad pmd %08lx.\n", __FILE__, __LINE__, pud_val(e))
diff --git a/include/asm-ppc64/pgtable-64k.h b/include/asm-ppc64/pgtable-64k.h
new file mode 100644
index 000000000000..154f1840ece4
--- /dev/null
+++ b/include/asm-ppc64/pgtable-64k.h
@@ -0,0 +1,90 @@
+#include <asm-generic/pgtable-nopud.h>
+
+
+#define PTE_INDEX_SIZE 12
+#define PMD_INDEX_SIZE 12
+#define PUD_INDEX_SIZE 0
+#define PGD_INDEX_SIZE 4
+
+#define PTE_TABLE_SIZE (sizeof(real_pte_t) << PTE_INDEX_SIZE)
+#define PMD_TABLE_SIZE (sizeof(pmd_t) << PMD_INDEX_SIZE)
+#define PGD_TABLE_SIZE (sizeof(pgd_t) << PGD_INDEX_SIZE)
+
+#define PTRS_PER_PTE (1 << PTE_INDEX_SIZE)
+#define PTRS_PER_PMD (1 << PMD_INDEX_SIZE)
+#define PTRS_PER_PGD (1 << PGD_INDEX_SIZE)
+
+/* With 4k base page size, hugepage PTEs go at the PMD level */
+#define MIN_HUGEPTE_SHIFT PAGE_SHIFT
+
+/* PMD_SHIFT determines what a second-level page table entry can map */
+#define PMD_SHIFT (PAGE_SHIFT + PTE_INDEX_SIZE)
+#define PMD_SIZE (1UL << PMD_SHIFT)
+#define PMD_MASK (~(PMD_SIZE-1))
+
+/* PGDIR_SHIFT determines what a third-level page table entry can map */
+#define PGDIR_SHIFT (PMD_SHIFT + PMD_INDEX_SIZE)
+#define PGDIR_SIZE (1UL << PGDIR_SHIFT)
+#define PGDIR_MASK (~(PGDIR_SIZE-1))
+
+/* Additional PTE bits (don't change without checking asm in hash_low.S) */
+#define _PAGE_HPTE_SUB 0x0ffff000 /* combo only: sub pages HPTE bits */
+#define _PAGE_HPTE_SUB0 0x08000000 /* combo only: first sub page */
+#define _PAGE_COMBO 0x10000000 /* this is a combo 4k page */
+#define _PAGE_F_SECOND 0x00008000 /* full page: hidx bits */
+#define _PAGE_F_GIX 0x00007000 /* full page: hidx bits */
+
+/* PTE flags to conserve for HPTE identification */
+#define _PAGE_HPTEFLAGS (_PAGE_BUSY | _PAGE_HASHPTE | _PAGE_HPTE_SUB |\
+ _PAGE_COMBO)
+
+/* Shift to put page number into pte.
+ *
+ * That gives us a max RPN of 32 bits, which means a max of 48 bits
+ * of addressable physical space.
+ * We could get 3 more bits here by setting PTE_RPN_SHIFT to 29 but
+ * 32 makes PTEs more readable for debugging for now :)
+ */
+#define PTE_RPN_SHIFT (32)
+#define PTE_RPN_MAX (1UL << (64 - PTE_RPN_SHIFT))
+#define PTE_RPN_MASK (~((1UL<<PTE_RPN_SHIFT)-1))
+
+/* _PAGE_CHG_MASK masks of bits that are to be preserved accross
+ * pgprot changes
+ */
+#define _PAGE_CHG_MASK (PTE_RPN_MASK | _PAGE_HPTEFLAGS | _PAGE_DIRTY | \
+ _PAGE_ACCESSED)
+
+/* Bits to mask out from a PMD to get to the PTE page */
+#define PMD_MASKED_BITS 0x1ff
+/* Bits to mask out from a PGD/PUD to get to the PMD page */
+#define PUD_MASKED_BITS 0x1ff
+
+#ifndef __ASSEMBLY__
+
+/* Manipulate "rpte" values */
+#define __real_pte(e,p) ((real_pte_t) { \
+ (e), pte_val(*((p) + PTRS_PER_PTE)) })
+#define __rpte_to_hidx(r,index) ((pte_val((r).pte) & _PAGE_COMBO) ? \
+ (((r).hidx >> ((index)<<2)) & 0xf) : ((pte_val((r).pte) >> 12) & 0xf))
+#define __rpte_to_pte(r) ((r).pte)
+#define __rpte_sub_valid(rpte, index) \
+ (pte_val(rpte.pte) & (_PAGE_HPTE_SUB0 >> (index)))
+
+
+/* Trick: we set __end to va + 64k, which happens works for
+ * a 16M page as well as we want only one iteration
+ */
+#define pte_iterate_hashed_subpages(rpte, psize, va, index, shift) \
+ do { \
+ unsigned long __end = va + PAGE_SIZE; \
+ unsigned __split = (psize == MMU_PAGE_4K || \
+ psize == MMU_PAGE_64K_AP); \
+ shift = mmu_psize_defs[psize].shift; \
+ for (index = 0; va < __end; index++, va += (1 << shift)) { \
+ if (!__split || __rpte_sub_valid(rpte, index)) do { \
+
+#define pte_iterate_hashed_end() } while(0); } } while(0)
+
+
+#endif /* __ASSEMBLY__ */
diff --git a/include/asm-ppc64/pgtable.h b/include/asm-ppc64/pgtable.h
index c83679c9d2b0..a9783ba7fe98 100644
--- a/include/asm-ppc64/pgtable.h
+++ b/include/asm-ppc64/pgtable.h
@@ -13,42 +13,14 @@
#include <asm/mmu.h>
#include <asm/page.h>
#include <asm/tlbflush.h>
+struct mm_struct;
#endif /* __ASSEMBLY__ */
-/*
- * Entries per page directory level. The PTE level must use a 64b record
- * for each page table entry. The PMD and PGD level use a 32b record for
- * each entry by assuming that each entry is page aligned.
- */
-#define PTE_INDEX_SIZE 9
-#define PMD_INDEX_SIZE 7
-#define PUD_INDEX_SIZE 7
-#define PGD_INDEX_SIZE 9
-
-#define PTE_TABLE_SIZE (sizeof(pte_t) << PTE_INDEX_SIZE)
-#define PMD_TABLE_SIZE (sizeof(pmd_t) << PMD_INDEX_SIZE)
-#define PUD_TABLE_SIZE (sizeof(pud_t) << PUD_INDEX_SIZE)
-#define PGD_TABLE_SIZE (sizeof(pgd_t) << PGD_INDEX_SIZE)
-
-#define PTRS_PER_PTE (1 << PTE_INDEX_SIZE)
-#define PTRS_PER_PMD (1 << PMD_INDEX_SIZE)
-#define PTRS_PER_PUD (1 << PMD_INDEX_SIZE)
-#define PTRS_PER_PGD (1 << PGD_INDEX_SIZE)
-
-/* PMD_SHIFT determines what a second-level page table entry can map */
-#define PMD_SHIFT (PAGE_SHIFT + PTE_INDEX_SIZE)
-#define PMD_SIZE (1UL << PMD_SHIFT)
-#define PMD_MASK (~(PMD_SIZE-1))
-
-/* PUD_SHIFT determines what a third-level page table entry can map */
-#define PUD_SHIFT (PMD_SHIFT + PMD_INDEX_SIZE)
-#define PUD_SIZE (1UL << PUD_SHIFT)
-#define PUD_MASK (~(PUD_SIZE-1))
-
-/* PGDIR_SHIFT determines what a fourth-level page table entry can map */
-#define PGDIR_SHIFT (PUD_SHIFT + PUD_INDEX_SIZE)
-#define PGDIR_SIZE (1UL << PGDIR_SHIFT)
-#define PGDIR_MASK (~(PGDIR_SIZE-1))
+#ifdef CONFIG_PPC_64K_PAGES
+#include <asm/pgtable-64k.h>
+#else
+#include <asm/pgtable-4k.h>
+#endif
#define FIRST_USER_ADDRESS 0
@@ -75,8 +47,9 @@
#define VMALLOC_END (VMALLOC_START + VMALLOC_SIZE)
/*
- * Bits in a linux-style PTE. These match the bits in the
- * (hardware-defined) PowerPC PTE as closely as possible.
+ * Common bits in a linux-style PTE. These match the bits in the
+ * (hardware-defined) PowerPC PTE as closely as possible. Additional
+ * bits may be defined in pgtable-*.h
*/
#define _PAGE_PRESENT 0x0001 /* software: pte contains a translation */
#define _PAGE_USER 0x0002 /* matches one of the PP bits */
@@ -91,15 +64,6 @@
#define _PAGE_RW 0x0200 /* software: user write access allowed */
#define _PAGE_HASHPTE 0x0400 /* software: pte has an associated HPTE */
#define _PAGE_BUSY 0x0800 /* software: PTE & hash are busy */
-#define _PAGE_SECONDARY 0x8000 /* software: HPTE is in secondary group */
-#define _PAGE_GROUP_IX 0x7000 /* software: HPTE index within group */
-#define _PAGE_HUGE 0x10000 /* 16MB page */
-/* Bits 0x7000 identify the index within an HPT Group */
-#define _PAGE_HPTEFLAGS (_PAGE_BUSY | _PAGE_HASHPTE | _PAGE_SECONDARY | _PAGE_GROUP_IX)
-/* PAGE_MASK gives the right answer below, but only by accident */
-/* It should be preserving the high 48 bits and then specifically */
-/* preserving _PAGE_SECONDARY | _PAGE_GROUP_IX */
-#define _PAGE_CHG_MASK (PAGE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_HPTEFLAGS)
#define _PAGE_BASE (_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_COHERENT)
@@ -122,10 +86,10 @@
#define PAGE_AGP __pgprot(_PAGE_BASE | _PAGE_WRENABLE | _PAGE_NO_CACHE)
#define HAVE_PAGE_AGP
-/*
- * This bit in a hardware PTE indicates that the page is *not* executable.
- */
-#define HW_NO_EXEC _PAGE_EXEC
+/* PTEIDX nibble */
+#define _PTEIDX_SECONDARY 0x8
+#define _PTEIDX_GROUP_IX 0x7
+
/*
* POWER4 and newer have per page execute protection, older chips can only
@@ -164,21 +128,10 @@ extern unsigned long empty_zero_page[PAGE_SIZE/sizeof(unsigned long)];
#define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page))
#endif /* __ASSEMBLY__ */
-/* shift to put page number into pte */
-#define PTE_SHIFT (17)
-
#ifdef CONFIG_HUGETLB_PAGE
-#ifndef __ASSEMBLY__
-int hash_huge_page(struct mm_struct *mm, unsigned long access,
- unsigned long ea, unsigned long vsid, int local);
-#endif /* __ASSEMBLY__ */
-
#define HAVE_ARCH_UNMAPPED_AREA
#define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN
-#else
-
-#define hash_huge_page(mm,a,ea,vsid,local) -1
#endif
@@ -197,7 +150,7 @@ static inline pte_t pfn_pte(unsigned long pfn, pgprot_t pgprot)
pte_t pte;
- pte_val(pte) = (pfn << PTE_SHIFT) | pgprot_val(pgprot);
+ pte_val(pte) = (pfn << PTE_RPN_SHIFT) | pgprot_val(pgprot);
return pte;
}
@@ -209,30 +162,25 @@ static inline pte_t pfn_pte(unsigned long pfn, pgprot_t pgprot)
/* pte_clear moved to later in this file */
-#define pte_pfn(x) ((unsigned long)((pte_val(x) >> PTE_SHIFT)))
+#define pte_pfn(x) ((unsigned long)((pte_val(x)>>PTE_RPN_SHIFT)))
#define pte_page(x) pfn_to_page(pte_pfn(x))
-#define pmd_set(pmdp, ptep) ({BUG_ON((u64)ptep < KERNELBASE); pmd_val(*(pmdp)) = (unsigned long)(ptep);})
+#define pmd_set(pmdp, pmdval) (pmd_val(*(pmdp)) = (pmdval))
#define pmd_none(pmd) (!pmd_val(pmd))
#define pmd_bad(pmd) (pmd_val(pmd) == 0)
#define pmd_present(pmd) (pmd_val(pmd) != 0)
#define pmd_clear(pmdp) (pmd_val(*(pmdp)) = 0)
-#define pmd_page_kernel(pmd) (pmd_val(pmd))
+#define pmd_page_kernel(pmd) (pmd_val(pmd) & ~PMD_MASKED_BITS)
#define pmd_page(pmd) virt_to_page(pmd_page_kernel(pmd))
-#define pud_set(pudp, pmdp) (pud_val(*(pudp)) = (unsigned long)(pmdp))
+#define pud_set(pudp, pudval) (pud_val(*(pudp)) = (pudval))
#define pud_none(pud) (!pud_val(pud))
#define pud_bad(pud) ((pud_val(pud)) == 0)
#define pud_present(pud) (pud_val(pud) != 0)
#define pud_clear(pudp) (pud_val(*(pudp)) = 0)
-#define pud_page(pud) (pud_val(pud))
+#define pud_page(pud) (pud_val(pud) & ~PUD_MASKED_BITS)
#define pgd_set(pgdp, pudp) ({pgd_val(*(pgdp)) = (unsigned long)(pudp);})
-#define pgd_none(pgd) (!pgd_val(pgd))
-#define pgd_bad(pgd) (pgd_val(pgd) == 0)
-#define pgd_present(pgd) (pgd_val(pgd) != 0)
-#define pgd_clear(pgdp) (pgd_val(*(pgdp)) = 0)
-#define pgd_page(pgd) (pgd_val(pgd))
/*
* Find an entry in a page-table-directory. We combine the address region
@@ -243,9 +191,6 @@ static inline pte_t pfn_pte(unsigned long pfn, pgprot_t pgprot)
#define pgd_offset(mm, address) ((mm)->pgd + pgd_index(address))
-#define pud_offset(pgdp, addr) \
- (((pud_t *) pgd_page(*(pgdp))) + (((addr) >> PUD_SHIFT) & (PTRS_PER_PUD - 1)))
-
#define pmd_offset(pudp,addr) \
(((pmd_t *) pud_page(*(pudp))) + (((addr) >> PMD_SHIFT) & (PTRS_PER_PMD - 1)))
@@ -271,7 +216,6 @@ static inline int pte_exec(pte_t pte) { return pte_val(pte) & _PAGE_EXEC;}
static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY;}
static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED;}
static inline int pte_file(pte_t pte) { return pte_val(pte) & _PAGE_FILE;}
-static inline int pte_huge(pte_t pte) { return pte_val(pte) & _PAGE_HUGE;}
static inline void pte_uncache(pte_t pte) { pte_val(pte) |= _PAGE_NO_CACHE; }
static inline void pte_cache(pte_t pte) { pte_val(pte) &= ~_PAGE_NO_CACHE; }
@@ -286,7 +230,6 @@ static inline pte_t pte_mkclean(pte_t pte) {
pte_val(pte) &= ~(_PAGE_DIRTY); return pte; }
static inline pte_t pte_mkold(pte_t pte) {
pte_val(pte) &= ~_PAGE_ACCESSED; return pte; }
-
static inline pte_t pte_mkread(pte_t pte) {
pte_val(pte) |= _PAGE_USER; return pte; }
static inline pte_t pte_mkexec(pte_t pte) {
@@ -298,7 +241,7 @@ static inline pte_t pte_mkdirty(pte_t pte) {
static inline pte_t pte_mkyoung(pte_t pte) {
pte_val(pte) |= _PAGE_ACCESSED; return pte; }
static inline pte_t pte_mkhuge(pte_t pte) {
- pte_val(pte) |= _PAGE_HUGE; return pte; }
+ return pte; }
/* Atomic PTE updates */
static inline unsigned long pte_update(pte_t *p, unsigned long clr)
@@ -321,11 +264,13 @@ static inline unsigned long pte_update(pte_t *p, unsigned long clr)
/* PTE updating functions, this function puts the PTE in the
* batch, doesn't actually triggers the hash flush immediately,
* you need to call flush_tlb_pending() to do that.
+ * Pass -1 for "normal" size (4K or 64K)
*/
-extern void hpte_update(struct mm_struct *mm, unsigned long addr, unsigned long pte,
- int wrprot);
+extern void hpte_update(struct mm_struct *mm, unsigned long addr,
+ pte_t *ptep, unsigned long pte, int huge);
-static inline int __ptep_test_and_clear_young(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
+static inline int __ptep_test_and_clear_young(struct mm_struct *mm,
+ unsigned long addr, pte_t *ptep)
{
unsigned long old;
@@ -333,7 +278,7 @@ static inline int __ptep_test_and_clear_young(struct mm_struct *mm, unsigned lon
return 0;
old = pte_update(ptep, _PAGE_ACCESSED);
if (old & _PAGE_HASHPTE) {
- hpte_update(mm, addr, old, 0);
+ hpte_update(mm, addr, ptep, old, 0);
flush_tlb_pending();
}
return (old & _PAGE_ACCESSED) != 0;
@@ -351,7 +296,8 @@ static inline int __ptep_test_and_clear_young(struct mm_struct *mm, unsigned lon
* moment we always flush but we need to fix hpte_update and test if the
* optimisation is worth it.
*/
-static inline int __ptep_test_and_clear_dirty(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
+static inline int __ptep_test_and_clear_dirty(struct mm_struct *mm,
+ unsigned long addr, pte_t *ptep)
{
unsigned long old;
@@ -359,7 +305,7 @@ static inline int __ptep_test_and_clear_dirty(struct mm_struct *mm, unsigned lon
return 0;
old = pte_update(ptep, _PAGE_DIRTY);
if (old & _PAGE_HASHPTE)
- hpte_update(mm, addr, old, 0);
+ hpte_update(mm, addr, ptep, old, 0);
return (old & _PAGE_DIRTY) != 0;
}
#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_DIRTY
@@ -371,7 +317,8 @@ static inline int __ptep_test_and_clear_dirty(struct mm_struct *mm, unsigned lon
})
#define __HAVE_ARCH_PTEP_SET_WRPROTECT
-static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
+static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr,
+ pte_t *ptep)
{
unsigned long old;
@@ -379,7 +326,7 @@ static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr,
return;
old = pte_update(ptep, _PAGE_RW);
if (old & _PAGE_HASHPTE)
- hpte_update(mm, addr, old, 0);
+ hpte_update(mm, addr, ptep, old, 0);
}
/*
@@ -408,21 +355,23 @@ static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr,
})
#define __HAVE_ARCH_PTEP_GET_AND_CLEAR
-static inline pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
+static inline pte_t ptep_get_and_clear(struct mm_struct *mm,
+ unsigned long addr, pte_t *ptep)
{
unsigned long old = pte_update(ptep, ~0UL);
if (old & _PAGE_HASHPTE)
- hpte_update(mm, addr, old, 0);
+ hpte_update(mm, addr, ptep, old, 0);
return __pte(old);
}
-static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t * ptep)
+static inline void pte_clear(struct mm_struct *mm, unsigned long addr,
+ pte_t * ptep)
{
unsigned long old = pte_update(ptep, ~0UL);
if (old & _PAGE_HASHPTE)
- hpte_update(mm, addr, old, 0);
+ hpte_update(mm, addr, ptep, old, 0);
}
/*
@@ -435,7 +384,14 @@ static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
pte_clear(mm, addr, ptep);
flush_tlb_pending();
}
- *ptep = __pte(pte_val(pte) & ~_PAGE_HPTEFLAGS);
+ pte = __pte(pte_val(pte) & ~_PAGE_HPTEFLAGS);
+
+#ifdef CONFIG_PPC_64K_PAGES
+ if (mmu_virtual_psize != MMU_PAGE_64K)
+ pte = __pte(pte_val(pte) | _PAGE_COMBO);
+#endif /* CONFIG_PPC_64K_PAGES */
+
+ *ptep = pte;
}
/* Set the dirty and/or accessed bits atomically in a linux PTE, this
@@ -471,17 +427,17 @@ static inline void __ptep_set_access_flags(pte_t *ptep, pte_t entry, int dirty)
#define pgprot_noncached(prot) (__pgprot(pgprot_val(prot) | _PAGE_NO_CACHE | _PAGE_GUARDED))
struct file;
-extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long addr,
+extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
unsigned long size, pgprot_t vma_prot);
#define __HAVE_PHYS_MEM_ACCESS_PROT
#define __HAVE_ARCH_PTE_SAME
#define pte_same(A,B) (((pte_val(A) ^ pte_val(B)) & ~_PAGE_HPTEFLAGS) == 0)
+#define pte_ERROR(e) \
+ printk("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, pte_val(e))
#define pmd_ERROR(e) \
printk("%s:%d: bad pmd %08lx.\n", __FILE__, __LINE__, pmd_val(e))
-#define pud_ERROR(e) \
- printk("%s:%d: bad pmd %08lx.\n", __FILE__, __LINE__, pud_val(e))
#define pgd_ERROR(e) \
printk("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, pgd_val(e))
@@ -507,12 +463,12 @@ extern void update_mmu_cache(struct vm_area_struct *, unsigned long, pte_t);
/* Encode and de-code a swap entry */
#define __swp_type(entry) (((entry).val >> 1) & 0x3f)
#define __swp_offset(entry) ((entry).val >> 8)
-#define __swp_entry(type, offset) ((swp_entry_t) { ((type) << 1) | ((offset) << 8) })
-#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) >> PTE_SHIFT })
-#define __swp_entry_to_pte(x) ((pte_t) { (x).val << PTE_SHIFT })
-#define pte_to_pgoff(pte) (pte_val(pte) >> PTE_SHIFT)
-#define pgoff_to_pte(off) ((pte_t) {((off) << PTE_SHIFT)|_PAGE_FILE})
-#define PTE_FILE_MAX_BITS (BITS_PER_LONG - PTE_SHIFT)
+#define __swp_entry(type, offset) ((swp_entry_t){((type)<< 1)|((offset)<<8)})
+#define __pte_to_swp_entry(pte) ((swp_entry_t){pte_val(pte) >> PTE_RPN_SHIFT})
+#define __swp_entry_to_pte(x) ((pte_t) { (x).val << PTE_RPN_SHIFT })
+#define pte_to_pgoff(pte) (pte_val(pte) >> PTE_RPN_SHIFT)
+#define pgoff_to_pte(off) ((pte_t) {((off) << PTE_RPN_SHIFT)|_PAGE_FILE})
+#define PTE_FILE_MAX_BITS (BITS_PER_LONG - PTE_RPN_SHIFT)
/*
* kern_addr_valid is intended to indicate whether an address is a valid
@@ -530,29 +486,22 @@ void pgtable_cache_init(void);
/*
* find_linux_pte returns the address of a linux pte for a given
* effective address and directory. If not found, it returns zero.
- */
-static inline pte_t *find_linux_pte(pgd_t *pgdir, unsigned long ea)
+ */static inline pte_t *find_linux_pte(pgd_t *pgdir, unsigned long ea)
{
pgd_t *pg;
pud_t *pu;
pmd_t *pm;
pte_t *pt = NULL;
- pte_t pte;
pg = pgdir + pgd_index(ea);
if (!pgd_none(*pg)) {
pu = pud_offset(pg, ea);
if (!pud_none(*pu)) {
pm = pmd_offset(pu, ea);
- if (pmd_present(*pm)) {
+ if (pmd_present(*pm))
pt = pte_offset_kernel(pm, ea);
- pte = *pt;
- if (!pte_present(pte))
- pt = NULL;
- }
}
}
-
return pt;
}
diff --git a/include/asm-ppc64/plpar_wrappers.h b/include/asm-ppc64/plpar_wrappers.h
deleted file mode 100644
index 72dd2449ee76..000000000000
--- a/include/asm-ppc64/plpar_wrappers.h
+++ /dev/null
@@ -1,120 +0,0 @@
-#ifndef _PPC64_PLPAR_WRAPPERS_H
-#define _PPC64_PLPAR_WRAPPERS_H
-
-#include <asm/hvcall.h>
-
-static inline long poll_pending(void)
-{
- unsigned long dummy;
- return plpar_hcall(H_POLL_PENDING, 0, 0, 0, 0,
- &dummy, &dummy, &dummy);
-}
-
-static inline long prod_processor(void)
-{
- plpar_hcall_norets(H_PROD);
- return(0);
-}
-
-static inline long cede_processor(void)
-{
- plpar_hcall_norets(H_CEDE);
- return(0);
-}
-
-static inline long register_vpa(unsigned long flags, unsigned long proc,
- unsigned long vpa)
-{
- return plpar_hcall_norets(H_REGISTER_VPA, flags, proc, vpa);
-}
-
-void vpa_init(int cpu);
-
-static inline long plpar_pte_remove(unsigned long flags,
- unsigned long ptex,
- unsigned long avpn,
- unsigned long *old_pteh_ret,
- unsigned long *old_ptel_ret)
-{
- unsigned long dummy;
- return plpar_hcall(H_REMOVE, flags, ptex, avpn, 0,
- old_pteh_ret, old_ptel_ret, &dummy);
-}
-
-static inline long plpar_pte_read(unsigned long flags,
- unsigned long ptex,
- unsigned long *old_pteh_ret, unsigned long *old_ptel_ret)
-{
- unsigned long dummy;
- return plpar_hcall(H_READ, flags, ptex, 0, 0,
- old_pteh_ret, old_ptel_ret, &dummy);
-}
-
-static inline long plpar_pte_protect(unsigned long flags,
- unsigned long ptex,
- unsigned long avpn)
-{
- return plpar_hcall_norets(H_PROTECT, flags, ptex, avpn);
-}
-
-static inline long plpar_tce_get(unsigned long liobn,
- unsigned long ioba,
- unsigned long *tce_ret)
-{
- unsigned long dummy;
- return plpar_hcall(H_GET_TCE, liobn, ioba, 0, 0,
- tce_ret, &dummy, &dummy);
-}
-
-static inline long plpar_tce_put(unsigned long liobn,
- unsigned long ioba,
- unsigned long tceval)
-{
- return plpar_hcall_norets(H_PUT_TCE, liobn, ioba, tceval);
-}
-
-static inline long plpar_tce_put_indirect(unsigned long liobn,
- unsigned long ioba,
- unsigned long page,
- unsigned long count)
-{
- return plpar_hcall_norets(H_PUT_TCE_INDIRECT, liobn, ioba, page, count);
-}
-
-static inline long plpar_tce_stuff(unsigned long liobn,
- unsigned long ioba,
- unsigned long tceval,
- unsigned long count)
-{
- return plpar_hcall_norets(H_STUFF_TCE, liobn, ioba, tceval, count);
-}
-
-static inline long plpar_get_term_char(unsigned long termno,
- unsigned long *len_ret,
- char *buf_ret)
-{
- unsigned long *lbuf = (unsigned long *)buf_ret; /* ToDo: alignment? */
- return plpar_hcall(H_GET_TERM_CHAR, termno, 0, 0, 0,
- len_ret, lbuf+0, lbuf+1);
-}
-
-static inline long plpar_put_term_char(unsigned long termno,
- unsigned long len,
- const char *buffer)
-{
- unsigned long *lbuf = (unsigned long *)buffer; /* ToDo: alignment? */
- return plpar_hcall_norets(H_PUT_TERM_CHAR, termno, len, lbuf[0],
- lbuf[1]);
-}
-
-static inline long plpar_set_xdabr(unsigned long address, unsigned long flags)
-{
- return plpar_hcall_norets(H_SET_XDABR, address, flags);
-}
-
-static inline long plpar_set_dabr(unsigned long val)
-{
- return plpar_hcall_norets(H_SET_DABR, val);
-}
-
-#endif /* _PPC64_PLPAR_WRAPPERS_H */
diff --git a/include/asm-ppc64/pmac_feature.h b/include/asm-ppc64/pmac_feature.h
deleted file mode 100644
index e07e36c4cbb2..000000000000
--- a/include/asm-ppc64/pmac_feature.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include <asm-ppc/pmac_feature.h>
-
diff --git a/include/asm-ppc64/pmac_low_i2c.h b/include/asm-ppc64/pmac_low_i2c.h
deleted file mode 100644
index 7bcfc72c5c8a..000000000000
--- a/include/asm-ppc64/pmac_low_i2c.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include <asm-ppc/pmac_low_i2c.h>
-
diff --git a/include/asm-ppc64/ppc_asm.h b/include/asm-ppc64/ppc_asm.h
deleted file mode 100644
index 9031d8a29aca..000000000000
--- a/include/asm-ppc64/ppc_asm.h
+++ /dev/null
@@ -1,242 +0,0 @@
-/*
- * arch/ppc64/kernel/ppc_asm.h
- *
- * Definitions used by various bits of low-level assembly code on PowerPC.
- *
- * Copyright (C) 1995-1999 Gary Thomas, Paul Mackerras, Cort Dougan.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-
-#ifndef _PPC64_PPC_ASM_H
-#define _PPC64_PPC_ASM_H
-/*
- * Macros for storing registers into and loading registers from
- * exception frames.
- */
-#define SAVE_GPR(n, base) std n,GPR0+8*(n)(base)
-#define SAVE_2GPRS(n, base) SAVE_GPR(n, base); SAVE_GPR(n+1, base)
-#define SAVE_4GPRS(n, base) SAVE_2GPRS(n, base); SAVE_2GPRS(n+2, base)
-#define SAVE_8GPRS(n, base) SAVE_4GPRS(n, base); SAVE_4GPRS(n+4, base)
-#define SAVE_10GPRS(n, base) SAVE_8GPRS(n, base); SAVE_2GPRS(n+8, base)
-#define REST_GPR(n, base) ld n,GPR0+8*(n)(base)
-#define REST_2GPRS(n, base) REST_GPR(n, base); REST_GPR(n+1, base)
-#define REST_4GPRS(n, base) REST_2GPRS(n, base); REST_2GPRS(n+2, base)
-#define REST_8GPRS(n, base) REST_4GPRS(n, base); REST_4GPRS(n+4, base)
-#define REST_10GPRS(n, base) REST_8GPRS(n, base); REST_2GPRS(n+8, base)
-
-#define SAVE_NVGPRS(base) SAVE_8GPRS(14, base); SAVE_10GPRS(22, base)
-#define REST_NVGPRS(base) REST_8GPRS(14, base); REST_10GPRS(22, base)
-
-#define SAVE_FPR(n, base) stfd n,THREAD_FPR0+8*(n)(base)
-#define SAVE_2FPRS(n, base) SAVE_FPR(n, base); SAVE_FPR(n+1, base)
-#define SAVE_4FPRS(n, base) SAVE_2FPRS(n, base); SAVE_2FPRS(n+2, base)
-#define SAVE_8FPRS(n, base) SAVE_4FPRS(n, base); SAVE_4FPRS(n+4, base)
-#define SAVE_16FPRS(n, base) SAVE_8FPRS(n, base); SAVE_8FPRS(n+8, base)
-#define SAVE_32FPRS(n, base) SAVE_16FPRS(n, base); SAVE_16FPRS(n+16, base)
-#define REST_FPR(n, base) lfd n,THREAD_FPR0+8*(n)(base)
-#define REST_2FPRS(n, base) REST_FPR(n, base); REST_FPR(n+1, base)
-#define REST_4FPRS(n, base) REST_2FPRS(n, base); REST_2FPRS(n+2, base)
-#define REST_8FPRS(n, base) REST_4FPRS(n, base); REST_4FPRS(n+4, base)
-#define REST_16FPRS(n, base) REST_8FPRS(n, base); REST_8FPRS(n+8, base)
-#define REST_32FPRS(n, base) REST_16FPRS(n, base); REST_16FPRS(n+16, base)
-
-#define SAVE_VR(n,b,base) li b,THREAD_VR0+(16*(n)); stvx n,b,base
-#define SAVE_2VRS(n,b,base) SAVE_VR(n,b,base); SAVE_VR(n+1,b,base)
-#define SAVE_4VRS(n,b,base) SAVE_2VRS(n,b,base); SAVE_2VRS(n+2,b,base)
-#define SAVE_8VRS(n,b,base) SAVE_4VRS(n,b,base); SAVE_4VRS(n+4,b,base)
-#define SAVE_16VRS(n,b,base) SAVE_8VRS(n,b,base); SAVE_8VRS(n+8,b,base)
-#define SAVE_32VRS(n,b,base) SAVE_16VRS(n,b,base); SAVE_16VRS(n+16,b,base)
-#define REST_VR(n,b,base) li b,THREAD_VR0+(16*(n)); lvx n,b,base
-#define REST_2VRS(n,b,base) REST_VR(n,b,base); REST_VR(n+1,b,base)
-#define REST_4VRS(n,b,base) REST_2VRS(n,b,base); REST_2VRS(n+2,b,base)
-#define REST_8VRS(n,b,base) REST_4VRS(n,b,base); REST_4VRS(n+4,b,base)
-#define REST_16VRS(n,b,base) REST_8VRS(n,b,base); REST_8VRS(n+8,b,base)
-#define REST_32VRS(n,b,base) REST_16VRS(n,b,base); REST_16VRS(n+16,b,base)
-
-/* Macros to adjust thread priority for Iseries hardware multithreading */
-#define HMT_LOW or 1,1,1
-#define HMT_MEDIUM or 2,2,2
-#define HMT_HIGH or 3,3,3
-
-/* Insert the high 32 bits of the MSR into what will be the new
- MSR (via SRR1 and rfid) This preserves the MSR.SF and MSR.ISF
- bits. */
-
-#define FIX_SRR1(ra, rb) \
- mr rb,ra; \
- mfmsr ra; \
- rldimi ra,rb,0,32
-
-#define CLR_TOP32(r) rlwinm (r),(r),0,0,31 /* clear top 32 bits */
-
-/*
- * LOADADDR( rn, name )
- * loads the address of 'name' into 'rn'
- *
- * LOADBASE( rn, name )
- * loads the address (less the low 16 bits) of 'name' into 'rn'
- * suitable for base+disp addressing
- */
-#define LOADADDR(rn,name) \
- lis rn,name##@highest; \
- ori rn,rn,name##@higher; \
- rldicr rn,rn,32,31; \
- oris rn,rn,name##@h; \
- ori rn,rn,name##@l
-
-#define LOADBASE(rn,name) \
- lis rn,name@highest; \
- ori rn,rn,name@higher; \
- rldicr rn,rn,32,31; \
- oris rn,rn,name@ha
-
-
-#define SET_REG_TO_CONST(reg, value) \
- lis reg,(((value)>>48)&0xFFFF); \
- ori reg,reg,(((value)>>32)&0xFFFF); \
- rldicr reg,reg,32,31; \
- oris reg,reg,(((value)>>16)&0xFFFF); \
- ori reg,reg,((value)&0xFFFF);
-
-#define SET_REG_TO_LABEL(reg, label) \
- lis reg,(label)@highest; \
- ori reg,reg,(label)@higher; \
- rldicr reg,reg,32,31; \
- oris reg,reg,(label)@h; \
- ori reg,reg,(label)@l;
-
-
-/* PPPBBB - DRENG If KERNELBASE is always 0xC0...,
- * Then we can easily do this with one asm insn. -Peter
- */
-#define tophys(rd,rs) \
- lis rd,((KERNELBASE>>48)&0xFFFF); \
- rldicr rd,rd,32,31; \
- sub rd,rs,rd
-
-#define tovirt(rd,rs) \
- lis rd,((KERNELBASE>>48)&0xFFFF); \
- rldicr rd,rd,32,31; \
- add rd,rs,rd
-
-/* Condition Register Bit Fields */
-
-#define cr0 0
-#define cr1 1
-#define cr2 2
-#define cr3 3
-#define cr4 4
-#define cr5 5
-#define cr6 6
-#define cr7 7
-
-
-/* General Purpose Registers (GPRs) */
-
-#define r0 0
-#define r1 1
-#define r2 2
-#define r3 3
-#define r4 4
-#define r5 5
-#define r6 6
-#define r7 7
-#define r8 8
-#define r9 9
-#define r10 10
-#define r11 11
-#define r12 12
-#define r13 13
-#define r14 14
-#define r15 15
-#define r16 16
-#define r17 17
-#define r18 18
-#define r19 19
-#define r20 20
-#define r21 21
-#define r22 22
-#define r23 23
-#define r24 24
-#define r25 25
-#define r26 26
-#define r27 27
-#define r28 28
-#define r29 29
-#define r30 30
-#define r31 31
-
-
-/* Floating Point Registers (FPRs) */
-
-#define fr0 0
-#define fr1 1
-#define fr2 2
-#define fr3 3
-#define fr4 4
-#define fr5 5
-#define fr6 6
-#define fr7 7
-#define fr8 8
-#define fr9 9
-#define fr10 10
-#define fr11 11
-#define fr12 12
-#define fr13 13
-#define fr14 14
-#define fr15 15
-#define fr16 16
-#define fr17 17
-#define fr18 18
-#define fr19 19
-#define fr20 20
-#define fr21 21
-#define fr22 22
-#define fr23 23
-#define fr24 24
-#define fr25 25
-#define fr26 26
-#define fr27 27
-#define fr28 28
-#define fr29 29
-#define fr30 30
-#define fr31 31
-
-#define vr0 0
-#define vr1 1
-#define vr2 2
-#define vr3 3
-#define vr4 4
-#define vr5 5
-#define vr6 6
-#define vr7 7
-#define vr8 8
-#define vr9 9
-#define vr10 10
-#define vr11 11
-#define vr12 12
-#define vr13 13
-#define vr14 14
-#define vr15 15
-#define vr16 16
-#define vr17 17
-#define vr18 18
-#define vr19 19
-#define vr20 20
-#define vr21 21
-#define vr22 22
-#define vr23 23
-#define vr24 24
-#define vr25 25
-#define vr26 26
-#define vr27 27
-#define vr28 28
-#define vr29 29
-#define vr30 30
-#define vr31 31
-
-#endif /* _PPC64_PPC_ASM_H */
diff --git a/include/asm-ppc64/ppcdebug.h b/include/asm-ppc64/ppcdebug.h
deleted file mode 100644
index fd7f696065c4..000000000000
--- a/include/asm-ppc64/ppcdebug.h
+++ /dev/null
@@ -1,108 +0,0 @@
-#ifndef __PPCDEBUG_H
-#define __PPCDEBUG_H
-/********************************************************************
- * Author: Adam Litke, IBM Corp
- * (c) 2001
- *
- * This file contains definitions and macros for a runtime debugging
- * system for ppc64 (This should also work on 32 bit with a few
- * adjustments.
- *
- * 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/config.h>
-#include <linux/types.h>
-#include <asm/udbg.h>
-#include <stdarg.h>
-
-#define PPCDBG_BITVAL(X) ((1UL)<<((unsigned long)(X)))
-
-/* Defined below are the bit positions of various debug flags in the
- * ppc64_debug_switch variable.
- * -- When adding new values, please enter them into trace names below --
- *
- * Values 62 & 63 can be used to stress the hardware page table management
- * code. They must be set statically, any attempt to change them dynamically
- * would be a very bad idea.
- */
-#define PPCDBG_MMINIT PPCDBG_BITVAL(0)
-#define PPCDBG_MM PPCDBG_BITVAL(1)
-#define PPCDBG_SYS32 PPCDBG_BITVAL(2)
-#define PPCDBG_SYS32NI PPCDBG_BITVAL(3)
-#define PPCDBG_SYS32X PPCDBG_BITVAL(4)
-#define PPCDBG_SYS32M PPCDBG_BITVAL(5)
-#define PPCDBG_SYS64 PPCDBG_BITVAL(6)
-#define PPCDBG_SYS64NI PPCDBG_BITVAL(7)
-#define PPCDBG_SYS64X PPCDBG_BITVAL(8)
-#define PPCDBG_SIGNAL PPCDBG_BITVAL(9)
-#define PPCDBG_SIGNALXMON PPCDBG_BITVAL(10)
-#define PPCDBG_BINFMT32 PPCDBG_BITVAL(11)
-#define PPCDBG_BINFMT64 PPCDBG_BITVAL(12)
-#define PPCDBG_BINFMTXMON PPCDBG_BITVAL(13)
-#define PPCDBG_BINFMT_32ADDR PPCDBG_BITVAL(14)
-#define PPCDBG_ALIGNFIXUP PPCDBG_BITVAL(15)
-#define PPCDBG_TCEINIT PPCDBG_BITVAL(16)
-#define PPCDBG_TCE PPCDBG_BITVAL(17)
-#define PPCDBG_PHBINIT PPCDBG_BITVAL(18)
-#define PPCDBG_SMP PPCDBG_BITVAL(19)
-#define PPCDBG_BOOT PPCDBG_BITVAL(20)
-#define PPCDBG_BUSWALK PPCDBG_BITVAL(21)
-#define PPCDBG_PROM PPCDBG_BITVAL(22)
-#define PPCDBG_RTAS PPCDBG_BITVAL(23)
-#define PPCDBG_HTABSTRESS PPCDBG_BITVAL(62)
-#define PPCDBG_HTABSIZE PPCDBG_BITVAL(63)
-#define PPCDBG_NONE (0UL)
-#define PPCDBG_ALL (0xffffffffUL)
-
-/* The default initial value for the debug switch */
-#define PPC_DEBUG_DEFAULT 0
-/* #define PPC_DEBUG_DEFAULT PPCDBG_ALL */
-
-#define PPCDBG_NUM_FLAGS 64
-
-extern u64 ppc64_debug_switch;
-
-#ifdef WANT_PPCDBG_TAB
-/* A table of debug switch names to allow name lookup in xmon
- * (and whoever else wants it.
- */
-char *trace_names[PPCDBG_NUM_FLAGS] = {
- /* Known debug names */
- "mminit", "mm",
- "syscall32", "syscall32_ni", "syscall32x", "syscall32m",
- "syscall64", "syscall64_ni", "syscall64x",
- "signal", "signal_xmon",
- "binfmt32", "binfmt64", "binfmt_xmon", "binfmt_32addr",
- "alignfixup", "tceinit", "tce", "phb_init",
- "smp", "boot", "buswalk", "prom",
- "rtas"
-};
-#else
-extern char *trace_names[64];
-#endif /* WANT_PPCDBG_TAB */
-
-#ifdef CONFIG_PPCDBG
-/* Macro to conditionally print debug based on debug_switch */
-#define PPCDBG(...) udbg_ppcdbg(__VA_ARGS__)
-
-/* Macro to conditionally call a debug routine based on debug_switch */
-#define PPCDBGCALL(FLAGS,FUNCTION) ifppcdebug(FLAGS) FUNCTION
-
-/* Macros to test for debug states */
-#define ifppcdebug(FLAGS) if (udbg_ifdebug(FLAGS))
-#define ppcdebugset(FLAGS) (udbg_ifdebug(FLAGS))
-#define PPCDBG_BINFMT (test_thread_flag(TIF_32BIT) ? PPCDBG_BINFMT32 : PPCDBG_BINFMT64)
-
-#else
-#define PPCDBG(...) do {;} while (0)
-#define PPCDBGCALL(FLAGS,FUNCTION) do {;} while (0)
-#define ifppcdebug(...) if (0)
-#define ppcdebugset(FLAGS) (0)
-#endif /* CONFIG_PPCDBG */
-
-#endif /*__PPCDEBUG_H */
diff --git a/include/asm-ppc64/processor.h b/include/asm-ppc64/processor.h
deleted file mode 100644
index 4146189006e3..000000000000
--- a/include/asm-ppc64/processor.h
+++ /dev/null
@@ -1,558 +0,0 @@
-#ifndef __ASM_PPC64_PROCESSOR_H
-#define __ASM_PPC64_PROCESSOR_H
-
-/*
- * Copyright (C) 2001 PPC 64 Team, IBM Corp
- *
- * 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/stringify.h>
-#ifndef __ASSEMBLY__
-#include <linux/config.h>
-#include <asm/atomic.h>
-#include <asm/ppcdebug.h>
-#include <asm/a.out.h>
-#endif
-#include <asm/ptrace.h>
-#include <asm/types.h>
-#include <asm/systemcfg.h>
-#include <asm/cputable.h>
-
-/* Machine State Register (MSR) Fields */
-#define MSR_SF_LG 63 /* Enable 64 bit mode */
-#define MSR_ISF_LG 61 /* Interrupt 64b mode valid on 630 */
-#define MSR_HV_LG 60 /* Hypervisor state */
-#define MSR_VEC_LG 25 /* Enable AltiVec */
-#define MSR_POW_LG 18 /* Enable Power Management */
-#define MSR_WE_LG 18 /* Wait State Enable */
-#define MSR_TGPR_LG 17 /* TLB Update registers in use */
-#define MSR_CE_LG 17 /* Critical Interrupt Enable */
-#define MSR_ILE_LG 16 /* Interrupt Little Endian */
-#define MSR_EE_LG 15 /* External Interrupt Enable */
-#define MSR_PR_LG 14 /* Problem State / Privilege Level */
-#define MSR_FP_LG 13 /* Floating Point enable */
-#define MSR_ME_LG 12 /* Machine Check Enable */
-#define MSR_FE0_LG 11 /* Floating Exception mode 0 */
-#define MSR_SE_LG 10 /* Single Step */
-#define MSR_BE_LG 9 /* Branch Trace */
-#define MSR_DE_LG 9 /* Debug Exception Enable */
-#define MSR_FE1_LG 8 /* Floating Exception mode 1 */
-#define MSR_IP_LG 6 /* Exception prefix 0x000/0xFFF */
-#define MSR_IR_LG 5 /* Instruction Relocate */
-#define MSR_DR_LG 4 /* Data Relocate */
-#define MSR_PE_LG 3 /* Protection Enable */
-#define MSR_PX_LG 2 /* Protection Exclusive Mode */
-#define MSR_PMM_LG 2 /* Performance monitor */
-#define MSR_RI_LG 1 /* Recoverable Exception */
-#define MSR_LE_LG 0 /* Little Endian */
-
-#ifdef __ASSEMBLY__
-#define __MASK(X) (1<<(X))
-#else
-#define __MASK(X) (1UL<<(X))
-#endif
-
-#define MSR_SF __MASK(MSR_SF_LG) /* Enable 64 bit mode */
-#define MSR_ISF __MASK(MSR_ISF_LG) /* Interrupt 64b mode valid on 630 */
-#define MSR_HV __MASK(MSR_HV_LG) /* Hypervisor state */
-#define MSR_VEC __MASK(MSR_VEC_LG) /* Enable AltiVec */
-#define MSR_POW __MASK(MSR_POW_LG) /* Enable Power Management */
-#define MSR_WE __MASK(MSR_WE_LG) /* Wait State Enable */
-#define MSR_TGPR __MASK(MSR_TGPR_LG) /* TLB Update registers in use */
-#define MSR_CE __MASK(MSR_CE_LG) /* Critical Interrupt Enable */
-#define MSR_ILE __MASK(MSR_ILE_LG) /* Interrupt Little Endian */
-#define MSR_EE __MASK(MSR_EE_LG) /* External Interrupt Enable */
-#define MSR_PR __MASK(MSR_PR_LG) /* Problem State / Privilege Level */
-#define MSR_FP __MASK(MSR_FP_LG) /* Floating Point enable */
-#define MSR_ME __MASK(MSR_ME_LG) /* Machine Check Enable */
-#define MSR_FE0 __MASK(MSR_FE0_LG) /* Floating Exception mode 0 */
-#define MSR_SE __MASK(MSR_SE_LG) /* Single Step */
-#define MSR_BE __MASK(MSR_BE_LG) /* Branch Trace */
-#define MSR_DE __MASK(MSR_DE_LG) /* Debug Exception Enable */
-#define MSR_FE1 __MASK(MSR_FE1_LG) /* Floating Exception mode 1 */
-#define MSR_IP __MASK(MSR_IP_LG) /* Exception prefix 0x000/0xFFF */
-#define MSR_IR __MASK(MSR_IR_LG) /* Instruction Relocate */
-#define MSR_DR __MASK(MSR_DR_LG) /* Data Relocate */
-#define MSR_PE __MASK(MSR_PE_LG) /* Protection Enable */
-#define MSR_PX __MASK(MSR_PX_LG) /* Protection Exclusive Mode */
-#define MSR_PMM __MASK(MSR_PMM_LG) /* Performance monitor */
-#define MSR_RI __MASK(MSR_RI_LG) /* Recoverable Exception */
-#define MSR_LE __MASK(MSR_LE_LG) /* Little Endian */
-
-#define MSR_ MSR_ME | MSR_RI | MSR_IR | MSR_DR | MSR_ISF
-#define MSR_KERNEL MSR_ | MSR_SF | MSR_HV
-
-#define MSR_USER32 MSR_ | MSR_PR | MSR_EE
-#define MSR_USER64 MSR_USER32 | MSR_SF
-
-/* Floating Point Status and Control Register (FPSCR) Fields */
-
-#define FPSCR_FX 0x80000000 /* FPU exception summary */
-#define FPSCR_FEX 0x40000000 /* FPU enabled exception summary */
-#define FPSCR_VX 0x20000000 /* Invalid operation summary */
-#define FPSCR_OX 0x10000000 /* Overflow exception summary */
-#define FPSCR_UX 0x08000000 /* Underflow exception summary */
-#define FPSCR_ZX 0x04000000 /* Zero-divide exception summary */
-#define FPSCR_XX 0x02000000 /* Inexact exception summary */
-#define FPSCR_VXSNAN 0x01000000 /* Invalid op for SNaN */
-#define FPSCR_VXISI 0x00800000 /* Invalid op for Inv - Inv */
-#define FPSCR_VXIDI 0x00400000 /* Invalid op for Inv / Inv */
-#define FPSCR_VXZDZ 0x00200000 /* Invalid op for Zero / Zero */
-#define FPSCR_VXIMZ 0x00100000 /* Invalid op for Inv * Zero */
-#define FPSCR_VXVC 0x00080000 /* Invalid op for Compare */
-#define FPSCR_FR 0x00040000 /* Fraction rounded */
-#define FPSCR_FI 0x00020000 /* Fraction inexact */
-#define FPSCR_FPRF 0x0001f000 /* FPU Result Flags */
-#define FPSCR_FPCC 0x0000f000 /* FPU Condition Codes */
-#define FPSCR_VXSOFT 0x00000400 /* Invalid op for software request */
-#define FPSCR_VXSQRT 0x00000200 /* Invalid op for square root */
-#define FPSCR_VXCVI 0x00000100 /* Invalid op for integer convert */
-#define FPSCR_VE 0x00000080 /* Invalid op exception enable */
-#define FPSCR_OE 0x00000040 /* IEEE overflow exception enable */
-#define FPSCR_UE 0x00000020 /* IEEE underflow exception enable */
-#define FPSCR_ZE 0x00000010 /* IEEE zero divide exception enable */
-#define FPSCR_XE 0x00000008 /* FP inexact exception enable */
-#define FPSCR_NI 0x00000004 /* FPU non IEEE-Mode */
-#define FPSCR_RN 0x00000003 /* FPU rounding control */
-
-/* Special Purpose Registers (SPRNs)*/
-
-#define SPRN_CTR 0x009 /* Count Register */
-#define SPRN_DABR 0x3F5 /* Data Address Breakpoint Register */
-#define DABR_TRANSLATION (1UL << 2)
-#define SPRN_DAR 0x013 /* Data Address Register */
-#define SPRN_DEC 0x016 /* Decrement Register */
-#define SPRN_DSISR 0x012 /* Data Storage Interrupt Status Register */
-#define DSISR_NOHPTE 0x40000000 /* no translation found */
-#define DSISR_PROTFAULT 0x08000000 /* protection fault */
-#define DSISR_ISSTORE 0x02000000 /* access was a store */
-#define DSISR_DABRMATCH 0x00400000 /* hit data breakpoint */
-#define DSISR_NOSEGMENT 0x00200000 /* STAB/SLB miss */
-#define SPRN_HID0 0x3F0 /* Hardware Implementation Register 0 */
-#define SPRN_MSRDORM 0x3F1 /* Hardware Implementation Register 1 */
-#define SPRN_HID1 0x3F1 /* Hardware Implementation Register 1 */
-#define SPRN_IABR 0x3F2 /* Instruction Address Breakpoint Register */
-#define SPRN_NIADORM 0x3F3 /* Hardware Implementation Register 2 */
-#define SPRN_HID4 0x3F4 /* 970 HID4 */
-#define SPRN_HID5 0x3F6 /* 970 HID5 */
-#define SPRN_HID6 0x3F9 /* BE HID 6 */
-#define HID6_LB (0x0F<<12) /* Concurrent Large Page Modes */
-#define HID6_DLP (1<<20) /* Disable all large page modes (4K only) */
-#define SPRN_TSCR 0x399 /* Thread switch control on BE */
-#define SPRN_TTR 0x39A /* Thread switch timeout on BE */
-#define TSCR_DEC_ENABLE 0x200000 /* Decrementer Interrupt */
-#define TSCR_EE_ENABLE 0x100000 /* External Interrupt */
-#define TSCR_EE_BOOST 0x080000 /* External Interrupt Boost */
-#define SPRN_TSC 0x3FD /* Thread switch control on others */
-#define SPRN_TST 0x3FC /* Thread switch timeout on others */
-#define SPRN_L2CR 0x3F9 /* Level 2 Cache Control Regsiter */
-#define SPRN_LR 0x008 /* Link Register */
-#define SPRN_PIR 0x3FF /* Processor Identification Register */
-#define SPRN_PIT 0x3DB /* Programmable Interval Timer */
-#define SPRN_PURR 0x135 /* Processor Utilization of Resources Register */
-#define SPRN_PVR 0x11F /* Processor Version Register */
-#define SPRN_RPA 0x3D6 /* Required Physical Address Register */
-#define SPRN_SDA 0x3BF /* Sampled Data Address Register */
-#define SPRN_SDR1 0x019 /* MMU Hash Base Register */
-#define SPRN_SIA 0x3BB /* Sampled Instruction Address Register */
-#define SPRN_SPRG0 0x110 /* Special Purpose Register General 0 */
-#define SPRN_SPRG1 0x111 /* Special Purpose Register General 1 */
-#define SPRN_SPRG2 0x112 /* Special Purpose Register General 2 */
-#define SPRN_SPRG3 0x113 /* Special Purpose Register General 3 */
-#define SPRN_SRR0 0x01A /* Save/Restore Register 0 */
-#define SPRN_SRR1 0x01B /* Save/Restore Register 1 */
-#define SPRN_TBRL 0x10C /* Time Base Read Lower Register (user, R/O) */
-#define SPRN_TBRU 0x10D /* Time Base Read Upper Register (user, R/O) */
-#define SPRN_TBWL 0x11C /* Time Base Lower Register (super, W/O) */
-#define SPRN_TBWU 0x11D /* Time Base Write Upper Register (super, W/O) */
-#define SPRN_HIOR 0x137 /* 970 Hypervisor interrupt offset */
-#define SPRN_USIA 0x3AB /* User Sampled Instruction Address Register */
-#define SPRN_XER 0x001 /* Fixed Point Exception Register */
-#define SPRN_VRSAVE 0x100 /* Vector save */
-#define SPRN_CTRLF 0x088
-#define SPRN_CTRLT 0x098
-#define CTRL_RUNLATCH 0x1
-
-/* Performance monitor SPRs */
-#define SPRN_SIAR 780
-#define SPRN_SDAR 781
-#define SPRN_MMCRA 786
-#define MMCRA_SIHV 0x10000000UL /* state of MSR HV when SIAR set */
-#define MMCRA_SIPR 0x08000000UL /* state of MSR PR when SIAR set */
-#define MMCRA_SAMPLE_ENABLE 0x00000001UL /* enable sampling */
-#define SPRN_PMC1 787
-#define SPRN_PMC2 788
-#define SPRN_PMC3 789
-#define SPRN_PMC4 790
-#define SPRN_PMC5 791
-#define SPRN_PMC6 792
-#define SPRN_PMC7 793
-#define SPRN_PMC8 794
-#define SPRN_MMCR0 795
-#define MMCR0_FC 0x80000000UL /* freeze counters. set to 1 on a perfmon exception */
-#define MMCR0_FCS 0x40000000UL /* freeze in supervisor state */
-#define MMCR0_KERNEL_DISABLE MMCR0_FCS
-#define MMCR0_FCP 0x20000000UL /* freeze in problem state */
-#define MMCR0_PROBLEM_DISABLE MMCR0_FCP
-#define MMCR0_FCM1 0x10000000UL /* freeze counters while MSR mark = 1 */
-#define MMCR0_FCM0 0x08000000UL /* freeze counters while MSR mark = 0 */
-#define MMCR0_PMXE 0x04000000UL /* performance monitor exception enable */
-#define MMCR0_FCECE 0x02000000UL /* freeze counters on enabled condition or event */
-/* time base exception enable */
-#define MMCR0_TBEE 0x00400000UL /* time base exception enable */
-#define MMCR0_PMC1CE 0x00008000UL /* PMC1 count enable*/
-#define MMCR0_PMCjCE 0x00004000UL /* PMCj count enable*/
-#define MMCR0_TRIGGER 0x00002000UL /* TRIGGER enable */
-#define MMCR0_PMAO 0x00000080UL /* performance monitor alert has occurred, set to 0 after handling exception */
-#define MMCR0_SHRFC 0x00000040UL /* SHRre freeze conditions between threads */
-#define MMCR0_FCTI 0x00000008UL /* freeze counters in tags inactive mode */
-#define MMCR0_FCTA 0x00000004UL /* freeze counters in tags active mode */
-#define MMCR0_FCWAIT 0x00000002UL /* freeze counter in WAIT state */
-#define MMCR0_FCHV 0x00000001UL /* freeze conditions in hypervisor mode */
-#define SPRN_MMCR1 798
-
-/* Short-hand versions for a number of the above SPRNs */
-
-#define CTR SPRN_CTR /* Counter Register */
-#define DAR SPRN_DAR /* Data Address Register */
-#define DABR SPRN_DABR /* Data Address Breakpoint Register */
-#define DEC SPRN_DEC /* Decrement Register */
-#define DSISR SPRN_DSISR /* Data Storage Interrupt Status Register */
-#define HID0 SPRN_HID0 /* Hardware Implementation Register 0 */
-#define MSRDORM SPRN_MSRDORM /* MSR Dormant Register */
-#define NIADORM SPRN_NIADORM /* NIA Dormant Register */
-#define TSC SPRN_TSC /* Thread switch control */
-#define TST SPRN_TST /* Thread switch timeout */
-#define IABR SPRN_IABR /* Instruction Address Breakpoint Register */
-#define L2CR SPRN_L2CR /* PPC 750 L2 control register */
-#define __LR SPRN_LR
-#define PVR SPRN_PVR /* Processor Version */
-#define PIR SPRN_PIR /* Processor ID */
-#define PURR SPRN_PURR /* Processor Utilization of Resource Register */
-#define SDR1 SPRN_SDR1 /* MMU hash base register */
-#define SPR0 SPRN_SPRG0 /* Supervisor Private Registers */
-#define SPR1 SPRN_SPRG1
-#define SPR2 SPRN_SPRG2
-#define SPR3 SPRN_SPRG3
-#define SPRG0 SPRN_SPRG0
-#define SPRG1 SPRN_SPRG1
-#define SPRG2 SPRN_SPRG2
-#define SPRG3 SPRN_SPRG3
-#define SRR0 SPRN_SRR0 /* Save and Restore Register 0 */
-#define SRR1 SPRN_SRR1 /* Save and Restore Register 1 */
-#define TBRL SPRN_TBRL /* Time Base Read Lower Register */
-#define TBRU SPRN_TBRU /* Time Base Read Upper Register */
-#define TBWL SPRN_TBWL /* Time Base Write Lower Register */
-#define TBWU SPRN_TBWU /* Time Base Write Upper Register */
-#define XER SPRN_XER
-
-/* Processor Version Register (PVR) field extraction */
-
-#define PVR_VER(pvr) (((pvr) >> 16) & 0xFFFF) /* Version field */
-#define PVR_REV(pvr) (((pvr) >> 0) & 0xFFFF) /* Revison field */
-
-/* Processor Version Numbers */
-#define PV_NORTHSTAR 0x0033
-#define PV_PULSAR 0x0034
-#define PV_POWER4 0x0035
-#define PV_ICESTAR 0x0036
-#define PV_SSTAR 0x0037
-#define PV_POWER4p 0x0038
-#define PV_970 0x0039
-#define PV_POWER5 0x003A
-#define PV_POWER5p 0x003B
-#define PV_970FX 0x003C
-#define PV_630 0x0040
-#define PV_630p 0x0041
-#define PV_970MP 0x0044
-#define PV_BE 0x0070
-
-/* Platforms supported by PPC64 */
-#define PLATFORM_PSERIES 0x0100
-#define PLATFORM_PSERIES_LPAR 0x0101
-#define PLATFORM_ISERIES_LPAR 0x0201
-#define PLATFORM_LPAR 0x0001
-#define PLATFORM_POWERMAC 0x0400
-#define PLATFORM_MAPLE 0x0500
-#define PLATFORM_BPA 0x1000
-
-/* Compatibility with drivers coming from PPC32 world */
-#define _machine (systemcfg->platform)
-#define _MACH_Pmac PLATFORM_POWERMAC
-
-/*
- * List of interrupt controllers.
- */
-#define IC_INVALID 0
-#define IC_OPEN_PIC 1
-#define IC_PPC_XIC 2
-#define IC_BPA_IIC 3
-
-#define XGLUE(a,b) a##b
-#define GLUE(a,b) XGLUE(a,b)
-
-#ifdef __ASSEMBLY__
-
-#define _GLOBAL(name) \
- .section ".text"; \
- .align 2 ; \
- .globl name; \
- .globl GLUE(.,name); \
- .section ".opd","aw"; \
-name: \
- .quad GLUE(.,name); \
- .quad .TOC.@tocbase; \
- .quad 0; \
- .previous; \
- .type GLUE(.,name),@function; \
-GLUE(.,name):
-
-#define _KPROBE(name) \
- .section ".kprobes.text","a"; \
- .align 2 ; \
- .globl name; \
- .globl GLUE(.,name); \
- .section ".opd","aw"; \
-name: \
- .quad GLUE(.,name); \
- .quad .TOC.@tocbase; \
- .quad 0; \
- .previous; \
- .type GLUE(.,name),@function; \
-GLUE(.,name):
-
-#define _STATIC(name) \
- .section ".text"; \
- .align 2 ; \
- .section ".opd","aw"; \
-name: \
- .quad GLUE(.,name); \
- .quad .TOC.@tocbase; \
- .quad 0; \
- .previous; \
- .type GLUE(.,name),@function; \
-GLUE(.,name):
-
-#else /* __ASSEMBLY__ */
-
-/*
- * Default implementation of macro that returns current
- * instruction pointer ("program counter").
- */
-#define current_text_addr() ({ __label__ _l; _l: &&_l;})
-
-/* Macros for setting and retrieving special purpose registers */
-
-#define mfmsr() ({unsigned long rval; \
- asm volatile("mfmsr %0" : "=r" (rval)); rval;})
-
-#define __mtmsrd(v, l) asm volatile("mtmsrd %0," __stringify(l) \
- : : "r" (v))
-#define mtmsrd(v) __mtmsrd((v), 0)
-
-#define mfspr(rn) ({unsigned long rval; \
- asm volatile("mfspr %0," __stringify(rn) \
- : "=r" (rval)); rval;})
-#define mtspr(rn, v) asm volatile("mtspr " __stringify(rn) ",%0" : : "r" (v))
-
-#define mftb() ({unsigned long rval; \
- asm volatile("mftb %0" : "=r" (rval)); rval;})
-
-#define mttbl(v) asm volatile("mttbl %0":: "r"(v))
-#define mttbu(v) asm volatile("mttbu %0":: "r"(v))
-
-#define mfasr() ({unsigned long rval; \
- asm volatile("mfasr %0" : "=r" (rval)); rval;})
-
-static inline void set_tb(unsigned int upper, unsigned int lower)
-{
- mttbl(0);
- mttbu(upper);
- mttbl(lower);
-}
-
-#define __get_SP() ({unsigned long sp; \
- asm volatile("mr %0,1": "=r" (sp)); sp;})
-
-#ifdef __KERNEL__
-
-extern int have_of;
-extern u64 ppc64_interrupt_controller;
-
-struct task_struct;
-void start_thread(struct pt_regs *regs, unsigned long fdptr, unsigned long sp);
-void release_thread(struct task_struct *);
-
-/* Prepare to copy thread state - unlazy all lazy status */
-extern void prepare_to_copy(struct task_struct *tsk);
-
-/* Create a new kernel thread. */
-extern long kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
-
-/* Lazy FPU handling on uni-processor */
-extern struct task_struct *last_task_used_math;
-extern struct task_struct *last_task_used_altivec;
-
-/* 64-bit user address space is 44-bits (16TB user VM) */
-#define TASK_SIZE_USER64 (0x0000100000000000UL)
-
-/*
- * 32-bit user address space is 4GB - 1 page
- * (this 1 page is needed so referencing of 0xFFFFFFFF generates EFAULT
- */
-#define TASK_SIZE_USER32 (0x0000000100000000UL - (1*PAGE_SIZE))
-
-#define TASK_SIZE (test_thread_flag(TIF_32BIT) ? \
- TASK_SIZE_USER32 : TASK_SIZE_USER64)
-
-/* This decides where the kernel will search for a free chunk of vm
- * space during mmap's.
- */
-#define TASK_UNMAPPED_BASE_USER32 (PAGE_ALIGN(TASK_SIZE_USER32 / 4))
-#define TASK_UNMAPPED_BASE_USER64 (PAGE_ALIGN(TASK_SIZE_USER64 / 4))
-
-#define TASK_UNMAPPED_BASE ((test_thread_flag(TIF_32BIT)||(ppcdebugset(PPCDBG_BINFMT_32ADDR))) ? \
- TASK_UNMAPPED_BASE_USER32 : TASK_UNMAPPED_BASE_USER64 )
-
-typedef struct {
- unsigned long seg;
-} mm_segment_t;
-
-struct thread_struct {
- unsigned long ksp; /* Kernel stack pointer */
- unsigned long ksp_vsid;
- struct pt_regs *regs; /* Pointer to saved register state */
- mm_segment_t fs; /* for get_fs() validation */
- double fpr[32]; /* Complete floating point set */
- unsigned long fpscr; /* Floating point status (plus pad) */
- unsigned long fpexc_mode; /* Floating-point exception mode */
- unsigned long start_tb; /* Start purr when proc switched in */
- unsigned long accum_tb; /* Total accumilated purr for process */
- unsigned long vdso_base; /* base of the vDSO library */
- unsigned long dabr; /* Data address breakpoint register */
-#ifdef CONFIG_ALTIVEC
- /* Complete AltiVec register set */
- vector128 vr[32] __attribute((aligned(16)));
- /* AltiVec status */
- vector128 vscr __attribute((aligned(16)));
- unsigned long vrsave;
- int used_vr; /* set if process has used altivec */
-#endif /* CONFIG_ALTIVEC */
-};
-
-#define ARCH_MIN_TASKALIGN 16
-
-#define INIT_SP (sizeof(init_stack) + (unsigned long) &init_stack)
-
-#define INIT_THREAD { \
- .ksp = INIT_SP, \
- .regs = (struct pt_regs *)INIT_SP - 1, \
- .fs = KERNEL_DS, \
- .fpr = {0}, \
- .fpscr = 0, \
- .fpexc_mode = MSR_FE0|MSR_FE1, \
-}
-
-/*
- * Return saved PC of a blocked thread. For now, this is the "user" PC
- */
-#define thread_saved_pc(tsk) \
- ((tsk)->thread.regs? (tsk)->thread.regs->nip: 0)
-
-unsigned long get_wchan(struct task_struct *p);
-
-#define KSTK_EIP(tsk) ((tsk)->thread.regs? (tsk)->thread.regs->nip: 0)
-#define KSTK_ESP(tsk) ((tsk)->thread.regs? (tsk)->thread.regs->gpr[1]: 0)
-
-/* Get/set floating-point exception mode */
-#define GET_FPEXC_CTL(tsk, adr) get_fpexc_mode((tsk), (adr))
-#define SET_FPEXC_CTL(tsk, val) set_fpexc_mode((tsk), (val))
-
-extern int get_fpexc_mode(struct task_struct *tsk, unsigned long adr);
-extern int set_fpexc_mode(struct task_struct *tsk, unsigned int val);
-
-static inline unsigned int __unpack_fe01(unsigned long msr_bits)
-{
- return ((msr_bits & MSR_FE0) >> 10) | ((msr_bits & MSR_FE1) >> 8);
-}
-
-static inline unsigned long __pack_fe01(unsigned int fpmode)
-{
- return ((fpmode << 10) & MSR_FE0) | ((fpmode << 8) & MSR_FE1);
-}
-
-#define cpu_relax() do { HMT_low(); HMT_medium(); barrier(); } while (0)
-
-/*
- * Prefetch macros.
- */
-#define ARCH_HAS_PREFETCH
-#define ARCH_HAS_PREFETCHW
-#define ARCH_HAS_SPINLOCK_PREFETCH
-
-static inline void prefetch(const void *x)
-{
- if (unlikely(!x))
- return;
-
- __asm__ __volatile__ ("dcbt 0,%0" : : "r" (x));
-}
-
-static inline void prefetchw(const void *x)
-{
- if (unlikely(!x))
- return;
-
- __asm__ __volatile__ ("dcbtst 0,%0" : : "r" (x));
-}
-
-#define spin_lock_prefetch(x) prefetchw(x)
-
-#define HAVE_ARCH_PICK_MMAP_LAYOUT
-
-static inline void ppc64_runlatch_on(void)
-{
- unsigned long ctrl;
-
- if (cpu_has_feature(CPU_FTR_CTRL)) {
- ctrl = mfspr(SPRN_CTRLF);
- ctrl |= CTRL_RUNLATCH;
- mtspr(SPRN_CTRLT, ctrl);
- }
-}
-
-static inline void ppc64_runlatch_off(void)
-{
- unsigned long ctrl;
-
- if (cpu_has_feature(CPU_FTR_CTRL)) {
- ctrl = mfspr(SPRN_CTRLF);
- ctrl &= ~CTRL_RUNLATCH;
- mtspr(SPRN_CTRLT, ctrl);
- }
-}
-
-#endif /* __KERNEL__ */
-
-#endif /* __ASSEMBLY__ */
-
-#ifdef __KERNEL__
-#define RUNLATCH_ON(REG) \
-BEGIN_FTR_SECTION \
- mfspr (REG),SPRN_CTRLF; \
- ori (REG),(REG),CTRL_RUNLATCH; \
- mtspr SPRN_CTRLT,(REG); \
-END_FTR_SECTION_IFSET(CPU_FTR_CTRL)
-#endif
-
-/*
- * Number of entries in the SLB. If this ever changes we should handle
- * it with a use a cpu feature fixup.
- */
-#define SLB_NUM_ENTRIES 64
-
-#endif /* __ASM_PPC64_PROCESSOR_H */
diff --git a/include/asm-ppc64/prom.h b/include/asm-ppc64/prom.h
index c02ec1d6b909..ddfe186589fa 100644
--- a/include/asm-ppc64/prom.h
+++ b/include/asm-ppc64/prom.h
@@ -14,6 +14,7 @@
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
+#include <linux/config.h>
#include <linux/proc_fs.h>
#include <asm/atomic.h>
@@ -137,6 +138,9 @@ struct device_node {
struct kref kref;
unsigned long _flags;
void *data;
+#ifdef CONFIG_PPC_ISERIES
+ struct list_head Device_List;
+#endif
};
extern struct device_node *of_chosen;
@@ -184,6 +188,14 @@ extern struct device_node *of_get_next_child(const struct device_node *node,
extern struct device_node *of_node_get(struct device_node *node);
extern void of_node_put(struct device_node *node);
+/* For scanning the flat device-tree at boot time */
+int __init of_scan_flat_dt(int (*it)(unsigned long node,
+ const char *uname, int depth,
+ void *data),
+ void *data);
+void* __init of_get_flat_dt_prop(unsigned long node, const char *name,
+ unsigned long *size);
+
/* For updating the device tree at runtime */
extern void of_attach_node(struct device_node *);
extern void of_detach_node(const struct device_node *);
@@ -192,6 +204,8 @@ extern void of_detach_node(const struct device_node *);
extern unsigned long prom_init(unsigned long, unsigned long, unsigned long,
unsigned long, unsigned long);
extern void finish_device_tree(void);
+extern void unflatten_device_tree(void);
+extern void early_init_devtree(void *);
extern int device_is_compatible(struct device_node *device, const char *);
extern int machine_is_compatible(const char *compat);
extern unsigned char *get_property(struct device_node *node, const char *name,
@@ -201,6 +215,6 @@ extern int prom_n_addr_cells(struct device_node* np);
extern int prom_n_size_cells(struct device_node* np);
extern int prom_n_intr_cells(struct device_node* np);
extern void prom_get_irq_senses(unsigned char *senses, int off, int max);
-extern void prom_add_property(struct device_node* np, struct property* prop);
+extern int prom_add_property(struct device_node* np, struct property* prop);
#endif /* _PPC64_PROM_H */
diff --git a/include/asm-ppc64/signal.h b/include/asm-ppc64/signal.h
deleted file mode 100644
index 432df7dd355d..000000000000
--- a/include/asm-ppc64/signal.h
+++ /dev/null
@@ -1,132 +0,0 @@
-#ifndef _ASMPPC64_SIGNAL_H
-#define _ASMPPC64_SIGNAL_H
-
-#include <linux/types.h>
-#include <linux/compiler.h>
-#include <asm/siginfo.h>
-
-/* Avoid too many header ordering problems. */
-struct siginfo;
-
-#define _NSIG 64
-#define _NSIG_BPW 64
-#define _NSIG_WORDS (_NSIG / _NSIG_BPW)
-
-typedef unsigned long old_sigset_t; /* at least 32 bits */
-
-typedef struct {
- unsigned long sig[_NSIG_WORDS];
-} sigset_t;
-
-#define SIGHUP 1
-#define SIGINT 2
-#define SIGQUIT 3
-#define SIGILL 4
-#define SIGTRAP 5
-#define SIGABRT 6
-#define SIGIOT 6
-#define SIGBUS 7
-#define SIGFPE 8
-#define SIGKILL 9
-#define SIGUSR1 10
-#define SIGSEGV 11
-#define SIGUSR2 12
-#define SIGPIPE 13
-#define SIGALRM 14
-#define SIGTERM 15
-#define SIGSTKFLT 16
-#define SIGCHLD 17
-#define SIGCONT 18
-#define SIGSTOP 19
-#define SIGTSTP 20
-#define SIGTTIN 21
-#define SIGTTOU 22
-#define SIGURG 23
-#define SIGXCPU 24
-#define SIGXFSZ 25
-#define SIGVTALRM 26
-#define SIGPROF 27
-#define SIGWINCH 28
-#define SIGIO 29
-#define SIGPOLL SIGIO
-/*
-#define SIGLOST 29
-*/
-#define SIGPWR 30
-#define SIGSYS 31
-#define SIGUNUSED 31
-
-/* These should not be considered constants from userland. */
-#define SIGRTMIN 32
-#define SIGRTMAX _NSIG
-
-/*
- * SA_FLAGS values:
- *
- * SA_ONSTACK is not currently supported, but will allow sigaltstack(2).
- * SA_INTERRUPT is a no-op, but left due to historical reasons. Use the
- * SA_RESTART flag to get restarting signals (which were the default long ago)
- * SA_NOCLDSTOP flag to turn off SIGCHLD when children stop.
- * SA_RESETHAND clears the handler when the signal is delivered.
- * SA_NOCLDWAIT flag on SIGCHLD to inhibit zombies.
- * SA_NODEFER prevents the current signal from being masked in the handler.
- *
- * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single
- * Unix names RESETHAND and NODEFER respectively.
- */
-#define SA_NOCLDSTOP 0x00000001u
-#define SA_NOCLDWAIT 0x00000002u
-#define SA_SIGINFO 0x00000004u
-#define SA_ONSTACK 0x08000000u
-#define SA_RESTART 0x10000000u
-#define SA_NODEFER 0x40000000u
-#define SA_RESETHAND 0x80000000u
-
-#define SA_NOMASK SA_NODEFER
-#define SA_ONESHOT SA_RESETHAND
-#define SA_INTERRUPT 0x20000000u /* dummy -- ignored */
-
-#define SA_RESTORER 0x04000000u
-
-/*
- * sigaltstack controls
- */
-#define SS_ONSTACK 1
-#define SS_DISABLE 2
-
-#define MINSIGSTKSZ 2048
-#define SIGSTKSZ 8192
-
-#include <asm-generic/signal.h>
-
-struct old_sigaction {
- __sighandler_t sa_handler;
- old_sigset_t sa_mask;
- unsigned long sa_flags;
- __sigrestore_t sa_restorer;
-};
-
-struct sigaction {
- __sighandler_t sa_handler;
- unsigned long sa_flags;
- __sigrestore_t sa_restorer;
- sigset_t sa_mask; /* mask last for extensibility */
-};
-
-struct k_sigaction {
- struct sigaction sa;
-};
-
-typedef struct sigaltstack {
- void __user *ss_sp;
- int ss_flags;
- size_t ss_size;
-} stack_t;
-
-struct pt_regs;
-struct timespec;
-extern int do_signal(sigset_t *oldset, struct pt_regs *regs);
-extern int do_signal32(sigset_t *oldset, struct pt_regs *regs);
-#define ptrace_signal_deliver(regs, cookie) do { } while (0)
-
-#endif /* _ASMPPC64_SIGNAL_H */
diff --git a/include/asm-ppc64/spinlock.h b/include/asm-ppc64/spinlock.h
index 14cb895bb607..7d84fb5e39f1 100644
--- a/include/asm-ppc64/spinlock.h
+++ b/include/asm-ppc64/spinlock.h
@@ -21,7 +21,7 @@
#include <linux/config.h>
#include <asm/paca.h>
#include <asm/hvcall.h>
-#include <asm/iSeries/HvCall.h>
+#include <asm/iseries/hv_call.h>
#define __raw_spin_is_locked(x) ((x)->slock != 0)
diff --git a/include/asm-ppc64/stat.h b/include/asm-ppc64/stat.h
deleted file mode 100644
index 973a5f97951d..000000000000
--- a/include/asm-ppc64/stat.h
+++ /dev/null
@@ -1,60 +0,0 @@
-#ifndef _PPC64_STAT_H
-#define _PPC64_STAT_H
-
-/*
- * 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/types.h>
-
-struct stat {
- unsigned long st_dev;
- ino_t st_ino;
- nlink_t st_nlink;
- mode_t st_mode;
- uid_t st_uid;
- gid_t st_gid;
- unsigned long st_rdev;
- off_t st_size;
- unsigned long st_blksize;
- unsigned long st_blocks;
- unsigned long st_atime;
- unsigned long st_atime_nsec;
- unsigned long st_mtime;
- unsigned long st_mtime_nsec;
- unsigned long st_ctime;
- unsigned long st_ctime_nsec;
- unsigned long __unused4;
- unsigned long __unused5;
- unsigned long __unused6;
-};
-
-#define STAT_HAVE_NSEC 1
-
-/* This matches struct stat64 in glibc2.1. Only used for 32 bit. */
-struct stat64 {
- unsigned long st_dev; /* Device. */
- unsigned long st_ino; /* File serial number. */
- unsigned int st_mode; /* File mode. */
- unsigned int st_nlink; /* Link count. */
- unsigned int st_uid; /* User ID of the file's owner. */
- unsigned int st_gid; /* Group ID of the file's group. */
- unsigned long st_rdev; /* Device number, if device. */
- unsigned short __pad2;
- long st_size; /* Size of file, in bytes. */
- int st_blksize; /* Optimal block size for I/O. */
-
- long st_blocks; /* Number 512-byte blocks allocated. */
- int st_atime; /* Time of last access. */
- int st_atime_nsec;
- int st_mtime; /* Time of last modification. */
- int st_mtime_nsec;
- int st_ctime; /* Time of last status change. */
- int st_ctime_nsec;
- unsigned int __unused4;
- unsigned int __unused5;
-};
-#endif
diff --git a/include/asm-ppc64/system.h b/include/asm-ppc64/system.h
index 375015c62f20..bf9a6aba19c9 100644
--- a/include/asm-ppc64/system.h
+++ b/include/asm-ppc64/system.h
@@ -13,7 +13,7 @@
#include <asm/page.h>
#include <asm/processor.h>
#include <asm/hw_irq.h>
-#include <asm/memory.h>
+#include <asm/synch.h>
/*
* Memory barrier.
@@ -48,7 +48,7 @@
#ifdef CONFIG_SMP
#define smp_mb() mb()
#define smp_rmb() rmb()
-#define smp_wmb() __asm__ __volatile__ ("eieio" : : : "memory")
+#define smp_wmb() eieio()
#define smp_read_barrier_depends() read_barrier_depends()
#else
#define smp_mb() __asm__ __volatile__("": : :"memory")
@@ -120,8 +120,8 @@ extern void giveup_altivec(struct task_struct *);
extern void disable_kernel_altivec(void);
extern void enable_kernel_altivec(void);
extern int emulate_altivec(struct pt_regs *);
-extern void cvt_fd(float *from, double *to, unsigned long *fpscr);
-extern void cvt_df(double *from, float *to, unsigned long *fpscr);
+extern void cvt_fd(float *from, double *to, struct thread_struct *thread);
+extern void cvt_df(double *from, float *to, struct thread_struct *thread);
#ifdef CONFIG_ALTIVEC
extern void flush_altivec_to_thread(struct task_struct *);
@@ -131,7 +131,12 @@ static inline void flush_altivec_to_thread(struct task_struct *t)
}
#endif
+static inline void flush_spe_to_thread(struct task_struct *t)
+{
+}
+
extern int mem_init_done; /* set on boot once kmalloc can be called */
+extern unsigned long memory_limit;
/* EBCDIC -> ASCII conversion for [0-9A-Z] on iSeries */
extern unsigned char e2a(unsigned char);
@@ -144,12 +149,9 @@ struct thread_struct;
extern struct task_struct * _switch(struct thread_struct *prev,
struct thread_struct *next);
-static inline int __is_processor(unsigned long pv)
-{
- unsigned long pvr;
- asm("mfspr %0, 0x11F" : "=r" (pvr));
- return(PVR_VER(pvr) == pv);
-}
+extern unsigned long klimit;
+
+extern int powersave_nap; /* set if nap mode can be used in idle loop */
/*
* Atomic exchange
@@ -248,7 +250,7 @@ __cmpxchg_u32(volatile unsigned int *p, unsigned long old, unsigned long new)
}
static __inline__ unsigned long
-__cmpxchg_u64(volatile long *p, unsigned long old, unsigned long new)
+__cmpxchg_u64(volatile unsigned long *p, unsigned long old, unsigned long new)
{
unsigned long prev;
diff --git a/include/asm-ppc64/time.h b/include/asm-ppc64/time.h
deleted file mode 100644
index c6c762cad8b0..000000000000
--- a/include/asm-ppc64/time.h
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Common time prototypes and such for all ppc machines.
- *
- * Written by Cort Dougan (cort@cs.nmt.edu) to merge
- * Paul Mackerras' version and mine for PReP and Pmac.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-
-#ifndef __PPC64_TIME_H
-#define __PPC64_TIME_H
-
-#ifdef __KERNEL__
-#include <linux/config.h>
-#include <linux/types.h>
-#include <linux/mc146818rtc.h>
-
-#include <asm/processor.h>
-#include <asm/paca.h>
-#include <asm/iSeries/HvCall.h>
-
-/* time.c */
-extern unsigned long tb_ticks_per_jiffy;
-extern unsigned long tb_ticks_per_usec;
-extern unsigned long tb_ticks_per_sec;
-extern unsigned long tb_to_xs;
-extern unsigned tb_to_us;
-extern unsigned long tb_last_stamp;
-
-struct rtc_time;
-extern void to_tm(int tim, struct rtc_time * tm);
-extern time_t last_rtc_update;
-
-void generic_calibrate_decr(void);
-void setup_default_decr(void);
-
-/* Some sane defaults: 125 MHz timebase, 1GHz processor */
-extern unsigned long ppc_proc_freq;
-#define DEFAULT_PROC_FREQ (DEFAULT_TB_FREQ * 8)
-extern unsigned long ppc_tb_freq;
-#define DEFAULT_TB_FREQ 125000000UL
-
-/*
- * By putting all of this stuff into a single struct we
- * reduce the number of cache lines touched by do_gettimeofday.
- * Both by collecting all of the data in one cache line and
- * by touching only one TOC entry
- */
-struct gettimeofday_vars {
- unsigned long tb_to_xs;
- unsigned long stamp_xsec;
- unsigned long tb_orig_stamp;
-};
-
-struct gettimeofday_struct {
- unsigned long tb_ticks_per_sec;
- struct gettimeofday_vars vars[2];
- struct gettimeofday_vars * volatile varp;
- unsigned var_idx;
- unsigned tb_to_us;
-};
-
-struct div_result {
- unsigned long result_high;
- unsigned long result_low;
-};
-
-int via_calibrate_decr(void);
-
-static __inline__ unsigned long get_tb(void)
-{
- return mftb();
-}
-
-/* Accessor functions for the decrementer register. */
-static __inline__ unsigned int get_dec(void)
-{
- return (mfspr(SPRN_DEC));
-}
-
-static __inline__ void set_dec(int val)
-{
-#ifdef CONFIG_PPC_ISERIES
- struct paca_struct *lpaca = get_paca();
- int cur_dec;
-
- if (lpaca->lppaca.shared_proc) {
- lpaca->lppaca.virtual_decr = val;
- cur_dec = get_dec();
- if (cur_dec > val)
- HvCall_setVirtualDecr();
- } else
-#endif
- mtspr(SPRN_DEC, val);
-}
-
-static inline unsigned long tb_ticks_since(unsigned long tstamp)
-{
- return get_tb() - tstamp;
-}
-
-#define mulhwu(x,y) \
-({unsigned z; asm ("mulhwu %0,%1,%2" : "=r" (z) : "r" (x), "r" (y)); z;})
-#define mulhdu(x,y) \
-({unsigned long z; asm ("mulhdu %0,%1,%2" : "=r" (z) : "r" (x), "r" (y)); z;})
-
-
-unsigned mulhwu_scale_factor(unsigned, unsigned);
-void div128_by_32( unsigned long dividend_high, unsigned long dividend_low,
- unsigned divisor, struct div_result *dr );
-
-/* Used to store Processor Utilization register (purr) values */
-
-struct cpu_usage {
- u64 current_tb; /* Holds the current purr register values */
-};
-
-DECLARE_PER_CPU(struct cpu_usage, cpu_usage_array);
-
-#endif /* __KERNEL__ */
-#endif /* __PPC64_TIME_H */
diff --git a/include/asm-ppc64/tlb.h b/include/asm-ppc64/tlb.h
deleted file mode 100644
index 97cb696ce68d..000000000000
--- a/include/asm-ppc64/tlb.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * TLB shootdown specifics for PPC64
- *
- * Copyright (C) 2002 Anton Blanchard, IBM Corp.
- * Copyright (C) 2002 Paul Mackerras, IBM Corp.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-#ifndef _PPC64_TLB_H
-#define _PPC64_TLB_H
-
-#include <asm/tlbflush.h>
-
-struct mmu_gather;
-
-extern void pte_free_finish(void);
-
-static inline void tlb_flush(struct mmu_gather *tlb)
-{
- flush_tlb_pending();
- pte_free_finish();
-}
-
-/* Avoid pulling in another include just for this */
-#define check_pgt_cache() do { } while (0)
-
-/* Get the generic bits... */
-#include <asm-generic/tlb.h>
-
-/* Nothing needed here in fact... */
-#define tlb_start_vma(tlb, vma) do { } while (0)
-#define tlb_end_vma(tlb, vma) do { } while (0)
-
-#define __tlb_remove_tlb_entry(tlb, pte, address) do { } while (0)
-
-#endif /* _PPC64_TLB_H */
diff --git a/include/asm-ppc64/tlbflush.h b/include/asm-ppc64/tlbflush.h
deleted file mode 100644
index 74271d7c1d16..000000000000
--- a/include/asm-ppc64/tlbflush.h
+++ /dev/null
@@ -1,55 +0,0 @@
-#ifndef _PPC64_TLBFLUSH_H
-#define _PPC64_TLBFLUSH_H
-
-/*
- * TLB flushing:
- *
- * - flush_tlb_mm(mm) flushes the specified mm context TLB's
- * - flush_tlb_page(vma, vmaddr) flushes one page
- * - flush_tlb_page_nohash(vma, vmaddr) flushes one page if SW loaded TLB
- * - flush_tlb_range(vma, start, end) flushes a range of pages
- * - flush_tlb_kernel_range(start, end) flushes a range of kernel pages
- * - flush_tlb_pgtables(mm, start, end) flushes a range of page tables
- */
-
-#include <linux/percpu.h>
-#include <asm/page.h>
-
-#define PPC64_TLB_BATCH_NR 192
-
-struct mm_struct;
-struct ppc64_tlb_batch {
- unsigned long index;
- unsigned long context;
- struct mm_struct *mm;
- pte_t pte[PPC64_TLB_BATCH_NR];
- unsigned long addr[PPC64_TLB_BATCH_NR];
- unsigned long vaddr[PPC64_TLB_BATCH_NR];
- unsigned int large;
-};
-DECLARE_PER_CPU(struct ppc64_tlb_batch, ppc64_tlb_batch);
-
-extern void __flush_tlb_pending(struct ppc64_tlb_batch *batch);
-
-static inline void flush_tlb_pending(void)
-{
- struct ppc64_tlb_batch *batch = &get_cpu_var(ppc64_tlb_batch);
-
- if (batch->index)
- __flush_tlb_pending(batch);
- put_cpu_var(ppc64_tlb_batch);
-}
-
-#define flush_tlb_mm(mm) flush_tlb_pending()
-#define flush_tlb_page(vma, addr) flush_tlb_pending()
-#define flush_tlb_page_nohash(vma, addr) do { } while (0)
-#define flush_tlb_range(vma, start, end) \
- do { (void)(start); flush_tlb_pending(); } while (0)
-#define flush_tlb_kernel_range(start, end) flush_tlb_pending()
-#define flush_tlb_pgtables(mm, start, end) do { } while (0)
-
-extern void flush_hash_page(unsigned long context, unsigned long ea, pte_t pte,
- int local);
-void flush_hash_range(unsigned long context, unsigned long number, int local);
-
-#endif /* _PPC64_TLBFLUSH_H */
diff --git a/include/asm-ppc64/uaccess.h b/include/asm-ppc64/uaccess.h
deleted file mode 100644
index 132c1276547b..000000000000
--- a/include/asm-ppc64/uaccess.h
+++ /dev/null
@@ -1,341 +0,0 @@
-#ifndef _PPC64_UACCESS_H
-#define _PPC64_UACCESS_H
-
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-
-#ifndef __ASSEMBLY__
-#include <linux/sched.h>
-#include <linux/errno.h>
-#include <asm/processor.h>
-
-#define VERIFY_READ 0
-#define VERIFY_WRITE 1
-
-/*
- * The fs value determines whether argument validity checking should be
- * performed or not. If get_fs() == USER_DS, checking is performed, with
- * get_fs() == KERNEL_DS, checking is bypassed.
- *
- * For historical reasons, these macros are grossly misnamed.
- */
-
-#define MAKE_MM_SEG(s) ((mm_segment_t) { (s) })
-
-#define KERNEL_DS MAKE_MM_SEG(0UL)
-#define USER_DS MAKE_MM_SEG(0xf000000000000000UL)
-
-#define get_ds() (KERNEL_DS)
-#define get_fs() (current->thread.fs)
-#define set_fs(val) (current->thread.fs = (val))
-
-#define segment_eq(a,b) ((a).seg == (b).seg)
-
-/*
- * Use the alpha trick for checking ranges:
- *
- * Is a address valid? This does a straightforward calculation rather
- * than tests.
- *
- * Address valid if:
- * - "addr" doesn't have any high-bits set
- * - AND "size" doesn't have any high-bits set
- * - OR we are in kernel mode.
- *
- * We dont have to check for high bits in (addr+size) because the first
- * two checks force the maximum result to be below the start of the
- * kernel region.
- */
-#define __access_ok(addr,size,segment) \
- (((segment).seg & (addr | size )) == 0)
-
-#define access_ok(type,addr,size) \
- __access_ok(((__force unsigned long)(addr)),(size),get_fs())
-
-/*
- * The exception table consists of pairs of addresses: the first is the
- * address of an instruction that is allowed to fault, and the second is
- * the address at which the program should continue. No registers are
- * modified, so it is entirely up to the continuation code to figure out
- * what to do.
- *
- * All the routines below use bits of fixup code that are out of line
- * with the main instruction path. This means when everything is well,
- * we don't even have to jump over them. Further, they do not intrude
- * on our cache or tlb entries.
- */
-
-struct exception_table_entry
-{
- unsigned long insn, fixup;
-};
-
-/* Returns 0 if exception not found and fixup otherwise. */
-extern unsigned long search_exception_table(unsigned long);
-
-/*
- * These are the main single-value transfer routines. They automatically
- * use the right size if we just have the right pointer type.
- *
- * This gets kind of ugly. We want to return _two_ values in "get_user()"
- * and yet we don't want to do any pointers, because that is too much
- * of a performance impact. Thus we have a few rather ugly macros here,
- * and hide all the ugliness from the user.
- *
- * The "__xxx" versions of the user access functions are versions that
- * do not verify the address space, that must have been done previously
- * with a separate "access_ok()" call (this is used when we do multiple
- * accesses to the same area of user memory).
- *
- * As we use the same address space for kernel and user data on the
- * PowerPC, we can just do these as direct assignments. (Of course, the
- * exception handling means that it's no longer "just"...)
- */
-#define get_user(x,ptr) \
- __get_user_check((x),(ptr),sizeof(*(ptr)))
-#define put_user(x,ptr) \
- __put_user_check((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr)))
-
-#define __get_user(x,ptr) \
- __get_user_nocheck((x),(ptr),sizeof(*(ptr)))
-#define __put_user(x,ptr) \
- __put_user_nocheck((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr)))
-
-#define __get_user_unaligned __get_user
-#define __put_user_unaligned __put_user
-
-extern long __put_user_bad(void);
-
-#define __put_user_nocheck(x,ptr,size) \
-({ \
- long __pu_err; \
- might_sleep(); \
- __chk_user_ptr(ptr); \
- __put_user_size((x),(ptr),(size),__pu_err,-EFAULT); \
- __pu_err; \
-})
-
-#define __put_user_check(x,ptr,size) \
-({ \
- long __pu_err = -EFAULT; \
- void __user *__pu_addr = (ptr); \
- might_sleep(); \
- if (access_ok(VERIFY_WRITE,__pu_addr,size)) \
- __put_user_size((x),__pu_addr,(size),__pu_err,-EFAULT); \
- __pu_err; \
-})
-
-#define __put_user_size(x,ptr,size,retval,errret) \
-do { \
- retval = 0; \
- switch (size) { \
- case 1: __put_user_asm(x,ptr,retval,"stb",errret); break; \
- case 2: __put_user_asm(x,ptr,retval,"sth",errret); break; \
- case 4: __put_user_asm(x,ptr,retval,"stw",errret); break; \
- case 8: __put_user_asm(x,ptr,retval,"std",errret); break; \
- default: __put_user_bad(); \
- } \
-} while (0)
-
-/*
- * We don't tell gcc that we are accessing memory, but this is OK
- * because we do not write to any memory gcc knows about, so there
- * are no aliasing issues.
- */
-#define __put_user_asm(x, addr, err, op, errret) \
- __asm__ __volatile__( \
- "1: "op" %1,0(%2) # put_user\n" \
- "2:\n" \
- ".section .fixup,\"ax\"\n" \
- "3: li %0,%3\n" \
- " b 2b\n" \
- ".previous\n" \
- ".section __ex_table,\"a\"\n" \
- " .align 3\n" \
- " .llong 1b,3b\n" \
- ".previous" \
- : "=r"(err) \
- : "r"(x), "b"(addr), "i"(errret), "0"(err))
-
-
-#define __get_user_nocheck(x,ptr,size) \
-({ \
- long __gu_err; \
- unsigned long __gu_val; \
- might_sleep(); \
- __get_user_size(__gu_val,(ptr),(size),__gu_err,-EFAULT);\
- (x) = (__typeof__(*(ptr)))__gu_val; \
- __gu_err; \
-})
-
-#define __get_user_check(x,ptr,size) \
-({ \
- long __gu_err = -EFAULT; \
- unsigned long __gu_val = 0; \
- const __typeof__(*(ptr)) __user *__gu_addr = (ptr); \
- might_sleep(); \
- if (access_ok(VERIFY_READ,__gu_addr,size)) \
- __get_user_size(__gu_val,__gu_addr,(size),__gu_err,-EFAULT);\
- (x) = (__typeof__(*(ptr)))__gu_val; \
- __gu_err; \
-})
-
-extern long __get_user_bad(void);
-
-#define __get_user_size(x,ptr,size,retval,errret) \
-do { \
- retval = 0; \
- __chk_user_ptr(ptr); \
- switch (size) { \
- case 1: __get_user_asm(x,ptr,retval,"lbz",errret); break; \
- case 2: __get_user_asm(x,ptr,retval,"lhz",errret); break; \
- case 4: __get_user_asm(x,ptr,retval,"lwz",errret); break; \
- case 8: __get_user_asm(x,ptr,retval,"ld",errret); break; \
- default: (x) = __get_user_bad(); \
- } \
-} while (0)
-
-#define __get_user_asm(x, addr, err, op, errret) \
- __asm__ __volatile__( \
- "1: "op" %1,0(%2) # get_user\n" \
- "2:\n" \
- ".section .fixup,\"ax\"\n" \
- "3: li %0,%3\n" \
- " li %1,0\n" \
- " b 2b\n" \
- ".previous\n" \
- ".section __ex_table,\"a\"\n" \
- " .align 3\n" \
- " .llong 1b,3b\n" \
- ".previous" \
- : "=r"(err), "=r"(x) \
- : "b"(addr), "i"(errret), "0"(err))
-
-/* more complex routines */
-
-extern unsigned long __copy_tofrom_user(void __user *to, const void __user *from,
- unsigned long size);
-
-static inline unsigned long
-__copy_from_user_inatomic(void *to, const void __user *from, unsigned long n)
-{
- if (__builtin_constant_p(n)) {
- unsigned long ret;
-
- switch (n) {
- case 1:
- __get_user_size(*(u8 *)to, from, 1, ret, 1);
- return ret;
- case 2:
- __get_user_size(*(u16 *)to, from, 2, ret, 2);
- return ret;
- case 4:
- __get_user_size(*(u32 *)to, from, 4, ret, 4);
- return ret;
- case 8:
- __get_user_size(*(u64 *)to, from, 8, ret, 8);
- return ret;
- }
- }
- return __copy_tofrom_user((__force void __user *) to, from, n);
-}
-
-static inline unsigned long
-__copy_from_user(void *to, const void __user *from, unsigned long n)
-{
- might_sleep();
- return __copy_from_user_inatomic(to, from, n);
-}
-
-static inline unsigned long
-__copy_to_user_inatomic(void __user *to, const void *from, unsigned long n)
-{
- if (__builtin_constant_p(n)) {
- unsigned long ret;
-
- switch (n) {
- case 1:
- __put_user_size(*(u8 *)from, (u8 __user *)to, 1, ret, 1);
- return ret;
- case 2:
- __put_user_size(*(u16 *)from, (u16 __user *)to, 2, ret, 2);
- return ret;
- case 4:
- __put_user_size(*(u32 *)from, (u32 __user *)to, 4, ret, 4);
- return ret;
- case 8:
- __put_user_size(*(u64 *)from, (u64 __user *)to, 8, ret, 8);
- return ret;
- }
- }
- return __copy_tofrom_user(to, (__force const void __user *) from, n);
-}
-
-static inline unsigned long
-__copy_to_user(void __user *to, const void *from, unsigned long n)
-{
- might_sleep();
- return __copy_to_user_inatomic(to, from, n);
-}
-
-#define __copy_in_user(to, from, size) \
- __copy_tofrom_user((to), (from), (size))
-
-extern unsigned long copy_from_user(void *to, const void __user *from,
- unsigned long n);
-extern unsigned long copy_to_user(void __user *to, const void *from,
- unsigned long n);
-extern unsigned long copy_in_user(void __user *to, const void __user *from,
- unsigned long n);
-
-extern unsigned long __clear_user(void __user *addr, unsigned long size);
-
-static inline unsigned long
-clear_user(void __user *addr, unsigned long size)
-{
- might_sleep();
- if (likely(access_ok(VERIFY_WRITE, addr, size)))
- size = __clear_user(addr, size);
- return size;
-}
-
-extern int __strncpy_from_user(char *dst, const char __user *src, long count);
-
-static inline long
-strncpy_from_user(char *dst, const char __user *src, long count)
-{
- might_sleep();
- if (likely(access_ok(VERIFY_READ, src, 1)))
- return __strncpy_from_user(dst, src, count);
- return -EFAULT;
-}
-
-/*
- * Return the size of a string (including the ending 0)
- *
- * Return 0 for error
- */
-extern int __strnlen_user(const char __user *str, long len);
-
-/*
- * Returns the length of the string at str (including the null byte),
- * or 0 if we hit a page we can't access,
- * or something > len if we didn't find a null byte.
- */
-static inline int strnlen_user(const char __user *str, long len)
-{
- might_sleep();
- if (likely(access_ok(VERIFY_READ, str, 1)))
- return __strnlen_user(str, len);
- return 0;
-}
-
-#define strlen_user(str) strnlen_user((str), 0x7ffffffe)
-
-#endif /* __ASSEMBLY__ */
-
-#endif /* _PPC64_UACCESS_H */
diff --git a/include/asm-ppc64/ucontext.h b/include/asm-ppc64/ucontext.h
deleted file mode 100644
index ef8cc5b37542..000000000000
--- a/include/asm-ppc64/ucontext.h
+++ /dev/null
@@ -1,22 +0,0 @@
-#ifndef _ASMPPC64_UCONTEXT_H
-#define _ASMPPC64_UCONTEXT_H
-
-#include <asm/sigcontext.h>
-
-/*
- * 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.
- */
-
-struct ucontext {
- unsigned long uc_flags;
- struct ucontext *uc_link;
- stack_t uc_stack;
- sigset_t uc_sigmask;
- sigset_t __unsued[15]; /* Allow for uc_sigmask growth */
- struct sigcontext uc_mcontext; /* last for extensibility */
-};
-
-#endif /* _ASMPPC64_UCONTEXT_H */
diff --git a/include/asm-ppc64/udbg.h b/include/asm-ppc64/udbg.h
index c786604aef02..e3b927991851 100644
--- a/include/asm-ppc64/udbg.h
+++ b/include/asm-ppc64/udbg.h
@@ -23,9 +23,9 @@ extern int udbg_read(char *buf, int buflen);
extern void register_early_udbg_console(void);
extern void udbg_printf(const char *fmt, ...);
-extern void udbg_ppcdbg(unsigned long flags, const char *fmt, ...);
-extern unsigned long udbg_ifdebug(unsigned long flags);
-extern void __init ppcdbg_initialize(void);
extern void udbg_init_uart(void __iomem *comport, unsigned int speed);
+
+struct device_node;
+extern void udbg_init_scc(struct device_node *np);
#endif
diff --git a/include/asm-ppc64/uninorth.h b/include/asm-ppc64/uninorth.h
deleted file mode 100644
index 7ad7059f2c80..000000000000
--- a/include/asm-ppc64/uninorth.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include <asm-ppc/uninorth.h>
-
diff --git a/include/asm-ppc64/unistd.h b/include/asm-ppc64/unistd.h
deleted file mode 100644
index 977bc980c1af..000000000000
--- a/include/asm-ppc64/unistd.h
+++ /dev/null
@@ -1,487 +0,0 @@
-#ifndef _ASM_PPC_UNISTD_H_
-#define _ASM_PPC_UNISTD_H_
-
-/*
- * This file contains the system call numbers.
- *
- * 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.
- */
-
-#define __NR_restart_syscall 0
-#define __NR_exit 1
-#define __NR_fork 2
-#define __NR_read 3
-#define __NR_write 4
-#define __NR_open 5
-#define __NR_close 6
-#define __NR_waitpid 7
-#define __NR_creat 8
-#define __NR_link 9
-#define __NR_unlink 10
-#define __NR_execve 11
-#define __NR_chdir 12
-#define __NR_time 13
-#define __NR_mknod 14
-#define __NR_chmod 15
-#define __NR_lchown 16
-#define __NR_break 17
-#define __NR_oldstat 18
-#define __NR_lseek 19
-#define __NR_getpid 20
-#define __NR_mount 21
-#define __NR_umount 22
-#define __NR_setuid 23
-#define __NR_getuid 24
-#define __NR_stime 25
-#define __NR_ptrace 26
-#define __NR_alarm 27
-#define __NR_oldfstat 28
-#define __NR_pause 29
-#define __NR_utime 30
-#define __NR_stty 31
-#define __NR_gtty 32
-#define __NR_access 33
-#define __NR_nice 34
-#define __NR_ftime 35
-#define __NR_sync 36
-#define __NR_kill 37
-#define __NR_rename 38
-#define __NR_mkdir 39
-#define __NR_rmdir 40
-#define __NR_dup 41
-#define __NR_pipe 42
-#define __NR_times 43
-#define __NR_prof 44
-#define __NR_brk 45
-#define __NR_setgid 46
-#define __NR_getgid 47
-#define __NR_signal 48
-#define __NR_geteuid 49
-#define __NR_getegid 50
-#define __NR_acct 51
-#define __NR_umount2 52
-#define __NR_lock 53
-#define __NR_ioctl 54
-#define __NR_fcntl 55
-#define __NR_mpx 56
-#define __NR_setpgid 57
-#define __NR_ulimit 58
-#define __NR_oldolduname 59
-#define __NR_umask 60
-#define __NR_chroot 61
-#define __NR_ustat 62
-#define __NR_dup2 63
-#define __NR_getppid 64
-#define __NR_getpgrp 65
-#define __NR_setsid 66
-#define __NR_sigaction 67
-#define __NR_sgetmask 68
-#define __NR_ssetmask 69
-#define __NR_setreuid 70
-#define __NR_setregid 71
-#define __NR_sigsuspend 72
-#define __NR_sigpending 73
-#define __NR_sethostname 74
-#define __NR_setrlimit 75
-#define __NR_getrlimit 76
-#define __NR_getrusage 77
-#define __NR_gettimeofday 78
-#define __NR_settimeofday 79
-#define __NR_getgroups 80
-#define __NR_setgroups 81
-#define __NR_select 82
-#define __NR_symlink 83
-#define __NR_oldlstat 84
-#define __NR_readlink 85
-#define __NR_uselib 86
-#define __NR_swapon 87
-#define __NR_reboot 88
-#define __NR_readdir 89
-#define __NR_mmap 90
-#define __NR_munmap 91
-#define __NR_truncate 92
-#define __NR_ftruncate 93
-#define __NR_fchmod 94
-#define __NR_fchown 95
-#define __NR_getpriority 96
-#define __NR_setpriority 97
-#define __NR_profil 98
-#define __NR_statfs 99
-#define __NR_fstatfs 100
-#define __NR_ioperm 101
-#define __NR_socketcall 102
-#define __NR_syslog 103
-#define __NR_setitimer 104
-#define __NR_getitimer 105
-#define __NR_stat 106
-#define __NR_lstat 107
-#define __NR_fstat 108
-#define __NR_olduname 109
-#define __NR_iopl 110
-#define __NR_vhangup 111
-#define __NR_idle 112
-#define __NR_vm86 113
-#define __NR_wait4 114
-#define __NR_swapoff 115
-#define __NR_sysinfo 116
-#define __NR_ipc 117
-#define __NR_fsync 118
-#define __NR_sigreturn 119
-#define __NR_clone 120
-#define __NR_setdomainname 121
-#define __NR_uname 122
-#define __NR_modify_ldt 123
-#define __NR_adjtimex 124
-#define __NR_mprotect 125
-#define __NR_sigprocmask 126
-#define __NR_create_module 127
-#define __NR_init_module 128
-#define __NR_delete_module 129
-#define __NR_get_kernel_syms 130
-#define __NR_quotactl 131
-#define __NR_getpgid 132
-#define __NR_fchdir 133
-#define __NR_bdflush 134
-#define __NR_sysfs 135
-#define __NR_personality 136
-#define __NR_afs_syscall 137 /* Syscall for Andrew File System */
-#define __NR_setfsuid 138
-#define __NR_setfsgid 139
-#define __NR__llseek 140
-#define __NR_getdents 141
-#define __NR__newselect 142
-#define __NR_flock 143
-#define __NR_msync 144
-#define __NR_readv 145
-#define __NR_writev 146
-#define __NR_getsid 147
-#define __NR_fdatasync 148
-#define __NR__sysctl 149
-#define __NR_mlock 150
-#define __NR_munlock 151
-#define __NR_mlockall 152
-#define __NR_munlockall 153
-#define __NR_sched_setparam 154
-#define __NR_sched_getparam 155
-#define __NR_sched_setscheduler 156
-#define __NR_sched_getscheduler 157
-#define __NR_sched_yield 158
-#define __NR_sched_get_priority_max 159
-#define __NR_sched_get_priority_min 160
-#define __NR_sched_rr_get_interval 161
-#define __NR_nanosleep 162
-#define __NR_mremap 163
-#define __NR_setresuid 164
-#define __NR_getresuid 165
-#define __NR_query_module 166
-#define __NR_poll 167
-#define __NR_nfsservctl 168
-#define __NR_setresgid 169
-#define __NR_getresgid 170
-#define __NR_prctl 171
-#define __NR_rt_sigreturn 172
-#define __NR_rt_sigaction 173
-#define __NR_rt_sigprocmask 174
-#define __NR_rt_sigpending 175
-#define __NR_rt_sigtimedwait 176
-#define __NR_rt_sigqueueinfo 177
-#define __NR_rt_sigsuspend 178
-#define __NR_pread64 179
-#define __NR_pwrite64 180
-#define __NR_chown 181
-#define __NR_getcwd 182
-#define __NR_capget 183
-#define __NR_capset 184
-#define __NR_sigaltstack 185
-#define __NR_sendfile 186
-#define __NR_getpmsg 187 /* some people actually want streams */
-#define __NR_putpmsg 188 /* some people actually want streams */
-#define __NR_vfork 189
-#define __NR_ugetrlimit 190 /* SuS compliant getrlimit */
-#define __NR_readahead 191
-/* #define __NR_mmap2 192 32bit only */
-/* #define __NR_truncate64 193 32bit only */
-/* #define __NR_ftruncate64 194 32bit only */
-/* #define __NR_stat64 195 32bit only */
-/* #define __NR_lstat64 196 32bit only */
-/* #define __NR_fstat64 197 32bit only */
-#define __NR_pciconfig_read 198
-#define __NR_pciconfig_write 199
-#define __NR_pciconfig_iobase 200
-#define __NR_multiplexer 201
-#define __NR_getdents64 202
-#define __NR_pivot_root 203
-/* #define __NR_fcntl64 204 32bit only */
-#define __NR_madvise 205
-#define __NR_mincore 206
-#define __NR_gettid 207
-#define __NR_tkill 208
-#define __NR_setxattr 209
-#define __NR_lsetxattr 210
-#define __NR_fsetxattr 211
-#define __NR_getxattr 212
-#define __NR_lgetxattr 213
-#define __NR_fgetxattr 214
-#define __NR_listxattr 215
-#define __NR_llistxattr 216
-#define __NR_flistxattr 217
-#define __NR_removexattr 218
-#define __NR_lremovexattr 219
-#define __NR_fremovexattr 220
-#define __NR_futex 221
-#define __NR_sched_setaffinity 222
-#define __NR_sched_getaffinity 223
-/* 224 currently unused */
-#define __NR_tuxcall 225
-/* #define __NR_sendfile64 226 32bit only */
-#define __NR_io_setup 227
-#define __NR_io_destroy 228
-#define __NR_io_getevents 229
-#define __NR_io_submit 230
-#define __NR_io_cancel 231
-#define __NR_set_tid_address 232
-#define __NR_fadvise64 233
-#define __NR_exit_group 234
-#define __NR_lookup_dcookie 235
-#define __NR_epoll_create 236
-#define __NR_epoll_ctl 237
-#define __NR_epoll_wait 238
-#define __NR_remap_file_pages 239
-#define __NR_timer_create 240
-#define __NR_timer_settime 241
-#define __NR_timer_gettime 242
-#define __NR_timer_getoverrun 243
-#define __NR_timer_delete 244
-#define __NR_clock_settime 245
-#define __NR_clock_gettime 246
-#define __NR_clock_getres 247
-#define __NR_clock_nanosleep 248
-#define __NR_swapcontext 249
-#define __NR_tgkill 250
-#define __NR_utimes 251
-#define __NR_statfs64 252
-#define __NR_fstatfs64 253
-/* #define __NR_fadvise64_64 254 32bit only */
-#define __NR_rtas 255
-/* Number 256 is reserved for sys_debug_setcontext */
-/* Number 257 is reserved for vserver */
-/* 258 currently unused */
-#define __NR_mbind 259
-#define __NR_get_mempolicy 260
-#define __NR_set_mempolicy 261
-#define __NR_mq_open 262
-#define __NR_mq_unlink 263
-#define __NR_mq_timedsend 264
-#define __NR_mq_timedreceive 265
-#define __NR_mq_notify 266
-#define __NR_mq_getsetattr 267
-#define __NR_kexec_load 268
-#define __NR_add_key 269
-#define __NR_request_key 270
-#define __NR_keyctl 271
-#define __NR_waitid 272
-#define __NR_ioprio_set 273
-#define __NR_ioprio_get 274
-#define __NR_inotify_init 275
-#define __NR_inotify_add_watch 276
-#define __NR_inotify_rm_watch 277
-
-#define __NR_syscalls 278
-#ifdef __KERNEL__
-#define NR_syscalls __NR_syscalls
-#endif
-
-#ifndef __ASSEMBLY__
-
-/* On powerpc a system call basically clobbers the same registers like a
- * function call, with the exception of LR (which is needed for the
- * "sc; bnslr" sequence) and CR (where only CR0.SO is clobbered to signal
- * an error return status).
- */
-
-#define __syscall_nr(nr, type, name, args...) \
- unsigned long __sc_ret, __sc_err; \
- { \
- register unsigned long __sc_0 __asm__ ("r0"); \
- register unsigned long __sc_3 __asm__ ("r3"); \
- register unsigned long __sc_4 __asm__ ("r4"); \
- register unsigned long __sc_5 __asm__ ("r5"); \
- register unsigned long __sc_6 __asm__ ("r6"); \
- register unsigned long __sc_7 __asm__ ("r7"); \
- register unsigned long __sc_8 __asm__ ("r8"); \
- \
- __sc_loadargs_##nr(name, args); \
- __asm__ __volatile__ \
- ("sc \n\t" \
- "mfcr %0 " \
- : "=&r" (__sc_0), \
- "=&r" (__sc_3), "=&r" (__sc_4), \
- "=&r" (__sc_5), "=&r" (__sc_6), \
- "=&r" (__sc_7), "=&r" (__sc_8) \
- : __sc_asm_input_##nr \
- : "cr0", "ctr", "memory", \
- "r9", "r10","r11", "r12"); \
- __sc_ret = __sc_3; \
- __sc_err = __sc_0; \
- } \
- if (__sc_err & 0x10000000) \
- { \
- errno = __sc_ret; \
- __sc_ret = -1; \
- } \
- return (type) __sc_ret
-
-#define __sc_loadargs_0(name, dummy...) \
- __sc_0 = __NR_##name
-#define __sc_loadargs_1(name, arg1) \
- __sc_loadargs_0(name); \
- __sc_3 = (unsigned long) (arg1)
-#define __sc_loadargs_2(name, arg1, arg2) \
- __sc_loadargs_1(name, arg1); \
- __sc_4 = (unsigned long) (arg2)
-#define __sc_loadargs_3(name, arg1, arg2, arg3) \
- __sc_loadargs_2(name, arg1, arg2); \
- __sc_5 = (unsigned long) (arg3)
-#define __sc_loadargs_4(name, arg1, arg2, arg3, arg4) \
- __sc_loadargs_3(name, arg1, arg2, arg3); \
- __sc_6 = (unsigned long) (arg4)
-#define __sc_loadargs_5(name, arg1, arg2, arg3, arg4, arg5) \
- __sc_loadargs_4(name, arg1, arg2, arg3, arg4); \
- __sc_7 = (unsigned long) (arg5)
-#define __sc_loadargs_6(name, arg1, arg2, arg3, arg4, arg5, arg6) \
- __sc_loadargs_5(name, arg1, arg2, arg3, arg4, arg5); \
- __sc_8 = (unsigned long) (arg6)
-
-#define __sc_asm_input_0 "0" (__sc_0)
-#define __sc_asm_input_1 __sc_asm_input_0, "1" (__sc_3)
-#define __sc_asm_input_2 __sc_asm_input_1, "2" (__sc_4)
-#define __sc_asm_input_3 __sc_asm_input_2, "3" (__sc_5)
-#define __sc_asm_input_4 __sc_asm_input_3, "4" (__sc_6)
-#define __sc_asm_input_5 __sc_asm_input_4, "5" (__sc_7)
-#define __sc_asm_input_6 __sc_asm_input_5, "6" (__sc_8)
-
-#define _syscall0(type,name) \
-type name(void) \
-{ \
- __syscall_nr(0, type, name); \
-}
-
-#define _syscall1(type,name,type1,arg1) \
-type name(type1 arg1) \
-{ \
- __syscall_nr(1, type, name, arg1); \
-}
-
-#define _syscall2(type,name,type1,arg1,type2,arg2) \
-type name(type1 arg1, type2 arg2) \
-{ \
- __syscall_nr(2, type, name, arg1, arg2); \
-}
-
-#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
-type name(type1 arg1, type2 arg2, type3 arg3) \
-{ \
- __syscall_nr(3, type, name, arg1, arg2, arg3); \
-}
-
-#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
-type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4) \
-{ \
- __syscall_nr(4, type, name, arg1, arg2, arg3, arg4); \
-}
-
-#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5) \
-type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5) \
-{ \
- __syscall_nr(5, type, name, arg1, arg2, arg3, arg4, arg5); \
-}
-#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5,type6,arg6) \
-type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6) \
-{ \
- __syscall_nr(6, type, name, arg1, arg2, arg3, arg4, arg5, arg6); \
-}
-
-#ifdef __KERNEL_SYSCALLS__
-
-/*
- * Forking from kernel space will result in the child getting a new,
- * empty kernel stack area. Thus the child cannot access automatic
- * variables set in the parent unless they are in registers, and the
- * procedure where the fork was done cannot return to its caller in
- * the child.
- */
-
-/*
- * System call prototypes.
- */
-static inline _syscall3(int, execve, __const__ char *, file, char **, argv,
- char **,envp)
-
-#endif /* __KERNEL_SYSCALLS__ */
-
-#ifdef __KERNEL__
-
-#include <linux/types.h>
-#include <linux/compiler.h>
-#include <linux/linkage.h>
-
-#define __ARCH_WANT_IPC_PARSE_VERSION
-#define __ARCH_WANT_OLD_READDIR
-#define __ARCH_WANT_STAT64
-#define __ARCH_WANT_SYS_ALARM
-#define __ARCH_WANT_SYS_GETHOSTNAME
-#define __ARCH_WANT_SYS_PAUSE
-#define __ARCH_WANT_SYS_SGETMASK
-#define __ARCH_WANT_SYS_SIGNAL
-#define __ARCH_WANT_SYS_TIME
-#define __ARCH_WANT_COMPAT_SYS_TIME
-#define __ARCH_WANT_SYS_UTIME
-#define __ARCH_WANT_SYS_WAITPID
-#define __ARCH_WANT_SYS_SOCKETCALL
-#define __ARCH_WANT_SYS_FADVISE64
-#define __ARCH_WANT_SYS_GETPGRP
-#define __ARCH_WANT_SYS_LLSEEK
-#define __ARCH_WANT_SYS_NICE
-#define __ARCH_WANT_SYS_OLD_GETRLIMIT
-#define __ARCH_WANT_SYS_OLDUMOUNT
-#define __ARCH_WANT_SYS_SIGPENDING
-#define __ARCH_WANT_SYS_SIGPROCMASK
-#define __ARCH_WANT_SYS_RT_SIGACTION
-
-unsigned long sys_mmap(unsigned long addr, size_t len, unsigned long prot,
- unsigned long flags, unsigned long fd, off_t offset);
-struct pt_regs;
-int sys_execve(unsigned long a0, unsigned long a1, unsigned long a2,
- unsigned long a3, unsigned long a4, unsigned long a5,
- struct pt_regs *regs);
-int sys_clone(unsigned long clone_flags, unsigned long p2, unsigned long p3,
- unsigned long p4, unsigned long p5, unsigned long p6,
- struct pt_regs *regs);
-int sys_fork(unsigned long p1, unsigned long p2, unsigned long p3,
- unsigned long p4, unsigned long p5, unsigned long p6,
- struct pt_regs *regs);
-int sys_vfork(unsigned long p1, unsigned long p2, unsigned long p3,
- unsigned long p4, unsigned long p5, unsigned long p6,
- struct pt_regs *regs);
-int sys_pipe(int __user *fildes);
-int sys_ptrace(long request, long pid, long addr, long data);
-struct sigaction;
-long sys_rt_sigaction(int sig, const struct sigaction __user *act,
- struct sigaction __user *oact, size_t sigsetsize);
-
-/*
- * "Conditional" syscalls
- *
- * What we want is __attribute__((weak,alias("sys_ni_syscall"))),
- * but it doesn't work on all toolchains, so we just do it by hand
- */
-#define cond_syscall(x) asm(".weak\t." #x "\n\t.set\t." #x ",.sys_ni_syscall")
-
-#endif /* __KERNEL__ */
-
-#endif /* __ASSEMBLY__ */
-
-#endif /* _ASM_PPC_UNISTD_H_ */
diff --git a/include/asm-s390/bitops.h b/include/asm-s390/bitops.h
index 8651524217fd..b07c578b22ea 100644
--- a/include/asm-s390/bitops.h
+++ b/include/asm-s390/bitops.h
@@ -518,8 +518,8 @@ static inline int __test_bit(unsigned long nr, const volatile unsigned long *ptr
static inline int
__constant_test_bit(unsigned long nr, const volatile unsigned long *addr) {
- return (((volatile char *) addr)
- [(nr^(__BITOPS_WORDSIZE-8))>>3] & (1<<(nr&7)));
+ return ((((volatile char *) addr)
+ [(nr^(__BITOPS_WORDSIZE-8))>>3] & (1<<(nr&7)))) != 0;
}
#define test_bit(nr,addr) \
diff --git a/include/asm-s390/debug.h b/include/asm-s390/debug.h
index 7127030ae162..23450ed4b571 100644
--- a/include/asm-s390/debug.h
+++ b/include/asm-s390/debug.h
@@ -129,7 +129,7 @@ void debug_set_level(debug_info_t* id, int new_level);
void debug_stop_all(void);
-extern inline debug_entry_t*
+static inline debug_entry_t*
debug_event(debug_info_t* id, int level, void* data, int length)
{
if ((!id) || (level > id->level) || (id->pages_per_area == 0))
@@ -137,7 +137,7 @@ debug_event(debug_info_t* id, int level, void* data, int length)
return debug_event_common(id,level,data,length);
}
-extern inline debug_entry_t*
+static inline debug_entry_t*
debug_int_event(debug_info_t* id, int level, unsigned int tag)
{
unsigned int t=tag;
@@ -146,7 +146,7 @@ debug_int_event(debug_info_t* id, int level, unsigned int tag)
return debug_event_common(id,level,&t,sizeof(unsigned int));
}
-extern inline debug_entry_t *
+static inline debug_entry_t *
debug_long_event (debug_info_t* id, int level, unsigned long tag)
{
unsigned long t=tag;
@@ -155,7 +155,7 @@ debug_long_event (debug_info_t* id, int level, unsigned long tag)
return debug_event_common(id,level,&t,sizeof(unsigned long));
}
-extern inline debug_entry_t*
+static inline debug_entry_t*
debug_text_event(debug_info_t* id, int level, const char* txt)
{
if ((!id) || (level > id->level) || (id->pages_per_area == 0))
@@ -168,7 +168,7 @@ debug_sprintf_event(debug_info_t* id,int level,char *string,...)
__attribute__ ((format(printf, 3, 4)));
-extern inline debug_entry_t*
+static inline debug_entry_t*
debug_exception(debug_info_t* id, int level, void* data, int length)
{
if ((!id) || (level > id->level) || (id->pages_per_area == 0))
@@ -176,7 +176,7 @@ debug_exception(debug_info_t* id, int level, void* data, int length)
return debug_exception_common(id,level,data,length);
}
-extern inline debug_entry_t*
+static inline debug_entry_t*
debug_int_exception(debug_info_t* id, int level, unsigned int tag)
{
unsigned int t=tag;
@@ -185,7 +185,7 @@ debug_int_exception(debug_info_t* id, int level, unsigned int tag)
return debug_exception_common(id,level,&t,sizeof(unsigned int));
}
-extern inline debug_entry_t *
+static inline debug_entry_t *
debug_long_exception (debug_info_t* id, int level, unsigned long tag)
{
unsigned long t=tag;
@@ -194,7 +194,7 @@ debug_long_exception (debug_info_t* id, int level, unsigned long tag)
return debug_exception_common(id,level,&t,sizeof(unsigned long));
}
-extern inline debug_entry_t*
+static inline debug_entry_t*
debug_text_exception(debug_info_t* id, int level, const char* txt)
{
if ((!id) || (level > id->level) || (id->pages_per_area == 0))
diff --git a/include/asm-s390/ebcdic.h b/include/asm-s390/ebcdic.h
index 20e81e885821..4cbc336e4d60 100644
--- a/include/asm-s390/ebcdic.h
+++ b/include/asm-s390/ebcdic.h
@@ -21,7 +21,7 @@ extern __u8 _ebcasc[]; /* EBCDIC -> ASCII conversion table */
extern __u8 _ebc_tolower[]; /* EBCDIC -> lowercase */
extern __u8 _ebc_toupper[]; /* EBCDIC -> uppercase */
-extern __inline__ void
+static inline void
codepage_convert(const __u8 *codepage, volatile __u8 * addr, unsigned long nr)
{
if (nr-- <= 0)
diff --git a/include/asm-s390/elf.h b/include/asm-s390/elf.h
index 3b8bd46832a1..372d51cccd53 100644
--- a/include/asm-s390/elf.h
+++ b/include/asm-s390/elf.h
@@ -96,6 +96,7 @@
* ELF register definitions..
*/
+#include <linux/sched.h> /* for task_struct */
#include <asm/ptrace.h>
#include <asm/user.h>
#include <asm/system.h> /* for save_access_regs */
diff --git a/include/asm-s390/io.h b/include/asm-s390/io.h
index 8188fdc9884f..71f55eb2350a 100644
--- a/include/asm-s390/io.h
+++ b/include/asm-s390/io.h
@@ -24,7 +24,7 @@
* Change virtual addresses to physical addresses and vv.
* These are pretty trivial
*/
-extern inline unsigned long virt_to_phys(volatile void * address)
+static inline unsigned long virt_to_phys(volatile void * address)
{
unsigned long real_address;
__asm__ (
@@ -42,7 +42,7 @@ extern inline unsigned long virt_to_phys(volatile void * address)
return real_address;
}
-extern inline void * phys_to_virt(unsigned long address)
+static inline void * phys_to_virt(unsigned long address)
{
return __io_virt(address);
}
@@ -54,7 +54,7 @@ extern inline void * phys_to_virt(unsigned long address)
extern void * __ioremap(unsigned long offset, unsigned long size, unsigned long flags);
-extern inline void * ioremap (unsigned long offset, unsigned long size)
+static inline void * ioremap (unsigned long offset, unsigned long size)
{
return __ioremap(offset, size, 0);
}
@@ -64,7 +64,7 @@ extern inline void * ioremap (unsigned long offset, unsigned long size)
* it's useful if some control registers are in such an area and write combining
* or read caching is not desirable:
*/
-extern inline void * ioremap_nocache (unsigned long offset, unsigned long size)
+static inline void * ioremap_nocache (unsigned long offset, unsigned long size)
{
return __ioremap(offset, size, 0);
}
diff --git a/include/asm-s390/lowcore.h b/include/asm-s390/lowcore.h
index c6f51c9ce3ff..db0606c1abd4 100644
--- a/include/asm-s390/lowcore.h
+++ b/include/asm-s390/lowcore.h
@@ -346,7 +346,7 @@ struct _lowcore
#define S390_lowcore (*((struct _lowcore *) 0))
extern struct _lowcore *lowcore_ptr[];
-extern __inline__ void set_prefix(__u32 address)
+static inline void set_prefix(__u32 address)
{
__asm__ __volatile__ ("spx %0" : : "m" (address) : "memory" );
}
diff --git a/include/asm-s390/mmu_context.h b/include/asm-s390/mmu_context.h
index 3a3bb3f2dad5..bcf24a873874 100644
--- a/include/asm-s390/mmu_context.h
+++ b/include/asm-s390/mmu_context.h
@@ -44,7 +44,7 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
#define deactivate_mm(tsk,mm) do { } while (0)
-extern inline void activate_mm(struct mm_struct *prev,
+static inline void activate_mm(struct mm_struct *prev,
struct mm_struct *next)
{
switch_mm(prev, next, current);
diff --git a/include/asm-s390/pgtable.h b/include/asm-s390/pgtable.h
index df94f89038cc..859b5e969826 100644
--- a/include/asm-s390/pgtable.h
+++ b/include/asm-s390/pgtable.h
@@ -36,6 +36,7 @@
#include <linux/threads.h>
struct vm_area_struct; /* forward declaration (include/linux/mm.h) */
+struct mm_struct;
extern pgd_t swapper_pg_dir[] __attribute__ ((aligned (4096)));
extern void paging_init(void);
@@ -318,7 +319,7 @@ extern char empty_zero_page[PAGE_SIZE];
* within a page table are directly modified. Thus, the following
* hook is made available.
*/
-extern inline void set_pte(pte_t *pteptr, pte_t pteval)
+static inline void set_pte(pte_t *pteptr, pte_t pteval)
{
*pteptr = pteval;
}
@@ -329,63 +330,63 @@ extern inline void set_pte(pte_t *pteptr, pte_t pteval)
*/
#ifndef __s390x__
-extern inline int pgd_present(pgd_t pgd) { return 1; }
-extern inline int pgd_none(pgd_t pgd) { return 0; }
-extern inline int pgd_bad(pgd_t pgd) { return 0; }
+static inline int pgd_present(pgd_t pgd) { return 1; }
+static inline int pgd_none(pgd_t pgd) { return 0; }
+static inline int pgd_bad(pgd_t pgd) { return 0; }
-extern inline int pmd_present(pmd_t pmd) { return pmd_val(pmd) & _SEG_PRESENT; }
-extern inline int pmd_none(pmd_t pmd) { return pmd_val(pmd) & _PAGE_TABLE_INV; }
-extern inline int pmd_bad(pmd_t pmd)
+static inline int pmd_present(pmd_t pmd) { return pmd_val(pmd) & _SEG_PRESENT; }
+static inline int pmd_none(pmd_t pmd) { return pmd_val(pmd) & _PAGE_TABLE_INV; }
+static inline int pmd_bad(pmd_t pmd)
{
return (pmd_val(pmd) & (~PAGE_MASK & ~_PAGE_TABLE_INV)) != _PAGE_TABLE;
}
#else /* __s390x__ */
-extern inline int pgd_present(pgd_t pgd)
+static inline int pgd_present(pgd_t pgd)
{
return (pgd_val(pgd) & ~PAGE_MASK) == _PGD_ENTRY;
}
-extern inline int pgd_none(pgd_t pgd)
+static inline int pgd_none(pgd_t pgd)
{
return pgd_val(pgd) & _PGD_ENTRY_INV;
}
-extern inline int pgd_bad(pgd_t pgd)
+static inline int pgd_bad(pgd_t pgd)
{
return (pgd_val(pgd) & (~PAGE_MASK & ~_PGD_ENTRY_INV)) != _PGD_ENTRY;
}
-extern inline int pmd_present(pmd_t pmd)
+static inline int pmd_present(pmd_t pmd)
{
return (pmd_val(pmd) & ~PAGE_MASK) == _PMD_ENTRY;
}
-extern inline int pmd_none(pmd_t pmd)
+static inline int pmd_none(pmd_t pmd)
{
return pmd_val(pmd) & _PMD_ENTRY_INV;
}
-extern inline int pmd_bad(pmd_t pmd)
+static inline int pmd_bad(pmd_t pmd)
{
return (pmd_val(pmd) & (~PAGE_MASK & ~_PMD_ENTRY_INV)) != _PMD_ENTRY;
}
#endif /* __s390x__ */
-extern inline int pte_none(pte_t pte)
+static inline int pte_none(pte_t pte)
{
return (pte_val(pte) & _PAGE_INVALID_MASK) == _PAGE_INVALID_EMPTY;
}
-extern inline int pte_present(pte_t pte)
+static inline int pte_present(pte_t pte)
{
return !(pte_val(pte) & _PAGE_INVALID) ||
(pte_val(pte) & _PAGE_INVALID_MASK) == _PAGE_INVALID_NONE;
}
-extern inline int pte_file(pte_t pte)
+static inline int pte_file(pte_t pte)
{
return (pte_val(pte) & _PAGE_INVALID_MASK) == _PAGE_INVALID_FILE;
}
@@ -396,12 +397,12 @@ extern inline int pte_file(pte_t pte)
* query functions pte_write/pte_dirty/pte_young only work if
* pte_present() is true. Undefined behaviour if not..
*/
-extern inline int pte_write(pte_t pte)
+static inline int pte_write(pte_t pte)
{
return (pte_val(pte) & _PAGE_RO) == 0;
}
-extern inline int pte_dirty(pte_t pte)
+static inline int pte_dirty(pte_t pte)
{
/* A pte is neither clean nor dirty on s/390. The dirty bit
* is in the storage key. See page_test_and_clear_dirty for
@@ -410,7 +411,7 @@ extern inline int pte_dirty(pte_t pte)
return 0;
}
-extern inline int pte_young(pte_t pte)
+static inline int pte_young(pte_t pte)
{
/* A pte is neither young nor old on s/390. The young bit
* is in the storage key. See page_test_and_clear_young for
@@ -419,7 +420,7 @@ extern inline int pte_young(pte_t pte)
return 0;
}
-extern inline int pte_read(pte_t pte)
+static inline int pte_read(pte_t pte)
{
/* All pages are readable since we don't use the fetch
* protection bit in the storage key.
@@ -433,9 +434,9 @@ extern inline int pte_read(pte_t pte)
#ifndef __s390x__
-extern inline void pgd_clear(pgd_t * pgdp) { }
+static inline void pgd_clear(pgd_t * pgdp) { }
-extern inline void pmd_clear(pmd_t * pmdp)
+static inline void pmd_clear(pmd_t * pmdp)
{
pmd_val(pmdp[0]) = _PAGE_TABLE_INV;
pmd_val(pmdp[1]) = _PAGE_TABLE_INV;
@@ -445,12 +446,12 @@ extern inline void pmd_clear(pmd_t * pmdp)
#else /* __s390x__ */
-extern inline void pgd_clear(pgd_t * pgdp)
+static inline void pgd_clear(pgd_t * pgdp)
{
pgd_val(*pgdp) = _PGD_ENTRY_INV | _PGD_ENTRY;
}
-extern inline void pmd_clear(pmd_t * pmdp)
+static inline void pmd_clear(pmd_t * pmdp)
{
pmd_val(*pmdp) = _PMD_ENTRY_INV | _PMD_ENTRY;
pmd_val1(*pmdp) = _PMD_ENTRY_INV | _PMD_ENTRY;
@@ -458,7 +459,7 @@ extern inline void pmd_clear(pmd_t * pmdp)
#endif /* __s390x__ */
-extern inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
+static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
{
pte_val(*ptep) = _PAGE_INVALID_EMPTY;
}
@@ -467,14 +468,14 @@ extern inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *pt
* The following pte modification functions only work if
* pte_present() is true. Undefined behaviour if not..
*/
-extern inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
+static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
{
pte_val(pte) &= PAGE_MASK;
pte_val(pte) |= pgprot_val(newprot);
return pte;
}
-extern inline pte_t pte_wrprotect(pte_t pte)
+static inline pte_t pte_wrprotect(pte_t pte)
{
/* Do not clobber _PAGE_INVALID_NONE pages! */
if (!(pte_val(pte) & _PAGE_INVALID))
@@ -482,13 +483,13 @@ extern inline pte_t pte_wrprotect(pte_t pte)
return pte;
}
-extern inline pte_t pte_mkwrite(pte_t pte)
+static inline pte_t pte_mkwrite(pte_t pte)
{
pte_val(pte) &= ~_PAGE_RO;
return pte;
}
-extern inline pte_t pte_mkclean(pte_t pte)
+static inline pte_t pte_mkclean(pte_t pte)
{
/* The only user of pte_mkclean is the fork() code.
We must *not* clear the *physical* page dirty bit
@@ -497,7 +498,7 @@ extern inline pte_t pte_mkclean(pte_t pte)
return pte;
}
-extern inline pte_t pte_mkdirty(pte_t pte)
+static inline pte_t pte_mkdirty(pte_t pte)
{
/* We do not explicitly set the dirty bit because the
* sske instruction is slow. It is faster to let the
@@ -506,7 +507,7 @@ extern inline pte_t pte_mkdirty(pte_t pte)
return pte;
}
-extern inline pte_t pte_mkold(pte_t pte)
+static inline pte_t pte_mkold(pte_t pte)
{
/* S/390 doesn't keep its dirty/referenced bit in the pte.
* There is no point in clearing the real referenced bit.
@@ -514,7 +515,7 @@ extern inline pte_t pte_mkold(pte_t pte)
return pte;
}
-extern inline pte_t pte_mkyoung(pte_t pte)
+static inline pte_t pte_mkyoung(pte_t pte)
{
/* S/390 doesn't keep its dirty/referenced bit in the pte.
* There is no point in setting the real referenced bit.
@@ -694,7 +695,7 @@ static inline pte_t mk_pte_phys(unsigned long physpage, pgprot_t pgprot)
#ifndef __s390x__
/* Find an entry in the second-level page table.. */
-extern inline pmd_t * pmd_offset(pgd_t * dir, unsigned long address)
+static inline pmd_t * pmd_offset(pgd_t * dir, unsigned long address)
{
return (pmd_t *) dir;
}
@@ -757,7 +758,7 @@ extern inline pmd_t * pmd_offset(pgd_t * dir, unsigned long address)
#else
#define __SWP_OFFSET_MASK (~0UL >> 11)
#endif
-extern inline pte_t mk_swap_pte(unsigned long type, unsigned long offset)
+static inline pte_t mk_swap_pte(unsigned long type, unsigned long offset)
{
pte_t pte;
offset &= __SWP_OFFSET_MASK;
diff --git a/include/asm-s390/ptrace.h b/include/asm-s390/ptrace.h
index fc7c96edc697..a949cc077cc7 100644
--- a/include/asm-s390/ptrace.h
+++ b/include/asm-s390/ptrace.h
@@ -468,6 +468,8 @@ struct user_regs_struct
};
#ifdef __KERNEL__
+#define __ARCH_SYS_PTRACE 1
+
#define user_mode(regs) (((regs)->psw.mask & PSW_MASK_PSTATE) != 0)
#define instruction_pointer(regs) ((regs)->psw.addr & PSW_ADDR_INSN)
#define profile_pc(regs) instruction_pointer(regs)
diff --git a/include/asm-s390/rwsem.h b/include/asm-s390/rwsem.h
index 8c0cebbfc034..0422a085dd56 100644
--- a/include/asm-s390/rwsem.h
+++ b/include/asm-s390/rwsem.h
@@ -351,5 +351,10 @@ static inline long rwsem_atomic_update(long delta, struct rw_semaphore *sem)
return new;
}
+static inline int rwsem_is_locked(struct rw_semaphore *sem)
+{
+ return (sem->count != 0);
+}
+
#endif /* __KERNEL__ */
#endif /* _S390_RWSEM_H */
diff --git a/include/asm-s390/semaphore.h b/include/asm-s390/semaphore.h
index 873def6f363a..702cf436698c 100644
--- a/include/asm-s390/semaphore.h
+++ b/include/asm-s390/semaphore.h
@@ -29,9 +29,6 @@ struct semaphore {
#define __SEMAPHORE_INITIALIZER(name,count) \
{ ATOMIC_INIT(count), __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) }
-#define __MUTEX_INITIALIZER(name) \
- __SEMAPHORE_INITIALIZER(name,1)
-
#define __DECLARE_SEMAPHORE_GENERIC(name,count) \
struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
diff --git a/include/asm-s390/setup.h b/include/asm-s390/setup.h
index 0d51c484c2ea..348a88137445 100644
--- a/include/asm-s390/setup.h
+++ b/include/asm-s390/setup.h
@@ -8,11 +8,14 @@
#ifndef _ASM_S390_SETUP_H
#define _ASM_S390_SETUP_H
+#include <asm/types.h>
+
#define PARMAREA 0x10400
#define COMMAND_LINE_SIZE 896
#define RAMDISK_ORIGIN 0x800000
#define RAMDISK_SIZE 0x800000
#define MEMORY_CHUNKS 16 /* max 0x7fff */
+#define IPL_PARMBLOCK_ORIGIN 0x2000
#ifndef __ASSEMBLY__
@@ -64,6 +67,53 @@ extern unsigned int console_irq;
#define SET_CONSOLE_3215 do { console_mode = 2; } while (0)
#define SET_CONSOLE_3270 do { console_mode = 3; } while (0)
+struct ipl_list_header {
+ u32 length;
+ u8 reserved[3];
+ u8 version;
+} __attribute__((packed));
+
+struct ipl_block_fcp {
+ u32 length;
+ u8 pbt;
+ u8 reserved1[322-1];
+ u16 devno;
+ u8 reserved2[4];
+ u64 wwpn;
+ u64 lun;
+ u32 bootprog;
+ u8 reserved3[12];
+ u64 br_lba;
+ u32 scp_data_len;
+ u8 reserved4[260];
+ u8 scp_data[];
+} __attribute__((packed));
+
+struct ipl_parameter_block {
+ union {
+ u32 length;
+ struct ipl_list_header header;
+ } hdr;
+ struct ipl_block_fcp fcp;
+} __attribute__((packed));
+
+#define IPL_MAX_SUPPORTED_VERSION (0)
+
+#define IPL_TYPE_FCP (0)
+
+/*
+ * IPL validity flags and parameters as detected in head.S
+ */
+extern u32 ipl_parameter_flags;
+extern u16 ipl_devno;
+
+#define IPL_DEVNO_VALID (ipl_parameter_flags & 1)
+#define IPL_PARMBLOCK_VALID (ipl_parameter_flags & 2)
+
+#define IPL_PARMBLOCK_START ((struct ipl_parameter_block *) \
+ IPL_PARMBLOCK_ORIGIN)
+#define IPL_PARMBLOCK_SIZE (IPL_PARMBLOCK_START->hdr.length)
+
#else
#ifndef __s390x__
diff --git a/include/asm-s390/sigp.h b/include/asm-s390/sigp.h
index 3979bc3858e2..fc56458aff66 100644
--- a/include/asm-s390/sigp.h
+++ b/include/asm-s390/sigp.h
@@ -67,7 +67,7 @@ typedef enum
/*
* Signal processor
*/
-extern __inline__ sigp_ccode
+static inline sigp_ccode
signal_processor(__u16 cpu_addr, sigp_order_code order_code)
{
sigp_ccode ccode;
@@ -86,7 +86,7 @@ signal_processor(__u16 cpu_addr, sigp_order_code order_code)
/*
* Signal processor with parameter
*/
-extern __inline__ sigp_ccode
+static inline sigp_ccode
signal_processor_p(__u32 parameter, __u16 cpu_addr,
sigp_order_code order_code)
{
@@ -107,7 +107,7 @@ signal_processor_p(__u32 parameter, __u16 cpu_addr,
/*
* Signal processor with parameter and return status
*/
-extern __inline__ sigp_ccode
+static inline sigp_ccode
signal_processor_ps(__u32 *statusptr, __u32 parameter,
__u16 cpu_addr, sigp_order_code order_code)
{
diff --git a/include/asm-s390/smp.h b/include/asm-s390/smp.h
index dd50e57a928f..a2ae7628bbaa 100644
--- a/include/asm-s390/smp.h
+++ b/include/asm-s390/smp.h
@@ -52,7 +52,7 @@ extern int smp_call_function_on(void (*func) (void *info), void *info,
extern int smp_get_cpu(cpumask_t cpu_map);
extern void smp_put_cpu(int cpu);
-extern __inline__ __u16 hard_smp_processor_id(void)
+static inline __u16 hard_smp_processor_id(void)
{
__u16 cpu_address;
diff --git a/include/asm-s390/uaccess.h b/include/asm-s390/uaccess.h
index 38a5cf8ab9e3..10a619da4761 100644
--- a/include/asm-s390/uaccess.h
+++ b/include/asm-s390/uaccess.h
@@ -200,21 +200,37 @@ extern int __put_user_bad(void) __attribute__((noreturn));
#define __get_user(x, ptr) \
({ \
- __typeof__(*(ptr)) __x; \
int __gu_err; \
__chk_user_ptr(ptr); \
switch (sizeof(*(ptr))) { \
- case 1: \
- case 2: \
- case 4: \
- case 8: \
+ case 1: { \
+ unsigned char __x; \
+ __get_user_asm(__x, ptr, __gu_err); \
+ (x) = (__typeof__(*(ptr))) __x; \
+ break; \
+ }; \
+ case 2: { \
+ unsigned short __x; \
+ __get_user_asm(__x, ptr, __gu_err); \
+ (x) = (__typeof__(*(ptr))) __x; \
+ break; \
+ }; \
+ case 4: { \
+ unsigned int __x; \
+ __get_user_asm(__x, ptr, __gu_err); \
+ (x) = (__typeof__(*(ptr))) __x; \
+ break; \
+ }; \
+ case 8: { \
+ unsigned long long __x; \
__get_user_asm(__x, ptr, __gu_err); \
+ (x) = (__typeof__(*(ptr))) __x; \
break; \
+ }; \
default: \
__get_user_bad(); \
break; \
} \
- (x) = __x; \
__gu_err; \
})
diff --git a/include/asm-s390/unistd.h b/include/asm-s390/unistd.h
index 221e965da924..f97d92691f17 100644
--- a/include/asm-s390/unistd.h
+++ b/include/asm-s390/unistd.h
@@ -590,7 +590,6 @@ asmlinkage long sys_clone(struct pt_regs regs);
asmlinkage long sys_fork(struct pt_regs regs);
asmlinkage long sys_vfork(struct pt_regs regs);
asmlinkage long sys_pipe(unsigned long __user *fildes);
-asmlinkage long sys_ptrace(long request, long pid, long addr, long data);
struct sigaction;
asmlinkage long sys_rt_sigaction(int sig,
const struct sigaction __user *act,
diff --git a/include/asm-s390/vtoc.h b/include/asm-s390/vtoc.h
index a14e34e80b88..41d369f38b0e 100644
--- a/include/asm-s390/vtoc.h
+++ b/include/asm-s390/vtoc.h
@@ -1,372 +1,179 @@
-#ifndef __KERNEL__
-#include <string.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <errno.h>
-#include <ctype.h>
-#include <time.h>
-#include <fcntl.h>
-#include <unistd.h>
+/*
+ * include/asm-s390/vtoc.h
+ *
+ * This file contains volume label definitions for DASD devices.
+ *
+ * (C) Copyright IBM Corp. 2005
+ *
+ * Author(s): Volker Sameske <sameske@de.ibm.com>
+ *
+ */
+
+#ifndef _ASM_S390_VTOC_H
+#define _ASM_S390_VTOC_H
-#include <sys/stat.h>
-#include <sys/ioctl.h>
-
-#include <linux/fs.h>
#include <linux/types.h>
-#include <linux/hdreg.h>
-#include <asm/dasd.h>
-#endif
-
-
-#define LINE_LENGTH 80
-#define VTOC_START_CC 0x0
-#define VTOC_START_HH 0x1
-#define FIRST_USABLE_CYL 1
-#define FIRST_USABLE_TRK 2
-
-#define DASD_3380_TYPE 13148
-#define DASD_3390_TYPE 13200
-#define DASD_9345_TYPE 37701
-
-#define DASD_3380_VALUE 0xbb60
-#define DASD_3390_VALUE 0xe5a2
-#define DASD_9345_VALUE 0xbc98
-
-#define VOLSER_LENGTH 6
-#define BIG_DISK_SIZE 0x10000
-
-#define VTOC_ERROR "VTOC error:"
-
-typedef struct ttr
+struct vtoc_ttr
{
- __u16 tt;
- __u8 r;
-} __attribute__ ((packed)) ttr_t;
+ __u16 tt;
+ __u8 r;
+} __attribute__ ((packed));
-typedef struct cchhb
+struct vtoc_cchhb
{
- __u16 cc;
- __u16 hh;
- __u8 b;
-} __attribute__ ((packed)) cchhb_t;
+ __u16 cc;
+ __u16 hh;
+ __u8 b;
+} __attribute__ ((packed));
-typedef struct cchh
+struct vtoc_cchh
{
- __u16 cc;
- __u16 hh;
-} __attribute__ ((packed)) cchh_t;
+ __u16 cc;
+ __u16 hh;
+} __attribute__ ((packed));
-typedef struct labeldate
+struct vtoc_labeldate
{
- __u8 year;
- __u16 day;
-} __attribute__ ((packed)) labeldate_t;
+ __u8 year;
+ __u16 day;
+} __attribute__ ((packed));
-
-typedef struct volume_label
+struct vtoc_volume_label
{
- char volkey[4]; /* volume key = volume label */
- char vollbl[4]; /* volume label */
- char volid[6]; /* volume identifier */
- __u8 security; /* security byte */
- cchhb_t vtoc; /* VTOC address */
- char res1[5]; /* reserved */
- char cisize[4]; /* CI-size for FBA,... */
- /* ...blanks for CKD */
- char blkperci[4]; /* no of blocks per CI (FBA), blanks for CKD */
- char labperci[4]; /* no of labels per CI (FBA), blanks for CKD */
- char res2[4]; /* reserved */
- char lvtoc[14]; /* owner code for LVTOC */
- char res3[29]; /* reserved */
-} __attribute__ ((packed)) volume_label_t;
-
-
-typedef struct extent
+ char volkey[4]; /* volume key = volume label */
+ char vollbl[4]; /* volume label */
+ char volid[6]; /* volume identifier */
+ __u8 security; /* security byte */
+ struct vtoc_cchhb vtoc; /* VTOC address */
+ char res1[5]; /* reserved */
+ char cisize[4]; /* CI-size for FBA,... */
+ /* ...blanks for CKD */
+ char blkperci[4]; /* no of blocks per CI (FBA), blanks for CKD */
+ char labperci[4]; /* no of labels per CI (FBA), blanks for CKD */
+ char res2[4]; /* reserved */
+ char lvtoc[14]; /* owner code for LVTOC */
+ char res3[29]; /* reserved */
+} __attribute__ ((packed));
+
+struct vtoc_extent
{
- __u8 typeind; /* extent type indicator */
- __u8 seqno; /* extent sequence number */
- cchh_t llimit; /* starting point of this extent */
- cchh_t ulimit; /* ending point of this extent */
-} __attribute__ ((packed)) extent_t;
-
+ __u8 typeind; /* extent type indicator */
+ __u8 seqno; /* extent sequence number */
+ struct vtoc_cchh llimit; /* starting point of this extent */
+ struct vtoc_cchh ulimit; /* ending point of this extent */
+} __attribute__ ((packed));
-typedef struct dev_const
+struct vtoc_dev_const
{
- __u16 DS4DSCYL; /* number of logical cyls */
- __u16 DS4DSTRK; /* number of tracks in a logical cylinder */
- __u16 DS4DEVTK; /* device track length */
- __u8 DS4DEVI; /* non-last keyed record overhead */
- __u8 DS4DEVL; /* last keyed record overhead */
- __u8 DS4DEVK; /* non-keyed record overhead differential */
- __u8 DS4DEVFG; /* flag byte */
- __u16 DS4DEVTL; /* device tolerance */
- __u8 DS4DEVDT; /* number of DSCB's per track */
- __u8 DS4DEVDB; /* number of directory blocks per track */
-} __attribute__ ((packed)) dev_const_t;
-
-
-typedef struct format1_label
+ __u16 DS4DSCYL; /* number of logical cyls */
+ __u16 DS4DSTRK; /* number of tracks in a logical cylinder */
+ __u16 DS4DEVTK; /* device track length */
+ __u8 DS4DEVI; /* non-last keyed record overhead */
+ __u8 DS4DEVL; /* last keyed record overhead */
+ __u8 DS4DEVK; /* non-keyed record overhead differential */
+ __u8 DS4DEVFG; /* flag byte */
+ __u16 DS4DEVTL; /* device tolerance */
+ __u8 DS4DEVDT; /* number of DSCB's per track */
+ __u8 DS4DEVDB; /* number of directory blocks per track */
+} __attribute__ ((packed));
+
+struct vtoc_format1_label
{
- char DS1DSNAM[44]; /* data set name */
- __u8 DS1FMTID; /* format identifier */
- char DS1DSSN[6]; /* data set serial number */
- __u16 DS1VOLSQ; /* volume sequence number */
- labeldate_t DS1CREDT; /* creation date: ydd */
- labeldate_t DS1EXPDT; /* expiration date */
- __u8 DS1NOEPV; /* number of extents on volume */
- __u8 DS1NOBDB; /* no. of bytes used in last direction blk */
- __u8 DS1FLAG1; /* flag 1 */
- char DS1SYSCD[13]; /* system code */
- labeldate_t DS1REFD; /* date last referenced */
- __u8 DS1SMSFG; /* system managed storage indicators */
- __u8 DS1SCXTF; /* sec. space extension flag byte */
- __u16 DS1SCXTV; /* secondary space extension value */
- __u8 DS1DSRG1; /* data set organisation byte 1 */
- __u8 DS1DSRG2; /* data set organisation byte 2 */
- __u8 DS1RECFM; /* record format */
- __u8 DS1OPTCD; /* option code */
- __u16 DS1BLKL; /* block length */
- __u16 DS1LRECL; /* record length */
- __u8 DS1KEYL; /* key length */
- __u16 DS1RKP; /* relative key position */
- __u8 DS1DSIND; /* data set indicators */
- __u8 DS1SCAL1; /* secondary allocation flag byte */
- char DS1SCAL3[3]; /* secondary allocation quantity */
- ttr_t DS1LSTAR; /* last used track and block on track */
- __u16 DS1TRBAL; /* space remaining on last used track */
- __u16 res1; /* reserved */
- extent_t DS1EXT1; /* first extent description */
- extent_t DS1EXT2; /* second extent description */
- extent_t DS1EXT3; /* third extent description */
- cchhb_t DS1PTRDS; /* possible pointer to f2 or f3 DSCB */
-} __attribute__ ((packed)) format1_label_t;
-
-
-typedef struct format4_label
+ char DS1DSNAM[44]; /* data set name */
+ __u8 DS1FMTID; /* format identifier */
+ char DS1DSSN[6]; /* data set serial number */
+ __u16 DS1VOLSQ; /* volume sequence number */
+ struct vtoc_labeldate DS1CREDT; /* creation date: ydd */
+ struct vtoc_labeldate DS1EXPDT; /* expiration date */
+ __u8 DS1NOEPV; /* number of extents on volume */
+ __u8 DS1NOBDB; /* no. of bytes used in last direction blk */
+ __u8 DS1FLAG1; /* flag 1 */
+ char DS1SYSCD[13]; /* system code */
+ struct vtoc_labeldate DS1REFD; /* date last referenced */
+ __u8 DS1SMSFG; /* system managed storage indicators */
+ __u8 DS1SCXTF; /* sec. space extension flag byte */
+ __u16 DS1SCXTV; /* secondary space extension value */
+ __u8 DS1DSRG1; /* data set organisation byte 1 */
+ __u8 DS1DSRG2; /* data set organisation byte 2 */
+ __u8 DS1RECFM; /* record format */
+ __u8 DS1OPTCD; /* option code */
+ __u16 DS1BLKL; /* block length */
+ __u16 DS1LRECL; /* record length */
+ __u8 DS1KEYL; /* key length */
+ __u16 DS1RKP; /* relative key position */
+ __u8 DS1DSIND; /* data set indicators */
+ __u8 DS1SCAL1; /* secondary allocation flag byte */
+ char DS1SCAL3[3]; /* secondary allocation quantity */
+ struct vtoc_ttr DS1LSTAR; /* last used track and block on track */
+ __u16 DS1TRBAL; /* space remaining on last used track */
+ __u16 res1; /* reserved */
+ struct vtoc_extent DS1EXT1; /* first extent description */
+ struct vtoc_extent DS1EXT2; /* second extent description */
+ struct vtoc_extent DS1EXT3; /* third extent description */
+ struct vtoc_cchhb DS1PTRDS; /* possible pointer to f2 or f3 DSCB */
+} __attribute__ ((packed));
+
+struct vtoc_format4_label
{
- char DS4KEYCD[44]; /* key code for VTOC labels: 44 times 0x04 */
- __u8 DS4IDFMT; /* format identifier */
- cchhb_t DS4HPCHR; /* highest address of a format 1 DSCB */
- __u16 DS4DSREC; /* number of available DSCB's */
- cchh_t DS4HCCHH; /* CCHH of next available alternate track */
- __u16 DS4NOATK; /* number of remaining alternate tracks */
- __u8 DS4VTOCI; /* VTOC indicators */
- __u8 DS4NOEXT; /* number of extents in VTOC */
- __u8 DS4SMSFG; /* system managed storage indicators */
- __u8 DS4DEVAC; /* number of alternate cylinders.
- Subtract from first two bytes of
- DS4DEVSZ to get number of usable
- cylinders. can be zero. valid
- only if DS4DEVAV on. */
- dev_const_t DS4DEVCT; /* device constants */
- char DS4AMTIM[8]; /* VSAM time stamp */
- char DS4AMCAT[3]; /* VSAM catalog indicator */
- char DS4R2TIM[8]; /* VSAM volume/catalog match time stamp */
- char res1[5]; /* reserved */
- char DS4F6PTR[5]; /* pointer to first format 6 DSCB */
- extent_t DS4VTOCE; /* VTOC extent description */
- char res2[10]; /* reserved */
- __u8 DS4EFLVL; /* extended free-space management level */
- cchhb_t DS4EFPTR; /* pointer to extended free-space info */
- char res3[9]; /* reserved */
-} __attribute__ ((packed)) format4_label_t;
-
-
-typedef struct ds5ext
+ char DS4KEYCD[44]; /* key code for VTOC labels: 44 times 0x04 */
+ __u8 DS4IDFMT; /* format identifier */
+ struct vtoc_cchhb DS4HPCHR; /* highest address of a format 1 DSCB */
+ __u16 DS4DSREC; /* number of available DSCB's */
+ struct vtoc_cchh DS4HCCHH; /* CCHH of next available alternate track */
+ __u16 DS4NOATK; /* number of remaining alternate tracks */
+ __u8 DS4VTOCI; /* VTOC indicators */
+ __u8 DS4NOEXT; /* number of extents in VTOC */
+ __u8 DS4SMSFG; /* system managed storage indicators */
+ __u8 DS4DEVAC; /* number of alternate cylinders.
+ * Subtract from first two bytes of
+ * DS4DEVSZ to get number of usable
+ * cylinders. can be zero. valid
+ * only if DS4DEVAV on. */
+ struct vtoc_dev_const DS4DEVCT; /* device constants */
+ char DS4AMTIM[8]; /* VSAM time stamp */
+ char DS4AMCAT[3]; /* VSAM catalog indicator */
+ char DS4R2TIM[8]; /* VSAM volume/catalog match time stamp */
+ char res1[5]; /* reserved */
+ char DS4F6PTR[5]; /* pointer to first format 6 DSCB */
+ struct vtoc_extent DS4VTOCE; /* VTOC extent description */
+ char res2[10]; /* reserved */
+ __u8 DS4EFLVL; /* extended free-space management level */
+ struct vtoc_cchhb DS4EFPTR; /* pointer to extended free-space info */
+ char res3[9]; /* reserved */
+} __attribute__ ((packed));
+
+struct vtoc_ds5ext
{
- __u16 t; /* RTA of the first track of free extent */
- __u16 fc; /* number of whole cylinders in free ext. */
- __u8 ft; /* number of remaining free tracks */
-} __attribute__ ((packed)) ds5ext_t;
-
+ __u16 t; /* RTA of the first track of free extent */
+ __u16 fc; /* number of whole cylinders in free ext. */
+ __u8 ft; /* number of remaining free tracks */
+} __attribute__ ((packed));
-typedef struct format5_label
+struct vtoc_format5_label
{
- char DS5KEYID[4]; /* key identifier */
- ds5ext_t DS5AVEXT; /* first available (free-space) extent. */
- ds5ext_t DS5EXTAV[7]; /* seven available extents */
- __u8 DS5FMTID; /* format identifier */
- ds5ext_t DS5MAVET[18]; /* eighteen available extents */
- cchhb_t DS5PTRDS; /* pointer to next format5 DSCB */
-} __attribute__ ((packed)) format5_label_t;
-
-
-typedef struct ds7ext
+ char DS5KEYID[4]; /* key identifier */
+ struct vtoc_ds5ext DS5AVEXT; /* first available (free-space) extent. */
+ struct vtoc_ds5ext DS5EXTAV[7]; /* seven available extents */
+ __u8 DS5FMTID; /* format identifier */
+ struct vtoc_ds5ext DS5MAVET[18]; /* eighteen available extents */
+ struct vtoc_cchhb DS5PTRDS; /* pointer to next format5 DSCB */
+} __attribute__ ((packed));
+
+struct vtoc_ds7ext
{
- __u32 a; /* starting RTA value */
- __u32 b; /* ending RTA value + 1 */
-} __attribute__ ((packed)) ds7ext_t;
+ __u32 a; /* starting RTA value */
+ __u32 b; /* ending RTA value + 1 */
+} __attribute__ ((packed));
-
-typedef struct format7_label
+struct vtoc_format7_label
{
- char DS7KEYID[4]; /* key identifier */
- ds7ext_t DS7EXTNT[5]; /* space for 5 extent descriptions */
- __u8 DS7FMTID; /* format identifier */
- ds7ext_t DS7ADEXT[11]; /* space for 11 extent descriptions */
- char res1[2]; /* reserved */
- cchhb_t DS7PTRDS; /* pointer to next FMT7 DSCB */
-} __attribute__ ((packed)) format7_label_t;
-
-
-char * vtoc_ebcdic_enc (
- unsigned char source[LINE_LENGTH],
- unsigned char target[LINE_LENGTH],
- int l);
-char * vtoc_ebcdic_dec (
- unsigned char source[LINE_LENGTH],
- unsigned char target[LINE_LENGTH],
- int l);
-void vtoc_set_extent (
- extent_t * ext,
- __u8 typeind,
- __u8 seqno,
- cchh_t * lower,
- cchh_t * upper);
-void vtoc_set_cchh (
- cchh_t * addr,
- __u16 cc,
- __u16 hh);
-void vtoc_set_cchhb (
- cchhb_t * addr,
- __u16 cc,
- __u16 hh,
- __u8 b);
-void vtoc_set_date (
- labeldate_t * d,
- __u8 year,
- __u16 day);
-
-void vtoc_volume_label_init (
- volume_label_t *vlabel);
-
-int vtoc_read_volume_label (
- char * device,
- unsigned long vlabel_start,
- volume_label_t * vlabel);
-
-int vtoc_write_volume_label (
- char *device,
- unsigned long vlabel_start,
- volume_label_t *vlabel);
-
-void vtoc_volume_label_set_volser (
- volume_label_t *vlabel,
- char *volser);
-
-char *vtoc_volume_label_get_volser (
- volume_label_t *vlabel,
- char *volser);
-
-void vtoc_volume_label_set_key (
- volume_label_t *vlabel,
- char *key);
-
-void vtoc_volume_label_set_label (
- volume_label_t *vlabel,
- char *lbl);
-
-char *vtoc_volume_label_get_label (
- volume_label_t *vlabel,
- char *lbl);
-
-void vtoc_read_label (
- char *device,
- unsigned long position,
- format1_label_t *f1,
- format4_label_t *f4,
- format5_label_t *f5,
- format7_label_t *f7);
-
-void vtoc_write_label (
- char *device,
- unsigned long position,
- format1_label_t *f1,
- format4_label_t *f4,
- format5_label_t *f5,
- format7_label_t *f7);
-
-
-void vtoc_init_format1_label (
- char *volid,
- unsigned int blksize,
- extent_t *part_extent,
- format1_label_t *f1);
-
-
-void vtoc_init_format4_label (
- format4_label_t *f4lbl,
- unsigned int usable_partitions,
- unsigned int cylinders,
- unsigned int tracks,
- unsigned int blocks,
- unsigned int blksize,
- __u16 dev_type);
-
-void vtoc_update_format4_label (
- format4_label_t *f4,
- cchhb_t *highest_f1,
- __u16 unused_update);
-
-
-void vtoc_init_format5_label (
- format5_label_t *f5);
-
-void vtoc_update_format5_label_add (
- format5_label_t *f5,
- int verbose,
- int cyl,
- int trk,
- __u16 a,
- __u16 b,
- __u8 c);
-
-void vtoc_update_format5_label_del (
- format5_label_t *f5,
- int verbose,
- int cyl,
- int trk,
- __u16 a,
- __u16 b,
- __u8 c);
-
-
-void vtoc_init_format7_label (
- format7_label_t *f7);
-
-void vtoc_update_format7_label_add (
- format7_label_t *f7,
- int verbose,
- __u32 a,
- __u32 b);
-
-void vtoc_update_format7_label_del (
- format7_label_t *f7,
- int verbose,
- __u32 a,
- __u32 b);
-
-
-void vtoc_set_freespace(
- format4_label_t *f4,
- format5_label_t *f5,
- format7_label_t *f7,
- char ch,
- int verbose,
- __u32 start,
- __u32 stop,
- int cyl,
- int trk);
-
-
-
-
-
-
-
-
-
-
-
-
+ char DS7KEYID[4]; /* key identifier */
+ struct vtoc_ds7ext DS7EXTNT[5]; /* space for 5 extent descriptions */
+ __u8 DS7FMTID; /* format identifier */
+ struct vtoc_ds7ext DS7ADEXT[11]; /* space for 11 extent descriptions */
+ char res1[2]; /* reserved */
+ struct vtoc_cchhb DS7PTRDS; /* pointer to next FMT7 DSCB */
+} __attribute__ ((packed));
+
+#endif /* _ASM_S390_VTOC_H */
diff --git a/include/asm-sh/dma-mapping.h b/include/asm-sh/dma-mapping.h
index 80d164c1529e..d3fa5c2b889d 100644
--- a/include/asm-sh/dma-mapping.h
+++ b/include/asm-sh/dma-mapping.h
@@ -9,7 +9,7 @@
extern struct bus_type pci_bus_type;
/* arch/sh/mm/consistent.c */
-extern void *consistent_alloc(int gfp, size_t size, dma_addr_t *handle);
+extern void *consistent_alloc(gfp_t gfp, size_t size, dma_addr_t *handle);
extern void consistent_free(void *vaddr, size_t size);
extern void consistent_sync(void *vaddr, size_t size, int direction);
@@ -26,7 +26,7 @@ static inline int dma_set_mask(struct device *dev, u64 mask)
}
static inline void *dma_alloc_coherent(struct device *dev, size_t size,
- dma_addr_t *dma_handle, int flag)
+ dma_addr_t *dma_handle, gfp_t flag)
{
if (sh_mv.mv_consistent_alloc) {
void *ret;
diff --git a/include/asm-sh/elf.h b/include/asm-sh/elf.h
index 8fe00a1981ce..1b63dfeea4f2 100644
--- a/include/asm-sh/elf.h
+++ b/include/asm-sh/elf.h
@@ -111,6 +111,7 @@ typedef struct user_fpu_struct elf_fpregset_t;
#ifdef __KERNEL__
#define SET_PERSONALITY(ex, ibcs2) set_personality(PER_LINUX_32BIT)
+struct task_struct;
extern int dump_task_regs (struct task_struct *, elf_gregset_t *);
extern int dump_task_fpu (struct task_struct *, elf_fpregset_t *);
diff --git a/include/asm-sh/ide.h b/include/asm-sh/ide.h
index f42cf3977a57..711dad4cb48b 100644
--- a/include/asm-sh/ide.h
+++ b/include/asm-sh/ide.h
@@ -16,10 +16,6 @@
#include <linux/config.h>
-#ifndef MAX_HWIFS
-#define MAX_HWIFS CONFIG_IDE_MAX_HWIFS
-#endif
-
#define ide_default_io_ctl(base) (0)
#include <asm-generic/ide_iops.h>
diff --git a/include/asm-sh/machvec.h b/include/asm-sh/machvec.h
index 5771f4baa478..3f18aa180516 100644
--- a/include/asm-sh/machvec.h
+++ b/include/asm-sh/machvec.h
@@ -64,7 +64,7 @@ struct sh_machine_vector
void (*mv_heartbeat)(void);
- void *(*mv_consistent_alloc)(struct device *, size_t, dma_addr_t *, int);
+ void *(*mv_consistent_alloc)(struct device *, size_t, dma_addr_t *, gfp_t);
int (*mv_consistent_free)(struct device *, size_t, void *, dma_addr_t);
};
diff --git a/include/asm-sh/mmzone.h b/include/asm-sh/mmzone.h
deleted file mode 100644
index 0e7406601fdf..000000000000
--- a/include/asm-sh/mmzone.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * linux/include/asm-sh/mmzone.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 __ASM_SH_MMZONE_H
-#define __ASM_SH_MMZONE_H
-
-#include <linux/config.h>
-
-#ifdef CONFIG_DISCONTIGMEM
-
-/* Currently, just for HP690 */
-#define PHYSADDR_TO_NID(phys) ((((phys) - __MEMORY_START) >= 0x01000000)?1:0)
-
-extern pg_data_t discontig_page_data[MAX_NUMNODES];
-extern bootmem_data_t discontig_node_bdata[MAX_NUMNODES];
-
-/*
- * Following are macros that each numa implmentation must define.
- */
-
-/*
- * Given a kernel address, find the home node of the underlying memory.
- */
-#define KVADDR_TO_NID(kaddr) PHYSADDR_TO_NID(__pa(kaddr))
-
-/*
- * Return a pointer to the node data for node n.
- */
-#define NODE_DATA(nid) (&discontig_page_data[nid])
-
-/*
- * NODE_MEM_MAP gives the kaddr for the mem_map of the node.
- */
-#define NODE_MEM_MAP(nid) (NODE_DATA(nid)->node_mem_map)
-
-#define phys_to_page(phys) \
-({ unsigned int node = PHYSADDR_TO_NID(phys); \
- NODE_MEM_MAP(node) \
- + (((phys) - NODE_DATA(node)->node_start_paddr) >> PAGE_SHIFT); })
-
-static inline int is_valid_page(struct page *page)
-{
- unsigned int i;
-
- for (i = 0; i < MAX_NUMNODES; i++) {
- if (page >= NODE_MEM_MAP(i) &&
- page < NODE_MEM_MAP(i) + NODE_DATA(i)->node_size)
- return 1;
- }
- return 0;
-}
-
-#define VALID_PAGE(page) is_valid_page(page)
-#define page_to_phys(page) PHYSADDR(page_address(page))
-
-#endif /* CONFIG_DISCONTIGMEM */
-#endif
diff --git a/include/asm-sh/page.h b/include/asm-sh/page.h
index 324e6cc5ecf7..972c3f655b2a 100644
--- a/include/asm-sh/page.h
+++ b/include/asm-sh/page.h
@@ -93,11 +93,6 @@ typedef struct { unsigned long pgprot; } pgprot_t;
#define __MEMORY_START CONFIG_MEMORY_START
#define __MEMORY_SIZE CONFIG_MEMORY_SIZE
-#ifdef CONFIG_DISCONTIGMEM
-/* Just for HP690, for now.. */
-#define __MEMORY_START_2ND (__MEMORY_START+0x02000000)
-#define __MEMORY_SIZE_2ND 0x001000000 /* 16MB */
-#endif
#define PAGE_OFFSET (0x80000000UL)
#define __pa(x) ((unsigned long)(x)-PAGE_OFFSET)
@@ -105,10 +100,8 @@ typedef struct { unsigned long pgprot; } pgprot_t;
#define MAP_NR(addr) (((unsigned long)(addr)-PAGE_OFFSET) >> PAGE_SHIFT)
-#ifndef CONFIG_DISCONTIGMEM
#define phys_to_page(phys) (mem_map + (((phys)-__MEMORY_START) >> PAGE_SHIFT))
#define page_to_phys(page) (((page - mem_map) << PAGE_SHIFT) + __MEMORY_START)
-#endif
/* PFN start number, because of __MEMORY_START */
#define PFN_START (__MEMORY_START >> PAGE_SHIFT)
diff --git a/include/asm-sh/pgtable.h b/include/asm-sh/pgtable.h
index 0f4bcaae61bd..bb0efb31a8cb 100644
--- a/include/asm-sh/pgtable.h
+++ b/include/asm-sh/pgtable.h
@@ -196,7 +196,9 @@ static inline pte_t pte_mkexec(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) | _
static inline pte_t pte_mkdirty(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) | _PAGE_DIRTY)); return pte; }
static inline pte_t pte_mkyoung(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) | _PAGE_ACCESSED)); return pte; }
static inline pte_t pte_mkwrite(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) | _PAGE_RW)); return pte; }
+#ifdef CONFIG_HUGETLB_PAGE
static inline pte_t pte_mkhuge(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) | _PAGE_SZHUGE)); return pte; }
+#endif
/*
* Macro and implementation to make a page protection as uncachable.
@@ -224,8 +226,6 @@ static inline pgprot_t pgprot_noncached(pgprot_t _prot)
static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
{ set_pte(&pte, __pte((pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot))); return pte; }
-#define page_pte(page) page_pte_prot(page, __pgprot(0))
-
#define pmd_page_kernel(pmd) \
((unsigned long) __va(pmd_val(pmd) & PAGE_MASK))
@@ -284,6 +284,8 @@ typedef pte_t *pte_addr_t;
#define GET_IOSPACE(pfn) 0
#define GET_PFN(pfn) (pfn)
+struct mm_struct;
+
/*
* No page table caches to initialise
*/
diff --git a/include/asm-sh/rwsem.h b/include/asm-sh/rwsem.h
index 1be4337f5259..0262d3d1e5e0 100644
--- a/include/asm-sh/rwsem.h
+++ b/include/asm-sh/rwsem.h
@@ -166,5 +166,10 @@ static inline int rwsem_atomic_update(int delta, struct rw_semaphore *sem)
return atomic_add_return(delta, (atomic_t *)(&sem->count));
}
+static inline int rwsem_is_locked(struct rw_semaphore *sem)
+{
+ return (sem->count != 0);
+}
+
#endif /* __KERNEL__ */
#endif /* _ASM_SH_RWSEM_H */
diff --git a/include/asm-sh/semaphore.h b/include/asm-sh/semaphore.h
index b923a77a8a7e..489f7847c5d9 100644
--- a/include/asm-sh/semaphore.h
+++ b/include/asm-sh/semaphore.h
@@ -33,9 +33,6 @@ struct semaphore {
.wait = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \
}
-#define __MUTEX_INITIALIZER(name) \
- __SEMAPHORE_INITIALIZER(name,1)
-
#define __DECLARE_SEMAPHORE_GENERIC(name,count) \
struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
diff --git a/include/asm-sh/unistd.h b/include/asm-sh/unistd.h
index ea89e8f223ea..f2c8e14d1fd9 100644
--- a/include/asm-sh/unistd.h
+++ b/include/asm-sh/unistd.h
@@ -503,7 +503,6 @@ asmlinkage int sys_vfork(unsigned long r4, unsigned long r5,
asmlinkage int sys_pipe(unsigned long r4, unsigned long r5,
unsigned long r6, unsigned long r7,
struct pt_regs regs);
-asmlinkage int sys_ptrace(long request, long pid, long addr, long data);
asmlinkage ssize_t sys_pread_wrapper(unsigned int fd, char *buf,
size_t count, long dummy, loff_t pos);
asmlinkage ssize_t sys_pwrite_wrapper(unsigned int fd, const char *buf,
diff --git a/include/asm-sh64/dma-mapping.h b/include/asm-sh64/dma-mapping.h
index b8d26fe677f4..cc9a2e86f5b4 100644
--- a/include/asm-sh64/dma-mapping.h
+++ b/include/asm-sh64/dma-mapping.h
@@ -25,7 +25,7 @@ static inline int dma_set_mask(struct device *dev, u64 mask)
}
static inline void *dma_alloc_coherent(struct device *dev, size_t size,
- dma_addr_t *dma_handle, int flag)
+ dma_addr_t *dma_handle, gfp_t flag)
{
return consistent_alloc(NULL, size, dma_handle);
}
diff --git a/include/asm-sh64/ide.h b/include/asm-sh64/ide.h
index 6fd514daa1ba..852f50afe39c 100644
--- a/include/asm-sh64/ide.h
+++ b/include/asm-sh64/ide.h
@@ -17,10 +17,6 @@
#include <linux/config.h>
-#ifndef MAX_HWIFS
-#define MAX_HWIFS CONFIG_IDE_MAX_HWIFS
-#endif
-
/* Without this, the initialisation of PCI IDE cards end up calling
* ide_init_hwif_ports, which won't work. */
#ifdef CONFIG_BLK_DEV_IDEPCI
diff --git a/include/asm-sh64/pgtable.h b/include/asm-sh64/pgtable.h
index 51db4307bfaf..a1906a772df9 100644
--- a/include/asm-sh64/pgtable.h
+++ b/include/asm-sh64/pgtable.h
@@ -24,6 +24,8 @@
#include <linux/threads.h>
#include <linux/config.h>
+struct vm_area_struct;
+
extern void paging_init(void);
/* We provide our own get_unmapped_area to avoid cache synonym issue */
@@ -457,9 +459,6 @@ extern inline pte_t pte_mkhuge(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) | _
extern inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
{ set_pte(&pte, __pte((pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot))); return pte; }
-#define page_pte_prot(page, prot) mk_pte(page, prot)
-#define page_pte(page) page_pte_prot(page, __pgprot(0))
-
typedef pte_t *pte_addr_t;
#define pgtable_cache_init() do { } while (0)
diff --git a/include/asm-sh64/semaphore.h b/include/asm-sh64/semaphore.h
index fce22bb9a546..469526459149 100644
--- a/include/asm-sh64/semaphore.h
+++ b/include/asm-sh64/semaphore.h
@@ -40,9 +40,6 @@ struct semaphore {
.wait = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \
}
-#define __MUTEX_INITIALIZER(name) \
- __SEMAPHORE_INITIALIZER(name,1)
-
#define __DECLARE_SEMAPHORE_GENERIC(name,count) \
struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
diff --git a/include/asm-sparc/audioio.h b/include/asm-sparc/audioio.h
deleted file mode 100644
index cf16173f521b..000000000000
--- a/include/asm-sparc/audioio.h
+++ /dev/null
@@ -1,234 +0,0 @@
-/*
- * include/asm-sparc/audioio.h
- *
- * Sparc Audio Midlayer
- * Copyright (C) 1996 Thomas K. Dyas (tdyas@noc.rutgers.edu)
- */
-
-#ifndef _AUDIOIO_H_
-#define _AUDIOIO_H_
-
-/*
- * SunOS/Solaris /dev/audio interface
- */
-
-#if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2)
-#include <linux/types.h>
-#include <linux/time.h>
-#include <linux/ioctl.h>
-#endif
-
-/*
- * This structure contains state information for audio device IO streams.
- */
-typedef struct audio_prinfo {
- /*
- * The following values describe the audio data encoding.
- */
- unsigned int sample_rate; /* samples per second */
- unsigned int channels; /* number of interleaved channels */
- unsigned int precision; /* bit-width of each sample */
- unsigned int encoding; /* data encoding method */
-
- /*
- * The following values control audio device configuration
- */
- unsigned int gain; /* gain level: 0 - 255 */
- unsigned int port; /* selected I/O port (see below) */
- unsigned int avail_ports; /* available I/O ports (see below) */
- unsigned int _xxx[2]; /* Reserved for future use */
-
- unsigned int buffer_size; /* I/O buffer size */
-
- /*
- * The following values describe driver state
- */
- unsigned int samples; /* number of samples converted */
- unsigned int eof; /* End Of File counter (play only) */
-
- unsigned char pause; /* non-zero for pause, zero to resume */
- unsigned char error; /* non-zero if overflow/underflow */
- unsigned char waiting; /* non-zero if a process wants access */
- unsigned char balance; /* stereo channel balance */
-
- unsigned short minordev;
-
- /*
- * The following values are read-only state flags
- */
- unsigned char open; /* non-zero if open access permitted */
- unsigned char active; /* non-zero if I/O is active */
-} audio_prinfo_t;
-
-
-/*
- * This structure describes the current state of the audio device.
- */
-typedef struct audio_info {
- /*
- * Per-stream information
- */
- audio_prinfo_t play; /* output status information */
- audio_prinfo_t record; /* input status information */
-
- /*
- * Per-unit/channel information
- */
- unsigned int monitor_gain; /* input to output mix: 0 - 255 */
- unsigned char output_muted; /* non-zero if output is muted */
- unsigned char _xxx[3]; /* Reserved for future use */
- unsigned int _yyy[3]; /* Reserved for future use */
-} audio_info_t;
-
-
-/*
- * Audio encoding types
- */
-#define AUDIO_ENCODING_NONE (0) /* no encoding assigned */
-#define AUDIO_ENCODING_ULAW (1) /* u-law encoding */
-#define AUDIO_ENCODING_ALAW (2) /* A-law encoding */
-#define AUDIO_ENCODING_LINEAR (3) /* Linear PCM encoding */
-#define AUDIO_ENCODING_FLOAT (4) /* IEEE float (-1. <-> +1.) */
-#define AUDIO_ENCODING_DVI (104) /* DVI ADPCM */
-#define AUDIO_ENCODING_LINEAR8 (105) /* 8 bit UNSIGNED */
-#define AUDIO_ENCODING_LINEARLE (106) /* Linear PCM LE encoding */
-
-/*
- * These ranges apply to record, play, and monitor gain values
- */
-#define AUDIO_MIN_GAIN (0) /* minimum gain value */
-#define AUDIO_MAX_GAIN (255) /* maximum gain value */
-
-/*
- * These values apply to the balance field to adjust channel gain values
- */
-#define AUDIO_LEFT_BALANCE (0) /* left channel only */
-#define AUDIO_MID_BALANCE (32) /* equal left/right channel */
-#define AUDIO_RIGHT_BALANCE (64) /* right channel only */
-#define AUDIO_BALANCE_SHIFT (3)
-
-/*
- * Generic minimum/maximum limits for number of channels, both modes
- */
-#define AUDIO_MIN_PLAY_CHANNELS (1)
-#define AUDIO_MAX_PLAY_CHANNELS (4)
-#define AUDIO_MIN_REC_CHANNELS (1)
-#define AUDIO_MAX_REC_CHANNELS (4)
-
-/*
- * Generic minimum/maximum limits for sample precision
- */
-#define AUDIO_MIN_PLAY_PRECISION (8)
-#define AUDIO_MAX_PLAY_PRECISION (32)
-#define AUDIO_MIN_REC_PRECISION (8)
-#define AUDIO_MAX_REC_PRECISION (32)
-
-/*
- * Define some convenient names for typical audio ports
- */
-/*
- * output ports (several may be enabled simultaneously)
- */
-#define AUDIO_SPEAKER 0x01 /* output to built-in speaker */
-#define AUDIO_HEADPHONE 0x02 /* output to headphone jack */
-#define AUDIO_LINE_OUT 0x04 /* output to line out */
-
-/*
- * input ports (usually only one at a time)
- */
-#define AUDIO_MICROPHONE 0x01 /* input from microphone */
-#define AUDIO_LINE_IN 0x02 /* input from line in */
-#define AUDIO_CD 0x04 /* input from on-board CD inputs */
-#define AUDIO_INTERNAL_CD_IN AUDIO_CD /* input from internal CDROM */
-#define AUDIO_ANALOG_LOOPBACK 0x40 /* input from output */
-
-
-/*
- * This macro initializes an audio_info structure to 'harmless' values.
- * Note that (~0) might not be a harmless value for a flag that was
- * a signed int.
- */
-#define AUDIO_INITINFO(i) { \
- unsigned int *__x__; \
- for (__x__ = (unsigned int *)(i); \
- (char *) __x__ < (((char *)(i)) + sizeof (audio_info_t)); \
- *__x__++ = ~0); \
-}
-
-/*
- * These allow testing for what the user wants to set
- */
-#define AUD_INITVALUE (~0)
-#define Modify(X) ((unsigned int)(X) != AUD_INITVALUE)
-#define Modifys(X) ((X) != (unsigned short)AUD_INITVALUE)
-#define Modifyc(X) ((X) != (unsigned char)AUD_INITVALUE)
-
-/*
- * Parameter for the AUDIO_GETDEV ioctl to determine current
- * audio devices.
- */
-#define MAX_AUDIO_DEV_LEN (16)
-typedef struct audio_device {
- char name[MAX_AUDIO_DEV_LEN];
- char version[MAX_AUDIO_DEV_LEN];
- char config[MAX_AUDIO_DEV_LEN];
-} audio_device_t;
-
-
-/*
- * Ioctl calls for the audio device.
- */
-
-/*
- * AUDIO_GETINFO retrieves the current state of the audio device.
- *
- * AUDIO_SETINFO copies all fields of the audio_info structure whose
- * values are not set to the initialized value (-1) to the device state.
- * It performs an implicit AUDIO_GETINFO to return the new state of the
- * device. Note that the record.samples and play.samples fields are set
- * to the last value before the AUDIO_SETINFO took effect. This allows
- * an application to reset the counters while atomically retrieving the
- * last value.
- *
- * AUDIO_DRAIN suspends the calling process until the write buffers are
- * empty.
- *
- * AUDIO_GETDEV returns a structure of type audio_device_t which contains
- * three strings. The string "name" is a short identifying string (for
- * example, the SBus Fcode name string), the string "version" identifies
- * the current version of the device, and the "config" string identifies
- * the specific configuration of the audio stream. All fields are
- * device-dependent -- see the device specific manual pages for details.
- *
- * AUDIO_GETDEV_SUNOS returns a number which is an audio device defined
- * herein (making it not too portable)
- *
- * AUDIO_FLUSH stops all playback and recording, clears all queued buffers,
- * resets error counters, and restarts recording and playback as appropriate
- * for the current sampling mode.
- */
-#define AUDIO_GETINFO _IOR('A', 1, audio_info_t)
-#define AUDIO_SETINFO _IOWR('A', 2, audio_info_t)
-#define AUDIO_DRAIN _IO('A', 3)
-#define AUDIO_GETDEV _IOR('A', 4, audio_device_t)
-#define AUDIO_GETDEV_SUNOS _IOR('A', 4, int)
-#define AUDIO_FLUSH _IO('A', 5)
-
-/* Define possible audio hardware configurations for
- * old SunOS-style AUDIO_GETDEV ioctl */
-#define AUDIO_DEV_UNKNOWN (0) /* not defined */
-#define AUDIO_DEV_AMD (1) /* audioamd device */
-#define AUDIO_DEV_SPEAKERBOX (2) /* dbri device with speakerbox */
-#define AUDIO_DEV_CODEC (3) /* dbri device (internal speaker) */
-#define AUDIO_DEV_CS4231 (5) /* cs4231 device */
-
-/*
- * The following ioctl sets the audio device into an internal loopback mode,
- * if the hardware supports this. The argument is TRUE to set loopback,
- * FALSE to reset to normal operation. If the hardware does not support
- * internal loopback, the ioctl should fail with EINVAL.
- * Causes ADC data to be digitally mixed in and sent to the DAC.
- */
-#define AUDIO_DIAG_LOOPBACK _IOW('A', 101, int)
-
-#endif /* _AUDIOIO_H_ */
diff --git a/include/asm-sparc/dma-mapping.h b/include/asm-sparc/dma-mapping.h
index 2dc5bb8effa6..d7c3b0f0a901 100644
--- a/include/asm-sparc/dma-mapping.h
+++ b/include/asm-sparc/dma-mapping.h
@@ -8,7 +8,7 @@
#else
static inline void *dma_alloc_coherent(struct device *dev, size_t size,
- dma_addr_t *dma_handle, int flag)
+ dma_addr_t *dma_handle, gfp_t flag)
{
BUG();
return NULL;
diff --git a/include/asm-sparc/floppy.h b/include/asm-sparc/floppy.h
index caf926116506..7a941b800b6b 100644
--- a/include/asm-sparc/floppy.h
+++ b/include/asm-sparc/floppy.h
@@ -17,10 +17,8 @@
/* We don't need no stinkin' I/O port allocation crap. */
#undef release_region
-#undef check_region
#undef request_region
#define release_region(X, Y) do { } while(0)
-#define check_region(X, Y) (0)
#define request_region(X, Y, Z) (1)
/* References:
diff --git a/include/asm-sparc/kbio.h b/include/asm-sparc/kbio.h
deleted file mode 100644
index 3cf496bdf399..000000000000
--- a/include/asm-sparc/kbio.h
+++ /dev/null
@@ -1,56 +0,0 @@
-#ifndef __LINUX_KBIO_H
-#define __LINUX_KBIO_H
-
-/* Return keyboard type */
-#define KIOCTYPE _IOR('k', 9, int)
-/* Return Keyboard layout */
-#define KIOCLAYOUT _IOR('k', 20, int)
-
-enum {
- TR_NONE,
- TR_ASCII, /* keyboard is in regular state */
- TR_EVENT, /* keystrokes sent as firm events */
- TR_UNTRANS_EVENT /* EVENT+up and down+no translation */
-};
-
-/* Return the current keyboard translation */
-#define KIOCGTRANS _IOR('k', 5, int)
-/* Set the keyboard translation */
-#define KIOCTRANS _IOW('k', 0, int)
-
-/* Send a keyboard command */
-#define KIOCCMD _IOW('k', 8, int)
-
-/* Return if keystrokes are being sent to /dev/kbd */
-
-/* Set routing of keystrokes to /dev/kbd */
-#define KIOCSDIRECT _IOW('k', 10, int)
-
-/* Set keyboard leds */
-#define KIOCSLED _IOW('k', 14, unsigned char)
-
-/* Get keyboard leds */
-#define KIOCGLED _IOR('k', 15, unsigned char)
-
-/* Used by KIOC[GS]RATE */
-struct kbd_rate {
- unsigned char delay; /* Delay in Hz before first repeat. */
- unsigned char rate; /* In characters per second (0..50). */
-};
-
-/* Set keyboard rate */
-#define KIOCSRATE _IOW('k', 40, struct kbd_rate)
-
-/* Get keyboard rate */
-#define KIOCGRATE _IOW('k', 41, struct kbd_rate)
-
-/* Top bit records if the key is up or down */
-#define KBD_UP 0x80
-
-/* Usable information */
-#define KBD_KEYMASK 0x7f
-
-/* All keys up */
-#define KBD_IDLE 0x75
-
-#endif /* __LINUX_KBIO_H */
diff --git a/include/asm-sparc/pgtable.h b/include/asm-sparc/pgtable.h
index a14e98677500..b33c35411e82 100644
--- a/include/asm-sparc/pgtable.h
+++ b/include/asm-sparc/pgtable.h
@@ -255,8 +255,6 @@ BTFIXUPDEF_CALL_CONST(pte_t, pte_mkyoung, pte_t)
#define pte_mkdirty(pte) BTFIXUP_CALL(pte_mkdirty)(pte)
#define pte_mkyoung(pte) BTFIXUP_CALL(pte_mkyoung)(pte)
-#define page_pte_prot(page, prot) mk_pte(page, prot)
-#define page_pte(page) mk_pte(page, __pgprot(0))
#define pfn_pte(pfn, prot) mk_pte(pfn_to_page(pfn), prot)
BTFIXUPDEF_CALL(unsigned long, pte_pfn, pte_t)
diff --git a/include/asm-sparc/ptrace.h b/include/asm-sparc/ptrace.h
index a8ecb2d6977a..714497099a42 100644
--- a/include/asm-sparc/ptrace.h
+++ b/include/asm-sparc/ptrace.h
@@ -60,6 +60,9 @@ struct sparc_stackf {
#define STACKFRAME_SZ sizeof(struct sparc_stackf)
#ifdef __KERNEL__
+
+#define __ARCH_SYS_PTRACE 1
+
#define user_mode(regs) (!((regs)->psr & PSR_PS))
#define instruction_pointer(regs) ((regs)->pc)
unsigned long profile_pc(struct pt_regs *);
diff --git a/include/asm-sparc/semaphore.h b/include/asm-sparc/semaphore.h
index 60ac5fd9eb48..f74ba31e265b 100644
--- a/include/asm-sparc/semaphore.h
+++ b/include/asm-sparc/semaphore.h
@@ -22,9 +22,6 @@ struct semaphore {
.wait = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \
}
-#define __MUTEX_INITIALIZER(name) \
- __SEMAPHORE_INITIALIZER(name,1)
-
#define __DECLARE_SEMAPHORE_GENERIC(name,count) \
struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
diff --git a/include/asm-sparc/termios.h b/include/asm-sparc/termios.h
index 0a8ad4cac125..d05f83c80989 100644
--- a/include/asm-sparc/termios.h
+++ b/include/asm-sparc/termios.h
@@ -38,15 +38,6 @@ struct sunos_ttysize {
int st_columns; /* Columns on the terminal */
};
-/* Used for packet mode */
-#define TIOCPKT_DATA 0
-#define TIOCPKT_FLUSHREAD 1
-#define TIOCPKT_FLUSHWRITE 2
-#define TIOCPKT_STOP 4
-#define TIOCPKT_START 8
-#define TIOCPKT_NOSTOP 16
-#define TIOCPKT_DOSTOP 32
-
struct winsize {
unsigned short ws_row;
unsigned short ws_col;
diff --git a/include/asm-sparc/vuid_event.h b/include/asm-sparc/vuid_event.h
deleted file mode 100644
index 7781e9f2fdd3..000000000000
--- a/include/asm-sparc/vuid_event.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/* SunOS Virtual User Input Device (VUID) compatibility */
-
-
-typedef struct firm_event {
- unsigned short id; /* tag for this event */
- unsigned char pair_type; /* unused by X11 */
- unsigned char pair; /* unused by X11 */
- int value; /* VKEY_UP, VKEY_DOWN or delta */
- struct timeval time;
-} Firm_event;
-
-enum {
- FE_PAIR_NONE,
- FE_PAIR_SET,
- FE_PAIR_DELTA,
- FE_PAIR_ABSOLUTE
-};
-
-/* VUID stream formats */
-#define VUID_NATIVE 0 /* Native byte stream format */
-#define VUID_FIRM_EVENT 1 /* send firm_event structures */
-
-/* ioctls */
- /* Set input device byte stream format (any of VUID_{NATIVE,FIRM_EVENT}) */
-#define VUIDSFORMAT _IOW('v', 1, int)
- /* Retrieve input device byte stream format */
-#define VUIDGFORMAT _IOR('v', 2, int)
-
-/* Possible tag values */
-/* mouse buttons: */
-#define MS_LEFT 0x7f20
-#define MS_MIDDLE 0x7f21
-#define MS_RIGHT 0x7f22
-/* motion: */
-#define LOC_X_DELTA 0x7f80
-#define LOC_Y_DELTA 0x7f81
-#define LOC_X_ABSOLUTE 0x7f82 /* X compat, unsupported */
-#define LOC_Y_ABSOLUTE 0x7f83 /* X compat, unsupported */
-
-#define VKEY_UP 0
-#define VKEY_DOWN 1
diff --git a/include/asm-sparc64/audioio.h b/include/asm-sparc64/audioio.h
deleted file mode 100644
index cf16173f521b..000000000000
--- a/include/asm-sparc64/audioio.h
+++ /dev/null
@@ -1,234 +0,0 @@
-/*
- * include/asm-sparc/audioio.h
- *
- * Sparc Audio Midlayer
- * Copyright (C) 1996 Thomas K. Dyas (tdyas@noc.rutgers.edu)
- */
-
-#ifndef _AUDIOIO_H_
-#define _AUDIOIO_H_
-
-/*
- * SunOS/Solaris /dev/audio interface
- */
-
-#if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2)
-#include <linux/types.h>
-#include <linux/time.h>
-#include <linux/ioctl.h>
-#endif
-
-/*
- * This structure contains state information for audio device IO streams.
- */
-typedef struct audio_prinfo {
- /*
- * The following values describe the audio data encoding.
- */
- unsigned int sample_rate; /* samples per second */
- unsigned int channels; /* number of interleaved channels */
- unsigned int precision; /* bit-width of each sample */
- unsigned int encoding; /* data encoding method */
-
- /*
- * The following values control audio device configuration
- */
- unsigned int gain; /* gain level: 0 - 255 */
- unsigned int port; /* selected I/O port (see below) */
- unsigned int avail_ports; /* available I/O ports (see below) */
- unsigned int _xxx[2]; /* Reserved for future use */
-
- unsigned int buffer_size; /* I/O buffer size */
-
- /*
- * The following values describe driver state
- */
- unsigned int samples; /* number of samples converted */
- unsigned int eof; /* End Of File counter (play only) */
-
- unsigned char pause; /* non-zero for pause, zero to resume */
- unsigned char error; /* non-zero if overflow/underflow */
- unsigned char waiting; /* non-zero if a process wants access */
- unsigned char balance; /* stereo channel balance */
-
- unsigned short minordev;
-
- /*
- * The following values are read-only state flags
- */
- unsigned char open; /* non-zero if open access permitted */
- unsigned char active; /* non-zero if I/O is active */
-} audio_prinfo_t;
-
-
-/*
- * This structure describes the current state of the audio device.
- */
-typedef struct audio_info {
- /*
- * Per-stream information
- */
- audio_prinfo_t play; /* output status information */
- audio_prinfo_t record; /* input status information */
-
- /*
- * Per-unit/channel information
- */
- unsigned int monitor_gain; /* input to output mix: 0 - 255 */
- unsigned char output_muted; /* non-zero if output is muted */
- unsigned char _xxx[3]; /* Reserved for future use */
- unsigned int _yyy[3]; /* Reserved for future use */
-} audio_info_t;
-
-
-/*
- * Audio encoding types
- */
-#define AUDIO_ENCODING_NONE (0) /* no encoding assigned */
-#define AUDIO_ENCODING_ULAW (1) /* u-law encoding */
-#define AUDIO_ENCODING_ALAW (2) /* A-law encoding */
-#define AUDIO_ENCODING_LINEAR (3) /* Linear PCM encoding */
-#define AUDIO_ENCODING_FLOAT (4) /* IEEE float (-1. <-> +1.) */
-#define AUDIO_ENCODING_DVI (104) /* DVI ADPCM */
-#define AUDIO_ENCODING_LINEAR8 (105) /* 8 bit UNSIGNED */
-#define AUDIO_ENCODING_LINEARLE (106) /* Linear PCM LE encoding */
-
-/*
- * These ranges apply to record, play, and monitor gain values
- */
-#define AUDIO_MIN_GAIN (0) /* minimum gain value */
-#define AUDIO_MAX_GAIN (255) /* maximum gain value */
-
-/*
- * These values apply to the balance field to adjust channel gain values
- */
-#define AUDIO_LEFT_BALANCE (0) /* left channel only */
-#define AUDIO_MID_BALANCE (32) /* equal left/right channel */
-#define AUDIO_RIGHT_BALANCE (64) /* right channel only */
-#define AUDIO_BALANCE_SHIFT (3)
-
-/*
- * Generic minimum/maximum limits for number of channels, both modes
- */
-#define AUDIO_MIN_PLAY_CHANNELS (1)
-#define AUDIO_MAX_PLAY_CHANNELS (4)
-#define AUDIO_MIN_REC_CHANNELS (1)
-#define AUDIO_MAX_REC_CHANNELS (4)
-
-/*
- * Generic minimum/maximum limits for sample precision
- */
-#define AUDIO_MIN_PLAY_PRECISION (8)
-#define AUDIO_MAX_PLAY_PRECISION (32)
-#define AUDIO_MIN_REC_PRECISION (8)
-#define AUDIO_MAX_REC_PRECISION (32)
-
-/*
- * Define some convenient names for typical audio ports
- */
-/*
- * output ports (several may be enabled simultaneously)
- */
-#define AUDIO_SPEAKER 0x01 /* output to built-in speaker */
-#define AUDIO_HEADPHONE 0x02 /* output to headphone jack */
-#define AUDIO_LINE_OUT 0x04 /* output to line out */
-
-/*
- * input ports (usually only one at a time)
- */
-#define AUDIO_MICROPHONE 0x01 /* input from microphone */
-#define AUDIO_LINE_IN 0x02 /* input from line in */
-#define AUDIO_CD 0x04 /* input from on-board CD inputs */
-#define AUDIO_INTERNAL_CD_IN AUDIO_CD /* input from internal CDROM */
-#define AUDIO_ANALOG_LOOPBACK 0x40 /* input from output */
-
-
-/*
- * This macro initializes an audio_info structure to 'harmless' values.
- * Note that (~0) might not be a harmless value for a flag that was
- * a signed int.
- */
-#define AUDIO_INITINFO(i) { \
- unsigned int *__x__; \
- for (__x__ = (unsigned int *)(i); \
- (char *) __x__ < (((char *)(i)) + sizeof (audio_info_t)); \
- *__x__++ = ~0); \
-}
-
-/*
- * These allow testing for what the user wants to set
- */
-#define AUD_INITVALUE (~0)
-#define Modify(X) ((unsigned int)(X) != AUD_INITVALUE)
-#define Modifys(X) ((X) != (unsigned short)AUD_INITVALUE)
-#define Modifyc(X) ((X) != (unsigned char)AUD_INITVALUE)
-
-/*
- * Parameter for the AUDIO_GETDEV ioctl to determine current
- * audio devices.
- */
-#define MAX_AUDIO_DEV_LEN (16)
-typedef struct audio_device {
- char name[MAX_AUDIO_DEV_LEN];
- char version[MAX_AUDIO_DEV_LEN];
- char config[MAX_AUDIO_DEV_LEN];
-} audio_device_t;
-
-
-/*
- * Ioctl calls for the audio device.
- */
-
-/*
- * AUDIO_GETINFO retrieves the current state of the audio device.
- *
- * AUDIO_SETINFO copies all fields of the audio_info structure whose
- * values are not set to the initialized value (-1) to the device state.
- * It performs an implicit AUDIO_GETINFO to return the new state of the
- * device. Note that the record.samples and play.samples fields are set
- * to the last value before the AUDIO_SETINFO took effect. This allows
- * an application to reset the counters while atomically retrieving the
- * last value.
- *
- * AUDIO_DRAIN suspends the calling process until the write buffers are
- * empty.
- *
- * AUDIO_GETDEV returns a structure of type audio_device_t which contains
- * three strings. The string "name" is a short identifying string (for
- * example, the SBus Fcode name string), the string "version" identifies
- * the current version of the device, and the "config" string identifies
- * the specific configuration of the audio stream. All fields are
- * device-dependent -- see the device specific manual pages for details.
- *
- * AUDIO_GETDEV_SUNOS returns a number which is an audio device defined
- * herein (making it not too portable)
- *
- * AUDIO_FLUSH stops all playback and recording, clears all queued buffers,
- * resets error counters, and restarts recording and playback as appropriate
- * for the current sampling mode.
- */
-#define AUDIO_GETINFO _IOR('A', 1, audio_info_t)
-#define AUDIO_SETINFO _IOWR('A', 2, audio_info_t)
-#define AUDIO_DRAIN _IO('A', 3)
-#define AUDIO_GETDEV _IOR('A', 4, audio_device_t)
-#define AUDIO_GETDEV_SUNOS _IOR('A', 4, int)
-#define AUDIO_FLUSH _IO('A', 5)
-
-/* Define possible audio hardware configurations for
- * old SunOS-style AUDIO_GETDEV ioctl */
-#define AUDIO_DEV_UNKNOWN (0) /* not defined */
-#define AUDIO_DEV_AMD (1) /* audioamd device */
-#define AUDIO_DEV_SPEAKERBOX (2) /* dbri device with speakerbox */
-#define AUDIO_DEV_CODEC (3) /* dbri device (internal speaker) */
-#define AUDIO_DEV_CS4231 (5) /* cs4231 device */
-
-/*
- * The following ioctl sets the audio device into an internal loopback mode,
- * if the hardware supports this. The argument is TRUE to set loopback,
- * FALSE to reset to normal operation. If the hardware does not support
- * internal loopback, the ioctl should fail with EINVAL.
- * Causes ADC data to be digitally mixed in and sent to the DAC.
- */
-#define AUDIO_DIAG_LOOPBACK _IOW('A', 101, int)
-
-#endif /* _AUDIOIO_H_ */
diff --git a/include/asm-sparc64/dma-mapping.h b/include/asm-sparc64/dma-mapping.h
index 1c5da41653a4..c7d5804ba76d 100644
--- a/include/asm-sparc64/dma-mapping.h
+++ b/include/asm-sparc64/dma-mapping.h
@@ -10,7 +10,7 @@
struct device;
static inline void *dma_alloc_coherent(struct device *dev, size_t size,
- dma_addr_t *dma_handle, int flag)
+ dma_addr_t *dma_handle, gfp_t flag)
{
BUG();
return NULL;
diff --git a/include/asm-sparc64/ebus.h b/include/asm-sparc64/ebus.h
index 543e4e500a72..7a408a030f52 100644
--- a/include/asm-sparc64/ebus.h
+++ b/include/asm-sparc64/ebus.h
@@ -79,6 +79,7 @@ extern int ebus_dma_request(struct ebus_dma_info *p, dma_addr_t bus_addr,
size_t len);
extern void ebus_dma_prepare(struct ebus_dma_info *p, int write);
extern unsigned int ebus_dma_residue(struct ebus_dma_info *p);
+extern unsigned int ebus_dma_addr(struct ebus_dma_info *p);
extern void ebus_dma_enable(struct ebus_dma_info *p, int on);
extern struct linux_ebus *ebus_chain;
diff --git a/include/asm-sparc64/kbio.h b/include/asm-sparc64/kbio.h
deleted file mode 100644
index 3cf496bdf399..000000000000
--- a/include/asm-sparc64/kbio.h
+++ /dev/null
@@ -1,56 +0,0 @@
-#ifndef __LINUX_KBIO_H
-#define __LINUX_KBIO_H
-
-/* Return keyboard type */
-#define KIOCTYPE _IOR('k', 9, int)
-/* Return Keyboard layout */
-#define KIOCLAYOUT _IOR('k', 20, int)
-
-enum {
- TR_NONE,
- TR_ASCII, /* keyboard is in regular state */
- TR_EVENT, /* keystrokes sent as firm events */
- TR_UNTRANS_EVENT /* EVENT+up and down+no translation */
-};
-
-/* Return the current keyboard translation */
-#define KIOCGTRANS _IOR('k', 5, int)
-/* Set the keyboard translation */
-#define KIOCTRANS _IOW('k', 0, int)
-
-/* Send a keyboard command */
-#define KIOCCMD _IOW('k', 8, int)
-
-/* Return if keystrokes are being sent to /dev/kbd */
-
-/* Set routing of keystrokes to /dev/kbd */
-#define KIOCSDIRECT _IOW('k', 10, int)
-
-/* Set keyboard leds */
-#define KIOCSLED _IOW('k', 14, unsigned char)
-
-/* Get keyboard leds */
-#define KIOCGLED _IOR('k', 15, unsigned char)
-
-/* Used by KIOC[GS]RATE */
-struct kbd_rate {
- unsigned char delay; /* Delay in Hz before first repeat. */
- unsigned char rate; /* In characters per second (0..50). */
-};
-
-/* Set keyboard rate */
-#define KIOCSRATE _IOW('k', 40, struct kbd_rate)
-
-/* Get keyboard rate */
-#define KIOCGRATE _IOW('k', 41, struct kbd_rate)
-
-/* Top bit records if the key is up or down */
-#define KBD_UP 0x80
-
-/* Usable information */
-#define KBD_KEYMASK 0x7f
-
-/* All keys up */
-#define KBD_IDLE 0x75
-
-#endif /* __LINUX_KBIO_H */
diff --git a/include/asm-sparc64/kprobes.h b/include/asm-sparc64/kprobes.h
index a8d326a598f0..7ba845320f5c 100644
--- a/include/asm-sparc64/kprobes.h
+++ b/include/asm-sparc64/kprobes.h
@@ -3,6 +3,7 @@
#include <linux/config.h>
#include <linux/types.h>
+#include <linux/percpu.h>
typedef u32 kprobe_opcode_t;
@@ -18,6 +19,25 @@ struct arch_specific_insn {
kprobe_opcode_t insn[MAX_INSN_SIZE];
};
+struct prev_kprobe {
+ struct kprobe *kp;
+ unsigned int status;
+ unsigned long orig_tnpc;
+ unsigned long orig_tstate_pil;
+};
+
+/* per-cpu kprobe control block */
+struct kprobe_ctlblk {
+ unsigned long kprobe_status;
+ unsigned long kprobe_orig_tnpc;
+ unsigned long kprobe_orig_tstate_pil;
+ long *jprobe_saved_esp;
+ struct pt_regs jprobe_saved_regs;
+ struct pt_regs *jprobe_saved_regs_location;
+ struct sparc_stackf jprobe_saved_stack;
+ struct prev_kprobe prev_kprobe;
+};
+
#ifdef CONFIG_KPROBES
extern int kprobe_exceptions_notify(struct notifier_block *self,
unsigned long val, void *data);
diff --git a/include/asm-sparc64/mmu_context.h b/include/asm-sparc64/mmu_context.h
index 87c43c67866e..08ba72d7722c 100644
--- a/include/asm-sparc64/mmu_context.h
+++ b/include/asm-sparc64/mmu_context.h
@@ -87,37 +87,35 @@ extern void __flush_tlb_mm(unsigned long, unsigned long);
static inline void switch_mm(struct mm_struct *old_mm, struct mm_struct *mm, struct task_struct *tsk)
{
unsigned long ctx_valid;
+ int cpu;
+ /* Note: page_table_lock is used here to serialize switch_mm
+ * and activate_mm, and their calls to get_new_mmu_context.
+ * This use of page_table_lock is unrelated to its other uses.
+ */
spin_lock(&mm->page_table_lock);
- if (CTX_VALID(mm->context))
- ctx_valid = 1;
- else
- ctx_valid = 0;
+ ctx_valid = CTX_VALID(mm->context);
+ if (!ctx_valid)
+ get_new_mmu_context(mm);
+ spin_unlock(&mm->page_table_lock);
if (!ctx_valid || (old_mm != mm)) {
- if (!ctx_valid)
- get_new_mmu_context(mm);
-
load_secondary_context(mm);
reload_tlbmiss_state(tsk, mm);
}
- {
- int cpu = smp_processor_id();
-
- /* Even if (mm == old_mm) we _must_ check
- * the cpu_vm_mask. If we do not we could
- * corrupt the TLB state because of how
- * smp_flush_tlb_{page,range,mm} on sparc64
- * and lazy tlb switches work. -DaveM
- */
- if (!ctx_valid || !cpu_isset(cpu, mm->cpu_vm_mask)) {
- cpu_set(cpu, mm->cpu_vm_mask);
- __flush_tlb_mm(CTX_HWBITS(mm->context),
- SECONDARY_CONTEXT);
- }
+ /* Even if (mm == old_mm) we _must_ check
+ * the cpu_vm_mask. If we do not we could
+ * corrupt the TLB state because of how
+ * smp_flush_tlb_{page,range,mm} on sparc64
+ * and lazy tlb switches work. -DaveM
+ */
+ cpu = smp_processor_id();
+ if (!ctx_valid || !cpu_isset(cpu, mm->cpu_vm_mask)) {
+ cpu_set(cpu, mm->cpu_vm_mask);
+ __flush_tlb_mm(CTX_HWBITS(mm->context),
+ SECONDARY_CONTEXT);
}
- spin_unlock(&mm->page_table_lock);
}
#define deactivate_mm(tsk,mm) do { } while (0)
@@ -127,6 +125,10 @@ static inline void activate_mm(struct mm_struct *active_mm, struct mm_struct *mm
{
int cpu;
+ /* Note: page_table_lock is used here to serialize switch_mm
+ * and activate_mm, and their calls to get_new_mmu_context.
+ * This use of page_table_lock is unrelated to its other uses.
+ */
spin_lock(&mm->page_table_lock);
if (!CTX_VALID(mm->context))
get_new_mmu_context(mm);
diff --git a/include/asm-sparc64/pgtable.h b/include/asm-sparc64/pgtable.h
index 8c6dfc6c7af6..9a02879b235d 100644
--- a/include/asm-sparc64/pgtable.h
+++ b/include/asm-sparc64/pgtable.h
@@ -231,9 +231,6 @@ extern struct page *mem_map_zero;
#define pte_pfn(x) ((pte_val(x) & _PAGE_PADDR)>>PAGE_SHIFT)
#define pte_page(x) pfn_to_page(pte_pfn(x))
-#define page_pte_prot(page, prot) mk_pte(page, prot)
-#define page_pte(page) page_pte_prot(page, __pgprot(0))
-
static inline pte_t pte_modify(pte_t orig_pte, pgprot_t new_prot)
{
pte_t __pte;
diff --git a/include/asm-sparc64/ptrace.h b/include/asm-sparc64/ptrace.h
index 6194f771e9fc..7eba90c6c753 100644
--- a/include/asm-sparc64/ptrace.h
+++ b/include/asm-sparc64/ptrace.h
@@ -94,6 +94,9 @@ struct sparc_trapf {
#define STACKFRAME32_SZ sizeof(struct sparc_stackf32)
#ifdef __KERNEL__
+
+#define __ARCH_SYS_PTRACE 1
+
#define force_successful_syscall_return() \
do { current_thread_info()->syscall_noerror = 1; \
} while (0)
diff --git a/include/asm-sparc64/rwsem.h b/include/asm-sparc64/rwsem.h
index 4568ee4022df..cef5e8270421 100644
--- a/include/asm-sparc64/rwsem.h
+++ b/include/asm-sparc64/rwsem.h
@@ -56,6 +56,11 @@ static inline void rwsem_atomic_add(int delta, struct rw_semaphore *sem)
atomic_add(delta, (atomic_t *)(&sem->count));
}
+static inline int rwsem_is_locked(struct rw_semaphore *sem)
+{
+ return (sem->count != 0);
+}
+
#endif /* __KERNEL__ */
#endif /* _SPARC64_RWSEM_H */
diff --git a/include/asm-sparc64/semaphore.h b/include/asm-sparc64/semaphore.h
index 7419dd88b49e..093dcc6788db 100644
--- a/include/asm-sparc64/semaphore.h
+++ b/include/asm-sparc64/semaphore.h
@@ -22,9 +22,6 @@ struct semaphore {
{ ATOMIC_INIT(count), \
__WAIT_QUEUE_HEAD_INITIALIZER((name).wait) }
-#define __MUTEX_INITIALIZER(name) \
- __SEMAPHORE_INITIALIZER(name, 1)
-
#define __DECLARE_SEMAPHORE_GENERIC(name, count) \
struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
diff --git a/include/asm-sparc64/termios.h b/include/asm-sparc64/termios.h
index 9777a9cca88a..ee26a071c677 100644
--- a/include/asm-sparc64/termios.h
+++ b/include/asm-sparc64/termios.h
@@ -38,15 +38,6 @@ struct sunos_ttysize {
int st_columns; /* Columns on the terminal */
};
-/* Used for packet mode */
-#define TIOCPKT_DATA 0
-#define TIOCPKT_FLUSHREAD 1
-#define TIOCPKT_FLUSHWRITE 2
-#define TIOCPKT_STOP 4
-#define TIOCPKT_START 8
-#define TIOCPKT_NOSTOP 16
-#define TIOCPKT_DOSTOP 32
-
struct winsize {
unsigned short ws_row;
unsigned short ws_col;
diff --git a/include/asm-sparc64/tlb.h b/include/asm-sparc64/tlb.h
index 9baf57db01d2..61c01882b562 100644
--- a/include/asm-sparc64/tlb.h
+++ b/include/asm-sparc64/tlb.h
@@ -25,9 +25,8 @@ struct mmu_gather {
struct mm_struct *mm;
unsigned int pages_nr;
unsigned int need_flush;
- unsigned int tlb_frozen;
+ unsigned int fullmm;
unsigned int tlb_nr;
- unsigned long freed;
unsigned long vaddrs[TLB_BATCH_NR];
struct page *pages[FREE_PTE_NR];
};
@@ -44,14 +43,13 @@ extern void flush_tlb_pending(void);
static inline struct mmu_gather *tlb_gather_mmu(struct mm_struct *mm, unsigned int full_mm_flush)
{
- struct mmu_gather *mp = &__get_cpu_var(mmu_gathers);
+ struct mmu_gather *mp = &get_cpu_var(mmu_gathers);
BUG_ON(mp->tlb_nr);
mp->mm = mm;
mp->pages_nr = num_online_cpus() > 1 ? 0U : ~0U;
- mp->tlb_frozen = full_mm_flush;
- mp->freed = 0;
+ mp->fullmm = full_mm_flush;
return mp;
}
@@ -60,11 +58,9 @@ static inline struct mmu_gather *tlb_gather_mmu(struct mm_struct *mm, unsigned i
static inline void tlb_flush_mmu(struct mmu_gather *mp)
{
if (mp->need_flush) {
+ free_pages_and_swap_cache(mp->pages, mp->pages_nr);
+ mp->pages_nr = 0;
mp->need_flush = 0;
- if (!tlb_fast_mode(mp)) {
- free_pages_and_swap_cache(mp->pages, mp->pages_nr);
- mp->pages_nr = 0;
- }
}
}
@@ -78,39 +74,26 @@ extern void smp_flush_tlb_mm(struct mm_struct *mm);
static inline void tlb_finish_mmu(struct mmu_gather *mp, unsigned long start, unsigned long end)
{
- unsigned long freed = mp->freed;
- struct mm_struct *mm = mp->mm;
- unsigned long rss = get_mm_counter(mm, rss);
-
- if (rss < freed)
- freed = rss;
- add_mm_counter(mm, rss, -freed);
-
tlb_flush_mmu(mp);
- if (mp->tlb_frozen) {
- if (CTX_VALID(mm->context))
- do_flush_tlb_mm(mm);
- mp->tlb_frozen = 0;
- } else
+ if (mp->fullmm)
+ mp->fullmm = 0;
+ else
flush_tlb_pending();
/* keep the page table cache within bounds */
check_pgt_cache();
-}
-static inline unsigned int tlb_is_full_mm(struct mmu_gather *mp)
-{
- return mp->tlb_frozen;
+ put_cpu_var(mmu_gathers);
}
static inline void tlb_remove_page(struct mmu_gather *mp, struct page *page)
{
- mp->need_flush = 1;
if (tlb_fast_mode(mp)) {
free_page_and_swap_cache(page);
return;
}
+ mp->need_flush = 1;
mp->pages[mp->pages_nr++] = page;
if (mp->pages_nr >= FREE_PTE_NR)
tlb_flush_mmu(mp);
diff --git a/include/asm-sparc64/vuid_event.h b/include/asm-sparc64/vuid_event.h
deleted file mode 100644
index 9ef4d17ad08f..000000000000
--- a/include/asm-sparc64/vuid_event.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/* SunOS Virtual User Input Device (VUID) compatibility */
-
-typedef struct firm_event {
- unsigned short id; /* tag for this event */
- unsigned char pair_type; /* unused by X11 */
- unsigned char pair; /* unused by X11 */
- int value; /* VKEY_UP, VKEY_DOWN or delta */
- struct timeval time;
-} Firm_event;
-
-enum {
- FE_PAIR_NONE,
- FE_PAIR_SET,
- FE_PAIR_DELTA,
- FE_PAIR_ABSOLUTE
-};
-
-/* VUID stream formats */
-#define VUID_NATIVE 0 /* Native byte stream format */
-#define VUID_FIRM_EVENT 1 /* send firm_event structures */
-
-/* ioctls */
- /* Set input device byte stream format (any of VUID_{NATIVE,FIRM_EVENT}) */
-#define VUIDSFORMAT _IOW('v', 1, int)
- /* Retrieve input device byte stream format */
-#define VUIDGFORMAT _IOR('v', 2, int)
-
-/* Possible tag values */
-/* mouse buttons: */
-#define MS_LEFT 0x7f20
-#define MS_MIDDLE 0x7f21
-#define MS_RIGHT 0x7f22
-/* motion: */
-#define LOC_X_DELTA 0x7f80
-#define LOC_Y_DELTA 0x7f81
-#define LOC_X_ABSOLUTE 0x7f82 /* X compat, unsupported */
-#define LOC_Y_ABSOLUTE 0x7f83 /* X compat, unsupported */
-
-#define VKEY_UP 0
-#define VKEY_DOWN 1
diff --git a/include/asm-um/cache.h b/include/asm-um/cache.h
index 4b134fe8504e..a10602a5b2d6 100644
--- a/include/asm-um/cache.h
+++ b/include/asm-um/cache.h
@@ -1,10 +1,21 @@
#ifndef __UM_CACHE_H
#define __UM_CACHE_H
-/* These are x86 numbers */
-#define L1_CACHE_SHIFT 5
-#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
+#include <linux/config.h>
-#define L1_CACHE_SHIFT_MAX 7 /* largest L1 which this arch supports */
+#if defined(CONFIG_UML_X86) && !defined(CONFIG_64BIT)
+# define L1_CACHE_SHIFT (CONFIG_X86_L1_CACHE_SHIFT)
+#elif defined(CONFIG_UML_X86) /* 64-bit */
+# define L1_CACHE_SHIFT 6 /* Should be 7 on Intel */
+#else
+/* XXX: this was taken from x86, now it's completely random. Luckily only
+ * affects SMP padding. */
+# define L1_CACHE_SHIFT 5
+#endif
+
+/* XXX: this is valid for x86 and x86_64. */
+#define L1_CACHE_SHIFT_MAX 7 /* largest L1 which this arch supports */
+
+#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
#endif
diff --git a/include/asm-um/dma-mapping.h b/include/asm-um/dma-mapping.h
index 13e6291f7151..babd29895114 100644
--- a/include/asm-um/dma-mapping.h
+++ b/include/asm-um/dma-mapping.h
@@ -19,7 +19,7 @@ dma_set_mask(struct device *dev, u64 dma_mask)
static inline void *
dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle,
- int flag)
+ gfp_t flag)
{
BUG();
return((void *) 0);
diff --git a/include/asm-um/ldt-i386.h b/include/asm-um/ldt-i386.h
new file mode 100644
index 000000000000..b42662929b6c
--- /dev/null
+++ b/include/asm-um/ldt-i386.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2004 Fujitsu Siemens Computers GmbH
+ * Licensed under the GPL
+ *
+ * Author: Bodo Stroesser <bstroesser@fujitsu-siemens.com>
+ */
+
+#ifndef __ASM_LDT_I386_H
+#define __ASM_LDT_I386_H
+
+#include "asm/semaphore.h"
+#include "asm/arch/ldt.h"
+
+struct mmu_context_skas;
+extern void ldt_host_info(void);
+extern long init_new_ldt(struct mmu_context_skas * to_mm,
+ struct mmu_context_skas * from_mm);
+extern void free_ldt(struct mmu_context_skas * mm);
+
+#define LDT_PAGES_MAX \
+ ((LDT_ENTRIES * LDT_ENTRY_SIZE)/PAGE_SIZE)
+#define LDT_ENTRIES_PER_PAGE \
+ (PAGE_SIZE/LDT_ENTRY_SIZE)
+#define LDT_DIRECT_ENTRIES \
+ ((LDT_PAGES_MAX*sizeof(void *))/LDT_ENTRY_SIZE)
+
+struct ldt_entry {
+ __u32 a;
+ __u32 b;
+};
+
+typedef struct uml_ldt {
+ int entry_count;
+ struct semaphore semaphore;
+ union {
+ struct ldt_entry * pages[LDT_PAGES_MAX];
+ struct ldt_entry entries[LDT_DIRECT_ENTRIES];
+ };
+} uml_ldt_t;
+
+/*
+ * macros stolen from include/asm-i386/desc.h
+ */
+#define LDT_entry_a(info) \
+ ((((info)->base_addr & 0x0000ffff) << 16) | ((info)->limit & 0x0ffff))
+
+#define LDT_entry_b(info) \
+ (((info)->base_addr & 0xff000000) | \
+ (((info)->base_addr & 0x00ff0000) >> 16) | \
+ ((info)->limit & 0xf0000) | \
+ (((info)->read_exec_only ^ 1) << 9) | \
+ ((info)->contents << 10) | \
+ (((info)->seg_not_present ^ 1) << 15) | \
+ ((info)->seg_32bit << 22) | \
+ ((info)->limit_in_pages << 23) | \
+ ((info)->useable << 20) | \
+ 0x7000)
+
+#define LDT_empty(info) (\
+ (info)->base_addr == 0 && \
+ (info)->limit == 0 && \
+ (info)->contents == 0 && \
+ (info)->read_exec_only == 1 && \
+ (info)->seg_32bit == 0 && \
+ (info)->limit_in_pages == 0 && \
+ (info)->seg_not_present == 1 && \
+ (info)->useable == 0 )
+
+#endif
diff --git a/include/asm-um/ldt.h b/include/asm-um/ldt.h
index e908439d338a..4466ff6de0fd 100644
--- a/include/asm-um/ldt.h
+++ b/include/asm-um/ldt.h
@@ -1,3 +1,72 @@
+/*
+ * Copyright (C) 2004 Fujitsu Siemens Computers GmbH
+ * Licensed under the GPL
+ *
+ * Author: Bodo Stroesser <bstroesser@fujitsu-siemens.com>
+ */
+
+#ifndef __ASM_LDT_I386_H
+#define __ASM_LDT_I386_H
+
+#include "asm/semaphore.h"
+#include "asm/arch/ldt.h"
+
+struct mmu_context_skas;
+extern void ldt_host_info(void);
+extern long init_new_ldt(struct mmu_context_skas * to_mm,
+ struct mmu_context_skas * from_mm);
+extern void free_ldt(struct mmu_context_skas * mm);
+
+#define LDT_PAGES_MAX \
+ ((LDT_ENTRIES * LDT_ENTRY_SIZE)/PAGE_SIZE)
+#define LDT_ENTRIES_PER_PAGE \
+ (PAGE_SIZE/LDT_ENTRY_SIZE)
+#define LDT_DIRECT_ENTRIES \
+ ((LDT_PAGES_MAX*sizeof(void *))/LDT_ENTRY_SIZE)
+
+struct ldt_entry {
+ __u32 a;
+ __u32 b;
+};
+
+typedef struct uml_ldt {
+ int entry_count;
+ struct semaphore semaphore;
+ union {
+ struct ldt_entry * pages[LDT_PAGES_MAX];
+ struct ldt_entry entries[LDT_DIRECT_ENTRIES];
+ };
+} uml_ldt_t;
+
+/*
+ * macros stolen from include/asm-i386/desc.h
+ */
+#define LDT_entry_a(info) \
+ ((((info)->base_addr & 0x0000ffff) << 16) | ((info)->limit & 0x0ffff))
+
+#define LDT_entry_b(info) \
+ (((info)->base_addr & 0xff000000) | \
+ (((info)->base_addr & 0x00ff0000) >> 16) | \
+ ((info)->limit & 0xf0000) | \
+ (((info)->read_exec_only ^ 1) << 9) | \
+ ((info)->contents << 10) | \
+ (((info)->seg_not_present ^ 1) << 15) | \
+ ((info)->seg_32bit << 22) | \
+ ((info)->limit_in_pages << 23) | \
+ ((info)->useable << 20) | \
+ 0x7000)
+
+#define LDT_empty(info) (\
+ (info)->base_addr == 0 && \
+ (info)->limit == 0 && \
+ (info)->contents == 0 && \
+ (info)->read_exec_only == 1 && \
+ (info)->seg_32bit == 0 && \
+ (info)->limit_in_pages == 0 && \
+ (info)->seg_not_present == 1 && \
+ (info)->useable == 0 )
+
+#endif
#ifndef __UM_LDT_H
#define __UM_LDT_H
diff --git a/include/asm-um/linkage.h b/include/asm-um/linkage.h
index 7dfce37adc8b..e3d62dcbd356 100644
--- a/include/asm-um/linkage.h
+++ b/include/asm-um/linkage.h
@@ -3,4 +3,12 @@
#include "asm/arch/linkage.h"
+#include <linux/config.h>
+
+/* <linux/linkage.h> will pick sane defaults */
+#ifdef CONFIG_GPROF
+#undef FASTCALL
+#undef fastcall
+#endif
+
#endif
diff --git a/include/asm-um/mmu_context.h b/include/asm-um/mmu_context.h
index 2edb4f1f789c..9a0e48eb542e 100644
--- a/include/asm-um/mmu_context.h
+++ b/include/asm-um/mmu_context.h
@@ -29,7 +29,8 @@ static inline void activate_mm(struct mm_struct *old, struct mm_struct *new)
* possible.
*/
if (old != new && (current->flags & PF_BORROWED_MM))
- force_flush_all();
+ CHOOSE_MODE(force_flush_all(),
+ switch_mm_skas(&new->context.skas.id));
}
static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
diff --git a/include/asm-um/page.h b/include/asm-um/page.h
index 2c192abe9aeb..0229814af31e 100644
--- a/include/asm-um/page.h
+++ b/include/asm-um/page.h
@@ -115,7 +115,7 @@ extern unsigned long uml_physmem;
#define pfn_valid(pfn) ((pfn) < max_mapnr)
#define virt_addr_valid(v) pfn_valid(phys_to_pfn(__pa(v)))
-extern struct page *arch_validate(struct page *page, int mask, int order);
+extern struct page *arch_validate(struct page *page, gfp_t mask, int order);
#define HAVE_ARCH_VALIDATE
extern void arch_free_page(struct page *page, int order);
diff --git a/include/asm-um/pgtable.h b/include/asm-um/pgtable.h
index 616d02b57ea9..ac64eb955868 100644
--- a/include/asm-um/pgtable.h
+++ b/include/asm-um/pgtable.h
@@ -138,7 +138,7 @@ extern unsigned long pg0[1024];
#define pte_clear(mm,addr,xp) pte_set_val(*(xp), (phys_t) 0, __pgprot(_PAGE_NEWPAGE))
-#define pmd_none(x) (!(pmd_val(x) & ~_PAGE_NEWPAGE))
+#define pmd_none(x) (!((unsigned long)pmd_val(x) & ~_PAGE_NEWPAGE))
#define pmd_bad(x) ((pmd_val(x) & (~PAGE_MASK & ~_PAGE_USER)) != _KERNPG_TABLE)
#define pmd_present(x) (pmd_val(x) & _PAGE_PRESENT)
#define pmd_clear(xp) do { pmd_val(*(xp)) = _PAGE_NEWPAGE; } while (0)
diff --git a/include/asm-v850/atomic.h b/include/asm-v850/atomic.h
index 8284aa7363f2..395268a8c0de 100644
--- a/include/asm-v850/atomic.h
+++ b/include/asm-v850/atomic.h
@@ -31,7 +31,7 @@ typedef struct { int counter; } atomic_t;
#define atomic_read(v) ((v)->counter)
#define atomic_set(v,i) (((v)->counter) = (i))
-extern __inline__ int atomic_add_return (int i, volatile atomic_t *v)
+static inline int atomic_add_return (int i, volatile atomic_t *v)
{
unsigned long flags;
int res;
diff --git a/include/asm-v850/bitops.h b/include/asm-v850/bitops.h
index 0e5c2f210872..b91e799763fd 100644
--- a/include/asm-v850/bitops.h
+++ b/include/asm-v850/bitops.h
@@ -30,7 +30,7 @@
* ffz = Find First Zero in word. Undefined if no zero exists,
* so code should check against ~0UL first..
*/
-extern __inline__ unsigned long ffz (unsigned long word)
+static inline unsigned long ffz (unsigned long word)
{
unsigned long result = 0;
@@ -135,7 +135,7 @@ extern __inline__ unsigned long ffz (unsigned long word)
"m" (*((const char *)(addr) + ((nr) >> 3)))); \
__test_bit_res; \
})
-extern __inline__ int __test_bit (int nr, const void *addr)
+static inline int __test_bit (int nr, const void *addr)
{
int res;
__asm__ __volatile__ ("tst1 %1, [%2]; setf nz, %0"
@@ -157,7 +157,7 @@ extern __inline__ int __test_bit (int nr, const void *addr)
#define find_first_zero_bit(addr, size) \
find_next_zero_bit ((addr), (size), 0)
-extern __inline__ int find_next_zero_bit(const void *addr, int size, int offset)
+static inline int find_next_zero_bit(const void *addr, int size, int offset)
{
unsigned long *p = ((unsigned long *) addr) + (offset >> 5);
unsigned long result = offset & ~31UL;
diff --git a/include/asm-v850/delay.h b/include/asm-v850/delay.h
index 1ce65d48a7c5..6d028e6b2354 100644
--- a/include/asm-v850/delay.h
+++ b/include/asm-v850/delay.h
@@ -16,7 +16,7 @@
#include <asm/param.h>
-extern __inline__ void __delay(unsigned long loops)
+static inline void __delay(unsigned long loops)
{
if (loops)
__asm__ __volatile__ ("1: add -1, %0; bnz 1b"
@@ -33,7 +33,7 @@ extern __inline__ void __delay(unsigned long loops)
extern unsigned long loops_per_jiffy;
-extern __inline__ void udelay(unsigned long usecs)
+static inline void udelay(unsigned long usecs)
{
register unsigned long full_loops, part_loops;
diff --git a/include/asm-v850/hw_irq.h b/include/asm-v850/hw_irq.h
index 4bdc98edb9f8..a8aab4342712 100644
--- a/include/asm-v850/hw_irq.h
+++ b/include/asm-v850/hw_irq.h
@@ -1,7 +1,7 @@
#ifndef __V850_HW_IRQ_H__
#define __V850_HW_IRQ_H__
-extern inline void hw_resend_irq (struct hw_interrupt_type *h, unsigned int i)
+static inline void hw_resend_irq (struct hw_interrupt_type *h, unsigned int i)
{
}
diff --git a/include/asm-v850/processor.h b/include/asm-v850/processor.h
index d41f925f5182..98f929427d3d 100644
--- a/include/asm-v850/processor.h
+++ b/include/asm-v850/processor.h
@@ -59,7 +59,7 @@ struct thread_struct {
/* Do necessary setup to start up a newly executed thread. */
-extern inline void start_thread (struct pt_regs *regs,
+static inline void start_thread (struct pt_regs *regs,
unsigned long pc, unsigned long usp)
{
regs->pc = pc;
@@ -68,7 +68,7 @@ extern inline void start_thread (struct pt_regs *regs,
}
/* Free all resources held by a thread. */
-extern inline void release_thread (struct task_struct *dead_task)
+static inline void release_thread (struct task_struct *dead_task)
{
}
diff --git a/include/asm-v850/semaphore.h b/include/asm-v850/semaphore.h
index c514062bb69e..735baaf3a16e 100644
--- a/include/asm-v850/semaphore.h
+++ b/include/asm-v850/semaphore.h
@@ -18,16 +18,13 @@ struct semaphore {
{ ATOMIC_INIT (count), 0, \
__WAIT_QUEUE_HEAD_INITIALIZER ((name).wait) }
-#define __MUTEX_INITIALIZER(name) \
- __SEMAPHORE_INITIALIZER (name,1)
-
#define __DECLARE_SEMAPHORE_GENERIC(name,count) \
struct semaphore name = __SEMAPHORE_INITIALIZER (name,count)
#define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC (name,1)
#define DECLARE_MUTEX_LOCKED(name) __DECLARE_SEMAPHORE_GENERIC (name,0)
-extern inline void sema_init (struct semaphore *sem, int val)
+static inline void sema_init (struct semaphore *sem, int val)
{
*sem = (struct semaphore)__SEMAPHORE_INITIALIZER((*sem),val);
}
@@ -55,14 +52,14 @@ extern int __down_interruptible (struct semaphore * sem);
extern int __down_trylock (struct semaphore * sem);
extern void __up (struct semaphore * sem);
-extern inline void down (struct semaphore * sem)
+static inline void down (struct semaphore * sem)
{
might_sleep();
if (atomic_dec_return (&sem->count) < 0)
__down (sem);
}
-extern inline int down_interruptible (struct semaphore * sem)
+static inline int down_interruptible (struct semaphore * sem)
{
int ret = 0;
might_sleep();
@@ -71,7 +68,7 @@ extern inline int down_interruptible (struct semaphore * sem)
return ret;
}
-extern inline int down_trylock (struct semaphore *sem)
+static inline int down_trylock (struct semaphore *sem)
{
int ret = 0;
if (atomic_dec_return (&sem->count) < 0)
@@ -79,7 +76,7 @@ extern inline int down_trylock (struct semaphore *sem)
return ret;
}
-extern inline void up (struct semaphore * sem)
+static inline void up (struct semaphore * sem)
{
if (atomic_inc_return (&sem->count) <= 0)
__up (sem);
diff --git a/include/asm-v850/system.h b/include/asm-v850/system.h
index 20f4c738c04e..107decbd6e6c 100644
--- a/include/asm-v850/system.h
+++ b/include/asm-v850/system.h
@@ -81,7 +81,7 @@ static inline int irqs_disabled (void)
((__typeof__ (*(ptr)))__xchg ((unsigned long)(with), (ptr), sizeof (*(ptr))))
#define tas(ptr) (xchg ((ptr), 1))
-extern inline unsigned long __xchg (unsigned long with,
+static inline unsigned long __xchg (unsigned long with,
__volatile__ void *ptr, int size)
{
unsigned long tmp, flags;
diff --git a/include/asm-v850/tlbflush.h b/include/asm-v850/tlbflush.h
index 501e4498172c..5f2f85f636ea 100644
--- a/include/asm-v850/tlbflush.h
+++ b/include/asm-v850/tlbflush.h
@@ -56,12 +56,12 @@ static inline void flush_tlb_range(struct vm_area_struct *vma,
BUG ();
}
-extern inline void flush_tlb_kernel_page(unsigned long addr)
+static inline void flush_tlb_kernel_page(unsigned long addr)
{
BUG ();
}
-extern inline void flush_tlb_pgtables(struct mm_struct *mm,
+static inline void flush_tlb_pgtables(struct mm_struct *mm,
unsigned long start, unsigned long end)
{
BUG ();
diff --git a/include/asm-v850/uaccess.h b/include/asm-v850/uaccess.h
index 188b28597cf1..64563c409bb2 100644
--- a/include/asm-v850/uaccess.h
+++ b/include/asm-v850/uaccess.h
@@ -14,7 +14,7 @@
#define VERIFY_READ 0
#define VERIFY_WRITE 1
-extern inline int access_ok (int type, const void *addr, unsigned long size)
+static inline int access_ok (int type, const void *addr, unsigned long size)
{
/* XXX I guess we should check against real ram bounds at least, and
possibly make sure ADDR is not within the kernel.
diff --git a/include/asm-v850/unaligned.h b/include/asm-v850/unaligned.h
index 65e38362142b..e30b18653a94 100644
--- a/include/asm-v850/unaligned.h
+++ b/include/asm-v850/unaligned.h
@@ -82,19 +82,19 @@ extern int __bug_unaligned_x(void *ptr);
})
-extern inline void __put_unaligned_2(__u32 __v, register __u8 *__p)
+static inline void __put_unaligned_2(__u32 __v, register __u8 *__p)
{
*__p++ = __v;
*__p++ = __v >> 8;
}
-extern inline void __put_unaligned_4(__u32 __v, register __u8 *__p)
+static inline void __put_unaligned_4(__u32 __v, register __u8 *__p)
{
__put_unaligned_2(__v >> 16, __p + 2);
__put_unaligned_2(__v, __p);
}
-extern inline void __put_unaligned_8(const unsigned long long __v, register __u8 *__p)
+static inline void __put_unaligned_8(const unsigned long long __v, register __u8 *__p)
{
/*
* tradeoff: 8 bytes of stack for all unaligned puts (2
diff --git a/include/asm-v850/unistd.h b/include/asm-v850/unistd.h
index 3b552096c0e8..5a86f8e976ec 100644
--- a/include/asm-v850/unistd.h
+++ b/include/asm-v850/unistd.h
@@ -452,7 +452,6 @@ unsigned long sys_mmap2(unsigned long addr, size_t len,
struct pt_regs;
int sys_execve (char *name, char **argv, char **envp, struct pt_regs *regs);
int sys_pipe (int *fildes);
-int sys_ptrace(long request, long pid, long addr, long data);
struct sigaction;
asmlinkage long sys_rt_sigaction(int sig,
const struct sigaction __user *act,
diff --git a/include/asm-x86_64/dma-mapping.h b/include/asm-x86_64/dma-mapping.h
index e784fdc524f1..36d16dfbac88 100644
--- a/include/asm-x86_64/dma-mapping.h
+++ b/include/asm-x86_64/dma-mapping.h
@@ -17,7 +17,7 @@ extern dma_addr_t bad_dma_address;
(swiotlb ? swiotlb_dma_mapping_error(x) : ((x) == bad_dma_address))
void *dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle,
- unsigned gfp);
+ gfp_t gfp);
void dma_free_coherent(struct device *dev, size_t size, void *vaddr,
dma_addr_t dma_handle);
@@ -85,10 +85,33 @@ static inline void dma_sync_single_for_device(struct device *hwdev,
flush_write_buffers();
}
-#define dma_sync_single_range_for_cpu(dev, dma_handle, offset, size, dir) \
- dma_sync_single_for_cpu(dev, dma_handle, size, dir)
-#define dma_sync_single_range_for_device(dev, dma_handle, offset, size, dir) \
- dma_sync_single_for_device(dev, dma_handle, size, dir)
+static inline void dma_sync_single_range_for_cpu(struct device *hwdev,
+ dma_addr_t dma_handle,
+ unsigned long offset,
+ size_t size, int direction)
+{
+ if (direction == DMA_NONE)
+ out_of_line_bug();
+
+ if (swiotlb)
+ return swiotlb_sync_single_range_for_cpu(hwdev,dma_handle,offset,size,direction);
+
+ flush_write_buffers();
+}
+
+static inline void dma_sync_single_range_for_device(struct device *hwdev,
+ dma_addr_t dma_handle,
+ unsigned long offset,
+ size_t size, int direction)
+{
+ if (direction == DMA_NONE)
+ out_of_line_bug();
+
+ if (swiotlb)
+ return swiotlb_sync_single_range_for_device(hwdev,dma_handle,offset,size,direction);
+
+ flush_write_buffers();
+}
static inline void dma_sync_sg_for_cpu(struct device *hwdev,
struct scatterlist *sg,
diff --git a/include/asm-x86_64/elf.h b/include/asm-x86_64/elf.h
index a60a35e79222..43862cd6a569 100644
--- a/include/asm-x86_64/elf.h
+++ b/include/asm-x86_64/elf.h
@@ -149,6 +149,8 @@ extern void set_personality_64bit(void);
*/
#define elf_read_implies_exec(ex, executable_stack) (executable_stack != EXSTACK_DISABLE_X)
+struct task_struct;
+
extern int dump_task_regs (struct task_struct *, elf_gregset_t *);
extern int dump_task_fpu (struct task_struct *, elf_fpregset_t *);
diff --git a/include/asm-x86_64/kprobes.h b/include/asm-x86_64/kprobes.h
index 6d6d883fdf6d..4dd7a7e148d4 100644
--- a/include/asm-x86_64/kprobes.h
+++ b/include/asm-x86_64/kprobes.h
@@ -25,6 +25,7 @@
*/
#include <linux/types.h>
#include <linux/ptrace.h>
+#include <linux/percpu.h>
struct pt_regs;
@@ -48,6 +49,24 @@ struct arch_specific_insn {
kprobe_opcode_t *insn;
};
+struct prev_kprobe {
+ struct kprobe *kp;
+ unsigned long status;
+ unsigned long old_rflags;
+ unsigned long saved_rflags;
+};
+
+/* per-cpu kprobe control block */
+struct kprobe_ctlblk {
+ unsigned long kprobe_status;
+ unsigned long kprobe_old_rflags;
+ unsigned long kprobe_saved_rflags;
+ long *jprobe_saved_rsp;
+ struct pt_regs jprobe_saved_regs;
+ kprobe_opcode_t jprobes_stack[MAX_STACK_SIZE];
+ struct prev_kprobe prev_kprobe;
+};
+
/* trap3/1 are intr gates for kprobes. So, restore the status of IF,
* if necessary, before executing the original int3/1 (trap) handler.
*/
diff --git a/include/asm-x86_64/msi.h b/include/asm-x86_64/msi.h
index 85c427e472bf..356e0e82f50b 100644
--- a/include/asm-x86_64/msi.h
+++ b/include/asm-x86_64/msi.h
@@ -11,8 +11,6 @@
#include <asm/smp.h>
#define LAST_DEVICE_VECTOR 232
-#define MSI_DEST_MODE MSI_LOGICAL_MODE
-#define MSI_TARGET_CPU_SHIFT 12
-#define MSI_TARGET_CPU logical_smp_processor_id()
+#define MSI_TARGET_CPU_SHIFT 12
#endif /* ASM_MSI_H */
diff --git a/include/asm-x86_64/mtrr.h b/include/asm-x86_64/mtrr.h
index c5959d6418bb..66ac1c0f27e1 100644
--- a/include/asm-x86_64/mtrr.h
+++ b/include/asm-x86_64/mtrr.h
@@ -25,6 +25,7 @@
#include <linux/config.h>
#include <linux/ioctl.h>
+#include <linux/compat.h>
#define MTRR_IOCTL_BASE 'M'
@@ -105,4 +106,36 @@ static __inline__ int mtrr_del_page (int reg, unsigned long base,
#endif
+#ifdef CONFIG_COMPAT
+
+struct mtrr_sentry32
+{
+ compat_ulong_t base; /* Base address */
+ compat_uint_t size; /* Size of region */
+ compat_uint_t type; /* Type of region */
+};
+
+struct mtrr_gentry32
+{
+ compat_ulong_t regnum; /* Register number */
+ compat_uint_t base; /* Base address */
+ compat_uint_t size; /* Size of region */
+ compat_uint_t type; /* Type of region */
+};
+
+#define MTRR_IOCTL_BASE 'M'
+
+#define MTRRIOC32_ADD_ENTRY _IOW(MTRR_IOCTL_BASE, 0, struct mtrr_sentry32)
+#define MTRRIOC32_SET_ENTRY _IOW(MTRR_IOCTL_BASE, 1, struct mtrr_sentry32)
+#define MTRRIOC32_DEL_ENTRY _IOW(MTRR_IOCTL_BASE, 2, struct mtrr_sentry32)
+#define MTRRIOC32_GET_ENTRY _IOWR(MTRR_IOCTL_BASE, 3, struct mtrr_gentry32)
+#define MTRRIOC32_KILL_ENTRY _IOW(MTRR_IOCTL_BASE, 4, struct mtrr_sentry32)
+#define MTRRIOC32_ADD_PAGE_ENTRY _IOW(MTRR_IOCTL_BASE, 5, struct mtrr_sentry32)
+#define MTRRIOC32_SET_PAGE_ENTRY _IOW(MTRR_IOCTL_BASE, 6, struct mtrr_sentry32)
+#define MTRRIOC32_DEL_PAGE_ENTRY _IOW(MTRR_IOCTL_BASE, 7, struct mtrr_sentry32)
+#define MTRRIOC32_GET_PAGE_ENTRY _IOWR(MTRR_IOCTL_BASE, 8, struct mtrr_gentry32)
+#define MTRRIOC32_KILL_PAGE_ENTRY _IOW(MTRR_IOCTL_BASE, 9, struct mtrr_sentry32)
+
+#endif /* CONFIG_COMPAT */
+
#endif /* _LINUX_MTRR_H */
diff --git a/include/asm-x86_64/pgtable.h b/include/asm-x86_64/pgtable.h
index dd8711ecaf2f..7309fffeec9a 100644
--- a/include/asm-x86_64/pgtable.h
+++ b/include/asm-x86_64/pgtable.h
@@ -105,6 +105,8 @@ static inline void pgd_clear (pgd_t * pgd)
#define ptep_get_and_clear(mm,addr,xp) __pte(xchg(&(xp)->pte, 0))
+struct mm_struct;
+
static inline pte_t ptep_get_and_clear_full(struct mm_struct *mm, unsigned long addr, pte_t *ptep, int full)
{
pte_t pte;
@@ -318,8 +320,6 @@ static inline int pmd_large(pmd_t pte) {
* and a page entry and page directory to the page they refer to.
*/
-#define page_pte(page) page_pte_prot(page, __pgprot(0))
-
/*
* Level 4 access.
*/
diff --git a/include/asm-x86_64/rwsem.h b/include/asm-x86_64/rwsem.h
index c002175b6e82..46077e9c1910 100644
--- a/include/asm-x86_64/rwsem.h
+++ b/include/asm-x86_64/rwsem.h
@@ -274,5 +274,10 @@ LOCK_PREFIX "xaddl %0,(%2)"
return tmp+delta;
}
+static inline int rwsem_is_locked(struct rw_semaphore *sem)
+{
+ return (sem->count != 0);
+}
+
#endif /* __KERNEL__ */
#endif /* _X8664_RWSEM_H */
diff --git a/include/asm-x86_64/semaphore.h b/include/asm-x86_64/semaphore.h
index f325e39bf3b9..a389aa6fe80f 100644
--- a/include/asm-x86_64/semaphore.h
+++ b/include/asm-x86_64/semaphore.h
@@ -56,9 +56,6 @@ struct semaphore {
.wait = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \
}
-#define __MUTEX_INITIALIZER(name) \
- __SEMAPHORE_INITIALIZER(name,1)
-
#define __DECLARE_SEMAPHORE_GENERIC(name,count) \
struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
diff --git a/include/asm-x86_64/smp.h b/include/asm-x86_64/smp.h
index c57ce4071342..b9fb2173ef99 100644
--- a/include/asm-x86_64/smp.h
+++ b/include/asm-x86_64/smp.h
@@ -135,5 +135,11 @@ static __inline int logical_smp_processor_id(void)
}
#endif
+#ifdef CONFIG_SMP
+#define cpu_physical_id(cpu) x86_cpu_to_apicid[cpu]
+#else
+#define cpu_physical_id(cpu) boot_cpu_id
+#endif
+
#endif
diff --git a/include/asm-x86_64/swiotlb.h b/include/asm-x86_64/swiotlb.h
index 36293061f4ed..dddf1b218681 100644
--- a/include/asm-x86_64/swiotlb.h
+++ b/include/asm-x86_64/swiotlb.h
@@ -15,6 +15,14 @@ extern void swiotlb_sync_single_for_cpu(struct device *hwdev,
extern void swiotlb_sync_single_for_device(struct device *hwdev,
dma_addr_t dev_addr,
size_t size, int dir);
+extern void swiotlb_sync_single_range_for_cpu(struct device *hwdev,
+ dma_addr_t dev_addr,
+ unsigned long offset,
+ size_t size, int dir);
+extern void swiotlb_sync_single_range_for_device(struct device *hwdev,
+ dma_addr_t dev_addr,
+ unsigned long offset,
+ size_t size, int dir);
extern void swiotlb_sync_sg_for_cpu(struct device *hwdev,
struct scatterlist *sg, int nelems,
int dir);
@@ -27,7 +35,7 @@ extern void swiotlb_unmap_sg(struct device *hwdev, struct scatterlist *sg,
int nents, int direction);
extern int swiotlb_dma_mapping_error(dma_addr_t dma_addr);
extern void *swiotlb_alloc_coherent (struct device *hwdev, size_t size,
- dma_addr_t *dma_handle, int flags);
+ dma_addr_t *dma_handle, gfp_t flags);
extern void swiotlb_free_coherent (struct device *hwdev, size_t size,
void *vaddr, dma_addr_t dma_handle);
diff --git a/include/asm-x86_64/unistd.h b/include/asm-x86_64/unistd.h
index 11ba931cf82f..3c494b65d33a 100644
--- a/include/asm-x86_64/unistd.h
+++ b/include/asm-x86_64/unistd.h
@@ -780,8 +780,6 @@ asmlinkage long sys_pipe(int *fildes);
#include <linux/types.h>
#include <asm/ptrace.h>
-asmlinkage long sys_ptrace(long request, long pid,
- unsigned long addr, long data);
asmlinkage long sys_iopl(unsigned int level, struct pt_regs *regs);
asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int turn_on);
struct sigaction;
diff --git a/include/asm-xtensa/dma-mapping.h b/include/asm-xtensa/dma-mapping.h
index e86a206f1209..c425f10d086a 100644
--- a/include/asm-xtensa/dma-mapping.h
+++ b/include/asm-xtensa/dma-mapping.h
@@ -28,7 +28,7 @@ extern void consistent_sync(void*, size_t, int);
#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
void *dma_alloc_coherent(struct device *dev, size_t size,
- dma_addr_t *dma_handle, int flag);
+ dma_addr_t *dma_handle, gfp_t flag);
void dma_free_coherent(struct device *dev, size_t size,
void *vaddr, dma_addr_t dma_handle);
diff --git a/include/asm-xtensa/elf.h b/include/asm-xtensa/elf.h
index 64f1f53874fe..de0667453b2e 100644
--- a/include/asm-xtensa/elf.h
+++ b/include/asm-xtensa/elf.h
@@ -209,6 +209,8 @@ extern void xtensa_elf_core_copy_regs (xtensa_gregset_t *, struct pt_regs *);
#define SET_PERSONALITY(ex, ibcs2) set_personality(PER_LINUX_32BIT)
+struct task_struct;
+
extern void do_copy_regs (xtensa_gregset_t*, struct pt_regs*,
struct task_struct*);
extern void do_restore_regs (xtensa_gregset_t*, struct pt_regs*,
diff --git a/include/asm-xtensa/pgtable.h b/include/asm-xtensa/pgtable.h
index 987e3b802313..7b15afb70c56 100644
--- a/include/asm-xtensa/pgtable.h
+++ b/include/asm-xtensa/pgtable.h
@@ -278,6 +278,8 @@ static inline void update_pte(pte_t *ptep, pte_t pteval)
#endif
}
+struct mm_struct;
+
static inline void
set_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pteval)
{
@@ -294,6 +296,7 @@ set_pmd(pmd_t *pmdp, pmd_t pmdval)
#endif
}
+struct vm_area_struct;
static inline int
ptep_test_and_clear_young(struct vm_area_struct *vma, unsigned long addr,
diff --git a/include/asm-xtensa/semaphore.h b/include/asm-xtensa/semaphore.h
index 09e89ab3eb61..f10c3487cd4c 100644
--- a/include/asm-xtensa/semaphore.h
+++ b/include/asm-xtensa/semaphore.h
@@ -29,9 +29,6 @@ struct semaphore {
.wait = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \
}
-#define __MUTEX_INITIALIZER(name) \
- __SEMAPHORE_INITIALIZER(name, 1)
-
#define __DECLARE_SEMAPHORE_GENERIC(name,count) \
struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
@@ -41,6 +38,7 @@ struct semaphore {
static inline void sema_init (struct semaphore *sem, int val)
{
atomic_set(&sem->count, val);
+ sem->sleepers = 0;
init_waitqueue_head(&sem->wait);
}
diff --git a/include/keys/user-type.h b/include/keys/user-type.h
new file mode 100644
index 000000000000..26f6ec38577a
--- /dev/null
+++ b/include/keys/user-type.h
@@ -0,0 +1,47 @@
+/* user-type.h: User-defined key type
+ *
+ * Copyright (C) 2005 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _KEYS_USER_TYPE_H
+#define _KEYS_USER_TYPE_H
+
+#include <linux/key.h>
+#include <linux/rcupdate.h>
+
+/*****************************************************************************/
+/*
+ * the payload for a key of type "user"
+ * - once filled in and attached to a key:
+ * - the payload struct is invariant may not be changed, only replaced
+ * - the payload must be read with RCU procedures or with the key semaphore
+ * held
+ * - the payload may only be replaced with the key semaphore write-locked
+ * - the key's data length is the size of the actual data, not including the
+ * payload wrapper
+ */
+struct user_key_payload {
+ struct rcu_head rcu; /* RCU destructor */
+ unsigned short datalen; /* length of this data */
+ char data[0]; /* actual data */
+};
+
+extern struct key_type key_type_user;
+
+extern int user_instantiate(struct key *key, const void *data, size_t datalen);
+extern int user_duplicate(struct key *key, const struct key *source);
+extern int user_update(struct key *key, const void *data, size_t datalen);
+extern int user_match(const struct key *key, const void *criterion);
+extern void user_destroy(struct key *key);
+extern void user_describe(const struct key *user, struct seq_file *m);
+extern long user_read(const struct key *key,
+ char __user *buffer, size_t buflen);
+
+
+#endif /* _KEYS_USER_TYPE_H */
diff --git a/include/linux/acct.h b/include/linux/acct.h
index 19f70462b3be..93c5b3cdf951 100644
--- a/include/linux/acct.h
+++ b/include/linux/acct.h
@@ -117,12 +117,15 @@ struct acct_v3
#include <linux/config.h>
#ifdef CONFIG_BSD_PROCESS_ACCT
+struct vfsmount;
struct super_block;
+extern void acct_auto_close_mnt(struct vfsmount *m);
extern void acct_auto_close(struct super_block *sb);
extern void acct_process(long exitcode);
extern void acct_update_integrals(struct task_struct *tsk);
extern void acct_clear_integrals(struct task_struct *tsk);
#else
+#define acct_auto_close_mnt(x) do { } while (0)
#define acct_auto_close(x) do { } while (0)
#define acct_process(x) do { } while (0)
#define acct_update_integrals(x) do { } while (0)
diff --git a/include/linux/aio.h b/include/linux/aio.h
index 0decf66117c1..403d71dcb7c8 100644
--- a/include/linux/aio.h
+++ b/include/linux/aio.h
@@ -183,6 +183,7 @@ struct kioctx {
struct list_head active_reqs; /* used for cancellation */
struct list_head run_list; /* used for kicked reqs */
+ /* sys_io_setup currently limits this to an unsigned int */
unsigned max_reqs;
struct aio_ring_info ring_info;
@@ -234,7 +235,7 @@ static inline struct kiocb *list_kiocb(struct list_head *h)
}
/* for sysctl: */
-extern atomic_t aio_nr;
-extern unsigned aio_max_nr;
+extern unsigned long aio_nr;
+extern unsigned long aio_max_nr;
#endif /* __LINUX__AIO_H */
diff --git a/include/linux/ata.h b/include/linux/ata.h
index a5b74efab067..d2873b732bb1 100644
--- a/include/linux/ata.h
+++ b/include/linux/ata.h
@@ -42,13 +42,18 @@ enum {
ATA_SECT_SIZE = 512,
ATA_ID_WORDS = 256,
- ATA_ID_PROD_OFS = 27,
- ATA_ID_FW_REV_OFS = 23,
ATA_ID_SERNO_OFS = 10,
- ATA_ID_MAJOR_VER = 80,
- ATA_ID_PIO_MODES = 64,
+ ATA_ID_FW_REV_OFS = 23,
+ ATA_ID_PROD_OFS = 27,
+ ATA_ID_OLD_PIO_MODES = 51,
+ ATA_ID_FIELD_VALID = 53,
ATA_ID_MWDMA_MODES = 63,
+ ATA_ID_PIO_MODES = 64,
+ ATA_ID_EIDE_DMA_MIN = 65,
+ ATA_ID_EIDE_PIO = 67,
+ ATA_ID_EIDE_PIO_IORDY = 68,
ATA_ID_UDMA_MODES = 88,
+ ATA_ID_MAJOR_VER = 80,
ATA_ID_PIO4 = (1 << 1),
ATA_PCI_CTL_OFS = 2,
@@ -128,10 +133,15 @@ enum {
ATA_CMD_PIO_READ_EXT = 0x24,
ATA_CMD_PIO_WRITE = 0x30,
ATA_CMD_PIO_WRITE_EXT = 0x34,
+ ATA_CMD_READ_MULTI = 0xC4,
+ ATA_CMD_READ_MULTI_EXT = 0x29,
+ ATA_CMD_WRITE_MULTI = 0xC5,
+ ATA_CMD_WRITE_MULTI_EXT = 0x39,
ATA_CMD_SET_FEATURES = 0xEF,
ATA_CMD_PACKET = 0xA0,
ATA_CMD_VERIFY = 0x40,
ATA_CMD_VERIFY_EXT = 0x42,
+ ATA_CMD_INIT_DEV_PARAMS = 0x91,
/* SETFEATURES stuff */
SETFEATURES_XFER = 0x03,
@@ -146,14 +156,14 @@ enum {
XFER_MW_DMA_2 = 0x22,
XFER_MW_DMA_1 = 0x21,
XFER_MW_DMA_0 = 0x20,
+ XFER_SW_DMA_2 = 0x12,
+ XFER_SW_DMA_1 = 0x11,
+ XFER_SW_DMA_0 = 0x10,
XFER_PIO_4 = 0x0C,
XFER_PIO_3 = 0x0B,
XFER_PIO_2 = 0x0A,
XFER_PIO_1 = 0x09,
XFER_PIO_0 = 0x08,
- XFER_SW_DMA_2 = 0x12,
- XFER_SW_DMA_1 = 0x11,
- XFER_SW_DMA_0 = 0x10,
XFER_PIO_SLOW = 0x00,
/* ATAPI stuff */
@@ -181,6 +191,7 @@ enum {
ATA_TFLAG_ISADDR = (1 << 1), /* enable r/w to nsect/lba regs */
ATA_TFLAG_DEVICE = (1 << 2), /* enable r/w to device reg */
ATA_TFLAG_WRITE = (1 << 3), /* data dir: host->dev==1 (write) */
+ ATA_TFLAG_LBA = (1 << 4), /* enable LBA */
};
enum ata_tf_protocols {
@@ -250,7 +261,19 @@ struct ata_taskfile {
((u64) (id)[(n) + 1] << 16) | \
((u64) (id)[(n) + 0]) )
-static inline int atapi_cdb_len(u16 *dev_id)
+static inline int ata_id_current_chs_valid(const u16 *id)
+{
+ /* For ATA-1 devices, if the INITIALIZE DEVICE PARAMETERS command
+ has not been issued to the device then the values of
+ id[54] to id[56] are vendor specific. */
+ return (id[53] & 0x01) && /* Current translation valid */
+ id[54] && /* cylinders in current translation */
+ id[55] && /* heads in current translation */
+ id[55] <= 16 &&
+ id[56]; /* sectors in current translation */
+}
+
+static inline int atapi_cdb_len(const u16 *dev_id)
{
u16 tmp = dev_id[0] & 0x3;
switch (tmp) {
@@ -260,7 +283,7 @@ static inline int atapi_cdb_len(u16 *dev_id)
}
}
-static inline int is_atapi_taskfile(struct ata_taskfile *tf)
+static inline int is_atapi_taskfile(const struct ata_taskfile *tf)
{
return (tf->protocol == ATA_PROT_ATAPI) ||
(tf->protocol == ATA_PROT_ATAPI_NODATA) ||
diff --git a/include/linux/audit.h b/include/linux/audit.h
index b2a2509bd7ea..da3c01955f3d 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -260,11 +260,11 @@ extern int audit_filter_user(struct netlink_skb_parms *cb, int type);
#ifdef CONFIG_AUDIT
/* These are defined in audit.c */
/* Public API */
-extern void audit_log(struct audit_context *ctx, int gfp_mask,
+extern void audit_log(struct audit_context *ctx, gfp_t gfp_mask,
int type, const char *fmt, ...)
__attribute__((format(printf,4,5)));
-extern struct audit_buffer *audit_log_start(struct audit_context *ctx, int gfp_mask, int type);
+extern struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp_mask, int type);
extern void audit_log_format(struct audit_buffer *ab,
const char *fmt, ...)
__attribute__((format(printf,2,3)));
diff --git a/include/linux/bio.h b/include/linux/bio.h
index 3344b4e8e43a..685fd3720df5 100644
--- a/include/linux/bio.h
+++ b/include/linux/bio.h
@@ -301,7 +301,7 @@ extern struct bio *bio_map_user_iov(struct request_queue *,
struct sg_iovec *, int, int);
extern void bio_unmap_user(struct bio *);
extern struct bio *bio_map_kern(struct request_queue *, void *, unsigned int,
- unsigned int);
+ gfp_t);
extern void bio_set_pages_dirty(struct bio *bio);
extern void bio_check_pages_dirty(struct bio *bio);
extern struct bio *bio_copy_user(struct request_queue *, unsigned long, unsigned int, int);
diff --git a/include/linux/bitmap.h b/include/linux/bitmap.h
index 86dd5502b05c..7d8ff97b3e92 100644
--- a/include/linux/bitmap.h
+++ b/include/linux/bitmap.h
@@ -40,6 +40,8 @@
* bitmap_weight(src, nbits) Hamming Weight: number set bits
* bitmap_shift_right(dst, src, n, nbits) *dst = *src >> n
* bitmap_shift_left(dst, src, n, nbits) *dst = *src << n
+ * bitmap_remap(dst, src, old, new, nbits) *dst = map(old, new)(src)
+ * bitmap_bitremap(oldbit, old, new, nbits) newbit = map(old, new)(oldbit)
* bitmap_scnprintf(buf, len, src, nbits) Print bitmap src to buf
* bitmap_parse(ubuf, ulen, dst, nbits) Parse bitmap dst from user buf
* bitmap_scnlistprintf(buf, len, src, nbits) Print bitmap src as list to buf
@@ -104,6 +106,10 @@ extern int bitmap_scnlistprintf(char *buf, unsigned int len,
const unsigned long *src, int nbits);
extern int bitmap_parselist(const char *buf, unsigned long *maskp,
int nmaskbits);
+extern void bitmap_remap(unsigned long *dst, const unsigned long *src,
+ const unsigned long *old, const unsigned long *new, int bits);
+extern int bitmap_bitremap(int oldbit,
+ const unsigned long *old, const unsigned long *new, int bits);
extern int bitmap_find_free_region(unsigned long *bitmap, int bits, int order);
extern void bitmap_release_region(unsigned long *bitmap, int pos, int order);
extern int bitmap_allocate_region(unsigned long *bitmap, int pos, int order);
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index efdc9b5bc05c..025a7f084dbd 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -96,8 +96,8 @@ struct io_context {
void put_io_context(struct io_context *ioc);
void exit_io_context(void);
-struct io_context *current_io_context(int gfp_flags);
-struct io_context *get_io_context(int gfp_flags);
+struct io_context *current_io_context(gfp_t gfp_flags);
+struct io_context *get_io_context(gfp_t gfp_flags);
void copy_io_context(struct io_context **pdst, struct io_context **psrc);
void swap_io_context(struct io_context **ioc1, struct io_context **ioc2);
@@ -107,9 +107,9 @@ typedef void (rq_end_io_fn)(struct request *);
struct request_list {
int count[2];
int starved[2];
+ int elvpriv;
mempool_t *rq_pool;
wait_queue_head_t wait[2];
- wait_queue_head_t drain;
};
#define BLK_MAX_CDB 16
@@ -203,6 +203,7 @@ struct request {
enum rq_flag_bits {
__REQ_RW, /* not set, read. set, write */
__REQ_FAILFAST, /* no low level driver retries */
+ __REQ_SORTED, /* elevator knows about this request */
__REQ_SOFTBARRIER, /* may not be passed by ioscheduler */
__REQ_HARDBARRIER, /* may not be passed by drive either */
__REQ_CMD, /* is a regular fs rw request */
@@ -210,6 +211,7 @@ enum rq_flag_bits {
__REQ_STARTED, /* drive already may have started this one */
__REQ_DONTPREP, /* don't call prep for this one */
__REQ_QUEUED, /* uses queueing */
+ __REQ_ELVPRIV, /* elevator private data attached */
/*
* for ATA/ATAPI devices
*/
@@ -235,6 +237,7 @@ enum rq_flag_bits {
#define REQ_RW (1 << __REQ_RW)
#define REQ_FAILFAST (1 << __REQ_FAILFAST)
+#define REQ_SORTED (1 << __REQ_SORTED)
#define REQ_SOFTBARRIER (1 << __REQ_SOFTBARRIER)
#define REQ_HARDBARRIER (1 << __REQ_HARDBARRIER)
#define REQ_CMD (1 << __REQ_CMD)
@@ -242,6 +245,7 @@ enum rq_flag_bits {
#define REQ_STARTED (1 << __REQ_STARTED)
#define REQ_DONTPREP (1 << __REQ_DONTPREP)
#define REQ_QUEUED (1 << __REQ_QUEUED)
+#define REQ_ELVPRIV (1 << __REQ_ELVPRIV)
#define REQ_PC (1 << __REQ_PC)
#define REQ_BLOCK_PC (1 << __REQ_BLOCK_PC)
#define REQ_SENSE (1 << __REQ_SENSE)
@@ -333,6 +337,12 @@ struct request_queue
end_flush_fn *end_flush_fn;
/*
+ * Dispatch queue sorting
+ */
+ sector_t end_sector;
+ struct request *boundary_rq;
+
+ /*
* Auto-unplugging state
*/
struct timer_list unplug_timer;
@@ -354,7 +364,7 @@ struct request_queue
* queue needs bounce pages for pages above this limit
*/
unsigned long bounce_pfn;
- unsigned int bounce_gfp;
+ gfp_t bounce_gfp;
/*
* various queue flags, see QUEUE_* below
@@ -405,8 +415,6 @@ struct request_queue
unsigned int sg_reserved_size;
int node;
- struct list_head drain_list;
-
/*
* reserved for flush operations
*/
@@ -434,7 +442,7 @@ enum {
#define QUEUE_FLAG_DEAD 5 /* queue being torn down */
#define QUEUE_FLAG_REENTER 6 /* Re-entrancy avoidance */
#define QUEUE_FLAG_PLUGGED 7 /* queue is plugged */
-#define QUEUE_FLAG_DRAIN 8 /* draining queue for sched switch */
+#define QUEUE_FLAG_ELVSWITCH 8 /* don't use elevator, just do FIFO */
#define QUEUE_FLAG_FLUSH 9 /* doing barrier flush sequence */
#define blk_queue_plugged(q) test_bit(QUEUE_FLAG_PLUGGED, &(q)->queue_flags)
@@ -454,6 +462,7 @@ enum {
#define blk_pm_request(rq) \
((rq)->flags & (REQ_PM_SUSPEND | REQ_PM_RESUME))
+#define blk_sorted_rq(rq) ((rq)->flags & REQ_SORTED)
#define blk_barrier_rq(rq) ((rq)->flags & REQ_HARDBARRIER)
#define blk_barrier_preflush(rq) ((rq)->flags & REQ_BAR_PREFLUSH)
#define blk_barrier_postflush(rq) ((rq)->flags & REQ_BAR_POSTFLUSH)
@@ -550,7 +559,7 @@ extern void generic_make_request(struct bio *bio);
extern void blk_put_request(struct request *);
extern void blk_end_sync_rq(struct request *rq);
extern void blk_attempt_remerge(request_queue_t *, struct request *);
-extern struct request *blk_get_request(request_queue_t *, int, int);
+extern struct request *blk_get_request(request_queue_t *, int, gfp_t);
extern void blk_insert_request(request_queue_t *, struct request *, int, void *);
extern void blk_requeue_request(request_queue_t *, struct request *);
extern void blk_plug_device(request_queue_t *);
@@ -565,7 +574,7 @@ extern void blk_run_queue(request_queue_t *);
extern void blk_queue_activity_fn(request_queue_t *, activity_fn *, void *);
extern int blk_rq_map_user(request_queue_t *, struct request *, void __user *, unsigned int);
extern int blk_rq_unmap_user(struct bio *, unsigned int);
-extern int blk_rq_map_kern(request_queue_t *, struct request *, void *, unsigned int, unsigned int);
+extern int blk_rq_map_kern(request_queue_t *, struct request *, void *, unsigned int, gfp_t);
extern int blk_rq_map_user_iov(request_queue_t *, struct request *, struct sg_iovec *, int);
extern int blk_execute_rq(request_queue_t *, struct gendisk *,
struct request *, int);
@@ -611,12 +620,21 @@ extern void end_request(struct request *req, int uptodate);
static inline void blkdev_dequeue_request(struct request *req)
{
- BUG_ON(list_empty(&req->queuelist));
+ elv_dequeue_request(req->q, req);
+}
- list_del_init(&req->queuelist);
+/*
+ * This should be in elevator.h, but that requires pulling in rq and q
+ */
+static inline void elv_dispatch_add_tail(struct request_queue *q,
+ struct request *rq)
+{
+ if (q->last_merge == rq)
+ q->last_merge = NULL;
- if (req->rl)
- elv_remove_request(req->q, req);
+ q->end_sector = rq_end_sector(rq);
+ q->boundary_rq = rq;
+ list_add_tail(&rq->queuelist, &q->queue_head);
}
/*
@@ -650,12 +668,10 @@ extern void blk_dump_rq_flags(struct request *, char *);
extern void generic_unplug_device(request_queue_t *);
extern void __generic_unplug_device(request_queue_t *);
extern long nr_blockdev_pages(void);
-extern void blk_wait_queue_drained(request_queue_t *, int);
-extern void blk_finish_queue_drain(request_queue_t *);
int blk_get_queue(request_queue_t *);
-request_queue_t *blk_alloc_queue(int gfp_mask);
-request_queue_t *blk_alloc_queue_node(int,int);
+request_queue_t *blk_alloc_queue(gfp_t);
+request_queue_t *blk_alloc_queue_node(gfp_t, int);
#define blk_put_queue(q) blk_cleanup_queue((q))
/*
diff --git a/include/linux/buffer_head.h b/include/linux/buffer_head.h
index 6a1d154c0825..1db061bb6b08 100644
--- a/include/linux/buffer_head.h
+++ b/include/linux/buffer_head.h
@@ -126,8 +126,8 @@ BUFFER_FNS(Eopnotsupp, eopnotsupp)
/* If we *know* page->private refers to buffer_heads */
#define page_buffers(page) \
({ \
- BUG_ON(!PagePrivate(page)); \
- ((struct buffer_head *)(page)->private); \
+ BUG_ON(!PagePrivate(page)); \
+ ((struct buffer_head *)page_private(page)); \
})
#define page_has_buffers(page) PagePrivate(page)
@@ -188,8 +188,9 @@ extern int buffer_heads_over_limit;
* Generic address_space_operations implementations for buffer_head-backed
* address_spaces.
*/
-int try_to_release_page(struct page * page, int gfp_mask);
+int try_to_release_page(struct page * page, gfp_t gfp_mask);
int block_invalidatepage(struct page *page, unsigned long offset);
+int do_invalidatepage(struct page *page, unsigned long offset);
int block_write_full_page(struct page *page, get_block_t *get_block,
struct writeback_control *wbc);
int block_read_full_page(struct page*, get_block_t*);
@@ -219,7 +220,7 @@ static inline void attach_page_buffers(struct page *page,
{
page_cache_get(page);
SetPagePrivate(page);
- page->private = (unsigned long)head;
+ set_page_private(page, (unsigned long)head);
}
static inline void get_bh(struct buffer_head *bh)
diff --git a/include/linux/cn_proc.h b/include/linux/cn_proc.h
new file mode 100644
index 000000000000..70ab56317380
--- /dev/null
+++ b/include/linux/cn_proc.h
@@ -0,0 +1,127 @@
+/*
+ * cn_proc.h - process events connector
+ *
+ * Copyright (C) Matt Helsley, IBM Corp. 2005
+ * Based on cn_fork.h by Nguyen Anh Quynh and Guillaume Thouvenin
+ * Original copyright notice follows:
+ * Copyright (C) 2005 Nguyen Anh Quynh <aquynh@gmail.com>
+ * Copyright (C) 2005 Guillaume Thouvenin <guillaume.thouvenin@bull.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.
+ *
+ * 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 CN_PROC_H
+#define CN_PROC_H
+
+#include <linux/types.h>
+#include <linux/connector.h>
+
+/*
+ * Userspace sends this enum to register with the kernel that it is listening
+ * for events on the connector.
+ */
+enum proc_cn_mcast_op {
+ PROC_CN_MCAST_LISTEN = 1,
+ PROC_CN_MCAST_IGNORE = 2
+};
+
+/*
+ * From the user's point of view, the process
+ * ID is the thread group ID and thread ID is the internal
+ * kernel "pid". So, fields are assigned as follow:
+ *
+ * In user space - In kernel space
+ *
+ * parent process ID = parent->tgid
+ * parent thread ID = parent->pid
+ * child process ID = child->tgid
+ * child thread ID = child->pid
+ */
+
+struct proc_event {
+ enum what {
+ /* Use successive bits so the enums can be used to record
+ * sets of events as well
+ */
+ PROC_EVENT_NONE = 0x00000000,
+ PROC_EVENT_FORK = 0x00000001,
+ PROC_EVENT_EXEC = 0x00000002,
+ PROC_EVENT_UID = 0x00000004,
+ PROC_EVENT_GID = 0x00000040,
+ /* "next" should be 0x00000400 */
+ /* "last" is the last process event: exit */
+ PROC_EVENT_EXIT = 0x80000000
+ } what;
+ __u32 cpu;
+ union { /* must be last field of proc_event struct */
+ struct {
+ __u32 err;
+ } ack;
+
+ struct fork_proc_event {
+ pid_t parent_pid;
+ pid_t parent_tgid;
+ pid_t child_pid;
+ pid_t child_tgid;
+ } fork;
+
+ struct exec_proc_event {
+ pid_t process_pid;
+ pid_t process_tgid;
+ } exec;
+
+ struct id_proc_event {
+ pid_t process_pid;
+ pid_t process_tgid;
+ union {
+ uid_t ruid; /* current->uid */
+ gid_t rgid; /* current->gid */
+ } r;
+ union {
+ uid_t euid;
+ gid_t egid;
+ } e;
+ } id;
+
+ struct exit_proc_event {
+ pid_t process_pid;
+ pid_t process_tgid;
+ __u32 exit_code, exit_signal;
+ } exit;
+ } event_data;
+};
+
+#ifdef __KERNEL__
+#ifdef CONFIG_PROC_EVENTS
+void proc_fork_connector(struct task_struct *task);
+void proc_exec_connector(struct task_struct *task);
+void proc_id_connector(struct task_struct *task, int which_id);
+void proc_exit_connector(struct task_struct *task);
+#else
+static inline void proc_fork_connector(struct task_struct *task)
+{}
+
+static inline void proc_exec_connector(struct task_struct *task)
+{}
+
+static inline void proc_id_connector(struct task_struct *task,
+ int which_id)
+{}
+
+static inline void proc_exit_connector(struct task_struct *task)
+{}
+#endif /* CONFIG_PROC_EVENTS */
+#endif /* __KERNEL__ */
+#endif /* CN_PROC_H */
diff --git a/include/linux/compat_ioctl.h b/include/linux/compat_ioctl.h
index ecb0d39c0798..2209ad3499a3 100644
--- a/include/linux/compat_ioctl.h
+++ b/include/linux/compat_ioctl.h
@@ -10,6 +10,10 @@
#define ULONG_IOCTL(cmd) HANDLE_IOCTL((cmd),(ioctl_trans_handler_t)sys_ioctl)
#endif
+
+COMPATIBLE_IOCTL(0x4B50) /* KDGHWCLK - not in the kernel, but don't complain */
+COMPATIBLE_IOCTL(0x4B51) /* KDSHWCLK - not in the kernel, but don't complain */
+
/* Big T */
COMPATIBLE_IOCTL(TCGETA)
COMPATIBLE_IOCTL(TCSETA)
@@ -52,13 +56,6 @@ ULONG_IOCTL(TIOCSCTTY)
COMPATIBLE_IOCTL(TIOCGPTN)
COMPATIBLE_IOCTL(TIOCSPTLCK)
COMPATIBLE_IOCTL(TIOCSERGETLSR)
-/* Big F */
-COMPATIBLE_IOCTL(FBIOBLANK)
-COMPATIBLE_IOCTL(FBIOGET_VSCREENINFO)
-COMPATIBLE_IOCTL(FBIOPUT_VSCREENINFO)
-COMPATIBLE_IOCTL(FBIOPAN_DISPLAY)
-COMPATIBLE_IOCTL(FBIOGET_CON2FBMAP)
-COMPATIBLE_IOCTL(FBIOPUT_CON2FBMAP)
/* Little f */
COMPATIBLE_IOCTL(FIOCLEX)
COMPATIBLE_IOCTL(FIONCLEX)
@@ -81,6 +78,8 @@ COMPATIBLE_IOCTL(HDIO_DRIVE_CMD)
COMPATIBLE_IOCTL(HDIO_DRIVE_TASK)
COMPATIBLE_IOCTL(HDIO_SET_PIO_MODE)
COMPATIBLE_IOCTL(HDIO_SET_NICE)
+COMPATIBLE_IOCTL(HDIO_SET_KEEPSETTINGS)
+COMPATIBLE_IOCTL(HDIO_SCAN_HWIF)
/* 0x02 -- Floppy ioctls */
COMPATIBLE_IOCTL(FDMSGON)
COMPATIBLE_IOCTL(FDMSGOFF)
@@ -99,6 +98,7 @@ COMPATIBLE_IOCTL(FDTWADDLE)
COMPATIBLE_IOCTL(FDFMTTRK)
COMPATIBLE_IOCTL(FDRAWCMD)
/* 0x12 */
+COMPATIBLE_IOCTL(BLKRASET)
COMPATIBLE_IOCTL(BLKROSET)
COMPATIBLE_IOCTL(BLKROGET)
COMPATIBLE_IOCTL(BLKRRPART)
@@ -262,6 +262,7 @@ COMPATIBLE_IOCTL(RTC_WKALM_RD)
/* Little m */
COMPATIBLE_IOCTL(MTIOCTOP)
/* Socket level stuff */
+COMPATIBLE_IOCTL(FIOQSIZE)
COMPATIBLE_IOCTL(FIOSETOWN)
COMPATIBLE_IOCTL(SIOCSPGRP)
COMPATIBLE_IOCTL(FIOGETOWN)
diff --git a/include/linux/config.h b/include/linux/config.h
index 9d1c14f7ad6d..a91f5e55b525 100644
--- a/include/linux/config.h
+++ b/include/linux/config.h
@@ -1,6 +1,8 @@
#ifndef _LINUX_CONFIG_H
#define _LINUX_CONFIG_H
-
+/* This file is no longer in use and kept only for backward compatibility.
+ * autoconf.h is now included via -imacros on the commandline
+ */
#include <linux/autoconf.h>
#endif
diff --git a/include/linux/connector.h b/include/linux/connector.h
index 95952cc1f525..ad1a22c1c42e 100644
--- a/include/linux/connector.h
+++ b/include/linux/connector.h
@@ -27,6 +27,14 @@
#define CN_IDX_CONNECTOR 0xffffffff
#define CN_VAL_CONNECTOR 0xffffffff
+/*
+ * Process Events connector unique ids -- used for message routing
+ */
+#define CN_IDX_PROC 0x1
+#define CN_VAL_PROC 0x1
+#define CN_IDX_CIFS 0x2
+#define CN_VAL_CIFS 0x1
+
#define CN_NETLINK_USERS 1
/*
diff --git a/include/linux/console_struct.h b/include/linux/console_struct.h
index 725be90ef55e..f8e5587a0f92 100644
--- a/include/linux/console_struct.h
+++ b/include/linux/console_struct.h
@@ -9,6 +9,8 @@
* to achieve effects such as fast scrolling by changing the origin.
*/
+#include <linux/vt.h>
+
struct vt_struct;
#define NPAR 16
diff --git a/include/linux/cpu.h b/include/linux/cpu.h
index 86980c68234a..43c44530ef9d 100644
--- a/include/linux/cpu.h
+++ b/include/linux/cpu.h
@@ -32,6 +32,7 @@ struct cpu {
};
extern int register_cpu(struct cpu *, int, struct node *);
+extern struct sys_device *get_cpu_sysdev(int cpu);
#ifdef CONFIG_HOTPLUG_CPU
extern void unregister_cpu(struct cpu *, struct node *);
#endif
@@ -41,6 +42,7 @@ struct notifier_block;
/* Need to know about CPUs going up/down? */
extern int register_cpu_notifier(struct notifier_block *nb);
extern void unregister_cpu_notifier(struct notifier_block *nb);
+extern int current_in_cpu_hotplug(void);
int cpu_up(unsigned int cpu);
@@ -53,6 +55,10 @@ static inline int register_cpu_notifier(struct notifier_block *nb)
static inline void unregister_cpu_notifier(struct notifier_block *nb)
{
}
+static inline int current_in_cpu_hotplug(void)
+{
+ return 0;
+}
#endif /* CONFIG_SMP */
extern struct sysdev_class cpu_sysdev_class;
diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h
index ff7f80f48df1..d068176b7ad7 100644
--- a/include/linux/cpufreq.h
+++ b/include/linux/cpufreq.h
@@ -23,6 +23,7 @@
#include <linux/completion.h>
#include <linux/workqueue.h>
#include <linux/cpumask.h>
+#include <asm/div64.h>
#define CPUFREQ_NAME_LEN 16
diff --git a/include/linux/cpumask.h b/include/linux/cpumask.h
index 9bdba8169b41..13e9f4a3ab26 100644
--- a/include/linux/cpumask.h
+++ b/include/linux/cpumask.h
@@ -12,6 +12,8 @@
* see bitmap_scnprintf() and bitmap_parse() in lib/bitmap.c.
* For details of cpulist_scnprintf() and cpulist_parse(), see
* bitmap_scnlistprintf() and bitmap_parselist(), also in bitmap.c.
+ * For details of cpu_remap(), see bitmap_bitremap in lib/bitmap.c
+ * For details of cpus_remap(), see bitmap_remap in lib/bitmap.c.
*
* The available cpumask operations are:
*
@@ -50,6 +52,8 @@
* int cpumask_parse(ubuf, ulen, mask) Parse ascii string as cpumask
* int cpulist_scnprintf(buf, len, mask) Format cpumask as list for printing
* int cpulist_parse(buf, map) Parse ascii string as cpulist
+ * int cpu_remap(oldbit, old, new) newbit = map(old, new)(oldbit)
+ * int cpus_remap(dst, src, old, new) *dst = map(old, new)(src)
*
* for_each_cpu_mask(cpu, mask) for-loop cpu over mask
*
@@ -294,6 +298,22 @@ static inline int __cpulist_parse(const char *buf, cpumask_t *dstp, int nbits)
return bitmap_parselist(buf, dstp->bits, nbits);
}
+#define cpu_remap(oldbit, old, new) \
+ __cpu_remap((oldbit), &(old), &(new), NR_CPUS)
+static inline int __cpu_remap(int oldbit,
+ const cpumask_t *oldp, const cpumask_t *newp, int nbits)
+{
+ return bitmap_bitremap(oldbit, oldp->bits, newp->bits, nbits);
+}
+
+#define cpus_remap(dst, src, old, new) \
+ __cpus_remap(&(dst), &(src), &(old), &(new), NR_CPUS)
+static inline void __cpus_remap(cpumask_t *dstp, const cpumask_t *srcp,
+ const cpumask_t *oldp, const cpumask_t *newp, int nbits)
+{
+ bitmap_remap(dstp->bits, srcp->bits, oldp->bits, newp->bits, nbits);
+}
+
#if NR_CPUS > 1
#define for_each_cpu_mask(cpu, mask) \
for ((cpu) = first_cpu(mask); \
diff --git a/include/linux/cyclomx.h b/include/linux/cyclomx.h
index 04fa7dff079c..300d704bdb9a 100644
--- a/include/linux/cyclomx.h
+++ b/include/linux/cyclomx.h
@@ -37,8 +37,6 @@
#include <linux/cycx_x25.h>
#endif
-#define is_digit(ch) (((ch)>=(unsigned)'0'&&(ch)<=(unsigned)'9')?1:0)
-
/* Adapter Data Space.
* This structure is needed because we handle multiple cards, otherwise
* static data would do it.
diff --git a/include/linux/cycx_drv.h b/include/linux/cycx_drv.h
index 6621df86a748..12fe6b0bfcff 100644
--- a/include/linux/cycx_drv.h
+++ b/include/linux/cycx_drv.h
@@ -60,6 +60,5 @@ extern int cycx_peek(struct cycx_hw *hw, u32 addr, void *buf, u32 len);
extern int cycx_poke(struct cycx_hw *hw, u32 addr, void *buf, u32 len);
extern int cycx_exec(void __iomem *addr);
-extern void cycx_inten(struct cycx_hw *hw);
extern void cycx_intr(struct cycx_hw *hw);
#endif /* _CYCX_DRV_H */
diff --git a/include/linux/dcache.h b/include/linux/dcache.h
index ab04b4f9b0db..46a2ba617595 100644
--- a/include/linux/dcache.h
+++ b/include/linux/dcache.h
@@ -329,6 +329,7 @@ static inline int d_mountpoint(struct dentry *dentry)
}
extern struct vfsmount *lookup_mnt(struct vfsmount *, struct dentry *);
+extern struct vfsmount *__lookup_mnt(struct vfsmount *, struct dentry *, int);
extern struct dentry *lookup_create(struct nameidata *nd, int is_dir);
extern int sysctl_vfs_cache_pressure;
diff --git a/include/linux/device.h b/include/linux/device.h
index 95d607a48f06..17cbc6db67b4 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -28,19 +28,6 @@
#define BUS_ID_SIZE KOBJ_NAME_LEN
-enum {
- SUSPEND_NOTIFY,
- SUSPEND_SAVE_STATE,
- SUSPEND_DISABLE,
- SUSPEND_POWER_DOWN,
-};
-
-enum {
- RESUME_POWER_ON,
- RESUME_RESTORE_STATE,
- RESUME_ENABLE,
-};
-
struct device;
struct device_driver;
struct class;
@@ -115,8 +102,8 @@ struct device_driver {
int (*probe) (struct device * dev);
int (*remove) (struct device * dev);
void (*shutdown) (struct device * dev);
- int (*suspend) (struct device * dev, pm_message_t state, u32 level);
- int (*resume) (struct device * dev, u32 level);
+ int (*suspend) (struct device * dev, pm_message_t state);
+ int (*resume) (struct device * dev);
};
@@ -190,7 +177,43 @@ struct class_attribute class_attr_##_name = __ATTR(_name,_mode,_show,_store)
extern int class_create_file(struct class *, const struct class_attribute *);
extern void class_remove_file(struct class *, const struct class_attribute *);
+struct class_device_attribute {
+ struct attribute attr;
+ ssize_t (*show)(struct class_device *, char * buf);
+ ssize_t (*store)(struct class_device *, const char * buf, size_t count);
+};
+#define CLASS_DEVICE_ATTR(_name,_mode,_show,_store) \
+struct class_device_attribute class_device_attr_##_name = \
+ __ATTR(_name,_mode,_show,_store)
+
+extern int class_device_create_file(struct class_device *,
+ const struct class_device_attribute *);
+
+/**
+ * struct class_device - class devices
+ * @class: pointer to the parent class for this class device. This is required.
+ * @devt: for internal use by the driver core only.
+ * @node: for internal use by the driver core only.
+ * @kobj: for internal use by the driver core only.
+ * @devt_attr: for internal use by the driver core only.
+ * @dev: if set, a symlink to the struct device is created in the sysfs
+ * directory for this struct class device.
+ * @class_data: pointer to whatever you want to store here for this struct
+ * class_device. Use class_get_devdata() and class_set_devdata() to get and
+ * set this pointer.
+ * @parent: pointer to a struct class_device that is the parent of this struct
+ * class_device. If NULL, this class_device will show up at the root of the
+ * struct class in sysfs (which is probably what you want to have happen.)
+ * @release: pointer to a release function for this struct class_device. If
+ * set, this will be called instead of the class specific release function.
+ * Only use this if you want to override the default release function, like
+ * when you are nesting class_device structures.
+ * @hotplug: pointer to a hotplug function for this struct class_device. If
+ * set, this will be called instead of the class specific hotplug function.
+ * Only use this if you want to override the default hotplug function, like
+ * when you are nesting class_device structures.
+ */
struct class_device {
struct list_head node;
@@ -198,9 +221,14 @@ struct class_device {
struct class * class; /* required */
dev_t devt; /* dev_t, creates the sysfs "dev" */
struct class_device_attribute *devt_attr;
+ struct class_device_attribute uevent_attr;
struct device * dev; /* not necessary, but nice to have */
void * class_data; /* class-specific data */
+ struct class_device *parent; /* parent of this child device, if there is one */
+ void (*release)(struct class_device *dev);
+ int (*hotplug)(struct class_device *dev, char **envp,
+ int num_envp, char *buffer, int buffer_size);
char class_id[BUS_ID_SIZE]; /* unique to this class */
};
@@ -228,18 +256,6 @@ extern int class_device_rename(struct class_device *, char *);
extern struct class_device * class_device_get(struct class_device *);
extern void class_device_put(struct class_device *);
-struct class_device_attribute {
- struct attribute attr;
- ssize_t (*show)(struct class_device *, char * buf);
- ssize_t (*store)(struct class_device *, const char * buf, size_t count);
-};
-
-#define CLASS_DEVICE_ATTR(_name,_mode,_show,_store) \
-struct class_device_attribute class_device_attr_##_name = \
- __ATTR(_name,_mode,_show,_store)
-
-extern int class_device_create_file(struct class_device *,
- const struct class_device_attribute *);
extern void class_device_remove_file(struct class_device *,
const struct class_device_attribute *);
extern int class_device_create_bin_file(struct class_device *,
@@ -251,8 +267,8 @@ struct class_interface {
struct list_head node;
struct class *class;
- int (*add) (struct class_device *);
- void (*remove) (struct class_device *);
+ int (*add) (struct class_device *, struct class_interface *);
+ void (*remove) (struct class_device *, struct class_interface *);
};
extern int class_interface_register(struct class_interface *);
@@ -260,12 +276,29 @@ extern void class_interface_unregister(struct class_interface *);
extern struct class *class_create(struct module *owner, char *name);
extern void class_destroy(struct class *cls);
-extern struct class_device *class_device_create(struct class *cls, dev_t devt,
- struct device *device, char *fmt, ...)
- __attribute__((format(printf,4,5)));
+extern struct class_device *class_device_create(struct class *cls,
+ struct class_device *parent,
+ dev_t devt,
+ struct device *device,
+ char *fmt, ...)
+ __attribute__((format(printf,5,6)));
extern void class_device_destroy(struct class *cls, dev_t devt);
+/* interface for exporting device attributes */
+struct device_attribute {
+ struct attribute attr;
+ ssize_t (*show)(struct device *dev, struct device_attribute *attr,
+ char *buf);
+ ssize_t (*store)(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count);
+};
+
+#define DEVICE_ATTR(_name,_mode,_show,_store) \
+struct device_attribute dev_attr_##_name = __ATTR(_name,_mode,_show,_store)
+
+extern int device_create_file(struct device *device, struct device_attribute * entry);
+extern void device_remove_file(struct device * dev, struct device_attribute * attr);
struct device {
struct klist klist_children;
struct klist_node knode_parent; /* node in sibling list */
@@ -275,6 +308,7 @@ struct device {
struct kobject kobj;
char bus_id[BUS_ID_SIZE]; /* position on parent bus */
+ struct device_attribute uevent_attr;
struct semaphore sem; /* semaphore to synchronize calls to
* its driver.
@@ -343,23 +377,6 @@ extern int device_attach(struct device * dev);
extern void driver_attach(struct device_driver * drv);
-/* driverfs interface for exporting device attributes */
-
-struct device_attribute {
- struct attribute attr;
- ssize_t (*show)(struct device *dev, struct device_attribute *attr,
- char *buf);
- ssize_t (*store)(struct device *dev, struct device_attribute *attr,
- const char *buf, size_t count);
-};
-
-#define DEVICE_ATTR(_name,_mode,_show,_store) \
-struct device_attribute dev_attr_##_name = __ATTR(_name,_mode,_show,_store)
-
-
-extern int device_create_file(struct device *device, struct device_attribute * entry);
-extern void device_remove_file(struct device * dev, struct device_attribute * attr);
-
/*
* Platform "fixup" functions - allow the platform to have their say
* about devices and actions that the general device layer doesn't
@@ -379,32 +396,6 @@ extern struct device * get_device(struct device * dev);
extern void put_device(struct device * dev);
-/* drivers/base/platform.c */
-
-struct platform_device {
- const char * name;
- u32 id;
- struct device dev;
- u32 num_resources;
- struct resource * resource;
-};
-
-#define to_platform_device(x) container_of((x), struct platform_device, dev)
-
-extern int platform_device_register(struct platform_device *);
-extern void platform_device_unregister(struct platform_device *);
-
-extern struct bus_type platform_bus_type;
-extern struct device platform_bus;
-
-extern struct resource *platform_get_resource(struct platform_device *, unsigned int, unsigned int);
-extern int platform_get_irq(struct platform_device *, unsigned int);
-extern struct resource *platform_get_resource_byname(struct platform_device *, unsigned int, char *);
-extern int platform_get_irq_byname(struct platform_device *, char *);
-extern int platform_add_devices(struct platform_device **, int);
-
-extern struct platform_device *platform_device_register_simple(char *, unsigned int, struct resource *, unsigned int);
-
/* drivers/base/power.c */
extern void device_shutdown(void);
diff --git a/include/linux/dmi.h b/include/linux/dmi.h
index a415f1d93e9a..05f4132622fc 100644
--- a/include/linux/dmi.h
+++ b/include/linux/dmi.h
@@ -60,7 +60,7 @@ struct dmi_device {
void *device_data; /* Type specific data */
};
-#if defined(CONFIG_X86) && !defined(CONFIG_X86_64)
+#if defined(CONFIG_X86_32)
extern int dmi_check_system(struct dmi_system_id *list);
extern char * dmi_get_system_info(int field);
diff --git a/include/linux/dqblk_xfs.h b/include/linux/dqblk_xfs.h
index cb31719ee192..2fda1b2aabd9 100644
--- a/include/linux/dqblk_xfs.h
+++ b/include/linux/dqblk_xfs.h
@@ -1,22 +1,18 @@
/*
* Copyright (c) 1995-2001,2004 Silicon Graphics, Inc. All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2.1 of the GNU Lesser General Public License
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation.
*
* 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.
+ * GNU Lesser 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
- *
- * Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane,
- * Mountain View, CA 94043, USA, or: http://www.sgi.com
+ * You should have received a copy of the GNU Lesset 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_DQBLK_XFS_H
#define _LINUX_DQBLK_XFS_H
@@ -32,7 +28,8 @@
#define XQM_USRQUOTA 0 /* system call user quota type */
#define XQM_GRPQUOTA 1 /* system call group quota type */
-#define XQM_MAXQUOTAS 2
+#define XQM_PRJQUOTA 2 /* system call project quota type */
+#define XQM_MAXQUOTAS 3
#define Q_XQUOTAON XQM_CMD(1) /* enable accounting/enforcement */
#define Q_XQUOTAOFF XQM_CMD(2) /* disable accounting/enforcement */
@@ -40,6 +37,7 @@
#define Q_XSETQLIM XQM_CMD(4) /* set disk limits */
#define Q_XGETQSTAT XQM_CMD(5) /* get quota subsystem status */
#define Q_XQUOTARM XQM_CMD(6) /* free disk space used by dquots */
+#define Q_XQUOTASYNC XQM_CMD(7) /* delalloc flush, updates dquots */
/*
* fs_disk_quota structure:
diff --git a/include/linux/eeprom.h b/include/linux/eeprom.h
deleted file mode 100644
index 38afd9da1dfe..000000000000
--- a/include/linux/eeprom.h
+++ /dev/null
@@ -1,136 +0,0 @@
-/* credit winbond-840.c
- */
-#include <asm/io.h>
-struct eeprom_ops {
- void (*set_cs)(void *ee);
- void (*clear_cs)(void *ee);
-};
-
-#define EEPOL_EEDI 0x01
-#define EEPOL_EEDO 0x02
-#define EEPOL_EECLK 0x04
-#define EEPOL_EESEL 0x08
-
-struct eeprom {
- void *dev;
- struct eeprom_ops *ops;
-
- void __iomem * addr;
-
- unsigned ee_addr_bits;
-
- unsigned eesel;
- unsigned eeclk;
- unsigned eedo;
- unsigned eedi;
- unsigned polarity;
- unsigned ee_state;
-
- spinlock_t *lock;
- u32 *cache;
-};
-
-
-u8 eeprom_readb(struct eeprom *ee, unsigned address);
-void eeprom_read(struct eeprom *ee, unsigned address, u8 *bytes,
- unsigned count);
-void eeprom_writeb(struct eeprom *ee, unsigned address, u8 data);
-void eeprom_write(struct eeprom *ee, unsigned address, u8 *bytes,
- unsigned count);
-
-/* The EEPROM commands include the alway-set leading bit. */
-enum EEPROM_Cmds {
- EE_WriteCmd=(5 << 6), EE_ReadCmd=(6 << 6), EE_EraseCmd=(7 << 6),
-};
-
-void setup_ee_mem_bitbanger(struct eeprom *ee, void __iomem *memaddr, int eesel_bit, int eeclk_bit, int eedo_bit, int eedi_bit, unsigned polarity)
-{
- ee->addr = memaddr;
- ee->eesel = 1 << eesel_bit;
- ee->eeclk = 1 << eeclk_bit;
- ee->eedo = 1 << eedo_bit;
- ee->eedi = 1 << eedi_bit;
-
- ee->polarity = polarity;
-
- *ee->cache = readl(ee->addr);
-}
-
-/* foo. put this in a .c file */
-static inline void eeprom_update(struct eeprom *ee, u32 mask, int pol)
-{
- unsigned long flags;
- u32 data;
-
- spin_lock_irqsave(ee->lock, flags);
- data = *ee->cache;
-
- data &= ~mask;
- if (pol)
- data |= mask;
-
- *ee->cache = data;
-//printk("update: %08x\n", data);
- writel(data, ee->addr);
- spin_unlock_irqrestore(ee->lock, flags);
-}
-
-void eeprom_clk_lo(struct eeprom *ee)
-{
- int pol = !!(ee->polarity & EEPOL_EECLK);
-
- eeprom_update(ee, ee->eeclk, pol);
- udelay(2);
-}
-
-void eeprom_clk_hi(struct eeprom *ee)
-{
- int pol = !!(ee->polarity & EEPOL_EECLK);
-
- eeprom_update(ee, ee->eeclk, !pol);
- udelay(2);
-}
-
-void eeprom_send_addr(struct eeprom *ee, unsigned address)
-{
- int pol = !!(ee->polarity & EEPOL_EEDI);
- unsigned i;
- address |= 6 << 6;
-
- /* Shift the read command bits out. */
- for (i=0; i<11; i++) {
- eeprom_update(ee, ee->eedi, ((address >> 10) & 1) ^ pol);
- address <<= 1;
- eeprom_clk_hi(ee);
- eeprom_clk_lo(ee);
- }
- eeprom_update(ee, ee->eedi, pol);
-}
-
-u16 eeprom_readw(struct eeprom *ee, unsigned address)
-{
- unsigned i;
- u16 res = 0;
-
- eeprom_clk_lo(ee);
- eeprom_update(ee, ee->eesel, 1 ^ !!(ee->polarity & EEPOL_EESEL));
- eeprom_send_addr(ee, address);
-
- for (i=0; i<16; i++) {
- u32 data;
- eeprom_clk_hi(ee);
- res <<= 1;
- data = readl(ee->addr);
-//printk("eeprom_readw: %08x\n", data);
- res |= !!(data & ee->eedo) ^ !!(ee->polarity & EEPOL_EEDO);
- eeprom_clk_lo(ee);
- }
- eeprom_update(ee, ee->eesel, 0 ^ !!(ee->polarity & EEPOL_EESEL));
-
- return res;
-}
-
-
-void eeprom_writeb(struct eeprom *ee, unsigned address, u8 data)
-{
-}
diff --git a/include/linux/elevator.h b/include/linux/elevator.h
index ea6bbc2d7407..a74c27e460ba 100644
--- a/include/linux/elevator.h
+++ b/include/linux/elevator.h
@@ -8,18 +8,17 @@ typedef void (elevator_merge_req_fn) (request_queue_t *, struct request *, struc
typedef void (elevator_merged_fn) (request_queue_t *, struct request *);
-typedef struct request *(elevator_next_req_fn) (request_queue_t *);
+typedef int (elevator_dispatch_fn) (request_queue_t *, int);
-typedef void (elevator_add_req_fn) (request_queue_t *, struct request *, int);
+typedef void (elevator_add_req_fn) (request_queue_t *, struct request *);
typedef int (elevator_queue_empty_fn) (request_queue_t *);
-typedef void (elevator_remove_req_fn) (request_queue_t *, struct request *);
-typedef void (elevator_requeue_req_fn) (request_queue_t *, struct request *);
typedef struct request *(elevator_request_list_fn) (request_queue_t *, struct request *);
typedef void (elevator_completed_req_fn) (request_queue_t *, struct request *);
typedef int (elevator_may_queue_fn) (request_queue_t *, int, struct bio *);
-typedef int (elevator_set_req_fn) (request_queue_t *, struct request *, struct bio *, int);
+typedef int (elevator_set_req_fn) (request_queue_t *, struct request *, struct bio *, gfp_t);
typedef void (elevator_put_req_fn) (request_queue_t *, struct request *);
+typedef void (elevator_activate_req_fn) (request_queue_t *, struct request *);
typedef void (elevator_deactivate_req_fn) (request_queue_t *, struct request *);
typedef int (elevator_init_fn) (request_queue_t *, elevator_t *);
@@ -31,10 +30,9 @@ struct elevator_ops
elevator_merged_fn *elevator_merged_fn;
elevator_merge_req_fn *elevator_merge_req_fn;
- elevator_next_req_fn *elevator_next_req_fn;
+ elevator_dispatch_fn *elevator_dispatch_fn;
elevator_add_req_fn *elevator_add_req_fn;
- elevator_remove_req_fn *elevator_remove_req_fn;
- elevator_requeue_req_fn *elevator_requeue_req_fn;
+ elevator_activate_req_fn *elevator_activate_req_fn;
elevator_deactivate_req_fn *elevator_deactivate_req_fn;
elevator_queue_empty_fn *elevator_queue_empty_fn;
@@ -81,15 +79,15 @@ struct elevator_queue
/*
* block elevator interface
*/
+extern void elv_dispatch_sort(request_queue_t *, struct request *);
extern void elv_add_request(request_queue_t *, struct request *, int, int);
extern void __elv_add_request(request_queue_t *, struct request *, int, int);
extern int elv_merge(request_queue_t *, struct request **, struct bio *);
extern void elv_merge_requests(request_queue_t *, struct request *,
struct request *);
extern void elv_merged_request(request_queue_t *, struct request *);
-extern void elv_remove_request(request_queue_t *, struct request *);
+extern void elv_dequeue_request(request_queue_t *, struct request *);
extern void elv_requeue_request(request_queue_t *, struct request *);
-extern void elv_deactivate_request(request_queue_t *, struct request *);
extern int elv_queue_empty(request_queue_t *);
extern struct request *elv_next_request(struct request_queue *q);
extern struct request *elv_former_request(request_queue_t *, struct request *);
@@ -98,7 +96,7 @@ extern int elv_register_queue(request_queue_t *q);
extern void elv_unregister_queue(request_queue_t *q);
extern int elv_may_queue(request_queue_t *, int, struct bio *);
extern void elv_completed_request(request_queue_t *, struct request *);
-extern int elv_set_request(request_queue_t *, struct request *, struct bio *, int);
+extern int elv_set_request(request_queue_t *, struct request *, struct bio *, gfp_t);
extern void elv_put_request(request_queue_t *, struct request *);
/*
@@ -142,4 +140,6 @@ enum {
ELV_MQUEUE_MUST,
};
+#define rq_end_sector(rq) ((rq)->sector + (rq)->nr_sectors)
+
#endif
diff --git a/include/linux/etherdevice.h b/include/linux/etherdevice.h
index 4522c7186bf3..5f49a30eb6f2 100644
--- a/include/linux/etherdevice.h
+++ b/include/linux/etherdevice.h
@@ -48,8 +48,10 @@ static inline void eth_copy_and_sum (struct sk_buff *dest,
}
/**
- * is_zero_ether_addr - Determine if give Ethernet address is all
- * zeros.
+ * is_zero_ether_addr - Determine if give Ethernet address is all zeros.
+ * @addr: Pointer to a six-byte array containing the Ethernet address
+ *
+ * Return true if the address is all zeroes.
*/
static inline int is_zero_ether_addr(const u8 *addr)
{
@@ -57,9 +59,7 @@ static inline int is_zero_ether_addr(const u8 *addr)
}
/**
- * is_multicast_ether_addr - Determine if the given Ethernet address is a
- * multicast address.
- *
+ * is_multicast_ether_addr - Determine if the Ethernet address is a multicast.
* @addr: Pointer to a six-byte array containing the Ethernet address
*
* Return true if the address is a multicast address.
@@ -69,10 +69,15 @@ static inline int is_multicast_ether_addr(const u8 *addr)
return ((addr[0] != 0xff) && (0x01 & addr[0]));
}
+/**
+ * is_broadcast_ether_addr - Determine if the Ethernet address is broadcast
+ * @addr: Pointer to a six-byte array containing the Ethernet address
+ *
+ * Return true if the address is the broadcast address.
+ */
static inline int is_broadcast_ether_addr(const u8 *addr)
{
- return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) &&
- (addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff));
+ return (addr[0] & addr[1] & addr[2] & addr[3] & addr[4] & addr[5]) == 0xff;
}
/**
@@ -104,6 +109,22 @@ static inline void random_ether_addr(u8 *addr)
addr [0] &= 0xfe; /* clear multicast bit */
addr [0] |= 0x02; /* set local assignment bit (IEEE802) */
}
+
+/**
+ * compare_ether_addr - Compare two Ethernet addresses
+ * @addr1: Pointer to a six-byte array containing the Ethernet address
+ * @addr2: Pointer other six-byte array containing the Ethernet address
+ *
+ * Compare two ethernet addresses, returns 0 if equal
+ */
+static inline unsigned compare_ether_addr(const u8 *addr1, const u8 *addr2)
+{
+ const u16 *a = (const u16 *) addr1;
+ const u16 *b = (const u16 *) addr2;
+
+ BUILD_BUG_ON(ETH_ALEN != 6);
+ return ((a[0] ^ b[0]) | (a[1] ^ b[1]) | (a[2] ^ b[2])) != 0;
+}
#endif /* __KERNEL__ */
#endif /* _LINUX_ETHERDEVICE_H */
diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h
index ed1440ea4c91..93535f093216 100644
--- a/include/linux/ethtool.h
+++ b/include/linux/ethtool.h
@@ -269,6 +269,8 @@ u32 ethtool_op_get_tso(struct net_device *dev);
int ethtool_op_set_tso(struct net_device *dev, u32 data);
int ethtool_op_get_perm_addr(struct net_device *dev,
struct ethtool_perm_addr *addr, u8 *data);
+u32 ethtool_op_get_ufo(struct net_device *dev);
+int ethtool_op_set_ufo(struct net_device *dev, u32 data);
/**
* &ethtool_ops - Alter and report network device settings
@@ -298,6 +300,8 @@ int ethtool_op_get_perm_addr(struct net_device *dev,
* set_sg: Turn scatter-gather on or off
* get_tso: Report whether TCP segmentation offload is enabled
* set_tso: Turn TCP segmentation offload on or off
+ * get_ufo: Report whether UDP fragmentation offload is enabled
+ * set_ufo: Turn UDP fragmentation offload on or off
* self_test: Run specified self-tests
* get_strings: Return a set of strings that describe the requested objects
* phys_id: Identify the device
@@ -364,6 +368,8 @@ struct ethtool_ops {
int (*get_perm_addr)(struct net_device *, struct ethtool_perm_addr *, u8 *);
int (*begin)(struct net_device *);
void (*complete)(struct net_device *);
+ u32 (*get_ufo)(struct net_device *);
+ int (*set_ufo)(struct net_device *, u32);
};
/* CMDs currently supported */
@@ -400,6 +406,8 @@ struct ethtool_ops {
#define ETHTOOL_GTSO 0x0000001e /* Get TSO enable (ethtool_value) */
#define ETHTOOL_STSO 0x0000001f /* Set TSO enable (ethtool_value) */
#define ETHTOOL_GPERMADDR 0x00000020 /* Get permanent hardware address */
+#define ETHTOOL_GUFO 0x00000021 /* Get UFO enable (ethtool_value) */
+#define ETHTOOL_SUFO 0x00000022 /* Set UFO enable (ethtool_value) */
/* compatibility with older code */
#define SPARC_ETH_GSET ETHTOOL_GSET
@@ -445,10 +453,11 @@ struct ethtool_ops {
* it was foced up into this mode or autonegotiated.
*/
-/* The forced speed, 10Mb, 100Mb, gigabit, 10GbE. */
+/* The forced speed, 10Mb, 100Mb, gigabit, 2.5Gb, 10GbE. */
#define SPEED_10 10
#define SPEED_100 100
#define SPEED_1000 1000
+#define SPEED_2500 2500
#define SPEED_10000 10000
/* Duplex, half or full. */
diff --git a/include/linux/fb.h b/include/linux/fb.h
index c698055266d0..04a58f33ec53 100644
--- a/include/linux/fb.h
+++ b/include/linux/fb.h
@@ -201,6 +201,14 @@ struct fb_bitfield {
#define FB_VMODE_SMOOTH_XPAN 512 /* smooth xpan possible (internally used) */
#define FB_VMODE_CONUPDATE 512 /* don't update x/yoffset */
+/*
+ * Display rotation support
+ */
+#define FB_ROTATE_UR 0
+#define FB_ROTATE_CW 1
+#define FB_ROTATE_UD 2
+#define FB_ROTATE_CCW 3
+
#define PICOS2KHZ(a) (1000000000UL/(a))
#define KHZ2PICOS(a) (1000000000UL/(a))
@@ -489,9 +497,9 @@ struct fb_cursor_user {
#define FB_EVENT_MODE_DELETE 0x04
/* A driver registered itself */
#define FB_EVENT_FB_REGISTERED 0x05
-/* get console to framebuffer mapping */
+/* CONSOLE-SPECIFIC: get console to framebuffer mapping */
#define FB_EVENT_GET_CONSOLE_MAP 0x06
-/* set console to framebuffer mapping */
+/* CONSOLE-SPECIFIC: set console to framebuffer mapping */
#define FB_EVENT_SET_CONSOLE_MAP 0x07
/* A display blank is requested */
#define FB_EVENT_BLANK 0x08
@@ -500,6 +508,12 @@ struct fb_cursor_user {
/* The resolution of the passed in fb_info about to change and
all vc's should be changed */
#define FB_EVENT_MODE_CHANGE_ALL 0x0A
+/* CONSOLE-SPECIFIC: set console rotation */
+#define FB_EVENT_SET_CON_ROTATE 0x0B
+/* CONSOLE-SPECIFIC: get console rotation */
+#define FB_EVENT_GET_CON_ROTATE 0x0C
+/* CONSOLE-SPECIFIC: rotate all consoles */
+#define FB_EVENT_SET_CON_ROTATE_ALL 0x0D
struct fb_event {
struct fb_info *info;
@@ -810,7 +824,6 @@ struct fb_info {
extern int fb_set_var(struct fb_info *info, struct fb_var_screeninfo *var);
extern int fb_pan_display(struct fb_info *info, struct fb_var_screeninfo *var);
extern int fb_blank(struct fb_info *info, int blank);
-extern int soft_cursor(struct fb_info *info, struct fb_cursor *cursor);
extern void cfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect);
extern void cfb_copyarea(struct fb_info *info, const struct fb_copyarea *area);
extern void cfb_imageblit(struct fb_info *info, const struct fb_image *image);
@@ -818,8 +831,8 @@ extern void cfb_imageblit(struct fb_info *info, const struct fb_image *image);
/* drivers/video/fbmem.c */
extern int register_framebuffer(struct fb_info *fb_info);
extern int unregister_framebuffer(struct fb_info *fb_info);
-extern int fb_prepare_logo(struct fb_info *fb_info);
-extern int fb_show_logo(struct fb_info *fb_info);
+extern int fb_prepare_logo(struct fb_info *fb_info, int rotate);
+extern int fb_show_logo(struct fb_info *fb_info, int rotate);
extern char* fb_get_buffer_offset(struct fb_info *info, struct fb_pixmap *buf, u32 size);
extern void fb_pad_unaligned_buffer(u8 *dst, u32 d_pitch, u8 *src, u32 idx,
u32 height, u32 shift_high, u32 shift_low, u32 mod);
@@ -829,6 +842,7 @@ extern int fb_get_color_depth(struct fb_var_screeninfo *var,
struct fb_fix_screeninfo *fix);
extern int fb_get_options(char *name, char **option);
extern int fb_new_modelist(struct fb_info *info);
+extern int fb_con_duit(struct fb_info *info, int event, void *data);
extern struct fb_info *registered_fb[FB_MAX];
extern int num_registered_fb;
@@ -898,11 +912,13 @@ extern struct fb_videomode *fb_match_mode(struct fb_var_screeninfo *var,
struct list_head *head);
extern struct fb_videomode *fb_find_best_mode(struct fb_var_screeninfo *var,
struct list_head *head);
-extern struct fb_videomode *fb_find_nearest_mode(struct fb_var_screeninfo *var,
+extern struct fb_videomode *fb_find_nearest_mode(struct fb_videomode *mode,
struct list_head *head);
extern void fb_destroy_modelist(struct list_head *head);
extern void fb_videomode_to_modelist(struct fb_videomode *modedb, int num,
struct list_head *head);
+extern struct fb_videomode *fb_find_best_display(struct fb_monspecs *specs,
+ struct list_head *head);
/* drivers/video/fbcmap.c */
extern int fb_alloc_cmap(struct fb_cmap *cmap, int len, int transp);
diff --git a/include/linux/file.h b/include/linux/file.h
index f5bbd4c508b3..d3b1a15d5f21 100644
--- a/include/linux/file.h
+++ b/include/linux/file.h
@@ -59,9 +59,9 @@ extern void FASTCALL(set_close_on_exec(unsigned int fd, int flag));
extern void put_filp(struct file *);
extern int get_unused_fd(void);
extern void FASTCALL(put_unused_fd(unsigned int fd));
-struct kmem_cache_s;
-extern void filp_ctor(void * objp, struct kmem_cache_s *cachep, unsigned long cflags);
-extern void filp_dtor(void * objp, struct kmem_cache_s *cachep, unsigned long dflags);
+struct kmem_cache;
+extern void filp_ctor(void * objp, struct kmem_cache *cachep, unsigned long cflags);
+extern void filp_dtor(void * objp, struct kmem_cache *cachep, unsigned long dflags);
extern struct file ** alloc_fd_array(int);
extern void free_fd_array(struct file **, int);
diff --git a/include/linux/font.h b/include/linux/font.h
index 53b129f07f6f..8aac48c37f3d 100644
--- a/include/linux/font.h
+++ b/include/linux/font.h
@@ -31,6 +31,7 @@ struct font_desc {
#define SUN12x22_IDX 7
#define ACORN8x8_IDX 8
#define MINI4x6_IDX 9
+#define RL_IDX 10
extern const struct font_desc font_vga_8x8,
font_vga_8x16,
@@ -41,6 +42,7 @@ extern const struct font_desc font_vga_8x8,
font_sun_8x16,
font_sun_12x22,
font_acorn_8x8,
+ font_rl,
font_mini_4x6;
/* Find a font with a specific name */
diff --git a/include/linux/fs.h b/include/linux/fs.h
index e0b77c5af9a0..cc35b6ac778d 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -104,6 +104,10 @@ extern int dir_notify_enable;
#define MS_MOVE 8192
#define MS_REC 16384
#define MS_VERBOSE 32768
+#define MS_UNBINDABLE (1<<17) /* change to unbindable */
+#define MS_PRIVATE (1<<18) /* change to private */
+#define MS_SLAVE (1<<19) /* change to slave */
+#define MS_SHARED (1<<20) /* change to shared */
#define MS_POSIXACL (1<<16) /* VFS does not apply the umask */
#define MS_ACTIVE (1<<30)
#define MS_NOUSER (1<<31)
@@ -264,6 +268,7 @@ typedef void (dio_iodone_t)(struct kiocb *iocb, loff_t offset,
#define ATTR_ATTR_FLAG 1024
#define ATTR_KILL_SUID 2048
#define ATTR_KILL_SGID 4096
+#define ATTR_FILE 8192
/*
* This is the Inode Attributes structure, used for notify_change(). It
@@ -283,6 +288,13 @@ struct iattr {
struct timespec ia_atime;
struct timespec ia_mtime;
struct timespec ia_ctime;
+
+ /*
+ * Not an attribute, but an auxilary info for filesystems wanting to
+ * implement an ftruncate() like method. NOTE: filesystem should
+ * check for (ia_valid & ATTR_FILE), and not for (ia_file != NULL).
+ */
+ struct file *ia_file;
};
/*
@@ -320,7 +332,7 @@ struct address_space_operations {
/* Unfortunately this kludge is needed for FIBMAP. Don't use it */
sector_t (*bmap)(struct address_space *, sector_t);
int (*invalidatepage) (struct page *, unsigned long);
- int (*releasepage) (struct page *, int);
+ int (*releasepage) (struct page *, gfp_t);
ssize_t (*direct_IO)(int, struct kiocb *, const struct iovec *iov,
loff_t offset, unsigned long nr_segs);
struct page* (*get_xip_page)(struct address_space *, sector_t,
@@ -574,7 +586,14 @@ struct file_ra_state {
#define RA_FLAG_INCACHE 0x02 /* file is already in cache */
struct file {
- struct list_head f_list;
+ /*
+ * fu_list becomes invalid after file_free is called and queued via
+ * fu_rcuhead for RCU freeing
+ */
+ union {
+ struct list_head fu_list;
+ struct rcu_head fu_rcuhead;
+ } f_u;
struct dentry *f_dentry;
struct vfsmount *f_vfsmnt;
struct file_operations *f_op;
@@ -598,7 +617,6 @@ struct file {
spinlock_t f_ep_lock;
#endif /* #ifdef CONFIG_EPOLL */
struct address_space *f_mapping;
- struct rcu_head f_rcuhead;
};
extern spinlock_t files_lock;
#define file_list_lock() spin_lock(&files_lock);
@@ -856,6 +874,7 @@ static inline void unlock_super(struct super_block * sb)
/*
* VFS helper functions..
*/
+extern int vfs_permission(struct nameidata *, int);
extern int vfs_create(struct inode *, struct dentry *, int, struct nameidata *);
extern int vfs_mkdir(struct inode *, struct dentry *, int);
extern int vfs_mknod(struct inode *, struct dentry *, int, dev_t);
@@ -871,6 +890,11 @@ extern int vfs_rename(struct inode *, struct dentry *, struct inode *, struct de
extern void dentry_unhash(struct dentry *dentry);
/*
+ * VFS file helper functions.
+ */
+extern int file_permission(struct file *, int);
+
+/*
* File types
*
* NOTE! These match bits 12..15 of stat.st_mode
@@ -1082,6 +1106,8 @@ int sync_inode(struct inode *inode, struct writeback_control *wbc);
* @get_name: find the name for a given inode in a given directory
* @get_parent: find the parent of a given directory
* @get_dentry: find a dentry for the inode given a file handle sub-fragment
+ * @find_exported_dentry:
+ * set by the exporting module to a standard helper function.
*
* Description:
* The export_operations structure provides a means for nfsd to communicate
@@ -1233,7 +1259,12 @@ extern int unregister_filesystem(struct file_system_type *);
extern struct vfsmount *kern_mount(struct file_system_type *);
extern int may_umount_tree(struct vfsmount *);
extern int may_umount(struct vfsmount *);
+extern void umount_tree(struct vfsmount *, int, struct list_head *);
+extern void release_mounts(struct list_head *);
extern long do_mount(char *, char *, char *, unsigned long, void *);
+extern struct vfsmount *copy_tree(struct vfsmount *, struct dentry *, int);
+extern void mnt_set_mountpoint(struct vfsmount *, struct dentry *,
+ struct vfsmount *);
extern int vfs_statfs(struct super_block *, struct kstatfs *);
@@ -1282,7 +1313,7 @@ static inline int break_lease(struct inode *inode, unsigned int mode)
/* fs/open.c */
-extern int do_truncate(struct dentry *, loff_t start);
+extern int do_truncate(struct dentry *, loff_t start, struct file *filp);
extern long do_sys_open(const char __user *filename, int flags, int mode);
extern struct file *filp_open(const char *, int, int);
extern struct file * dentry_open(struct dentry *, struct vfsmount *, int);
diff --git a/include/linux/fs_enet_pd.h b/include/linux/fs_enet_pd.h
new file mode 100644
index 000000000000..783c476b8674
--- /dev/null
+++ b/include/linux/fs_enet_pd.h
@@ -0,0 +1,135 @@
+/*
+ * Platform information definitions for the
+ * universal Freescale Ethernet driver.
+ *
+ * Copyright (c) 2003 Intracom S.A.
+ * by Pantelis Antoniou <panto@intracom.gr>
+ *
+ * 2005 (c) MontaVista Software, Inc.
+ * Vitaly Bordug <vbordug@ru.mvista.com>
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+#ifndef FS_ENET_PD_H
+#define FS_ENET_PD_H
+
+#include <asm/types.h>
+
+#define FS_ENET_NAME "fs_enet"
+
+enum fs_id {
+ fsid_fec1,
+ fsid_fec2,
+ fsid_fcc1,
+ fsid_fcc2,
+ fsid_fcc3,
+ fsid_scc1,
+ fsid_scc2,
+ fsid_scc3,
+ fsid_scc4,
+};
+
+#define FS_MAX_INDEX 9
+
+static inline int fs_get_fec_index(enum fs_id id)
+{
+ if (id >= fsid_fec1 && id <= fsid_fec2)
+ return id - fsid_fec1;
+ return -1;
+}
+
+static inline int fs_get_fcc_index(enum fs_id id)
+{
+ if (id >= fsid_fcc1 && id <= fsid_fcc3)
+ return id - fsid_fcc1;
+ return -1;
+}
+
+static inline int fs_get_scc_index(enum fs_id id)
+{
+ if (id >= fsid_scc1 && id <= fsid_scc4)
+ return id - fsid_scc1;
+ return -1;
+}
+
+enum fs_mii_method {
+ fsmii_fixed,
+ fsmii_fec,
+ fsmii_bitbang,
+};
+
+enum fs_ioport {
+ fsiop_porta,
+ fsiop_portb,
+ fsiop_portc,
+ fsiop_portd,
+ fsiop_porte,
+};
+
+struct fs_mii_bus_info {
+ int method; /* mii method */
+ int id; /* the id of the mii_bus */
+ int disable_aneg; /* if the controller needs to negothiate speed & duplex */
+ int lpa; /* the default board-specific vallues will be applied otherwise */
+
+ union {
+ struct {
+ int duplex;
+ int speed;
+ } fixed;
+
+ struct {
+ /* nothing */
+ } fec;
+
+ struct {
+ /* nothing */
+ } scc;
+
+ struct {
+ int mdio_port; /* port & bit for MDIO */
+ int mdio_bit;
+ int mdc_port; /* port & bit for MDC */
+ int mdc_bit;
+ int delay; /* delay in us */
+ } bitbang;
+ } i;
+};
+
+struct fs_platform_info {
+
+ void(*init_ioports)(void);
+ /* device specific information */
+ int fs_no; /* controller index */
+
+ u32 cp_page; /* CPM page */
+ u32 cp_block; /* CPM sblock */
+
+ u32 clk_trx; /* some stuff for pins & mux configuration*/
+ u32 clk_route;
+ u32 clk_mask;
+
+ u32 mem_offset;
+ u32 dpram_offset;
+ u32 fcc_regs_c;
+
+ u32 device_flags;
+
+ int phy_addr; /* the phy address (-1 no phy) */
+ int phy_irq; /* the phy irq (if it exists) */
+
+ const struct fs_mii_bus_info *bus_info;
+
+ int rx_ring, tx_ring; /* number of buffers on rx */
+ __u8 macaddr[6]; /* mac address */
+ int rx_copybreak; /* limit we copy small frames */
+ int use_napi; /* use NAPI */
+ int napi_weight; /* NAPI weight */
+
+ int use_rmii; /* use RMII mode */
+};
+
+#endif
diff --git a/include/linux/fsl_devices.h b/include/linux/fsl_devices.h
index 70f54af87b9f..114d5d59f695 100644
--- a/include/linux/fsl_devices.h
+++ b/include/linux/fsl_devices.h
@@ -47,16 +47,21 @@
struct gianfar_platform_data {
/* device specific information */
u32 device_flags;
- u32 phy_reg_addr;
/* board specific information */
u32 board_flags;
- u32 phy_flags;
- u32 phyid;
- u32 interruptPHY;
+ const char *bus_id;
u8 mac_addr[6];
};
+struct gianfar_mdio_data {
+ /* device specific information */
+ u32 paddr;
+
+ /* board specific information */
+ int irq[32];
+};
+
/* Flags related to gianfar device features */
#define FSL_GIANFAR_DEV_HAS_GIGABIT 0x00000001
#define FSL_GIANFAR_DEV_HAS_COALESCE 0x00000002
diff --git a/include/linux/fuse.h b/include/linux/fuse.h
index acbeb96a3353..b76b558b03d4 100644
--- a/include/linux/fuse.h
+++ b/include/linux/fuse.h
@@ -14,7 +14,7 @@
#define FUSE_KERNEL_VERSION 7
/** Minor version number of this interface */
-#define FUSE_KERNEL_MINOR_VERSION 2
+#define FUSE_KERNEL_MINOR_VERSION 3
/** The node ID of the root inode */
#define FUSE_ROOT_ID 1
@@ -61,7 +61,7 @@ struct fuse_kstatfs {
#define FATTR_SIZE (1 << 3)
#define FATTR_ATIME (1 << 4)
#define FATTR_MTIME (1 << 5)
-#define FATTR_CTIME (1 << 6)
+#define FATTR_FH (1 << 6)
/**
* Flags returned by the OPEN request
@@ -100,7 +100,9 @@ enum fuse_opcode {
FUSE_OPENDIR = 27,
FUSE_READDIR = 28,
FUSE_RELEASEDIR = 29,
- FUSE_FSYNCDIR = 30
+ FUSE_FSYNCDIR = 30,
+ FUSE_ACCESS = 34,
+ FUSE_CREATE = 35
};
/* Conservative buffer size for the client */
@@ -153,12 +155,25 @@ struct fuse_link_in {
struct fuse_setattr_in {
__u32 valid;
__u32 padding;
- struct fuse_attr attr;
+ __u64 fh;
+ __u64 size;
+ __u64 unused1;
+ __u64 atime;
+ __u64 mtime;
+ __u64 unused2;
+ __u32 atimensec;
+ __u32 mtimensec;
+ __u32 unused3;
+ __u32 mode;
+ __u32 unused4;
+ __u32 uid;
+ __u32 gid;
+ __u32 unused5;
};
struct fuse_open_in {
__u32 flags;
- __u32 padding;
+ __u32 mode;
};
struct fuse_open_out {
@@ -223,6 +238,11 @@ struct fuse_getxattr_out {
__u32 padding;
};
+struct fuse_access_in {
+ __u32 mask;
+ __u32 padding;
+};
+
struct fuse_init_in_out {
__u32 major;
__u32 minor;
diff --git a/include/linux/gameport.h b/include/linux/gameport.h
index cd623eccdbea..2401dea2b867 100644
--- a/include/linux/gameport.h
+++ b/include/linux/gameport.h
@@ -12,6 +12,7 @@
#include <asm/io.h>
#include <linux/list.h>
#include <linux/device.h>
+#include <linux/timer.h>
struct gameport {
diff --git a/include/linux/genetlink.h b/include/linux/genetlink.h
new file mode 100644
index 000000000000..84f12a41dc01
--- /dev/null
+++ b/include/linux/genetlink.h
@@ -0,0 +1,51 @@
+#ifndef __LINUX_GENERIC_NETLINK_H
+#define __LINUX_GENERIC_NETLINK_H
+
+#include <linux/netlink.h>
+
+#define GENL_NAMSIZ 16 /* length of family name */
+
+#define GENL_MIN_ID NLMSG_MIN_TYPE
+#define GENL_MAX_ID 1023
+
+struct genlmsghdr {
+ __u8 cmd;
+ __u8 version;
+ __u16 reserved;
+};
+
+#define GENL_HDRLEN NLMSG_ALIGN(sizeof(struct genlmsghdr))
+
+/*
+ * List of reserved static generic netlink identifiers:
+ */
+#define GENL_ID_GENERATE 0
+#define GENL_ID_CTRL NLMSG_MIN_TYPE
+
+/**************************************************************************
+ * Controller
+ **************************************************************************/
+
+enum {
+ CTRL_CMD_UNSPEC,
+ CTRL_CMD_NEWFAMILY,
+ CTRL_CMD_DELFAMILY,
+ CTRL_CMD_GETFAMILY,
+ CTRL_CMD_NEWOPS,
+ CTRL_CMD_DELOPS,
+ CTRL_CMD_GETOPS,
+ __CTRL_CMD_MAX,
+};
+
+#define CTRL_CMD_MAX (__CTRL_CMD_MAX - 1)
+
+enum {
+ CTRL_ATTR_UNSPEC,
+ CTRL_ATTR_FAMILY_ID,
+ CTRL_ATTR_FAMILY_NAME,
+ __CTRL_ATTR_MAX,
+};
+
+#define CTRL_ATTR_MAX (__CTRL_ATTR_MAX - 1)
+
+#endif /* __LINUX_GENERIC_NETLINK_H */
diff --git a/include/linux/genhd.h b/include/linux/genhd.h
index 01796c41c951..8eeaa53a68c9 100644
--- a/include/linux/genhd.h
+++ b/include/linux/genhd.h
@@ -78,7 +78,7 @@ struct hd_struct {
sector_t start_sect;
sector_t nr_sects;
struct kobject kobj;
- unsigned reads, read_sectors, writes, write_sectors;
+ unsigned ios[2], sectors[2];
int policy, partno;
};
@@ -89,10 +89,10 @@ struct hd_struct {
#define GENHD_FL_SUPPRESS_PARTITION_INFO 32
struct disk_stats {
- unsigned read_sectors, write_sectors;
- unsigned reads, writes;
- unsigned read_merges, write_merges;
- unsigned read_ticks, write_ticks;
+ unsigned sectors[2];
+ unsigned ios[2];
+ unsigned merges[2];
+ unsigned ticks[2];
unsigned io_ticks;
unsigned time_in_queue;
};
@@ -119,7 +119,7 @@ struct gendisk {
int policy;
atomic_t sync_io; /* RAID */
- unsigned long stamp, stamp_idle;
+ unsigned long stamp;
int in_flight;
#ifdef CONFIG_SMP
struct disk_stats *dkstats;
@@ -132,6 +132,7 @@ struct gendisk {
struct disk_attribute {
struct attribute attr;
ssize_t (*show)(struct gendisk *, char *);
+ ssize_t (*store)(struct gendisk *, const char *, size_t);
};
/*
diff --git a/include/linux/gfp.h b/include/linux/gfp.h
index 3010e172394d..c3779432a723 100644
--- a/include/linux/gfp.h
+++ b/include/linux/gfp.h
@@ -12,8 +12,8 @@ struct vm_area_struct;
* GFP bitmasks..
*/
/* Zone modifiers in GFP_ZONEMASK (see linux/mmzone.h - low two bits) */
-#define __GFP_DMA 0x01u
-#define __GFP_HIGHMEM 0x02u
+#define __GFP_DMA ((__force gfp_t)0x01u)
+#define __GFP_HIGHMEM ((__force gfp_t)0x02u)
/*
* Action modifiers - doesn't change the zoning
@@ -26,24 +26,24 @@ struct vm_area_struct;
*
* __GFP_NORETRY: The VM implementation must not retry indefinitely.
*/
-#define __GFP_WAIT 0x10u /* Can wait and reschedule? */
-#define __GFP_HIGH 0x20u /* Should access emergency pools? */
-#define __GFP_IO 0x40u /* Can start physical IO? */
-#define __GFP_FS 0x80u /* Can call down to low-level FS? */
-#define __GFP_COLD 0x100u /* Cache-cold page required */
-#define __GFP_NOWARN 0x200u /* Suppress page allocation failure warning */
-#define __GFP_REPEAT 0x400u /* Retry the allocation. Might fail */
-#define __GFP_NOFAIL 0x800u /* Retry for ever. Cannot fail */
-#define __GFP_NORETRY 0x1000u /* Do not retry. Might fail */
-#define __GFP_NO_GROW 0x2000u /* Slab internal usage */
-#define __GFP_COMP 0x4000u /* Add compound page metadata */
-#define __GFP_ZERO 0x8000u /* Return zeroed page on success */
-#define __GFP_NOMEMALLOC 0x10000u /* Don't use emergency reserves */
-#define __GFP_NORECLAIM 0x20000u /* No realy zone reclaim during allocation */
-#define __GFP_HARDWALL 0x40000u /* Enforce hardwall cpuset memory allocs */
+#define __GFP_WAIT ((__force gfp_t)0x10u) /* Can wait and reschedule? */
+#define __GFP_HIGH ((__force gfp_t)0x20u) /* Should access emergency pools? */
+#define __GFP_IO ((__force gfp_t)0x40u) /* Can start physical IO? */
+#define __GFP_FS ((__force gfp_t)0x80u) /* Can call down to low-level FS? */
+#define __GFP_COLD ((__force gfp_t)0x100u) /* Cache-cold page required */
+#define __GFP_NOWARN ((__force gfp_t)0x200u) /* Suppress page allocation failure warning */
+#define __GFP_REPEAT ((__force gfp_t)0x400u) /* Retry the allocation. Might fail */
+#define __GFP_NOFAIL ((__force gfp_t)0x800u) /* Retry for ever. Cannot fail */
+#define __GFP_NORETRY ((__force gfp_t)0x1000u)/* Do not retry. Might fail */
+#define __GFP_NO_GROW ((__force gfp_t)0x2000u)/* Slab internal usage */
+#define __GFP_COMP ((__force gfp_t)0x4000u)/* Add compound page metadata */
+#define __GFP_ZERO ((__force gfp_t)0x8000u)/* Return zeroed page on success */
+#define __GFP_NOMEMALLOC ((__force gfp_t)0x10000u) /* Don't use emergency reserves */
+#define __GFP_NORECLAIM ((__force gfp_t)0x20000u) /* No realy zone reclaim during allocation */
+#define __GFP_HARDWALL ((__force gfp_t)0x40000u) /* Enforce hardwall cpuset memory allocs */
#define __GFP_BITS_SHIFT 20 /* Room for 20 __GFP_FOO bits */
-#define __GFP_BITS_MASK ((1 << __GFP_BITS_SHIFT) - 1)
+#define __GFP_BITS_MASK ((__force gfp_t)((1 << __GFP_BITS_SHIFT) - 1))
/* if you forget to add the bitmask here kernel will crash, period */
#define GFP_LEVEL_MASK (__GFP_WAIT|__GFP_HIGH|__GFP_IO|__GFP_FS| \
@@ -64,6 +64,7 @@ struct vm_area_struct;
#define GFP_DMA __GFP_DMA
+#define gfp_zone(mask) ((__force int)((mask) & (__force gfp_t)GFP_ZONEMASK))
/*
* There is only one page-allocator function, and two main namespaces to
@@ -94,7 +95,7 @@ static inline struct page *alloc_pages_node(int nid, gfp_t gfp_mask,
return NULL;
return __alloc_pages(gfp_mask, order,
- NODE_DATA(nid)->node_zonelists + (gfp_mask & GFP_ZONEMASK));
+ NODE_DATA(nid)->node_zonelists + gfp_zone(gfp_mask));
}
#ifdef CONFIG_NUMA
diff --git a/include/linux/hil.h b/include/linux/hil.h
new file mode 100644
index 000000000000..13352d7d0caf
--- /dev/null
+++ b/include/linux/hil.h
@@ -0,0 +1,483 @@
+#ifndef _HIL_H_
+#define _HIL_H_
+
+/*
+ * Hewlett Packard Human Interface Loop (HP-HIL) Protocol -- header.
+ *
+ * Copyright (c) 2001 Brian S. Julin
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL").
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ *
+ * References:
+ * HP-HIL Technical Reference Manual. Hewlett Packard Product No. 45918A
+ *
+ * A note of thanks to HP for providing and shipping reference materials
+ * free of charge to help in the development of HIL support for Linux.
+ *
+ */
+
+#include <asm/types.h>
+
+/* Physical constants relevant to raw loop/device timing.
+ */
+
+#define HIL_CLOCK 8MHZ
+#define HIL_EK1_CLOCK 30HZ
+#define HIL_EK2_CLOCK 60HZ
+
+#define HIL_TIMEOUT_DEV 5 /* ms */
+#define HIL_TIMEOUT_DEVS 10 /* ms */
+#define HIL_TIMEOUT_NORESP 10 /* ms */
+#define HIL_TIMEOUT_DEVS_DATA 16 /* ms */
+#define HIL_TIMEOUT_SELFTEST 200 /* ms */
+
+
+/* Actual wire line coding. These will only be useful if someone is
+ * implementing a software MLC to run HIL devices on a non-parisc machine.
+ */
+
+#define HIL_WIRE_PACKET_LEN 15
+enum hil_wire_bitpos {
+ HIL_WIRE_START = 0,
+ HIL_WIRE_ADDR2,
+ HIL_WIRE_ADDR1,
+ HIL_WIRE_ADDR0,
+ HIL_WIRE_COMMAND,
+ HIL_WIRE_DATA7,
+ HIL_WIRE_DATA6,
+ HIL_WIRE_DATA5,
+ HIL_WIRE_DATA4,
+ HIL_WIRE_DATA3,
+ HIL_WIRE_DATA2,
+ HIL_WIRE_DATA1,
+ HIL_WIRE_DATA0,
+ HIL_WIRE_PARITY,
+ HIL_WIRE_STOP
+};
+
+/* HP documentation uses these bit positions to refer to commands;
+ * we will call these "packets".
+ */
+enum hil_pkt_bitpos {
+ HIL_PKT_CMD = 0x00000800,
+ HIL_PKT_ADDR2 = 0x00000400,
+ HIL_PKT_ADDR1 = 0x00000200,
+ HIL_PKT_ADDR0 = 0x00000100,
+ HIL_PKT_ADDR_MASK = 0x00000700,
+ HIL_PKT_ADDR_SHIFT = 8,
+ HIL_PKT_DATA7 = 0x00000080,
+ HIL_PKT_DATA6 = 0x00000040,
+ HIL_PKT_DATA5 = 0x00000020,
+ HIL_PKT_DATA4 = 0x00000010,
+ HIL_PKT_DATA3 = 0x00000008,
+ HIL_PKT_DATA2 = 0x00000004,
+ HIL_PKT_DATA1 = 0x00000002,
+ HIL_PKT_DATA0 = 0x00000001,
+ HIL_PKT_DATA_MASK = 0x000000FF,
+ HIL_PKT_DATA_SHIFT = 0
+};
+
+/* The HIL MLC also has several error/status/control bits. We extend the
+ * "packet" to include these when direct access to the MLC is available,
+ * or emulate them in cases where they are not available.
+ *
+ * This way the device driver knows that the underlying MLC driver
+ * has had to deal with loop errors.
+ */
+enum hil_error_bitpos {
+ HIL_ERR_OB = 0x00000800, /* MLC is busy sending an auto-poll,
+ or we have filled up the output
+ buffer and must wait. */
+ HIL_ERR_INT = 0x00010000, /* A normal interrupt has occurred. */
+ HIL_ERR_NMI = 0x00020000, /* An NMI has occurred. */
+ HIL_ERR_LERR = 0x00040000, /* A poll didn't come back. */
+ HIL_ERR_PERR = 0x01000000, /* There was a Parity Error. */
+ HIL_ERR_FERR = 0x02000000, /* There was a Framing Error. */
+ HIL_ERR_FOF = 0x04000000 /* Input FIFO Overflowed. */
+};
+
+enum hil_control_bitpos {
+ HIL_CTRL_TEST = 0x00010000,
+ HIL_CTRL_IPF = 0x00040000,
+ HIL_CTRL_APE = 0x02000000
+};
+
+/* Bits 30,31 are unused, we use them to control write behavior. */
+#define HIL_DO_ALTER_CTRL 0x40000000 /* Write MSW of packet to control
+ before writing LSW to loop */
+#define HIL_CTRL_ONLY 0xc0000000 /* *Only* alter the control registers */
+
+/* This gives us a 32-bit "packet"
+ */
+typedef u32 hil_packet;
+
+
+/* HIL Loop commands
+ */
+enum hil_command {
+ HIL_CMD_IFC = 0x00, /* Interface Clear */
+ HIL_CMD_EPT = 0x01, /* Enter Pass-Thru Mode */
+ HIL_CMD_ELB = 0x02, /* Enter Loop-Back Mode */
+ HIL_CMD_IDD = 0x03, /* Identify and Describe */
+ HIL_CMD_DSR = 0x04, /* Device Soft Reset */
+ HIL_CMD_PST = 0x05, /* Perform Self Test */
+ HIL_CMD_RRG = 0x06, /* Read Register */
+ HIL_CMD_WRG = 0x07, /* Write Register */
+ HIL_CMD_ACF = 0x08, /* Auto Configure */
+ HIL_CMDID_ACF = 0x07, /* Auto Configure bits with incremented ID */
+ HIL_CMD_POL = 0x10, /* Poll */
+ HIL_CMDCT_POL = 0x0f, /* Poll command bits with item count */
+ HIL_CMD_RPL = 0x20, /* RePoll */
+ HIL_CMDCT_RPL = 0x0f, /* RePoll command bits with item count */
+ HIL_CMD_RNM = 0x30, /* Report Name */
+ HIL_CMD_RST = 0x31, /* Report Status */
+ HIL_CMD_EXD = 0x32, /* Extended Describe */
+ HIL_CMD_RSC = 0x33, /* Report Security Code */
+
+ /* 0x34 to 0x3c reserved for future use */
+
+ HIL_CMD_DKA = 0x3d, /* Disable Keyswitch Autorepeat */
+ HIL_CMD_EK1 = 0x3e, /* Enable Keyswitch Autorepeat 1 */
+ HIL_CMD_EK2 = 0x3f, /* Enable Keyswitch Autorepeat 2 */
+ HIL_CMD_PR1 = 0x40, /* Prompt1 */
+ HIL_CMD_PR2 = 0x41, /* Prompt2 */
+ HIL_CMD_PR3 = 0x42, /* Prompt3 */
+ HIL_CMD_PR4 = 0x43, /* Prompt4 */
+ HIL_CMD_PR5 = 0x44, /* Prompt5 */
+ HIL_CMD_PR6 = 0x45, /* Prompt6 */
+ HIL_CMD_PR7 = 0x46, /* Prompt7 */
+ HIL_CMD_PRM = 0x47, /* Prompt (General Purpose) */
+ HIL_CMD_AK1 = 0x48, /* Acknowlege1 */
+ HIL_CMD_AK2 = 0x49, /* Acknowlege2 */
+ HIL_CMD_AK3 = 0x4a, /* Acknowlege3 */
+ HIL_CMD_AK4 = 0x4b, /* Acknowlege4 */
+ HIL_CMD_AK5 = 0x4c, /* Acknowlege5 */
+ HIL_CMD_AK6 = 0x4d, /* Acknowlege6 */
+ HIL_CMD_AK7 = 0x4e, /* Acknowlege7 */
+ HIL_CMD_ACK = 0x4f, /* Acknowlege (General Purpose) */
+
+ /* 0x50 to 0x78 reserved for future use */
+ /* 0x80 to 0xEF device-specific commands */
+ /* 0xf0 to 0xf9 reserved for future use */
+
+ HIL_CMD_RIO = 0xfa, /* Register I/O Error */
+ HIL_CMD_SHR = 0xfb, /* System Hard Reset */
+ HIL_CMD_TER = 0xfc, /* Transmission Error */
+ HIL_CMD_CAE = 0xfd, /* Configuration Address Error */
+ HIL_CMD_DHR = 0xfe, /* Device Hard Reset */
+
+ /* 0xff is prohibited from use. */
+};
+
+
+/*
+ * Response "records" to HIL commands
+ */
+
+/* Device ID byte
+ */
+#define HIL_IDD_DID_TYPE_MASK 0xe0 /* Primary type bits */
+#define HIL_IDD_DID_TYPE_KB_INTEGRAL 0xa0 /* Integral keyboard */
+#define HIL_IDD_DID_TYPE_KB_ITF 0xc0 /* ITD keyboard */
+#define HIL_IDD_DID_TYPE_KB_RSVD 0xe0 /* Reserved keyboard type */
+#define HIL_IDD_DID_TYPE_KB_LANG_MASK 0x1f /* Keyboard locale bits */
+#define HIL_IDD_DID_KBLANG_USE_ESD 0x00 /* Use ESD Locale instead */
+#define HIL_IDD_DID_TYPE_ABS 0x80 /* Absolute Positioners */
+#define HIL_IDD_DID_ABS_RSVD1_MASK 0xf8 /* Reserved */
+#define HIL_IDD_DID_ABS_RSVD1 0x98
+#define HIL_IDD_DID_ABS_TABLET_MASK 0xf8 /* Tablets and digitizers */
+#define HIL_IDD_DID_ABS_TABLET 0x90
+#define HIL_IDD_DID_ABS_TSCREEN_MASK 0xfc /* Touch screens */
+#define HIL_IDD_DID_ABS_TSCREEN 0x8c
+#define HIL_IDD_DID_ABS_RSVD2_MASK 0xfc /* Reserved */
+#define HIL_IDD_DID_ABS_RSVD2 0x88
+#define HIL_IDD_DID_ABS_RSVD3_MASK 0xfc /* Reserved */
+#define HIL_IDD_DID_ABS_RSVD3 0x80
+#define HIL_IDD_DID_TYPE_REL 0x60 /* Relative Positioners */
+#define HIL_IDD_DID_REL_RSVD1_MASK 0xf0 /* Reserved */
+#define HIL_IDD_DID_REL_RSVD1 0x70
+#define HIL_IDD_DID_REL_RSVD2_MASK 0xfc /* Reserved */
+#define HIL_IDD_DID_REL_RSVD2 0x6c
+#define HIL_IDD_DID_REL_MOUSE_MASK 0xfc /* Mouse */
+#define HIL_IDD_DID_REL_MOUSE 0x68
+#define HIL_IDD_DID_REL_QUAD_MASK 0xf8 /* Other Quadrature Devices */
+#define HIL_IDD_DID_REL_QUAD 0x60
+#define HIL_IDD_DID_TYPE_CHAR 0x40 /* Character Entry */
+#define HIL_IDD_DID_CHAR_BARCODE_MASK 0xfc /* Barcode Reader */
+#define HIL_IDD_DID_CHAR_BARCODE 0x5c
+#define HIL_IDD_DID_CHAR_RSVD1_MASK 0xfc /* Reserved */
+#define HIL_IDD_DID_CHAR_RSVD1 0x58
+#define HIL_IDD_DID_CHAR_RSVD2_MASK 0xf8 /* Reserved */
+#define HIL_IDD_DID_CHAR_RSVD2 0x50
+#define HIL_IDD_DID_CHAR_RSVD3_MASK 0xf0 /* Reserved */
+#define HIL_IDD_DID_CHAR_RSVD3 0x40
+#define HIL_IDD_DID_TYPE_OTHER 0x20 /* Miscellaneous */
+#define HIL_IDD_DID_OTHER_RSVD1_MASK 0xf0 /* Reserved */
+#define HIL_IDD_DID_OTHER_RSVD1 0x30
+#define HIL_IDD_DID_OTHER_BARCODE_MASK 0xfc /* Tone Generator */
+#define HIL_IDD_DID_OTHER_BARCODE 0x2c
+#define HIL_IDD_DID_OTHER_RSVD2_MASK 0xfc /* Reserved */
+#define HIL_IDD_DID_OTHER_RSVD2 0x28
+#define HIL_IDD_DID_OTHER_RSVD3_MASK 0xf8 /* Reserved */
+#define HIL_IDD_DID_OTHER_RSVD3 0x20
+#define HIL_IDD_DID_TYPE_KEYPAD 0x00 /* Vectra Keyboard */
+
+/* IDD record header
+ */
+#define HIL_IDD_HEADER_AXSET_MASK 0x03 /* Number of axis in a set */
+#define HIL_IDD_HEADER_RSC 0x04 /* Supports RSC command */
+#define HIL_IDD_HEADER_EXD 0x08 /* Supports EXD command */
+#define HIL_IDD_HEADER_IOD 0x10 /* IOD byte to follow */
+#define HIL_IDD_HEADER_16BIT 0x20 /* 16 (vs. 8) bit resolution */
+#define HIL_IDD_HEADER_ABS 0x40 /* Reports Absolute Position */
+#define HIL_IDD_HEADER_2X_AXIS 0x80 /* Two sets of 1-3 axis */
+
+/* I/O Descriptor
+ */
+#define HIL_IDD_IOD_NBUTTON_MASK 0x07 /* Number of buttons */
+#define HIL_IDD_IOD_PROXIMITY 0x08 /* Proximity in/out events */
+#define HIL_IDD_IOD_PROMPT_MASK 0x70 /* Number of prompts/acks */
+#define HIL_IDD_IOD_PROMPT_SHIFT 4
+#define HIL_IDD_IOD_PROMPT 0x80 /* Generic prompt/ack */
+
+#define HIL_IDD_NUM_AXES_PER_SET(header_packet) \
+((header_packet) & HIL_IDD_HEADER_AXSET_MASK)
+
+#define HIL_IDD_NUM_AXSETS(header_packet) \
+(2 - !((header_packet) & HIL_IDD_HEADER_2X_AXIS))
+
+#define HIL_IDD_LEN(header_packet) \
+((4 - !(header_packet & HIL_IDD_HEADER_IOD) - \
+ 2 * !(HIL_IDD_NUM_AXES_PER_SET(header_packet))) + \
+ 2 * HIL_IDD_NUM_AXES_PER_SET(header_packet) * \
+ !!((header_packet) & HIL_IDD_HEADER_ABS))
+
+/* The following HIL_IDD_* macros assume you have an array of
+ * packets and/or unpacked 8-bit data in the order that they
+ * were received.
+ */
+
+#define HIL_IDD_AXIS_COUNTS_PER_M(header_ptr) \
+(!(HIL_IDD_NUM_AXSETS(*(header_ptr))) ? -1 : \
+(((*(header_ptr + 1) & HIL_PKT_DATA_MASK) + \
+ ((*(header_ptr + 2) & HIL_PKT_DATA_MASK)) << 8) \
+* ((*(header_ptr) & HIL_IDD_HEADER_16BIT) ? 100 : 1)))
+
+#define HIL_IDD_AXIS_MAX(header_ptr, __axnum) \
+((!(*(header_ptr) & HIL_IDD_HEADER_ABS) || \
+ (HIL_IDD_NUM_AXES_PER_SET(*(header_ptr)) <= __axnum)) ? 0 : \
+ ((HIL_PKT_DATA_MASK & *((header_ptr) + 3 + 2 * __axnum)) + \
+ ((HIL_PKT_DATA_MASK & *((header_ptr) + 4 + 2 * __axnum)) << 8)))
+
+#define HIL_IDD_IOD(header_ptr) \
+(*(header_ptr + HIL_IDD_LEN((*header_ptr)) - 1))
+
+#define HIL_IDD_HAS_GEN_PROMPT(header_ptr) \
+((*header_ptr & HIL_IDD_HEADER_IOD) && \
+ (HIL_IDD_IOD(header_ptr) & HIL_IDD_IOD_PROMPT))
+
+#define HIL_IDD_HAS_GEN_PROXIMITY(header_ptr) \
+((*header_ptr & HIL_IDD_HEADER_IOD) && \
+ (HIL_IDD_IOD(header_ptr) & HIL_IDD_IOD_PROXIMITY))
+
+#define HIL_IDD_NUM_BUTTONS(header_ptr) \
+((*header_ptr & HIL_IDD_HEADER_IOD) ? \
+ (HIL_IDD_IOD(header_ptr) & HIL_IDD_IOD_NBUTTON_MASK) : 0)
+
+#define HIL_IDD_NUM_PROMPTS(header_ptr) \
+((*header_ptr & HIL_IDD_HEADER_IOD) ? \
+ ((HIL_IDD_IOD(header_ptr) & HIL_IDD_IOD_NPROMPT_MASK) \
+ >> HIL_IDD_IOD_PROMPT_SHIFT) : 0)
+
+/* The response to HIL EXD commands -- the "extended describe record" */
+#define HIL_EXD_HEADER_WRG 0x03 /* Supports type2 WRG */
+#define HIL_EXD_HEADER_WRG_TYPE1 0x01 /* Supports type1 WRG */
+#define HIL_EXD_HEADER_WRG_TYPE2 0x02 /* Supports type2 WRG */
+#define HIL_EXD_HEADER_RRG 0x04 /* Supports RRG command */
+#define HIL_EXD_HEADER_RNM 0x10 /* Supports RNM command */
+#define HIL_EXD_HEADER_RST 0x20 /* Supports RST command */
+#define HIL_EXD_HEADER_LOCALE 0x40 /* Contains locale code */
+
+#define HIL_EXD_NUM_RRG(header_ptr) \
+((*header_ptr & HIL_EXD_HEADER_RRG) ? \
+ (*(header_ptr + 1) & HIL_PKT_DATA_MASK) : 0)
+
+#define HIL_EXD_NUM_WWG(header_ptr) \
+((*header_ptr & HIL_EXD_HEADER_WRG) ? \
+ (*(header_ptr + 2 - !(*header_ptr & HIL_EXD_HEADER_RRG)) & \
+ HIL_PKT_DATA_MASK) : 0)
+
+#define HIL_EXD_LEN(header_ptr) \
+(!!(*header_ptr & HIL_EXD_HEADER_RRG) + \
+ !!(*header_ptr & HIL_EXD_HEADER_WRG) + \
+ !!(*header_ptr & HIL_EXD_HEADER_LOCALE) + \
+ 2 * !!(*header_ptr & HIL_EXD_HEADER_WRG_TYPE2) + 1)
+
+#define HIL_EXD_LOCALE(header_ptr) \
+(!(*header_ptr & HIL_EXD_HEADER_LOCALE) ? -1 : \
+ (*(header_ptr + HIL_EXD_LEN(header_ptr) - 1) & HIL_PKT_DATA_MASK))
+
+#define HIL_EXD_WRG_TYPE2_LEN(header_ptr) \
+(!(*header_ptr & HIL_EXD_HEADER_WRG_TYPE2) ? -1 : \
+ (*(header_ptr + HIL_EXD_LEN(header_ptr) - 2 - \
+ !!(*header_ptr & HIL_EXD_HEADER_LOCALE)) & HIL_PKT_DATA_MASK) + \
+ ((*(header_ptr + HIL_EXD_LEN(header_ptr) - 1 - \
+ !!(*header_ptr & HIL_EXD_HEADER_LOCALE)) & HIL_PKT_DATA_MASK) << 8))
+
+/* Device locale codes. */
+
+/* Last defined locale code. Everything above this is "Reserved",
+ and note that this same table applies to the Device ID Byte where
+ keyboards may have a nationality code which is only 5 bits. */
+#define HIL_LOCALE_MAX 0x1f
+
+/* Map to hopefully useful strings. I was trying to make these look
+ like locale.aliases strings do; maybe that isn't the right table to
+ emulate. In either case, I didn't have much to work on. */
+#define HIL_LOCALE_MAP \
+"", /* 0x00 Reserved */ \
+"", /* 0x01 Reserved */ \
+"", /* 0x02 Reserved */ \
+"swiss.french", /* 0x03 Swiss/French */ \
+"portuguese", /* 0x04 Portuguese */ \
+"arabic", /* 0x05 Arabic */ \
+"hebrew", /* 0x06 Hebrew */ \
+"english.canadian", /* 0x07 Canadian English */ \
+"turkish", /* 0x08 Turkish */ \
+"greek", /* 0x09 Greek */ \
+"thai", /* 0x0a Thai (Thailand) */ \
+"italian", /* 0x0b Italian */ \
+"korean", /* 0x0c Hangul (Korea) */ \
+"dutch", /* 0x0d Dutch */ \
+"swedish", /* 0x0e Swedish */ \
+"german", /* 0x0f German */ \
+"chinese", /* 0x10 Chinese-PRC */ \
+"chinese", /* 0x11 Chinese-ROC */ \
+"swiss.french", /* 0x12 Swiss/French II */ \
+"spanish", /* 0x13 Spanish */ \
+"swiss.german", /* 0x14 Swiss/German II */ \
+"flemish", /* 0x15 Belgian (Flemish) */ \
+"finnish", /* 0x16 Finnish */ \
+"english.uk", /* 0x17 United Kingdom */ \
+"french.canadian", /* 0x18 French/Canadian */ \
+"swiss.german", /* 0x19 Swiss/German */ \
+"norwegian", /* 0x1a Norwegian */ \
+"french", /* 0x1b French */ \
+"danish", /* 0x1c Danish */ \
+"japanese", /* 0x1d Katakana */ \
+"spanish", /* 0x1e Latin American/Spanish*/\
+"english.us" /* 0x1f United States */ \
+
+
+/* HIL keycodes */
+#define HIL_KEYCODES_SET1_TBLSIZE 128
+#define HIL_KEYCODES_SET1 \
+ KEY_5, KEY_RESERVED, KEY_RIGHTALT, KEY_LEFTALT, \
+ KEY_RIGHTSHIFT, KEY_LEFTSHIFT, KEY_LEFTCTRL, KEY_SYSRQ, \
+ KEY_KP4, KEY_KP8, KEY_KP5, KEY_KP9, \
+ KEY_KP6, KEY_KP7, KEY_KPCOMMA, KEY_KPENTER, \
+ KEY_KP1, KEY_KPSLASH, KEY_KP2, KEY_KPPLUS, \
+ KEY_KP3, KEY_KPASTERISK, KEY_KP0, KEY_KPMINUS, \
+ KEY_B, KEY_V, KEY_C, KEY_X, \
+ KEY_Z, KEY_RESERVED, KEY_RESERVED, KEY_ESC, \
+ KEY_6, KEY_F10, KEY_3, KEY_F11, \
+ KEY_KPDOT, KEY_F9, KEY_TAB /*KP*/, KEY_F12, \
+ KEY_H, KEY_G, KEY_F, KEY_D, \
+ KEY_S, KEY_A, KEY_RESERVED, KEY_CAPSLOCK, \
+ KEY_U, KEY_Y, KEY_T, KEY_R, \
+ KEY_E, KEY_W, KEY_Q, KEY_TAB, \
+ KEY_7, KEY_6, KEY_5, KEY_4, \
+ KEY_3, KEY_2, KEY_1, KEY_GRAVE, \
+ KEY_F13, KEY_F14, KEY_F15, KEY_F16, \
+ KEY_F17, KEY_F18, KEY_F19, KEY_F20, \
+ KEY_MENU, KEY_F4, KEY_F3, KEY_F2, \
+ KEY_F1, KEY_VOLUMEUP, KEY_STOP, KEY_SENDFILE, \
+ KEY_SYSRQ, KEY_F5, KEY_F6, KEY_F7, \
+ KEY_F8, KEY_VOLUMEDOWN, KEY_DEL_EOL, KEY_DEL_EOS, \
+ KEY_8, KEY_9, KEY_0, KEY_MINUS, \
+ KEY_EQUAL, KEY_BACKSPACE, KEY_INS_LINE, KEY_DEL_LINE, \
+ KEY_I, KEY_O, KEY_P, KEY_LEFTBRACE, \
+ KEY_RIGHTBRACE, KEY_BACKSLASH, KEY_INSERT, KEY_DELETE, \
+ KEY_J, KEY_K, KEY_L, KEY_SEMICOLON, \
+ KEY_APOSTROPHE, KEY_ENTER, KEY_HOME, KEY_PAGEUP, \
+ KEY_M, KEY_COMMA, KEY_DOT, KEY_SLASH, \
+ KEY_BACKSLASH, KEY_SELECT, KEY_102ND, KEY_PAGEDOWN, \
+ KEY_N, KEY_SPACE, KEY_NEXT, KEY_RESERVED, \
+ KEY_LEFT, KEY_DOWN, KEY_UP, KEY_RIGHT
+
+
+#define HIL_KEYCODES_SET3_TBLSIZE 128
+#define HIL_KEYCODES_SET3 \
+ KEY_RESERVED, KEY_ESC, KEY_1, KEY_2, \
+ KEY_3, KEY_4, KEY_5, KEY_6, \
+ KEY_7, KEY_8, KEY_9, KEY_0, \
+ KEY_MINUS, KEY_EQUAL, KEY_BACKSPACE, KEY_TAB, \
+ KEY_Q, KEY_W, KEY_E, KEY_R, \
+ KEY_T, KEY_Y, KEY_U, KEY_I, \
+ KEY_O, KEY_P, KEY_LEFTBRACE, KEY_RIGHTBRACE, \
+ KEY_ENTER, KEY_LEFTCTRL, KEY_A, KEY_S, \
+ KEY_D, KEY_F, KEY_G, KEY_H, \
+ KEY_J, KEY_K, KEY_L, KEY_SEMICOLON, \
+ KEY_APOSTROPHE,KEY_GRAVE, KEY_LEFTSHIFT, KEY_BACKSLASH, \
+ KEY_Z, KEY_X, KEY_C, KEY_V, \
+ KEY_B, KEY_N, KEY_M, KEY_COMMA, \
+ KEY_DOT, KEY_SLASH, KEY_RIGHTSHIFT, KEY_KPASTERISK, \
+ KEY_LEFTALT, KEY_SPACE, KEY_CAPSLOCK, KEY_F1, \
+ KEY_F2, KEY_F3, KEY_F4, KEY_F5, \
+ KEY_F6, KEY_F7, KEY_F8, KEY_F9, \
+ KEY_F10, KEY_NUMLOCK, KEY_SCROLLLOCK, KEY_KP7, \
+ KEY_KP8, KEY_KP9, KEY_KPMINUS, KEY_KP4, \
+ KEY_KP5, KEY_KP6, KEY_KPPLUS, KEY_KP1, \
+ KEY_KP2, KEY_KP3, KEY_KP0, KEY_KPDOT, \
+ KEY_SYSRQ, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, \
+ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, \
+ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, \
+ KEY_UP, KEY_LEFT, KEY_DOWN, KEY_RIGHT, \
+ KEY_HOME, KEY_PAGEUP, KEY_END, KEY_PAGEDOWN, \
+ KEY_INSERT, KEY_DELETE, KEY_102ND, KEY_RESERVED, \
+ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, \
+ KEY_F1, KEY_F2, KEY_F3, KEY_F4, \
+ KEY_F5, KEY_F6, KEY_F7, KEY_F8, \
+ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, \
+ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED
+
+
+/* Response to POL command, the "poll record header" */
+
+#define HIL_POL_NUM_AXES_MASK 0x03 /* Number of axis reported */
+#define HIL_POL_CTS 0x04 /* Device ready to receive data */
+#define HIL_POL_STATUS_PENDING 0x08 /* Device has status to report */
+#define HIL_POL_CHARTYPE_MASK 0x70 /* Type of character data to follow */
+#define HIL_POL_CHARTYPE_NONE 0x00 /* No character data to follow */
+#define HIL_POL_CHARTYPE_RSVD1 0x10 /* Reserved Set 1 */
+#define HIL_POL_CHARTYPE_ASCII 0x20 /* U.S. ASCII */
+#define HIL_POL_CHARTYPE_BINARY 0x30 /* Binary data */
+#define HIL_POL_CHARTYPE_SET1 0x40 /* Keycode Set 1 */
+#define HIL_POL_CHARTYPE_RSVD2 0x50 /* Reserved Set 2 */
+#define HIL_POL_CHARTYPE_SET2 0x60 /* Keycode Set 2 */
+#define HIL_POL_CHARTYPE_SET3 0x70 /* Keycode Set 3 */
+#define HIL_POL_AXIS_ALT 0x80 /* Data is from axis set 2 */
+
+
+#endif /* _HIL_H_ */
diff --git a/include/linux/hil_mlc.h b/include/linux/hil_mlc.h
new file mode 100644
index 000000000000..8df29ca48a13
--- /dev/null
+++ b/include/linux/hil_mlc.h
@@ -0,0 +1,168 @@
+/*
+ * HP Human Interface Loop Master Link Controller driver.
+ *
+ * Copyright (c) 2001 Brian S. Julin
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL").
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ *
+ * References:
+ * HP-HIL Technical Reference Manual. Hewlett Packard Product No. 45918A
+ *
+ */
+
+#include <linux/hil.h>
+#include <linux/time.h>
+#include <linux/interrupt.h>
+#include <asm/semaphore.h>
+#include <linux/serio.h>
+#include <linux/list.h>
+
+typedef struct hil_mlc hil_mlc;
+
+/* The HIL has a complicated state engine.
+ * We define the structure of nodes in the state engine here.
+ */
+enum hilse_act {
+ /* HILSE_OUT prepares to receive input if the next node
+ * is an IN or EXPECT, and then sends the given packet.
+ */
+ HILSE_OUT = 0,
+
+ /* HILSE_CTS checks if the loop is busy. */
+ HILSE_CTS,
+
+ /* HILSE_OUT_LAST sends the given command packet to
+ * the last configured/running device on the loop.
+ */
+ HILSE_OUT_LAST,
+
+ /* HILSE_OUT_DISC sends the given command packet to
+ * the next device past the last configured/running one.
+ */
+ HILSE_OUT_DISC,
+
+ /* HILSE_FUNC runs a callback function with given arguments.
+ * a positive return value causes the "ugly" branch to be taken.
+ */
+ HILSE_FUNC,
+
+ /* HILSE_IN simply expects any non-errored packet to arrive
+ * within arg usecs.
+ */
+ HILSE_IN = 0x100,
+
+ /* HILSE_EXPECT expects a particular packet to arrive
+ * within arg usecs, any other packet is considered an error.
+ */
+ HILSE_EXPECT,
+
+ /* HILSE_EXPECT_LAST as above but dev field should be last
+ * discovered/operational device.
+ */
+ HILSE_EXPECT_LAST,
+
+ /* HILSE_EXPECT_LAST as above but dev field should be first
+ * undiscovered/inoperational device.
+ */
+ HILSE_EXPECT_DISC
+};
+
+typedef int (hilse_func) (hil_mlc *mlc, int arg);
+struct hilse_node {
+ enum hilse_act act; /* How to process this node */
+ union {
+ hilse_func *func; /* Function to call if HILSE_FUNC */
+ hil_packet packet; /* Packet to send or to compare */
+ } object;
+ int arg; /* Timeout in usec or parm for func */
+ int good; /* Node to jump to on success */
+ int bad; /* Node to jump to on error */
+ int ugly; /* Node to jump to on timeout */
+};
+
+/* Methods for back-end drivers, e.g. hp_sdc_mlc */
+typedef int (hil_mlc_cts) (hil_mlc *mlc);
+typedef void (hil_mlc_out) (hil_mlc *mlc);
+typedef int (hil_mlc_in) (hil_mlc *mlc, suseconds_t timeout);
+
+struct hil_mlc_devinfo {
+ uint8_t idd[16]; /* Device ID Byte and Describe Record */
+ uint8_t rsc[16]; /* Security Code Header and Record */
+ uint8_t exd[16]; /* Extended Describe Record */
+ uint8_t rnm[16]; /* Device name as returned by RNM command */
+};
+
+struct hil_mlc_serio_map {
+ hil_mlc *mlc;
+ int di_revmap;
+ int didx;
+};
+
+/* How many (possibly old/detached) devices the we try to keep track of */
+#define HIL_MLC_DEVMEM 16
+
+struct hil_mlc {
+ struct list_head list; /* hil_mlc is organized as linked list */
+
+ rwlock_t lock;
+
+ void *priv; /* Data specific to a particular type of MLC */
+
+ int seidx; /* Current node in state engine */
+ int istarted, ostarted;
+
+ hil_mlc_cts *cts;
+ struct semaphore csem; /* Raised when loop idle */
+
+ hil_mlc_out *out;
+ struct semaphore osem; /* Raised when outpacket dispatched */
+ hil_packet opacket;
+
+ hil_mlc_in *in;
+ struct semaphore isem; /* Raised when a packet arrives */
+ hil_packet ipacket[16];
+ hil_packet imatch;
+ int icount;
+ struct timeval instart;
+ suseconds_t intimeout;
+
+ int ddi; /* Last operational device id */
+ int lcv; /* LCV to throttle loops */
+ struct timeval lcv_tv; /* Time loop was started */
+
+ int di_map[7]; /* Maps below items to live devs */
+ struct hil_mlc_devinfo di[HIL_MLC_DEVMEM];
+ struct serio *serio[HIL_MLC_DEVMEM];
+ struct hil_mlc_serio_map serio_map[HIL_MLC_DEVMEM];
+ hil_packet serio_opacket[HIL_MLC_DEVMEM];
+ int serio_oidx[HIL_MLC_DEVMEM];
+ struct hil_mlc_devinfo di_scratch; /* Temporary area */
+
+ int opercnt;
+
+ struct tasklet_struct *tasklet;
+};
+
+int hil_mlc_register(hil_mlc *mlc);
+int hil_mlc_unregister(hil_mlc *mlc);
diff --git a/include/linux/hp_sdc.h b/include/linux/hp_sdc.h
new file mode 100644
index 000000000000..debd71515312
--- /dev/null
+++ b/include/linux/hp_sdc.h
@@ -0,0 +1,300 @@
+/*
+ * HP i8042 System Device Controller -- header
+ *
+ * Copyright (c) 2001 Brian S. Julin
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL").
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ *
+ * References:
+ *
+ * HP-HIL Technical Reference Manual. Hewlett Packard Product No. 45918A
+ *
+ * System Device Controller Microprocessor Firmware Theory of Operation
+ * for Part Number 1820-4784 Revision B. Dwg No. A-1820-4784-2
+ *
+ */
+
+#ifndef _LINUX_HP_SDC_H
+#define _LINUX_HP_SDC_H
+
+#include <linux/interrupt.h>
+#include <linux/types.h>
+#include <linux/time.h>
+#include <linux/timer.h>
+#if defined(__hppa__)
+#include <asm/hardware.h>
+#endif
+
+
+/* No 4X status reads take longer than this (in usec).
+ */
+#define HP_SDC_MAX_REG_DELAY 20000
+
+typedef void (hp_sdc_irqhook) (int irq, void *dev_id,
+ uint8_t status, uint8_t data);
+
+int hp_sdc_request_timer_irq(hp_sdc_irqhook *callback);
+int hp_sdc_request_hil_irq(hp_sdc_irqhook *callback);
+int hp_sdc_request_cooked_irq(hp_sdc_irqhook *callback);
+int hp_sdc_release_timer_irq(hp_sdc_irqhook *callback);
+int hp_sdc_release_hil_irq(hp_sdc_irqhook *callback);
+int hp_sdc_release_cooked_irq(hp_sdc_irqhook *callback);
+
+typedef struct {
+ int actidx; /* Start of act. Acts are atomic WRT I/O to SDC */
+ int idx; /* Index within the act */
+ int endidx; /* transaction is over and done if idx == endidx */
+ uint8_t *seq; /* commands/data for the transaction */
+ union {
+ hp_sdc_irqhook *irqhook; /* Callback, isr or tasklet context */
+ struct semaphore *semaphore; /* Semaphore to sleep on. */
+ } act;
+} hp_sdc_transaction;
+int hp_sdc_enqueue_transaction(hp_sdc_transaction *this);
+int hp_sdc_dequeue_transaction(hp_sdc_transaction *this);
+
+/* The HP_SDC_ACT* values are peculiar to this driver.
+ * Nuance: never HP_SDC_ACT_DATAIN | HP_SDC_ACT_DEALLOC, use another
+ * act to perform the dealloc.
+ */
+#define HP_SDC_ACT_PRECMD 0x01 /* Send a command first */
+#define HP_SDC_ACT_DATAREG 0x02 /* Set data registers */
+#define HP_SDC_ACT_DATAOUT 0x04 /* Send data bytes */
+#define HP_SDC_ACT_POSTCMD 0x08 /* Send command after */
+#define HP_SDC_ACT_DATAIN 0x10 /* Collect data after */
+#define HP_SDC_ACT_DURING 0x1f
+#define HP_SDC_ACT_SEMAPHORE 0x20 /* Raise semaphore after */
+#define HP_SDC_ACT_CALLBACK 0x40 /* Pass data to IRQ handler */
+#define HP_SDC_ACT_DEALLOC 0x80 /* Destroy transaction after */
+#define HP_SDC_ACT_AFTER 0xe0
+#define HP_SDC_ACT_DEAD 0x60 /* Act timed out. */
+
+/* Rest of the flags are straightforward representation of the SDC interface */
+#define HP_SDC_STATUS_IBF 0x02 /* Input buffer full */
+
+#define HP_SDC_STATUS_IRQMASK 0xf0 /* Bits containing "level 1" irq */
+#define HP_SDC_STATUS_PERIODIC 0x10 /* Periodic 10ms timer */
+#define HP_SDC_STATUS_USERTIMER 0x20 /* "Special purpose" timer */
+#define HP_SDC_STATUS_TIMER 0x30 /* Both PERIODIC and USERTIMER */
+#define HP_SDC_STATUS_REG 0x40 /* Data from an i8042 register */
+#define HP_SDC_STATUS_HILCMD 0x50 /* Command from HIL MLC */
+#define HP_SDC_STATUS_HILDATA 0x60 /* Data from HIL MLC */
+#define HP_SDC_STATUS_PUP 0x70 /* Sucessful power-up self test */
+#define HP_SDC_STATUS_KCOOKED 0x80 /* Key from cooked kbd */
+#define HP_SDC_STATUS_KRPG 0xc0 /* Key from Repeat Gen */
+#define HP_SDC_STATUS_KMOD_SUP 0x10 /* Shift key is up */
+#define HP_SDC_STATUS_KMOD_CUP 0x20 /* Control key is up */
+
+#define HP_SDC_NMISTATUS_FHS 0x40 /* NMI is a fast handshake irq */
+
+/* Internal i8042 registers (there are more, but they are not too useful). */
+
+#define HP_SDC_USE 0x02 /* Resource usage (including OB bit) */
+#define HP_SDC_IM 0x04 /* Interrupt mask */
+#define HP_SDC_CFG 0x11 /* Configuration register */
+#define HP_SDC_KBLANGUAGE 0x12 /* Keyboard language */
+
+#define HP_SDC_D0 0x70 /* General purpose data buffer 0 */
+#define HP_SDC_D1 0x71 /* General purpose data buffer 1 */
+#define HP_SDC_D2 0x72 /* General purpose data buffer 2 */
+#define HP_SDC_D3 0x73 /* General purpose data buffer 3 */
+#define HP_SDC_VT1 0x74 /* Timer for voice 1 */
+#define HP_SDC_VT2 0x75 /* Timer for voice 2 */
+#define HP_SDC_VT3 0x76 /* Timer for voice 3 */
+#define HP_SDC_VT4 0x77 /* Timer for voice 4 */
+#define HP_SDC_KBN 0x78 /* Which HIL devs are Nimitz */
+#define HP_SDC_KBC 0x79 /* Which HIL devs are cooked kbds */
+#define HP_SDC_LPS 0x7a /* i8042's view of HIL status */
+#define HP_SDC_LPC 0x7b /* i8042's view of HIL "control" */
+#define HP_SDC_RSV 0x7c /* Reserved "for testing" */
+#define HP_SDC_LPR 0x7d /* i8042 count of HIL reconfigs */
+#define HP_SDC_XTD 0x7e /* "Extended Configuration" register */
+#define HP_SDC_STR 0x7f /* i8042 self-test result */
+
+/* Bitfields for above registers */
+#define HP_SDC_USE_LOOP 0x04 /* Command is currently on the loop. */
+
+#define HP_SDC_IM_MASK 0x1f /* these bits not part of cmd/status */
+#define HP_SDC_IM_FH 0x10 /* Mask the fast handshake irq */
+#define HP_SDC_IM_PT 0x08 /* Mask the periodic timer irq */
+#define HP_SDC_IM_TIMERS 0x04 /* Mask the MT/DT/CT irq */
+#define HP_SDC_IM_RESET 0x02 /* Mask the reset key irq */
+#define HP_SDC_IM_HIL 0x01 /* Mask the HIL MLC irq */
+
+#define HP_SDC_CFG_ROLLOVER 0x08 /* WTF is "N-key rollover"? */
+#define HP_SDC_CFG_KBD 0x10 /* There is a keyboard */
+#define HP_SDC_CFG_NEW 0x20 /* Supports/uses HIL MLC */
+#define HP_SDC_CFG_KBD_OLD 0x03 /* keyboard code for non-HIL */
+#define HP_SDC_CFG_KBD_NEW 0x07 /* keyboard code from HIL autoconfig */
+#define HP_SDC_CFG_REV 0x40 /* Code revision bit */
+#define HP_SDC_CFG_IDPROM 0x80 /* IDPROM present in kbd (not HIL) */
+
+#define HP_SDC_LPS_NDEV 0x07 /* # devices autoconfigured on HIL */
+#define HP_SDC_LPS_ACSUCC 0x08 /* loop autoconfigured successfully */
+#define HP_SDC_LPS_ACFAIL 0x80 /* last loop autoconfigure failed */
+
+#define HP_SDC_LPC_APE_IPF 0x01 /* HIL MLC APE/IPF (autopoll) set */
+#define HP_SDC_LPC_ARCONERR 0x02 /* i8042 autoreconfigs loop on err */
+#define HP_SDC_LPC_ARCQUIET 0x03 /* i8042 doesn't report autoreconfigs*/
+#define HP_SDC_LPC_COOK 0x10 /* i8042 cooks devices in _KBN */
+#define HP_SDC_LPC_RC 0x80 /* causes autoreconfig */
+
+#define HP_SDC_XTD_REV 0x07 /* contains revision code */
+#define HP_SDC_XTD_REV_STRINGS(val, str) \
+switch (val) { \
+ case 0x1: str = "1820-3712"; break; \
+ case 0x2: str = "1820-4379"; break; \
+ case 0x3: str = "1820-4784"; break; \
+ default: str = "unknown"; \
+};
+#define HP_SDC_XTD_BEEPER 0x08 /* TI SN76494 beeper available */
+#define HP_SDC_XTD_BBRTC 0x20 /* OKI MSM-58321 BBRTC present */
+
+#define HP_SDC_CMD_LOAD_RT 0x31 /* Load real time (from 8042) */
+#define HP_SDC_CMD_LOAD_FHS 0x36 /* Load the fast handshake timer */
+#define HP_SDC_CMD_LOAD_MT 0x38 /* Load the match timer */
+#define HP_SDC_CMD_LOAD_DT 0x3B /* Load the delay timer */
+#define HP_SDC_CMD_LOAD_CT 0x3E /* Load the cycle timer */
+
+#define HP_SDC_CMD_SET_IM 0x40 /* 010xxxxx == set irq mask */
+
+/* The documents provided do not explicitly state that all registers betweem
+ * 0x01 and 0x1f inclusive can be read by sending their register index as a
+ * command, but this is implied and appears to be the case.
+ */
+#define HP_SDC_CMD_READ_RAM 0x00 /* Load from i8042 RAM (autoinc) */
+#define HP_SDC_CMD_READ_USE 0x02 /* Undocumented! Load from usage reg */
+#define HP_SDC_CMD_READ_IM 0x04 /* Load current interrupt mask */
+#define HP_SDC_CMD_READ_KCC 0x11 /* Load primary kbd config code */
+#define HP_SDC_CMD_READ_KLC 0x12 /* Load primary kbd language code */
+#define HP_SDC_CMD_READ_T1 0x13 /* Load timer output buffer byte 1 */
+#define HP_SDC_CMD_READ_T2 0x14 /* Load timer output buffer byte 1 */
+#define HP_SDC_CMD_READ_T3 0x15 /* Load timer output buffer byte 1 */
+#define HP_SDC_CMD_READ_T4 0x16 /* Load timer output buffer byte 1 */
+#define HP_SDC_CMD_READ_T5 0x17 /* Load timer output buffer byte 1 */
+#define HP_SDC_CMD_READ_D0 0xf0 /* Load from i8042 RAM location 0x70 */
+#define HP_SDC_CMD_READ_D1 0xf1 /* Load from i8042 RAM location 0x71 */
+#define HP_SDC_CMD_READ_D2 0xf2 /* Load from i8042 RAM location 0x72 */
+#define HP_SDC_CMD_READ_D3 0xf3 /* Load from i8042 RAM location 0x73 */
+#define HP_SDC_CMD_READ_VT1 0xf4 /* Load from i8042 RAM location 0x74 */
+#define HP_SDC_CMD_READ_VT2 0xf5 /* Load from i8042 RAM location 0x75 */
+#define HP_SDC_CMD_READ_VT3 0xf6 /* Load from i8042 RAM location 0x76 */
+#define HP_SDC_CMD_READ_VT4 0xf7 /* Load from i8042 RAM location 0x77 */
+#define HP_SDC_CMD_READ_KBN 0xf8 /* Load from i8042 RAM location 0x78 */
+#define HP_SDC_CMD_READ_KBC 0xf9 /* Load from i8042 RAM location 0x79 */
+#define HP_SDC_CMD_READ_LPS 0xfa /* Load from i8042 RAM location 0x7a */
+#define HP_SDC_CMD_READ_LPC 0xfb /* Load from i8042 RAM location 0x7b */
+#define HP_SDC_CMD_READ_RSV 0xfc /* Load from i8042 RAM location 0x7c */
+#define HP_SDC_CMD_READ_LPR 0xfd /* Load from i8042 RAM location 0x7d */
+#define HP_SDC_CMD_READ_XTD 0xfe /* Load from i8042 RAM location 0x7e */
+#define HP_SDC_CMD_READ_STR 0xff /* Load from i8042 RAM location 0x7f */
+
+#define HP_SDC_CMD_SET_ARD 0xA0 /* Set emulated autorepeat delay */
+#define HP_SDC_CMD_SET_ARR 0xA2 /* Set emulated autorepeat rate */
+#define HP_SDC_CMD_SET_BELL 0xA3 /* Set voice 3 params for "beep" cmd */
+#define HP_SDC_CMD_SET_RPGR 0xA6 /* Set "RPG" irq rate (doesn't work) */
+#define HP_SDC_CMD_SET_RTMS 0xAD /* Set the RTC time (milliseconds) */
+#define HP_SDC_CMD_SET_RTD 0xAF /* Set the RTC time (days) */
+#define HP_SDC_CMD_SET_FHS 0xB2 /* Set fast handshake timer */
+#define HP_SDC_CMD_SET_MT 0xB4 /* Set match timer */
+#define HP_SDC_CMD_SET_DT 0xB7 /* Set delay timer */
+#define HP_SDC_CMD_SET_CT 0xBA /* Set cycle timer */
+#define HP_SDC_CMD_SET_RAMP 0xC1 /* Reset READ_RAM autoinc counter */
+#define HP_SDC_CMD_SET_D0 0xe0 /* Load to i8042 RAM location 0x70 */
+#define HP_SDC_CMD_SET_D1 0xe1 /* Load to i8042 RAM location 0x71 */
+#define HP_SDC_CMD_SET_D2 0xe2 /* Load to i8042 RAM location 0x72 */
+#define HP_SDC_CMD_SET_D3 0xe3 /* Load to i8042 RAM location 0x73 */
+#define HP_SDC_CMD_SET_VT1 0xe4 /* Load to i8042 RAM location 0x74 */
+#define HP_SDC_CMD_SET_VT2 0xe5 /* Load to i8042 RAM location 0x75 */
+#define HP_SDC_CMD_SET_VT3 0xe6 /* Load to i8042 RAM location 0x76 */
+#define HP_SDC_CMD_SET_VT4 0xe7 /* Load to i8042 RAM location 0x77 */
+#define HP_SDC_CMD_SET_KBN 0xe8 /* Load to i8042 RAM location 0x78 */
+#define HP_SDC_CMD_SET_KBC 0xe9 /* Load to i8042 RAM location 0x79 */
+#define HP_SDC_CMD_SET_LPS 0xea /* Load to i8042 RAM location 0x7a */
+#define HP_SDC_CMD_SET_LPC 0xeb /* Load to i8042 RAM location 0x7b */
+#define HP_SDC_CMD_SET_RSV 0xec /* Load to i8042 RAM location 0x7c */
+#define HP_SDC_CMD_SET_LPR 0xed /* Load to i8042 RAM location 0x7d */
+#define HP_SDC_CMD_SET_XTD 0xee /* Load to i8042 RAM location 0x7e */
+#define HP_SDC_CMD_SET_STR 0xef /* Load to i8042 RAM location 0x7f */
+
+#define HP_SDC_CMD_DO_RTCW 0xc2 /* i8042 RAM 0x70 --> RTC */
+#define HP_SDC_CMD_DO_RTCR 0xc3 /* RTC[0x70 0:3] --> irq/status/data */
+#define HP_SDC_CMD_DO_BEEP 0xc4 /* i8042 RAM 0x70-74 --> beeper,VT3 */
+#define HP_SDC_CMD_DO_HIL 0xc5 /* i8042 RAM 0x70-73 -->
+ HIL MLC R0,R1 i8042 HIL watchdog */
+
+/* Values used to (de)mangle input/output to/from the HIL MLC */
+#define HP_SDC_DATA 0x40 /* Data from an 8042 register */
+#define HP_SDC_HIL_CMD 0x50 /* Data from HIL MLC R1/8042 */
+#define HP_SDC_HIL_R1MASK 0x0f /* Contents of HIL MLC R1 0:3 */
+#define HP_SDC_HIL_AUTO 0x10 /* Set if POL results from i8042 */
+#define HP_SDC_HIL_ISERR 0x80 /* Has meaning as in next 4 values */
+#define HP_SDC_HIL_RC_DONE 0x80 /* i8042 auto-configured loop */
+#define HP_SDC_HIL_ERR 0x81 /* HIL MLC R2 had a bit set */
+#define HP_SDC_HIL_TO 0x82 /* i8042 HIL watchdog expired */
+#define HP_SDC_HIL_RC 0x84 /* i8042 is auto-configuring loop */
+#define HP_SDC_HIL_DAT 0x60 /* Data from HIL MLC R0 */
+
+
+typedef struct {
+ rwlock_t ibf_lock;
+ rwlock_t lock; /* user/tasklet lock */
+ rwlock_t rtq_lock; /* isr/tasklet lock */
+ rwlock_t hook_lock; /* isr/user lock for handler add/del */
+
+ unsigned int irq, nmi; /* Our IRQ lines */
+ unsigned long base_io, status_io, data_io; /* Our IO ports */
+
+ uint8_t im; /* Interrupt mask */
+ int set_im; /* Interrupt mask needs to be set. */
+
+ int ibf; /* Last known status of IBF flag */
+ uint8_t wi; /* current i8042 write index */
+ uint8_t r7[4]; /* current i8042[0x70 - 0x74] values */
+ uint8_t r11, r7e; /* Values from version/revision regs */
+
+ hp_sdc_irqhook *timer, *reg, *hil, *pup, *cooked;
+
+#define HP_SDC_QUEUE_LEN 16
+ hp_sdc_transaction *tq[HP_SDC_QUEUE_LEN]; /* All pending read/writes */
+
+ int rcurr, rqty; /* Current read transact in process */
+ struct timeval rtv; /* Time when current read started */
+ int wcurr; /* Current write transact in process */
+
+ int dev_err; /* carries status from registration */
+#if defined(__hppa__)
+ struct parisc_device *dev;
+#elif defined(__mc68000__)
+ void *dev;
+#else
+#error No support for device registration on this arch yet.
+#endif
+
+ struct timer_list kicker; /* Keeps below task alive */
+ struct tasklet_struct task;
+
+} hp_i8042_sdc;
+
+#endif /* _LINUX_HP_SDC_H */
diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h
index d664330d900e..0cea162b08c0 100644
--- a/include/linux/hugetlb.h
+++ b/include/linux/hugetlb.h
@@ -16,7 +16,6 @@ static inline int is_vm_hugetlb_page(struct vm_area_struct *vma)
int hugetlb_sysctl_handler(struct ctl_table *, int, struct file *, void __user *, size_t *, loff_t *);
int copy_hugetlb_page_range(struct mm_struct *, struct mm_struct *, struct vm_area_struct *);
int follow_hugetlb_page(struct mm_struct *, struct vm_area_struct *, struct page **, struct vm_area_struct **, unsigned long *, int *, int);
-void zap_hugepage_range(struct vm_area_struct *, unsigned long, unsigned long);
void unmap_hugepage_range(struct vm_area_struct *, unsigned long, unsigned long);
int hugetlb_prefault(struct address_space *, struct vm_area_struct *);
int hugetlb_report_meminfo(char *);
@@ -87,7 +86,6 @@ static inline unsigned long hugetlb_total_pages(void)
#define follow_huge_addr(mm, addr, write) ERR_PTR(-EINVAL)
#define copy_hugetlb_page_range(src, dst, vma) ({ BUG(); 0; })
#define hugetlb_prefault(mapping, vma) ({ BUG(); 0; })
-#define zap_hugepage_range(vma, start, len) BUG()
#define unmap_hugepage_range(vma, start, end) BUG()
#define is_hugepage_mem_enough(size) 0
#define hugetlb_report_meminfo(buf) 0
diff --git a/include/linux/i2c-algo-bit.h b/include/linux/i2c-algo-bit.h
index 110904481238..c0e7fab28ce3 100644
--- a/include/linux/i2c-algo-bit.h
+++ b/include/linux/i2c-algo-bit.h
@@ -21,8 +21,6 @@
/* With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi> and even
Frodo Looijaard <frodol@dds.nl> */
-/* $Id: i2c-algo-bit.h,v 1.10 2003/01/21 08:08:16 kmalkki Exp $ */
-
#ifndef _LINUX_I2C_ALGO_BIT_H
#define _LINUX_I2C_ALGO_BIT_H
@@ -46,8 +44,6 @@ struct i2c_algo_bit_data {
int timeout; /* in jiffies */
};
-#define I2C_BIT_ADAP_MAX 16
-
int i2c_bit_add_bus(struct i2c_adapter *);
int i2c_bit_del_bus(struct i2c_adapter *);
diff --git a/include/linux/i2c-algo-pca.h b/include/linux/i2c-algo-pca.h
index 941b786c5732..226693e0d88b 100644
--- a/include/linux/i2c-algo-pca.h
+++ b/include/linux/i2c-algo-pca.h
@@ -9,8 +9,6 @@ struct i2c_algo_pca_data {
int (*wait_for_interrupt) (struct i2c_algo_pca_data *adap);
};
-#define I2C_PCA_ADAP_MAX 16
-
int i2c_pca_add_bus(struct i2c_adapter *);
int i2c_pca_del_bus(struct i2c_adapter *);
diff --git a/include/linux/i2c-algo-pcf.h b/include/linux/i2c-algo-pcf.h
index 2a508562255f..18b0adf57a3d 100644
--- a/include/linux/i2c-algo-pcf.h
+++ b/include/linux/i2c-algo-pcf.h
@@ -22,8 +22,6 @@
/* With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi> and even
Frodo Looijaard <frodol@dds.nl> */
-/* $Id: i2c-algo-pcf.h,v 1.8 2003/01/21 08:08:16 kmalkki Exp $ */
-
#ifndef _LINUX_I2C_ALGO_PCF_H
#define _LINUX_I2C_ALGO_PCF_H
@@ -41,8 +39,6 @@ struct i2c_algo_pcf_data {
int timeout;
};
-#define I2C_PCF_ADAP_MAX 16
-
int i2c_pcf_add_bus(struct i2c_adapter *);
int i2c_pcf_del_bus(struct i2c_adapter *);
diff --git a/include/linux/i2c-dev.h b/include/linux/i2c-dev.h
index 541695679762..81c229a0fbca 100644
--- a/include/linux/i2c-dev.h
+++ b/include/linux/i2c-dev.h
@@ -19,8 +19,6 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* $Id: i2c-dev.h,v 1.13 2003/01/21 08:08:16 kmalkki Exp $ */
-
#ifndef _LINUX_I2C_DEV_H
#define _LINUX_I2C_DEV_H
diff --git a/include/linux/i2c-id.h b/include/linux/i2c-id.h
index 44f30876a1c9..74abaecdb572 100644
--- a/include/linux/i2c-id.h
+++ b/include/linux/i2c-id.h
@@ -27,10 +27,10 @@
* ---- Driver types -----------------------------------------------------
* device id name + number function description, i2c address(es)
*
- * Range 1000-1999 range is defined in sensors/sensors.h
- * Range 0x100 - 0x1ff is for V4L2 Common Components
+ * Range 1000-1999 range is defined in sensors/sensors.h
+ * Range 0x100 - 0x1ff is for V4L2 Common Components
* Range 0xf000 - 0xffff is reserved for local experimentation, and should
- * never be used in official drivers
+ * never be used in official drivers
*/
#define I2C_DRIVERID_MSP3400 1
@@ -99,7 +99,14 @@
#define I2C_DRIVERID_MAX6900 63 /* MAX6900 real-time clock */
#define I2C_DRIVERID_SAA7114H 64 /* video decoder */
#define I2C_DRIVERID_DS1374 65 /* DS1374 real time clock */
-
+#define I2C_DRIVERID_TDA9874 66 /* TV sound decoder */
+#define I2C_DRIVERID_SAA6752HS 67 /* MPEG2 encoder */
+#define I2C_DRIVERID_TVEEPROM 68 /* TV EEPROM */
+#define I2C_DRIVERID_WM8775 69 /* wm8775 audio processor */
+#define I2C_DRIVERID_CS53L32A 70 /* cs53l32a audio processor */
+#define I2C_DRIVERID_CX25840 71 /* cx2584x video encoder */
+#define I2C_DRIVERID_SAA7127 72 /* saa7124 video encoder */
+#define I2C_DRIVERID_SAA711X 73 /* saa711x video encoders */
#define I2C_DRIVERID_EXP0 0xF0 /* experimental use id's */
#define I2C_DRIVERID_EXP1 0xF1
@@ -111,7 +118,7 @@
#define I2C_DRIVERID_ARP 902 /* SMBus ARP Client */
#define I2C_DRIVERID_ALERT 903 /* SMBus Alert Responder Client */
-/* IDs -- Use DRIVERIDs 1000-1999 for sensors.
+/* IDs -- Use DRIVERIDs 1000-1999 for sensors.
These were originally in sensors.h in the lm_sensors package */
#define I2C_DRIVERID_LM78 1002
#define I2C_DRIVERID_LM75 1003
@@ -164,10 +171,7 @@
/* --- Bit algorithm adapters */
#define I2C_HW_B_LP 0x010000 /* Parallel port Philips style */
-#define I2C_HW_B_LPC 0x010001 /* Parallel port control reg. */
#define I2C_HW_B_SER 0x010002 /* Serial line interface */
-#define I2C_HW_B_ELV 0x010003 /* ELV Card */
-#define I2C_HW_B_VELLE 0x010004 /* Vellemann K8000 */
#define I2C_HW_B_BT848 0x010005 /* BT848 video boards */
#define I2C_HW_B_WNV 0x010006 /* Winnov Videums */
#define I2C_HW_B_VIA 0x010007 /* Via vt82c586b */
@@ -193,6 +197,7 @@
#define I2C_HW_B_NVIDIA 0x01001c /* nvidia framebuffer driver */
#define I2C_HW_B_SAVAGE 0x01001d /* savage framebuffer driver */
#define I2C_HW_B_RADEON 0x01001e /* radeon framebuffer driver */
+#define I2C_HW_B_EM28XX 0x01001f /* em28xx video capture cards */
/* --- PCF 8584 based algorithms */
#define I2C_HW_P_LP 0x020000 /* Parallel port interface */
diff --git a/include/linux/i2c.h b/include/linux/i2c.h
index 3d49a305bf88..5e19a7ba69b2 100644
--- a/include/linux/i2c.h
+++ b/include/linux/i2c.h
@@ -23,15 +23,15 @@
/* With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi> and
Frodo Looijaard <frodol@dds.nl> */
-/* $Id: i2c.h,v 1.68 2003/01/21 08:08:16 kmalkki Exp $ */
-
#ifndef _LINUX_I2C_H
#define _LINUX_I2C_H
#include <linux/module.h>
#include <linux/types.h>
#include <linux/i2c-id.h>
+#include <linux/mod_devicetable.h>
#include <linux/device.h> /* for struct device */
+#include <linux/sched.h> /* for completion */
#include <asm/semaphore.h>
/* --- For i2c-isa ---------------------------------------------------- */
@@ -94,10 +94,10 @@ extern s32 i2c_smbus_write_byte_data(struct i2c_client * client,
extern s32 i2c_smbus_read_word_data(struct i2c_client * client, u8 command);
extern s32 i2c_smbus_write_word_data(struct i2c_client * client,
u8 command, u16 value);
-/* Returns the number of bytes transferred */
extern s32 i2c_smbus_write_block_data(struct i2c_client * client,
u8 command, u8 length,
u8 *values);
+/* Returns the number of read bytes */
extern s32 i2c_smbus_read_i2c_block_data(struct i2c_client * client,
u8 command, u8 *values);
@@ -391,10 +391,6 @@ struct i2c_msg {
#define I2C_FUNC_10BIT_ADDR 0x00000002
#define I2C_FUNC_PROTOCOL_MANGLING 0x00000004 /* I2C_M_{REV_DIR_ADDR,NOSTART,..} */
#define I2C_FUNC_SMBUS_HWPEC_CALC 0x00000008 /* SMBus 2.0 */
-#define I2C_FUNC_SMBUS_READ_WORD_DATA_PEC 0x00000800 /* SMBus 2.0 */
-#define I2C_FUNC_SMBUS_WRITE_WORD_DATA_PEC 0x00001000 /* SMBus 2.0 */
-#define I2C_FUNC_SMBUS_PROC_CALL_PEC 0x00002000 /* SMBus 2.0 */
-#define I2C_FUNC_SMBUS_BLOCK_PROC_CALL_PEC 0x00004000 /* SMBus 2.0 */
#define I2C_FUNC_SMBUS_BLOCK_PROC_CALL 0x00008000 /* SMBus 2.0 */
#define I2C_FUNC_SMBUS_QUICK 0x00010000
#define I2C_FUNC_SMBUS_READ_BYTE 0x00020000
@@ -410,8 +406,6 @@ struct i2c_msg {
#define I2C_FUNC_SMBUS_WRITE_I2C_BLOCK 0x08000000 /* w/ 1-byte reg. addr. */
#define I2C_FUNC_SMBUS_READ_I2C_BLOCK_2 0x10000000 /* I2C-like block xfer */
#define I2C_FUNC_SMBUS_WRITE_I2C_BLOCK_2 0x20000000 /* w/ 2-byte reg. addr. */
-#define I2C_FUNC_SMBUS_READ_BLOCK_DATA_PEC 0x40000000 /* SMBus 2.0 */
-#define I2C_FUNC_SMBUS_WRITE_BLOCK_DATA_PEC 0x80000000 /* SMBus 2.0 */
#define I2C_FUNC_SMBUS_BYTE (I2C_FUNC_SMBUS_READ_BYTE | \
I2C_FUNC_SMBUS_WRITE_BYTE)
@@ -425,17 +419,6 @@ struct i2c_msg {
I2C_FUNC_SMBUS_WRITE_I2C_BLOCK)
#define I2C_FUNC_SMBUS_I2C_BLOCK_2 (I2C_FUNC_SMBUS_READ_I2C_BLOCK_2 | \
I2C_FUNC_SMBUS_WRITE_I2C_BLOCK_2)
-#define I2C_FUNC_SMBUS_BLOCK_DATA_PEC (I2C_FUNC_SMBUS_READ_BLOCK_DATA_PEC | \
- I2C_FUNC_SMBUS_WRITE_BLOCK_DATA_PEC)
-#define I2C_FUNC_SMBUS_WORD_DATA_PEC (I2C_FUNC_SMBUS_READ_WORD_DATA_PEC | \
- I2C_FUNC_SMBUS_WRITE_WORD_DATA_PEC)
-
-#define I2C_FUNC_SMBUS_READ_BYTE_PEC I2C_FUNC_SMBUS_READ_BYTE_DATA
-#define I2C_FUNC_SMBUS_WRITE_BYTE_PEC I2C_FUNC_SMBUS_WRITE_BYTE_DATA
-#define I2C_FUNC_SMBUS_READ_BYTE_DATA_PEC I2C_FUNC_SMBUS_READ_WORD_DATA
-#define I2C_FUNC_SMBUS_WRITE_BYTE_DATA_PEC I2C_FUNC_SMBUS_WRITE_WORD_DATA
-#define I2C_FUNC_SMBUS_BYTE_PEC I2C_FUNC_SMBUS_BYTE_DATA
-#define I2C_FUNC_SMBUS_BYTE_DATA_PEC I2C_FUNC_SMBUS_WORD_DATA
#define I2C_FUNC_SMBUS_EMUL (I2C_FUNC_SMBUS_QUICK | \
I2C_FUNC_SMBUS_BYTE | \
@@ -443,20 +426,17 @@ struct i2c_msg {
I2C_FUNC_SMBUS_WORD_DATA | \
I2C_FUNC_SMBUS_PROC_CALL | \
I2C_FUNC_SMBUS_WRITE_BLOCK_DATA | \
- I2C_FUNC_SMBUS_WRITE_BLOCK_DATA_PEC | \
I2C_FUNC_SMBUS_I2C_BLOCK)
/*
* Data for SMBus Messages
*/
#define I2C_SMBUS_BLOCK_MAX 32 /* As specified in SMBus standard */
-#define I2C_SMBUS_I2C_BLOCK_MAX 32 /* Not specified but we use same structure */
union i2c_smbus_data {
__u8 byte;
__u16 word;
- __u8 block[I2C_SMBUS_BLOCK_MAX + 3]; /* block[0] is used for length */
- /* one more for read length in block process call */
- /* and one more for PEC */
+ __u8 block[I2C_SMBUS_BLOCK_MAX + 2]; /* block[0] is used for length */
+ /* and one more for user-space compatibility */
};
/* smbus_access read or write markers */
@@ -473,10 +453,6 @@ union i2c_smbus_data {
#define I2C_SMBUS_BLOCK_DATA 5
#define I2C_SMBUS_I2C_BLOCK_DATA 6
#define I2C_SMBUS_BLOCK_PROC_CALL 7 /* SMBus 2.0 */
-#define I2C_SMBUS_BLOCK_DATA_PEC 8 /* SMBus 2.0 */
-#define I2C_SMBUS_PROC_CALL_PEC 9 /* SMBus 2.0 */
-#define I2C_SMBUS_BLOCK_PROC_CALL_PEC 10 /* SMBus 2.0 */
-#define I2C_SMBUS_WORD_DATA_PEC 11 /* SMBus 2.0 */
/* ----- commands for the ioctl like i2c_command call:
@@ -506,11 +482,6 @@ union i2c_smbus_data {
#define I2C_SMBUS 0x0720 /* SMBus-level access */
-/* ... algo-bit.c recognizes */
-#define I2C_UDELAY 0x0705 /* set delay in microsecs between each */
- /* written byte (except address) */
-#define I2C_MDELAY 0x0706 /* millisec delay between written bytes */
-
/* ----- I2C-DEV: char device interface stuff ------------------------- */
#define I2C_MAJOR 89 /* Device major number */
diff --git a/include/linux/i2o.h b/include/linux/i2o.h
index bdc286ec947c..d79c8a4bc4f8 100644
--- a/include/linux/i2o.h
+++ b/include/linux/i2o.h
@@ -25,10 +25,14 @@
/* How many different OSM's are we allowing */
#define I2O_MAX_DRIVERS 8
-#include <asm/io.h>
-#include <asm/semaphore.h> /* Needed for MUTEX init macros */
#include <linux/pci.h>
#include <linux/dma-mapping.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/workqueue.h> /* work_struct */
+
+#include <asm/io.h>
+#include <asm/semaphore.h> /* Needed for MUTEX init macros */
/* message queue empty */
#define I2O_QUEUE_EMPTY 0xffffffff
@@ -66,8 +70,6 @@ struct i2o_device {
struct device device;
struct semaphore lock; /* device lock */
-
- struct class_device classdev; /* i2o device class */
};
/*
@@ -194,7 +196,7 @@ struct i2o_controller {
struct resource mem_resource; /* Mem resource allocated to the IOP */
struct device device;
- struct class_device classdev; /* I2O controller class */
+ struct class_device *classdev; /* I2O controller class device */
struct i2o_device *exec; /* Executive */
#if BITS_PER_LONG == 64
spinlock_t context_list_lock; /* lock for context_list */
@@ -492,7 +494,7 @@ static inline int i2o_dma_map_sg(struct i2o_controller *c,
* Returns 0 on success or -ENOMEM on failure.
*/
static inline int i2o_dma_alloc(struct device *dev, struct i2o_dma *addr,
- size_t len, unsigned int gfp_mask)
+ size_t len, gfp_t gfp_mask)
{
struct pci_dev *pdev = to_pci_dev(dev);
int dma_64 = 0;
@@ -551,7 +553,7 @@ static inline void i2o_dma_free(struct device *dev, struct i2o_dma *addr)
* Returns the 0 on success or negative error code on failure.
*/
static inline int i2o_dma_realloc(struct device *dev, struct i2o_dma *addr,
- size_t len, unsigned int gfp_mask)
+ size_t len, gfp_t gfp_mask)
{
i2o_dma_free(dev, addr);
diff --git a/include/linux/ibmtr.h b/include/linux/ibmtr.h
index 2ef0b21517fb..1c7a0dd5536a 100644
--- a/include/linux/ibmtr.h
+++ b/include/linux/ibmtr.h
@@ -7,8 +7,8 @@
/* ported to the Alpha architecture 02/20/96 (just used the HZ macro) */
#define TR_RETRY_INTERVAL (30*HZ) /* 500 on PC = 5 s */
-#define TR_RST_TIME (HZ/20) /* 5 on PC = 50 ms */
-#define TR_BUSY_INTERVAL (HZ/5) /* 5 on PC = 200 ms */
+#define TR_RST_TIME (msecs_to_jiffies(50)) /* 5 on PC = 50 ms */
+#define TR_BUSY_INTERVAL (msecs_to_jiffies(200)) /* 5 on PC = 200 ms */
#define TR_SPIN_INTERVAL (3*HZ) /* 3 seconds before init timeout */
#define TR_ISA 1
diff --git a/include/linux/ide.h b/include/linux/ide.h
index a6dbb51ecd7b..ac8b25fa6506 100644
--- a/include/linux/ide.h
+++ b/include/linux/ide.h
@@ -218,7 +218,7 @@ typedef enum { ide_unknown, ide_generic, ide_pci,
ide_rz1000, ide_trm290,
ide_cmd646, ide_cy82c693, ide_4drives,
ide_pmac, ide_etrax100, ide_acorn,
- ide_forced
+ ide_au1xxx, ide_forced
} hwif_chipset_t;
/*
@@ -230,6 +230,7 @@ typedef struct hw_regs_s {
int dma; /* our dma entry */
ide_ack_intr_t *ack_intr; /* acknowledge interrupt */
hwif_chipset_t chipset;
+ struct device *dev;
} hw_regs_t;
/*
@@ -266,6 +267,10 @@ static inline void ide_std_init_ports(hw_regs_t *hw,
#include <asm/ide.h>
+#ifndef MAX_HWIFS
+#define MAX_HWIFS CONFIG_IDE_MAX_HWIFS
+#endif
+
/* needed on alpha, x86/x86_64, ia64, mips, ppc32 and sh */
#ifndef IDE_ARCH_OBSOLETE_DEFAULTS
# define ide_default_io_base(index) (0)
@@ -1324,7 +1329,8 @@ void ide_init_disk(struct gendisk *, ide_drive_t *);
extern int ideprobe_init(void);
extern void ide_scan_pcibus(int scan_direction) __init;
-extern int ide_pci_register_driver(struct pci_driver *driver);
+extern int __ide_pci_register_driver(struct pci_driver *driver, struct module *owner);
+#define ide_pci_register_driver(d) __ide_pci_register_driver(d, THIS_MODULE)
extern void ide_pci_unregister_driver(struct pci_driver *driver);
void ide_pci_setup_ports(struct pci_dev *, struct ide_pci_device_s *, int, ata_index_t *);
extern void ide_setup_pci_noise (struct pci_dev *dev, struct ide_pci_device_s *d);
diff --git a/include/linux/idr.h b/include/linux/idr.h
index 3d5de45f961b..7fb3ff9c7b0e 100644
--- a/include/linux/idr.h
+++ b/include/linux/idr.h
@@ -71,7 +71,7 @@ struct idr {
*/
void *idr_find(struct idr *idp, int id);
-int idr_pre_get(struct idr *idp, unsigned gfp_mask);
+int idr_pre_get(struct idr *idp, gfp_t gfp_mask);
int idr_get_new(struct idr *idp, void *ptr, int *id);
int idr_get_new_above(struct idr *idp, void *ptr, int starting_id, int *id);
void idr_remove(struct idr *idp, int id);
diff --git a/include/linux/if_arp.h b/include/linux/if_arp.h
index 0856548a2a08..a8b1a2071838 100644
--- a/include/linux/if_arp.h
+++ b/include/linux/if_arp.h
@@ -84,6 +84,7 @@
#define ARPHRD_IEEE802_TR 800 /* Magic type ident for TR */
#define ARPHRD_IEEE80211 801 /* IEEE 802.11 */
#define ARPHRD_IEEE80211_PRISM 802 /* IEEE 802.11 + Prism2 header */
+#define ARPHRD_IEEE80211_RADIOTAP 803 /* IEEE 802.11 + radiotap header */
#define ARPHRD_VOID 0xFFFF /* Void type, nothing is known */
#define ARPHRD_NONE 0xFFFE /* zero header length */
diff --git a/include/linux/if_ether.h b/include/linux/if_ether.h
index d21c305c6c64..fe26d431de87 100644
--- a/include/linux/if_ether.h
+++ b/include/linux/if_ether.h
@@ -21,6 +21,8 @@
#ifndef _LINUX_IF_ETHER_H
#define _LINUX_IF_ETHER_H
+#include <linux/types.h>
+
/*
* IEEE 802.3 Ethernet magic constants. The frame sizes omit the preamble
* and FCS/CRC (frame check sequence).
@@ -100,7 +102,7 @@
struct ethhdr {
unsigned char h_dest[ETH_ALEN]; /* destination eth addr */
unsigned char h_source[ETH_ALEN]; /* source ether addr */
- unsigned short h_proto; /* packet type ID field */
+ __be16 h_proto; /* packet type ID field */
} __attribute__((packed));
#ifdef __KERNEL__
diff --git a/include/linux/if_ppp.h b/include/linux/if_ppp.h
index 572aff7daa21..768372f07caa 100644
--- a/include/linux/if_ppp.h
+++ b/include/linux/if_ppp.h
@@ -21,7 +21,7 @@
*/
/*
- * ==FILEVERSION 20000724==
+ * ==FILEVERSION 20050812==
*
* NOTE TO MAINTAINERS:
* If you modify this file at all, please set the above date.
@@ -35,6 +35,8 @@
#ifndef _IF_PPP_H_
#define _IF_PPP_H_
+#include <linux/compiler.h>
+
/*
* Packet sizes
*/
@@ -70,7 +72,8 @@
#define SC_LOG_RAWIN 0x00080000 /* log all chars received */
#define SC_LOG_FLUSH 0x00100000 /* log all chars flushed */
#define SC_SYNC 0x00200000 /* synchronous serial mode */
-#define SC_MASK 0x0f200fff /* bits that user can change */
+#define SC_MUST_COMP 0x00400000 /* no uncompressed packets may be sent or received */
+#define SC_MASK 0x0f600fff /* bits that user can change */
/* state bits */
#define SC_XMIT_BUSY 0x10000000 /* (used by isdn_ppp?) */
diff --git a/include/linux/if_wanpipe_common.h b/include/linux/if_wanpipe_common.h
index f25fec8ee2ca..6e5461d69fdd 100644
--- a/include/linux/if_wanpipe_common.h
+++ b/include/linux/if_wanpipe_common.h
@@ -17,8 +17,6 @@
#ifndef _WANPIPE_SOCK_DRIVER_COMMON_H
#define _WANPIPE_SOCK_DRIVER_COMMON_H
-#include <linux/version.h>
-
typedef struct {
struct net_device *slave;
atomic_t packet_sent;
diff --git a/include/linux/input.h b/include/linux/input.h
index e8c296ff6257..3c5823368ddb 100644
--- a/include/linux/input.h
+++ b/include/linux/input.h
@@ -12,6 +12,7 @@
#ifdef __KERNEL__
#include <linux/time.h>
#include <linux/list.h>
+#include <linux/device.h>
#else
#include <sys/time.h>
#include <sys/ioctl.h>
@@ -644,6 +645,7 @@ struct input_absinfo {
#define BUS_ADB 0x17
#define BUS_I2C 0x18
#define BUS_HOST 0x19
+#define BUS_GSC 0x1A
/*
* Values describing the status of an effect
@@ -889,11 +891,15 @@ struct input_dev {
struct semaphore sem; /* serializes open and close operations */
unsigned int users;
- struct device *dev;
+ struct class_device cdev;
+ struct device *dev; /* will be removed soon */
+
+ int dynalloc; /* temporarily */
struct list_head h_list;
struct list_head node;
};
+#define to_input_dev(d) container_of(d, struct input_dev, cdev)
/*
* Structure for hotplug & device<->driver matching.
@@ -984,7 +990,24 @@ static inline void init_input_dev(struct input_dev *dev)
INIT_LIST_HEAD(&dev->node);
}
-void input_register_device(struct input_dev *);
+struct input_dev *input_allocate_device(void);
+
+static inline void input_free_device(struct input_dev *dev)
+{
+ kfree(dev);
+}
+
+static inline struct input_dev *input_get_device(struct input_dev *dev)
+{
+ return to_input_dev(class_device_get(&dev->cdev));
+}
+
+static inline void input_put_device(struct input_dev *dev)
+{
+ class_device_put(&dev->cdev);
+}
+
+int input_register_device(struct input_dev *);
void input_unregister_device(struct input_dev *);
void input_register_handler(struct input_handler *);
@@ -1052,7 +1075,7 @@ static inline void input_set_abs_params(struct input_dev *dev, int axis, int min
dev->absbit[LONG(axis)] |= BIT(axis);
}
-extern struct class *input_class;
+extern struct class input_class;
#endif
#endif
diff --git a/include/linux/ioport.h b/include/linux/ioport.h
index 18d010bee635..cd6bd001ba4e 100644
--- a/include/linux/ioport.h
+++ b/include/linux/ioport.h
@@ -94,7 +94,7 @@ extern struct resource iomem_resource;
extern int request_resource(struct resource *root, struct resource *new);
extern struct resource * ____request_resource(struct resource *root, struct resource *new);
extern int release_resource(struct resource *new);
-extern int insert_resource(struct resource *parent, struct resource *new);
+extern __deprecated_for_modules int insert_resource(struct resource *parent, struct resource *new);
extern int allocate_resource(struct resource *root, struct resource *new,
unsigned long size,
unsigned long min, unsigned long max,
diff --git a/include/linux/ipmi.h b/include/linux/ipmi.h
index 938d55b813a5..d6276e60b3bf 100644
--- a/include/linux/ipmi.h
+++ b/include/linux/ipmi.h
@@ -256,10 +256,7 @@ struct ipmi_recv_msg
};
/* Allocate and free the receive message. */
-static inline void ipmi_free_recv_msg(struct ipmi_recv_msg *msg)
-{
- msg->done(msg);
-}
+void ipmi_free_recv_msg(struct ipmi_recv_msg *msg);
struct ipmi_user_hndl
{
diff --git a/include/linux/irq.h b/include/linux/irq.h
index 69681c3b1f05..c516382fbec2 100644
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -10,6 +10,7 @@
*/
#include <linux/config.h>
+#include <asm/smp.h> /* cpu_online_map */
#if !defined(CONFIG_ARCH_S390)
diff --git a/include/linux/istallion.h b/include/linux/istallion.h
index 5f4ee646c119..1f996621bc9c 100644
--- a/include/linux/istallion.h
+++ b/include/linux/istallion.h
@@ -21,8 +21,6 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#include <linux/version.h>
-
/*****************************************************************************/
#ifndef _ISTALLION_H
#define _ISTALLION_H
diff --git a/include/linux/jbd.h b/include/linux/jbd.h
index ff853b3173c6..aa56172c6fed 100644
--- a/include/linux/jbd.h
+++ b/include/linux/jbd.h
@@ -69,7 +69,7 @@ extern int journal_enable_debug;
#define jbd_debug(f, a...) /**/
#endif
-extern void * __jbd_kmalloc (const char *where, size_t size, int flags, int retry);
+extern void * __jbd_kmalloc (const char *where, size_t size, gfp_t flags, int retry);
#define jbd_kmalloc(size, flags) \
__jbd_kmalloc(__FUNCTION__, (size), (flags), journal_oom_retry)
#define jbd_rep_kmalloc(size, flags) \
@@ -611,6 +611,9 @@ struct transaction_s
* @j_revoke: The revoke table - maintains the list of revoked blocks in the
* current transaction.
* @j_revoke_table: alternate revoke tables for j_revoke
+ * @j_wbuf: array of buffer_heads for journal_commit_transaction
+ * @j_wbufsize: maximum number of buffer_heads allowed in j_wbuf, the
+ * number that will fit in j_blocksize
* @j_private: An opaque pointer to fs-private information.
*/
@@ -890,7 +893,7 @@ extern int journal_forget (handle_t *, struct buffer_head *);
extern void journal_sync_buffer (struct buffer_head *);
extern int journal_invalidatepage(journal_t *,
struct page *, unsigned long);
-extern int journal_try_to_free_buffers(journal_t *, struct page *, int);
+extern int journal_try_to_free_buffers(journal_t *, struct page *, gfp_t);
extern int journal_stop(handle_t *);
extern int journal_flush (journal_t *);
extern void journal_lock_updates (journal_t *);
diff --git a/include/linux/jffs2.h b/include/linux/jffs2.h
index 419fc953ac16..cf792bb3c726 100644
--- a/include/linux/jffs2.h
+++ b/include/linux/jffs2.h
@@ -5,10 +5,10 @@
*
* Created by David Woodhouse <dwmw2@infradead.org>
*
- * For licensing information, see the file 'LICENCE' in the
+ * For licensing information, see the file 'LICENCE' in the
* jffs2 directory.
*
- * $Id: jffs2.h,v 1.34 2004/11/16 20:36:14 dwmw2 Exp $
+ * $Id: jffs2.h,v 1.38 2005/09/26 11:37:23 havasi Exp $
*
*/
@@ -28,6 +28,9 @@
#define JFFS2_EMPTY_BITMASK 0xffff
#define JFFS2_DIRTY_BITMASK 0x0000
+/* Summary node MAGIC marker */
+#define JFFS2_SUM_MAGIC 0x02851885
+
/* We only allow a single char for length, and 0xFF is empty flash so
we don't want it confused with a real length. Hence max 254.
*/
@@ -43,8 +46,6 @@
#define JFFS2_COMPR_COPY 0x04
#define JFFS2_COMPR_DYNRUBIN 0x05
#define JFFS2_COMPR_ZLIB 0x06
-#define JFFS2_COMPR_LZO 0x07
-#define JFFS2_COMPR_LZARI 0x08
/* Compatibility flags. */
#define JFFS2_COMPAT_MASK 0xc000 /* What do to if an unknown nodetype is found */
#define JFFS2_NODE_ACCURATE 0x2000
@@ -62,15 +63,17 @@
#define JFFS2_NODETYPE_CLEANMARKER (JFFS2_FEATURE_RWCOMPAT_DELETE | JFFS2_NODE_ACCURATE | 3)
#define JFFS2_NODETYPE_PADDING (JFFS2_FEATURE_RWCOMPAT_DELETE | JFFS2_NODE_ACCURATE | 4)
+#define JFFS2_NODETYPE_SUMMARY (JFFS2_FEATURE_RWCOMPAT_DELETE | JFFS2_NODE_ACCURATE | 6)
+
// Maybe later...
//#define JFFS2_NODETYPE_CHECKPOINT (JFFS2_FEATURE_RWCOMPAT_DELETE | JFFS2_NODE_ACCURATE | 3)
//#define JFFS2_NODETYPE_OPTIONS (JFFS2_FEATURE_RWCOMPAT_COPY | JFFS2_NODE_ACCURATE | 4)
-#define JFFS2_INO_FLAG_PREREAD 1 /* Do read_inode() for this one at
- mount time, don't wait for it to
+#define JFFS2_INO_FLAG_PREREAD 1 /* Do read_inode() for this one at
+ mount time, don't wait for it to
happen later */
-#define JFFS2_INO_FLAG_USERCOMPR 2 /* User has requested a specific
+#define JFFS2_INO_FLAG_USERCOMPR 2 /* User has requested a specific
compression type */
@@ -101,7 +104,7 @@ struct jffs2_unknown_node
struct jffs2_raw_dirent
{
jint16_t magic;
- jint16_t nodetype; /* == JFFS_NODETYPE_DIRENT */
+ jint16_t nodetype; /* == JFFS2_NODETYPE_DIRENT */
jint32_t totlen;
jint32_t hdr_crc;
jint32_t pino;
@@ -117,7 +120,7 @@ struct jffs2_raw_dirent
} __attribute__((packed));
/* The JFFS2 raw inode structure: Used for storage on physical media. */
-/* The uid, gid, atime, mtime and ctime members could be longer, but
+/* The uid, gid, atime, mtime and ctime members could be longer, but
are left like this for space efficiency. If and when people decide
they really need them extended, it's simple enough to add support for
a new type of raw node.
@@ -125,7 +128,7 @@ struct jffs2_raw_dirent
struct jffs2_raw_inode
{
jint16_t magic; /* A constant magic number. */
- jint16_t nodetype; /* == JFFS_NODETYPE_INODE */
+ jint16_t nodetype; /* == JFFS2_NODETYPE_INODE */
jint32_t totlen; /* Total length of this node (inc data, etc.) */
jint32_t hdr_crc;
jint32_t ino; /* Inode number. */
@@ -148,9 +151,25 @@ struct jffs2_raw_inode
uint8_t data[0];
} __attribute__((packed));
-union jffs2_node_union {
+struct jffs2_raw_summary
+{
+ jint16_t magic;
+ jint16_t nodetype; /* = JFFS2_NODETYPE_SUMMARY */
+ jint32_t totlen;
+ jint32_t hdr_crc;
+ jint32_t sum_num; /* number of sum entries*/
+ jint32_t cln_mkr; /* clean marker size, 0 = no cleanmarker */
+ jint32_t padded; /* sum of the size of padding nodes */
+ jint32_t sum_crc; /* summary information crc */
+ jint32_t node_crc; /* node crc */
+ jint32_t sum[0]; /* inode summary info */
+} __attribute__((packed));
+
+union jffs2_node_union
+{
struct jffs2_raw_inode i;
struct jffs2_raw_dirent d;
+ struct jffs2_raw_summary s;
struct jffs2_unknown_node u;
};
diff --git a/include/linux/jffs2_fs_i.h b/include/linux/jffs2_fs_i.h
index 6dbb1cce6646..ef85ab56302b 100644
--- a/include/linux/jffs2_fs_i.h
+++ b/include/linux/jffs2_fs_i.h
@@ -1,4 +1,4 @@
-/* $Id: jffs2_fs_i.h,v 1.17 2004/11/11 23:51:27 dwmw2 Exp $ */
+/* $Id: jffs2_fs_i.h,v 1.19 2005/11/07 11:14:52 gleixner Exp $ */
#ifndef _JFFS2_FS_I
#define _JFFS2_FS_I
@@ -25,13 +25,16 @@ struct jffs2_inode_info {
/* There may be one datanode which isn't referenced by any of the
above fragments, if it contains a metadata update but no actual
data - or if this is a directory inode */
- /* This also holds the _only_ dnode for symlinks/device nodes,
+ /* This also holds the _only_ dnode for symlinks/device nodes,
etc. */
struct jffs2_full_dnode *metadata;
/* Directory entries */
struct jffs2_full_dirent *dents;
+ /* The target path if this is the inode of a symlink */
+ unsigned char *target;
+
/* Some stuff we just have to keep in-core at all times, for each inode. */
struct jffs2_inode_cache *inocache;
diff --git a/include/linux/jffs2_fs_sb.h b/include/linux/jffs2_fs_sb.h
index 1e21546622de..4bcfb5570221 100644
--- a/include/linux/jffs2_fs_sb.h
+++ b/include/linux/jffs2_fs_sb.h
@@ -1,4 +1,4 @@
-/* $Id: jffs2_fs_sb.h,v 1.52 2005/05/19 16:12:17 gleixner Exp $ */
+/* $Id: jffs2_fs_sb.h,v 1.54 2005/09/21 13:37:34 dedekind Exp $ */
#ifndef _JFFS2_FS_SB
#define _JFFS2_FS_SB
@@ -20,7 +20,7 @@
struct jffs2_inodirty;
/* A struct for the overall file system control. Pointers to
- jffs2_sb_info structs are named `c' in the source code.
+ jffs2_sb_info structs are named `c' in the source code.
Nee jffs_control
*/
struct jffs2_sb_info {
@@ -35,7 +35,7 @@ struct jffs2_sb_info {
struct completion gc_thread_start; /* GC thread start completion */
struct completion gc_thread_exit; /* GC thread exit completion port */
- struct semaphore alloc_sem; /* Used to protect all the following
+ struct semaphore alloc_sem; /* Used to protect all the following
fields, and also to protect against
out-of-order writing of nodes. And GC. */
uint32_t cleanmarker_size; /* Size of an _inline_ CLEANMARKER
@@ -64,7 +64,7 @@ struct jffs2_sb_info {
uint32_t nospc_dirty_size;
uint32_t nr_blocks;
- struct jffs2_eraseblock *blocks; /* The whole array of blocks. Used for getting blocks
+ struct jffs2_eraseblock *blocks; /* The whole array of blocks. Used for getting blocks
* from the offset (blocks[ofs / sector_size]) */
struct jffs2_eraseblock *nextblock; /* The block we're currently filling */
@@ -82,25 +82,26 @@ struct jffs2_sb_info {
struct list_head bad_list; /* Bad blocks. */
struct list_head bad_used_list; /* Bad blocks with valid data in. */
- spinlock_t erase_completion_lock; /* Protect free_list and erasing_list
+ spinlock_t erase_completion_lock; /* Protect free_list and erasing_list
against erase completion handler */
wait_queue_head_t erase_wait; /* For waiting for erases to complete */
wait_queue_head_t inocache_wq;
struct jffs2_inode_cache **inocache_list;
spinlock_t inocache_lock;
-
+
/* Sem to allow jffs2_garbage_collect_deletion_dirent to
- drop the erase_completion_lock while it's holding a pointer
+ drop the erase_completion_lock while it's holding a pointer
to an obsoleted node. I don't like this. Alternatives welcomed. */
struct semaphore erase_free_sem;
+ uint32_t wbuf_pagesize; /* 0 for NOR and other flashes with no wbuf */
+
#ifdef CONFIG_JFFS2_FS_WRITEBUFFER
/* Write-behind buffer for NAND flash */
unsigned char *wbuf;
uint32_t wbuf_ofs;
uint32_t wbuf_len;
- uint32_t wbuf_pagesize;
struct jffs2_inodirty *wbuf_inodes;
struct rw_semaphore wbuf_sem; /* Protects the write buffer */
@@ -112,6 +113,8 @@ struct jffs2_sb_info {
uint32_t fsdata_len;
#endif
+ struct jffs2_summary *summary; /* Summary information */
+
/* OS-private pointer for getting back to master superblock info */
void *os_priv;
};
diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index 4367ce4db52a..b1e407a4fbda 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -168,7 +168,7 @@ static inline void console_verbose(void)
extern void bust_spinlocks(int yes);
extern int oops_in_progress; /* If set, an oops, panic(), BUG() or die() is in progress */
-extern int panic_timeout;
+extern __deprecated_for_modules int panic_timeout;
extern int panic_on_oops;
extern int tainted;
extern const char *print_tainted(void);
@@ -266,7 +266,6 @@ extern void dump_stack(void);
/**
* container_of - cast a member of a structure out to the containing structure
- *
* @ptr: the pointer to the member.
* @type: the type of the container struct this is embedded in.
* @member: the name of the member within the struct.
@@ -307,7 +306,7 @@ struct sysinfo {
char _f[20-2*sizeof(long)-sizeof(int)]; /* Padding: libc5 uses this.. */
};
-/* Force a compilation error if condition is false */
+/* Force a compilation error if condition is true */
#define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)]))
#ifdef CONFIG_SYSCTL
diff --git a/include/linux/kernel_stat.h b/include/linux/kernel_stat.h
index dba27749b428..a484572c302e 100644
--- a/include/linux/kernel_stat.h
+++ b/include/linux/kernel_stat.h
@@ -6,6 +6,7 @@
#include <linux/smp.h>
#include <linux/threads.h>
#include <linux/percpu.h>
+#include <linux/cpumask.h>
#include <asm/cputime.h>
/*
@@ -43,11 +44,10 @@ extern unsigned long long nr_context_switches(void);
*/
static inline int kstat_irqs(int irq)
{
- int i, sum=0;
+ int cpu, sum = 0;
- for (i = 0; i < NR_CPUS; i++)
- if (cpu_possible(i))
- sum += kstat_cpu(i).irqs[irq];
+ for_each_cpu(cpu)
+ sum += kstat_cpu(cpu).irqs[irq];
return sum;
}
diff --git a/include/linux/key-ui.h b/include/linux/key-ui.h
index 7a2e332067c3..e8b8a7a5c496 100644
--- a/include/linux/key-ui.h
+++ b/include/linux/key-ui.h
@@ -24,7 +24,8 @@ extern spinlock_t key_serial_lock;
#define KEY_WRITE 0x04 /* require permission to update / modify */
#define KEY_SEARCH 0x08 /* require permission to search (keyring) or find (key) */
#define KEY_LINK 0x10 /* require permission to link */
-#define KEY_ALL 0x1f /* all the above permissions */
+#define KEY_SETATTR 0x20 /* require permission to change attributes */
+#define KEY_ALL 0x3f /* all the above permissions */
/*
* the keyring payload contains a list of the keys to which the keyring is
diff --git a/include/linux/key.h b/include/linux/key.h
index f1efa016dbf3..53513a3be53b 100644
--- a/include/linux/key.h
+++ b/include/linux/key.h
@@ -40,28 +40,32 @@ struct key;
#define KEY_POS_WRITE 0x04000000 /* possessor can update key payload / add link to keyring */
#define KEY_POS_SEARCH 0x08000000 /* possessor can find a key in search / search a keyring */
#define KEY_POS_LINK 0x10000000 /* possessor can create a link to a key/keyring */
-#define KEY_POS_ALL 0x1f000000
+#define KEY_POS_SETATTR 0x20000000 /* possessor can set key attributes */
+#define KEY_POS_ALL 0x3f000000
#define KEY_USR_VIEW 0x00010000 /* user permissions... */
#define KEY_USR_READ 0x00020000
#define KEY_USR_WRITE 0x00040000
#define KEY_USR_SEARCH 0x00080000
#define KEY_USR_LINK 0x00100000
-#define KEY_USR_ALL 0x001f0000
+#define KEY_USR_SETATTR 0x00200000
+#define KEY_USR_ALL 0x003f0000
#define KEY_GRP_VIEW 0x00000100 /* group permissions... */
#define KEY_GRP_READ 0x00000200
#define KEY_GRP_WRITE 0x00000400
#define KEY_GRP_SEARCH 0x00000800
#define KEY_GRP_LINK 0x00001000
-#define KEY_GRP_ALL 0x00001f00
+#define KEY_GRP_SETATTR 0x00002000
+#define KEY_GRP_ALL 0x00003f00
#define KEY_OTH_VIEW 0x00000001 /* third party permissions... */
#define KEY_OTH_READ 0x00000002
#define KEY_OTH_WRITE 0x00000004
#define KEY_OTH_SEARCH 0x00000008
#define KEY_OTH_LINK 0x00000010
-#define KEY_OTH_ALL 0x0000001f
+#define KEY_OTH_SETATTR 0x00000020
+#define KEY_OTH_ALL 0x0000003f
struct seq_file;
struct user_struct;
@@ -119,6 +123,7 @@ struct key {
struct key_type *type; /* type of key */
struct rw_semaphore sem; /* change vs change sem */
struct key_user *user; /* owner of this key */
+ void *security; /* security data for this key */
time_t expiry; /* time at which key expires (or 0) */
uid_t uid;
gid_t gid;
diff --git a/include/linux/kobj_map.h b/include/linux/kobj_map.h
index b6cc10bf8dfc..cbe7d8008042 100644
--- a/include/linux/kobj_map.h
+++ b/include/linux/kobj_map.h
@@ -1,5 +1,7 @@
#ifdef __KERNEL__
+#include <asm/semaphore.h>
+
typedef struct kobject *kobj_probe_t(dev_t, int *, void *);
struct kobj_map;
diff --git a/include/linux/kobject.h b/include/linux/kobject.h
index 3b22304f12fd..7f7403aa4a41 100644
--- a/include/linux/kobject.h
+++ b/include/linux/kobject.h
@@ -65,7 +65,7 @@ extern void kobject_unregister(struct kobject *);
extern struct kobject * kobject_get(struct kobject *);
extern void kobject_put(struct kobject *);
-extern char * kobject_get_path(struct kobject *, int);
+extern char * kobject_get_path(struct kobject *, gfp_t);
struct kobj_type {
void (*release)(struct kobject *);
diff --git a/include/linux/kprobes.h b/include/linux/kprobes.h
index e30afdca7917..e373c4a9de53 100644
--- a/include/linux/kprobes.h
+++ b/include/linux/kprobes.h
@@ -33,6 +33,9 @@
#include <linux/list.h>
#include <linux/notifier.h>
#include <linux/smp.h>
+#include <linux/percpu.h>
+#include <linux/spinlock.h>
+#include <linux/rcupdate.h>
#include <asm/kprobes.h>
@@ -106,6 +109,9 @@ struct jprobe {
kprobe_opcode_t *entry; /* probe handling code to jump to */
};
+DECLARE_PER_CPU(struct kprobe *, current_kprobe);
+DECLARE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
+
#ifdef ARCH_SUPPORTS_KRETPROBES
extern void arch_prepare_kretprobe(struct kretprobe *rp, struct pt_regs *regs);
#else /* ARCH_SUPPORTS_KRETPROBES */
@@ -142,17 +148,7 @@ struct kretprobe_instance {
};
#ifdef CONFIG_KPROBES
-/* Locks kprobe: irq must be disabled */
-void lock_kprobes(void);
-void unlock_kprobes(void);
-
-/* kprobe running now on this CPU? */
-static inline int kprobe_running(void)
-{
- extern unsigned int kprobe_cpu;
- return kprobe_cpu == smp_processor_id();
-}
-
+extern spinlock_t kretprobe_lock;
extern int arch_prepare_kprobe(struct kprobe *p);
extern void arch_copy_kprobe(struct kprobe *p);
extern void arch_arm_kprobe(struct kprobe *p);
@@ -163,10 +159,26 @@ extern void show_registers(struct pt_regs *regs);
extern kprobe_opcode_t *get_insn_slot(void);
extern void free_insn_slot(kprobe_opcode_t *slot);
-/* Get the kprobe at this addr (if any). Must have called lock_kprobes */
+/* Get the kprobe at this addr (if any) - called with preemption disabled */
struct kprobe *get_kprobe(void *addr);
struct hlist_head * kretprobe_inst_table_head(struct task_struct *tsk);
+/* kprobe_running() will just return the current_kprobe on this CPU */
+static inline struct kprobe *kprobe_running(void)
+{
+ return (__get_cpu_var(current_kprobe));
+}
+
+static inline void reset_current_kprobe(void)
+{
+ __get_cpu_var(current_kprobe) = NULL;
+}
+
+static inline struct kprobe_ctlblk *get_kprobe_ctlblk(void)
+{
+ return (&__get_cpu_var(kprobe_ctlblk));
+}
+
int register_kprobe(struct kprobe *p);
void unregister_kprobe(struct kprobe *p);
int setjmp_pre_handler(struct kprobe *, struct pt_regs *);
@@ -183,9 +195,9 @@ void add_rp_inst(struct kretprobe_instance *ri);
void kprobe_flush_task(struct task_struct *tk);
void recycle_rp_inst(struct kretprobe_instance *ri);
#else /* CONFIG_KPROBES */
-static inline int kprobe_running(void)
+static inline struct kprobe *kprobe_running(void)
{
- return 0;
+ return NULL;
}
static inline int register_kprobe(struct kprobe *p)
{
diff --git a/include/linux/kthread.h b/include/linux/kthread.h
index 3fa786448db3..ebdd41fd1082 100644
--- a/include/linux/kthread.h
+++ b/include/linux/kthread.h
@@ -70,6 +70,18 @@ void kthread_bind(struct task_struct *k, unsigned int cpu);
int kthread_stop(struct task_struct *k);
/**
+ * kthread_stop_sem: stop a thread created by kthread_create().
+ * @k: thread created by kthread_create().
+ * @s: semaphore that @k waits on while idle.
+ *
+ * Does essentially the same thing as kthread_stop() above, but wakes
+ * @k by calling up(@s).
+ *
+ * Returns the result of threadfn(), or -EINTR if wake_up_process()
+ * was never called. */
+int kthread_stop_sem(struct task_struct *k, struct semaphore *s);
+
+/**
* kthread_should_stop: should this kthread return now?
*
* When someone calls kthread_stop on your kthread, it will be woken
diff --git a/include/linux/libata.h b/include/linux/libata.h
index ceee1fc42c60..6f0752219f64 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -91,12 +91,13 @@ enum {
ATA_SHT_EMULATED = 1,
ATA_SHT_CMD_PER_LUN = 1,
ATA_SHT_THIS_ID = -1,
- ATA_SHT_USE_CLUSTERING = 0,
+ ATA_SHT_USE_CLUSTERING = 1,
/* struct ata_device stuff */
ATA_DFLAG_LBA48 = (1 << 0), /* device supports LBA48 */
ATA_DFLAG_PIO = (1 << 1), /* device currently in PIO mode */
ATA_DFLAG_LOCK_SECTORS = (1 << 2), /* don't adjust max_sectors */
+ ATA_DFLAG_LBA = (1 << 3), /* device supports LBA */
ATA_DEV_UNKNOWN = 0, /* unknown device */
ATA_DEV_ATA = 1, /* ATA device */
@@ -154,17 +155,32 @@ enum {
ATA_SHIFT_UDMA = 0,
ATA_SHIFT_MWDMA = 8,
ATA_SHIFT_PIO = 11,
+
+ /* size of buffer to pad xfers ending on unaligned boundaries */
+ ATA_DMA_PAD_SZ = 4,
+ ATA_DMA_PAD_BUF_SZ = ATA_DMA_PAD_SZ * ATA_MAX_QUEUE,
+
+ /* Masks for port functions */
+ ATA_PORT_PRIMARY = (1 << 0),
+ ATA_PORT_SECONDARY = (1 << 1),
+};
+
+enum hsm_task_states {
+ HSM_ST_UNKNOWN,
+ HSM_ST_IDLE,
+ HSM_ST_POLL,
+ HSM_ST_TMOUT,
+ HSM_ST,
+ HSM_ST_LAST,
+ HSM_ST_LAST_POLL,
+ HSM_ST_ERR,
};
-enum pio_task_states {
- PIO_ST_UNKNOWN,
- PIO_ST_IDLE,
- PIO_ST_POLL,
- PIO_ST_TMOUT,
- PIO_ST,
- PIO_ST_LAST,
- PIO_ST_LAST_POLL,
- PIO_ST_ERR,
+enum ata_completion_errors {
+ AC_ERR_OTHER = (1 << 0),
+ AC_ERR_DEV = (1 << 1),
+ AC_ERR_ATA_BUS = (1 << 2),
+ AC_ERR_HOST_BUS = (1 << 3),
};
/* forward declarations */
@@ -174,7 +190,7 @@ struct ata_port;
struct ata_queued_cmd;
/* typedefs */
-typedef int (*ata_qc_cb_t) (struct ata_queued_cmd *qc, u8 drv_stat);
+typedef int (*ata_qc_cb_t) (struct ata_queued_cmd *qc, unsigned int err_mask);
struct ata_ioports {
unsigned long cmd_addr;
@@ -197,8 +213,8 @@ struct ata_ioports {
struct ata_probe_ent {
struct list_head node;
struct device *dev;
- struct ata_port_operations *port_ops;
- Scsi_Host_Template *sht;
+ const struct ata_port_operations *port_ops;
+ struct scsi_host_template *sht;
struct ata_ioports port[ATA_MAX_PORTS];
unsigned int n_ports;
unsigned int hard_port_no;
@@ -220,7 +236,7 @@ struct ata_host_set {
void __iomem *mmio_base;
unsigned int n_ports;
void *private_data;
- struct ata_port_operations *ops;
+ const struct ata_port_operations *ops;
struct ata_port * ports[0];
};
@@ -237,9 +253,12 @@ struct ata_queued_cmd {
unsigned long flags; /* ATA_QCFLAG_xxx */
unsigned int tag;
unsigned int n_elem;
+ unsigned int orig_n_elem;
int dma_dir;
+ unsigned int pad_len;
+
unsigned int nsect;
unsigned int cursect;
@@ -250,9 +269,11 @@ struct ata_queued_cmd {
unsigned int cursg_ofs;
struct scatterlist sgent;
+ struct scatterlist pad_sgent;
void *buf_virt;
- struct scatterlist *sg;
+ /* DO NOT iterate over __sg manually, use ata_for_each_sg() */
+ struct scatterlist *__sg;
ata_qc_cb_t complete_fn;
@@ -278,15 +299,18 @@ struct ata_device {
u8 xfer_mode;
unsigned int xfer_shift; /* ATA_SHIFT_xxx */
- /* cache info about current transfer mode */
- u8 xfer_protocol; /* taskfile xfer protocol */
- u8 read_cmd; /* opcode to use on read */
- u8 write_cmd; /* opcode to use on write */
+ unsigned int multi_count; /* sectors count for
+ READ/WRITE MULTIPLE */
+
+ /* for CHS addressing */
+ u16 cylinders; /* Number of cylinders */
+ u16 heads; /* Number of heads */
+ u16 sectors; /* Number of sectors per track */
};
struct ata_port {
struct Scsi_Host *host; /* our co-allocated scsi host */
- struct ata_port_operations *ops;
+ const struct ata_port_operations *ops;
unsigned long flags; /* ATA_FLAG_xxx */
unsigned int id; /* unique id req'd by scsi midlyr */
unsigned int port_no; /* unique port #; from zero */
@@ -295,6 +319,9 @@ struct ata_port {
struct ata_prd *prd; /* our SG list */
dma_addr_t prd_dma; /* and its DMA mapping */
+ void *pad; /* array of DMA pad buffers */
+ dma_addr_t pad_dma;
+
struct ata_ioports ioaddr; /* ATA cmd/ctl/dma register blocks */
u8 ctl; /* cache of ATA control register */
@@ -319,7 +346,7 @@ struct ata_port {
struct work_struct packet_task;
struct work_struct pio_task;
- unsigned int pio_task_state;
+ unsigned int hsm_task_state;
unsigned long pio_task_timeout;
void *private_data;
@@ -333,13 +360,12 @@ struct ata_port_operations {
void (*set_piomode) (struct ata_port *, struct ata_device *);
void (*set_dmamode) (struct ata_port *, struct ata_device *);
- void (*tf_load) (struct ata_port *ap, struct ata_taskfile *tf);
+ void (*tf_load) (struct ata_port *ap, const struct ata_taskfile *tf);
void (*tf_read) (struct ata_port *ap, struct ata_taskfile *tf);
- void (*exec_command)(struct ata_port *ap, struct ata_taskfile *tf);
+ void (*exec_command)(struct ata_port *ap, const struct ata_taskfile *tf);
u8 (*check_status)(struct ata_port *ap);
u8 (*check_altstatus)(struct ata_port *ap);
- u8 (*check_err)(struct ata_port *ap);
void (*dev_select)(struct ata_port *ap, unsigned int device);
void (*phy_reset) (struct ata_port *ap);
@@ -372,14 +398,27 @@ struct ata_port_operations {
};
struct ata_port_info {
- Scsi_Host_Template *sht;
+ struct scsi_host_template *sht;
unsigned long host_flags;
unsigned long pio_mask;
unsigned long mwdma_mask;
unsigned long udma_mask;
- struct ata_port_operations *port_ops;
+ const struct ata_port_operations *port_ops;
+};
+
+struct ata_timing {
+ unsigned short mode; /* ATA mode */
+ unsigned short setup; /* t1 */
+ unsigned short act8b; /* t2 for 8-bit I/O */
+ unsigned short rec8b; /* t2i for 8-bit I/O */
+ unsigned short cyc8b; /* t0 for 8-bit I/O */
+ unsigned short active; /* t2 or tD */
+ unsigned short recover; /* t2i or tK */
+ unsigned short cycle; /* t0 */
+ unsigned short udma; /* t2CYCTYP/2 */
};
+#define FIT(v,vmin,vmax) max_t(short,min_t(short,v,vmax),vmin)
extern void ata_port_probe(struct ata_port *);
extern void __sata_phy_reset(struct ata_port *ap);
@@ -392,27 +431,28 @@ extern int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_i
unsigned int n_ports);
extern void ata_pci_remove_one (struct pci_dev *pdev);
#endif /* CONFIG_PCI */
-extern int ata_device_add(struct ata_probe_ent *ent);
+extern int ata_device_add(const struct ata_probe_ent *ent);
extern void ata_host_set_remove(struct ata_host_set *host_set);
-extern int ata_scsi_detect(Scsi_Host_Template *sht);
+extern int ata_scsi_detect(struct scsi_host_template *sht);
extern int ata_scsi_ioctl(struct scsi_device *dev, int cmd, void __user *arg);
extern int ata_scsi_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *));
extern int ata_scsi_error(struct Scsi_Host *host);
extern int ata_scsi_release(struct Scsi_Host *host);
extern unsigned int ata_host_intr(struct ata_port *ap, struct ata_queued_cmd *qc);
+extern int ata_ratelimit(void);
+
/*
* Default driver ops implementations
*/
-extern void ata_tf_load(struct ata_port *ap, struct ata_taskfile *tf);
+extern void ata_tf_load(struct ata_port *ap, const struct ata_taskfile *tf);
extern void ata_tf_read(struct ata_port *ap, struct ata_taskfile *tf);
-extern void ata_tf_to_fis(struct ata_taskfile *tf, u8 *fis, u8 pmp);
-extern void ata_tf_from_fis(u8 *fis, struct ata_taskfile *tf);
+extern void ata_tf_to_fis(const struct ata_taskfile *tf, u8 *fis, u8 pmp);
+extern void ata_tf_from_fis(const u8 *fis, struct ata_taskfile *tf);
extern void ata_noop_dev_select (struct ata_port *ap, unsigned int device);
extern void ata_std_dev_select (struct ata_port *ap, unsigned int device);
extern u8 ata_check_status(struct ata_port *ap);
extern u8 ata_altstatus(struct ata_port *ap);
-extern u8 ata_chk_err(struct ata_port *ap);
-extern void ata_exec_command(struct ata_port *ap, struct ata_taskfile *tf);
+extern void ata_exec_command(struct ata_port *ap, const struct ata_taskfile *tf);
extern int ata_port_start (struct ata_port *ap);
extern void ata_port_stop (struct ata_port *ap);
extern void ata_host_stop (struct ata_host_set *host_set);
@@ -423,8 +463,8 @@ extern void ata_sg_init_one(struct ata_queued_cmd *qc, void *buf,
unsigned int buflen);
extern void ata_sg_init(struct ata_queued_cmd *qc, struct scatterlist *sg,
unsigned int n_elem);
-extern unsigned int ata_dev_classify(struct ata_taskfile *tf);
-extern void ata_dev_id_string(u16 *id, unsigned char *s,
+extern unsigned int ata_dev_classify(const struct ata_taskfile *tf);
+extern void ata_dev_id_string(const u16 *id, unsigned char *s,
unsigned int ofs, unsigned int len);
extern void ata_dev_config(struct ata_port *ap, unsigned int i);
extern void ata_bmdma_setup (struct ata_queued_cmd *qc);
@@ -432,7 +472,7 @@ extern void ata_bmdma_start (struct ata_queued_cmd *qc);
extern void ata_bmdma_stop(struct ata_queued_cmd *qc);
extern u8 ata_bmdma_status(struct ata_port *ap);
extern void ata_bmdma_irq_clear(struct ata_port *ap);
-extern void ata_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat);
+extern void ata_qc_complete(struct ata_queued_cmd *qc, unsigned int err_mask);
extern void ata_eng_timeout(struct ata_port *ap);
extern void ata_scsi_simulate(u16 *id, struct scsi_cmnd *cmd,
void (*done)(struct scsi_cmnd *));
@@ -441,6 +481,32 @@ extern int ata_std_bios_param(struct scsi_device *sdev,
sector_t capacity, int geom[]);
extern int ata_scsi_slave_config(struct scsi_device *sdev);
+/*
+ * Timing helpers
+ */
+extern int ata_timing_compute(struct ata_device *, unsigned short,
+ struct ata_timing *, int, int);
+extern void ata_timing_merge(const struct ata_timing *,
+ const struct ata_timing *, struct ata_timing *,
+ unsigned int);
+
+enum {
+ ATA_TIMING_SETUP = (1 << 0),
+ ATA_TIMING_ACT8B = (1 << 1),
+ ATA_TIMING_REC8B = (1 << 2),
+ ATA_TIMING_CYC8B = (1 << 3),
+ ATA_TIMING_8BIT = ATA_TIMING_ACT8B | ATA_TIMING_REC8B |
+ ATA_TIMING_CYC8B,
+ ATA_TIMING_ACTIVE = (1 << 4),
+ ATA_TIMING_RECOVER = (1 << 5),
+ ATA_TIMING_CYCLE = (1 << 6),
+ ATA_TIMING_UDMA = (1 << 7),
+ ATA_TIMING_ALL = ATA_TIMING_SETUP | ATA_TIMING_ACT8B |
+ ATA_TIMING_REC8B | ATA_TIMING_CYC8B |
+ ATA_TIMING_ACTIVE | ATA_TIMING_RECOVER |
+ ATA_TIMING_CYCLE | ATA_TIMING_UDMA,
+};
+
#ifdef CONFIG_PCI
struct pci_bits {
@@ -452,18 +518,43 @@ struct pci_bits {
extern void ata_pci_host_stop (struct ata_host_set *host_set);
extern struct ata_probe_ent *
-ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port);
-extern int pci_test_config_bits(struct pci_dev *pdev, struct pci_bits *bits);
+ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port, int portmask);
+extern int pci_test_config_bits(struct pci_dev *pdev, const struct pci_bits *bits);
#endif /* CONFIG_PCI */
+static inline int
+ata_sg_is_last(struct scatterlist *sg, struct ata_queued_cmd *qc)
+{
+ if (sg == &qc->pad_sgent)
+ return 1;
+ if (qc->pad_len)
+ return 0;
+ if (((sg - qc->__sg) + 1) == qc->n_elem)
+ return 1;
+ return 0;
+}
+
+static inline struct scatterlist *
+ata_qc_next_sg(struct scatterlist *sg, struct ata_queued_cmd *qc)
+{
+ if (sg == &qc->pad_sgent)
+ return NULL;
+ if (++sg - qc->__sg < qc->n_elem)
+ return sg;
+ return qc->pad_len ? &qc->pad_sgent : NULL;
+}
+
+#define ata_for_each_sg(sg, qc) \
+ for (sg = qc->__sg; sg; sg = ata_qc_next_sg(sg, qc))
+
static inline unsigned int ata_tag_valid(unsigned int tag)
{
return (tag < ATA_MAX_QUEUE) ? 1 : 0;
}
-static inline unsigned int ata_dev_present(struct ata_device *dev)
+static inline unsigned int ata_dev_present(const struct ata_device *dev)
{
return ((dev->class == ATA_DEV_ATA) ||
(dev->class == ATA_DEV_ATAPI));
@@ -662,11 +753,41 @@ static inline unsigned int sata_dev_present(struct ata_port *ap)
return ((scr_read(ap, SCR_STATUS) & 0xf) == 0x3) ? 1 : 0;
}
-static inline int ata_try_flush_cache(struct ata_device *dev)
+static inline int ata_try_flush_cache(const struct ata_device *dev)
{
return ata_id_wcache_enabled(dev->id) ||
ata_id_has_flush(dev->id) ||
ata_id_has_flush_ext(dev->id);
}
+static inline unsigned int ac_err_mask(u8 status)
+{
+ if (status & ATA_BUSY)
+ return AC_ERR_ATA_BUS;
+ if (status & (ATA_ERR | ATA_DF))
+ return AC_ERR_DEV;
+ return 0;
+}
+
+static inline unsigned int __ac_err_mask(u8 status)
+{
+ unsigned int mask = ac_err_mask(status);
+ if (mask == 0)
+ return AC_ERR_OTHER;
+ return mask;
+}
+
+static inline int ata_pad_alloc(struct ata_port *ap, struct device *dev)
+{
+ ap->pad_dma = 0;
+ ap->pad = dma_alloc_coherent(dev, ATA_DMA_PAD_BUF_SZ,
+ &ap->pad_dma, GFP_KERNEL);
+ return (ap->pad == NULL) ? -ENOMEM : 0;
+}
+
+static inline void ata_pad_free(struct ata_port *ap, struct device *dev)
+{
+ dma_free_coherent(dev, ATA_DMA_PAD_BUF_SZ, ap->pad, ap->pad_dma);
+}
+
#endif /* __LINUX_LIBATA_H__ */
diff --git a/include/linux/list.h b/include/linux/list.h
index 084971f333fe..fbfca73355a3 100644
--- a/include/linux/list.h
+++ b/include/linux/list.h
@@ -601,7 +601,7 @@ static inline void hlist_add_head(struct hlist_node *n, struct hlist_head *h)
* or hlist_del_rcu(), running on this same list.
* However, it is perfectly legal to run concurrently with
* the _rcu list-traversal primitives, such as
- * hlist_for_each_rcu(), used to prevent memory-consistency
+ * hlist_for_each_entry_rcu(), used to prevent memory-consistency
* problems on Alpha CPUs. Regardless of the type of CPU, the
* list-traversal primitive must be guarded by rcu_read_lock().
*/
@@ -650,7 +650,7 @@ static inline void hlist_add_after(struct hlist_node *n,
* or hlist_del_rcu(), running on this same list.
* However, it is perfectly legal to run concurrently with
* the _rcu list-traversal primitives, such as
- * hlist_for_each_rcu(), used to prevent memory-consistency
+ * hlist_for_each_entry_rcu(), used to prevent memory-consistency
* problems on Alpha CPUs.
*/
static inline void hlist_add_before_rcu(struct hlist_node *n,
@@ -675,7 +675,7 @@ static inline void hlist_add_before_rcu(struct hlist_node *n,
* or hlist_del_rcu(), running on this same list.
* However, it is perfectly legal to run concurrently with
* the _rcu list-traversal primitives, such as
- * hlist_for_each_rcu(), used to prevent memory-consistency
+ * hlist_for_each_entry_rcu(), used to prevent memory-consistency
* problems on Alpha CPUs.
*/
static inline void hlist_add_after_rcu(struct hlist_node *prev,
@@ -699,11 +699,6 @@ static inline void hlist_add_after_rcu(struct hlist_node *prev,
for (pos = (head)->first; pos && ({ n = pos->next; 1; }); \
pos = n)
-#define hlist_for_each_rcu(pos, head) \
- for ((pos) = (head)->first; \
- rcu_dereference((pos)) && ({ prefetch((pos)->next); 1; }); \
- (pos) = (pos)->next)
-
/**
* hlist_for_each_entry - iterate over list of given type
* @tpos: the type * to use as a loop counter.
@@ -756,7 +751,7 @@ static inline void hlist_add_after_rcu(struct hlist_node *prev,
/**
* hlist_for_each_entry_rcu - iterate over rcu list of given type
- * @pos: the type * to use as a loop counter.
+ * @tpos: the type * to use as a loop counter.
* @pos: the &struct hlist_node to use as a loop counter.
* @head: the head for your list.
* @member: the name of the hlist_node within the struct.
diff --git a/include/linux/loop.h b/include/linux/loop.h
index 53fa51595443..40f63c9879d2 100644
--- a/include/linux/loop.h
+++ b/include/linux/loop.h
@@ -52,7 +52,7 @@ struct loop_device {
unsigned lo_blocksize;
void *key_data;
- int old_gfp_mask;
+ gfp_t old_gfp_mask;
spinlock_t lo_lock;
struct bio *lo_bio;
diff --git a/include/linux/mbcache.h b/include/linux/mbcache.h
index 9263d2db2d67..99e044b4efc6 100644
--- a/include/linux/mbcache.h
+++ b/include/linux/mbcache.h
@@ -22,7 +22,7 @@ struct mb_cache_entry {
};
struct mb_cache_op {
- int (*free)(struct mb_cache_entry *, int);
+ int (*free)(struct mb_cache_entry *, gfp_t);
};
/* Functions on caches */
diff --git a/include/linux/memory.h b/include/linux/memory.h
new file mode 100644
index 000000000000..9a424383e6c6
--- /dev/null
+++ b/include/linux/memory.h
@@ -0,0 +1,97 @@
+/*
+ * include/linux/memory.h - generic memory definition
+ *
+ * This is mainly for topological representation. We define the
+ * basic "struct memory_block" here, which can be embedded in per-arch
+ * definitions or NUMA information.
+ *
+ * Basic handling of the devices is done in drivers/base/memory.c
+ * and system devices are handled in drivers/base/sys.c.
+ *
+ * Memory block are exported via sysfs in the class/memory/devices/
+ * directory.
+ *
+ */
+#ifndef _LINUX_MEMORY_H_
+#define _LINUX_MEMORY_H_
+
+#include <linux/sysdev.h>
+#include <linux/node.h>
+#include <linux/compiler.h>
+
+#include <asm/semaphore.h>
+
+struct memory_block {
+ unsigned long phys_index;
+ unsigned long state;
+ /*
+ * This serializes all state change requests. It isn't
+ * held during creation because the control files are
+ * created long after the critical areas during
+ * initialization.
+ */
+ struct semaphore state_sem;
+ int phys_device; /* to which fru does this belong? */
+ void *hw; /* optional pointer to fw/hw data */
+ int (*phys_callback)(struct memory_block *);
+ struct sys_device sysdev;
+};
+
+/* These states are exposed to userspace as text strings in sysfs */
+#define MEM_ONLINE (1<<0) /* exposed to userspace */
+#define MEM_GOING_OFFLINE (1<<1) /* exposed to userspace */
+#define MEM_OFFLINE (1<<2) /* exposed to userspace */
+
+/*
+ * All of these states are currently kernel-internal for notifying
+ * kernel components and architectures.
+ *
+ * For MEM_MAPPING_INVALID, all notifier chains with priority >0
+ * are called before pfn_to_page() becomes invalid. The priority=0
+ * entry is reserved for the function that actually makes
+ * pfn_to_page() stop working. Any notifiers that want to be called
+ * after that should have priority <0.
+ */
+#define MEM_MAPPING_INVALID (1<<3)
+
+struct notifier_block;
+struct mem_section;
+
+#ifndef CONFIG_MEMORY_HOTPLUG
+static inline int memory_dev_init(void)
+{
+ return 0;
+}
+static inline int register_memory_notifier(struct notifier_block *nb)
+{
+ return 0;
+}
+static inline void unregister_memory_notifier(struct notifier_block *nb)
+{
+}
+#else
+extern int register_memory(struct memory_block *, struct mem_section *section, struct node *);
+extern int register_new_memory(struct mem_section *);
+extern int unregister_memory_section(struct mem_section *);
+extern int memory_dev_init(void);
+extern int register_memory_notifier(struct notifier_block *nb);
+extern void unregister_memory_notifier(struct notifier_block *nb);
+
+#define CONFIG_MEM_BLOCK_SIZE (PAGES_PER_SECTION<<PAGE_SHIFT)
+
+extern int invalidate_phys_mapping(unsigned long, unsigned long);
+struct notifier_block;
+
+extern int register_memory_notifier(struct notifier_block *nb);
+extern void unregister_memory_notifier(struct notifier_block *nb);
+
+extern struct sysdev_class memory_sysdev_class;
+#endif /* CONFIG_MEMORY_HOTPLUG */
+
+#define hotplug_memory_notifier(fn, pri) { \
+ static struct notifier_block fn##_mem_nb = \
+ { .notifier_call = fn, .priority = pri }; \
+ register_memory_notifier(&fn##_mem_nb); \
+}
+
+#endif /* _LINUX_MEMORY_H_ */
diff --git a/include/linux/memory_hotplug.h b/include/linux/memory_hotplug.h
new file mode 100644
index 000000000000..01f03bc06eff
--- /dev/null
+++ b/include/linux/memory_hotplug.h
@@ -0,0 +1,104 @@
+#ifndef __LINUX_MEMORY_HOTPLUG_H
+#define __LINUX_MEMORY_HOTPLUG_H
+
+#include <linux/mmzone.h>
+#include <linux/spinlock.h>
+#include <linux/mmzone.h>
+#include <linux/notifier.h>
+
+#ifdef CONFIG_MEMORY_HOTPLUG
+/*
+ * pgdat resizing functions
+ */
+static inline
+void pgdat_resize_lock(struct pglist_data *pgdat, unsigned long *flags)
+{
+ spin_lock_irqsave(&pgdat->node_size_lock, *flags);
+}
+static inline
+void pgdat_resize_unlock(struct pglist_data *pgdat, unsigned long *flags)
+{
+ spin_unlock_irqrestore(&pgdat->node_size_lock, *flags);
+}
+static inline
+void pgdat_resize_init(struct pglist_data *pgdat)
+{
+ spin_lock_init(&pgdat->node_size_lock);
+}
+/*
+ * Zone resizing functions
+ */
+static inline unsigned zone_span_seqbegin(struct zone *zone)
+{
+ return read_seqbegin(&zone->span_seqlock);
+}
+static inline int zone_span_seqretry(struct zone *zone, unsigned iv)
+{
+ return read_seqretry(&zone->span_seqlock, iv);
+}
+static inline void zone_span_writelock(struct zone *zone)
+{
+ write_seqlock(&zone->span_seqlock);
+}
+static inline void zone_span_writeunlock(struct zone *zone)
+{
+ write_sequnlock(&zone->span_seqlock);
+}
+static inline void zone_seqlock_init(struct zone *zone)
+{
+ seqlock_init(&zone->span_seqlock);
+}
+extern int zone_grow_free_lists(struct zone *zone, unsigned long new_nr_pages);
+extern int zone_grow_waitqueues(struct zone *zone, unsigned long nr_pages);
+extern int add_one_highpage(struct page *page, int pfn, int bad_ppro);
+/* need some defines for these for archs that don't support it */
+extern void online_page(struct page *page);
+/* VM interface that may be used by firmware interface */
+extern int add_memory(u64 start, u64 size);
+extern int remove_memory(u64 start, u64 size);
+extern int online_pages(unsigned long, unsigned long);
+
+/* reasonably generic interface to expand the physical pages in a zone */
+extern int __add_pages(struct zone *zone, unsigned long start_pfn,
+ unsigned long nr_pages);
+#else /* ! CONFIG_MEMORY_HOTPLUG */
+/*
+ * Stub functions for when hotplug is off
+ */
+static inline void pgdat_resize_lock(struct pglist_data *p, unsigned long *f) {}
+static inline void pgdat_resize_unlock(struct pglist_data *p, unsigned long *f) {}
+static inline void pgdat_resize_init(struct pglist_data *pgdat) {}
+
+static inline unsigned zone_span_seqbegin(struct zone *zone)
+{
+ return 0;
+}
+static inline int zone_span_seqretry(struct zone *zone, unsigned iv)
+{
+ return 0;
+}
+static inline void zone_span_writelock(struct zone *zone) {}
+static inline void zone_span_writeunlock(struct zone *zone) {}
+static inline void zone_seqlock_init(struct zone *zone) {}
+
+static inline int mhp_notimplemented(const char *func)
+{
+ printk(KERN_WARNING "%s() called, with CONFIG_MEMORY_HOTPLUG disabled\n", func);
+ dump_stack();
+ return -ENOSYS;
+}
+
+static inline int __add_pages(struct zone *zone, unsigned long start_pfn,
+ unsigned long nr_pages)
+{
+ return mhp_notimplemented(__FUNCTION__);
+}
+#endif /* ! CONFIG_MEMORY_HOTPLUG */
+static inline int __remove_pages(struct zone *zone, unsigned long start_pfn,
+ unsigned long nr_pages)
+{
+ printk(KERN_WARNING "%s() called, not yet supported\n", __FUNCTION__);
+ dump_stack();
+ return -ENOSYS;
+}
+#endif /* __LINUX_MEMORY_HOTPLUG_H */
diff --git a/include/linux/mempolicy.h b/include/linux/mempolicy.h
index 58385ee1c0ac..8b67cf837ca9 100644
--- a/include/linux/mempolicy.h
+++ b/include/linux/mempolicy.h
@@ -27,10 +27,10 @@
#include <linux/config.h>
#include <linux/mmzone.h>
-#include <linux/bitmap.h>
#include <linux/slab.h>
#include <linux/rbtree.h>
#include <linux/spinlock.h>
+#include <linux/nodemask.h>
struct vm_area_struct;
@@ -47,8 +47,7 @@ struct vm_area_struct;
* Locking policy for interlave:
* In process context there is no locking because only the process accesses
* its own state. All vma manipulation is somewhat protected by a down_read on
- * mmap_sem. For allocating in the interleave policy the page_table_lock
- * must be also aquired to protect il_next.
+ * mmap_sem.
*
* Freeing policy:
* When policy is MPOL_BIND v.zonelist is kmalloc'ed and must be kfree'd.
@@ -63,7 +62,7 @@ struct mempolicy {
union {
struct zonelist *zonelist; /* bind */
short preferred_node; /* preferred */
- DECLARE_BITMAP(nodes, MAX_NUMNODES); /* interleave */
+ nodemask_t nodes; /* interleave */
/* undefined for default */
} v;
};
@@ -155,6 +154,7 @@ struct mempolicy *get_vma_policy(struct task_struct *task,
extern void numa_default_policy(void);
extern void numa_policy_init(void);
+extern void numa_policy_rebind(const nodemask_t *old, const nodemask_t *new);
extern struct mempolicy default_policy;
#else
@@ -227,6 +227,11 @@ static inline void numa_default_policy(void)
{
}
+static inline void numa_policy_rebind(const nodemask_t *old,
+ const nodemask_t *new)
+{
+}
+
#endif /* CONFIG_NUMA */
#endif /* __KERNEL__ */
diff --git a/include/linux/mii.h b/include/linux/mii.h
index 9b8d0476988a..68f5a0f392dd 100644
--- a/include/linux/mii.h
+++ b/include/linux/mii.h
@@ -158,6 +158,7 @@ extern int mii_link_ok (struct mii_if_info *mii);
extern int mii_nway_restart (struct mii_if_info *mii);
extern int mii_ethtool_gset(struct mii_if_info *mii, struct ethtool_cmd *ecmd);
extern int mii_ethtool_sset(struct mii_if_info *mii, struct ethtool_cmd *ecmd);
+extern int mii_check_gmii_support(struct mii_if_info *mii);
extern void mii_check_link (struct mii_if_info *mii);
extern unsigned int mii_check_media (struct mii_if_info *mii,
unsigned int ok_to_print,
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 097b3a3c693d..7b115feca4df 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -157,7 +157,7 @@ extern unsigned int kobjsize(const void *objp);
#define VM_DONTCOPY 0x00020000 /* Do not copy this vma on fork */
#define VM_DONTEXPAND 0x00040000 /* Cannot expand with mremap() */
-#define VM_RESERVED 0x00080000 /* Don't unmap it from swap_out */
+#define VM_RESERVED 0x00080000 /* Pages managed in a special way */
#define VM_ACCOUNT 0x00100000 /* Is a VM accounted object */
#define VM_HUGETLB 0x00400000 /* Huge TLB Page VM */
#define VM_NONLINEAR 0x00800000 /* Is non-linear (remap_file_pages) */
@@ -226,13 +226,18 @@ struct page {
* to show when page is mapped
* & limit reverse map searches.
*/
- unsigned long private; /* Mapping-private opaque data:
+ union {
+ unsigned long private; /* Mapping-private opaque data:
* usually used for buffer_heads
* if PagePrivate set; used for
* swp_entry_t if PageSwapCache
* When page is free, this indicates
* order in the buddy system.
*/
+#if NR_CPUS >= CONFIG_SPLIT_PTLOCK_CPUS
+ spinlock_t ptl;
+#endif
+ } u;
struct address_space *mapping; /* If low bit clear, points to
* inode address_space, or NULL.
* If page mapped as anonymous
@@ -260,6 +265,9 @@ struct page {
#endif /* WANT_PAGE_VIRTUAL */
};
+#define page_private(page) ((page)->u.private)
+#define set_page_private(page, v) ((page)->u.private = (v))
+
/*
* FIXME: take this include out, include page-flags.h in
* files which need it (119 of them)
@@ -311,17 +319,17 @@ extern void FASTCALL(__page_cache_release(struct page *));
#ifdef CONFIG_HUGETLB_PAGE
-static inline int page_count(struct page *p)
+static inline int page_count(struct page *page)
{
- if (PageCompound(p))
- p = (struct page *)p->private;
- return atomic_read(&(p)->_count) + 1;
+ if (PageCompound(page))
+ page = (struct page *)page_private(page);
+ return atomic_read(&page->_count) + 1;
}
static inline void get_page(struct page *page)
{
if (unlikely(PageCompound(page)))
- page = (struct page *)page->private;
+ page = (struct page *)page_private(page);
atomic_inc(&page->_count);
}
@@ -338,7 +346,7 @@ static inline void get_page(struct page *page)
static inline void put_page(struct page *page)
{
- if (!PageReserved(page) && put_page_testzero(page))
+ if (put_page_testzero(page))
__page_cache_release(page);
}
@@ -587,7 +595,7 @@ static inline int PageAnon(struct page *page)
static inline pgoff_t page_index(struct page *page)
{
if (unlikely(PageSwapCache(page)))
- return page->private;
+ return page_private(page);
return page->index;
}
@@ -682,7 +690,7 @@ struct zap_details {
unsigned long zap_page_range(struct vm_area_struct *vma, unsigned long address,
unsigned long size, struct zap_details *);
-unsigned long unmap_vmas(struct mmu_gather **tlb, struct mm_struct *mm,
+unsigned long unmap_vmas(struct mmu_gather **tlb,
struct vm_area_struct *start_vma, unsigned long start_addr,
unsigned long end_addr, unsigned long *nr_accounted,
struct zap_details *);
@@ -704,10 +712,6 @@ static inline void unmap_shared_mapping_range(struct address_space *mapping,
}
extern int vmtruncate(struct inode * inode, loff_t offset);
-extern pud_t *FASTCALL(__pud_alloc(struct mm_struct *mm, pgd_t *pgd, unsigned long address));
-extern pmd_t *FASTCALL(__pmd_alloc(struct mm_struct *mm, pud_t *pud, unsigned long address));
-extern pte_t *FASTCALL(pte_alloc_kernel(struct mm_struct *mm, pmd_t *pmd, unsigned long address));
-extern pte_t *FASTCALL(pte_alloc_map(struct mm_struct *mm, pmd_t *pmd, unsigned long address));
extern int install_page(struct mm_struct *mm, struct vm_area_struct *vma, unsigned long addr, struct page *page, pgprot_t prot);
extern int install_file_pte(struct mm_struct *mm, struct vm_area_struct *vma, unsigned long addr, unsigned long pgoff, pgprot_t prot);
extern int __handle_mm_fault(struct mm_struct *mm,struct vm_area_struct *vma, unsigned long address, int write_access);
@@ -723,6 +727,7 @@ void install_arg_page(struct vm_area_struct *, struct page *, unsigned long);
int get_user_pages(struct task_struct *tsk, struct mm_struct *mm, unsigned long start,
int len, int write, int force, struct page **pages, struct vm_area_struct **vmas);
+void print_bad_pte(struct vm_area_struct *, pte_t, unsigned long);
int __set_page_dirty_buffers(struct page *page);
int __set_page_dirty_nobuffers(struct page *page);
@@ -747,7 +752,7 @@ extern unsigned long do_mremap(unsigned long addr,
* The callback will be passed nr_to_scan == 0 when the VM is querying the
* cache size, so a fastpath for that case is appropriate.
*/
-typedef int (*shrinker_t)(int nr_to_scan, unsigned int gfp_mask);
+typedef int (*shrinker_t)(int nr_to_scan, gfp_t gfp_mask);
/*
* Add an aging callback. The int is the number of 'seeks' it takes
@@ -759,38 +764,83 @@ struct shrinker;
extern struct shrinker *set_shrinker(int, shrinker_t);
extern void remove_shrinker(struct shrinker *shrinker);
-/*
- * On a two-level or three-level page table, this ends up being trivial. Thus
- * the inlining and the symmetry break with pte_alloc_map() that does all
- * of this out-of-line.
- */
+int __pud_alloc(struct mm_struct *mm, pgd_t *pgd, unsigned long address);
+int __pmd_alloc(struct mm_struct *mm, pud_t *pud, unsigned long address);
+int __pte_alloc(struct mm_struct *mm, pmd_t *pmd, unsigned long address);
+int __pte_alloc_kernel(pmd_t *pmd, unsigned long address);
+
/*
* The following ifdef needed to get the 4level-fixup.h header to work.
* Remove it when 4level-fixup.h has been removed.
*/
-#ifdef CONFIG_MMU
-#ifndef __ARCH_HAS_4LEVEL_HACK
+#if defined(CONFIG_MMU) && !defined(__ARCH_HAS_4LEVEL_HACK)
static inline pud_t *pud_alloc(struct mm_struct *mm, pgd_t *pgd, unsigned long address)
{
- if (pgd_none(*pgd))
- return __pud_alloc(mm, pgd, address);
- return pud_offset(pgd, address);
+ return (unlikely(pgd_none(*pgd)) && __pud_alloc(mm, pgd, address))?
+ NULL: pud_offset(pgd, address);
}
static inline pmd_t *pmd_alloc(struct mm_struct *mm, pud_t *pud, unsigned long address)
{
- if (pud_none(*pud))
- return __pmd_alloc(mm, pud, address);
- return pmd_offset(pud, address);
+ return (unlikely(pud_none(*pud)) && __pmd_alloc(mm, pud, address))?
+ NULL: pmd_offset(pud, address);
}
-#endif
-#endif /* CONFIG_MMU */
+#endif /* CONFIG_MMU && !__ARCH_HAS_4LEVEL_HACK */
+
+#if NR_CPUS >= CONFIG_SPLIT_PTLOCK_CPUS
+/*
+ * We tuck a spinlock to guard each pagetable page into its struct page,
+ * at page->private, with BUILD_BUG_ON to make sure that this will not
+ * overflow into the next struct page (as it might with DEBUG_SPINLOCK).
+ * When freeing, reset page->mapping so free_pages_check won't complain.
+ */
+#define __pte_lockptr(page) &((page)->u.ptl)
+#define pte_lock_init(_page) do { \
+ spin_lock_init(__pte_lockptr(_page)); \
+} while (0)
+#define pte_lock_deinit(page) ((page)->mapping = NULL)
+#define pte_lockptr(mm, pmd) ({(void)(mm); __pte_lockptr(pmd_page(*(pmd)));})
+#else
+/*
+ * We use mm->page_table_lock to guard all pagetable pages of the mm.
+ */
+#define pte_lock_init(page) do {} while (0)
+#define pte_lock_deinit(page) do {} while (0)
+#define pte_lockptr(mm, pmd) ({(void)(pmd); &(mm)->page_table_lock;})
+#endif /* NR_CPUS < CONFIG_SPLIT_PTLOCK_CPUS */
+
+#define pte_offset_map_lock(mm, pmd, address, ptlp) \
+({ \
+ spinlock_t *__ptl = pte_lockptr(mm, pmd); \
+ pte_t *__pte = pte_offset_map(pmd, address); \
+ *(ptlp) = __ptl; \
+ spin_lock(__ptl); \
+ __pte; \
+})
+
+#define pte_unmap_unlock(pte, ptl) do { \
+ spin_unlock(ptl); \
+ pte_unmap(pte); \
+} while (0)
+
+#define pte_alloc_map(mm, pmd, address) \
+ ((unlikely(!pmd_present(*(pmd))) && __pte_alloc(mm, pmd, address))? \
+ NULL: pte_offset_map(pmd, address))
+
+#define pte_alloc_map_lock(mm, pmd, address, ptlp) \
+ ((unlikely(!pmd_present(*(pmd))) && __pte_alloc(mm, pmd, address))? \
+ NULL: pte_offset_map_lock(mm, pmd, address, ptlp))
+
+#define pte_alloc_kernel(pmd, address) \
+ ((unlikely(!pmd_present(*(pmd))) && __pte_alloc_kernel(pmd, address))? \
+ NULL: pte_offset_kernel(pmd, address))
extern void free_area_init(unsigned long * zones_size);
extern void free_area_init_node(int nid, pg_data_t *pgdat,
unsigned long * zones_size, unsigned long zone_start_pfn,
unsigned long *zholes_size);
extern void memmap_init_zone(unsigned long, int, unsigned long, unsigned long);
+extern void setup_per_zone_pages_min(void);
extern void mem_init(void);
extern void show_mem(void);
extern void si_meminfo(struct sysinfo * val);
@@ -834,6 +884,7 @@ extern int split_vma(struct mm_struct *,
extern int insert_vm_struct(struct mm_struct *, struct vm_area_struct *);
extern void __vma_link_rb(struct mm_struct *, struct vm_area_struct *,
struct rb_node **, struct rb_node *);
+extern void unlink_file_vma(struct vm_area_struct *);
extern struct vm_area_struct *copy_vma(struct vm_area_struct **,
unsigned long addr, unsigned long len, pgoff_t pgoff);
extern void exit_mmap(struct mm_struct *);
@@ -881,20 +932,21 @@ int write_one_page(struct page *page, int wait);
* turning readahead off */
int do_page_cache_readahead(struct address_space *mapping, struct file *filp,
- unsigned long offset, unsigned long nr_to_read);
+ pgoff_t offset, unsigned long nr_to_read);
int force_page_cache_readahead(struct address_space *mapping, struct file *filp,
- unsigned long offset, unsigned long nr_to_read);
-unsigned long page_cache_readahead(struct address_space *mapping,
+ pgoff_t offset, unsigned long nr_to_read);
+unsigned long page_cache_readahead(struct address_space *mapping,
struct file_ra_state *ra,
struct file *filp,
- unsigned long offset,
+ pgoff_t offset,
unsigned long size);
void handle_ra_miss(struct address_space *mapping,
struct file_ra_state *ra, pgoff_t offset);
unsigned long max_sane_readahead(unsigned long nr);
/* Do stack extension */
-extern int expand_stack(struct vm_area_struct * vma, unsigned long address);
+extern int expand_stack(struct vm_area_struct *vma, unsigned long address);
+extern int expand_upwards(struct vm_area_struct *vma, unsigned long address);
/* Look up the first VMA which satisfies addr < vm_end, NULL if none. */
extern struct vm_area_struct * find_vma(struct mm_struct * mm, unsigned long addr);
@@ -917,40 +969,28 @@ static inline unsigned long vma_pages(struct vm_area_struct *vma)
return (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
}
-extern struct vm_area_struct *find_extend_vma(struct mm_struct *mm, unsigned long addr);
+struct vm_area_struct *find_extend_vma(struct mm_struct *, unsigned long addr);
+struct page *vmalloc_to_page(void *addr);
+unsigned long vmalloc_to_pfn(void *addr);
+int remap_pfn_range(struct vm_area_struct *, unsigned long addr,
+ unsigned long pfn, unsigned long size, pgprot_t);
-extern struct page * vmalloc_to_page(void *addr);
-extern unsigned long vmalloc_to_pfn(void *addr);
-extern struct page * follow_page(struct mm_struct *mm, unsigned long address,
- int write);
-extern int check_user_page_readable(struct mm_struct *mm, unsigned long address);
-int remap_pfn_range(struct vm_area_struct *, unsigned long,
- unsigned long, unsigned long, pgprot_t);
+struct page *follow_page(struct mm_struct *, unsigned long address,
+ unsigned int foll_flags);
+#define FOLL_WRITE 0x01 /* check pte is writable */
+#define FOLL_TOUCH 0x02 /* mark page accessed */
+#define FOLL_GET 0x04 /* do get_page on page */
+#define FOLL_ANON 0x08 /* give ZERO_PAGE if no pgtable */
#ifdef CONFIG_PROC_FS
-void __vm_stat_account(struct mm_struct *, unsigned long, struct file *, long);
+void vm_stat_account(struct mm_struct *, unsigned long, struct file *, long);
#else
-static inline void __vm_stat_account(struct mm_struct *mm,
+static inline void vm_stat_account(struct mm_struct *mm,
unsigned long flags, struct file *file, long pages)
{
}
#endif /* CONFIG_PROC_FS */
-static inline void vm_stat_account(struct vm_area_struct *vma)
-{
- __vm_stat_account(vma->vm_mm, vma->vm_flags, vma->vm_file,
- vma_pages(vma));
-}
-
-static inline void vm_stat_unaccount(struct vm_area_struct *vma)
-{
- __vm_stat_account(vma->vm_mm, vma->vm_flags, vma->vm_file,
- -vma_pages(vma));
-}
-
-/* update per process rss and vm hiwater data */
-extern void update_mem_hiwater(struct task_struct *tsk);
-
#ifndef CONFIG_DEBUG_PAGEALLOC
static inline void
kernel_map_pages(struct page *page, int numpages, int enable)
diff --git a/include/linux/mmc/mmc.h b/include/linux/mmc/mmc.h
index 1ab78e8d6c53..aef6042f8f0b 100644
--- a/include/linux/mmc/mmc.h
+++ b/include/linux/mmc/mmc.h
@@ -50,7 +50,7 @@ struct mmc_command {
#define MMC_ERR_INVALID 5
struct mmc_data *data; /* data segment associated with cmd */
- struct mmc_request *mrq; /* assoicated request */
+ struct mmc_request *mrq; /* associated request */
};
struct mmc_data {
@@ -68,7 +68,7 @@ struct mmc_data {
unsigned int bytes_xfered;
struct mmc_command *stop; /* stop command */
- struct mmc_request *mrq; /* assoicated request */
+ struct mmc_request *mrq; /* associated request */
unsigned int sg_len; /* size of scatter list */
struct scatterlist *sg; /* I/O scatter list */
diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
index 5ed471b58f4f..f5fa3082fd6a 100644
--- a/include/linux/mmzone.h
+++ b/include/linux/mmzone.h
@@ -12,6 +12,7 @@
#include <linux/threads.h>
#include <linux/numa.h>
#include <linux/init.h>
+#include <linux/seqlock.h>
#include <asm/atomic.h>
/* Free memory management - zoned buddy allocator. */
@@ -137,6 +138,10 @@ struct zone {
* free areas of different sizes
*/
spinlock_t lock;
+#ifdef CONFIG_MEMORY_HOTPLUG
+ /* see spanned/present_pages for more description */
+ seqlock_t span_seqlock;
+#endif
struct free_area free_area[MAX_ORDER];
@@ -220,6 +225,16 @@ struct zone {
/* zone_start_pfn == zone_start_paddr >> PAGE_SHIFT */
unsigned long zone_start_pfn;
+ /*
+ * zone_start_pfn, spanned_pages and present_pages are all
+ * protected by span_seqlock. It is a seqlock because it has
+ * to be read outside of zone->lock, and it is done in the main
+ * allocator path. But, it is written quite infrequently.
+ *
+ * The lock is declared along with zone->lock because it is
+ * frequently read in proximity to zone->lock. It's good to
+ * give them a chance of being in the same cacheline.
+ */
unsigned long spanned_pages; /* total size, including holes */
unsigned long present_pages; /* amount of memory (excluding holes) */
@@ -273,6 +288,16 @@ typedef struct pglist_data {
struct page *node_mem_map;
#endif
struct bootmem_data *bdata;
+#ifdef CONFIG_MEMORY_HOTPLUG
+ /*
+ * Must be held any time you expect node_start_pfn, node_present_pages
+ * or node_spanned_pages stay constant. Holding this will also
+ * guarantee that any pfn_valid() stays that way.
+ *
+ * Nests above zone->lock and zone->size_seqlock.
+ */
+ spinlock_t node_size_lock;
+#endif
unsigned long node_start_pfn;
unsigned long node_present_pages; /* total number of physical pages */
unsigned long node_spanned_pages; /* total size of physical page
@@ -293,6 +318,8 @@ typedef struct pglist_data {
#endif
#define nid_page_nr(nid, pagenr) pgdat_page_nr(NODE_DATA(nid),(pagenr))
+#include <linux/memory_hotplug.h>
+
extern struct pglist_data *pgdat_list;
void __get_zone_counts(unsigned long *active, unsigned long *inactive,
@@ -302,7 +329,7 @@ void get_zone_counts(unsigned long *active, unsigned long *inactive,
void build_all_zonelists(void);
void wakeup_kswapd(struct zone *zone, int order);
int zone_watermark_ok(struct zone *z, int order, unsigned long mark,
- int alloc_type, int can_try_harder, int gfp_high);
+ int alloc_type, int can_try_harder, gfp_t gfp_high);
#ifdef CONFIG_HAVE_MEMORY_PRESENT
void memory_present(int nid, unsigned long start, unsigned long end);
@@ -509,6 +536,7 @@ static inline struct mem_section *__nr_to_section(unsigned long nr)
return NULL;
return &mem_section[SECTION_NR_TO_ROOT(nr)][nr & SECTION_ROOT_MASK];
}
+extern int __section_nr(struct mem_section* ms);
/*
* We use the lower bits of the mem_map pointer to store
diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h
index 2f0299a448f6..7b08c11ec4cc 100644
--- a/include/linux/mod_devicetable.h
+++ b/include/linux/mod_devicetable.h
@@ -244,4 +244,9 @@ struct pcmcia_device_id {
#define PCMCIA_DEV_ID_MATCH_FAKE_CIS 0x0200
#define PCMCIA_DEV_ID_MATCH_ANONYMOUS 0x0400
+/* I2C */
+struct i2c_device_id {
+ __u16 id;
+};
+
#endif /* LINUX_MOD_DEVICETABLE_H */
diff --git a/include/linux/module.h b/include/linux/module.h
index f05372b7fe77..84d75f3a8aca 100644
--- a/include/linux/module.h
+++ b/include/linux/module.h
@@ -554,7 +554,9 @@ static inline void MODULE_PARM_(void) { }
#ifdef MODULE
/* DEPRECATED: Do not use. */
#define MODULE_PARM(var,type) \
-struct obsolete_modparm __parm_##var __attribute__((section("__obsparm"))) = \
+extern struct obsolete_modparm __parm_##var \
+__attribute__((section("__obsparm"))); \
+struct obsolete_modparm __parm_##var = \
{ __stringify(var), type, &MODULE_PARM_ }; \
__MODULE_PARM_TYPE(var, type);
#else
diff --git a/include/linux/mount.h b/include/linux/mount.h
index f8f39937e301..dd4e83eba933 100644
--- a/include/linux/mount.h
+++ b/include/linux/mount.h
@@ -17,12 +17,14 @@
#include <linux/spinlock.h>
#include <asm/atomic.h>
-#define MNT_NOSUID 1
-#define MNT_NODEV 2
-#define MNT_NOEXEC 4
+#define MNT_NOSUID 0x01
+#define MNT_NODEV 0x02
+#define MNT_NOEXEC 0x04
+#define MNT_SHARED 0x10 /* if the vfsmount is a shared mount */
+#define MNT_UNBINDABLE 0x20 /* if the vfsmount is a unbindable mount */
+#define MNT_PNODE_MASK 0x30 /* propogation flag mask */
-struct vfsmount
-{
+struct vfsmount {
struct list_head mnt_hash;
struct vfsmount *mnt_parent; /* fs we are mounted on */
struct dentry *mnt_mountpoint; /* dentry of mountpoint */
@@ -36,7 +38,12 @@ struct vfsmount
char *mnt_devname; /* Name of device e.g. /dev/dsk/hda1 */
struct list_head mnt_list;
struct list_head mnt_expire; /* link in fs-specific expiry list */
+ struct list_head mnt_share; /* circular list of shared mounts */
+ struct list_head mnt_slave_list;/* list of slave mounts */
+ struct list_head mnt_slave; /* slave list entry */
+ struct vfsmount *mnt_master; /* slave is on master->mnt_slave_list */
struct namespace *mnt_namespace; /* containing namespace */
+ int mnt_pinned;
};
static inline struct vfsmount *mntget(struct vfsmount *mnt)
@@ -46,15 +53,9 @@ static inline struct vfsmount *mntget(struct vfsmount *mnt)
return mnt;
}
-extern void __mntput(struct vfsmount *mnt);
-
-static inline void mntput_no_expire(struct vfsmount *mnt)
-{
- if (mnt) {
- if (atomic_dec_and_test(&mnt->mnt_count))
- __mntput(mnt);
- }
-}
+extern void mntput_no_expire(struct vfsmount *mnt);
+extern void mnt_pin(struct vfsmount *mnt);
+extern void mnt_unpin(struct vfsmount *mnt);
static inline void mntput(struct vfsmount *mnt)
{
diff --git a/include/linux/msdos_fs.h b/include/linux/msdos_fs.h
index 9a3d27257984..941da5c016a0 100644
--- a/include/linux/msdos_fs.h
+++ b/include/linux/msdos_fs.h
@@ -282,6 +282,17 @@ static inline u8 fat_attr(struct inode *inode)
MSDOS_I(inode)->i_attrs;
}
+static inline unsigned char fat_checksum(const __u8 *name)
+{
+ unsigned char s = name[0];
+ s = (s<<7) + (s>>1) + name[1]; s = (s<<7) + (s>>1) + name[2];
+ s = (s<<7) + (s>>1) + name[3]; s = (s<<7) + (s>>1) + name[4];
+ s = (s<<7) + (s>>1) + name[5]; s = (s<<7) + (s>>1) + name[6];
+ s = (s<<7) + (s>>1) + name[7]; s = (s<<7) + (s>>1) + name[8];
+ s = (s<<7) + (s>>1) + name[9]; s = (s<<7) + (s>>1) + name[10];
+ return s;
+}
+
static inline sector_t fat_clus_to_blknr(struct msdos_sb_info *sbi, int clus)
{
return ((sector_t)clus - FAT_START_ENT) * sbi->sec_per_clus
diff --git a/include/linux/mtd/bbm.h b/include/linux/mtd/bbm.h
new file mode 100644
index 000000000000..7a7fbe87fef0
--- /dev/null
+++ b/include/linux/mtd/bbm.h
@@ -0,0 +1,122 @@
+/*
+ * linux/include/linux/mtd/bbm.h
+ *
+ * NAND family Bad Block Management (BBM) header file
+ * - Bad Block Table (BBT) implementation
+ *
+ * Copyright (c) 2005 Samsung Electronics
+ * Kyungmin Park <kyungmin.park@samsung.com>
+ *
+ * Copyright (c) 2000-2005
+ * Thomas Gleixner <tglx@linuxtronix.de>
+ *
+ */
+#ifndef __LINUX_MTD_BBM_H
+#define __LINUX_MTD_BBM_H
+
+/* The maximum number of NAND chips in an array */
+#define NAND_MAX_CHIPS 8
+
+/**
+ * struct nand_bbt_descr - bad block table descriptor
+ * @param options options for this descriptor
+ * @param pages the page(s) where we find the bbt, used with
+ * option BBT_ABSPAGE when bbt is searched,
+ * then we store the found bbts pages here.
+ * Its an array and supports up to 8 chips now
+ * @param offs offset of the pattern in the oob area of the page
+ * @param veroffs offset of the bbt version counter in the oob are of the page
+ * @param version version read from the bbt page during scan
+ * @param len length of the pattern, if 0 no pattern check is performed
+ * @param maxblocks maximum number of blocks to search for a bbt. This number of
+ * blocks is reserved at the end of the device
+ * where the tables are written.
+ * @param reserved_block_code if non-0, this pattern denotes a reserved
+ * (rather than bad) block in the stored bbt
+ * @param pattern pattern to identify bad block table or factory marked
+ * good / bad blocks, can be NULL, if len = 0
+ *
+ * Descriptor for the bad block table marker and the descriptor for the
+ * pattern which identifies good and bad blocks. The assumption is made
+ * that the pattern and the version count are always located in the oob area
+ * of the first block.
+ */
+struct nand_bbt_descr {
+ int options;
+ int pages[NAND_MAX_CHIPS];
+ int offs;
+ int veroffs;
+ uint8_t version[NAND_MAX_CHIPS];
+ int len;
+ int maxblocks;
+ int reserved_block_code;
+ uint8_t *pattern;
+};
+
+/* Options for the bad block table descriptors */
+
+/* The number of bits used per block in the bbt on the device */
+#define NAND_BBT_NRBITS_MSK 0x0000000F
+#define NAND_BBT_1BIT 0x00000001
+#define NAND_BBT_2BIT 0x00000002
+#define NAND_BBT_4BIT 0x00000004
+#define NAND_BBT_8BIT 0x00000008
+/* The bad block table is in the last good block of the device */
+#define NAND_BBT_LASTBLOCK 0x00000010
+/* The bbt is at the given page, else we must scan for the bbt */
+#define NAND_BBT_ABSPAGE 0x00000020
+/* The bbt is at the given page, else we must scan for the bbt */
+#define NAND_BBT_SEARCH 0x00000040
+/* bbt is stored per chip on multichip devices */
+#define NAND_BBT_PERCHIP 0x00000080
+/* bbt has a version counter at offset veroffs */
+#define NAND_BBT_VERSION 0x00000100
+/* Create a bbt if none axists */
+#define NAND_BBT_CREATE 0x00000200
+/* Search good / bad pattern through all pages of a block */
+#define NAND_BBT_SCANALLPAGES 0x00000400
+/* Scan block empty during good / bad block scan */
+#define NAND_BBT_SCANEMPTY 0x00000800
+/* Write bbt if neccecary */
+#define NAND_BBT_WRITE 0x00001000
+/* Read and write back block contents when writing bbt */
+#define NAND_BBT_SAVECONTENT 0x00002000
+/* Search good / bad pattern on the first and the second page */
+#define NAND_BBT_SCAN2NDPAGE 0x00004000
+
+/* The maximum number of blocks to scan for a bbt */
+#define NAND_BBT_SCAN_MAXBLOCKS 4
+
+/*
+ * Constants for oob configuration
+ */
+#define ONENAND_BADBLOCK_POS 0
+
+/**
+ * struct bbt_info - [GENERIC] Bad Block Table data structure
+ * @param bbt_erase_shift [INTERN] number of address bits in a bbt entry
+ * @param badblockpos [INTERN] position of the bad block marker in the oob area
+ * @param bbt [INTERN] bad block table pointer
+ * @param badblock_pattern [REPLACEABLE] bad block scan pattern used for initial bad block scan
+ * @param priv [OPTIONAL] pointer to private bbm date
+ */
+struct bbm_info {
+ int bbt_erase_shift;
+ int badblockpos;
+ int options;
+
+ uint8_t *bbt;
+
+ int (*isbad_bbt)(struct mtd_info *mtd, loff_t ofs, int allowbbt);
+
+ /* TODO Add more NAND specific fileds */
+ struct nand_bbt_descr *badblock_pattern;
+
+ void *priv;
+};
+
+/* OneNAND BBT interface */
+extern int onenand_scan_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd);
+extern int onenand_default_bbt(struct mtd_info *mtd);
+
+#endif /* __LINUX_MTD_BBM_H */
diff --git a/include/linux/mtd/blktrans.h b/include/linux/mtd/blktrans.h
index 4ebc2e5a16e2..f46afec6fbf8 100644
--- a/include/linux/mtd/blktrans.h
+++ b/include/linux/mtd/blktrans.h
@@ -1,5 +1,5 @@
/*
- * $Id: blktrans.h,v 1.5 2003/06/23 12:00:08 dwmw2 Exp $
+ * $Id: blktrans.h,v 1.6 2005/11/07 11:14:54 gleixner Exp $
*
* (C) 2003 David Woodhouse <dwmw2@infradead.org>
*
@@ -67,6 +67,6 @@ extern int register_mtd_blktrans(struct mtd_blktrans_ops *tr);
extern int deregister_mtd_blktrans(struct mtd_blktrans_ops *tr);
extern int add_mtd_blktrans_dev(struct mtd_blktrans_dev *dev);
extern int del_mtd_blktrans_dev(struct mtd_blktrans_dev *dev);
-
+
#endif /* __MTD_TRANS_H__ */
diff --git a/include/linux/mtd/cfi.h b/include/linux/mtd/cfi.h
index e6b6a1c66bd5..3c9ea4b7adda 100644
--- a/include/linux/mtd/cfi.h
+++ b/include/linux/mtd/cfi.h
@@ -1,14 +1,13 @@
-/* Common Flash Interface structures
+/* Common Flash Interface structures
* See http://support.intel.com/design/flash/technote/index.htm
- * $Id: cfi.h,v 1.54 2005/06/06 23:04:36 tpoynor Exp $
+ * $Id: cfi.h,v 1.56 2005/11/07 11:14:54 gleixner Exp $
*/
#ifndef __MTD_CFI_H__
#define __MTD_CFI_H__
#include <linux/config.h>
-#include <linux/version.h>
#include <linux/delay.h>
#include <linux/types.h>
#include <linux/interrupt.h>
@@ -82,8 +81,8 @@ static inline int cfi_interleave_supported(int i)
}
-/* NB: these values must represents the number of bytes needed to meet the
- * device type (x8, x16, x32). Eg. a 32 bit device is 4 x 8 bytes.
+/* NB: these values must represents the number of bytes needed to meet the
+ * device type (x8, x16, x32). Eg. a 32 bit device is 4 x 8 bytes.
* These numbers are used in calculations.
*/
#define CFI_DEVICETYPE_X8 (8 / 8)
@@ -173,6 +172,15 @@ struct cfi_intelext_regioninfo {
struct cfi_intelext_blockinfo BlockTypes[1];
} __attribute__((packed));
+struct cfi_intelext_programming_regioninfo {
+ uint8_t ProgRegShift;
+ uint8_t Reserved1;
+ uint8_t ControlValid;
+ uint8_t Reserved2;
+ uint8_t ControlInvalid;
+ uint8_t Reserved3;
+} __attribute__((packed));
+
/* Vendor-Specific PRI for AMD/Fujitsu Extended Command Set (0x0002) */
struct cfi_pri_amdstd {
@@ -250,7 +258,7 @@ static inline uint32_t cfi_build_cmd_addr(uint32_t cmd_ofs, int interleave, int
/*
* Transforms the CFI command for the given geometry (bus width & interleave).
* It looks too long to be inline, but in the common case it should almost all
- * get optimised away.
+ * get optimised away.
*/
static inline map_word cfi_build_cmd(u_long cmd, struct map_info *map, struct cfi_private *cfi)
{
@@ -259,7 +267,7 @@ static inline map_word cfi_build_cmd(u_long cmd, struct map_info *map, struct cf
unsigned long onecmd;
int i;
- /* We do it this way to give the compiler a fighting chance
+ /* We do it this way to give the compiler a fighting chance
of optimising away all the crap for 'bankwidth' larger than
an unsigned long, in the common case where that support is
disabled */
@@ -270,7 +278,7 @@ static inline map_word cfi_build_cmd(u_long cmd, struct map_info *map, struct cf
wordwidth = map_bankwidth(map);
words_per_bus = 1;
}
-
+
chip_mode = map_bankwidth(map) / cfi_interleave(cfi);
chips_per_word = wordwidth * cfi_interleave(cfi) / map_bankwidth(map);
@@ -289,7 +297,7 @@ static inline map_word cfi_build_cmd(u_long cmd, struct map_info *map, struct cf
break;
}
- /* Now replicate it across the size of an unsigned long, or
+ /* Now replicate it across the size of an unsigned long, or
just to the bus width as appropriate */
switch (chips_per_word) {
default: BUG();
@@ -305,7 +313,7 @@ static inline map_word cfi_build_cmd(u_long cmd, struct map_info *map, struct cf
;
}
- /* And finally, for the multi-word case, replicate it
+ /* And finally, for the multi-word case, replicate it
in all words in the structure */
for (i=0; i < words_per_bus; i++) {
val.x[i] = onecmd;
@@ -316,14 +324,14 @@ static inline map_word cfi_build_cmd(u_long cmd, struct map_info *map, struct cf
#define CMD(x) cfi_build_cmd((x), map, cfi)
-static inline unsigned char cfi_merge_status(map_word val, struct map_info *map,
+static inline unsigned long cfi_merge_status(map_word val, struct map_info *map,
struct cfi_private *cfi)
{
int wordwidth, words_per_bus, chip_mode, chips_per_word;
unsigned long onestat, res = 0;
int i;
- /* We do it this way to give the compiler a fighting chance
+ /* We do it this way to give the compiler a fighting chance
of optimising away all the crap for 'bankwidth' larger than
an unsigned long, in the common case where that support is
disabled */
@@ -334,7 +342,7 @@ static inline unsigned char cfi_merge_status(map_word val, struct map_info *map,
wordwidth = map_bankwidth(map);
words_per_bus = 1;
}
-
+
chip_mode = map_bankwidth(map) / cfi_interleave(cfi);
chips_per_word = wordwidth * cfi_interleave(cfi) / map_bankwidth(map);
diff --git a/include/linux/mtd/doc2000.h b/include/linux/mtd/doc2000.h
index 953e64fb8ac5..386a52cf8b1b 100644
--- a/include/linux/mtd/doc2000.h
+++ b/include/linux/mtd/doc2000.h
@@ -1,12 +1,12 @@
-/*
+/*
* Linux driver for Disk-On-Chip devices
*
- * Copyright (C) 1999 Machine Vision Holdings, Inc.
+ * Copyright (C) 1999 Machine Vision Holdings, Inc.
* Copyright (C) 2001-2003 David Woodhouse <dwmw2@infradead.org>
* Copyright (C) 2002-2003 Greg Ungerer <gerg@snapgear.com>
* Copyright (C) 2002-2003 SnapGear Inc
*
- * $Id: doc2000.h,v 1.24 2005/01/05 12:40:38 dwmw2 Exp $
+ * $Id: doc2000.h,v 1.25 2005/11/07 11:14:54 gleixner Exp $
*
* Released under GPL
*/
@@ -75,10 +75,10 @@
#define DoC_Mplus_CtrlConfirm 0x1076
#define DoC_Mplus_Power 0x1fff
-/* How to access the device?
- * On ARM, it'll be mmap'd directly with 32-bit wide accesses.
+/* How to access the device?
+ * On ARM, it'll be mmap'd directly with 32-bit wide accesses.
* On PPC, it's mmap'd and 16-bit wide.
- * Others use readb/writeb
+ * Others use readb/writeb
*/
#if defined(__arm__)
#define ReadDOC_(adr, reg) ((unsigned char)(*(volatile __u32 *)(((unsigned long)adr)+((reg)<<2))))
@@ -172,7 +172,7 @@ struct DiskOnChip {
unsigned long totlen;
unsigned char ChipID; /* Type of DiskOnChip */
int ioreg;
-
+
unsigned long mfr; /* Flash IDs - only one type of flash per device */
unsigned long id;
int chipshift;
@@ -180,10 +180,10 @@ struct DiskOnChip {
char pageadrlen;
char interleave; /* Internal interleaving - Millennium Plus style */
unsigned long erasesize;
-
+
int curfloor;
int curchip;
-
+
int numchips;
struct Nand *chips;
struct mtd_info *nextdoc;
diff --git a/include/linux/mtd/flashchip.h b/include/linux/mtd/flashchip.h
index 675776fa3e27..a293a3b78e05 100644
--- a/include/linux/mtd/flashchip.h
+++ b/include/linux/mtd/flashchip.h
@@ -1,12 +1,12 @@
-/*
+/*
* struct flchip definition
- *
- * Contains information about the location and state of a given flash device
+ *
+ * Contains information about the location and state of a given flash device
*
* (C) 2000 Red Hat. GPLd.
*
- * $Id: flashchip.h,v 1.17 2005/03/14 18:27:15 bjd Exp $
+ * $Id: flashchip.h,v 1.18 2005/11/07 11:14:54 gleixner Exp $
*
*/
@@ -15,11 +15,11 @@
/* For spinlocks. sched.h includes spinlock.h from whichever directory it
* happens to be in - so we don't have to care whether we're on 2.2, which
- * has asm/spinlock.h, or 2.4, which has linux/spinlock.h
+ * has asm/spinlock.h, or 2.4, which has linux/spinlock.h
*/
#include <linux/sched.h>
-typedef enum {
+typedef enum {
FL_READY,
FL_STATUS,
FL_CFI_QUERY,
@@ -45,7 +45,7 @@ typedef enum {
-/* NOTE: confusingly, this can be used to refer to more than one chip at a time,
+/* NOTE: confusingly, this can be used to refer to more than one chip at a time,
if they're interleaved. This can even refer to individual partitions on
the same physical chip when present. */
diff --git a/include/linux/mtd/ftl.h b/include/linux/mtd/ftl.h
index 3678459b4535..d99609113307 100644
--- a/include/linux/mtd/ftl.h
+++ b/include/linux/mtd/ftl.h
@@ -1,6 +1,6 @@
/*
- * $Id: ftl.h,v 1.6 2003/01/24 13:20:04 dwmw2 Exp $
- *
+ * $Id: ftl.h,v 1.7 2005/11/07 11:14:54 gleixner Exp $
+ *
* Derived from (and probably identical to):
* ftl.h 1.7 1999/10/25 20:23:17
*
@@ -12,7 +12,7 @@
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and
- * limitations under the License.
+ * limitations under the License.
*
* The initial developer of the original code is David A. Hinds
* <dahinds@users.sourceforge.net>. Portions created by David A. Hinds
diff --git a/include/linux/mtd/gen_probe.h b/include/linux/mtd/gen_probe.h
index 3d7bdec14f97..256e7342ed1e 100644
--- a/include/linux/mtd/gen_probe.h
+++ b/include/linux/mtd/gen_probe.h
@@ -1,14 +1,14 @@
/*
* (C) 2001, 2001 Red Hat, Inc.
* GPL'd
- * $Id: gen_probe.h,v 1.3 2004/10/20 22:10:33 dwmw2 Exp $
+ * $Id: gen_probe.h,v 1.4 2005/11/07 11:14:54 gleixner Exp $
*/
#ifndef __LINUX_MTD_GEN_PROBE_H__
#define __LINUX_MTD_GEN_PROBE_H__
#include <linux/mtd/flashchip.h>
-#include <linux/mtd/map.h>
+#include <linux/mtd/map.h>
#include <linux/mtd/cfi.h>
#include <linux/bitops.h>
diff --git a/include/linux/mtd/jedec.h b/include/linux/mtd/jedec.h
index 2ba0f700ddbc..9006feb218b9 100644
--- a/include/linux/mtd/jedec.h
+++ b/include/linux/mtd/jedec.h
@@ -1,13 +1,13 @@
/* JEDEC Flash Interface.
- * This is an older type of interface for self programming flash. It is
+ * This is an older type of interface for self programming flash. It is
* commonly use in older AMD chips and is obsolete compared with CFI.
* It is called JEDEC because the JEDEC association distributes the ID codes
* for the chips.
*
* See the AMD flash databook for information on how to operate the interface.
*
- * $Id: jedec.h,v 1.3 2003/05/21 11:51:01 dwmw2 Exp $
+ * $Id: jedec.h,v 1.4 2005/11/07 11:14:54 gleixner Exp $
*/
#ifndef __LINUX_MTD_JEDEC_H__
@@ -33,16 +33,16 @@ struct jedec_flash_chip
__u16 jedec;
unsigned long size;
unsigned long sectorsize;
-
+
// *(__u8*)(base + (adder << addrshift)) = data << datashift
// Address size = size << addrshift
unsigned long base; // Byte 0 of the flash, will be unaligned
unsigned int datashift; // Useful for 32bit/16bit accesses
unsigned int addrshift;
unsigned long offset; // linerized start. base==offset for unbanked, uninterleaved flash
-
+
__u32 capabilities;
-
+
// These markers are filled in by the flash_chip_scan function
unsigned long start;
unsigned long length;
@@ -51,16 +51,16 @@ struct jedec_flash_chip
struct jedec_private
{
unsigned long size; // Total size of all the devices
-
+
/* Bank handling. If sum(bank_fill) == size then this is linear flash.
Otherwise the mapping has holes in it. bank_fill may be used to
- find the holes, but in the common symetric case
- bank_fill[0] == bank_fill[*], thus addresses may be computed
+ find the holes, but in the common symetric case
+ bank_fill[0] == bank_fill[*], thus addresses may be computed
mathmatically. bank_fill must be powers of two */
unsigned is_banked;
unsigned long bank_fill[MAX_JEDEC_CHIPS];
-
- struct jedec_flash_chip chips[MAX_JEDEC_CHIPS];
+
+ struct jedec_flash_chip chips[MAX_JEDEC_CHIPS];
};
#endif
diff --git a/include/linux/mtd/map.h b/include/linux/mtd/map.h
index 142963f01d29..fedfbc8a287f 100644
--- a/include/linux/mtd/map.h
+++ b/include/linux/mtd/map.h
@@ -1,6 +1,6 @@
/* Overhauled routines for dealing with different mmap regions of flash */
-/* $Id: map.h,v 1.52 2005/05/25 10:29:41 gleixner Exp $ */
+/* $Id: map.h,v 1.54 2005/11/07 11:14:54 gleixner Exp $ */
#ifndef __LINUX_MTD_MAP_H__
#define __LINUX_MTD_MAP_H__
@@ -8,7 +8,10 @@
#include <linux/config.h>
#include <linux/types.h>
#include <linux/list.h>
+#include <linux/string.h>
+
#include <linux/mtd/compatmac.h>
+
#include <asm/unaligned.h>
#include <asm/system.h>
#include <asm/io.h>
@@ -167,14 +170,14 @@ typedef union {
to a chip probe routine -- either JEDEC or CFI probe or both -- via
do_map_probe(). If a chip is recognised, the probe code will invoke the
appropriate chip driver (if present) and return a struct mtd_info.
- At which point, you fill in the mtd->module with your own module
+ At which point, you fill in the mtd->module with your own module
address, and register it with the MTD core code. Or you could partition
it and register the partitions instead, or keep it for your own private
use; whatever.
-
+
The mtd->priv field will point to the struct map_info, and any further
- private data required by the chip driver is linked from the
- mtd->priv->fldrv_priv field. This allows the map driver to get at
+ private data required by the chip driver is linked from the
+ mtd->priv->fldrv_priv field. This allows the map driver to get at
the destructor function map->fldrv_destroy() when it's tired
of living.
*/
@@ -211,7 +214,7 @@ struct map_info {
If there is no cache to care about this can be set to NULL. */
void (*inval_cache)(struct map_info *, unsigned long, ssize_t);
- /* set_vpp() must handle being reentered -- enable, enable, disable
+ /* set_vpp() must handle being reentered -- enable, enable, disable
must leave it enabled. */
void (*set_vpp)(struct map_info *, int);
@@ -350,7 +353,7 @@ static inline map_word map_word_ff(struct map_info *map)
{
map_word r;
int i;
-
+
if (map_bankwidth(map) < MAP_FF_LIMIT) {
int bw = 8 * map_bankwidth(map);
r.x[0] = (1 << bw) - 1;
diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h
index c50c3f3927d9..b6f2fdae65c6 100644
--- a/include/linux/mtd/mtd.h
+++ b/include/linux/mtd/mtd.h
@@ -1,5 +1,5 @@
-/*
- * $Id: mtd.h,v 1.59 2005/04/11 10:19:02 gleixner Exp $
+/*
+ * $Id: mtd.h,v 1.61 2005/11/07 11:14:54 gleixner Exp $
*
* Copyright (C) 1999-2003 David Woodhouse <dwmw2@infradead.org> et al.
*
@@ -14,7 +14,6 @@
#endif
#include <linux/config.h>
-#include <linux/version.h>
#include <linux/types.h>
#include <linux/module.h>
#include <linux/uio.h>
@@ -72,7 +71,17 @@ struct mtd_info {
u_int32_t oobsize; // Amount of OOB data per block (e.g. 16)
u_int32_t ecctype;
u_int32_t eccsize;
-
+
+ /*
+ * Reuse some of the above unused fields in the case of NOR flash
+ * with configurable programming regions to avoid modifying the
+ * user visible structure layout/size. Only valid when the
+ * MTD_PROGRAM_REGIONS flag is set.
+ * (Maybe we should have an union for those?)
+ */
+#define MTD_PROGREGION_SIZE(mtd) (mtd)->oobblock
+#define MTD_PROGREGION_CTRLMODE_VALID(mtd) (mtd)->oobsize
+#define MTD_PROGREGION_CTRLMODE_INVALID(mtd) (mtd)->ecctype
// Kernel-only stuff starts here.
char *name;
@@ -80,13 +89,13 @@ struct mtd_info {
// oobinfo is a nand_oobinfo structure, which can be set by iotcl (MEMSETOOBINFO)
struct nand_oobinfo oobinfo;
- u_int32_t oobavail; // Number of bytes in OOB area available for fs
+ u_int32_t oobavail; // Number of bytes in OOB area available for fs
/* Data for variable erase regions. If numeraseregions is zero,
- * it means that the whole device has erasesize as given above.
+ * it means that the whole device has erasesize as given above.
*/
int numeraseregions;
- struct mtd_erase_region_info *eraseregions;
+ struct mtd_erase_region_info *eraseregions;
/* This really shouldn't be here. It can go away in 2.5 */
u_int32_t bank_size;
@@ -109,10 +118,10 @@ struct mtd_info {
int (*read_oob) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf);
int (*write_oob) (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf);
- /*
- * Methods to access the protection register area, present in some
+ /*
+ * Methods to access the protection register area, present in some
* flash devices. The user data is one time programmable but the
- * factory data is read only.
+ * factory data is read only.
*/
int (*get_fact_prot_info) (struct mtd_info *mtd, struct otp_info *buf, size_t len);
int (*read_fact_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf);
@@ -123,14 +132,14 @@ struct mtd_info {
/* kvec-based read/write methods. We need these especially for NAND flash,
with its limited number of write cycles per erase.
- NB: The 'count' parameter is the number of _vectors_, each of
+ NB: The 'count' parameter is the number of _vectors_, each of
which contains an (ofs, len) tuple.
*/
int (*readv) (struct mtd_info *mtd, struct kvec *vecs, unsigned long count, loff_t from, size_t *retlen);
- int (*readv_ecc) (struct mtd_info *mtd, struct kvec *vecs, unsigned long count, loff_t from,
+ int (*readv_ecc) (struct mtd_info *mtd, struct kvec *vecs, unsigned long count, loff_t from,
size_t *retlen, u_char *eccbuf, struct nand_oobinfo *oobsel);
int (*writev) (struct mtd_info *mtd, const struct kvec *vecs, unsigned long count, loff_t to, size_t *retlen);
- int (*writev_ecc) (struct mtd_info *mtd, const struct kvec *vecs, unsigned long count, loff_t to,
+ int (*writev_ecc) (struct mtd_info *mtd, const struct kvec *vecs, unsigned long count, loff_t to,
size_t *retlen, u_char *eccbuf, struct nand_oobinfo *oobsel);
/* Sync */
@@ -194,7 +203,7 @@ int default_mtd_readv(struct mtd_info *mtd, struct kvec *vecs,
#define MTD_WRITEECC(mtd, args...) (*(mtd->write_ecc))(mtd, args)
#define MTD_READOOB(mtd, args...) (*(mtd->read_oob))(mtd, args)
#define MTD_WRITEOOB(mtd, args...) (*(mtd->write_oob))(mtd, args)
-#define MTD_SYNC(mtd) do { if (mtd->sync) (*(mtd->sync))(mtd); } while (0)
+#define MTD_SYNC(mtd) do { if (mtd->sync) (*(mtd->sync))(mtd); } while (0)
#ifdef CONFIG_MTD_PARTITIONS
diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
index 9b5b76217584..da5e67b3fc70 100644
--- a/include/linux/mtd/nand.h
+++ b/include/linux/mtd/nand.h
@@ -5,7 +5,7 @@
* Steven J. Hill <sjhill@realitydiluted.com>
* Thomas Gleixner <tglx@linutronix.de>
*
- * $Id: nand.h,v 1.73 2005/05/31 19:39:17 gleixner Exp $
+ * $Id: nand.h,v 1.74 2005/09/15 13:58:50 vwool Exp $
*
* 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
@@ -24,7 +24,7 @@
* bat later if I did something naughty.
* 10-11-2000 SJH Added private NAND flash structure for driver
* 10-24-2000 SJH Added prototype for 'nand_scan' function
- * 10-29-2001 TG changed nand_chip structure to support
+ * 10-29-2001 TG changed nand_chip structure to support
* hardwarespecific function for accessing control lines
* 02-21-2002 TG added support for different read/write adress and
* ready/busy line access function
@@ -36,21 +36,21 @@
* CONFIG_MTD_NAND_ECC_JFFS2 is not set
* 08-10-2002 TG extensions to nand_chip structure to support HW-ECC
*
- * 08-29-2002 tglx nand_chip structure: data_poi for selecting
+ * 08-29-2002 tglx nand_chip structure: data_poi for selecting
* internal / fs-driver buffer
* support for 6byte/512byte hardware ECC
* read_ecc, write_ecc extended for different oob-layout
* oob layout selections: NAND_NONE_OOB, NAND_JFFS2_OOB,
* NAND_YAFFS_OOB
* 11-25-2002 tglx Added Manufacturer code FUJITSU, NATIONAL
- * Split manufacturer and device ID structures
+ * Split manufacturer and device ID structures
*
* 02-08-2004 tglx added option field to nand structure for chip anomalities
* 05-25-2004 tglx added bad block table support, ST-MICRO manufacturer id
* update of nand_chip structure description
- * 01-17-2005 dmarlin added extended commands for AG-AND device and added option
+ * 01-17-2005 dmarlin added extended commands for AG-AND device and added option
* for BBT_AUTO_REFRESH.
- * 01-20-2005 dmarlin added optional pointer to hardware specific callback for
+ * 01-20-2005 dmarlin added optional pointer to hardware specific callback for
* extra error status checks.
*/
#ifndef __LINUX_MTD_NAND_H
@@ -120,8 +120,8 @@ extern int nand_read_raw (struct mtd_info *mtd, uint8_t *buf, loff_t from, size_
#define NAND_CMD_CACHEDPROG 0x15
/* Extended commands for AG-AND device */
-/*
- * Note: the command for NAND_CMD_DEPLETE1 is really 0x00 but
+/*
+ * Note: the command for NAND_CMD_DEPLETE1 is really 0x00 but
* there is no way to distinguish that from NAND_CMD_READ0
* until the remaining sequence of commands has been completed
* so add a high order bit and mask it off in the command.
@@ -145,7 +145,7 @@ extern int nand_read_raw (struct mtd_info *mtd, uint8_t *buf, loff_t from, size_
#define NAND_STATUS_READY 0x40
#define NAND_STATUS_WP 0x80
-/*
+/*
* Constants for ECC_MODES
*/
@@ -191,12 +191,12 @@ extern int nand_read_raw (struct mtd_info *mtd, uint8_t *buf, loff_t from, size_
#define NAND_CACHEPRG 0x00000008
/* Chip has copy back function */
#define NAND_COPYBACK 0x00000010
-/* AND Chip which has 4 banks and a confusing page / block
+/* AND Chip which has 4 banks and a confusing page / block
* assignment. See Renesas datasheet for further information */
#define NAND_IS_AND 0x00000020
/* Chip has a array of 4 pages which can be read without
* additional ready /busy waits */
-#define NAND_4PAGE_ARRAY 0x00000040
+#define NAND_4PAGE_ARRAY 0x00000040
/* Chip requires that BBT is periodically rewritten to prevent
* bits from adjacent blocks from 'leaking' in altering data.
* This happens with the Renesas AG-AND chips, possibly others. */
@@ -219,8 +219,8 @@ extern int nand_read_raw (struct mtd_info *mtd, uint8_t *buf, loff_t from, size_
/* Use a flash based bad block table. This option is passed to the
* default bad block table function. */
#define NAND_USE_FLASH_BBT 0x00010000
-/* The hw ecc generator provides a syndrome instead a ecc value on read
- * This can only work if we have the ecc bytes directly behind the
+/* The hw ecc generator provides a syndrome instead a ecc value on read
+ * This can only work if we have the ecc bytes directly behind the
* data bytes. Applies for DOC and AG-AND Renesas HW Reed Solomon generators */
#define NAND_HWECC_SYNDROME 0x00020000
/* This option skips the bbt scan during initialization. */
@@ -244,6 +244,7 @@ typedef enum {
FL_ERASING,
FL_SYNCING,
FL_CACHEDPRG,
+ FL_PM_SUSPENDED,
} nand_state_t;
/* Keep gcc happy */
@@ -251,7 +252,7 @@ struct nand_chip;
/**
* struct nand_hw_control - Control structure for hardware controller (e.g ECC generator) shared among independend devices
- * @lock: protection lock
+ * @lock: protection lock
* @active: the mtd device which holds the controller currently
* @wq: wait queue to sleep on if a NAND operation is in progress
* used instead of the per chip wait queue when a hw controller is available
@@ -264,8 +265,8 @@ struct nand_hw_control {
/**
* struct nand_chip - NAND Private Flash Chip Data
- * @IO_ADDR_R: [BOARDSPECIFIC] address to read the 8 I/O lines of the flash device
- * @IO_ADDR_W: [BOARDSPECIFIC] address to write the 8 I/O lines of the flash device
+ * @IO_ADDR_R: [BOARDSPECIFIC] address to read the 8 I/O lines of the flash device
+ * @IO_ADDR_W: [BOARDSPECIFIC] address to write the 8 I/O lines of the flash device
* @read_byte: [REPLACEABLE] read one byte from the chip
* @write_byte: [REPLACEABLE] write one byte to the chip
* @read_word: [REPLACEABLE] read one word from the chip
@@ -288,7 +289,7 @@ struct nand_hw_control {
* be provided if a hardware ECC is available
* @erase_cmd: [INTERN] erase command write function, selectable due to AND support
* @scan_bbt: [REPLACEABLE] function to scan bad block table
- * @eccmode: [BOARDSPECIFIC] mode of ecc, see defines
+ * @eccmode: [BOARDSPECIFIC] mode of ecc, see defines
* @eccsize: [INTERN] databytes used per ecc-calculation
* @eccbytes: [INTERN] number of ecc bytes per ecc-calculation step
* @eccsteps: [INTERN] number of ecc calculation steps per page
@@ -300,7 +301,7 @@ struct nand_hw_control {
* @phys_erase_shift: [INTERN] number of address bits in a physical eraseblock
* @bbt_erase_shift: [INTERN] number of address bits in a bbt entry
* @chip_shift: [INTERN] number of address bits in one chip
- * @data_buf: [INTERN] internal buffer for one page + oob
+ * @data_buf: [INTERN] internal buffer for one page + oob
* @oob_buf: [INTERN] oob buffer for one eraseblock
* @oobdirty: [INTERN] indicates that oob_buf must be reinitialized
* @data_poi: [INTERN] pointer to a data buffer
@@ -315,22 +316,22 @@ struct nand_hw_control {
* @bbt: [INTERN] bad block table pointer
* @bbt_td: [REPLACEABLE] bad block table descriptor for flash lookup
* @bbt_md: [REPLACEABLE] bad block table mirror descriptor
- * @badblock_pattern: [REPLACEABLE] bad block scan pattern used for initial bad block scan
+ * @badblock_pattern: [REPLACEABLE] bad block scan pattern used for initial bad block scan
* @controller: [OPTIONAL] a pointer to a hardware controller structure which is shared among multiple independend devices
* @priv: [OPTIONAL] pointer to private chip date
- * @errstat: [OPTIONAL] hardware specific function to perform additional error status checks
+ * @errstat: [OPTIONAL] hardware specific function to perform additional error status checks
* (determine if errors are correctable)
*/
-
+
struct nand_chip {
void __iomem *IO_ADDR_R;
void __iomem *IO_ADDR_W;
-
+
u_char (*read_byte)(struct mtd_info *mtd);
void (*write_byte)(struct mtd_info *mtd, u_char byte);
u16 (*read_word)(struct mtd_info *mtd);
void (*write_word)(struct mtd_info *mtd, u16 word);
-
+
void (*write_buf)(struct mtd_info *mtd, const u_char *buf, int len);
void (*read_buf)(struct mtd_info *mtd, u_char *buf, int len);
int (*verify_buf)(struct mtd_info *mtd, const u_char *buf, int len);
@@ -395,7 +396,7 @@ struct nand_chip {
* @name: Identify the device type
* @id: device ID code
* @pagesize: Pagesize in bytes. Either 256 or 512 or 0
- * If the pagesize is 0, then the real pagesize
+ * If the pagesize is 0, then the real pagesize
* and the eraseize are determined from the
* extended id bytes in the chip
* @erasesize: Size of an erase block in the flash device.
@@ -424,7 +425,7 @@ struct nand_manufacturers {
extern struct nand_flash_dev nand_flash_ids[];
extern struct nand_manufacturers nand_manuf_ids[];
-/**
+/**
* struct nand_bbt_descr - bad block table descriptor
* @options: options for this descriptor
* @pages: the page(s) where we find the bbt, used with option BBT_ABSPAGE
@@ -435,14 +436,14 @@ extern struct nand_manufacturers nand_manuf_ids[];
* @version: version read from the bbt page during scan
* @len: length of the pattern, if 0 no pattern check is performed
* @maxblocks: maximum number of blocks to search for a bbt. This number of
- * blocks is reserved at the end of the device where the tables are
+ * blocks is reserved at the end of the device where the tables are
* written.
* @reserved_block_code: if non-0, this pattern denotes a reserved (rather than
* bad) block in the stored bbt
- * @pattern: pattern to identify bad block table or factory marked good /
+ * @pattern: pattern to identify bad block table or factory marked good /
* bad blocks, can be NULL, if len = 0
*
- * Descriptor for the bad block table marker and the descriptor for the
+ * Descriptor for the bad block table marker and the descriptor for the
* pattern which identifies good and bad blocks. The assumption is made
* that the pattern and the version count are always located in the oob area
* of the first block.
diff --git a/include/linux/mtd/onenand.h b/include/linux/mtd/onenand.h
new file mode 100644
index 000000000000..f1fd4215686a
--- /dev/null
+++ b/include/linux/mtd/onenand.h
@@ -0,0 +1,155 @@
+/*
+ * linux/include/linux/mtd/onenand.h
+ *
+ * Copyright (C) 2005 Samsung Electronics
+ * Kyungmin Park <kyungmin.park@samsung.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 __LINUX_MTD_ONENAND_H
+#define __LINUX_MTD_ONENAND_H
+
+#include <linux/spinlock.h>
+#include <linux/mtd/onenand_regs.h>
+#include <linux/mtd/bbm.h>
+
+#define MAX_BUFFERRAM 2
+#define MAX_ONENAND_PAGESIZE (2048 + 64)
+
+/* Scan and identify a OneNAND device */
+extern int onenand_scan(struct mtd_info *mtd, int max_chips);
+/* Free resources held by the OneNAND device */
+extern void onenand_release(struct mtd_info *mtd);
+
+/**
+ * onenand_state_t - chip states
+ * Enumeration for OneNAND flash chip state
+ */
+typedef enum {
+ FL_READY,
+ FL_READING,
+ FL_WRITING,
+ FL_ERASING,
+ FL_SYNCING,
+ FL_UNLOCKING,
+ FL_LOCKING,
+ FL_PM_SUSPENDED,
+} onenand_state_t;
+
+/**
+ * struct onenand_bufferram - OneNAND BufferRAM Data
+ * @param block block address in BufferRAM
+ * @param page page address in BufferRAM
+ * @param valid valid flag
+ */
+struct onenand_bufferram {
+ int block;
+ int page;
+ int valid;
+};
+
+/**
+ * struct onenand_chip - OneNAND Private Flash Chip Data
+ * @param base [BOARDSPECIFIC] address to access OneNAND
+ * @param chipsize [INTERN] the size of one chip for multichip arrays
+ * @param device_id [INTERN] device ID
+ * @param verstion_id [INTERN] version ID
+ * @param options [BOARDSPECIFIC] various chip options. They can partly be set to inform onenand_scan about
+ * @param erase_shift [INTERN] number of address bits in a block
+ * @param page_shift [INTERN] number of address bits in a page
+ * @param ppb_shift [INTERN] number of address bits in a pages per block
+ * @param page_mask [INTERN] a page per block mask
+ * @param bufferam_index [INTERN] BufferRAM index
+ * @param bufferam [INTERN] BufferRAM info
+ * @param readw [REPLACEABLE] hardware specific function for read short
+ * @param writew [REPLACEABLE] hardware specific function for write short
+ * @param command [REPLACEABLE] hardware specific function for writing commands to the chip
+ * @param wait [REPLACEABLE] hardware specific function for wait on ready
+ * @param read_bufferram [REPLACEABLE] hardware specific function for BufferRAM Area
+ * @param write_bufferram [REPLACEABLE] hardware specific function for BufferRAM Area
+ * @param read_word [REPLACEABLE] hardware specific function for read register of OneNAND
+ * @param write_word [REPLACEABLE] hardware specific function for write register of OneNAND
+ * @param scan_bbt [REPLACEALBE] hardware specific function for scaning Bad block Table
+ * @param chip_lock [INTERN] spinlock used to protect access to this structure and the chip
+ * @param wq [INTERN] wait queue to sleep on if a OneNAND operation is in progress
+ * @param state [INTERN] the current state of the OneNAND device
+ * @param autooob [REPLACEABLE] the default (auto)placement scheme
+ * @param bbm [REPLACEABLE] pointer to Bad Block Management
+ * @param priv [OPTIONAL] pointer to private chip date
+ */
+struct onenand_chip {
+ void __iomem *base;
+ unsigned int chipsize;
+ unsigned int device_id;
+ unsigned int density_mask;
+ unsigned int options;
+
+ unsigned int erase_shift;
+ unsigned int page_shift;
+ unsigned int ppb_shift; /* Pages per block shift */
+ unsigned int page_mask;
+
+ unsigned int bufferram_index;
+ struct onenand_bufferram bufferram[MAX_BUFFERRAM];
+
+ int (*command)(struct mtd_info *mtd, int cmd, loff_t address, size_t len);
+ int (*wait)(struct mtd_info *mtd, int state);
+ int (*read_bufferram)(struct mtd_info *mtd, int area,
+ unsigned char *buffer, int offset, size_t count);
+ int (*write_bufferram)(struct mtd_info *mtd, int area,
+ const unsigned char *buffer, int offset, size_t count);
+ unsigned short (*read_word)(void __iomem *addr);
+ void (*write_word)(unsigned short value, void __iomem *addr);
+ void (*mmcontrol)(struct mtd_info *mtd, int sync_read);
+ int (*block_markbad)(struct mtd_info *mtd, loff_t ofs);
+ int (*scan_bbt)(struct mtd_info *mtd);
+
+ spinlock_t chip_lock;
+ wait_queue_head_t wq;
+ onenand_state_t state;
+
+ struct nand_oobinfo *autooob;
+
+ void *bbm;
+
+ void *priv;
+};
+
+/*
+ * Helper macros
+ */
+#define ONENAND_CURRENT_BUFFERRAM(this) (this->bufferram_index)
+#define ONENAND_NEXT_BUFFERRAM(this) (this->bufferram_index ^ 1)
+#define ONENAND_SET_NEXT_BUFFERRAM(this) (this->bufferram_index ^= 1)
+
+#define ONENAND_GET_SYS_CFG1(this) \
+ (this->read_word(this->base + ONENAND_REG_SYS_CFG1))
+#define ONENAND_SET_SYS_CFG1(v, this) \
+ (this->write_word(v, this->base + ONENAND_REG_SYS_CFG1))
+
+/*
+ * Options bits
+ */
+#define ONENAND_CONT_LOCK (0x0001)
+
+
+/*
+ * OneNAND Flash Manufacturer ID Codes
+ */
+#define ONENAND_MFR_SAMSUNG 0xec
+#define ONENAND_MFR_UNKNOWN 0x00
+
+/**
+ * struct nand_manufacturers - NAND Flash Manufacturer ID Structure
+ * @param name: Manufacturer name
+ * @param id: manufacturer ID code of device.
+*/
+struct onenand_manufacturers {
+ int id;
+ char *name;
+};
+
+#endif /* __LINUX_MTD_ONENAND_H */
diff --git a/include/linux/mtd/onenand_regs.h b/include/linux/mtd/onenand_regs.h
new file mode 100644
index 000000000000..d7832ef8ed63
--- /dev/null
+++ b/include/linux/mtd/onenand_regs.h
@@ -0,0 +1,180 @@
+/*
+ * linux/include/linux/mtd/onenand_regs.h
+ *
+ * OneNAND Register header file
+ *
+ * Copyright (C) 2005 Samsung Electronics
+ *
+ * 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 __ONENAND_REG_H
+#define __ONENAND_REG_H
+
+/* Memory Address Map Translation (Word order) */
+#define ONENAND_MEMORY_MAP(x) ((x) << 1)
+
+/*
+ * External BufferRAM area
+ */
+#define ONENAND_BOOTRAM ONENAND_MEMORY_MAP(0x0000)
+#define ONENAND_DATARAM ONENAND_MEMORY_MAP(0x0200)
+#define ONENAND_SPARERAM ONENAND_MEMORY_MAP(0x8010)
+
+/*
+ * OneNAND Registers
+ */
+#define ONENAND_REG_MANUFACTURER_ID ONENAND_MEMORY_MAP(0xF000)
+#define ONENAND_REG_DEVICE_ID ONENAND_MEMORY_MAP(0xF001)
+#define ONENAND_REG_VERSION_ID ONENAND_MEMORY_MAP(0xF002)
+#define ONENAND_REG_DATA_BUFFER_SIZE ONENAND_MEMORY_MAP(0xF003)
+#define ONENAND_REG_BOOT_BUFFER_SIZE ONENAND_MEMORY_MAP(0xF004)
+#define ONENAND_REG_NUM_BUFFERS ONENAND_MEMORY_MAP(0xF005)
+#define ONENAND_REG_TECHNOLOGY ONENAND_MEMORY_MAP(0xF006)
+
+#define ONENAND_REG_START_ADDRESS1 ONENAND_MEMORY_MAP(0xF100)
+#define ONENAND_REG_START_ADDRESS2 ONENAND_MEMORY_MAP(0xF101)
+#define ONENAND_REG_START_ADDRESS3 ONENAND_MEMORY_MAP(0xF102)
+#define ONENAND_REG_START_ADDRESS4 ONENAND_MEMORY_MAP(0xF103)
+#define ONENAND_REG_START_ADDRESS5 ONENAND_MEMORY_MAP(0xF104)
+#define ONENAND_REG_START_ADDRESS6 ONENAND_MEMORY_MAP(0xF105)
+#define ONENAND_REG_START_ADDRESS7 ONENAND_MEMORY_MAP(0xF106)
+#define ONENAND_REG_START_ADDRESS8 ONENAND_MEMORY_MAP(0xF107)
+
+#define ONENAND_REG_START_BUFFER ONENAND_MEMORY_MAP(0xF200)
+#define ONENAND_REG_COMMAND ONENAND_MEMORY_MAP(0xF220)
+#define ONENAND_REG_SYS_CFG1 ONENAND_MEMORY_MAP(0xF221)
+#define ONENAND_REG_SYS_CFG2 ONENAND_MEMORY_MAP(0xF222)
+#define ONENAND_REG_CTRL_STATUS ONENAND_MEMORY_MAP(0xF240)
+#define ONENAND_REG_INTERRUPT ONENAND_MEMORY_MAP(0xF241)
+#define ONENAND_REG_START_BLOCK_ADDRESS ONENAND_MEMORY_MAP(0xF24C)
+#define ONENAND_REG_END_BLOCK_ADDRESS ONENAND_MEMORY_MAP(0xF24D)
+#define ONENAND_REG_WP_STATUS ONENAND_MEMORY_MAP(0xF24E)
+
+#define ONENAND_REG_ECC_STATUS ONENAND_MEMORY_MAP(0xFF00)
+#define ONENAND_REG_ECC_M0 ONENAND_MEMORY_MAP(0xFF01)
+#define ONENAND_REG_ECC_S0 ONENAND_MEMORY_MAP(0xFF02)
+#define ONENAND_REG_ECC_M1 ONENAND_MEMORY_MAP(0xFF03)
+#define ONENAND_REG_ECC_S1 ONENAND_MEMORY_MAP(0xFF04)
+#define ONENAND_REG_ECC_M2 ONENAND_MEMORY_MAP(0xFF05)
+#define ONENAND_REG_ECC_S2 ONENAND_MEMORY_MAP(0xFF06)
+#define ONENAND_REG_ECC_M3 ONENAND_MEMORY_MAP(0xFF07)
+#define ONENAND_REG_ECC_S3 ONENAND_MEMORY_MAP(0xFF08)
+
+/*
+ * Device ID Register F001h (R)
+ */
+#define ONENAND_DEVICE_DENSITY_SHIFT (4)
+#define ONENAND_DEVICE_IS_DDP (1 << 3)
+#define ONENAND_DEVICE_IS_DEMUX (1 << 2)
+#define ONENAND_DEVICE_VCC_MASK (0x3)
+
+#define ONENAND_DEVICE_DENSITY_512Mb (0x002)
+
+/*
+ * Version ID Register F002h (R)
+ */
+#define ONENAND_VERSION_PROCESS_SHIFT (8)
+
+/*
+ * Start Address 1 F100h (R/W)
+ */
+#define ONENAND_DDP_SHIFT (15)
+
+/*
+ * Start Address 8 F107h (R/W)
+ */
+#define ONENAND_FPA_MASK (0x3f)
+#define ONENAND_FPA_SHIFT (2)
+#define ONENAND_FSA_MASK (0x03)
+
+/*
+ * Start Buffer Register F200h (R/W)
+ */
+#define ONENAND_BSA_MASK (0x03)
+#define ONENAND_BSA_SHIFT (8)
+#define ONENAND_BSA_BOOTRAM (0 << 2)
+#define ONENAND_BSA_DATARAM0 (2 << 2)
+#define ONENAND_BSA_DATARAM1 (3 << 2)
+#define ONENAND_BSC_MASK (0x03)
+
+/*
+ * Command Register F220h (R/W)
+ */
+#define ONENAND_CMD_READ (0x00)
+#define ONENAND_CMD_READOOB (0x13)
+#define ONENAND_CMD_PROG (0x80)
+#define ONENAND_CMD_PROGOOB (0x1A)
+#define ONENAND_CMD_UNLOCK (0x23)
+#define ONENAND_CMD_LOCK (0x2A)
+#define ONENAND_CMD_LOCK_TIGHT (0x2C)
+#define ONENAND_CMD_ERASE (0x94)
+#define ONENAND_CMD_RESET (0xF0)
+#define ONENAND_CMD_READID (0x90)
+
+/* NOTE: Those are not *REAL* commands */
+#define ONENAND_CMD_BUFFERRAM (0x1978)
+
+/*
+ * System Configuration 1 Register F221h (R, R/W)
+ */
+#define ONENAND_SYS_CFG1_SYNC_READ (1 << 15)
+#define ONENAND_SYS_CFG1_BRL_7 (7 << 12)
+#define ONENAND_SYS_CFG1_BRL_6 (6 << 12)
+#define ONENAND_SYS_CFG1_BRL_5 (5 << 12)
+#define ONENAND_SYS_CFG1_BRL_4 (4 << 12)
+#define ONENAND_SYS_CFG1_BRL_3 (3 << 12)
+#define ONENAND_SYS_CFG1_BRL_10 (2 << 12)
+#define ONENAND_SYS_CFG1_BRL_9 (1 << 12)
+#define ONENAND_SYS_CFG1_BRL_8 (0 << 12)
+#define ONENAND_SYS_CFG1_BRL_SHIFT (12)
+#define ONENAND_SYS_CFG1_BL_32 (4 << 9)
+#define ONENAND_SYS_CFG1_BL_16 (3 << 9)
+#define ONENAND_SYS_CFG1_BL_8 (2 << 9)
+#define ONENAND_SYS_CFG1_BL_4 (1 << 9)
+#define ONENAND_SYS_CFG1_BL_CONT (0 << 9)
+#define ONENAND_SYS_CFG1_BL_SHIFT (9)
+#define ONENAND_SYS_CFG1_NO_ECC (1 << 8)
+#define ONENAND_SYS_CFG1_RDY (1 << 7)
+#define ONENAND_SYS_CFG1_INT (1 << 6)
+#define ONENAND_SYS_CFG1_IOBE (1 << 5)
+#define ONENAND_SYS_CFG1_RDY_CONF (1 << 4)
+
+/*
+ * Controller Status Register F240h (R)
+ */
+#define ONENAND_CTRL_ONGO (1 << 15)
+#define ONENAND_CTRL_LOCK (1 << 14)
+#define ONENAND_CTRL_LOAD (1 << 13)
+#define ONENAND_CTRL_PROGRAM (1 << 12)
+#define ONENAND_CTRL_ERASE (1 << 11)
+#define ONENAND_CTRL_ERROR (1 << 10)
+#define ONENAND_CTRL_RSTB (1 << 7)
+
+/*
+ * Interrupt Status Register F241h (R)
+ */
+#define ONENAND_INT_MASTER (1 << 15)
+#define ONENAND_INT_READ (1 << 7)
+#define ONENAND_INT_WRITE (1 << 6)
+#define ONENAND_INT_ERASE (1 << 5)
+#define ONENAND_INT_RESET (1 << 4)
+#define ONENAND_INT_CLEAR (0 << 0)
+
+/*
+ * NAND Flash Write Protection Status Register F24Eh (R)
+ */
+#define ONENAND_WP_US (1 << 2)
+#define ONENAND_WP_LS (1 << 1)
+#define ONENAND_WP_LTS (1 << 0)
+
+/*
+ * ECC Status Reigser FF00h (R)
+ */
+#define ONENAND_ECC_1BIT (1 << 0)
+#define ONENAND_ECC_2BIT (1 << 1)
+#define ONENAND_ECC_2BIT_ALL (0xAAAA)
+
+#endif /* __ONENAND_REG_H */
diff --git a/include/linux/mtd/partitions.h b/include/linux/mtd/partitions.h
index 50b2edfc8f11..b03f512d51b9 100644
--- a/include/linux/mtd/partitions.h
+++ b/include/linux/mtd/partitions.h
@@ -5,7 +5,7 @@
*
* This code is GPL
*
- * $Id: partitions.h,v 1.16 2004/11/16 18:34:40 dwmw2 Exp $
+ * $Id: partitions.h,v 1.17 2005/11/07 11:14:55 gleixner Exp $
*/
#ifndef MTD_PARTITIONS_H
@@ -16,25 +16,25 @@
/*
* Partition definition structure:
- *
+ *
* An array of struct partition is passed along with a MTD object to
* add_mtd_partitions() to create them.
*
* For each partition, these fields are available:
* name: string that will be used to label the partition's MTD device.
- * size: the partition size; if defined as MTDPART_SIZ_FULL, the partition
+ * size: the partition size; if defined as MTDPART_SIZ_FULL, the partition
* will extend to the end of the master MTD device.
- * offset: absolute starting position within the master MTD device; if
- * defined as MTDPART_OFS_APPEND, the partition will start where the
+ * offset: absolute starting position within the master MTD device; if
+ * defined as MTDPART_OFS_APPEND, the partition will start where the
* previous one ended; if MTDPART_OFS_NXTBLK, at the next erase block.
- * mask_flags: contains flags that have to be masked (removed) from the
+ * mask_flags: contains flags that have to be masked (removed) from the
* master MTD flag set for the corresponding MTD partition.
- * For example, to force a read-only partition, simply adding
+ * For example, to force a read-only partition, simply adding
* MTD_WRITEABLE to the mask_flags will do the trick.
*
- * Note: writeable partitions require their size and offset be
+ * Note: writeable partitions require their size and offset be
* erasesize aligned (e.g. use MTDPART_OFS_NEXTBLK).
- */
+ */
struct mtd_partition {
char *name; /* identifier string */
@@ -66,7 +66,7 @@ struct mtd_part_parser {
extern int register_mtd_parser(struct mtd_part_parser *parser);
extern int deregister_mtd_parser(struct mtd_part_parser *parser);
-extern int parse_mtd_partitions(struct mtd_info *master, const char **types,
+extern int parse_mtd_partitions(struct mtd_info *master, const char **types,
struct mtd_partition **pparts, unsigned long origin);
#define put_partition_parser(p) do { module_put((p)->owner); } while(0)
diff --git a/include/linux/mtd/physmap.h b/include/linux/mtd/physmap.h
index 05aa4970677f..c7b8bcdef013 100644
--- a/include/linux/mtd/physmap.h
+++ b/include/linux/mtd/physmap.h
@@ -1,8 +1,8 @@
/*
- * For boards with physically mapped flash and using
+ * For boards with physically mapped flash and using
* drivers/mtd/maps/physmap.c mapping driver.
*
- * $Id: physmap.h,v 1.3 2004/07/21 00:16:15 jwboyer Exp $
+ * $Id: physmap.h,v 1.4 2005/11/07 11:14:55 gleixner Exp $
*
* Copyright (C) 2003 MontaVista Software Inc.
* Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
@@ -18,7 +18,7 @@
#include <linux/config.h>
-#if defined(CONFIG_MTD_PHYSMAP)
+#if defined(CONFIG_MTD_PHYSMAP)
#include <linux/mtd/mtd.h>
#include <linux/mtd/map.h>
@@ -44,12 +44,12 @@ static inline void physmap_configure(unsigned long addr, unsigned long size, int
#if defined(CONFIG_MTD_PARTITIONS)
/*
- * Machines that wish to do flash partition may want to call this function in
- * their setup routine.
+ * Machines that wish to do flash partition may want to call this function in
+ * their setup routine.
*
* physmap_set_partitions(mypartitions, num_parts);
*
- * Note that one can always override this hard-coded partition with
+ * Note that one can always override this hard-coded partition with
* command line partition (you need to enable CONFIG_MTD_CMDLINE_PARTS).
*/
void physmap_set_partitions(struct mtd_partition *parts, int num_parts);
diff --git a/include/linux/mtd/pmc551.h b/include/linux/mtd/pmc551.h
index 113e3087f68a..a7f6d20ad407 100644
--- a/include/linux/mtd/pmc551.h
+++ b/include/linux/mtd/pmc551.h
@@ -1,5 +1,5 @@
/*
- * $Id: pmc551.h,v 1.5 2003/01/24 16:49:53 dwmw2 Exp $
+ * $Id: pmc551.h,v 1.6 2005/11/07 11:14:55 gleixner Exp $
*
* PMC551 PCI Mezzanine Ram Device
*
@@ -7,7 +7,7 @@
* Mark Ferrell
* Copyright 1999,2000 Nortel Networks
*
- * License:
+ * License:
* As part of this driver was derrived from the slram.c driver it falls
* under the same license, which is GNU General Public License v2
*/
@@ -17,7 +17,7 @@
#include <linux/mtd/mtd.h>
-#define PMC551_VERSION "$Id: pmc551.h,v 1.5 2003/01/24 16:49:53 dwmw2 Exp $\n"\
+#define PMC551_VERSION "$Id: pmc551.h,v 1.6 2005/11/07 11:14:55 gleixner Exp $\n"\
"Ramix PMC551 PCI Mezzanine Ram Driver. (C) 1999,2000 Nortel Networks.\n"
/*
@@ -30,7 +30,7 @@ struct mypriv {
u32 curr_map0;
u32 asize;
struct mtd_info *nextpmc551;
-};
+};
/*
* Function Prototypes
@@ -39,7 +39,7 @@ static int pmc551_erase(struct mtd_info *, struct erase_info *);
static void pmc551_unpoint(struct mtd_info *, u_char *, loff_t, size_t);
static int pmc551_point (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char **mtdbuf);
static int pmc551_read(struct mtd_info *, loff_t, size_t, size_t *, u_char *);
-static int pmc551_write(struct mtd_info *, loff_t, size_t, size_t *, const u_char *);
+static int pmc551_write(struct mtd_info *, loff_t, size_t, size_t *, const u_char *);
/*
@@ -50,7 +50,7 @@ static int pmc551_write(struct mtd_info *, loff_t, size_t, size_t *, const u_cha
#endif
#ifndef PCI_DEVICE_ID_V3_SEMI_V370PDC
-#define PCI_DEVICE_ID_V3_SEMI_V370PDC 0x0200
+#define PCI_DEVICE_ID_V3_SEMI_V370PDC 0x0200
#endif
diff --git a/include/linux/mtd/xip.h b/include/linux/mtd/xip.h
index 7b7deef6b180..220d50bb71cd 100644
--- a/include/linux/mtd/xip.h
+++ b/include/linux/mtd/xip.h
@@ -12,7 +12,7 @@
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
- * $Id: xip.h,v 1.2 2004/12/01 15:49:10 nico Exp $
+ * $Id: xip.h,v 1.5 2005/11/07 11:14:55 gleixner Exp $
*/
#ifndef __LINUX_MTD_XIP_H__
@@ -23,19 +23,19 @@
#ifdef CONFIG_MTD_XIP
/*
- * Function that are modifying the flash state away from array mode must
- * obviously not be running from flash. The __xipram is therefore marking
- * those functions so they get relocated to ram.
- */
-#define __xipram __attribute__ ((__section__ (".data")))
-
-/*
* We really don't want gcc to guess anything.
* We absolutely _need_ proper inlining.
*/
#include <linux/compiler.h>
/*
+ * Function that are modifying the flash state away from array mode must
+ * obviously not be running from flash. The __xipram is therefore marking
+ * those functions so they get relocated to ram.
+ */
+#define __xipram noinline __attribute__ ((__section__ (".data")))
+
+/*
* Each architecture has to provide the following macros. They must access
* the hardware directly and not rely on any other (XIP) functions since they
* won't be available when used (flash not in array mode).
@@ -60,9 +60,9 @@
* overflowing.
*
* xip_iprefetch()
- *
+ *
* Macro to fill instruction prefetch
- * e.g. a series of nops: asm volatile (".rep 8; nop; .endr");
+ * e.g. a series of nops: asm volatile (".rep 8; nop; .endr");
*/
#include <asm/mtd-xip.h>
diff --git a/include/linux/namei.h b/include/linux/namei.h
index 7db67b008cac..455660eafba9 100644
--- a/include/linux/namei.h
+++ b/include/linux/namei.h
@@ -8,6 +8,7 @@ struct vfsmount;
struct open_intent {
int flags;
int create_mode;
+ struct file *file;
};
enum { MAX_NESTED_LINKS = 5 };
@@ -65,8 +66,15 @@ extern int FASTCALL(link_path_walk(const char *, struct nameidata *));
extern void path_release(struct nameidata *);
extern void path_release_on_umount(struct nameidata *);
+extern int __user_path_lookup_open(const char __user *, unsigned lookup_flags, struct nameidata *nd, int open_flags);
+extern int path_lookup_open(const char *, 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);
+extern void release_open_intent(struct nameidata *);
+
extern struct dentry * lookup_one_len(const char *, struct dentry *, int);
-extern struct dentry * lookup_hash(struct qstr *, struct dentry *);
+extern struct dentry * lookup_hash(struct nameidata *);
extern int follow_down(struct vfsmount **, struct dentry **);
extern int follow_up(struct vfsmount **, struct dentry **);
diff --git a/include/linux/namespace.h b/include/linux/namespace.h
index 0e5a86f13b2f..6731977c4c13 100644
--- a/include/linux/namespace.h
+++ b/include/linux/namespace.h
@@ -9,7 +9,8 @@ struct namespace {
atomic_t count;
struct vfsmount * root;
struct list_head list;
- struct rw_semaphore sem;
+ wait_queue_head_t poll;
+ int event;
};
extern int copy_namespace(int, struct task_struct *);
diff --git a/include/linux/net.h b/include/linux/net.h
index 4e981585a89a..d6a41e6577f6 100644
--- a/include/linux/net.h
+++ b/include/linux/net.h
@@ -71,6 +71,7 @@ typedef enum {
* @SOCK_RAW: raw socket
* @SOCK_RDM: reliably-delivered message
* @SOCK_SEQPACKET: sequential packet socket
+ * @SOCK_DCCP: Datagram Congestion Control Protocol socket
* @SOCK_PACKET: linux specific way of getting packets at the dev level.
* For writing rarp and other similar things on the user level.
*
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 368e4c825ff1..936f8b76114e 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -308,6 +308,7 @@ struct net_device
#define NETIF_F_VLAN_CHALLENGED 1024 /* Device cannot handle VLAN packets */
#define NETIF_F_TSO 2048 /* Can offload TCP/IP segmentation */
#define NETIF_F_LLTX 4096 /* LockLess TX */
+#define NETIF_F_UFO 8192 /* Can offload UDP Large Send*/
struct net_device *next_sched;
@@ -873,11 +874,9 @@ static inline void netif_rx_complete(struct net_device *dev)
static inline void netif_poll_disable(struct net_device *dev)
{
- while (test_and_set_bit(__LINK_STATE_RX_SCHED, &dev->state)) {
+ while (test_and_set_bit(__LINK_STATE_RX_SCHED, &dev->state))
/* No hurry. */
- current->state = TASK_INTERRUPTIBLE;
- schedule_timeout(1);
- }
+ schedule_timeout_interruptible(1);
}
static inline void netif_poll_enable(struct net_device *dev)
@@ -928,6 +927,13 @@ extern int netdev_max_backlog;
extern int weight_p;
extern int netdev_set_master(struct net_device *dev, struct net_device *master);
extern int skb_checksum_help(struct sk_buff *skb, int inward);
+#ifdef CONFIG_BUG
+extern void netdev_rx_csum_fault(struct net_device *dev);
+#else
+static inline void netdev_rx_csum_fault(struct net_device *dev)
+{
+}
+#endif
/* rx skb timestamps */
extern void net_enable_timestamp(void);
extern void net_disable_timestamp(void);
diff --git a/include/linux/netfilter/nf_conntrack_common.h b/include/linux/netfilter/nf_conntrack_common.h
new file mode 100644
index 000000000000..6d39b518486b
--- /dev/null
+++ b/include/linux/netfilter/nf_conntrack_common.h
@@ -0,0 +1,159 @@
+#ifndef _NF_CONNTRACK_COMMON_H
+#define _NF_CONNTRACK_COMMON_H
+/* Connection state tracking for netfilter. This is separated from,
+ but required by, the NAT layer; it can also be used by an iptables
+ extension. */
+enum ip_conntrack_info
+{
+ /* Part of an established connection (either direction). */
+ IP_CT_ESTABLISHED,
+
+ /* Like NEW, but related to an existing connection, or ICMP error
+ (in either direction). */
+ IP_CT_RELATED,
+
+ /* Started a new connection to track (only
+ IP_CT_DIR_ORIGINAL); may be a retransmission. */
+ IP_CT_NEW,
+
+ /* >= this indicates reply direction */
+ IP_CT_IS_REPLY,
+
+ /* Number of distinct IP_CT types (no NEW in reply dirn). */
+ IP_CT_NUMBER = IP_CT_IS_REPLY * 2 - 1
+};
+
+/* Bitset representing status of connection. */
+enum ip_conntrack_status {
+ /* It's an expected connection: bit 0 set. This bit never changed */
+ IPS_EXPECTED_BIT = 0,
+ IPS_EXPECTED = (1 << IPS_EXPECTED_BIT),
+
+ /* We've seen packets both ways: bit 1 set. Can be set, not unset. */
+ IPS_SEEN_REPLY_BIT = 1,
+ IPS_SEEN_REPLY = (1 << IPS_SEEN_REPLY_BIT),
+
+ /* Conntrack should never be early-expired. */
+ IPS_ASSURED_BIT = 2,
+ IPS_ASSURED = (1 << IPS_ASSURED_BIT),
+
+ /* Connection is confirmed: originating packet has left box */
+ IPS_CONFIRMED_BIT = 3,
+ IPS_CONFIRMED = (1 << IPS_CONFIRMED_BIT),
+
+ /* Connection needs src nat in orig dir. This bit never changed. */
+ IPS_SRC_NAT_BIT = 4,
+ IPS_SRC_NAT = (1 << IPS_SRC_NAT_BIT),
+
+ /* Connection needs dst nat in orig dir. This bit never changed. */
+ IPS_DST_NAT_BIT = 5,
+ IPS_DST_NAT = (1 << IPS_DST_NAT_BIT),
+
+ /* Both together. */
+ IPS_NAT_MASK = (IPS_DST_NAT | IPS_SRC_NAT),
+
+ /* Connection needs TCP sequence adjusted. */
+ IPS_SEQ_ADJUST_BIT = 6,
+ IPS_SEQ_ADJUST = (1 << IPS_SEQ_ADJUST_BIT),
+
+ /* NAT initialization bits. */
+ IPS_SRC_NAT_DONE_BIT = 7,
+ IPS_SRC_NAT_DONE = (1 << IPS_SRC_NAT_DONE_BIT),
+
+ IPS_DST_NAT_DONE_BIT = 8,
+ IPS_DST_NAT_DONE = (1 << IPS_DST_NAT_DONE_BIT),
+
+ /* Both together */
+ IPS_NAT_DONE_MASK = (IPS_DST_NAT_DONE | IPS_SRC_NAT_DONE),
+
+ /* Connection is dying (removed from lists), can not be unset. */
+ IPS_DYING_BIT = 9,
+ IPS_DYING = (1 << IPS_DYING_BIT),
+};
+
+/* Connection tracking event bits */
+enum ip_conntrack_events
+{
+ /* New conntrack */
+ IPCT_NEW_BIT = 0,
+ IPCT_NEW = (1 << IPCT_NEW_BIT),
+
+ /* Expected connection */
+ IPCT_RELATED_BIT = 1,
+ IPCT_RELATED = (1 << IPCT_RELATED_BIT),
+
+ /* Destroyed conntrack */
+ IPCT_DESTROY_BIT = 2,
+ IPCT_DESTROY = (1 << IPCT_DESTROY_BIT),
+
+ /* Timer has been refreshed */
+ IPCT_REFRESH_BIT = 3,
+ IPCT_REFRESH = (1 << IPCT_REFRESH_BIT),
+
+ /* Status has changed */
+ IPCT_STATUS_BIT = 4,
+ IPCT_STATUS = (1 << IPCT_STATUS_BIT),
+
+ /* Update of protocol info */
+ IPCT_PROTOINFO_BIT = 5,
+ IPCT_PROTOINFO = (1 << IPCT_PROTOINFO_BIT),
+
+ /* Volatile protocol info */
+ IPCT_PROTOINFO_VOLATILE_BIT = 6,
+ IPCT_PROTOINFO_VOLATILE = (1 << IPCT_PROTOINFO_VOLATILE_BIT),
+
+ /* New helper for conntrack */
+ IPCT_HELPER_BIT = 7,
+ IPCT_HELPER = (1 << IPCT_HELPER_BIT),
+
+ /* Update of helper info */
+ IPCT_HELPINFO_BIT = 8,
+ IPCT_HELPINFO = (1 << IPCT_HELPINFO_BIT),
+
+ /* Volatile helper info */
+ IPCT_HELPINFO_VOLATILE_BIT = 9,
+ IPCT_HELPINFO_VOLATILE = (1 << IPCT_HELPINFO_VOLATILE_BIT),
+
+ /* NAT info */
+ IPCT_NATINFO_BIT = 10,
+ IPCT_NATINFO = (1 << IPCT_NATINFO_BIT),
+
+ /* Counter highest bit has been set */
+ IPCT_COUNTER_FILLING_BIT = 11,
+ IPCT_COUNTER_FILLING = (1 << IPCT_COUNTER_FILLING_BIT),
+};
+
+enum ip_conntrack_expect_events {
+ IPEXP_NEW_BIT = 0,
+ IPEXP_NEW = (1 << IPEXP_NEW_BIT),
+};
+
+#ifdef __KERNEL__
+struct ip_conntrack_counter
+{
+ u_int32_t packets;
+ u_int32_t bytes;
+};
+
+struct ip_conntrack_stat
+{
+ unsigned int searched;
+ unsigned int found;
+ unsigned int new;
+ unsigned int invalid;
+ unsigned int ignore;
+ unsigned int delete;
+ unsigned int delete_list;
+ unsigned int insert;
+ unsigned int insert_failed;
+ unsigned int drop;
+ unsigned int early_drop;
+ unsigned int error;
+ unsigned int expect_new;
+ unsigned int expect_create;
+ unsigned int expect_delete;
+};
+
+#endif /* __KERNEL__ */
+
+#endif /* _NF_CONNTRACK_COMMON_H */
diff --git a/include/linux/netfilter/nf_conntrack_ftp.h b/include/linux/netfilter/nf_conntrack_ftp.h
new file mode 100644
index 000000000000..ad4a41c9ce93
--- /dev/null
+++ b/include/linux/netfilter/nf_conntrack_ftp.h
@@ -0,0 +1,44 @@
+#ifndef _NF_CONNTRACK_FTP_H
+#define _NF_CONNTRACK_FTP_H
+/* FTP tracking. */
+
+/* This enum is exposed to userspace */
+enum ip_ct_ftp_type
+{
+ /* PORT command from client */
+ IP_CT_FTP_PORT,
+ /* PASV response from server */
+ IP_CT_FTP_PASV,
+ /* EPRT command from client */
+ IP_CT_FTP_EPRT,
+ /* EPSV response from server */
+ IP_CT_FTP_EPSV,
+};
+
+#ifdef __KERNEL__
+
+#define FTP_PORT 21
+
+#define NUM_SEQ_TO_REMEMBER 2
+/* This structure exists only once per master */
+struct ip_ct_ftp_master {
+ /* Valid seq positions for cmd matching after newline */
+ u_int32_t seq_aft_nl[IP_CT_DIR_MAX][NUM_SEQ_TO_REMEMBER];
+ /* 0 means seq_match_aft_nl not set */
+ int seq_aft_nl_num[IP_CT_DIR_MAX];
+};
+
+struct ip_conntrack_expect;
+
+/* For NAT to hook in when we find a packet which describes what other
+ * connection we should expect. */
+extern unsigned int (*ip_nat_ftp_hook)(struct sk_buff **pskb,
+ enum ip_conntrack_info ctinfo,
+ enum ip_ct_ftp_type type,
+ unsigned int matchoff,
+ unsigned int matchlen,
+ struct ip_conntrack_expect *exp,
+ u32 *seq);
+#endif /* __KERNEL__ */
+
+#endif /* _NF_CONNTRACK_FTP_H */
diff --git a/include/linux/netfilter/nf_conntrack_sctp.h b/include/linux/netfilter/nf_conntrack_sctp.h
new file mode 100644
index 000000000000..b8994d9fd1a9
--- /dev/null
+++ b/include/linux/netfilter/nf_conntrack_sctp.h
@@ -0,0 +1,27 @@
+#ifndef _NF_CONNTRACK_SCTP_H
+#define _NF_CONNTRACK_SCTP_H
+/* SCTP tracking. */
+
+#include <linux/netfilter/nf_conntrack_tuple_common.h>
+
+enum sctp_conntrack {
+ SCTP_CONNTRACK_NONE,
+ SCTP_CONNTRACK_CLOSED,
+ SCTP_CONNTRACK_COOKIE_WAIT,
+ SCTP_CONNTRACK_COOKIE_ECHOED,
+ SCTP_CONNTRACK_ESTABLISHED,
+ SCTP_CONNTRACK_SHUTDOWN_SENT,
+ SCTP_CONNTRACK_SHUTDOWN_RECD,
+ SCTP_CONNTRACK_SHUTDOWN_ACK_SENT,
+ SCTP_CONNTRACK_MAX
+};
+
+struct ip_ct_sctp
+{
+ enum sctp_conntrack state;
+
+ u_int32_t vtag[IP_CT_DIR_MAX];
+ u_int32_t ttag[IP_CT_DIR_MAX];
+};
+
+#endif /* _NF_CONNTRACK_SCTP_H */
diff --git a/include/linux/netfilter/nf_conntrack_tcp.h b/include/linux/netfilter/nf_conntrack_tcp.h
new file mode 100644
index 000000000000..b2feeffde384
--- /dev/null
+++ b/include/linux/netfilter/nf_conntrack_tcp.h
@@ -0,0 +1,56 @@
+#ifndef _NF_CONNTRACK_TCP_H
+#define _NF_CONNTRACK_TCP_H
+/* TCP tracking. */
+
+/* This is exposed to userspace (ctnetlink) */
+enum tcp_conntrack {
+ TCP_CONNTRACK_NONE,
+ TCP_CONNTRACK_SYN_SENT,
+ TCP_CONNTRACK_SYN_RECV,
+ TCP_CONNTRACK_ESTABLISHED,
+ TCP_CONNTRACK_FIN_WAIT,
+ TCP_CONNTRACK_CLOSE_WAIT,
+ TCP_CONNTRACK_LAST_ACK,
+ TCP_CONNTRACK_TIME_WAIT,
+ TCP_CONNTRACK_CLOSE,
+ TCP_CONNTRACK_LISTEN,
+ TCP_CONNTRACK_MAX,
+ TCP_CONNTRACK_IGNORE
+};
+
+/* Window scaling is advertised by the sender */
+#define IP_CT_TCP_FLAG_WINDOW_SCALE 0x01
+
+/* SACK is permitted by the sender */
+#define IP_CT_TCP_FLAG_SACK_PERM 0x02
+
+/* This sender sent FIN first */
+#define IP_CT_TCP_FLAG_CLOSE_INIT 0x03
+
+#ifdef __KERNEL__
+
+struct ip_ct_tcp_state {
+ u_int32_t td_end; /* max of seq + len */
+ u_int32_t td_maxend; /* max of ack + max(win, 1) */
+ u_int32_t td_maxwin; /* max(win) */
+ u_int8_t td_scale; /* window scale factor */
+ u_int8_t loose; /* used when connection picked up from the middle */
+ u_int8_t flags; /* per direction options */
+};
+
+struct ip_ct_tcp
+{
+ struct ip_ct_tcp_state seen[2]; /* connection parameters per direction */
+ u_int8_t state; /* state of the connection (enum tcp_conntrack) */
+ /* For detecting stale connections */
+ u_int8_t last_dir; /* Direction of the last packet (enum ip_conntrack_dir) */
+ u_int8_t retrans; /* Number of retransmitted packets */
+ u_int8_t last_index; /* Index of the last packet */
+ u_int32_t last_seq; /* Last sequence number seen in dir */
+ u_int32_t last_ack; /* Last sequence number seen in opposite dir */
+ u_int32_t last_end; /* Last seq + len */
+};
+
+#endif /* __KERNEL__ */
+
+#endif /* _NF_CONNTRACK_TCP_H */
diff --git a/include/linux/netfilter/nf_conntrack_tuple_common.h b/include/linux/netfilter/nf_conntrack_tuple_common.h
new file mode 100644
index 000000000000..8e145f0d61cb
--- /dev/null
+++ b/include/linux/netfilter/nf_conntrack_tuple_common.h
@@ -0,0 +1,13 @@
+#ifndef _NF_CONNTRACK_TUPLE_COMMON_H
+#define _NF_CONNTRACK_TUPLE_COMMON_H
+
+enum ip_conntrack_dir
+{
+ IP_CT_DIR_ORIGINAL,
+ IP_CT_DIR_REPLY,
+ IP_CT_DIR_MAX
+};
+
+#define CTINFO2DIR(ctinfo) ((ctinfo) >= IP_CT_IS_REPLY ? IP_CT_DIR_REPLY : IP_CT_DIR_ORIGINAL)
+
+#endif /* _NF_CONNTRACK_TUPLE_COMMON_H */
diff --git a/include/linux/netfilter/nfnetlink.h b/include/linux/netfilter/nfnetlink.h
index f08e870100f4..72975fa8795d 100644
--- a/include/linux/netfilter/nfnetlink.h
+++ b/include/linux/netfilter/nfnetlink.h
@@ -146,7 +146,7 @@ extern void nfnl_unlock(void);
extern int nfnetlink_subsys_register(struct nfnetlink_subsystem *n);
extern int nfnetlink_subsys_unregister(struct nfnetlink_subsystem *n);
-extern int nfattr_parse(struct nfattr *tb[], int maxattr,
+extern void nfattr_parse(struct nfattr *tb[], int maxattr,
struct nfattr *nfa, int len);
#define nfattr_parse_nested(tb, max, nfa) \
diff --git a/include/linux/netfilter_arp/arp_tables.h b/include/linux/netfilter_arp/arp_tables.h
index d759a637bded..e98a870a20be 100644
--- a/include/linux/netfilter_arp/arp_tables.h
+++ b/include/linux/netfilter_arp/arp_tables.h
@@ -68,7 +68,8 @@ struct arpt_entry_target
u_int16_t target_size;
/* Used by userspace */
- char name[ARPT_FUNCTION_MAXNAMELEN];
+ char name[ARPT_FUNCTION_MAXNAMELEN-1];
+ u_int8_t revision;
} user;
struct {
u_int16_t target_size;
@@ -148,7 +149,9 @@ struct arpt_entry
#define ARPT_SO_GET_INFO (ARPT_BASE_CTL)
#define ARPT_SO_GET_ENTRIES (ARPT_BASE_CTL + 1)
-#define ARPT_SO_GET_MAX ARPT_SO_GET_ENTRIES
+/* #define ARPT_SO_GET_REVISION_MATCH (ARPT_BASE_CTL + 2)*/
+#define ARPT_SO_GET_REVISION_TARGET (ARPT_BASE_CTL + 3)
+#define ARPT_SO_GET_MAX ARPT_SO_GET_REVISION_TARGET
/* CONTINUE verdict for targets */
#define ARPT_CONTINUE 0xFFFFFFFF
@@ -236,6 +239,15 @@ struct arpt_get_entries
struct arpt_entry entrytable[0];
};
+/* The argument to ARPT_SO_GET_REVISION_*. Returns highest revision
+ * kernel supports, if >= revision. */
+struct arpt_get_revision
+{
+ char name[ARPT_FUNCTION_MAXNAMELEN-1];
+
+ u_int8_t revision;
+};
+
/* Standard return verdict, or do jump. */
#define ARPT_STANDARD_TARGET ""
/* Error verdict. */
@@ -274,7 +286,9 @@ struct arpt_target
{
struct list_head list;
- const char name[ARPT_FUNCTION_MAXNAMELEN];
+ const char name[ARPT_FUNCTION_MAXNAMELEN-1];
+
+ u_int8_t revision;
/* Returns verdict. */
unsigned int (*target)(struct sk_buff **pskb,
diff --git a/include/linux/netfilter_ipv4/ip_conntrack.h b/include/linux/netfilter_ipv4/ip_conntrack.h
index d078bb91d9e5..b3432ab59a17 100644
--- a/include/linux/netfilter_ipv4/ip_conntrack.h
+++ b/include/linux/netfilter_ipv4/ip_conntrack.h
@@ -1,132 +1,7 @@
#ifndef _IP_CONNTRACK_H
#define _IP_CONNTRACK_H
-/* Connection state tracking for netfilter. This is separated from,
- but required by, the NAT layer; it can also be used by an iptables
- extension. */
-enum ip_conntrack_info
-{
- /* Part of an established connection (either direction). */
- IP_CT_ESTABLISHED,
-
- /* Like NEW, but related to an existing connection, or ICMP error
- (in either direction). */
- IP_CT_RELATED,
-
- /* Started a new connection to track (only
- IP_CT_DIR_ORIGINAL); may be a retransmission. */
- IP_CT_NEW,
-
- /* >= this indicates reply direction */
- IP_CT_IS_REPLY,
-
- /* Number of distinct IP_CT types (no NEW in reply dirn). */
- IP_CT_NUMBER = IP_CT_IS_REPLY * 2 - 1
-};
-
-/* Bitset representing status of connection. */
-enum ip_conntrack_status {
- /* It's an expected connection: bit 0 set. This bit never changed */
- IPS_EXPECTED_BIT = 0,
- IPS_EXPECTED = (1 << IPS_EXPECTED_BIT),
-
- /* We've seen packets both ways: bit 1 set. Can be set, not unset. */
- IPS_SEEN_REPLY_BIT = 1,
- IPS_SEEN_REPLY = (1 << IPS_SEEN_REPLY_BIT),
-
- /* Conntrack should never be early-expired. */
- IPS_ASSURED_BIT = 2,
- IPS_ASSURED = (1 << IPS_ASSURED_BIT),
-
- /* Connection is confirmed: originating packet has left box */
- IPS_CONFIRMED_BIT = 3,
- IPS_CONFIRMED = (1 << IPS_CONFIRMED_BIT),
-
- /* Connection needs src nat in orig dir. This bit never changed. */
- IPS_SRC_NAT_BIT = 4,
- IPS_SRC_NAT = (1 << IPS_SRC_NAT_BIT),
-
- /* Connection needs dst nat in orig dir. This bit never changed. */
- IPS_DST_NAT_BIT = 5,
- IPS_DST_NAT = (1 << IPS_DST_NAT_BIT),
-
- /* Both together. */
- IPS_NAT_MASK = (IPS_DST_NAT | IPS_SRC_NAT),
-
- /* Connection needs TCP sequence adjusted. */
- IPS_SEQ_ADJUST_BIT = 6,
- IPS_SEQ_ADJUST = (1 << IPS_SEQ_ADJUST_BIT),
-
- /* NAT initialization bits. */
- IPS_SRC_NAT_DONE_BIT = 7,
- IPS_SRC_NAT_DONE = (1 << IPS_SRC_NAT_DONE_BIT),
-
- IPS_DST_NAT_DONE_BIT = 8,
- IPS_DST_NAT_DONE = (1 << IPS_DST_NAT_DONE_BIT),
-
- /* Both together */
- IPS_NAT_DONE_MASK = (IPS_DST_NAT_DONE | IPS_SRC_NAT_DONE),
-
- /* Connection is dying (removed from lists), can not be unset. */
- IPS_DYING_BIT = 9,
- IPS_DYING = (1 << IPS_DYING_BIT),
-};
-
-/* Connection tracking event bits */
-enum ip_conntrack_events
-{
- /* New conntrack */
- IPCT_NEW_BIT = 0,
- IPCT_NEW = (1 << IPCT_NEW_BIT),
-
- /* Expected connection */
- IPCT_RELATED_BIT = 1,
- IPCT_RELATED = (1 << IPCT_RELATED_BIT),
-
- /* Destroyed conntrack */
- IPCT_DESTROY_BIT = 2,
- IPCT_DESTROY = (1 << IPCT_DESTROY_BIT),
-
- /* Timer has been refreshed */
- IPCT_REFRESH_BIT = 3,
- IPCT_REFRESH = (1 << IPCT_REFRESH_BIT),
-
- /* Status has changed */
- IPCT_STATUS_BIT = 4,
- IPCT_STATUS = (1 << IPCT_STATUS_BIT),
-
- /* Update of protocol info */
- IPCT_PROTOINFO_BIT = 5,
- IPCT_PROTOINFO = (1 << IPCT_PROTOINFO_BIT),
-
- /* Volatile protocol info */
- IPCT_PROTOINFO_VOLATILE_BIT = 6,
- IPCT_PROTOINFO_VOLATILE = (1 << IPCT_PROTOINFO_VOLATILE_BIT),
-
- /* New helper for conntrack */
- IPCT_HELPER_BIT = 7,
- IPCT_HELPER = (1 << IPCT_HELPER_BIT),
-
- /* Update of helper info */
- IPCT_HELPINFO_BIT = 8,
- IPCT_HELPINFO = (1 << IPCT_HELPINFO_BIT),
-
- /* Volatile helper info */
- IPCT_HELPINFO_VOLATILE_BIT = 9,
- IPCT_HELPINFO_VOLATILE = (1 << IPCT_HELPINFO_VOLATILE_BIT),
- /* NAT info */
- IPCT_NATINFO_BIT = 10,
- IPCT_NATINFO = (1 << IPCT_NATINFO_BIT),
-
- /* Counter highest bit has been set */
- IPCT_COUNTER_FILLING_BIT = 11,
- IPCT_COUNTER_FILLING = (1 << IPCT_COUNTER_FILLING_BIT),
-};
-
-enum ip_conntrack_expect_events {
- IPEXP_NEW_BIT = 0,
- IPEXP_NEW = (1 << IPEXP_NEW_BIT),
-};
+#include <linux/netfilter/nf_conntrack_common.h>
#ifdef __KERNEL__
#include <linux/config.h>
@@ -194,12 +69,6 @@ do { \
#define IP_NF_ASSERT(x)
#endif
-struct ip_conntrack_counter
-{
- u_int32_t packets;
- u_int32_t bytes;
-};
-
struct ip_conntrack_helper;
struct ip_conntrack
@@ -426,25 +295,6 @@ static inline int is_dying(struct ip_conntrack *ct)
extern unsigned int ip_conntrack_htable_size;
-struct ip_conntrack_stat
-{
- unsigned int searched;
- unsigned int found;
- unsigned int new;
- unsigned int invalid;
- unsigned int ignore;
- unsigned int delete;
- unsigned int delete_list;
- unsigned int insert;
- unsigned int insert_failed;
- unsigned int drop;
- unsigned int early_drop;
- unsigned int error;
- unsigned int expect_new;
- unsigned int expect_create;
- unsigned int expect_delete;
-};
-
#define CONNTRACK_STAT_INC(count) (__get_cpu_var(ip_conntrack_stat).count++)
#ifdef CONFIG_IP_NF_CONNTRACK_EVENTS
diff --git a/include/linux/netfilter_ipv4/ip_conntrack_ftp.h b/include/linux/netfilter_ipv4/ip_conntrack_ftp.h
index 5f06429b9047..63811934de4d 100644
--- a/include/linux/netfilter_ipv4/ip_conntrack_ftp.h
+++ b/include/linux/netfilter_ipv4/ip_conntrack_ftp.h
@@ -1,43 +1,6 @@
#ifndef _IP_CONNTRACK_FTP_H
#define _IP_CONNTRACK_FTP_H
-/* FTP tracking. */
-#ifdef __KERNEL__
+#include <linux/netfilter/nf_conntrack_ftp.h>
-#define FTP_PORT 21
-
-#endif /* __KERNEL__ */
-
-enum ip_ct_ftp_type
-{
- /* PORT command from client */
- IP_CT_FTP_PORT,
- /* PASV response from server */
- IP_CT_FTP_PASV,
- /* EPRT command from client */
- IP_CT_FTP_EPRT,
- /* EPSV response from server */
- IP_CT_FTP_EPSV,
-};
-
-#define NUM_SEQ_TO_REMEMBER 2
-/* This structure exists only once per master */
-struct ip_ct_ftp_master {
- /* Valid seq positions for cmd matching after newline */
- u_int32_t seq_aft_nl[IP_CT_DIR_MAX][NUM_SEQ_TO_REMEMBER];
- /* 0 means seq_match_aft_nl not set */
- int seq_aft_nl_num[IP_CT_DIR_MAX];
-};
-
-struct ip_conntrack_expect;
-
-/* For NAT to hook in when we find a packet which describes what other
- * connection we should expect. */
-extern unsigned int (*ip_nat_ftp_hook)(struct sk_buff **pskb,
- enum ip_conntrack_info ctinfo,
- enum ip_ct_ftp_type type,
- unsigned int matchoff,
- unsigned int matchlen,
- struct ip_conntrack_expect *exp,
- u32 *seq);
#endif /* _IP_CONNTRACK_FTP_H */
diff --git a/include/linux/netfilter_ipv4/ip_conntrack_icmp.h b/include/linux/netfilter_ipv4/ip_conntrack_icmp.h
index f1664abbe392..eed5ee3e4744 100644
--- a/include/linux/netfilter_ipv4/ip_conntrack_icmp.h
+++ b/include/linux/netfilter_ipv4/ip_conntrack_icmp.h
@@ -1,11 +1,6 @@
#ifndef _IP_CONNTRACK_ICMP_H
#define _IP_CONNTRACK_ICMP_H
-/* ICMP tracking. */
-#include <asm/atomic.h>
-struct ip_ct_icmp
-{
- /* Optimization: when number in == number out, forget immediately. */
- atomic_t count;
-};
+#include <net/netfilter/ipv4/nf_conntrack_icmp.h>
+
#endif /* _IP_CONNTRACK_ICMP_H */
diff --git a/include/linux/netfilter_ipv4/ip_conntrack_sctp.h b/include/linux/netfilter_ipv4/ip_conntrack_sctp.h
index 7a8d869321f7..4099a041a32a 100644
--- a/include/linux/netfilter_ipv4/ip_conntrack_sctp.h
+++ b/include/linux/netfilter_ipv4/ip_conntrack_sctp.h
@@ -1,25 +1,6 @@
#ifndef _IP_CONNTRACK_SCTP_H
#define _IP_CONNTRACK_SCTP_H
-/* SCTP tracking. */
-enum sctp_conntrack {
- SCTP_CONNTRACK_NONE,
- SCTP_CONNTRACK_CLOSED,
- SCTP_CONNTRACK_COOKIE_WAIT,
- SCTP_CONNTRACK_COOKIE_ECHOED,
- SCTP_CONNTRACK_ESTABLISHED,
- SCTP_CONNTRACK_SHUTDOWN_SENT,
- SCTP_CONNTRACK_SHUTDOWN_RECD,
- SCTP_CONNTRACK_SHUTDOWN_ACK_SENT,
- SCTP_CONNTRACK_MAX
-};
-
-struct ip_ct_sctp
-{
- enum sctp_conntrack state;
-
- u_int32_t vtag[IP_CT_DIR_MAX];
- u_int32_t ttag[IP_CT_DIR_MAX];
-};
+#include <linux/netfilter/nf_conntrack_sctp.h>
#endif /* _IP_CONNTRACK_SCTP_H */
diff --git a/include/linux/netfilter_ipv4/ip_conntrack_tcp.h b/include/linux/netfilter_ipv4/ip_conntrack_tcp.h
index 16da044d97a7..876b8fb17e68 100644
--- a/include/linux/netfilter_ipv4/ip_conntrack_tcp.h
+++ b/include/linux/netfilter_ipv4/ip_conntrack_tcp.h
@@ -1,51 +1,6 @@
#ifndef _IP_CONNTRACK_TCP_H
#define _IP_CONNTRACK_TCP_H
-/* TCP tracking. */
-enum tcp_conntrack {
- TCP_CONNTRACK_NONE,
- TCP_CONNTRACK_SYN_SENT,
- TCP_CONNTRACK_SYN_RECV,
- TCP_CONNTRACK_ESTABLISHED,
- TCP_CONNTRACK_FIN_WAIT,
- TCP_CONNTRACK_CLOSE_WAIT,
- TCP_CONNTRACK_LAST_ACK,
- TCP_CONNTRACK_TIME_WAIT,
- TCP_CONNTRACK_CLOSE,
- TCP_CONNTRACK_LISTEN,
- TCP_CONNTRACK_MAX,
- TCP_CONNTRACK_IGNORE
-};
-
-/* Window scaling is advertised by the sender */
-#define IP_CT_TCP_FLAG_WINDOW_SCALE 0x01
-
-/* SACK is permitted by the sender */
-#define IP_CT_TCP_FLAG_SACK_PERM 0x02
-
-/* This sender sent FIN first */
-#define IP_CT_TCP_FLAG_CLOSE_INIT 0x03
-
-struct ip_ct_tcp_state {
- u_int32_t td_end; /* max of seq + len */
- u_int32_t td_maxend; /* max of ack + max(win, 1) */
- u_int32_t td_maxwin; /* max(win) */
- u_int8_t td_scale; /* window scale factor */
- u_int8_t loose; /* used when connection picked up from the middle */
- u_int8_t flags; /* per direction options */
-};
-
-struct ip_ct_tcp
-{
- struct ip_ct_tcp_state seen[2]; /* connection parameters per direction */
- u_int8_t state; /* state of the connection (enum tcp_conntrack) */
- /* For detecting stale connections */
- u_int8_t last_dir; /* Direction of the last packet (enum ip_conntrack_dir) */
- u_int8_t retrans; /* Number of retransmitted packets */
- u_int8_t last_index; /* Index of the last packet */
- u_int32_t last_seq; /* Last sequence number seen in dir */
- u_int32_t last_ack; /* Last sequence number seen in opposite dir */
- u_int32_t last_end; /* Last seq + len */
-};
+#include <linux/netfilter/nf_conntrack_tcp.h>
#endif /* _IP_CONNTRACK_TCP_H */
diff --git a/include/linux/netfilter_ipv4/ip_conntrack_tuple.h b/include/linux/netfilter_ipv4/ip_conntrack_tuple.h
index 3232db11a4e5..2fdabdb4c0ef 100644
--- a/include/linux/netfilter_ipv4/ip_conntrack_tuple.h
+++ b/include/linux/netfilter_ipv4/ip_conntrack_tuple.h
@@ -2,6 +2,7 @@
#define _IP_CONNTRACK_TUPLE_H
#include <linux/types.h>
+#include <linux/netfilter/nf_conntrack_tuple_common.h>
/* A `tuple' is a structure containing the information to uniquely
identify a connection. ie. if two packets have the same tuple, they
@@ -88,13 +89,6 @@ struct ip_conntrack_tuple
(tuple)->dst.u.all = 0; \
} while (0)
-enum ip_conntrack_dir
-{
- IP_CT_DIR_ORIGINAL,
- IP_CT_DIR_REPLY,
- IP_CT_DIR_MAX
-};
-
#ifdef __KERNEL__
#define DUMP_TUPLE(tp) \
@@ -103,8 +97,6 @@ DEBUGP("tuple %p: %u %u.%u.%u.%u:%hu -> %u.%u.%u.%u:%hu\n", \
NIPQUAD((tp)->src.ip), ntohs((tp)->src.u.all), \
NIPQUAD((tp)->dst.ip), ntohs((tp)->dst.u.all))
-#define CTINFO2DIR(ctinfo) ((ctinfo) >= IP_CT_IS_REPLY ? IP_CT_DIR_REPLY : IP_CT_DIR_ORIGINAL)
-
/* If we're the first tuple, it's the original dir. */
#define DIRECTION(h) ((enum ip_conntrack_dir)(h)->tuple.dst.dir)
diff --git a/include/linux/netfilter_ipv6.h b/include/linux/netfilter_ipv6.h
index edcc2c6eb5c7..53b2983f6278 100644
--- a/include/linux/netfilter_ipv6.h
+++ b/include/linux/netfilter_ipv6.h
@@ -59,6 +59,7 @@
enum nf_ip6_hook_priorities {
NF_IP6_PRI_FIRST = INT_MIN,
+ NF_IP6_PRI_CONNTRACK_DEFRAG = -400,
NF_IP6_PRI_SELINUX_FIRST = -225,
NF_IP6_PRI_CONNTRACK = -200,
NF_IP6_PRI_BRIDGE_SABOTAGE_FORWARD = -175,
diff --git a/include/linux/netfilter_ipv6/ip6_tables.h b/include/linux/netfilter_ipv6/ip6_tables.h
index 59f70b34e029..2efc046d9e94 100644
--- a/include/linux/netfilter_ipv6/ip6_tables.h
+++ b/include/linux/netfilter_ipv6/ip6_tables.h
@@ -57,7 +57,8 @@ struct ip6t_entry_match
u_int16_t match_size;
/* Used by userspace */
- char name[IP6T_FUNCTION_MAXNAMELEN];
+ char name[IP6T_FUNCTION_MAXNAMELEN-1];
+ u_int8_t revision;
} user;
struct {
u_int16_t match_size;
@@ -80,7 +81,8 @@ struct ip6t_entry_target
u_int16_t target_size;
/* Used by userspace */
- char name[IP6T_FUNCTION_MAXNAMELEN];
+ char name[IP6T_FUNCTION_MAXNAMELEN-1];
+ u_int8_t revision;
} user;
struct {
u_int16_t target_size;
@@ -161,7 +163,9 @@ struct ip6t_entry
#define IP6T_SO_GET_INFO (IP6T_BASE_CTL)
#define IP6T_SO_GET_ENTRIES (IP6T_BASE_CTL + 1)
-#define IP6T_SO_GET_MAX IP6T_SO_GET_ENTRIES
+#define IP6T_SO_GET_REVISION_MATCH (IP6T_BASE_CTL + 2)
+#define IP6T_SO_GET_REVISION_TARGET (IP6T_BASE_CTL + 3)
+#define IP6T_SO_GET_MAX IP6T_SO_GET_REVISION_TARGET
/* CONTINUE verdict for targets */
#define IP6T_CONTINUE 0xFFFFFFFF
@@ -291,6 +295,15 @@ struct ip6t_get_entries
struct ip6t_entry entrytable[0];
};
+/* The argument to IP6T_SO_GET_REVISION_*. Returns highest revision
+ * kernel supports, if >= revision. */
+struct ip6t_get_revision
+{
+ char name[IP6T_FUNCTION_MAXNAMELEN-1];
+
+ u_int8_t revision;
+};
+
/* Standard return verdict, or do jump. */
#define IP6T_STANDARD_TARGET ""
/* Error verdict. */
@@ -352,7 +365,9 @@ struct ip6t_match
{
struct list_head list;
- const char name[IP6T_FUNCTION_MAXNAMELEN];
+ const char name[IP6T_FUNCTION_MAXNAMELEN-1];
+
+ u_int8_t revision;
/* Return true or false: return FALSE and set *hotdrop = 1 to
force immediate packet drop. */
@@ -387,7 +402,9 @@ struct ip6t_target
{
struct list_head list;
- const char name[IP6T_FUNCTION_MAXNAMELEN];
+ const char name[IP6T_FUNCTION_MAXNAMELEN-1];
+
+ u_int8_t revision;
/* Returns verdict. Argument order changed since 2.6.9, as this
must now handle non-linear skbs, using skb_copy_bits and
diff --git a/include/linux/netlink.h b/include/linux/netlink.h
index ba25ca874c20..6a2ccf78a356 100644
--- a/include/linux/netlink.h
+++ b/include/linux/netlink.h
@@ -71,7 +71,8 @@ struct nlmsghdr
#define NLMSG_ALIGNTO 4
#define NLMSG_ALIGN(len) ( ((len)+NLMSG_ALIGNTO-1) & ~(NLMSG_ALIGNTO-1) )
-#define NLMSG_LENGTH(len) ((len)+NLMSG_ALIGN(sizeof(struct nlmsghdr)))
+#define NLMSG_HDRLEN ((int) NLMSG_ALIGN(sizeof(struct nlmsghdr)))
+#define NLMSG_LENGTH(len) ((len)+NLMSG_ALIGN(NLMSG_HDRLEN))
#define NLMSG_SPACE(len) NLMSG_ALIGN(NLMSG_LENGTH(len))
#define NLMSG_DATA(nlh) ((void*)(((char*)nlh) + NLMSG_LENGTH(0)))
#define NLMSG_NEXT(nlh,len) ((len) -= NLMSG_ALIGN((nlh)->nlmsg_len), \
@@ -86,6 +87,8 @@ struct nlmsghdr
#define NLMSG_DONE 0x3 /* End of a dump */
#define NLMSG_OVERRUN 0x4 /* Data lost */
+#define NLMSG_MIN_TYPE 0x10 /* < 0x10: reserved control messages */
+
struct nlmsgerr
{
int error;
@@ -108,6 +111,25 @@ enum {
NETLINK_CONNECTED,
};
+/*
+ * <------- NLA_HDRLEN ------> <-- NLA_ALIGN(payload)-->
+ * +---------------------+- - -+- - - - - - - - - -+- - -+
+ * | Header | Pad | Payload | Pad |
+ * | (struct nlattr) | ing | | ing |
+ * +---------------------+- - -+- - - - - - - - - -+- - -+
+ * <-------------- nlattr->nla_len -------------->
+ */
+
+struct nlattr
+{
+ __u16 nla_len;
+ __u16 nla_type;
+};
+
+#define NLA_ALIGNTO 4
+#define NLA_ALIGN(len) (((len) + NLA_ALIGNTO - 1) & ~(NLA_ALIGNTO - 1))
+#define NLA_HDRLEN ((int) NLA_ALIGN(sizeof(struct nlattr)))
+
#ifdef __KERNEL__
#include <linux/capability.h>
diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h
index 9a6047ff1b25..12787a9b0259 100644
--- a/include/linux/nfs_fs.h
+++ b/include/linux/nfs_fs.h
@@ -41,6 +41,10 @@
#define NFS_MAX_FILE_IO_BUFFER_SIZE 32768
#define NFS_DEF_FILE_IO_BUFFER_SIZE 4096
+/* Default timeout values */
+#define NFS_MAX_UDP_TIMEOUT (60*HZ)
+#define NFS_MAX_TCP_TIMEOUT (600*HZ)
+
/*
* superblock magic number for NFS
*/
@@ -137,6 +141,7 @@ struct nfs_inode {
unsigned long attrtimeo_timestamp;
__u64 change_attr; /* v4 only */
+ unsigned long last_updated;
/* "Generation counter" for the attribute cache. This is
* bumped whenever we update the metadata on the
* server.
@@ -236,13 +241,17 @@ static inline int nfs_caches_unstable(struct inode *inode)
return atomic_read(&NFS_I(inode)->data_updates) != 0;
}
+static inline void nfs_mark_for_revalidate(struct inode *inode)
+{
+ spin_lock(&inode->i_lock);
+ NFS_I(inode)->cache_validity |= NFS_INO_INVALID_ATTR | NFS_INO_INVALID_ACCESS;
+ spin_unlock(&inode->i_lock);
+}
+
static inline void NFS_CACHEINV(struct inode *inode)
{
- if (!nfs_caches_unstable(inode)) {
- spin_lock(&inode->i_lock);
- NFS_I(inode)->cache_validity |= NFS_INO_INVALID_ATTR | NFS_INO_INVALID_ACCESS;
- spin_unlock(&inode->i_lock);
- }
+ if (!nfs_caches_unstable(inode))
+ nfs_mark_for_revalidate(inode);
}
static inline int nfs_server_capable(struct inode *inode, int cap)
@@ -276,7 +285,7 @@ static inline long nfs_save_change_attribute(struct inode *inode)
static inline int nfs_verify_change_attribute(struct inode *inode, unsigned long chattr)
{
return !nfs_caches_unstable(inode)
- && chattr == NFS_I(inode)->cache_change_attribute;
+ && time_after_eq(chattr, NFS_I(inode)->cache_change_attribute);
}
/*
@@ -286,6 +295,7 @@ extern void nfs_zap_caches(struct inode *);
extern struct inode *nfs_fhget(struct super_block *, struct nfs_fh *,
struct nfs_fattr *);
extern int nfs_refresh_inode(struct inode *, struct nfs_fattr *);
+extern int nfs_post_op_update_inode(struct inode *inode, struct nfs_fattr *fattr);
extern int nfs_getattr(struct vfsmount *, struct dentry *, struct kstat *);
extern int nfs_permission(struct inode *, int, struct nameidata *);
extern int nfs_access_get_cached(struct inode *, struct rpc_cred *, struct nfs_access_entry *);
@@ -306,12 +316,18 @@ extern struct nfs_open_context *alloc_nfs_open_context(struct dentry *dentry, st
extern struct nfs_open_context *get_nfs_open_context(struct nfs_open_context *ctx);
extern void put_nfs_open_context(struct nfs_open_context *ctx);
extern void nfs_file_set_open_context(struct file *filp, struct nfs_open_context *ctx);
-extern struct nfs_open_context *nfs_find_open_context(struct inode *inode, int mode);
+extern struct nfs_open_context *nfs_find_open_context(struct inode *inode, struct rpc_cred *cred, int mode);
extern void nfs_file_clear_open_context(struct file *filp);
/* linux/net/ipv4/ipconfig.c: trims ip addr off front of name, too. */
extern u32 root_nfs_parse_addr(char *name); /*__init*/
+static inline void nfs_fattr_init(struct nfs_fattr *fattr)
+{
+ fattr->valid = 0;
+ fattr->time_start = jiffies;
+}
+
/*
* linux/fs/nfs/file.c
*/
diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h
index a2bf6914ff1b..40718669b9c8 100644
--- a/include/linux/nfs_xdr.h
+++ b/include/linux/nfs_xdr.h
@@ -41,7 +41,7 @@ struct nfs_fattr {
__u32 bitmap[2]; /* NFSv4 returned attribute bitmap */
__u64 change_attr; /* NFSv4 change attribute */
__u64 pre_change_attr;/* pre-op NFSv4 change attribute */
- unsigned long timestamp;
+ unsigned long time_start;
};
#define NFS_ATTR_WCC 0x0001 /* pre-op WCC data */
@@ -96,12 +96,13 @@ struct nfs4_change_info {
u64 after;
};
+struct nfs_seqid;
/*
* Arguments to the open call.
*/
struct nfs_openargs {
const struct nfs_fh * fh;
- __u32 seqid;
+ struct nfs_seqid * seqid;
int open_flags;
__u64 clientid;
__u32 id;
@@ -123,6 +124,7 @@ struct nfs_openres {
struct nfs4_change_info cinfo;
__u32 rflags;
struct nfs_fattr * f_attr;
+ struct nfs_fattr * dir_attr;
const struct nfs_server *server;
int delegation_type;
nfs4_stateid delegation;
@@ -136,7 +138,7 @@ struct nfs_openres {
struct nfs_open_confirmargs {
const struct nfs_fh * fh;
nfs4_stateid stateid;
- __u32 seqid;
+ struct nfs_seqid * seqid;
};
struct nfs_open_confirmres {
@@ -148,13 +150,16 @@ struct nfs_open_confirmres {
*/
struct nfs_closeargs {
struct nfs_fh * fh;
- nfs4_stateid stateid;
- __u32 seqid;
+ nfs4_stateid * stateid;
+ struct nfs_seqid * seqid;
int open_flags;
+ const u32 * bitmask;
};
struct nfs_closeres {
nfs4_stateid stateid;
+ struct nfs_fattr * fattr;
+ const struct nfs_server *server;
};
/*
* * Arguments to the lock,lockt, and locku call.
@@ -164,30 +169,19 @@ struct nfs_lowner {
u32 id;
};
-struct nfs_open_to_lock {
- __u32 open_seqid;
- nfs4_stateid open_stateid;
- __u32 lock_seqid;
- struct nfs_lowner lock_owner;
-};
-
-struct nfs_exist_lock {
- nfs4_stateid stateid;
- __u32 seqid;
-};
-
struct nfs_lock_opargs {
+ struct nfs_seqid * lock_seqid;
+ nfs4_stateid * lock_stateid;
+ struct nfs_seqid * open_seqid;
+ nfs4_stateid * open_stateid;
+ struct nfs_lowner lock_owner;
__u32 reclaim;
__u32 new_lock_owner;
- union {
- struct nfs_open_to_lock *open_lock;
- struct nfs_exist_lock *exist_lock;
- } u;
};
struct nfs_locku_opargs {
- __u32 seqid;
- nfs4_stateid stateid;
+ struct nfs_seqid * seqid;
+ nfs4_stateid * stateid;
};
struct nfs_lockargs {
@@ -262,6 +256,7 @@ struct nfs_writeargs {
enum nfs3_stable_how stable;
unsigned int pgbase;
struct page ** pages;
+ const u32 * bitmask;
};
struct nfs_writeverf {
@@ -273,6 +268,7 @@ struct nfs_writeres {
struct nfs_fattr * fattr;
struct nfs_writeverf * verf;
__u32 count;
+ const struct nfs_server *server;
};
/*
@@ -550,6 +546,7 @@ struct nfs4_create_res {
struct nfs_fh * fh;
struct nfs_fattr * fattr;
struct nfs4_change_info dir_cinfo;
+ struct nfs_fattr * dir_fattr;
};
struct nfs4_fsinfo_arg {
@@ -571,8 +568,17 @@ struct nfs4_link_arg {
const struct nfs_fh * fh;
const struct nfs_fh * dir_fh;
const struct qstr * name;
+ const u32 * bitmask;
+};
+
+struct nfs4_link_res {
+ const struct nfs_server * server;
+ struct nfs_fattr * fattr;
+ struct nfs4_change_info cinfo;
+ struct nfs_fattr * dir_attr;
};
+
struct nfs4_lookup_arg {
const struct nfs_fh * dir_fh;
const struct qstr * name;
@@ -619,6 +625,13 @@ struct nfs4_readlink {
struct nfs4_remove_arg {
const struct nfs_fh * fh;
const struct qstr * name;
+ const u32 * bitmask;
+};
+
+struct nfs4_remove_res {
+ const struct nfs_server * server;
+ struct nfs4_change_info cinfo;
+ struct nfs_fattr * dir_attr;
};
struct nfs4_rename_arg {
@@ -626,11 +639,15 @@ struct nfs4_rename_arg {
const struct nfs_fh * new_dir;
const struct qstr * old_name;
const struct qstr * new_name;
+ const u32 * bitmask;
};
struct nfs4_rename_res {
+ const struct nfs_server * server;
struct nfs4_change_info old_cinfo;
+ struct nfs_fattr * old_fattr;
struct nfs4_change_info new_cinfo;
+ struct nfs_fattr * new_fattr;
};
struct nfs4_setclientid {
@@ -722,7 +739,7 @@ struct nfs_rpc_ops {
int (*write) (struct nfs_write_data *);
int (*commit) (struct nfs_write_data *);
int (*create) (struct inode *, struct dentry *,
- struct iattr *, int);
+ struct iattr *, int, struct nameidata *);
int (*remove) (struct inode *, struct qstr *);
int (*unlink_setup) (struct rpc_message *,
struct dentry *, struct qstr *);
diff --git a/include/linux/nfsd/nfsd.h b/include/linux/nfsd/nfsd.h
index 6d5a24f3fc6d..51c231a1e5a6 100644
--- a/include/linux/nfsd/nfsd.h
+++ b/include/linux/nfsd/nfsd.h
@@ -60,7 +60,7 @@ typedef int (*nfsd_dirop_t)(struct inode *, struct dentry *, int, int);
extern struct svc_program nfsd_program;
extern struct svc_version nfsd_version2, nfsd_version3,
nfsd_version4;
-
+extern struct svc_serv *nfsd_serv;
/*
* Function prototypes.
*/
diff --git a/include/linux/nfsd/syscall.h b/include/linux/nfsd/syscall.h
index e65c9db6d13f..781efbf94ed3 100644
--- a/include/linux/nfsd/syscall.h
+++ b/include/linux/nfsd/syscall.h
@@ -39,6 +39,21 @@
#define NFSCTL_GETFD 7 /* get an fh by path (used by mountd) */
#define NFSCTL_GETFS 8 /* get an fh by path with max FH len */
+/*
+ * Macros used to set version
+ */
+#define NFSCTL_VERSET(_cltbits, _v) ((_cltbits) |= (1 << (_v)))
+#define NFSCTL_VERUNSET(_cltbits, _v) ((_cltbits) &= ~(1 << (_v)))
+#define NFSCTL_VERISSET(_cltbits, _v) ((_cltbits) & (1 << (_v)))
+
+#if defined(CONFIG_NFSD_V4)
+#define NFSCTL_VERALL (0x1c /* 0b011100 */)
+#elif defined(CONFIG_NFSD_V3)
+#define NFSCTL_VERALL (0x0c /* 0b001100 */)
+#else
+#define NFSCTL_VERALL (0x04 /* 0b000100 */)
+#endif
+
/* SVC */
struct nfsctl_svc {
unsigned short svc_port;
@@ -120,6 +135,8 @@ extern int exp_delclient(struct nfsctl_client *ncp);
extern int exp_export(struct nfsctl_export *nxp);
extern int exp_unexport(struct nfsctl_export *nxp);
+extern unsigned int nfsd_versbits;
+
#endif /* __KERNEL__ */
#endif /* NFSD_SYSCALL_H */
diff --git a/include/linux/nfsd/xdr3.h b/include/linux/nfsd/xdr3.h
index 21e18ce7ca63..3c2a71b43bac 100644
--- a/include/linux/nfsd/xdr3.h
+++ b/include/linux/nfsd/xdr3.h
@@ -42,7 +42,7 @@ struct nfsd3_writeargs {
__u64 offset;
__u32 count;
int stable;
- int len;
+ __u32 len;
struct kvec vec[RPCSVC_MAXPAGES];
int vlen;
};
diff --git a/include/linux/nodemask.h b/include/linux/nodemask.h
index e96fe9062500..4726ef7ba8e8 100644
--- a/include/linux/nodemask.h
+++ b/include/linux/nodemask.h
@@ -12,6 +12,8 @@
* see bitmap_scnprintf() and bitmap_parse() in lib/bitmap.c.
* For details of nodelist_scnprintf() and nodelist_parse(), see
* bitmap_scnlistprintf() and bitmap_parselist(), also in bitmap.c.
+ * For details of node_remap(), see bitmap_bitremap in lib/bitmap.c.
+ * For details of nodes_remap(), see bitmap_remap in lib/bitmap.c.
*
* The available nodemask operations are:
*
@@ -52,6 +54,8 @@
* int nodemask_parse(ubuf, ulen, mask) Parse ascii string as nodemask
* int nodelist_scnprintf(buf, len, mask) Format nodemask as list for printing
* int nodelist_parse(buf, map) Parse ascii string as nodelist
+ * int node_remap(oldbit, old, new) newbit = map(old, new)(oldbit)
+ * int nodes_remap(dst, src, old, new) *dst = map(old, new)(dst)
*
* for_each_node_mask(node, mask) for-loop node over mask
*
@@ -307,6 +311,22 @@ static inline int __nodelist_parse(const char *buf, nodemask_t *dstp, int nbits)
return bitmap_parselist(buf, dstp->bits, nbits);
}
+#define node_remap(oldbit, old, new) \
+ __node_remap((oldbit), &(old), &(new), MAX_NUMNODES)
+static inline int __node_remap(int oldbit,
+ const nodemask_t *oldp, const nodemask_t *newp, int nbits)
+{
+ return bitmap_bitremap(oldbit, oldp->bits, newp->bits, nbits);
+}
+
+#define nodes_remap(dst, src, old, new) \
+ __nodes_remap(&(dst), &(src), &(old), &(new), MAX_NUMNODES)
+static inline void __nodes_remap(nodemask_t *dstp, const nodemask_t *srcp,
+ const nodemask_t *oldp, const nodemask_t *newp, int nbits)
+{
+ bitmap_remap(dstp->bits, srcp->bits, oldp->bits, newp->bits, nbits);
+}
+
#if MAX_NUMNODES > 1
#define for_each_node_mask(node, mask) \
for ((node) = first_node(mask); \
diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h
index acbf31c154f8..ba6c310a055f 100644
--- a/include/linux/pagemap.h
+++ b/include/linux/pagemap.h
@@ -21,16 +21,17 @@
static inline gfp_t mapping_gfp_mask(struct address_space * mapping)
{
- return mapping->flags & __GFP_BITS_MASK;
+ return (__force gfp_t)mapping->flags & __GFP_BITS_MASK;
}
/*
* This is non-atomic. Only to be used before the mapping is activated.
* Probably needs a barrier...
*/
-static inline void mapping_set_gfp_mask(struct address_space *m, int mask)
+static inline void mapping_set_gfp_mask(struct address_space *m, gfp_t mask)
{
- m->flags = (m->flags & ~__GFP_BITS_MASK) | mask;
+ m->flags = (m->flags & ~(__force unsigned long)__GFP_BITS_MASK) |
+ (__force unsigned long)mask;
}
/*
@@ -69,7 +70,7 @@ extern struct page * find_lock_page(struct address_space *mapping,
extern struct page * find_trylock_page(struct address_space *mapping,
unsigned long index);
extern struct page * find_or_create_page(struct address_space *mapping,
- unsigned long index, unsigned int gfp_mask);
+ unsigned long index, gfp_t gfp_mask);
unsigned find_get_pages(struct address_space *mapping, pgoff_t start,
unsigned int nr_pages, struct page **pages);
unsigned find_get_pages_tag(struct address_space *mapping, pgoff_t *index,
@@ -92,9 +93,9 @@ extern int read_cache_pages(struct address_space *mapping,
struct list_head *pages, filler_t *filler, void *data);
int add_to_page_cache(struct page *page, struct address_space *mapping,
- unsigned long index, int gfp_mask);
+ unsigned long index, gfp_t gfp_mask);
int add_to_page_cache_lru(struct page *page, struct address_space *mapping,
- unsigned long index, int gfp_mask);
+ unsigned long index, gfp_t gfp_mask);
extern void remove_from_page_cache(struct page *page);
extern void __remove_from_page_cache(struct page *page);
diff --git a/include/linux/pci-acpi.h b/include/linux/pci-acpi.h
index 857126a36ecc..4877e35ae202 100644
--- a/include/linux/pci-acpi.h
+++ b/include/linux/pci-acpi.h
@@ -47,14 +47,15 @@
OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL)
#ifdef CONFIG_ACPI
-extern acpi_status pci_osc_control_set(u32 flags);
+extern acpi_status pci_osc_control_set(acpi_handle handle, u32 flags);
extern acpi_status pci_osc_support_set(u32 flags);
#else
#if !defined(acpi_status)
typedef u32 acpi_status;
#define AE_ERROR (acpi_status) (0x0001)
#endif
-static inline acpi_status pci_osc_control_set(u32 flags) {return AE_ERROR;}
+static inline acpi_status pci_osc_control_set(acpi_handle handle, u32 flags)
+{return AE_ERROR;}
static inline acpi_status pci_osc_support_set(u32 flags) {return AE_ERROR;}
#endif
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 7349058ed778..de690ca73d58 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -132,6 +132,7 @@ struct pci_dev {
unsigned int is_enabled:1; /* pci_enable_device has been called */
unsigned int is_busmaster:1; /* device is busmaster */
unsigned int no_msi:1; /* device may not use msi */
+ unsigned int block_ucfg_access:1; /* userspace config space access is blocked */
u32 saved_config_space[16]; /* config space saved at suspend time */
struct bin_attribute *rom_attr; /* attribute descriptor for sysfs ROM entry */
@@ -235,7 +236,6 @@ struct module;
struct pci_driver {
struct list_head node;
char *name;
- struct module *owner;
const struct pci_device_id *id_table; /* must be non-NULL for probe to be called */
int (*probe) (struct pci_dev *dev, const struct pci_device_id *id); /* New device inserted */
void (*remove) (struct pci_dev *dev); /* Device removed (NULL if not a hot-plug capable driver) */
@@ -337,6 +337,7 @@ struct pci_dev *pci_find_device (unsigned int vendor, unsigned int device, const
struct pci_dev *pci_find_device_reverse (unsigned int vendor, unsigned int device, const struct pci_dev *from);
struct pci_dev *pci_find_slot (unsigned int bus, unsigned int devfn);
int pci_find_capability (struct pci_dev *dev, int cap);
+int pci_find_next_capability (struct pci_dev *dev, u8 pos, int cap);
int pci_find_ext_capability (struct pci_dev *dev, int cap);
struct pci_bus * pci_find_next_bus(const struct pci_bus *from);
@@ -431,8 +432,13 @@ int pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res,
void *alignf_data);
void pci_enable_bridges(struct pci_bus *bus);
-/* New-style probing supporting hot-pluggable devices */
-int pci_register_driver(struct pci_driver *);
+/* Proper probing supporting hot-pluggable devices */
+int __pci_register_driver(struct pci_driver *, struct module *);
+static inline int pci_register_driver(struct pci_driver *driver)
+{
+ return __pci_register_driver(driver, THIS_MODULE);
+}
+
void pci_unregister_driver(struct pci_driver *);
void pci_remove_behind_bridge(struct pci_dev *);
struct pci_driver *pci_dev_driver(const struct pci_dev *);
@@ -490,6 +496,9 @@ extern void pci_disable_msix(struct pci_dev *dev);
extern void msi_remove_pci_irq_vectors(struct pci_dev *dev);
#endif
+extern void pci_block_user_cfg_access(struct pci_dev *dev);
+extern void pci_unblock_user_cfg_access(struct pci_dev *dev);
+
/*
* PCI domain support. Sometimes called PCI segment (eg by ACPI),
* a PCI domain is defined to be a set of PCI busses which share
@@ -543,9 +552,11 @@ static inline int pci_enable_device(struct pci_dev *dev) { return -EIO; }
static inline void pci_disable_device(struct pci_dev *dev) { }
static inline int pci_set_dma_mask(struct pci_dev *dev, u64 mask) { return -EIO; }
static inline int pci_assign_resource(struct pci_dev *dev, int i) { return -EBUSY;}
+static inline int __pci_register_driver(struct pci_driver *drv, struct module *owner) { return 0;}
static inline int pci_register_driver(struct pci_driver *drv) { return 0;}
static inline void pci_unregister_driver(struct pci_driver *drv) { }
static inline int pci_find_capability (struct pci_dev *dev, int cap) {return 0; }
+static inline int pci_find_next_capability (struct pci_dev *dev, u8 post, int cap) { return 0; }
static inline int pci_find_ext_capability (struct pci_dev *dev, int cap) {return 0; }
static inline const struct pci_device_id *pci_match_device(const struct pci_device_id *ids, const struct pci_dev *dev) { return NULL; }
@@ -560,6 +571,9 @@ static inline int pci_enable_wake(struct pci_dev *dev, pci_power_t state, int en
#define pci_dma_burst_advice(pdev, strat, strategy_parameter) do { } while (0)
+static inline void pci_block_user_cfg_access(struct pci_dev *dev) { }
+static inline void pci_unblock_user_cfg_access(struct pci_dev *dev) { }
+
#endif /* CONFIG_PCI */
/* Include architecture-dependent settings and functions */
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index 71834f05504f..4e06eb0f4451 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -96,6 +96,9 @@
#define PCI_CLASS_SERIAL_ACCESS 0x0c01
#define PCI_CLASS_SERIAL_SSA 0x0c02
#define PCI_CLASS_SERIAL_USB 0x0c03
+#define PCI_CLASS_SERIAL_USB_UHCI 0x0c0300
+#define PCI_CLASS_SERIAL_USB_OHCI 0x0c0310
+#define PCI_CLASS_SERIAL_USB_EHCI 0x0c0320
#define PCI_CLASS_SERIAL_FIBER 0x0c04
#define PCI_CLASS_SERIAL_SMBUS 0x0c05
@@ -132,9 +135,6 @@
#define PCI_VENDOR_ID_COMPAQ 0x0e11
#define PCI_DEVICE_ID_COMPAQ_TOKENRING 0x0508
-#define PCI_DEVICE_ID_COMPAQ_1280 0x3033
-#define PCI_DEVICE_ID_COMPAQ_TRIFLEX 0x4000
-#define PCI_DEVICE_ID_COMPAQ_6010 0x6010
#define PCI_DEVICE_ID_COMPAQ_TACHYON 0xa0fc
#define PCI_DEVICE_ID_COMPAQ_SMART2P 0xae10
#define PCI_DEVICE_ID_COMPAQ_NETEL100 0xae32
@@ -274,7 +274,6 @@
#define PCI_DEVICE_ID_ATI_RAGE128_PP 0x5050
#define PCI_DEVICE_ID_ATI_RAGE128_PQ 0x5051
#define PCI_DEVICE_ID_ATI_RAGE128_PR 0x5052
-#define PCI_DEVICE_ID_ATI_RAGE128_TR 0x5452
#define PCI_DEVICE_ID_ATI_RAGE128_PS 0x5053
#define PCI_DEVICE_ID_ATI_RAGE128_PT 0x5054
#define PCI_DEVICE_ID_ATI_RAGE128_PU 0x5055
@@ -282,8 +281,6 @@
#define PCI_DEVICE_ID_ATI_RAGE128_PW 0x5057
#define PCI_DEVICE_ID_ATI_RAGE128_PX 0x5058
/* Rage128 M4 */
-#define PCI_DEVICE_ID_ATI_RADEON_LE 0x4d45
-#define PCI_DEVICE_ID_ATI_RADEON_LF 0x4d46
/* Radeon R100 */
#define PCI_DEVICE_ID_ATI_RADEON_QD 0x5144
#define PCI_DEVICE_ID_ATI_RADEON_QE 0x5145
@@ -304,32 +301,22 @@
#define PCI_DEVICE_ID_ATI_RADEON_QW 0x5157
#define PCI_DEVICE_ID_ATI_RADEON_QX 0x5158
/* Radeon NV-100 */
-#define PCI_DEVICE_ID_ATI_RADEON_N1 0x5159
-#define PCI_DEVICE_ID_ATI_RADEON_N2 0x515a
/* Radeon RV250 (9000) */
#define PCI_DEVICE_ID_ATI_RADEON_Id 0x4964
#define PCI_DEVICE_ID_ATI_RADEON_Ie 0x4965
#define PCI_DEVICE_ID_ATI_RADEON_If 0x4966
#define PCI_DEVICE_ID_ATI_RADEON_Ig 0x4967
/* Radeon RV280 (9200) */
-#define PCI_DEVICE_ID_ATI_RADEON_Y_ 0x5960
#define PCI_DEVICE_ID_ATI_RADEON_Ya 0x5961
#define PCI_DEVICE_ID_ATI_RADEON_Yd 0x5964
/* Radeon R300 (9500) */
-#define PCI_DEVICE_ID_ATI_RADEON_AD 0x4144
/* Radeon R300 (9700) */
#define PCI_DEVICE_ID_ATI_RADEON_ND 0x4e44
#define PCI_DEVICE_ID_ATI_RADEON_NE 0x4e45
#define PCI_DEVICE_ID_ATI_RADEON_NF 0x4e46
#define PCI_DEVICE_ID_ATI_RADEON_NG 0x4e47
-#define PCI_DEVICE_ID_ATI_RADEON_AE 0x4145
-#define PCI_DEVICE_ID_ATI_RADEON_AF 0x4146
/* Radeon R350 (9800) */
-#define PCI_DEVICE_ID_ATI_RADEON_NH 0x4e48
-#define PCI_DEVICE_ID_ATI_RADEON_NI 0x4e49
/* Radeon RV350 (9600) */
-#define PCI_DEVICE_ID_ATI_RADEON_AP 0x4150
-#define PCI_DEVICE_ID_ATI_RADEON_AR 0x4152
/* Radeon M6 */
#define PCI_DEVICE_ID_ATI_RADEON_LY 0x4c59
#define PCI_DEVICE_ID_ATI_RADEON_LZ 0x4c5a
@@ -342,10 +329,6 @@
#define PCI_DEVICE_ID_ATI_RADEON_Lf 0x4c66
#define PCI_DEVICE_ID_ATI_RADEON_Lg 0x4c67
/* Radeon */
-#define PCI_DEVICE_ID_ATI_RADEON_RA 0x5144
-#define PCI_DEVICE_ID_ATI_RADEON_RB 0x5145
-#define PCI_DEVICE_ID_ATI_RADEON_RC 0x5146
-#define PCI_DEVICE_ID_ATI_RADEON_RD 0x5147
/* RadeonIGP */
#define PCI_DEVICE_ID_ATI_RS100 0xcab0
#define PCI_DEVICE_ID_ATI_RS200 0xcab2
@@ -404,6 +387,7 @@
#define PCI_DEVICE_ID_NS_SC1100_SMI 0x0511
#define PCI_DEVICE_ID_NS_SC1100_XBUS 0x0515
#define PCI_DEVICE_ID_NS_87410 0xd001
+#define PCI_DEVICE_ID_NS_CS5535_IDE 0x002d
#define PCI_VENDOR_ID_TSENG 0x100c
#define PCI_DEVICE_ID_TSENG_W32P_2 0x3202
@@ -446,45 +430,28 @@
#define PCI_DEVICE_ID_CIRRUS_5465 0x00d6
#define PCI_DEVICE_ID_CIRRUS_6729 0x1100
#define PCI_DEVICE_ID_CIRRUS_6832 0x1110
-#define PCI_DEVICE_ID_CIRRUS_7542 0x1200
#define PCI_DEVICE_ID_CIRRUS_7543 0x1202
-#define PCI_DEVICE_ID_CIRRUS_7541 0x1204
#define PCI_DEVICE_ID_CIRRUS_4610 0x6001
#define PCI_DEVICE_ID_CIRRUS_4612 0x6003
#define PCI_DEVICE_ID_CIRRUS_4615 0x6004
-#define PCI_DEVICE_ID_CIRRUS_4281 0x6005
#define PCI_VENDOR_ID_IBM 0x1014
-#define PCI_DEVICE_ID_IBM_FIRE_CORAL 0x000a
#define PCI_DEVICE_ID_IBM_TR 0x0018
-#define PCI_DEVICE_ID_IBM_82G2675 0x001d
-#define PCI_DEVICE_ID_IBM_MCA 0x0020
-#define PCI_DEVICE_ID_IBM_82351 0x0022
-#define PCI_DEVICE_ID_IBM_PYTHON 0x002d
-#define PCI_DEVICE_ID_IBM_SERVERAID 0x002e
#define PCI_DEVICE_ID_IBM_TR_WAKE 0x003e
-#define PCI_DEVICE_ID_IBM_MPIC 0x0046
-#define PCI_DEVICE_ID_IBM_3780IDSP 0x007d
-#define PCI_DEVICE_ID_IBM_CHUKAR 0x0096
#define PCI_DEVICE_ID_IBM_CPC710_PCI64 0x00fc
-#define PCI_DEVICE_ID_IBM_CPC710_PCI32 0x0105
-#define PCI_DEVICE_ID_IBM_405GP 0x0156
#define PCI_DEVICE_ID_IBM_SNIPE 0x0180
-#define PCI_DEVICE_ID_IBM_SERVERAIDI960 0x01bd
#define PCI_DEVICE_ID_IBM_CITRINE 0x028C
#define PCI_DEVICE_ID_IBM_GEMSTONE 0xB166
-#define PCI_DEVICE_ID_IBM_MPIC_2 0xffff
#define PCI_DEVICE_ID_IBM_ICOM_DEV_ID_1 0x0031
#define PCI_DEVICE_ID_IBM_ICOM_DEV_ID_2 0x0219
#define PCI_DEVICE_ID_IBM_ICOM_V2_TWO_PORTS_RVX 0x021A
#define PCI_DEVICE_ID_IBM_ICOM_V2_ONE_PORT_RVX_ONE_PORT_MDM 0x0251
#define PCI_DEVICE_ID_IBM_ICOM_FOUR_PORT_MODEL 0x252
-#define PCI_VENDOR_ID_COMPEX2 0x101a // pci.ids says "AT&T GIS (NCR)"
+#define PCI_VENDOR_ID_COMPEX2 0x101a /* pci.ids says "AT&T GIS (NCR)" */
#define PCI_DEVICE_ID_COMPEX2_100VG 0x0005
#define PCI_VENDOR_ID_WD 0x101c
-#define PCI_DEVICE_ID_WD_7197 0x3296
#define PCI_DEVICE_ID_WD_90C 0xc24a
#define PCI_VENDOR_ID_AMI 0x101e
@@ -501,33 +468,18 @@
#define PCI_DEVICE_ID_AMD_FE_GATE_7006 0x7006
#define PCI_DEVICE_ID_AMD_FE_GATE_7007 0x7007
#define PCI_DEVICE_ID_AMD_FE_GATE_700C 0x700C
-#define PCI_DEVICE_ID_AMD_FE_GATE_700D 0x700D
#define PCI_DEVICE_ID_AMD_FE_GATE_700E 0x700E
-#define PCI_DEVICE_ID_AMD_FE_GATE_700F 0x700F
-#define PCI_DEVICE_ID_AMD_COBRA_7400 0x7400
#define PCI_DEVICE_ID_AMD_COBRA_7401 0x7401
-#define PCI_DEVICE_ID_AMD_COBRA_7403 0x7403
-#define PCI_DEVICE_ID_AMD_COBRA_7404 0x7404
-#define PCI_DEVICE_ID_AMD_VIPER_7408 0x7408
#define PCI_DEVICE_ID_AMD_VIPER_7409 0x7409
#define PCI_DEVICE_ID_AMD_VIPER_740B 0x740B
-#define PCI_DEVICE_ID_AMD_VIPER_740C 0x740C
#define PCI_DEVICE_ID_AMD_VIPER_7410 0x7410
#define PCI_DEVICE_ID_AMD_VIPER_7411 0x7411
#define PCI_DEVICE_ID_AMD_VIPER_7413 0x7413
-#define PCI_DEVICE_ID_AMD_VIPER_7414 0x7414
-#define PCI_DEVICE_ID_AMD_OPUS_7440 0x7440
-# define PCI_DEVICE_ID_AMD_VIPER_7440 PCI_DEVICE_ID_AMD_OPUS_7440
+#define PCI_DEVICE_ID_AMD_VIPER_7440 0x7440
#define PCI_DEVICE_ID_AMD_OPUS_7441 0x7441
-# define PCI_DEVICE_ID_AMD_VIPER_7441 PCI_DEVICE_ID_AMD_OPUS_7441
#define PCI_DEVICE_ID_AMD_OPUS_7443 0x7443
-# define PCI_DEVICE_ID_AMD_VIPER_7443 PCI_DEVICE_ID_AMD_OPUS_7443
+#define PCI_DEVICE_ID_AMD_VIPER_7443 0x7443
#define PCI_DEVICE_ID_AMD_OPUS_7445 0x7445
-#define PCI_DEVICE_ID_AMD_OPUS_7448 0x7448
-# define PCI_DEVICE_ID_AMD_VIPER_7448 PCI_DEVICE_ID_AMD_OPUS_7448
-#define PCI_DEVICE_ID_AMD_OPUS_7449 0x7449
-# define PCI_DEVICE_ID_AMD_VIPER_7449 PCI_DEVICE_ID_AMD_OPUS_7449
-#define PCI_DEVICE_ID_AMD_8111_LAN 0x7462
#define PCI_DEVICE_ID_AMD_8111_LPC 0x7468
#define PCI_DEVICE_ID_AMD_8111_IDE 0x7469
#define PCI_DEVICE_ID_AMD_8111_SMBUS2 0x746a
@@ -536,6 +488,8 @@
#define PCI_DEVICE_ID_AMD_8151_0 0x7454
#define PCI_DEVICE_ID_AMD_8131_APIC 0x7450
+#define PCI_DEVICE_ID_AMD_CS5536_IDE 0x209A
+
#define PCI_VENDOR_ID_TRIDENT 0x1023
#define PCI_DEVICE_ID_TRIDENT_4DWAVE_DX 0x2000
#define PCI_DEVICE_ID_TRIDENT_4DWAVE_NX 0x2001
@@ -568,6 +522,7 @@
#define PCI_DEVICE_ID_MATROX_MIL 0x0519
#define PCI_DEVICE_ID_MATROX_MYS 0x051A
#define PCI_DEVICE_ID_MATROX_MIL_2 0x051b
+#define PCI_DEVICE_ID_MATROX_MYS_AGP 0x051e
#define PCI_DEVICE_ID_MATROX_MIL_2_AGP 0x051f
#define PCI_DEVICE_ID_MATROX_MGA_IMP 0x0d10
#define PCI_DEVICE_ID_MATROX_G100_MM 0x1000
@@ -585,7 +540,6 @@
#define PCI_DEVICE_ID_CT_65550 0x00e0
#define PCI_DEVICE_ID_CT_65554 0x00e4
#define PCI_DEVICE_ID_CT_65555 0x00e5
-#define PCI_DEVICE_ID_CT_69000 0x00c0
#define PCI_VENDOR_ID_MIRO 0x1031
#define PCI_DEVICE_ID_MIRO_36050 0x5601
@@ -639,7 +593,6 @@
#define PCI_DEVICE_ID_SI_550 0x0550
#define PCI_DEVICE_ID_SI_540_VGA 0x5300
#define PCI_DEVICE_ID_SI_550_VGA 0x5315
-#define PCI_DEVICE_ID_SI_601 0x0601
#define PCI_DEVICE_ID_SI_620 0x0620
#define PCI_DEVICE_ID_SI_630 0x0630
#define PCI_DEVICE_ID_SI_633 0x0633
@@ -650,30 +603,22 @@
#define PCI_DEVICE_ID_SI_648 0x0648
#define PCI_DEVICE_ID_SI_650 0x0650
#define PCI_DEVICE_ID_SI_651 0x0651
-#define PCI_DEVICE_ID_SI_652 0x0652
#define PCI_DEVICE_ID_SI_655 0x0655
#define PCI_DEVICE_ID_SI_661 0x0661
#define PCI_DEVICE_ID_SI_730 0x0730
#define PCI_DEVICE_ID_SI_733 0x0733
#define PCI_DEVICE_ID_SI_630_VGA 0x6300
-#define PCI_DEVICE_ID_SI_730_VGA 0x7300
#define PCI_DEVICE_ID_SI_735 0x0735
#define PCI_DEVICE_ID_SI_740 0x0740
#define PCI_DEVICE_ID_SI_741 0x0741
#define PCI_DEVICE_ID_SI_745 0x0745
#define PCI_DEVICE_ID_SI_746 0x0746
-#define PCI_DEVICE_ID_SI_748 0x0748
-#define PCI_DEVICE_ID_SI_750 0x0750
-#define PCI_DEVICE_ID_SI_751 0x0751
-#define PCI_DEVICE_ID_SI_752 0x0752
#define PCI_DEVICE_ID_SI_755 0x0755
#define PCI_DEVICE_ID_SI_760 0x0760
#define PCI_DEVICE_ID_SI_900 0x0900
#define PCI_DEVICE_ID_SI_961 0x0961
#define PCI_DEVICE_ID_SI_962 0x0962
#define PCI_DEVICE_ID_SI_963 0x0963
-#define PCI_DEVICE_ID_SI_5107 0x5107
-#define PCI_DEVICE_ID_SI_5300 0x5300
#define PCI_DEVICE_ID_SI_5511 0x5511
#define PCI_DEVICE_ID_SI_5513 0x5513
#define PCI_DEVICE_ID_SI_5518 0x5518
@@ -685,10 +630,6 @@
#define PCI_DEVICE_ID_SI_5597 0x5597
#define PCI_DEVICE_ID_SI_5598 0x5598
#define PCI_DEVICE_ID_SI_5600 0x5600
-#define PCI_DEVICE_ID_SI_6300 0x6300
-#define PCI_DEVICE_ID_SI_6306 0x6306
-#define PCI_DEVICE_ID_SI_6326 0x6326
-#define PCI_DEVICE_ID_SI_7001 0x7001
#define PCI_DEVICE_ID_SI_7012 0x7012
#define PCI_DEVICE_ID_SI_7013 0x7013
#define PCI_DEVICE_ID_SI_7016 0x7016
@@ -709,14 +650,11 @@
#define PCI_DEVICE_ID_HP_DIVA_TOSCA1 0x1049
#define PCI_DEVICE_ID_HP_DIVA_TOSCA2 0x104A
#define PCI_DEVICE_ID_HP_DIVA_MAESTRO 0x104B
-#define PCI_DEVICE_ID_HP_PCI_LBA 0x1054
-#define PCI_DEVICE_ID_HP_REO_SBA 0x10f0
#define PCI_DEVICE_ID_HP_REO_IOC 0x10f1
#define PCI_DEVICE_ID_HP_VISUALIZE_FXE 0x108b
#define PCI_DEVICE_ID_HP_DIVA_HALFDOME 0x1223
#define PCI_DEVICE_ID_HP_DIVA_KEYSTONE 0x1226
#define PCI_DEVICE_ID_HP_DIVA_POWERBAR 0x1227
-#define PCI_DEVICE_ID_HP_ZX1_SBA 0x1229
#define PCI_DEVICE_ID_HP_ZX1_IOC 0x122a
#define PCI_DEVICE_ID_HP_PCIX_LBA 0x122e
#define PCI_DEVICE_ID_HP_SX1000_IOC 0x127c
@@ -724,9 +662,7 @@
#define PCI_DEVICE_ID_HP_DIVA_AUX 0x1290
#define PCI_DEVICE_ID_HP_DIVA_RMP3 0x1301
#define PCI_DEVICE_ID_HP_DIVA_HURRICANE 0x132a
-#define PCI_DEVICE_ID_HP_CISS 0x3210
#define PCI_DEVICE_ID_HP_CISSA 0x3220
-#define PCI_DEVICE_ID_HP_CISSB 0x3222
#define PCI_DEVICE_ID_HP_CISSC 0x3230
#define PCI_DEVICE_ID_HP_CISSD 0x3238
#define PCI_DEVICE_ID_HP_ZX2_IOC 0x4031
@@ -734,8 +670,6 @@
#define PCI_VENDOR_ID_PCTECH 0x1042
#define PCI_DEVICE_ID_PCTECH_RZ1000 0x1000
#define PCI_DEVICE_ID_PCTECH_RZ1001 0x1001
-#define PCI_DEVICE_ID_PCTECH_SAMURAI_0 0x3000
-#define PCI_DEVICE_ID_PCTECH_SAMURAI_1 0x3010
#define PCI_DEVICE_ID_PCTECH_SAMURAI_IDE 0x3020
#define PCI_VENDOR_ID_ASUSTEK 0x1043
@@ -745,24 +679,15 @@
#define PCI_DEVICE_ID_DPT 0xa400
#define PCI_VENDOR_ID_OPTI 0x1045
-#define PCI_DEVICE_ID_OPTI_92C178 0xc178
-#define PCI_DEVICE_ID_OPTI_82C557 0xc557
#define PCI_DEVICE_ID_OPTI_82C558 0xc558
#define PCI_DEVICE_ID_OPTI_82C621 0xc621
#define PCI_DEVICE_ID_OPTI_82C700 0xc700
-#define PCI_DEVICE_ID_OPTI_82C701 0xc701
-#define PCI_DEVICE_ID_OPTI_82C814 0xc814
-#define PCI_DEVICE_ID_OPTI_82C822 0xc822
-#define PCI_DEVICE_ID_OPTI_82C861 0xc861
#define PCI_DEVICE_ID_OPTI_82C825 0xd568
#define PCI_VENDOR_ID_ELSA 0x1048
#define PCI_DEVICE_ID_ELSA_MICROLINK 0x1000
#define PCI_DEVICE_ID_ELSA_QS3000 0x3000
-#define PCI_VENDOR_ID_SGS 0x104a
-#define PCI_DEVICE_ID_SGS_2000 0x0008
-#define PCI_DEVICE_ID_SGS_1764 0x0009
#define PCI_VENDOR_ID_BUSLOGIC 0x104B
#define PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER_NC 0x0140
@@ -770,7 +695,6 @@
#define PCI_DEVICE_ID_BUSLOGIC_FLASHPOINT 0x8130
#define PCI_VENDOR_ID_TI 0x104c
-#define PCI_DEVICE_ID_TI_TVP4010 0x3d04
#define PCI_DEVICE_ID_TI_TVP4020 0x3d07
#define PCI_DEVICE_ID_TI_4450 0x8011
#define PCI_DEVICE_ID_TI_XX21_XX11 0x8031
@@ -804,14 +728,10 @@
#define PCI_DEVICE_ID_TI_X420 0xac8e
#define PCI_VENDOR_ID_SONY 0x104d
-#define PCI_DEVICE_ID_SONY_CXD3222 0x8039
-#define PCI_VENDOR_ID_OAK 0x104e
-#define PCI_DEVICE_ID_OAK_OTI107 0x0107
/* Winbond have two vendor IDs! See 0x10ad as well */
#define PCI_VENDOR_ID_WINBOND2 0x1050
-#define PCI_DEVICE_ID_WINBOND2_89C940 0x0940
#define PCI_DEVICE_ID_WINBOND2_89C940F 0x5a5a
#define PCI_DEVICE_ID_WINBOND2_6692 0x6692
@@ -820,19 +740,15 @@
#define PCI_VENDOR_ID_EFAR 0x1055
#define PCI_DEVICE_ID_EFAR_SLC90E66_1 0x9130
-#define PCI_DEVICE_ID_EFAR_SLC90E66_0 0x9460
-#define PCI_DEVICE_ID_EFAR_SLC90E66_2 0x9462
#define PCI_DEVICE_ID_EFAR_SLC90E66_3 0x9463
#define PCI_VENDOR_ID_MOTOROLA 0x1057
-#define PCI_VENDOR_ID_MOTOROLA_OOPS 0x1507
#define PCI_DEVICE_ID_MOTOROLA_MPC105 0x0001
#define PCI_DEVICE_ID_MOTOROLA_MPC106 0x0002
#define PCI_DEVICE_ID_MOTOROLA_MPC107 0x0004
#define PCI_DEVICE_ID_MOTOROLA_RAVEN 0x4801
#define PCI_DEVICE_ID_MOTOROLA_FALCON 0x4802
#define PCI_DEVICE_ID_MOTOROLA_HAWK 0x4803
-#define PCI_DEVICE_ID_MOTOROLA_CPX8216 0x4806
#define PCI_DEVICE_ID_MOTOROLA_HARRIER 0x480b
#define PCI_DEVICE_ID_MOTOROLA_MPC5200 0x5803
@@ -843,33 +759,19 @@
#define PCI_DEVICE_ID_PROMISE_20262 0x4d38
#define PCI_DEVICE_ID_PROMISE_20263 0x0D38
#define PCI_DEVICE_ID_PROMISE_20268 0x4d68
-#define PCI_DEVICE_ID_PROMISE_20268R 0x6268
#define PCI_DEVICE_ID_PROMISE_20269 0x4d69
#define PCI_DEVICE_ID_PROMISE_20270 0x6268
#define PCI_DEVICE_ID_PROMISE_20271 0x6269
#define PCI_DEVICE_ID_PROMISE_20275 0x1275
#define PCI_DEVICE_ID_PROMISE_20276 0x5275
#define PCI_DEVICE_ID_PROMISE_20277 0x7275
-#define PCI_DEVICE_ID_PROMISE_5300 0x5300
-#define PCI_VENDOR_ID_N9 0x105d
-#define PCI_DEVICE_ID_N9_I128 0x2309
-#define PCI_DEVICE_ID_N9_I128_2 0x2339
-#define PCI_DEVICE_ID_N9_I128_T2R 0x493d
#define PCI_VENDOR_ID_UMC 0x1060
#define PCI_DEVICE_ID_UMC_UM8673F 0x0101
-#define PCI_DEVICE_ID_UMC_UM8891A 0x0891
#define PCI_DEVICE_ID_UMC_UM8886BF 0x673a
#define PCI_DEVICE_ID_UMC_UM8886A 0x886a
-#define PCI_DEVICE_ID_UMC_UM8881F 0x8881
-#define PCI_DEVICE_ID_UMC_UM8886F 0x8886
-#define PCI_DEVICE_ID_UMC_UM9017F 0x9017
-#define PCI_DEVICE_ID_UMC_UM8886N 0xe886
-#define PCI_DEVICE_ID_UMC_UM8891N 0xe891
-#define PCI_VENDOR_ID_X 0x1061
-#define PCI_DEVICE_ID_X_AGX016 0x0001
#define PCI_VENDOR_ID_MYLEX 0x1069
#define PCI_DEVICE_ID_MYLEX_DAC960_P 0x0001
@@ -880,37 +782,26 @@
#define PCI_DEVICE_ID_MYLEX_DAC960_BA 0xBA56
#define PCI_DEVICE_ID_MYLEX_DAC960_GEM 0xB166
-#define PCI_VENDOR_ID_PICOP 0x1066
-#define PCI_DEVICE_ID_PICOP_PT86C52X 0x0001
-#define PCI_DEVICE_ID_PICOP_PT80C524 0x8002
#define PCI_VENDOR_ID_APPLE 0x106b
#define PCI_DEVICE_ID_APPLE_BANDIT 0x0001
-#define PCI_DEVICE_ID_APPLE_GC 0x0002
#define PCI_DEVICE_ID_APPLE_HYDRA 0x000e
#define PCI_DEVICE_ID_APPLE_UNI_N_FW 0x0018
-#define PCI_DEVICE_ID_APPLE_KL_USB 0x0019
#define PCI_DEVICE_ID_APPLE_UNI_N_AGP 0x0020
#define PCI_DEVICE_ID_APPLE_UNI_N_GMAC 0x0021
-#define PCI_DEVICE_ID_APPLE_KEYLARGO 0x0022
#define PCI_DEVICE_ID_APPLE_UNI_N_GMACP 0x0024
-#define PCI_DEVICE_ID_APPLE_KEYLARGO_P 0x0025
-#define PCI_DEVICE_ID_APPLE_KL_USB_P 0x0026
#define PCI_DEVICE_ID_APPLE_UNI_N_AGP_P 0x0027
#define PCI_DEVICE_ID_APPLE_UNI_N_AGP15 0x002d
#define PCI_DEVICE_ID_APPLE_UNI_N_PCI15 0x002e
-#define PCI_DEVICE_ID_APPLE_UNI_N_FW2 0x0030
#define PCI_DEVICE_ID_APPLE_UNI_N_GMAC2 0x0032
#define PCI_DEVICE_ID_APPLE_UNI_N_ATA 0x0033
#define PCI_DEVICE_ID_APPLE_UNI_N_AGP2 0x0034
#define PCI_DEVICE_ID_APPLE_IPID_ATA100 0x003b
-#define PCI_DEVICE_ID_APPLE_KEYLARGO_I 0x003e
#define PCI_DEVICE_ID_APPLE_K2_ATA100 0x0043
#define PCI_DEVICE_ID_APPLE_U3_AGP 0x004b
#define PCI_DEVICE_ID_APPLE_K2_GMAC 0x004c
#define PCI_DEVICE_ID_APPLE_SH_ATA 0x0050
#define PCI_DEVICE_ID_APPLE_SH_SUNGEM 0x0051
-#define PCI_DEVICE_ID_APPLE_SH_FW 0x0052
#define PCI_DEVICE_ID_APPLE_U3L_AGP 0x0058
#define PCI_DEVICE_ID_APPLE_U3H_AGP 0x0059
#define PCI_DEVICE_ID_APPLE_TIGON3 0x1645
@@ -923,12 +814,9 @@
#define PCI_DEVICE_ID_YAMAHA_744 0x0010
#define PCI_DEVICE_ID_YAMAHA_754 0x0012
-#define PCI_VENDOR_ID_NEXGEN 0x1074
-#define PCI_DEVICE_ID_NEXGEN_82C501 0x4e78
#define PCI_VENDOR_ID_QLOGIC 0x1077
#define PCI_DEVICE_ID_QLOGIC_ISP1020 0x1020
-#define PCI_DEVICE_ID_QLOGIC_ISP1022 0x1022
#define PCI_DEVICE_ID_QLOGIC_ISP2100 0x2100
#define PCI_DEVICE_ID_QLOGIC_ISP2200 0x2200
#define PCI_DEVICE_ID_QLOGIC_ISP2300 0x2300
@@ -946,32 +834,20 @@
#define PCI_DEVICE_ID_CYRIX_PCI_MASTER 0x0001
#define PCI_DEVICE_ID_CYRIX_5520 0x0002
#define PCI_DEVICE_ID_CYRIX_5530_LEGACY 0x0100
-#define PCI_DEVICE_ID_CYRIX_5530_SMI 0x0101
#define PCI_DEVICE_ID_CYRIX_5530_IDE 0x0102
#define PCI_DEVICE_ID_CYRIX_5530_AUDIO 0x0103
#define PCI_DEVICE_ID_CYRIX_5530_VIDEO 0x0104
-#define PCI_VENDOR_ID_LEADTEK 0x107d
-#define PCI_DEVICE_ID_LEADTEK_805 0x0000
-#define PCI_VENDOR_ID_INTERPHASE 0x107e
-#define PCI_DEVICE_ID_INTERPHASE_5526 0x0004
-#define PCI_DEVICE_ID_INTERPHASE_55x6 0x0005
-#define PCI_DEVICE_ID_INTERPHASE_5575 0x0008
#define PCI_VENDOR_ID_CONTAQ 0x1080
-#define PCI_DEVICE_ID_CONTAQ_82C599 0x0600
#define PCI_DEVICE_ID_CONTAQ_82C693 0xc693
-#define PCI_VENDOR_ID_FOREX 0x1083
#define PCI_VENDOR_ID_OLICOM 0x108d
-#define PCI_DEVICE_ID_OLICOM_OC3136 0x0001
-#define PCI_DEVICE_ID_OLICOM_OC2315 0x0011
#define PCI_DEVICE_ID_OLICOM_OC2325 0x0012
#define PCI_DEVICE_ID_OLICOM_OC2183 0x0013
#define PCI_DEVICE_ID_OLICOM_OC2326 0x0014
-#define PCI_DEVICE_ID_OLICOM_OC6151 0x0021
#define PCI_VENDOR_ID_SUN 0x108e
#define PCI_DEVICE_ID_SUN_EBUS 0x1000
@@ -990,49 +866,31 @@
#define PCI_DEVICE_ID_SUN_CASSINI 0xabba
#define PCI_VENDOR_ID_CMD 0x1095
-#define PCI_DEVICE_ID_CMD_640 0x0640
#define PCI_DEVICE_ID_CMD_643 0x0643
#define PCI_DEVICE_ID_CMD_646 0x0646
-#define PCI_DEVICE_ID_CMD_647 0x0647
#define PCI_DEVICE_ID_CMD_648 0x0648
#define PCI_DEVICE_ID_CMD_649 0x0649
-#define PCI_DEVICE_ID_CMD_670 0x0670
-#define PCI_DEVICE_ID_CMD_680 0x0680
#define PCI_DEVICE_ID_SII_680 0x0680
#define PCI_DEVICE_ID_SII_3112 0x3112
#define PCI_DEVICE_ID_SII_1210SA 0x0240
-#define PCI_VENDOR_ID_VISION 0x1098
-#define PCI_DEVICE_ID_VISION_QD8500 0x0001
-#define PCI_DEVICE_ID_VISION_QD8580 0x0002
#define PCI_VENDOR_ID_BROOKTREE 0x109e
-#define PCI_DEVICE_ID_BROOKTREE_848 0x0350
-#define PCI_DEVICE_ID_BROOKTREE_849A 0x0351
-#define PCI_DEVICE_ID_BROOKTREE_878_1 0x036e
#define PCI_DEVICE_ID_BROOKTREE_878 0x0878
#define PCI_DEVICE_ID_BROOKTREE_879 0x0879
-#define PCI_DEVICE_ID_BROOKTREE_8474 0x8474
-#define PCI_VENDOR_ID_SIERRA 0x10a8
-#define PCI_DEVICE_ID_SIERRA_STB 0x0000
#define PCI_VENDOR_ID_SGI 0x10a9
#define PCI_DEVICE_ID_SGI_IOC3 0x0003
#define PCI_DEVICE_ID_SGI_IOC4 0x100a
#define PCI_VENDOR_ID_SGI_LITHIUM 0x1002
-#define PCI_VENDOR_ID_ACC 0x10aa
-#define PCI_DEVICE_ID_ACC_2056 0x0000
#define PCI_VENDOR_ID_WINBOND 0x10ad
-#define PCI_DEVICE_ID_WINBOND_83769 0x0001
#define PCI_DEVICE_ID_WINBOND_82C105 0x0105
#define PCI_DEVICE_ID_WINBOND_83C553 0x0565
-#define PCI_VENDOR_ID_DATABOOK 0x10b3
-#define PCI_DEVICE_ID_DATABOOK_87144 0xb106
#define PCI_VENDOR_ID_PLX 0x10b5
#define PCI_DEVICE_ID_PLX_R685 0x1030
@@ -1043,33 +901,19 @@
#define PCI_DEVICE_ID_PLX_DJINN_ITOO 0x1151
#define PCI_DEVICE_ID_PLX_R753 0x1152
#define PCI_DEVICE_ID_PLX_OLITEC 0x1187
-#define PCI_DEVICE_ID_PLX_9030 0x9030
#define PCI_DEVICE_ID_PLX_9050 0x9050
-#define PCI_DEVICE_ID_PLX_9060 0x9060
-#define PCI_DEVICE_ID_PLX_9060ES 0x906E
-#define PCI_DEVICE_ID_PLX_9060SD 0x906D
#define PCI_DEVICE_ID_PLX_9080 0x9080
#define PCI_DEVICE_ID_PLX_GTEK_SERIAL2 0xa001
#define PCI_VENDOR_ID_MADGE 0x10b6
#define PCI_DEVICE_ID_MADGE_MK2 0x0002
-#define PCI_DEVICE_ID_MADGE_C155S 0x1001
#define PCI_VENDOR_ID_3COM 0x10b7
#define PCI_DEVICE_ID_3COM_3C985 0x0001
#define PCI_DEVICE_ID_3COM_3C940 0x1700
#define PCI_DEVICE_ID_3COM_3C339 0x3390
#define PCI_DEVICE_ID_3COM_3C359 0x3590
-#define PCI_DEVICE_ID_3COM_3C590 0x5900
-#define PCI_DEVICE_ID_3COM_3C595TX 0x5950
-#define PCI_DEVICE_ID_3COM_3C595T4 0x5951
-#define PCI_DEVICE_ID_3COM_3C595MII 0x5952
#define PCI_DEVICE_ID_3COM_3C940B 0x80eb
-#define PCI_DEVICE_ID_3COM_3C900TPO 0x9000
-#define PCI_DEVICE_ID_3COM_3C900COMBO 0x9001
-#define PCI_DEVICE_ID_3COM_3C905TX 0x9050
-#define PCI_DEVICE_ID_3COM_3C905T4 0x9051
-#define PCI_DEVICE_ID_3COM_3C905B_TX 0x9055
#define PCI_DEVICE_ID_3COM_3CR990 0x9900
#define PCI_DEVICE_ID_3COM_3CR990_TX_95 0x9902
#define PCI_DEVICE_ID_3COM_3CR990_TX_97 0x9903
@@ -1079,24 +923,11 @@
#define PCI_DEVICE_ID_3COM_3CR990SVR97 0x9909
#define PCI_DEVICE_ID_3COM_3CR990SVR 0x990a
-#define PCI_VENDOR_ID_SMC 0x10b8
-#define PCI_DEVICE_ID_SMC_EPIC100 0x0005
#define PCI_VENDOR_ID_AL 0x10b9
-#define PCI_DEVICE_ID_AL_M1445 0x1445
-#define PCI_DEVICE_ID_AL_M1449 0x1449
-#define PCI_DEVICE_ID_AL_M1451 0x1451
-#define PCI_DEVICE_ID_AL_M1461 0x1461
-#define PCI_DEVICE_ID_AL_M1489 0x1489
-#define PCI_DEVICE_ID_AL_M1511 0x1511
-#define PCI_DEVICE_ID_AL_M1513 0x1513
-#define PCI_DEVICE_ID_AL_M1521 0x1521
-#define PCI_DEVICE_ID_AL_M1523 0x1523
-#define PCI_DEVICE_ID_AL_M1531 0x1531
#define PCI_DEVICE_ID_AL_M1533 0x1533
#define PCI_DEVICE_ID_AL_M1535 0x1535
#define PCI_DEVICE_ID_AL_M1541 0x1541
-#define PCI_DEVICE_ID_AL_M1543 0x1543
#define PCI_DEVICE_ID_AL_M1563 0x1563
#define PCI_DEVICE_ID_AL_M1621 0x1621
#define PCI_DEVICE_ID_AL_M1631 0x1631
@@ -1109,49 +940,23 @@
#define PCI_DEVICE_ID_AL_M1681 0x1681
#define PCI_DEVICE_ID_AL_M1683 0x1683
#define PCI_DEVICE_ID_AL_M1689 0x1689
-#define PCI_DEVICE_ID_AL_M3307 0x3307
-#define PCI_DEVICE_ID_AL_M4803 0x5215
#define PCI_DEVICE_ID_AL_M5219 0x5219
#define PCI_DEVICE_ID_AL_M5228 0x5228
#define PCI_DEVICE_ID_AL_M5229 0x5229
-#define PCI_DEVICE_ID_AL_M5237 0x5237
-#define PCI_DEVICE_ID_AL_M5243 0x5243
#define PCI_DEVICE_ID_AL_M5451 0x5451
#define PCI_DEVICE_ID_AL_M7101 0x7101
-#define PCI_VENDOR_ID_MITSUBISHI 0x10ba
-#define PCI_VENDOR_ID_SURECOM 0x10bd
-#define PCI_DEVICE_ID_SURECOM_NE34 0x0e34
#define PCI_VENDOR_ID_NEOMAGIC 0x10c8
-#define PCI_DEVICE_ID_NEOMAGIC_MAGICGRAPH_NM2070 0x0001
-#define PCI_DEVICE_ID_NEOMAGIC_MAGICGRAPH_128V 0x0002
-#define PCI_DEVICE_ID_NEOMAGIC_MAGICGRAPH_128ZV 0x0003
-#define PCI_DEVICE_ID_NEOMAGIC_MAGICGRAPH_NM2160 0x0004
-#define PCI_DEVICE_ID_NEOMAGIC_MAGICMEDIA_256AV 0x0005
-#define PCI_DEVICE_ID_NEOMAGIC_MAGICGRAPH_128ZVPLUS 0x0083
#define PCI_DEVICE_ID_NEOMAGIC_NM256AV_AUDIO 0x8005
#define PCI_DEVICE_ID_NEOMAGIC_NM256ZX_AUDIO 0x8006
#define PCI_DEVICE_ID_NEOMAGIC_NM256XL_PLUS_AUDIO 0x8016
-#define PCI_VENDOR_ID_ASP 0x10cd
-#define PCI_DEVICE_ID_ASP_ABP940 0x1200
-#define PCI_DEVICE_ID_ASP_ABP940U 0x1300
-#define PCI_DEVICE_ID_ASP_ABP940UW 0x2300
-
-#define PCI_VENDOR_ID_MACRONIX 0x10d9
-#define PCI_DEVICE_ID_MACRONIX_MX98713 0x0512
-#define PCI_DEVICE_ID_MACRONIX_MX987x5 0x0531
#define PCI_VENDOR_ID_TCONRAD 0x10da
#define PCI_DEVICE_ID_TCONRAD_TOKENRING 0x0508
-#define PCI_VENDOR_ID_CERN 0x10dc
-#define PCI_DEVICE_ID_CERN_SPSB_PMC 0x0001
-#define PCI_DEVICE_ID_CERN_SPSB_PCI 0x0002
-#define PCI_DEVICE_ID_CERN_HIPPI_DST 0x0021
-#define PCI_DEVICE_ID_CERN_HIPPI_SRC 0x0022
#define PCI_VENDOR_ID_NVIDIA 0x10de
#define PCI_DEVICE_ID_NVIDIA_TNT 0x0020
@@ -1189,6 +994,10 @@
#define PCI_DEVICE_ID_NVIDIA_CK8_AUDIO 0x008a
#define PCI_DEVICE_ID_NVIDIA_NVENET_5 0x008c
#define PCI_DEVICE_ID_NVIDIA_NFORCE2S_SATA 0x008e
+#define PCI_DEVICE_ID_NVIDIA_GEFORCE_7800_GT 0x0090
+#define PCI_DEVICE_ID_NVIDIA_GEFORCE_7800_GTX 0x0091
+#define PCI_DEVICE_ID_NVIDIA_GEFORCE_GO_7800 0x0098
+#define PCI_DEVICE_ID_NVIDIA_GEFORCE_GO_7800_GTX 0x0099
#define PCI_DEVICE_ID_NVIDIA_ITNT2 0x00A0
#define PCI_DEVICE_ID_GEFORCE_6800A 0x00c1
#define PCI_DEVICE_ID_GEFORCE_6800A_LE 0x00c2
@@ -1197,7 +1006,6 @@
#define PCI_DEVICE_ID_QUADRO_FX_GO1400 0x00cc
#define PCI_DEVICE_ID_QUADRO_FX_1400 0x00ce
#define PCI_DEVICE_ID_NVIDIA_NFORCE3 0x00d1
-#define PCI_DEVICE_ID_NVIDIA_MCP3_AUDIO 0x00da
#define PCI_DEVICE_ID_NVIDIA_NFORCE3_SMBUS 0x00d4
#define PCI_DEVICE_ID_NVIDIA_NFORCE3_IDE 0x00d5
#define PCI_DEVICE_ID_NVIDIA_NVENET_3 0x00d6
@@ -1284,7 +1092,6 @@
#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SATA2 0x037F
#define PCI_DEVICE_ID_NVIDIA_NVENET_12 0x0268
#define PCI_DEVICE_ID_NVIDIA_NVENET_13 0x0269
-#define PCI_DEVICE_ID_NVIDIA_MCP51_AUDIO 0x026B
#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4800 0x0280
#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4800_8X 0x0281
#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4800SE 0x0282
@@ -1335,24 +1142,13 @@
#define PCI_DEVICE_ID_NVIDIA_NVENET_15 0x0373
#define PCI_VENDOR_ID_IMS 0x10e0
-#define PCI_DEVICE_ID_IMS_8849 0x8849
#define PCI_DEVICE_ID_IMS_TT128 0x9128
#define PCI_DEVICE_ID_IMS_TT3D 0x9135
-#define PCI_VENDOR_ID_TEKRAM2 0x10e1
-#define PCI_DEVICE_ID_TEKRAM2_690c 0x690c
-#define PCI_VENDOR_ID_TUNDRA 0x10e3
-#define PCI_DEVICE_ID_TUNDRA_CA91C042 0x0000
-#define PCI_VENDOR_ID_AMCC 0x10e8
-#define PCI_DEVICE_ID_AMCC_MYRINET 0x8043
-#define PCI_DEVICE_ID_AMCC_PARASTATION 0x8062
-#define PCI_DEVICE_ID_AMCC_S5933 0x807d
-#define PCI_DEVICE_ID_AMCC_S5933_HEPC3 0x809c
#define PCI_VENDOR_ID_INTERG 0x10ea
-#define PCI_DEVICE_ID_INTERG_1680 0x1680
#define PCI_DEVICE_ID_INTERG_1682 0x1682
#define PCI_DEVICE_ID_INTERG_2000 0x2000
#define PCI_DEVICE_ID_INTERG_2010 0x2010
@@ -1360,32 +1156,23 @@
#define PCI_DEVICE_ID_INTERG_5050 0x5050
#define PCI_VENDOR_ID_REALTEK 0x10ec
-#define PCI_DEVICE_ID_REALTEK_8029 0x8029
-#define PCI_DEVICE_ID_REALTEK_8129 0x8129
#define PCI_DEVICE_ID_REALTEK_8139 0x8139
-#define PCI_DEVICE_ID_REALTEK_8169 0x8169
#define PCI_VENDOR_ID_XILINX 0x10ee
#define PCI_DEVICE_ID_RME_DIGI96 0x3fc0
#define PCI_DEVICE_ID_RME_DIGI96_8 0x3fc1
#define PCI_DEVICE_ID_RME_DIGI96_8_PRO 0x3fc2
#define PCI_DEVICE_ID_RME_DIGI96_8_PAD_OR_PST 0x3fc3
-#define PCI_DEVICE_ID_XILINX_HAMMERFALL 0x3fc4
#define PCI_DEVICE_ID_XILINX_HAMMERFALL_DSP 0x3fc5
#define PCI_DEVICE_ID_XILINX_HAMMERFALL_DSP_MADI 0x3fc6
-#define PCI_DEVICE_ID_TURBOPAM 0x4020
-#define PCI_VENDOR_ID_TRUEVISION 0x10fa
-#define PCI_DEVICE_ID_TRUEVISION_T1000 0x000c
#define PCI_VENDOR_ID_INIT 0x1101
-#define PCI_DEVICE_ID_INIT_320P 0x9100
-#define PCI_DEVICE_ID_INIT_360P 0x9500
-#define PCI_VENDOR_ID_CREATIVE 0x1102 // duplicate: ECTIVA
+#define PCI_VENDOR_ID_CREATIVE 0x1102 /* duplicate: ECTIVA */
#define PCI_DEVICE_ID_CREATIVE_EMU10K1 0x0002
-#define PCI_VENDOR_ID_ECTIVA 0x1102 // duplicate: CREATIVE
+#define PCI_VENDOR_ID_ECTIVA 0x1102 /* duplicate: CREATIVE */
#define PCI_DEVICE_ID_ECTIVA_EV1938 0x8938
#define PCI_VENDOR_ID_TTI 0x1103
@@ -1395,7 +1182,7 @@
#define PCI_DEVICE_ID_TTI_HPT302 0x0006
#define PCI_DEVICE_ID_TTI_HPT371 0x0007
#define PCI_DEVICE_ID_TTI_HPT374 0x0008
-#define PCI_DEVICE_ID_TTI_HPT372N 0x0009 // apparently a 372N variant?
+#define PCI_DEVICE_ID_TTI_HPT372N 0x0009 /* apparently a 372N variant? */
#define PCI_VENDOR_ID_VIA 0x1106
#define PCI_DEVICE_ID_VIA_8763_0 0x0198
@@ -1408,36 +1195,25 @@
#define PCI_DEVICE_ID_VIA_8363_0 0x0305
#define PCI_DEVICE_ID_VIA_8371_0 0x0391
#define PCI_DEVICE_ID_VIA_8501_0 0x0501
-#define PCI_DEVICE_ID_VIA_82C505 0x0505
#define PCI_DEVICE_ID_VIA_82C561 0x0561
#define PCI_DEVICE_ID_VIA_82C586_1 0x0571
#define PCI_DEVICE_ID_VIA_82C576 0x0576
-#define PCI_DEVICE_ID_VIA_82C585 0x0585
#define PCI_DEVICE_ID_VIA_82C586_0 0x0586
-#define PCI_DEVICE_ID_VIA_82C595 0x0595
#define PCI_DEVICE_ID_VIA_82C596 0x0596
#define PCI_DEVICE_ID_VIA_82C597_0 0x0597
#define PCI_DEVICE_ID_VIA_82C598_0 0x0598
#define PCI_DEVICE_ID_VIA_8601_0 0x0601
#define PCI_DEVICE_ID_VIA_8605_0 0x0605
-#define PCI_DEVICE_ID_VIA_82C680 0x0680
#define PCI_DEVICE_ID_VIA_82C686 0x0686
#define PCI_DEVICE_ID_VIA_82C691_0 0x0691
-#define PCI_DEVICE_ID_VIA_82C693 0x0693
-#define PCI_DEVICE_ID_VIA_82C693_1 0x0698
-#define PCI_DEVICE_ID_VIA_82C926 0x0926
#define PCI_DEVICE_ID_VIA_82C576_1 0x1571
-#define PCI_DEVICE_ID_VIA_82C595_97 0x1595
#define PCI_DEVICE_ID_VIA_82C586_2 0x3038
#define PCI_DEVICE_ID_VIA_82C586_3 0x3040
-#define PCI_DEVICE_ID_VIA_6305 0x3044
#define PCI_DEVICE_ID_VIA_82C596_3 0x3050
#define PCI_DEVICE_ID_VIA_82C596B_3 0x3051
#define PCI_DEVICE_ID_VIA_82C686_4 0x3057
#define PCI_DEVICE_ID_VIA_82C686_5 0x3058
#define PCI_DEVICE_ID_VIA_8233_5 0x3059
-#define PCI_DEVICE_ID_VIA_8233_7 0x3065
-#define PCI_DEVICE_ID_VIA_82C686_6 0x3068
#define PCI_DEVICE_ID_VIA_8233_0 0x3074
#define PCI_DEVICE_ID_VIA_8633_0 0x3091
#define PCI_DEVICE_ID_VIA_8367_0 0x3099
@@ -1455,38 +1231,23 @@
#define PCI_DEVICE_ID_VIA_XN266 0x3156
#define PCI_DEVICE_ID_VIA_8754C_0 0x3168
#define PCI_DEVICE_ID_VIA_8235 0x3177
-#define PCI_DEVICE_ID_VIA_P4N333 0x3178
#define PCI_DEVICE_ID_VIA_8385_0 0x3188
#define PCI_DEVICE_ID_VIA_8377_0 0x3189
#define PCI_DEVICE_ID_VIA_8378_0 0x3205
#define PCI_DEVICE_ID_VIA_8783_0 0x3208
-#define PCI_DEVICE_ID_VIA_P4M400 0x3209
#define PCI_DEVICE_ID_VIA_8237 0x3227
#define PCI_DEVICE_ID_VIA_3296_0 0x0296
-#define PCI_DEVICE_ID_VIA_86C100A 0x6100
#define PCI_DEVICE_ID_VIA_8231 0x8231
#define PCI_DEVICE_ID_VIA_8231_4 0x8235
#define PCI_DEVICE_ID_VIA_8365_1 0x8305
#define PCI_DEVICE_ID_VIA_8371_1 0x8391
-#define PCI_DEVICE_ID_VIA_8501_1 0x8501
-#define PCI_DEVICE_ID_VIA_82C597_1 0x8597
#define PCI_DEVICE_ID_VIA_82C598_1 0x8598
-#define PCI_DEVICE_ID_VIA_8601_1 0x8601
-#define PCI_DEVICE_ID_VIA_8505_1 0x8605
-#define PCI_DEVICE_ID_VIA_8633_1 0xB091
-#define PCI_DEVICE_ID_VIA_8367_1 0xB099
-#define PCI_DEVICE_ID_VIA_P4X266_1 0xB101
-#define PCI_DEVICE_ID_VIA_8615_1 0xB103
-#define PCI_DEVICE_ID_VIA_8361_1 0xB112
-#define PCI_DEVICE_ID_VIA_8235_1 0xB168
#define PCI_DEVICE_ID_VIA_838X_1 0xB188
#define PCI_DEVICE_ID_VIA_83_87XX_1 0xB198
#define PCI_VENDOR_ID_SIEMENS 0x110A
#define PCI_DEVICE_ID_SIEMENS_DSCC4 0x2102
-#define PCI_VENDOR_ID_SMC2 0x1113
-#define PCI_DEVICE_ID_SMC2_1211TX 0x1211
#define PCI_VENDOR_ID_VORTEX 0x1119
#define PCI_DEVICE_ID_VORTEX_GDT60x0 0x0000
@@ -1509,18 +1270,6 @@
#define PCI_DEVICE_ID_VORTEX_GDT6557RP 0x0103
#define PCI_DEVICE_ID_VORTEX_GDT6x11RP 0x0104
#define PCI_DEVICE_ID_VORTEX_GDT6x21RP 0x0105
-#define PCI_DEVICE_ID_VORTEX_GDT6x17RP1 0x0110
-#define PCI_DEVICE_ID_VORTEX_GDT6x27RP1 0x0111
-#define PCI_DEVICE_ID_VORTEX_GDT6537RP1 0x0112
-#define PCI_DEVICE_ID_VORTEX_GDT6557RP1 0x0113
-#define PCI_DEVICE_ID_VORTEX_GDT6x11RP1 0x0114
-#define PCI_DEVICE_ID_VORTEX_GDT6x21RP1 0x0115
-#define PCI_DEVICE_ID_VORTEX_GDT6x17RP2 0x0120
-#define PCI_DEVICE_ID_VORTEX_GDT6x27RP2 0x0121
-#define PCI_DEVICE_ID_VORTEX_GDT6537RP2 0x0122
-#define PCI_DEVICE_ID_VORTEX_GDT6557RP2 0x0123
-#define PCI_DEVICE_ID_VORTEX_GDT6x11RP2 0x0124
-#define PCI_DEVICE_ID_VORTEX_GDT6x21RP2 0x0125
#define PCI_VENDOR_ID_EF 0x111a
#define PCI_DEVICE_ID_EF_ATM_FPGA 0x0000
@@ -1532,21 +1281,15 @@
#define PCI_DEVICE_ID_IDT_IDT77201 0x0001
#define PCI_VENDOR_ID_FORE 0x1127
-#define PCI_DEVICE_ID_FORE_PCA200PC 0x0210
#define PCI_DEVICE_ID_FORE_PCA200E 0x0300
-#define PCI_VENDOR_ID_IMAGINGTECH 0x112f
-#define PCI_DEVICE_ID_IMAGINGTECH_ICPCI 0x0000
#define PCI_VENDOR_ID_PHILIPS 0x1131
-#define PCI_DEVICE_ID_PHILIPS_SAA7145 0x7145
#define PCI_DEVICE_ID_PHILIPS_SAA7146 0x7146
#define PCI_DEVICE_ID_PHILIPS_SAA9730 0x9730
#define PCI_VENDOR_ID_EICON 0x1133
-#define PCI_DEVICE_ID_EICON_DIVA20PRO 0xe001
#define PCI_DEVICE_ID_EICON_DIVA20 0xe002
-#define PCI_DEVICE_ID_EICON_DIVA20PRO_U 0xe003
#define PCI_DEVICE_ID_EICON_DIVA20_U 0xe004
#define PCI_DEVICE_ID_EICON_DIVA201 0xe005
#define PCI_DEVICE_ID_EICON_DIVA202 0xe00b
@@ -1558,35 +1301,17 @@
#define PCI_VENDOR_ID_ZIATECH 0x1138
#define PCI_DEVICE_ID_ZIATECH_5550_HC 0x5550
-#define PCI_VENDOR_ID_CYCLONE 0x113c
-#define PCI_DEVICE_ID_CYCLONE_SDK 0x0001
-#define PCI_VENDOR_ID_ALLIANCE 0x1142
-#define PCI_DEVICE_ID_ALLIANCE_PROMOTIO 0x3210
-#define PCI_DEVICE_ID_ALLIANCE_PROVIDEO 0x6422
-#define PCI_DEVICE_ID_ALLIANCE_AT24 0x6424
-#define PCI_DEVICE_ID_ALLIANCE_AT3D 0x643d
#define PCI_VENDOR_ID_SYSKONNECT 0x1148
-#define PCI_DEVICE_ID_SYSKONNECT_FP 0x4000
#define PCI_DEVICE_ID_SYSKONNECT_TR 0x4200
#define PCI_DEVICE_ID_SYSKONNECT_GE 0x4300
#define PCI_DEVICE_ID_SYSKONNECT_YU 0x4320
#define PCI_DEVICE_ID_SYSKONNECT_9DXX 0x4400
#define PCI_DEVICE_ID_SYSKONNECT_9MXX 0x4500
-#define PCI_VENDOR_ID_VMIC 0x114a
-#define PCI_DEVICE_ID_VMIC_VME 0x7587
#define PCI_VENDOR_ID_DIGI 0x114f
-#define PCI_DEVICE_ID_DIGI_EPC 0x0002
-#define PCI_DEVICE_ID_DIGI_RIGHTSWITCH 0x0003
-#define PCI_DEVICE_ID_DIGI_XEM 0x0004
-#define PCI_DEVICE_ID_DIGI_XR 0x0005
-#define PCI_DEVICE_ID_DIGI_CX 0x0006
-#define PCI_DEVICE_ID_DIGI_XRJ 0x0009
-#define PCI_DEVICE_ID_DIGI_EPCJ 0x000a
-#define PCI_DEVICE_ID_DIGI_XR_920 0x0027
#define PCI_DEVICE_ID_DIGI_DF_M_IOM2_E 0x0070
#define PCI_DEVICE_ID_DIGI_DF_M_E 0x0071
#define PCI_DEVICE_ID_DIGI_DF_M_IOM2_A 0x0072
@@ -1596,23 +1321,15 @@
#define PCI_DEVICE_ID_NEO_2RJ45 0x00CA
#define PCI_DEVICE_ID_NEO_2RJ45PRI 0x00CB
-#define PCI_VENDOR_ID_MUTECH 0x1159
-#define PCI_DEVICE_ID_MUTECH_MV1000 0x0001
#define PCI_VENDOR_ID_XIRCOM 0x115d
-#define PCI_DEVICE_ID_XIRCOM_X3201_ETH 0x0003
#define PCI_DEVICE_ID_XIRCOM_RBM56G 0x0101
#define PCI_DEVICE_ID_XIRCOM_X3201_MDM 0x0103
-#define PCI_VENDOR_ID_RENDITION 0x1163
-#define PCI_DEVICE_ID_RENDITION_VERITE 0x0001
-#define PCI_DEVICE_ID_RENDITION_VERITE2100 0x2000
#define PCI_VENDOR_ID_SERVERWORKS 0x1166
#define PCI_DEVICE_ID_SERVERWORKS_HE 0x0008
#define PCI_DEVICE_ID_SERVERWORKS_LE 0x0009
-#define PCI_DEVICE_ID_SERVERWORKS_CIOB30 0x0010
-#define PCI_DEVICE_ID_SERVERWORKS_CMIC_HE 0x0011
#define PCI_DEVICE_ID_SERVERWORKS_GCNB_LE 0x0017
#define PCI_DEVICE_ID_SERVERWORKS_OSB4 0x0200
#define PCI_DEVICE_ID_SERVERWORKS_CSB5 0x0201
@@ -1622,13 +1339,7 @@
#define PCI_DEVICE_ID_SERVERWORKS_CSB6IDE 0x0213
#define PCI_DEVICE_ID_SERVERWORKS_HT1000IDE 0x0214
#define PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2 0x0217
-#define PCI_DEVICE_ID_SERVERWORKS_OSB4USB 0x0220
-#define PCI_DEVICE_ID_SERVERWORKS_CSB5USB PCI_DEVICE_ID_SERVERWORKS_OSB4USB
-#define PCI_DEVICE_ID_SERVERWORKS_CSB6USB 0x0221
#define PCI_DEVICE_ID_SERVERWORKS_CSB6LPC 0x0227
-#define PCI_DEVICE_ID_SERVERWORKS_GCLE 0x0225
-#define PCI_DEVICE_ID_SERVERWORKS_GCLE2 0x0227
-#define PCI_DEVICE_ID_SERVERWORKS_CSB5ISA 0x0230
#define PCI_VENDOR_ID_SBE 0x1176
#define PCI_DEVICE_ID_SBE_WANXL100 0x0301
@@ -1639,17 +1350,12 @@
#define PCI_DEVICE_ID_TOSHIBA_PICCOLO 0x0102
#define PCI_DEVICE_ID_TOSHIBA_PICCOLO_1 0x0103
#define PCI_DEVICE_ID_TOSHIBA_PICCOLO_2 0x0105
-#define PCI_DEVICE_ID_TOSHIBA_601 0x0601
#define PCI_DEVICE_ID_TOSHIBA_TOPIC95 0x060a
-#define PCI_DEVICE_ID_TOSHIBA_TOPIC95_A 0x0603
-#define PCI_DEVICE_ID_TOSHIBA_TOPIC95_B 0x060a
#define PCI_DEVICE_ID_TOSHIBA_TOPIC97 0x060f
#define PCI_DEVICE_ID_TOSHIBA_TOPIC100 0x0617
#define PCI_VENDOR_ID_TOSHIBA_2 0x102f
-#define PCI_DEVICE_ID_TOSHIBA_TX3927 0x000a
#define PCI_DEVICE_ID_TOSHIBA_TC35815CF 0x0030
-#define PCI_DEVICE_ID_TOSHIBA_TX4927 0x0180
#define PCI_DEVICE_ID_TOSHIBA_TC86C001_MISC 0x0108
#define PCI_DEVICE_ID_TOSHIBA_SPIDER_NET 0x01b3
@@ -1664,7 +1370,6 @@
#define PCI_DEVICE_ID_DLINK_DGE510T 0x4c00
#define PCI_VENDOR_ID_ARTOP 0x1191
-#define PCI_DEVICE_ID_ARTOP_ATP8400 0x0004
#define PCI_DEVICE_ID_ARTOP_ATP850UF 0x0005
#define PCI_DEVICE_ID_ARTOP_ATP860 0x0006
#define PCI_DEVICE_ID_ARTOP_ATP860R 0x0007
@@ -1677,16 +1382,11 @@
#define PCI_DEVICE_ID_ARTOP_AEC7612D 0x8040
#define PCI_DEVICE_ID_ARTOP_AEC7612SUW 0x8050
#define PCI_DEVICE_ID_ARTOP_8060 0x8060
-#define PCI_DEVICE_ID_ARTOP_AEC67160 0x8080
-#define PCI_DEVICE_ID_ARTOP_AEC67160_2 0x8081
-#define PCI_DEVICE_ID_ARTOP_AEC67162 0x808a
#define PCI_VENDOR_ID_ZEITNET 0x1193
#define PCI_DEVICE_ID_ZEITNET_1221 0x0001
#define PCI_DEVICE_ID_ZEITNET_1225 0x0002
-#define PCI_VENDOR_ID_OMEGA 0x119b
-#define PCI_DEVICE_ID_OMEGA_82C092G 0x1221
#define PCI_VENDOR_ID_FUJITSU_ME 0x119e
#define PCI_DEVICE_ID_FUJITSU_FS155 0x0001
@@ -1696,61 +1396,41 @@
#define PCI_SUBDEVICE_ID_KEYSPAN_SX2 0x5334
#define PCI_VENDOR_ID_MARVELL 0x11ab
-#define PCI_DEVICE_ID_MARVELL_GT64011 0x4146
-#define PCI_DEVICE_ID_MARVELL_GT64111 0x4146
#define PCI_DEVICE_ID_MARVELL_GT64260 0x6430
#define PCI_DEVICE_ID_MARVELL_MV64360 0x6460
#define PCI_DEVICE_ID_MARVELL_MV64460 0x6480
#define PCI_DEVICE_ID_MARVELL_GT96100 0x9652
#define PCI_DEVICE_ID_MARVELL_GT96100A 0x9653
-#define PCI_VENDOR_ID_LITEON 0x11ad
-#define PCI_DEVICE_ID_LITEON_LNE100TX 0x0002
#define PCI_VENDOR_ID_V3 0x11b0
#define PCI_DEVICE_ID_V3_V960 0x0001
-#define PCI_DEVICE_ID_V3_V350 0x0001
-#define PCI_DEVICE_ID_V3_V961 0x0002
#define PCI_DEVICE_ID_V3_V351 0x0002
-#define PCI_VENDOR_ID_NP 0x11bc
-#define PCI_DEVICE_ID_NP_PCI_FDDI 0x0001
#define PCI_VENDOR_ID_ATT 0x11c1
-#define PCI_DEVICE_ID_ATT_L56XMF 0x0440
#define PCI_DEVICE_ID_ATT_VENUS_MODEM 0x480
-#define PCI_VENDOR_ID_NEC2 0x11c3 /* NEC (2nd) */
#define PCI_VENDOR_ID_SPECIALIX 0x11cb
#define PCI_DEVICE_ID_SPECIALIX_IO8 0x2000
-#define PCI_DEVICE_ID_SPECIALIX_XIO 0x4000
#define PCI_DEVICE_ID_SPECIALIX_RIO 0x8000
#define PCI_SUBDEVICE_ID_SPECIALIX_SPEED4 0xa004
-#define PCI_VENDOR_ID_AURAVISION 0x11d1
-#define PCI_DEVICE_ID_AURAVISION_VXP524 0x01f7
#define PCI_VENDOR_ID_ANALOG_DEVICES 0x11d4
#define PCI_DEVICE_ID_AD1889JS 0x1889
-#define PCI_VENDOR_ID_IKON 0x11d5
-#define PCI_DEVICE_ID_IKON_10115 0x0115
-#define PCI_DEVICE_ID_IKON_10117 0x0117
-#define PCI_VENDOR_ID_SEGA 0x11db
#define PCI_DEVICE_ID_SEGA_BBA 0x1234
#define PCI_VENDOR_ID_ZORAN 0x11de
#define PCI_DEVICE_ID_ZORAN_36057 0x6057
#define PCI_DEVICE_ID_ZORAN_36120 0x6120
-#define PCI_VENDOR_ID_KINETIC 0x11f4
-#define PCI_DEVICE_ID_KINETIC_2915 0x2915
#define PCI_VENDOR_ID_COMPEX 0x11f6
#define PCI_DEVICE_ID_COMPEX_ENET100VG4 0x0112
-#define PCI_DEVICE_ID_COMPEX_RL2000 0x1401
#define PCI_VENDOR_ID_RP 0x11fe
#define PCI_DEVICE_ID_RP32INTF 0x0001
@@ -1764,7 +1444,6 @@
#define PCI_DEVICE_ID_RP16SNI 0x0009
#define PCI_DEVICE_ID_RPP4 0x000A
#define PCI_DEVICE_ID_RPP8 0x000B
-#define PCI_DEVICE_ID_RP8M 0x000C
#define PCI_DEVICE_ID_RP4M 0x000D
#define PCI_DEVICE_ID_RP2_232 0x000E
#define PCI_DEVICE_ID_RP2_422 0x000F
@@ -1792,10 +1471,6 @@
#define PCI_DEVICE_ID_PC300_TE_M_2 0x0320
#define PCI_DEVICE_ID_PC300_TE_M_1 0x0321
-/* Allied Telesyn */
-#define PCI_VENDOR_ID_AT 0x1259
-#define PCI_SUBDEVICE_ID_AT_2701FX 0x2703
-
#define PCI_VENDOR_ID_ESSENTIAL 0x120f
#define PCI_DEVICE_ID_ESSENTIAL_ROADRUNNER 0x0001
@@ -1812,10 +1487,7 @@
#define PCI_DEVICE_ID_3DFX_VOODOO3 0x0005
#define PCI_DEVICE_ID_3DFX_VOODOO5 0x0009
-#define PCI_VENDOR_ID_SIGMADES 0x1236
-#define PCI_DEVICE_ID_SIGMADES_6425 0x6401
-#define PCI_VENDOR_ID_CCUBE 0x123f
#define PCI_VENDOR_ID_AVM 0x1244
#define PCI_DEVICE_ID_AVM_B1 0x0700
@@ -1825,19 +1497,8 @@
#define PCI_DEVICE_ID_AVM_C2 0x1100
#define PCI_DEVICE_ID_AVM_T1 0x1200
-#define PCI_VENDOR_ID_DIPIX 0x1246
#define PCI_VENDOR_ID_STALLION 0x124d
-#define PCI_DEVICE_ID_STALLION_ECHPCI832 0x0000
-#define PCI_DEVICE_ID_STALLION_ECHPCI864 0x0002
-#define PCI_DEVICE_ID_STALLION_EIOPCI 0x0003
-
-#define PCI_VENDOR_ID_OPTIBASE 0x1255
-#define PCI_DEVICE_ID_OPTIBASE_FORGE 0x1110
-#define PCI_DEVICE_ID_OPTIBASE_FUSION 0x1210
-#define PCI_DEVICE_ID_OPTIBASE_VPLEX 0x2110
-#define PCI_DEVICE_ID_OPTIBASE_VPLEXCC 0x2120
-#define PCI_DEVICE_ID_OPTIBASE_VQUEST 0x2130
/* Allied Telesyn */
#define PCI_VENDOR_ID_AT 0x1259
@@ -1846,7 +1507,6 @@
#define PCI_VENDOR_ID_ESS 0x125d
#define PCI_DEVICE_ID_ESS_ESS1968 0x1968
-#define PCI_DEVICE_ID_ESS_AUDIOPCI 0x1969
#define PCI_DEVICE_ID_ESS_ESS1978 0x1978
#define PCI_DEVICE_ID_ESS_ALLEGRO_1 0x1988
#define PCI_DEVICE_ID_ESS_ALLEGRO 0x1989
@@ -1859,11 +1519,7 @@
#define PCI_VENDOR_ID_SATSAGEM 0x1267
#define PCI_DEVICE_ID_SATSAGEM_NICCY 0x1016
-#define PCI_DEVICE_ID_SATSAGEM_PCR2101 0x5352
-#define PCI_DEVICE_ID_SATSAGEM_TELSATTURBO 0x5a4b
-#define PCI_VENDOR_ID_HUGHES 0x1273
-#define PCI_DEVICE_ID_HUGHES_DIRECPC 0x0002
#define PCI_VENDOR_ID_ENSONIQ 0x1274
#define PCI_DEVICE_ID_ENSONIQ_CT5880 0x5880
@@ -1884,13 +1540,10 @@
#define PCI_DEVICE_ID_ITE_IT8330G_0 0xe886
/* formerly Platform Tech */
-#define PCI_VENDOR_ID_ESS_OLD 0x1285
#define PCI_DEVICE_ID_ESS_ESS0100 0x0100
#define PCI_VENDOR_ID_ALTEON 0x12ae
-#define PCI_DEVICE_ID_ALTEON_ACENIC 0x0001
-#define PCI_VENDOR_ID_USR 0x12B9
#define PCI_SUBVENDOR_ID_CONNECT_TECH 0x12c4
#define PCI_SUBDEVICE_ID_CONNECT_TECH_BH8_232 0x0001
@@ -1905,8 +1558,6 @@
#define PCI_SUBDEVICE_ID_CONNECT_TECH_BH081101V1 0x000A
#define PCI_SUBDEVICE_ID_CONNECT_TECH_BH041101V1 0x000B
-#define PCI_VENDOR_ID_PICTUREL 0x12c5
-#define PCI_DEVICE_ID_PICTUREL_PCIVST 0x0081
#define PCI_VENDOR_ID_NVIDIA_SGS 0x12d2
#define PCI_DEVICE_ID_NVIDIA_SGS_RIVA128 0x0018
@@ -1928,8 +1579,6 @@
#define PCI_VENDOR_ID_ELECTRONICDESIGNGMBH 0x12f8
#define PCI_DEVICE_ID_LML_33R10 0x8a02
-#define PCI_VENDOR_ID_CBOARDS 0x1307
-#define PCI_DEVICE_ID_CBOARDS_DAS1602_16 0x0001
#define PCI_VENDOR_ID_SIIG 0x131f
#define PCI_SUBVENDOR_ID_SIIG 0x131f
@@ -1973,7 +1622,6 @@
#define PCI_SUBDEVICE_ID_SIIG_QUARTET_SERIAL 0x2050
#define PCI_VENDOR_ID_RADISYS 0x1331
-#define PCI_DEVICE_ID_RADISYS_ENP2611 0x0030
#define PCI_VENDOR_ID_DOMEX 0x134a
#define PCI_DEVICE_ID_DOMEX_DMX3191D 0x0001
@@ -1981,8 +1629,6 @@
#define PCI_VENDOR_ID_QUATECH 0x135C
#define PCI_DEVICE_ID_QUATECH_QSC100 0x0010
#define PCI_DEVICE_ID_QUATECH_DSC100 0x0020
-#define PCI_DEVICE_ID_QUATECH_DSC200 0x0030
-#define PCI_DEVICE_ID_QUATECH_QSC200 0x0040
#define PCI_DEVICE_ID_QUATECH_ESC100D 0x0050
#define PCI_DEVICE_ID_QUATECH_ESC100M 0x0060
@@ -2001,7 +1647,6 @@
#define PCI_SUBDEVICE_ID_HYPERCOPE_ERGO 0x0106
#define PCI_SUBDEVICE_ID_HYPERCOPE_METRO 0x0107
#define PCI_SUBDEVICE_ID_HYPERCOPE_CHAMP2 0x0108
-#define PCI_SUBDEVICE_ID_HYPERCOPE_PLEXUS 0x0109
#define PCI_VENDOR_ID_KAWASAKI 0x136b
#define PCI_DEVICE_ID_MCHIP_KL5A72002 0xff01
@@ -2015,12 +1660,9 @@
#define PCI_DEVICE_ID_LMC_SSI 0x0005
#define PCI_DEVICE_ID_LMC_T1 0x0006
-#define PCI_VENDOR_ID_MARIAN 0x1382
-#define PCI_DEVICE_ID_MARIAN_PRODIF_PLUS 0x2048
#define PCI_VENDOR_ID_NETGEAR 0x1385
#define PCI_DEVICE_ID_NETGEAR_GA620 0x620a
-#define PCI_DEVICE_ID_NETGEAR_GA622 0x622a
#define PCI_VENDOR_ID_APPLICOM 0x1389
#define PCI_DEVICE_ID_APPLICOM_PCIGENERIC 0x0001
@@ -2043,9 +1685,6 @@
#define PCI_DEVICE_ID_MOXA_CP134U 0x1340
#define PCI_DEVICE_ID_MOXA_C168 0x1680
#define PCI_DEVICE_ID_MOXA_CP168U 0x1681
-#define PCI_DEVICE_ID_MOXA_CP204J 0x2040
-#define PCI_DEVICE_ID_MOXA_C218 0x2180
-#define PCI_DEVICE_ID_MOXA_C320 0x3200
#define PCI_VENDOR_ID_CCD 0x1397
#define PCI_DEVICE_ID_CCD_2BD0 0x2bd0
@@ -2066,9 +1705,7 @@
#define PCI_VENDOR_ID_MICROGATE 0x13c0
#define PCI_DEVICE_ID_MICROGATE_USC 0x0010
-#define PCI_DEVICE_ID_MICROGATE_SCC 0x0020
#define PCI_DEVICE_ID_MICROGATE_SCA 0x0030
-#define PCI_DEVICE_ID_MICROGATE_USC2 0x0210
#define PCI_VENDOR_ID_3WARE 0x13C1
#define PCI_DEVICE_ID_3WARE_1000 0x1000
@@ -2119,10 +1756,6 @@
#define PCI_VENDOR_ID_SAMSUNG 0x144d
-#define PCI_VENDOR_ID_AIRONET 0x14b9
-#define PCI_DEVICE_ID_AIRONET_4800_1 0x0001
-#define PCI_DEVICE_ID_AIRONET_4800 0x4500 // values switched? see
-#define PCI_DEVICE_ID_AIRONET_4500 0x4800 // drivers/net/aironet4500_card.c
#define PCI_VENDOR_ID_TITAN 0x14D2
#define PCI_DEVICE_ID_TITAN_010L 0x8001
@@ -2141,8 +1774,6 @@
#define PCI_DEVICE_ID_PANACOM_QUADMODEM 0x0400
#define PCI_DEVICE_ID_PANACOM_DUALMODEM 0x0402
-#define PCI_VENDOR_ID_SIPACKETS 0x14d9
-#define PCI_DEVICE_ID_SP_HT 0x0010
#define PCI_VENDOR_ID_AFAVLAB 0x14db
#define PCI_DEVICE_ID_AFAVLAB_P028 0x2180
@@ -2158,6 +1789,7 @@
#define PCI_DEVICE_ID_TIGON3_5704 0x1648
#define PCI_DEVICE_ID_TIGON3_5704S_2 0x1649
#define PCI_DEVICE_ID_NX2_5706 0x164a
+#define PCI_DEVICE_ID_NX2_5708 0x164c
#define PCI_DEVICE_ID_TIGON3_5702FE 0x164d
#define PCI_DEVICE_ID_TIGON3_5705 0x1653
#define PCI_DEVICE_ID_TIGON3_5705_2 0x1654
@@ -2165,11 +1797,13 @@
#define PCI_DEVICE_ID_TIGON3_5721 0x1659
#define PCI_DEVICE_ID_TIGON3_5705M 0x165d
#define PCI_DEVICE_ID_TIGON3_5705M_2 0x165e
+#define PCI_DEVICE_ID_TIGON3_5714 0x1668
#define PCI_DEVICE_ID_TIGON3_5780 0x166a
#define PCI_DEVICE_ID_TIGON3_5780S 0x166b
#define PCI_DEVICE_ID_TIGON3_5705F 0x166e
#define PCI_DEVICE_ID_TIGON3_5750 0x1676
#define PCI_DEVICE_ID_TIGON3_5751 0x1677
+#define PCI_DEVICE_ID_TIGON3_5715 0x1678
#define PCI_DEVICE_ID_TIGON3_5750M 0x167c
#define PCI_DEVICE_ID_TIGON3_5751M 0x167d
#define PCI_DEVICE_ID_TIGON3_5751F 0x167e
@@ -2180,6 +1814,7 @@
#define PCI_DEVICE_ID_TIGON3_5703X 0x16a7
#define PCI_DEVICE_ID_TIGON3_5704S 0x16a8
#define PCI_DEVICE_ID_NX2_5706S 0x16aa
+#define PCI_DEVICE_ID_NX2_5708S 0x16ac
#define PCI_DEVICE_ID_TIGON3_5702A3 0x16c6
#define PCI_DEVICE_ID_TIGON3_5703A3 0x16c7
#define PCI_DEVICE_ID_TIGON3_5781 0x16dd
@@ -2207,8 +1842,6 @@
#define PCI_VENDOR_ID_CHELSIO 0x1425
-#define PCI_VENDOR_ID_MIPS 0x153f
-#define PCI_DEVICE_ID_SOC_IT 0x0001
#define PCI_VENDOR_ID_SYBA 0x1592
#define PCI_DEVICE_ID_SYBA_2P_EPP 0x0782
@@ -2228,15 +1861,7 @@
#define PCI_DEVICE_ID_MELLANOX_SINAI 0x6274
#define PCI_VENDOR_ID_PDC 0x15e9
-#define PCI_DEVICE_ID_PDC_1841 0x1841
-#define PCI_VENDOR_ID_MACROLINK 0x15ed
-#define PCI_DEVICE_ID_MACROLINK_MCCS8 0x1000
-#define PCI_DEVICE_ID_MACROLINK_MCCS 0x1001
-#define PCI_DEVICE_ID_MACROLINK_MCCS8H 0x1002
-#define PCI_DEVICE_ID_MACROLINK_MCCSH 0x1003
-#define PCI_DEVICE_ID_MACROLINK_MCCR8 0x2000
-#define PCI_DEVICE_ID_MACROLINK_MCCR 0x2001
#define PCI_VENDOR_ID_FARSITE 0x1619
#define PCI_DEVICE_ID_FARSITE_T2P 0x0400
@@ -2254,7 +1879,6 @@
#define PCI_DEVICE_ID_REVOLUTION 0x0044
#define PCI_VENDOR_ID_LINKSYS 0x1737
-#define PCI_DEVICE_ID_LINKSYS_EG1032 0x1032
#define PCI_DEVICE_ID_LINKSYS_EG1064 0x1064
#define PCI_VENDOR_ID_ALTIMA 0x173b
@@ -2269,7 +1893,6 @@
#define PCI_DEVICE_ID_HERC_WIN 0x5732
#define PCI_DEVICE_ID_HERC_UNI 0x5832
-#define PCI_VENDOR_ID_INFINICON 0x1820
#define PCI_VENDOR_ID_SITECOM 0x182d
#define PCI_DEVICE_ID_SITECOM_DC105V2 0x3069
@@ -2279,8 +1902,6 @@
#define PCI_VENDOR_ID_TDI 0x192E
#define PCI_DEVICE_ID_TDI_EHCI 0x0101
-#define PCI_VENDOR_ID_SYMPHONY 0x1c1c
-#define PCI_DEVICE_ID_SYMPHONY_101 0x0001
#define PCI_VENDOR_ID_TEKRAM 0x1de1
#define PCI_DEVICE_ID_TEKRAM_DC290 0xdc29
@@ -2289,70 +1910,33 @@
#define PCI_DEVICE_ID_HINT_VXPROII_IDE 0x8013
#define PCI_VENDOR_ID_3DLABS 0x3d3d
-#define PCI_DEVICE_ID_3DLABS_300SX 0x0001
-#define PCI_DEVICE_ID_3DLABS_500TX 0x0002
-#define PCI_DEVICE_ID_3DLABS_DELTA 0x0003
-#define PCI_DEVICE_ID_3DLABS_PERMEDIA 0x0004
-#define PCI_DEVICE_ID_3DLABS_MX 0x0006
#define PCI_DEVICE_ID_3DLABS_PERMEDIA2 0x0007
-#define PCI_DEVICE_ID_3DLABS_GAMMA 0x0008
#define PCI_DEVICE_ID_3DLABS_PERMEDIA2V 0x0009
-#define PCI_VENDOR_ID_AVANCE 0x4005
-#define PCI_DEVICE_ID_AVANCE_ALG2064 0x2064
-#define PCI_DEVICE_ID_AVANCE_2302 0x2302
#define PCI_VENDOR_ID_AKS 0x416c
#define PCI_DEVICE_ID_AKS_ALADDINCARD 0x0100
-#define PCI_DEVICE_ID_AKS_CPC 0x0200
-#define PCI_VENDOR_ID_REDCREEK 0x4916
-#define PCI_DEVICE_ID_RC45 0x1960
-#define PCI_VENDOR_ID_NETVIN 0x4a14
-#define PCI_DEVICE_ID_NETVIN_NV5000SC 0x5000
#define PCI_VENDOR_ID_S3 0x5333
-#define PCI_DEVICE_ID_S3_PLATO_PXS 0x0551
-#define PCI_DEVICE_ID_S3_ViRGE 0x5631
#define PCI_DEVICE_ID_S3_TRIO 0x8811
-#define PCI_DEVICE_ID_S3_AURORA64VP 0x8812
-#define PCI_DEVICE_ID_S3_TRIO64UVP 0x8814
-#define PCI_DEVICE_ID_S3_ViRGE_VX 0x883d
#define PCI_DEVICE_ID_S3_868 0x8880
-#define PCI_DEVICE_ID_S3_928 0x88b0
-#define PCI_DEVICE_ID_S3_864_1 0x88c0
-#define PCI_DEVICE_ID_S3_864_2 0x88c1
-#define PCI_DEVICE_ID_S3_964_1 0x88d0
-#define PCI_DEVICE_ID_S3_964_2 0x88d1
#define PCI_DEVICE_ID_S3_968 0x88f0
-#define PCI_DEVICE_ID_S3_TRIO64V2 0x8901
-#define PCI_DEVICE_ID_S3_PLATO_PXG 0x8902
-#define PCI_DEVICE_ID_S3_ViRGE_DXGX 0x8a01
-#define PCI_DEVICE_ID_S3_ViRGE_GX2 0x8a10
#define PCI_DEVICE_ID_S3_SAVAGE4 0x8a25
-#define PCI_DEVICE_ID_S3_ViRGE_MX 0x8c01
-#define PCI_DEVICE_ID_S3_ViRGE_MXP 0x8c02
-#define PCI_DEVICE_ID_S3_ViRGE_MXPMV 0x8c03
#define PCI_DEVICE_ID_S3_PROSAVAGE8 0x8d04
#define PCI_DEVICE_ID_S3_SONICVIBES 0xca00
#define PCI_VENDOR_ID_DUNORD 0x5544
#define PCI_DEVICE_ID_DUNORD_I3000 0x0001
+
#define PCI_VENDOR_ID_DCI 0x6666
#define PCI_DEVICE_ID_DCI_PCCOM4 0x0001
#define PCI_DEVICE_ID_DCI_PCCOM8 0x0002
-#define PCI_VENDOR_ID_DUNORD 0x5544
-#define PCI_DEVICE_ID_DUNORD_I3000 0x0001
-
-#define PCI_VENDOR_ID_GENROCO 0x5555
-#define PCI_DEVICE_ID_GENROCO_HFP832 0x0003
-
#define PCI_VENDOR_ID_INTEL 0x8086
#define PCI_DEVICE_ID_INTEL_EESSC 0x0008
-#define PCI_DEVICE_ID_INTEL_21145 0x0039
#define PCI_DEVICE_ID_INTEL_PXHD_0 0x0320
#define PCI_DEVICE_ID_INTEL_PXHD_1 0x0321
#define PCI_DEVICE_ID_INTEL_PXH_0 0x0329
@@ -2361,30 +1945,17 @@
#define PCI_DEVICE_ID_INTEL_82375 0x0482
#define PCI_DEVICE_ID_INTEL_82424 0x0483
#define PCI_DEVICE_ID_INTEL_82378 0x0484
-#define PCI_DEVICE_ID_INTEL_82430 0x0486
-#define PCI_DEVICE_ID_INTEL_82434 0x04a3
#define PCI_DEVICE_ID_INTEL_I960 0x0960
#define PCI_DEVICE_ID_INTEL_I960RM 0x0962
-#define PCI_DEVICE_ID_INTEL_82562ET 0x1031
-#define PCI_DEVICE_ID_INTEL_82801CAM 0x1038
#define PCI_DEVICE_ID_INTEL_82815_MC 0x1130
-#define PCI_DEVICE_ID_INTEL_82815_AB 0x1131
#define PCI_DEVICE_ID_INTEL_82815_CGC 0x1132
-#define PCI_DEVICE_ID_INTEL_82559ER 0x1209
#define PCI_DEVICE_ID_INTEL_82092AA_0 0x1221
-#define PCI_DEVICE_ID_INTEL_82092AA_1 0x1222
-#define PCI_DEVICE_ID_INTEL_7116 0x1223
#define PCI_DEVICE_ID_INTEL_7505_0 0x2550
-#define PCI_DEVICE_ID_INTEL_7505_1 0x2552
#define PCI_DEVICE_ID_INTEL_7205_0 0x255d
-#define PCI_DEVICE_ID_INTEL_82596 0x1226
-#define PCI_DEVICE_ID_INTEL_82865 0x1227
-#define PCI_DEVICE_ID_INTEL_82557 0x1229
#define PCI_DEVICE_ID_INTEL_82437 0x122d
#define PCI_DEVICE_ID_INTEL_82371FB_0 0x122e
#define PCI_DEVICE_ID_INTEL_82371FB_1 0x1230
#define PCI_DEVICE_ID_INTEL_82371MX 0x1234
-#define PCI_DEVICE_ID_INTEL_82437MX 0x1235
#define PCI_DEVICE_ID_INTEL_82441 0x1237
#define PCI_DEVICE_ID_INTEL_82380FB 0x124b
#define PCI_DEVICE_ID_INTEL_82439 0x1250
@@ -2393,83 +1964,53 @@
#define PCI_DEVICE_ID_INTEL_82845_HB 0x1a30
#define PCI_DEVICE_ID_INTEL_82801AA_0 0x2410
#define PCI_DEVICE_ID_INTEL_82801AA_1 0x2411
-#define PCI_DEVICE_ID_INTEL_82801AA_2 0x2412
#define PCI_DEVICE_ID_INTEL_82801AA_3 0x2413
#define PCI_DEVICE_ID_INTEL_82801AA_5 0x2415
#define PCI_DEVICE_ID_INTEL_82801AA_6 0x2416
#define PCI_DEVICE_ID_INTEL_82801AA_8 0x2418
#define PCI_DEVICE_ID_INTEL_82801AB_0 0x2420
#define PCI_DEVICE_ID_INTEL_82801AB_1 0x2421
-#define PCI_DEVICE_ID_INTEL_82801AB_2 0x2422
#define PCI_DEVICE_ID_INTEL_82801AB_3 0x2423
#define PCI_DEVICE_ID_INTEL_82801AB_5 0x2425
#define PCI_DEVICE_ID_INTEL_82801AB_6 0x2426
#define PCI_DEVICE_ID_INTEL_82801AB_8 0x2428
#define PCI_DEVICE_ID_INTEL_82801BA_0 0x2440
-#define PCI_DEVICE_ID_INTEL_82801BA_1 0x2442
#define PCI_DEVICE_ID_INTEL_82801BA_2 0x2443
-#define PCI_DEVICE_ID_INTEL_82801BA_3 0x2444
#define PCI_DEVICE_ID_INTEL_82801BA_4 0x2445
-#define PCI_DEVICE_ID_INTEL_82801BA_5 0x2446
#define PCI_DEVICE_ID_INTEL_82801BA_6 0x2448
-#define PCI_DEVICE_ID_INTEL_82801BA_7 0x2449
#define PCI_DEVICE_ID_INTEL_82801BA_8 0x244a
#define PCI_DEVICE_ID_INTEL_82801BA_9 0x244b
#define PCI_DEVICE_ID_INTEL_82801BA_10 0x244c
#define PCI_DEVICE_ID_INTEL_82801BA_11 0x244e
#define PCI_DEVICE_ID_INTEL_82801E_0 0x2450
-#define PCI_DEVICE_ID_INTEL_82801E_2 0x2452
-#define PCI_DEVICE_ID_INTEL_82801E_3 0x2453
-#define PCI_DEVICE_ID_INTEL_82801E_9 0x2459
#define PCI_DEVICE_ID_INTEL_82801E_11 0x245b
-#define PCI_DEVICE_ID_INTEL_82801E_13 0x245d
-#define PCI_DEVICE_ID_INTEL_82801E_14 0x245e
#define PCI_DEVICE_ID_INTEL_82801CA_0 0x2480
-#define PCI_DEVICE_ID_INTEL_82801CA_2 0x2482
#define PCI_DEVICE_ID_INTEL_82801CA_3 0x2483
-#define PCI_DEVICE_ID_INTEL_82801CA_4 0x2484
#define PCI_DEVICE_ID_INTEL_82801CA_5 0x2485
#define PCI_DEVICE_ID_INTEL_82801CA_6 0x2486
-#define PCI_DEVICE_ID_INTEL_82801CA_7 0x2487
#define PCI_DEVICE_ID_INTEL_82801CA_10 0x248a
#define PCI_DEVICE_ID_INTEL_82801CA_11 0x248b
#define PCI_DEVICE_ID_INTEL_82801CA_12 0x248c
#define PCI_DEVICE_ID_INTEL_82801DB_0 0x24c0
#define PCI_DEVICE_ID_INTEL_82801DB_1 0x24c1
-#define PCI_DEVICE_ID_INTEL_82801DB_2 0x24c2
#define PCI_DEVICE_ID_INTEL_82801DB_3 0x24c3
-#define PCI_DEVICE_ID_INTEL_82801DB_4 0x24c4
#define PCI_DEVICE_ID_INTEL_82801DB_5 0x24c5
#define PCI_DEVICE_ID_INTEL_82801DB_6 0x24c6
-#define PCI_DEVICE_ID_INTEL_82801DB_7 0x24c7
#define PCI_DEVICE_ID_INTEL_82801DB_9 0x24c9
#define PCI_DEVICE_ID_INTEL_82801DB_10 0x24ca
#define PCI_DEVICE_ID_INTEL_82801DB_11 0x24cb
#define PCI_DEVICE_ID_INTEL_82801DB_12 0x24cc
-#define PCI_DEVICE_ID_INTEL_82801DB_13 0x24cd
#define PCI_DEVICE_ID_INTEL_82801EB_0 0x24d0
#define PCI_DEVICE_ID_INTEL_82801EB_1 0x24d1
-#define PCI_DEVICE_ID_INTEL_82801EB_2 0x24d2
#define PCI_DEVICE_ID_INTEL_82801EB_3 0x24d3
-#define PCI_DEVICE_ID_INTEL_82801EB_4 0x24d4
#define PCI_DEVICE_ID_INTEL_82801EB_5 0x24d5
#define PCI_DEVICE_ID_INTEL_82801EB_6 0x24d6
-#define PCI_DEVICE_ID_INTEL_82801EB_7 0x24d7
#define PCI_DEVICE_ID_INTEL_82801EB_11 0x24db
-#define PCI_DEVICE_ID_INTEL_82801EB_13 0x24dd
#define PCI_DEVICE_ID_INTEL_ESB_1 0x25a1
#define PCI_DEVICE_ID_INTEL_ESB_2 0x25a2
-#define PCI_DEVICE_ID_INTEL_ESB_3 0x25a3
-#define PCI_DEVICE_ID_INTEL_ESB_31 0x25b0
#define PCI_DEVICE_ID_INTEL_ESB_4 0x25a4
#define PCI_DEVICE_ID_INTEL_ESB_5 0x25a6
-#define PCI_DEVICE_ID_INTEL_ESB_6 0x25a7
-#define PCI_DEVICE_ID_INTEL_ESB_7 0x25a9
-#define PCI_DEVICE_ID_INTEL_ESB_8 0x25aa
#define PCI_DEVICE_ID_INTEL_ESB_9 0x25ab
-#define PCI_DEVICE_ID_INTEL_ESB_11 0x25ac
-#define PCI_DEVICE_ID_INTEL_ESB_12 0x25ad
-#define PCI_DEVICE_ID_INTEL_ESB_13 0x25ae
#define PCI_DEVICE_ID_INTEL_82820_HB 0x2500
#define PCI_DEVICE_ID_INTEL_82820_UP_HB 0x2501
#define PCI_DEVICE_ID_INTEL_82850_HB 0x2530
@@ -2479,7 +2020,6 @@
#define PCI_DEVICE_ID_INTEL_82865_HB 0x2570
#define PCI_DEVICE_ID_INTEL_82865_IG 0x2572
#define PCI_DEVICE_ID_INTEL_82875_HB 0x2578
-#define PCI_DEVICE_ID_INTEL_82875_IG 0x257b
#define PCI_DEVICE_ID_INTEL_82915G_HB 0x2580
#define PCI_DEVICE_ID_INTEL_82915G_IG 0x2582
#define PCI_DEVICE_ID_INTEL_82915GM_HB 0x2590
@@ -2489,80 +2029,23 @@
#define PCI_DEVICE_ID_INTEL_ICH6_0 0x2640
#define PCI_DEVICE_ID_INTEL_ICH6_1 0x2641
#define PCI_DEVICE_ID_INTEL_ICH6_2 0x2642
-#define PCI_DEVICE_ID_INTEL_ICH6_3 0x2651
-#define PCI_DEVICE_ID_INTEL_ICH6_4 0x2652
-#define PCI_DEVICE_ID_INTEL_ICH6_5 0x2653
-#define PCI_DEVICE_ID_INTEL_ICH6_6 0x2658
-#define PCI_DEVICE_ID_INTEL_ICH6_7 0x2659
-#define PCI_DEVICE_ID_INTEL_ICH6_8 0x265a
-#define PCI_DEVICE_ID_INTEL_ICH6_9 0x265b
-#define PCI_DEVICE_ID_INTEL_ICH6_10 0x265c
-#define PCI_DEVICE_ID_INTEL_ICH6_11 0x2660
-#define PCI_DEVICE_ID_INTEL_ICH6_12 0x2662
-#define PCI_DEVICE_ID_INTEL_ICH6_13 0x2664
-#define PCI_DEVICE_ID_INTEL_ICH6_14 0x2666
-#define PCI_DEVICE_ID_INTEL_ICH6_15 0x2668
#define PCI_DEVICE_ID_INTEL_ICH6_16 0x266a
#define PCI_DEVICE_ID_INTEL_ICH6_17 0x266d
#define PCI_DEVICE_ID_INTEL_ICH6_18 0x266e
#define PCI_DEVICE_ID_INTEL_ICH6_19 0x266f
#define PCI_DEVICE_ID_INTEL_ESB2_0 0x2670
-#define PCI_DEVICE_ID_INTEL_ESB2_1 0x2680
-#define PCI_DEVICE_ID_INTEL_ESB2_2 0x2681
-#define PCI_DEVICE_ID_INTEL_ESB2_3 0x2682
-#define PCI_DEVICE_ID_INTEL_ESB2_4 0x2683
-#define PCI_DEVICE_ID_INTEL_ESB2_5 0x2688
-#define PCI_DEVICE_ID_INTEL_ESB2_6 0x2689
-#define PCI_DEVICE_ID_INTEL_ESB2_7 0x268a
-#define PCI_DEVICE_ID_INTEL_ESB2_8 0x268b
-#define PCI_DEVICE_ID_INTEL_ESB2_9 0x268c
-#define PCI_DEVICE_ID_INTEL_ESB2_10 0x2690
-#define PCI_DEVICE_ID_INTEL_ESB2_11 0x2692
-#define PCI_DEVICE_ID_INTEL_ESB2_12 0x2694
-#define PCI_DEVICE_ID_INTEL_ESB2_13 0x2696
#define PCI_DEVICE_ID_INTEL_ESB2_14 0x2698
-#define PCI_DEVICE_ID_INTEL_ESB2_15 0x2699
-#define PCI_DEVICE_ID_INTEL_ESB2_16 0x269a
#define PCI_DEVICE_ID_INTEL_ESB2_17 0x269b
#define PCI_DEVICE_ID_INTEL_ESB2_18 0x269e
#define PCI_DEVICE_ID_INTEL_ICH7_0 0x27b8
#define PCI_DEVICE_ID_INTEL_ICH7_1 0x27b9
-#define PCI_DEVICE_ID_INTEL_ICH7_2 0x27c0
-#define PCI_DEVICE_ID_INTEL_ICH7_3 0x27c1
#define PCI_DEVICE_ID_INTEL_ICH7_30 0x27b0
#define PCI_DEVICE_ID_INTEL_ICH7_31 0x27bd
-#define PCI_DEVICE_ID_INTEL_ICH7_5 0x27c4
-#define PCI_DEVICE_ID_INTEL_ICH7_6 0x27c5
-#define PCI_DEVICE_ID_INTEL_ICH7_7 0x27c8
-#define PCI_DEVICE_ID_INTEL_ICH7_8 0x27c9
-#define PCI_DEVICE_ID_INTEL_ICH7_9 0x27ca
-#define PCI_DEVICE_ID_INTEL_ICH7_10 0x27cb
-#define PCI_DEVICE_ID_INTEL_ICH7_11 0x27cc
-#define PCI_DEVICE_ID_INTEL_ICH7_12 0x27d0
-#define PCI_DEVICE_ID_INTEL_ICH7_13 0x27d2
-#define PCI_DEVICE_ID_INTEL_ICH7_14 0x27d4
-#define PCI_DEVICE_ID_INTEL_ICH7_15 0x27d6
-#define PCI_DEVICE_ID_INTEL_ICH7_16 0x27d8
#define PCI_DEVICE_ID_INTEL_ICH7_17 0x27da
-#define PCI_DEVICE_ID_INTEL_ICH7_18 0x27dc
#define PCI_DEVICE_ID_INTEL_ICH7_19 0x27dd
#define PCI_DEVICE_ID_INTEL_ICH7_20 0x27de
#define PCI_DEVICE_ID_INTEL_ICH7_21 0x27df
-#define PCI_DEVICE_ID_INTEL_ICH7_22 0x27e0
-#define PCI_DEVICE_ID_INTEL_ICH7_23 0x27e2
#define PCI_DEVICE_ID_INTEL_82855PM_HB 0x3340
-#define PCI_DEVICE_ID_INTEL_ESB2_19 0x3500
-#define PCI_DEVICE_ID_INTEL_ESB2_20 0x3501
-#define PCI_DEVICE_ID_INTEL_ESB2_21 0x3504
-#define PCI_DEVICE_ID_INTEL_ESB2_22 0x3505
-#define PCI_DEVICE_ID_INTEL_ESB2_23 0x350c
-#define PCI_DEVICE_ID_INTEL_ESB2_24 0x350d
-#define PCI_DEVICE_ID_INTEL_ESB2_25 0x3510
-#define PCI_DEVICE_ID_INTEL_ESB2_26 0x3511
-#define PCI_DEVICE_ID_INTEL_ESB2_27 0x3514
-#define PCI_DEVICE_ID_INTEL_ESB2_28 0x3515
-#define PCI_DEVICE_ID_INTEL_ESB2_29 0x3518
-#define PCI_DEVICE_ID_INTEL_ESB2_30 0x3519
#define PCI_DEVICE_ID_INTEL_82830_HB 0x3575
#define PCI_DEVICE_ID_INTEL_82830_CGC 0x3577
#define PCI_DEVICE_ID_INTEL_82855GM_HB 0x3580
@@ -2576,7 +2059,6 @@
#define PCI_DEVICE_ID_INTEL_MCH_PC 0x3599
#define PCI_DEVICE_ID_INTEL_MCH_PC1 0x359a
#define PCI_DEVICE_ID_INTEL_E7525_MCH 0x359e
-#define PCI_DEVICE_ID_INTEL_80310 0x530d
#define PCI_DEVICE_ID_INTEL_82371SB_0 0x7000
#define PCI_DEVICE_ID_INTEL_82371SB_1 0x7010
#define PCI_DEVICE_ID_INTEL_82371SB_2 0x7020
@@ -2601,22 +2083,15 @@
#define PCI_DEVICE_ID_INTEL_440MX_6 0x7196
#define PCI_DEVICE_ID_INTEL_82443MX_0 0x7198
#define PCI_DEVICE_ID_INTEL_82443MX_1 0x7199
-#define PCI_DEVICE_ID_INTEL_82443MX_2 0x719a
#define PCI_DEVICE_ID_INTEL_82443MX_3 0x719b
#define PCI_DEVICE_ID_INTEL_82443GX_0 0x71a0
-#define PCI_DEVICE_ID_INTEL_82443GX_1 0x71a1
#define PCI_DEVICE_ID_INTEL_82443GX_2 0x71a2
-#define PCI_DEVICE_ID_INTEL_82372FB_0 0x7600
#define PCI_DEVICE_ID_INTEL_82372FB_1 0x7601
-#define PCI_DEVICE_ID_INTEL_82372FB_2 0x7602
-#define PCI_DEVICE_ID_INTEL_82372FB_3 0x7603
#define PCI_DEVICE_ID_INTEL_82454GX 0x84c4
-#define PCI_DEVICE_ID_INTEL_82450GX 0x84c5
#define PCI_DEVICE_ID_INTEL_82451NX 0x84ca
#define PCI_DEVICE_ID_INTEL_82454NX 0x84cb
#define PCI_DEVICE_ID_INTEL_84460GX 0x84ea
#define PCI_DEVICE_ID_INTEL_IXP4XX 0x8500
-#define PCI_DEVICE_ID_INTEL_IXP2400 0x9001
#define PCI_DEVICE_ID_INTEL_IXP2800 0x9004
#define PCI_DEVICE_ID_INTEL_S21152BB 0xb152
@@ -2629,7 +2104,6 @@
#define PCI_SUBDEVICE_ID_COMPUTONE_PG6 0x0003
#define PCI_VENDOR_ID_KTI 0x8e2e
-#define PCI_DEVICE_ID_KTI_ET32P2 0x3000
#define PCI_VENDOR_ID_ADAPTEC 0x9004
#define PCI_DEVICE_ID_ADAPTEC_7810 0x1078
@@ -2637,7 +2111,6 @@
#define PCI_DEVICE_ID_ADAPTEC_38602 0x3860
#define PCI_DEVICE_ID_ADAPTEC_7850 0x5078
#define PCI_DEVICE_ID_ADAPTEC_7855 0x5578
-#define PCI_DEVICE_ID_ADAPTEC_5800 0x5800
#define PCI_DEVICE_ID_ADAPTEC_3860 0x6038
#define PCI_DEVICE_ID_ADAPTEC_1480A 0x6075
#define PCI_DEVICE_ID_ADAPTEC_7860 0x6078
@@ -2657,7 +2130,6 @@
#define PCI_DEVICE_ID_ADAPTEC_7886 0x8678
#define PCI_DEVICE_ID_ADAPTEC_7887 0x8778
#define PCI_DEVICE_ID_ADAPTEC_7888 0x8878
-#define PCI_DEVICE_ID_ADAPTEC_1030 0x8b78
#define PCI_VENDOR_ID_ADAPTEC2 0x9005
#define PCI_DEVICE_ID_ADAPTEC2_2940U2 0x0010
@@ -2677,8 +2149,6 @@
#define PCI_DEVICE_ID_ADAPTEC2_7899P 0x00cf
#define PCI_DEVICE_ID_ADAPTEC2_SCAMP 0x0503
-#define PCI_VENDOR_ID_ATRONICS 0x907f
-#define PCI_DEVICE_ID_ATRONICS_2015 0x2015
#define PCI_VENDOR_ID_HOLTEK 0x9412
#define PCI_DEVICE_ID_HOLTEK_6565 0x6565
@@ -2711,7 +2181,3 @@
#define PCI_DEVICE_ID_RME_DIGI32_PRO 0x9897
#define PCI_DEVICE_ID_RME_DIGI32_8 0x9898
-#define PCI_VENDOR_ID_ARK 0xedd8
-#define PCI_DEVICE_ID_ARK_STING 0xa091
-#define PCI_DEVICE_ID_ARK_STINGARK 0xa099
-#define PCI_DEVICE_ID_ARK_2000MT 0xa0a1
diff --git a/include/linux/phonedev.h b/include/linux/phonedev.h
index d54049eed0c3..a0e31adf3abe 100644
--- a/include/linux/phonedev.h
+++ b/include/linux/phonedev.h
@@ -2,7 +2,6 @@
#define __LINUX_PHONEDEV_H
#include <linux/types.h>
-#include <linux/version.h>
#ifdef __KERNEL__
diff --git a/include/linux/phy.h b/include/linux/phy.h
index 72cb67b66e0c..92a9696fdebe 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -72,6 +72,9 @@ struct mii_bus {
/* list of all PHYs on bus */
struct phy_device *phy_map[PHY_MAX_ADDR];
+ /* Phy addresses to be ignored when probing */
+ u32 phy_mask;
+
/* Pointer to an array of interrupts, each PHY's
* interrupt at the index matching its address */
int *irq;
diff --git a/include/linux/pkt_sched.h b/include/linux/pkt_sched.h
index 60ffcb9c5791..e87b233615b3 100644
--- a/include/linux/pkt_sched.h
+++ b/include/linux/pkt_sched.h
@@ -93,6 +93,7 @@ struct tc_fifo_qopt
/* PRIO section */
#define TCQ_PRIO_BANDS 16
+#define TCQ_MIN_PRIO_BANDS 2
struct tc_prio_qopt
{
@@ -169,6 +170,7 @@ struct tc_red_qopt
unsigned char Scell_log; /* cell size for idle damping */
unsigned char flags;
#define TC_RED_ECN 1
+#define TC_RED_HARDDROP 2
};
struct tc_red_xstats
@@ -194,38 +196,34 @@ enum
#define TCA_GRED_MAX (__TCA_GRED_MAX - 1)
-#define TCA_SET_OFF TCA_GRED_PARMS
struct tc_gred_qopt
{
- __u32 limit; /* HARD maximal queue length (bytes)
-*/
- __u32 qth_min; /* Min average length threshold (bytes)
-*/
- __u32 qth_max; /* Max average length threshold (bytes)
-*/
- __u32 DP; /* upto 2^32 DPs */
- __u32 backlog;
- __u32 qave;
- __u32 forced;
- __u32 early;
- __u32 other;
- __u32 pdrop;
-
- unsigned char Wlog; /* log(W) */
- unsigned char Plog; /* log(P_max/(qth_max-qth_min)) */
- unsigned char Scell_log; /* cell size for idle damping */
- __u8 prio; /* prio of this VQ */
- __u32 packets;
- __u32 bytesin;
+ __u32 limit; /* HARD maximal queue length (bytes) */
+ __u32 qth_min; /* Min average length threshold (bytes) */
+ __u32 qth_max; /* Max average length threshold (bytes) */
+ __u32 DP; /* upto 2^32 DPs */
+ __u32 backlog;
+ __u32 qave;
+ __u32 forced;
+ __u32 early;
+ __u32 other;
+ __u32 pdrop;
+ __u8 Wlog; /* log(W) */
+ __u8 Plog; /* log(P_max/(qth_max-qth_min)) */
+ __u8 Scell_log; /* cell size for idle damping */
+ __u8 prio; /* prio of this VQ */
+ __u32 packets;
+ __u32 bytesin;
};
+
/* gred setup */
struct tc_gred_sopt
{
- __u32 DPs;
- __u32 def_DP;
- __u8 grio;
- __u8 pad1;
- __u16 pad2;
+ __u32 DPs;
+ __u32 def_DP;
+ __u8 grio;
+ __u8 flags;
+ __u16 pad1;
};
/* HTB section */
diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h
new file mode 100644
index 000000000000..1a165b7ae01b
--- /dev/null
+++ b/include/linux/platform_device.h
@@ -0,0 +1,46 @@
+/*
+ * platform_device.h - generic, centralized driver model
+ *
+ * Copyright (c) 2001-2003 Patrick Mochel <mochel@osdl.org>
+ *
+ * This file is released under the GPLv2
+ *
+ * See Documentation/driver-model/ for more information.
+ */
+
+#ifndef _PLATFORM_DEVICE_H_
+#define _PLATFORM_DEVICE_H_
+
+#include <linux/device.h>
+
+struct platform_device {
+ const char * name;
+ u32 id;
+ struct device dev;
+ u32 num_resources;
+ struct resource * resource;
+};
+
+#define to_platform_device(x) container_of((x), struct platform_device, dev)
+
+extern int platform_device_register(struct platform_device *);
+extern void platform_device_unregister(struct platform_device *);
+
+extern struct bus_type platform_bus_type;
+extern struct device platform_bus;
+
+extern struct resource *platform_get_resource(struct platform_device *, unsigned int, unsigned int);
+extern int platform_get_irq(struct platform_device *, unsigned int);
+extern struct resource *platform_get_resource_byname(struct platform_device *, unsigned int, char *);
+extern int platform_get_irq_byname(struct platform_device *, char *);
+extern int platform_add_devices(struct platform_device **, int);
+
+extern struct platform_device *platform_device_register_simple(char *, unsigned int, struct resource *, unsigned int);
+
+extern struct platform_device *platform_device_alloc(const char *name, unsigned int id);
+extern int platform_device_add_resources(struct platform_device *pdev, struct resource *res, unsigned int num);
+extern int platform_device_add_data(struct platform_device *pdev, void *data, size_t size);
+extern int platform_device_add(struct platform_device *pdev);
+extern void platform_device_put(struct platform_device *pdev);
+
+#endif /* _PLATFORM_DEVICE_H_ */
diff --git a/include/linux/pm.h b/include/linux/pm.h
index 5cfb07648eca..1514098d156d 100644
--- a/include/linux/pm.h
+++ b/include/linux/pm.h
@@ -170,6 +170,7 @@ typedef int __bitwise suspend_disk_method_t;
struct pm_ops {
suspend_disk_method_t pm_disk_mode;
+ int (*valid)(suspend_state_t state);
int (*prepare)(suspend_state_t state);
int (*enter)(suspend_state_t state);
int (*finish)(suspend_state_t state);
@@ -219,10 +220,11 @@ typedef struct pm_message {
struct dev_pm_info {
pm_message_t power_state;
+ unsigned can_wakeup:1;
#ifdef CONFIG_PM
+ unsigned should_wakeup:1;
pm_message_t prev_state;
void * saved_state;
- atomic_t pm_users;
struct device * pm_parent;
struct list_head entry;
#endif
@@ -236,13 +238,48 @@ extern void device_resume(void);
#ifdef CONFIG_PM
extern int device_suspend(pm_message_t state);
-#else
+
+#define device_set_wakeup_enable(dev,val) \
+ ((dev)->power.should_wakeup = !!(val))
+#define device_may_wakeup(dev) \
+ (device_can_wakeup(dev) && (dev)->power.should_wakeup)
+
+extern int dpm_runtime_suspend(struct device *, pm_message_t);
+extern void dpm_runtime_resume(struct device *);
+
+#else /* !CONFIG_PM */
+
static inline int device_suspend(pm_message_t state)
{
return 0;
}
+
+#define device_set_wakeup_enable(dev,val) do{}while(0)
+#define device_may_wakeup(dev) (0)
+
+static inline int dpm_runtime_suspend(struct device * dev, pm_message_t state)
+{
+ return 0;
+}
+
+static inline void dpm_runtime_resume(struct device * dev)
+{
+
+}
+
#endif
+/* changes to device_may_wakeup take effect on the next pm state change.
+ * by default, devices should wakeup if they can.
+ */
+#define device_can_wakeup(dev) \
+ ((dev)->power.can_wakeup)
+#define device_init_wakeup(dev,val) \
+ do { \
+ device_can_wakeup(dev) = !!(val); \
+ device_set_wakeup_enable(dev,val); \
+ } while(0)
+
#endif /* __KERNEL__ */
#endif /* _LINUX_PM_H */
diff --git a/include/linux/pnp.h b/include/linux/pnp.h
index aadbac29103c..584d57cb393a 100644
--- a/include/linux/pnp.h
+++ b/include/linux/pnp.h
@@ -353,7 +353,6 @@ struct pnp_protocol {
int pnp_register_protocol(struct pnp_protocol *protocol);
void pnp_unregister_protocol(struct pnp_protocol *protocol);
int pnp_add_device(struct pnp_dev *dev);
-void pnp_remove_device(struct pnp_dev *dev);
int pnp_device_attach(struct pnp_dev *pnp_dev);
void pnp_device_detach(struct pnp_dev *pnp_dev);
extern struct list_head pnp_global;
@@ -399,7 +398,6 @@ static inline int pnp_register_protocol(struct pnp_protocol *protocol) { return
static inline void pnp_unregister_protocol(struct pnp_protocol *protocol) { }
static inline int pnp_init_device(struct pnp_dev *dev) { return -ENODEV; }
static inline int pnp_add_device(struct pnp_dev *dev) { return -ENODEV; }
-static inline void pnp_remove_device(struct pnp_dev *dev) { }
static inline int pnp_device_attach(struct pnp_dev *pnp_dev) { return -ENODEV; }
static inline void pnp_device_detach(struct pnp_dev *pnp_dev) { ; }
diff --git a/include/linux/ppp-comp.h b/include/linux/ppp-comp.h
index 7227e653b3be..e86a7a5cf355 100644
--- a/include/linux/ppp-comp.h
+++ b/include/linux/ppp-comp.h
@@ -111,6 +111,8 @@ struct compressor {
/* Used in locking compressor modules */
struct module *owner;
+ /* Extra skb space needed by the compressor algorithm */
+ unsigned int comp_extra;
};
/*
@@ -191,6 +193,13 @@ struct compressor {
#define DEFLATE_CHK_SEQUENCE 0
/*
+ * Definitions for MPPE.
+ */
+
+#define CI_MPPE 18 /* config option for MPPE */
+#define CILEN_MPPE 6 /* length of config option */
+
+/*
* Definitions for other, as yet unsupported, compression methods.
*/
diff --git a/include/linux/proc_fs.h b/include/linux/proc_fs.h
index 0563581e3a02..74488e49166d 100644
--- a/include/linux/proc_fs.h
+++ b/include/linux/proc_fs.h
@@ -66,6 +66,7 @@ struct proc_dir_entry {
write_proc_t *write_proc;
atomic_t count; /* use count */
int deleted; /* delete flag */
+ void *set;
};
struct kcore_list {
@@ -139,15 +140,12 @@ extern void proc_tty_unregister_driver(struct tty_driver *driver);
/*
* proc_devtree.c
*/
+#ifdef CONFIG_PROC_DEVICETREE
struct device_node;
+struct property;
extern void proc_device_tree_init(void);
-#ifdef CONFIG_PROC_DEVICETREE
extern void proc_device_tree_add_node(struct device_node *, struct proc_dir_entry *);
-#else /* !CONFIG_PROC_DEVICETREE */
-static inline void proc_device_tree_add_node(struct device_node *np, struct proc_dir_entry *pde)
-{
- return;
-}
+extern void proc_device_tree_add_prop(struct proc_dir_entry *pde, struct property *prop);
#endif /* CONFIG_PROC_DEVICETREE */
extern struct proc_dir_entry *proc_symlink(const char *,
diff --git a/include/linux/ptrace.h b/include/linux/ptrace.h
index dc6f3647bfbc..b2b3dba1298d 100644
--- a/include/linux/ptrace.h
+++ b/include/linux/ptrace.h
@@ -78,6 +78,8 @@
#include <linux/compiler.h> /* For unlikely. */
#include <linux/sched.h> /* For struct task_struct. */
+
+extern long arch_ptrace(struct task_struct *child, long request, long addr, long data);
extern int ptrace_readdata(struct task_struct *tsk, unsigned long src, char __user *dst, int len);
extern int ptrace_writedata(struct task_struct *tsk, char __user *src, unsigned long dst, int len);
extern int ptrace_attach(struct task_struct *tsk);
diff --git a/include/linux/quota.h b/include/linux/quota.h
index 700ead45084f..f33aeb22c26a 100644
--- a/include/linux/quota.h
+++ b/include/linux/quota.h
@@ -289,7 +289,6 @@ struct quota_info {
struct semaphore dqonoff_sem; /* Serialize quotaon & quotaoff */
struct rw_semaphore dqptr_sem; /* serialize ops using quota_info struct, pointers from inode to dquots */
struct inode *files[MAXQUOTAS]; /* inodes of quotafiles */
- struct vfsmount *mnt[MAXQUOTAS]; /* mountpoint entries of filesystems with quota files */
struct mem_dqinfo info[MAXQUOTAS]; /* Information for each quota type */
struct quota_format_ops *ops[MAXQUOTAS]; /* Operations for each type */
};
diff --git a/include/linux/quotaops.h b/include/linux/quotaops.h
index d211507ab246..4f34d3d60f2e 100644
--- a/include/linux/quotaops.h
+++ b/include/linux/quotaops.h
@@ -198,38 +198,38 @@ static __inline__ int DQUOT_OFF(struct super_block *sb)
#define DQUOT_SYNC(sb) do { } while(0)
#define DQUOT_OFF(sb) do { } while(0)
#define DQUOT_TRANSFER(inode, iattr) (0)
-extern __inline__ int DQUOT_PREALLOC_SPACE_NODIRTY(struct inode *inode, qsize_t nr)
+static inline int DQUOT_PREALLOC_SPACE_NODIRTY(struct inode *inode, qsize_t nr)
{
inode_add_bytes(inode, nr);
return 0;
}
-extern __inline__ int DQUOT_PREALLOC_SPACE(struct inode *inode, qsize_t nr)
+static inline int DQUOT_PREALLOC_SPACE(struct inode *inode, qsize_t nr)
{
DQUOT_PREALLOC_SPACE_NODIRTY(inode, nr);
mark_inode_dirty(inode);
return 0;
}
-extern __inline__ int DQUOT_ALLOC_SPACE_NODIRTY(struct inode *inode, qsize_t nr)
+static inline int DQUOT_ALLOC_SPACE_NODIRTY(struct inode *inode, qsize_t nr)
{
inode_add_bytes(inode, nr);
return 0;
}
-extern __inline__ int DQUOT_ALLOC_SPACE(struct inode *inode, qsize_t nr)
+static inline int DQUOT_ALLOC_SPACE(struct inode *inode, qsize_t nr)
{
DQUOT_ALLOC_SPACE_NODIRTY(inode, nr);
mark_inode_dirty(inode);
return 0;
}
-extern __inline__ void DQUOT_FREE_SPACE_NODIRTY(struct inode *inode, qsize_t nr)
+static inline void DQUOT_FREE_SPACE_NODIRTY(struct inode *inode, qsize_t nr)
{
inode_sub_bytes(inode, nr);
}
-extern __inline__ void DQUOT_FREE_SPACE(struct inode *inode, qsize_t nr)
+static inline void DQUOT_FREE_SPACE(struct inode *inode, qsize_t nr)
{
DQUOT_FREE_SPACE_NODIRTY(inode, nr);
mark_inode_dirty(inode);
diff --git a/include/linux/radix-tree.h b/include/linux/radix-tree.h
index 045d4761febc..36e5d269612f 100644
--- a/include/linux/radix-tree.h
+++ b/include/linux/radix-tree.h
@@ -24,7 +24,7 @@
struct radix_tree_root {
unsigned int height;
- unsigned int gfp_mask;
+ gfp_t gfp_mask;
struct radix_tree_node *rnode;
};
@@ -46,6 +46,7 @@ do { \
int radix_tree_insert(struct radix_tree_root *, unsigned long, void *);
void *radix_tree_lookup(struct radix_tree_root *, unsigned long);
+void **radix_tree_lookup_slot(struct radix_tree_root *, unsigned long);
void *radix_tree_delete(struct radix_tree_root *, unsigned long);
unsigned int
radix_tree_gang_lookup(struct radix_tree_root *root, void **results,
diff --git a/include/linux/raid/bitmap.h b/include/linux/raid/bitmap.h
index 9de99198caf1..899437802aea 100644
--- a/include/linux/raid/bitmap.h
+++ b/include/linux/raid/bitmap.h
@@ -6,7 +6,13 @@
#ifndef BITMAP_H
#define BITMAP_H 1
-#define BITMAP_MAJOR 3
+#define BITMAP_MAJOR_LO 3
+/* version 4 insists the bitmap is in little-endian order
+ * with version 3, it is host-endian which is non-portable
+ */
+#define BITMAP_MAJOR_HI 4
+#define BITMAP_MAJOR_HOSTENDIAN 3
+
#define BITMAP_MINOR 39
/*
@@ -133,7 +139,8 @@ typedef __u16 bitmap_counter_t;
/* use these for bitmap->flags and bitmap->sb->state bit-fields */
enum bitmap_state {
BITMAP_ACTIVE = 0x001, /* the bitmap is in use */
- BITMAP_STALE = 0x002 /* the bitmap file is out of date or had -EIO */
+ BITMAP_STALE = 0x002, /* the bitmap file is out of date or had -EIO */
+ BITMAP_HOSTENDIAN = 0x8000,
};
/* the superblock at the front of the bitmap file -- little endian */
diff --git a/include/linux/raid/md.h b/include/linux/raid/md.h
index ffa316ce4dc8..13e7c4b62367 100644
--- a/include/linux/raid/md.h
+++ b/include/linux/raid/md.h
@@ -66,8 +66,10 @@
* and major_version/minor_version accordingly
* >=2 means that Internal bitmaps are supported by setting MD_SB_BITMAP_PRESENT
* in the super status byte
+ * >=3 means that bitmap superblock version 4 is supported, which uses
+ * little-ending representation rather than host-endian
*/
-#define MD_PATCHLEVEL_VERSION 2
+#define MD_PATCHLEVEL_VERSION 3
extern int register_md_personality (int p_num, mdk_personality_t *p);
extern int unregister_md_personality (int p_num);
@@ -87,6 +89,7 @@ extern void md_print_devices (void);
extern void md_super_write(mddev_t *mddev, mdk_rdev_t *rdev,
sector_t sector, int size, struct page *page);
+extern void md_super_wait(mddev_t *mddev);
extern int sync_page_io(struct block_device *bdev, sector_t sector, int size,
struct page *page, int rw);
diff --git a/include/linux/raid/md_k.h b/include/linux/raid/md_k.h
index ebce949b1443..46629a275ba9 100644
--- a/include/linux/raid/md_k.h
+++ b/include/linux/raid/md_k.h
@@ -105,6 +105,8 @@ struct mdk_rdev_s
int sb_size; /* bytes in the superblock */
int preferred_minor; /* autorun support */
+ struct kobject kobj;
+
/* A device can be in one of three states based on two flags:
* Not working: faulty==1 in_sync==0
* Fully working: faulty==0 in_sync==1
@@ -115,11 +117,12 @@ struct mdk_rdev_s
* It can never have faulty==1, in_sync==1
* This reduces the burden of testing multiple flags in many cases
*/
- int faulty; /* if faulty do not issue IO requests */
- int in_sync; /* device is a full member of the array */
- unsigned long flags; /* Should include faulty and in_sync here. */
+ unsigned long flags;
+#define Faulty 1 /* device is known to have a fault */
+#define In_sync 2 /* device is in_sync with rest of array */
#define WriteMostly 4 /* Avoid reading if at all possible */
+#define BarriersNotsupp 5 /* BIO_RW_BARRIER is not supported */
int desc_nr; /* descriptor index in the superblock */
int raid_disk; /* role of device in array */
@@ -132,6 +135,9 @@ struct mdk_rdev_s
* only maintained for arrays that
* support hot removal
*/
+ atomic_t read_errors; /* number of consecutive read errors that
+ * we have tried to ignore.
+ */
};
typedef struct mdk_personality_s mdk_personality_t;
@@ -148,6 +154,8 @@ struct mddev_s
struct gendisk *gendisk;
+ struct kobject kobj;
+
/* Superblock information */
int major_version,
minor_version,
@@ -171,6 +179,10 @@ struct mddev_s
sector_t resync_mark_cnt;/* blocks written at resync_mark */
sector_t resync_max_sectors; /* may be set by personality */
+
+ sector_t resync_mismatches; /* count of sectors where
+ * parity/replica mismatch found
+ */
/* recovery/resync flags
* NEEDED: we might need to start a resync/recover
* RUNNING: a thread is running, or about to be started
@@ -178,6 +190,8 @@ struct mddev_s
* ERR: and IO error was detected - abort the resync/recovery
* INTR: someone requested a (clean) early abort.
* DONE: thread is done and is waiting to be reaped
+ * REQUEST: user-space has requested a sync (used with SYNC)
+ * CHECK: user-space request for for check-only, no repair
*/
#define MD_RECOVERY_RUNNING 0
#define MD_RECOVERY_SYNC 1
@@ -185,6 +199,8 @@ struct mddev_s
#define MD_RECOVERY_INTR 3
#define MD_RECOVERY_DONE 4
#define MD_RECOVERY_NEEDED 5
+#define MD_RECOVERY_REQUESTED 6
+#define MD_RECOVERY_CHECK 7
unsigned long recovery;
int in_sync; /* know to not need resync */
@@ -195,6 +211,13 @@ struct mddev_s
int degraded; /* whether md should consider
* adding a spare
*/
+ int barriers_work; /* initialised to true, cleared as soon
+ * as a barrier request to slave
+ * fails. Only supported
+ */
+ struct bio *biolist; /* bios that need to be retried
+ * because BIO_RW_BARRIER is not supported
+ */
atomic_t recovery_active; /* blocks scheduled, but not written */
wait_queue_head_t recovery_wait;
@@ -232,7 +255,7 @@ struct mddev_s
static inline void rdev_dec_pending(mdk_rdev_t *rdev, mddev_t *mddev)
{
- int faulty = rdev->faulty;
+ int faulty = test_bit(Faulty, &rdev->flags);
if (atomic_dec_and_test(&rdev->nr_pending) && faulty)
set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
}
@@ -270,6 +293,13 @@ struct mdk_personality_s
};
+struct md_sysfs_entry {
+ struct attribute attr;
+ ssize_t (*show)(mddev_t *, char *);
+ ssize_t (*store)(mddev_t *, const char *, size_t);
+};
+
+
static inline char * mdname (mddev_t * mddev)
{
return mddev->gendisk ? mddev->gendisk->disk_name : "mdX";
@@ -304,10 +334,8 @@ typedef struct mdk_thread_s {
mddev_t *mddev;
wait_queue_head_t wqueue;
unsigned long flags;
- struct completion *event;
struct task_struct *tsk;
unsigned long timeout;
- const char *name;
} mdk_thread_t;
#define THREAD_WAKEUP 0
diff --git a/include/linux/raid/raid1.h b/include/linux/raid/raid1.h
index 60e19b667548..292b98f2b408 100644
--- a/include/linux/raid/raid1.h
+++ b/include/linux/raid/raid1.h
@@ -110,7 +110,9 @@ struct r1bio_s {
#define R1BIO_Uptodate 0
#define R1BIO_IsSync 1
#define R1BIO_Degraded 2
-#define R1BIO_BehindIO 3
+#define R1BIO_BehindIO 3
+#define R1BIO_Barrier 4
+#define R1BIO_BarrierRetry 5
/* For write-behind requests, we call bi_end_io when
* the last non-write-behind device completes, providing
* any write was successful. Otherwise we call when
diff --git a/include/linux/raid/raid5.h b/include/linux/raid/raid5.h
index 176fc653c284..f025ba6fb14c 100644
--- a/include/linux/raid/raid5.h
+++ b/include/linux/raid/raid5.h
@@ -154,6 +154,8 @@ struct stripe_head {
#define R5_Wantwrite 5
#define R5_Syncio 6 /* this io need to be accounted as resync io */
#define R5_Overlap 7 /* There is a pending overlapping request on this block */
+#define R5_ReadError 8 /* seen a read error here recently */
+#define R5_ReWrite 9 /* have tried to over-write the readerror */
/*
* Write method
diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h
index 70191a5a148f..cce25591eec2 100644
--- a/include/linux/rcupdate.h
+++ b/include/linux/rcupdate.h
@@ -275,6 +275,7 @@ static inline int rcu_pending(int cpu)
extern void rcu_init(void);
extern void rcu_check_callbacks(int cpu, int user);
extern void rcu_restart_cpu(int cpu);
+extern long rcu_batches_completed(void);
/* Exported interfaces */
extern void FASTCALL(call_rcu(struct rcu_head *head,
diff --git a/include/linux/reiserfs_fs.h b/include/linux/reiserfs_fs.h
index af00b10294cd..001ab82df051 100644
--- a/include/linux/reiserfs_fs.h
+++ b/include/linux/reiserfs_fs.h
@@ -1972,7 +1972,7 @@ extern struct address_space_operations reiserfs_address_space_operations;
/* fix_nodes.c */
#ifdef CONFIG_REISERFS_CHECK
-void *reiserfs_kmalloc(size_t size, int flags, struct super_block *s);
+void *reiserfs_kmalloc(size_t size, gfp_t flags, struct super_block *s);
void reiserfs_kfree(const void *vp, size_t size, struct super_block *s);
#else
static inline void *reiserfs_kmalloc(size_t size, int flags,
diff --git a/include/linux/rio.h b/include/linux/rio.h
new file mode 100644
index 000000000000..c7e907faae9c
--- /dev/null
+++ b/include/linux/rio.h
@@ -0,0 +1,325 @@
+/*
+ * RapidIO interconnect services
+ * (RapidIO Interconnect Specification, http://www.rapidio.org)
+ *
+ * Copyright 2005 MontaVista Software, Inc.
+ * Matt Porter <mporter@kernel.crashing.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.
+ */
+
+#ifndef LINUX_RIO_H
+#define LINUX_RIO_H
+
+#ifdef __KERNEL__
+
+#include <linux/types.h>
+#include <linux/config.h>
+#include <linux/ioport.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/device.h>
+#include <linux/rio_regs.h>
+
+#define RIO_ANY_DESTID 0xff
+#define RIO_NO_HOPCOUNT -1
+
+#define RIO_MAX_MPORT_RESOURCES 16
+#define RIO_MAX_DEV_RESOURCES 16
+
+#define RIO_GLOBAL_TABLE 0xff /* Indicates access of a switch's
+ global routing table if it
+ has multiple (or per port)
+ tables */
+
+#define RIO_INVALID_ROUTE 0xff /* Indicates that a route table
+ entry is invalid (no route
+ exists for the device ID) */
+
+#ifdef CONFIG_RAPIDIO_8_BIT_TRANSPORT
+#define RIO_MAX_ROUTE_ENTRIES (1 << 8)
+#else
+#define RIO_MAX_ROUTE_ENTRIES (1 << 16)
+#endif
+
+#define RIO_MAX_MBOX 4
+#define RIO_MAX_MSG_SIZE 0x1000
+
+/*
+ * Error values that may be returned by RIO functions.
+ */
+#define RIO_SUCCESSFUL 0x00
+#define RIO_BAD_SIZE 0x81
+
+/*
+ * For RIO devices, the region numbers are assigned this way:
+ *
+ * 0 RapidIO outbound doorbells
+ * 1-15 RapidIO memory regions
+ *
+ * For RIO master ports, the region number are assigned this way:
+ *
+ * 0 RapidIO inbound doorbells
+ * 1 RapidIO inbound mailboxes
+ * 1 RapidIO outbound mailboxes
+ */
+#define RIO_DOORBELL_RESOURCE 0
+#define RIO_INB_MBOX_RESOURCE 1
+#define RIO_OUTB_MBOX_RESOURCE 2
+
+extern struct bus_type rio_bus_type;
+extern struct list_head rio_devices; /* list of all devices */
+
+struct rio_mport;
+
+/**
+ * struct rio_dev - RIO device info
+ * @global_list: Node in list of all RIO devices
+ * @net_list: Node in list of RIO devices in a network
+ * @net: Network this device is a part of
+ * @did: Device ID
+ * @vid: Vendor ID
+ * @device_rev: Device revision
+ * @asm_did: Assembly device ID
+ * @asm_vid: Assembly vendor ID
+ * @asm_rev: Assembly revision
+ * @efptr: Extended feature pointer
+ * @pef: Processing element features
+ * @swpinfo: Switch port info
+ * @src_ops: Source operation capabilities
+ * @dst_ops: Destination operation capabilities
+ * @dma_mask: Mask of bits of RIO address this device implements
+ * @rswitch: Pointer to &struct rio_switch if valid for this device
+ * @driver: Driver claiming this device
+ * @dev: Device model device
+ * @riores: RIO resources this device owns
+ * @destid: Network destination ID
+ */
+struct rio_dev {
+ struct list_head global_list; /* node in list of all RIO devices */
+ struct list_head net_list; /* node in per net list */
+ struct rio_net *net; /* RIO net this device resides in */
+ u16 did;
+ u16 vid;
+ u32 device_rev;
+ u16 asm_did;
+ u16 asm_vid;
+ u16 asm_rev;
+ u16 efptr;
+ u32 pef;
+ u32 swpinfo; /* Only used for switches */
+ u32 src_ops;
+ u32 dst_ops;
+ u64 dma_mask;
+ struct rio_switch *rswitch; /* RIO switch info */
+ struct rio_driver *driver; /* RIO driver claiming this device */
+ struct device dev; /* LDM device structure */
+ struct resource riores[RIO_MAX_DEV_RESOURCES];
+ u16 destid;
+};
+
+#define rio_dev_g(n) list_entry(n, struct rio_dev, global_list)
+#define rio_dev_f(n) list_entry(n, struct rio_dev, net_list)
+#define to_rio_dev(n) container_of(n, struct rio_dev, dev)
+
+/**
+ * struct rio_msg - RIO message event
+ * @res: Mailbox resource
+ * @mcback: Message event callback
+ */
+struct rio_msg {
+ struct resource *res;
+ void (*mcback) (struct rio_mport * mport, void *dev_id, int mbox, int slot);
+};
+
+/**
+ * struct rio_dbell - RIO doorbell event
+ * @node: Node in list of doorbell events
+ * @res: Doorbell resource
+ * @dinb: Doorbell event callback
+ * @dev_id: Device specific pointer to pass on event
+ */
+struct rio_dbell {
+ struct list_head node;
+ struct resource *res;
+ void (*dinb) (struct rio_mport *mport, void *dev_id, u16 src, u16 dst, u16 info);
+ void *dev_id;
+};
+
+/**
+ * struct rio_mport - RIO master port info
+ * @dbells: List of doorbell events
+ * @node: Node in global list of master ports
+ * @nnode: Node in network list of master ports
+ * @iores: I/O mem resource that this master port interface owns
+ * @riores: RIO resources that this master port interfaces owns
+ * @inb_msg: RIO inbound message event descriptors
+ * @outb_msg: RIO outbound message event descriptors
+ * @host_deviceid: Host device ID associated with this master port
+ * @ops: configuration space functions
+ * @id: Port ID, unique among all ports
+ * @index: Port index, unique among all port interfaces of the same type
+ * @name: Port name string
+ */
+struct rio_mport {
+ struct list_head dbells; /* list of doorbell events */
+ struct list_head node; /* node in global list of ports */
+ struct list_head nnode; /* node in net list of ports */
+ struct resource iores;
+ struct resource riores[RIO_MAX_MPORT_RESOURCES];
+ struct rio_msg inb_msg[RIO_MAX_MBOX];
+ struct rio_msg outb_msg[RIO_MAX_MBOX];
+ int host_deviceid; /* Host device ID */
+ struct rio_ops *ops; /* maintenance transaction functions */
+ unsigned char id; /* port ID, unique among all ports */
+ unsigned char index; /* port index, unique among all port
+ interfaces of the same type */
+ unsigned char name[40];
+};
+
+/**
+ * struct rio_net - RIO network info
+ * @node: Node in global list of RIO networks
+ * @devices: List of devices in this network
+ * @mports: List of master ports accessing this network
+ * @hport: Default port for accessing this network
+ * @id: RIO network ID
+ */
+struct rio_net {
+ struct list_head node; /* node in list of networks */
+ struct list_head devices; /* list of devices in this net */
+ struct list_head mports; /* list of ports accessing net */
+ struct rio_mport *hport; /* primary port for accessing net */
+ unsigned char id; /* RIO network ID */
+};
+
+/**
+ * struct rio_switch - RIO switch info
+ * @node: Node in global list of switches
+ * @switchid: Switch ID that is unique across a network
+ * @hopcount: Hopcount to this switch
+ * @destid: Associated destid in the path
+ * @route_table: Copy of switch routing table
+ * @add_entry: Callback for switch-specific route add function
+ * @get_entry: Callback for switch-specific route get function
+ */
+struct rio_switch {
+ struct list_head node;
+ u16 switchid;
+ u16 hopcount;
+ u16 destid;
+ u8 route_table[RIO_MAX_ROUTE_ENTRIES];
+ int (*add_entry) (struct rio_mport * mport, u16 destid, u8 hopcount,
+ u16 table, u16 route_destid, u8 route_port);
+ int (*get_entry) (struct rio_mport * mport, u16 destid, u8 hopcount,
+ u16 table, u16 route_destid, u8 * route_port);
+};
+
+/* Low-level architecture-dependent routines */
+
+/**
+ * struct rio_ops - Low-level RIO configuration space operations
+ * @lcread: Callback to perform local (master port) read of config space.
+ * @lcwrite: Callback to perform local (master port) write of config space.
+ * @cread: Callback to perform network read of config space.
+ * @cwrite: Callback to perform network write of config space.
+ * @dsend: Callback to send a doorbell message.
+ */
+struct rio_ops {
+ int (*lcread) (int index, u32 offset, int len, u32 * data);
+ int (*lcwrite) (int index, u32 offset, int len, u32 data);
+ int (*cread) (int index, u16 destid, u8 hopcount, u32 offset, int len,
+ u32 * data);
+ int (*cwrite) (int index, u16 destid, u8 hopcount, u32 offset, int len,
+ u32 data);
+ int (*dsend) (int index, u16 destid, u16 data);
+};
+
+#define RIO_RESOURCE_MEM 0x00000100
+#define RIO_RESOURCE_DOORBELL 0x00000200
+#define RIO_RESOURCE_MAILBOX 0x00000400
+
+#define RIO_RESOURCE_CACHEABLE 0x00010000
+#define RIO_RESOURCE_PCI 0x00020000
+
+#define RIO_RESOURCE_BUSY 0x80000000
+
+/**
+ * struct rio_driver - RIO driver info
+ * @node: Node in list of drivers
+ * @name: RIO driver name
+ * @id_table: RIO device ids to be associated with this driver
+ * @probe: RIO device inserted
+ * @remove: RIO device removed
+ * @suspend: RIO device suspended
+ * @resume: RIO device awakened
+ * @enable_wake: RIO device enable wake event
+ * @driver: LDM driver struct
+ *
+ * Provides info on a RIO device driver for insertion/removal and
+ * power management purposes.
+ */
+struct rio_driver {
+ struct list_head node;
+ char *name;
+ const struct rio_device_id *id_table;
+ int (*probe) (struct rio_dev * dev, const struct rio_device_id * id);
+ void (*remove) (struct rio_dev * dev);
+ int (*suspend) (struct rio_dev * dev, u32 state);
+ int (*resume) (struct rio_dev * dev);
+ int (*enable_wake) (struct rio_dev * dev, u32 state, int enable);
+ struct device_driver driver;
+};
+
+#define to_rio_driver(drv) container_of(drv,struct rio_driver, driver)
+
+/**
+ * struct rio_device_id - RIO device identifier
+ * @did: RIO device ID
+ * @vid: RIO vendor ID
+ * @asm_did: RIO assembly device ID
+ * @asm_vid: RIO assembly vendor ID
+ *
+ * Identifies a RIO device based on both the device/vendor IDs and
+ * the assembly device/vendor IDs.
+ */
+struct rio_device_id {
+ u16 did, vid;
+ u16 asm_did, asm_vid;
+};
+
+/**
+ * struct rio_route_ops - Per-switch route operations
+ * @vid: RIO vendor ID
+ * @did: RIO device ID
+ * @add_hook: Callback that adds a route entry
+ * @get_hook: Callback that gets a route entry
+ *
+ * Defines the operations that are necessary to manipulate the route
+ * tables for a particular RIO switch device.
+ */
+struct rio_route_ops {
+ u16 vid, did;
+ int (*add_hook) (struct rio_mport * mport, u16 destid, u8 hopcount,
+ u16 table, u16 route_destid, u8 route_port);
+ int (*get_hook) (struct rio_mport * mport, u16 destid, u8 hopcount,
+ u16 table, u16 route_destid, u8 * route_port);
+};
+
+/* Architecture and hardware-specific functions */
+extern int rio_init_mports(void);
+extern void rio_register_mport(struct rio_mport *);
+extern int rio_hw_add_outb_message(struct rio_mport *, struct rio_dev *, int,
+ void *, size_t);
+extern int rio_hw_add_inb_buffer(struct rio_mport *, int, void *);
+extern void *rio_hw_get_inb_message(struct rio_mport *, int);
+extern int rio_open_inb_mbox(struct rio_mport *, void *, int, int);
+extern void rio_close_inb_mbox(struct rio_mport *, int);
+extern int rio_open_outb_mbox(struct rio_mport *, void *, int, int);
+extern void rio_close_outb_mbox(struct rio_mport *, int);
+
+#endif /* __KERNEL__ */
+#endif /* LINUX_RIO_H */
diff --git a/include/linux/rio_drv.h b/include/linux/rio_drv.h
new file mode 100644
index 000000000000..3bd7cce19e26
--- /dev/null
+++ b/include/linux/rio_drv.h
@@ -0,0 +1,469 @@
+/*
+ * RapidIO driver services
+ *
+ * Copyright 2005 MontaVista Software, Inc.
+ * Matt Porter <mporter@kernel.crashing.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.
+ */
+
+#ifndef LINUX_RIO_DRV_H
+#define LINUX_RIO_DRV_H
+
+#ifdef __KERNEL__
+
+#include <linux/types.h>
+#include <linux/config.h>
+#include <linux/ioport.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/device.h>
+#include <linux/rio.h>
+
+extern int __rio_local_read_config_32(struct rio_mport *port, u32 offset,
+ u32 * data);
+extern int __rio_local_write_config_32(struct rio_mport *port, u32 offset,
+ u32 data);
+extern int __rio_local_read_config_16(struct rio_mport *port, u32 offset,
+ u16 * data);
+extern int __rio_local_write_config_16(struct rio_mport *port, u32 offset,
+ u16 data);
+extern int __rio_local_read_config_8(struct rio_mport *port, u32 offset,
+ u8 * data);
+extern int __rio_local_write_config_8(struct rio_mport *port, u32 offset,
+ u8 data);
+
+extern int rio_mport_read_config_32(struct rio_mport *port, u16 destid,
+ u8 hopcount, u32 offset, u32 * data);
+extern int rio_mport_write_config_32(struct rio_mport *port, u16 destid,
+ u8 hopcount, u32 offset, u32 data);
+extern int rio_mport_read_config_16(struct rio_mport *port, u16 destid,
+ u8 hopcount, u32 offset, u16 * data);
+extern int rio_mport_write_config_16(struct rio_mport *port, u16 destid,
+ u8 hopcount, u32 offset, u16 data);
+extern int rio_mport_read_config_8(struct rio_mport *port, u16 destid,
+ u8 hopcount, u32 offset, u8 * data);
+extern int rio_mport_write_config_8(struct rio_mport *port, u16 destid,
+ u8 hopcount, u32 offset, u8 data);
+
+/**
+ * rio_local_read_config_32 - Read 32 bits from local configuration space
+ * @port: Master port
+ * @offset: Offset into local configuration space
+ * @data: Pointer to read data into
+ *
+ * Reads 32 bits of data from the specified offset within the local
+ * device's configuration space.
+ */
+static inline int rio_local_read_config_32(struct rio_mport *port, u32 offset,
+ u32 * data)
+{
+ return __rio_local_read_config_32(port, offset, data);
+}
+
+/**
+ * rio_local_write_config_32 - Write 32 bits to local configuration space
+ * @port: Master port
+ * @offset: Offset into local configuration space
+ * @data: Data to be written
+ *
+ * Writes 32 bits of data to the specified offset within the local
+ * device's configuration space.
+ */
+static inline int rio_local_write_config_32(struct rio_mport *port, u32 offset,
+ u32 data)
+{
+ return __rio_local_write_config_32(port, offset, data);
+}
+
+/**
+ * rio_local_read_config_16 - Read 16 bits from local configuration space
+ * @port: Master port
+ * @offset: Offset into local configuration space
+ * @data: Pointer to read data into
+ *
+ * Reads 16 bits of data from the specified offset within the local
+ * device's configuration space.
+ */
+static inline int rio_local_read_config_16(struct rio_mport *port, u32 offset,
+ u16 * data)
+{
+ return __rio_local_read_config_16(port, offset, data);
+}
+
+/**
+ * rio_local_write_config_16 - Write 16 bits to local configuration space
+ * @port: Master port
+ * @offset: Offset into local configuration space
+ * @data: Data to be written
+ *
+ * Writes 16 bits of data to the specified offset within the local
+ * device's configuration space.
+ */
+
+static inline int rio_local_write_config_16(struct rio_mport *port, u32 offset,
+ u16 data)
+{
+ return __rio_local_write_config_16(port, offset, data);
+}
+
+/**
+ * rio_local_read_config_8 - Read 8 bits from local configuration space
+ * @port: Master port
+ * @offset: Offset into local configuration space
+ * @data: Pointer to read data into
+ *
+ * Reads 8 bits of data from the specified offset within the local
+ * device's configuration space.
+ */
+static inline int rio_local_read_config_8(struct rio_mport *port, u32 offset,
+ u8 * data)
+{
+ return __rio_local_read_config_8(port, offset, data);
+}
+
+/**
+ * rio_local_write_config_8 - Write 8 bits to local configuration space
+ * @port: Master port
+ * @offset: Offset into local configuration space
+ * @data: Data to be written
+ *
+ * Writes 8 bits of data to the specified offset within the local
+ * device's configuration space.
+ */
+static inline int rio_local_write_config_8(struct rio_mport *port, u32 offset,
+ u8 data)
+{
+ return __rio_local_write_config_8(port, offset, data);
+}
+
+/**
+ * rio_read_config_32 - Read 32 bits from configuration space
+ * @rdev: RIO device
+ * @offset: Offset into device configuration space
+ * @data: Pointer to read data into
+ *
+ * Reads 32 bits of data from the specified offset within the
+ * RIO device's configuration space.
+ */
+static inline int rio_read_config_32(struct rio_dev *rdev, u32 offset,
+ u32 * data)
+{
+ u8 hopcount = 0xff;
+ u16 destid = rdev->destid;
+
+ if (rdev->rswitch) {
+ destid = rdev->rswitch->destid;
+ hopcount = rdev->rswitch->hopcount;
+ }
+
+ return rio_mport_read_config_32(rdev->net->hport, destid, hopcount,
+ offset, data);
+};
+
+/**
+ * rio_write_config_32 - Write 32 bits to configuration space
+ * @rdev: RIO device
+ * @offset: Offset into device configuration space
+ * @data: Data to be written
+ *
+ * Writes 32 bits of data to the specified offset within the
+ * RIO device's configuration space.
+ */
+static inline int rio_write_config_32(struct rio_dev *rdev, u32 offset,
+ u32 data)
+{
+ u8 hopcount = 0xff;
+ u16 destid = rdev->destid;
+
+ if (rdev->rswitch) {
+ destid = rdev->rswitch->destid;
+ hopcount = rdev->rswitch->hopcount;
+ }
+
+ return rio_mport_write_config_32(rdev->net->hport, destid, hopcount,
+ offset, data);
+};
+
+/**
+ * rio_read_config_16 - Read 16 bits from configuration space
+ * @rdev: RIO device
+ * @offset: Offset into device configuration space
+ * @data: Pointer to read data into
+ *
+ * Reads 16 bits of data from the specified offset within the
+ * RIO device's configuration space.
+ */
+static inline int rio_read_config_16(struct rio_dev *rdev, u32 offset,
+ u16 * data)
+{
+ u8 hopcount = 0xff;
+ u16 destid = rdev->destid;
+
+ if (rdev->rswitch) {
+ destid = rdev->rswitch->destid;
+ hopcount = rdev->rswitch->hopcount;
+ }
+
+ return rio_mport_read_config_16(rdev->net->hport, destid, hopcount,
+ offset, data);
+};
+
+/**
+ * rio_write_config_16 - Write 16 bits to configuration space
+ * @rdev: RIO device
+ * @offset: Offset into device configuration space
+ * @data: Data to be written
+ *
+ * Writes 16 bits of data to the specified offset within the
+ * RIO device's configuration space.
+ */
+static inline int rio_write_config_16(struct rio_dev *rdev, u32 offset,
+ u16 data)
+{
+ u8 hopcount = 0xff;
+ u16 destid = rdev->destid;
+
+ if (rdev->rswitch) {
+ destid = rdev->rswitch->destid;
+ hopcount = rdev->rswitch->hopcount;
+ }
+
+ return rio_mport_write_config_16(rdev->net->hport, destid, hopcount,
+ offset, data);
+};
+
+/**
+ * rio_read_config_8 - Read 8 bits from configuration space
+ * @rdev: RIO device
+ * @offset: Offset into device configuration space
+ * @data: Pointer to read data into
+ *
+ * Reads 8 bits of data from the specified offset within the
+ * RIO device's configuration space.
+ */
+static inline int rio_read_config_8(struct rio_dev *rdev, u32 offset, u8 * data)
+{
+ u8 hopcount = 0xff;
+ u16 destid = rdev->destid;
+
+ if (rdev->rswitch) {
+ destid = rdev->rswitch->destid;
+ hopcount = rdev->rswitch->hopcount;
+ }
+
+ return rio_mport_read_config_8(rdev->net->hport, destid, hopcount,
+ offset, data);
+};
+
+/**
+ * rio_write_config_8 - Write 8 bits to configuration space
+ * @rdev: RIO device
+ * @offset: Offset into device configuration space
+ * @data: Data to be written
+ *
+ * Writes 8 bits of data to the specified offset within the
+ * RIO device's configuration space.
+ */
+static inline int rio_write_config_8(struct rio_dev *rdev, u32 offset, u8 data)
+{
+ u8 hopcount = 0xff;
+ u16 destid = rdev->destid;
+
+ if (rdev->rswitch) {
+ destid = rdev->rswitch->destid;
+ hopcount = rdev->rswitch->hopcount;
+ }
+
+ return rio_mport_write_config_8(rdev->net->hport, destid, hopcount,
+ offset, data);
+};
+
+extern int rio_mport_send_doorbell(struct rio_mport *mport, u16 destid,
+ u16 data);
+
+/**
+ * rio_send_doorbell - Send a doorbell message to a device
+ * @rdev: RIO device
+ * @data: Doorbell message data
+ *
+ * Send a doorbell message to a RIO device. The doorbell message
+ * has a 16-bit info field provided by the @data argument.
+ */
+static inline int rio_send_doorbell(struct rio_dev *rdev, u16 data)
+{
+ return rio_mport_send_doorbell(rdev->net->hport, rdev->destid, data);
+};
+
+/**
+ * rio_init_mbox_res - Initialize a RIO mailbox resource
+ * @res: resource struct
+ * @start: start of mailbox range
+ * @end: end of mailbox range
+ *
+ * This function is used to initialize the fields of a resource
+ * for use as a mailbox resource. It initializes a range of
+ * mailboxes using the start and end arguments.
+ */
+static inline void rio_init_mbox_res(struct resource *res, int start, int end)
+{
+ memset(res, 0, sizeof(struct resource));
+ res->start = start;
+ res->end = end;
+ res->flags = RIO_RESOURCE_MAILBOX;
+}
+
+/**
+ * rio_init_dbell_res - Initialize a RIO doorbell resource
+ * @res: resource struct
+ * @start: start of doorbell range
+ * @end: end of doorbell range
+ *
+ * This function is used to initialize the fields of a resource
+ * for use as a doorbell resource. It initializes a range of
+ * doorbell messages using the start and end arguments.
+ */
+static inline void rio_init_dbell_res(struct resource *res, u16 start, u16 end)
+{
+ memset(res, 0, sizeof(struct resource));
+ res->start = start;
+ res->end = end;
+ res->flags = RIO_RESOURCE_DOORBELL;
+}
+
+/**
+ * RIO_DEVICE - macro used to describe a specific RIO device
+ * @vid: the 16 bit RIO vendor ID
+ * @did: the 16 bit RIO device ID
+ *
+ * This macro is used to create a struct rio_device_id that matches a
+ * specific device. The assembly vendor and assembly device fields
+ * will be set to %RIO_ANY_ID.
+ */
+#define RIO_DEVICE(dev,ven) \
+ .did = (dev), .vid = (ven), \
+ .asm_did = RIO_ANY_ID, .asm_vid = RIO_ANY_ID
+
+/* Mailbox management */
+extern int rio_request_outb_mbox(struct rio_mport *, void *, int, int,
+ void (*)(struct rio_mport *, void *,int, int));
+extern int rio_release_outb_mbox(struct rio_mport *, int);
+
+/**
+ * rio_add_outb_message - Add RIO message to an outbound mailbox queue
+ * @mport: RIO master port containing the outbound queue
+ * @rdev: RIO device the message is be sent to
+ * @mbox: The outbound mailbox queue
+ * @buffer: Pointer to the message buffer
+ * @len: Length of the message buffer
+ *
+ * Adds a RIO message buffer to an outbound mailbox queue for
+ * transmission. Returns 0 on success.
+ */
+static inline int rio_add_outb_message(struct rio_mport *mport,
+ struct rio_dev *rdev, int mbox,
+ void *buffer, size_t len)
+{
+ return rio_hw_add_outb_message(mport, rdev, mbox, buffer, len);
+}
+
+extern int rio_request_inb_mbox(struct rio_mport *, void *, int, int,
+ void (*)(struct rio_mport *, void *, int, int));
+extern int rio_release_inb_mbox(struct rio_mport *, int);
+
+/**
+ * rio_add_inb_buffer - Add buffer to an inbound mailbox queue
+ * @mport: Master port containing the inbound mailbox
+ * @mbox: The inbound mailbox number
+ * @buffer: Pointer to the message buffer
+ *
+ * Adds a buffer to an inbound mailbox queue for reception. Returns
+ * 0 on success.
+ */
+static inline int rio_add_inb_buffer(struct rio_mport *mport, int mbox,
+ void *buffer)
+{
+ return rio_hw_add_inb_buffer(mport, mbox, buffer);
+}
+
+/**
+ * rio_get_inb_message - Get A RIO message from an inbound mailbox queue
+ * @mport: Master port containing the inbound mailbox
+ * @mbox: The inbound mailbox number
+ * @buffer: Pointer to the message buffer
+ *
+ * Get a RIO message from an inbound mailbox queue. Returns 0 on success.
+ */
+static inline void *rio_get_inb_message(struct rio_mport *mport, int mbox)
+{
+ return rio_hw_get_inb_message(mport, mbox);
+}
+
+/* Doorbell management */
+extern int rio_request_inb_dbell(struct rio_mport *, void *, u16, u16,
+ void (*)(struct rio_mport *, void *, u16, u16, u16));
+extern int rio_release_inb_dbell(struct rio_mport *, u16, u16);
+extern struct resource *rio_request_outb_dbell(struct rio_dev *, u16, u16);
+extern int rio_release_outb_dbell(struct rio_dev *, struct resource *);
+
+/* Memory region management */
+int rio_claim_resource(struct rio_dev *, int);
+int rio_request_regions(struct rio_dev *, char *);
+void rio_release_regions(struct rio_dev *);
+int rio_request_region(struct rio_dev *, int, char *);
+void rio_release_region(struct rio_dev *, int);
+
+/* LDM support */
+int rio_register_driver(struct rio_driver *);
+void rio_unregister_driver(struct rio_driver *);
+struct rio_dev *rio_dev_get(struct rio_dev *);
+void rio_dev_put(struct rio_dev *);
+
+/**
+ * rio_name - Get the unique RIO device identifier
+ * @rdev: RIO device
+ *
+ * Get the unique RIO device identifier. Returns the device
+ * identifier string.
+ */
+static inline char *rio_name(struct rio_dev *rdev)
+{
+ return rdev->dev.bus_id;
+}
+
+/**
+ * rio_get_drvdata - Get RIO driver specific data
+ * @rdev: RIO device
+ *
+ * Get RIO driver specific data. Returns a pointer to the
+ * driver specific data.
+ */
+static inline void *rio_get_drvdata(struct rio_dev *rdev)
+{
+ return dev_get_drvdata(&rdev->dev);
+}
+
+/**
+ * rio_set_drvdata - Set RIO driver specific data
+ * @rdev: RIO device
+ * @data: Pointer to driver specific data
+ *
+ * Set RIO driver specific data. device struct driver data pointer
+ * is set to the @data argument.
+ */
+static inline void rio_set_drvdata(struct rio_dev *rdev, void *data)
+{
+ dev_set_drvdata(&rdev->dev, data);
+}
+
+/* Misc driver helpers */
+extern u16 rio_local_get_device_id(struct rio_mport *port);
+extern struct rio_dev *rio_get_device(u16 vid, u16 did, struct rio_dev *from);
+extern struct rio_dev *rio_get_asm(u16 vid, u16 did, u16 asm_vid, u16 asm_did,
+ struct rio_dev *from);
+
+#endif /* __KERNEL__ */
+#endif /* LINUX_RIO_DRV_H */
diff --git a/include/linux/rio_ids.h b/include/linux/rio_ids.h
new file mode 100644
index 000000000000..919d4e07d54e
--- /dev/null
+++ b/include/linux/rio_ids.h
@@ -0,0 +1,24 @@
+/*
+ * RapidIO devices
+ *
+ * Copyright 2005 MontaVista Software, Inc.
+ * Matt Porter <mporter@kernel.crashing.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.
+ */
+
+#ifndef LINUX_RIO_IDS_H
+#define LINUX_RIO_IDS_H
+
+#define RIO_ANY_ID 0xffff
+
+#define RIO_VID_FREESCALE 0x0002
+#define RIO_DID_MPC8560 0x0003
+
+#define RIO_VID_TUNDRA 0x000d
+#define RIO_DID_TSI500 0x0500
+
+#endif /* LINUX_RIO_IDS_H */
diff --git a/include/linux/rio_regs.h b/include/linux/rio_regs.h
new file mode 100644
index 000000000000..326540f9b54e
--- /dev/null
+++ b/include/linux/rio_regs.h
@@ -0,0 +1,215 @@
+/*
+ * RapidIO register definitions
+ *
+ * Copyright 2005 MontaVista Software, Inc.
+ * Matt Porter <mporter@kernel.crashing.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.
+ */
+
+#ifndef LINUX_RIO_REGS_H
+#define LINUX_RIO_REGS_H
+
+/*
+ * In RapidIO, each device has a 2MB configuration space that is
+ * accessed via maintenance transactions. Portions of configuration
+ * space are standardized and/or reserved.
+ */
+#define RIO_DEV_ID_CAR 0x00 /* [I] Device Identity CAR */
+#define RIO_DEV_INFO_CAR 0x04 /* [I] Device Information CAR */
+#define RIO_ASM_ID_CAR 0x08 /* [I] Assembly Identity CAR */
+#define RIO_ASM_ID_MASK 0xffff0000 /* [I] Asm ID Mask */
+#define RIO_ASM_VEN_ID_MASK 0x0000ffff /* [I] Asm Vend Mask */
+
+#define RIO_ASM_INFO_CAR 0x0c /* [I] Assembly Information CAR */
+#define RIO_ASM_REV_MASK 0xffff0000 /* [I] Asm Rev Mask */
+#define RIO_EXT_FTR_PTR_MASK 0x0000ffff /* [I] EF_PTR Mask */
+
+#define RIO_PEF_CAR 0x10 /* [I] Processing Element Features CAR */
+#define RIO_PEF_BRIDGE 0x80000000 /* [I] Bridge */
+#define RIO_PEF_MEMORY 0x40000000 /* [I] MMIO */
+#define RIO_PEF_PROCESSOR 0x20000000 /* [I] Processor */
+#define RIO_PEF_SWITCH 0x10000000 /* [I] Switch */
+#define RIO_PEF_INB_MBOX 0x00f00000 /* [II] Mailboxes */
+#define RIO_PEF_INB_MBOX0 0x00800000 /* [II] Mailbox 0 */
+#define RIO_PEF_INB_MBOX1 0x00400000 /* [II] Mailbox 1 */
+#define RIO_PEF_INB_MBOX2 0x00200000 /* [II] Mailbox 2 */
+#define RIO_PEF_INB_MBOX3 0x00100000 /* [II] Mailbox 3 */
+#define RIO_PEF_INB_DOORBELL 0x00080000 /* [II] Doorbells */
+#define RIO_PEF_CTLS 0x00000010 /* [III] CTLS */
+#define RIO_PEF_EXT_FEATURES 0x00000008 /* [I] EFT_PTR valid */
+#define RIO_PEF_ADDR_66 0x00000004 /* [I] 66 bits */
+#define RIO_PEF_ADDR_50 0x00000002 /* [I] 50 bits */
+#define RIO_PEF_ADDR_34 0x00000001 /* [I] 34 bits */
+
+#define RIO_SWP_INFO_CAR 0x14 /* [I] Switch Port Information CAR */
+#define RIO_SWP_INFO_PORT_TOTAL_MASK 0x0000ff00 /* [I] Total number of ports */
+#define RIO_SWP_INFO_PORT_NUM_MASK 0x000000ff /* [I] Maintenance transaction port number */
+#define RIO_GET_TOTAL_PORTS(x) ((x & RIO_SWP_INFO_PORT_TOTAL_MASK) >> 8)
+
+#define RIO_SRC_OPS_CAR 0x18 /* [I] Source Operations CAR */
+#define RIO_SRC_OPS_READ 0x00008000 /* [I] Read op */
+#define RIO_SRC_OPS_WRITE 0x00004000 /* [I] Write op */
+#define RIO_SRC_OPS_STREAM_WRITE 0x00002000 /* [I] Str-write op */
+#define RIO_SRC_OPS_WRITE_RESPONSE 0x00001000 /* [I] Write/resp op */
+#define RIO_SRC_OPS_DATA_MSG 0x00000800 /* [II] Data msg op */
+#define RIO_SRC_OPS_DOORBELL 0x00000400 /* [II] Doorbell op */
+#define RIO_SRC_OPS_ATOMIC_TST_SWP 0x00000100 /* [I] Atomic TAS op */
+#define RIO_SRC_OPS_ATOMIC_INC 0x00000080 /* [I] Atomic inc op */
+#define RIO_SRC_OPS_ATOMIC_DEC 0x00000040 /* [I] Atomic dec op */
+#define RIO_SRC_OPS_ATOMIC_SET 0x00000020 /* [I] Atomic set op */
+#define RIO_SRC_OPS_ATOMIC_CLR 0x00000010 /* [I] Atomic clr op */
+#define RIO_SRC_OPS_PORT_WRITE 0x00000004 /* [I] Port-write op */
+
+#define RIO_DST_OPS_CAR 0x1c /* Destination Operations CAR */
+#define RIO_DST_OPS_READ 0x00008000 /* [I] Read op */
+#define RIO_DST_OPS_WRITE 0x00004000 /* [I] Write op */
+#define RIO_DST_OPS_STREAM_WRITE 0x00002000 /* [I] Str-write op */
+#define RIO_DST_OPS_WRITE_RESPONSE 0x00001000 /* [I] Write/resp op */
+#define RIO_DST_OPS_DATA_MSG 0x00000800 /* [II] Data msg op */
+#define RIO_DST_OPS_DOORBELL 0x00000400 /* [II] Doorbell op */
+#define RIO_DST_OPS_ATOMIC_TST_SWP 0x00000100 /* [I] Atomic TAS op */
+#define RIO_DST_OPS_ATOMIC_INC 0x00000080 /* [I] Atomic inc op */
+#define RIO_DST_OPS_ATOMIC_DEC 0x00000040 /* [I] Atomic dec op */
+#define RIO_DST_OPS_ATOMIC_SET 0x00000020 /* [I] Atomic set op */
+#define RIO_DST_OPS_ATOMIC_CLR 0x00000010 /* [I] Atomic clr op */
+#define RIO_DST_OPS_PORT_WRITE 0x00000004 /* [I] Port-write op */
+
+#define RIO_OPS_READ 0x00008000 /* [I] Read op */
+#define RIO_OPS_WRITE 0x00004000 /* [I] Write op */
+#define RIO_OPS_STREAM_WRITE 0x00002000 /* [I] Str-write op */
+#define RIO_OPS_WRITE_RESPONSE 0x00001000 /* [I] Write/resp op */
+#define RIO_OPS_DATA_MSG 0x00000800 /* [II] Data msg op */
+#define RIO_OPS_DOORBELL 0x00000400 /* [II] Doorbell op */
+#define RIO_OPS_ATOMIC_TST_SWP 0x00000100 /* [I] Atomic TAS op */
+#define RIO_OPS_ATOMIC_INC 0x00000080 /* [I] Atomic inc op */
+#define RIO_OPS_ATOMIC_DEC 0x00000040 /* [I] Atomic dec op */
+#define RIO_OPS_ATOMIC_SET 0x00000020 /* [I] Atomic set op */
+#define RIO_OPS_ATOMIC_CLR 0x00000010 /* [I] Atomic clr op */
+#define RIO_OPS_PORT_WRITE 0x00000004 /* [I] Port-write op */
+
+ /* 0x20-0x3c *//* Reserved */
+
+#define RIO_MBOX_CSR 0x40 /* [II] Mailbox CSR */
+#define RIO_MBOX0_AVAIL 0x80000000 /* [II] Mbox 0 avail */
+#define RIO_MBOX0_FULL 0x40000000 /* [II] Mbox 0 full */
+#define RIO_MBOX0_EMPTY 0x20000000 /* [II] Mbox 0 empty */
+#define RIO_MBOX0_BUSY 0x10000000 /* [II] Mbox 0 busy */
+#define RIO_MBOX0_FAIL 0x08000000 /* [II] Mbox 0 fail */
+#define RIO_MBOX0_ERROR 0x04000000 /* [II] Mbox 0 error */
+#define RIO_MBOX1_AVAIL 0x00800000 /* [II] Mbox 1 avail */
+#define RIO_MBOX1_FULL 0x00200000 /* [II] Mbox 1 full */
+#define RIO_MBOX1_EMPTY 0x00200000 /* [II] Mbox 1 empty */
+#define RIO_MBOX1_BUSY 0x00100000 /* [II] Mbox 1 busy */
+#define RIO_MBOX1_FAIL 0x00080000 /* [II] Mbox 1 fail */
+#define RIO_MBOX1_ERROR 0x00040000 /* [II] Mbox 1 error */
+#define RIO_MBOX2_AVAIL 0x00008000 /* [II] Mbox 2 avail */
+#define RIO_MBOX2_FULL 0x00004000 /* [II] Mbox 2 full */
+#define RIO_MBOX2_EMPTY 0x00002000 /* [II] Mbox 2 empty */
+#define RIO_MBOX2_BUSY 0x00001000 /* [II] Mbox 2 busy */
+#define RIO_MBOX2_FAIL 0x00000800 /* [II] Mbox 2 fail */
+#define RIO_MBOX2_ERROR 0x00000400 /* [II] Mbox 2 error */
+#define RIO_MBOX3_AVAIL 0x00000080 /* [II] Mbox 3 avail */
+#define RIO_MBOX3_FULL 0x00000040 /* [II] Mbox 3 full */
+#define RIO_MBOX3_EMPTY 0x00000020 /* [II] Mbox 3 empty */
+#define RIO_MBOX3_BUSY 0x00000010 /* [II] Mbox 3 busy */
+#define RIO_MBOX3_FAIL 0x00000008 /* [II] Mbox 3 fail */
+#define RIO_MBOX3_ERROR 0x00000004 /* [II] Mbox 3 error */
+
+#define RIO_WRITE_PORT_CSR 0x44 /* [I] Write Port CSR */
+#define RIO_DOORBELL_CSR 0x44 /* [II] Doorbell CSR */
+#define RIO_DOORBELL_AVAIL 0x80000000 /* [II] Doorbell avail */
+#define RIO_DOORBELL_FULL 0x40000000 /* [II] Doorbell full */
+#define RIO_DOORBELL_EMPTY 0x20000000 /* [II] Doorbell empty */
+#define RIO_DOORBELL_BUSY 0x10000000 /* [II] Doorbell busy */
+#define RIO_DOORBELL_FAILED 0x08000000 /* [II] Doorbell failed */
+#define RIO_DOORBELL_ERROR 0x04000000 /* [II] Doorbell error */
+#define RIO_WRITE_PORT_AVAILABLE 0x00000080 /* [I] Write Port Available */
+#define RIO_WRITE_PORT_FULL 0x00000040 /* [I] Write Port Full */
+#define RIO_WRITE_PORT_EMPTY 0x00000020 /* [I] Write Port Empty */
+#define RIO_WRITE_PORT_BUSY 0x00000010 /* [I] Write Port Busy */
+#define RIO_WRITE_PORT_FAILED 0x00000008 /* [I] Write Port Failed */
+#define RIO_WRITE_PORT_ERROR 0x00000004 /* [I] Write Port Error */
+
+ /* 0x48 *//* Reserved */
+
+#define RIO_PELL_CTRL_CSR 0x4c /* [I] PE Logical Layer Control CSR */
+#define RIO_PELL_ADDR_66 0x00000004 /* [I] 66-bit addr */
+#define RIO_PELL_ADDR_50 0x00000002 /* [I] 50-bit addr */
+#define RIO_PELL_ADDR_34 0x00000001 /* [I] 34-bit addr */
+
+ /* 0x50-0x54 *//* Reserved */
+
+#define RIO_LCSH_BA 0x58 /* [I] LCS High Base Address */
+#define RIO_LCSL_BA 0x5c /* [I] LCS Base Address */
+
+#define RIO_DID_CSR 0x60 /* [III] Base Device ID CSR */
+
+ /* 0x64 *//* Reserved */
+
+#define RIO_HOST_DID_LOCK_CSR 0x68 /* [III] Host Base Device ID Lock CSR */
+#define RIO_COMPONENT_TAG_CSR 0x6c /* [III] Component Tag CSR */
+
+ /* 0x70-0xf8 *//* Reserved */
+ /* 0x100-0xfff8 *//* [I] Extended Features Space */
+ /* 0x10000-0xfffff8 *//* [I] Implementation-defined Space */
+
+/*
+ * Extended Features Space is a configuration space area where
+ * functionality is mapped into extended feature blocks via a
+ * singly linked list of extended feature pointers (EFT_PTR).
+ *
+ * Each extended feature block can be identified/located in
+ * Extended Features Space by walking the extended feature
+ * list starting with the Extended Feature Pointer located
+ * in the Assembly Information CAR.
+ *
+ * Extended Feature Blocks (EFBs) are identified with an assigned
+ * EFB ID. Extended feature block offsets in the definitions are
+ * relative to the offset of the EFB within the Extended Features
+ * Space.
+ */
+
+/* Helper macros to parse the Extended Feature Block header */
+#define RIO_EFB_PTR_MASK 0xffff0000
+#define RIO_EFB_ID_MASK 0x0000ffff
+#define RIO_GET_BLOCK_PTR(x) ((x & RIO_EFB_PTR_MASK) >> 16)
+#define RIO_GET_BLOCK_ID(x) (x & RIO_EFB_ID_MASK)
+
+/* Extended Feature Block IDs */
+#define RIO_EFB_PAR_EP_ID 0x0001 /* [IV] LP/LVDS EP Devices */
+#define RIO_EFB_PAR_EP_REC_ID 0x0002 /* [IV] LP/LVDS EP Recovery Devices */
+#define RIO_EFB_PAR_EP_FREE_ID 0x0003 /* [IV] LP/LVDS EP Free Devices */
+#define RIO_EFB_SER_EP_ID 0x0004 /* [VI] LP/Serial EP Devices */
+#define RIO_EFB_SER_EP_REC_ID 0x0005 /* [VI] LP/Serial EP Recovery Devices */
+#define RIO_EFB_SER_EP_FREE_ID 0x0006 /* [VI] LP/Serial EP Free Devices */
+
+/*
+ * Physical 8/16 LP-LVDS
+ * ID=0x0001, Generic End Point Devices
+ * ID=0x0002, Generic End Point Devices, software assisted recovery option
+ * ID=0x0003, Generic End Point Free Devices
+ *
+ * Physical LP-Serial
+ * ID=0x0004, Generic End Point Devices
+ * ID=0x0005, Generic End Point Devices, software assisted recovery option
+ * ID=0x0006, Generic End Point Free Devices
+ */
+#define RIO_PORT_MNT_HEADER 0x0000
+#define RIO_PORT_REQ_CTL_CSR 0x0020
+#define RIO_PORT_RSP_CTL_CSR 0x0024 /* 0x0001/0x0002 */
+#define RIO_PORT_GEN_CTL_CSR 0x003c
+#define RIO_PORT_GEN_HOST 0x80000000
+#define RIO_PORT_GEN_MASTER 0x40000000
+#define RIO_PORT_GEN_DISCOVERED 0x20000000
+#define RIO_PORT_N_MNT_REQ_CSR(x) (0x0040 + x*0x20) /* 0x0002 */
+#define RIO_PORT_N_MNT_RSP_CSR(x) (0x0044 + x*0x20) /* 0x0002 */
+#define RIO_PORT_N_ACK_STS_CSR(x) (0x0048 + x*0x20) /* 0x0002 */
+#define RIO_PORT_N_ERR_STS_CSR(x) (0x58 + x*0x20)
+#define PORT_N_ERR_STS_PORT_OK 0x00000002
+#define RIO_PORT_N_CTL_CSR(x) (0x5c + x*0x20)
+
+#endif /* LINUX_RIO_REGS_H */
diff --git a/include/linux/rmap.h b/include/linux/rmap.h
index e80fb7ee6efd..35b30e6c8cf8 100644
--- a/include/linux/rmap.h
+++ b/include/linux/rmap.h
@@ -95,8 +95,8 @@ int try_to_unmap(struct page *);
/*
* Called from mm/filemap_xip.c to unmap empty zero page
*/
-pte_t *page_check_address(struct page *, struct mm_struct *, unsigned long);
-
+pte_t *page_check_address(struct page *, struct mm_struct *,
+ unsigned long, spinlock_t **);
/*
* Used by swapoff to help locate where page is expected in vma.
diff --git a/include/linux/rslib.h b/include/linux/rslib.h
index 980c8f74d8dc..ace25acfdc97 100644
--- a/include/linux/rslib.h
+++ b/include/linux/rslib.h
@@ -1,15 +1,15 @@
-/*
+/*
* include/linux/rslib.h
*
* Overview:
* Generic Reed Solomon encoder / decoder library
- *
+ *
* Copyright (C) 2004 Thomas Gleixner (tglx@linutronix.de)
*
* RS code lifted from reed solomon library written by Phil Karn
* Copyright 2002 Phil Karn, KA9Q
*
- * $Id: rslib.h,v 1.3 2004/10/05 22:08:22 gleixner Exp $
+ * $Id: rslib.h,v 1.4 2005/11/07 11:14:52 gleixner Exp $
*
* 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
@@ -21,20 +21,20 @@
#include <linux/list.h>
-/**
+/**
* struct rs_control - rs control structure
- *
+ *
* @mm: Bits per symbol
* @nn: Symbols per block (= (1<<mm)-1)
* @alpha_to: log lookup table
* @index_of: Antilog lookup table
- * @genpoly: Generator polynomial
+ * @genpoly: Generator polynomial
* @nroots: Number of generator roots = number of parity symbols
* @fcr: First consecutive root, index form
- * @prim: Primitive element, index form
- * @iprim: prim-th root of 1, index form
- * @gfpoly: The primitive generator polynominal
- * @users: Users of this structure
+ * @prim: Primitive element, index form
+ * @iprim: prim-th root of 1, index form
+ * @gfpoly: The primitive generator polynominal
+ * @users: Users of this structure
* @list: List entry for the rs control list
*/
struct rs_control {
@@ -58,7 +58,7 @@ int encode_rs8(struct rs_control *rs, uint8_t *data, int len, uint16_t *par,
uint16_t invmsk);
#endif
#ifdef CONFIG_REED_SOLOMON_DEC8
-int decode_rs8(struct rs_control *rs, uint8_t *data, uint16_t *par, int len,
+int decode_rs8(struct rs_control *rs, uint8_t *data, uint16_t *par, int len,
uint16_t *s, int no_eras, int *eras_pos, uint16_t invmsk,
uint16_t *corr);
#endif
@@ -75,7 +75,7 @@ int decode_rs16(struct rs_control *rs, uint16_t *data, uint16_t *par, int len,
#endif
/* Create or get a matching rs control structure */
-struct rs_control *init_rs(int symsize, int gfpoly, int fcr, int prim,
+struct rs_control *init_rs(int symsize, int gfpoly, int fcr, int prim,
int nroots);
/* Release a rs control structure */
@@ -87,9 +87,9 @@ void free_rs(struct rs_control *rs);
* @x: the value to reduce
*
* where
- * rs->mm = number of bits per symbol
+ * rs->mm = number of bits per symbol
* rs->nn = (2^rs->mm) - 1
- *
+ *
* Simple arithmetic modulo would return a wrong result for values
* >= 3 * rs->nn
*/
diff --git a/include/linux/rwsem-spinlock.h b/include/linux/rwsem-spinlock.h
index b52a2af25f1f..f30f805080ae 100644
--- a/include/linux/rwsem-spinlock.h
+++ b/include/linux/rwsem-spinlock.h
@@ -61,5 +61,10 @@ extern void FASTCALL(__up_read(struct rw_semaphore *sem));
extern void FASTCALL(__up_write(struct rw_semaphore *sem));
extern void FASTCALL(__downgrade_write(struct rw_semaphore *sem));
+static inline int rwsem_is_locked(struct rw_semaphore *sem)
+{
+ return (sem->activity != 0);
+}
+
#endif /* __KERNEL__ */
#endif /* _LINUX_RWSEM_SPINLOCK_H */
diff --git a/include/linux/scatterlist.h b/include/linux/scatterlist.h
index 7f717e95ae37..66ff545552f7 100644
--- a/include/linux/scatterlist.h
+++ b/include/linux/scatterlist.h
@@ -1,14 +1,23 @@
#ifndef _LINUX_SCATTERLIST_H
#define _LINUX_SCATTERLIST_H
-static inline void sg_init_one(struct scatterlist *sg,
- u8 *buf, unsigned int buflen)
-{
- memset(sg, 0, sizeof(*sg));
+#include <asm/scatterlist.h>
+#include <linux/mm.h>
+#include <linux/string.h>
+static inline void sg_set_buf(struct scatterlist *sg, void *buf,
+ unsigned int buflen)
+{
sg->page = virt_to_page(buf);
sg->offset = offset_in_page(buf);
sg->length = buflen;
}
+static inline void sg_init_one(struct scatterlist *sg, void *buf,
+ unsigned int buflen)
+{
+ memset(sg, 0, sizeof(*sg));
+ sg_set_buf(sg, buf, buflen);
+}
+
#endif /* _LINUX_SCATTERLIST_H */
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 27519df0f987..2bbf968b23d9 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -249,6 +249,36 @@ arch_get_unmapped_area_topdown(struct file *filp, unsigned long addr,
extern void arch_unmap_area(struct mm_struct *, unsigned long);
extern void arch_unmap_area_topdown(struct mm_struct *, unsigned long);
+#if NR_CPUS >= CONFIG_SPLIT_PTLOCK_CPUS
+/*
+ * The mm counters are not protected by its page_table_lock,
+ * so must be incremented atomically.
+ */
+#ifdef ATOMIC64_INIT
+#define set_mm_counter(mm, member, value) atomic64_set(&(mm)->_##member, value)
+#define get_mm_counter(mm, member) ((unsigned long)atomic64_read(&(mm)->_##member))
+#define add_mm_counter(mm, member, value) atomic64_add(value, &(mm)->_##member)
+#define inc_mm_counter(mm, member) atomic64_inc(&(mm)->_##member)
+#define dec_mm_counter(mm, member) atomic64_dec(&(mm)->_##member)
+typedef atomic64_t mm_counter_t;
+#else /* !ATOMIC64_INIT */
+/*
+ * The counters wrap back to 0 at 2^32 * PAGE_SIZE,
+ * that is, at 16TB if using 4kB page size.
+ */
+#define set_mm_counter(mm, member, value) atomic_set(&(mm)->_##member, value)
+#define get_mm_counter(mm, member) ((unsigned long)atomic_read(&(mm)->_##member))
+#define add_mm_counter(mm, member, value) atomic_add(value, &(mm)->_##member)
+#define inc_mm_counter(mm, member) atomic_inc(&(mm)->_##member)
+#define dec_mm_counter(mm, member) atomic_dec(&(mm)->_##member)
+typedef atomic_t mm_counter_t;
+#endif /* !ATOMIC64_INIT */
+
+#else /* NR_CPUS < CONFIG_SPLIT_PTLOCK_CPUS */
+/*
+ * The mm counters are protected by its page_table_lock,
+ * so can be incremented directly.
+ */
#define set_mm_counter(mm, member, value) (mm)->_##member = (value)
#define get_mm_counter(mm, member) ((mm)->_##member)
#define add_mm_counter(mm, member, value) (mm)->_##member += (value)
@@ -256,6 +286,20 @@ extern void arch_unmap_area_topdown(struct mm_struct *, unsigned long);
#define dec_mm_counter(mm, member) (mm)->_##member--
typedef unsigned long mm_counter_t;
+#endif /* NR_CPUS < CONFIG_SPLIT_PTLOCK_CPUS */
+
+#define get_mm_rss(mm) \
+ (get_mm_counter(mm, file_rss) + get_mm_counter(mm, anon_rss))
+#define update_hiwater_rss(mm) do { \
+ unsigned long _rss = get_mm_rss(mm); \
+ if ((mm)->hiwater_rss < _rss) \
+ (mm)->hiwater_rss = _rss; \
+} while (0)
+#define update_hiwater_vm(mm) do { \
+ if ((mm)->hiwater_vm < (mm)->total_vm) \
+ (mm)->hiwater_vm = (mm)->total_vm; \
+} while (0)
+
struct mm_struct {
struct vm_area_struct * mmap; /* list of VMAs */
struct rb_root mm_rb;
@@ -279,15 +323,20 @@ struct mm_struct {
* by mmlist_lock
*/
+ /* Special counters, in some configurations protected by the
+ * page_table_lock, in other configurations by being atomic.
+ */
+ mm_counter_t _file_rss;
+ mm_counter_t _anon_rss;
+
+ unsigned long hiwater_rss; /* High-watermark of RSS usage */
+ unsigned long hiwater_vm; /* High-water virtual memory usage */
+
+ unsigned long total_vm, locked_vm, shared_vm, exec_vm;
+ unsigned long stack_vm, reserved_vm, def_flags, nr_ptes;
unsigned long start_code, end_code, start_data, end_data;
unsigned long start_brk, brk, start_stack;
unsigned long arg_start, arg_end, env_start, env_end;
- unsigned long total_vm, locked_vm, shared_vm;
- unsigned long exec_vm, stack_vm, reserved_vm, def_flags, nr_ptes;
-
- /* Special counters protected by the page_table_lock */
- mm_counter_t _rss;
- mm_counter_t _anon_rss;
unsigned long saved_auxv[AT_VECTOR_SIZE]; /* for /proc/PID/auxv */
@@ -308,11 +357,7 @@ struct mm_struct {
/* aio bits */
rwlock_t ioctx_list_lock;
struct kioctx *ioctx_list;
-
struct kioctx default_kioctx;
-
- unsigned long hiwater_rss; /* High-water RSS usage */
- unsigned long hiwater_vm; /* High-water virtual memory usage */
};
struct sighand_struct {
@@ -864,6 +909,7 @@ do { if (atomic_dec_and_test(&(tsk)->usage)) __put_task_struct(tsk); } while(0)
#define PF_SYNCWRITE 0x00200000 /* I am doing a sync write */
#define PF_BORROWED_MM 0x00400000 /* I am a kthread doing use_mm */
#define PF_RANDOMIZE 0x00800000 /* randomize virtual address space */
+#define PF_HOTPLUG_CPU 0x01000000 /* Currently performing CPU hotplug */
/*
* Only the _current_ task can read/write to tsk->flags, but other
@@ -895,7 +941,7 @@ extern int set_cpus_allowed(task_t *p, cpumask_t new_mask);
#else
static inline int set_cpus_allowed(task_t *p, cpumask_t new_mask)
{
- if (!cpus_intersects(new_mask, cpu_online_map))
+ if (!cpu_isset(0, new_mask))
return -EINVAL;
return 0;
}
@@ -1039,6 +1085,11 @@ extern int do_sigaltstack(const stack_t __user *, stack_t __user *, unsigned lon
#define SEND_SIG_PRIV ((struct siginfo *) 1)
#define SEND_SIG_FORCED ((struct siginfo *) 2)
+static inline int is_si_special(const struct siginfo *info)
+{
+ return info <= SEND_SIG_FORCED;
+}
+
/* True if we are on the alternate signal stack. */
static inline int on_sig_stack(unsigned long sp)
@@ -1166,7 +1217,7 @@ extern void unhash_process(struct task_struct *p);
/*
* Protects ->fs, ->files, ->mm, ->ptrace, ->group_info, ->comm, keyring
* subscriptions and synchronises with wait4(). Also used in procfs. Also
- * pins the final release of task.io_context.
+ * pins the final release of task.io_context. Also protects ->cpuset.
*
* Nests both inside and outside of read_lock(&tasklist_lock).
* It must not be nested with write_lock_irq(&tasklist_lock),
diff --git a/include/linux/sdladrv.h b/include/linux/sdladrv.h
index 78f634007fc6..c85e103d5e7b 100644
--- a/include/linux/sdladrv.h
+++ b/include/linux/sdladrv.h
@@ -52,12 +52,8 @@ typedef struct sdlahw
extern int sdla_setup (sdlahw_t* hw, void* sfm, unsigned len);
extern int sdla_down (sdlahw_t* hw);
-extern int sdla_inten (sdlahw_t* hw);
-extern int sdla_intde (sdlahw_t* hw);
-extern int sdla_intack (sdlahw_t* hw);
extern void S514_intack (sdlahw_t* hw, u32 int_status);
extern void read_S514_int_stat (sdlahw_t* hw, u32* int_status);
-extern int sdla_intr (sdlahw_t* hw);
extern int sdla_mapmem (sdlahw_t* hw, unsigned long addr);
extern int sdla_peek (sdlahw_t* hw, unsigned long addr, void* buf,
unsigned len);
diff --git a/include/linux/security.h b/include/linux/security.h
index 627382e74057..f7e0ae018712 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -30,6 +30,7 @@
#include <linux/shm.h>
#include <linux/msg.h>
#include <linux/sched.h>
+#include <linux/key.h>
struct ctl_table;
@@ -385,6 +386,9 @@ struct swap_info_struct;
* NULL to request the size of the buffer required. @size indicates
* the size of @buffer in bytes. Note that @name is the remainder
* of the attribute name after the security. prefix has been removed.
+ * @err is the return value from the preceding fs getxattr call,
+ * and can be used by the security module to determine whether it
+ * should try and canonicalize the attribute value.
* Return number of bytes used/required on success.
* @inode_setsecurity:
* Set the security label associated with @name for @inode from the
@@ -785,6 +789,27 @@ struct swap_info_struct;
* @sk_free_security:
* Deallocate security structure.
*
+ * Security hooks affecting all Key Management operations
+ *
+ * @key_alloc:
+ * Permit allocation of a key and assign security data. Note that key does
+ * not have a serial number assigned at this point.
+ * @key points to the key.
+ * Return 0 if permission is granted, -ve error otherwise.
+ * @key_free:
+ * Notification of destruction; free security data.
+ * @key points to the key.
+ * No return value.
+ * @key_permission:
+ * See whether a specific operational right is granted to a process on a
+ * key.
+ * @key_ref refers to the key (key pointer + possession attribute bit).
+ * @context points to the process to provide the context against which to
+ * evaluate the security data on the key.
+ * @perm describes the combination of permissions required of this key.
+ * Return 1 if permission granted, 0 if permission denied and -ve it the
+ * normal permissions model should be effected.
+ *
* Security hooks affecting all System V IPC operations.
*
* @ipc_permission:
@@ -1091,7 +1116,7 @@ struct security_operations {
int (*inode_getxattr) (struct dentry *dentry, char *name);
int (*inode_listxattr) (struct dentry *dentry);
int (*inode_removexattr) (struct dentry *dentry, char *name);
- int (*inode_getsecurity)(struct inode *inode, const char *name, void *buffer, size_t size);
+ int (*inode_getsecurity)(struct inode *inode, const char *name, void *buffer, size_t size, int err);
int (*inode_setsecurity)(struct inode *inode, const char *name, const void *value, size_t size, int flags);
int (*inode_listsecurity)(struct inode *inode, char *buffer, size_t buffer_size);
@@ -1210,9 +1235,20 @@ struct security_operations {
int (*socket_shutdown) (struct socket * sock, int how);
int (*socket_sock_rcv_skb) (struct sock * sk, struct sk_buff * skb);
int (*socket_getpeersec) (struct socket *sock, char __user *optval, int __user *optlen, unsigned len);
- int (*sk_alloc_security) (struct sock *sk, int family, int priority);
+ int (*sk_alloc_security) (struct sock *sk, int family, gfp_t priority);
void (*sk_free_security) (struct sock *sk);
#endif /* CONFIG_SECURITY_NETWORK */
+
+ /* key management security hooks */
+#ifdef CONFIG_KEYS
+ int (*key_alloc)(struct key *key);
+ void (*key_free)(struct key *key);
+ int (*key_permission)(key_ref_t key_ref,
+ struct task_struct *context,
+ key_perm_t perm);
+
+#endif /* CONFIG_KEYS */
+
};
/* global variables */
@@ -1580,11 +1616,11 @@ static inline int security_inode_removexattr (struct dentry *dentry, char *name)
return security_ops->inode_removexattr (dentry, name);
}
-static inline int security_inode_getsecurity(struct inode *inode, const char *name, void *buffer, size_t size)
+static inline int security_inode_getsecurity(struct inode *inode, const char *name, void *buffer, size_t size, int err)
{
if (unlikely (IS_PRIVATE (inode)))
return 0;
- return security_ops->inode_getsecurity(inode, name, buffer, size);
+ return security_ops->inode_getsecurity(inode, name, buffer, size, err);
}
static inline int security_inode_setsecurity(struct inode *inode, const char *name, const void *value, size_t size, int flags)
@@ -2222,7 +2258,7 @@ static inline int security_inode_removexattr (struct dentry *dentry, char *name)
return cap_inode_removexattr(dentry, name);
}
-static inline int security_inode_getsecurity(struct inode *inode, const char *name, void *buffer, size_t size)
+static inline int security_inode_getsecurity(struct inode *inode, const char *name, void *buffer, size_t size, int err)
{
return -EOPNOTSUPP;
}
@@ -2761,5 +2797,45 @@ static inline void security_sk_free(struct sock *sk)
}
#endif /* CONFIG_SECURITY_NETWORK */
+#ifdef CONFIG_KEYS
+#ifdef CONFIG_SECURITY
+static inline int security_key_alloc(struct key *key)
+{
+ return security_ops->key_alloc(key);
+}
+
+static inline void security_key_free(struct key *key)
+{
+ security_ops->key_free(key);
+}
+
+static inline int security_key_permission(key_ref_t key_ref,
+ struct task_struct *context,
+ key_perm_t perm)
+{
+ return security_ops->key_permission(key_ref, context, perm);
+}
+
+#else
+
+static inline int security_key_alloc(struct key *key)
+{
+ return 0;
+}
+
+static inline void security_key_free(struct key *key)
+{
+}
+
+static inline int security_key_permission(key_ref_t key_ref,
+ struct task_struct *context,
+ key_perm_t perm)
+{
+ return 0;
+}
+
+#endif
+#endif /* CONFIG_KEYS */
+
#endif /* ! __LINUX_SECURITY_H */
diff --git a/include/linux/sem.h b/include/linux/sem.h
index 106f9757339a..3c1f1120fe88 100644
--- a/include/linux/sem.h
+++ b/include/linux/sem.h
@@ -79,6 +79,8 @@ struct seminfo {
#ifdef __KERNEL__
+struct task_struct;
+
/* One semaphore structure for each semaphore in the system. */
struct sem {
int semval; /* current value */
diff --git a/include/linux/serial.h b/include/linux/serial.h
index 12cd9cf65e8f..33fc8cb8ddfb 100644
--- a/include/linux/serial.h
+++ b/include/linux/serial.h
@@ -11,6 +11,7 @@
#define _LINUX_SERIAL_H
#ifdef __KERNEL__
+#include <linux/types.h>
#include <asm/page.h>
/*
diff --git a/include/linux/serial_8250.h b/include/linux/serial_8250.h
index 317a979b24de..cee302aefdb7 100644
--- a/include/linux/serial_8250.h
+++ b/include/linux/serial_8250.h
@@ -12,7 +12,7 @@
#define _LINUX_SERIAL_8250_H
#include <linux/serial_core.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
/*
* This is the platform device platform_data structure
@@ -42,6 +42,7 @@ enum {
PLAT8250_DEV_BOCA,
PLAT8250_DEV_HUB6,
PLAT8250_DEV_MCA,
+ PLAT8250_DEV_AU1X00,
};
/*
diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h
index 27db8da43aa4..a3ac92b19aca 100644
--- a/include/linux/serial_core.h
+++ b/include/linux/serial_core.h
@@ -117,7 +117,9 @@
#define PORT_M32R_SIO 68
/*Digi jsm */
-#define PORT_JSM 65
+#define PORT_JSM 69
+
+#define PORT_IP3106 70
#ifdef __KERNEL__
@@ -209,6 +211,7 @@ struct uart_port {
#define UPIO_HUB6 (1)
#define UPIO_MEM (2)
#define UPIO_MEM32 (3)
+#define UPIO_AU (4) /* Au1x00 type IO */
unsigned int read_status_mask; /* driver specific */
unsigned int ignore_status_mask; /* driver specific */
diff --git a/include/linux/serial_ip3106.h b/include/linux/serial_ip3106.h
new file mode 100644
index 000000000000..f500ac602c5c
--- /dev/null
+++ b/include/linux/serial_ip3106.h
@@ -0,0 +1,81 @@
+/*
+ * Embedded Alley Solutions, source@embeddedalley.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
+ */
+
+#ifndef _LINUX_SERIAL_IP3106_H
+#define _LINUX_SERIAL_IP3106_H
+
+#include <linux/serial_core.h>
+#include <linux/device.h>
+
+#define IP3106_NR_PORTS 2
+
+struct ip3106_port {
+ struct uart_port port;
+ struct timer_list timer;
+ unsigned int old_status;
+};
+
+/* register offsets */
+#define IP3106_LCR 0
+#define IP3106_MCR 0x004
+#define IP3106_BAUD 0x008
+#define IP3106_CFG 0x00c
+#define IP3106_FIFO 0x028
+#define IP3106_ISTAT 0xfe0
+#define IP3106_IEN 0xfe4
+#define IP3106_ICLR 0xfe8
+#define IP3106_ISET 0xfec
+#define IP3106_PD 0xff4
+#define IP3106_MID 0xffc
+
+#define IP3106_UART_LCR_TXBREAK (1<<30)
+#define IP3106_UART_LCR_PAREVN 0x10000000
+#define IP3106_UART_LCR_PAREN 0x08000000
+#define IP3106_UART_LCR_2STOPB 0x04000000
+#define IP3106_UART_LCR_8BIT 0x01000000
+#define IP3106_UART_LCR_TX_RST 0x00040000
+#define IP3106_UART_LCR_RX_RST 0x00020000
+#define IP3106_UART_LCR_RX_NEXT 0x00010000
+
+#define IP3106_UART_MCR_SCR 0xFF000000
+#define IP3106_UART_MCR_DCD 0x00800000
+#define IP3106_UART_MCR_CTS 0x00100000
+#define IP3106_UART_MCR_LOOP 0x00000010
+#define IP3106_UART_MCR_RTS 0x00000002
+#define IP3106_UART_MCR_DTR 0x00000001
+
+#define IP3106_UART_INT_TX 0x00000080
+#define IP3106_UART_INT_EMPTY 0x00000040
+#define IP3106_UART_INT_RCVTO 0x00000020
+#define IP3106_UART_INT_RX 0x00000010
+#define IP3106_UART_INT_RXOVRN 0x00000008
+#define IP3106_UART_INT_FRERR 0x00000004
+#define IP3106_UART_INT_BREAK 0x00000002
+#define IP3106_UART_INT_PARITY 0x00000001
+#define IP3106_UART_INT_ALLRX 0x0000003F
+#define IP3106_UART_INT_ALLTX 0x000000C0
+
+#define IP3106_UART_FIFO_TXFIFO 0x001F0000
+#define IP3106_UART_FIFO_TXFIFO_STA (0x1f<<16)
+#define IP3106_UART_FIFO_RXBRK 0x00008000
+#define IP3106_UART_FIFO_RXFE 0x00004000
+#define IP3106_UART_FIFO_RXPAR 0x00002000
+#define IP3106_UART_FIFO_RXFIFO 0x00001F00
+#define IP3106_UART_FIFO_RBRTHR 0x000000FF
+
+#endif
diff --git a/include/linux/shm.h b/include/linux/shm.h
index 80113a1f60bc..a2c896ad0bef 100644
--- a/include/linux/shm.h
+++ b/include/linux/shm.h
@@ -92,6 +92,7 @@ struct shmid_kernel /* private to the kernel */
#define SHM_DEST 01000 /* segment will be destroyed on last detach */
#define SHM_LOCKED 02000 /* segment will not be swapped */
#define SHM_HUGETLB 04000 /* segment will use huge TLB pages */
+#define SHM_NORESERVE 010000 /* don't check for reservations */
#ifdef CONFIG_SYSVIPC
long do_shmat(int shmid, char __user *shmaddr, int shmflg, unsigned long *addr);
diff --git a/include/linux/signal.h b/include/linux/signal.h
index 7be18b5e2fb4..5dd5f02c5c5f 100644
--- a/include/linux/signal.h
+++ b/include/linux/signal.h
@@ -25,7 +25,6 @@
struct sigqueue {
struct list_head list;
- spinlock_t *lock;
int flags;
siginfo_t info;
struct user_struct *user;
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 8f5d9e7f8734..0a8ea8b35816 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -137,6 +137,8 @@ struct skb_shared_info {
unsigned int nr_frags;
unsigned short tso_size;
unsigned short tso_segs;
+ unsigned short ufo_size;
+ unsigned int ip6_frag_id;
struct sk_buff *frag_list;
skb_frag_t frags[MAX_SKB_FRAGS];
};
@@ -171,7 +173,6 @@ enum {
* struct sk_buff - socket buffer
* @next: Next buffer in list
* @prev: Previous buffer in list
- * @list: List we are on
* @sk: Socket we are owned by
* @tstamp: Time we arrived
* @dev: Device we arrived on/are leaving by
@@ -190,6 +191,7 @@ enum {
* @cloned: Head may be cloned (check refcnt to be sure)
* @nohdr: Payload reference only, must not modify header
* @pkt_type: Packet class
+ * @fclone: skbuff clone status
* @ip_summed: Driver fed us an IP checksum
* @priority: Packet queueing priority
* @users: User count - see {datagram,tcp}.c
@@ -202,6 +204,7 @@ enum {
* @destructor: Destruct function
* @nfmark: Can be used for communication between hooks
* @nfct: Associated connection, if any
+ * @ipvs_property: skbuff is owned by ipvs
* @nfctinfo: Relationship of this skb to the connection
* @nf_bridge: Saved data about a bridged frame - see br_netfilter.c
* @tc_index: Traffic control index
@@ -271,6 +274,9 @@ struct sk_buff {
#if defined(CONFIG_IP_VS) || defined(CONFIG_IP_VS_MODULE)
__u8 ipvs_property:1;
#endif
+#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
+ struct sk_buff *nfct_reasm;
+#endif
#ifdef CONFIG_BRIDGE_NETFILTER
struct nf_bridge_info *nf_bridge;
#endif
@@ -340,6 +346,11 @@ extern void skb_over_panic(struct sk_buff *skb, int len,
extern void skb_under_panic(struct sk_buff *skb, int len,
void *here);
+extern int skb_append_datato_frags(struct sock *sk, struct sk_buff *skb,
+ int getfrag(void *from, char *to, int offset,
+ int len,int odd, struct sk_buff *skb),
+ void *from, int length);
+
struct skb_seq_state
{
__u32 lower_offset;
@@ -595,23 +606,23 @@ static inline void skb_queue_head_init(struct sk_buff_head *list)
*/
/**
- * __skb_queue_head - queue a buffer at the list head
+ * __skb_queue_after - queue a buffer at the list head
* @list: list to use
+ * @prev: place after this buffer
* @newsk: buffer to queue
*
- * Queue a buffer at the start of a list. This function takes no locks
+ * Queue a buffer int the middle of a list. This function takes no locks
* and you must therefore hold required locks before calling it.
*
* A buffer cannot be placed on two lists at the same time.
*/
-extern void skb_queue_head(struct sk_buff_head *list, struct sk_buff *newsk);
-static inline void __skb_queue_head(struct sk_buff_head *list,
- struct sk_buff *newsk)
+static inline void __skb_queue_after(struct sk_buff_head *list,
+ struct sk_buff *prev,
+ struct sk_buff *newsk)
{
- struct sk_buff *prev, *next;
-
+ struct sk_buff *next;
list->qlen++;
- prev = (struct sk_buff *)list;
+
next = prev->next;
newsk->next = next;
newsk->prev = prev;
@@ -619,6 +630,23 @@ static inline void __skb_queue_head(struct sk_buff_head *list,
}
/**
+ * __skb_queue_head - queue a buffer at the list head
+ * @list: list to use
+ * @newsk: buffer to queue
+ *
+ * Queue a buffer at the start of a list. This function takes no locks
+ * and you must therefore hold required locks before calling it.
+ *
+ * A buffer cannot be placed on two lists at the same time.
+ */
+extern void skb_queue_head(struct sk_buff_head *list, struct sk_buff *newsk);
+static inline void __skb_queue_head(struct sk_buff_head *list,
+ struct sk_buff *newsk)
+{
+ __skb_queue_after(list, (struct sk_buff *)list, newsk);
+}
+
+/**
* __skb_queue_tail - queue a buffer at the list tail
* @list: list to use
* @newsk: buffer to queue
@@ -1195,6 +1223,11 @@ static inline void kunmap_skb_frag(void *vaddr)
prefetch(skb->next), (skb != (struct sk_buff *)(queue)); \
skb = skb->next)
+#define skb_queue_reverse_walk(queue, skb) \
+ for (skb = (queue)->prev; \
+ prefetch(skb->prev), (skb != (struct sk_buff *)(queue)); \
+ skb = skb->prev)
+
extern struct sk_buff *skb_recv_datagram(struct sock *sk, unsigned flags,
int noblock, int *err);
@@ -1203,8 +1236,7 @@ extern unsigned int datagram_poll(struct file *file, struct socket *sock,
extern int skb_copy_datagram_iovec(const struct sk_buff *from,
int offset, struct iovec *to,
int size);
-extern int skb_copy_and_csum_datagram_iovec(const
- struct sk_buff *skb,
+extern int skb_copy_and_csum_datagram_iovec(struct sk_buff *skb,
int hlen,
struct iovec *iov);
extern void skb_free_datagram(struct sock *sk, struct sk_buff *skb);
@@ -1272,6 +1304,30 @@ static inline void skb_set_timestamp(struct sk_buff *skb, const struct timeval *
extern void __net_timestamp(struct sk_buff *skb);
+extern unsigned int __skb_checksum_complete(struct sk_buff *skb);
+
+/**
+ * skb_checksum_complete - Calculate checksum of an entire packet
+ * @skb: packet to process
+ *
+ * This function calculates the checksum over the entire packet plus
+ * the value of skb->csum. The latter can be used to supply the
+ * checksum of a pseudo header as used by TCP/UDP. It returns the
+ * checksum.
+ *
+ * For protocols that contain complete checksums such as ICMP/TCP/UDP,
+ * this function can be used to verify that checksum on received
+ * packets. In that case the function should return zero if the
+ * checksum is correct. In particular, this function will return zero
+ * if skb->ip_summed is CHECKSUM_UNNECESSARY which indicates that the
+ * hardware has already verified the correctness of the checksum.
+ */
+static inline unsigned int skb_checksum_complete(struct sk_buff *skb)
+{
+ return skb->ip_summed != CHECKSUM_UNNECESSARY &&
+ __skb_checksum_complete(skb);
+}
+
#ifdef CONFIG_NETFILTER
static inline void nf_conntrack_put(struct nf_conntrack *nfct)
{
@@ -1283,10 +1339,26 @@ static inline void nf_conntrack_get(struct nf_conntrack *nfct)
if (nfct)
atomic_inc(&nfct->use);
}
+#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
+static inline void nf_conntrack_get_reasm(struct sk_buff *skb)
+{
+ if (skb)
+ atomic_inc(&skb->users);
+}
+static inline void nf_conntrack_put_reasm(struct sk_buff *skb)
+{
+ if (skb)
+ kfree_skb(skb);
+}
+#endif
static inline void nf_reset(struct sk_buff *skb)
{
nf_conntrack_put(skb->nfct);
skb->nfct = NULL;
+#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
+ nf_conntrack_put_reasm(skb->nfct_reasm);
+ skb->nfct_reasm = NULL;
+#endif
}
#ifdef CONFIG_BRIDGE_NETFILTER
diff --git a/include/linux/slab.h b/include/linux/slab.h
index 5fc04a16ecb0..d1ea4051b996 100644
--- a/include/linux/slab.h
+++ b/include/linux/slab.h
@@ -9,7 +9,7 @@
#if defined(__KERNEL__)
-typedef struct kmem_cache_s kmem_cache_t;
+typedef struct kmem_cache kmem_cache_t;
#include <linux/config.h> /* kmalloc_sizes.h needs CONFIG_ options */
#include <linux/gfp.h>
@@ -121,7 +121,7 @@ extern unsigned int ksize(const void *);
extern void *kmem_cache_alloc_node(kmem_cache_t *, gfp_t flags, int node);
extern void *kmalloc_node(size_t size, gfp_t flags, int node);
#else
-static inline void *kmem_cache_alloc_node(kmem_cache_t *cachep, int flags, int node)
+static inline void *kmem_cache_alloc_node(kmem_cache_t *cachep, gfp_t flags, int node)
{
return kmem_cache_alloc(cachep, flags);
}
diff --git a/include/linux/spinlock.h b/include/linux/spinlock.h
index cdc99a27840d..0e9682c9def5 100644
--- a/include/linux/spinlock.h
+++ b/include/linux/spinlock.h
@@ -171,23 +171,42 @@ extern int __lockfunc generic__raw_read_trylock(raw_rwlock_t *lock);
#define write_lock_irq(lock) _write_lock_irq(lock)
#define write_lock_bh(lock) _write_lock_bh(lock)
-#define spin_unlock(lock) _spin_unlock(lock)
-#define write_unlock(lock) _write_unlock(lock)
-#define read_unlock(lock) _read_unlock(lock)
+/*
+ * We inline the unlock functions in the nondebug case:
+ */
+#if defined(CONFIG_DEBUG_SPINLOCK) || defined(CONFIG_PREEMPT) || !defined(CONFIG_SMP)
+# define spin_unlock(lock) _spin_unlock(lock)
+# define read_unlock(lock) _read_unlock(lock)
+# define write_unlock(lock) _write_unlock(lock)
+#else
+# define spin_unlock(lock) __raw_spin_unlock(&(lock)->raw_lock)
+# define read_unlock(lock) __raw_read_unlock(&(lock)->raw_lock)
+# define write_unlock(lock) __raw_write_unlock(&(lock)->raw_lock)
+#endif
+
+#if defined(CONFIG_DEBUG_SPINLOCK) || defined(CONFIG_PREEMPT) || !defined(CONFIG_SMP)
+# define spin_unlock_irq(lock) _spin_unlock_irq(lock)
+# define read_unlock_irq(lock) _read_unlock_irq(lock)
+# define write_unlock_irq(lock) _write_unlock_irq(lock)
+#else
+# define spin_unlock_irq(lock) \
+ do { __raw_spin_unlock(&(lock)->raw_lock); local_irq_enable(); } while (0)
+# define read_unlock_irq(lock) \
+ do { __raw_read_unlock(&(lock)->raw_lock); local_irq_enable(); } while (0)
+# define write_unlock_irq(lock) \
+ do { __raw_write_unlock(&(lock)->raw_lock); local_irq_enable(); } while (0)
+#endif
#define spin_unlock_irqrestore(lock, flags) \
_spin_unlock_irqrestore(lock, flags)
-#define spin_unlock_irq(lock) _spin_unlock_irq(lock)
#define spin_unlock_bh(lock) _spin_unlock_bh(lock)
#define read_unlock_irqrestore(lock, flags) \
_read_unlock_irqrestore(lock, flags)
-#define read_unlock_irq(lock) _read_unlock_irq(lock)
#define read_unlock_bh(lock) _read_unlock_bh(lock)
#define write_unlock_irqrestore(lock, flags) \
_write_unlock_irqrestore(lock, flags)
-#define write_unlock_irq(lock) _write_unlock_irq(lock)
#define write_unlock_bh(lock) _write_unlock_bh(lock)
#define spin_trylock_bh(lock) __cond_lock(_spin_trylock_bh(lock))
diff --git a/include/linux/stallion.h b/include/linux/stallion.h
index e89b77b6505a..13a37f137ea2 100644
--- a/include/linux/stallion.h
+++ b/include/linux/stallion.h
@@ -21,8 +21,6 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#include <linux/version.h>
-
/*****************************************************************************/
#ifndef _STALLION_H
#define _STALLION_H
diff --git a/include/linux/sunrpc/auth.h b/include/linux/sunrpc/auth.h
index 04ebc24db348..b68c11a2d6dd 100644
--- a/include/linux/sunrpc/auth.h
+++ b/include/linux/sunrpc/auth.h
@@ -66,7 +66,12 @@ struct rpc_cred_cache {
struct rpc_auth {
unsigned int au_cslack; /* call cred size estimate */
- unsigned int au_rslack; /* reply verf size guess */
+ /* guess at number of u32's auth adds before
+ * reply data; normally the verifier size: */
+ unsigned int au_rslack;
+ /* for gss, used to calculate au_rslack: */
+ unsigned int au_verfsize;
+
unsigned int au_flags; /* various flags */
struct rpc_authops * au_ops; /* operations */
rpc_authflavor_t au_flavor; /* pseudoflavor (note may
diff --git a/include/linux/sunrpc/debug.h b/include/linux/sunrpc/debug.h
index eadb31e3c198..1a42d902bc11 100644
--- a/include/linux/sunrpc/debug.h
+++ b/include/linux/sunrpc/debug.h
@@ -32,6 +32,7 @@
#define RPCDBG_AUTH 0x0010
#define RPCDBG_PMAP 0x0020
#define RPCDBG_SCHED 0x0040
+#define RPCDBG_TRANS 0x0080
#define RPCDBG_SVCSOCK 0x0100
#define RPCDBG_SVCDSP 0x0200
#define RPCDBG_MISC 0x0400
@@ -94,6 +95,8 @@ enum {
CTL_NLMDEBUG,
CTL_SLOTTABLE_UDP,
CTL_SLOTTABLE_TCP,
+ CTL_MIN_RESVPORT,
+ CTL_MAX_RESVPORT,
};
#endif /* _LINUX_SUNRPC_DEBUG_H_ */
diff --git a/include/linux/sunrpc/gss_api.h b/include/linux/sunrpc/gss_api.h
index 689262f63059..9b8bcf125c18 100644
--- a/include/linux/sunrpc/gss_api.h
+++ b/include/linux/sunrpc/gss_api.h
@@ -40,14 +40,21 @@ int gss_import_sec_context(
struct gss_ctx **ctx_id);
u32 gss_get_mic(
struct gss_ctx *ctx_id,
- u32 qop,
struct xdr_buf *message,
struct xdr_netobj *mic_token);
u32 gss_verify_mic(
struct gss_ctx *ctx_id,
struct xdr_buf *message,
- struct xdr_netobj *mic_token,
- u32 *qstate);
+ struct xdr_netobj *mic_token);
+u32 gss_wrap(
+ struct gss_ctx *ctx_id,
+ int offset,
+ struct xdr_buf *outbuf,
+ struct page **inpages);
+u32 gss_unwrap(
+ struct gss_ctx *ctx_id,
+ int offset,
+ struct xdr_buf *inbuf);
u32 gss_delete_sec_context(
struct gss_ctx **ctx_id);
@@ -56,7 +63,6 @@ char *gss_service_to_auth_domain_name(struct gss_api_mech *, u32 service);
struct pf_desc {
u32 pseudoflavor;
- u32 qop;
u32 service;
char *name;
char *auth_domain_name;
@@ -85,14 +91,21 @@ struct gss_api_ops {
struct gss_ctx *ctx_id);
u32 (*gss_get_mic)(
struct gss_ctx *ctx_id,
- u32 qop,
struct xdr_buf *message,
struct xdr_netobj *mic_token);
u32 (*gss_verify_mic)(
struct gss_ctx *ctx_id,
struct xdr_buf *message,
- struct xdr_netobj *mic_token,
- u32 *qstate);
+ struct xdr_netobj *mic_token);
+ u32 (*gss_wrap)(
+ struct gss_ctx *ctx_id,
+ int offset,
+ struct xdr_buf *outbuf,
+ struct page **inpages);
+ u32 (*gss_unwrap)(
+ struct gss_ctx *ctx_id,
+ int offset,
+ struct xdr_buf *buf);
void (*gss_delete_sec_context)(
void *internal_ctx_id);
};
diff --git a/include/linux/sunrpc/gss_err.h b/include/linux/sunrpc/gss_err.h
index 92608a2e574c..a6807867bd21 100644
--- a/include/linux/sunrpc/gss_err.h
+++ b/include/linux/sunrpc/gss_err.h
@@ -66,16 +66,6 @@ typedef unsigned int OM_uint32;
/*
- * Define the default Quality of Protection for per-message services. Note
- * that an implementation that offers multiple levels of QOP may either reserve
- * a value (for example zero, as assumed here) to mean "default protection", or
- * alternatively may simply equate GSS_C_QOP_DEFAULT to a specific explicit
- * QOP value. However a value of 0 should always be interpreted by a GSSAPI
- * implementation as a request for the default protection level.
- */
-#define GSS_C_QOP_DEFAULT 0
-
-/*
* Expiration time of 2^32-1 seconds means infinite lifetime for a
* credential or security context
*/
diff --git a/include/linux/sunrpc/gss_krb5.h b/include/linux/sunrpc/gss_krb5.h
index ffe31d2eb9ec..2c3601d31045 100644
--- a/include/linux/sunrpc/gss_krb5.h
+++ b/include/linux/sunrpc/gss_krb5.h
@@ -116,18 +116,22 @@ enum seal_alg {
s32
make_checksum(s32 cksumtype, char *header, int hdrlen, struct xdr_buf *body,
- struct xdr_netobj *cksum);
+ int body_offset, struct xdr_netobj *cksum);
+
+u32 gss_get_mic_kerberos(struct gss_ctx *, struct xdr_buf *,
+ struct xdr_netobj *);
+
+u32 gss_verify_mic_kerberos(struct gss_ctx *, struct xdr_buf *,
+ struct xdr_netobj *);
u32
-krb5_make_token(struct krb5_ctx *context_handle, int qop_req,
- struct xdr_buf *input_message_buffer,
- struct xdr_netobj *output_message_buffer, int toktype);
+gss_wrap_kerberos(struct gss_ctx *ctx_id, int offset,
+ struct xdr_buf *outbuf, struct page **pages);
u32
-krb5_read_token(struct krb5_ctx *context_handle,
- struct xdr_netobj *input_token_buffer,
- struct xdr_buf *message_buffer,
- int *qop_state, int toktype);
+gss_unwrap_kerberos(struct gss_ctx *ctx_id, int offset,
+ struct xdr_buf *buf);
+
u32
krb5_encrypt(struct crypto_tfm * key,
@@ -137,6 +141,13 @@ u32
krb5_decrypt(struct crypto_tfm * key,
void *iv, void *in, void *out, int length);
+int
+gss_encrypt_xdr_buf(struct crypto_tfm *tfm, struct xdr_buf *outbuf, int offset,
+ struct page **pages);
+
+int
+gss_decrypt_xdr_buf(struct crypto_tfm *tfm, struct xdr_buf *inbuf, int offset);
+
s32
krb5_make_seq_num(struct crypto_tfm * key,
int direction,
diff --git a/include/linux/sunrpc/gss_spkm3.h b/include/linux/sunrpc/gss_spkm3.h
index b5c9968c3c17..0beb2cf00a84 100644
--- a/include/linux/sunrpc/gss_spkm3.h
+++ b/include/linux/sunrpc/gss_spkm3.h
@@ -41,9 +41,9 @@ struct spkm3_ctx {
#define SPKM_WRAP_TOK 5
#define SPKM_DEL_TOK 6
-u32 spkm3_make_token(struct spkm3_ctx *ctx, int qop_req, struct xdr_buf * text, struct xdr_netobj * token, int toktype);
+u32 spkm3_make_token(struct spkm3_ctx *ctx, struct xdr_buf * text, struct xdr_netobj * token, int toktype);
-u32 spkm3_read_token(struct spkm3_ctx *ctx, struct xdr_netobj *read_token, struct xdr_buf *message_buffer, int *qop_state, int toktype);
+u32 spkm3_read_token(struct spkm3_ctx *ctx, struct xdr_netobj *read_token, struct xdr_buf *message_buffer, int toktype);
#define CKSUMTYPE_RSA_MD5 0x0007
diff --git a/include/linux/sunrpc/msg_prot.h b/include/linux/sunrpc/msg_prot.h
index 15f115332389..f43f237360ae 100644
--- a/include/linux/sunrpc/msg_prot.h
+++ b/include/linux/sunrpc/msg_prot.h
@@ -76,5 +76,30 @@ enum rpc_auth_stat {
#define RPC_MAXNETNAMELEN 256
+/*
+ * From RFC 1831:
+ *
+ * "A record is composed of one or more record fragments. A record
+ * fragment is a four-byte header followed by 0 to (2**31) - 1 bytes of
+ * fragment data. The bytes encode an unsigned binary number; as with
+ * XDR integers, the byte order is from highest to lowest. The number
+ * encodes two values -- a boolean which indicates whether the fragment
+ * is the last fragment of the record (bit value 1 implies the fragment
+ * is the last fragment) and a 31-bit unsigned binary value which is the
+ * length in bytes of the fragment's data. The boolean value is the
+ * highest-order bit of the header; the length is the 31 low-order bits.
+ * (Note that this record specification is NOT in XDR standard form!)"
+ *
+ * The Linux RPC client always sends its requests in a single record
+ * fragment, limiting the maximum payload size for stream transports to
+ * 2GB.
+ */
+
+typedef u32 rpc_fraghdr;
+
+#define RPC_LAST_STREAM_FRAGMENT (1U << 31)
+#define RPC_FRAGMENT_SIZE_MASK (~RPC_LAST_STREAM_FRAGMENT)
+#define RPC_MAX_FRAGMENT_SIZE ((1U << 31) - 1)
+
#endif /* __KERNEL__ */
#endif /* _LINUX_SUNRPC_MSGPROT_H_ */
diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h
index 5af8800e0ce3..e4086ec8b952 100644
--- a/include/linux/sunrpc/svc.h
+++ b/include/linux/sunrpc/svc.h
@@ -171,7 +171,8 @@ xdr_argsize_check(struct svc_rqst *rqstp, u32 *p)
{
char *cp = (char *)p;
struct kvec *vec = &rqstp->rq_arg.head[0];
- return cp - (char*)vec->iov_base <= vec->iov_len;
+ return cp >= (char*)vec->iov_base
+ && cp <= (char*)vec->iov_base + vec->iov_len;
}
static inline int
diff --git a/include/linux/sunrpc/xdr.h b/include/linux/sunrpc/xdr.h
index 23448d0fb5bc..5da968729cf8 100644
--- a/include/linux/sunrpc/xdr.h
+++ b/include/linux/sunrpc/xdr.h
@@ -161,14 +161,10 @@ typedef struct {
typedef size_t (*skb_read_actor_t)(skb_reader_t *desc, void *to, size_t len);
+extern int csum_partial_copy_to_xdr(struct xdr_buf *, struct sk_buff *);
extern ssize_t xdr_partial_copy_from_skb(struct xdr_buf *, unsigned int,
skb_reader_t *, skb_read_actor_t);
-struct socket;
-struct sockaddr;
-extern int xdr_sendpages(struct socket *, struct sockaddr *, int,
- struct xdr_buf *, unsigned int, int);
-
extern int xdr_encode_word(struct xdr_buf *, int, u32);
extern int xdr_decode_word(struct xdr_buf *, int, u32 *);
diff --git a/include/linux/sunrpc/xprt.h b/include/linux/sunrpc/xprt.h
index e618c1649814..3b8b6e823c70 100644
--- a/include/linux/sunrpc/xprt.h
+++ b/include/linux/sunrpc/xprt.h
@@ -1,5 +1,5 @@
/*
- * linux/include/linux/sunrpc/clnt_xprt.h
+ * linux/include/linux/sunrpc/xprt.h
*
* Declarations for the RPC transport interface.
*
@@ -15,20 +15,6 @@
#include <linux/sunrpc/sched.h>
#include <linux/sunrpc/xdr.h>
-/*
- * The transport code maintains an estimate on the maximum number of out-
- * standing RPC requests, using a smoothed version of the congestion
- * avoidance implemented in 44BSD. This is basically the Van Jacobson
- * congestion algorithm: If a retransmit occurs, the congestion window is
- * halved; otherwise, it is incremented by 1/cwnd when
- *
- * - a reply is received and
- * - a full number of requests are outstanding and
- * - the congestion window hasn't been updated recently.
- *
- * Upper procedures may check whether a request would block waiting for
- * a free RPC slot by using the RPC_CONGESTED() macro.
- */
extern unsigned int xprt_udp_slot_table_entries;
extern unsigned int xprt_tcp_slot_table_entries;
@@ -36,34 +22,23 @@ extern unsigned int xprt_tcp_slot_table_entries;
#define RPC_DEF_SLOT_TABLE (16U)
#define RPC_MAX_SLOT_TABLE (128U)
-#define RPC_CWNDSHIFT (8U)
-#define RPC_CWNDSCALE (1U << RPC_CWNDSHIFT)
-#define RPC_INITCWND RPC_CWNDSCALE
-#define RPC_MAXCWND(xprt) ((xprt)->max_reqs << RPC_CWNDSHIFT)
-#define RPCXPRT_CONGESTED(xprt) ((xprt)->cong >= (xprt)->cwnd)
-
-/* Default timeout values */
-#define RPC_MAX_UDP_TIMEOUT (60*HZ)
-#define RPC_MAX_TCP_TIMEOUT (600*HZ)
-
/*
- * Wait duration for an RPC TCP connection to be established. Solaris
- * NFS over TCP uses 60 seconds, for example, which is in line with how
- * long a server takes to reboot.
+ * RPC call and reply header size as number of 32bit words (verifier
+ * size computed separately)
*/
-#define RPC_CONNECT_TIMEOUT (60*HZ)
+#define RPC_CALLHDRSIZE 6
+#define RPC_REPHDRSIZE 4
/*
- * Delay an arbitrary number of seconds before attempting to reconnect
- * after an error.
+ * Parameters for choosing a free port
*/
-#define RPC_REESTABLISH_TIMEOUT (15*HZ)
+extern unsigned int xprt_min_resvport;
+extern unsigned int xprt_max_resvport;
-/* RPC call and reply header size as number of 32bit words (verifier
- * size computed separately)
- */
-#define RPC_CALLHDRSIZE 6
-#define RPC_REPHDRSIZE 4
+#define RPC_MIN_RESVPORT (1U)
+#define RPC_MAX_RESVPORT (65535U)
+#define RPC_DEF_MIN_RESVPORT (650U)
+#define RPC_DEF_MAX_RESVPORT (1023U)
/*
* This describes a timeout strategy
@@ -76,6 +51,9 @@ struct rpc_timeout {
unsigned char to_exponential;
};
+struct rpc_task;
+struct rpc_xprt;
+
/*
* This describes a complete RPC request
*/
@@ -95,7 +73,10 @@ struct rpc_rqst {
int rq_cong; /* has incremented xprt->cong */
int rq_received; /* receive completed */
u32 rq_seqno; /* gss seq no. used on req. */
-
+ int rq_enc_pages_num;
+ struct page **rq_enc_pages; /* scratch pages for use by
+ gss privacy code */
+ void (*rq_release_snd_buf)(struct rpc_rqst *); /* release rq_enc_pages */
struct list_head rq_list;
struct xdr_buf rq_private_buf; /* The receive buffer
@@ -121,12 +102,21 @@ struct rpc_rqst {
#define rq_svec rq_snd_buf.head
#define rq_slen rq_snd_buf.len
-#define XPRT_LAST_FRAG (1 << 0)
-#define XPRT_COPY_RECM (1 << 1)
-#define XPRT_COPY_XID (1 << 2)
-#define XPRT_COPY_DATA (1 << 3)
+struct rpc_xprt_ops {
+ void (*set_buffer_size)(struct rpc_xprt *xprt, size_t sndsize, size_t rcvsize);
+ int (*reserve_xprt)(struct rpc_task *task);
+ void (*release_xprt)(struct rpc_xprt *xprt, struct rpc_task *task);
+ void (*connect)(struct rpc_task *task);
+ int (*send_request)(struct rpc_task *task);
+ void (*set_retrans_timeout)(struct rpc_task *task);
+ void (*timer)(struct rpc_task *task);
+ void (*release_request)(struct rpc_task *task);
+ void (*close)(struct rpc_xprt *xprt);
+ void (*destroy)(struct rpc_xprt *xprt);
+};
struct rpc_xprt {
+ struct rpc_xprt_ops * ops; /* transport methods */
struct socket * sock; /* BSD socket layer */
struct sock * inet; /* INET layer */
@@ -137,11 +127,13 @@ struct rpc_xprt {
unsigned long cong; /* current congestion */
unsigned long cwnd; /* congestion window */
- unsigned int rcvsize, /* socket receive buffer size */
- sndsize; /* socket send buffer size */
+ size_t rcvsize, /* transport rcv buffer size */
+ sndsize; /* transport send buffer size */
size_t max_payload; /* largest RPC payload size,
in bytes */
+ unsigned int tsh_size; /* size of transport specific
+ header */
struct rpc_wait_queue sending; /* requests waiting to send */
struct rpc_wait_queue resend; /* requests waiting to resend */
@@ -150,11 +142,9 @@ struct rpc_xprt {
struct list_head free; /* free slots */
struct rpc_rqst * slot; /* slot table storage */
unsigned int max_reqs; /* total slots */
- unsigned long sockstate; /* Socket state */
+ unsigned long state; /* transport state */
unsigned char shutdown : 1, /* being shut down */
- nocong : 1, /* no congestion control */
- resvport : 1, /* use a reserved port */
- stream : 1; /* TCP */
+ resvport : 1; /* use a reserved port */
/*
* XID
@@ -171,22 +161,27 @@ struct rpc_xprt {
unsigned long tcp_copied, /* copied to request */
tcp_flags;
/*
- * Connection of sockets
+ * Connection of transports
*/
- struct work_struct sock_connect;
+ unsigned long connect_timeout,
+ bind_timeout,
+ reestablish_timeout;
+ struct work_struct connect_worker;
unsigned short port;
+
/*
- * Disconnection of idle sockets
+ * Disconnection of idle transports
*/
struct work_struct task_cleanup;
struct timer_list timer;
- unsigned long last_used;
+ unsigned long last_used,
+ idle_timeout;
/*
* Send stuff
*/
- spinlock_t sock_lock; /* lock socket info */
- spinlock_t xprt_lock; /* lock xprt info */
+ spinlock_t transport_lock; /* lock transport info */
+ spinlock_t reserve_lock; /* lock slot table */
struct rpc_task * snd_task; /* Task blocked in send */
struct list_head recv;
@@ -195,37 +190,111 @@ struct rpc_xprt {
void (*old_data_ready)(struct sock *, int);
void (*old_state_change)(struct sock *);
void (*old_write_space)(struct sock *);
-
- wait_queue_head_t cong_wait;
};
+#define XPRT_LAST_FRAG (1 << 0)
+#define XPRT_COPY_RECM (1 << 1)
+#define XPRT_COPY_XID (1 << 2)
+#define XPRT_COPY_DATA (1 << 3)
+
#ifdef __KERNEL__
-struct rpc_xprt * xprt_create_proto(int proto, struct sockaddr_in *addr,
- struct rpc_timeout *toparms);
-int xprt_destroy(struct rpc_xprt *);
-void xprt_set_timeout(struct rpc_timeout *, unsigned int,
- unsigned long);
+/*
+ * Transport operations used by ULPs
+ */
+struct rpc_xprt * xprt_create_proto(int proto, struct sockaddr_in *addr, struct rpc_timeout *to);
+void xprt_set_timeout(struct rpc_timeout *to, unsigned int retr, unsigned long incr);
-void xprt_reserve(struct rpc_task *);
-int xprt_prepare_transmit(struct rpc_task *);
-void xprt_transmit(struct rpc_task *);
-void xprt_receive(struct rpc_task *);
+/*
+ * Generic internal transport functions
+ */
+void xprt_connect(struct rpc_task *task);
+void xprt_reserve(struct rpc_task *task);
+int xprt_reserve_xprt(struct rpc_task *task);
+int xprt_reserve_xprt_cong(struct rpc_task *task);
+int xprt_prepare_transmit(struct rpc_task *task);
+void xprt_transmit(struct rpc_task *task);
+void xprt_abort_transmit(struct rpc_task *task);
int xprt_adjust_timeout(struct rpc_rqst *req);
-void xprt_release(struct rpc_task *);
-void xprt_connect(struct rpc_task *);
-void xprt_sock_setbufsize(struct rpc_xprt *);
-
-#define XPRT_LOCKED 0
-#define XPRT_CONNECT 1
-#define XPRT_CONNECTING 2
-
-#define xprt_connected(xp) (test_bit(XPRT_CONNECT, &(xp)->sockstate))
-#define xprt_set_connected(xp) (set_bit(XPRT_CONNECT, &(xp)->sockstate))
-#define xprt_test_and_set_connected(xp) (test_and_set_bit(XPRT_CONNECT, &(xp)->sockstate))
-#define xprt_test_and_clear_connected(xp) \
- (test_and_clear_bit(XPRT_CONNECT, &(xp)->sockstate))
-#define xprt_clear_connected(xp) (clear_bit(XPRT_CONNECT, &(xp)->sockstate))
+void xprt_release_xprt(struct rpc_xprt *xprt, struct rpc_task *task);
+void xprt_release_xprt_cong(struct rpc_xprt *xprt, struct rpc_task *task);
+void xprt_release(struct rpc_task *task);
+int xprt_destroy(struct rpc_xprt *xprt);
+
+static inline u32 *xprt_skip_transport_header(struct rpc_xprt *xprt, u32 *p)
+{
+ return p + xprt->tsh_size;
+}
+
+/*
+ * Transport switch helper functions
+ */
+void xprt_set_retrans_timeout_def(struct rpc_task *task);
+void xprt_set_retrans_timeout_rtt(struct rpc_task *task);
+void xprt_wake_pending_tasks(struct rpc_xprt *xprt, int status);
+void xprt_wait_for_buffer_space(struct rpc_task *task);
+void xprt_write_space(struct rpc_xprt *xprt);
+void xprt_update_rtt(struct rpc_task *task);
+void xprt_adjust_cwnd(struct rpc_task *task, int result);
+struct rpc_rqst * xprt_lookup_rqst(struct rpc_xprt *xprt, u32 xid);
+void xprt_complete_rqst(struct rpc_task *task, int copied);
+void xprt_release_rqst_cong(struct rpc_task *task);
+void xprt_disconnect(struct rpc_xprt *xprt);
+
+/*
+ * Socket transport setup operations
+ */
+int xs_setup_udp(struct rpc_xprt *xprt, struct rpc_timeout *to);
+int xs_setup_tcp(struct rpc_xprt *xprt, struct rpc_timeout *to);
+
+/*
+ * Reserved bit positions in xprt->state
+ */
+#define XPRT_LOCKED (0)
+#define XPRT_CONNECTED (1)
+#define XPRT_CONNECTING (2)
+
+static inline void xprt_set_connected(struct rpc_xprt *xprt)
+{
+ set_bit(XPRT_CONNECTED, &xprt->state);
+}
+
+static inline void xprt_clear_connected(struct rpc_xprt *xprt)
+{
+ clear_bit(XPRT_CONNECTED, &xprt->state);
+}
+
+static inline int xprt_connected(struct rpc_xprt *xprt)
+{
+ return test_bit(XPRT_CONNECTED, &xprt->state);
+}
+
+static inline int xprt_test_and_set_connected(struct rpc_xprt *xprt)
+{
+ return test_and_set_bit(XPRT_CONNECTED, &xprt->state);
+}
+
+static inline int xprt_test_and_clear_connected(struct rpc_xprt *xprt)
+{
+ return test_and_clear_bit(XPRT_CONNECTED, &xprt->state);
+}
+
+static inline void xprt_clear_connecting(struct rpc_xprt *xprt)
+{
+ smp_mb__before_clear_bit();
+ clear_bit(XPRT_CONNECTING, &xprt->state);
+ smp_mb__after_clear_bit();
+}
+
+static inline int xprt_connecting(struct rpc_xprt *xprt)
+{
+ return test_bit(XPRT_CONNECTING, &xprt->state);
+}
+
+static inline int xprt_test_and_set_connecting(struct rpc_xprt *xprt)
+{
+ return test_and_set_bit(XPRT_CONNECTING, &xprt->state);
+}
#endif /* __KERNEL__*/
diff --git a/include/linux/superhyway.h b/include/linux/superhyway.h
index c906c5a0aaef..17ea468fa362 100644
--- a/include/linux/superhyway.h
+++ b/include/linux/superhyway.h
@@ -19,7 +19,7 @@
*/
#define SUPERHYWAY_DEVICE_ID_SH5_DMAC 0x0183
-struct vcr_info {
+struct superhyway_vcr_info {
u8 perr_flags; /* P-port Error flags */
u8 merr_flags; /* Module Error flags */
u16 mod_vers; /* Module Version */
@@ -28,6 +28,17 @@ struct vcr_info {
u8 top_mb; /* Top Memory block */
};
+struct superhyway_ops {
+ int (*read_vcr)(unsigned long base, struct superhyway_vcr_info *vcr);
+ int (*write_vcr)(unsigned long base, struct superhyway_vcr_info vcr);
+};
+
+struct superhyway_bus {
+ struct superhyway_ops *ops;
+};
+
+extern struct superhyway_bus superhyway_channels[];
+
struct superhyway_device_id {
unsigned int id;
unsigned long driver_data;
@@ -55,9 +66,11 @@ struct superhyway_device {
struct superhyway_device_id id;
struct superhyway_driver *drv;
+ struct superhyway_bus *bus;
- struct resource resource;
- struct vcr_info vcr;
+ int num_resources;
+ struct resource *resource;
+ struct superhyway_vcr_info vcr;
};
#define to_superhyway_device(d) container_of((d), struct superhyway_device, dev)
@@ -65,12 +78,27 @@ struct superhyway_device {
#define superhyway_get_drvdata(d) dev_get_drvdata(&(d)->dev)
#define superhyway_set_drvdata(d,p) dev_set_drvdata(&(d)->dev, (p))
-extern int superhyway_scan_bus(void);
+static inline int
+superhyway_read_vcr(struct superhyway_device *dev, unsigned long base,
+ struct superhyway_vcr_info *vcr)
+{
+ return dev->bus->ops->read_vcr(base, vcr);
+}
+
+static inline int
+superhyway_write_vcr(struct superhyway_device *dev, unsigned long base,
+ struct superhyway_vcr_info vcr)
+{
+ return dev->bus->ops->write_vcr(base, vcr);
+}
+
+extern int superhyway_scan_bus(struct superhyway_bus *);
/* drivers/sh/superhyway/superhyway.c */
int superhyway_register_driver(struct superhyway_driver *);
void superhyway_unregister_driver(struct superhyway_driver *);
-int superhyway_add_device(unsigned int, unsigned long, unsigned long long);
+int superhyway_add_device(unsigned long base, struct superhyway_device *, struct superhyway_bus *);
+int superhyway_add_devices(struct superhyway_bus *bus, struct superhyway_device **devices, int nr_devices);
/* drivers/sh/superhyway/superhyway-sysfs.c */
extern struct device_attribute superhyway_dev_attrs[];
diff --git a/include/linux/suspend.h b/include/linux/suspend.h
index ad15a54806d8..a61c04f804b2 100644
--- a/include/linux/suspend.h
+++ b/include/linux/suspend.h
@@ -71,7 +71,12 @@ void restore_processor_state(void);
struct saved_context;
void __save_processor_state(struct saved_context *ctxt);
void __restore_processor_state(struct saved_context *ctxt);
-extern unsigned long get_usable_page(unsigned gfp_mask);
-extern void free_eaten_memory(void);
+unsigned long get_safe_page(gfp_t gfp_mask);
+
+/*
+ * XXX: We try to keep some more pages free so that I/O operations succeed
+ * without paging. Might this be more?
+ */
+#define PAGES_FOR_IO 512
#endif /* _LINUX_SWSUSP_H */
diff --git a/include/linux/swap.h b/include/linux/swap.h
index a7bf1a3b1496..20c975642cab 100644
--- a/include/linux/swap.h
+++ b/include/linux/swap.h
@@ -171,8 +171,8 @@ extern int rotate_reclaimable_page(struct page *page);
extern void swap_setup(void);
/* linux/mm/vmscan.c */
-extern int try_to_free_pages(struct zone **, unsigned int);
-extern int zone_reclaim(struct zone *, unsigned int, unsigned int);
+extern int try_to_free_pages(struct zone **, gfp_t);
+extern int zone_reclaim(struct zone *, gfp_t, unsigned int);
extern int shrink_all_memory(int);
extern int vm_swappiness;
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index a6f03e473737..c7007b1db91d 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -491,6 +491,7 @@ asmlinkage long sys_nfsservctl(int cmd,
asmlinkage long sys_syslog(int type, char __user *buf, int len);
asmlinkage long sys_uselib(const char __user *library);
asmlinkage long sys_ni_syscall(void);
+asmlinkage long sys_ptrace(long request, long pid, long addr, long data);
asmlinkage long sys_add_key(const char __user *_type,
const char __user *_description,
diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h
index fc8e367f671e..ab2791b3189d 100644
--- a/include/linux/sysctl.h
+++ b/include/linux/sysctl.h
@@ -24,6 +24,7 @@
#include <linux/compiler.h>
struct file;
+struct completion;
#define CTL_MAXNAME 10 /* how many path components do we allow in a
call to sysctl? In other words, what is
@@ -204,6 +205,7 @@ enum
NET_ECONET=16,
NET_SCTP=17,
NET_LLC=18,
+ NET_NETFILTER=19,
};
/* /proc/sys/kernel/random */
@@ -269,6 +271,42 @@ enum
NET_UNIX_MAX_DGRAM_QLEN=3,
};
+/* /proc/sys/net/netfilter */
+enum
+{
+ NET_NF_CONNTRACK_MAX=1,
+ NET_NF_CONNTRACK_TCP_TIMEOUT_SYN_SENT=2,
+ NET_NF_CONNTRACK_TCP_TIMEOUT_SYN_RECV=3,
+ NET_NF_CONNTRACK_TCP_TIMEOUT_ESTABLISHED=4,
+ NET_NF_CONNTRACK_TCP_TIMEOUT_FIN_WAIT=5,
+ NET_NF_CONNTRACK_TCP_TIMEOUT_CLOSE_WAIT=6,
+ NET_NF_CONNTRACK_TCP_TIMEOUT_LAST_ACK=7,
+ NET_NF_CONNTRACK_TCP_TIMEOUT_TIME_WAIT=8,
+ NET_NF_CONNTRACK_TCP_TIMEOUT_CLOSE=9,
+ NET_NF_CONNTRACK_UDP_TIMEOUT=10,
+ NET_NF_CONNTRACK_UDP_TIMEOUT_STREAM=11,
+ NET_NF_CONNTRACK_ICMP_TIMEOUT=12,
+ NET_NF_CONNTRACK_GENERIC_TIMEOUT=13,
+ NET_NF_CONNTRACK_BUCKETS=14,
+ NET_NF_CONNTRACK_LOG_INVALID=15,
+ NET_NF_CONNTRACK_TCP_TIMEOUT_MAX_RETRANS=16,
+ NET_NF_CONNTRACK_TCP_LOOSE=17,
+ NET_NF_CONNTRACK_TCP_BE_LIBERAL=18,
+ NET_NF_CONNTRACK_TCP_MAX_RETRANS=19,
+ NET_NF_CONNTRACK_SCTP_TIMEOUT_CLOSED=20,
+ NET_NF_CONNTRACK_SCTP_TIMEOUT_COOKIE_WAIT=21,
+ NET_NF_CONNTRACK_SCTP_TIMEOUT_COOKIE_ECHOED=22,
+ NET_NF_CONNTRACK_SCTP_TIMEOUT_ESTABLISHED=23,
+ NET_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_SENT=24,
+ NET_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_RECD=25,
+ NET_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_ACK_SENT=26,
+ NET_NF_CONNTRACK_COUNT=27,
+ NET_NF_CONNTRACK_ICMPV6_TIMEOUT=28,
+ NET_NF_CONNTRACK_FRAG6_TIMEOUT=29,
+ NET_NF_CONNTRACK_FRAG6_LOW_THRESH=30,
+ NET_NF_CONNTRACK_FRAG6_HIGH_THRESH=31,
+};
+
/* /proc/sys/net/ipv4 */
enum
{
@@ -352,6 +390,7 @@ enum
NET_TCP_BIC_BETA=108,
NET_IPV4_ICMP_ERRORS_USE_INBOUND_IFADDR=109,
NET_TCP_CONG_CONTROL=110,
+ NET_TCP_ABC=111,
};
enum {
@@ -925,6 +964,8 @@ struct ctl_table_header
{
ctl_table *ctl_table;
struct list_head ctl_entry;
+ int used;
+ struct completion *unregistering;
};
struct ctl_table_header * register_sysctl_table(ctl_table * table,
diff --git a/include/linux/tcp.h b/include/linux/tcp.h
index ac4ca44c75ca..0e1da6602e05 100644
--- a/include/linux/tcp.h
+++ b/include/linux/tcp.h
@@ -307,6 +307,21 @@ struct tcp_sock {
struct tcp_sack_block duplicate_sack[1]; /* D-SACK block */
struct tcp_sack_block selective_acks[4]; /* The SACKS themselves*/
+ struct tcp_sack_block recv_sack_cache[4];
+
+ /* from STCP, retrans queue hinting */
+ struct sk_buff* lost_skb_hint;
+
+ struct sk_buff *scoreboard_skb_hint;
+ struct sk_buff *retransmit_skb_hint;
+ struct sk_buff *forward_skb_hint;
+ struct sk_buff *fastpath_skb_hint;
+
+ int fastpath_cnt_hint;
+ int lost_cnt_hint;
+ int retransmit_cnt_hint;
+ int forward_cnt_hint;
+
__u16 advmss; /* Advertised MSS */
__u16 prior_ssthresh; /* ssthresh saved at recovery start */
__u32 lost_out; /* Lost packets */
@@ -326,6 +341,7 @@ struct tcp_sock {
__u32 snd_up; /* Urgent pointer */
__u32 total_retrans; /* Total retransmits for entire connection */
+ __u32 bytes_acked; /* Appropriate Byte Counting - RFC3465 */
unsigned int keepalive_time; /* time before keep alive takes place */
unsigned int keepalive_intvl; /* time interval between keep alive probes */
diff --git a/include/linux/textsearch.h b/include/linux/textsearch.h
index 515046d1b2f4..7dac8f04d28e 100644
--- a/include/linux/textsearch.h
+++ b/include/linux/textsearch.h
@@ -8,6 +8,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/err.h>
+#include <linux/slab.h>
struct ts_config;
@@ -40,7 +41,7 @@ struct ts_state
struct ts_ops
{
const char *name;
- struct ts_config * (*init)(const void *, unsigned int, int);
+ struct ts_config * (*init)(const void *, unsigned int, gfp_t);
unsigned int (*find)(struct ts_config *,
struct ts_state *);
void (*destroy)(struct ts_config *);
@@ -148,7 +149,7 @@ static inline unsigned int textsearch_get_pattern_len(struct ts_config *conf)
extern int textsearch_register(struct ts_ops *);
extern int textsearch_unregister(struct ts_ops *);
extern struct ts_config *textsearch_prepare(const char *, const void *,
- unsigned int, int, int);
+ unsigned int, gfp_t, int);
extern void textsearch_destroy(struct ts_config *conf);
extern unsigned int textsearch_find_continuous(struct ts_config *,
struct ts_state *,
diff --git a/include/linux/timer.h b/include/linux/timer.h
index 3340f3bd135d..72f3a7781106 100644
--- a/include/linux/timer.h
+++ b/include/linux/timer.h
@@ -12,16 +12,12 @@ struct timer_list {
struct list_head entry;
unsigned long expires;
- unsigned long magic;
-
void (*function)(unsigned long);
unsigned long data;
struct timer_base_s *base;
};
-#define TIMER_MAGIC 0x4b87ad6e
-
extern struct timer_base_s __init_timer_base;
#define TIMER_INITIALIZER(_function, _expires, _data) { \
@@ -29,7 +25,6 @@ extern struct timer_base_s __init_timer_base;
.expires = (_expires), \
.data = (_data), \
.base = &__init_timer_base, \
- .magic = TIMER_MAGIC, \
}
#define DEFINE_TIMER(_name, _function, _expires, _data) \
@@ -38,6 +33,15 @@ extern struct timer_base_s __init_timer_base;
void fastcall init_timer(struct timer_list * timer);
+static inline void setup_timer(struct timer_list * timer,
+ void (*function)(unsigned long),
+ unsigned long data)
+{
+ timer->function = function;
+ timer->data = data;
+ init_timer(timer);
+}
+
/***
* timer_pending - is a timer pending?
* @timer: the timer in question
@@ -74,8 +78,9 @@ extern unsigned long next_timer_interrupt(void);
* Timers with an ->expired field in the past will be executed in the next
* timer tick.
*/
-static inline void add_timer(struct timer_list * timer)
+static inline void add_timer(struct timer_list *timer)
{
+ BUG_ON(timer_pending(timer));
__mod_timer(timer, timer->expires);
}
diff --git a/include/linux/timex.h b/include/linux/timex.h
index 7e050a2cc35b..04a4a8cb4ed3 100644
--- a/include/linux/timex.h
+++ b/include/linux/timex.h
@@ -282,6 +282,13 @@ static inline int ntp_synced(void)
return !(time_status & STA_UNSYNC);
}
+/* Required to safely shift negative values */
+#define shift_right(x, s) ({ \
+ __typeof__(x) __x = (x); \
+ __typeof__(s) __s = (s); \
+ __x < 0 ? -(-__x >> __s) : __x >> __s; \
+})
+
#ifdef CONFIG_TIME_INTERPOLATION
diff --git a/include/linux/types.h b/include/linux/types.h
index 0aee34f9da9f..21b9ce803644 100644
--- a/include/linux/types.h
+++ b/include/linux/types.h
@@ -151,7 +151,12 @@ typedef unsigned long sector_t;
*/
#ifdef __CHECKER__
-#define __bitwise __attribute__((bitwise))
+#define __bitwise__ __attribute__((bitwise))
+#else
+#define __bitwise__
+#endif
+#ifdef __CHECK_ENDIAN__
+#define __bitwise __bitwise__
#else
#define __bitwise
#endif
@@ -166,7 +171,7 @@ typedef __u64 __bitwise __be64;
#endif
#ifdef __KERNEL__
-typedef unsigned __nocast gfp_t;
+typedef unsigned __bitwise__ gfp_t;
#endif
struct ustat {
diff --git a/include/linux/usb.h b/include/linux/usb.h
index 4dbe580f9335..748d04385256 100644
--- a/include/linux/usb.h
+++ b/include/linux/usb.h
@@ -57,6 +57,7 @@ struct usb_host_endpoint {
struct usb_endpoint_descriptor desc;
struct list_head urb_list;
void *hcpriv;
+ struct kobject *kobj; /* For sysfs info */
unsigned char *extra; /* Extra descriptors */
int extralen;
@@ -136,7 +137,8 @@ struct usb_interface {
* active alternate setting */
unsigned num_altsetting; /* number of alternate settings */
- int minor; /* minor number this interface is bound to */
+ int minor; /* minor number this interface is
+ * bound to */
enum usb_interface_condition condition; /* state of binding */
struct device dev; /* interface specific device info */
struct class_device *class_dev;
@@ -229,7 +231,7 @@ struct usb_interface_cache {
struct usb_host_config {
struct usb_config_descriptor desc;
- char *string;
+ char *string; /* iConfiguration string, if present */
/* the interfaces associated with this configuration,
* stored in no particular order */
struct usb_interface *interface[USB_MAXINTERFACES];
@@ -248,7 +250,7 @@ int __usb_get_extra_descriptor(char *buffer, unsigned size,
__usb_get_extra_descriptor((ifpoint)->extra,(ifpoint)->extralen,\
type,(void**)ptr)
-/* -------------------------------------------------------------------------- */
+/* ----------------------------------------------------------------------- */
struct usb_operations;
@@ -268,7 +270,8 @@ struct usb_bus {
unsigned is_b_host:1; /* true during some HNP roleswitches */
unsigned b_hnp_enable:1; /* OTG: did A-Host enable HNP? */
- int devnum_next; /* Next open device number in round-robin allocation */
+ int devnum_next; /* Next open device number in
+ * round-robin allocation */
struct usb_devmap devmap; /* device address allocation map */
struct usb_operations *op; /* Operations (specific to the HC) */
@@ -289,15 +292,16 @@ struct usb_bus {
struct dentry *usbfs_dentry; /* usbfs dentry entry for the bus */
struct class_device *class_dev; /* class device for this bus */
- struct kref kref; /* handles reference counting this bus */
- void (*release)(struct usb_bus *bus); /* function to destroy this bus's memory */
+ struct kref kref; /* reference counting for this bus */
+ void (*release)(struct usb_bus *bus);
+
#if defined(CONFIG_USB_MON)
struct mon_bus *mon_bus; /* non-null when associated */
int monitored; /* non-zero when monitored */
#endif
};
-/* -------------------------------------------------------------------------- */
+/* ----------------------------------------------------------------------- */
/* This is arbitrary.
* From USB 2.0 spec Table 11-13, offset 7, a hub can
@@ -326,7 +330,8 @@ struct usb_device {
struct semaphore serialize;
- unsigned int toggle[2]; /* one bit for each endpoint ([0] = IN, [1] = OUT) */
+ unsigned int toggle[2]; /* one bit for each endpoint
+ * ([0] = IN, [1] = OUT) */
struct usb_device *parent; /* our hub, unless we're the root */
struct usb_bus *bus; /* Bus we're part of */
@@ -343,12 +348,14 @@ struct usb_device {
char **rawdescriptors; /* Raw descriptors for each config */
- int have_langid; /* whether string_langid is valid yet */
+ int have_langid; /* whether string_langid is valid */
int string_langid; /* language ID for strings */
- char *product;
- char *manufacturer;
- char *serial; /* static strings from the device */
+ /* static strings from the device */
+ char *product; /* iProduct string, if present */
+ char *manufacturer; /* iManufacturer string, if present */
+ char *serial; /* iSerialNumber string, if present */
+
struct list_head filelist;
struct class_device *class_dev;
struct dentry *usbfs_dentry; /* usbfs dentry entry for the device */
@@ -440,22 +447,31 @@ extern struct usb_host_interface *usb_altnum_to_altsetting(
* USB 2.0 root hubs (EHCI host controllers) will get one path ID if they are
* high speed, and a different one if they are full or low speed.
*/
-static inline int usb_make_path (struct usb_device *dev, char *buf, size_t size)
+static inline int usb_make_path (struct usb_device *dev, char *buf,
+ size_t size)
{
int actual;
- actual = snprintf (buf, size, "usb-%s-%s", dev->bus->bus_name, dev->devpath);
+ actual = snprintf (buf, size, "usb-%s-%s", dev->bus->bus_name,
+ dev->devpath);
return (actual >= (int)size) ? -1 : actual;
}
/*-------------------------------------------------------------------------*/
-#define USB_DEVICE_ID_MATCH_DEVICE (USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_PRODUCT)
-#define USB_DEVICE_ID_MATCH_DEV_RANGE (USB_DEVICE_ID_MATCH_DEV_LO | USB_DEVICE_ID_MATCH_DEV_HI)
-#define USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION (USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_DEV_RANGE)
+#define USB_DEVICE_ID_MATCH_DEVICE \
+ (USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_PRODUCT)
+#define USB_DEVICE_ID_MATCH_DEV_RANGE \
+ (USB_DEVICE_ID_MATCH_DEV_LO | USB_DEVICE_ID_MATCH_DEV_HI)
+#define USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION \
+ (USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_DEV_RANGE)
#define USB_DEVICE_ID_MATCH_DEV_INFO \
- (USB_DEVICE_ID_MATCH_DEV_CLASS | USB_DEVICE_ID_MATCH_DEV_SUBCLASS | USB_DEVICE_ID_MATCH_DEV_PROTOCOL)
+ (USB_DEVICE_ID_MATCH_DEV_CLASS | \
+ USB_DEVICE_ID_MATCH_DEV_SUBCLASS | \
+ USB_DEVICE_ID_MATCH_DEV_PROTOCOL)
#define USB_DEVICE_ID_MATCH_INT_INFO \
- (USB_DEVICE_ID_MATCH_INT_CLASS | USB_DEVICE_ID_MATCH_INT_SUBCLASS | USB_DEVICE_ID_MATCH_INT_PROTOCOL)
+ (USB_DEVICE_ID_MATCH_INT_CLASS | \
+ USB_DEVICE_ID_MATCH_INT_SUBCLASS | \
+ USB_DEVICE_ID_MATCH_INT_PROTOCOL)
/**
* USB_DEVICE - macro used to describe a specific usb device
@@ -466,9 +482,11 @@ static inline int usb_make_path (struct usb_device *dev, char *buf, size_t size)
* specific device.
*/
#define USB_DEVICE(vend,prod) \
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE, .idVendor = (vend), .idProduct = (prod)
+ .match_flags = USB_DEVICE_ID_MATCH_DEVICE, .idVendor = (vend), \
+ .idProduct = (prod)
/**
- * USB_DEVICE_VER - macro used to describe a specific usb device with a version range
+ * USB_DEVICE_VER - macro used to describe a specific usb device with a
+ * version range
* @vend: the 16 bit USB Vendor ID
* @prod: the 16 bit USB Product ID
* @lo: the bcdDevice_lo value
@@ -478,7 +496,9 @@ static inline int usb_make_path (struct usb_device *dev, char *buf, size_t size)
* specific device, with a version range.
*/
#define USB_DEVICE_VER(vend,prod,lo,hi) \
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION, .idVendor = (vend), .idProduct = (prod), .bcdDevice_lo = (lo), .bcdDevice_hi = (hi)
+ .match_flags = USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION, \
+ .idVendor = (vend), .idProduct = (prod), \
+ .bcdDevice_lo = (lo), .bcdDevice_hi = (hi)
/**
* USB_DEVICE_INFO - macro used to describe a class of usb devices
@@ -490,7 +510,8 @@ static inline int usb_make_path (struct usb_device *dev, char *buf, size_t size)
* specific class of devices.
*/
#define USB_DEVICE_INFO(cl,sc,pr) \
- .match_flags = USB_DEVICE_ID_MATCH_DEV_INFO, .bDeviceClass = (cl), .bDeviceSubClass = (sc), .bDeviceProtocol = (pr)
+ .match_flags = USB_DEVICE_ID_MATCH_DEV_INFO, .bDeviceClass = (cl), \
+ .bDeviceSubClass = (sc), .bDeviceProtocol = (pr)
/**
* USB_INTERFACE_INFO - macro used to describe a class of usb interfaces
@@ -502,9 +523,10 @@ static inline int usb_make_path (struct usb_device *dev, char *buf, size_t size)
* specific class of interfaces.
*/
#define USB_INTERFACE_INFO(cl,sc,pr) \
- .match_flags = USB_DEVICE_ID_MATCH_INT_INFO, .bInterfaceClass = (cl), .bInterfaceSubClass = (sc), .bInterfaceProtocol = (pr)
+ .match_flags = USB_DEVICE_ID_MATCH_INT_INFO, .bInterfaceClass = (cl), \
+ .bInterfaceSubClass = (sc), .bInterfaceProtocol = (pr)
-/* -------------------------------------------------------------------------- */
+/* ----------------------------------------------------------------------- */
/**
* struct usb_driver - identifies USB driver to usbcore
@@ -557,7 +579,8 @@ struct usb_driver {
void (*disconnect) (struct usb_interface *intf);
- int (*ioctl) (struct usb_interface *intf, unsigned int code, void *buf);
+ int (*ioctl) (struct usb_interface *intf, unsigned int code,
+ void *buf);
int (*suspend) (struct usb_interface *intf, pm_message_t message);
int (*resume) (struct usb_interface *intf);
@@ -572,10 +595,8 @@ extern struct bus_type usb_bus_type;
/**
* struct usb_class_driver - identifies a USB driver that wants to use the USB major number
- * @name: devfs name for this driver. Will also be used by the driver
- * class code to create a usb class device.
+ * @name: the usb class device name for this driver. Will show up in sysfs.
* @fops: pointer to the struct file_operations of this driver.
- * @mode: the mode for the devfs file to be created for this driver.
* @minor_base: the start of the minor range for this driver.
*
* This structure is used for the usb_register_dev() and
@@ -585,8 +606,7 @@ extern struct bus_type usb_bus_type;
struct usb_class_driver {
char *name;
struct file_operations *fops;
- mode_t mode;
- int minor_base;
+ int minor_base;
};
/*
@@ -603,7 +623,7 @@ extern void usb_deregister_dev(struct usb_interface *intf,
extern int usb_disabled(void);
-/* -------------------------------------------------------------------------- */
+/* ----------------------------------------------------------------------- */
/*
* URB support, for asynchronous request completions
@@ -613,12 +633,14 @@ extern int usb_disabled(void);
* urb->transfer_flags:
*/
#define URB_SHORT_NOT_OK 0x0001 /* report short reads as errors */
-#define URB_ISO_ASAP 0x0002 /* iso-only, urb->start_frame ignored */
+#define URB_ISO_ASAP 0x0002 /* iso-only, urb->start_frame
+ * ignored */
#define URB_NO_TRANSFER_DMA_MAP 0x0004 /* urb->transfer_dma valid on submit */
#define URB_NO_SETUP_DMA_MAP 0x0008 /* urb->setup_dma valid on submit */
#define URB_NO_FSBR 0x0020 /* UHCI-specific */
-#define URB_ZERO_PACKET 0x0040 /* Finish bulk OUTs with short packet */
-#define URB_NO_INTERRUPT 0x0080 /* HINT: no non-error interrupt needed */
+#define URB_ZERO_PACKET 0x0040 /* Finish bulk OUT with short packet */
+#define URB_NO_INTERRUPT 0x0080 /* HINT: no non-error interrupt
+ * needed */
struct usb_iso_packet_descriptor {
unsigned int offset;
@@ -806,7 +828,8 @@ struct urb
u8 reject; /* submissions will fail */
/* public, documented fields in the urb that can be used by drivers */
- struct list_head urb_list; /* list head for use by the urb owner */
+ struct list_head urb_list; /* list head for use by the urb's
+ * current owner */
struct usb_device *dev; /* (in) pointer to associated device */
unsigned int pipe; /* (in) pipe information */
int status; /* (return) non-ISO status */
@@ -819,14 +842,16 @@ struct urb
dma_addr_t setup_dma; /* (in) dma addr for setup_packet */
int start_frame; /* (modify) start frame (ISO) */
int number_of_packets; /* (in) number of ISO packets */
- int interval; /* (modify) transfer interval (INT/ISO) */
+ int interval; /* (modify) transfer interval
+ * (INT/ISO) */
int error_count; /* (return) number of ISO errors */
void *context; /* (in) context for completion */
usb_complete_t complete; /* (in) completion routine */
- struct usb_iso_packet_descriptor iso_frame_desc[0]; /* (in) ISO ONLY */
+ struct usb_iso_packet_descriptor iso_frame_desc[0];
+ /* (in) ISO ONLY */
};
-/* -------------------------------------------------------------------------- */
+/* ----------------------------------------------------------------------- */
/**
* usb_fill_control_urb - initializes a control urb
@@ -933,17 +958,17 @@ static inline void usb_fill_int_urb (struct urb *urb,
}
extern void usb_init_urb(struct urb *urb);
-extern struct urb *usb_alloc_urb(int iso_packets, unsigned mem_flags);
+extern struct urb *usb_alloc_urb(int iso_packets, gfp_t mem_flags);
extern void usb_free_urb(struct urb *urb);
#define usb_put_urb usb_free_urb
extern struct urb *usb_get_urb(struct urb *urb);
-extern int usb_submit_urb(struct urb *urb, unsigned mem_flags);
+extern int usb_submit_urb(struct urb *urb, gfp_t mem_flags);
extern int usb_unlink_urb(struct urb *urb);
extern void usb_kill_urb(struct urb *urb);
#define HAVE_USB_BUFFERS
void *usb_buffer_alloc (struct usb_device *dev, size_t size,
- unsigned mem_flags, dma_addr_t *dma);
+ gfp_t mem_flags, dma_addr_t *dma);
void usb_buffer_free (struct usb_device *dev, size_t size,
void *addr, dma_addr_t dma);
@@ -974,11 +999,6 @@ extern int usb_bulk_msg(struct usb_device *usb_dev, unsigned int pipe,
void *data, int len, int *actual_length,
int timeout);
-/* selective suspend/resume */
-extern int usb_suspend_device(struct usb_device *dev, pm_message_t message);
-extern int usb_resume_device(struct usb_device *dev);
-
-
/* wrappers around usb_control_msg() for the most common standard requests */
extern int usb_get_descriptor(struct usb_device *dev, unsigned char desctype,
unsigned char descindex, void *buf, int size);
@@ -1050,13 +1070,13 @@ int usb_sg_init (
struct scatterlist *sg,
int nents,
size_t length,
- unsigned mem_flags
+ gfp_t mem_flags
);
void usb_sg_cancel (struct usb_sg_request *io);
void usb_sg_wait (struct usb_sg_request *io);
-/* -------------------------------------------------------------------------- */
+/* ----------------------------------------------------------------------- */
/*
* For various legacy reasons, Linux has a small cookie that's paired with
@@ -1097,23 +1117,34 @@ void usb_sg_wait (struct usb_sg_request *io);
/* The D0/D1 toggle bits ... USE WITH CAUTION (they're almost hcd-internal) */
#define usb_gettoggle(dev, ep, out) (((dev)->toggle[out] >> (ep)) & 1)
#define usb_dotoggle(dev, ep, out) ((dev)->toggle[out] ^= (1 << (ep)))
-#define usb_settoggle(dev, ep, out, bit) ((dev)->toggle[out] = ((dev)->toggle[out] & ~(1 << (ep))) | ((bit) << (ep)))
+#define usb_settoggle(dev, ep, out, bit) \
+ ((dev)->toggle[out] = ((dev)->toggle[out] & ~(1 << (ep))) | \
+ ((bit) << (ep)))
-static inline unsigned int __create_pipe(struct usb_device *dev, unsigned int endpoint)
+static inline unsigned int __create_pipe(struct usb_device *dev,
+ unsigned int endpoint)
{
return (dev->devnum << 8) | (endpoint << 15);
}
/* Create various pipes... */
-#define usb_sndctrlpipe(dev,endpoint) ((PIPE_CONTROL << 30) | __create_pipe(dev,endpoint))
-#define usb_rcvctrlpipe(dev,endpoint) ((PIPE_CONTROL << 30) | __create_pipe(dev,endpoint) | USB_DIR_IN)
-#define usb_sndisocpipe(dev,endpoint) ((PIPE_ISOCHRONOUS << 30) | __create_pipe(dev,endpoint))
-#define usb_rcvisocpipe(dev,endpoint) ((PIPE_ISOCHRONOUS << 30) | __create_pipe(dev,endpoint) | USB_DIR_IN)
-#define usb_sndbulkpipe(dev,endpoint) ((PIPE_BULK << 30) | __create_pipe(dev,endpoint))
-#define usb_rcvbulkpipe(dev,endpoint) ((PIPE_BULK << 30) | __create_pipe(dev,endpoint) | USB_DIR_IN)
-#define usb_sndintpipe(dev,endpoint) ((PIPE_INTERRUPT << 30) | __create_pipe(dev,endpoint))
-#define usb_rcvintpipe(dev,endpoint) ((PIPE_INTERRUPT << 30) | __create_pipe(dev,endpoint) | USB_DIR_IN)
+#define usb_sndctrlpipe(dev,endpoint) \
+ ((PIPE_CONTROL << 30) | __create_pipe(dev,endpoint))
+#define usb_rcvctrlpipe(dev,endpoint) \
+ ((PIPE_CONTROL << 30) | __create_pipe(dev,endpoint) | USB_DIR_IN)
+#define usb_sndisocpipe(dev,endpoint) \
+ ((PIPE_ISOCHRONOUS << 30) | __create_pipe(dev,endpoint))
+#define usb_rcvisocpipe(dev,endpoint) \
+ ((PIPE_ISOCHRONOUS << 30) | __create_pipe(dev,endpoint) | USB_DIR_IN)
+#define usb_sndbulkpipe(dev,endpoint) \
+ ((PIPE_BULK << 30) | __create_pipe(dev,endpoint))
+#define usb_rcvbulkpipe(dev,endpoint) \
+ ((PIPE_BULK << 30) | __create_pipe(dev,endpoint) | USB_DIR_IN)
+#define usb_sndintpipe(dev,endpoint) \
+ ((PIPE_INTERRUPT << 30) | __create_pipe(dev,endpoint))
+#define usb_rcvintpipe(dev,endpoint) \
+ ((PIPE_INTERRUPT << 30) | __create_pipe(dev,endpoint) | USB_DIR_IN)
/*-------------------------------------------------------------------------*/
@@ -1137,17 +1168,29 @@ usb_maxpacket(struct usb_device *udev, int pipe, int is_out)
return le16_to_cpu(ep->desc.wMaxPacketSize);
}
-/* -------------------------------------------------------------------------- */
+/* ----------------------------------------------------------------------- */
+
+/* Events from the usb core */
+#define USB_DEVICE_ADD 0x0001
+#define USB_DEVICE_REMOVE 0x0002
+#define USB_BUS_ADD 0x0003
+#define USB_BUS_REMOVE 0x0004
+extern void usb_register_notify(struct notifier_block *nb);
+extern void usb_unregister_notify(struct notifier_block *nb);
#ifdef DEBUG
-#define dbg(format, arg...) printk(KERN_DEBUG "%s: " format "\n" , __FILE__ , ## arg)
+#define dbg(format, arg...) printk(KERN_DEBUG "%s: " format "\n" , \
+ __FILE__ , ## arg)
#else
#define dbg(format, arg...) do {} while (0)
#endif
-#define err(format, arg...) printk(KERN_ERR "%s: " format "\n" , __FILE__ , ## arg)
-#define info(format, arg...) printk(KERN_INFO "%s: " format "\n" , __FILE__ , ## arg)
-#define warn(format, arg...) printk(KERN_WARNING "%s: " format "\n" , __FILE__ , ## arg)
+#define err(format, arg...) printk(KERN_ERR "%s: " format "\n" , \
+ __FILE__ , ## arg)
+#define info(format, arg...) printk(KERN_INFO "%s: " format "\n" , \
+ __FILE__ , ## arg)
+#define warn(format, arg...) printk(KERN_WARNING "%s: " format "\n" , \
+ __FILE__ , ## arg)
#endif /* __KERNEL__ */
diff --git a/include/linux/usb_gadget.h b/include/linux/usb_gadget.h
index 71e608607324..ff81117eb733 100644
--- a/include/linux/usb_gadget.h
+++ b/include/linux/usb_gadget.h
@@ -107,18 +107,18 @@ struct usb_ep_ops {
int (*disable) (struct usb_ep *ep);
struct usb_request *(*alloc_request) (struct usb_ep *ep,
- unsigned gfp_flags);
+ gfp_t gfp_flags);
void (*free_request) (struct usb_ep *ep, struct usb_request *req);
void *(*alloc_buffer) (struct usb_ep *ep, unsigned bytes,
- dma_addr_t *dma, unsigned gfp_flags);
+ dma_addr_t *dma, gfp_t gfp_flags);
void (*free_buffer) (struct usb_ep *ep, void *buf, dma_addr_t dma,
unsigned bytes);
// NOTE: on 2.6, drivers may also use dma_map() and
// dma_sync_single_*() to directly manage dma overhead.
int (*queue) (struct usb_ep *ep, struct usb_request *req,
- unsigned gfp_flags);
+ gfp_t gfp_flags);
int (*dequeue) (struct usb_ep *ep, struct usb_request *req);
int (*set_halt) (struct usb_ep *ep, int value);
@@ -214,7 +214,7 @@ usb_ep_disable (struct usb_ep *ep)
* Returns the request, or null if one could not be allocated.
*/
static inline struct usb_request *
-usb_ep_alloc_request (struct usb_ep *ep, unsigned gfp_flags)
+usb_ep_alloc_request (struct usb_ep *ep, gfp_t gfp_flags)
{
return ep->ops->alloc_request (ep, gfp_flags);
}
@@ -254,7 +254,7 @@ usb_ep_free_request (struct usb_ep *ep, struct usb_request *req)
*/
static inline void *
usb_ep_alloc_buffer (struct usb_ep *ep, unsigned len, dma_addr_t *dma,
- unsigned gfp_flags)
+ gfp_t gfp_flags)
{
return ep->ops->alloc_buffer (ep, len, dma, gfp_flags);
}
@@ -330,7 +330,7 @@ usb_ep_free_buffer (struct usb_ep *ep, void *buf, dma_addr_t dma, unsigned len)
* reported when the usb peripheral is disconnected.
*/
static inline int
-usb_ep_queue (struct usb_ep *ep, struct usb_request *req, unsigned gfp_flags)
+usb_ep_queue (struct usb_ep *ep, struct usb_request *req, gfp_t gfp_flags)
{
return ep->ops->queue (ep, req, gfp_flags);
}
diff --git a/include/linux/usb_otg.h b/include/linux/usb_otg.h
index c6683146e9b0..f827f6e203c2 100644
--- a/include/linux/usb_otg.h
+++ b/include/linux/usb_otg.h
@@ -63,6 +63,10 @@ struct otg_transceiver {
int (*set_power)(struct otg_transceiver *otg,
unsigned mA);
+ /* for non-OTG B devices: set transceiver into suspend mode */
+ int (*set_suspend)(struct otg_transceiver *otg,
+ int suspend);
+
/* for B devices only: start session with A-Host */
int (*start_srp)(struct otg_transceiver *otg);
@@ -108,6 +112,15 @@ otg_set_power(struct otg_transceiver *otg, unsigned mA)
}
static inline int
+otg_set_suspend(struct otg_transceiver *otg, int suspend)
+{
+ if (otg->set_suspend != NULL)
+ return otg->set_suspend(otg, suspend);
+ else
+ return 0;
+}
+
+static inline int
otg_start_srp(struct otg_transceiver *otg)
{
return otg->start_srp(otg);
diff --git a/include/linux/usbdevice_fs.h b/include/linux/usbdevice_fs.h
index 9facf733800c..8859f0b41543 100644
--- a/include/linux/usbdevice_fs.h
+++ b/include/linux/usbdevice_fs.h
@@ -140,6 +140,12 @@ struct usbdevfs_urb32 {
compat_caddr_t usercontext; /* unused */
struct usbdevfs_iso_packet_desc iso_frame_desc[0];
};
+
+struct usbdevfs_ioctl32 {
+ s32 ifno;
+ s32 ioctl_code;
+ compat_caddr_t data;
+};
#endif
#define USBDEVFS_CONTROL _IOWR('U', 0, struct usbdevfs_ctrltransfer)
@@ -160,6 +166,7 @@ struct usbdevfs_urb32 {
#define USBDEVFS_RELEASEINTERFACE _IOR('U', 16, unsigned int)
#define USBDEVFS_CONNECTINFO _IOW('U', 17, struct usbdevfs_connectinfo)
#define USBDEVFS_IOCTL _IOWR('U', 18, struct usbdevfs_ioctl)
+#define USBDEVFS_IOCTL32 _IOWR('U', 18, struct usbdevfs_ioctl32)
#define USBDEVFS_HUB_PORTINFO _IOR('U', 19, struct usbdevfs_hub_portinfo)
#define USBDEVFS_RESET _IO('U', 20)
#define USBDEVFS_CLEAR_HALT _IOR('U', 21, unsigned int)
diff --git a/include/linux/videodev.h b/include/linux/videodev.h
index 1cc8c31b7988..91140091ced2 100644
--- a/include/linux/videodev.h
+++ b/include/linux/videodev.h
@@ -1,57 +1,16 @@
#ifndef __LINUX_VIDEODEV_H
#define __LINUX_VIDEODEV_H
-#include <linux/compiler.h>
#include <linux/types.h>
-#define HAVE_V4L2 1
+#define HAVE_V4L1 1
+
#include <linux/videodev2.h>
#ifdef __KERNEL__
-#include <linux/poll.h>
#include <linux/mm.h>
-#include <linux/device.h>
-
-struct video_device
-{
- /* device info */
- struct device *dev;
- char name[32];
- int type; /* v4l1 */
- int type2; /* v4l2 */
- int hardware;
- int minor;
-
- /* device ops + callbacks */
- struct file_operations *fops;
- void (*release)(struct video_device *vfd);
-
-
- /* obsolete -- fops->owner is used instead */
- struct module *owner;
- /* dev->driver_data will be used instead some day.
- * Use the video_{get|set}_drvdata() helper functions,
- * so the switch over will be transparent for you.
- * Or use {pci|usb}_{get|set}_drvdata() directly. */
- void *priv;
-
- /* for videodev.c intenal usage -- please don't touch */
- int users; /* video_exclusive_{open|close} ... */
- struct semaphore lock; /* ... helper function uses these */
- char devfs_name[64]; /* devfs */
- struct class_device class_dev; /* sysfs */
-};
-
-#define VIDEO_MAJOR 81
-
-#define VFL_TYPE_GRABBER 0
-#define VFL_TYPE_VBI 1
-#define VFL_TYPE_RADIO 2
-#define VFL_TYPE_VTX 3
-extern int video_register_device(struct video_device *, int type, int nr);
-extern void video_unregister_device(struct video_device *);
extern struct video_device* video_devdata(struct file*);
#define to_video_device(cd) container_of(cd, struct video_device, class_dev)
@@ -68,11 +27,7 @@ video_device_remove_file(struct video_device *vfd,
class_device_remove_file(&vfd->class_dev, attr);
}
-/* helper functions to alloc / release struct video_device, the
- later can be used for video_device->release() */
-struct video_device *video_device_alloc(void);
-void video_device_release(struct video_device *vfd);
-
+#if OBSOLETE_OWNER /* to be removed in 2.6.15 */
/* helper functions to access driver private data. */
static inline void *video_get_drvdata(struct video_device *dev)
{
@@ -83,30 +38,12 @@ static inline void video_set_drvdata(struct video_device *dev, void *data)
{
dev->priv = data;
}
+#endif
extern int video_exclusive_open(struct inode *inode, struct file *file);
extern int video_exclusive_release(struct inode *inode, struct file *file);
-extern int video_usercopy(struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long arg,
- int (*func)(struct inode *inode, struct file *file,
- unsigned int cmd, void *arg));
#endif /* __KERNEL__ */
-#define VID_TYPE_CAPTURE 1 /* Can capture */
-#define VID_TYPE_TUNER 2 /* Can tune */
-#define VID_TYPE_TELETEXT 4 /* Does teletext */
-#define VID_TYPE_OVERLAY 8 /* Overlay onto frame buffer */
-#define VID_TYPE_CHROMAKEY 16 /* Overlay by chromakey */
-#define VID_TYPE_CLIPPING 32 /* Can clip */
-#define VID_TYPE_FRAMERAM 64 /* Uses the frame buffer memory */
-#define VID_TYPE_SCALES 128 /* Scalable */
-#define VID_TYPE_MONOCHROME 256 /* Monochrome only */
-#define VID_TYPE_SUBCAPTURE 512 /* Can capture subareas of the image */
-#define VID_TYPE_MPEG_DECODER 1024 /* Can decode MPEG streams */
-#define VID_TYPE_MPEG_ENCODER 2048 /* Can encode MPEG streams */
-#define VID_TYPE_MJPEG_DECODER 4096 /* Can decode MJPEG streams */
-#define VID_TYPE_MJPEG_ENCODER 8192 /* Can encode MJPEG streams */
-
struct video_capability
{
char name[32];
@@ -202,9 +139,9 @@ struct video_audio
#define VIDEO_SOUND_STEREO 2
#define VIDEO_SOUND_LANG1 4
#define VIDEO_SOUND_LANG2 8
- __u16 mode;
- __u16 balance; /* Stereo balance */
- __u16 step; /* Step actual volume uses */
+ __u16 mode;
+ __u16 balance; /* Stereo balance */
+ __u16 step; /* Step actual volume uses */
};
struct video_clip
@@ -260,9 +197,6 @@ struct video_key
__u32 flags;
};
-
-#define VIDEO_MAX_FRAME 32
-
struct video_mbuf
{
int size; /* Total memory to map */
@@ -270,10 +204,8 @@ struct video_mbuf
int offsets[VIDEO_MAX_FRAME];
};
-
#define VIDEO_NO_UNIT (-1)
-
struct video_unit
{
int video; /* Video minor */
diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
index 89a055761bed..a114fff6568b 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -15,16 +15,99 @@
*/
#ifdef __KERNEL__
#include <linux/time.h> /* need struct timeval */
+#include <linux/poll.h>
+#include <linux/device.h>
#endif
#include <linux/compiler.h> /* need __user */
+
+#define OBSOLETE_OWNER 1 /* It will be removed for 2.6.15 */
+#define HAVE_V4L2 1
+
+/*
+ * Common stuff for both V4L1 and V4L2
+ * Moved from videodev.h
+ */
+
+#define VIDEO_MAX_FRAME 32
+
+#define VID_TYPE_CAPTURE 1 /* Can capture */
+#define VID_TYPE_TUNER 2 /* Can tune */
+#define VID_TYPE_TELETEXT 4 /* Does teletext */
+#define VID_TYPE_OVERLAY 8 /* Overlay onto frame buffer */
+#define VID_TYPE_CHROMAKEY 16 /* Overlay by chromakey */
+#define VID_TYPE_CLIPPING 32 /* Can clip */
+#define VID_TYPE_FRAMERAM 64 /* Uses the frame buffer memory */
+#define VID_TYPE_SCALES 128 /* Scalable */
+#define VID_TYPE_MONOCHROME 256 /* Monochrome only */
+#define VID_TYPE_SUBCAPTURE 512 /* Can capture subareas of the image */
+#define VID_TYPE_MPEG_DECODER 1024 /* Can decode MPEG streams */
+#define VID_TYPE_MPEG_ENCODER 2048 /* Can encode MPEG streams */
+#define VID_TYPE_MJPEG_DECODER 4096 /* Can decode MJPEG streams */
+#define VID_TYPE_MJPEG_ENCODER 8192 /* Can encode MJPEG streams */
+
+#ifdef __KERNEL__
+
+#define VFL_TYPE_GRABBER 0
+#define VFL_TYPE_VBI 1
+#define VFL_TYPE_RADIO 2
+#define VFL_TYPE_VTX 3
+
+struct video_device
+{
+ /* device info */
+ struct device *dev;
+ char name[32];
+ int type; /* v4l1 */
+ int type2; /* v4l2 */
+ int hardware;
+ int minor;
+
+ /* device ops + callbacks */
+ struct file_operations *fops;
+ void (*release)(struct video_device *vfd);
+
+
+#if OBSOLETE_OWNER /* to be removed in 2.6.15 */
+ /* obsolete -- fops->owner is used instead */
+ struct module *owner;
+ /* dev->driver_data will be used instead some day.
+ * Use the video_{get|set}_drvdata() helper functions,
+ * so the switch over will be transparent for you.
+ * Or use {pci|usb}_{get|set}_drvdata() directly. */
+ void *priv;
+#endif
+
+ /* for videodev.c intenal usage -- please don't touch */
+ int users; /* video_exclusive_{open|close} ... */
+ struct semaphore lock; /* ... helper function uses these */
+ char devfs_name[64]; /* devfs */
+ struct class_device class_dev; /* sysfs */
+};
+
+#define VIDEO_MAJOR 81
+
+extern int video_register_device(struct video_device *, int type, int nr);
+extern void video_unregister_device(struct video_device *);
+extern int video_usercopy(struct inode *inode, struct file *file,
+ unsigned int cmd, unsigned long arg,
+ int (*func)(struct inode *inode, struct file *file,
+ unsigned int cmd, void *arg));
+
+/* helper functions to alloc / release struct video_device, the
+ later can be used for video_device->release() */
+struct video_device *video_device_alloc(void);
+void video_device_release(struct video_device *vfd);
+
+#endif
+
/*
* M I S C E L L A N E O U S
*/
/* Four-character-code (FOURCC) */
#define v4l2_fourcc(a,b,c,d)\
- (((__u32)(a)<<0)|((__u32)(b)<<8)|((__u32)(c)<<16)|((__u32)(d)<<24))
+ (((__u32)(a)<<0)|((__u32)(b)<<8)|((__u32)(c)<<16)|((__u32)(d)<<24))
/*
* E N U M S
@@ -154,20 +237,20 @@ struct v4l2_capability
};
/* Values for 'capabilities' field */
-#define V4L2_CAP_VIDEO_CAPTURE 0x00000001 /* Is a video capture device */
-#define V4L2_CAP_VIDEO_OUTPUT 0x00000002 /* Is a video output device */
-#define V4L2_CAP_VIDEO_OVERLAY 0x00000004 /* Can do video overlay */
-#define V4L2_CAP_VBI_CAPTURE 0x00000010 /* Is a raw VBI capture device */
-#define V4L2_CAP_VBI_OUTPUT 0x00000020 /* Is a raw VBI output device */
+#define V4L2_CAP_VIDEO_CAPTURE 0x00000001 /* Is a video capture device */
+#define V4L2_CAP_VIDEO_OUTPUT 0x00000002 /* Is a video output device */
+#define V4L2_CAP_VIDEO_OVERLAY 0x00000004 /* Can do video overlay */
+#define V4L2_CAP_VBI_CAPTURE 0x00000010 /* Is a raw VBI capture device */
+#define V4L2_CAP_VBI_OUTPUT 0x00000020 /* Is a raw VBI output device */
#if 1
#define V4L2_CAP_SLICED_VBI_CAPTURE 0x00000040 /* Is a sliced VBI capture device */
#define V4L2_CAP_SLICED_VBI_OUTPUT 0x00000080 /* Is a sliced VBI output device */
#endif
-#define V4L2_CAP_RDS_CAPTURE 0x00000100 /* RDS data capture */
+#define V4L2_CAP_RDS_CAPTURE 0x00000100 /* RDS data capture */
-#define V4L2_CAP_TUNER 0x00010000 /* has a tuner */
-#define V4L2_CAP_AUDIO 0x00020000 /* has audio support */
-#define V4L2_CAP_RADIO 0x00040000 /* is a radio device */
+#define V4L2_CAP_TUNER 0x00010000 /* has a tuner */
+#define V4L2_CAP_AUDIO 0x00020000 /* has audio support */
+#define V4L2_CAP_RADIO 0x00040000 /* is a radio device */
#define V4L2_CAP_READWRITE 0x01000000 /* read/write systemcalls */
#define V4L2_CAP_ASYNCIO 0x02000000 /* async I/O */
@@ -179,13 +262,13 @@ struct v4l2_capability
struct v4l2_pix_format
{
- __u32 width;
- __u32 height;
- __u32 pixelformat;
+ __u32 width;
+ __u32 height;
+ __u32 pixelformat;
enum v4l2_field field;
__u32 bytesperline; /* for padding, zero if unused */
- __u32 sizeimage;
- enum v4l2_colorspace colorspace;
+ __u32 sizeimage;
+ enum v4l2_colorspace colorspace;
__u32 priv; /* private data, depends on pixelformat */
};
@@ -238,12 +321,12 @@ struct v4l2_pix_format
*/
struct v4l2_fmtdesc
{
- __u32 index; /* Format number */
+ __u32 index; /* Format number */
enum v4l2_buf_type type; /* buffer type */
__u32 flags;
- __u8 description[32]; /* Description string */
- __u32 pixelformat; /* Format fourcc */
- __u32 reserved[4];
+ __u8 description[32]; /* Description string */
+ __u32 pixelformat; /* Format fourcc */
+ __u32 reserved[4];
};
#define V4L2_FMT_FLAG_COMPRESSED 0x0001
@@ -393,7 +476,7 @@ struct v4l2_jpegcompression
#define V4L2_JPEG_MARKER_DRI (1<<5) /* Define Restart Interval */
#define V4L2_JPEG_MARKER_COM (1<<6) /* Comment segment */
#define V4L2_JPEG_MARKER_APP (1<<7) /* App segment, driver will
- * allways use APP0 */
+ * allways use APP0 */
};
@@ -402,10 +485,10 @@ struct v4l2_jpegcompression
*/
struct v4l2_requestbuffers
{
- __u32 count;
+ __u32 count;
enum v4l2_buf_type type;
enum v4l2_memory memory;
- __u32 reserved[2];
+ __u32 reserved[2];
};
struct v4l2_buffer
@@ -511,9 +594,9 @@ struct v4l2_outputparm
struct v4l2_cropcap {
enum v4l2_buf_type type;
- struct v4l2_rect bounds;
- struct v4l2_rect defrect;
- struct v4l2_fract pixelaspect;
+ struct v4l2_rect bounds;
+ struct v4l2_rect defrect;
+ struct v4l2_fract pixelaspect;
};
struct v4l2_crop {
@@ -544,6 +627,7 @@ typedef __u64 v4l2_std_id;
#define V4L2_STD_NTSC_M ((v4l2_std_id)0x00001000)
#define V4L2_STD_NTSC_M_JP ((v4l2_std_id)0x00002000)
+#define V4L2_STD_NTSC_443 ((v4l2_std_id)0x00004000)
#define V4L2_STD_SECAM_B ((v4l2_std_id)0x00010000)
#define V4L2_STD_SECAM_D ((v4l2_std_id)0x00020000)
@@ -581,13 +665,14 @@ typedef __u64 v4l2_std_id;
#define V4L2_STD_525_60 (V4L2_STD_PAL_M |\
V4L2_STD_PAL_60 |\
- V4L2_STD_NTSC)
+ V4L2_STD_NTSC |\
+ V4L2_STD_NTSC_443)
#define V4L2_STD_625_50 (V4L2_STD_PAL |\
V4L2_STD_PAL_N |\
V4L2_STD_PAL_Nc |\
V4L2_STD_SECAM)
#define V4L2_STD_ATSC (V4L2_STD_ATSC_8_VSB |\
- V4L2_STD_ATSC_16_VSB)
+ V4L2_STD_ATSC_16_VSB)
#define V4L2_STD_UNKNOWN 0
#define V4L2_STD_ALL (V4L2_STD_525_60 |\
@@ -595,7 +680,7 @@ typedef __u64 v4l2_std_id;
struct v4l2_standard
{
- __u32 index;
+ __u32 index;
v4l2_std_id id;
__u8 name[24];
struct v4l2_fract frameperiod; /* Frames, not fields */
@@ -610,9 +695,9 @@ struct v4l2_standard
struct v4l2_input
{
__u32 index; /* Which input */
- __u8 name[32]; /* Label */
+ __u8 name[32]; /* Label */
__u32 type; /* Type of input */
- __u32 audioset; /* Associated audios (bitfield) */
+ __u32 audioset; /* Associated audios (bitfield) */
__u32 tuner; /* Associated tuner */
v4l2_std_id std;
__u32 status;
@@ -647,9 +732,9 @@ struct v4l2_input
struct v4l2_output
{
__u32 index; /* Which output */
- __u8 name[32]; /* Label */
+ __u8 name[32]; /* Label */
__u32 type; /* Type of output */
- __u32 audioset; /* Associated audios (bitfield) */
+ __u32 audioset; /* Associated audios (bitfield) */
__u32 modulator; /* Associated modulator */
v4l2_std_id std;
__u32 reserved[4];
@@ -671,12 +756,12 @@ struct v4l2_control
/* Used in the VIDIOC_QUERYCTRL ioctl for querying controls */
struct v4l2_queryctrl
{
- __u32 id;
+ __u32 id;
enum v4l2_ctrl_type type;
__u8 name[32]; /* Whatever */
__s32 minimum; /* Note signedness */
__s32 maximum;
- __s32 step;
+ __s32 step;
__s32 default_value;
__u32 flags;
__u32 reserved[2];
@@ -779,10 +864,10 @@ struct v4l2_modulator
struct v4l2_frequency
{
- __u32 tuner;
+ __u32 tuner;
enum v4l2_tuner_type type;
- __u32 frequency;
- __u32 reserved[8];
+ __u32 frequency;
+ __u32 reserved[8];
};
/*
@@ -802,6 +887,7 @@ struct v4l2_audio
/* Flags for the 'mode' field */
#define V4L2_AUDMODE_AVL 0x00001
+#define V4L2_AUDMODE_32BITS 0x00002
struct v4l2_audioout
{
@@ -846,14 +932,14 @@ struct v4l2_vbi_format
struct v4l2_sliced_vbi_format
{
- __u16 service_set;
- /* service_lines[0][...] specifies lines 0-23 (1-23 used) of the first field
- service_lines[1][...] specifies lines 0-23 (1-23 used) of the second field
- (equals frame lines 313-336 for 625 line video
- standards, 263-286 for 525 line standards) */
- __u16 service_lines[2][24];
- __u32 io_size;
- __u32 reserved[2]; /* must be zero */
+ __u16 service_set;
+ /* service_lines[0][...] specifies lines 0-23 (1-23 used) of the first field
+ service_lines[1][...] specifies lines 0-23 (1-23 used) of the second field
+ (equals frame lines 313-336 for 625 line video
+ standards, 263-286 for 525 line standards) */
+ __u16 service_lines[2][24];
+ __u32 io_size;
+ __u32 reserved[2]; /* must be zero */
};
#define V4L2_SLICED_TELETEXT_B (0x0001)
@@ -866,22 +952,22 @@ struct v4l2_sliced_vbi_format
struct v4l2_sliced_vbi_cap
{
- __u16 service_set;
- /* service_lines[0][...] specifies lines 0-23 (1-23 used) of the first field
- service_lines[1][...] specifies lines 0-23 (1-23 used) of the second field
- (equals frame lines 313-336 for 625 line video
- standards, 263-286 for 525 line standards) */
- __u16 service_lines[2][24];
- __u32 reserved[4]; /* must be 0 */
+ __u16 service_set;
+ /* service_lines[0][...] specifies lines 0-23 (1-23 used) of the first field
+ service_lines[1][...] specifies lines 0-23 (1-23 used) of the second field
+ (equals frame lines 313-336 for 625 line video
+ standards, 263-286 for 525 line standards) */
+ __u16 service_lines[2][24];
+ __u32 reserved[4]; /* must be 0 */
};
struct v4l2_sliced_vbi_data
{
- __u32 id;
- __u32 field; /* 0: first field, 1: second field */
- __u32 line; /* 1-23 */
- __u32 reserved; /* must be 0 */
- __u8 data[48];
+ __u32 id;
+ __u32 field; /* 0: first field, 1: second field */
+ __u32 line; /* 1-23 */
+ __u32 reserved; /* must be 0 */
+ __u8 data[48];
};
#endif
@@ -896,9 +982,9 @@ struct v4l2_format
enum v4l2_buf_type type;
union
{
- struct v4l2_pix_format pix; // V4L2_BUF_TYPE_VIDEO_CAPTURE
- struct v4l2_window win; // V4L2_BUF_TYPE_VIDEO_OVERLAY
- struct v4l2_vbi_format vbi; // V4L2_BUF_TYPE_VBI_CAPTURE
+ struct v4l2_pix_format pix; // V4L2_BUF_TYPE_VIDEO_CAPTURE
+ struct v4l2_window win; // V4L2_BUF_TYPE_VIDEO_OVERLAY
+ struct v4l2_vbi_format vbi; // V4L2_BUF_TYPE_VBI_CAPTURE
#if 1
struct v4l2_sliced_vbi_format sliced; // V4L2_BUF_TYPE_SLICED_VBI_CAPTURE
#endif
@@ -981,6 +1067,7 @@ struct v4l2_streamparm
#if 1
#define VIDIOC_G_SLICED_VBI_CAP _IOR ('V', 69, struct v4l2_sliced_vbi_cap)
#endif
+#define VIDIOC_LOG_STATUS _IO ('V', 70)
/* for compatibility, will go away some day */
#define VIDIOC_OVERLAY_OLD _IOWR ('V', 14, int)
diff --git a/include/linux/vmalloc.h b/include/linux/vmalloc.h
index 3701a0673d2c..1d5577b2b752 100644
--- a/include/linux/vmalloc.h
+++ b/include/linux/vmalloc.h
@@ -32,10 +32,14 @@ struct vm_struct {
* Highlevel APIs for driver use
*/
extern void *vmalloc(unsigned long size);
+extern void *vmalloc_node(unsigned long size, int node);
extern void *vmalloc_exec(unsigned long size);
extern void *vmalloc_32(unsigned long size);
extern void *__vmalloc(unsigned long size, gfp_t gfp_mask, pgprot_t prot);
-extern void *__vmalloc_area(struct vm_struct *area, gfp_t gfp_mask, pgprot_t prot);
+extern void *__vmalloc_area(struct vm_struct *area, gfp_t gfp_mask,
+ pgprot_t prot);
+extern void *__vmalloc_node(unsigned long size, gfp_t gfp_mask,
+ pgprot_t prot, int node);
extern void vfree(void *addr);
extern void *vmap(struct page **pages, unsigned int count,
@@ -48,6 +52,8 @@ extern void vunmap(void *addr);
extern struct vm_struct *get_vm_area(unsigned long size, unsigned long flags);
extern struct vm_struct *__get_vm_area(unsigned long size, unsigned long flags,
unsigned long start, unsigned long end);
+extern struct vm_struct *get_vm_area_node(unsigned long size,
+ unsigned long flags, int node);
extern struct vm_struct *remove_vm_area(void *addr);
extern struct vm_struct *__remove_vm_area(void *addr);
extern int map_vm_area(struct vm_struct *area, pgprot_t prot,
diff --git a/include/linux/wait.h b/include/linux/wait.h
index d38c9fecdc36..d28518236b62 100644
--- a/include/linux/wait.h
+++ b/include/linux/wait.h
@@ -54,6 +54,7 @@ struct __wait_queue_head {
};
typedef struct __wait_queue_head wait_queue_head_t;
+struct task_struct;
/*
* Macros for declaration and initialisaton of the datatypes
diff --git a/include/linux/wanpipe.h b/include/linux/wanpipe.h
index 167d956c492b..dae9860091dd 100644
--- a/include/linux/wanpipe.h
+++ b/include/linux/wanpipe.h
@@ -265,15 +265,6 @@ typedef struct {
#include <linux/tty_driver.h>
#include <linux/tty_flip.h>
-
-#define is_digit(ch) (((ch)>=(unsigned)'0'&&(ch)<=(unsigned)'9')?1:0)
-#define is_alpha(ch) ((((ch)>=(unsigned)'a'&&(ch)<=(unsigned)'z')||\
- ((ch)>=(unsigned)'A'&&(ch)<=(unsigned)'Z'))?1:0)
-#define is_hex_digit(ch) ((((ch)>=(unsigned)'0'&&(ch)<=(unsigned)'9')||\
- ((ch)>=(unsigned)'a'&&(ch)<=(unsigned)'f')||\
- ((ch)>=(unsigned)'A'&&(ch)<=(unsigned)'F'))?1:0)
-
-
/****** Data Structures *****************************************************/
/* Adapter Data Space.
diff --git a/include/linux/x1205.h b/include/linux/x1205.h
new file mode 100644
index 000000000000..64fd3af894a5
--- /dev/null
+++ b/include/linux/x1205.h
@@ -0,0 +1,31 @@
+/*
+ * x1205.h - defines for drivers/i2c/chips/x1205.c
+ * Copyright 2004 Karen Spearel
+ * Copyright 2005 Alessandro Zummo
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef __LINUX_X1205_H__
+#define __LINUX_X1205_H__
+
+/* commands */
+
+#define X1205_CMD_GETDATETIME 0
+#define X1205_CMD_SETTIME 1
+#define X1205_CMD_SETDATETIME 2
+#define X1205_CMD_GETALARM 3
+#define X1205_CMD_SETALARM 4
+#define X1205_CMD_GETDTRIM 5
+#define X1205_CMD_SETDTRIM 6
+#define X1205_CMD_GETATRIM 7
+#define X1205_CMD_SETATRIM 8
+
+extern int x1205_do_command(unsigned int cmd, void *arg);
+extern int x1205_direct_attach(int adapter_id,
+ struct i2c_client_address_data *address_data);
+
+#endif /* __LINUX_X1205_H__ */
diff --git a/include/linux/zutil.h b/include/linux/zutil.h
index fdfd5ed41ec4..ee0c59cf2136 100644
--- a/include/linux/zutil.h
+++ b/include/linux/zutil.h
@@ -15,7 +15,6 @@
#include <linux/zlib.h>
#include <linux/string.h>
-#include <linux/errno.h>
#include <linux/kernel.h>
typedef unsigned char uch;
diff --git a/include/media/audiochip.h b/include/media/audiochip.h
index a7ceee9fc5e9..b7d4b0930408 100644
--- a/include/media/audiochip.h
+++ b/include/media/audiochip.h
@@ -4,6 +4,23 @@
#ifndef AUDIOCHIP_H
#define AUDIOCHIP_H
+enum audiochip {
+ AUDIO_CHIP_NONE,
+ AUDIO_CHIP_UNKNOWN,
+ /* Provided by video chip */
+ AUDIO_CHIP_INTERNAL,
+ /* Provided by tvaudio.c */
+ AUDIO_CHIP_TDA8425,
+ AUDIO_CHIP_TEA6300,
+ AUDIO_CHIP_TEA6420,
+ AUDIO_CHIP_TDA9840,
+ AUDIO_CHIP_TDA985X,
+ AUDIO_CHIP_TDA9874,
+ AUDIO_CHIP_PIC16C54,
+ /* Provided by msp3400.c */
+ AUDIO_CHIP_MSP34XX
+};
+
/* ---------------------------------------------------------------------- */
/* v4l device was opened in Radio mode */
diff --git a/include/media/id.h b/include/media/id.h
deleted file mode 100644
index 6d02c94cdc0d..000000000000
--- a/include/media/id.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- */
-
-/* FIXME: this temporarely, until these are included in linux/i2c-id.h */
-
-/* drivers */
-#ifndef I2C_DRIVERID_TVMIXER
-# define I2C_DRIVERID_TVMIXER I2C_DRIVERID_EXP0
-#endif
-#ifndef I2C_DRIVERID_TVAUDIO
-# define I2C_DRIVERID_TVAUDIO I2C_DRIVERID_EXP1
-#endif
-
-/* chips */
-#ifndef I2C_DRIVERID_DPL3518
-# define I2C_DRIVERID_DPL3518 I2C_DRIVERID_EXP2
-#endif
-#ifndef I2C_DRIVERID_TDA9873
-# define I2C_DRIVERID_TDA9873 I2C_DRIVERID_EXP3
-#endif
-#ifndef I2C_DRIVERID_TDA9875
-# define I2C_DRIVERID_TDA9875 I2C_DRIVERID_EXP0+4
-#endif
-#ifndef I2C_DRIVERID_PIC16C54_PV951
-# define I2C_DRIVERID_PIC16C54_PV951 I2C_DRIVERID_EXP0+5
-#endif
-#ifndef I2C_DRIVERID_TDA7432
-# define I2C_DRIVERID_TDA7432 I2C_DRIVERID_EXP0+6
-#endif
-#ifndef I2C_DRIVERID_TDA9874
-# define I2C_DRIVERID_TDA9874 I2C_DRIVERID_EXP0+7
-#endif
-#ifndef I2C_DRIVERID_SAA6752HS
-# define I2C_DRIVERID_SAA6752HS I2C_DRIVERID_EXP0+8
-#endif
diff --git a/include/media/ir-common.h b/include/media/ir-common.h
index 01b56822df4d..0f1ba95ec8d6 100644
--- a/include/media/ir-common.h
+++ b/include/media/ir-common.h
@@ -20,8 +20,10 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include <linux/input.h>
+#ifndef _IR_COMMON
+#define _IR_COMMON
+#include <linux/input.h>
#define IR_TYPE_RC5 1
#define IR_TYPE_PD 2 /* Pulse distance encoded IR */
@@ -61,6 +63,8 @@ int ir_dump_samples(u32 *samples, int count);
int ir_decode_biphase(u32 *samples, int count, int low, int high);
int ir_decode_pulsedistance(u32 *samples, int count, int low, int high);
+#endif
+
/*
* Local variables:
* c-basic-offset: 8
diff --git a/include/media/ir-kbd-i2c.h b/include/media/ir-kbd-i2c.h
new file mode 100644
index 000000000000..00fa57eb9fde
--- /dev/null
+++ b/include/media/ir-kbd-i2c.h
@@ -0,0 +1,22 @@
+#ifndef _IR_I2C
+#define _IR_I2C
+
+#include <media/ir-common.h>
+
+struct IR_i2c;
+
+struct IR_i2c {
+ IR_KEYTAB_TYPE *ir_codes;
+ struct i2c_client c;
+ struct input_dev *input;
+ struct ir_input_state ir;
+
+ /* Used to avoid fast repeating */
+ unsigned char old;
+
+ struct work_struct work;
+ struct timer_list timer;
+ char phys[32];
+ int (*get_key)(struct IR_i2c*, u32*, u32*);
+};
+#endif
diff --git a/include/media/ovcamchip.h b/include/media/ovcamchip.h
index cb7c0aa96f22..8138983adced 100644
--- a/include/media/ovcamchip.h
+++ b/include/media/ovcamchip.h
@@ -17,20 +17,6 @@
#include <linux/videodev.h>
#include <linux/i2c.h>
-/* Remove these once they are officially defined */
-#ifndef I2C_DRIVERID_OVCAMCHIP
- #define I2C_DRIVERID_OVCAMCHIP 0xf00f
-#endif
-#ifndef I2C_HW_SMBUS_OV511
- #define I2C_HW_SMBUS_OV511 0xfe
-#endif
-#ifndef I2C_HW_SMBUS_OV518
- #define I2C_HW_SMBUS_OV518 0xff
-#endif
-#ifndef I2C_HW_SMBUS_OVFX2
- #define I2C_HW_SMBUS_OVFX2 0xfd
-#endif
-
/* --------------------------------- */
/* ENUMERATIONS */
/* --------------------------------- */
diff --git a/include/media/saa7146_vv.h b/include/media/saa7146_vv.h
index f3aa24f8131c..64691753721e 100644
--- a/include/media/saa7146_vv.h
+++ b/include/media/saa7146_vv.h
@@ -1,7 +1,7 @@
#ifndef __SAA7146_VV__
#define __SAA7146_VV__
-#include <linux/videodev2.h>
+#include <linux/videodev.h>
#include <media/saa7146.h>
#include <media/video-buf.h>
diff --git a/include/media/tuner.h b/include/media/tuner.h
index 4ad08e24a1aa..9184e534b7ef 100644
--- a/include/media/tuner.h
+++ b/include/media/tuner.h
@@ -95,7 +95,7 @@
#define TUNER_THOMSON_DTT7610 52
#define TUNER_PHILIPS_FQ1286 53
#define TUNER_PHILIPS_TDA8290 54
-#define TUNER_LG_PAL_TAPE 55 /* Hauppauge PVR-150 PAL */
+#define TUNER_TCL_2002MB 55 /* Hauppauge PVR-150 PAL */
#define TUNER_PHILIPS_FQ1216AME_MK4 56 /* Hauppauge PVR-150 PAL */
#define TUNER_PHILIPS_FQ1236A_MK4 57 /* Hauppauge PVR-500MCE NTSC */
@@ -110,6 +110,9 @@
#define TUNER_LG_TDVS_H062F 64 /* DViCO FusionHDTV 5 */
#define TUNER_YMEC_TVF66T5_B_DFF 65 /* Acorp Y878F */
#define TUNER_LG_NTSC_TALN_MINI 66
+#define TUNER_PHILIPS_TD1316 67
+
+#define TUNER_PHILIPS_TUV1236D 68 /* ATI HDTV Wonder */
#define NOTUNER 0
#define PAL 1 /* PAL_BG */
@@ -145,6 +148,7 @@
# define TDA9887_INTERCARRIER (1<<4)
# define TDA9887_PORT1_ACTIVE (1<<5)
# define TDA9887_PORT2_ACTIVE (1<<6)
+# define TDA9887_INTERCARRIER_NTSC (1<<7)
/* config options */
# define TDA9887_DEEMPHASIS_MASK (3<<16)
# define TDA9887_DEEMPHASIS_NONE (1<<16)
@@ -188,8 +192,11 @@ struct tuner {
unsigned int radio_if2;
/* used by tda8290 */
- unsigned char i2c_easy_mode[2];
- unsigned char i2c_set_freq[8];
+ unsigned char tda8290_easy_mode;
+ unsigned char tda827x_lpsel;
+ unsigned char tda827x_addr;
+ unsigned char tda827x_ver;
+ unsigned int sgIF;
/* function ptrs */
void (*tv_freq)(struct i2c_client *c, unsigned int freq);
@@ -204,20 +211,21 @@ extern unsigned const int tuner_count;
extern int microtune_init(struct i2c_client *c);
extern int tda8290_init(struct i2c_client *c);
+extern int tda8290_probe(struct i2c_client *c);
extern int tea5767_tuner_init(struct i2c_client *c);
extern int default_tuner_init(struct i2c_client *c);
extern int tea5767_autodetection(struct i2c_client *c);
#define tuner_warn(fmt, arg...) do {\
printk(KERN_WARNING "%s %d-%04x: " fmt, t->i2c.driver->name, \
- t->i2c.adapter->nr, t->i2c.addr , ##arg); } while (0)
+ t->i2c.adapter->nr, t->i2c.addr , ##arg); } while (0)
#define tuner_info(fmt, arg...) do {\
printk(KERN_INFO "%s %d-%04x: " fmt, t->i2c.driver->name, \
- t->i2c.adapter->nr, t->i2c.addr , ##arg); } while (0)
+ t->i2c.adapter->nr, t->i2c.addr , ##arg); } while (0)
#define tuner_dbg(fmt, arg...) do {\
if (tuner_debug) \
- printk(KERN_DEBUG "%s %d-%04x: " fmt, t->i2c.driver->name, \
- t->i2c.adapter->nr, t->i2c.addr , ##arg); } while (0)
+ printk(KERN_DEBUG "%s %d-%04x: " fmt, t->i2c.driver->name, \
+ t->i2c.adapter->nr, t->i2c.addr , ##arg); } while (0)
#endif /* __KERNEL__ */
diff --git a/include/media/video-buf.h b/include/media/video-buf.h
index ae8d7a000440..8ecfd78e0027 100644
--- a/include/media/video-buf.h
+++ b/include/media/video-buf.h
@@ -17,7 +17,7 @@
* (at your option) any later version.
*/
-#include <linux/videodev.h>
+#include <linux/videodev2.h>
#define UNSET (-1U)
@@ -177,7 +177,7 @@ struct videobuf_queue_ops {
};
struct videobuf_queue {
- struct semaphore lock;
+ struct semaphore lock;
spinlock_t *irqlock;
struct pci_dev *pci;
diff --git a/include/mtd/inftl-user.h b/include/mtd/inftl-user.h
index bda4f2c8f728..9b1e2526b45e 100644
--- a/include/mtd/inftl-user.h
+++ b/include/mtd/inftl-user.h
@@ -1,7 +1,7 @@
/*
- * $Id: inftl-user.h,v 1.1 2004/05/05 15:17:00 dwmw2 Exp $
+ * $Id: inftl-user.h,v 1.2 2005/11/07 11:14:56 gleixner Exp $
*
- * Parts of INFTL headers shared with userspace
+ * Parts of INFTL headers shared with userspace
*
*/
diff --git a/include/mtd/mtd-abi.h b/include/mtd/mtd-abi.h
index 428d9122940b..b5994ea56a5a 100644
--- a/include/mtd/mtd-abi.h
+++ b/include/mtd/mtd-abi.h
@@ -1,7 +1,7 @@
/*
- * $Id: mtd-abi.h,v 1.11 2005/05/19 16:08:58 gleixner Exp $
+ * $Id: mtd-abi.h,v 1.13 2005/11/07 11:14:56 gleixner Exp $
*
- * Portions of MTD ABI definition which are shared by kernel and user space
+ * Portions of MTD ABI definition which are shared by kernel and user space
*/
#ifndef __MTD_ABI_H__
@@ -42,6 +42,7 @@ struct mtd_oob_buf {
#define MTD_OOB 64 // Out-of-band data (NAND flash)
#define MTD_ECC 128 // Device capable of automatic ECC
#define MTD_NO_VIRTBLOCKS 256 // Virtual blocks not allowed
+#define MTD_PROGRAM_REGIONS 512 // Configurable Programming Regions
// Some common devices / combinations of capabilities
#define MTD_CAP_ROM 0
@@ -80,7 +81,7 @@ struct mtd_info_user {
};
struct region_info_user {
- uint32_t offset; /* At which this region starts,
+ uint32_t offset; /* At which this region starts,
* from the beginning of the MTD */
uint32_t erasesize; /* For this region */
uint32_t numblocks; /* Number of blocks in this region */
diff --git a/include/mtd/nftl-user.h b/include/mtd/nftl-user.h
index 924ec0459e9c..b2bca18e7311 100644
--- a/include/mtd/nftl-user.h
+++ b/include/mtd/nftl-user.h
@@ -1,7 +1,7 @@
/*
- * $Id: nftl-user.h,v 1.1 2004/05/05 14:44:57 dwmw2 Exp $
+ * $Id: nftl-user.h,v 1.2 2005/11/07 11:14:56 gleixner Exp $
*
- * Parts of NFTL headers shared with userspace
+ * Parts of NFTL headers shared with userspace
*
*/
diff --git a/include/net/ax25.h b/include/net/ax25.h
index 30bb4a893237..2250a18b0cbb 100644
--- a/include/net/ax25.h
+++ b/include/net/ax25.h
@@ -237,8 +237,7 @@ typedef struct ax25_cb {
static __inline__ void ax25_cb_put(ax25_cb *ax25)
{
if (atomic_dec_and_test(&ax25->refcount)) {
- if (ax25->digipeat)
- kfree(ax25->digipeat);
+ kfree(ax25->digipeat);
kfree(ax25);
}
}
diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h
index 210458624840..911ceb5cd263 100644
--- a/include/net/bluetooth/bluetooth.h
+++ b/include/net/bluetooth/bluetooth.h
@@ -57,8 +57,6 @@
#define BT_DBG(fmt, arg...) printk(KERN_INFO "%s: " fmt "\n" , __FUNCTION__ , ## arg)
#define BT_ERR(fmt, arg...) printk(KERN_ERR "%s: " fmt "\n" , __FUNCTION__ , ## arg)
-extern struct proc_dir_entry *proc_bt;
-
/* Connection and socket states */
enum {
BT_CONNECTED = 1, /* Equal to TCP_ESTABLISHED to make net code happy */
@@ -171,4 +169,12 @@ static inline int skb_frags_no(struct sk_buff *skb)
int bt_err(__u16 code);
+extern int hci_sock_init(void);
+extern int hci_sock_cleanup(void);
+
+extern int bt_sysfs_init(void);
+extern void bt_sysfs_cleanup(void);
+
+extern struct class bt_class;
+
#endif /* __BLUETOOTH_H */
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index fa2d12b0579b..b06a2d2f63d2 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -184,10 +184,10 @@ enum {
struct hci_rp_read_loc_version {
__u8 status;
__u8 hci_ver;
- __u16 hci_rev;
+ __le16 hci_rev;
__u8 lmp_ver;
- __u16 manufacturer;
- __u16 lmp_subver;
+ __le16 manufacturer;
+ __le16 lmp_subver;
} __attribute__ ((packed));
#define OCF_READ_LOCAL_FEATURES 0x0003
@@ -199,10 +199,10 @@ struct hci_rp_read_loc_features {
#define OCF_READ_BUFFER_SIZE 0x0005
struct hci_rp_read_buffer_size {
__u8 status;
- __u16 acl_mtu;
+ __le16 acl_mtu;
__u8 sco_mtu;
- __u16 acl_max_pkt;
- __u16 sco_max_pkt;
+ __le16 acl_max_pkt;
+ __le16 sco_max_pkt;
} __attribute__ ((packed));
#define OCF_READ_BD_ADDR 0x0009
@@ -267,21 +267,21 @@ struct hci_cp_write_dev_class {
#define OCF_READ_VOICE_SETTING 0x0025
struct hci_rp_read_voice_setting {
- __u8 status;
- __u16 voice_setting;
+ __u8 status;
+ __le16 voice_setting;
} __attribute__ ((packed));
#define OCF_WRITE_VOICE_SETTING 0x0026
struct hci_cp_write_voice_setting {
- __u16 voice_setting;
+ __le16 voice_setting;
} __attribute__ ((packed));
#define OCF_HOST_BUFFER_SIZE 0x0033
struct hci_cp_host_buffer_size {
- __u16 acl_mtu;
+ __le16 acl_mtu;
__u8 sco_mtu;
- __u16 acl_max_pkt;
- __u16 sco_max_pkt;
+ __le16 acl_max_pkt;
+ __le16 sco_max_pkt;
} __attribute__ ((packed));
/* Link Control */
@@ -289,10 +289,10 @@ struct hci_cp_host_buffer_size {
#define OCF_CREATE_CONN 0x0005
struct hci_cp_create_conn {
bdaddr_t bdaddr;
- __u16 pkt_type;
+ __le16 pkt_type;
__u8 pscan_rep_mode;
__u8 pscan_mode;
- __u16 clock_offset;
+ __le16 clock_offset;
__u8 role_switch;
} __attribute__ ((packed));
@@ -310,14 +310,14 @@ struct hci_cp_reject_conn_req {
#define OCF_DISCONNECT 0x0006
struct hci_cp_disconnect {
- __u16 handle;
+ __le16 handle;
__u8 reason;
} __attribute__ ((packed));
#define OCF_ADD_SCO 0x0007
struct hci_cp_add_sco {
- __u16 handle;
- __u16 pkt_type;
+ __le16 handle;
+ __le16 pkt_type;
} __attribute__ ((packed));
#define OCF_INQUIRY 0x0001
@@ -354,56 +354,56 @@ struct hci_cp_pin_code_neg_reply {
#define OCF_CHANGE_CONN_PTYPE 0x000F
struct hci_cp_change_conn_ptype {
- __u16 handle;
- __u16 pkt_type;
+ __le16 handle;
+ __le16 pkt_type;
} __attribute__ ((packed));
#define OCF_AUTH_REQUESTED 0x0011
struct hci_cp_auth_requested {
- __u16 handle;
+ __le16 handle;
} __attribute__ ((packed));
#define OCF_SET_CONN_ENCRYPT 0x0013
struct hci_cp_set_conn_encrypt {
- __u16 handle;
+ __le16 handle;
__u8 encrypt;
} __attribute__ ((packed));
#define OCF_CHANGE_CONN_LINK_KEY 0x0015
struct hci_cp_change_conn_link_key {
- __u16 handle;
+ __le16 handle;
} __attribute__ ((packed));
#define OCF_READ_REMOTE_FEATURES 0x001B
struct hci_cp_read_rmt_features {
- __u16 handle;
+ __le16 handle;
} __attribute__ ((packed));
#define OCF_READ_REMOTE_VERSION 0x001D
struct hci_cp_read_rmt_version {
- __u16 handle;
+ __le16 handle;
} __attribute__ ((packed));
/* Link Policy */
#define OGF_LINK_POLICY 0x02
#define OCF_ROLE_DISCOVERY 0x0009
struct hci_cp_role_discovery {
- __u16 handle;
+ __le16 handle;
} __attribute__ ((packed));
struct hci_rp_role_discovery {
__u8 status;
- __u16 handle;
+ __le16 handle;
__u8 role;
} __attribute__ ((packed));
#define OCF_READ_LINK_POLICY 0x000C
struct hci_cp_read_link_policy {
- __u16 handle;
+ __le16 handle;
} __attribute__ ((packed));
struct hci_rp_read_link_policy {
__u8 status;
- __u16 handle;
- __u16 policy;
+ __le16 handle;
+ __le16 policy;
} __attribute__ ((packed));
#define OCF_SWITCH_ROLE 0x000B
@@ -414,12 +414,12 @@ struct hci_cp_switch_role {
#define OCF_WRITE_LINK_POLICY 0x000D
struct hci_cp_write_link_policy {
- __u16 handle;
- __u16 policy;
+ __le16 handle;
+ __le16 policy;
} __attribute__ ((packed));
struct hci_rp_write_link_policy {
__u8 status;
- __u16 handle;
+ __le16 handle;
} __attribute__ ((packed));
/* Status params */
@@ -441,7 +441,7 @@ struct inquiry_info {
__u8 pscan_period_mode;
__u8 pscan_mode;
__u8 dev_class[3];
- __u16 clock_offset;
+ __le16 clock_offset;
} __attribute__ ((packed));
#define HCI_EV_INQUIRY_RESULT_WITH_RSSI 0x22
@@ -450,7 +450,7 @@ struct inquiry_info_with_rssi {
__u8 pscan_rep_mode;
__u8 pscan_period_mode;
__u8 dev_class[3];
- __u16 clock_offset;
+ __le16 clock_offset;
__s8 rssi;
} __attribute__ ((packed));
struct inquiry_info_with_rssi_and_pscan_mode {
@@ -459,7 +459,7 @@ struct inquiry_info_with_rssi_and_pscan_mode {
__u8 pscan_period_mode;
__u8 pscan_mode;
__u8 dev_class[3];
- __u16 clock_offset;
+ __le16 clock_offset;
__s8 rssi;
} __attribute__ ((packed));
@@ -469,7 +469,7 @@ struct extended_inquiry_info {
__u8 pscan_rep_mode;
__u8 pscan_period_mode;
__u8 dev_class[3];
- __u16 clock_offset;
+ __le16 clock_offset;
__s8 rssi;
__u8 data[240];
} __attribute__ ((packed));
@@ -477,7 +477,7 @@ struct extended_inquiry_info {
#define HCI_EV_CONN_COMPLETE 0x03
struct hci_ev_conn_complete {
__u8 status;
- __u16 handle;
+ __le16 handle;
bdaddr_t bdaddr;
__u8 link_type;
__u8 encr_mode;
@@ -493,27 +493,27 @@ struct hci_ev_conn_request {
#define HCI_EV_DISCONN_COMPLETE 0x05
struct hci_ev_disconn_complete {
__u8 status;
- __u16 handle;
+ __le16 handle;
__u8 reason;
} __attribute__ ((packed));
#define HCI_EV_AUTH_COMPLETE 0x06
struct hci_ev_auth_complete {
__u8 status;
- __u16 handle;
+ __le16 handle;
} __attribute__ ((packed));
#define HCI_EV_ENCRYPT_CHANGE 0x08
struct hci_ev_encrypt_change {
__u8 status;
- __u16 handle;
+ __le16 handle;
__u8 encrypt;
} __attribute__ ((packed));
#define HCI_EV_CHANGE_CONN_LINK_KEY_COMPLETE 0x09
struct hci_ev_change_conn_link_key_complete {
__u8 status;
- __u16 handle;
+ __le16 handle;
} __attribute__ ((packed));
#define HCI_EV_QOS_SETUP_COMPLETE 0x0D
@@ -526,21 +526,21 @@ struct hci_qos {
} __attribute__ ((packed));
struct hci_ev_qos_setup_complete {
__u8 status;
- __u16 handle;
+ __le16 handle;
struct hci_qos qos;
} __attribute__ ((packed));
#define HCI_EV_CMD_COMPLETE 0x0E
struct hci_ev_cmd_complete {
__u8 ncmd;
- __u16 opcode;
+ __le16 opcode;
} __attribute__ ((packed));
#define HCI_EV_CMD_STATUS 0x0F
struct hci_ev_cmd_status {
__u8 status;
__u8 ncmd;
- __u16 opcode;
+ __le16 opcode;
} __attribute__ ((packed));
#define HCI_EV_NUM_COMP_PKTS 0x13
@@ -559,9 +559,9 @@ struct hci_ev_role_change {
#define HCI_EV_MODE_CHANGE 0x14
struct hci_ev_mode_change {
__u8 status;
- __u16 handle;
+ __le16 handle;
__u8 mode;
- __u16 interval;
+ __le16 interval;
} __attribute__ ((packed));
#define HCI_EV_PIN_CODE_REQ 0x16
@@ -584,24 +584,24 @@ struct hci_ev_link_key_notify {
#define HCI_EV_RMT_FEATURES 0x0B
struct hci_ev_rmt_features {
__u8 status;
- __u16 handle;
+ __le16 handle;
__u8 features[8];
} __attribute__ ((packed));
#define HCI_EV_RMT_VERSION 0x0C
struct hci_ev_rmt_version {
__u8 status;
- __u16 handle;
+ __le16 handle;
__u8 lmp_ver;
- __u16 manufacturer;
- __u16 lmp_subver;
+ __le16 manufacturer;
+ __le16 lmp_subver;
} __attribute__ ((packed));
#define HCI_EV_CLOCK_OFFSET 0x01C
struct hci_ev_clock_offset {
__u8 status;
- __u16 handle;
- __u16 clock_offset;
+ __le16 handle;
+ __le16 clock_offset;
} __attribute__ ((packed));
#define HCI_EV_PSCAN_REP_MODE 0x20
@@ -638,7 +638,7 @@ struct hci_ev_si_security {
#define HCI_SCO_HDR_SIZE 3
struct hci_command_hdr {
- __u16 opcode; /* OCF & OGF */
+ __le16 opcode; /* OCF & OGF */
__u8 plen;
} __attribute__ ((packed));
@@ -648,22 +648,22 @@ struct hci_event_hdr {
} __attribute__ ((packed));
struct hci_acl_hdr {
- __u16 handle; /* Handle & Flags(PB, BC) */
- __u16 dlen;
+ __le16 handle; /* Handle & Flags(PB, BC) */
+ __le16 dlen;
} __attribute__ ((packed));
struct hci_sco_hdr {
- __u16 handle;
+ __le16 handle;
__u8 dlen;
} __attribute__ ((packed));
/* Command opcode pack/unpack */
-#define hci_opcode_pack(ogf, ocf) (__u16)((ocf & 0x03ff)|(ogf << 10))
+#define hci_opcode_pack(ogf, ocf) (__u16) ((ocf & 0x03ff)|(ogf << 10))
#define hci_opcode_ogf(op) (op >> 10)
#define hci_opcode_ocf(op) (op & 0x03ff)
/* ACL handle and flags pack/unpack */
-#define hci_handle_pack(h, f) (__u16)((h & 0x0fff)|(f << 12))
+#define hci_handle_pack(h, f) (__u16) ((h & 0x0fff)|(f << 12))
#define hci_handle(h) (h & 0x0fff)
#define hci_flags(h) (h >> 12)
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 7f933f302078..bb9f81dc8723 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -25,7 +25,6 @@
#ifndef __HCI_CORE_H
#define __HCI_CORE_H
-#include <linux/proc_fs.h>
#include <net/bluetooth/hci.h>
/* HCI upper protocols */
@@ -34,8 +33,6 @@
#define HCI_INIT_TIMEOUT (HZ * 10)
-extern struct proc_dir_entry *proc_bt_hci;
-
/* HCI Core structures */
struct inquiry_data {
@@ -44,7 +41,7 @@ struct inquiry_data {
__u8 pscan_period_mode;
__u8 pscan_mode;
__u8 dev_class[3];
- __u16 clock_offset;
+ __le16 clock_offset;
__s8 rssi;
};
@@ -126,10 +123,6 @@ struct hci_dev {
atomic_t promisc;
-#ifdef CONFIG_PROC_FS
- struct proc_dir_entry *proc;
-#endif
-
struct class_device class_dev;
struct module *owner;
diff --git a/include/net/bluetooth/rfcomm.h b/include/net/bluetooth/rfcomm.h
index fbe557f7ea1d..bbfac86734ec 100644
--- a/include/net/bluetooth/rfcomm.h
+++ b/include/net/bluetooth/rfcomm.h
@@ -275,9 +275,6 @@ static inline void rfcomm_session_hold(struct rfcomm_session *s)
atomic_inc(&s->refcnt);
}
-/* ---- RFCOMM chechsum ---- */
-extern u8 rfcomm_crc_table[];
-
/* ---- RFCOMM sockets ---- */
struct sockaddr_rc {
sa_family_t rc_family;
@@ -354,6 +351,4 @@ int rfcomm_dev_ioctl(struct sock *sk, unsigned int cmd, void __user *arg);
int rfcomm_init_ttys(void);
void rfcomm_cleanup_ttys(void);
-extern struct proc_dir_entry *proc_bt_rfcomm;
-
#endif /* __RFCOMM_H */
diff --git a/include/net/dst.h b/include/net/dst.h
index 4a056a682435..6c196a5baf24 100644
--- a/include/net/dst.h
+++ b/include/net/dst.h
@@ -94,7 +94,6 @@ struct dst_ops
struct dst_entry * (*negative_advice)(struct dst_entry *);
void (*link_failure)(struct sk_buff *);
void (*update_pmtu)(struct dst_entry *dst, u32 mtu);
- int (*get_mss)(struct dst_entry *dst, u32 mtu);
int entry_size;
atomic_t entries;
diff --git a/include/net/genetlink.h b/include/net/genetlink.h
new file mode 100644
index 000000000000..52d8b1a73d52
--- /dev/null
+++ b/include/net/genetlink.h
@@ -0,0 +1,154 @@
+#ifndef __NET_GENERIC_NETLINK_H
+#define __NET_GENERIC_NETLINK_H
+
+#include <linux/genetlink.h>
+#include <net/netlink.h>
+
+/**
+ * struct genl_family - generic netlink family
+ * @id: protocol family idenfitier
+ * @hdrsize: length of user specific header in bytes
+ * @name: name of family
+ * @version: protocol version
+ * @maxattr: maximum number of attributes supported
+ * @attrbuf: buffer to store parsed attributes
+ * @ops_list: list of all assigned operations
+ * @family_list: family list
+ */
+struct genl_family
+{
+ unsigned int id;
+ unsigned int hdrsize;
+ char name[GENL_NAMSIZ];
+ unsigned int version;
+ unsigned int maxattr;
+ struct module * owner;
+ struct nlattr ** attrbuf; /* private */
+ struct list_head ops_list; /* private */
+ struct list_head family_list; /* private */
+};
+
+#define GENL_ADMIN_PERM 0x01
+
+/**
+ * struct genl_info - receiving information
+ * @snd_seq: sending sequence number
+ * @snd_pid: netlink pid of sender
+ * @nlhdr: netlink message header
+ * @genlhdr: generic netlink message header
+ * @userhdr: user specific header
+ * @attrs: netlink attributes
+ */
+struct genl_info
+{
+ u32 snd_seq;
+ u32 snd_pid;
+ struct nlmsghdr * nlhdr;
+ struct genlmsghdr * genlhdr;
+ void * userhdr;
+ struct nlattr ** attrs;
+};
+
+/**
+ * struct genl_ops - generic netlink operations
+ * @cmd: command identifier
+ * @flags: flags
+ * @policy: attribute validation policy
+ * @doit: standard command callback
+ * @dumpit: callback for dumpers
+ * @ops_list: operations list
+ */
+struct genl_ops
+{
+ unsigned int cmd;
+ unsigned int flags;
+ struct nla_policy *policy;
+ int (*doit)(struct sk_buff *skb,
+ struct genl_info *info);
+ int (*dumpit)(struct sk_buff *skb,
+ struct netlink_callback *cb);
+ struct list_head ops_list;
+};
+
+extern int genl_register_family(struct genl_family *family);
+extern int genl_unregister_family(struct genl_family *family);
+extern int genl_register_ops(struct genl_family *, struct genl_ops *ops);
+extern int genl_unregister_ops(struct genl_family *, struct genl_ops *ops);
+
+extern struct sock *genl_sock;
+
+/**
+ * genlmsg_put - Add generic netlink header to netlink message
+ * @skb: socket buffer holding the message
+ * @pid: netlink pid the message is addressed to
+ * @seq: sequence number (usually the one of the sender)
+ * @type: netlink message type
+ * @hdrlen: length of the user specific header
+ * @flags netlink message flags
+ * @cmd: generic netlink command
+ * @version: version
+ *
+ * Returns pointer to user specific header
+ */
+static inline void *genlmsg_put(struct sk_buff *skb, u32 pid, u32 seq,
+ int type, int hdrlen, int flags,
+ u8 cmd, u8 version)
+{
+ struct nlmsghdr *nlh;
+ struct genlmsghdr *hdr;
+
+ nlh = nlmsg_put(skb, pid, seq, type, GENL_HDRLEN + hdrlen, flags);
+ if (nlh == NULL)
+ return NULL;
+
+ hdr = nlmsg_data(nlh);
+ hdr->cmd = cmd;
+ hdr->version = version;
+ hdr->reserved = 0;
+
+ return (char *) hdr + GENL_HDRLEN;
+}
+
+/**
+ * genlmsg_end - Finalize a generic netlink message
+ * @skb: socket buffer the message is stored in
+ * @hdr: user specific header
+ */
+static inline int genlmsg_end(struct sk_buff *skb, void *hdr)
+{
+ return nlmsg_end(skb, hdr - GENL_HDRLEN - NLMSG_HDRLEN);
+}
+
+/**
+ * genlmsg_cancel - Cancel construction of a generic netlink message
+ * @skb: socket buffer the message is stored in
+ * @hdr: generic netlink message header
+ */
+static inline int genlmsg_cancel(struct sk_buff *skb, void *hdr)
+{
+ return nlmsg_cancel(skb, hdr - GENL_HDRLEN - NLMSG_HDRLEN);
+}
+
+/**
+ * genlmsg_multicast - multicast a netlink message
+ * @skb: netlink message as socket buffer
+ * @pid: own netlink pid to avoid sending to yourself
+ * @group: multicast group id
+ */
+static inline int genlmsg_multicast(struct sk_buff *skb, u32 pid,
+ unsigned int group)
+{
+ return nlmsg_multicast(genl_sock, skb, pid, group);
+}
+
+/**
+ * genlmsg_unicast - unicast a netlink message
+ * @skb: netlink message as socket buffer
+ * @pid: netlink pid of the destination socket
+ */
+static inline int genlmsg_unicast(struct sk_buff *skb, u32 pid)
+{
+ return nlmsg_unicast(genl_sock, skb, pid);
+}
+
+#endif /* __NET_GENERIC_NETLINK_H */
diff --git a/include/net/ieee80211.h b/include/net/ieee80211.h
index dc36b1be6745..b93fd8c1d884 100644
--- a/include/net/ieee80211.h
+++ b/include/net/ieee80211.h
@@ -11,19 +11,26 @@
*
* Adaption to a generic IEEE 802.11 stack by James Ketrenos
* <jketreno@linux.intel.com>
- * Copyright (c) 2004, Intel Corporation
+ * Copyright (c) 2004-2005, Intel 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. See README and COPYING for
* more details.
+ *
+ * API Version History
+ * 1.0.x -- Initial version
+ * 1.1.x -- Added radiotap, QoS, TIM, ieee80211_geo APIs,
+ * various structure changes, and crypto API init method
*/
#ifndef IEEE80211_H
#define IEEE80211_H
-#include <linux/if_ether.h> /* ETH_ALEN */
-#include <linux/kernel.h> /* ARRAY_SIZE */
+#include <linux/if_ether.h> /* ETH_ALEN */
+#include <linux/kernel.h> /* ARRAY_SIZE */
#include <linux/wireless.h>
+#define IEEE80211_VERSION "git-1.1.7"
+
#define IEEE80211_DATA_LEN 2304
/* Maximum size for the MA-UNITDATA primitive, 802.11 standard section
6.2.1.1.2.
@@ -33,34 +40,13 @@
represents the 2304 bytes of real data, plus a possible 8 bytes of
WEP IV and ICV. (this interpretation suggested by Ramiro Barreiro) */
-
-#define IEEE80211_HLEN 30
-#define IEEE80211_FRAME_LEN (IEEE80211_DATA_LEN + IEEE80211_HLEN)
-
-struct ieee80211_hdr {
- __le16 frame_ctl;
- __le16 duration_id;
- u8 addr1[ETH_ALEN];
- u8 addr2[ETH_ALEN];
- u8 addr3[ETH_ALEN];
- __le16 seq_ctl;
- u8 addr4[ETH_ALEN];
-} __attribute__ ((packed));
-
-struct ieee80211_hdr_3addr {
- __le16 frame_ctl;
- __le16 duration_id;
- u8 addr1[ETH_ALEN];
- u8 addr2[ETH_ALEN];
- u8 addr3[ETH_ALEN];
- __le16 seq_ctl;
-} __attribute__ ((packed));
-
#define IEEE80211_1ADDR_LEN 10
#define IEEE80211_2ADDR_LEN 16
#define IEEE80211_3ADDR_LEN 24
#define IEEE80211_4ADDR_LEN 30
#define IEEE80211_FCS_LEN 4
+#define IEEE80211_HLEN (IEEE80211_4ADDR_LEN)
+#define IEEE80211_FRAME_LEN (IEEE80211_DATA_LEN + IEEE80211_HLEN)
#define MIN_FRAG_THRESHOLD 256U
#define MAX_FRAG_THRESHOLD 2346U
@@ -113,11 +99,11 @@ struct ieee80211_hdr_3addr {
#define IEEE80211_STYPE_CFACK 0x0050
#define IEEE80211_STYPE_CFPOLL 0x0060
#define IEEE80211_STYPE_CFACKPOLL 0x0070
+#define IEEE80211_STYPE_QOS_DATA 0x0080
#define IEEE80211_SCTL_FRAG 0x000F
#define IEEE80211_SCTL_SEQ 0xFFF0
-
/* debug macros */
#ifdef CONFIG_IEEE80211_DEBUG
@@ -128,8 +114,7 @@ do { if (ieee80211_debug_level & (level)) \
in_interrupt() ? 'I' : 'U', __FUNCTION__ , ## args); } while (0)
#else
#define IEEE80211_DEBUG(level, fmt, args...) do {} while (0)
-#endif /* CONFIG_IEEE80211_DEBUG */
-
+#endif /* CONFIG_IEEE80211_DEBUG */
/* debug macros not dependent on CONFIG_IEEE80211_DEBUG */
@@ -140,7 +125,6 @@ do { if (ieee80211_debug_level & (level)) \
* messages. It should never be used for passing essid to user space. */
const char *escape_essid(const char *essid, u8 essid_len);
-
/*
* To use the debug system:
*
@@ -177,6 +161,7 @@ const char *escape_essid(const char *essid, u8 essid_len);
#define IEEE80211_DL_TX (1<<8)
#define IEEE80211_DL_RX (1<<9)
+#define IEEE80211_DL_QOS (1<<31)
#define IEEE80211_ERROR(f, a...) printk(KERN_ERR "ieee80211: " f, ## a)
#define IEEE80211_WARNING(f, a...) printk(KERN_WARNING "ieee80211: " f, ## a)
@@ -190,9 +175,10 @@ const char *escape_essid(const char *essid, u8 essid_len);
#define IEEE80211_DEBUG_DROP(f, a...) IEEE80211_DEBUG(IEEE80211_DL_DROP, f, ## a)
#define IEEE80211_DEBUG_TX(f, a...) IEEE80211_DEBUG(IEEE80211_DL_TX, f, ## a)
#define IEEE80211_DEBUG_RX(f, a...) IEEE80211_DEBUG(IEEE80211_DL_RX, f, ## a)
+#define IEEE80211_DEBUG_QOS(f, a...) IEEE80211_DEBUG(IEEE80211_DL_QOS, f, ## a)
#include <linux/netdevice.h>
#include <linux/wireless.h>
-#include <linux/if_arp.h> /* ARPHRD_ETHER */
+#include <linux/if_arp.h> /* ARPHRD_ETHER */
#ifndef WIRELESS_SPY
#define WIRELESS_SPY /* enable iwspy support */
@@ -200,10 +186,10 @@ const char *escape_essid(const char *essid, u8 essid_len);
#include <net/iw_handler.h> /* new driver API */
#ifndef ETH_P_PAE
-#define ETH_P_PAE 0x888E /* Port Access Entity (IEEE 802.1X) */
-#endif /* ETH_P_PAE */
+#define ETH_P_PAE 0x888E /* Port Access Entity (IEEE 802.1X) */
+#endif /* ETH_P_PAE */
-#define ETH_P_PREAUTH 0x88C7 /* IEEE 802.11i pre-authentication */
+#define ETH_P_PREAUTH 0x88C7 /* IEEE 802.11i pre-authentication */
#ifndef ETH_P_80211_RAW
#define ETH_P_80211_RAW (ETH_P_ECONET + 1)
@@ -215,10 +201,10 @@ const char *escape_essid(const char *essid, u8 essid_len);
struct ieee80211_snap_hdr {
- u8 dsap; /* always 0xAA */
- u8 ssap; /* always 0xAA */
- u8 ctrl; /* always 0x03 */
- u8 oui[P80211_OUI_LEN]; /* organizational universal id */
+ u8 dsap; /* always 0xAA */
+ u8 ssap; /* always 0xAA */
+ u8 ctrl; /* always 0x03 */
+ u8 oui[P80211_OUI_LEN]; /* organizational universal id */
} __attribute__ ((packed));
@@ -246,8 +232,9 @@ struct ieee80211_snap_hdr {
#define WLAN_CAPABILITY_PBCC (1<<6)
#define WLAN_CAPABILITY_CHANNEL_AGILITY (1<<7)
#define WLAN_CAPABILITY_SPECTRUM_MGMT (1<<8)
+#define WLAN_CAPABILITY_QOS (1<<9)
#define WLAN_CAPABILITY_SHORT_SLOT_TIME (1<<10)
-#define WLAN_CAPABILITY_OSSS_OFDM (1<<13)
+#define WLAN_CAPABILITY_DSSS_OFDM (1<<13)
/* Status codes */
enum ieee80211_statuscode {
@@ -312,14 +299,12 @@ enum ieee80211_reasoncode {
WLAN_REASON_CIPHER_SUITE_REJECTED = 24,
};
-
#define IEEE80211_STATMASK_SIGNAL (1<<0)
#define IEEE80211_STATMASK_RSSI (1<<1)
#define IEEE80211_STATMASK_NOISE (1<<2)
#define IEEE80211_STATMASK_RATE (1<<3)
#define IEEE80211_STATMASK_WEMASK 0x7
-
#define IEEE80211_CCK_MODULATION (1<<0)
#define IEEE80211_OFDM_MODULATION (1<<1)
@@ -377,9 +362,6 @@ enum ieee80211_reasoncode {
#define IEEE80211_NUM_CCK_RATES 4
#define IEEE80211_OFDM_SHIFT_MASK_A 4
-
-
-
/* NOTE: This data is for statistical purposes; not all hardware provides this
* information for frames received. Not setting these will not cause
* any adverse affects. */
@@ -388,7 +370,7 @@ struct ieee80211_rx_stats {
s8 rssi;
u8 signal;
u8 noise;
- u16 rate; /* in 100 kbps */
+ u16 rate; /* in 100 kbps */
u8 received_channel;
u8 control;
u8 mask;
@@ -439,38 +421,44 @@ struct ieee80211_device;
#include "ieee80211_crypt.h"
-#define SEC_KEY_1 (1<<0)
-#define SEC_KEY_2 (1<<1)
-#define SEC_KEY_3 (1<<2)
-#define SEC_KEY_4 (1<<3)
-#define SEC_ACTIVE_KEY (1<<4)
-#define SEC_AUTH_MODE (1<<5)
-#define SEC_UNICAST_GROUP (1<<6)
-#define SEC_LEVEL (1<<7)
-#define SEC_ENABLED (1<<8)
-
-#define SEC_LEVEL_0 0 /* None */
-#define SEC_LEVEL_1 1 /* WEP 40 and 104 bit */
-#define SEC_LEVEL_2 2 /* Level 1 + TKIP */
-#define SEC_LEVEL_2_CKIP 3 /* Level 1 + CKIP */
-#define SEC_LEVEL_3 4 /* Level 2 + CCMP */
-
-#define WEP_KEYS 4
-#define WEP_KEY_LEN 13
+#define SEC_KEY_1 (1<<0)
+#define SEC_KEY_2 (1<<1)
+#define SEC_KEY_3 (1<<2)
+#define SEC_KEY_4 (1<<3)
+#define SEC_ACTIVE_KEY (1<<4)
+#define SEC_AUTH_MODE (1<<5)
+#define SEC_UNICAST_GROUP (1<<6)
+#define SEC_LEVEL (1<<7)
+#define SEC_ENABLED (1<<8)
+#define SEC_ENCRYPT (1<<9)
+
+#define SEC_LEVEL_0 0 /* None */
+#define SEC_LEVEL_1 1 /* WEP 40 and 104 bit */
+#define SEC_LEVEL_2 2 /* Level 1 + TKIP */
+#define SEC_LEVEL_2_CKIP 3 /* Level 1 + CKIP */
+#define SEC_LEVEL_3 4 /* Level 2 + CCMP */
+
+#define SEC_ALG_NONE 0
+#define SEC_ALG_WEP 1
+#define SEC_ALG_TKIP 2
+#define SEC_ALG_CCMP 3
+
+#define WEP_KEYS 4
+#define WEP_KEY_LEN 13
+#define SCM_KEY_LEN 32
+#define SCM_TEMPORAL_KEY_LENGTH 16
struct ieee80211_security {
u16 active_key:2,
- enabled:1,
- auth_mode:2,
- auth_algo:4,
- unicast_uses_group:1;
+ enabled:1,
+ auth_mode:2, auth_algo:4, unicast_uses_group:1, encrypt:1;
+ u8 encode_alg[WEP_KEYS];
u8 key_sizes[WEP_KEYS];
- u8 keys[WEP_KEYS][WEP_KEY_LEN];
+ u8 keys[WEP_KEYS][SCM_KEY_LEN];
u8 level;
u16 flags;
} __attribute__ ((packed));
-
/*
802.11 data frame from AP
@@ -494,7 +482,7 @@ enum ieee80211_mfie {
MFIE_TYPE_RATES = 1,
MFIE_TYPE_FH_SET = 2,
MFIE_TYPE_DS_SET = 3,
- MFIE_TYPE_CF_SET = 4,
+ MFIE_TYPE_CF_SET = 4,
MFIE_TYPE_TIM = 5,
MFIE_TYPE_IBSS_SET = 6,
MFIE_TYPE_COUNTRY = 7,
@@ -516,11 +504,75 @@ enum ieee80211_mfie {
MFIE_TYPE_RSN = 48,
MFIE_TYPE_RATES_EX = 50,
MFIE_TYPE_GENERIC = 221,
+ MFIE_TYPE_QOS_PARAMETER = 222,
};
-struct ieee80211_info_element_hdr {
- u8 id;
- u8 len;
+/* Minimal header; can be used for passing 802.11 frames with sufficient
+ * information to determine what type of underlying data type is actually
+ * stored in the data. */
+struct ieee80211_hdr {
+ __le16 frame_ctl;
+ __le16 duration_id;
+ u8 payload[0];
+} __attribute__ ((packed));
+
+struct ieee80211_hdr_1addr {
+ __le16 frame_ctl;
+ __le16 duration_id;
+ u8 addr1[ETH_ALEN];
+ u8 payload[0];
+} __attribute__ ((packed));
+
+struct ieee80211_hdr_2addr {
+ __le16 frame_ctl;
+ __le16 duration_id;
+ u8 addr1[ETH_ALEN];
+ u8 addr2[ETH_ALEN];
+ u8 payload[0];
+} __attribute__ ((packed));
+
+struct ieee80211_hdr_3addr {
+ __le16 frame_ctl;
+ __le16 duration_id;
+ u8 addr1[ETH_ALEN];
+ u8 addr2[ETH_ALEN];
+ u8 addr3[ETH_ALEN];
+ __le16 seq_ctl;
+ u8 payload[0];
+} __attribute__ ((packed));
+
+struct ieee80211_hdr_4addr {
+ __le16 frame_ctl;
+ __le16 duration_id;
+ u8 addr1[ETH_ALEN];
+ u8 addr2[ETH_ALEN];
+ u8 addr3[ETH_ALEN];
+ __le16 seq_ctl;
+ u8 addr4[ETH_ALEN];
+ u8 payload[0];
+} __attribute__ ((packed));
+
+struct ieee80211_hdr_3addrqos {
+ __le16 frame_ctl;
+ __le16 duration_id;
+ u8 addr1[ETH_ALEN];
+ u8 addr2[ETH_ALEN];
+ u8 addr3[ETH_ALEN];
+ __le16 seq_ctl;
+ u8 payload[0];
+ __le16 qos_ctl;
+} __attribute__ ((packed));
+
+struct ieee80211_hdr_4addrqos {
+ __le16 frame_ctl;
+ __le16 duration_id;
+ u8 addr1[ETH_ALEN];
+ u8 addr2[ETH_ALEN];
+ u8 addr3[ETH_ALEN];
+ __le16 seq_ctl;
+ u8 addr4[ETH_ALEN];
+ u8 payload[0];
+ __le16 qos_ctl;
} __attribute__ ((packed));
struct ieee80211_info_element {
@@ -546,49 +598,77 @@ struct ieee80211_info_element {
u16 status;
*/
-struct ieee80211_authentication {
+struct ieee80211_auth {
struct ieee80211_hdr_3addr header;
__le16 algorithm;
__le16 transaction;
__le16 status;
- struct ieee80211_info_element info_element;
+ /* challenge */
+ struct ieee80211_info_element info_element[0];
} __attribute__ ((packed));
+struct ieee80211_disassoc {
+ struct ieee80211_hdr_3addr header;
+ __le16 reason;
+} __attribute__ ((packed));
+
+/* Alias deauth for disassoc */
+#define ieee80211_deauth ieee80211_disassoc
+
+struct ieee80211_probe_request {
+ struct ieee80211_hdr_3addr header;
+ /* SSID, supported rates */
+ struct ieee80211_info_element info_element[0];
+} __attribute__ ((packed));
struct ieee80211_probe_response {
struct ieee80211_hdr_3addr header;
u32 time_stamp[2];
__le16 beacon_interval;
__le16 capability;
- struct ieee80211_info_element info_element;
+ /* SSID, supported rates, FH params, DS params,
+ * CF params, IBSS params, TIM (if beacon), RSN */
+ struct ieee80211_info_element info_element[0];
} __attribute__ ((packed));
-struct ieee80211_assoc_request_frame {
+/* Alias beacon for probe_response */
+#define ieee80211_beacon ieee80211_probe_response
+
+struct ieee80211_assoc_request {
+ struct ieee80211_hdr_3addr header;
+ __le16 capability;
+ __le16 listen_interval;
+ /* SSID, supported rates, RSN */
+ struct ieee80211_info_element info_element[0];
+} __attribute__ ((packed));
+
+struct ieee80211_reassoc_request {
+ struct ieee80211_hdr_3addr header;
__le16 capability;
__le16 listen_interval;
u8 current_ap[ETH_ALEN];
- struct ieee80211_info_element info_element;
+ struct ieee80211_info_element info_element[0];
} __attribute__ ((packed));
-struct ieee80211_assoc_response_frame {
+struct ieee80211_assoc_response {
struct ieee80211_hdr_3addr header;
__le16 capability;
__le16 status;
__le16 aid;
- struct ieee80211_info_element info_element; /* supported rates */
+ /* supported rates */
+ struct ieee80211_info_element info_element[0];
} __attribute__ ((packed));
-
struct ieee80211_txb {
u8 nr_frags;
u8 encrypted;
- u16 reserved;
- u16 frag_size;
- u16 payload_size;
+ u8 rts_included;
+ u8 reserved;
+ __le16 frag_size;
+ __le16 payload_size;
struct sk_buff *fragments[0];
};
-
/* SWEEP TABLE ENTRIES NUMBER */
#define MAX_SWEEP_TAB_ENTRIES 42
#define MAX_SWEEP_TAB_ENTRIES_PER_PACKET 7
@@ -604,9 +684,68 @@ struct ieee80211_txb {
#define MAX_WPA_IE_LEN 64
-#define NETWORK_EMPTY_ESSID (1<<0)
-#define NETWORK_HAS_OFDM (1<<1)
-#define NETWORK_HAS_CCK (1<<2)
+#define NETWORK_EMPTY_ESSID (1<<0)
+#define NETWORK_HAS_OFDM (1<<1)
+#define NETWORK_HAS_CCK (1<<2)
+
+/* QoS structure */
+#define NETWORK_HAS_QOS_PARAMETERS (1<<3)
+#define NETWORK_HAS_QOS_INFORMATION (1<<4)
+#define NETWORK_HAS_QOS_MASK (NETWORK_HAS_QOS_PARAMETERS | NETWORK_HAS_QOS_INFORMATION)
+
+#define QOS_QUEUE_NUM 4
+#define QOS_OUI_LEN 3
+#define QOS_OUI_TYPE 2
+#define QOS_ELEMENT_ID 221
+#define QOS_OUI_INFO_SUB_TYPE 0
+#define QOS_OUI_PARAM_SUB_TYPE 1
+#define QOS_VERSION_1 1
+#define QOS_AIFSN_MIN_VALUE 2
+
+struct ieee80211_qos_information_element {
+ u8 elementID;
+ u8 length;
+ u8 qui[QOS_OUI_LEN];
+ u8 qui_type;
+ u8 qui_subtype;
+ u8 version;
+ u8 ac_info;
+} __attribute__ ((packed));
+
+struct ieee80211_qos_ac_parameter {
+ u8 aci_aifsn;
+ u8 ecw_min_max;
+ __le16 tx_op_limit;
+} __attribute__ ((packed));
+
+struct ieee80211_qos_parameter_info {
+ struct ieee80211_qos_information_element info_element;
+ u8 reserved;
+ struct ieee80211_qos_ac_parameter ac_params_record[QOS_QUEUE_NUM];
+} __attribute__ ((packed));
+
+struct ieee80211_qos_parameters {
+ __le16 cw_min[QOS_QUEUE_NUM];
+ __le16 cw_max[QOS_QUEUE_NUM];
+ u8 aifs[QOS_QUEUE_NUM];
+ u8 flag[QOS_QUEUE_NUM];
+ __le16 tx_op_limit[QOS_QUEUE_NUM];
+} __attribute__ ((packed));
+
+struct ieee80211_qos_data {
+ struct ieee80211_qos_parameters parameters;
+ int active;
+ int supported;
+ u8 param_count;
+ u8 old_param_count;
+};
+
+struct ieee80211_tim_parameters {
+ u8 tim_count;
+ u8 tim_period;
+} __attribute__ ((packed));
+
+/*******************************************************/
struct ieee80211_network {
/* These entries are used to identify a unique network */
@@ -616,6 +755,8 @@ struct ieee80211_network {
u8 ssid[IW_ESSID_MAX_SIZE + 1];
u8 ssid_len;
+ struct ieee80211_qos_data qos_data;
+
/* These are network statistics */
struct ieee80211_rx_stats stats;
u16 capability;
@@ -631,10 +772,12 @@ struct ieee80211_network {
u16 beacon_interval;
u16 listen_interval;
u16 atim_window;
+ u8 erp_value;
u8 wpa_ie[MAX_WPA_IE_LEN];
size_t wpa_ie_len;
u8 rsn_ie[MAX_WPA_IE_LEN];
size_t rsn_ie_len;
+ struct ieee80211_tim_parameters tim;
struct list_head list;
};
@@ -651,17 +794,52 @@ enum ieee80211_state {
#define DEFAULT_MAX_SCAN_AGE (15 * HZ)
#define DEFAULT_FTS 2346
-
#define CFG_IEEE80211_RESERVE_FCS (1<<0)
#define CFG_IEEE80211_COMPUTE_FCS (1<<1)
+#define CFG_IEEE80211_RTS (1<<2)
+
+#define IEEE80211_24GHZ_MIN_CHANNEL 1
+#define IEEE80211_24GHZ_MAX_CHANNEL 14
+#define IEEE80211_24GHZ_CHANNELS 14
+
+#define IEEE80211_52GHZ_MIN_CHANNEL 36
+#define IEEE80211_52GHZ_MAX_CHANNEL 165
+#define IEEE80211_52GHZ_CHANNELS 32
+
+enum {
+ IEEE80211_CH_PASSIVE_ONLY = (1 << 0),
+ IEEE80211_CH_B_ONLY = (1 << 2),
+ IEEE80211_CH_NO_IBSS = (1 << 3),
+ IEEE80211_CH_UNIFORM_SPREADING = (1 << 4),
+ IEEE80211_CH_RADAR_DETECT = (1 << 5),
+ IEEE80211_CH_INVALID = (1 << 6),
+};
+
+struct ieee80211_channel {
+ u32 freq;
+ u8 channel;
+ u8 flags;
+ u8 max_power;
+};
+
+struct ieee80211_geo {
+ u8 name[4];
+ u8 bg_channels;
+ u8 a_channels;
+ struct ieee80211_channel bg[IEEE80211_24GHZ_CHANNELS];
+ struct ieee80211_channel a[IEEE80211_52GHZ_CHANNELS];
+};
struct ieee80211_device {
struct net_device *dev;
+ struct ieee80211_security sec;
/* Bookkeeping structures */
struct net_device_stats stats;
struct ieee80211_stats ieee_stats;
+ struct ieee80211_geo geo;
+
/* Probe / Beacon management */
struct list_head network_free_list;
struct list_head network_list;
@@ -669,62 +847,102 @@ struct ieee80211_device {
int scans;
int scan_age;
- int iw_mode; /* operating mode (IW_MODE_*) */
+ int iw_mode; /* operating mode (IW_MODE_*) */
+ struct iw_spy_data spy_data; /* iwspy support */
spinlock_t lock;
- int tx_headroom; /* Set to size of any additional room needed at front
- * of allocated Tx SKBs */
+ int tx_headroom; /* Set to size of any additional room needed at front
+ * of allocated Tx SKBs */
u32 config;
/* WEP and other encryption related settings at the device level */
- int open_wep; /* Set to 1 to allow unencrypted frames */
+ int open_wep; /* Set to 1 to allow unencrypted frames */
- int reset_on_keychange; /* Set to 1 if the HW needs to be reset on
+ int reset_on_keychange; /* Set to 1 if the HW needs to be reset on
* WEP key changes */
/* If the host performs {en,de}cryption, then set to 1 */
int host_encrypt;
+ int host_encrypt_msdu;
int host_decrypt;
- int ieee802_1x; /* is IEEE 802.1X used */
+ /* host performs multicast decryption */
+ int host_mc_decrypt;
+
+ int host_open_frag;
+ int host_build_iv;
+ int ieee802_1x; /* is IEEE 802.1X used */
/* WPA data */
int wpa_enabled;
int drop_unencrypted;
- int tkip_countermeasures;
int privacy_invoked;
size_t wpa_ie_len;
u8 *wpa_ie;
struct list_head crypt_deinit_list;
struct ieee80211_crypt_data *crypt[WEP_KEYS];
- int tx_keyidx; /* default TX key index (crypt[tx_keyidx]) */
+ int tx_keyidx; /* default TX key index (crypt[tx_keyidx]) */
struct timer_list crypt_deinit_timer;
+ int crypt_quiesced;
- int bcrx_sta_key; /* use individual keys to override default keys even
- * with RX of broad/multicast frames */
+ int bcrx_sta_key; /* use individual keys to override default keys even
+ * with RX of broad/multicast frames */
/* Fragmentation structures */
struct ieee80211_frag_entry frag_cache[IEEE80211_FRAG_CACHE_LEN];
unsigned int frag_next_idx;
- u16 fts; /* Fragmentation Threshold */
+ u16 fts; /* Fragmentation Threshold */
+ u16 rts; /* RTS threshold */
/* Association info */
u8 bssid[ETH_ALEN];
enum ieee80211_state state;
- int mode; /* A, B, G */
- int modulation; /* CCK, OFDM */
- int freq_band; /* 2.4Ghz, 5.2Ghz, Mixed */
- int abg_ture; /* ABG flag */
+ int mode; /* A, B, G */
+ int modulation; /* CCK, OFDM */
+ int freq_band; /* 2.4Ghz, 5.2Ghz, Mixed */
+ int abg_true; /* ABG flag */
+
+ int perfect_rssi;
+ int worst_rssi;
/* Callback functions */
- void (*set_security)(struct net_device *dev,
- struct ieee80211_security *sec);
- int (*hard_start_xmit)(struct ieee80211_txb *txb,
- struct net_device *dev);
- int (*reset_port)(struct net_device *dev);
+ void (*set_security) (struct net_device * dev,
+ struct ieee80211_security * sec);
+ int (*hard_start_xmit) (struct ieee80211_txb * txb,
+ struct net_device * dev, int pri);
+ int (*reset_port) (struct net_device * dev);
+ int (*is_queue_full) (struct net_device * dev, int pri);
+
+ int (*handle_management) (struct net_device * dev,
+ struct ieee80211_network * network, u16 type);
+
+ /* Typical STA methods */
+ int (*handle_auth) (struct net_device * dev,
+ struct ieee80211_auth * auth);
+ int (*handle_deauth) (struct net_device * dev,
+ struct ieee80211_auth * auth);
+ int (*handle_disassoc) (struct net_device * dev,
+ struct ieee80211_disassoc * assoc);
+ int (*handle_beacon) (struct net_device * dev,
+ struct ieee80211_beacon * beacon,
+ struct ieee80211_network * network);
+ int (*handle_probe_response) (struct net_device * dev,
+ struct ieee80211_probe_response * resp,
+ struct ieee80211_network * network);
+ int (*handle_probe_request) (struct net_device * dev,
+ struct ieee80211_probe_request * req,
+ struct ieee80211_rx_stats * stats);
+ int (*handle_assoc_response) (struct net_device * dev,
+ struct ieee80211_assoc_response * resp,
+ struct ieee80211_network * network);
+
+ /* Typical AP methods */
+ int (*handle_assoc_request) (struct net_device * dev);
+ int (*handle_reassoc_request) (struct net_device * dev,
+ struct ieee80211_reassoc_request * req);
/* This must be the last item so that it points to the data
* allocated beyond this structure by alloc_ieee80211 */
@@ -736,12 +954,12 @@ struct ieee80211_device {
#define IEEE_G (1<<2)
#define IEEE_MODE_MASK (IEEE_A|IEEE_B|IEEE_G)
-extern inline void *ieee80211_priv(struct net_device *dev)
+static inline void *ieee80211_priv(struct net_device *dev)
{
return ((struct ieee80211_device *)netdev_priv(dev))->priv;
}
-extern inline int ieee80211_is_empty_essid(const char *essid, int essid_len)
+static inline int ieee80211_is_empty_essid(const char *essid, int essid_len)
{
/* Single white space is for Linksys APs */
if (essid_len == 1 && essid[0] == ' ')
@@ -757,7 +975,8 @@ extern inline int ieee80211_is_empty_essid(const char *essid, int essid_len)
return 1;
}
-extern inline int ieee80211_is_valid_mode(struct ieee80211_device *ieee, int mode)
+static inline int ieee80211_is_valid_mode(struct ieee80211_device *ieee,
+ int mode)
{
/*
* It is possible for both access points and our device to support
@@ -783,14 +1002,17 @@ extern inline int ieee80211_is_valid_mode(struct ieee80211_device *ieee, int mod
return 0;
}
-extern inline int ieee80211_get_hdrlen(u16 fc)
+static inline int ieee80211_get_hdrlen(u16 fc)
{
int hdrlen = IEEE80211_3ADDR_LEN;
+ u16 stype = WLAN_FC_GET_STYPE(fc);
switch (WLAN_FC_GET_TYPE(fc)) {
case IEEE80211_FTYPE_DATA:
if ((fc & IEEE80211_FCTL_FROMDS) && (fc & IEEE80211_FCTL_TODS))
hdrlen = IEEE80211_4ADDR_LEN;
+ if (stype & IEEE80211_STYPE_QOS_DATA)
+ hdrlen += 2;
break;
case IEEE80211_FTYPE_CTL:
switch (WLAN_FC_GET_STYPE(fc)) {
@@ -808,7 +1030,48 @@ extern inline int ieee80211_get_hdrlen(u16 fc)
return hdrlen;
}
+static inline u8 *ieee80211_get_payload(struct ieee80211_hdr *hdr)
+{
+ switch (ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl))) {
+ case IEEE80211_1ADDR_LEN:
+ return ((struct ieee80211_hdr_1addr *)hdr)->payload;
+ case IEEE80211_2ADDR_LEN:
+ return ((struct ieee80211_hdr_2addr *)hdr)->payload;
+ case IEEE80211_3ADDR_LEN:
+ return ((struct ieee80211_hdr_3addr *)hdr)->payload;
+ case IEEE80211_4ADDR_LEN:
+ return ((struct ieee80211_hdr_4addr *)hdr)->payload;
+ }
+
+}
+
+static inline int ieee80211_is_ofdm_rate(u8 rate)
+{
+ switch (rate & ~IEEE80211_BASIC_RATE_MASK) {
+ case IEEE80211_OFDM_RATE_6MB:
+ case IEEE80211_OFDM_RATE_9MB:
+ case IEEE80211_OFDM_RATE_12MB:
+ case IEEE80211_OFDM_RATE_18MB:
+ case IEEE80211_OFDM_RATE_24MB:
+ case IEEE80211_OFDM_RATE_36MB:
+ case IEEE80211_OFDM_RATE_48MB:
+ case IEEE80211_OFDM_RATE_54MB:
+ return 1;
+ }
+ return 0;
+}
+static inline int ieee80211_is_cck_rate(u8 rate)
+{
+ switch (rate & ~IEEE80211_BASIC_RATE_MASK) {
+ case IEEE80211_CCK_RATE_1MB:
+ case IEEE80211_CCK_RATE_2MB:
+ case IEEE80211_CCK_RATE_5MB:
+ case IEEE80211_CCK_RATE_11MB:
+ return 1;
+ }
+ return 0;
+}
/* ieee80211.c */
extern void free_ieee80211(struct net_device *dev);
@@ -817,18 +1080,30 @@ extern struct net_device *alloc_ieee80211(int sizeof_priv);
extern int ieee80211_set_encryption(struct ieee80211_device *ieee);
/* ieee80211_tx.c */
-extern int ieee80211_xmit(struct sk_buff *skb,
- struct net_device *dev);
+extern int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev);
extern void ieee80211_txb_free(struct ieee80211_txb *);
-
+extern int ieee80211_tx_frame(struct ieee80211_device *ieee,
+ struct ieee80211_hdr *frame, int len);
/* ieee80211_rx.c */
extern int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
struct ieee80211_rx_stats *rx_stats);
extern void ieee80211_rx_mgt(struct ieee80211_device *ieee,
- struct ieee80211_hdr *header,
+ struct ieee80211_hdr_4addr *header,
struct ieee80211_rx_stats *stats);
+/* ieee80211_geo.c */
+extern const struct ieee80211_geo *ieee80211_get_geo(struct ieee80211_device
+ *ieee);
+extern int ieee80211_set_geo(struct ieee80211_device *ieee,
+ const struct ieee80211_geo *geo);
+
+extern int ieee80211_is_valid_channel(struct ieee80211_device *ieee,
+ u8 channel);
+extern int ieee80211_channel_to_index(struct ieee80211_device *ieee,
+ u8 channel);
+extern u8 ieee80211_freq_to_channel(struct ieee80211_device *ieee, u32 freq);
+
/* ieee80211_wx.c */
extern int ieee80211_wx_get_scan(struct ieee80211_device *ieee,
struct iw_request_info *info,
@@ -839,17 +1114,21 @@ extern int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
extern int ieee80211_wx_get_encode(struct ieee80211_device *ieee,
struct iw_request_info *info,
union iwreq_data *wrqu, char *key);
-
-
-extern inline void ieee80211_increment_scans(struct ieee80211_device *ieee)
+extern int ieee80211_wx_set_encodeext(struct ieee80211_device *ieee,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra);
+extern int ieee80211_wx_get_encodeext(struct ieee80211_device *ieee,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra);
+
+static inline void ieee80211_increment_scans(struct ieee80211_device *ieee)
{
ieee->scans++;
}
-extern inline int ieee80211_get_scans(struct ieee80211_device *ieee)
+static inline int ieee80211_get_scans(struct ieee80211_device *ieee)
{
return ieee->scans;
}
-
-#endif /* IEEE80211_H */
+#endif /* IEEE80211_H */
diff --git a/include/net/ieee80211_crypt.h b/include/net/ieee80211_crypt.h
index b58a3bcc0dc0..225fc751d464 100644
--- a/include/net/ieee80211_crypt.h
+++ b/include/net/ieee80211_crypt.h
@@ -25,16 +25,23 @@
#include <linux/skbuff.h>
+enum {
+ IEEE80211_CRYPTO_TKIP_COUNTERMEASURES = (1 << 0),
+};
+
struct ieee80211_crypto_ops {
const char *name;
+ struct list_head list;
/* init new crypto context (e.g., allocate private data space,
* select IV, etc.); returns NULL on failure or pointer to allocated
* private data on success */
- void * (*init)(int keyidx);
+ void *(*init) (int keyidx);
/* deinitialize crypto context and free allocated private data */
- void (*deinit)(void *priv);
+ void (*deinit) (void *priv);
+
+ int (*build_iv) (struct sk_buff * skb, int hdr_len, void *priv);
/* encrypt/decrypt return < 0 on error or >= 0 on success. The return
* value from decrypt_mpdu is passed as the keyidx value for
@@ -42,34 +49,39 @@ struct ieee80211_crypto_ops {
* encryption; if not, error will be returned; these functions are
* called for all MPDUs (i.e., fragments).
*/
- int (*encrypt_mpdu)(struct sk_buff *skb, int hdr_len, void *priv);
- int (*decrypt_mpdu)(struct sk_buff *skb, int hdr_len, void *priv);
+ int (*encrypt_mpdu) (struct sk_buff * skb, int hdr_len, void *priv);
+ int (*decrypt_mpdu) (struct sk_buff * skb, int hdr_len, void *priv);
/* These functions are called for full MSDUs, i.e. full frames.
* These can be NULL if full MSDU operations are not needed. */
- int (*encrypt_msdu)(struct sk_buff *skb, int hdr_len, void *priv);
- int (*decrypt_msdu)(struct sk_buff *skb, int keyidx, int hdr_len,
- void *priv);
+ int (*encrypt_msdu) (struct sk_buff * skb, int hdr_len, void *priv);
+ int (*decrypt_msdu) (struct sk_buff * skb, int keyidx, int hdr_len,
+ void *priv);
- int (*set_key)(void *key, int len, u8 *seq, void *priv);
- int (*get_key)(void *key, int len, u8 *seq, void *priv);
+ int (*set_key) (void *key, int len, u8 * seq, void *priv);
+ int (*get_key) (void *key, int len, u8 * seq, void *priv);
/* procfs handler for printing out key information and possible
* statistics */
- char * (*print_stats)(char *p, void *priv);
+ char *(*print_stats) (char *p, void *priv);
+
+ /* Crypto specific flag get/set for configuration settings */
+ unsigned long (*get_flags) (void *priv);
+ unsigned long (*set_flags) (unsigned long flags, void *priv);
/* maximum number of bytes added by encryption; encrypt buf is
* allocated with extra_prefix_len bytes, copy of in_buf, and
* extra_postfix_len; encrypt need not use all this space, but
* the result must start at the beginning of the buffer and correct
* length must be returned */
- int extra_prefix_len, extra_postfix_len;
+ int extra_mpdu_prefix_len, extra_mpdu_postfix_len;
+ int extra_msdu_prefix_len, extra_msdu_postfix_len;
struct module *owner;
};
struct ieee80211_crypt_data {
- struct list_head list; /* delayed deletion list */
+ struct list_head list; /* delayed deletion list */
struct ieee80211_crypto_ops *ops;
void *priv;
atomic_t refcnt;
@@ -77,10 +89,11 @@ struct ieee80211_crypt_data {
int ieee80211_register_crypto_ops(struct ieee80211_crypto_ops *ops);
int ieee80211_unregister_crypto_ops(struct ieee80211_crypto_ops *ops);
-struct ieee80211_crypto_ops * ieee80211_get_crypto_ops(const char *name);
+struct ieee80211_crypto_ops *ieee80211_get_crypto_ops(const char *name);
void ieee80211_crypt_deinit_entries(struct ieee80211_device *, int);
void ieee80211_crypt_deinit_handler(unsigned long);
void ieee80211_crypt_delayed_deinit(struct ieee80211_device *ieee,
struct ieee80211_crypt_data **crypt);
+void ieee80211_crypt_quiescing(struct ieee80211_device *ieee);
#endif
diff --git a/include/net/ieee80211_radiotap.h b/include/net/ieee80211_radiotap.h
new file mode 100644
index 000000000000..429b73892a5f
--- /dev/null
+++ b/include/net/ieee80211_radiotap.h
@@ -0,0 +1,231 @@
+/* $FreeBSD: src/sys/net80211/ieee80211_radiotap.h,v 1.5 2005/01/22 20:12:05 sam Exp $ */
+/* $NetBSD: ieee80211_radiotap.h,v 1.11 2005/06/22 06:16:02 dyoung Exp $ */
+
+/*-
+ * Copyright (c) 2003, 2004 David Young. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of David Young may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY DAVID YOUNG ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DAVID
+ * YOUNG BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ */
+
+/*
+ * Modifications to fit into the linux IEEE 802.11 stack,
+ * Mike Kershaw (dragorn@kismetwireless.net)
+ */
+
+#ifndef IEEE80211RADIOTAP_H
+#define IEEE80211RADIOTAP_H
+
+#include <linux/if_ether.h>
+#include <linux/kernel.h>
+
+/* Radiotap header version (from official NetBSD feed) */
+#define IEEE80211RADIOTAP_VERSION "1.5"
+/* Base version of the radiotap packet header data */
+#define PKTHDR_RADIOTAP_VERSION 0
+
+/* A generic radio capture format is desirable. There is one for
+ * Linux, but it is neither rigidly defined (there were not even
+ * units given for some fields) nor easily extensible.
+ *
+ * I suggest the following extensible radio capture format. It is
+ * based on a bitmap indicating which fields are present.
+ *
+ * I am trying to describe precisely what the application programmer
+ * should expect in the following, and for that reason I tell the
+ * units and origin of each measurement (where it applies), or else I
+ * use sufficiently weaselly language ("is a monotonically nondecreasing
+ * function of...") that I cannot set false expectations for lawyerly
+ * readers.
+ */
+
+/* XXX tcpdump/libpcap do not tolerate variable-length headers,
+ * yet, so we pad every radiotap header to 64 bytes. Ugh.
+ */
+#define IEEE80211_RADIOTAP_HDRLEN 64
+
+/* The radio capture header precedes the 802.11 header. */
+struct ieee80211_radiotap_header {
+ u8 it_version; /* Version 0. Only increases
+ * for drastic changes,
+ * introduction of compatible
+ * new fields does not count.
+ */
+ u8 it_pad;
+ u16 it_len; /* length of the whole
+ * header in bytes, including
+ * it_version, it_pad,
+ * it_len, and data fields.
+ */
+ u32 it_present; /* A bitmap telling which
+ * fields are present. Set bit 31
+ * (0x80000000) to extend the
+ * bitmap by another 32 bits.
+ * Additional extensions are made
+ * by setting bit 31.
+ */
+};
+
+/* Name Data type Units
+ * ---- --------- -----
+ *
+ * IEEE80211_RADIOTAP_TSFT u64 microseconds
+ *
+ * Value in microseconds of the MAC's 64-bit 802.11 Time
+ * Synchronization Function timer when the first bit of the
+ * MPDU arrived at the MAC. For received frames, only.
+ *
+ * IEEE80211_RADIOTAP_CHANNEL 2 x u16 MHz, bitmap
+ *
+ * Tx/Rx frequency in MHz, followed by flags (see below).
+ *
+ * IEEE80211_RADIOTAP_FHSS u16 see below
+ *
+ * For frequency-hopping radios, the hop set (first byte)
+ * and pattern (second byte).
+ *
+ * IEEE80211_RADIOTAP_RATE u8 500kb/s
+ *
+ * Tx/Rx data rate
+ *
+ * IEEE80211_RADIOTAP_DBM_ANTSIGNAL int8_t decibels from
+ * one milliwatt (dBm)
+ *
+ * RF signal power at the antenna, decibel difference from
+ * one milliwatt.
+ *
+ * IEEE80211_RADIOTAP_DBM_ANTNOISE int8_t decibels from
+ * one milliwatt (dBm)
+ *
+ * RF noise power at the antenna, decibel difference from one
+ * milliwatt.
+ *
+ * IEEE80211_RADIOTAP_DB_ANTSIGNAL u8 decibel (dB)
+ *
+ * RF signal power at the antenna, decibel difference from an
+ * arbitrary, fixed reference.
+ *
+ * IEEE80211_RADIOTAP_DB_ANTNOISE u8 decibel (dB)
+ *
+ * RF noise power at the antenna, decibel difference from an
+ * arbitrary, fixed reference point.
+ *
+ * IEEE80211_RADIOTAP_LOCK_QUALITY u16 unitless
+ *
+ * Quality of Barker code lock. Unitless. Monotonically
+ * nondecreasing with "better" lock strength. Called "Signal
+ * Quality" in datasheets. (Is there a standard way to measure
+ * this?)
+ *
+ * IEEE80211_RADIOTAP_TX_ATTENUATION u16 unitless
+ *
+ * Transmit power expressed as unitless distance from max
+ * power set at factory calibration. 0 is max power.
+ * Monotonically nondecreasing with lower power levels.
+ *
+ * IEEE80211_RADIOTAP_DB_TX_ATTENUATION u16 decibels (dB)
+ *
+ * Transmit power expressed as decibel distance from max power
+ * set at factory calibration. 0 is max power. Monotonically
+ * nondecreasing with lower power levels.
+ *
+ * IEEE80211_RADIOTAP_DBM_TX_POWER int8_t decibels from
+ * one milliwatt (dBm)
+ *
+ * Transmit power expressed as dBm (decibels from a 1 milliwatt
+ * reference). This is the absolute power level measured at
+ * the antenna port.
+ *
+ * IEEE80211_RADIOTAP_FLAGS u8 bitmap
+ *
+ * Properties of transmitted and received frames. See flags
+ * defined below.
+ *
+ * IEEE80211_RADIOTAP_ANTENNA u8 antenna index
+ *
+ * Unitless indication of the Rx/Tx antenna for this packet.
+ * The first antenna is antenna 0.
+ *
+ * IEEE80211_RADIOTAP_FCS u32 data
+ *
+ * FCS from frame in network byte order.
+ */
+enum ieee80211_radiotap_type {
+ IEEE80211_RADIOTAP_TSFT = 0,
+ IEEE80211_RADIOTAP_FLAGS = 1,
+ IEEE80211_RADIOTAP_RATE = 2,
+ IEEE80211_RADIOTAP_CHANNEL = 3,
+ IEEE80211_RADIOTAP_FHSS = 4,
+ IEEE80211_RADIOTAP_DBM_ANTSIGNAL = 5,
+ IEEE80211_RADIOTAP_DBM_ANTNOISE = 6,
+ IEEE80211_RADIOTAP_LOCK_QUALITY = 7,
+ IEEE80211_RADIOTAP_TX_ATTENUATION = 8,
+ IEEE80211_RADIOTAP_DB_TX_ATTENUATION = 9,
+ IEEE80211_RADIOTAP_DBM_TX_POWER = 10,
+ IEEE80211_RADIOTAP_ANTENNA = 11,
+ IEEE80211_RADIOTAP_DB_ANTSIGNAL = 12,
+ IEEE80211_RADIOTAP_DB_ANTNOISE = 13,
+ IEEE80211_RADIOTAP_EXT = 31,
+};
+
+/* Channel flags. */
+#define IEEE80211_CHAN_TURBO 0x0010 /* Turbo channel */
+#define IEEE80211_CHAN_CCK 0x0020 /* CCK channel */
+#define IEEE80211_CHAN_OFDM 0x0040 /* OFDM channel */
+#define IEEE80211_CHAN_2GHZ 0x0080 /* 2 GHz spectrum channel. */
+#define IEEE80211_CHAN_5GHZ 0x0100 /* 5 GHz spectrum channel */
+#define IEEE80211_CHAN_PASSIVE 0x0200 /* Only passive scan allowed */
+#define IEEE80211_CHAN_DYN 0x0400 /* Dynamic CCK-OFDM channel */
+#define IEEE80211_CHAN_GFSK 0x0800 /* GFSK channel (FHSS PHY) */
+
+/* For IEEE80211_RADIOTAP_FLAGS */
+#define IEEE80211_RADIOTAP_F_CFP 0x01 /* sent/received
+ * during CFP
+ */
+#define IEEE80211_RADIOTAP_F_SHORTPRE 0x02 /* sent/received
+ * with short
+ * preamble
+ */
+#define IEEE80211_RADIOTAP_F_WEP 0x04 /* sent/received
+ * with WEP encryption
+ */
+#define IEEE80211_RADIOTAP_F_FRAG 0x08 /* sent/received
+ * with fragmentation
+ */
+#define IEEE80211_RADIOTAP_F_FCS 0x10 /* frame includes FCS */
+#define IEEE80211_RADIOTAP_F_DATAPAD 0x20 /* frame has padding between
+ * 802.11 header and payload
+ * (to 32-bit boundary)
+ */
+
+/* Ugly macro to convert literal channel numbers into their mhz equivalents
+ * There are certianly some conditions that will break this (like feeding it '30')
+ * but they shouldn't arise since nothing talks on channel 30. */
+#define ieee80211chan2mhz(x) \
+ (((x) <= 14) ? \
+ (((x) == 14) ? 2484 : ((x) * 5) + 2407) : \
+ ((x) + 1000) * 5)
+
+#endif /* IEEE80211_RADIOTAP_H */
diff --git a/include/net/inet_ecn.h b/include/net/inet_ecn.h
index f87845e2e965..b0c47e2eccf1 100644
--- a/include/net/inet_ecn.h
+++ b/include/net/inet_ecn.h
@@ -2,6 +2,7 @@
#define _INET_ECN_H_
#include <linux/ip.h>
+#include <linux/skbuff.h>
#include <net/dsfield.h>
enum {
@@ -48,7 +49,7 @@ static inline __u8 INET_ECN_encapsulate(__u8 outer, __u8 inner)
(label) |= __constant_htons(INET_ECN_ECT_0 << 4); \
} while (0)
-static inline void IP_ECN_set_ce(struct iphdr *iph)
+static inline int IP_ECN_set_ce(struct iphdr *iph)
{
u32 check = iph->check;
u32 ecn = (iph->tos + 1) & INET_ECN_MASK;
@@ -61,7 +62,7 @@ static inline void IP_ECN_set_ce(struct iphdr *iph)
* INET_ECN_CE => 00
*/
if (!(ecn & 2))
- return;
+ return !ecn;
/*
* The following gives us:
@@ -72,6 +73,7 @@ static inline void IP_ECN_set_ce(struct iphdr *iph)
iph->check = check + (check>=0xFFFF);
iph->tos |= INET_ECN_CE;
+ return 1;
}
static inline void IP_ECN_clear(struct iphdr *iph)
@@ -87,11 +89,12 @@ static inline void ipv4_copy_dscp(struct iphdr *outer, struct iphdr *inner)
struct ipv6hdr;
-static inline void IP6_ECN_set_ce(struct ipv6hdr *iph)
+static inline int IP6_ECN_set_ce(struct ipv6hdr *iph)
{
if (INET_ECN_is_not_ect(ipv6_get_dsfield(iph)))
- return;
+ return 0;
*(u32*)iph |= htonl(INET_ECN_CE << 20);
+ return 1;
}
static inline void IP6_ECN_clear(struct ipv6hdr *iph)
@@ -105,4 +108,21 @@ static inline void ipv6_copy_dscp(struct ipv6hdr *outer, struct ipv6hdr *inner)
ipv6_change_dsfield(inner, INET_ECN_MASK, dscp);
}
+static inline int INET_ECN_set_ce(struct sk_buff *skb)
+{
+ switch (skb->protocol) {
+ case __constant_htons(ETH_P_IP):
+ if (skb->nh.raw + sizeof(struct iphdr) <= skb->tail)
+ return IP_ECN_set_ce(skb->nh.iph);
+ break;
+
+ case __constant_htons(ETH_P_IPV6):
+ if (skb->nh.raw + sizeof(struct ipv6hdr) <= skb->tail)
+ return IP6_ECN_set_ce(skb->nh.ipv6h);
+ break;
+ }
+
+ return 0;
+}
+
#endif
diff --git a/include/net/inet_hashtables.h b/include/net/inet_hashtables.h
index f50f95968340..07840baa9341 100644
--- a/include/net/inet_hashtables.h
+++ b/include/net/inet_hashtables.h
@@ -125,9 +125,7 @@ struct inet_hashinfo {
rwlock_t lhash_lock ____cacheline_aligned;
atomic_t lhash_users;
wait_queue_head_t lhash_wait;
- spinlock_t portalloc_lock;
kmem_cache_t *bind_bucket_cachep;
- int port_rover;
};
static inline unsigned int inet_ehashfn(const __u32 laddr, const __u16 lport,
diff --git a/include/net/ipv6.h b/include/net/ipv6.h
index 65ec86678a08..6addb4d464d6 100644
--- a/include/net/ipv6.h
+++ b/include/net/ipv6.h
@@ -252,12 +252,25 @@ typedef int (*inet_getfrag_t) (const void *data,
char *,
unsigned int, unsigned int);
-
-extern int ipv6_addr_type(const struct in6_addr *addr);
+extern int __ipv6_addr_type(const struct in6_addr *addr);
+static inline int ipv6_addr_type(const struct in6_addr *addr)
+{
+ return __ipv6_addr_type(addr) & 0xffff;
+}
static inline int ipv6_addr_scope(const struct in6_addr *addr)
{
- return ipv6_addr_type(addr) & IPV6_ADDR_SCOPE_MASK;
+ return __ipv6_addr_type(addr) & IPV6_ADDR_SCOPE_MASK;
+}
+
+static inline int __ipv6_addr_src_scope(int type)
+{
+ return (type == IPV6_ADDR_ANY ? __IPV6_ADDR_SCOPE_INVALID : (type >> 16));
+}
+
+static inline int ipv6_addr_src_scope(const struct in6_addr *addr)
+{
+ return __ipv6_addr_src_scope(__ipv6_addr_type(addr));
}
static inline int ipv6_addr_cmp(const struct in6_addr *a1, const struct in6_addr *a2)
@@ -341,6 +354,54 @@ static inline int ipv6_addr_any(const struct in6_addr *a)
}
/*
+ * find the first different bit between two addresses
+ * length of address must be a multiple of 32bits
+ */
+static inline int __ipv6_addr_diff(const void *token1, const void *token2, int addrlen)
+{
+ const __u32 *a1 = token1, *a2 = token2;
+ int i;
+
+ addrlen >>= 2;
+
+ for (i = 0; i < addrlen; i++) {
+ __u32 xb = a1[i] ^ a2[i];
+ if (xb) {
+ int j = 31;
+
+ xb = ntohl(xb);
+ while ((xb & (1 << j)) == 0)
+ j--;
+
+ return (i * 32 + 31 - j);
+ }
+ }
+
+ /*
+ * we should *never* get to this point since that
+ * would mean the addrs are equal
+ *
+ * However, we do get to it 8) And exacly, when
+ * addresses are equal 8)
+ *
+ * ip route add 1111::/128 via ...
+ * ip route add 1111::/64 via ...
+ * and we are here.
+ *
+ * Ideally, this function should stop comparison
+ * at prefix length. It does not, but it is still OK,
+ * if returned value is greater than prefix length.
+ * --ANK (980803)
+ */
+ return (addrlen << 5);
+}
+
+static inline int ipv6_addr_diff(const struct in6_addr *a1, const struct in6_addr *a2)
+{
+ return __ipv6_addr_diff(a1, a2, sizeof(struct in6_addr));
+}
+
+/*
* Prototypes exported by ipv6
*/
diff --git a/include/net/netfilter/ipv4/nf_conntrack_icmp.h b/include/net/netfilter/ipv4/nf_conntrack_icmp.h
new file mode 100644
index 000000000000..3dd22cff23ec
--- /dev/null
+++ b/include/net/netfilter/ipv4/nf_conntrack_icmp.h
@@ -0,0 +1,11 @@
+#ifndef _NF_CONNTRACK_ICMP_H
+#define _NF_CONNTRACK_ICMP_H
+/* ICMP tracking. */
+#include <asm/atomic.h>
+
+struct ip_ct_icmp
+{
+ /* Optimization: when number in == number out, forget immediately. */
+ atomic_t count;
+};
+#endif /* _NF_CONNTRACK_ICMP_H */
diff --git a/include/net/netfilter/ipv4/nf_conntrack_ipv4.h b/include/net/netfilter/ipv4/nf_conntrack_ipv4.h
new file mode 100644
index 000000000000..25b081a730e6
--- /dev/null
+++ b/include/net/netfilter/ipv4/nf_conntrack_ipv4.h
@@ -0,0 +1,43 @@
+/*
+ * IPv4 support for nf_conntrack.
+ *
+ * 23 Mar 2004: Yasuyuki Kozakai @ USAGI <yasuyuki.kozakai@toshiba.co.jp>
+ * - move L3 protocol dependent part from include/linux/netfilter_ipv4/
+ * ip_conntarck.h
+ */
+
+#ifndef _NF_CONNTRACK_IPV4_H
+#define _NF_CONNTRACK_IPV4_H
+
+#ifdef CONFIG_IP_NF_NAT_NEEDED
+#include <linux/netfilter_ipv4/ip_nat.h>
+
+/* per conntrack: nat application helper private data */
+union ip_conntrack_nat_help {
+ /* insert nat helper private data here */
+};
+
+struct nf_conntrack_ipv4_nat {
+ struct ip_nat_info info;
+ union ip_conntrack_nat_help help;
+#if defined(CONFIG_IP_NF_TARGET_MASQUERADE) || \
+ defined(CONFIG_IP_NF_TARGET_MASQUERADE_MODULE)
+ int masq_index;
+#endif
+};
+#endif /* CONFIG_IP_NF_NAT_NEEDED */
+
+struct nf_conntrack_ipv4 {
+#ifdef CONFIG_IP_NF_NAT_NEEDED
+ struct nf_conntrack_ipv4_nat *nat;
+#endif
+};
+
+/* Returns new sk_buff, or NULL */
+struct sk_buff *
+nf_ct_ipv4_ct_gather_frags(struct sk_buff *skb);
+
+/* call to create an explicit dependency on nf_conntrack_l3proto_ipv4. */
+extern void need_ip_conntrack(void);
+
+#endif /*_NF_CONNTRACK_IPV4_H*/
diff --git a/include/net/netfilter/ipv6/nf_conntrack_icmpv6.h b/include/net/netfilter/ipv6/nf_conntrack_icmpv6.h
new file mode 100644
index 000000000000..86591afda29c
--- /dev/null
+++ b/include/net/netfilter/ipv6/nf_conntrack_icmpv6.h
@@ -0,0 +1,27 @@
+/*
+ * ICMPv6 tracking.
+ *
+ * 21 Apl 2004: Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp>
+ * - separated from nf_conntrack_icmp.h
+ *
+ * Derived from include/linux/netfiter_ipv4/ip_conntrack_icmp.h
+ */
+
+#ifndef _NF_CONNTRACK_ICMPV6_H
+#define _NF_CONNTRACK_ICMPV6_H
+#include <asm/atomic.h>
+
+#ifndef ICMPV6_NI_QUERY
+#define ICMPV6_NI_QUERY 139
+#endif
+#ifndef ICMPV6_NI_REPLY
+#define ICMPV6_NI_REPLY 140
+#endif
+
+struct nf_ct_icmpv6
+{
+ /* Optimization: when number in == number out, forget immediately. */
+ atomic_t count;
+};
+
+#endif /* _NF_CONNTRACK_ICMPV6_H */
diff --git a/include/net/netfilter/nf_conntrack.h b/include/net/netfilter/nf_conntrack.h
new file mode 100644
index 000000000000..cc4825610795
--- /dev/null
+++ b/include/net/netfilter/nf_conntrack.h
@@ -0,0 +1,354 @@
+/*
+ * Connection state tracking for netfilter. This is separated from,
+ * but required by, the (future) NAT layer; it can also be used by an iptables
+ * extension.
+ *
+ * 16 Dec 2003: Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp>
+ * - generalize L3 protocol dependent part.
+ *
+ * Derived from include/linux/netfiter_ipv4/ip_conntrack.h
+ */
+
+#ifndef _NF_CONNTRACK_H
+#define _NF_CONNTRACK_H
+
+#include <linux/netfilter/nf_conntrack_common.h>
+
+#ifdef __KERNEL__
+#include <linux/config.h>
+#include <linux/bitops.h>
+#include <linux/compiler.h>
+#include <asm/atomic.h>
+
+#include <linux/netfilter/nf_conntrack_tcp.h>
+#include <linux/netfilter/nf_conntrack_sctp.h>
+#include <net/netfilter/ipv4/nf_conntrack_icmp.h>
+#include <net/netfilter/ipv6/nf_conntrack_icmpv6.h>
+
+#include <net/netfilter/nf_conntrack_tuple.h>
+
+/* per conntrack: protocol private data */
+union nf_conntrack_proto {
+ /* insert conntrack proto private data here */
+ struct ip_ct_sctp sctp;
+ struct ip_ct_tcp tcp;
+ struct ip_ct_icmp icmp;
+ struct nf_ct_icmpv6 icmpv6;
+};
+
+union nf_conntrack_expect_proto {
+ /* insert expect proto private data here */
+};
+
+/* Add protocol helper include file here */
+#include <linux/netfilter/nf_conntrack_ftp.h>
+
+/* per conntrack: application helper private data */
+union nf_conntrack_help {
+ /* insert conntrack helper private data (master) here */
+ struct ip_ct_ftp_master ct_ftp_info;
+};
+
+#include <linux/types.h>
+#include <linux/skbuff.h>
+
+#ifdef CONFIG_NETFILTER_DEBUG
+#define NF_CT_ASSERT(x) \
+do { \
+ if (!(x)) \
+ /* Wooah! I'm tripping my conntrack in a frenzy of \
+ netplay... */ \
+ printk("NF_CT_ASSERT: %s:%i(%s)\n", \
+ __FILE__, __LINE__, __FUNCTION__); \
+} while(0)
+#else
+#define NF_CT_ASSERT(x)
+#endif
+
+struct nf_conntrack_helper;
+
+#include <net/netfilter/ipv4/nf_conntrack_ipv4.h>
+struct nf_conn
+{
+ /* Usage count in here is 1 for hash table/destruct timer, 1 per skb,
+ plus 1 for any connection(s) we are `master' for */
+ struct nf_conntrack ct_general;
+
+ /* XXX should I move this to the tail ? - Y.K */
+ /* These are my tuples; original and reply */
+ struct nf_conntrack_tuple_hash tuplehash[IP_CT_DIR_MAX];
+
+ /* Have we seen traffic both ways yet? (bitset) */
+ unsigned long status;
+
+ /* Timer function; drops refcnt when it goes off. */
+ struct timer_list timeout;
+
+#ifdef CONFIG_NF_CT_ACCT
+ /* Accounting Information (same cache line as other written members) */
+ struct ip_conntrack_counter counters[IP_CT_DIR_MAX];
+#endif
+ /* If we were expected by an expectation, this will be it */
+ struct nf_conn *master;
+
+ /* Current number of expected connections */
+ unsigned int expecting;
+
+ /* Helper. if any */
+ struct nf_conntrack_helper *helper;
+
+ /* features - nat, helper, ... used by allocating system */
+ u_int32_t features;
+
+ /* Storage reserved for other modules: */
+
+ union nf_conntrack_proto proto;
+
+#if defined(CONFIG_NF_CONNTRACK_MARK)
+ u_int32_t mark;
+#endif
+
+ /* These members are dynamically allocated. */
+
+ union nf_conntrack_help *help;
+
+ /* Layer 3 dependent members. (ex: NAT) */
+ union {
+ struct nf_conntrack_ipv4 *ipv4;
+ } l3proto;
+ void *data[0];
+};
+
+struct nf_conntrack_expect
+{
+ /* Internal linked list (global expectation list) */
+ struct list_head list;
+
+ /* We expect this tuple, with the following mask */
+ struct nf_conntrack_tuple tuple, mask;
+
+ /* Function to call after setup and insertion */
+ void (*expectfn)(struct nf_conn *new,
+ struct nf_conntrack_expect *this);
+
+ /* The conntrack of the master connection */
+ struct nf_conn *master;
+
+ /* Timer function; deletes the expectation. */
+ struct timer_list timeout;
+
+ /* Usage count. */
+ atomic_t use;
+
+ /* Flags */
+ unsigned int flags;
+
+#ifdef CONFIG_NF_NAT_NEEDED
+ /* This is the original per-proto part, used to map the
+ * expected connection the way the recipient expects. */
+ union nf_conntrack_manip_proto saved_proto;
+ /* Direction relative to the master connection. */
+ enum ip_conntrack_dir dir;
+#endif
+};
+
+#define NF_CT_EXPECT_PERMANENT 0x1
+
+static inline struct nf_conn *
+nf_ct_tuplehash_to_ctrack(const struct nf_conntrack_tuple_hash *hash)
+{
+ return container_of(hash, struct nf_conn,
+ tuplehash[hash->tuple.dst.dir]);
+}
+
+/* get master conntrack via master expectation */
+#define master_ct(conntr) (conntr->master)
+
+/* Alter reply tuple (maybe alter helper). */
+extern void
+nf_conntrack_alter_reply(struct nf_conn *conntrack,
+ const struct nf_conntrack_tuple *newreply);
+
+/* Is this tuple taken? (ignoring any belonging to the given
+ conntrack). */
+extern int
+nf_conntrack_tuple_taken(const struct nf_conntrack_tuple *tuple,
+ const struct nf_conn *ignored_conntrack);
+
+/* Return conntrack_info and tuple hash for given skb. */
+static inline struct nf_conn *
+nf_ct_get(const struct sk_buff *skb, enum ip_conntrack_info *ctinfo)
+{
+ *ctinfo = skb->nfctinfo;
+ return (struct nf_conn *)skb->nfct;
+}
+
+/* decrement reference count on a conntrack */
+static inline void nf_ct_put(struct nf_conn *ct)
+{
+ NF_CT_ASSERT(ct);
+ nf_conntrack_put(&ct->ct_general);
+}
+
+/* call to create an explicit dependency on nf_conntrack. */
+extern void need_nf_conntrack(void);
+
+extern int nf_ct_invert_tuplepr(struct nf_conntrack_tuple *inverse,
+ const struct nf_conntrack_tuple *orig);
+
+extern void __nf_ct_refresh_acct(struct nf_conn *ct,
+ enum ip_conntrack_info ctinfo,
+ const struct sk_buff *skb,
+ unsigned long extra_jiffies,
+ int do_acct);
+
+/* Refresh conntrack for this many jiffies and do accounting */
+static inline void nf_ct_refresh_acct(struct nf_conn *ct,
+ enum ip_conntrack_info ctinfo,
+ const struct sk_buff *skb,
+ unsigned long extra_jiffies)
+{
+ __nf_ct_refresh_acct(ct, ctinfo, skb, extra_jiffies, 1);
+}
+
+/* Refresh conntrack for this many jiffies */
+static inline void nf_ct_refresh(struct nf_conn *ct,
+ const struct sk_buff *skb,
+ unsigned long extra_jiffies)
+{
+ __nf_ct_refresh_acct(ct, 0, skb, extra_jiffies, 0);
+}
+
+/* These are for NAT. Icky. */
+/* Update TCP window tracking data when NAT mangles the packet */
+extern void nf_conntrack_tcp_update(struct sk_buff *skb,
+ unsigned int dataoff,
+ struct nf_conn *conntrack,
+ int dir);
+
+/* Call me when a conntrack is destroyed. */
+extern void (*nf_conntrack_destroyed)(struct nf_conn *conntrack);
+
+/* Fake conntrack entry for untracked connections */
+extern struct nf_conn nf_conntrack_untracked;
+
+extern int nf_ct_no_defrag;
+
+/* Iterate over all conntracks: if iter returns true, it's deleted. */
+extern void
+nf_ct_iterate_cleanup(int (*iter)(struct nf_conn *i, void *data), void *data);
+extern void nf_conntrack_free(struct nf_conn *ct);
+extern struct nf_conn *
+nf_conntrack_alloc(const struct nf_conntrack_tuple *orig,
+ const struct nf_conntrack_tuple *repl);
+
+/* It's confirmed if it is, or has been in the hash table. */
+static inline int nf_ct_is_confirmed(struct nf_conn *ct)
+{
+ return test_bit(IPS_CONFIRMED_BIT, &ct->status);
+}
+
+static inline int nf_ct_is_dying(struct nf_conn *ct)
+{
+ return test_bit(IPS_DYING_BIT, &ct->status);
+}
+
+extern unsigned int nf_conntrack_htable_size;
+
+#define NF_CT_STAT_INC(count) (__get_cpu_var(nf_conntrack_stat).count++)
+
+#ifdef CONFIG_NF_CONNTRACK_EVENTS
+#include <linux/notifier.h>
+#include <linux/interrupt.h>
+
+struct nf_conntrack_ecache {
+ struct nf_conn *ct;
+ unsigned int events;
+};
+DECLARE_PER_CPU(struct nf_conntrack_ecache, nf_conntrack_ecache);
+
+#define CONNTRACK_ECACHE(x) (__get_cpu_var(nf_conntrack_ecache).x)
+
+extern struct notifier_block *nf_conntrack_chain;
+extern struct notifier_block *nf_conntrack_expect_chain;
+
+static inline int nf_conntrack_register_notifier(struct notifier_block *nb)
+{
+ return notifier_chain_register(&nf_conntrack_chain, nb);
+}
+
+static inline int nf_conntrack_unregister_notifier(struct notifier_block *nb)
+{
+ return notifier_chain_unregister(&nf_conntrack_chain, nb);
+}
+
+static inline int
+nf_conntrack_expect_register_notifier(struct notifier_block *nb)
+{
+ return notifier_chain_register(&nf_conntrack_expect_chain, nb);
+}
+
+static inline int
+nf_conntrack_expect_unregister_notifier(struct notifier_block *nb)
+{
+ return notifier_chain_unregister(&nf_conntrack_expect_chain, nb);
+}
+
+extern void nf_ct_deliver_cached_events(const struct nf_conn *ct);
+extern void __nf_ct_event_cache_init(struct nf_conn *ct);
+
+static inline void
+nf_conntrack_event_cache(enum ip_conntrack_events event,
+ const struct sk_buff *skb)
+{
+ struct nf_conn *ct = (struct nf_conn *)skb->nfct;
+ struct nf_conntrack_ecache *ecache;
+
+ local_bh_disable();
+ ecache = &__get_cpu_var(nf_conntrack_ecache);
+ if (ct != ecache->ct)
+ __nf_ct_event_cache_init(ct);
+ ecache->events |= event;
+ local_bh_enable();
+}
+
+static inline void nf_conntrack_event(enum ip_conntrack_events event,
+ struct nf_conn *ct)
+{
+ if (nf_ct_is_confirmed(ct) && !nf_ct_is_dying(ct))
+ notifier_call_chain(&nf_conntrack_chain, event, ct);
+}
+
+static inline void
+nf_conntrack_expect_event(enum ip_conntrack_expect_events event,
+ struct nf_conntrack_expect *exp)
+{
+ notifier_call_chain(&nf_conntrack_expect_chain, event, exp);
+}
+#else /* CONFIG_NF_CONNTRACK_EVENTS */
+static inline void nf_conntrack_event_cache(enum ip_conntrack_events event,
+ const struct sk_buff *skb) {}
+static inline void nf_conntrack_event(enum ip_conntrack_events event,
+ struct nf_conn *ct) {}
+static inline void nf_ct_deliver_cached_events(const struct nf_conn *ct) {}
+static inline void
+nf_conntrack_expect_event(enum ip_conntrack_expect_events event,
+ struct nf_conntrack_expect *exp) {}
+#endif /* CONFIG_NF_CONNTRACK_EVENTS */
+
+/* no helper, no nat */
+#define NF_CT_F_BASIC 0
+/* for helper */
+#define NF_CT_F_HELP 1
+/* for nat. */
+#define NF_CT_F_NAT 2
+#define NF_CT_F_NUM 4
+
+extern int
+nf_conntrack_register_cache(u_int32_t features, const char *name, size_t size,
+ int (*init_conntrack)(struct nf_conn *, u_int32_t));
+extern void
+nf_conntrack_unregister_cache(u_int32_t features);
+
+#endif /* __KERNEL__ */
+#endif /* _NF_CONNTRACK_H */
diff --git a/include/net/netfilter/nf_conntrack_compat.h b/include/net/netfilter/nf_conntrack_compat.h
new file mode 100644
index 000000000000..3cac19fb3648
--- /dev/null
+++ b/include/net/netfilter/nf_conntrack_compat.h
@@ -0,0 +1,108 @@
+#ifndef _NF_CONNTRACK_COMPAT_H
+#define _NF_CONNTRACK_COMPAT_H
+
+#ifdef __KERNEL__
+
+#if defined(CONFIG_IP_NF_CONNTRACK) || defined(CONFIG_IP_NF_CONNTRACK_MODULE)
+
+#include <linux/netfilter_ipv4/ip_conntrack.h>
+
+#ifdef CONFIG_IP_NF_CONNTRACK_MARK
+static inline u_int32_t *nf_ct_get_mark(const struct sk_buff *skb,
+ u_int32_t *ctinfo)
+{
+ struct ip_conntrack *ct = ip_conntrack_get(skb, ctinfo);
+
+ if (ct)
+ return &ct->mark;
+ else
+ return NULL;
+}
+#endif /* CONFIG_IP_NF_CONNTRACK_MARK */
+
+#ifdef CONFIG_IP_NF_CT_ACCT
+static inline struct ip_conntrack_counter *
+nf_ct_get_counters(const struct sk_buff *skb)
+{
+ enum ip_conntrack_info ctinfo;
+ struct ip_conntrack *ct = ip_conntrack_get(skb, &ctinfo);
+
+ if (ct)
+ return ct->counters;
+ else
+ return NULL;
+}
+#endif /* CONFIG_IP_NF_CT_ACCT */
+
+static inline int nf_ct_is_untracked(const struct sk_buff *skb)
+{
+ return (skb->nfct == &ip_conntrack_untracked.ct_general);
+}
+
+static inline void nf_ct_untrack(struct sk_buff *skb)
+{
+ skb->nfct = &ip_conntrack_untracked.ct_general;
+}
+
+static inline int nf_ct_get_ctinfo(const struct sk_buff *skb,
+ enum ip_conntrack_info *ctinfo)
+{
+ struct ip_conntrack *ct = ip_conntrack_get(skb, ctinfo);
+ return (ct != NULL);
+}
+
+#else /* CONFIG_IP_NF_CONNTRACK */
+
+#include <net/netfilter/ipv4/nf_conntrack_ipv4.h>
+#include <net/netfilter/nf_conntrack.h>
+
+#ifdef CONFIG_NF_CONNTRACK_MARK
+
+static inline u_int32_t *nf_ct_get_mark(const struct sk_buff *skb,
+ u_int32_t *ctinfo)
+{
+ struct nf_conn *ct = nf_ct_get(skb, ctinfo);
+
+ if (ct)
+ return &ct->mark;
+ else
+ return NULL;
+}
+#endif /* CONFIG_NF_CONNTRACK_MARK */
+
+#ifdef CONFIG_NF_CT_ACCT
+static inline struct ip_conntrack_counter *
+nf_ct_get_counters(const struct sk_buff *skb)
+{
+ enum ip_conntrack_info ctinfo;
+ struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
+
+ if (ct)
+ return ct->counters;
+ else
+ return NULL;
+}
+#endif /* CONFIG_NF_CT_ACCT */
+
+static inline int nf_ct_is_untracked(const struct sk_buff *skb)
+{
+ return (skb->nfct == &nf_conntrack_untracked.ct_general);
+}
+
+static inline void nf_ct_untrack(struct sk_buff *skb)
+{
+ skb->nfct = &nf_conntrack_untracked.ct_general;
+}
+
+static inline int nf_ct_get_ctinfo(const struct sk_buff *skb,
+ enum ip_conntrack_info *ctinfo)
+{
+ struct nf_conn *ct = nf_ct_get(skb, ctinfo);
+ return (ct != NULL);
+}
+
+#endif /* CONFIG_IP_NF_CONNTRACK */
+
+#endif /* __KERNEL__ */
+
+#endif /* _NF_CONNTRACK_COMPAT_H */
diff --git a/include/net/netfilter/nf_conntrack_core.h b/include/net/netfilter/nf_conntrack_core.h
new file mode 100644
index 000000000000..da254525a4ce
--- /dev/null
+++ b/include/net/netfilter/nf_conntrack_core.h
@@ -0,0 +1,76 @@
+/*
+ * This header is used to share core functionality between the
+ * standalone connection tracking module, and the compatibility layer's use
+ * of connection tracking.
+ *
+ * 16 Dec 2003: Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp>
+ * - generalize L3 protocol dependent part.
+ *
+ * Derived from include/linux/netfiter_ipv4/ip_conntrack_core.h
+ */
+
+#ifndef _NF_CONNTRACK_CORE_H
+#define _NF_CONNTRACK_CORE_H
+
+#include <linux/netfilter.h>
+
+/* This header is used to share core functionality between the
+ standalone connection tracking module, and the compatibility layer's use
+ of connection tracking. */
+extern unsigned int nf_conntrack_in(int pf,
+ unsigned int hooknum,
+ struct sk_buff **pskb);
+
+extern int nf_conntrack_init(void);
+extern void nf_conntrack_cleanup(void);
+
+struct nf_conntrack_l3proto;
+extern struct nf_conntrack_l3proto *nf_ct_find_l3proto(u_int16_t pf);
+/* Like above, but you already have conntrack read lock. */
+extern struct nf_conntrack_l3proto *__nf_ct_find_l3proto(u_int16_t l3proto);
+
+struct nf_conntrack_protocol;
+
+extern int
+nf_ct_get_tuple(const struct sk_buff *skb,
+ unsigned int nhoff,
+ unsigned int dataoff,
+ u_int16_t l3num,
+ u_int8_t protonum,
+ struct nf_conntrack_tuple *tuple,
+ const struct nf_conntrack_l3proto *l3proto,
+ const struct nf_conntrack_protocol *protocol);
+
+extern int
+nf_ct_invert_tuple(struct nf_conntrack_tuple *inverse,
+ const struct nf_conntrack_tuple *orig,
+ const struct nf_conntrack_l3proto *l3proto,
+ const struct nf_conntrack_protocol *protocol);
+
+/* Find a connection corresponding to a tuple. */
+extern struct nf_conntrack_tuple_hash *
+nf_conntrack_find_get(const struct nf_conntrack_tuple *tuple,
+ const struct nf_conn *ignored_conntrack);
+
+extern int __nf_conntrack_confirm(struct sk_buff **pskb);
+
+/* Confirm a connection: returns NF_DROP if packet must be dropped. */
+static inline int nf_conntrack_confirm(struct sk_buff **pskb)
+{
+ struct nf_conn *ct = (struct nf_conn *)(*pskb)->nfct;
+ int ret = NF_ACCEPT;
+
+ if (ct) {
+ if (!nf_ct_is_confirmed(ct))
+ ret = __nf_conntrack_confirm(pskb);
+ nf_ct_deliver_cached_events(ct);
+ }
+ return ret;
+}
+
+extern void __nf_conntrack_attach(struct sk_buff *nskb, struct sk_buff *skb);
+
+extern struct list_head *nf_conntrack_hash;
+extern struct list_head nf_conntrack_expect_list;
+extern rwlock_t nf_conntrack_lock ;
+#endif /* _NF_CONNTRACK_CORE_H */
diff --git a/include/net/netfilter/nf_conntrack_helper.h b/include/net/netfilter/nf_conntrack_helper.h
new file mode 100644
index 000000000000..5a66b2a3a623
--- /dev/null
+++ b/include/net/netfilter/nf_conntrack_helper.h
@@ -0,0 +1,51 @@
+/*
+ * connection tracking helpers.
+ *
+ * 16 Dec 2003: Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp>
+ * - generalize L3 protocol dependent part.
+ *
+ * Derived from include/linux/netfiter_ipv4/ip_conntrack_helper.h
+ */
+
+#ifndef _NF_CONNTRACK_HELPER_H
+#define _NF_CONNTRACK_HELPER_H
+#include <net/netfilter/nf_conntrack.h>
+
+struct module;
+
+struct nf_conntrack_helper
+{
+ struct list_head list; /* Internal use. */
+
+ const char *name; /* name of the module */
+ struct module *me; /* pointer to self */
+ unsigned int max_expected; /* Maximum number of concurrent
+ * expected connections */
+ unsigned int timeout; /* timeout for expecteds */
+
+ /* Mask of things we will help (compared against server response) */
+ struct nf_conntrack_tuple tuple;
+ struct nf_conntrack_tuple mask;
+
+ /* Function to call when data passes; return verdict, or -1 to
+ invalidate. */
+ int (*help)(struct sk_buff **pskb,
+ unsigned int protoff,
+ struct nf_conn *ct,
+ enum ip_conntrack_info conntrackinfo);
+};
+
+extern int nf_conntrack_helper_register(struct nf_conntrack_helper *);
+extern void nf_conntrack_helper_unregister(struct nf_conntrack_helper *);
+
+/* Allocate space for an expectation: this is mandatory before calling
+ nf_conntrack_expect_related. You will have to call put afterwards. */
+extern struct nf_conntrack_expect *
+nf_conntrack_expect_alloc(struct nf_conn *master);
+extern void nf_conntrack_expect_put(struct nf_conntrack_expect *exp);
+
+/* Add an expected connection: can have more than one per connection */
+extern int nf_conntrack_expect_related(struct nf_conntrack_expect *exp);
+extern void nf_conntrack_unexpect_related(struct nf_conntrack_expect *exp);
+
+#endif /*_NF_CONNTRACK_HELPER_H*/
diff --git a/include/net/netfilter/nf_conntrack_l3proto.h b/include/net/netfilter/nf_conntrack_l3proto.h
new file mode 100644
index 000000000000..01663e5b33df
--- /dev/null
+++ b/include/net/netfilter/nf_conntrack_l3proto.h
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C)2003,2004 USAGI/WIDE Project
+ *
+ * Header for use in defining a given L3 protocol for connection tracking.
+ *
+ * Author:
+ * Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp>
+ *
+ * Derived from include/netfilter_ipv4/ip_conntrack_protocol.h
+ */
+
+#ifndef _NF_CONNTRACK_L3PROTO_H
+#define _NF_CONNTRACK_L3PROTO_H
+#include <linux/seq_file.h>
+#include <net/netfilter/nf_conntrack.h>
+
+struct nf_conntrack_l3proto
+{
+ /* Next pointer. */
+ struct list_head list;
+
+ /* L3 Protocol Family number. ex) PF_INET */
+ u_int16_t l3proto;
+
+ /* Protocol name */
+ const char *name;
+
+ /*
+ * Try to fill in the third arg: nhoff is offset of l3 proto
+ * hdr. Return true if possible.
+ */
+ int (*pkt_to_tuple)(const struct sk_buff *skb, unsigned int nhoff,
+ struct nf_conntrack_tuple *tuple);
+
+ /*
+ * Invert the per-proto part of the tuple: ie. turn xmit into reply.
+ * Some packets can't be inverted: return 0 in that case.
+ */
+ int (*invert_tuple)(struct nf_conntrack_tuple *inverse,
+ const struct nf_conntrack_tuple *orig);
+
+ /* Print out the per-protocol part of the tuple. */
+ int (*print_tuple)(struct seq_file *s,
+ const struct nf_conntrack_tuple *);
+
+ /* Print out the private part of the conntrack. */
+ int (*print_conntrack)(struct seq_file *s, const struct nf_conn *);
+
+ /* Returns verdict for packet, or -1 for invalid. */
+ int (*packet)(struct nf_conn *conntrack,
+ const struct sk_buff *skb,
+ enum ip_conntrack_info ctinfo);
+
+ /*
+ * Called when a new connection for this protocol found;
+ * returns TRUE if it's OK. If so, packet() called next.
+ */
+ int (*new)(struct nf_conn *conntrack, const struct sk_buff *skb);
+
+ /* Called when a conntrack entry is destroyed */
+ void (*destroy)(struct nf_conn *conntrack);
+
+ /*
+ * Called before tracking.
+ * *dataoff: offset of protocol header (TCP, UDP,...) in *pskb
+ * *protonum: protocol number
+ */
+ int (*prepare)(struct sk_buff **pskb, unsigned int hooknum,
+ unsigned int *dataoff, u_int8_t *protonum);
+
+ u_int32_t (*get_features)(const struct nf_conntrack_tuple *tuple);
+
+ /* Module (if any) which this is connected to. */
+ struct module *me;
+};
+
+extern struct nf_conntrack_l3proto *nf_ct_l3protos[AF_MAX];
+
+/* Protocol registration. */
+extern int nf_conntrack_l3proto_register(struct nf_conntrack_l3proto *proto);
+extern void nf_conntrack_l3proto_unregister(struct nf_conntrack_l3proto *proto);
+
+static inline struct nf_conntrack_l3proto *
+nf_ct_find_l3proto(u_int16_t l3proto)
+{
+ return nf_ct_l3protos[l3proto];
+}
+
+/* Existing built-in protocols */
+extern struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv4;
+extern struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv6;
+extern struct nf_conntrack_l3proto nf_conntrack_generic_l3proto;
+#endif /*_NF_CONNTRACK_L3PROTO_H*/
diff --git a/include/net/netfilter/nf_conntrack_protocol.h b/include/net/netfilter/nf_conntrack_protocol.h
new file mode 100644
index 000000000000..b3afda35397a
--- /dev/null
+++ b/include/net/netfilter/nf_conntrack_protocol.h
@@ -0,0 +1,105 @@
+/*
+ * Header for use in defining a given protocol for connection tracking.
+ *
+ * 16 Dec 2003: Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp>
+ * - generalized L3 protocol dependent part.
+ *
+ * Derived from include/linux/netfiter_ipv4/ip_conntrack_protcol.h
+ */
+
+#ifndef _NF_CONNTRACK_PROTOCOL_H
+#define _NF_CONNTRACK_PROTOCOL_H
+#include <net/netfilter/nf_conntrack.h>
+
+struct seq_file;
+
+struct nf_conntrack_protocol
+{
+ /* Next pointer. */
+ struct list_head list;
+
+ /* L3 Protocol number. */
+ u_int16_t l3proto;
+
+ /* Protocol number. */
+ u_int8_t proto;
+
+ /* Protocol name */
+ const char *name;
+
+ /* Try to fill in the third arg: dataoff is offset past network protocol
+ hdr. Return true if possible. */
+ int (*pkt_to_tuple)(const struct sk_buff *skb,
+ unsigned int dataoff,
+ struct nf_conntrack_tuple *tuple);
+
+ /* Invert the per-proto part of the tuple: ie. turn xmit into reply.
+ * Some packets can't be inverted: return 0 in that case.
+ */
+ int (*invert_tuple)(struct nf_conntrack_tuple *inverse,
+ const struct nf_conntrack_tuple *orig);
+
+ /* Print out the per-protocol part of the tuple. Return like seq_* */
+ int (*print_tuple)(struct seq_file *s,
+ const struct nf_conntrack_tuple *);
+
+ /* Print out the private part of the conntrack. */
+ int (*print_conntrack)(struct seq_file *s, const struct nf_conn *);
+
+ /* Returns verdict for packet, or -1 for invalid. */
+ int (*packet)(struct nf_conn *conntrack,
+ const struct sk_buff *skb,
+ unsigned int dataoff,
+ enum ip_conntrack_info ctinfo,
+ int pf,
+ unsigned int hooknum);
+
+ /* Called when a new connection for this protocol found;
+ * returns TRUE if it's OK. If so, packet() called next. */
+ int (*new)(struct nf_conn *conntrack, const struct sk_buff *skb,
+ unsigned int dataoff);
+
+ /* Called when a conntrack entry is destroyed */
+ void (*destroy)(struct nf_conn *conntrack);
+
+ int (*error)(struct sk_buff *skb, unsigned int dataoff,
+ enum ip_conntrack_info *ctinfo,
+ int pf, unsigned int hooknum);
+
+ /* Module (if any) which this is connected to. */
+ struct module *me;
+};
+
+/* Existing built-in protocols */
+extern struct nf_conntrack_protocol nf_conntrack_protocol_tcp6;
+extern struct nf_conntrack_protocol nf_conntrack_protocol_udp4;
+extern struct nf_conntrack_protocol nf_conntrack_protocol_udp6;
+extern struct nf_conntrack_protocol nf_conntrack_generic_protocol;
+
+#define MAX_NF_CT_PROTO 256
+extern struct nf_conntrack_protocol **nf_ct_protos[PF_MAX];
+
+extern struct nf_conntrack_protocol *
+nf_ct_find_proto(u_int16_t l3proto, u_int8_t protocol);
+
+/* Protocol registration. */
+extern int nf_conntrack_protocol_register(struct nf_conntrack_protocol *proto);
+extern void nf_conntrack_protocol_unregister(struct nf_conntrack_protocol *proto);
+
+/* Log invalid packets */
+extern unsigned int nf_ct_log_invalid;
+
+#ifdef CONFIG_SYSCTL
+#ifdef DEBUG_INVALID_PACKETS
+#define LOG_INVALID(proto) \
+ (nf_ct_log_invalid == (proto) || nf_ct_log_invalid == IPPROTO_RAW)
+#else
+#define LOG_INVALID(proto) \
+ ((nf_ct_log_invalid == (proto) || nf_ct_log_invalid == IPPROTO_RAW) \
+ && net_ratelimit())
+#endif
+#else
+#define LOG_INVALID(proto) 0
+#endif /* CONFIG_SYSCTL */
+
+#endif /*_NF_CONNTRACK_PROTOCOL_H*/
diff --git a/include/net/netfilter/nf_conntrack_tuple.h b/include/net/netfilter/nf_conntrack_tuple.h
new file mode 100644
index 000000000000..14ce790e5c65
--- /dev/null
+++ b/include/net/netfilter/nf_conntrack_tuple.h
@@ -0,0 +1,190 @@
+/*
+ * Definitions and Declarations for tuple.
+ *
+ * 16 Dec 2003: Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp>
+ * - generalize L3 protocol dependent part.
+ *
+ * Derived from include/linux/netfiter_ipv4/ip_conntrack_tuple.h
+ */
+
+#ifndef _NF_CONNTRACK_TUPLE_H
+#define _NF_CONNTRACK_TUPLE_H
+
+#include <linux/netfilter/nf_conntrack_tuple_common.h>
+
+/* A `tuple' is a structure containing the information to uniquely
+ identify a connection. ie. if two packets have the same tuple, they
+ are in the same connection; if not, they are not.
+
+ We divide the structure along "manipulatable" and
+ "non-manipulatable" lines, for the benefit of the NAT code.
+*/
+
+#define NF_CT_TUPLE_L3SIZE 4
+
+/* The l3 protocol-specific manipulable parts of the tuple: always in
+ network order! */
+union nf_conntrack_man_l3proto {
+ u_int32_t all[NF_CT_TUPLE_L3SIZE];
+ u_int32_t ip;
+ u_int32_t ip6[4];
+};
+
+/* The protocol-specific manipulable parts of the tuple: always in
+ network order! */
+union nf_conntrack_man_proto
+{
+ /* Add other protocols here. */
+ u_int16_t all;
+
+ struct {
+ u_int16_t port;
+ } tcp;
+ struct {
+ u_int16_t port;
+ } udp;
+ struct {
+ u_int16_t id;
+ } icmp;
+ struct {
+ u_int16_t port;
+ } sctp;
+};
+
+/* The manipulable part of the tuple. */
+struct nf_conntrack_man
+{
+ union nf_conntrack_man_l3proto u3;
+ union nf_conntrack_man_proto u;
+ /* Layer 3 protocol */
+ u_int16_t l3num;
+};
+
+/* This contains the information to distinguish a connection. */
+struct nf_conntrack_tuple
+{
+ struct nf_conntrack_man src;
+
+ /* These are the parts of the tuple which are fixed. */
+ struct {
+ union {
+ u_int32_t all[NF_CT_TUPLE_L3SIZE];
+ u_int32_t ip;
+ u_int32_t ip6[4];
+ } u3;
+ union {
+ /* Add other protocols here. */
+ u_int16_t all;
+
+ struct {
+ u_int16_t port;
+ } tcp;
+ struct {
+ u_int16_t port;
+ } udp;
+ struct {
+ u_int8_t type, code;
+ } icmp;
+ struct {
+ u_int16_t port;
+ } sctp;
+ } u;
+
+ /* The protocol. */
+ u_int8_t protonum;
+
+ /* The direction (for tuplehash) */
+ u_int8_t dir;
+ } dst;
+};
+
+/* This is optimized opposed to a memset of the whole structure. Everything we
+ * really care about is the source/destination unions */
+#define NF_CT_TUPLE_U_BLANK(tuple) \
+ do { \
+ (tuple)->src.u.all = 0; \
+ (tuple)->dst.u.all = 0; \
+ memset(&(tuple)->src.u3, 0, sizeof((tuple)->src.u3)); \
+ memset(&(tuple)->dst.u3, 0, sizeof((tuple)->dst.u3)); \
+ } while (0)
+
+#ifdef __KERNEL__
+
+#define NF_CT_DUMP_TUPLE(tp) \
+DEBUGP("tuple %p: %u %u %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x %hu -> %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x %hu\n", \
+ (tp), (tp)->src.l3num, (tp)->dst.protonum, \
+ NIP6(*(struct in6_addr *)(tp)->src.u3.all), ntohs((tp)->src.u.all), \
+ NIP6(*(struct in6_addr *)(tp)->dst.u3.all), ntohs((tp)->dst.u.all))
+
+/* If we're the first tuple, it's the original dir. */
+#define NF_CT_DIRECTION(h) \
+ ((enum ip_conntrack_dir)(h)->tuple.dst.dir)
+
+/* Connections have two entries in the hash table: one for each way */
+struct nf_conntrack_tuple_hash
+{
+ struct list_head list;
+
+ struct nf_conntrack_tuple tuple;
+};
+
+#endif /* __KERNEL__ */
+
+static inline int nf_ct_tuple_src_equal(const struct nf_conntrack_tuple *t1,
+ const struct nf_conntrack_tuple *t2)
+{
+ return (t1->src.u3.all[0] == t2->src.u3.all[0] &&
+ t1->src.u3.all[1] == t2->src.u3.all[1] &&
+ t1->src.u3.all[2] == t2->src.u3.all[2] &&
+ t1->src.u3.all[3] == t2->src.u3.all[3] &&
+ t1->src.u.all == t2->src.u.all &&
+ t1->src.l3num == t2->src.l3num &&
+ t1->dst.protonum == t2->dst.protonum);
+}
+
+static inline int nf_ct_tuple_dst_equal(const struct nf_conntrack_tuple *t1,
+ const struct nf_conntrack_tuple *t2)
+{
+ return (t1->dst.u3.all[0] == t2->dst.u3.all[0] &&
+ t1->dst.u3.all[1] == t2->dst.u3.all[1] &&
+ t1->dst.u3.all[2] == t2->dst.u3.all[2] &&
+ t1->dst.u3.all[3] == t2->dst.u3.all[3] &&
+ t1->dst.u.all == t2->dst.u.all &&
+ t1->src.l3num == t2->src.l3num &&
+ t1->dst.protonum == t2->dst.protonum);
+}
+
+static inline int nf_ct_tuple_equal(const struct nf_conntrack_tuple *t1,
+ const struct nf_conntrack_tuple *t2)
+{
+ return nf_ct_tuple_src_equal(t1, t2) && nf_ct_tuple_dst_equal(t1, t2);
+}
+
+static inline int nf_ct_tuple_mask_cmp(const struct nf_conntrack_tuple *t,
+ const struct nf_conntrack_tuple *tuple,
+ const struct nf_conntrack_tuple *mask)
+{
+ int count = 0;
+
+ for (count = 0; count < NF_CT_TUPLE_L3SIZE; count++){
+ if ((t->src.u3.all[count] ^ tuple->src.u3.all[count]) &
+ mask->src.u3.all[count])
+ return 0;
+ }
+
+ for (count = 0; count < NF_CT_TUPLE_L3SIZE; count++){
+ if ((t->dst.u3.all[count] ^ tuple->dst.u3.all[count]) &
+ mask->dst.u3.all[count])
+ return 0;
+ }
+
+ if ((t->src.u.all ^ tuple->src.u.all) & mask->src.u.all ||
+ (t->dst.u.all ^ tuple->dst.u.all) & mask->dst.u.all ||
+ (t->src.l3num ^ tuple->src.l3num) & mask->src.l3num ||
+ (t->dst.protonum ^ tuple->dst.protonum) & mask->dst.protonum)
+ return 0;
+
+ return 1;
+}
+
+#endif /* _NF_CONNTRACK_TUPLE_H */
diff --git a/include/net/netlink.h b/include/net/netlink.h
new file mode 100644
index 000000000000..640c26a90cf1
--- /dev/null
+++ b/include/net/netlink.h
@@ -0,0 +1,883 @@
+#ifndef __NET_NETLINK_H
+#define __NET_NETLINK_H
+
+#include <linux/types.h>
+#include <linux/netlink.h>
+
+/* ========================================================================
+ * Netlink Messages and Attributes Interface (As Seen On TV)
+ * ------------------------------------------------------------------------
+ * Messages Interface
+ * ------------------------------------------------------------------------
+ *
+ * Message Format:
+ * <--- nlmsg_total_size(payload) --->
+ * <-- nlmsg_msg_size(payload) ->
+ * +----------+- - -+-------------+- - -+-------- - -
+ * | nlmsghdr | Pad | Payload | Pad | nlmsghdr
+ * +----------+- - -+-------------+- - -+-------- - -
+ * nlmsg_data(nlh)---^ ^
+ * nlmsg_next(nlh)-----------------------+
+ *
+ * Payload Format:
+ * <---------------------- nlmsg_len(nlh) --------------------->
+ * <------ hdrlen ------> <- nlmsg_attrlen(nlh, hdrlen) ->
+ * +----------------------+- - -+--------------------------------+
+ * | Family Header | Pad | Attributes |
+ * +----------------------+- - -+--------------------------------+
+ * nlmsg_attrdata(nlh, hdrlen)---^
+ *
+ * Data Structures:
+ * struct nlmsghdr netlink message header
+ *
+ * Message Construction:
+ * nlmsg_new() create a new netlink message
+ * nlmsg_put() add a netlink message to an skb
+ * nlmsg_put_answer() callback based nlmsg_put()
+ * nlmsg_end() finanlize netlink message
+ * nlmsg_cancel() cancel message construction
+ * nlmsg_free() free a netlink message
+ *
+ * Message Sending:
+ * nlmsg_multicast() multicast message to several groups
+ * nlmsg_unicast() unicast a message to a single socket
+ *
+ * Message Length Calculations:
+ * nlmsg_msg_size(payload) length of message w/o padding
+ * nlmsg_total_size(payload) length of message w/ padding
+ * nlmsg_padlen(payload) length of padding at tail
+ *
+ * Message Payload Access:
+ * nlmsg_data(nlh) head of message payload
+ * nlmsg_len(nlh) length of message payload
+ * nlmsg_attrdata(nlh, hdrlen) head of attributes data
+ * nlmsg_attrlen(nlh, hdrlen) length of attributes data
+ *
+ * Message Parsing:
+ * nlmsg_ok(nlh, remaining) does nlh fit into remaining bytes?
+ * nlmsg_next(nlh, remaining) get next netlink message
+ * nlmsg_parse() parse attributes of a message
+ * nlmsg_find_attr() find an attribute in a message
+ * nlmsg_for_each_msg() loop over all messages
+ * nlmsg_validate() validate netlink message incl. attrs
+ * nlmsg_for_each_attr() loop over all attributes
+ *
+ * ------------------------------------------------------------------------
+ * Attributes Interface
+ * ------------------------------------------------------------------------
+ *
+ * Attribute Format:
+ * <------- nla_total_size(payload) ------->
+ * <---- nla_attr_size(payload) ----->
+ * +----------+- - -+- - - - - - - - - +- - -+-------- - -
+ * | Header | Pad | Payload | Pad | Header
+ * +----------+- - -+- - - - - - - - - +- - -+-------- - -
+ * <- nla_len(nla) -> ^
+ * nla_data(nla)----^ |
+ * nla_next(nla)-----------------------------'
+ *
+ * Data Structures:
+ * struct nlattr netlink attribtue header
+ *
+ * Attribute Construction:
+ * nla_reserve(skb, type, len) reserve skb tailroom for an attribute
+ * nla_put(skb, type, len, data) add attribute to skb
+ *
+ * Attribute Construction for Basic Types:
+ * nla_put_u8(skb, type, value) add u8 attribute to skb
+ * nla_put_u16(skb, type, value) add u16 attribute to skb
+ * nla_put_u32(skb, type, value) add u32 attribute to skb
+ * nla_put_u64(skb, type, value) add u64 attribute to skb
+ * nla_put_string(skb, type, str) add string attribute to skb
+ * nla_put_flag(skb, type) add flag attribute to skb
+ * nla_put_msecs(skb, type, jiffies) add msecs attribute to skb
+ *
+ * Exceptions Based Attribute Construction:
+ * NLA_PUT(skb, type, len, data) add attribute to skb
+ * NLA_PUT_U8(skb, type, value) add u8 attribute to skb
+ * NLA_PUT_U16(skb, type, value) add u16 attribute to skb
+ * NLA_PUT_U32(skb, type, value) add u32 attribute to skb
+ * NLA_PUT_U64(skb, type, value) add u64 attribute to skb
+ * NLA_PUT_STRING(skb, type, str) add string attribute to skb
+ * NLA_PUT_FLAG(skb, type) add flag attribute to skb
+ * NLA_PUT_MSECS(skb, type, jiffies) add msecs attribute to skb
+ *
+ * The meaning of these functions is equal to their lower case
+ * variants but they jump to the label nla_put_failure in case
+ * of a failure.
+ *
+ * Nested Attributes Construction:
+ * nla_nest_start(skb, type) start a nested attribute
+ * nla_nest_end(skb, nla) finalize a nested attribute
+ * nla_nest_cancel(skb, nla) cancel nested attribute construction
+ *
+ * Attribute Length Calculations:
+ * nla_attr_size(payload) length of attribute w/o padding
+ * nla_total_size(payload) length of attribute w/ padding
+ * nla_padlen(payload) length of padding
+ *
+ * Attribute Payload Access:
+ * nla_data(nla) head of attribute payload
+ * nla_len(nla) length of attribute payload
+ *
+ * Attribute Payload Access for Basic Types:
+ * nla_get_u8(nla) get payload for a u8 attribute
+ * nla_get_u16(nla) get payload for a u16 attribute
+ * nla_get_u32(nla) get payload for a u32 attribute
+ * nla_get_u64(nla) get payload for a u64 attribute
+ * nla_get_flag(nla) return 1 if flag is true
+ * nla_get_msecs(nla) get payload for a msecs attribute
+ *
+ * Attribute Misc:
+ * nla_memcpy(dest, nla, count) copy attribute into memory
+ * nla_memcmp(nla, data, size) compare attribute with memory area
+ * nla_strlcpy(dst, nla, size) copy attribute to a sized string
+ * nla_strcmp(nla, str) compare attribute with string
+ *
+ * Attribute Parsing:
+ * nla_ok(nla, remaining) does nla fit into remaining bytes?
+ * nla_next(nla, remaining) get next netlink attribute
+ * nla_validate() validate a stream of attributes
+ * nla_find() find attribute in stream of attributes
+ * nla_parse() parse and validate stream of attrs
+ * nla_parse_nested() parse nested attribuets
+ * nla_for_each_attr() loop over all attributes
+ *=========================================================================
+ */
+
+ /**
+ * Standard attribute types to specify validation policy
+ */
+enum {
+ NLA_UNSPEC,
+ NLA_U8,
+ NLA_U16,
+ NLA_U32,
+ NLA_U64,
+ NLA_STRING,
+ NLA_FLAG,
+ NLA_MSECS,
+ NLA_NESTED,
+ __NLA_TYPE_MAX,
+};
+
+#define NLA_TYPE_MAX (__NLA_TYPE_MAX - 1)
+
+/**
+ * struct nla_policy - attribute validation policy
+ * @type: Type of attribute or NLA_UNSPEC
+ * @minlen: Minimal length of payload required to be available
+ *
+ * Policies are defined as arrays of this struct, the array must be
+ * accessible by attribute type up to the highest identifier to be expected.
+ *
+ * Example:
+ * static struct nla_policy my_policy[ATTR_MAX+1] __read_mostly = {
+ * [ATTR_FOO] = { .type = NLA_U16 },
+ * [ATTR_BAR] = { .type = NLA_STRING },
+ * [ATTR_BAZ] = { .minlen = sizeof(struct mystruct) },
+ * };
+ */
+struct nla_policy {
+ u16 type;
+ u16 minlen;
+};
+
+extern void netlink_run_queue(struct sock *sk, unsigned int *qlen,
+ int (*cb)(struct sk_buff *,
+ struct nlmsghdr *, int *));
+extern void netlink_queue_skip(struct nlmsghdr *nlh,
+ struct sk_buff *skb);
+
+extern int nla_validate(struct nlattr *head, int len, int maxtype,
+ struct nla_policy *policy);
+extern int nla_parse(struct nlattr *tb[], int maxtype,
+ struct nlattr *head, int len,
+ struct nla_policy *policy);
+extern struct nlattr * nla_find(struct nlattr *head, int len, int attrtype);
+extern size_t nla_strlcpy(char *dst, const struct nlattr *nla,
+ size_t dstsize);
+extern int nla_memcpy(void *dest, struct nlattr *src, int count);
+extern int nla_memcmp(const struct nlattr *nla, const void *data,
+ size_t size);
+extern int nla_strcmp(const struct nlattr *nla, const char *str);
+extern struct nlattr * __nla_reserve(struct sk_buff *skb, int attrtype,
+ int attrlen);
+extern struct nlattr * nla_reserve(struct sk_buff *skb, int attrtype,
+ int attrlen);
+extern void __nla_put(struct sk_buff *skb, int attrtype,
+ int attrlen, const void *data);
+extern int nla_put(struct sk_buff *skb, int attrtype,
+ int attrlen, const void *data);
+
+/**************************************************************************
+ * Netlink Messages
+ **************************************************************************/
+
+/**
+ * nlmsg_msg_size - length of netlink message not including padding
+ * @payload: length of message payload
+ */
+static inline int nlmsg_msg_size(int payload)
+{
+ return NLMSG_HDRLEN + payload;
+}
+
+/**
+ * nlmsg_total_size - length of netlink message including padding
+ * @payload: length of message payload
+ */
+static inline int nlmsg_total_size(int payload)
+{
+ return NLMSG_ALIGN(nlmsg_msg_size(payload));
+}
+
+/**
+ * nlmsg_padlen - length of padding at the message's tail
+ * @payload: length of message payload
+ */
+static inline int nlmsg_padlen(int payload)
+{
+ return nlmsg_total_size(payload) - nlmsg_msg_size(payload);
+}
+
+/**
+ * nlmsg_data - head of message payload
+ * @nlh: netlink messsage header
+ */
+static inline void *nlmsg_data(const struct nlmsghdr *nlh)
+{
+ return (unsigned char *) nlh + NLMSG_HDRLEN;
+}
+
+/**
+ * nlmsg_len - length of message payload
+ * @nlh: netlink message header
+ */
+static inline int nlmsg_len(const struct nlmsghdr *nlh)
+{
+ return nlh->nlmsg_len - NLMSG_HDRLEN;
+}
+
+/**
+ * nlmsg_attrdata - head of attributes data
+ * @nlh: netlink message header
+ * @hdrlen: length of family specific header
+ */
+static inline struct nlattr *nlmsg_attrdata(const struct nlmsghdr *nlh,
+ int hdrlen)
+{
+ unsigned char *data = nlmsg_data(nlh);
+ return (struct nlattr *) (data + NLMSG_ALIGN(hdrlen));
+}
+
+/**
+ * nlmsg_attrlen - length of attributes data
+ * @nlh: netlink message header
+ * @hdrlen: length of family specific header
+ */
+static inline int nlmsg_attrlen(const struct nlmsghdr *nlh, int hdrlen)
+{
+ return nlmsg_len(nlh) - NLMSG_ALIGN(hdrlen);
+}
+
+/**
+ * nlmsg_ok - check if the netlink message fits into the remaining bytes
+ * @nlh: netlink message header
+ * @remaining: number of bytes remaining in message stream
+ */
+static inline int nlmsg_ok(const struct nlmsghdr *nlh, int remaining)
+{
+ return (remaining >= sizeof(struct nlmsghdr) &&
+ nlh->nlmsg_len >= sizeof(struct nlmsghdr) &&
+ nlh->nlmsg_len <= remaining);
+}
+
+/**
+ * nlmsg_next - next netlink message in message stream
+ * @nlh: netlink message header
+ * @remaining: number of bytes remaining in message stream
+ *
+ * Returns the next netlink message in the message stream and
+ * decrements remaining by the size of the current message.
+ */
+static inline struct nlmsghdr *nlmsg_next(struct nlmsghdr *nlh, int *remaining)
+{
+ int totlen = NLMSG_ALIGN(nlh->nlmsg_len);
+
+ *remaining -= totlen;
+
+ return (struct nlmsghdr *) ((unsigned char *) nlh + totlen);
+}
+
+/**
+ * nlmsg_parse - parse attributes of a netlink message
+ * @nlh: netlink message header
+ * @hdrlen: length of family specific header
+ * @tb: destination array with maxtype+1 elements
+ * @maxtype: maximum attribute type to be expected
+ * @policy: validation policy
+ *
+ * See nla_parse()
+ */
+static inline int nlmsg_parse(struct nlmsghdr *nlh, int hdrlen,
+ struct nlattr *tb[], int maxtype,
+ struct nla_policy *policy)
+{
+ if (nlh->nlmsg_len < nlmsg_msg_size(hdrlen))
+ return -EINVAL;
+
+ return nla_parse(tb, maxtype, nlmsg_attrdata(nlh, hdrlen),
+ nlmsg_attrlen(nlh, hdrlen), policy);
+}
+
+/**
+ * nlmsg_find_attr - find a specific attribute in a netlink message
+ * @nlh: netlink message header
+ * @hdrlen: length of familiy specific header
+ * @attrtype: type of attribute to look for
+ *
+ * Returns the first attribute which matches the specified type.
+ */
+static inline struct nlattr *nlmsg_find_attr(struct nlmsghdr *nlh,
+ int hdrlen, int attrtype)
+{
+ return nla_find(nlmsg_attrdata(nlh, hdrlen),
+ nlmsg_attrlen(nlh, hdrlen), attrtype);
+}
+
+/**
+ * nlmsg_validate - validate a netlink message including attributes
+ * @nlh: netlinket message header
+ * @hdrlen: length of familiy specific header
+ * @maxtype: maximum attribute type to be expected
+ * @policy: validation policy
+ */
+static inline int nlmsg_validate(struct nlmsghdr *nlh, int hdrlen, int maxtype,
+ struct nla_policy *policy)
+{
+ if (nlh->nlmsg_len < nlmsg_msg_size(hdrlen))
+ return -EINVAL;
+
+ return nla_validate(nlmsg_attrdata(nlh, hdrlen),
+ nlmsg_attrlen(nlh, hdrlen), maxtype, policy);
+}
+
+/**
+ * nlmsg_for_each_attr - iterate over a stream of attributes
+ * @pos: loop counter, set to current attribute
+ * @nlh: netlink message header
+ * @hdrlen: length of familiy specific header
+ * @rem: initialized to len, holds bytes currently remaining in stream
+ */
+#define nlmsg_for_each_attr(pos, nlh, hdrlen, rem) \
+ nla_for_each_attr(pos, nlmsg_attrdata(nlh, hdrlen), \
+ nlmsg_attrlen(nlh, hdrlen), rem)
+
+#if 0
+/* FIXME: Enable once all users have been converted */
+
+/**
+ * __nlmsg_put - Add a new netlink message to an skb
+ * @skb: socket buffer to store message in
+ * @pid: netlink process id
+ * @seq: sequence number of message
+ * @type: message type
+ * @payload: length of message payload
+ * @flags: message flags
+ *
+ * The caller is responsible to ensure that the skb provides enough
+ * tailroom for both the netlink header and payload.
+ */
+static inline struct nlmsghdr *__nlmsg_put(struct sk_buff *skb, u32 pid,
+ u32 seq, int type, int payload,
+ int flags)
+{
+ struct nlmsghdr *nlh;
+
+ nlh = (struct nlmsghdr *) skb_put(skb, nlmsg_total_size(payload));
+ nlh->nlmsg_type = type;
+ nlh->nlmsg_len = nlmsg_msg_size(payload);
+ nlh->nlmsg_flags = flags;
+ nlh->nlmsg_pid = pid;
+ nlh->nlmsg_seq = seq;
+
+ memset((unsigned char *) nlmsg_data(nlh) + payload, 0,
+ nlmsg_padlen(payload));
+
+ return nlh;
+}
+#endif
+
+/**
+ * nlmsg_put - Add a new netlink message to an skb
+ * @skb: socket buffer to store message in
+ * @pid: netlink process id
+ * @seq: sequence number of message
+ * @type: message type
+ * @payload: length of message payload
+ * @flags: message flags
+ *
+ * Returns NULL if the tailroom of the skb is insufficient to store
+ * the message header and payload.
+ */
+static inline struct nlmsghdr *nlmsg_put(struct sk_buff *skb, u32 pid, u32 seq,
+ int type, int payload, int flags)
+{
+ if (unlikely(skb_tailroom(skb) < nlmsg_total_size(payload)))
+ return NULL;
+
+ return __nlmsg_put(skb, pid, seq, type, payload, flags);
+}
+
+/**
+ * nlmsg_put_answer - Add a new callback based netlink message to an skb
+ * @skb: socket buffer to store message in
+ * @cb: netlink callback
+ * @type: message type
+ * @payload: length of message payload
+ * @flags: message flags
+ *
+ * Returns NULL if the tailroom of the skb is insufficient to store
+ * the message header and payload.
+ */
+static inline struct nlmsghdr *nlmsg_put_answer(struct sk_buff *skb,
+ struct netlink_callback *cb,
+ int type, int payload,
+ int flags)
+{
+ return nlmsg_put(skb, NETLINK_CB(cb->skb).pid, cb->nlh->nlmsg_seq,
+ type, payload, flags);
+}
+
+/**
+ * nlmsg_new - Allocate a new netlink message
+ * @size: maximum size of message
+ *
+ * Use NLMSG_GOODSIZE if size isn't know and you need a good default size.
+ */
+static inline struct sk_buff *nlmsg_new(int size)
+{
+ return alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
+}
+
+/**
+ * nlmsg_end - Finalize a netlink message
+ * @skb: socket buffer the message is stored in
+ * @nlh: netlink message header
+ *
+ * Corrects the netlink message header to include the appeneded
+ * attributes. Only necessary if attributes have been added to
+ * the message.
+ *
+ * Returns the total data length of the skb.
+ */
+static inline int nlmsg_end(struct sk_buff *skb, struct nlmsghdr *nlh)
+{
+ nlh->nlmsg_len = skb->tail - (unsigned char *) nlh;
+
+ return skb->len;
+}
+
+/**
+ * nlmsg_cancel - Cancel construction of a netlink message
+ * @skb: socket buffer the message is stored in
+ * @nlh: netlink message header
+ *
+ * Removes the complete netlink message including all
+ * attributes from the socket buffer again. Returns -1.
+ */
+static inline int nlmsg_cancel(struct sk_buff *skb, struct nlmsghdr *nlh)
+{
+ skb_trim(skb, (unsigned char *) nlh - skb->data);
+
+ return -1;
+}
+
+/**
+ * nlmsg_free - free a netlink message
+ * @skb: socket buffer of netlink message
+ */
+static inline void nlmsg_free(struct sk_buff *skb)
+{
+ kfree_skb(skb);
+}
+
+/**
+ * nlmsg_multicast - multicast a netlink message
+ * @sk: netlink socket to spread messages to
+ * @skb: netlink message as socket buffer
+ * @pid: own netlink pid to avoid sending to yourself
+ * @group: multicast group id
+ */
+static inline int nlmsg_multicast(struct sock *sk, struct sk_buff *skb,
+ u32 pid, unsigned int group)
+{
+ int err;
+
+ NETLINK_CB(skb).dst_group = group;
+
+ err = netlink_broadcast(sk, skb, pid, group, GFP_KERNEL);
+ if (err > 0)
+ err = 0;
+
+ return err;
+}
+
+/**
+ * nlmsg_unicast - unicast a netlink message
+ * @sk: netlink socket to spread message to
+ * @skb: netlink message as socket buffer
+ * @pid: netlink pid of the destination socket
+ */
+static inline int nlmsg_unicast(struct sock *sk, struct sk_buff *skb, u32 pid)
+{
+ int err;
+
+ err = netlink_unicast(sk, skb, pid, MSG_DONTWAIT);
+ if (err > 0)
+ err = 0;
+
+ return err;
+}
+
+/**
+ * nlmsg_for_each_msg - iterate over a stream of messages
+ * @pos: loop counter, set to current message
+ * @head: head of message stream
+ * @len: length of message stream
+ * @rem: initialized to len, holds bytes currently remaining in stream
+ */
+#define nlmsg_for_each_msg(pos, head, len, rem) \
+ for (pos = head, rem = len; \
+ nlmsg_ok(pos, rem); \
+ pos = nlmsg_next(pos, &(rem)))
+
+/**************************************************************************
+ * Netlink Attributes
+ **************************************************************************/
+
+/**
+ * nla_attr_size - length of attribute not including padding
+ * @payload: length of payload
+ */
+static inline int nla_attr_size(int payload)
+{
+ return NLA_HDRLEN + payload;
+}
+
+/**
+ * nla_total_size - total length of attribute including padding
+ * @payload: length of payload
+ */
+static inline int nla_total_size(int payload)
+{
+ return NLA_ALIGN(nla_attr_size(payload));
+}
+
+/**
+ * nla_padlen - length of padding at the tail of attribute
+ * @payload: length of payload
+ */
+static inline int nla_padlen(int payload)
+{
+ return nla_total_size(payload) - nla_attr_size(payload);
+}
+
+/**
+ * nla_data - head of payload
+ * @nla: netlink attribute
+ */
+static inline void *nla_data(const struct nlattr *nla)
+{
+ return (char *) nla + NLA_HDRLEN;
+}
+
+/**
+ * nla_len - length of payload
+ * @nla: netlink attribute
+ */
+static inline int nla_len(const struct nlattr *nla)
+{
+ return nla->nla_len - NLA_HDRLEN;
+}
+
+/**
+ * nla_ok - check if the netlink attribute fits into the remaining bytes
+ * @nla: netlink attribute
+ * @remaining: number of bytes remaining in attribute stream
+ */
+static inline int nla_ok(const struct nlattr *nla, int remaining)
+{
+ return remaining >= sizeof(*nla) &&
+ nla->nla_len >= sizeof(*nla) &&
+ nla->nla_len <= remaining;
+}
+
+/**
+ * nla_next - next netlink attribte in attribute stream
+ * @nla: netlink attribute
+ * @remaining: number of bytes remaining in attribute stream
+ *
+ * Returns the next netlink attribute in the attribute stream and
+ * decrements remaining by the size of the current attribute.
+ */
+static inline struct nlattr *nla_next(const struct nlattr *nla, int *remaining)
+{
+ int totlen = NLA_ALIGN(nla->nla_len);
+
+ *remaining -= totlen;
+ return (struct nlattr *) ((char *) nla + totlen);
+}
+
+/**
+ * nla_parse_nested - parse nested attributes
+ * @tb: destination array with maxtype+1 elements
+ * @maxtype: maximum attribute type to be expected
+ * @nla: attribute containing the nested attributes
+ * @policy: validation policy
+ *
+ * See nla_parse()
+ */
+static inline int nla_parse_nested(struct nlattr *tb[], int maxtype,
+ struct nlattr *nla,
+ struct nla_policy *policy)
+{
+ return nla_parse(tb, maxtype, nla_data(nla), nla_len(nla), policy);
+}
+/**
+ * nla_put_u8 - Add a u16 netlink attribute to a socket buffer
+ * @skb: socket buffer to add attribute to
+ * @attrtype: attribute type
+ * @value: numeric value
+ */
+static inline int nla_put_u8(struct sk_buff *skb, int attrtype, u8 value)
+{
+ return nla_put(skb, attrtype, sizeof(u8), &value);
+}
+
+/**
+ * nla_put_u16 - Add a u16 netlink attribute to a socket buffer
+ * @skb: socket buffer to add attribute to
+ * @attrtype: attribute type
+ * @value: numeric value
+ */
+static inline int nla_put_u16(struct sk_buff *skb, int attrtype, u16 value)
+{
+ return nla_put(skb, attrtype, sizeof(u16), &value);
+}
+
+/**
+ * nla_put_u32 - Add a u32 netlink attribute to a socket buffer
+ * @skb: socket buffer to add attribute to
+ * @attrtype: attribute type
+ * @value: numeric value
+ */
+static inline int nla_put_u32(struct sk_buff *skb, int attrtype, u32 value)
+{
+ return nla_put(skb, attrtype, sizeof(u32), &value);
+}
+
+/**
+ * nla_put_64 - Add a u64 netlink attribute to a socket buffer
+ * @skb: socket buffer to add attribute to
+ * @attrtype: attribute type
+ * @value: numeric value
+ */
+static inline int nla_put_u64(struct sk_buff *skb, int attrtype, u64 value)
+{
+ return nla_put(skb, attrtype, sizeof(u64), &value);
+}
+
+/**
+ * nla_put_string - Add a string netlink attribute to a socket buffer
+ * @skb: socket buffer to add attribute to
+ * @attrtype: attribute type
+ * @str: NUL terminated string
+ */
+static inline int nla_put_string(struct sk_buff *skb, int attrtype,
+ const char *str)
+{
+ return nla_put(skb, attrtype, strlen(str) + 1, str);
+}
+
+/**
+ * nla_put_flag - Add a flag netlink attribute to a socket buffer
+ * @skb: socket buffer to add attribute to
+ * @attrtype: attribute type
+ */
+static inline int nla_put_flag(struct sk_buff *skb, int attrtype)
+{
+ return nla_put(skb, attrtype, 0, NULL);
+}
+
+/**
+ * nla_put_msecs - Add a msecs netlink attribute to a socket buffer
+ * @skb: socket buffer to add attribute to
+ * @attrtype: attribute type
+ * @jiffies: number of msecs in jiffies
+ */
+static inline int nla_put_msecs(struct sk_buff *skb, int attrtype,
+ unsigned long jiffies)
+{
+ u64 tmp = jiffies_to_msecs(jiffies);
+ return nla_put(skb, attrtype, sizeof(u64), &tmp);
+}
+
+#define NLA_PUT(skb, attrtype, attrlen, data) \
+ do { \
+ if (nla_put(skb, attrtype, attrlen, data) < 0) \
+ goto nla_put_failure; \
+ } while(0)
+
+#define NLA_PUT_TYPE(skb, type, attrtype, value) \
+ do { \
+ type __tmp = value; \
+ NLA_PUT(skb, attrtype, sizeof(type), &__tmp); \
+ } while(0)
+
+#define NLA_PUT_U8(skb, attrtype, value) \
+ NLA_PUT_TYPE(skb, u8, attrtype, value)
+
+#define NLA_PUT_U16(skb, attrtype, value) \
+ NLA_PUT_TYPE(skb, u16, attrtype, value)
+
+#define NLA_PUT_U32(skb, attrtype, value) \
+ NLA_PUT_TYPE(skb, u32, attrtype, value)
+
+#define NLA_PUT_U64(skb, attrtype, value) \
+ NLA_PUT_TYPE(skb, u64, attrtype, value)
+
+#define NLA_PUT_STRING(skb, attrtype, value) \
+ NLA_PUT(skb, attrtype, strlen(value) + 1, value)
+
+#define NLA_PUT_FLAG(skb, attrtype, value) \
+ NLA_PUT(skb, attrtype, 0, NULL)
+
+#define NLA_PUT_MSECS(skb, attrtype, jiffies) \
+ NLA_PUT_U64(skb, attrtype, jiffies_to_msecs(jiffies))
+
+/**
+ * nla_get_u32 - return payload of u32 attribute
+ * @nla: u32 netlink attribute
+ */
+static inline u32 nla_get_u32(struct nlattr *nla)
+{
+ return *(u32 *) nla_data(nla);
+}
+
+/**
+ * nla_get_u16 - return payload of u16 attribute
+ * @nla: u16 netlink attribute
+ */
+static inline u16 nla_get_u16(struct nlattr *nla)
+{
+ return *(u16 *) nla_data(nla);
+}
+
+/**
+ * nla_get_u8 - return payload of u8 attribute
+ * @nla: u8 netlink attribute
+ */
+static inline u8 nla_get_u8(struct nlattr *nla)
+{
+ return *(u8 *) nla_data(nla);
+}
+
+/**
+ * nla_get_u64 - return payload of u64 attribute
+ * @nla: u64 netlink attribute
+ */
+static inline u64 nla_get_u64(struct nlattr *nla)
+{
+ u64 tmp;
+
+ nla_memcpy(&tmp, nla, sizeof(tmp));
+
+ return tmp;
+}
+
+/**
+ * nla_get_flag - return payload of flag attribute
+ * @nla: flag netlink attribute
+ */
+static inline int nla_get_flag(struct nlattr *nla)
+{
+ return !!nla;
+}
+
+/**
+ * nla_get_msecs - return payload of msecs attribute
+ * @nla: msecs netlink attribute
+ *
+ * Returns the number of milliseconds in jiffies.
+ */
+static inline unsigned long nla_get_msecs(struct nlattr *nla)
+{
+ u64 msecs = nla_get_u64(nla);
+
+ return msecs_to_jiffies((unsigned long) msecs);
+}
+
+/**
+ * nla_nest_start - Start a new level of nested attributes
+ * @skb: socket buffer to add attributes to
+ * @attrtype: attribute type of container
+ *
+ * Returns the container attribute
+ */
+static inline struct nlattr *nla_nest_start(struct sk_buff *skb, int attrtype)
+{
+ struct nlattr *start = (struct nlattr *) skb->tail;
+
+ if (nla_put(skb, attrtype, 0, NULL) < 0)
+ return NULL;
+
+ return start;
+}
+
+/**
+ * nla_nest_end - Finalize nesting of attributes
+ * @skb: socket buffer the attribtues are stored in
+ * @start: container attribute
+ *
+ * Corrects the container attribute header to include the all
+ * appeneded attributes.
+ *
+ * Returns the total data length of the skb.
+ */
+static inline int nla_nest_end(struct sk_buff *skb, struct nlattr *start)
+{
+ start->nla_len = skb->tail - (unsigned char *) start;
+ return skb->len;
+}
+
+/**
+ * nla_nest_cancel - Cancel nesting of attributes
+ * @skb: socket buffer the message is stored in
+ * @start: container attribute
+ *
+ * Removes the container attribute and including all nested
+ * attributes. Returns -1.
+ */
+static inline int nla_nest_cancel(struct sk_buff *skb, struct nlattr *start)
+{
+ if (start)
+ skb_trim(skb, (unsigned char *) start - skb->data);
+
+ return -1;
+}
+
+/**
+ * nla_for_each_attr - iterate over a stream of attributes
+ * @pos: loop counter, set to current attribute
+ * @head: head of attribute stream
+ * @len: length of attribute stream
+ * @rem: initialized to len, holds bytes currently remaining in stream
+ */
+#define nla_for_each_attr(pos, head, len, rem) \
+ for (pos = head, rem = len; \
+ nla_ok(pos, rem); \
+ pos = nla_next(pos, &(rem)))
+
+#endif
diff --git a/include/net/netrom.h b/include/net/netrom.h
index a6bf6e0f606a..a5ee53bce62f 100644
--- a/include/net/netrom.h
+++ b/include/net/netrom.h
@@ -136,8 +136,7 @@ static __inline__ void nr_node_put(struct nr_node *nr_node)
static __inline__ void nr_neigh_put(struct nr_neigh *nr_neigh)
{
if (atomic_dec_and_test(&nr_neigh->refcount)) {
- if (nr_neigh->digipeat != NULL)
- kfree(nr_neigh->digipeat);
+ kfree(nr_neigh->digipeat);
kfree(nr_neigh);
}
}
diff --git a/include/net/red.h b/include/net/red.h
new file mode 100644
index 000000000000..2ed4358e3295
--- /dev/null
+++ b/include/net/red.h
@@ -0,0 +1,325 @@
+#ifndef __NET_SCHED_RED_H
+#define __NET_SCHED_RED_H
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <net/pkt_sched.h>
+#include <net/inet_ecn.h>
+#include <net/dsfield.h>
+
+/* Random Early Detection (RED) algorithm.
+ =======================================
+
+ Source: Sally Floyd and Van Jacobson, "Random Early Detection Gateways
+ for Congestion Avoidance", 1993, IEEE/ACM Transactions on Networking.
+
+ This file codes a "divisionless" version of RED algorithm
+ as written down in Fig.17 of the paper.
+
+ Short description.
+ ------------------
+
+ When a new packet arrives we calculate the average queue length:
+
+ avg = (1-W)*avg + W*current_queue_len,
+
+ W is the filter time constant (chosen as 2^(-Wlog)), it controls
+ the inertia of the algorithm. To allow larger bursts, W should be
+ decreased.
+
+ if (avg > th_max) -> packet marked (dropped).
+ if (avg < th_min) -> packet passes.
+ if (th_min < avg < th_max) we calculate probability:
+
+ Pb = max_P * (avg - th_min)/(th_max-th_min)
+
+ and mark (drop) packet with this probability.
+ Pb changes from 0 (at avg==th_min) to max_P (avg==th_max).
+ max_P should be small (not 1), usually 0.01..0.02 is good value.
+
+ max_P is chosen as a number, so that max_P/(th_max-th_min)
+ is a negative power of two in order arithmetics to contain
+ only shifts.
+
+
+ Parameters, settable by user:
+ -----------------------------
+
+ qth_min - bytes (should be < qth_max/2)
+ qth_max - bytes (should be at least 2*qth_min and less limit)
+ Wlog - bits (<32) log(1/W).
+ Plog - bits (<32)
+
+ Plog is related to max_P by formula:
+
+ max_P = (qth_max-qth_min)/2^Plog;
+
+ F.e. if qth_max=128K and qth_min=32K, then Plog=22
+ corresponds to max_P=0.02
+
+ Scell_log
+ Stab
+
+ Lookup table for log((1-W)^(t/t_ave).
+
+
+ NOTES:
+
+ Upper bound on W.
+ -----------------
+
+ If you want to allow bursts of L packets of size S,
+ you should choose W:
+
+ L + 1 - th_min/S < (1-(1-W)^L)/W
+
+ th_min/S = 32 th_min/S = 4
+
+ log(W) L
+ -1 33
+ -2 35
+ -3 39
+ -4 46
+ -5 57
+ -6 75
+ -7 101
+ -8 135
+ -9 190
+ etc.
+ */
+
+#define RED_STAB_SIZE 256
+#define RED_STAB_MASK (RED_STAB_SIZE - 1)
+
+struct red_stats
+{
+ u32 prob_drop; /* Early probability drops */
+ u32 prob_mark; /* Early probability marks */
+ u32 forced_drop; /* Forced drops, qavg > max_thresh */
+ u32 forced_mark; /* Forced marks, qavg > max_thresh */
+ u32 pdrop; /* Drops due to queue limits */
+ u32 other; /* Drops due to drop() calls */
+ u32 backlog;
+};
+
+struct red_parms
+{
+ /* Parameters */
+ u32 qth_min; /* Min avg length threshold: A scaled */
+ u32 qth_max; /* Max avg length threshold: A scaled */
+ u32 Scell_max;
+ u32 Rmask; /* Cached random mask, see red_rmask */
+ u8 Scell_log;
+ u8 Wlog; /* log(W) */
+ u8 Plog; /* random number bits */
+ u8 Stab[RED_STAB_SIZE];
+
+ /* Variables */
+ int qcount; /* Number of packets since last random
+ number generation */
+ u32 qR; /* Cached random number */
+
+ unsigned long qavg; /* Average queue length: A scaled */
+ psched_time_t qidlestart; /* Start of current idle period */
+};
+
+static inline u32 red_rmask(u8 Plog)
+{
+ return Plog < 32 ? ((1 << Plog) - 1) : ~0UL;
+}
+
+static inline void red_set_parms(struct red_parms *p,
+ u32 qth_min, u32 qth_max, u8 Wlog, u8 Plog,
+ u8 Scell_log, u8 *stab)
+{
+ /* Reset average queue length, the value is strictly bound
+ * to the parameters below, reseting hurts a bit but leaving
+ * it might result in an unreasonable qavg for a while. --TGR
+ */
+ p->qavg = 0;
+
+ p->qcount = -1;
+ p->qth_min = qth_min << Wlog;
+ p->qth_max = qth_max << Wlog;
+ p->Wlog = Wlog;
+ p->Plog = Plog;
+ p->Rmask = red_rmask(Plog);
+ p->Scell_log = Scell_log;
+ p->Scell_max = (255 << Scell_log);
+
+ memcpy(p->Stab, stab, sizeof(p->Stab));
+}
+
+static inline int red_is_idling(struct red_parms *p)
+{
+ return !PSCHED_IS_PASTPERFECT(p->qidlestart);
+}
+
+static inline void red_start_of_idle_period(struct red_parms *p)
+{
+ PSCHED_GET_TIME(p->qidlestart);
+}
+
+static inline void red_end_of_idle_period(struct red_parms *p)
+{
+ PSCHED_SET_PASTPERFECT(p->qidlestart);
+}
+
+static inline void red_restart(struct red_parms *p)
+{
+ red_end_of_idle_period(p);
+ p->qavg = 0;
+ p->qcount = -1;
+}
+
+static inline unsigned long red_calc_qavg_from_idle_time(struct red_parms *p)
+{
+ psched_time_t now;
+ long us_idle;
+ int shift;
+
+ PSCHED_GET_TIME(now);
+ us_idle = PSCHED_TDIFF_SAFE(now, p->qidlestart, p->Scell_max);
+
+ /*
+ * The problem: ideally, average length queue recalcultion should
+ * be done over constant clock intervals. This is too expensive, so
+ * that the calculation is driven by outgoing packets.
+ * When the queue is idle we have to model this clock by hand.
+ *
+ * SF+VJ proposed to "generate":
+ *
+ * m = idletime / (average_pkt_size / bandwidth)
+ *
+ * dummy packets as a burst after idle time, i.e.
+ *
+ * p->qavg *= (1-W)^m
+ *
+ * This is an apparently overcomplicated solution (f.e. we have to
+ * precompute a table to make this calculation in reasonable time)
+ * I believe that a simpler model may be used here,
+ * but it is field for experiments.
+ */
+
+ shift = p->Stab[(us_idle >> p->Scell_log) & RED_STAB_MASK];
+
+ if (shift)
+ return p->qavg >> shift;
+ else {
+ /* Approximate initial part of exponent with linear function:
+ *
+ * (1-W)^m ~= 1-mW + ...
+ *
+ * Seems, it is the best solution to
+ * problem of too coarse exponent tabulation.
+ */
+ us_idle = (p->qavg * us_idle) >> p->Scell_log;
+
+ if (us_idle < (p->qavg >> 1))
+ return p->qavg - us_idle;
+ else
+ return p->qavg >> 1;
+ }
+}
+
+static inline unsigned long red_calc_qavg_no_idle_time(struct red_parms *p,
+ unsigned int backlog)
+{
+ /*
+ * NOTE: p->qavg is fixed point number with point at Wlog.
+ * The formula below is equvalent to floating point
+ * version:
+ *
+ * qavg = qavg*(1-W) + backlog*W;
+ *
+ * --ANK (980924)
+ */
+ return p->qavg + (backlog - (p->qavg >> p->Wlog));
+}
+
+static inline unsigned long red_calc_qavg(struct red_parms *p,
+ unsigned int backlog)
+{
+ if (!red_is_idling(p))
+ return red_calc_qavg_no_idle_time(p, backlog);
+ else
+ return red_calc_qavg_from_idle_time(p);
+}
+
+static inline u32 red_random(struct red_parms *p)
+{
+ return net_random() & p->Rmask;
+}
+
+static inline int red_mark_probability(struct red_parms *p, unsigned long qavg)
+{
+ /* The formula used below causes questions.
+
+ OK. qR is random number in the interval 0..Rmask
+ i.e. 0..(2^Plog). If we used floating point
+ arithmetics, it would be: (2^Plog)*rnd_num,
+ where rnd_num is less 1.
+
+ Taking into account, that qavg have fixed
+ point at Wlog, and Plog is related to max_P by
+ max_P = (qth_max-qth_min)/2^Plog; two lines
+ below have the following floating point equivalent:
+
+ max_P*(qavg - qth_min)/(qth_max-qth_min) < rnd/qcount
+
+ Any questions? --ANK (980924)
+ */
+ return !(((qavg - p->qth_min) >> p->Wlog) * p->qcount < p->qR);
+}
+
+enum {
+ RED_BELOW_MIN_THRESH,
+ RED_BETWEEN_TRESH,
+ RED_ABOVE_MAX_TRESH,
+};
+
+static inline int red_cmp_thresh(struct red_parms *p, unsigned long qavg)
+{
+ if (qavg < p->qth_min)
+ return RED_BELOW_MIN_THRESH;
+ else if (qavg >= p->qth_max)
+ return RED_ABOVE_MAX_TRESH;
+ else
+ return RED_BETWEEN_TRESH;
+}
+
+enum {
+ RED_DONT_MARK,
+ RED_PROB_MARK,
+ RED_HARD_MARK,
+};
+
+static inline int red_action(struct red_parms *p, unsigned long qavg)
+{
+ switch (red_cmp_thresh(p, qavg)) {
+ case RED_BELOW_MIN_THRESH:
+ p->qcount = -1;
+ return RED_DONT_MARK;
+
+ case RED_BETWEEN_TRESH:
+ if (++p->qcount) {
+ if (red_mark_probability(p, qavg)) {
+ p->qcount = 0;
+ p->qR = red_random(p);
+ return RED_PROB_MARK;
+ }
+ } else
+ p->qR = red_random(p);
+
+ return RED_DONT_MARK;
+
+ case RED_ABOVE_MAX_TRESH:
+ p->qcount = -1;
+ return RED_HARD_MARK;
+ }
+
+ BUG();
+ return RED_DONT_MARK;
+}
+
+#endif
diff --git a/include/net/sctp/user.h b/include/net/sctp/user.h
index 1c5f19f995ad..f1c3bc54526a 100644
--- a/include/net/sctp/user.h
+++ b/include/net/sctp/user.h
@@ -171,10 +171,10 @@ struct sctp_sndrcvinfo {
*/
enum sctp_sinfo_flags {
- MSG_UNORDERED = 1, /* Send/receive message unordered. */
- MSG_ADDR_OVER = 2, /* Override the primary destination. */
- MSG_ABORT=4, /* Send an ABORT message to the peer. */
- /* MSG_EOF is already defined per socket.h */
+ SCTP_UNORDERED = 1, /* Send/receive message unordered. */
+ SCTP_ADDR_OVER = 2, /* Override the primary destination. */
+ SCTP_ABORT=4, /* Send an ABORT message to the peer. */
+ SCTP_EOF=MSG_FIN, /* Initiate graceful shutdown process. */
};
diff --git a/include/net/sock.h b/include/net/sock.h
index ecb75526cba0..982b4ecd187b 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -207,7 +207,7 @@ struct sock {
struct sk_buff_head sk_write_queue;
int sk_wmem_queued;
int sk_forward_alloc;
- unsigned int sk_allocation;
+ gfp_t sk_allocation;
int sk_sndbuf;
int sk_route_caps;
unsigned long sk_flags;
@@ -461,16 +461,16 @@ static inline void sk_stream_free_skb(struct sock *sk, struct sk_buff *skb)
}
/* The per-socket spinlock must be held here. */
-#define sk_add_backlog(__sk, __skb) \
-do { if (!(__sk)->sk_backlog.tail) { \
- (__sk)->sk_backlog.head = \
- (__sk)->sk_backlog.tail = (__skb); \
- } else { \
- ((__sk)->sk_backlog.tail)->next = (__skb); \
- (__sk)->sk_backlog.tail = (__skb); \
- } \
- (__skb)->next = NULL; \
-} while(0)
+static inline void sk_add_backlog(struct sock *sk, struct sk_buff *skb)
+{
+ if (!sk->sk_backlog.tail) {
+ sk->sk_backlog.head = sk->sk_backlog.tail = skb;
+ } else {
+ sk->sk_backlog.tail->next = skb;
+ sk->sk_backlog.tail = skb;
+ }
+ skb->next = NULL;
+}
#define sk_wait_event(__sk, __timeo, __condition) \
({ int rc; \
@@ -1247,6 +1247,12 @@ static inline struct page *sk_stream_alloc_page(struct sock *sk)
(skb != (struct sk_buff *)&(sk)->sk_write_queue); \
skb = skb->next)
+/*from STCP for fast SACK Process*/
+#define sk_stream_for_retrans_queue_from(skb, sk) \
+ for (; (skb != (sk)->sk_send_head) && \
+ (skb != (struct sk_buff *)&(sk)->sk_write_queue); \
+ skb = skb->next)
+
/*
* Default write policy as shown to user space via poll/select/SIGIO
*/
diff --git a/include/net/syncppp.h b/include/net/syncppp.h
index 614cb6ba564e..877efa434700 100644
--- a/include/net/syncppp.h
+++ b/include/net/syncppp.h
@@ -86,7 +86,6 @@ static inline struct sppp *sppp_of(struct net_device *dev)
void sppp_attach (struct ppp_device *pd);
void sppp_detach (struct net_device *dev);
-void sppp_input (struct net_device *dev, struct sk_buff *m);
int sppp_do_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd);
struct sk_buff *sppp_dequeue (struct net_device *dev);
int sppp_isempty (struct net_device *dev);
diff --git a/include/net/tcp.h b/include/net/tcp.h
index c24339c4e310..0f9848011972 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -27,6 +27,7 @@
#include <linux/slab.h>
#include <linux/cache.h>
#include <linux/percpu.h>
+#include <linux/skbuff.h>
#include <net/inet_connection_sock.h>
#include <net/inet_timewait_sock.h>
@@ -88,10 +89,10 @@ extern void tcp_time_wait(struct sock *sk, int state, int timeo);
*/
#define TCP_SYN_RETRIES 5 /* number of times to retry active opening a
- * connection: ~180sec is RFC minumum */
+ * connection: ~180sec is RFC minimum */
#define TCP_SYNACK_RETRIES 5 /* number of times to retry passive opening a
- * connection: ~180sec is RFC minumum */
+ * connection: ~180sec is RFC minimum */
#define TCP_ORPHAN_RETRIES 7 /* number of times to retry on an orphaned
@@ -179,7 +180,7 @@ extern void tcp_time_wait(struct sock *sk, int state, int timeo);
/* Flags in tp->nonagle */
#define TCP_NAGLE_OFF 1 /* Nagle's algo is disabled */
#define TCP_NAGLE_CORK 2 /* Socket is corked */
-#define TCP_NAGLE_PUSH 4 /* Cork is overriden for already queued data */
+#define TCP_NAGLE_PUSH 4 /* Cork is overridden for already queued data */
extern struct inet_timewait_death_row tcp_death_row;
@@ -217,6 +218,7 @@ extern int sysctl_tcp_low_latency;
extern int sysctl_tcp_nometrics_save;
extern int sysctl_tcp_moderate_rcvbuf;
extern int sysctl_tcp_tso_win_divisor;
+extern int sysctl_tcp_abc;
extern atomic_t tcp_memory_allocated;
extern atomic_t tcp_sockets_allocated;
@@ -550,13 +552,13 @@ extern u32 __tcp_select_window(struct sock *sk);
/* TCP timestamps are only 32-bits, this causes a slight
* complication on 64-bit systems since we store a snapshot
- * of jiffies in the buffer control blocks below. We decidely
+ * of jiffies in the buffer control blocks below. We decidedly
* only use of the low 32-bits of jiffies and hide the ugly
* casts with the following macro.
*/
#define tcp_time_stamp ((__u32)(jiffies))
-/* This is what the send packet queueing engine uses to pass
+/* This is what the send packet queuing engine uses to pass
* TCP per-packet control information to the transmission
* code. We also store the host-order sequence numbers in
* here too. This is 36 bytes on 32-bit architectures,
@@ -596,7 +598,7 @@ struct tcp_skb_cb {
#define TCPCB_EVER_RETRANS 0x80 /* Ever retransmitted frame */
#define TCPCB_RETRANS (TCPCB_SACKED_RETRANS|TCPCB_EVER_RETRANS)
-#define TCPCB_URG 0x20 /* Urgent pointer advenced here */
+#define TCPCB_URG 0x20 /* Urgent pointer advanced here */
#define TCPCB_AT_TAIL (TCPCB_URG)
@@ -764,6 +766,33 @@ static inline __u32 tcp_current_ssthresh(const struct sock *sk)
(tp->snd_cwnd >> 2)));
}
+/*
+ * Linear increase during slow start
+ */
+static inline void tcp_slow_start(struct tcp_sock *tp)
+{
+ if (sysctl_tcp_abc) {
+ /* RFC3465: Slow Start
+ * TCP sender SHOULD increase cwnd by the number of
+ * previously unacknowledged bytes ACKed by each incoming
+ * acknowledgment, provided the increase is not more than L
+ */
+ if (tp->bytes_acked < tp->mss_cache)
+ return;
+
+ /* We MAY increase by 2 if discovered delayed ack */
+ if (sysctl_tcp_abc > 1 && tp->bytes_acked > 2*tp->mss_cache) {
+ if (tp->snd_cwnd < tp->snd_cwnd_clamp)
+ tp->snd_cwnd++;
+ }
+ }
+ tp->bytes_acked = 0;
+
+ if (tp->snd_cwnd < tp->snd_cwnd_clamp)
+ tp->snd_cwnd++;
+}
+
+
static inline void tcp_sync_left_out(struct tcp_sock *tp)
{
if (tp->rx_opt.sack_ok &&
@@ -793,6 +822,7 @@ static inline void tcp_enter_cwr(struct sock *sk)
struct tcp_sock *tp = tcp_sk(sk);
tp->prior_ssthresh = 0;
+ tp->bytes_acked = 0;
if (inet_csk(sk)->icsk_ca_state < TCP_CA_CWR) {
__tcp_enter_cwr(sk);
tcp_set_ca_state(sk, TCP_CA_CWR);
@@ -809,6 +839,27 @@ static __inline__ __u32 tcp_max_burst(const struct tcp_sock *tp)
return 3;
}
+/* RFC2861 Check whether we are limited by application or congestion window
+ * This is the inverse of cwnd check in tcp_tso_should_defer
+ */
+static inline int tcp_is_cwnd_limited(const struct sock *sk, u32 in_flight)
+{
+ const struct tcp_sock *tp = tcp_sk(sk);
+ u32 left;
+
+ if (in_flight >= tp->snd_cwnd)
+ return 1;
+
+ if (!(sk->sk_route_caps & NETIF_F_TSO))
+ return 0;
+
+ left = tp->snd_cwnd - in_flight;
+ if (sysctl_tcp_tso_win_divisor)
+ return left * sysctl_tcp_tso_win_divisor < tp->snd_cwnd;
+ else
+ return left <= tcp_max_burst(tp);
+}
+
static __inline__ void tcp_minshall_update(struct tcp_sock *tp, int mss,
const struct sk_buff *skb)
{
@@ -852,7 +903,7 @@ static __inline__ u16 tcp_v4_check(struct tcphdr *th, int len,
static __inline__ int __tcp_checksum_complete(struct sk_buff *skb)
{
- return (unsigned short)csum_fold(skb_checksum(skb, 0, skb->len, skb->csum));
+ return __skb_checksum_complete(skb);
}
static __inline__ int tcp_checksum_complete(struct sk_buff *skb)
@@ -1156,6 +1207,15 @@ static inline void tcp_mib_init(void)
TCP_ADD_STATS_USER(TCP_MIB_MAXCONN, -1);
}
+/*from STCP */
+static inline void clear_all_retrans_hints(struct tcp_sock *tp){
+ tp->lost_skb_hint = NULL;
+ tp->scoreboard_skb_hint = NULL;
+ tp->retransmit_skb_hint = NULL;
+ tp->forward_skb_hint = NULL;
+ tp->fastpath_skb_hint = NULL;
+}
+
/* /proc */
enum tcp_seq_states {
TCP_SEQ_STATE_LISTENING,
diff --git a/include/pcmcia/ss.h b/include/pcmcia/ss.h
index c8592c7e8eaa..e788bbc5657d 100644
--- a/include/pcmcia/ss.h
+++ b/include/pcmcia/ss.h
@@ -17,6 +17,7 @@
#include <linux/config.h>
#include <linux/device.h>
+#include <linux/sched.h> /* task_struct, completion */
#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
diff --git a/include/rdma/ib_cm.h b/include/rdma/ib_cm.h
index 5308683c8c41..0a9fcd59eb43 100644
--- a/include/rdma/ib_cm.h
+++ b/include/rdma/ib_cm.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004 Intel Corporation. All rights reserved.
+ * Copyright (c) 2004, 2005 Intel Corporation. All rights reserved.
* Copyright (c) 2004 Topspin Corporation. All rights reserved.
* Copyright (c) 2004 Voltaire Corporation. All rights reserved.
* Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
@@ -109,7 +109,6 @@ struct ib_cm_id;
struct ib_cm_req_event_param {
struct ib_cm_id *listen_id;
- struct ib_device *device;
u8 port;
struct ib_sa_path_rec *primary_path;
@@ -220,7 +219,6 @@ struct ib_cm_apr_event_param {
struct ib_cm_sidr_req_event_param {
struct ib_cm_id *listen_id;
- struct ib_device *device;
u8 port;
u16 pkey;
};
@@ -284,6 +282,7 @@ typedef int (*ib_cm_handler)(struct ib_cm_id *cm_id,
struct ib_cm_id {
ib_cm_handler cm_handler;
void *context;
+ struct ib_device *device;
__be64 service_id;
__be64 service_mask;
enum ib_cm_state state; /* internal CM/debug use */
@@ -295,6 +294,8 @@ struct ib_cm_id {
/**
* ib_create_cm_id - Allocate a communication identifier.
+ * @device: Device associated with the cm_id. All related communication will
+ * be associated with the specified device.
* @cm_handler: Callback invoked to notify the user of CM events.
* @context: User specified context associated with the communication
* identifier.
@@ -302,7 +303,8 @@ struct ib_cm_id {
* Communication identifiers are used to track connection states, service
* ID resolution requests, and listen requests.
*/
-struct ib_cm_id *ib_create_cm_id(ib_cm_handler cm_handler,
+struct ib_cm_id *ib_create_cm_id(struct ib_device *device,
+ ib_cm_handler cm_handler,
void *context);
/**
diff --git a/include/rdma/ib_mad.h b/include/rdma/ib_mad.h
index 4172e6841e3d..2c133506742b 100644
--- a/include/rdma/ib_mad.h
+++ b/include/rdma/ib_mad.h
@@ -109,10 +109,14 @@
#define IB_QP_SET_QKEY 0x80000000
enum {
+ IB_MGMT_MAD_HDR = 24,
IB_MGMT_MAD_DATA = 232,
+ IB_MGMT_RMPP_HDR = 36,
IB_MGMT_RMPP_DATA = 220,
+ IB_MGMT_VENDOR_HDR = 40,
IB_MGMT_VENDOR_DATA = 216,
- IB_MGMT_SA_DATA = 200
+ IB_MGMT_SA_HDR = 56,
+ IB_MGMT_SA_DATA = 200,
};
struct ib_mad_hdr {
@@ -203,26 +207,25 @@ struct ib_class_port_info
/**
* ib_mad_send_buf - MAD data buffer and work request for sends.
- * @mad: References an allocated MAD data buffer. The size of the data
- * buffer is specified in the @send_wr.length field.
- * @mapping: DMA mapping information.
+ * @next: A pointer used to chain together MADs for posting.
+ * @mad: References an allocated MAD data buffer.
* @mad_agent: MAD agent that allocated the buffer.
+ * @ah: The address handle to use when sending the MAD.
* @context: User-controlled context fields.
- * @send_wr: An initialized work request structure used when sending the MAD.
- * The wr_id field of the work request is initialized to reference this
- * data structure.
- * @sge: A scatter-gather list referenced by the work request.
+ * @timeout_ms: Time to wait for a response.
+ * @retries: Number of times to retry a request for a response.
*
* Users are responsible for initializing the MAD buffer itself, with the
* exception of specifying the payload length field in any RMPP MAD.
*/
struct ib_mad_send_buf {
- struct ib_mad *mad;
- DECLARE_PCI_UNMAP_ADDR(mapping)
+ struct ib_mad_send_buf *next;
+ void *mad;
struct ib_mad_agent *mad_agent;
+ struct ib_ah *ah;
void *context[2];
- struct ib_send_wr send_wr;
- struct ib_sge sge;
+ int timeout_ms;
+ int retries;
};
/**
@@ -287,7 +290,7 @@ typedef void (*ib_mad_send_handler)(struct ib_mad_agent *mad_agent,
* or @mad_send_wc.
*/
typedef void (*ib_mad_snoop_handler)(struct ib_mad_agent *mad_agent,
- struct ib_send_wr *send_wr,
+ struct ib_mad_send_buf *send_buf,
struct ib_mad_send_wc *mad_send_wc);
/**
@@ -334,13 +337,13 @@ struct ib_mad_agent {
/**
* ib_mad_send_wc - MAD send completion information.
- * @wr_id: Work request identifier associated with the send MAD request.
+ * @send_buf: Send MAD data buffer associated with the send MAD request.
* @status: Completion status.
* @vendor_err: Optional vendor error information returned with a failed
* request.
*/
struct ib_mad_send_wc {
- u64 wr_id;
+ struct ib_mad_send_buf *send_buf;
enum ib_wc_status status;
u32 vendor_err;
};
@@ -366,7 +369,7 @@ struct ib_mad_recv_buf {
* @rmpp_list: Specifies a list of RMPP reassembled received MAD buffers.
* @mad_len: The length of the received MAD, without duplicated headers.
*
- * For received response, the wr_id field of the wc is set to the wr_id
+ * For received response, the wr_id contains a pointer to the ib_mad_send_buf
* for the corresponding send request.
*/
struct ib_mad_recv_wc {
@@ -463,9 +466,9 @@ int ib_unregister_mad_agent(struct ib_mad_agent *mad_agent);
/**
* ib_post_send_mad - Posts MAD(s) to the send queue of the QP associated
* with the registered client.
- * @mad_agent: Specifies the associated registration to post the send to.
- * @send_wr: Specifies the information needed to send the MAD(s).
- * @bad_send_wr: Specifies the MAD on which an error was encountered.
+ * @send_buf: Specifies the information needed to send the MAD(s).
+ * @bad_send_buf: Specifies the MAD on which an error was encountered. This
+ * parameter is optional if only a single MAD is posted.
*
* Sent MADs are not guaranteed to complete in the order that they were posted.
*
@@ -479,9 +482,8 @@ int ib_unregister_mad_agent(struct ib_mad_agent *mad_agent);
* defined data being transferred. The paylen_newwin field should be
* specified in network-byte order.
*/
-int ib_post_send_mad(struct ib_mad_agent *mad_agent,
- struct ib_send_wr *send_wr,
- struct ib_send_wr **bad_send_wr);
+int ib_post_send_mad(struct ib_mad_send_buf *send_buf,
+ struct ib_mad_send_buf **bad_send_buf);
/**
* ib_coalesce_recv_mad - Coalesces received MAD data into a single buffer.
@@ -507,23 +509,25 @@ void ib_free_recv_mad(struct ib_mad_recv_wc *mad_recv_wc);
/**
* ib_cancel_mad - Cancels an outstanding send MAD operation.
* @mad_agent: Specifies the registration associated with sent MAD.
- * @wr_id: Indicates the work request identifier of the MAD to cancel.
+ * @send_buf: Indicates the MAD to cancel.
*
* MADs will be returned to the user through the corresponding
* ib_mad_send_handler.
*/
-void ib_cancel_mad(struct ib_mad_agent *mad_agent, u64 wr_id);
+void ib_cancel_mad(struct ib_mad_agent *mad_agent,
+ struct ib_mad_send_buf *send_buf);
/**
* ib_modify_mad - Modifies an outstanding send MAD operation.
* @mad_agent: Specifies the registration associated with sent MAD.
- * @wr_id: Indicates the work request identifier of the MAD to modify.
+ * @send_buf: Indicates the MAD to modify.
* @timeout_ms: New timeout value for sent MAD.
*
* This call will reset the timeout value for a sent MAD to the specified
* value.
*/
-int ib_modify_mad(struct ib_mad_agent *mad_agent, u64 wr_id, u32 timeout_ms);
+int ib_modify_mad(struct ib_mad_agent *mad_agent,
+ struct ib_mad_send_buf *send_buf, u32 timeout_ms);
/**
* ib_redirect_mad_qp - Registers a QP for MAD services.
@@ -572,7 +576,6 @@ int ib_process_mad_wc(struct ib_mad_agent *mad_agent,
* @remote_qpn: Specifies the QPN of the receiving node.
* @pkey_index: Specifies which PKey the MAD will be sent using. This field
* is valid only if the remote_qpn is QP 1.
- * @ah: References the address handle used to transfer to the remote node.
* @rmpp_active: Indicates if the send will enable RMPP.
* @hdr_len: Indicates the size of the data header of the MAD. This length
* should include the common MAD header, RMPP header, plus any class
@@ -582,11 +585,10 @@ int ib_process_mad_wc(struct ib_mad_agent *mad_agent,
* additional padding that may be necessary.
* @gfp_mask: GFP mask used for the memory allocation.
*
- * This is a helper routine that may be used to allocate a MAD. Users are
- * not required to allocate outbound MADs using this call. The returned
- * MAD send buffer will reference a data buffer usable for sending a MAD, along
+ * This routine allocates a MAD for sending. The returned MAD send buffer
+ * will reference a data buffer usable for sending a MAD, along
* with an initialized work request structure. Users may modify the returned
- * MAD data buffer or work request before posting the send.
+ * MAD data buffer before posting the send.
*
* The returned data buffer will be cleared. Users are responsible for
* initializing the common MAD and any class specific headers. If @rmpp_active
@@ -594,7 +596,7 @@ int ib_process_mad_wc(struct ib_mad_agent *mad_agent,
*/
struct ib_mad_send_buf * ib_create_send_mad(struct ib_mad_agent *mad_agent,
u32 remote_qpn, u16 pkey_index,
- struct ib_ah *ah, int rmpp_active,
+ int rmpp_active,
int hdr_len, int data_len,
gfp_t gfp_mask);
diff --git a/include/rdma/ib_user_cm.h b/include/rdma/ib_user_cm.h
index e4d1654276ad..19be116047f6 100644
--- a/include/rdma/ib_user_cm.h
+++ b/include/rdma/ib_user_cm.h
@@ -38,7 +38,7 @@
#include <linux/types.h>
-#define IB_USER_CM_ABI_VERSION 2
+#define IB_USER_CM_ABI_VERSION 4
enum {
IB_USER_CM_CMD_CREATE_ID,
@@ -84,6 +84,7 @@ struct ib_ucm_create_id_resp {
struct ib_ucm_destroy_id {
__u64 response;
__u32 id;
+ __u32 reserved;
};
struct ib_ucm_destroy_id_resp {
@@ -93,6 +94,7 @@ struct ib_ucm_destroy_id_resp {
struct ib_ucm_attr_id {
__u64 response;
__u32 id;
+ __u32 reserved;
};
struct ib_ucm_attr_id_resp {
@@ -164,6 +166,7 @@ struct ib_ucm_listen {
__be64 service_id;
__be64 service_mask;
__u32 id;
+ __u32 reserved;
};
struct ib_ucm_establish {
@@ -219,7 +222,7 @@ struct ib_ucm_req {
__u8 rnr_retry_count;
__u8 max_cm_retries;
__u8 srq;
- __u8 reserved[1];
+ __u8 reserved[5];
};
struct ib_ucm_rep {
@@ -236,6 +239,7 @@ struct ib_ucm_rep {
__u8 flow_control;
__u8 rnr_retry_count;
__u8 srq;
+ __u8 reserved[4];
};
struct ib_ucm_info {
@@ -245,7 +249,7 @@ struct ib_ucm_info {
__u64 data;
__u8 info_len;
__u8 data_len;
- __u8 reserved[2];
+ __u8 reserved[6];
};
struct ib_ucm_mra {
@@ -273,6 +277,7 @@ struct ib_ucm_sidr_req {
__u16 pkey;
__u8 len;
__u8 max_cm_retries;
+ __u8 reserved[4];
};
struct ib_ucm_sidr_rep {
@@ -284,7 +289,7 @@ struct ib_ucm_sidr_rep {
__u64 data;
__u8 info_len;
__u8 data_len;
- __u8 reserved[2];
+ __u8 reserved[6];
};
/*
* event notification ABI structures.
@@ -295,12 +300,10 @@ struct ib_ucm_event_get {
__u64 info;
__u8 data_len;
__u8 info_len;
- __u8 reserved[2];
+ __u8 reserved[6];
};
struct ib_ucm_req_event_resp {
- /* device */
- /* port */
struct ib_ucm_path_rec primary_path;
struct ib_ucm_path_rec alternate_path;
__be64 remote_ca_guid;
@@ -316,6 +319,8 @@ struct ib_ucm_req_event_resp {
__u8 retry_count;
__u8 rnr_retry_count;
__u8 srq;
+ __u8 port;
+ __u8 reserved[7];
};
struct ib_ucm_rep_event_resp {
@@ -330,7 +335,7 @@ struct ib_ucm_rep_event_resp {
__u8 flow_control;
__u8 rnr_retry_count;
__u8 srq;
- __u8 reserved[1];
+ __u8 reserved[5];
};
struct ib_ucm_rej_event_resp {
@@ -353,10 +358,9 @@ struct ib_ucm_apr_event_resp {
};
struct ib_ucm_sidr_req_event_resp {
- /* device */
- /* port */
__u16 pkey;
- __u8 reserved[2];
+ __u8 port;
+ __u8 reserved;
};
struct ib_ucm_sidr_rep_event_resp {
@@ -376,6 +380,7 @@ struct ib_ucm_event_resp {
__u32 id;
__u32 event;
__u32 present;
+ __u32 reserved;
union {
struct ib_ucm_req_event_resp req_resp;
struct ib_ucm_rep_event_resp rep_resp;
diff --git a/include/rdma/ib_user_verbs.h b/include/rdma/ib_user_verbs.h
index fd85725391a4..5ff1490c08db 100644
--- a/include/rdma/ib_user_verbs.h
+++ b/include/rdma/ib_user_verbs.h
@@ -1,6 +1,7 @@
/*
* Copyright (c) 2005 Topspin Communications. All rights reserved.
* Copyright (c) 2005 Cisco Systems. All rights reserved.
+ * Copyright (c) 2005 PathScale, Inc. All rights reserved.
*
* This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU
@@ -42,15 +43,12 @@
* Increment this value if any changes that break userspace ABI
* compatibility are made.
*/
-#define IB_USER_VERBS_ABI_VERSION 2
+#define IB_USER_VERBS_ABI_VERSION 4
enum {
- IB_USER_VERBS_CMD_QUERY_PARAMS,
IB_USER_VERBS_CMD_GET_CONTEXT,
IB_USER_VERBS_CMD_QUERY_DEVICE,
IB_USER_VERBS_CMD_QUERY_PORT,
- IB_USER_VERBS_CMD_QUERY_GID,
- IB_USER_VERBS_CMD_QUERY_PKEY,
IB_USER_VERBS_CMD_ALLOC_PD,
IB_USER_VERBS_CMD_DEALLOC_PD,
IB_USER_VERBS_CMD_CREATE_AH,
@@ -65,6 +63,7 @@ enum {
IB_USER_VERBS_CMD_ALLOC_MW,
IB_USER_VERBS_CMD_BIND_MW,
IB_USER_VERBS_CMD_DEALLOC_MW,
+ IB_USER_VERBS_CMD_CREATE_COMP_CHANNEL,
IB_USER_VERBS_CMD_CREATE_CQ,
IB_USER_VERBS_CMD_RESIZE_CQ,
IB_USER_VERBS_CMD_DESTROY_CQ,
@@ -90,8 +89,11 @@ enum {
* Make sure that all structs defined in this file remain laid out so
* that they pack the same way on 32-bit and 64-bit architectures (to
* avoid incompatibility between 32-bit userspace and 64-bit kernels).
- * In particular do not use pointer types -- pass pointers in __u64
- * instead.
+ * Specifically:
+ * - Do not use pointer types -- pass pointers in __u64 instead.
+ * - Make sure that any structure larger than 4 bytes is padded to a
+ * multiple of 8 bytes. Otherwise the structure size will be
+ * different between 32-bit and 64-bit architectures.
*/
struct ib_uverbs_async_event_desc {
@@ -118,27 +120,14 @@ struct ib_uverbs_cmd_hdr {
__u16 out_words;
};
-/*
- * No driver_data for "query params" command, since this is intended
- * to be a core function with no possible device dependence.
- */
-struct ib_uverbs_query_params {
- __u64 response;
-};
-
-struct ib_uverbs_query_params_resp {
- __u32 num_cq_events;
-};
-
struct ib_uverbs_get_context {
__u64 response;
- __u64 cq_fd_tab;
__u64 driver_data[0];
};
struct ib_uverbs_get_context_resp {
__u32 async_fd;
- __u32 reserved;
+ __u32 num_comp_vectors;
};
struct ib_uverbs_query_device {
@@ -220,31 +209,6 @@ struct ib_uverbs_query_port_resp {
__u8 reserved[3];
};
-struct ib_uverbs_query_gid {
- __u64 response;
- __u8 port_num;
- __u8 index;
- __u8 reserved[6];
- __u64 driver_data[0];
-};
-
-struct ib_uverbs_query_gid_resp {
- __u8 gid[16];
-};
-
-struct ib_uverbs_query_pkey {
- __u64 response;
- __u8 port_num;
- __u8 index;
- __u8 reserved[6];
- __u64 driver_data[0];
-};
-
-struct ib_uverbs_query_pkey_resp {
- __u16 pkey;
- __u16 reserved;
-};
-
struct ib_uverbs_alloc_pd {
__u64 response;
__u64 driver_data[0];
@@ -278,11 +242,21 @@ struct ib_uverbs_dereg_mr {
__u32 mr_handle;
};
+struct ib_uverbs_create_comp_channel {
+ __u64 response;
+};
+
+struct ib_uverbs_create_comp_channel_resp {
+ __u32 fd;
+};
+
struct ib_uverbs_create_cq {
__u64 response;
__u64 user_handle;
__u32 cqe;
- __u32 event_handler;
+ __u32 comp_vector;
+ __s32 comp_channel;
+ __u32 reserved;
__u64 driver_data[0];
};
@@ -291,6 +265,41 @@ struct ib_uverbs_create_cq_resp {
__u32 cqe;
};
+struct ib_uverbs_poll_cq {
+ __u64 response;
+ __u32 cq_handle;
+ __u32 ne;
+};
+
+struct ib_uverbs_wc {
+ __u64 wr_id;
+ __u32 status;
+ __u32 opcode;
+ __u32 vendor_err;
+ __u32 byte_len;
+ __u32 imm_data;
+ __u32 qp_num;
+ __u32 src_qp;
+ __u32 wc_flags;
+ __u16 pkey_index;
+ __u16 slid;
+ __u8 sl;
+ __u8 dlid_path_bits;
+ __u8 port_num;
+ __u8 reserved;
+};
+
+struct ib_uverbs_poll_cq_resp {
+ __u32 count;
+ __u32 reserved;
+ struct ib_uverbs_wc wc[0];
+};
+
+struct ib_uverbs_req_notify_cq {
+ __u32 cq_handle;
+ __u32 solicited_only;
+};
+
struct ib_uverbs_destroy_cq {
__u64 response;
__u32 cq_handle;
@@ -324,6 +333,11 @@ struct ib_uverbs_create_qp {
struct ib_uverbs_create_qp_resp {
__u32 qp_handle;
__u32 qpn;
+ __u32 max_send_wr;
+ __u32 max_recv_wr;
+ __u32 max_send_sge;
+ __u32 max_recv_sge;
+ __u32 max_inline_data;
};
/*
@@ -388,6 +402,127 @@ struct ib_uverbs_destroy_qp_resp {
__u32 events_reported;
};
+/*
+ * The ib_uverbs_sge structure isn't used anywhere, since we assume
+ * the ib_sge structure is packed the same way on 32-bit and 64-bit
+ * architectures in both kernel and user space. It's just here to
+ * document the ABI.
+ */
+struct ib_uverbs_sge {
+ __u64 addr;
+ __u32 length;
+ __u32 lkey;
+};
+
+struct ib_uverbs_send_wr {
+ __u64 wr_id;
+ __u32 num_sge;
+ __u32 opcode;
+ __u32 send_flags;
+ __u32 imm_data;
+ union {
+ struct {
+ __u64 remote_addr;
+ __u32 rkey;
+ __u32 reserved;
+ } rdma;
+ struct {
+ __u64 remote_addr;
+ __u64 compare_add;
+ __u64 swap;
+ __u32 rkey;
+ __u32 reserved;
+ } atomic;
+ struct {
+ __u32 ah;
+ __u32 remote_qpn;
+ __u32 remote_qkey;
+ __u32 reserved;
+ } ud;
+ } wr;
+};
+
+struct ib_uverbs_post_send {
+ __u64 response;
+ __u32 qp_handle;
+ __u32 wr_count;
+ __u32 sge_count;
+ __u32 wqe_size;
+ struct ib_uverbs_send_wr send_wr[0];
+};
+
+struct ib_uverbs_post_send_resp {
+ __u32 bad_wr;
+};
+
+struct ib_uverbs_recv_wr {
+ __u64 wr_id;
+ __u32 num_sge;
+ __u32 reserved;
+};
+
+struct ib_uverbs_post_recv {
+ __u64 response;
+ __u32 qp_handle;
+ __u32 wr_count;
+ __u32 sge_count;
+ __u32 wqe_size;
+ struct ib_uverbs_recv_wr recv_wr[0];
+};
+
+struct ib_uverbs_post_recv_resp {
+ __u32 bad_wr;
+};
+
+struct ib_uverbs_post_srq_recv {
+ __u64 response;
+ __u32 srq_handle;
+ __u32 wr_count;
+ __u32 sge_count;
+ __u32 wqe_size;
+ struct ib_uverbs_recv_wr recv[0];
+};
+
+struct ib_uverbs_post_srq_recv_resp {
+ __u32 bad_wr;
+};
+
+struct ib_uverbs_global_route {
+ __u8 dgid[16];
+ __u32 flow_label;
+ __u8 sgid_index;
+ __u8 hop_limit;
+ __u8 traffic_class;
+ __u8 reserved;
+};
+
+struct ib_uverbs_ah_attr {
+ struct ib_uverbs_global_route grh;
+ __u16 dlid;
+ __u8 sl;
+ __u8 src_path_bits;
+ __u8 static_rate;
+ __u8 is_global;
+ __u8 port_num;
+ __u8 reserved;
+};
+
+struct ib_uverbs_create_ah {
+ __u64 response;
+ __u64 user_handle;
+ __u32 pd_handle;
+ __u32 reserved;
+ struct ib_uverbs_ah_attr attr;
+};
+
+struct ib_uverbs_create_ah_resp {
+ __u32 ah_handle;
+};
+
+struct ib_uverbs_destroy_ah {
+ __u32 ah_handle;
+};
+
struct ib_uverbs_attach_mcast {
__u8 gid[16];
__u32 qp_handle;
@@ -422,9 +557,7 @@ struct ib_uverbs_modify_srq {
__u32 srq_handle;
__u32 attr_mask;
__u32 max_wr;
- __u32 max_sge;
__u32 srq_limit;
- __u32 reserved;
__u64 driver_data[0];
};
diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h
index e6f4c9e55df7..a7f4c355a91f 100644
--- a/include/rdma/ib_verbs.h
+++ b/include/rdma/ib_verbs.h
@@ -595,11 +595,8 @@ struct ib_send_wr {
} atomic;
struct {
struct ib_ah *ah;
- struct ib_mad_hdr *mad_hdr;
u32 remote_qpn;
u32 remote_qkey;
- int timeout_ms; /* valid for MADs only */
- int retries; /* valid for MADs only */
u16 pkey_index; /* valid for GSI only */
u8 port_num; /* valid for DR SMPs on switch only */
} ud;
@@ -884,7 +881,7 @@ struct ib_device {
struct ib_ucontext *context,
struct ib_udata *udata);
int (*destroy_cq)(struct ib_cq *cq);
- int (*resize_cq)(struct ib_cq *cq, int *cqe);
+ int (*resize_cq)(struct ib_cq *cq, int cqe);
int (*poll_cq)(struct ib_cq *cq, int num_entries,
struct ib_wc *wc);
int (*peek_cq)(struct ib_cq *cq, int wc_cnt);
@@ -951,6 +948,9 @@ struct ib_device {
IB_DEV_UNREGISTERED
} reg_state;
+ u64 uverbs_cmd_mask;
+ int uverbs_abi_ver;
+
u8 node_type;
u8 phys_port_cnt;
};
diff --git a/include/scsi/iscsi_if.h b/include/scsi/iscsi_if.h
new file mode 100644
index 000000000000..be1bc792ab18
--- /dev/null
+++ b/include/scsi/iscsi_if.h
@@ -0,0 +1,245 @@
+/*
+ * iSCSI User/Kernel Shares (Defines, Constants, Protocol definitions, etc)
+ *
+ * Copyright (C) 2005 Dmitry Yusupov
+ * Copyright (C) 2005 Alex Aizman
+ * maintained by open-iscsi@googlegroups.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.
+ *
+ * See the file COPYING included with this distribution for more details.
+ */
+
+#ifndef ISCSI_IF_H
+#define ISCSI_IF_H
+
+#include <scsi/iscsi_proto.h>
+
+#define UEVENT_BASE 10
+#define KEVENT_BASE 100
+#define ISCSI_ERR_BASE 1000
+
+enum iscsi_uevent_e {
+ ISCSI_UEVENT_UNKNOWN = 0,
+
+ /* down events */
+ ISCSI_UEVENT_CREATE_SESSION = UEVENT_BASE + 1,
+ ISCSI_UEVENT_DESTROY_SESSION = UEVENT_BASE + 2,
+ ISCSI_UEVENT_CREATE_CONN = UEVENT_BASE + 3,
+ ISCSI_UEVENT_DESTROY_CONN = UEVENT_BASE + 4,
+ ISCSI_UEVENT_BIND_CONN = UEVENT_BASE + 5,
+ ISCSI_UEVENT_SET_PARAM = UEVENT_BASE + 6,
+ ISCSI_UEVENT_START_CONN = UEVENT_BASE + 7,
+ ISCSI_UEVENT_STOP_CONN = UEVENT_BASE + 8,
+ ISCSI_UEVENT_SEND_PDU = UEVENT_BASE + 9,
+ ISCSI_UEVENT_GET_STATS = UEVENT_BASE + 10,
+ ISCSI_UEVENT_GET_PARAM = UEVENT_BASE + 11,
+
+ /* up events */
+ ISCSI_KEVENT_RECV_PDU = KEVENT_BASE + 1,
+ ISCSI_KEVENT_CONN_ERROR = KEVENT_BASE + 2,
+ ISCSI_KEVENT_IF_ERROR = KEVENT_BASE + 3,
+};
+
+struct iscsi_uevent {
+ uint32_t type; /* k/u events type */
+ uint32_t iferror; /* carries interface or resource errors */
+ uint64_t transport_handle;
+
+ union {
+ /* messages u -> k */
+ struct msg_create_session {
+ uint32_t initial_cmdsn;
+ } c_session;
+ struct msg_destroy_session {
+ uint64_t session_handle;
+ uint32_t sid;
+ } d_session;
+ struct msg_create_conn {
+ uint64_t session_handle;
+ uint32_t cid;
+ uint32_t sid;
+ } c_conn;
+ struct msg_bind_conn {
+ uint64_t session_handle;
+ uint64_t conn_handle;
+ uint32_t transport_fd;
+ uint32_t is_leading;
+ } b_conn;
+ struct msg_destroy_conn {
+ uint64_t conn_handle;
+ uint32_t cid;
+ } d_conn;
+ struct msg_send_pdu {
+ uint32_t hdr_size;
+ uint32_t data_size;
+ uint64_t conn_handle;
+ } send_pdu;
+ struct msg_set_param {
+ uint64_t conn_handle;
+ uint32_t param; /* enum iscsi_param */
+ uint32_t value;
+ } set_param;
+ struct msg_start_conn {
+ uint64_t conn_handle;
+ } start_conn;
+ struct msg_stop_conn {
+ uint64_t conn_handle;
+ uint32_t flag;
+ } stop_conn;
+ struct msg_get_stats {
+ uint64_t conn_handle;
+ } get_stats;
+ } u;
+ union {
+ /* messages k -> u */
+ uint64_t handle;
+ int retcode;
+ struct msg_create_session_ret {
+ uint64_t session_handle;
+ uint32_t sid;
+ } c_session_ret;
+ struct msg_recv_req {
+ uint64_t recv_handle;
+ uint64_t conn_handle;
+ } recv_req;
+ struct msg_conn_error {
+ uint64_t conn_handle;
+ uint32_t error; /* enum iscsi_err */
+ } connerror;
+ } r;
+} __attribute__ ((aligned (sizeof(uint64_t))));
+
+/*
+ * Common error codes
+ */
+enum iscsi_err {
+ ISCSI_OK = 0,
+
+ ISCSI_ERR_DATASN = ISCSI_ERR_BASE + 1,
+ ISCSI_ERR_DATA_OFFSET = ISCSI_ERR_BASE + 2,
+ ISCSI_ERR_MAX_CMDSN = ISCSI_ERR_BASE + 3,
+ ISCSI_ERR_EXP_CMDSN = ISCSI_ERR_BASE + 4,
+ ISCSI_ERR_BAD_OPCODE = ISCSI_ERR_BASE + 5,
+ ISCSI_ERR_DATALEN = ISCSI_ERR_BASE + 6,
+ ISCSI_ERR_AHSLEN = ISCSI_ERR_BASE + 7,
+ ISCSI_ERR_PROTO = ISCSI_ERR_BASE + 8,
+ ISCSI_ERR_LUN = ISCSI_ERR_BASE + 9,
+ ISCSI_ERR_BAD_ITT = ISCSI_ERR_BASE + 10,
+ ISCSI_ERR_CONN_FAILED = ISCSI_ERR_BASE + 11,
+ ISCSI_ERR_R2TSN = ISCSI_ERR_BASE + 12,
+ ISCSI_ERR_SESSION_FAILED = ISCSI_ERR_BASE + 13,
+ ISCSI_ERR_HDR_DGST = ISCSI_ERR_BASE + 14,
+ ISCSI_ERR_DATA_DGST = ISCSI_ERR_BASE + 15,
+ ISCSI_ERR_PARAM_NOT_FOUND = ISCSI_ERR_BASE + 16
+};
+
+/*
+ * iSCSI Parameters (RFC3720)
+ */
+enum iscsi_param {
+ ISCSI_PARAM_MAX_RECV_DLENGTH = 0,
+ ISCSI_PARAM_MAX_XMIT_DLENGTH = 1,
+ ISCSI_PARAM_HDRDGST_EN = 2,
+ ISCSI_PARAM_DATADGST_EN = 3,
+ ISCSI_PARAM_INITIAL_R2T_EN = 4,
+ ISCSI_PARAM_MAX_R2T = 5,
+ ISCSI_PARAM_IMM_DATA_EN = 6,
+ ISCSI_PARAM_FIRST_BURST = 7,
+ ISCSI_PARAM_MAX_BURST = 8,
+ ISCSI_PARAM_PDU_INORDER_EN = 9,
+ ISCSI_PARAM_DATASEQ_INORDER_EN = 10,
+ ISCSI_PARAM_ERL = 11,
+ ISCSI_PARAM_IFMARKER_EN = 12,
+ ISCSI_PARAM_OFMARKER_EN = 13,
+};
+#define ISCSI_PARAM_MAX 14
+
+typedef uint64_t iscsi_sessionh_t; /* iSCSI Data-Path session handle */
+typedef uint64_t iscsi_connh_t; /* iSCSI Data-Path connection handle */
+
+#define iscsi_ptr(_handle) ((void*)(unsigned long)_handle)
+#define iscsi_handle(_ptr) ((uint64_t)(unsigned long)_ptr)
+#define iscsi_hostdata(_hostdata) ((void*)_hostdata + sizeof(unsigned long))
+
+/*
+ * These flags presents iSCSI Data-Path capabilities.
+ */
+#define CAP_RECOVERY_L0 0x1
+#define CAP_RECOVERY_L1 0x2
+#define CAP_RECOVERY_L2 0x4
+#define CAP_MULTI_R2T 0x8
+#define CAP_HDRDGST 0x10
+#define CAP_DATADGST 0x20
+#define CAP_MULTI_CONN 0x40
+#define CAP_TEXT_NEGO 0x80
+#define CAP_MARKERS 0x100
+
+/*
+ * These flags describes reason of stop_conn() call
+ */
+#define STOP_CONN_TERM 0x1
+#define STOP_CONN_SUSPEND 0x2
+#define STOP_CONN_RECOVER 0x3
+
+#define ISCSI_STATS_CUSTOM_MAX 32
+#define ISCSI_STATS_CUSTOM_DESC_MAX 64
+struct iscsi_stats_custom {
+ char desc[ISCSI_STATS_CUSTOM_DESC_MAX];
+ uint64_t value;
+};
+
+/*
+ * struct iscsi_stats - iSCSI Statistics (iSCSI MIB)
+ *
+ * Note: this structure contains counters collected on per-connection basis.
+ */
+struct iscsi_stats {
+ /* octets */
+ uint64_t txdata_octets;
+ uint64_t rxdata_octets;
+
+ /* xmit pdus */
+ uint32_t noptx_pdus;
+ uint32_t scsicmd_pdus;
+ uint32_t tmfcmd_pdus;
+ uint32_t login_pdus;
+ uint32_t text_pdus;
+ uint32_t dataout_pdus;
+ uint32_t logout_pdus;
+ uint32_t snack_pdus;
+
+ /* recv pdus */
+ uint32_t noprx_pdus;
+ uint32_t scsirsp_pdus;
+ uint32_t tmfrsp_pdus;
+ uint32_t textrsp_pdus;
+ uint32_t datain_pdus;
+ uint32_t logoutrsp_pdus;
+ uint32_t r2t_pdus;
+ uint32_t async_pdus;
+ uint32_t rjt_pdus;
+
+ /* errors */
+ uint32_t digest_err;
+ uint32_t timeout_err;
+
+ /*
+ * iSCSI Custom Statistics support, i.e. Transport could
+ * extend existing MIB statistics with its own specific statistics
+ * up to ISCSI_STATS_CUSTOM_MAX
+ */
+ uint32_t custom_length;
+ struct iscsi_stats_custom custom[0]
+ __attribute__ ((aligned (sizeof(uint64_t))));
+};
+
+#endif
diff --git a/include/scsi/iscsi_proto.h b/include/scsi/iscsi_proto.h
new file mode 100644
index 000000000000..4feda05fdf25
--- /dev/null
+++ b/include/scsi/iscsi_proto.h
@@ -0,0 +1,589 @@
+/*
+ * RFC 3720 (iSCSI) protocol data types
+ *
+ * Copyright (C) 2005 Dmitry Yusupov
+ * Copyright (C) 2005 Alex Aizman
+ * maintained by open-iscsi@googlegroups.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.
+ *
+ * See the file COPYING included with this distribution for more details.
+ */
+
+#ifndef ISCSI_PROTO_H
+#define ISCSI_PROTO_H
+
+#define ISCSI_VERSION_STR "0.3"
+#define ISCSI_DATE_STR "22-Apr-2005"
+#define ISCSI_DRAFT20_VERSION 0x00
+
+/* default iSCSI listen port for incoming connections */
+#define ISCSI_LISTEN_PORT 3260
+
+/* Padding word length */
+#define PAD_WORD_LEN 4
+
+/*
+ * useful common(control and data pathes) macro
+ */
+#define ntoh24(p) (((p)[0] << 16) | ((p)[1] << 8) | ((p)[2]))
+#define hton24(p, v) { \
+ p[0] = (((v) >> 16) & 0xFF); \
+ p[1] = (((v) >> 8) & 0xFF); \
+ p[2] = ((v) & 0xFF); \
+}
+#define zero_data(p) {p[0]=0;p[1]=0;p[2]=0;}
+
+/*
+ * iSCSI Template Message Header
+ */
+struct iscsi_hdr {
+ uint8_t opcode;
+ uint8_t flags; /* Final bit */
+ uint8_t rsvd2[2];
+ uint8_t hlength; /* AHSs total length */
+ uint8_t dlength[3]; /* Data length */
+ uint8_t lun[8];
+ __be32 itt; /* Initiator Task Tag */
+ __be32 ttt; /* Target Task Tag */
+ __be32 statsn;
+ __be32 exp_statsn;
+ __be32 max_statsn;
+ uint8_t other[12];
+};
+
+/************************* RFC 3720 Begin *****************************/
+
+#define ISCSI_RESERVED_TAG 0xffffffff
+
+/* Opcode encoding bits */
+#define ISCSI_OP_RETRY 0x80
+#define ISCSI_OP_IMMEDIATE 0x40
+#define ISCSI_OPCODE_MASK 0x3F
+
+/* Initiator Opcode values */
+#define ISCSI_OP_NOOP_OUT 0x00
+#define ISCSI_OP_SCSI_CMD 0x01
+#define ISCSI_OP_SCSI_TMFUNC 0x02
+#define ISCSI_OP_LOGIN 0x03
+#define ISCSI_OP_TEXT 0x04
+#define ISCSI_OP_SCSI_DATA_OUT 0x05
+#define ISCSI_OP_LOGOUT 0x06
+#define ISCSI_OP_SNACK 0x10
+
+#define ISCSI_OP_VENDOR1_CMD 0x1c
+#define ISCSI_OP_VENDOR2_CMD 0x1d
+#define ISCSI_OP_VENDOR3_CMD 0x1e
+#define ISCSI_OP_VENDOR4_CMD 0x1f
+
+/* Target Opcode values */
+#define ISCSI_OP_NOOP_IN 0x20
+#define ISCSI_OP_SCSI_CMD_RSP 0x21
+#define ISCSI_OP_SCSI_TMFUNC_RSP 0x22
+#define ISCSI_OP_LOGIN_RSP 0x23
+#define ISCSI_OP_TEXT_RSP 0x24
+#define ISCSI_OP_SCSI_DATA_IN 0x25
+#define ISCSI_OP_LOGOUT_RSP 0x26
+#define ISCSI_OP_R2T 0x31
+#define ISCSI_OP_ASYNC_EVENT 0x32
+#define ISCSI_OP_REJECT 0x3f
+
+struct iscsi_ahs_hdr {
+ __be16 ahslength;
+ uint8_t ahstype;
+ uint8_t ahspec[5];
+};
+
+#define ISCSI_AHSTYPE_CDB 1
+#define ISCSI_AHSTYPE_RLENGTH 2
+
+/* iSCSI PDU Header */
+struct iscsi_cmd {
+ uint8_t opcode;
+ uint8_t flags;
+ __be16 rsvd2;
+ uint8_t hlength;
+ uint8_t dlength[3];
+ uint8_t lun[8];
+ __be32 itt; /* Initiator Task Tag */
+ __be32 data_length;
+ __be32 cmdsn;
+ __be32 exp_statsn;
+ uint8_t cdb[16]; /* SCSI Command Block */
+ /* Additional Data (Command Dependent) */
+};
+
+/* Command PDU flags */
+#define ISCSI_FLAG_CMD_FINAL 0x80
+#define ISCSI_FLAG_CMD_READ 0x40
+#define ISCSI_FLAG_CMD_WRITE 0x20
+#define ISCSI_FLAG_CMD_ATTR_MASK 0x07 /* 3 bits */
+
+/* SCSI Command Attribute values */
+#define ISCSI_ATTR_UNTAGGED 0
+#define ISCSI_ATTR_SIMPLE 1
+#define ISCSI_ATTR_ORDERED 2
+#define ISCSI_ATTR_HEAD_OF_QUEUE 3
+#define ISCSI_ATTR_ACA 4
+
+struct iscsi_rlength_ahdr {
+ __be16 ahslength;
+ uint8_t ahstype;
+ uint8_t reserved;
+ __be32 read_length;
+};
+
+/* SCSI Response Header */
+struct iscsi_cmd_rsp {
+ uint8_t opcode;
+ uint8_t flags;
+ uint8_t response;
+ uint8_t cmd_status;
+ uint8_t hlength;
+ uint8_t dlength[3];
+ uint8_t rsvd[8];
+ __be32 itt; /* Initiator Task Tag */
+ __be32 rsvd1;
+ __be32 statsn;
+ __be32 exp_cmdsn;
+ __be32 max_cmdsn;
+ __be32 exp_datasn;
+ __be32 bi_residual_count;
+ __be32 residual_count;
+ /* Response or Sense Data (optional) */
+};
+
+/* Command Response PDU flags */
+#define ISCSI_FLAG_CMD_BIDI_OVERFLOW 0x10
+#define ISCSI_FLAG_CMD_BIDI_UNDERFLOW 0x08
+#define ISCSI_FLAG_CMD_OVERFLOW 0x04
+#define ISCSI_FLAG_CMD_UNDERFLOW 0x02
+
+/* iSCSI Status values. Valid if Rsp Selector bit is not set */
+#define ISCSI_STATUS_CMD_COMPLETED 0
+#define ISCSI_STATUS_TARGET_FAILURE 1
+#define ISCSI_STATUS_SUBSYS_FAILURE 2
+
+/* Asynchronous Event Header */
+struct iscsi_async {
+ uint8_t opcode;
+ uint8_t flags;
+ uint8_t rsvd2[2];
+ uint8_t rsvd3;
+ uint8_t dlength[3];
+ uint8_t lun[8];
+ uint8_t rsvd4[8];
+ __be32 statsn;
+ __be32 exp_cmdsn;
+ __be32 max_cmdsn;
+ uint8_t async_event;
+ uint8_t async_vcode;
+ __be16 param1;
+ __be16 param2;
+ __be16 param3;
+ uint8_t rsvd5[4];
+};
+
+/* iSCSI Event Codes */
+#define ISCSI_ASYNC_MSG_SCSI_EVENT 0
+#define ISCSI_ASYNC_MSG_REQUEST_LOGOUT 1
+#define ISCSI_ASYNC_MSG_DROPPING_CONNECTION 2
+#define ISCSI_ASYNC_MSG_DROPPING_ALL_CONNECTIONS 3
+#define ISCSI_ASYNC_MSG_PARAM_NEGOTIATION 4
+#define ISCSI_ASYNC_MSG_VENDOR_SPECIFIC 255
+
+/* NOP-Out Message */
+struct iscsi_nopout {
+ uint8_t opcode;
+ uint8_t flags;
+ __be16 rsvd2;
+ uint8_t rsvd3;
+ uint8_t dlength[3];
+ uint8_t lun[8];
+ __be32 itt; /* Initiator Task Tag */
+ __be32 ttt; /* Target Transfer Tag */
+ __be32 cmdsn;
+ __be32 exp_statsn;
+ uint8_t rsvd4[16];
+};
+
+/* NOP-In Message */
+struct iscsi_nopin {
+ uint8_t opcode;
+ uint8_t flags;
+ __be16 rsvd2;
+ uint8_t rsvd3;
+ uint8_t dlength[3];
+ uint8_t lun[8];
+ __be32 itt; /* Initiator Task Tag */
+ __be32 ttt; /* Target Transfer Tag */
+ __be32 statsn;
+ __be32 exp_cmdsn;
+ __be32 max_cmdsn;
+ uint8_t rsvd4[12];
+};
+
+/* SCSI Task Management Message Header */
+struct iscsi_tm {
+ uint8_t opcode;
+ uint8_t flags;
+ uint8_t rsvd1[2];
+ uint8_t hlength;
+ uint8_t dlength[3];
+ uint8_t lun[8];
+ __be32 itt; /* Initiator Task Tag */
+ __be32 rtt; /* Reference Task Tag */
+ __be32 cmdsn;
+ __be32 exp_statsn;
+ __be32 refcmdsn;
+ __be32 exp_datasn;
+ uint8_t rsvd2[8];
+};
+
+#define ISCSI_FLAG_TM_FUNC_MASK 0x7F
+
+/* Function values */
+#define ISCSI_TM_FUNC_ABORT_TASK 1
+#define ISCSI_TM_FUNC_ABORT_TASK_SET 2
+#define ISCSI_TM_FUNC_CLEAR_ACA 3
+#define ISCSI_TM_FUNC_CLEAR_TASK_SET 4
+#define ISCSI_TM_FUNC_LOGICAL_UNIT_RESET 5
+#define ISCSI_TM_FUNC_TARGET_WARM_RESET 6
+#define ISCSI_TM_FUNC_TARGET_COLD_RESET 7
+#define ISCSI_TM_FUNC_TASK_REASSIGN 8
+
+/* SCSI Task Management Response Header */
+struct iscsi_tm_rsp {
+ uint8_t opcode;
+ uint8_t flags;
+ uint8_t response; /* see Response values below */
+ uint8_t qualifier;
+ uint8_t hlength;
+ uint8_t dlength[3];
+ uint8_t rsvd2[8];
+ __be32 itt; /* Initiator Task Tag */
+ __be32 rtt; /* Reference Task Tag */
+ __be32 statsn;
+ __be32 exp_cmdsn;
+ __be32 max_cmdsn;
+ uint8_t rsvd3[12];
+};
+
+/* Response values */
+#define ISCSI_TMF_RSP_COMPLETE 0x00
+#define ISCSI_TMF_RSP_NO_TASK 0x01
+#define ISCSI_TMF_RSP_NO_LUN 0x02
+#define ISCSI_TMF_RSP_TASK_ALLEGIANT 0x03
+#define ISCSI_TMF_RSP_NO_FAILOVER 0x04
+#define ISCSI_TMF_RSP_NOT_SUPPORTED 0x05
+#define ISCSI_TMF_RSP_AUTH_FAILED 0x06
+#define ISCSI_TMF_RSP_REJECTED 0xff
+
+/* Ready To Transfer Header */
+struct iscsi_r2t_rsp {
+ uint8_t opcode;
+ uint8_t flags;
+ uint8_t rsvd2[2];
+ uint8_t hlength;
+ uint8_t dlength[3];
+ uint8_t lun[8];
+ __be32 itt; /* Initiator Task Tag */
+ __be32 ttt; /* Target Transfer Tag */
+ __be32 statsn;
+ __be32 exp_cmdsn;
+ __be32 max_cmdsn;
+ __be32 r2tsn;
+ __be32 data_offset;
+ __be32 data_length;
+};
+
+/* SCSI Data Hdr */
+struct iscsi_data {
+ uint8_t opcode;
+ uint8_t flags;
+ uint8_t rsvd2[2];
+ uint8_t rsvd3;
+ uint8_t dlength[3];
+ uint8_t lun[8];
+ __be32 itt;
+ __be32 ttt;
+ __be32 rsvd4;
+ __be32 exp_statsn;
+ __be32 rsvd5;
+ __be32 datasn;
+ __be32 offset;
+ __be32 rsvd6;
+ /* Payload */
+};
+
+/* SCSI Data Response Hdr */
+struct iscsi_data_rsp {
+ uint8_t opcode;
+ uint8_t flags;
+ uint8_t rsvd2;
+ uint8_t cmd_status;
+ uint8_t hlength;
+ uint8_t dlength[3];
+ uint8_t lun[8];
+ __be32 itt;
+ __be32 ttt;
+ __be32 statsn;
+ __be32 exp_cmdsn;
+ __be32 max_cmdsn;
+ __be32 datasn;
+ __be32 offset;
+ __be32 residual_count;
+};
+
+/* Data Response PDU flags */
+#define ISCSI_FLAG_DATA_ACK 0x40
+#define ISCSI_FLAG_DATA_OVERFLOW 0x04
+#define ISCSI_FLAG_DATA_UNDERFLOW 0x02
+#define ISCSI_FLAG_DATA_STATUS 0x01
+
+/* Text Header */
+struct iscsi_text {
+ uint8_t opcode;
+ uint8_t flags;
+ uint8_t rsvd2[2];
+ uint8_t hlength;
+ uint8_t dlength[3];
+ uint8_t rsvd4[8];
+ __be32 itt;
+ __be32 ttt;
+ __be32 cmdsn;
+ __be32 exp_statsn;
+ uint8_t rsvd5[16];
+ /* Text - key=value pairs */
+};
+
+#define ISCSI_FLAG_TEXT_CONTINUE 0x40
+
+/* Text Response Header */
+struct iscsi_text_rsp {
+ uint8_t opcode;
+ uint8_t flags;
+ uint8_t rsvd2[2];
+ uint8_t hlength;
+ uint8_t dlength[3];
+ uint8_t rsvd4[8];
+ __be32 itt;
+ __be32 ttt;
+ __be32 statsn;
+ __be32 exp_cmdsn;
+ __be32 max_cmdsn;
+ uint8_t rsvd5[12];
+ /* Text Response - key:value pairs */
+};
+
+/* Login Header */
+struct iscsi_login {
+ uint8_t opcode;
+ uint8_t flags;
+ uint8_t max_version; /* Max. version supported */
+ uint8_t min_version; /* Min. version supported */
+ uint8_t hlength;
+ uint8_t dlength[3];
+ uint8_t isid[6]; /* Initiator Session ID */
+ __be16 tsih; /* Target Session Handle */
+ __be32 itt; /* Initiator Task Tag */
+ __be16 cid;
+ __be16 rsvd3;
+ __be32 cmdsn;
+ __be32 exp_statsn;
+ uint8_t rsvd5[16];
+};
+
+/* Login PDU flags */
+#define ISCSI_FLAG_LOGIN_TRANSIT 0x80
+#define ISCSI_FLAG_LOGIN_CONTINUE 0x40
+#define ISCSI_FLAG_LOGIN_CURRENT_STAGE_MASK 0x0C /* 2 bits */
+#define ISCSI_FLAG_LOGIN_NEXT_STAGE_MASK 0x03 /* 2 bits */
+
+#define ISCSI_LOGIN_CURRENT_STAGE(flags) \
+ ((flags & ISCSI_FLAG_LOGIN_CURRENT_STAGE_MASK) >> 2)
+#define ISCSI_LOGIN_NEXT_STAGE(flags) \
+ (flags & ISCSI_FLAG_LOGIN_NEXT_STAGE_MASK)
+
+/* Login Response Header */
+struct iscsi_login_rsp {
+ uint8_t opcode;
+ uint8_t flags;
+ uint8_t max_version; /* Max. version supported */
+ uint8_t active_version; /* Active version */
+ uint8_t hlength;
+ uint8_t dlength[3];
+ uint8_t isid[6]; /* Initiator Session ID */
+ __be16 tsih; /* Target Session Handle */
+ __be32 itt; /* Initiator Task Tag */
+ __be32 rsvd3;
+ __be32 statsn;
+ __be32 exp_cmdsn;
+ __be32 max_cmdsn;
+ uint8_t status_class; /* see Login RSP ststus classes below */
+ uint8_t status_detail; /* see Login RSP Status details below */
+ uint8_t rsvd4[10];
+};
+
+/* Login stage (phase) codes for CSG, NSG */
+#define ISCSI_INITIAL_LOGIN_STAGE -1
+#define ISCSI_SECURITY_NEGOTIATION_STAGE 0
+#define ISCSI_OP_PARMS_NEGOTIATION_STAGE 1
+#define ISCSI_FULL_FEATURE_PHASE 3
+
+/* Login Status response classes */
+#define ISCSI_STATUS_CLS_SUCCESS 0x00
+#define ISCSI_STATUS_CLS_REDIRECT 0x01
+#define ISCSI_STATUS_CLS_INITIATOR_ERR 0x02
+#define ISCSI_STATUS_CLS_TARGET_ERR 0x03
+
+/* Login Status response detail codes */
+/* Class-0 (Success) */
+#define ISCSI_LOGIN_STATUS_ACCEPT 0x00
+
+/* Class-1 (Redirection) */
+#define ISCSI_LOGIN_STATUS_TGT_MOVED_TEMP 0x01
+#define ISCSI_LOGIN_STATUS_TGT_MOVED_PERM 0x02
+
+/* Class-2 (Initiator Error) */
+#define ISCSI_LOGIN_STATUS_INIT_ERR 0x00
+#define ISCSI_LOGIN_STATUS_AUTH_FAILED 0x01
+#define ISCSI_LOGIN_STATUS_TGT_FORBIDDEN 0x02
+#define ISCSI_LOGIN_STATUS_TGT_NOT_FOUND 0x03
+#define ISCSI_LOGIN_STATUS_TGT_REMOVED 0x04
+#define ISCSI_LOGIN_STATUS_NO_VERSION 0x05
+#define ISCSI_LOGIN_STATUS_ISID_ERROR 0x06
+#define ISCSI_LOGIN_STATUS_MISSING_FIELDS 0x07
+#define ISCSI_LOGIN_STATUS_CONN_ADD_FAILED 0x08
+#define ISCSI_LOGIN_STATUS_NO_SESSION_TYPE 0x09
+#define ISCSI_LOGIN_STATUS_NO_SESSION 0x0a
+#define ISCSI_LOGIN_STATUS_INVALID_REQUEST 0x0b
+
+/* Class-3 (Target Error) */
+#define ISCSI_LOGIN_STATUS_TARGET_ERROR 0x00
+#define ISCSI_LOGIN_STATUS_SVC_UNAVAILABLE 0x01
+#define ISCSI_LOGIN_STATUS_NO_RESOURCES 0x02
+
+/* Logout Header */
+struct iscsi_logout {
+ uint8_t opcode;
+ uint8_t flags;
+ uint8_t rsvd1[2];
+ uint8_t hlength;
+ uint8_t dlength[3];
+ uint8_t rsvd2[8];
+ __be32 itt; /* Initiator Task Tag */
+ __be16 cid;
+ uint8_t rsvd3[2];
+ __be32 cmdsn;
+ __be32 exp_statsn;
+ uint8_t rsvd4[16];
+};
+
+/* Logout PDU flags */
+#define ISCSI_FLAG_LOGOUT_REASON_MASK 0x7F
+
+/* logout reason_code values */
+
+#define ISCSI_LOGOUT_REASON_CLOSE_SESSION 0
+#define ISCSI_LOGOUT_REASON_CLOSE_CONNECTION 1
+#define ISCSI_LOGOUT_REASON_RECOVERY 2
+#define ISCSI_LOGOUT_REASON_AEN_REQUEST 3
+
+/* Logout Response Header */
+struct iscsi_logout_rsp {
+ uint8_t opcode;
+ uint8_t flags;
+ uint8_t response; /* see Logout response values below */
+ uint8_t rsvd2;
+ uint8_t hlength;
+ uint8_t dlength[3];
+ uint8_t rsvd3[8];
+ __be32 itt; /* Initiator Task Tag */
+ __be32 rsvd4;
+ __be32 statsn;
+ __be32 exp_cmdsn;
+ __be32 max_cmdsn;
+ __be32 rsvd5;
+ __be16 t2wait;
+ __be16 t2retain;
+ __be32 rsvd6;
+};
+
+/* logout response status values */
+
+#define ISCSI_LOGOUT_SUCCESS 0
+#define ISCSI_LOGOUT_CID_NOT_FOUND 1
+#define ISCSI_LOGOUT_RECOVERY_UNSUPPORTED 2
+#define ISCSI_LOGOUT_CLEANUP_FAILED 3
+
+/* SNACK Header */
+struct iscsi_snack {
+ uint8_t opcode;
+ uint8_t flags;
+ uint8_t rsvd2[14];
+ __be32 itt;
+ __be32 begrun;
+ __be32 runlength;
+ __be32 exp_statsn;
+ __be32 rsvd3;
+ __be32 exp_datasn;
+ uint8_t rsvd6[8];
+};
+
+/* SNACK PDU flags */
+#define ISCSI_FLAG_SNACK_TYPE_MASK 0x0F /* 4 bits */
+
+/* Reject Message Header */
+struct iscsi_reject {
+ uint8_t opcode;
+ uint8_t flags;
+ uint8_t reason;
+ uint8_t rsvd2;
+ uint8_t hlength;
+ uint8_t dlength[3];
+ uint8_t rsvd3[8];
+ __be32 ffffffff;
+ uint8_t rsvd4[4];
+ __be32 statsn;
+ __be32 exp_cmdsn;
+ __be32 max_cmdsn;
+ __be32 datasn;
+ uint8_t rsvd5[8];
+ /* Text - Rejected hdr */
+};
+
+/* Reason for Reject */
+#define ISCSI_REASON_CMD_BEFORE_LOGIN 1
+#define ISCSI_REASON_DATA_DIGEST_ERROR 2
+#define ISCSI_REASON_DATA_SNACK_REJECT 3
+#define ISCSI_REASON_PROTOCOL_ERROR 4
+#define ISCSI_REASON_CMD_NOT_SUPPORTED 5
+#define ISCSI_REASON_IMM_CMD_REJECT 6
+#define ISCSI_REASON_TASK_IN_PROGRESS 7
+#define ISCSI_REASON_INVALID_SNACK 8
+#define ISCSI_REASON_BOOKMARK_INVALID 9
+#define ISCSI_REASON_BOOKMARK_NO_RESOURCES 10
+#define ISCSI_REASON_NEGOTIATION_RESET 11
+
+/* Max. number of Key=Value pairs in a text message */
+#define MAX_KEY_VALUE_PAIRS 8192
+
+/* maximum length for text keys/values */
+#define KEY_MAXLEN 64
+#define VALUE_MAXLEN 255
+#define TARGET_NAME_MAXLEN VALUE_MAXLEN
+
+#define DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH 8192
+
+/************************* RFC 3720 End *****************************/
+
+#endif /* ISCSI_PROTO_H */
diff --git a/include/scsi/scsi.h b/include/scsi/scsi.h
index b361172b576c..6cb1e2788d8b 100644
--- a/include/scsi/scsi.h
+++ b/include/scsi/scsi.h
@@ -116,6 +116,9 @@ extern const char *const scsi_device_types[MAX_SCSI_DEVICE_CODE];
/* values for service action in */
#define SAI_READ_CAPACITY_16 0x10
+/* Values for T10/04-262r7 */
+#define ATA_16 0x85 /* 16-byte pass-thru */
+#define ATA_12 0xa1 /* 12-byte pass-thru */
/*
* SCSI Architecture Model (SAM) Status codes. Taken from SAM-3 draft
diff --git a/include/scsi/scsi_cmnd.h b/include/scsi/scsi_cmnd.h
index bed4b7c9be99..7529f4388bb4 100644
--- a/include/scsi/scsi_cmnd.h
+++ b/include/scsi/scsi_cmnd.h
@@ -4,6 +4,7 @@
#include <linux/dma-mapping.h>
#include <linux/list.h>
#include <linux/types.h>
+#include <linux/timer.h>
struct request;
struct scatterlist;
@@ -146,7 +147,7 @@ struct scsi_cmnd {
#define SCSI_STATE_MLQUEUE 0x100b
-extern struct scsi_cmnd *scsi_get_command(struct scsi_device *, int);
+extern struct scsi_cmnd *scsi_get_command(struct scsi_device *, gfp_t);
extern void scsi_put_command(struct scsi_cmnd *);
extern void scsi_io_completion(struct scsi_cmnd *, unsigned int, unsigned int);
extern void scsi_finish_command(struct scsi_cmnd *cmd);
diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h
index 7ece05666feb..85cfd88461c8 100644
--- a/include/scsi/scsi_device.h
+++ b/include/scsi/scsi_device.h
@@ -148,6 +148,12 @@ struct scsi_device {
#define transport_class_to_sdev(class_dev) \
to_scsi_device(class_dev->dev)
+#define sdev_printk(prefix, sdev, fmt, a...) \
+ dev_printk(prefix, &(sdev)->sdev_gendev, fmt, ##a)
+
+#define scmd_printk(prefix, scmd, fmt, a...) \
+ dev_printk(prefix, &(scmd)->device->sdev_gendev, fmt, ##a)
+
/*
* scsi_target: representation of a scsi target, for now, this is only
* used for single_lun devices. If no one has active IO to the target,
@@ -177,6 +183,9 @@ static inline struct scsi_target *scsi_target(struct scsi_device *sdev)
#define transport_class_to_starget(class_dev) \
to_scsi_target(class_dev->dev)
+#define starget_printk(prefix, starget, fmt, a...) \
+ dev_printk(prefix, &(starget)->dev, fmt, ##a)
+
extern struct scsi_device *__scsi_add_device(struct Scsi_Host *,
uint, uint, uint, void *hostdata);
extern int scsi_add_device(struct Scsi_Host *host, uint channel,
@@ -266,6 +275,19 @@ extern int scsi_execute_req(struct scsi_device *sdev, const unsigned char *cmd,
int data_direction, void *buffer, unsigned bufflen,
struct scsi_sense_hdr *, int timeout, int retries);
+static inline unsigned int sdev_channel(struct scsi_device *sdev)
+{
+ return sdev->channel;
+}
+
+static inline unsigned int sdev_id(struct scsi_device *sdev)
+{
+ return sdev->id;
+}
+
+#define scmd_id(scmd) sdev_id((scmd)->device)
+#define scmd_channel(scmd) sdev_channel((scmd)->device)
+
static inline int scsi_device_online(struct scsi_device *sdev)
{
return sdev->sdev_state != SDEV_OFFLINE;
diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h
index 69313ba7505b..ecd53d7872d2 100644
--- a/include/scsi/scsi_host.h
+++ b/include/scsi/scsi_host.h
@@ -609,6 +609,10 @@ struct Scsi_Host {
#define class_to_shost(d) \
container_of(d, struct Scsi_Host, shost_classdev)
+#define shost_printk(prefix, shost, fmt, a...) \
+ dev_printk(prefix, &(shost)->shost_gendev, fmt, ##a)
+
+
int scsi_is_host_device(const struct device *);
static inline struct Scsi_Host *dev_to_shost(struct device *dev)
@@ -634,8 +638,6 @@ extern void scsi_flush_work(struct Scsi_Host *);
extern struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *, int);
extern int __must_check scsi_add_host(struct Scsi_Host *, struct device *);
extern void scsi_scan_host(struct Scsi_Host *);
-extern void scsi_scan_single_target(struct Scsi_Host *, unsigned int,
- unsigned int);
extern void scsi_rescan_device(struct device *);
extern void scsi_remove_host(struct Scsi_Host *);
extern struct Scsi_Host *scsi_host_get(struct Scsi_Host *);
diff --git a/include/scsi/scsi_request.h b/include/scsi/scsi_request.h
index 6a140020d7cb..2539debb7993 100644
--- a/include/scsi/scsi_request.h
+++ b/include/scsi/scsi_request.h
@@ -45,7 +45,7 @@ struct scsi_request {
level driver) of this request */
};
-extern struct scsi_request *scsi_allocate_request(struct scsi_device *, int);
+extern struct scsi_request *scsi_allocate_request(struct scsi_device *, gfp_t);
extern void scsi_release_request(struct scsi_request *);
extern void scsi_wait_req(struct scsi_request *, const void *cmnd,
void *buffer, unsigned bufflen,
diff --git a/include/scsi/scsi_transport_fc.h b/include/scsi/scsi_transport_fc.h
index b0d445437372..fac547d32a98 100644
--- a/include/scsi/scsi_transport_fc.h
+++ b/include/scsi/scsi_transport_fc.h
@@ -28,6 +28,8 @@
#define SCSI_TRANSPORT_FC_H
#include <linux/config.h>
+#include <linux/sched.h>
+#include <scsi/scsi.h>
struct scsi_transport_template;
@@ -384,6 +386,8 @@ struct fc_function_template {
struct fc_host_statistics * (*get_fc_host_stats)(struct Scsi_Host *);
void (*reset_fc_host_stats)(struct Scsi_Host *);
+ int (*issue_fc_host_lip)(struct Scsi_Host *);
+
/* allocation lengths for host-specific data */
u32 dd_fcrport_size;
@@ -427,6 +431,34 @@ struct fc_function_template {
};
+/**
+ * fc_remote_port_chkready - called to validate the remote port state
+ * prior to initiating io to the port.
+ *
+ * Returns a scsi result code that can be returned by the LLDD.
+ *
+ * @rport: remote port to be checked
+ **/
+static inline int
+fc_remote_port_chkready(struct fc_rport *rport)
+{
+ int result;
+
+ switch (rport->port_state) {
+ case FC_PORTSTATE_ONLINE:
+ result = 0;
+ break;
+ case FC_PORTSTATE_BLOCKED:
+ result = DID_BUS_BUSY << 16;
+ break;
+ default:
+ result = DID_NO_CONNECT << 16;
+ break;
+ }
+ return result;
+}
+
+
struct scsi_transport_template *fc_attach_transport(
struct fc_function_template *);
void fc_release_transport(struct scsi_transport_template *);
@@ -435,8 +467,6 @@ struct fc_rport *fc_remote_port_add(struct Scsi_Host *shost,
int channel, struct fc_rport_identifiers *ids);
void fc_remote_port_delete(struct fc_rport *rport);
void fc_remote_port_rolechg(struct fc_rport *rport, u32 roles);
-int fc_remote_port_block(struct fc_rport *rport);
-void fc_remote_port_unblock(struct fc_rport *rport);
int scsi_is_fc_rport(const struct device *);
static inline u64 wwn_to_u64(u8 *wwn)
diff --git a/include/scsi/scsi_transport_iscsi.h b/include/scsi/scsi_transport_iscsi.h
index 1b26a6c0aa2a..f25041c386ec 100644
--- a/include/scsi/scsi_transport_iscsi.h
+++ b/include/scsi/scsi_transport_iscsi.h
@@ -1,8 +1,10 @@
-/*
+/*
* iSCSI transport class definitions
*
* Copyright (C) IBM Corporation, 2004
- * Copyright (C) Mike Christie, 2004
+ * Copyright (C) Mike Christie, 2004 - 2005
+ * Copyright (C) Dmitry Yusupov, 2004 - 2005
+ * Copyright (C) Alex Aizman, 2004 - 2005
*
* 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
@@ -21,158 +23,64 @@
#ifndef SCSI_TRANSPORT_ISCSI_H
#define SCSI_TRANSPORT_ISCSI_H
-#include <linux/config.h>
-#include <linux/in6.h>
-#include <linux/in.h>
-
-struct scsi_transport_template;
+#include <scsi/iscsi_if.h>
-struct iscsi_class_session {
- uint8_t isid[6];
- uint16_t tsih;
- int header_digest; /* 1 CRC32, 0 None */
- int data_digest; /* 1 CRC32, 0 None */
- uint16_t tpgt;
- union {
- struct in6_addr sin6_addr;
- struct in_addr sin_addr;
- } u;
- sa_family_t addr_type; /* must be AF_INET or AF_INET6 */
- uint16_t port; /* must be in network byte order */
- int initial_r2t; /* 1 Yes, 0 No */
- int immediate_data; /* 1 Yes, 0 No */
- uint32_t max_recv_data_segment_len;
- uint32_t max_burst_len;
- uint32_t first_burst_len;
- uint16_t def_time2wait;
- uint16_t def_time2retain;
- uint16_t max_outstanding_r2t;
- int data_pdu_in_order; /* 1 Yes, 0 No */
- int data_sequence_in_order; /* 1 Yes, 0 No */
- int erl;
+/**
+ * struct iscsi_transport - iSCSI Transport template
+ *
+ * @name: transport name
+ * @caps: iSCSI Data-Path capabilities
+ * @create_session: create new iSCSI session object
+ * @destroy_session: destroy existing iSCSI session object
+ * @create_conn: create new iSCSI connection
+ * @bind_conn: associate this connection with existing iSCSI session
+ * and specified transport descriptor
+ * @destroy_conn: destroy inactive iSCSI connection
+ * @set_param: set iSCSI Data-Path operational parameter
+ * @start_conn: set connection to be operational
+ * @stop_conn: suspend/recover/terminate connection
+ * @send_pdu: send iSCSI PDU, Login, Logout, NOP-Out, Reject, Text.
+ *
+ * Template API provided by iSCSI Transport
+ */
+struct iscsi_transport {
+ struct module *owner;
+ char *name;
+ unsigned int caps;
+ struct scsi_host_template *host_template;
+ int hostdata_size;
+ int max_lun;
+ unsigned int max_conn;
+ unsigned int max_cmd_len;
+ iscsi_sessionh_t (*create_session) (uint32_t initial_cmdsn,
+ struct Scsi_Host *shost);
+ void (*destroy_session) (iscsi_sessionh_t session);
+ iscsi_connh_t (*create_conn) (iscsi_sessionh_t session, uint32_t cid);
+ int (*bind_conn) (iscsi_sessionh_t session, iscsi_connh_t conn,
+ uint32_t transport_fd, int is_leading);
+ int (*start_conn) (iscsi_connh_t conn);
+ void (*stop_conn) (iscsi_connh_t conn, int flag);
+ void (*destroy_conn) (iscsi_connh_t conn);
+ int (*set_param) (iscsi_connh_t conn, enum iscsi_param param,
+ uint32_t value);
+ int (*get_param) (iscsi_connh_t conn, enum iscsi_param param,
+ uint32_t *value);
+ int (*send_pdu) (iscsi_connh_t conn, struct iscsi_hdr *hdr,
+ char *data, uint32_t data_size);
+ void (*get_stats) (iscsi_connh_t conn, struct iscsi_stats *stats);
};
/*
- * accessor macros
+ * transport registration upcalls
*/
-#define iscsi_isid(x) \
- (((struct iscsi_class_session *)&(x)->starget_data)->isid)
-#define iscsi_tsih(x) \
- (((struct iscsi_class_session *)&(x)->starget_data)->tsih)
-#define iscsi_header_digest(x) \
- (((struct iscsi_class_session *)&(x)->starget_data)->header_digest)
-#define iscsi_data_digest(x) \
- (((struct iscsi_class_session *)&(x)->starget_data)->data_digest)
-#define iscsi_port(x) \
- (((struct iscsi_class_session *)&(x)->starget_data)->port)
-#define iscsi_addr_type(x) \
- (((struct iscsi_class_session *)&(x)->starget_data)->addr_type)
-#define iscsi_sin_addr(x) \
- (((struct iscsi_class_session *)&(x)->starget_data)->u.sin_addr)
-#define iscsi_sin6_addr(x) \
- (((struct iscsi_class_session *)&(x)->starget_data)->u.sin6_addr)
-#define iscsi_tpgt(x) \
- (((struct iscsi_class_session *)&(x)->starget_data)->tpgt)
-#define iscsi_initial_r2t(x) \
- (((struct iscsi_class_session *)&(x)->starget_data)->initial_r2t)
-#define iscsi_immediate_data(x) \
- (((struct iscsi_class_session *)&(x)->starget_data)->immediate_data)
-#define iscsi_max_recv_data_segment_len(x) \
- (((struct iscsi_class_session *)&(x)->starget_data)->max_recv_data_segment_len)
-#define iscsi_max_burst_len(x) \
- (((struct iscsi_class_session *)&(x)->starget_data)->max_burst_len)
-#define iscsi_first_burst_len(x) \
- (((struct iscsi_class_session *)&(x)->starget_data)->first_burst_len)
-#define iscsi_def_time2wait(x) \
- (((struct iscsi_class_session *)&(x)->starget_data)->def_time2wait)
-#define iscsi_def_time2retain(x) \
- (((struct iscsi_class_session *)&(x)->starget_data)->def_time2retain)
-#define iscsi_max_outstanding_r2t(x) \
- (((struct iscsi_class_session *)&(x)->starget_data)->max_outstanding_r2t)
-#define iscsi_data_pdu_in_order(x) \
- (((struct iscsi_class_session *)&(x)->starget_data)->data_pdu_in_order)
-#define iscsi_data_sequence_in_order(x) \
- (((struct iscsi_class_session *)&(x)->starget_data)->data_sequence_in_order)
-#define iscsi_erl(x) \
- (((struct iscsi_class_session *)&(x)->starget_data)->erl)
+extern int iscsi_register_transport(struct iscsi_transport *tt);
+extern int iscsi_unregister_transport(struct iscsi_transport *tt);
/*
- * The functions by which the transport class and the driver communicate
+ * control plane upcalls
*/
-struct iscsi_function_template {
- /*
- * target attrs
- */
- void (*get_isid)(struct scsi_target *);
- void (*get_tsih)(struct scsi_target *);
- void (*get_header_digest)(struct scsi_target *);
- void (*get_data_digest)(struct scsi_target *);
- void (*get_port)(struct scsi_target *);
- void (*get_tpgt)(struct scsi_target *);
- /*
- * In get_ip_address the lld must set the address and
- * the address type
- */
- void (*get_ip_address)(struct scsi_target *);
- /*
- * The lld should snprintf the name or alias to the buffer
- */
- ssize_t (*get_target_name)(struct scsi_target *, char *, ssize_t);
- ssize_t (*get_target_alias)(struct scsi_target *, char *, ssize_t);
- void (*get_initial_r2t)(struct scsi_target *);
- void (*get_immediate_data)(struct scsi_target *);
- void (*get_max_recv_data_segment_len)(struct scsi_target *);
- void (*get_max_burst_len)(struct scsi_target *);
- void (*get_first_burst_len)(struct scsi_target *);
- void (*get_def_time2wait)(struct scsi_target *);
- void (*get_def_time2retain)(struct scsi_target *);
- void (*get_max_outstanding_r2t)(struct scsi_target *);
- void (*get_data_pdu_in_order)(struct scsi_target *);
- void (*get_data_sequence_in_order)(struct scsi_target *);
- void (*get_erl)(struct scsi_target *);
-
- /*
- * host atts
- */
-
- /*
- * The lld should snprintf the name or alias to the buffer
- */
- ssize_t (*get_initiator_alias)(struct Scsi_Host *, char *, ssize_t);
- ssize_t (*get_initiator_name)(struct Scsi_Host *, char *, ssize_t);
- /*
- * The driver sets these to tell the transport class it
- * wants the attributes displayed in sysfs. If the show_ flag
- * is not set, the attribute will be private to the transport
- * class. We could probably just test if a get_ fn was set
- * since we only use the values for sysfs but this is how
- * fc does it too.
- */
- unsigned long show_isid:1;
- unsigned long show_tsih:1;
- unsigned long show_header_digest:1;
- unsigned long show_data_digest:1;
- unsigned long show_port:1;
- unsigned long show_tpgt:1;
- unsigned long show_ip_address:1;
- unsigned long show_target_name:1;
- unsigned long show_target_alias:1;
- unsigned long show_initial_r2t:1;
- unsigned long show_immediate_data:1;
- unsigned long show_max_recv_data_segment_len:1;
- unsigned long show_max_burst_len:1;
- unsigned long show_first_burst_len:1;
- unsigned long show_def_time2wait:1;
- unsigned long show_def_time2retain:1;
- unsigned long show_max_outstanding_r2t:1;
- unsigned long show_data_pdu_in_order:1;
- unsigned long show_data_sequence_in_order:1;
- unsigned long show_erl:1;
- unsigned long show_initiator_name:1;
- unsigned long show_initiator_alias:1;
-};
-
-struct scsi_transport_template *iscsi_attach_transport(struct iscsi_function_template *);
-void iscsi_release_transport(struct scsi_transport_template *);
+extern void iscsi_conn_error(iscsi_connh_t conn, enum iscsi_err error);
+extern int iscsi_recv_pdu(iscsi_connh_t conn, struct iscsi_hdr *hdr,
+ char *data, uint32_t data_size);
#endif
diff --git a/include/scsi/scsi_transport_sas.h b/include/scsi/scsi_transport_sas.h
index bc4aeb660dd3..b91400bfb02a 100644
--- a/include/scsi/scsi_transport_sas.h
+++ b/include/scsi/scsi_transport_sas.h
@@ -41,20 +41,31 @@ struct sas_identify {
u8 phy_identifier;
};
-/* The functions by which the transport class and the driver communicate */
-struct sas_function_template {
-};
-
struct sas_phy {
struct device dev;
int number;
+
+ /* phy identification */
struct sas_identify identify;
+
+ /* phy attributes */
enum sas_linkrate negotiated_linkrate;
enum sas_linkrate minimum_linkrate_hw;
enum sas_linkrate minimum_linkrate;
enum sas_linkrate maximum_linkrate_hw;
enum sas_linkrate maximum_linkrate;
u8 port_identifier;
+
+ /* internal state */
+ unsigned int local_attached : 1;
+
+ /* link error statistics */
+ u32 invalid_dword_count;
+ u32 running_disparity_error_count;
+ u32 loss_of_dword_sync_count;
+ u32 phy_reset_problem_count;
+
+ /* the other end of the link */
struct sas_rphy *rphy;
};
@@ -79,6 +90,14 @@ struct sas_rphy {
#define rphy_to_shost(rphy) \
dev_to_shost((rphy)->dev.parent)
+
+/* The functions by which the transport class and the driver communicate */
+struct sas_function_template {
+ int (*get_linkerrors)(struct sas_phy *);
+ int (*phy_reset)(struct sas_phy *, int);
+};
+
+
extern void sas_remove_host(struct Scsi_Host *);
extern struct sas_phy *sas_phy_alloc(struct device *, int);
diff --git a/include/scsi/srp.h b/include/scsi/srp.h
new file mode 100644
index 000000000000..6c2681dc5b46
--- /dev/null
+++ b/include/scsi/srp.h
@@ -0,0 +1,226 @@
+/*
+ * Copyright (c) 2005 Cisco Systems. All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses. You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * - Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * 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.
+ *
+ * $Id$
+ */
+
+#ifndef SCSI_SRP_H
+#define SCSI_SRP_H
+
+/*
+ * Structures and constants for the SCSI RDMA Protocol (SRP) as
+ * defined by the INCITS T10 committee. This file was written using
+ * draft Revision 16a of the SRP standard.
+ */
+
+#include <linux/types.h>
+
+enum {
+ SRP_LOGIN_REQ = 0x00,
+ SRP_TSK_MGMT = 0x01,
+ SRP_CMD = 0x02,
+ SRP_I_LOGOUT = 0x03,
+ SRP_LOGIN_RSP = 0xc0,
+ SRP_RSP = 0xc1,
+ SRP_LOGIN_REJ = 0xc2,
+ SRP_T_LOGOUT = 0x80,
+ SRP_CRED_REQ = 0x81,
+ SRP_AER_REQ = 0x82,
+ SRP_CRED_RSP = 0x41,
+ SRP_AER_RSP = 0x42
+};
+
+enum {
+ SRP_BUF_FORMAT_DIRECT = 1 << 1,
+ SRP_BUF_FORMAT_INDIRECT = 1 << 2
+};
+
+enum {
+ SRP_NO_DATA_DESC = 0,
+ SRP_DATA_DESC_DIRECT = 1,
+ SRP_DATA_DESC_INDIRECT = 2
+};
+
+enum {
+ SRP_TSK_ABORT_TASK = 0x01,
+ SRP_TSK_ABORT_TASK_SET = 0x02,
+ SRP_TSK_CLEAR_TASK_SET = 0x04,
+ SRP_TSK_LUN_RESET = 0x08,
+ SRP_TSK_CLEAR_ACA = 0x40
+};
+
+enum srp_login_rej_reason {
+ SRP_LOGIN_REJ_UNABLE_ESTABLISH_CHANNEL = 0x00010000,
+ SRP_LOGIN_REJ_INSUFFICIENT_RESOURCES = 0x00010001,
+ SRP_LOGIN_REJ_REQ_IT_IU_LENGTH_TOO_LARGE = 0x00010002,
+ SRP_LOGIN_REJ_UNABLE_ASSOCIATE_CHANNEL = 0x00010003,
+ SRP_LOGIN_REJ_UNSUPPORTED_DESCRIPTOR_FMT = 0x00010004,
+ SRP_LOGIN_REJ_MULTI_CHANNEL_UNSUPPORTED = 0x00010005,
+ SRP_LOGIN_REJ_CHANNEL_LIMIT_REACHED = 0x00010006
+};
+
+struct srp_direct_buf {
+ __be64 va;
+ __be32 key;
+ __be32 len;
+};
+
+/*
+ * We need the packed attribute because the SRP spec puts the list of
+ * descriptors at an offset of 20, which is not aligned to the size
+ * of struct srp_direct_buf.
+ */
+struct srp_indirect_buf {
+ struct srp_direct_buf table_desc;
+ __be32 len;
+ struct srp_direct_buf desc_list[0] __attribute__((packed));
+};
+
+enum {
+ SRP_MULTICHAN_SINGLE = 0,
+ SRP_MULTICHAN_MULTI = 1
+};
+
+struct srp_login_req {
+ u8 opcode;
+ u8 reserved1[7];
+ u64 tag;
+ __be32 req_it_iu_len;
+ u8 reserved2[4];
+ __be16 req_buf_fmt;
+ u8 req_flags;
+ u8 reserved3[5];
+ u8 initiator_port_id[16];
+ u8 target_port_id[16];
+};
+
+struct srp_login_rsp {
+ u8 opcode;
+ u8 reserved1[3];
+ __be32 req_lim_delta;
+ u64 tag;
+ __be32 max_it_iu_len;
+ __be32 max_ti_iu_len;
+ __be16 buf_fmt;
+ u8 rsp_flags;
+ u8 reserved2[25];
+};
+
+struct srp_login_rej {
+ u8 opcode;
+ u8 reserved1[3];
+ __be32 reason;
+ u64 tag;
+ u8 reserved2[8];
+ __be16 buf_fmt;
+ u8 reserved3[6];
+};
+
+struct srp_i_logout {
+ u8 opcode;
+ u8 reserved[7];
+ u64 tag;
+};
+
+struct srp_t_logout {
+ u8 opcode;
+ u8 sol_not;
+ u8 reserved[2];
+ __be32 reason;
+ u64 tag;
+};
+
+/*
+ * We need the packed attribute because the SRP spec only aligns the
+ * 8-byte LUN field to 4 bytes.
+ */
+struct srp_tsk_mgmt {
+ u8 opcode;
+ u8 sol_not;
+ u8 reserved1[6];
+ u64 tag;
+ u8 reserved2[4];
+ __be64 lun __attribute__((packed));
+ u8 reserved3[2];
+ u8 tsk_mgmt_func;
+ u8 reserved4;
+ u64 task_tag;
+ u8 reserved5[8];
+};
+
+/*
+ * We need the packed attribute because the SRP spec only aligns the
+ * 8-byte LUN field to 4 bytes.
+ */
+struct srp_cmd {
+ u8 opcode;
+ u8 sol_not;
+ u8 reserved1[3];
+ u8 buf_fmt;
+ u8 data_out_desc_cnt;
+ u8 data_in_desc_cnt;
+ u64 tag;
+ u8 reserved2[4];
+ __be64 lun __attribute__((packed));
+ u8 reserved3;
+ u8 task_attr;
+ u8 reserved4;
+ u8 add_cdb_len;
+ u8 cdb[16];
+ u8 add_data[0];
+};
+
+enum {
+ SRP_RSP_FLAG_RSPVALID = 1 << 0,
+ SRP_RSP_FLAG_SNSVALID = 1 << 1,
+ SRP_RSP_FLAG_DOOVER = 1 << 2,
+ SRP_RSP_FLAG_DOUNDER = 1 << 3,
+ SRP_RSP_FLAG_DIOVER = 1 << 4,
+ SRP_RSP_FLAG_DIUNDER = 1 << 5
+};
+
+struct srp_rsp {
+ u8 opcode;
+ u8 sol_not;
+ u8 reserved1[2];
+ __be32 req_lim_delta;
+ u64 tag;
+ u8 reserved2[2];
+ u8 flags;
+ u8 status;
+ __be32 data_out_res_cnt;
+ __be32 data_in_res_cnt;
+ __be32 sense_data_len;
+ __be32 resp_data_len;
+ u8 data[0];
+};
+
+#endif /* SCSI_SRP_H */
diff --git a/include/sound/ac97_codec.h b/include/sound/ac97_codec.h
index d11f34832a97..7f0ca79d6c98 100644
--- a/include/sound/ac97_codec.h
+++ b/include/sound/ac97_codec.h
@@ -387,15 +387,6 @@
#define AC97_RATES_MIC_ADC 4
#define AC97_RATES_SPDIF 5
-/* shared controllers */
-enum {
- AC97_SHARED_TYPE_NONE,
- AC97_SHARED_TYPE_ICH,
- AC97_SHARED_TYPE_ATIIXP,
- AC97_SHARED_TYPE_VIA,
- AC97_SHARED_TYPES
-};
-
/*
*
*/
@@ -468,7 +459,6 @@ struct _snd_ac97_bus {
unsigned short used_slots[2][4]; /* actually used PCM slots */
unsigned short pcms_count; /* count of PCMs */
struct ac97_pcm *pcms;
- unsigned int shared_type; /* type of shared controller betwen audio and modem */
ac97_t *codec[4];
snd_info_entry_t *proc;
};
diff --git a/include/sound/core.h b/include/sound/core.h
index 6d971a4c4ca0..2be65ad2fd83 100644
--- a/include/sound/core.h
+++ b/include/sound/core.h
@@ -29,7 +29,6 @@
#include <linux/pm.h> /* pm_message_t */
/* Typedef's */
-typedef struct timespec snd_timestamp_t;
typedef struct sndrv_interval snd_interval_t;
typedef enum sndrv_card_type snd_card_type;
typedef struct sndrv_xferi snd_xferi_t;
@@ -256,6 +255,7 @@ typedef struct _snd_minor snd_minor_t;
/* sound.c */
+extern int snd_major;
extern int snd_ecards_limit;
void snd_request_card(int card);
@@ -285,39 +285,6 @@ int snd_oss_init_module(void);
/* memory.c */
-#ifdef CONFIG_SND_DEBUG_MEMORY
-void snd_memory_init(void);
-void snd_memory_done(void);
-int snd_memory_info_init(void);
-int snd_memory_info_done(void);
-void *snd_hidden_kmalloc(size_t size, gfp_t flags);
-void *snd_hidden_kzalloc(size_t size, gfp_t flags);
-void *snd_hidden_kcalloc(size_t n, size_t size, gfp_t flags);
-void snd_hidden_kfree(const void *obj);
-void *snd_hidden_vmalloc(unsigned long size);
-void snd_hidden_vfree(void *obj);
-char *snd_hidden_kstrdup(const char *s, gfp_t flags);
-#define kmalloc(size, flags) snd_hidden_kmalloc(size, flags)
-#define kzalloc(size, flags) snd_hidden_kzalloc(size, flags)
-#define kcalloc(n, size, flags) snd_hidden_kcalloc(n, size, flags)
-#define kfree(obj) snd_hidden_kfree(obj)
-#define vmalloc(size) snd_hidden_vmalloc(size)
-#define vfree(obj) snd_hidden_vfree(obj)
-#define kmalloc_nocheck(size, flags) snd_wrapper_kmalloc(size, flags)
-#define vmalloc_nocheck(size) snd_wrapper_vmalloc(size)
-#define kfree_nocheck(obj) snd_wrapper_kfree(obj)
-#define vfree_nocheck(obj) snd_wrapper_vfree(obj)
-#define kstrdup(s, flags) snd_hidden_kstrdup(s, flags)
-#else
-#define snd_memory_init() /*NOP*/
-#define snd_memory_done() /*NOP*/
-#define snd_memory_info_init() /*NOP*/
-#define snd_memory_info_done() /*NOP*/
-#define kmalloc_nocheck(size, flags) kmalloc(size, flags)
-#define vmalloc_nocheck(size) vmalloc(size)
-#define kfree_nocheck(obj) kfree(obj)
-#define vfree_nocheck(obj) vfree(obj)
-#endif
int copy_to_user_fromio(void __user *dst, const volatile void __iomem *src, size_t count);
int copy_from_user_toio(volatile void __iomem *dst, const void __user *src, size_t count);
@@ -373,8 +340,9 @@ unsigned int snd_dma_pointer(unsigned long dma, unsigned int size);
#endif
/* misc.c */
+struct resource;
+void release_and_free_resource(struct resource *res);
-int snd_task_name(struct task_struct *task, char *name, size_t size);
#ifdef CONFIG_SND_VERBOSE_PRINTK
void snd_verbose_printk(const char *file, int line, const char *format, ...)
__attribute__ ((format (printf, 3, 4)));
@@ -429,34 +397,24 @@ void snd_verbose_printd(const char *file, int line, const char *format, ...)
* When CONFIG_SND_DEBUG is not set, the expression is executed but
* not checked.
*/
-#define snd_assert(expr, args...) do {\
- if (unlikely(!(expr))) { \
- snd_printk(KERN_ERR "BUG? (%s) (called from %p)\n", __ASTRING__(expr), __builtin_return_address(0));\
- args;\
- }\
+#define snd_assert(expr, args...) do { \
+ if (unlikely(!(expr))) { \
+ snd_printk(KERN_ERR "BUG? (%s)\n", __ASTRING__(expr)); \
+ dump_stack(); \
+ args; \
+ } \
} while (0)
-/**
- * snd_runtime_check - run-time assertion macro
- * @expr: expression
- * @args...: the action
- *
- * This macro checks the expression in run-time and invokes the commands
- * given in the rest arguments if the assertion is failed.
- * Unlike snd_assert(), the action commands are executed even if
- * CONFIG_SND_DEBUG is not set but without any error messages.
- */
-#define snd_runtime_check(expr, args...) do {\
- if (unlikely(!(expr))) { \
- snd_printk(KERN_ERR "ERROR (%s) (called from %p)\n", __ASTRING__(expr), __builtin_return_address(0));\
- args;\
- }\
+
+#define snd_BUG() do { \
+ snd_printk(KERN_ERR "BUG?\n"); \
+ dump_stack(); \
} while (0)
#else /* !CONFIG_SND_DEBUG */
#define snd_printd(fmt, args...) /* nothing */
#define snd_assert(expr, args...) (void)(expr)
-#define snd_runtime_check(expr, args...) do { if (!(expr)) { args; } } while (0)
+#define snd_BUG() /* nothing */
#endif /* CONFIG_SND_DEBUG */
@@ -473,30 +431,6 @@ void snd_verbose_printd(const char *file, int line, const char *format, ...)
#define snd_printdd(format, args...) /* nothing */
#endif
-#define snd_BUG() snd_assert(0, )
-
-
-static inline void snd_timestamp_now(struct timespec *tstamp, int timespec)
-{
- struct timeval val;
- /* FIXME: use a linear time source */
- do_gettimeofday(&val);
- tstamp->tv_sec = val.tv_sec;
- tstamp->tv_nsec = val.tv_usec;
- if (timespec)
- tstamp->tv_nsec *= 1000L;
-}
-
-static inline void snd_timestamp_zero(struct timespec *tstamp)
-{
- tstamp->tv_sec = 0;
- tstamp->tv_nsec = 0;
-}
-
-static inline int snd_timestamp_null(struct timespec *tstamp)
-{
- return tstamp->tv_sec == 0 && tstamp->tv_nsec == 0;
-}
#define SNDRV_OSS_VERSION ((3<<16)|(8<<8)|(1<<4)|(0)) /* 3.8.1a */
diff --git a/include/sound/driver.h b/include/sound/driver.h
index 1ec2fae050a6..3f0416ac24d9 100644
--- a/include/sound/driver.h
+++ b/include/sound/driver.h
@@ -44,21 +44,4 @@
#include <linux/module.h>
-/*
- * ==========================================================================
- */
-
-#ifdef CONFIG_SND_DEBUG_MEMORY
-#include <linux/slab.h>
-#include <linux/vmalloc.h>
-void *snd_wrapper_kmalloc(size_t, gfp_t);
-#undef kmalloc
-void snd_wrapper_kfree(const void *);
-#undef kfree
-void *snd_wrapper_vmalloc(size_t);
-#undef vmalloc
-void snd_wrapper_vfree(void *);
-#undef vfree
-#endif
-
#endif /* __SOUND_DRIVER_H */
diff --git a/include/sound/emu10k1.h b/include/sound/emu10k1.h
index 14cb2718cb77..8411c7ef6f11 100644
--- a/include/sound/emu10k1.h
+++ b/include/sound/emu10k1.h
@@ -48,7 +48,8 @@
/* FIXME? - according to the OSS driver the EMU10K1 needs a 29 bit DMA mask */
#define EMU10K1_DMA_MASK 0x7fffffffUL /* 31bit */
-#define AUDIGY_DMA_MASK 0xffffffffUL /* 32bit */
+#define AUDIGY_DMA_MASK 0x7fffffffUL /* 31bit FIXME - 32 should work? */
+ /* See ALSA bug #1276 - rlrevell */
#define TMEMSIZE 256*1024
#define TMEMSIZEREG 4
@@ -1055,6 +1056,7 @@ typedef struct {
unsigned char emu10k2_chip; /* Audigy 1 or Audigy 2. */
unsigned char ca0102_chip; /* Audigy 1 or Audigy 2. Not SB Audigy 2 Value. */
unsigned char ca0108_chip; /* Audigy 2 Value */
+ unsigned char ca_cardbus_chip; /* Audigy 2 ZS Notebook */
unsigned char ca0151_chip; /* P16V */
unsigned char spk71; /* Has 7.1 speakers */
unsigned char sblive51; /* SBLive! 5.1 - extout 0x11 -> center, 0x12 -> lfe */
diff --git a/include/sound/memalloc.h b/include/sound/memalloc.h
index 3a2fd2cc9f19..83489c3abbaf 100644
--- a/include/sound/memalloc.h
+++ b/include/sound/memalloc.h
@@ -111,7 +111,7 @@ size_t snd_dma_get_reserved_buf(struct snd_dma_buffer *dmab, unsigned int id);
int snd_dma_reserve_buf(struct snd_dma_buffer *dmab, unsigned int id);
/* basic memory allocation functions */
-void *snd_malloc_pages(size_t size, unsigned int gfp_flags);
+void *snd_malloc_pages(size_t size, gfp_t gfp_flags);
void snd_free_pages(void *ptr, size_t size);
#endif /* __SOUND_MEMALLOC_H */
diff --git a/include/sound/minors.h b/include/sound/minors.h
index b7b0d8309449..a17b5c9961bb 100644
--- a/include/sound/minors.h
+++ b/include/sound/minors.h
@@ -27,8 +27,9 @@
#define SNDRV_MINOR(card, dev) (((card) << 5) | (dev))
#define SNDRV_MINOR_CONTROL 0 /* 0 - 0 */
-#define SNDRV_MINOR_SEQUENCER 1
-#define SNDRV_MINOR_TIMER (1+32)
+#define SNDRV_MINOR_GLOBAL 1 /* 1 */
+#define SNDRV_MINOR_SEQUENCER (SNDRV_MINOR_GLOBAL + 0 * 32)
+#define SNDRV_MINOR_TIMER (SNDRV_MINOR_GLOBAL + 1 * 32)
#define SNDRV_MINOR_HWDEP 4 /* 4 - 7 */
#define SNDRV_MINOR_HWDEPS 4
#define SNDRV_MINOR_RAWMIDI 8 /* 8 - 15 */
@@ -39,12 +40,9 @@
#define SNDRV_DEVICE_TYPE_CONTROL SNDRV_MINOR_CONTROL
#define SNDRV_DEVICE_TYPE_HWDEP SNDRV_MINOR_HWDEP
-#define SNDRV_DEVICE_TYPE_MIXER SNDRV_MINOR_MIXER
#define SNDRV_DEVICE_TYPE_RAWMIDI SNDRV_MINOR_RAWMIDI
#define SNDRV_DEVICE_TYPE_PCM_PLAYBACK SNDRV_MINOR_PCM_PLAYBACK
-#define SNDRV_DEVICE_TYPE_PCM_PLOOP SNDRV_MINOR_PCM_PLOOP
#define SNDRV_DEVICE_TYPE_PCM_CAPTURE SNDRV_MINOR_PCM_CAPTURE
-#define SNDRV_DEVICE_TYPE_PCM_CLOOP SNDRV_MINOR_PCM_CLOOP
#define SNDRV_DEVICE_TYPE_SEQUENCER SNDRV_MINOR_SEQUENCER
#define SNDRV_DEVICE_TYPE_TIMER SNDRV_MINOR_TIMER
diff --git a/include/sound/pcm.h b/include/sound/pcm.h
index 2b23a5967071..acc4fa9d5abe 100644
--- a/include/sound/pcm.h
+++ b/include/sound/pcm.h
@@ -281,7 +281,7 @@ typedef struct {
struct _snd_pcm_runtime {
/* -- Status -- */
snd_pcm_substream_t *trigger_master;
- snd_timestamp_t trigger_tstamp; /* trigger timestamp */
+ struct timespec trigger_tstamp; /* trigger timestamp */
int overrange;
snd_pcm_uframes_t avail_max;
snd_pcm_uframes_t hw_ptr_base; /* Position at buffer restart */
@@ -306,7 +306,6 @@ struct _snd_pcm_runtime {
unsigned int rate_den;
/* -- SW params -- */
- int tstamp_timespec; /* use timeval (0) or timespec (1) */
snd_pcm_tstamp_t tstamp_mode; /* mmap timestamp is updated */
unsigned int period_step;
unsigned int sleep_min; /* min ticks to sleep */
diff --git a/include/sound/timer.h b/include/sound/timer.h
index 1898511a0f38..b55f38ae56e1 100644
--- a/include/sound/timer.h
+++ b/include/sound/timer.h
@@ -88,6 +88,7 @@ struct _snd_timer_hardware {
struct _snd_timer {
snd_timer_class_t tmr_class;
snd_card_t *card;
+ struct module *module;
int tmr_device;
int tmr_subdevice;
char id[64];
diff --git a/include/sound/version.h b/include/sound/version.h
index ee32af20dba9..d1bd3b723967 100644
--- a/include/sound/version.h
+++ b/include/sound/version.h
@@ -1,3 +1,3 @@
/* include/version.h. Generated by configure. */
-#define CONFIG_SND_VERSION "1.0.10rc1"
-#define CONFIG_SND_DATE " (Mon Sep 12 08:13:09 2005 UTC)"
+#define CONFIG_SND_VERSION "1.0.10rc3"
+#define CONFIG_SND_DATE " (Mon Nov 07 13:30:21 2005 UTC)"
diff --git a/init/Kconfig b/init/Kconfig
index d5a1a1228fab..ea097e0a9c02 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -60,8 +60,8 @@ config INIT_ENV_ARG_LIMIT
default 32 if !USERMODE
default 128 if USERMODE
help
- This is the value of the two limits on the number of argument and of
- env.var passed to init from the kernel command line.
+ Maximum of each of the number of arguments and environment
+ variables passed to init from the kernel command line.
endmenu
@@ -501,3 +501,7 @@ config STOP_MACHINE
help
Need stop_machine() primitive.
endmenu
+
+menu "Block layer"
+source "block/Kconfig"
+endmenu
diff --git a/init/main.c b/init/main.c
index f142d4035341..27f97f9b4636 100644
--- a/init/main.c
+++ b/init/main.c
@@ -394,14 +394,16 @@ static void noinline rest_init(void)
kernel_thread(init, NULL, CLONE_FS | CLONE_SIGHAND);
numa_default_policy();
unlock_kernel();
- preempt_enable_no_resched();
/*
* The boot idle thread must execute schedule()
* at least one to get things moving:
*/
+ preempt_enable_no_resched();
schedule();
+ preempt_disable();
+ /* Call into cpu_idle with preempt disabled */
cpu_idle();
}
diff --git a/ipc/mqueue.c b/ipc/mqueue.c
index a0f18c9cc89d..c8943b53d8e6 100644
--- a/ipc/mqueue.c
+++ b/ipc/mqueue.c
@@ -2,7 +2,7 @@
* POSIX message queues filesystem for Linux.
*
* Copyright (C) 2003,2004 Krzysztof Benedyczak (golbi@mat.uni.torun.pl)
- * Michal Wronski (wrona@mat.uni.torun.pl)
+ * Michal Wronski (Michal.Wronski@motorola.com)
*
* Spinlocks: Mohamed Abbas (abbas.mohamed@intel.com)
* Lockless receive & send, fd based notify:
diff --git a/ipc/shm.c b/ipc/shm.c
index dca90489e3b0..587d836d80d9 100644
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -212,8 +212,16 @@ static int newseg (key_t key, int shmflg, size_t size)
file = hugetlb_zero_setup(size);
shp->mlock_user = current->user;
} else {
+ int acctflag = VM_ACCOUNT;
+ /*
+ * Do not allow no accounting for OVERCOMMIT_NEVER, even
+ * if it's asked for.
+ */
+ if ((shmflg & SHM_NORESERVE) &&
+ sysctl_overcommit_memory != OVERCOMMIT_NEVER)
+ acctflag = 0;
sprintf (name, "SYSV%08x", key);
- file = shmem_file_setup(name, size, VM_ACCOUNT);
+ file = shmem_file_setup(name, size, acctflag);
}
error = PTR_ERR(file);
if (IS_ERR(file))
@@ -233,10 +241,11 @@ static int newseg (key_t key, int shmflg, size_t size)
shp->id = shm_buildid(id,shp->shm_perm.seq);
shp->shm_file = file;
file->f_dentry->d_inode->i_ino = shp->id;
- if (shmflg & SHM_HUGETLB)
- set_file_hugepages(file);
- else
+
+ /* Hugetlb ops would have already been assigned. */
+ if (!(shmflg & SHM_HUGETLB))
file->f_op = &shm_file_operations;
+
shm_tot += numpages;
shm_unlock(shp);
return shp->id;
diff --git a/ipc/util.c b/ipc/util.c
index 10e836d0d89e..23f1cec150c1 100644
--- a/ipc/util.c
+++ b/ipc/util.c
@@ -410,7 +410,8 @@ void ipc_rcu_getref(void *ptr)
}
/**
- * ipc_schedule_free - free ipc + rcu space
+ * ipc_schedule_free - free ipc + rcu space
+ * @head: RCU callback structure for queued work
*
* Since RCU callback function is called in bh,
* we need to defer the vfree to schedule_work
@@ -427,10 +428,10 @@ static void ipc_schedule_free(struct rcu_head *head)
}
/**
- * ipc_immediate_free - free ipc + rcu space
- *
- * Free from the RCU callback context
+ * ipc_immediate_free - free ipc + rcu space
+ * @head: RCU callback structure that contains pointer to be freed
*
+ * Free from the RCU callback context
*/
static void ipc_immediate_free(struct rcu_head *head)
{
diff --git a/kernel/Makefile b/kernel/Makefile
index ff4dc02ce170..4f5a1453093a 100644
--- a/kernel/Makefile
+++ b/kernel/Makefile
@@ -22,7 +22,6 @@ obj-$(CONFIG_KEXEC) += kexec.o
obj-$(CONFIG_COMPAT) += compat.o
obj-$(CONFIG_CPUSETS) += cpuset.o
obj-$(CONFIG_IKCONFIG) += configs.o
-obj-$(CONFIG_IKCONFIG_PROC) += configs.o
obj-$(CONFIG_STOP_MACHINE) += stop_machine.o
obj-$(CONFIG_AUDIT) += audit.o
obj-$(CONFIG_AUDITSYSCALL) += auditsc.o
@@ -32,6 +31,7 @@ obj-$(CONFIG_DETECT_SOFTLOCKUP) += softlockup.o
obj-$(CONFIG_GENERIC_HARDIRQS) += irq/
obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
obj-$(CONFIG_SECCOMP) += seccomp.o
+obj-$(CONFIG_RCU_TORTURE_TEST) += rcutorture.o
ifneq ($(CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER),y)
# According to Alan Modra <alan@linuxcare.com.au>, the -fno-omit-frame-pointer is
diff --git a/kernel/acct.c b/kernel/acct.c
index b756f527497e..6312d6bd43e3 100644
--- a/kernel/acct.c
+++ b/kernel/acct.c
@@ -54,6 +54,7 @@
#include <linux/jiffies.h>
#include <linux/times.h>
#include <linux/syscalls.h>
+#include <linux/mount.h>
#include <asm/uaccess.h>
#include <asm/div64.h>
#include <linux/blkdev.h> /* sector_div */
@@ -192,6 +193,7 @@ static void acct_file_reopen(struct file *file)
add_timer(&acct_globals.timer);
}
if (old_acct) {
+ mnt_unpin(old_acct->f_vfsmnt);
spin_unlock(&acct_globals.lock);
do_acct_process(0, old_acct);
filp_close(old_acct, NULL);
@@ -199,6 +201,42 @@ static void acct_file_reopen(struct file *file)
}
}
+static int acct_on(char *name)
+{
+ struct file *file;
+ int error;
+
+ /* Difference from BSD - they don't do O_APPEND */
+ file = filp_open(name, O_WRONLY|O_APPEND|O_LARGEFILE, 0);
+ if (IS_ERR(file))
+ return PTR_ERR(file);
+
+ if (!S_ISREG(file->f_dentry->d_inode->i_mode)) {
+ filp_close(file, NULL);
+ return -EACCES;
+ }
+
+ if (!file->f_op->write) {
+ filp_close(file, NULL);
+ return -EIO;
+ }
+
+ error = security_acct(file);
+ if (error) {
+ filp_close(file, NULL);
+ return error;
+ }
+
+ spin_lock(&acct_globals.lock);
+ mnt_pin(file->f_vfsmnt);
+ acct_file_reopen(file);
+ spin_unlock(&acct_globals.lock);
+
+ mntput(file->f_vfsmnt); /* it's pinned, now give up active reference */
+
+ return 0;
+}
+
/**
* sys_acct - enable/disable process accounting
* @name: file name for accounting records or NULL to shutdown accounting
@@ -212,47 +250,41 @@ static void acct_file_reopen(struct file *file)
*/
asmlinkage long sys_acct(const char __user *name)
{
- struct file *file = NULL;
- char *tmp;
int error;
if (!capable(CAP_SYS_PACCT))
return -EPERM;
if (name) {
- tmp = getname(name);
- if (IS_ERR(tmp)) {
+ char *tmp = getname(name);
+ if (IS_ERR(tmp))
return (PTR_ERR(tmp));
- }
- /* Difference from BSD - they don't do O_APPEND */
- file = filp_open(tmp, O_WRONLY|O_APPEND|O_LARGEFILE, 0);
+ error = acct_on(tmp);
putname(tmp);
- if (IS_ERR(file)) {
- return (PTR_ERR(file));
- }
- if (!S_ISREG(file->f_dentry->d_inode->i_mode)) {
- filp_close(file, NULL);
- return (-EACCES);
- }
-
- if (!file->f_op->write) {
- filp_close(file, NULL);
- return (-EIO);
+ } else {
+ error = security_acct(NULL);
+ if (!error) {
+ spin_lock(&acct_globals.lock);
+ acct_file_reopen(NULL);
+ spin_unlock(&acct_globals.lock);
}
}
+ return error;
+}
- error = security_acct(file);
- if (error) {
- if (file)
- filp_close(file, NULL);
- return error;
- }
-
+/**
+ * acct_auto_close - turn off a filesystem's accounting if it is on
+ * @m: vfsmount being shut down
+ *
+ * If the accounting is turned on for a file in the subtree pointed to
+ * to by m, turn accounting off. Done when m is about to die.
+ */
+void acct_auto_close_mnt(struct vfsmount *m)
+{
spin_lock(&acct_globals.lock);
- acct_file_reopen(file);
+ if (acct_globals.file && acct_globals.file->f_vfsmnt == m)
+ acct_file_reopen(NULL);
spin_unlock(&acct_globals.lock);
-
- return (0);
}
/**
@@ -266,8 +298,8 @@ void acct_auto_close(struct super_block *sb)
{
spin_lock(&acct_globals.lock);
if (acct_globals.file &&
- acct_globals.file->f_dentry->d_inode->i_sb == sb) {
- acct_file_reopen((struct file *)NULL);
+ acct_globals.file->f_vfsmnt->mnt_sb == sb) {
+ acct_file_reopen(NULL);
}
spin_unlock(&acct_globals.lock);
}
@@ -553,7 +585,7 @@ void acct_update_integrals(struct task_struct *tsk)
if (delta == 0)
return;
tsk->acct_stimexpd = tsk->stime;
- tsk->acct_rss_mem1 += delta * get_mm_counter(tsk->mm, rss);
+ tsk->acct_rss_mem1 += delta * get_mm_rss(tsk->mm);
tsk->acct_vm_mem1 += delta * tsk->mm->total_vm;
}
}
diff --git a/kernel/audit.c b/kernel/audit.c
index aefa73a8a586..0c56320d38dc 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -133,7 +133,7 @@ struct audit_buffer {
struct list_head list;
struct sk_buff *skb; /* formatted skb ready to send */
struct audit_context *ctx; /* NULL or associated context */
- int gfp_mask;
+ gfp_t gfp_mask;
};
static void audit_set_pid(struct audit_buffer *ab, pid_t pid)
@@ -647,7 +647,7 @@ static inline void audit_get_stamp(struct audit_context *ctx,
* will be written at syscall exit. If there is no associated task, tsk
* should be NULL. */
-struct audit_buffer *audit_log_start(struct audit_context *ctx, int gfp_mask,
+struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp_mask,
int type)
{
struct audit_buffer *ab = NULL;
@@ -879,7 +879,7 @@ void audit_log_end(struct audit_buffer *ab)
/* Log an audit record. This is a convenience function that calls
* audit_log_start, audit_log_vformat, and audit_log_end. It may be
* called in any context. */
-void audit_log(struct audit_context *ctx, int gfp_mask, int type,
+void audit_log(struct audit_context *ctx, gfp_t gfp_mask, int type,
const char *fmt, ...)
{
struct audit_buffer *ab;
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index 88696f639aab..d8a68509e729 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -803,7 +803,7 @@ static void audit_log_task_info(struct audit_buffer *ab)
up_read(&mm->mmap_sem);
}
-static void audit_log_exit(struct audit_context *context, unsigned int gfp_mask)
+static void audit_log_exit(struct audit_context *context, gfp_t gfp_mask)
{
int i;
struct audit_buffer *ab;
diff --git a/kernel/cpu.c b/kernel/cpu.c
index 53d8263ae12e..d61ba88f34e5 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -17,9 +17,28 @@
/* This protects CPUs going up and down... */
DECLARE_MUTEX(cpucontrol);
+EXPORT_SYMBOL_GPL(cpucontrol);
static struct notifier_block *cpu_chain;
+/*
+ * Used to check by callers if they need to acquire the cpucontrol
+ * or not to protect a cpu from being removed. Its sometimes required to
+ * call these functions both for normal operations, and in response to
+ * a cpu being added/removed. If the context of the call is in the same
+ * thread context as a CPU hotplug thread, we dont need to take the lock
+ * since its already protected
+ * check drivers/cpufreq/cpufreq.c for its usage - Ashok Raj
+ */
+
+int current_in_cpu_hotplug(void)
+{
+ return (current->flags & PF_HOTPLUG_CPU);
+}
+
+EXPORT_SYMBOL_GPL(current_in_cpu_hotplug);
+
+
/* Need to know about CPUs going up/down? */
int register_cpu_notifier(struct notifier_block *nb)
{
@@ -93,6 +112,13 @@ int cpu_down(unsigned int cpu)
goto out;
}
+ /*
+ * Leave a trace in current->flags indicating we are already in
+ * process of performing CPU hotplug. Callers can check if cpucontrol
+ * is already acquired by current thread, and if so not cause
+ * a dead lock by not acquiring the lock
+ */
+ current->flags |= PF_HOTPLUG_CPU;
err = notifier_call_chain(&cpu_chain, CPU_DOWN_PREPARE,
(void *)(long)cpu);
if (err == NOTIFY_BAD) {
@@ -145,6 +171,7 @@ out_thread:
out_allowed:
set_cpus_allowed(current, old_allowed);
out:
+ current->flags &= ~PF_HOTPLUG_CPU;
unlock_cpu_hotplug();
return err;
}
@@ -162,6 +189,12 @@ int __devinit cpu_up(unsigned int cpu)
ret = -EINVAL;
goto out;
}
+
+ /*
+ * Leave a trace in current->flags indicating we are already in
+ * process of performing CPU hotplug.
+ */
+ current->flags |= PF_HOTPLUG_CPU;
ret = notifier_call_chain(&cpu_chain, CPU_UP_PREPARE, hcpu);
if (ret == NOTIFY_BAD) {
printk("%s: attempt to bring up CPU %u failed\n",
@@ -184,6 +217,7 @@ out_notify:
if (ret != 0)
notifier_call_chain(&cpu_chain, CPU_UP_CANCELED, hcpu);
out:
+ current->flags &= ~PF_HOTPLUG_CPU;
up(&cpucontrol);
return ret;
}
diff --git a/kernel/cpuset.c b/kernel/cpuset.c
index 28176d083f7b..5a737ed9dac7 100644
--- a/kernel/cpuset.c
+++ b/kernel/cpuset.c
@@ -32,6 +32,7 @@
#include <linux/kernel.h>
#include <linux/kmod.h>
#include <linux/list.h>
+#include <linux/mempolicy.h>
#include <linux/mm.h>
#include <linux/module.h>
#include <linux/mount.h>
@@ -60,6 +61,9 @@ struct cpuset {
cpumask_t cpus_allowed; /* CPUs allowed to tasks in cpuset */
nodemask_t mems_allowed; /* Memory Nodes allowed to tasks */
+ /*
+ * Count is atomic so can incr (fork) or decr (exit) without a lock.
+ */
atomic_t count; /* count tasks using this cpuset */
/*
@@ -142,80 +146,91 @@ static struct vfsmount *cpuset_mount;
static struct super_block *cpuset_sb = NULL;
/*
- * cpuset_sem should be held by anyone who is depending on the children
- * or sibling lists of any cpuset, or performing non-atomic operations
- * on the flags or *_allowed values of a cpuset, such as raising the
- * CS_REMOVED flag bit iff it is not already raised, or reading and
- * conditionally modifying the *_allowed values. One kernel global
- * cpuset semaphore should be sufficient - these things don't change
- * that much.
- *
- * The code that modifies cpusets holds cpuset_sem across the entire
- * operation, from cpuset_common_file_write() down, single threading
- * all cpuset modifications (except for counter manipulations from
- * fork and exit) across the system. This presumes that cpuset
- * modifications are rare - better kept simple and safe, even if slow.
- *
- * The code that reads cpusets, such as in cpuset_common_file_read()
- * and below, only holds cpuset_sem across small pieces of code, such
- * as when reading out possibly multi-word cpumasks and nodemasks, as
- * the risks are less, and the desire for performance a little greater.
- * The proc_cpuset_show() routine needs to hold cpuset_sem to insure
- * that no cs->dentry is NULL, as it walks up the cpuset tree to root.
- *
- * The hooks from fork and exit, cpuset_fork() and cpuset_exit(), don't
- * (usually) grab cpuset_sem. These are the two most performance
- * critical pieces of code here. The exception occurs on exit(),
- * when a task in a notify_on_release cpuset exits. Then cpuset_sem
+ * We have two global cpuset semaphores below. They can nest.
+ * It is ok to first take manage_sem, then nest callback_sem. We also
+ * require taking task_lock() when dereferencing a tasks cpuset pointer.
+ * See "The task_lock() exception", at the end of this comment.
+ *
+ * A task must hold both semaphores to modify cpusets. If a task
+ * holds manage_sem, then it blocks others wanting that semaphore,
+ * ensuring that it is the only task able to also acquire callback_sem
+ * and be able to modify cpusets. It can perform various checks on
+ * the cpuset structure first, knowing nothing will change. It can
+ * also allocate memory while just holding manage_sem. While it is
+ * performing these checks, various callback routines can briefly
+ * acquire callback_sem to query cpusets. Once it is ready to make
+ * the changes, it takes callback_sem, blocking everyone else.
+ *
+ * Calls to the kernel memory allocator can not be made while holding
+ * callback_sem, as that would risk double tripping on callback_sem
+ * from one of the callbacks into the cpuset code from within
+ * __alloc_pages().
+ *
+ * If a task is only holding callback_sem, then it has read-only
+ * access to cpusets.
+ *
+ * The task_struct fields mems_allowed and mems_generation may only
+ * be accessed in the context of that task, so require no locks.
+ *
+ * Any task can increment and decrement the count field without lock.
+ * So in general, code holding manage_sem or callback_sem can't rely
+ * on the count field not changing. However, if the count goes to
+ * zero, then only attach_task(), which holds both semaphores, can
+ * increment it again. Because a count of zero means that no tasks
+ * are currently attached, therefore there is no way a task attached
+ * to that cpuset can fork (the other way to increment the count).
+ * So code holding manage_sem or callback_sem can safely assume that
+ * if the count is zero, it will stay zero. Similarly, if a task
+ * holds manage_sem or callback_sem on a cpuset with zero count, it
+ * knows that the cpuset won't be removed, as cpuset_rmdir() needs
+ * both of those semaphores.
+ *
+ * A possible optimization to improve parallelism would be to make
+ * callback_sem a R/W semaphore (rwsem), allowing the callback routines
+ * to proceed in parallel, with read access, until the holder of
+ * manage_sem needed to take this rwsem for exclusive write access
+ * and modify some cpusets.
+ *
+ * The cpuset_common_file_write handler for operations that modify
+ * the cpuset hierarchy holds manage_sem across the entire operation,
+ * single threading all such cpuset modifications across the system.
+ *
+ * The cpuset_common_file_read() handlers only hold callback_sem across
+ * small pieces of code, such as when reading out possibly multi-word
+ * cpumasks and nodemasks.
+ *
+ * The fork and exit callbacks cpuset_fork() and cpuset_exit(), don't
+ * (usually) take either semaphore. These are the two most performance
+ * critical pieces of code here. The exception occurs on cpuset_exit(),
+ * when a task in a notify_on_release cpuset exits. Then manage_sem
* is taken, and if the cpuset count is zero, a usermode call made
* to /sbin/cpuset_release_agent with the name of the cpuset (path
* relative to the root of cpuset file system) as the argument.
*
- * A cpuset can only be deleted if both its 'count' of using tasks is
- * zero, and its list of 'children' cpusets is empty. Since all tasks
- * in the system use _some_ cpuset, and since there is always at least
- * one task in the system (init, pid == 1), therefore, top_cpuset
- * always has either children cpusets and/or using tasks. So no need
- * for any special hack to ensure that top_cpuset cannot be deleted.
+ * A cpuset can only be deleted if both its 'count' of using tasks
+ * is zero, and its list of 'children' cpusets is empty. Since all
+ * tasks in the system use _some_ cpuset, and since there is always at
+ * least one task in the system (init, pid == 1), therefore, top_cpuset
+ * always has either children cpusets and/or using tasks. So we don't
+ * need a special hack to ensure that top_cpuset cannot be deleted.
+ *
+ * The above "Tale of Two Semaphores" would be complete, but for:
+ *
+ * The task_lock() exception
+ *
+ * The need for this exception arises from the action of attach_task(),
+ * which overwrites one tasks cpuset pointer with another. It does
+ * so using both semaphores, however there are several performance
+ * critical places that need to reference task->cpuset without the
+ * expense of grabbing a system global semaphore. Therefore except as
+ * noted below, when dereferencing or, as in attach_task(), modifying
+ * a tasks cpuset pointer we use task_lock(), which acts on a spinlock
+ * (task->alloc_lock) already in the task_struct routinely used for
+ * such matters.
*/
-static DECLARE_MUTEX(cpuset_sem);
-static struct task_struct *cpuset_sem_owner;
-static int cpuset_sem_depth;
-
-/*
- * The global cpuset semaphore cpuset_sem can be needed by the
- * memory allocator to update a tasks mems_allowed (see the calls
- * to cpuset_update_current_mems_allowed()) or to walk up the
- * cpuset hierarchy to find a mem_exclusive cpuset see the calls
- * to cpuset_excl_nodes_overlap()).
- *
- * But if the memory allocation is being done by cpuset.c code, it
- * usually already holds cpuset_sem. Double tripping on a kernel
- * semaphore deadlocks the current task, and any other task that
- * subsequently tries to obtain the lock.
- *
- * Run all up's and down's on cpuset_sem through the following
- * wrappers, which will detect this nested locking, and avoid
- * deadlocking.
- */
-
-static inline void cpuset_down(struct semaphore *psem)
-{
- if (cpuset_sem_owner != current) {
- down(psem);
- cpuset_sem_owner = current;
- }
- cpuset_sem_depth++;
-}
-
-static inline void cpuset_up(struct semaphore *psem)
-{
- if (--cpuset_sem_depth == 0) {
- cpuset_sem_owner = NULL;
- up(psem);
- }
-}
+static DECLARE_MUTEX(manage_sem);
+static DECLARE_MUTEX(callback_sem);
/*
* A couple of forward declarations required, due to cyclic reference loop:
@@ -390,7 +405,7 @@ static inline struct cftype *__d_cft(struct dentry *dentry)
}
/*
- * Call with cpuset_sem held. Writes path of cpuset into buf.
+ * Call with manage_sem held. Writes path of cpuset into buf.
* Returns 0 on success, -errno on error.
*/
@@ -442,10 +457,11 @@ static int cpuset_path(const struct cpuset *cs, char *buf, int buflen)
* status of the /sbin/cpuset_release_agent task, so no sense holding
* our caller up for that.
*
- * The simple act of forking that task might require more memory,
- * which might need cpuset_sem. So this routine must be called while
- * cpuset_sem is not held, to avoid a possible deadlock. See also
- * comments for check_for_release(), below.
+ * When we had only one cpuset semaphore, we had to call this
+ * without holding it, to avoid deadlock when call_usermodehelper()
+ * allocated memory. With two locks, we could now call this while
+ * holding manage_sem, but we still don't, so as to minimize
+ * the time manage_sem is held.
*/
static void cpuset_release_agent(const char *pathbuf)
@@ -477,15 +493,15 @@ static void cpuset_release_agent(const char *pathbuf)
* cs is notify_on_release() and now both the user count is zero and
* the list of children is empty, prepare cpuset path in a kmalloc'd
* buffer, to be returned via ppathbuf, so that the caller can invoke
- * cpuset_release_agent() with it later on, once cpuset_sem is dropped.
- * Call here with cpuset_sem held.
+ * cpuset_release_agent() with it later on, once manage_sem is dropped.
+ * Call here with manage_sem held.
*
* This check_for_release() routine is responsible for kmalloc'ing
* pathbuf. The above cpuset_release_agent() is responsible for
* kfree'ing pathbuf. The caller of these routines is responsible
* for providing a pathbuf pointer, initialized to NULL, then
- * calling check_for_release() with cpuset_sem held and the address
- * of the pathbuf pointer, then dropping cpuset_sem, then calling
+ * calling check_for_release() with manage_sem held and the address
+ * of the pathbuf pointer, then dropping manage_sem, then calling
* cpuset_release_agent() with pathbuf, as set by check_for_release().
*/
@@ -516,7 +532,7 @@ static void check_for_release(struct cpuset *cs, char **ppathbuf)
* One way or another, we guarantee to return some non-empty subset
* of cpu_online_map.
*
- * Call with cpuset_sem held.
+ * Call with callback_sem held.
*/
static void guarantee_online_cpus(const struct cpuset *cs, cpumask_t *pmask)
@@ -540,7 +556,7 @@ static void guarantee_online_cpus(const struct cpuset *cs, cpumask_t *pmask)
* One way or another, we guarantee to return some non-empty subset
* of node_online_map.
*
- * Call with cpuset_sem held.
+ * Call with callback_sem held.
*/
static void guarantee_online_mems(const struct cpuset *cs, nodemask_t *pmask)
@@ -555,22 +571,47 @@ static void guarantee_online_mems(const struct cpuset *cs, nodemask_t *pmask)
}
/*
- * Refresh current tasks mems_allowed and mems_generation from
- * current tasks cpuset. Call with cpuset_sem held.
+ * Refresh current tasks mems_allowed and mems_generation from current
+ * tasks cpuset.
*
- * This routine is needed to update the per-task mems_allowed
- * data, within the tasks context, when it is trying to allocate
- * memory (in various mm/mempolicy.c routines) and notices
- * that some other task has been modifying its cpuset.
+ * Call without callback_sem or task_lock() held. May be called with
+ * or without manage_sem held. Will acquire task_lock() and might
+ * acquire callback_sem during call.
+ *
+ * The task_lock() is required to dereference current->cpuset safely.
+ * Without it, we could pick up the pointer value of current->cpuset
+ * in one instruction, and then attach_task could give us a different
+ * cpuset, and then the cpuset we had could be removed and freed,
+ * and then on our next instruction, we could dereference a no longer
+ * valid cpuset pointer to get its mems_generation field.
+ *
+ * This routine is needed to update the per-task mems_allowed data,
+ * within the tasks context, when it is trying to allocate memory
+ * (in various mm/mempolicy.c routines) and notices that some other
+ * task has been modifying its cpuset.
*/
static void refresh_mems(void)
{
- struct cpuset *cs = current->cpuset;
+ int my_cpusets_mem_gen;
+
+ task_lock(current);
+ my_cpusets_mem_gen = current->cpuset->mems_generation;
+ task_unlock(current);
- if (current->cpuset_mems_generation != cs->mems_generation) {
+ if (current->cpuset_mems_generation != my_cpusets_mem_gen) {
+ struct cpuset *cs;
+ nodemask_t oldmem = current->mems_allowed;
+
+ down(&callback_sem);
+ task_lock(current);
+ cs = current->cpuset;
guarantee_online_mems(cs, &current->mems_allowed);
current->cpuset_mems_generation = cs->mems_generation;
+ task_unlock(current);
+ up(&callback_sem);
+ if (!nodes_equal(oldmem, current->mems_allowed))
+ numa_policy_rebind(&oldmem, &current->mems_allowed);
}
}
@@ -579,7 +620,7 @@ static void refresh_mems(void)
*
* One cpuset is a subset of another if all its allowed CPUs and
* Memory Nodes are a subset of the other, and its exclusive flags
- * are only set if the other's are set.
+ * are only set if the other's are set. Call holding manage_sem.
*/
static int is_cpuset_subset(const struct cpuset *p, const struct cpuset *q)
@@ -597,7 +638,7 @@ static int is_cpuset_subset(const struct cpuset *p, const struct cpuset *q)
* If we replaced the flag and mask values of the current cpuset
* (cur) with those values in the trial cpuset (trial), would
* our various subset and exclusive rules still be valid? Presumes
- * cpuset_sem held.
+ * manage_sem held.
*
* 'cur' is the address of an actual, in-use cpuset. Operations
* such as list traversal that depend on the actual address of the
@@ -651,7 +692,7 @@ static int validate_change(const struct cpuset *cur, const struct cpuset *trial)
* exclusive child cpusets
* Build these two partitions by calling partition_sched_domains
*
- * Call with cpuset_sem held. May nest a call to the
+ * Call with manage_sem held. May nest a call to the
* lock_cpu_hotplug()/unlock_cpu_hotplug() pair.
*/
@@ -696,6 +737,10 @@ static void update_cpu_domains(struct cpuset *cur)
unlock_cpu_hotplug();
}
+/*
+ * Call with manage_sem held. May take callback_sem during call.
+ */
+
static int update_cpumask(struct cpuset *cs, char *buf)
{
struct cpuset trialcs;
@@ -712,12 +757,18 @@ static int update_cpumask(struct cpuset *cs, char *buf)
if (retval < 0)
return retval;
cpus_unchanged = cpus_equal(cs->cpus_allowed, trialcs.cpus_allowed);
+ down(&callback_sem);
cs->cpus_allowed = trialcs.cpus_allowed;
+ up(&callback_sem);
if (is_cpu_exclusive(cs) && !cpus_unchanged)
update_cpu_domains(cs);
return 0;
}
+/*
+ * Call with manage_sem held. May take callback_sem during call.
+ */
+
static int update_nodemask(struct cpuset *cs, char *buf)
{
struct cpuset trialcs;
@@ -732,9 +783,11 @@ static int update_nodemask(struct cpuset *cs, char *buf)
return -ENOSPC;
retval = validate_change(cs, &trialcs);
if (retval == 0) {
+ down(&callback_sem);
cs->mems_allowed = trialcs.mems_allowed;
atomic_inc(&cpuset_mems_generation);
cs->mems_generation = atomic_read(&cpuset_mems_generation);
+ up(&callback_sem);
}
return retval;
}
@@ -745,6 +798,8 @@ static int update_nodemask(struct cpuset *cs, char *buf)
* CS_NOTIFY_ON_RELEASE)
* cs: the cpuset to update
* buf: the buffer where we read the 0 or 1
+ *
+ * Call with manage_sem held.
*/
static int update_flag(cpuset_flagbits_t bit, struct cpuset *cs, char *buf)
@@ -766,16 +821,27 @@ static int update_flag(cpuset_flagbits_t bit, struct cpuset *cs, char *buf)
return err;
cpu_exclusive_changed =
(is_cpu_exclusive(cs) != is_cpu_exclusive(&trialcs));
+ down(&callback_sem);
if (turning_on)
set_bit(bit, &cs->flags);
else
clear_bit(bit, &cs->flags);
+ up(&callback_sem);
if (cpu_exclusive_changed)
update_cpu_domains(cs);
return 0;
}
+/*
+ * Attack task specified by pid in 'pidbuf' to cpuset 'cs', possibly
+ * writing the path of the old cpuset in 'ppathbuf' if it needs to be
+ * notified on release.
+ *
+ * Call holding manage_sem. May take callback_sem and task_lock of
+ * the task 'pid' during call.
+ */
+
static int attach_task(struct cpuset *cs, char *pidbuf, char **ppathbuf)
{
pid_t pid;
@@ -792,7 +858,7 @@ static int attach_task(struct cpuset *cs, char *pidbuf, char **ppathbuf)
read_lock(&tasklist_lock);
tsk = find_task_by_pid(pid);
- if (!tsk) {
+ if (!tsk || tsk->flags & PF_EXITING) {
read_unlock(&tasklist_lock);
return -ESRCH;
}
@@ -810,10 +876,13 @@ static int attach_task(struct cpuset *cs, char *pidbuf, char **ppathbuf)
get_task_struct(tsk);
}
+ down(&callback_sem);
+
task_lock(tsk);
oldcs = tsk->cpuset;
if (!oldcs) {
task_unlock(tsk);
+ up(&callback_sem);
put_task_struct(tsk);
return -ESRCH;
}
@@ -824,6 +893,7 @@ static int attach_task(struct cpuset *cs, char *pidbuf, char **ppathbuf)
guarantee_online_cpus(cs, &cpus);
set_cpus_allowed(tsk, cpus);
+ up(&callback_sem);
put_task_struct(tsk);
if (atomic_dec_and_test(&oldcs->count))
check_for_release(oldcs, ppathbuf);
@@ -867,7 +937,7 @@ static ssize_t cpuset_common_file_write(struct file *file, const char __user *us
}
buffer[nbytes] = 0; /* nul-terminate */
- cpuset_down(&cpuset_sem);
+ down(&manage_sem);
if (is_removed(cs)) {
retval = -ENODEV;
@@ -901,7 +971,7 @@ static ssize_t cpuset_common_file_write(struct file *file, const char __user *us
if (retval == 0)
retval = nbytes;
out2:
- cpuset_up(&cpuset_sem);
+ up(&manage_sem);
cpuset_release_agent(pathbuf);
out1:
kfree(buffer);
@@ -941,9 +1011,9 @@ static int cpuset_sprintf_cpulist(char *page, struct cpuset *cs)
{
cpumask_t mask;
- cpuset_down(&cpuset_sem);
+ down(&callback_sem);
mask = cs->cpus_allowed;
- cpuset_up(&cpuset_sem);
+ up(&callback_sem);
return cpulist_scnprintf(page, PAGE_SIZE, mask);
}
@@ -952,9 +1022,9 @@ static int cpuset_sprintf_memlist(char *page, struct cpuset *cs)
{
nodemask_t mask;
- cpuset_down(&cpuset_sem);
+ down(&callback_sem);
mask = cs->mems_allowed;
- cpuset_up(&cpuset_sem);
+ up(&callback_sem);
return nodelist_scnprintf(page, PAGE_SIZE, mask);
}
@@ -995,7 +1065,6 @@ static ssize_t cpuset_common_file_read(struct file *file, char __user *buf,
goto out;
}
*s++ = '\n';
- *s = '\0';
retval = simple_read_from_buffer(buf, nbytes, ppos, page, s - page);
out:
@@ -1048,6 +1117,21 @@ static int cpuset_file_release(struct inode *inode, struct file *file)
return 0;
}
+/*
+ * cpuset_rename - Only allow simple rename of directories in place.
+ */
+static int cpuset_rename(struct inode *old_dir, struct dentry *old_dentry,
+ struct inode *new_dir, struct dentry *new_dentry)
+{
+ if (!S_ISDIR(old_dentry->d_inode->i_mode))
+ return -ENOTDIR;
+ if (new_dentry->d_inode)
+ return -EEXIST;
+ if (old_dir != new_dir)
+ return -EIO;
+ return simple_rename(old_dir, old_dentry, new_dir, new_dentry);
+}
+
static struct file_operations cpuset_file_operations = {
.read = cpuset_file_read,
.write = cpuset_file_write,
@@ -1060,6 +1144,7 @@ static struct inode_operations cpuset_dir_inode_operations = {
.lookup = simple_lookup,
.mkdir = cpuset_mkdir,
.rmdir = cpuset_rmdir,
+ .rename = cpuset_rename,
};
static int cpuset_create_file(struct dentry *dentry, int mode)
@@ -1163,7 +1248,9 @@ struct ctr_struct {
/*
* Load into 'pidarray' up to 'npids' of the tasks using cpuset 'cs'.
- * Return actual number of pids loaded.
+ * Return actual number of pids loaded. No need to task_lock(p)
+ * when reading out p->cpuset, as we don't really care if it changes
+ * on the next cycle, and we are not going to try to dereference it.
*/
static inline int pid_array_load(pid_t *pidarray, int npids, struct cpuset *cs)
{
@@ -1205,6 +1292,12 @@ static int pid_array_to_buf(char *buf, int sz, pid_t *a, int npids)
return cnt;
}
+/*
+ * Handle an open on 'tasks' file. Prepare a buffer listing the
+ * process id's of tasks currently attached to the cpuset being opened.
+ *
+ * Does not require any specific cpuset semaphores, and does not take any.
+ */
static int cpuset_tasks_open(struct inode *unused, struct file *file)
{
struct cpuset *cs = __d_cs(file->f_dentry->d_parent);
@@ -1352,7 +1445,8 @@ static long cpuset_create(struct cpuset *parent, const char *name, int mode)
if (!cs)
return -ENOMEM;
- cpuset_down(&cpuset_sem);
+ down(&manage_sem);
+ refresh_mems();
cs->flags = 0;
if (notify_on_release(parent))
set_bit(CS_NOTIFY_ON_RELEASE, &cs->flags);
@@ -1366,25 +1460,27 @@ static long cpuset_create(struct cpuset *parent, const char *name, int mode)
cs->parent = parent;
+ down(&callback_sem);
list_add(&cs->sibling, &cs->parent->children);
+ up(&callback_sem);
err = cpuset_create_dir(cs, name, mode);
if (err < 0)
goto err;
/*
- * Release cpuset_sem before cpuset_populate_dir() because it
+ * Release manage_sem before cpuset_populate_dir() because it
* will down() this new directory's i_sem and if we race with
* another mkdir, we might deadlock.
*/
- cpuset_up(&cpuset_sem);
+ up(&manage_sem);
err = cpuset_populate_dir(cs->dentry);
/* If err < 0, we have a half-filled directory - oh well ;) */
return 0;
err:
list_del(&cs->sibling);
- cpuset_up(&cpuset_sem);
+ up(&manage_sem);
kfree(cs);
return err;
}
@@ -1406,29 +1502,32 @@ static int cpuset_rmdir(struct inode *unused_dir, struct dentry *dentry)
/* the vfs holds both inode->i_sem already */
- cpuset_down(&cpuset_sem);
+ down(&manage_sem);
+ refresh_mems();
if (atomic_read(&cs->count) > 0) {
- cpuset_up(&cpuset_sem);
+ up(&manage_sem);
return -EBUSY;
}
if (!list_empty(&cs->children)) {
- cpuset_up(&cpuset_sem);
+ up(&manage_sem);
return -EBUSY;
}
parent = cs->parent;
+ down(&callback_sem);
set_bit(CS_REMOVED, &cs->flags);
if (is_cpu_exclusive(cs))
update_cpu_domains(cs);
list_del(&cs->sibling); /* delete my sibling from parent->children */
- if (list_empty(&parent->children))
- check_for_release(parent, &pathbuf);
spin_lock(&cs->dentry->d_lock);
d = dget(cs->dentry);
cs->dentry = NULL;
spin_unlock(&d->d_lock);
cpuset_d_remove_dir(d);
dput(d);
- cpuset_up(&cpuset_sem);
+ up(&callback_sem);
+ if (list_empty(&parent->children))
+ check_for_release(parent, &pathbuf);
+ up(&manage_sem);
cpuset_release_agent(pathbuf);
return 0;
}
@@ -1488,16 +1587,26 @@ void __init cpuset_init_smp(void)
* cpuset_fork - attach newly forked task to its parents cpuset.
* @tsk: pointer to task_struct of forking parent process.
*
- * Description: By default, on fork, a task inherits its
- * parent's cpuset. The pointer to the shared cpuset is
- * automatically copied in fork.c by dup_task_struct().
- * This cpuset_fork() routine need only increment the usage
- * counter in that cpuset.
+ * Description: A task inherits its parent's cpuset at fork().
+ *
+ * A pointer to the shared cpuset was automatically copied in fork.c
+ * by dup_task_struct(). However, we ignore that copy, since it was
+ * not made under the protection of task_lock(), so might no longer be
+ * a valid cpuset pointer. attach_task() might have already changed
+ * current->cpuset, allowing the previously referenced cpuset to
+ * be removed and freed. Instead, we task_lock(current) and copy
+ * its present value of current->cpuset for our freshly forked child.
+ *
+ * At the point that cpuset_fork() is called, 'current' is the parent
+ * task, and the passed argument 'child' points to the child task.
**/
-void cpuset_fork(struct task_struct *tsk)
+void cpuset_fork(struct task_struct *child)
{
- atomic_inc(&tsk->cpuset->count);
+ task_lock(current);
+ child->cpuset = current->cpuset;
+ atomic_inc(&child->cpuset->count);
+ task_unlock(current);
}
/**
@@ -1506,35 +1615,42 @@ void cpuset_fork(struct task_struct *tsk)
*
* Description: Detach cpuset from @tsk and release it.
*
- * Note that cpusets marked notify_on_release force every task
- * in them to take the global cpuset_sem semaphore when exiting.
- * This could impact scaling on very large systems. Be reluctant
- * to use notify_on_release cpusets where very high task exit
- * scaling is required on large systems.
- *
- * Don't even think about derefencing 'cs' after the cpuset use
- * count goes to zero, except inside a critical section guarded
- * by the cpuset_sem semaphore. If you don't hold cpuset_sem,
- * then a zero cpuset use count is a license to any other task to
- * nuke the cpuset immediately.
+ * Note that cpusets marked notify_on_release force every task in
+ * them to take the global manage_sem semaphore when exiting.
+ * This could impact scaling on very large systems. Be reluctant to
+ * use notify_on_release cpusets where very high task exit scaling
+ * is required on large systems.
+ *
+ * Don't even think about derefencing 'cs' after the cpuset use count
+ * goes to zero, except inside a critical section guarded by manage_sem
+ * or callback_sem. Otherwise a zero cpuset use count is a license to
+ * any other task to nuke the cpuset immediately, via cpuset_rmdir().
+ *
+ * This routine has to take manage_sem, not callback_sem, because
+ * it is holding that semaphore while calling check_for_release(),
+ * which calls kmalloc(), so can't be called holding callback__sem().
+ *
+ * We don't need to task_lock() this reference to tsk->cpuset,
+ * because tsk is already marked PF_EXITING, so attach_task() won't
+ * mess with it.
**/
void cpuset_exit(struct task_struct *tsk)
{
struct cpuset *cs;
- task_lock(tsk);
+ BUG_ON(!(tsk->flags & PF_EXITING));
+
cs = tsk->cpuset;
tsk->cpuset = NULL;
- task_unlock(tsk);
if (notify_on_release(cs)) {
char *pathbuf = NULL;
- cpuset_down(&cpuset_sem);
+ down(&manage_sem);
if (atomic_dec_and_test(&cs->count))
check_for_release(cs, &pathbuf);
- cpuset_up(&cpuset_sem);
+ up(&manage_sem);
cpuset_release_agent(pathbuf);
} else {
atomic_dec(&cs->count);
@@ -1555,11 +1671,11 @@ cpumask_t cpuset_cpus_allowed(const struct task_struct *tsk)
{
cpumask_t mask;
- cpuset_down(&cpuset_sem);
+ down(&callback_sem);
task_lock((struct task_struct *)tsk);
guarantee_online_cpus(tsk->cpuset, &mask);
task_unlock((struct task_struct *)tsk);
- cpuset_up(&cpuset_sem);
+ up(&callback_sem);
return mask;
}
@@ -1575,19 +1691,28 @@ void cpuset_init_current_mems_allowed(void)
* If the current tasks cpusets mems_allowed changed behind our backs,
* update current->mems_allowed and mems_generation to the new value.
* Do not call this routine if in_interrupt().
+ *
+ * Call without callback_sem or task_lock() held. May be called
+ * with or without manage_sem held. Unless exiting, it will acquire
+ * task_lock(). Also might acquire callback_sem during call to
+ * refresh_mems().
*/
void cpuset_update_current_mems_allowed(void)
{
- struct cpuset *cs = current->cpuset;
+ struct cpuset *cs;
+ int need_to_refresh = 0;
+ task_lock(current);
+ cs = current->cpuset;
if (!cs)
- return; /* task is exiting */
- if (current->cpuset_mems_generation != cs->mems_generation) {
- cpuset_down(&cpuset_sem);
+ goto done;
+ if (current->cpuset_mems_generation != cs->mems_generation)
+ need_to_refresh = 1;
+done:
+ task_unlock(current);
+ if (need_to_refresh)
refresh_mems();
- cpuset_up(&cpuset_sem);
- }
}
/**
@@ -1621,7 +1746,7 @@ int cpuset_zonelist_valid_mems_allowed(struct zonelist *zl)
/*
* nearest_exclusive_ancestor() - Returns the nearest mem_exclusive
- * ancestor to the specified cpuset. Call while holding cpuset_sem.
+ * ancestor to the specified cpuset. Call holding callback_sem.
* If no ancestor is mem_exclusive (an unusual configuration), then
* returns the root cpuset.
*/
@@ -1648,12 +1773,12 @@ static const struct cpuset *nearest_exclusive_ancestor(const struct cpuset *cs)
* GFP_KERNEL allocations are not so marked, so can escape to the
* nearest mem_exclusive ancestor cpuset.
*
- * Scanning up parent cpusets requires cpuset_sem. The __alloc_pages()
+ * Scanning up parent cpusets requires callback_sem. The __alloc_pages()
* routine only calls here with __GFP_HARDWALL bit _not_ set if
* it's a GFP_KERNEL allocation, and all nodes in the current tasks
* mems_allowed came up empty on the first pass over the zonelist.
* So only GFP_KERNEL allocations, if all nodes in the cpuset are
- * short of memory, might require taking the cpuset_sem semaphore.
+ * short of memory, might require taking the callback_sem semaphore.
*
* The first loop over the zonelist in mm/page_alloc.c:__alloc_pages()
* calls here with __GFP_HARDWALL always set in gfp_mask, enforcing
@@ -1685,14 +1810,16 @@ int cpuset_zone_allowed(struct zone *z, gfp_t gfp_mask)
return 0;
/* Not hardwall and node outside mems_allowed: scan up cpusets */
- cpuset_down(&cpuset_sem);
- cs = current->cpuset;
- if (!cs)
- goto done; /* current task exiting */
- cs = nearest_exclusive_ancestor(cs);
+ down(&callback_sem);
+
+ if (current->flags & PF_EXITING) /* Let dying task have memory */
+ return 1;
+ task_lock(current);
+ cs = nearest_exclusive_ancestor(current->cpuset);
+ task_unlock(current);
+
allowed = node_isset(node, cs->mems_allowed);
-done:
- cpuset_up(&cpuset_sem);
+ up(&callback_sem);
return allowed;
}
@@ -1705,7 +1832,7 @@ done:
* determine if task @p's memory usage might impact the memory
* available to the current task.
*
- * Acquires cpuset_sem - not suitable for calling from a fast path.
+ * Acquires callback_sem - not suitable for calling from a fast path.
**/
int cpuset_excl_nodes_overlap(const struct task_struct *p)
@@ -1713,18 +1840,27 @@ int cpuset_excl_nodes_overlap(const struct task_struct *p)
const struct cpuset *cs1, *cs2; /* my and p's cpuset ancestors */
int overlap = 0; /* do cpusets overlap? */
- cpuset_down(&cpuset_sem);
- cs1 = current->cpuset;
- if (!cs1)
- goto done; /* current task exiting */
- cs2 = p->cpuset;
- if (!cs2)
- goto done; /* task p is exiting */
- cs1 = nearest_exclusive_ancestor(cs1);
- cs2 = nearest_exclusive_ancestor(cs2);
+ down(&callback_sem);
+
+ task_lock(current);
+ if (current->flags & PF_EXITING) {
+ task_unlock(current);
+ goto done;
+ }
+ cs1 = nearest_exclusive_ancestor(current->cpuset);
+ task_unlock(current);
+
+ task_lock((struct task_struct *)p);
+ if (p->flags & PF_EXITING) {
+ task_unlock((struct task_struct *)p);
+ goto done;
+ }
+ cs2 = nearest_exclusive_ancestor(p->cpuset);
+ task_unlock((struct task_struct *)p);
+
overlap = nodes_intersects(cs1->mems_allowed, cs2->mems_allowed);
done:
- cpuset_up(&cpuset_sem);
+ up(&callback_sem);
return overlap;
}
@@ -1733,6 +1869,10 @@ done:
* proc_cpuset_show()
* - Print tasks cpuset path into seq_file.
* - Used for /proc/<pid>/cpuset.
+ * - No need to task_lock(tsk) on this tsk->cpuset reference, as it
+ * doesn't really matter if tsk->cpuset changes after we read it,
+ * and we take manage_sem, keeping attach_task() from changing it
+ * anyway.
*/
static int proc_cpuset_show(struct seq_file *m, void *v)
@@ -1747,10 +1887,8 @@ static int proc_cpuset_show(struct seq_file *m, void *v)
return -ENOMEM;
tsk = m->private;
- cpuset_down(&cpuset_sem);
- task_lock(tsk);
+ down(&manage_sem);
cs = tsk->cpuset;
- task_unlock(tsk);
if (!cs) {
retval = -EINVAL;
goto out;
@@ -1762,7 +1900,7 @@ static int proc_cpuset_show(struct seq_file *m, void *v)
seq_puts(m, buf);
seq_putc(m, '\n');
out:
- cpuset_up(&cpuset_sem);
+ up(&manage_sem);
kfree(buf);
return retval;
}
diff --git a/kernel/exit.c b/kernel/exit.c
index 3b25b182d2be..452a1d116178 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -28,6 +28,7 @@
#include <linux/cpuset.h>
#include <linux/syscalls.h>
#include <linux/signal.h>
+#include <linux/cn_proc.h>
#include <asm/uaccess.h>
#include <asm/unistd.h>
@@ -547,7 +548,7 @@ static inline void reparent_thread(task_t *p, task_t *father, int traced)
if (p->pdeath_signal)
/* We already hold the tasklist_lock here. */
- group_send_sig_info(p->pdeath_signal, (void *) 0, p);
+ group_send_sig_info(p->pdeath_signal, SEND_SIG_NOINFO, p);
/* Move the child from its dying parent to the new one. */
if (unlikely(traced)) {
@@ -591,8 +592,8 @@ static inline void reparent_thread(task_t *p, task_t *father, int traced)
int pgrp = process_group(p);
if (will_become_orphaned_pgrp(pgrp, NULL) && has_stopped_jobs(pgrp)) {
- __kill_pg_info(SIGHUP, (void *)1, pgrp);
- __kill_pg_info(SIGCONT, (void *)1, pgrp);
+ __kill_pg_info(SIGHUP, SEND_SIG_PRIV, pgrp);
+ __kill_pg_info(SIGCONT, SEND_SIG_PRIV, pgrp);
}
}
}
@@ -727,8 +728,8 @@ static void exit_notify(struct task_struct *tsk)
(t->signal->session == tsk->signal->session) &&
will_become_orphaned_pgrp(process_group(tsk), tsk) &&
has_stopped_jobs(process_group(tsk))) {
- __kill_pg_info(SIGHUP, (void *)1, process_group(tsk));
- __kill_pg_info(SIGCONT, (void *)1, process_group(tsk));
+ __kill_pg_info(SIGHUP, SEND_SIG_PRIV, process_group(tsk));
+ __kill_pg_info(SIGCONT, SEND_SIG_PRIV, process_group(tsk));
}
/* Let father know we died
@@ -783,10 +784,6 @@ static void exit_notify(struct task_struct *tsk)
/* If the process is dead, release it - nobody will wait for it */
if (state == EXIT_DEAD)
release_task(tsk);
-
- /* PF_DEAD causes final put_task_struct after we schedule. */
- preempt_disable();
- tsk->flags |= PF_DEAD;
}
fastcall NORET_TYPE void do_exit(long code)
@@ -839,7 +836,10 @@ fastcall NORET_TYPE void do_exit(long code)
preempt_count());
acct_update_integrals(tsk);
- update_mem_hiwater(tsk);
+ if (tsk->mm) {
+ update_hiwater_rss(tsk->mm);
+ update_hiwater_vm(tsk->mm);
+ }
group_dead = atomic_dec_and_test(&tsk->signal->live);
if (group_dead) {
del_timer_sync(&tsk->signal->real_timer);
@@ -864,13 +864,18 @@ fastcall NORET_TYPE void do_exit(long code)
module_put(tsk->binfmt->module);
tsk->exit_code = code;
+ proc_exit_connector(tsk);
exit_notify(tsk);
#ifdef CONFIG_NUMA
mpol_free(tsk->mempolicy);
tsk->mempolicy = NULL;
#endif
- BUG_ON(!(current->flags & PF_DEAD));
+ /* PF_DEAD causes final put_task_struct after we schedule. */
+ preempt_disable();
+ BUG_ON(tsk->flags & PF_DEAD);
+ tsk->flags |= PF_DEAD;
+
schedule();
BUG();
/* Avoid "noreturn function does return". */
@@ -1380,6 +1385,15 @@ repeat:
switch (p->state) {
case TASK_TRACED:
+ /*
+ * When we hit the race with PTRACE_ATTACH,
+ * we will not report this child. But the
+ * race means it has not yet been moved to
+ * our ptrace_children list, so we need to
+ * set the flag here to avoid a spurious ECHILD
+ * when the race happens with the only child.
+ */
+ flag = 1;
if (!my_ptrace_child(p))
continue;
/*FALLTHROUGH*/
diff --git a/kernel/fork.c b/kernel/fork.c
index 280bd44ac441..158710d22566 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -42,6 +42,7 @@
#include <linux/profile.h>
#include <linux/rmap.h>
#include <linux/acct.h>
+#include <linux/cn_proc.h>
#include <asm/pgtable.h>
#include <asm/pgalloc.h>
@@ -182,37 +183,37 @@ static struct task_struct *dup_task_struct(struct task_struct *orig)
}
#ifdef CONFIG_MMU
-static inline int dup_mmap(struct mm_struct * mm, struct mm_struct * oldmm)
+static inline int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm)
{
- struct vm_area_struct * mpnt, *tmp, **pprev;
+ struct vm_area_struct *mpnt, *tmp, **pprev;
struct rb_node **rb_link, *rb_parent;
int retval;
unsigned long charge;
struct mempolicy *pol;
down_write(&oldmm->mmap_sem);
- flush_cache_mm(current->mm);
+ flush_cache_mm(oldmm);
+ down_write(&mm->mmap_sem);
+
mm->locked_vm = 0;
mm->mmap = NULL;
mm->mmap_cache = NULL;
mm->free_area_cache = oldmm->mmap_base;
mm->cached_hole_size = ~0UL;
mm->map_count = 0;
- set_mm_counter(mm, rss, 0);
- set_mm_counter(mm, anon_rss, 0);
cpus_clear(mm->cpu_vm_mask);
mm->mm_rb = RB_ROOT;
rb_link = &mm->mm_rb.rb_node;
rb_parent = NULL;
pprev = &mm->mmap;
- for (mpnt = current->mm->mmap ; mpnt ; mpnt = mpnt->vm_next) {
+ for (mpnt = oldmm->mmap; mpnt; mpnt = mpnt->vm_next) {
struct file *file;
if (mpnt->vm_flags & VM_DONTCOPY) {
long pages = vma_pages(mpnt);
mm->total_vm -= pages;
- __vm_stat_account(mm, mpnt->vm_flags, mpnt->vm_file,
+ vm_stat_account(mm, mpnt->vm_flags, mpnt->vm_file,
-pages);
continue;
}
@@ -253,12 +254,8 @@ static inline int dup_mmap(struct mm_struct * mm, struct mm_struct * oldmm)
}
/*
- * Link in the new vma and copy the page table entries:
- * link in first so that swapoff can see swap entries.
- * Note that, exceptionally, here the vma is inserted
- * without holding mm->mmap_sem.
+ * Link in the new vma and copy the page table entries.
*/
- spin_lock(&mm->page_table_lock);
*pprev = tmp;
pprev = &tmp->vm_next;
@@ -267,8 +264,7 @@ static inline int dup_mmap(struct mm_struct * mm, struct mm_struct * oldmm)
rb_parent = &tmp->vm_rb;
mm->map_count++;
- retval = copy_page_range(mm, current->mm, tmp);
- spin_unlock(&mm->page_table_lock);
+ retval = copy_page_range(mm, oldmm, tmp);
if (tmp->vm_ops && tmp->vm_ops->open)
tmp->vm_ops->open(tmp);
@@ -277,9 +273,9 @@ static inline int dup_mmap(struct mm_struct * mm, struct mm_struct * oldmm)
goto out;
}
retval = 0;
-
out:
- flush_tlb_mm(current->mm);
+ up_write(&mm->mmap_sem);
+ flush_tlb_mm(oldmm);
up_write(&oldmm->mmap_sem);
return retval;
fail_nomem_policy:
@@ -323,6 +319,8 @@ static struct mm_struct * mm_init(struct mm_struct * mm)
INIT_LIST_HEAD(&mm->mmlist);
mm->core_waiters = 0;
mm->nr_ptes = 0;
+ set_mm_counter(mm, file_rss, 0);
+ set_mm_counter(mm, anon_rss, 0);
spin_lock_init(&mm->page_table_lock);
rwlock_init(&mm->ioctx_list_lock);
mm->ioctx_list = NULL;
@@ -472,13 +470,6 @@ static int copy_mm(unsigned long clone_flags, struct task_struct * tsk)
if (clone_flags & CLONE_VM) {
atomic_inc(&oldmm->mm_users);
mm = oldmm;
- /*
- * There are cases where the PTL is held to ensure no
- * new threads start up in user mode using an mm, which
- * allows optimizing out ipis; the tlb_gather_mmu code
- * is an example.
- */
- spin_unlock_wait(&oldmm->page_table_lock);
goto good_mm;
}
@@ -499,7 +490,7 @@ static int copy_mm(unsigned long clone_flags, struct task_struct * tsk)
if (retval)
goto free_pt;
- mm->hiwater_rss = get_mm_counter(mm,rss);
+ mm->hiwater_rss = get_mm_rss(mm);
mm->hiwater_vm = mm->total_vm;
good_mm:
@@ -1146,6 +1137,7 @@ static task_t *copy_process(unsigned long clone_flags,
__get_cpu_var(process_counts)++;
}
+ proc_fork_connector(p);
if (!current->signal->tty && p->signal->tty)
p->signal->tty = NULL;
diff --git a/kernel/futex.c b/kernel/futex.c
index ca05fe6a70b2..aca8d10704f6 100644
--- a/kernel/futex.c
+++ b/kernel/futex.c
@@ -205,15 +205,13 @@ static int get_futex_key(unsigned long uaddr, union futex_key *key)
/*
* Do a quick atomic lookup first - this is the fastpath.
*/
- spin_lock(&current->mm->page_table_lock);
- page = follow_page(mm, uaddr, 0);
+ page = follow_page(mm, uaddr, FOLL_TOUCH|FOLL_GET);
if (likely(page != NULL)) {
key->shared.pgoff =
page->index << (PAGE_CACHE_SHIFT - PAGE_SHIFT);
- spin_unlock(&current->mm->page_table_lock);
+ put_page(page);
return 0;
}
- spin_unlock(&current->mm->page_table_lock);
/*
* Do it the general way.
@@ -367,6 +365,11 @@ retry:
if (bh1 != bh2)
spin_unlock(&bh2->lock);
+ if (unlikely(op_ret != -EFAULT)) {
+ ret = op_ret;
+ goto out;
+ }
+
/* futex_atomic_op_inuser needs to both read and write
* *(int __user *)uaddr2, but we can't modify it
* non-atomically. Therefore, if get_user below is not
diff --git a/kernel/irq/handle.c b/kernel/irq/handle.c
index 3ff7b925c387..51df337b37db 100644
--- a/kernel/irq/handle.c
+++ b/kernel/irq/handle.c
@@ -117,14 +117,16 @@ fastcall unsigned int __do_IRQ(unsigned int irq, struct pt_regs *regs)
/*
* No locking required for CPU-local interrupts:
*/
- desc->handler->ack(irq);
+ if (desc->handler->ack)
+ desc->handler->ack(irq);
action_ret = handle_IRQ_event(irq, regs, desc->action);
desc->handler->end(irq);
return 1;
}
spin_lock(&desc->lock);
- desc->handler->ack(irq);
+ if (desc->handler->ack)
+ desc->handler->ack(irq);
/*
* 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/manage.c b/kernel/irq/manage.c
index 1cfdb08ddf20..3bd7226d15fa 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -24,6 +24,7 @@ cpumask_t __cacheline_aligned pending_irq_cpumask[NR_IRQS];
/**
* synchronize_irq - wait for pending IRQ handlers (on other CPUs)
+ * @irq: interrupt number to wait for
*
* This function waits for any pending IRQ handlers for this interrupt
* to complete before returning. If you use this function while
diff --git a/kernel/kallsyms.c b/kernel/kallsyms.c
index 13bcec151b57..39277dd6bf90 100644
--- a/kernel/kallsyms.c
+++ b/kernel/kallsyms.c
@@ -18,6 +18,7 @@
#include <linux/fs.h>
#include <linux/err.h>
#include <linux/proc_fs.h>
+#include <linux/sched.h> /* for cond_resched */
#include <linux/mm.h>
#include <asm/sections.h>
diff --git a/kernel/kexec.c b/kernel/kexec.c
index cdd4dcd8fb63..2c95848fbce8 100644
--- a/kernel/kexec.c
+++ b/kernel/kexec.c
@@ -90,7 +90,7 @@ int kexec_should_crash(struct task_struct *p)
static int kimage_is_destination_range(struct kimage *image,
unsigned long start, unsigned long end);
static struct page *kimage_alloc_page(struct kimage *image,
- unsigned int gfp_mask,
+ gfp_t gfp_mask,
unsigned long dest);
static int do_kimage_alloc(struct kimage **rimage, unsigned long entry,
@@ -326,8 +326,7 @@ static int kimage_is_destination_range(struct kimage *image,
return 0;
}
-static struct page *kimage_alloc_pages(unsigned int gfp_mask,
- unsigned int order)
+static struct page *kimage_alloc_pages(gfp_t gfp_mask, unsigned int order)
{
struct page *pages;
@@ -335,7 +334,7 @@ static struct page *kimage_alloc_pages(unsigned int gfp_mask,
if (pages) {
unsigned int count, i;
pages->mapping = NULL;
- pages->private = order;
+ set_page_private(pages, order);
count = 1 << order;
for (i = 0; i < count; i++)
SetPageReserved(pages + i);
@@ -348,7 +347,7 @@ static void kimage_free_pages(struct page *page)
{
unsigned int order, count, i;
- order = page->private;
+ order = page_private(page);
count = 1 << order;
for (i = 0; i < count; i++)
ClearPageReserved(page + i);
@@ -654,7 +653,7 @@ static kimage_entry_t *kimage_dst_used(struct kimage *image,
}
static struct page *kimage_alloc_page(struct kimage *image,
- unsigned int gfp_mask,
+ gfp_t gfp_mask,
unsigned long destination)
{
/*
diff --git a/kernel/kmod.c b/kernel/kmod.c
index 44166e3bb8af..51a892063aaa 100644
--- a/kernel/kmod.c
+++ b/kernel/kmod.c
@@ -131,14 +131,14 @@ struct subprocess_info {
static int ____call_usermodehelper(void *data)
{
struct subprocess_info *sub_info = data;
- struct key *old_session;
+ struct key *new_session, *old_session;
int retval;
/* Unblock all signals and set the session keyring. */
- key_get(sub_info->ring);
+ new_session = key_get(sub_info->ring);
flush_signals(current);
spin_lock_irq(&current->sighand->siglock);
- old_session = __install_session_keyring(current, sub_info->ring);
+ old_session = __install_session_keyring(current, new_session);
flush_signal_handlers(current, 1);
sigemptyset(&current->blocked);
recalc_sigpending();
diff --git a/kernel/kprobes.c b/kernel/kprobes.c
index f3ea492ab44d..5beda378cc75 100644
--- a/kernel/kprobes.c
+++ b/kernel/kprobes.c
@@ -32,9 +32,9 @@
* <prasanna@in.ibm.com> added function-return probes.
*/
#include <linux/kprobes.h>
-#include <linux/spinlock.h>
#include <linux/hash.h>
#include <linux/init.h>
+#include <linux/slab.h>
#include <linux/module.h>
#include <linux/moduleloader.h>
#include <asm-generic/sections.h>
@@ -48,9 +48,9 @@
static struct hlist_head kprobe_table[KPROBE_TABLE_SIZE];
static struct hlist_head kretprobe_inst_table[KPROBE_TABLE_SIZE];
-unsigned int kprobe_cpu = NR_CPUS;
-static DEFINE_SPINLOCK(kprobe_lock);
-static struct kprobe *curr_kprobe;
+static DEFINE_SPINLOCK(kprobe_lock); /* Protects kprobe_table */
+DEFINE_SPINLOCK(kretprobe_lock); /* Protects kretprobe_inst_table */
+static DEFINE_PER_CPU(struct kprobe *, kprobe_instance) = NULL;
/*
* kprobe->ainsn.insn points to the copy of the instruction to be
@@ -152,50 +152,31 @@ void __kprobes free_insn_slot(kprobe_opcode_t *slot)
}
}
-/* Locks kprobe: irqs must be disabled */
-void __kprobes lock_kprobes(void)
+/* We have preemption disabled.. so it is safe to use __ versions */
+static inline void set_kprobe_instance(struct kprobe *kp)
{
- unsigned long flags = 0;
-
- /* Avoiding local interrupts to happen right after we take the kprobe_lock
- * and before we get a chance to update kprobe_cpu, this to prevent
- * deadlock when we have a kprobe on ISR routine and a kprobe on task
- * routine
- */
- local_irq_save(flags);
-
- spin_lock(&kprobe_lock);
- kprobe_cpu = smp_processor_id();
-
- local_irq_restore(flags);
+ __get_cpu_var(kprobe_instance) = kp;
}
-void __kprobes unlock_kprobes(void)
+static inline void reset_kprobe_instance(void)
{
- unsigned long flags = 0;
-
- /* Avoiding local interrupts to happen right after we update
- * kprobe_cpu and before we get a a chance to release kprobe_lock,
- * this to prevent deadlock when we have a kprobe on ISR routine and
- * a kprobe on task routine
- */
- local_irq_save(flags);
-
- kprobe_cpu = NR_CPUS;
- spin_unlock(&kprobe_lock);
-
- local_irq_restore(flags);
+ __get_cpu_var(kprobe_instance) = NULL;
}
-/* You have to be holding the kprobe_lock */
+/*
+ * This routine is called either:
+ * - under the kprobe_lock spinlock - during kprobe_[un]register()
+ * OR
+ * - with preemption disabled - from arch/xxx/kernel/kprobes.c
+ */
struct kprobe __kprobes *get_kprobe(void *addr)
{
struct hlist_head *head;
struct hlist_node *node;
+ struct kprobe *p;
head = &kprobe_table[hash_ptr(addr, KPROBE_HASH_BITS)];
- hlist_for_each(node, head) {
- struct kprobe *p = hlist_entry(node, struct kprobe, hlist);
+ hlist_for_each_entry_rcu(p, node, head, hlist) {
if (p->addr == addr)
return p;
}
@@ -210,13 +191,13 @@ static int __kprobes aggr_pre_handler(struct kprobe *p, struct pt_regs *regs)
{
struct kprobe *kp;
- list_for_each_entry(kp, &p->list, list) {
+ list_for_each_entry_rcu(kp, &p->list, list) {
if (kp->pre_handler) {
- curr_kprobe = kp;
+ set_kprobe_instance(kp);
if (kp->pre_handler(kp, regs))
return 1;
}
- curr_kprobe = NULL;
+ reset_kprobe_instance();
}
return 0;
}
@@ -226,11 +207,11 @@ static void __kprobes aggr_post_handler(struct kprobe *p, struct pt_regs *regs,
{
struct kprobe *kp;
- list_for_each_entry(kp, &p->list, list) {
+ list_for_each_entry_rcu(kp, &p->list, list) {
if (kp->post_handler) {
- curr_kprobe = kp;
+ set_kprobe_instance(kp);
kp->post_handler(kp, regs, flags);
- curr_kprobe = NULL;
+ reset_kprobe_instance();
}
}
return;
@@ -239,12 +220,14 @@ static void __kprobes aggr_post_handler(struct kprobe *p, struct pt_regs *regs,
static int __kprobes aggr_fault_handler(struct kprobe *p, struct pt_regs *regs,
int trapnr)
{
+ struct kprobe *cur = __get_cpu_var(kprobe_instance);
+
/*
* if we faulted "during" the execution of a user specified
* probe handler, invoke just that probe's fault handler
*/
- if (curr_kprobe && curr_kprobe->fault_handler) {
- if (curr_kprobe->fault_handler(curr_kprobe, regs, trapnr))
+ if (cur && cur->fault_handler) {
+ if (cur->fault_handler(cur, regs, trapnr))
return 1;
}
return 0;
@@ -252,17 +235,18 @@ static int __kprobes aggr_fault_handler(struct kprobe *p, struct pt_regs *regs,
static int __kprobes aggr_break_handler(struct kprobe *p, struct pt_regs *regs)
{
- struct kprobe *kp = curr_kprobe;
- if (curr_kprobe && kp->break_handler) {
- if (kp->break_handler(kp, regs)) {
- curr_kprobe = NULL;
- return 1;
- }
+ struct kprobe *cur = __get_cpu_var(kprobe_instance);
+ int ret = 0;
+
+ if (cur && cur->break_handler) {
+ if (cur->break_handler(cur, regs))
+ ret = 1;
}
- curr_kprobe = NULL;
- return 0;
+ reset_kprobe_instance();
+ return ret;
}
+/* Called with kretprobe_lock held */
struct kretprobe_instance __kprobes *get_free_rp_inst(struct kretprobe *rp)
{
struct hlist_node *node;
@@ -272,6 +256,7 @@ struct kretprobe_instance __kprobes *get_free_rp_inst(struct kretprobe *rp)
return NULL;
}
+/* Called with kretprobe_lock held */
static struct kretprobe_instance __kprobes *get_used_rp_inst(struct kretprobe
*rp)
{
@@ -282,6 +267,7 @@ static struct kretprobe_instance __kprobes *get_used_rp_inst(struct kretprobe
return NULL;
}
+/* Called with kretprobe_lock held */
void __kprobes add_rp_inst(struct kretprobe_instance *ri)
{
/*
@@ -300,6 +286,7 @@ void __kprobes add_rp_inst(struct kretprobe_instance *ri)
hlist_add_head(&ri->uflist, &ri->rp->used_instances);
}
+/* Called with kretprobe_lock held */
void __kprobes recycle_rp_inst(struct kretprobe_instance *ri)
{
/* remove rp inst off the rprobe_inst_table */
@@ -333,13 +320,13 @@ void __kprobes kprobe_flush_task(struct task_struct *tk)
struct hlist_node *node, *tmp;
unsigned long flags = 0;
- spin_lock_irqsave(&kprobe_lock, flags);
+ spin_lock_irqsave(&kretprobe_lock, flags);
head = kretprobe_inst_table_head(current);
hlist_for_each_entry_safe(ri, node, tmp, head, hlist) {
if (ri->task == tk)
recycle_rp_inst(ri);
}
- spin_unlock_irqrestore(&kprobe_lock, flags);
+ spin_unlock_irqrestore(&kretprobe_lock, flags);
}
/*
@@ -350,9 +337,12 @@ static int __kprobes pre_handler_kretprobe(struct kprobe *p,
struct pt_regs *regs)
{
struct kretprobe *rp = container_of(p, struct kretprobe, kp);
+ unsigned long flags = 0;
/*TODO: consider to only swap the RA after the last pre_handler fired */
+ spin_lock_irqsave(&kretprobe_lock, flags);
arch_prepare_kretprobe(rp, regs);
+ spin_unlock_irqrestore(&kretprobe_lock, flags);
return 0;
}
@@ -383,13 +373,13 @@ static int __kprobes add_new_kprobe(struct kprobe *old_p, struct kprobe *p)
struct kprobe *kp;
if (p->break_handler) {
- list_for_each_entry(kp, &old_p->list, list) {
+ list_for_each_entry_rcu(kp, &old_p->list, list) {
if (kp->break_handler)
return -EEXIST;
}
- list_add_tail(&p->list, &old_p->list);
+ list_add_tail_rcu(&p->list, &old_p->list);
} else
- list_add(&p->list, &old_p->list);
+ list_add_rcu(&p->list, &old_p->list);
return 0;
}
@@ -407,18 +397,18 @@ static inline void add_aggr_kprobe(struct kprobe *ap, struct kprobe *p)
ap->break_handler = aggr_break_handler;
INIT_LIST_HEAD(&ap->list);
- list_add(&p->list, &ap->list);
+ list_add_rcu(&p->list, &ap->list);
INIT_HLIST_NODE(&ap->hlist);
- hlist_del(&p->hlist);
- hlist_add_head(&ap->hlist,
+ hlist_del_rcu(&p->hlist);
+ hlist_add_head_rcu(&ap->hlist,
&kprobe_table[hash_ptr(ap->addr, KPROBE_HASH_BITS)]);
}
/*
* This is the second or subsequent kprobe at the address - handle
* the intricacies
- * TODO: Move kcalloc outside the spinlock
+ * TODO: Move kcalloc outside the spin_lock
*/
static int __kprobes register_aggr_kprobe(struct kprobe *old_p,
struct kprobe *p)
@@ -444,7 +434,7 @@ static int __kprobes register_aggr_kprobe(struct kprobe *old_p,
static inline void cleanup_kprobe(struct kprobe *p, unsigned long flags)
{
arch_disarm_kprobe(p);
- hlist_del(&p->hlist);
+ hlist_del_rcu(&p->hlist);
spin_unlock_irqrestore(&kprobe_lock, flags);
arch_remove_kprobe(p);
}
@@ -452,11 +442,10 @@ static inline void cleanup_kprobe(struct kprobe *p, unsigned long flags)
static inline void cleanup_aggr_kprobe(struct kprobe *old_p,
struct kprobe *p, unsigned long flags)
{
- list_del(&p->list);
- if (list_empty(&old_p->list)) {
+ list_del_rcu(&p->list);
+ if (list_empty(&old_p->list))
cleanup_kprobe(old_p, flags);
- kfree(old_p);
- } else
+ else
spin_unlock_irqrestore(&kprobe_lock, flags);
}
@@ -479,9 +468,9 @@ int __kprobes register_kprobe(struct kprobe *p)
if ((ret = arch_prepare_kprobe(p)) != 0)
goto rm_kprobe;
+ p->nmissed = 0;
spin_lock_irqsave(&kprobe_lock, flags);
old_p = get_kprobe(p->addr);
- p->nmissed = 0;
if (old_p) {
ret = register_aggr_kprobe(old_p, p);
goto out;
@@ -489,7 +478,7 @@ int __kprobes register_kprobe(struct kprobe *p)
arch_copy_kprobe(p);
INIT_HLIST_NODE(&p->hlist);
- hlist_add_head(&p->hlist,
+ hlist_add_head_rcu(&p->hlist,
&kprobe_table[hash_ptr(p->addr, KPROBE_HASH_BITS)]);
arch_arm_kprobe(p);
@@ -510,10 +499,16 @@ void __kprobes unregister_kprobe(struct kprobe *p)
spin_lock_irqsave(&kprobe_lock, flags);
old_p = get_kprobe(p->addr);
if (old_p) {
+ /* cleanup_*_kprobe() does the spin_unlock_irqrestore */
if (old_p->pre_handler == aggr_pre_handler)
cleanup_aggr_kprobe(old_p, p, flags);
else
cleanup_kprobe(p, flags);
+
+ synchronize_sched();
+ if (old_p->pre_handler == aggr_pre_handler &&
+ list_empty(&old_p->list))
+ kfree(old_p);
} else
spin_unlock_irqrestore(&kprobe_lock, flags);
}
@@ -590,13 +585,13 @@ void __kprobes unregister_kretprobe(struct kretprobe *rp)
unregister_kprobe(&rp->kp);
/* No race here */
- spin_lock_irqsave(&kprobe_lock, flags);
+ spin_lock_irqsave(&kretprobe_lock, flags);
free_rp_inst(rp);
while ((ri = get_used_rp_inst(rp)) != NULL) {
ri->rp = NULL;
hlist_del(&ri->uflist);
}
- spin_unlock_irqrestore(&kprobe_lock, flags);
+ spin_unlock_irqrestore(&kretprobe_lock, flags);
}
static int __init init_kprobes(void)
diff --git a/kernel/kthread.c b/kernel/kthread.c
index f50f174e92da..e75950a1092c 100644
--- a/kernel/kthread.c
+++ b/kernel/kthread.c
@@ -165,6 +165,12 @@ EXPORT_SYMBOL(kthread_bind);
int kthread_stop(struct task_struct *k)
{
+ return kthread_stop_sem(k, NULL);
+}
+EXPORT_SYMBOL(kthread_stop);
+
+int kthread_stop_sem(struct task_struct *k, struct semaphore *s)
+{
int ret;
down(&kthread_stop_lock);
@@ -178,7 +184,10 @@ int kthread_stop(struct task_struct *k)
/* Now set kthread_should_stop() to true, and wake it up. */
kthread_stop_info.k = k;
- wake_up_process(k);
+ if (s)
+ up(s);
+ else
+ wake_up_process(k);
put_task_struct(k);
/* Once it dies, reset stop ptr, gather result and we're done. */
@@ -189,7 +198,7 @@ int kthread_stop(struct task_struct *k)
return ret;
}
-EXPORT_SYMBOL(kthread_stop);
+EXPORT_SYMBOL(kthread_stop_sem);
static __init int helper_init(void)
{
diff --git a/kernel/module.c b/kernel/module.c
index ff5c500ab625..2ea929d51ad0 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -37,6 +37,7 @@
#include <linux/stop_machine.h>
#include <linux/device.h>
#include <linux/string.h>
+#include <linux/sched.h>
#include <asm/uaccess.h>
#include <asm/semaphore.h>
#include <asm/cacheflush.h>
diff --git a/kernel/params.c b/kernel/params.c
index 1a8614bac5d5..47ba69547945 100644
--- a/kernel/params.c
+++ b/kernel/params.c
@@ -23,6 +23,7 @@
#include <linux/module.h>
#include <linux/device.h>
#include <linux/err.h>
+#include <linux/slab.h>
#if 0
#define DEBUGP printk
diff --git a/kernel/posix-cpu-timers.c b/kernel/posix-cpu-timers.c
index bf374fceb39c..84af54c39e1b 100644
--- a/kernel/posix-cpu-timers.c
+++ b/kernel/posix-cpu-timers.c
@@ -497,7 +497,7 @@ static void process_timer_rebalance(struct task_struct *p,
left = cputime_div(cputime_sub(expires.cpu, val.cpu),
nthreads);
do {
- if (!unlikely(t->flags & PF_EXITING)) {
+ if (likely(!(t->flags & PF_EXITING))) {
ticks = cputime_add(prof_ticks(t), left);
if (cputime_eq(t->it_prof_expires,
cputime_zero) ||
@@ -512,7 +512,7 @@ static void process_timer_rebalance(struct task_struct *p,
left = cputime_div(cputime_sub(expires.cpu, val.cpu),
nthreads);
do {
- if (!unlikely(t->flags & PF_EXITING)) {
+ if (likely(!(t->flags & PF_EXITING))) {
ticks = cputime_add(virt_ticks(t), left);
if (cputime_eq(t->it_virt_expires,
cputime_zero) ||
@@ -527,7 +527,7 @@ static void process_timer_rebalance(struct task_struct *p,
nsleft = expires.sched - val.sched;
do_div(nsleft, nthreads);
do {
- if (!unlikely(t->flags & PF_EXITING)) {
+ if (likely(!(t->flags & PF_EXITING))) {
ns = t->sched_time + nsleft;
if (t->it_sched_expires == 0 ||
t->it_sched_expires > ns) {
@@ -1225,7 +1225,7 @@ void posix_cpu_timer_schedule(struct k_itimer *timer)
/*
* The task was cleaned up already, no future firings.
*/
- return;
+ goto out;
/*
* Fetch the current sample and update the timer's expiry time.
@@ -1235,7 +1235,7 @@ void posix_cpu_timer_schedule(struct k_itimer *timer)
bump_cpu_timer(timer, now);
if (unlikely(p->exit_state)) {
clear_dead_task(timer, now);
- return;
+ goto out;
}
read_lock(&tasklist_lock); /* arm_timer needs it. */
} else {
@@ -1248,8 +1248,7 @@ void posix_cpu_timer_schedule(struct k_itimer *timer)
put_task_struct(p);
timer->it.cpu.task = p = NULL;
timer->it.cpu.expires.sched = 0;
- read_unlock(&tasklist_lock);
- return;
+ goto out_unlock;
} else if (unlikely(p->exit_state) && thread_group_empty(p)) {
/*
* We've noticed that the thread is dead, but
@@ -1257,8 +1256,7 @@ void posix_cpu_timer_schedule(struct k_itimer *timer)
* drop our task ref.
*/
clear_dead_task(timer, now);
- read_unlock(&tasklist_lock);
- return;
+ goto out_unlock;
}
cpu_clock_sample_group(timer->it_clock, p, &now);
bump_cpu_timer(timer, now);
@@ -1270,7 +1268,13 @@ void posix_cpu_timer_schedule(struct k_itimer *timer)
*/
arm_timer(timer, now);
+out_unlock:
read_unlock(&tasklist_lock);
+
+out:
+ timer->it_overrun_last = timer->it_overrun;
+ timer->it_overrun = -1;
+ ++timer->it_requeue_pending;
}
/*
diff --git a/kernel/posix-timers.c b/kernel/posix-timers.c
index dda3cda73c77..ea55c7a1cd75 100644
--- a/kernel/posix-timers.c
+++ b/kernel/posix-timers.c
@@ -1295,13 +1295,6 @@ sys_clock_getres(clockid_t which_clock, struct timespec __user *tp)
return error;
}
-static void nanosleep_wake_up(unsigned long __data)
-{
- struct task_struct *p = (struct task_struct *) __data;
-
- wake_up_process(p);
-}
-
/*
* The standard says that an absolute nanosleep call MUST wake up at
* the requested time in spite of clock settings. Here is what we do:
@@ -1442,7 +1435,6 @@ static int common_nsleep(clockid_t which_clock,
int flags, struct timespec *tsave)
{
struct timespec t, dum;
- struct timer_list new_timer;
DECLARE_WAITQUEUE(abs_wqueue, current);
u64 rq_time = (u64)0;
s64 left;
@@ -1451,10 +1443,6 @@ static int common_nsleep(clockid_t which_clock,
&current_thread_info()->restart_block;
abs_wqueue.flags = 0;
- init_timer(&new_timer);
- new_timer.expires = 0;
- new_timer.data = (unsigned long) current;
- new_timer.function = nanosleep_wake_up;
abs = flags & TIMER_ABSTIME;
if (restart_block->fn == clock_nanosleep_restart) {
@@ -1490,13 +1478,8 @@ static int common_nsleep(clockid_t which_clock,
if (left < (s64)0)
break;
- new_timer.expires = jiffies + left;
- __set_current_state(TASK_INTERRUPTIBLE);
- add_timer(&new_timer);
-
- schedule();
+ schedule_timeout_interruptible(left);
- del_timer_sync(&new_timer);
left = rq_time - get_jiffies_64();
} while (left > (s64)0 && !test_thread_flag(TIF_SIGPENDING));
diff --git a/kernel/power/Makefile b/kernel/power/Makefile
index 2f438d0eaa13..c71eb4579c07 100644
--- a/kernel/power/Makefile
+++ b/kernel/power/Makefile
@@ -4,7 +4,7 @@ EXTRA_CFLAGS += -DDEBUG
endif
obj-y := main.o process.o console.o pm.o
-obj-$(CONFIG_SOFTWARE_SUSPEND) += swsusp.o disk.o
+obj-$(CONFIG_SOFTWARE_SUSPEND) += swsusp.o disk.o snapshot.o
obj-$(CONFIG_SUSPEND_SMP) += smp.o
diff --git a/kernel/power/disk.c b/kernel/power/disk.c
index 761956e813f5..027322a564f4 100644
--- a/kernel/power/disk.c
+++ b/kernel/power/disk.c
@@ -30,7 +30,6 @@ extern int swsusp_check(void);
extern int swsusp_read(void);
extern void swsusp_close(void);
extern int swsusp_resume(void);
-extern int swsusp_free(void);
static int noresume = 0;
@@ -93,10 +92,7 @@ static void free_some_memory(void)
printk("Freeing memory... ");
while ((tmp = shrink_all_memory(10000))) {
pages += tmp;
- printk("\b%c", p[i]);
- i++;
- if (i > 3)
- i = 0;
+ printk("\b%c", p[i++ % 4]);
}
printk("\bdone (%li pages freed)\n", pages);
}
@@ -178,13 +174,12 @@ int pm_suspend_disk(void)
goto Done;
if (in_suspend) {
+ device_resume();
pr_debug("PM: writing image.\n");
error = swsusp_write();
if (!error)
power_down(pm_disk_mode);
else {
- /* swsusp_write can not fail in device_resume,
- no need to do second device_resume */
swsusp_free();
unprepare_processes();
return error;
@@ -252,14 +247,17 @@ static int software_resume(void)
pr_debug("PM: Reading swsusp image.\n");
- if ((error = swsusp_read()))
- goto Cleanup;
+ if ((error = swsusp_read())) {
+ swsusp_free();
+ goto Thaw;
+ }
pr_debug("PM: Preparing devices for restore.\n");
if ((error = device_suspend(PMSG_FREEZE))) {
printk("Some devices failed to suspend\n");
- goto Free;
+ swsusp_free();
+ goto Thaw;
}
mb();
@@ -268,9 +266,7 @@ static int software_resume(void)
swsusp_resume();
pr_debug("PM: Restore failed, recovering.n");
device_resume();
- Free:
- swsusp_free();
- Cleanup:
+ Thaw:
unprepare_processes();
Done:
/* For success case, the suspend path will release the lock */
diff --git a/kernel/power/main.c b/kernel/power/main.c
index 22bdc93cc038..6ee2cad530e8 100644
--- a/kernel/power/main.c
+++ b/kernel/power/main.c
@@ -167,6 +167,8 @@ static int enter_state(suspend_state_t state)
{
int error;
+ if (pm_ops && pm_ops->valid && !pm_ops->valid(state))
+ return -ENODEV;
if (down_trylock(&pm_sem))
return -EBUSY;
@@ -236,7 +238,8 @@ static ssize_t state_show(struct subsystem * subsys, char * buf)
char * s = buf;
for (i = 0; i < PM_SUSPEND_MAX; i++) {
- if (pm_states[i])
+ if (pm_states[i] && pm_ops && (!pm_ops->valid
+ ||(pm_ops->valid && pm_ops->valid(i))))
s += sprintf(s,"%s ",pm_states[i]);
}
s += sprintf(s,"\n");
diff --git a/kernel/power/power.h b/kernel/power/power.h
index 6748de23e83c..6c042b5ee14b 100644
--- a/kernel/power/power.h
+++ b/kernel/power/power.h
@@ -53,3 +53,20 @@ extern void thaw_processes(void);
extern int pm_prepare_console(void);
extern void pm_restore_console(void);
+
+
+/* References to section boundaries */
+extern const void __nosave_begin, __nosave_end;
+
+extern unsigned int nr_copy_pages;
+extern suspend_pagedir_t *pagedir_nosave;
+extern suspend_pagedir_t *pagedir_save;
+
+extern asmlinkage int swsusp_arch_suspend(void);
+extern asmlinkage int swsusp_arch_resume(void);
+
+extern void free_pagedir(struct pbe *pblist);
+extern struct pbe *alloc_pagedir(unsigned nr_pages, gfp_t gfp_mask, int safe_needed);
+extern void create_pbe_list(struct pbe *pblist, unsigned nr_pages);
+extern void swsusp_free(void);
+extern int alloc_data_pages(struct pbe *pblist, gfp_t gfp_mask, int safe_needed);
diff --git a/kernel/power/snapshot.c b/kernel/power/snapshot.c
new file mode 100644
index 000000000000..4a6dbcefd378
--- /dev/null
+++ b/kernel/power/snapshot.c
@@ -0,0 +1,453 @@
+/*
+ * linux/kernel/power/snapshot.c
+ *
+ * This file provide system snapshot/restore functionality.
+ *
+ * Copyright (C) 1998-2005 Pavel Machek <pavel@suse.cz>
+ *
+ * This file is released under the GPLv2, and is based on swsusp.c.
+ *
+ */
+
+
+#include <linux/module.h>
+#include <linux/mm.h>
+#include <linux/suspend.h>
+#include <linux/smp_lock.h>
+#include <linux/delay.h>
+#include <linux/bitops.h>
+#include <linux/spinlock.h>
+#include <linux/kernel.h>
+#include <linux/pm.h>
+#include <linux/device.h>
+#include <linux/bootmem.h>
+#include <linux/syscalls.h>
+#include <linux/console.h>
+#include <linux/highmem.h>
+
+#include <asm/uaccess.h>
+#include <asm/mmu_context.h>
+#include <asm/pgtable.h>
+#include <asm/tlbflush.h>
+#include <asm/io.h>
+
+#include "power.h"
+
+#ifdef CONFIG_HIGHMEM
+struct highmem_page {
+ char *data;
+ struct page *page;
+ struct highmem_page *next;
+};
+
+static struct highmem_page *highmem_copy;
+
+static int save_highmem_zone(struct zone *zone)
+{
+ unsigned long zone_pfn;
+ mark_free_pages(zone);
+ for (zone_pfn = 0; zone_pfn < zone->spanned_pages; ++zone_pfn) {
+ struct page *page;
+ struct highmem_page *save;
+ void *kaddr;
+ unsigned long pfn = zone_pfn + zone->zone_start_pfn;
+
+ if (!(pfn%1000))
+ printk(".");
+ if (!pfn_valid(pfn))
+ continue;
+ page = pfn_to_page(pfn);
+ /*
+ * This condition results from rvmalloc() sans vmalloc_32()
+ * and architectural memory reservations. This should be
+ * corrected eventually when the cases giving rise to this
+ * are better understood.
+ */
+ if (PageReserved(page)) {
+ printk("highmem reserved page?!\n");
+ continue;
+ }
+ BUG_ON(PageNosave(page));
+ if (PageNosaveFree(page))
+ continue;
+ save = kmalloc(sizeof(struct highmem_page), GFP_ATOMIC);
+ if (!save)
+ return -ENOMEM;
+ save->next = highmem_copy;
+ save->page = page;
+ save->data = (void *) get_zeroed_page(GFP_ATOMIC);
+ if (!save->data) {
+ kfree(save);
+ return -ENOMEM;
+ }
+ kaddr = kmap_atomic(page, KM_USER0);
+ memcpy(save->data, kaddr, PAGE_SIZE);
+ kunmap_atomic(kaddr, KM_USER0);
+ highmem_copy = save;
+ }
+ return 0;
+}
+
+int save_highmem(void)
+{
+ struct zone *zone;
+ int res = 0;
+
+ pr_debug("swsusp: Saving Highmem\n");
+ for_each_zone (zone) {
+ if (is_highmem(zone))
+ res = save_highmem_zone(zone);
+ if (res)
+ return res;
+ }
+ return 0;
+}
+
+int restore_highmem(void)
+{
+ printk("swsusp: Restoring Highmem\n");
+ while (highmem_copy) {
+ struct highmem_page *save = highmem_copy;
+ void *kaddr;
+ highmem_copy = save->next;
+
+ kaddr = kmap_atomic(save->page, KM_USER0);
+ memcpy(kaddr, save->data, PAGE_SIZE);
+ kunmap_atomic(kaddr, KM_USER0);
+ free_page((long) save->data);
+ kfree(save);
+ }
+ return 0;
+}
+#endif
+
+static int pfn_is_nosave(unsigned long pfn)
+{
+ unsigned long nosave_begin_pfn = __pa(&__nosave_begin) >> PAGE_SHIFT;
+ unsigned long nosave_end_pfn = PAGE_ALIGN(__pa(&__nosave_end)) >> PAGE_SHIFT;
+ return (pfn >= nosave_begin_pfn) && (pfn < nosave_end_pfn);
+}
+
+/**
+ * saveable - Determine whether a page should be cloned or not.
+ * @pfn: The page
+ *
+ * We save a page if it's Reserved, and not in the range of pages
+ * statically defined as 'unsaveable', or if it isn't reserved, and
+ * isn't part of a free chunk of pages.
+ */
+
+static int saveable(struct zone *zone, unsigned long *zone_pfn)
+{
+ unsigned long pfn = *zone_pfn + zone->zone_start_pfn;
+ struct page *page;
+
+ if (!pfn_valid(pfn))
+ return 0;
+
+ page = pfn_to_page(pfn);
+ BUG_ON(PageReserved(page) && PageNosave(page));
+ if (PageNosave(page))
+ return 0;
+ if (PageReserved(page) && pfn_is_nosave(pfn)) {
+ pr_debug("[nosave pfn 0x%lx]", pfn);
+ return 0;
+ }
+ if (PageNosaveFree(page))
+ return 0;
+
+ return 1;
+}
+
+static unsigned count_data_pages(void)
+{
+ struct zone *zone;
+ unsigned long zone_pfn;
+ unsigned int n = 0;
+
+ for_each_zone (zone) {
+ if (is_highmem(zone))
+ continue;
+ mark_free_pages(zone);
+ for (zone_pfn = 0; zone_pfn < zone->spanned_pages; ++zone_pfn)
+ n += saveable(zone, &zone_pfn);
+ }
+ return n;
+}
+
+static void copy_data_pages(struct pbe *pblist)
+{
+ struct zone *zone;
+ unsigned long zone_pfn;
+ struct pbe *pbe, *p;
+
+ pbe = pblist;
+ for_each_zone (zone) {
+ if (is_highmem(zone))
+ continue;
+ mark_free_pages(zone);
+ /* This is necessary for swsusp_free() */
+ for_each_pb_page (p, pblist)
+ SetPageNosaveFree(virt_to_page(p));
+ for_each_pbe (p, pblist)
+ SetPageNosaveFree(virt_to_page(p->address));
+ for (zone_pfn = 0; zone_pfn < zone->spanned_pages; ++zone_pfn) {
+ if (saveable(zone, &zone_pfn)) {
+ struct page *page;
+ page = pfn_to_page(zone_pfn + zone->zone_start_pfn);
+ BUG_ON(!pbe);
+ pbe->orig_address = (unsigned long)page_address(page);
+ /* copy_page is not usable for copying task structs. */
+ memcpy((void *)pbe->address, (void *)pbe->orig_address, PAGE_SIZE);
+ pbe = pbe->next;
+ }
+ }
+ }
+ BUG_ON(pbe);
+}
+
+
+/**
+ * free_pagedir - free pages allocated with alloc_pagedir()
+ */
+
+void free_pagedir(struct pbe *pblist)
+{
+ struct pbe *pbe;
+
+ while (pblist) {
+ pbe = (pblist + PB_PAGE_SKIP)->next;
+ ClearPageNosave(virt_to_page(pblist));
+ ClearPageNosaveFree(virt_to_page(pblist));
+ free_page((unsigned long)pblist);
+ pblist = pbe;
+ }
+}
+
+/**
+ * fill_pb_page - Create a list of PBEs on a given memory page
+ */
+
+static inline void fill_pb_page(struct pbe *pbpage)
+{
+ struct pbe *p;
+
+ p = pbpage;
+ pbpage += PB_PAGE_SKIP;
+ do
+ p->next = p + 1;
+ while (++p < pbpage);
+}
+
+/**
+ * create_pbe_list - Create a list of PBEs on top of a given chain
+ * of memory pages allocated with alloc_pagedir()
+ */
+
+void create_pbe_list(struct pbe *pblist, unsigned int nr_pages)
+{
+ struct pbe *pbpage, *p;
+ unsigned int num = PBES_PER_PAGE;
+
+ for_each_pb_page (pbpage, pblist) {
+ if (num >= nr_pages)
+ break;
+
+ fill_pb_page(pbpage);
+ num += PBES_PER_PAGE;
+ }
+ if (pbpage) {
+ for (num -= PBES_PER_PAGE - 1, p = pbpage; num < nr_pages; p++, num++)
+ p->next = p + 1;
+ p->next = NULL;
+ }
+ pr_debug("create_pbe_list(): initialized %d PBEs\n", num);
+}
+
+/**
+ * @safe_needed - on resume, for storing the PBE list and the image,
+ * we can only use memory pages that do not conflict with the pages
+ * which had been used before suspend.
+ *
+ * The unsafe pages are marked with the PG_nosave_free flag
+ *
+ * Allocated but unusable (ie eaten) memory pages should be marked
+ * so that swsusp_free() can release them
+ */
+
+static inline void *alloc_image_page(gfp_t gfp_mask, int safe_needed)
+{
+ void *res;
+
+ if (safe_needed)
+ do {
+ res = (void *)get_zeroed_page(gfp_mask);
+ if (res && PageNosaveFree(virt_to_page(res)))
+ /* This is for swsusp_free() */
+ SetPageNosave(virt_to_page(res));
+ } while (res && PageNosaveFree(virt_to_page(res)));
+ else
+ res = (void *)get_zeroed_page(gfp_mask);
+ if (res) {
+ SetPageNosave(virt_to_page(res));
+ SetPageNosaveFree(virt_to_page(res));
+ }
+ return res;
+}
+
+unsigned long get_safe_page(gfp_t gfp_mask)
+{
+ return (unsigned long)alloc_image_page(gfp_mask, 1);
+}
+
+/**
+ * alloc_pagedir - Allocate the page directory.
+ *
+ * First, determine exactly how many pages we need and
+ * allocate them.
+ *
+ * We arrange the pages in a chain: each page is an array of PBES_PER_PAGE
+ * struct pbe elements (pbes) and the last element in the page points
+ * to the next page.
+ *
+ * On each page we set up a list of struct_pbe elements.
+ */
+
+struct pbe *alloc_pagedir(unsigned int nr_pages, gfp_t gfp_mask, int safe_needed)
+{
+ unsigned int num;
+ struct pbe *pblist, *pbe;
+
+ if (!nr_pages)
+ return NULL;
+
+ pr_debug("alloc_pagedir(): nr_pages = %d\n", nr_pages);
+ pblist = alloc_image_page(gfp_mask, safe_needed);
+ /* FIXME: rewrite this ugly loop */
+ for (pbe = pblist, num = PBES_PER_PAGE; pbe && num < nr_pages;
+ pbe = pbe->next, num += PBES_PER_PAGE) {
+ pbe += PB_PAGE_SKIP;
+ pbe->next = alloc_image_page(gfp_mask, safe_needed);
+ }
+ if (!pbe) { /* get_zeroed_page() failed */
+ free_pagedir(pblist);
+ pblist = NULL;
+ }
+ return pblist;
+}
+
+/**
+ * Free pages we allocated for suspend. Suspend pages are alocated
+ * before atomic copy, so we need to free them after resume.
+ */
+
+void swsusp_free(void)
+{
+ struct zone *zone;
+ unsigned long zone_pfn;
+
+ for_each_zone(zone) {
+ for (zone_pfn = 0; zone_pfn < zone->spanned_pages; ++zone_pfn)
+ if (pfn_valid(zone_pfn + zone->zone_start_pfn)) {
+ struct page *page;
+ page = pfn_to_page(zone_pfn + zone->zone_start_pfn);
+ if (PageNosave(page) && PageNosaveFree(page)) {
+ ClearPageNosave(page);
+ ClearPageNosaveFree(page);
+ free_page((long) page_address(page));
+ }
+ }
+ }
+}
+
+
+/**
+ * enough_free_mem - Make sure we enough free memory to snapshot.
+ *
+ * Returns TRUE or FALSE after checking the number of available
+ * free pages.
+ */
+
+static int enough_free_mem(unsigned int nr_pages)
+{
+ pr_debug("swsusp: available memory: %u pages\n", nr_free_pages());
+ return nr_free_pages() > (nr_pages + PAGES_FOR_IO +
+ (nr_pages + PBES_PER_PAGE - 1) / PBES_PER_PAGE);
+}
+
+int alloc_data_pages(struct pbe *pblist, gfp_t gfp_mask, int safe_needed)
+{
+ struct pbe *p;
+
+ for_each_pbe (p, pblist) {
+ p->address = (unsigned long)alloc_image_page(gfp_mask, safe_needed);
+ if (!p->address)
+ return -ENOMEM;
+ }
+ return 0;
+}
+
+static struct pbe *swsusp_alloc(unsigned int nr_pages)
+{
+ struct pbe *pblist;
+
+ if (!(pblist = alloc_pagedir(nr_pages, GFP_ATOMIC | __GFP_COLD, 0))) {
+ printk(KERN_ERR "suspend: Allocating pagedir failed.\n");
+ return NULL;
+ }
+ create_pbe_list(pblist, nr_pages);
+
+ if (alloc_data_pages(pblist, GFP_ATOMIC | __GFP_COLD, 0)) {
+ printk(KERN_ERR "suspend: Allocating image pages failed.\n");
+ swsusp_free();
+ return NULL;
+ }
+
+ return pblist;
+}
+
+asmlinkage int swsusp_save(void)
+{
+ unsigned int nr_pages;
+
+ pr_debug("swsusp: critical section: \n");
+
+ drain_local_pages();
+ nr_pages = count_data_pages();
+ printk("swsusp: Need to copy %u pages\n", nr_pages);
+
+ pr_debug("swsusp: pages needed: %u + %lu + %u, free: %u\n",
+ nr_pages,
+ (nr_pages + PBES_PER_PAGE - 1) / PBES_PER_PAGE,
+ PAGES_FOR_IO, nr_free_pages());
+
+ /* This is needed because of the fixed size of swsusp_info */
+ if (MAX_PBES < (nr_pages + PBES_PER_PAGE - 1) / PBES_PER_PAGE)
+ return -ENOSPC;
+
+ if (!enough_free_mem(nr_pages)) {
+ printk(KERN_ERR "swsusp: Not enough free memory\n");
+ return -ENOMEM;
+ }
+
+ pagedir_nosave = swsusp_alloc(nr_pages);
+ if (!pagedir_nosave)
+ return -ENOMEM;
+
+ /* During allocating of suspend pagedir, new cold pages may appear.
+ * Kill them.
+ */
+ drain_local_pages();
+ copy_data_pages(pagedir_nosave);
+
+ /*
+ * End of critical section. From now on, we can write to memory,
+ * but we should not touch disk. This specially means we must _not_
+ * touch swap space! Except we must write out our image of course.
+ */
+
+ nr_copy_pages = nr_pages;
+
+ printk("swsusp: critical section/: done (%d pages copied)\n", nr_pages);
+ return 0;
+}
diff --git a/kernel/power/swsusp.c b/kernel/power/swsusp.c
index 2d5c45676442..c05f46e7348f 100644
--- a/kernel/power/swsusp.c
+++ b/kernel/power/swsusp.c
@@ -1,11 +1,10 @@
/*
* linux/kernel/power/swsusp.c
*
- * This file is to realize architecture-independent
- * machine suspend feature using pretty near only high-level routines
+ * This file provides code to write suspend image to swap and read it back.
*
* Copyright (C) 1998-2001 Gabor Kuti <seasons@fornax.hu>
- * Copyright (C) 1998,2001-2004 Pavel Machek <pavel@suse.cz>
+ * Copyright (C) 1998,2001-2005 Pavel Machek <pavel@suse.cz>
*
* This file is released under the GPLv2.
*
@@ -47,11 +46,7 @@
#include <linux/utsname.h>
#include <linux/version.h>
#include <linux/delay.h>
-#include <linux/reboot.h>
#include <linux/bitops.h>
-#include <linux/vt_kern.h>
-#include <linux/kbd_kern.h>
-#include <linux/keyboard.h>
#include <linux/spinlock.h>
#include <linux/genhd.h>
#include <linux/kernel.h>
@@ -63,10 +58,8 @@
#include <linux/swapops.h>
#include <linux/bootmem.h>
#include <linux/syscalls.h>
-#include <linux/console.h>
#include <linux/highmem.h>
#include <linux/bio.h>
-#include <linux/mount.h>
#include <asm/uaccess.h>
#include <asm/mmu_context.h>
@@ -80,36 +73,31 @@
#include "power.h"
+#ifdef CONFIG_HIGHMEM
+int save_highmem(void);
+int restore_highmem(void);
+#else
+static int save_highmem(void) { return 0; }
+static int restore_highmem(void) { return 0; }
+#endif
+
#define CIPHER "aes"
#define MAXKEY 32
#define MAXIV 32
-/* References to section boundaries */
-extern const void __nosave_begin, __nosave_end;
-
-/* Variables to be preserved over suspend */
-static int nr_copy_pages_check;
-
extern char resume_file[];
/* Local variables that should not be affected by save */
-static unsigned int nr_copy_pages __nosavedata = 0;
+unsigned int nr_copy_pages __nosavedata = 0;
/* Suspend pagedir is allocated before final copy, therefore it
must be freed after resume
- Warning: this is evil. There are actually two pagedirs at time of
- resume. One is "pagedir_save", which is empty frame allocated at
- time of suspend, that must be freed. Second is "pagedir_nosave",
- allocated at time of resume, that travels through memory not to
- collide with anything.
-
Warning: this is even more evil than it seems. Pagedirs this file
talks about are completely different from page directories used by
MMU hardware.
*/
suspend_pagedir_t *pagedir_nosave __nosavedata = NULL;
-static suspend_pagedir_t *pagedir_save;
#define SWSUSP_SIG "S1SUSPEND"
@@ -124,12 +112,6 @@ static struct swsusp_header {
static struct swsusp_info swsusp_info;
/*
- * XXX: We try to keep some more pages free so that I/O operations succeed
- * without paging. Might this be more?
- */
-#define PAGES_FOR_IO 512
-
-/*
* Saving part...
*/
@@ -141,8 +123,8 @@ static struct swsusp_info swsusp_info;
static unsigned short swapfile_used[MAX_SWAPFILES];
static unsigned short root_swap;
-static int write_page(unsigned long addr, swp_entry_t * loc);
-static int bio_read_page(pgoff_t page_off, void * page);
+static int write_page(unsigned long addr, swp_entry_t *loc);
+static int bio_read_page(pgoff_t page_off, void *page);
static u8 key_iv[MAXKEY+MAXIV];
@@ -374,7 +356,7 @@ static void lock_swapdevices(void)
* This is a partial improvement, since we will at least return other
* errors, though we need to eventually fix the damn code.
*/
-static int write_page(unsigned long addr, swp_entry_t * loc)
+static int write_page(unsigned long addr, swp_entry_t *loc)
{
swp_entry_t entry;
int error = 0;
@@ -402,9 +384,9 @@ static int write_page(unsigned long addr, swp_entry_t * loc)
static void data_free(void)
{
swp_entry_t entry;
- struct pbe * p;
+ struct pbe *p;
- for_each_pbe(p, pagedir_nosave) {
+ for_each_pbe (p, pagedir_nosave) {
entry = p->swap_address;
if (entry.val)
swap_free(entry);
@@ -511,8 +493,8 @@ static void free_pagedir_entries(void)
static int write_pagedir(void)
{
int error = 0;
- unsigned n = 0;
- struct pbe * pbe;
+ unsigned int n = 0;
+ struct pbe *pbe;
printk( "Writing pagedir...");
for_each_pb_page (pbe, pagedir_nosave) {
@@ -526,6 +508,26 @@ static int write_pagedir(void)
}
/**
+ * enough_swap - Make sure we have enough swap to save the image.
+ *
+ * Returns TRUE or FALSE after checking the total amount of swap
+ * space avaiable.
+ *
+ * FIXME: si_swapinfo(&i) returns all swap devices information.
+ * We should only consider resume_device.
+ */
+
+static int enough_swap(unsigned int nr_pages)
+{
+ struct sysinfo i;
+
+ si_swapinfo(&i);
+ pr_debug("swsusp: available swap: %lu pages\n", i.freeswap);
+ return i.freeswap > (nr_pages + PAGES_FOR_IO +
+ (nr_pages + PBES_PER_PAGE - 1) / PBES_PER_PAGE);
+}
+
+/**
* write_suspend_image - Write entire image and metadata.
*
*/
@@ -533,6 +535,11 @@ static int write_suspend_image(void)
{
int error;
+ if (!enough_swap(nr_copy_pages)) {
+ printk(KERN_ERR "swsusp: Not enough free swap\n");
+ return -ENOSPC;
+ }
+
init_header();
if ((error = data_write()))
goto FreeData;
@@ -552,440 +559,6 @@ static int write_suspend_image(void)
goto Done;
}
-
-#ifdef CONFIG_HIGHMEM
-struct highmem_page {
- char *data;
- struct page *page;
- struct highmem_page *next;
-};
-
-static struct highmem_page *highmem_copy;
-
-static int save_highmem_zone(struct zone *zone)
-{
- unsigned long zone_pfn;
- mark_free_pages(zone);
- for (zone_pfn = 0; zone_pfn < zone->spanned_pages; ++zone_pfn) {
- struct page *page;
- struct highmem_page *save;
- void *kaddr;
- unsigned long pfn = zone_pfn + zone->zone_start_pfn;
-
- if (!(pfn%1000))
- printk(".");
- if (!pfn_valid(pfn))
- continue;
- page = pfn_to_page(pfn);
- /*
- * This condition results from rvmalloc() sans vmalloc_32()
- * and architectural memory reservations. This should be
- * corrected eventually when the cases giving rise to this
- * are better understood.
- */
- if (PageReserved(page)) {
- printk("highmem reserved page?!\n");
- continue;
- }
- BUG_ON(PageNosave(page));
- if (PageNosaveFree(page))
- continue;
- save = kmalloc(sizeof(struct highmem_page), GFP_ATOMIC);
- if (!save)
- return -ENOMEM;
- save->next = highmem_copy;
- save->page = page;
- save->data = (void *) get_zeroed_page(GFP_ATOMIC);
- if (!save->data) {
- kfree(save);
- return -ENOMEM;
- }
- kaddr = kmap_atomic(page, KM_USER0);
- memcpy(save->data, kaddr, PAGE_SIZE);
- kunmap_atomic(kaddr, KM_USER0);
- highmem_copy = save;
- }
- return 0;
-}
-#endif /* CONFIG_HIGHMEM */
-
-
-static int save_highmem(void)
-{
-#ifdef CONFIG_HIGHMEM
- struct zone *zone;
- int res = 0;
-
- pr_debug("swsusp: Saving Highmem\n");
- for_each_zone (zone) {
- if (is_highmem(zone))
- res = save_highmem_zone(zone);
- if (res)
- return res;
- }
-#endif
- return 0;
-}
-
-static int restore_highmem(void)
-{
-#ifdef CONFIG_HIGHMEM
- printk("swsusp: Restoring Highmem\n");
- while (highmem_copy) {
- struct highmem_page *save = highmem_copy;
- void *kaddr;
- highmem_copy = save->next;
-
- kaddr = kmap_atomic(save->page, KM_USER0);
- memcpy(kaddr, save->data, PAGE_SIZE);
- kunmap_atomic(kaddr, KM_USER0);
- free_page((long) save->data);
- kfree(save);
- }
-#endif
- return 0;
-}
-
-
-static int pfn_is_nosave(unsigned long pfn)
-{
- unsigned long nosave_begin_pfn = __pa(&__nosave_begin) >> PAGE_SHIFT;
- unsigned long nosave_end_pfn = PAGE_ALIGN(__pa(&__nosave_end)) >> PAGE_SHIFT;
- return (pfn >= nosave_begin_pfn) && (pfn < nosave_end_pfn);
-}
-
-/**
- * saveable - Determine whether a page should be cloned or not.
- * @pfn: The page
- *
- * We save a page if it's Reserved, and not in the range of pages
- * statically defined as 'unsaveable', or if it isn't reserved, and
- * isn't part of a free chunk of pages.
- */
-
-static int saveable(struct zone * zone, unsigned long * zone_pfn)
-{
- unsigned long pfn = *zone_pfn + zone->zone_start_pfn;
- struct page * page;
-
- if (!pfn_valid(pfn))
- return 0;
-
- page = pfn_to_page(pfn);
- BUG_ON(PageReserved(page) && PageNosave(page));
- if (PageNosave(page))
- return 0;
- if (PageReserved(page) && pfn_is_nosave(pfn)) {
- pr_debug("[nosave pfn 0x%lx]", pfn);
- return 0;
- }
- if (PageNosaveFree(page))
- return 0;
-
- return 1;
-}
-
-static void count_data_pages(void)
-{
- struct zone *zone;
- unsigned long zone_pfn;
-
- nr_copy_pages = 0;
-
- for_each_zone (zone) {
- if (is_highmem(zone))
- continue;
- mark_free_pages(zone);
- for (zone_pfn = 0; zone_pfn < zone->spanned_pages; ++zone_pfn)
- nr_copy_pages += saveable(zone, &zone_pfn);
- }
-}
-
-
-static void copy_data_pages(void)
-{
- struct zone *zone;
- unsigned long zone_pfn;
- struct pbe * pbe = pagedir_nosave;
-
- pr_debug("copy_data_pages(): pages to copy: %d\n", nr_copy_pages);
- for_each_zone (zone) {
- if (is_highmem(zone))
- continue;
- mark_free_pages(zone);
- for (zone_pfn = 0; zone_pfn < zone->spanned_pages; ++zone_pfn) {
- if (saveable(zone, &zone_pfn)) {
- struct page * page;
- page = pfn_to_page(zone_pfn + zone->zone_start_pfn);
- BUG_ON(!pbe);
- pbe->orig_address = (long) page_address(page);
- /* copy_page is not usable for copying task structs. */
- memcpy((void *)pbe->address, (void *)pbe->orig_address, PAGE_SIZE);
- pbe = pbe->next;
- }
- }
- }
- BUG_ON(pbe);
-}
-
-
-/**
- * calc_nr - Determine the number of pages needed for a pbe list.
- */
-
-static int calc_nr(int nr_copy)
-{
- return nr_copy + (nr_copy+PBES_PER_PAGE-2)/(PBES_PER_PAGE-1);
-}
-
-/**
- * free_pagedir - free pages allocated with alloc_pagedir()
- */
-
-static inline void free_pagedir(struct pbe *pblist)
-{
- struct pbe *pbe;
-
- while (pblist) {
- pbe = (pblist + PB_PAGE_SKIP)->next;
- free_page((unsigned long)pblist);
- pblist = pbe;
- }
-}
-
-/**
- * fill_pb_page - Create a list of PBEs on a given memory page
- */
-
-static inline void fill_pb_page(struct pbe *pbpage)
-{
- struct pbe *p;
-
- p = pbpage;
- pbpage += PB_PAGE_SKIP;
- do
- p->next = p + 1;
- while (++p < pbpage);
-}
-
-/**
- * create_pbe_list - Create a list of PBEs on top of a given chain
- * of memory pages allocated with alloc_pagedir()
- */
-
-static void create_pbe_list(struct pbe *pblist, unsigned nr_pages)
-{
- struct pbe *pbpage, *p;
- unsigned num = PBES_PER_PAGE;
-
- for_each_pb_page (pbpage, pblist) {
- if (num >= nr_pages)
- break;
-
- fill_pb_page(pbpage);
- num += PBES_PER_PAGE;
- }
- if (pbpage) {
- for (num -= PBES_PER_PAGE - 1, p = pbpage; num < nr_pages; p++, num++)
- p->next = p + 1;
- p->next = NULL;
- }
- pr_debug("create_pbe_list(): initialized %d PBEs\n", num);
-}
-
-/**
- * alloc_pagedir - Allocate the page directory.
- *
- * First, determine exactly how many pages we need and
- * allocate them.
- *
- * We arrange the pages in a chain: each page is an array of PBES_PER_PAGE
- * struct pbe elements (pbes) and the last element in the page points
- * to the next page.
- *
- * On each page we set up a list of struct_pbe elements.
- */
-
-static struct pbe * alloc_pagedir(unsigned nr_pages)
-{
- unsigned num;
- struct pbe *pblist, *pbe;
-
- if (!nr_pages)
- return NULL;
-
- pr_debug("alloc_pagedir(): nr_pages = %d\n", nr_pages);
- pblist = (struct pbe *)get_zeroed_page(GFP_ATOMIC | __GFP_COLD);
- for (pbe = pblist, num = PBES_PER_PAGE; pbe && num < nr_pages;
- pbe = pbe->next, num += PBES_PER_PAGE) {
- pbe += PB_PAGE_SKIP;
- pbe->next = (struct pbe *)get_zeroed_page(GFP_ATOMIC | __GFP_COLD);
- }
- if (!pbe) { /* get_zeroed_page() failed */
- free_pagedir(pblist);
- pblist = NULL;
- }
- return pblist;
-}
-
-/**
- * free_image_pages - Free pages allocated for snapshot
- */
-
-static void free_image_pages(void)
-{
- struct pbe * p;
-
- for_each_pbe (p, pagedir_save) {
- if (p->address) {
- ClearPageNosave(virt_to_page(p->address));
- free_page(p->address);
- p->address = 0;
- }
- }
-}
-
-/**
- * alloc_image_pages - Allocate pages for the snapshot.
- */
-
-static int alloc_image_pages(void)
-{
- struct pbe * p;
-
- for_each_pbe (p, pagedir_save) {
- p->address = get_zeroed_page(GFP_ATOMIC | __GFP_COLD);
- if (!p->address)
- return -ENOMEM;
- SetPageNosave(virt_to_page(p->address));
- }
- return 0;
-}
-
-/* Free pages we allocated for suspend. Suspend pages are alocated
- * before atomic copy, so we need to free them after resume.
- */
-void swsusp_free(void)
-{
- BUG_ON(PageNosave(virt_to_page(pagedir_save)));
- BUG_ON(PageNosaveFree(virt_to_page(pagedir_save)));
- free_image_pages();
- free_pagedir(pagedir_save);
-}
-
-
-/**
- * enough_free_mem - Make sure we enough free memory to snapshot.
- *
- * Returns TRUE or FALSE after checking the number of available
- * free pages.
- */
-
-static int enough_free_mem(void)
-{
- if (nr_free_pages() < (nr_copy_pages + PAGES_FOR_IO)) {
- pr_debug("swsusp: Not enough free pages: Have %d\n",
- nr_free_pages());
- return 0;
- }
- return 1;
-}
-
-
-/**
- * enough_swap - Make sure we have enough swap to save the image.
- *
- * Returns TRUE or FALSE after checking the total amount of swap
- * space avaiable.
- *
- * FIXME: si_swapinfo(&i) returns all swap devices information.
- * We should only consider resume_device.
- */
-
-static int enough_swap(void)
-{
- struct sysinfo i;
-
- si_swapinfo(&i);
- if (i.freeswap < (nr_copy_pages + PAGES_FOR_IO)) {
- pr_debug("swsusp: Not enough swap. Need %ld\n",i.freeswap);
- return 0;
- }
- return 1;
-}
-
-static int swsusp_alloc(void)
-{
- int error;
-
- pagedir_nosave = NULL;
- nr_copy_pages = calc_nr(nr_copy_pages);
- nr_copy_pages_check = nr_copy_pages;
-
- pr_debug("suspend: (pages needed: %d + %d free: %d)\n",
- nr_copy_pages, PAGES_FOR_IO, nr_free_pages());
-
- if (!enough_free_mem())
- return -ENOMEM;
-
- if (!enough_swap())
- return -ENOSPC;
-
- if (MAX_PBES < nr_copy_pages / PBES_PER_PAGE +
- !!(nr_copy_pages % PBES_PER_PAGE))
- return -ENOSPC;
-
- if (!(pagedir_save = alloc_pagedir(nr_copy_pages))) {
- printk(KERN_ERR "suspend: Allocating pagedir failed.\n");
- return -ENOMEM;
- }
- create_pbe_list(pagedir_save, nr_copy_pages);
- pagedir_nosave = pagedir_save;
- if ((error = alloc_image_pages())) {
- printk(KERN_ERR "suspend: Allocating image pages failed.\n");
- swsusp_free();
- return error;
- }
-
- return 0;
-}
-
-static int suspend_prepare_image(void)
-{
- int error;
-
- pr_debug("swsusp: critical section: \n");
- if (save_highmem()) {
- printk(KERN_CRIT "Suspend machine: Not enough free pages for highmem\n");
- restore_highmem();
- return -ENOMEM;
- }
-
- drain_local_pages();
- count_data_pages();
- printk("swsusp: Need to copy %u pages\n", nr_copy_pages);
-
- error = swsusp_alloc();
- if (error)
- return error;
-
- /* During allocating of suspend pagedir, new cold pages may appear.
- * Kill them.
- */
- drain_local_pages();
- copy_data_pages();
-
- /*
- * End of critical section. From now on, we can write to memory,
- * but we should not touch disk. This specially means we must _not_
- * touch swap space! Except we must write out our image of course.
- */
-
- printk("swsusp: critical section/: done (%d pages copied)\n", nr_copy_pages );
- return 0;
-}
-
-
/* It is important _NOT_ to umount filesystems at this point. We want
* them synced (in case something goes wrong) but we DO not want to mark
* filesystem clean: it is not. (And it does not matter, if we resume
@@ -994,28 +567,24 @@ static int suspend_prepare_image(void)
int swsusp_write(void)
{
int error;
- device_resume();
+
+ if ((error = swsusp_swap_check())) {
+ printk(KERN_ERR "swsusp: cannot find swap device, try swapon -a.\n");
+ return error;
+ }
lock_swapdevices();
error = write_suspend_image();
/* This will unlock ignored swap devices since writing is finished */
lock_swapdevices();
return error;
-
}
-extern asmlinkage int swsusp_arch_suspend(void);
-extern asmlinkage int swsusp_arch_resume(void);
-
-
-asmlinkage int swsusp_save(void)
-{
- return suspend_prepare_image();
-}
int swsusp_suspend(void)
{
int error;
+
if ((error = arch_prepare_suspend()))
return error;
local_irq_disable();
@@ -1027,15 +596,12 @@ int swsusp_suspend(void)
*/
if ((error = device_power_down(PMSG_FREEZE))) {
printk(KERN_ERR "Some devices failed to power down, aborting suspend\n");
- local_irq_enable();
- return error;
+ goto Enable_irqs;
}
- if ((error = swsusp_swap_check())) {
- printk(KERN_ERR "swsusp: cannot find swap device, try swapon -a.\n");
- device_power_up();
- local_irq_enable();
- return error;
+ if ((error = save_highmem())) {
+ printk(KERN_ERR "swsusp: Not enough free pages for highmem\n");
+ goto Restore_highmem;
}
save_processor_state();
@@ -1043,9 +609,10 @@ int swsusp_suspend(void)
printk(KERN_ERR "Error %d suspending\n", error);
/* Restore control flow magically appears here */
restore_processor_state();
- BUG_ON (nr_copy_pages_check != nr_copy_pages);
+Restore_highmem:
restore_highmem();
device_power_up();
+Enable_irqs:
local_irq_enable();
return error;
}
@@ -1063,6 +630,11 @@ int swsusp_resume(void)
* execution continues at place where swsusp_arch_suspend was called
*/
BUG_ON(!error);
+ /* The only reason why swsusp_arch_resume() can fail is memory being
+ * very tight, so we have to free it as soon as we can to avoid
+ * subsequent failures
+ */
+ swsusp_free();
restore_processor_state();
restore_highmem();
touch_softlockup_watchdog();
@@ -1072,159 +644,43 @@ int swsusp_resume(void)
}
/**
- * On resume, for storing the PBE list and the image,
- * we can only use memory pages that do not conflict with the pages
- * which had been used before suspend.
- *
- * We don't know which pages are usable until we allocate them.
- *
- * Allocated but unusable (ie eaten) memory pages are linked together
- * to create a list, so that we can free them easily
- *
- * We could have used a type other than (void *)
- * for this purpose, but ...
+ * mark_unsafe_pages - mark the pages that cannot be used for storing
+ * the image during resume, because they conflict with the pages that
+ * had been used before suspend
*/
-static void **eaten_memory = NULL;
-static inline void eat_page(void *page)
-{
- void **c;
-
- c = eaten_memory;
- eaten_memory = page;
- *eaten_memory = c;
-}
-
-unsigned long get_usable_page(unsigned gfp_mask)
-{
- unsigned long m;
-
- m = get_zeroed_page(gfp_mask);
- while (!PageNosaveFree(virt_to_page(m))) {
- eat_page((void *)m);
- m = get_zeroed_page(gfp_mask);
- if (!m)
- break;
- }
- return m;
-}
-
-void free_eaten_memory(void)
-{
- unsigned long m;
- void **c;
- int i = 0;
-
- c = eaten_memory;
- while (c) {
- m = (unsigned long)c;
- c = *c;
- free_page(m);
- i++;
- }
- eaten_memory = NULL;
- pr_debug("swsusp: %d unused pages freed\n", i);
-}
-
-/**
- * check_pagedir - We ensure here that pages that the PBEs point to
- * won't collide with pages where we're going to restore from the loaded
- * pages later
- */
-
-static int check_pagedir(struct pbe *pblist)
-{
- struct pbe *p;
-
- /* This is necessary, so that we can free allocated pages
- * in case of failure
- */
- for_each_pbe (p, pblist)
- p->address = 0UL;
-
- for_each_pbe (p, pblist) {
- p->address = get_usable_page(GFP_ATOMIC);
- if (!p->address)
- return -ENOMEM;
- }
- return 0;
-}
-
-/**
- * swsusp_pagedir_relocate - It is possible, that some memory pages
- * occupied by the list of PBEs collide with pages where we're going to
- * restore from the loaded pages later. We relocate them here.
- */
-
-static struct pbe * swsusp_pagedir_relocate(struct pbe *pblist)
+static void mark_unsafe_pages(struct pbe *pblist)
{
struct zone *zone;
unsigned long zone_pfn;
- struct pbe *pbpage, *tail, *p;
- void *m;
- int rel = 0, error = 0;
+ struct pbe *p;
if (!pblist) /* a sanity check */
- return NULL;
-
- pr_debug("swsusp: Relocating pagedir (%lu pages to check)\n",
- swsusp_info.pagedir_pages);
-
- /* Set page flags */
+ return;
+ /* Clear page flags */
for_each_zone (zone) {
- for (zone_pfn = 0; zone_pfn < zone->spanned_pages; ++zone_pfn)
- SetPageNosaveFree(pfn_to_page(zone_pfn +
+ for (zone_pfn = 0; zone_pfn < zone->spanned_pages; ++zone_pfn)
+ if (pfn_valid(zone_pfn + zone->zone_start_pfn))
+ ClearPageNosaveFree(pfn_to_page(zone_pfn +
zone->zone_start_pfn));
}
- /* Clear orig addresses */
-
+ /* Mark orig addresses */
for_each_pbe (p, pblist)
- ClearPageNosaveFree(virt_to_page(p->orig_address));
-
- tail = pblist + PB_PAGE_SKIP;
-
- /* Relocate colliding pages */
+ SetPageNosaveFree(virt_to_page(p->orig_address));
- for_each_pb_page (pbpage, pblist) {
- if (!PageNosaveFree(virt_to_page((unsigned long)pbpage))) {
- m = (void *)get_usable_page(GFP_ATOMIC | __GFP_COLD);
- if (!m) {
- error = -ENOMEM;
- break;
- }
- memcpy(m, (void *)pbpage, PAGE_SIZE);
- if (pbpage == pblist)
- pblist = (struct pbe *)m;
- else
- tail->next = (struct pbe *)m;
-
- eat_page((void *)pbpage);
- pbpage = (struct pbe *)m;
-
- /* We have to link the PBEs again */
-
- for (p = pbpage; p < pbpage + PB_PAGE_SKIP; p++)
- if (p->next) /* needed to save the end */
- p->next = p + 1;
+}
- rel++;
- }
- tail = pbpage + PB_PAGE_SKIP;
+static void copy_page_backup_list(struct pbe *dst, struct pbe *src)
+{
+ /* We assume both lists contain the same number of elements */
+ while (src) {
+ dst->orig_address = src->orig_address;
+ dst->swap_address = src->swap_address;
+ dst = dst->next;
+ src = src->next;
}
-
- if (error) {
- printk("\nswsusp: Out of memory\n\n");
- free_pagedir(pblist);
- free_eaten_memory();
- pblist = NULL;
- /* Is this even worth handling? It should never ever happen, and we
- have just lost user's state, anyway... */
- } else
- printk("swsusp: Relocated %d pages\n", rel);
-
- return pblist;
}
/*
@@ -1238,7 +694,7 @@ static struct pbe * swsusp_pagedir_relocate(struct pbe *pblist)
static atomic_t io_done = ATOMIC_INIT(0);
-static int end_io(struct bio * bio, unsigned int num, int err)
+static int end_io(struct bio *bio, unsigned int num, int err)
{
if (!test_bit(BIO_UPTODATE, &bio->bi_flags))
panic("I/O error reading memory image");
@@ -1246,7 +702,7 @@ static int end_io(struct bio * bio, unsigned int num, int err)
return 0;
}
-static struct block_device * resume_bdev;
+static struct block_device *resume_bdev;
/**
* submit - submit BIO request.
@@ -1259,10 +715,10 @@ static struct block_device * resume_bdev;
* Then submit it and wait.
*/
-static int submit(int rw, pgoff_t page_off, void * page)
+static int submit(int rw, pgoff_t page_off, void *page)
{
int error = 0;
- struct bio * bio;
+ struct bio *bio;
bio = bio_alloc(GFP_ATOMIC, 1);
if (!bio)
@@ -1291,12 +747,12 @@ static int submit(int rw, pgoff_t page_off, void * page)
return error;
}
-static int bio_read_page(pgoff_t page_off, void * page)
+static int bio_read_page(pgoff_t page_off, void *page)
{
return submit(READ, page_off, page);
}
-static int bio_write_page(pgoff_t page_off, void * page)
+static int bio_write_page(pgoff_t page_off, void *page)
{
return submit(WRITE, page_off, page);
}
@@ -1306,7 +762,7 @@ static int bio_write_page(pgoff_t page_off, void * page)
* I really don't think that it's foolproof but more than nothing..
*/
-static const char * sanity_check(void)
+static const char *sanity_check(void)
{
dump_info();
if (swsusp_info.version_code != LINUX_VERSION_CODE)
@@ -1332,7 +788,7 @@ static const char * sanity_check(void)
static int check_header(void)
{
- const char * reason = NULL;
+ const char *reason = NULL;
int error;
if ((error = bio_read_page(swp_offset(swsusp_header.swsusp_info), &swsusp_info)))
@@ -1363,7 +819,7 @@ static int check_sig(void)
* Reset swap signature now.
*/
error = bio_write_page(0, &swsusp_header);
- } else {
+ } else {
return -EINVAL;
}
if (!error)
@@ -1380,7 +836,7 @@ static int check_sig(void)
static int data_read(struct pbe *pblist)
{
- struct pbe * p;
+ struct pbe *p;
int error = 0;
int i = 0;
int mod = swsusp_info.image_pages / 100;
@@ -1418,7 +874,7 @@ static int data_read(struct pbe *pblist)
static int read_pagedir(struct pbe *pblist)
{
struct pbe *pbpage, *p;
- unsigned i = 0;
+ unsigned int i = 0;
int error;
if (!pblist)
@@ -1440,9 +896,7 @@ static int read_pagedir(struct pbe *pblist)
break;
}
- if (error)
- free_pagedir(pblist);
- else
+ if (!error)
BUG_ON(i != swsusp_info.pagedir_pages);
return error;
@@ -1467,33 +921,29 @@ static int read_suspend_image(void)
int error = 0;
struct pbe *p;
- if (!(p = alloc_pagedir(nr_copy_pages)))
+ if (!(p = alloc_pagedir(nr_copy_pages, GFP_ATOMIC, 0)))
return -ENOMEM;
if ((error = read_pagedir(p)))
return error;
-
create_pbe_list(p, nr_copy_pages);
-
- if (!(pagedir_nosave = swsusp_pagedir_relocate(p)))
+ mark_unsafe_pages(p);
+ pagedir_nosave = alloc_pagedir(nr_copy_pages, GFP_ATOMIC, 1);
+ if (pagedir_nosave) {
+ create_pbe_list(pagedir_nosave, nr_copy_pages);
+ copy_page_backup_list(pagedir_nosave, p);
+ }
+ free_pagedir(p);
+ if (!pagedir_nosave)
return -ENOMEM;
/* Allocate memory for the image and read the data from swap */
- error = check_pagedir(pagedir_nosave);
+ error = alloc_data_pages(pagedir_nosave, GFP_ATOMIC, 1);
if (!error)
error = data_read(pagedir_nosave);
- if (error) { /* We fail cleanly */
- free_eaten_memory();
- for_each_pbe (p, pagedir_nosave)
- if (p->address) {
- free_page(p->address);
- p->address = 0UL;
- }
- free_pagedir(pagedir_nosave);
- }
return error;
}
diff --git a/kernel/printk.c b/kernel/printk.c
index 4b8f0f9230a4..e9be027bc930 100644
--- a/kernel/printk.c
+++ b/kernel/printk.c
@@ -10,7 +10,7 @@
* elsewhere, in preparation for a serial line console (someday).
* Ted Ts'o, 2/11/93.
* Modified for sysctl support, 1/8/97, Chris Horn.
- * Fixed SMP synchronization, 08/08/99, Manfred Spraul
+ * Fixed SMP synchronization, 08/08/99, Manfred Spraul
* manfreds@colorfullife.com
* Rewrote bits to get rid of console_lock
* 01Mar01 Andrew Morton <andrewm@uow.edu.au>
@@ -148,7 +148,7 @@ static int __init console_setup(char *str)
if (!strcmp(str, "ttyb"))
strcpy(name, "ttyS1");
#endif
- for(s = name; *s; s++)
+ for (s = name; *s; s++)
if ((*s >= '0' && *s <= '9') || *s == ',')
break;
idx = simple_strtoul(s, NULL, 10);
@@ -169,11 +169,11 @@ static int __init log_buf_len_setup(char *str)
size = roundup_pow_of_two(size);
if (size > log_buf_len) {
unsigned long start, dest_idx, offset;
- char * new_log_buf;
+ char *new_log_buf;
new_log_buf = alloc_bootmem(size);
if (!new_log_buf) {
- printk("log_buf_len: allocation failed\n");
+ printk(KERN_WARNING "log_buf_len: allocation failed\n");
goto out;
}
@@ -193,10 +193,9 @@ static int __init log_buf_len_setup(char *str)
log_end -= offset;
spin_unlock_irqrestore(&logbuf_lock, flags);
- printk("log_buf_len: %d\n", log_buf_len);
+ printk(KERN_NOTICE "log_buf_len: %d\n", log_buf_len);
}
out:
-
return 1;
}
@@ -217,7 +216,7 @@ __setup("log_buf_len=", log_buf_len_setup);
* 9 -- Return number of unread characters in the log buffer
* 10 -- Return size of the log buffer
*/
-int do_syslog(int type, char __user * buf, int len)
+int do_syslog(int type, char __user *buf, int len)
{
unsigned long i, j, limit, count;
int do_clear = 0;
@@ -244,7 +243,8 @@ int do_syslog(int type, char __user * buf, int len)
error = -EFAULT;
goto out;
}
- error = wait_event_interruptible(log_wait, (log_start - log_end));
+ error = wait_event_interruptible(log_wait,
+ (log_start - log_end));
if (error)
goto out;
i = 0;
@@ -264,7 +264,7 @@ int do_syslog(int type, char __user * buf, int len)
error = i;
break;
case 4: /* Read/clear last kernel messages */
- do_clear = 1;
+ do_clear = 1;
/* FALL THRU */
case 3: /* Read last kernel messages */
error = -EINVAL;
@@ -288,11 +288,11 @@ int do_syslog(int type, char __user * buf, int len)
limit = log_end;
/*
* __put_user() could sleep, and while we sleep
- * printk() could overwrite the messages
+ * printk() could overwrite the messages
* we try to copy to user space. Therefore
* the messages are copied in reverse. <manfreds>
*/
- for(i = 0; i < count && !error; i++) {
+ for (i = 0; i < count && !error; i++) {
j = limit-1-i;
if (j + log_buf_len < log_end)
break;
@@ -306,10 +306,10 @@ int do_syslog(int type, char __user * buf, int len)
if (error)
break;
error = i;
- if(i != count) {
+ if (i != count) {
int offset = count-error;
/* buffer overflow during copy, correct user buffer. */
- for(i=0;i<error;i++) {
+ for (i = 0; i < error; i++) {
if (__get_user(c,&buf[i+offset]) ||
__put_user(c,&buf[i])) {
error = -EFAULT;
@@ -351,7 +351,7 @@ out:
return error;
}
-asmlinkage long sys_syslog(int type, char __user * buf, int len)
+asmlinkage long sys_syslog(int type, char __user *buf, int len)
{
return do_syslog(type, buf, len);
}
@@ -404,21 +404,19 @@ static void call_console_drivers(unsigned long start, unsigned long end)
cur_index = start;
start_print = start;
while (cur_index != end) {
- if ( msg_level < 0 &&
- ((end - cur_index) > 2) &&
- LOG_BUF(cur_index + 0) == '<' &&
- LOG_BUF(cur_index + 1) >= '0' &&
- LOG_BUF(cur_index + 1) <= '7' &&
- LOG_BUF(cur_index + 2) == '>')
- {
+ if (msg_level < 0 && ((end - cur_index) > 2) &&
+ LOG_BUF(cur_index + 0) == '<' &&
+ LOG_BUF(cur_index + 1) >= '0' &&
+ LOG_BUF(cur_index + 1) <= '7' &&
+ LOG_BUF(cur_index + 2) == '>') {
msg_level = LOG_BUF(cur_index + 1) - '0';
cur_index += 3;
start_print = cur_index;
}
while (cur_index != end) {
char c = LOG_BUF(cur_index);
- cur_index++;
+ cur_index++;
if (c == '\n') {
if (msg_level < 0) {
/*
@@ -461,7 +459,7 @@ static void zap_locks(void)
static unsigned long oops_timestamp;
if (time_after_eq(jiffies, oops_timestamp) &&
- !time_after(jiffies, oops_timestamp + 30*HZ))
+ !time_after(jiffies, oops_timestamp + 30 * HZ))
return;
oops_timestamp = jiffies;
@@ -495,7 +493,7 @@ __attribute__((weak)) unsigned long long printk_clock(void)
/*
* This is printk. It can be called from any context. We want it to work.
- *
+ *
* We try to grab the console_sem. If we succeed, it's easy - we log the output and
* call the console drivers. If we fail to get the semaphore we place the output
* into the log buffer and return. The current holder of the console_sem will
@@ -639,13 +637,19 @@ EXPORT_SYMBOL(vprintk);
#else
-asmlinkage long sys_syslog(int type, char __user * buf, int len)
+asmlinkage long sys_syslog(int type, char __user *buf, int len)
{
return 0;
}
-int do_syslog(int type, char __user * buf, int len) { return 0; }
-static void call_console_drivers(unsigned long start, unsigned long end) {}
+int do_syslog(int type, char __user *buf, int len)
+{
+ return 0;
+}
+
+static void call_console_drivers(unsigned long start, unsigned long end)
+{
+}
#endif
@@ -802,7 +806,6 @@ void console_unblank(void)
c->unblank();
release_console_sem();
}
-EXPORT_SYMBOL(console_unblank);
/*
* Return the console tty driver structure and its associated index
@@ -851,9 +854,9 @@ EXPORT_SYMBOL(console_start);
* print any messages that were printed by the kernel before the
* console driver was initialized.
*/
-void register_console(struct console * console)
+void register_console(struct console *console)
{
- int i;
+ int i;
unsigned long flags;
if (preferred_console < 0)
@@ -878,7 +881,8 @@ void register_console(struct console * console)
* See if this console matches one we selected on
* the command line.
*/
- for(i = 0; i < MAX_CMDLINECONSOLES && console_cmdline[i].name[0]; i++) {
+ for (i = 0; i < MAX_CMDLINECONSOLES && console_cmdline[i].name[0];
+ i++) {
if (strcmp(console_cmdline[i].name, console->name) != 0)
continue;
if (console->index >= 0 &&
@@ -933,9 +937,9 @@ void register_console(struct console * console)
}
EXPORT_SYMBOL(register_console);
-int unregister_console(struct console * console)
+int unregister_console(struct console *console)
{
- struct console *a,*b;
+ struct console *a, *b;
int res = 1;
acquire_console_sem();
@@ -949,10 +953,10 @@ int unregister_console(struct console * console)
b->next = a->next;
res = 0;
break;
- }
+ }
}
}
-
+
/* If last console is removed, we re-enable picking the first
* one that gets registered. Without that, pmac early boot console
* would prevent fbcon from taking over.
@@ -994,7 +998,7 @@ void tty_write_message(struct tty_struct *tty, char *msg)
int __printk_ratelimit(int ratelimit_jiffies, int ratelimit_burst)
{
static DEFINE_SPINLOCK(ratelimit_lock);
- static unsigned long toks = 10*5*HZ;
+ static unsigned long toks = 10 * 5 * HZ;
static unsigned long last_msg;
static int missed;
unsigned long flags;
@@ -1007,6 +1011,7 @@ int __printk_ratelimit(int ratelimit_jiffies, int ratelimit_burst)
toks = ratelimit_burst * ratelimit_jiffies;
if (toks >= ratelimit_jiffies) {
int lost = missed;
+
missed = 0;
toks -= ratelimit_jiffies;
spin_unlock_irqrestore(&ratelimit_lock, flags);
@@ -1021,7 +1026,7 @@ int __printk_ratelimit(int ratelimit_jiffies, int ratelimit_burst)
EXPORT_SYMBOL(__printk_ratelimit);
/* minimum time in jiffies between messages */
-int printk_ratelimit_jiffies = 5*HZ;
+int printk_ratelimit_jiffies = 5 * HZ;
/* number of messages we send before ratelimiting */
int printk_ratelimit_burst = 10;
diff --git a/kernel/ptrace.c b/kernel/ptrace.c
index 019e04ec065a..b88d4186cd7a 100644
--- a/kernel/ptrace.c
+++ b/kernel/ptrace.c
@@ -56,6 +56,10 @@ void ptrace_untrace(task_t *child)
signal_wake_up(child, 1);
}
}
+ if (child->signal->flags & SIGNAL_GROUP_EXIT) {
+ sigaddset(&child->pending.signal, SIGKILL);
+ signal_wake_up(child, 1);
+ }
spin_unlock(&child->sighand->siglock);
}
@@ -77,8 +81,7 @@ void __ptrace_unlink(task_t *child)
SET_LINKS(child);
}
- if (child->state == TASK_TRACED)
- ptrace_untrace(child);
+ ptrace_untrace(child);
}
/*
@@ -152,7 +155,7 @@ int ptrace_attach(struct task_struct *task)
retval = -EPERM;
if (task->pid <= 1)
goto bad;
- if (task == current)
+ if (task->tgid == current->tgid)
goto bad;
/* the same process cannot be attached many times */
if (task->ptrace & PT_PTRACED)
@@ -403,3 +406,85 @@ int ptrace_request(struct task_struct *child, long request,
return ret;
}
+
+#ifndef __ARCH_SYS_PTRACE
+static int ptrace_get_task_struct(long request, long pid,
+ struct task_struct **childp)
+{
+ struct task_struct *child;
+ int ret;
+
+ /*
+ * Callers use child == NULL as an indication to exit early even
+ * when the return value is 0, so make sure it is non-NULL here.
+ */
+ *childp = NULL;
+
+ if (request == PTRACE_TRACEME) {
+ /*
+ * Are we already being traced?
+ */
+ if (current->ptrace & PT_PTRACED)
+ return -EPERM;
+ ret = security_ptrace(current->parent, current);
+ if (ret)
+ return -EPERM;
+ /*
+ * Set the ptrace bit in the process ptrace flags.
+ */
+ current->ptrace |= PT_PTRACED;
+ return 0;
+ }
+
+ /*
+ * You may not mess with init
+ */
+ if (pid == 1)
+ return -EPERM;
+
+ ret = -ESRCH;
+ read_lock(&tasklist_lock);
+ child = find_task_by_pid(pid);
+ if (child)
+ get_task_struct(child);
+ read_unlock(&tasklist_lock);
+ if (!child)
+ return -ESRCH;
+
+ *childp = child;
+ return 0;
+}
+
+asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
+{
+ struct task_struct *child;
+ long ret;
+
+ /*
+ * This lock_kernel fixes a subtle race with suid exec
+ */
+ lock_kernel();
+ ret = ptrace_get_task_struct(request, pid, &child);
+ if (!child)
+ goto out;
+
+ if (request == PTRACE_ATTACH) {
+ ret = ptrace_attach(child);
+ goto out;
+ }
+
+ ret = ptrace_check_attach(child, request == PTRACE_KILL);
+ if (ret < 0)
+ goto out_put_task_struct;
+
+ ret = arch_ptrace(child, request, addr, data);
+ if (ret < 0)
+ goto out_put_task_struct;
+
+ out_put_task_struct:
+ put_task_struct(child);
+ out:
+ unlock_kernel();
+ return ret;
+}
+#endif /* __ARCH_SYS_PTRACE */
diff --git a/kernel/rcupdate.c b/kernel/rcupdate.c
index 2559d4b8f23f..c4d159a21e04 100644
--- a/kernel/rcupdate.c
+++ b/kernel/rcupdate.c
@@ -154,6 +154,15 @@ void fastcall call_rcu_bh(struct rcu_head *head,
}
/*
+ * Return the number of RCU batches processed thus far. Useful
+ * for debug and statistics.
+ */
+long rcu_batches_completed(void)
+{
+ return rcu_ctrlblk.completed;
+}
+
+/*
* Invoke the completed RCU callbacks. They are expected to be in
* a per-cpu list.
*/
@@ -501,6 +510,7 @@ void synchronize_kernel(void)
}
module_param(maxbatch, int, 0);
+EXPORT_SYMBOL_GPL(rcu_batches_completed);
EXPORT_SYMBOL(call_rcu); /* WARNING: GPL-only in April 2006. */
EXPORT_SYMBOL(call_rcu_bh); /* WARNING: GPL-only in April 2006. */
EXPORT_SYMBOL_GPL(synchronize_rcu);
diff --git a/kernel/rcutorture.c b/kernel/rcutorture.c
new file mode 100644
index 000000000000..9b58f1eff3ca
--- /dev/null
+++ b/kernel/rcutorture.c
@@ -0,0 +1,492 @@
+/*
+ * Read-Copy Update /proc-based torture test facility
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright (C) IBM Corporation, 2005
+ *
+ * Authors: Paul E. McKenney <paulmck@us.ibm.com>
+ *
+ * See also: Documentation/RCU/torture.txt
+ */
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kthread.h>
+#include <linux/err.h>
+#include <linux/spinlock.h>
+#include <linux/smp.h>
+#include <linux/rcupdate.h>
+#include <linux/interrupt.h>
+#include <linux/sched.h>
+#include <asm/atomic.h>
+#include <linux/bitops.h>
+#include <linux/module.h>
+#include <linux/completion.h>
+#include <linux/moduleparam.h>
+#include <linux/percpu.h>
+#include <linux/notifier.h>
+#include <linux/rcuref.h>
+#include <linux/cpu.h>
+#include <linux/random.h>
+#include <linux/delay.h>
+#include <linux/byteorder/swabb.h>
+#include <linux/stat.h>
+
+MODULE_LICENSE("GPL");
+
+static int nreaders = -1; /* # reader threads, defaults to 4*ncpus */
+static int stat_interval = 0; /* Interval between stats, in seconds. */
+ /* Defaults to "only at end of test". */
+static int verbose = 0; /* Print more debug info. */
+
+MODULE_PARM(nreaders, "i");
+MODULE_PARM_DESC(nreaders, "Number of RCU reader threads");
+MODULE_PARM(stat_interval, "i");
+MODULE_PARM_DESC(stat_interval, "Number of seconds between stats printk()s");
+MODULE_PARM(verbose, "i");
+MODULE_PARM_DESC(verbose, "Enable verbose debugging printk()s");
+#define TORTURE_FLAG "rcutorture: "
+#define PRINTK_STRING(s) \
+ do { printk(KERN_ALERT TORTURE_FLAG s "\n"); } while (0)
+#define VERBOSE_PRINTK_STRING(s) \
+ do { if (verbose) printk(KERN_ALERT TORTURE_FLAG s "\n"); } while (0)
+#define VERBOSE_PRINTK_ERRSTRING(s) \
+ do { if (verbose) printk(KERN_ALERT TORTURE_FLAG "!!! " s "\n"); } while (0)
+
+static char printk_buf[4096];
+
+static int nrealreaders;
+static struct task_struct *writer_task;
+static struct task_struct **reader_tasks;
+static struct task_struct *stats_task;
+
+#define RCU_TORTURE_PIPE_LEN 10
+
+struct rcu_torture {
+ struct rcu_head rtort_rcu;
+ int rtort_pipe_count;
+ struct list_head rtort_free;
+};
+
+static int fullstop = 0; /* stop generating callbacks at test end. */
+static LIST_HEAD(rcu_torture_freelist);
+static struct rcu_torture *rcu_torture_current = NULL;
+static long rcu_torture_current_version = 0;
+static struct rcu_torture rcu_tortures[10 * RCU_TORTURE_PIPE_LEN];
+static DEFINE_SPINLOCK(rcu_torture_lock);
+static DEFINE_PER_CPU(long [RCU_TORTURE_PIPE_LEN + 1], rcu_torture_count) =
+ { 0 };
+static DEFINE_PER_CPU(long [RCU_TORTURE_PIPE_LEN + 1], rcu_torture_batch) =
+ { 0 };
+static atomic_t rcu_torture_wcount[RCU_TORTURE_PIPE_LEN + 1];
+atomic_t n_rcu_torture_alloc;
+atomic_t n_rcu_torture_alloc_fail;
+atomic_t n_rcu_torture_free;
+
+/*
+ * Allocate an element from the rcu_tortures pool.
+ */
+struct rcu_torture *
+rcu_torture_alloc(void)
+{
+ struct list_head *p;
+
+ spin_lock(&rcu_torture_lock);
+ if (list_empty(&rcu_torture_freelist)) {
+ atomic_inc(&n_rcu_torture_alloc_fail);
+ spin_unlock(&rcu_torture_lock);
+ return NULL;
+ }
+ atomic_inc(&n_rcu_torture_alloc);
+ p = rcu_torture_freelist.next;
+ list_del_init(p);
+ spin_unlock(&rcu_torture_lock);
+ return container_of(p, struct rcu_torture, rtort_free);
+}
+
+/*
+ * Free an element to the rcu_tortures pool.
+ */
+static void
+rcu_torture_free(struct rcu_torture *p)
+{
+ atomic_inc(&n_rcu_torture_free);
+ spin_lock(&rcu_torture_lock);
+ list_add_tail(&p->rtort_free, &rcu_torture_freelist);
+ spin_unlock(&rcu_torture_lock);
+}
+
+static void
+rcu_torture_cb(struct rcu_head *p)
+{
+ int i;
+ struct rcu_torture *rp = container_of(p, struct rcu_torture, rtort_rcu);
+
+ if (fullstop) {
+ /* Test is ending, just drop callbacks on the floor. */
+ /* The next initialization will pick up the pieces. */
+ return;
+ }
+ i = rp->rtort_pipe_count;
+ if (i > RCU_TORTURE_PIPE_LEN)
+ i = RCU_TORTURE_PIPE_LEN;
+ atomic_inc(&rcu_torture_wcount[i]);
+ if (++rp->rtort_pipe_count >= RCU_TORTURE_PIPE_LEN)
+ rcu_torture_free(rp);
+ else
+ call_rcu(p, rcu_torture_cb);
+}
+
+struct rcu_random_state {
+ unsigned long rrs_state;
+ unsigned long rrs_count;
+};
+
+#define RCU_RANDOM_MULT 39916801 /* prime */
+#define RCU_RANDOM_ADD 479001701 /* prime */
+#define RCU_RANDOM_REFRESH 10000
+
+#define DEFINE_RCU_RANDOM(name) struct rcu_random_state name = { 0, 0 }
+
+/*
+ * Crude but fast random-number generator. Uses a linear congruential
+ * generator, with occasional help from get_random_bytes().
+ */
+static long
+rcu_random(struct rcu_random_state *rrsp)
+{
+ long refresh;
+
+ if (--rrsp->rrs_count < 0) {
+ get_random_bytes(&refresh, sizeof(refresh));
+ rrsp->rrs_state += refresh;
+ rrsp->rrs_count = RCU_RANDOM_REFRESH;
+ }
+ rrsp->rrs_state = rrsp->rrs_state * RCU_RANDOM_MULT + RCU_RANDOM_ADD;
+ return swahw32(rrsp->rrs_state);
+}
+
+/*
+ * RCU torture writer kthread. Repeatedly substitutes a new structure
+ * for that pointed to by rcu_torture_current, freeing the old structure
+ * after a series of grace periods (the "pipeline").
+ */
+static int
+rcu_torture_writer(void *arg)
+{
+ int i;
+ long oldbatch = rcu_batches_completed();
+ struct rcu_torture *rp;
+ struct rcu_torture *old_rp;
+ static DEFINE_RCU_RANDOM(rand);
+
+ VERBOSE_PRINTK_STRING("rcu_torture_writer task started");
+ do {
+ schedule_timeout_uninterruptible(1);
+ if (rcu_batches_completed() == oldbatch)
+ continue;
+ if ((rp = rcu_torture_alloc()) == NULL)
+ continue;
+ rp->rtort_pipe_count = 0;
+ udelay(rcu_random(&rand) & 0x3ff);
+ old_rp = rcu_torture_current;
+ rcu_assign_pointer(rcu_torture_current, rp);
+ smp_wmb();
+ if (old_rp != NULL) {
+ i = old_rp->rtort_pipe_count;
+ if (i > RCU_TORTURE_PIPE_LEN)
+ i = RCU_TORTURE_PIPE_LEN;
+ atomic_inc(&rcu_torture_wcount[i]);
+ old_rp->rtort_pipe_count++;
+ call_rcu(&old_rp->rtort_rcu, rcu_torture_cb);
+ }
+ rcu_torture_current_version++;
+ oldbatch = rcu_batches_completed();
+ } while (!kthread_should_stop() && !fullstop);
+ VERBOSE_PRINTK_STRING("rcu_torture_writer task stopping");
+ while (!kthread_should_stop())
+ schedule_timeout_uninterruptible(1);
+ return 0;
+}
+
+/*
+ * RCU torture reader kthread. Repeatedly dereferences rcu_torture_current,
+ * incrementing the corresponding element of the pipeline array. The
+ * counter in the element should never be greater than 1, otherwise, the
+ * RCU implementation is broken.
+ */
+static int
+rcu_torture_reader(void *arg)
+{
+ int completed;
+ DEFINE_RCU_RANDOM(rand);
+ struct rcu_torture *p;
+ int pipe_count;
+
+ VERBOSE_PRINTK_STRING("rcu_torture_reader task started");
+ do {
+ rcu_read_lock();
+ completed = rcu_batches_completed();
+ p = rcu_dereference(rcu_torture_current);
+ if (p == NULL) {
+ /* Wait for rcu_torture_writer to get underway */
+ rcu_read_unlock();
+ schedule_timeout_interruptible(HZ);
+ continue;
+ }
+ udelay(rcu_random(&rand) & 0x7f);
+ preempt_disable();
+ pipe_count = p->rtort_pipe_count;
+ if (pipe_count > RCU_TORTURE_PIPE_LEN) {
+ /* Should not happen, but... */
+ pipe_count = RCU_TORTURE_PIPE_LEN;
+ }
+ ++__get_cpu_var(rcu_torture_count)[pipe_count];
+ completed = rcu_batches_completed() - completed;
+ if (completed > RCU_TORTURE_PIPE_LEN) {
+ /* Should not happen, but... */
+ completed = RCU_TORTURE_PIPE_LEN;
+ }
+ ++__get_cpu_var(rcu_torture_batch)[completed];
+ preempt_enable();
+ rcu_read_unlock();
+ schedule();
+ } while (!kthread_should_stop() && !fullstop);
+ VERBOSE_PRINTK_STRING("rcu_torture_reader task stopping");
+ while (!kthread_should_stop())
+ schedule_timeout_uninterruptible(1);
+ return 0;
+}
+
+/*
+ * Create an RCU-torture statistics message in the specified buffer.
+ */
+static int
+rcu_torture_printk(char *page)
+{
+ int cnt = 0;
+ int cpu;
+ int i;
+ long pipesummary[RCU_TORTURE_PIPE_LEN + 1] = { 0 };
+ long batchsummary[RCU_TORTURE_PIPE_LEN + 1] = { 0 };
+
+ for_each_cpu(cpu) {
+ for (i = 0; i < RCU_TORTURE_PIPE_LEN + 1; i++) {
+ pipesummary[i] += per_cpu(rcu_torture_count, cpu)[i];
+ batchsummary[i] += per_cpu(rcu_torture_batch, cpu)[i];
+ }
+ }
+ for (i = RCU_TORTURE_PIPE_LEN - 1; i >= 0; i--) {
+ if (pipesummary[i] != 0)
+ break;
+ }
+ cnt += sprintf(&page[cnt], "rcutorture: ");
+ cnt += sprintf(&page[cnt],
+ "rtc: %p ver: %ld tfle: %d rta: %d rtaf: %d rtf: %d",
+ rcu_torture_current,
+ rcu_torture_current_version,
+ list_empty(&rcu_torture_freelist),
+ atomic_read(&n_rcu_torture_alloc),
+ atomic_read(&n_rcu_torture_alloc_fail),
+ atomic_read(&n_rcu_torture_free));
+ cnt += sprintf(&page[cnt], "\nrcutorture: ");
+ if (i > 1)
+ cnt += sprintf(&page[cnt], "!!! ");
+ cnt += sprintf(&page[cnt], "Reader Pipe: ");
+ for (i = 0; i < RCU_TORTURE_PIPE_LEN + 1; i++)
+ cnt += sprintf(&page[cnt], " %ld", pipesummary[i]);
+ cnt += sprintf(&page[cnt], "\nrcutorture: ");
+ cnt += sprintf(&page[cnt], "Reader Batch: ");
+ for (i = 0; i < RCU_TORTURE_PIPE_LEN; i++)
+ cnt += sprintf(&page[cnt], " %ld", batchsummary[i]);
+ cnt += sprintf(&page[cnt], "\nrcutorture: ");
+ cnt += sprintf(&page[cnt], "Free-Block Circulation: ");
+ for (i = 0; i < RCU_TORTURE_PIPE_LEN + 1; i++) {
+ cnt += sprintf(&page[cnt], " %d",
+ atomic_read(&rcu_torture_wcount[i]));
+ }
+ cnt += sprintf(&page[cnt], "\n");
+ return cnt;
+}
+
+/*
+ * Print torture statistics. Caller must ensure that there is only
+ * one call to this function at a given time!!! This is normally
+ * accomplished by relying on the module system to only have one copy
+ * of the module loaded, and then by giving the rcu_torture_stats
+ * kthread full control (or the init/cleanup functions when rcu_torture_stats
+ * thread is not running).
+ */
+static void
+rcu_torture_stats_print(void)
+{
+ int cnt;
+
+ cnt = rcu_torture_printk(printk_buf);
+ printk(KERN_ALERT "%s", printk_buf);
+}
+
+/*
+ * Periodically prints torture statistics, if periodic statistics printing
+ * was specified via the stat_interval module parameter.
+ *
+ * No need to worry about fullstop here, since this one doesn't reference
+ * volatile state or register callbacks.
+ */
+static int
+rcu_torture_stats(void *arg)
+{
+ VERBOSE_PRINTK_STRING("rcu_torture_stats task started");
+ do {
+ schedule_timeout_interruptible(stat_interval * HZ);
+ rcu_torture_stats_print();
+ } while (!kthread_should_stop());
+ VERBOSE_PRINTK_STRING("rcu_torture_stats task stopping");
+ return 0;
+}
+
+static void
+rcu_torture_cleanup(void)
+{
+ int i;
+
+ fullstop = 1;
+ if (writer_task != NULL) {
+ VERBOSE_PRINTK_STRING("Stopping rcu_torture_writer task");
+ kthread_stop(writer_task);
+ }
+ writer_task = NULL;
+
+ if (reader_tasks != NULL) {
+ for (i = 0; i < nrealreaders; i++) {
+ if (reader_tasks[i] != NULL) {
+ VERBOSE_PRINTK_STRING(
+ "Stopping rcu_torture_reader task");
+ kthread_stop(reader_tasks[i]);
+ }
+ reader_tasks[i] = NULL;
+ }
+ kfree(reader_tasks);
+ reader_tasks = NULL;
+ }
+ rcu_torture_current = NULL;
+
+ if (stats_task != NULL) {
+ VERBOSE_PRINTK_STRING("Stopping rcu_torture_stats task");
+ kthread_stop(stats_task);
+ }
+ stats_task = NULL;
+
+ /* Wait for all RCU callbacks to fire. */
+
+ for (i = 0; i < RCU_TORTURE_PIPE_LEN; i++)
+ synchronize_rcu();
+ rcu_torture_stats_print(); /* -After- the stats thread is stopped! */
+ PRINTK_STRING("--- End of test");
+}
+
+static int
+rcu_torture_init(void)
+{
+ int i;
+ int cpu;
+ int firsterr = 0;
+
+ /* Process args and tell the world that the torturer is on the job. */
+
+ if (nreaders >= 0)
+ nrealreaders = nreaders;
+ else
+ nrealreaders = 2 * num_online_cpus();
+ printk(KERN_ALERT TORTURE_FLAG
+ "--- Start of test: nreaders=%d stat_interval=%d verbose=%d\n",
+ nrealreaders, stat_interval, verbose);
+ fullstop = 0;
+
+ /* Set up the freelist. */
+
+ INIT_LIST_HEAD(&rcu_torture_freelist);
+ for (i = 0; i < sizeof(rcu_tortures) / sizeof(rcu_tortures[0]); i++) {
+ list_add_tail(&rcu_tortures[i].rtort_free,
+ &rcu_torture_freelist);
+ }
+
+ /* Initialize the statistics so that each run gets its own numbers. */
+
+ rcu_torture_current = NULL;
+ rcu_torture_current_version = 0;
+ atomic_set(&n_rcu_torture_alloc, 0);
+ atomic_set(&n_rcu_torture_alloc_fail, 0);
+ atomic_set(&n_rcu_torture_free, 0);
+ for (i = 0; i < RCU_TORTURE_PIPE_LEN + 1; i++)
+ atomic_set(&rcu_torture_wcount[i], 0);
+ for_each_cpu(cpu) {
+ for (i = 0; i < RCU_TORTURE_PIPE_LEN + 1; i++) {
+ per_cpu(rcu_torture_count, cpu)[i] = 0;
+ per_cpu(rcu_torture_batch, cpu)[i] = 0;
+ }
+ }
+
+ /* Start up the kthreads. */
+
+ VERBOSE_PRINTK_STRING("Creating rcu_torture_writer task");
+ writer_task = kthread_run(rcu_torture_writer, NULL,
+ "rcu_torture_writer");
+ if (IS_ERR(writer_task)) {
+ firsterr = PTR_ERR(writer_task);
+ VERBOSE_PRINTK_ERRSTRING("Failed to create writer");
+ writer_task = NULL;
+ goto unwind;
+ }
+ reader_tasks = kmalloc(nrealreaders * sizeof(reader_tasks[0]),
+ GFP_KERNEL);
+ if (reader_tasks == NULL) {
+ VERBOSE_PRINTK_ERRSTRING("out of memory");
+ firsterr = -ENOMEM;
+ goto unwind;
+ }
+ for (i = 0; i < nrealreaders; i++) {
+ VERBOSE_PRINTK_STRING("Creating rcu_torture_reader task");
+ reader_tasks[i] = kthread_run(rcu_torture_reader, NULL,
+ "rcu_torture_reader");
+ if (IS_ERR(reader_tasks[i])) {
+ firsterr = PTR_ERR(reader_tasks[i]);
+ VERBOSE_PRINTK_ERRSTRING("Failed to create reader");
+ reader_tasks[i] = NULL;
+ goto unwind;
+ }
+ }
+ if (stat_interval > 0) {
+ VERBOSE_PRINTK_STRING("Creating rcu_torture_stats task");
+ stats_task = kthread_run(rcu_torture_stats, NULL,
+ "rcu_torture_stats");
+ if (IS_ERR(stats_task)) {
+ firsterr = PTR_ERR(stats_task);
+ VERBOSE_PRINTK_ERRSTRING("Failed to create stats");
+ stats_task = NULL;
+ goto unwind;
+ }
+ }
+ return 0;
+
+unwind:
+ rcu_torture_cleanup();
+ return firsterr;
+}
+
+module_init(rcu_torture_init);
+module_exit(rcu_torture_cleanup);
diff --git a/kernel/sched.c b/kernel/sched.c
index 1e5cafdf4e27..b6506671b2be 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -206,6 +206,7 @@ struct runqueue {
*/
unsigned long nr_running;
#ifdef CONFIG_SMP
+ unsigned long prio_bias;
unsigned long cpu_load[3];
#endif
unsigned long long nr_switches;
@@ -659,13 +660,68 @@ static int effective_prio(task_t *p)
return prio;
}
+#ifdef CONFIG_SMP
+static inline void inc_prio_bias(runqueue_t *rq, int prio)
+{
+ rq->prio_bias += MAX_PRIO - prio;
+}
+
+static inline void dec_prio_bias(runqueue_t *rq, int prio)
+{
+ rq->prio_bias -= MAX_PRIO - prio;
+}
+
+static inline void inc_nr_running(task_t *p, runqueue_t *rq)
+{
+ rq->nr_running++;
+ if (rt_task(p)) {
+ if (p != rq->migration_thread)
+ /*
+ * The migration thread does the actual balancing. Do
+ * not bias by its priority as the ultra high priority
+ * will skew balancing adversely.
+ */
+ inc_prio_bias(rq, p->prio);
+ } else
+ inc_prio_bias(rq, p->static_prio);
+}
+
+static inline void dec_nr_running(task_t *p, runqueue_t *rq)
+{
+ rq->nr_running--;
+ if (rt_task(p)) {
+ if (p != rq->migration_thread)
+ dec_prio_bias(rq, p->prio);
+ } else
+ dec_prio_bias(rq, p->static_prio);
+}
+#else
+static inline void inc_prio_bias(runqueue_t *rq, int prio)
+{
+}
+
+static inline void dec_prio_bias(runqueue_t *rq, int prio)
+{
+}
+
+static inline void inc_nr_running(task_t *p, runqueue_t *rq)
+{
+ rq->nr_running++;
+}
+
+static inline void dec_nr_running(task_t *p, runqueue_t *rq)
+{
+ rq->nr_running--;
+}
+#endif
+
/*
* __activate_task - move a task to the runqueue.
*/
static inline void __activate_task(task_t *p, runqueue_t *rq)
{
enqueue_task(p, rq->active);
- rq->nr_running++;
+ inc_nr_running(p, rq);
}
/*
@@ -674,7 +730,7 @@ static inline void __activate_task(task_t *p, runqueue_t *rq)
static inline void __activate_idle_task(task_t *p, runqueue_t *rq)
{
enqueue_task_head(p, rq->active);
- rq->nr_running++;
+ inc_nr_running(p, rq);
}
static int recalc_task_prio(task_t *p, unsigned long long now)
@@ -759,7 +815,8 @@ static void activate_task(task_t *p, runqueue_t *rq, int local)
}
#endif
- p->prio = recalc_task_prio(p, now);
+ if (!rt_task(p))
+ p->prio = recalc_task_prio(p, now);
/*
* This checks to make sure it's not an uninterruptible task
@@ -793,7 +850,7 @@ static void activate_task(task_t *p, runqueue_t *rq, int local)
*/
static void deactivate_task(struct task_struct *p, runqueue_t *rq)
{
- rq->nr_running--;
+ dec_nr_running(p, rq);
dequeue_task(p, p->array);
p->array = NULL;
}
@@ -808,21 +865,28 @@ static void deactivate_task(struct task_struct *p, runqueue_t *rq)
#ifdef CONFIG_SMP
static void resched_task(task_t *p)
{
- int need_resched, nrpolling;
+ int cpu;
assert_spin_locked(&task_rq(p)->lock);
- /* minimise the chance of sending an interrupt to poll_idle() */
- nrpolling = test_tsk_thread_flag(p,TIF_POLLING_NRFLAG);
- need_resched = test_and_set_tsk_thread_flag(p,TIF_NEED_RESCHED);
- nrpolling |= test_tsk_thread_flag(p,TIF_POLLING_NRFLAG);
+ if (unlikely(test_tsk_thread_flag(p, TIF_NEED_RESCHED)))
+ return;
+
+ set_tsk_thread_flag(p, TIF_NEED_RESCHED);
+
+ cpu = task_cpu(p);
+ if (cpu == smp_processor_id())
+ return;
- if (!need_resched && !nrpolling && (task_cpu(p) != smp_processor_id()))
- smp_send_reschedule(task_cpu(p));
+ /* NEED_RESCHED must be visible before we test POLLING_NRFLAG */
+ smp_mb();
+ if (!test_tsk_thread_flag(p, TIF_POLLING_NRFLAG))
+ smp_send_reschedule(cpu);
}
#else
static inline void resched_task(task_t *p)
{
+ assert_spin_locked(&task_rq(p)->lock);
set_tsk_need_resched(p);
}
#endif
@@ -930,27 +994,61 @@ void kick_process(task_t *p)
* We want to under-estimate the load of migration sources, to
* balance conservatively.
*/
-static inline unsigned long source_load(int cpu, int type)
+static inline unsigned long __source_load(int cpu, int type, enum idle_type idle)
{
runqueue_t *rq = cpu_rq(cpu);
- unsigned long load_now = rq->nr_running * SCHED_LOAD_SCALE;
+ unsigned long running = rq->nr_running;
+ unsigned long source_load, cpu_load = rq->cpu_load[type-1],
+ load_now = running * SCHED_LOAD_SCALE;
+
if (type == 0)
- return load_now;
+ source_load = load_now;
+ else
+ source_load = min(cpu_load, load_now);
+
+ if (running > 1 || (idle == NOT_IDLE && running))
+ /*
+ * If we are busy rebalancing the load is biased by
+ * priority to create 'nice' support across cpus. When
+ * idle rebalancing we should only bias the source_load if
+ * there is more than one task running on that queue to
+ * prevent idle rebalance from trying to pull tasks from a
+ * queue with only one running task.
+ */
+ source_load = source_load * rq->prio_bias / running;
+
+ return source_load;
+}
- return min(rq->cpu_load[type-1], load_now);
+static inline unsigned long source_load(int cpu, int type)
+{
+ return __source_load(cpu, type, NOT_IDLE);
}
/*
* Return a high guess at the load of a migration-target cpu
*/
-static inline unsigned long target_load(int cpu, int type)
+static inline unsigned long __target_load(int cpu, int type, enum idle_type idle)
{
runqueue_t *rq = cpu_rq(cpu);
- unsigned long load_now = rq->nr_running * SCHED_LOAD_SCALE;
+ unsigned long running = rq->nr_running;
+ unsigned long target_load, cpu_load = rq->cpu_load[type-1],
+ load_now = running * SCHED_LOAD_SCALE;
+
if (type == 0)
- return load_now;
+ target_load = load_now;
+ else
+ target_load = max(cpu_load, load_now);
+
+ if (running > 1 || (idle == NOT_IDLE && running))
+ target_load = target_load * rq->prio_bias / running;
+
+ return target_load;
+}
- return max(rq->cpu_load[type-1], load_now);
+static inline unsigned long target_load(int cpu, int type)
+{
+ return __target_load(cpu, type, NOT_IDLE);
}
/*
@@ -1411,7 +1509,7 @@ void fastcall wake_up_new_task(task_t *p, unsigned long clone_flags)
list_add_tail(&p->run_list, &current->run_list);
p->array = current->array;
p->array->nr_active++;
- rq->nr_running++;
+ inc_nr_running(p, rq);
}
set_need_resched();
} else
@@ -1468,7 +1566,7 @@ void fastcall sched_exit(task_t *p)
* the sleep_avg of the parent as well.
*/
rq = task_rq_lock(p->parent, &flags);
- if (p->first_time_slice) {
+ if (p->first_time_slice && task_cpu(p) == task_cpu(p->parent)) {
p->parent->time_slice += p->time_slice;
if (unlikely(p->parent->time_slice > task_timeslice(p)))
p->parent->time_slice = task_timeslice(p);
@@ -1756,9 +1854,9 @@ void pull_task(runqueue_t *src_rq, prio_array_t *src_array, task_t *p,
runqueue_t *this_rq, prio_array_t *this_array, int this_cpu)
{
dequeue_task(p, src_array);
- src_rq->nr_running--;
+ dec_nr_running(p, src_rq);
set_task_cpu(p, this_cpu);
- this_rq->nr_running++;
+ inc_nr_running(p, this_rq);
enqueue_task(p, this_array);
p->timestamp = (p->timestamp - src_rq->timestamp_last_tick)
+ this_rq->timestamp_last_tick;
@@ -1937,9 +2035,9 @@ find_busiest_group(struct sched_domain *sd, int this_cpu,
/* Bias balancing toward cpus of our domain */
if (local_group)
- load = target_load(i, load_idx);
+ load = __target_load(i, load_idx, idle);
else
- load = source_load(i, load_idx);
+ load = __source_load(i, load_idx, idle);
avg_load += load;
}
@@ -2044,14 +2142,15 @@ out_balanced:
/*
* find_busiest_queue - find the busiest runqueue among the cpus in group.
*/
-static runqueue_t *find_busiest_queue(struct sched_group *group)
+static runqueue_t *find_busiest_queue(struct sched_group *group,
+ enum idle_type idle)
{
unsigned long load, max_load = 0;
runqueue_t *busiest = NULL;
int i;
for_each_cpu_mask(i, group->cpumask) {
- load = source_load(i, 0);
+ load = __source_load(i, 0, idle);
if (load > max_load) {
max_load = load;
@@ -2095,7 +2194,7 @@ static int load_balance(int this_cpu, runqueue_t *this_rq,
goto out_balanced;
}
- busiest = find_busiest_queue(group);
+ busiest = find_busiest_queue(group, idle);
if (!busiest) {
schedstat_inc(sd, lb_nobusyq[idle]);
goto out_balanced;
@@ -2218,7 +2317,7 @@ static int load_balance_newidle(int this_cpu, runqueue_t *this_rq,
goto out_balanced;
}
- busiest = find_busiest_queue(group);
+ busiest = find_busiest_queue(group, NEWLY_IDLE);
if (!busiest) {
schedstat_inc(sd, lb_nobusyq[NEWLY_IDLE]);
goto out_balanced;
@@ -2511,8 +2610,6 @@ void account_system_time(struct task_struct *p, int hardirq_offset,
cpustat->idle = cputime64_add(cpustat->idle, tmp);
/* Account for system time used */
acct_update_integrals(p);
- /* Update rss highwater mark */
- update_mem_hiwater(p);
}
/*
@@ -3453,8 +3550,10 @@ void set_user_nice(task_t *p, long nice)
goto out_unlock;
}
array = p->array;
- if (array)
+ if (array) {
dequeue_task(p, array);
+ dec_prio_bias(rq, p->static_prio);
+ }
old_prio = p->prio;
new_prio = NICE_TO_PRIO(nice);
@@ -3464,6 +3563,7 @@ void set_user_nice(task_t *p, long nice)
if (array) {
enqueue_task(p, array);
+ inc_prio_bias(rq, p->static_prio);
/*
* If the task increased its priority or is running and
* lowered its priority, then reschedule its CPU:
@@ -3565,8 +3665,6 @@ int idle_cpu(int cpu)
return cpu_curr(cpu) == cpu_rq(cpu)->idle;
}
-EXPORT_SYMBOL_GPL(idle_cpu);
-
/**
* idle_task - return the idle task for a given cpu.
* @cpu: the processor in question.
@@ -3879,7 +3977,6 @@ EXPORT_SYMBOL(cpu_present_map);
#ifndef CONFIG_SMP
cpumask_t cpu_online_map = CPU_MASK_ALL;
-EXPORT_SYMBOL_GPL(cpu_online_map);
cpumask_t cpu_possible_map = CPU_MASK_ALL;
#endif
@@ -4683,7 +4780,8 @@ static int migration_call(struct notifier_block *nfb, unsigned long action,
#ifdef CONFIG_HOTPLUG_CPU
case CPU_UP_CANCELED:
/* Unbind it from offline cpu so it can run. Fall thru. */
- kthread_bind(cpu_rq(cpu)->migration_thread,smp_processor_id());
+ kthread_bind(cpu_rq(cpu)->migration_thread,
+ any_online_cpu(cpu_online_map));
kthread_stop(cpu_rq(cpu)->migration_thread);
cpu_rq(cpu)->migration_thread = NULL;
break;
diff --git a/kernel/signal.c b/kernel/signal.c
index f2b96b08fb44..80789a59b4db 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -277,7 +277,6 @@ static struct sigqueue *__sigqueue_alloc(struct task_struct *t, gfp_t flags,
} else {
INIT_LIST_HEAD(&q->list);
q->flags = 0;
- q->lock = NULL;
q->user = get_uid(t->user);
}
return(q);
@@ -406,6 +405,8 @@ void __exit_signal(struct task_struct *tsk)
void exit_signal(struct task_struct *tsk)
{
+ atomic_dec(&tsk->signal->live);
+
write_lock_irq(&tasklist_lock);
__exit_signal(tsk);
write_unlock_irq(&tasklist_lock);
@@ -650,8 +651,7 @@ static int check_kill_permission(int sig, struct siginfo *info,
if (!valid_signal(sig))
return error;
error = -EPERM;
- if ((!info || ((unsigned long)info != 1 &&
- (unsigned long)info != 2 && SI_FROMUSER(info)))
+ if ((info == SEND_SIG_NOINFO || (!is_si_special(info) && SI_FROMUSER(info)))
&& ((sig != SIGCONT) ||
(current->signal->session != t->signal->session))
&& (current->euid ^ t->suid) && (current->euid ^ t->uid)
@@ -788,7 +788,7 @@ static int send_signal(int sig, struct siginfo *info, struct task_struct *t,
* fast-pathed signals for kernel-internal things like SIGSTOP
* or SIGKILL.
*/
- if ((unsigned long)info == 2)
+ if (info == SEND_SIG_FORCED)
goto out_set;
/* Real-time signals must be queued if sent by sigqueue, or
@@ -800,19 +800,19 @@ static int send_signal(int sig, struct siginfo *info, struct task_struct *t,
pass on the info struct. */
q = __sigqueue_alloc(t, GFP_ATOMIC, (sig < SIGRTMIN &&
- ((unsigned long) info < 2 ||
+ (is_si_special(info) ||
info->si_code >= 0)));
if (q) {
list_add_tail(&q->list, &signals->list);
switch ((unsigned long) info) {
- case 0:
+ case (unsigned long) SEND_SIG_NOINFO:
q->info.si_signo = sig;
q->info.si_errno = 0;
q->info.si_code = SI_USER;
q->info.si_pid = current->pid;
q->info.si_uid = current->uid;
break;
- case 1:
+ case (unsigned long) SEND_SIG_PRIV:
q->info.si_signo = sig;
q->info.si_errno = 0;
q->info.si_code = SI_KERNEL;
@@ -823,20 +823,13 @@ static int send_signal(int sig, struct siginfo *info, struct task_struct *t,
copy_siginfo(&q->info, info);
break;
}
- } else {
- if (sig >= SIGRTMIN && info && (unsigned long)info != 1
- && info->si_code != SI_USER)
+ } else if (!is_si_special(info)) {
+ if (sig >= SIGRTMIN && info->si_code != SI_USER)
/*
* Queue overflow, abort. We may abort if the signal was rt
* and sent by user using something other than kill().
*/
return -EAGAIN;
- if (((unsigned long)info > 1) && (info->si_code == SI_TIMER))
- /*
- * Set up a return to indicate that we dropped
- * the signal.
- */
- ret = info->si_sys_private;
}
out_set:
@@ -857,12 +850,6 @@ specific_send_sig_info(int sig, struct siginfo *info, struct task_struct *t)
BUG();
assert_spin_locked(&t->sighand->siglock);
- if (((unsigned long)info > 2) && (info->si_code == SI_TIMER))
- /*
- * Set up a return to indicate that we dropped the signal.
- */
- ret = info->si_sys_private;
-
/* Short-circuit ignored signals. */
if (sig_ignored(t, sig))
goto out;
@@ -892,11 +879,13 @@ force_sig_info(int sig, struct siginfo *info, struct task_struct *t)
int ret;
spin_lock_irqsave(&t->sighand->siglock, flags);
- if (sigismember(&t->blocked, sig) || t->sighand->action[sig-1].sa.sa_handler == SIG_IGN) {
+ if (t->sighand->action[sig-1].sa.sa_handler == SIG_IGN) {
t->sighand->action[sig-1].sa.sa_handler = SIG_DFL;
+ }
+ if (sigismember(&t->blocked, sig)) {
sigdelset(&t->blocked, sig);
- recalc_sigpending_tsk(t);
}
+ recalc_sigpending_tsk(t);
ret = specific_send_sig_info(sig, info, t);
spin_unlock_irqrestore(&t->sighand->siglock, flags);
@@ -906,15 +895,7 @@ force_sig_info(int sig, struct siginfo *info, struct task_struct *t)
void
force_sig_specific(int sig, struct task_struct *t)
{
- unsigned long int flags;
-
- spin_lock_irqsave(&t->sighand->siglock, flags);
- if (t->sighand->action[sig-1].sa.sa_handler == SIG_IGN)
- t->sighand->action[sig-1].sa.sa_handler = SIG_DFL;
- sigdelset(&t->blocked, sig);
- recalc_sigpending_tsk(t);
- specific_send_sig_info(sig, (void *)2, t);
- spin_unlock_irqrestore(&t->sighand->siglock, flags);
+ force_sig_info(sig, SEND_SIG_FORCED, t);
}
/*
@@ -1049,12 +1030,6 @@ __group_send_sig_info(int sig, struct siginfo *info, struct task_struct *p)
assert_spin_locked(&p->sighand->siglock);
handle_stop_signal(sig, p);
- if (((unsigned long)info > 2) && (info->si_code == SI_TIMER))
- /*
- * Set up a return to indicate that we dropped the signal.
- */
- ret = info->si_sys_private;
-
/* Short-circuit ignored signals. */
if (sig_ignored(p, sig))
return ret;
@@ -1107,8 +1082,8 @@ void zap_other_threads(struct task_struct *p)
if (t != p->group_leader)
t->exit_signal = -1;
+ /* SIGKILL will be handled before any pending SIGSTOP */
sigaddset(&t->pending.signal, SIGKILL);
- rm_from_queue(SIG_KERNEL_STOP_MASK, &t->pending);
signal_wake_up(t, 1);
}
}
@@ -1284,10 +1259,13 @@ send_sig_info(int sig, struct siginfo *info, struct task_struct *p)
return ret;
}
+#define __si_special(priv) \
+ ((priv) ? SEND_SIG_PRIV : SEND_SIG_NOINFO)
+
int
send_sig(int sig, struct task_struct *p, int priv)
{
- return send_sig_info(sig, (void*)(long)(priv != 0), p);
+ return send_sig_info(sig, __si_special(priv), p);
}
/*
@@ -1307,7 +1285,7 @@ send_group_sig_info(int sig, struct siginfo *info, struct task_struct *p)
void
force_sig(int sig, struct task_struct *p)
{
- force_sig_info(sig, (void*)1L, p);
+ force_sig_info(sig, SEND_SIG_PRIV, p);
}
/*
@@ -1332,13 +1310,13 @@ force_sigsegv(int sig, struct task_struct *p)
int
kill_pg(pid_t pgrp, int sig, int priv)
{
- return kill_pg_info(sig, (void *)(long)(priv != 0), pgrp);
+ return kill_pg_info(sig, __si_special(priv), pgrp);
}
int
kill_proc(pid_t pid, int sig, int priv)
{
- return kill_proc_info(sig, (void *)(long)(priv != 0), pid);
+ return kill_proc_info(sig, __si_special(priv), pid);
}
/*
@@ -1369,11 +1347,12 @@ void sigqueue_free(struct sigqueue *q)
* pending queue.
*/
if (unlikely(!list_empty(&q->list))) {
- read_lock(&tasklist_lock);
- spin_lock_irqsave(q->lock, flags);
+ spinlock_t *lock = &current->sighand->siglock;
+ read_lock(&tasklist_lock);
+ spin_lock_irqsave(lock, flags);
if (!list_empty(&q->list))
list_del_init(&q->list);
- spin_unlock_irqrestore(q->lock, flags);
+ spin_unlock_irqrestore(lock, flags);
read_unlock(&tasklist_lock);
}
q->flags &= ~SIGQUEUE_PREALLOC;
@@ -1412,7 +1391,6 @@ send_sigqueue(int sig, struct sigqueue *q, struct task_struct *p)
goto out;
}
- q->lock = &p->sighand->siglock;
list_add_tail(&q->list, &p->pending.list);
sigaddset(&p->pending.signal, sig);
if (!sigismember(&p->blocked, sig))
@@ -1460,7 +1438,6 @@ send_group_sigqueue(int sig, struct sigqueue *q, struct task_struct *p)
* We always use the shared queue for process-wide signals,
* to avoid several races.
*/
- q->lock = &p->sighand->siglock;
list_add_tail(&q->list, &p->signal->shared_pending.list);
sigaddset(&p->signal->shared_pending.signal, sig);
@@ -1522,7 +1499,7 @@ void do_notify_parent(struct task_struct *tsk, int sig)
psig = tsk->parent->sighand;
spin_lock_irqsave(&psig->siglock, flags);
- if (sig == SIGCHLD &&
+ if (!tsk->ptrace && sig == SIGCHLD &&
(psig->action[SIGCHLD-1].sa.sa_handler == SIG_IGN ||
(psig->action[SIGCHLD-1].sa.sa_flags & SA_NOCLDWAIT))) {
/*
@@ -1879,9 +1856,9 @@ relock:
/* Let the debugger run. */
ptrace_stop(signr, signr, info);
- /* We're back. Did the debugger cancel the sig? */
+ /* We're back. Did the debugger cancel the sig or group_exit? */
signr = current->exit_code;
- if (signr == 0)
+ if (signr == 0 || current->signal->flags & SIGNAL_GROUP_EXIT)
continue;
current->exit_code = 0;
@@ -2283,26 +2260,13 @@ sys_kill(int pid, int sig)
return kill_something_info(sig, &info, pid);
}
-/**
- * sys_tgkill - send signal to one specific thread
- * @tgid: the thread group ID of the thread
- * @pid: the PID of the thread
- * @sig: signal to be sent
- *
- * This syscall also checks the tgid and returns -ESRCH even if the PID
- * exists but it's not belonging to the target process anymore. This
- * method solves the problem of threads exiting and PIDs getting reused.
- */
-asmlinkage long sys_tgkill(int tgid, int pid, int sig)
+static int do_tkill(int tgid, int pid, int sig)
{
- struct siginfo info;
int error;
+ struct siginfo info;
struct task_struct *p;
- /* This is only valid for single tasks */
- if (pid <= 0 || tgid <= 0)
- return -EINVAL;
-
+ error = -ESRCH;
info.si_signo = sig;
info.si_errno = 0;
info.si_code = SI_TKILL;
@@ -2311,8 +2275,7 @@ asmlinkage long sys_tgkill(int tgid, int pid, int sig)
read_lock(&tasklist_lock);
p = find_task_by_pid(pid);
- error = -ESRCH;
- if (p && (p->tgid == tgid)) {
+ if (p && (tgid <= 0 || p->tgid == tgid)) {
error = check_kill_permission(sig, &info, p);
/*
* The null signal is a permissions and process existence
@@ -2326,47 +2289,40 @@ asmlinkage long sys_tgkill(int tgid, int pid, int sig)
}
}
read_unlock(&tasklist_lock);
+
return error;
}
+/**
+ * sys_tgkill - send signal to one specific thread
+ * @tgid: the thread group ID of the thread
+ * @pid: the PID of the thread
+ * @sig: signal to be sent
+ *
+ * This syscall also checks the tgid and returns -ESRCH even if the PID
+ * exists but it's not belonging to the target process anymore. This
+ * method solves the problem of threads exiting and PIDs getting reused.
+ */
+asmlinkage long sys_tgkill(int tgid, int pid, int sig)
+{
+ /* This is only valid for single tasks */
+ if (pid <= 0 || tgid <= 0)
+ return -EINVAL;
+
+ return do_tkill(tgid, pid, sig);
+}
+
/*
* Send a signal to only one task, even if it's a CLONE_THREAD task.
*/
asmlinkage long
sys_tkill(int pid, int sig)
{
- struct siginfo info;
- int error;
- struct task_struct *p;
-
/* This is only valid for single tasks */
if (pid <= 0)
return -EINVAL;
- info.si_signo = sig;
- info.si_errno = 0;
- info.si_code = SI_TKILL;
- info.si_pid = current->tgid;
- info.si_uid = current->uid;
-
- read_lock(&tasklist_lock);
- p = find_task_by_pid(pid);
- error = -ESRCH;
- if (p) {
- error = check_kill_permission(sig, &info, p);
- /*
- * The null signal is a permissions and process existence
- * probe. No signal is actually delivered.
- */
- if (!error && sig && p->sighand) {
- spin_lock_irq(&p->sighand->siglock);
- handle_stop_signal(sig, p);
- error = specific_send_sig_info(sig, &info, p);
- spin_unlock_irq(&p->sighand->siglock);
- }
- }
- read_unlock(&tasklist_lock);
- return error;
+ return do_tkill(0, pid, sig);
}
asmlinkage long
diff --git a/kernel/softirq.c b/kernel/softirq.c
index f766b2fc48be..ad3295cdded5 100644
--- a/kernel/softirq.c
+++ b/kernel/softirq.c
@@ -470,7 +470,8 @@ static int __devinit cpu_callback(struct notifier_block *nfb,
#ifdef CONFIG_HOTPLUG_CPU
case CPU_UP_CANCELED:
/* Unbind so it can run. Fall thru. */
- kthread_bind(per_cpu(ksoftirqd, hotcpu), smp_processor_id());
+ kthread_bind(per_cpu(ksoftirqd, hotcpu),
+ any_online_cpu(cpu_online_map));
case CPU_DEAD:
p = per_cpu(ksoftirqd, hotcpu);
per_cpu(ksoftirqd, hotcpu) = NULL;
diff --git a/kernel/softlockup.c b/kernel/softlockup.c
index 75976209cea7..c67189a25d52 100644
--- a/kernel/softlockup.c
+++ b/kernel/softlockup.c
@@ -73,9 +73,6 @@ void softlockup_tick(struct pt_regs *regs)
static int watchdog(void * __bind_cpu)
{
struct sched_param param = { .sched_priority = 99 };
- int this_cpu = (long) __bind_cpu;
-
- printk("softlockup thread %d started up.\n", this_cpu);
sched_setscheduler(current, SCHED_FIFO, &param);
current->flags |= PF_NOFREEZE;
@@ -123,7 +120,8 @@ cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu)
#ifdef CONFIG_HOTPLUG_CPU
case CPU_UP_CANCELED:
/* Unbind so it can run. Fall thru. */
- kthread_bind(per_cpu(watchdog_task, hotcpu), smp_processor_id());
+ kthread_bind(per_cpu(watchdog_task, hotcpu),
+ any_online_cpu(cpu_online_map));
case CPU_DEAD:
p = per_cpu(watchdog_task, hotcpu);
per_cpu(watchdog_task, hotcpu) = NULL;
diff --git a/kernel/sys.c b/kernel/sys.c
index 2fa1ed18123c..bce933ebb29f 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -28,6 +28,7 @@
#include <linux/suspend.h>
#include <linux/tty.h>
#include <linux/signal.h>
+#include <linux/cn_proc.h>
#include <linux/compat.h>
#include <linux/syscalls.h>
@@ -375,18 +376,21 @@ void emergency_restart(void)
}
EXPORT_SYMBOL_GPL(emergency_restart);
-/**
- * kernel_restart - reboot the system
- *
- * Shutdown everything and perform a clean reboot.
- * This is not safe to call in interrupt context.
- */
void kernel_restart_prepare(char *cmd)
{
notifier_call_chain(&reboot_notifier_list, SYS_RESTART, cmd);
system_state = SYSTEM_RESTART;
device_shutdown();
}
+
+/**
+ * kernel_restart - reboot the system
+ * @cmd: pointer to buffer containing command to execute for restart
+ * or %NULL
+ *
+ * Shutdown everything and perform a clean reboot.
+ * This is not safe to call in interrupt context.
+ */
void kernel_restart(char *cmd)
{
kernel_restart_prepare(cmd);
@@ -623,6 +627,7 @@ asmlinkage long sys_setregid(gid_t rgid, gid_t egid)
current->egid = new_egid;
current->gid = new_rgid;
key_fsgid_changed(current);
+ proc_id_connector(current, PROC_EVENT_GID);
return 0;
}
@@ -662,6 +667,7 @@ asmlinkage long sys_setgid(gid_t gid)
return -EPERM;
key_fsgid_changed(current);
+ proc_id_connector(current, PROC_EVENT_GID);
return 0;
}
@@ -751,6 +757,7 @@ asmlinkage long sys_setreuid(uid_t ruid, uid_t euid)
current->fsuid = current->euid;
key_fsuid_changed(current);
+ proc_id_connector(current, PROC_EVENT_UID);
return security_task_post_setuid(old_ruid, old_euid, old_suid, LSM_SETID_RE);
}
@@ -798,6 +805,7 @@ asmlinkage long sys_setuid(uid_t uid)
current->suid = new_suid;
key_fsuid_changed(current);
+ proc_id_connector(current, PROC_EVENT_UID);
return security_task_post_setuid(old_ruid, old_euid, old_suid, LSM_SETID_ID);
}
@@ -846,6 +854,7 @@ asmlinkage long sys_setresuid(uid_t ruid, uid_t euid, uid_t suid)
current->suid = suid;
key_fsuid_changed(current);
+ proc_id_connector(current, PROC_EVENT_UID);
return security_task_post_setuid(old_ruid, old_euid, old_suid, LSM_SETID_RES);
}
@@ -898,6 +907,7 @@ asmlinkage long sys_setresgid(gid_t rgid, gid_t egid, gid_t sgid)
current->sgid = sgid;
key_fsgid_changed(current);
+ proc_id_connector(current, PROC_EVENT_GID);
return 0;
}
@@ -940,6 +950,7 @@ asmlinkage long sys_setfsuid(uid_t uid)
}
key_fsuid_changed(current);
+ proc_id_connector(current, PROC_EVENT_UID);
security_task_post_setuid(old_fsuid, (uid_t)-1, (uid_t)-1, LSM_SETID_FS);
@@ -968,6 +979,7 @@ asmlinkage long sys_setfsgid(gid_t gid)
}
current->fsgid = gid;
key_fsgid_changed(current);
+ proc_id_connector(current, PROC_EVENT_GID);
}
return old_fsgid;
}
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index 8e56e2495542..9990e10192e8 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -169,7 +169,7 @@ struct file_operations proc_sys_file_operations = {
extern struct proc_dir_entry *proc_sys_root;
-static void register_proc_table(ctl_table *, struct proc_dir_entry *);
+static void register_proc_table(ctl_table *, struct proc_dir_entry *, void *);
static void unregister_proc_table(ctl_table *, struct proc_dir_entry *);
#endif
@@ -952,7 +952,7 @@ static ctl_table fs_table[] = {
.data = &aio_nr,
.maxlen = sizeof(aio_nr),
.mode = 0444,
- .proc_handler = &proc_dointvec,
+ .proc_handler = &proc_doulongvec_minmax,
},
{
.ctl_name = FS_AIO_MAX_NR,
@@ -960,7 +960,7 @@ static ctl_table fs_table[] = {
.data = &aio_max_nr,
.maxlen = sizeof(aio_max_nr),
.mode = 0644,
- .proc_handler = &proc_dointvec,
+ .proc_handler = &proc_doulongvec_minmax,
},
#ifdef CONFIG_INOTIFY
{
@@ -992,10 +992,51 @@ static ctl_table dev_table[] = {
extern void init_irq_proc (void);
+static DEFINE_SPINLOCK(sysctl_lock);
+
+/* called under sysctl_lock */
+static int use_table(struct ctl_table_header *p)
+{
+ if (unlikely(p->unregistering))
+ return 0;
+ p->used++;
+ return 1;
+}
+
+/* called under sysctl_lock */
+static void unuse_table(struct ctl_table_header *p)
+{
+ if (!--p->used)
+ if (unlikely(p->unregistering))
+ complete(p->unregistering);
+}
+
+/* called under sysctl_lock, will reacquire if has to wait */
+static void start_unregistering(struct ctl_table_header *p)
+{
+ /*
+ * if p->used is 0, nobody will ever touch that entry again;
+ * we'll eliminate all paths to it before dropping sysctl_lock
+ */
+ if (unlikely(p->used)) {
+ struct completion wait;
+ init_completion(&wait);
+ p->unregistering = &wait;
+ spin_unlock(&sysctl_lock);
+ wait_for_completion(&wait);
+ spin_lock(&sysctl_lock);
+ }
+ /*
+ * do not remove from the list until nobody holds it; walking the
+ * list in do_sysctl() relies on that.
+ */
+ list_del_init(&p->ctl_entry);
+}
+
void __init sysctl_init(void)
{
#ifdef CONFIG_PROC_FS
- register_proc_table(root_table, proc_sys_root);
+ register_proc_table(root_table, proc_sys_root, &root_table_header);
init_irq_proc();
#endif
}
@@ -1004,6 +1045,7 @@ int do_sysctl(int __user *name, int nlen, void __user *oldval, size_t __user *ol
void __user *newval, size_t newlen)
{
struct list_head *tmp;
+ int error = -ENOTDIR;
if (nlen <= 0 || nlen >= CTL_MAXNAME)
return -ENOTDIR;
@@ -1012,20 +1054,30 @@ int do_sysctl(int __user *name, int nlen, void __user *oldval, size_t __user *ol
if (!oldlenp || get_user(old_len, oldlenp))
return -EFAULT;
}
+ spin_lock(&sysctl_lock);
tmp = &root_table_header.ctl_entry;
do {
struct ctl_table_header *head =
list_entry(tmp, struct ctl_table_header, ctl_entry);
void *context = NULL;
- int error = parse_table(name, nlen, oldval, oldlenp,
+
+ if (!use_table(head))
+ continue;
+
+ spin_unlock(&sysctl_lock);
+
+ error = parse_table(name, nlen, oldval, oldlenp,
newval, newlen, head->ctl_table,
&context);
kfree(context);
+
+ spin_lock(&sysctl_lock);
+ unuse_table(head);
if (error != -ENOTDIR)
- return error;
- tmp = tmp->next;
- } while (tmp != &root_table_header.ctl_entry);
- return -ENOTDIR;
+ break;
+ } while ((tmp = tmp->next) != &root_table_header.ctl_entry);
+ spin_unlock(&sysctl_lock);
+ return error;
}
asmlinkage long sys_sysctl(struct __sysctl_args __user *args)
@@ -1236,12 +1288,16 @@ struct ctl_table_header *register_sysctl_table(ctl_table * table,
return NULL;
tmp->ctl_table = table;
INIT_LIST_HEAD(&tmp->ctl_entry);
+ tmp->used = 0;
+ tmp->unregistering = NULL;
+ spin_lock(&sysctl_lock);
if (insert_at_head)
list_add(&tmp->ctl_entry, &root_table_header.ctl_entry);
else
list_add_tail(&tmp->ctl_entry, &root_table_header.ctl_entry);
+ spin_unlock(&sysctl_lock);
#ifdef CONFIG_PROC_FS
- register_proc_table(table, proc_sys_root);
+ register_proc_table(table, proc_sys_root, tmp);
#endif
return tmp;
}
@@ -1255,10 +1311,13 @@ struct ctl_table_header *register_sysctl_table(ctl_table * table,
*/
void unregister_sysctl_table(struct ctl_table_header * header)
{
- list_del(&header->ctl_entry);
+ might_sleep();
+ spin_lock(&sysctl_lock);
+ start_unregistering(header);
#ifdef CONFIG_PROC_FS
unregister_proc_table(header->ctl_table, proc_sys_root);
#endif
+ spin_unlock(&sysctl_lock);
kfree(header);
}
@@ -1269,7 +1328,7 @@ void unregister_sysctl_table(struct ctl_table_header * header)
#ifdef CONFIG_PROC_FS
/* Scan the sysctl entries in table and add them all into /proc */
-static void register_proc_table(ctl_table * table, struct proc_dir_entry *root)
+static void register_proc_table(ctl_table * table, struct proc_dir_entry *root, void *set)
{
struct proc_dir_entry *de;
int len;
@@ -1305,13 +1364,14 @@ static void register_proc_table(ctl_table * table, struct proc_dir_entry *root)
de = create_proc_entry(table->procname, mode, root);
if (!de)
continue;
+ de->set = set;
de->data = (void *) table;
if (table->proc_handler)
de->proc_fops = &proc_sys_file_operations;
}
table->de = de;
if (de->mode & S_IFDIR)
- register_proc_table(table->child, de);
+ register_proc_table(table->child, de, set);
}
}
@@ -1336,6 +1396,13 @@ static void unregister_proc_table(ctl_table * table, struct proc_dir_entry *root
continue;
}
+ /*
+ * In any case, mark the entry as goner; we'll keep it
+ * around if it's busy, but we'll know to do nothing with
+ * its fields. We are under sysctl_lock here.
+ */
+ de->data = NULL;
+
/* Don't unregister proc entries that are still being used.. */
if (atomic_read(&de->count))
continue;
@@ -1349,27 +1416,38 @@ static ssize_t do_rw_proc(int write, struct file * file, char __user * buf,
size_t count, loff_t *ppos)
{
int op;
- struct proc_dir_entry *de;
+ struct proc_dir_entry *de = PDE(file->f_dentry->d_inode);
struct ctl_table *table;
size_t res;
- ssize_t error;
-
- de = PDE(file->f_dentry->d_inode);
- if (!de || !de->data)
- return -ENOTDIR;
- table = (struct ctl_table *) de->data;
- if (!table || !table->proc_handler)
- return -ENOTDIR;
- op = (write ? 002 : 004);
- if (ctl_perm(table, op))
- return -EPERM;
+ ssize_t error = -ENOTDIR;
- res = count;
-
- error = (*table->proc_handler) (table, write, file, buf, &res, ppos);
- if (error)
- return error;
- return res;
+ spin_lock(&sysctl_lock);
+ if (de && de->data && use_table(de->set)) {
+ /*
+ * at that point we know that sysctl was not unregistered
+ * and won't be until we finish
+ */
+ spin_unlock(&sysctl_lock);
+ table = (struct ctl_table *) de->data;
+ if (!table || !table->proc_handler)
+ goto out;
+ error = -EPERM;
+ op = (write ? 002 : 004);
+ if (ctl_perm(table, op))
+ goto out;
+
+ /* careful: calling conventions are nasty here */
+ res = count;
+ error = (*table->proc_handler)(table, write, file,
+ buf, &res, ppos);
+ if (!error)
+ error = res;
+ out:
+ spin_lock(&sysctl_lock);
+ unuse_table(de->set);
+ }
+ spin_unlock(&sysctl_lock);
+ return error;
}
static int proc_opensys(struct inode *inode, struct file *file)
@@ -1997,6 +2075,7 @@ int proc_dointvec_jiffies(ctl_table *table, int write, struct file *filp,
* @filp: the file structure
* @buffer: the user buffer
* @lenp: the size of the user buffer
+ * @ppos: pointer to the file position
*
* Reads/writes up to table->maxlen/sizeof(unsigned int) integer
* values from/to the user buffer, treated as an ASCII string.
diff --git a/kernel/time.c b/kernel/time.c
index 40c2410ac99a..245d595a13cb 100644
--- a/kernel/time.c
+++ b/kernel/time.c
@@ -338,30 +338,20 @@ int do_adjtimex(struct timex *txc)
if (mtemp >= MINSEC) {
ltemp = (time_offset / mtemp) << (SHIFT_USEC -
SHIFT_UPDATE);
- if (ltemp < 0)
- time_freq -= -ltemp >> SHIFT_KH;
- else
- time_freq += ltemp >> SHIFT_KH;
+ time_freq += shift_right(ltemp, SHIFT_KH);
} else /* calibration interval too short (p. 12) */
result = TIME_ERROR;
} else { /* PLL mode */
if (mtemp < MAXSEC) {
ltemp *= mtemp;
- if (ltemp < 0)
- time_freq -= -ltemp >> (time_constant +
- time_constant +
- SHIFT_KF - SHIFT_USEC);
- else
- time_freq += ltemp >> (time_constant +
+ time_freq += shift_right(ltemp,(time_constant +
time_constant +
- SHIFT_KF - SHIFT_USEC);
+ SHIFT_KF - SHIFT_USEC));
} else /* calibration interval too long (p. 12) */
result = TIME_ERROR;
}
- if (time_freq > time_tolerance)
- time_freq = time_tolerance;
- else if (time_freq < -time_tolerance)
- time_freq = -time_tolerance;
+ time_freq = min(time_freq, time_tolerance);
+ time_freq = max(time_freq, -time_tolerance);
} /* STA_PLL || STA_PPSTIME */
} /* txc->modes & ADJ_OFFSET */
if (txc->modes & ADJ_TICK) {
@@ -384,10 +374,7 @@ leave: if ((time_status & (STA_UNSYNC|STA_CLOCKERR)) != 0
if ((txc->modes & ADJ_OFFSET_SINGLESHOT) == ADJ_OFFSET_SINGLESHOT)
txc->offset = save_adjust;
else {
- if (time_offset < 0)
- txc->offset = -(-time_offset >> SHIFT_UPDATE);
- else
- txc->offset = time_offset >> SHIFT_UPDATE;
+ txc->offset = shift_right(time_offset, SHIFT_UPDATE);
}
txc->freq = time_freq + pps_freq;
txc->maxerror = time_maxerror;
@@ -532,6 +519,7 @@ int do_settimeofday (struct timespec *tv)
clock_was_set();
return 0;
}
+EXPORT_SYMBOL(do_settimeofday);
void do_gettimeofday (struct timeval *tv)
{
diff --git a/kernel/timer.c b/kernel/timer.c
index 3ba10fa35b60..fd74268d8663 100644
--- a/kernel/timer.c
+++ b/kernel/timer.c
@@ -46,6 +46,10 @@ static void time_interpolator_update(long delta_nsec);
#define time_interpolator_update(x)
#endif
+u64 jiffies_64 __cacheline_aligned_in_smp = INITIAL_JIFFIES;
+
+EXPORT_SYMBOL(jiffies_64);
+
/*
* per-CPU timer vector definitions:
*/
@@ -91,30 +95,6 @@ static inline void set_running_timer(tvec_base_t *base,
#endif
}
-static void check_timer_failed(struct timer_list *timer)
-{
- static int whine_count;
- if (whine_count < 16) {
- whine_count++;
- printk("Uninitialised timer!\n");
- printk("This is just a warning. Your computer is OK\n");
- printk("function=0x%p, data=0x%lx\n",
- timer->function, timer->data);
- dump_stack();
- }
- /*
- * Now fix it up
- */
- timer->magic = TIMER_MAGIC;
-}
-
-static inline void check_timer(struct timer_list *timer)
-{
- if (timer->magic != TIMER_MAGIC)
- check_timer_failed(timer);
-}
-
-
static void internal_add_timer(tvec_base_t *base, struct timer_list *timer)
{
unsigned long expires = timer->expires;
@@ -177,7 +157,6 @@ void fastcall init_timer(struct timer_list *timer)
{
timer->entry.next = NULL;
timer->base = &per_cpu(tvec_bases, raw_smp_processor_id()).t_base;
- timer->magic = TIMER_MAGIC;
}
EXPORT_SYMBOL(init_timer);
@@ -230,7 +209,6 @@ int __mod_timer(struct timer_list *timer, unsigned long expires)
int ret = 0;
BUG_ON(!timer->function);
- check_timer(timer);
base = lock_timer_base(timer, &flags);
@@ -283,9 +261,6 @@ void add_timer_on(struct timer_list *timer, int cpu)
unsigned long flags;
BUG_ON(timer_pending(timer) || !timer->function);
-
- check_timer(timer);
-
spin_lock_irqsave(&base->t_base.lock, flags);
timer->base = &base->t_base;
internal_add_timer(base, timer);
@@ -316,8 +291,6 @@ int mod_timer(struct timer_list *timer, unsigned long expires)
{
BUG_ON(!timer->function);
- check_timer(timer);
-
/*
* This is a common optimization triggered by the
* networking code - if the timer is re-modified
@@ -348,8 +321,6 @@ int del_timer(struct timer_list *timer)
unsigned long flags;
int ret = 0;
- check_timer(timer);
-
if (timer_pending(timer)) {
base = lock_timer_base(timer, &flags);
if (timer_pending(timer)) {
@@ -412,8 +383,6 @@ out:
*/
int del_timer_sync(struct timer_list *timer)
{
- check_timer(timer);
-
for (;;) {
int ret = try_to_del_timer_sync(timer);
if (ret >= 0)
@@ -632,134 +601,118 @@ long time_next_adjust;
*/
static void second_overflow(void)
{
- long ltemp;
-
- /* Bump the maxerror field */
- time_maxerror += time_tolerance >> SHIFT_USEC;
- if ( time_maxerror > NTP_PHASE_LIMIT ) {
- time_maxerror = NTP_PHASE_LIMIT;
- time_status |= STA_UNSYNC;
- }
-
- /*
- * Leap second processing. If in leap-insert state at
- * the end of the day, the system clock is set back one
- * second; if in leap-delete state, the system clock is
- * set ahead one second. The microtime() routine or
- * external clock driver will insure that reported time
- * is always monotonic. The ugly divides should be
- * replaced.
- */
- switch (time_state) {
-
- case TIME_OK:
- if (time_status & STA_INS)
- time_state = TIME_INS;
- else if (time_status & STA_DEL)
- time_state = TIME_DEL;
- break;
-
- case TIME_INS:
- if (xtime.tv_sec % 86400 == 0) {
- xtime.tv_sec--;
- wall_to_monotonic.tv_sec++;
- /* The timer interpolator will make time change gradually instead
- * of an immediate jump by one second.
- */
- time_interpolator_update(-NSEC_PER_SEC);
- time_state = TIME_OOP;
- clock_was_set();
- printk(KERN_NOTICE "Clock: inserting leap second 23:59:60 UTC\n");
+ long ltemp;
+
+ /* Bump the maxerror field */
+ time_maxerror += time_tolerance >> SHIFT_USEC;
+ if (time_maxerror > NTP_PHASE_LIMIT) {
+ time_maxerror = NTP_PHASE_LIMIT;
+ time_status |= STA_UNSYNC;
}
- break;
-
- case TIME_DEL:
- if ((xtime.tv_sec + 1) % 86400 == 0) {
- xtime.tv_sec++;
- wall_to_monotonic.tv_sec--;
- /* Use of time interpolator for a gradual change of time */
- time_interpolator_update(NSEC_PER_SEC);
- time_state = TIME_WAIT;
- clock_was_set();
- printk(KERN_NOTICE "Clock: deleting leap second 23:59:59 UTC\n");
+
+ /*
+ * Leap second processing. If in leap-insert state at the end of the
+ * day, the system clock is set back one second; if in leap-delete
+ * state, the system clock is set ahead one second. The microtime()
+ * routine or external clock driver will insure that reported time is
+ * always monotonic. The ugly divides should be replaced.
+ */
+ switch (time_state) {
+ case TIME_OK:
+ if (time_status & STA_INS)
+ time_state = TIME_INS;
+ else if (time_status & STA_DEL)
+ time_state = TIME_DEL;
+ break;
+ case TIME_INS:
+ if (xtime.tv_sec % 86400 == 0) {
+ xtime.tv_sec--;
+ wall_to_monotonic.tv_sec++;
+ /*
+ * The timer interpolator will make time change
+ * gradually instead of an immediate jump by one second
+ */
+ time_interpolator_update(-NSEC_PER_SEC);
+ time_state = TIME_OOP;
+ clock_was_set();
+ printk(KERN_NOTICE "Clock: inserting leap second "
+ "23:59:60 UTC\n");
+ }
+ break;
+ case TIME_DEL:
+ if ((xtime.tv_sec + 1) % 86400 == 0) {
+ xtime.tv_sec++;
+ wall_to_monotonic.tv_sec--;
+ /*
+ * Use of time interpolator for a gradual change of
+ * time
+ */
+ time_interpolator_update(NSEC_PER_SEC);
+ time_state = TIME_WAIT;
+ clock_was_set();
+ printk(KERN_NOTICE "Clock: deleting leap second "
+ "23:59:59 UTC\n");
+ }
+ break;
+ case TIME_OOP:
+ time_state = TIME_WAIT;
+ break;
+ case TIME_WAIT:
+ if (!(time_status & (STA_INS | STA_DEL)))
+ time_state = TIME_OK;
}
- break;
-
- case TIME_OOP:
- time_state = TIME_WAIT;
- break;
-
- case TIME_WAIT:
- if (!(time_status & (STA_INS | STA_DEL)))
- time_state = TIME_OK;
- }
-
- /*
- * Compute the phase adjustment for the next second. In
- * PLL mode, the offset is reduced by a fixed factor
- * times the time constant. In FLL mode the offset is
- * used directly. In either mode, the maximum phase
- * adjustment for each second is clamped so as to spread
- * the adjustment over not more than the number of
- * seconds between updates.
- */
- if (time_offset < 0) {
- ltemp = -time_offset;
- if (!(time_status & STA_FLL))
- ltemp >>= SHIFT_KG + time_constant;
- if (ltemp > (MAXPHASE / MINSEC) << SHIFT_UPDATE)
- ltemp = (MAXPHASE / MINSEC) << SHIFT_UPDATE;
- time_offset += ltemp;
- time_adj = -ltemp << (SHIFT_SCALE - SHIFT_HZ - SHIFT_UPDATE);
- } else {
+
+ /*
+ * Compute the phase adjustment for the next second. In PLL mode, the
+ * offset is reduced by a fixed factor times the time constant. In FLL
+ * mode the offset is used directly. In either mode, the maximum phase
+ * adjustment for each second is clamped so as to spread the adjustment
+ * over not more than the number of seconds between updates.
+ */
ltemp = time_offset;
if (!(time_status & STA_FLL))
- ltemp >>= SHIFT_KG + time_constant;
- if (ltemp > (MAXPHASE / MINSEC) << SHIFT_UPDATE)
- ltemp = (MAXPHASE / MINSEC) << SHIFT_UPDATE;
+ ltemp = shift_right(ltemp, SHIFT_KG + time_constant);
+ ltemp = min(ltemp, (MAXPHASE / MINSEC) << SHIFT_UPDATE);
+ ltemp = max(ltemp, -(MAXPHASE / MINSEC) << SHIFT_UPDATE);
time_offset -= ltemp;
time_adj = ltemp << (SHIFT_SCALE - SHIFT_HZ - SHIFT_UPDATE);
- }
-
- /*
- * Compute the frequency estimate and additional phase
- * adjustment due to frequency error for the next
- * second. When the PPS signal is engaged, gnaw on the
- * watchdog counter and update the frequency computed by
- * the pll and the PPS signal.
- */
- pps_valid++;
- if (pps_valid == PPS_VALID) { /* PPS signal lost */
- pps_jitter = MAXTIME;
- pps_stabil = MAXFREQ;
- time_status &= ~(STA_PPSSIGNAL | STA_PPSJITTER |
- STA_PPSWANDER | STA_PPSERROR);
- }
- ltemp = time_freq + pps_freq;
- if (ltemp < 0)
- time_adj -= -ltemp >>
- (SHIFT_USEC + SHIFT_HZ - SHIFT_SCALE);
- else
- time_adj += ltemp >>
- (SHIFT_USEC + SHIFT_HZ - SHIFT_SCALE);
+
+ /*
+ * Compute the frequency estimate and additional phase adjustment due
+ * to frequency error for the next second. When the PPS signal is
+ * engaged, gnaw on the watchdog counter and update the frequency
+ * computed by the pll and the PPS signal.
+ */
+ pps_valid++;
+ if (pps_valid == PPS_VALID) { /* PPS signal lost */
+ pps_jitter = MAXTIME;
+ pps_stabil = MAXFREQ;
+ time_status &= ~(STA_PPSSIGNAL | STA_PPSJITTER |
+ STA_PPSWANDER | STA_PPSERROR);
+ }
+ ltemp = time_freq + pps_freq;
+ time_adj += shift_right(ltemp,(SHIFT_USEC + SHIFT_HZ - SHIFT_SCALE));
#if HZ == 100
- /* Compensate for (HZ==100) != (1 << SHIFT_HZ).
- * Add 25% and 3.125% to get 128.125; => only 0.125% error (p. 14)
- */
- if (time_adj < 0)
- time_adj -= (-time_adj >> 2) + (-time_adj >> 5);
- else
- time_adj += (time_adj >> 2) + (time_adj >> 5);
+ /*
+ * Compensate for (HZ==100) != (1 << SHIFT_HZ). Add 25% and 3.125% to
+ * get 128.125; => only 0.125% error (p. 14)
+ */
+ time_adj += shift_right(time_adj, 2) + shift_right(time_adj, 5);
+#endif
+#if HZ == 250
+ /*
+ * Compensate for (HZ==250) != (1 << SHIFT_HZ). Add 1.5625% and
+ * 0.78125% to get 255.85938; => only 0.05% error (p. 14)
+ */
+ time_adj += shift_right(time_adj, 6) + shift_right(time_adj, 7);
#endif
#if HZ == 1000
- /* Compensate for (HZ==1000) != (1 << SHIFT_HZ).
- * Add 1.5625% and 0.78125% to get 1023.4375; => only 0.05% error (p. 14)
- */
- if (time_adj < 0)
- time_adj -= (-time_adj >> 6) + (-time_adj >> 7);
- else
- time_adj += (time_adj >> 6) + (time_adj >> 7);
+ /*
+ * Compensate for (HZ==1000) != (1 << SHIFT_HZ). Add 1.5625% and
+ * 0.78125% to get 1023.4375; => only 0.05% error (p. 14)
+ */
+ time_adj += shift_right(time_adj, 6) + shift_right(time_adj, 7);
#endif
}
@@ -768,23 +721,20 @@ static void update_wall_time_one_tick(void)
{
long time_adjust_step, delta_nsec;
- if ( (time_adjust_step = time_adjust) != 0 ) {
- /* We are doing an adjtime thing.
- *
- * Prepare time_adjust_step to be within bounds.
- * Note that a positive time_adjust means we want the clock
- * to run faster.
- *
- * Limit the amount of the step to be in the range
- * -tickadj .. +tickadj
- */
- if (time_adjust > tickadj)
- time_adjust_step = tickadj;
- else if (time_adjust < -tickadj)
- time_adjust_step = -tickadj;
-
- /* Reduce by this step the amount of time left */
- time_adjust -= time_adjust_step;
+ if ((time_adjust_step = time_adjust) != 0 ) {
+ /*
+ * We are doing an adjtime thing. Prepare time_adjust_step to
+ * be within bounds. Note that a positive time_adjust means we
+ * want the clock to run faster.
+ *
+ * Limit the amount of the step to be in the range
+ * -tickadj .. +tickadj
+ */
+ time_adjust_step = min(time_adjust_step, (long)tickadj);
+ time_adjust_step = max(time_adjust_step, (long)-tickadj);
+
+ /* Reduce by this step the amount of time left */
+ time_adjust -= time_adjust_step;
}
delta_nsec = tick_nsec + time_adjust_step * 1000;
/*
@@ -792,13 +742,8 @@ static void update_wall_time_one_tick(void)
* advance the tick more.
*/
time_phase += time_adj;
- if (time_phase <= -FINENSEC) {
- long ltemp = -time_phase >> (SHIFT_SCALE - 10);
- time_phase += ltemp << (SHIFT_SCALE - 10);
- delta_nsec -= ltemp;
- }
- else if (time_phase >= FINENSEC) {
- long ltemp = time_phase >> (SHIFT_SCALE - 10);
+ if ((time_phase >= FINENSEC) || (time_phase <= -FINENSEC)) {
+ long ltemp = shift_right(time_phase, (SHIFT_SCALE - 10));
time_phase -= ltemp << (SHIFT_SCALE - 10);
delta_nsec += ltemp;
}
@@ -1128,8 +1073,8 @@ fastcall signed long __sched schedule_timeout(signed long timeout)
if (timeout < 0)
{
printk(KERN_ERR "schedule_timeout: wrong timeout "
- "value %lx from %p\n", timeout,
- __builtin_return_address(0));
+ "value %lx from %p\n", timeout,
+ __builtin_return_address(0));
current->state = TASK_RUNNING;
goto out;
}
@@ -1137,12 +1082,8 @@ fastcall signed long __sched schedule_timeout(signed long timeout)
expire = timeout + jiffies;
- init_timer(&timer);
- timer.expires = expire;
- timer.data = (unsigned long) current;
- timer.function = process_timeout;
-
- add_timer(&timer);
+ setup_timer(&timer, process_timeout, (unsigned long)current);
+ __mod_timer(&timer, expire);
schedule();
del_singleshot_timer_sync(&timer);
@@ -1159,15 +1100,15 @@ EXPORT_SYMBOL(schedule_timeout);
*/
signed long __sched schedule_timeout_interruptible(signed long timeout)
{
- __set_current_state(TASK_INTERRUPTIBLE);
- return schedule_timeout(timeout);
+ __set_current_state(TASK_INTERRUPTIBLE);
+ return schedule_timeout(timeout);
}
EXPORT_SYMBOL(schedule_timeout_interruptible);
signed long __sched schedule_timeout_uninterruptible(signed long timeout)
{
- __set_current_state(TASK_UNINTERRUPTIBLE);
- return schedule_timeout(timeout);
+ __set_current_state(TASK_UNINTERRUPTIBLE);
+ return schedule_timeout(timeout);
}
EXPORT_SYMBOL(schedule_timeout_uninterruptible);
@@ -1507,16 +1448,18 @@ static void time_interpolator_update(long delta_nsec)
if (!time_interpolator)
return;
- /* The interpolator compensates for late ticks by accumulating
- * the late time in time_interpolator->offset. A tick earlier than
- * expected will lead to a reset of the offset and a corresponding
- * jump of the clock forward. Again this only works if the
- * interpolator clock is running slightly slower than the regular clock
- * and the tuning logic insures that.
- */
+ /*
+ * The interpolator compensates for late ticks by accumulating the late
+ * time in time_interpolator->offset. A tick earlier than expected will
+ * lead to a reset of the offset and a corresponding jump of the clock
+ * forward. Again this only works if the interpolator clock is running
+ * slightly slower than the regular clock and the tuning logic insures
+ * that.
+ */
counter = time_interpolator_get_counter(1);
- offset = time_interpolator->offset + GET_TI_NSECS(counter, time_interpolator);
+ offset = time_interpolator->offset +
+ GET_TI_NSECS(counter, time_interpolator);
if (delta_nsec < 0 || (unsigned long) delta_nsec < offset)
time_interpolator->offset = offset - delta_nsec;
diff --git a/kernel/workqueue.c b/kernel/workqueue.c
index 91bacb13a7e2..42df83d7fad2 100644
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -12,6 +12,8 @@
* Andrew Morton <andrewm@uow.edu.au>
* Kai Petzke <wpp@marie.physik.tu-berlin.de>
* Theodore Ts'o <tytso@mit.edu>
+ *
+ * Made to use alloc_percpu by Christoph Lameter <clameter@sgi.com>.
*/
#include <linux/module.h>
@@ -57,7 +59,7 @@ struct cpu_workqueue_struct {
* per-CPU workqueues:
*/
struct workqueue_struct {
- struct cpu_workqueue_struct cpu_wq[NR_CPUS];
+ struct cpu_workqueue_struct *cpu_wq;
const char *name;
struct list_head list; /* Empty if single thread */
};
@@ -102,7 +104,7 @@ int fastcall queue_work(struct workqueue_struct *wq, struct work_struct *work)
if (unlikely(is_single_threaded(wq)))
cpu = 0;
BUG_ON(!list_empty(&work->entry));
- __queue_work(wq->cpu_wq + cpu, work);
+ __queue_work(per_cpu_ptr(wq->cpu_wq, cpu), work);
ret = 1;
}
put_cpu();
@@ -118,7 +120,7 @@ static void delayed_work_timer_fn(unsigned long __data)
if (unlikely(is_single_threaded(wq)))
cpu = 0;
- __queue_work(wq->cpu_wq + cpu, work);
+ __queue_work(per_cpu_ptr(wq->cpu_wq, cpu), work);
}
int fastcall queue_delayed_work(struct workqueue_struct *wq,
@@ -265,13 +267,13 @@ void fastcall flush_workqueue(struct workqueue_struct *wq)
if (is_single_threaded(wq)) {
/* Always use cpu 0's area. */
- flush_cpu_workqueue(wq->cpu_wq + 0);
+ flush_cpu_workqueue(per_cpu_ptr(wq->cpu_wq, 0));
} else {
int cpu;
lock_cpu_hotplug();
for_each_online_cpu(cpu)
- flush_cpu_workqueue(wq->cpu_wq + cpu);
+ flush_cpu_workqueue(per_cpu_ptr(wq->cpu_wq, cpu));
unlock_cpu_hotplug();
}
}
@@ -279,7 +281,7 @@ void fastcall flush_workqueue(struct workqueue_struct *wq)
static struct task_struct *create_workqueue_thread(struct workqueue_struct *wq,
int cpu)
{
- struct cpu_workqueue_struct *cwq = wq->cpu_wq + cpu;
+ struct cpu_workqueue_struct *cwq = per_cpu_ptr(wq->cpu_wq, cpu);
struct task_struct *p;
spin_lock_init(&cwq->lock);
@@ -312,6 +314,7 @@ struct workqueue_struct *__create_workqueue(const char *name,
if (!wq)
return NULL;
+ wq->cpu_wq = alloc_percpu(struct cpu_workqueue_struct);
wq->name = name;
/* We don't need the distraction of CPUs appearing and vanishing. */
lock_cpu_hotplug();
@@ -353,7 +356,7 @@ static void cleanup_workqueue_thread(struct workqueue_struct *wq, int cpu)
unsigned long flags;
struct task_struct *p;
- cwq = wq->cpu_wq + cpu;
+ cwq = per_cpu_ptr(wq->cpu_wq, cpu);
spin_lock_irqsave(&cwq->lock, flags);
p = cwq->thread;
cwq->thread = NULL;
@@ -380,6 +383,7 @@ void destroy_workqueue(struct workqueue_struct *wq)
spin_unlock(&workqueue_lock);
}
unlock_cpu_hotplug();
+ free_percpu(wq->cpu_wq);
kfree(wq);
}
@@ -458,7 +462,7 @@ int current_is_keventd(void)
BUG_ON(!keventd_wq);
- cwq = keventd_wq->cpu_wq + cpu;
+ cwq = per_cpu_ptr(keventd_wq->cpu_wq, cpu);
if (current == cwq->thread)
ret = 1;
@@ -470,7 +474,7 @@ int current_is_keventd(void)
/* Take the work from this (downed) CPU. */
static void take_over_work(struct workqueue_struct *wq, unsigned int cpu)
{
- struct cpu_workqueue_struct *cwq = wq->cpu_wq + cpu;
+ struct cpu_workqueue_struct *cwq = per_cpu_ptr(wq->cpu_wq, cpu);
LIST_HEAD(list);
struct work_struct *work;
@@ -481,7 +485,7 @@ static void take_over_work(struct workqueue_struct *wq, unsigned int cpu)
printk("Taking work for %s\n", wq->name);
work = list_entry(list.next,struct work_struct,entry);
list_del(&work->entry);
- __queue_work(wq->cpu_wq + smp_processor_id(), work);
+ __queue_work(per_cpu_ptr(wq->cpu_wq, smp_processor_id()), work);
}
spin_unlock_irq(&cwq->lock);
}
@@ -508,16 +512,19 @@ static int __devinit workqueue_cpu_callback(struct notifier_block *nfb,
case CPU_ONLINE:
/* Kick off worker threads. */
list_for_each_entry(wq, &workqueues, list) {
- kthread_bind(wq->cpu_wq[hotcpu].thread, hotcpu);
- wake_up_process(wq->cpu_wq[hotcpu].thread);
+ struct cpu_workqueue_struct *cwq;
+
+ cwq = per_cpu_ptr(wq->cpu_wq, hotcpu);
+ kthread_bind(cwq->thread, hotcpu);
+ wake_up_process(cwq->thread);
}
break;
case CPU_UP_CANCELED:
list_for_each_entry(wq, &workqueues, list) {
/* Unbind so it can run. */
- kthread_bind(wq->cpu_wq[hotcpu].thread,
- smp_processor_id());
+ kthread_bind(per_cpu_ptr(wq->cpu_wq, hotcpu)->thread,
+ any_online_cpu(cpu_online_map));
cleanup_workqueue_thread(wq, hotcpu);
}
break;
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 016e89a44ac8..156822e3cc79 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -128,7 +128,7 @@ config DEBUG_HIGHMEM
config DEBUG_BUGVERBOSE
bool "Verbose BUG() reporting (adds 70K)" if DEBUG_KERNEL && EMBEDDED
depends on BUG
- depends on ARM || ARM26 || M32R || M68K || SPARC32 || SPARC64 || (X86 && !X86_64) || FRV
+ depends on ARM || ARM26 || M32R || M68K || SPARC32 || SPARC64 || X86_32 || FRV
default !EMBEDDED
help
Say Y here to make BUG() panics output the file name and line number
@@ -168,13 +168,34 @@ config DEBUG_FS
If unsure, say N.
+config DEBUG_VM
+ bool "Debug VM"
+ depends on DEBUG_KERNEL
+ help
+ Enable this to debug the virtual-memory system.
+
+ If unsure, say N.
+
config FRAME_POINTER
bool "Compile the kernel with frame pointers"
depends on DEBUG_KERNEL && (X86 || CRIS || M68K || M68KNOMMU || FRV || UML)
default y if DEBUG_INFO && UML
help
If you say Y here the resulting kernel image will be slightly larger
- and slower, but it might give very useful debugging information
- on some architectures or you use external debuggers.
+ and slower, but it might give very useful debugging information on
+ some architectures or if you use external debuggers.
If you don't debug the kernel, you can say N.
+config RCU_TORTURE_TEST
+ tristate "torture tests for RCU"
+ depends on DEBUG_KERNEL
+ default n
+ help
+ This option provides a kernel module that runs torture tests
+ on the RCU infrastructure. The kernel module may be built
+ after the fact on the running kernel to be tested, if desired.
+
+ Say Y here if you want RCU torture tests to start automatically
+ at boot time (you probably don't).
+ Say M if you want the RCU torture tests to build as a module.
+ Say N if you are unsure.
diff --git a/lib/Makefile b/lib/Makefile
index 44a46750690a..8535f4d7d1c3 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -44,6 +44,8 @@ obj-$(CONFIG_TEXTSEARCH_KMP) += ts_kmp.o
obj-$(CONFIG_TEXTSEARCH_BM) += ts_bm.o
obj-$(CONFIG_TEXTSEARCH_FSM) += ts_fsm.o
+obj-$(CONFIG_SWIOTLB) += swiotlb.o
+
hostprogs-y := gen_crc32table
clean-files := crc32table.h
diff --git a/lib/bitmap.c b/lib/bitmap.c
index fb9371fdd44a..23d3b1147fe9 100644
--- a/lib/bitmap.c
+++ b/lib/bitmap.c
@@ -511,6 +511,172 @@ int bitmap_parselist(const char *bp, unsigned long *maskp, int nmaskbits)
}
EXPORT_SYMBOL(bitmap_parselist);
+/*
+ * bitmap_pos_to_ord(buf, pos, bits)
+ * @buf: pointer to a bitmap
+ * @pos: a bit position in @buf (0 <= @pos < @bits)
+ * @bits: number of valid bit positions in @buf
+ *
+ * Map the bit at position @pos in @buf (of length @bits) to the
+ * ordinal of which set bit it is. If it is not set or if @pos
+ * is not a valid bit position, map to zero (0).
+ *
+ * If for example, just bits 4 through 7 are set in @buf, then @pos
+ * values 4 through 7 will get mapped to 0 through 3, respectively,
+ * and other @pos values will get mapped to 0. When @pos value 7
+ * gets mapped to (returns) @ord value 3 in this example, that means
+ * that bit 7 is the 3rd (starting with 0th) set bit in @buf.
+ *
+ * The bit positions 0 through @bits are valid positions in @buf.
+ */
+static int bitmap_pos_to_ord(const unsigned long *buf, int pos, int bits)
+{
+ int ord = 0;
+
+ if (pos >= 0 && pos < bits) {
+ int i;
+
+ for (i = find_first_bit(buf, bits);
+ i < pos;
+ i = find_next_bit(buf, bits, i + 1))
+ ord++;
+ if (i > pos)
+ ord = 0;
+ }
+ return ord;
+}
+
+/**
+ * bitmap_ord_to_pos(buf, ord, bits)
+ * @buf: pointer to bitmap
+ * @ord: ordinal bit position (n-th set bit, n >= 0)
+ * @bits: number of valid bit positions in @buf
+ *
+ * Map the ordinal offset of bit @ord in @buf to its position in @buf.
+ * If @ord is not the ordinal offset of a set bit in @buf, map to zero (0).
+ *
+ * If for example, just bits 4 through 7 are set in @buf, then @ord
+ * values 0 through 3 will get mapped to 4 through 7, respectively,
+ * and all other @ord valuds will get mapped to 0. When @ord value 3
+ * gets mapped to (returns) @pos value 7 in this example, that means
+ * that the 3rd set bit (starting with 0th) is at position 7 in @buf.
+ *
+ * The bit positions 0 through @bits are valid positions in @buf.
+ */
+static int bitmap_ord_to_pos(const unsigned long *buf, int ord, int bits)
+{
+ int pos = 0;
+
+ if (ord >= 0 && ord < bits) {
+ int i;
+
+ for (i = find_first_bit(buf, bits);
+ i < bits && ord > 0;
+ i = find_next_bit(buf, bits, i + 1))
+ ord--;
+ if (i < bits && ord == 0)
+ pos = i;
+ }
+
+ return pos;
+}
+
+/**
+ * bitmap_remap - Apply map defined by a pair of bitmaps to another bitmap
+ * @src: subset to be remapped
+ * @dst: remapped result
+ * @old: defines domain of map
+ * @new: defines range of map
+ * @bits: number of bits in each of these bitmaps
+ *
+ * Let @old and @new define a mapping of bit positions, such that
+ * whatever position is held by the n-th set bit in @old is mapped
+ * to the n-th set bit in @new. In the more general case, allowing
+ * for the possibility that the weight 'w' of @new is less than the
+ * weight of @old, map the position of the n-th set bit in @old to
+ * the position of the m-th set bit in @new, where m == n % w.
+ *
+ * If either of the @old and @new bitmaps are empty, or if@src and @dst
+ * point to the same location, then this routine does nothing.
+ *
+ * The positions of unset bits in @old are mapped to the position of
+ * the first set bit in @new.
+ *
+ * Apply the above specified mapping to @src, placing the result in
+ * @dst, clearing any bits previously set in @dst.
+ *
+ * The resulting value of @dst will have either the same weight as
+ * @src, or less weight in the general case that the mapping wasn't
+ * injective due to the weight of @new being less than that of @old.
+ * The resulting value of @dst will never have greater weight than
+ * that of @src, except perhaps in the case that one of the above
+ * conditions was not met and this routine just returned.
+ *
+ * For example, lets say that @old has bits 4 through 7 set, and
+ * @new has bits 12 through 15 set. This defines the mapping of bit
+ * position 4 to 12, 5 to 13, 6 to 14 and 7 to 15, and of all other
+ * bit positions to 12 (the first set bit in @new. So if say @src
+ * comes into this routine with bits 1, 5 and 7 set, then @dst should
+ * leave with bits 12, 13 and 15 set.
+ */
+void bitmap_remap(unsigned long *dst, const unsigned long *src,
+ const unsigned long *old, const unsigned long *new,
+ int bits)
+{
+ int s;
+
+ if (bitmap_weight(old, bits) == 0)
+ return;
+ if (bitmap_weight(new, bits) == 0)
+ return;
+ if (dst == src) /* following doesn't handle inplace remaps */
+ return;
+
+ bitmap_zero(dst, bits);
+ for (s = find_first_bit(src, bits);
+ s < bits;
+ s = find_next_bit(src, bits, s + 1)) {
+ int x = bitmap_pos_to_ord(old, s, bits);
+ int y = bitmap_ord_to_pos(new, x, bits);
+ set_bit(y, dst);
+ }
+}
+EXPORT_SYMBOL(bitmap_remap);
+
+/**
+ * bitmap_bitremap - Apply map defined by a pair of bitmaps to a single bit
+ * @oldbit - bit position to be mapped
+ * @old: defines domain of map
+ * @new: defines range of map
+ * @bits: number of bits in each of these bitmaps
+ *
+ * Let @old and @new define a mapping of bit positions, such that
+ * whatever position is held by the n-th set bit in @old is mapped
+ * to the n-th set bit in @new. In the more general case, allowing
+ * for the possibility that the weight 'w' of @new is less than the
+ * weight of @old, map the position of the n-th set bit in @old to
+ * the position of the m-th set bit in @new, where m == n % w.
+ *
+ * The positions of unset bits in @old are mapped to the position of
+ * the first set bit in @new.
+ *
+ * Apply the above specified mapping to bit position @oldbit, returning
+ * the new bit position.
+ *
+ * For example, lets say that @old has bits 4 through 7 set, and
+ * @new has bits 12 through 15 set. This defines the mapping of bit
+ * position 4 to 12, 5 to 13, 6 to 14 and 7 to 15, and of all other
+ * bit positions to 12 (the first set bit in @new. So if say @oldbit
+ * is 5, then this routine returns 13.
+ */
+int bitmap_bitremap(int oldbit, const unsigned long *old,
+ const unsigned long *new, int bits)
+{
+ int x = bitmap_pos_to_ord(old, oldbit, bits);
+ return bitmap_ord_to_pos(new, x, bits);
+}
+EXPORT_SYMBOL(bitmap_bitremap);
+
/**
* bitmap_find_free_region - find a contiguous aligned mem region
* @bitmap: an array of unsigned longs corresponding to the bitmap
diff --git a/lib/extable.c b/lib/extable.c
index 3f677a8f0c3c..18df57c029df 100644
--- a/lib/extable.c
+++ b/lib/extable.c
@@ -16,9 +16,6 @@
#include <linux/sort.h>
#include <asm/uaccess.h>
-extern struct exception_table_entry __start___ex_table[];
-extern struct exception_table_entry __stop___ex_table[];
-
#ifndef ARCH_HAS_SORT_EXTABLE
/*
* The exception table needs to be sorted so that the binary
diff --git a/lib/idr.c b/lib/idr.c
index d4df21debc4d..d226259c3c28 100644
--- a/lib/idr.c
+++ b/lib/idr.c
@@ -6,20 +6,20 @@
* Modified by George Anzinger to reuse immediately and to use
* find bit instructions. Also removed _irq on spinlocks.
*
- * Small id to pointer translation service.
+ * Small id to pointer translation service.
*
- * It uses a radix tree like structure as a sparse array indexed
+ * It uses a radix tree like structure as a sparse array indexed
* by the id to obtain the pointer. The bitmap makes allocating
- * a new id quick.
+ * a new id quick.
*
* You call it to allocate an id (an int) an associate with that id a
* pointer or what ever, we treat it as a (void *). You can pass this
* id to a user for him to pass back at a later time. You then pass
* that id to this code and it returns your pointer.
- * You can release ids at any time. When all ids are released, most of
+ * You can release ids at any time. When all ids are released, most of
* the memory is returned (we keep IDR_FREE_MAX) in a local pool so we
- * don't need to go to the memory "store" during an id allocate, just
+ * don't need to go to the memory "store" during an id allocate, just
* so you don't need to be too concerned about locking and conflicts
* with the slab allocator.
*/
@@ -72,12 +72,12 @@ static void free_layer(struct idr *idp, struct idr_layer *p)
* If the system is REALLY out of memory this function returns 0,
* otherwise 1.
*/
-int idr_pre_get(struct idr *idp, unsigned gfp_mask)
+int idr_pre_get(struct idr *idp, gfp_t gfp_mask)
{
while (idp->id_free_cnt < IDR_FREE_MAX) {
struct idr_layer *new;
new = kmem_cache_alloc(idr_layer_cache, gfp_mask);
- if(new == NULL)
+ if (new == NULL)
return (0);
free_layer(idp, new);
}
@@ -107,7 +107,7 @@ static int sub_alloc(struct idr *idp, void *ptr, int *starting_id)
if (m == IDR_SIZE) {
/* no space available go back to previous layer. */
l++;
- id = (id | ((1 << (IDR_BITS*l))-1)) + 1;
+ id = (id | ((1 << (IDR_BITS * l)) - 1)) + 1;
if (!(p = pa[l])) {
*starting_id = id;
return -2;
@@ -161,7 +161,7 @@ static int idr_get_new_above_int(struct idr *idp, void *ptr, int starting_id)
{
struct idr_layer *p, *new;
int layers, v, id;
-
+
id = starting_id;
build_up:
p = idp->top;
@@ -225,6 +225,7 @@ build_up:
int idr_get_new_above(struct idr *idp, void *ptr, int starting_id, int *id)
{
int rv;
+
rv = idr_get_new_above_int(idp, ptr, starting_id);
/*
* This is a cheap hack until the IDR code can be fixed to
@@ -259,6 +260,7 @@ EXPORT_SYMBOL(idr_get_new_above);
int idr_get_new(struct idr *idp, void *ptr, int *id)
{
int rv;
+
rv = idr_get_new_above_int(idp, ptr, 0);
/*
* This is a cheap hack until the IDR code can be fixed to
@@ -306,11 +308,10 @@ static void sub_remove(struct idr *idp, int shift, int id)
free_layer(idp, **paa);
**paa-- = NULL;
}
- if ( ! *paa )
+ if (!*paa)
idp->layers = 0;
- } else {
+ } else
idr_remove_warning(id);
- }
}
/**
@@ -326,9 +327,8 @@ void idr_remove(struct idr *idp, int id)
id &= MAX_ID_MASK;
sub_remove(idp, (idp->layers - 1) * IDR_BITS, id);
- if ( idp->top && idp->top->count == 1 &&
- (idp->layers > 1) &&
- idp->top->ary[0]){ // We can drop a layer
+ if (idp->top && idp->top->count == 1 && (idp->layers > 1) &&
+ idp->top->ary[0]) { // We can drop a layer
p = idp->top->ary[0];
idp->top->bitmap = idp->top->count = 0;
@@ -337,7 +337,6 @@ void idr_remove(struct idr *idp, int id)
--idp->layers;
}
while (idp->id_free_cnt >= IDR_FREE_MAX) {
-
p = alloc_layer(idp);
kmem_cache_free(idr_layer_cache, p);
return;
@@ -391,8 +390,8 @@ void *idr_find(struct idr *idp, int id)
}
EXPORT_SYMBOL(idr_find);
-static void idr_cache_ctor(void * idr_layer,
- kmem_cache_t *idr_layer_cache, unsigned long flags)
+static void idr_cache_ctor(void * idr_layer, kmem_cache_t *idr_layer_cache,
+ unsigned long flags)
{
memset(idr_layer, 0, sizeof(struct idr_layer));
}
@@ -400,7 +399,7 @@ static void idr_cache_ctor(void * idr_layer,
static int init_id_cache(void)
{
if (!idr_layer_cache)
- idr_layer_cache = kmem_cache_create("idr_layer_cache",
+ idr_layer_cache = kmem_cache_create("idr_layer_cache",
sizeof(struct idr_layer), 0, 0, idr_cache_ctor, NULL);
return 0;
}
diff --git a/lib/kobject.c b/lib/kobject.c
index dd0917dd9fa9..a181abed89f6 100644
--- a/lib/kobject.c
+++ b/lib/kobject.c
@@ -14,6 +14,7 @@
#include <linux/string.h>
#include <linux/module.h>
#include <linux/stat.h>
+#include <linux/slab.h>
/**
* populate_dir - populate directory with attributes.
@@ -100,7 +101,7 @@ static void fill_kobj_path(struct kobject *kobj, char *path, int length)
* @kobj: kobject in question, with which to build the path
* @gfp_mask: the allocation type used to allocate the path
*/
-char *kobject_get_path(struct kobject *kobj, int gfp_mask)
+char *kobject_get_path(struct kobject *kobj, gfp_t gfp_mask)
{
char *path;
int len;
diff --git a/lib/kobject_uevent.c b/lib/kobject_uevent.c
index 04ca4429ddfa..3ab375411e38 100644
--- a/lib/kobject_uevent.c
+++ b/lib/kobject_uevent.c
@@ -54,7 +54,7 @@ static char *action_to_string(enum kobject_action action)
static struct sock *uevent_sock;
/**
- * send_uevent - notify userspace by sending event trough netlink socket
+ * send_uevent - notify userspace by sending event through netlink socket
*
* @signal: signal name
* @obj: object path (kobject)
@@ -62,7 +62,7 @@ static struct sock *uevent_sock;
* @gfp_mask:
*/
static int send_uevent(const char *signal, const char *obj,
- char **envp, int gfp_mask)
+ char **envp, gfp_t gfp_mask)
{
struct sk_buff *skb;
char *pos;
@@ -98,7 +98,7 @@ static int send_uevent(const char *signal, const char *obj,
}
static int do_kobject_uevent(struct kobject *kobj, enum kobject_action action,
- struct attribute *attr, int gfp_mask)
+ struct attribute *attr, gfp_t gfp_mask)
{
char *path;
char *attrpath;
diff --git a/lib/radix-tree.c b/lib/radix-tree.c
index d1c057e71b68..88511c3805ad 100644
--- a/lib/radix-tree.c
+++ b/lib/radix-tree.c
@@ -281,35 +281,60 @@ int radix_tree_insert(struct radix_tree_root *root,
}
EXPORT_SYMBOL(radix_tree_insert);
-/**
- * radix_tree_lookup - perform lookup operation on a radix tree
- * @root: radix tree root
- * @index: index key
- *
- * Lookup the item at the position @index in the radix tree @root.
- */
-void *radix_tree_lookup(struct radix_tree_root *root, unsigned long index)
+static inline void **__lookup_slot(struct radix_tree_root *root,
+ unsigned long index)
{
unsigned int height, shift;
- struct radix_tree_node *slot;
+ struct radix_tree_node **slot;
height = root->height;
if (index > radix_tree_maxindex(height))
return NULL;
shift = (height-1) * RADIX_TREE_MAP_SHIFT;
- slot = root->rnode;
+ slot = &root->rnode;
while (height > 0) {
- if (slot == NULL)
+ if (*slot == NULL)
return NULL;
- slot = slot->slots[(index >> shift) & RADIX_TREE_MAP_MASK];
+ slot = (struct radix_tree_node **)
+ ((*slot)->slots +
+ ((index >> shift) & RADIX_TREE_MAP_MASK));
shift -= RADIX_TREE_MAP_SHIFT;
height--;
}
- return slot;
+ return (void **)slot;
+}
+
+/**
+ * radix_tree_lookup_slot - lookup a slot in a radix tree
+ * @root: radix tree root
+ * @index: index key
+ *
+ * Lookup the slot corresponding to the position @index in the radix tree
+ * @root. This is useful for update-if-exists operations.
+ */
+void **radix_tree_lookup_slot(struct radix_tree_root *root, unsigned long index)
+{
+ return __lookup_slot(root, index);
+}
+EXPORT_SYMBOL(radix_tree_lookup_slot);
+
+/**
+ * radix_tree_lookup - perform lookup operation on a radix tree
+ * @root: radix tree root
+ * @index: index key
+ *
+ * Lookup the item at the position @index in the radix tree @root.
+ */
+void *radix_tree_lookup(struct radix_tree_root *root, unsigned long index)
+{
+ void **slot;
+
+ slot = __lookup_slot(root, index);
+ return slot != NULL ? *slot : NULL;
}
EXPORT_SYMBOL(radix_tree_lookup);
diff --git a/lib/reed_solomon/Makefile b/lib/reed_solomon/Makefile
index 747a2de29346..c3d7136827ed 100644
--- a/lib/reed_solomon/Makefile
+++ b/lib/reed_solomon/Makefile
@@ -1,5 +1,5 @@
#
-# This is a modified version of reed solomon lib,
+# This is a modified version of reed solomon lib,
#
obj-$(CONFIG_REED_SOLOMON) += reed_solomon.o
diff --git a/lib/reed_solomon/decode_rs.c b/lib/reed_solomon/decode_rs.c
index d401decd6289..a58df56f09b6 100644
--- a/lib/reed_solomon/decode_rs.c
+++ b/lib/reed_solomon/decode_rs.c
@@ -1,22 +1,22 @@
-/*
+/*
* lib/reed_solomon/decode_rs.c
*
* Overview:
* Generic Reed Solomon encoder / decoder library
- *
+ *
* Copyright 2002, Phil Karn, KA9Q
* May be used under the terms of the GNU General Public License (GPL)
*
* Adaption to the kernel by Thomas Gleixner (tglx@linutronix.de)
*
- * $Id: decode_rs.c,v 1.6 2004/10/22 15:41:47 gleixner Exp $
+ * $Id: decode_rs.c,v 1.7 2005/11/07 11:14:59 gleixner Exp $
*
*/
-/* Generic data width independent code which is included by the
+/* Generic data width independent code which is included by the
* wrappers.
*/
-{
+{
int deg_lambda, el, deg_omega;
int i, j, r, k, pad;
int nn = rs->nn;
@@ -41,9 +41,9 @@
pad = nn - nroots - len;
if (pad < 0 || pad >= nn)
return -ERANGE;
-
+
/* Does the caller provide the syndrome ? */
- if (s != NULL)
+ if (s != NULL)
goto decode;
/* form the syndromes; i.e., evaluate data(x) at roots of
@@ -54,11 +54,11 @@
for (j = 1; j < len; j++) {
for (i = 0; i < nroots; i++) {
if (syn[i] == 0) {
- syn[i] = (((uint16_t) data[j]) ^
+ syn[i] = (((uint16_t) data[j]) ^
invmsk) & msk;
} else {
syn[i] = ((((uint16_t) data[j]) ^
- invmsk) & msk) ^
+ invmsk) & msk) ^
alpha_to[rs_modnn(rs, index_of[syn[i]] +
(fcr + i) * prim)];
}
@@ -70,7 +70,7 @@
if (syn[i] == 0) {
syn[i] = ((uint16_t) par[j]) & msk;
} else {
- syn[i] = (((uint16_t) par[j]) & msk) ^
+ syn[i] = (((uint16_t) par[j]) & msk) ^
alpha_to[rs_modnn(rs, index_of[syn[i]] +
(fcr+i)*prim)];
}
@@ -99,14 +99,14 @@
if (no_eras > 0) {
/* Init lambda to be the erasure locator polynomial */
- lambda[1] = alpha_to[rs_modnn(rs,
+ lambda[1] = alpha_to[rs_modnn(rs,
prim * (nn - 1 - eras_pos[0]))];
for (i = 1; i < no_eras; i++) {
u = rs_modnn(rs, prim * (nn - 1 - eras_pos[i]));
for (j = i + 1; j > 0; j--) {
tmp = index_of[lambda[j - 1]];
if (tmp != nn) {
- lambda[j] ^=
+ lambda[j] ^=
alpha_to[rs_modnn(rs, u + tmp)];
}
}
@@ -127,8 +127,8 @@
discr_r = 0;
for (i = 0; i < r; i++) {
if ((lambda[i] != 0) && (s[r - i - 1] != nn)) {
- discr_r ^=
- alpha_to[rs_modnn(rs,
+ discr_r ^=
+ alpha_to[rs_modnn(rs,
index_of[lambda[i]] +
s[r - i - 1])];
}
@@ -143,7 +143,7 @@
t[0] = lambda[0];
for (i = 0; i < nroots; i++) {
if (b[i] != nn) {
- t[i + 1] = lambda[i + 1] ^
+ t[i + 1] = lambda[i + 1] ^
alpha_to[rs_modnn(rs, discr_r +
b[i])];
} else
@@ -229,7 +229,7 @@
num1 = 0;
for (i = deg_omega; i >= 0; i--) {
if (omega[i] != nn)
- num1 ^= alpha_to[rs_modnn(rs, omega[i] +
+ num1 ^= alpha_to[rs_modnn(rs, omega[i] +
i * root[j])];
}
num2 = alpha_to[rs_modnn(rs, root[j] * (fcr - 1) + nn)];
@@ -239,13 +239,13 @@
* lambda_pr of lambda[i] */
for (i = min(deg_lambda, nroots - 1) & ~1; i >= 0; i -= 2) {
if (lambda[i + 1] != nn) {
- den ^= alpha_to[rs_modnn(rs, lambda[i + 1] +
+ den ^= alpha_to[rs_modnn(rs, lambda[i + 1] +
i * root[j])];
}
}
/* Apply error to data */
if (num1 != 0 && loc[j] >= pad) {
- uint16_t cor = alpha_to[rs_modnn(rs,index_of[num1] +
+ uint16_t cor = alpha_to[rs_modnn(rs,index_of[num1] +
index_of[num2] +
nn - index_of[den])];
/* Store the error correction pattern, if a
diff --git a/lib/reed_solomon/encode_rs.c b/lib/reed_solomon/encode_rs.c
index 237bf65ae886..0b5b1a6728ec 100644
--- a/lib/reed_solomon/encode_rs.c
+++ b/lib/reed_solomon/encode_rs.c
@@ -1,19 +1,19 @@
-/*
+/*
* lib/reed_solomon/encode_rs.c
*
* Overview:
* Generic Reed Solomon encoder / decoder library
- *
+ *
* Copyright 2002, Phil Karn, KA9Q
* May be used under the terms of the GNU General Public License (GPL)
*
* Adaption to the kernel by Thomas Gleixner (tglx@linutronix.de)
*
- * $Id: encode_rs.c,v 1.4 2004/10/22 15:41:47 gleixner Exp $
+ * $Id: encode_rs.c,v 1.5 2005/11/07 11:14:59 gleixner Exp $
*
*/
-/* Generic data width independent code which is included by the
+/* Generic data width independent code which is included by the
* wrappers.
* int encode_rsX (struct rs_control *rs, uintX_t *data, int len, uintY_t *par)
*/
@@ -35,16 +35,16 @@
for (i = 0; i < len; i++) {
fb = index_of[((((uint16_t) data[i])^invmsk) & msk) ^ par[0]];
/* feedback term is non-zero */
- if (fb != nn) {
+ if (fb != nn) {
for (j = 1; j < nroots; j++) {
- par[j] ^= alpha_to[rs_modnn(rs, fb +
+ par[j] ^= alpha_to[rs_modnn(rs, fb +
genpoly[nroots - j])];
}
}
/* Shift */
memmove(&par[0], &par[1], sizeof(uint16_t) * (nroots - 1));
if (fb != nn) {
- par[nroots - 1] = alpha_to[rs_modnn(rs,
+ par[nroots - 1] = alpha_to[rs_modnn(rs,
fb + genpoly[0])];
} else {
par[nroots - 1] = 0;
diff --git a/lib/reed_solomon/reed_solomon.c b/lib/reed_solomon/reed_solomon.c
index 6604e3b1940c..f5fef948a415 100644
--- a/lib/reed_solomon/reed_solomon.c
+++ b/lib/reed_solomon/reed_solomon.c
@@ -1,22 +1,22 @@
-/*
+/*
* lib/reed_solomon/rslib.c
*
* Overview:
* Generic Reed Solomon encoder / decoder library
- *
+ *
* Copyright (C) 2004 Thomas Gleixner (tglx@linutronix.de)
*
* Reed Solomon code lifted from reed solomon library written by Phil Karn
* Copyright 2002 Phil Karn, KA9Q
*
- * $Id: rslib.c,v 1.5 2004/10/22 15:41:47 gleixner Exp $
+ * $Id: rslib.c,v 1.7 2005/11/07 11:14:59 gleixner Exp $
*
* 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.
*
* Description:
- *
+ *
* The generic Reed Solomon library provides runtime configurable
* encoding / decoding of RS codes.
* Each user must call init_rs to get a pointer to a rs_control
@@ -25,11 +25,11 @@
* If a structure is generated then the polynomial arrays for
* fast encoding / decoding are built. This can take some time so
* make sure not to call this function from a time critical path.
- * Usually a module / driver should initialize the necessary
+ * Usually a module / driver should initialize the necessary
* rs_control structure on module / driver init and release it
* on exit.
- * The encoding puts the calculated syndrome into a given syndrome
- * buffer.
+ * The encoding puts the calculated syndrome into a given syndrome
+ * buffer.
* The decoding is a two step process. The first step calculates
* the syndrome over the received (data + syndrome) and calls the
* second stage, which does the decoding / error correction itself.
@@ -51,7 +51,7 @@ static LIST_HEAD (rslist);
/* Protection for the list */
static DECLARE_MUTEX(rslistlock);
-/**
+/**
* rs_init - Initialize a Reed-Solomon codec
*
* @symsize: symbol size, bits (1-8)
@@ -63,7 +63,7 @@ static DECLARE_MUTEX(rslistlock);
* Allocate a control structure and the polynom arrays for faster
* en/decoding. Fill the arrays according to the given parameters
*/
-static struct rs_control *rs_init(int symsize, int gfpoly, int fcr,
+static struct rs_control *rs_init(int symsize, int gfpoly, int fcr,
int prim, int nroots)
{
struct rs_control *rs;
@@ -124,15 +124,15 @@ static struct rs_control *rs_init(int symsize, int gfpoly, int fcr,
/* Multiply rs->genpoly[] by @**(root + x) */
for (j = i; j > 0; j--) {
if (rs->genpoly[j] != 0) {
- rs->genpoly[j] = rs->genpoly[j -1] ^
- rs->alpha_to[rs_modnn(rs,
+ rs->genpoly[j] = rs->genpoly[j -1] ^
+ rs->alpha_to[rs_modnn(rs,
rs->index_of[rs->genpoly[j]] + root)];
} else
rs->genpoly[j] = rs->genpoly[j - 1];
}
/* rs->genpoly[0] can never be zero */
- rs->genpoly[0] =
- rs->alpha_to[rs_modnn(rs,
+ rs->genpoly[0] =
+ rs->alpha_to[rs_modnn(rs,
rs->index_of[rs->genpoly[0]] + root)];
}
/* convert rs->genpoly[] to index form for quicker encoding */
@@ -153,7 +153,7 @@ errrs:
}
-/**
+/**
* free_rs - Free the rs control structure, if its not longer used
*
* @rs: the control structure which is not longer used by the
@@ -173,19 +173,19 @@ void free_rs(struct rs_control *rs)
up(&rslistlock);
}
-/**
+/**
* init_rs - Find a matching or allocate a new rs control structure
*
* @symsize: the symbol size (number of bits)
* @gfpoly: the extended Galois field generator polynomial coefficients,
* with the 0th coefficient in the low order bit. The polynomial
* must be primitive;
- * @fcr: the first consecutive root of the rs code generator polynomial
+ * @fcr: the first consecutive root of the rs code generator polynomial
* in index form
* @prim: primitive element to generate polynomial roots
* @nroots: RS code generator polynomial degree (number of roots)
*/
-struct rs_control *init_rs(int symsize, int gfpoly, int fcr, int prim,
+struct rs_control *init_rs(int symsize, int gfpoly, int fcr, int prim,
int nroots)
{
struct list_head *tmp;
@@ -198,9 +198,9 @@ struct rs_control *init_rs(int symsize, int gfpoly, int fcr, int prim,
return NULL;
if (prim <= 0 || prim >= (1<<symsize))
return NULL;
- if (nroots < 0 || nroots >= (1<<symsize) || nroots > 8)
+ if (nroots < 0 || nroots >= (1<<symsize))
return NULL;
-
+
down(&rslistlock);
/* Walk through the list and look for a matching entry */
@@ -211,9 +211,9 @@ struct rs_control *init_rs(int symsize, int gfpoly, int fcr, int prim,
if (gfpoly != rs->gfpoly)
continue;
if (fcr != rs->fcr)
- continue;
+ continue;
if (prim != rs->prim)
- continue;
+ continue;
if (nroots != rs->nroots)
continue;
/* We have a matching one already */
@@ -227,18 +227,18 @@ struct rs_control *init_rs(int symsize, int gfpoly, int fcr, int prim,
rs->users = 1;
list_add(&rs->list, &rslist);
}
-out:
+out:
up(&rslistlock);
return rs;
}
#ifdef CONFIG_REED_SOLOMON_ENC8
-/**
+/**
* encode_rs8 - Calculate the parity for data values (8bit data width)
*
* @rs: the rs control structure
* @data: data field of a given type
- * @len: data length
+ * @len: data length
* @par: parity data, must be initialized by caller (usually all 0)
* @invmsk: invert data mask (will be xored on data)
*
@@ -246,7 +246,7 @@ out:
* symbol size > 8. The calling code must take care of encoding of the
* syndrome result for storage itself.
*/
-int encode_rs8(struct rs_control *rs, uint8_t *data, int len, uint16_t *par,
+int encode_rs8(struct rs_control *rs, uint8_t *data, int len, uint16_t *par,
uint16_t invmsk)
{
#include "encode_rs.c"
@@ -255,7 +255,7 @@ EXPORT_SYMBOL_GPL(encode_rs8);
#endif
#ifdef CONFIG_REED_SOLOMON_DEC8
-/**
+/**
* decode_rs8 - Decode codeword (8bit data width)
*
* @rs: the rs control structure
@@ -273,7 +273,7 @@ EXPORT_SYMBOL_GPL(encode_rs8);
* syndrome result and the received parity before calling this code.
*/
int decode_rs8(struct rs_control *rs, uint8_t *data, uint16_t *par, int len,
- uint16_t *s, int no_eras, int *eras_pos, uint16_t invmsk,
+ uint16_t *s, int no_eras, int *eras_pos, uint16_t invmsk,
uint16_t *corr)
{
#include "decode_rs.c"
@@ -287,13 +287,13 @@ EXPORT_SYMBOL_GPL(decode_rs8);
*
* @rs: the rs control structure
* @data: data field of a given type
- * @len: data length
+ * @len: data length
* @par: parity data, must be initialized by caller (usually all 0)
* @invmsk: invert data mask (will be xored on data, not on parity!)
*
* Each field in the data array contains up to symbol size bits of valid data.
*/
-int encode_rs16(struct rs_control *rs, uint16_t *data, int len, uint16_t *par,
+int encode_rs16(struct rs_control *rs, uint16_t *data, int len, uint16_t *par,
uint16_t invmsk)
{
#include "encode_rs.c"
@@ -302,7 +302,7 @@ EXPORT_SYMBOL_GPL(encode_rs16);
#endif
#ifdef CONFIG_REED_SOLOMON_DEC16
-/**
+/**
* decode_rs16 - Decode codeword (16bit data width)
*
* @rs: the rs control structure
@@ -312,13 +312,13 @@ EXPORT_SYMBOL_GPL(encode_rs16);
* @s: syndrome data field (if NULL, syndrome is calculated)
* @no_eras: number of erasures
* @eras_pos: position of erasures, can be NULL
- * @invmsk: invert data mask (will be xored on data, not on parity!)
+ * @invmsk: invert data mask (will be xored on data, not on parity!)
* @corr: buffer to store correction bitmask on eras_pos
*
* Each field in the data array contains up to symbol size bits of valid data.
*/
int decode_rs16(struct rs_control *rs, uint16_t *data, uint16_t *par, int len,
- uint16_t *s, int no_eras, int *eras_pos, uint16_t invmsk,
+ uint16_t *s, int no_eras, int *eras_pos, uint16_t invmsk,
uint16_t *corr)
{
#include "decode_rs.c"
diff --git a/lib/smp_processor_id.c b/lib/smp_processor_id.c
index 42c08ef828c5..eddc9b3d3876 100644
--- a/lib/smp_processor_id.c
+++ b/lib/smp_processor_id.c
@@ -5,6 +5,7 @@
*/
#include <linux/module.h>
#include <linux/kallsyms.h>
+#include <linux/sched.h>
unsigned int debug_smp_processor_id(void)
{
diff --git a/lib/sort.c b/lib/sort.c
index ddc4d35df289..5f3b51ffa1dc 100644
--- a/lib/sort.c
+++ b/lib/sort.c
@@ -7,6 +7,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/sort.h>
+#include <linux/slab.h>
static void u32_swap(void *a, void *b, int size)
{
diff --git a/lib/string.c b/lib/string.c
index d886ef157c12..037a48acedbb 100644
--- a/lib/string.c
+++ b/lib/string.c
@@ -36,11 +36,13 @@ int strnicmp(const char *s1, const char *s2, size_t len)
/* Yes, Virginia, it had better be unsigned */
unsigned char c1, c2;
- c1 = 0; c2 = 0;
+ c1 = c2 = 0;
if (len) {
do {
- c1 = *s1; c2 = *s2;
- s1++; s2++;
+ c1 = *s1;
+ c2 = *s2;
+ s1++;
+ s2++;
if (!c1)
break;
if (!c2)
@@ -55,7 +57,6 @@ int strnicmp(const char *s1, const char *s2, size_t len)
}
return (int)c1 - (int)c2;
}
-
EXPORT_SYMBOL(strnicmp);
#endif
@@ -66,7 +67,7 @@ EXPORT_SYMBOL(strnicmp);
* @src: Where to copy the string from
*/
#undef strcpy
-char * strcpy(char * dest,const char *src)
+char *strcpy(char *dest, const char *src)
{
char *tmp = dest;
@@ -91,12 +92,13 @@ EXPORT_SYMBOL(strcpy);
* count, the remainder of @dest will be padded with %NUL.
*
*/
-char * strncpy(char * dest,const char *src,size_t count)
+char *strncpy(char *dest, const char *src, size_t count)
{
char *tmp = dest;
while (count) {
- if ((*tmp = *src) != 0) src++;
+ if ((*tmp = *src) != 0)
+ src++;
tmp++;
count--;
}
@@ -122,7 +124,7 @@ size_t strlcpy(char *dest, const char *src, size_t size)
size_t ret = strlen(src);
if (size) {
- size_t len = (ret >= size) ? size-1 : ret;
+ size_t len = (ret >= size) ? size - 1 : ret;
memcpy(dest, src, len);
dest[len] = '\0';
}
@@ -138,7 +140,7 @@ EXPORT_SYMBOL(strlcpy);
* @src: The string to append to it
*/
#undef strcat
-char * strcat(char * dest, const char * src)
+char *strcat(char *dest, const char *src)
{
char *tmp = dest;
@@ -146,7 +148,6 @@ char * strcat(char * dest, const char * src)
dest++;
while ((*dest++ = *src++) != '\0')
;
-
return tmp;
}
EXPORT_SYMBOL(strcat);
@@ -162,7 +163,7 @@ EXPORT_SYMBOL(strcat);
* Note that in contrast to strncpy, strncat ensures the result is
* terminated.
*/
-char * strncat(char *dest, const char *src, size_t count)
+char *strncat(char *dest, const char *src, size_t count)
{
char *tmp = dest;
@@ -176,7 +177,6 @@ char * strncat(char *dest, const char *src, size_t count)
}
}
}
-
return tmp;
}
EXPORT_SYMBOL(strncat);
@@ -216,15 +216,14 @@ EXPORT_SYMBOL(strlcat);
* @ct: Another string
*/
#undef strcmp
-int strcmp(const char * cs,const char * ct)
+int strcmp(const char *cs, const char *ct)
{
- register signed char __res;
+ signed char __res;
while (1) {
if ((__res = *cs - *ct++) != 0 || !*cs++)
break;
}
-
return __res;
}
EXPORT_SYMBOL(strcmp);
@@ -237,16 +236,15 @@ EXPORT_SYMBOL(strcmp);
* @ct: Another string
* @count: The maximum number of bytes to compare
*/
-int strncmp(const char * cs,const char * ct,size_t count)
+int strncmp(const char *cs, const char *ct, size_t count)
{
- register signed char __res = 0;
+ signed char __res = 0;
while (count) {
if ((__res = *cs - *ct++) != 0 || !*cs++)
break;
count--;
}
-
return __res;
}
EXPORT_SYMBOL(strncmp);
@@ -258,12 +256,12 @@ EXPORT_SYMBOL(strncmp);
* @s: The string to be searched
* @c: The character to search for
*/
-char * strchr(const char * s, int c)
+char *strchr(const char *s, int c)
{
- for(; *s != (char) c; ++s)
+ for (; *s != (char)c; ++s)
if (*s == '\0')
return NULL;
- return (char *) s;
+ return (char *)s;
}
EXPORT_SYMBOL(strchr);
#endif
@@ -274,7 +272,7 @@ EXPORT_SYMBOL(strchr);
* @s: The string to be searched
* @c: The character to search for
*/
-char * strrchr(const char * s, int c)
+char *strrchr(const char *s, int c)
{
const char *p = s + strlen(s);
do {
@@ -296,8 +294,8 @@ EXPORT_SYMBOL(strrchr);
char *strnchr(const char *s, size_t count, int c)
{
for (; count-- && *s != '\0'; ++s)
- if (*s == (char) c)
- return (char *) s;
+ if (*s == (char)c)
+ return (char *)s;
return NULL;
}
EXPORT_SYMBOL(strnchr);
@@ -308,7 +306,7 @@ EXPORT_SYMBOL(strnchr);
* strlen - Find the length of a string
* @s: The string to be sized
*/
-size_t strlen(const char * s)
+size_t strlen(const char *s)
{
const char *sc;
@@ -325,7 +323,7 @@ EXPORT_SYMBOL(strlen);
* @s: The string to be sized
* @count: The maximum number of bytes to search
*/
-size_t strnlen(const char * s, size_t count)
+size_t strnlen(const char *s, size_t count)
{
const char *sc;
@@ -358,7 +356,6 @@ size_t strspn(const char *s, const char *accept)
return count;
++count;
}
-
return count;
}
@@ -384,9 +381,8 @@ size_t strcspn(const char *s, const char *reject)
}
++count;
}
-
return count;
-}
+}
EXPORT_SYMBOL(strcspn);
#ifndef __HAVE_ARCH_STRPBRK
@@ -395,14 +391,14 @@ EXPORT_SYMBOL(strcspn);
* @cs: The string to be searched
* @ct: The characters to search for
*/
-char * strpbrk(const char * cs,const char * ct)
+char *strpbrk(const char *cs, const char *ct)
{
- const char *sc1,*sc2;
+ const char *sc1, *sc2;
- for( sc1 = cs; *sc1 != '\0'; ++sc1) {
- for( sc2 = ct; *sc2 != '\0'; ++sc2) {
+ for (sc1 = cs; *sc1 != '\0'; ++sc1) {
+ for (sc2 = ct; *sc2 != '\0'; ++sc2) {
if (*sc1 == *sc2)
- return (char *) sc1;
+ return (char *)sc1;
}
}
return NULL;
@@ -422,9 +418,10 @@ EXPORT_SYMBOL(strpbrk);
* of that name. In fact, it was stolen from glibc2 and de-fancy-fied.
* Same semantics, slimmer shape. ;)
*/
-char * strsep(char **s, const char *ct)
+char *strsep(char **s, const char *ct)
{
- char *sbegin = *s, *end;
+ char *sbegin = *s;
+ char *end;
if (sbegin == NULL)
return NULL;
@@ -433,10 +430,8 @@ char * strsep(char **s, const char *ct)
if (end)
*end++ = '\0';
*s = end;
-
return sbegin;
}
-
EXPORT_SYMBOL(strsep);
#endif
@@ -449,13 +444,12 @@ EXPORT_SYMBOL(strsep);
*
* Do not use memset() to access IO space, use memset_io() instead.
*/
-void * memset(void * s,int c,size_t count)
+void *memset(void *s, int c, size_t count)
{
- char *xs = (char *) s;
+ char *xs = s;
while (count--)
*xs++ = c;
-
return s;
}
EXPORT_SYMBOL(memset);
@@ -471,13 +465,13 @@ EXPORT_SYMBOL(memset);
* You should not use this function to access IO space, use memcpy_toio()
* or memcpy_fromio() instead.
*/
-void * memcpy(void * dest,const void *src,size_t count)
+void *memcpy(void *dest, const void *src, size_t count)
{
- char *tmp = (char *) dest, *s = (char *) src;
+ char *tmp = dest;
+ char *s = src;
while (count--)
*tmp++ = *s++;
-
return dest;
}
EXPORT_SYMBOL(memcpy);
@@ -492,23 +486,24 @@ EXPORT_SYMBOL(memcpy);
*
* Unlike memcpy(), memmove() copes with overlapping areas.
*/
-void * memmove(void * dest,const void *src,size_t count)
+void *memmove(void *dest, const void *src, size_t count)
{
- char *tmp, *s;
+ char *tmp;
+ const char *s;
if (dest <= src) {
- tmp = (char *) dest;
- s = (char *) src;
+ tmp = dest;
+ s = src;
while (count--)
*tmp++ = *s++;
- }
- else {
- tmp = (char *) dest + count;
- s = (char *) src + count;
+ } else {
+ tmp = dest;
+ tmp += count;
+ s = src;
+ s += count;
while (count--)
*--tmp = *--s;
- }
-
+ }
return dest;
}
EXPORT_SYMBOL(memmove);
@@ -522,12 +517,12 @@ EXPORT_SYMBOL(memmove);
* @count: The size of the area.
*/
#undef memcmp
-int memcmp(const void * cs,const void * ct,size_t count)
+int memcmp(const void *cs, const void *ct, size_t count)
{
const unsigned char *su1, *su2;
int res = 0;
- for( su1 = cs, su2 = ct; 0 < count; ++su1, ++su2, count--)
+ for (su1 = cs, su2 = ct; 0 < count; ++su1, ++su2, count--)
if ((res = *su1 - *su2) != 0)
break;
return res;
@@ -545,17 +540,17 @@ EXPORT_SYMBOL(memcmp);
* returns the address of the first occurrence of @c, or 1 byte past
* the area if @c is not found
*/
-void * memscan(void * addr, int c, size_t size)
+void *memscan(void *addr, int c, size_t size)
{
- unsigned char * p = (unsigned char *) addr;
+ unsigned char *p = addr;
while (size) {
if (*p == c)
- return (void *) p;
+ return (void *)p;
p++;
size--;
}
- return (void *) p;
+ return (void *)p;
}
EXPORT_SYMBOL(memscan);
#endif
@@ -566,18 +561,18 @@ EXPORT_SYMBOL(memscan);
* @s1: The string to be searched
* @s2: The string to search for
*/
-char * strstr(const char * s1,const char * s2)
+char *strstr(const char *s1, const char *s2)
{
int l1, l2;
l2 = strlen(s2);
if (!l2)
- return (char *) s1;
+ return (char *)s1;
l1 = strlen(s1);
while (l1 >= l2) {
l1--;
- if (!memcmp(s1,s2,l2))
- return (char *) s1;
+ if (!memcmp(s1, s2, l2))
+ return (char *)s1;
s1++;
}
return NULL;
@@ -600,7 +595,7 @@ void *memchr(const void *s, int c, size_t n)
const unsigned char *p = s;
while (n-- != 0) {
if ((unsigned char)c == *p++) {
- return (void *)(p-1);
+ return (void *)(p - 1);
}
}
return NULL;
diff --git a/arch/ia64/lib/swiotlb.c b/lib/swiotlb.c
index a604efc7f6c9..57216f3544ca 100644
--- a/arch/ia64/lib/swiotlb.c
+++ b/lib/swiotlb.c
@@ -1,7 +1,7 @@
/*
* Dynamic DMA mapping support.
*
- * This implementation is for IA-64 platforms that do not support
+ * This implementation is for IA-64 and EM64T platforms that do not support
* I/O TLBs (aka DMA address translation hardware).
* Copyright (C) 2000 Asit Mallick <Asit.K.Mallick@intel.com>
* Copyright (C) 2000 Goutham Rao <goutham.rao@intel.com>
@@ -11,21 +11,23 @@
* 03/05/07 davidm Switch from PCI-DMA to generic device DMA API.
* 00/12/13 davidm Rename to swiotlb.c and add mark_clean() to avoid
* unnecessary i-cache flushing.
- * 04/07/.. ak Better overflow handling. Assorted fixes.
+ * 04/07/.. ak Better overflow handling. Assorted fixes.
+ * 05/09/10 linville Add support for syncing ranges, support syncing for
+ * DMA_BIDIRECTIONAL mappings, miscellaneous cleanup.
*/
#include <linux/cache.h>
+#include <linux/dma-mapping.h>
#include <linux/mm.h>
#include <linux/module.h>
-#include <linux/pci.h>
#include <linux/spinlock.h>
#include <linux/string.h>
#include <linux/types.h>
#include <linux/ctype.h>
#include <asm/io.h>
-#include <asm/pci.h>
#include <asm/dma.h>
+#include <asm/scatterlist.h>
#include <linux/init.h>
#include <linux/bootmem.h>
@@ -49,6 +51,23 @@
*/
#define IO_TLB_SHIFT 11
+#define SLABS_PER_PAGE (1 << (PAGE_SHIFT - IO_TLB_SHIFT))
+
+/*
+ * Minimum IO TLB size to bother booting with. Systems with mainly
+ * 64bit capable cards will only lightly use the swiotlb. If we can't
+ * allocate a contiguous 1MB, we're probably in trouble anyway.
+ */
+#define IO_TLB_MIN_SLABS ((1<<20) >> IO_TLB_SHIFT)
+
+/*
+ * Enumeration for sync targets
+ */
+enum dma_sync_target {
+ SYNC_FOR_CPU = 0,
+ SYNC_FOR_DEVICE = 1,
+};
+
int swiotlb_force;
/*
@@ -108,7 +127,7 @@ __setup("swiotlb=", setup_io_tlb_npages);
/*
* Statically reserve bounce buffer space and initialize bounce buffer data
- * structures for the software IO TLB used to implement the PCI DMA API.
+ * structures for the software IO TLB used to implement the DMA API.
*/
void
swiotlb_init_with_default_size (size_t default_size)
@@ -154,6 +173,99 @@ swiotlb_init (void)
swiotlb_init_with_default_size(64 * (1<<20)); /* default to 64MB */
}
+/*
+ * Systems with larger DMA zones (those that don't support ISA) can
+ * initialize the swiotlb later using the slab allocator if needed.
+ * This should be just like above, but with some error catching.
+ */
+int
+swiotlb_late_init_with_default_size (size_t default_size)
+{
+ unsigned long i, req_nslabs = io_tlb_nslabs;
+ unsigned int order;
+
+ if (!io_tlb_nslabs) {
+ io_tlb_nslabs = (default_size >> IO_TLB_SHIFT);
+ io_tlb_nslabs = ALIGN(io_tlb_nslabs, IO_TLB_SEGSIZE);
+ }
+
+ /*
+ * Get IO TLB memory from the low pages
+ */
+ order = get_order(io_tlb_nslabs * (1 << IO_TLB_SHIFT));
+ io_tlb_nslabs = SLABS_PER_PAGE << order;
+
+ while ((SLABS_PER_PAGE << order) > IO_TLB_MIN_SLABS) {
+ io_tlb_start = (char *)__get_free_pages(GFP_DMA | __GFP_NOWARN,
+ order);
+ if (io_tlb_start)
+ break;
+ order--;
+ }
+
+ if (!io_tlb_start)
+ goto cleanup1;
+
+ if (order != get_order(io_tlb_nslabs * (1 << IO_TLB_SHIFT))) {
+ printk(KERN_WARNING "Warning: only able to allocate %ld MB "
+ "for software IO TLB\n", (PAGE_SIZE << order) >> 20);
+ io_tlb_nslabs = SLABS_PER_PAGE << order;
+ }
+ io_tlb_end = io_tlb_start + io_tlb_nslabs * (1 << IO_TLB_SHIFT);
+ memset(io_tlb_start, 0, io_tlb_nslabs * (1 << IO_TLB_SHIFT));
+
+ /*
+ * Allocate and initialize the free list array. This array is used
+ * to find contiguous free memory regions of size up to IO_TLB_SEGSIZE
+ * between io_tlb_start and io_tlb_end.
+ */
+ io_tlb_list = (unsigned int *)__get_free_pages(GFP_KERNEL,
+ get_order(io_tlb_nslabs * sizeof(int)));
+ if (!io_tlb_list)
+ goto cleanup2;
+
+ for (i = 0; i < io_tlb_nslabs; i++)
+ io_tlb_list[i] = IO_TLB_SEGSIZE - OFFSET(i, IO_TLB_SEGSIZE);
+ io_tlb_index = 0;
+
+ io_tlb_orig_addr = (unsigned char **)__get_free_pages(GFP_KERNEL,
+ get_order(io_tlb_nslabs * sizeof(char *)));
+ if (!io_tlb_orig_addr)
+ goto cleanup3;
+
+ memset(io_tlb_orig_addr, 0, io_tlb_nslabs * sizeof(char *));
+
+ /*
+ * Get the overflow emergency buffer
+ */
+ io_tlb_overflow_buffer = (void *)__get_free_pages(GFP_DMA,
+ get_order(io_tlb_overflow));
+ if (!io_tlb_overflow_buffer)
+ goto cleanup4;
+
+ printk(KERN_INFO "Placing %ldMB software IO TLB between 0x%lx - "
+ "0x%lx\n", (io_tlb_nslabs * (1 << IO_TLB_SHIFT)) >> 20,
+ virt_to_phys(io_tlb_start), virt_to_phys(io_tlb_end));
+
+ return 0;
+
+cleanup4:
+ free_pages((unsigned long)io_tlb_orig_addr, get_order(io_tlb_nslabs *
+ sizeof(char *)));
+ io_tlb_orig_addr = NULL;
+cleanup3:
+ free_pages((unsigned long)io_tlb_list, get_order(io_tlb_nslabs *
+ sizeof(int)));
+ io_tlb_list = NULL;
+ io_tlb_end = NULL;
+cleanup2:
+ free_pages((unsigned long)io_tlb_start, order);
+ io_tlb_start = NULL;
+cleanup1:
+ io_tlb_nslabs = req_nslabs;
+ return -ENOMEM;
+}
+
static inline int
address_needs_mapping(struct device *hwdev, dma_addr_t addr)
{
@@ -295,26 +407,33 @@ unmap_single(struct device *hwdev, char *dma_addr, size_t size, int dir)
}
static void
-sync_single(struct device *hwdev, char *dma_addr, size_t size, int dir)
+sync_single(struct device *hwdev, char *dma_addr, size_t size,
+ int dir, int target)
{
int index = (dma_addr - io_tlb_start) >> IO_TLB_SHIFT;
char *buffer = io_tlb_orig_addr[index];
- /*
- * bounce... copy the data back into/from the original buffer
- * XXX How do you handle DMA_BIDIRECTIONAL here ?
- */
- if (dir == DMA_FROM_DEVICE)
- memcpy(buffer, dma_addr, size);
- else if (dir == DMA_TO_DEVICE)
- memcpy(dma_addr, buffer, size);
- else
+ switch (target) {
+ case SYNC_FOR_CPU:
+ if (likely(dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL))
+ memcpy(buffer, dma_addr, size);
+ else if (dir != DMA_TO_DEVICE)
+ BUG();
+ break;
+ case SYNC_FOR_DEVICE:
+ if (likely(dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL))
+ memcpy(dma_addr, buffer, size);
+ else if (dir != DMA_FROM_DEVICE)
+ BUG();
+ break;
+ default:
BUG();
+ }
}
void *
swiotlb_alloc_coherent(struct device *hwdev, size_t size,
- dma_addr_t *dma_handle, int flags)
+ dma_addr_t *dma_handle, gfp_t flags)
{
unsigned long dev_addr;
void *ret;
@@ -383,24 +502,24 @@ swiotlb_full(struct device *dev, size_t size, int dir, int do_panic)
/*
* Ran out of IOMMU space for this operation. This is very bad.
* Unfortunately the drivers cannot handle this operation properly.
- * unless they check for pci_dma_mapping_error (most don't)
+ * unless they check for dma_mapping_error (most don't)
* When the mapping is small enough return a static buffer to limit
* the damage, or panic when the transfer is too big.
*/
- printk(KERN_ERR "PCI-DMA: Out of SW-IOMMU space for %lu bytes at "
+ printk(KERN_ERR "DMA: Out of SW-IOMMU space for %lu bytes at "
"device %s\n", size, dev ? dev->bus_id : "?");
if (size > io_tlb_overflow && do_panic) {
- if (dir == PCI_DMA_FROMDEVICE || dir == PCI_DMA_BIDIRECTIONAL)
- panic("PCI-DMA: Memory would be corrupted\n");
- if (dir == PCI_DMA_TODEVICE || dir == PCI_DMA_BIDIRECTIONAL)
- panic("PCI-DMA: Random memory would be DMAed\n");
+ if (dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL)
+ panic("DMA: Memory would be corrupted\n");
+ if (dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL)
+ panic("DMA: Random memory would be DMAed\n");
}
}
/*
* Map a single buffer of the indicated size for DMA in streaming mode. The
- * PCI address to use is returned.
+ * 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.
@@ -487,39 +606,73 @@ swiotlb_unmap_single(struct device *hwdev, dma_addr_t dev_addr, size_t size,
* after a transfer.
*
* If you perform a swiotlb_map_single() but wish to interrogate the buffer
- * using the cpu, yet do not wish to teardown the PCI dma mapping, you must
- * call this function before doing so. At the next point you give the PCI dma
+ * 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
* swiotlb_dma_sync_for_device, and then the device again owns the buffer
*/
-void
-swiotlb_sync_single_for_cpu(struct device *hwdev, dma_addr_t dev_addr,
- size_t size, int dir)
+static inline void
+swiotlb_sync_single(struct device *hwdev, dma_addr_t dev_addr,
+ size_t size, int dir, int target)
{
char *dma_addr = phys_to_virt(dev_addr);
if (dir == DMA_NONE)
BUG();
if (dma_addr >= io_tlb_start && dma_addr < io_tlb_end)
- sync_single(hwdev, dma_addr, size, dir);
+ sync_single(hwdev, dma_addr, size, dir, target);
else if (dir == DMA_FROM_DEVICE)
mark_clean(dma_addr, size);
}
void
+swiotlb_sync_single_for_cpu(struct device *hwdev, dma_addr_t dev_addr,
+ size_t size, int dir)
+{
+ swiotlb_sync_single(hwdev, dev_addr, size, dir, SYNC_FOR_CPU);
+}
+
+void
swiotlb_sync_single_for_device(struct device *hwdev, dma_addr_t dev_addr,
size_t size, int dir)
{
- char *dma_addr = phys_to_virt(dev_addr);
+ swiotlb_sync_single(hwdev, dev_addr, size, dir, SYNC_FOR_DEVICE);
+}
+
+/*
+ * Same as above, but for a sub-range of the mapping.
+ */
+static inline void
+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 = phys_to_virt(dev_addr) + offset;
if (dir == DMA_NONE)
BUG();
if (dma_addr >= io_tlb_start && dma_addr < io_tlb_end)
- sync_single(hwdev, dma_addr, size, dir);
+ sync_single(hwdev, dma_addr, size, dir, target);
else if (dir == DMA_FROM_DEVICE)
mark_clean(dma_addr, size);
}
+void
+swiotlb_sync_single_range_for_cpu(struct device *hwdev, dma_addr_t dev_addr,
+ unsigned long offset, size_t size, int dir)
+{
+ swiotlb_sync_single_range(hwdev, dev_addr, offset, size, dir,
+ SYNC_FOR_CPU);
+}
+
+void
+swiotlb_sync_single_range_for_device(struct device *hwdev, dma_addr_t dev_addr,
+ unsigned long offset, size_t size, int dir)
+{
+ swiotlb_sync_single_range(hwdev, dev_addr, offset, size, dir,
+ SYNC_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
@@ -594,9 +747,9 @@ swiotlb_unmap_sg(struct device *hwdev, struct scatterlist *sg, int nelems,
* The same as swiotlb_sync_single_* but for a scatter-gather list, same rules
* and usage.
*/
-void
-swiotlb_sync_sg_for_cpu(struct device *hwdev, struct scatterlist *sg,
- int nelems, int dir)
+static inline void
+swiotlb_sync_sg(struct device *hwdev, struct scatterlist *sg,
+ int nelems, int dir, int target)
{
int i;
@@ -606,22 +759,21 @@ swiotlb_sync_sg_for_cpu(struct device *hwdev, struct scatterlist *sg,
for (i = 0; i < nelems; i++, sg++)
if (sg->dma_address != SG_ENT_PHYS_ADDRESS(sg))
sync_single(hwdev, (void *) sg->dma_address,
- sg->dma_length, dir);
+ sg->dma_length, dir, target);
+}
+
+void
+swiotlb_sync_sg_for_cpu(struct device *hwdev, struct scatterlist *sg,
+ int nelems, int dir)
+{
+ swiotlb_sync_sg(hwdev, sg, nelems, dir, SYNC_FOR_CPU);
}
void
swiotlb_sync_sg_for_device(struct device *hwdev, struct scatterlist *sg,
int nelems, int dir)
{
- int i;
-
- if (dir == DMA_NONE)
- BUG();
-
- for (i = 0; i < nelems; i++, sg++)
- if (sg->dma_address != SG_ENT_PHYS_ADDRESS(sg))
- sync_single(hwdev, (void *) sg->dma_address,
- sg->dma_length, dir);
+ swiotlb_sync_sg(hwdev, sg, nelems, dir, SYNC_FOR_DEVICE);
}
int
@@ -631,9 +783,9 @@ swiotlb_dma_mapping_error(dma_addr_t dma_addr)
}
/*
- * Return whether the given PCI device DMA address mask can be supported
+ * Return whether the given device DMA address mask can be supported
* properly. For example, if your device can only drive the low 24-bits
- * during PCI bus mastering, then you would pass 0x00ffffff as the mask to
+ * during bus mastering, then you would pass 0x00ffffff as the mask to
* this function.
*/
int
@@ -649,6 +801,8 @@ EXPORT_SYMBOL(swiotlb_map_sg);
EXPORT_SYMBOL(swiotlb_unmap_sg);
EXPORT_SYMBOL(swiotlb_sync_single_for_cpu);
EXPORT_SYMBOL(swiotlb_sync_single_for_device);
+EXPORT_SYMBOL_GPL(swiotlb_sync_single_range_for_cpu);
+EXPORT_SYMBOL_GPL(swiotlb_sync_single_range_for_device);
EXPORT_SYMBOL(swiotlb_sync_sg_for_cpu);
EXPORT_SYMBOL(swiotlb_sync_sg_for_device);
EXPORT_SYMBOL(swiotlb_dma_mapping_error);
diff --git a/lib/textsearch.c b/lib/textsearch.c
index 1e934c196f0f..6f3093efbd7b 100644
--- a/lib/textsearch.c
+++ b/lib/textsearch.c
@@ -254,7 +254,7 @@ unsigned int textsearch_find_continuous(struct ts_config *conf,
* parameters or a ERR_PTR().
*/
struct ts_config *textsearch_prepare(const char *algo, const void *pattern,
- unsigned int len, int gfp_mask, int flags)
+ unsigned int len, gfp_t gfp_mask, int flags)
{
int err = -ENOENT;
struct ts_config *conf;
diff --git a/lib/vsprintf.c b/lib/vsprintf.c
index e4e9031dd9c3..b07db5ca3f66 100644
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c
@@ -23,6 +23,7 @@
#include <linux/ctype.h>
#include <linux/kernel.h>
+#include <asm/page.h> /* for PAGE_SIZE */
#include <asm/div64.h>
/**
diff --git a/lib/zlib_inflate/inflate.c b/lib/zlib_inflate/inflate.c
index 3d94cb90c1d3..31b9e9054bf7 100644
--- a/lib/zlib_inflate/inflate.c
+++ b/lib/zlib_inflate/inflate.c
@@ -3,7 +3,6 @@
* For conditions of distribution and use, see copyright notice in zlib.h
*/
-#include <linux/module.h>
#include <linux/zutil.h>
#include "infblock.h"
#include "infutil.h"
diff --git a/mm/Kconfig b/mm/Kconfig
index 391ffc54d136..ae9ce6b73e8a 100644
--- a/mm/Kconfig
+++ b/mm/Kconfig
@@ -111,3 +111,26 @@ config SPARSEMEM_STATIC
config SPARSEMEM_EXTREME
def_bool y
depends on SPARSEMEM && !SPARSEMEM_STATIC
+
+# eventually, we can have this option just 'select SPARSEMEM'
+config MEMORY_HOTPLUG
+ bool "Allow for memory hot-add"
+ depends on SPARSEMEM && HOTPLUG && !SOFTWARE_SUSPEND
+
+comment "Memory hotplug is currently incompatible with Software Suspend"
+ depends on SPARSEMEM && HOTPLUG && SOFTWARE_SUSPEND
+
+# Heavily threaded applications may benefit from splitting the mm-wide
+# page_table_lock, so that faults on different parts of the user address
+# space can be handled with less contention: split it at this NR_CPUS.
+# Default to 4 for wider testing, though 8 might be more appropriate.
+# ARM's adjust_pte (unused if VIPT) depends on mm-wide page_table_lock.
+# PA-RISC's debug spinlock_t is too large for the 32-bit struct page.
+# ARM26 and SPARC32 and PPC64 may use one page for multiple page tables.
+#
+config SPLIT_PTLOCK_CPUS
+ int
+ default "4096" if ARM && !CPU_CACHE_VIPT
+ default "4096" if PARISC && DEBUG_SPINLOCK && !64BIT
+ default "4096" if ARM26 || SPARC32 || PPC64
+ default "4"
diff --git a/mm/Makefile b/mm/Makefile
index 4cd69e3ce421..2fa6d2ca9f28 100644
--- a/mm/Makefile
+++ b/mm/Makefile
@@ -18,5 +18,5 @@ obj-$(CONFIG_NUMA) += mempolicy.o
obj-$(CONFIG_SPARSEMEM) += sparse.o
obj-$(CONFIG_SHMEM) += shmem.o
obj-$(CONFIG_TINY_SHMEM) += tiny-shmem.o
-
+obj-$(CONFIG_MEMORY_HOTPLUG) += memory_hotplug.o
obj-$(CONFIG_FS_XIP) += filemap_xip.o
diff --git a/mm/bootmem.c b/mm/bootmem.c
index a58699b6579e..e8c567177dcf 100644
--- a/mm/bootmem.c
+++ b/mm/bootmem.c
@@ -305,6 +305,7 @@ static unsigned long __init free_all_bootmem_core(pg_data_t *pgdat)
if (j + 16 < BITS_PER_LONG)
prefetchw(page + j + 16);
__ClearPageReserved(page + j);
+ set_page_count(page + j, 0);
}
__free_pages(page, order);
i += BITS_PER_LONG;
diff --git a/mm/filemap.c b/mm/filemap.c
index b5346576e58d..5d6e4c2000dc 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -66,7 +66,7 @@ generic_file_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov,
*
* ->mmap_sem
* ->i_mmap_lock
- * ->page_table_lock (various places, mainly in mmap.c)
+ * ->page_table_lock or pte_lock (various, mainly in memory.c)
* ->mapping->tree_lock (arch-dependent flush_dcache_mmap_lock)
*
* ->mmap_sem
@@ -86,9 +86,9 @@ generic_file_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov,
* ->anon_vma.lock (vma_adjust)
*
* ->anon_vma.lock
- * ->page_table_lock (anon_vma_prepare and various)
+ * ->page_table_lock or pte_lock (anon_vma_prepare and various)
*
- * ->page_table_lock
+ * ->page_table_lock or pte_lock
* ->swap_lock (try_to_unmap_one)
* ->private_lock (try_to_unmap_one)
* ->tree_lock (try_to_unmap_one)
@@ -152,7 +152,7 @@ static int sync_page(void *word)
* in the ->sync_page() methods make essential use of the
* page_mapping(), merely passing the page down to the backing
* device's unplug functions when it's non-NULL, which in turn
- * ignore it for all cases but swap, where only page->private is
+ * ignore it for all cases but swap, where only page_private(page) is
* of interest. When page_mapping() does go NULL, the entire
* call stack gracefully ignores the page and returns.
* -- wli
@@ -377,7 +377,7 @@ int filemap_write_and_wait_range(struct address_space *mapping,
* This function does not add the page to the LRU. The caller must do that.
*/
int add_to_page_cache(struct page *page, struct address_space *mapping,
- pgoff_t offset, int gfp_mask)
+ pgoff_t offset, gfp_t gfp_mask)
{
int error = radix_tree_preload(gfp_mask & ~__GFP_HIGHMEM);
@@ -401,7 +401,7 @@ int add_to_page_cache(struct page *page, struct address_space *mapping,
EXPORT_SYMBOL(add_to_page_cache);
int add_to_page_cache_lru(struct page *page, struct address_space *mapping,
- pgoff_t offset, int gfp_mask)
+ pgoff_t offset, gfp_t gfp_mask)
{
int ret = add_to_page_cache(page, mapping, offset, gfp_mask);
if (ret == 0)
@@ -591,7 +591,7 @@ EXPORT_SYMBOL(find_lock_page);
* memory exhaustion.
*/
struct page *find_or_create_page(struct address_space *mapping,
- unsigned long index, unsigned int gfp_mask)
+ unsigned long index, gfp_t gfp_mask)
{
struct page *page, *cached_page = NULL;
int err;
@@ -683,7 +683,7 @@ struct page *
grab_cache_page_nowait(struct address_space *mapping, unsigned long index)
{
struct page *page = find_get_page(mapping, index);
- unsigned int gfp_mask;
+ gfp_t gfp_mask;
if (page) {
if (!TestSetPageLocked(page))
@@ -1030,8 +1030,8 @@ __generic_file_aio_read(struct kiocb *iocb, const struct iovec *iov,
desc.error = 0;
do_generic_file_read(filp,ppos,&desc,file_read_actor);
retval += desc.written;
- if (!retval) {
- retval = desc.error;
+ if (desc.error) {
+ retval = retval ?: desc.error;
break;
}
}
@@ -1520,7 +1520,7 @@ repeat:
page_cache_release(page);
return err;
}
- } else {
+ } else if (vma->vm_flags & VM_NONLINEAR) {
/* No page was found just because we can't read it in now (being
* here implies nonblock != 0), but the page may exist, so set
* the PTE to fault it in later. */
@@ -1537,6 +1537,7 @@ repeat:
return 0;
}
+EXPORT_SYMBOL(filemap_populate);
struct vm_operations_struct generic_file_vm_ops = {
.nopage = filemap_nopage,
@@ -1555,7 +1556,6 @@ int generic_file_mmap(struct file * file, struct vm_area_struct * vma)
vma->vm_ops = &generic_file_vm_ops;
return 0;
}
-EXPORT_SYMBOL(filemap_populate);
/*
* This is for filesystems which do not implement ->writepage.
diff --git a/mm/filemap_xip.c b/mm/filemap_xip.c
index 8c199f537732..9cf687e4a29a 100644
--- a/mm/filemap_xip.c
+++ b/mm/filemap_xip.c
@@ -174,6 +174,8 @@ __xip_unmap (struct address_space * mapping,
unsigned long address;
pte_t *pte;
pte_t pteval;
+ spinlock_t *ptl;
+ struct page *page;
spin_lock(&mapping->i_mmap_lock);
vma_prio_tree_foreach(vma, &iter, &mapping->i_mmap, pgoff, pgoff) {
@@ -181,19 +183,17 @@ __xip_unmap (struct address_space * mapping,
address = vma->vm_start +
((pgoff - vma->vm_pgoff) << PAGE_SHIFT);
BUG_ON(address < vma->vm_start || address >= vma->vm_end);
- /*
- * We need the page_table_lock to protect us from page faults,
- * munmap, fork, etc...
- */
- pte = page_check_address(ZERO_PAGE(address), mm,
- address);
- if (!IS_ERR(pte)) {
+ page = ZERO_PAGE(address);
+ pte = page_check_address(page, mm, address, &ptl);
+ if (pte) {
/* Nuke the page table entry. */
flush_cache_page(vma, address, pte_pfn(*pte));
pteval = ptep_clear_flush(vma, address, pte);
+ page_remove_rmap(page);
+ dec_mm_counter(mm, file_rss);
BUG_ON(pte_dirty(pteval));
- pte_unmap(pte);
- spin_unlock(&mm->page_table_lock);
+ pte_unmap_unlock(pte, ptl);
+ page_cache_release(page);
}
}
spin_unlock(&mapping->i_mmap_lock);
@@ -228,7 +228,7 @@ xip_file_nopage(struct vm_area_struct * area,
page = mapping->a_ops->get_xip_page(mapping, pgoff*(PAGE_SIZE/512), 0);
if (!IS_ERR(page)) {
- return page;
+ goto out;
}
if (PTR_ERR(page) != -ENODATA)
return NULL;
@@ -249,6 +249,8 @@ xip_file_nopage(struct vm_area_struct * area,
page = ZERO_PAGE(address);
}
+out:
+ page_cache_get(page);
return page;
}
diff --git a/mm/fremap.c b/mm/fremap.c
index ab23a0673c35..d862be3bc3e3 100644
--- a/mm/fremap.c
+++ b/mm/fremap.c
@@ -20,33 +20,32 @@
#include <asm/cacheflush.h>
#include <asm/tlbflush.h>
-static inline void zap_pte(struct mm_struct *mm, struct vm_area_struct *vma,
+static int zap_pte(struct mm_struct *mm, struct vm_area_struct *vma,
unsigned long addr, pte_t *ptep)
{
pte_t pte = *ptep;
+ struct page *page = NULL;
- if (pte_none(pte))
- return;
if (pte_present(pte)) {
unsigned long pfn = pte_pfn(pte);
-
flush_cache_page(vma, addr, pfn);
pte = ptep_clear_flush(vma, addr, ptep);
- if (pfn_valid(pfn)) {
- struct page *page = pfn_to_page(pfn);
- if (!PageReserved(page)) {
- if (pte_dirty(pte))
- set_page_dirty(page);
- page_remove_rmap(page);
- page_cache_release(page);
- dec_mm_counter(mm, rss);
- }
+ if (unlikely(!pfn_valid(pfn))) {
+ print_bad_pte(vma, pte, addr);
+ goto out;
}
+ page = pfn_to_page(pfn);
+ if (pte_dirty(pte))
+ set_page_dirty(page);
+ page_remove_rmap(page);
+ page_cache_release(page);
} else {
if (!pte_file(pte))
free_swap_and_cache(pte_to_swp_entry(pte));
pte_clear(mm, addr, ptep);
}
+out:
+ return !!page;
}
/*
@@ -64,21 +63,20 @@ int install_page(struct mm_struct *mm, struct vm_area_struct *vma,
pud_t *pud;
pgd_t *pgd;
pte_t pte_val;
+ spinlock_t *ptl;
+
+ BUG_ON(vma->vm_flags & VM_RESERVED);
pgd = pgd_offset(mm, addr);
- spin_lock(&mm->page_table_lock);
-
pud = pud_alloc(mm, pgd, addr);
if (!pud)
- goto err_unlock;
-
+ goto out;
pmd = pmd_alloc(mm, pud, addr);
if (!pmd)
- goto err_unlock;
-
- pte = pte_alloc_map(mm, pmd, addr);
+ goto out;
+ pte = pte_alloc_map_lock(mm, pmd, addr, &ptl);
if (!pte)
- goto err_unlock;
+ goto out;
/*
* This page may have been truncated. Tell the
@@ -88,29 +86,27 @@ int install_page(struct mm_struct *mm, struct vm_area_struct *vma,
inode = vma->vm_file->f_mapping->host;
size = (i_size_read(inode) + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
if (!page->mapping || page->index >= size)
- goto err_unlock;
+ goto unlock;
err = -ENOMEM;
if (page_mapcount(page) > INT_MAX/2)
- goto err_unlock;
+ goto unlock;
- zap_pte(mm, vma, addr, pte);
+ if (pte_none(*pte) || !zap_pte(mm, vma, addr, pte))
+ inc_mm_counter(mm, file_rss);
- inc_mm_counter(mm,rss);
flush_icache_page(vma, page);
set_pte_at(mm, addr, pte, mk_pte(page, prot));
page_add_file_rmap(page);
pte_val = *pte;
- pte_unmap(pte);
update_mmu_cache(vma, addr, pte_val);
-
err = 0;
-err_unlock:
- spin_unlock(&mm->page_table_lock);
+unlock:
+ pte_unmap_unlock(pte, ptl);
+out:
return err;
}
EXPORT_SYMBOL(install_page);
-
/*
* Install a file pte to a given virtual memory address, release any
* previously existing mapping.
@@ -124,37 +120,35 @@ int install_file_pte(struct mm_struct *mm, struct vm_area_struct *vma,
pud_t *pud;
pgd_t *pgd;
pte_t pte_val;
+ spinlock_t *ptl;
+
+ BUG_ON(vma->vm_flags & VM_RESERVED);
pgd = pgd_offset(mm, addr);
- spin_lock(&mm->page_table_lock);
-
pud = pud_alloc(mm, pgd, addr);
if (!pud)
- goto err_unlock;
-
+ goto out;
pmd = pmd_alloc(mm, pud, addr);
if (!pmd)
- goto err_unlock;
-
- pte = pte_alloc_map(mm, pmd, addr);
+ goto out;
+ pte = pte_alloc_map_lock(mm, pmd, addr, &ptl);
if (!pte)
- goto err_unlock;
+ goto out;
- zap_pte(mm, vma, addr, pte);
+ if (!pte_none(*pte) && zap_pte(mm, vma, addr, pte)) {
+ update_hiwater_rss(mm);
+ dec_mm_counter(mm, file_rss);
+ }
set_pte_at(mm, addr, pte, pgoff_to_pte(pgoff));
pte_val = *pte;
- pte_unmap(pte);
update_mmu_cache(vma, addr, pte_val);
- spin_unlock(&mm->page_table_lock);
- return 0;
-
-err_unlock:
- spin_unlock(&mm->page_table_lock);
+ pte_unmap_unlock(pte, ptl);
+ err = 0;
+out:
return err;
}
-
/***
* sys_remap_file_pages - remap arbitrary pages of a shared backing store
* file within an existing vma.
diff --git a/mm/highmem.c b/mm/highmem.c
index 90e1861e2da0..ce2e7e8bbfa7 100644
--- a/mm/highmem.c
+++ b/mm/highmem.c
@@ -30,11 +30,9 @@
static mempool_t *page_pool, *isa_page_pool;
-static void *page_pool_alloc(gfp_t gfp_mask, void *data)
+static void *page_pool_alloc_isa(gfp_t gfp_mask, void *data)
{
- unsigned int gfp = gfp_mask | (unsigned int) (long) data;
-
- return alloc_page(gfp);
+ return alloc_page(gfp_mask | GFP_DMA);
}
static void page_pool_free(void *page, void *data)
@@ -51,6 +49,12 @@ static void page_pool_free(void *page, void *data)
* n means that there are (n-1) current users of it.
*/
#ifdef CONFIG_HIGHMEM
+
+static void *page_pool_alloc(gfp_t gfp_mask, void *data)
+{
+ return alloc_page(gfp_mask);
+}
+
static int pkmap_count[LAST_PKMAP];
static unsigned int last_pkmap_nr;
static __cacheline_aligned_in_smp DEFINE_SPINLOCK(kmap_lock);
@@ -267,7 +271,7 @@ int init_emergency_isa_pool(void)
if (isa_page_pool)
return 0;
- isa_page_pool = mempool_create(ISA_POOL_SIZE, page_pool_alloc, page_pool_free, (void *) __GFP_DMA);
+ isa_page_pool = mempool_create(ISA_POOL_SIZE, page_pool_alloc_isa, page_pool_free, NULL);
if (!isa_page_pool)
BUG();
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index 61d380678030..728e9bda12ea 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -103,6 +103,9 @@ static int __init hugetlb_init(void)
unsigned long i;
struct page *page;
+ if (HPAGE_SHIFT == 0)
+ return 0;
+
for (i = 0; i < MAX_NUMNODES; ++i)
INIT_LIST_HEAD(&hugepage_freelists[i]);
@@ -234,7 +237,6 @@ unsigned long hugetlb_total_pages(void)
{
return nr_huge_pages * (HPAGE_SIZE / PAGE_SIZE);
}
-EXPORT_SYMBOL(hugetlb_total_pages);
/*
* We cannot handle pagefaults against hugetlb pages at all. They cause
@@ -277,19 +279,23 @@ int copy_hugetlb_page_range(struct mm_struct *dst, struct mm_struct *src,
unsigned long addr;
for (addr = vma->vm_start; addr < vma->vm_end; addr += HPAGE_SIZE) {
+ src_pte = huge_pte_offset(src, addr);
+ if (!src_pte)
+ continue;
dst_pte = huge_pte_alloc(dst, addr);
if (!dst_pte)
goto nomem;
+ spin_lock(&dst->page_table_lock);
spin_lock(&src->page_table_lock);
- src_pte = huge_pte_offset(src, addr);
- if (src_pte && !pte_none(*src_pte)) {
+ if (!pte_none(*src_pte)) {
entry = *src_pte;
ptepage = pte_page(entry);
get_page(ptepage);
- add_mm_counter(dst, rss, HPAGE_SIZE / PAGE_SIZE);
+ add_mm_counter(dst, file_rss, HPAGE_SIZE / PAGE_SIZE);
set_huge_pte_at(dst, addr, dst_pte, entry);
}
spin_unlock(&src->page_table_lock);
+ spin_unlock(&dst->page_table_lock);
}
return 0;
@@ -310,12 +316,14 @@ void unmap_hugepage_range(struct vm_area_struct *vma, unsigned long start,
BUG_ON(start & ~HPAGE_MASK);
BUG_ON(end & ~HPAGE_MASK);
+ spin_lock(&mm->page_table_lock);
+
+ /* Update high watermark before we lower rss */
+ update_hiwater_rss(mm);
+
for (address = start; address < end; address += HPAGE_SIZE) {
ptep = huge_pte_offset(mm, address);
- if (! ptep)
- /* This can happen on truncate, or if an
- * mmap() is aborted due to an error before
- * the prefault */
+ if (!ptep)
continue;
pte = huge_ptep_get_and_clear(mm, address, ptep);
@@ -324,96 +332,99 @@ void unmap_hugepage_range(struct vm_area_struct *vma, unsigned long start,
page = pte_page(pte);
put_page(page);
- add_mm_counter(mm, rss, - (HPAGE_SIZE / PAGE_SIZE));
+ add_mm_counter(mm, file_rss, (int) -(HPAGE_SIZE / PAGE_SIZE));
}
- flush_tlb_range(vma, start, end);
-}
-void zap_hugepage_range(struct vm_area_struct *vma,
- unsigned long start, unsigned long length)
-{
- struct mm_struct *mm = vma->vm_mm;
-
- spin_lock(&mm->page_table_lock);
- unmap_hugepage_range(vma, start, start + length);
spin_unlock(&mm->page_table_lock);
+ flush_tlb_range(vma, start, end);
}
-int hugetlb_prefault(struct address_space *mapping, struct vm_area_struct *vma)
+static struct page *find_lock_huge_page(struct address_space *mapping,
+ unsigned long idx)
{
- struct mm_struct *mm = current->mm;
- unsigned long addr;
- int ret = 0;
-
- WARN_ON(!is_vm_hugetlb_page(vma));
- BUG_ON(vma->vm_start & ~HPAGE_MASK);
- BUG_ON(vma->vm_end & ~HPAGE_MASK);
-
- hugetlb_prefault_arch_hook(mm);
-
- spin_lock(&mm->page_table_lock);
- for (addr = vma->vm_start; addr < vma->vm_end; addr += HPAGE_SIZE) {
- unsigned long idx;
- pte_t *pte = huge_pte_alloc(mm, addr);
- struct page *page;
-
- if (!pte) {
- ret = -ENOMEM;
- goto out;
- }
+ struct page *page;
+ int err;
+ struct inode *inode = mapping->host;
+ unsigned long size;
+
+retry:
+ page = find_lock_page(mapping, idx);
+ if (page)
+ goto out;
+
+ /* Check to make sure the mapping hasn't been truncated */
+ size = i_size_read(inode) >> HPAGE_SHIFT;
+ if (idx >= size)
+ goto out;
+
+ if (hugetlb_get_quota(mapping))
+ goto out;
+ page = alloc_huge_page();
+ if (!page) {
+ hugetlb_put_quota(mapping);
+ goto out;
+ }
- idx = ((addr - vma->vm_start) >> HPAGE_SHIFT)
- + (vma->vm_pgoff >> (HPAGE_SHIFT - PAGE_SHIFT));
- page = find_get_page(mapping, idx);
- if (!page) {
- /* charge the fs quota first */
- if (hugetlb_get_quota(mapping)) {
- ret = -ENOMEM;
- goto out;
- }
- page = alloc_huge_page();
- if (!page) {
- hugetlb_put_quota(mapping);
- ret = -ENOMEM;
- goto out;
- }
- ret = add_to_page_cache(page, mapping, idx, GFP_ATOMIC);
- if (! ret) {
- unlock_page(page);
- } else {
- hugetlb_put_quota(mapping);
- free_huge_page(page);
- goto out;
- }
- }
- add_mm_counter(mm, rss, HPAGE_SIZE / PAGE_SIZE);
- set_huge_pte_at(mm, addr, pte, make_huge_pte(vma, page));
+ err = add_to_page_cache(page, mapping, idx, GFP_KERNEL);
+ if (err) {
+ put_page(page);
+ hugetlb_put_quota(mapping);
+ if (err == -EEXIST)
+ goto retry;
+ page = NULL;
}
out:
- spin_unlock(&mm->page_table_lock);
- return ret;
+ return page;
}
-/*
- * On ia64 at least, it is possible to receive a hugetlb fault from a
- * stale zero entry left in the TLB from earlier hardware prefetching.
- * Low-level arch code should already have flushed the stale entry as
- * part of its fault handling, but we do need to accept this minor fault
- * and return successfully. Whereas the "normal" case is that this is
- * an access to a hugetlb page which has been truncated off since mmap.
- */
int hugetlb_fault(struct mm_struct *mm, struct vm_area_struct *vma,
unsigned long address, int write_access)
{
int ret = VM_FAULT_SIGBUS;
+ unsigned long idx;
+ unsigned long size;
pte_t *pte;
+ struct page *page;
+ struct address_space *mapping;
+
+ pte = huge_pte_alloc(mm, address);
+ if (!pte)
+ goto out;
+
+ mapping = vma->vm_file->f_mapping;
+ idx = ((address - vma->vm_start) >> HPAGE_SHIFT)
+ + (vma->vm_pgoff >> (HPAGE_SHIFT - PAGE_SHIFT));
+
+ /*
+ * Use page lock to guard against racing truncation
+ * before we get page_table_lock.
+ */
+ page = find_lock_huge_page(mapping, idx);
+ if (!page)
+ goto out;
spin_lock(&mm->page_table_lock);
- pte = huge_pte_offset(mm, address);
- if (pte && !pte_none(*pte))
- ret = VM_FAULT_MINOR;
+ size = i_size_read(mapping->host) >> HPAGE_SHIFT;
+ if (idx >= size)
+ goto backout;
+
+ ret = VM_FAULT_MINOR;
+ if (!pte_none(*pte))
+ goto backout;
+
+ add_mm_counter(mm, file_rss, HPAGE_SIZE / PAGE_SIZE);
+ set_huge_pte_at(mm, address, pte, make_huge_pte(vma, page));
spin_unlock(&mm->page_table_lock);
+ unlock_page(page);
+out:
return ret;
+
+backout:
+ spin_unlock(&mm->page_table_lock);
+ hugetlb_put_quota(mapping);
+ unlock_page(page);
+ put_page(page);
+ goto out;
}
int follow_hugetlb_page(struct mm_struct *mm, struct vm_area_struct *vma,
@@ -423,34 +434,36 @@ int follow_hugetlb_page(struct mm_struct *mm, struct vm_area_struct *vma,
unsigned long vpfn, vaddr = *position;
int remainder = *length;
- BUG_ON(!is_vm_hugetlb_page(vma));
-
vpfn = vaddr/PAGE_SIZE;
spin_lock(&mm->page_table_lock);
while (vaddr < vma->vm_end && remainder) {
+ pte_t *pte;
+ struct page *page;
- if (pages) {
- pte_t *pte;
- struct page *page;
-
- /* Some archs (sparc64, sh*) have multiple
- * pte_ts to each hugepage. We have to make
- * sure we get the first, for the page
- * indexing below to work. */
- pte = huge_pte_offset(mm, vaddr & HPAGE_MASK);
-
- /* the hugetlb file might have been truncated */
- if (!pte || pte_none(*pte)) {
- remainder = 0;
- if (!i)
- i = -EFAULT;
- break;
- }
+ /*
+ * Some archs (sparc64, sh*) have multiple pte_ts to
+ * each hugepage. We have to make * sure we get the
+ * first, for the page indexing below to work.
+ */
+ pte = huge_pte_offset(mm, vaddr & HPAGE_MASK);
- page = &pte_page(*pte)[vpfn % (HPAGE_SIZE/PAGE_SIZE)];
+ if (!pte || pte_none(*pte)) {
+ int ret;
- WARN_ON(!PageCompound(page));
+ spin_unlock(&mm->page_table_lock);
+ ret = hugetlb_fault(mm, vma, vaddr, 0);
+ spin_lock(&mm->page_table_lock);
+ if (ret == VM_FAULT_MINOR)
+ continue;
+
+ remainder = 0;
+ if (!i)
+ i = -EFAULT;
+ break;
+ }
+ if (pages) {
+ page = &pte_page(*pte)[vpfn % (HPAGE_SIZE/PAGE_SIZE)];
get_page(page);
pages[i] = page;
}
diff --git a/mm/madvise.c b/mm/madvise.c
index 20e075d1c64c..17aaf3e16449 100644
--- a/mm/madvise.c
+++ b/mm/madvise.c
@@ -126,7 +126,7 @@ static long madvise_dontneed(struct vm_area_struct * vma,
unsigned long start, unsigned long end)
{
*prev = vma;
- if ((vma->vm_flags & VM_LOCKED) || is_vm_hugetlb_page(vma))
+ if (vma->vm_flags & (VM_LOCKED|VM_HUGETLB|VM_RESERVED))
return -EINVAL;
if (unlikely(vma->vm_flags & VM_NONLINEAR)) {
diff --git a/mm/memory.c b/mm/memory.c
index 1db40e935e55..0f60baf6f69b 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -114,6 +114,7 @@ static void free_pte_range(struct mmu_gather *tlb, pmd_t *pmd)
{
struct page *page = pmd_page(*pmd);
pmd_clear(pmd);
+ pte_lock_deinit(page);
pte_free_tlb(tlb, page);
dec_page_state(nr_page_table_pages);
tlb->mm->nr_ptes--;
@@ -249,7 +250,7 @@ void free_pgd_range(struct mmu_gather **tlb,
free_pud_range(*tlb, pgd, addr, next, floor, ceiling);
} while (pgd++, addr = next, addr != end);
- if (!tlb_is_full_mm(*tlb))
+ if (!(*tlb)->fullmm)
flush_tlb_pgtables((*tlb)->mm, start, end);
}
@@ -260,6 +261,12 @@ void free_pgtables(struct mmu_gather **tlb, struct vm_area_struct *vma,
struct vm_area_struct *next = vma->vm_next;
unsigned long addr = vma->vm_start;
+ /*
+ * Hide vma from rmap and vmtruncate before freeing pgtables
+ */
+ anon_vma_unlink(vma);
+ unlink_file_vma(vma);
+
if (is_hugepage_only_range(vma->vm_mm, addr, HPAGE_SIZE)) {
hugetlb_free_pgd_range(tlb, addr, vma->vm_end,
floor, next? next->vm_start: ceiling);
@@ -272,6 +279,8 @@ void free_pgtables(struct mmu_gather **tlb, struct vm_area_struct *vma,
HPAGE_SIZE)) {
vma = next;
next = vma->vm_next;
+ anon_vma_unlink(vma);
+ unlink_file_vma(vma);
}
free_pgd_range(tlb, addr, vma->vm_end,
floor, next? next->vm_start: ceiling);
@@ -280,72 +289,78 @@ void free_pgtables(struct mmu_gather **tlb, struct vm_area_struct *vma,
}
}
-pte_t fastcall *pte_alloc_map(struct mm_struct *mm, pmd_t *pmd,
- unsigned long address)
+int __pte_alloc(struct mm_struct *mm, pmd_t *pmd, unsigned long address)
{
- if (!pmd_present(*pmd)) {
- struct page *new;
-
- spin_unlock(&mm->page_table_lock);
- new = pte_alloc_one(mm, address);
- spin_lock(&mm->page_table_lock);
- if (!new)
- return NULL;
- /*
- * Because we dropped the lock, we should re-check the
- * entry, as somebody else could have populated it..
- */
- if (pmd_present(*pmd)) {
- pte_free(new);
- goto out;
- }
+ struct page *new = pte_alloc_one(mm, address);
+ if (!new)
+ return -ENOMEM;
+
+ pte_lock_init(new);
+ spin_lock(&mm->page_table_lock);
+ if (pmd_present(*pmd)) { /* Another has populated it */
+ pte_lock_deinit(new);
+ pte_free(new);
+ } else {
mm->nr_ptes++;
inc_page_state(nr_page_table_pages);
pmd_populate(mm, pmd, new);
}
-out:
- return pte_offset_map(pmd, address);
+ spin_unlock(&mm->page_table_lock);
+ return 0;
}
-pte_t fastcall * pte_alloc_kernel(struct mm_struct *mm, pmd_t *pmd, unsigned long address)
+int __pte_alloc_kernel(pmd_t *pmd, unsigned long address)
{
- if (!pmd_present(*pmd)) {
- pte_t *new;
+ pte_t *new = pte_alloc_one_kernel(&init_mm, address);
+ if (!new)
+ return -ENOMEM;
- spin_unlock(&mm->page_table_lock);
- new = pte_alloc_one_kernel(mm, address);
- spin_lock(&mm->page_table_lock);
- if (!new)
- return NULL;
+ spin_lock(&init_mm.page_table_lock);
+ if (pmd_present(*pmd)) /* Another has populated it */
+ pte_free_kernel(new);
+ else
+ pmd_populate_kernel(&init_mm, pmd, new);
+ spin_unlock(&init_mm.page_table_lock);
+ return 0;
+}
- /*
- * Because we dropped the lock, we should re-check the
- * entry, as somebody else could have populated it..
- */
- if (pmd_present(*pmd)) {
- pte_free_kernel(new);
- goto out;
- }
- pmd_populate_kernel(mm, pmd, new);
- }
-out:
- return pte_offset_kernel(pmd, address);
+static inline void add_mm_rss(struct mm_struct *mm, int file_rss, int anon_rss)
+{
+ if (file_rss)
+ add_mm_counter(mm, file_rss, file_rss);
+ if (anon_rss)
+ add_mm_counter(mm, anon_rss, anon_rss);
+}
+
+/*
+ * This function is called to print an error when a pte in a
+ * !VM_RESERVED region is found pointing to an invalid pfn (which
+ * is an error.
+ *
+ * The calling function must still handle the error.
+ */
+void print_bad_pte(struct vm_area_struct *vma, pte_t pte, unsigned long vaddr)
+{
+ printk(KERN_ERR "Bad pte = %08llx, process = %s, "
+ "vm_flags = %lx, vaddr = %lx\n",
+ (long long)pte_val(pte),
+ (vma->vm_mm == current->mm ? current->comm : "???"),
+ vma->vm_flags, vaddr);
+ dump_stack();
}
/*
* copy one vm_area from one task to the other. Assumes the page tables
* already present in the new task to be cleared in the whole range
* covered by this vma.
- *
- * dst->page_table_lock is held on entry and exit,
- * but may be dropped within p[mg]d_alloc() and pte_alloc_map().
*/
static inline void
copy_one_pte(struct mm_struct *dst_mm, struct mm_struct *src_mm,
- pte_t *dst_pte, pte_t *src_pte, unsigned long vm_flags,
- unsigned long addr)
+ pte_t *dst_pte, pte_t *src_pte, struct vm_area_struct *vma,
+ unsigned long addr, int *rss)
{
+ unsigned long vm_flags = vma->vm_flags;
pte_t pte = *src_pte;
struct page *page;
unsigned long pfn;
@@ -357,29 +372,32 @@ copy_one_pte(struct mm_struct *dst_mm, struct mm_struct *src_mm,
/* make sure dst_mm is on swapoff's mmlist. */
if (unlikely(list_empty(&dst_mm->mmlist))) {
spin_lock(&mmlist_lock);
- list_add(&dst_mm->mmlist, &src_mm->mmlist);
+ if (list_empty(&dst_mm->mmlist))
+ list_add(&dst_mm->mmlist,
+ &src_mm->mmlist);
spin_unlock(&mmlist_lock);
}
}
- set_pte_at(dst_mm, addr, dst_pte, pte);
- return;
+ goto out_set_pte;
}
- pfn = pte_pfn(pte);
- /* the pte points outside of valid memory, the
- * mapping is assumed to be good, meaningful
- * and not mapped via rmap - duplicate the
- * mapping as is.
+ /* If the region is VM_RESERVED, the mapping is not
+ * mapped via rmap - duplicate the pte as is.
*/
- page = NULL;
- if (pfn_valid(pfn))
- page = pfn_to_page(pfn);
+ if (vm_flags & VM_RESERVED)
+ goto out_set_pte;
- if (!page || PageReserved(page)) {
- set_pte_at(dst_mm, addr, dst_pte, pte);
- return;
+ pfn = pte_pfn(pte);
+ /* If the pte points outside of valid memory but
+ * the region is not VM_RESERVED, we have a problem.
+ */
+ if (unlikely(!pfn_valid(pfn))) {
+ print_bad_pte(vma, pte, addr);
+ goto out_set_pte; /* try to do something sane */
}
+ page = pfn_to_page(pfn);
+
/*
* If it's a COW mapping, write protect it both
* in the parent and the child
@@ -397,11 +415,11 @@ copy_one_pte(struct mm_struct *dst_mm, struct mm_struct *src_mm,
pte = pte_mkclean(pte);
pte = pte_mkold(pte);
get_page(page);
- inc_mm_counter(dst_mm, rss);
- if (PageAnon(page))
- inc_mm_counter(dst_mm, anon_rss);
- set_pte_at(dst_mm, addr, dst_pte, pte);
page_dup_rmap(page);
+ rss[!!PageAnon(page)]++;
+
+out_set_pte:
+ set_pte_at(dst_mm, addr, dst_pte, pte);
}
static int copy_pte_range(struct mm_struct *dst_mm, struct mm_struct *src_mm,
@@ -409,38 +427,44 @@ static int copy_pte_range(struct mm_struct *dst_mm, struct mm_struct *src_mm,
unsigned long addr, unsigned long end)
{
pte_t *src_pte, *dst_pte;
- unsigned long vm_flags = vma->vm_flags;
- int progress;
+ spinlock_t *src_ptl, *dst_ptl;
+ int progress = 0;
+ int rss[2];
again:
- dst_pte = pte_alloc_map(dst_mm, dst_pmd, addr);
+ rss[1] = rss[0] = 0;
+ dst_pte = pte_alloc_map_lock(dst_mm, dst_pmd, addr, &dst_ptl);
if (!dst_pte)
return -ENOMEM;
src_pte = pte_offset_map_nested(src_pmd, addr);
+ src_ptl = pte_lockptr(src_mm, src_pmd);
+ spin_lock(src_ptl);
- progress = 0;
- spin_lock(&src_mm->page_table_lock);
do {
/*
* We are holding two locks at this point - either of them
* could generate latencies in another task on another CPU.
*/
- if (progress >= 32 && (need_resched() ||
- need_lockbreak(&src_mm->page_table_lock) ||
- need_lockbreak(&dst_mm->page_table_lock)))
- break;
+ if (progress >= 32) {
+ progress = 0;
+ if (need_resched() ||
+ need_lockbreak(src_ptl) ||
+ need_lockbreak(dst_ptl))
+ break;
+ }
if (pte_none(*src_pte)) {
progress++;
continue;
}
- copy_one_pte(dst_mm, src_mm, dst_pte, src_pte, vm_flags, addr);
+ copy_one_pte(dst_mm, src_mm, dst_pte, src_pte, vma, addr, rss);
progress += 8;
} while (dst_pte++, src_pte++, addr += PAGE_SIZE, addr != end);
- spin_unlock(&src_mm->page_table_lock);
+ spin_unlock(src_ptl);
pte_unmap_nested(src_pte - 1);
- pte_unmap(dst_pte - 1);
- cond_resched_lock(&dst_mm->page_table_lock);
+ add_mm_rss(dst_mm, rss[0], rss[1]);
+ pte_unmap_unlock(dst_pte - 1, dst_ptl);
+ cond_resched();
if (addr != end)
goto again;
return 0;
@@ -525,24 +549,30 @@ int copy_page_range(struct mm_struct *dst_mm, struct mm_struct *src_mm,
return 0;
}
-static void zap_pte_range(struct mmu_gather *tlb, pmd_t *pmd,
+static void zap_pte_range(struct mmu_gather *tlb,
+ struct vm_area_struct *vma, pmd_t *pmd,
unsigned long addr, unsigned long end,
struct zap_details *details)
{
+ struct mm_struct *mm = tlb->mm;
pte_t *pte;
+ spinlock_t *ptl;
+ int file_rss = 0;
+ int anon_rss = 0;
- pte = pte_offset_map(pmd, addr);
+ pte = pte_offset_map_lock(mm, pmd, addr, &ptl);
do {
pte_t ptent = *pte;
if (pte_none(ptent))
continue;
if (pte_present(ptent)) {
struct page *page = NULL;
- unsigned long pfn = pte_pfn(ptent);
- if (pfn_valid(pfn)) {
- page = pfn_to_page(pfn);
- if (PageReserved(page))
- page = NULL;
+ if (!(vma->vm_flags & VM_RESERVED)) {
+ unsigned long pfn = pte_pfn(ptent);
+ if (unlikely(!pfn_valid(pfn)))
+ print_bad_pte(vma, ptent, addr);
+ else
+ page = pfn_to_page(pfn);
}
if (unlikely(details) && page) {
/*
@@ -562,7 +592,7 @@ static void zap_pte_range(struct mmu_gather *tlb, pmd_t *pmd,
page->index > details->last_index))
continue;
}
- ptent = ptep_get_and_clear_full(tlb->mm, addr, pte,
+ ptent = ptep_get_and_clear_full(mm, addr, pte,
tlb->fullmm);
tlb_remove_tlb_entry(tlb, pte, addr);
if (unlikely(!page))
@@ -570,15 +600,17 @@ static void zap_pte_range(struct mmu_gather *tlb, pmd_t *pmd,
if (unlikely(details) && details->nonlinear_vma
&& linear_page_index(details->nonlinear_vma,
addr) != page->index)
- set_pte_at(tlb->mm, addr, pte,
+ set_pte_at(mm, addr, pte,
pgoff_to_pte(page->index));
- if (pte_dirty(ptent))
- set_page_dirty(page);
if (PageAnon(page))
- dec_mm_counter(tlb->mm, anon_rss);
- else if (pte_young(ptent))
- mark_page_accessed(page);
- tlb->freed++;
+ anon_rss--;
+ else {
+ if (pte_dirty(ptent))
+ set_page_dirty(page);
+ if (pte_young(ptent))
+ mark_page_accessed(page);
+ file_rss--;
+ }
page_remove_rmap(page);
tlb_remove_page(tlb, page);
continue;
@@ -591,12 +623,15 @@ static void zap_pte_range(struct mmu_gather *tlb, pmd_t *pmd,
continue;
if (!pte_file(ptent))
free_swap_and_cache(pte_to_swp_entry(ptent));
- pte_clear_full(tlb->mm, addr, pte, tlb->fullmm);
+ pte_clear_full(mm, addr, pte, tlb->fullmm);
} while (pte++, addr += PAGE_SIZE, addr != end);
- pte_unmap(pte - 1);
+
+ add_mm_rss(mm, file_rss, anon_rss);
+ pte_unmap_unlock(pte - 1, ptl);
}
-static inline void zap_pmd_range(struct mmu_gather *tlb, pud_t *pud,
+static inline void zap_pmd_range(struct mmu_gather *tlb,
+ struct vm_area_struct *vma, pud_t *pud,
unsigned long addr, unsigned long end,
struct zap_details *details)
{
@@ -608,11 +643,12 @@ static inline void zap_pmd_range(struct mmu_gather *tlb, pud_t *pud,
next = pmd_addr_end(addr, end);
if (pmd_none_or_clear_bad(pmd))
continue;
- zap_pte_range(tlb, pmd, addr, next, details);
+ zap_pte_range(tlb, vma, pmd, addr, next, details);
} while (pmd++, addr = next, addr != end);
}
-static inline void zap_pud_range(struct mmu_gather *tlb, pgd_t *pgd,
+static inline void zap_pud_range(struct mmu_gather *tlb,
+ struct vm_area_struct *vma, pgd_t *pgd,
unsigned long addr, unsigned long end,
struct zap_details *details)
{
@@ -624,7 +660,7 @@ static inline void zap_pud_range(struct mmu_gather *tlb, pgd_t *pgd,
next = pud_addr_end(addr, end);
if (pud_none_or_clear_bad(pud))
continue;
- zap_pmd_range(tlb, pud, addr, next, details);
+ zap_pmd_range(tlb, vma, pud, addr, next, details);
} while (pud++, addr = next, addr != end);
}
@@ -645,7 +681,7 @@ static void unmap_page_range(struct mmu_gather *tlb, struct vm_area_struct *vma,
next = pgd_addr_end(addr, end);
if (pgd_none_or_clear_bad(pgd))
continue;
- zap_pud_range(tlb, pgd, addr, next, details);
+ zap_pud_range(tlb, vma, pgd, addr, next, details);
} while (pgd++, addr = next, addr != end);
tlb_end_vma(tlb, vma);
}
@@ -660,7 +696,6 @@ static void unmap_page_range(struct mmu_gather *tlb, struct vm_area_struct *vma,
/**
* unmap_vmas - unmap a range of memory covered by a list of vma's
* @tlbp: address of the caller's struct mmu_gather
- * @mm: the controlling mm_struct
* @vma: the starting vma
* @start_addr: virtual address at which to start unmapping
* @end_addr: virtual address at which to end unmapping
@@ -669,10 +704,10 @@ static void unmap_page_range(struct mmu_gather *tlb, struct vm_area_struct *vma,
*
* Returns the end address of the unmapping (restart addr if interrupted).
*
- * Unmap all pages in the vma list. Called under page_table_lock.
+ * Unmap all pages in the vma list.
*
- * We aim to not hold page_table_lock for too long (for scheduling latency
- * reasons). So zap pages in ZAP_BLOCK_SIZE bytecounts. This means we need to
+ * We aim to not hold locks for too long (for scheduling latency reasons).
+ * So zap pages in ZAP_BLOCK_SIZE bytecounts. This means we need to
* return the ending mmu_gather to the caller.
*
* Only addresses between `start' and `end' will be unmapped.
@@ -684,7 +719,7 @@ static void unmap_page_range(struct mmu_gather *tlb, struct vm_area_struct *vma,
* ensure that any thus-far unmapped pages are flushed before unmap_vmas()
* drops the lock and schedules.
*/
-unsigned long unmap_vmas(struct mmu_gather **tlbp, struct mm_struct *mm,
+unsigned long unmap_vmas(struct mmu_gather **tlbp,
struct vm_area_struct *vma, unsigned long start_addr,
unsigned long end_addr, unsigned long *nr_accounted,
struct zap_details *details)
@@ -694,7 +729,7 @@ unsigned long unmap_vmas(struct mmu_gather **tlbp, struct mm_struct *mm,
int tlb_start_valid = 0;
unsigned long start = start_addr;
spinlock_t *i_mmap_lock = details? details->i_mmap_lock: NULL;
- int fullmm = tlb_is_full_mm(*tlbp);
+ int fullmm = (*tlbp)->fullmm;
for ( ; vma && vma->vm_start < end_addr; vma = vma->vm_next) {
unsigned long end;
@@ -734,19 +769,15 @@ unsigned long unmap_vmas(struct mmu_gather **tlbp, struct mm_struct *mm,
tlb_finish_mmu(*tlbp, tlb_start, start);
if (need_resched() ||
- need_lockbreak(&mm->page_table_lock) ||
(i_mmap_lock && need_lockbreak(i_mmap_lock))) {
if (i_mmap_lock) {
- /* must reset count of rss freed */
- *tlbp = tlb_gather_mmu(mm, fullmm);
+ *tlbp = NULL;
goto out;
}
- spin_unlock(&mm->page_table_lock);
cond_resched();
- spin_lock(&mm->page_table_lock);
}
- *tlbp = tlb_gather_mmu(mm, fullmm);
+ *tlbp = tlb_gather_mmu(vma->vm_mm, fullmm);
tlb_start_valid = 0;
zap_bytes = ZAP_BLOCK_SIZE;
}
@@ -770,123 +801,93 @@ unsigned long zap_page_range(struct vm_area_struct *vma, unsigned long address,
unsigned long end = address + size;
unsigned long nr_accounted = 0;
- if (is_vm_hugetlb_page(vma)) {
- zap_hugepage_range(vma, address, size);
- return end;
- }
-
lru_add_drain();
- spin_lock(&mm->page_table_lock);
tlb = tlb_gather_mmu(mm, 0);
- end = unmap_vmas(&tlb, mm, vma, address, end, &nr_accounted, details);
- tlb_finish_mmu(tlb, address, end);
- spin_unlock(&mm->page_table_lock);
+ update_hiwater_rss(mm);
+ end = unmap_vmas(&tlb, vma, address, end, &nr_accounted, details);
+ if (tlb)
+ tlb_finish_mmu(tlb, address, end);
return end;
}
/*
* Do a quick page-table lookup for a single page.
- * mm->page_table_lock must be held.
*/
-static struct page *__follow_page(struct mm_struct *mm, unsigned long address,
- int read, int write, int accessed)
+struct page *follow_page(struct mm_struct *mm, unsigned long address,
+ unsigned int flags)
{
pgd_t *pgd;
pud_t *pud;
pmd_t *pmd;
pte_t *ptep, pte;
+ spinlock_t *ptl;
unsigned long pfn;
struct page *page;
- page = follow_huge_addr(mm, address, write);
- if (! IS_ERR(page))
- return page;
+ page = follow_huge_addr(mm, address, flags & FOLL_WRITE);
+ if (!IS_ERR(page)) {
+ BUG_ON(flags & FOLL_GET);
+ goto out;
+ }
+ page = NULL;
pgd = pgd_offset(mm, address);
if (pgd_none(*pgd) || unlikely(pgd_bad(*pgd)))
- goto out;
+ goto no_page_table;
pud = pud_offset(pgd, address);
if (pud_none(*pud) || unlikely(pud_bad(*pud)))
- goto out;
+ goto no_page_table;
pmd = pmd_offset(pud, address);
if (pmd_none(*pmd) || unlikely(pmd_bad(*pmd)))
+ goto no_page_table;
+
+ if (pmd_huge(*pmd)) {
+ BUG_ON(flags & FOLL_GET);
+ page = follow_huge_pmd(mm, address, pmd, flags & FOLL_WRITE);
goto out;
- if (pmd_huge(*pmd))
- return follow_huge_pmd(mm, address, pmd, write);
+ }
- ptep = pte_offset_map(pmd, address);
+ ptep = pte_offset_map_lock(mm, pmd, address, &ptl);
if (!ptep)
goto out;
pte = *ptep;
- pte_unmap(ptep);
- if (pte_present(pte)) {
- if (write && !pte_write(pte))
- goto out;
- if (read && !pte_read(pte))
- goto out;
- pfn = pte_pfn(pte);
- if (pfn_valid(pfn)) {
- page = pfn_to_page(pfn);
- if (accessed) {
- if (write && !pte_dirty(pte) &&!PageDirty(page))
- set_page_dirty(page);
- mark_page_accessed(page);
- }
- return page;
- }
+ if (!pte_present(pte))
+ goto unlock;
+ if ((flags & FOLL_WRITE) && !pte_write(pte))
+ goto unlock;
+ pfn = pte_pfn(pte);
+ if (!pfn_valid(pfn))
+ goto unlock;
+
+ page = pfn_to_page(pfn);
+ if (flags & FOLL_GET)
+ get_page(page);
+ if (flags & FOLL_TOUCH) {
+ if ((flags & FOLL_WRITE) &&
+ !pte_dirty(pte) && !PageDirty(page))
+ set_page_dirty(page);
+ mark_page_accessed(page);
}
-
+unlock:
+ pte_unmap_unlock(ptep, ptl);
out:
- return NULL;
-}
-
-inline struct page *
-follow_page(struct mm_struct *mm, unsigned long address, int write)
-{
- return __follow_page(mm, address, 0, write, 1);
-}
-
-/*
- * check_user_page_readable() can be called frm niterrupt context by oprofile,
- * so we need to avoid taking any non-irq-safe locks
- */
-int check_user_page_readable(struct mm_struct *mm, unsigned long address)
-{
- return __follow_page(mm, address, 1, 0, 0) != NULL;
-}
-EXPORT_SYMBOL(check_user_page_readable);
-
-static inline int
-untouched_anonymous_page(struct mm_struct* mm, struct vm_area_struct *vma,
- unsigned long address)
-{
- pgd_t *pgd;
- pud_t *pud;
- pmd_t *pmd;
-
- /* Check if the vma is for an anonymous mapping. */
- if (vma->vm_ops && vma->vm_ops->nopage)
- return 0;
-
- /* Check if page directory entry exists. */
- pgd = pgd_offset(mm, address);
- if (pgd_none(*pgd) || unlikely(pgd_bad(*pgd)))
- return 1;
-
- pud = pud_offset(pgd, address);
- if (pud_none(*pud) || unlikely(pud_bad(*pud)))
- return 1;
-
- /* Check if page middle directory entry exists. */
- pmd = pmd_offset(pud, address);
- if (pmd_none(*pmd) || unlikely(pmd_bad(*pmd)))
- return 1;
+ return page;
- /* There is a pte slot for 'address' in 'mm'. */
- return 0;
+no_page_table:
+ /*
+ * When core dumping an enormous anonymous area that nobody
+ * has touched so far, we don't want to allocate page tables.
+ */
+ if (flags & FOLL_ANON) {
+ page = ZERO_PAGE(address);
+ if (flags & FOLL_GET)
+ get_page(page);
+ BUG_ON(flags & FOLL_WRITE);
+ }
+ return page;
}
int get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
@@ -894,18 +895,19 @@ int get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
struct page **pages, struct vm_area_struct **vmas)
{
int i;
- unsigned int flags;
+ unsigned int vm_flags;
/*
* Require read or write permissions.
* If 'force' is set, we only require the "MAY" flags.
*/
- flags = write ? (VM_WRITE | VM_MAYWRITE) : (VM_READ | VM_MAYREAD);
- flags &= force ? (VM_MAYREAD | VM_MAYWRITE) : (VM_READ | VM_WRITE);
+ vm_flags = write ? (VM_WRITE | VM_MAYWRITE) : (VM_READ | VM_MAYREAD);
+ vm_flags &= force ? (VM_MAYREAD | VM_MAYWRITE) : (VM_READ | VM_WRITE);
i = 0;
do {
- struct vm_area_struct * vma;
+ struct vm_area_struct *vma;
+ unsigned int foll_flags;
vma = find_extend_vma(mm, start);
if (!vma && in_gate_area(tsk, start)) {
@@ -945,8 +947,8 @@ int get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
continue;
}
- if (!vma || (vma->vm_flags & VM_IO)
- || !(flags & vma->vm_flags))
+ if (!vma || (vma->vm_flags & (VM_IO | VM_RESERVED))
+ || !(vm_flags & vma->vm_flags))
return i ? : -EFAULT;
if (is_vm_hugetlb_page(vma)) {
@@ -954,29 +956,25 @@ int get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
&start, &len, i);
continue;
}
- spin_lock(&mm->page_table_lock);
+
+ foll_flags = FOLL_TOUCH;
+ if (pages)
+ foll_flags |= FOLL_GET;
+ if (!write && !(vma->vm_flags & VM_LOCKED) &&
+ (!vma->vm_ops || !vma->vm_ops->nopage))
+ foll_flags |= FOLL_ANON;
+
do {
- int write_access = write;
struct page *page;
- cond_resched_lock(&mm->page_table_lock);
- while (!(page = follow_page(mm, start, write_access))) {
- int ret;
-
- /*
- * Shortcut for anonymous pages. We don't want
- * to force the creation of pages tables for
- * insanely big anonymously mapped areas that
- * nobody touched so far. This is important
- * for doing a core dump for these mappings.
- */
- if (!write && untouched_anonymous_page(mm,vma,start)) {
- page = ZERO_PAGE(start);
- break;
- }
- spin_unlock(&mm->page_table_lock);
- ret = __handle_mm_fault(mm, vma, start, write_access);
+ if (write)
+ foll_flags |= FOLL_WRITE;
+ cond_resched();
+ while (!(page = follow_page(mm, start, foll_flags))) {
+ int ret;
+ ret = __handle_mm_fault(mm, vma, start,
+ foll_flags & FOLL_WRITE);
/*
* The VM_FAULT_WRITE bit tells us that do_wp_page has
* broken COW when necessary, even if maybe_mkwrite
@@ -984,7 +982,7 @@ int get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
* subsequent page lookups as if they were reads.
*/
if (ret & VM_FAULT_WRITE)
- write_access = 0;
+ foll_flags &= ~FOLL_WRITE;
switch (ret & ~VM_FAULT_WRITE) {
case VM_FAULT_MINOR:
@@ -1000,13 +998,10 @@ int get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
default:
BUG();
}
- spin_lock(&mm->page_table_lock);
}
if (pages) {
pages[i] = page;
flush_dcache_page(page);
- if (!PageReserved(page))
- page_cache_get(page);
}
if (vmas)
vmas[i] = vma;
@@ -1014,7 +1009,6 @@ int get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
start += PAGE_SIZE;
len--;
} while (len && start < vma->vm_end);
- spin_unlock(&mm->page_table_lock);
} while (len);
return i;
}
@@ -1024,16 +1018,21 @@ static int zeromap_pte_range(struct mm_struct *mm, pmd_t *pmd,
unsigned long addr, unsigned long end, pgprot_t prot)
{
pte_t *pte;
+ spinlock_t *ptl;
- pte = pte_alloc_map(mm, pmd, addr);
+ pte = pte_alloc_map_lock(mm, pmd, addr, &ptl);
if (!pte)
return -ENOMEM;
do {
- pte_t zero_pte = pte_wrprotect(mk_pte(ZERO_PAGE(addr), prot));
+ struct page *page = ZERO_PAGE(addr);
+ pte_t zero_pte = pte_wrprotect(mk_pte(page, prot));
+ page_cache_get(page);
+ page_add_file_rmap(page);
+ inc_mm_counter(mm, file_rss);
BUG_ON(!pte_none(*pte));
set_pte_at(mm, addr, pte, zero_pte);
} while (pte++, addr += PAGE_SIZE, addr != end);
- pte_unmap(pte - 1);
+ pte_unmap_unlock(pte - 1, ptl);
return 0;
}
@@ -1083,14 +1082,12 @@ int zeromap_page_range(struct vm_area_struct *vma,
BUG_ON(addr >= end);
pgd = pgd_offset(mm, addr);
flush_cache_range(vma, addr, end);
- spin_lock(&mm->page_table_lock);
do {
next = pgd_addr_end(addr, end);
err = zeromap_pud_range(mm, pgd, addr, next, prot);
if (err)
break;
} while (pgd++, addr = next, addr != end);
- spin_unlock(&mm->page_table_lock);
return err;
}
@@ -1104,17 +1101,17 @@ static int remap_pte_range(struct mm_struct *mm, pmd_t *pmd,
unsigned long pfn, pgprot_t prot)
{
pte_t *pte;
+ spinlock_t *ptl;
- pte = pte_alloc_map(mm, pmd, addr);
+ pte = pte_alloc_map_lock(mm, pmd, addr, &ptl);
if (!pte)
return -ENOMEM;
do {
BUG_ON(!pte_none(*pte));
- if (!pfn_valid(pfn) || PageReserved(pfn_to_page(pfn)))
- set_pte_at(mm, addr, pte, pfn_pte(pfn, prot));
+ set_pte_at(mm, addr, pte, pfn_pte(pfn, prot));
pfn++;
} while (pte++, addr += PAGE_SIZE, addr != end);
- pte_unmap(pte - 1);
+ pte_unmap_unlock(pte - 1, ptl);
return 0;
}
@@ -1173,8 +1170,8 @@ int remap_pfn_range(struct vm_area_struct *vma, unsigned long addr,
* rest of the world about it:
* VM_IO tells people not to look at these pages
* (accesses can have side effects).
- * VM_RESERVED tells swapout not to try to touch
- * this region.
+ * VM_RESERVED tells the core MM not to "manage" these pages
+ * (e.g. refcount, mapcount, try to swap them out).
*/
vma->vm_flags |= VM_IO | VM_RESERVED;
@@ -1182,7 +1179,6 @@ int remap_pfn_range(struct vm_area_struct *vma, unsigned long addr,
pfn -= addr >> PAGE_SHIFT;
pgd = pgd_offset(mm, addr);
flush_cache_range(vma, addr, end);
- spin_lock(&mm->page_table_lock);
do {
next = pgd_addr_end(addr, end);
err = remap_pud_range(mm, pgd, addr, next,
@@ -1190,12 +1186,36 @@ int remap_pfn_range(struct vm_area_struct *vma, unsigned long addr,
if (err)
break;
} while (pgd++, addr = next, addr != end);
- spin_unlock(&mm->page_table_lock);
return err;
}
EXPORT_SYMBOL(remap_pfn_range);
/*
+ * handle_pte_fault chooses page fault handler according to an entry
+ * which was read non-atomically. Before making any commitment, on
+ * those architectures or configurations (e.g. i386 with PAE) which
+ * might give a mix of unmatched parts, do_swap_page and do_file_page
+ * must check under lock before unmapping the pte and proceeding
+ * (but do_wp_page is only called after already making such a check;
+ * and do_anonymous_page and do_no_page can safely check later on).
+ */
+static inline int pte_unmap_same(struct mm_struct *mm, pmd_t *pmd,
+ pte_t *page_table, pte_t orig_pte)
+{
+ int same = 1;
+#if defined(CONFIG_SMP) || defined(CONFIG_PREEMPT)
+ if (sizeof(pte_t) > sizeof(unsigned long)) {
+ spinlock_t *ptl = pte_lockptr(mm, pmd);
+ spin_lock(ptl);
+ same = pte_same(*page_table, orig_pte);
+ spin_unlock(ptl);
+ }
+#endif
+ pte_unmap(page_table);
+ return same;
+}
+
+/*
* Do pte_mkwrite, but only if the vma says VM_WRITE. We do this when
* servicing faults for write access. In the normal case, do always want
* pte_mkwrite. But get_user_pages can cause write faults for mappings
@@ -1209,28 +1229,10 @@ static inline pte_t maybe_mkwrite(pte_t pte, struct vm_area_struct *vma)
}
/*
- * We hold the mm semaphore for reading and vma->vm_mm->page_table_lock
- */
-static inline void break_cow(struct vm_area_struct * vma, struct page * new_page, unsigned long address,
- pte_t *page_table)
-{
- pte_t entry;
-
- entry = maybe_mkwrite(pte_mkdirty(mk_pte(new_page, vma->vm_page_prot)),
- vma);
- ptep_establish(vma, address, page_table, entry);
- update_mmu_cache(vma, address, entry);
- lazy_mmu_prot_update(entry);
-}
-
-/*
* This routine handles present pages, when users try to write
* to a shared page. It is done by copying the page to a new address
* and decrementing the shared-page counter for the old page.
*
- * Goto-purists beware: the only reason for goto's here is that it results
- * in better assembly code.. The "default" path will see no jumps at all.
- *
* Note that this routine assumes that the protection checks have been
* done by the caller (the low-level page fault routine in most cases).
* Thus we can safely just mark it writable once we've done any necessary
@@ -1240,28 +1242,28 @@ static inline void break_cow(struct vm_area_struct * vma, struct page * new_page
* change only once the write actually happens. This avoids a few races,
* and potentially makes it more efficient.
*
- * We hold the mm semaphore and the page_table_lock on entry and exit
- * with the page_table_lock released.
+ * We enter with non-exclusive mmap_sem (to exclude vma changes,
+ * but allow concurrent faults), with pte both mapped and locked.
+ * We return with mmap_sem still held, but pte unmapped and unlocked.
*/
-static int do_wp_page(struct mm_struct *mm, struct vm_area_struct * vma,
- unsigned long address, pte_t *page_table, pmd_t *pmd, pte_t pte)
+static int do_wp_page(struct mm_struct *mm, struct vm_area_struct *vma,
+ unsigned long address, pte_t *page_table, pmd_t *pmd,
+ spinlock_t *ptl, pte_t orig_pte)
{
struct page *old_page, *new_page;
- unsigned long pfn = pte_pfn(pte);
+ unsigned long pfn = pte_pfn(orig_pte);
pte_t entry;
- int ret;
+ int ret = VM_FAULT_MINOR;
+
+ BUG_ON(vma->vm_flags & VM_RESERVED);
if (unlikely(!pfn_valid(pfn))) {
/*
- * This should really halt the system so it can be debugged or
- * at least the kernel stops what it's doing before it corrupts
- * data, but for the moment just pretend this is OOM.
+ * Page table corrupted: show pte and kill process.
*/
- pte_unmap(page_table);
- printk(KERN_ERR "do_wp_page: bogus page at address %08lx\n",
- address);
- spin_unlock(&mm->page_table_lock);
- return VM_FAULT_OOM;
+ print_bad_pte(vma, orig_pte, address);
+ ret = VM_FAULT_OOM;
+ goto unlock;
}
old_page = pfn_to_page(pfn);
@@ -1270,52 +1272,51 @@ static int do_wp_page(struct mm_struct *mm, struct vm_area_struct * vma,
unlock_page(old_page);
if (reuse) {
flush_cache_page(vma, address, pfn);
- entry = maybe_mkwrite(pte_mkyoung(pte_mkdirty(pte)),
- vma);
+ entry = pte_mkyoung(orig_pte);
+ entry = maybe_mkwrite(pte_mkdirty(entry), vma);
ptep_set_access_flags(vma, address, page_table, entry, 1);
update_mmu_cache(vma, address, entry);
lazy_mmu_prot_update(entry);
- pte_unmap(page_table);
- spin_unlock(&mm->page_table_lock);
- return VM_FAULT_MINOR|VM_FAULT_WRITE;
+ ret |= VM_FAULT_WRITE;
+ goto unlock;
}
}
- pte_unmap(page_table);
/*
* Ok, we need to copy. Oh, well..
*/
- if (!PageReserved(old_page))
- page_cache_get(old_page);
- spin_unlock(&mm->page_table_lock);
+ page_cache_get(old_page);
+ pte_unmap_unlock(page_table, ptl);
if (unlikely(anon_vma_prepare(vma)))
- goto no_new_page;
+ goto oom;
if (old_page == ZERO_PAGE(address)) {
new_page = alloc_zeroed_user_highpage(vma, address);
if (!new_page)
- goto no_new_page;
+ goto oom;
} else {
new_page = alloc_page_vma(GFP_HIGHUSER, vma, address);
if (!new_page)
- goto no_new_page;
+ goto oom;
copy_user_highpage(new_page, old_page, address);
}
+
/*
* Re-check the pte - we dropped the lock
*/
- ret = VM_FAULT_MINOR;
- spin_lock(&mm->page_table_lock);
- page_table = pte_offset_map(pmd, address);
- if (likely(pte_same(*page_table, pte))) {
- if (PageAnon(old_page))
- dec_mm_counter(mm, anon_rss);
- if (PageReserved(old_page))
- inc_mm_counter(mm, rss);
- else
- page_remove_rmap(old_page);
+ page_table = pte_offset_map_lock(mm, pmd, address, &ptl);
+ if (likely(pte_same(*page_table, orig_pte))) {
+ page_remove_rmap(old_page);
+ if (!PageAnon(old_page)) {
+ inc_mm_counter(mm, anon_rss);
+ dec_mm_counter(mm, file_rss);
+ }
flush_cache_page(vma, address, pfn);
- break_cow(vma, new_page, address, page_table);
+ entry = mk_pte(new_page, vma->vm_page_prot);
+ entry = maybe_mkwrite(pte_mkdirty(entry), vma);
+ ptep_establish(vma, address, page_table, entry);
+ update_mmu_cache(vma, address, entry);
+ lazy_mmu_prot_update(entry);
lru_cache_add_active(new_page);
page_add_anon_rmap(new_page, vma, address);
@@ -1323,13 +1324,12 @@ static int do_wp_page(struct mm_struct *mm, struct vm_area_struct * vma,
new_page = old_page;
ret |= VM_FAULT_WRITE;
}
- pte_unmap(page_table);
page_cache_release(new_page);
page_cache_release(old_page);
- spin_unlock(&mm->page_table_lock);
+unlock:
+ pte_unmap_unlock(page_table, ptl);
return ret;
-
-no_new_page:
+oom:
page_cache_release(old_page);
return VM_FAULT_OOM;
}
@@ -1399,13 +1399,6 @@ again:
restart_addr = zap_page_range(vma, start_addr,
end_addr - start_addr, details);
-
- /*
- * We cannot rely on the break test in unmap_vmas:
- * on the one hand, we don't want to restart our loop
- * just because that broke out for the page_table_lock;
- * on the other hand, it does no test when vma is small.
- */
need_break = need_resched() ||
need_lockbreak(details->i_mmap_lock);
@@ -1654,38 +1647,37 @@ void swapin_readahead(swp_entry_t entry, unsigned long addr,struct vm_area_struc
}
/*
- * We hold the mm semaphore and the page_table_lock on entry and
- * should release the pagetable lock on exit..
+ * We enter with non-exclusive mmap_sem (to exclude vma changes,
+ * but allow concurrent faults), and pte mapped but not yet locked.
+ * We return with mmap_sem still held, but pte unmapped and unlocked.
*/
-static int do_swap_page(struct mm_struct * mm,
- struct vm_area_struct * vma, unsigned long address,
- pte_t *page_table, pmd_t *pmd, pte_t orig_pte, int write_access)
+static int do_swap_page(struct mm_struct *mm, struct vm_area_struct *vma,
+ unsigned long address, pte_t *page_table, pmd_t *pmd,
+ int write_access, pte_t orig_pte)
{
+ spinlock_t *ptl;
struct page *page;
- swp_entry_t entry = pte_to_swp_entry(orig_pte);
+ swp_entry_t entry;
pte_t pte;
int ret = VM_FAULT_MINOR;
- pte_unmap(page_table);
- spin_unlock(&mm->page_table_lock);
+ if (!pte_unmap_same(mm, pmd, page_table, orig_pte))
+ goto out;
+
+ entry = pte_to_swp_entry(orig_pte);
page = lookup_swap_cache(entry);
if (!page) {
swapin_readahead(entry, address, vma);
page = read_swap_cache_async(entry, vma, address);
if (!page) {
/*
- * Back out if somebody else faulted in this pte while
- * we released the page table lock.
+ * Back out if somebody else faulted in this pte
+ * while we released the pte lock.
*/
- spin_lock(&mm->page_table_lock);
- page_table = pte_offset_map(pmd, address);
+ page_table = pte_offset_map_lock(mm, pmd, address, &ptl);
if (likely(pte_same(*page_table, orig_pte)))
ret = VM_FAULT_OOM;
- else
- ret = VM_FAULT_MINOR;
- pte_unmap(page_table);
- spin_unlock(&mm->page_table_lock);
- goto out;
+ goto unlock;
}
/* Had to read the page from swap area: Major fault */
@@ -1698,15 +1690,11 @@ static int do_swap_page(struct mm_struct * mm,
lock_page(page);
/*
- * Back out if somebody else faulted in this pte while we
- * released the page table lock.
+ * Back out if somebody else already faulted in this pte.
*/
- spin_lock(&mm->page_table_lock);
- page_table = pte_offset_map(pmd, address);
- if (unlikely(!pte_same(*page_table, orig_pte))) {
- ret = VM_FAULT_MINOR;
+ page_table = pte_offset_map_lock(mm, pmd, address, &ptl);
+ if (unlikely(!pte_same(*page_table, orig_pte)))
goto out_nomap;
- }
if (unlikely(!PageUptodate(page))) {
ret = VM_FAULT_SIGBUS;
@@ -1715,7 +1703,7 @@ static int do_swap_page(struct mm_struct * mm,
/* The page isn't present yet, go ahead with the fault. */
- inc_mm_counter(mm, rss);
+ inc_mm_counter(mm, anon_rss);
pte = mk_pte(page, vma->vm_page_prot);
if (write_access && can_share_swap_page(page)) {
pte = maybe_mkwrite(pte_mkdirty(pte), vma);
@@ -1733,7 +1721,7 @@ static int do_swap_page(struct mm_struct * mm,
if (write_access) {
if (do_wp_page(mm, vma, address,
- page_table, pmd, pte) == VM_FAULT_OOM)
+ page_table, pmd, ptl, pte) == VM_FAULT_OOM)
ret = VM_FAULT_OOM;
goto out;
}
@@ -1741,74 +1729,76 @@ static int do_swap_page(struct mm_struct * mm,
/* No need to invalidate - it was non-present before */
update_mmu_cache(vma, address, pte);
lazy_mmu_prot_update(pte);
- pte_unmap(page_table);
- spin_unlock(&mm->page_table_lock);
+unlock:
+ pte_unmap_unlock(page_table, ptl);
out:
return ret;
out_nomap:
- pte_unmap(page_table);
- spin_unlock(&mm->page_table_lock);
+ pte_unmap_unlock(page_table, ptl);
unlock_page(page);
page_cache_release(page);
- goto out;
+ return ret;
}
/*
- * We are called with the MM semaphore and page_table_lock
- * spinlock held to protect against concurrent faults in
- * multithreaded programs.
+ * We enter with non-exclusive mmap_sem (to exclude vma changes,
+ * but allow concurrent faults), and pte mapped but not yet locked.
+ * We return with mmap_sem still held, but pte unmapped and unlocked.
*/
-static int
-do_anonymous_page(struct mm_struct *mm, struct vm_area_struct *vma,
- pte_t *page_table, pmd_t *pmd, int write_access,
- unsigned long addr)
+static int do_anonymous_page(struct mm_struct *mm, struct vm_area_struct *vma,
+ unsigned long address, pte_t *page_table, pmd_t *pmd,
+ int write_access)
{
+ struct page *page;
+ spinlock_t *ptl;
pte_t entry;
- struct page * page = ZERO_PAGE(addr);
-
- /* Read-only mapping of ZERO_PAGE. */
- entry = pte_wrprotect(mk_pte(ZERO_PAGE(addr), vma->vm_page_prot));
- /* ..except if it's a write access */
if (write_access) {
/* Allocate our own private page. */
pte_unmap(page_table);
- spin_unlock(&mm->page_table_lock);
if (unlikely(anon_vma_prepare(vma)))
- goto no_mem;
- page = alloc_zeroed_user_highpage(vma, addr);
+ goto oom;
+ page = alloc_zeroed_user_highpage(vma, address);
if (!page)
- goto no_mem;
+ goto oom;
- spin_lock(&mm->page_table_lock);
- page_table = pte_offset_map(pmd, addr);
+ entry = mk_pte(page, vma->vm_page_prot);
+ entry = maybe_mkwrite(pte_mkdirty(entry), vma);
- if (!pte_none(*page_table)) {
- pte_unmap(page_table);
- page_cache_release(page);
- spin_unlock(&mm->page_table_lock);
- goto out;
- }
- inc_mm_counter(mm, rss);
- entry = maybe_mkwrite(pte_mkdirty(mk_pte(page,
- vma->vm_page_prot)),
- vma);
+ page_table = pte_offset_map_lock(mm, pmd, address, &ptl);
+ if (!pte_none(*page_table))
+ goto release;
+ inc_mm_counter(mm, anon_rss);
lru_cache_add_active(page);
SetPageReferenced(page);
- page_add_anon_rmap(page, vma, addr);
+ page_add_anon_rmap(page, vma, address);
+ } else {
+ /* Map the ZERO_PAGE - vm_page_prot is readonly */
+ page = ZERO_PAGE(address);
+ page_cache_get(page);
+ entry = mk_pte(page, vma->vm_page_prot);
+
+ ptl = pte_lockptr(mm, pmd);
+ spin_lock(ptl);
+ if (!pte_none(*page_table))
+ goto release;
+ inc_mm_counter(mm, file_rss);
+ page_add_file_rmap(page);
}
- set_pte_at(mm, addr, page_table, entry);
- pte_unmap(page_table);
+ set_pte_at(mm, address, page_table, entry);
/* No need to invalidate - it was non-present before */
- update_mmu_cache(vma, addr, entry);
+ update_mmu_cache(vma, address, entry);
lazy_mmu_prot_update(entry);
- spin_unlock(&mm->page_table_lock);
-out:
+unlock:
+ pte_unmap_unlock(page_table, ptl);
return VM_FAULT_MINOR;
-no_mem:
+release:
+ page_cache_release(page);
+ goto unlock;
+oom:
return VM_FAULT_OOM;
}
@@ -1821,25 +1811,23 @@ no_mem:
* As this is called only for pages that do not currently exist, we
* do not need to flush old virtual caches or the TLB.
*
- * This is called with the MM semaphore held and the page table
- * spinlock held. Exit with the spinlock released.
+ * We enter with non-exclusive mmap_sem (to exclude vma changes,
+ * but allow concurrent faults), and pte mapped but not yet locked.
+ * We return with mmap_sem still held, but pte unmapped and unlocked.
*/
-static int
-do_no_page(struct mm_struct *mm, struct vm_area_struct *vma,
- unsigned long address, int write_access, pte_t *page_table, pmd_t *pmd)
+static int do_no_page(struct mm_struct *mm, struct vm_area_struct *vma,
+ unsigned long address, pte_t *page_table, pmd_t *pmd,
+ int write_access)
{
- struct page * new_page;
+ spinlock_t *ptl;
+ struct page *new_page;
struct address_space *mapping = NULL;
pte_t entry;
unsigned int sequence = 0;
int ret = VM_FAULT_MINOR;
int anon = 0;
- if (!vma->vm_ops || !vma->vm_ops->nopage)
- return do_anonymous_page(mm, vma, page_table,
- pmd, write_access, address);
pte_unmap(page_table);
- spin_unlock(&mm->page_table_lock);
if (vma->vm_file) {
mapping = vma->vm_file->f_mapping;
@@ -1847,7 +1835,6 @@ do_no_page(struct mm_struct *mm, struct vm_area_struct *vma,
smp_rmb(); /* serializes i_size against truncate_count */
}
retry:
- cond_resched();
new_page = vma->vm_ops->nopage(vma, address & PAGE_MASK, &ret);
/*
* No smp_rmb is needed here as long as there's a full
@@ -1880,19 +1867,20 @@ retry:
anon = 1;
}
- spin_lock(&mm->page_table_lock);
+ page_table = pte_offset_map_lock(mm, pmd, address, &ptl);
/*
* For a file-backed vma, someone could have truncated or otherwise
* invalidated this page. If unmap_mapping_range got called,
* retry getting the page.
*/
if (mapping && unlikely(sequence != mapping->truncate_count)) {
- sequence = mapping->truncate_count;
- spin_unlock(&mm->page_table_lock);
+ pte_unmap_unlock(page_table, ptl);
page_cache_release(new_page);
+ cond_resched();
+ sequence = mapping->truncate_count;
+ smp_rmb();
goto retry;
}
- page_table = pte_offset_map(pmd, address);
/*
* This silly early PAGE_DIRTY setting removes a race
@@ -1906,68 +1894,67 @@ retry:
*/
/* Only go through if we didn't race with anybody else... */
if (pte_none(*page_table)) {
- if (!PageReserved(new_page))
- inc_mm_counter(mm, rss);
-
flush_icache_page(vma, new_page);
entry = mk_pte(new_page, vma->vm_page_prot);
if (write_access)
entry = maybe_mkwrite(pte_mkdirty(entry), vma);
set_pte_at(mm, address, page_table, entry);
if (anon) {
+ inc_mm_counter(mm, anon_rss);
lru_cache_add_active(new_page);
page_add_anon_rmap(new_page, vma, address);
- } else
+ } else if (!(vma->vm_flags & VM_RESERVED)) {
+ inc_mm_counter(mm, file_rss);
page_add_file_rmap(new_page);
- pte_unmap(page_table);
+ }
} else {
/* One of our sibling threads was faster, back out. */
- pte_unmap(page_table);
page_cache_release(new_page);
- spin_unlock(&mm->page_table_lock);
- goto out;
+ goto unlock;
}
/* no need to invalidate: a not-present page shouldn't be cached */
update_mmu_cache(vma, address, entry);
lazy_mmu_prot_update(entry);
- spin_unlock(&mm->page_table_lock);
-out:
+unlock:
+ pte_unmap_unlock(page_table, ptl);
return ret;
oom:
page_cache_release(new_page);
- ret = VM_FAULT_OOM;
- goto out;
+ return VM_FAULT_OOM;
}
/*
* Fault of a previously existing named mapping. Repopulate the pte
* from the encoded file_pte if possible. This enables swappable
* nonlinear vmas.
+ *
+ * We enter with non-exclusive mmap_sem (to exclude vma changes,
+ * but allow concurrent faults), and pte mapped but not yet locked.
+ * We return with mmap_sem still held, but pte unmapped and unlocked.
*/
-static int do_file_page(struct mm_struct * mm, struct vm_area_struct * vma,
- unsigned long address, int write_access, pte_t *pte, pmd_t *pmd)
+static int do_file_page(struct mm_struct *mm, struct vm_area_struct *vma,
+ unsigned long address, pte_t *page_table, pmd_t *pmd,
+ int write_access, pte_t orig_pte)
{
- unsigned long pgoff;
+ pgoff_t pgoff;
int err;
- BUG_ON(!vma->vm_ops || !vma->vm_ops->nopage);
- /*
- * Fall back to the linear mapping if the fs does not support
- * ->populate:
- */
- if (!vma->vm_ops->populate ||
- (write_access && !(vma->vm_flags & VM_SHARED))) {
- pte_clear(mm, address, pte);
- return do_no_page(mm, vma, address, write_access, pte, pmd);
- }
-
- pgoff = pte_to_pgoff(*pte);
+ if (!pte_unmap_same(mm, pmd, page_table, orig_pte))
+ return VM_FAULT_MINOR;
- pte_unmap(pte);
- spin_unlock(&mm->page_table_lock);
+ if (unlikely(!(vma->vm_flags & VM_NONLINEAR))) {
+ /*
+ * Page table corrupted: show pte and kill process.
+ */
+ print_bad_pte(vma, orig_pte, address);
+ return VM_FAULT_OOM;
+ }
+ /* We can then assume vm->vm_ops && vma->vm_ops->populate */
- err = vma->vm_ops->populate(vma, address & PAGE_MASK, PAGE_SIZE, vma->vm_page_prot, pgoff, 0);
+ pgoff = pte_to_pgoff(orig_pte);
+ err = vma->vm_ops->populate(vma, address & PAGE_MASK, PAGE_SIZE,
+ vma->vm_page_prot, pgoff, 0);
if (err == -ENOMEM)
return VM_FAULT_OOM;
if (err)
@@ -1984,56 +1971,68 @@ static int do_file_page(struct mm_struct * mm, struct vm_area_struct * vma,
* with external mmu caches can use to update those (ie the Sparc or
* PowerPC hashed page tables that act as extended TLBs).
*
- * Note the "page_table_lock". It is to protect against kswapd removing
- * pages from under us. Note that kswapd only ever _removes_ pages, never
- * adds them. As such, once we have noticed that the page is not present,
- * we can drop the lock early.
- *
- * The adding of pages is protected by the MM semaphore (which we hold),
- * so we don't need to worry about a page being suddenly been added into
- * our VM.
- *
- * We enter with the pagetable spinlock held, we are supposed to
- * release it when done.
+ * We enter with non-exclusive mmap_sem (to exclude vma changes,
+ * but allow concurrent faults), and pte mapped but not yet locked.
+ * We return with mmap_sem still held, but pte unmapped and unlocked.
*/
static inline int handle_pte_fault(struct mm_struct *mm,
- struct vm_area_struct * vma, unsigned long address,
- int write_access, pte_t *pte, pmd_t *pmd)
+ struct vm_area_struct *vma, unsigned long address,
+ pte_t *pte, pmd_t *pmd, int write_access)
{
pte_t entry;
+ pte_t old_entry;
+ spinlock_t *ptl;
- entry = *pte;
+ old_entry = entry = *pte;
if (!pte_present(entry)) {
- /*
- * If it truly wasn't present, we know that kswapd
- * and the PTE updates will not touch it later. So
- * drop the lock.
- */
- if (pte_none(entry))
- return do_no_page(mm, vma, address, write_access, pte, pmd);
+ if (pte_none(entry)) {
+ if (!vma->vm_ops || !vma->vm_ops->nopage)
+ return do_anonymous_page(mm, vma, address,
+ pte, pmd, write_access);
+ return do_no_page(mm, vma, address,
+ pte, pmd, write_access);
+ }
if (pte_file(entry))
- return do_file_page(mm, vma, address, write_access, pte, pmd);
- return do_swap_page(mm, vma, address, pte, pmd, entry, write_access);
+ return do_file_page(mm, vma, address,
+ pte, pmd, write_access, entry);
+ return do_swap_page(mm, vma, address,
+ pte, pmd, write_access, entry);
}
+ ptl = pte_lockptr(mm, pmd);
+ spin_lock(ptl);
+ if (unlikely(!pte_same(*pte, entry)))
+ goto unlock;
if (write_access) {
if (!pte_write(entry))
- return do_wp_page(mm, vma, address, pte, pmd, entry);
+ return do_wp_page(mm, vma, address,
+ pte, pmd, ptl, entry);
entry = pte_mkdirty(entry);
}
entry = pte_mkyoung(entry);
- ptep_set_access_flags(vma, address, pte, entry, write_access);
- update_mmu_cache(vma, address, entry);
- lazy_mmu_prot_update(entry);
- pte_unmap(pte);
- spin_unlock(&mm->page_table_lock);
+ if (!pte_same(old_entry, entry)) {
+ ptep_set_access_flags(vma, address, pte, entry, write_access);
+ update_mmu_cache(vma, address, entry);
+ lazy_mmu_prot_update(entry);
+ } else {
+ /*
+ * This is needed only for protection faults but the arch code
+ * is not yet telling us if this is a protection fault or not.
+ * This still avoids useless tlb flushes for .text page faults
+ * with threads.
+ */
+ if (write_access)
+ flush_tlb_page(vma, address);
+ }
+unlock:
+ pte_unmap_unlock(pte, ptl);
return VM_FAULT_MINOR;
}
/*
* By the time we get here, we already hold the mm semaphore
*/
-int __handle_mm_fault(struct mm_struct *mm, struct vm_area_struct * vma,
+int __handle_mm_fault(struct mm_struct *mm, struct vm_area_struct *vma,
unsigned long address, int write_access)
{
pgd_t *pgd;
@@ -2048,100 +2047,66 @@ int __handle_mm_fault(struct mm_struct *mm, struct vm_area_struct * vma,
if (unlikely(is_vm_hugetlb_page(vma)))
return hugetlb_fault(mm, vma, address, write_access);
- /*
- * We need the page table lock to synchronize with kswapd
- * and the SMP-safe atomic PTE updates.
- */
pgd = pgd_offset(mm, address);
- spin_lock(&mm->page_table_lock);
-
pud = pud_alloc(mm, pgd, address);
if (!pud)
- goto oom;
-
+ return VM_FAULT_OOM;
pmd = pmd_alloc(mm, pud, address);
if (!pmd)
- goto oom;
-
+ return VM_FAULT_OOM;
pte = pte_alloc_map(mm, pmd, address);
if (!pte)
- goto oom;
-
- return handle_pte_fault(mm, vma, address, write_access, pte, pmd);
+ return VM_FAULT_OOM;
- oom:
- spin_unlock(&mm->page_table_lock);
- return VM_FAULT_OOM;
+ return handle_pte_fault(mm, vma, address, pte, pmd, write_access);
}
#ifndef __PAGETABLE_PUD_FOLDED
/*
* Allocate page upper directory.
- *
- * We've already handled the fast-path in-line, and we own the
- * page table lock.
+ * We've already handled the fast-path in-line.
*/
-pud_t fastcall *__pud_alloc(struct mm_struct *mm, pgd_t *pgd, unsigned long address)
+int __pud_alloc(struct mm_struct *mm, pgd_t *pgd, unsigned long address)
{
- pud_t *new;
-
- spin_unlock(&mm->page_table_lock);
- new = pud_alloc_one(mm, address);
- spin_lock(&mm->page_table_lock);
+ pud_t *new = pud_alloc_one(mm, address);
if (!new)
- return NULL;
+ return -ENOMEM;
- /*
- * Because we dropped the lock, we should re-check the
- * entry, as somebody else could have populated it..
- */
- if (pgd_present(*pgd)) {
+ spin_lock(&mm->page_table_lock);
+ if (pgd_present(*pgd)) /* Another has populated it */
pud_free(new);
- goto out;
- }
- pgd_populate(mm, pgd, new);
- out:
- return pud_offset(pgd, address);
+ else
+ pgd_populate(mm, pgd, new);
+ spin_unlock(&mm->page_table_lock);
+ return 0;
}
#endif /* __PAGETABLE_PUD_FOLDED */
#ifndef __PAGETABLE_PMD_FOLDED
/*
* Allocate page middle directory.
- *
- * We've already handled the fast-path in-line, and we own the
- * page table lock.
+ * We've already handled the fast-path in-line.
*/
-pmd_t fastcall *__pmd_alloc(struct mm_struct *mm, pud_t *pud, unsigned long address)
+int __pmd_alloc(struct mm_struct *mm, pud_t *pud, unsigned long address)
{
- pmd_t *new;
-
- spin_unlock(&mm->page_table_lock);
- new = pmd_alloc_one(mm, address);
- spin_lock(&mm->page_table_lock);
+ pmd_t *new = pmd_alloc_one(mm, address);
if (!new)
- return NULL;
+ return -ENOMEM;
- /*
- * Because we dropped the lock, we should re-check the
- * entry, as somebody else could have populated it..
- */
+ spin_lock(&mm->page_table_lock);
#ifndef __ARCH_HAS_4LEVEL_HACK
- if (pud_present(*pud)) {
+ if (pud_present(*pud)) /* Another has populated it */
pmd_free(new);
- goto out;
- }
- pud_populate(mm, pud, new);
+ else
+ pud_populate(mm, pud, new);
#else
- if (pgd_present(*pud)) {
+ if (pgd_present(*pud)) /* Another has populated it */
pmd_free(new);
- goto out;
- }
- pgd_populate(mm, pud, new);
+ else
+ pgd_populate(mm, pud, new);
#endif /* __ARCH_HAS_4LEVEL_HACK */
-
- out:
- return pmd_offset(pud, address);
+ spin_unlock(&mm->page_table_lock);
+ return 0;
}
#endif /* __PAGETABLE_PMD_FOLDED */
@@ -2206,22 +2171,6 @@ unsigned long vmalloc_to_pfn(void * vmalloc_addr)
EXPORT_SYMBOL(vmalloc_to_pfn);
-/*
- * update_mem_hiwater
- * - update per process rss and vm high water data
- */
-void update_mem_hiwater(struct task_struct *tsk)
-{
- if (tsk->mm) {
- unsigned long rss = get_mm_counter(tsk->mm, rss);
-
- if (tsk->mm->hiwater_rss < rss)
- tsk->mm->hiwater_rss = rss;
- if (tsk->mm->hiwater_vm < tsk->mm->total_vm)
- tsk->mm->hiwater_vm = tsk->mm->total_vm;
- }
-}
-
#if !defined(__HAVE_ARCH_GATE_AREA)
#if defined(AT_SYSINFO_EHDR)
@@ -2233,7 +2182,7 @@ static int __init gate_vma_init(void)
gate_vma.vm_start = FIXADDR_USER_START;
gate_vma.vm_end = FIXADDR_USER_END;
gate_vma.vm_page_prot = PAGE_READONLY;
- gate_vma.vm_flags = 0;
+ gate_vma.vm_flags = VM_RESERVED;
return 0;
}
__initcall(gate_vma_init);
diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
new file mode 100644
index 000000000000..431a64f021c0
--- /dev/null
+++ b/mm/memory_hotplug.c
@@ -0,0 +1,138 @@
+/*
+ * linux/mm/memory_hotplug.c
+ *
+ * Copyright (C)
+ */
+
+#include <linux/config.h>
+#include <linux/stddef.h>
+#include <linux/mm.h>
+#include <linux/swap.h>
+#include <linux/interrupt.h>
+#include <linux/pagemap.h>
+#include <linux/bootmem.h>
+#include <linux/compiler.h>
+#include <linux/module.h>
+#include <linux/pagevec.h>
+#include <linux/slab.h>
+#include <linux/sysctl.h>
+#include <linux/cpu.h>
+#include <linux/memory.h>
+#include <linux/memory_hotplug.h>
+#include <linux/highmem.h>
+#include <linux/vmalloc.h>
+
+#include <asm/tlbflush.h>
+
+extern void zonetable_add(struct zone *zone, int nid, int zid, unsigned long pfn,
+ unsigned long size);
+static void __add_zone(struct zone *zone, unsigned long phys_start_pfn)
+{
+ struct pglist_data *pgdat = zone->zone_pgdat;
+ int nr_pages = PAGES_PER_SECTION;
+ int nid = pgdat->node_id;
+ int zone_type;
+
+ zone_type = zone - pgdat->node_zones;
+ memmap_init_zone(nr_pages, nid, zone_type, phys_start_pfn);
+ zonetable_add(zone, nid, zone_type, phys_start_pfn, nr_pages);
+}
+
+extern int sparse_add_one_section(struct zone *zone, unsigned long start_pfn,
+ int nr_pages);
+static int __add_section(struct zone *zone, unsigned long phys_start_pfn)
+{
+ struct pglist_data *pgdat = zone->zone_pgdat;
+ int nr_pages = PAGES_PER_SECTION;
+ int ret;
+
+ ret = sparse_add_one_section(zone, phys_start_pfn, nr_pages);
+
+ if (ret < 0)
+ return ret;
+
+ __add_zone(zone, phys_start_pfn);
+ return register_new_memory(__pfn_to_section(phys_start_pfn));
+}
+
+/*
+ * Reasonably generic function for adding memory. It is
+ * expected that archs that support memory hotplug will
+ * call this function after deciding the zone to which to
+ * add the new pages.
+ */
+int __add_pages(struct zone *zone, unsigned long phys_start_pfn,
+ unsigned long nr_pages)
+{
+ unsigned long i;
+ int err = 0;
+
+ for (i = 0; i < nr_pages; i += PAGES_PER_SECTION) {
+ err = __add_section(zone, phys_start_pfn + i);
+
+ if (err)
+ break;
+ }
+
+ return err;
+}
+
+static void grow_zone_span(struct zone *zone,
+ unsigned long start_pfn, unsigned long end_pfn)
+{
+ unsigned long old_zone_end_pfn;
+
+ zone_span_writelock(zone);
+
+ old_zone_end_pfn = zone->zone_start_pfn + zone->spanned_pages;
+ if (start_pfn < zone->zone_start_pfn)
+ zone->zone_start_pfn = start_pfn;
+
+ if (end_pfn > old_zone_end_pfn)
+ zone->spanned_pages = end_pfn - zone->zone_start_pfn;
+
+ zone_span_writeunlock(zone);
+}
+
+static void grow_pgdat_span(struct pglist_data *pgdat,
+ unsigned long start_pfn, unsigned long end_pfn)
+{
+ unsigned long old_pgdat_end_pfn =
+ pgdat->node_start_pfn + pgdat->node_spanned_pages;
+
+ if (start_pfn < pgdat->node_start_pfn)
+ pgdat->node_start_pfn = start_pfn;
+
+ if (end_pfn > old_pgdat_end_pfn)
+ pgdat->node_spanned_pages = end_pfn - pgdat->node_spanned_pages;
+}
+
+int online_pages(unsigned long pfn, unsigned long nr_pages)
+{
+ unsigned long i;
+ unsigned long flags;
+ unsigned long onlined_pages = 0;
+ struct zone *zone;
+
+ /*
+ * This doesn't need a lock to do pfn_to_page().
+ * The section can't be removed here because of the
+ * memory_block->state_sem.
+ */
+ zone = page_zone(pfn_to_page(pfn));
+ pgdat_resize_lock(zone->zone_pgdat, &flags);
+ grow_zone_span(zone, pfn, pfn + nr_pages);
+ grow_pgdat_span(zone->zone_pgdat, pfn, pfn + nr_pages);
+ pgdat_resize_unlock(zone->zone_pgdat, &flags);
+
+ for (i = 0; i < nr_pages; i++) {
+ struct page *page = pfn_to_page(pfn + i);
+ online_page(page);
+ onlined_pages++;
+ }
+ zone->present_pages += onlined_pages;
+
+ setup_per_zone_pages_min();
+
+ return 0;
+}
diff --git a/mm/mempolicy.c b/mm/mempolicy.c
index 37af443eb094..5abc57c2b8bd 100644
--- a/mm/mempolicy.c
+++ b/mm/mempolicy.c
@@ -2,6 +2,7 @@
* Simple NUMA memory policy for the Linux kernel.
*
* Copyright 2003,2004 Andi Kleen, SuSE Labs.
+ * (C) Copyright 2005 Christoph Lameter, Silicon Graphics, Inc.
* Subject to the GNU Public License, version 2.
*
* NUMA policy allows the user to give hints in which node(s) memory should
@@ -17,13 +18,19 @@
* offset into the backing object or offset into the mapping
* for anonymous memory. For process policy an process counter
* is used.
+ *
* bind Only allocate memory on a specific set of nodes,
* no fallback.
+ * FIXME: memory is allocated starting with the first node
+ * to the last. It would be better if bind would truly restrict
+ * the allocation to memory nodes instead
+ *
* preferred Try a specific node first before normal fallback.
* As a special case node -1 here means do the allocation
* on the local CPU. This is normally identical to default,
* but useful to set in a VMA when you have a non default
* process policy.
+ *
* default Allocate on the local node first, or when on a VMA
* use the process policy. This is what Linux always did
* in a NUMA aware kernel and still does by, ahem, default.
@@ -93,23 +100,10 @@ struct mempolicy default_policy = {
.policy = MPOL_DEFAULT,
};
-/* Check if all specified nodes are online */
-static int nodes_online(unsigned long *nodes)
-{
- DECLARE_BITMAP(online2, MAX_NUMNODES);
-
- bitmap_copy(online2, nodes_addr(node_online_map), MAX_NUMNODES);
- if (bitmap_empty(online2, MAX_NUMNODES))
- set_bit(0, online2);
- if (!bitmap_subset(nodes, online2, MAX_NUMNODES))
- return -EINVAL;
- return 0;
-}
-
/* Do sanity checking on a policy */
-static int mpol_check_policy(int mode, unsigned long *nodes)
+static int mpol_check_policy(int mode, nodemask_t *nodes)
{
- int empty = bitmap_empty(nodes, MAX_NUMNODES);
+ int empty = nodes_empty(*nodes);
switch (mode) {
case MPOL_DEFAULT:
@@ -124,71 +118,20 @@ static int mpol_check_policy(int mode, unsigned long *nodes)
return -EINVAL;
break;
}
- return nodes_online(nodes);
-}
-
-/* Copy a node mask from user space. */
-static int get_nodes(unsigned long *nodes, unsigned long __user *nmask,
- unsigned long maxnode, int mode)
-{
- unsigned long k;
- unsigned long nlongs;
- unsigned long endmask;
-
- --maxnode;
- bitmap_zero(nodes, MAX_NUMNODES);
- if (maxnode == 0 || !nmask)
- return 0;
-
- nlongs = BITS_TO_LONGS(maxnode);
- if ((maxnode % BITS_PER_LONG) == 0)
- endmask = ~0UL;
- else
- endmask = (1UL << (maxnode % BITS_PER_LONG)) - 1;
-
- /* When the user specified more nodes than supported just check
- if the non supported part is all zero. */
- if (nlongs > BITS_TO_LONGS(MAX_NUMNODES)) {
- if (nlongs > PAGE_SIZE/sizeof(long))
- return -EINVAL;
- for (k = BITS_TO_LONGS(MAX_NUMNODES); k < nlongs; k++) {
- unsigned long t;
- if (get_user(t, nmask + k))
- return -EFAULT;
- if (k == nlongs - 1) {
- if (t & endmask)
- return -EINVAL;
- } else if (t)
- return -EINVAL;
- }
- nlongs = BITS_TO_LONGS(MAX_NUMNODES);
- endmask = ~0UL;
- }
-
- if (copy_from_user(nodes, nmask, nlongs*sizeof(unsigned long)))
- return -EFAULT;
- nodes[nlongs-1] &= endmask;
- /* Update current mems_allowed */
- cpuset_update_current_mems_allowed();
- /* Ignore nodes not set in current->mems_allowed */
- cpuset_restrict_to_mems_allowed(nodes);
- return mpol_check_policy(mode, nodes);
+ return nodes_subset(*nodes, node_online_map) ? 0 : -EINVAL;
}
-
/* Generate a custom zonelist for the BIND policy. */
-static struct zonelist *bind_zonelist(unsigned long *nodes)
+static struct zonelist *bind_zonelist(nodemask_t *nodes)
{
struct zonelist *zl;
int num, max, nd;
- max = 1 + MAX_NR_ZONES * bitmap_weight(nodes, MAX_NUMNODES);
+ max = 1 + MAX_NR_ZONES * nodes_weight(*nodes);
zl = kmalloc(sizeof(void *) * max, GFP_KERNEL);
if (!zl)
return NULL;
num = 0;
- for (nd = find_first_bit(nodes, MAX_NUMNODES);
- nd < MAX_NUMNODES;
- nd = find_next_bit(nodes, MAX_NUMNODES, 1+nd)) {
+ for_each_node_mask(nd, *nodes) {
int k;
for (k = MAX_NR_ZONES-1; k >= 0; k--) {
struct zone *z = &NODE_DATA(nd)->node_zones[k];
@@ -199,17 +142,16 @@ static struct zonelist *bind_zonelist(unsigned long *nodes)
policy_zone = k;
}
}
- BUG_ON(num >= max);
zl->zones[num] = NULL;
return zl;
}
/* Create a new policy */
-static struct mempolicy *mpol_new(int mode, unsigned long *nodes)
+static struct mempolicy *mpol_new(int mode, nodemask_t *nodes)
{
struct mempolicy *policy;
- PDprintk("setting mode %d nodes[0] %lx\n", mode, nodes[0]);
+ PDprintk("setting mode %d nodes[0] %lx\n", mode, nodes_addr(*nodes)[0]);
if (mode == MPOL_DEFAULT)
return NULL;
policy = kmem_cache_alloc(policy_cache, GFP_KERNEL);
@@ -218,10 +160,10 @@ static struct mempolicy *mpol_new(int mode, unsigned long *nodes)
atomic_set(&policy->refcnt, 1);
switch (mode) {
case MPOL_INTERLEAVE:
- bitmap_copy(policy->v.nodes, nodes, MAX_NUMNODES);
+ policy->v.nodes = *nodes;
break;
case MPOL_PREFERRED:
- policy->v.preferred_node = find_first_bit(nodes, MAX_NUMNODES);
+ policy->v.preferred_node = first_node(*nodes);
if (policy->v.preferred_node >= MAX_NUMNODES)
policy->v.preferred_node = -1;
break;
@@ -238,14 +180,14 @@ static struct mempolicy *mpol_new(int mode, unsigned long *nodes)
}
/* Ensure all existing pages follow the policy. */
-static int check_pte_range(struct mm_struct *mm, pmd_t *pmd,
- unsigned long addr, unsigned long end, unsigned long *nodes)
+static int check_pte_range(struct vm_area_struct *vma, pmd_t *pmd,
+ unsigned long addr, unsigned long end, nodemask_t *nodes)
{
pte_t *orig_pte;
pte_t *pte;
+ spinlock_t *ptl;
- spin_lock(&mm->page_table_lock);
- orig_pte = pte = pte_offset_map(pmd, addr);
+ orig_pte = pte = pte_offset_map_lock(vma->vm_mm, pmd, addr, &ptl);
do {
unsigned long pfn;
unsigned int nid;
@@ -253,19 +195,20 @@ static int check_pte_range(struct mm_struct *mm, pmd_t *pmd,
if (!pte_present(*pte))
continue;
pfn = pte_pfn(*pte);
- if (!pfn_valid(pfn))
+ if (!pfn_valid(pfn)) {
+ print_bad_pte(vma, *pte, addr);
continue;
+ }
nid = pfn_to_nid(pfn);
- if (!test_bit(nid, nodes))
+ if (!node_isset(nid, *nodes))
break;
} while (pte++, addr += PAGE_SIZE, addr != end);
- pte_unmap(orig_pte);
- spin_unlock(&mm->page_table_lock);
+ pte_unmap_unlock(orig_pte, ptl);
return addr != end;
}
-static inline int check_pmd_range(struct mm_struct *mm, pud_t *pud,
- unsigned long addr, unsigned long end, unsigned long *nodes)
+static inline int check_pmd_range(struct vm_area_struct *vma, pud_t *pud,
+ unsigned long addr, unsigned long end, nodemask_t *nodes)
{
pmd_t *pmd;
unsigned long next;
@@ -275,14 +218,14 @@ static inline int check_pmd_range(struct mm_struct *mm, pud_t *pud,
next = pmd_addr_end(addr, end);
if (pmd_none_or_clear_bad(pmd))
continue;
- if (check_pte_range(mm, pmd, addr, next, nodes))
+ if (check_pte_range(vma, pmd, addr, next, nodes))
return -EIO;
} while (pmd++, addr = next, addr != end);
return 0;
}
-static inline int check_pud_range(struct mm_struct *mm, pgd_t *pgd,
- unsigned long addr, unsigned long end, unsigned long *nodes)
+static inline int check_pud_range(struct vm_area_struct *vma, pgd_t *pgd,
+ unsigned long addr, unsigned long end, nodemask_t *nodes)
{
pud_t *pud;
unsigned long next;
@@ -292,24 +235,24 @@ static inline int check_pud_range(struct mm_struct *mm, pgd_t *pgd,
next = pud_addr_end(addr, end);
if (pud_none_or_clear_bad(pud))
continue;
- if (check_pmd_range(mm, pud, addr, next, nodes))
+ if (check_pmd_range(vma, pud, addr, next, nodes))
return -EIO;
} while (pud++, addr = next, addr != end);
return 0;
}
-static inline int check_pgd_range(struct mm_struct *mm,
- unsigned long addr, unsigned long end, unsigned long *nodes)
+static inline int check_pgd_range(struct vm_area_struct *vma,
+ unsigned long addr, unsigned long end, nodemask_t *nodes)
{
pgd_t *pgd;
unsigned long next;
- pgd = pgd_offset(mm, addr);
+ pgd = pgd_offset(vma->vm_mm, addr);
do {
next = pgd_addr_end(addr, end);
if (pgd_none_or_clear_bad(pgd))
continue;
- if (check_pud_range(mm, pgd, addr, next, nodes))
+ if (check_pud_range(vma, pgd, addr, next, nodes))
return -EIO;
} while (pgd++, addr = next, addr != end);
return 0;
@@ -318,7 +261,7 @@ static inline int check_pgd_range(struct mm_struct *mm,
/* Step 1: check the range */
static struct vm_area_struct *
check_range(struct mm_struct *mm, unsigned long start, unsigned long end,
- unsigned long *nodes, unsigned long flags)
+ nodemask_t *nodes, unsigned long flags)
{
int err;
struct vm_area_struct *first, *vma, *prev;
@@ -326,6 +269,8 @@ check_range(struct mm_struct *mm, unsigned long start, unsigned long end,
first = find_vma(mm, start);
if (!first)
return ERR_PTR(-EFAULT);
+ if (first->vm_flags & VM_RESERVED)
+ return ERR_PTR(-EACCES);
prev = NULL;
for (vma = first; vma && vma->vm_start < end; vma = vma->vm_next) {
if (!vma->vm_next && vma->vm_end < end)
@@ -338,8 +283,7 @@ check_range(struct mm_struct *mm, unsigned long start, unsigned long end,
endvma = end;
if (vma->vm_start > start)
start = vma->vm_start;
- err = check_pgd_range(vma->vm_mm,
- start, endvma, nodes);
+ err = check_pgd_range(vma, start, endvma, nodes);
if (err) {
first = ERR_PTR(err);
break;
@@ -393,17 +337,25 @@ static int mbind_range(struct vm_area_struct *vma, unsigned long start,
return err;
}
-/* Change policy for a memory range */
-asmlinkage long sys_mbind(unsigned long start, unsigned long len,
- unsigned long mode,
- unsigned long __user *nmask, unsigned long maxnode,
- unsigned flags)
+static int contextualize_policy(int mode, nodemask_t *nodes)
+{
+ if (!nodes)
+ return 0;
+
+ /* Update current mems_allowed */
+ cpuset_update_current_mems_allowed();
+ /* Ignore nodes not set in current->mems_allowed */
+ cpuset_restrict_to_mems_allowed(nodes->bits);
+ return mpol_check_policy(mode, nodes);
+}
+
+long do_mbind(unsigned long start, unsigned long len,
+ unsigned long mode, nodemask_t *nmask, unsigned long flags)
{
struct vm_area_struct *vma;
struct mm_struct *mm = current->mm;
struct mempolicy *new;
unsigned long end;
- DECLARE_BITMAP(nodes, MAX_NUMNODES);
int err;
if ((flags & ~(unsigned long)(MPOL_MF_STRICT)) || mode > MPOL_MAX)
@@ -418,20 +370,17 @@ asmlinkage long sys_mbind(unsigned long start, unsigned long len,
return -EINVAL;
if (end == start)
return 0;
-
- err = get_nodes(nodes, nmask, maxnode, mode);
- if (err)
- return err;
-
- new = mpol_new(mode, nodes);
+ if (mpol_check_policy(mode, nmask))
+ return -EINVAL;
+ new = mpol_new(mode, nmask);
if (IS_ERR(new))
return PTR_ERR(new);
PDprintk("mbind %lx-%lx mode:%ld nodes:%lx\n",start,start+len,
- mode,nodes[0]);
+ mode,nodes_addr(nodes)[0]);
down_write(&mm->mmap_sem);
- vma = check_range(mm, start, end, nodes, flags);
+ vma = check_range(mm, start, end, nmask, flags);
err = PTR_ERR(vma);
if (!IS_ERR(vma))
err = mbind_range(vma, start, end, new);
@@ -441,50 +390,45 @@ asmlinkage long sys_mbind(unsigned long start, unsigned long len,
}
/* Set the process memory policy */
-asmlinkage long sys_set_mempolicy(int mode, unsigned long __user *nmask,
- unsigned long maxnode)
+long do_set_mempolicy(int mode, nodemask_t *nodes)
{
- int err;
struct mempolicy *new;
- DECLARE_BITMAP(nodes, MAX_NUMNODES);
- if (mode < 0 || mode > MPOL_MAX)
+ if (contextualize_policy(mode, nodes))
return -EINVAL;
- err = get_nodes(nodes, nmask, maxnode, mode);
- if (err)
- return err;
new = mpol_new(mode, nodes);
if (IS_ERR(new))
return PTR_ERR(new);
mpol_free(current->mempolicy);
current->mempolicy = new;
if (new && new->policy == MPOL_INTERLEAVE)
- current->il_next = find_first_bit(new->v.nodes, MAX_NUMNODES);
+ current->il_next = first_node(new->v.nodes);
return 0;
}
/* Fill a zone bitmap for a policy */
-static void get_zonemask(struct mempolicy *p, unsigned long *nodes)
+static void get_zonemask(struct mempolicy *p, nodemask_t *nodes)
{
int i;
- bitmap_zero(nodes, MAX_NUMNODES);
+ nodes_clear(*nodes);
switch (p->policy) {
case MPOL_BIND:
for (i = 0; p->v.zonelist->zones[i]; i++)
- __set_bit(p->v.zonelist->zones[i]->zone_pgdat->node_id, nodes);
+ node_set(p->v.zonelist->zones[i]->zone_pgdat->node_id,
+ *nodes);
break;
case MPOL_DEFAULT:
break;
case MPOL_INTERLEAVE:
- bitmap_copy(nodes, p->v.nodes, MAX_NUMNODES);
+ *nodes = p->v.nodes;
break;
case MPOL_PREFERRED:
/* or use current node instead of online map? */
if (p->v.preferred_node < 0)
- bitmap_copy(nodes, nodes_addr(node_online_map), MAX_NUMNODES);
+ *nodes = node_online_map;
else
- __set_bit(p->v.preferred_node, nodes);
+ node_set(p->v.preferred_node, *nodes);
break;
default:
BUG();
@@ -504,37 +448,18 @@ static int lookup_node(struct mm_struct *mm, unsigned long addr)
return err;
}
-/* Copy a kernel node mask to user space */
-static int copy_nodes_to_user(unsigned long __user *mask, unsigned long maxnode,
- void *nodes, unsigned nbytes)
-{
- unsigned long copy = ALIGN(maxnode-1, 64) / 8;
-
- if (copy > nbytes) {
- if (copy > PAGE_SIZE)
- return -EINVAL;
- if (clear_user((char __user *)mask + nbytes, copy - nbytes))
- return -EFAULT;
- copy = nbytes;
- }
- return copy_to_user(mask, nodes, copy) ? -EFAULT : 0;
-}
-
/* Retrieve NUMA policy */
-asmlinkage long sys_get_mempolicy(int __user *policy,
- unsigned long __user *nmask,
- unsigned long maxnode,
- unsigned long addr, unsigned long flags)
+long do_get_mempolicy(int *policy, nodemask_t *nmask,
+ unsigned long addr, unsigned long flags)
{
- int err, pval;
+ int err;
struct mm_struct *mm = current->mm;
struct vm_area_struct *vma = NULL;
struct mempolicy *pol = current->mempolicy;
+ cpuset_update_current_mems_allowed();
if (flags & ~(unsigned long)(MPOL_F_NODE|MPOL_F_ADDR))
return -EINVAL;
- if (nmask != NULL && maxnode < MAX_NUMNODES)
- return -EINVAL;
if (flags & MPOL_F_ADDR) {
down_read(&mm->mmap_sem);
vma = find_vma_intersection(mm, addr, addr+1);
@@ -557,31 +482,25 @@ asmlinkage long sys_get_mempolicy(int __user *policy,
err = lookup_node(mm, addr);
if (err < 0)
goto out;
- pval = err;
+ *policy = err;
} else if (pol == current->mempolicy &&
pol->policy == MPOL_INTERLEAVE) {
- pval = current->il_next;
+ *policy = current->il_next;
} else {
err = -EINVAL;
goto out;
}
} else
- pval = pol->policy;
+ *policy = pol->policy;
if (vma) {
up_read(&current->mm->mmap_sem);
vma = NULL;
}
- if (policy && put_user(pval, policy))
- return -EFAULT;
-
err = 0;
- if (nmask) {
- DECLARE_BITMAP(nodes, MAX_NUMNODES);
- get_zonemask(pol, nodes);
- err = copy_nodes_to_user(nmask, maxnode, nodes, sizeof(nodes));
- }
+ if (nmask)
+ get_zonemask(pol, nmask);
out:
if (vma)
@@ -589,6 +508,126 @@ asmlinkage long sys_get_mempolicy(int __user *policy,
return err;
}
+/*
+ * User space interface with variable sized bitmaps for nodelists.
+ */
+
+/* Copy a node mask from user space. */
+static int get_nodes(nodemask_t *nodes, unsigned long __user *nmask,
+ unsigned long maxnode)
+{
+ unsigned long k;
+ unsigned long nlongs;
+ unsigned long endmask;
+
+ --maxnode;
+ nodes_clear(*nodes);
+ if (maxnode == 0 || !nmask)
+ return 0;
+
+ nlongs = BITS_TO_LONGS(maxnode);
+ if ((maxnode % BITS_PER_LONG) == 0)
+ endmask = ~0UL;
+ else
+ endmask = (1UL << (maxnode % BITS_PER_LONG)) - 1;
+
+ /* When the user specified more nodes than supported just check
+ if the non supported part is all zero. */
+ if (nlongs > BITS_TO_LONGS(MAX_NUMNODES)) {
+ if (nlongs > PAGE_SIZE/sizeof(long))
+ return -EINVAL;
+ for (k = BITS_TO_LONGS(MAX_NUMNODES); k < nlongs; k++) {
+ unsigned long t;
+ if (get_user(t, nmask + k))
+ return -EFAULT;
+ if (k == nlongs - 1) {
+ if (t & endmask)
+ return -EINVAL;
+ } else if (t)
+ return -EINVAL;
+ }
+ nlongs = BITS_TO_LONGS(MAX_NUMNODES);
+ endmask = ~0UL;
+ }
+
+ if (copy_from_user(nodes_addr(*nodes), nmask, nlongs*sizeof(unsigned long)))
+ return -EFAULT;
+ nodes_addr(*nodes)[nlongs-1] &= endmask;
+ return 0;
+}
+
+/* Copy a kernel node mask to user space */
+static int copy_nodes_to_user(unsigned long __user *mask, unsigned long maxnode,
+ nodemask_t *nodes)
+{
+ unsigned long copy = ALIGN(maxnode-1, 64) / 8;
+ const int nbytes = BITS_TO_LONGS(MAX_NUMNODES) * sizeof(long);
+
+ if (copy > nbytes) {
+ if (copy > PAGE_SIZE)
+ return -EINVAL;
+ if (clear_user((char __user *)mask + nbytes, copy - nbytes))
+ return -EFAULT;
+ copy = nbytes;
+ }
+ return copy_to_user(mask, nodes_addr(*nodes), copy) ? -EFAULT : 0;
+}
+
+asmlinkage long sys_mbind(unsigned long start, unsigned long len,
+ unsigned long mode,
+ unsigned long __user *nmask, unsigned long maxnode,
+ unsigned flags)
+{
+ nodemask_t nodes;
+ int err;
+
+ err = get_nodes(&nodes, nmask, maxnode);
+ if (err)
+ return err;
+ return do_mbind(start, len, mode, &nodes, flags);
+}
+
+/* Set the process memory policy */
+asmlinkage long sys_set_mempolicy(int mode, unsigned long __user *nmask,
+ unsigned long maxnode)
+{
+ int err;
+ nodemask_t nodes;
+
+ if (mode < 0 || mode > MPOL_MAX)
+ return -EINVAL;
+ err = get_nodes(&nodes, nmask, maxnode);
+ if (err)
+ return err;
+ return do_set_mempolicy(mode, &nodes);
+}
+
+/* Retrieve NUMA policy */
+asmlinkage long sys_get_mempolicy(int __user *policy,
+ unsigned long __user *nmask,
+ unsigned long maxnode,
+ unsigned long addr, unsigned long flags)
+{
+ int err, pval;
+ nodemask_t nodes;
+
+ if (nmask != NULL && maxnode < MAX_NUMNODES)
+ return -EINVAL;
+
+ err = do_get_mempolicy(&pval, &nodes, addr, flags);
+
+ if (err)
+ return err;
+
+ if (policy && put_user(pval, policy))
+ return -EFAULT;
+
+ if (nmask)
+ err = copy_nodes_to_user(nmask, maxnode, &nodes);
+
+ return err;
+}
+
#ifdef CONFIG_COMPAT
asmlinkage long compat_sys_get_mempolicy(int __user *policy,
@@ -649,15 +688,15 @@ asmlinkage long compat_sys_mbind(compat_ulong_t start, compat_ulong_t len,
long err = 0;
unsigned long __user *nm = NULL;
unsigned long nr_bits, alloc_size;
- DECLARE_BITMAP(bm, MAX_NUMNODES);
+ nodemask_t bm;
nr_bits = min_t(unsigned long, maxnode-1, MAX_NUMNODES);
alloc_size = ALIGN(nr_bits, BITS_PER_LONG) / 8;
if (nmask) {
- err = compat_get_bitmap(bm, nmask, nr_bits);
+ err = compat_get_bitmap(nodes_addr(bm), nmask, nr_bits);
nm = compat_alloc_user_space(alloc_size);
- err |= copy_to_user(nm, bm, alloc_size);
+ err |= copy_to_user(nm, nodes_addr(bm), alloc_size);
}
if (err)
@@ -676,7 +715,7 @@ get_vma_policy(struct task_struct *task, struct vm_area_struct *vma, unsigned lo
if (vma) {
if (vma->vm_ops && vma->vm_ops->get_policy)
- pol = vma->vm_ops->get_policy(vma, addr);
+ pol = vma->vm_ops->get_policy(vma, addr);
else if (vma->vm_policy &&
vma->vm_policy->policy != MPOL_DEFAULT)
pol = vma->vm_policy;
@@ -700,7 +739,7 @@ static struct zonelist *zonelist_policy(gfp_t gfp, struct mempolicy *policy)
case MPOL_BIND:
/* Lower zones don't get a policy applied */
/* Careful: current->mems_allowed might have moved */
- if ((gfp & GFP_ZONEMASK) >= policy_zone)
+ if (gfp_zone(gfp) >= policy_zone)
if (cpuset_zonelist_valid_mems_allowed(policy->v.zonelist))
return policy->v.zonelist;
/*FALL THROUGH*/
@@ -712,7 +751,7 @@ static struct zonelist *zonelist_policy(gfp_t gfp, struct mempolicy *policy)
nd = 0;
BUG();
}
- return NODE_DATA(nd)->node_zonelists + (gfp & GFP_ZONEMASK);
+ return NODE_DATA(nd)->node_zonelists + gfp_zone(gfp);
}
/* Do dynamic interleaving for a process */
@@ -722,10 +761,9 @@ static unsigned interleave_nodes(struct mempolicy *policy)
struct task_struct *me = current;
nid = me->il_next;
- BUG_ON(nid >= MAX_NUMNODES);
- next = find_next_bit(policy->v.nodes, MAX_NUMNODES, 1+nid);
+ next = next_node(nid, policy->v.nodes);
if (next >= MAX_NUMNODES)
- next = find_first_bit(policy->v.nodes, MAX_NUMNODES);
+ next = first_node(policy->v.nodes);
me->il_next = next;
return nid;
}
@@ -734,30 +772,28 @@ static unsigned interleave_nodes(struct mempolicy *policy)
static unsigned offset_il_node(struct mempolicy *pol,
struct vm_area_struct *vma, unsigned long off)
{
- unsigned nnodes = bitmap_weight(pol->v.nodes, MAX_NUMNODES);
+ unsigned nnodes = nodes_weight(pol->v.nodes);
unsigned target = (unsigned)off % nnodes;
int c;
int nid = -1;
c = 0;
do {
- nid = find_next_bit(pol->v.nodes, MAX_NUMNODES, nid+1);
+ nid = next_node(nid, pol->v.nodes);
c++;
} while (c <= target);
- BUG_ON(nid >= MAX_NUMNODES);
- BUG_ON(!test_bit(nid, pol->v.nodes));
return nid;
}
/* Allocate a page in interleaved policy.
Own path because it needs to do special accounting. */
-static struct page *alloc_page_interleave(gfp_t gfp, unsigned order, unsigned nid)
+static struct page *alloc_page_interleave(gfp_t gfp, unsigned order,
+ unsigned nid)
{
struct zonelist *zl;
struct page *page;
- BUG_ON(!node_online(nid));
- zl = NODE_DATA(nid)->node_zonelists + (gfp & GFP_ZONEMASK);
+ zl = NODE_DATA(nid)->node_zonelists + gfp_zone(gfp);
page = __alloc_pages(gfp, order, zl);
if (page && page_zone(page) == zl->zones[0]) {
zone_pcp(zl->zones[0],get_cpu())->interleave_hit++;
@@ -799,8 +835,6 @@ alloc_page_vma(gfp_t gfp, struct vm_area_struct *vma, unsigned long addr)
unsigned nid;
if (vma) {
unsigned long off;
- BUG_ON(addr >= vma->vm_end);
- BUG_ON(addr < vma->vm_start);
off = vma->vm_pgoff;
off += (addr - vma->vm_start) >> PAGE_SHIFT;
nid = offset_il_node(pol, vma, off);
@@ -878,7 +912,7 @@ int __mpol_equal(struct mempolicy *a, struct mempolicy *b)
case MPOL_DEFAULT:
return 1;
case MPOL_INTERLEAVE:
- return bitmap_equal(a->v.nodes, b->v.nodes, MAX_NUMNODES);
+ return nodes_equal(a->v.nodes, b->v.nodes);
case MPOL_PREFERRED:
return a->v.preferred_node == b->v.preferred_node;
case MPOL_BIND: {
@@ -1117,7 +1151,7 @@ int mpol_set_shared_policy(struct shared_policy *info,
PDprintk("set_shared_policy %lx sz %lu %d %lx\n",
vma->vm_pgoff,
sz, npol? npol->policy : -1,
- npol ? npol->v.nodes[0] : -1);
+ npol ? nodes_addr(npol->v.nodes)[0] : -1);
if (npol) {
new = sp_alloc(vma->vm_pgoff, vma->vm_pgoff + sz, npol);
@@ -1164,14 +1198,75 @@ void __init numa_policy_init(void)
/* Set interleaving policy for system init. This way not all
the data structures allocated at system boot end up in node zero. */
- if (sys_set_mempolicy(MPOL_INTERLEAVE, nodes_addr(node_online_map),
- MAX_NUMNODES) < 0)
+ if (do_set_mempolicy(MPOL_INTERLEAVE, &node_online_map))
printk("numa_policy_init: interleaving failed\n");
}
-/* Reset policy of current process to default.
- * Assumes fs == KERNEL_DS */
+/* Reset policy of current process to default */
void numa_default_policy(void)
{
- sys_set_mempolicy(MPOL_DEFAULT, NULL, 0);
+ do_set_mempolicy(MPOL_DEFAULT, NULL);
+}
+
+/* Migrate a policy to a different set of nodes */
+static void rebind_policy(struct mempolicy *pol, const nodemask_t *old,
+ const nodemask_t *new)
+{
+ nodemask_t tmp;
+
+ if (!pol)
+ return;
+
+ switch (pol->policy) {
+ case MPOL_DEFAULT:
+ break;
+ case MPOL_INTERLEAVE:
+ nodes_remap(tmp, pol->v.nodes, *old, *new);
+ pol->v.nodes = tmp;
+ current->il_next = node_remap(current->il_next, *old, *new);
+ break;
+ case MPOL_PREFERRED:
+ pol->v.preferred_node = node_remap(pol->v.preferred_node,
+ *old, *new);
+ break;
+ case MPOL_BIND: {
+ nodemask_t nodes;
+ struct zone **z;
+ struct zonelist *zonelist;
+
+ nodes_clear(nodes);
+ for (z = pol->v.zonelist->zones; *z; z++)
+ node_set((*z)->zone_pgdat->node_id, nodes);
+ nodes_remap(tmp, nodes, *old, *new);
+ nodes = tmp;
+
+ zonelist = bind_zonelist(&nodes);
+
+ /* If no mem, then zonelist is NULL and we keep old zonelist.
+ * If that old zonelist has no remaining mems_allowed nodes,
+ * then zonelist_policy() will "FALL THROUGH" to MPOL_DEFAULT.
+ */
+
+ if (zonelist) {
+ /* Good - got mem - substitute new zonelist */
+ kfree(pol->v.zonelist);
+ pol->v.zonelist = zonelist;
+ }
+ break;
+ }
+ default:
+ BUG();
+ break;
+ }
+}
+
+/*
+ * Someone moved this task to different nodes. Fixup mempolicies.
+ *
+ * TODO - fixup current->mm->vma and shmfs/tmpfs/hugetlbfs policies as well,
+ * once we have a cpuset mechanism to mark which cpuset subtree is migrating.
+ */
+void numa_policy_rebind(const nodemask_t *old, const nodemask_t *new)
+{
+ rebind_policy(current->mempolicy, old, new);
}
diff --git a/mm/mempool.c b/mm/mempool.c
index 9e377ea700b2..1a99b80480d3 100644
--- a/mm/mempool.c
+++ b/mm/mempool.c
@@ -205,7 +205,7 @@ void * mempool_alloc(mempool_t *pool, gfp_t gfp_mask)
void *element;
unsigned long flags;
wait_queue_t wait;
- unsigned int gfp_temp;
+ gfp_t gfp_temp;
might_sleep_if(gfp_mask & __GFP_WAIT);
diff --git a/mm/mmap.c b/mm/mmap.c
index fa11d91242e8..6c997b159600 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -155,10 +155,6 @@ int __vm_enough_memory(long pages, int cap_sys_admin)
return -ENOMEM;
}
-EXPORT_SYMBOL(sysctl_overcommit_memory);
-EXPORT_SYMBOL(sysctl_overcommit_ratio);
-EXPORT_SYMBOL(sysctl_max_map_count);
-EXPORT_SYMBOL(vm_committed_space);
EXPORT_SYMBOL(__vm_enough_memory);
/*
@@ -181,26 +177,36 @@ static void __remove_shared_vm_struct(struct vm_area_struct *vma,
}
/*
- * Remove one vm structure and free it.
+ * Unlink a file-based vm structure from its prio_tree, to hide
+ * vma from rmap and vmtruncate before freeing its page tables.
*/
-static void remove_vm_struct(struct vm_area_struct *vma)
+void unlink_file_vma(struct vm_area_struct *vma)
{
struct file *file = vma->vm_file;
- might_sleep();
if (file) {
struct address_space *mapping = file->f_mapping;
spin_lock(&mapping->i_mmap_lock);
__remove_shared_vm_struct(vma, file, mapping);
spin_unlock(&mapping->i_mmap_lock);
}
+}
+
+/*
+ * Close a vm structure and free it, returning the next.
+ */
+static struct vm_area_struct *remove_vma(struct vm_area_struct *vma)
+{
+ struct vm_area_struct *next = vma->vm_next;
+
+ might_sleep();
if (vma->vm_ops && vma->vm_ops->close)
vma->vm_ops->close(vma);
- if (file)
- fput(file);
- anon_vma_unlink(vma);
+ if (vma->vm_file)
+ fput(vma->vm_file);
mpol_free(vma_policy(vma));
kmem_cache_free(vm_area_cachep, vma);
+ return next;
}
asmlinkage unsigned long sys_brk(unsigned long brk)
@@ -832,7 +838,7 @@ none:
}
#ifdef CONFIG_PROC_FS
-void __vm_stat_account(struct mm_struct *mm, unsigned long flags,
+void vm_stat_account(struct mm_struct *mm, unsigned long flags,
struct file *file, long pages)
{
const unsigned long stack_flags
@@ -1070,6 +1076,17 @@ munmap_back:
error = file->f_op->mmap(file, vma);
if (error)
goto unmap_and_free_vma;
+ if ((vma->vm_flags & (VM_SHARED | VM_WRITE | VM_RESERVED))
+ == (VM_WRITE | VM_RESERVED)) {
+ printk(KERN_WARNING "program %s is using MAP_PRIVATE, "
+ "PROT_WRITE mmap of VM_RESERVED memory, which "
+ "is deprecated. Please report this to "
+ "linux-kernel@vger.kernel.org\n",current->comm);
+ if (vma->vm_ops && vma->vm_ops->close)
+ vma->vm_ops->close(vma);
+ error = -EACCES;
+ goto unmap_and_free_vma;
+ }
} else if (vm_flags & VM_SHARED) {
error = shmem_zero_setup(vma);
if (error)
@@ -1110,7 +1127,7 @@ munmap_back:
}
out:
mm->total_vm += len >> PAGE_SHIFT;
- __vm_stat_account(mm, vm_flags, file, len >> PAGE_SHIFT);
+ vm_stat_account(mm, vm_flags, file, len >> PAGE_SHIFT);
if (vm_flags & VM_LOCKED) {
mm->locked_vm += len >> PAGE_SHIFT;
make_pages_present(addr, addr + len);
@@ -1475,15 +1492,19 @@ static int acct_stack_growth(struct vm_area_struct * vma, unsigned long size, un
mm->total_vm += grow;
if (vma->vm_flags & VM_LOCKED)
mm->locked_vm += grow;
- __vm_stat_account(mm, vma->vm_flags, vma->vm_file, grow);
+ vm_stat_account(mm, vma->vm_flags, vma->vm_file, grow);
return 0;
}
-#ifdef CONFIG_STACK_GROWSUP
+#if defined(CONFIG_STACK_GROWSUP) || defined(CONFIG_IA64)
/*
- * vma is the first one with address > vma->vm_end. Have to extend vma.
+ * PA-RISC uses this for its stack; IA64 for its Register Backing Store.
+ * vma is the last one with address > vma->vm_end. Have to extend vma.
*/
-int expand_stack(struct vm_area_struct * vma, unsigned long address)
+#ifdef CONFIG_STACK_GROWSUP
+static inline
+#endif
+int expand_upwards(struct vm_area_struct *vma, unsigned long address)
{
int error;
@@ -1521,6 +1542,13 @@ int expand_stack(struct vm_area_struct * vma, unsigned long address)
anon_vma_unlock(vma);
return error;
}
+#endif /* CONFIG_STACK_GROWSUP || CONFIG_IA64 */
+
+#ifdef CONFIG_STACK_GROWSUP
+int expand_stack(struct vm_area_struct *vma, unsigned long address)
+{
+ return expand_upwards(vma, address);
+}
struct vm_area_struct *
find_extend_vma(struct mm_struct *mm, unsigned long addr)
@@ -1603,36 +1631,24 @@ find_extend_vma(struct mm_struct * mm, unsigned long addr)
}
#endif
-/* Normal function to fix up a mapping
- * This function is the default for when an area has no specific
- * function. This may be used as part of a more specific routine.
- *
- * By the time this function is called, the area struct has been
- * removed from the process mapping list.
- */
-static void unmap_vma(struct mm_struct *mm, struct vm_area_struct *area)
-{
- size_t len = area->vm_end - area->vm_start;
-
- area->vm_mm->total_vm -= len >> PAGE_SHIFT;
- if (area->vm_flags & VM_LOCKED)
- area->vm_mm->locked_vm -= len >> PAGE_SHIFT;
- vm_stat_unaccount(area);
- remove_vm_struct(area);
-}
-
/*
- * Update the VMA and inode share lists.
- *
- * Ok - we have the memory areas we should free on the 'free' list,
+ * Ok - we have the memory areas we should free on the vma list,
* so release them, and do the vma updates.
+ *
+ * Called with the mm semaphore held.
*/
-static void unmap_vma_list(struct mm_struct *mm, struct vm_area_struct *vma)
+static void remove_vma_list(struct mm_struct *mm, struct vm_area_struct *vma)
{
+ /* Update high watermark before we lower total_vm */
+ update_hiwater_vm(mm);
do {
- struct vm_area_struct *next = vma->vm_next;
- unmap_vma(mm, vma);
- vma = next;
+ long nrpages = vma_pages(vma);
+
+ mm->total_vm -= nrpages;
+ if (vma->vm_flags & VM_LOCKED)
+ mm->locked_vm -= nrpages;
+ vm_stat_account(mm, vma->vm_flags, vma->vm_file, -nrpages);
+ vma = remove_vma(vma);
} while (vma);
validate_mm(mm);
}
@@ -1651,14 +1667,13 @@ static void unmap_region(struct mm_struct *mm,
unsigned long nr_accounted = 0;
lru_add_drain();
- spin_lock(&mm->page_table_lock);
tlb = tlb_gather_mmu(mm, 0);
- unmap_vmas(&tlb, mm, vma, start, end, &nr_accounted, NULL);
+ update_hiwater_rss(mm);
+ unmap_vmas(&tlb, vma, start, end, &nr_accounted, NULL);
vm_unacct_memory(nr_accounted);
free_pgtables(&tlb, vma, prev? prev->vm_end: FIRST_USER_ADDRESS,
next? next->vm_start: 0);
tlb_finish_mmu(tlb, start, end);
- spin_unlock(&mm->page_table_lock);
}
/*
@@ -1799,7 +1814,7 @@ int do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
unmap_region(mm, vma, prev, start, end);
/* Fix up all other VM information */
- unmap_vma_list(mm, vma);
+ remove_vma_list(mm, vma);
return 0;
}
@@ -1821,7 +1836,7 @@ asmlinkage long sys_munmap(unsigned long addr, size_t len)
static inline void verify_mm_writelocked(struct mm_struct *mm)
{
-#ifdef CONFIG_DEBUG_KERNEL
+#ifdef CONFIG_DEBUG_VM
if (unlikely(down_read_trylock(&mm->mmap_sem))) {
WARN_ON(1);
up_read(&mm->mmap_sem);
@@ -1933,34 +1948,21 @@ void exit_mmap(struct mm_struct *mm)
unsigned long end;
lru_add_drain();
-
- spin_lock(&mm->page_table_lock);
-
flush_cache_mm(mm);
tlb = tlb_gather_mmu(mm, 1);
+ /* Don't update_hiwater_rss(mm) here, do_exit already did */
/* Use -1 here to ensure all VMAs in the mm are unmapped */
- end = unmap_vmas(&tlb, mm, vma, 0, -1, &nr_accounted, NULL);
+ end = unmap_vmas(&tlb, vma, 0, -1, &nr_accounted, NULL);
vm_unacct_memory(nr_accounted);
free_pgtables(&tlb, vma, FIRST_USER_ADDRESS, 0);
tlb_finish_mmu(tlb, 0, end);
- mm->mmap = mm->mmap_cache = NULL;
- mm->mm_rb = RB_ROOT;
- set_mm_counter(mm, rss, 0);
- mm->total_vm = 0;
- mm->locked_vm = 0;
-
- spin_unlock(&mm->page_table_lock);
-
/*
- * Walk the list again, actually closing and freeing it
- * without holding any MM locks.
+ * Walk the list again, actually closing and freeing it,
+ * with preemption enabled, without holding any MM locks.
*/
- while (vma) {
- struct vm_area_struct *next = vma->vm_next;
- remove_vm_struct(vma);
- vma = next;
- }
+ while (vma)
+ vma = remove_vma(vma);
BUG_ON(mm->nr_ptes > (FIRST_USER_ADDRESS+PMD_SIZE-1)>>PMD_SHIFT);
}
diff --git a/mm/mprotect.c b/mm/mprotect.c
index 57577f63b305..17a2b52b753b 100644
--- a/mm/mprotect.c
+++ b/mm/mprotect.c
@@ -29,8 +29,9 @@ static void change_pte_range(struct mm_struct *mm, pmd_t *pmd,
unsigned long addr, unsigned long end, pgprot_t newprot)
{
pte_t *pte;
+ spinlock_t *ptl;
- pte = pte_offset_map(pmd, addr);
+ pte = pte_offset_map_lock(mm, pmd, addr, &ptl);
do {
if (pte_present(*pte)) {
pte_t ptent;
@@ -44,7 +45,7 @@ static void change_pte_range(struct mm_struct *mm, pmd_t *pmd,
lazy_mmu_prot_update(ptent);
}
} while (pte++, addr += PAGE_SIZE, addr != end);
- pte_unmap(pte - 1);
+ pte_unmap_unlock(pte - 1, ptl);
}
static inline void change_pmd_range(struct mm_struct *mm, pud_t *pud,
@@ -88,7 +89,6 @@ static void change_protection(struct vm_area_struct *vma,
BUG_ON(addr >= end);
pgd = pgd_offset(mm, addr);
flush_cache_range(vma, addr, end);
- spin_lock(&mm->page_table_lock);
do {
next = pgd_addr_end(addr, end);
if (pgd_none_or_clear_bad(pgd))
@@ -96,7 +96,6 @@ static void change_protection(struct vm_area_struct *vma,
change_pud_range(mm, pgd, addr, next, newprot);
} while (pgd++, addr = next, addr != end);
flush_tlb_range(vma, start, end);
- spin_unlock(&mm->page_table_lock);
}
static int
@@ -125,6 +124,14 @@ mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev,
* a MAP_NORESERVE private mapping to writable will now reserve.
*/
if (newflags & VM_WRITE) {
+ if (oldflags & VM_RESERVED) {
+ BUG_ON(oldflags & VM_WRITE);
+ printk(KERN_WARNING "program %s is using MAP_PRIVATE, "
+ "PROT_WRITE mprotect of VM_RESERVED memory, "
+ "which is deprecated. Please report this to "
+ "linux-kernel@vger.kernel.org\n",current->comm);
+ return -EACCES;
+ }
if (!(oldflags & (VM_ACCOUNT|VM_WRITE|VM_SHARED|VM_HUGETLB))) {
charged = nrpages;
if (security_vm_enough_memory(charged))
@@ -168,8 +175,8 @@ success:
vma->vm_flags = newflags;
vma->vm_page_prot = newprot;
change_protection(vma, start, end, newprot);
- __vm_stat_account(mm, oldflags, vma->vm_file, -nrpages);
- __vm_stat_account(mm, newflags, vma->vm_file, nrpages);
+ vm_stat_account(mm, oldflags, vma->vm_file, -nrpages);
+ vm_stat_account(mm, newflags, vma->vm_file, nrpages);
return 0;
fail:
diff --git a/mm/mremap.c b/mm/mremap.c
index f343fc73a8bd..b535438c363c 100644
--- a/mm/mremap.c
+++ b/mm/mremap.c
@@ -22,35 +22,7 @@
#include <asm/cacheflush.h>
#include <asm/tlbflush.h>
-static pte_t *get_one_pte_map_nested(struct mm_struct *mm, unsigned long addr)
-{
- pgd_t *pgd;
- pud_t *pud;
- pmd_t *pmd;
- pte_t *pte = NULL;
-
- pgd = pgd_offset(mm, addr);
- if (pgd_none_or_clear_bad(pgd))
- goto end;
-
- pud = pud_offset(pgd, addr);
- if (pud_none_or_clear_bad(pud))
- goto end;
-
- pmd = pmd_offset(pud, addr);
- if (pmd_none_or_clear_bad(pmd))
- goto end;
-
- pte = pte_offset_map_nested(pmd, addr);
- if (pte_none(*pte)) {
- pte_unmap_nested(pte);
- pte = NULL;
- }
-end:
- return pte;
-}
-
-static pte_t *get_one_pte_map(struct mm_struct *mm, unsigned long addr)
+static pmd_t *get_old_pmd(struct mm_struct *mm, unsigned long addr)
{
pgd_t *pgd;
pud_t *pud;
@@ -68,35 +40,39 @@ static pte_t *get_one_pte_map(struct mm_struct *mm, unsigned long addr)
if (pmd_none_or_clear_bad(pmd))
return NULL;
- return pte_offset_map(pmd, addr);
+ return pmd;
}
-static inline pte_t *alloc_one_pte_map(struct mm_struct *mm, unsigned long addr)
+static pmd_t *alloc_new_pmd(struct mm_struct *mm, unsigned long addr)
{
pgd_t *pgd;
pud_t *pud;
pmd_t *pmd;
- pte_t *pte = NULL;
pgd = pgd_offset(mm, addr);
-
pud = pud_alloc(mm, pgd, addr);
if (!pud)
return NULL;
+
pmd = pmd_alloc(mm, pud, addr);
- if (pmd)
- pte = pte_alloc_map(mm, pmd, addr);
- return pte;
+ if (!pmd)
+ return NULL;
+
+ if (!pmd_present(*pmd) && __pte_alloc(mm, pmd, addr))
+ return NULL;
+
+ return pmd;
}
-static int
-move_one_page(struct vm_area_struct *vma, unsigned long old_addr,
- struct vm_area_struct *new_vma, unsigned long new_addr)
+static void move_ptes(struct vm_area_struct *vma, pmd_t *old_pmd,
+ unsigned long old_addr, unsigned long old_end,
+ struct vm_area_struct *new_vma, pmd_t *new_pmd,
+ unsigned long new_addr)
{
struct address_space *mapping = NULL;
struct mm_struct *mm = vma->vm_mm;
- int error = 0;
- pte_t *src, *dst;
+ pte_t *old_pte, *new_pte, pte;
+ spinlock_t *old_ptl, *new_ptl;
if (vma->vm_file) {
/*
@@ -111,74 +87,69 @@ move_one_page(struct vm_area_struct *vma, unsigned long old_addr,
new_vma->vm_truncate_count != vma->vm_truncate_count)
new_vma->vm_truncate_count = 0;
}
- spin_lock(&mm->page_table_lock);
- src = get_one_pte_map_nested(mm, old_addr);
- if (src) {
- /*
- * Look to see whether alloc_one_pte_map needs to perform a
- * memory allocation. If it does then we need to drop the
- * atomic kmap
- */
- dst = get_one_pte_map(mm, new_addr);
- if (unlikely(!dst)) {
- pte_unmap_nested(src);
- if (mapping)
- spin_unlock(&mapping->i_mmap_lock);
- dst = alloc_one_pte_map(mm, new_addr);
- if (mapping && !spin_trylock(&mapping->i_mmap_lock)) {
- spin_unlock(&mm->page_table_lock);
- spin_lock(&mapping->i_mmap_lock);
- spin_lock(&mm->page_table_lock);
- }
- src = get_one_pte_map_nested(mm, old_addr);
- }
- /*
- * Since alloc_one_pte_map can drop and re-acquire
- * page_table_lock, we should re-check the src entry...
- */
- if (src) {
- if (dst) {
- pte_t pte;
- pte = ptep_clear_flush(vma, old_addr, src);
-
- /* ZERO_PAGE can be dependant on virtual addr */
- pte = move_pte(pte, new_vma->vm_page_prot,
- old_addr, new_addr);
- set_pte_at(mm, new_addr, dst, pte);
- } else
- error = -ENOMEM;
- pte_unmap_nested(src);
- }
- if (dst)
- pte_unmap(dst);
+ /*
+ * We don't have to worry about the ordering of src and dst
+ * pte locks because exclusive mmap_sem prevents deadlock.
+ */
+ old_pte = pte_offset_map_lock(mm, old_pmd, old_addr, &old_ptl);
+ new_pte = pte_offset_map_nested(new_pmd, new_addr);
+ new_ptl = pte_lockptr(mm, new_pmd);
+ if (new_ptl != old_ptl)
+ spin_lock(new_ptl);
+
+ for (; old_addr < old_end; old_pte++, old_addr += PAGE_SIZE,
+ new_pte++, new_addr += PAGE_SIZE) {
+ if (pte_none(*old_pte))
+ continue;
+ pte = ptep_clear_flush(vma, old_addr, old_pte);
+ /* ZERO_PAGE can be dependant on virtual addr */
+ pte = move_pte(pte, new_vma->vm_page_prot, old_addr, new_addr);
+ set_pte_at(mm, new_addr, new_pte, pte);
}
- spin_unlock(&mm->page_table_lock);
+
+ if (new_ptl != old_ptl)
+ spin_unlock(new_ptl);
+ pte_unmap_nested(new_pte - 1);
+ pte_unmap_unlock(old_pte - 1, old_ptl);
if (mapping)
spin_unlock(&mapping->i_mmap_lock);
- return error;
}
+#define LATENCY_LIMIT (64 * PAGE_SIZE)
+
static unsigned long move_page_tables(struct vm_area_struct *vma,
unsigned long old_addr, struct vm_area_struct *new_vma,
unsigned long new_addr, unsigned long len)
{
- unsigned long offset;
+ unsigned long extent, next, old_end;
+ pmd_t *old_pmd, *new_pmd;
- flush_cache_range(vma, old_addr, old_addr + len);
+ old_end = old_addr + len;
+ flush_cache_range(vma, old_addr, old_end);
- /*
- * This is not the clever way to do this, but we're taking the
- * easy way out on the assumption that most remappings will be
- * only a few pages.. This also makes error recovery easier.
- */
- for (offset = 0; offset < len; offset += PAGE_SIZE) {
- if (move_one_page(vma, old_addr + offset,
- new_vma, new_addr + offset) < 0)
- break;
+ for (; old_addr < old_end; old_addr += extent, new_addr += extent) {
cond_resched();
+ next = (old_addr + PMD_SIZE) & PMD_MASK;
+ if (next - 1 > old_end)
+ next = old_end;
+ extent = next - old_addr;
+ old_pmd = get_old_pmd(vma->vm_mm, old_addr);
+ if (!old_pmd)
+ continue;
+ new_pmd = alloc_new_pmd(vma->vm_mm, new_addr);
+ if (!new_pmd)
+ break;
+ next = (new_addr + PMD_SIZE) & PMD_MASK;
+ if (extent > next - new_addr)
+ extent = next - new_addr;
+ if (extent > LATENCY_LIMIT)
+ extent = LATENCY_LIMIT;
+ move_ptes(vma, old_pmd, old_addr, old_addr + extent,
+ new_vma, new_pmd, new_addr);
}
- return offset;
+
+ return len + old_addr - old_end; /* how much done */
}
static unsigned long move_vma(struct vm_area_struct *vma,
@@ -191,6 +162,7 @@ static unsigned long move_vma(struct vm_area_struct *vma,
unsigned long new_pgoff;
unsigned long moved_len;
unsigned long excess = 0;
+ unsigned long hiwater_vm;
int split = 0;
/*
@@ -229,17 +201,24 @@ static unsigned long move_vma(struct vm_area_struct *vma,
}
/*
- * if we failed to move page tables we still do total_vm increment
- * since do_munmap() will decrement it by old_len == new_len
+ * If we failed to move page tables we still do total_vm increment
+ * since do_munmap() will decrement it by old_len == new_len.
+ *
+ * Since total_vm is about to be raised artificially high for a
+ * moment, we need to restore high watermark afterwards: if stats
+ * are taken meanwhile, total_vm and hiwater_vm appear too high.
+ * If this were a serious issue, we'd add a flag to do_munmap().
*/
+ hiwater_vm = mm->hiwater_vm;
mm->total_vm += new_len >> PAGE_SHIFT;
- __vm_stat_account(mm, vma->vm_flags, vma->vm_file, new_len>>PAGE_SHIFT);
+ vm_stat_account(mm, vma->vm_flags, vma->vm_file, new_len>>PAGE_SHIFT);
if (do_munmap(mm, old_addr, old_len) < 0) {
/* OOM: unable to split vma, just get accounts right */
vm_unacct_memory(excess >> PAGE_SHIFT);
excess = 0;
}
+ mm->hiwater_vm = hiwater_vm;
/* Restore VM_ACCOUNT if one or two pieces of vma left */
if (excess) {
@@ -269,6 +248,7 @@ unsigned long do_mremap(unsigned long addr,
unsigned long old_len, unsigned long new_len,
unsigned long flags, unsigned long new_addr)
{
+ struct mm_struct *mm = current->mm;
struct vm_area_struct *vma;
unsigned long ret = -EINVAL;
unsigned long charged = 0;
@@ -309,7 +289,7 @@ unsigned long do_mremap(unsigned long addr,
if ((addr <= new_addr) && (addr+old_len) > new_addr)
goto out;
- ret = do_munmap(current->mm, new_addr, new_len);
+ ret = do_munmap(mm, new_addr, new_len);
if (ret)
goto out;
}
@@ -320,7 +300,7 @@ unsigned long do_mremap(unsigned long addr,
* do_munmap does all the needed commit accounting
*/
if (old_len >= new_len) {
- ret = do_munmap(current->mm, addr+new_len, old_len - new_len);
+ ret = do_munmap(mm, addr+new_len, old_len - new_len);
if (ret && old_len != new_len)
goto out;
ret = addr;
@@ -333,7 +313,7 @@ unsigned long do_mremap(unsigned long addr,
* Ok, we need to grow.. or relocate.
*/
ret = -EFAULT;
- vma = find_vma(current->mm, addr);
+ vma = find_vma(mm, addr);
if (!vma || vma->vm_start > addr)
goto out;
if (is_vm_hugetlb_page(vma)) {
@@ -349,14 +329,14 @@ unsigned long do_mremap(unsigned long addr,
}
if (vma->vm_flags & VM_LOCKED) {
unsigned long locked, lock_limit;
- locked = current->mm->locked_vm << PAGE_SHIFT;
+ locked = mm->locked_vm << PAGE_SHIFT;
lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur;
locked += new_len - old_len;
ret = -EAGAIN;
if (locked > lock_limit && !capable(CAP_IPC_LOCK))
goto out;
}
- if (!may_expand_vm(current->mm, (new_len - old_len) >> PAGE_SHIFT)) {
+ if (!may_expand_vm(mm, (new_len - old_len) >> PAGE_SHIFT)) {
ret = -ENOMEM;
goto out;
}
@@ -383,11 +363,10 @@ unsigned long do_mremap(unsigned long addr,
vma_adjust(vma, vma->vm_start,
addr + new_len, vma->vm_pgoff, NULL);
- current->mm->total_vm += pages;
- __vm_stat_account(vma->vm_mm, vma->vm_flags,
- vma->vm_file, pages);
+ mm->total_vm += pages;
+ vm_stat_account(mm, vma->vm_flags, vma->vm_file, pages);
if (vma->vm_flags & VM_LOCKED) {
- current->mm->locked_vm += pages;
+ mm->locked_vm += pages;
make_pages_present(addr + old_len,
addr + new_len);
}
diff --git a/mm/msync.c b/mm/msync.c
index d0f5a1bce7cb..0e040e9c39d8 100644
--- a/mm/msync.c
+++ b/mm/msync.c
@@ -17,40 +17,48 @@
#include <asm/pgtable.h>
#include <asm/tlbflush.h>
-/*
- * Called with mm->page_table_lock held to protect against other
- * threads/the swapper from ripping pte's out from under us.
- */
-
-static void sync_pte_range(struct vm_area_struct *vma, pmd_t *pmd,
+static void msync_pte_range(struct vm_area_struct *vma, pmd_t *pmd,
unsigned long addr, unsigned long end)
{
pte_t *pte;
+ spinlock_t *ptl;
+ int progress = 0;
- pte = pte_offset_map(pmd, addr);
+again:
+ pte = pte_offset_map_lock(vma->vm_mm, pmd, addr, &ptl);
do {
unsigned long pfn;
struct page *page;
+ if (progress >= 64) {
+ progress = 0;
+ if (need_resched() || need_lockbreak(ptl))
+ break;
+ }
+ progress++;
if (!pte_present(*pte))
continue;
if (!pte_maybe_dirty(*pte))
continue;
pfn = pte_pfn(*pte);
- if (!pfn_valid(pfn))
+ if (unlikely(!pfn_valid(pfn))) {
+ print_bad_pte(vma, *pte, addr);
continue;
+ }
page = pfn_to_page(pfn);
- if (PageReserved(page))
- continue;
if (ptep_clear_flush_dirty(vma, addr, pte) ||
page_test_and_clear_dirty(page))
set_page_dirty(page);
+ progress += 3;
} while (pte++, addr += PAGE_SIZE, addr != end);
- pte_unmap(pte - 1);
+ pte_unmap_unlock(pte - 1, ptl);
+ cond_resched();
+ if (addr != end)
+ goto again;
}
-static inline void sync_pmd_range(struct vm_area_struct *vma, pud_t *pud,
+static inline void msync_pmd_range(struct vm_area_struct *vma, pud_t *pud,
unsigned long addr, unsigned long end)
{
pmd_t *pmd;
@@ -61,11 +69,11 @@ static inline void sync_pmd_range(struct vm_area_struct *vma, pud_t *pud,
next = pmd_addr_end(addr, end);
if (pmd_none_or_clear_bad(pmd))
continue;
- sync_pte_range(vma, pmd, addr, next);
+ msync_pte_range(vma, pmd, addr, next);
} while (pmd++, addr = next, addr != end);
}
-static inline void sync_pud_range(struct vm_area_struct *vma, pgd_t *pgd,
+static inline void msync_pud_range(struct vm_area_struct *vma, pgd_t *pgd,
unsigned long addr, unsigned long end)
{
pud_t *pud;
@@ -76,58 +84,34 @@ static inline void sync_pud_range(struct vm_area_struct *vma, pgd_t *pgd,
next = pud_addr_end(addr, end);
if (pud_none_or_clear_bad(pud))
continue;
- sync_pmd_range(vma, pud, addr, next);
+ msync_pmd_range(vma, pud, addr, next);
} while (pud++, addr = next, addr != end);
}
-static void sync_page_range(struct vm_area_struct *vma,
+static void msync_page_range(struct vm_area_struct *vma,
unsigned long addr, unsigned long end)
{
- struct mm_struct *mm = vma->vm_mm;
pgd_t *pgd;
unsigned long next;
/* For hugepages we can't go walking the page table normally,
* but that's ok, hugetlbfs is memory based, so we don't need
- * to do anything more on an msync() */
- if (is_vm_hugetlb_page(vma))
+ * to do anything more on an msync().
+ * Can't do anything with VM_RESERVED regions either.
+ */
+ if (vma->vm_flags & (VM_HUGETLB|VM_RESERVED))
return;
BUG_ON(addr >= end);
- pgd = pgd_offset(mm, addr);
+ pgd = pgd_offset(vma->vm_mm, addr);
flush_cache_range(vma, addr, end);
- spin_lock(&mm->page_table_lock);
do {
next = pgd_addr_end(addr, end);
if (pgd_none_or_clear_bad(pgd))
continue;
- sync_pud_range(vma, pgd, addr, next);
+ msync_pud_range(vma, pgd, addr, next);
} while (pgd++, addr = next, addr != end);
- spin_unlock(&mm->page_table_lock);
-}
-
-#ifdef CONFIG_PREEMPT
-static inline void filemap_sync(struct vm_area_struct *vma,
- unsigned long addr, unsigned long end)
-{
- const size_t chunk = 64 * 1024; /* bytes */
- unsigned long next;
-
- do {
- next = addr + chunk;
- if (next > end || next < addr)
- next = end;
- sync_page_range(vma, addr, next);
- cond_resched();
- } while (addr = next, addr != end);
-}
-#else
-static inline void filemap_sync(struct vm_area_struct *vma,
- unsigned long addr, unsigned long end)
-{
- sync_page_range(vma, addr, end);
}
-#endif
/*
* MS_SYNC syncs the entire file - including mappings.
@@ -150,7 +134,7 @@ static int msync_interval(struct vm_area_struct *vma,
return -EBUSY;
if (file && (vma->vm_flags & VM_SHARED)) {
- filemap_sync(vma, addr, end);
+ msync_page_range(vma, addr, end);
if (flags & MS_SYNC) {
struct address_space *mapping = file->f_mapping;
diff --git a/mm/nommu.c b/mm/nommu.c
index 0ef241ae3763..6deb6ab3d6ad 100644
--- a/mm/nommu.c
+++ b/mm/nommu.c
@@ -44,10 +44,6 @@ int sysctl_max_map_count = DEFAULT_MAX_MAP_COUNT;
int heap_stack_gap = 0;
EXPORT_SYMBOL(mem_map);
-EXPORT_SYMBOL(sysctl_max_map_count);
-EXPORT_SYMBOL(sysctl_overcommit_memory);
-EXPORT_SYMBOL(sysctl_overcommit_ratio);
-EXPORT_SYMBOL(vm_committed_space);
EXPORT_SYMBOL(__vm_enough_memory);
/* list of shareable VMAs */
@@ -931,6 +927,8 @@ int do_munmap(struct mm_struct *mm, unsigned long addr, size_t len)
realalloc -= kobjsize(vml);
askedalloc -= sizeof(*vml);
kfree(vml);
+
+ update_hiwater_vm(mm);
mm->total_vm -= len >> PAGE_SHIFT;
#ifdef DEBUG
@@ -1047,7 +1045,8 @@ struct vm_area_struct *find_vma(struct mm_struct *mm, unsigned long addr)
EXPORT_SYMBOL(find_vma);
-struct page * follow_page(struct mm_struct *mm, unsigned long addr, int write)
+struct page *follow_page(struct mm_struct *mm, unsigned long address,
+ unsigned int foll_flags)
{
return NULL;
}
@@ -1078,19 +1077,6 @@ void arch_unmap_area(struct mm_struct *mm, unsigned long addr)
{
}
-void update_mem_hiwater(struct task_struct *tsk)
-{
- unsigned long rss;
-
- if (likely(tsk->mm)) {
- rss = get_mm_counter(tsk->mm, rss);
- if (tsk->mm->hiwater_rss < rss)
- tsk->mm->hiwater_rss = rss;
- if (tsk->mm->hiwater_vm < tsk->mm->total_vm)
- tsk->mm->hiwater_vm = tsk->mm->total_vm;
- }
-}
-
void unmap_mapping_range(struct address_space *mapping,
loff_t const holebegin, loff_t const holelen,
int even_cows)
diff --git a/mm/page-writeback.c b/mm/page-writeback.c
index 0166ea15c9ee..74138c9a22b9 100644
--- a/mm/page-writeback.c
+++ b/mm/page-writeback.c
@@ -750,7 +750,6 @@ int clear_page_dirty_for_io(struct page *page)
}
return TestClearPageDirty(page);
}
-EXPORT_SYMBOL(clear_page_dirty_for_io);
int test_clear_page_writeback(struct page *page)
{
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index e1d3d77f4aee..987225bdd661 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -33,6 +33,7 @@
#include <linux/sysctl.h>
#include <linux/cpu.h>
#include <linux/cpuset.h>
+#include <linux/memory_hotplug.h>
#include <linux/nodemask.h>
#include <linux/vmalloc.h>
@@ -63,7 +64,6 @@ long nr_swap_pages;
int sysctl_lowmem_reserve_ratio[MAX_NR_ZONES-1] = { 256, 32 };
EXPORT_SYMBOL(totalram_pages);
-EXPORT_SYMBOL(nr_swap_pages);
/*
* Used by page_zone() to look up the address of the struct zone whose
@@ -78,21 +78,44 @@ int min_free_kbytes = 1024;
unsigned long __initdata nr_kernel_pages;
unsigned long __initdata nr_all_pages;
+static int page_outside_zone_boundaries(struct zone *zone, struct page *page)
+{
+ int ret = 0;
+ unsigned seq;
+ unsigned long pfn = page_to_pfn(page);
+
+ do {
+ seq = zone_span_seqbegin(zone);
+ if (pfn >= zone->zone_start_pfn + zone->spanned_pages)
+ ret = 1;
+ else if (pfn < zone->zone_start_pfn)
+ ret = 1;
+ } while (zone_span_seqretry(zone, seq));
+
+ return ret;
+}
+
+static int page_is_consistent(struct zone *zone, struct page *page)
+{
+#ifdef CONFIG_HOLES_IN_ZONE
+ if (!pfn_valid(page_to_pfn(page)))
+ return 0;
+#endif
+ if (zone != page_zone(page))
+ return 0;
+
+ return 1;
+}
/*
* Temporary debugging check for pages not lying within a given zone.
*/
static int bad_range(struct zone *zone, struct page *page)
{
- if (page_to_pfn(page) >= zone->zone_start_pfn + zone->spanned_pages)
+ if (page_outside_zone_boundaries(zone, page))
return 1;
- if (page_to_pfn(page) < zone->zone_start_pfn)
- return 1;
-#ifdef CONFIG_HOLES_IN_ZONE
- if (!pfn_valid(page_to_pfn(page)))
- return 1;
-#endif
- if (zone != page_zone(page))
+ if (!page_is_consistent(zone, page))
return 1;
+
return 0;
}
@@ -114,7 +137,8 @@ static void bad_page(const char *function, struct page *page)
1 << PG_reclaim |
1 << PG_slab |
1 << PG_swapcache |
- 1 << PG_writeback);
+ 1 << PG_writeback |
+ 1 << PG_reserved );
set_page_count(page, 0);
reset_page_mapcount(page);
page->mapping = NULL;
@@ -153,7 +177,7 @@ static void prep_compound_page(struct page *page, unsigned long order)
struct page *p = page + i;
SetPageCompound(p);
- p->private = (unsigned long)page;
+ set_page_private(p, (unsigned long)page);
}
}
@@ -173,7 +197,7 @@ static void destroy_compound_page(struct page *page, unsigned long order)
if (!PageCompound(p))
bad_page(__FUNCTION__, page);
- if (p->private != (unsigned long)page)
+ if (page_private(p) != (unsigned long)page)
bad_page(__FUNCTION__, page);
ClearPageCompound(p);
}
@@ -186,18 +210,18 @@ static void destroy_compound_page(struct page *page, unsigned long order)
* So, we don't need atomic page->flags operations here.
*/
static inline unsigned long page_order(struct page *page) {
- return page->private;
+ return page_private(page);
}
static inline void set_page_order(struct page *page, int order) {
- page->private = order;
+ set_page_private(page, order);
__SetPagePrivate(page);
}
static inline void rmv_page_order(struct page *page)
{
__ClearPagePrivate(page);
- page->private = 0;
+ set_page_private(page, 0);
}
/*
@@ -237,14 +261,13 @@ __find_combined_index(unsigned long page_idx, unsigned int order)
* (a) the buddy is free &&
* (b) the buddy is on the buddy system &&
* (c) a page and its buddy have the same order.
- * for recording page's order, we use page->private and PG_private.
+ * for recording page's order, we use page_private(page) and PG_private.
*
*/
static inline int page_is_buddy(struct page *page, int order)
{
if (PagePrivate(page) &&
(page_order(page) == order) &&
- !PageReserved(page) &&
page_count(page) == 0)
return 1;
return 0;
@@ -264,7 +287,7 @@ static inline int page_is_buddy(struct page *page, int order)
* parts of the VM system.
* At each level, we keep a list of pages, which are heads of continuous
* free pages of length of (1 << order) and marked with PG_Private.Page's
- * order is recorded in page->private field.
+ * order is recorded in page_private(page) field.
* So when we are allocating or freeing one, we can derive the state of the
* other. That is, if we allocate a small block, and both were
* free, the remainder of the region must be split into blocks.
@@ -327,7 +350,8 @@ static inline void free_pages_check(const char *function, struct page *page)
1 << PG_reclaim |
1 << PG_slab |
1 << PG_swapcache |
- 1 << PG_writeback )))
+ 1 << PG_writeback |
+ 1 << PG_reserved )))
bad_page(function, page);
if (PageDirty(page))
__ClearPageDirty(page);
@@ -455,13 +479,14 @@ static void prep_new_page(struct page *page, int order)
1 << PG_reclaim |
1 << PG_slab |
1 << PG_swapcache |
- 1 << PG_writeback )))
+ 1 << PG_writeback |
+ 1 << PG_reserved )))
bad_page(__FUNCTION__, page);
page->flags &= ~(1 << PG_uptodate | 1 << PG_error |
1 << PG_referenced | 1 << PG_arch_1 |
1 << PG_checked | 1 << PG_mappedtodisk);
- page->private = 0;
+ set_page_private(page, 0);
set_page_refs(page, order);
kernel_map_pages(page, 1 << order, 1);
}
@@ -734,7 +759,7 @@ buffered_rmqueue(struct zone *zone, int order, gfp_t gfp_flags)
* of the allocation.
*/
int zone_watermark_ok(struct zone *z, int order, unsigned long mark,
- int classzone_idx, int can_try_harder, int gfp_high)
+ int classzone_idx, int can_try_harder, gfp_t gfp_high)
{
/* free_pages my go negative - that's OK */
long min = mark, free_pages = z->free_pages - (1 << order) + 1;
@@ -777,7 +802,7 @@ struct page * fastcall
__alloc_pages(gfp_t gfp_mask, unsigned int order,
struct zonelist *zonelist)
{
- const int wait = gfp_mask & __GFP_WAIT;
+ const gfp_t wait = gfp_mask & __GFP_WAIT;
struct zone **zones, *z;
struct page *page;
struct reclaim_state reclaim_state;
@@ -996,7 +1021,7 @@ fastcall unsigned long get_zeroed_page(gfp_t gfp_mask)
* get_zeroed_page() returns a 32-bit address, which cannot represent
* a highmem page
*/
- BUG_ON(gfp_mask & __GFP_HIGHMEM);
+ BUG_ON((gfp_mask & __GFP_HIGHMEM) != 0);
page = alloc_pages(gfp_mask | __GFP_ZERO, 0);
if (page)
@@ -1016,7 +1041,7 @@ void __pagevec_free(struct pagevec *pvec)
fastcall void __free_pages(struct page *page, unsigned int order)
{
- if (!PageReserved(page) && put_page_testzero(page)) {
+ if (put_page_testzero(page)) {
if (order == 0)
free_hot_page(page);
else
@@ -1089,7 +1114,7 @@ static unsigned int nr_free_zone_pages(int offset)
*/
unsigned int nr_free_buffer_pages(void)
{
- return nr_free_zone_pages(GFP_USER & GFP_ZONEMASK);
+ return nr_free_zone_pages(gfp_zone(GFP_USER));
}
/*
@@ -1097,7 +1122,7 @@ unsigned int nr_free_buffer_pages(void)
*/
unsigned int nr_free_pagecache_pages(void)
{
- return nr_free_zone_pages(GFP_HIGHUSER & GFP_ZONEMASK);
+ return nr_free_zone_pages(gfp_zone(GFP_HIGHUSER));
}
#ifdef CONFIG_HIGHMEM
@@ -1305,12 +1330,9 @@ void show_free_areas(void)
} else
printk("\n");
- for (cpu = 0; cpu < NR_CPUS; ++cpu) {
+ for_each_online_cpu(cpu) {
struct per_cpu_pageset *pageset;
- if (!cpu_possible(cpu))
- continue;
-
pageset = zone_pcp(zone, cpu);
for (temperature = 0; temperature < 2; temperature++)
@@ -1428,6 +1450,16 @@ static int __init build_zonelists_node(pg_data_t *pgdat, struct zonelist *zoneli
return j;
}
+static inline int highest_zone(int zone_bits)
+{
+ int res = ZONE_NORMAL;
+ if (zone_bits & (__force int)__GFP_HIGHMEM)
+ res = ZONE_HIGHMEM;
+ if (zone_bits & (__force int)__GFP_DMA)
+ res = ZONE_DMA;
+ return res;
+}
+
#ifdef CONFIG_NUMA
#define MAX_NODE_LOAD (num_online_nodes())
static int __initdata node_load[MAX_NUMNODES];
@@ -1524,11 +1556,7 @@ static void __init build_zonelists(pg_data_t *pgdat)
zonelist = pgdat->node_zonelists + i;
for (j = 0; zonelist->zones[j] != NULL; j++);
- k = ZONE_NORMAL;
- if (i & __GFP_HIGHMEM)
- k = ZONE_HIGHMEM;
- if (i & __GFP_DMA)
- k = ZONE_DMA;
+ k = highest_zone(i);
j = build_zonelists_node(NODE_DATA(node), zonelist, j, k);
zonelist->zones[j] = NULL;
@@ -1549,12 +1577,7 @@ static void __init build_zonelists(pg_data_t *pgdat)
zonelist = pgdat->node_zonelists + i;
j = 0;
- k = ZONE_NORMAL;
- if (i & __GFP_HIGHMEM)
- k = ZONE_HIGHMEM;
- if (i & __GFP_DMA)
- k = ZONE_DMA;
-
+ k = highest_zone(i);
j = build_zonelists_node(pgdat, zonelist, j, k);
/*
* Now we build the zonelist so that it contains the zones
@@ -1659,7 +1682,7 @@ static void __init calculate_zone_totalpages(struct pglist_data *pgdat,
* up by free_all_bootmem() once the early boot process is
* done. Non-atomic initialization, single-pass.
*/
-void __init memmap_init_zone(unsigned long size, int nid, unsigned long zone,
+void __devinit memmap_init_zone(unsigned long size, int nid, unsigned long zone,
unsigned long start_pfn)
{
struct page *page;
@@ -1673,7 +1696,7 @@ void __init memmap_init_zone(unsigned long size, int nid, unsigned long zone,
continue;
page = pfn_to_page(pfn);
set_page_links(page, zone, nid, pfn);
- set_page_count(page, 0);
+ set_page_count(page, 1);
reset_page_mapcount(page);
SetPageReserved(page);
INIT_LIST_HEAD(&page->lru);
@@ -1720,29 +1743,29 @@ static int __devinit zone_batchsize(struct zone *zone)
/*
* The per-cpu-pages pools are set to around 1000th of the
- * size of the zone. But no more than 1/4 of a meg - there's
- * no point in going beyond the size of L2 cache.
+ * size of the zone. But no more than 1/2 of a meg.
*
* OK, so we don't know how big the cache is. So guess.
*/
batch = zone->present_pages / 1024;
- if (batch * PAGE_SIZE > 256 * 1024)
- batch = (256 * 1024) / PAGE_SIZE;
+ if (batch * PAGE_SIZE > 512 * 1024)
+ batch = (512 * 1024) / PAGE_SIZE;
batch /= 4; /* We effectively *= 4 below */
if (batch < 1)
batch = 1;
/*
- * Clamp the batch to a 2^n - 1 value. Having a power
- * of 2 value was found to be more likely to have
- * suboptimal cache aliasing properties in some cases.
+ * We will be trying to allcoate bigger chunks of contiguous
+ * memory of the order of fls(batch). This should result in
+ * better cache coloring.
*
- * For example if 2 tasks are alternately allocating
- * batches of pages, one task can end up with a lot
- * of pages of one half of the possible page colors
- * and the other with pages of the other colors.
+ * A sanity check also to ensure that batch is still in limits.
*/
- batch = (1 << fls(batch + batch/2)) - 1;
+ batch = (1 << fls(batch + batch/2));
+
+ if (fls(batch) >= (PAGE_SHIFT + MAX_ORDER - 2))
+ batch = PAGE_SHIFT + ((MAX_ORDER - 1 - PAGE_SHIFT)/2);
+
return batch;
}
@@ -1754,7 +1777,7 @@ inline void setup_pageset(struct per_cpu_pageset *p, unsigned long batch)
pcp = &p->pcp[0]; /* hot */
pcp->count = 0;
- pcp->low = 2 * batch;
+ pcp->low = 0;
pcp->high = 6 * batch;
pcp->batch = max(1UL, 1 * batch);
INIT_LIST_HEAD(&pcp->list);
@@ -1763,7 +1786,7 @@ inline void setup_pageset(struct per_cpu_pageset *p, unsigned long batch)
pcp->count = 0;
pcp->low = 0;
pcp->high = 2 * batch;
- pcp->batch = max(1UL, 1 * batch);
+ pcp->batch = max(1UL, batch/2);
INIT_LIST_HEAD(&pcp->list);
}
@@ -1872,6 +1895,60 @@ void __init setup_per_cpu_pageset()
#endif
+static __devinit
+void zone_wait_table_init(struct zone *zone, unsigned long zone_size_pages)
+{
+ int i;
+ struct pglist_data *pgdat = zone->zone_pgdat;
+
+ /*
+ * The per-page waitqueue mechanism uses hashed waitqueues
+ * per zone.
+ */
+ zone->wait_table_size = wait_table_size(zone_size_pages);
+ zone->wait_table_bits = wait_table_bits(zone->wait_table_size);
+ zone->wait_table = (wait_queue_head_t *)
+ alloc_bootmem_node(pgdat, zone->wait_table_size
+ * sizeof(wait_queue_head_t));
+
+ for(i = 0; i < zone->wait_table_size; ++i)
+ init_waitqueue_head(zone->wait_table + i);
+}
+
+static __devinit void zone_pcp_init(struct zone *zone)
+{
+ int cpu;
+ unsigned long batch = zone_batchsize(zone);
+
+ for (cpu = 0; cpu < NR_CPUS; cpu++) {
+#ifdef CONFIG_NUMA
+ /* Early boot. Slab allocator not functional yet */
+ zone->pageset[cpu] = &boot_pageset[cpu];
+ setup_pageset(&boot_pageset[cpu],0);
+#else
+ setup_pageset(zone_pcp(zone,cpu), batch);
+#endif
+ }
+ printk(KERN_DEBUG " %s zone: %lu pages, LIFO batch:%lu\n",
+ zone->name, zone->present_pages, batch);
+}
+
+static __devinit void init_currently_empty_zone(struct zone *zone,
+ unsigned long zone_start_pfn, unsigned long size)
+{
+ struct pglist_data *pgdat = zone->zone_pgdat;
+
+ zone_wait_table_init(zone, size);
+ pgdat->nr_zones = zone_idx(zone) + 1;
+
+ zone->zone_mem_map = pfn_to_page(zone_start_pfn);
+ zone->zone_start_pfn = zone_start_pfn;
+
+ memmap_init(size, pgdat->node_id, zone_idx(zone), zone_start_pfn);
+
+ zone_init_free_lists(pgdat, zone, zone->spanned_pages);
+}
+
/*
* Set up the zone data structures:
* - mark all pages reserved
@@ -1881,10 +1958,11 @@ void __init setup_per_cpu_pageset()
static void __init free_area_init_core(struct pglist_data *pgdat,
unsigned long *zones_size, unsigned long *zholes_size)
{
- unsigned long i, j;
- int cpu, nid = pgdat->node_id;
+ unsigned long j;
+ int nid = pgdat->node_id;
unsigned long zone_start_pfn = pgdat->node_start_pfn;
+ pgdat_resize_init(pgdat);
pgdat->nr_zones = 0;
init_waitqueue_head(&pgdat->kswapd_wait);
pgdat->kswapd_max_order = 0;
@@ -1892,7 +1970,6 @@ static void __init free_area_init_core(struct pglist_data *pgdat,
for (j = 0; j < MAX_NR_ZONES; j++) {
struct zone *zone = pgdat->node_zones + j;
unsigned long size, realsize;
- unsigned long batch;
realsize = size = zones_size[j];
if (zholes_size)
@@ -1907,24 +1984,13 @@ static void __init free_area_init_core(struct pglist_data *pgdat,
zone->name = zone_names[j];
spin_lock_init(&zone->lock);
spin_lock_init(&zone->lru_lock);
+ zone_seqlock_init(zone);
zone->zone_pgdat = pgdat;
zone->free_pages = 0;
zone->temp_priority = zone->prev_priority = DEF_PRIORITY;
- batch = zone_batchsize(zone);
-
- for (cpu = 0; cpu < NR_CPUS; cpu++) {
-#ifdef CONFIG_NUMA
- /* Early boot. Slab allocator not functional yet */
- zone->pageset[cpu] = &boot_pageset[cpu];
- setup_pageset(&boot_pageset[cpu],0);
-#else
- setup_pageset(zone_pcp(zone,cpu), batch);
-#endif
- }
- printk(KERN_DEBUG " %s zone: %lu pages, LIFO batch:%lu\n",
- zone_names[j], realsize, batch);
+ zone_pcp_init(zone);
INIT_LIST_HEAD(&zone->active_list);
INIT_LIST_HEAD(&zone->inactive_list);
zone->nr_scan_active = 0;
@@ -1935,32 +2001,9 @@ static void __init free_area_init_core(struct pglist_data *pgdat,
if (!size)
continue;
- /*
- * The per-page waitqueue mechanism uses hashed waitqueues
- * per zone.
- */
- zone->wait_table_size = wait_table_size(size);
- zone->wait_table_bits =
- wait_table_bits(zone->wait_table_size);
- zone->wait_table = (wait_queue_head_t *)
- alloc_bootmem_node(pgdat, zone->wait_table_size
- * sizeof(wait_queue_head_t));
-
- for(i = 0; i < zone->wait_table_size; ++i)
- init_waitqueue_head(zone->wait_table + i);
-
- pgdat->nr_zones = j+1;
-
- zone->zone_mem_map = pfn_to_page(zone_start_pfn);
- zone->zone_start_pfn = zone_start_pfn;
-
- memmap_init(size, nid, j, zone_start_pfn);
-
zonetable_add(zone, nid, j, zone_start_pfn, size);
-
+ init_currently_empty_zone(zone, zone_start_pfn, size);
zone_start_pfn += size;
-
- zone_init_free_lists(pgdat, zone, zone->spanned_pages);
}
}
@@ -2360,7 +2403,7 @@ static void setup_per_zone_lowmem_reserve(void)
* that the pages_{min,low,high} values for each zone are set correctly
* with respect to min_free_kbytes.
*/
-static void setup_per_zone_pages_min(void)
+void setup_per_zone_pages_min(void)
{
unsigned long pages_min = min_free_kbytes >> (PAGE_SHIFT - 10);
unsigned long lowmem_pages = 0;
diff --git a/mm/page_io.c b/mm/page_io.c
index 330e00d6db00..bb2b0d53889c 100644
--- a/mm/page_io.c
+++ b/mm/page_io.c
@@ -91,7 +91,8 @@ int swap_writepage(struct page *page, struct writeback_control *wbc)
unlock_page(page);
goto out;
}
- bio = get_swap_bio(GFP_NOIO, page->private, page, end_swap_bio_write);
+ bio = get_swap_bio(GFP_NOIO, page_private(page), page,
+ end_swap_bio_write);
if (bio == NULL) {
set_page_dirty(page);
unlock_page(page);
@@ -115,7 +116,8 @@ int swap_readpage(struct file *file, struct page *page)
BUG_ON(!PageLocked(page));
ClearPageUptodate(page);
- bio = get_swap_bio(GFP_KERNEL, page->private, page, end_swap_bio_read);
+ bio = get_swap_bio(GFP_KERNEL, page_private(page), page,
+ end_swap_bio_read);
if (bio == NULL) {
unlock_page(page);
ret = -ENOMEM;
diff --git a/mm/pdflush.c b/mm/pdflush.c
index d6781951267e..52822c98c489 100644
--- a/mm/pdflush.c
+++ b/mm/pdflush.c
@@ -20,6 +20,7 @@
#include <linux/fs.h> // Needed by writeback.h
#include <linux/writeback.h> // Prototypes pdflush_operation()
#include <linux/kthread.h>
+#include <linux/cpuset.h>
/*
@@ -170,12 +171,24 @@ static int __pdflush(struct pdflush_work *my_work)
static int pdflush(void *dummy)
{
struct pdflush_work my_work;
+ cpumask_t cpus_allowed;
/*
* pdflush can spend a lot of time doing encryption via dm-crypt. We
* don't want to do that at keventd's priority.
*/
set_user_nice(current, 0);
+
+ /*
+ * Some configs put our parent kthread in a limited cpuset,
+ * which kthread() overrides, forcing cpus_allowed == CPU_MASK_ALL.
+ * Our needs are more modest - cut back to our cpusets cpus_allowed.
+ * This is needed as pdflush's are dynamically created and destroyed.
+ * The boottime pdflush's are easily placed w/o these 2 lines.
+ */
+ cpus_allowed = cpuset_cpus_allowed(current);
+ set_cpus_allowed(current, cpus_allowed);
+
return __pdflush(&my_work);
}
diff --git a/mm/readahead.c b/mm/readahead.c
index d0b50034e245..72e7adbb87c7 100644
--- a/mm/readahead.c
+++ b/mm/readahead.c
@@ -254,7 +254,7 @@ out:
*/
static int
__do_page_cache_readahead(struct address_space *mapping, struct file *filp,
- unsigned long offset, unsigned long nr_to_read)
+ pgoff_t offset, unsigned long nr_to_read)
{
struct inode *inode = mapping->host;
struct page *page;
@@ -274,7 +274,7 @@ __do_page_cache_readahead(struct address_space *mapping, struct file *filp,
*/
read_lock_irq(&mapping->tree_lock);
for (page_idx = 0; page_idx < nr_to_read; page_idx++) {
- unsigned long page_offset = offset + page_idx;
+ pgoff_t page_offset = offset + page_idx;
if (page_offset > end_index)
break;
@@ -311,7 +311,7 @@ out:
* memory at once.
*/
int force_page_cache_readahead(struct address_space *mapping, struct file *filp,
- unsigned long offset, unsigned long nr_to_read)
+ pgoff_t offset, unsigned long nr_to_read)
{
int ret = 0;
@@ -368,7 +368,7 @@ static inline int check_ra_success(struct file_ra_state *ra,
* request queues.
*/
int do_page_cache_readahead(struct address_space *mapping, struct file *filp,
- unsigned long offset, unsigned long nr_to_read)
+ pgoff_t offset, unsigned long nr_to_read)
{
if (bdi_read_congested(mapping->backing_dev_info))
return -1;
@@ -385,7 +385,7 @@ int do_page_cache_readahead(struct address_space *mapping, struct file *filp,
*/
static int
blockable_page_cache_readahead(struct address_space *mapping, struct file *filp,
- unsigned long offset, unsigned long nr_to_read,
+ pgoff_t offset, unsigned long nr_to_read,
struct file_ra_state *ra, int block)
{
int actual;
@@ -430,14 +430,27 @@ static int make_ahead_window(struct address_space *mapping, struct file *filp,
return ret;
}
-/*
- * page_cache_readahead is the main function. If performs the adaptive
+/**
+ * page_cache_readahead - generic adaptive readahead
+ * @mapping: address_space which holds the pagecache and I/O vectors
+ * @ra: file_ra_state which holds the readahead state
+ * @filp: passed on to ->readpage() and ->readpages()
+ * @offset: start offset into @mapping, in PAGE_CACHE_SIZE units
+ * @req_size: hint: total size of the read which the caller is performing in
+ * PAGE_CACHE_SIZE units
+ *
+ * page_cache_readahead() is the main function. If performs the adaptive
* readahead window size management and submits the readahead I/O.
+ *
+ * Note that @filp is purely used for passing on to the ->readpage[s]()
+ * handler: it may refer to a different file from @mapping (so we may not use
+ * @filp->f_mapping or @filp->f_dentry->d_inode here).
+ * Also, @ra may not be equal to &@filp->f_ra.
+ *
*/
unsigned long
page_cache_readahead(struct address_space *mapping, struct file_ra_state *ra,
- struct file *filp, unsigned long offset,
- unsigned long req_size)
+ struct file *filp, pgoff_t offset, unsigned long req_size)
{
unsigned long max, newsize;
int sequential;
diff --git a/mm/rmap.c b/mm/rmap.c
index 450f5241b5a5..914d04b98bee 100644
--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -32,7 +32,7 @@
* page->flags PG_locked (lock_page)
* mapping->i_mmap_lock
* anon_vma->lock
- * mm->page_table_lock
+ * mm->page_table_lock or pte_lock
* zone->lru_lock (in mark_page_accessed)
* swap_lock (in swap_duplicate, swap_info_get)
* mmlist_lock (in mmput, drain_mmlist and others)
@@ -244,37 +244,44 @@ unsigned long page_address_in_vma(struct page *page, struct vm_area_struct *vma)
/*
* Check that @page is mapped at @address into @mm.
*
- * On success returns with mapped pte and locked mm->page_table_lock.
+ * On success returns with pte mapped and locked.
*/
pte_t *page_check_address(struct page *page, struct mm_struct *mm,
- unsigned long address)
+ unsigned long address, spinlock_t **ptlp)
{
pgd_t *pgd;
pud_t *pud;
pmd_t *pmd;
pte_t *pte;
+ spinlock_t *ptl;
- /*
- * We need the page_table_lock to protect us from page faults,
- * munmap, fork, etc...
- */
- spin_lock(&mm->page_table_lock);
pgd = pgd_offset(mm, address);
- if (likely(pgd_present(*pgd))) {
- pud = pud_offset(pgd, address);
- if (likely(pud_present(*pud))) {
- pmd = pmd_offset(pud, address);
- if (likely(pmd_present(*pmd))) {
- pte = pte_offset_map(pmd, address);
- if (likely(pte_present(*pte) &&
- page_to_pfn(page) == pte_pfn(*pte)))
- return pte;
- pte_unmap(pte);
- }
- }
+ if (!pgd_present(*pgd))
+ return NULL;
+
+ pud = pud_offset(pgd, address);
+ if (!pud_present(*pud))
+ return NULL;
+
+ pmd = pmd_offset(pud, address);
+ if (!pmd_present(*pmd))
+ return NULL;
+
+ pte = pte_offset_map(pmd, address);
+ /* Make a quick check before getting the lock */
+ if (!pte_present(*pte)) {
+ pte_unmap(pte);
+ return NULL;
+ }
+
+ ptl = pte_lockptr(mm, pmd);
+ spin_lock(ptl);
+ if (pte_present(*pte) && page_to_pfn(page) == pte_pfn(*pte)) {
+ *ptlp = ptl;
+ return pte;
}
- spin_unlock(&mm->page_table_lock);
- return ERR_PTR(-ENOENT);
+ pte_unmap_unlock(pte, ptl);
+ return NULL;
}
/*
@@ -287,24 +294,28 @@ static int page_referenced_one(struct page *page,
struct mm_struct *mm = vma->vm_mm;
unsigned long address;
pte_t *pte;
+ spinlock_t *ptl;
int referenced = 0;
address = vma_address(page, vma);
if (address == -EFAULT)
goto out;
- pte = page_check_address(page, mm, address);
- if (!IS_ERR(pte)) {
- if (ptep_clear_flush_young(vma, address, pte))
- referenced++;
+ pte = page_check_address(page, mm, address, &ptl);
+ if (!pte)
+ goto out;
- if (mm != current->mm && !ignore_token && has_swap_token(mm))
- referenced++;
+ if (ptep_clear_flush_young(vma, address, pte))
+ referenced++;
- (*mapcount)--;
- pte_unmap(pte);
- spin_unlock(&mm->page_table_lock);
- }
+ /* Pretend the page is referenced if the task has the
+ swap token and is in the middle of a page fault. */
+ if (mm != current->mm && !ignore_token && has_swap_token(mm) &&
+ rwsem_is_locked(&mm->mmap_sem))
+ referenced++;
+
+ (*mapcount)--;
+ pte_unmap_unlock(pte, ptl);
out:
return referenced;
}
@@ -434,15 +445,11 @@ int page_referenced(struct page *page, int is_locked, int ignore_token)
* @vma: the vm area in which the mapping is added
* @address: the user virtual address mapped
*
- * The caller needs to hold the mm->page_table_lock.
+ * The caller needs to hold the pte lock.
*/
void page_add_anon_rmap(struct page *page,
struct vm_area_struct *vma, unsigned long address)
{
- BUG_ON(PageReserved(page));
-
- inc_mm_counter(vma->vm_mm, anon_rss);
-
if (atomic_inc_and_test(&page->_mapcount)) {
struct anon_vma *anon_vma = vma->anon_vma;
@@ -461,13 +468,12 @@ void page_add_anon_rmap(struct page *page,
* page_add_file_rmap - add pte mapping to a file page
* @page: the page to add the mapping to
*
- * The caller needs to hold the mm->page_table_lock.
+ * The caller needs to hold the pte lock.
*/
void page_add_file_rmap(struct page *page)
{
BUG_ON(PageAnon(page));
- if (!pfn_valid(page_to_pfn(page)) || PageReserved(page))
- return;
+ BUG_ON(!pfn_valid(page_to_pfn(page)));
if (atomic_inc_and_test(&page->_mapcount))
inc_page_state(nr_mapped);
@@ -477,12 +483,10 @@ void page_add_file_rmap(struct page *page)
* page_remove_rmap - take down pte mapping from a page
* @page: page to remove mapping from
*
- * Caller needs to hold the mm->page_table_lock.
+ * The caller needs to hold the pte lock.
*/
void page_remove_rmap(struct page *page)
{
- BUG_ON(PageReserved(page));
-
if (atomic_add_negative(-1, &page->_mapcount)) {
BUG_ON(page_mapcount(page) < 0);
/*
@@ -510,14 +514,15 @@ static int try_to_unmap_one(struct page *page, struct vm_area_struct *vma)
unsigned long address;
pte_t *pte;
pte_t pteval;
+ spinlock_t *ptl;
int ret = SWAP_AGAIN;
address = vma_address(page, vma);
if (address == -EFAULT)
goto out;
- pte = page_check_address(page, mm, address);
- if (IS_ERR(pte))
+ pte = page_check_address(page, mm, address, &ptl);
+ if (!pte)
goto out;
/*
@@ -541,8 +546,11 @@ static int try_to_unmap_one(struct page *page, struct vm_area_struct *vma)
if (pte_dirty(pteval))
set_page_dirty(page);
+ /* Update high watermark before we lower rss */
+ update_hiwater_rss(mm);
+
if (PageAnon(page)) {
- swp_entry_t entry = { .val = page->private };
+ swp_entry_t entry = { .val = page_private(page) };
/*
* Store the swap location in the pte.
* See handle_pte_fault() ...
@@ -551,21 +559,21 @@ static int try_to_unmap_one(struct page *page, struct vm_area_struct *vma)
swap_duplicate(entry);
if (list_empty(&mm->mmlist)) {
spin_lock(&mmlist_lock);
- list_add(&mm->mmlist, &init_mm.mmlist);
+ if (list_empty(&mm->mmlist))
+ list_add(&mm->mmlist, &init_mm.mmlist);
spin_unlock(&mmlist_lock);
}
set_pte_at(mm, address, pte, swp_entry_to_pte(entry));
BUG_ON(pte_file(*pte));
dec_mm_counter(mm, anon_rss);
- }
+ } else
+ dec_mm_counter(mm, file_rss);
- dec_mm_counter(mm, rss);
page_remove_rmap(page);
page_cache_release(page);
out_unmap:
- pte_unmap(pte);
- spin_unlock(&mm->page_table_lock);
+ pte_unmap_unlock(pte, ptl);
out:
return ret;
}
@@ -599,19 +607,14 @@ static void try_to_unmap_cluster(unsigned long cursor,
pgd_t *pgd;
pud_t *pud;
pmd_t *pmd;
- pte_t *pte, *original_pte;
+ pte_t *pte;
pte_t pteval;
+ spinlock_t *ptl;
struct page *page;
unsigned long address;
unsigned long end;
unsigned long pfn;
- /*
- * We need the page_table_lock to protect us from page faults,
- * munmap, fork, etc...
- */
- spin_lock(&mm->page_table_lock);
-
address = (vma->vm_start + cursor) & CLUSTER_MASK;
end = address + CLUSTER_SIZE;
if (address < vma->vm_start)
@@ -621,30 +624,33 @@ static void try_to_unmap_cluster(unsigned long cursor,
pgd = pgd_offset(mm, address);
if (!pgd_present(*pgd))
- goto out_unlock;
+ return;
pud = pud_offset(pgd, address);
if (!pud_present(*pud))
- goto out_unlock;
+ return;
pmd = pmd_offset(pud, address);
if (!pmd_present(*pmd))
- goto out_unlock;
+ return;
+
+ pte = pte_offset_map_lock(mm, pmd, address, &ptl);
- for (original_pte = pte = pte_offset_map(pmd, address);
- address < end; pte++, address += PAGE_SIZE) {
+ /* Update high watermark before we lower rss */
+ update_hiwater_rss(mm);
+ for (; address < end; pte++, address += PAGE_SIZE) {
if (!pte_present(*pte))
continue;
pfn = pte_pfn(*pte);
- if (!pfn_valid(pfn))
+ if (unlikely(!pfn_valid(pfn))) {
+ print_bad_pte(vma, *pte, address);
continue;
+ }
page = pfn_to_page(pfn);
BUG_ON(PageAnon(page));
- if (PageReserved(page))
- continue;
if (ptep_clear_flush_young(vma, address, pte))
continue;
@@ -663,13 +669,10 @@ static void try_to_unmap_cluster(unsigned long cursor,
page_remove_rmap(page);
page_cache_release(page);
- dec_mm_counter(mm, rss);
+ dec_mm_counter(mm, file_rss);
(*mapcount)--;
}
-
- pte_unmap(original_pte);
-out_unlock:
- spin_unlock(&mm->page_table_lock);
+ pte_unmap_unlock(pte - 1, ptl);
}
static int try_to_unmap_anon(struct page *page)
@@ -806,7 +809,6 @@ int try_to_unmap(struct page *page)
{
int ret;
- BUG_ON(PageReserved(page));
BUG_ON(!PageLocked(page));
if (PageAnon(page))
diff --git a/mm/shmem.c b/mm/shmem.c
index ea064d89cda9..dc25565a61e9 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -71,9 +71,6 @@
/* Pretend that each entry is of this size in directory's i_size */
#define BOGO_DIRENT_SIZE 20
-/* Keep swapped page count in private field of indirect struct page */
-#define nr_swapped private
-
/* Flag allocation requirements to shmem_getpage and shmem_swp_alloc */
enum sgp_type {
SGP_QUICK, /* don't try more than file page cache lookup */
@@ -85,7 +82,7 @@ enum sgp_type {
static int shmem_getpage(struct inode *inode, unsigned long idx,
struct page **pagep, enum sgp_type sgp, int *type);
-static inline struct page *shmem_dir_alloc(unsigned int gfp_mask)
+static inline struct page *shmem_dir_alloc(gfp_t gfp_mask)
{
/*
* The above definition of ENTRIES_PER_PAGE, and the use of
@@ -324,8 +321,10 @@ static void shmem_swp_set(struct shmem_inode_info *info, swp_entry_t *entry, uns
entry->val = value;
info->swapped += incdec;
- if ((unsigned long)(entry - info->i_direct) >= SHMEM_NR_DIRECT)
- kmap_atomic_to_page(entry)->nr_swapped += incdec;
+ if ((unsigned long)(entry - info->i_direct) >= SHMEM_NR_DIRECT) {
+ struct page *page = kmap_atomic_to_page(entry);
+ set_page_private(page, page_private(page) + incdec);
+ }
}
/*
@@ -368,9 +367,8 @@ static swp_entry_t *shmem_swp_alloc(struct shmem_inode_info *info, unsigned long
spin_unlock(&info->lock);
page = shmem_dir_alloc(mapping_gfp_mask(inode->i_mapping) | __GFP_ZERO);
- if (page) {
- page->nr_swapped = 0;
- }
+ if (page)
+ set_page_private(page, 0);
spin_lock(&info->lock);
if (!page) {
@@ -561,7 +559,7 @@ static void shmem_truncate(struct inode *inode)
diroff = 0;
}
subdir = dir[diroff];
- if (subdir && subdir->nr_swapped) {
+ if (subdir && page_private(subdir)) {
size = limit - idx;
if (size > ENTRIES_PER_PAGE)
size = ENTRIES_PER_PAGE;
@@ -572,10 +570,10 @@ static void shmem_truncate(struct inode *inode)
nr_swaps_freed += freed;
if (offset)
spin_lock(&info->lock);
- subdir->nr_swapped -= freed;
+ set_page_private(subdir, page_private(subdir) - freed);
if (offset)
spin_unlock(&info->lock);
- BUG_ON(subdir->nr_swapped > offset);
+ BUG_ON(page_private(subdir) > offset);
}
if (offset)
offset = 0;
@@ -743,7 +741,7 @@ static int shmem_unuse_inode(struct shmem_inode_info *info, swp_entry_t entry, s
dir = shmem_dir_map(subdir);
}
subdir = *dir;
- if (subdir && subdir->nr_swapped) {
+ if (subdir && page_private(subdir)) {
ptr = shmem_swp_map(subdir);
size = limit - idx;
if (size > ENTRIES_PER_PAGE)
@@ -898,7 +896,7 @@ struct page *shmem_swapin(struct shmem_inode_info *info, swp_entry_t entry,
}
static struct page *
-shmem_alloc_page(unsigned long gfp, struct shmem_inode_info *info,
+shmem_alloc_page(gfp_t gfp, struct shmem_inode_info *info,
unsigned long idx)
{
struct vm_area_struct pvma;
@@ -1201,7 +1199,7 @@ static int shmem_populate(struct vm_area_struct *vma,
page_cache_release(page);
return err;
}
- } else {
+ } else if (vma->vm_flags & VM_NONLINEAR) {
/* No page was found just because we can't read it in
* now (being here implies nonblock != 0), but the page
* may exist, so set the PTE to fault it in later. */
@@ -1506,8 +1504,10 @@ static void do_shmem_file_read(struct file *filp, loff_t *ppos, read_descriptor_
*/
if (!offset)
mark_page_accessed(page);
- } else
+ } else {
page = ZERO_PAGE(0);
+ page_cache_get(page);
+ }
/*
* Ok, we have the page, and it's up-to-date, so
diff --git a/mm/slab.c b/mm/slab.c
index d05c678bceb3..e291f5e1afbb 100644
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -368,7 +368,7 @@ static inline void kmem_list3_init(struct kmem_list3 *parent)
* manages a cache.
*/
-struct kmem_cache_s {
+struct kmem_cache {
/* 1) per-cpu data, touched during every alloc/free */
struct array_cache *array[NR_CPUS];
unsigned int batchcount;
@@ -386,7 +386,7 @@ struct kmem_cache_s {
unsigned int gfporder;
/* force GFP flags, e.g. GFP_DMA */
- unsigned int gfpflags;
+ gfp_t gfpflags;
size_t colour; /* cache colouring range */
unsigned int colour_off; /* colour offset */
@@ -1502,6 +1502,7 @@ kmem_cache_create (const char *name, size_t size, size_t align,
{
size_t left_over, slab_size, ralign;
kmem_cache_t *cachep = NULL;
+ struct list_head *p;
/*
* Sanity checks... these are all serious usage bugs.
@@ -1516,6 +1517,35 @@ kmem_cache_create (const char *name, size_t size, size_t align,
BUG();
}
+ down(&cache_chain_sem);
+
+ list_for_each(p, &cache_chain) {
+ kmem_cache_t *pc = list_entry(p, kmem_cache_t, next);
+ mm_segment_t old_fs = get_fs();
+ char tmp;
+ 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.
+ */
+ set_fs(KERNEL_DS);
+ res = __get_user(tmp, pc->name);
+ set_fs(old_fs);
+ if (res) {
+ printk("SLAB: cache with size %d has lost its name\n",
+ pc->objsize);
+ continue;
+ }
+
+ if (!strcmp(pc->name,name)) {
+ printk("kmem_cache_create: duplicate cache %s\n", name);
+ dump_stack();
+ goto oops;
+ }
+ }
+
#if DEBUG
WARN_ON(strchr(name, ' ')); /* It confuses parsers */
if ((flags & SLAB_DEBUG_INITIAL) && !ctor) {
@@ -1592,7 +1622,7 @@ kmem_cache_create (const char *name, size_t size, size_t align,
/* Get cache's description obj. */
cachep = (kmem_cache_t *) kmem_cache_alloc(&cache_cache, SLAB_KERNEL);
if (!cachep)
- goto opps;
+ goto oops;
memset(cachep, 0, sizeof(kmem_cache_t));
#if DEBUG
@@ -1686,7 +1716,7 @@ next:
printk("kmem_cache_create: couldn't create cache %s.\n", name);
kmem_cache_free(&cache_cache, cachep);
cachep = NULL;
- goto opps;
+ goto oops;
}
slab_size = ALIGN(cachep->num*sizeof(kmem_bufctl_t)
+ sizeof(struct slab), align);
@@ -1781,43 +1811,14 @@ next:
cachep->limit = BOOT_CPUCACHE_ENTRIES;
}
- /* Need the semaphore to access the chain. */
- down(&cache_chain_sem);
- {
- struct list_head *p;
- mm_segment_t old_fs;
-
- old_fs = get_fs();
- set_fs(KERNEL_DS);
- list_for_each(p, &cache_chain) {
- kmem_cache_t *pc = list_entry(p, kmem_cache_t, next);
- char tmp;
- /* This happens when the module gets unloaded and doesn't
- destroy its slab cache and noone else reuses the vmalloc
- area of the module. Print a warning. */
- if (__get_user(tmp,pc->name)) {
- printk("SLAB: cache with size %d has lost its name\n",
- pc->objsize);
- continue;
- }
- if (!strcmp(pc->name,name)) {
- printk("kmem_cache_create: duplicate cache %s\n",name);
- up(&cache_chain_sem);
- unlock_cpu_hotplug();
- BUG();
- }
- }
- set_fs(old_fs);
- }
-
/* cache setup completed, link it into the list */
list_add(&cachep->next, &cache_chain);
- up(&cache_chain_sem);
unlock_cpu_hotplug();
-opps:
+oops:
if (!cachep && (flags & SLAB_PANIC))
panic("kmem_cache_create(): failed to create slab `%s'\n",
name);
+ up(&cache_chain_sem);
return cachep;
}
EXPORT_SYMBOL(kmem_cache_create);
@@ -2117,7 +2118,7 @@ static void cache_init_objs(kmem_cache_t *cachep,
slabp->free = 0;
}
-static void kmem_flagcheck(kmem_cache_t *cachep, unsigned int flags)
+static void kmem_flagcheck(kmem_cache_t *cachep, gfp_t flags)
{
if (flags & SLAB_DMA) {
if (!(cachep->gfpflags & GFP_DMA))
@@ -2152,7 +2153,7 @@ static int cache_grow(kmem_cache_t *cachep, gfp_t flags, int nodeid)
struct slab *slabp;
void *objp;
size_t offset;
- unsigned int local_flags;
+ gfp_t local_flags;
unsigned long ctor_flags;
struct kmem_list3 *l3;
@@ -2419,6 +2420,7 @@ retry:
next = slab_bufctl(slabp)[slabp->free];
#if DEBUG
slab_bufctl(slabp)[slabp->free] = BUFCTL_FREE;
+ WARN_ON(numa_node_id() != slabp->nodeid);
#endif
slabp->free = next;
}
@@ -2546,7 +2548,7 @@ static inline void *__cache_alloc(kmem_cache_t *cachep, gfp_t flags)
/*
* A interface to enable slab creation on nodeid
*/
-static void *__cache_alloc_node(kmem_cache_t *cachep, int flags, int nodeid)
+static void *__cache_alloc_node(kmem_cache_t *cachep, gfp_t flags, int nodeid)
{
struct list_head *entry;
struct slab *slabp;
@@ -2633,8 +2635,10 @@ static void free_block(kmem_cache_t *cachep, void **objpp, int nr_objects, int n
check_spinlock_acquired_node(cachep, node);
check_slabp(cachep, slabp);
-
#if DEBUG
+ /* Verify that the slab belongs to the intended node */
+ WARN_ON(slabp->nodeid != node);
+
if (slab_bufctl(slabp)[objnr] != BUFCTL_FREE) {
printk(KERN_ERR "slab: double free detected in cache "
"'%s', objp %p\n", cachep->name, objp);
@@ -3259,6 +3263,7 @@ static void drain_array_locked(kmem_cache_t *cachep,
/**
* cache_reap - Reclaim memory from caches.
+ * @unused: unused parameter
*
* Called from workqueue/eventd every few seconds.
* Purpose:
@@ -3275,7 +3280,7 @@ static void cache_reap(void *unused)
if (down_trylock(&cache_chain_sem)) {
/* Give up. Setup the next iteration. */
- schedule_delayed_work(&__get_cpu_var(reap_work), REAPTIMEOUT_CPUC + smp_processor_id());
+ schedule_delayed_work(&__get_cpu_var(reap_work), REAPTIMEOUT_CPUC);
return;
}
@@ -3344,7 +3349,7 @@ next:
up(&cache_chain_sem);
drain_remote_pages();
/* Setup the next iteration */
- schedule_delayed_work(&__get_cpu_var(reap_work), REAPTIMEOUT_CPUC + smp_processor_id());
+ schedule_delayed_work(&__get_cpu_var(reap_work), REAPTIMEOUT_CPUC);
}
#ifdef CONFIG_PROC_FS
diff --git a/mm/sparse.c b/mm/sparse.c
index 347249a4917a..72079b538e2d 100644
--- a/mm/sparse.c
+++ b/mm/sparse.c
@@ -5,8 +5,10 @@
#include <linux/mm.h>
#include <linux/mmzone.h>
#include <linux/bootmem.h>
+#include <linux/highmem.h>
#include <linux/module.h>
#include <linux/spinlock.h>
+#include <linux/vmalloc.h>
#include <asm/dma.h>
/*
@@ -72,6 +74,31 @@ static inline int sparse_index_init(unsigned long section_nr, int nid)
}
#endif
+/*
+ * Although written for the SPARSEMEM_EXTREME case, this happens
+ * to also work for the flat array case becase
+ * NR_SECTION_ROOTS==NR_MEM_SECTIONS.
+ */
+int __section_nr(struct mem_section* ms)
+{
+ unsigned long root_nr;
+ struct mem_section* root;
+
+ for (root_nr = 0;
+ root_nr < NR_MEM_SECTIONS;
+ root_nr += SECTIONS_PER_ROOT) {
+ root = __nr_to_section(root_nr);
+
+ if (!root)
+ continue;
+
+ if ((ms >= root) && (ms < (root + SECTIONS_PER_ROOT)))
+ break;
+ }
+
+ return (root_nr * SECTIONS_PER_ROOT) + (ms - root);
+}
+
/* Record a memory area against a node. */
void memory_present(int nid, unsigned long start, unsigned long end)
{
@@ -162,6 +189,45 @@ static struct page *sparse_early_mem_map_alloc(unsigned long pnum)
return NULL;
}
+static struct page *__kmalloc_section_memmap(unsigned long nr_pages)
+{
+ struct page *page, *ret;
+ unsigned long memmap_size = sizeof(struct page) * nr_pages;
+
+ page = alloc_pages(GFP_KERNEL, get_order(memmap_size));
+ if (page)
+ goto got_map_page;
+
+ ret = vmalloc(memmap_size);
+ if (ret)
+ goto got_map_ptr;
+
+ return NULL;
+got_map_page:
+ ret = (struct page *)pfn_to_kaddr(page_to_pfn(page));
+got_map_ptr:
+ memset(ret, 0, memmap_size);
+
+ return ret;
+}
+
+static int vaddr_in_vmalloc_area(void *addr)
+{
+ if (addr >= (void *)VMALLOC_START &&
+ addr < (void *)VMALLOC_END)
+ return 1;
+ return 0;
+}
+
+static void __kfree_section_memmap(struct page *memmap, unsigned long nr_pages)
+{
+ if (vaddr_in_vmalloc_area(memmap))
+ vfree(memmap);
+ else
+ free_pages((unsigned long)memmap,
+ get_order(sizeof(struct page) * nr_pages));
+}
+
/*
* Allocate the accumulated non-linear sections, allocate a mem_map
* for each and record the physical to section mapping.
@@ -187,14 +253,37 @@ void sparse_init(void)
* set. If this is <=0, then that means that the passed-in
* map was not consumed and must be freed.
*/
-int sparse_add_one_section(unsigned long start_pfn, int nr_pages, struct page *map)
+int sparse_add_one_section(struct zone *zone, unsigned long start_pfn,
+ int nr_pages)
{
- struct mem_section *ms = __pfn_to_section(start_pfn);
+ unsigned long section_nr = pfn_to_section_nr(start_pfn);
+ struct pglist_data *pgdat = zone->zone_pgdat;
+ struct mem_section *ms;
+ struct page *memmap;
+ unsigned long flags;
+ int ret;
- if (ms->section_mem_map & SECTION_MARKED_PRESENT)
- return -EEXIST;
+ /*
+ * no locking for this, because it does its own
+ * plus, it does a kmalloc
+ */
+ sparse_index_init(section_nr, pgdat->node_id);
+ memmap = __kmalloc_section_memmap(nr_pages);
+
+ pgdat_resize_lock(pgdat, &flags);
+ ms = __pfn_to_section(start_pfn);
+ if (ms->section_mem_map & SECTION_MARKED_PRESENT) {
+ ret = -EEXIST;
+ goto out;
+ }
ms->section_mem_map |= SECTION_MARKED_PRESENT;
- return sparse_init_one_section(ms, pfn_to_section_nr(start_pfn), map);
+ ret = sparse_init_one_section(ms, section_nr, memmap);
+
+ if (ret <= 0)
+ __kfree_section_memmap(memmap, nr_pages);
+out:
+ pgdat_resize_unlock(pgdat, &flags);
+ return ret;
}
diff --git a/mm/swap.c b/mm/swap.c
index 7771d2803f62..d09cf7f03e76 100644
--- a/mm/swap.c
+++ b/mm/swap.c
@@ -39,7 +39,7 @@ int page_cluster;
void put_page(struct page *page)
{
if (unlikely(PageCompound(page))) {
- page = (struct page *)page->private;
+ page = (struct page *)page_private(page);
if (put_page_testzero(page)) {
void (*dtor)(struct page *page);
@@ -48,7 +48,7 @@ void put_page(struct page *page)
}
return;
}
- if (!PageReserved(page) && put_page_testzero(page))
+ if (put_page_testzero(page))
__page_cache_release(page);
}
EXPORT_SYMBOL(put_page);
@@ -215,7 +215,7 @@ void release_pages(struct page **pages, int nr, int cold)
struct page *page = pages[i];
struct zone *pagezone;
- if (PageReserved(page) || !put_page_testzero(page))
+ if (!put_page_testzero(page))
continue;
pagezone = page_zone(page);
@@ -259,6 +259,8 @@ void __pagevec_release(struct pagevec *pvec)
pagevec_reinit(pvec);
}
+EXPORT_SYMBOL(__pagevec_release);
+
/*
* pagevec_release() for pages which are known to not be on the LRU
*
@@ -270,7 +272,6 @@ void __pagevec_release_nonlru(struct pagevec *pvec)
struct pagevec pages_to_free;
pagevec_init(&pages_to_free, pvec->cold);
- pages_to_free.cold = pvec->cold;
for (i = 0; i < pagevec_count(pvec); i++) {
struct page *page = pvec->pages[i];
@@ -388,6 +389,7 @@ unsigned pagevec_lookup_tag(struct pagevec *pvec, struct address_space *mapping,
return pagevec_count(pvec);
}
+EXPORT_SYMBOL(pagevec_lookup_tag);
#ifdef CONFIG_SMP
/*
@@ -411,7 +413,6 @@ void vm_acct_memory(long pages)
}
preempt_enable();
}
-EXPORT_SYMBOL(vm_acct_memory);
#ifdef CONFIG_HOTPLUG_CPU
static void lru_drain_cache(unsigned int cpu)
diff --git a/mm/swap_state.c b/mm/swap_state.c
index 132164f7d0a7..0df9a57b1de8 100644
--- a/mm/swap_state.c
+++ b/mm/swap_state.c
@@ -40,7 +40,6 @@ struct address_space swapper_space = {
.i_mmap_nonlinear = LIST_HEAD_INIT(swapper_space.i_mmap_nonlinear),
.backing_dev_info = &swap_backing_dev_info,
};
-EXPORT_SYMBOL(swapper_space);
#define INC_CACHE_INFO(x) do { swap_cache_info.x++; } while (0)
@@ -83,7 +82,7 @@ static int __add_to_swap_cache(struct page *page, swp_entry_t entry,
page_cache_get(page);
SetPageLocked(page);
SetPageSwapCache(page);
- page->private = entry.val;
+ set_page_private(page, entry.val);
total_swapcache_pages++;
pagecache_acct(1);
}
@@ -126,8 +125,8 @@ void __delete_from_swap_cache(struct page *page)
BUG_ON(PageWriteback(page));
BUG_ON(PagePrivate(page));
- radix_tree_delete(&swapper_space.page_tree, page->private);
- page->private = 0;
+ radix_tree_delete(&swapper_space.page_tree, page_private(page));
+ set_page_private(page, 0);
ClearPageSwapCache(page);
total_swapcache_pages--;
pagecache_acct(-1);
@@ -197,7 +196,7 @@ void delete_from_swap_cache(struct page *page)
{
swp_entry_t entry;
- entry.val = page->private;
+ entry.val = page_private(page);
write_lock_irq(&swapper_space.tree_lock);
__delete_from_swap_cache(page);
@@ -259,8 +258,7 @@ static inline void free_swap_cache(struct page *page)
/*
* Perform a free_page(), also freeing any swap cache associated with
- * this page if it is the last user of the page. Can not do a lock_page,
- * as we are holding the page_table_lock spinlock.
+ * this page if it is the last user of the page.
*/
void free_page_and_swap_cache(struct page *page)
{
diff --git a/mm/swapfile.c b/mm/swapfile.c
index 1dcaeda039f4..edafeace301f 100644
--- a/mm/swapfile.c
+++ b/mm/swapfile.c
@@ -36,8 +36,6 @@ unsigned int nr_swapfiles;
long total_swap_pages;
static int swap_overflow;
-EXPORT_SYMBOL(total_swap_pages);
-
static const char Bad_file[] = "Bad swap file entry ";
static const char Unused_file[] = "Unused swap file entry ";
static const char Bad_offset[] = "Bad swap offset entry ";
@@ -61,7 +59,7 @@ void swap_unplug_io_fn(struct backing_dev_info *unused_bdi, struct page *page)
swp_entry_t entry;
down_read(&swap_unplug_sem);
- entry.val = page->private;
+ entry.val = page_private(page);
if (PageSwapCache(page)) {
struct block_device *bdev = swap_info[swp_type(entry)].bdev;
struct backing_dev_info *bdi;
@@ -69,8 +67,8 @@ void swap_unplug_io_fn(struct backing_dev_info *unused_bdi, struct page *page)
/*
* If the page is removed from swapcache from under us (with a
* racy try_to_unuse/swapoff) we need an additional reference
- * count to avoid reading garbage from page->private above. If
- * the WARN_ON triggers during a swapoff it maybe the race
+ * count to avoid reading garbage from page_private(page) above.
+ * If the WARN_ON triggers during a swapoff it maybe the race
* condition and it's harmless. However if it triggers without
* swapoff it signals a problem.
*/
@@ -294,7 +292,7 @@ static inline int page_swapcount(struct page *page)
struct swap_info_struct *p;
swp_entry_t entry;
- entry.val = page->private;
+ entry.val = page_private(page);
p = swap_info_get(entry);
if (p) {
/* Subtract the 1 for the swap cache itself */
@@ -339,7 +337,7 @@ int remove_exclusive_swap_page(struct page *page)
if (page_count(page) != 2) /* 2: us + cache */
return 0;
- entry.val = page->private;
+ entry.val = page_private(page);
p = swap_info_get(entry);
if (!p)
return 0;
@@ -398,17 +396,14 @@ void free_swap_and_cache(swp_entry_t entry)
}
/*
- * Always set the resulting pte to be nowrite (the same as COW pages
- * after one process has exited). We don't know just how many PTEs will
- * share this swap entry, so be cautious and let do_wp_page work out
- * what to do if a write is requested later.
- *
- * vma->vm_mm->page_table_lock is held.
+ * No need to decide whether this PTE shares the swap entry with others,
+ * just let do_wp_page work it out if a write is requested later - to
+ * force COW, vm_page_prot omits write permission from any private vma.
*/
static void unuse_pte(struct vm_area_struct *vma, pte_t *pte,
unsigned long addr, swp_entry_t entry, struct page *page)
{
- inc_mm_counter(vma->vm_mm, rss);
+ inc_mm_counter(vma->vm_mm, anon_rss);
get_page(page);
set_pte_at(vma->vm_mm, addr, pte,
pte_mkold(mk_pte(page, vma->vm_page_prot)));
@@ -425,23 +420,25 @@ static int unuse_pte_range(struct vm_area_struct *vma, pmd_t *pmd,
unsigned long addr, unsigned long end,
swp_entry_t entry, struct page *page)
{
- pte_t *pte;
pte_t swp_pte = swp_entry_to_pte(entry);
+ pte_t *pte;
+ spinlock_t *ptl;
+ int found = 0;
- pte = pte_offset_map(pmd, addr);
+ pte = pte_offset_map_lock(vma->vm_mm, pmd, addr, &ptl);
do {
/*
* swapoff spends a _lot_ of time in this loop!
* Test inline before going to call unuse_pte.
*/
if (unlikely(pte_same(*pte, swp_pte))) {
- unuse_pte(vma, pte, addr, entry, page);
- pte_unmap(pte);
- return 1;
+ unuse_pte(vma, pte++, addr, entry, page);
+ found = 1;
+ break;
}
} while (pte++, addr += PAGE_SIZE, addr != end);
- pte_unmap(pte - 1);
- return 0;
+ pte_unmap_unlock(pte - 1, ptl);
+ return found;
}
static inline int unuse_pmd_range(struct vm_area_struct *vma, pud_t *pud,
@@ -523,12 +520,10 @@ static int unuse_mm(struct mm_struct *mm,
down_read(&mm->mmap_sem);
lock_page(page);
}
- spin_lock(&mm->page_table_lock);
for (vma = mm->mmap; vma; vma = vma->vm_next) {
if (vma->anon_vma && unuse_vma(vma, entry, page))
break;
}
- spin_unlock(&mm->page_table_lock);
up_read(&mm->mmap_sem);
/*
* Currently unuse_mm cannot fail, but leave error handling
@@ -1045,7 +1040,7 @@ int page_queue_congested(struct page *page)
BUG_ON(!PageLocked(page)); /* It pins the swap_info_struct */
if (PageSwapCache(page)) {
- swp_entry_t entry = { .val = page->private };
+ swp_entry_t entry = { .val = page_private(page) };
struct swap_info_struct *sis;
sis = get_swap_info_struct(swp_type(entry));
diff --git a/mm/thrash.c b/mm/thrash.c
index 11461f7ad830..eff3c18c33a1 100644
--- a/mm/thrash.c
+++ b/mm/thrash.c
@@ -19,7 +19,7 @@ static unsigned long swap_token_check;
struct mm_struct * swap_token_mm = &init_mm;
#define SWAP_TOKEN_CHECK_INTERVAL (HZ * 2)
-#define SWAP_TOKEN_TIMEOUT 0
+#define SWAP_TOKEN_TIMEOUT (300 * HZ)
/*
* Currently disabled; Needs further code to work at HZ * 300.
*/
diff --git a/mm/tiny-shmem.c b/mm/tiny-shmem.c
index c13a2161bca2..b58abcf44ed6 100644
--- a/mm/tiny-shmem.c
+++ b/mm/tiny-shmem.c
@@ -31,11 +31,14 @@ static struct vfsmount *shm_mnt;
static int __init init_tmpfs(void)
{
- register_filesystem(&tmpfs_fs_type);
+ BUG_ON(register_filesystem(&tmpfs_fs_type) != 0);
+
#ifdef CONFIG_TMPFS
devfs_mk_dir("shm");
#endif
shm_mnt = kern_mount(&tmpfs_fs_type);
+ BUG_ON(IS_ERR(shm_mnt));
+
return 0;
}
module_init(init_tmpfs)
diff --git a/mm/truncate.c b/mm/truncate.c
index 60c8764bfac2..29c18f68dc35 100644
--- a/mm/truncate.c
+++ b/mm/truncate.c
@@ -13,18 +13,9 @@
#include <linux/pagemap.h>
#include <linux/pagevec.h>
#include <linux/buffer_head.h> /* grr. try_to_release_page,
- block_invalidatepage */
+ do_invalidatepage */
-static int do_invalidatepage(struct page *page, unsigned long offset)
-{
- int (*invalidatepage)(struct page *, unsigned long);
- invalidatepage = page->mapping->a_ops->invalidatepage;
- if (invalidatepage == NULL)
- invalidatepage = block_invalidatepage;
- return (*invalidatepage)(page, offset);
-}
-
static inline void truncate_partial_page(struct page *page, unsigned partial)
{
memclear_highpage_flush(page, partial, PAGE_CACHE_SIZE-partial);
diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index 1150229b6366..729eb3eec75f 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -5,6 +5,7 @@
* Support of BIGMEM added by Gerhard Wichert, Siemens AG, July 1999
* SMP-safe vmalloc/vfree/ioremap, Tigran Aivazian <tigran@veritas.com>, May 2000
* Major rework to support vmap/vunmap, Christoph Hellwig, SGI, August 2002
+ * Numa awareness, Christoph Lameter, SGI, June 2005
*/
#include <linux/mm.h>
@@ -88,7 +89,7 @@ static int vmap_pte_range(pmd_t *pmd, unsigned long addr,
{
pte_t *pte;
- pte = pte_alloc_kernel(&init_mm, pmd, addr);
+ pte = pte_alloc_kernel(pmd, addr);
if (!pte)
return -ENOMEM;
do {
@@ -146,20 +147,18 @@ int map_vm_area(struct vm_struct *area, pgprot_t prot, struct page ***pages)
BUG_ON(addr >= end);
pgd = pgd_offset_k(addr);
- spin_lock(&init_mm.page_table_lock);
do {
next = pgd_addr_end(addr, end);
err = vmap_pud_range(pgd, addr, next, prot, pages);
if (err)
break;
} while (pgd++, addr = next, addr != end);
- spin_unlock(&init_mm.page_table_lock);
flush_cache_vmap((unsigned long) area->addr, end);
return err;
}
-struct vm_struct *__get_vm_area(unsigned long size, unsigned long flags,
- unsigned long start, unsigned long end)
+struct vm_struct *__get_vm_area_node(unsigned long size, unsigned long flags,
+ unsigned long start, unsigned long end, int node)
{
struct vm_struct **p, *tmp, *area;
unsigned long align = 1;
@@ -178,7 +177,7 @@ struct vm_struct *__get_vm_area(unsigned long size, unsigned long flags,
addr = ALIGN(start, align);
size = PAGE_ALIGN(size);
- area = kmalloc(sizeof(*area), GFP_KERNEL);
+ area = kmalloc_node(sizeof(*area), GFP_KERNEL, node);
if (unlikely(!area))
return NULL;
@@ -231,6 +230,12 @@ out:
return NULL;
}
+struct vm_struct *__get_vm_area(unsigned long size, unsigned long flags,
+ unsigned long start, unsigned long end)
+{
+ return __get_vm_area_node(size, flags, start, end, -1);
+}
+
/**
* get_vm_area - reserve a contingous kernel virtual area
*
@@ -246,6 +251,11 @@ struct vm_struct *get_vm_area(unsigned long size, unsigned long flags)
return __get_vm_area(size, flags, VMALLOC_START, VMALLOC_END);
}
+struct vm_struct *get_vm_area_node(unsigned long size, unsigned long flags, int node)
+{
+ return __get_vm_area_node(size, flags, VMALLOC_START, VMALLOC_END, node);
+}
+
/* Caller must hold vmlist_lock */
struct vm_struct *__remove_vm_area(void *addr)
{
@@ -342,7 +352,6 @@ void vfree(void *addr)
BUG_ON(in_interrupt());
__vunmap(addr, 1);
}
-
EXPORT_SYMBOL(vfree);
/**
@@ -360,7 +369,6 @@ void vunmap(void *addr)
BUG_ON(in_interrupt());
__vunmap(addr, 0);
}
-
EXPORT_SYMBOL(vunmap);
/**
@@ -392,10 +400,10 @@ void *vmap(struct page **pages, unsigned int count,
return area->addr;
}
-
EXPORT_SYMBOL(vmap);
-void *__vmalloc_area(struct vm_struct *area, gfp_t gfp_mask, pgprot_t prot)
+void *__vmalloc_area_node(struct vm_struct *area, gfp_t gfp_mask,
+ pgprot_t prot, int node)
{
struct page **pages;
unsigned int nr_pages, array_size, i;
@@ -406,9 +414,9 @@ void *__vmalloc_area(struct vm_struct *area, gfp_t gfp_mask, pgprot_t prot)
area->nr_pages = nr_pages;
/* Please note that the recursion is strictly bounded. */
if (array_size > PAGE_SIZE)
- pages = __vmalloc(array_size, gfp_mask, PAGE_KERNEL);
+ pages = __vmalloc_node(array_size, gfp_mask, PAGE_KERNEL, node);
else
- pages = kmalloc(array_size, (gfp_mask & ~__GFP_HIGHMEM));
+ pages = kmalloc_node(array_size, (gfp_mask & ~__GFP_HIGHMEM), node);
area->pages = pages;
if (!area->pages) {
remove_vm_area(area->addr);
@@ -418,7 +426,10 @@ void *__vmalloc_area(struct vm_struct *area, gfp_t gfp_mask, pgprot_t prot)
memset(area->pages, 0, array_size);
for (i = 0; i < area->nr_pages; i++) {
- area->pages[i] = alloc_page(gfp_mask);
+ if (node < 0)
+ area->pages[i] = alloc_page(gfp_mask);
+ else
+ area->pages[i] = alloc_pages_node(node, gfp_mask, 0);
if (unlikely(!area->pages[i])) {
/* Successfully allocated i pages, free them in __vunmap() */
area->nr_pages = i;
@@ -435,18 +446,25 @@ fail:
return NULL;
}
+void *__vmalloc_area(struct vm_struct *area, gfp_t gfp_mask, pgprot_t prot)
+{
+ return __vmalloc_area_node(area, gfp_mask, prot, -1);
+}
+
/**
- * __vmalloc - allocate virtually contiguous memory
+ * __vmalloc_node - allocate virtually contiguous memory
*
* @size: allocation size
* @gfp_mask: flags for the page level allocator
* @prot: protection mask for the allocated pages
+ * @node: node to use for allocation or -1
*
* Allocate enough pages to cover @size from the page level
* allocator with @gfp_mask flags. Map them into contiguous
* kernel virtual space, using a pagetable protection of @prot.
*/
-void *__vmalloc(unsigned long size, gfp_t gfp_mask, pgprot_t prot)
+void *__vmalloc_node(unsigned long size, gfp_t gfp_mask, pgprot_t prot,
+ int node)
{
struct vm_struct *area;
@@ -454,13 +472,18 @@ void *__vmalloc(unsigned long size, gfp_t gfp_mask, pgprot_t prot)
if (!size || (size >> PAGE_SHIFT) > num_physpages)
return NULL;
- area = get_vm_area(size, VM_ALLOC);
+ area = get_vm_area_node(size, VM_ALLOC, node);
if (!area)
return NULL;
- return __vmalloc_area(area, gfp_mask, prot);
+ return __vmalloc_area_node(area, gfp_mask, prot, node);
}
+EXPORT_SYMBOL(__vmalloc_node);
+void *__vmalloc(unsigned long size, gfp_t gfp_mask, pgprot_t prot)
+{
+ return __vmalloc_node(size, gfp_mask, prot, -1);
+}
EXPORT_SYMBOL(__vmalloc);
/**
@@ -478,9 +501,26 @@ void *vmalloc(unsigned long size)
{
return __vmalloc(size, GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL);
}
-
EXPORT_SYMBOL(vmalloc);
+/**
+ * vmalloc_node - allocate memory on a specific node
+ *
+ * @size: allocation size
+ * @node: numa node
+ *
+ * Allocate enough pages to cover @size from the page level
+ * allocator and map them into contiguous kernel virtual space.
+ *
+ * For tight cotrol over page level allocator and protection flags
+ * use __vmalloc() instead.
+ */
+void *vmalloc_node(unsigned long size, int node)
+{
+ return __vmalloc_node(size, GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL, node);
+}
+EXPORT_SYMBOL(vmalloc_node);
+
#ifndef PAGE_KERNEL_EXEC
# define PAGE_KERNEL_EXEC PAGE_KERNEL
#endif
@@ -515,7 +555,6 @@ void *vmalloc_32(unsigned long size)
{
return __vmalloc(size, GFP_KERNEL, PAGE_KERNEL);
}
-
EXPORT_SYMBOL(vmalloc_32);
long vread(char *buf, char *addr, unsigned long count)
diff --git a/mm/vmscan.c b/mm/vmscan.c
index 64f9570cff56..135bf8ca96ee 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -70,7 +70,7 @@ struct scan_control {
unsigned int priority;
/* This context's GFP mask */
- unsigned int gfp_mask;
+ gfp_t gfp_mask;
int may_writepage;
@@ -186,7 +186,7 @@ EXPORT_SYMBOL(remove_shrinker);
*
* Returns the number of slab objects which we shrunk.
*/
-static int shrink_slab(unsigned long scanned, unsigned int gfp_mask,
+static int shrink_slab(unsigned long scanned, gfp_t gfp_mask,
unsigned long lru_pages)
{
struct shrinker *shrinker;
@@ -417,7 +417,9 @@ static int shrink_list(struct list_head *page_list, struct scan_control *sc)
* Anonymous process memory has backing store?
* Try to allocate it some swap space here.
*/
- if (PageAnon(page) && !PageSwapCache(page) && sc->may_swap) {
+ if (PageAnon(page) && !PageSwapCache(page)) {
+ if (!sc->may_swap)
+ goto keep_locked;
if (!add_to_swap(page))
goto activate_locked;
}
@@ -519,7 +521,7 @@ static int shrink_list(struct list_head *page_list, struct scan_control *sc)
#ifdef CONFIG_SWAP
if (PageSwapCache(page)) {
- swp_entry_t swap = { .val = page->private };
+ swp_entry_t swap = { .val = page_private(page) };
__delete_from_swap_cache(page);
write_unlock_irq(&mapping->tree_lock);
swap_free(swap);
@@ -926,7 +928,7 @@ shrink_caches(struct zone **zones, struct scan_control *sc)
* holds filesystem locks which prevent writeout this might not work, and the
* allocation attempt will fail.
*/
-int try_to_free_pages(struct zone **zones, unsigned int gfp_mask)
+int try_to_free_pages(struct zone **zones, gfp_t gfp_mask)
{
int priority;
int ret = 0;
@@ -1338,7 +1340,7 @@ module_init(kswapd_init)
/*
* Try to free up some pages from this zone through reclaim.
*/
-int zone_reclaim(struct zone *zone, unsigned int gfp_mask, unsigned int order)
+int zone_reclaim(struct zone *zone, gfp_t gfp_mask, unsigned int order)
{
struct scan_control sc;
int nr_pages = 1 << order;
diff --git a/net/802/p8023.c b/net/802/p8023.c
index 6368d3dce444..d23e906456eb 100644
--- a/net/802/p8023.c
+++ b/net/802/p8023.c
@@ -54,8 +54,7 @@ struct datalink_proto *make_8023_client(void)
*/
void destroy_8023_client(struct datalink_proto *dl)
{
- if (dl)
- kfree(dl);
+ kfree(dl);
}
EXPORT_SYMBOL(destroy_8023_client);
diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c
index 8e37e71e34ff..1b683f302657 100644
--- a/net/ax25/af_ax25.c
+++ b/net/ax25/af_ax25.c
@@ -1138,10 +1138,8 @@ static int ax25_connect(struct socket *sock, struct sockaddr *uaddr,
sk->sk_state = TCP_CLOSE;
sock->state = SS_UNCONNECTED;
- if (ax25->digipeat != NULL) {
- kfree(ax25->digipeat);
- ax25->digipeat = NULL;
- }
+ kfree(ax25->digipeat);
+ ax25->digipeat = NULL;
/*
* Handle digi-peaters to be used.
diff --git a/net/ax25/ax25_in.c b/net/ax25/ax25_in.c
index 73cfc3411c46..4cf87540fb3a 100644
--- a/net/ax25/ax25_in.c
+++ b/net/ax25/ax25_in.c
@@ -401,10 +401,8 @@ static int ax25_rcv(struct sk_buff *skb, struct net_device *dev,
}
if (dp.ndigi == 0) {
- if (ax25->digipeat != NULL) {
- kfree(ax25->digipeat);
- ax25->digipeat = NULL;
- }
+ kfree(ax25->digipeat);
+ ax25->digipeat = NULL;
} else {
/* Reverse the source SABM's path */
memcpy(ax25->digipeat, &reverse_dp, sizeof(ax25_digi));
diff --git a/net/ax25/ax25_route.c b/net/ax25/ax25_route.c
index 26b77d972220..b1e945bd6ed3 100644
--- a/net/ax25/ax25_route.c
+++ b/net/ax25/ax25_route.c
@@ -54,15 +54,13 @@ void ax25_rt_device_down(struct net_device *dev)
if (s->dev == dev) {
if (ax25_route_list == s) {
ax25_route_list = s->next;
- if (s->digipeat != NULL)
- kfree(s->digipeat);
+ kfree(s->digipeat);
kfree(s);
} else {
for (t = ax25_route_list; t != NULL; t = t->next) {
if (t->next == s) {
t->next = s->next;
- if (s->digipeat != NULL)
- kfree(s->digipeat);
+ kfree(s->digipeat);
kfree(s);
break;
}
@@ -90,10 +88,8 @@ static int ax25_rt_add(struct ax25_routes_struct *route)
while (ax25_rt != NULL) {
if (ax25cmp(&ax25_rt->callsign, &route->dest_addr) == 0 &&
ax25_rt->dev == ax25_dev->dev) {
- if (ax25_rt->digipeat != NULL) {
- kfree(ax25_rt->digipeat);
- ax25_rt->digipeat = NULL;
- }
+ kfree(ax25_rt->digipeat);
+ ax25_rt->digipeat = NULL;
if (route->digi_count != 0) {
if ((ax25_rt->digipeat = kmalloc(sizeof(ax25_digi), GFP_ATOMIC)) == NULL) {
write_unlock(&ax25_route_lock);
@@ -145,8 +141,7 @@ static int ax25_rt_add(struct ax25_routes_struct *route)
static void ax25_rt_destroy(ax25_route *ax25_rt)
{
if (atomic_read(&ax25_rt->ref) == 0) {
- if (ax25_rt->digipeat != NULL)
- kfree(ax25_rt->digipeat);
+ kfree(ax25_rt->digipeat);
kfree(ax25_rt);
return;
}
@@ -530,9 +525,7 @@ void __exit ax25_rt_free(void)
s = ax25_rt;
ax25_rt = ax25_rt->next;
- if (s->digipeat != NULL)
- kfree(s->digipeat);
-
+ kfree(s->digipeat);
kfree(s);
}
write_unlock(&ax25_route_lock);
diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c
index 12b43345b54f..ea616e3fc98e 100644
--- a/net/bluetooth/af_bluetooth.c
+++ b/net/bluetooth/af_bluetooth.c
@@ -36,7 +36,6 @@
#include <linux/skbuff.h>
#include <linux/init.h>
#include <linux/poll.h>
-#include <linux/proc_fs.h>
#include <net/sock.h>
#if defined(CONFIG_KMOD)
@@ -50,10 +49,7 @@
#define BT_DBG(D...)
#endif
-#define VERSION "2.7"
-
-struct proc_dir_entry *proc_bt;
-EXPORT_SYMBOL(proc_bt);
+#define VERSION "2.8"
/* Bluetooth sockets */
#define BT_MAX_PROTO 8
@@ -308,20 +304,10 @@ static struct net_proto_family bt_sock_family_ops = {
.create = bt_sock_create,
};
-extern int hci_sock_init(void);
-extern int hci_sock_cleanup(void);
-
-extern int bt_sysfs_init(void);
-extern int bt_sysfs_cleanup(void);
-
static int __init bt_init(void)
{
BT_INFO("Core ver %s", VERSION);
- proc_bt = proc_mkdir("bluetooth", NULL);
- if (proc_bt)
- proc_bt->owner = THIS_MODULE;
-
sock_register(&bt_sock_family_ops);
BT_INFO("HCI device and connection manager initialized");
@@ -340,8 +326,6 @@ static void __exit bt_exit(void)
bt_sysfs_cleanup();
sock_unregister(PF_BLUETOOTH);
-
- remove_proc_entry("bluetooth", NULL);
}
subsys_initcall(bt_init);
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 55dc42eac92c..9106354c781e 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -87,7 +87,7 @@ int hci_unregister_notifier(struct notifier_block *nb)
return notifier_chain_unregister(&hci_notifier, nb);
}
-void hci_notify(struct hci_dev *hdev, int event)
+static void hci_notify(struct hci_dev *hdev, int event)
{
notifier_call_chain(&hci_notifier, event, hdev);
}
@@ -183,7 +183,7 @@ static void hci_reset_req(struct hci_dev *hdev, unsigned long opt)
static void hci_init_req(struct hci_dev *hdev, unsigned long opt)
{
struct sk_buff *skb;
- __u16 param;
+ __le16 param;
BT_DBG("%s %ld", hdev->name, opt);
@@ -1347,7 +1347,7 @@ static inline void hci_scodata_packet(struct hci_dev *hdev, struct sk_buff *skb)
kfree_skb(skb);
}
-void hci_rx_task(unsigned long arg)
+static void hci_rx_task(unsigned long arg)
{
struct hci_dev *hdev = (struct hci_dev *) arg;
struct sk_buff *skb;
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index b61b4e8e36fd..eb64555d1fb3 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -242,7 +242,7 @@ static void hci_cc_host_ctl(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb
break;
status = *((__u8 *) skb->data);
- setting = __le16_to_cpu(get_unaligned((__u16 *) sent));
+ setting = __le16_to_cpu(get_unaligned((__le16 *) sent));
if (!status && hdev->voice_setting != setting) {
hdev->voice_setting = setting;
@@ -728,7 +728,7 @@ static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff
static inline void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb)
{
struct hci_ev_num_comp_pkts *ev = (struct hci_ev_num_comp_pkts *) skb->data;
- __u16 *ptr;
+ __le16 *ptr;
int i;
skb_pull(skb, sizeof(*ev));
@@ -742,7 +742,7 @@ static inline void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *s
tasklet_disable(&hdev->tx_task);
- for (i = 0, ptr = (__u16 *) skb->data; i < ev->num_hndl; i++) {
+ for (i = 0, ptr = (__le16 *) skb->data; i < ev->num_hndl; i++) {
struct hci_conn *conn;
__u16 handle, count;
diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c
index 32ef7975a139..1d6d0a15c099 100644
--- a/net/bluetooth/hci_sock.c
+++ b/net/bluetooth/hci_sock.c
@@ -66,20 +66,20 @@ static struct hci_sec_filter hci_sec_filter = {
/* Packet types */
0x10,
/* Events */
- { 0x1000d9fe, 0x0000300c },
+ { 0x1000d9fe, 0x0000b00c },
/* Commands */
{
{ 0x0 },
/* OGF_LINK_CTL */
- { 0xbe000006, 0x00000001, 0x0000, 0x00 },
+ { 0xbe000006, 0x00000001, 0x000000, 0x00 },
/* OGF_LINK_POLICY */
- { 0x00005200, 0x00000000, 0x0000, 0x00 },
+ { 0x00005200, 0x00000000, 0x000000, 0x00 },
/* OGF_HOST_CTL */
- { 0xaab00200, 0x2b402aaa, 0x0154, 0x00 },
+ { 0xaab00200, 0x2b402aaa, 0x020154, 0x00 },
/* OGF_INFO_PARAM */
- { 0x000002be, 0x00000000, 0x0000, 0x00 },
+ { 0x000002be, 0x00000000, 0x000000, 0x00 },
/* OGF_STATUS_PARAM */
- { 0x000000ea, 0x00000000, 0x0000, 0x00 }
+ { 0x000000ea, 0x00000000, 0x000000, 0x00 }
}
};
@@ -416,7 +416,7 @@ static int hci_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
skb->dev = (void *) hdev;
if (bt_cb(skb)->pkt_type == HCI_COMMAND_PKT) {
- u16 opcode = __le16_to_cpu(get_unaligned((u16 *)skb->data));
+ u16 opcode = __le16_to_cpu(get_unaligned((__le16 *) skb->data));
u16 ogf = hci_opcode_ogf(opcode);
u16 ocf = hci_opcode_ocf(opcode);
diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c
index 7856bc26accb..bd7568ac87fc 100644
--- a/net/bluetooth/hci_sysfs.c
+++ b/net/bluetooth/hci_sysfs.c
@@ -103,7 +103,7 @@ static void bt_release(struct class_device *cdev)
kfree(hdev);
}
-static struct class bt_class = {
+struct class bt_class = {
.name = "bluetooth",
.release = bt_release,
#ifdef CONFIG_HOTPLUG
@@ -111,6 +111,8 @@ static struct class bt_class = {
#endif
};
+EXPORT_SYMBOL_GPL(bt_class);
+
int hci_register_sysfs(struct hci_dev *hdev)
{
struct class_device *cdev = &hdev->class_dev;
diff --git a/net/bluetooth/hidp/Kconfig b/net/bluetooth/hidp/Kconfig
index 4e958f7d9418..edfea772fb67 100644
--- a/net/bluetooth/hidp/Kconfig
+++ b/net/bluetooth/hidp/Kconfig
@@ -1,6 +1,6 @@
config BT_HIDP
tristate "HIDP protocol support"
- depends on BT && BT_L2CAP
+ depends on BT && BT_L2CAP && (BROKEN || !S390)
select INPUT
help
HIDP (Human Interface Device Protocol) is a transport layer
diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c
index de8af5f42394..cdb9cfafd960 100644
--- a/net/bluetooth/hidp/core.c
+++ b/net/bluetooth/hidp/core.c
@@ -520,7 +520,7 @@ static int hidp_session(void *arg)
if (session->input) {
input_unregister_device(session->input);
- kfree(session->input);
+ session->input = NULL;
}
up_write(&hidp_session_sem);
@@ -536,6 +536,8 @@ static inline void hidp_setup_input(struct hidp_session *session, struct hidp_co
input->private = session;
+ input->name = "Bluetooth HID Boot Protocol Device";
+
input->id.bustype = BUS_BLUETOOTH;
input->id.vendor = req->vendor;
input->id.product = req->product;
@@ -582,16 +584,15 @@ int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock,
return -ENOTUNIQ;
session = kmalloc(sizeof(struct hidp_session), GFP_KERNEL);
- if (!session)
+ if (!session)
return -ENOMEM;
memset(session, 0, sizeof(struct hidp_session));
- session->input = kmalloc(sizeof(struct input_dev), GFP_KERNEL);
+ session->input = input_allocate_device();
if (!session->input) {
kfree(session);
return -ENOMEM;
}
- memset(session->input, 0, sizeof(struct input_dev));
down_write(&hidp_session_sem);
@@ -651,15 +652,15 @@ unlink:
__hidp_unlink_session(session);
- if (session->input)
+ if (session->input) {
input_unregister_device(session->input);
+ session->input = NULL; /* don't try to free it here */
+ }
failed:
up_write(&hidp_session_sem);
- if (session->input)
- kfree(session->input);
-
+ kfree(session->input);
kfree(session);
return err;
}
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index 59b2dd36baa7..e3bb11ca4235 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -38,9 +38,8 @@
#include <linux/interrupt.h>
#include <linux/socket.h>
#include <linux/skbuff.h>
-#include <linux/proc_fs.h>
-#include <linux/seq_file.h>
#include <linux/list.h>
+#include <linux/device.h>
#include <net/sock.h>
#include <asm/system.h>
@@ -56,7 +55,7 @@
#define BT_DBG(D...)
#endif
-#define VERSION "2.7"
+#define VERSION "2.8"
static struct proto_ops l2cap_sock_ops;
@@ -2137,94 +2136,29 @@ drop:
return 0;
}
-/* ---- Proc fs support ---- */
-#ifdef CONFIG_PROC_FS
-static void *l2cap_seq_start(struct seq_file *seq, loff_t *pos)
+static ssize_t l2cap_sysfs_show(struct class *dev, char *buf)
{
struct sock *sk;
struct hlist_node *node;
- loff_t l = *pos;
+ char *str = buf;
read_lock_bh(&l2cap_sk_list.lock);
- sk_for_each(sk, node, &l2cap_sk_list.head)
- if (!l--)
- goto found;
- sk = NULL;
-found:
- return sk;
-}
+ sk_for_each(sk, node, &l2cap_sk_list.head) {
+ struct l2cap_pinfo *pi = l2cap_pi(sk);
-static void *l2cap_seq_next(struct seq_file *seq, void *e, loff_t *pos)
-{
- (*pos)++;
- return sk_next(e);
-}
+ str += sprintf(str, "%s %s %d %d 0x%4.4x 0x%4.4x %d %d 0x%x\n",
+ batostr(&bt_sk(sk)->src), batostr(&bt_sk(sk)->dst),
+ sk->sk_state, pi->psm, pi->scid, pi->dcid, pi->imtu,
+ pi->omtu, pi->link_mode);
+ }
-static void l2cap_seq_stop(struct seq_file *seq, void *e)
-{
read_unlock_bh(&l2cap_sk_list.lock);
-}
-static int l2cap_seq_show(struct seq_file *seq, void *e)
-{
- struct sock *sk = e;
- struct l2cap_pinfo *pi = l2cap_pi(sk);
-
- seq_printf(seq, "%s %s %d %d 0x%4.4x 0x%4.4x %d %d 0x%x\n",
- batostr(&bt_sk(sk)->src), batostr(&bt_sk(sk)->dst),
- sk->sk_state, pi->psm, pi->scid, pi->dcid, pi->imtu,
- pi->omtu, pi->link_mode);
- return 0;
+ return (str - buf);
}
-static struct seq_operations l2cap_seq_ops = {
- .start = l2cap_seq_start,
- .next = l2cap_seq_next,
- .stop = l2cap_seq_stop,
- .show = l2cap_seq_show
-};
-
-static int l2cap_seq_open(struct inode *inode, struct file *file)
-{
- return seq_open(file, &l2cap_seq_ops);
-}
-
-static struct file_operations l2cap_seq_fops = {
- .owner = THIS_MODULE,
- .open = l2cap_seq_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = seq_release,
-};
-
-static int __init l2cap_proc_init(void)
-{
- struct proc_dir_entry *p = create_proc_entry("l2cap", S_IRUGO, proc_bt);
- if (!p)
- return -ENOMEM;
- p->owner = THIS_MODULE;
- p->proc_fops = &l2cap_seq_fops;
- return 0;
-}
-
-static void __exit l2cap_proc_cleanup(void)
-{
- remove_proc_entry("l2cap", proc_bt);
-}
-
-#else /* CONFIG_PROC_FS */
-
-static int __init l2cap_proc_init(void)
-{
- return 0;
-}
-
-static void __exit l2cap_proc_cleanup(void)
-{
- return;
-}
-#endif /* CONFIG_PROC_FS */
+static CLASS_ATTR(l2cap, S_IRUGO, l2cap_sysfs_show, NULL);
static struct proto_ops l2cap_sock_ops = {
.family = PF_BLUETOOTH,
@@ -2266,7 +2200,7 @@ static struct hci_proto l2cap_hci_proto = {
static int __init l2cap_init(void)
{
int err;
-
+
err = proto_register(&l2cap_proto, 0);
if (err < 0)
return err;
@@ -2284,7 +2218,7 @@ static int __init l2cap_init(void)
goto error;
}
- l2cap_proc_init();
+ class_create_file(&bt_class, &class_attr_l2cap);
BT_INFO("L2CAP ver %s", VERSION);
BT_INFO("L2CAP socket layer initialized");
@@ -2298,7 +2232,7 @@ error:
static void __exit l2cap_exit(void)
{
- l2cap_proc_cleanup();
+ class_remove_file(&bt_class, &class_attr_l2cap);
if (bt_sock_unregister(BTPROTO_L2CAP) < 0)
BT_ERR("L2CAP socket unregistration failed");
diff --git a/net/bluetooth/rfcomm/Makefile b/net/bluetooth/rfcomm/Makefile
index aecec45ec68d..fe07988a3705 100644
--- a/net/bluetooth/rfcomm/Makefile
+++ b/net/bluetooth/rfcomm/Makefile
@@ -4,5 +4,5 @@
obj-$(CONFIG_BT_RFCOMM) += rfcomm.o
-rfcomm-y := core.o sock.o crc.o
+rfcomm-y := core.o sock.o
rfcomm-$(CONFIG_BT_RFCOMM_TTY) += tty.o
diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c
index 35adce6482b6..0d89d6434136 100644
--- a/net/bluetooth/rfcomm/core.c
+++ b/net/bluetooth/rfcomm/core.c
@@ -35,9 +35,8 @@
#include <linux/signal.h>
#include <linux/init.h>
#include <linux/wait.h>
+#include <linux/device.h>
#include <linux/net.h>
-#include <linux/proc_fs.h>
-#include <linux/seq_file.h>
#include <net/sock.h>
#include <asm/uaccess.h>
#include <asm/unaligned.h>
@@ -47,17 +46,13 @@
#include <net/bluetooth/l2cap.h>
#include <net/bluetooth/rfcomm.h>
-#define VERSION "1.5"
+#define VERSION "1.6"
#ifndef CONFIG_BT_RFCOMM_DEBUG
#undef BT_DBG
#define BT_DBG(D...)
#endif
-#ifdef CONFIG_PROC_FS
-struct proc_dir_entry *proc_bt_rfcomm;
-#endif
-
static struct task_struct *rfcomm_thread;
static DECLARE_MUTEX(rfcomm_sem);
@@ -133,6 +128,49 @@ static inline void rfcomm_session_put(struct rfcomm_session *s)
/* ---- RFCOMM FCS computation ---- */
+/* reversed, 8-bit, poly=0x07 */
+static unsigned char rfcomm_crc_table[256] = {
+ 0x00, 0x91, 0xe3, 0x72, 0x07, 0x96, 0xe4, 0x75,
+ 0x0e, 0x9f, 0xed, 0x7c, 0x09, 0x98, 0xea, 0x7b,
+ 0x1c, 0x8d, 0xff, 0x6e, 0x1b, 0x8a, 0xf8, 0x69,
+ 0x12, 0x83, 0xf1, 0x60, 0x15, 0x84, 0xf6, 0x67,
+
+ 0x38, 0xa9, 0xdb, 0x4a, 0x3f, 0xae, 0xdc, 0x4d,
+ 0x36, 0xa7, 0xd5, 0x44, 0x31, 0xa0, 0xd2, 0x43,
+ 0x24, 0xb5, 0xc7, 0x56, 0x23, 0xb2, 0xc0, 0x51,
+ 0x2a, 0xbb, 0xc9, 0x58, 0x2d, 0xbc, 0xce, 0x5f,
+
+ 0x70, 0xe1, 0x93, 0x02, 0x77, 0xe6, 0x94, 0x05,
+ 0x7e, 0xef, 0x9d, 0x0c, 0x79, 0xe8, 0x9a, 0x0b,
+ 0x6c, 0xfd, 0x8f, 0x1e, 0x6b, 0xfa, 0x88, 0x19,
+ 0x62, 0xf3, 0x81, 0x10, 0x65, 0xf4, 0x86, 0x17,
+
+ 0x48, 0xd9, 0xab, 0x3a, 0x4f, 0xde, 0xac, 0x3d,
+ 0x46, 0xd7, 0xa5, 0x34, 0x41, 0xd0, 0xa2, 0x33,
+ 0x54, 0xc5, 0xb7, 0x26, 0x53, 0xc2, 0xb0, 0x21,
+ 0x5a, 0xcb, 0xb9, 0x28, 0x5d, 0xcc, 0xbe, 0x2f,
+
+ 0xe0, 0x71, 0x03, 0x92, 0xe7, 0x76, 0x04, 0x95,
+ 0xee, 0x7f, 0x0d, 0x9c, 0xe9, 0x78, 0x0a, 0x9b,
+ 0xfc, 0x6d, 0x1f, 0x8e, 0xfb, 0x6a, 0x18, 0x89,
+ 0xf2, 0x63, 0x11, 0x80, 0xf5, 0x64, 0x16, 0x87,
+
+ 0xd8, 0x49, 0x3b, 0xaa, 0xdf, 0x4e, 0x3c, 0xad,
+ 0xd6, 0x47, 0x35, 0xa4, 0xd1, 0x40, 0x32, 0xa3,
+ 0xc4, 0x55, 0x27, 0xb6, 0xc3, 0x52, 0x20, 0xb1,
+ 0xca, 0x5b, 0x29, 0xb8, 0xcd, 0x5c, 0x2e, 0xbf,
+
+ 0x90, 0x01, 0x73, 0xe2, 0x97, 0x06, 0x74, 0xe5,
+ 0x9e, 0x0f, 0x7d, 0xec, 0x99, 0x08, 0x7a, 0xeb,
+ 0x8c, 0x1d, 0x6f, 0xfe, 0x8b, 0x1a, 0x68, 0xf9,
+ 0x82, 0x13, 0x61, 0xf0, 0x85, 0x14, 0x66, 0xf7,
+
+ 0xa8, 0x39, 0x4b, 0xda, 0xaf, 0x3e, 0x4c, 0xdd,
+ 0xa6, 0x37, 0x45, 0xd4, 0xa1, 0x30, 0x42, 0xd3,
+ 0xb4, 0x25, 0x57, 0xc6, 0xb3, 0x22, 0x50, 0xc1,
+ 0xba, 0x2b, 0x59, 0xc8, 0xbd, 0x2c, 0x5e, 0xcf
+};
+
/* CRC on 2 bytes */
#define __crc(data) (rfcomm_crc_table[rfcomm_crc_table[0xff ^ data[0]] ^ data[1]])
@@ -1958,117 +1996,32 @@ static struct hci_cb rfcomm_cb = {
.encrypt_cfm = rfcomm_encrypt_cfm
};
-/* ---- Proc fs support ---- */
-#ifdef CONFIG_PROC_FS
-static void *rfcomm_seq_start(struct seq_file *seq, loff_t *pos)
+static ssize_t rfcomm_dlc_sysfs_show(struct class *dev, char *buf)
{
struct rfcomm_session *s;
struct list_head *pp, *p;
- loff_t l = *pos;
+ char *str = buf;
rfcomm_lock();
list_for_each(p, &session_list) {
s = list_entry(p, struct rfcomm_session, list);
- list_for_each(pp, &s->dlcs)
- if (!l--) {
- seq->private = s;
- return pp;
- }
- }
- return NULL;
-}
-
-static void *rfcomm_seq_next(struct seq_file *seq, void *e, loff_t *pos)
-{
- struct rfcomm_session *s = seq->private;
- struct list_head *pp, *p = e;
- (*pos)++;
+ list_for_each(pp, &s->dlcs) {
+ struct sock *sk = s->sock->sk;
+ struct rfcomm_dlc *d = list_entry(pp, struct rfcomm_dlc, list);
- if (p->next != &s->dlcs)
- return p->next;
-
- list_for_each(p, &session_list) {
- s = list_entry(p, struct rfcomm_session, list);
- __list_for_each(pp, &s->dlcs) {
- seq->private = s;
- return pp;
+ str += sprintf(str, "%s %s %ld %d %d %d %d\n",
+ batostr(&bt_sk(sk)->src), batostr(&bt_sk(sk)->dst),
+ d->state, d->dlci, d->mtu, d->rx_credits, d->tx_credits);
}
}
- return NULL;
-}
-static void rfcomm_seq_stop(struct seq_file *seq, void *e)
-{
rfcomm_unlock();
-}
-
-static int rfcomm_seq_show(struct seq_file *seq, void *e)
-{
- struct rfcomm_session *s = seq->private;
- struct sock *sk = s->sock->sk;
- struct rfcomm_dlc *d = list_entry(e, struct rfcomm_dlc, list);
-
- seq_printf(seq, "%s %s %ld %d %d %d %d\n",
- batostr(&bt_sk(sk)->src), batostr(&bt_sk(sk)->dst),
- d->state, d->dlci, d->mtu, d->rx_credits, d->tx_credits);
- return 0;
-}
-
-static struct seq_operations rfcomm_seq_ops = {
- .start = rfcomm_seq_start,
- .next = rfcomm_seq_next,
- .stop = rfcomm_seq_stop,
- .show = rfcomm_seq_show
-};
-static int rfcomm_seq_open(struct inode *inode, struct file *file)
-{
- return seq_open(file, &rfcomm_seq_ops);
-}
-
-static struct file_operations rfcomm_seq_fops = {
- .owner = THIS_MODULE,
- .open = rfcomm_seq_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = seq_release,
-};
-
-static int __init rfcomm_proc_init(void)
-{
- struct proc_dir_entry *p;
-
- proc_bt_rfcomm = proc_mkdir("rfcomm", proc_bt);
- if (proc_bt_rfcomm) {
- proc_bt_rfcomm->owner = THIS_MODULE;
-
- p = create_proc_entry("dlc", S_IRUGO, proc_bt_rfcomm);
- if (p)
- p->proc_fops = &rfcomm_seq_fops;
- }
- return 0;
-}
-
-static void __exit rfcomm_proc_cleanup(void)
-{
- remove_proc_entry("dlc", proc_bt_rfcomm);
-
- remove_proc_entry("rfcomm", proc_bt);
+ return (str - buf);
}
-#else /* CONFIG_PROC_FS */
-
-static int __init rfcomm_proc_init(void)
-{
- return 0;
-}
-
-static void __exit rfcomm_proc_cleanup(void)
-{
- return;
-}
-#endif /* CONFIG_PROC_FS */
+static CLASS_ATTR(rfcomm_dlc, S_IRUGO, rfcomm_dlc_sysfs_show, NULL);
/* ---- Initialization ---- */
static int __init rfcomm_init(void)
@@ -2079,9 +2032,7 @@ static int __init rfcomm_init(void)
kernel_thread(rfcomm_run, NULL, CLONE_KERNEL);
- BT_INFO("RFCOMM ver %s", VERSION);
-
- rfcomm_proc_init();
+ class_create_file(&bt_class, &class_attr_rfcomm_dlc);
rfcomm_init_sockets();
@@ -2089,11 +2040,15 @@ static int __init rfcomm_init(void)
rfcomm_init_ttys();
#endif
+ BT_INFO("RFCOMM ver %s", VERSION);
+
return 0;
}
static void __exit rfcomm_exit(void)
{
+ class_remove_file(&bt_class, &class_attr_rfcomm_dlc);
+
hci_unregister_cb(&rfcomm_cb);
/* Terminate working thread.
@@ -2110,8 +2065,6 @@ static void __exit rfcomm_exit(void)
#endif
rfcomm_cleanup_sockets();
-
- rfcomm_proc_cleanup();
}
module_init(rfcomm_init);
diff --git a/net/bluetooth/rfcomm/crc.c b/net/bluetooth/rfcomm/crc.c
deleted file mode 100644
index 1011bc4a8692..000000000000
--- a/net/bluetooth/rfcomm/crc.c
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- RFCOMM implementation for Linux Bluetooth stack (BlueZ).
- Copyright (C) 2002 Maxim Krasnyansky <maxk@qualcomm.com>
- Copyright (C) 2002 Marcel Holtmann <marcel@holtmann.org>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License version 2 as
- published by the Free Software Foundation;
-
- 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 OF THIRD PARTY RIGHTS.
- IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
- CLAIM, OR ANY SPECIAL 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.
-
- ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
- COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
- SOFTWARE IS DISCLAIMED.
-*/
-
-/*
- * RFCOMM FCS calculation.
- *
- * $Id: crc.c,v 1.2 2002/09/21 09:54:32 holtmann Exp $
- */
-
-/* reversed, 8-bit, poly=0x07 */
-unsigned char rfcomm_crc_table[256] = {
- 0x00, 0x91, 0xe3, 0x72, 0x07, 0x96, 0xe4, 0x75,
- 0x0e, 0x9f, 0xed, 0x7c, 0x09, 0x98, 0xea, 0x7b,
- 0x1c, 0x8d, 0xff, 0x6e, 0x1b, 0x8a, 0xf8, 0x69,
- 0x12, 0x83, 0xf1, 0x60, 0x15, 0x84, 0xf6, 0x67,
-
- 0x38, 0xa9, 0xdb, 0x4a, 0x3f, 0xae, 0xdc, 0x4d,
- 0x36, 0xa7, 0xd5, 0x44, 0x31, 0xa0, 0xd2, 0x43,
- 0x24, 0xb5, 0xc7, 0x56, 0x23, 0xb2, 0xc0, 0x51,
- 0x2a, 0xbb, 0xc9, 0x58, 0x2d, 0xbc, 0xce, 0x5f,
-
- 0x70, 0xe1, 0x93, 0x02, 0x77, 0xe6, 0x94, 0x05,
- 0x7e, 0xef, 0x9d, 0x0c, 0x79, 0xe8, 0x9a, 0x0b,
- 0x6c, 0xfd, 0x8f, 0x1e, 0x6b, 0xfa, 0x88, 0x19,
- 0x62, 0xf3, 0x81, 0x10, 0x65, 0xf4, 0x86, 0x17,
-
- 0x48, 0xd9, 0xab, 0x3a, 0x4f, 0xde, 0xac, 0x3d,
- 0x46, 0xd7, 0xa5, 0x34, 0x41, 0xd0, 0xa2, 0x33,
- 0x54, 0xc5, 0xb7, 0x26, 0x53, 0xc2, 0xb0, 0x21,
- 0x5a, 0xcb, 0xb9, 0x28, 0x5d, 0xcc, 0xbe, 0x2f,
-
- 0xe0, 0x71, 0x03, 0x92, 0xe7, 0x76, 0x04, 0x95,
- 0xee, 0x7f, 0x0d, 0x9c, 0xe9, 0x78, 0x0a, 0x9b,
- 0xfc, 0x6d, 0x1f, 0x8e, 0xfb, 0x6a, 0x18, 0x89,
- 0xf2, 0x63, 0x11, 0x80, 0xf5, 0x64, 0x16, 0x87,
-
- 0xd8, 0x49, 0x3b, 0xaa, 0xdf, 0x4e, 0x3c, 0xad,
- 0xd6, 0x47, 0x35, 0xa4, 0xd1, 0x40, 0x32, 0xa3,
- 0xc4, 0x55, 0x27, 0xb6, 0xc3, 0x52, 0x20, 0xb1,
- 0xca, 0x5b, 0x29, 0xb8, 0xcd, 0x5c, 0x2e, 0xbf,
-
- 0x90, 0x01, 0x73, 0xe2, 0x97, 0x06, 0x74, 0xe5,
- 0x9e, 0x0f, 0x7d, 0xec, 0x99, 0x08, 0x7a, 0xeb,
- 0x8c, 0x1d, 0x6f, 0xfe, 0x8b, 0x1a, 0x68, 0xf9,
- 0x82, 0x13, 0x61, 0xf0, 0x85, 0x14, 0x66, 0xf7,
-
- 0xa8, 0x39, 0x4b, 0xda, 0xaf, 0x3e, 0x4c, 0xdd,
- 0xa6, 0x37, 0x45, 0xd4, 0xa1, 0x30, 0x42, 0xd3,
- 0xb4, 0x25, 0x57, 0xc6, 0xb3, 0x22, 0x50, 0xc1,
- 0xba, 0x2b, 0x59, 0xc8, 0xbd, 0x2c, 0x5e, 0xcf
-};
diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c
index a2b30f0aedb7..6c34261b232e 100644
--- a/net/bluetooth/rfcomm/sock.c
+++ b/net/bluetooth/rfcomm/sock.c
@@ -42,8 +42,7 @@
#include <linux/socket.h>
#include <linux/skbuff.h>
#include <linux/list.h>
-#include <linux/proc_fs.h>
-#include <linux/seq_file.h>
+#include <linux/device.h>
#include <net/sock.h>
#include <asm/system.h>
@@ -887,89 +886,26 @@ done:
return result;
}
-/* ---- Proc fs support ---- */
-#ifdef CONFIG_PROC_FS
-static void *rfcomm_seq_start(struct seq_file *seq, loff_t *pos)
+static ssize_t rfcomm_sock_sysfs_show(struct class *dev, char *buf)
{
struct sock *sk;
struct hlist_node *node;
- loff_t l = *pos;
+ char *str = buf;
read_lock_bh(&rfcomm_sk_list.lock);
- sk_for_each(sk, node, &rfcomm_sk_list.head)
- if (!l--)
- return sk;
- return NULL;
-}
-
-static void *rfcomm_seq_next(struct seq_file *seq, void *e, loff_t *pos)
-{
- struct sock *sk = e;
- (*pos)++;
- return sk_next(sk);
-}
+ sk_for_each(sk, node, &rfcomm_sk_list.head) {
+ str += sprintf(str, "%s %s %d %d\n",
+ batostr(&bt_sk(sk)->src), batostr(&bt_sk(sk)->dst),
+ sk->sk_state, rfcomm_pi(sk)->channel);
+ }
-static void rfcomm_seq_stop(struct seq_file *seq, void *e)
-{
read_unlock_bh(&rfcomm_sk_list.lock);
-}
-static int rfcomm_seq_show(struct seq_file *seq, void *e)
-{
- struct sock *sk = e;
- seq_printf(seq, "%s %s %d %d\n",
- batostr(&bt_sk(sk)->src), batostr(&bt_sk(sk)->dst),
- sk->sk_state, rfcomm_pi(sk)->channel);
- return 0;
-}
-
-static struct seq_operations rfcomm_seq_ops = {
- .start = rfcomm_seq_start,
- .next = rfcomm_seq_next,
- .stop = rfcomm_seq_stop,
- .show = rfcomm_seq_show
-};
-
-static int rfcomm_seq_open(struct inode *inode, struct file *file)
-{
- return seq_open(file, &rfcomm_seq_ops);
+ return (str - buf);
}
-static struct file_operations rfcomm_seq_fops = {
- .owner = THIS_MODULE,
- .open = rfcomm_seq_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = seq_release,
-};
-
-static int __init rfcomm_sock_proc_init(void)
-{
- struct proc_dir_entry *p = create_proc_entry("sock", S_IRUGO, proc_bt_rfcomm);
- if (!p)
- return -ENOMEM;
- p->proc_fops = &rfcomm_seq_fops;
- return 0;
-}
-
-static void __exit rfcomm_sock_proc_cleanup(void)
-{
- remove_proc_entry("sock", proc_bt_rfcomm);
-}
-
-#else /* CONFIG_PROC_FS */
-
-static int __init rfcomm_sock_proc_init(void)
-{
- return 0;
-}
-
-static void __exit rfcomm_sock_proc_cleanup(void)
-{
- return;
-}
-#endif /* CONFIG_PROC_FS */
+static CLASS_ATTR(rfcomm, S_IRUGO, rfcomm_sock_sysfs_show, NULL);
static struct proto_ops rfcomm_sock_ops = {
.family = PF_BLUETOOTH,
@@ -997,7 +933,7 @@ static struct net_proto_family rfcomm_sock_family_ops = {
.create = rfcomm_sock_create
};
-int __init rfcomm_init_sockets(void)
+int __init rfcomm_init_sockets(void)
{
int err;
@@ -1009,7 +945,7 @@ int __init rfcomm_init_sockets(void)
if (err < 0)
goto error;
- rfcomm_sock_proc_init();
+ class_create_file(&bt_class, &class_attr_rfcomm);
BT_INFO("RFCOMM socket layer initialized");
@@ -1023,7 +959,7 @@ error:
void __exit rfcomm_cleanup_sockets(void)
{
- rfcomm_sock_proc_cleanup();
+ class_remove_file(&bt_class, &class_attr_rfcomm);
if (bt_sock_unregister(BTPROTO_RFCOMM) < 0)
BT_ERR("RFCOMM socket layer unregistration failed");
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c
index 997e42df115c..9cb00dc6c08c 100644
--- a/net/bluetooth/sco.c
+++ b/net/bluetooth/sco.c
@@ -38,8 +38,7 @@
#include <linux/interrupt.h>
#include <linux/socket.h>
#include <linux/skbuff.h>
-#include <linux/proc_fs.h>
-#include <linux/seq_file.h>
+#include <linux/device.h>
#include <linux/list.h>
#include <net/sock.h>
@@ -55,7 +54,7 @@
#define BT_DBG(D...)
#endif
-#define VERSION "0.4"
+#define VERSION "0.5"
static struct proto_ops sco_sock_ops;
@@ -893,91 +892,26 @@ drop:
return 0;
}
-/* ---- Proc fs support ---- */
-#ifdef CONFIG_PROC_FS
-static void *sco_seq_start(struct seq_file *seq, loff_t *pos)
+static ssize_t sco_sysfs_show(struct class *dev, char *buf)
{
struct sock *sk;
struct hlist_node *node;
- loff_t l = *pos;
+ char *str = buf;
read_lock_bh(&sco_sk_list.lock);
- sk_for_each(sk, node, &sco_sk_list.head)
- if (!l--)
- goto found;
- sk = NULL;
-found:
- return sk;
-}
-
-static void *sco_seq_next(struct seq_file *seq, void *e, loff_t *pos)
-{
- struct sock *sk = e;
- (*pos)++;
- return sk_next(sk);
-}
+ sk_for_each(sk, node, &sco_sk_list.head) {
+ str += sprintf(str, "%s %s %d\n",
+ batostr(&bt_sk(sk)->src), batostr(&bt_sk(sk)->dst),
+ sk->sk_state);
+ }
-static void sco_seq_stop(struct seq_file *seq, void *e)
-{
read_unlock_bh(&sco_sk_list.lock);
-}
-
-static int sco_seq_show(struct seq_file *seq, void *e)
-{
- struct sock *sk = e;
- seq_printf(seq, "%s %s %d\n",
- batostr(&bt_sk(sk)->src), batostr(&bt_sk(sk)->dst), sk->sk_state);
- return 0;
-}
-static struct seq_operations sco_seq_ops = {
- .start = sco_seq_start,
- .next = sco_seq_next,
- .stop = sco_seq_stop,
- .show = sco_seq_show
-};
-
-static int sco_seq_open(struct inode *inode, struct file *file)
-{
- return seq_open(file, &sco_seq_ops);
+ return (str - buf);
}
-static struct file_operations sco_seq_fops = {
- .owner = THIS_MODULE,
- .open = sco_seq_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = seq_release,
-};
-
-static int __init sco_proc_init(void)
-{
- struct proc_dir_entry *p = create_proc_entry("sco", S_IRUGO, proc_bt);
- if (!p)
- return -ENOMEM;
- p->owner = THIS_MODULE;
- p->proc_fops = &sco_seq_fops;
- return 0;
-}
-
-static void __exit sco_proc_cleanup(void)
-{
- remove_proc_entry("sco", proc_bt);
-}
-
-#else /* CONFIG_PROC_FS */
-
-static int __init sco_proc_init(void)
-{
- return 0;
-}
-
-static void __exit sco_proc_cleanup(void)
-{
- return;
-}
-#endif /* CONFIG_PROC_FS */
+static CLASS_ATTR(sco, S_IRUGO, sco_sysfs_show, NULL);
static struct proto_ops sco_sock_ops = {
.family = PF_BLUETOOTH,
@@ -1035,7 +969,7 @@ static int __init sco_init(void)
goto error;
}
- sco_proc_init();
+ class_create_file(&bt_class, &class_attr_sco);
BT_INFO("SCO (Voice Link) ver %s", VERSION);
BT_INFO("SCO socket layer initialized");
@@ -1049,7 +983,7 @@ error:
static void __exit sco_exit(void)
{
- sco_proc_cleanup();
+ class_remove_file(&bt_class, &class_attr_sco);
if (bt_sock_unregister(BTPROTO_SCO) < 0)
BT_ERR("SCO socket unregistration failed");
diff --git a/net/bridge/br_fdb.c b/net/bridge/br_fdb.c
index 24396b914d11..1f08a59b51ea 100644
--- a/net/bridge/br_fdb.c
+++ b/net/bridge/br_fdb.c
@@ -86,8 +86,8 @@ void br_fdb_changeaddr(struct net_bridge_port *p, const unsigned char *newaddr)
struct net_bridge_port *op;
list_for_each_entry(op, &br->port_list, list) {
if (op != p &&
- !memcmp(op->dev->dev_addr,
- f->addr.addr, ETH_ALEN)) {
+ !compare_ether_addr(op->dev->dev_addr,
+ f->addr.addr)) {
f->dst = op;
goto insert;
}
@@ -151,8 +151,8 @@ void br_fdb_delete_by_port(struct net_bridge *br, struct net_bridge_port *p)
struct net_bridge_port *op;
list_for_each_entry(op, &br->port_list, list) {
if (op != p &&
- !memcmp(op->dev->dev_addr,
- f->addr.addr, ETH_ALEN)) {
+ !compare_ether_addr(op->dev->dev_addr,
+ f->addr.addr)) {
f->dst = op;
goto skip_delete;
}
@@ -174,7 +174,7 @@ struct net_bridge_fdb_entry *__br_fdb_get(struct net_bridge *br,
struct net_bridge_fdb_entry *fdb;
hlist_for_each_entry_rcu(fdb, h, &br->hash[br_mac_hash(addr)], hlist) {
- if (!memcmp(fdb->addr.addr, addr, ETH_ALEN)) {
+ if (!compare_ether_addr(fdb->addr.addr, addr)) {
if (unlikely(has_expired(br, fdb)))
break;
return fdb;
@@ -264,7 +264,7 @@ static inline struct net_bridge_fdb_entry *fdb_find(struct hlist_head *head,
struct net_bridge_fdb_entry *fdb;
hlist_for_each_entry_rcu(fdb, h, head, hlist) {
- if (!memcmp(fdb->addr.addr, addr, ETH_ALEN))
+ if (!compare_ether_addr(fdb->addr.addr, addr))
return fdb;
}
return NULL;
diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c
index 9a45e6279c57..b88220a64cd8 100644
--- a/net/bridge/br_input.c
+++ b/net/bridge/br_input.c
@@ -128,7 +128,7 @@ int br_handle_frame(struct net_bridge_port *p, struct sk_buff **pskb)
dest = eth_hdr(skb)->h_dest;
}
- if (!memcmp(p->br->dev->dev_addr, dest, ETH_ALEN))
+ if (!compare_ether_addr(p->br->dev->dev_addr, dest))
skb->pkt_type = PACKET_HOST;
NF_HOOK(PF_BRIDGE, NF_BR_PRE_ROUTING, skb, skb->dev, NULL,
diff --git a/net/bridge/br_stp_if.c b/net/bridge/br_stp_if.c
index 0da11ff05fa3..ac09b6a23523 100644
--- a/net/bridge/br_stp_if.c
+++ b/net/bridge/br_stp_if.c
@@ -15,6 +15,7 @@
#include <linux/kernel.h>
#include <linux/smp_lock.h>
+#include <linux/etherdevice.h>
#include "br_private.h"
#include "br_private_stp.h"
@@ -133,10 +134,10 @@ static void br_stp_change_bridge_id(struct net_bridge *br,
memcpy(br->dev->dev_addr, addr, ETH_ALEN);
list_for_each_entry(p, &br->port_list, list) {
- if (!memcmp(p->designated_bridge.addr, oldaddr, ETH_ALEN))
+ if (!compare_ether_addr(p->designated_bridge.addr, oldaddr))
memcpy(p->designated_bridge.addr, addr, ETH_ALEN);
- if (!memcmp(p->designated_root.addr, oldaddr, ETH_ALEN))
+ if (!compare_ether_addr(p->designated_root.addr, oldaddr))
memcpy(p->designated_root.addr, addr, ETH_ALEN);
}
@@ -157,12 +158,12 @@ void br_stp_recalculate_bridge_id(struct net_bridge *br)
list_for_each_entry(p, &br->port_list, list) {
if (addr == br_mac_zero ||
- memcmp(p->dev->dev_addr, addr, ETH_ALEN) < 0)
+ compare_ether_addr(p->dev->dev_addr, addr) < 0)
addr = p->dev->dev_addr;
}
- if (memcmp(br->bridge_id.addr, addr, ETH_ALEN))
+ if (compare_ether_addr(br->bridge_id.addr, addr))
br_stp_change_bridge_id(br, addr);
}
diff --git a/net/core/datagram.c b/net/core/datagram.c
index 81987df536eb..1bcfef51ac58 100644
--- a/net/core/datagram.c
+++ b/net/core/datagram.c
@@ -213,6 +213,10 @@ int skb_copy_datagram_iovec(const struct sk_buff *skb, int offset,
{
int i, err, fraglen, end = 0;
struct sk_buff *next = skb_shinfo(skb)->frag_list;
+
+ if (!len)
+ return 0;
+
next_skb:
fraglen = skb_headlen(skb);
i = -1;
@@ -346,6 +350,20 @@ fault:
return -EFAULT;
}
+unsigned int __skb_checksum_complete(struct sk_buff *skb)
+{
+ unsigned int sum;
+
+ sum = (u16)csum_fold(skb_checksum(skb, 0, skb->len, skb->csum));
+ if (likely(!sum)) {
+ if (unlikely(skb->ip_summed == CHECKSUM_HW))
+ netdev_rx_csum_fault(skb->dev);
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
+ }
+ return sum;
+}
+EXPORT_SYMBOL(__skb_checksum_complete);
+
/**
* skb_copy_and_csum_datagram_iovec - Copy and checkum skb to user iovec.
* @skb: skbuff
@@ -359,7 +377,7 @@ fault:
* -EFAULT - fault during copy. Beware, in this case iovec
* can be modified!
*/
-int skb_copy_and_csum_datagram_iovec(const struct sk_buff *skb,
+int skb_copy_and_csum_datagram_iovec(struct sk_buff *skb,
int hlen, struct iovec *iov)
{
unsigned int csum;
@@ -372,8 +390,7 @@ int skb_copy_and_csum_datagram_iovec(const struct sk_buff *skb,
iov++;
if (iov->iov_len < chunk) {
- if ((unsigned short)csum_fold(skb_checksum(skb, 0, chunk + hlen,
- skb->csum)))
+ if (__skb_checksum_complete(skb))
goto csum_error;
if (skb_copy_datagram_iovec(skb, hlen, iov, chunk))
goto fault;
@@ -384,6 +401,8 @@ int skb_copy_and_csum_datagram_iovec(const struct sk_buff *skb,
goto fault;
if ((unsigned short)csum_fold(csum))
goto csum_error;
+ if (unlikely(skb->ip_summed == CHECKSUM_HW))
+ netdev_rx_csum_fault(skb->dev);
iov->iov_len -= chunk;
iov->iov_base += chunk;
}
diff --git a/net/core/dev.c b/net/core/dev.c
index a44eeef24edf..0b48e294aafe 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -1108,6 +1108,18 @@ out:
return ret;
}
+/* Take action when hardware reception checksum errors are detected. */
+#ifdef CONFIG_BUG
+void netdev_rx_csum_fault(struct net_device *dev)
+{
+ if (net_ratelimit()) {
+ printk(KERN_ERR "%s: hw csum failure.\n", dev->name);
+ dump_stack();
+ }
+}
+EXPORT_SYMBOL(netdev_rx_csum_fault);
+#endif
+
#ifdef CONFIG_HIGHMEM
/* Actually, we should eliminate this check as soon as we know, that:
* 1. IOMMU is present and allows to map all the memory.
@@ -2717,6 +2729,20 @@ int register_netdevice(struct net_device *dev)
dev->name);
dev->features &= ~NETIF_F_TSO;
}
+ if (dev->features & NETIF_F_UFO) {
+ if (!(dev->features & NETIF_F_HW_CSUM)) {
+ printk(KERN_ERR "%s: Dropping NETIF_F_UFO since no "
+ "NETIF_F_HW_CSUM feature.\n",
+ dev->name);
+ dev->features &= ~NETIF_F_UFO;
+ }
+ if (!(dev->features & NETIF_F_SG)) {
+ printk(KERN_ERR "%s: Dropping NETIF_F_UFO since no "
+ "NETIF_F_SG feature.\n",
+ dev->name);
+ dev->features &= ~NETIF_F_UFO;
+ }
+ }
/*
* nil rebuild_header routine,
diff --git a/net/core/dev_mcast.c b/net/core/dev_mcast.c
index db098ff3cd6a..cb530eef0e39 100644
--- a/net/core/dev_mcast.c
+++ b/net/core/dev_mcast.c
@@ -194,8 +194,7 @@ int dev_mc_add(struct net_device *dev, void *addr, int alen, int glbl)
done:
spin_unlock_bh(&dev->xmit_lock);
- if (dmi1)
- kfree(dmi1);
+ kfree(dmi1);
return err;
}
diff --git a/net/core/ethtool.c b/net/core/ethtool.c
index 404b761e82ce..0350586e9195 100644
--- a/net/core/ethtool.c
+++ b/net/core/ethtool.c
@@ -93,6 +93,20 @@ int ethtool_op_get_perm_addr(struct net_device *dev, struct ethtool_perm_addr *a
}
+u32 ethtool_op_get_ufo(struct net_device *dev)
+{
+ return (dev->features & NETIF_F_UFO) != 0;
+}
+
+int ethtool_op_set_ufo(struct net_device *dev, u32 data)
+{
+ if (data)
+ dev->features |= NETIF_F_UFO;
+ else
+ dev->features &= ~NETIF_F_UFO;
+ return 0;
+}
+
/* Handlers for each ethtool command */
static int ethtool_get_settings(struct net_device *dev, void __user *useraddr)
@@ -483,6 +497,11 @@ static int __ethtool_set_sg(struct net_device *dev, u32 data)
return err;
}
+ if (!data && dev->ethtool_ops->set_ufo) {
+ err = dev->ethtool_ops->set_ufo(dev, 0);
+ if (err)
+ return err;
+ }
return dev->ethtool_ops->set_sg(dev, data);
}
@@ -569,6 +588,32 @@ static int ethtool_set_tso(struct net_device *dev, char __user *useraddr)
return dev->ethtool_ops->set_tso(dev, edata.data);
}
+static int ethtool_get_ufo(struct net_device *dev, char __user *useraddr)
+{
+ struct ethtool_value edata = { ETHTOOL_GTSO };
+
+ if (!dev->ethtool_ops->get_ufo)
+ return -EOPNOTSUPP;
+ edata.data = dev->ethtool_ops->get_ufo(dev);
+ if (copy_to_user(useraddr, &edata, sizeof(edata)))
+ return -EFAULT;
+ return 0;
+}
+static int ethtool_set_ufo(struct net_device *dev, char __user *useraddr)
+{
+ struct ethtool_value edata;
+
+ if (!dev->ethtool_ops->set_ufo)
+ return -EOPNOTSUPP;
+ if (copy_from_user(&edata, useraddr, sizeof(edata)))
+ return -EFAULT;
+ if (edata.data && !(dev->features & NETIF_F_SG))
+ return -EINVAL;
+ if (edata.data && !(dev->features & NETIF_F_HW_CSUM))
+ return -EINVAL;
+ return dev->ethtool_ops->set_ufo(dev, edata.data);
+}
+
static int ethtool_self_test(struct net_device *dev, char __user *useraddr)
{
struct ethtool_test test;
@@ -854,6 +899,12 @@ int dev_ethtool(struct ifreq *ifr)
case ETHTOOL_GPERMADDR:
rc = ethtool_get_perm_addr(dev, useraddr);
break;
+ case ETHTOOL_GUFO:
+ rc = ethtool_get_ufo(dev, useraddr);
+ break;
+ case ETHTOOL_SUFO:
+ rc = ethtool_set_ufo(dev, useraddr);
+ break;
default:
rc = -EOPNOTSUPP;
}
@@ -882,3 +933,5 @@ EXPORT_SYMBOL(ethtool_op_set_sg);
EXPORT_SYMBOL(ethtool_op_set_tso);
EXPORT_SYMBOL(ethtool_op_set_tx_csum);
EXPORT_SYMBOL(ethtool_op_set_tx_hw_csum);
+EXPORT_SYMBOL(ethtool_op_set_ufo);
+EXPORT_SYMBOL(ethtool_op_get_ufo);
diff --git a/net/core/neighbour.c b/net/core/neighbour.c
index 1dcf7fa1f0fe..e68700f950a5 100644
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -1625,12 +1625,9 @@ static int neightbl_fill_info(struct neigh_table *tbl, struct sk_buff *skb,
memset(&ndst, 0, sizeof(ndst));
- for (cpu = 0; cpu < NR_CPUS; cpu++) {
+ for_each_cpu(cpu) {
struct neigh_statistics *st;
- if (!cpu_possible(cpu))
- continue;
-
st = per_cpu_ptr(tbl->stats, cpu);
ndst.ndts_allocs += st->allocs;
ndst.ndts_destroys += st->destroys;
diff --git a/net/core/netpoll.c b/net/core/netpoll.c
index 802fe11efad0..49424a42a2c0 100644
--- a/net/core/netpoll.c
+++ b/net/core/netpoll.c
@@ -101,16 +101,20 @@ void netpoll_queue(struct sk_buff *skb)
static int checksum_udp(struct sk_buff *skb, struct udphdr *uh,
unsigned short ulen, u32 saddr, u32 daddr)
{
- if (uh->check == 0)
+ unsigned int psum;
+
+ if (uh->check == 0 || skb->ip_summed == CHECKSUM_UNNECESSARY)
return 0;
- if (skb->ip_summed == CHECKSUM_HW)
- return csum_tcpudp_magic(
- saddr, daddr, ulen, IPPROTO_UDP, skb->csum);
+ psum = csum_tcpudp_nofold(saddr, daddr, ulen, IPPROTO_UDP, 0);
+
+ if (skb->ip_summed == CHECKSUM_HW &&
+ !(u16)csum_fold(csum_add(psum, skb->csum)))
+ return 0;
- skb->csum = csum_tcpudp_nofold(saddr, daddr, ulen, IPPROTO_UDP, 0);
+ skb->csum = psum;
- return csum_fold(skb_checksum(skb, 0, skb->len, skb->csum));
+ return __skb_checksum_complete(skb);
}
/*
@@ -489,7 +493,7 @@ int __netpoll_rx(struct sk_buff *skb)
if (ulen != len)
goto out;
- if (checksum_udp(skb, uh, ulen, iph->saddr, iph->daddr) < 0)
+ if (checksum_udp(skb, uh, ulen, iph->saddr, iph->daddr))
goto out;
if (np->local_ip && np->local_ip != ntohl(iph->daddr))
goto out;
diff --git a/net/core/pktgen.c b/net/core/pktgen.c
index 5f043d346694..7fc3e9e28c34 100644
--- a/net/core/pktgen.c
+++ b/net/core/pktgen.c
@@ -75,7 +75,7 @@
* By design there should only be *one* "controlling" process. In practice
* multiple write accesses gives unpredictable result. Understood by "write"
* to /proc gives result code thats should be read be the "writer".
- * For pratical use this should be no problem.
+ * For practical use this should be no problem.
*
* Note when adding devices to a specific CPU there good idea to also assign
* /proc/irq/XX/smp_affinity so TX-interrupts gets bound to the same CPU.
@@ -96,7 +96,7 @@
* New xmit() return, do_div and misc clean up by Stephen Hemminger
* <shemminger@osdl.org> 040923
*
- * Rany Dunlap fixed u64 printk compiler waring
+ * Randy Dunlap fixed u64 printk compiler waring
*
* Remove FCS from BW calculation. Lennert Buytenhek <buytenh@wantstofly.org>
* New time handling. Lennert Buytenhek <buytenh@wantstofly.org> 041213
@@ -137,6 +137,7 @@
#include <linux/ipv6.h>
#include <linux/udp.h>
#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
#include <linux/wait.h>
#include <net/checksum.h>
#include <net/ipv6.h>
@@ -151,7 +152,7 @@
#include <asm/timex.h>
-#define VERSION "pktgen v2.62: Packet Generator for packet performance testing.\n"
+#define VERSION "pktgen v2.63: Packet Generator for packet performance testing.\n"
/* #define PG_DEBUG(a) a */
#define PG_DEBUG(a)
@@ -177,8 +178,8 @@
#define T_REMDEV (1<<3) /* Remove all devs */
/* Locks */
-#define thread_lock() spin_lock(&_thread_lock)
-#define thread_unlock() spin_unlock(&_thread_lock)
+#define thread_lock() down(&pktgen_sem)
+#define thread_unlock() up(&pktgen_sem)
/* If lock -- can be removed after some work */
#define if_lock(t) spin_lock(&(t->if_lock));
@@ -186,7 +187,9 @@
/* Used to help with determining the pkts on receive */
#define PKTGEN_MAGIC 0xbe9be955
-#define PG_PROC_DIR "net/pktgen"
+#define PG_PROC_DIR "pktgen"
+#define PGCTRL "pgctrl"
+static struct proc_dir_entry *pg_proc_dir = NULL;
#define MAX_CFLOWS 65536
@@ -202,11 +205,8 @@ struct pktgen_dev {
* Try to keep frequent/infrequent used vars. separated.
*/
- char ifname[32];
- struct proc_dir_entry *proc_ent;
+ char ifname[IFNAMSIZ];
char result[512];
- /* proc file names */
- char fname[80];
struct pktgen_thread* pg_thread; /* the owner */
struct pktgen_dev *next; /* Used for chaining in the thread's run-queue */
@@ -244,7 +244,7 @@ struct pktgen_dev {
__u32 seq_num;
int clone_skb; /* Use multiple SKBs during packet gen. If this number
- * is greater than 1, then that many coppies of the same
+ * is greater than 1, then that many copies of the same
* packet will be sent before a new packet is allocated.
* For instance, if you want to send 1024 identical packets
* before creating a new packet, set clone_skb to 1024.
@@ -330,8 +330,6 @@ struct pktgen_thread {
struct pktgen_dev *if_list; /* All device here */
struct pktgen_thread* next;
char name[32];
- char fname[128]; /* name of proc file */
- struct proc_dir_entry *proc_ent;
char result[512];
u32 max_before_softirq; /* We'll call do_softirq to prevent starvation. */
@@ -396,7 +394,7 @@ static inline s64 divremdi3(s64 x, s64 y, int type)
/* End of hacks to deal with 64-bit math on x86 */
-/** Convert to miliseconds */
+/** Convert to milliseconds */
static inline __u64 tv_to_ms(const struct timeval* tv)
{
__u64 ms = tv->tv_usec / 1000;
@@ -425,7 +423,7 @@ static inline __u64 pg_div64(__u64 n, __u64 base)
{
__u64 tmp = n;
/*
- * How do we know if the architectrure we are running on
+ * How do we know if the architecture we are running on
* supports division with 64 bit base?
*
*/
@@ -473,16 +471,6 @@ static inline __u64 tv_diff(const struct timeval* a, const struct timeval* b)
static char version[] __initdata = VERSION;
-static ssize_t proc_pgctrl_read(struct file* file, char __user * buf, size_t count, loff_t *ppos);
-static ssize_t proc_pgctrl_write(struct file* file, const char __user * buf, size_t count, loff_t *ppos);
-static int proc_if_read(char *buf , char **start, off_t offset, int len, int *eof, void *data);
-
-static int proc_thread_read(char *buf , char **start, off_t offset, int len, int *eof, void *data);
-static int proc_if_write(struct file *file, const char __user *user_buffer, unsigned long count, void *data);
-static int proc_thread_write(struct file *file, const char __user *user_buffer, unsigned long count, void *data);
-static int create_proc_dir(void);
-static int remove_proc_dir(void);
-
static int pktgen_remove_device(struct pktgen_thread* t, struct pktgen_dev *i);
static int pktgen_add_device(struct pktgen_thread* t, const char* ifname);
static struct pktgen_thread* pktgen_find_thread(const char* name);
@@ -503,83 +491,41 @@ static int pg_delay_d = 0;
static int pg_clone_skb_d = 0;
static int debug = 0;
-static DEFINE_SPINLOCK(_thread_lock);
+static DECLARE_MUTEX(pktgen_sem);
static struct pktgen_thread *pktgen_threads = NULL;
-static char module_fname[128];
-static struct proc_dir_entry *module_proc_ent = NULL;
-
static struct notifier_block pktgen_notifier_block = {
.notifier_call = pktgen_device_event,
};
-static struct file_operations pktgen_fops = {
- .read = proc_pgctrl_read,
- .write = proc_pgctrl_write,
- /* .ioctl = pktgen_ioctl, later maybe */
-};
-
/*
* /proc handling functions
*
*/
-static struct proc_dir_entry *pg_proc_dir = NULL;
-static int proc_pgctrl_read_eof=0;
-
-static ssize_t proc_pgctrl_read(struct file* file, char __user * buf,
- size_t count, loff_t *ppos)
+static int pgctrl_show(struct seq_file *seq, void *v)
{
- char data[200];
- int len = 0;
-
- if(proc_pgctrl_read_eof) {
- proc_pgctrl_read_eof=0;
- len = 0;
- goto out;
- }
-
- sprintf(data, "%s", VERSION);
-
- len = strlen(data);
-
- if(len > count) {
- len =-EFAULT;
- goto out;
- }
-
- if (copy_to_user(buf, data, len)) {
- len =-EFAULT;
- goto out;
- }
-
- *ppos += len;
- proc_pgctrl_read_eof=1; /* EOF next call */
-
- out:
- return len;
+ seq_puts(seq, VERSION);
+ return 0;
}
-static ssize_t proc_pgctrl_write(struct file* file,const char __user * buf,
- size_t count, loff_t *ppos)
+static ssize_t pgctrl_write(struct file* file,const char __user * buf,
+ size_t count, loff_t *ppos)
{
- char *data = NULL;
int err = 0;
+ char data[128];
if (!capable(CAP_NET_ADMIN)){
err = -EPERM;
goto out;
}
- data = (void*)vmalloc ((unsigned int)count);
+ if (count > sizeof(data))
+ count = sizeof(data);
- if(!data) {
- err = -ENOMEM;
- goto out;
- }
if (copy_from_user(data, buf, count)) {
- err =-EFAULT;
- goto out_free;
+ err = -EFAULT;
+ goto out;
}
data[count-1] = 0; /* Make string */
@@ -594,31 +540,40 @@ static ssize_t proc_pgctrl_write(struct file* file,const char __user * buf,
err = count;
- out_free:
- vfree (data);
out:
return err;
}
-static int proc_if_read(char *buf , char **start, off_t offset,
- int len, int *eof, void *data)
+static int pgctrl_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, pgctrl_show, PDE(inode)->data);
+}
+
+static struct file_operations pktgen_fops = {
+ .owner = THIS_MODULE,
+ .open = pgctrl_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .write = pgctrl_write,
+ .release = single_release,
+};
+
+static int pktgen_if_show(struct seq_file *seq, void *v)
{
- char *p;
int i;
- struct pktgen_dev *pkt_dev = (struct pktgen_dev*)(data);
+ struct pktgen_dev *pkt_dev = seq->private;
__u64 sa;
__u64 stopped;
__u64 now = getCurUs();
- p = buf;
- p += sprintf(p, "Params: count %llu min_pkt_size: %u max_pkt_size: %u\n",
- (unsigned long long) pkt_dev->count,
- pkt_dev->min_pkt_size, pkt_dev->max_pkt_size);
+ seq_printf(seq, "Params: count %llu min_pkt_size: %u max_pkt_size: %u\n",
+ (unsigned long long) pkt_dev->count,
+ pkt_dev->min_pkt_size, pkt_dev->max_pkt_size);
- p += sprintf(p, " frags: %d delay: %u clone_skb: %d ifname: %s\n",
- pkt_dev->nfrags, 1000*pkt_dev->delay_us+pkt_dev->delay_ns, pkt_dev->clone_skb, pkt_dev->ifname);
+ seq_printf(seq, " frags: %d delay: %u clone_skb: %d ifname: %s\n",
+ pkt_dev->nfrags, 1000*pkt_dev->delay_us+pkt_dev->delay_ns, pkt_dev->clone_skb, pkt_dev->ifname);
- p += sprintf(p, " flows: %u flowlen: %u\n", pkt_dev->cflows, pkt_dev->lflow);
+ seq_printf(seq, " flows: %u flowlen: %u\n", pkt_dev->cflows, pkt_dev->lflow);
if(pkt_dev->flags & F_IPV6) {
@@ -626,19 +581,19 @@ static int proc_if_read(char *buf , char **start, off_t offset,
fmt_ip6(b1, pkt_dev->in6_saddr.s6_addr);
fmt_ip6(b2, pkt_dev->min_in6_saddr.s6_addr);
fmt_ip6(b3, pkt_dev->max_in6_saddr.s6_addr);
- p += sprintf(p, " saddr: %s min_saddr: %s max_saddr: %s\n", b1, b2, b3);
+ seq_printf(seq, " saddr: %s min_saddr: %s max_saddr: %s\n", b1, b2, b3);
fmt_ip6(b1, pkt_dev->in6_daddr.s6_addr);
fmt_ip6(b2, pkt_dev->min_in6_daddr.s6_addr);
fmt_ip6(b3, pkt_dev->max_in6_daddr.s6_addr);
- p += sprintf(p, " daddr: %s min_daddr: %s max_daddr: %s\n", b1, b2, b3);
+ seq_printf(seq, " daddr: %s min_daddr: %s max_daddr: %s\n", b1, b2, b3);
}
else
- p += sprintf(p, " dst_min: %s dst_max: %s\n src_min: %s src_max: %s\n",
- pkt_dev->dst_min, pkt_dev->dst_max, pkt_dev->src_min, pkt_dev->src_max);
+ seq_printf(seq," dst_min: %s dst_max: %s\n src_min: %s src_max: %s\n",
+ pkt_dev->dst_min, pkt_dev->dst_max, pkt_dev->src_min, pkt_dev->src_max);
- p += sprintf(p, " src_mac: ");
+ seq_puts(seq, " src_mac: ");
if ((pkt_dev->src_mac[0] == 0) &&
(pkt_dev->src_mac[1] == 0) &&
@@ -648,89 +603,89 @@ static int proc_if_read(char *buf , char **start, off_t offset,
(pkt_dev->src_mac[5] == 0))
for (i = 0; i < 6; i++)
- p += sprintf(p, "%02X%s", pkt_dev->odev->dev_addr[i], i == 5 ? " " : ":");
+ seq_printf(seq, "%02X%s", pkt_dev->odev->dev_addr[i], i == 5 ? " " : ":");
else
for (i = 0; i < 6; i++)
- p += sprintf(p, "%02X%s", pkt_dev->src_mac[i], i == 5 ? " " : ":");
+ seq_printf(seq, "%02X%s", pkt_dev->src_mac[i], i == 5 ? " " : ":");
- p += sprintf(p, "dst_mac: ");
+ seq_printf(seq, "dst_mac: ");
for (i = 0; i < 6; i++)
- p += sprintf(p, "%02X%s", pkt_dev->dst_mac[i], i == 5 ? "\n" : ":");
+ seq_printf(seq, "%02X%s", pkt_dev->dst_mac[i], i == 5 ? "\n" : ":");
- p += sprintf(p, " udp_src_min: %d udp_src_max: %d udp_dst_min: %d udp_dst_max: %d\n",
- pkt_dev->udp_src_min, pkt_dev->udp_src_max, pkt_dev->udp_dst_min,
- pkt_dev->udp_dst_max);
+ seq_printf(seq, " udp_src_min: %d udp_src_max: %d udp_dst_min: %d udp_dst_max: %d\n",
+ pkt_dev->udp_src_min, pkt_dev->udp_src_max, pkt_dev->udp_dst_min,
+ pkt_dev->udp_dst_max);
- p += sprintf(p, " src_mac_count: %d dst_mac_count: %d \n Flags: ",
- pkt_dev->src_mac_count, pkt_dev->dst_mac_count);
+ seq_printf(seq, " src_mac_count: %d dst_mac_count: %d \n Flags: ",
+ pkt_dev->src_mac_count, pkt_dev->dst_mac_count);
if (pkt_dev->flags & F_IPV6)
- p += sprintf(p, "IPV6 ");
+ seq_printf(seq, "IPV6 ");
if (pkt_dev->flags & F_IPSRC_RND)
- p += sprintf(p, "IPSRC_RND ");
+ seq_printf(seq, "IPSRC_RND ");
if (pkt_dev->flags & F_IPDST_RND)
- p += sprintf(p, "IPDST_RND ");
+ seq_printf(seq, "IPDST_RND ");
if (pkt_dev->flags & F_TXSIZE_RND)
- p += sprintf(p, "TXSIZE_RND ");
+ seq_printf(seq, "TXSIZE_RND ");
if (pkt_dev->flags & F_UDPSRC_RND)
- p += sprintf(p, "UDPSRC_RND ");
+ seq_printf(seq, "UDPSRC_RND ");
if (pkt_dev->flags & F_UDPDST_RND)
- p += sprintf(p, "UDPDST_RND ");
+ seq_printf(seq, "UDPDST_RND ");
if (pkt_dev->flags & F_MACSRC_RND)
- p += sprintf(p, "MACSRC_RND ");
+ seq_printf(seq, "MACSRC_RND ");
if (pkt_dev->flags & F_MACDST_RND)
- p += sprintf(p, "MACDST_RND ");
+ seq_printf(seq, "MACDST_RND ");
- p += sprintf(p, "\n");
+ seq_puts(seq, "\n");
sa = pkt_dev->started_at;
stopped = pkt_dev->stopped_at;
if (pkt_dev->running)
stopped = now; /* not really stopped, more like last-running-at */
- p += sprintf(p, "Current:\n pkts-sofar: %llu errors: %llu\n started: %lluus stopped: %lluus idle: %lluus\n",
- (unsigned long long) pkt_dev->sofar,
- (unsigned long long) pkt_dev->errors,
- (unsigned long long) sa,
- (unsigned long long) stopped,
- (unsigned long long) pkt_dev->idle_acc);
+ seq_printf(seq, "Current:\n pkts-sofar: %llu errors: %llu\n started: %lluus stopped: %lluus idle: %lluus\n",
+ (unsigned long long) pkt_dev->sofar,
+ (unsigned long long) pkt_dev->errors,
+ (unsigned long long) sa,
+ (unsigned long long) stopped,
+ (unsigned long long) pkt_dev->idle_acc);
- p += sprintf(p, " seq_num: %d cur_dst_mac_offset: %d cur_src_mac_offset: %d\n",
- pkt_dev->seq_num, pkt_dev->cur_dst_mac_offset, pkt_dev->cur_src_mac_offset);
+ seq_printf(seq, " seq_num: %d cur_dst_mac_offset: %d cur_src_mac_offset: %d\n",
+ pkt_dev->seq_num, pkt_dev->cur_dst_mac_offset,
+ pkt_dev->cur_src_mac_offset);
if(pkt_dev->flags & F_IPV6) {
char b1[128], b2[128];
fmt_ip6(b1, pkt_dev->cur_in6_daddr.s6_addr);
fmt_ip6(b2, pkt_dev->cur_in6_saddr.s6_addr);
- p += sprintf(p, " cur_saddr: %s cur_daddr: %s\n", b2, b1);
+ seq_printf(seq, " cur_saddr: %s cur_daddr: %s\n", b2, b1);
}
else
- p += sprintf(p, " cur_saddr: 0x%x cur_daddr: 0x%x\n",
- pkt_dev->cur_saddr, pkt_dev->cur_daddr);
+ seq_printf(seq, " cur_saddr: 0x%x cur_daddr: 0x%x\n",
+ pkt_dev->cur_saddr, pkt_dev->cur_daddr);
- p += sprintf(p, " cur_udp_dst: %d cur_udp_src: %d\n",
- pkt_dev->cur_udp_dst, pkt_dev->cur_udp_src);
+ seq_printf(seq, " cur_udp_dst: %d cur_udp_src: %d\n",
+ pkt_dev->cur_udp_dst, pkt_dev->cur_udp_src);
- p += sprintf(p, " flows: %u\n", pkt_dev->nflows);
+ seq_printf(seq, " flows: %u\n", pkt_dev->nflows);
if (pkt_dev->result[0])
- p += sprintf(p, "Result: %s\n", pkt_dev->result);
+ seq_printf(seq, "Result: %s\n", pkt_dev->result);
else
- p += sprintf(p, "Result: Idle\n");
- *eof = 1;
+ seq_printf(seq, "Result: Idle\n");
- return p - buf;
+ return 0;
}
@@ -802,13 +757,14 @@ done_str:
return i;
}
-static int proc_if_write(struct file *file, const char __user *user_buffer,
- unsigned long count, void *data)
+static ssize_t pktgen_if_write(struct file *file, const char __user *user_buffer,
+ size_t count, loff_t *offset)
{
+ struct seq_file *seq = (struct seq_file *) file->private_data;
+ struct pktgen_dev *pkt_dev = seq->private;
int i = 0, max, len;
char name[16], valstr[32];
unsigned long value = 0;
- struct pktgen_dev *pkt_dev = (struct pktgen_dev*)(data);
char* pg_result = NULL;
int tmp = 0;
char buf[128];
@@ -849,7 +805,8 @@ static int proc_if_write(struct file *file, const char __user *user_buffer,
if (copy_from_user(tb, user_buffer, count))
return -EFAULT;
tb[count] = 0;
- printk("pktgen: %s,%lu buffer -:%s:-\n", name, count, tb);
+ printk("pktgen: %s,%lu buffer -:%s:-\n", name,
+ (unsigned long) count, tb);
}
if (!strcmp(name, "min_pkt_size")) {
@@ -1335,92 +1292,98 @@ static int proc_if_write(struct file *file, const char __user *user_buffer,
return -EINVAL;
}
-static int proc_thread_read(char *buf , char **start, off_t offset,
- int len, int *eof, void *data)
+static int pktgen_if_open(struct inode *inode, struct file *file)
{
- char *p;
- struct pktgen_thread *t = (struct pktgen_thread*)(data);
- struct pktgen_dev *pkt_dev = NULL;
+ return single_open(file, pktgen_if_show, PDE(inode)->data);
+}
+static struct file_operations pktgen_if_fops = {
+ .owner = THIS_MODULE,
+ .open = pktgen_if_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .write = pktgen_if_write,
+ .release = single_release,
+};
- if (!t) {
- printk("pktgen: ERROR: could not find thread in proc_thread_read\n");
- return -EINVAL;
- }
+static int pktgen_thread_show(struct seq_file *seq, void *v)
+{
+ struct pktgen_thread *t = seq->private;
+ struct pktgen_dev *pkt_dev = NULL;
+
+ BUG_ON(!t);
- p = buf;
- p += sprintf(p, "Name: %s max_before_softirq: %d\n",
+ seq_printf(seq, "Name: %s max_before_softirq: %d\n",
t->name, t->max_before_softirq);
- p += sprintf(p, "Running: ");
+ seq_printf(seq, "Running: ");
if_lock(t);
for(pkt_dev = t->if_list;pkt_dev; pkt_dev = pkt_dev->next)
if(pkt_dev->running)
- p += sprintf(p, "%s ", pkt_dev->ifname);
+ seq_printf(seq, "%s ", pkt_dev->ifname);
- p += sprintf(p, "\nStopped: ");
+ seq_printf(seq, "\nStopped: ");
for(pkt_dev = t->if_list;pkt_dev; pkt_dev = pkt_dev->next)
if(!pkt_dev->running)
- p += sprintf(p, "%s ", pkt_dev->ifname);
+ seq_printf(seq, "%s ", pkt_dev->ifname);
if (t->result[0])
- p += sprintf(p, "\nResult: %s\n", t->result);
+ seq_printf(seq, "\nResult: %s\n", t->result);
else
- p += sprintf(p, "\nResult: NA\n");
-
- *eof = 1;
+ seq_printf(seq, "\nResult: NA\n");
if_unlock(t);
- return p - buf;
+ return 0;
}
-static int proc_thread_write(struct file *file, const char __user *user_buffer,
- unsigned long count, void *data)
+static ssize_t pktgen_thread_write(struct file *file,
+ const char __user *user_buffer,
+ size_t count, loff_t *offset)
{
+ struct seq_file *seq = (struct seq_file *) file->private_data;
+ struct pktgen_thread *t = seq->private;
int i = 0, max, len, ret;
char name[40];
- struct pktgen_thread *t;
char *pg_result;
unsigned long value = 0;
-
+
if (count < 1) {
// sprintf(pg_result, "Wrong command format");
return -EINVAL;
}
-
+
max = count - i;
len = count_trail_chars(&user_buffer[i], max);
- if (len < 0)
- return len;
-
+ if (len < 0)
+ return len;
+
i += len;
-
+
/* Read variable name */
len = strn_len(&user_buffer[i], sizeof(name) - 1);
- if (len < 0)
- return len;
+ if (len < 0)
+ return len;
memset(name, 0, sizeof(name));
if (copy_from_user(name, &user_buffer[i], len))
return -EFAULT;
i += len;
-
+
max = count -i;
len = count_trail_chars(&user_buffer[i], max);
- if (len < 0)
- return len;
-
+ if (len < 0)
+ return len;
+
i += len;
- if (debug)
- printk("pktgen: t=%s, count=%lu\n", name, count);
-
+ if (debug)
+ printk("pktgen: t=%s, count=%lu\n", name,
+ (unsigned long) count);
- t = (struct pktgen_thread*)(data);
if(!t) {
printk("pktgen: ERROR: No thread\n");
ret = -EINVAL;
@@ -1474,21 +1437,19 @@ static int proc_thread_write(struct file *file, const char __user *user_buffer,
return ret;
}
-static int create_proc_dir(void)
+static int pktgen_thread_open(struct inode *inode, struct file *file)
{
- pg_proc_dir = proc_mkdir(PG_PROC_DIR, NULL);
-
- if (!pg_proc_dir)
- return -ENODEV;
-
- return 0;
+ return single_open(file, pktgen_thread_show, PDE(inode)->data);
}
-static int remove_proc_dir(void)
-{
- remove_proc_entry(PG_PROC_DIR, NULL);
- return 0;
-}
+static struct file_operations pktgen_thread_fops = {
+ .owner = THIS_MODULE,
+ .open = pktgen_thread_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .write = pktgen_thread_write,
+ .release = single_release,
+};
/* Think find or remove for NN */
static struct pktgen_dev *__pktgen_NN_threads(const char* ifname, int remove)
@@ -1702,7 +1663,7 @@ static void spin(struct pktgen_dev *pkt_dev, __u64 spin_until_us)
start = now = getCurUs();
printk(KERN_INFO "sleeping for %d\n", (int)(spin_until_us - now));
while (now < spin_until_us) {
- /* TODO: optimise sleeping behavior */
+ /* TODO: optimize sleeping behavior */
if (spin_until_us - now > jiffies_to_usecs(1)+1)
schedule_timeout_interruptible(1);
else if (spin_until_us - now > 100) {
@@ -2361,7 +2322,7 @@ static void pktgen_stop_all_threads_ifs(void)
pktgen_stop(t);
t = t->next;
}
- thread_unlock();
+ thread_unlock();
}
static int thread_is_running(struct pktgen_thread *t )
@@ -2552,10 +2513,9 @@ static void pktgen_rem_thread(struct pktgen_thread *t)
struct pktgen_thread *tmp = pktgen_threads;
- if (strlen(t->fname))
- remove_proc_entry(t->fname, NULL);
+ remove_proc_entry(t->name, pg_proc_dir);
- thread_lock();
+ thread_lock();
if (tmp == t)
pktgen_threads = tmp->next;
@@ -2825,7 +2785,7 @@ static struct pktgen_dev *pktgen_find_dev(struct pktgen_thread *t, const char* i
if_lock(t);
for(pkt_dev=t->if_list; pkt_dev; pkt_dev = pkt_dev->next ) {
- if (strcmp(pkt_dev->ifname, ifname) == 0) {
+ if (strncmp(pkt_dev->ifname, ifname, IFNAMSIZ) == 0) {
break;
}
}
@@ -2864,74 +2824,70 @@ static int add_dev_to_thread(struct pktgen_thread *t, struct pktgen_dev *pkt_dev
static int pktgen_add_device(struct pktgen_thread *t, const char* ifname)
{
struct pktgen_dev *pkt_dev;
+ struct proc_dir_entry *pe;
/* We don't allow a device to be on several threads */
- if( (pkt_dev = __pktgen_NN_threads(ifname, FIND)) == NULL) {
-
- pkt_dev = kmalloc(sizeof(struct pktgen_dev), GFP_KERNEL);
- if (!pkt_dev)
- return -ENOMEM;
+ pkt_dev = __pktgen_NN_threads(ifname, FIND);
+ if (pkt_dev) {
+ printk("pktgen: ERROR: interface already used.\n");
+ return -EBUSY;
+ }
- memset(pkt_dev, 0, sizeof(struct pktgen_dev));
+ pkt_dev = kzalloc(sizeof(struct pktgen_dev), GFP_KERNEL);
+ if (!pkt_dev)
+ return -ENOMEM;
- pkt_dev->flows = vmalloc(MAX_CFLOWS*sizeof(struct flow_state));
- if (pkt_dev->flows == NULL) {
- kfree(pkt_dev);
- return -ENOMEM;
- }
- memset(pkt_dev->flows, 0, MAX_CFLOWS*sizeof(struct flow_state));
-
- pkt_dev->min_pkt_size = ETH_ZLEN;
- pkt_dev->max_pkt_size = ETH_ZLEN;
- pkt_dev->nfrags = 0;
- pkt_dev->clone_skb = pg_clone_skb_d;
- pkt_dev->delay_us = pg_delay_d / 1000;
- pkt_dev->delay_ns = pg_delay_d % 1000;
- pkt_dev->count = pg_count_d;
- pkt_dev->sofar = 0;
- pkt_dev->udp_src_min = 9; /* sink port */
- pkt_dev->udp_src_max = 9;
- pkt_dev->udp_dst_min = 9;
- pkt_dev->udp_dst_max = 9;
-
- strncpy(pkt_dev->ifname, ifname, 31);
- sprintf(pkt_dev->fname, "%s/%s", PG_PROC_DIR, ifname);
-
- if (! pktgen_setup_dev(pkt_dev)) {
- printk("pktgen: ERROR: pktgen_setup_dev failed.\n");
- if (pkt_dev->flows)
- vfree(pkt_dev->flows);
- kfree(pkt_dev);
- return -ENODEV;
- }
+ pkt_dev->flows = vmalloc(MAX_CFLOWS*sizeof(struct flow_state));
+ if (pkt_dev->flows == NULL) {
+ kfree(pkt_dev);
+ return -ENOMEM;
+ }
+ memset(pkt_dev->flows, 0, MAX_CFLOWS*sizeof(struct flow_state));
- pkt_dev->proc_ent = create_proc_entry(pkt_dev->fname, 0600, NULL);
- if (!pkt_dev->proc_ent) {
- printk("pktgen: cannot create %s procfs entry.\n", pkt_dev->fname);
- if (pkt_dev->flows)
- vfree(pkt_dev->flows);
- kfree(pkt_dev);
- return -EINVAL;
- }
- pkt_dev->proc_ent->read_proc = proc_if_read;
- pkt_dev->proc_ent->write_proc = proc_if_write;
- pkt_dev->proc_ent->data = (void*)(pkt_dev);
- pkt_dev->proc_ent->owner = THIS_MODULE;
+ pkt_dev->min_pkt_size = ETH_ZLEN;
+ pkt_dev->max_pkt_size = ETH_ZLEN;
+ pkt_dev->nfrags = 0;
+ pkt_dev->clone_skb = pg_clone_skb_d;
+ pkt_dev->delay_us = pg_delay_d / 1000;
+ pkt_dev->delay_ns = pg_delay_d % 1000;
+ pkt_dev->count = pg_count_d;
+ pkt_dev->sofar = 0;
+ pkt_dev->udp_src_min = 9; /* sink port */
+ pkt_dev->udp_src_max = 9;
+ pkt_dev->udp_dst_min = 9;
+ pkt_dev->udp_dst_max = 9;
+
+ strncpy(pkt_dev->ifname, ifname, IFNAMSIZ);
+
+ if (! pktgen_setup_dev(pkt_dev)) {
+ printk("pktgen: ERROR: pktgen_setup_dev failed.\n");
+ if (pkt_dev->flows)
+ vfree(pkt_dev->flows);
+ kfree(pkt_dev);
+ return -ENODEV;
+ }
+
+ pe = create_proc_entry(ifname, 0600, pg_proc_dir);
+ if (!pe) {
+ printk("pktgen: cannot create %s/%s procfs entry.\n",
+ PG_PROC_DIR, ifname);
+ if (pkt_dev->flows)
+ vfree(pkt_dev->flows);
+ kfree(pkt_dev);
+ return -EINVAL;
+ }
+ pe->proc_fops = &pktgen_if_fops;
+ pe->data = pkt_dev;
- return add_dev_to_thread(t, pkt_dev);
- }
- else {
- printk("pktgen: ERROR: interface already used.\n");
- return -EBUSY;
- }
+ return add_dev_to_thread(t, pkt_dev);
}
static struct pktgen_thread *pktgen_find_thread(const char* name)
{
struct pktgen_thread *t = NULL;
- thread_lock();
+ thread_lock();
t = pktgen_threads;
while (t) {
@@ -2947,6 +2903,7 @@ static struct pktgen_thread *pktgen_find_thread(const char* name)
static int pktgen_create_thread(const char* name, int cpu)
{
struct pktgen_thread *t = NULL;
+ struct proc_dir_entry *pe;
if (strlen(name) > 31) {
printk("pktgen: ERROR: Thread name cannot be more than 31 characters.\n");
@@ -2958,28 +2915,26 @@ static int pktgen_create_thread(const char* name, int cpu)
return -EINVAL;
}
- t = (struct pktgen_thread*)(kmalloc(sizeof(struct pktgen_thread), GFP_KERNEL));
+ t = kzalloc(sizeof(struct pktgen_thread), GFP_KERNEL);
if (!t) {
printk("pktgen: ERROR: out of memory, can't create new thread.\n");
return -ENOMEM;
}
- memset(t, 0, sizeof(struct pktgen_thread));
strcpy(t->name, name);
spin_lock_init(&t->if_lock);
t->cpu = cpu;
- sprintf(t->fname, "%s/%s", PG_PROC_DIR, t->name);
- t->proc_ent = create_proc_entry(t->fname, 0600, NULL);
- if (!t->proc_ent) {
- printk("pktgen: cannot create %s procfs entry.\n", t->fname);
+ pe = create_proc_entry(t->name, 0600, pg_proc_dir);
+ if (!pe) {
+ printk("pktgen: cannot create %s/%s procfs entry.\n",
+ PG_PROC_DIR, t->name);
kfree(t);
return -EINVAL;
}
- t->proc_ent->read_proc = proc_thread_read;
- t->proc_ent->write_proc = proc_thread_write;
- t->proc_ent->data = (void*)(t);
- t->proc_ent->owner = THIS_MODULE;
+
+ pe->proc_fops = &pktgen_thread_fops;
+ pe->data = t;
t->next = pktgen_threads;
pktgen_threads = t;
@@ -3034,8 +2989,7 @@ static int pktgen_remove_device(struct pktgen_thread *t, struct pktgen_dev *pkt_
/* Clean up proc file system */
- if (strlen(pkt_dev->fname))
- remove_proc_entry(pkt_dev->fname, NULL);
+ remove_proc_entry(pkt_dev->ifname, pg_proc_dir);
if (pkt_dev->flows)
vfree(pkt_dev->flows);
@@ -3046,31 +3000,31 @@ static int pktgen_remove_device(struct pktgen_thread *t, struct pktgen_dev *pkt_
static int __init pg_init(void)
{
int cpu;
- printk(version);
+ struct proc_dir_entry *pe;
- module_fname[0] = 0;
+ printk(version);
- create_proc_dir();
+ pg_proc_dir = proc_mkdir(PG_PROC_DIR, proc_net);
+ if (!pg_proc_dir)
+ return -ENODEV;
+ pg_proc_dir->owner = THIS_MODULE;
- sprintf(module_fname, "%s/pgctrl", PG_PROC_DIR);
- module_proc_ent = create_proc_entry(module_fname, 0600, NULL);
- if (!module_proc_ent) {
- printk("pktgen: ERROR: cannot create %s procfs entry.\n", module_fname);
+ pe = create_proc_entry(PGCTRL, 0600, pg_proc_dir);
+ if (pe == NULL) {
+ printk("pktgen: ERROR: cannot create %s procfs entry.\n", PGCTRL);
+ proc_net_remove(PG_PROC_DIR);
return -EINVAL;
}
- module_proc_ent->proc_fops = &pktgen_fops;
- module_proc_ent->data = NULL;
+ pe->proc_fops = &pktgen_fops;
+ pe->data = NULL;
/* Register us to receive netdevice events */
register_netdevice_notifier(&pktgen_notifier_block);
- for (cpu = 0; cpu < NR_CPUS ; cpu++) {
+ for_each_online_cpu(cpu) {
char buf[30];
- if (!cpu_online(cpu))
- continue;
-
sprintf(buf, "kpktgend_%i", cpu);
pktgen_create_thread(buf, cpu);
}
@@ -3095,10 +3049,8 @@ static void __exit pg_cleanup(void)
unregister_netdevice_notifier(&pktgen_notifier_block);
/* Clean up proc file system */
-
- remove_proc_entry(module_fname, NULL);
-
- remove_proc_dir();
+ remove_proc_entry(PGCTRL, pg_proc_dir);
+ proc_net_remove(PG_PROC_DIR);
}
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 9bed7569ce3f..8700379685e0 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -49,6 +49,7 @@
#include <net/udp.h>
#include <net/sock.h>
#include <net/pkt_sched.h>
+#include <net/netlink.h>
DECLARE_MUTEX(rtnl_sem);
@@ -462,11 +463,6 @@ void rtmsg_ifinfo(int type, struct net_device *dev, unsigned change)
netlink_broadcast(rtnl, skb, 0, RTNLGRP_LINK, GFP_KERNEL);
}
-static int rtnetlink_done(struct netlink_callback *cb)
-{
- return 0;
-}
-
/* Protected by RTNL sempahore. */
static struct rtattr **rta_buf;
static int rtattr_max;
@@ -524,8 +520,6 @@ rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, int *errp)
}
if (kind == 2 && nlh->nlmsg_flags&NLM_F_DUMP) {
- u32 rlen;
-
if (link->dumpit == NULL)
link = &(rtnetlink_links[PF_UNSPEC][type]);
@@ -533,14 +527,11 @@ rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, int *errp)
goto err_inval;
if ((*errp = netlink_dump_start(rtnl, skb, nlh,
- link->dumpit,
- rtnetlink_done)) != 0) {
+ link->dumpit, NULL)) != 0) {
return -1;
}
- rlen = NLMSG_ALIGN(nlh->nlmsg_len);
- if (rlen > skb->len)
- rlen = skb->len;
- skb_pull(skb, rlen);
+
+ netlink_queue_skip(nlh, skb);
return -1;
}
@@ -579,75 +570,13 @@ err_inval:
return -1;
}
-/*
- * Process one packet of messages.
- * Malformed skbs with wrong lengths of messages are discarded silently.
- */
-
-static inline int rtnetlink_rcv_skb(struct sk_buff *skb)
-{
- int err;
- struct nlmsghdr * nlh;
-
- while (skb->len >= NLMSG_SPACE(0)) {
- u32 rlen;
-
- nlh = (struct nlmsghdr *)skb->data;
- if (nlh->nlmsg_len < sizeof(*nlh) || skb->len < nlh->nlmsg_len)
- return 0;
- rlen = NLMSG_ALIGN(nlh->nlmsg_len);
- if (rlen > skb->len)
- rlen = skb->len;
- if (rtnetlink_rcv_msg(skb, nlh, &err)) {
- /* Not error, but we must interrupt processing here:
- * Note, that in this case we do not pull message
- * from skb, it will be processed later.
- */
- if (err == 0)
- return -1;
- netlink_ack(skb, nlh, err);
- } else if (nlh->nlmsg_flags&NLM_F_ACK)
- netlink_ack(skb, nlh, 0);
- skb_pull(skb, rlen);
- }
-
- return 0;
-}
-
-/*
- * rtnetlink input queue processing routine:
- * - process as much as there was in the queue upon entry.
- * - feed skbs to rtnetlink_rcv_skb, until it refuse a message,
- * that will occur, when a dump started.
- */
-
static void rtnetlink_rcv(struct sock *sk, int len)
{
- unsigned int qlen = skb_queue_len(&sk->sk_receive_queue);
+ unsigned int qlen = 0;
do {
- struct sk_buff *skb;
-
rtnl_lock();
-
- if (qlen > skb_queue_len(&sk->sk_receive_queue))
- qlen = skb_queue_len(&sk->sk_receive_queue);
-
- for (; qlen; qlen--) {
- skb = skb_dequeue(&sk->sk_receive_queue);
- if (rtnetlink_rcv_skb(skb)) {
- if (skb->len)
- skb_queue_head(&sk->sk_receive_queue,
- skb);
- else {
- kfree_skb(skb);
- qlen--;
- }
- break;
- }
- kfree_skb(skb);
- }
-
+ netlink_run_queue(sk, &qlen, &rtnetlink_rcv_msg);
up(&rtnl_sem);
netdev_run_todo();
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 02cd4cde2112..b7d13a4fff48 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -122,6 +122,8 @@ void skb_under_panic(struct sk_buff *skb, int sz, void *here)
* __alloc_skb - allocate a network buffer
* @size: size to allocate
* @gfp_mask: allocation mask
+ * @fclone: allocate from fclone cache instead of head cache
+ * and allocate a cloned (child) skb
*
* Allocate a new &sk_buff. The returned buffer has no headroom and a
* tail room of size bytes. The object has a reference count of one.
@@ -174,6 +176,8 @@ struct sk_buff *__alloc_skb(unsigned int size, gfp_t gfp_mask,
skb_shinfo(skb)->tso_size = 0;
skb_shinfo(skb)->tso_segs = 0;
skb_shinfo(skb)->frag_list = NULL;
+ skb_shinfo(skb)->ufo_size = 0;
+ skb_shinfo(skb)->ip6_frag_id = 0;
out:
return skb;
nodata:
@@ -332,6 +336,9 @@ void __kfree_skb(struct sk_buff *skb)
}
#ifdef CONFIG_NETFILTER
nf_conntrack_put(skb->nfct);
+#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
+ nf_conntrack_put_reasm(skb->nfct_reasm);
+#endif
#ifdef CONFIG_BRIDGE_NETFILTER
nf_bridge_put(skb->nf_bridge);
#endif
@@ -410,9 +417,17 @@ struct sk_buff *skb_clone(struct sk_buff *skb, gfp_t gfp_mask)
C(nfct);
nf_conntrack_get(skb->nfct);
C(nfctinfo);
+#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
+ C(nfct_reasm);
+ nf_conntrack_get_reasm(skb->nfct_reasm);
+#endif
#if defined(CONFIG_IP_VS) || defined(CONFIG_IP_VS_MODULE)
C(ipvs_property);
#endif
+#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
+ C(nfct_reasm);
+ nf_conntrack_get_reasm(skb->nfct_reasm);
+#endif
#ifdef CONFIG_BRIDGE_NETFILTER
C(nf_bridge);
nf_bridge_get(skb->nf_bridge);
@@ -470,6 +485,10 @@ static void copy_skb_header(struct sk_buff *new, const struct sk_buff *old)
new->nfct = old->nfct;
nf_conntrack_get(old->nfct);
new->nfctinfo = old->nfctinfo;
+#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
+ new->nfct_reasm = old->nfct_reasm;
+ nf_conntrack_get_reasm(old->nfct_reasm);
+#endif
#if defined(CONFIG_IP_VS) || defined(CONFIG_IP_VS_MODULE)
new->ipvs_property = old->ipvs_property;
#endif
@@ -1694,6 +1713,78 @@ unsigned int skb_find_text(struct sk_buff *skb, unsigned int from,
return textsearch_find(config, state);
}
+/**
+ * skb_append_datato_frags: - append the user data to a skb
+ * @sk: sock structure
+ * @skb: skb structure to be appened with user data.
+ * @getfrag: call back function to be used for getting the user data
+ * @from: pointer to user message iov
+ * @length: length of the iov message
+ *
+ * Description: This procedure append the user data in the fragment part
+ * of the skb if any page alloc fails user this procedure returns -ENOMEM
+ */
+int skb_append_datato_frags(struct sock *sk, struct sk_buff *skb,
+ int getfrag(void *from, char *to, int offset,
+ int len, int odd, struct sk_buff *skb),
+ void *from, int length)
+{
+ int frg_cnt = 0;
+ skb_frag_t *frag = NULL;
+ struct page *page = NULL;
+ int copy, left;
+ int offset = 0;
+ int ret;
+
+ do {
+ /* Return error if we don't have space for new frag */
+ frg_cnt = skb_shinfo(skb)->nr_frags;
+ if (frg_cnt >= MAX_SKB_FRAGS)
+ return -EFAULT;
+
+ /* allocate a new page for next frag */
+ page = alloc_pages(sk->sk_allocation, 0);
+
+ /* If alloc_page fails just return failure and caller will
+ * free previous allocated pages by doing kfree_skb()
+ */
+ if (page == NULL)
+ return -ENOMEM;
+
+ /* initialize the next frag */
+ sk->sk_sndmsg_page = page;
+ sk->sk_sndmsg_off = 0;
+ skb_fill_page_desc(skb, frg_cnt, page, 0, 0);
+ skb->truesize += PAGE_SIZE;
+ atomic_add(PAGE_SIZE, &sk->sk_wmem_alloc);
+
+ /* get the new initialized frag */
+ frg_cnt = skb_shinfo(skb)->nr_frags;
+ frag = &skb_shinfo(skb)->frags[frg_cnt - 1];
+
+ /* copy the user data to page */
+ left = PAGE_SIZE - frag->page_offset;
+ copy = (length > left)? left : length;
+
+ ret = getfrag(from, (page_address(frag->page) +
+ frag->page_offset + frag->size),
+ offset, copy, 0, skb);
+ if (ret < 0)
+ return -EFAULT;
+
+ /* copy was successful so update the size parameters */
+ sk->sk_sndmsg_off += copy;
+ frag->size += copy;
+ skb->len += copy;
+ skb->data_len += copy;
+ offset += copy;
+ length -= copy;
+
+ } while (length > 0);
+
+ return 0;
+}
+
void __init skb_init(void)
{
skbuff_head_cache = kmem_cache_create("skbuff_head_cache",
@@ -1745,3 +1836,4 @@ EXPORT_SYMBOL(skb_prepare_seq_read);
EXPORT_SYMBOL(skb_seq_read);
EXPORT_SYMBOL(skb_abort_seq_read);
EXPORT_SYMBOL(skb_find_text);
+EXPORT_SYMBOL(skb_append_datato_frags);
diff --git a/net/core/sock.c b/net/core/sock.c
index 1c52fe809eda..13cc3be4f056 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -940,7 +940,7 @@ static struct sk_buff *sock_alloc_send_pskb(struct sock *sk,
int noblock, int *errcode)
{
struct sk_buff *skb;
- unsigned int gfp_mask;
+ gfp_t gfp_mask;
long timeo;
int err;
@@ -1242,8 +1242,7 @@ static void sock_def_write_space(struct sock *sk)
static void sock_def_destruct(struct sock *sk)
{
- if (sk->sk_protinfo)
- kfree(sk->sk_protinfo);
+ kfree(sk->sk_protinfo);
}
void sk_send_sigurg(struct sock *sk)
diff --git a/net/core/stream.c b/net/core/stream.c
index ac9edfdf8742..15bfd03e8024 100644
--- a/net/core/stream.c
+++ b/net/core/stream.c
@@ -52,8 +52,9 @@ int sk_stream_wait_connect(struct sock *sk, long *timeo_p)
{
struct task_struct *tsk = current;
DEFINE_WAIT(wait);
+ int done;
- while (1) {
+ do {
if (sk->sk_err)
return sock_error(sk);
if ((1 << sk->sk_state) & ~(TCPF_SYN_SENT | TCPF_SYN_RECV))
@@ -65,13 +66,12 @@ int sk_stream_wait_connect(struct sock *sk, long *timeo_p)
prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE);
sk->sk_write_pending++;
- if (sk_wait_event(sk, timeo_p,
- !((1 << sk->sk_state) &
- ~(TCPF_ESTABLISHED | TCPF_CLOSE_WAIT))))
- break;
+ done = sk_wait_event(sk, timeo_p,
+ !((1 << sk->sk_state) &
+ ~(TCPF_ESTABLISHED | TCPF_CLOSE_WAIT)));
finish_wait(sk->sk_sleep, &wait);
sk->sk_write_pending--;
- }
+ } while (!done);
return 0;
}
diff --git a/net/dccp/dccp.h b/net/dccp/dccp.h
index 5871c027f9dc..f97b85d55ad8 100644
--- a/net/dccp/dccp.h
+++ b/net/dccp/dccp.h
@@ -118,7 +118,6 @@ DECLARE_SNMP_STAT(struct dccp_mib, dccp_statistics);
#define DCCP_ADD_STATS_USER(field, val) \
SNMP_ADD_STATS_USER(dccp_statistics, field, val)
-extern int dccp_transmit_skb(struct sock *sk, struct sk_buff *skb);
extern int dccp_retransmit_skb(struct sock *sk, struct sk_buff *skb);
extern int dccp_send_response(struct sock *sk);
diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c
index 6298cf58ff9e..ca03521112c5 100644
--- a/net/dccp/ipv4.c
+++ b/net/dccp/ipv4.c
@@ -31,8 +31,6 @@ struct inet_hashinfo __cacheline_aligned dccp_hashinfo = {
.lhash_lock = RW_LOCK_UNLOCKED,
.lhash_users = ATOMIC_INIT(0),
.lhash_wait = __WAIT_QUEUE_HEAD_INITIALIZER(dccp_hashinfo.lhash_wait),
- .portalloc_lock = SPIN_LOCK_UNLOCKED,
- .port_rover = 1024 - 1,
};
EXPORT_SYMBOL_GPL(dccp_hashinfo);
@@ -125,36 +123,15 @@ static int dccp_v4_hash_connect(struct sock *sk)
int ret;
if (snum == 0) {
- int rover;
int low = sysctl_local_port_range[0];
int high = sysctl_local_port_range[1];
int remaining = (high - low) + 1;
+ int rover = net_random() % (high - low) + low;
struct hlist_node *node;
struct inet_timewait_sock *tw = NULL;
local_bh_disable();
-
- /* TODO. Actually it is not so bad idea to remove
- * dccp_hashinfo.portalloc_lock before next submission to
- * Linus.
- * As soon as we touch this place at all it is time to think.
- *
- * Now it protects single _advisory_ variable
- * dccp_hashinfo.port_rover, hence it is mostly useless.
- * Code will work nicely if we just delete it, but
- * I am afraid in contented case it will work not better or
- * even worse: another cpu just will hit the same bucket
- * and spin there.
- * So some cpu salt could remove both contention and
- * memory pingpong. Any ideas how to do this in a nice way?
- */
- spin_lock(&dccp_hashinfo.portalloc_lock);
- rover = dccp_hashinfo.port_rover;
-
do {
- rover++;
- if ((rover < low) || (rover > high))
- rover = low;
head = &dccp_hashinfo.bhash[inet_bhashfn(rover,
dccp_hashinfo.bhash_size)];
spin_lock(&head->lock);
@@ -187,9 +164,9 @@ static int dccp_v4_hash_connect(struct sock *sk)
next_port:
spin_unlock(&head->lock);
+ if (++rover > high)
+ rover = low;
} while (--remaining > 0);
- dccp_hashinfo.port_rover = rover;
- spin_unlock(&dccp_hashinfo.portalloc_lock);
local_bh_enable();
@@ -197,9 +174,6 @@ static int dccp_v4_hash_connect(struct sock *sk)
ok:
/* All locks still held and bhs disabled */
- dccp_hashinfo.port_rover = rover;
- spin_unlock(&dccp_hashinfo.portalloc_lock);
-
inet_bind_hash(sk, tb, rover);
if (sk_unhashed(sk)) {
inet_sk(sk)->sport = htons(rover);
@@ -1289,10 +1263,8 @@ static int dccp_v4_destroy_sock(struct sock *sk)
if (inet_csk(sk)->icsk_bind_hash != NULL)
inet_put_port(&dccp_hashinfo, sk);
- if (dp->dccps_service_list != NULL) {
- kfree(dp->dccps_service_list);
- dp->dccps_service_list = NULL;
- }
+ kfree(dp->dccps_service_list);
+ dp->dccps_service_list = NULL;
ccid_hc_rx_exit(dp->dccps_hc_rx_ccid, sk);
ccid_hc_tx_exit(dp->dccps_hc_tx_ccid, sk);
diff --git a/net/dccp/output.c b/net/dccp/output.c
index 29250749f16f..74ff87025878 100644
--- a/net/dccp/output.c
+++ b/net/dccp/output.c
@@ -12,6 +12,7 @@
#include <linux/config.h>
#include <linux/dccp.h>
+#include <linux/kernel.h>
#include <linux/skbuff.h>
#include <net/sock.h>
@@ -25,13 +26,20 @@ static inline void dccp_event_ack_sent(struct sock *sk)
inet_csk_clear_xmit_timer(sk, ICSK_TIME_DACK);
}
+static inline void dccp_skb_entail(struct sock *sk, struct sk_buff *skb)
+{
+ skb_set_owner_w(skb, sk);
+ WARN_ON(sk->sk_send_head);
+ sk->sk_send_head = skb;
+}
+
/*
* All SKB's seen here are completely headerless. It is our
* job to build the DCCP header, and pass the packet down to
* IP so it can do the same plus pass the packet off to the
* device.
*/
-int dccp_transmit_skb(struct sock *sk, struct sk_buff *skb)
+static int dccp_transmit_skb(struct sock *sk, struct sk_buff *skb)
{
if (likely(skb != NULL)) {
const struct inet_sock *inet = inet_sk(sk);
@@ -50,10 +58,21 @@ int dccp_transmit_skb(struct sock *sk, struct sk_buff *skb)
switch (dcb->dccpd_type) {
case DCCP_PKT_DATA:
set_ack = 0;
+ /* fall through */
+ case DCCP_PKT_DATAACK:
break;
+
case DCCP_PKT_SYNC:
case DCCP_PKT_SYNCACK:
ackno = dcb->dccpd_seq;
+ /* fall through */
+ default:
+ /*
+ * Only data packets should come through with skb->sk
+ * set.
+ */
+ WARN_ON(skb->sk);
+ skb_set_owner_w(skb, sk);
break;
}
@@ -63,9 +82,6 @@ int dccp_transmit_skb(struct sock *sk, struct sk_buff *skb)
skb->h.raw = skb_push(skb, dccp_header_size);
dh = dccp_hdr(skb);
- if (!skb->sk)
- skb_set_owner_w(skb, sk);
-
/* Build DCCP header and checksum it. */
memset(dh, 0, dccp_header_size);
dh->dccph_type = dcb->dccpd_type;
@@ -393,10 +409,8 @@ int dccp_connect(struct sock *sk)
DCCP_SKB_CB(skb)->dccpd_type = DCCP_PKT_REQUEST;
skb->csum = 0;
- skb_set_owner_w(skb, sk);
- BUG_TRAP(sk->sk_send_head == NULL);
- sk->sk_send_head = skb;
+ dccp_skb_entail(sk, skb);
dccp_transmit_skb(sk, skb_clone(skb, GFP_KERNEL));
DCCP_INC_STATS(DCCP_MIB_ACTIVEOPENS);
@@ -425,7 +439,6 @@ void dccp_send_ack(struct sock *sk)
skb_reserve(skb, MAX_DCCP_HEADER);
skb->csum = 0;
DCCP_SKB_CB(skb)->dccpd_type = DCCP_PKT_ACK;
- skb_set_owner_w(skb, sk);
dccp_transmit_skb(sk, skb);
}
}
@@ -482,7 +495,6 @@ void dccp_send_sync(struct sock *sk, const u64 seq,
DCCP_SKB_CB(skb)->dccpd_type = pkt_type;
DCCP_SKB_CB(skb)->dccpd_seq = seq;
- skb_set_owner_w(skb, sk);
dccp_transmit_skb(sk, skb);
}
@@ -495,7 +507,7 @@ void dccp_send_close(struct sock *sk, const int active)
{
struct dccp_sock *dp = dccp_sk(sk);
struct sk_buff *skb;
- const unsigned int prio = active ? GFP_KERNEL : GFP_ATOMIC;
+ const gfp_t prio = active ? GFP_KERNEL : GFP_ATOMIC;
skb = alloc_skb(sk->sk_prot->max_header, prio);
if (skb == NULL)
@@ -507,10 +519,8 @@ void dccp_send_close(struct sock *sk, const int active)
DCCP_SKB_CB(skb)->dccpd_type = dp->dccps_role == DCCP_ROLE_CLIENT ?
DCCP_PKT_CLOSE : DCCP_PKT_CLOSEREQ;
- skb_set_owner_w(skb, sk);
if (active) {
- BUG_TRAP(sk->sk_send_head == NULL);
- sk->sk_send_head = skb;
+ dccp_skb_entail(sk, skb);
dccp_transmit_skb(sk, skb_clone(skb, prio));
} else
dccp_transmit_skb(sk, skb);
diff --git a/net/dccp/proto.c b/net/dccp/proto.c
index a021c3422f67..e0ace7cbb996 100644
--- a/net/dccp/proto.c
+++ b/net/dccp/proto.c
@@ -238,8 +238,7 @@ static int dccp_setsockopt_service(struct sock *sk, const u32 service,
lock_sock(sk);
dp->dccps_service = service;
- if (dp->dccps_service_list != NULL)
- kfree(dp->dccps_service_list);
+ kfree(dp->dccps_service_list);
dp->dccps_service_list = sl;
release_sock(sk);
diff --git a/net/decnet/af_decnet.c b/net/decnet/af_decnet.c
index 1186dc44cdff..3f25cadccddd 100644
--- a/net/decnet/af_decnet.c
+++ b/net/decnet/af_decnet.c
@@ -719,22 +719,9 @@ static int dn_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
if (saddr->sdn_flags & ~SDF_WILD)
return -EINVAL;
-#if 1
if (!capable(CAP_NET_BIND_SERVICE) && (saddr->sdn_objnum ||
(saddr->sdn_flags & SDF_WILD)))
return -EACCES;
-#else
- /*
- * Maybe put the default actions in the default security ops for
- * dn_prot_sock ? Would be nice if the capable call would go there
- * too.
- */
- if (security_dn_prot_sock(saddr) &&
- !capable(CAP_NET_BIND_SERVICE) ||
- saddr->sdn_objnum || (saddr->sdn_flags & SDF_WILD))
- return -EACCES;
-#endif
-
if (!(saddr->sdn_flags & SDF_WILD)) {
if (dn_ntohs(saddr->sdn_nodeaddrl)) {
diff --git a/net/decnet/dn_table.c b/net/decnet/dn_table.c
index eeba56f99323..6f8b5658cb4e 100644
--- a/net/decnet/dn_table.c
+++ b/net/decnet/dn_table.c
@@ -784,16 +784,14 @@ struct dn_fib_table *dn_fib_get_table(int n, int create)
static void dn_fib_del_tree(int n)
{
- struct dn_fib_table *t;
+ struct dn_fib_table *t;
- write_lock(&dn_fib_tables_lock);
- t = dn_fib_tables[n];
- dn_fib_tables[n] = NULL;
- write_unlock(&dn_fib_tables_lock);
+ write_lock(&dn_fib_tables_lock);
+ t = dn_fib_tables[n];
+ dn_fib_tables[n] = NULL;
+ write_unlock(&dn_fib_tables_lock);
- if (t) {
- kfree(t);
- }
+ kfree(t);
}
struct dn_fib_table *dn_fib_empty_table(void)
diff --git a/net/ethernet/eth.c b/net/ethernet/eth.c
index 68a5ca866442..e24577367274 100644
--- a/net/ethernet/eth.c
+++ b/net/ethernet/eth.c
@@ -146,19 +146,6 @@ int eth_rebuild_header(struct sk_buff *skb)
return 0;
}
-static inline unsigned int compare_eth_addr(const unsigned char *__a, const unsigned char *__b)
-{
- const unsigned short *dest = (unsigned short *) __a;
- const unsigned short *devaddr = (unsigned short *) __b;
- unsigned int res;
-
- BUILD_BUG_ON(ETH_ALEN != 6);
- res = ((dest[0] ^ devaddr[0]) |
- (dest[1] ^ devaddr[1]) |
- (dest[2] ^ devaddr[2])) != 0;
-
- return res;
-}
/*
* Determine the packet's protocol ID. The rule here is that we
@@ -176,7 +163,7 @@ __be16 eth_type_trans(struct sk_buff *skb, struct net_device *dev)
eth = eth_hdr(skb);
if (*eth->h_dest&1) {
- if (!compare_eth_addr(eth->h_dest, dev->broadcast))
+ if (!compare_ether_addr(eth->h_dest, dev->broadcast))
skb->pkt_type = PACKET_BROADCAST;
else
skb->pkt_type = PACKET_MULTICAST;
@@ -191,7 +178,7 @@ __be16 eth_type_trans(struct sk_buff *skb, struct net_device *dev)
*/
else if(1 /*dev->flags&IFF_PROMISC*/) {
- if (unlikely(compare_eth_addr(eth->h_dest, dev->dev_addr)))
+ if (unlikely(compare_ether_addr(eth->h_dest, dev->dev_addr)))
skb->pkt_type = PACKET_OTHERHOST;
}
diff --git a/net/ethernet/pe2.c b/net/ethernet/pe2.c
index 98a494be6039..9d57b4fb6440 100644
--- a/net/ethernet/pe2.c
+++ b/net/ethernet/pe2.c
@@ -32,8 +32,7 @@ struct datalink_proto *make_EII_client(void)
void destroy_EII_client(struct datalink_proto *dl)
{
- if (dl)
- kfree(dl);
+ kfree(dl);
}
EXPORT_SYMBOL(destroy_EII_client);
diff --git a/net/ieee80211/Makefile b/net/ieee80211/Makefile
index a6ccac5baea8..f988417121da 100644
--- a/net/ieee80211/Makefile
+++ b/net/ieee80211/Makefile
@@ -7,5 +7,6 @@ ieee80211-objs := \
ieee80211_module.o \
ieee80211_tx.o \
ieee80211_rx.o \
- ieee80211_wx.o
+ ieee80211_wx.o \
+ ieee80211_geo.o
diff --git a/net/ieee80211/ieee80211_crypt.c b/net/ieee80211/ieee80211_crypt.c
index 61a9d92e455b..ecc9bb196abc 100644
--- a/net/ieee80211/ieee80211_crypt.c
+++ b/net/ieee80211/ieee80211_crypt.c
@@ -11,16 +11,14 @@
*
*/
-#include <linux/config.h>
-#include <linux/version.h>
+#include <linux/errno.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
-#include <asm/string.h>
-#include <asm/errno.h>
-
+#include <linux/string.h>
#include <net/ieee80211.h>
+
MODULE_AUTHOR("Jouni Malinen");
MODULE_DESCRIPTION("HostAP crypto");
MODULE_LICENSE("GPL");
@@ -30,26 +28,20 @@ struct ieee80211_crypto_alg {
struct ieee80211_crypto_ops *ops;
};
-struct ieee80211_crypto {
- struct list_head algs;
- spinlock_t lock;
-};
-
-static struct ieee80211_crypto *hcrypt;
+static LIST_HEAD(ieee80211_crypto_algs);
+static DEFINE_SPINLOCK(ieee80211_crypto_lock);
void ieee80211_crypt_deinit_entries(struct ieee80211_device *ieee, int force)
{
- struct list_head *ptr, *n;
- struct ieee80211_crypt_data *entry;
-
- for (ptr = ieee->crypt_deinit_list.next, n = ptr->next;
- ptr != &ieee->crypt_deinit_list; ptr = n, n = ptr->next) {
- entry = list_entry(ptr, struct ieee80211_crypt_data, list);
+ struct ieee80211_crypt_data *entry, *next;
+ unsigned long flags;
+ spin_lock_irqsave(&ieee->lock, flags);
+ list_for_each_entry_safe(entry, next, &ieee->crypt_deinit_list, list) {
if (atomic_read(&entry->refcnt) != 0 && !force)
continue;
- list_del(ptr);
+ list_del(&entry->list);
if (entry->ops) {
entry->ops->deinit(entry->priv);
@@ -57,6 +49,17 @@ void ieee80211_crypt_deinit_entries(struct ieee80211_device *ieee, int force)
}
kfree(entry);
}
+ spin_unlock_irqrestore(&ieee->lock, flags);
+}
+
+/* After this, crypt_deinit_list won't accept new members */
+void ieee80211_crypt_quiescing(struct ieee80211_device *ieee)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&ieee->lock, flags);
+ ieee->crypt_quiesced = 1;
+ spin_unlock_irqrestore(&ieee->lock, flags);
}
void ieee80211_crypt_deinit_handler(unsigned long data)
@@ -64,16 +67,16 @@ void ieee80211_crypt_deinit_handler(unsigned long data)
struct ieee80211_device *ieee = (struct ieee80211_device *)data;
unsigned long flags;
- spin_lock_irqsave(&ieee->lock, flags);
ieee80211_crypt_deinit_entries(ieee, 0);
- if (!list_empty(&ieee->crypt_deinit_list)) {
+
+ spin_lock_irqsave(&ieee->lock, flags);
+ if (!list_empty(&ieee->crypt_deinit_list) && !ieee->crypt_quiesced) {
printk(KERN_DEBUG "%s: entries remaining in delayed crypt "
"deletion list\n", ieee->dev->name);
ieee->crypt_deinit_timer.expires = jiffies + HZ;
add_timer(&ieee->crypt_deinit_timer);
}
spin_unlock_irqrestore(&ieee->lock, flags);
-
}
void ieee80211_crypt_delayed_deinit(struct ieee80211_device *ieee,
@@ -93,10 +96,12 @@ void ieee80211_crypt_delayed_deinit(struct ieee80211_device *ieee,
* locking. */
spin_lock_irqsave(&ieee->lock, flags);
- list_add(&tmp->list, &ieee->crypt_deinit_list);
- if (!timer_pending(&ieee->crypt_deinit_timer)) {
- ieee->crypt_deinit_timer.expires = jiffies + HZ;
- add_timer(&ieee->crypt_deinit_timer);
+ if (!ieee->crypt_quiesced) {
+ list_add(&tmp->list, &ieee->crypt_deinit_list);
+ if (!timer_pending(&ieee->crypt_deinit_timer)) {
+ ieee->crypt_deinit_timer.expires = jiffies + HZ;
+ add_timer(&ieee->crypt_deinit_timer);
+ }
}
spin_unlock_irqrestore(&ieee->lock, flags);
}
@@ -106,9 +111,6 @@ int ieee80211_register_crypto_ops(struct ieee80211_crypto_ops *ops)
unsigned long flags;
struct ieee80211_crypto_alg *alg;
- if (hcrypt == NULL)
- return -1;
-
alg = kmalloc(sizeof(*alg), GFP_KERNEL);
if (alg == NULL)
return -ENOMEM;
@@ -116,9 +118,9 @@ int ieee80211_register_crypto_ops(struct ieee80211_crypto_ops *ops)
memset(alg, 0, sizeof(*alg));
alg->ops = ops;
- spin_lock_irqsave(&hcrypt->lock, flags);
- list_add(&alg->list, &hcrypt->algs);
- spin_unlock_irqrestore(&hcrypt->lock, flags);
+ spin_lock_irqsave(&ieee80211_crypto_lock, flags);
+ list_add(&alg->list, &ieee80211_crypto_algs);
+ spin_unlock_irqrestore(&ieee80211_crypto_lock, flags);
printk(KERN_DEBUG "ieee80211_crypt: registered algorithm '%s'\n",
ops->name);
@@ -128,127 +130,75 @@ int ieee80211_register_crypto_ops(struct ieee80211_crypto_ops *ops)
int ieee80211_unregister_crypto_ops(struct ieee80211_crypto_ops *ops)
{
+ struct ieee80211_crypto_alg *alg;
unsigned long flags;
- struct list_head *ptr;
- struct ieee80211_crypto_alg *del_alg = NULL;
-
- if (hcrypt == NULL)
- return -1;
-
- spin_lock_irqsave(&hcrypt->lock, flags);
- for (ptr = hcrypt->algs.next; ptr != &hcrypt->algs; ptr = ptr->next) {
- struct ieee80211_crypto_alg *alg =
- (struct ieee80211_crypto_alg *)ptr;
- if (alg->ops == ops) {
- list_del(&alg->list);
- del_alg = alg;
- break;
- }
- }
- spin_unlock_irqrestore(&hcrypt->lock, flags);
- if (del_alg) {
- printk(KERN_DEBUG "ieee80211_crypt: unregistered algorithm "
- "'%s'\n", ops->name);
- kfree(del_alg);
+ spin_lock_irqsave(&ieee80211_crypto_lock, flags);
+ list_for_each_entry(alg, &ieee80211_crypto_algs, list) {
+ if (alg->ops == ops)
+ goto found;
}
-
- return del_alg ? 0 : -1;
+ spin_unlock_irqrestore(&ieee80211_crypto_lock, flags);
+ return -EINVAL;
+
+ found:
+ printk(KERN_DEBUG "ieee80211_crypt: unregistered algorithm "
+ "'%s'\n", ops->name);
+ list_del(&alg->list);
+ spin_unlock_irqrestore(&ieee80211_crypto_lock, flags);
+ kfree(alg);
+ return 0;
}
struct ieee80211_crypto_ops *ieee80211_get_crypto_ops(const char *name)
{
+ struct ieee80211_crypto_alg *alg;
unsigned long flags;
- struct list_head *ptr;
- struct ieee80211_crypto_alg *found_alg = NULL;
-
- if (hcrypt == NULL)
- return NULL;
-
- spin_lock_irqsave(&hcrypt->lock, flags);
- for (ptr = hcrypt->algs.next; ptr != &hcrypt->algs; ptr = ptr->next) {
- struct ieee80211_crypto_alg *alg =
- (struct ieee80211_crypto_alg *)ptr;
- if (strcmp(alg->ops->name, name) == 0) {
- found_alg = alg;
- break;
- }
+
+ spin_lock_irqsave(&ieee80211_crypto_lock, flags);
+ list_for_each_entry(alg, &ieee80211_crypto_algs, list) {
+ if (strcmp(alg->ops->name, name) == 0)
+ goto found;
}
- spin_unlock_irqrestore(&hcrypt->lock, flags);
+ spin_unlock_irqrestore(&ieee80211_crypto_lock, flags);
+ return NULL;
- if (found_alg)
- return found_alg->ops;
- else
- return NULL;
+ found:
+ spin_unlock_irqrestore(&ieee80211_crypto_lock, flags);
+ return alg->ops;
}
static void *ieee80211_crypt_null_init(int keyidx)
{
return (void *)1;
}
+
static void ieee80211_crypt_null_deinit(void *priv)
{
}
static struct ieee80211_crypto_ops ieee80211_crypt_null = {
- .name = "NULL",
- .init = ieee80211_crypt_null_init,
- .deinit = ieee80211_crypt_null_deinit,
- .encrypt_mpdu = NULL,
- .decrypt_mpdu = NULL,
- .encrypt_msdu = NULL,
- .decrypt_msdu = NULL,
- .set_key = NULL,
- .get_key = NULL,
- .extra_prefix_len = 0,
- .extra_postfix_len = 0,
- .owner = THIS_MODULE,
+ .name = "NULL",
+ .init = ieee80211_crypt_null_init,
+ .deinit = ieee80211_crypt_null_deinit,
+ .owner = THIS_MODULE,
};
static int __init ieee80211_crypto_init(void)
{
- int ret = -ENOMEM;
-
- hcrypt = kmalloc(sizeof(*hcrypt), GFP_KERNEL);
- if (!hcrypt)
- goto out;
-
- memset(hcrypt, 0, sizeof(*hcrypt));
- INIT_LIST_HEAD(&hcrypt->algs);
- spin_lock_init(&hcrypt->lock);
-
- ret = ieee80211_register_crypto_ops(&ieee80211_crypt_null);
- if (ret < 0) {
- kfree(hcrypt);
- hcrypt = NULL;
- }
- out:
- return ret;
+ return ieee80211_register_crypto_ops(&ieee80211_crypt_null);
}
static void __exit ieee80211_crypto_deinit(void)
{
- struct list_head *ptr, *n;
-
- if (hcrypt == NULL)
- return;
-
- for (ptr = hcrypt->algs.next, n = ptr->next; ptr != &hcrypt->algs;
- ptr = n, n = ptr->next) {
- struct ieee80211_crypto_alg *alg =
- (struct ieee80211_crypto_alg *)ptr;
- list_del(ptr);
- printk(KERN_DEBUG "ieee80211_crypt: unregistered algorithm "
- "'%s' (deinit)\n", alg->ops->name);
- kfree(alg);
- }
-
- kfree(hcrypt);
+ ieee80211_unregister_crypto_ops(&ieee80211_crypt_null);
+ BUG_ON(!list_empty(&ieee80211_crypto_algs));
}
EXPORT_SYMBOL(ieee80211_crypt_deinit_entries);
EXPORT_SYMBOL(ieee80211_crypt_deinit_handler);
EXPORT_SYMBOL(ieee80211_crypt_delayed_deinit);
+EXPORT_SYMBOL(ieee80211_crypt_quiescing);
EXPORT_SYMBOL(ieee80211_register_crypto_ops);
EXPORT_SYMBOL(ieee80211_unregister_crypto_ops);
diff --git a/net/ieee80211/ieee80211_crypt_ccmp.c b/net/ieee80211/ieee80211_crypt_ccmp.c
index 8fc13f45971e..470221728503 100644
--- a/net/ieee80211/ieee80211_crypt_ccmp.c
+++ b/net/ieee80211/ieee80211_crypt_ccmp.c
@@ -10,7 +10,6 @@
*/
#include <linux/config.h>
-#include <linux/version.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
@@ -119,7 +118,7 @@ static inline void xor_block(u8 * b, u8 * a, size_t len)
}
static void ccmp_init_blocks(struct crypto_tfm *tfm,
- struct ieee80211_hdr *hdr,
+ struct ieee80211_hdr_4addr *hdr,
u8 * pn, size_t dlen, u8 * b0, u8 * auth, u8 * s0)
{
u8 *pos, qc = 0;
@@ -191,26 +190,18 @@ static void ccmp_init_blocks(struct crypto_tfm *tfm,
ieee80211_ccmp_aes_encrypt(tfm, b0, s0);
}
-static int ieee80211_ccmp_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
+static int ieee80211_ccmp_hdr(struct sk_buff *skb, int hdr_len, void *priv)
{
struct ieee80211_ccmp_data *key = priv;
- int data_len, i, blocks, last, len;
- u8 *pos, *mic;
- struct ieee80211_hdr *hdr;
- u8 *b0 = key->tx_b0;
- u8 *b = key->tx_b;
- u8 *e = key->tx_e;
- u8 *s0 = key->tx_s0;
+ int i;
+ u8 *pos;
- if (skb_headroom(skb) < CCMP_HDR_LEN ||
- skb_tailroom(skb) < CCMP_MIC_LEN || skb->len < hdr_len)
+ if (skb_headroom(skb) < CCMP_HDR_LEN || skb->len < hdr_len)
return -1;
- data_len = skb->len - hdr_len;
pos = skb_push(skb, CCMP_HDR_LEN);
memmove(pos, pos + CCMP_HDR_LEN, hdr_len);
pos += hdr_len;
- mic = skb_put(skb, CCMP_MIC_LEN);
i = CCMP_PN_LEN - 1;
while (i >= 0) {
@@ -229,7 +220,31 @@ static int ieee80211_ccmp_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
*pos++ = key->tx_pn[1];
*pos++ = key->tx_pn[0];
- hdr = (struct ieee80211_hdr *)skb->data;
+ return CCMP_HDR_LEN;
+}
+
+static int ieee80211_ccmp_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
+{
+ struct ieee80211_ccmp_data *key = priv;
+ int data_len, i, blocks, last, len;
+ u8 *pos, *mic;
+ struct ieee80211_hdr_4addr *hdr;
+ u8 *b0 = key->tx_b0;
+ u8 *b = key->tx_b;
+ u8 *e = key->tx_e;
+ u8 *s0 = key->tx_s0;
+
+ if (skb_tailroom(skb) < CCMP_MIC_LEN || skb->len < hdr_len)
+ return -1;
+
+ data_len = skb->len - hdr_len;
+ len = ieee80211_ccmp_hdr(skb, hdr_len, priv);
+ if (len < 0)
+ return -1;
+
+ pos = skb->data + hdr_len + CCMP_HDR_LEN;
+ mic = skb_put(skb, CCMP_MIC_LEN);
+ hdr = (struct ieee80211_hdr_4addr *)skb->data;
ccmp_init_blocks(key->tfm, hdr, key->tx_pn, data_len, b0, b, s0);
blocks = (data_len + AES_BLOCK_LEN - 1) / AES_BLOCK_LEN;
@@ -258,7 +273,7 @@ static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
{
struct ieee80211_ccmp_data *key = priv;
u8 keyidx, *pos;
- struct ieee80211_hdr *hdr;
+ struct ieee80211_hdr_4addr *hdr;
u8 *b0 = key->rx_b0;
u8 *b = key->rx_b;
u8 *a = key->rx_a;
@@ -272,7 +287,7 @@ static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
return -1;
}
- hdr = (struct ieee80211_hdr *)skb->data;
+ hdr = (struct ieee80211_hdr_4addr *)skb->data;
pos = skb->data + hdr_len;
keyidx = pos[3];
if (!(keyidx & (1 << 5))) {
@@ -426,19 +441,20 @@ static char *ieee80211_ccmp_print_stats(char *p, void *priv)
}
static struct ieee80211_crypto_ops ieee80211_crypt_ccmp = {
- .name = "CCMP",
- .init = ieee80211_ccmp_init,
- .deinit = ieee80211_ccmp_deinit,
- .encrypt_mpdu = ieee80211_ccmp_encrypt,
- .decrypt_mpdu = ieee80211_ccmp_decrypt,
- .encrypt_msdu = NULL,
- .decrypt_msdu = NULL,
- .set_key = ieee80211_ccmp_set_key,
- .get_key = ieee80211_ccmp_get_key,
- .print_stats = ieee80211_ccmp_print_stats,
- .extra_prefix_len = CCMP_HDR_LEN,
- .extra_postfix_len = CCMP_MIC_LEN,
- .owner = THIS_MODULE,
+ .name = "CCMP",
+ .init = ieee80211_ccmp_init,
+ .deinit = ieee80211_ccmp_deinit,
+ .build_iv = ieee80211_ccmp_hdr,
+ .encrypt_mpdu = ieee80211_ccmp_encrypt,
+ .decrypt_mpdu = ieee80211_ccmp_decrypt,
+ .encrypt_msdu = NULL,
+ .decrypt_msdu = NULL,
+ .set_key = ieee80211_ccmp_set_key,
+ .get_key = ieee80211_ccmp_get_key,
+ .print_stats = ieee80211_ccmp_print_stats,
+ .extra_mpdu_prefix_len = CCMP_HDR_LEN,
+ .extra_mpdu_postfix_len = CCMP_MIC_LEN,
+ .owner = THIS_MODULE,
};
static int __init ieee80211_crypto_ccmp_init(void)
diff --git a/net/ieee80211/ieee80211_crypt_tkip.c b/net/ieee80211/ieee80211_crypt_tkip.c
index d4f9164be1a1..e0988320efbf 100644
--- a/net/ieee80211/ieee80211_crypt_tkip.c
+++ b/net/ieee80211/ieee80211_crypt_tkip.c
@@ -10,7 +10,6 @@
*/
#include <linux/config.h>
-#include <linux/version.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
@@ -59,8 +58,24 @@ struct ieee80211_tkip_data {
/* scratch buffers for virt_to_page() (crypto API) */
u8 rx_hdr[16], tx_hdr[16];
+
+ unsigned long flags;
};
+static unsigned long ieee80211_tkip_set_flags(unsigned long flags, void *priv)
+{
+ struct ieee80211_tkip_data *_priv = priv;
+ unsigned long old_flags = _priv->flags;
+ _priv->flags = flags;
+ return old_flags;
+}
+
+static unsigned long ieee80211_tkip_get_flags(void *priv)
+{
+ struct ieee80211_tkip_data *_priv = priv;
+ return _priv->flags;
+}
+
static void *ieee80211_tkip_init(int key_idx)
{
struct ieee80211_tkip_data *priv;
@@ -69,6 +84,7 @@ static void *ieee80211_tkip_init(int key_idx)
if (priv == NULL)
goto fail;
memset(priv, 0, sizeof(*priv));
+
priv->key_idx = key_idx;
priv->tfm_arc4 = crypto_alloc_tfm("arc4", 0);
@@ -255,25 +271,27 @@ static void tkip_mixing_phase2(u8 * WEPSeed, const u8 * TK, const u16 * TTAK,
#endif
}
-static int ieee80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
+static u8 *ieee80211_tkip_hdr(struct sk_buff *skb, int hdr_len, void *priv)
{
struct ieee80211_tkip_data *tkey = priv;
int len;
- u8 rc4key[16], *pos, *icv;
- struct ieee80211_hdr *hdr;
+ u8 *rc4key, *pos, *icv;
+ struct ieee80211_hdr_4addr *hdr;
u32 crc;
- struct scatterlist sg;
- if (skb_headroom(skb) < 8 || skb_tailroom(skb) < 4 ||
- skb->len < hdr_len)
- return -1;
+ hdr = (struct ieee80211_hdr_4addr *)skb->data;
+
+ if (skb_headroom(skb) < 8 || skb->len < hdr_len)
+ return NULL;
- hdr = (struct ieee80211_hdr *)skb->data;
if (!tkey->tx_phase1_done) {
tkip_mixing_phase1(tkey->tx_ttak, tkey->key, hdr->addr2,
tkey->tx_iv32);
tkey->tx_phase1_done = 1;
}
+ rc4key = kmalloc(16, GFP_ATOMIC);
+ if (!rc4key)
+ return NULL;
tkip_mixing_phase2(rc4key, tkey->key, tkey->tx_ttak, tkey->tx_iv16);
len = skb->len - hdr_len;
@@ -282,9 +300,9 @@ static int ieee80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
pos += hdr_len;
icv = skb_put(skb, 4);
- *pos++ = rc4key[0];
- *pos++ = rc4key[1];
- *pos++ = rc4key[2];
+ *pos++ = *rc4key;
+ *pos++ = *(rc4key + 1);
+ *pos++ = *(rc4key + 2);
*pos++ = (tkey->key_idx << 6) | (1 << 5) /* Ext IV included */ ;
*pos++ = tkey->tx_iv32 & 0xff;
*pos++ = (tkey->tx_iv32 >> 8) & 0xff;
@@ -297,6 +315,38 @@ static int ieee80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
icv[2] = crc >> 16;
icv[3] = crc >> 24;
+ return rc4key;
+}
+
+static int ieee80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
+{
+ struct ieee80211_tkip_data *tkey = priv;
+ int len;
+ const u8 *rc4key;
+ u8 *pos;
+ struct scatterlist sg;
+
+ if (tkey->flags & IEEE80211_CRYPTO_TKIP_COUNTERMEASURES) {
+ if (net_ratelimit()) {
+ struct ieee80211_hdr_4addr *hdr =
+ (struct ieee80211_hdr_4addr *)skb->data;
+ printk(KERN_DEBUG "TKIP countermeasures: dropped "
+ "TX packet to " MAC_FMT "\n",
+ MAC_ARG(hdr->addr1));
+ }
+ return -1;
+ }
+
+ if (skb_tailroom(skb) < 4 || skb->len < hdr_len)
+ return -1;
+
+ len = skb->len - hdr_len;
+ pos = skb->data + hdr_len;
+
+ rc4key = ieee80211_tkip_hdr(skb, hdr_len, priv);
+ if (!rc4key)
+ return -1;
+
crypto_cipher_setkey(tkey->tfm_arc4, rc4key, 16);
sg.page = virt_to_page(pos);
sg.offset = offset_in_page(pos);
@@ -319,16 +369,26 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
u8 keyidx, *pos;
u32 iv32;
u16 iv16;
- struct ieee80211_hdr *hdr;
+ struct ieee80211_hdr_4addr *hdr;
u8 icv[4];
u32 crc;
struct scatterlist sg;
int plen;
+ hdr = (struct ieee80211_hdr_4addr *)skb->data;
+
+ if (tkey->flags & IEEE80211_CRYPTO_TKIP_COUNTERMEASURES) {
+ if (net_ratelimit()) {
+ printk(KERN_DEBUG "TKIP countermeasures: dropped "
+ "received packet from " MAC_FMT "\n",
+ MAC_ARG(hdr->addr2));
+ }
+ return -1;
+ }
+
if (skb->len < hdr_len + 8 + 4)
return -1;
- hdr = (struct ieee80211_hdr *)skb->data;
pos = skb->data + hdr_len;
keyidx = pos[3];
if (!(keyidx & (1 << 5))) {
@@ -441,9 +501,9 @@ static int michael_mic(struct ieee80211_tkip_data *tkey, u8 * key, u8 * hdr,
static void michael_mic_hdr(struct sk_buff *skb, u8 * hdr)
{
- struct ieee80211_hdr *hdr11;
+ struct ieee80211_hdr_4addr *hdr11;
- hdr11 = (struct ieee80211_hdr *)skb->data;
+ hdr11 = (struct ieee80211_hdr_4addr *)skb->data;
switch (le16_to_cpu(hdr11->frame_ctl) &
(IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS)) {
case IEEE80211_FCTL_TODS:
@@ -490,9 +550,9 @@ static int ieee80211_michael_mic_add(struct sk_buff *skb, int hdr_len,
return 0;
}
-#if WIRELESS_EXT >= 18
static void ieee80211_michael_mic_failure(struct net_device *dev,
- struct ieee80211_hdr *hdr, int keyidx)
+ struct ieee80211_hdr_4addr *hdr,
+ int keyidx)
{
union iwreq_data wrqu;
struct iw_michaelmicfailure ev;
@@ -510,28 +570,6 @@ static void ieee80211_michael_mic_failure(struct net_device *dev,
wrqu.data.length = sizeof(ev);
wireless_send_event(dev, IWEVMICHAELMICFAILURE, &wrqu, (char *)&ev);
}
-#elif WIRELESS_EXT >= 15
-static void ieee80211_michael_mic_failure(struct net_device *dev,
- struct ieee80211_hdr *hdr, int keyidx)
-{
- union iwreq_data wrqu;
- char buf[128];
-
- /* TODO: needed parameters: count, keyid, key type, TSC */
- sprintf(buf, "MLME-MICHAELMICFAILURE.indication(keyid=%d %scast addr="
- MAC_FMT ")", keyidx, hdr->addr1[0] & 0x01 ? "broad" : "uni",
- MAC_ARG(hdr->addr2));
- memset(&wrqu, 0, sizeof(wrqu));
- wrqu.data.length = strlen(buf);
- wireless_send_event(dev, IWEVCUSTOM, &wrqu, buf);
-}
-#else /* WIRELESS_EXT >= 15 */
-static inline void ieee80211_michael_mic_failure(struct net_device *dev,
- struct ieee80211_hdr *hdr,
- int keyidx)
-{
-}
-#endif /* WIRELESS_EXT >= 15 */
static int ieee80211_michael_mic_verify(struct sk_buff *skb, int keyidx,
int hdr_len, void *priv)
@@ -547,8 +585,8 @@ static int ieee80211_michael_mic_verify(struct sk_buff *skb, int keyidx,
skb->data + hdr_len, skb->len - 8 - hdr_len, mic))
return -1;
if (memcmp(mic, skb->data + skb->len - 8, 8) != 0) {
- struct ieee80211_hdr *hdr;
- hdr = (struct ieee80211_hdr *)skb->data;
+ struct ieee80211_hdr_4addr *hdr;
+ hdr = (struct ieee80211_hdr_4addr *)skb->data;
printk(KERN_DEBUG "%s: Michael MIC verification failed for "
"MSDU from " MAC_FMT " keyidx=%d\n",
skb->dev ? skb->dev->name : "N/A", MAC_ARG(hdr->addr2),
@@ -654,19 +692,22 @@ static char *ieee80211_tkip_print_stats(char *p, void *priv)
}
static struct ieee80211_crypto_ops ieee80211_crypt_tkip = {
- .name = "TKIP",
- .init = ieee80211_tkip_init,
- .deinit = ieee80211_tkip_deinit,
- .encrypt_mpdu = ieee80211_tkip_encrypt,
- .decrypt_mpdu = ieee80211_tkip_decrypt,
- .encrypt_msdu = ieee80211_michael_mic_add,
- .decrypt_msdu = ieee80211_michael_mic_verify,
- .set_key = ieee80211_tkip_set_key,
- .get_key = ieee80211_tkip_get_key,
- .print_stats = ieee80211_tkip_print_stats,
- .extra_prefix_len = 4 + 4, /* IV + ExtIV */
- .extra_postfix_len = 8 + 4, /* MIC + ICV */
- .owner = THIS_MODULE,
+ .name = "TKIP",
+ .init = ieee80211_tkip_init,
+ .deinit = ieee80211_tkip_deinit,
+ .encrypt_mpdu = ieee80211_tkip_encrypt,
+ .decrypt_mpdu = ieee80211_tkip_decrypt,
+ .encrypt_msdu = ieee80211_michael_mic_add,
+ .decrypt_msdu = ieee80211_michael_mic_verify,
+ .set_key = ieee80211_tkip_set_key,
+ .get_key = ieee80211_tkip_get_key,
+ .print_stats = ieee80211_tkip_print_stats,
+ .extra_mpdu_prefix_len = 4 + 4, /* IV + ExtIV */
+ .extra_mpdu_postfix_len = 4, /* ICV */
+ .extra_msdu_postfix_len = 8, /* MIC */
+ .get_flags = ieee80211_tkip_get_flags,
+ .set_flags = ieee80211_tkip_set_flags,
+ .owner = THIS_MODULE,
};
static int __init ieee80211_crypto_tkip_init(void)
diff --git a/net/ieee80211/ieee80211_crypt_wep.c b/net/ieee80211/ieee80211_crypt_wep.c
index b4d2514a0902..073aebdf0f67 100644
--- a/net/ieee80211/ieee80211_crypt_wep.c
+++ b/net/ieee80211/ieee80211_crypt_wep.c
@@ -10,7 +10,6 @@
*/
#include <linux/config.h>
-#include <linux/version.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
@@ -229,19 +228,19 @@ static char *prism2_wep_print_stats(char *p, void *priv)
}
static struct ieee80211_crypto_ops ieee80211_crypt_wep = {
- .name = "WEP",
- .init = prism2_wep_init,
- .deinit = prism2_wep_deinit,
- .encrypt_mpdu = prism2_wep_encrypt,
- .decrypt_mpdu = prism2_wep_decrypt,
- .encrypt_msdu = NULL,
- .decrypt_msdu = NULL,
- .set_key = prism2_wep_set_key,
- .get_key = prism2_wep_get_key,
- .print_stats = prism2_wep_print_stats,
- .extra_prefix_len = 4, /* IV */
- .extra_postfix_len = 4, /* ICV */
- .owner = THIS_MODULE,
+ .name = "WEP",
+ .init = prism2_wep_init,
+ .deinit = prism2_wep_deinit,
+ .encrypt_mpdu = prism2_wep_encrypt,
+ .decrypt_mpdu = prism2_wep_decrypt,
+ .encrypt_msdu = NULL,
+ .decrypt_msdu = NULL,
+ .set_key = prism2_wep_set_key,
+ .get_key = prism2_wep_get_key,
+ .print_stats = prism2_wep_print_stats,
+ .extra_mpdu_prefix_len = 4, /* IV */
+ .extra_mpdu_postfix_len = 4, /* ICV */
+ .owner = THIS_MODULE,
};
static int __init ieee80211_crypto_wep_init(void)
diff --git a/net/ieee80211/ieee80211_geo.c b/net/ieee80211/ieee80211_geo.c
new file mode 100644
index 000000000000..610cc5cbc252
--- /dev/null
+++ b/net/ieee80211/ieee80211_geo.c
@@ -0,0 +1,140 @@
+/******************************************************************************
+
+ Copyright(c) 2005 Intel Corporation. All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of version 2 of the GNU General Public License as
+ published by the Free Software Foundation.
+
+ This program is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ more details.
+
+ You should have received a copy of the GNU General Public License along with
+ this program; if not, write to the Free Software Foundation, Inc., 59
+ Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ The full GNU General Public License is included in this distribution in the
+ file called LICENSE.
+
+ Contact Information:
+ James P. Ketrenos <ipw2100-admin@linux.intel.com>
+ Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+
+******************************************************************************/
+#include <linux/compiler.h>
+#include <linux/config.h>
+#include <linux/errno.h>
+#include <linux/if_arp.h>
+#include <linux/in6.h>
+#include <linux/in.h>
+#include <linux/ip.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/netdevice.h>
+#include <linux/proc_fs.h>
+#include <linux/skbuff.h>
+#include <linux/slab.h>
+#include <linux/tcp.h>
+#include <linux/types.h>
+#include <linux/wireless.h>
+#include <linux/etherdevice.h>
+#include <asm/uaccess.h>
+
+#include <net/ieee80211.h>
+
+int ieee80211_is_valid_channel(struct ieee80211_device *ieee, u8 channel)
+{
+ int i;
+
+ /* Driver needs to initialize the geography map before using
+ * these helper functions */
+ BUG_ON(ieee->geo.bg_channels == 0 && ieee->geo.a_channels == 0);
+
+ if (ieee->freq_band & IEEE80211_24GHZ_BAND)
+ for (i = 0; i < ieee->geo.bg_channels; i++)
+ /* NOTE: If G mode is currently supported but
+ * this is a B only channel, we don't see it
+ * as valid. */
+ if ((ieee->geo.bg[i].channel == channel) &&
+ (!(ieee->mode & IEEE_G) ||
+ !(ieee->geo.bg[i].flags & IEEE80211_CH_B_ONLY)))
+ return IEEE80211_24GHZ_BAND;
+
+ if (ieee->freq_band & IEEE80211_52GHZ_BAND)
+ for (i = 0; i < ieee->geo.a_channels; i++)
+ if (ieee->geo.a[i].channel == channel)
+ return IEEE80211_52GHZ_BAND;
+
+ return 0;
+}
+
+int ieee80211_channel_to_index(struct ieee80211_device *ieee, u8 channel)
+{
+ int i;
+
+ /* Driver needs to initialize the geography map before using
+ * these helper functions */
+ BUG_ON(ieee->geo.bg_channels == 0 && ieee->geo.a_channels == 0);
+
+ if (ieee->freq_band & IEEE80211_24GHZ_BAND)
+ for (i = 0; i < ieee->geo.bg_channels; i++)
+ if (ieee->geo.bg[i].channel == channel)
+ return i;
+
+ if (ieee->freq_band & IEEE80211_52GHZ_BAND)
+ for (i = 0; i < ieee->geo.a_channels; i++)
+ if (ieee->geo.a[i].channel == channel)
+ return i;
+
+ return -1;
+}
+
+u8 ieee80211_freq_to_channel(struct ieee80211_device * ieee, u32 freq)
+{
+ int i;
+
+ /* Driver needs to initialize the geography map before using
+ * these helper functions */
+ BUG_ON(ieee->geo.bg_channels == 0 && ieee->geo.a_channels == 0);
+
+ freq /= 100000;
+
+ if (ieee->freq_band & IEEE80211_24GHZ_BAND)
+ for (i = 0; i < ieee->geo.bg_channels; i++)
+ if (ieee->geo.bg[i].freq == freq)
+ return ieee->geo.bg[i].channel;
+
+ if (ieee->freq_band & IEEE80211_52GHZ_BAND)
+ for (i = 0; i < ieee->geo.a_channels; i++)
+ if (ieee->geo.a[i].freq == freq)
+ return ieee->geo.a[i].channel;
+
+ return 0;
+}
+
+int ieee80211_set_geo(struct ieee80211_device *ieee,
+ const struct ieee80211_geo *geo)
+{
+ memcpy(ieee->geo.name, geo->name, 3);
+ ieee->geo.name[3] = '\0';
+ ieee->geo.bg_channels = geo->bg_channels;
+ ieee->geo.a_channels = geo->a_channels;
+ memcpy(ieee->geo.bg, geo->bg, geo->bg_channels *
+ sizeof(struct ieee80211_channel));
+ memcpy(ieee->geo.a, geo->a, ieee->geo.a_channels *
+ sizeof(struct ieee80211_channel));
+ return 0;
+}
+
+const struct ieee80211_geo *ieee80211_get_geo(struct ieee80211_device *ieee)
+{
+ return &ieee->geo;
+}
+
+EXPORT_SYMBOL(ieee80211_is_valid_channel);
+EXPORT_SYMBOL(ieee80211_freq_to_channel);
+EXPORT_SYMBOL(ieee80211_channel_to_index);
+EXPORT_SYMBOL(ieee80211_set_geo);
+EXPORT_SYMBOL(ieee80211_get_geo);
diff --git a/net/ieee80211/ieee80211_module.c b/net/ieee80211/ieee80211_module.c
index 6059e9e37123..321287bc887f 100644
--- a/net/ieee80211/ieee80211_module.c
+++ b/net/ieee80211/ieee80211_module.c
@@ -1,6 +1,6 @@
/*******************************************************************************
- Copyright(c) 2004 Intel Corporation. All rights reserved.
+ Copyright(c) 2004-2005 Intel Corporation. All rights reserved.
Portions of this file are based on the WEP enablement code provided by the
Host AP project hostap-drivers v0.1.3
@@ -45,7 +45,6 @@
#include <linux/slab.h>
#include <linux/tcp.h>
#include <linux/types.h>
-#include <linux/version.h>
#include <linux/wireless.h>
#include <linux/etherdevice.h>
#include <asm/uaccess.h>
@@ -53,12 +52,15 @@
#include <net/ieee80211.h>
-MODULE_DESCRIPTION("802.11 data/management/control stack");
-MODULE_AUTHOR
- ("Copyright (C) 2004 Intel Corporation <jketreno@linux.intel.com>");
-MODULE_LICENSE("GPL");
+#define DRV_DESCRIPTION "802.11 data/management/control stack"
+#define DRV_NAME "ieee80211"
+#define DRV_VERSION IEEE80211_VERSION
+#define DRV_COPYRIGHT "Copyright (C) 2004-2005 Intel Corporation <jketreno@linux.intel.com>"
-#define DRV_NAME "ieee80211"
+MODULE_VERSION(DRV_VERSION);
+MODULE_DESCRIPTION(DRV_DESCRIPTION);
+MODULE_AUTHOR(DRV_COPYRIGHT);
+MODULE_LICENSE("GPL");
static inline int ieee80211_networks_allocate(struct ieee80211_device *ieee)
{
@@ -126,26 +128,34 @@ struct net_device *alloc_ieee80211(int sizeof_priv)
/* Default fragmentation threshold is maximum payload size */
ieee->fts = DEFAULT_FTS;
+ ieee->rts = DEFAULT_FTS;
ieee->scan_age = DEFAULT_MAX_SCAN_AGE;
ieee->open_wep = 1;
/* Default to enabling full open WEP with host based encrypt/decrypt */
ieee->host_encrypt = 1;
ieee->host_decrypt = 1;
+ ieee->host_mc_decrypt = 1;
+
+ /* Host fragementation in Open mode. Default is enabled.
+ * Note: host fragmentation is always enabled if host encryption
+ * is enabled. For cards can do hardware encryption, they must do
+ * hardware fragmentation as well. So we don't need a variable
+ * like host_enc_frag. */
+ ieee->host_open_frag = 1;
ieee->ieee802_1x = 1; /* Default to supporting 802.1x */
INIT_LIST_HEAD(&ieee->crypt_deinit_list);
init_timer(&ieee->crypt_deinit_timer);
ieee->crypt_deinit_timer.data = (unsigned long)ieee;
ieee->crypt_deinit_timer.function = ieee80211_crypt_deinit_handler;
+ ieee->crypt_quiesced = 0;
spin_lock_init(&ieee->lock);
ieee->wpa_enabled = 0;
- ieee->tkip_countermeasures = 0;
ieee->drop_unencrypted = 0;
ieee->privacy_invoked = 0;
- ieee->ieee802_1x = 1;
return dev;
@@ -161,6 +171,7 @@ void free_ieee80211(struct net_device *dev)
int i;
+ ieee80211_crypt_quiescing(ieee);
del_timer_sync(&ieee->crypt_deinit_timer);
ieee80211_crypt_deinit_entries(ieee, 1);
@@ -195,38 +206,26 @@ static int show_debug_level(char *page, char **start, off_t offset,
static int store_debug_level(struct file *file, const char __user * buffer,
unsigned long count, void *data)
{
- char buf[] = "0x00000000";
- char *p = (char *)buf;
+ char buf[] = "0x00000000\n";
+ unsigned long len = min((unsigned long)sizeof(buf) - 1, count);
unsigned long val;
- if (count > sizeof(buf) - 1)
- count = sizeof(buf) - 1;
-
- if (copy_from_user(buf, buffer, count))
+ if (copy_from_user(buf, buffer, len))
return count;
- buf[count] = 0;
- /*
- * what a FPOS... What, sscanf(buf, "%i", &val) would be too
- * scary?
- */
- if (p[1] == 'x' || p[1] == 'X' || p[0] == 'x' || p[0] == 'X') {
- p++;
- if (p[0] == 'x' || p[0] == 'X')
- p++;
- val = simple_strtoul(p, &p, 16);
- } else
- val = simple_strtoul(p, &p, 10);
- if (p == buf)
+ buf[len] = 0;
+ if (sscanf(buf, "%li", &val) != 1)
printk(KERN_INFO DRV_NAME
": %s is not in hex or decimal form.\n", buf);
else
ieee80211_debug_level = val;
- return strlen(buf);
+ return strnlen(buf, len);
}
+#endif /* CONFIG_IEEE80211_DEBUG */
static int __init ieee80211_init(void)
{
+#ifdef CONFIG_IEEE80211_DEBUG
struct proc_dir_entry *e;
ieee80211_debug_level = debug;
@@ -246,26 +245,33 @@ static int __init ieee80211_init(void)
e->read_proc = show_debug_level;
e->write_proc = store_debug_level;
e->data = NULL;
+#endif /* CONFIG_IEEE80211_DEBUG */
+
+ printk(KERN_INFO DRV_NAME ": " DRV_DESCRIPTION ", " DRV_VERSION "\n");
+ printk(KERN_INFO DRV_NAME ": " DRV_COPYRIGHT "\n");
return 0;
}
static void __exit ieee80211_exit(void)
{
+#ifdef CONFIG_IEEE80211_DEBUG
if (ieee80211_proc) {
remove_proc_entry("debug_level", ieee80211_proc);
remove_proc_entry(DRV_NAME, proc_net);
ieee80211_proc = NULL;
}
+#endif /* CONFIG_IEEE80211_DEBUG */
}
+#ifdef CONFIG_IEEE80211_DEBUG
#include <linux/moduleparam.h>
module_param(debug, int, 0444);
MODULE_PARM_DESC(debug, "debug output mask");
+#endif /* CONFIG_IEEE80211_DEBUG */
module_exit(ieee80211_exit);
module_init(ieee80211_init);
-#endif
const char *escape_essid(const char *essid, u8 essid_len)
{
diff --git a/net/ieee80211/ieee80211_rx.c b/net/ieee80211/ieee80211_rx.c
index f7dcd854139e..03efaacbdb73 100644
--- a/net/ieee80211/ieee80211_rx.c
+++ b/net/ieee80211/ieee80211_rx.c
@@ -5,7 +5,7 @@
* Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
* <jkmaline@cc.hut.fi>
* Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
- * Copyright (c) 2004, Intel Corporation
+ * Copyright (c) 2004-2005, Intel 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
@@ -28,7 +28,6 @@
#include <linux/slab.h>
#include <linux/tcp.h>
#include <linux/types.h>
-#include <linux/version.h>
#include <linux/wireless.h>
#include <linux/etherdevice.h>
#include <asm/uaccess.h>
@@ -87,7 +86,7 @@ static struct ieee80211_frag_entry *ieee80211_frag_cache_find(struct
/* Called only as a tasklet (software IRQ) */
static struct sk_buff *ieee80211_frag_cache_get(struct ieee80211_device *ieee,
- struct ieee80211_hdr *hdr)
+ struct ieee80211_hdr_4addr *hdr)
{
struct sk_buff *skb = NULL;
u16 sc;
@@ -101,7 +100,7 @@ static struct sk_buff *ieee80211_frag_cache_get(struct ieee80211_device *ieee,
if (frag == 0) {
/* Reserve enough space to fit maximum frame length */
skb = dev_alloc_skb(ieee->dev->mtu +
- sizeof(struct ieee80211_hdr) +
+ sizeof(struct ieee80211_hdr_4addr) +
8 /* LLC */ +
2 /* alignment */ +
8 /* WEP */ + ETH_ALEN /* WDS */ );
@@ -138,7 +137,7 @@ static struct sk_buff *ieee80211_frag_cache_get(struct ieee80211_device *ieee,
/* Called only as a tasklet (software IRQ) */
static int ieee80211_frag_cache_invalidate(struct ieee80211_device *ieee,
- struct ieee80211_hdr *hdr)
+ struct ieee80211_hdr_4addr *hdr)
{
u16 sc;
unsigned int seq;
@@ -176,7 +175,7 @@ ieee80211_rx_frame_mgmt(struct ieee80211_device *ieee, struct sk_buff *skb,
ieee->dev->name);
return 0;
/*
- hostap_update_sta_ps(ieee, (struct hostap_ieee80211_hdr *)
+ hostap_update_sta_ps(ieee, (struct hostap_ieee80211_hdr_4addr *)
skb->data);*/
}
@@ -232,13 +231,13 @@ static int ieee80211_is_eapol_frame(struct ieee80211_device *ieee,
{
struct net_device *dev = ieee->dev;
u16 fc, ethertype;
- struct ieee80211_hdr *hdr;
+ struct ieee80211_hdr_3addr *hdr;
u8 *pos;
if (skb->len < 24)
return 0;
- hdr = (struct ieee80211_hdr *)skb->data;
+ hdr = (struct ieee80211_hdr_3addr *)skb->data;
fc = le16_to_cpu(hdr->frame_ctl);
/* check that the frame is unicast frame to us */
@@ -271,26 +270,15 @@ static inline int
ieee80211_rx_frame_decrypt(struct ieee80211_device *ieee, struct sk_buff *skb,
struct ieee80211_crypt_data *crypt)
{
- struct ieee80211_hdr *hdr;
+ struct ieee80211_hdr_3addr *hdr;
int res, hdrlen;
if (crypt == NULL || crypt->ops->decrypt_mpdu == NULL)
return 0;
- hdr = (struct ieee80211_hdr *)skb->data;
+ hdr = (struct ieee80211_hdr_3addr *)skb->data;
hdrlen = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl));
-#ifdef CONFIG_IEEE80211_CRYPT_TKIP
- if (ieee->tkip_countermeasures && strcmp(crypt->ops->name, "TKIP") == 0) {
- if (net_ratelimit()) {
- printk(KERN_DEBUG "%s: TKIP countermeasures: dropped "
- "received packet from " MAC_FMT "\n",
- ieee->dev->name, MAC_ARG(hdr->addr2));
- }
- return -1;
- }
-#endif
-
atomic_inc(&crypt->refcnt);
res = crypt->ops->decrypt_mpdu(skb, hdrlen, crypt->priv);
atomic_dec(&crypt->refcnt);
@@ -314,13 +302,13 @@ ieee80211_rx_frame_decrypt_msdu(struct ieee80211_device *ieee,
struct sk_buff *skb, int keyidx,
struct ieee80211_crypt_data *crypt)
{
- struct ieee80211_hdr *hdr;
+ struct ieee80211_hdr_3addr *hdr;
int res, hdrlen;
if (crypt == NULL || crypt->ops->decrypt_msdu == NULL)
return 0;
- hdr = (struct ieee80211_hdr *)skb->data;
+ hdr = (struct ieee80211_hdr_3addr *)skb->data;
hdrlen = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl));
atomic_inc(&crypt->refcnt);
@@ -343,7 +331,7 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
struct ieee80211_rx_stats *rx_stats)
{
struct net_device *dev = ieee->dev;
- struct ieee80211_hdr *hdr;
+ struct ieee80211_hdr_4addr *hdr;
size_t hdrlen;
u16 fc, type, stype, sc;
struct net_device_stats *stats;
@@ -363,7 +351,7 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
struct ieee80211_crypt_data *crypt = NULL;
int keyidx = 0;
- hdr = (struct ieee80211_hdr *)skb->data;
+ hdr = (struct ieee80211_hdr_4addr *)skb->data;
stats = &ieee->stats;
if (skb->len < 10) {
@@ -378,35 +366,53 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
frag = WLAN_GET_SEQ_FRAG(sc);
hdrlen = ieee80211_get_hdrlen(fc);
-#ifdef NOT_YET
-#if WIRELESS_EXT > 15
/* Put this code here so that we avoid duplicating it in all
* Rx paths. - Jean II */
#ifdef IW_WIRELESS_SPY /* defined in iw_handler.h */
+#ifdef CONFIG_NET_RADIO
/* If spy monitoring on */
- if (iface->spy_data.spy_number > 0) {
+ if (ieee->spy_data.spy_number > 0) {
struct iw_quality wstats;
- wstats.level = rx_stats->signal;
- wstats.noise = rx_stats->noise;
- wstats.updated = 6; /* No qual value */
+
+ wstats.updated = 0;
+ if (rx_stats->mask & IEEE80211_STATMASK_RSSI) {
+ wstats.level = rx_stats->rssi;
+ wstats.updated |= IW_QUAL_LEVEL_UPDATED;
+ } else
+ wstats.updated |= IW_QUAL_LEVEL_INVALID;
+
+ if (rx_stats->mask & IEEE80211_STATMASK_NOISE) {
+ wstats.noise = rx_stats->noise;
+ wstats.updated |= IW_QUAL_NOISE_UPDATED;
+ } else
+ wstats.updated |= IW_QUAL_NOISE_INVALID;
+
+ if (rx_stats->mask & IEEE80211_STATMASK_SIGNAL) {
+ wstats.qual = rx_stats->signal;
+ wstats.updated |= IW_QUAL_QUAL_UPDATED;
+ } else
+ wstats.updated |= IW_QUAL_QUAL_INVALID;
+
/* Update spy records */
- wireless_spy_update(dev, hdr->addr2, &wstats);
+ wireless_spy_update(ieee->dev, hdr->addr2, &wstats);
}
+#endif /* CONFIG_NET_RADIO */
#endif /* IW_WIRELESS_SPY */
-#endif /* WIRELESS_EXT > 15 */
+
+#ifdef NOT_YET
hostap_update_rx_stats(local->ap, hdr, rx_stats);
#endif
-#if WIRELESS_EXT > 15
if (ieee->iw_mode == IW_MODE_MONITOR) {
ieee80211_monitor_rx(ieee, skb, rx_stats);
stats->rx_packets++;
stats->rx_bytes += skb->len;
return 1;
}
-#endif
- if (ieee->host_decrypt) {
+ if ((is_multicast_ether_addr(hdr->addr1) ||
+ is_broadcast_ether_addr(hdr->addr2)) ? ieee->host_mc_decrypt :
+ ieee->host_decrypt) {
int idx = 0;
if (skb->len >= hdrlen + 3)
idx = skb->data[hdrlen + 3] >> 6;
@@ -531,6 +537,9 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
/* Nullfunc frames may have PS-bit set, so they must be passed to
* hostap_handle_sta_rx() before being dropped here. */
+
+ stype &= ~IEEE80211_STYPE_QOS_DATA;
+
if (stype != IEEE80211_STYPE_DATA &&
stype != IEEE80211_STYPE_DATA_CFACK &&
stype != IEEE80211_STYPE_DATA_CFPOLL &&
@@ -549,7 +558,7 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
(keyidx = ieee80211_rx_frame_decrypt(ieee, skb, crypt)) < 0)
goto rx_dropped;
- hdr = (struct ieee80211_hdr *)skb->data;
+ hdr = (struct ieee80211_hdr_4addr *)skb->data;
/* skb: hdr + (possibly fragmented) plaintext payload */
// PR: FIXME: hostap has additional conditions in the "if" below:
@@ -603,7 +612,7 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
/* this was the last fragment and the frame will be
* delivered, so remove skb from fragment cache */
skb = frag_skb;
- hdr = (struct ieee80211_hdr *)skb->data;
+ hdr = (struct ieee80211_hdr_4addr *)skb->data;
ieee80211_frag_cache_invalidate(ieee, hdr);
}
@@ -613,7 +622,7 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
ieee80211_rx_frame_decrypt_msdu(ieee, skb, keyidx, crypt))
goto rx_dropped;
- hdr = (struct ieee80211_hdr *)skb->data;
+ hdr = (struct ieee80211_hdr_4addr *)skb->data;
if (crypt && !(fc & IEEE80211_FCTL_PROTECTED) && !ieee->open_wep) {
if ( /*ieee->ieee802_1x && */
ieee80211_is_eapol_frame(ieee, skb)) {
@@ -755,69 +764,179 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
#define MGMT_FRAME_FIXED_PART_LENGTH 0x24
-static inline int ieee80211_is_ofdm_rate(u8 rate)
+static u8 qos_oui[QOS_OUI_LEN] = { 0x00, 0x50, 0xF2 };
+
+/*
+* Make ther structure we read from the beacon packet has
+* the right values
+*/
+static int ieee80211_verify_qos_info(struct ieee80211_qos_information_element
+ *info_element, int sub_type)
{
- switch (rate & ~IEEE80211_BASIC_RATE_MASK) {
- case IEEE80211_OFDM_RATE_6MB:
- case IEEE80211_OFDM_RATE_9MB:
- case IEEE80211_OFDM_RATE_12MB:
- case IEEE80211_OFDM_RATE_18MB:
- case IEEE80211_OFDM_RATE_24MB:
- case IEEE80211_OFDM_RATE_36MB:
- case IEEE80211_OFDM_RATE_48MB:
- case IEEE80211_OFDM_RATE_54MB:
- return 1;
- }
+
+ if (info_element->qui_subtype != sub_type)
+ return -1;
+ if (memcmp(info_element->qui, qos_oui, QOS_OUI_LEN))
+ return -1;
+ if (info_element->qui_type != QOS_OUI_TYPE)
+ return -1;
+ if (info_element->version != QOS_VERSION_1)
+ return -1;
+
return 0;
}
-static inline int ieee80211_network_init(struct ieee80211_device *ieee,
- struct ieee80211_probe_response
- *beacon,
- struct ieee80211_network *network,
- struct ieee80211_rx_stats *stats)
+/*
+ * Parse a QoS parameter element
+ */
+static int ieee80211_read_qos_param_element(struct ieee80211_qos_parameter_info
+ *element_param, struct ieee80211_info_element
+ *info_element)
{
-#ifdef CONFIG_IEEE80211_DEBUG
- char rates_str[64];
- char *p;
-#endif
- struct ieee80211_info_element *info_element;
- u16 left;
- u8 i;
+ int ret = 0;
+ u16 size = sizeof(struct ieee80211_qos_parameter_info) - 2;
- /* Pull out fixed field data */
- memcpy(network->bssid, beacon->header.addr3, ETH_ALEN);
- network->capability = beacon->capability;
- network->last_scanned = jiffies;
- network->time_stamp[0] = beacon->time_stamp[0];
- network->time_stamp[1] = beacon->time_stamp[1];
- network->beacon_interval = beacon->beacon_interval;
- /* Where to pull this? beacon->listen_interval; */
- network->listen_interval = 0x0A;
- network->rates_len = network->rates_ex_len = 0;
- network->last_associate = 0;
- network->ssid_len = 0;
- network->flags = 0;
- network->atim_window = 0;
+ if ((info_element == NULL) || (element_param == NULL))
+ return -1;
- if (stats->freq == IEEE80211_52GHZ_BAND) {
- /* for A band (No DS info) */
- network->channel = stats->received_channel;
+ if (info_element->id == QOS_ELEMENT_ID && info_element->len == size) {
+ memcpy(element_param->info_element.qui, info_element->data,
+ info_element->len);
+ element_param->info_element.elementID = info_element->id;
+ element_param->info_element.length = info_element->len;
} else
- network->flags |= NETWORK_HAS_CCK;
+ ret = -1;
+ if (ret == 0)
+ ret = ieee80211_verify_qos_info(&element_param->info_element,
+ QOS_OUI_PARAM_SUB_TYPE);
+ return ret;
+}
- network->wpa_ie_len = 0;
- network->rsn_ie_len = 0;
+/*
+ * Parse a QoS information element
+ */
+static int ieee80211_read_qos_info_element(struct
+ ieee80211_qos_information_element
+ *element_info, struct ieee80211_info_element
+ *info_element)
+{
+ int ret = 0;
+ u16 size = sizeof(struct ieee80211_qos_information_element) - 2;
+
+ if (element_info == NULL)
+ return -1;
+ if (info_element == NULL)
+ return -1;
+
+ if ((info_element->id == QOS_ELEMENT_ID) && (info_element->len == size)) {
+ memcpy(element_info->qui, info_element->data,
+ info_element->len);
+ element_info->elementID = info_element->id;
+ element_info->length = info_element->len;
+ } else
+ ret = -1;
+
+ if (ret == 0)
+ ret = ieee80211_verify_qos_info(element_info,
+ QOS_OUI_INFO_SUB_TYPE);
+ return ret;
+}
+
+/*
+ * Write QoS parameters from the ac parameters.
+ */
+static int ieee80211_qos_convert_ac_to_parameters(struct
+ ieee80211_qos_parameter_info
+ *param_elm, struct
+ ieee80211_qos_parameters
+ *qos_param)
+{
+ int rc = 0;
+ int i;
+ struct ieee80211_qos_ac_parameter *ac_params;
+ u32 txop;
+ u8 cw_min;
+ u8 cw_max;
+
+ for (i = 0; i < QOS_QUEUE_NUM; i++) {
+ ac_params = &(param_elm->ac_params_record[i]);
+
+ qos_param->aifs[i] = (ac_params->aci_aifsn) & 0x0F;
+ qos_param->aifs[i] -= (qos_param->aifs[i] < 2) ? 0 : 2;
+
+ cw_min = ac_params->ecw_min_max & 0x0F;
+ qos_param->cw_min[i] = (u16) ((1 << cw_min) - 1);
+
+ cw_max = (ac_params->ecw_min_max & 0xF0) >> 4;
+ qos_param->cw_max[i] = (u16) ((1 << cw_max) - 1);
+
+ qos_param->flag[i] =
+ (ac_params->aci_aifsn & 0x10) ? 0x01 : 0x00;
+
+ txop = le16_to_cpu(ac_params->tx_op_limit) * 32;
+ qos_param->tx_op_limit[i] = (u16) txop;
+ }
+ return rc;
+}
+
+/*
+ * we have a generic data element which it may contain QoS information or
+ * parameters element. check the information element length to decide
+ * which type to read
+ */
+static int ieee80211_parse_qos_info_param_IE(struct ieee80211_info_element
+ *info_element,
+ struct ieee80211_network *network)
+{
+ int rc = 0;
+ struct ieee80211_qos_parameters *qos_param = NULL;
+ struct ieee80211_qos_information_element qos_info_element;
+
+ rc = ieee80211_read_qos_info_element(&qos_info_element, info_element);
+
+ if (rc == 0) {
+ network->qos_data.param_count = qos_info_element.ac_info & 0x0F;
+ network->flags |= NETWORK_HAS_QOS_INFORMATION;
+ } else {
+ struct ieee80211_qos_parameter_info param_element;
+
+ rc = ieee80211_read_qos_param_element(&param_element,
+ info_element);
+ if (rc == 0) {
+ qos_param = &(network->qos_data.parameters);
+ ieee80211_qos_convert_ac_to_parameters(&param_element,
+ qos_param);
+ network->flags |= NETWORK_HAS_QOS_PARAMETERS;
+ network->qos_data.param_count =
+ param_element.info_element.ac_info & 0x0F;
+ }
+ }
+
+ if (rc == 0) {
+ IEEE80211_DEBUG_QOS("QoS is supported\n");
+ network->qos_data.supported = 1;
+ }
+ return rc;
+}
+
+static int ieee80211_parse_info_param(struct ieee80211_info_element
+ *info_element, u16 length,
+ struct ieee80211_network *network)
+{
+ u8 i;
+#ifdef CONFIG_IEEE80211_DEBUG
+ char rates_str[64];
+ char *p;
+#endif
- info_element = &beacon->info_element;
- left = stats->len - ((void *)info_element - (void *)beacon);
- while (left >= sizeof(struct ieee80211_info_element_hdr)) {
- if (sizeof(struct ieee80211_info_element_hdr) +
- info_element->len > left) {
- IEEE80211_DEBUG_SCAN
- ("SCAN: parse failed: info_element->len + 2 > left : info_element->len+2=%Zd left=%d.\n",
- info_element->len +
- sizeof(struct ieee80211_info_element), left);
+ while (length >= sizeof(*info_element)) {
+ if (sizeof(*info_element) + info_element->len > length) {
+ IEEE80211_DEBUG_MGMT("Info elem: parse failed: "
+ "info_element->len + 2 > left : "
+ "info_element->len+2=%zd left=%d, id=%d.\n",
+ info_element->len +
+ sizeof(*info_element),
+ length, info_element->id);
return 1;
}
@@ -837,7 +956,7 @@ static inline int ieee80211_network_init(struct ieee80211_device *ieee,
memset(network->ssid + network->ssid_len, 0,
IW_ESSID_MAX_SIZE - network->ssid_len);
- IEEE80211_DEBUG_SCAN("MFIE_TYPE_SSID: '%s' len=%d.\n",
+ IEEE80211_DEBUG_MGMT("MFIE_TYPE_SSID: '%s' len=%d.\n",
network->ssid, network->ssid_len);
break;
@@ -845,15 +964,14 @@ static inline int ieee80211_network_init(struct ieee80211_device *ieee,
#ifdef CONFIG_IEEE80211_DEBUG
p = rates_str;
#endif
- network->rates_len =
- min(info_element->len, MAX_RATES_LENGTH);
+ network->rates_len = min(info_element->len,
+ MAX_RATES_LENGTH);
for (i = 0; i < network->rates_len; i++) {
network->rates[i] = info_element->data[i];
#ifdef CONFIG_IEEE80211_DEBUG
- p += snprintf(p,
- sizeof(rates_str) - (p -
- rates_str),
- "%02X ", network->rates[i]);
+ p += snprintf(p, sizeof(rates_str) -
+ (p - rates_str), "%02X ",
+ network->rates[i]);
#endif
if (ieee80211_is_ofdm_rate
(info_element->data[i])) {
@@ -865,7 +983,7 @@ static inline int ieee80211_network_init(struct ieee80211_device *ieee,
}
}
- IEEE80211_DEBUG_SCAN("MFIE_TYPE_RATES: '%s' (%d)\n",
+ IEEE80211_DEBUG_MGMT("MFIE_TYPE_RATES: '%s' (%d)\n",
rates_str, network->rates_len);
break;
@@ -873,15 +991,14 @@ static inline int ieee80211_network_init(struct ieee80211_device *ieee,
#ifdef CONFIG_IEEE80211_DEBUG
p = rates_str;
#endif
- network->rates_ex_len =
- min(info_element->len, MAX_RATES_EX_LENGTH);
+ network->rates_ex_len = min(info_element->len,
+ MAX_RATES_EX_LENGTH);
for (i = 0; i < network->rates_ex_len; i++) {
network->rates_ex[i] = info_element->data[i];
#ifdef CONFIG_IEEE80211_DEBUG
- p += snprintf(p,
- sizeof(rates_str) - (p -
- rates_str),
- "%02X ", network->rates[i]);
+ p += snprintf(p, sizeof(rates_str) -
+ (p - rates_str), "%02X ",
+ network->rates[i]);
#endif
if (ieee80211_is_ofdm_rate
(info_element->data[i])) {
@@ -893,40 +1010,51 @@ static inline int ieee80211_network_init(struct ieee80211_device *ieee,
}
}
- IEEE80211_DEBUG_SCAN("MFIE_TYPE_RATES_EX: '%s' (%d)\n",
+ IEEE80211_DEBUG_MGMT("MFIE_TYPE_RATES_EX: '%s' (%d)\n",
rates_str, network->rates_ex_len);
break;
case MFIE_TYPE_DS_SET:
- IEEE80211_DEBUG_SCAN("MFIE_TYPE_DS_SET: %d\n",
+ IEEE80211_DEBUG_MGMT("MFIE_TYPE_DS_SET: %d\n",
info_element->data[0]);
- if (stats->freq == IEEE80211_24GHZ_BAND)
- network->channel = info_element->data[0];
+ network->channel = info_element->data[0];
break;
case MFIE_TYPE_FH_SET:
- IEEE80211_DEBUG_SCAN("MFIE_TYPE_FH_SET: ignored\n");
+ IEEE80211_DEBUG_MGMT("MFIE_TYPE_FH_SET: ignored\n");
break;
case MFIE_TYPE_CF_SET:
- IEEE80211_DEBUG_SCAN("MFIE_TYPE_CF_SET: ignored\n");
+ IEEE80211_DEBUG_MGMT("MFIE_TYPE_CF_SET: ignored\n");
break;
case MFIE_TYPE_TIM:
- IEEE80211_DEBUG_SCAN("MFIE_TYPE_TIM: ignored\n");
+ IEEE80211_DEBUG_MGMT("MFIE_TYPE_TIM: ignored\n");
+ break;
+
+ case MFIE_TYPE_ERP_INFO:
+ network->erp_value = info_element->data[0];
+ IEEE80211_DEBUG_MGMT("MFIE_TYPE_ERP_SET: %d\n",
+ network->erp_value);
break;
case MFIE_TYPE_IBSS_SET:
- IEEE80211_DEBUG_SCAN("MFIE_TYPE_IBSS_SET: ignored\n");
+ network->atim_window = info_element->data[0];
+ IEEE80211_DEBUG_MGMT("MFIE_TYPE_IBSS_SET: %d\n",
+ network->atim_window);
break;
case MFIE_TYPE_CHALLENGE:
- IEEE80211_DEBUG_SCAN("MFIE_TYPE_CHALLENGE: ignored\n");
+ IEEE80211_DEBUG_MGMT("MFIE_TYPE_CHALLENGE: ignored\n");
break;
case MFIE_TYPE_GENERIC:
- IEEE80211_DEBUG_SCAN("MFIE_TYPE_GENERIC: %d bytes\n",
+ IEEE80211_DEBUG_MGMT("MFIE_TYPE_GENERIC: %d bytes\n",
info_element->len);
+ if (!ieee80211_parse_qos_info_param_IE(info_element,
+ network))
+ break;
+
if (info_element->len >= 4 &&
info_element->data[0] == 0x00 &&
info_element->data[1] == 0x50 &&
@@ -940,7 +1068,7 @@ static inline int ieee80211_network_init(struct ieee80211_device *ieee,
break;
case MFIE_TYPE_RSN:
- IEEE80211_DEBUG_SCAN("MFIE_TYPE_RSN: %d bytes\n",
+ IEEE80211_DEBUG_MGMT("MFIE_TYPE_RSN: %d bytes\n",
info_element->len);
network->rsn_ie_len = min(info_element->len + 2,
MAX_WPA_IE_LEN);
@@ -948,18 +1076,127 @@ static inline int ieee80211_network_init(struct ieee80211_device *ieee,
network->rsn_ie_len);
break;
+ case MFIE_TYPE_QOS_PARAMETER:
+ printk(KERN_ERR
+ "QoS Error need to parse QOS_PARAMETER IE\n");
+ break;
+
default:
- IEEE80211_DEBUG_SCAN("unsupported IE %d\n",
+ IEEE80211_DEBUG_MGMT("unsupported IE %d\n",
info_element->id);
break;
}
- left -= sizeof(struct ieee80211_info_element_hdr) +
- info_element->len;
- info_element = (struct ieee80211_info_element *)
- &info_element->data[info_element->len];
+ length -= sizeof(*info_element) + info_element->len;
+ info_element =
+ (struct ieee80211_info_element *)&info_element->
+ data[info_element->len];
+ }
+
+ return 0;
+}
+
+static int ieee80211_handle_assoc_resp(struct ieee80211_device *ieee, struct ieee80211_assoc_response
+ *frame, struct ieee80211_rx_stats *stats)
+{
+ struct ieee80211_network network_resp;
+ struct ieee80211_network *network = &network_resp;
+ struct net_device *dev = ieee->dev;
+
+ network->flags = 0;
+ network->qos_data.active = 0;
+ network->qos_data.supported = 0;
+ network->qos_data.param_count = 0;
+ network->qos_data.old_param_count = 0;
+
+ //network->atim_window = le16_to_cpu(frame->aid) & (0x3FFF);
+ network->atim_window = le16_to_cpu(frame->aid);
+ network->listen_interval = le16_to_cpu(frame->status);
+ memcpy(network->bssid, frame->header.addr3, ETH_ALEN);
+ network->capability = le16_to_cpu(frame->capability);
+ network->last_scanned = jiffies;
+ network->rates_len = network->rates_ex_len = 0;
+ network->last_associate = 0;
+ network->ssid_len = 0;
+ network->erp_value =
+ (network->capability & WLAN_CAPABILITY_IBSS) ? 0x3 : 0x0;
+
+ if (stats->freq == IEEE80211_52GHZ_BAND) {
+ /* for A band (No DS info) */
+ network->channel = stats->received_channel;
+ } else
+ network->flags |= NETWORK_HAS_CCK;
+
+ network->wpa_ie_len = 0;
+ network->rsn_ie_len = 0;
+
+ if (ieee80211_parse_info_param
+ (frame->info_element, stats->len - sizeof(*frame), network))
+ return 1;
+
+ network->mode = 0;
+ if (stats->freq == IEEE80211_52GHZ_BAND)
+ network->mode = IEEE_A;
+ else {
+ if (network->flags & NETWORK_HAS_OFDM)
+ network->mode |= IEEE_G;
+ if (network->flags & NETWORK_HAS_CCK)
+ network->mode |= IEEE_B;
}
+ if (ieee80211_is_empty_essid(network->ssid, network->ssid_len))
+ network->flags |= NETWORK_EMPTY_ESSID;
+
+ memcpy(&network->stats, stats, sizeof(network->stats));
+
+ if (ieee->handle_assoc_response != NULL)
+ ieee->handle_assoc_response(dev, frame, network);
+
+ return 0;
+}
+
+/***************************************************/
+
+static inline int ieee80211_network_init(struct ieee80211_device *ieee, struct ieee80211_probe_response
+ *beacon,
+ struct ieee80211_network *network,
+ struct ieee80211_rx_stats *stats)
+{
+ network->qos_data.active = 0;
+ network->qos_data.supported = 0;
+ network->qos_data.param_count = 0;
+ network->qos_data.old_param_count = 0;
+
+ /* Pull out fixed field data */
+ memcpy(network->bssid, beacon->header.addr3, ETH_ALEN);
+ network->capability = le16_to_cpu(beacon->capability);
+ network->last_scanned = jiffies;
+ network->time_stamp[0] = le32_to_cpu(beacon->time_stamp[0]);
+ network->time_stamp[1] = le32_to_cpu(beacon->time_stamp[1]);
+ network->beacon_interval = le16_to_cpu(beacon->beacon_interval);
+ /* Where to pull this? beacon->listen_interval; */
+ network->listen_interval = 0x0A;
+ network->rates_len = network->rates_ex_len = 0;
+ network->last_associate = 0;
+ network->ssid_len = 0;
+ network->flags = 0;
+ network->atim_window = 0;
+ network->erp_value = (network->capability & WLAN_CAPABILITY_IBSS) ?
+ 0x3 : 0x0;
+
+ if (stats->freq == IEEE80211_52GHZ_BAND) {
+ /* for A band (No DS info) */
+ network->channel = stats->received_channel;
+ } else
+ network->flags |= NETWORK_HAS_CCK;
+
+ network->wpa_ie_len = 0;
+ network->rsn_ie_len = 0;
+
+ if (ieee80211_parse_info_param
+ (beacon->info_element, stats->len - sizeof(*beacon), network))
+ return 1;
+
network->mode = 0;
if (stats->freq == IEEE80211_52GHZ_BAND)
network->mode = IEEE_A;
@@ -1002,6 +1239,9 @@ static inline int is_same_network(struct ieee80211_network *src,
static inline void update_network(struct ieee80211_network *dst,
struct ieee80211_network *src)
{
+ int qos_active;
+ u8 old_param;
+
memcpy(&dst->stats, &src->stats, sizeof(struct ieee80211_rx_stats));
dst->capability = src->capability;
memcpy(dst->rates, src->rates, src->rates_len);
@@ -1017,6 +1257,7 @@ static inline void update_network(struct ieee80211_network *dst,
dst->beacon_interval = src->beacon_interval;
dst->listen_interval = src->listen_interval;
dst->atim_window = src->atim_window;
+ dst->erp_value = src->erp_value;
memcpy(dst->wpa_ie, src->wpa_ie, src->wpa_ie_len);
dst->wpa_ie_len = src->wpa_ie_len;
@@ -1024,22 +1265,48 @@ static inline void update_network(struct ieee80211_network *dst,
dst->rsn_ie_len = src->rsn_ie_len;
dst->last_scanned = jiffies;
+ qos_active = src->qos_data.active;
+ old_param = dst->qos_data.old_param_count;
+ if (dst->flags & NETWORK_HAS_QOS_MASK)
+ memcpy(&dst->qos_data, &src->qos_data,
+ sizeof(struct ieee80211_qos_data));
+ else {
+ dst->qos_data.supported = src->qos_data.supported;
+ dst->qos_data.param_count = src->qos_data.param_count;
+ }
+
+ if (dst->qos_data.supported == 1) {
+ if (dst->ssid_len)
+ IEEE80211_DEBUG_QOS
+ ("QoS the network %s is QoS supported\n",
+ dst->ssid);
+ else
+ IEEE80211_DEBUG_QOS
+ ("QoS the network is QoS supported\n");
+ }
+ dst->qos_data.active = qos_active;
+ dst->qos_data.old_param_count = old_param;
+
/* dst->last_associate is not overwritten */
}
+static inline int is_beacon(int fc)
+{
+ return (WLAN_FC_GET_STYPE(le16_to_cpu(fc)) == IEEE80211_STYPE_BEACON);
+}
+
static inline void ieee80211_process_probe_response(struct ieee80211_device
- *ieee,
- struct
+ *ieee, struct
ieee80211_probe_response
- *beacon,
- struct ieee80211_rx_stats
+ *beacon, struct ieee80211_rx_stats
*stats)
{
+ struct net_device *dev = ieee->dev;
struct ieee80211_network network;
struct ieee80211_network *target;
struct ieee80211_network *oldest = NULL;
#ifdef CONFIG_IEEE80211_DEBUG
- struct ieee80211_info_element *info_element = &beacon->info_element;
+ struct ieee80211_info_element *info_element = beacon->info_element;
#endif
unsigned long flags;
@@ -1070,10 +1337,10 @@ static inline void ieee80211_process_probe_response(struct ieee80211_device
escape_essid(info_element->data,
info_element->len),
MAC_ARG(beacon->header.addr3),
- WLAN_FC_GET_STYPE(beacon->header.
- frame_ctl) ==
- IEEE80211_STYPE_PROBE_RESP ?
- "PROBE RESPONSE" : "BEACON");
+ is_beacon(le16_to_cpu
+ (beacon->header.
+ frame_ctl)) ?
+ "BEACON" : "PROBE RESPONSE");
return;
}
@@ -1122,10 +1389,10 @@ static inline void ieee80211_process_probe_response(struct ieee80211_device
escape_essid(network.ssid,
network.ssid_len),
MAC_ARG(network.bssid),
- WLAN_FC_GET_STYPE(beacon->header.
- frame_ctl) ==
- IEEE80211_STYPE_PROBE_RESP ?
- "PROBE RESPONSE" : "BEACON");
+ is_beacon(le16_to_cpu
+ (beacon->header.
+ frame_ctl)) ?
+ "BEACON" : "PROBE RESPONSE");
#endif
memcpy(target, &network, sizeof(*target));
list_add_tail(&target->list, &ieee->network_list);
@@ -1134,34 +1401,60 @@ static inline void ieee80211_process_probe_response(struct ieee80211_device
escape_essid(target->ssid,
target->ssid_len),
MAC_ARG(target->bssid),
- WLAN_FC_GET_STYPE(beacon->header.
- frame_ctl) ==
- IEEE80211_STYPE_PROBE_RESP ?
- "PROBE RESPONSE" : "BEACON");
+ is_beacon(le16_to_cpu
+ (beacon->header.
+ frame_ctl)) ?
+ "BEACON" : "PROBE RESPONSE");
update_network(target, &network);
}
spin_unlock_irqrestore(&ieee->lock, flags);
+
+ if (is_beacon(le16_to_cpu(beacon->header.frame_ctl))) {
+ if (ieee->handle_beacon != NULL)
+ ieee->handle_beacon(dev, beacon, &network);
+ } else {
+ if (ieee->handle_probe_response != NULL)
+ ieee->handle_probe_response(dev, beacon, &network);
+ }
}
void ieee80211_rx_mgt(struct ieee80211_device *ieee,
- struct ieee80211_hdr *header,
+ struct ieee80211_hdr_4addr *header,
struct ieee80211_rx_stats *stats)
{
- switch (WLAN_FC_GET_STYPE(header->frame_ctl)) {
+ switch (WLAN_FC_GET_STYPE(le16_to_cpu(header->frame_ctl))) {
case IEEE80211_STYPE_ASSOC_RESP:
IEEE80211_DEBUG_MGMT("received ASSOCIATION RESPONSE (%d)\n",
- WLAN_FC_GET_STYPE(header->frame_ctl));
+ WLAN_FC_GET_STYPE(le16_to_cpu
+ (header->frame_ctl)));
+ ieee80211_handle_assoc_resp(ieee,
+ (struct ieee80211_assoc_response *)
+ header, stats);
break;
case IEEE80211_STYPE_REASSOC_RESP:
IEEE80211_DEBUG_MGMT("received REASSOCIATION RESPONSE (%d)\n",
- WLAN_FC_GET_STYPE(header->frame_ctl));
+ WLAN_FC_GET_STYPE(le16_to_cpu
+ (header->frame_ctl)));
+ break;
+
+ case IEEE80211_STYPE_PROBE_REQ:
+ IEEE80211_DEBUG_MGMT("recieved auth (%d)\n",
+ WLAN_FC_GET_STYPE(le16_to_cpu
+ (header->frame_ctl)));
+
+ if (ieee->handle_probe_request != NULL)
+ ieee->handle_probe_request(ieee->dev,
+ (struct
+ ieee80211_probe_request *)
+ header, stats);
break;
case IEEE80211_STYPE_PROBE_RESP:
IEEE80211_DEBUG_MGMT("received PROBE RESPONSE (%d)\n",
- WLAN_FC_GET_STYPE(header->frame_ctl));
+ WLAN_FC_GET_STYPE(le16_to_cpu
+ (header->frame_ctl)));
IEEE80211_DEBUG_SCAN("Probe response\n");
ieee80211_process_probe_response(ieee,
(struct
@@ -1171,20 +1464,46 @@ void ieee80211_rx_mgt(struct ieee80211_device *ieee,
case IEEE80211_STYPE_BEACON:
IEEE80211_DEBUG_MGMT("received BEACON (%d)\n",
- WLAN_FC_GET_STYPE(header->frame_ctl));
+ WLAN_FC_GET_STYPE(le16_to_cpu
+ (header->frame_ctl)));
IEEE80211_DEBUG_SCAN("Beacon\n");
ieee80211_process_probe_response(ieee,
(struct
ieee80211_probe_response *)
header, stats);
break;
+ case IEEE80211_STYPE_AUTH:
+ IEEE80211_DEBUG_MGMT("recieved auth (%d)\n",
+ WLAN_FC_GET_STYPE(le16_to_cpu
+ (header->frame_ctl)));
+
+ if (ieee->handle_auth != NULL)
+ ieee->handle_auth(ieee->dev,
+ (struct ieee80211_auth *)header);
+ break;
+
+ case IEEE80211_STYPE_DISASSOC:
+ if (ieee->handle_disassoc != NULL)
+ ieee->handle_disassoc(ieee->dev,
+ (struct ieee80211_disassoc *)
+ header);
+ break;
+
+ case IEEE80211_STYPE_DEAUTH:
+ printk("DEAUTH from AP\n");
+ if (ieee->handle_deauth != NULL)
+ ieee->handle_deauth(ieee->dev, (struct ieee80211_auth *)
+ header);
+ break;
default:
IEEE80211_DEBUG_MGMT("received UNKNOWN (%d)\n",
- WLAN_FC_GET_STYPE(header->frame_ctl));
+ WLAN_FC_GET_STYPE(le16_to_cpu
+ (header->frame_ctl)));
IEEE80211_WARNING("%s: Unknown management packet: %d\n",
ieee->dev->name,
- WLAN_FC_GET_STYPE(header->frame_ctl));
+ WLAN_FC_GET_STYPE(le16_to_cpu
+ (header->frame_ctl)));
break;
}
}
diff --git a/net/ieee80211/ieee80211_tx.c b/net/ieee80211/ieee80211_tx.c
index eed07bbbe6b6..445f206e65e0 100644
--- a/net/ieee80211/ieee80211_tx.c
+++ b/net/ieee80211/ieee80211_tx.c
@@ -1,6 +1,6 @@
/******************************************************************************
- Copyright(c) 2003 - 2004 Intel Corporation. All rights reserved.
+ Copyright(c) 2003 - 2005 Intel Corporation. All rights reserved.
This program is free software; you can redistribute it and/or modify it
under the terms of version 2 of the GNU General Public License as
@@ -38,7 +38,6 @@
#include <linux/slab.h>
#include <linux/tcp.h>
#include <linux/types.h>
-#include <linux/version.h>
#include <linux/wireless.h>
#include <linux/etherdevice.h>
#include <asm/uaccess.h>
@@ -128,7 +127,7 @@ payload of each frame is reduced to 492 bytes.
static u8 P802_1H_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0xf8 };
static u8 RFC1042_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0x00 };
-static inline int ieee80211_put_snap(u8 * data, u16 h_proto)
+static inline int ieee80211_copy_snap(u8 * data, u16 h_proto)
{
struct ieee80211_snap_hdr *snap;
u8 *oui;
@@ -157,31 +156,14 @@ static inline int ieee80211_encrypt_fragment(struct ieee80211_device *ieee,
struct ieee80211_crypt_data *crypt = ieee->crypt[ieee->tx_keyidx];
int res;
-#ifdef CONFIG_IEEE80211_CRYPT_TKIP
- struct ieee80211_hdr *header;
-
- if (ieee->tkip_countermeasures &&
- crypt && crypt->ops && strcmp(crypt->ops->name, "TKIP") == 0) {
- header = (struct ieee80211_hdr *)frag->data;
- if (net_ratelimit()) {
- printk(KERN_DEBUG "%s: TKIP countermeasures: dropped "
- "TX packet to " MAC_FMT "\n",
- ieee->dev->name, MAC_ARG(header->addr1));
- }
+ if (crypt == NULL)
return -1;
- }
-#endif
+
/* To encrypt, frame format is:
* IV (4 bytes), clear payload (including SNAP), ICV (4 bytes) */
-
- // PR: FIXME: Copied from hostap. Check fragmentation/MSDU/MPDU encryption.
- /* Host-based IEEE 802.11 fragmentation for TX is not yet supported, so
- * call both MSDU and MPDU encryption functions from here. */
atomic_inc(&crypt->refcnt);
res = 0;
- if (crypt->ops->encrypt_msdu)
- res = crypt->ops->encrypt_msdu(frag, hdr_len, crypt->priv);
- if (res == 0 && crypt->ops->encrypt_mpdu)
+ if (crypt->ops && crypt->ops->encrypt_mpdu)
res = crypt->ops->encrypt_mpdu(frag, hdr_len, crypt->priv);
atomic_dec(&crypt->refcnt);
@@ -207,7 +189,7 @@ void ieee80211_txb_free(struct ieee80211_txb *txb)
}
static struct ieee80211_txb *ieee80211_alloc_txb(int nr_frags, int txb_size,
- gfp_t gfp_mask)
+ int headroom, gfp_t gfp_mask)
{
struct ieee80211_txb *txb;
int i;
@@ -221,11 +203,13 @@ static struct ieee80211_txb *ieee80211_alloc_txb(int nr_frags, int txb_size,
txb->frag_size = txb_size;
for (i = 0; i < nr_frags; i++) {
- txb->fragments[i] = dev_alloc_skb(txb_size);
+ txb->fragments[i] = __dev_alloc_skb(txb_size + headroom,
+ gfp_mask);
if (unlikely(!txb->fragments[i])) {
i--;
break;
}
+ skb_reserve(txb->fragments[i], headroom);
}
if (unlikely(i != nr_frags)) {
while (i >= 0)
@@ -236,25 +220,31 @@ static struct ieee80211_txb *ieee80211_alloc_txb(int nr_frags, int txb_size,
return txb;
}
-/* SKBs are added to the ieee->tx_queue. */
+/* Incoming skb is converted to a txb which consists of
+ * a block of 802.11 fragment packets (stored as skbs) */
int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct ieee80211_device *ieee = netdev_priv(dev);
struct ieee80211_txb *txb = NULL;
- struct ieee80211_hdr *frag_hdr;
- int i, bytes_per_frag, nr_frags, bytes_last_frag, frag_size;
+ struct ieee80211_hdr_3addr *frag_hdr;
+ int i, bytes_per_frag, nr_frags, bytes_last_frag, frag_size,
+ rts_required;
unsigned long flags;
struct net_device_stats *stats = &ieee->stats;
- int ether_type, encrypt;
+ int ether_type, encrypt, host_encrypt, host_encrypt_msdu, host_build_iv;
int bytes, fc, hdr_len;
struct sk_buff *skb_frag;
- struct ieee80211_hdr header = { /* Ensure zero initialized */
+ struct ieee80211_hdr_3addr header = { /* Ensure zero initialized */
.duration_id = 0,
.seq_ctl = 0
};
u8 dest[ETH_ALEN], src[ETH_ALEN];
-
struct ieee80211_crypt_data *crypt;
+ int priority = skb->priority;
+ int snapped = 0;
+
+ if (ieee->is_queue_full && (*ieee->is_queue_full) (dev, priority))
+ return NETDEV_TX_BUSY;
spin_lock_irqsave(&ieee->lock, flags);
@@ -276,7 +266,11 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
crypt = ieee->crypt[ieee->tx_keyidx];
encrypt = !(ether_type == ETH_P_PAE && ieee->ieee802_1x) &&
- ieee->host_encrypt && crypt && crypt->ops;
+ ieee->sec.encrypt;
+
+ host_encrypt = ieee->host_encrypt && encrypt && crypt;
+ host_encrypt_msdu = ieee->host_encrypt_msdu && encrypt && crypt;
+ host_build_iv = ieee->host_build_iv && encrypt && crypt;
if (!encrypt && ieee->ieee802_1x &&
ieee->drop_unencrypted && ether_type != ETH_P_PAE) {
@@ -285,8 +279,8 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
}
/* Save source and destination addresses */
- memcpy(&dest, skb->data, ETH_ALEN);
- memcpy(&src, skb->data + ETH_ALEN, ETH_ALEN);
+ memcpy(dest, skb->data, ETH_ALEN);
+ memcpy(src, skb->data + ETH_ALEN, ETH_ALEN);
/* Advance the SKB to the start of the payload */
skb_pull(skb, sizeof(struct ethhdr));
@@ -294,7 +288,7 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
/* Determine total amount of storage required for TXB packets */
bytes = skb->len + SNAP_SIZE + sizeof(u16);
- if (encrypt)
+ if (host_encrypt)
fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA |
IEEE80211_FCTL_PROTECTED;
else
@@ -302,70 +296,144 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
if (ieee->iw_mode == IW_MODE_INFRA) {
fc |= IEEE80211_FCTL_TODS;
- /* To DS: Addr1 = BSSID, Addr2 = SA,
- Addr3 = DA */
- memcpy(&header.addr1, ieee->bssid, ETH_ALEN);
- memcpy(&header.addr2, &src, ETH_ALEN);
- memcpy(&header.addr3, &dest, ETH_ALEN);
+ /* To DS: Addr1 = BSSID, Addr2 = SA, Addr3 = DA */
+ memcpy(header.addr1, ieee->bssid, ETH_ALEN);
+ memcpy(header.addr2, src, ETH_ALEN);
+ memcpy(header.addr3, dest, ETH_ALEN);
} else if (ieee->iw_mode == IW_MODE_ADHOC) {
- /* not From/To DS: Addr1 = DA, Addr2 = SA,
- Addr3 = BSSID */
- memcpy(&header.addr1, dest, ETH_ALEN);
- memcpy(&header.addr2, src, ETH_ALEN);
- memcpy(&header.addr3, ieee->bssid, ETH_ALEN);
+ /* not From/To DS: Addr1 = DA, Addr2 = SA, Addr3 = BSSID */
+ memcpy(header.addr1, dest, ETH_ALEN);
+ memcpy(header.addr2, src, ETH_ALEN);
+ memcpy(header.addr3, ieee->bssid, ETH_ALEN);
}
header.frame_ctl = cpu_to_le16(fc);
hdr_len = IEEE80211_3ADDR_LEN;
- /* Determine fragmentation size based on destination (multicast
- * and broadcast are not fragmented) */
- if (is_multicast_ether_addr(dest) || is_broadcast_ether_addr(dest))
- frag_size = MAX_FRAG_THRESHOLD;
- else
- frag_size = ieee->fts;
+ /* Encrypt msdu first on the whole data packet. */
+ if ((host_encrypt || host_encrypt_msdu) &&
+ crypt && crypt->ops && crypt->ops->encrypt_msdu) {
+ int res = 0;
+ int len = bytes + hdr_len + crypt->ops->extra_msdu_prefix_len +
+ crypt->ops->extra_msdu_postfix_len;
+ struct sk_buff *skb_new = dev_alloc_skb(len);
+
+ if (unlikely(!skb_new))
+ goto failed;
+
+ skb_reserve(skb_new, crypt->ops->extra_msdu_prefix_len);
+ memcpy(skb_put(skb_new, hdr_len), &header, hdr_len);
+ snapped = 1;
+ ieee80211_copy_snap(skb_put(skb_new, SNAP_SIZE + sizeof(u16)),
+ ether_type);
+ memcpy(skb_put(skb_new, skb->len), skb->data, skb->len);
+ res = crypt->ops->encrypt_msdu(skb_new, hdr_len, crypt->priv);
+ if (res < 0) {
+ IEEE80211_ERROR("msdu encryption failed\n");
+ dev_kfree_skb_any(skb_new);
+ goto failed;
+ }
+ dev_kfree_skb_any(skb);
+ skb = skb_new;
+ bytes += crypt->ops->extra_msdu_prefix_len +
+ crypt->ops->extra_msdu_postfix_len;
+ skb_pull(skb, hdr_len);
+ }
- /* Determine amount of payload per fragment. Regardless of if
- * this stack is providing the full 802.11 header, one will
- * eventually be affixed to this fragment -- so we must account for
- * it when determining the amount of payload space. */
- bytes_per_frag = frag_size - IEEE80211_3ADDR_LEN;
- if (ieee->config &
- (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
- bytes_per_frag -= IEEE80211_FCS_LEN;
-
- /* Each fragment may need to have room for encryptiong pre/postfix */
- if (encrypt)
- bytes_per_frag -= crypt->ops->extra_prefix_len +
- crypt->ops->extra_postfix_len;
-
- /* Number of fragments is the total bytes_per_frag /
- * payload_per_fragment */
- nr_frags = bytes / bytes_per_frag;
- bytes_last_frag = bytes % bytes_per_frag;
- if (bytes_last_frag)
+ if (host_encrypt || ieee->host_open_frag) {
+ /* Determine fragmentation size based on destination (multicast
+ * and broadcast are not fragmented) */
+ if (is_multicast_ether_addr(dest) ||
+ is_broadcast_ether_addr(dest))
+ frag_size = MAX_FRAG_THRESHOLD;
+ else
+ frag_size = ieee->fts;
+
+ /* Determine amount of payload per fragment. Regardless of if
+ * this stack is providing the full 802.11 header, one will
+ * eventually be affixed to this fragment -- so we must account
+ * for it when determining the amount of payload space. */
+ bytes_per_frag = frag_size - IEEE80211_3ADDR_LEN;
+ if (ieee->config &
+ (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
+ bytes_per_frag -= IEEE80211_FCS_LEN;
+
+ /* Each fragment may need to have room for encryptiong
+ * pre/postfix */
+ if (host_encrypt)
+ bytes_per_frag -= crypt->ops->extra_mpdu_prefix_len +
+ crypt->ops->extra_mpdu_postfix_len;
+
+ /* Number of fragments is the total
+ * bytes_per_frag / payload_per_fragment */
+ nr_frags = bytes / bytes_per_frag;
+ bytes_last_frag = bytes % bytes_per_frag;
+ if (bytes_last_frag)
+ nr_frags++;
+ else
+ bytes_last_frag = bytes_per_frag;
+ } else {
+ nr_frags = 1;
+ bytes_per_frag = bytes_last_frag = bytes;
+ frag_size = bytes + IEEE80211_3ADDR_LEN;
+ }
+
+ rts_required = (frag_size > ieee->rts
+ && ieee->config & CFG_IEEE80211_RTS);
+ if (rts_required)
nr_frags++;
- else
- bytes_last_frag = bytes_per_frag;
/* When we allocate the TXB we allocate enough space for the reserve
* and full fragment bytes (bytes_per_frag doesn't include prefix,
* postfix, header, FCS, etc.) */
- txb = ieee80211_alloc_txb(nr_frags, frag_size, GFP_ATOMIC);
+ txb = ieee80211_alloc_txb(nr_frags, frag_size,
+ ieee->tx_headroom, GFP_ATOMIC);
if (unlikely(!txb)) {
printk(KERN_WARNING "%s: Could not allocate TXB\n",
ieee->dev->name);
goto failed;
}
txb->encrypted = encrypt;
- txb->payload_size = bytes;
+ if (host_encrypt)
+ txb->payload_size = frag_size * (nr_frags - 1) +
+ bytes_last_frag;
+ else
+ txb->payload_size = bytes;
+
+ if (rts_required) {
+ skb_frag = txb->fragments[0];
+ frag_hdr =
+ (struct ieee80211_hdr_3addr *)skb_put(skb_frag, hdr_len);
+
+ /*
+ * Set header frame_ctl to the RTS.
+ */
+ header.frame_ctl =
+ cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_RTS);
+ memcpy(frag_hdr, &header, hdr_len);
- for (i = 0; i < nr_frags; i++) {
+ /*
+ * Restore header frame_ctl to the original data setting.
+ */
+ header.frame_ctl = cpu_to_le16(fc);
+
+ if (ieee->config &
+ (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
+ skb_put(skb_frag, 4);
+
+ txb->rts_included = 1;
+ i = 1;
+ } else
+ i = 0;
+
+ for (; i < nr_frags; i++) {
skb_frag = txb->fragments[i];
- if (encrypt)
- skb_reserve(skb_frag, crypt->ops->extra_prefix_len);
+ if (host_encrypt || host_build_iv)
+ skb_reserve(skb_frag,
+ crypt->ops->extra_mpdu_prefix_len);
- frag_hdr = (struct ieee80211_hdr *)skb_put(skb_frag, hdr_len);
+ frag_hdr =
+ (struct ieee80211_hdr_3addr *)skb_put(skb_frag, hdr_len);
memcpy(frag_hdr, &header, hdr_len);
/* If this is not the last fragment, then add the MOREFRAGS
@@ -379,11 +447,10 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
bytes = bytes_last_frag;
}
- /* Put a SNAP header on the first fragment */
- if (i == 0) {
- ieee80211_put_snap(skb_put
- (skb_frag, SNAP_SIZE + sizeof(u16)),
- ether_type);
+ if (i == 0 && !snapped) {
+ ieee80211_copy_snap(skb_put
+ (skb_frag, SNAP_SIZE + sizeof(u16)),
+ ether_type);
bytes -= SNAP_SIZE + sizeof(u16);
}
@@ -394,8 +461,19 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
/* Encryption routine will move the header forward in order
* to insert the IV between the header and the payload */
- if (encrypt)
+ if (host_encrypt)
ieee80211_encrypt_fragment(ieee, skb_frag, hdr_len);
+ else if (host_build_iv) {
+ struct ieee80211_crypt_data *crypt;
+
+ crypt = ieee->crypt[ieee->tx_keyidx];
+ atomic_inc(&crypt->refcnt);
+ if (crypt->ops->build_iv)
+ crypt->ops->build_iv(skb_frag, hdr_len,
+ crypt->priv);
+ atomic_dec(&crypt->refcnt);
+ }
+
if (ieee->config &
(CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
skb_put(skb_frag, 4);
@@ -407,11 +485,20 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
dev_kfree_skb_any(skb);
if (txb) {
- if ((*ieee->hard_start_xmit) (txb, dev) == 0) {
+ int ret = (*ieee->hard_start_xmit) (txb, dev, priority);
+ if (ret == 0) {
stats->tx_packets++;
stats->tx_bytes += txb->payload_size;
return 0;
}
+
+ if (ret == NETDEV_TX_BUSY) {
+ printk(KERN_ERR "%s: NETDEV_TX_BUSY returned; "
+ "driver should report queue full via "
+ "ieee_device->is_queue_full.\n",
+ ieee->dev->name);
+ }
+
ieee80211_txb_free(txb);
}
@@ -422,7 +509,72 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
netif_stop_queue(dev);
stats->tx_errors++;
return 1;
+}
+
+/* Incoming 802.11 strucure is converted to a TXB
+ * a block of 802.11 fragment packets (stored as skbs) */
+int ieee80211_tx_frame(struct ieee80211_device *ieee,
+ struct ieee80211_hdr *frame, int len)
+{
+ struct ieee80211_txb *txb = NULL;
+ unsigned long flags;
+ struct net_device_stats *stats = &ieee->stats;
+ struct sk_buff *skb_frag;
+ int priority = -1;
+
+ spin_lock_irqsave(&ieee->lock, flags);
+ /* If there is no driver handler to take the TXB, dont' bother
+ * creating it... */
+ if (!ieee->hard_start_xmit) {
+ printk(KERN_WARNING "%s: No xmit handler.\n", ieee->dev->name);
+ goto success;
+ }
+
+ if (unlikely(len < 24)) {
+ printk(KERN_WARNING "%s: skb too small (%d).\n",
+ ieee->dev->name, len);
+ goto success;
+ }
+
+ /* When we allocate the TXB we allocate enough space for the reserve
+ * and full fragment bytes (bytes_per_frag doesn't include prefix,
+ * postfix, header, FCS, etc.) */
+ txb = ieee80211_alloc_txb(1, len, ieee->tx_headroom, GFP_ATOMIC);
+ if (unlikely(!txb)) {
+ printk(KERN_WARNING "%s: Could not allocate TXB\n",
+ ieee->dev->name);
+ goto failed;
+ }
+ txb->encrypted = 0;
+ txb->payload_size = len;
+
+ skb_frag = txb->fragments[0];
+
+ memcpy(skb_put(skb_frag, len), frame, len);
+
+ if (ieee->config &
+ (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
+ skb_put(skb_frag, 4);
+
+ success:
+ spin_unlock_irqrestore(&ieee->lock, flags);
+
+ if (txb) {
+ if ((*ieee->hard_start_xmit) (txb, ieee->dev, priority) == 0) {
+ stats->tx_packets++;
+ stats->tx_bytes += txb->payload_size;
+ return 0;
+ }
+ ieee80211_txb_free(txb);
+ }
+ return 0;
+
+ failed:
+ spin_unlock_irqrestore(&ieee->lock, flags);
+ stats->tx_errors++;
+ return 1;
}
+EXPORT_SYMBOL(ieee80211_tx_frame);
EXPORT_SYMBOL(ieee80211_txb_free);
diff --git a/net/ieee80211/ieee80211_wx.c b/net/ieee80211/ieee80211_wx.c
index 94882f39b072..181755f2aa8b 100644
--- a/net/ieee80211/ieee80211_wx.c
+++ b/net/ieee80211/ieee80211_wx.c
@@ -1,6 +1,6 @@
/******************************************************************************
- Copyright(c) 2004 Intel Corporation. All rights reserved.
+ Copyright(c) 2004-2005 Intel Corporation. All rights reserved.
Portions of this file are based on the WEP enablement code provided by the
Host AP project hostap-drivers v0.1.3
@@ -32,6 +32,7 @@
#include <linux/kmod.h>
#include <linux/module.h>
+#include <linux/jiffies.h>
#include <net/ieee80211.h>
#include <linux/wireless.h>
@@ -140,18 +141,43 @@ static inline char *ipw2100_translate_scan(struct ieee80211_device *ieee,
start = iwe_stream_add_point(start, stop, &iwe, custom);
/* Add quality statistics */
- /* TODO: Fix these values... */
iwe.cmd = IWEVQUAL;
- iwe.u.qual.qual = network->stats.signal;
- iwe.u.qual.level = network->stats.rssi;
- iwe.u.qual.noise = network->stats.noise;
- iwe.u.qual.updated = network->stats.mask & IEEE80211_STATMASK_WEMASK;
- if (!(network->stats.mask & IEEE80211_STATMASK_RSSI))
- iwe.u.qual.updated |= IW_QUAL_LEVEL_INVALID;
- if (!(network->stats.mask & IEEE80211_STATMASK_NOISE))
+ iwe.u.qual.updated = IW_QUAL_QUAL_UPDATED | IW_QUAL_LEVEL_UPDATED |
+ IW_QUAL_NOISE_UPDATED;
+
+ if (!(network->stats.mask & IEEE80211_STATMASK_RSSI)) {
+ iwe.u.qual.updated |= IW_QUAL_QUAL_INVALID |
+ IW_QUAL_LEVEL_INVALID;
+ iwe.u.qual.qual = 0;
+ iwe.u.qual.level = 0;
+ } else {
+ iwe.u.qual.level = network->stats.rssi;
+ if (ieee->perfect_rssi == ieee->worst_rssi)
+ iwe.u.qual.qual = 100;
+ else
+ iwe.u.qual.qual =
+ (100 *
+ (ieee->perfect_rssi - ieee->worst_rssi) *
+ (ieee->perfect_rssi - ieee->worst_rssi) -
+ (ieee->perfect_rssi - network->stats.rssi) *
+ (15 * (ieee->perfect_rssi - ieee->worst_rssi) +
+ 62 * (ieee->perfect_rssi -
+ network->stats.rssi))) /
+ ((ieee->perfect_rssi -
+ ieee->worst_rssi) * (ieee->perfect_rssi -
+ ieee->worst_rssi));
+ if (iwe.u.qual.qual > 100)
+ iwe.u.qual.qual = 100;
+ else if (iwe.u.qual.qual < 1)
+ iwe.u.qual.qual = 0;
+ }
+
+ if (!(network->stats.mask & IEEE80211_STATMASK_NOISE)) {
iwe.u.qual.updated |= IW_QUAL_NOISE_INVALID;
- if (!(network->stats.mask & IEEE80211_STATMASK_SIGNAL))
- iwe.u.qual.updated |= IW_QUAL_QUAL_INVALID;
+ iwe.u.qual.noise = 0;
+ } else {
+ iwe.u.qual.noise = network->stats.noise;
+ }
start = iwe_stream_add_event(start, stop, &iwe, IW_EV_QUAL_LEN);
@@ -162,7 +188,7 @@ static inline char *ipw2100_translate_scan(struct ieee80211_device *ieee,
if (iwe.u.data.length)
start = iwe_stream_add_point(start, stop, &iwe, custom);
- if (ieee->wpa_enabled && network->wpa_ie_len) {
+ if (network->wpa_ie_len) {
char buf[MAX_WPA_IE_LEN * 2 + 30];
u8 *p = buf;
@@ -177,7 +203,7 @@ static inline char *ipw2100_translate_scan(struct ieee80211_device *ieee,
start = iwe_stream_add_point(start, stop, &iwe, buf);
}
- if (ieee->wpa_enabled && network->rsn_ie_len) {
+ if (network->rsn_ie_len) {
char buf[MAX_WPA_IE_LEN * 2 + 30];
u8 *p = buf;
@@ -197,8 +223,8 @@ static inline char *ipw2100_translate_scan(struct ieee80211_device *ieee,
iwe.cmd = IWEVCUSTOM;
p = custom;
p += snprintf(p, MAX_CUSTOM_LEN - (p - custom),
- " Last beacon: %lums ago",
- (jiffies - network->last_scanned) / (HZ / 100));
+ " Last beacon: %dms ago",
+ jiffies_to_msecs(jiffies - network->last_scanned));
iwe.u.data.length = p - custom;
if (iwe.u.data.length)
start = iwe_stream_add_point(start, stop, &iwe, custom);
@@ -228,13 +254,13 @@ int ieee80211_wx_get_scan(struct ieee80211_device *ieee,
ev = ipw2100_translate_scan(ieee, ev, stop, network);
else
IEEE80211_DEBUG_SCAN("Not showing network '%s ("
- MAC_FMT ")' due to age (%lums).\n",
+ MAC_FMT ")' due to age (%dms).\n",
escape_essid(network->ssid,
network->ssid_len),
MAC_ARG(network->bssid),
- (jiffies -
- network->last_scanned) / (HZ /
- 100));
+ jiffies_to_msecs(jiffies -
+ network->
+ last_scanned));
}
spin_unlock_irqrestore(&ieee->lock, flags);
@@ -258,6 +284,7 @@ int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
};
int i, key, key_provided, len;
struct ieee80211_crypt_data **crypt;
+ int host_crypto = ieee->host_encrypt || ieee->host_decrypt;
IEEE80211_DEBUG_WX("SET_ENCODE\n");
@@ -298,15 +325,17 @@ int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
if (i == WEP_KEYS) {
sec.enabled = 0;
+ sec.encrypt = 0;
sec.level = SEC_LEVEL_0;
- sec.flags |= SEC_ENABLED | SEC_LEVEL;
+ sec.flags |= SEC_ENABLED | SEC_LEVEL | SEC_ENCRYPT;
}
goto done;
}
sec.enabled = 1;
- sec.flags |= SEC_ENABLED;
+ sec.encrypt = 1;
+ sec.flags |= SEC_ENABLED | SEC_ENCRYPT;
if (*crypt != NULL && (*crypt)->ops != NULL &&
strcmp((*crypt)->ops->name, "WEP") != 0) {
@@ -315,7 +344,7 @@ int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
ieee80211_crypt_delayed_deinit(ieee, crypt);
}
- if (*crypt == NULL) {
+ if (*crypt == NULL && host_crypto) {
struct ieee80211_crypt_data *new_crypt;
/* take WEP into use */
@@ -355,49 +384,56 @@ int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
key, escape_essid(sec.keys[key], len),
erq->length, len);
sec.key_sizes[key] = len;
- (*crypt)->ops->set_key(sec.keys[key], len, NULL,
- (*crypt)->priv);
+ if (*crypt)
+ (*crypt)->ops->set_key(sec.keys[key], len, NULL,
+ (*crypt)->priv);
sec.flags |= (1 << key);
/* This ensures a key will be activated if no key is
* explicitely set */
if (key == sec.active_key)
sec.flags |= SEC_ACTIVE_KEY;
+
} else {
- len = (*crypt)->ops->get_key(sec.keys[key], WEP_KEY_LEN,
- NULL, (*crypt)->priv);
- if (len == 0) {
- /* Set a default key of all 0 */
- IEEE80211_DEBUG_WX("Setting key %d to all zero.\n",
- key);
- memset(sec.keys[key], 0, 13);
- (*crypt)->ops->set_key(sec.keys[key], 13, NULL,
- (*crypt)->priv);
- sec.key_sizes[key] = 13;
- sec.flags |= (1 << key);
+ if (host_crypto) {
+ len = (*crypt)->ops->get_key(sec.keys[key], WEP_KEY_LEN,
+ NULL, (*crypt)->priv);
+ if (len == 0) {
+ /* Set a default key of all 0 */
+ IEEE80211_DEBUG_WX("Setting key %d to all "
+ "zero.\n", key);
+ memset(sec.keys[key], 0, 13);
+ (*crypt)->ops->set_key(sec.keys[key], 13, NULL,
+ (*crypt)->priv);
+ sec.key_sizes[key] = 13;
+ sec.flags |= (1 << key);
+ }
}
-
/* No key data - just set the default TX key index */
if (key_provided) {
- IEEE80211_DEBUG_WX
- ("Setting key %d to default Tx key.\n", key);
+ IEEE80211_DEBUG_WX("Setting key %d to default Tx "
+ "key.\n", key);
ieee->tx_keyidx = key;
sec.active_key = key;
sec.flags |= SEC_ACTIVE_KEY;
}
}
-
- done:
- ieee->open_wep = !(erq->flags & IW_ENCODE_RESTRICTED);
- sec.auth_mode = ieee->open_wep ? WLAN_AUTH_OPEN : WLAN_AUTH_SHARED_KEY;
- sec.flags |= SEC_AUTH_MODE;
- IEEE80211_DEBUG_WX("Auth: %s\n", sec.auth_mode == WLAN_AUTH_OPEN ?
- "OPEN" : "SHARED KEY");
+ if (erq->flags & (IW_ENCODE_OPEN | IW_ENCODE_RESTRICTED)) {
+ ieee->open_wep = !(erq->flags & IW_ENCODE_RESTRICTED);
+ sec.auth_mode = ieee->open_wep ? WLAN_AUTH_OPEN :
+ WLAN_AUTH_SHARED_KEY;
+ sec.flags |= SEC_AUTH_MODE;
+ IEEE80211_DEBUG_WX("Auth: %s\n",
+ sec.auth_mode == WLAN_AUTH_OPEN ?
+ "OPEN" : "SHARED KEY");
+ }
/* For now we just support WEP, so only set that security level...
* TODO: When WPA is added this is one place that needs to change */
sec.flags |= SEC_LEVEL;
sec.level = SEC_LEVEL_1; /* 40 and 104 bit WEP */
+ sec.encode_alg[key] = SEC_ALG_WEP;
+ done:
if (ieee->set_security)
ieee->set_security(dev, &sec);
@@ -422,6 +458,7 @@ int ieee80211_wx_get_encode(struct ieee80211_device *ieee,
struct iw_point *erq = &(wrqu->encoding);
int len, key;
struct ieee80211_crypt_data *crypt;
+ struct ieee80211_security *sec = &ieee->sec;
IEEE80211_DEBUG_WX("GET_ENCODE\n");
@@ -436,23 +473,16 @@ int ieee80211_wx_get_encode(struct ieee80211_device *ieee,
crypt = ieee->crypt[key];
erq->flags = key + 1;
- if (crypt == NULL || crypt->ops == NULL) {
+ if (!sec->enabled) {
erq->length = 0;
erq->flags |= IW_ENCODE_DISABLED;
return 0;
}
- if (strcmp(crypt->ops->name, "WEP") != 0) {
- /* only WEP is supported with wireless extensions, so just
- * report that encryption is used */
- erq->length = 0;
- erq->flags |= IW_ENCODE_ENABLED;
- return 0;
- }
+ len = sec->key_sizes[key];
+ memcpy(keybuf, sec->keys[key], len);
- len = crypt->ops->get_key(keybuf, WEP_KEY_LEN, NULL, crypt->priv);
erq->length = (len >= 0 ? len : 0);
-
erq->flags |= IW_ENCODE_ENABLED;
if (ieee->open_wep)
@@ -463,6 +493,242 @@ int ieee80211_wx_get_encode(struct ieee80211_device *ieee,
return 0;
}
+int ieee80211_wx_set_encodeext(struct ieee80211_device *ieee,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct net_device *dev = ieee->dev;
+ struct iw_point *encoding = &wrqu->encoding;
+ struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
+ int i, idx, ret = 0;
+ int group_key = 0;
+ const char *alg, *module;
+ struct ieee80211_crypto_ops *ops;
+ struct ieee80211_crypt_data **crypt;
+
+ struct ieee80211_security sec = {
+ .flags = 0,
+ };
+
+ idx = encoding->flags & IW_ENCODE_INDEX;
+ if (idx) {
+ if (idx < 1 || idx > WEP_KEYS)
+ return -EINVAL;
+ idx--;
+ } else
+ idx = ieee->tx_keyidx;
+
+ if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
+ crypt = &ieee->crypt[idx];
+ group_key = 1;
+ } else {
+ /* some Cisco APs use idx>0 for unicast in dynamic WEP */
+ if (idx != 0 && ext->alg != IW_ENCODE_ALG_WEP)
+ return -EINVAL;
+ if (ieee->iw_mode == IW_MODE_INFRA)
+ crypt = &ieee->crypt[idx];
+ else
+ return -EINVAL;
+ }
+
+ sec.flags |= SEC_ENABLED | SEC_ENCRYPT;
+ if ((encoding->flags & IW_ENCODE_DISABLED) ||
+ ext->alg == IW_ENCODE_ALG_NONE) {
+ if (*crypt)
+ ieee80211_crypt_delayed_deinit(ieee, crypt);
+
+ for (i = 0; i < WEP_KEYS; i++)
+ if (ieee->crypt[i] != NULL)
+ break;
+
+ if (i == WEP_KEYS) {
+ sec.enabled = 0;
+ sec.encrypt = 0;
+ sec.level = SEC_LEVEL_0;
+ sec.flags |= SEC_LEVEL;
+ }
+ goto done;
+ }
+
+ sec.enabled = 1;
+ sec.encrypt = 1;
+
+ if (group_key ? !ieee->host_mc_decrypt :
+ !(ieee->host_encrypt || ieee->host_decrypt ||
+ ieee->host_encrypt_msdu))
+ goto skip_host_crypt;
+
+ switch (ext->alg) {
+ case IW_ENCODE_ALG_WEP:
+ alg = "WEP";
+ module = "ieee80211_crypt_wep";
+ break;
+ case IW_ENCODE_ALG_TKIP:
+ alg = "TKIP";
+ module = "ieee80211_crypt_tkip";
+ break;
+ case IW_ENCODE_ALG_CCMP:
+ alg = "CCMP";
+ module = "ieee80211_crypt_ccmp";
+ break;
+ default:
+ IEEE80211_DEBUG_WX("%s: unknown crypto alg %d\n",
+ dev->name, ext->alg);
+ ret = -EINVAL;
+ goto done;
+ }
+
+ ops = ieee80211_get_crypto_ops(alg);
+ if (ops == NULL) {
+ request_module(module);
+ ops = ieee80211_get_crypto_ops(alg);
+ }
+ if (ops == NULL) {
+ IEEE80211_DEBUG_WX("%s: unknown crypto alg %d\n",
+ dev->name, ext->alg);
+ ret = -EINVAL;
+ goto done;
+ }
+
+ if (*crypt == NULL || (*crypt)->ops != ops) {
+ struct ieee80211_crypt_data *new_crypt;
+
+ ieee80211_crypt_delayed_deinit(ieee, crypt);
+
+ new_crypt = (struct ieee80211_crypt_data *)
+ kmalloc(sizeof(*new_crypt), GFP_KERNEL);
+ if (new_crypt == NULL) {
+ ret = -ENOMEM;
+ goto done;
+ }
+ memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data));
+ new_crypt->ops = ops;
+ if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
+ new_crypt->priv = new_crypt->ops->init(idx);
+ if (new_crypt->priv == NULL) {
+ kfree(new_crypt);
+ ret = -EINVAL;
+ goto done;
+ }
+ *crypt = new_crypt;
+ }
+
+ if (ext->key_len > 0 && (*crypt)->ops->set_key &&
+ (*crypt)->ops->set_key(ext->key, ext->key_len, ext->rx_seq,
+ (*crypt)->priv) < 0) {
+ IEEE80211_DEBUG_WX("%s: key setting failed\n", dev->name);
+ ret = -EINVAL;
+ goto done;
+ }
+
+ skip_host_crypt:
+ if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
+ ieee->tx_keyidx = idx;
+ sec.active_key = idx;
+ sec.flags |= SEC_ACTIVE_KEY;
+ }
+
+ if (ext->alg != IW_ENCODE_ALG_NONE) {
+ memcpy(sec.keys[idx], ext->key, ext->key_len);
+ sec.key_sizes[idx] = ext->key_len;
+ sec.flags |= (1 << idx);
+ if (ext->alg == IW_ENCODE_ALG_WEP) {
+ sec.encode_alg[idx] = SEC_ALG_WEP;
+ sec.flags |= SEC_LEVEL;
+ sec.level = SEC_LEVEL_1;
+ } else if (ext->alg == IW_ENCODE_ALG_TKIP) {
+ sec.encode_alg[idx] = SEC_ALG_TKIP;
+ sec.flags |= SEC_LEVEL;
+ sec.level = SEC_LEVEL_2;
+ } else if (ext->alg == IW_ENCODE_ALG_CCMP) {
+ sec.encode_alg[idx] = SEC_ALG_CCMP;
+ sec.flags |= SEC_LEVEL;
+ sec.level = SEC_LEVEL_3;
+ }
+ /* Don't set sec level for group keys. */
+ if (group_key)
+ sec.flags &= ~SEC_LEVEL;
+ }
+ done:
+ if (ieee->set_security)
+ ieee->set_security(ieee->dev, &sec);
+
+ /*
+ * Do not reset port if card is in Managed mode since resetting will
+ * generate new IEEE 802.11 authentication which may end up in looping
+ * with IEEE 802.1X. If your hardware requires a reset after WEP
+ * configuration (for example... Prism2), implement the reset_port in
+ * the callbacks structures used to initialize the 802.11 stack.
+ */
+ if (ieee->reset_on_keychange &&
+ ieee->iw_mode != IW_MODE_INFRA &&
+ ieee->reset_port && ieee->reset_port(dev)) {
+ IEEE80211_DEBUG_WX("%s: reset_port failed\n", dev->name);
+ return -EINVAL;
+ }
+
+ return ret;
+}
+
+int ieee80211_wx_get_encodeext(struct ieee80211_device *ieee,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct iw_point *encoding = &wrqu->encoding;
+ struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
+ struct ieee80211_security *sec = &ieee->sec;
+ int idx, max_key_len;
+
+ max_key_len = encoding->length - sizeof(*ext);
+ if (max_key_len < 0)
+ return -EINVAL;
+
+ idx = encoding->flags & IW_ENCODE_INDEX;
+ if (idx) {
+ if (idx < 1 || idx > WEP_KEYS)
+ return -EINVAL;
+ idx--;
+ } else
+ idx = ieee->tx_keyidx;
+
+ if (!ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY &&
+ ext->alg != IW_ENCODE_ALG_WEP)
+ if (idx != 0 || ieee->iw_mode != IW_MODE_INFRA)
+ return -EINVAL;
+
+ encoding->flags = idx + 1;
+ memset(ext, 0, sizeof(*ext));
+
+ if (!sec->enabled) {
+ ext->alg = IW_ENCODE_ALG_NONE;
+ ext->key_len = 0;
+ encoding->flags |= IW_ENCODE_DISABLED;
+ } else {
+ if (sec->encode_alg[idx] == SEC_ALG_WEP)
+ ext->alg = IW_ENCODE_ALG_WEP;
+ else if (sec->encode_alg[idx] == SEC_ALG_TKIP)
+ ext->alg = IW_ENCODE_ALG_TKIP;
+ else if (sec->encode_alg[idx] == SEC_ALG_CCMP)
+ ext->alg = IW_ENCODE_ALG_CCMP;
+ else
+ return -EINVAL;
+
+ ext->key_len = sec->key_sizes[idx];
+ memcpy(ext->key, sec->keys[idx], ext->key_len);
+ encoding->flags |= IW_ENCODE_ENABLED;
+ if (ext->key_len &&
+ (ext->alg == IW_ENCODE_ALG_TKIP ||
+ ext->alg == IW_ENCODE_ALG_CCMP))
+ ext->ext_flags |= IW_ENCODE_EXT_TX_SEQ_VALID;
+
+ }
+
+ return 0;
+}
+
+EXPORT_SYMBOL(ieee80211_wx_set_encodeext);
+EXPORT_SYMBOL(ieee80211_wx_get_encodeext);
+
EXPORT_SYMBOL(ieee80211_wx_get_scan);
EXPORT_SYMBOL(ieee80211_wx_set_encode);
EXPORT_SYMBOL(ieee80211_wx_get_encode);
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index a9d84f93442c..eaa150c33b04 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -147,8 +147,7 @@ void inet_sock_destruct(struct sock *sk)
BUG_TRAP(!sk->sk_wmem_queued);
BUG_TRAP(!sk->sk_forward_alloc);
- if (inet->opt)
- kfree(inet->opt);
+ kfree(inet->opt);
dst_release(sk->sk_dst_cache);
sk_refcnt_debug_dec(sk);
}
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
index 74f2207e131a..4ec4b2ca6ab1 100644
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
@@ -715,6 +715,7 @@ int devinet_ioctl(unsigned int cmd, void __user *arg)
break;
ret = 0;
if (ifa->ifa_mask != sin->sin_addr.s_addr) {
+ u32 old_mask = ifa->ifa_mask;
inet_del_ifa(in_dev, ifap, 0);
ifa->ifa_mask = sin->sin_addr.s_addr;
ifa->ifa_prefixlen = inet_mask_len(ifa->ifa_mask);
@@ -728,7 +729,7 @@ int devinet_ioctl(unsigned int cmd, void __user *arg)
if ((dev->flags & IFF_BROADCAST) &&
(ifa->ifa_prefixlen < 31) &&
(ifa->ifa_broadcast ==
- (ifa->ifa_local|~ifa->ifa_mask))) {
+ (ifa->ifa_local|~old_mask))) {
ifa->ifa_broadcast = (ifa->ifa_local |
~sin->sin_addr.s_addr);
}
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c
index e61bc7177eb1..2267c1fad879 100644
--- a/net/ipv4/fib_frontend.c
+++ b/net/ipv4/fib_frontend.c
@@ -266,8 +266,7 @@ int ip_rt_ioctl(unsigned int cmd, void __user *arg)
if (tb)
err = tb->tb_insert(tb, &req.rtm, &rta, &req.nlh, NULL);
}
- if (rta.rta_mx)
- kfree(rta.rta_mx);
+ kfree(rta.rta_mx);
}
rtnl_unlock();
return err;
@@ -591,7 +590,7 @@ static int fib_inetaddr_event(struct notifier_block *this, unsigned long event,
break;
case NETDEV_DOWN:
fib_del_ifaddr(ifa);
- if (ifa->ifa_dev && ifa->ifa_dev->ifa_list == NULL) {
+ if (ifa->ifa_dev->ifa_list == NULL) {
/* Last address was deleted from this interface.
Disable IP.
*/
diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c
index 0093ea08c7f5..66247f38b371 100644
--- a/net/ipv4/fib_trie.c
+++ b/net/ipv4/fib_trie.c
@@ -2404,7 +2404,7 @@ static int fib_route_seq_show(struct seq_file *seq, void *v)
prefix = htonl(l->key);
list_for_each_entry_rcu(fa, &li->falh, fa_list) {
- const struct fib_info *fi = rcu_dereference(fa->fa_info);
+ const struct fib_info *fi = fa->fa_info;
unsigned flags = fib_flag_trans(fa->fa_type, mask, fi);
if (fa->fa_type == RTN_BROADCAST
diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c
index 90dca711ac9f..e3eceecd0496 100644
--- a/net/ipv4/icmp.c
+++ b/net/ipv4/icmp.c
@@ -934,11 +934,11 @@ int icmp_rcv(struct sk_buff *skb)
case CHECKSUM_HW:
if (!(u16)csum_fold(skb->csum))
break;
- LIMIT_NETDEBUG(KERN_DEBUG "icmp v4 hw csum failure\n");
+ /* fall through */
case CHECKSUM_NONE:
- if ((u16)csum_fold(skb_checksum(skb, 0, skb->len, 0)))
+ skb->csum = 0;
+ if (__skb_checksum_complete(skb))
goto error;
- default:;
}
if (!pskb_pull(skb, sizeof(struct icmphdr)))
@@ -1108,12 +1108,9 @@ void __init icmp_init(struct net_proto_family *ops)
struct inet_sock *inet;
int i;
- for (i = 0; i < NR_CPUS; i++) {
+ for_each_cpu(i) {
int err;
- if (!cpu_possible(i))
- continue;
-
err = sock_create_kern(PF_INET, SOCK_RAW, IPPROTO_ICMP,
&per_cpu(__icmp_socket, i));
diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c
index 8b6d3939e1e6..c04607b49212 100644
--- a/net/ipv4/igmp.c
+++ b/net/ipv4/igmp.c
@@ -872,11 +872,18 @@ int igmp_rcv(struct sk_buff *skb)
return 0;
}
- if (!pskb_may_pull(skb, sizeof(struct igmphdr)) ||
- (u16)csum_fold(skb_checksum(skb, 0, len, 0))) {
- in_dev_put(in_dev);
- kfree_skb(skb);
- return 0;
+ if (!pskb_may_pull(skb, sizeof(struct igmphdr)))
+ goto drop;
+
+ switch (skb->ip_summed) {
+ case CHECKSUM_HW:
+ if (!(u16)csum_fold(skb->csum))
+ break;
+ /* fall through */
+ case CHECKSUM_NONE:
+ skb->csum = 0;
+ if (__skb_checksum_complete(skb))
+ goto drop;
}
ih = skb->h.igmph;
@@ -906,6 +913,8 @@ int igmp_rcv(struct sk_buff *skb)
default:
NETDEBUG(KERN_DEBUG "New IGMP type=%d, why we do not know about it?\n", ih->type);
}
+
+drop:
in_dev_put(in_dev);
kfree_skb(skb);
return 0;
@@ -1908,8 +1917,11 @@ int ip_mc_msfilter(struct sock *sk, struct ip_msfilter *msf, int ifindex)
sock_kfree_s(sk, newpsl, IP_SFLSIZE(newpsl->sl_max));
goto done;
}
- } else
+ } else {
newpsl = NULL;
+ (void) ip_mc_add_src(in_dev, &msf->imsf_multiaddr,
+ msf->imsf_fmode, 0, NULL, 0);
+ }
psl = pmc->sflist;
if (psl) {
(void) ip_mc_del_src(in_dev, &msf->imsf_multiaddr, pmc->sfmode,
diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c
index 94468a76c5b4..3fe021f1a566 100644
--- a/net/ipv4/inet_connection_sock.c
+++ b/net/ipv4/inet_connection_sock.c
@@ -78,17 +78,9 @@ int inet_csk_get_port(struct inet_hashinfo *hashinfo,
int low = sysctl_local_port_range[0];
int high = sysctl_local_port_range[1];
int remaining = (high - low) + 1;
- int rover;
+ int rover = net_random() % (high - low) + low;
- spin_lock(&hashinfo->portalloc_lock);
- if (hashinfo->port_rover < low)
- rover = low;
- else
- rover = hashinfo->port_rover;
do {
- rover++;
- if (rover > high)
- rover = low;
head = &hashinfo->bhash[inet_bhashfn(rover, hashinfo->bhash_size)];
spin_lock(&head->lock);
inet_bind_bucket_for_each(tb, node, &head->chain)
@@ -97,9 +89,9 @@ int inet_csk_get_port(struct inet_hashinfo *hashinfo,
break;
next:
spin_unlock(&head->lock);
+ if (++rover > high)
+ rover = low;
} while (--remaining > 0);
- hashinfo->port_rover = rover;
- spin_unlock(&hashinfo->portalloc_lock);
/* Exhausted local port range during search? It is not
* possible for us to be holding one of the bind hash
diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c
index 71f3c7350c6e..39061ed53cfd 100644
--- a/net/ipv4/inet_diag.c
+++ b/net/ipv4/inet_diag.c
@@ -724,12 +724,6 @@ done:
return skb->len;
}
-static int inet_diag_dump_done(struct netlink_callback *cb)
-{
- return 0;
-}
-
-
static __inline__ int
inet_diag_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
{
@@ -760,8 +754,7 @@ inet_diag_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
goto err_inval;
}
return netlink_dump_start(idiagnl, skb, nlh,
- inet_diag_dump,
- inet_diag_dump_done);
+ inet_diag_dump, NULL);
} else {
return inet_diag_get_exact(skb, nlh);
}
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
index 896ce3f8f53a..4e9c74b54b15 100644
--- a/net/ipv4/ip_gre.c
+++ b/net/ipv4/ip_gre.c
@@ -577,15 +577,16 @@ static int ipgre_rcv(struct sk_buff *skb)
goto drop_nolock;
if (flags&GRE_CSUM) {
- if (skb->ip_summed == CHECKSUM_HW) {
+ switch (skb->ip_summed) {
+ case CHECKSUM_HW:
csum = (u16)csum_fold(skb->csum);
- if (csum)
- skb->ip_summed = CHECKSUM_NONE;
- }
- if (skb->ip_summed == CHECKSUM_NONE) {
- skb->csum = skb_checksum(skb, 0, skb->len, 0);
+ if (!csum)
+ break;
+ /* fall through */
+ case CHECKSUM_NONE:
+ skb->csum = 0;
+ csum = __skb_checksum_complete(skb);
skb->ip_summed = CHECKSUM_HW;
- csum = (u16)csum_fold(skb->csum);
}
offset += 4;
}
diff --git a/net/ipv4/ip_options.c b/net/ipv4/ip_options.c
index bce4e875193b..dbe12da8d8b3 100644
--- a/net/ipv4/ip_options.c
+++ b/net/ipv4/ip_options.c
@@ -510,8 +510,7 @@ static int ip_options_get_finish(struct ip_options **optp,
kfree(opt);
return -EINVAL;
}
- if (*optp)
- kfree(*optp);
+ kfree(*optp);
*optp = opt;
return 0;
}
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index 1ad5202e556b..11c2f68254f0 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -275,7 +275,8 @@ int ip_output(struct sk_buff *skb)
{
IP_INC_STATS(IPSTATS_MIB_OUTREQUESTS);
- if (skb->len > dst_mtu(skb->dst) && !skb_shinfo(skb)->tso_size)
+ if (skb->len > dst_mtu(skb->dst) &&
+ !(skb_shinfo(skb)->ufo_size || skb_shinfo(skb)->tso_size))
return ip_fragment(skb, ip_finish_output);
else
return ip_finish_output(skb);
@@ -352,7 +353,8 @@ packet_routed:
ip_options_build(skb, opt, inet->daddr, rt, 0);
}
- ip_select_ident_more(iph, &rt->u.dst, sk, skb_shinfo(skb)->tso_segs);
+ ip_select_ident_more(iph, &rt->u.dst, sk,
+ (skb_shinfo(skb)->tso_segs ?: 1) - 1);
/* Add an IP checksum. */
ip_send_check(iph);
@@ -688,6 +690,60 @@ csum_page(struct page *page, int offset, int copy)
return csum;
}
+inline int ip_ufo_append_data(struct sock *sk,
+ int getfrag(void *from, char *to, int offset, int len,
+ int odd, struct sk_buff *skb),
+ void *from, int length, int hh_len, int fragheaderlen,
+ int transhdrlen, int mtu,unsigned int flags)
+{
+ struct sk_buff *skb;
+ int err;
+
+ /* There is support for UDP fragmentation offload by network
+ * device, so create one single skb packet containing complete
+ * udp datagram
+ */
+ if ((skb = skb_peek_tail(&sk->sk_write_queue)) == NULL) {
+ skb = sock_alloc_send_skb(sk,
+ hh_len + fragheaderlen + transhdrlen + 20,
+ (flags & MSG_DONTWAIT), &err);
+
+ if (skb == NULL)
+ return err;
+
+ /* reserve space for Hardware header */
+ skb_reserve(skb, hh_len);
+
+ /* create space for UDP/IP header */
+ skb_put(skb,fragheaderlen + transhdrlen);
+
+ /* initialize network header pointer */
+ skb->nh.raw = skb->data;
+
+ /* initialize protocol header pointer */
+ skb->h.raw = skb->data + fragheaderlen;
+
+ skb->ip_summed = CHECKSUM_HW;
+ skb->csum = 0;
+ sk->sk_sndmsg_off = 0;
+ }
+
+ err = skb_append_datato_frags(sk,skb, getfrag, from,
+ (length - transhdrlen));
+ if (!err) {
+ /* specify the length of each IP datagram fragment*/
+ skb_shinfo(skb)->ufo_size = (mtu - fragheaderlen);
+ __skb_queue_tail(&sk->sk_write_queue, skb);
+
+ return 0;
+ }
+ /* There is not enough support do UFO ,
+ * so follow normal path
+ */
+ kfree_skb(skb);
+ return err;
+}
+
/*
* ip_append_data() and ip_append_page() can make one large IP datagram
* from many pieces of data. Each pieces will be holded on the socket
@@ -777,6 +833,15 @@ int ip_append_data(struct sock *sk,
csummode = CHECKSUM_HW;
inet->cork.length += length;
+ if (((length > mtu) && (sk->sk_protocol == IPPROTO_UDP)) &&
+ (rt->u.dst.dev->features & NETIF_F_UFO)) {
+
+ if(ip_ufo_append_data(sk, getfrag, from, length, hh_len,
+ fragheaderlen, transhdrlen, mtu, flags))
+ goto error;
+
+ return 0;
+ }
/* So, what's going on in the loop below?
*
@@ -1008,14 +1073,23 @@ ssize_t ip_append_page(struct sock *sk, struct page *page,
return -EINVAL;
inet->cork.length += size;
+ if ((sk->sk_protocol == IPPROTO_UDP) &&
+ (rt->u.dst.dev->features & NETIF_F_UFO))
+ skb_shinfo(skb)->ufo_size = (mtu - fragheaderlen);
+
while (size > 0) {
int i;
- /* Check if the remaining data fits into current packet. */
- len = mtu - skb->len;
- if (len < size)
- len = maxfraglen - skb->len;
+ if (skb_shinfo(skb)->ufo_size)
+ len = size;
+ else {
+
+ /* Check if the remaining data fits into current packet. */
+ len = mtu - skb->len;
+ if (len < size)
+ len = maxfraglen - skb->len;
+ }
if (len <= 0) {
struct sk_buff *skb_prev;
char *data;
@@ -1023,10 +1097,7 @@ ssize_t ip_append_page(struct sock *sk, struct page *page,
int alloclen;
skb_prev = skb;
- if (skb_prev)
- fraggap = skb_prev->len - maxfraglen;
- else
- fraggap = 0;
+ fraggap = skb_prev->len - maxfraglen;
alloclen = fragheaderlen + hh_len + fraggap + 15;
skb = sock_wmalloc(sk, alloclen, 1, sk->sk_allocation);
@@ -1192,10 +1263,8 @@ int ip_push_pending_frames(struct sock *sk)
out:
inet->cork.flags &= ~IPCORK_OPT;
- if (inet->cork.opt) {
- kfree(inet->cork.opt);
- inet->cork.opt = NULL;
- }
+ kfree(inet->cork.opt);
+ inet->cork.opt = NULL;
if (inet->cork.rt) {
ip_rt_put(inet->cork.rt);
inet->cork.rt = NULL;
@@ -1219,10 +1288,8 @@ void ip_flush_pending_frames(struct sock *sk)
kfree_skb(skb);
inet->cork.flags &= ~IPCORK_OPT;
- if (inet->cork.opt) {
- kfree(inet->cork.opt);
- inet->cork.opt = NULL;
- }
+ kfree(inet->cork.opt);
+ inet->cork.opt = NULL;
if (inet->cork.rt) {
ip_rt_put(inet->cork.rt);
inet->cork.rt = NULL;
diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c
index 2f0b47da5b37..4f2d87257309 100644
--- a/net/ipv4/ip_sockglue.c
+++ b/net/ipv4/ip_sockglue.c
@@ -202,8 +202,7 @@ int ip_ra_control(struct sock *sk, unsigned char on, void (*destructor)(struct s
if (ra->sk == sk) {
if (on) {
write_unlock_bh(&ip_ra_lock);
- if (new_ra)
- kfree(new_ra);
+ kfree(new_ra);
return -EADDRINUSE;
}
*rap = ra->next;
@@ -446,8 +445,7 @@ int ip_setsockopt(struct sock *sk, int level, int optname, char __user *optval,
#endif
}
opt = xchg(&inet->opt, opt);
- if (opt)
- kfree(opt);
+ kfree(opt);
break;
}
case IP_PKTINFO:
@@ -828,10 +826,8 @@ int ip_setsockopt(struct sock *sk, int level, int optname, char __user *optval,
err = ip_mc_msfilter(sk, msf, ifindex);
mc_msf_out:
- if (msf)
- kfree(msf);
- if (gsf)
- kfree(gsf);
+ kfree(msf);
+ kfree(gsf);
break;
}
case IP_ROUTER_ALERT:
diff --git a/net/ipv4/ipvs/ip_vs_app.c b/net/ipv4/ipvs/ip_vs_app.c
index fc6f95aaa969..d7eb680101c2 100644
--- a/net/ipv4/ipvs/ip_vs_app.c
+++ b/net/ipv4/ipvs/ip_vs_app.c
@@ -110,8 +110,7 @@ ip_vs_app_inc_new(struct ip_vs_app *app, __u16 proto, __u16 port)
return 0;
out:
- if (inc->timeout_table)
- kfree(inc->timeout_table);
+ kfree(inc->timeout_table);
kfree(inc);
return ret;
}
@@ -136,8 +135,7 @@ ip_vs_app_inc_release(struct ip_vs_app *inc)
list_del(&inc->a_list);
- if (inc->timeout_table != NULL)
- kfree(inc->timeout_table);
+ kfree(inc->timeout_table);
kfree(inc);
}
diff --git a/net/ipv4/ipvs/ip_vs_core.c b/net/ipv4/ipvs/ip_vs_core.c
index 981cc3244ef2..1a0843cd58a9 100644
--- a/net/ipv4/ipvs/ip_vs_core.c
+++ b/net/ipv4/ipvs/ip_vs_core.c
@@ -1009,11 +1009,10 @@ ip_vs_in(unsigned int hooknum, struct sk_buff **pskb,
if (sysctl_ip_vs_expire_nodest_conn) {
/* try to expire the connection immediately */
ip_vs_conn_expire_now(cp);
- } else {
- /* don't restart its timer, and silently
- drop the packet. */
- __ip_vs_conn_put(cp);
}
+ /* don't restart its timer, and silently
+ drop the packet. */
+ __ip_vs_conn_put(cp);
return NF_DROP;
}
diff --git a/net/ipv4/multipath_wrandom.c b/net/ipv4/multipath_wrandom.c
index bd7d75b6abe0..d34a9fa608e0 100644
--- a/net/ipv4/multipath_wrandom.c
+++ b/net/ipv4/multipath_wrandom.c
@@ -207,16 +207,12 @@ static void wrandom_select_route(const struct flowi *flp,
decision = mpc->rt;
last_power = mpc->power;
- if (last_mpc)
- kfree(last_mpc);
-
+ kfree(last_mpc);
last_mpc = mpc;
}
- if (last_mpc) {
- /* concurrent __multipath_flush may lead to !last_mpc */
- kfree(last_mpc);
- }
+ /* concurrent __multipath_flush may lead to !last_mpc */
+ kfree(last_mpc);
decision->u.dst.__use++;
*rp = decision;
diff --git a/net/ipv4/netfilter/Kconfig b/net/ipv4/netfilter/Kconfig
index 7d917e4ce1d9..9d3c8b5f327e 100644
--- a/net/ipv4/netfilter/Kconfig
+++ b/net/ipv4/netfilter/Kconfig
@@ -5,6 +5,20 @@
menu "IP: Netfilter Configuration"
depends on INET && NETFILTER
+config NF_CONNTRACK_IPV4
+ tristate "IPv4 support for new connection tracking (EXPERIMENTAL)"
+ depends on EXPERIMENTAL && NF_CONNTRACK
+ ---help---
+ Connection tracking keeps a record of what packets have passed
+ through your machine, in order to figure out how they are related
+ into connections.
+
+ This is IPv4 support on Layer 3 independent connection tracking.
+ Layer 3 independent connection tracking is experimental scheme
+ which generalize ip_conntrack to support other layer 3 protocols.
+
+ To compile it as a module, choose M here. If unsure, say N.
+
# connection tracking, helpers and protocols
config IP_NF_CONNTRACK
tristate "Connection tracking (required for masq/NAT)"
@@ -209,8 +223,8 @@ config IP_NF_MATCH_PKTTYPE
tristate "Packet type match support"
depends on IP_NF_IPTABLES
help
- Packet type matching allows you to match a packet by
- its "class", eg. BROADCAST, MULTICAST, ...
+ Packet type matching allows you to match a packet by
+ its "class", eg. BROADCAST, MULTICAST, ...
Typical usage:
iptables -A INPUT -m pkttype --pkt-type broadcast -j LOG
@@ -317,7 +331,8 @@ config IP_NF_MATCH_TCPMSS
config IP_NF_MATCH_HELPER
tristate "Helper match support"
- depends on IP_NF_CONNTRACK && IP_NF_IPTABLES
+ depends on IP_NF_IPTABLES
+ depends on IP_NF_CONNTRACK || NF_CONNTRACK_IPV4
help
Helper matching allows you to match packets in dynamic connections
tracked by a conntrack-helper, ie. ip_conntrack_ftp
@@ -326,7 +341,8 @@ config IP_NF_MATCH_HELPER
config IP_NF_MATCH_STATE
tristate "Connection state match support"
- depends on IP_NF_CONNTRACK && IP_NF_IPTABLES
+ depends on IP_NF_IPTABLES
+ depends on IP_NF_CONNTRACK || NF_CONNTRACK_IPV4
help
Connection state matching allows you to match packets based on their
relationship to a tracked connection (ie. previous packets). This
@@ -336,7 +352,8 @@ config IP_NF_MATCH_STATE
config IP_NF_MATCH_CONNTRACK
tristate "Connection tracking match support"
- depends on IP_NF_CONNTRACK && IP_NF_IPTABLES
+ depends on IP_NF_IPTABLES
+ depends on IP_NF_CONNTRACK || NF_CONNTRACK_IPV4
help
This is a general conntrack match module, a superset of the state match.
@@ -422,7 +439,8 @@ config IP_NF_MATCH_COMMENT
config IP_NF_MATCH_CONNMARK
tristate 'Connection mark match support'
- depends on IP_NF_CONNTRACK_MARK && IP_NF_IPTABLES
+ depends on IP_NF_IPTABLES
+ depends on IP_NF_CONNTRACK_MARK || (NF_CONNTRACK_MARK && NF_CONNTRACK_IPV4)
help
This option adds a `connmark' match, which allows you to match the
connection mark value previously set for the session by `CONNMARK'.
@@ -433,7 +451,8 @@ config IP_NF_MATCH_CONNMARK
config IP_NF_MATCH_CONNBYTES
tristate 'Connection byte/packet counter match support'
- depends on IP_NF_CT_ACCT && IP_NF_IPTABLES
+ depends on IP_NF_IPTABLES
+ depends on IP_NF_CT_ACCT || (NF_CT_ACCT && NF_CONNTRACK_IPV4)
help
This option adds a `connbytes' match, which allows you to match the
number of bytes and/or packets for each direction within a connection.
@@ -747,7 +766,8 @@ config IP_NF_TARGET_TTL
config IP_NF_TARGET_CONNMARK
tristate 'CONNMARK target support'
- depends on IP_NF_CONNTRACK_MARK && IP_NF_MANGLE
+ depends on IP_NF_MANGLE
+ depends on IP_NF_CONNTRACK_MARK || (NF_CONNTRACK_MARK && NF_CONNTRACK_IPV4)
help
This option adds a `CONNMARK' target, which allows one to manipulate
the connection mark value. Similar to the MARK target, but
@@ -759,7 +779,8 @@ config IP_NF_TARGET_CONNMARK
config IP_NF_TARGET_CLUSTERIP
tristate "CLUSTERIP target support (EXPERIMENTAL)"
- depends on IP_NF_CONNTRACK_MARK && IP_NF_IPTABLES && EXPERIMENTAL
+ depends on IP_NF_IPTABLES && EXPERIMENTAL
+ depends on IP_NF_CONNTRACK_MARK || (NF_CONNTRACK_MARK && NF_CONNTRACK_IPV4)
help
The CLUSTERIP target allows you to build load-balancing clusters of
network servers without having a dedicated load-balancing
@@ -782,7 +803,7 @@ config IP_NF_RAW
config IP_NF_TARGET_NOTRACK
tristate 'NOTRACK target support'
depends on IP_NF_RAW
- depends on IP_NF_CONNTRACK
+ depends on IP_NF_CONNTRACK || NF_CONNTRACK_IPV4
help
The NOTRACK target allows a select rule to specify
which packets *not* to enter the conntrack/NAT
diff --git a/net/ipv4/netfilter/Makefile b/net/ipv4/netfilter/Makefile
index dab4b58dd31e..058c48e258fc 100644
--- a/net/ipv4/netfilter/Makefile
+++ b/net/ipv4/netfilter/Makefile
@@ -103,3 +103,9 @@ obj-$(CONFIG_IP_NF_ARP_MANGLE) += arpt_mangle.o
obj-$(CONFIG_IP_NF_ARPFILTER) += arptable_filter.o
obj-$(CONFIG_IP_NF_QUEUE) += ip_queue.o
+
+# objects for l3 independent conntrack
+nf_conntrack_ipv4-objs := nf_conntrack_l3proto_ipv4.o nf_conntrack_proto_icmp.o
+
+# l3 independent conntrack
+obj-$(CONFIG_NF_CONNTRACK_IPV4) += nf_conntrack_ipv4.o
diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c
index a7969286e6e7..3c2e9639bba6 100644
--- a/net/ipv4/netfilter/arp_tables.c
+++ b/net/ipv4/netfilter/arp_tables.c
@@ -347,58 +347,106 @@ unsigned int arpt_do_table(struct sk_buff **pskb,
return verdict;
}
-static inline void *find_inlist_lock_noload(struct list_head *head,
- const char *name,
- int *error,
- struct semaphore *mutex)
+/*
+ * These are weird, but module loading must not be done with mutex
+ * held (since they will register), and we have to have a single
+ * function to use try_then_request_module().
+ */
+
+/* Find table by name, grabs mutex & ref. Returns ERR_PTR() on error. */
+static inline struct arpt_table *find_table_lock(const char *name)
{
- void *ret;
+ struct arpt_table *t;
- *error = down_interruptible(mutex);
- if (*error != 0)
- return NULL;
+ if (down_interruptible(&arpt_mutex) != 0)
+ return ERR_PTR(-EINTR);
- ret = list_named_find(head, name);
- if (!ret) {
- *error = -ENOENT;
- up(mutex);
- }
- return ret;
+ list_for_each_entry(t, &arpt_tables, list)
+ if (strcmp(t->name, name) == 0 && try_module_get(t->me))
+ return t;
+ up(&arpt_mutex);
+ return NULL;
}
-#ifndef CONFIG_KMOD
-#define find_inlist_lock(h,n,p,e,m) find_inlist_lock_noload((h),(n),(e),(m))
-#else
-static void *
-find_inlist_lock(struct list_head *head,
- const char *name,
- const char *prefix,
- int *error,
- struct semaphore *mutex)
+
+/* Find target, grabs ref. Returns ERR_PTR() on error. */
+static inline struct arpt_target *find_target(const char *name, u8 revision)
{
- void *ret;
+ struct arpt_target *t;
+ int err = 0;
- ret = find_inlist_lock_noload(head, name, error, mutex);
- if (!ret) {
- duprintf("find_inlist: loading `%s%s'.\n", prefix, name);
- request_module("%s%s", prefix, name);
- ret = find_inlist_lock_noload(head, name, error, mutex);
+ if (down_interruptible(&arpt_mutex) != 0)
+ return ERR_PTR(-EINTR);
+
+ list_for_each_entry(t, &arpt_target, list) {
+ if (strcmp(t->name, name) == 0) {
+ if (t->revision == revision) {
+ if (try_module_get(t->me)) {
+ up(&arpt_mutex);
+ return t;
+ }
+ } else
+ err = -EPROTOTYPE; /* Found something. */
+ }
}
+ up(&arpt_mutex);
+ return ERR_PTR(err);
+}
- return ret;
+struct arpt_target *arpt_find_target(const char *name, u8 revision)
+{
+ struct arpt_target *target;
+
+ target = try_then_request_module(find_target(name, revision),
+ "arpt_%s", name);
+ if (IS_ERR(target) || !target)
+ return NULL;
+ return target;
}
-#endif
-static inline struct arpt_table *arpt_find_table_lock(const char *name, int *error, struct semaphore *mutex)
+static int target_revfn(const char *name, u8 revision, int *bestp)
{
- return find_inlist_lock(&arpt_tables, name, "arptable_", error, mutex);
+ struct arpt_target *t;
+ int have_rev = 0;
+
+ list_for_each_entry(t, &arpt_target, list) {
+ if (strcmp(t->name, name) == 0) {
+ if (t->revision > *bestp)
+ *bestp = t->revision;
+ if (t->revision == revision)
+ have_rev =1;
+ }
+ }
+ return have_rev;
}
-static struct arpt_target *arpt_find_target_lock(const char *name, int *error, struct semaphore *mutex)
+/* Returns true or false (if no such extension at all) */
+static inline int find_revision(const char *name, u8 revision,
+ int (*revfn)(const char *, u8, int *),
+ int *err)
{
- return find_inlist_lock(&arpt_target, name, "arpt_", error, mutex);
+ int have_rev, best = -1;
+
+ if (down_interruptible(&arpt_mutex) != 0) {
+ *err = -EINTR;
+ return 1;
+ }
+ have_rev = revfn(name, revision, &best);
+ up(&arpt_mutex);
+
+ /* Nothing at all? Return 0 to try loading module. */
+ if (best == -1) {
+ *err = -ENOENT;
+ return 0;
+ }
+
+ *err = best;
+ if (!have_rev)
+ *err = -EPROTONOSUPPORT;
+ return 1;
}
+
/* All zeroes == unconditional rule. */
static inline int unconditional(const struct arpt_arp *arp)
{
@@ -544,17 +592,15 @@ static inline int check_entry(struct arpt_entry *e, const char *name, unsigned i
}
t = arpt_get_target(e);
- target = arpt_find_target_lock(t->u.user.name, &ret, &arpt_mutex);
- if (!target) {
+ target = try_then_request_module(find_target(t->u.user.name,
+ t->u.user.revision),
+ "arpt_%s", t->u.user.name);
+ if (IS_ERR(target) || !target) {
duprintf("check_entry: `%s' not found\n", t->u.user.name);
+ ret = target ? PTR_ERR(target) : -ENOENT;
goto out;
}
- if (!try_module_get((target->me))) {
- ret = -ENOENT;
- goto out_unlock;
- }
t->u.kernel.target = target;
- up(&arpt_mutex);
if (t->u.kernel.target == &arpt_standard_target) {
if (!standard_check(t, size)) {
@@ -576,8 +622,6 @@ static inline int check_entry(struct arpt_entry *e, const char *name, unsigned i
(*i)++;
return 0;
-out_unlock:
- up(&arpt_mutex);
out:
return ret;
}
@@ -846,8 +890,8 @@ static int get_entries(const struct arpt_get_entries *entries,
int ret;
struct arpt_table *t;
- t = arpt_find_table_lock(entries->name, &ret, &arpt_mutex);
- if (t) {
+ t = find_table_lock(entries->name);
+ if (t || !IS_ERR(t)) {
duprintf("t->private->number = %u\n",
t->private->number);
if (entries->size == t->private->size)
@@ -859,10 +903,10 @@ static int get_entries(const struct arpt_get_entries *entries,
entries->size);
ret = -EINVAL;
}
+ module_put(t->me);
up(&arpt_mutex);
} else
- duprintf("get_entries: Can't find %s!\n",
- entries->name);
+ ret = t ? PTR_ERR(t) : -ENOENT;
return ret;
}
@@ -913,22 +957,19 @@ static int do_replace(void __user *user, unsigned int len)
duprintf("arp_tables: Translated table\n");
- t = arpt_find_table_lock(tmp.name, &ret, &arpt_mutex);
- if (!t)
+ t = try_then_request_module(find_table_lock(tmp.name),
+ "arptable_%s", tmp.name);
+ if (!t || IS_ERR(t)) {
+ ret = t ? PTR_ERR(t) : -ENOENT;
goto free_newinfo_counters_untrans;
+ }
/* You lied! */
if (tmp.valid_hooks != t->valid_hooks) {
duprintf("Valid hook crap: %08X vs %08X\n",
tmp.valid_hooks, t->valid_hooks);
ret = -EINVAL;
- goto free_newinfo_counters_untrans_unlock;
- }
-
- /* Get a reference in advance, we're not allowed fail later */
- if (!try_module_get(t->me)) {
- ret = -EBUSY;
- goto free_newinfo_counters_untrans_unlock;
+ goto put_module;
}
oldinfo = replace_table(t, tmp.num_counters, newinfo, &ret);
@@ -959,7 +1000,6 @@ static int do_replace(void __user *user, unsigned int len)
put_module:
module_put(t->me);
- free_newinfo_counters_untrans_unlock:
up(&arpt_mutex);
free_newinfo_counters_untrans:
ARPT_ENTRY_ITERATE(newinfo->entries, newinfo->size, cleanup_entry, NULL);
@@ -989,7 +1029,7 @@ static int do_add_counters(void __user *user, unsigned int len)
unsigned int i;
struct arpt_counters_info tmp, *paddc;
struct arpt_table *t;
- int ret;
+ int ret = 0;
if (copy_from_user(&tmp, user, sizeof(tmp)) != 0)
return -EFAULT;
@@ -1006,9 +1046,11 @@ static int do_add_counters(void __user *user, unsigned int len)
goto free;
}
- t = arpt_find_table_lock(tmp.name, &ret, &arpt_mutex);
- if (!t)
+ t = find_table_lock(tmp.name);
+ if (!t || IS_ERR(t)) {
+ ret = t ? PTR_ERR(t) : -ENOENT;
goto free;
+ }
write_lock_bh(&t->lock);
if (t->private->number != paddc->num_counters) {
@@ -1025,6 +1067,7 @@ static int do_add_counters(void __user *user, unsigned int len)
unlock_up_free:
write_unlock_bh(&t->lock);
up(&arpt_mutex);
+ module_put(t->me);
free:
vfree(paddc);
@@ -1079,8 +1122,10 @@ static int do_arpt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len
break;
}
name[ARPT_TABLE_MAXNAMELEN-1] = '\0';
- t = arpt_find_table_lock(name, &ret, &arpt_mutex);
- if (t) {
+
+ t = try_then_request_module(find_table_lock(name),
+ "arptable_%s", name);
+ if (t && !IS_ERR(t)) {
struct arpt_getinfo info;
info.valid_hooks = t->valid_hooks;
@@ -1096,9 +1141,10 @@ static int do_arpt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len
ret = -EFAULT;
else
ret = 0;
-
up(&arpt_mutex);
- }
+ module_put(t->me);
+ } else
+ ret = t ? PTR_ERR(t) : -ENOENT;
}
break;
@@ -1119,6 +1165,24 @@ static int do_arpt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len
break;
}
+ case ARPT_SO_GET_REVISION_TARGET: {
+ struct arpt_get_revision rev;
+
+ if (*len != sizeof(rev)) {
+ ret = -EINVAL;
+ break;
+ }
+ if (copy_from_user(&rev, user, sizeof(rev)) != 0) {
+ ret = -EFAULT;
+ break;
+ }
+
+ try_then_request_module(find_revision(rev.name, rev.revision,
+ target_revfn, &ret),
+ "arpt_%s", rev.name);
+ break;
+ }
+
default:
duprintf("do_arpt_get_ctl: unknown request %i\n", cmd);
ret = -EINVAL;
@@ -1136,12 +1200,9 @@ int arpt_register_target(struct arpt_target *target)
if (ret != 0)
return ret;
- if (!list_named_insert(&arpt_target, target)) {
- duprintf("arpt_register_target: `%s' already in list!\n",
- target->name);
- ret = -EINVAL;
- }
+ list_add(&target->list, &arpt_target);
up(&arpt_mutex);
+
return ret;
}
diff --git a/net/ipv4/netfilter/ip_conntrack_core.c b/net/ipv4/netfilter/ip_conntrack_core.c
index 07a80b56e8dc..422ab68ee7fb 100644
--- a/net/ipv4/netfilter/ip_conntrack_core.c
+++ b/net/ipv4/netfilter/ip_conntrack_core.c
@@ -50,7 +50,7 @@
#include <linux/netfilter_ipv4/ip_conntrack_core.h>
#include <linux/netfilter_ipv4/listhelp.h>
-#define IP_CONNTRACK_VERSION "2.3"
+#define IP_CONNTRACK_VERSION "2.4"
#if 0
#define DEBUGP printk
@@ -148,16 +148,20 @@ DEFINE_PER_CPU(struct ip_conntrack_stat, ip_conntrack_stat);
static int ip_conntrack_hash_rnd_initted;
static unsigned int ip_conntrack_hash_rnd;
-static u_int32_t
-hash_conntrack(const struct ip_conntrack_tuple *tuple)
+static u_int32_t __hash_conntrack(const struct ip_conntrack_tuple *tuple,
+ unsigned int size, unsigned int rnd)
{
-#if 0
- dump_tuple(tuple);
-#endif
return (jhash_3words(tuple->src.ip,
(tuple->dst.ip ^ tuple->dst.protonum),
(tuple->src.u.all | (tuple->dst.u.all << 16)),
- ip_conntrack_hash_rnd) % ip_conntrack_htable_size);
+ rnd) % size);
+}
+
+static u_int32_t
+hash_conntrack(const struct ip_conntrack_tuple *tuple)
+{
+ return __hash_conntrack(tuple, ip_conntrack_htable_size,
+ ip_conntrack_hash_rnd);
}
int
@@ -1341,14 +1345,13 @@ static int kill_all(struct ip_conntrack *i, void *data)
return 1;
}
-static void free_conntrack_hash(void)
+static void free_conntrack_hash(struct list_head *hash, int vmalloced,int size)
{
- if (ip_conntrack_vmalloc)
- vfree(ip_conntrack_hash);
+ if (vmalloced)
+ vfree(hash);
else
- free_pages((unsigned long)ip_conntrack_hash,
- get_order(sizeof(struct list_head)
- * ip_conntrack_htable_size));
+ free_pages((unsigned long)hash,
+ get_order(sizeof(struct list_head) * size));
}
void ip_conntrack_flush()
@@ -1378,12 +1381,83 @@ void ip_conntrack_cleanup(void)
ip_conntrack_flush();
kmem_cache_destroy(ip_conntrack_cachep);
kmem_cache_destroy(ip_conntrack_expect_cachep);
- free_conntrack_hash();
+ free_conntrack_hash(ip_conntrack_hash, ip_conntrack_vmalloc,
+ ip_conntrack_htable_size);
nf_unregister_sockopt(&so_getorigdst);
}
-static int hashsize;
-module_param(hashsize, int, 0400);
+static struct list_head *alloc_hashtable(int size, int *vmalloced)
+{
+ struct list_head *hash;
+ unsigned int i;
+
+ *vmalloced = 0;
+ hash = (void*)__get_free_pages(GFP_KERNEL,
+ get_order(sizeof(struct list_head)
+ * size));
+ if (!hash) {
+ *vmalloced = 1;
+ printk(KERN_WARNING"ip_conntrack: falling back to vmalloc.\n");
+ hash = vmalloc(sizeof(struct list_head) * size);
+ }
+
+ if (hash)
+ for (i = 0; i < size; i++)
+ INIT_LIST_HEAD(&hash[i]);
+
+ return hash;
+}
+
+int set_hashsize(const char *val, struct kernel_param *kp)
+{
+ int i, bucket, hashsize, vmalloced;
+ int old_vmalloced, old_size;
+ int rnd;
+ struct list_head *hash, *old_hash;
+ struct ip_conntrack_tuple_hash *h;
+
+ /* On boot, we can set this without any fancy locking. */
+ if (!ip_conntrack_htable_size)
+ return param_set_int(val, kp);
+
+ hashsize = simple_strtol(val, NULL, 0);
+ if (!hashsize)
+ return -EINVAL;
+
+ hash = alloc_hashtable(hashsize, &vmalloced);
+ if (!hash)
+ return -ENOMEM;
+
+ /* We have to rehash for the new table anyway, so we also can
+ * use a new random seed */
+ get_random_bytes(&rnd, 4);
+
+ write_lock_bh(&ip_conntrack_lock);
+ for (i = 0; i < ip_conntrack_htable_size; i++) {
+ while (!list_empty(&ip_conntrack_hash[i])) {
+ h = list_entry(ip_conntrack_hash[i].next,
+ struct ip_conntrack_tuple_hash, list);
+ list_del(&h->list);
+ bucket = __hash_conntrack(&h->tuple, hashsize, rnd);
+ list_add_tail(&h->list, &hash[bucket]);
+ }
+ }
+ old_size = ip_conntrack_htable_size;
+ old_vmalloced = ip_conntrack_vmalloc;
+ old_hash = ip_conntrack_hash;
+
+ ip_conntrack_htable_size = hashsize;
+ ip_conntrack_vmalloc = vmalloced;
+ ip_conntrack_hash = hash;
+ ip_conntrack_hash_rnd = rnd;
+ write_unlock_bh(&ip_conntrack_lock);
+
+ free_conntrack_hash(old_hash, old_vmalloced, old_size);
+ return 0;
+}
+
+module_param_call(hashsize, set_hashsize, param_get_uint,
+ &ip_conntrack_htable_size, 0600);
int __init ip_conntrack_init(void)
{
@@ -1392,9 +1466,7 @@ int __init ip_conntrack_init(void)
/* Idea from tcp.c: use 1/16384 of memory. On i386: 32MB
* machine has 256 buckets. >= 1GB machines have 8192 buckets. */
- if (hashsize) {
- ip_conntrack_htable_size = hashsize;
- } else {
+ if (!ip_conntrack_htable_size) {
ip_conntrack_htable_size
= (((num_physpages << PAGE_SHIFT) / 16384)
/ sizeof(struct list_head));
@@ -1416,20 +1488,8 @@ int __init ip_conntrack_init(void)
return ret;
}
- /* AK: the hash table is twice as big than needed because it
- uses list_head. it would be much nicer to caches to use a
- single pointer list head here. */
- ip_conntrack_vmalloc = 0;
- ip_conntrack_hash
- =(void*)__get_free_pages(GFP_KERNEL,
- get_order(sizeof(struct list_head)
- *ip_conntrack_htable_size));
- if (!ip_conntrack_hash) {
- ip_conntrack_vmalloc = 1;
- printk(KERN_WARNING "ip_conntrack: falling back to vmalloc.\n");
- ip_conntrack_hash = vmalloc(sizeof(struct list_head)
- * ip_conntrack_htable_size);
- }
+ ip_conntrack_hash = alloc_hashtable(ip_conntrack_htable_size,
+ &ip_conntrack_vmalloc);
if (!ip_conntrack_hash) {
printk(KERN_ERR "Unable to create ip_conntrack_hash\n");
goto err_unreg_sockopt;
@@ -1461,9 +1521,6 @@ int __init ip_conntrack_init(void)
ip_ct_protos[IPPROTO_ICMP] = &ip_conntrack_protocol_icmp;
write_unlock_bh(&ip_conntrack_lock);
- for (i = 0; i < ip_conntrack_htable_size; i++)
- INIT_LIST_HEAD(&ip_conntrack_hash[i]);
-
/* For use by ipt_REJECT */
ip_ct_attach = ip_conntrack_attach;
@@ -1478,7 +1535,8 @@ int __init ip_conntrack_init(void)
err_free_conntrack_slab:
kmem_cache_destroy(ip_conntrack_cachep);
err_free_hash:
- free_conntrack_hash();
+ free_conntrack_hash(ip_conntrack_hash, ip_conntrack_vmalloc,
+ ip_conntrack_htable_size);
err_unreg_sockopt:
nf_unregister_sockopt(&so_getorigdst);
diff --git a/net/ipv4/netfilter/ip_conntrack_helper_pptp.c b/net/ipv4/netfilter/ip_conntrack_helper_pptp.c
index 926a6684643d..4108a5e12b3c 100644
--- a/net/ipv4/netfilter/ip_conntrack_helper_pptp.c
+++ b/net/ipv4/netfilter/ip_conntrack_helper_pptp.c
@@ -270,14 +270,10 @@ exp_gre(struct ip_conntrack *master,
exp_orig->expectfn = pptp_expectfn;
exp_orig->flags = 0;
- exp_orig->dir = IP_CT_DIR_ORIGINAL;
-
/* both expectations are identical apart from tuple */
memcpy(exp_reply, exp_orig, sizeof(*exp_reply));
memcpy(&exp_reply->tuple, &exp_tuples[1], sizeof(exp_reply->tuple));
- exp_reply->dir = !exp_orig->dir;
-
if (ip_nat_pptp_hook_exp_gre)
ret = ip_nat_pptp_hook_exp_gre(exp_orig, exp_reply);
else {
diff --git a/net/ipv4/netfilter/ip_conntrack_netlink.c b/net/ipv4/netfilter/ip_conntrack_netlink.c
index 166e6069f121..d2a4fec22862 100644
--- a/net/ipv4/netfilter/ip_conntrack_netlink.c
+++ b/net/ipv4/netfilter/ip_conntrack_netlink.c
@@ -28,11 +28,8 @@
#include <linux/netlink.h>
#include <linux/spinlock.h>
#include <linux/notifier.h>
-#include <linux/rtnetlink.h>
#include <linux/netfilter.h>
-#include <linux/netfilter_ipv4.h>
-#include <linux/netfilter_ipv4/ip_tables.h>
#include <linux/netfilter_ipv4/ip_conntrack.h>
#include <linux/netfilter_ipv4/ip_conntrack_core.h>
#include <linux/netfilter_ipv4/ip_conntrack_helper.h>
@@ -58,14 +55,17 @@ ctnetlink_dump_tuples_proto(struct sk_buff *skb,
const struct ip_conntrack_tuple *tuple)
{
struct ip_conntrack_protocol *proto;
+ int ret = 0;
NFA_PUT(skb, CTA_PROTO_NUM, sizeof(u_int8_t), &tuple->dst.protonum);
proto = ip_conntrack_proto_find_get(tuple->dst.protonum);
- if (proto && proto->tuple_to_nfattr)
- return proto->tuple_to_nfattr(skb, tuple);
+ if (likely(proto && proto->tuple_to_nfattr)) {
+ ret = proto->tuple_to_nfattr(skb, tuple);
+ ip_conntrack_proto_put(proto);
+ }
- return 0;
+ return ret;
nfattr_failure:
return -1;
@@ -175,7 +175,7 @@ ctnetlink_dump_counters(struct sk_buff *skb, const struct ip_conntrack *ct,
{
enum ctattr_type type = dir ? CTA_COUNTERS_REPLY: CTA_COUNTERS_ORIG;
struct nfattr *nest_count = NFA_NEST(skb, type);
- u_int64_t tmp;
+ u_int32_t tmp;
tmp = htonl(ct->counters[dir].packets);
NFA_PUT(skb, CTA_COUNTERS32_PACKETS, sizeof(u_int32_t), &tmp);
@@ -479,9 +479,7 @@ ctnetlink_parse_tuple_ip(struct nfattr *attr, struct ip_conntrack_tuple *tuple)
DEBUGP("entered %s\n", __FUNCTION__);
-
- if (nfattr_parse_nested(tb, CTA_IP_MAX, attr) < 0)
- goto nfattr_failure;
+ nfattr_parse_nested(tb, CTA_IP_MAX, attr);
if (nfattr_bad_size(tb, CTA_IP_MAX, cta_min_ip))
return -EINVAL;
@@ -497,9 +495,6 @@ ctnetlink_parse_tuple_ip(struct nfattr *attr, struct ip_conntrack_tuple *tuple)
DEBUGP("leaving\n");
return 0;
-
-nfattr_failure:
- return -1;
}
static const int cta_min_proto[CTA_PROTO_MAX] = {
@@ -521,8 +516,7 @@ ctnetlink_parse_tuple_proto(struct nfattr *attr,
DEBUGP("entered %s\n", __FUNCTION__);
- if (nfattr_parse_nested(tb, CTA_PROTO_MAX, attr) < 0)
- goto nfattr_failure;
+ nfattr_parse_nested(tb, CTA_PROTO_MAX, attr);
if (nfattr_bad_size(tb, CTA_PROTO_MAX, cta_min_proto))
return -EINVAL;
@@ -539,9 +533,6 @@ ctnetlink_parse_tuple_proto(struct nfattr *attr,
}
return ret;
-
-nfattr_failure:
- return -1;
}
static inline int
@@ -555,8 +546,7 @@ ctnetlink_parse_tuple(struct nfattr *cda[], struct ip_conntrack_tuple *tuple,
memset(tuple, 0, sizeof(*tuple));
- if (nfattr_parse_nested(tb, CTA_TUPLE_MAX, cda[type-1]) < 0)
- goto nfattr_failure;
+ nfattr_parse_nested(tb, CTA_TUPLE_MAX, cda[type-1]);
if (!tb[CTA_TUPLE_IP-1])
return -EINVAL;
@@ -583,9 +573,6 @@ ctnetlink_parse_tuple(struct nfattr *cda[], struct ip_conntrack_tuple *tuple,
DEBUGP("leaving\n");
return 0;
-
-nfattr_failure:
- return -1;
}
#ifdef CONFIG_IP_NF_NAT_NEEDED
@@ -603,11 +590,10 @@ static int ctnetlink_parse_nat_proto(struct nfattr *attr,
DEBUGP("entered %s\n", __FUNCTION__);
- if (nfattr_parse_nested(tb, CTA_PROTONAT_MAX, attr) < 0)
- goto nfattr_failure;
+ nfattr_parse_nested(tb, CTA_PROTONAT_MAX, attr);
if (nfattr_bad_size(tb, CTA_PROTONAT_MAX, cta_min_protonat))
- goto nfattr_failure;
+ return -EINVAL;
npt = ip_nat_proto_find_get(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum);
if (!npt)
@@ -626,9 +612,6 @@ static int ctnetlink_parse_nat_proto(struct nfattr *attr,
DEBUGP("leaving\n");
return 0;
-
-nfattr_failure:
- return -1;
}
static inline int
@@ -642,8 +625,7 @@ ctnetlink_parse_nat(struct nfattr *cda[],
memset(range, 0, sizeof(*range));
- if (nfattr_parse_nested(tb, CTA_NAT_MAX, cda[CTA_NAT-1]) < 0)
- goto nfattr_failure;
+ nfattr_parse_nested(tb, CTA_NAT_MAX, cda[CTA_NAT-1]);
if (tb[CTA_NAT_MINIP-1])
range->min_ip = *(u_int32_t *)NFA_DATA(tb[CTA_NAT_MINIP-1]);
@@ -665,9 +647,6 @@ ctnetlink_parse_nat(struct nfattr *cda[],
DEBUGP("leaving\n");
return 0;
-
-nfattr_failure:
- return -1;
}
#endif
@@ -678,8 +657,7 @@ ctnetlink_parse_help(struct nfattr *attr, char **helper_name)
DEBUGP("entered %s\n", __FUNCTION__);
- if (nfattr_parse_nested(tb, CTA_HELP_MAX, attr) < 0)
- goto nfattr_failure;
+ nfattr_parse_nested(tb, CTA_HELP_MAX, attr);
if (!tb[CTA_HELP_NAME-1])
return -EINVAL;
@@ -687,9 +665,6 @@ ctnetlink_parse_help(struct nfattr *attr, char **helper_name)
*helper_name = NFA_DATA(tb[CTA_HELP_NAME-1]);
return 0;
-
-nfattr_failure:
- return -1;
}
static int
@@ -804,7 +779,7 @@ ctnetlink_get_conntrack(struct sock *ctnl, struct sk_buff *skb,
ct = tuplehash_to_ctrack(h);
err = -ENOMEM;
- skb2 = alloc_skb(NLMSG_GOODSIZE, GFP_ATOMIC);
+ skb2 = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
if (!skb2) {
ip_conntrack_put(ct);
return -ENOMEM;
@@ -815,7 +790,7 @@ ctnetlink_get_conntrack(struct sock *ctnl, struct sk_buff *skb,
IPCTNL_MSG_CT_NEW, 1, ct);
ip_conntrack_put(ct);
if (err <= 0)
- goto out;
+ goto free;
err = netlink_unicast(ctnl, skb2, NETLINK_CB(skb).pid, MSG_DONTWAIT);
if (err < 0)
@@ -824,10 +799,10 @@ ctnetlink_get_conntrack(struct sock *ctnl, struct sk_buff *skb,
DEBUGP("leaving\n");
return 0;
+free:
+ kfree_skb(skb2);
out:
- if (skb2)
- kfree_skb(skb2);
- return -1;
+ return err;
}
static inline int
@@ -957,8 +932,7 @@ ctnetlink_change_protoinfo(struct ip_conntrack *ct, struct nfattr *cda[])
u_int16_t npt = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum;
int err = 0;
- if (nfattr_parse_nested(tb, CTA_PROTOINFO_MAX, attr) < 0)
- goto nfattr_failure;
+ nfattr_parse_nested(tb, CTA_PROTOINFO_MAX, attr);
proto = ip_conntrack_proto_find_get(npt);
if (!proto)
@@ -969,9 +943,6 @@ ctnetlink_change_protoinfo(struct ip_conntrack *ct, struct nfattr *cda[])
ip_conntrack_proto_put(proto);
return err;
-
-nfattr_failure:
- return -ENOMEM;
}
static int
@@ -1005,6 +976,11 @@ ctnetlink_change_conntrack(struct ip_conntrack *ct, struct nfattr *cda[])
return err;
}
+#if defined(CONFIG_IP_NF_CONNTRACK_MARK)
+ if (cda[CTA_MARK-1])
+ ct->mark = ntohl(*(u_int32_t *)NFA_DATA(cda[CTA_MARK-1]));
+#endif
+
DEBUGP("all done\n");
return 0;
}
@@ -1048,6 +1024,11 @@ ctnetlink_create_conntrack(struct nfattr *cda[],
if (ct->helper)
ip_conntrack_helper_put(ct->helper);
+#if defined(CONFIG_IP_NF_CONNTRACK_MARK)
+ if (cda[CTA_MARK-1])
+ ct->mark = ntohl(*(u_int32_t *)NFA_DATA(cda[CTA_MARK-1]));
+#endif
+
DEBUGP("conntrack with id %u inserted\n", ct->id);
return 0;
@@ -1312,6 +1293,14 @@ ctnetlink_get_expect(struct sock *ctnl, struct sk_buff *skb,
if (!exp)
return -ENOENT;
+ if (cda[CTA_EXPECT_ID-1]) {
+ u_int32_t id = *(u_int32_t *)NFA_DATA(cda[CTA_EXPECT_ID-1]);
+ if (exp->id != ntohl(id)) {
+ ip_conntrack_expect_put(exp);
+ return -ENOENT;
+ }
+ }
+
err = -ENOMEM;
skb2 = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
if (!skb2)
@@ -1322,21 +1311,16 @@ ctnetlink_get_expect(struct sock *ctnl, struct sk_buff *skb,
nlh->nlmsg_seq, IPCTNL_MSG_EXP_NEW,
1, exp);
if (err <= 0)
- goto out;
+ goto free;
ip_conntrack_expect_put(exp);
- err = netlink_unicast(ctnl, skb2, NETLINK_CB(skb).pid, MSG_DONTWAIT);
- if (err < 0)
- goto free;
-
- return err;
+ return netlink_unicast(ctnl, skb2, NETLINK_CB(skb).pid, MSG_DONTWAIT);
+free:
+ kfree_skb(skb2);
out:
ip_conntrack_expect_put(exp);
-free:
- if (skb2)
- kfree_skb(skb2);
return err;
}
@@ -1392,7 +1376,7 @@ ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb,
ip_conntrack_expect_put(exp);
}
}
- write_unlock(&ip_conntrack_lock);
+ write_unlock_bh(&ip_conntrack_lock);
} else {
/* This basically means we have to flush everything*/
write_lock_bh(&ip_conntrack_lock);
@@ -1559,6 +1543,8 @@ static struct nfnetlink_subsystem ctnl_exp_subsys = {
.cb = ctnl_exp_cb,
};
+MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_CTNETLINK);
+
static int __init ctnetlink_init(void)
{
int ret;
diff --git a/net/ipv4/netfilter/ip_conntrack_proto_icmp.c b/net/ipv4/netfilter/ip_conntrack_proto_icmp.c
index 98f0015dd255..e4d6b268e8c4 100644
--- a/net/ipv4/netfilter/ip_conntrack_proto_icmp.c
+++ b/net/ipv4/netfilter/ip_conntrack_proto_icmp.c
@@ -13,6 +13,7 @@
#include <linux/in.h>
#include <linux/icmp.h>
#include <linux/seq_file.h>
+#include <linux/skbuff.h>
#include <net/ip.h>
#include <net/checksum.h>
#include <linux/netfilter.h>
@@ -151,13 +152,13 @@ icmp_error_message(struct sk_buff *skb,
/* Not enough header? */
inside = skb_header_pointer(skb, skb->nh.iph->ihl*4, sizeof(_in), &_in);
if (inside == NULL)
- return NF_ACCEPT;
+ return -NF_ACCEPT;
/* Ignore ICMP's containing fragments (shouldn't happen) */
if (inside->ip.frag_off & htons(IP_OFFSET)) {
DEBUGP("icmp_error_track: fragment of proto %u\n",
inside->ip.protocol);
- return NF_ACCEPT;
+ return -NF_ACCEPT;
}
innerproto = ip_conntrack_proto_find_get(inside->ip.protocol);
@@ -166,7 +167,7 @@ icmp_error_message(struct sk_buff *skb,
if (!ip_ct_get_tuple(&inside->ip, skb, dataoff, &origtuple, innerproto)) {
DEBUGP("icmp_error: ! get_tuple p=%u", inside->ip.protocol);
ip_conntrack_proto_put(innerproto);
- return NF_ACCEPT;
+ return -NF_ACCEPT;
}
/* Ordinarily, we'd expect the inverted tupleproto, but it's
@@ -174,7 +175,7 @@ icmp_error_message(struct sk_buff *skb,
if (!ip_ct_invert_tuple(&innertuple, &origtuple, innerproto)) {
DEBUGP("icmp_error_track: Can't invert tuple\n");
ip_conntrack_proto_put(innerproto);
- return NF_ACCEPT;
+ return -NF_ACCEPT;
}
ip_conntrack_proto_put(innerproto);
@@ -190,7 +191,7 @@ icmp_error_message(struct sk_buff *skb,
if (!h) {
DEBUGP("icmp_error_track: no match\n");
- return NF_ACCEPT;
+ return -NF_ACCEPT;
}
/* Reverse direction from that found */
if (DIRECTION(h) != IP_CT_DIR_REPLY)
@@ -230,19 +231,15 @@ icmp_error(struct sk_buff *skb, enum ip_conntrack_info *ctinfo,
case CHECKSUM_HW:
if (!(u16)csum_fold(skb->csum))
break;
- if (LOG_INVALID(IPPROTO_ICMP))
- nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL,
- "ip_ct_icmp: bad HW ICMP checksum ");
- return -NF_ACCEPT;
+ /* fall through */
case CHECKSUM_NONE:
- if ((u16)csum_fold(skb_checksum(skb, 0, skb->len, 0))) {
+ skb->csum = 0;
+ if (__skb_checksum_complete(skb)) {
if (LOG_INVALID(IPPROTO_ICMP))
nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL,
"ip_ct_icmp: bad ICMP checksum ");
return -NF_ACCEPT;
}
- default:
- break;
}
checksum_skipped:
@@ -296,7 +293,8 @@ static int icmp_nfattr_to_tuple(struct nfattr *tb[],
struct ip_conntrack_tuple *tuple)
{
if (!tb[CTA_PROTO_ICMP_TYPE-1]
- || !tb[CTA_PROTO_ICMP_CODE-1])
+ || !tb[CTA_PROTO_ICMP_CODE-1]
+ || !tb[CTA_PROTO_ICMP_ID-1])
return -1;
tuple->dst.u.icmp.type =
@@ -304,7 +302,7 @@ static int icmp_nfattr_to_tuple(struct nfattr *tb[],
tuple->dst.u.icmp.code =
*(u_int8_t *)NFA_DATA(tb[CTA_PROTO_ICMP_CODE-1]);
tuple->src.u.icmp.id =
- *(u_int8_t *)NFA_DATA(tb[CTA_PROTO_ICMP_ID-1]);
+ *(u_int16_t *)NFA_DATA(tb[CTA_PROTO_ICMP_ID-1]);
return 0;
}
diff --git a/net/ipv4/netfilter/ip_conntrack_proto_tcp.c b/net/ipv4/netfilter/ip_conntrack_proto_tcp.c
index d6701cafbcc2..468c6003b4c7 100644
--- a/net/ipv4/netfilter/ip_conntrack_proto_tcp.c
+++ b/net/ipv4/netfilter/ip_conntrack_proto_tcp.c
@@ -362,8 +362,12 @@ static int nfattr_to_tcp(struct nfattr *cda[], struct ip_conntrack *ct)
struct nfattr *attr = cda[CTA_PROTOINFO_TCP-1];
struct nfattr *tb[CTA_PROTOINFO_TCP_MAX];
- if (nfattr_parse_nested(tb, CTA_PROTOINFO_TCP_MAX, attr) < 0)
- goto nfattr_failure;
+ /* updates could not contain anything about the private
+ * protocol info, in that case skip the parsing */
+ if (!attr)
+ return 0;
+
+ nfattr_parse_nested(tb, CTA_PROTOINFO_TCP_MAX, attr);
if (!tb[CTA_PROTOINFO_TCP_STATE-1])
return -EINVAL;
@@ -374,9 +378,6 @@ static int nfattr_to_tcp(struct nfattr *cda[], struct ip_conntrack *ct)
write_unlock_bh(&tcp_lock);
return 0;
-
-nfattr_failure:
- return -1;
}
#endif
diff --git a/net/ipv4/netfilter/ip_nat_core.c b/net/ipv4/netfilter/ip_nat_core.c
index c5e3abd24672..762f4d93936b 100644
--- a/net/ipv4/netfilter/ip_nat_core.c
+++ b/net/ipv4/netfilter/ip_nat_core.c
@@ -66,10 +66,8 @@ ip_nat_proto_find_get(u_int8_t protonum)
* removed until we've grabbed the reference */
preempt_disable();
p = __ip_nat_proto_find(protonum);
- if (p) {
- if (!try_module_get(p->me))
- p = &ip_nat_unknown_protocol;
- }
+ if (!try_module_get(p->me))
+ p = &ip_nat_unknown_protocol;
preempt_enable();
return p;
diff --git a/net/ipv4/netfilter/ip_nat_helper_pptp.c b/net/ipv4/netfilter/ip_nat_helper_pptp.c
index 3cdd0684d30d..e546203f5662 100644
--- a/net/ipv4/netfilter/ip_nat_helper_pptp.c
+++ b/net/ipv4/netfilter/ip_nat_helper_pptp.c
@@ -73,6 +73,7 @@ static void pptp_nat_expected(struct ip_conntrack *ct,
struct ip_conntrack_tuple t;
struct ip_ct_pptp_master *ct_pptp_info;
struct ip_nat_pptp *nat_pptp_info;
+ struct ip_nat_range range;
ct_pptp_info = &master->help.ct_pptp_info;
nat_pptp_info = &master->nat.help.nat_pptp_info;
@@ -110,7 +111,30 @@ static void pptp_nat_expected(struct ip_conntrack *ct,
DEBUGP("not found!\n");
}
- ip_nat_follow_master(ct, exp);
+ /* This must be a fresh one. */
+ BUG_ON(ct->status & IPS_NAT_DONE_MASK);
+
+ /* Change src to where master sends to */
+ range.flags = IP_NAT_RANGE_MAP_IPS;
+ range.min_ip = range.max_ip
+ = ct->master->tuplehash[!exp->dir].tuple.dst.ip;
+ if (exp->dir == IP_CT_DIR_ORIGINAL) {
+ range.flags |= IP_NAT_RANGE_PROTO_SPECIFIED;
+ range.min = range.max = exp->saved_proto;
+ }
+ /* hook doesn't matter, but it has to do source manip */
+ ip_nat_setup_info(ct, &range, NF_IP_POST_ROUTING);
+
+ /* For DST manip, map port here to where it's expected. */
+ range.flags = IP_NAT_RANGE_MAP_IPS;
+ range.min_ip = range.max_ip
+ = ct->master->tuplehash[!exp->dir].tuple.src.ip;
+ if (exp->dir == IP_CT_DIR_REPLY) {
+ range.flags |= IP_NAT_RANGE_PROTO_SPECIFIED;
+ range.min = range.max = exp->saved_proto;
+ }
+ /* hook doesn't matter, but it has to do destination manip */
+ ip_nat_setup_info(ct, &range, NF_IP_PRE_ROUTING);
}
/* outbound packets == from PNS to PAC */
@@ -213,9 +237,10 @@ pptp_exp_gre(struct ip_conntrack_expect *expect_orig,
/* alter expectation for PNS->PAC direction */
invert_tuplepr(&inv_t, &expect_orig->tuple);
- expect_orig->saved_proto.gre.key = htons(nat_pptp_info->pac_call_id);
+ expect_orig->saved_proto.gre.key = htons(ct_pptp_info->pns_call_id);
expect_orig->tuple.src.u.gre.key = htons(nat_pptp_info->pns_call_id);
expect_orig->tuple.dst.u.gre.key = htons(ct_pptp_info->pac_call_id);
+ expect_orig->dir = IP_CT_DIR_ORIGINAL;
inv_t.src.ip = reply_t->src.ip;
inv_t.dst.ip = reply_t->dst.ip;
inv_t.src.u.gre.key = htons(nat_pptp_info->pac_call_id);
@@ -233,6 +258,7 @@ pptp_exp_gre(struct ip_conntrack_expect *expect_orig,
expect_reply->saved_proto.gre.key = htons(nat_pptp_info->pns_call_id);
expect_reply->tuple.src.u.gre.key = htons(nat_pptp_info->pac_call_id);
expect_reply->tuple.dst.u.gre.key = htons(ct_pptp_info->pns_call_id);
+ expect_reply->dir = IP_CT_DIR_REPLY;
inv_t.src.ip = orig_t->src.ip;
inv_t.dst.ip = orig_t->dst.ip;
inv_t.src.u.gre.key = htons(nat_pptp_info->pns_call_id);
diff --git a/net/ipv4/netfilter/ip_nat_proto_gre.c b/net/ipv4/netfilter/ip_nat_proto_gre.c
index 7c1285401672..f7cad7cf1aec 100644
--- a/net/ipv4/netfilter/ip_nat_proto_gre.c
+++ b/net/ipv4/netfilter/ip_nat_proto_gre.c
@@ -139,8 +139,8 @@ gre_manip_pkt(struct sk_buff **pskb,
break;
case GRE_VERSION_PPTP:
DEBUGP("call_id -> 0x%04x\n",
- ntohl(tuple->dst.u.gre.key));
- pgreh->call_id = htons(ntohl(tuple->dst.u.gre.key));
+ ntohs(tuple->dst.u.gre.key));
+ pgreh->call_id = tuple->dst.u.gre.key;
break;
default:
DEBUGP("can't nat unknown GRE version\n");
diff --git a/net/ipv4/netfilter/ip_nat_proto_unknown.c b/net/ipv4/netfilter/ip_nat_proto_unknown.c
index 99bbef56f84e..f0099a646a0b 100644
--- a/net/ipv4/netfilter/ip_nat_proto_unknown.c
+++ b/net/ipv4/netfilter/ip_nat_proto_unknown.c
@@ -62,7 +62,7 @@ unknown_print_range(char *buffer, const struct ip_nat_range *range)
struct ip_nat_protocol ip_nat_unknown_protocol = {
.name = "unknown",
- .me = THIS_MODULE,
+ /* .me isn't set: getting a ref to this cannot fail. */
.manip_pkt = unknown_manip_pkt,
.in_range = unknown_in_range,
.unique_tuple = unknown_unique_tuple,
diff --git a/net/ipv4/netfilter/ip_nat_snmp_basic.c b/net/ipv4/netfilter/ip_nat_snmp_basic.c
index 93b2c5111bb2..8acb7ed40b47 100644
--- a/net/ipv4/netfilter/ip_nat_snmp_basic.c
+++ b/net/ipv4/netfilter/ip_nat_snmp_basic.c
@@ -1161,8 +1161,7 @@ static int snmp_parse_mangle(unsigned char *msg,
if (!snmp_object_decode(&ctx, obj)) {
if (*obj) {
- if ((*obj)->id)
- kfree((*obj)->id);
+ kfree((*obj)->id);
kfree(*obj);
}
kfree(obj);
diff --git a/net/ipv4/netfilter/ipt_CLUSTERIP.c b/net/ipv4/netfilter/ipt_CLUSTERIP.c
index 9bcb398fbc1f..45c52d8f4d99 100644
--- a/net/ipv4/netfilter/ipt_CLUSTERIP.c
+++ b/net/ipv4/netfilter/ipt_CLUSTERIP.c
@@ -29,7 +29,7 @@
#include <linux/netfilter_ipv4/ip_tables.h>
#include <linux/netfilter_ipv4/ipt_CLUSTERIP.h>
-#include <linux/netfilter_ipv4/ip_conntrack.h>
+#include <net/netfilter/nf_conntrack_compat.h>
#define CLUSTERIP_VERSION "0.8"
@@ -316,14 +316,14 @@ target(struct sk_buff **pskb,
{
const struct ipt_clusterip_tgt_info *cipinfo = targinfo;
enum ip_conntrack_info ctinfo;
- struct ip_conntrack *ct = ip_conntrack_get((*pskb), &ctinfo);
- u_int32_t hash;
+ u_int32_t *mark, hash;
/* don't need to clusterip_config_get() here, since refcount
* is only decremented by destroy() - and ip_tables guarantees
* that the ->target() function isn't called after ->destroy() */
- if (!ct) {
+ mark = nf_ct_get_mark((*pskb), &ctinfo);
+ if (mark == NULL) {
printk(KERN_ERR "CLUSTERIP: no conntrack!\n");
/* FIXME: need to drop invalid ones, since replies
* to outgoing connections of other nodes will be
@@ -346,7 +346,7 @@ target(struct sk_buff **pskb,
switch (ctinfo) {
case IP_CT_NEW:
- ct->mark = hash;
+ *mark = hash;
break;
case IP_CT_RELATED:
case IP_CT_RELATED+IP_CT_IS_REPLY:
@@ -363,7 +363,7 @@ target(struct sk_buff **pskb,
#ifdef DEBUG_CLUSTERP
DUMP_TUPLE(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple);
#endif
- DEBUGP("hash=%u ct_hash=%u ", hash, ct->mark);
+ DEBUGP("hash=%u ct_hash=%u ", hash, *mark);
if (!clusterip_responsible(cipinfo->config, hash)) {
DEBUGP("not responsible\n");
return NF_DROP;
diff --git a/net/ipv4/netfilter/ipt_CONNMARK.c b/net/ipv4/netfilter/ipt_CONNMARK.c
index 134638021339..8acac5a40a92 100644
--- a/net/ipv4/netfilter/ipt_CONNMARK.c
+++ b/net/ipv4/netfilter/ipt_CONNMARK.c
@@ -29,7 +29,7 @@ MODULE_LICENSE("GPL");
#include <linux/netfilter_ipv4/ip_tables.h>
#include <linux/netfilter_ipv4/ipt_CONNMARK.h>
-#include <linux/netfilter_ipv4/ip_conntrack.h>
+#include <net/netfilter/nf_conntrack_compat.h>
static unsigned int
target(struct sk_buff **pskb,
@@ -43,24 +43,24 @@ target(struct sk_buff **pskb,
u_int32_t diff;
u_int32_t nfmark;
u_int32_t newmark;
+ u_int32_t ctinfo;
+ u_int32_t *ctmark = nf_ct_get_mark(*pskb, &ctinfo);
- enum ip_conntrack_info ctinfo;
- struct ip_conntrack *ct = ip_conntrack_get((*pskb), &ctinfo);
- if (ct) {
+ if (ctmark) {
switch(markinfo->mode) {
case IPT_CONNMARK_SET:
- newmark = (ct->mark & ~markinfo->mask) | markinfo->mark;
- if (newmark != ct->mark)
- ct->mark = newmark;
+ newmark = (*ctmark & ~markinfo->mask) | markinfo->mark;
+ if (newmark != *ctmark)
+ *ctmark = newmark;
break;
case IPT_CONNMARK_SAVE:
- newmark = (ct->mark & ~markinfo->mask) | ((*pskb)->nfmark & markinfo->mask);
- if (ct->mark != newmark)
- ct->mark = newmark;
+ newmark = (*ctmark & ~markinfo->mask) | ((*pskb)->nfmark & markinfo->mask);
+ if (*ctmark != newmark)
+ *ctmark = newmark;
break;
case IPT_CONNMARK_RESTORE:
nfmark = (*pskb)->nfmark;
- diff = (ct->mark ^ nfmark) & markinfo->mask;
+ diff = (*ctmark ^ nfmark) & markinfo->mask;
if (diff != 0)
(*pskb)->nfmark = nfmark ^ diff;
break;
@@ -109,6 +109,7 @@ static struct ipt_target ipt_connmark_reg = {
static int __init init(void)
{
+ need_ip_conntrack();
return ipt_register_target(&ipt_connmark_reg);
}
diff --git a/net/ipv4/netfilter/ipt_NOTRACK.c b/net/ipv4/netfilter/ipt_NOTRACK.c
index a4bb9b3bc292..e3c69d072c6e 100644
--- a/net/ipv4/netfilter/ipt_NOTRACK.c
+++ b/net/ipv4/netfilter/ipt_NOTRACK.c
@@ -5,7 +5,7 @@
#include <linux/skbuff.h>
#include <linux/netfilter_ipv4/ip_tables.h>
-#include <linux/netfilter_ipv4/ip_conntrack.h>
+#include <net/netfilter/nf_conntrack_compat.h>
static unsigned int
target(struct sk_buff **pskb,
@@ -23,7 +23,7 @@ target(struct sk_buff **pskb,
If there is a real ct entry correspondig to this packet,
it'll hang aroun till timing out. We don't deal with it
for performance reasons. JK */
- (*pskb)->nfct = &ip_conntrack_untracked.ct_general;
+ nf_ct_untrack(*pskb);
(*pskb)->nfctinfo = IP_CT_NEW;
nf_conntrack_get((*pskb)->nfct);
diff --git a/net/ipv4/netfilter/ipt_addrtype.c b/net/ipv4/netfilter/ipt_addrtype.c
index f5909a4c3fc7..e19c2a52d00c 100644
--- a/net/ipv4/netfilter/ipt_addrtype.c
+++ b/net/ipv4/netfilter/ipt_addrtype.c
@@ -48,7 +48,7 @@ static int checkentry(const char *tablename, const struct ipt_ip *ip,
unsigned int hook_mask)
{
if (matchsize != IPT_ALIGN(sizeof(struct ipt_addrtype_info))) {
- printk(KERN_ERR "ipt_addrtype: invalid size (%u != %Zu)\n.",
+ printk(KERN_ERR "ipt_addrtype: invalid size (%u != %Zu)\n",
matchsize, IPT_ALIGN(sizeof(struct ipt_addrtype_info)));
return 0;
}
diff --git a/net/ipv4/netfilter/ipt_connbytes.c b/net/ipv4/netfilter/ipt_connbytes.c
index df4a42c6da22..d68a048b7176 100644
--- a/net/ipv4/netfilter/ipt_connbytes.c
+++ b/net/ipv4/netfilter/ipt_connbytes.c
@@ -10,7 +10,7 @@
*/
#include <linux/module.h>
#include <linux/skbuff.h>
-#include <linux/netfilter_ipv4/ip_conntrack.h>
+#include <net/netfilter/nf_conntrack_compat.h>
#include <linux/netfilter_ipv4/ip_tables.h>
#include <linux/netfilter_ipv4/ipt_connbytes.h>
@@ -46,60 +46,59 @@ match(const struct sk_buff *skb,
int *hotdrop)
{
const struct ipt_connbytes_info *sinfo = matchinfo;
- enum ip_conntrack_info ctinfo;
- struct ip_conntrack *ct;
u_int64_t what = 0; /* initialize to make gcc happy */
+ const struct ip_conntrack_counter *counters;
- if (!(ct = ip_conntrack_get((struct sk_buff *)skb, &ctinfo)))
+ if (!(counters = nf_ct_get_counters(skb)))
return 0; /* no match */
switch (sinfo->what) {
case IPT_CONNBYTES_PKTS:
switch (sinfo->direction) {
case IPT_CONNBYTES_DIR_ORIGINAL:
- what = ct->counters[IP_CT_DIR_ORIGINAL].packets;
+ what = counters[IP_CT_DIR_ORIGINAL].packets;
break;
case IPT_CONNBYTES_DIR_REPLY:
- what = ct->counters[IP_CT_DIR_REPLY].packets;
+ what = counters[IP_CT_DIR_REPLY].packets;
break;
case IPT_CONNBYTES_DIR_BOTH:
- what = ct->counters[IP_CT_DIR_ORIGINAL].packets;
- what += ct->counters[IP_CT_DIR_REPLY].packets;
+ what = counters[IP_CT_DIR_ORIGINAL].packets;
+ what += counters[IP_CT_DIR_REPLY].packets;
break;
}
break;
case IPT_CONNBYTES_BYTES:
switch (sinfo->direction) {
case IPT_CONNBYTES_DIR_ORIGINAL:
- what = ct->counters[IP_CT_DIR_ORIGINAL].bytes;
+ what = counters[IP_CT_DIR_ORIGINAL].bytes;
break;
case IPT_CONNBYTES_DIR_REPLY:
- what = ct->counters[IP_CT_DIR_REPLY].bytes;
+ what = counters[IP_CT_DIR_REPLY].bytes;
break;
case IPT_CONNBYTES_DIR_BOTH:
- what = ct->counters[IP_CT_DIR_ORIGINAL].bytes;
- what += ct->counters[IP_CT_DIR_REPLY].bytes;
+ what = counters[IP_CT_DIR_ORIGINAL].bytes;
+ what += counters[IP_CT_DIR_REPLY].bytes;
break;
}
break;
case IPT_CONNBYTES_AVGPKT:
switch (sinfo->direction) {
case IPT_CONNBYTES_DIR_ORIGINAL:
- what = div64_64(ct->counters[IP_CT_DIR_ORIGINAL].bytes,
- ct->counters[IP_CT_DIR_ORIGINAL].packets);
+ what = div64_64(counters[IP_CT_DIR_ORIGINAL].bytes,
+ counters[IP_CT_DIR_ORIGINAL].packets);
break;
case IPT_CONNBYTES_DIR_REPLY:
- what = div64_64(ct->counters[IP_CT_DIR_REPLY].bytes,
- ct->counters[IP_CT_DIR_REPLY].packets);
+ what = div64_64(counters[IP_CT_DIR_REPLY].bytes,
+ counters[IP_CT_DIR_REPLY].packets);
break;
case IPT_CONNBYTES_DIR_BOTH:
{
u_int64_t bytes;
u_int64_t pkts;
- bytes = ct->counters[IP_CT_DIR_ORIGINAL].bytes +
- ct->counters[IP_CT_DIR_REPLY].bytes;
- pkts = ct->counters[IP_CT_DIR_ORIGINAL].packets+
- ct->counters[IP_CT_DIR_REPLY].packets;
+ bytes = counters[IP_CT_DIR_ORIGINAL].bytes +
+ counters[IP_CT_DIR_REPLY].bytes;
+ pkts = counters[IP_CT_DIR_ORIGINAL].packets+
+ counters[IP_CT_DIR_REPLY].packets;
/* FIXME_THEORETICAL: what to do if sum
* overflows ? */
diff --git a/net/ipv4/netfilter/ipt_connmark.c b/net/ipv4/netfilter/ipt_connmark.c
index bf8de47ce004..5306ef293b92 100644
--- a/net/ipv4/netfilter/ipt_connmark.c
+++ b/net/ipv4/netfilter/ipt_connmark.c
@@ -28,7 +28,7 @@ MODULE_LICENSE("GPL");
#include <linux/netfilter_ipv4/ip_tables.h>
#include <linux/netfilter_ipv4/ipt_connmark.h>
-#include <linux/netfilter_ipv4/ip_conntrack.h>
+#include <net/netfilter/nf_conntrack_compat.h>
static int
match(const struct sk_buff *skb,
@@ -39,12 +39,12 @@ match(const struct sk_buff *skb,
int *hotdrop)
{
const struct ipt_connmark_info *info = matchinfo;
- enum ip_conntrack_info ctinfo;
- struct ip_conntrack *ct = ip_conntrack_get((struct sk_buff *)skb, &ctinfo);
- if (!ct)
+ u_int32_t ctinfo;
+ const u_int32_t *ctmark = nf_ct_get_mark(skb, &ctinfo);
+ if (!ctmark)
return 0;
- return ((ct->mark & info->mask) == info->mark) ^ info->invert;
+ return (((*ctmark) & info->mask) == info->mark) ^ info->invert;
}
static int
diff --git a/net/ipv4/netfilter/ipt_conntrack.c b/net/ipv4/netfilter/ipt_conntrack.c
index c1d22801b7cf..c8d18705469b 100644
--- a/net/ipv4/netfilter/ipt_conntrack.c
+++ b/net/ipv4/netfilter/ipt_conntrack.c
@@ -10,7 +10,14 @@
#include <linux/module.h>
#include <linux/skbuff.h>
+
+#if defined(CONFIG_IP_NF_CONNTRACK) || defined(CONFIG_IP_NF_CONNTRACK_MODULE)
#include <linux/netfilter_ipv4/ip_conntrack.h>
+#include <linux/netfilter_ipv4/ip_conntrack_tuple.h>
+#else
+#include <net/netfilter/nf_conntrack.h>
+#endif
+
#include <linux/netfilter_ipv4/ip_tables.h>
#include <linux/netfilter_ipv4/ipt_conntrack.h>
@@ -18,6 +25,8 @@ MODULE_LICENSE("GPL");
MODULE_AUTHOR("Marc Boucher <marc@mbsi.ca>");
MODULE_DESCRIPTION("iptables connection tracking match module");
+#if defined(CONFIG_IP_NF_CONNTRACK) || defined(CONFIG_IP_NF_CONNTRACK_MODULE)
+
static int
match(const struct sk_buff *skb,
const struct net_device *in,
@@ -102,6 +111,93 @@ match(const struct sk_buff *skb,
return 1;
}
+#else /* CONFIG_IP_NF_CONNTRACK */
+static int
+match(const struct sk_buff *skb,
+ const struct net_device *in,
+ const struct net_device *out,
+ const void *matchinfo,
+ int offset,
+ int *hotdrop)
+{
+ const struct ipt_conntrack_info *sinfo = matchinfo;
+ struct nf_conn *ct;
+ enum ip_conntrack_info ctinfo;
+ unsigned int statebit;
+
+ ct = nf_ct_get((struct sk_buff *)skb, &ctinfo);
+
+#define FWINV(bool,invflg) ((bool) ^ !!(sinfo->invflags & invflg))
+
+ if (ct == &nf_conntrack_untracked)
+ statebit = IPT_CONNTRACK_STATE_UNTRACKED;
+ else if (ct)
+ statebit = IPT_CONNTRACK_STATE_BIT(ctinfo);
+ else
+ statebit = IPT_CONNTRACK_STATE_INVALID;
+
+ if(sinfo->flags & IPT_CONNTRACK_STATE) {
+ if (ct) {
+ if(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u3.ip !=
+ ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u3.ip)
+ statebit |= IPT_CONNTRACK_STATE_SNAT;
+
+ if(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.u3.ip !=
+ ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.u3.ip)
+ statebit |= IPT_CONNTRACK_STATE_DNAT;
+ }
+
+ if (FWINV((statebit & sinfo->statemask) == 0, IPT_CONNTRACK_STATE))
+ return 0;
+ }
+
+ if(sinfo->flags & IPT_CONNTRACK_PROTO) {
+ if (!ct || FWINV(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum != sinfo->tuple[IP_CT_DIR_ORIGINAL].dst.protonum, IPT_CONNTRACK_PROTO))
+ return 0;
+ }
+
+ if(sinfo->flags & IPT_CONNTRACK_ORIGSRC) {
+ if (!ct || FWINV((ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u3.ip&sinfo->sipmsk[IP_CT_DIR_ORIGINAL].s_addr) != sinfo->tuple[IP_CT_DIR_ORIGINAL].src.ip, IPT_CONNTRACK_ORIGSRC))
+ return 0;
+ }
+
+ if(sinfo->flags & IPT_CONNTRACK_ORIGDST) {
+ if (!ct || FWINV((ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.u3.ip&sinfo->dipmsk[IP_CT_DIR_ORIGINAL].s_addr) != sinfo->tuple[IP_CT_DIR_ORIGINAL].dst.ip, IPT_CONNTRACK_ORIGDST))
+ return 0;
+ }
+
+ if(sinfo->flags & IPT_CONNTRACK_REPLSRC) {
+ if (!ct || FWINV((ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.u3.ip&sinfo->sipmsk[IP_CT_DIR_REPLY].s_addr) != sinfo->tuple[IP_CT_DIR_REPLY].src.ip, IPT_CONNTRACK_REPLSRC))
+ return 0;
+ }
+
+ if(sinfo->flags & IPT_CONNTRACK_REPLDST) {
+ if (!ct || FWINV((ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u3.ip&sinfo->dipmsk[IP_CT_DIR_REPLY].s_addr) != sinfo->tuple[IP_CT_DIR_REPLY].dst.ip, IPT_CONNTRACK_REPLDST))
+ return 0;
+ }
+
+ if(sinfo->flags & IPT_CONNTRACK_STATUS) {
+ if (!ct || FWINV((ct->status & sinfo->statusmask) == 0, IPT_CONNTRACK_STATUS))
+ return 0;
+ }
+
+ if(sinfo->flags & IPT_CONNTRACK_EXPIRES) {
+ unsigned long expires;
+
+ if(!ct)
+ return 0;
+
+ expires = timer_pending(&ct->timeout) ? (ct->timeout.expires - jiffies)/HZ : 0;
+
+ if (FWINV(!(expires >= sinfo->expires_min && expires <= sinfo->expires_max), IPT_CONNTRACK_EXPIRES))
+ return 0;
+ }
+
+ return 1;
+}
+
+#endif /* CONFIG_NF_IP_CONNTRACK */
+
static int check(const char *tablename,
const struct ipt_ip *ip,
void *matchinfo,
diff --git a/net/ipv4/netfilter/ipt_helper.c b/net/ipv4/netfilter/ipt_helper.c
index 3e7dd014de43..bf14e1c7798a 100644
--- a/net/ipv4/netfilter/ipt_helper.c
+++ b/net/ipv4/netfilter/ipt_helper.c
@@ -13,9 +13,15 @@
#include <linux/module.h>
#include <linux/skbuff.h>
#include <linux/netfilter.h>
+#if defined(CONFIG_IP_NF_CONNTRACK) || defined(CONFIG_IP_NF_CONNTRACK_MODULE)
#include <linux/netfilter_ipv4/ip_conntrack.h>
#include <linux/netfilter_ipv4/ip_conntrack_core.h>
#include <linux/netfilter_ipv4/ip_conntrack_helper.h>
+#else
+#include <net/netfilter/nf_conntrack.h>
+#include <net/netfilter/nf_conntrack_core.h>
+#include <net/netfilter/nf_conntrack_helper.h>
+#endif
#include <linux/netfilter_ipv4/ip_tables.h>
#include <linux/netfilter_ipv4/ipt_helper.h>
@@ -29,6 +35,7 @@ MODULE_DESCRIPTION("iptables helper match module");
#define DEBUGP(format, args...)
#endif
+#if defined(CONFIG_IP_NF_CONNTRACK) || defined(CONFIG_IP_NF_CONNTRACK_MODULE)
static int
match(const struct sk_buff *skb,
const struct net_device *in,
@@ -73,6 +80,53 @@ out_unlock:
return ret;
}
+#else /* CONFIG_IP_NF_CONNTRACK */
+
+static int
+match(const struct sk_buff *skb,
+ const struct net_device *in,
+ const struct net_device *out,
+ const void *matchinfo,
+ int offset,
+ int *hotdrop)
+{
+ const struct ipt_helper_info *info = matchinfo;
+ struct nf_conn *ct;
+ enum ip_conntrack_info ctinfo;
+ int ret = info->invert;
+
+ ct = nf_ct_get((struct sk_buff *)skb, &ctinfo);
+ if (!ct) {
+ DEBUGP("ipt_helper: Eek! invalid conntrack?\n");
+ return ret;
+ }
+
+ if (!ct->master) {
+ DEBUGP("ipt_helper: conntrack %p has no master\n", ct);
+ return ret;
+ }
+
+ read_lock_bh(&nf_conntrack_lock);
+ if (!ct->master->helper) {
+ DEBUGP("ipt_helper: master ct %p has no helper\n",
+ exp->expectant);
+ goto out_unlock;
+ }
+
+ DEBUGP("master's name = %s , info->name = %s\n",
+ ct->master->helper->name, info->name);
+
+ if (info->name[0] == '\0')
+ ret ^= 1;
+ else
+ ret ^= !strncmp(ct->master->helper->name, info->name,
+ strlen(ct->master->helper->name));
+out_unlock:
+ read_unlock_bh(&nf_conntrack_lock);
+ return ret;
+}
+#endif
+
static int check(const char *tablename,
const struct ipt_ip *ip,
void *matchinfo,
diff --git a/net/ipv4/netfilter/ipt_state.c b/net/ipv4/netfilter/ipt_state.c
index b1511b97ea5f..4d7f16b70cec 100644
--- a/net/ipv4/netfilter/ipt_state.c
+++ b/net/ipv4/netfilter/ipt_state.c
@@ -10,7 +10,7 @@
#include <linux/module.h>
#include <linux/skbuff.h>
-#include <linux/netfilter_ipv4/ip_conntrack.h>
+#include <net/netfilter/nf_conntrack_compat.h>
#include <linux/netfilter_ipv4/ip_tables.h>
#include <linux/netfilter_ipv4/ipt_state.h>
@@ -30,9 +30,9 @@ match(const struct sk_buff *skb,
enum ip_conntrack_info ctinfo;
unsigned int statebit;
- if (skb->nfct == &ip_conntrack_untracked.ct_general)
+ if (nf_ct_is_untracked(skb))
statebit = IPT_STATE_UNTRACKED;
- else if (!ip_conntrack_get(skb, &ctinfo))
+ else if (!nf_ct_get_ctinfo(skb, &ctinfo))
statebit = IPT_STATE_INVALID;
else
statebit = IPT_STATE_BIT(ctinfo);
diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
new file mode 100644
index 000000000000..8202c1c0afad
--- /dev/null
+++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
@@ -0,0 +1,571 @@
+/* (C) 1999-2001 Paul `Rusty' Russell
+ * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.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.
+ *
+ * 16 Dec 2003: Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp>
+ * - move L3 protocol dependent part to this file.
+ * 23 Mar 2004: Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp>
+ * - add get_features() to support various size of conntrack
+ * structures.
+ *
+ * Derived from net/ipv4/netfilter/ip_conntrack_standalone.c
+ */
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/ip.h>
+#include <linux/netfilter.h>
+#include <linux/module.h>
+#include <linux/skbuff.h>
+#include <linux/icmp.h>
+#include <linux/sysctl.h>
+#include <net/ip.h>
+
+#include <linux/netfilter_ipv4.h>
+#include <net/netfilter/nf_conntrack.h>
+#include <net/netfilter/nf_conntrack_helper.h>
+#include <net/netfilter/nf_conntrack_protocol.h>
+#include <net/netfilter/nf_conntrack_l3proto.h>
+#include <net/netfilter/nf_conntrack_core.h>
+#include <net/netfilter/ipv4/nf_conntrack_ipv4.h>
+
+#if 0
+#define DEBUGP printk
+#else
+#define DEBUGP(format, args...)
+#endif
+
+DECLARE_PER_CPU(struct nf_conntrack_stat, nf_conntrack_stat);
+
+static int ipv4_pkt_to_tuple(const struct sk_buff *skb, unsigned int nhoff,
+ struct nf_conntrack_tuple *tuple)
+{
+ u_int32_t _addrs[2], *ap;
+ ap = skb_header_pointer(skb, nhoff + offsetof(struct iphdr, saddr),
+ sizeof(u_int32_t) * 2, _addrs);
+ if (ap == NULL)
+ return 0;
+
+ tuple->src.u3.ip = ap[0];
+ tuple->dst.u3.ip = ap[1];
+
+ return 1;
+}
+
+static int ipv4_invert_tuple(struct nf_conntrack_tuple *tuple,
+ const struct nf_conntrack_tuple *orig)
+{
+ tuple->src.u3.ip = orig->dst.u3.ip;
+ tuple->dst.u3.ip = orig->src.u3.ip;
+
+ return 1;
+}
+
+static int ipv4_print_tuple(struct seq_file *s,
+ const struct nf_conntrack_tuple *tuple)
+{
+ return seq_printf(s, "src=%u.%u.%u.%u dst=%u.%u.%u.%u ",
+ NIPQUAD(tuple->src.u3.ip),
+ NIPQUAD(tuple->dst.u3.ip));
+}
+
+static int ipv4_print_conntrack(struct seq_file *s,
+ const struct nf_conn *conntrack)
+{
+ return 0;
+}
+
+/* Returns new sk_buff, or NULL */
+static struct sk_buff *
+nf_ct_ipv4_gather_frags(struct sk_buff *skb, u_int32_t user)
+{
+ skb_orphan(skb);
+
+ local_bh_disable();
+ skb = ip_defrag(skb, user);
+ local_bh_enable();
+
+ if (skb)
+ ip_send_check(skb->nh.iph);
+
+ return skb;
+}
+
+static int
+ipv4_prepare(struct sk_buff **pskb, unsigned int hooknum, unsigned int *dataoff,
+ u_int8_t *protonum)
+{
+ /* Never happen */
+ if ((*pskb)->nh.iph->frag_off & htons(IP_OFFSET)) {
+ if (net_ratelimit()) {
+ printk(KERN_ERR "ipv4_prepare: Frag of proto %u (hook=%u)\n",
+ (*pskb)->nh.iph->protocol, hooknum);
+ }
+ return -NF_DROP;
+ }
+
+ *dataoff = (*pskb)->nh.raw - (*pskb)->data + (*pskb)->nh.iph->ihl*4;
+ *protonum = (*pskb)->nh.iph->protocol;
+
+ return NF_ACCEPT;
+}
+
+int nat_module_is_loaded = 0;
+static u_int32_t ipv4_get_features(const struct nf_conntrack_tuple *tuple)
+{
+ if (nat_module_is_loaded)
+ return NF_CT_F_NAT;
+
+ return NF_CT_F_BASIC;
+}
+
+static unsigned int ipv4_confirm(unsigned int hooknum,
+ struct sk_buff **pskb,
+ const struct net_device *in,
+ const struct net_device *out,
+ int (*okfn)(struct sk_buff *))
+{
+ /* We've seen it coming out the other side: confirm it */
+ return nf_conntrack_confirm(pskb);
+}
+
+static unsigned int ipv4_conntrack_help(unsigned int hooknum,
+ struct sk_buff **pskb,
+ const struct net_device *in,
+ const struct net_device *out,
+ int (*okfn)(struct sk_buff *))
+{
+ struct nf_conn *ct;
+ enum ip_conntrack_info ctinfo;
+
+ /* This is where we call the helper: as the packet goes out. */
+ ct = nf_ct_get(*pskb, &ctinfo);
+ if (ct && ct->helper) {
+ unsigned int ret;
+ ret = ct->helper->help(pskb,
+ (*pskb)->nh.raw - (*pskb)->data
+ + (*pskb)->nh.iph->ihl*4,
+ ct, ctinfo);
+ if (ret != NF_ACCEPT)
+ return ret;
+ }
+ return NF_ACCEPT;
+}
+
+static unsigned int ipv4_conntrack_defrag(unsigned int hooknum,
+ struct sk_buff **pskb,
+ const struct net_device *in,
+ const struct net_device *out,
+ int (*okfn)(struct sk_buff *))
+{
+#if !defined(CONFIG_IP_NF_NAT) && !defined(CONFIG_IP_NF_NAT_MODULE)
+ /* Previously seen (loopback)? Ignore. Do this before
+ fragment check. */
+ if ((*pskb)->nfct)
+ return NF_ACCEPT;
+#endif
+
+ /* Gather fragments. */
+ if ((*pskb)->nh.iph->frag_off & htons(IP_MF|IP_OFFSET)) {
+ *pskb = nf_ct_ipv4_gather_frags(*pskb,
+ hooknum == NF_IP_PRE_ROUTING ?
+ IP_DEFRAG_CONNTRACK_IN :
+ IP_DEFRAG_CONNTRACK_OUT);
+ if (!*pskb)
+ return NF_STOLEN;
+ }
+ return NF_ACCEPT;
+}
+
+static unsigned int ipv4_refrag(unsigned int hooknum,
+ struct sk_buff **pskb,
+ const struct net_device *in,
+ const struct net_device *out,
+ int (*okfn)(struct sk_buff *))
+{
+ struct rtable *rt = (struct rtable *)(*pskb)->dst;
+
+ /* We've seen it coming out the other side: confirm */
+ if (ipv4_confirm(hooknum, pskb, in, out, okfn) != NF_ACCEPT)
+ return NF_DROP;
+
+ /* Local packets are never produced too large for their
+ interface. We degfragment them at LOCAL_OUT, however,
+ so we have to refragment them here. */
+ if ((*pskb)->len > dst_mtu(&rt->u.dst) &&
+ !skb_shinfo(*pskb)->tso_size) {
+ /* No hook can be after us, so this should be OK. */
+ ip_fragment(*pskb, okfn);
+ return NF_STOLEN;
+ }
+ return NF_ACCEPT;
+}
+
+static unsigned int ipv4_conntrack_in(unsigned int hooknum,
+ struct sk_buff **pskb,
+ const struct net_device *in,
+ const struct net_device *out,
+ int (*okfn)(struct sk_buff *))
+{
+ return nf_conntrack_in(PF_INET, hooknum, pskb);
+}
+
+static unsigned int ipv4_conntrack_local(unsigned int hooknum,
+ struct sk_buff **pskb,
+ const struct net_device *in,
+ const struct net_device *out,
+ int (*okfn)(struct sk_buff *))
+{
+ /* root is playing with raw sockets. */
+ if ((*pskb)->len < sizeof(struct iphdr)
+ || (*pskb)->nh.iph->ihl * 4 < sizeof(struct iphdr)) {
+ if (net_ratelimit())
+ printk("ipt_hook: happy cracking.\n");
+ return NF_ACCEPT;
+ }
+ return nf_conntrack_in(PF_INET, hooknum, pskb);
+}
+
+/* Connection tracking may drop packets, but never alters them, so
+ make it the first hook. */
+static struct nf_hook_ops ipv4_conntrack_defrag_ops = {
+ .hook = ipv4_conntrack_defrag,
+ .owner = THIS_MODULE,
+ .pf = PF_INET,
+ .hooknum = NF_IP_PRE_ROUTING,
+ .priority = NF_IP_PRI_CONNTRACK_DEFRAG,
+};
+
+static struct nf_hook_ops ipv4_conntrack_in_ops = {
+ .hook = ipv4_conntrack_in,
+ .owner = THIS_MODULE,
+ .pf = PF_INET,
+ .hooknum = NF_IP_PRE_ROUTING,
+ .priority = NF_IP_PRI_CONNTRACK,
+};
+
+static struct nf_hook_ops ipv4_conntrack_defrag_local_out_ops = {
+ .hook = ipv4_conntrack_defrag,
+ .owner = THIS_MODULE,
+ .pf = PF_INET,
+ .hooknum = NF_IP_LOCAL_OUT,
+ .priority = NF_IP_PRI_CONNTRACK_DEFRAG,
+};
+
+static struct nf_hook_ops ipv4_conntrack_local_out_ops = {
+ .hook = ipv4_conntrack_local,
+ .owner = THIS_MODULE,
+ .pf = PF_INET,
+ .hooknum = NF_IP_LOCAL_OUT,
+ .priority = NF_IP_PRI_CONNTRACK,
+};
+
+/* helpers */
+static struct nf_hook_ops ipv4_conntrack_helper_out_ops = {
+ .hook = ipv4_conntrack_help,
+ .owner = THIS_MODULE,
+ .pf = PF_INET,
+ .hooknum = NF_IP_POST_ROUTING,
+ .priority = NF_IP_PRI_CONNTRACK_HELPER,
+};
+
+static struct nf_hook_ops ipv4_conntrack_helper_in_ops = {
+ .hook = ipv4_conntrack_help,
+ .owner = THIS_MODULE,
+ .pf = PF_INET,
+ .hooknum = NF_IP_LOCAL_IN,
+ .priority = NF_IP_PRI_CONNTRACK_HELPER,
+};
+
+
+/* Refragmenter; last chance. */
+static struct nf_hook_ops ipv4_conntrack_out_ops = {
+ .hook = ipv4_refrag,
+ .owner = THIS_MODULE,
+ .pf = PF_INET,
+ .hooknum = NF_IP_POST_ROUTING,
+ .priority = NF_IP_PRI_CONNTRACK_CONFIRM,
+};
+
+static struct nf_hook_ops ipv4_conntrack_local_in_ops = {
+ .hook = ipv4_confirm,
+ .owner = THIS_MODULE,
+ .pf = PF_INET,
+ .hooknum = NF_IP_LOCAL_IN,
+ .priority = NF_IP_PRI_CONNTRACK_CONFIRM,
+};
+
+#ifdef CONFIG_SYSCTL
+/* From nf_conntrack_proto_icmp.c */
+extern unsigned long nf_ct_icmp_timeout;
+static struct ctl_table_header *nf_ct_ipv4_sysctl_header;
+
+static ctl_table nf_ct_sysctl_table[] = {
+ {
+ .ctl_name = NET_NF_CONNTRACK_ICMP_TIMEOUT,
+ .procname = "nf_conntrack_icmp_timeout",
+ .data = &nf_ct_icmp_timeout,
+ .maxlen = sizeof(unsigned int),
+ .mode = 0644,
+ .proc_handler = &proc_dointvec_jiffies,
+ },
+ { .ctl_name = 0 }
+};
+
+static ctl_table nf_ct_netfilter_table[] = {
+ {
+ .ctl_name = NET_NETFILTER,
+ .procname = "netfilter",
+ .mode = 0555,
+ .child = nf_ct_sysctl_table,
+ },
+ { .ctl_name = 0 }
+};
+
+static ctl_table nf_ct_net_table[] = {
+ {
+ .ctl_name = CTL_NET,
+ .procname = "net",
+ .mode = 0555,
+ .child = nf_ct_netfilter_table,
+ },
+ { .ctl_name = 0 }
+};
+#endif
+
+/* Fast function for those who don't want to parse /proc (and I don't
+ blame them). */
+/* Reversing the socket's dst/src point of view gives us the reply
+ mapping. */
+static int
+getorigdst(struct sock *sk, int optval, void __user *user, int *len)
+{
+ struct inet_sock *inet = inet_sk(sk);
+ struct nf_conntrack_tuple_hash *h;
+ struct nf_conntrack_tuple tuple;
+
+ NF_CT_TUPLE_U_BLANK(&tuple);
+ tuple.src.u3.ip = inet->rcv_saddr;
+ tuple.src.u.tcp.port = inet->sport;
+ tuple.dst.u3.ip = inet->daddr;
+ tuple.dst.u.tcp.port = inet->dport;
+ tuple.src.l3num = PF_INET;
+ tuple.dst.protonum = IPPROTO_TCP;
+
+ /* We only do TCP at the moment: is there a better way? */
+ if (strcmp(sk->sk_prot->name, "TCP")) {
+ DEBUGP("SO_ORIGINAL_DST: Not a TCP socket\n");
+ return -ENOPROTOOPT;
+ }
+
+ if ((unsigned int) *len < sizeof(struct sockaddr_in)) {
+ DEBUGP("SO_ORIGINAL_DST: len %u not %u\n",
+ *len, sizeof(struct sockaddr_in));
+ return -EINVAL;
+ }
+
+ h = nf_conntrack_find_get(&tuple, NULL);
+ if (h) {
+ struct sockaddr_in sin;
+ struct nf_conn *ct = nf_ct_tuplehash_to_ctrack(h);
+
+ sin.sin_family = AF_INET;
+ sin.sin_port = ct->tuplehash[IP_CT_DIR_ORIGINAL]
+ .tuple.dst.u.tcp.port;
+ sin.sin_addr.s_addr = ct->tuplehash[IP_CT_DIR_ORIGINAL]
+ .tuple.dst.u3.ip;
+
+ DEBUGP("SO_ORIGINAL_DST: %u.%u.%u.%u %u\n",
+ NIPQUAD(sin.sin_addr.s_addr), ntohs(sin.sin_port));
+ nf_ct_put(ct);
+ if (copy_to_user(user, &sin, sizeof(sin)) != 0)
+ return -EFAULT;
+ else
+ return 0;
+ }
+ DEBUGP("SO_ORIGINAL_DST: Can't find %u.%u.%u.%u/%u-%u.%u.%u.%u/%u.\n",
+ NIPQUAD(tuple.src.u3.ip), ntohs(tuple.src.u.tcp.port),
+ NIPQUAD(tuple.dst.u3.ip), ntohs(tuple.dst.u.tcp.port));
+ return -ENOENT;
+}
+
+static struct nf_sockopt_ops so_getorigdst = {
+ .pf = PF_INET,
+ .get_optmin = SO_ORIGINAL_DST,
+ .get_optmax = SO_ORIGINAL_DST+1,
+ .get = &getorigdst,
+};
+
+struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv4 = {
+ .l3proto = PF_INET,
+ .name = "ipv4",
+ .pkt_to_tuple = ipv4_pkt_to_tuple,
+ .invert_tuple = ipv4_invert_tuple,
+ .print_tuple = ipv4_print_tuple,
+ .print_conntrack = ipv4_print_conntrack,
+ .prepare = ipv4_prepare,
+ .get_features = ipv4_get_features,
+ .me = THIS_MODULE,
+};
+
+extern struct nf_conntrack_protocol nf_conntrack_protocol_tcp4;
+extern struct nf_conntrack_protocol nf_conntrack_protocol_udp4;
+extern struct nf_conntrack_protocol nf_conntrack_protocol_icmp;
+static int init_or_cleanup(int init)
+{
+ int ret = 0;
+
+ if (!init) goto cleanup;
+
+ ret = nf_register_sockopt(&so_getorigdst);
+ if (ret < 0) {
+ printk(KERN_ERR "Unable to register netfilter socket option\n");
+ goto cleanup_nothing;
+ }
+
+ ret = nf_conntrack_protocol_register(&nf_conntrack_protocol_tcp4);
+ if (ret < 0) {
+ printk("nf_conntrack_ipv4: can't register tcp.\n");
+ goto cleanup_sockopt;
+ }
+
+ ret = nf_conntrack_protocol_register(&nf_conntrack_protocol_udp4);
+ if (ret < 0) {
+ printk("nf_conntrack_ipv4: can't register udp.\n");
+ goto cleanup_tcp;
+ }
+
+ ret = nf_conntrack_protocol_register(&nf_conntrack_protocol_icmp);
+ if (ret < 0) {
+ printk("nf_conntrack_ipv4: can't register icmp.\n");
+ goto cleanup_udp;
+ }
+
+ ret = nf_conntrack_l3proto_register(&nf_conntrack_l3proto_ipv4);
+ if (ret < 0) {
+ printk("nf_conntrack_ipv4: can't register ipv4\n");
+ goto cleanup_icmp;
+ }
+
+ ret = nf_register_hook(&ipv4_conntrack_defrag_ops);
+ if (ret < 0) {
+ printk("nf_conntrack_ipv4: can't register pre-routing defrag hook.\n");
+ goto cleanup_ipv4;
+ }
+ ret = nf_register_hook(&ipv4_conntrack_defrag_local_out_ops);
+ if (ret < 0) {
+ printk("nf_conntrack_ipv4: can't register local_out defrag hook.\n");
+ goto cleanup_defragops;
+ }
+
+ ret = nf_register_hook(&ipv4_conntrack_in_ops);
+ if (ret < 0) {
+ printk("nf_conntrack_ipv4: can't register pre-routing hook.\n");
+ goto cleanup_defraglocalops;
+ }
+
+ ret = nf_register_hook(&ipv4_conntrack_local_out_ops);
+ if (ret < 0) {
+ printk("nf_conntrack_ipv4: can't register local out hook.\n");
+ goto cleanup_inops;
+ }
+
+ ret = nf_register_hook(&ipv4_conntrack_helper_in_ops);
+ if (ret < 0) {
+ printk("nf_conntrack_ipv4: can't register local helper hook.\n");
+ goto cleanup_inandlocalops;
+ }
+
+ ret = nf_register_hook(&ipv4_conntrack_helper_out_ops);
+ if (ret < 0) {
+ printk("nf_conntrack_ipv4: can't register postrouting helper hook.\n");
+ goto cleanup_helperinops;
+ }
+
+ ret = nf_register_hook(&ipv4_conntrack_out_ops);
+ if (ret < 0) {
+ printk("nf_conntrack_ipv4: can't register post-routing hook.\n");
+ goto cleanup_helperoutops;
+ }
+
+ ret = nf_register_hook(&ipv4_conntrack_local_in_ops);
+ if (ret < 0) {
+ printk("nf_conntrack_ipv4: can't register local in hook.\n");
+ goto cleanup_inoutandlocalops;
+ }
+
+#ifdef CONFIG_SYSCTL
+ nf_ct_ipv4_sysctl_header = register_sysctl_table(nf_ct_net_table, 0);
+ if (nf_ct_ipv4_sysctl_header == NULL) {
+ printk("nf_conntrack: can't register to sysctl.\n");
+ ret = -ENOMEM;
+ goto cleanup_localinops;
+ }
+#endif
+
+ /* For use by REJECT target */
+ ip_ct_attach = __nf_conntrack_attach;
+
+ return ret;
+
+ cleanup:
+ synchronize_net();
+ ip_ct_attach = NULL;
+#ifdef CONFIG_SYSCTL
+ unregister_sysctl_table(nf_ct_ipv4_sysctl_header);
+ cleanup_localinops:
+#endif
+ nf_unregister_hook(&ipv4_conntrack_local_in_ops);
+ cleanup_inoutandlocalops:
+ nf_unregister_hook(&ipv4_conntrack_out_ops);
+ cleanup_helperoutops:
+ nf_unregister_hook(&ipv4_conntrack_helper_out_ops);
+ cleanup_helperinops:
+ nf_unregister_hook(&ipv4_conntrack_helper_in_ops);
+ cleanup_inandlocalops:
+ nf_unregister_hook(&ipv4_conntrack_local_out_ops);
+ cleanup_inops:
+ nf_unregister_hook(&ipv4_conntrack_in_ops);
+ cleanup_defraglocalops:
+ nf_unregister_hook(&ipv4_conntrack_defrag_local_out_ops);
+ cleanup_defragops:
+ nf_unregister_hook(&ipv4_conntrack_defrag_ops);
+ cleanup_ipv4:
+ nf_conntrack_l3proto_unregister(&nf_conntrack_l3proto_ipv4);
+ cleanup_icmp:
+ nf_conntrack_protocol_unregister(&nf_conntrack_protocol_icmp);
+ cleanup_udp:
+ nf_conntrack_protocol_unregister(&nf_conntrack_protocol_udp4);
+ cleanup_tcp:
+ nf_conntrack_protocol_unregister(&nf_conntrack_protocol_tcp4);
+ cleanup_sockopt:
+ nf_unregister_sockopt(&so_getorigdst);
+ cleanup_nothing:
+ return ret;
+}
+
+MODULE_LICENSE("GPL");
+
+static int __init init(void)
+{
+ need_nf_conntrack();
+ return init_or_cleanup(1);
+}
+
+static void __exit fini(void)
+{
+ init_or_cleanup(0);
+}
+
+module_init(init);
+module_exit(fini);
+
+void need_ip_conntrack(void)
+{
+}
+
+EXPORT_SYMBOL(need_ip_conntrack);
+EXPORT_SYMBOL(nf_ct_ipv4_gather_frags);
diff --git a/net/ipv4/netfilter/nf_conntrack_proto_icmp.c b/net/ipv4/netfilter/nf_conntrack_proto_icmp.c
new file mode 100644
index 000000000000..7ddb5c08f7b8
--- /dev/null
+++ b/net/ipv4/netfilter/nf_conntrack_proto_icmp.c
@@ -0,0 +1,301 @@
+/* (C) 1999-2001 Paul `Rusty' Russell
+ * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.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.
+ *
+ * 16 Dec 2003: Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp>
+ * - enable working with Layer 3 protocol independent connection tracking.
+ *
+ * Derived from net/ipv4/netfilter/ip_conntrack_proto_icmp.c
+ */
+
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/timer.h>
+#include <linux/netfilter.h>
+#include <linux/in.h>
+#include <linux/icmp.h>
+#include <linux/seq_file.h>
+#include <net/ip.h>
+#include <net/checksum.h>
+#include <linux/netfilter_ipv4.h>
+#include <net/netfilter/nf_conntrack_tuple.h>
+#include <net/netfilter/nf_conntrack_protocol.h>
+#include <net/netfilter/nf_conntrack_core.h>
+
+unsigned long nf_ct_icmp_timeout = 30*HZ;
+
+#if 0
+#define DEBUGP printk
+#else
+#define DEBUGP(format, args...)
+#endif
+
+static int icmp_pkt_to_tuple(const struct sk_buff *skb,
+ unsigned int dataoff,
+ struct nf_conntrack_tuple *tuple)
+{
+ struct icmphdr _hdr, *hp;
+
+ hp = skb_header_pointer(skb, dataoff, sizeof(_hdr), &_hdr);
+ if (hp == NULL)
+ return 0;
+
+ tuple->dst.u.icmp.type = hp->type;
+ tuple->src.u.icmp.id = hp->un.echo.id;
+ tuple->dst.u.icmp.code = hp->code;
+
+ return 1;
+}
+
+static int icmp_invert_tuple(struct nf_conntrack_tuple *tuple,
+ const struct nf_conntrack_tuple *orig)
+{
+ /* Add 1; spaces filled with 0. */
+ static u_int8_t invmap[]
+ = { [ICMP_ECHO] = ICMP_ECHOREPLY + 1,
+ [ICMP_ECHOREPLY] = ICMP_ECHO + 1,
+ [ICMP_TIMESTAMP] = ICMP_TIMESTAMPREPLY + 1,
+ [ICMP_TIMESTAMPREPLY] = ICMP_TIMESTAMP + 1,
+ [ICMP_INFO_REQUEST] = ICMP_INFO_REPLY + 1,
+ [ICMP_INFO_REPLY] = ICMP_INFO_REQUEST + 1,
+ [ICMP_ADDRESS] = ICMP_ADDRESSREPLY + 1,
+ [ICMP_ADDRESSREPLY] = ICMP_ADDRESS + 1};
+
+ if (orig->dst.u.icmp.type >= sizeof(invmap)
+ || !invmap[orig->dst.u.icmp.type])
+ return 0;
+
+ tuple->src.u.icmp.id = orig->src.u.icmp.id;
+ tuple->dst.u.icmp.type = invmap[orig->dst.u.icmp.type] - 1;
+ tuple->dst.u.icmp.code = orig->dst.u.icmp.code;
+ return 1;
+}
+
+/* Print out the per-protocol part of the tuple. */
+static int icmp_print_tuple(struct seq_file *s,
+ const struct nf_conntrack_tuple *tuple)
+{
+ return seq_printf(s, "type=%u code=%u id=%u ",
+ tuple->dst.u.icmp.type,
+ tuple->dst.u.icmp.code,
+ ntohs(tuple->src.u.icmp.id));
+}
+
+/* Print out the private part of the conntrack. */
+static int icmp_print_conntrack(struct seq_file *s,
+ const struct nf_conn *conntrack)
+{
+ return 0;
+}
+
+/* Returns verdict for packet, or -1 for invalid. */
+static int icmp_packet(struct nf_conn *ct,
+ const struct sk_buff *skb,
+ unsigned int dataoff,
+ enum ip_conntrack_info ctinfo,
+ int pf,
+ unsigned int hooknum)
+{
+ /* Try to delete connection immediately after all replies:
+ won't actually vanish as we still have skb, and del_timer
+ means this will only run once even if count hits zero twice
+ (theoretically possible with SMP) */
+ if (CTINFO2DIR(ctinfo) == IP_CT_DIR_REPLY) {
+ if (atomic_dec_and_test(&ct->proto.icmp.count)
+ && del_timer(&ct->timeout))
+ ct->timeout.function((unsigned long)ct);
+ } else {
+ atomic_inc(&ct->proto.icmp.count);
+ nf_conntrack_event_cache(IPCT_PROTOINFO_VOLATILE, skb);
+ nf_ct_refresh_acct(ct, ctinfo, skb, nf_ct_icmp_timeout);
+ }
+
+ return NF_ACCEPT;
+}
+
+/* Called when a new connection for this protocol found. */
+static int icmp_new(struct nf_conn *conntrack,
+ const struct sk_buff *skb, unsigned int dataoff)
+{
+ static u_int8_t valid_new[]
+ = { [ICMP_ECHO] = 1,
+ [ICMP_TIMESTAMP] = 1,
+ [ICMP_INFO_REQUEST] = 1,
+ [ICMP_ADDRESS] = 1 };
+
+ if (conntrack->tuplehash[0].tuple.dst.u.icmp.type >= sizeof(valid_new)
+ || !valid_new[conntrack->tuplehash[0].tuple.dst.u.icmp.type]) {
+ /* Can't create a new ICMP `conn' with this. */
+ DEBUGP("icmp: can't create new conn with type %u\n",
+ conntrack->tuplehash[0].tuple.dst.u.icmp.type);
+ NF_CT_DUMP_TUPLE(&conntrack->tuplehash[0].tuple);
+ return 0;
+ }
+ atomic_set(&conntrack->proto.icmp.count, 0);
+ return 1;
+}
+
+extern struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv4;
+/* Returns conntrack if it dealt with ICMP, and filled in skb fields */
+static int
+icmp_error_message(struct sk_buff *skb,
+ enum ip_conntrack_info *ctinfo,
+ unsigned int hooknum)
+{
+ struct nf_conntrack_tuple innertuple, origtuple;
+ struct {
+ struct icmphdr icmp;
+ struct iphdr ip;
+ } _in, *inside;
+ struct nf_conntrack_protocol *innerproto;
+ struct nf_conntrack_tuple_hash *h;
+ int dataoff;
+
+ NF_CT_ASSERT(skb->nfct == NULL);
+
+ /* Not enough header? */
+ inside = skb_header_pointer(skb, skb->nh.iph->ihl*4, sizeof(_in), &_in);
+ if (inside == NULL)
+ return -NF_ACCEPT;
+
+ /* Ignore ICMP's containing fragments (shouldn't happen) */
+ if (inside->ip.frag_off & htons(IP_OFFSET)) {
+ DEBUGP("icmp_error_message: fragment of proto %u\n",
+ inside->ip.protocol);
+ return -NF_ACCEPT;
+ }
+
+ innerproto = nf_ct_find_proto(PF_INET, inside->ip.protocol);
+ dataoff = skb->nh.iph->ihl*4 + sizeof(inside->icmp);
+ /* Are they talking about one of our connections? */
+ if (!nf_ct_get_tuple(skb, dataoff, dataoff + inside->ip.ihl*4, PF_INET,
+ inside->ip.protocol, &origtuple,
+ &nf_conntrack_l3proto_ipv4, innerproto)) {
+ DEBUGP("icmp_error_message: ! get_tuple p=%u",
+ inside->ip.protocol);
+ return -NF_ACCEPT;
+ }
+
+ /* Ordinarily, we'd expect the inverted tupleproto, but it's
+ been preserved inside the ICMP. */
+ if (!nf_ct_invert_tuple(&innertuple, &origtuple,
+ &nf_conntrack_l3proto_ipv4, innerproto)) {
+ DEBUGP("icmp_error_message: no match\n");
+ return -NF_ACCEPT;
+ }
+
+ *ctinfo = IP_CT_RELATED;
+
+ h = nf_conntrack_find_get(&innertuple, NULL);
+ if (!h) {
+ /* Locally generated ICMPs will match inverted if they
+ haven't been SNAT'ed yet */
+ /* FIXME: NAT code has to handle half-done double NAT --RR */
+ if (hooknum == NF_IP_LOCAL_OUT)
+ h = nf_conntrack_find_get(&origtuple, NULL);
+
+ if (!h) {
+ DEBUGP("icmp_error_message: no match\n");
+ return -NF_ACCEPT;
+ }
+
+ /* Reverse direction from that found */
+ if (NF_CT_DIRECTION(h) == IP_CT_DIR_REPLY)
+ *ctinfo += IP_CT_IS_REPLY;
+ } else {
+ if (NF_CT_DIRECTION(h) == IP_CT_DIR_REPLY)
+ *ctinfo += IP_CT_IS_REPLY;
+ }
+
+ /* Update skb to refer to this connection */
+ skb->nfct = &nf_ct_tuplehash_to_ctrack(h)->ct_general;
+ skb->nfctinfo = *ctinfo;
+ return -NF_ACCEPT;
+}
+
+/* Small and modified version of icmp_rcv */
+static int
+icmp_error(struct sk_buff *skb, unsigned int dataoff,
+ enum ip_conntrack_info *ctinfo, int pf, unsigned int hooknum)
+{
+ struct icmphdr _ih, *icmph;
+
+ /* Not enough header? */
+ icmph = skb_header_pointer(skb, skb->nh.iph->ihl*4, sizeof(_ih), &_ih);
+ if (icmph == NULL) {
+ if (LOG_INVALID(IPPROTO_ICMP))
+ nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL,
+ "nf_ct_icmp: short packet ");
+ return -NF_ACCEPT;
+ }
+
+ /* See ip_conntrack_proto_tcp.c */
+ if (hooknum != NF_IP_PRE_ROUTING)
+ goto checksum_skipped;
+
+ switch (skb->ip_summed) {
+ case CHECKSUM_HW:
+ if (!(u16)csum_fold(skb->csum))
+ break;
+ if (LOG_INVALID(IPPROTO_ICMP))
+ nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL,
+ "nf_ct_icmp: bad HW ICMP checksum ");
+ return -NF_ACCEPT;
+ case CHECKSUM_NONE:
+ if ((u16)csum_fold(skb_checksum(skb, 0, skb->len, 0))) {
+ if (LOG_INVALID(IPPROTO_ICMP))
+ nf_log_packet(PF_INET, 0, skb, NULL, NULL,
+ NULL,
+ "nf_ct_icmp: bad ICMP checksum ");
+ return -NF_ACCEPT;
+ }
+ default:
+ break;
+ }
+
+checksum_skipped:
+ /*
+ * 18 is the highest 'known' ICMP type. Anything else is a mystery
+ *
+ * RFC 1122: 3.2.2 Unknown ICMP messages types MUST be silently
+ * discarded.
+ */
+ if (icmph->type > NR_ICMP_TYPES) {
+ if (LOG_INVALID(IPPROTO_ICMP))
+ nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL,
+ "nf_ct_icmp: invalid ICMP type ");
+ return -NF_ACCEPT;
+ }
+
+ /* Need to track icmp error message? */
+ if (icmph->type != ICMP_DEST_UNREACH
+ && icmph->type != ICMP_SOURCE_QUENCH
+ && icmph->type != ICMP_TIME_EXCEEDED
+ && icmph->type != ICMP_PARAMETERPROB
+ && icmph->type != ICMP_REDIRECT)
+ return NF_ACCEPT;
+
+ return icmp_error_message(skb, ctinfo, hooknum);
+}
+
+struct nf_conntrack_protocol nf_conntrack_protocol_icmp =
+{
+ .list = { NULL, NULL },
+ .l3proto = PF_INET,
+ .proto = IPPROTO_ICMP,
+ .name = "icmp",
+ .pkt_to_tuple = icmp_pkt_to_tuple,
+ .invert_tuple = icmp_invert_tuple,
+ .print_tuple = icmp_print_tuple,
+ .print_conntrack = icmp_print_conntrack,
+ .packet = icmp_packet,
+ .new = icmp_new,
+ .error = icmp_error,
+ .destroy = NULL,
+ .me = NULL
+};
+
+EXPORT_SYMBOL(nf_conntrack_protocol_icmp);
diff --git a/net/ipv4/proc.c b/net/ipv4/proc.c
index f7943ba1f43c..a65e508fbd40 100644
--- a/net/ipv4/proc.c
+++ b/net/ipv4/proc.c
@@ -90,9 +90,7 @@ fold_field(void *mib[], int offt)
unsigned long res = 0;
int i;
- for (i = 0; i < NR_CPUS; i++) {
- if (!cpu_possible(i))
- continue;
+ for_each_cpu(i) {
res += *(((unsigned long *) per_cpu_ptr(mib[0], i)) + offt);
res += *(((unsigned long *) per_cpu_ptr(mib[1], i)) + offt);
}
diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c
index 652685623519..01444a02b48b 100644
--- a/net/ipv4/sysctl_net_ipv4.c
+++ b/net/ipv4/sysctl_net_ipv4.c
@@ -645,6 +645,14 @@ ctl_table ipv4_table[] = {
.proc_handler = &proc_tcp_congestion_control,
.strategy = &sysctl_tcp_congestion_control,
},
+ {
+ .ctl_name = NET_TCP_ABC,
+ .procname = "tcp_abc",
+ .data = &sysctl_tcp_abc,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = &proc_dointvec,
+ },
{ .ctl_name = 0 }
};
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index f3f0013a9580..9ac7a4f46bd8 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -1640,7 +1640,7 @@ int tcp_disconnect(struct sock *sk, int flags)
} else if (tcp_need_reset(old_state) ||
(tp->snd_nxt != tp->write_seq &&
(1 << old_state) & (TCPF_CLOSING | TCPF_LAST_ACK))) {
- /* The last check adjusts for discrepance of Linux wrt. RFC
+ /* The last check adjusts for discrepancy of Linux wrt. RFC
* states
*/
tcp_send_active_reset(sk, gfp_any());
@@ -1669,6 +1669,7 @@ int tcp_disconnect(struct sock *sk, int flags)
tp->packets_out = 0;
tp->snd_ssthresh = 0x7fffffff;
tp->snd_cwnd_cnt = 0;
+ tp->bytes_acked = 0;
tcp_set_ca_state(sk, TCP_CA_Open);
tcp_clear_retrans(tp);
inet_csk_delack_init(sk);
@@ -2112,7 +2113,6 @@ void __init tcp_init(void)
sysctl_tcp_max_orphans >>= (3 - order);
sysctl_max_syn_backlog = 128;
}
- tcp_hashinfo.port_rover = sysctl_local_port_range[0] - 1;
sysctl_tcp_mem[0] = 768 << order;
sysctl_tcp_mem[1] = 1024 << order;
diff --git a/net/ipv4/tcp_bic.c b/net/ipv4/tcp_bic.c
index 6d80e063c187..1d0cd86621b1 100644
--- a/net/ipv4/tcp_bic.c
+++ b/net/ipv4/tcp_bic.c
@@ -27,7 +27,7 @@
*/
static int fast_convergence = 1;
-static int max_increment = 32;
+static int max_increment = 16;
static int low_window = 14;
static int beta = 819; /* = 819/1024 (BICTCP_BETA_SCALE) */
static int low_utilization_threshold = 153;
@@ -217,17 +217,15 @@ static void bictcp_cong_avoid(struct sock *sk, u32 ack,
bictcp_low_utilization(sk, data_acked);
- if (in_flight < tp->snd_cwnd)
+ if (!tcp_is_cwnd_limited(sk, in_flight))
return;
- if (tp->snd_cwnd <= tp->snd_ssthresh) {
- /* In "safe" area, increase. */
- if (tp->snd_cwnd < tp->snd_cwnd_clamp)
- tp->snd_cwnd++;
- } else {
+ if (tp->snd_cwnd <= tp->snd_ssthresh)
+ tcp_slow_start(tp);
+ else {
bictcp_update(ca, tp->snd_cwnd);
- /* In dangerous area, increase slowly.
+ /* In dangerous area, increase slowly.
* In theory this is tp->snd_cwnd += 1 / tp->snd_cwnd
*/
if (tp->snd_cwnd_cnt >= ca->cnt) {
diff --git a/net/ipv4/tcp_cong.c b/net/ipv4/tcp_cong.c
index bbf2d6624e89..c7cc62c8dc12 100644
--- a/net/ipv4/tcp_cong.c
+++ b/net/ipv4/tcp_cong.c
@@ -186,24 +186,32 @@ void tcp_reno_cong_avoid(struct sock *sk, u32 ack, u32 rtt, u32 in_flight,
{
struct tcp_sock *tp = tcp_sk(sk);
- if (in_flight < tp->snd_cwnd)
+ if (!tcp_is_cwnd_limited(sk, in_flight))
return;
- if (tp->snd_cwnd <= tp->snd_ssthresh) {
- /* In "safe" area, increase. */
- if (tp->snd_cwnd < tp->snd_cwnd_clamp)
- tp->snd_cwnd++;
- } else {
- /* In dangerous area, increase slowly.
- * In theory this is tp->snd_cwnd += 1 / tp->snd_cwnd
- */
- if (tp->snd_cwnd_cnt >= tp->snd_cwnd) {
- if (tp->snd_cwnd < tp->snd_cwnd_clamp)
- tp->snd_cwnd++;
- tp->snd_cwnd_cnt = 0;
- } else
- tp->snd_cwnd_cnt++;
- }
+ /* In "safe" area, increase. */
+ if (tp->snd_cwnd <= tp->snd_ssthresh)
+ tcp_slow_start(tp);
+
+ /* In dangerous area, increase slowly. */
+ else if (sysctl_tcp_abc) {
+ /* RFC3465: Apppriate Byte Count
+ * increase once for each full cwnd acked
+ */
+ if (tp->bytes_acked >= tp->snd_cwnd*tp->mss_cache) {
+ tp->bytes_acked -= tp->snd_cwnd*tp->mss_cache;
+ if (tp->snd_cwnd < tp->snd_cwnd_clamp)
+ tp->snd_cwnd++;
+ }
+ } else {
+ /* In theory this is tp->snd_cwnd += 1 / tp->snd_cwnd */
+ if (tp->snd_cwnd_cnt >= tp->snd_cwnd) {
+ if (tp->snd_cwnd < tp->snd_cwnd_clamp)
+ tp->snd_cwnd++;
+ tp->snd_cwnd_cnt = 0;
+ } else
+ tp->snd_cwnd_cnt++;
+ }
}
EXPORT_SYMBOL_GPL(tcp_reno_cong_avoid);
diff --git a/net/ipv4/tcp_highspeed.c b/net/ipv4/tcp_highspeed.c
index 6acc04bde080..82b3c189bd7d 100644
--- a/net/ipv4/tcp_highspeed.c
+++ b/net/ipv4/tcp_highspeed.c
@@ -111,18 +111,17 @@ static void hstcp_init(struct sock *sk)
}
static void hstcp_cong_avoid(struct sock *sk, u32 adk, u32 rtt,
- u32 in_flight, int good)
+ u32 in_flight, u32 pkts_acked)
{
struct tcp_sock *tp = tcp_sk(sk);
struct hstcp *ca = inet_csk_ca(sk);
- if (in_flight < tp->snd_cwnd)
+ if (!tcp_is_cwnd_limited(sk, in_flight))
return;
- if (tp->snd_cwnd <= tp->snd_ssthresh) {
- if (tp->snd_cwnd < tp->snd_cwnd_clamp)
- tp->snd_cwnd++;
- } else {
+ if (tp->snd_cwnd <= tp->snd_ssthresh)
+ tcp_slow_start(tp);
+ else {
/* Update AIMD parameters */
if (tp->snd_cwnd > hstcp_aimd_vals[ca->ai].cwnd) {
while (tp->snd_cwnd > hstcp_aimd_vals[ca->ai].cwnd &&
diff --git a/net/ipv4/tcp_htcp.c b/net/ipv4/tcp_htcp.c
index e47b37984e95..3284cfb993e6 100644
--- a/net/ipv4/tcp_htcp.c
+++ b/net/ipv4/tcp_htcp.c
@@ -207,14 +207,13 @@ static void htcp_cong_avoid(struct sock *sk, u32 ack, u32 rtt,
struct tcp_sock *tp = tcp_sk(sk);
struct htcp *ca = inet_csk_ca(sk);
- if (in_flight < tp->snd_cwnd)
+ if (!tcp_is_cwnd_limited(sk, in_flight))
return;
- if (tp->snd_cwnd <= tp->snd_ssthresh) {
- /* In "safe" area, increase. */
- if (tp->snd_cwnd < tp->snd_cwnd_clamp)
- tp->snd_cwnd++;
- } else {
+ if (tp->snd_cwnd <= tp->snd_ssthresh)
+ tcp_slow_start(tp);
+ else {
+
measure_rtt(sk);
/* keep track of number of round-trip times since last backoff event */
@@ -224,7 +223,7 @@ static void htcp_cong_avoid(struct sock *sk, u32 ack, u32 rtt,
htcp_alpha_update(ca);
}
- /* In dangerous area, increase slowly.
+ /* In dangerous area, increase slowly.
* In theory this is tp->snd_cwnd += alpha / tp->snd_cwnd
*/
if ((tp->snd_cwnd_cnt++ * ca->alpha)>>7 >= tp->snd_cwnd) {
diff --git a/net/ipv4/tcp_hybla.c b/net/ipv4/tcp_hybla.c
index 77add63623df..40dbb3877510 100644
--- a/net/ipv4/tcp_hybla.c
+++ b/net/ipv4/tcp_hybla.c
@@ -100,12 +100,12 @@ static void hybla_cong_avoid(struct sock *sk, u32 ack, u32 rtt,
ca->minrtt = tp->srtt;
}
+ if (!tcp_is_cwnd_limited(sk, in_flight))
+ return;
+
if (!ca->hybla_en)
return tcp_reno_cong_avoid(sk, ack, rtt, in_flight, flag);
- if (in_flight < tp->snd_cwnd)
- return;
-
if (ca->rho == 0)
hybla_recalc_param(sk);
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 3e98b57578dc..40a26b7157b4 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -42,7 +42,7 @@
* Andi Kleen : Moved open_request checking here
* and process RSTs for open_requests.
* Andi Kleen : Better prune_queue, and other fixes.
- * Andrey Savochkin: Fix RTT measurements in the presnce of
+ * Andrey Savochkin: Fix RTT measurements in the presence of
* timestamps.
* Andrey Savochkin: Check sequence numbers correctly when
* removing SACKs due to in sequence incoming
@@ -89,6 +89,7 @@ int sysctl_tcp_frto;
int sysctl_tcp_nometrics_save;
int sysctl_tcp_moderate_rcvbuf = 1;
+int sysctl_tcp_abc = 1;
#define FLAG_DATA 0x01 /* Incoming frame contained data. */
#define FLAG_WIN_UPDATE 0x02 /* Incoming ACK was a window update. */
@@ -223,7 +224,7 @@ static void tcp_fixup_sndbuf(struct sock *sk)
* of receiver window. Check #2.
*
* The scheme does not work when sender sends good segments opening
- * window and then starts to feed us spagetti. But it should work
+ * window and then starts to feed us spaghetti. But it should work
* in common situations. Otherwise, we have to rely on queue collapsing.
*/
@@ -233,7 +234,7 @@ static int __tcp_grow_window(const struct sock *sk, struct tcp_sock *tp,
{
/* Optimize this! */
int truesize = tcp_win_from_space(skb->truesize)/2;
- int window = tcp_full_space(sk)/2;
+ int window = tcp_win_from_space(sysctl_tcp_rmem[2])/2;
while (tp->rcv_ssthresh <= window) {
if (truesize <= skb->len)
@@ -277,7 +278,7 @@ static void tcp_fixup_rcvbuf(struct sock *sk)
int rcvmem = tp->advmss + MAX_TCP_HEADER + 16 + sizeof(struct sk_buff);
/* Try to select rcvbuf so that 4 mss-sized segments
- * will fit to window and correspoding skbs will fit to our rcvbuf.
+ * will fit to window and corresponding skbs will fit to our rcvbuf.
* (was 3; 4 is minimum to allow fast retransmit to work.)
*/
while (tcp_win_from_space(rcvmem) < tp->advmss)
@@ -286,7 +287,7 @@ static void tcp_fixup_rcvbuf(struct sock *sk)
sk->sk_rcvbuf = min(4 * rcvmem, sysctl_tcp_rmem[2]);
}
-/* 4. Try to fixup all. It is made iimediately after connection enters
+/* 4. Try to fixup all. It is made immediately after connection enters
* established state.
*/
static void tcp_init_buffer_space(struct sock *sk)
@@ -326,37 +327,18 @@ static void tcp_init_buffer_space(struct sock *sk)
static void tcp_clamp_window(struct sock *sk, struct tcp_sock *tp)
{
struct inet_connection_sock *icsk = inet_csk(sk);
- struct sk_buff *skb;
- unsigned int app_win = tp->rcv_nxt - tp->copied_seq;
- int ofo_win = 0;
icsk->icsk_ack.quick = 0;
- skb_queue_walk(&tp->out_of_order_queue, skb) {
- ofo_win += skb->len;
- }
-
- /* If overcommit is due to out of order segments,
- * do not clamp window. Try to expand rcvbuf instead.
- */
- if (ofo_win) {
- if (sk->sk_rcvbuf < sysctl_tcp_rmem[2] &&
- !(sk->sk_userlocks & SOCK_RCVBUF_LOCK) &&
- !tcp_memory_pressure &&
- atomic_read(&tcp_memory_allocated) < sysctl_tcp_mem[0])
- sk->sk_rcvbuf = min(atomic_read(&sk->sk_rmem_alloc),
- sysctl_tcp_rmem[2]);
+ if (sk->sk_rcvbuf < sysctl_tcp_rmem[2] &&
+ !(sk->sk_userlocks & SOCK_RCVBUF_LOCK) &&
+ !tcp_memory_pressure &&
+ atomic_read(&tcp_memory_allocated) < sysctl_tcp_mem[0]) {
+ sk->sk_rcvbuf = min(atomic_read(&sk->sk_rmem_alloc),
+ sysctl_tcp_rmem[2]);
}
- if (atomic_read(&sk->sk_rmem_alloc) > sk->sk_rcvbuf) {
- app_win += ofo_win;
- if (atomic_read(&sk->sk_rmem_alloc) >= 2 * sk->sk_rcvbuf)
- app_win >>= 1;
- if (app_win > icsk->icsk_ack.rcv_mss)
- app_win -= icsk->icsk_ack.rcv_mss;
- app_win = max(app_win, 2U*tp->advmss);
-
+ if (atomic_read(&sk->sk_rmem_alloc) > sk->sk_rcvbuf)
tp->rcv_ssthresh = min(tp->window_clamp, 2U*tp->advmss);
- }
}
/* Receiver "autotuning" code.
@@ -385,8 +367,8 @@ static void tcp_rcv_rtt_update(struct tcp_sock *tp, u32 sample, int win_dep)
* are stalled on filesystem I/O.
*
* Also, since we are only going for a minimum in the
- * non-timestamp case, we do not smoothe things out
- * else with timestamps disabled convergance takes too
+ * non-timestamp case, we do not smoother things out
+ * else with timestamps disabled convergence takes too
* long.
*/
if (!win_dep) {
@@ -395,7 +377,7 @@ static void tcp_rcv_rtt_update(struct tcp_sock *tp, u32 sample, int win_dep)
} else if (m < new_sample)
new_sample = m << 3;
} else {
- /* No previous mesaure. */
+ /* No previous measure. */
new_sample = m << 3;
}
@@ -524,7 +506,7 @@ static void tcp_event_data_recv(struct sock *sk, struct tcp_sock *tp, struct sk_
if (icsk->icsk_ack.ato > icsk->icsk_rto)
icsk->icsk_ack.ato = icsk->icsk_rto;
} else if (m > icsk->icsk_rto) {
- /* Too long gap. Apparently sender falled to
+ /* Too long gap. Apparently sender failed to
* restart window, so that we send ACKs quickly.
*/
tcp_incr_quickack(sk);
@@ -548,10 +530,9 @@ static void tcp_event_data_recv(struct sock *sk, struct tcp_sock *tp, struct sk_
* To save cycles in the RFC 1323 implementation it was better to break
* it up into three procedures. -- erics
*/
-static void tcp_rtt_estimator(struct sock *sk, const __u32 mrtt, u32 *usrtt)
+static void tcp_rtt_estimator(struct sock *sk, const __u32 mrtt)
{
struct tcp_sock *tp = tcp_sk(sk);
- const struct inet_connection_sock *icsk = inet_csk(sk);
long m = mrtt; /* RTT */
/* The following amusing code comes from Jacobson's
@@ -565,7 +546,7 @@ static void tcp_rtt_estimator(struct sock *sk, const __u32 mrtt, u32 *usrtt)
*
* Funny. This algorithm seems to be very broken.
* These formulae increase RTO, when it should be decreased, increase
- * too slowly, when it should be incresed fastly, decrease too fastly
+ * too slowly, when it should be increased fastly, decrease too fastly
* etc. I guess in BSD RTO takes ONE value, so that it is absolutely
* does not matter how to _calculate_ it. Seems, it was trap
* that VJ failed to avoid. 8)
@@ -610,9 +591,6 @@ static void tcp_rtt_estimator(struct sock *sk, const __u32 mrtt, u32 *usrtt)
tp->mdev_max = tp->rttvar = max(tp->mdev, TCP_RTO_MIN);
tp->rtt_seq = tp->snd_nxt;
}
-
- if (icsk->icsk_ca_ops->rtt_sample)
- icsk->icsk_ca_ops->rtt_sample(sk, *usrtt);
}
/* Calculate rto without backoff. This is the second half of Van Jacobson's
@@ -629,14 +607,14 @@ static inline void tcp_set_rto(struct sock *sk)
* at least by solaris and freebsd. "Erratic ACKs" has _nothing_
* to do with delayed acks, because at cwnd>2 true delack timeout
* is invisible. Actually, Linux-2.4 also generates erratic
- * ACKs in some curcumstances.
+ * ACKs in some circumstances.
*/
inet_csk(sk)->icsk_rto = (tp->srtt >> 3) + tp->rttvar;
/* 2. Fixups made earlier cannot be right.
* If we do not estimate RTO correctly without them,
* all the algo is pure shit and should be replaced
- * with correct one. It is exaclty, which we pretend to do.
+ * with correct one. It is exactly, which we pretend to do.
*/
}
@@ -794,7 +772,7 @@ static void tcp_init_metrics(struct sock *sk)
* to make it more realistic.
*
* A bit of theory. RTT is time passed after "normal" sized packet
- * is sent until it is ACKed. In normal curcumstances sending small
+ * is sent until it is ACKed. In normal circumstances sending small
* packets force peer to delay ACKs and calculation is correct too.
* The algorithm is adaptive and, provided we follow specs, it
* NEVER underestimate RTT. BUT! If peer tries to make some clever
@@ -919,18 +897,32 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_
int prior_fackets;
u32 lost_retrans = 0;
int flag = 0;
+ int dup_sack = 0;
int i;
if (!tp->sacked_out)
tp->fackets_out = 0;
prior_fackets = tp->fackets_out;
- for (i=0; i<num_sacks; i++, sp++) {
- struct sk_buff *skb;
- __u32 start_seq = ntohl(sp->start_seq);
- __u32 end_seq = ntohl(sp->end_seq);
- int fack_count = 0;
- int dup_sack = 0;
+ /* SACK fastpath:
+ * if the only SACK change is the increase of the end_seq of
+ * the first block then only apply that SACK block
+ * and use retrans queue hinting otherwise slowpath */
+ flag = 1;
+ for (i = 0; i< num_sacks; i++) {
+ __u32 start_seq = ntohl(sp[i].start_seq);
+ __u32 end_seq = ntohl(sp[i].end_seq);
+
+ if (i == 0){
+ if (tp->recv_sack_cache[i].start_seq != start_seq)
+ flag = 0;
+ } else {
+ if ((tp->recv_sack_cache[i].start_seq != start_seq) ||
+ (tp->recv_sack_cache[i].end_seq != end_seq))
+ flag = 0;
+ }
+ tp->recv_sack_cache[i].start_seq = start_seq;
+ tp->recv_sack_cache[i].end_seq = end_seq;
/* Check for D-SACK. */
if (i == 0) {
@@ -962,15 +954,58 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_
if (before(ack, prior_snd_una - tp->max_window))
return 0;
}
+ }
+
+ if (flag)
+ num_sacks = 1;
+ else {
+ int j;
+ tp->fastpath_skb_hint = NULL;
+
+ /* order SACK blocks to allow in order walk of the retrans queue */
+ for (i = num_sacks-1; i > 0; i--) {
+ for (j = 0; j < i; j++){
+ if (after(ntohl(sp[j].start_seq),
+ ntohl(sp[j+1].start_seq))){
+ sp[j].start_seq = htonl(tp->recv_sack_cache[j+1].start_seq);
+ sp[j].end_seq = htonl(tp->recv_sack_cache[j+1].end_seq);
+ sp[j+1].start_seq = htonl(tp->recv_sack_cache[j].start_seq);
+ sp[j+1].end_seq = htonl(tp->recv_sack_cache[j].end_seq);
+ }
+
+ }
+ }
+ }
+
+ /* clear flag as used for different purpose in following code */
+ flag = 0;
+
+ for (i=0; i<num_sacks; i++, sp++) {
+ struct sk_buff *skb;
+ __u32 start_seq = ntohl(sp->start_seq);
+ __u32 end_seq = ntohl(sp->end_seq);
+ int fack_count;
+
+ /* Use SACK fastpath hint if valid */
+ if (tp->fastpath_skb_hint) {
+ skb = tp->fastpath_skb_hint;
+ fack_count = tp->fastpath_cnt_hint;
+ } else {
+ skb = sk->sk_write_queue.next;
+ fack_count = 0;
+ }
/* Event "B" in the comment above. */
if (after(end_seq, tp->high_seq))
flag |= FLAG_DATA_LOST;
- sk_stream_for_retrans_queue(skb, sk) {
+ sk_stream_for_retrans_queue_from(skb, sk) {
int in_sack, pcount;
u8 sacked;
+ tp->fastpath_skb_hint = skb;
+ tp->fastpath_cnt_hint = fack_count;
+
/* The retransmission queue is always in order, so
* we can short-circuit the walk early.
*/
@@ -1045,6 +1080,9 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_
TCP_SKB_CB(skb)->sacked &= ~(TCPCB_LOST|TCPCB_SACKED_RETRANS);
tp->lost_out -= tcp_skb_pcount(skb);
tp->retrans_out -= tcp_skb_pcount(skb);
+
+ /* clear lost hint */
+ tp->retransmit_skb_hint = NULL;
}
} else {
/* New sack for not retransmitted frame,
@@ -1057,6 +1095,9 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_
if (sacked & TCPCB_LOST) {
TCP_SKB_CB(skb)->sacked &= ~TCPCB_LOST;
tp->lost_out -= tcp_skb_pcount(skb);
+
+ /* clear lost hint */
+ tp->retransmit_skb_hint = NULL;
}
}
@@ -1080,6 +1121,7 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_
(TCP_SKB_CB(skb)->sacked&TCPCB_SACKED_RETRANS)) {
TCP_SKB_CB(skb)->sacked &= ~TCPCB_SACKED_RETRANS;
tp->retrans_out -= tcp_skb_pcount(skb);
+ tp->retransmit_skb_hint = NULL;
}
}
}
@@ -1107,6 +1149,9 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_
TCP_SKB_CB(skb)->sacked &= ~TCPCB_SACKED_RETRANS;
tp->retrans_out -= tcp_skb_pcount(skb);
+ /* clear lost hint */
+ tp->retransmit_skb_hint = NULL;
+
if (!(TCP_SKB_CB(skb)->sacked&(TCPCB_LOST|TCPCB_SACKED_ACKED))) {
tp->lost_out += tcp_skb_pcount(skb);
TCP_SKB_CB(skb)->sacked |= TCPCB_LOST;
@@ -1214,6 +1259,8 @@ static void tcp_enter_frto_loss(struct sock *sk)
tcp_set_ca_state(sk, TCP_CA_Loss);
tp->high_seq = tp->frto_highmark;
TCP_ECN_queue_cwr(tp);
+
+ clear_all_retrans_hints(tp);
}
void tcp_clear_retrans(struct tcp_sock *tp)
@@ -1251,6 +1298,7 @@ void tcp_enter_loss(struct sock *sk, int how)
tp->snd_cwnd_cnt = 0;
tp->snd_cwnd_stamp = tcp_time_stamp;
+ tp->bytes_acked = 0;
tcp_clear_retrans(tp);
/* Push undo marker, if it was plain RTO and nothing
@@ -1279,6 +1327,8 @@ void tcp_enter_loss(struct sock *sk, int how)
tcp_set_ca_state(sk, TCP_CA_Loss);
tp->high_seq = tp->snd_nxt;
TCP_ECN_queue_cwr(tp);
+
+ clear_all_retrans_hints(tp);
}
static int tcp_check_sack_reneging(struct sock *sk)
@@ -1503,17 +1553,37 @@ static void tcp_mark_head_lost(struct sock *sk, struct tcp_sock *tp,
int packets, u32 high_seq)
{
struct sk_buff *skb;
- int cnt = packets;
+ int cnt;
- BUG_TRAP(cnt <= tp->packets_out);
+ BUG_TRAP(packets <= tp->packets_out);
+ if (tp->lost_skb_hint) {
+ skb = tp->lost_skb_hint;
+ cnt = tp->lost_cnt_hint;
+ } else {
+ skb = sk->sk_write_queue.next;
+ cnt = 0;
+ }
- sk_stream_for_retrans_queue(skb, sk) {
- cnt -= tcp_skb_pcount(skb);
- if (cnt < 0 || after(TCP_SKB_CB(skb)->end_seq, high_seq))
+ sk_stream_for_retrans_queue_from(skb, sk) {
+ /* TODO: do this better */
+ /* this is not the most efficient way to do this... */
+ tp->lost_skb_hint = skb;
+ tp->lost_cnt_hint = cnt;
+ cnt += tcp_skb_pcount(skb);
+ if (cnt > packets || after(TCP_SKB_CB(skb)->end_seq, high_seq))
break;
if (!(TCP_SKB_CB(skb)->sacked&TCPCB_TAGBITS)) {
TCP_SKB_CB(skb)->sacked |= TCPCB_LOST;
tp->lost_out += tcp_skb_pcount(skb);
+
+ /* clear xmit_retransmit_queue hints
+ * if this is beyond hint */
+ if(tp->retransmit_skb_hint != NULL &&
+ before(TCP_SKB_CB(skb)->seq,
+ TCP_SKB_CB(tp->retransmit_skb_hint)->seq)) {
+
+ tp->retransmit_skb_hint = NULL;
+ }
}
}
tcp_sync_left_out(tp);
@@ -1540,13 +1610,28 @@ static void tcp_update_scoreboard(struct sock *sk, struct tcp_sock *tp)
if (tcp_head_timedout(sk, tp)) {
struct sk_buff *skb;
- sk_stream_for_retrans_queue(skb, sk) {
- if (tcp_skb_timedout(sk, skb) &&
- !(TCP_SKB_CB(skb)->sacked&TCPCB_TAGBITS)) {
+ skb = tp->scoreboard_skb_hint ? tp->scoreboard_skb_hint
+ : sk->sk_write_queue.next;
+
+ sk_stream_for_retrans_queue_from(skb, sk) {
+ if (!tcp_skb_timedout(sk, skb))
+ break;
+
+ if (!(TCP_SKB_CB(skb)->sacked&TCPCB_TAGBITS)) {
TCP_SKB_CB(skb)->sacked |= TCPCB_LOST;
tp->lost_out += tcp_skb_pcount(skb);
+
+ /* clear xmit_retrans hint */
+ if (tp->retransmit_skb_hint &&
+ before(TCP_SKB_CB(skb)->seq,
+ TCP_SKB_CB(tp->retransmit_skb_hint)->seq))
+
+ tp->retransmit_skb_hint = NULL;
}
}
+
+ tp->scoreboard_skb_hint = skb;
+
tcp_sync_left_out(tp);
}
}
@@ -1626,6 +1711,10 @@ static void tcp_undo_cwr(struct sock *sk, const int undo)
}
tcp_moderate_cwnd(tp);
tp->snd_cwnd_stamp = tcp_time_stamp;
+
+ /* There is something screwy going on with the retrans hints after
+ an undo */
+ clear_all_retrans_hints(tp);
}
static inline int tcp_may_undo(struct tcp_sock *tp)
@@ -1709,6 +1798,9 @@ static int tcp_try_undo_loss(struct sock *sk, struct tcp_sock *tp)
sk_stream_for_retrans_queue(skb, sk) {
TCP_SKB_CB(skb)->sacked &= ~TCPCB_LOST;
}
+
+ clear_all_retrans_hints(tp);
+
DBGUNDO(sk, tp, "partial loss");
tp->lost_out = 0;
tp->left_out = tp->sacked_out;
@@ -1908,6 +2000,7 @@ tcp_fastretrans_alert(struct sock *sk, u32 prior_snd_una,
TCP_ECN_queue_cwr(tp);
}
+ tp->bytes_acked = 0;
tp->snd_cwnd_cnt = 0;
tcp_set_ca_state(sk, TCP_CA_Recovery);
}
@@ -1919,9 +2012,9 @@ tcp_fastretrans_alert(struct sock *sk, u32 prior_snd_una,
}
/* Read draft-ietf-tcplw-high-performance before mucking
- * with this code. (Superceeds RFC1323)
+ * with this code. (Supersedes RFC1323)
*/
-static void tcp_ack_saw_tstamp(struct sock *sk, u32 *usrtt, int flag)
+static void tcp_ack_saw_tstamp(struct sock *sk, int flag)
{
/* RTTM Rule: A TSecr value received in a segment is used to
* update the averaged RTT measurement only if the segment
@@ -1932,7 +2025,7 @@ static void tcp_ack_saw_tstamp(struct sock *sk, u32 *usrtt, int flag)
* 1998/04/10 Andrey V. Savochkin <saw@msu.ru>
*
* Changed: reset backoff as soon as we see the first valid sample.
- * If we do not, we get strongly overstimated rto. With timestamps
+ * If we do not, we get strongly overestimated rto. With timestamps
* samples are accepted even from very old segments: f.e., when rtt=1
* increases to 8, we retransmit 5 times and after 8 seconds delayed
* answer arrives rto becomes 120 seconds! If at least one of segments
@@ -1940,13 +2033,13 @@ static void tcp_ack_saw_tstamp(struct sock *sk, u32 *usrtt, int flag)
*/
struct tcp_sock *tp = tcp_sk(sk);
const __u32 seq_rtt = tcp_time_stamp - tp->rx_opt.rcv_tsecr;
- tcp_rtt_estimator(sk, seq_rtt, usrtt);
+ tcp_rtt_estimator(sk, seq_rtt);
tcp_set_rto(sk);
inet_csk(sk)->icsk_backoff = 0;
tcp_bound_rto(sk);
}
-static void tcp_ack_no_tstamp(struct sock *sk, u32 seq_rtt, u32 *usrtt, int flag)
+static void tcp_ack_no_tstamp(struct sock *sk, u32 seq_rtt, int flag)
{
/* We don't have a timestamp. Can only use
* packets that are not retransmitted to determine
@@ -1960,21 +2053,21 @@ static void tcp_ack_no_tstamp(struct sock *sk, u32 seq_rtt, u32 *usrtt, int flag
if (flag & FLAG_RETRANS_DATA_ACKED)
return;
- tcp_rtt_estimator(sk, seq_rtt, usrtt);
+ tcp_rtt_estimator(sk, seq_rtt);
tcp_set_rto(sk);
inet_csk(sk)->icsk_backoff = 0;
tcp_bound_rto(sk);
}
static inline void tcp_ack_update_rtt(struct sock *sk, const int flag,
- const s32 seq_rtt, u32 *usrtt)
+ const s32 seq_rtt)
{
const struct tcp_sock *tp = tcp_sk(sk);
/* Note that peer MAY send zero echo. In this case it is ignored. (rfc1323) */
if (tp->rx_opt.saw_tstamp && tp->rx_opt.rcv_tsecr)
- tcp_ack_saw_tstamp(sk, usrtt, flag);
+ tcp_ack_saw_tstamp(sk, flag);
else if (seq_rtt >= 0)
- tcp_ack_no_tstamp(sk, seq_rtt, usrtt, flag);
+ tcp_ack_no_tstamp(sk, seq_rtt, flag);
}
static inline void tcp_cong_avoid(struct sock *sk, u32 ack, u32 rtt,
@@ -2054,20 +2147,27 @@ static int tcp_tso_acked(struct sock *sk, struct sk_buff *skb,
return acked;
}
+static inline u32 tcp_usrtt(const struct sk_buff *skb)
+{
+ struct timeval tv, now;
+
+ do_gettimeofday(&now);
+ skb_get_timestamp(skb, &tv);
+ return (now.tv_sec - tv.tv_sec) * 1000000 + (now.tv_usec - tv.tv_usec);
+}
/* Remove acknowledged frames from the retransmission queue. */
-static int tcp_clean_rtx_queue(struct sock *sk, __s32 *seq_rtt_p, s32 *seq_usrtt)
+static int tcp_clean_rtx_queue(struct sock *sk, __s32 *seq_rtt_p)
{
struct tcp_sock *tp = tcp_sk(sk);
+ const struct inet_connection_sock *icsk = inet_csk(sk);
struct sk_buff *skb;
__u32 now = tcp_time_stamp;
int acked = 0;
__s32 seq_rtt = -1;
- struct timeval usnow;
u32 pkts_acked = 0;
-
- if (seq_usrtt)
- do_gettimeofday(&usnow);
+ void (*rtt_sample)(struct sock *sk, u32 usrtt)
+ = icsk->icsk_ca_ops->rtt_sample;
while ((skb = skb_peek(&sk->sk_write_queue)) &&
skb != sk->sk_send_head) {
@@ -2107,16 +2207,11 @@ static int tcp_clean_rtx_queue(struct sock *sk, __s32 *seq_rtt_p, s32 *seq_usrtt
tp->retrans_out -= tcp_skb_pcount(skb);
acked |= FLAG_RETRANS_DATA_ACKED;
seq_rtt = -1;
- } else if (seq_rtt < 0)
+ } else if (seq_rtt < 0) {
seq_rtt = now - scb->when;
- if (seq_usrtt) {
- struct timeval tv;
-
- skb_get_timestamp(skb, &tv);
- *seq_usrtt = (usnow.tv_sec - tv.tv_sec) * 1000000
- + (usnow.tv_usec - tv.tv_usec);
+ if (rtt_sample)
+ (*rtt_sample)(sk, tcp_usrtt(skb));
}
-
if (sacked & TCPCB_SACKED_ACKED)
tp->sacked_out -= tcp_skb_pcount(skb);
if (sacked & TCPCB_LOST)
@@ -2126,17 +2221,20 @@ static int tcp_clean_rtx_queue(struct sock *sk, __s32 *seq_rtt_p, s32 *seq_usrtt
!before(scb->end_seq, tp->snd_up))
tp->urg_mode = 0;
}
- } else if (seq_rtt < 0)
+ } else if (seq_rtt < 0) {
seq_rtt = now - scb->when;
+ if (rtt_sample)
+ (*rtt_sample)(sk, tcp_usrtt(skb));
+ }
tcp_dec_pcount_approx(&tp->fackets_out, skb);
tcp_packets_out_dec(tp, skb);
__skb_unlink(skb, &sk->sk_write_queue);
sk_stream_free_skb(sk, skb);
+ clear_all_retrans_hints(tp);
}
if (acked&FLAG_ACKED) {
- const struct inet_connection_sock *icsk = inet_csk(sk);
- tcp_ack_update_rtt(sk, acked, seq_rtt, seq_usrtt);
+ tcp_ack_update_rtt(sk, acked, seq_rtt);
tcp_ack_packets_out(sk, tp);
if (icsk->icsk_ca_ops->pkts_acked)
@@ -2284,7 +2382,7 @@ static void tcp_process_frto(struct sock *sk, u32 prior_snd_una)
}
/* F-RTO affects on two new ACKs following RTO.
- * At latest on third ACK the TCP behavor is back to normal.
+ * At latest on third ACK the TCP behavior is back to normal.
*/
tp->frto_counter = (tp->frto_counter + 1) % 3;
}
@@ -2299,7 +2397,6 @@ static int tcp_ack(struct sock *sk, struct sk_buff *skb, int flag)
u32 ack = TCP_SKB_CB(skb)->ack_seq;
u32 prior_in_flight;
s32 seq_rtt;
- s32 seq_usrtt = 0;
int prior_packets;
/* If the ack is newer than sent or older than previous acks
@@ -2311,6 +2408,9 @@ static int tcp_ack(struct sock *sk, struct sk_buff *skb, int flag)
if (before(ack, prior_snd_una))
goto old_ack;
+ if (sysctl_tcp_abc && icsk->icsk_ca_state < TCP_CA_CWR)
+ tp->bytes_acked += ack - prior_snd_una;
+
if (!(flag&FLAG_SLOWPATH) && after(ack, prior_snd_una)) {
/* Window is constant, pure forward advance.
* No more checks are required.
@@ -2352,14 +2452,13 @@ static int tcp_ack(struct sock *sk, struct sk_buff *skb, int flag)
prior_in_flight = tcp_packets_in_flight(tp);
/* See if we can take anything off of the retransmit queue. */
- flag |= tcp_clean_rtx_queue(sk, &seq_rtt,
- icsk->icsk_ca_ops->rtt_sample ? &seq_usrtt : NULL);
+ flag |= tcp_clean_rtx_queue(sk, &seq_rtt);
if (tp->frto_counter)
tcp_process_frto(sk, prior_snd_una);
if (tcp_ack_is_dubious(sk, flag)) {
- /* Advanve CWND, if state allows this. */
+ /* Advance CWND, if state allows this. */
if ((flag & FLAG_DATA_ACKED) && tcp_may_raise_cwnd(sk, flag))
tcp_cong_avoid(sk, ack, seq_rtt, prior_in_flight, 0);
tcp_fastretrans_alert(sk, prior_snd_una, prior_packets, flag);
@@ -3148,7 +3247,7 @@ tcp_collapse(struct sock *sk, struct sk_buff_head *list,
{
struct sk_buff *skb;
- /* First, check that queue is collapsable and find
+ /* First, check that queue is collapsible and find
* the point where collapsing can be useful. */
for (skb = head; skb != tail; ) {
/* No new bits? It is possible on ofo queue. */
@@ -3456,7 +3555,7 @@ static __inline__ void tcp_ack_snd_check(struct sock *sk)
/*
* This routine is only called when we have urgent data
- * signalled. Its the 'slow' part of tcp_urg. It could be
+ * signaled. Its the 'slow' part of tcp_urg. It could be
* moved inline now as tcp_urg is only called from one
* place. We handle URGent data wrong. We have to - as
* BSD still doesn't use the correction from RFC961.
@@ -3501,7 +3600,7 @@ static void tcp_check_urg(struct sock * sk, struct tcphdr * th)
* urgent. To do this requires some care. We cannot just ignore
* tp->copied_seq since we would read the last urgent byte again
* as data, nor can we alter copied_seq until this data arrives
- * or we break the sematics of SIOCATMARK (and thus sockatmark())
+ * or we break the semantics of SIOCATMARK (and thus sockatmark())
*
* NOTE. Double Dutch. Rendering to plain English: author of comment
* above did something sort of send("A", MSG_OOB); send("B", MSG_OOB);
@@ -3646,7 +3745,7 @@ int tcp_rcv_established(struct sock *sk, struct sk_buff *skb,
tp->rx_opt.saw_tstamp = 0;
/* pred_flags is 0xS?10 << 16 + snd_wnd
- * if header_predition is to be made
+ * if header_prediction is to be made
* 'S' will always be tp->tcp_header_len >> 2
* '?' will be 0 for the fast path, otherwise pred_flags is 0 to
* turn it off (when there are holes in the receive
@@ -4242,7 +4341,7 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
*/
if (tp->rx_opt.saw_tstamp && tp->rx_opt.rcv_tsecr &&
!tp->srtt)
- tcp_ack_saw_tstamp(sk, NULL, 0);
+ tcp_ack_saw_tstamp(sk, 0);
if (tp->rx_opt.tstamp_ok)
tp->advmss -= TCPOLEN_TSTAMP_ALIGNED;
@@ -4372,6 +4471,7 @@ discard:
EXPORT_SYMBOL(sysctl_tcp_ecn);
EXPORT_SYMBOL(sysctl_tcp_reordering);
+EXPORT_SYMBOL(sysctl_tcp_abc);
EXPORT_SYMBOL(tcp_parse_options);
EXPORT_SYMBOL(tcp_rcv_established);
EXPORT_SYMBOL(tcp_rcv_state_process);
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index c85819d8474b..4d5021e1929b 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -39,7 +39,7 @@
* request_sock handling and moved
* most of it into the af independent code.
* Added tail drop and some other bugfixes.
- * Added new listen sematics.
+ * Added new listen semantics.
* Mike McLagan : Routing by source
* Juan Jose Ciarlante: ip_dynaddr bits
* Andi Kleen: various fixes.
@@ -93,8 +93,6 @@ struct inet_hashinfo __cacheline_aligned tcp_hashinfo = {
.lhash_lock = RW_LOCK_UNLOCKED,
.lhash_users = ATOMIC_INIT(0),
.lhash_wait = __WAIT_QUEUE_HEAD_INITIALIZER(tcp_hashinfo.lhash_wait),
- .portalloc_lock = SPIN_LOCK_UNLOCKED,
- .port_rover = 1024 - 1,
};
static int tcp_v4_get_port(struct sock *sk, unsigned short snum)
@@ -825,8 +823,7 @@ out:
*/
static void tcp_v4_reqsk_destructor(struct request_sock *req)
{
- if (inet_rsk(req)->opt)
- kfree(inet_rsk(req)->opt);
+ kfree(inet_rsk(req)->opt);
}
static inline void syn_flood_warning(struct sk_buff *skb)
@@ -1113,24 +1110,18 @@ static struct sock *tcp_v4_hnd_req(struct sock *sk, struct sk_buff *skb)
static int tcp_v4_checksum_init(struct sk_buff *skb)
{
if (skb->ip_summed == CHECKSUM_HW) {
- skb->ip_summed = CHECKSUM_UNNECESSARY;
if (!tcp_v4_check(skb->h.th, skb->len, skb->nh.iph->saddr,
- skb->nh.iph->daddr, skb->csum))
+ skb->nh.iph->daddr, skb->csum)) {
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
return 0;
-
- LIMIT_NETDEBUG(KERN_DEBUG "hw tcp v4 csum failed\n");
- skb->ip_summed = CHECKSUM_NONE;
+ }
}
+
+ skb->csum = csum_tcpudp_nofold(skb->nh.iph->saddr, skb->nh.iph->daddr,
+ skb->len, IPPROTO_TCP, 0);
+
if (skb->len <= 76) {
- if (tcp_v4_check(skb->h.th, skb->len, skb->nh.iph->saddr,
- skb->nh.iph->daddr,
- skb_checksum(skb, 0, skb->len, 0)))
- return -1;
- skb->ip_summed = CHECKSUM_UNNECESSARY;
- } else {
- skb->csum = ~tcp_v4_check(skb->h.th, skb->len,
- skb->nh.iph->saddr,
- skb->nh.iph->daddr, 0);
+ return __skb_checksum_complete(skb);
}
return 0;
}
@@ -1219,10 +1210,10 @@ int tcp_v4_rcv(struct sk_buff *skb)
/* An explanation is required here, I think.
* Packet length and doff are validated by header prediction,
- * provided case of th->doff==0 is elimineted.
+ * provided case of th->doff==0 is eliminated.
* So, we defer the checks. */
if ((skb->ip_summed != CHECKSUM_UNNECESSARY &&
- tcp_v4_checksum_init(skb) < 0))
+ tcp_v4_checksum_init(skb)))
goto bad_packet;
th = skb->h.th;
diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c
index b1a63b2c6b4a..1b66a2ac4321 100644
--- a/net/ipv4/tcp_minisocks.c
+++ b/net/ipv4/tcp_minisocks.c
@@ -158,7 +158,7 @@ kill_with_rst:
/* I am shamed, but failed to make it more elegant.
* Yes, it is direct reference to IP, which is impossible
* to generalize to IPv6. Taking into account that IPv6
- * do not undertsnad recycling in any case, it not
+ * do not understand recycling in any case, it not
* a big problem in practice. --ANK */
if (tw->tw_family == AF_INET &&
tcp_death_row.sysctl_tw_recycle && tcptw->tw_ts_recent_stamp &&
@@ -194,7 +194,7 @@ kill_with_rst:
/* In window segment, it may be only reset or bare ack. */
if (th->rst) {
- /* This is TIME_WAIT assasination, in two flavors.
+ /* This is TIME_WAIT assassination, in two flavors.
* Oh well... nobody has a sufficient solution to this
* protocol bug yet.
*/
@@ -380,6 +380,7 @@ struct sock *tcp_create_openreq_child(struct sock *sk, struct request_sock *req,
*/
newtp->snd_cwnd = 2;
newtp->snd_cwnd_cnt = 0;
+ newtp->bytes_acked = 0;
newtp->frto_counter = 0;
newtp->frto_highmark = 0;
@@ -550,7 +551,7 @@ struct sock *tcp_check_req(struct sock *sk,struct sk_buff *skb,
/* RFC793 page 36: "If the connection is in any non-synchronized state ...
* and the incoming segment acknowledges something not yet
- * sent (the segment carries an unaccaptable ACK) ...
+ * sent (the segment carries an unacceptable ACK) ...
* a reset is sent."
*
* Invalid ACK: reset will be sent by listening socket
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index b907456a79f4..029c70dfb585 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -436,6 +436,8 @@ int tcp_fragment(struct sock *sk, struct sk_buff *skb, u32 len, unsigned int mss
u16 flags;
BUG_ON(len > skb->len);
+
+ clear_all_retrans_hints(tp);
nsize = skb_headlen(skb) - len;
if (nsize < 0)
nsize = 0;
@@ -599,7 +601,7 @@ int tcp_trim_head(struct sock *sk, struct sk_buff *skb, u32 len)
for TCP options, but includes only bare TCP header.
tp->rx_opt.mss_clamp is mss negotiated at connection setup.
- It is minumum of user_mss and mss received with SYN.
+ It is minimum of user_mss and mss received with SYN.
It also does not include TCP options.
tp->pmtu_cookie is last pmtu, seen by this function.
@@ -1171,7 +1173,7 @@ u32 __tcp_select_window(struct sock *sk)
{
struct inet_connection_sock *icsk = inet_csk(sk);
struct tcp_sock *tp = tcp_sk(sk);
- /* MSS for the peer's data. Previous verions used mss_clamp
+ /* MSS for the peer's data. Previous versions used mss_clamp
* here. I don't know if the value based on our guesses
* of peer's MSS is better for the performance. It's more correct
* but may be worse for the performance because of rcv_mss
@@ -1260,7 +1262,10 @@ static void tcp_retrans_try_collapse(struct sock *sk, struct sk_buff *skb, int m
BUG_ON(tcp_skb_pcount(skb) != 1 ||
tcp_skb_pcount(next_skb) != 1);
- /* Ok. We will be able to collapse the packet. */
+ /* changing transmit queue under us so clear hints */
+ clear_all_retrans_hints(tp);
+
+ /* Ok. We will be able to collapse the packet. */
__skb_unlink(next_skb, &sk->sk_write_queue);
memcpy(skb_put(skb, next_skb_size), next_skb->data, next_skb_size);
@@ -1330,6 +1335,8 @@ void tcp_simple_retransmit(struct sock *sk)
}
}
+ clear_all_retrans_hints(tp);
+
if (!lost)
return;
@@ -1361,7 +1368,7 @@ int tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb)
int err;
/* Do not sent more than we queued. 1/4 is reserved for possible
- * copying overhead: frgagmentation, tunneling, mangling etc.
+ * copying overhead: fragmentation, tunneling, mangling etc.
*/
if (atomic_read(&sk->sk_wmem_alloc) >
min(sk->sk_wmem_queued + (sk->sk_wmem_queued >> 2), sk->sk_sndbuf))
@@ -1468,13 +1475,25 @@ void tcp_xmit_retransmit_queue(struct sock *sk)
const struct inet_connection_sock *icsk = inet_csk(sk);
struct tcp_sock *tp = tcp_sk(sk);
struct sk_buff *skb;
- int packet_cnt = tp->lost_out;
+ int packet_cnt;
+
+ if (tp->retransmit_skb_hint) {
+ skb = tp->retransmit_skb_hint;
+ packet_cnt = tp->retransmit_cnt_hint;
+ }else{
+ skb = sk->sk_write_queue.next;
+ packet_cnt = 0;
+ }
/* First pass: retransmit lost packets. */
- if (packet_cnt) {
- sk_stream_for_retrans_queue(skb, sk) {
+ if (tp->lost_out) {
+ sk_stream_for_retrans_queue_from(skb, sk) {
__u8 sacked = TCP_SKB_CB(skb)->sacked;
+ /* we could do better than to assign each time */
+ tp->retransmit_skb_hint = skb;
+ tp->retransmit_cnt_hint = packet_cnt;
+
/* Assume this retransmit will generate
* only one packet for congestion window
* calculation purposes. This works because
@@ -1485,10 +1504,12 @@ void tcp_xmit_retransmit_queue(struct sock *sk)
if (tcp_packets_in_flight(tp) >= tp->snd_cwnd)
return;
- if (sacked&TCPCB_LOST) {
+ if (sacked & TCPCB_LOST) {
if (!(sacked&(TCPCB_SACKED_ACKED|TCPCB_SACKED_RETRANS))) {
- if (tcp_retransmit_skb(sk, skb))
+ if (tcp_retransmit_skb(sk, skb)) {
+ tp->retransmit_skb_hint = NULL;
return;
+ }
if (icsk->icsk_ca_state != TCP_CA_Loss)
NET_INC_STATS_BH(LINUX_MIB_TCPFASTRETRANS);
else
@@ -1501,8 +1522,8 @@ void tcp_xmit_retransmit_queue(struct sock *sk)
TCP_RTO_MAX);
}
- packet_cnt -= tcp_skb_pcount(skb);
- if (packet_cnt <= 0)
+ packet_cnt += tcp_skb_pcount(skb);
+ if (packet_cnt >= tp->lost_out)
break;
}
}
@@ -1528,9 +1549,18 @@ void tcp_xmit_retransmit_queue(struct sock *sk)
if (tcp_may_send_now(sk, tp))
return;
- packet_cnt = 0;
+ if (tp->forward_skb_hint) {
+ skb = tp->forward_skb_hint;
+ packet_cnt = tp->forward_cnt_hint;
+ } else{
+ skb = sk->sk_write_queue.next;
+ packet_cnt = 0;
+ }
+
+ sk_stream_for_retrans_queue_from(skb, sk) {
+ tp->forward_cnt_hint = packet_cnt;
+ tp->forward_skb_hint = skb;
- sk_stream_for_retrans_queue(skb, sk) {
/* Similar to the retransmit loop above we
* can pretend that the retransmitted SKB
* we send out here will be composed of one
@@ -1547,8 +1577,10 @@ void tcp_xmit_retransmit_queue(struct sock *sk)
continue;
/* Ok, retransmit it. */
- if (tcp_retransmit_skb(sk, skb))
+ if (tcp_retransmit_skb(sk, skb)) {
+ tp->forward_skb_hint = NULL;
break;
+ }
if (skb == skb_peek(&sk->sk_write_queue))
inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS,
@@ -2058,3 +2090,4 @@ EXPORT_SYMBOL(tcp_connect);
EXPORT_SYMBOL(tcp_make_synack);
EXPORT_SYMBOL(tcp_simple_retransmit);
EXPORT_SYMBOL(tcp_sync_mss);
+EXPORT_SYMBOL(sysctl_tcp_tso_win_divisor);
diff --git a/net/ipv4/tcp_scalable.c b/net/ipv4/tcp_scalable.c
index 327770bf5522..26d7486ee501 100644
--- a/net/ipv4/tcp_scalable.c
+++ b/net/ipv4/tcp_scalable.c
@@ -20,20 +20,20 @@ static void tcp_scalable_cong_avoid(struct sock *sk, u32 ack, u32 rtt,
u32 in_flight, int flag)
{
struct tcp_sock *tp = tcp_sk(sk);
- if (in_flight < tp->snd_cwnd)
+
+ if (!tcp_is_cwnd_limited(sk, in_flight))
return;
- if (tp->snd_cwnd <= tp->snd_ssthresh) {
- tp->snd_cwnd++;
- } else {
+ if (tp->snd_cwnd <= tp->snd_ssthresh)
+ tcp_slow_start(tp);
+ else {
tp->snd_cwnd_cnt++;
if (tp->snd_cwnd_cnt > min(tp->snd_cwnd, TCP_SCALABLE_AI_CNT)){
- tp->snd_cwnd++;
+ if (tp->snd_cwnd < tp->snd_cwnd_clamp)
+ tp->snd_cwnd++;
tp->snd_cwnd_cnt = 0;
}
}
- tp->snd_cwnd = min_t(u32, tp->snd_cwnd, tp->snd_cwnd_clamp);
- tp->snd_cwnd_stamp = tcp_time_stamp;
}
static u32 tcp_scalable_ssthresh(struct sock *sk)
diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c
index 415ee47ac1c5..e1880959614a 100644
--- a/net/ipv4/tcp_timer.c
+++ b/net/ipv4/tcp_timer.c
@@ -58,7 +58,7 @@ static void tcp_write_err(struct sock *sk)
* to prevent DoS attacks. It is called when a retransmission timeout
* or zero probe timeout occurs on orphaned socket.
*
- * Criterium is still not confirmed experimentally and may change.
+ * Criteria is still not confirmed experimentally and may change.
* We kill the socket, if:
* 1. If number of orphaned sockets exceeds an administratively configured
* limit.
@@ -132,7 +132,7 @@ static int tcp_write_timeout(struct sock *sk)
hole detection. :-(
It is place to make it. It is not made. I do not want
- to make it. It is disguisting. It does not work in any
+ to make it. It is disgusting. It does not work in any
case. Let me to cite the same draft, which requires for
us to implement this:
diff --git a/net/ipv4/tcp_vegas.c b/net/ipv4/tcp_vegas.c
index 93c5f92070f9..4376814d29fb 100644
--- a/net/ipv4/tcp_vegas.c
+++ b/net/ipv4/tcp_vegas.c
@@ -236,8 +236,7 @@ static void tcp_vegas_cong_avoid(struct sock *sk, u32 ack,
/* We don't have enough RTT samples to do the Vegas
* calculation, so we'll behave like Reno.
*/
- if (tp->snd_cwnd > tp->snd_ssthresh)
- tp->snd_cwnd++;
+ tcp_reno_cong_avoid(sk, ack, seq_rtt, in_flight, cnt);
} else {
u32 rtt, target_cwnd, diff;
@@ -275,7 +274,7 @@ static void tcp_vegas_cong_avoid(struct sock *sk, u32 ack,
*/
diff = (old_wnd << V_PARAM_SHIFT) - target_cwnd;
- if (tp->snd_cwnd < tp->snd_ssthresh) {
+ if (tp->snd_cwnd <= tp->snd_ssthresh) {
/* Slow start. */
if (diff > gamma) {
/* Going too fast. Time to slow down
@@ -295,6 +294,7 @@ static void tcp_vegas_cong_avoid(struct sock *sk, u32 ack,
V_PARAM_SHIFT)+1);
}
+ tcp_slow_start(tp);
} else {
/* Congestion avoidance. */
u32 next_snd_cwnd;
@@ -327,37 +327,17 @@ static void tcp_vegas_cong_avoid(struct sock *sk, u32 ack,
else if (next_snd_cwnd < tp->snd_cwnd)
tp->snd_cwnd--;
}
- }
- /* Wipe the slate clean for the next RTT. */
- vegas->cntRTT = 0;
- vegas->minRTT = 0x7fffffff;
+ if (tp->snd_cwnd < 2)
+ tp->snd_cwnd = 2;
+ else if (tp->snd_cwnd > tp->snd_cwnd_clamp)
+ tp->snd_cwnd = tp->snd_cwnd_clamp;
+ }
}
- /* The following code is executed for every ack we receive,
- * except for conditions checked in should_advance_cwnd()
- * before the call to tcp_cong_avoid(). Mainly this means that
- * we only execute this code if the ack actually acked some
- * data.
- */
-
- /* If we are in slow start, increase our cwnd in response to this ACK.
- * (If we are not in slow start then we are in congestion avoidance,
- * and adjust our congestion window only once per RTT. See the code
- * above.)
- */
- if (tp->snd_cwnd <= tp->snd_ssthresh)
- tp->snd_cwnd++;
-
- /* to keep cwnd from growing without bound */
- tp->snd_cwnd = min_t(u32, tp->snd_cwnd, tp->snd_cwnd_clamp);
-
- /* Make sure that we are never so timid as to reduce our cwnd below
- * 2 MSS.
- *
- * Going below 2 MSS would risk huge delayed ACKs from our receiver.
- */
- tp->snd_cwnd = max(tp->snd_cwnd, 2U);
+ /* Wipe the slate clean for the next RTT. */
+ vegas->cntRTT = 0;
+ vegas->minRTT = 0x7fffffff;
}
/* Extract info for Tcp socket info provided via netlink. */
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index e0bd1013cb0d..2422a5f7195d 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -761,7 +761,7 @@ int udp_ioctl(struct sock *sk, int cmd, unsigned long arg)
static __inline__ int __udp_checksum_complete(struct sk_buff *skb)
{
- return (unsigned short)csum_fold(skb_checksum(skb, 0, skb->len, skb->csum));
+ return __skb_checksum_complete(skb);
}
static __inline__ int udp_checksum_complete(struct sk_buff *skb)
@@ -1100,11 +1100,8 @@ static int udp_checksum_init(struct sk_buff *skb, struct udphdr *uh,
if (uh->check == 0) {
skb->ip_summed = CHECKSUM_UNNECESSARY;
} else if (skb->ip_summed == CHECKSUM_HW) {
- skb->ip_summed = CHECKSUM_UNNECESSARY;
if (!udp_check(uh, ulen, saddr, daddr, skb->csum))
- return 0;
- LIMIT_NETDEBUG(KERN_DEBUG "udp v4 hw csum failure.\n");
- skb->ip_summed = CHECKSUM_NONE;
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
}
if (skb->ip_summed != CHECKSUM_UNNECESSARY)
skb->csum = csum_tcpudp_nofold(saddr, daddr, ulen, IPPROTO_UDP, 0);
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index a970b4727ce8..ddcf7754eec2 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -35,6 +35,9 @@
* YOSHIFUJI Hideaki @USAGI : ARCnet support
* YOSHIFUJI Hideaki @USAGI : convert /proc/net/if_inet6 to
* seq_file.
+ * YOSHIFUJI Hideaki @USAGI : improved source address
+ * selection; consider scope,
+ * status etc.
*/
#include <linux/config.h>
@@ -75,7 +78,7 @@
#ifdef CONFIG_IPV6_PRIVACY
#include <linux/random.h>
#include <linux/crypto.h>
-#include <asm/scatterlist.h>
+#include <linux/scatterlist.h>
#endif
#include <asm/uaccess.h>
@@ -193,46 +196,51 @@ const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT;
#endif
const struct in6_addr in6addr_loopback = IN6ADDR_LOOPBACK_INIT;
-int ipv6_addr_type(const struct in6_addr *addr)
+#define IPV6_ADDR_SCOPE_TYPE(scope) ((scope) << 16)
+
+static inline unsigned ipv6_addr_scope2type(unsigned scope)
+{
+ switch(scope) {
+ case IPV6_ADDR_SCOPE_NODELOCAL:
+ return (IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_NODELOCAL) |
+ IPV6_ADDR_LOOPBACK);
+ case IPV6_ADDR_SCOPE_LINKLOCAL:
+ return (IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_LINKLOCAL) |
+ IPV6_ADDR_LINKLOCAL);
+ case IPV6_ADDR_SCOPE_SITELOCAL:
+ return (IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_SITELOCAL) |
+ IPV6_ADDR_SITELOCAL);
+ }
+ return IPV6_ADDR_SCOPE_TYPE(scope);
+}
+
+int __ipv6_addr_type(const struct in6_addr *addr)
{
- int type;
u32 st;
st = addr->s6_addr32[0];
- if ((st & htonl(0xFF000000)) == htonl(0xFF000000)) {
- type = IPV6_ADDR_MULTICAST;
-
- switch((st & htonl(0x00FF0000))) {
- case __constant_htonl(0x00010000):
- type |= IPV6_ADDR_LOOPBACK;
- break;
-
- case __constant_htonl(0x00020000):
- type |= IPV6_ADDR_LINKLOCAL;
- break;
-
- case __constant_htonl(0x00050000):
- type |= IPV6_ADDR_SITELOCAL;
- break;
- };
- return type;
- }
-
- type = IPV6_ADDR_UNICAST;
-
/* Consider all addresses with the first three bits different of
- 000 and 111 as finished.
+ 000 and 111 as unicasts.
*/
if ((st & htonl(0xE0000000)) != htonl(0x00000000) &&
(st & htonl(0xE0000000)) != htonl(0xE0000000))
- return type;
-
- if ((st & htonl(0xFFC00000)) == htonl(0xFE800000))
- return (IPV6_ADDR_LINKLOCAL | type);
+ return (IPV6_ADDR_UNICAST |
+ IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_GLOBAL));
+
+ if ((st & htonl(0xFF000000)) == htonl(0xFF000000)) {
+ /* multicast */
+ /* addr-select 3.1 */
+ return (IPV6_ADDR_MULTICAST |
+ ipv6_addr_scope2type(IPV6_ADDR_MC_SCOPE(addr)));
+ }
+ if ((st & htonl(0xFFC00000)) == htonl(0xFE800000))
+ return (IPV6_ADDR_LINKLOCAL | IPV6_ADDR_UNICAST |
+ IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_LINKLOCAL)); /* addr-select 3.1 */
if ((st & htonl(0xFFC00000)) == htonl(0xFEC00000))
- return (IPV6_ADDR_SITELOCAL | type);
+ return (IPV6_ADDR_SITELOCAL | IPV6_ADDR_UNICAST |
+ IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_SITELOCAL)); /* addr-select 3.1 */
if ((addr->s6_addr32[0] | addr->s6_addr32[1]) == 0) {
if (addr->s6_addr32[2] == 0) {
@@ -240,24 +248,20 @@ int ipv6_addr_type(const struct in6_addr *addr)
return IPV6_ADDR_ANY;
if (addr->s6_addr32[3] == htonl(0x00000001))
- return (IPV6_ADDR_LOOPBACK | type);
+ return (IPV6_ADDR_LOOPBACK | IPV6_ADDR_UNICAST |
+ IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_LINKLOCAL)); /* addr-select 3.4 */
- return (IPV6_ADDR_COMPATv4 | type);
+ return (IPV6_ADDR_COMPATv4 | IPV6_ADDR_UNICAST |
+ IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_GLOBAL)); /* addr-select 3.3 */
}
if (addr->s6_addr32[2] == htonl(0x0000ffff))
- return IPV6_ADDR_MAPPED;
+ return (IPV6_ADDR_MAPPED |
+ IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_GLOBAL)); /* addr-select 3.3 */
}
- st &= htonl(0xFF000000);
- if (st == 0)
- return IPV6_ADDR_RESERVED;
- st &= htonl(0xFE000000);
- if (st == htonl(0x02000000))
- return IPV6_ADDR_RESERVED; /* for NSAP */
- if (st == htonl(0x04000000))
- return IPV6_ADDR_RESERVED; /* for IPX */
- return type;
+ return (IPV6_ADDR_RESERVED |
+ IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_GLOBAL)); /* addr-select 3.4 */
}
static void addrconf_del_timer(struct inet6_ifaddr *ifp)
@@ -805,138 +809,275 @@ out:
#endif
/*
- * Choose an appropriate source address
- * should do:
- * i) get an address with an appropriate scope
- * ii) see if there is a specific route for the destination and use
- * an address of the attached interface
- * iii) don't use deprecated addresses
+ * Choose an appropriate source address (RFC3484)
*/
-static int inline ipv6_saddr_pref(const struct inet6_ifaddr *ifp, u8 invpref)
+struct ipv6_saddr_score {
+ int addr_type;
+ unsigned int attrs;
+ int matchlen;
+ unsigned int scope;
+ unsigned int rule;
+};
+
+#define IPV6_SADDR_SCORE_LOCAL 0x0001
+#define IPV6_SADDR_SCORE_PREFERRED 0x0004
+#define IPV6_SADDR_SCORE_HOA 0x0008
+#define IPV6_SADDR_SCORE_OIF 0x0010
+#define IPV6_SADDR_SCORE_LABEL 0x0020
+#define IPV6_SADDR_SCORE_PRIVACY 0x0040
+
+static int inline ipv6_saddr_preferred(int type)
{
- int pref;
- pref = ifp->flags&IFA_F_DEPRECATED ? 0 : 2;
-#ifdef CONFIG_IPV6_PRIVACY
- pref |= (ifp->flags^invpref)&IFA_F_TEMPORARY ? 0 : 1;
-#endif
- return pref;
+ if (type & (IPV6_ADDR_MAPPED|IPV6_ADDR_COMPATv4|
+ IPV6_ADDR_LOOPBACK|IPV6_ADDR_RESERVED))
+ return 1;
+ return 0;
}
-#ifdef CONFIG_IPV6_PRIVACY
-#define IPV6_GET_SADDR_MAXSCORE(score) ((score) == 3)
-#else
-#define IPV6_GET_SADDR_MAXSCORE(score) (score)
-#endif
+/* static matching label */
+static int inline ipv6_saddr_label(const struct in6_addr *addr, int type)
+{
+ /*
+ * prefix (longest match) label
+ * -----------------------------
+ * ::1/128 0
+ * ::/0 1
+ * 2002::/16 2
+ * ::/96 3
+ * ::ffff:0:0/96 4
+ */
+ if (type & IPV6_ADDR_LOOPBACK)
+ return 0;
+ else if (type & IPV6_ADDR_COMPATv4)
+ return 3;
+ else if (type & IPV6_ADDR_MAPPED)
+ return 4;
+ else if (addr->s6_addr16[0] == htons(0x2002))
+ return 2;
+ return 1;
+}
-int ipv6_dev_get_saddr(struct net_device *dev,
+int ipv6_dev_get_saddr(struct net_device *daddr_dev,
struct in6_addr *daddr, struct in6_addr *saddr)
{
- struct inet6_ifaddr *ifp = NULL;
- struct inet6_ifaddr *match = NULL;
- struct inet6_dev *idev;
- int scope;
- int err;
- int hiscore = -1, score;
+ struct ipv6_saddr_score hiscore;
+ struct inet6_ifaddr *ifa_result = NULL;
+ int daddr_type = __ipv6_addr_type(daddr);
+ int daddr_scope = __ipv6_addr_src_scope(daddr_type);
+ u32 daddr_label = ipv6_saddr_label(daddr, daddr_type);
+ struct net_device *dev;
- scope = ipv6_addr_scope(daddr);
+ memset(&hiscore, 0, sizeof(hiscore));
- /*
- * known dev
- * search dev and walk through dev addresses
- */
+ read_lock(&dev_base_lock);
+ read_lock(&addrconf_lock);
- if (dev) {
- if (dev->flags & IFF_LOOPBACK)
- scope = IFA_HOST;
+ for (dev = dev_base; dev; dev=dev->next) {
+ struct inet6_dev *idev;
+ struct inet6_ifaddr *ifa;
+
+ /* Rule 0: Candidate Source Address (section 4)
+ * - multicast and link-local destination address,
+ * the set of candidate source address MUST only
+ * include addresses assigned to interfaces
+ * belonging to the same link as the outgoing
+ * interface.
+ * (- For site-local destination addresses, the
+ * set of candidate source addresses MUST only
+ * include addresses assigned to interfaces
+ * belonging to the same site as the outgoing
+ * interface.)
+ */
+ if ((daddr_type & IPV6_ADDR_MULTICAST ||
+ daddr_scope <= IPV6_ADDR_SCOPE_LINKLOCAL) &&
+ daddr_dev && dev != daddr_dev)
+ continue;
- read_lock(&addrconf_lock);
idev = __in6_dev_get(dev);
- if (idev) {
- read_lock_bh(&idev->lock);
- for (ifp=idev->addr_list; ifp; ifp=ifp->if_next) {
- if (ifp->scope == scope) {
- if (ifp->flags&IFA_F_TENTATIVE)
- continue;
-#ifdef CONFIG_IPV6_PRIVACY
- score = ipv6_saddr_pref(ifp, idev->cnf.use_tempaddr > 1 ? IFA_F_TEMPORARY : 0);
-#else
- score = ipv6_saddr_pref(ifp, 0);
-#endif
- if (score <= hiscore)
- continue;
+ if (!idev)
+ continue;
- if (match)
- in6_ifa_put(match);
- match = ifp;
- hiscore = score;
- in6_ifa_hold(ifp);
+ read_lock_bh(&idev->lock);
+ for (ifa = idev->addr_list; ifa; ifa = ifa->if_next) {
+ struct ipv6_saddr_score score;
- if (IPV6_GET_SADDR_MAXSCORE(score)) {
- read_unlock_bh(&idev->lock);
- read_unlock(&addrconf_lock);
- goto out;
- }
+ score.addr_type = __ipv6_addr_type(&ifa->addr);
+
+ /* Rule 0: Candidate Source Address (section 4)
+ * - In any case, anycast addresses, multicast
+ * addresses, and the unspecified address MUST
+ * NOT be included in a candidate set.
+ */
+ if (unlikely(score.addr_type == IPV6_ADDR_ANY ||
+ score.addr_type & IPV6_ADDR_MULTICAST)) {
+ LIMIT_NETDEBUG(KERN_DEBUG
+ "ADDRCONF: unspecified / multicast address"
+ "assigned as unicast address on %s",
+ dev->name);
+ continue;
+ }
+
+ score.attrs = 0;
+ score.matchlen = 0;
+ score.scope = 0;
+ score.rule = 0;
+
+ if (ifa_result == NULL) {
+ /* record it if the first available entry */
+ goto record_it;
+ }
+
+ /* Rule 1: Prefer same address */
+ if (hiscore.rule < 1) {
+ if (ipv6_addr_equal(&ifa_result->addr, daddr))
+ hiscore.attrs |= IPV6_SADDR_SCORE_LOCAL;
+ hiscore.rule++;
+ }
+ if (ipv6_addr_equal(&ifa->addr, daddr)) {
+ score.attrs |= IPV6_SADDR_SCORE_LOCAL;
+ if (!(hiscore.attrs & IPV6_SADDR_SCORE_LOCAL)) {
+ score.rule = 1;
+ goto record_it;
}
+ } else {
+ if (hiscore.attrs & IPV6_SADDR_SCORE_LOCAL)
+ continue;
}
- read_unlock_bh(&idev->lock);
- }
- read_unlock(&addrconf_lock);
- }
- if (scope == IFA_LINK)
- goto out;
+ /* Rule 2: Prefer appropriate scope */
+ if (hiscore.rule < 2) {
+ hiscore.scope = __ipv6_addr_src_scope(hiscore.addr_type);
+ hiscore.rule++;
+ }
+ score.scope = __ipv6_addr_src_scope(score.addr_type);
+ if (hiscore.scope < score.scope) {
+ if (hiscore.scope < daddr_scope) {
+ score.rule = 2;
+ goto record_it;
+ } else
+ continue;
+ } else if (score.scope < hiscore.scope) {
+ if (score.scope < daddr_scope)
+ continue;
+ else {
+ score.rule = 2;
+ goto record_it;
+ }
+ }
- /*
- * dev == NULL or search failed for specified dev
- */
+ /* Rule 3: Avoid deprecated address */
+ if (hiscore.rule < 3) {
+ if (ipv6_saddr_preferred(hiscore.addr_type) ||
+ !(ifa_result->flags & IFA_F_DEPRECATED))
+ hiscore.attrs |= IPV6_SADDR_SCORE_PREFERRED;
+ hiscore.rule++;
+ }
+ if (ipv6_saddr_preferred(score.addr_type) ||
+ !(ifa->flags & IFA_F_DEPRECATED)) {
+ score.attrs |= IPV6_SADDR_SCORE_PREFERRED;
+ if (!(hiscore.attrs & IPV6_SADDR_SCORE_PREFERRED)) {
+ score.rule = 3;
+ goto record_it;
+ }
+ } else {
+ if (hiscore.attrs & IPV6_SADDR_SCORE_PREFERRED)
+ continue;
+ }
- read_lock(&dev_base_lock);
- read_lock(&addrconf_lock);
- for (dev = dev_base; dev; dev=dev->next) {
- idev = __in6_dev_get(dev);
- if (idev) {
- read_lock_bh(&idev->lock);
- for (ifp=idev->addr_list; ifp; ifp=ifp->if_next) {
- if (ifp->scope == scope) {
- if (ifp->flags&IFA_F_TENTATIVE)
- continue;
-#ifdef CONFIG_IPV6_PRIVACY
- score = ipv6_saddr_pref(ifp, idev->cnf.use_tempaddr > 1 ? IFA_F_TEMPORARY : 0);
-#else
- score = ipv6_saddr_pref(ifp, 0);
-#endif
- if (score <= hiscore)
- continue;
+ /* Rule 4: Prefer home address -- not implemented yet */
- if (match)
- in6_ifa_put(match);
- match = ifp;
- hiscore = score;
- in6_ifa_hold(ifp);
+ /* Rule 5: Prefer outgoing interface */
+ if (hiscore.rule < 5) {
+ if (daddr_dev == NULL ||
+ daddr_dev == ifa_result->idev->dev)
+ hiscore.attrs |= IPV6_SADDR_SCORE_OIF;
+ hiscore.rule++;
+ }
+ if (daddr_dev == NULL ||
+ daddr_dev == ifa->idev->dev) {
+ score.attrs |= IPV6_SADDR_SCORE_OIF;
+ if (!(hiscore.attrs & IPV6_SADDR_SCORE_OIF)) {
+ score.rule = 5;
+ goto record_it;
+ }
+ } else {
+ if (hiscore.attrs & IPV6_SADDR_SCORE_OIF)
+ continue;
+ }
- if (IPV6_GET_SADDR_MAXSCORE(score)) {
- read_unlock_bh(&idev->lock);
- goto out_unlock_base;
- }
+ /* Rule 6: Prefer matching label */
+ if (hiscore.rule < 6) {
+ if (ipv6_saddr_label(&ifa_result->addr, hiscore.addr_type) == daddr_label)
+ hiscore.attrs |= IPV6_SADDR_SCORE_LABEL;
+ hiscore.rule++;
+ }
+ if (ipv6_saddr_label(&ifa->addr, score.addr_type) == daddr_label) {
+ score.attrs |= IPV6_SADDR_SCORE_LABEL;
+ if (!(hiscore.attrs & IPV6_SADDR_SCORE_LABEL)) {
+ score.rule = 6;
+ goto record_it;
}
+ } else {
+ if (hiscore.attrs & IPV6_SADDR_SCORE_LABEL)
+ continue;
}
- read_unlock_bh(&idev->lock);
+
+#ifdef CONFIG_IPV6_PRIVACY
+ /* Rule 7: Prefer public address
+ * Note: prefer temprary address if use_tempaddr >= 2
+ */
+ if (hiscore.rule < 7) {
+ if ((!(ifa_result->flags & IFA_F_TEMPORARY)) ^
+ (ifa_result->idev->cnf.use_tempaddr >= 2))
+ hiscore.attrs |= IPV6_SADDR_SCORE_PRIVACY;
+ hiscore.rule++;
+ }
+ if ((!(ifa->flags & IFA_F_TEMPORARY)) ^
+ (ifa->idev->cnf.use_tempaddr >= 2)) {
+ score.attrs |= IPV6_SADDR_SCORE_PRIVACY;
+ if (!(hiscore.attrs & IPV6_SADDR_SCORE_PRIVACY)) {
+ score.rule = 7;
+ goto record_it;
+ }
+ } else {
+ if (hiscore.attrs & IPV6_SADDR_SCORE_PRIVACY)
+ continue;
+ }
+#endif
+ /* Rule 8: Use longest matching prefix */
+ if (hiscore.rule < 8)
+ hiscore.matchlen = ipv6_addr_diff(&ifa_result->addr, daddr);
+ score.rule++;
+ score.matchlen = ipv6_addr_diff(&ifa->addr, daddr);
+ if (score.matchlen > hiscore.matchlen) {
+ score.rule = 8;
+ goto record_it;
+ }
+#if 0
+ else if (score.matchlen < hiscore.matchlen)
+ continue;
+#endif
+
+ /* Final Rule: choose first available one */
+ continue;
+record_it:
+ if (ifa_result)
+ in6_ifa_put(ifa_result);
+ in6_ifa_hold(ifa);
+ ifa_result = ifa;
+ hiscore = score;
}
+ read_unlock_bh(&idev->lock);
}
-
-out_unlock_base:
read_unlock(&addrconf_lock);
read_unlock(&dev_base_lock);
-out:
- err = -EADDRNOTAVAIL;
- if (match) {
- ipv6_addr_copy(saddr, &match->addr);
- err = 0;
- in6_ifa_put(match);
- }
-
- return err;
+ if (!ifa_result)
+ return -EADDRNOTAVAIL;
+
+ ipv6_addr_copy(saddr, &ifa_result->addr);
+ in6_ifa_put(ifa_result);
+ return 0;
}
@@ -1217,12 +1358,8 @@ static int __ipv6_regen_rndid(struct inet6_dev *idev)
struct net_device *dev;
struct scatterlist sg[2];
- sg[0].page = virt_to_page(idev->entropy);
- sg[0].offset = offset_in_page(idev->entropy);
- sg[0].length = 8;
- sg[1].page = virt_to_page(idev->work_eui64);
- sg[1].offset = offset_in_page(idev->work_eui64);
- sg[1].length = 8;
+ sg_set_buf(&sg[0], idev->entropy, 8);
+ sg_set_buf(&sg[1], idev->work_eui64, 8);
dev = idev->dev;
@@ -2167,7 +2304,7 @@ static int addrconf_ifdown(struct net_device *dev, int how)
/* Step 5: netlink notification of this interface */
idev->tstamp = jiffies;
- inet6_ifinfo_notify(RTM_NEWLINK, idev);
+ inet6_ifinfo_notify(RTM_DELLINK, idev);
/* Shot the device (if unregistered) */
@@ -2954,8 +3091,7 @@ static int inet6_fill_ifinfo(struct sk_buff *skb, struct inet6_dev *idev,
nlmsg_failure:
rtattr_failure:
- if (array)
- kfree(array);
+ kfree(array);
skb_trim(skb, b - skb->data);
return -1;
}
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
index b7185fb3377c..1bdf0fb8bf8a 100644
--- a/net/ipv6/icmp.c
+++ b/net/ipv6/icmp.c
@@ -585,17 +585,16 @@ static int icmpv6_rcv(struct sk_buff **pskb, unsigned int *nhoffp)
daddr = &skb->nh.ipv6h->daddr;
/* Perform checksum. */
- if (skb->ip_summed == CHECKSUM_HW) {
- skb->ip_summed = CHECKSUM_UNNECESSARY;
- if (csum_ipv6_magic(saddr, daddr, skb->len, IPPROTO_ICMPV6,
- skb->csum)) {
- LIMIT_NETDEBUG(KERN_DEBUG "ICMPv6 hw checksum failed\n");
- skb->ip_summed = CHECKSUM_NONE;
- }
- }
- if (skb->ip_summed == CHECKSUM_NONE) {
- if (csum_ipv6_magic(saddr, daddr, skb->len, IPPROTO_ICMPV6,
- skb_checksum(skb, 0, skb->len, 0))) {
+ switch (skb->ip_summed) {
+ case CHECKSUM_HW:
+ if (!csum_ipv6_magic(saddr, daddr, skb->len, IPPROTO_ICMPV6,
+ skb->csum))
+ break;
+ /* fall through */
+ case CHECKSUM_NONE:
+ skb->csum = ~csum_ipv6_magic(saddr, daddr, skb->len,
+ IPPROTO_ICMPV6, 0);
+ if (__skb_checksum_complete(skb)) {
LIMIT_NETDEBUG(KERN_DEBUG "ICMPv6 checksum failed [%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x > %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x]\n",
NIP6(*saddr), NIP6(*daddr));
goto discard_it;
@@ -700,10 +699,7 @@ int __init icmpv6_init(struct net_proto_family *ops)
struct sock *sk;
int err, i, j;
- for (i = 0; i < NR_CPUS; i++) {
- if (!cpu_possible(i))
- continue;
-
+ for_each_cpu(i) {
err = sock_create_kern(PF_INET6, SOCK_RAW, IPPROTO_ICMPV6,
&per_cpu(__icmpv6_socket, i));
if (err < 0) {
@@ -749,9 +745,7 @@ void icmpv6_cleanup(void)
{
int i;
- for (i = 0; i < NR_CPUS; i++) {
- if (!cpu_possible(i))
- continue;
+ for_each_cpu(i) {
sock_release(per_cpu(__icmpv6_socket, i));
}
inet6_del_protocol(&icmpv6_protocol, IPPROTO_ICMPV6);
diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c
index 4fcc5a7acf6e..1bf6d9a769e6 100644
--- a/net/ipv6/ip6_fib.c
+++ b/net/ipv6/ip6_fib.c
@@ -127,56 +127,6 @@ static __inline__ int addr_bit_set(void *token, int fn_bit)
return htonl(1 << ((~fn_bit)&0x1F)) & addr[fn_bit>>5];
}
-/*
- * find the first different bit between two addresses
- * length of address must be a multiple of 32bits
- */
-
-static __inline__ int addr_diff(void *token1, void *token2, int addrlen)
-{
- __u32 *a1 = token1;
- __u32 *a2 = token2;
- int i;
-
- addrlen >>= 2;
-
- for (i = 0; i < addrlen; i++) {
- __u32 xb;
-
- xb = a1[i] ^ a2[i];
-
- if (xb) {
- int j = 31;
-
- xb = ntohl(xb);
-
- while ((xb & (1 << j)) == 0)
- j--;
-
- return (i * 32 + 31 - j);
- }
- }
-
- /*
- * we should *never* get to this point since that
- * would mean the addrs are equal
- *
- * However, we do get to it 8) And exacly, when
- * addresses are equal 8)
- *
- * ip route add 1111::/128 via ...
- * ip route add 1111::/64 via ...
- * and we are here.
- *
- * Ideally, this function should stop comparison
- * at prefix length. It does not, but it is still OK,
- * if returned value is greater than prefix length.
- * --ANK (980803)
- */
-
- return addrlen<<5;
-}
-
static __inline__ struct fib6_node * node_alloc(void)
{
struct fib6_node *fn;
@@ -296,11 +246,11 @@ insert_above:
/* find 1st bit in difference between the 2 addrs.
- See comment in addr_diff: bit may be an invalid value,
+ See comment in __ipv6_addr_diff: bit may be an invalid value,
but if it is >= plen, the value is ignored in any case.
*/
- bit = addr_diff(addr, &key->addr, addrlen);
+ bit = __ipv6_addr_diff(addr, &key->addr, addrlen);
/*
* (intermediate)[in]
diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c
index 6e3480426939..a6026d2787d2 100644
--- a/net/ipv6/ip6_input.c
+++ b/net/ipv6/ip6_input.c
@@ -176,6 +176,11 @@ resubmit:
if (ipprot->flags & INET6_PROTO_FINAL) {
struct ipv6hdr *hdr;
+ /* Free reference early: we don't need it any more,
+ and it may hold ip_conntrack module loaded
+ indefinitely. */
+ nf_reset(skb);
+
skb_postpull_rcsum(skb, skb->nh.raw,
skb->h.raw - skb->nh.raw);
hdr = skb->nh.ipv6h;
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 563b442ffab8..c1fa693511a1 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -147,7 +147,8 @@ static int ip6_output2(struct sk_buff *skb)
int ip6_output(struct sk_buff *skb)
{
- if (skb->len > dst_mtu(skb->dst) || dst_allfrag(skb->dst))
+ if ((skb->len > dst_mtu(skb->dst) && !skb_shinfo(skb)->ufo_size) ||
+ dst_allfrag(skb->dst))
return ip6_fragment(skb, ip6_output2);
else
return ip6_output2(skb);
@@ -440,9 +441,15 @@ static void ip6_copy_metadata(struct sk_buff *to, struct sk_buff *from)
#ifdef CONFIG_NETFILTER
to->nfmark = from->nfmark;
/* Connection association is same as pre-frag packet */
+ nf_conntrack_put(to->nfct);
to->nfct = from->nfct;
nf_conntrack_get(to->nfct);
to->nfctinfo = from->nfctinfo;
+#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
+ nf_conntrack_put_reasm(to->nfct_reasm);
+ to->nfct_reasm = from->nfct_reasm;
+ nf_conntrack_get_reasm(to->nfct_reasm);
+#endif
#ifdef CONFIG_BRIDGE_NETFILTER
nf_bridge_put(to->nf_bridge);
to->nf_bridge = from->nf_bridge;
@@ -586,8 +593,7 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
skb->next = NULL;
}
- if (tmp_hdr)
- kfree(tmp_hdr);
+ kfree(tmp_hdr);
if (err == 0) {
IP6_INC_STATS(IPSTATS_MIB_FRAGOKS);
@@ -768,6 +774,65 @@ out_err_release:
*dst = NULL;
return err;
}
+inline int ip6_ufo_append_data(struct sock *sk,
+ int getfrag(void *from, char *to, int offset, int len,
+ int odd, struct sk_buff *skb),
+ void *from, int length, int hh_len, int fragheaderlen,
+ int transhdrlen, int mtu,unsigned int flags)
+
+{
+ struct sk_buff *skb;
+ int err;
+
+ /* There is support for UDP large send offload by network
+ * device, so create one single skb packet containing complete
+ * udp datagram
+ */
+ if ((skb = skb_peek_tail(&sk->sk_write_queue)) == NULL) {
+ skb = sock_alloc_send_skb(sk,
+ hh_len + fragheaderlen + transhdrlen + 20,
+ (flags & MSG_DONTWAIT), &err);
+ if (skb == NULL)
+ return -ENOMEM;
+
+ /* reserve space for Hardware header */
+ skb_reserve(skb, hh_len);
+
+ /* create space for UDP/IP header */
+ skb_put(skb,fragheaderlen + transhdrlen);
+
+ /* initialize network header pointer */
+ skb->nh.raw = skb->data;
+
+ /* initialize protocol header pointer */
+ skb->h.raw = skb->data + fragheaderlen;
+
+ skb->ip_summed = CHECKSUM_HW;
+ skb->csum = 0;
+ sk->sk_sndmsg_off = 0;
+ }
+
+ err = skb_append_datato_frags(sk,skb, getfrag, from,
+ (length - transhdrlen));
+ if (!err) {
+ struct frag_hdr fhdr;
+
+ /* specify the length of each IP datagram fragment*/
+ skb_shinfo(skb)->ufo_size = (mtu - fragheaderlen) -
+ sizeof(struct frag_hdr);
+ ipv6_select_ident(skb, &fhdr);
+ skb_shinfo(skb)->ip6_frag_id = fhdr.identification;
+ __skb_queue_tail(&sk->sk_write_queue, skb);
+
+ return 0;
+ }
+ /* There is not enough support do UPD LSO,
+ * so follow normal path
+ */
+ kfree_skb(skb);
+
+ return err;
+}
int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to,
int offset, int len, int odd, struct sk_buff *skb),
@@ -860,6 +925,15 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to,
*/
inet->cork.length += length;
+ if (((length > mtu) && (sk->sk_protocol == IPPROTO_UDP)) &&
+ (rt->u.dst.dev->features & NETIF_F_UFO)) {
+
+ if(ip6_ufo_append_data(sk, getfrag, from, length, hh_len,
+ fragheaderlen, transhdrlen, mtu, flags))
+ goto error;
+
+ return 0;
+ }
if ((skb = skb_peek_tail(&sk->sk_write_queue)) == NULL)
goto alloc_new_skb;
@@ -1117,10 +1191,8 @@ int ip6_push_pending_frames(struct sock *sk)
out:
inet->cork.flags &= ~IPCORK_OPT;
- if (np->cork.opt) {
- kfree(np->cork.opt);
- np->cork.opt = NULL;
- }
+ kfree(np->cork.opt);
+ np->cork.opt = NULL;
if (np->cork.rt) {
dst_release(&np->cork.rt->u.dst);
np->cork.rt = NULL;
@@ -1145,10 +1217,8 @@ void ip6_flush_pending_frames(struct sock *sk)
inet->cork.flags &= ~IPCORK_OPT;
- if (np->cork.opt) {
- kfree(np->cork.opt);
- np->cork.opt = NULL;
- }
+ kfree(np->cork.opt);
+ np->cork.opt = NULL;
if (np->cork.rt) {
dst_release(&np->cork.rt->u.dst);
np->cork.rt = NULL;
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index cf94372d1af3..e315d0f80af1 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -525,6 +525,7 @@ ip6ip6_rcv(struct sk_buff **pskb, unsigned int *nhoffp)
if ((t = ip6ip6_tnl_lookup(&ipv6h->saddr, &ipv6h->daddr)) != NULL) {
if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) {
+ read_unlock(&ip6ip6_lock);
kfree_skb(skb);
return 0;
}
@@ -756,8 +757,7 @@ ip6ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev)
}
ip6_tnl_dst_store(t, dst);
- if (opt)
- kfree(opt);
+ kfree(opt);
t->recursion--;
return 0;
@@ -766,8 +766,7 @@ tx_err_link_failure:
dst_link_failure(skb);
tx_err_dst_release:
dst_release(dst);
- if (opt)
- kfree(opt);
+ kfree(opt);
tx_err:
stats->tx_errors++;
stats->tx_dropped++;
diff --git a/net/ipv6/ipcomp6.c b/net/ipv6/ipcomp6.c
index 85bfbc69b2c3..55917fb17094 100644
--- a/net/ipv6/ipcomp6.c
+++ b/net/ipv6/ipcomp6.c
@@ -130,8 +130,7 @@ static int ipcomp6_input(struct xfrm_state *x, struct xfrm_decap_state *decap, s
out_put_cpu:
put_cpu();
out:
- if (tmp_hdr)
- kfree(tmp_hdr);
+ kfree(tmp_hdr);
if (err)
goto error_out;
return nexthdr;
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c
index 8567873d0dd8..003fd99ff597 100644
--- a/net/ipv6/ipv6_sockglue.c
+++ b/net/ipv6/ipv6_sockglue.c
@@ -80,8 +80,7 @@ int ip6_ra_control(struct sock *sk, int sel, void (*destructor)(struct sock *))
if (ra->sk == sk) {
if (sel>=0) {
write_unlock_bh(&ip6_ra_lock);
- if (new_ra)
- kfree(new_ra);
+ kfree(new_ra);
return -EADDRINUSE;
}
diff --git a/net/ipv6/ipv6_syms.c b/net/ipv6/ipv6_syms.c
index 37a4a99c9fe9..16482785bdfd 100644
--- a/net/ipv6/ipv6_syms.c
+++ b/net/ipv6/ipv6_syms.c
@@ -7,7 +7,7 @@
#include <net/ip6_route.h>
#include <net/xfrm.h>
-EXPORT_SYMBOL(ipv6_addr_type);
+EXPORT_SYMBOL(__ipv6_addr_type);
EXPORT_SYMBOL(icmpv6_send);
EXPORT_SYMBOL(icmpv6_statistics);
EXPORT_SYMBOL(icmpv6_err_convert);
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
index 39a96c768102..f15e04ad026e 100644
--- a/net/ipv6/mcast.c
+++ b/net/ipv6/mcast.c
@@ -164,7 +164,7 @@ static int ip6_mc_leave_src(struct sock *sk, struct ipv6_mc_socklist *iml,
#define MLDV2_MASK(value, nb) ((nb)>=32 ? (value) : ((1<<(nb))-1) & (value))
#define MLDV2_EXP(thresh, nbmant, nbexp, value) \
((value) < (thresh) ? (value) : \
- ((MLDV2_MASK(value, nbmant) | (1<<(nbmant+nbexp))) << \
+ ((MLDV2_MASK(value, nbmant) | (1<<(nbmant))) << \
(MLDV2_MASK((value) >> (nbmant), nbexp) + (nbexp))))
#define MLDV2_QQIC(value) MLDV2_EXP(0x80, 4, 3, value)
@@ -545,8 +545,10 @@ int ip6_mc_msfilter(struct sock *sk, struct group_filter *gsf)
sock_kfree_s(sk, newpsl, IP6_SFLSIZE(newpsl->sl_max));
goto done;
}
- } else
+ } else {
newpsl = NULL;
+ (void) ip6_mc_add_src(idev, group, gsf->gf_fmode, 0, NULL, 0);
+ }
psl = pmc->sflist;
if (psl) {
(void) ip6_mc_del_src(idev, group, pmc->sfmode,
@@ -1087,7 +1089,7 @@ static void mld_marksources(struct ifmcaddr6 *pmc, int nsrcs,
int igmp6_event_query(struct sk_buff *skb)
{
- struct mld2_query *mlh2 = (struct mld2_query *) skb->h.raw;
+ struct mld2_query *mlh2 = NULL;
struct ifmcaddr6 *ma;
struct in6_addr *group;
unsigned long max_delay;
@@ -1140,6 +1142,13 @@ int igmp6_event_query(struct sk_buff *skb)
/* clear deleted report items */
mld_clear_delrec(idev);
} else if (len >= 28) {
+ int srcs_offset = sizeof(struct mld2_query) -
+ sizeof(struct icmp6hdr);
+ if (!pskb_may_pull(skb, srcs_offset)) {
+ in6_dev_put(idev);
+ return -EINVAL;
+ }
+ mlh2 = (struct mld2_query *) skb->h.raw;
max_delay = (MLDV2_MRC(ntohs(mlh2->mrc))*HZ)/1000;
if (!max_delay)
max_delay = 1;
@@ -1156,7 +1165,15 @@ int igmp6_event_query(struct sk_buff *skb)
return 0;
}
/* mark sources to include, if group & source-specific */
- mark = mlh2->nsrcs != 0;
+ if (mlh2->nsrcs != 0) {
+ if (!pskb_may_pull(skb, srcs_offset +
+ mlh2->nsrcs * sizeof(struct in6_addr))) {
+ in6_dev_put(idev);
+ return -EINVAL;
+ }
+ mlh2 = (struct mld2_query *) skb->h.raw;
+ mark = 1;
+ }
} else {
in6_dev_put(idev);
return -EINVAL;
diff --git a/net/ipv6/netfilter/Kconfig b/net/ipv6/netfilter/Kconfig
index bb7ccfe33f23..971ba60bf6e9 100644
--- a/net/ipv6/netfilter/Kconfig
+++ b/net/ipv6/netfilter/Kconfig
@@ -278,5 +278,19 @@ config IP6_NF_RAW
If you want to compile it as a module, say M here and read
<file:Documentation/modules.txt>. If unsure, say `N'.
+config NF_CONNTRACK_IPV6
+ tristate "IPv6 support for new connection tracking (EXPERIMENTAL)"
+ depends on EXPERIMENTAL && NF_CONNTRACK
+ ---help---
+ Connection tracking keeps a record of what packets have passed
+ through your machine, in order to figure out how they are related
+ into connections.
+
+ This is IPv6 support on Layer 3 independent connection tracking.
+ Layer 3 independent connection tracking is experimental scheme
+ which generalize ip_conntrack to support other layer 3 protocols.
+
+ To compile it as a module, choose M here. If unsure, say N.
+
endmenu
diff --git a/net/ipv6/netfilter/Makefile b/net/ipv6/netfilter/Makefile
index 2b2c370e8b1c..9ab5b2ca1f59 100644
--- a/net/ipv6/netfilter/Makefile
+++ b/net/ipv6/netfilter/Makefile
@@ -27,3 +27,9 @@ obj-$(CONFIG_IP6_NF_TARGET_LOG) += ip6t_LOG.o
obj-$(CONFIG_IP6_NF_RAW) += ip6table_raw.o
obj-$(CONFIG_IP6_NF_MATCH_HL) += ip6t_hl.o
obj-$(CONFIG_IP6_NF_TARGET_REJECT) += ip6t_REJECT.o
+
+# objects for l3 independent conntrack
+nf_conntrack_ipv6-objs := nf_conntrack_l3proto_ipv6.o nf_conntrack_proto_icmpv6.o nf_conntrack_reasm.o
+
+# l3 independent conntrack
+obj-$(CONFIG_NF_CONNTRACK_IPV6) += nf_conntrack_ipv6.o
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
index 21deec25a12b..7d492226c16e 100644
--- a/net/ipv6/netfilter/ip6_tables.c
+++ b/net/ipv6/netfilter/ip6_tables.c
@@ -2,7 +2,7 @@
* Packet matching code.
*
* Copyright (C) 1999 Paul `Rusty' Russell & Michael J. Neuling
- * Copyright (C) 2000-2002 Netfilter core team <coreteam@netfilter.org>
+ * Copyright (C) 2000-2005 Netfilter Core Team <coreteam@netfilter.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
@@ -23,7 +23,6 @@
#include <linux/tcp.h>
#include <linux/udp.h>
#include <linux/icmpv6.h>
-#include <net/ip.h>
#include <net/ipv6.h>
#include <asm/uaccess.h>
#include <asm/semaphore.h>
@@ -80,13 +79,12 @@ static DECLARE_MUTEX(ip6t_mutex);
#define inline
#endif
-/* Locking is simple: we assume at worst case there will be one packet
- in user context and one from bottom halves (or soft irq if Alexey's
- softnet patch was applied).
-
+/*
We keep a set of rules for each CPU, so we can avoid write-locking
- them; doing a readlock_bh() stops packets coming through if we're
- in user context.
+ them in the softirq when updating the counters and therefore
+ only need to read-lock in the softirq; doing a write_lock_bh() in user
+ context stops packets coming through and allows user context to read
+ the counters or update the rules.
To be cache friendly on SMP, we arrange them like so:
[ n-entries ]
@@ -356,7 +354,7 @@ ip6t_do_table(struct sk_buff **pskb,
struct ip6t_table *table,
void *userdata)
{
- static const char nulldevname[IFNAMSIZ];
+ static const char nulldevname[IFNAMSIZ] __attribute__((aligned(sizeof(long))));
int offset = 0;
unsigned int protoff = 0;
int hotdrop = 0;
@@ -369,7 +367,6 @@ ip6t_do_table(struct sk_buff **pskb,
/* Initialization */
indev = in ? in->name : nulldevname;
outdev = out ? out->name : nulldevname;
-
/* We handle fragments by dealing with the first fragment as
* if it was a normal packet. All other fragments are treated
* normally, except that they will NEVER match rules that ask
@@ -497,75 +494,145 @@ ip6t_do_table(struct sk_buff **pskb,
#endif
}
-/* If it succeeds, returns element and locks mutex */
-static inline void *
-find_inlist_lock_noload(struct list_head *head,
- const char *name,
- int *error,
- struct semaphore *mutex)
+/*
+ * These are weird, but module loading must not be done with mutex
+ * held (since they will register), and we have to have a single
+ * function to use try_then_request_module().
+ */
+
+/* Find table by name, grabs mutex & ref. Returns ERR_PTR() on error. */
+static inline struct ip6t_table *find_table_lock(const char *name)
{
- void *ret;
+ struct ip6t_table *t;
-#if 1
- duprintf("find_inlist: searching for `%s' in %s.\n",
- name, head == &ip6t_target ? "ip6t_target"
- : head == &ip6t_match ? "ip6t_match"
- : head == &ip6t_tables ? "ip6t_tables" : "UNKNOWN");
-#endif
+ if (down_interruptible(&ip6t_mutex) != 0)
+ return ERR_PTR(-EINTR);
- *error = down_interruptible(mutex);
- if (*error != 0)
- return NULL;
+ list_for_each_entry(t, &ip6t_tables, list)
+ if (strcmp(t->name, name) == 0 && try_module_get(t->me))
+ return t;
+ up(&ip6t_mutex);
+ return NULL;
+}
+
+/* Find match, grabs ref. Returns ERR_PTR() on error. */
+static inline struct ip6t_match *find_match(const char *name, u8 revision)
+{
+ struct ip6t_match *m;
+ int err = 0;
- ret = list_named_find(head, name);
- if (!ret) {
- *error = -ENOENT;
- up(mutex);
+ if (down_interruptible(&ip6t_mutex) != 0)
+ return ERR_PTR(-EINTR);
+
+ list_for_each_entry(m, &ip6t_match, list) {
+ if (strcmp(m->name, name) == 0) {
+ if (m->revision == revision) {
+ if (try_module_get(m->me)) {
+ up(&ip6t_mutex);
+ return m;
+ }
+ } else
+ err = -EPROTOTYPE; /* Found something. */
+ }
}
- return ret;
+ up(&ip6t_mutex);
+ return ERR_PTR(err);
}
-#ifndef CONFIG_KMOD
-#define find_inlist_lock(h,n,p,e,m) find_inlist_lock_noload((h),(n),(e),(m))
-#else
-static void *
-find_inlist_lock(struct list_head *head,
- const char *name,
- const char *prefix,
- int *error,
- struct semaphore *mutex)
+/* Find target, grabs ref. Returns ERR_PTR() on error. */
+static inline struct ip6t_target *find_target(const char *name, u8 revision)
{
- void *ret;
+ struct ip6t_target *t;
+ int err = 0;
- ret = find_inlist_lock_noload(head, name, error, mutex);
- if (!ret) {
- duprintf("find_inlist: loading `%s%s'.\n", prefix, name);
- request_module("%s%s", prefix, name);
- ret = find_inlist_lock_noload(head, name, error, mutex);
+ if (down_interruptible(&ip6t_mutex) != 0)
+ return ERR_PTR(-EINTR);
+
+ list_for_each_entry(t, &ip6t_target, list) {
+ if (strcmp(t->name, name) == 0) {
+ if (t->revision == revision) {
+ if (try_module_get(t->me)) {
+ up(&ip6t_mutex);
+ return t;
+ }
+ } else
+ err = -EPROTOTYPE; /* Found something. */
+ }
}
+ up(&ip6t_mutex);
+ return ERR_PTR(err);
+}
- return ret;
+struct ip6t_target *ip6t_find_target(const char *name, u8 revision)
+{
+ struct ip6t_target *target;
+
+ target = try_then_request_module(find_target(name, revision),
+ "ip6t_%s", name);
+ if (IS_ERR(target) || !target)
+ return NULL;
+ return target;
}
-#endif
-static inline struct ip6t_table *
-ip6t_find_table_lock(const char *name, int *error, struct semaphore *mutex)
+static int match_revfn(const char *name, u8 revision, int *bestp)
{
- return find_inlist_lock(&ip6t_tables, name, "ip6table_", error, mutex);
+ struct ip6t_match *m;
+ int have_rev = 0;
+
+ list_for_each_entry(m, &ip6t_match, list) {
+ if (strcmp(m->name, name) == 0) {
+ if (m->revision > *bestp)
+ *bestp = m->revision;
+ if (m->revision == revision)
+ have_rev = 1;
+ }
+ }
+ return have_rev;
}
-static inline struct ip6t_match *
-find_match_lock(const char *name, int *error, struct semaphore *mutex)
+static int target_revfn(const char *name, u8 revision, int *bestp)
{
- return find_inlist_lock(&ip6t_match, name, "ip6t_", error, mutex);
+ struct ip6t_target *t;
+ int have_rev = 0;
+
+ list_for_each_entry(t, &ip6t_target, list) {
+ if (strcmp(t->name, name) == 0) {
+ if (t->revision > *bestp)
+ *bestp = t->revision;
+ if (t->revision == revision)
+ have_rev = 1;
+ }
+ }
+ return have_rev;
}
-static struct ip6t_target *
-ip6t_find_target_lock(const char *name, int *error, struct semaphore *mutex)
+/* Returns true or fals (if no such extension at all) */
+static inline int find_revision(const char *name, u8 revision,
+ int (*revfn)(const char *, u8, int *),
+ int *err)
{
- return find_inlist_lock(&ip6t_target, name, "ip6t_", error, mutex);
+ int have_rev, best = -1;
+
+ if (down_interruptible(&ip6t_mutex) != 0) {
+ *err = -EINTR;
+ return 1;
+ }
+ have_rev = revfn(name, revision, &best);
+ up(&ip6t_mutex);
+
+ /* Nothing at all? Return 0 to try loading module. */
+ if (best == -1) {
+ *err = -ENOENT;
+ return 0;
+ }
+
+ *err = best;
+ if (!have_rev)
+ *err = -EPROTONOSUPPORT;
+ return 1;
}
+
/* All zeroes == unconditional rule. */
static inline int
unconditional(const struct ip6t_ip6 *ipv6)
@@ -725,20 +792,16 @@ check_match(struct ip6t_entry_match *m,
unsigned int hookmask,
unsigned int *i)
{
- int ret;
struct ip6t_match *match;
- match = find_match_lock(m->u.user.name, &ret, &ip6t_mutex);
- if (!match) {
- // duprintf("check_match: `%s' not found\n", m->u.name);
- return ret;
- }
- if (!try_module_get(match->me)) {
- up(&ip6t_mutex);
- return -ENOENT;
+ match = try_then_request_module(find_match(m->u.user.name,
+ m->u.user.revision),
+ "ip6t_%s", m->u.user.name);
+ if (IS_ERR(match) || !match) {
+ duprintf("check_match: `%s' not found\n", m->u.user.name);
+ return match ? PTR_ERR(match) : -ENOENT;
}
m->u.kernel.match = match;
- up(&ip6t_mutex);
if (m->u.kernel.match->checkentry
&& !m->u.kernel.match->checkentry(name, ipv6, m->data,
@@ -776,22 +839,16 @@ check_entry(struct ip6t_entry *e, const char *name, unsigned int size,
goto cleanup_matches;
t = ip6t_get_target(e);
- target = ip6t_find_target_lock(t->u.user.name, &ret, &ip6t_mutex);
- if (!target) {
+ target = try_then_request_module(find_target(t->u.user.name,
+ t->u.user.revision),
+ "ip6t_%s", t->u.user.name);
+ if (IS_ERR(target) || !target) {
duprintf("check_entry: `%s' not found\n", t->u.user.name);
- goto cleanup_matches;
- }
- if (!try_module_get(target->me)) {
- up(&ip6t_mutex);
- ret = -ENOENT;
+ ret = target ? PTR_ERR(target) : -ENOENT;
goto cleanup_matches;
}
t->u.kernel.target = target;
- up(&ip6t_mutex);
- if (!t->u.kernel.target) {
- ret = -EBUSY;
- goto cleanup_matches;
- }
+
if (t->u.kernel.target == &ip6t_standard_target) {
if (!standard_check(t, size)) {
ret = -EINVAL;
@@ -1118,8 +1175,8 @@ get_entries(const struct ip6t_get_entries *entries,
int ret;
struct ip6t_table *t;
- t = ip6t_find_table_lock(entries->name, &ret, &ip6t_mutex);
- if (t) {
+ t = find_table_lock(entries->name);
+ if (t && !IS_ERR(t)) {
duprintf("t->private->number = %u\n",
t->private->number);
if (entries->size == t->private->size)
@@ -1131,10 +1188,10 @@ get_entries(const struct ip6t_get_entries *entries,
entries->size);
ret = -EINVAL;
}
+ module_put(t->me);
up(&ip6t_mutex);
} else
- duprintf("get_entries: Can't find %s!\n",
- entries->name);
+ ret = t ? PTR_ERR(t) : -ENOENT;
return ret;
}
@@ -1182,22 +1239,19 @@ do_replace(void __user *user, unsigned int len)
duprintf("ip_tables: Translated table\n");
- t = ip6t_find_table_lock(tmp.name, &ret, &ip6t_mutex);
- if (!t)
+ t = try_then_request_module(find_table_lock(tmp.name),
+ "ip6table_%s", tmp.name);
+ if (!t || IS_ERR(t)) {
+ ret = t ? PTR_ERR(t) : -ENOENT;
goto free_newinfo_counters_untrans;
+ }
/* You lied! */
if (tmp.valid_hooks != t->valid_hooks) {
duprintf("Valid hook crap: %08X vs %08X\n",
tmp.valid_hooks, t->valid_hooks);
ret = -EINVAL;
- goto free_newinfo_counters_untrans_unlock;
- }
-
- /* Get a reference in advance, we're not allowed fail later */
- if (!try_module_get(t->me)) {
- ret = -EBUSY;
- goto free_newinfo_counters_untrans_unlock;
+ goto put_module;
}
oldinfo = replace_table(t, tmp.num_counters, newinfo, &ret);
@@ -1219,7 +1273,6 @@ do_replace(void __user *user, unsigned int len)
/* Decrease module usage counts and free resource */
IP6T_ENTRY_ITERATE(oldinfo->entries, oldinfo->size, cleanup_entry,NULL);
vfree(oldinfo);
- /* Silent error: too late now. */
if (copy_to_user(tmp.counters, counters,
sizeof(struct ip6t_counters) * tmp.num_counters) != 0)
ret = -EFAULT;
@@ -1229,7 +1282,6 @@ do_replace(void __user *user, unsigned int len)
put_module:
module_put(t->me);
- free_newinfo_counters_untrans_unlock:
up(&ip6t_mutex);
free_newinfo_counters_untrans:
IP6T_ENTRY_ITERATE(newinfo->entries, newinfo->size, cleanup_entry,NULL);
@@ -1268,7 +1320,7 @@ do_add_counters(void __user *user, unsigned int len)
unsigned int i;
struct ip6t_counters_info tmp, *paddc;
struct ip6t_table *t;
- int ret;
+ int ret = 0;
if (copy_from_user(&tmp, user, sizeof(tmp)) != 0)
return -EFAULT;
@@ -1285,9 +1337,11 @@ do_add_counters(void __user *user, unsigned int len)
goto free;
}
- t = ip6t_find_table_lock(tmp.name, &ret, &ip6t_mutex);
- if (!t)
+ t = find_table_lock(tmp.name);
+ if (!t || IS_ERR(t)) {
+ ret = t ? PTR_ERR(t) : -ENOENT;
goto free;
+ }
write_lock_bh(&t->lock);
if (t->private->number != paddc->num_counters) {
@@ -1304,6 +1358,7 @@ do_add_counters(void __user *user, unsigned int len)
unlock_up_free:
write_unlock_bh(&t->lock);
up(&ip6t_mutex);
+ module_put(t->me);
free:
vfree(paddc);
@@ -1360,8 +1415,10 @@ do_ip6t_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
break;
}
name[IP6T_TABLE_MAXNAMELEN-1] = '\0';
- t = ip6t_find_table_lock(name, &ret, &ip6t_mutex);
- if (t) {
+
+ t = try_then_request_module(find_table_lock(name),
+ "ip6table_%s", name);
+ if (t && !IS_ERR(t)) {
struct ip6t_getinfo info;
info.valid_hooks = t->valid_hooks;
@@ -1377,9 +1434,10 @@ do_ip6t_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
ret = -EFAULT;
else
ret = 0;
-
up(&ip6t_mutex);
- }
+ module_put(t->me);
+ } else
+ ret = t ? PTR_ERR(t) : -ENOENT;
}
break;
@@ -1400,6 +1458,31 @@ do_ip6t_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
break;
}
+ case IP6T_SO_GET_REVISION_MATCH:
+ case IP6T_SO_GET_REVISION_TARGET: {
+ struct ip6t_get_revision rev;
+ int (*revfn)(const char *, u8, int *);
+
+ if (*len != sizeof(rev)) {
+ ret = -EINVAL;
+ break;
+ }
+ if (copy_from_user(&rev, user, sizeof(rev)) != 0) {
+ ret = -EFAULT;
+ break;
+ }
+
+ if (cmd == IP6T_SO_GET_REVISION_TARGET)
+ revfn = target_revfn;
+ else
+ revfn = match_revfn;
+
+ try_then_request_module(find_revision(rev.name, rev.revision,
+ revfn, &ret),
+ "ip6t_%s", rev.name);
+ break;
+ }
+
default:
duprintf("do_ip6t_get_ctl: unknown request %i\n", cmd);
ret = -EINVAL;
@@ -1417,12 +1500,7 @@ ip6t_register_target(struct ip6t_target *target)
ret = down_interruptible(&ip6t_mutex);
if (ret != 0)
return ret;
-
- if (!list_named_insert(&ip6t_target, target)) {
- duprintf("ip6t_register_target: `%s' already in list!\n",
- target->name);
- ret = -EINVAL;
- }
+ list_add(&target->list, &ip6t_target);
up(&ip6t_mutex);
return ret;
}
@@ -1444,11 +1522,7 @@ ip6t_register_match(struct ip6t_match *match)
if (ret != 0)
return ret;
- if (!list_named_insert(&ip6t_match, match)) {
- duprintf("ip6t_register_match: `%s' already in list!\n",
- match->name);
- ret = -EINVAL;
- }
+ list_add(&match->list, &ip6t_match);
up(&ip6t_mutex);
return ret;
diff --git a/net/ipv6/netfilter/ip6t_MARK.c b/net/ipv6/netfilter/ip6t_MARK.c
index 81924fcc5857..eab8fb864ee0 100644
--- a/net/ipv6/netfilter/ip6t_MARK.c
+++ b/net/ipv6/netfilter/ip6t_MARK.c
@@ -56,8 +56,12 @@ checkentry(const char *tablename,
return 1;
}
-static struct ip6t_target ip6t_mark_reg
-= { { NULL, NULL }, "MARK", target, checkentry, NULL, THIS_MODULE };
+static struct ip6t_target ip6t_mark_reg = {
+ .name = "MARK",
+ .target = target,
+ .checkentry = checkentry,
+ .me = THIS_MODULE
+};
static int __init init(void)
{
diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
new file mode 100644
index 000000000000..e2c90b3a8074
--- /dev/null
+++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
@@ -0,0 +1,556 @@
+/*
+ * Copyright (C)2004 USAGI/WIDE Project
+ *
+ * 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.
+ *
+ * Author:
+ * Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp>
+ *
+ * 16 Dec 2003: Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp>
+ * - support Layer 3 protocol independent connection tracking.
+ * Based on the original ip_conntrack code which had the following
+ * copyright information:
+ * (C) 1999-2001 Paul `Rusty' Russell
+ * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
+ *
+ * 23 Mar 2004: Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp>
+ * - add get_features() to support various size of conntrack
+ * structures.
+ */
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/ipv6.h>
+#include <linux/in6.h>
+#include <linux/netfilter.h>
+#include <linux/module.h>
+#include <linux/skbuff.h>
+#include <linux/icmp.h>
+#include <linux/sysctl.h>
+#include <net/ipv6.h>
+
+#include <linux/netfilter_ipv6.h>
+#include <net/netfilter/nf_conntrack.h>
+#include <net/netfilter/nf_conntrack_helper.h>
+#include <net/netfilter/nf_conntrack_protocol.h>
+#include <net/netfilter/nf_conntrack_l3proto.h>
+#include <net/netfilter/nf_conntrack_core.h>
+
+#if 0
+#define DEBUGP printk
+#else
+#define DEBUGP(format, args...)
+#endif
+
+DECLARE_PER_CPU(struct ip_conntrack_stat, nf_conntrack_stat);
+
+static int ipv6_pkt_to_tuple(const struct sk_buff *skb, unsigned int nhoff,
+ struct nf_conntrack_tuple *tuple)
+{
+ u_int32_t _addrs[8], *ap;
+
+ ap = skb_header_pointer(skb, nhoff + offsetof(struct ipv6hdr, saddr),
+ sizeof(_addrs), _addrs);
+ if (ap == NULL)
+ return 0;
+
+ memcpy(tuple->src.u3.ip6, ap, sizeof(tuple->src.u3.ip6));
+ memcpy(tuple->dst.u3.ip6, ap + 4, sizeof(tuple->dst.u3.ip6));
+
+ return 1;
+}
+
+static int ipv6_invert_tuple(struct nf_conntrack_tuple *tuple,
+ const struct nf_conntrack_tuple *orig)
+{
+ memcpy(tuple->src.u3.ip6, orig->dst.u3.ip6, sizeof(tuple->src.u3.ip6));
+ memcpy(tuple->dst.u3.ip6, orig->src.u3.ip6, sizeof(tuple->dst.u3.ip6));
+
+ return 1;
+}
+
+static int ipv6_print_tuple(struct seq_file *s,
+ const struct nf_conntrack_tuple *tuple)
+{
+ return seq_printf(s, "src=%x:%x:%x:%x:%x:%x:%x:%x dst=%x:%x:%x:%x:%x:%x:%x:%x ",
+ NIP6(*((struct in6_addr *)tuple->src.u3.ip6)),
+ NIP6(*((struct in6_addr *)tuple->dst.u3.ip6)));
+}
+
+static int ipv6_print_conntrack(struct seq_file *s,
+ const struct nf_conn *conntrack)
+{
+ return 0;
+}
+
+/*
+ * Based on ipv6_skip_exthdr() in net/ipv6/exthdr.c
+ *
+ * This function parses (probably truncated) exthdr set "hdr"
+ * of length "len". "nexthdrp" initially points to some place,
+ * where type of the first header can be found.
+ *
+ * It skips all well-known exthdrs, and returns pointer to the start
+ * of unparsable area i.e. the first header with unknown type.
+ * if success, *nexthdr is updated by type/protocol of this header.
+ *
+ * NOTES: - it may return pointer pointing beyond end of packet,
+ * if the last recognized header is truncated in the middle.
+ * - if packet is truncated, so that all parsed headers are skipped,
+ * it returns -1.
+ * - if packet is fragmented, return pointer of the fragment header.
+ * - ESP is unparsable for now and considered like
+ * normal payload protocol.
+ * - Note also special handling of AUTH header. Thanks to IPsec wizards.
+ */
+
+int nf_ct_ipv6_skip_exthdr(struct sk_buff *skb, int start, u8 *nexthdrp,
+ int len)
+{
+ u8 nexthdr = *nexthdrp;
+
+ while (ipv6_ext_hdr(nexthdr)) {
+ struct ipv6_opt_hdr hdr;
+ int hdrlen;
+
+ if (len < (int)sizeof(struct ipv6_opt_hdr))
+ return -1;
+ if (nexthdr == NEXTHDR_NONE)
+ break;
+ if (nexthdr == NEXTHDR_FRAGMENT)
+ break;
+ if (skb_copy_bits(skb, start, &hdr, sizeof(hdr)))
+ BUG();
+ if (nexthdr == NEXTHDR_AUTH)
+ hdrlen = (hdr.hdrlen+2)<<2;
+ else
+ hdrlen = ipv6_optlen(&hdr);
+
+ nexthdr = hdr.nexthdr;
+ len -= hdrlen;
+ start += hdrlen;
+ }
+
+ *nexthdrp = nexthdr;
+ return start;
+}
+
+static int
+ipv6_prepare(struct sk_buff **pskb, unsigned int hooknum, unsigned int *dataoff,
+ u_int8_t *protonum)
+{
+ unsigned int extoff;
+ unsigned char pnum;
+ int protoff;
+
+ extoff = (u8*)((*pskb)->nh.ipv6h + 1) - (*pskb)->data;
+ pnum = (*pskb)->nh.ipv6h->nexthdr;
+
+ protoff = nf_ct_ipv6_skip_exthdr(*pskb, extoff, &pnum,
+ (*pskb)->len - extoff);
+
+ /*
+ * (protoff == (*pskb)->len) mean that the packet doesn't have no data
+ * except of IPv6 & ext headers. but it's tracked anyway. - YK
+ */
+ if ((protoff < 0) || (protoff > (*pskb)->len)) {
+ DEBUGP("ip6_conntrack_core: can't find proto in pkt\n");
+ NF_CT_STAT_INC(error);
+ NF_CT_STAT_INC(invalid);
+ return -NF_ACCEPT;
+ }
+
+ *dataoff = protoff;
+ *protonum = pnum;
+ return NF_ACCEPT;
+}
+
+static u_int32_t ipv6_get_features(const struct nf_conntrack_tuple *tuple)
+{
+ return NF_CT_F_BASIC;
+}
+
+static unsigned int ipv6_confirm(unsigned int hooknum,
+ struct sk_buff **pskb,
+ const struct net_device *in,
+ const struct net_device *out,
+ int (*okfn)(struct sk_buff *))
+{
+ struct nf_conn *ct;
+ enum ip_conntrack_info ctinfo;
+
+ /* This is where we call the helper: as the packet goes out. */
+ ct = nf_ct_get(*pskb, &ctinfo);
+ if (ct && ct->helper) {
+ unsigned int ret, protoff;
+ unsigned int extoff = (u8*)((*pskb)->nh.ipv6h + 1)
+ - (*pskb)->data;
+ unsigned char pnum = (*pskb)->nh.ipv6h->nexthdr;
+
+ protoff = nf_ct_ipv6_skip_exthdr(*pskb, extoff, &pnum,
+ (*pskb)->len - extoff);
+ if (protoff < 0 || protoff > (*pskb)->len ||
+ pnum == NEXTHDR_FRAGMENT) {
+ DEBUGP("proto header not found\n");
+ return NF_ACCEPT;
+ }
+
+ ret = ct->helper->help(pskb, protoff, ct, ctinfo);
+ if (ret != NF_ACCEPT)
+ return ret;
+ }
+
+ /* We've seen it coming out the other side: confirm it */
+
+ return nf_conntrack_confirm(pskb);
+}
+
+extern struct sk_buff *nf_ct_frag6_gather(struct sk_buff *skb);
+extern void nf_ct_frag6_output(unsigned int hooknum, struct sk_buff *skb,
+ struct net_device *in,
+ struct net_device *out,
+ int (*okfn)(struct sk_buff *));
+static unsigned int ipv6_defrag(unsigned int hooknum,
+ struct sk_buff **pskb,
+ const struct net_device *in,
+ const struct net_device *out,
+ int (*okfn)(struct sk_buff *))
+{
+ struct sk_buff *reasm;
+
+ /* Previously seen (loopback)? */
+ if ((*pskb)->nfct)
+ return NF_ACCEPT;
+
+ reasm = nf_ct_frag6_gather(*pskb);
+
+ /* queued */
+ if (reasm == NULL)
+ return NF_STOLEN;
+
+ /* error occured or not fragmented */
+ if (reasm == *pskb)
+ return NF_ACCEPT;
+
+ nf_ct_frag6_output(hooknum, reasm, (struct net_device *)in,
+ (struct net_device *)out, okfn);
+
+ return NF_STOLEN;
+}
+
+static unsigned int ipv6_conntrack_in(unsigned int hooknum,
+ struct sk_buff **pskb,
+ const struct net_device *in,
+ const struct net_device *out,
+ int (*okfn)(struct sk_buff *))
+{
+ struct sk_buff *reasm = (*pskb)->nfct_reasm;
+
+ /* This packet is fragmented and has reassembled packet. */
+ if (reasm) {
+ /* Reassembled packet isn't parsed yet ? */
+ if (!reasm->nfct) {
+ unsigned int ret;
+
+ ret = nf_conntrack_in(PF_INET6, hooknum, &reasm);
+ if (ret != NF_ACCEPT)
+ return ret;
+ }
+ nf_conntrack_get(reasm->nfct);
+ (*pskb)->nfct = reasm->nfct;
+ return NF_ACCEPT;
+ }
+
+ return nf_conntrack_in(PF_INET6, hooknum, pskb);
+}
+
+static unsigned int ipv6_conntrack_local(unsigned int hooknum,
+ struct sk_buff **pskb,
+ const struct net_device *in,
+ const struct net_device *out,
+ int (*okfn)(struct sk_buff *))
+{
+ /* root is playing with raw sockets. */
+ if ((*pskb)->len < sizeof(struct ipv6hdr)) {
+ if (net_ratelimit())
+ printk("ipv6_conntrack_local: packet too short\n");
+ return NF_ACCEPT;
+ }
+ return ipv6_conntrack_in(hooknum, pskb, in, out, okfn);
+}
+
+/* Connection tracking may drop packets, but never alters them, so
+ make it the first hook. */
+static struct nf_hook_ops ipv6_conntrack_defrag_ops = {
+ .hook = ipv6_defrag,
+ .owner = THIS_MODULE,
+ .pf = PF_INET6,
+ .hooknum = NF_IP6_PRE_ROUTING,
+ .priority = NF_IP6_PRI_CONNTRACK_DEFRAG,
+};
+
+static struct nf_hook_ops ipv6_conntrack_in_ops = {
+ .hook = ipv6_conntrack_in,
+ .owner = THIS_MODULE,
+ .pf = PF_INET6,
+ .hooknum = NF_IP6_PRE_ROUTING,
+ .priority = NF_IP6_PRI_CONNTRACK,
+};
+
+static struct nf_hook_ops ipv6_conntrack_local_out_ops = {
+ .hook = ipv6_conntrack_local,
+ .owner = THIS_MODULE,
+ .pf = PF_INET6,
+ .hooknum = NF_IP6_LOCAL_OUT,
+ .priority = NF_IP6_PRI_CONNTRACK,
+};
+
+static struct nf_hook_ops ipv6_conntrack_defrag_local_out_ops = {
+ .hook = ipv6_defrag,
+ .owner = THIS_MODULE,
+ .pf = PF_INET6,
+ .hooknum = NF_IP6_LOCAL_OUT,
+ .priority = NF_IP6_PRI_CONNTRACK_DEFRAG,
+};
+
+/* Refragmenter; last chance. */
+static struct nf_hook_ops ipv6_conntrack_out_ops = {
+ .hook = ipv6_confirm,
+ .owner = THIS_MODULE,
+ .pf = PF_INET6,
+ .hooknum = NF_IP6_POST_ROUTING,
+ .priority = NF_IP6_PRI_LAST,
+};
+
+static struct nf_hook_ops ipv6_conntrack_local_in_ops = {
+ .hook = ipv6_confirm,
+ .owner = THIS_MODULE,
+ .pf = PF_INET6,
+ .hooknum = NF_IP6_LOCAL_IN,
+ .priority = NF_IP6_PRI_LAST-1,
+};
+
+#ifdef CONFIG_SYSCTL
+
+/* From nf_conntrack_proto_icmpv6.c */
+extern unsigned long nf_ct_icmpv6_timeout;
+
+/* From nf_conntrack_frag6.c */
+extern unsigned long nf_ct_frag6_timeout;
+extern unsigned long nf_ct_frag6_low_thresh;
+extern unsigned long nf_ct_frag6_high_thresh;
+
+static struct ctl_table_header *nf_ct_ipv6_sysctl_header;
+
+static ctl_table nf_ct_sysctl_table[] = {
+ {
+ .ctl_name = NET_NF_CONNTRACK_ICMPV6_TIMEOUT,
+ .procname = "nf_conntrack_icmpv6_timeout",
+ .data = &nf_ct_icmpv6_timeout,
+ .maxlen = sizeof(unsigned int),
+ .mode = 0644,
+ .proc_handler = &proc_dointvec_jiffies,
+ },
+ {
+ .ctl_name = NET_NF_CONNTRACK_FRAG6_TIMEOUT,
+ .procname = "nf_conntrack_frag6_timeout",
+ .data = &nf_ct_frag6_timeout,
+ .maxlen = sizeof(unsigned int),
+ .mode = 0644,
+ .proc_handler = &proc_dointvec_jiffies,
+ },
+ {
+ .ctl_name = NET_NF_CONNTRACK_FRAG6_LOW_THRESH,
+ .procname = "nf_conntrack_frag6_low_thresh",
+ .data = &nf_ct_frag6_low_thresh,
+ .maxlen = sizeof(unsigned int),
+ .mode = 0644,
+ .proc_handler = &proc_dointvec_jiffies,
+ },
+ {
+ .ctl_name = NET_NF_CONNTRACK_FRAG6_HIGH_THRESH,
+ .procname = "nf_conntrack_frag6_high_thresh",
+ .data = &nf_ct_frag6_high_thresh,
+ .maxlen = sizeof(unsigned int),
+ .mode = 0644,
+ .proc_handler = &proc_dointvec_jiffies,
+ },
+ { .ctl_name = 0 }
+};
+
+static ctl_table nf_ct_netfilter_table[] = {
+ {
+ .ctl_name = NET_NETFILTER,
+ .procname = "netfilter",
+ .mode = 0555,
+ .child = nf_ct_sysctl_table,
+ },
+ { .ctl_name = 0 }
+};
+
+static ctl_table nf_ct_net_table[] = {
+ {
+ .ctl_name = CTL_NET,
+ .procname = "net",
+ .mode = 0555,
+ .child = nf_ct_netfilter_table,
+ },
+ { .ctl_name = 0 }
+};
+#endif
+
+struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv6 = {
+ .l3proto = PF_INET6,
+ .name = "ipv6",
+ .pkt_to_tuple = ipv6_pkt_to_tuple,
+ .invert_tuple = ipv6_invert_tuple,
+ .print_tuple = ipv6_print_tuple,
+ .print_conntrack = ipv6_print_conntrack,
+ .prepare = ipv6_prepare,
+ .get_features = ipv6_get_features,
+ .me = THIS_MODULE,
+};
+
+extern struct nf_conntrack_protocol nf_conntrack_protocol_tcp6;
+extern struct nf_conntrack_protocol nf_conntrack_protocol_udp6;
+extern struct nf_conntrack_protocol nf_conntrack_protocol_icmpv6;
+extern int nf_ct_frag6_init(void);
+extern void nf_ct_frag6_cleanup(void);
+static int init_or_cleanup(int init)
+{
+ int ret = 0;
+
+ if (!init) goto cleanup;
+
+ ret = nf_ct_frag6_init();
+ if (ret < 0) {
+ printk("nf_conntrack_ipv6: can't initialize frag6.\n");
+ goto cleanup_nothing;
+ }
+ ret = nf_conntrack_protocol_register(&nf_conntrack_protocol_tcp6);
+ if (ret < 0) {
+ printk("nf_conntrack_ipv6: can't register tcp.\n");
+ goto cleanup_frag6;
+ }
+
+ ret = nf_conntrack_protocol_register(&nf_conntrack_protocol_udp6);
+ if (ret < 0) {
+ printk("nf_conntrack_ipv6: can't register udp.\n");
+ goto cleanup_tcp;
+ }
+
+ ret = nf_conntrack_protocol_register(&nf_conntrack_protocol_icmpv6);
+ if (ret < 0) {
+ printk("nf_conntrack_ipv6: can't register icmpv6.\n");
+ goto cleanup_udp;
+ }
+
+ ret = nf_conntrack_l3proto_register(&nf_conntrack_l3proto_ipv6);
+ if (ret < 0) {
+ printk("nf_conntrack_ipv6: can't register ipv6\n");
+ goto cleanup_icmpv6;
+ }
+
+ ret = nf_register_hook(&ipv6_conntrack_defrag_ops);
+ if (ret < 0) {
+ printk("nf_conntrack_ipv6: can't register pre-routing defrag "
+ "hook.\n");
+ goto cleanup_ipv6;
+ }
+
+ ret = nf_register_hook(&ipv6_conntrack_defrag_local_out_ops);
+ if (ret < 0) {
+ printk("nf_conntrack_ipv6: can't register local_out defrag "
+ "hook.\n");
+ goto cleanup_defragops;
+ }
+
+ ret = nf_register_hook(&ipv6_conntrack_in_ops);
+ if (ret < 0) {
+ printk("nf_conntrack_ipv6: can't register pre-routing hook.\n");
+ goto cleanup_defraglocalops;
+ }
+
+ ret = nf_register_hook(&ipv6_conntrack_local_out_ops);
+ if (ret < 0) {
+ printk("nf_conntrack_ipv6: can't register local out hook.\n");
+ goto cleanup_inops;
+ }
+
+ ret = nf_register_hook(&ipv6_conntrack_out_ops);
+ if (ret < 0) {
+ printk("nf_conntrack_ipv6: can't register post-routing hook.\n");
+ goto cleanup_inandlocalops;
+ }
+
+ ret = nf_register_hook(&ipv6_conntrack_local_in_ops);
+ if (ret < 0) {
+ printk("nf_conntrack_ipv6: can't register local in hook.\n");
+ goto cleanup_inoutandlocalops;
+ }
+
+#ifdef CONFIG_SYSCTL
+ nf_ct_ipv6_sysctl_header = register_sysctl_table(nf_ct_net_table, 0);
+ if (nf_ct_ipv6_sysctl_header == NULL) {
+ printk("nf_conntrack: can't register to sysctl.\n");
+ ret = -ENOMEM;
+ goto cleanup_localinops;
+ }
+#endif
+ return ret;
+
+ cleanup:
+ synchronize_net();
+#ifdef CONFIG_SYSCTL
+ unregister_sysctl_table(nf_ct_ipv6_sysctl_header);
+ cleanup_localinops:
+#endif
+ nf_unregister_hook(&ipv6_conntrack_local_in_ops);
+ cleanup_inoutandlocalops:
+ nf_unregister_hook(&ipv6_conntrack_out_ops);
+ cleanup_inandlocalops:
+ nf_unregister_hook(&ipv6_conntrack_local_out_ops);
+ cleanup_inops:
+ nf_unregister_hook(&ipv6_conntrack_in_ops);
+ cleanup_defraglocalops:
+ nf_unregister_hook(&ipv6_conntrack_defrag_local_out_ops);
+ cleanup_defragops:
+ nf_unregister_hook(&ipv6_conntrack_defrag_ops);
+ cleanup_ipv6:
+ nf_conntrack_l3proto_unregister(&nf_conntrack_l3proto_ipv6);
+ cleanup_icmpv6:
+ nf_conntrack_protocol_unregister(&nf_conntrack_protocol_icmpv6);
+ cleanup_udp:
+ nf_conntrack_protocol_unregister(&nf_conntrack_protocol_udp6);
+ cleanup_tcp:
+ nf_conntrack_protocol_unregister(&nf_conntrack_protocol_tcp6);
+ cleanup_frag6:
+ nf_ct_frag6_cleanup();
+ cleanup_nothing:
+ return ret;
+}
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Yasuyuki KOZAKAI @USAGI <yasuyuki.kozakai@toshiba.co.jp>");
+
+static int __init init(void)
+{
+ need_nf_conntrack();
+ return init_or_cleanup(1);
+}
+
+static void __exit fini(void)
+{
+ init_or_cleanup(0);
+}
+
+module_init(init);
+module_exit(fini);
+
+void need_ip6_conntrack(void)
+{
+}
+
+EXPORT_SYMBOL(need_ip6_conntrack);
diff --git a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
new file mode 100644
index 000000000000..c0f1da5497a9
--- /dev/null
+++ b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
@@ -0,0 +1,272 @@
+/*
+ * Copyright (C)2003,2004 USAGI/WIDE Project
+ *
+ * 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.
+ *
+ * Author:
+ * Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp>
+ *
+ * 16 Dec 2003: Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp>
+ * - ICMPv6 tracking support. Derived from the original ip_conntrack code
+ * net/ipv4/netfilter/ip_conntrack_proto_icmp.c which had the following
+ * copyright information:
+ * (C) 1999-2001 Paul `Rusty' Russell
+ * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
+ */
+
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/timer.h>
+#include <linux/module.h>
+#include <linux/netfilter.h>
+#include <linux/in6.h>
+#include <linux/icmpv6.h>
+#include <linux/ipv6.h>
+#include <net/ipv6.h>
+#include <net/ip6_checksum.h>
+#include <linux/seq_file.h>
+#include <linux/netfilter_ipv6.h>
+#include <net/netfilter/nf_conntrack_tuple.h>
+#include <net/netfilter/nf_conntrack_protocol.h>
+#include <net/netfilter/nf_conntrack_core.h>
+#include <net/netfilter/ipv6/nf_conntrack_icmpv6.h>
+
+unsigned long nf_ct_icmpv6_timeout = 30*HZ;
+
+#if 0
+#define DEBUGP printk
+#else
+#define DEBUGP(format, args...)
+#endif
+
+static int icmpv6_pkt_to_tuple(const struct sk_buff *skb,
+ unsigned int dataoff,
+ struct nf_conntrack_tuple *tuple)
+{
+ struct icmp6hdr _hdr, *hp;
+
+ hp = skb_header_pointer(skb, dataoff, sizeof(_hdr), &_hdr);
+ if (hp == NULL)
+ return 0;
+ tuple->dst.u.icmp.type = hp->icmp6_type;
+ tuple->src.u.icmp.id = hp->icmp6_identifier;
+ tuple->dst.u.icmp.code = hp->icmp6_code;
+
+ return 1;
+}
+
+static int icmpv6_invert_tuple(struct nf_conntrack_tuple *tuple,
+ const struct nf_conntrack_tuple *orig)
+{
+ /* Add 1; spaces filled with 0. */
+ static u_int8_t invmap[] = {
+ [ICMPV6_ECHO_REQUEST - 128] = ICMPV6_ECHO_REPLY + 1,
+ [ICMPV6_ECHO_REPLY - 128] = ICMPV6_ECHO_REQUEST + 1,
+ [ICMPV6_NI_QUERY - 128] = ICMPV6_NI_QUERY + 1,
+ [ICMPV6_NI_REPLY - 128] = ICMPV6_NI_REPLY +1
+ };
+
+ __u8 type = orig->dst.u.icmp.type - 128;
+ if (type >= sizeof(invmap) || !invmap[type])
+ return 0;
+
+ tuple->src.u.icmp.id = orig->src.u.icmp.id;
+ tuple->dst.u.icmp.type = invmap[type] - 1;
+ tuple->dst.u.icmp.code = orig->dst.u.icmp.code;
+ return 1;
+}
+
+/* Print out the per-protocol part of the tuple. */
+static int icmpv6_print_tuple(struct seq_file *s,
+ const struct nf_conntrack_tuple *tuple)
+{
+ return seq_printf(s, "type=%u code=%u id=%u ",
+ tuple->dst.u.icmp.type,
+ tuple->dst.u.icmp.code,
+ ntohs(tuple->src.u.icmp.id));
+}
+
+/* Print out the private part of the conntrack. */
+static int icmpv6_print_conntrack(struct seq_file *s,
+ const struct nf_conn *conntrack)
+{
+ return 0;
+}
+
+/* Returns verdict for packet, or -1 for invalid. */
+static int icmpv6_packet(struct nf_conn *ct,
+ const struct sk_buff *skb,
+ unsigned int dataoff,
+ enum ip_conntrack_info ctinfo,
+ int pf,
+ unsigned int hooknum)
+{
+ /* Try to delete connection immediately after all replies:
+ won't actually vanish as we still have skb, and del_timer
+ means this will only run once even if count hits zero twice
+ (theoretically possible with SMP) */
+ if (CTINFO2DIR(ctinfo) == IP_CT_DIR_REPLY) {
+ if (atomic_dec_and_test(&ct->proto.icmp.count)
+ && del_timer(&ct->timeout))
+ ct->timeout.function((unsigned long)ct);
+ } else {
+ atomic_inc(&ct->proto.icmp.count);
+ nf_conntrack_event_cache(IPCT_PROTOINFO_VOLATILE, skb);
+ nf_ct_refresh_acct(ct, ctinfo, skb, nf_ct_icmpv6_timeout);
+ }
+
+ return NF_ACCEPT;
+}
+
+/* Called when a new connection for this protocol found. */
+static int icmpv6_new(struct nf_conn *conntrack,
+ const struct sk_buff *skb,
+ unsigned int dataoff)
+{
+ static u_int8_t valid_new[] = {
+ [ICMPV6_ECHO_REQUEST - 128] = 1,
+ [ICMPV6_NI_QUERY - 128] = 1
+ };
+
+ if (conntrack->tuplehash[0].tuple.dst.u.icmp.type - 128 >= sizeof(valid_new)
+ || !valid_new[conntrack->tuplehash[0].tuple.dst.u.icmp.type - 128]) {
+ /* Can't create a new ICMPv6 `conn' with this. */
+ DEBUGP("icmp: can't create new conn with type %u\n",
+ conntrack->tuplehash[0].tuple.dst.u.icmp.type);
+ NF_CT_DUMP_TUPLE(&conntrack->tuplehash[0].tuple);
+ return 0;
+ }
+ atomic_set(&conntrack->proto.icmp.count, 0);
+ return 1;
+}
+
+extern int
+nf_ct_ipv6_skip_exthdr(struct sk_buff *skb, int start, u8 *nexthdrp, int len);
+extern struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv6;
+static int
+icmpv6_error_message(struct sk_buff *skb,
+ unsigned int icmp6off,
+ enum ip_conntrack_info *ctinfo,
+ unsigned int hooknum)
+{
+ struct nf_conntrack_tuple intuple, origtuple;
+ struct nf_conntrack_tuple_hash *h;
+ struct icmp6hdr _hdr, *hp;
+ unsigned int inip6off;
+ struct nf_conntrack_protocol *inproto;
+ u_int8_t inprotonum;
+ unsigned int inprotoff;
+
+ NF_CT_ASSERT(skb->nfct == NULL);
+
+ hp = skb_header_pointer(skb, icmp6off, sizeof(_hdr), &_hdr);
+ if (hp == NULL) {
+ DEBUGP("icmpv6_error: Can't get ICMPv6 hdr.\n");
+ return -NF_ACCEPT;
+ }
+
+ inip6off = icmp6off + sizeof(_hdr);
+ if (skb_copy_bits(skb, inip6off+offsetof(struct ipv6hdr, nexthdr),
+ &inprotonum, sizeof(inprotonum)) != 0) {
+ DEBUGP("icmpv6_error: Can't get nexthdr in inner IPv6 header.\n");
+ return -NF_ACCEPT;
+ }
+ inprotoff = nf_ct_ipv6_skip_exthdr(skb,
+ inip6off + sizeof(struct ipv6hdr),
+ &inprotonum,
+ skb->len - inip6off
+ - sizeof(struct ipv6hdr));
+
+ if ((inprotoff < 0) || (inprotoff > skb->len) ||
+ (inprotonum == NEXTHDR_FRAGMENT)) {
+ DEBUGP("icmpv6_error: Can't get protocol header in ICMPv6 payload.\n");
+ return -NF_ACCEPT;
+ }
+
+ inproto = nf_ct_find_proto(PF_INET6, inprotonum);
+
+ /* Are they talking about one of our connections? */
+ if (!nf_ct_get_tuple(skb, inip6off, inprotoff, PF_INET6, inprotonum,
+ &origtuple, &nf_conntrack_l3proto_ipv6, inproto)) {
+ DEBUGP("icmpv6_error: Can't get tuple\n");
+ return -NF_ACCEPT;
+ }
+
+ /* Ordinarily, we'd expect the inverted tupleproto, but it's
+ been preserved inside the ICMP. */
+ if (!nf_ct_invert_tuple(&intuple, &origtuple,
+ &nf_conntrack_l3proto_ipv6, inproto)) {
+ DEBUGP("icmpv6_error: Can't invert tuple\n");
+ return -NF_ACCEPT;
+ }
+
+ *ctinfo = IP_CT_RELATED;
+
+ h = nf_conntrack_find_get(&intuple, NULL);
+ if (!h) {
+ DEBUGP("icmpv6_error: no match\n");
+ return -NF_ACCEPT;
+ } else {
+ if (NF_CT_DIRECTION(h) == IP_CT_DIR_REPLY)
+ *ctinfo += IP_CT_IS_REPLY;
+ }
+
+ /* Update skb to refer to this connection */
+ skb->nfct = &nf_ct_tuplehash_to_ctrack(h)->ct_general;
+ skb->nfctinfo = *ctinfo;
+ return -NF_ACCEPT;
+}
+
+static int
+icmpv6_error(struct sk_buff *skb, unsigned int dataoff,
+ enum ip_conntrack_info *ctinfo, int pf, unsigned int hooknum)
+{
+ struct icmp6hdr _ih, *icmp6h;
+
+ icmp6h = skb_header_pointer(skb, dataoff, sizeof(_ih), &_ih);
+ if (icmp6h == NULL) {
+ if (LOG_INVALID(IPPROTO_ICMPV6))
+ nf_log_packet(PF_INET6, 0, skb, NULL, NULL, NULL,
+ "nf_ct_icmpv6: short packet ");
+ return -NF_ACCEPT;
+ }
+
+ if (hooknum != NF_IP6_PRE_ROUTING)
+ goto skipped;
+
+ /* Ignore it if the checksum's bogus. */
+ if (csum_ipv6_magic(&skb->nh.ipv6h->saddr, &skb->nh.ipv6h->daddr,
+ skb->len - dataoff, IPPROTO_ICMPV6,
+ skb_checksum(skb, dataoff,
+ skb->len - dataoff, 0))) {
+ nf_log_packet(PF_INET6, 0, skb, NULL, NULL, NULL,
+ "nf_ct_icmpv6: ICMPv6 checksum failed\n");
+ return -NF_ACCEPT;
+ }
+
+skipped:
+
+ /* is not error message ? */
+ if (icmp6h->icmp6_type >= 128)
+ return NF_ACCEPT;
+
+ return icmpv6_error_message(skb, dataoff, ctinfo, hooknum);
+}
+
+struct nf_conntrack_protocol nf_conntrack_protocol_icmpv6 =
+{
+ .l3proto = PF_INET6,
+ .proto = IPPROTO_ICMPV6,
+ .name = "icmpv6",
+ .pkt_to_tuple = icmpv6_pkt_to_tuple,
+ .invert_tuple = icmpv6_invert_tuple,
+ .print_tuple = icmpv6_print_tuple,
+ .print_conntrack = icmpv6_print_conntrack,
+ .packet = icmpv6_packet,
+ .new = icmpv6_new,
+ .error = icmpv6_error,
+};
+
+EXPORT_SYMBOL(nf_conntrack_protocol_icmpv6);
diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c
new file mode 100644
index 000000000000..7640b9bb7694
--- /dev/null
+++ b/net/ipv6/netfilter/nf_conntrack_reasm.c
@@ -0,0 +1,885 @@
+/*
+ * IPv6 fragment reassembly for connection tracking
+ *
+ * Copyright (C)2004 USAGI/WIDE Project
+ *
+ * Author:
+ * Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp>
+ *
+ * Based on: net/ipv6/reassembly.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/config.h>
+#include <linux/errno.h>
+#include <linux/types.h>
+#include <linux/string.h>
+#include <linux/socket.h>
+#include <linux/sockios.h>
+#include <linux/jiffies.h>
+#include <linux/net.h>
+#include <linux/list.h>
+#include <linux/netdevice.h>
+#include <linux/in6.h>
+#include <linux/ipv6.h>
+#include <linux/icmpv6.h>
+#include <linux/random.h>
+#include <linux/jhash.h>
+
+#include <net/sock.h>
+#include <net/snmp.h>
+
+#include <net/ipv6.h>
+#include <net/protocol.h>
+#include <net/transp_v6.h>
+#include <net/rawv6.h>
+#include <net/ndisc.h>
+#include <net/addrconf.h>
+#include <linux/sysctl.h>
+#include <linux/netfilter.h>
+#include <linux/netfilter_ipv6.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+
+#if 0
+#define DEBUGP printk
+#else
+#define DEBUGP(format, args...)
+#endif
+
+#define NF_CT_FRAG6_HIGH_THRESH 262144 /* == 256*1024 */
+#define NF_CT_FRAG6_LOW_THRESH 196608 /* == 192*1024 */
+#define NF_CT_FRAG6_TIMEOUT IPV6_FRAG_TIMEOUT
+
+int nf_ct_frag6_high_thresh = 256*1024;
+int nf_ct_frag6_low_thresh = 192*1024;
+int nf_ct_frag6_timeout = IPV6_FRAG_TIMEOUT;
+
+struct nf_ct_frag6_skb_cb
+{
+ struct inet6_skb_parm h;
+ int offset;
+ struct sk_buff *orig;
+};
+
+#define NFCT_FRAG6_CB(skb) ((struct nf_ct_frag6_skb_cb*)((skb)->cb))
+
+struct nf_ct_frag6_queue
+{
+ struct nf_ct_frag6_queue *next;
+ struct list_head lru_list; /* lru list member */
+
+ __u32 id; /* fragment id */
+ struct in6_addr saddr;
+ struct in6_addr daddr;
+
+ spinlock_t lock;
+ atomic_t refcnt;
+ struct timer_list timer; /* expire timer */
+ struct sk_buff *fragments;
+ int len;
+ int meat;
+ struct timeval stamp;
+ unsigned int csum;
+ __u8 last_in; /* has first/last segment arrived? */
+#define COMPLETE 4
+#define FIRST_IN 2
+#define LAST_IN 1
+ __u16 nhoffset;
+ struct nf_ct_frag6_queue **pprev;
+};
+
+/* Hash table. */
+
+#define FRAG6Q_HASHSZ 64
+
+static struct nf_ct_frag6_queue *nf_ct_frag6_hash[FRAG6Q_HASHSZ];
+static rwlock_t nf_ct_frag6_lock = RW_LOCK_UNLOCKED;
+static u32 nf_ct_frag6_hash_rnd;
+static LIST_HEAD(nf_ct_frag6_lru_list);
+int nf_ct_frag6_nqueues = 0;
+
+static __inline__ void __fq_unlink(struct nf_ct_frag6_queue *fq)
+{
+ if (fq->next)
+ fq->next->pprev = fq->pprev;
+ *fq->pprev = fq->next;
+ list_del(&fq->lru_list);
+ nf_ct_frag6_nqueues--;
+}
+
+static __inline__ void fq_unlink(struct nf_ct_frag6_queue *fq)
+{
+ write_lock(&nf_ct_frag6_lock);
+ __fq_unlink(fq);
+ write_unlock(&nf_ct_frag6_lock);
+}
+
+static unsigned int ip6qhashfn(u32 id, struct in6_addr *saddr,
+ struct in6_addr *daddr)
+{
+ u32 a, b, c;
+
+ a = saddr->s6_addr32[0];
+ b = saddr->s6_addr32[1];
+ c = saddr->s6_addr32[2];
+
+ a += JHASH_GOLDEN_RATIO;
+ b += JHASH_GOLDEN_RATIO;
+ c += nf_ct_frag6_hash_rnd;
+ __jhash_mix(a, b, c);
+
+ a += saddr->s6_addr32[3];
+ b += daddr->s6_addr32[0];
+ c += daddr->s6_addr32[1];
+ __jhash_mix(a, b, c);
+
+ a += daddr->s6_addr32[2];
+ b += daddr->s6_addr32[3];
+ c += id;
+ __jhash_mix(a, b, c);
+
+ return c & (FRAG6Q_HASHSZ - 1);
+}
+
+static struct timer_list nf_ct_frag6_secret_timer;
+int nf_ct_frag6_secret_interval = 10 * 60 * HZ;
+
+static void nf_ct_frag6_secret_rebuild(unsigned long dummy)
+{
+ unsigned long now = jiffies;
+ int i;
+
+ write_lock(&nf_ct_frag6_lock);
+ get_random_bytes(&nf_ct_frag6_hash_rnd, sizeof(u32));
+ for (i = 0; i < FRAG6Q_HASHSZ; i++) {
+ struct nf_ct_frag6_queue *q;
+
+ q = nf_ct_frag6_hash[i];
+ while (q) {
+ struct nf_ct_frag6_queue *next = q->next;
+ unsigned int hval = ip6qhashfn(q->id,
+ &q->saddr,
+ &q->daddr);
+
+ if (hval != i) {
+ /* Unlink. */
+ if (q->next)
+ q->next->pprev = q->pprev;
+ *q->pprev = q->next;
+
+ /* Relink to new hash chain. */
+ if ((q->next = nf_ct_frag6_hash[hval]) != NULL)
+ q->next->pprev = &q->next;
+ nf_ct_frag6_hash[hval] = q;
+ q->pprev = &nf_ct_frag6_hash[hval];
+ }
+
+ q = next;
+ }
+ }
+ write_unlock(&nf_ct_frag6_lock);
+
+ mod_timer(&nf_ct_frag6_secret_timer, now + nf_ct_frag6_secret_interval);
+}
+
+atomic_t nf_ct_frag6_mem = ATOMIC_INIT(0);
+
+/* Memory Tracking Functions. */
+static inline void frag_kfree_skb(struct sk_buff *skb)
+{
+ atomic_sub(skb->truesize, &nf_ct_frag6_mem);
+ if (NFCT_FRAG6_CB(skb)->orig)
+ kfree_skb(NFCT_FRAG6_CB(skb)->orig);
+
+ kfree_skb(skb);
+}
+
+static inline void frag_free_queue(struct nf_ct_frag6_queue *fq)
+{
+ atomic_sub(sizeof(struct nf_ct_frag6_queue), &nf_ct_frag6_mem);
+ kfree(fq);
+}
+
+static inline struct nf_ct_frag6_queue *frag_alloc_queue(void)
+{
+ struct nf_ct_frag6_queue *fq = kmalloc(sizeof(struct nf_ct_frag6_queue), GFP_ATOMIC);
+
+ if (!fq)
+ return NULL;
+ atomic_add(sizeof(struct nf_ct_frag6_queue), &nf_ct_frag6_mem);
+ return fq;
+}
+
+/* Destruction primitives. */
+
+/* Complete destruction of fq. */
+static void nf_ct_frag6_destroy(struct nf_ct_frag6_queue *fq)
+{
+ struct sk_buff *fp;
+
+ BUG_TRAP(fq->last_in&COMPLETE);
+ BUG_TRAP(del_timer(&fq->timer) == 0);
+
+ /* Release all fragment data. */
+ fp = fq->fragments;
+ while (fp) {
+ struct sk_buff *xp = fp->next;
+
+ frag_kfree_skb(fp);
+ fp = xp;
+ }
+
+ frag_free_queue(fq);
+}
+
+static __inline__ void fq_put(struct nf_ct_frag6_queue *fq)
+{
+ if (atomic_dec_and_test(&fq->refcnt))
+ nf_ct_frag6_destroy(fq);
+}
+
+/* Kill fq entry. It is not destroyed immediately,
+ * because caller (and someone more) holds reference count.
+ */
+static __inline__ void fq_kill(struct nf_ct_frag6_queue *fq)
+{
+ if (del_timer(&fq->timer))
+ atomic_dec(&fq->refcnt);
+
+ if (!(fq->last_in & COMPLETE)) {
+ fq_unlink(fq);
+ atomic_dec(&fq->refcnt);
+ fq->last_in |= COMPLETE;
+ }
+}
+
+static void nf_ct_frag6_evictor(void)
+{
+ struct nf_ct_frag6_queue *fq;
+ struct list_head *tmp;
+
+ for (;;) {
+ if (atomic_read(&nf_ct_frag6_mem) <= nf_ct_frag6_low_thresh)
+ return;
+ read_lock(&nf_ct_frag6_lock);
+ if (list_empty(&nf_ct_frag6_lru_list)) {
+ read_unlock(&nf_ct_frag6_lock);
+ return;
+ }
+ tmp = nf_ct_frag6_lru_list.next;
+ fq = list_entry(tmp, struct nf_ct_frag6_queue, lru_list);
+ atomic_inc(&fq->refcnt);
+ read_unlock(&nf_ct_frag6_lock);
+
+ spin_lock(&fq->lock);
+ if (!(fq->last_in&COMPLETE))
+ fq_kill(fq);
+ spin_unlock(&fq->lock);
+
+ fq_put(fq);
+ }
+}
+
+static void nf_ct_frag6_expire(unsigned long data)
+{
+ struct nf_ct_frag6_queue *fq = (struct nf_ct_frag6_queue *) data;
+
+ spin_lock(&fq->lock);
+
+ if (fq->last_in & COMPLETE)
+ goto out;
+
+ fq_kill(fq);
+
+out:
+ spin_unlock(&fq->lock);
+ fq_put(fq);
+}
+
+/* Creation primitives. */
+
+
+static struct nf_ct_frag6_queue *nf_ct_frag6_intern(unsigned int hash,
+ struct nf_ct_frag6_queue *fq_in)
+{
+ struct nf_ct_frag6_queue *fq;
+
+ write_lock(&nf_ct_frag6_lock);
+#ifdef CONFIG_SMP
+ for (fq = nf_ct_frag6_hash[hash]; fq; fq = fq->next) {
+ if (fq->id == fq_in->id &&
+ !ipv6_addr_cmp(&fq_in->saddr, &fq->saddr) &&
+ !ipv6_addr_cmp(&fq_in->daddr, &fq->daddr)) {
+ atomic_inc(&fq->refcnt);
+ write_unlock(&nf_ct_frag6_lock);
+ fq_in->last_in |= COMPLETE;
+ fq_put(fq_in);
+ return fq;
+ }
+ }
+#endif
+ fq = fq_in;
+
+ if (!mod_timer(&fq->timer, jiffies + nf_ct_frag6_timeout))
+ atomic_inc(&fq->refcnt);
+
+ atomic_inc(&fq->refcnt);
+ if ((fq->next = nf_ct_frag6_hash[hash]) != NULL)
+ fq->next->pprev = &fq->next;
+ nf_ct_frag6_hash[hash] = fq;
+ fq->pprev = &nf_ct_frag6_hash[hash];
+ INIT_LIST_HEAD(&fq->lru_list);
+ list_add_tail(&fq->lru_list, &nf_ct_frag6_lru_list);
+ nf_ct_frag6_nqueues++;
+ write_unlock(&nf_ct_frag6_lock);
+ return fq;
+}
+
+
+static struct nf_ct_frag6_queue *
+nf_ct_frag6_create(unsigned int hash, u32 id, struct in6_addr *src, struct in6_addr *dst)
+{
+ struct nf_ct_frag6_queue *fq;
+
+ if ((fq = frag_alloc_queue()) == NULL) {
+ DEBUGP("Can't alloc new queue\n");
+ goto oom;
+ }
+
+ memset(fq, 0, sizeof(struct nf_ct_frag6_queue));
+
+ fq->id = id;
+ ipv6_addr_copy(&fq->saddr, src);
+ ipv6_addr_copy(&fq->daddr, dst);
+
+ init_timer(&fq->timer);
+ fq->timer.function = nf_ct_frag6_expire;
+ fq->timer.data = (long) fq;
+ fq->lock = SPIN_LOCK_UNLOCKED;
+ atomic_set(&fq->refcnt, 1);
+
+ return nf_ct_frag6_intern(hash, fq);
+
+oom:
+ return NULL;
+}
+
+static __inline__ struct nf_ct_frag6_queue *
+fq_find(u32 id, struct in6_addr *src, struct in6_addr *dst)
+{
+ struct nf_ct_frag6_queue *fq;
+ unsigned int hash = ip6qhashfn(id, src, dst);
+
+ read_lock(&nf_ct_frag6_lock);
+ for (fq = nf_ct_frag6_hash[hash]; fq; fq = fq->next) {
+ if (fq->id == id &&
+ !ipv6_addr_cmp(src, &fq->saddr) &&
+ !ipv6_addr_cmp(dst, &fq->daddr)) {
+ atomic_inc(&fq->refcnt);
+ read_unlock(&nf_ct_frag6_lock);
+ return fq;
+ }
+ }
+ read_unlock(&nf_ct_frag6_lock);
+
+ return nf_ct_frag6_create(hash, id, src, dst);
+}
+
+
+static int nf_ct_frag6_queue(struct nf_ct_frag6_queue *fq, struct sk_buff *skb,
+ struct frag_hdr *fhdr, int nhoff)
+{
+ struct sk_buff *prev, *next;
+ int offset, end;
+
+ if (fq->last_in & COMPLETE) {
+ DEBUGP("Allready completed\n");
+ goto err;
+ }
+
+ offset = ntohs(fhdr->frag_off) & ~0x7;
+ end = offset + (ntohs(skb->nh.ipv6h->payload_len) -
+ ((u8 *) (fhdr + 1) - (u8 *) (skb->nh.ipv6h + 1)));
+
+ if ((unsigned int)end > IPV6_MAXPLEN) {
+ DEBUGP("offset is too large.\n");
+ return -1;
+ }
+
+ if (skb->ip_summed == CHECKSUM_HW)
+ skb->csum = csum_sub(skb->csum,
+ csum_partial(skb->nh.raw,
+ (u8*)(fhdr + 1) - skb->nh.raw,
+ 0));
+
+ /* Is this the final fragment? */
+ if (!(fhdr->frag_off & htons(IP6_MF))) {
+ /* If we already have some bits beyond end
+ * or have different end, the segment is corrupted.
+ */
+ if (end < fq->len ||
+ ((fq->last_in & LAST_IN) && end != fq->len)) {
+ DEBUGP("already received last fragment\n");
+ goto err;
+ }
+ fq->last_in |= LAST_IN;
+ fq->len = end;
+ } else {
+ /* Check if the fragment is rounded to 8 bytes.
+ * Required by the RFC.
+ */
+ if (end & 0x7) {
+ /* RFC2460 says always send parameter problem in
+ * this case. -DaveM
+ */
+ DEBUGP("the end of this fragment is not rounded to 8 bytes.\n");
+ return -1;
+ }
+ if (end > fq->len) {
+ /* Some bits beyond end -> corruption. */
+ if (fq->last_in & LAST_IN) {
+ DEBUGP("last packet already reached.\n");
+ goto err;
+ }
+ fq->len = end;
+ }
+ }
+
+ if (end == offset)
+ goto err;
+
+ /* Point into the IP datagram 'data' part. */
+ if (!pskb_pull(skb, (u8 *) (fhdr + 1) - skb->data)) {
+ DEBUGP("queue: message is too short.\n");
+ goto err;
+ }
+ if (end-offset < skb->len) {
+ if (pskb_trim(skb, end - offset)) {
+ DEBUGP("Can't trim\n");
+ goto err;
+ }
+ if (skb->ip_summed != CHECKSUM_UNNECESSARY)
+ skb->ip_summed = CHECKSUM_NONE;
+ }
+
+ /* Find out which fragments are in front and at the back of us
+ * in the chain of fragments so far. We must know where to put
+ * this fragment, right?
+ */
+ prev = NULL;
+ for (next = fq->fragments; next != NULL; next = next->next) {
+ if (NFCT_FRAG6_CB(next)->offset >= offset)
+ break; /* bingo! */
+ prev = next;
+ }
+
+ /* We found where to put this one. Check for overlap with
+ * preceding fragment, and, if needed, align things so that
+ * any overlaps are eliminated.
+ */
+ if (prev) {
+ int i = (NFCT_FRAG6_CB(prev)->offset + prev->len) - offset;
+
+ if (i > 0) {
+ offset += i;
+ if (end <= offset) {
+ DEBUGP("overlap\n");
+ goto err;
+ }
+ if (!pskb_pull(skb, i)) {
+ DEBUGP("Can't pull\n");
+ goto err;
+ }
+ if (skb->ip_summed != CHECKSUM_UNNECESSARY)
+ skb->ip_summed = CHECKSUM_NONE;
+ }
+ }
+
+ /* Look for overlap with succeeding segments.
+ * If we can merge fragments, do it.
+ */
+ while (next && NFCT_FRAG6_CB(next)->offset < end) {
+ /* overlap is 'i' bytes */
+ int i = end - NFCT_FRAG6_CB(next)->offset;
+
+ if (i < next->len) {
+ /* Eat head of the next overlapped fragment
+ * and leave the loop. The next ones cannot overlap.
+ */
+ DEBUGP("Eat head of the overlapped parts.: %d", i);
+ if (!pskb_pull(next, i))
+ goto err;
+
+ /* next fragment */
+ NFCT_FRAG6_CB(next)->offset += i;
+ fq->meat -= i;
+ if (next->ip_summed != CHECKSUM_UNNECESSARY)
+ next->ip_summed = CHECKSUM_NONE;
+ break;
+ } else {
+ struct sk_buff *free_it = next;
+
+ /* Old fragmnet is completely overridden with
+ * new one drop it.
+ */
+ next = next->next;
+
+ if (prev)
+ prev->next = next;
+ else
+ fq->fragments = next;
+
+ fq->meat -= free_it->len;
+ frag_kfree_skb(free_it);
+ }
+ }
+
+ NFCT_FRAG6_CB(skb)->offset = offset;
+
+ /* Insert this fragment in the chain of fragments. */
+ skb->next = next;
+ if (prev)
+ prev->next = skb;
+ else
+ fq->fragments = skb;
+
+ skb->dev = NULL;
+ skb_get_timestamp(skb, &fq->stamp);
+ fq->meat += skb->len;
+ atomic_add(skb->truesize, &nf_ct_frag6_mem);
+
+ /* The first fragment.
+ * nhoffset is obtained from the first fragment, of course.
+ */
+ if (offset == 0) {
+ fq->nhoffset = nhoff;
+ fq->last_in |= FIRST_IN;
+ }
+ write_lock(&nf_ct_frag6_lock);
+ list_move_tail(&fq->lru_list, &nf_ct_frag6_lru_list);
+ write_unlock(&nf_ct_frag6_lock);
+ return 0;
+
+err:
+ return -1;
+}
+
+/*
+ * Check if this packet is complete.
+ * Returns NULL on failure by any reason, and pointer
+ * to current nexthdr field in reassembled frame.
+ *
+ * It is called with locked fq, and caller must check that
+ * queue is eligible for reassembly i.e. it is not COMPLETE,
+ * the last and the first frames arrived and all the bits are here.
+ */
+static struct sk_buff *
+nf_ct_frag6_reasm(struct nf_ct_frag6_queue *fq, struct net_device *dev)
+{
+ struct sk_buff *fp, *op, *head = fq->fragments;
+ int payload_len;
+
+ fq_kill(fq);
+
+ BUG_TRAP(head != NULL);
+ BUG_TRAP(NFCT_FRAG6_CB(head)->offset == 0);
+
+ /* Unfragmented part is taken from the first segment. */
+ payload_len = (head->data - head->nh.raw) - sizeof(struct ipv6hdr) + fq->len - sizeof(struct frag_hdr);
+ if (payload_len > IPV6_MAXPLEN) {
+ DEBUGP("payload len is too large.\n");
+ goto out_oversize;
+ }
+
+ /* Head of list must not be cloned. */
+ if (skb_cloned(head) && pskb_expand_head(head, 0, 0, GFP_ATOMIC)) {
+ DEBUGP("skb is cloned but can't expand head");
+ goto out_oom;
+ }
+
+ /* If the first fragment is fragmented itself, we split
+ * it to two chunks: the first with data and paged part
+ * and the second, holding only fragments. */
+ if (skb_shinfo(head)->frag_list) {
+ struct sk_buff *clone;
+ int i, plen = 0;
+
+ if ((clone = alloc_skb(0, GFP_ATOMIC)) == NULL) {
+ DEBUGP("Can't alloc skb\n");
+ goto out_oom;
+ }
+ clone->next = head->next;
+ head->next = clone;
+ skb_shinfo(clone)->frag_list = skb_shinfo(head)->frag_list;
+ skb_shinfo(head)->frag_list = NULL;
+ for (i=0; i<skb_shinfo(head)->nr_frags; i++)
+ plen += skb_shinfo(head)->frags[i].size;
+ clone->len = clone->data_len = head->data_len - plen;
+ head->data_len -= clone->len;
+ head->len -= clone->len;
+ clone->csum = 0;
+ clone->ip_summed = head->ip_summed;
+
+ NFCT_FRAG6_CB(clone)->orig = NULL;
+ atomic_add(clone->truesize, &nf_ct_frag6_mem);
+ }
+
+ /* We have to remove fragment header from datagram and to relocate
+ * header in order to calculate ICV correctly. */
+ head->nh.raw[fq->nhoffset] = head->h.raw[0];
+ memmove(head->head + sizeof(struct frag_hdr), head->head,
+ (head->data - head->head) - sizeof(struct frag_hdr));
+ head->mac.raw += sizeof(struct frag_hdr);
+ head->nh.raw += sizeof(struct frag_hdr);
+
+ skb_shinfo(head)->frag_list = head->next;
+ head->h.raw = head->data;
+ skb_push(head, head->data - head->nh.raw);
+ atomic_sub(head->truesize, &nf_ct_frag6_mem);
+
+ for (fp=head->next; fp; fp = fp->next) {
+ head->data_len += fp->len;
+ head->len += fp->len;
+ if (head->ip_summed != fp->ip_summed)
+ head->ip_summed = CHECKSUM_NONE;
+ else if (head->ip_summed == CHECKSUM_HW)
+ head->csum = csum_add(head->csum, fp->csum);
+ head->truesize += fp->truesize;
+ atomic_sub(fp->truesize, &nf_ct_frag6_mem);
+ }
+
+ head->next = NULL;
+ head->dev = dev;
+ skb_set_timestamp(head, &fq->stamp);
+ head->nh.ipv6h->payload_len = htons(payload_len);
+
+ /* Yes, and fold redundant checksum back. 8) */
+ if (head->ip_summed == CHECKSUM_HW)
+ head->csum = csum_partial(head->nh.raw, head->h.raw-head->nh.raw, head->csum);
+
+ fq->fragments = NULL;
+
+ /* all original skbs are linked into the NFCT_FRAG6_CB(head).orig */
+ fp = skb_shinfo(head)->frag_list;
+ if (NFCT_FRAG6_CB(fp)->orig == NULL)
+ /* at above code, head skb is divided into two skbs. */
+ fp = fp->next;
+
+ op = NFCT_FRAG6_CB(head)->orig;
+ for (; fp; fp = fp->next) {
+ struct sk_buff *orig = NFCT_FRAG6_CB(fp)->orig;
+
+ op->next = orig;
+ op = orig;
+ NFCT_FRAG6_CB(fp)->orig = NULL;
+ }
+
+ return head;
+
+out_oversize:
+ if (net_ratelimit())
+ printk(KERN_DEBUG "nf_ct_frag6_reasm: payload len = %d\n", payload_len);
+ goto out_fail;
+out_oom:
+ if (net_ratelimit())
+ printk(KERN_DEBUG "nf_ct_frag6_reasm: no memory for reassembly\n");
+out_fail:
+ return NULL;
+}
+
+/*
+ * find the header just before Fragment Header.
+ *
+ * if success return 0 and set ...
+ * (*prevhdrp): the value of "Next Header Field" in the header
+ * just before Fragment Header.
+ * (*prevhoff): the offset of "Next Header Field" in the header
+ * just before Fragment Header.
+ * (*fhoff) : the offset of Fragment Header.
+ *
+ * Based on ipv6_skip_hdr() in net/ipv6/exthdr.c
+ *
+ */
+static int
+find_prev_fhdr(struct sk_buff *skb, u8 *prevhdrp, int *prevhoff, int *fhoff)
+{
+ u8 nexthdr = skb->nh.ipv6h->nexthdr;
+ u8 prev_nhoff = (u8 *)&skb->nh.ipv6h->nexthdr - skb->data;
+ int start = (u8 *)(skb->nh.ipv6h+1) - skb->data;
+ int len = skb->len - start;
+ u8 prevhdr = NEXTHDR_IPV6;
+
+ while (nexthdr != NEXTHDR_FRAGMENT) {
+ struct ipv6_opt_hdr hdr;
+ int hdrlen;
+
+ if (!ipv6_ext_hdr(nexthdr)) {
+ return -1;
+ }
+ if (len < (int)sizeof(struct ipv6_opt_hdr)) {
+ DEBUGP("too short\n");
+ return -1;
+ }
+ if (nexthdr == NEXTHDR_NONE) {
+ DEBUGP("next header is none\n");
+ return -1;
+ }
+ if (skb_copy_bits(skb, start, &hdr, sizeof(hdr)))
+ BUG();
+ if (nexthdr == NEXTHDR_AUTH)
+ hdrlen = (hdr.hdrlen+2)<<2;
+ else
+ hdrlen = ipv6_optlen(&hdr);
+
+ prevhdr = nexthdr;
+ prev_nhoff = start;
+
+ nexthdr = hdr.nexthdr;
+ len -= hdrlen;
+ start += hdrlen;
+ }
+
+ if (len < 0)
+ return -1;
+
+ *prevhdrp = prevhdr;
+ *prevhoff = prev_nhoff;
+ *fhoff = start;
+
+ return 0;
+}
+
+struct sk_buff *nf_ct_frag6_gather(struct sk_buff *skb)
+{
+ struct sk_buff *clone;
+ struct net_device *dev = skb->dev;
+ struct frag_hdr *fhdr;
+ struct nf_ct_frag6_queue *fq;
+ struct ipv6hdr *hdr;
+ int fhoff, nhoff;
+ u8 prevhdr;
+ struct sk_buff *ret_skb = NULL;
+
+ /* Jumbo payload inhibits frag. header */
+ if (skb->nh.ipv6h->payload_len == 0) {
+ DEBUGP("payload len = 0\n");
+ return skb;
+ }
+
+ if (find_prev_fhdr(skb, &prevhdr, &nhoff, &fhoff) < 0)
+ return skb;
+
+ clone = skb_clone(skb, GFP_ATOMIC);
+ if (clone == NULL) {
+ DEBUGP("Can't clone skb\n");
+ return skb;
+ }
+
+ NFCT_FRAG6_CB(clone)->orig = skb;
+
+ if (!pskb_may_pull(clone, fhoff + sizeof(*fhdr))) {
+ DEBUGP("message is too short.\n");
+ goto ret_orig;
+ }
+
+ clone->h.raw = clone->data + fhoff;
+ hdr = clone->nh.ipv6h;
+ fhdr = (struct frag_hdr *)clone->h.raw;
+
+ if (!(fhdr->frag_off & htons(0xFFF9))) {
+ DEBUGP("Invalid fragment offset\n");
+ /* It is not a fragmented frame */
+ goto ret_orig;
+ }
+
+ if (atomic_read(&nf_ct_frag6_mem) > nf_ct_frag6_high_thresh)
+ nf_ct_frag6_evictor();
+
+ fq = fq_find(fhdr->identification, &hdr->saddr, &hdr->daddr);
+ if (fq == NULL) {
+ DEBUGP("Can't find and can't create new queue\n");
+ goto ret_orig;
+ }
+
+ spin_lock(&fq->lock);
+
+ if (nf_ct_frag6_queue(fq, clone, fhdr, nhoff) < 0) {
+ spin_unlock(&fq->lock);
+ DEBUGP("Can't insert skb to queue\n");
+ fq_put(fq);
+ goto ret_orig;
+ }
+
+ if (fq->last_in == (FIRST_IN|LAST_IN) && fq->meat == fq->len) {
+ ret_skb = nf_ct_frag6_reasm(fq, dev);
+ if (ret_skb == NULL)
+ DEBUGP("Can't reassemble fragmented packets\n");
+ }
+ spin_unlock(&fq->lock);
+
+ fq_put(fq);
+ return ret_skb;
+
+ret_orig:
+ kfree_skb(clone);
+ return skb;
+}
+
+void nf_ct_frag6_output(unsigned int hooknum, struct sk_buff *skb,
+ struct net_device *in, struct net_device *out,
+ int (*okfn)(struct sk_buff *))
+{
+ struct sk_buff *s, *s2;
+
+ for (s = NFCT_FRAG6_CB(skb)->orig; s;) {
+ nf_conntrack_put_reasm(s->nfct_reasm);
+ nf_conntrack_get_reasm(skb);
+ s->nfct_reasm = skb;
+
+ s2 = s->next;
+ NF_HOOK_THRESH(PF_INET6, hooknum, s, in, out, okfn,
+ NF_IP6_PRI_CONNTRACK_DEFRAG + 1);
+ s = s2;
+ }
+ nf_conntrack_put_reasm(skb);
+}
+
+int nf_ct_frag6_kfree_frags(struct sk_buff *skb)
+{
+ struct sk_buff *s, *s2;
+
+ for (s = NFCT_FRAG6_CB(skb)->orig; s; s = s2) {
+
+ s2 = s->next;
+ kfree_skb(s);
+ }
+
+ kfree_skb(skb);
+
+ return 0;
+}
+
+int nf_ct_frag6_init(void)
+{
+ nf_ct_frag6_hash_rnd = (u32) ((num_physpages ^ (num_physpages>>7)) ^
+ (jiffies ^ (jiffies >> 6)));
+
+ init_timer(&nf_ct_frag6_secret_timer);
+ nf_ct_frag6_secret_timer.function = nf_ct_frag6_secret_rebuild;
+ nf_ct_frag6_secret_timer.expires = jiffies
+ + nf_ct_frag6_secret_interval;
+ add_timer(&nf_ct_frag6_secret_timer);
+
+ return 0;
+}
+
+void nf_ct_frag6_cleanup(void)
+{
+ del_timer(&nf_ct_frag6_secret_timer);
+ nf_ct_frag6_evictor();
+}
diff --git a/net/ipv6/proc.c b/net/ipv6/proc.c
index 334a5967831e..50a13e75d70e 100644
--- a/net/ipv6/proc.c
+++ b/net/ipv6/proc.c
@@ -140,9 +140,7 @@ fold_field(void *mib[], int offt)
unsigned long res = 0;
int i;
- for (i = 0; i < NR_CPUS; i++) {
- if (!cpu_possible(i))
- continue;
+ for_each_cpu(i) {
res += *(((unsigned long *)per_cpu_ptr(mib[0], i)) + offt);
res += *(((unsigned long *)per_cpu_ptr(mib[1], i)) + offt);
}
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index a1265a320b11..8e9628f1c4c5 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -174,8 +174,10 @@ int ipv6_raw_deliver(struct sk_buff *skb, int nexthdr)
struct sk_buff *clone = skb_clone(skb, GFP_ATOMIC);
/* Not releasing hash table! */
- if (clone)
+ if (clone) {
+ nf_reset(clone);
rawv6_rcv(sk, clone);
+ }
}
sk = __raw_v6_lookup(sk_next(sk), nexthdr, daddr, saddr,
IP6CB(skb)->iif);
@@ -296,13 +298,10 @@ void rawv6_err(struct sock *sk, struct sk_buff *skb,
static inline int rawv6_rcv_skb(struct sock * sk, struct sk_buff * skb)
{
if ((raw6_sk(sk)->checksum || sk->sk_filter) &&
- skb->ip_summed != CHECKSUM_UNNECESSARY) {
- if ((unsigned short)csum_fold(skb_checksum(skb, 0, skb->len, skb->csum))) {
- /* FIXME: increment a raw6 drops counter here */
- kfree_skb(skb);
- return 0;
- }
- skb->ip_summed = CHECKSUM_UNNECESSARY;
+ skb_checksum_complete(skb)) {
+ /* FIXME: increment a raw6 drops counter here */
+ kfree_skb(skb);
+ return 0;
}
/* Charge it to the socket. */
@@ -335,32 +334,25 @@ int rawv6_rcv(struct sock *sk, struct sk_buff *skb)
if (!rp->checksum)
skb->ip_summed = CHECKSUM_UNNECESSARY;
- if (skb->ip_summed != CHECKSUM_UNNECESSARY) {
- if (skb->ip_summed == CHECKSUM_HW) {
- skb_postpull_rcsum(skb, skb->nh.raw,
- skb->h.raw - skb->nh.raw);
+ if (skb->ip_summed == CHECKSUM_HW) {
+ skb_postpull_rcsum(skb, skb->nh.raw,
+ skb->h.raw - skb->nh.raw);
+ if (!csum_ipv6_magic(&skb->nh.ipv6h->saddr,
+ &skb->nh.ipv6h->daddr,
+ skb->len, inet->num, skb->csum))
skb->ip_summed = CHECKSUM_UNNECESSARY;
- if (csum_ipv6_magic(&skb->nh.ipv6h->saddr,
- &skb->nh.ipv6h->daddr,
- skb->len, inet->num, skb->csum)) {
- LIMIT_NETDEBUG(KERN_DEBUG "raw v6 hw csum failure.\n");
- skb->ip_summed = CHECKSUM_NONE;
- }
- }
- if (skb->ip_summed == CHECKSUM_NONE)
- skb->csum = ~csum_ipv6_magic(&skb->nh.ipv6h->saddr,
- &skb->nh.ipv6h->daddr,
- skb->len, inet->num, 0);
}
+ if (skb->ip_summed != CHECKSUM_UNNECESSARY)
+ skb->csum = ~csum_ipv6_magic(&skb->nh.ipv6h->saddr,
+ &skb->nh.ipv6h->daddr,
+ skb->len, inet->num, 0);
if (inet->hdrincl) {
- if (skb->ip_summed != CHECKSUM_UNNECESSARY &&
- (unsigned short)csum_fold(skb_checksum(skb, 0, skb->len, skb->csum))) {
+ if (skb_checksum_complete(skb)) {
/* FIXME: increment a raw6 drops counter here */
kfree_skb(skb);
return 0;
}
- skb->ip_summed = CHECKSUM_UNNECESSARY;
}
rawv6_rcv_skb(sk, skb);
@@ -405,7 +397,7 @@ static int rawv6_recvmsg(struct kiocb *iocb, struct sock *sk,
if (skb->ip_summed==CHECKSUM_UNNECESSARY) {
err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
} else if (msg->msg_flags&MSG_TRUNC) {
- if ((unsigned short)csum_fold(skb_checksum(skb, 0, skb->len, skb->csum)))
+ if (__skb_checksum_complete(skb))
goto csum_copy_err;
err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
} else {
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 5d5bbb49ec78..f7f42c3e96cb 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -483,7 +483,7 @@ restart:
goto out;
}
- rt = rt6_device_match(rt, skb->dev->ifindex, 0);
+ rt = rt6_device_match(rt, skb->dev->ifindex, strict);
BACKTRACK();
if (!rt->rt6i_nexthop && !(rt->rt6i_flags & RTF_NONEXTHOP)) {
@@ -1710,7 +1710,7 @@ static void fib6_dump_end(struct netlink_callback *cb)
static int fib6_dump_done(struct netlink_callback *cb)
{
fib6_dump_end(cb);
- return cb->done(cb);
+ return cb->done ? cb->done(cb) : 0;
}
int inet6_dump_fib(struct sk_buff *skb, struct netlink_callback *cb)
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index d693cb988b78..62c0e5bd931c 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -114,16 +114,9 @@ static int tcp_v6_get_port(struct sock *sk, unsigned short snum)
int low = sysctl_local_port_range[0];
int high = sysctl_local_port_range[1];
int remaining = (high - low) + 1;
- int rover;
+ int rover = net_random() % (high - low) + low;
- spin_lock(&tcp_hashinfo.portalloc_lock);
- if (tcp_hashinfo.port_rover < low)
- rover = low;
- else
- rover = tcp_hashinfo.port_rover;
- do { rover++;
- if (rover > high)
- rover = low;
+ do {
head = &tcp_hashinfo.bhash[inet_bhashfn(rover, tcp_hashinfo.bhash_size)];
spin_lock(&head->lock);
inet_bind_bucket_for_each(tb, node, &head->chain)
@@ -132,9 +125,9 @@ static int tcp_v6_get_port(struct sock *sk, unsigned short snum)
break;
next:
spin_unlock(&head->lock);
+ if (++rover > high)
+ rover = low;
} while (--remaining > 0);
- tcp_hashinfo.port_rover = rover;
- spin_unlock(&tcp_hashinfo.portalloc_lock);
/* Exhausted local port range during search? It is not
* possible for us to be holding one of the bind hash
@@ -1408,20 +1401,18 @@ out:
static int tcp_v6_checksum_init(struct sk_buff *skb)
{
if (skb->ip_summed == CHECKSUM_HW) {
- skb->ip_summed = CHECKSUM_UNNECESSARY;
if (!tcp_v6_check(skb->h.th,skb->len,&skb->nh.ipv6h->saddr,
- &skb->nh.ipv6h->daddr,skb->csum))
+ &skb->nh.ipv6h->daddr,skb->csum)) {
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
return 0;
- LIMIT_NETDEBUG(KERN_DEBUG "hw tcp v6 csum failed\n");
+ }
}
+
+ skb->csum = ~tcp_v6_check(skb->h.th,skb->len,&skb->nh.ipv6h->saddr,
+ &skb->nh.ipv6h->daddr, 0);
+
if (skb->len <= 76) {
- if (tcp_v6_check(skb->h.th,skb->len,&skb->nh.ipv6h->saddr,
- &skb->nh.ipv6h->daddr,skb_checksum(skb, 0, skb->len, 0)))
- return -1;
- skb->ip_summed = CHECKSUM_UNNECESSARY;
- } else {
- skb->csum = ~tcp_v6_check(skb->h.th,skb->len,&skb->nh.ipv6h->saddr,
- &skb->nh.ipv6h->daddr,0);
+ return __skb_checksum_complete(skb);
}
return 0;
}
@@ -1582,7 +1573,7 @@ static int tcp_v6_rcv(struct sk_buff **pskb, unsigned int *nhoffp)
goto discard_it;
if ((skb->ip_summed != CHECKSUM_UNNECESSARY &&
- tcp_v6_checksum_init(skb) < 0))
+ tcp_v6_checksum_init(skb)))
goto bad_packet;
th = skb->h.th;
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index bf9519341fd3..e671153b47b2 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -248,7 +248,7 @@ try_again:
err = skb_copy_datagram_iovec(skb, sizeof(struct udphdr), msg->msg_iov,
copied);
} else if (msg->msg_flags&MSG_TRUNC) {
- if ((unsigned short)csum_fold(skb_checksum(skb, 0, skb->len, skb->csum)))
+ if (__skb_checksum_complete(skb))
goto csum_copy_err;
err = skb_copy_datagram_iovec(skb, sizeof(struct udphdr), msg->msg_iov,
copied);
@@ -363,13 +363,10 @@ static inline int udpv6_queue_rcv_skb(struct sock * sk, struct sk_buff *skb)
return -1;
}
- if (skb->ip_summed != CHECKSUM_UNNECESSARY) {
- if ((unsigned short)csum_fold(skb_checksum(skb, 0, skb->len, skb->csum))) {
- UDP6_INC_STATS_BH(UDP_MIB_INERRORS);
- kfree_skb(skb);
- return 0;
- }
- skb->ip_summed = CHECKSUM_UNNECESSARY;
+ if (skb_checksum_complete(skb)) {
+ UDP6_INC_STATS_BH(UDP_MIB_INERRORS);
+ kfree_skb(skb);
+ return 0;
}
if (sock_queue_rcv_skb(sk,skb)<0) {
@@ -491,13 +488,10 @@ static int udpv6_rcv(struct sk_buff **pskb, unsigned int *nhoffp)
uh = skb->h.uh;
}
- if (skb->ip_summed==CHECKSUM_HW) {
+ if (skb->ip_summed == CHECKSUM_HW &&
+ !csum_ipv6_magic(saddr, daddr, ulen, IPPROTO_UDP, skb->csum))
skb->ip_summed = CHECKSUM_UNNECESSARY;
- if (csum_ipv6_magic(saddr, daddr, ulen, IPPROTO_UDP, skb->csum)) {
- LIMIT_NETDEBUG(KERN_DEBUG "udp v6 hw csum failure.\n");
- skb->ip_summed = CHECKSUM_NONE;
- }
- }
+
if (skb->ip_summed != CHECKSUM_UNNECESSARY)
skb->csum = ~csum_ipv6_magic(saddr, daddr, ulen, IPPROTO_UDP, 0);
@@ -521,8 +515,7 @@ static int udpv6_rcv(struct sk_buff **pskb, unsigned int *nhoffp)
if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb))
goto discard;
- if (skb->ip_summed != CHECKSUM_UNNECESSARY &&
- (unsigned short)csum_fold(skb_checksum(skb, 0, skb->len, skb->csum)))
+ if (skb_checksum_complete(skb))
goto discard;
UDP6_INC_STATS_BH(UDP_MIB_NOPORTS);
diff --git a/net/irda/discovery.c b/net/irda/discovery.c
index c4ba5fa1446a..3fefc822c1c0 100644
--- a/net/irda/discovery.c
+++ b/net/irda/discovery.c
@@ -194,8 +194,7 @@ void irlmp_expire_discoveries(hashbin_t *log, __u32 saddr, int force)
/* Remove it from the log */
curr = hashbin_remove_this(log, (irda_queue_t *) curr);
- if (curr)
- kfree(curr);
+ kfree(curr);
}
}
diff --git a/net/irda/irias_object.c b/net/irda/irias_object.c
index 6fec428b4512..75f2666e8630 100644
--- a/net/irda/irias_object.c
+++ b/net/irda/irias_object.c
@@ -122,8 +122,7 @@ static void __irias_delete_attrib(struct ias_attrib *attrib)
IRDA_ASSERT(attrib != NULL, return;);
IRDA_ASSERT(attrib->magic == IAS_ATTRIB_MAGIC, return;);
- if (attrib->name)
- kfree(attrib->name);
+ kfree(attrib->name);
irias_delete_value(attrib->value);
attrib->magic = ~IAS_ATTRIB_MAGIC;
@@ -136,8 +135,7 @@ void __irias_delete_object(struct ias_object *obj)
IRDA_ASSERT(obj != NULL, return;);
IRDA_ASSERT(obj->magic == IAS_OBJECT_MAGIC, return;);
- if (obj->name)
- kfree(obj->name);
+ kfree(obj->name);
hashbin_delete(obj->attribs, (FREE_FUNC) __irias_delete_attrib);
@@ -562,14 +560,12 @@ void irias_delete_value(struct ias_value *value)
/* No need to deallocate */
break;
case IAS_STRING:
- /* If string, deallocate string */
- if (value->t.string != NULL)
- kfree(value->t.string);
+ /* Deallocate string */
+ kfree(value->t.string);
break;
case IAS_OCT_SEQ:
- /* If byte stream, deallocate byte stream */
- if (value->t.oct_seq != NULL)
- kfree(value->t.oct_seq);
+ /* Deallocate byte stream */
+ kfree(value->t.oct_seq);
break;
default:
IRDA_DEBUG(0, "%s(), Unknown value type!\n", __FUNCTION__);
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
index 8296b38bf270..a84f9221e5f0 100644
--- a/net/netfilter/Kconfig
+++ b/net/netfilter/Kconfig
@@ -1,3 +1,6 @@
+menu "Core Netfilter Configuration"
+ depends on NET && NETFILTER
+
config NETFILTER_NETLINK
tristate "Netfilter netlink interface"
help
@@ -22,3 +25,74 @@ config NETFILTER_NETLINK_LOG
and is also scheduled to replace the old syslog-based ipt_LOG
and ip6t_LOG modules.
+config NF_CONNTRACK
+ tristate "Layer 3 Independent Connection tracking (EXPERIMENTAL)"
+ depends on EXPERIMENTAL && IP_NF_CONNTRACK=n
+ default n
+ ---help---
+ Connection tracking keeps a record of what packets have passed
+ through your machine, in order to figure out how they are related
+ into connections.
+
+ Layer 3 independent connection tracking is experimental scheme
+ which generalize ip_conntrack to support other layer 3 protocols.
+
+ To compile it as a module, choose M here. If unsure, say N.
+
+config NF_CT_ACCT
+ bool "Connection tracking flow accounting"
+ depends on NF_CONNTRACK
+ help
+ If this option is enabled, the connection tracking code will
+ keep per-flow packet and byte counters.
+
+ Those counters can be used for flow-based accounting or the
+ `connbytes' match.
+
+ If unsure, say `N'.
+
+config NF_CONNTRACK_MARK
+ bool 'Connection mark tracking support'
+ depends on NF_CONNTRACK
+ help
+ This option enables support for connection marks, used by the
+ `CONNMARK' target and `connmark' match. Similar to the mark value
+ of packets, but this mark value is kept in the conntrack session
+ instead of the individual packets.
+
+config NF_CONNTRACK_EVENTS
+ bool "Connection tracking events"
+ depends on NF_CONNTRACK
+ help
+ If this option is enabled, the connection tracking code will
+ provide a notifier chain that can be used by other kernel code
+ to get notified aboutchanges in the connection tracking state.
+
+ If unsure, say `N'.
+
+config NF_CT_PROTO_SCTP
+ tristate 'SCTP protocol on new connection tracking support (EXPERIMENTAL)'
+ depends on EXPERIMENTAL && NF_CONNTRACK
+ default n
+ help
+ With this option enabled, the layer 3 independent connection
+ tracking code will be able to do state tracking on SCTP connections.
+
+ If you want to compile it as a module, say M here and read
+ Documentation/modules.txt. If unsure, say `N'.
+
+config NF_CONNTRACK_FTP
+ tristate "FTP support on new connection tracking (EXPERIMENTAL)"
+ depends on EXPERIMENTAL && NF_CONNTRACK
+ help
+ Tracking FTP connections is problematic: special helpers are
+ required for tracking them, and doing masquerading and other forms
+ of Network Address Translation on them.
+
+ This is FTP support on Layer 3 independent connection tracking.
+ Layer 3 independent connection tracking is experimental scheme
+ which generalize ip_conntrack to support other layer 3 protocols.
+
+ To compile it as a module, choose M here. If unsure, say N.
+
+endmenu
diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile
index b3b44f8b415a..55f019ad2c08 100644
--- a/net/netfilter/Makefile
+++ b/net/netfilter/Makefile
@@ -5,3 +5,11 @@ obj-$(CONFIG_NETFILTER) = netfilter.o
obj-$(CONFIG_NETFILTER_NETLINK) += nfnetlink.o
obj-$(CONFIG_NETFILTER_NETLINK_QUEUE) += nfnetlink_queue.o
obj-$(CONFIG_NETFILTER_NETLINK_LOG) += nfnetlink_log.o
+
+nf_conntrack-objs := nf_conntrack_core.o nf_conntrack_standalone.o nf_conntrack_l3proto_generic.o nf_conntrack_proto_generic.o nf_conntrack_proto_tcp.o nf_conntrack_proto_udp.o
+
+obj-$(CONFIG_NF_CONNTRACK) += nf_conntrack.o
+obj-$(CONFIG_NF_CONNTRACK_FTP) += nf_conntrack_ftp.o
+
+# SCTP protocol connection tracking
+obj-$(CONFIG_NF_CT_PROTO_SCTP) += nf_conntrack_proto_sctp.o
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
new file mode 100644
index 000000000000..9a67c796b385
--- /dev/null
+++ b/net/netfilter/nf_conntrack_core.c
@@ -0,0 +1,1538 @@
+/* Connection state tracking for netfilter. This is separated from,
+ but required by, the NAT layer; it can also be used by an iptables
+ extension. */
+
+/* (C) 1999-2001 Paul `Rusty' Russell
+ * (C) 2002-2005 Netfilter Core Team <coreteam@netfilter.org>
+ * (C) 2003,2004 USAGI/WIDE Project <http://www.linux-ipv6.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.
+ *
+ * 23 Apr 2001: Harald Welte <laforge@gnumonks.org>
+ * - new API and handling of conntrack/nat helpers
+ * - now capable of multiple expectations for one master
+ * 16 Jul 2002: Harald Welte <laforge@gnumonks.org>
+ * - add usage/reference counts to ip_conntrack_expect
+ * - export ip_conntrack[_expect]_{find_get,put} functions
+ * 16 Dec 2003: Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp>
+ * - generalize L3 protocol denendent part.
+ * 23 Mar 2004: Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp>
+ * - add support various size of conntrack structures.
+ *
+ * Derived from net/ipv4/netfilter/ip_conntrack_core.c
+ */
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/netfilter.h>
+#include <linux/module.h>
+#include <linux/skbuff.h>
+#include <linux/proc_fs.h>
+#include <linux/vmalloc.h>
+#include <linux/stddef.h>
+#include <linux/slab.h>
+#include <linux/random.h>
+#include <linux/jhash.h>
+#include <linux/err.h>
+#include <linux/percpu.h>
+#include <linux/moduleparam.h>
+#include <linux/notifier.h>
+#include <linux/kernel.h>
+#include <linux/netdevice.h>
+#include <linux/socket.h>
+
+/* This rwlock protects the main hash table, protocol/helper/expected
+ registrations, conntrack timers*/
+#define ASSERT_READ_LOCK(x)
+#define ASSERT_WRITE_LOCK(x)
+
+#include <net/netfilter/nf_conntrack.h>
+#include <net/netfilter/nf_conntrack_l3proto.h>
+#include <net/netfilter/nf_conntrack_protocol.h>
+#include <net/netfilter/nf_conntrack_helper.h>
+#include <net/netfilter/nf_conntrack_core.h>
+#include <linux/netfilter_ipv4/listhelp.h>
+
+#define NF_CONNTRACK_VERSION "0.4.1"
+
+#if 0
+#define DEBUGP printk
+#else
+#define DEBUGP(format, args...)
+#endif
+
+DEFINE_RWLOCK(nf_conntrack_lock);
+
+/* nf_conntrack_standalone needs this */
+atomic_t nf_conntrack_count = ATOMIC_INIT(0);
+
+void (*nf_conntrack_destroyed)(struct nf_conn *conntrack) = NULL;
+LIST_HEAD(nf_conntrack_expect_list);
+struct nf_conntrack_protocol **nf_ct_protos[PF_MAX];
+struct nf_conntrack_l3proto *nf_ct_l3protos[PF_MAX];
+static LIST_HEAD(helpers);
+unsigned int nf_conntrack_htable_size = 0;
+int nf_conntrack_max;
+struct list_head *nf_conntrack_hash;
+static kmem_cache_t *nf_conntrack_expect_cachep;
+struct nf_conn nf_conntrack_untracked;
+unsigned int nf_ct_log_invalid;
+static LIST_HEAD(unconfirmed);
+static int nf_conntrack_vmalloc;
+
+#ifdef CONFIG_NF_CONNTRACK_EVENTS
+struct notifier_block *nf_conntrack_chain;
+struct notifier_block *nf_conntrack_expect_chain;
+
+DEFINE_PER_CPU(struct nf_conntrack_ecache, nf_conntrack_ecache);
+
+/* deliver cached events and clear cache entry - must be called with locally
+ * disabled softirqs */
+static inline void
+__nf_ct_deliver_cached_events(struct nf_conntrack_ecache *ecache)
+{
+ DEBUGP("ecache: delivering events for %p\n", ecache->ct);
+ if (nf_ct_is_confirmed(ecache->ct) && !nf_ct_is_dying(ecache->ct)
+ && ecache->events)
+ notifier_call_chain(&nf_conntrack_chain, ecache->events,
+ ecache->ct);
+
+ ecache->events = 0;
+ nf_ct_put(ecache->ct);
+ ecache->ct = NULL;
+}
+
+/* Deliver all cached events for a particular conntrack. This is called
+ * by code prior to async packet handling for freeing the skb */
+void nf_ct_deliver_cached_events(const struct nf_conn *ct)
+{
+ struct nf_conntrack_ecache *ecache;
+
+ local_bh_disable();
+ ecache = &__get_cpu_var(nf_conntrack_ecache);
+ if (ecache->ct == ct)
+ __nf_ct_deliver_cached_events(ecache);
+ local_bh_enable();
+}
+
+/* Deliver cached events for old pending events, if current conntrack != old */
+void __nf_ct_event_cache_init(struct nf_conn *ct)
+{
+ struct nf_conntrack_ecache *ecache;
+
+ /* take care of delivering potentially old events */
+ ecache = &__get_cpu_var(nf_conntrack_ecache);
+ BUG_ON(ecache->ct == ct);
+ if (ecache->ct)
+ __nf_ct_deliver_cached_events(ecache);
+ /* initialize for this conntrack/packet */
+ ecache->ct = ct;
+ nf_conntrack_get(&ct->ct_general);
+}
+
+/* flush the event cache - touches other CPU's data and must not be called
+ * while packets are still passing through the code */
+static void nf_ct_event_cache_flush(void)
+{
+ struct nf_conntrack_ecache *ecache;
+ int cpu;
+
+ for_each_cpu(cpu) {
+ ecache = &per_cpu(nf_conntrack_ecache, cpu);
+ if (ecache->ct)
+ nf_ct_put(ecache->ct);
+ }
+}
+#else
+static inline void nf_ct_event_cache_flush(void) {}
+#endif /* CONFIG_NF_CONNTRACK_EVENTS */
+
+DEFINE_PER_CPU(struct ip_conntrack_stat, nf_conntrack_stat);
+EXPORT_PER_CPU_SYMBOL(nf_conntrack_stat);
+
+/*
+ * This scheme offers various size of "struct nf_conn" dependent on
+ * features(helper, nat, ...)
+ */
+
+#define NF_CT_FEATURES_NAMELEN 256
+static struct {
+ /* name of slab cache. printed in /proc/slabinfo */
+ char *name;
+
+ /* size of slab cache */
+ size_t size;
+
+ /* slab cache pointer */
+ kmem_cache_t *cachep;
+
+ /* allocated slab cache + modules which uses this slab cache */
+ int use;
+
+ /* Initialization */
+ int (*init_conntrack)(struct nf_conn *, u_int32_t);
+
+} nf_ct_cache[NF_CT_F_NUM];
+
+/* protect members of nf_ct_cache except of "use" */
+DEFINE_RWLOCK(nf_ct_cache_lock);
+
+/* This avoids calling kmem_cache_create() with same name simultaneously */
+DECLARE_MUTEX(nf_ct_cache_mutex);
+
+extern struct nf_conntrack_protocol nf_conntrack_generic_protocol;
+struct nf_conntrack_protocol *
+nf_ct_find_proto(u_int16_t l3proto, u_int8_t protocol)
+{
+ if (unlikely(nf_ct_protos[l3proto] == NULL))
+ return &nf_conntrack_generic_protocol;
+
+ return nf_ct_protos[l3proto][protocol];
+}
+
+static int nf_conntrack_hash_rnd_initted;
+static unsigned int nf_conntrack_hash_rnd;
+
+static u_int32_t __hash_conntrack(const struct nf_conntrack_tuple *tuple,
+ unsigned int size, unsigned int rnd)
+{
+ unsigned int a, b;
+ a = jhash((void *)tuple->src.u3.all, sizeof(tuple->src.u3.all),
+ ((tuple->src.l3num) << 16) | tuple->dst.protonum);
+ b = jhash((void *)tuple->dst.u3.all, sizeof(tuple->dst.u3.all),
+ (tuple->src.u.all << 16) | tuple->dst.u.all);
+
+ return jhash_2words(a, b, rnd) % size;
+}
+
+static inline u_int32_t hash_conntrack(const struct nf_conntrack_tuple *tuple)
+{
+ return __hash_conntrack(tuple, nf_conntrack_htable_size,
+ nf_conntrack_hash_rnd);
+}
+
+/* Initialize "struct nf_conn" which has spaces for helper */
+static int
+init_conntrack_for_helper(struct nf_conn *conntrack, u_int32_t features)
+{
+
+ conntrack->help = (union nf_conntrack_help *)
+ (((unsigned long)conntrack->data
+ + (__alignof__(union nf_conntrack_help) - 1))
+ & (~((unsigned long)(__alignof__(union nf_conntrack_help) -1))));
+ return 0;
+}
+
+int nf_conntrack_register_cache(u_int32_t features, const char *name,
+ size_t size,
+ int (*init)(struct nf_conn *, u_int32_t))
+{
+ int ret = 0;
+ char *cache_name;
+ kmem_cache_t *cachep;
+
+ DEBUGP("nf_conntrack_register_cache: features=0x%x, name=%s, size=%d\n",
+ features, name, size);
+
+ if (features < NF_CT_F_BASIC || features >= NF_CT_F_NUM) {
+ DEBUGP("nf_conntrack_register_cache: invalid features.: 0x%x\n",
+ features);
+ return -EINVAL;
+ }
+
+ down(&nf_ct_cache_mutex);
+
+ write_lock_bh(&nf_ct_cache_lock);
+ /* e.g: multiple helpers are loaded */
+ if (nf_ct_cache[features].use > 0) {
+ DEBUGP("nf_conntrack_register_cache: already resisterd.\n");
+ if ((!strncmp(nf_ct_cache[features].name, name,
+ NF_CT_FEATURES_NAMELEN))
+ && nf_ct_cache[features].size == size
+ && nf_ct_cache[features].init_conntrack == init) {
+ DEBUGP("nf_conntrack_register_cache: reusing.\n");
+ nf_ct_cache[features].use++;
+ ret = 0;
+ } else
+ ret = -EBUSY;
+
+ write_unlock_bh(&nf_ct_cache_lock);
+ up(&nf_ct_cache_mutex);
+ return ret;
+ }
+ write_unlock_bh(&nf_ct_cache_lock);
+
+ /*
+ * The memory space for name of slab cache must be alive until
+ * cache is destroyed.
+ */
+ cache_name = kmalloc(sizeof(char)*NF_CT_FEATURES_NAMELEN, GFP_ATOMIC);
+ if (cache_name == NULL) {
+ DEBUGP("nf_conntrack_register_cache: can't alloc cache_name\n");
+ ret = -ENOMEM;
+ goto out_up_mutex;
+ }
+
+ if (strlcpy(cache_name, name, NF_CT_FEATURES_NAMELEN)
+ >= NF_CT_FEATURES_NAMELEN) {
+ printk("nf_conntrack_register_cache: name too long\n");
+ ret = -EINVAL;
+ goto out_free_name;
+ }
+
+ cachep = kmem_cache_create(cache_name, size, 0, 0,
+ NULL, NULL);
+ if (!cachep) {
+ printk("nf_conntrack_register_cache: Can't create slab cache "
+ "for the features = 0x%x\n", features);
+ ret = -ENOMEM;
+ goto out_free_name;
+ }
+
+ write_lock_bh(&nf_ct_cache_lock);
+ nf_ct_cache[features].use = 1;
+ nf_ct_cache[features].size = size;
+ nf_ct_cache[features].init_conntrack = init;
+ nf_ct_cache[features].cachep = cachep;
+ nf_ct_cache[features].name = cache_name;
+ write_unlock_bh(&nf_ct_cache_lock);
+
+ goto out_up_mutex;
+
+out_free_name:
+ kfree(cache_name);
+out_up_mutex:
+ up(&nf_ct_cache_mutex);
+ return ret;
+}
+
+/* FIXME: In the current, only nf_conntrack_cleanup() can call this function. */
+void nf_conntrack_unregister_cache(u_int32_t features)
+{
+ kmem_cache_t *cachep;
+ char *name;
+
+ /*
+ * This assures that kmem_cache_create() isn't called before destroying
+ * slab cache.
+ */
+ DEBUGP("nf_conntrack_unregister_cache: 0x%04x\n", features);
+ down(&nf_ct_cache_mutex);
+
+ write_lock_bh(&nf_ct_cache_lock);
+ if (--nf_ct_cache[features].use > 0) {
+ write_unlock_bh(&nf_ct_cache_lock);
+ up(&nf_ct_cache_mutex);
+ return;
+ }
+ cachep = nf_ct_cache[features].cachep;
+ name = nf_ct_cache[features].name;
+ nf_ct_cache[features].cachep = NULL;
+ nf_ct_cache[features].name = NULL;
+ nf_ct_cache[features].init_conntrack = NULL;
+ nf_ct_cache[features].size = 0;
+ write_unlock_bh(&nf_ct_cache_lock);
+
+ synchronize_net();
+
+ kmem_cache_destroy(cachep);
+ kfree(name);
+
+ up(&nf_ct_cache_mutex);
+}
+
+int
+nf_ct_get_tuple(const struct sk_buff *skb,
+ unsigned int nhoff,
+ unsigned int dataoff,
+ u_int16_t l3num,
+ u_int8_t protonum,
+ struct nf_conntrack_tuple *tuple,
+ const struct nf_conntrack_l3proto *l3proto,
+ const struct nf_conntrack_protocol *protocol)
+{
+ NF_CT_TUPLE_U_BLANK(tuple);
+
+ tuple->src.l3num = l3num;
+ if (l3proto->pkt_to_tuple(skb, nhoff, tuple) == 0)
+ return 0;
+
+ tuple->dst.protonum = protonum;
+ tuple->dst.dir = IP_CT_DIR_ORIGINAL;
+
+ return protocol->pkt_to_tuple(skb, dataoff, tuple);
+}
+
+int
+nf_ct_invert_tuple(struct nf_conntrack_tuple *inverse,
+ const struct nf_conntrack_tuple *orig,
+ const struct nf_conntrack_l3proto *l3proto,
+ const struct nf_conntrack_protocol *protocol)
+{
+ NF_CT_TUPLE_U_BLANK(inverse);
+
+ inverse->src.l3num = orig->src.l3num;
+ if (l3proto->invert_tuple(inverse, orig) == 0)
+ return 0;
+
+ inverse->dst.dir = !orig->dst.dir;
+
+ inverse->dst.protonum = orig->dst.protonum;
+ return protocol->invert_tuple(inverse, orig);
+}
+
+/* nf_conntrack_expect helper functions */
+static void nf_ct_unlink_expect(struct nf_conntrack_expect *exp)
+{
+ ASSERT_WRITE_LOCK(&nf_conntrack_lock);
+ NF_CT_ASSERT(!timer_pending(&exp_timeout));
+ list_del(&exp->list);
+ NF_CT_STAT_INC(expect_delete);
+ exp->master->expecting--;
+ nf_conntrack_expect_put(exp);
+}
+
+static void expectation_timed_out(unsigned long ul_expect)
+{
+ struct nf_conntrack_expect *exp = (void *)ul_expect;
+
+ write_lock_bh(&nf_conntrack_lock);
+ nf_ct_unlink_expect(exp);
+ write_unlock_bh(&nf_conntrack_lock);
+ nf_conntrack_expect_put(exp);
+}
+
+/* If an expectation for this connection is found, it gets delete from
+ * global list then returned. */
+static struct nf_conntrack_expect *
+find_expectation(const struct nf_conntrack_tuple *tuple)
+{
+ struct nf_conntrack_expect *i;
+
+ list_for_each_entry(i, &nf_conntrack_expect_list, list) {
+ /* If master is not in hash table yet (ie. packet hasn't left
+ this machine yet), how can other end know about expected?
+ Hence these are not the droids you are looking for (if
+ master ct never got confirmed, we'd hold a reference to it
+ and weird things would happen to future packets). */
+ if (nf_ct_tuple_mask_cmp(tuple, &i->tuple, &i->mask)
+ && nf_ct_is_confirmed(i->master)) {
+ if (i->flags & NF_CT_EXPECT_PERMANENT) {
+ atomic_inc(&i->use);
+ return i;
+ } else if (del_timer(&i->timeout)) {
+ nf_ct_unlink_expect(i);
+ return i;
+ }
+ }
+ }
+ return NULL;
+}
+
+/* delete all expectations for this conntrack */
+static void remove_expectations(struct nf_conn *ct)
+{
+ struct nf_conntrack_expect *i, *tmp;
+
+ /* Optimization: most connection never expect any others. */
+ if (ct->expecting == 0)
+ return;
+
+ list_for_each_entry_safe(i, tmp, &nf_conntrack_expect_list, list) {
+ if (i->master == ct && del_timer(&i->timeout)) {
+ nf_ct_unlink_expect(i);
+ nf_conntrack_expect_put(i);
+ }
+ }
+}
+
+static void
+clean_from_lists(struct nf_conn *ct)
+{
+ unsigned int ho, hr;
+
+ DEBUGP("clean_from_lists(%p)\n", ct);
+ ASSERT_WRITE_LOCK(&nf_conntrack_lock);
+
+ ho = hash_conntrack(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple);
+ hr = hash_conntrack(&ct->tuplehash[IP_CT_DIR_REPLY].tuple);
+ LIST_DELETE(&nf_conntrack_hash[ho], &ct->tuplehash[IP_CT_DIR_ORIGINAL]);
+ LIST_DELETE(&nf_conntrack_hash[hr], &ct->tuplehash[IP_CT_DIR_REPLY]);
+
+ /* Destroy all pending expectations */
+ remove_expectations(ct);
+}
+
+static void
+destroy_conntrack(struct nf_conntrack *nfct)
+{
+ struct nf_conn *ct = (struct nf_conn *)nfct;
+ struct nf_conntrack_l3proto *l3proto;
+ struct nf_conntrack_protocol *proto;
+
+ DEBUGP("destroy_conntrack(%p)\n", ct);
+ NF_CT_ASSERT(atomic_read(&nfct->use) == 0);
+ NF_CT_ASSERT(!timer_pending(&ct->timeout));
+
+ nf_conntrack_event(IPCT_DESTROY, ct);
+ set_bit(IPS_DYING_BIT, &ct->status);
+
+ /* To make sure we don't get any weird locking issues here:
+ * destroy_conntrack() MUST NOT be called with a write lock
+ * to nf_conntrack_lock!!! -HW */
+ l3proto = nf_ct_find_l3proto(ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.l3num);
+ if (l3proto && l3proto->destroy)
+ l3proto->destroy(ct);
+
+ proto = nf_ct_find_proto(ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.l3num,
+ ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.protonum);
+ if (proto && proto->destroy)
+ proto->destroy(ct);
+
+ if (nf_conntrack_destroyed)
+ nf_conntrack_destroyed(ct);
+
+ write_lock_bh(&nf_conntrack_lock);
+ /* Expectations will have been removed in clean_from_lists,
+ * except TFTP can create an expectation on the first packet,
+ * before connection is in the list, so we need to clean here,
+ * too. */
+ remove_expectations(ct);
+
+ /* We overload first tuple to link into unconfirmed list. */
+ if (!nf_ct_is_confirmed(ct)) {
+ BUG_ON(list_empty(&ct->tuplehash[IP_CT_DIR_ORIGINAL].list));
+ list_del(&ct->tuplehash[IP_CT_DIR_ORIGINAL].list);
+ }
+
+ NF_CT_STAT_INC(delete);
+ write_unlock_bh(&nf_conntrack_lock);
+
+ if (ct->master)
+ nf_ct_put(ct->master);
+
+ DEBUGP("destroy_conntrack: returning ct=%p to slab\n", ct);
+ nf_conntrack_free(ct);
+}
+
+static void death_by_timeout(unsigned long ul_conntrack)
+{
+ struct nf_conn *ct = (void *)ul_conntrack;
+
+ write_lock_bh(&nf_conntrack_lock);
+ /* Inside lock so preempt is disabled on module removal path.
+ * Otherwise we can get spurious warnings. */
+ NF_CT_STAT_INC(delete_list);
+ clean_from_lists(ct);
+ write_unlock_bh(&nf_conntrack_lock);
+ nf_ct_put(ct);
+}
+
+static inline int
+conntrack_tuple_cmp(const struct nf_conntrack_tuple_hash *i,
+ const struct nf_conntrack_tuple *tuple,
+ const struct nf_conn *ignored_conntrack)
+{
+ ASSERT_READ_LOCK(&nf_conntrack_lock);
+ return nf_ct_tuplehash_to_ctrack(i) != ignored_conntrack
+ && nf_ct_tuple_equal(tuple, &i->tuple);
+}
+
+static struct nf_conntrack_tuple_hash *
+__nf_conntrack_find(const struct nf_conntrack_tuple *tuple,
+ const struct nf_conn *ignored_conntrack)
+{
+ struct nf_conntrack_tuple_hash *h;
+ unsigned int hash = hash_conntrack(tuple);
+
+ ASSERT_READ_LOCK(&nf_conntrack_lock);
+ list_for_each_entry(h, &nf_conntrack_hash[hash], list) {
+ if (conntrack_tuple_cmp(h, tuple, ignored_conntrack)) {
+ NF_CT_STAT_INC(found);
+ return h;
+ }
+ NF_CT_STAT_INC(searched);
+ }
+
+ return NULL;
+}
+
+/* Find a connection corresponding to a tuple. */
+struct nf_conntrack_tuple_hash *
+nf_conntrack_find_get(const struct nf_conntrack_tuple *tuple,
+ const struct nf_conn *ignored_conntrack)
+{
+ struct nf_conntrack_tuple_hash *h;
+
+ read_lock_bh(&nf_conntrack_lock);
+ h = __nf_conntrack_find(tuple, ignored_conntrack);
+ if (h)
+ atomic_inc(&nf_ct_tuplehash_to_ctrack(h)->ct_general.use);
+ read_unlock_bh(&nf_conntrack_lock);
+
+ return h;
+}
+
+/* Confirm a connection given skb; places it in hash table */
+int
+__nf_conntrack_confirm(struct sk_buff **pskb)
+{
+ unsigned int hash, repl_hash;
+ struct nf_conn *ct;
+ enum ip_conntrack_info ctinfo;
+
+ ct = nf_ct_get(*pskb, &ctinfo);
+
+ /* ipt_REJECT uses nf_conntrack_attach to attach related
+ ICMP/TCP RST packets in other direction. Actual packet
+ which created connection will be IP_CT_NEW or for an
+ expected connection, IP_CT_RELATED. */
+ if (CTINFO2DIR(ctinfo) != IP_CT_DIR_ORIGINAL)
+ return NF_ACCEPT;
+
+ hash = hash_conntrack(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple);
+ repl_hash = hash_conntrack(&ct->tuplehash[IP_CT_DIR_REPLY].tuple);
+
+ /* We're not in hash table, and we refuse to set up related
+ connections for unconfirmed conns. But packet copies and
+ REJECT will give spurious warnings here. */
+ /* NF_CT_ASSERT(atomic_read(&ct->ct_general.use) == 1); */
+
+ /* No external references means noone else could have
+ confirmed us. */
+ NF_CT_ASSERT(!nf_ct_is_confirmed(ct));
+ DEBUGP("Confirming conntrack %p\n", ct);
+
+ write_lock_bh(&nf_conntrack_lock);
+
+ /* See if there's one in the list already, including reverse:
+ NAT could have grabbed it without realizing, since we're
+ not in the hash. If there is, we lost race. */
+ if (!LIST_FIND(&nf_conntrack_hash[hash],
+ conntrack_tuple_cmp,
+ struct nf_conntrack_tuple_hash *,
+ &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple, NULL)
+ && !LIST_FIND(&nf_conntrack_hash[repl_hash],
+ conntrack_tuple_cmp,
+ struct nf_conntrack_tuple_hash *,
+ &ct->tuplehash[IP_CT_DIR_REPLY].tuple, NULL)) {
+ /* Remove from unconfirmed list */
+ list_del(&ct->tuplehash[IP_CT_DIR_ORIGINAL].list);
+
+ list_prepend(&nf_conntrack_hash[hash],
+ &ct->tuplehash[IP_CT_DIR_ORIGINAL]);
+ list_prepend(&nf_conntrack_hash[repl_hash],
+ &ct->tuplehash[IP_CT_DIR_REPLY]);
+ /* Timer relative to confirmation time, not original
+ setting time, otherwise we'd get timer wrap in
+ weird delay cases. */
+ ct->timeout.expires += jiffies;
+ add_timer(&ct->timeout);
+ atomic_inc(&ct->ct_general.use);
+ set_bit(IPS_CONFIRMED_BIT, &ct->status);
+ NF_CT_STAT_INC(insert);
+ write_unlock_bh(&nf_conntrack_lock);
+ if (ct->helper)
+ nf_conntrack_event_cache(IPCT_HELPER, *pskb);
+#ifdef CONFIG_NF_NAT_NEEDED
+ if (test_bit(IPS_SRC_NAT_DONE_BIT, &ct->status) ||
+ test_bit(IPS_DST_NAT_DONE_BIT, &ct->status))
+ nf_conntrack_event_cache(IPCT_NATINFO, *pskb);
+#endif
+ nf_conntrack_event_cache(master_ct(ct) ?
+ IPCT_RELATED : IPCT_NEW, *pskb);
+ return NF_ACCEPT;
+ }
+
+ NF_CT_STAT_INC(insert_failed);
+ write_unlock_bh(&nf_conntrack_lock);
+ return NF_DROP;
+}
+
+/* Returns true if a connection correspondings to the tuple (required
+ for NAT). */
+int
+nf_conntrack_tuple_taken(const struct nf_conntrack_tuple *tuple,
+ const struct nf_conn *ignored_conntrack)
+{
+ struct nf_conntrack_tuple_hash *h;
+
+ read_lock_bh(&nf_conntrack_lock);
+ h = __nf_conntrack_find(tuple, ignored_conntrack);
+ read_unlock_bh(&nf_conntrack_lock);
+
+ return h != NULL;
+}
+
+/* There's a small race here where we may free a just-assured
+ connection. Too bad: we're in trouble anyway. */
+static inline int unreplied(const struct nf_conntrack_tuple_hash *i)
+{
+ return !(test_bit(IPS_ASSURED_BIT,
+ &nf_ct_tuplehash_to_ctrack(i)->status));
+}
+
+static int early_drop(struct list_head *chain)
+{
+ /* Traverse backwards: gives us oldest, which is roughly LRU */
+ struct nf_conntrack_tuple_hash *h;
+ struct nf_conn *ct = NULL;
+ int dropped = 0;
+
+ read_lock_bh(&nf_conntrack_lock);
+ h = LIST_FIND_B(chain, unreplied, struct nf_conntrack_tuple_hash *);
+ if (h) {
+ ct = nf_ct_tuplehash_to_ctrack(h);
+ atomic_inc(&ct->ct_general.use);
+ }
+ read_unlock_bh(&nf_conntrack_lock);
+
+ if (!ct)
+ return dropped;
+
+ if (del_timer(&ct->timeout)) {
+ death_by_timeout((unsigned long)ct);
+ dropped = 1;
+ NF_CT_STAT_INC(early_drop);
+ }
+ nf_ct_put(ct);
+ return dropped;
+}
+
+static inline int helper_cmp(const struct nf_conntrack_helper *i,
+ const struct nf_conntrack_tuple *rtuple)
+{
+ return nf_ct_tuple_mask_cmp(rtuple, &i->tuple, &i->mask);
+}
+
+static struct nf_conntrack_helper *
+nf_ct_find_helper(const struct nf_conntrack_tuple *tuple)
+{
+ return LIST_FIND(&helpers, helper_cmp,
+ struct nf_conntrack_helper *,
+ tuple);
+}
+
+static struct nf_conn *
+__nf_conntrack_alloc(const struct nf_conntrack_tuple *orig,
+ const struct nf_conntrack_tuple *repl,
+ const struct nf_conntrack_l3proto *l3proto)
+{
+ struct nf_conn *conntrack = NULL;
+ u_int32_t features = 0;
+
+ if (!nf_conntrack_hash_rnd_initted) {
+ get_random_bytes(&nf_conntrack_hash_rnd, 4);
+ nf_conntrack_hash_rnd_initted = 1;
+ }
+
+ if (nf_conntrack_max
+ && atomic_read(&nf_conntrack_count) >= nf_conntrack_max) {
+ unsigned int hash = hash_conntrack(orig);
+ /* Try dropping from this hash chain. */
+ if (!early_drop(&nf_conntrack_hash[hash])) {
+ if (net_ratelimit())
+ printk(KERN_WARNING
+ "nf_conntrack: table full, dropping"
+ " packet.\n");
+ return ERR_PTR(-ENOMEM);
+ }
+ }
+
+ /* find features needed by this conntrack. */
+ features = l3proto->get_features(orig);
+ read_lock_bh(&nf_conntrack_lock);
+ if (nf_ct_find_helper(repl) != NULL)
+ features |= NF_CT_F_HELP;
+ read_unlock_bh(&nf_conntrack_lock);
+
+ DEBUGP("nf_conntrack_alloc: features=0x%x\n", features);
+
+ read_lock_bh(&nf_ct_cache_lock);
+
+ if (!nf_ct_cache[features].use) {
+ DEBUGP("nf_conntrack_alloc: not supported features = 0x%x\n",
+ features);
+ goto out;
+ }
+
+ conntrack = kmem_cache_alloc(nf_ct_cache[features].cachep, GFP_ATOMIC);
+ if (conntrack == NULL) {
+ DEBUGP("nf_conntrack_alloc: Can't alloc conntrack from cache\n");
+ goto out;
+ }
+
+ memset(conntrack, 0, nf_ct_cache[features].size);
+ conntrack->features = features;
+ if (nf_ct_cache[features].init_conntrack &&
+ nf_ct_cache[features].init_conntrack(conntrack, features) < 0) {
+ DEBUGP("nf_conntrack_alloc: failed to init\n");
+ kmem_cache_free(nf_ct_cache[features].cachep, conntrack);
+ conntrack = NULL;
+ goto out;
+ }
+
+ atomic_set(&conntrack->ct_general.use, 1);
+ conntrack->ct_general.destroy = destroy_conntrack;
+ conntrack->tuplehash[IP_CT_DIR_ORIGINAL].tuple = *orig;
+ conntrack->tuplehash[IP_CT_DIR_REPLY].tuple = *repl;
+ /* Don't set timer yet: wait for confirmation */
+ init_timer(&conntrack->timeout);
+ conntrack->timeout.data = (unsigned long)conntrack;
+ conntrack->timeout.function = death_by_timeout;
+
+ atomic_inc(&nf_conntrack_count);
+out:
+ read_unlock_bh(&nf_ct_cache_lock);
+ return conntrack;
+}
+
+struct nf_conn *nf_conntrack_alloc(const struct nf_conntrack_tuple *orig,
+ const struct nf_conntrack_tuple *repl)
+{
+ struct nf_conntrack_l3proto *l3proto;
+
+ l3proto = nf_ct_find_l3proto(orig->src.l3num);
+ return __nf_conntrack_alloc(orig, repl, l3proto);
+}
+
+void nf_conntrack_free(struct nf_conn *conntrack)
+{
+ u_int32_t features = conntrack->features;
+ NF_CT_ASSERT(features >= NF_CT_F_BASIC && features < NF_CT_F_NUM);
+ DEBUGP("nf_conntrack_free: features = 0x%x, conntrack=%p\n", features,
+ conntrack);
+ kmem_cache_free(nf_ct_cache[features].cachep, conntrack);
+ atomic_dec(&nf_conntrack_count);
+}
+
+/* Allocate a new conntrack: we return -ENOMEM if classification
+ failed due to stress. Otherwise it really is unclassifiable. */
+static struct nf_conntrack_tuple_hash *
+init_conntrack(const struct nf_conntrack_tuple *tuple,
+ struct nf_conntrack_l3proto *l3proto,
+ struct nf_conntrack_protocol *protocol,
+ struct sk_buff *skb,
+ unsigned int dataoff)
+{
+ struct nf_conn *conntrack;
+ struct nf_conntrack_tuple repl_tuple;
+ struct nf_conntrack_expect *exp;
+
+ if (!nf_ct_invert_tuple(&repl_tuple, tuple, l3proto, protocol)) {
+ DEBUGP("Can't invert tuple.\n");
+ return NULL;
+ }
+
+ conntrack = __nf_conntrack_alloc(tuple, &repl_tuple, l3proto);
+ if (conntrack == NULL || IS_ERR(conntrack)) {
+ DEBUGP("Can't allocate conntrack.\n");
+ return (struct nf_conntrack_tuple_hash *)conntrack;
+ }
+
+ if (!protocol->new(conntrack, skb, dataoff)) {
+ nf_conntrack_free(conntrack);
+ DEBUGP("init conntrack: can't track with proto module\n");
+ return NULL;
+ }
+
+ write_lock_bh(&nf_conntrack_lock);
+ exp = find_expectation(tuple);
+
+ if (exp) {
+ DEBUGP("conntrack: expectation arrives ct=%p exp=%p\n",
+ conntrack, exp);
+ /* Welcome, Mr. Bond. We've been expecting you... */
+ __set_bit(IPS_EXPECTED_BIT, &conntrack->status);
+ conntrack->master = exp->master;
+#ifdef CONFIG_NF_CONNTRACK_MARK
+ conntrack->mark = exp->master->mark;
+#endif
+ nf_conntrack_get(&conntrack->master->ct_general);
+ NF_CT_STAT_INC(expect_new);
+ } else {
+ conntrack->helper = nf_ct_find_helper(&repl_tuple);
+
+ NF_CT_STAT_INC(new);
+ }
+
+ /* Overload tuple linked list to put us in unconfirmed list. */
+ list_add(&conntrack->tuplehash[IP_CT_DIR_ORIGINAL].list, &unconfirmed);
+
+ write_unlock_bh(&nf_conntrack_lock);
+
+ if (exp) {
+ if (exp->expectfn)
+ exp->expectfn(conntrack, exp);
+ nf_conntrack_expect_put(exp);
+ }
+
+ return &conntrack->tuplehash[IP_CT_DIR_ORIGINAL];
+}
+
+/* On success, returns conntrack ptr, sets skb->nfct and ctinfo */
+static inline struct nf_conn *
+resolve_normal_ct(struct sk_buff *skb,
+ unsigned int dataoff,
+ u_int16_t l3num,
+ u_int8_t protonum,
+ struct nf_conntrack_l3proto *l3proto,
+ struct nf_conntrack_protocol *proto,
+ int *set_reply,
+ enum ip_conntrack_info *ctinfo)
+{
+ struct nf_conntrack_tuple tuple;
+ struct nf_conntrack_tuple_hash *h;
+ struct nf_conn *ct;
+
+ if (!nf_ct_get_tuple(skb, (unsigned int)(skb->nh.raw - skb->data),
+ dataoff, l3num, protonum, &tuple, l3proto,
+ proto)) {
+ DEBUGP("resolve_normal_ct: Can't get tuple\n");
+ return NULL;
+ }
+
+ /* look for tuple match */
+ h = nf_conntrack_find_get(&tuple, NULL);
+ if (!h) {
+ h = init_conntrack(&tuple, l3proto, proto, skb, dataoff);
+ if (!h)
+ return NULL;
+ if (IS_ERR(h))
+ return (void *)h;
+ }
+ ct = nf_ct_tuplehash_to_ctrack(h);
+
+ /* It exists; we have (non-exclusive) reference. */
+ if (NF_CT_DIRECTION(h) == IP_CT_DIR_REPLY) {
+ *ctinfo = IP_CT_ESTABLISHED + IP_CT_IS_REPLY;
+ /* Please set reply bit if this packet OK */
+ *set_reply = 1;
+ } else {
+ /* Once we've had two way comms, always ESTABLISHED. */
+ if (test_bit(IPS_SEEN_REPLY_BIT, &ct->status)) {
+ DEBUGP("nf_conntrack_in: normal packet for %p\n", ct);
+ *ctinfo = IP_CT_ESTABLISHED;
+ } else if (test_bit(IPS_EXPECTED_BIT, &ct->status)) {
+ DEBUGP("nf_conntrack_in: related packet for %p\n", ct);
+ *ctinfo = IP_CT_RELATED;
+ } else {
+ DEBUGP("nf_conntrack_in: new packet for %p\n", ct);
+ *ctinfo = IP_CT_NEW;
+ }
+ *set_reply = 0;
+ }
+ skb->nfct = &ct->ct_general;
+ skb->nfctinfo = *ctinfo;
+ return ct;
+}
+
+unsigned int
+nf_conntrack_in(int pf, unsigned int hooknum, struct sk_buff **pskb)
+{
+ struct nf_conn *ct;
+ enum ip_conntrack_info ctinfo;
+ struct nf_conntrack_l3proto *l3proto;
+ struct nf_conntrack_protocol *proto;
+ unsigned int dataoff;
+ u_int8_t protonum;
+ int set_reply = 0;
+ int ret;
+
+ /* Previously seen (loopback or untracked)? Ignore. */
+ if ((*pskb)->nfct) {
+ NF_CT_STAT_INC(ignore);
+ return NF_ACCEPT;
+ }
+
+ l3proto = nf_ct_find_l3proto((u_int16_t)pf);
+ if ((ret = l3proto->prepare(pskb, hooknum, &dataoff, &protonum)) <= 0) {
+ DEBUGP("not prepared to track yet or error occured\n");
+ return -ret;
+ }
+
+ proto = nf_ct_find_proto((u_int16_t)pf, protonum);
+
+ /* It may be an special packet, error, unclean...
+ * inverse of the return code tells to the netfilter
+ * core what to do with the packet. */
+ if (proto->error != NULL &&
+ (ret = proto->error(*pskb, dataoff, &ctinfo, pf, hooknum)) <= 0) {
+ NF_CT_STAT_INC(error);
+ NF_CT_STAT_INC(invalid);
+ return -ret;
+ }
+
+ ct = resolve_normal_ct(*pskb, dataoff, pf, protonum, l3proto, proto,
+ &set_reply, &ctinfo);
+ if (!ct) {
+ /* Not valid part of a connection */
+ NF_CT_STAT_INC(invalid);
+ return NF_ACCEPT;
+ }
+
+ if (IS_ERR(ct)) {
+ /* Too stressed to deal. */
+ NF_CT_STAT_INC(drop);
+ return NF_DROP;
+ }
+
+ NF_CT_ASSERT((*pskb)->nfct);
+
+ ret = proto->packet(ct, *pskb, dataoff, ctinfo, pf, hooknum);
+ if (ret < 0) {
+ /* Invalid: inverse of the return code tells
+ * the netfilter core what to do */
+ DEBUGP("nf_conntrack_in: Can't track with proto module\n");
+ nf_conntrack_put((*pskb)->nfct);
+ (*pskb)->nfct = NULL;
+ NF_CT_STAT_INC(invalid);
+ return -ret;
+ }
+
+ if (set_reply && !test_and_set_bit(IPS_SEEN_REPLY_BIT, &ct->status))
+ nf_conntrack_event_cache(IPCT_STATUS, *pskb);
+
+ return ret;
+}
+
+int nf_ct_invert_tuplepr(struct nf_conntrack_tuple *inverse,
+ const struct nf_conntrack_tuple *orig)
+{
+ return nf_ct_invert_tuple(inverse, orig,
+ nf_ct_find_l3proto(orig->src.l3num),
+ nf_ct_find_proto(orig->src.l3num,
+ orig->dst.protonum));
+}
+
+/* Would two expected things clash? */
+static inline int expect_clash(const struct nf_conntrack_expect *a,
+ const struct nf_conntrack_expect *b)
+{
+ /* Part covered by intersection of masks must be unequal,
+ otherwise they clash */
+ struct nf_conntrack_tuple intersect_mask;
+ int count;
+
+ intersect_mask.src.l3num = a->mask.src.l3num & b->mask.src.l3num;
+ intersect_mask.src.u.all = a->mask.src.u.all & b->mask.src.u.all;
+ intersect_mask.dst.u.all = a->mask.dst.u.all & b->mask.dst.u.all;
+ intersect_mask.dst.protonum = a->mask.dst.protonum
+ & b->mask.dst.protonum;
+
+ for (count = 0; count < NF_CT_TUPLE_L3SIZE; count++){
+ intersect_mask.src.u3.all[count] =
+ a->mask.src.u3.all[count] & b->mask.src.u3.all[count];
+ }
+
+ for (count = 0; count < NF_CT_TUPLE_L3SIZE; count++){
+ intersect_mask.dst.u3.all[count] =
+ a->mask.dst.u3.all[count] & b->mask.dst.u3.all[count];
+ }
+
+ return nf_ct_tuple_mask_cmp(&a->tuple, &b->tuple, &intersect_mask);
+}
+
+static inline int expect_matches(const struct nf_conntrack_expect *a,
+ const struct nf_conntrack_expect *b)
+{
+ return a->master == b->master
+ && nf_ct_tuple_equal(&a->tuple, &b->tuple)
+ && nf_ct_tuple_equal(&a->mask, &b->mask);
+}
+
+/* Generally a bad idea to call this: could have matched already. */
+void nf_conntrack_unexpect_related(struct nf_conntrack_expect *exp)
+{
+ struct nf_conntrack_expect *i;
+
+ write_lock_bh(&nf_conntrack_lock);
+ /* choose the the oldest expectation to evict */
+ list_for_each_entry_reverse(i, &nf_conntrack_expect_list, list) {
+ if (expect_matches(i, exp) && del_timer(&i->timeout)) {
+ nf_ct_unlink_expect(i);
+ write_unlock_bh(&nf_conntrack_lock);
+ nf_conntrack_expect_put(i);
+ return;
+ }
+ }
+ write_unlock_bh(&nf_conntrack_lock);
+}
+
+/* We don't increase the master conntrack refcount for non-fulfilled
+ * conntracks. During the conntrack destruction, the expectations are
+ * always killed before the conntrack itself */
+struct nf_conntrack_expect *nf_conntrack_expect_alloc(struct nf_conn *me)
+{
+ struct nf_conntrack_expect *new;
+
+ new = kmem_cache_alloc(nf_conntrack_expect_cachep, GFP_ATOMIC);
+ if (!new) {
+ DEBUGP("expect_related: OOM allocating expect\n");
+ return NULL;
+ }
+ new->master = me;
+ atomic_set(&new->use, 1);
+ return new;
+}
+
+void nf_conntrack_expect_put(struct nf_conntrack_expect *exp)
+{
+ if (atomic_dec_and_test(&exp->use))
+ kmem_cache_free(nf_conntrack_expect_cachep, exp);
+}
+
+static void nf_conntrack_expect_insert(struct nf_conntrack_expect *exp)
+{
+ atomic_inc(&exp->use);
+ exp->master->expecting++;
+ list_add(&exp->list, &nf_conntrack_expect_list);
+
+ init_timer(&exp->timeout);
+ exp->timeout.data = (unsigned long)exp;
+ exp->timeout.function = expectation_timed_out;
+ exp->timeout.expires = jiffies + exp->master->helper->timeout * HZ;
+ add_timer(&exp->timeout);
+
+ atomic_inc(&exp->use);
+ NF_CT_STAT_INC(expect_create);
+}
+
+/* Race with expectations being used means we could have none to find; OK. */
+static void evict_oldest_expect(struct nf_conn *master)
+{
+ struct nf_conntrack_expect *i;
+
+ list_for_each_entry_reverse(i, &nf_conntrack_expect_list, list) {
+ if (i->master == master) {
+ if (del_timer(&i->timeout)) {
+ nf_ct_unlink_expect(i);
+ nf_conntrack_expect_put(i);
+ }
+ break;
+ }
+ }
+}
+
+static inline int refresh_timer(struct nf_conntrack_expect *i)
+{
+ if (!del_timer(&i->timeout))
+ return 0;
+
+ i->timeout.expires = jiffies + i->master->helper->timeout*HZ;
+ add_timer(&i->timeout);
+ return 1;
+}
+
+int nf_conntrack_expect_related(struct nf_conntrack_expect *expect)
+{
+ struct nf_conntrack_expect *i;
+ int ret;
+
+ DEBUGP("nf_conntrack_expect_related %p\n", related_to);
+ DEBUGP("tuple: "); NF_CT_DUMP_TUPLE(&expect->tuple);
+ DEBUGP("mask: "); NF_CT_DUMP_TUPLE(&expect->mask);
+
+ write_lock_bh(&nf_conntrack_lock);
+ list_for_each_entry(i, &nf_conntrack_expect_list, list) {
+ if (expect_matches(i, expect)) {
+ /* Refresh timer: if it's dying, ignore.. */
+ if (refresh_timer(i)) {
+ ret = 0;
+ goto out;
+ }
+ } else if (expect_clash(i, expect)) {
+ ret = -EBUSY;
+ goto out;
+ }
+ }
+ /* Will be over limit? */
+ if (expect->master->helper->max_expected &&
+ expect->master->expecting >= expect->master->helper->max_expected)
+ evict_oldest_expect(expect->master);
+
+ nf_conntrack_expect_insert(expect);
+ nf_conntrack_expect_event(IPEXP_NEW, expect);
+ ret = 0;
+out:
+ write_unlock_bh(&nf_conntrack_lock);
+ return ret;
+}
+
+/* Alter reply tuple (maybe alter helper). This is for NAT, and is
+ implicitly racy: see __nf_conntrack_confirm */
+void nf_conntrack_alter_reply(struct nf_conn *conntrack,
+ const struct nf_conntrack_tuple *newreply)
+{
+ write_lock_bh(&nf_conntrack_lock);
+ /* Should be unconfirmed, so not in hash table yet */
+ NF_CT_ASSERT(!nf_ct_is_confirmed(conntrack));
+
+ DEBUGP("Altering reply tuple of %p to ", conntrack);
+ NF_CT_DUMP_TUPLE(newreply);
+
+ conntrack->tuplehash[IP_CT_DIR_REPLY].tuple = *newreply;
+ if (!conntrack->master && conntrack->expecting == 0)
+ conntrack->helper = nf_ct_find_helper(newreply);
+ write_unlock_bh(&nf_conntrack_lock);
+}
+
+int nf_conntrack_helper_register(struct nf_conntrack_helper *me)
+{
+ int ret;
+ BUG_ON(me->timeout == 0);
+
+ ret = nf_conntrack_register_cache(NF_CT_F_HELP, "nf_conntrack:help",
+ sizeof(struct nf_conn)
+ + sizeof(union nf_conntrack_help)
+ + __alignof__(union nf_conntrack_help),
+ init_conntrack_for_helper);
+ if (ret < 0) {
+ printk(KERN_ERR "nf_conntrack_helper_reigster: Unable to create slab cache for conntracks\n");
+ return ret;
+ }
+ write_lock_bh(&nf_conntrack_lock);
+ list_prepend(&helpers, me);
+ write_unlock_bh(&nf_conntrack_lock);
+
+ return 0;
+}
+
+static inline int unhelp(struct nf_conntrack_tuple_hash *i,
+ const struct nf_conntrack_helper *me)
+{
+ if (nf_ct_tuplehash_to_ctrack(i)->helper == me) {
+ nf_conntrack_event(IPCT_HELPER, nf_ct_tuplehash_to_ctrack(i));
+ nf_ct_tuplehash_to_ctrack(i)->helper = NULL;
+ }
+ return 0;
+}
+
+void nf_conntrack_helper_unregister(struct nf_conntrack_helper *me)
+{
+ unsigned int i;
+ struct nf_conntrack_expect *exp, *tmp;
+
+ /* Need write lock here, to delete helper. */
+ write_lock_bh(&nf_conntrack_lock);
+ LIST_DELETE(&helpers, me);
+
+ /* Get rid of expectations */
+ list_for_each_entry_safe(exp, tmp, &nf_conntrack_expect_list, list) {
+ if (exp->master->helper == me && del_timer(&exp->timeout)) {
+ nf_ct_unlink_expect(exp);
+ nf_conntrack_expect_put(exp);
+ }
+ }
+
+ /* Get rid of expecteds, set helpers to NULL. */
+ LIST_FIND_W(&unconfirmed, unhelp, struct nf_conntrack_tuple_hash*, me);
+ for (i = 0; i < nf_conntrack_htable_size; i++)
+ LIST_FIND_W(&nf_conntrack_hash[i], unhelp,
+ struct nf_conntrack_tuple_hash *, me);
+ write_unlock_bh(&nf_conntrack_lock);
+
+ /* Someone could be still looking at the helper in a bh. */
+ synchronize_net();
+}
+
+/* Refresh conntrack for this many jiffies and do accounting if do_acct is 1 */
+void __nf_ct_refresh_acct(struct nf_conn *ct,
+ enum ip_conntrack_info ctinfo,
+ const struct sk_buff *skb,
+ unsigned long extra_jiffies,
+ int do_acct)
+{
+ int event = 0;
+
+ NF_CT_ASSERT(ct->timeout.data == (unsigned long)ct);
+ NF_CT_ASSERT(skb);
+
+ write_lock_bh(&nf_conntrack_lock);
+
+ /* If not in hash table, timer will not be active yet */
+ if (!nf_ct_is_confirmed(ct)) {
+ ct->timeout.expires = extra_jiffies;
+ event = IPCT_REFRESH;
+ } else {
+ /* Need del_timer for race avoidance (may already be dying). */
+ if (del_timer(&ct->timeout)) {
+ ct->timeout.expires = jiffies + extra_jiffies;
+ add_timer(&ct->timeout);
+ event = IPCT_REFRESH;
+ }
+ }
+
+#ifdef CONFIG_NF_CT_ACCT
+ if (do_acct) {
+ ct->counters[CTINFO2DIR(ctinfo)].packets++;
+ ct->counters[CTINFO2DIR(ctinfo)].bytes +=
+ skb->len - (unsigned int)(skb->nh.raw - skb->data);
+ if ((ct->counters[CTINFO2DIR(ctinfo)].packets & 0x80000000)
+ || (ct->counters[CTINFO2DIR(ctinfo)].bytes & 0x80000000))
+ event |= IPCT_COUNTER_FILLING;
+ }
+#endif
+
+ write_unlock_bh(&nf_conntrack_lock);
+
+ /* must be unlocked when calling event cache */
+ if (event)
+ nf_conntrack_event_cache(event, skb);
+}
+
+/* Used by ipt_REJECT and ip6t_REJECT. */
+void __nf_conntrack_attach(struct sk_buff *nskb, struct sk_buff *skb)
+{
+ struct nf_conn *ct;
+ enum ip_conntrack_info ctinfo;
+
+ /* This ICMP is in reverse direction to the packet which caused it */
+ ct = nf_ct_get(skb, &ctinfo);
+ if (CTINFO2DIR(ctinfo) == IP_CT_DIR_ORIGINAL)
+ ctinfo = IP_CT_RELATED + IP_CT_IS_REPLY;
+ else
+ ctinfo = IP_CT_RELATED;
+
+ /* Attach to new skbuff, and increment count */
+ nskb->nfct = &ct->ct_general;
+ nskb->nfctinfo = ctinfo;
+ nf_conntrack_get(nskb->nfct);
+}
+
+static inline int
+do_iter(const struct nf_conntrack_tuple_hash *i,
+ int (*iter)(struct nf_conn *i, void *data),
+ void *data)
+{
+ return iter(nf_ct_tuplehash_to_ctrack(i), data);
+}
+
+/* Bring out ya dead! */
+static struct nf_conntrack_tuple_hash *
+get_next_corpse(int (*iter)(struct nf_conn *i, void *data),
+ void *data, unsigned int *bucket)
+{
+ struct nf_conntrack_tuple_hash *h = NULL;
+
+ write_lock_bh(&nf_conntrack_lock);
+ for (; *bucket < nf_conntrack_htable_size; (*bucket)++) {
+ h = LIST_FIND_W(&nf_conntrack_hash[*bucket], do_iter,
+ struct nf_conntrack_tuple_hash *, iter, data);
+ if (h)
+ break;
+ }
+ if (!h)
+ h = LIST_FIND_W(&unconfirmed, do_iter,
+ struct nf_conntrack_tuple_hash *, iter, data);
+ if (h)
+ atomic_inc(&nf_ct_tuplehash_to_ctrack(h)->ct_general.use);
+ write_unlock_bh(&nf_conntrack_lock);
+
+ return h;
+}
+
+void
+nf_ct_iterate_cleanup(int (*iter)(struct nf_conn *i, void *data), void *data)
+{
+ struct nf_conntrack_tuple_hash *h;
+ unsigned int bucket = 0;
+
+ while ((h = get_next_corpse(iter, data, &bucket)) != NULL) {
+ struct nf_conn *ct = nf_ct_tuplehash_to_ctrack(h);
+ /* Time to push up daises... */
+ if (del_timer(&ct->timeout))
+ death_by_timeout((unsigned long)ct);
+ /* ... else the timer will get him soon. */
+
+ nf_ct_put(ct);
+ }
+}
+
+static int kill_all(struct nf_conn *i, void *data)
+{
+ return 1;
+}
+
+static void free_conntrack_hash(struct list_head *hash, int vmalloced, int size)
+{
+ if (vmalloced)
+ vfree(hash);
+ else
+ free_pages((unsigned long)hash,
+ get_order(sizeof(struct list_head) * size));
+}
+
+/* Mishearing the voices in his head, our hero wonders how he's
+ supposed to kill the mall. */
+void nf_conntrack_cleanup(void)
+{
+ int i;
+
+ /* This makes sure all current packets have passed through
+ netfilter framework. Roll on, two-stage module
+ delete... */
+ synchronize_net();
+
+ nf_ct_event_cache_flush();
+ i_see_dead_people:
+ nf_ct_iterate_cleanup(kill_all, NULL);
+ if (atomic_read(&nf_conntrack_count) != 0) {
+ schedule();
+ goto i_see_dead_people;
+ }
+
+ for (i = 0; i < NF_CT_F_NUM; i++) {
+ if (nf_ct_cache[i].use == 0)
+ continue;
+
+ NF_CT_ASSERT(nf_ct_cache[i].use == 1);
+ nf_ct_cache[i].use = 1;
+ nf_conntrack_unregister_cache(i);
+ }
+ kmem_cache_destroy(nf_conntrack_expect_cachep);
+ free_conntrack_hash(nf_conntrack_hash, nf_conntrack_vmalloc,
+ nf_conntrack_htable_size);
+}
+
+static struct list_head *alloc_hashtable(int size, int *vmalloced)
+{
+ struct list_head *hash;
+ unsigned int i;
+
+ *vmalloced = 0;
+ hash = (void*)__get_free_pages(GFP_KERNEL,
+ get_order(sizeof(struct list_head)
+ * size));
+ if (!hash) {
+ *vmalloced = 1;
+ printk(KERN_WARNING "nf_conntrack: falling back to vmalloc.\n");
+ hash = vmalloc(sizeof(struct list_head) * size);
+ }
+
+ if (hash)
+ for (i = 0; i < size; i++)
+ INIT_LIST_HEAD(&hash[i]);
+
+ return hash;
+}
+
+int set_hashsize(const char *val, struct kernel_param *kp)
+{
+ int i, bucket, hashsize, vmalloced;
+ int old_vmalloced, old_size;
+ int rnd;
+ struct list_head *hash, *old_hash;
+ struct nf_conntrack_tuple_hash *h;
+
+ /* On boot, we can set this without any fancy locking. */
+ if (!nf_conntrack_htable_size)
+ return param_set_uint(val, kp);
+
+ hashsize = simple_strtol(val, NULL, 0);
+ if (!hashsize)
+ return -EINVAL;
+
+ hash = alloc_hashtable(hashsize, &vmalloced);
+ if (!hash)
+ return -ENOMEM;
+
+ /* We have to rehahs for the new table anyway, so we also can
+ * use a newrandom seed */
+ get_random_bytes(&rnd, 4);
+
+ write_lock_bh(&nf_conntrack_lock);
+ for (i = 0; i < nf_conntrack_htable_size; i++) {
+ while (!list_empty(&nf_conntrack_hash[i])) {
+ h = list_entry(nf_conntrack_hash[i].next,
+ struct nf_conntrack_tuple_hash, list);
+ list_del(&h->list);
+ bucket = __hash_conntrack(&h->tuple, hashsize, rnd);
+ list_add_tail(&h->list, &hash[bucket]);
+ }
+ }
+ old_size = nf_conntrack_htable_size;
+ old_vmalloced = nf_conntrack_vmalloc;
+ old_hash = nf_conntrack_hash;
+
+ nf_conntrack_htable_size = hashsize;
+ nf_conntrack_vmalloc = vmalloced;
+ nf_conntrack_hash = hash;
+ nf_conntrack_hash_rnd = rnd;
+ write_unlock_bh(&nf_conntrack_lock);
+
+ free_conntrack_hash(old_hash, old_vmalloced, old_size);
+ return 0;
+}
+
+module_param_call(hashsize, set_hashsize, param_get_uint,
+ &nf_conntrack_htable_size, 0600);
+
+int __init nf_conntrack_init(void)
+{
+ unsigned int i;
+ int ret;
+
+ /* Idea from tcp.c: use 1/16384 of memory. On i386: 32MB
+ * machine has 256 buckets. >= 1GB machines have 8192 buckets. */
+ if (!nf_conntrack_htable_size) {
+ nf_conntrack_htable_size
+ = (((num_physpages << PAGE_SHIFT) / 16384)
+ / sizeof(struct list_head));
+ if (num_physpages > (1024 * 1024 * 1024 / PAGE_SIZE))
+ nf_conntrack_htable_size = 8192;
+ if (nf_conntrack_htable_size < 16)
+ nf_conntrack_htable_size = 16;
+ }
+ nf_conntrack_max = 8 * nf_conntrack_htable_size;
+
+ printk("nf_conntrack version %s (%u buckets, %d max)\n",
+ NF_CONNTRACK_VERSION, nf_conntrack_htable_size,
+ nf_conntrack_max);
+
+ nf_conntrack_hash = alloc_hashtable(nf_conntrack_htable_size,
+ &nf_conntrack_vmalloc);
+ if (!nf_conntrack_hash) {
+ printk(KERN_ERR "Unable to create nf_conntrack_hash\n");
+ goto err_out;
+ }
+
+ ret = nf_conntrack_register_cache(NF_CT_F_BASIC, "nf_conntrack:basic",
+ sizeof(struct nf_conn), NULL);
+ if (ret < 0) {
+ printk(KERN_ERR "Unable to create nf_conn slab cache\n");
+ goto err_free_hash;
+ }
+
+ nf_conntrack_expect_cachep = kmem_cache_create("nf_conntrack_expect",
+ sizeof(struct nf_conntrack_expect),
+ 0, 0, NULL, NULL);
+ if (!nf_conntrack_expect_cachep) {
+ printk(KERN_ERR "Unable to create nf_expect slab cache\n");
+ goto err_free_conntrack_slab;
+ }
+
+ /* Don't NEED lock here, but good form anyway. */
+ write_lock_bh(&nf_conntrack_lock);
+ for (i = 0; i < PF_MAX; i++)
+ nf_ct_l3protos[i] = &nf_conntrack_generic_l3proto;
+ write_unlock_bh(&nf_conntrack_lock);
+
+ /* Set up fake conntrack:
+ - to never be deleted, not in any hashes */
+ atomic_set(&nf_conntrack_untracked.ct_general.use, 1);
+ /* - and look it like as a confirmed connection */
+ set_bit(IPS_CONFIRMED_BIT, &nf_conntrack_untracked.status);
+
+ return ret;
+
+err_free_conntrack_slab:
+ nf_conntrack_unregister_cache(NF_CT_F_BASIC);
+err_free_hash:
+ free_conntrack_hash(nf_conntrack_hash, nf_conntrack_vmalloc,
+ nf_conntrack_htable_size);
+err_out:
+ return -ENOMEM;
+}
diff --git a/net/netfilter/nf_conntrack_ftp.c b/net/netfilter/nf_conntrack_ftp.c
new file mode 100644
index 000000000000..65080e269f27
--- /dev/null
+++ b/net/netfilter/nf_conntrack_ftp.c
@@ -0,0 +1,698 @@
+/* FTP extension for connection tracking. */
+
+/* (C) 1999-2001 Paul `Rusty' Russell
+ * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
+ * (C) 2003,2004 USAGI/WIDE Project <http://www.linux-ipv6.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.
+ *
+ * 16 Dec 2003: Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp>
+ * - enable working with Layer 3 protocol independent connection tracking.
+ * - track EPRT and EPSV commands with IPv6 address.
+ *
+ * Derived from net/ipv4/netfilter/ip_conntrack_ftp.c
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/netfilter.h>
+#include <linux/ip.h>
+#include <linux/ipv6.h>
+#include <linux/ctype.h>
+#include <net/checksum.h>
+#include <net/tcp.h>
+
+#include <net/netfilter/nf_conntrack.h>
+#include <net/netfilter/nf_conntrack_helper.h>
+#include <linux/netfilter/nf_conntrack_ftp.h>
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Rusty Russell <rusty@rustcorp.com.au>");
+MODULE_DESCRIPTION("ftp connection tracking helper");
+
+/* This is slow, but it's simple. --RR */
+static char *ftp_buffer;
+
+static DEFINE_SPINLOCK(nf_ftp_lock);
+
+#define MAX_PORTS 8
+static u_int16_t ports[MAX_PORTS];
+static unsigned int ports_c;
+module_param_array(ports, ushort, &ports_c, 0400);
+
+static int loose;
+module_param(loose, int, 0600);
+
+unsigned int (*nf_nat_ftp_hook)(struct sk_buff **pskb,
+ enum ip_conntrack_info ctinfo,
+ enum ip_ct_ftp_type type,
+ unsigned int matchoff,
+ unsigned int matchlen,
+ struct nf_conntrack_expect *exp,
+ u32 *seq);
+EXPORT_SYMBOL_GPL(nf_nat_ftp_hook);
+
+#if 0
+#define DEBUGP printk
+#else
+#define DEBUGP(format, args...)
+#endif
+
+static int try_rfc959(const char *, size_t, struct nf_conntrack_man *, char);
+static int try_eprt(const char *, size_t, struct nf_conntrack_man *, char);
+static int try_epsv_response(const char *, size_t, struct nf_conntrack_man *,
+ char);
+
+static struct ftp_search {
+ enum ip_conntrack_dir dir;
+ const char *pattern;
+ size_t plen;
+ char skip;
+ char term;
+ enum ip_ct_ftp_type ftptype;
+ int (*getnum)(const char *, size_t, struct nf_conntrack_man *, char);
+} search[] = {
+ {
+ IP_CT_DIR_ORIGINAL,
+ "PORT", sizeof("PORT") - 1, ' ', '\r',
+ IP_CT_FTP_PORT,
+ try_rfc959,
+ },
+ {
+ IP_CT_DIR_REPLY,
+ "227 ", sizeof("227 ") - 1, '(', ')',
+ IP_CT_FTP_PASV,
+ try_rfc959,
+ },
+ {
+ IP_CT_DIR_ORIGINAL,
+ "EPRT", sizeof("EPRT") - 1, ' ', '\r',
+ IP_CT_FTP_EPRT,
+ try_eprt,
+ },
+ {
+ IP_CT_DIR_REPLY,
+ "229 ", sizeof("229 ") - 1, '(', ')',
+ IP_CT_FTP_EPSV,
+ try_epsv_response,
+ },
+};
+
+/* This code is based on inet_pton() in glibc-2.2.4 */
+static int
+get_ipv6_addr(const char *src, size_t dlen, struct in6_addr *dst, u_int8_t term)
+{
+ static const char xdigits[] = "0123456789abcdef";
+ u_int8_t tmp[16], *tp, *endp, *colonp;
+ int ch, saw_xdigit;
+ u_int32_t val;
+ size_t clen = 0;
+
+ tp = memset(tmp, '\0', sizeof(tmp));
+ endp = tp + sizeof(tmp);
+ colonp = NULL;
+
+ /* Leading :: requires some special handling. */
+ if (*src == ':'){
+ if (*++src != ':') {
+ DEBUGP("invalid \":\" at the head of addr\n");
+ return 0;
+ }
+ clen++;
+ }
+
+ saw_xdigit = 0;
+ val = 0;
+ while ((clen < dlen) && (*src != term)) {
+ const char *pch;
+
+ ch = tolower(*src++);
+ clen++;
+
+ pch = strchr(xdigits, ch);
+ if (pch != NULL) {
+ val <<= 4;
+ val |= (pch - xdigits);
+ if (val > 0xffff)
+ return 0;
+
+ saw_xdigit = 1;
+ continue;
+ }
+ if (ch != ':') {
+ DEBUGP("get_ipv6_addr: invalid char. \'%c\'\n", ch);
+ return 0;
+ }
+
+ if (!saw_xdigit) {
+ if (colonp) {
+ DEBUGP("invalid location of \"::\".\n");
+ return 0;
+ }
+ colonp = tp;
+ continue;
+ } else if (*src == term) {
+ DEBUGP("trancated IPv6 addr\n");
+ return 0;
+ }
+
+ if (tp + 2 > endp)
+ return 0;
+ *tp++ = (u_int8_t) (val >> 8) & 0xff;
+ *tp++ = (u_int8_t) val & 0xff;
+
+ saw_xdigit = 0;
+ val = 0;
+ continue;
+ }
+ if (saw_xdigit) {
+ if (tp + 2 > endp)
+ return 0;
+ *tp++ = (u_int8_t) (val >> 8) & 0xff;
+ *tp++ = (u_int8_t) val & 0xff;
+ }
+ if (colonp != NULL) {
+ /*
+ * Since some memmove()'s erroneously fail to handle
+ * overlapping regions, we'll do the shift by hand.
+ */
+ const int n = tp - colonp;
+ int i;
+
+ if (tp == endp)
+ return 0;
+
+ for (i = 1; i <= n; i++) {
+ endp[- i] = colonp[n - i];
+ colonp[n - i] = 0;
+ }
+ tp = endp;
+ }
+ if (tp != endp || (*src != term))
+ return 0;
+
+ memcpy(dst->s6_addr, tmp, sizeof(dst->s6_addr));
+ return clen;
+}
+
+static int try_number(const char *data, size_t dlen, u_int32_t array[],
+ int array_size, char sep, char term)
+{
+ u_int32_t i, len;
+
+ memset(array, 0, sizeof(array[0])*array_size);
+
+ /* Keep data pointing at next char. */
+ for (i = 0, len = 0; len < dlen && i < array_size; len++, data++) {
+ if (*data >= '0' && *data <= '9') {
+ array[i] = array[i]*10 + *data - '0';
+ }
+ else if (*data == sep)
+ i++;
+ else {
+ /* Unexpected character; true if it's the
+ terminator and we're finished. */
+ if (*data == term && i == array_size - 1)
+ return len;
+
+ DEBUGP("Char %u (got %u nums) `%u' unexpected\n",
+ len, i, *data);
+ return 0;
+ }
+ }
+ DEBUGP("Failed to fill %u numbers separated by %c\n", array_size, sep);
+
+ return 0;
+}
+
+/* Returns 0, or length of numbers: 192,168,1,1,5,6 */
+static int try_rfc959(const char *data, size_t dlen,
+ struct nf_conntrack_man *cmd, char term)
+{
+ int length;
+ u_int32_t array[6];
+
+ length = try_number(data, dlen, array, 6, ',', term);
+ if (length == 0)
+ return 0;
+
+ cmd->u3.ip = htonl((array[0] << 24) | (array[1] << 16) |
+ (array[2] << 8) | array[3]);
+ cmd->u.tcp.port = htons((array[4] << 8) | array[5]);
+ return length;
+}
+
+/* Grab port: number up to delimiter */
+static int get_port(const char *data, int start, size_t dlen, char delim,
+ u_int16_t *port)
+{
+ u_int16_t tmp_port = 0;
+ int i;
+
+ for (i = start; i < dlen; i++) {
+ /* Finished? */
+ if (data[i] == delim) {
+ if (tmp_port == 0)
+ break;
+ *port = htons(tmp_port);
+ DEBUGP("get_port: return %d\n", tmp_port);
+ return i + 1;
+ }
+ else if (data[i] >= '0' && data[i] <= '9')
+ tmp_port = tmp_port*10 + data[i] - '0';
+ else { /* Some other crap */
+ DEBUGP("get_port: invalid char.\n");
+ break;
+ }
+ }
+ return 0;
+}
+
+/* Returns 0, or length of numbers: |1|132.235.1.2|6275| or |2|3ffe::1|6275| */
+static int try_eprt(const char *data, size_t dlen, struct nf_conntrack_man *cmd,
+ char term)
+{
+ char delim;
+ int length;
+
+ /* First character is delimiter, then "1" for IPv4 or "2" for IPv6,
+ then delimiter again. */
+ if (dlen <= 3) {
+ DEBUGP("EPRT: too short\n");
+ return 0;
+ }
+ delim = data[0];
+ if (isdigit(delim) || delim < 33 || delim > 126 || data[2] != delim) {
+ DEBUGP("try_eprt: invalid delimitter.\n");
+ return 0;
+ }
+
+ if ((cmd->l3num == PF_INET && data[1] != '1') ||
+ (cmd->l3num == PF_INET6 && data[1] != '2')) {
+ DEBUGP("EPRT: invalid protocol number.\n");
+ return 0;
+ }
+
+ DEBUGP("EPRT: Got %c%c%c\n", delim, data[1], delim);
+
+ if (data[1] == '1') {
+ u_int32_t array[4];
+
+ /* Now we have IP address. */
+ length = try_number(data + 3, dlen - 3, array, 4, '.', delim);
+ if (length != 0)
+ cmd->u3.ip = htonl((array[0] << 24) | (array[1] << 16)
+ | (array[2] << 8) | array[3]);
+ } else {
+ /* Now we have IPv6 address. */
+ length = get_ipv6_addr(data + 3, dlen - 3,
+ (struct in6_addr *)cmd->u3.ip6, delim);
+ }
+
+ if (length == 0)
+ return 0;
+ DEBUGP("EPRT: Got IP address!\n");
+ /* Start offset includes initial "|1|", and trailing delimiter */
+ return get_port(data, 3 + length + 1, dlen, delim, &cmd->u.tcp.port);
+}
+
+/* Returns 0, or length of numbers: |||6446| */
+static int try_epsv_response(const char *data, size_t dlen,
+ struct nf_conntrack_man *cmd, char term)
+{
+ char delim;
+
+ /* Three delimiters. */
+ if (dlen <= 3) return 0;
+ delim = data[0];
+ if (isdigit(delim) || delim < 33 || delim > 126
+ || data[1] != delim || data[2] != delim)
+ return 0;
+
+ return get_port(data, 3, dlen, delim, &cmd->u.tcp.port);
+}
+
+/* Return 1 for match, 0 for accept, -1 for partial. */
+static int find_pattern(const char *data, size_t dlen,
+ const char *pattern, size_t plen,
+ char skip, char term,
+ unsigned int *numoff,
+ unsigned int *numlen,
+ struct nf_conntrack_man *cmd,
+ int (*getnum)(const char *, size_t,
+ struct nf_conntrack_man *, char))
+{
+ size_t i;
+
+ DEBUGP("find_pattern `%s': dlen = %u\n", pattern, dlen);
+ if (dlen == 0)
+ return 0;
+
+ if (dlen <= plen) {
+ /* Short packet: try for partial? */
+ if (strnicmp(data, pattern, dlen) == 0)
+ return -1;
+ else return 0;
+ }
+
+ if (strnicmp(data, pattern, plen) != 0) {
+#if 0
+ size_t i;
+
+ DEBUGP("ftp: string mismatch\n");
+ for (i = 0; i < plen; i++) {
+ DEBUGP("ftp:char %u `%c'(%u) vs `%c'(%u)\n",
+ i, data[i], data[i],
+ pattern[i], pattern[i]);
+ }
+#endif
+ return 0;
+ }
+
+ DEBUGP("Pattern matches!\n");
+ /* Now we've found the constant string, try to skip
+ to the 'skip' character */
+ for (i = plen; data[i] != skip; i++)
+ if (i == dlen - 1) return -1;
+
+ /* Skip over the last character */
+ i++;
+
+ DEBUGP("Skipped up to `%c'!\n", skip);
+
+ *numoff = i;
+ *numlen = getnum(data + i, dlen - i, cmd, term);
+ if (!*numlen)
+ return -1;
+
+ DEBUGP("Match succeeded!\n");
+ return 1;
+}
+
+/* Look up to see if we're just after a \n. */
+static int find_nl_seq(u32 seq, const struct ip_ct_ftp_master *info, int dir)
+{
+ unsigned int i;
+
+ for (i = 0; i < info->seq_aft_nl_num[dir]; i++)
+ if (info->seq_aft_nl[dir][i] == seq)
+ return 1;
+ return 0;
+}
+
+/* We don't update if it's older than what we have. */
+static void update_nl_seq(u32 nl_seq, struct ip_ct_ftp_master *info, int dir,
+ struct sk_buff *skb)
+{
+ unsigned int i, oldest = NUM_SEQ_TO_REMEMBER;
+
+ /* Look for oldest: if we find exact match, we're done. */
+ for (i = 0; i < info->seq_aft_nl_num[dir]; i++) {
+ if (info->seq_aft_nl[dir][i] == nl_seq)
+ return;
+
+ if (oldest == info->seq_aft_nl_num[dir]
+ || before(info->seq_aft_nl[dir][i], oldest))
+ oldest = i;
+ }
+
+ if (info->seq_aft_nl_num[dir] < NUM_SEQ_TO_REMEMBER) {
+ info->seq_aft_nl[dir][info->seq_aft_nl_num[dir]++] = nl_seq;
+ nf_conntrack_event_cache(IPCT_HELPINFO_VOLATILE, skb);
+ } else if (oldest != NUM_SEQ_TO_REMEMBER) {
+ info->seq_aft_nl[dir][oldest] = nl_seq;
+ nf_conntrack_event_cache(IPCT_HELPINFO_VOLATILE, skb);
+ }
+}
+
+static int help(struct sk_buff **pskb,
+ unsigned int protoff,
+ struct nf_conn *ct,
+ enum ip_conntrack_info ctinfo)
+{
+ unsigned int dataoff, datalen;
+ struct tcphdr _tcph, *th;
+ char *fb_ptr;
+ int ret;
+ u32 seq;
+ int dir = CTINFO2DIR(ctinfo);
+ unsigned int matchlen, matchoff;
+ struct ip_ct_ftp_master *ct_ftp_info = &ct->help->ct_ftp_info;
+ struct nf_conntrack_expect *exp;
+ struct nf_conntrack_man cmd = {};
+
+ unsigned int i;
+ int found = 0, ends_in_nl;
+
+ /* Until there's been traffic both ways, don't look in packets. */
+ if (ctinfo != IP_CT_ESTABLISHED
+ && ctinfo != IP_CT_ESTABLISHED+IP_CT_IS_REPLY) {
+ DEBUGP("ftp: Conntrackinfo = %u\n", ctinfo);
+ return NF_ACCEPT;
+ }
+
+ th = skb_header_pointer(*pskb, protoff, sizeof(_tcph), &_tcph);
+ if (th == NULL)
+ return NF_ACCEPT;
+
+ dataoff = protoff + th->doff * 4;
+ /* No data? */
+ if (dataoff >= (*pskb)->len) {
+ DEBUGP("ftp: dataoff(%u) >= skblen(%u)\n", dataoff,
+ (*pskb)->len);
+ return NF_ACCEPT;
+ }
+ datalen = (*pskb)->len - dataoff;
+
+ spin_lock_bh(&nf_ftp_lock);
+ fb_ptr = skb_header_pointer(*pskb, dataoff, datalen, ftp_buffer);
+ BUG_ON(fb_ptr == NULL);
+
+ ends_in_nl = (fb_ptr[datalen - 1] == '\n');
+ seq = ntohl(th->seq) + datalen;
+
+ /* Look up to see if we're just after a \n. */
+ if (!find_nl_seq(ntohl(th->seq), ct_ftp_info, dir)) {
+ /* Now if this ends in \n, update ftp info. */
+ DEBUGP("nf_conntrack_ftp_help: wrong seq pos %s(%u) or %s(%u)\n",
+ ct_ftp_info->seq_aft_nl_num[dir] > 0 ? "" : "(UNSET)",
+ ct_ftp_info->seq_aft_nl[dir][0],
+ ct_ftp_info->seq_aft_nl_num[dir] > 1 ? "" : "(UNSET)",
+ ct_ftp_info->seq_aft_nl[dir][1]);
+ ret = NF_ACCEPT;
+ goto out_update_nl;
+ }
+
+ /* Initialize IP/IPv6 addr to expected address (it's not mentioned
+ in EPSV responses) */
+ cmd.l3num = ct->tuplehash[dir].tuple.src.l3num;
+ memcpy(cmd.u3.all, &ct->tuplehash[dir].tuple.src.u3.all,
+ sizeof(cmd.u3.all));
+
+ for (i = 0; i < ARRAY_SIZE(search); i++) {
+ if (search[i].dir != dir) continue;
+
+ found = find_pattern(fb_ptr, datalen,
+ search[i].pattern,
+ search[i].plen,
+ search[i].skip,
+ search[i].term,
+ &matchoff, &matchlen,
+ &cmd,
+ search[i].getnum);
+ if (found) break;
+ }
+ if (found == -1) {
+ /* We don't usually drop packets. After all, this is
+ connection tracking, not packet filtering.
+ However, it is necessary for accurate tracking in
+ this case. */
+ if (net_ratelimit())
+ printk("conntrack_ftp: partial %s %u+%u\n",
+ search[i].pattern,
+ ntohl(th->seq), datalen);
+ ret = NF_DROP;
+ goto out;
+ } else if (found == 0) { /* No match */
+ ret = NF_ACCEPT;
+ goto out_update_nl;
+ }
+
+ DEBUGP("conntrack_ftp: match `%.*s' (%u bytes at %u)\n",
+ (int)matchlen, fb_ptr + matchoff,
+ matchlen, ntohl(th->seq) + matchoff);
+
+ exp = nf_conntrack_expect_alloc(ct);
+ if (exp == NULL) {
+ ret = NF_DROP;
+ goto out;
+ }
+
+ /* We refer to the reverse direction ("!dir") tuples here,
+ * because we're expecting something in the other direction.
+ * Doesn't matter unless NAT is happening. */
+ exp->tuple.dst.u3 = ct->tuplehash[!dir].tuple.dst.u3;
+
+ /* Update the ftp info */
+ if ((cmd.l3num == ct->tuplehash[dir].tuple.src.l3num) &&
+ memcmp(&cmd.u3.all, &ct->tuplehash[dir].tuple.src.u3.all,
+ sizeof(cmd.u3.all))) {
+ /* Enrico Scholz's passive FTP to partially RNAT'd ftp
+ server: it really wants us to connect to a
+ different IP address. Simply don't record it for
+ NAT. */
+ if (cmd.l3num == PF_INET) {
+ DEBUGP("conntrack_ftp: NOT RECORDING: %u,%u,%u,%u != %u.%u.%u.%u\n",
+ NIPQUAD(cmd.u3.ip),
+ NIPQUAD(ct->tuplehash[dir].tuple.src.u3.ip));
+ } else {
+ DEBUGP("conntrack_ftp: NOT RECORDING: %x:%x:%x:%x:%x:%x:%x:%x != %x:%x:%x:%x:%x:%x:%x:%x\n",
+ NIP6(*((struct in6_addr *)cmd.u3.ip6)),
+ NIP6(*((struct in6_addr *)ct->tuplehash[dir]
+ .tuple.src.u3.ip6)));
+ }
+
+ /* Thanks to Cristiano Lincoln Mattos
+ <lincoln@cesar.org.br> for reporting this potential
+ problem (DMZ machines opening holes to internal
+ networks, or the packet filter itself). */
+ if (!loose) {
+ ret = NF_ACCEPT;
+ goto out_put_expect;
+ }
+ memcpy(&exp->tuple.dst.u3, &cmd.u3.all,
+ sizeof(exp->tuple.dst.u3));
+ }
+
+ exp->tuple.src.u3 = ct->tuplehash[!dir].tuple.src.u3;
+ exp->tuple.src.l3num = cmd.l3num;
+ exp->tuple.src.u.tcp.port = 0;
+ exp->tuple.dst.u.tcp.port = cmd.u.tcp.port;
+ exp->tuple.dst.protonum = IPPROTO_TCP;
+
+ exp->mask = (struct nf_conntrack_tuple)
+ { .src = { .l3num = 0xFFFF,
+ .u = { .tcp = { 0 }},
+ },
+ .dst = { .protonum = 0xFF,
+ .u = { .tcp = { 0xFFFF }},
+ },
+ };
+ if (cmd.l3num == PF_INET) {
+ exp->mask.src.u3.ip = 0xFFFFFFFF;
+ exp->mask.dst.u3.ip = 0xFFFFFFFF;
+ } else {
+ memset(exp->mask.src.u3.ip6, 0xFF,
+ sizeof(exp->mask.src.u3.ip6));
+ memset(exp->mask.dst.u3.ip6, 0xFF,
+ sizeof(exp->mask.src.u3.ip6));
+ }
+
+ exp->expectfn = NULL;
+ exp->flags = 0;
+
+ /* Now, NAT might want to mangle the packet, and register the
+ * (possibly changed) expectation itself. */
+ if (nf_nat_ftp_hook)
+ ret = nf_nat_ftp_hook(pskb, ctinfo, search[i].ftptype,
+ matchoff, matchlen, exp, &seq);
+ else {
+ /* Can't expect this? Best to drop packet now. */
+ if (nf_conntrack_expect_related(exp) != 0)
+ ret = NF_DROP;
+ else
+ ret = NF_ACCEPT;
+ }
+
+out_put_expect:
+ nf_conntrack_expect_put(exp);
+
+out_update_nl:
+ /* Now if this ends in \n, update ftp info. Seq may have been
+ * adjusted by NAT code. */
+ if (ends_in_nl)
+ update_nl_seq(seq, ct_ftp_info, dir, *pskb);
+ out:
+ spin_unlock_bh(&nf_ftp_lock);
+ return ret;
+}
+
+static struct nf_conntrack_helper ftp[MAX_PORTS][2];
+static char ftp_names[MAX_PORTS][2][sizeof("ftp-65535")];
+
+/* don't make this __exit, since it's called from __init ! */
+static void fini(void)
+{
+ int i, j;
+ for (i = 0; i < ports_c; i++) {
+ for (j = 0; j < 2; j++) {
+ if (ftp[i][j].me == NULL)
+ continue;
+
+ DEBUGP("nf_ct_ftp: unregistering helper for pf: %d "
+ "port: %d\n",
+ ftp[i][j].tuple.src.l3num, ports[i]);
+ nf_conntrack_helper_unregister(&ftp[i][j]);
+ }
+ }
+
+ kfree(ftp_buffer);
+}
+
+static int __init init(void)
+{
+ int i, j = -1, ret = 0;
+ char *tmpname;
+
+ ftp_buffer = kmalloc(65536, GFP_KERNEL);
+ if (!ftp_buffer)
+ return -ENOMEM;
+
+ if (ports_c == 0)
+ ports[ports_c++] = FTP_PORT;
+
+ /* FIXME should be configurable whether IPv4 and IPv6 FTP connections
+ are tracked or not - YK */
+ for (i = 0; i < ports_c; i++) {
+ memset(&ftp[i], 0, sizeof(struct nf_conntrack_helper));
+
+ ftp[i][0].tuple.src.l3num = PF_INET;
+ ftp[i][1].tuple.src.l3num = PF_INET6;
+ for (j = 0; j < 2; j++) {
+ ftp[i][j].tuple.src.u.tcp.port = htons(ports[i]);
+ ftp[i][j].tuple.dst.protonum = IPPROTO_TCP;
+ ftp[i][j].mask.src.u.tcp.port = 0xFFFF;
+ ftp[i][j].mask.dst.protonum = 0xFF;
+ ftp[i][j].max_expected = 1;
+ ftp[i][j].timeout = 5 * 60; /* 5 Minutes */
+ ftp[i][j].me = THIS_MODULE;
+ ftp[i][j].help = help;
+ tmpname = &ftp_names[i][j][0];
+ if (ports[i] == FTP_PORT)
+ sprintf(tmpname, "ftp");
+ else
+ sprintf(tmpname, "ftp-%d", ports[i]);
+ ftp[i][j].name = tmpname;
+
+ DEBUGP("nf_ct_ftp: registering helper for pf: %d "
+ "port: %d\n",
+ ftp[i][j].tuple.src.l3num, ports[i]);
+ ret = nf_conntrack_helper_register(&ftp[i][j]);
+ if (ret) {
+ printk("nf_ct_ftp: failed to register helper "
+ " for pf: %d port: %d\n",
+ ftp[i][j].tuple.src.l3num, ports[i]);
+ fini();
+ return ret;
+ }
+ }
+ }
+
+ return 0;
+}
+
+module_init(init);
+module_exit(fini);
diff --git a/net/netfilter/nf_conntrack_l3proto_generic.c b/net/netfilter/nf_conntrack_l3proto_generic.c
new file mode 100644
index 000000000000..7de4f06c63c5
--- /dev/null
+++ b/net/netfilter/nf_conntrack_l3proto_generic.c
@@ -0,0 +1,98 @@
+/*
+ * (C) 2003,2004 USAGI/WIDE Project <http://www.linux-ipv6.org>
+ *
+ * Based largely upon the original ip_conntrack code which
+ * had the following copyright information:
+ *
+ * (C) 1999-2001 Paul `Rusty' Russell
+ * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.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.
+ *
+ * Author:
+ * Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp>
+ */
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/ip.h>
+#include <linux/netfilter.h>
+#include <linux/module.h>
+#include <linux/skbuff.h>
+#include <linux/icmp.h>
+#include <linux/sysctl.h>
+#include <net/ip.h>
+
+#include <linux/netfilter_ipv4.h>
+#include <net/netfilter/nf_conntrack.h>
+#include <net/netfilter/nf_conntrack_protocol.h>
+#include <net/netfilter/nf_conntrack_l3proto.h>
+#include <net/netfilter/nf_conntrack_core.h>
+#include <net/netfilter/ipv4/nf_conntrack_ipv4.h>
+
+#if 0
+#define DEBUGP printk
+#else
+#define DEBUGP(format, args...)
+#endif
+
+DECLARE_PER_CPU(struct nf_conntrack_stat, nf_conntrack_stat);
+
+static int generic_pkt_to_tuple(const struct sk_buff *skb, unsigned int nhoff,
+ struct nf_conntrack_tuple *tuple)
+{
+ memset(&tuple->src.u3, 0, sizeof(tuple->src.u3));
+ memset(&tuple->dst.u3, 0, sizeof(tuple->dst.u3));
+
+ return 1;
+}
+
+static int generic_invert_tuple(struct nf_conntrack_tuple *tuple,
+ const struct nf_conntrack_tuple *orig)
+{
+ memset(&tuple->src.u3, 0, sizeof(tuple->src.u3));
+ memset(&tuple->dst.u3, 0, sizeof(tuple->dst.u3));
+
+ return 1;
+}
+
+static int generic_print_tuple(struct seq_file *s,
+ const struct nf_conntrack_tuple *tuple)
+{
+ return 0;
+}
+
+static int generic_print_conntrack(struct seq_file *s,
+ const struct nf_conn *conntrack)
+{
+ return 0;
+}
+
+static int
+generic_prepare(struct sk_buff **pskb, unsigned int hooknum,
+ unsigned int *dataoff, u_int8_t *protonum)
+{
+ /* Never track !!! */
+ return -NF_ACCEPT;
+}
+
+
+static u_int32_t generic_get_features(const struct nf_conntrack_tuple *tuple)
+
+{
+ return NF_CT_F_BASIC;
+}
+
+struct nf_conntrack_l3proto nf_conntrack_generic_l3proto = {
+ .l3proto = PF_UNSPEC,
+ .name = "unknown",
+ .pkt_to_tuple = generic_pkt_to_tuple,
+ .invert_tuple = generic_invert_tuple,
+ .print_tuple = generic_print_tuple,
+ .print_conntrack = generic_print_conntrack,
+ .prepare = generic_prepare,
+ .get_features = generic_get_features,
+ .me = THIS_MODULE,
+};
diff --git a/net/netfilter/nf_conntrack_proto_generic.c b/net/netfilter/nf_conntrack_proto_generic.c
new file mode 100644
index 000000000000..36425f6c833f
--- /dev/null
+++ b/net/netfilter/nf_conntrack_proto_generic.c
@@ -0,0 +1,85 @@
+/* (C) 1999-2001 Paul `Rusty' Russell
+ * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.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.
+ *
+ * 16 Dec 2003: Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp>
+ * - enable working with L3 protocol independent connection tracking.
+ *
+ * Derived from net/ipv4/netfilter/ip_conntrack_proto_generic.c
+ */
+
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/timer.h>
+#include <linux/netfilter.h>
+#include <net/netfilter/nf_conntrack_protocol.h>
+
+unsigned long nf_ct_generic_timeout = 600*HZ;
+
+static int generic_pkt_to_tuple(const struct sk_buff *skb,
+ unsigned int dataoff,
+ struct nf_conntrack_tuple *tuple)
+{
+ tuple->src.u.all = 0;
+ tuple->dst.u.all = 0;
+
+ return 1;
+}
+
+static int generic_invert_tuple(struct nf_conntrack_tuple *tuple,
+ const struct nf_conntrack_tuple *orig)
+{
+ tuple->src.u.all = 0;
+ tuple->dst.u.all = 0;
+
+ return 1;
+}
+
+/* Print out the per-protocol part of the tuple. */
+static int generic_print_tuple(struct seq_file *s,
+ const struct nf_conntrack_tuple *tuple)
+{
+ return 0;
+}
+
+/* Print out the private part of the conntrack. */
+static int generic_print_conntrack(struct seq_file *s,
+ const struct nf_conn *state)
+{
+ return 0;
+}
+
+/* Returns verdict for packet, or -1 for invalid. */
+static int packet(struct nf_conn *conntrack,
+ const struct sk_buff *skb,
+ unsigned int dataoff,
+ enum ip_conntrack_info ctinfo,
+ int pf,
+ unsigned int hooknum)
+{
+ nf_ct_refresh_acct(conntrack, ctinfo, skb, nf_ct_generic_timeout);
+ return NF_ACCEPT;
+}
+
+/* Called when a new connection for this protocol found. */
+static int new(struct nf_conn *conntrack, const struct sk_buff *skb,
+ unsigned int dataoff)
+{
+ return 1;
+}
+
+struct nf_conntrack_protocol nf_conntrack_generic_protocol =
+{
+ .l3proto = PF_UNSPEC,
+ .proto = 0,
+ .name = "unknown",
+ .pkt_to_tuple = generic_pkt_to_tuple,
+ .invert_tuple = generic_invert_tuple,
+ .print_tuple = generic_print_tuple,
+ .print_conntrack = generic_print_conntrack,
+ .packet = packet,
+ .new = new,
+};
diff --git a/net/netfilter/nf_conntrack_proto_sctp.c b/net/netfilter/nf_conntrack_proto_sctp.c
new file mode 100644
index 000000000000..3a600f77b4e0
--- /dev/null
+++ b/net/netfilter/nf_conntrack_proto_sctp.c
@@ -0,0 +1,670 @@
+/*
+ * Connection tracking protocol helper module for SCTP.
+ *
+ * SCTP is defined in RFC 2960. References to various sections in this code
+ * are to this RFC.
+ *
+ * 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.
+ *
+ * 17 Oct 2004: Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp>
+ * - enable working with L3 protocol independent connection tracking.
+ *
+ * Derived from net/ipv4/ip_conntrack_sctp.c
+ */
+
+/*
+ * Added support for proc manipulation of timeouts.
+ */
+
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/timer.h>
+#include <linux/netfilter.h>
+#include <linux/module.h>
+#include <linux/in.h>
+#include <linux/ip.h>
+#include <linux/sctp.h>
+#include <linux/string.h>
+#include <linux/seq_file.h>
+
+#include <net/netfilter/nf_conntrack.h>
+#include <net/netfilter/nf_conntrack_protocol.h>
+
+#if 0
+#define DEBUGP(format, ...) printk(format, ## __VA_ARGS__)
+#else
+#define DEBUGP(format, args...)
+#endif
+
+/* Protects conntrack->proto.sctp */
+static DEFINE_RWLOCK(sctp_lock);
+
+/* FIXME: Examine ipfilter's timeouts and conntrack transitions more
+ closely. They're more complex. --RR
+
+ And so for me for SCTP :D -Kiran */
+
+static const char *sctp_conntrack_names[] = {
+ "NONE",
+ "CLOSED",
+ "COOKIE_WAIT",
+ "COOKIE_ECHOED",
+ "ESTABLISHED",
+ "SHUTDOWN_SENT",
+ "SHUTDOWN_RECD",
+ "SHUTDOWN_ACK_SENT",
+};
+
+#define SECS * HZ
+#define MINS * 60 SECS
+#define HOURS * 60 MINS
+#define DAYS * 24 HOURS
+
+static unsigned long nf_ct_sctp_timeout_closed = 10 SECS;
+static unsigned long nf_ct_sctp_timeout_cookie_wait = 3 SECS;
+static unsigned long nf_ct_sctp_timeout_cookie_echoed = 3 SECS;
+static unsigned long nf_ct_sctp_timeout_established = 5 DAYS;
+static unsigned long nf_ct_sctp_timeout_shutdown_sent = 300 SECS / 1000;
+static unsigned long nf_ct_sctp_timeout_shutdown_recd = 300 SECS / 1000;
+static unsigned long nf_ct_sctp_timeout_shutdown_ack_sent = 3 SECS;
+
+static unsigned long * sctp_timeouts[]
+= { NULL, /* SCTP_CONNTRACK_NONE */
+ &nf_ct_sctp_timeout_closed, /* SCTP_CONNTRACK_CLOSED */
+ &nf_ct_sctp_timeout_cookie_wait, /* SCTP_CONNTRACK_COOKIE_WAIT */
+ &nf_ct_sctp_timeout_cookie_echoed, /* SCTP_CONNTRACK_COOKIE_ECHOED */
+ &nf_ct_sctp_timeout_established, /* SCTP_CONNTRACK_ESTABLISHED */
+ &nf_ct_sctp_timeout_shutdown_sent, /* SCTP_CONNTRACK_SHUTDOWN_SENT */
+ &nf_ct_sctp_timeout_shutdown_recd, /* SCTP_CONNTRACK_SHUTDOWN_RECD */
+ &nf_ct_sctp_timeout_shutdown_ack_sent /* SCTP_CONNTRACK_SHUTDOWN_ACK_SENT */
+ };
+
+#define sNO SCTP_CONNTRACK_NONE
+#define sCL SCTP_CONNTRACK_CLOSED
+#define sCW SCTP_CONNTRACK_COOKIE_WAIT
+#define sCE SCTP_CONNTRACK_COOKIE_ECHOED
+#define sES SCTP_CONNTRACK_ESTABLISHED
+#define sSS SCTP_CONNTRACK_SHUTDOWN_SENT
+#define sSR SCTP_CONNTRACK_SHUTDOWN_RECD
+#define sSA SCTP_CONNTRACK_SHUTDOWN_ACK_SENT
+#define sIV SCTP_CONNTRACK_MAX
+
+/*
+ These are the descriptions of the states:
+
+NOTE: These state names are tantalizingly similar to the states of an
+SCTP endpoint. But the interpretation of the states is a little different,
+considering that these are the states of the connection and not of an end
+point. Please note the subtleties. -Kiran
+
+NONE - Nothing so far.
+COOKIE WAIT - We have seen an INIT chunk in the original direction, or also
+ an INIT_ACK chunk in the reply direction.
+COOKIE ECHOED - We have seen a COOKIE_ECHO chunk in the original direction.
+ESTABLISHED - We have seen a COOKIE_ACK in the reply direction.
+SHUTDOWN_SENT - We have seen a SHUTDOWN chunk in the original direction.
+SHUTDOWN_RECD - We have seen a SHUTDOWN chunk in the reply directoin.
+SHUTDOWN_ACK_SENT - We have seen a SHUTDOWN_ACK chunk in the direction opposite
+ to that of the SHUTDOWN chunk.
+CLOSED - We have seen a SHUTDOWN_COMPLETE chunk in the direction of
+ the SHUTDOWN chunk. Connection is closed.
+*/
+
+/* TODO
+ - I have assumed that the first INIT is in the original direction.
+ This messes things when an INIT comes in the reply direction in CLOSED
+ state.
+ - Check the error type in the reply dir before transitioning from
+cookie echoed to closed.
+ - Sec 5.2.4 of RFC 2960
+ - Multi Homing support.
+*/
+
+/* SCTP conntrack state transitions */
+static enum sctp_conntrack sctp_conntracks[2][9][SCTP_CONNTRACK_MAX] = {
+ {
+/* ORIGINAL */
+/* sNO, sCL, sCW, sCE, sES, sSS, sSR, sSA */
+/* init */ {sCW, sCW, sCW, sCE, sES, sSS, sSR, sSA},
+/* init_ack */ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sSA},
+/* abort */ {sCL, sCL, sCL, sCL, sCL, sCL, sCL, sCL},
+/* shutdown */ {sCL, sCL, sCW, sCE, sSS, sSS, sSR, sSA},
+/* shutdown_ack */ {sSA, sCL, sCW, sCE, sES, sSA, sSA, sSA},
+/* error */ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sSA},/* Cant have Stale cookie*/
+/* cookie_echo */ {sCL, sCL, sCE, sCE, sES, sSS, sSR, sSA},/* 5.2.4 - Big TODO */
+/* cookie_ack */ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sSA},/* Cant come in orig dir */
+/* shutdown_comp*/ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sCL}
+ },
+ {
+/* REPLY */
+/* sNO, sCL, sCW, sCE, sES, sSS, sSR, sSA */
+/* init */ {sIV, sCL, sCW, sCE, sES, sSS, sSR, sSA},/* INIT in sCL Big TODO */
+/* init_ack */ {sIV, sCL, sCW, sCE, sES, sSS, sSR, sSA},
+/* abort */ {sIV, sCL, sCL, sCL, sCL, sCL, sCL, sCL},
+/* shutdown */ {sIV, sCL, sCW, sCE, sSR, sSS, sSR, sSA},
+/* shutdown_ack */ {sIV, sCL, sCW, sCE, sES, sSA, sSA, sSA},
+/* error */ {sIV, sCL, sCW, sCL, sES, sSS, sSR, sSA},
+/* cookie_echo */ {sIV, sCL, sCW, sCE, sES, sSS, sSR, sSA},/* Cant come in reply dir */
+/* cookie_ack */ {sIV, sCL, sCW, sES, sES, sSS, sSR, sSA},
+/* shutdown_comp*/ {sIV, sCL, sCW, sCE, sES, sSS, sSR, sCL}
+ }
+};
+
+static int sctp_pkt_to_tuple(const struct sk_buff *skb,
+ unsigned int dataoff,
+ struct nf_conntrack_tuple *tuple)
+{
+ sctp_sctphdr_t _hdr, *hp;
+
+ DEBUGP(__FUNCTION__);
+ DEBUGP("\n");
+
+ /* Actually only need first 8 bytes. */
+ hp = skb_header_pointer(skb, dataoff, 8, &_hdr);
+ if (hp == NULL)
+ return 0;
+
+ tuple->src.u.sctp.port = hp->source;
+ tuple->dst.u.sctp.port = hp->dest;
+ return 1;
+}
+
+static int sctp_invert_tuple(struct nf_conntrack_tuple *tuple,
+ const struct nf_conntrack_tuple *orig)
+{
+ DEBUGP(__FUNCTION__);
+ DEBUGP("\n");
+
+ tuple->src.u.sctp.port = orig->dst.u.sctp.port;
+ tuple->dst.u.sctp.port = orig->src.u.sctp.port;
+ return 1;
+}
+
+/* Print out the per-protocol part of the tuple. */
+static int sctp_print_tuple(struct seq_file *s,
+ const struct nf_conntrack_tuple *tuple)
+{
+ DEBUGP(__FUNCTION__);
+ DEBUGP("\n");
+
+ return seq_printf(s, "sport=%hu dport=%hu ",
+ ntohs(tuple->src.u.sctp.port),
+ ntohs(tuple->dst.u.sctp.port));
+}
+
+/* Print out the private part of the conntrack. */
+static int sctp_print_conntrack(struct seq_file *s,
+ const struct nf_conn *conntrack)
+{
+ enum sctp_conntrack state;
+
+ DEBUGP(__FUNCTION__);
+ DEBUGP("\n");
+
+ read_lock_bh(&sctp_lock);
+ state = conntrack->proto.sctp.state;
+ read_unlock_bh(&sctp_lock);
+
+ return seq_printf(s, "%s ", sctp_conntrack_names[state]);
+}
+
+#define for_each_sctp_chunk(skb, sch, _sch, offset, dataoff, count) \
+for (offset = dataoff + sizeof(sctp_sctphdr_t), count = 0; \
+ offset < skb->len && \
+ (sch = skb_header_pointer(skb, offset, sizeof(_sch), &_sch)); \
+ offset += (htons(sch->length) + 3) & ~3, count++)
+
+/* Some validity checks to make sure the chunks are fine */
+static int do_basic_checks(struct nf_conn *conntrack,
+ const struct sk_buff *skb,
+ unsigned int dataoff,
+ char *map)
+{
+ u_int32_t offset, count;
+ sctp_chunkhdr_t _sch, *sch;
+ int flag;
+
+ DEBUGP(__FUNCTION__);
+ DEBUGP("\n");
+
+ flag = 0;
+
+ for_each_sctp_chunk (skb, sch, _sch, offset, dataoff, count) {
+ DEBUGP("Chunk Num: %d Type: %d\n", count, sch->type);
+
+ if (sch->type == SCTP_CID_INIT
+ || sch->type == SCTP_CID_INIT_ACK
+ || sch->type == SCTP_CID_SHUTDOWN_COMPLETE) {
+ flag = 1;
+ }
+
+ /* Cookie Ack/Echo chunks not the first OR
+ Init / Init Ack / Shutdown compl chunks not the only chunks */
+ if ((sch->type == SCTP_CID_COOKIE_ACK
+ || sch->type == SCTP_CID_COOKIE_ECHO
+ || flag)
+ && count !=0 ) {
+ DEBUGP("Basic checks failed\n");
+ return 1;
+ }
+
+ if (map) {
+ set_bit(sch->type, (void *)map);
+ }
+ }
+
+ DEBUGP("Basic checks passed\n");
+ return 0;
+}
+
+static int new_state(enum ip_conntrack_dir dir,
+ enum sctp_conntrack cur_state,
+ int chunk_type)
+{
+ int i;
+
+ DEBUGP(__FUNCTION__);
+ DEBUGP("\n");
+
+ DEBUGP("Chunk type: %d\n", chunk_type);
+
+ switch (chunk_type) {
+ case SCTP_CID_INIT:
+ DEBUGP("SCTP_CID_INIT\n");
+ i = 0; break;
+ case SCTP_CID_INIT_ACK:
+ DEBUGP("SCTP_CID_INIT_ACK\n");
+ i = 1; break;
+ case SCTP_CID_ABORT:
+ DEBUGP("SCTP_CID_ABORT\n");
+ i = 2; break;
+ case SCTP_CID_SHUTDOWN:
+ DEBUGP("SCTP_CID_SHUTDOWN\n");
+ i = 3; break;
+ case SCTP_CID_SHUTDOWN_ACK:
+ DEBUGP("SCTP_CID_SHUTDOWN_ACK\n");
+ i = 4; break;
+ case SCTP_CID_ERROR:
+ DEBUGP("SCTP_CID_ERROR\n");
+ i = 5; break;
+ case SCTP_CID_COOKIE_ECHO:
+ DEBUGP("SCTP_CID_COOKIE_ECHO\n");
+ i = 6; break;
+ case SCTP_CID_COOKIE_ACK:
+ DEBUGP("SCTP_CID_COOKIE_ACK\n");
+ i = 7; break;
+ case SCTP_CID_SHUTDOWN_COMPLETE:
+ DEBUGP("SCTP_CID_SHUTDOWN_COMPLETE\n");
+ i = 8; break;
+ default:
+ /* Other chunks like DATA, SACK, HEARTBEAT and
+ its ACK do not cause a change in state */
+ DEBUGP("Unknown chunk type, Will stay in %s\n",
+ sctp_conntrack_names[cur_state]);
+ return cur_state;
+ }
+
+ DEBUGP("dir: %d cur_state: %s chunk_type: %d new_state: %s\n",
+ dir, sctp_conntrack_names[cur_state], chunk_type,
+ sctp_conntrack_names[sctp_conntracks[dir][i][cur_state]]);
+
+ return sctp_conntracks[dir][i][cur_state];
+}
+
+/* Returns verdict for packet, or -1 for invalid. */
+static int sctp_packet(struct nf_conn *conntrack,
+ const struct sk_buff *skb,
+ unsigned int dataoff,
+ enum ip_conntrack_info ctinfo,
+ int pf,
+ unsigned int hooknum)
+{
+ enum sctp_conntrack newconntrack, oldsctpstate;
+ sctp_sctphdr_t _sctph, *sh;
+ sctp_chunkhdr_t _sch, *sch;
+ u_int32_t offset, count;
+ char map[256 / sizeof (char)] = {0};
+
+ DEBUGP(__FUNCTION__);
+ DEBUGP("\n");
+
+ sh = skb_header_pointer(skb, dataoff, sizeof(_sctph), &_sctph);
+ if (sh == NULL)
+ return -1;
+
+ if (do_basic_checks(conntrack, skb, dataoff, map) != 0)
+ return -1;
+
+ /* Check the verification tag (Sec 8.5) */
+ if (!test_bit(SCTP_CID_INIT, (void *)map)
+ && !test_bit(SCTP_CID_SHUTDOWN_COMPLETE, (void *)map)
+ && !test_bit(SCTP_CID_COOKIE_ECHO, (void *)map)
+ && !test_bit(SCTP_CID_ABORT, (void *)map)
+ && !test_bit(SCTP_CID_SHUTDOWN_ACK, (void *)map)
+ && (sh->vtag != conntrack->proto.sctp.vtag[CTINFO2DIR(ctinfo)])) {
+ DEBUGP("Verification tag check failed\n");
+ return -1;
+ }
+
+ oldsctpstate = newconntrack = SCTP_CONNTRACK_MAX;
+ for_each_sctp_chunk (skb, sch, _sch, offset, dataoff, count) {
+ write_lock_bh(&sctp_lock);
+
+ /* Special cases of Verification tag check (Sec 8.5.1) */
+ if (sch->type == SCTP_CID_INIT) {
+ /* Sec 8.5.1 (A) */
+ if (sh->vtag != 0) {
+ write_unlock_bh(&sctp_lock);
+ return -1;
+ }
+ } else if (sch->type == SCTP_CID_ABORT) {
+ /* Sec 8.5.1 (B) */
+ if (!(sh->vtag == conntrack->proto.sctp.vtag[CTINFO2DIR(ctinfo)])
+ && !(sh->vtag == conntrack->proto.sctp.vtag
+ [1 - CTINFO2DIR(ctinfo)])) {
+ write_unlock_bh(&sctp_lock);
+ return -1;
+ }
+ } else if (sch->type == SCTP_CID_SHUTDOWN_COMPLETE) {
+ /* Sec 8.5.1 (C) */
+ if (!(sh->vtag == conntrack->proto.sctp.vtag[CTINFO2DIR(ctinfo)])
+ && !(sh->vtag == conntrack->proto.sctp.vtag
+ [1 - CTINFO2DIR(ctinfo)]
+ && (sch->flags & 1))) {
+ write_unlock_bh(&sctp_lock);
+ return -1;
+ }
+ } else if (sch->type == SCTP_CID_COOKIE_ECHO) {
+ /* Sec 8.5.1 (D) */
+ if (!(sh->vtag == conntrack->proto.sctp.vtag[CTINFO2DIR(ctinfo)])) {
+ write_unlock_bh(&sctp_lock);
+ return -1;
+ }
+ }
+
+ oldsctpstate = conntrack->proto.sctp.state;
+ newconntrack = new_state(CTINFO2DIR(ctinfo), oldsctpstate, sch->type);
+
+ /* Invalid */
+ if (newconntrack == SCTP_CONNTRACK_MAX) {
+ DEBUGP("nf_conntrack_sctp: Invalid dir=%i ctype=%u conntrack=%u\n",
+ CTINFO2DIR(ctinfo), sch->type, oldsctpstate);
+ write_unlock_bh(&sctp_lock);
+ return -1;
+ }
+
+ /* If it is an INIT or an INIT ACK note down the vtag */
+ if (sch->type == SCTP_CID_INIT
+ || sch->type == SCTP_CID_INIT_ACK) {
+ sctp_inithdr_t _inithdr, *ih;
+
+ ih = skb_header_pointer(skb, offset + sizeof(sctp_chunkhdr_t),
+ sizeof(_inithdr), &_inithdr);
+ if (ih == NULL) {
+ write_unlock_bh(&sctp_lock);
+ return -1;
+ }
+ DEBUGP("Setting vtag %x for dir %d\n",
+ ih->init_tag, !CTINFO2DIR(ctinfo));
+ conntrack->proto.sctp.vtag[!CTINFO2DIR(ctinfo)] = ih->init_tag;
+ }
+
+ conntrack->proto.sctp.state = newconntrack;
+ if (oldsctpstate != newconntrack)
+ nf_conntrack_event_cache(IPCT_PROTOINFO, skb);
+ write_unlock_bh(&sctp_lock);
+ }
+
+ nf_ct_refresh_acct(conntrack, ctinfo, skb, *sctp_timeouts[newconntrack]);
+
+ if (oldsctpstate == SCTP_CONNTRACK_COOKIE_ECHOED
+ && CTINFO2DIR(ctinfo) == IP_CT_DIR_REPLY
+ && newconntrack == SCTP_CONNTRACK_ESTABLISHED) {
+ DEBUGP("Setting assured bit\n");
+ set_bit(IPS_ASSURED_BIT, &conntrack->status);
+ nf_conntrack_event_cache(IPCT_STATUS, skb);
+ }
+
+ return NF_ACCEPT;
+}
+
+/* Called when a new connection for this protocol found. */
+static int sctp_new(struct nf_conn *conntrack, const struct sk_buff *skb,
+ unsigned int dataoff)
+{
+ enum sctp_conntrack newconntrack;
+ sctp_sctphdr_t _sctph, *sh;
+ sctp_chunkhdr_t _sch, *sch;
+ u_int32_t offset, count;
+ char map[256 / sizeof (char)] = {0};
+
+ DEBUGP(__FUNCTION__);
+ DEBUGP("\n");
+
+ sh = skb_header_pointer(skb, dataoff, sizeof(_sctph), &_sctph);
+ if (sh == NULL)
+ return 0;
+
+ if (do_basic_checks(conntrack, skb, dataoff, map) != 0)
+ return 0;
+
+ /* If an OOTB packet has any of these chunks discard (Sec 8.4) */
+ if ((test_bit (SCTP_CID_ABORT, (void *)map))
+ || (test_bit (SCTP_CID_SHUTDOWN_COMPLETE, (void *)map))
+ || (test_bit (SCTP_CID_COOKIE_ACK, (void *)map))) {
+ return 0;
+ }
+
+ newconntrack = SCTP_CONNTRACK_MAX;
+ for_each_sctp_chunk (skb, sch, _sch, offset, dataoff, count) {
+ /* Don't need lock here: this conntrack not in circulation yet */
+ newconntrack = new_state(IP_CT_DIR_ORIGINAL,
+ SCTP_CONNTRACK_NONE, sch->type);
+
+ /* Invalid: delete conntrack */
+ if (newconntrack == SCTP_CONNTRACK_MAX) {
+ DEBUGP("nf_conntrack_sctp: invalid new deleting.\n");
+ return 0;
+ }
+
+ /* Copy the vtag into the state info */
+ if (sch->type == SCTP_CID_INIT) {
+ if (sh->vtag == 0) {
+ sctp_inithdr_t _inithdr, *ih;
+
+ ih = skb_header_pointer(skb, offset + sizeof(sctp_chunkhdr_t),
+ sizeof(_inithdr), &_inithdr);
+ if (ih == NULL)
+ return 0;
+
+ DEBUGP("Setting vtag %x for new conn\n",
+ ih->init_tag);
+
+ conntrack->proto.sctp.vtag[IP_CT_DIR_REPLY] =
+ ih->init_tag;
+ } else {
+ /* Sec 8.5.1 (A) */
+ return 0;
+ }
+ }
+ /* If it is a shutdown ack OOTB packet, we expect a return
+ shutdown complete, otherwise an ABORT Sec 8.4 (5) and (8) */
+ else {
+ DEBUGP("Setting vtag %x for new conn OOTB\n",
+ sh->vtag);
+ conntrack->proto.sctp.vtag[IP_CT_DIR_REPLY] = sh->vtag;
+ }
+
+ conntrack->proto.sctp.state = newconntrack;
+ }
+
+ return 1;
+}
+
+struct nf_conntrack_protocol nf_conntrack_protocol_sctp4 = {
+ .l3proto = PF_INET,
+ .proto = IPPROTO_SCTP,
+ .name = "sctp",
+ .pkt_to_tuple = sctp_pkt_to_tuple,
+ .invert_tuple = sctp_invert_tuple,
+ .print_tuple = sctp_print_tuple,
+ .print_conntrack = sctp_print_conntrack,
+ .packet = sctp_packet,
+ .new = sctp_new,
+ .destroy = NULL,
+ .me = THIS_MODULE
+};
+
+struct nf_conntrack_protocol nf_conntrack_protocol_sctp6 = {
+ .l3proto = PF_INET6,
+ .proto = IPPROTO_SCTP,
+ .name = "sctp",
+ .pkt_to_tuple = sctp_pkt_to_tuple,
+ .invert_tuple = sctp_invert_tuple,
+ .print_tuple = sctp_print_tuple,
+ .print_conntrack = sctp_print_conntrack,
+ .packet = sctp_packet,
+ .new = sctp_new,
+ .destroy = NULL,
+ .me = THIS_MODULE
+};
+
+#ifdef CONFIG_SYSCTL
+static ctl_table nf_ct_sysctl_table[] = {
+ {
+ .ctl_name = NET_NF_CONNTRACK_SCTP_TIMEOUT_CLOSED,
+ .procname = "nf_conntrack_sctp_timeout_closed",
+ .data = &nf_ct_sctp_timeout_closed,
+ .maxlen = sizeof(unsigned int),
+ .mode = 0644,
+ .proc_handler = &proc_dointvec_jiffies,
+ },
+ {
+ .ctl_name = NET_NF_CONNTRACK_SCTP_TIMEOUT_COOKIE_WAIT,
+ .procname = "nf_conntrack_sctp_timeout_cookie_wait",
+ .data = &nf_ct_sctp_timeout_cookie_wait,
+ .maxlen = sizeof(unsigned int),
+ .mode = 0644,
+ .proc_handler = &proc_dointvec_jiffies,
+ },
+ {
+ .ctl_name = NET_NF_CONNTRACK_SCTP_TIMEOUT_COOKIE_ECHOED,
+ .procname = "nf_conntrack_sctp_timeout_cookie_echoed",
+ .data = &nf_ct_sctp_timeout_cookie_echoed,
+ .maxlen = sizeof(unsigned int),
+ .mode = 0644,
+ .proc_handler = &proc_dointvec_jiffies,
+ },
+ {
+ .ctl_name = NET_NF_CONNTRACK_SCTP_TIMEOUT_ESTABLISHED,
+ .procname = "nf_conntrack_sctp_timeout_established",
+ .data = &nf_ct_sctp_timeout_established,
+ .maxlen = sizeof(unsigned int),
+ .mode = 0644,
+ .proc_handler = &proc_dointvec_jiffies,
+ },
+ {
+ .ctl_name = NET_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_SENT,
+ .procname = "nf_conntrack_sctp_timeout_shutdown_sent",
+ .data = &nf_ct_sctp_timeout_shutdown_sent,
+ .maxlen = sizeof(unsigned int),
+ .mode = 0644,
+ .proc_handler = &proc_dointvec_jiffies,
+ },
+ {
+ .ctl_name = NET_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_RECD,
+ .procname = "nf_conntrack_sctp_timeout_shutdown_recd",
+ .data = &nf_ct_sctp_timeout_shutdown_recd,
+ .maxlen = sizeof(unsigned int),
+ .mode = 0644,
+ .proc_handler = &proc_dointvec_jiffies,
+ },
+ {
+ .ctl_name = NET_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_ACK_SENT,
+ .procname = "nf_conntrack_sctp_timeout_shutdown_ack_sent",
+ .data = &nf_ct_sctp_timeout_shutdown_ack_sent,
+ .maxlen = sizeof(unsigned int),
+ .mode = 0644,
+ .proc_handler = &proc_dointvec_jiffies,
+ },
+ { .ctl_name = 0 }
+};
+
+static ctl_table nf_ct_netfilter_table[] = {
+ {
+ .ctl_name = NET_NETFILTER,
+ .procname = "netfilter",
+ .mode = 0555,
+ .child = nf_ct_sysctl_table,
+ },
+ { .ctl_name = 0 }
+};
+
+static ctl_table nf_ct_net_table[] = {
+ {
+ .ctl_name = CTL_NET,
+ .procname = "net",
+ .mode = 0555,
+ .child = nf_ct_netfilter_table,
+ },
+ { .ctl_name = 0 }
+};
+
+static struct ctl_table_header *nf_ct_sysctl_header;
+#endif
+
+int __init init(void)
+{
+ int ret;
+
+ ret = nf_conntrack_protocol_register(&nf_conntrack_protocol_sctp4);
+ if (ret) {
+ printk("nf_conntrack_proto_sctp4: protocol register failed\n");
+ goto out;
+ }
+ ret = nf_conntrack_protocol_register(&nf_conntrack_protocol_sctp6);
+ if (ret) {
+ printk("nf_conntrack_proto_sctp6: protocol register failed\n");
+ goto cleanup_sctp4;
+ }
+
+#ifdef CONFIG_SYSCTL
+ nf_ct_sysctl_header = register_sysctl_table(nf_ct_net_table, 0);
+ if (nf_ct_sysctl_header == NULL) {
+ printk("nf_conntrack_proto_sctp: can't register to sysctl.\n");
+ goto cleanup;
+ }
+#endif
+
+ return ret;
+
+#ifdef CONFIG_SYSCTL
+ cleanup:
+ nf_conntrack_protocol_unregister(&nf_conntrack_protocol_sctp6);
+#endif
+ cleanup_sctp4:
+ nf_conntrack_protocol_unregister(&nf_conntrack_protocol_sctp4);
+ out:
+ DEBUGP("SCTP conntrack module loading %s\n",
+ ret ? "failed": "succeeded");
+ return ret;
+}
+
+void __exit fini(void)
+{
+ nf_conntrack_protocol_unregister(&nf_conntrack_protocol_sctp6);
+ nf_conntrack_protocol_unregister(&nf_conntrack_protocol_sctp4);
+#ifdef CONFIG_SYSCTL
+ unregister_sysctl_table(nf_ct_sysctl_header);
+#endif
+ DEBUGP("SCTP conntrack module unloaded\n");
+}
+
+module_init(init);
+module_exit(fini);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Kiran Kumar Immidi");
+MODULE_DESCRIPTION("Netfilter connection tracking protocol helper for SCTP");
diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c
new file mode 100644
index 000000000000..83d90dd624f0
--- /dev/null
+++ b/net/netfilter/nf_conntrack_proto_tcp.c
@@ -0,0 +1,1162 @@
+/* (C) 1999-2001 Paul `Rusty' Russell
+ * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.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.
+ *
+ * Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>:
+ * - Real stateful connection tracking
+ * - Modified state transitions table
+ * - Window scaling support added
+ * - SACK support added
+ *
+ * Willy Tarreau:
+ * - State table bugfixes
+ * - More robust state changes
+ * - Tuning timer parameters
+ *
+ * 27 Oct 2004: Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp>
+ * - genelized Layer 3 protocol part.
+ *
+ * Derived from net/ipv4/netfilter/ip_conntrack_proto_tcp.c
+ *
+ * version 2.2
+ */
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/timer.h>
+#include <linux/netfilter.h>
+#include <linux/module.h>
+#include <linux/in.h>
+#include <linux/tcp.h>
+#include <linux/spinlock.h>
+#include <linux/skbuff.h>
+#include <linux/ipv6.h>
+#include <net/ip6_checksum.h>
+
+#include <net/tcp.h>
+
+#include <linux/netfilter.h>
+#include <linux/netfilter_ipv4.h>
+#include <linux/netfilter_ipv6.h>
+#include <net/netfilter/nf_conntrack.h>
+#include <net/netfilter/nf_conntrack_protocol.h>
+
+#if 0
+#define DEBUGP printk
+#define DEBUGP_VARS
+#else
+#define DEBUGP(format, args...)
+#endif
+
+/* Protects conntrack->proto.tcp */
+static DEFINE_RWLOCK(tcp_lock);
+
+/* "Be conservative in what you do,
+ be liberal in what you accept from others."
+ If it's non-zero, we mark only out of window RST segments as INVALID. */
+int nf_ct_tcp_be_liberal = 0;
+
+/* When connection is picked up from the middle, how many packets are required
+ to pass in each direction when we assume we are in sync - if any side uses
+ window scaling, we lost the game.
+ If it is set to zero, we disable picking up already established
+ connections. */
+int nf_ct_tcp_loose = 3;
+
+/* Max number of the retransmitted packets without receiving an (acceptable)
+ ACK from the destination. If this number is reached, a shorter timer
+ will be started. */
+int nf_ct_tcp_max_retrans = 3;
+
+ /* FIXME: Examine ipfilter's timeouts and conntrack transitions more
+ closely. They're more complex. --RR */
+
+static const char *tcp_conntrack_names[] = {
+ "NONE",
+ "SYN_SENT",
+ "SYN_RECV",
+ "ESTABLISHED",
+ "FIN_WAIT",
+ "CLOSE_WAIT",
+ "LAST_ACK",
+ "TIME_WAIT",
+ "CLOSE",
+ "LISTEN"
+};
+
+#define SECS * HZ
+#define MINS * 60 SECS
+#define HOURS * 60 MINS
+#define DAYS * 24 HOURS
+
+unsigned long nf_ct_tcp_timeout_syn_sent = 2 MINS;
+unsigned long nf_ct_tcp_timeout_syn_recv = 60 SECS;
+unsigned long nf_ct_tcp_timeout_established = 5 DAYS;
+unsigned long nf_ct_tcp_timeout_fin_wait = 2 MINS;
+unsigned long nf_ct_tcp_timeout_close_wait = 60 SECS;
+unsigned long nf_ct_tcp_timeout_last_ack = 30 SECS;
+unsigned long nf_ct_tcp_timeout_time_wait = 2 MINS;
+unsigned long nf_ct_tcp_timeout_close = 10 SECS;
+
+/* RFC1122 says the R2 limit should be at least 100 seconds.
+ Linux uses 15 packets as limit, which corresponds
+ to ~13-30min depending on RTO. */
+unsigned long nf_ct_tcp_timeout_max_retrans = 5 MINS;
+
+static unsigned long * tcp_timeouts[]
+= { NULL, /* TCP_CONNTRACK_NONE */
+ &nf_ct_tcp_timeout_syn_sent, /* TCP_CONNTRACK_SYN_SENT, */
+ &nf_ct_tcp_timeout_syn_recv, /* TCP_CONNTRACK_SYN_RECV, */
+ &nf_ct_tcp_timeout_established, /* TCP_CONNTRACK_ESTABLISHED, */
+ &nf_ct_tcp_timeout_fin_wait, /* TCP_CONNTRACK_FIN_WAIT, */
+ &nf_ct_tcp_timeout_close_wait, /* TCP_CONNTRACK_CLOSE_WAIT, */
+ &nf_ct_tcp_timeout_last_ack, /* TCP_CONNTRACK_LAST_ACK, */
+ &nf_ct_tcp_timeout_time_wait, /* TCP_CONNTRACK_TIME_WAIT, */
+ &nf_ct_tcp_timeout_close, /* TCP_CONNTRACK_CLOSE, */
+ NULL, /* TCP_CONNTRACK_LISTEN */
+ };
+
+#define sNO TCP_CONNTRACK_NONE
+#define sSS TCP_CONNTRACK_SYN_SENT
+#define sSR TCP_CONNTRACK_SYN_RECV
+#define sES TCP_CONNTRACK_ESTABLISHED
+#define sFW TCP_CONNTRACK_FIN_WAIT
+#define sCW TCP_CONNTRACK_CLOSE_WAIT
+#define sLA TCP_CONNTRACK_LAST_ACK
+#define sTW TCP_CONNTRACK_TIME_WAIT
+#define sCL TCP_CONNTRACK_CLOSE
+#define sLI TCP_CONNTRACK_LISTEN
+#define sIV TCP_CONNTRACK_MAX
+#define sIG TCP_CONNTRACK_IGNORE
+
+/* What TCP flags are set from RST/SYN/FIN/ACK. */
+enum tcp_bit_set {
+ TCP_SYN_SET,
+ TCP_SYNACK_SET,
+ TCP_FIN_SET,
+ TCP_ACK_SET,
+ TCP_RST_SET,
+ TCP_NONE_SET,
+};
+
+/*
+ * The TCP state transition table needs a few words...
+ *
+ * We are the man in the middle. All the packets go through us
+ * but might get lost in transit to the destination.
+ * It is assumed that the destinations can't receive segments
+ * we haven't seen.
+ *
+ * The checked segment is in window, but our windows are *not*
+ * equivalent with the ones of the sender/receiver. We always
+ * try to guess the state of the current sender.
+ *
+ * The meaning of the states are:
+ *
+ * NONE: initial state
+ * SYN_SENT: SYN-only packet seen
+ * SYN_RECV: SYN-ACK packet seen
+ * ESTABLISHED: ACK packet seen
+ * FIN_WAIT: FIN packet seen
+ * CLOSE_WAIT: ACK seen (after FIN)
+ * LAST_ACK: FIN seen (after FIN)
+ * TIME_WAIT: last ACK seen
+ * CLOSE: closed connection
+ *
+ * LISTEN state is not used.
+ *
+ * Packets marked as IGNORED (sIG):
+ * if they may be either invalid or valid
+ * and the receiver may send back a connection
+ * closing RST or a SYN/ACK.
+ *
+ * Packets marked as INVALID (sIV):
+ * if they are invalid
+ * or we do not support the request (simultaneous open)
+ */
+static enum tcp_conntrack tcp_conntracks[2][6][TCP_CONNTRACK_MAX] = {
+ {
+/* ORIGINAL */
+/* sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sLI */
+/*syn*/ { sSS, sSS, sIG, sIG, sIG, sIG, sIG, sSS, sSS, sIV },
+/*
+ * sNO -> sSS Initialize a new connection
+ * sSS -> sSS Retransmitted SYN
+ * sSR -> sIG Late retransmitted SYN?
+ * sES -> sIG Error: SYNs in window outside the SYN_SENT state
+ * are errors. Receiver will reply with RST
+ * and close the connection.
+ * Or we are not in sync and hold a dead connection.
+ * sFW -> sIG
+ * sCW -> sIG
+ * sLA -> sIG
+ * sTW -> sSS Reopened connection (RFC 1122).
+ * sCL -> sSS
+ */
+/* sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sLI */
+/*synack*/ { sIV, sIV, sIV, sIV, sIV, sIV, sIV, sIV, sIV, sIV },
+/*
+ * A SYN/ACK from the client is always invalid:
+ * - either it tries to set up a simultaneous open, which is
+ * not supported;
+ * - or the firewall has just been inserted between the two hosts
+ * during the session set-up. The SYN will be retransmitted
+ * by the true client (or it'll time out).
+ */
+/* sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sLI */
+/*fin*/ { sIV, sIV, sFW, sFW, sLA, sLA, sLA, sTW, sCL, sIV },
+/*
+ * sNO -> sIV Too late and no reason to do anything...
+ * sSS -> sIV Client migth not send FIN in this state:
+ * we enforce waiting for a SYN/ACK reply first.
+ * sSR -> sFW Close started.
+ * sES -> sFW
+ * sFW -> sLA FIN seen in both directions, waiting for
+ * the last ACK.
+ * Migth be a retransmitted FIN as well...
+ * sCW -> sLA
+ * sLA -> sLA Retransmitted FIN. Remain in the same state.
+ * sTW -> sTW
+ * sCL -> sCL
+ */
+/* sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sLI */
+/*ack*/ { sES, sIV, sES, sES, sCW, sCW, sTW, sTW, sCL, sIV },
+/*
+ * sNO -> sES Assumed.
+ * sSS -> sIV ACK is invalid: we haven't seen a SYN/ACK yet.
+ * sSR -> sES Established state is reached.
+ * sES -> sES :-)
+ * sFW -> sCW Normal close request answered by ACK.
+ * sCW -> sCW
+ * sLA -> sTW Last ACK detected.
+ * sTW -> sTW Retransmitted last ACK. Remain in the same state.
+ * sCL -> sCL
+ */
+/* sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sLI */
+/*rst*/ { sIV, sCL, sCL, sCL, sCL, sCL, sCL, sCL, sCL, sIV },
+/*none*/ { sIV, sIV, sIV, sIV, sIV, sIV, sIV, sIV, sIV, sIV }
+ },
+ {
+/* REPLY */
+/* sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sLI */
+/*syn*/ { sIV, sIV, sIV, sIV, sIV, sIV, sIV, sIV, sIV, sIV },
+/*
+ * sNO -> sIV Never reached.
+ * sSS -> sIV Simultaneous open, not supported
+ * sSR -> sIV Simultaneous open, not supported.
+ * sES -> sIV Server may not initiate a connection.
+ * sFW -> sIV
+ * sCW -> sIV
+ * sLA -> sIV
+ * sTW -> sIV Reopened connection, but server may not do it.
+ * sCL -> sIV
+ */
+/* sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sLI */
+/*synack*/ { sIV, sSR, sSR, sIG, sIG, sIG, sIG, sIG, sIG, sIV },
+/*
+ * sSS -> sSR Standard open.
+ * sSR -> sSR Retransmitted SYN/ACK.
+ * sES -> sIG Late retransmitted SYN/ACK?
+ * sFW -> sIG Might be SYN/ACK answering ignored SYN
+ * sCW -> sIG
+ * sLA -> sIG
+ * sTW -> sIG
+ * sCL -> sIG
+ */
+/* sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sLI */
+/*fin*/ { sIV, sIV, sFW, sFW, sLA, sLA, sLA, sTW, sCL, sIV },
+/*
+ * sSS -> sIV Server might not send FIN in this state.
+ * sSR -> sFW Close started.
+ * sES -> sFW
+ * sFW -> sLA FIN seen in both directions.
+ * sCW -> sLA
+ * sLA -> sLA Retransmitted FIN.
+ * sTW -> sTW
+ * sCL -> sCL
+ */
+/* sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sLI */
+/*ack*/ { sIV, sIV, sSR, sES, sCW, sCW, sTW, sTW, sCL, sIV },
+/*
+ * sSS -> sIV Might be a half-open connection.
+ * sSR -> sSR Might answer late resent SYN.
+ * sES -> sES :-)
+ * sFW -> sCW Normal close request answered by ACK.
+ * sCW -> sCW
+ * sLA -> sTW Last ACK detected.
+ * sTW -> sTW Retransmitted last ACK.
+ * sCL -> sCL
+ */
+/* sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sLI */
+/*rst*/ { sIV, sCL, sCL, sCL, sCL, sCL, sCL, sCL, sCL, sIV },
+/*none*/ { sIV, sIV, sIV, sIV, sIV, sIV, sIV, sIV, sIV, sIV }
+ }
+};
+
+static int tcp_pkt_to_tuple(const struct sk_buff *skb,
+ unsigned int dataoff,
+ struct nf_conntrack_tuple *tuple)
+{
+ struct tcphdr _hdr, *hp;
+
+ /* Actually only need first 8 bytes. */
+ hp = skb_header_pointer(skb, dataoff, 8, &_hdr);
+ if (hp == NULL)
+ return 0;
+
+ tuple->src.u.tcp.port = hp->source;
+ tuple->dst.u.tcp.port = hp->dest;
+
+ return 1;
+}
+
+static int tcp_invert_tuple(struct nf_conntrack_tuple *tuple,
+ const struct nf_conntrack_tuple *orig)
+{
+ tuple->src.u.tcp.port = orig->dst.u.tcp.port;
+ tuple->dst.u.tcp.port = orig->src.u.tcp.port;
+ return 1;
+}
+
+/* Print out the per-protocol part of the tuple. */
+static int tcp_print_tuple(struct seq_file *s,
+ const struct nf_conntrack_tuple *tuple)
+{
+ return seq_printf(s, "sport=%hu dport=%hu ",
+ ntohs(tuple->src.u.tcp.port),
+ ntohs(tuple->dst.u.tcp.port));
+}
+
+/* Print out the private part of the conntrack. */
+static int tcp_print_conntrack(struct seq_file *s,
+ const struct nf_conn *conntrack)
+{
+ enum tcp_conntrack state;
+
+ read_lock_bh(&tcp_lock);
+ state = conntrack->proto.tcp.state;
+ read_unlock_bh(&tcp_lock);
+
+ return seq_printf(s, "%s ", tcp_conntrack_names[state]);
+}
+
+static unsigned int get_conntrack_index(const struct tcphdr *tcph)
+{
+ if (tcph->rst) return TCP_RST_SET;
+ else if (tcph->syn) return (tcph->ack ? TCP_SYNACK_SET : TCP_SYN_SET);
+ else if (tcph->fin) return TCP_FIN_SET;
+ else if (tcph->ack) return TCP_ACK_SET;
+ else return TCP_NONE_SET;
+}
+
+/* TCP connection tracking based on 'Real Stateful TCP Packet Filtering
+ in IP Filter' by Guido van Rooij.
+
+ http://www.nluug.nl/events/sane2000/papers.html
+ http://www.iae.nl/users/guido/papers/tcp_filtering.ps.gz
+
+ The boundaries and the conditions are changed according to RFC793:
+ the packet must intersect the window (i.e. segments may be
+ after the right or before the left edge) and thus receivers may ACK
+ segments after the right edge of the window.
+
+ td_maxend = max(sack + max(win,1)) seen in reply packets
+ td_maxwin = max(max(win, 1)) + (sack - ack) seen in sent packets
+ td_maxwin += seq + len - sender.td_maxend
+ if seq + len > sender.td_maxend
+ td_end = max(seq + len) seen in sent packets
+
+ I. Upper bound for valid data: seq <= sender.td_maxend
+ II. Lower bound for valid data: seq + len >= sender.td_end - receiver.td_maxwin
+ III. Upper bound for valid ack: sack <= receiver.td_end
+ IV. Lower bound for valid ack: ack >= receiver.td_end - MAXACKWINDOW
+
+ where sack is the highest right edge of sack block found in the packet.
+
+ The upper bound limit for a valid ack is not ignored -
+ we doesn't have to deal with fragments.
+*/
+
+static inline __u32 segment_seq_plus_len(__u32 seq,
+ size_t len,
+ unsigned int dataoff,
+ struct tcphdr *tcph)
+{
+ /* XXX Should I use payload length field in IP/IPv6 header ?
+ * - YK */
+ return (seq + len - dataoff - tcph->doff*4
+ + (tcph->syn ? 1 : 0) + (tcph->fin ? 1 : 0));
+}
+
+/* Fixme: what about big packets? */
+#define MAXACKWINCONST 66000
+#define MAXACKWINDOW(sender) \
+ ((sender)->td_maxwin > MAXACKWINCONST ? (sender)->td_maxwin \
+ : MAXACKWINCONST)
+
+/*
+ * Simplified tcp_parse_options routine from tcp_input.c
+ */
+static void tcp_options(const struct sk_buff *skb,
+ unsigned int dataoff,
+ struct tcphdr *tcph,
+ struct ip_ct_tcp_state *state)
+{
+ unsigned char buff[(15 * 4) - sizeof(struct tcphdr)];
+ unsigned char *ptr;
+ int length = (tcph->doff*4) - sizeof(struct tcphdr);
+
+ if (!length)
+ return;
+
+ ptr = skb_header_pointer(skb, dataoff + sizeof(struct tcphdr),
+ length, buff);
+ BUG_ON(ptr == NULL);
+
+ state->td_scale =
+ state->flags = 0;
+
+ while (length > 0) {
+ int opcode=*ptr++;
+ int opsize;
+
+ switch (opcode) {
+ case TCPOPT_EOL:
+ return;
+ case TCPOPT_NOP: /* Ref: RFC 793 section 3.1 */
+ length--;
+ continue;
+ default:
+ opsize=*ptr++;
+ if (opsize < 2) /* "silly options" */
+ return;
+ if (opsize > length)
+ break; /* don't parse partial options */
+
+ if (opcode == TCPOPT_SACK_PERM
+ && opsize == TCPOLEN_SACK_PERM)
+ state->flags |= IP_CT_TCP_FLAG_SACK_PERM;
+ else if (opcode == TCPOPT_WINDOW
+ && opsize == TCPOLEN_WINDOW) {
+ state->td_scale = *(u_int8_t *)ptr;
+
+ if (state->td_scale > 14) {
+ /* See RFC1323 */
+ state->td_scale = 14;
+ }
+ state->flags |=
+ IP_CT_TCP_FLAG_WINDOW_SCALE;
+ }
+ ptr += opsize - 2;
+ length -= opsize;
+ }
+ }
+}
+
+static void tcp_sack(const struct sk_buff *skb, unsigned int dataoff,
+ struct tcphdr *tcph, __u32 *sack)
+{
+ unsigned char buff[(15 * 4) - sizeof(struct tcphdr)];
+ unsigned char *ptr;
+ int length = (tcph->doff*4) - sizeof(struct tcphdr);
+ __u32 tmp;
+
+ if (!length)
+ return;
+
+ ptr = skb_header_pointer(skb, dataoff + sizeof(struct tcphdr),
+ length, buff);
+ BUG_ON(ptr == NULL);
+
+ /* Fast path for timestamp-only option */
+ if (length == TCPOLEN_TSTAMP_ALIGNED*4
+ && *(__u32 *)ptr ==
+ __constant_ntohl((TCPOPT_NOP << 24)
+ | (TCPOPT_NOP << 16)
+ | (TCPOPT_TIMESTAMP << 8)
+ | TCPOLEN_TIMESTAMP))
+ return;
+
+ while (length > 0) {
+ int opcode = *ptr++;
+ int opsize, i;
+
+ switch (opcode) {
+ case TCPOPT_EOL:
+ return;
+ case TCPOPT_NOP: /* Ref: RFC 793 section 3.1 */
+ length--;
+ continue;
+ default:
+ opsize = *ptr++;
+ if (opsize < 2) /* "silly options" */
+ return;
+ if (opsize > length)
+ break; /* don't parse partial options */
+
+ if (opcode == TCPOPT_SACK
+ && opsize >= (TCPOLEN_SACK_BASE
+ + TCPOLEN_SACK_PERBLOCK)
+ && !((opsize - TCPOLEN_SACK_BASE)
+ % TCPOLEN_SACK_PERBLOCK)) {
+ for (i = 0;
+ i < (opsize - TCPOLEN_SACK_BASE);
+ i += TCPOLEN_SACK_PERBLOCK) {
+ memcpy(&tmp, (__u32 *)(ptr + i) + 1,
+ sizeof(__u32));
+ tmp = ntohl(tmp);
+
+ if (after(tmp, *sack))
+ *sack = tmp;
+ }
+ return;
+ }
+ ptr += opsize - 2;
+ length -= opsize;
+ }
+ }
+}
+
+static int tcp_in_window(struct ip_ct_tcp *state,
+ enum ip_conntrack_dir dir,
+ unsigned int index,
+ const struct sk_buff *skb,
+ unsigned int dataoff,
+ struct tcphdr *tcph,
+ int pf)
+{
+ struct ip_ct_tcp_state *sender = &state->seen[dir];
+ struct ip_ct_tcp_state *receiver = &state->seen[!dir];
+ __u32 seq, ack, sack, end, win, swin;
+ int res;
+
+ /*
+ * Get the required data from the packet.
+ */
+ seq = ntohl(tcph->seq);
+ ack = sack = ntohl(tcph->ack_seq);
+ win = ntohs(tcph->window);
+ end = segment_seq_plus_len(seq, skb->len, dataoff, tcph);
+
+ if (receiver->flags & IP_CT_TCP_FLAG_SACK_PERM)
+ tcp_sack(skb, dataoff, tcph, &sack);
+
+ DEBUGP("tcp_in_window: START\n");
+ DEBUGP("tcp_in_window: src=%u.%u.%u.%u:%hu dst=%u.%u.%u.%u:%hu "
+ "seq=%u ack=%u sack=%u win=%u end=%u\n",
+ NIPQUAD(iph->saddr), ntohs(tcph->source),
+ NIPQUAD(iph->daddr), ntohs(tcph->dest),
+ seq, ack, sack, win, end);
+ DEBUGP("tcp_in_window: sender end=%u maxend=%u maxwin=%u scale=%i "
+ "receiver end=%u maxend=%u maxwin=%u scale=%i\n",
+ sender->td_end, sender->td_maxend, sender->td_maxwin,
+ sender->td_scale,
+ receiver->td_end, receiver->td_maxend, receiver->td_maxwin,
+ receiver->td_scale);
+
+ if (sender->td_end == 0) {
+ /*
+ * Initialize sender data.
+ */
+ if (tcph->syn && tcph->ack) {
+ /*
+ * Outgoing SYN-ACK in reply to a SYN.
+ */
+ sender->td_end =
+ sender->td_maxend = end;
+ sender->td_maxwin = (win == 0 ? 1 : win);
+
+ tcp_options(skb, dataoff, tcph, sender);
+ /*
+ * RFC 1323:
+ * Both sides must send the Window Scale option
+ * to enable window scaling in either direction.
+ */
+ if (!(sender->flags & IP_CT_TCP_FLAG_WINDOW_SCALE
+ && receiver->flags & IP_CT_TCP_FLAG_WINDOW_SCALE))
+ sender->td_scale =
+ receiver->td_scale = 0;
+ } else {
+ /*
+ * We are in the middle of a connection,
+ * its history is lost for us.
+ * Let's try to use the data from the packet.
+ */
+ sender->td_end = end;
+ sender->td_maxwin = (win == 0 ? 1 : win);
+ sender->td_maxend = end + sender->td_maxwin;
+ }
+ } else if (((state->state == TCP_CONNTRACK_SYN_SENT
+ && dir == IP_CT_DIR_ORIGINAL)
+ || (state->state == TCP_CONNTRACK_SYN_RECV
+ && dir == IP_CT_DIR_REPLY))
+ && after(end, sender->td_end)) {
+ /*
+ * RFC 793: "if a TCP is reinitialized ... then it need
+ * not wait at all; it must only be sure to use sequence
+ * numbers larger than those recently used."
+ */
+ sender->td_end =
+ sender->td_maxend = end;
+ sender->td_maxwin = (win == 0 ? 1 : win);
+
+ tcp_options(skb, dataoff, tcph, sender);
+ }
+
+ if (!(tcph->ack)) {
+ /*
+ * If there is no ACK, just pretend it was set and OK.
+ */
+ ack = sack = receiver->td_end;
+ } else if (((tcp_flag_word(tcph) & (TCP_FLAG_ACK|TCP_FLAG_RST)) ==
+ (TCP_FLAG_ACK|TCP_FLAG_RST))
+ && (ack == 0)) {
+ /*
+ * Broken TCP stacks, that set ACK in RST packets as well
+ * with zero ack value.
+ */
+ ack = sack = receiver->td_end;
+ }
+
+ if (seq == end
+ && (!tcph->rst
+ || (seq == 0 && state->state == TCP_CONNTRACK_SYN_SENT)))
+ /*
+ * Packets contains no data: we assume it is valid
+ * and check the ack value only.
+ * However RST segments are always validated by their
+ * SEQ number, except when seq == 0 (reset sent answering
+ * SYN.
+ */
+ seq = end = sender->td_end;
+
+ DEBUGP("tcp_in_window: src=%u.%u.%u.%u:%hu dst=%u.%u.%u.%u:%hu "
+ "seq=%u ack=%u sack =%u win=%u end=%u\n",
+ NIPQUAD(iph->saddr), ntohs(tcph->source),
+ NIPQUAD(iph->daddr), ntohs(tcph->dest),
+ seq, ack, sack, win, end);
+ DEBUGP("tcp_in_window: sender end=%u maxend=%u maxwin=%u scale=%i "
+ "receiver end=%u maxend=%u maxwin=%u scale=%i\n",
+ sender->td_end, sender->td_maxend, sender->td_maxwin,
+ sender->td_scale,
+ receiver->td_end, receiver->td_maxend, receiver->td_maxwin,
+ receiver->td_scale);
+
+ DEBUGP("tcp_in_window: I=%i II=%i III=%i IV=%i\n",
+ before(seq, sender->td_maxend + 1),
+ after(end, sender->td_end - receiver->td_maxwin - 1),
+ before(sack, receiver->td_end + 1),
+ after(ack, receiver->td_end - MAXACKWINDOW(sender)));
+
+ if (sender->loose || receiver->loose ||
+ (before(seq, sender->td_maxend + 1) &&
+ after(end, sender->td_end - receiver->td_maxwin - 1) &&
+ before(sack, receiver->td_end + 1) &&
+ after(ack, receiver->td_end - MAXACKWINDOW(sender)))) {
+ /*
+ * Take into account window scaling (RFC 1323).
+ */
+ if (!tcph->syn)
+ win <<= sender->td_scale;
+
+ /*
+ * Update sender data.
+ */
+ swin = win + (sack - ack);
+ if (sender->td_maxwin < swin)
+ sender->td_maxwin = swin;
+ if (after(end, sender->td_end))
+ sender->td_end = end;
+ /*
+ * Update receiver data.
+ */
+ if (after(end, sender->td_maxend))
+ receiver->td_maxwin += end - sender->td_maxend;
+ if (after(sack + win, receiver->td_maxend - 1)) {
+ receiver->td_maxend = sack + win;
+ if (win == 0)
+ receiver->td_maxend++;
+ }
+
+ /*
+ * Check retransmissions.
+ */
+ if (index == TCP_ACK_SET) {
+ if (state->last_dir == dir
+ && state->last_seq == seq
+ && state->last_ack == ack
+ && state->last_end == end)
+ state->retrans++;
+ else {
+ state->last_dir = dir;
+ state->last_seq = seq;
+ state->last_ack = ack;
+ state->last_end = end;
+ state->retrans = 0;
+ }
+ }
+ /*
+ * Close the window of disabled window tracking :-)
+ */
+ if (sender->loose)
+ sender->loose--;
+
+ res = 1;
+ } else {
+ if (LOG_INVALID(IPPROTO_TCP))
+ nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
+ "nf_ct_tcp: %s ",
+ before(seq, sender->td_maxend + 1) ?
+ after(end, sender->td_end - receiver->td_maxwin - 1) ?
+ before(sack, receiver->td_end + 1) ?
+ after(ack, receiver->td_end - MAXACKWINDOW(sender)) ? "BUG"
+ : "ACK is under the lower bound (possible overly delayed ACK)"
+ : "ACK is over the upper bound (ACKed data not seen yet)"
+ : "SEQ is under the lower bound (already ACKed data retransmitted)"
+ : "SEQ is over the upper bound (over the window of the receiver)");
+
+ res = nf_ct_tcp_be_liberal;
+ }
+
+ DEBUGP("tcp_in_window: res=%i sender end=%u maxend=%u maxwin=%u "
+ "receiver end=%u maxend=%u maxwin=%u\n",
+ res, sender->td_end, sender->td_maxend, sender->td_maxwin,
+ receiver->td_end, receiver->td_maxend, receiver->td_maxwin);
+
+ return res;
+}
+
+#ifdef CONFIG_IP_NF_NAT_NEEDED
+/* Update sender->td_end after NAT successfully mangled the packet */
+/* Caller must linearize skb at tcp header. */
+void nf_conntrack_tcp_update(struct sk_buff *skb,
+ unsigned int dataoff,
+ struct nf_conn *conntrack,
+ int dir)
+{
+ struct tcphdr *tcph = (void *)skb->data + dataoff;
+ __u32 end;
+#ifdef DEBUGP_VARS
+ struct ip_ct_tcp_state *sender = &conntrack->proto.tcp.seen[dir];
+ struct ip_ct_tcp_state *receiver = &conntrack->proto.tcp.seen[!dir];
+#endif
+
+ end = segment_seq_plus_len(ntohl(tcph->seq), skb->len, dataoff, tcph);
+
+ write_lock_bh(&tcp_lock);
+ /*
+ * We have to worry for the ack in the reply packet only...
+ */
+ if (after(end, conntrack->proto.tcp.seen[dir].td_end))
+ conntrack->proto.tcp.seen[dir].td_end = end;
+ conntrack->proto.tcp.last_end = end;
+ write_unlock_bh(&tcp_lock);
+ DEBUGP("tcp_update: sender end=%u maxend=%u maxwin=%u scale=%i "
+ "receiver end=%u maxend=%u maxwin=%u scale=%i\n",
+ sender->td_end, sender->td_maxend, sender->td_maxwin,
+ sender->td_scale,
+ receiver->td_end, receiver->td_maxend, receiver->td_maxwin,
+ receiver->td_scale);
+}
+
+#endif
+
+#define TH_FIN 0x01
+#define TH_SYN 0x02
+#define TH_RST 0x04
+#define TH_PUSH 0x08
+#define TH_ACK 0x10
+#define TH_URG 0x20
+#define TH_ECE 0x40
+#define TH_CWR 0x80
+
+/* table of valid flag combinations - ECE and CWR are always valid */
+static u8 tcp_valid_flags[(TH_FIN|TH_SYN|TH_RST|TH_PUSH|TH_ACK|TH_URG) + 1] =
+{
+ [TH_SYN] = 1,
+ [TH_SYN|TH_ACK] = 1,
+ [TH_SYN|TH_ACK|TH_PUSH] = 1,
+ [TH_RST] = 1,
+ [TH_RST|TH_ACK] = 1,
+ [TH_RST|TH_ACK|TH_PUSH] = 1,
+ [TH_FIN|TH_ACK] = 1,
+ [TH_ACK] = 1,
+ [TH_ACK|TH_PUSH] = 1,
+ [TH_ACK|TH_URG] = 1,
+ [TH_ACK|TH_URG|TH_PUSH] = 1,
+ [TH_FIN|TH_ACK|TH_PUSH] = 1,
+ [TH_FIN|TH_ACK|TH_URG] = 1,
+ [TH_FIN|TH_ACK|TH_URG|TH_PUSH] = 1,
+};
+
+/* Protect conntrack agaist broken packets. Code taken from ipt_unclean.c. */
+static int tcp_error(struct sk_buff *skb,
+ unsigned int dataoff,
+ enum ip_conntrack_info *ctinfo,
+ int pf,
+ unsigned int hooknum,
+ int(*csum)(const struct sk_buff *,unsigned int))
+{
+ struct tcphdr _tcph, *th;
+ unsigned int tcplen = skb->len - dataoff;
+ u_int8_t tcpflags;
+
+ /* Smaller that minimal TCP header? */
+ th = skb_header_pointer(skb, dataoff, sizeof(_tcph), &_tcph);
+ if (th == NULL) {
+ if (LOG_INVALID(IPPROTO_TCP))
+ nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
+ "nf_ct_tcp: short packet ");
+ return -NF_ACCEPT;
+ }
+
+ /* Not whole TCP header or malformed packet */
+ if (th->doff*4 < sizeof(struct tcphdr) || tcplen < th->doff*4) {
+ if (LOG_INVALID(IPPROTO_TCP))
+ nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
+ "nf_ct_tcp: truncated/malformed packet ");
+ return -NF_ACCEPT;
+ }
+
+ /* Checksum invalid? Ignore.
+ * We skip checking packets on the outgoing path
+ * because the semantic of CHECKSUM_HW is different there
+ * and moreover root might send raw packets.
+ */
+ /* FIXME: Source route IP option packets --RR */
+ if (((pf == PF_INET && hooknum == NF_IP_PRE_ROUTING) ||
+ (pf == PF_INET6 && hooknum == NF_IP6_PRE_ROUTING))
+ && skb->ip_summed != CHECKSUM_UNNECESSARY
+ && csum(skb, dataoff)) {
+ if (LOG_INVALID(IPPROTO_TCP))
+ nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
+ "nf_ct_tcp: bad TCP checksum ");
+ return -NF_ACCEPT;
+ }
+
+ /* Check TCP flags. */
+ tcpflags = (((u_int8_t *)th)[13] & ~(TH_ECE|TH_CWR));
+ if (!tcp_valid_flags[tcpflags]) {
+ if (LOG_INVALID(IPPROTO_TCP))
+ nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
+ "nf_ct_tcp: invalid TCP flag combination ");
+ return -NF_ACCEPT;
+ }
+
+ return NF_ACCEPT;
+}
+
+static int csum4(const struct sk_buff *skb, unsigned int dataoff)
+{
+ return csum_tcpudp_magic(skb->nh.iph->saddr, skb->nh.iph->daddr,
+ skb->len - dataoff, IPPROTO_TCP,
+ skb->ip_summed == CHECKSUM_HW ? skb->csum
+ : skb_checksum(skb, dataoff,
+ skb->len - dataoff, 0));
+}
+
+static int csum6(const struct sk_buff *skb, unsigned int dataoff)
+{
+ return csum_ipv6_magic(&skb->nh.ipv6h->saddr, &skb->nh.ipv6h->daddr,
+ skb->len - dataoff, IPPROTO_TCP,
+ skb->ip_summed == CHECKSUM_HW ? skb->csum
+ : skb_checksum(skb, dataoff, skb->len - dataoff,
+ 0));
+}
+
+static int tcp_error4(struct sk_buff *skb,
+ unsigned int dataoff,
+ enum ip_conntrack_info *ctinfo,
+ int pf,
+ unsigned int hooknum)
+{
+ return tcp_error(skb, dataoff, ctinfo, pf, hooknum, csum4);
+}
+
+static int tcp_error6(struct sk_buff *skb,
+ unsigned int dataoff,
+ enum ip_conntrack_info *ctinfo,
+ int pf,
+ unsigned int hooknum)
+{
+ return tcp_error(skb, dataoff, ctinfo, pf, hooknum, csum6);
+}
+
+/* Returns verdict for packet, or -1 for invalid. */
+static int tcp_packet(struct nf_conn *conntrack,
+ const struct sk_buff *skb,
+ unsigned int dataoff,
+ enum ip_conntrack_info ctinfo,
+ int pf,
+ unsigned int hooknum)
+{
+ enum tcp_conntrack new_state, old_state;
+ enum ip_conntrack_dir dir;
+ struct tcphdr *th, _tcph;
+ unsigned long timeout;
+ unsigned int index;
+
+ th = skb_header_pointer(skb, dataoff, sizeof(_tcph), &_tcph);
+ BUG_ON(th == NULL);
+
+ write_lock_bh(&tcp_lock);
+ old_state = conntrack->proto.tcp.state;
+ dir = CTINFO2DIR(ctinfo);
+ index = get_conntrack_index(th);
+ new_state = tcp_conntracks[dir][index][old_state];
+
+ switch (new_state) {
+ case TCP_CONNTRACK_IGNORE:
+ /* Either SYN in ORIGINAL
+ * or SYN/ACK in REPLY. */
+ if (index == TCP_SYNACK_SET
+ && conntrack->proto.tcp.last_index == TCP_SYN_SET
+ && conntrack->proto.tcp.last_dir != dir
+ && ntohl(th->ack_seq) ==
+ conntrack->proto.tcp.last_end) {
+ /* This SYN/ACK acknowledges a SYN that we earlier
+ * ignored as invalid. This means that the client and
+ * the server are both in sync, while the firewall is
+ * not. We kill this session and block the SYN/ACK so
+ * that the client cannot but retransmit its SYN and
+ * thus initiate a clean new session.
+ */
+ write_unlock_bh(&tcp_lock);
+ if (LOG_INVALID(IPPROTO_TCP))
+ nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
+ "nf_ct_tcp: killing out of sync session ");
+ if (del_timer(&conntrack->timeout))
+ conntrack->timeout.function((unsigned long)
+ conntrack);
+ return -NF_DROP;
+ }
+ conntrack->proto.tcp.last_index = index;
+ conntrack->proto.tcp.last_dir = dir;
+ conntrack->proto.tcp.last_seq = ntohl(th->seq);
+ conntrack->proto.tcp.last_end =
+ segment_seq_plus_len(ntohl(th->seq), skb->len, dataoff, th);
+
+ write_unlock_bh(&tcp_lock);
+ if (LOG_INVALID(IPPROTO_TCP))
+ nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
+ "nf_ct_tcp: invalid packed ignored ");
+ return NF_ACCEPT;
+ case TCP_CONNTRACK_MAX:
+ /* Invalid packet */
+ DEBUGP("nf_ct_tcp: Invalid dir=%i index=%u ostate=%u\n",
+ dir, get_conntrack_index(th),
+ old_state);
+ write_unlock_bh(&tcp_lock);
+ if (LOG_INVALID(IPPROTO_TCP))
+ nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
+ "nf_ct_tcp: invalid state ");
+ return -NF_ACCEPT;
+ case TCP_CONNTRACK_SYN_SENT:
+ if (old_state < TCP_CONNTRACK_TIME_WAIT)
+ break;
+ if ((conntrack->proto.tcp.seen[dir].flags &
+ IP_CT_TCP_FLAG_CLOSE_INIT)
+ || after(ntohl(th->seq),
+ conntrack->proto.tcp.seen[dir].td_end)) {
+ /* Attempt to reopen a closed connection.
+ * Delete this connection and look up again. */
+ write_unlock_bh(&tcp_lock);
+ if (del_timer(&conntrack->timeout))
+ conntrack->timeout.function((unsigned long)
+ conntrack);
+ return -NF_REPEAT;
+ }
+ case TCP_CONNTRACK_CLOSE:
+ if (index == TCP_RST_SET
+ && test_bit(IPS_SEEN_REPLY_BIT, &conntrack->status)
+ && conntrack->proto.tcp.last_index == TCP_SYN_SET
+ && ntohl(th->ack_seq) == conntrack->proto.tcp.last_end) {
+ /* RST sent to invalid SYN we had let trough
+ * SYN was in window then, tear down connection.
+ * We skip window checking, because packet might ACK
+ * segments we ignored in the SYN. */
+ goto in_window;
+ }
+ /* Just fall trough */
+ default:
+ /* Keep compilers happy. */
+ break;
+ }
+
+ if (!tcp_in_window(&conntrack->proto.tcp, dir, index,
+ skb, dataoff, th, pf)) {
+ write_unlock_bh(&tcp_lock);
+ return -NF_ACCEPT;
+ }
+ in_window:
+ /* From now on we have got in-window packets */
+ conntrack->proto.tcp.last_index = index;
+
+ DEBUGP("tcp_conntracks: src=%u.%u.%u.%u:%hu dst=%u.%u.%u.%u:%hu "
+ "syn=%i ack=%i fin=%i rst=%i old=%i new=%i\n",
+ NIPQUAD(iph->saddr), ntohs(th->source),
+ NIPQUAD(iph->daddr), ntohs(th->dest),
+ (th->syn ? 1 : 0), (th->ack ? 1 : 0),
+ (th->fin ? 1 : 0), (th->rst ? 1 : 0),
+ old_state, new_state);
+
+ conntrack->proto.tcp.state = new_state;
+ if (old_state != new_state
+ && (new_state == TCP_CONNTRACK_FIN_WAIT
+ || new_state == TCP_CONNTRACK_CLOSE))
+ conntrack->proto.tcp.seen[dir].flags |= IP_CT_TCP_FLAG_CLOSE_INIT;
+ timeout = conntrack->proto.tcp.retrans >= nf_ct_tcp_max_retrans
+ && *tcp_timeouts[new_state] > nf_ct_tcp_timeout_max_retrans
+ ? nf_ct_tcp_timeout_max_retrans : *tcp_timeouts[new_state];
+ write_unlock_bh(&tcp_lock);
+
+ nf_conntrack_event_cache(IPCT_PROTOINFO_VOLATILE, skb);
+ if (new_state != old_state)
+ nf_conntrack_event_cache(IPCT_PROTOINFO, skb);
+
+ if (!test_bit(IPS_SEEN_REPLY_BIT, &conntrack->status)) {
+ /* If only reply is a RST, we can consider ourselves not to
+ have an established connection: this is a fairly common
+ problem case, so we can delete the conntrack
+ immediately. --RR */
+ if (th->rst) {
+ if (del_timer(&conntrack->timeout))
+ conntrack->timeout.function((unsigned long)
+ conntrack);
+ return NF_ACCEPT;
+ }
+ } else if (!test_bit(IPS_ASSURED_BIT, &conntrack->status)
+ && (old_state == TCP_CONNTRACK_SYN_RECV
+ || old_state == TCP_CONNTRACK_ESTABLISHED)
+ && new_state == TCP_CONNTRACK_ESTABLISHED) {
+ /* Set ASSURED if we see see valid ack in ESTABLISHED
+ after SYN_RECV or a valid answer for a picked up
+ connection. */
+ set_bit(IPS_ASSURED_BIT, &conntrack->status);
+ nf_conntrack_event_cache(IPCT_STATUS, skb);
+ }
+ nf_ct_refresh_acct(conntrack, ctinfo, skb, timeout);
+
+ return NF_ACCEPT;
+}
+
+/* Called when a new connection for this protocol found. */
+static int tcp_new(struct nf_conn *conntrack,
+ const struct sk_buff *skb,
+ unsigned int dataoff)
+{
+ enum tcp_conntrack new_state;
+ struct tcphdr *th, _tcph;
+#ifdef DEBUGP_VARS
+ struct ip_ct_tcp_state *sender = &conntrack->proto.tcp.seen[0];
+ struct ip_ct_tcp_state *receiver = &conntrack->proto.tcp.seen[1];
+#endif
+
+ th = skb_header_pointer(skb, dataoff, sizeof(_tcph), &_tcph);
+ BUG_ON(th == NULL);
+
+ /* Don't need lock here: this conntrack not in circulation yet */
+ new_state
+ = tcp_conntracks[0][get_conntrack_index(th)]
+ [TCP_CONNTRACK_NONE];
+
+ /* Invalid: delete conntrack */
+ if (new_state >= TCP_CONNTRACK_MAX) {
+ DEBUGP("nf_ct_tcp: invalid new deleting.\n");
+ return 0;
+ }
+
+ if (new_state == TCP_CONNTRACK_SYN_SENT) {
+ /* SYN packet */
+ conntrack->proto.tcp.seen[0].td_end =
+ segment_seq_plus_len(ntohl(th->seq), skb->len,
+ dataoff, th);
+ conntrack->proto.tcp.seen[0].td_maxwin = ntohs(th->window);
+ if (conntrack->proto.tcp.seen[0].td_maxwin == 0)
+ conntrack->proto.tcp.seen[0].td_maxwin = 1;
+ conntrack->proto.tcp.seen[0].td_maxend =
+ conntrack->proto.tcp.seen[0].td_end;
+
+ tcp_options(skb, dataoff, th, &conntrack->proto.tcp.seen[0]);
+ conntrack->proto.tcp.seen[1].flags = 0;
+ conntrack->proto.tcp.seen[0].loose =
+ conntrack->proto.tcp.seen[1].loose = 0;
+ } else if (nf_ct_tcp_loose == 0) {
+ /* Don't try to pick up connections. */
+ return 0;
+ } else {
+ /*
+ * We are in the middle of a connection,
+ * its history is lost for us.
+ * Let's try to use the data from the packet.
+ */
+ conntrack->proto.tcp.seen[0].td_end =
+ segment_seq_plus_len(ntohl(th->seq), skb->len,
+ dataoff, th);
+ conntrack->proto.tcp.seen[0].td_maxwin = ntohs(th->window);
+ if (conntrack->proto.tcp.seen[0].td_maxwin == 0)
+ conntrack->proto.tcp.seen[0].td_maxwin = 1;
+ conntrack->proto.tcp.seen[0].td_maxend =
+ conntrack->proto.tcp.seen[0].td_end +
+ conntrack->proto.tcp.seen[0].td_maxwin;
+ conntrack->proto.tcp.seen[0].td_scale = 0;
+
+ /* We assume SACK. Should we assume window scaling too? */
+ conntrack->proto.tcp.seen[0].flags =
+ conntrack->proto.tcp.seen[1].flags = IP_CT_TCP_FLAG_SACK_PERM;
+ conntrack->proto.tcp.seen[0].loose =
+ conntrack->proto.tcp.seen[1].loose = nf_ct_tcp_loose;
+ }
+
+ conntrack->proto.tcp.seen[1].td_end = 0;
+ conntrack->proto.tcp.seen[1].td_maxend = 0;
+ conntrack->proto.tcp.seen[1].td_maxwin = 1;
+ conntrack->proto.tcp.seen[1].td_scale = 0;
+
+ /* tcp_packet will set them */
+ conntrack->proto.tcp.state = TCP_CONNTRACK_NONE;
+ conntrack->proto.tcp.last_index = TCP_NONE_SET;
+
+ DEBUGP("tcp_new: sender end=%u maxend=%u maxwin=%u scale=%i "
+ "receiver end=%u maxend=%u maxwin=%u scale=%i\n",
+ sender->td_end, sender->td_maxend, sender->td_maxwin,
+ sender->td_scale,
+ receiver->td_end, receiver->td_maxend, receiver->td_maxwin,
+ receiver->td_scale);
+ return 1;
+}
+
+struct nf_conntrack_protocol nf_conntrack_protocol_tcp4 =
+{
+ .l3proto = PF_INET,
+ .proto = IPPROTO_TCP,
+ .name = "tcp",
+ .pkt_to_tuple = tcp_pkt_to_tuple,
+ .invert_tuple = tcp_invert_tuple,
+ .print_tuple = tcp_print_tuple,
+ .print_conntrack = tcp_print_conntrack,
+ .packet = tcp_packet,
+ .new = tcp_new,
+ .error = tcp_error4,
+};
+
+struct nf_conntrack_protocol nf_conntrack_protocol_tcp6 =
+{
+ .l3proto = PF_INET6,
+ .proto = IPPROTO_TCP,
+ .name = "tcp",
+ .pkt_to_tuple = tcp_pkt_to_tuple,
+ .invert_tuple = tcp_invert_tuple,
+ .print_tuple = tcp_print_tuple,
+ .print_conntrack = tcp_print_conntrack,
+ .packet = tcp_packet,
+ .new = tcp_new,
+ .error = tcp_error6,
+};
+
+EXPORT_SYMBOL(nf_conntrack_protocol_tcp4);
+EXPORT_SYMBOL(nf_conntrack_protocol_tcp6);
diff --git a/net/netfilter/nf_conntrack_proto_udp.c b/net/netfilter/nf_conntrack_proto_udp.c
new file mode 100644
index 000000000000..3cae7ce420dd
--- /dev/null
+++ b/net/netfilter/nf_conntrack_proto_udp.c
@@ -0,0 +1,216 @@
+/* (C) 1999-2001 Paul `Rusty' Russell
+ * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.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.
+ *
+ * 16 Dec 2003: Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp>
+ * - enable working with Layer 3 protocol independent connection tracking.
+ *
+ * Derived from net/ipv4/netfilter/ip_conntrack_proto_udp.c
+ */
+
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/timer.h>
+#include <linux/module.h>
+#include <linux/netfilter.h>
+#include <linux/udp.h>
+#include <linux/seq_file.h>
+#include <linux/skbuff.h>
+#include <linux/ipv6.h>
+#include <net/ip6_checksum.h>
+#include <net/checksum.h>
+#include <linux/netfilter.h>
+#include <linux/netfilter_ipv4.h>
+#include <linux/netfilter_ipv6.h>
+#include <net/netfilter/nf_conntrack_protocol.h>
+
+unsigned long nf_ct_udp_timeout = 30*HZ;
+unsigned long nf_ct_udp_timeout_stream = 180*HZ;
+
+static int udp_pkt_to_tuple(const struct sk_buff *skb,
+ unsigned int dataoff,
+ struct nf_conntrack_tuple *tuple)
+{
+ struct udphdr _hdr, *hp;
+
+ /* Actually only need first 8 bytes. */
+ hp = skb_header_pointer(skb, dataoff, sizeof(_hdr), &_hdr);
+ if (hp == NULL)
+ return 0;
+
+ tuple->src.u.udp.port = hp->source;
+ tuple->dst.u.udp.port = hp->dest;
+
+ return 1;
+}
+
+static int udp_invert_tuple(struct nf_conntrack_tuple *tuple,
+ const struct nf_conntrack_tuple *orig)
+{
+ tuple->src.u.udp.port = orig->dst.u.udp.port;
+ tuple->dst.u.udp.port = orig->src.u.udp.port;
+ return 1;
+}
+
+/* Print out the per-protocol part of the tuple. */
+static int udp_print_tuple(struct seq_file *s,
+ const struct nf_conntrack_tuple *tuple)
+{
+ return seq_printf(s, "sport=%hu dport=%hu ",
+ ntohs(tuple->src.u.udp.port),
+ ntohs(tuple->dst.u.udp.port));
+}
+
+/* Print out the private part of the conntrack. */
+static int udp_print_conntrack(struct seq_file *s,
+ const struct nf_conn *conntrack)
+{
+ return 0;
+}
+
+/* Returns verdict for packet, and may modify conntracktype */
+static int udp_packet(struct nf_conn *conntrack,
+ const struct sk_buff *skb,
+ unsigned int dataoff,
+ enum ip_conntrack_info ctinfo,
+ int pf,
+ unsigned int hooknum)
+{
+ /* If we've seen traffic both ways, this is some kind of UDP
+ stream. Extend timeout. */
+ if (test_bit(IPS_SEEN_REPLY_BIT, &conntrack->status)) {
+ nf_ct_refresh_acct(conntrack, ctinfo, skb,
+ nf_ct_udp_timeout_stream);
+ /* Also, more likely to be important, and not a probe */
+ if (!test_and_set_bit(IPS_ASSURED_BIT, &conntrack->status))
+ nf_conntrack_event_cache(IPCT_STATUS, skb);
+ } else
+ nf_ct_refresh_acct(conntrack, ctinfo, skb, nf_ct_udp_timeout);
+
+ return NF_ACCEPT;
+}
+
+/* Called when a new connection for this protocol found. */
+static int udp_new(struct nf_conn *conntrack, const struct sk_buff *skb,
+ unsigned int dataoff)
+{
+ return 1;
+}
+
+static int udp_error(struct sk_buff *skb, unsigned int dataoff,
+ enum ip_conntrack_info *ctinfo,
+ int pf,
+ unsigned int hooknum,
+ int (*csum)(const struct sk_buff *, unsigned int))
+{
+ unsigned int udplen = skb->len - dataoff;
+ struct udphdr _hdr, *hdr;
+
+ /* Header is too small? */
+ hdr = skb_header_pointer(skb, dataoff, sizeof(_hdr), &_hdr);
+ if (hdr == NULL) {
+ if (LOG_INVALID(IPPROTO_UDP))
+ nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
+ "nf_ct_udp: short packet ");
+ return -NF_ACCEPT;
+ }
+
+ /* Truncated/malformed packets */
+ if (ntohs(hdr->len) > udplen || ntohs(hdr->len) < sizeof(*hdr)) {
+ if (LOG_INVALID(IPPROTO_UDP))
+ nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
+ "nf_ct_udp: truncated/malformed packet ");
+ return -NF_ACCEPT;
+ }
+
+ /* Packet with no checksum */
+ if (!hdr->check)
+ return NF_ACCEPT;
+
+ /* Checksum invalid? Ignore.
+ * We skip checking packets on the outgoing path
+ * because the semantic of CHECKSUM_HW is different there
+ * and moreover root might send raw packets.
+ * FIXME: Source route IP option packets --RR */
+ if (((pf == PF_INET && hooknum == NF_IP_PRE_ROUTING) ||
+ (pf == PF_INET6 && hooknum == NF_IP6_PRE_ROUTING))
+ && skb->ip_summed != CHECKSUM_UNNECESSARY
+ && csum(skb, dataoff)) {
+ if (LOG_INVALID(IPPROTO_UDP))
+ nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
+ "nf_ct_udp: bad UDP checksum ");
+ return -NF_ACCEPT;
+ }
+
+ return NF_ACCEPT;
+}
+
+static int csum4(const struct sk_buff *skb, unsigned int dataoff)
+{
+ return csum_tcpudp_magic(skb->nh.iph->saddr, skb->nh.iph->daddr,
+ skb->len - dataoff, IPPROTO_UDP,
+ skb->ip_summed == CHECKSUM_HW ? skb->csum
+ : skb_checksum(skb, dataoff,
+ skb->len - dataoff, 0));
+}
+
+static int csum6(const struct sk_buff *skb, unsigned int dataoff)
+{
+ return csum_ipv6_magic(&skb->nh.ipv6h->saddr, &skb->nh.ipv6h->daddr,
+ skb->len - dataoff, IPPROTO_UDP,
+ skb->ip_summed == CHECKSUM_HW ? skb->csum
+ : skb_checksum(skb, dataoff, skb->len - dataoff,
+ 0));
+}
+
+static int udp_error4(struct sk_buff *skb,
+ unsigned int dataoff,
+ enum ip_conntrack_info *ctinfo,
+ int pf,
+ unsigned int hooknum)
+{
+ return udp_error(skb, dataoff, ctinfo, pf, hooknum, csum4);
+}
+
+static int udp_error6(struct sk_buff *skb,
+ unsigned int dataoff,
+ enum ip_conntrack_info *ctinfo,
+ int pf,
+ unsigned int hooknum)
+{
+ return udp_error(skb, dataoff, ctinfo, pf, hooknum, csum6);
+}
+
+struct nf_conntrack_protocol nf_conntrack_protocol_udp4 =
+{
+ .l3proto = PF_INET,
+ .proto = IPPROTO_UDP,
+ .name = "udp",
+ .pkt_to_tuple = udp_pkt_to_tuple,
+ .invert_tuple = udp_invert_tuple,
+ .print_tuple = udp_print_tuple,
+ .print_conntrack = udp_print_conntrack,
+ .packet = udp_packet,
+ .new = udp_new,
+ .error = udp_error4,
+};
+
+struct nf_conntrack_protocol nf_conntrack_protocol_udp6 =
+{
+ .l3proto = PF_INET6,
+ .proto = IPPROTO_UDP,
+ .name = "udp",
+ .pkt_to_tuple = udp_pkt_to_tuple,
+ .invert_tuple = udp_invert_tuple,
+ .print_tuple = udp_print_tuple,
+ .print_conntrack = udp_print_conntrack,
+ .packet = udp_packet,
+ .new = udp_new,
+ .error = udp_error6,
+};
+
+EXPORT_SYMBOL(nf_conntrack_protocol_udp4);
+EXPORT_SYMBOL(nf_conntrack_protocol_udp6);
diff --git a/net/netfilter/nf_conntrack_standalone.c b/net/netfilter/nf_conntrack_standalone.c
new file mode 100644
index 000000000000..45224db4fe2f
--- /dev/null
+++ b/net/netfilter/nf_conntrack_standalone.c
@@ -0,0 +1,869 @@
+/* This file contains all the functions required for the standalone
+ nf_conntrack module.
+
+ These are not required by the compatibility layer.
+*/
+
+/* (C) 1999-2001 Paul `Rusty' Russell
+ * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.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.
+ *
+ * 16 Dec 2003: Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp>
+ * - generalize L3 protocol dependent part.
+ *
+ * Derived from net/ipv4/netfilter/ip_conntrack_standalone.c
+ */
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/netfilter.h>
+#include <linux/module.h>
+#include <linux/skbuff.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+#include <linux/percpu.h>
+#include <linux/netdevice.h>
+#ifdef CONFIG_SYSCTL
+#include <linux/sysctl.h>
+#endif
+
+#define ASSERT_READ_LOCK(x)
+#define ASSERT_WRITE_LOCK(x)
+
+#include <net/netfilter/nf_conntrack.h>
+#include <net/netfilter/nf_conntrack_l3proto.h>
+#include <net/netfilter/nf_conntrack_protocol.h>
+#include <net/netfilter/nf_conntrack_core.h>
+#include <net/netfilter/nf_conntrack_helper.h>
+#include <linux/netfilter_ipv4/listhelp.h>
+
+#if 0
+#define DEBUGP printk
+#else
+#define DEBUGP(format, args...)
+#endif
+
+MODULE_LICENSE("GPL");
+
+extern atomic_t nf_conntrack_count;
+DECLARE_PER_CPU(struct ip_conntrack_stat, nf_conntrack_stat);
+
+static int kill_l3proto(struct nf_conn *i, void *data)
+{
+ return (i->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num ==
+ ((struct nf_conntrack_l3proto *)data)->l3proto);
+}
+
+static int kill_proto(struct nf_conn *i, void *data)
+{
+ struct nf_conntrack_protocol *proto;
+ proto = (struct nf_conntrack_protocol *)data;
+ return (i->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum ==
+ proto->proto) &&
+ (i->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num ==
+ proto->l3proto);
+}
+
+#ifdef CONFIG_PROC_FS
+static int
+print_tuple(struct seq_file *s, const struct nf_conntrack_tuple *tuple,
+ struct nf_conntrack_l3proto *l3proto,
+ struct nf_conntrack_protocol *proto)
+{
+ return l3proto->print_tuple(s, tuple) || proto->print_tuple(s, tuple);
+}
+
+#ifdef CONFIG_NF_CT_ACCT
+static unsigned int
+seq_print_counters(struct seq_file *s,
+ const struct ip_conntrack_counter *counter)
+{
+ return seq_printf(s, "packets=%llu bytes=%llu ",
+ (unsigned long long)counter->packets,
+ (unsigned long long)counter->bytes);
+}
+#else
+#define seq_print_counters(x, y) 0
+#endif
+
+struct ct_iter_state {
+ unsigned int bucket;
+};
+
+static struct list_head *ct_get_first(struct seq_file *seq)
+{
+ struct ct_iter_state *st = seq->private;
+
+ for (st->bucket = 0;
+ st->bucket < nf_conntrack_htable_size;
+ st->bucket++) {
+ if (!list_empty(&nf_conntrack_hash[st->bucket]))
+ return nf_conntrack_hash[st->bucket].next;
+ }
+ return NULL;
+}
+
+static struct list_head *ct_get_next(struct seq_file *seq, struct list_head *head)
+{
+ struct ct_iter_state *st = seq->private;
+
+ head = head->next;
+ while (head == &nf_conntrack_hash[st->bucket]) {
+ if (++st->bucket >= nf_conntrack_htable_size)
+ return NULL;
+ head = nf_conntrack_hash[st->bucket].next;
+ }
+ return head;
+}
+
+static struct list_head *ct_get_idx(struct seq_file *seq, loff_t pos)
+{
+ struct list_head *head = ct_get_first(seq);
+
+ if (head)
+ while (pos && (head = ct_get_next(seq, head)))
+ pos--;
+ return pos ? NULL : head;
+}
+
+static void *ct_seq_start(struct seq_file *seq, loff_t *pos)
+{
+ read_lock_bh(&nf_conntrack_lock);
+ return ct_get_idx(seq, *pos);
+}
+
+static void *ct_seq_next(struct seq_file *s, void *v, loff_t *pos)
+{
+ (*pos)++;
+ return ct_get_next(s, v);
+}
+
+static void ct_seq_stop(struct seq_file *s, void *v)
+{
+ read_unlock_bh(&nf_conntrack_lock);
+}
+
+/* return 0 on success, 1 in case of error */
+static int ct_seq_show(struct seq_file *s, void *v)
+{
+ const struct nf_conntrack_tuple_hash *hash = v;
+ const struct nf_conn *conntrack = nf_ct_tuplehash_to_ctrack(hash);
+ struct nf_conntrack_l3proto *l3proto;
+ struct nf_conntrack_protocol *proto;
+
+ ASSERT_READ_LOCK(&nf_conntrack_lock);
+ NF_CT_ASSERT(conntrack);
+
+ /* we only want to print DIR_ORIGINAL */
+ if (NF_CT_DIRECTION(hash))
+ return 0;
+
+ l3proto = nf_ct_find_l3proto(conntrack->tuplehash[IP_CT_DIR_ORIGINAL]
+ .tuple.src.l3num);
+
+ NF_CT_ASSERT(l3proto);
+ proto = nf_ct_find_proto(conntrack->tuplehash[IP_CT_DIR_ORIGINAL]
+ .tuple.src.l3num,
+ conntrack->tuplehash[IP_CT_DIR_ORIGINAL]
+ .tuple.dst.protonum);
+ NF_CT_ASSERT(proto);
+
+ if (seq_printf(s, "%-8s %u %-8s %u %ld ",
+ l3proto->name,
+ conntrack->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num,
+ proto->name,
+ conntrack->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum,
+ timer_pending(&conntrack->timeout)
+ ? (long)(conntrack->timeout.expires - jiffies)/HZ : 0) != 0)
+ return -ENOSPC;
+
+ if (l3proto->print_conntrack(s, conntrack))
+ return -ENOSPC;
+
+ if (proto->print_conntrack(s, conntrack))
+ return -ENOSPC;
+
+ if (print_tuple(s, &conntrack->tuplehash[IP_CT_DIR_ORIGINAL].tuple,
+ l3proto, proto))
+ return -ENOSPC;
+
+ if (seq_print_counters(s, &conntrack->counters[IP_CT_DIR_ORIGINAL]))
+ return -ENOSPC;
+
+ if (!(test_bit(IPS_SEEN_REPLY_BIT, &conntrack->status)))
+ if (seq_printf(s, "[UNREPLIED] "))
+ return -ENOSPC;
+
+ if (print_tuple(s, &conntrack->tuplehash[IP_CT_DIR_REPLY].tuple,
+ l3proto, proto))
+ return -ENOSPC;
+
+ if (seq_print_counters(s, &conntrack->counters[IP_CT_DIR_REPLY]))
+ return -ENOSPC;
+
+ if (test_bit(IPS_ASSURED_BIT, &conntrack->status))
+ if (seq_printf(s, "[ASSURED] "))
+ return -ENOSPC;
+
+#if defined(CONFIG_NF_CONNTRACK_MARK)
+ if (seq_printf(s, "mark=%u ", conntrack->mark))
+ return -ENOSPC;
+#endif
+
+ if (seq_printf(s, "use=%u\n", atomic_read(&conntrack->ct_general.use)))
+ return -ENOSPC;
+
+ return 0;
+}
+
+static struct seq_operations ct_seq_ops = {
+ .start = ct_seq_start,
+ .next = ct_seq_next,
+ .stop = ct_seq_stop,
+ .show = ct_seq_show
+};
+
+static int ct_open(struct inode *inode, struct file *file)
+{
+ struct seq_file *seq;
+ struct ct_iter_state *st;
+ int ret;
+
+ st = kmalloc(sizeof(struct ct_iter_state), GFP_KERNEL);
+ if (st == NULL)
+ return -ENOMEM;
+ ret = seq_open(file, &ct_seq_ops);
+ if (ret)
+ goto out_free;
+ seq = file->private_data;
+ seq->private = st;
+ memset(st, 0, sizeof(struct ct_iter_state));
+ return ret;
+out_free:
+ kfree(st);
+ return ret;
+}
+
+static struct file_operations ct_file_ops = {
+ .owner = THIS_MODULE,
+ .open = ct_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = seq_release_private,
+};
+
+/* expects */
+static void *exp_seq_start(struct seq_file *s, loff_t *pos)
+{
+ struct list_head *e = &nf_conntrack_expect_list;
+ loff_t i;
+
+ /* strange seq_file api calls stop even if we fail,
+ * thus we need to grab lock since stop unlocks */
+ read_lock_bh(&nf_conntrack_lock);
+
+ if (list_empty(e))
+ return NULL;
+
+ for (i = 0; i <= *pos; i++) {
+ e = e->next;
+ if (e == &nf_conntrack_expect_list)
+ return NULL;
+ }
+ return e;
+}
+
+static void *exp_seq_next(struct seq_file *s, void *v, loff_t *pos)
+{
+ struct list_head *e = v;
+
+ ++*pos;
+ e = e->next;
+
+ if (e == &nf_conntrack_expect_list)
+ return NULL;
+
+ return e;
+}
+
+static void exp_seq_stop(struct seq_file *s, void *v)
+{
+ read_unlock_bh(&nf_conntrack_lock);
+}
+
+static int exp_seq_show(struct seq_file *s, void *v)
+{
+ struct nf_conntrack_expect *expect = v;
+
+ if (expect->timeout.function)
+ seq_printf(s, "%ld ", timer_pending(&expect->timeout)
+ ? (long)(expect->timeout.expires - jiffies)/HZ : 0);
+ else
+ seq_printf(s, "- ");
+ seq_printf(s, "l3proto = %u proto=%u ",
+ expect->tuple.src.l3num,
+ expect->tuple.dst.protonum);
+ print_tuple(s, &expect->tuple,
+ nf_ct_find_l3proto(expect->tuple.src.l3num),
+ nf_ct_find_proto(expect->tuple.src.l3num,
+ expect->tuple.dst.protonum));
+ return seq_putc(s, '\n');
+}
+
+static struct seq_operations exp_seq_ops = {
+ .start = exp_seq_start,
+ .next = exp_seq_next,
+ .stop = exp_seq_stop,
+ .show = exp_seq_show
+};
+
+static int exp_open(struct inode *inode, struct file *file)
+{
+ return seq_open(file, &exp_seq_ops);
+}
+
+static struct file_operations exp_file_ops = {
+ .owner = THIS_MODULE,
+ .open = exp_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = seq_release
+};
+
+static void *ct_cpu_seq_start(struct seq_file *seq, loff_t *pos)
+{
+ int cpu;
+
+ if (*pos == 0)
+ return SEQ_START_TOKEN;
+
+ for (cpu = *pos-1; cpu < NR_CPUS; ++cpu) {
+ if (!cpu_possible(cpu))
+ continue;
+ *pos = cpu + 1;
+ return &per_cpu(nf_conntrack_stat, cpu);
+ }
+
+ return NULL;
+}
+
+static void *ct_cpu_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+{
+ int cpu;
+
+ for (cpu = *pos; cpu < NR_CPUS; ++cpu) {
+ if (!cpu_possible(cpu))
+ continue;
+ *pos = cpu + 1;
+ return &per_cpu(nf_conntrack_stat, cpu);
+ }
+
+ return NULL;
+}
+
+static void ct_cpu_seq_stop(struct seq_file *seq, void *v)
+{
+}
+
+static int ct_cpu_seq_show(struct seq_file *seq, void *v)
+{
+ unsigned int nr_conntracks = atomic_read(&nf_conntrack_count);
+ struct ip_conntrack_stat *st = v;
+
+ if (v == SEQ_START_TOKEN) {
+ seq_printf(seq, "entries searched found new invalid ignore delete delete_list insert insert_failed drop early_drop icmp_error expect_new expect_create expect_delete\n");
+ return 0;
+ }
+
+ seq_printf(seq, "%08x %08x %08x %08x %08x %08x %08x %08x "
+ "%08x %08x %08x %08x %08x %08x %08x %08x \n",
+ nr_conntracks,
+ st->searched,
+ st->found,
+ st->new,
+ st->invalid,
+ st->ignore,
+ st->delete,
+ st->delete_list,
+ st->insert,
+ st->insert_failed,
+ st->drop,
+ st->early_drop,
+ st->error,
+
+ st->expect_new,
+ st->expect_create,
+ st->expect_delete
+ );
+ return 0;
+}
+
+static struct seq_operations ct_cpu_seq_ops = {
+ .start = ct_cpu_seq_start,
+ .next = ct_cpu_seq_next,
+ .stop = ct_cpu_seq_stop,
+ .show = ct_cpu_seq_show,
+};
+
+static int ct_cpu_seq_open(struct inode *inode, struct file *file)
+{
+ return seq_open(file, &ct_cpu_seq_ops);
+}
+
+static struct file_operations ct_cpu_seq_fops = {
+ .owner = THIS_MODULE,
+ .open = ct_cpu_seq_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = seq_release_private,
+};
+#endif /* CONFIG_PROC_FS */
+
+/* Sysctl support */
+
+#ifdef CONFIG_SYSCTL
+
+/* From nf_conntrack_core.c */
+extern int nf_conntrack_max;
+extern unsigned int nf_conntrack_htable_size;
+
+/* From nf_conntrack_proto_tcp.c */
+extern unsigned long nf_ct_tcp_timeout_syn_sent;
+extern unsigned long nf_ct_tcp_timeout_syn_recv;
+extern unsigned long nf_ct_tcp_timeout_established;
+extern unsigned long nf_ct_tcp_timeout_fin_wait;
+extern unsigned long nf_ct_tcp_timeout_close_wait;
+extern unsigned long nf_ct_tcp_timeout_last_ack;
+extern unsigned long nf_ct_tcp_timeout_time_wait;
+extern unsigned long nf_ct_tcp_timeout_close;
+extern unsigned long nf_ct_tcp_timeout_max_retrans;
+extern int nf_ct_tcp_loose;
+extern int nf_ct_tcp_be_liberal;
+extern int nf_ct_tcp_max_retrans;
+
+/* From nf_conntrack_proto_udp.c */
+extern unsigned long nf_ct_udp_timeout;
+extern unsigned long nf_ct_udp_timeout_stream;
+
+/* From nf_conntrack_proto_generic.c */
+extern unsigned long nf_ct_generic_timeout;
+
+/* Log invalid packets of a given protocol */
+static int log_invalid_proto_min = 0;
+static int log_invalid_proto_max = 255;
+
+static struct ctl_table_header *nf_ct_sysctl_header;
+
+static ctl_table nf_ct_sysctl_table[] = {
+ {
+ .ctl_name = NET_NF_CONNTRACK_MAX,
+ .procname = "nf_conntrack_max",
+ .data = &nf_conntrack_max,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = &proc_dointvec,
+ },
+ {
+ .ctl_name = NET_NF_CONNTRACK_COUNT,
+ .procname = "nf_conntrack_count",
+ .data = &nf_conntrack_count,
+ .maxlen = sizeof(int),
+ .mode = 0444,
+ .proc_handler = &proc_dointvec,
+ },
+ {
+ .ctl_name = NET_NF_CONNTRACK_BUCKETS,
+ .procname = "nf_conntrack_buckets",
+ .data = &nf_conntrack_htable_size,
+ .maxlen = sizeof(unsigned int),
+ .mode = 0444,
+ .proc_handler = &proc_dointvec,
+ },
+ {
+ .ctl_name = NET_NF_CONNTRACK_TCP_TIMEOUT_SYN_SENT,
+ .procname = "nf_conntrack_tcp_timeout_syn_sent",
+ .data = &nf_ct_tcp_timeout_syn_sent,
+ .maxlen = sizeof(unsigned int),
+ .mode = 0644,
+ .proc_handler = &proc_dointvec_jiffies,
+ },
+ {
+ .ctl_name = NET_NF_CONNTRACK_TCP_TIMEOUT_SYN_RECV,
+ .procname = "nf_conntrack_tcp_timeout_syn_recv",
+ .data = &nf_ct_tcp_timeout_syn_recv,
+ .maxlen = sizeof(unsigned int),
+ .mode = 0644,
+ .proc_handler = &proc_dointvec_jiffies,
+ },
+ {
+ .ctl_name = NET_NF_CONNTRACK_TCP_TIMEOUT_ESTABLISHED,
+ .procname = "nf_conntrack_tcp_timeout_established",
+ .data = &nf_ct_tcp_timeout_established,
+ .maxlen = sizeof(unsigned int),
+ .mode = 0644,
+ .proc_handler = &proc_dointvec_jiffies,
+ },
+ {
+ .ctl_name = NET_NF_CONNTRACK_TCP_TIMEOUT_FIN_WAIT,
+ .procname = "nf_conntrack_tcp_timeout_fin_wait",
+ .data = &nf_ct_tcp_timeout_fin_wait,
+ .maxlen = sizeof(unsigned int),
+ .mode = 0644,
+ .proc_handler = &proc_dointvec_jiffies,
+ },
+ {
+ .ctl_name = NET_NF_CONNTRACK_TCP_TIMEOUT_CLOSE_WAIT,
+ .procname = "nf_conntrack_tcp_timeout_close_wait",
+ .data = &nf_ct_tcp_timeout_close_wait,
+ .maxlen = sizeof(unsigned int),
+ .mode = 0644,
+ .proc_handler = &proc_dointvec_jiffies,
+ },
+ {
+ .ctl_name = NET_NF_CONNTRACK_TCP_TIMEOUT_LAST_ACK,
+ .procname = "nf_conntrack_tcp_timeout_last_ack",
+ .data = &nf_ct_tcp_timeout_last_ack,
+ .maxlen = sizeof(unsigned int),
+ .mode = 0644,
+ .proc_handler = &proc_dointvec_jiffies,
+ },
+ {
+ .ctl_name = NET_NF_CONNTRACK_TCP_TIMEOUT_TIME_WAIT,
+ .procname = "nf_conntrack_tcp_timeout_time_wait",
+ .data = &nf_ct_tcp_timeout_time_wait,
+ .maxlen = sizeof(unsigned int),
+ .mode = 0644,
+ .proc_handler = &proc_dointvec_jiffies,
+ },
+ {
+ .ctl_name = NET_NF_CONNTRACK_TCP_TIMEOUT_CLOSE,
+ .procname = "nf_conntrack_tcp_timeout_close",
+ .data = &nf_ct_tcp_timeout_close,
+ .maxlen = sizeof(unsigned int),
+ .mode = 0644,
+ .proc_handler = &proc_dointvec_jiffies,
+ },
+ {
+ .ctl_name = NET_NF_CONNTRACK_UDP_TIMEOUT,
+ .procname = "nf_conntrack_udp_timeout",
+ .data = &nf_ct_udp_timeout,
+ .maxlen = sizeof(unsigned int),
+ .mode = 0644,
+ .proc_handler = &proc_dointvec_jiffies,
+ },
+ {
+ .ctl_name = NET_NF_CONNTRACK_UDP_TIMEOUT_STREAM,
+ .procname = "nf_conntrack_udp_timeout_stream",
+ .data = &nf_ct_udp_timeout_stream,
+ .maxlen = sizeof(unsigned int),
+ .mode = 0644,
+ .proc_handler = &proc_dointvec_jiffies,
+ },
+ {
+ .ctl_name = NET_NF_CONNTRACK_GENERIC_TIMEOUT,
+ .procname = "nf_conntrack_generic_timeout",
+ .data = &nf_ct_generic_timeout,
+ .maxlen = sizeof(unsigned int),
+ .mode = 0644,
+ .proc_handler = &proc_dointvec_jiffies,
+ },
+ {
+ .ctl_name = NET_NF_CONNTRACK_LOG_INVALID,
+ .procname = "nf_conntrack_log_invalid",
+ .data = &nf_ct_log_invalid,
+ .maxlen = sizeof(unsigned int),
+ .mode = 0644,
+ .proc_handler = &proc_dointvec_minmax,
+ .strategy = &sysctl_intvec,
+ .extra1 = &log_invalid_proto_min,
+ .extra2 = &log_invalid_proto_max,
+ },
+ {
+ .ctl_name = NET_NF_CONNTRACK_TCP_TIMEOUT_MAX_RETRANS,
+ .procname = "nf_conntrack_tcp_timeout_max_retrans",
+ .data = &nf_ct_tcp_timeout_max_retrans,
+ .maxlen = sizeof(unsigned int),
+ .mode = 0644,
+ .proc_handler = &proc_dointvec_jiffies,
+ },
+ {
+ .ctl_name = NET_NF_CONNTRACK_TCP_LOOSE,
+ .procname = "nf_conntrack_tcp_loose",
+ .data = &nf_ct_tcp_loose,
+ .maxlen = sizeof(unsigned int),
+ .mode = 0644,
+ .proc_handler = &proc_dointvec,
+ },
+ {
+ .ctl_name = NET_NF_CONNTRACK_TCP_BE_LIBERAL,
+ .procname = "nf_conntrack_tcp_be_liberal",
+ .data = &nf_ct_tcp_be_liberal,
+ .maxlen = sizeof(unsigned int),
+ .mode = 0644,
+ .proc_handler = &proc_dointvec,
+ },
+ {
+ .ctl_name = NET_NF_CONNTRACK_TCP_MAX_RETRANS,
+ .procname = "nf_conntrack_tcp_max_retrans",
+ .data = &nf_ct_tcp_max_retrans,
+ .maxlen = sizeof(unsigned int),
+ .mode = 0644,
+ .proc_handler = &proc_dointvec,
+ },
+
+ { .ctl_name = 0 }
+};
+
+#define NET_NF_CONNTRACK_MAX 2089
+
+static ctl_table nf_ct_netfilter_table[] = {
+ {
+ .ctl_name = NET_NETFILTER,
+ .procname = "netfilter",
+ .mode = 0555,
+ .child = nf_ct_sysctl_table,
+ },
+ {
+ .ctl_name = NET_NF_CONNTRACK_MAX,
+ .procname = "nf_conntrack_max",
+ .data = &nf_conntrack_max,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = &proc_dointvec,
+ },
+ { .ctl_name = 0 }
+};
+
+static ctl_table nf_ct_net_table[] = {
+ {
+ .ctl_name = CTL_NET,
+ .procname = "net",
+ .mode = 0555,
+ .child = nf_ct_netfilter_table,
+ },
+ { .ctl_name = 0 }
+};
+EXPORT_SYMBOL(nf_ct_log_invalid);
+#endif /* CONFIG_SYSCTL */
+
+static int init_or_cleanup(int init)
+{
+#ifdef CONFIG_PROC_FS
+ struct proc_dir_entry *proc, *proc_exp, *proc_stat;
+#endif
+ int ret = 0;
+
+ if (!init) goto cleanup;
+
+ ret = nf_conntrack_init();
+ if (ret < 0)
+ goto cleanup_nothing;
+
+#ifdef CONFIG_PROC_FS
+ proc = proc_net_fops_create("nf_conntrack", 0440, &ct_file_ops);
+ if (!proc) goto cleanup_init;
+
+ proc_exp = proc_net_fops_create("nf_conntrack_expect", 0440,
+ &exp_file_ops);
+ if (!proc_exp) goto cleanup_proc;
+
+ proc_stat = create_proc_entry("nf_conntrack", S_IRUGO, proc_net_stat);
+ if (!proc_stat)
+ goto cleanup_proc_exp;
+
+ proc_stat->proc_fops = &ct_cpu_seq_fops;
+ proc_stat->owner = THIS_MODULE;
+#endif
+#ifdef CONFIG_SYSCTL
+ nf_ct_sysctl_header = register_sysctl_table(nf_ct_net_table, 0);
+ if (nf_ct_sysctl_header == NULL) {
+ printk("nf_conntrack: can't register to sysctl.\n");
+ ret = -ENOMEM;
+ goto cleanup_proc_stat;
+ }
+#endif
+
+ return ret;
+
+ cleanup:
+#ifdef CONFIG_SYSCTL
+ unregister_sysctl_table(nf_ct_sysctl_header);
+ cleanup_proc_stat:
+#endif
+#ifdef CONFIG_PROC_FS
+ proc_net_remove("nf_conntrack_stat");
+ cleanup_proc_exp:
+ proc_net_remove("nf_conntrack_expect");
+ cleanup_proc:
+ proc_net_remove("nf_conntrack");
+ cleanup_init:
+#endif /* CNFIG_PROC_FS */
+ nf_conntrack_cleanup();
+ cleanup_nothing:
+ return ret;
+}
+
+int nf_conntrack_l3proto_register(struct nf_conntrack_l3proto *proto)
+{
+ int ret = 0;
+
+ write_lock_bh(&nf_conntrack_lock);
+ if (nf_ct_l3protos[proto->l3proto] != &nf_conntrack_generic_l3proto) {
+ ret = -EBUSY;
+ goto out;
+ }
+ nf_ct_l3protos[proto->l3proto] = proto;
+out:
+ write_unlock_bh(&nf_conntrack_lock);
+
+ return ret;
+}
+
+void nf_conntrack_l3proto_unregister(struct nf_conntrack_l3proto *proto)
+{
+ write_lock_bh(&nf_conntrack_lock);
+ nf_ct_l3protos[proto->l3proto] = &nf_conntrack_generic_l3proto;
+ write_unlock_bh(&nf_conntrack_lock);
+
+ /* Somebody could be still looking at the proto in bh. */
+ synchronize_net();
+
+ /* Remove all contrack entries for this protocol */
+ nf_ct_iterate_cleanup(kill_l3proto, proto);
+}
+
+/* FIXME: Allow NULL functions and sub in pointers to generic for
+ them. --RR */
+int nf_conntrack_protocol_register(struct nf_conntrack_protocol *proto)
+{
+ int ret = 0;
+
+retry:
+ write_lock_bh(&nf_conntrack_lock);
+ if (nf_ct_protos[proto->l3proto]) {
+ if (nf_ct_protos[proto->l3proto][proto->proto]
+ != &nf_conntrack_generic_protocol) {
+ ret = -EBUSY;
+ goto out_unlock;
+ }
+ } else {
+ /* l3proto may be loaded latter. */
+ struct nf_conntrack_protocol **proto_array;
+ int i;
+
+ write_unlock_bh(&nf_conntrack_lock);
+
+ proto_array = (struct nf_conntrack_protocol **)
+ kmalloc(MAX_NF_CT_PROTO *
+ sizeof(struct nf_conntrack_protocol *),
+ GFP_KERNEL);
+ if (proto_array == NULL) {
+ ret = -ENOMEM;
+ goto out;
+ }
+ for (i = 0; i < MAX_NF_CT_PROTO; i++)
+ proto_array[i] = &nf_conntrack_generic_protocol;
+
+ write_lock_bh(&nf_conntrack_lock);
+ if (nf_ct_protos[proto->l3proto]) {
+ /* bad timing, but no problem */
+ write_unlock_bh(&nf_conntrack_lock);
+ kfree(proto_array);
+ } else {
+ nf_ct_protos[proto->l3proto] = proto_array;
+ write_unlock_bh(&nf_conntrack_lock);
+ }
+
+ /*
+ * Just once because array is never freed until unloading
+ * nf_conntrack.ko
+ */
+ goto retry;
+ }
+
+ nf_ct_protos[proto->l3proto][proto->proto] = proto;
+
+out_unlock:
+ write_unlock_bh(&nf_conntrack_lock);
+out:
+ return ret;
+}
+
+void nf_conntrack_protocol_unregister(struct nf_conntrack_protocol *proto)
+{
+ write_lock_bh(&nf_conntrack_lock);
+ nf_ct_protos[proto->l3proto][proto->proto]
+ = &nf_conntrack_generic_protocol;
+ write_unlock_bh(&nf_conntrack_lock);
+
+ /* Somebody could be still looking at the proto in bh. */
+ synchronize_net();
+
+ /* Remove all contrack entries for this protocol */
+ nf_ct_iterate_cleanup(kill_proto, proto);
+}
+
+static int __init init(void)
+{
+ return init_or_cleanup(1);
+}
+
+static void __exit fini(void)
+{
+ init_or_cleanup(0);
+}
+
+module_init(init);
+module_exit(fini);
+
+/* Some modules need us, but don't depend directly on any symbol.
+ They should call this. */
+void need_nf_conntrack(void)
+{
+}
+
+#ifdef CONFIG_NF_CONNTRACK_EVENTS
+EXPORT_SYMBOL_GPL(nf_conntrack_chain);
+EXPORT_SYMBOL_GPL(nf_conntrack_expect_chain);
+EXPORT_SYMBOL_GPL(nf_conntrack_register_notifier);
+EXPORT_SYMBOL_GPL(nf_conntrack_unregister_notifier);
+EXPORT_SYMBOL_GPL(__nf_ct_event_cache_init);
+EXPORT_PER_CPU_SYMBOL_GPL(nf_conntrack_ecache);
+EXPORT_SYMBOL_GPL(nf_ct_deliver_cached_events);
+#endif
+EXPORT_SYMBOL(nf_conntrack_l3proto_register);
+EXPORT_SYMBOL(nf_conntrack_l3proto_unregister);
+EXPORT_SYMBOL(nf_conntrack_protocol_register);
+EXPORT_SYMBOL(nf_conntrack_protocol_unregister);
+EXPORT_SYMBOL(nf_ct_invert_tuplepr);
+EXPORT_SYMBOL(nf_conntrack_alter_reply);
+EXPORT_SYMBOL(nf_conntrack_destroyed);
+EXPORT_SYMBOL(need_nf_conntrack);
+EXPORT_SYMBOL(nf_conntrack_helper_register);
+EXPORT_SYMBOL(nf_conntrack_helper_unregister);
+EXPORT_SYMBOL(nf_ct_iterate_cleanup);
+EXPORT_SYMBOL(__nf_ct_refresh_acct);
+EXPORT_SYMBOL(nf_ct_protos);
+EXPORT_SYMBOL(nf_ct_find_proto);
+EXPORT_SYMBOL(nf_ct_l3protos);
+EXPORT_SYMBOL(nf_conntrack_expect_alloc);
+EXPORT_SYMBOL(nf_conntrack_expect_put);
+EXPORT_SYMBOL(nf_conntrack_expect_related);
+EXPORT_SYMBOL(nf_conntrack_unexpect_related);
+EXPORT_SYMBOL(nf_conntrack_tuple_taken);
+EXPORT_SYMBOL(nf_conntrack_htable_size);
+EXPORT_SYMBOL(nf_conntrack_lock);
+EXPORT_SYMBOL(nf_conntrack_hash);
+EXPORT_SYMBOL(nf_conntrack_untracked);
+EXPORT_SYMBOL_GPL(nf_conntrack_find_get);
+#ifdef CONFIG_IP_NF_NAT_NEEDED
+EXPORT_SYMBOL(nf_conntrack_tcp_update);
+#endif
+EXPORT_SYMBOL(__nf_conntrack_confirm);
+EXPORT_SYMBOL(nf_ct_get_tuple);
+EXPORT_SYMBOL(nf_ct_invert_tuple);
+EXPORT_SYMBOL(nf_conntrack_in);
+EXPORT_SYMBOL(__nf_conntrack_attach);
diff --git a/net/netfilter/nf_queue.c b/net/netfilter/nf_queue.c
index d10d552d9c40..d3a4f30a7f22 100644
--- a/net/netfilter/nf_queue.c
+++ b/net/netfilter/nf_queue.c
@@ -117,7 +117,7 @@ int nf_queue(struct sk_buff **skb,
/* QUEUE == DROP if noone is waiting, to be safe. */
read_lock(&queue_handler_lock);
- if (!queue_handler[pf]->outfn) {
+ if (!queue_handler[pf] || !queue_handler[pf]->outfn) {
read_unlock(&queue_handler_lock);
kfree_skb(*skb);
return 1;
diff --git a/net/netfilter/nfnetlink.c b/net/netfilter/nfnetlink.c
index 4bc27a6334c1..83f4c53030fc 100644
--- a/net/netfilter/nfnetlink.c
+++ b/net/netfilter/nfnetlink.c
@@ -128,7 +128,7 @@ void __nfa_fill(struct sk_buff *skb, int attrtype, int attrlen,
memset(NFA_DATA(nfa) + attrlen, 0, NFA_ALIGN(size) - size);
}
-int nfattr_parse(struct nfattr *tb[], int maxattr, struct nfattr *nfa, int len)
+void nfattr_parse(struct nfattr *tb[], int maxattr, struct nfattr *nfa, int len)
{
memset(tb, 0, sizeof(struct nfattr *) * maxattr);
@@ -138,8 +138,6 @@ int nfattr_parse(struct nfattr *tb[], int maxattr, struct nfattr *nfa, int len)
tb[flavor-1] = nfa;
nfa = NFA_NEXT(nfa, len);
}
-
- return 0;
}
/**
@@ -242,15 +240,18 @@ static inline int nfnetlink_rcv_msg(struct sk_buff *skb,
ss = nfnetlink_get_subsys(type);
if (!ss) {
#ifdef CONFIG_KMOD
- /* don't call nfnl_shunlock, since it would reenter
- * with further packet processing */
- up(&nfnl_sem);
- request_module("nfnetlink-subsys-%d", NFNL_SUBSYS_ID(type));
- nfnl_shlock();
- ss = nfnetlink_get_subsys(type);
+ if (cap_raised(NETLINK_CB(skb).eff_cap, CAP_NET_ADMIN)) {
+ /* don't call nfnl_shunlock, since it would reenter
+ * with further packet processing */
+ up(&nfnl_sem);
+ request_module("nfnetlink-subsys-%d",
+ NFNL_SUBSYS_ID(type));
+ nfnl_shlock();
+ ss = nfnetlink_get_subsys(type);
+ }
if (!ss)
#endif
- goto err_inval;
+ goto err_inval;
}
nc = nfnetlink_find_client(type, ss);
diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c
index efcd10f996ba..d194676f3655 100644
--- a/net/netfilter/nfnetlink_log.c
+++ b/net/netfilter/nfnetlink_log.c
@@ -146,11 +146,10 @@ instance_create(u_int16_t group_num, int pid)
goto out_unlock;
}
- inst = kmalloc(sizeof(*inst), GFP_ATOMIC);
+ inst = kzalloc(sizeof(*inst), GFP_ATOMIC);
if (!inst)
goto out_unlock;
- memset(inst, 0, sizeof(*inst));
INIT_HLIST_NODE(&inst->hlist);
inst->lock = SPIN_LOCK_UNLOCKED;
/* needs to be two, since we _put() after creation */
@@ -962,10 +961,9 @@ static int nful_open(struct inode *inode, struct file *file)
struct iter_state *is;
int ret;
- is = kmalloc(sizeof(*is), GFP_KERNEL);
+ is = kzalloc(sizeof(*is), GFP_KERNEL);
if (!is)
return -ENOMEM;
- memset(is, 0, sizeof(*is));
ret = seq_open(file, &nful_seq_ops);
if (ret < 0)
goto out_free;
diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c
index eaa44c49567b..f065a6c94953 100644
--- a/net/netfilter/nfnetlink_queue.c
+++ b/net/netfilter/nfnetlink_queue.c
@@ -136,11 +136,10 @@ instance_create(u_int16_t queue_num, int pid)
goto out_unlock;
}
- inst = kmalloc(sizeof(*inst), GFP_ATOMIC);
+ inst = kzalloc(sizeof(*inst), GFP_ATOMIC);
if (!inst)
goto out_unlock;
- memset(inst, 0, sizeof(*inst));
inst->queue_num = queue_num;
inst->peer_pid = pid;
inst->queue_maxlen = NFQNL_QMAX_DEFAULT;
@@ -1036,10 +1035,9 @@ static int nfqnl_open(struct inode *inode, struct file *file)
struct iter_state *is;
int ret;
- is = kmalloc(sizeof(*is), GFP_KERNEL);
+ is = kzalloc(sizeof(*is), GFP_KERNEL);
if (!is)
return -ENOMEM;
- memset(is, 0, sizeof(*is));
ret = seq_open(file, &nfqnl_seq_ops);
if (ret < 0)
goto out_free;
diff --git a/net/netlink/Makefile b/net/netlink/Makefile
index 39d9c2dcd03c..e3589c2de49e 100644
--- a/net/netlink/Makefile
+++ b/net/netlink/Makefile
@@ -2,4 +2,4 @@
# Makefile for the netlink driver.
#
-obj-y := af_netlink.o
+obj-y := af_netlink.o attr.o genetlink.o
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index 678c3f2c0d0b..8c38ee6d255e 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -58,6 +58,7 @@
#include <net/sock.h>
#include <net/scm.h>
+#include <net/netlink.h>
#define Nprintk(a...)
#define NLGRPSZ(x) (ALIGN(x, sizeof(unsigned long) * 8) / 8)
@@ -427,7 +428,8 @@ static int netlink_release(struct socket *sock)
spin_lock(&nlk->cb_lock);
if (nlk->cb) {
- nlk->cb->done(nlk->cb);
+ if (nlk->cb->done)
+ nlk->cb->done(nlk->cb);
netlink_destroy_callback(nlk->cb);
nlk->cb = NULL;
}
@@ -740,11 +742,8 @@ int netlink_attachskb(struct sock *sk, struct sk_buff *skb, int nonblock, long t
int netlink_sendskb(struct sock *sk, struct sk_buff *skb, int protocol)
{
- struct netlink_sock *nlk;
int len = skb->len;
- nlk = nlk_sk(sk);
-
skb_queue_tail(&sk->sk_receive_queue, skb);
sk->sk_data_ready(sk, len);
sock_put(sk);
@@ -827,7 +826,7 @@ struct netlink_broadcast_data {
int failure;
int congested;
int delivered;
- unsigned int allocation;
+ gfp_t allocation;
struct sk_buff *skb, *skb2;
};
@@ -1325,7 +1324,8 @@ static int netlink_dump(struct sock *sk)
skb_queue_tail(&sk->sk_receive_queue, skb);
sk->sk_data_ready(sk, skb->len);
- cb->done(cb);
+ if (cb->done)
+ cb->done(cb);
nlk->cb = NULL;
spin_unlock(&nlk->cb_lock);
@@ -1412,6 +1412,94 @@ void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err)
netlink_unicast(in_skb->sk, skb, NETLINK_CB(in_skb).pid, MSG_DONTWAIT);
}
+static int netlink_rcv_skb(struct sk_buff *skb, int (*cb)(struct sk_buff *,
+ struct nlmsghdr *, int *))
+{
+ unsigned int total_len;
+ struct nlmsghdr *nlh;
+ int err;
+
+ while (skb->len >= nlmsg_total_size(0)) {
+ nlh = (struct nlmsghdr *) skb->data;
+
+ if (skb->len < nlh->nlmsg_len)
+ return 0;
+
+ total_len = min(NLMSG_ALIGN(nlh->nlmsg_len), skb->len);
+
+ if (cb(skb, nlh, &err) < 0) {
+ /* Not an error, but we have to interrupt processing
+ * here. Note: that in this case we do not pull
+ * message from skb, it will be processed later.
+ */
+ if (err == 0)
+ return -1;
+ netlink_ack(skb, nlh, err);
+ } else if (nlh->nlmsg_flags & NLM_F_ACK)
+ netlink_ack(skb, nlh, 0);
+
+ skb_pull(skb, total_len);
+ }
+
+ return 0;
+}
+
+/**
+ * nelink_run_queue - Process netlink receive queue.
+ * @sk: Netlink socket containing the queue
+ * @qlen: Place to store queue length upon entry
+ * @cb: Callback function invoked for each netlink message found
+ *
+ * Processes as much as there was in the queue upon entry and invokes
+ * a callback function for each netlink message found. The callback
+ * function may refuse a message by returning a negative error code
+ * but setting the error pointer to 0 in which case this function
+ * returns with a qlen != 0.
+ *
+ * qlen must be initialized to 0 before the initial entry, afterwards
+ * the function may be called repeatedly until qlen reaches 0.
+ */
+void netlink_run_queue(struct sock *sk, unsigned int *qlen,
+ int (*cb)(struct sk_buff *, struct nlmsghdr *, int *))
+{
+ struct sk_buff *skb;
+
+ if (!*qlen || *qlen > skb_queue_len(&sk->sk_receive_queue))
+ *qlen = skb_queue_len(&sk->sk_receive_queue);
+
+ for (; *qlen; (*qlen)--) {
+ skb = skb_dequeue(&sk->sk_receive_queue);
+ if (netlink_rcv_skb(skb, cb)) {
+ if (skb->len)
+ skb_queue_head(&sk->sk_receive_queue, skb);
+ else {
+ kfree_skb(skb);
+ (*qlen)--;
+ }
+ break;
+ }
+
+ kfree_skb(skb);
+ }
+}
+
+/**
+ * netlink_queue_skip - Skip netlink message while processing queue.
+ * @nlh: Netlink message to be skipped
+ * @skb: Socket buffer containing the netlink messages.
+ *
+ * Pulls the given netlink message off the socket buffer so the next
+ * call to netlink_queue_run() will not reconsider the message.
+ */
+void netlink_queue_skip(struct nlmsghdr *nlh, struct sk_buff *skb)
+{
+ int msglen = NLMSG_ALIGN(nlh->nlmsg_len);
+
+ if (msglen > skb->len)
+ msglen = skb->len;
+
+ skb_pull(skb, msglen);
+}
#ifdef CONFIG_PROC_FS
struct nl_seq_iter {
@@ -1660,6 +1748,8 @@ out:
core_initcall(netlink_proto_init);
EXPORT_SYMBOL(netlink_ack);
+EXPORT_SYMBOL(netlink_run_queue);
+EXPORT_SYMBOL(netlink_queue_skip);
EXPORT_SYMBOL(netlink_broadcast);
EXPORT_SYMBOL(netlink_dump_start);
EXPORT_SYMBOL(netlink_kernel_create);
diff --git a/net/netlink/attr.c b/net/netlink/attr.c
new file mode 100644
index 000000000000..fffef4ab276f
--- /dev/null
+++ b/net/netlink/attr.c
@@ -0,0 +1,328 @@
+/*
+ * NETLINK Netlink attributes
+ *
+ * Authors: Thomas Graf <tgraf@suug.ch>
+ * Alexey Kuznetsov <kuznet@ms2.inr.ac.ru>
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/jiffies.h>
+#include <linux/netdevice.h>
+#include <linux/skbuff.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <net/netlink.h>
+
+static u16 nla_attr_minlen[NLA_TYPE_MAX+1] __read_mostly = {
+ [NLA_U8] = sizeof(u8),
+ [NLA_U16] = sizeof(u16),
+ [NLA_U32] = sizeof(u32),
+ [NLA_U64] = sizeof(u64),
+ [NLA_STRING] = 1,
+ [NLA_NESTED] = NLA_HDRLEN,
+};
+
+static int validate_nla(struct nlattr *nla, int maxtype,
+ struct nla_policy *policy)
+{
+ struct nla_policy *pt;
+ int minlen = 0;
+
+ if (nla->nla_type <= 0 || nla->nla_type > maxtype)
+ return 0;
+
+ pt = &policy[nla->nla_type];
+
+ BUG_ON(pt->type > NLA_TYPE_MAX);
+
+ if (pt->minlen)
+ minlen = pt->minlen;
+ else if (pt->type != NLA_UNSPEC)
+ minlen = nla_attr_minlen[pt->type];
+
+ if (pt->type == NLA_FLAG && nla_len(nla) > 0)
+ return -ERANGE;
+
+ if (nla_len(nla) < minlen)
+ return -ERANGE;
+
+ return 0;
+}
+
+/**
+ * nla_validate - Validate a stream of attributes
+ * @head: head of attribute stream
+ * @len: length of attribute stream
+ * @maxtype: maximum attribute type to be expected
+ * @policy: validation policy
+ *
+ * Validates all attributes in the specified attribute stream against the
+ * specified policy. Attributes with a type exceeding maxtype will be
+ * ignored. See documenation of struct nla_policy for more details.
+ *
+ * Returns 0 on success or a negative error code.
+ */
+int nla_validate(struct nlattr *head, int len, int maxtype,
+ struct nla_policy *policy)
+{
+ struct nlattr *nla;
+ int rem, err;
+
+ nla_for_each_attr(nla, head, len, rem) {
+ err = validate_nla(nla, maxtype, policy);
+ if (err < 0)
+ goto errout;
+ }
+
+ err = 0;
+errout:
+ return err;
+}
+
+/**
+ * nla_parse - Parse a stream of attributes into a tb buffer
+ * @tb: destination array with maxtype+1 elements
+ * @maxtype: maximum attribute type to be expected
+ * @head: head of attribute stream
+ * @len: length of attribute stream
+ *
+ * Parses a stream of attributes and stores a pointer to each attribute in
+ * the tb array accessable via the attribute type. Attributes with a type
+ * exceeding maxtype will be silently ignored for backwards compatibility
+ * reasons. policy may be set to NULL if no validation is required.
+ *
+ * Returns 0 on success or a negative error code.
+ */
+int nla_parse(struct nlattr *tb[], int maxtype, struct nlattr *head, int len,
+ struct nla_policy *policy)
+{
+ struct nlattr *nla;
+ int rem, err;
+
+ memset(tb, 0, sizeof(struct nlattr *) * (maxtype + 1));
+
+ nla_for_each_attr(nla, head, len, rem) {
+ u16 type = nla->nla_type;
+
+ if (type > 0 && type <= maxtype) {
+ if (policy) {
+ err = validate_nla(nla, maxtype, policy);
+ if (err < 0)
+ goto errout;
+ }
+
+ tb[type] = nla;
+ }
+ }
+
+ if (unlikely(rem > 0))
+ printk(KERN_WARNING "netlink: %d bytes leftover after parsing "
+ "attributes.\n", rem);
+
+ err = 0;
+errout:
+ return err;
+}
+
+/**
+ * nla_find - Find a specific attribute in a stream of attributes
+ * @head: head of attribute stream
+ * @len: length of attribute stream
+ * @attrtype: type of attribute to look for
+ *
+ * Returns the first attribute in the stream matching the specified type.
+ */
+struct nlattr *nla_find(struct nlattr *head, int len, int attrtype)
+{
+ struct nlattr *nla;
+ int rem;
+
+ nla_for_each_attr(nla, head, len, rem)
+ if (nla->nla_type == attrtype)
+ return nla;
+
+ return NULL;
+}
+
+/**
+ * nla_strlcpy - Copy string attribute payload into a sized buffer
+ * @dst: where to copy the string to
+ * @src: attribute to copy the string from
+ * @dstsize: size of destination buffer
+ *
+ * Copies at most dstsize - 1 bytes into the destination buffer.
+ * The result is always a valid NUL-terminated string. Unlike
+ * strlcpy the destination buffer is always padded out.
+ *
+ * Returns the length of the source buffer.
+ */
+size_t nla_strlcpy(char *dst, const struct nlattr *nla, size_t dstsize)
+{
+ size_t srclen = nla_len(nla);
+ char *src = nla_data(nla);
+
+ if (srclen > 0 && src[srclen - 1] == '\0')
+ srclen--;
+
+ if (dstsize > 0) {
+ size_t len = (srclen >= dstsize) ? dstsize - 1 : srclen;
+
+ memset(dst, 0, dstsize);
+ memcpy(dst, src, len);
+ }
+
+ return srclen;
+}
+
+/**
+ * nla_memcpy - Copy a netlink attribute into another memory area
+ * @dest: where to copy to memcpy
+ * @src: netlink attribute to copy from
+ * @count: size of the destination area
+ *
+ * Note: The number of bytes copied is limited by the length of
+ * attribute's payload. memcpy
+ *
+ * Returns the number of bytes copied.
+ */
+int nla_memcpy(void *dest, struct nlattr *src, int count)
+{
+ int minlen = min_t(int, count, nla_len(src));
+
+ memcpy(dest, nla_data(src), minlen);
+
+ return minlen;
+}
+
+/**
+ * nla_memcmp - Compare an attribute with sized memory area
+ * @nla: netlink attribute
+ * @data: memory area
+ * @size: size of memory area
+ */
+int nla_memcmp(const struct nlattr *nla, const void *data,
+ size_t size)
+{
+ int d = nla_len(nla) - size;
+
+ if (d == 0)
+ d = memcmp(nla_data(nla), data, size);
+
+ return d;
+}
+
+/**
+ * nla_strcmp - Compare a string attribute against a string
+ * @nla: netlink string attribute
+ * @str: another string
+ */
+int nla_strcmp(const struct nlattr *nla, const char *str)
+{
+ int len = strlen(str) + 1;
+ int d = nla_len(nla) - len;
+
+ if (d == 0)
+ d = memcmp(nla_data(nla), str, len);
+
+ return d;
+}
+
+/**
+ * __nla_reserve - reserve room for attribute on the skb
+ * @skb: socket buffer to reserve room on
+ * @attrtype: attribute type
+ * @attrlen: length of attribute payload
+ *
+ * Adds a netlink attribute header to a socket buffer and reserves
+ * room for the payload but does not copy it.
+ *
+ * The caller is responsible to ensure that the skb provides enough
+ * tailroom for the attribute header and payload.
+ */
+struct nlattr *__nla_reserve(struct sk_buff *skb, int attrtype, int attrlen)
+{
+ struct nlattr *nla;
+
+ nla = (struct nlattr *) skb_put(skb, nla_total_size(attrlen));
+ nla->nla_type = attrtype;
+ nla->nla_len = nla_attr_size(attrlen);
+
+ memset((unsigned char *) nla + nla->nla_len, 0, nla_padlen(attrlen));
+
+ return nla;
+}
+
+/**
+ * nla_reserve - reserve room for attribute on the skb
+ * @skb: socket buffer to reserve room on
+ * @attrtype: attribute type
+ * @attrlen: length of attribute payload
+ *
+ * Adds a netlink attribute header to a socket buffer and reserves
+ * room for the payload but does not copy it.
+ *
+ * Returns NULL if the tailroom of the skb is insufficient to store
+ * the attribute header and payload.
+ */
+struct nlattr *nla_reserve(struct sk_buff *skb, int attrtype, int attrlen)
+{
+ if (unlikely(skb_tailroom(skb) < nla_total_size(attrlen)))
+ return NULL;
+
+ return __nla_reserve(skb, attrtype, attrlen);
+}
+
+/**
+ * __nla_put - Add a netlink attribute to a socket buffer
+ * @skb: socket buffer to add attribute to
+ * @attrtype: attribute type
+ * @attrlen: length of attribute payload
+ * @data: head of attribute payload
+ *
+ * The caller is responsible to ensure that the skb provides enough
+ * tailroom for the attribute header and payload.
+ */
+void __nla_put(struct sk_buff *skb, int attrtype, int attrlen,
+ const void *data)
+{
+ struct nlattr *nla;
+
+ nla = __nla_reserve(skb, attrtype, attrlen);
+ memcpy(nla_data(nla), data, attrlen);
+}
+
+
+/**
+ * nla_put - Add a netlink attribute to a socket buffer
+ * @skb: socket buffer to add attribute to
+ * @attrtype: attribute type
+ * @attrlen: length of attribute payload
+ * @data: head of attribute payload
+ *
+ * Returns -1 if the tailroom of the skb is insufficient to store
+ * the attribute header and payload.
+ */
+int nla_put(struct sk_buff *skb, int attrtype, int attrlen, const void *data)
+{
+ if (unlikely(skb_tailroom(skb) < nla_total_size(attrlen)))
+ return -1;
+
+ __nla_put(skb, attrtype, attrlen, data);
+ return 0;
+}
+
+
+EXPORT_SYMBOL(nla_validate);
+EXPORT_SYMBOL(nla_parse);
+EXPORT_SYMBOL(nla_find);
+EXPORT_SYMBOL(nla_strlcpy);
+EXPORT_SYMBOL(__nla_reserve);
+EXPORT_SYMBOL(nla_reserve);
+EXPORT_SYMBOL(__nla_put);
+EXPORT_SYMBOL(nla_put);
+EXPORT_SYMBOL(nla_memcpy);
+EXPORT_SYMBOL(nla_memcmp);
+EXPORT_SYMBOL(nla_strcmp);
diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c
new file mode 100644
index 000000000000..287cfcc56951
--- /dev/null
+++ b/net/netlink/genetlink.c
@@ -0,0 +1,579 @@
+/*
+ * NETLINK Generic Netlink Family
+ *
+ * Authors: Jamal Hadi Salim
+ * Thomas Graf <tgraf@suug.ch>
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/types.h>
+#include <linux/socket.h>
+#include <linux/string.h>
+#include <linux/skbuff.h>
+#include <net/sock.h>
+#include <net/genetlink.h>
+
+struct sock *genl_sock = NULL;
+
+static DECLARE_MUTEX(genl_sem); /* serialization of message processing */
+
+static void genl_lock(void)
+{
+ down(&genl_sem);
+}
+
+static int genl_trylock(void)
+{
+ return down_trylock(&genl_sem);
+}
+
+static void genl_unlock(void)
+{
+ up(&genl_sem);
+
+ if (genl_sock && genl_sock->sk_receive_queue.qlen)
+ genl_sock->sk_data_ready(genl_sock, 0);
+}
+
+#define GENL_FAM_TAB_SIZE 16
+#define GENL_FAM_TAB_MASK (GENL_FAM_TAB_SIZE - 1)
+
+static struct list_head family_ht[GENL_FAM_TAB_SIZE];
+
+static int genl_ctrl_event(int event, void *data);
+
+static inline unsigned int genl_family_hash(unsigned int id)
+{
+ return id & GENL_FAM_TAB_MASK;
+}
+
+static inline struct list_head *genl_family_chain(unsigned int id)
+{
+ return &family_ht[genl_family_hash(id)];
+}
+
+static struct genl_family *genl_family_find_byid(unsigned int id)
+{
+ struct genl_family *f;
+
+ list_for_each_entry(f, genl_family_chain(id), family_list)
+ if (f->id == id)
+ return f;
+
+ return NULL;
+}
+
+static struct genl_family *genl_family_find_byname(char *name)
+{
+ struct genl_family *f;
+ int i;
+
+ for (i = 0; i < GENL_FAM_TAB_SIZE; i++)
+ list_for_each_entry(f, genl_family_chain(i), family_list)
+ if (strcmp(f->name, name) == 0)
+ return f;
+
+ return NULL;
+}
+
+static struct genl_ops *genl_get_cmd(u8 cmd, struct genl_family *family)
+{
+ struct genl_ops *ops;
+
+ list_for_each_entry(ops, &family->ops_list, ops_list)
+ if (ops->cmd == cmd)
+ return ops;
+
+ return NULL;
+}
+
+/* Of course we are going to have problems once we hit
+ * 2^16 alive types, but that can only happen by year 2K
+*/
+static inline u16 genl_generate_id(void)
+{
+ static u16 id_gen_idx;
+ int overflowed = 0;
+
+ do {
+ if (id_gen_idx == 0)
+ id_gen_idx = GENL_MIN_ID;
+
+ if (++id_gen_idx > GENL_MAX_ID) {
+ if (!overflowed) {
+ overflowed = 1;
+ id_gen_idx = 0;
+ continue;
+ } else
+ return 0;
+ }
+
+ } while (genl_family_find_byid(id_gen_idx));
+
+ return id_gen_idx;
+}
+
+/**
+ * genl_register_ops - register generic netlink operations
+ * @family: generic netlink family
+ * @ops: operations to be registered
+ *
+ * Registers the specified operations and assigns them to the specified
+ * family. Either a doit or dumpit callback must be specified or the
+ * operation will fail. Only one operation structure per command
+ * identifier may be registered.
+ *
+ * See include/net/genetlink.h for more documenation on the operations
+ * structure.
+ *
+ * Returns 0 on success or a negative error code.
+ */
+int genl_register_ops(struct genl_family *family, struct genl_ops *ops)
+{
+ int err = -EINVAL;
+
+ if (ops->dumpit == NULL && ops->doit == NULL)
+ goto errout;
+
+ if (genl_get_cmd(ops->cmd, family)) {
+ err = -EEXIST;
+ goto errout;
+ }
+
+ genl_lock();
+ list_add_tail(&ops->ops_list, &family->ops_list);
+ genl_unlock();
+
+ genl_ctrl_event(CTRL_CMD_NEWOPS, ops);
+ err = 0;
+errout:
+ return err;
+}
+
+/**
+ * genl_unregister_ops - unregister generic netlink operations
+ * @family: generic netlink family
+ * @ops: operations to be unregistered
+ *
+ * Unregisters the specified operations and unassigns them from the
+ * specified family. The operation blocks until the current message
+ * processing has finished and doesn't start again until the
+ * unregister process has finished.
+ *
+ * Note: It is not necessary to unregister all operations before
+ * unregistering the family, unregistering the family will cause
+ * all assigned operations to be unregistered automatically.
+ *
+ * Returns 0 on success or a negative error code.
+ */
+int genl_unregister_ops(struct genl_family *family, struct genl_ops *ops)
+{
+ struct genl_ops *rc;
+
+ genl_lock();
+ list_for_each_entry(rc, &family->ops_list, ops_list) {
+ if (rc == ops) {
+ list_del(&ops->ops_list);
+ genl_unlock();
+ genl_ctrl_event(CTRL_CMD_DELOPS, ops);
+ return 0;
+ }
+ }
+ genl_unlock();
+
+ return -ENOENT;
+}
+
+/**
+ * genl_register_family - register a generic netlink family
+ * @family: generic netlink family
+ *
+ * Registers the specified family after validating it first. Only one
+ * family may be registered with the same family name or identifier.
+ * The family id may equal GENL_ID_GENERATE causing an unique id to
+ * be automatically generated and assigned.
+ *
+ * Return 0 on success or a negative error code.
+ */
+int genl_register_family(struct genl_family *family)
+{
+ int err = -EINVAL;
+
+ if (family->id && family->id < GENL_MIN_ID)
+ goto errout;
+
+ if (family->id > GENL_MAX_ID)
+ goto errout;
+
+ INIT_LIST_HEAD(&family->ops_list);
+
+ genl_lock();
+
+ if (genl_family_find_byname(family->name)) {
+ err = -EEXIST;
+ goto errout_locked;
+ }
+
+ if (genl_family_find_byid(family->id)) {
+ err = -EEXIST;
+ goto errout_locked;
+ }
+
+ if (!try_module_get(family->owner)) {
+ err = -EBUSY;
+ goto errout_locked;
+ }
+
+ if (family->id == GENL_ID_GENERATE) {
+ u16 newid = genl_generate_id();
+
+ if (!newid) {
+ err = -ENOMEM;
+ goto errout_locked;
+ }
+
+ family->id = newid;
+ }
+
+ if (family->maxattr) {
+ family->attrbuf = kmalloc((family->maxattr+1) *
+ sizeof(struct nlattr *), GFP_KERNEL);
+ if (family->attrbuf == NULL) {
+ err = -ENOMEM;
+ goto errout;
+ }
+ } else
+ family->attrbuf = NULL;
+
+ list_add_tail(&family->family_list, genl_family_chain(family->id));
+ genl_unlock();
+
+ genl_ctrl_event(CTRL_CMD_NEWFAMILY, family);
+
+ return 0;
+
+errout_locked:
+ genl_unlock();
+errout:
+ return err;
+}
+
+/**
+ * genl_unregister_family - unregister generic netlink family
+ * @family: generic netlink family
+ *
+ * Unregisters the specified family.
+ *
+ * Returns 0 on success or a negative error code.
+ */
+int genl_unregister_family(struct genl_family *family)
+{
+ struct genl_family *rc;
+
+ genl_lock();
+
+ list_for_each_entry(rc, genl_family_chain(family->id), family_list) {
+ if (family->id != rc->id || strcmp(rc->name, family->name))
+ continue;
+
+ list_del(&rc->family_list);
+ INIT_LIST_HEAD(&family->ops_list);
+ genl_unlock();
+
+ module_put(family->owner);
+ kfree(family->attrbuf);
+ genl_ctrl_event(CTRL_CMD_DELFAMILY, family);
+ return 0;
+ }
+
+ genl_unlock();
+
+ return -ENOENT;
+}
+
+static inline int genl_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh,
+ int *errp)
+{
+ struct genl_ops *ops;
+ struct genl_family *family;
+ struct genl_info info;
+ struct genlmsghdr *hdr = nlmsg_data(nlh);
+ int hdrlen, err = -EINVAL;
+
+ if (!(nlh->nlmsg_flags & NLM_F_REQUEST))
+ goto ignore;
+
+ if (nlh->nlmsg_type < NLMSG_MIN_TYPE)
+ goto ignore;
+
+ family = genl_family_find_byid(nlh->nlmsg_type);
+ if (family == NULL) {
+ err = -ENOENT;
+ goto errout;
+ }
+
+ hdrlen = GENL_HDRLEN + family->hdrsize;
+ if (nlh->nlmsg_len < nlmsg_msg_size(hdrlen))
+ goto errout;
+
+ ops = genl_get_cmd(hdr->cmd, family);
+ if (ops == NULL) {
+ err = -EOPNOTSUPP;
+ goto errout;
+ }
+
+ if ((ops->flags & GENL_ADMIN_PERM) && security_netlink_recv(skb)) {
+ err = -EPERM;
+ goto errout;
+ }
+
+ if (nlh->nlmsg_flags & NLM_F_DUMP) {
+ if (ops->dumpit == NULL) {
+ err = -EOPNOTSUPP;
+ goto errout;
+ }
+
+ *errp = err = netlink_dump_start(genl_sock, skb, nlh,
+ ops->dumpit, NULL);
+ if (err == 0)
+ skb_pull(skb, min(NLMSG_ALIGN(nlh->nlmsg_len),
+ skb->len));
+ return -1;
+ }
+
+ if (ops->doit == NULL) {
+ err = -EOPNOTSUPP;
+ goto errout;
+ }
+
+ if (family->attrbuf) {
+ err = nlmsg_parse(nlh, hdrlen, family->attrbuf, family->maxattr,
+ ops->policy);
+ if (err < 0)
+ goto errout;
+ }
+
+ info.snd_seq = nlh->nlmsg_seq;
+ info.snd_pid = NETLINK_CB(skb).pid;
+ info.nlhdr = nlh;
+ info.genlhdr = nlmsg_data(nlh);
+ info.userhdr = nlmsg_data(nlh) + GENL_HDRLEN;
+ info.attrs = family->attrbuf;
+
+ *errp = err = ops->doit(skb, &info);
+ return err;
+
+ignore:
+ return 0;
+
+errout:
+ *errp = err;
+ return -1;
+}
+
+static void genl_rcv(struct sock *sk, int len)
+{
+ unsigned int qlen = 0;
+
+ do {
+ if (genl_trylock())
+ return;
+ netlink_run_queue(sk, &qlen, &genl_rcv_msg);
+ genl_unlock();
+ } while (qlen && genl_sock && genl_sock->sk_receive_queue.qlen);
+}
+
+/**************************************************************************
+ * Controller
+ **************************************************************************/
+
+static int ctrl_fill_info(struct genl_family *family, u32 pid, u32 seq,
+ u32 flags, struct sk_buff *skb, u8 cmd)
+{
+ void *hdr;
+
+ hdr = genlmsg_put(skb, pid, seq, GENL_ID_CTRL, 0, flags, cmd,
+ family->version);
+ if (hdr == NULL)
+ return -1;
+
+ NLA_PUT_STRING(skb, CTRL_ATTR_FAMILY_NAME, family->name);
+ NLA_PUT_U16(skb, CTRL_ATTR_FAMILY_ID, family->id);
+
+ return genlmsg_end(skb, hdr);
+
+nla_put_failure:
+ return genlmsg_cancel(skb, hdr);
+}
+
+static int ctrl_dumpfamily(struct sk_buff *skb, struct netlink_callback *cb)
+{
+
+ int i, n = 0;
+ struct genl_family *rt;
+ int chains_to_skip = cb->args[0];
+ int fams_to_skip = cb->args[1];
+
+ for (i = 0; i < GENL_FAM_TAB_SIZE; i++) {
+ if (i < chains_to_skip)
+ continue;
+ n = 0;
+ list_for_each_entry(rt, genl_family_chain(i), family_list) {
+ if (++n < fams_to_skip)
+ continue;
+ if (ctrl_fill_info(rt, NETLINK_CB(cb->skb).pid,
+ cb->nlh->nlmsg_seq, NLM_F_MULTI,
+ skb, CTRL_CMD_NEWFAMILY) < 0)
+ goto errout;
+ }
+
+ fams_to_skip = 0;
+ }
+
+errout:
+ cb->args[0] = i;
+ cb->args[1] = n;
+
+ return skb->len;
+}
+
+static struct sk_buff *ctrl_build_msg(struct genl_family *family, u32 pid,
+ int seq, int cmd)
+{
+ struct sk_buff *skb;
+ int err;
+
+ skb = nlmsg_new(NLMSG_GOODSIZE);
+ if (skb == NULL)
+ return ERR_PTR(-ENOBUFS);
+
+ err = ctrl_fill_info(family, pid, seq, 0, skb, cmd);
+ if (err < 0) {
+ nlmsg_free(skb);
+ return ERR_PTR(err);
+ }
+
+ return skb;
+}
+
+static struct nla_policy ctrl_policy[CTRL_ATTR_MAX+1] __read_mostly = {
+ [CTRL_ATTR_FAMILY_ID] = { .type = NLA_U16 },
+ [CTRL_ATTR_FAMILY_NAME] = { .type = NLA_STRING },
+};
+
+static int ctrl_getfamily(struct sk_buff *skb, struct genl_info *info)
+{
+ struct sk_buff *msg;
+ struct genl_family *res = NULL;
+ int err = -EINVAL;
+
+ if (info->attrs[CTRL_ATTR_FAMILY_ID]) {
+ u16 id = nla_get_u16(info->attrs[CTRL_ATTR_FAMILY_ID]);
+ res = genl_family_find_byid(id);
+ }
+
+ if (info->attrs[CTRL_ATTR_FAMILY_NAME]) {
+ char name[GENL_NAMSIZ];
+
+ if (nla_strlcpy(name, info->attrs[CTRL_ATTR_FAMILY_NAME],
+ GENL_NAMSIZ) >= GENL_NAMSIZ)
+ goto errout;
+
+ res = genl_family_find_byname(name);
+ }
+
+ if (res == NULL) {
+ err = -ENOENT;
+ goto errout;
+ }
+
+ msg = ctrl_build_msg(res, info->snd_pid, info->snd_seq,
+ CTRL_CMD_NEWFAMILY);
+ if (IS_ERR(msg)) {
+ err = PTR_ERR(msg);
+ goto errout;
+ }
+
+ err = genlmsg_unicast(msg, info->snd_pid);
+errout:
+ return err;
+}
+
+static int genl_ctrl_event(int event, void *data)
+{
+ struct sk_buff *msg;
+
+ if (genl_sock == NULL)
+ return 0;
+
+ switch (event) {
+ case CTRL_CMD_NEWFAMILY:
+ case CTRL_CMD_DELFAMILY:
+ msg = ctrl_build_msg(data, 0, 0, event);
+ if (IS_ERR(msg))
+ return PTR_ERR(msg);
+
+ genlmsg_multicast(msg, 0, GENL_ID_CTRL);
+ break;
+ }
+
+ return 0;
+}
+
+static struct genl_ops genl_ctrl_ops = {
+ .cmd = CTRL_CMD_GETFAMILY,
+ .doit = ctrl_getfamily,
+ .dumpit = ctrl_dumpfamily,
+ .policy = ctrl_policy,
+};
+
+static struct genl_family genl_ctrl = {
+ .id = GENL_ID_CTRL,
+ .name = "nlctrl",
+ .version = 0x1,
+ .maxattr = CTRL_ATTR_MAX,
+ .owner = THIS_MODULE,
+};
+
+static int __init genl_init(void)
+{
+ int i, err;
+
+ for (i = 0; i < GENL_FAM_TAB_SIZE; i++)
+ INIT_LIST_HEAD(&family_ht[i]);
+
+ err = genl_register_family(&genl_ctrl);
+ if (err < 0)
+ goto errout;
+
+ err = genl_register_ops(&genl_ctrl, &genl_ctrl_ops);
+ if (err < 0)
+ goto errout_register;
+
+ netlink_set_nonroot(NETLINK_GENERIC, NL_NONROOT_RECV);
+ genl_sock = netlink_kernel_create(NETLINK_GENERIC, GENL_MAX_ID,
+ genl_rcv, THIS_MODULE);
+ if (genl_sock == NULL) {
+ panic("GENL: Cannot initialize generic netlink\n");
+ return -ENOMEM;
+ }
+
+ return 0;
+
+errout_register:
+ genl_unregister_family(&genl_ctrl);
+errout:
+ panic("GENL: Cannot register controller: %d\n", err);
+ return err;
+}
+
+subsys_initcall(genl_init);
+
+EXPORT_SYMBOL(genl_sock);
+EXPORT_SYMBOL(genl_register_ops);
+EXPORT_SYMBOL(genl_unregister_ops);
+EXPORT_SYMBOL(genl_register_family);
+EXPORT_SYMBOL(genl_unregister_family);
diff --git a/net/rose/rose_route.c b/net/rose/rose_route.c
index e556d92c0bc4..8631b65a7312 100644
--- a/net/rose/rose_route.c
+++ b/net/rose/rose_route.c
@@ -240,8 +240,7 @@ static void rose_remove_neigh(struct rose_neigh *rose_neigh)
if ((s = rose_neigh_list) == rose_neigh) {
rose_neigh_list = rose_neigh->next;
spin_unlock_bh(&rose_neigh_list_lock);
- if (rose_neigh->digipeat != NULL)
- kfree(rose_neigh->digipeat);
+ kfree(rose_neigh->digipeat);
kfree(rose_neigh);
return;
}
@@ -250,8 +249,7 @@ static void rose_remove_neigh(struct rose_neigh *rose_neigh)
if (s->next == rose_neigh) {
s->next = rose_neigh->next;
spin_unlock_bh(&rose_neigh_list_lock);
- if (rose_neigh->digipeat != NULL)
- kfree(rose_neigh->digipeat);
+ kfree(rose_neigh->digipeat);
kfree(rose_neigh);
return;
}
@@ -727,7 +725,7 @@ int rose_rt_ioctl(unsigned int cmd, void __user *arg)
}
if (rose_route.mask > 10) /* Mask can't be more than 10 digits */
return -EINVAL;
- if (rose_route.ndigis > 8) /* No more than 8 digipeats */
+ if (rose_route.ndigis > AX25_MAX_DIGIS)
return -EINVAL;
err = rose_add_node(&rose_route, dev);
dev_put(dev);
diff --git a/net/rose/rose_timer.c b/net/rose/rose_timer.c
index 50ae0371dab8..b6c8f38cc26c 100644
--- a/net/rose/rose_timer.c
+++ b/net/rose/rose_timer.c
@@ -138,6 +138,7 @@ static void rose_heartbeat_expiry(unsigned long param)
is accepted() it isn't 'dead' so doesn't get removed. */
if (sock_flag(sk, SOCK_DESTROY) ||
(sk->sk_state == TCP_LISTEN && sock_flag(sk, SOCK_DEAD))) {
+ bh_unlock_sock(sk);
rose_destroy_socket(sk);
return;
}
diff --git a/net/rxrpc/transport.c b/net/rxrpc/transport.c
index 122c086ee2db..dbe6105e83a5 100644
--- a/net/rxrpc/transport.c
+++ b/net/rxrpc/transport.c
@@ -23,6 +23,7 @@
#include <linux/in.h>
#include <linux/in6.h>
#include <linux/icmp.h>
+#include <linux/skbuff.h>
#include <net/sock.h>
#include <net/ip.h>
#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
@@ -475,15 +476,11 @@ void rxrpc_trans_receive_packet(struct rxrpc_transport *trans)
/* we'll probably need to checksum it (didn't call
* sock_recvmsg) */
- if (pkt->ip_summed != CHECKSUM_UNNECESSARY) {
- if ((unsigned short)
- csum_fold(skb_checksum(pkt, 0, pkt->len,
- pkt->csum))) {
- kfree_skb(pkt);
- rxrpc_krxiod_queue_transport(trans);
- _leave(" CSUM failed");
- return;
- }
+ if (skb_checksum_complete(pkt)) {
+ kfree_skb(pkt);
+ rxrpc_krxiod_queue_transport(trans);
+ _leave(" CSUM failed");
+ return;
}
addr = pkt->nh.iph->saddr;
diff --git a/net/sched/Kconfig b/net/sched/Kconfig
index 81510da31792..7f34e7fd767c 100644
--- a/net/sched/Kconfig
+++ b/net/sched/Kconfig
@@ -2,13 +2,15 @@
# Traffic control configuration.
#
-menuconfig NET_SCHED
+menu "QoS and/or fair queueing"
+
+config NET_SCHED
bool "QoS and/or fair queueing"
---help---
When the kernel has several packets to send out over a network
device, it has to decide which ones to send first, which ones to
- delay, and which ones to drop. This is the job of the packet
- scheduler, and several different algorithms for how to do this
+ delay, and which ones to drop. This is the job of the queueing
+ disciplines, several different algorithms for how to do this
"fairly" have been proposed.
If you say N here, you will get the standard packet scheduler, which
@@ -23,13 +25,13 @@ menuconfig NET_SCHED
To administer these schedulers, you'll need the user-level utilities
from the package iproute2+tc at <ftp://ftp.tux.org/pub/net/ip-routing/>.
That package also contains some documentation; for more, check out
- <http://snafu.freedom.org/linux2.2/iproute-notes.html>.
+ <http://linux-net.osdl.org/index.php/Iproute2>.
This Quality of Service (QoS) support will enable you to use
Differentiated Services (diffserv) and Resource Reservation Protocol
- (RSVP) on your Linux router if you also say Y to "QoS support",
- "Packet classifier API" and to some classifiers below. Documentation
- and software is at <http://diffserv.sourceforge.net/>.
+ (RSVP) on your Linux router if you also say Y to the corresponding
+ classifiers below. Documentation and software is at
+ <http://diffserv.sourceforge.net/>.
If you say Y here and to "/proc file system" below, you will be able
to read status information about packet schedulers from the file
@@ -42,7 +44,7 @@ choice
prompt "Packet scheduler clock source"
depends on NET_SCHED
default NET_SCH_CLK_JIFFIES
- help
+ ---help---
Packet schedulers need a monotonic clock that increments at a static
rate. The kernel provides several suitable interfaces, each with
different properties:
@@ -56,7 +58,7 @@ choice
config NET_SCH_CLK_JIFFIES
bool "Timer interrupt"
- help
+ ---help---
Say Y here if you want to use the timer interrupt (jiffies) as clock
source. This clock source is fast, synchronized on all processors and
handles cpu clock frequency changes, but its resolution is too low
@@ -64,7 +66,7 @@ config NET_SCH_CLK_JIFFIES
config NET_SCH_CLK_GETTIMEOFDAY
bool "gettimeofday"
- help
+ ---help---
Say Y here if you want to use gettimeofday as clock source. This clock
source has high resolution, is synchronized on all processors and
handles cpu clock frequency changes, but it is slow.
@@ -77,7 +79,7 @@ config NET_SCH_CLK_GETTIMEOFDAY
config NET_SCH_CLK_CPU
bool "CPU cycle counter"
depends on ((X86_TSC || X86_64) && !SMP) || ALPHA || SPARC64 || PPC64 || IA64
- help
+ ---help---
Say Y here if you want to use the CPU's cycle counter as clock source.
This is a cheap and high resolution clock source, but on some
architectures it is not synchronized on all processors and doesn't
@@ -95,134 +97,129 @@ config NET_SCH_CLK_CPU
endchoice
+comment "Queueing/Scheduling"
+ depends on NET_SCHED
+
config NET_SCH_CBQ
- tristate "CBQ packet scheduler"
+ tristate "Class Based Queueing (CBQ)"
depends on NET_SCHED
---help---
Say Y here if you want to use the Class-Based Queueing (CBQ) packet
- scheduling algorithm for some of your network devices. This
- algorithm classifies the waiting packets into a tree-like hierarchy
- of classes; the leaves of this tree are in turn scheduled by
- separate algorithms (called "disciplines" in this context).
+ scheduling algorithm. This algorithm classifies the waiting packets
+ into a tree-like hierarchy of classes; the leaves of this tree are
+ in turn scheduled by separate algorithms.
- See the top of <file:net/sched/sch_cbq.c> for references about the
- CBQ algorithm.
+ See the top of <file:net/sched/sch_cbq.c> for more details.
CBQ is a commonly used scheduler, so if you're unsure, you should
say Y here. Then say Y to all the queueing algorithms below that you
- want to use as CBQ disciplines. Then say Y to "Packet classifier
- API" and say Y to all the classifiers you want to use; a classifier
- is a routine that allows you to sort your outgoing traffic into
- classes based on a certain criterion.
+ want to use as leaf disciplines.
To compile this code as a module, choose M here: the
module will be called sch_cbq.
config NET_SCH_HTB
- tristate "HTB packet scheduler"
+ tristate "Hierarchical Token Bucket (HTB)"
depends on NET_SCHED
---help---
Say Y here if you want to use the Hierarchical Token Buckets (HTB)
- packet scheduling algorithm for some of your network devices. See
+ packet scheduling algorithm. See
<http://luxik.cdi.cz/~devik/qos/htb/> for complete manual and
in-depth articles.
- HTB is very similar to the CBQ regarding its goals however is has
+ HTB is very similar to CBQ regarding its goals however is has
different properties and different algorithm.
To compile this code as a module, choose M here: the
module will be called sch_htb.
config NET_SCH_HFSC
- tristate "HFSC packet scheduler"
+ tristate "Hierarchical Fair Service Curve (HFSC)"
depends on NET_SCHED
---help---
Say Y here if you want to use the Hierarchical Fair Service Curve
- (HFSC) packet scheduling algorithm for some of your network devices.
+ (HFSC) packet scheduling algorithm.
To compile this code as a module, choose M here: the
module will be called sch_hfsc.
-#tristate ' H-PFQ packet scheduler' CONFIG_NET_SCH_HPFQ
config NET_SCH_ATM
- tristate "ATM pseudo-scheduler"
+ tristate "ATM Virtual Circuits (ATM)"
depends on NET_SCHED && ATM
---help---
Say Y here if you want to use the ATM pseudo-scheduler. This
- provides a framework for invoking classifiers (aka "filters"), which
- in turn select classes of this queuing discipline. Each class maps
- the flow(s) it is handling to a given virtual circuit (see the top of
- <file:net/sched/sch_atm.c>).
+ provides a framework for invoking classifiers, which in turn
+ select classes of this queuing discipline. Each class maps
+ the flow(s) it is handling to a given virtual circuit.
+
+ See the top of <file:net/sched/sch_atm.c>) for more details.
To compile this code as a module, choose M here: the
module will be called sch_atm.
config NET_SCH_PRIO
- tristate "The simplest PRIO pseudoscheduler"
+ tristate "Multi Band Priority Queueing (PRIO)"
depends on NET_SCHED
- help
+ ---help---
Say Y here if you want to use an n-band priority queue packet
- "scheduler" for some of your network devices or as a leaf discipline
- for the CBQ scheduling algorithm. If unsure, say Y.
+ scheduler.
To compile this code as a module, choose M here: the
module will be called sch_prio.
config NET_SCH_RED
- tristate "RED queue"
+ tristate "Random Early Detection (RED)"
depends on NET_SCHED
- help
+ ---help---
Say Y here if you want to use the Random Early Detection (RED)
- packet scheduling algorithm for some of your network devices (see
- the top of <file:net/sched/sch_red.c> for details and references
- about the algorithm).
+ packet scheduling algorithm.
+
+ See the top of <file:net/sched/sch_red.c> for more details.
To compile this code as a module, choose M here: the
module will be called sch_red.
config NET_SCH_SFQ
- tristate "SFQ queue"
+ tristate "Stochastic Fairness Queueing (SFQ)"
depends on NET_SCHED
---help---
Say Y here if you want to use the Stochastic Fairness Queueing (SFQ)
- packet scheduling algorithm for some of your network devices or as a
- leaf discipline for the CBQ scheduling algorithm (see the top of
- <file:net/sched/sch_sfq.c> for details and references about the SFQ
- algorithm).
+ packet scheduling algorithm .
+
+ See the top of <file:net/sched/sch_sfq.c> for more details.
To compile this code as a module, choose M here: the
module will be called sch_sfq.
config NET_SCH_TEQL
- tristate "TEQL queue"
+ tristate "True Link Equalizer (TEQL)"
depends on NET_SCHED
---help---
Say Y here if you want to use the True Link Equalizer (TLE) packet
- scheduling algorithm for some of your network devices or as a leaf
- discipline for the CBQ scheduling algorithm. This queueing
- discipline allows the combination of several physical devices into
- one virtual device. (see the top of <file:net/sched/sch_teql.c> for
- details).
+ scheduling algorithm. This queueing discipline allows the combination
+ of several physical devices into one virtual device.
+
+ See the top of <file:net/sched/sch_teql.c> for more details.
To compile this code as a module, choose M here: the
module will be called sch_teql.
config NET_SCH_TBF
- tristate "TBF queue"
+ tristate "Token Bucket Filter (TBF)"
depends on NET_SCHED
- help
- Say Y here if you want to use the Simple Token Bucket Filter (TBF)
- packet scheduling algorithm for some of your network devices or as a
- leaf discipline for the CBQ scheduling algorithm (see the top of
- <file:net/sched/sch_tbf.c> for a description of the TBF algorithm).
+ ---help---
+ Say Y here if you want to use the Token Bucket Filter (TBF) packet
+ scheduling algorithm.
+
+ See the top of <file:net/sched/sch_tbf.c> for more details.
To compile this code as a module, choose M here: the
module will be called sch_tbf.
config NET_SCH_GRED
- tristate "GRED queue"
+ tristate "Generic Random Early Detection (GRED)"
depends on NET_SCHED
- help
+ ---help---
Say Y here if you want to use the Generic Random Early Detection
(GRED) packet scheduling algorithm for some of your network devices
(see the top of <file:net/sched/sch_red.c> for details and
@@ -232,9 +229,9 @@ config NET_SCH_GRED
module will be called sch_gred.
config NET_SCH_DSMARK
- tristate "Diffserv field marker"
+ tristate "Differentiated Services marker (DSMARK)"
depends on NET_SCHED
- help
+ ---help---
Say Y if you want to schedule packets according to the
Differentiated Services architecture proposed in RFC 2475.
Technical information on this method, with pointers to associated
@@ -244,9 +241,9 @@ config NET_SCH_DSMARK
module will be called sch_dsmark.
config NET_SCH_NETEM
- tristate "Network emulator"
+ tristate "Network emulator (NETEM)"
depends on NET_SCHED
- help
+ ---help---
Say Y if you want to emulate network delay, loss, and packet
re-ordering. This is often useful to simulate networks when
testing applications or protocols.
@@ -259,58 +256,23 @@ config NET_SCH_NETEM
config NET_SCH_INGRESS
tristate "Ingress Qdisc"
depends on NET_SCHED
- help
- If you say Y here, you will be able to police incoming bandwidth
- and drop packets when this bandwidth exceeds your desired rate.
+ ---help---
+ Say Y here if you want to use classifiers for incoming packets.
If unsure, say Y.
To compile this code as a module, choose M here: the
module will be called sch_ingress.
-config NET_QOS
- bool "QoS support"
+comment "Classification"
depends on NET_SCHED
- ---help---
- Say Y here if you want to include Quality Of Service scheduling
- features, which means that you will be able to request certain
- rate-of-flow limits for your network devices.
-
- This Quality of Service (QoS) support will enable you to use
- Differentiated Services (diffserv) and Resource Reservation Protocol
- (RSVP) on your Linux router if you also say Y to "Packet classifier
- API" and to some classifiers below. Documentation and software is at
- <http://diffserv.sourceforge.net/>.
-
- Note that the answer to this question won't directly affect the
- kernel: saying N will just cause the configurator to skip all
- the questions about QoS support.
-
-config NET_ESTIMATOR
- bool "Rate estimator"
- depends on NET_QOS
- help
- In order for Quality of Service scheduling to work, the current
- rate-of-flow for a network device has to be estimated; if you say Y
- here, the kernel will do just that.
config NET_CLS
- bool "Packet classifier API"
- depends on NET_SCHED
- ---help---
- The CBQ scheduling algorithm requires that network packets which are
- scheduled to be sent out over a network device be classified
- according to some criterion. If you say Y here, you will get a
- choice of several different packet classifiers with the following
- questions.
-
- This will enable you to use Differentiated Services (diffserv) and
- Resource Reservation Protocol (RSVP) on your Linux router.
- Documentation and software is at
- <http://diffserv.sourceforge.net/>.
+ boolean
config NET_CLS_BASIC
- tristate "Basic classifier"
- depends on NET_CLS
+ tristate "Elementary classification (BASIC)"
+ depends NET_SCHED
+ select NET_CLS
---help---
Say Y here if you want to be able to classify packets using
only extended matches and actions.
@@ -319,24 +281,25 @@ config NET_CLS_BASIC
module will be called cls_basic.
config NET_CLS_TCINDEX
- tristate "TC index classifier"
- depends on NET_CLS
- help
- If you say Y here, you will be able to classify outgoing packets
- according to the tc_index field of the skb. You will want this
- feature if you want to implement Differentiated Services using
- sch_dsmark. If unsure, say Y.
+ tristate "Traffic-Control Index (TCINDEX)"
+ depends NET_SCHED
+ select NET_CLS
+ ---help---
+ Say Y here if you want to be able to classify packets based on
+ traffic control indices. You will want this feature if you want
+ to implement Differentiated Services together with DSMARK.
To compile this code as a module, choose M here: the
module will be called cls_tcindex.
config NET_CLS_ROUTE4
- tristate "Routing table based classifier"
- depends on NET_CLS
+ tristate "Routing decision (ROUTE)"
+ depends NET_SCHED
select NET_CLS_ROUTE
- help
- If you say Y here, you will be able to classify outgoing packets
- according to the route table entry they matched. If unsure, say Y.
+ select NET_CLS
+ ---help---
+ If you say Y here, you will be able to classify packets
+ according to the route table entry they matched.
To compile this code as a module, choose M here: the
module will be called cls_route.
@@ -346,58 +309,45 @@ config NET_CLS_ROUTE
default n
config NET_CLS_FW
- tristate "Firewall based classifier"
- depends on NET_CLS
- help
- If you say Y here, you will be able to classify outgoing packets
- according to firewall criteria you specified.
+ tristate "Netfilter mark (FW)"
+ depends NET_SCHED
+ select NET_CLS
+ ---help---
+ If you say Y here, you will be able to classify packets
+ according to netfilter/firewall marks.
To compile this code as a module, choose M here: the
module will be called cls_fw.
config NET_CLS_U32
- tristate "U32 classifier"
- depends on NET_CLS
- help
- If you say Y here, you will be able to classify outgoing packets
- according to their destination address. If unsure, say Y.
+ tristate "Universal 32bit comparisons w/ hashing (U32)"
+ depends NET_SCHED
+ select NET_CLS
+ ---help---
+ Say Y here to be able to classify packetes using a universal
+ 32bit pieces based comparison scheme.
To compile this code as a module, choose M here: the
module will be called cls_u32.
config CLS_U32_PERF
- bool "U32 classifier performance counters"
+ bool "Performance counters support"
depends on NET_CLS_U32
- help
- gathers stats that could be used to tune u32 classifier performance.
- Requires a new iproute2
- You MUST NOT turn this on if you dont have an update iproute2.
-
-config NET_CLS_IND
- bool "classify input device (slows things u32/fw) "
- depends on NET_CLS_U32 || NET_CLS_FW
- help
- This option will be killed eventually when a
- metadata action appears because it slows things a little
- Available only for u32 and fw classifiers.
- Requires a new iproute2
- You MUST NOT turn this on if you dont have an update iproute2.
+ ---help---
+ Say Y here to make u32 gather additional statistics useful for
+ fine tuning u32 classifiers.
config CLS_U32_MARK
- bool "Use nfmark as a key in U32 classifier"
+ bool "Netfilter marks support"
depends on NET_CLS_U32 && NETFILTER
- help
- This allows you to match mark in a u32 filter.
- Example:
- tc filter add dev eth0 protocol ip parent 1:0 prio 5 u32 \
- match mark 0x0090 0xffff \
- match ip dst 4.4.4.4 \
- flowid 1:90
- You must use a new iproute2 to use this feature.
+ ---help---
+ Say Y here to be able to use netfilter marks as u32 key.
config NET_CLS_RSVP
- tristate "Special RSVP classifier"
- depends on NET_CLS && NET_QOS
+ tristate "IPv4 Resource Reservation Protocol (RSVP)"
+ depends on NET_SCHED
+ select NET_CLS
+ select NET_ESTIMATOR
---help---
The Resource Reservation Protocol (RSVP) permits end systems to
request a minimum and maximum data flow rate for a connection; this
@@ -410,31 +360,33 @@ config NET_CLS_RSVP
module will be called cls_rsvp.
config NET_CLS_RSVP6
- tristate "Special RSVP classifier for IPv6"
- depends on NET_CLS && NET_QOS
+ tristate "IPv6 Resource Reservation Protocol (RSVP6)"
+ depends on NET_SCHED
+ select NET_CLS
+ select NET_ESTIMATOR
---help---
The Resource Reservation Protocol (RSVP) permits end systems to
request a minimum and maximum data flow rate for a connection; this
is important for real time data such as streaming sound or video.
Say Y here if you want to be able to classify outgoing packets based
- on their RSVP requests and you are using the new Internet Protocol
- IPv6 as opposed to the older and more common IPv4.
+ on their RSVP requests and you are using the IPv6.
To compile this code as a module, choose M here: the
module will be called cls_rsvp6.
config NET_EMATCH
bool "Extended Matches"
- depends on NET_CLS
+ depends NET_SCHED
+ select NET_CLS
---help---
Say Y here if you want to use extended matches on top of classifiers
and select the extended matches below.
Extended matches are small classification helpers not worth writing
- a separate classifier.
+ a separate classifier for.
- You must have a recent version of the iproute2 tools in order to use
+ A recent version of the iproute2 package is required to use
extended matches.
config NET_EMATCH_STACK
@@ -468,7 +420,7 @@ config NET_EMATCH_NBYTE
module will be called em_nbyte.
config NET_EMATCH_U32
- tristate "U32 hashing key"
+ tristate "U32 key"
depends on NET_EMATCH
---help---
Say Y here if you want to be able to classify packets using
@@ -496,76 +448,120 @@ config NET_EMATCH_TEXT
select TEXTSEARCH_BM
select TEXTSEARCH_FSM
---help---
- Say Y here if you want to be ablt to classify packets based on
+ Say Y here if you want to be able to classify packets based on
textsearch comparisons.
To compile this code as a module, choose M here: the
module will be called em_text.
config NET_CLS_ACT
- bool "Packet ACTION"
- depends on EXPERIMENTAL && NET_CLS && NET_QOS
+ bool "Actions"
+ depends on EXPERIMENTAL && NET_SCHED
+ select NET_ESTIMATOR
---help---
- This option requires you have a new iproute2. It enables
- tc extensions which can be used with tc classifiers.
- You MUST NOT turn this on if you dont have an update iproute2.
+ Say Y here if you want to use traffic control actions. Actions
+ get attached to classifiers and are invoked after a successful
+ classification. They are used to overwrite the classification
+ result, instantly drop or redirect packets, etc.
+
+ A recent version of the iproute2 package is required to use
+ extended matches.
config NET_ACT_POLICE
- tristate "Policing Actions"
+ tristate "Traffic Policing"
depends on NET_CLS_ACT
---help---
- If you are using a newer iproute2 select this one, otherwise use one
- below to select a policer.
- You MUST NOT turn this on if you dont have an update iproute2.
+ Say Y here if you want to do traffic policing, i.e. strict
+ bandwidth limiting. This action replaces the existing policing
+ module.
+
+ To compile this code as a module, choose M here: the
+ module will be called police.
config NET_ACT_GACT
- tristate "generic Actions"
+ tristate "Generic actions"
depends on NET_CLS_ACT
---help---
- You must have new iproute2 to use this feature.
- This adds simple filtering actions like drop, accept etc.
+ Say Y here to take generic actions such as dropping and
+ accepting packets.
+
+ To compile this code as a module, choose M here: the
+ module will be called gact.
config GACT_PROB
- bool "generic Actions probability"
+ bool "Probability support"
depends on NET_ACT_GACT
---help---
- Allows generic actions to be randomly or deterministically used.
+ Say Y here to use the generic action randomly or deterministically.
config NET_ACT_MIRRED
- tristate "Packet In/Egress redirecton/mirror Actions"
+ tristate "Redirecting and Mirroring"
depends on NET_CLS_ACT
---help---
- requires new iproute2
- This allows packets to be mirrored or redirected to netdevices
+ Say Y here to allow packets to be mirrored or redirected to
+ other devices.
+
+ To compile this code as a module, choose M here: the
+ module will be called mirred.
config NET_ACT_IPT
- tristate "iptables Actions"
+ tristate "IPtables targets"
depends on NET_CLS_ACT && NETFILTER && IP_NF_IPTABLES
---help---
- requires new iproute2
- This allows iptables targets to be used by tc filters
+ Say Y here to be able to invoke iptables targets after succesful
+ classification.
+
+ To compile this code as a module, choose M here: the
+ module will be called ipt.
config NET_ACT_PEDIT
- tristate "Generic Packet Editor Actions"
+ tristate "Packet Editing"
depends on NET_CLS_ACT
---help---
- requires new iproute2
- This allows for packets to be generically edited
+ Say Y here if you want to mangle the content of packets.
-config NET_CLS_POLICE
- bool "Traffic policing (needed for in/egress)"
- depends on NET_CLS && NET_QOS && NET_CLS_ACT!=y
- help
- Say Y to support traffic policing (bandwidth limits). Needed for
- ingress and egress rate limiting.
+ To compile this code as a module, choose M here: the
+ module will be called pedit.
config NET_ACT_SIMP
- tristate "Simple action"
+ tristate "Simple Example (Debug)"
depends on NET_CLS_ACT
---help---
- You must have new iproute2 to use this feature.
- This adds a very simple action for demonstration purposes
- The idea is to give action authors a basic example to look at.
- All this action will do is print on the console the configured
- policy string followed by _ then packet count.
+ Say Y here to add a simple action for demonstration purposes.
+ It is meant as an example and for debugging purposes. It will
+ print a configured policy string followed by the packet count
+ to the console for every packet that passes by.
+
+ If unsure, say N.
+
+ To compile this code as a module, choose M here: the
+ module will be called simple.
+
+config NET_CLS_POLICE
+ bool "Traffic Policing (obsolete)"
+ depends on NET_SCHED && NET_CLS_ACT!=y
+ select NET_ESTIMATOR
+ ---help---
+ Say Y here if you want to do traffic policing, i.e. strict
+ bandwidth limiting. This option is obsoleted by the traffic
+ policer implemented as action, it stays here for compatibility
+ reasons.
+
+config NET_CLS_IND
+ bool "Incoming device classification"
+ depends on NET_SCHED && (NET_CLS_U32 || NET_CLS_FW)
+ ---help---
+ Say Y here to extend the u32 and fw classifier to support
+ classification based on the incoming device. This option is
+ likely to disappear in favour of the metadata ematch.
+
+config NET_ESTIMATOR
+ bool "Rate estimator"
+ depends on NET_SCHED
+ ---help---
+ Say Y here to allow using rate estimators to estimate the current
+ rate-of-flow for network devices, queues, etc. This module is
+ automaticaly selected if needed but can be selected manually for
+ statstical purposes.
+endmenu
diff --git a/net/sched/cls_fw.c b/net/sched/cls_fw.c
index 29d8b9a4d162..75470486e405 100644
--- a/net/sched/cls_fw.c
+++ b/net/sched/cls_fw.c
@@ -298,8 +298,7 @@ static int fw_change(struct tcf_proto *tp, unsigned long base,
return 0;
errout:
- if (f)
- kfree(f);
+ kfree(f);
return err;
}
diff --git a/net/sched/cls_route.c b/net/sched/cls_route.c
index 02996ac05c75..520ff716dab2 100644
--- a/net/sched/cls_route.c
+++ b/net/sched/cls_route.c
@@ -525,8 +525,7 @@ reinsert:
return 0;
errout:
- if (f)
- kfree(f);
+ kfree(f);
return err;
}
diff --git a/net/sched/cls_rsvp.h b/net/sched/cls_rsvp.h
index 006168d69376..572f06be3b02 100644
--- a/net/sched/cls_rsvp.h
+++ b/net/sched/cls_rsvp.h
@@ -555,8 +555,7 @@ insert:
goto insert;
errout:
- if (f)
- kfree(f);
+ kfree(f);
errout2:
tcf_exts_destroy(tp, &e);
return err;
diff --git a/net/sched/cls_tcindex.c b/net/sched/cls_tcindex.c
index 404d9d83a7fa..9f921174c8ab 100644
--- a/net/sched/cls_tcindex.c
+++ b/net/sched/cls_tcindex.c
@@ -194,8 +194,7 @@ found:
}
tcf_unbind_filter(tp, &r->res);
tcf_exts_destroy(tp, &r->exts);
- if (f)
- kfree(f);
+ kfree(f);
return 0;
}
@@ -442,10 +441,8 @@ static void tcindex_destroy(struct tcf_proto *tp)
walker.skip = 0;
walker.fn = &tcindex_destroy_element;
tcindex_walk(tp,&walker);
- if (p->perfect)
- kfree(p->perfect);
- if (p->h)
- kfree(p->h);
+ kfree(p->perfect);
+ kfree(p->h);
kfree(p);
tp->root = NULL;
}
diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c
index 364b87d86455..2b670479dde1 100644
--- a/net/sched/cls_u32.c
+++ b/net/sched/cls_u32.c
@@ -347,7 +347,7 @@ static int u32_destroy_key(struct tcf_proto *tp, struct tc_u_knode *n)
if (n->ht_down)
n->ht_down->refcnt--;
#ifdef CONFIG_CLS_U32_PERF
- if (n && (NULL != n->pf))
+ if (n)
kfree(n->pf);
#endif
kfree(n);
@@ -680,7 +680,7 @@ static int u32_change(struct tcf_proto *tp, unsigned long base, u32 handle,
return 0;
}
#ifdef CONFIG_CLS_U32_PERF
- if (n && (NULL != n->pf))
+ if (n)
kfree(n->pf);
#endif
kfree(n);
diff --git a/net/sched/em_meta.c b/net/sched/em_meta.c
index cf68a59fdc5a..700844d49d79 100644
--- a/net/sched/em_meta.c
+++ b/net/sched/em_meta.c
@@ -561,8 +561,7 @@ static int meta_var_change(struct meta_value *dst, struct rtattr *rta)
static void meta_var_destroy(struct meta_value *v)
{
- if (v->val)
- kfree((void *) v->val);
+ kfree((void *) v->val);
}
static void meta_var_apply_extras(struct meta_value *v,
diff --git a/net/sched/ematch.c b/net/sched/ematch.c
index ebfe2e7d21bd..64b047c65568 100644
--- a/net/sched/ematch.c
+++ b/net/sched/ematch.c
@@ -298,6 +298,11 @@ int tcf_em_tree_validate(struct tcf_proto *tp, struct rtattr *rta,
struct tcf_ematch_tree_hdr *tree_hdr;
struct tcf_ematch *em;
+ if (!rta) {
+ memset(tree, 0, sizeof(*tree));
+ return 0;
+ }
+
if (rtattr_parse_nested(tb, TCA_EMATCH_TREE_MAX, rta) < 0)
goto errout;
diff --git a/net/sched/sch_gred.c b/net/sched/sch_gred.c
index 25c171c32715..29a2dd9f3029 100644
--- a/net/sched/sch_gred.c
+++ b/net/sched/sch_gred.c
@@ -15,247 +15,281 @@
* from Ren Liu
* - More error checks
*
- *
- *
- * For all the glorious comments look at Alexey's sch_red.c
+ * For all the glorious comments look at include/net/red.h
*/
#include <linux/config.h>
#include <linux/module.h>
-#include <asm/uaccess.h>
-#include <asm/system.h>
-#include <linux/bitops.h>
#include <linux/types.h>
#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/socket.h>
-#include <linux/sockios.h>
-#include <linux/in.h>
-#include <linux/errno.h>
-#include <linux/interrupt.h>
-#include <linux/if_ether.h>
-#include <linux/inet.h>
#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/notifier.h>
-#include <net/ip.h>
-#include <net/route.h>
#include <linux/skbuff.h>
-#include <net/sock.h>
#include <net/pkt_sched.h>
+#include <net/red.h>
-#if 1 /* control */
-#define DPRINTK(format,args...) printk(KERN_DEBUG format,##args)
-#else
-#define DPRINTK(format,args...)
-#endif
-
-#if 0 /* data */
-#define D2PRINTK(format,args...) printk(KERN_DEBUG format,##args)
-#else
-#define D2PRINTK(format,args...)
-#endif
+#define GRED_DEF_PRIO (MAX_DPs / 2)
+#define GRED_VQ_MASK (MAX_DPs - 1)
struct gred_sched_data;
struct gred_sched;
struct gred_sched_data
{
-/* Parameters */
u32 limit; /* HARD maximal queue length */
- u32 qth_min; /* Min average length threshold: A scaled */
- u32 qth_max; /* Max average length threshold: A scaled */
u32 DP; /* the drop pramaters */
- char Wlog; /* log(W) */
- char Plog; /* random number bits */
- u32 Scell_max;
- u32 Rmask;
u32 bytesin; /* bytes seen on virtualQ so far*/
u32 packetsin; /* packets seen on virtualQ so far*/
u32 backlog; /* bytes on the virtualQ */
- u32 forced; /* packets dropped for exceeding limits */
- u32 early; /* packets dropped as a warning */
- u32 other; /* packets dropped by invoking drop() */
- u32 pdrop; /* packets dropped because we exceeded physical queue limits */
- char Scell_log;
- u8 Stab[256];
- u8 prio; /* the prio of this vq */
-
-/* Variables */
- unsigned long qave; /* Average queue length: A scaled */
- int qcount; /* Packets since last random number generation */
- u32 qR; /* Cached random number */
-
- psched_time_t qidlestart; /* Start of idle period */
+ u8 prio; /* the prio of this vq */
+
+ struct red_parms parms;
+ struct red_stats stats;
+};
+
+enum {
+ GRED_WRED_MODE = 1,
+ GRED_RIO_MODE,
};
struct gred_sched
{
struct gred_sched_data *tab[MAX_DPs];
- u32 DPs;
- u32 def;
- u8 initd;
- u8 grio;
- u8 eqp;
+ unsigned long flags;
+ u32 red_flags;
+ u32 DPs;
+ u32 def;
+ struct red_parms wred_set;
};
-static int
-gred_enqueue(struct sk_buff *skb, struct Qdisc* sch)
+static inline int gred_wred_mode(struct gred_sched *table)
{
- psched_time_t now;
- struct gred_sched_data *q=NULL;
- struct gred_sched *t= qdisc_priv(sch);
- unsigned long qave=0;
- int i=0;
+ return test_bit(GRED_WRED_MODE, &table->flags);
+}
+
+static inline void gred_enable_wred_mode(struct gred_sched *table)
+{
+ __set_bit(GRED_WRED_MODE, &table->flags);
+}
+
+static inline void gred_disable_wred_mode(struct gred_sched *table)
+{
+ __clear_bit(GRED_WRED_MODE, &table->flags);
+}
+
+static inline int gred_rio_mode(struct gred_sched *table)
+{
+ return test_bit(GRED_RIO_MODE, &table->flags);
+}
+
+static inline void gred_enable_rio_mode(struct gred_sched *table)
+{
+ __set_bit(GRED_RIO_MODE, &table->flags);
+}
+
+static inline void gred_disable_rio_mode(struct gred_sched *table)
+{
+ __clear_bit(GRED_RIO_MODE, &table->flags);
+}
+
+static inline int gred_wred_mode_check(struct Qdisc *sch)
+{
+ struct gred_sched *table = qdisc_priv(sch);
+ int i;
- if (!t->initd && skb_queue_len(&sch->q) < (sch->dev->tx_queue_len ? : 1)) {
- D2PRINTK("NO GRED Queues setup yet! Enqueued anyway\n");
- goto do_enqueue;
+ /* Really ugly O(n^2) but shouldn't be necessary too frequent. */
+ for (i = 0; i < table->DPs; i++) {
+ struct gred_sched_data *q = table->tab[i];
+ int n;
+
+ if (q == NULL)
+ continue;
+
+ for (n = 0; n < table->DPs; n++)
+ if (table->tab[n] && table->tab[n] != q &&
+ table->tab[n]->prio == q->prio)
+ return 1;
}
+ return 0;
+}
+
+static inline unsigned int gred_backlog(struct gred_sched *table,
+ struct gred_sched_data *q,
+ struct Qdisc *sch)
+{
+ if (gred_wred_mode(table))
+ return sch->qstats.backlog;
+ else
+ return q->backlog;
+}
+
+static inline u16 tc_index_to_dp(struct sk_buff *skb)
+{
+ return skb->tc_index & GRED_VQ_MASK;
+}
+
+static inline void gred_load_wred_set(struct gred_sched *table,
+ struct gred_sched_data *q)
+{
+ q->parms.qavg = table->wred_set.qavg;
+ q->parms.qidlestart = table->wred_set.qidlestart;
+}
+
+static inline void gred_store_wred_set(struct gred_sched *table,
+ struct gred_sched_data *q)
+{
+ table->wred_set.qavg = q->parms.qavg;
+}
+
+static inline int gred_use_ecn(struct gred_sched *t)
+{
+ return t->red_flags & TC_RED_ECN;
+}
- if ( ((skb->tc_index&0xf) > (t->DPs -1)) || !(q=t->tab[skb->tc_index&0xf])) {
- printk("GRED: setting to default (%d)\n ",t->def);
- if (!(q=t->tab[t->def])) {
- DPRINTK("GRED: setting to default FAILED! dropping!! "
- "(%d)\n ", t->def);
- goto drop;
+static inline int gred_use_harddrop(struct gred_sched *t)
+{
+ return t->red_flags & TC_RED_HARDDROP;
+}
+
+static int gred_enqueue(struct sk_buff *skb, struct Qdisc* sch)
+{
+ struct gred_sched_data *q=NULL;
+ struct gred_sched *t= qdisc_priv(sch);
+ unsigned long qavg = 0;
+ u16 dp = tc_index_to_dp(skb);
+
+ if (dp >= t->DPs || (q = t->tab[dp]) == NULL) {
+ dp = t->def;
+
+ if ((q = t->tab[dp]) == NULL) {
+ /* Pass through packets not assigned to a DP
+ * if no default DP has been configured. This
+ * allows for DP flows to be left untouched.
+ */
+ if (skb_queue_len(&sch->q) < sch->dev->tx_queue_len)
+ return qdisc_enqueue_tail(skb, sch);
+ else
+ goto drop;
}
+
/* fix tc_index? --could be controvesial but needed for
requeueing */
- skb->tc_index=(skb->tc_index&0xfffffff0) | t->def;
+ skb->tc_index = (skb->tc_index & ~GRED_VQ_MASK) | dp;
}
- D2PRINTK("gred_enqueue virtualQ 0x%x classid %x backlog %d "
- "general backlog %d\n",skb->tc_index&0xf,sch->handle,q->backlog,
- sch->qstats.backlog);
- /* sum up all the qaves of prios <= to ours to get the new qave*/
- if (!t->eqp && t->grio) {
- for (i=0;i<t->DPs;i++) {
- if ((!t->tab[i]) || (i==q->DP))
- continue;
-
- if ((t->tab[i]->prio < q->prio) && (PSCHED_IS_PASTPERFECT(t->tab[i]->qidlestart)))
- qave +=t->tab[i]->qave;
+ /* sum up all the qaves of prios <= to ours to get the new qave */
+ if (!gred_wred_mode(t) && gred_rio_mode(t)) {
+ int i;
+
+ for (i = 0; i < t->DPs; i++) {
+ if (t->tab[i] && t->tab[i]->prio < q->prio &&
+ !red_is_idling(&t->tab[i]->parms))
+ qavg +=t->tab[i]->parms.qavg;
}
-
+
}
q->packetsin++;
- q->bytesin+=skb->len;
+ q->bytesin += skb->len;
- if (t->eqp && t->grio) {
- qave=0;
- q->qave=t->tab[t->def]->qave;
- q->qidlestart=t->tab[t->def]->qidlestart;
- }
+ if (gred_wred_mode(t))
+ gred_load_wred_set(t, q);
- if (!PSCHED_IS_PASTPERFECT(q->qidlestart)) {
- long us_idle;
- PSCHED_GET_TIME(now);
- us_idle = PSCHED_TDIFF_SAFE(now, q->qidlestart, q->Scell_max);
- PSCHED_SET_PASTPERFECT(q->qidlestart);
+ q->parms.qavg = red_calc_qavg(&q->parms, gred_backlog(t, q, sch));
- q->qave >>= q->Stab[(us_idle>>q->Scell_log)&0xFF];
- } else {
- if (t->eqp) {
- q->qave += sch->qstats.backlog - (q->qave >> q->Wlog);
- } else {
- q->qave += q->backlog - (q->qave >> q->Wlog);
- }
+ if (red_is_idling(&q->parms))
+ red_end_of_idle_period(&q->parms);
- }
-
-
- if (t->eqp && t->grio)
- t->tab[t->def]->qave=q->qave;
-
- if ((q->qave+qave) < q->qth_min) {
- q->qcount = -1;
-enqueue:
- if (q->backlog + skb->len <= q->limit) {
- q->backlog += skb->len;
-do_enqueue:
- __skb_queue_tail(&sch->q, skb);
- sch->qstats.backlog += skb->len;
- sch->bstats.bytes += skb->len;
- sch->bstats.packets++;
- return 0;
- } else {
- q->pdrop++;
- }
+ if (gred_wred_mode(t))
+ gred_store_wred_set(t, q);
-drop:
- kfree_skb(skb);
- sch->qstats.drops++;
- return NET_XMIT_DROP;
- }
- if ((q->qave+qave) >= q->qth_max) {
- q->qcount = -1;
- sch->qstats.overlimits++;
- q->forced++;
- goto drop;
+ switch (red_action(&q->parms, q->parms.qavg + qavg)) {
+ case RED_DONT_MARK:
+ break;
+
+ case RED_PROB_MARK:
+ sch->qstats.overlimits++;
+ if (!gred_use_ecn(t) || !INET_ECN_set_ce(skb)) {
+ q->stats.prob_drop++;
+ goto congestion_drop;
+ }
+
+ q->stats.prob_mark++;
+ break;
+
+ case RED_HARD_MARK:
+ sch->qstats.overlimits++;
+ if (gred_use_harddrop(t) || !gred_use_ecn(t) ||
+ !INET_ECN_set_ce(skb)) {
+ q->stats.forced_drop++;
+ goto congestion_drop;
+ }
+ q->stats.forced_mark++;
+ break;
}
- if (++q->qcount) {
- if ((((qave+q->qave) - q->qth_min)>>q->Wlog)*q->qcount < q->qR)
- goto enqueue;
- q->qcount = 0;
- q->qR = net_random()&q->Rmask;
- sch->qstats.overlimits++;
- q->early++;
- goto drop;
+
+ if (q->backlog + skb->len <= q->limit) {
+ q->backlog += skb->len;
+ return qdisc_enqueue_tail(skb, sch);
}
- q->qR = net_random()&q->Rmask;
- goto enqueue;
+
+ q->stats.pdrop++;
+drop:
+ return qdisc_drop(skb, sch);
+
+congestion_drop:
+ qdisc_drop(skb, sch);
+ return NET_XMIT_CN;
}
-static int
-gred_requeue(struct sk_buff *skb, struct Qdisc* sch)
+static int gred_requeue(struct sk_buff *skb, struct Qdisc* sch)
{
+ struct gred_sched *t = qdisc_priv(sch);
struct gred_sched_data *q;
- struct gred_sched *t= qdisc_priv(sch);
- q= t->tab[(skb->tc_index&0xf)];
-/* error checking here -- probably unnecessary */
- PSCHED_SET_PASTPERFECT(q->qidlestart);
-
- __skb_queue_head(&sch->q, skb);
- sch->qstats.backlog += skb->len;
- sch->qstats.requeues++;
- q->backlog += skb->len;
- return 0;
+ u16 dp = tc_index_to_dp(skb);
+
+ if (dp >= t->DPs || (q = t->tab[dp]) == NULL) {
+ if (net_ratelimit())
+ printk(KERN_WARNING "GRED: Unable to relocate VQ 0x%x "
+ "for requeue, screwing up backlog.\n",
+ tc_index_to_dp(skb));
+ } else {
+ if (red_is_idling(&q->parms))
+ red_end_of_idle_period(&q->parms);
+ q->backlog += skb->len;
+ }
+
+ return qdisc_requeue(skb, sch);
}
-static struct sk_buff *
-gred_dequeue(struct Qdisc* sch)
+static struct sk_buff *gred_dequeue(struct Qdisc* sch)
{
struct sk_buff *skb;
- struct gred_sched_data *q;
- struct gred_sched *t= qdisc_priv(sch);
+ struct gred_sched *t = qdisc_priv(sch);
+
+ skb = qdisc_dequeue_head(sch);
- skb = __skb_dequeue(&sch->q);
if (skb) {
- sch->qstats.backlog -= skb->len;
- q= t->tab[(skb->tc_index&0xf)];
- if (q) {
- q->backlog -= skb->len;
- if (!q->backlog && !t->eqp)
- PSCHED_GET_TIME(q->qidlestart);
+ struct gred_sched_data *q;
+ u16 dp = tc_index_to_dp(skb);
+
+ if (dp >= t->DPs || (q = t->tab[dp]) == NULL) {
+ if (net_ratelimit())
+ printk(KERN_WARNING "GRED: Unable to relocate "
+ "VQ 0x%x after dequeue, screwing up "
+ "backlog.\n", tc_index_to_dp(skb));
} else {
- D2PRINTK("gred_dequeue: skb has bad tcindex %x\n",skb->tc_index&0xf);
+ q->backlog -= skb->len;
+
+ if (!q->backlog && !gred_wred_mode(t))
+ red_start_of_idle_period(&q->parms);
}
+
return skb;
}
- if (t->eqp) {
- q= t->tab[t->def];
- if (!q)
- D2PRINTK("no default VQ set: Results will be "
- "screwed up\n");
- else
- PSCHED_GET_TIME(q->qidlestart);
- }
+ if (gred_wred_mode(t) && !red_is_idling(&t->wred_set))
+ red_start_of_idle_period(&t->wred_set);
return NULL;
}
@@ -263,36 +297,34 @@ gred_dequeue(struct Qdisc* sch)
static unsigned int gred_drop(struct Qdisc* sch)
{
struct sk_buff *skb;
+ struct gred_sched *t = qdisc_priv(sch);
- struct gred_sched_data *q;
- struct gred_sched *t= qdisc_priv(sch);
-
- skb = __skb_dequeue_tail(&sch->q);
+ skb = qdisc_dequeue_tail(sch);
if (skb) {
unsigned int len = skb->len;
- sch->qstats.backlog -= len;
- sch->qstats.drops++;
- q= t->tab[(skb->tc_index&0xf)];
- if (q) {
- q->backlog -= len;
- q->other++;
- if (!q->backlog && !t->eqp)
- PSCHED_GET_TIME(q->qidlestart);
+ struct gred_sched_data *q;
+ u16 dp = tc_index_to_dp(skb);
+
+ if (dp >= t->DPs || (q = t->tab[dp]) == NULL) {
+ if (net_ratelimit())
+ printk(KERN_WARNING "GRED: Unable to relocate "
+ "VQ 0x%x while dropping, screwing up "
+ "backlog.\n", tc_index_to_dp(skb));
} else {
- D2PRINTK("gred_dequeue: skb has bad tcindex %x\n",skb->tc_index&0xf);
+ q->backlog -= len;
+ q->stats.other++;
+
+ if (!q->backlog && !gred_wred_mode(t))
+ red_start_of_idle_period(&q->parms);
}
- kfree_skb(skb);
+ qdisc_drop(skb, sch);
return len;
}
- q=t->tab[t->def];
- if (!q) {
- D2PRINTK("no default VQ set: Results might be screwed up\n");
- return 0;
- }
+ if (gred_wred_mode(t) && !red_is_idling(&t->wred_set))
+ red_start_of_idle_period(&t->wred_set);
- PSCHED_GET_TIME(q->qidlestart);
return 0;
}
@@ -300,293 +332,241 @@ static unsigned int gred_drop(struct Qdisc* sch)
static void gred_reset(struct Qdisc* sch)
{
int i;
- struct gred_sched_data *q;
- struct gred_sched *t= qdisc_priv(sch);
+ struct gred_sched *t = qdisc_priv(sch);
+
+ qdisc_reset_queue(sch);
- __skb_queue_purge(&sch->q);
+ for (i = 0; i < t->DPs; i++) {
+ struct gred_sched_data *q = t->tab[i];
- sch->qstats.backlog = 0;
+ if (!q)
+ continue;
- for (i=0;i<t->DPs;i++) {
- q= t->tab[i];
- if (!q)
- continue;
- PSCHED_SET_PASTPERFECT(q->qidlestart);
- q->qave = 0;
- q->qcount = -1;
+ red_restart(&q->parms);
q->backlog = 0;
- q->other=0;
- q->forced=0;
- q->pdrop=0;
- q->early=0;
}
}
-static int gred_change(struct Qdisc *sch, struct rtattr *opt)
+static inline void gred_destroy_vq(struct gred_sched_data *q)
+{
+ kfree(q);
+}
+
+static inline int gred_change_table_def(struct Qdisc *sch, struct rtattr *dps)
{
struct gred_sched *table = qdisc_priv(sch);
- struct gred_sched_data *q;
- struct tc_gred_qopt *ctl;
struct tc_gred_sopt *sopt;
- struct rtattr *tb[TCA_GRED_STAB];
- struct rtattr *tb2[TCA_GRED_DPS];
int i;
- if (opt == NULL || rtattr_parse_nested(tb, TCA_GRED_STAB, opt))
+ if (dps == NULL || RTA_PAYLOAD(dps) < sizeof(*sopt))
return -EINVAL;
- if (tb[TCA_GRED_PARMS-1] == 0 && tb[TCA_GRED_STAB-1] == 0) {
- rtattr_parse_nested(tb2, TCA_GRED_DPS, opt);
+ sopt = RTA_DATA(dps);
+
+ if (sopt->DPs > MAX_DPs || sopt->DPs == 0 || sopt->def_DP >= sopt->DPs)
+ return -EINVAL;
- if (tb2[TCA_GRED_DPS-1] == 0)
- return -EINVAL;
+ sch_tree_lock(sch);
+ table->DPs = sopt->DPs;
+ table->def = sopt->def_DP;
+ table->red_flags = sopt->flags;
+
+ /*
+ * Every entry point to GRED is synchronized with the above code
+ * and the DP is checked against DPs, i.e. shadowed VQs can no
+ * longer be found so we can unlock right here.
+ */
+ sch_tree_unlock(sch);
+
+ if (sopt->grio) {
+ gred_enable_rio_mode(table);
+ gred_disable_wred_mode(table);
+ if (gred_wred_mode_check(sch))
+ gred_enable_wred_mode(table);
+ } else {
+ gred_disable_rio_mode(table);
+ gred_disable_wred_mode(table);
+ }
- sopt = RTA_DATA(tb2[TCA_GRED_DPS-1]);
- table->DPs=sopt->DPs;
- table->def=sopt->def_DP;
- table->grio=sopt->grio;
- table->initd=0;
- /* probably need to clear all the table DP entries as well */
- return 0;
- }
+ for (i = table->DPs; i < MAX_DPs; i++) {
+ if (table->tab[i]) {
+ printk(KERN_WARNING "GRED: Warning: Destroying "
+ "shadowed VQ 0x%x\n", i);
+ gred_destroy_vq(table->tab[i]);
+ table->tab[i] = NULL;
+ }
+ }
+ return 0;
+}
- if (!table->DPs || tb[TCA_GRED_PARMS-1] == 0 || tb[TCA_GRED_STAB-1] == 0 ||
- RTA_PAYLOAD(tb[TCA_GRED_PARMS-1]) < sizeof(*ctl) ||
- RTA_PAYLOAD(tb[TCA_GRED_STAB-1]) < 256)
- return -EINVAL;
+static inline int gred_change_vq(struct Qdisc *sch, int dp,
+ struct tc_gred_qopt *ctl, int prio, u8 *stab)
+{
+ struct gred_sched *table = qdisc_priv(sch);
+ struct gred_sched_data *q;
- ctl = RTA_DATA(tb[TCA_GRED_PARMS-1]);
- if (ctl->DP > MAX_DPs-1 ) {
- /* misbehaving is punished! Put in the default drop probability */
- DPRINTK("\nGRED: DP %u not in the proper range fixed. New DP "
- "set to default at %d\n",ctl->DP,table->def);
- ctl->DP=table->def;
- }
-
- if (table->tab[ctl->DP] == NULL) {
- table->tab[ctl->DP]=kmalloc(sizeof(struct gred_sched_data),
- GFP_KERNEL);
- if (NULL == table->tab[ctl->DP])
+ if (table->tab[dp] == NULL) {
+ table->tab[dp] = kmalloc(sizeof(*q), GFP_KERNEL);
+ if (table->tab[dp] == NULL)
return -ENOMEM;
- memset(table->tab[ctl->DP], 0, (sizeof(struct gred_sched_data)));
- }
- q= table->tab[ctl->DP];
-
- if (table->grio) {
- if (ctl->prio <=0) {
- if (table->def && table->tab[table->def]) {
- DPRINTK("\nGRED: DP %u does not have a prio"
- "setting default to %d\n",ctl->DP,
- table->tab[table->def]->prio);
- q->prio=table->tab[table->def]->prio;
- } else {
- DPRINTK("\nGRED: DP %u does not have a prio"
- " setting default to 8\n",ctl->DP);
- q->prio=8;
- }
- } else {
- q->prio=ctl->prio;
- }
- } else {
- q->prio=8;
+ memset(table->tab[dp], 0, sizeof(*q));
}
-
- q->DP=ctl->DP;
- q->Wlog = ctl->Wlog;
- q->Plog = ctl->Plog;
+ q = table->tab[dp];
+ q->DP = dp;
+ q->prio = prio;
q->limit = ctl->limit;
- q->Scell_log = ctl->Scell_log;
- q->Rmask = ctl->Plog < 32 ? ((1<<ctl->Plog) - 1) : ~0UL;
- q->Scell_max = (255<<q->Scell_log);
- q->qth_min = ctl->qth_min<<ctl->Wlog;
- q->qth_max = ctl->qth_max<<ctl->Wlog;
- q->qave=0;
- q->backlog=0;
- q->qcount = -1;
- q->other=0;
- q->forced=0;
- q->pdrop=0;
- q->early=0;
-
- PSCHED_SET_PASTPERFECT(q->qidlestart);
- memcpy(q->Stab, RTA_DATA(tb[TCA_GRED_STAB-1]), 256);
-
- if ( table->initd && table->grio) {
- /* this looks ugly but it's not in the fast path */
- for (i=0;i<table->DPs;i++) {
- if ((!table->tab[i]) || (i==q->DP) )
- continue;
- if (table->tab[i]->prio == q->prio ){
- /* WRED mode detected */
- table->eqp=1;
- break;
- }
- }
- }
- if (!table->initd) {
- table->initd=1;
- /*
- the first entry also goes into the default until
- over-written
- */
-
- if (table->tab[table->def] == NULL) {
- table->tab[table->def]=
- kmalloc(sizeof(struct gred_sched_data), GFP_KERNEL);
- if (NULL == table->tab[table->def])
- return -ENOMEM;
-
- memset(table->tab[table->def], 0,
- (sizeof(struct gred_sched_data)));
- }
- q= table->tab[table->def];
- q->DP=table->def;
- q->Wlog = ctl->Wlog;
- q->Plog = ctl->Plog;
- q->limit = ctl->limit;
- q->Scell_log = ctl->Scell_log;
- q->Rmask = ctl->Plog < 32 ? ((1<<ctl->Plog) - 1) : ~0UL;
- q->Scell_max = (255<<q->Scell_log);
- q->qth_min = ctl->qth_min<<ctl->Wlog;
- q->qth_max = ctl->qth_max<<ctl->Wlog;
-
- if (table->grio)
- q->prio=table->tab[ctl->DP]->prio;
- else
- q->prio=8;
-
- q->qcount = -1;
- PSCHED_SET_PASTPERFECT(q->qidlestart);
- memcpy(q->Stab, RTA_DATA(tb[TCA_GRED_STAB-1]), 256);
- }
- return 0;
+ if (q->backlog == 0)
+ red_end_of_idle_period(&q->parms);
+ red_set_parms(&q->parms,
+ ctl->qth_min, ctl->qth_max, ctl->Wlog, ctl->Plog,
+ ctl->Scell_log, stab);
+
+ return 0;
}
-static int gred_init(struct Qdisc *sch, struct rtattr *opt)
+static int gred_change(struct Qdisc *sch, struct rtattr *opt)
{
struct gred_sched *table = qdisc_priv(sch);
- struct tc_gred_sopt *sopt;
- struct rtattr *tb[TCA_GRED_STAB];
- struct rtattr *tb2[TCA_GRED_DPS];
+ struct tc_gred_qopt *ctl;
+ struct rtattr *tb[TCA_GRED_MAX];
+ int err = -EINVAL, prio = GRED_DEF_PRIO;
+ u8 *stab;
- if (opt == NULL || rtattr_parse_nested(tb, TCA_GRED_STAB, opt))
+ if (opt == NULL || rtattr_parse_nested(tb, TCA_GRED_MAX, opt))
return -EINVAL;
- if (tb[TCA_GRED_PARMS-1] == 0 && tb[TCA_GRED_STAB-1] == 0) {
- rtattr_parse_nested(tb2, TCA_GRED_DPS, opt);
+ if (tb[TCA_GRED_PARMS-1] == NULL && tb[TCA_GRED_STAB-1] == NULL)
+ return gred_change_table_def(sch, opt);
+
+ if (tb[TCA_GRED_PARMS-1] == NULL ||
+ RTA_PAYLOAD(tb[TCA_GRED_PARMS-1]) < sizeof(*ctl) ||
+ tb[TCA_GRED_STAB-1] == NULL ||
+ RTA_PAYLOAD(tb[TCA_GRED_STAB-1]) < 256)
+ return -EINVAL;
+
+ ctl = RTA_DATA(tb[TCA_GRED_PARMS-1]);
+ stab = RTA_DATA(tb[TCA_GRED_STAB-1]);
+
+ if (ctl->DP >= table->DPs)
+ goto errout;
- if (tb2[TCA_GRED_DPS-1] == 0)
- return -EINVAL;
+ if (gred_rio_mode(table)) {
+ if (ctl->prio == 0) {
+ int def_prio = GRED_DEF_PRIO;
- sopt = RTA_DATA(tb2[TCA_GRED_DPS-1]);
- table->DPs=sopt->DPs;
- table->def=sopt->def_DP;
- table->grio=sopt->grio;
- table->initd=0;
- return 0;
+ if (table->tab[table->def])
+ def_prio = table->tab[table->def]->prio;
+
+ printk(KERN_DEBUG "GRED: DP %u does not have a prio "
+ "setting default to %d\n", ctl->DP, def_prio);
+
+ prio = def_prio;
+ } else
+ prio = ctl->prio;
+ }
+
+ sch_tree_lock(sch);
+
+ err = gred_change_vq(sch, ctl->DP, ctl, prio, stab);
+ if (err < 0)
+ goto errout_locked;
+
+ if (gred_rio_mode(table)) {
+ gred_disable_wred_mode(table);
+ if (gred_wred_mode_check(sch))
+ gred_enable_wred_mode(table);
}
- DPRINTK("\n GRED_INIT error!\n");
- return -EINVAL;
+ err = 0;
+
+errout_locked:
+ sch_tree_unlock(sch);
+errout:
+ return err;
}
-static int gred_dump(struct Qdisc *sch, struct sk_buff *skb)
+static int gred_init(struct Qdisc *sch, struct rtattr *opt)
{
- unsigned long qave;
- struct rtattr *rta;
- struct tc_gred_qopt *opt = NULL ;
- struct tc_gred_qopt *dst;
- struct gred_sched *table = qdisc_priv(sch);
- struct gred_sched_data *q;
- int i;
- unsigned char *b = skb->tail;
+ struct rtattr *tb[TCA_GRED_MAX];
- rta = (struct rtattr*)b;
- RTA_PUT(skb, TCA_OPTIONS, 0, NULL);
+ if (opt == NULL || rtattr_parse_nested(tb, TCA_GRED_MAX, opt))
+ return -EINVAL;
- opt=kmalloc(sizeof(struct tc_gred_qopt)*MAX_DPs, GFP_KERNEL);
+ if (tb[TCA_GRED_PARMS-1] || tb[TCA_GRED_STAB-1])
+ return -EINVAL;
- if (opt == NULL) {
- DPRINTK("gred_dump:failed to malloc for %Zd\n",
- sizeof(struct tc_gred_qopt)*MAX_DPs);
- goto rtattr_failure;
- }
+ return gred_change_table_def(sch, tb[TCA_GRED_DPS-1]);
+}
- memset(opt, 0, (sizeof(struct tc_gred_qopt))*table->DPs);
+static int gred_dump(struct Qdisc *sch, struct sk_buff *skb)
+{
+ struct gred_sched *table = qdisc_priv(sch);
+ struct rtattr *parms, *opts = NULL;
+ int i;
+ struct tc_gred_sopt sopt = {
+ .DPs = table->DPs,
+ .def_DP = table->def,
+ .grio = gred_rio_mode(table),
+ .flags = table->red_flags,
+ };
- if (!table->initd) {
- DPRINTK("NO GRED Queues setup!\n");
- }
+ opts = RTA_NEST(skb, TCA_OPTIONS);
+ RTA_PUT(skb, TCA_GRED_DPS, sizeof(sopt), &sopt);
+ parms = RTA_NEST(skb, TCA_GRED_PARMS);
+
+ for (i = 0; i < MAX_DPs; i++) {
+ struct gred_sched_data *q = table->tab[i];
+ struct tc_gred_qopt opt;
- for (i=0;i<MAX_DPs;i++) {
- dst= &opt[i];
- q= table->tab[i];
+ memset(&opt, 0, sizeof(opt));
if (!q) {
/* hack -- fix at some point with proper message
This is how we indicate to tc that there is no VQ
at this DP */
- dst->DP=MAX_DPs+i;
- continue;
+ opt.DP = MAX_DPs + i;
+ goto append_opt;
}
- dst->limit=q->limit;
- dst->qth_min=q->qth_min>>q->Wlog;
- dst->qth_max=q->qth_max>>q->Wlog;
- dst->DP=q->DP;
- dst->backlog=q->backlog;
- if (q->qave) {
- if (table->eqp && table->grio) {
- q->qidlestart=table->tab[table->def]->qidlestart;
- q->qave=table->tab[table->def]->qave;
- }
- if (!PSCHED_IS_PASTPERFECT(q->qidlestart)) {
- long idle;
- psched_time_t now;
- PSCHED_GET_TIME(now);
- idle = PSCHED_TDIFF_SAFE(now, q->qidlestart, q->Scell_max);
- qave = q->qave >> q->Stab[(idle>>q->Scell_log)&0xFF];
- dst->qave = qave >> q->Wlog;
-
- } else {
- dst->qave = q->qave >> q->Wlog;
- }
- } else {
- dst->qave = 0;
+ opt.limit = q->limit;
+ opt.DP = q->DP;
+ opt.backlog = q->backlog;
+ opt.prio = q->prio;
+ opt.qth_min = q->parms.qth_min >> q->parms.Wlog;
+ opt.qth_max = q->parms.qth_max >> q->parms.Wlog;
+ opt.Wlog = q->parms.Wlog;
+ opt.Plog = q->parms.Plog;
+ opt.Scell_log = q->parms.Scell_log;
+ opt.other = q->stats.other;
+ opt.early = q->stats.prob_drop;
+ opt.forced = q->stats.forced_drop;
+ opt.pdrop = q->stats.pdrop;
+ opt.packets = q->packetsin;
+ opt.bytesin = q->bytesin;
+
+ if (gred_wred_mode(table)) {
+ q->parms.qidlestart =
+ table->tab[table->def]->parms.qidlestart;
+ q->parms.qavg = table->tab[table->def]->parms.qavg;
}
-
-
- dst->Wlog = q->Wlog;
- dst->Plog = q->Plog;
- dst->Scell_log = q->Scell_log;
- dst->other = q->other;
- dst->forced = q->forced;
- dst->early = q->early;
- dst->pdrop = q->pdrop;
- dst->prio = q->prio;
- dst->packets=q->packetsin;
- dst->bytesin=q->bytesin;
+
+ opt.qave = red_calc_qavg(&q->parms, q->parms.qavg);
+
+append_opt:
+ RTA_APPEND(skb, sizeof(opt), &opt);
}
- RTA_PUT(skb, TCA_GRED_PARMS, sizeof(struct tc_gred_qopt)*MAX_DPs, opt);
- rta->rta_len = skb->tail - b;
+ RTA_NEST_END(skb, parms);
- kfree(opt);
- return skb->len;
+ return RTA_NEST_END(skb, opts);
rtattr_failure:
- if (opt)
- kfree(opt);
- DPRINTK("gred_dump: FAILURE!!!!\n");
-
-/* also free the opt struct here */
- skb_trim(skb, b - skb->data);
- return -1;
+ return RTA_NEST_CANCEL(skb, opts);
}
static void gred_destroy(struct Qdisc *sch)
@@ -594,15 +574,13 @@ static void gred_destroy(struct Qdisc *sch)
struct gred_sched *table = qdisc_priv(sch);
int i;
- for (i = 0;i < table->DPs; i++) {
+ for (i = 0; i < table->DPs; i++) {
if (table->tab[i])
- kfree(table->tab[i]);
+ gred_destroy_vq(table->tab[i]);
}
}
static struct Qdisc_ops gred_qdisc_ops = {
- .next = NULL,
- .cl_ops = NULL,
.id = "gred",
.priv_size = sizeof(struct gred_sched),
.enqueue = gred_enqueue,
@@ -621,10 +599,13 @@ static int __init gred_module_init(void)
{
return register_qdisc(&gred_qdisc_ops);
}
-static void __exit gred_module_exit(void)
+
+static void __exit gred_module_exit(void)
{
unregister_qdisc(&gred_qdisc_ops);
}
+
module_init(gred_module_init)
module_exit(gred_module_exit)
+
MODULE_LICENSE("GPL");
diff --git a/net/sched/sch_netem.c b/net/sched/sch_netem.c
index bb9bf8d5003c..cdc8d283791c 100644
--- a/net/sched/sch_netem.c
+++ b/net/sched/sch_netem.c
@@ -25,6 +25,8 @@
#include <net/pkt_sched.h>
+#define VERSION "1.1"
+
/* Network Emulation Queuing algorithm.
====================================
@@ -185,10 +187,13 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch)
|| q->counter < q->gap /* inside last reordering gap */
|| q->reorder < get_crandom(&q->reorder_cor)) {
psched_time_t now;
+ psched_tdiff_t delay;
+
+ delay = tabledist(q->latency, q->jitter,
+ &q->delay_cor, q->delay_dist);
+
PSCHED_GET_TIME(now);
- PSCHED_TADD2(now, tabledist(q->latency, q->jitter,
- &q->delay_cor, q->delay_dist),
- cb->time_to_send);
+ PSCHED_TADD2(now, delay, cb->time_to_send);
++q->counter;
ret = q->qdisc->enqueue(skb, q->qdisc);
} else {
@@ -248,24 +253,31 @@ static struct sk_buff *netem_dequeue(struct Qdisc *sch)
const struct netem_skb_cb *cb
= (const struct netem_skb_cb *)skb->cb;
psched_time_t now;
- long delay;
/* if more time remaining? */
PSCHED_GET_TIME(now);
- delay = PSCHED_US2JIFFIE(PSCHED_TDIFF(cb->time_to_send, now));
- pr_debug("netem_run: skb=%p delay=%ld\n", skb, delay);
- if (delay <= 0) {
+
+ if (PSCHED_TLESS(cb->time_to_send, now)) {
pr_debug("netem_dequeue: return skb=%p\n", skb);
sch->q.qlen--;
sch->flags &= ~TCQ_F_THROTTLED;
return skb;
- }
+ } else {
+ psched_tdiff_t delay = PSCHED_TDIFF(cb->time_to_send, now);
+
+ if (q->qdisc->ops->requeue(skb, q->qdisc) != NET_XMIT_SUCCESS) {
+ sch->qstats.drops++;
- mod_timer(&q->timer, jiffies + delay);
- sch->flags |= TCQ_F_THROTTLED;
+ /* After this qlen is confused */
+ printk(KERN_ERR "netem: queue discpline %s could not requeue\n",
+ q->qdisc->ops->id);
- if (q->qdisc->ops->requeue(skb, q->qdisc) != 0)
- sch->qstats.drops++;
+ sch->q.qlen--;
+ }
+
+ mod_timer(&q->timer, jiffies + PSCHED_US2JIFFIE(delay));
+ sch->flags |= TCQ_F_THROTTLED;
+ }
}
return NULL;
@@ -290,11 +302,16 @@ static void netem_reset(struct Qdisc *sch)
del_timer_sync(&q->timer);
}
+/* Pass size change message down to embedded FIFO */
static int set_fifo_limit(struct Qdisc *q, int limit)
{
struct rtattr *rta;
int ret = -ENOMEM;
+ /* Hack to avoid sending change message to non-FIFO */
+ if (strncmp(q->ops->id + 1, "fifo", 4) != 0)
+ return 0;
+
rta = kmalloc(RTA_LENGTH(sizeof(struct tc_fifo_qopt)), GFP_KERNEL);
if (rta) {
rta->rta_type = RTM_NEWQDISC;
@@ -426,6 +443,84 @@ static int netem_change(struct Qdisc *sch, struct rtattr *opt)
return 0;
}
+/*
+ * Special case version of FIFO queue for use by netem.
+ * It queues in order based on timestamps in skb's
+ */
+struct fifo_sched_data {
+ u32 limit;
+};
+
+static int tfifo_enqueue(struct sk_buff *nskb, struct Qdisc *sch)
+{
+ struct fifo_sched_data *q = qdisc_priv(sch);
+ struct sk_buff_head *list = &sch->q;
+ const struct netem_skb_cb *ncb
+ = (const struct netem_skb_cb *)nskb->cb;
+ struct sk_buff *skb;
+
+ if (likely(skb_queue_len(list) < q->limit)) {
+ skb_queue_reverse_walk(list, skb) {
+ const struct netem_skb_cb *cb
+ = (const struct netem_skb_cb *)skb->cb;
+
+ if (PSCHED_TLESS(cb->time_to_send, ncb->time_to_send))
+ break;
+ }
+
+ __skb_queue_after(list, skb, nskb);
+
+ sch->qstats.backlog += nskb->len;
+ sch->bstats.bytes += nskb->len;
+ sch->bstats.packets++;
+
+ return NET_XMIT_SUCCESS;
+ }
+
+ return qdisc_drop(nskb, sch);
+}
+
+static int tfifo_init(struct Qdisc *sch, struct rtattr *opt)
+{
+ struct fifo_sched_data *q = qdisc_priv(sch);
+
+ if (opt) {
+ struct tc_fifo_qopt *ctl = RTA_DATA(opt);
+ if (RTA_PAYLOAD(opt) < sizeof(*ctl))
+ return -EINVAL;
+
+ q->limit = ctl->limit;
+ } else
+ q->limit = max_t(u32, sch->dev->tx_queue_len, 1);
+
+ return 0;
+}
+
+static int tfifo_dump(struct Qdisc *sch, struct sk_buff *skb)
+{
+ struct fifo_sched_data *q = qdisc_priv(sch);
+ struct tc_fifo_qopt opt = { .limit = q->limit };
+
+ RTA_PUT(skb, TCA_OPTIONS, sizeof(opt), &opt);
+ return skb->len;
+
+rtattr_failure:
+ return -1;
+}
+
+static struct Qdisc_ops tfifo_qdisc_ops = {
+ .id = "tfifo",
+ .priv_size = sizeof(struct fifo_sched_data),
+ .enqueue = tfifo_enqueue,
+ .dequeue = qdisc_dequeue_head,
+ .requeue = qdisc_requeue,
+ .drop = qdisc_queue_drop,
+ .init = tfifo_init,
+ .reset = qdisc_reset_queue,
+ .change = tfifo_init,
+ .dump = tfifo_dump,
+};
+
static int netem_init(struct Qdisc *sch, struct rtattr *opt)
{
struct netem_sched_data *q = qdisc_priv(sch);
@@ -438,7 +533,7 @@ static int netem_init(struct Qdisc *sch, struct rtattr *opt)
q->timer.function = netem_watchdog;
q->timer.data = (unsigned long) sch;
- q->qdisc = qdisc_create_dflt(sch->dev, &pfifo_qdisc_ops);
+ q->qdisc = qdisc_create_dflt(sch->dev, &tfifo_qdisc_ops);
if (!q->qdisc) {
pr_debug("netem: qdisc create failed\n");
return -ENOMEM;
@@ -601,6 +696,7 @@ static struct Qdisc_ops netem_qdisc_ops = {
static int __init netem_module_init(void)
{
+ pr_info("netem: version " VERSION "\n");
return register_qdisc(&netem_qdisc_ops);
}
static void __exit netem_module_exit(void)
diff --git a/net/sched/sch_red.c b/net/sched/sch_red.c
index 7845d045eec4..dccfa44c2d71 100644
--- a/net/sched/sch_red.c
+++ b/net/sched/sch_red.c
@@ -9,76 +9,23 @@
* Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
*
* Changes:
- * J Hadi Salim <hadi@nortel.com> 980914: computation fixes
+ * J Hadi Salim 980914: computation fixes
* Alexey Makarenko <makar@phoenix.kharkov.ua> 990814: qave on idle link was calculated incorrectly.
- * J Hadi Salim <hadi@nortelnetworks.com> 980816: ECN support
+ * J Hadi Salim 980816: ECN support
*/
#include <linux/config.h>
#include <linux/module.h>
-#include <asm/uaccess.h>
-#include <asm/system.h>
-#include <linux/bitops.h>
#include <linux/types.h>
#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/socket.h>
-#include <linux/sockios.h>
-#include <linux/in.h>
-#include <linux/errno.h>
-#include <linux/interrupt.h>
-#include <linux/if_ether.h>
-#include <linux/inet.h>
#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/notifier.h>
-#include <net/ip.h>
-#include <net/route.h>
#include <linux/skbuff.h>
-#include <net/sock.h>
#include <net/pkt_sched.h>
#include <net/inet_ecn.h>
-#include <net/dsfield.h>
+#include <net/red.h>
-/* Random Early Detection (RED) algorithm.
- =======================================
-
- Source: Sally Floyd and Van Jacobson, "Random Early Detection Gateways
- for Congestion Avoidance", 1993, IEEE/ACM Transactions on Networking.
-
- This file codes a "divisionless" version of RED algorithm
- as written down in Fig.17 of the paper.
-
-Short description.
-------------------
-
- When a new packet arrives we calculate the average queue length:
-
- avg = (1-W)*avg + W*current_queue_len,
-
- W is the filter time constant (chosen as 2^(-Wlog)), it controls
- the inertia of the algorithm. To allow larger bursts, W should be
- decreased.
-
- if (avg > th_max) -> packet marked (dropped).
- if (avg < th_min) -> packet passes.
- if (th_min < avg < th_max) we calculate probability:
-
- Pb = max_P * (avg - th_min)/(th_max-th_min)
-
- and mark (drop) packet with this probability.
- Pb changes from 0 (at avg==th_min) to max_P (avg==th_max).
- max_P should be small (not 1), usually 0.01..0.02 is good value.
-
- max_P is chosen as a number, so that max_P/(th_max-th_min)
- is a negative power of two in order arithmetics to contain
- only shifts.
-
-
- Parameters, settable by user:
+/* Parameters, settable by user:
-----------------------------
limit - bytes (must be > qth_max + burst)
@@ -89,243 +36,93 @@ Short description.
arbitrarily high (well, less than ram size)
Really, this limit will never be reached
if RED works correctly.
-
- qth_min - bytes (should be < qth_max/2)
- qth_max - bytes (should be at least 2*qth_min and less limit)
- Wlog - bits (<32) log(1/W).
- Plog - bits (<32)
-
- Plog is related to max_P by formula:
-
- max_P = (qth_max-qth_min)/2^Plog;
-
- F.e. if qth_max=128K and qth_min=32K, then Plog=22
- corresponds to max_P=0.02
-
- Scell_log
- Stab
-
- Lookup table for log((1-W)^(t/t_ave).
-
-
-NOTES:
-
-Upper bound on W.
------------------
-
- If you want to allow bursts of L packets of size S,
- you should choose W:
-
- L + 1 - th_min/S < (1-(1-W)^L)/W
-
- th_min/S = 32 th_min/S = 4
-
- log(W) L
- -1 33
- -2 35
- -3 39
- -4 46
- -5 57
- -6 75
- -7 101
- -8 135
- -9 190
- etc.
*/
struct red_sched_data
{
-/* Parameters */
- u32 limit; /* HARD maximal queue length */
- u32 qth_min; /* Min average length threshold: A scaled */
- u32 qth_max; /* Max average length threshold: A scaled */
- u32 Rmask;
- u32 Scell_max;
- unsigned char flags;
- char Wlog; /* log(W) */
- char Plog; /* random number bits */
- char Scell_log;
- u8 Stab[256];
-
-/* Variables */
- unsigned long qave; /* Average queue length: A scaled */
- int qcount; /* Packets since last random number generation */
- u32 qR; /* Cached random number */
-
- psched_time_t qidlestart; /* Start of idle period */
- struct tc_red_xstats st;
+ u32 limit; /* HARD maximal queue length */
+ unsigned char flags;
+ struct red_parms parms;
+ struct red_stats stats;
};
-static int red_ecn_mark(struct sk_buff *skb)
+static inline int red_use_ecn(struct red_sched_data *q)
{
- if (skb->nh.raw + 20 > skb->tail)
- return 0;
-
- switch (skb->protocol) {
- case __constant_htons(ETH_P_IP):
- if (INET_ECN_is_not_ect(skb->nh.iph->tos))
- return 0;
- IP_ECN_set_ce(skb->nh.iph);
- return 1;
- case __constant_htons(ETH_P_IPV6):
- if (INET_ECN_is_not_ect(ipv6_get_dsfield(skb->nh.ipv6h)))
- return 0;
- IP6_ECN_set_ce(skb->nh.ipv6h);
- return 1;
- default:
- return 0;
- }
+ return q->flags & TC_RED_ECN;
}
-static int
-red_enqueue(struct sk_buff *skb, struct Qdisc* sch)
+static inline int red_use_harddrop(struct red_sched_data *q)
+{
+ return q->flags & TC_RED_HARDDROP;
+}
+
+static int red_enqueue(struct sk_buff *skb, struct Qdisc* sch)
{
struct red_sched_data *q = qdisc_priv(sch);
- psched_time_t now;
+ q->parms.qavg = red_calc_qavg(&q->parms, sch->qstats.backlog);
- if (!PSCHED_IS_PASTPERFECT(q->qidlestart)) {
- long us_idle;
- int shift;
+ if (red_is_idling(&q->parms))
+ red_end_of_idle_period(&q->parms);
- PSCHED_GET_TIME(now);
- us_idle = PSCHED_TDIFF_SAFE(now, q->qidlestart, q->Scell_max);
- PSCHED_SET_PASTPERFECT(q->qidlestart);
+ switch (red_action(&q->parms, q->parms.qavg)) {
+ case RED_DONT_MARK:
+ break;
-/*
- The problem: ideally, average length queue recalcultion should
- be done over constant clock intervals. This is too expensive, so that
- the calculation is driven by outgoing packets.
- When the queue is idle we have to model this clock by hand.
-
- SF+VJ proposed to "generate" m = idletime/(average_pkt_size/bandwidth)
- dummy packets as a burst after idle time, i.e.
-
- q->qave *= (1-W)^m
-
- This is an apparently overcomplicated solution (f.e. we have to precompute
- a table to make this calculation in reasonable time)
- I believe that a simpler model may be used here,
- but it is field for experiments.
-*/
- shift = q->Stab[us_idle>>q->Scell_log];
-
- if (shift) {
- q->qave >>= shift;
- } else {
- /* Approximate initial part of exponent
- with linear function:
- (1-W)^m ~= 1-mW + ...
-
- Seems, it is the best solution to
- problem of too coarce exponent tabulation.
- */
-
- us_idle = (q->qave * us_idle)>>q->Scell_log;
- if (us_idle < q->qave/2)
- q->qave -= us_idle;
- else
- q->qave >>= 1;
- }
- } else {
- q->qave += sch->qstats.backlog - (q->qave >> q->Wlog);
- /* NOTE:
- q->qave is fixed point number with point at Wlog.
- The formulae above is equvalent to floating point
- version:
-
- qave = qave*(1-W) + sch->qstats.backlog*W;
- --ANK (980924)
- */
- }
+ case RED_PROB_MARK:
+ sch->qstats.overlimits++;
+ if (!red_use_ecn(q) || !INET_ECN_set_ce(skb)) {
+ q->stats.prob_drop++;
+ goto congestion_drop;
+ }
- if (q->qave < q->qth_min) {
- q->qcount = -1;
-enqueue:
- if (sch->qstats.backlog + skb->len <= q->limit) {
- __skb_queue_tail(&sch->q, skb);
- sch->qstats.backlog += skb->len;
- sch->bstats.bytes += skb->len;
- sch->bstats.packets++;
- return NET_XMIT_SUCCESS;
- } else {
- q->st.pdrop++;
- }
- kfree_skb(skb);
- sch->qstats.drops++;
- return NET_XMIT_DROP;
- }
- if (q->qave >= q->qth_max) {
- q->qcount = -1;
- sch->qstats.overlimits++;
-mark:
- if (!(q->flags&TC_RED_ECN) || !red_ecn_mark(skb)) {
- q->st.early++;
- goto drop;
- }
- q->st.marked++;
- goto enqueue;
- }
+ q->stats.prob_mark++;
+ break;
+
+ case RED_HARD_MARK:
+ sch->qstats.overlimits++;
+ if (red_use_harddrop(q) || !red_use_ecn(q) ||
+ !INET_ECN_set_ce(skb)) {
+ q->stats.forced_drop++;
+ goto congestion_drop;
+ }
- if (++q->qcount) {
- /* The formula used below causes questions.
-
- OK. qR is random number in the interval 0..Rmask
- i.e. 0..(2^Plog). If we used floating point
- arithmetics, it would be: (2^Plog)*rnd_num,
- where rnd_num is less 1.
-
- Taking into account, that qave have fixed
- point at Wlog, and Plog is related to max_P by
- max_P = (qth_max-qth_min)/2^Plog; two lines
- below have the following floating point equivalent:
-
- max_P*(qave - qth_min)/(qth_max-qth_min) < rnd/qcount
-
- Any questions? --ANK (980924)
- */
- if (((q->qave - q->qth_min)>>q->Wlog)*q->qcount < q->qR)
- goto enqueue;
- q->qcount = 0;
- q->qR = net_random()&q->Rmask;
- sch->qstats.overlimits++;
- goto mark;
+ q->stats.forced_mark++;
+ break;
}
- q->qR = net_random()&q->Rmask;
- goto enqueue;
-drop:
- kfree_skb(skb);
- sch->qstats.drops++;
+ if (sch->qstats.backlog + skb->len <= q->limit)
+ return qdisc_enqueue_tail(skb, sch);
+
+ q->stats.pdrop++;
+ return qdisc_drop(skb, sch);
+
+congestion_drop:
+ qdisc_drop(skb, sch);
return NET_XMIT_CN;
}
-static int
-red_requeue(struct sk_buff *skb, struct Qdisc* sch)
+static int red_requeue(struct sk_buff *skb, struct Qdisc* sch)
{
struct red_sched_data *q = qdisc_priv(sch);
- PSCHED_SET_PASTPERFECT(q->qidlestart);
+ if (red_is_idling(&q->parms))
+ red_end_of_idle_period(&q->parms);
- __skb_queue_head(&sch->q, skb);
- sch->qstats.backlog += skb->len;
- sch->qstats.requeues++;
- return 0;
+ return qdisc_requeue(skb, sch);
}
-static struct sk_buff *
-red_dequeue(struct Qdisc* sch)
+static struct sk_buff * red_dequeue(struct Qdisc* sch)
{
struct sk_buff *skb;
struct red_sched_data *q = qdisc_priv(sch);
- skb = __skb_dequeue(&sch->q);
- if (skb) {
- sch->qstats.backlog -= skb->len;
- return skb;
- }
- PSCHED_GET_TIME(q->qidlestart);
- return NULL;
+ skb = qdisc_dequeue_head(sch);
+
+ if (skb == NULL && !red_is_idling(&q->parms))
+ red_start_of_idle_period(&q->parms);
+
+ return skb;
}
static unsigned int red_drop(struct Qdisc* sch)
@@ -333,16 +130,17 @@ static unsigned int red_drop(struct Qdisc* sch)
struct sk_buff *skb;
struct red_sched_data *q = qdisc_priv(sch);
- skb = __skb_dequeue_tail(&sch->q);
+ skb = qdisc_dequeue_tail(sch);
if (skb) {
unsigned int len = skb->len;
- sch->qstats.backlog -= len;
- sch->qstats.drops++;
- q->st.other++;
- kfree_skb(skb);
+ q->stats.other++;
+ qdisc_drop(skb, sch);
return len;
}
- PSCHED_GET_TIME(q->qidlestart);
+
+ if (!red_is_idling(&q->parms))
+ red_start_of_idle_period(&q->parms);
+
return 0;
}
@@ -350,43 +148,38 @@ static void red_reset(struct Qdisc* sch)
{
struct red_sched_data *q = qdisc_priv(sch);
- __skb_queue_purge(&sch->q);
- sch->qstats.backlog = 0;
- PSCHED_SET_PASTPERFECT(q->qidlestart);
- q->qave = 0;
- q->qcount = -1;
+ qdisc_reset_queue(sch);
+ red_restart(&q->parms);
}
static int red_change(struct Qdisc *sch, struct rtattr *opt)
{
struct red_sched_data *q = qdisc_priv(sch);
- struct rtattr *tb[TCA_RED_STAB];
+ struct rtattr *tb[TCA_RED_MAX];
struct tc_red_qopt *ctl;
- if (opt == NULL ||
- rtattr_parse_nested(tb, TCA_RED_STAB, opt) ||
- tb[TCA_RED_PARMS-1] == 0 || tb[TCA_RED_STAB-1] == 0 ||
+ if (opt == NULL || rtattr_parse_nested(tb, TCA_RED_MAX, opt))
+ return -EINVAL;
+
+ if (tb[TCA_RED_PARMS-1] == NULL ||
RTA_PAYLOAD(tb[TCA_RED_PARMS-1]) < sizeof(*ctl) ||
- RTA_PAYLOAD(tb[TCA_RED_STAB-1]) < 256)
+ tb[TCA_RED_STAB-1] == NULL ||
+ RTA_PAYLOAD(tb[TCA_RED_STAB-1]) < RED_STAB_SIZE)
return -EINVAL;
ctl = RTA_DATA(tb[TCA_RED_PARMS-1]);
sch_tree_lock(sch);
q->flags = ctl->flags;
- q->Wlog = ctl->Wlog;
- q->Plog = ctl->Plog;
- q->Rmask = ctl->Plog < 32 ? ((1<<ctl->Plog) - 1) : ~0UL;
- q->Scell_log = ctl->Scell_log;
- q->Scell_max = (255<<q->Scell_log);
- q->qth_min = ctl->qth_min<<ctl->Wlog;
- q->qth_max = ctl->qth_max<<ctl->Wlog;
q->limit = ctl->limit;
- memcpy(q->Stab, RTA_DATA(tb[TCA_RED_STAB-1]), 256);
- q->qcount = -1;
+ red_set_parms(&q->parms, ctl->qth_min, ctl->qth_max, ctl->Wlog,
+ ctl->Plog, ctl->Scell_log,
+ RTA_DATA(tb[TCA_RED_STAB-1]));
+
if (skb_queue_empty(&sch->q))
- PSCHED_SET_PASTPERFECT(q->qidlestart);
+ red_end_of_idle_period(&q->parms);
+
sch_tree_unlock(sch);
return 0;
}
@@ -399,39 +192,39 @@ static int red_init(struct Qdisc* sch, struct rtattr *opt)
static int red_dump(struct Qdisc *sch, struct sk_buff *skb)
{
struct red_sched_data *q = qdisc_priv(sch);
- unsigned char *b = skb->tail;
- struct rtattr *rta;
- struct tc_red_qopt opt;
-
- rta = (struct rtattr*)b;
- RTA_PUT(skb, TCA_OPTIONS, 0, NULL);
- opt.limit = q->limit;
- opt.qth_min = q->qth_min>>q->Wlog;
- opt.qth_max = q->qth_max>>q->Wlog;
- opt.Wlog = q->Wlog;
- opt.Plog = q->Plog;
- opt.Scell_log = q->Scell_log;
- opt.flags = q->flags;
+ struct rtattr *opts = NULL;
+ struct tc_red_qopt opt = {
+ .limit = q->limit,
+ .flags = q->flags,
+ .qth_min = q->parms.qth_min >> q->parms.Wlog,
+ .qth_max = q->parms.qth_max >> q->parms.Wlog,
+ .Wlog = q->parms.Wlog,
+ .Plog = q->parms.Plog,
+ .Scell_log = q->parms.Scell_log,
+ };
+
+ opts = RTA_NEST(skb, TCA_OPTIONS);
RTA_PUT(skb, TCA_RED_PARMS, sizeof(opt), &opt);
- rta->rta_len = skb->tail - b;
-
- return skb->len;
+ return RTA_NEST_END(skb, opts);
rtattr_failure:
- skb_trim(skb, b - skb->data);
- return -1;
+ return RTA_NEST_CANCEL(skb, opts);
}
static int red_dump_stats(struct Qdisc *sch, struct gnet_dump *d)
{
struct red_sched_data *q = qdisc_priv(sch);
-
- return gnet_stats_copy_app(d, &q->st, sizeof(q->st));
+ struct tc_red_xstats st = {
+ .early = q->stats.prob_drop + q->stats.forced_drop,
+ .pdrop = q->stats.pdrop,
+ .other = q->stats.other,
+ .marked = q->stats.prob_mark + q->stats.forced_mark,
+ };
+
+ return gnet_stats_copy_app(d, &st, sizeof(st));
}
static struct Qdisc_ops red_qdisc_ops = {
- .next = NULL,
- .cl_ops = NULL,
.id = "red",
.priv_size = sizeof(struct red_sched_data),
.enqueue = red_enqueue,
@@ -450,10 +243,13 @@ static int __init red_module_init(void)
{
return register_qdisc(&red_qdisc_ops);
}
-static void __exit red_module_exit(void)
+
+static void __exit red_module_exit(void)
{
unregister_qdisc(&red_qdisc_ops);
}
+
module_init(red_module_init)
module_exit(red_module_exit)
+
MODULE_LICENSE("GPL");
diff --git a/net/sctp/associola.c b/net/sctp/associola.c
index 12b0f582a66b..8c8ddf7f9b61 100644
--- a/net/sctp/associola.c
+++ b/net/sctp/associola.c
@@ -344,9 +344,7 @@ void sctp_association_free(struct sctp_association *asoc)
}
/* Free peer's cached cookie. */
- if (asoc->peer.cookie) {
- kfree(asoc->peer.cookie);
- }
+ kfree(asoc->peer.cookie);
/* Release the transport structures. */
list_for_each_safe(pos, temp, &asoc->peer.transport_addr_list) {
diff --git a/net/sctp/proc.c b/net/sctp/proc.c
index b74f7772b576..6e4dc28874d7 100644
--- a/net/sctp/proc.c
+++ b/net/sctp/proc.c
@@ -69,9 +69,7 @@ fold_field(void *mib[], int nr)
unsigned long res = 0;
int i;
- for (i = 0; i < NR_CPUS; i++) {
- if (!cpu_possible(i))
- continue;
+ for_each_cpu(i) {
res +=
*((unsigned long *) (((void *) per_cpu_ptr(mib[0], i)) +
sizeof (unsigned long) * nr));
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
index 10e82ec2ebd3..f9573eba5c7a 100644
--- a/net/sctp/sm_make_chunk.c
+++ b/net/sctp/sm_make_chunk.c
@@ -254,8 +254,7 @@ struct sctp_chunk *sctp_make_init(const struct sctp_association *asoc,
aiparam.adaption_ind = htonl(sp->adaption_ind);
sctp_addto_chunk(retval, sizeof(aiparam), &aiparam);
nodata:
- if (addrs.v)
- kfree(addrs.v);
+ kfree(addrs.v);
return retval;
}
@@ -347,8 +346,7 @@ struct sctp_chunk *sctp_make_init_ack(const struct sctp_association *asoc,
nomem_chunk:
kfree(cookie);
nomem_cookie:
- if (addrs.v)
- kfree(addrs.v);
+ kfree(addrs.v);
return retval;
}
@@ -554,7 +552,7 @@ struct sctp_chunk *sctp_make_datafrag_empty(struct sctp_association *asoc,
dp.ppid = sinfo->sinfo_ppid;
/* Set the flags for an unordered send. */
- if (sinfo->sinfo_flags & MSG_UNORDERED) {
+ if (sinfo->sinfo_flags & SCTP_UNORDERED) {
flags |= SCTP_DATA_UNORDERED;
dp.ssn = 0;
} else
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 02e068d3450d..b529af5e6f2a 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -1010,6 +1010,19 @@ static int __sctp_connect(struct sock* sk,
err = -EAGAIN;
goto out_free;
}
+ } else {
+ /*
+ * If an unprivileged user inherits a 1-many
+ * style socket with open associations on a
+ * privileged port, it MAY be permitted to
+ * accept new associations, but it SHOULD NOT
+ * be permitted to open new associations.
+ */
+ if (ep->base.bind_addr.port < PROT_SOCK &&
+ !capable(CAP_NET_BIND_SERVICE)) {
+ err = -EACCES;
+ goto out_free;
+ }
}
scope = sctp_scope(&to);
@@ -1389,27 +1402,27 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk,
SCTP_DEBUG_PRINTK("msg_len: %zu, sinfo_flags: 0x%x\n",
msg_len, sinfo_flags);
- /* MSG_EOF or MSG_ABORT cannot be set on a TCP-style socket. */
- if (sctp_style(sk, TCP) && (sinfo_flags & (MSG_EOF | MSG_ABORT))) {
+ /* SCTP_EOF or SCTP_ABORT cannot be set on a TCP-style socket. */
+ if (sctp_style(sk, TCP) && (sinfo_flags & (SCTP_EOF | SCTP_ABORT))) {
err = -EINVAL;
goto out_nounlock;
}
- /* If MSG_EOF is set, no data can be sent. Disallow sending zero
- * length messages when MSG_EOF|MSG_ABORT is not set.
- * If MSG_ABORT is set, the message length could be non zero with
+ /* If SCTP_EOF is set, no data can be sent. Disallow sending zero
+ * length messages when SCTP_EOF|SCTP_ABORT is not set.
+ * If SCTP_ABORT is set, the message length could be non zero with
* the msg_iov set to the user abort reason.
*/
- if (((sinfo_flags & MSG_EOF) && (msg_len > 0)) ||
- (!(sinfo_flags & (MSG_EOF|MSG_ABORT)) && (msg_len == 0))) {
+ if (((sinfo_flags & SCTP_EOF) && (msg_len > 0)) ||
+ (!(sinfo_flags & (SCTP_EOF|SCTP_ABORT)) && (msg_len == 0))) {
err = -EINVAL;
goto out_nounlock;
}
- /* If MSG_ADDR_OVER is set, there must be an address
+ /* If SCTP_ADDR_OVER is set, there must be an address
* specified in msg_name.
*/
- if ((sinfo_flags & MSG_ADDR_OVER) && (!msg->msg_name)) {
+ if ((sinfo_flags & SCTP_ADDR_OVER) && (!msg->msg_name)) {
err = -EINVAL;
goto out_nounlock;
}
@@ -1458,14 +1471,14 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk,
goto out_unlock;
}
- if (sinfo_flags & MSG_EOF) {
+ if (sinfo_flags & SCTP_EOF) {
SCTP_DEBUG_PRINTK("Shutting down association: %p\n",
asoc);
sctp_primitive_SHUTDOWN(asoc, NULL);
err = 0;
goto out_unlock;
}
- if (sinfo_flags & MSG_ABORT) {
+ if (sinfo_flags & SCTP_ABORT) {
SCTP_DEBUG_PRINTK("Aborting association: %p\n", asoc);
sctp_primitive_ABORT(asoc, msg);
err = 0;
@@ -1477,7 +1490,7 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk,
if (!asoc) {
SCTP_DEBUG_PRINTK("There is no association yet.\n");
- if (sinfo_flags & (MSG_EOF | MSG_ABORT)) {
+ if (sinfo_flags & (SCTP_EOF | SCTP_ABORT)) {
err = -EINVAL;
goto out_unlock;
}
@@ -1515,6 +1528,19 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk,
err = -EAGAIN;
goto out_unlock;
}
+ } else {
+ /*
+ * If an unprivileged user inherits a one-to-many
+ * style socket with open associations on a privileged
+ * port, it MAY be permitted to accept new associations,
+ * but it SHOULD NOT be permitted to open new
+ * associations.
+ */
+ if (ep->base.bind_addr.port < PROT_SOCK &&
+ !capable(CAP_NET_BIND_SERVICE)) {
+ err = -EACCES;
+ goto out_unlock;
+ }
}
scope = sctp_scope(&to);
@@ -1611,10 +1637,10 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk,
/* If an address is passed with the sendto/sendmsg call, it is used
* to override the primary destination address in the TCP model, or
- * when MSG_ADDR_OVER flag is set in the UDP model.
+ * when SCTP_ADDR_OVER flag is set in the UDP model.
*/
if ((sctp_style(sk, TCP) && msg_name) ||
- (sinfo_flags & MSG_ADDR_OVER)) {
+ (sinfo_flags & SCTP_ADDR_OVER)) {
chunk_tp = sctp_assoc_lookup_paddr(asoc, &to);
if (!chunk_tp) {
err = -EINVAL;
@@ -2306,16 +2332,14 @@ static int sctp_setsockopt_maxseg(struct sock *sk, char __user *optval, int optl
return -EINVAL;
if (get_user(val, (int __user *)optval))
return -EFAULT;
- if ((val < 8) || (val > SCTP_MAX_CHUNK_LEN))
+ if ((val != 0) && ((val < 8) || (val > SCTP_MAX_CHUNK_LEN)))
return -EINVAL;
sp->user_frag = val;
- if (val) {
- /* Update the frag_point of the existing associations. */
- list_for_each(pos, &(sp->ep->asocs)) {
- asoc = list_entry(pos, struct sctp_association, asocs);
- asoc->frag_point = sctp_frag_point(sp, asoc->pmtu);
- }
+ /* Update the frag_point of the existing associations. */
+ list_for_each(pos, &(sp->ep->asocs)) {
+ asoc = list_entry(pos, struct sctp_association, asocs);
+ asoc->frag_point = sctp_frag_point(sp, asoc->pmtu);
}
return 0;
@@ -2384,14 +2408,14 @@ static int sctp_setsockopt_peer_primary_addr(struct sock *sk, char __user *optva
static int sctp_setsockopt_adaption_layer(struct sock *sk, char __user *optval,
int optlen)
{
- __u32 val;
+ struct sctp_setadaption adaption;
- if (optlen < sizeof(__u32))
+ if (optlen != sizeof(struct sctp_setadaption))
return -EINVAL;
- if (copy_from_user(&val, optval, sizeof(__u32)))
+ if (copy_from_user(&adaption, optval, optlen))
return -EFAULT;
- sctp_sk(sk)->adaption_ind = val;
+ sctp_sk(sk)->adaption_ind = adaption.ssb_adaption_ind;
return 0;
}
@@ -3672,17 +3696,15 @@ static int sctp_getsockopt_primary_addr(struct sock *sk, int len,
static int sctp_getsockopt_adaption_layer(struct sock *sk, int len,
char __user *optval, int __user *optlen)
{
- __u32 val;
+ struct sctp_setadaption adaption;
- if (len < sizeof(__u32))
+ if (len != sizeof(struct sctp_setadaption))
return -EINVAL;
- len = sizeof(__u32);
- val = sctp_sk(sk)->adaption_ind;
- if (put_user(len, optlen))
- return -EFAULT;
- if (copy_to_user(optval, &val, len))
+ adaption.ssb_adaption_ind = sctp_sk(sk)->adaption_ind;
+ if (copy_to_user(optval, &adaption, len))
return -EFAULT;
+
return 0;
}
@@ -4640,8 +4662,8 @@ SCTP_STATIC int sctp_msghdr_parse(const struct msghdr *msg,
/* Minimally, validate the sinfo_flags. */
if (cmsgs->info->sinfo_flags &
- ~(MSG_UNORDERED | MSG_ADDR_OVER |
- MSG_ABORT | MSG_EOF))
+ ~(SCTP_UNORDERED | SCTP_ADDR_OVER |
+ SCTP_ABORT | SCTP_EOF))
return -EINVAL;
break;
diff --git a/net/sctp/ulpevent.c b/net/sctp/ulpevent.c
index 057e7fac3af0..e049f41faa47 100644
--- a/net/sctp/ulpevent.c
+++ b/net/sctp/ulpevent.c
@@ -698,7 +698,7 @@ struct sctp_ulpevent *sctp_ulpevent_make_rcvmsg(struct sctp_association *asoc,
event->ssn = ntohs(chunk->subh.data_hdr->ssn);
event->ppid = chunk->subh.data_hdr->ppid;
if (chunk->chunk_hdr->flags & SCTP_DATA_UNORDERED) {
- event->flags |= MSG_UNORDERED;
+ event->flags |= SCTP_UNORDERED;
event->cumtsn = sctp_tsnmap_get_ctsn(&asoc->peer.tsn_map);
}
event->tsn = ntohl(chunk->subh.data_hdr->tsn);
@@ -824,7 +824,7 @@ void sctp_ulpevent_read_sndrcvinfo(const struct sctp_ulpevent *event,
*
* recvmsg() flags:
*
- * MSG_UNORDERED - This flag is present when the message was sent
+ * SCTP_UNORDERED - This flag is present when the message was sent
* non-ordered.
*/
sinfo.sinfo_flags = event->flags;
@@ -839,7 +839,7 @@ void sctp_ulpevent_read_sndrcvinfo(const struct sctp_ulpevent *event,
* This field will hold the current cumulative TSN as
* known by the underlying SCTP layer. Note this field is
* ignored when sending and only valid for a receive
- * operation when sinfo_flags are set to MSG_UNORDERED.
+ * operation when sinfo_flags are set to SCTP_UNORDERED.
*/
sinfo.sinfo_cumtsn = event->cumtsn;
/* sinfo_assoc_id: sizeof (sctp_assoc_t)
diff --git a/net/sunrpc/Makefile b/net/sunrpc/Makefile
index 46a2ce00a29b..cdcab9ca4c60 100644
--- a/net/sunrpc/Makefile
+++ b/net/sunrpc/Makefile
@@ -6,7 +6,7 @@
obj-$(CONFIG_SUNRPC) += sunrpc.o
obj-$(CONFIG_SUNRPC_GSS) += auth_gss/
-sunrpc-y := clnt.o xprt.o sched.o \
+sunrpc-y := clnt.o xprt.o socklib.o xprtsock.o sched.o \
auth.o auth_null.o auth_unix.o \
svc.o svcsock.o svcauth.o svcauth_unix.o \
pmap_clnt.o timer.o xdr.o \
diff --git a/net/sunrpc/auth.c b/net/sunrpc/auth.c
index 505e2d4b3d62..8c7756036e95 100644
--- a/net/sunrpc/auth.c
+++ b/net/sunrpc/auth.c
@@ -11,7 +11,6 @@
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/errno.h>
-#include <linux/socket.h>
#include <linux/sunrpc/clnt.h>
#include <linux/spinlock.h>
@@ -300,11 +299,10 @@ put_rpccred(struct rpc_cred *cred)
void
rpcauth_unbindcred(struct rpc_task *task)
{
- struct rpc_auth *auth = task->tk_auth;
struct rpc_cred *cred = task->tk_msg.rpc_cred;
dprintk("RPC: %4d releasing %s cred %p\n",
- task->tk_pid, auth->au_ops->au_name, cred);
+ task->tk_pid, task->tk_auth->au_ops->au_name, cred);
put_rpccred(cred);
task->tk_msg.rpc_cred = NULL;
@@ -313,22 +311,22 @@ rpcauth_unbindcred(struct rpc_task *task)
u32 *
rpcauth_marshcred(struct rpc_task *task, u32 *p)
{
- struct rpc_auth *auth = task->tk_auth;
struct rpc_cred *cred = task->tk_msg.rpc_cred;
dprintk("RPC: %4d marshaling %s cred %p\n",
- task->tk_pid, auth->au_ops->au_name, cred);
+ task->tk_pid, task->tk_auth->au_ops->au_name, cred);
+
return cred->cr_ops->crmarshal(task, p);
}
u32 *
rpcauth_checkverf(struct rpc_task *task, u32 *p)
{
- struct rpc_auth *auth = task->tk_auth;
struct rpc_cred *cred = task->tk_msg.rpc_cred;
dprintk("RPC: %4d validating %s cred %p\n",
- task->tk_pid, auth->au_ops->au_name, cred);
+ task->tk_pid, task->tk_auth->au_ops->au_name, cred);
+
return cred->cr_ops->crvalidate(task, p);
}
@@ -364,12 +362,12 @@ rpcauth_unwrap_resp(struct rpc_task *task, kxdrproc_t decode, void *rqstp,
int
rpcauth_refreshcred(struct rpc_task *task)
{
- struct rpc_auth *auth = task->tk_auth;
struct rpc_cred *cred = task->tk_msg.rpc_cred;
int err;
dprintk("RPC: %4d refreshing %s cred %p\n",
- task->tk_pid, auth->au_ops->au_name, cred);
+ task->tk_pid, task->tk_auth->au_ops->au_name, cred);
+
err = cred->cr_ops->crrefresh(task);
if (err < 0)
task->tk_status = err;
diff --git a/net/sunrpc/auth_gss/Makefile b/net/sunrpc/auth_gss/Makefile
index fe1b874084bc..f3431a7e33da 100644
--- a/net/sunrpc/auth_gss/Makefile
+++ b/net/sunrpc/auth_gss/Makefile
@@ -10,7 +10,7 @@ auth_rpcgss-objs := auth_gss.o gss_generic_token.o \
obj-$(CONFIG_RPCSEC_GSS_KRB5) += rpcsec_gss_krb5.o
rpcsec_gss_krb5-objs := gss_krb5_mech.o gss_krb5_seal.o gss_krb5_unseal.o \
- gss_krb5_seqnum.o
+ gss_krb5_seqnum.o gss_krb5_wrap.o
obj-$(CONFIG_RPCSEC_GSS_SPKM3) += rpcsec_gss_spkm3.o
diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c
index 2f7b867161d2..f44f46f1d8e0 100644
--- a/net/sunrpc/auth_gss/auth_gss.c
+++ b/net/sunrpc/auth_gss/auth_gss.c
@@ -42,9 +42,8 @@
#include <linux/init.h>
#include <linux/types.h>
#include <linux/slab.h>
-#include <linux/socket.h>
-#include <linux/in.h>
#include <linux/sched.h>
+#include <linux/pagemap.h>
#include <linux/sunrpc/clnt.h>
#include <linux/sunrpc/auth.h>
#include <linux/sunrpc/auth_gss.h>
@@ -846,10 +845,8 @@ gss_marshal(struct rpc_task *task, u32 *p)
/* We compute the checksum for the verifier over the xdr-encoded bytes
* starting with the xid and ending at the end of the credential: */
- iov.iov_base = req->rq_snd_buf.head[0].iov_base;
- if (task->tk_client->cl_xprt->stream)
- /* See clnt.c:call_header() */
- iov.iov_base += 4;
+ iov.iov_base = xprt_skip_transport_header(task->tk_xprt,
+ req->rq_snd_buf.head[0].iov_base);
iov.iov_len = (u8 *)p - (u8 *)iov.iov_base;
xdr_buf_from_iov(&iov, &verf_buf);
@@ -857,9 +854,7 @@ gss_marshal(struct rpc_task *task, u32 *p)
*p++ = htonl(RPC_AUTH_GSS);
mic.data = (u8 *)(p + 1);
- maj_stat = gss_get_mic(ctx->gc_gss_ctx,
- GSS_C_QOP_DEFAULT,
- &verf_buf, &mic);
+ maj_stat = gss_get_mic(ctx->gc_gss_ctx, &verf_buf, &mic);
if (maj_stat == GSS_S_CONTEXT_EXPIRED) {
cred->cr_flags &= ~RPCAUTH_CRED_UPTODATE;
} else if (maj_stat != 0) {
@@ -890,10 +885,8 @@ static u32 *
gss_validate(struct rpc_task *task, u32 *p)
{
struct rpc_cred *cred = task->tk_msg.rpc_cred;
- struct gss_cred *gss_cred = container_of(cred, struct gss_cred,
- gc_base);
struct gss_cl_ctx *ctx = gss_cred_get_ctx(cred);
- u32 seq, qop_state;
+ u32 seq;
struct kvec iov;
struct xdr_buf verf_buf;
struct xdr_netobj mic;
@@ -914,23 +907,14 @@ gss_validate(struct rpc_task *task, u32 *p)
mic.data = (u8 *)p;
mic.len = len;
- maj_stat = gss_verify_mic(ctx->gc_gss_ctx, &verf_buf, &mic, &qop_state);
+ maj_stat = gss_verify_mic(ctx->gc_gss_ctx, &verf_buf, &mic);
if (maj_stat == GSS_S_CONTEXT_EXPIRED)
cred->cr_flags &= ~RPCAUTH_CRED_UPTODATE;
if (maj_stat)
goto out_bad;
- switch (gss_cred->gc_service) {
- case RPC_GSS_SVC_NONE:
- /* verifier data, flavor, length: */
- task->tk_auth->au_rslack = XDR_QUADLEN(len) + 2;
- break;
- case RPC_GSS_SVC_INTEGRITY:
- /* verifier data, flavor, length, length, sequence number: */
- task->tk_auth->au_rslack = XDR_QUADLEN(len) + 4;
- break;
- case RPC_GSS_SVC_PRIVACY:
- goto out_bad;
- }
+ /* We leave it to unwrap to calculate au_rslack. For now we just
+ * calculate the length of the verifier: */
+ task->tk_auth->au_verfsize = XDR_QUADLEN(len) + 2;
gss_put_ctx(ctx);
dprintk("RPC: %4u GSS gss_validate: gss_verify_mic succeeded.\n",
task->tk_pid);
@@ -975,8 +959,7 @@ gss_wrap_req_integ(struct rpc_cred *cred, struct gss_cl_ctx *ctx,
p = iov->iov_base + iov->iov_len;
mic.data = (u8 *)(p + 1);
- maj_stat = gss_get_mic(ctx->gc_gss_ctx,
- GSS_C_QOP_DEFAULT, &integ_buf, &mic);
+ maj_stat = gss_get_mic(ctx->gc_gss_ctx, &integ_buf, &mic);
status = -EIO; /* XXX? */
if (maj_stat == GSS_S_CONTEXT_EXPIRED)
cred->cr_flags &= ~RPCAUTH_CRED_UPTODATE;
@@ -990,6 +973,113 @@ gss_wrap_req_integ(struct rpc_cred *cred, struct gss_cl_ctx *ctx,
return 0;
}
+static void
+priv_release_snd_buf(struct rpc_rqst *rqstp)
+{
+ int i;
+
+ for (i=0; i < rqstp->rq_enc_pages_num; i++)
+ __free_page(rqstp->rq_enc_pages[i]);
+ kfree(rqstp->rq_enc_pages);
+}
+
+static int
+alloc_enc_pages(struct rpc_rqst *rqstp)
+{
+ struct xdr_buf *snd_buf = &rqstp->rq_snd_buf;
+ int first, last, i;
+
+ if (snd_buf->page_len == 0) {
+ rqstp->rq_enc_pages_num = 0;
+ return 0;
+ }
+
+ first = snd_buf->page_base >> PAGE_CACHE_SHIFT;
+ last = (snd_buf->page_base + snd_buf->page_len - 1) >> PAGE_CACHE_SHIFT;
+ rqstp->rq_enc_pages_num = last - first + 1 + 1;
+ rqstp->rq_enc_pages
+ = kmalloc(rqstp->rq_enc_pages_num * sizeof(struct page *),
+ GFP_NOFS);
+ if (!rqstp->rq_enc_pages)
+ goto out;
+ for (i=0; i < rqstp->rq_enc_pages_num; i++) {
+ rqstp->rq_enc_pages[i] = alloc_page(GFP_NOFS);
+ if (rqstp->rq_enc_pages[i] == NULL)
+ goto out_free;
+ }
+ rqstp->rq_release_snd_buf = priv_release_snd_buf;
+ return 0;
+out_free:
+ for (i--; i >= 0; i--) {
+ __free_page(rqstp->rq_enc_pages[i]);
+ }
+out:
+ return -EAGAIN;
+}
+
+static inline int
+gss_wrap_req_priv(struct rpc_cred *cred, struct gss_cl_ctx *ctx,
+ kxdrproc_t encode, struct rpc_rqst *rqstp, u32 *p, void *obj)
+{
+ struct xdr_buf *snd_buf = &rqstp->rq_snd_buf;
+ u32 offset;
+ u32 maj_stat;
+ int status;
+ u32 *opaque_len;
+ struct page **inpages;
+ int first;
+ int pad;
+ struct kvec *iov;
+ char *tmp;
+
+ opaque_len = p++;
+ offset = (u8 *)p - (u8 *)snd_buf->head[0].iov_base;
+ *p++ = htonl(rqstp->rq_seqno);
+
+ status = encode(rqstp, p, obj);
+ if (status)
+ return status;
+
+ status = alloc_enc_pages(rqstp);
+ if (status)
+ return status;
+ first = snd_buf->page_base >> PAGE_CACHE_SHIFT;
+ inpages = snd_buf->pages + first;
+ snd_buf->pages = rqstp->rq_enc_pages;
+ snd_buf->page_base -= first << PAGE_CACHE_SHIFT;
+ /* Give the tail its own page, in case we need extra space in the
+ * head when wrapping: */
+ if (snd_buf->page_len || snd_buf->tail[0].iov_len) {
+ tmp = page_address(rqstp->rq_enc_pages[rqstp->rq_enc_pages_num - 1]);
+ memcpy(tmp, snd_buf->tail[0].iov_base, snd_buf->tail[0].iov_len);
+ snd_buf->tail[0].iov_base = tmp;
+ }
+ maj_stat = gss_wrap(ctx->gc_gss_ctx, offset, snd_buf, inpages);
+ /* RPC_SLACK_SPACE should prevent this ever happening: */
+ BUG_ON(snd_buf->len > snd_buf->buflen);
+ status = -EIO;
+ /* We're assuming that when GSS_S_CONTEXT_EXPIRED, the encryption was
+ * done anyway, so it's safe to put the request on the wire: */
+ if (maj_stat == GSS_S_CONTEXT_EXPIRED)
+ cred->cr_flags &= ~RPCAUTH_CRED_UPTODATE;
+ else if (maj_stat)
+ return status;
+
+ *opaque_len = htonl(snd_buf->len - offset);
+ /* guess whether we're in the head or the tail: */
+ if (snd_buf->page_len || snd_buf->tail[0].iov_len)
+ iov = snd_buf->tail;
+ else
+ iov = snd_buf->head;
+ p = iov->iov_base + iov->iov_len;
+ pad = 3 - ((snd_buf->len - offset - 1) & 3);
+ memset(p, 0, pad);
+ iov->iov_len += pad;
+ snd_buf->len += pad;
+
+ return 0;
+}
+
static int
gss_wrap_req(struct rpc_task *task,
kxdrproc_t encode, void *rqstp, u32 *p, void *obj)
@@ -1017,6 +1107,8 @@ gss_wrap_req(struct rpc_task *task,
rqstp, p, obj);
break;
case RPC_GSS_SVC_PRIVACY:
+ status = gss_wrap_req_priv(cred, ctx, encode,
+ rqstp, p, obj);
break;
}
out:
@@ -1054,8 +1146,7 @@ gss_unwrap_resp_integ(struct rpc_cred *cred, struct gss_cl_ctx *ctx,
if (xdr_buf_read_netobj(rcv_buf, &mic, mic_offset))
return status;
- maj_stat = gss_verify_mic(ctx->gc_gss_ctx, &integ_buf,
- &mic, NULL);
+ maj_stat = gss_verify_mic(ctx->gc_gss_ctx, &integ_buf, &mic);
if (maj_stat == GSS_S_CONTEXT_EXPIRED)
cred->cr_flags &= ~RPCAUTH_CRED_UPTODATE;
if (maj_stat != GSS_S_COMPLETE)
@@ -1063,6 +1154,35 @@ gss_unwrap_resp_integ(struct rpc_cred *cred, struct gss_cl_ctx *ctx,
return 0;
}
+static inline int
+gss_unwrap_resp_priv(struct rpc_cred *cred, struct gss_cl_ctx *ctx,
+ struct rpc_rqst *rqstp, u32 **p)
+{
+ struct xdr_buf *rcv_buf = &rqstp->rq_rcv_buf;
+ u32 offset;
+ u32 opaque_len;
+ u32 maj_stat;
+ int status = -EIO;
+
+ opaque_len = ntohl(*(*p)++);
+ offset = (u8 *)(*p) - (u8 *)rcv_buf->head[0].iov_base;
+ if (offset + opaque_len > rcv_buf->len)
+ return status;
+ /* remove padding: */
+ rcv_buf->len = offset + opaque_len;
+
+ maj_stat = gss_unwrap(ctx->gc_gss_ctx, offset, rcv_buf);
+ if (maj_stat == GSS_S_CONTEXT_EXPIRED)
+ cred->cr_flags &= ~RPCAUTH_CRED_UPTODATE;
+ if (maj_stat != GSS_S_COMPLETE)
+ return status;
+ if (ntohl(*(*p)++) != rqstp->rq_seqno)
+ return status;
+
+ return 0;
+}
+
+
static int
gss_unwrap_resp(struct rpc_task *task,
kxdrproc_t decode, void *rqstp, u32 *p, void *obj)
@@ -1071,6 +1191,9 @@ gss_unwrap_resp(struct rpc_task *task,
struct gss_cred *gss_cred = container_of(cred, struct gss_cred,
gc_base);
struct gss_cl_ctx *ctx = gss_cred_get_ctx(cred);
+ u32 *savedp = p;
+ struct kvec *head = ((struct rpc_rqst *)rqstp)->rq_rcv_buf.head;
+ int savedlen = head->iov_len;
int status = -EIO;
if (ctx->gc_proc != RPC_GSS_PROC_DATA)
@@ -1084,8 +1207,14 @@ gss_unwrap_resp(struct rpc_task *task,
goto out;
break;
case RPC_GSS_SVC_PRIVACY:
+ status = gss_unwrap_resp_priv(cred, ctx, rqstp, &p);
+ if (status)
+ goto out;
break;
}
+ /* take into account extra slack for integrity and privacy cases: */
+ task->tk_auth->au_rslack = task->tk_auth->au_verfsize + (p - savedp)
+ + (savedlen - head->iov_len);
out_decode:
status = decode(rqstp, p, obj);
out:
diff --git a/net/sunrpc/auth_gss/gss_krb5_crypto.c b/net/sunrpc/auth_gss/gss_krb5_crypto.c
index ee6ae74cd1b2..97c981fa6b8e 100644
--- a/net/sunrpc/auth_gss/gss_krb5_crypto.c
+++ b/net/sunrpc/auth_gss/gss_krb5_crypto.c
@@ -37,7 +37,7 @@
#include <linux/types.h>
#include <linux/mm.h>
#include <linux/slab.h>
-#include <asm/scatterlist.h>
+#include <linux/scatterlist.h>
#include <linux/crypto.h>
#include <linux/highmem.h>
#include <linux/pagemap.h>
@@ -75,9 +75,7 @@ krb5_encrypt(
memcpy(local_iv, iv, crypto_tfm_alg_ivsize(tfm));
memcpy(out, in, length);
- sg[0].page = virt_to_page(out);
- sg[0].offset = offset_in_page(out);
- sg[0].length = length;
+ sg_set_buf(sg, out, length);
ret = crypto_cipher_encrypt_iv(tfm, sg, sg, length, local_iv);
@@ -117,9 +115,7 @@ krb5_decrypt(
memcpy(local_iv,iv, crypto_tfm_alg_ivsize(tfm));
memcpy(out, in, length);
- sg[0].page = virt_to_page(out);
- sg[0].offset = offset_in_page(out);
- sg[0].length = length;
+ sg_set_buf(sg, out, length);
ret = crypto_cipher_decrypt_iv(tfm, sg, sg, length, local_iv);
@@ -132,24 +128,91 @@ out:
EXPORT_SYMBOL(krb5_decrypt);
-static void
-buf_to_sg(struct scatterlist *sg, char *ptr, int len) {
- sg->page = virt_to_page(ptr);
- sg->offset = offset_in_page(ptr);
- sg->length = len;
+static int
+process_xdr_buf(struct xdr_buf *buf, int offset, int len,
+ int (*actor)(struct scatterlist *, void *), void *data)
+{
+ int i, page_len, thislen, page_offset, ret = 0;
+ struct scatterlist sg[1];
+
+ if (offset >= buf->head[0].iov_len) {
+ offset -= buf->head[0].iov_len;
+ } else {
+ thislen = buf->head[0].iov_len - offset;
+ if (thislen > len)
+ thislen = len;
+ sg_set_buf(sg, buf->head[0].iov_base + offset, thislen);
+ ret = actor(sg, data);
+ if (ret)
+ goto out;
+ offset = 0;
+ len -= thislen;
+ }
+ if (len == 0)
+ goto out;
+
+ if (offset >= buf->page_len) {
+ offset -= buf->page_len;
+ } else {
+ page_len = buf->page_len - offset;
+ if (page_len > len)
+ page_len = len;
+ len -= page_len;
+ page_offset = (offset + buf->page_base) & (PAGE_CACHE_SIZE - 1);
+ i = (offset + buf->page_base) >> PAGE_CACHE_SHIFT;
+ thislen = PAGE_CACHE_SIZE - page_offset;
+ do {
+ if (thislen > page_len)
+ thislen = page_len;
+ sg->page = buf->pages[i];
+ sg->offset = page_offset;
+ sg->length = thislen;
+ ret = actor(sg, data);
+ if (ret)
+ goto out;
+ page_len -= thislen;
+ i++;
+ page_offset = 0;
+ thislen = PAGE_CACHE_SIZE;
+ } while (page_len != 0);
+ offset = 0;
+ }
+ if (len == 0)
+ goto out;
+
+ if (offset < buf->tail[0].iov_len) {
+ thislen = buf->tail[0].iov_len - offset;
+ if (thislen > len)
+ thislen = len;
+ sg_set_buf(sg, buf->tail[0].iov_base + offset, thislen);
+ ret = actor(sg, data);
+ len -= thislen;
+ }
+ if (len != 0)
+ ret = -EINVAL;
+out:
+ return ret;
+}
+
+static int
+checksummer(struct scatterlist *sg, void *data)
+{
+ struct crypto_tfm *tfm = (struct crypto_tfm *)data;
+
+ crypto_digest_update(tfm, sg, 1);
+
+ return 0;
}
/* checksum the plaintext data and hdrlen bytes of the token header */
s32
make_checksum(s32 cksumtype, char *header, int hdrlen, struct xdr_buf *body,
- struct xdr_netobj *cksum)
+ int body_offset, struct xdr_netobj *cksum)
{
char *cksumname;
struct crypto_tfm *tfm = NULL; /* XXX add to ctx? */
struct scatterlist sg[1];
u32 code = GSS_S_FAILURE;
- int len, thislen, offset;
- int i;
switch (cksumtype) {
case CKSUMTYPE_RSA_MD5:
@@ -167,35 +230,10 @@ make_checksum(s32 cksumtype, char *header, int hdrlen, struct xdr_buf *body,
goto out;
crypto_digest_init(tfm);
- buf_to_sg(sg, header, hdrlen);
+ sg_set_buf(sg, header, hdrlen);
crypto_digest_update(tfm, sg, 1);
- if (body->head[0].iov_len) {
- buf_to_sg(sg, body->head[0].iov_base, body->head[0].iov_len);
- crypto_digest_update(tfm, sg, 1);
- }
-
- len = body->page_len;
- if (len != 0) {
- offset = body->page_base & (PAGE_CACHE_SIZE - 1);
- i = body->page_base >> PAGE_CACHE_SHIFT;
- thislen = PAGE_CACHE_SIZE - offset;
- do {
- if (thislen > len)
- thislen = len;
- sg->page = body->pages[i];
- sg->offset = offset;
- sg->length = thislen;
- crypto_digest_update(tfm, sg, 1);
- len -= thislen;
- i++;
- offset = 0;
- thislen = PAGE_CACHE_SIZE;
- } while(len != 0);
- }
- if (body->tail[0].iov_len) {
- buf_to_sg(sg, body->tail[0].iov_base, body->tail[0].iov_len);
- crypto_digest_update(tfm, sg, 1);
- }
+ process_xdr_buf(body, body_offset, body->len - body_offset,
+ checksummer, tfm);
crypto_digest_final(tfm, cksum->data);
code = 0;
out:
@@ -204,3 +242,154 @@ out:
}
EXPORT_SYMBOL(make_checksum);
+
+struct encryptor_desc {
+ u8 iv[8]; /* XXX hard-coded blocksize */
+ struct crypto_tfm *tfm;
+ int pos;
+ struct xdr_buf *outbuf;
+ struct page **pages;
+ struct scatterlist infrags[4];
+ struct scatterlist outfrags[4];
+ int fragno;
+ int fraglen;
+};
+
+static int
+encryptor(struct scatterlist *sg, void *data)
+{
+ struct encryptor_desc *desc = data;
+ struct xdr_buf *outbuf = desc->outbuf;
+ struct page *in_page;
+ int thislen = desc->fraglen + sg->length;
+ int fraglen, ret;
+ int page_pos;
+
+ /* Worst case is 4 fragments: head, end of page 1, start
+ * of page 2, tail. Anything more is a bug. */
+ BUG_ON(desc->fragno > 3);
+ desc->infrags[desc->fragno] = *sg;
+ desc->outfrags[desc->fragno] = *sg;
+
+ page_pos = desc->pos - outbuf->head[0].iov_len;
+ if (page_pos >= 0 && page_pos < outbuf->page_len) {
+ /* pages are not in place: */
+ int i = (page_pos + outbuf->page_base) >> PAGE_CACHE_SHIFT;
+ in_page = desc->pages[i];
+ } else {
+ in_page = sg->page;
+ }
+ desc->infrags[desc->fragno].page = in_page;
+ desc->fragno++;
+ desc->fraglen += sg->length;
+ desc->pos += sg->length;
+
+ fraglen = thislen & 7; /* XXX hardcoded blocksize */
+ thislen -= fraglen;
+
+ if (thislen == 0)
+ return 0;
+
+ ret = crypto_cipher_encrypt_iv(desc->tfm, desc->outfrags, desc->infrags,
+ thislen, desc->iv);
+ if (ret)
+ return ret;
+ if (fraglen) {
+ desc->outfrags[0].page = sg->page;
+ desc->outfrags[0].offset = sg->offset + sg->length - fraglen;
+ desc->outfrags[0].length = fraglen;
+ desc->infrags[0] = desc->outfrags[0];
+ desc->infrags[0].page = in_page;
+ desc->fragno = 1;
+ desc->fraglen = fraglen;
+ } else {
+ desc->fragno = 0;
+ desc->fraglen = 0;
+ }
+ return 0;
+}
+
+int
+gss_encrypt_xdr_buf(struct crypto_tfm *tfm, struct xdr_buf *buf, int offset,
+ struct page **pages)
+{
+ int ret;
+ struct encryptor_desc desc;
+
+ BUG_ON((buf->len - offset) % crypto_tfm_alg_blocksize(tfm) != 0);
+
+ memset(desc.iv, 0, sizeof(desc.iv));
+ desc.tfm = tfm;
+ desc.pos = offset;
+ desc.outbuf = buf;
+ desc.pages = pages;
+ desc.fragno = 0;
+ desc.fraglen = 0;
+
+ ret = process_xdr_buf(buf, offset, buf->len - offset, encryptor, &desc);
+ return ret;
+}
+
+EXPORT_SYMBOL(gss_encrypt_xdr_buf);
+
+struct decryptor_desc {
+ u8 iv[8]; /* XXX hard-coded blocksize */
+ struct crypto_tfm *tfm;
+ struct scatterlist frags[4];
+ int fragno;
+ int fraglen;
+};
+
+static int
+decryptor(struct scatterlist *sg, void *data)
+{
+ struct decryptor_desc *desc = data;
+ int thislen = desc->fraglen + sg->length;
+ int fraglen, ret;
+
+ /* Worst case is 4 fragments: head, end of page 1, start
+ * of page 2, tail. Anything more is a bug. */
+ BUG_ON(desc->fragno > 3);
+ desc->frags[desc->fragno] = *sg;
+ desc->fragno++;
+ desc->fraglen += sg->length;
+
+ fraglen = thislen & 7; /* XXX hardcoded blocksize */
+ thislen -= fraglen;
+
+ if (thislen == 0)
+ return 0;
+
+ ret = crypto_cipher_decrypt_iv(desc->tfm, desc->frags, desc->frags,
+ thislen, desc->iv);
+ if (ret)
+ return ret;
+ if (fraglen) {
+ desc->frags[0].page = sg->page;
+ desc->frags[0].offset = sg->offset + sg->length - fraglen;
+ desc->frags[0].length = fraglen;
+ desc->fragno = 1;
+ desc->fraglen = fraglen;
+ } else {
+ desc->fragno = 0;
+ desc->fraglen = 0;
+ }
+ return 0;
+}
+
+int
+gss_decrypt_xdr_buf(struct crypto_tfm *tfm, struct xdr_buf *buf, int offset)
+{
+ struct decryptor_desc desc;
+
+ /* XXXJBF: */
+ BUG_ON((buf->len - offset) % crypto_tfm_alg_blocksize(tfm) != 0);
+
+ memset(desc.iv, 0, sizeof(desc.iv));
+ desc.tfm = tfm;
+ desc.fragno = 0;
+ desc.fraglen = 0;
+ return process_xdr_buf(buf, offset, buf->len - offset, decryptor, &desc);
+}
+
+EXPORT_SYMBOL(gss_decrypt_xdr_buf);
diff --git a/net/sunrpc/auth_gss/gss_krb5_mech.c b/net/sunrpc/auth_gss/gss_krb5_mech.c
index 606a8a82cafb..5f1f806a0b11 100644
--- a/net/sunrpc/auth_gss/gss_krb5_mech.c
+++ b/net/sunrpc/auth_gss/gss_krb5_mech.c
@@ -39,7 +39,6 @@
#include <linux/types.h>
#include <linux/slab.h>
#include <linux/sunrpc/auth.h>
-#include <linux/in.h>
#include <linux/sunrpc/gss_krb5.h>
#include <linux/sunrpc/xdr.h>
#include <linux/crypto.h>
@@ -191,43 +190,12 @@ gss_delete_sec_context_kerberos(void *internal_ctx) {
kfree(kctx);
}
-static u32
-gss_verify_mic_kerberos(struct gss_ctx *ctx,
- struct xdr_buf *message,
- struct xdr_netobj *mic_token,
- u32 *qstate) {
- u32 maj_stat = 0;
- int qop_state;
- struct krb5_ctx *kctx = ctx->internal_ctx_id;
-
- maj_stat = krb5_read_token(kctx, mic_token, message, &qop_state,
- KG_TOK_MIC_MSG);
- if (!maj_stat && qop_state)
- *qstate = qop_state;
-
- dprintk("RPC: gss_verify_mic_kerberos returning %d\n", maj_stat);
- return maj_stat;
-}
-
-static u32
-gss_get_mic_kerberos(struct gss_ctx *ctx,
- u32 qop,
- struct xdr_buf *message,
- struct xdr_netobj *mic_token) {
- u32 err = 0;
- struct krb5_ctx *kctx = ctx->internal_ctx_id;
-
- err = krb5_make_token(kctx, qop, message, mic_token, KG_TOK_MIC_MSG);
-
- dprintk("RPC: gss_get_mic_kerberos returning %d\n",err);
-
- return err;
-}
-
static struct gss_api_ops gss_kerberos_ops = {
.gss_import_sec_context = gss_import_sec_context_kerberos,
.gss_get_mic = gss_get_mic_kerberos,
.gss_verify_mic = gss_verify_mic_kerberos,
+ .gss_wrap = gss_wrap_kerberos,
+ .gss_unwrap = gss_unwrap_kerberos,
.gss_delete_sec_context = gss_delete_sec_context_kerberos,
};
@@ -242,6 +210,11 @@ static struct pf_desc gss_kerberos_pfs[] = {
.service = RPC_GSS_SVC_INTEGRITY,
.name = "krb5i",
},
+ [2] = {
+ .pseudoflavor = RPC_AUTH_GSS_KRB5P,
+ .service = RPC_GSS_SVC_PRIVACY,
+ .name = "krb5p",
+ },
};
static struct gss_api_mech gss_kerberos_mech = {
diff --git a/net/sunrpc/auth_gss/gss_krb5_seal.c b/net/sunrpc/auth_gss/gss_krb5_seal.c
index afeeb8715a77..d0dfdfd5e79e 100644
--- a/net/sunrpc/auth_gss/gss_krb5_seal.c
+++ b/net/sunrpc/auth_gss/gss_krb5_seal.c
@@ -70,22 +70,13 @@
# define RPCDBG_FACILITY RPCDBG_AUTH
#endif
-static inline int
-gss_krb5_padding(int blocksize, int length) {
- /* Most of the code is block-size independent but in practice we
- * use only 8: */
- BUG_ON(blocksize != 8);
- return 8 - (length & 7);
-}
-
u32
-krb5_make_token(struct krb5_ctx *ctx, int qop_req,
- struct xdr_buf *text, struct xdr_netobj *token,
- int toktype)
+gss_get_mic_kerberos(struct gss_ctx *gss_ctx, struct xdr_buf *text,
+ struct xdr_netobj *token)
{
+ struct krb5_ctx *ctx = gss_ctx->internal_ctx_id;
s32 checksum_type;
struct xdr_netobj md5cksum = {.len = 0, .data = NULL};
- int blocksize = 0, tmsglen;
unsigned char *ptr, *krb5_hdr, *msg_start;
s32 now;
@@ -93,9 +84,6 @@ krb5_make_token(struct krb5_ctx *ctx, int qop_req,
now = get_seconds();
- if (qop_req != 0)
- goto out_err;
-
switch (ctx->signalg) {
case SGN_ALG_DES_MAC_MD5:
checksum_type = CKSUMTYPE_RSA_MD5;
@@ -111,21 +99,13 @@ krb5_make_token(struct krb5_ctx *ctx, int qop_req,
goto out_err;
}
- if (toktype == KG_TOK_WRAP_MSG) {
- blocksize = crypto_tfm_alg_blocksize(ctx->enc);
- tmsglen = blocksize + text->len
- + gss_krb5_padding(blocksize, blocksize + text->len);
- } else {
- tmsglen = 0;
- }
-
- token->len = g_token_size(&ctx->mech_used, 22 + tmsglen);
+ token->len = g_token_size(&ctx->mech_used, 22);
ptr = token->data;
- g_make_token_header(&ctx->mech_used, 22 + tmsglen, &ptr);
+ g_make_token_header(&ctx->mech_used, 22, &ptr);
- *ptr++ = (unsigned char) ((toktype>>8)&0xff);
- *ptr++ = (unsigned char) (toktype&0xff);
+ *ptr++ = (unsigned char) ((KG_TOK_MIC_MSG>>8)&0xff);
+ *ptr++ = (unsigned char) (KG_TOK_MIC_MSG&0xff);
/* ptr now at byte 2 of header described in rfc 1964, section 1.2.1: */
krb5_hdr = ptr - 2;
@@ -133,17 +113,9 @@ krb5_make_token(struct krb5_ctx *ctx, int qop_req,
*(u16 *)(krb5_hdr + 2) = htons(ctx->signalg);
memset(krb5_hdr + 4, 0xff, 4);
- if (toktype == KG_TOK_WRAP_MSG)
- *(u16 *)(krb5_hdr + 4) = htons(ctx->sealalg);
- if (toktype == KG_TOK_WRAP_MSG) {
- /* XXX removing support for now */
- goto out_err;
- } else { /* Sign only. */
- if (make_checksum(checksum_type, krb5_hdr, 8, text,
- &md5cksum))
+ if (make_checksum(checksum_type, krb5_hdr, 8, text, 0, &md5cksum))
goto out_err;
- }
switch (ctx->signalg) {
case SGN_ALG_DES_MAC_MD5:
@@ -171,6 +143,6 @@ krb5_make_token(struct krb5_ctx *ctx, int qop_req,
return ((ctx->endtime < now) ? GSS_S_CONTEXT_EXPIRED : GSS_S_COMPLETE);
out_err:
- if (md5cksum.data) kfree(md5cksum.data);
+ kfree(md5cksum.data);
return GSS_S_FAILURE;
}
diff --git a/net/sunrpc/auth_gss/gss_krb5_unseal.c b/net/sunrpc/auth_gss/gss_krb5_unseal.c
index 8767fc53183d..db055fd7d778 100644
--- a/net/sunrpc/auth_gss/gss_krb5_unseal.c
+++ b/net/sunrpc/auth_gss/gss_krb5_unseal.c
@@ -68,21 +68,14 @@
#endif
-/* message_buffer is an input if toktype is MIC and an output if it is WRAP:
- * If toktype is MIC: read_token is a mic token, and message_buffer is the
- * data that the mic was supposedly taken over.
- * If toktype is WRAP: read_token is a wrap token, and message_buffer is used
- * to return the decrypted data.
- */
+/* read_token is a mic token, and message_buffer is the data that the mic was
+ * supposedly taken over. */
-/* XXX will need to change prototype and/or just split into a separate function
- * when we add privacy (because read_token will be in pages too). */
u32
-krb5_read_token(struct krb5_ctx *ctx,
- struct xdr_netobj *read_token,
- struct xdr_buf *message_buffer,
- int *qop_state, int toktype)
+gss_verify_mic_kerberos(struct gss_ctx *gss_ctx,
+ struct xdr_buf *message_buffer, struct xdr_netobj *read_token)
{
+ struct krb5_ctx *ctx = gss_ctx->internal_ctx_id;
int signalg;
int sealalg;
s32 checksum_type;
@@ -100,16 +93,12 @@ krb5_read_token(struct krb5_ctx *ctx,
read_token->len))
goto out;
- if ((*ptr++ != ((toktype>>8)&0xff)) || (*ptr++ != (toktype&0xff)))
+ if ((*ptr++ != ((KG_TOK_MIC_MSG>>8)&0xff)) ||
+ (*ptr++ != ( KG_TOK_MIC_MSG &0xff)) )
goto out;
/* XXX sanity-check bodysize?? */
- if (toktype == KG_TOK_WRAP_MSG) {
- /* XXX gone */
- goto out;
- }
-
/* get the sign and seal algorithms */
signalg = ptr[0] + (ptr[1] << 8);
@@ -120,14 +109,7 @@ krb5_read_token(struct krb5_ctx *ctx,
if ((ptr[4] != 0xff) || (ptr[5] != 0xff))
goto out;
- if (((toktype != KG_TOK_WRAP_MSG) && (sealalg != 0xffff)) ||
- ((toktype == KG_TOK_WRAP_MSG) && (sealalg == 0xffff)))
- goto out;
-
- /* in the current spec, there is only one valid seal algorithm per
- key type, so a simple comparison is ok */
-
- if ((toktype == KG_TOK_WRAP_MSG) && !(sealalg == ctx->sealalg))
+ if (sealalg != 0xffff)
goto out;
/* there are several mappings of seal algorithms to sign algorithms,
@@ -154,7 +136,7 @@ krb5_read_token(struct krb5_ctx *ctx,
switch (signalg) {
case SGN_ALG_DES_MAC_MD5:
ret = make_checksum(checksum_type, ptr - 2, 8,
- message_buffer, &md5cksum);
+ message_buffer, 0, &md5cksum);
if (ret)
goto out;
@@ -175,9 +157,6 @@ krb5_read_token(struct krb5_ctx *ctx,
/* it got through unscathed. Make sure the context is unexpired */
- if (qop_state)
- *qop_state = GSS_C_QOP_DEFAULT;
-
now = get_seconds();
ret = GSS_S_CONTEXT_EXPIRED;
@@ -197,6 +176,6 @@ krb5_read_token(struct krb5_ctx *ctx,
ret = GSS_S_COMPLETE;
out:
- if (md5cksum.data) kfree(md5cksum.data);
+ kfree(md5cksum.data);
return ret;
}
diff --git a/net/sunrpc/auth_gss/gss_krb5_wrap.c b/net/sunrpc/auth_gss/gss_krb5_wrap.c
new file mode 100644
index 000000000000..af777cf9f251
--- /dev/null
+++ b/net/sunrpc/auth_gss/gss_krb5_wrap.c
@@ -0,0 +1,363 @@
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/jiffies.h>
+#include <linux/sunrpc/gss_krb5.h>
+#include <linux/random.h>
+#include <linux/pagemap.h>
+#include <asm/scatterlist.h>
+#include <linux/crypto.h>
+
+#ifdef RPC_DEBUG
+# define RPCDBG_FACILITY RPCDBG_AUTH
+#endif
+
+static inline int
+gss_krb5_padding(int blocksize, int length)
+{
+ /* Most of the code is block-size independent but currently we
+ * use only 8: */
+ BUG_ON(blocksize != 8);
+ return 8 - (length & 7);
+}
+
+static inline void
+gss_krb5_add_padding(struct xdr_buf *buf, int offset, int blocksize)
+{
+ int padding = gss_krb5_padding(blocksize, buf->len - offset);
+ char *p;
+ struct kvec *iov;
+
+ if (buf->page_len || buf->tail[0].iov_len)
+ iov = &buf->tail[0];
+ else
+ iov = &buf->head[0];
+ p = iov->iov_base + iov->iov_len;
+ iov->iov_len += padding;
+ buf->len += padding;
+ memset(p, padding, padding);
+}
+
+static inline int
+gss_krb5_remove_padding(struct xdr_buf *buf, int blocksize)
+{
+ u8 *ptr;
+ u8 pad;
+ int len = buf->len;
+
+ if (len <= buf->head[0].iov_len) {
+ pad = *(u8 *)(buf->head[0].iov_base + len - 1);
+ if (pad > buf->head[0].iov_len)
+ return -EINVAL;
+ buf->head[0].iov_len -= pad;
+ goto out;
+ } else
+ len -= buf->head[0].iov_len;
+ if (len <= buf->page_len) {
+ int last = (buf->page_base + len - 1)
+ >>PAGE_CACHE_SHIFT;
+ int offset = (buf->page_base + len - 1)
+ & (PAGE_CACHE_SIZE - 1);
+ ptr = kmap_atomic(buf->pages[last], KM_SKB_SUNRPC_DATA);
+ pad = *(ptr + offset);
+ kunmap_atomic(ptr, KM_SKB_SUNRPC_DATA);
+ goto out;
+ } else
+ len -= buf->page_len;
+ BUG_ON(len > buf->tail[0].iov_len);
+ pad = *(u8 *)(buf->tail[0].iov_base + len - 1);
+out:
+ /* XXX: NOTE: we do not adjust the page lengths--they represent
+ * a range of data in the real filesystem page cache, and we need
+ * to know that range so the xdr code can properly place read data.
+ * However adjusting the head length, as we do above, is harmless.
+ * In the case of a request that fits into a single page, the server
+ * also uses length and head length together to determine the original
+ * start of the request to copy the request for deferal; so it's
+ * easier on the server if we adjust head and tail length in tandem.
+ * It's not really a problem that we don't fool with the page and
+ * tail lengths, though--at worst badly formed xdr might lead the
+ * server to attempt to parse the padding.
+ * XXX: Document all these weird requirements for gss mechanism
+ * wrap/unwrap functions. */
+ if (pad > blocksize)
+ return -EINVAL;
+ if (buf->len > pad)
+ buf->len -= pad;
+ else
+ return -EINVAL;
+ return 0;
+}
+
+static inline void
+make_confounder(char *p, int blocksize)
+{
+ static u64 i = 0;
+ u64 *q = (u64 *)p;
+
+ /* rfc1964 claims this should be "random". But all that's really
+ * necessary is that it be unique. And not even that is necessary in
+ * our case since our "gssapi" implementation exists only to support
+ * rpcsec_gss, so we know that the only buffers we will ever encrypt
+ * already begin with a unique sequence number. Just to hedge my bets
+ * I'll make a half-hearted attempt at something unique, but ensuring
+ * uniqueness would mean worrying about atomicity and rollover, and I
+ * don't care enough. */
+
+ BUG_ON(blocksize != 8);
+ *q = i++;
+}
+
+/* Assumptions: the head and tail of inbuf are ours to play with.
+ * The pages, however, may be real pages in the page cache and we replace
+ * them with scratch pages from **pages before writing to them. */
+/* XXX: obviously the above should be documentation of wrap interface,
+ * and shouldn't be in this kerberos-specific file. */
+
+/* XXX factor out common code with seal/unseal. */
+
+u32
+gss_wrap_kerberos(struct gss_ctx *ctx, int offset,
+ struct xdr_buf *buf, struct page **pages)
+{
+ struct krb5_ctx *kctx = ctx->internal_ctx_id;
+ s32 checksum_type;
+ struct xdr_netobj md5cksum = {.len = 0, .data = NULL};
+ int blocksize = 0, plainlen;
+ unsigned char *ptr, *krb5_hdr, *msg_start;
+ s32 now;
+ int headlen;
+ struct page **tmp_pages;
+
+ dprintk("RPC: gss_wrap_kerberos\n");
+
+ now = get_seconds();
+
+ switch (kctx->signalg) {
+ case SGN_ALG_DES_MAC_MD5:
+ checksum_type = CKSUMTYPE_RSA_MD5;
+ break;
+ default:
+ dprintk("RPC: gss_krb5_seal: kctx->signalg %d not"
+ " supported\n", kctx->signalg);
+ goto out_err;
+ }
+ if (kctx->sealalg != SEAL_ALG_NONE && kctx->sealalg != SEAL_ALG_DES) {
+ dprintk("RPC: gss_krb5_seal: kctx->sealalg %d not supported\n",
+ kctx->sealalg);
+ goto out_err;
+ }
+
+ blocksize = crypto_tfm_alg_blocksize(kctx->enc);
+ gss_krb5_add_padding(buf, offset, blocksize);
+ BUG_ON((buf->len - offset) % blocksize);
+ plainlen = blocksize + buf->len - offset;
+
+ headlen = g_token_size(&kctx->mech_used, 22 + plainlen) -
+ (buf->len - offset);
+
+ ptr = buf->head[0].iov_base + offset;
+ /* shift data to make room for header. */
+ /* XXX Would be cleverer to encrypt while copying. */
+ /* XXX bounds checking, slack, etc. */
+ memmove(ptr + headlen, ptr, buf->head[0].iov_len - offset);
+ buf->head[0].iov_len += headlen;
+ buf->len += headlen;
+ BUG_ON((buf->len - offset - headlen) % blocksize);
+
+ g_make_token_header(&kctx->mech_used, 22 + plainlen, &ptr);
+
+
+ *ptr++ = (unsigned char) ((KG_TOK_WRAP_MSG>>8)&0xff);
+ *ptr++ = (unsigned char) (KG_TOK_WRAP_MSG&0xff);
+
+ /* ptr now at byte 2 of header described in rfc 1964, section 1.2.1: */
+ krb5_hdr = ptr - 2;
+ msg_start = krb5_hdr + 24;
+ /* XXXJBF: */ BUG_ON(buf->head[0].iov_base + offset + headlen != msg_start + blocksize);
+
+ *(u16 *)(krb5_hdr + 2) = htons(kctx->signalg);
+ memset(krb5_hdr + 4, 0xff, 4);
+ *(u16 *)(krb5_hdr + 4) = htons(kctx->sealalg);
+
+ make_confounder(msg_start, blocksize);
+
+ /* XXXJBF: UGH!: */
+ tmp_pages = buf->pages;
+ buf->pages = pages;
+ if (make_checksum(checksum_type, krb5_hdr, 8, buf,
+ offset + headlen - blocksize, &md5cksum))
+ goto out_err;
+ buf->pages = tmp_pages;
+
+ switch (kctx->signalg) {
+ case SGN_ALG_DES_MAC_MD5:
+ if (krb5_encrypt(kctx->seq, NULL, md5cksum.data,
+ md5cksum.data, md5cksum.len))
+ goto out_err;
+ memcpy(krb5_hdr + 16,
+ md5cksum.data + md5cksum.len - KRB5_CKSUM_LENGTH,
+ KRB5_CKSUM_LENGTH);
+
+ dprintk("RPC: make_seal_token: cksum data: \n");
+ print_hexl((u32 *) (krb5_hdr + 16), KRB5_CKSUM_LENGTH, 0);
+ break;
+ default:
+ BUG();
+ }
+
+ kfree(md5cksum.data);
+
+ /* XXX would probably be more efficient to compute checksum
+ * and encrypt at the same time: */
+ if ((krb5_make_seq_num(kctx->seq, kctx->initiate ? 0 : 0xff,
+ kctx->seq_send, krb5_hdr + 16, krb5_hdr + 8)))
+ goto out_err;
+
+ if (gss_encrypt_xdr_buf(kctx->enc, buf, offset + headlen - blocksize,
+ pages))
+ goto out_err;
+
+ kctx->seq_send++;
+
+ return ((kctx->endtime < now) ? GSS_S_CONTEXT_EXPIRED : GSS_S_COMPLETE);
+out_err:
+ if (md5cksum.data) kfree(md5cksum.data);
+ return GSS_S_FAILURE;
+}
+
+u32
+gss_unwrap_kerberos(struct gss_ctx *ctx, int offset, struct xdr_buf *buf)
+{
+ struct krb5_ctx *kctx = ctx->internal_ctx_id;
+ int signalg;
+ int sealalg;
+ s32 checksum_type;
+ struct xdr_netobj md5cksum = {.len = 0, .data = NULL};
+ s32 now;
+ int direction;
+ s32 seqnum;
+ unsigned char *ptr;
+ int bodysize;
+ u32 ret = GSS_S_DEFECTIVE_TOKEN;
+ void *data_start, *orig_start;
+ int data_len;
+ int blocksize;
+
+ dprintk("RPC: gss_unwrap_kerberos\n");
+
+ ptr = (u8 *)buf->head[0].iov_base + offset;
+ if (g_verify_token_header(&kctx->mech_used, &bodysize, &ptr,
+ buf->len - offset))
+ goto out;
+
+ if ((*ptr++ != ((KG_TOK_WRAP_MSG>>8)&0xff)) ||
+ (*ptr++ != (KG_TOK_WRAP_MSG &0xff)) )
+ goto out;
+
+ /* XXX sanity-check bodysize?? */
+
+ /* get the sign and seal algorithms */
+
+ signalg = ptr[0] + (ptr[1] << 8);
+ sealalg = ptr[2] + (ptr[3] << 8);
+
+ /* Sanity checks */
+
+ if ((ptr[4] != 0xff) || (ptr[5] != 0xff))
+ goto out;
+
+ if (sealalg == 0xffff)
+ goto out;
+
+ /* in the current spec, there is only one valid seal algorithm per
+ key type, so a simple comparison is ok */
+
+ if (sealalg != kctx->sealalg)
+ goto out;
+
+ /* there are several mappings of seal algorithms to sign algorithms,
+ but few enough that we can try them all. */
+
+ if ((kctx->sealalg == SEAL_ALG_NONE && signalg > 1) ||
+ (kctx->sealalg == SEAL_ALG_1 && signalg != SGN_ALG_3) ||
+ (kctx->sealalg == SEAL_ALG_DES3KD &&
+ signalg != SGN_ALG_HMAC_SHA1_DES3_KD))
+ goto out;
+
+ if (gss_decrypt_xdr_buf(kctx->enc, buf,
+ ptr + 22 - (unsigned char *)buf->head[0].iov_base))
+ goto out;
+
+ /* compute the checksum of the message */
+
+ /* initialize the the cksum */
+ switch (signalg) {
+ case SGN_ALG_DES_MAC_MD5:
+ checksum_type = CKSUMTYPE_RSA_MD5;
+ break;
+ default:
+ ret = GSS_S_DEFECTIVE_TOKEN;
+ goto out;
+ }
+
+ switch (signalg) {
+ case SGN_ALG_DES_MAC_MD5:
+ ret = make_checksum(checksum_type, ptr - 2, 8, buf,
+ ptr + 22 - (unsigned char *)buf->head[0].iov_base, &md5cksum);
+ if (ret)
+ goto out;
+
+ ret = krb5_encrypt(kctx->seq, NULL, md5cksum.data,
+ md5cksum.data, md5cksum.len);
+ if (ret)
+ goto out;
+
+ if (memcmp(md5cksum.data + 8, ptr + 14, 8)) {
+ ret = GSS_S_BAD_SIG;
+ goto out;
+ }
+ break;
+ default:
+ ret = GSS_S_DEFECTIVE_TOKEN;
+ goto out;
+ }
+
+ /* it got through unscathed. Make sure the context is unexpired */
+
+ now = get_seconds();
+
+ ret = GSS_S_CONTEXT_EXPIRED;
+ if (now > kctx->endtime)
+ goto out;
+
+ /* do sequencing checks */
+
+ ret = GSS_S_BAD_SIG;
+ if ((ret = krb5_get_seq_num(kctx->seq, ptr + 14, ptr + 6, &direction,
+ &seqnum)))
+ goto out;
+
+ if ((kctx->initiate && direction != 0xff) ||
+ (!kctx->initiate && direction != 0))
+ goto out;
+
+ /* Copy the data back to the right position. XXX: Would probably be
+ * better to copy and encrypt at the same time. */
+
+ blocksize = crypto_tfm_alg_blocksize(kctx->enc);
+ data_start = ptr + 22 + blocksize;
+ orig_start = buf->head[0].iov_base + offset;
+ data_len = (buf->head[0].iov_base + buf->head[0].iov_len) - data_start;
+ memmove(orig_start, data_start, data_len);
+ buf->head[0].iov_len -= (data_start - orig_start);
+ buf->len -= (data_start - orig_start);
+
+ ret = GSS_S_DEFECTIVE_TOKEN;
+ if (gss_krb5_remove_padding(buf, blocksize))
+ goto out;
+
+ ret = GSS_S_COMPLETE;
+out:
+ if (md5cksum.data) kfree(md5cksum.data);
+ return ret;
+}
diff --git a/net/sunrpc/auth_gss/gss_mech_switch.c b/net/sunrpc/auth_gss/gss_mech_switch.c
index 9dfb68377d69..f8bac6ccd524 100644
--- a/net/sunrpc/auth_gss/gss_mech_switch.c
+++ b/net/sunrpc/auth_gss/gss_mech_switch.c
@@ -35,7 +35,6 @@
#include <linux/types.h>
#include <linux/slab.h>
-#include <linux/socket.h>
#include <linux/module.h>
#include <linux/sunrpc/msg_prot.h>
#include <linux/sunrpc/gss_asn1.h>
@@ -61,8 +60,7 @@ gss_mech_free(struct gss_api_mech *gm)
for (i = 0; i < gm->gm_pf_num; i++) {
pf = &gm->gm_pfs[i];
- if (pf->auth_domain_name)
- kfree(pf->auth_domain_name);
+ kfree(pf->auth_domain_name);
pf->auth_domain_name = NULL;
}
}
@@ -251,13 +249,11 @@ gss_import_sec_context(const void *input_token, size_t bufsize,
u32
gss_get_mic(struct gss_ctx *context_handle,
- u32 qop,
struct xdr_buf *message,
struct xdr_netobj *mic_token)
{
return context_handle->mech_type->gm_ops
->gss_get_mic(context_handle,
- qop,
message,
mic_token);
}
@@ -267,16 +263,34 @@ gss_get_mic(struct gss_ctx *context_handle,
u32
gss_verify_mic(struct gss_ctx *context_handle,
struct xdr_buf *message,
- struct xdr_netobj *mic_token,
- u32 *qstate)
+ struct xdr_netobj *mic_token)
{
return context_handle->mech_type->gm_ops
->gss_verify_mic(context_handle,
message,
- mic_token,
- qstate);
+ mic_token);
}
+u32
+gss_wrap(struct gss_ctx *ctx_id,
+ int offset,
+ struct xdr_buf *buf,
+ struct page **inpages)
+{
+ return ctx_id->mech_type->gm_ops
+ ->gss_wrap(ctx_id, offset, buf, inpages);
+}
+
+u32
+gss_unwrap(struct gss_ctx *ctx_id,
+ int offset,
+ struct xdr_buf *buf)
+{
+ return ctx_id->mech_type->gm_ops
+ ->gss_unwrap(ctx_id, offset, buf);
+}
+
+
/* gss_delete_sec_context: free all resources associated with context_handle.
* Note this differs from the RFC 2744-specified prototype in that we don't
* bother returning an output token, since it would never be used anyway. */
diff --git a/net/sunrpc/auth_gss/gss_spkm3_mech.c b/net/sunrpc/auth_gss/gss_spkm3_mech.c
index 6c97d61baa9b..39b3edc14694 100644
--- a/net/sunrpc/auth_gss/gss_spkm3_mech.c
+++ b/net/sunrpc/auth_gss/gss_spkm3_mech.c
@@ -224,18 +224,13 @@ gss_delete_sec_context_spkm3(void *internal_ctx) {
static u32
gss_verify_mic_spkm3(struct gss_ctx *ctx,
struct xdr_buf *signbuf,
- struct xdr_netobj *checksum,
- u32 *qstate) {
+ struct xdr_netobj *checksum)
+{
u32 maj_stat = 0;
- int qop_state = 0;
struct spkm3_ctx *sctx = ctx->internal_ctx_id;
dprintk("RPC: gss_verify_mic_spkm3 calling spkm3_read_token\n");
- maj_stat = spkm3_read_token(sctx, checksum, signbuf, &qop_state,
- SPKM_MIC_TOK);
-
- if (!maj_stat && qop_state)
- *qstate = qop_state;
+ maj_stat = spkm3_read_token(sctx, checksum, signbuf, SPKM_MIC_TOK);
dprintk("RPC: gss_verify_mic_spkm3 returning %d\n", maj_stat);
return maj_stat;
@@ -243,15 +238,15 @@ gss_verify_mic_spkm3(struct gss_ctx *ctx,
static u32
gss_get_mic_spkm3(struct gss_ctx *ctx,
- u32 qop,
struct xdr_buf *message_buffer,
- struct xdr_netobj *message_token) {
+ struct xdr_netobj *message_token)
+{
u32 err = 0;
struct spkm3_ctx *sctx = ctx->internal_ctx_id;
dprintk("RPC: gss_get_mic_spkm3\n");
- err = spkm3_make_token(sctx, qop, message_buffer,
+ err = spkm3_make_token(sctx, message_buffer,
message_token, SPKM_MIC_TOK);
return err;
}
@@ -264,8 +259,8 @@ static struct gss_api_ops gss_spkm3_ops = {
};
static struct pf_desc gss_spkm3_pfs[] = {
- {RPC_AUTH_GSS_SPKM, 0, RPC_GSS_SVC_NONE, "spkm3"},
- {RPC_AUTH_GSS_SPKMI, 0, RPC_GSS_SVC_INTEGRITY, "spkm3i"},
+ {RPC_AUTH_GSS_SPKM, RPC_GSS_SVC_NONE, "spkm3"},
+ {RPC_AUTH_GSS_SPKMI, RPC_GSS_SVC_INTEGRITY, "spkm3i"},
};
static struct gss_api_mech gss_spkm3_mech = {
diff --git a/net/sunrpc/auth_gss/gss_spkm3_seal.c b/net/sunrpc/auth_gss/gss_spkm3_seal.c
index 25339868d462..d1e12b25d6e2 100644
--- a/net/sunrpc/auth_gss/gss_spkm3_seal.c
+++ b/net/sunrpc/auth_gss/gss_spkm3_seal.c
@@ -51,7 +51,7 @@
*/
u32
-spkm3_make_token(struct spkm3_ctx *ctx, int qop_req,
+spkm3_make_token(struct spkm3_ctx *ctx,
struct xdr_buf * text, struct xdr_netobj * token,
int toktype)
{
@@ -68,8 +68,6 @@ spkm3_make_token(struct spkm3_ctx *ctx, int qop_req,
dprintk("RPC: spkm3_make_token\n");
now = jiffies;
- if (qop_req != 0)
- goto out_err;
if (ctx->ctx_id.len != 16) {
dprintk("RPC: spkm3_make_token BAD ctx_id.len %d\n",
@@ -124,8 +122,7 @@ spkm3_make_token(struct spkm3_ctx *ctx, int qop_req,
return GSS_S_COMPLETE;
out_err:
- if (md5cksum.data)
- kfree(md5cksum.data);
+ kfree(md5cksum.data);
token->data = NULL;
token->len = 0;
return GSS_S_FAILURE;
diff --git a/net/sunrpc/auth_gss/gss_spkm3_token.c b/net/sunrpc/auth_gss/gss_spkm3_token.c
index 46c08a0710f6..1f824578d773 100644
--- a/net/sunrpc/auth_gss/gss_spkm3_token.c
+++ b/net/sunrpc/auth_gss/gss_spkm3_token.c
@@ -259,8 +259,7 @@ spkm3_verify_mic_token(unsigned char **tokp, int *mic_hdrlen, unsigned char **ck
ret = GSS_S_COMPLETE;
out:
- if (spkm3_ctx_id.data)
- kfree(spkm3_ctx_id.data);
+ kfree(spkm3_ctx_id.data);
return ret;
}
diff --git a/net/sunrpc/auth_gss/gss_spkm3_unseal.c b/net/sunrpc/auth_gss/gss_spkm3_unseal.c
index 65ce81bf0bc4..241d5b30dfcb 100644
--- a/net/sunrpc/auth_gss/gss_spkm3_unseal.c
+++ b/net/sunrpc/auth_gss/gss_spkm3_unseal.c
@@ -52,7 +52,7 @@ u32
spkm3_read_token(struct spkm3_ctx *ctx,
struct xdr_netobj *read_token, /* checksum */
struct xdr_buf *message_buffer, /* signbuf */
- int *qop_state, int toktype)
+ int toktype)
{
s32 code;
struct xdr_netobj wire_cksum = {.len =0, .data = NULL};
@@ -120,9 +120,7 @@ spkm3_read_token(struct spkm3_ctx *ctx,
/* XXX: need to add expiration and sequencing */
ret = GSS_S_COMPLETE;
out:
- if (md5cksum.data)
- kfree(md5cksum.data);
- if (wire_cksum.data)
- kfree(wire_cksum.data);
+ kfree(md5cksum.data);
+ kfree(wire_cksum.data);
return ret;
}
diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c
index e3308195374e..e4ada15ed856 100644
--- a/net/sunrpc/auth_gss/svcauth_gss.c
+++ b/net/sunrpc/auth_gss/svcauth_gss.c
@@ -566,8 +566,7 @@ gss_verify_header(struct svc_rqst *rqstp, struct rsc *rsci,
if (rqstp->rq_deferred) /* skip verification of revisited request */
return SVC_OK;
- if (gss_verify_mic(ctx_id, &rpchdr, &checksum, NULL)
- != GSS_S_COMPLETE) {
+ if (gss_verify_mic(ctx_id, &rpchdr, &checksum) != GSS_S_COMPLETE) {
*authp = rpcsec_gsserr_credproblem;
return SVC_DENIED;
}
@@ -604,7 +603,7 @@ gss_write_verf(struct svc_rqst *rqstp, struct gss_ctx *ctx_id, u32 seq)
xdr_buf_from_iov(&iov, &verf_data);
p = rqstp->rq_res.head->iov_base + rqstp->rq_res.head->iov_len;
mic.data = (u8 *)(p + 1);
- maj_stat = gss_get_mic(ctx_id, 0, &verf_data, &mic);
+ maj_stat = gss_get_mic(ctx_id, &verf_data, &mic);
if (maj_stat != GSS_S_COMPLETE)
return -1;
*p++ = htonl(mic.len);
@@ -710,7 +709,7 @@ unwrap_integ_data(struct xdr_buf *buf, u32 seq, struct gss_ctx *ctx)
goto out;
if (read_bytes_from_xdr_buf(buf, integ_len + 4, mic.data, mic.len))
goto out;
- maj_stat = gss_verify_mic(ctx, &integ_buf, &mic, NULL);
+ maj_stat = gss_verify_mic(ctx, &integ_buf, &mic);
if (maj_stat != GSS_S_COMPLETE)
goto out;
if (ntohl(svc_getu32(&buf->head[0])) != seq)
@@ -1012,7 +1011,7 @@ svcauth_gss_release(struct svc_rqst *rqstp)
resv = &resbuf->tail[0];
}
mic.data = (u8 *)resv->iov_base + resv->iov_len + 4;
- if (gss_get_mic(gsd->rsci->mechctx, 0, &integ_buf, &mic))
+ if (gss_get_mic(gsd->rsci->mechctx, &integ_buf, &mic))
goto out_err;
svc_putu32(resv, htonl(mic.len));
memset(mic.data + mic.len, 0,
diff --git a/net/sunrpc/auth_null.c b/net/sunrpc/auth_null.c
index 9b72d3abf823..f56767aaa927 100644
--- a/net/sunrpc/auth_null.c
+++ b/net/sunrpc/auth_null.c
@@ -7,9 +7,7 @@
*/
#include <linux/types.h>
-#include <linux/socket.h>
#include <linux/module.h>
-#include <linux/in.h>
#include <linux/utsname.h>
#include <linux/sunrpc/clnt.h>
#include <linux/sched.h>
diff --git a/net/sunrpc/auth_unix.c b/net/sunrpc/auth_unix.c
index 4ff297a9b15b..890fb5ea0dcb 100644
--- a/net/sunrpc/auth_unix.c
+++ b/net/sunrpc/auth_unix.c
@@ -9,8 +9,6 @@
#include <linux/types.h>
#include <linux/sched.h>
#include <linux/module.h>
-#include <linux/socket.h>
-#include <linux/in.h>
#include <linux/sunrpc/clnt.h>
#include <linux/sunrpc/auth.h>
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
index f17e6153b688..61c3abeaccae 100644
--- a/net/sunrpc/clnt.c
+++ b/net/sunrpc/clnt.c
@@ -1,5 +1,5 @@
/*
- * linux/net/sunrpc/rpcclnt.c
+ * linux/net/sunrpc/clnt.c
*
* This file contains the high-level RPC interface.
* It is modeled as a finite state machine to support both synchronous
@@ -27,7 +27,6 @@
#include <linux/types.h>
#include <linux/mm.h>
#include <linux/slab.h>
-#include <linux/in.h>
#include <linux/utsname.h>
#include <linux/sunrpc/clnt.h>
@@ -53,8 +52,10 @@ static void call_allocate(struct rpc_task *task);
static void call_encode(struct rpc_task *task);
static void call_decode(struct rpc_task *task);
static void call_bind(struct rpc_task *task);
+static void call_bind_status(struct rpc_task *task);
static void call_transmit(struct rpc_task *task);
static void call_status(struct rpc_task *task);
+static void call_transmit_status(struct rpc_task *task);
static void call_refresh(struct rpc_task *task);
static void call_refreshresult(struct rpc_task *task);
static void call_timeout(struct rpc_task *task);
@@ -517,15 +518,8 @@ void
rpc_setbufsize(struct rpc_clnt *clnt, unsigned int sndsize, unsigned int rcvsize)
{
struct rpc_xprt *xprt = clnt->cl_xprt;
-
- xprt->sndsize = 0;
- if (sndsize)
- xprt->sndsize = sndsize + RPC_SLACK_SPACE;
- xprt->rcvsize = 0;
- if (rcvsize)
- xprt->rcvsize = rcvsize + RPC_SLACK_SPACE;
- if (xprt_connected(xprt))
- xprt_sock_setbufsize(xprt);
+ if (xprt->ops->set_buffer_size)
+ xprt->ops->set_buffer_size(xprt, sndsize, rcvsize);
}
/*
@@ -679,19 +673,29 @@ call_allocate(struct rpc_task *task)
rpc_exit(task, -ERESTARTSYS);
}
+static inline int
+rpc_task_need_encode(struct rpc_task *task)
+{
+ return task->tk_rqstp->rq_snd_buf.len == 0;
+}
+
+static inline void
+rpc_task_force_reencode(struct rpc_task *task)
+{
+ task->tk_rqstp->rq_snd_buf.len = 0;
+}
+
/*
* 3. Encode arguments of an RPC call
*/
static void
call_encode(struct rpc_task *task)
{
- struct rpc_clnt *clnt = task->tk_client;
struct rpc_rqst *req = task->tk_rqstp;
struct xdr_buf *sndbuf = &req->rq_snd_buf;
struct xdr_buf *rcvbuf = &req->rq_rcv_buf;
unsigned int bufsiz;
kxdrproc_t encode;
- int status;
u32 *p;
dprintk("RPC: %4d call_encode (status %d)\n",
@@ -719,11 +723,15 @@ call_encode(struct rpc_task *task)
rpc_exit(task, -EIO);
return;
}
- if (encode && (status = rpcauth_wrap_req(task, encode, req, p,
- task->tk_msg.rpc_argp)) < 0) {
- printk(KERN_WARNING "%s: can't encode arguments: %d\n",
- clnt->cl_protname, -status);
- rpc_exit(task, status);
+ if (encode == NULL)
+ return;
+
+ task->tk_status = rpcauth_wrap_req(task, encode, req, p,
+ task->tk_msg.rpc_argp);
+ if (task->tk_status == -ENOMEM) {
+ /* XXX: Is this sane? */
+ rpc_delay(task, 3*HZ);
+ task->tk_status = -EAGAIN;
}
}
@@ -734,43 +742,95 @@ static void
call_bind(struct rpc_task *task)
{
struct rpc_clnt *clnt = task->tk_client;
- struct rpc_xprt *xprt = clnt->cl_xprt;
-
- dprintk("RPC: %4d call_bind xprt %p %s connected\n", task->tk_pid,
- xprt, (xprt_connected(xprt) ? "is" : "is not"));
- task->tk_action = (xprt_connected(xprt)) ? call_transmit : call_connect;
+ dprintk("RPC: %4d call_bind (status %d)\n",
+ task->tk_pid, task->tk_status);
+ task->tk_action = call_connect;
if (!clnt->cl_port) {
- task->tk_action = call_connect;
- task->tk_timeout = RPC_CONNECT_TIMEOUT;
+ task->tk_action = call_bind_status;
+ task->tk_timeout = task->tk_xprt->bind_timeout;
rpc_getport(task, clnt);
}
}
/*
- * 4a. Connect to the RPC server (TCP case)
+ * 4a. Sort out bind result
+ */
+static void
+call_bind_status(struct rpc_task *task)
+{
+ int status = -EACCES;
+
+ if (task->tk_status >= 0) {
+ dprintk("RPC: %4d call_bind_status (status %d)\n",
+ task->tk_pid, task->tk_status);
+ task->tk_status = 0;
+ task->tk_action = call_connect;
+ return;
+ }
+
+ switch (task->tk_status) {
+ case -EACCES:
+ dprintk("RPC: %4d remote rpcbind: RPC program/version unavailable\n",
+ task->tk_pid);
+ rpc_delay(task, 3*HZ);
+ goto retry_bind;
+ case -ETIMEDOUT:
+ dprintk("RPC: %4d rpcbind request timed out\n",
+ task->tk_pid);
+ if (RPC_IS_SOFT(task)) {
+ status = -EIO;
+ break;
+ }
+ goto retry_bind;
+ case -EPFNOSUPPORT:
+ dprintk("RPC: %4d remote rpcbind service unavailable\n",
+ task->tk_pid);
+ break;
+ case -EPROTONOSUPPORT:
+ dprintk("RPC: %4d remote rpcbind version 2 unavailable\n",
+ task->tk_pid);
+ break;
+ default:
+ dprintk("RPC: %4d unrecognized rpcbind error (%d)\n",
+ task->tk_pid, -task->tk_status);
+ status = -EIO;
+ break;
+ }
+
+ rpc_exit(task, status);
+ return;
+
+retry_bind:
+ task->tk_status = 0;
+ task->tk_action = call_bind;
+ return;
+}
+
+/*
+ * 4b. Connect to the RPC server
*/
static void
call_connect(struct rpc_task *task)
{
- struct rpc_clnt *clnt = task->tk_client;
+ struct rpc_xprt *xprt = task->tk_xprt;
- dprintk("RPC: %4d call_connect status %d\n",
- task->tk_pid, task->tk_status);
+ dprintk("RPC: %4d call_connect xprt %p %s connected\n",
+ task->tk_pid, xprt,
+ (xprt_connected(xprt) ? "is" : "is not"));
- if (xprt_connected(clnt->cl_xprt)) {
- task->tk_action = call_transmit;
- return;
+ task->tk_action = call_transmit;
+ if (!xprt_connected(xprt)) {
+ task->tk_action = call_connect_status;
+ if (task->tk_status < 0)
+ return;
+ xprt_connect(task);
}
- task->tk_action = call_connect_status;
- if (task->tk_status < 0)
- return;
- xprt_connect(task);
}
/*
- * 4b. Sort out connect result
+ * 4c. Sort out connect result
*/
static void
call_connect_status(struct rpc_task *task)
@@ -778,6 +838,9 @@ call_connect_status(struct rpc_task *task)
struct rpc_clnt *clnt = task->tk_client;
int status = task->tk_status;
+ dprintk("RPC: %5u call_connect_status (status %d)\n",
+ task->tk_pid, task->tk_status);
+
task->tk_status = 0;
if (status >= 0) {
clnt->cl_stats->netreconn++;
@@ -785,17 +848,19 @@ call_connect_status(struct rpc_task *task)
return;
}
- /* Something failed: we may have to rebind */
+ /* Something failed: remote service port may have changed */
if (clnt->cl_autobind)
clnt->cl_port = 0;
+
switch (status) {
case -ENOTCONN:
case -ETIMEDOUT:
case -EAGAIN:
- task->tk_action = (clnt->cl_port == 0) ? call_bind : call_connect;
+ task->tk_action = call_bind;
break;
default:
rpc_exit(task, -EIO);
+ break;
}
}
@@ -815,10 +880,14 @@ call_transmit(struct rpc_task *task)
if (task->tk_status != 0)
return;
/* Encode here so that rpcsec_gss can use correct sequence number. */
- if (!task->tk_rqstp->rq_bytes_sent)
+ if (rpc_task_need_encode(task)) {
+ task->tk_rqstp->rq_bytes_sent = 0;
call_encode(task);
- if (task->tk_status < 0)
- return;
+ /* Did the encode result in an error condition? */
+ if (task->tk_status != 0)
+ goto out_nosend;
+ }
+ task->tk_action = call_transmit_status;
xprt_transmit(task);
if (task->tk_status < 0)
return;
@@ -826,6 +895,11 @@ call_transmit(struct rpc_task *task)
task->tk_action = NULL;
rpc_wake_up_task(task);
}
+ return;
+out_nosend:
+ /* release socket write lock before attempting to handle error */
+ xprt_abort_transmit(task);
+ rpc_task_force_reencode(task);
}
/*
@@ -857,7 +931,6 @@ call_status(struct rpc_task *task)
break;
case -ECONNREFUSED:
case -ENOTCONN:
- req->rq_bytes_sent = 0;
if (clnt->cl_autobind)
clnt->cl_port = 0;
task->tk_action = call_bind;
@@ -879,7 +952,18 @@ call_status(struct rpc_task *task)
}
/*
- * 6a. Handle RPC timeout
+ * 6a. Handle transmission errors.
+ */
+static void
+call_transmit_status(struct rpc_task *task)
+{
+ if (task->tk_status != -EAGAIN)
+ rpc_task_force_reencode(task);
+ call_status(task);
+}
+
+/*
+ * 6b. Handle RPC timeout
* We do not release the request slot, so we keep using the
* same XID for all retransmits.
*/
@@ -1020,13 +1104,12 @@ static u32 *
call_header(struct rpc_task *task)
{
struct rpc_clnt *clnt = task->tk_client;
- struct rpc_xprt *xprt = clnt->cl_xprt;
struct rpc_rqst *req = task->tk_rqstp;
u32 *p = req->rq_svec[0].iov_base;
/* FIXME: check buffer size? */
- if (xprt->stream)
- *p++ = 0; /* fill in later */
+
+ p = xprt_skip_transport_header(task->tk_xprt, p);
*p++ = req->rq_xid; /* XID */
*p++ = htonl(RPC_CALL); /* CALL */
*p++ = htonl(RPC_VERSION); /* RPC version */
diff --git a/net/sunrpc/pmap_clnt.c b/net/sunrpc/pmap_clnt.c
index 4e81f2766923..a398575f94b8 100644
--- a/net/sunrpc/pmap_clnt.c
+++ b/net/sunrpc/pmap_clnt.c
@@ -26,7 +26,7 @@
#define PMAP_GETPORT 3
static struct rpc_procinfo pmap_procedures[];
-static struct rpc_clnt * pmap_create(char *, struct sockaddr_in *, int);
+static struct rpc_clnt * pmap_create(char *, struct sockaddr_in *, int, int);
static void pmap_getport_done(struct rpc_task *);
static struct rpc_program pmap_program;
static DEFINE_SPINLOCK(pmap_lock);
@@ -65,7 +65,7 @@ rpc_getport(struct rpc_task *task, struct rpc_clnt *clnt)
map->pm_binding = 1;
spin_unlock(&pmap_lock);
- pmap_clnt = pmap_create(clnt->cl_server, sap, map->pm_prot);
+ pmap_clnt = pmap_create(clnt->cl_server, sap, map->pm_prot, 0);
if (IS_ERR(pmap_clnt)) {
task->tk_status = PTR_ERR(pmap_clnt);
goto bailout;
@@ -112,7 +112,7 @@ rpc_getport_external(struct sockaddr_in *sin, __u32 prog, __u32 vers, int prot)
NIPQUAD(sin->sin_addr.s_addr), prog, vers, prot);
sprintf(hostname, "%u.%u.%u.%u", NIPQUAD(sin->sin_addr.s_addr));
- pmap_clnt = pmap_create(hostname, sin, prot);
+ pmap_clnt = pmap_create(hostname, sin, prot, 0);
if (IS_ERR(pmap_clnt))
return PTR_ERR(pmap_clnt);
@@ -171,7 +171,7 @@ rpc_register(u32 prog, u32 vers, int prot, unsigned short port, int *okay)
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
- pmap_clnt = pmap_create("localhost", &sin, IPPROTO_UDP);
+ pmap_clnt = pmap_create("localhost", &sin, IPPROTO_UDP, 1);
if (IS_ERR(pmap_clnt)) {
error = PTR_ERR(pmap_clnt);
dprintk("RPC: couldn't create pmap client. Error = %d\n", error);
@@ -198,7 +198,7 @@ rpc_register(u32 prog, u32 vers, int prot, unsigned short port, int *okay)
}
static struct rpc_clnt *
-pmap_create(char *hostname, struct sockaddr_in *srvaddr, int proto)
+pmap_create(char *hostname, struct sockaddr_in *srvaddr, int proto, int privileged)
{
struct rpc_xprt *xprt;
struct rpc_clnt *clnt;
@@ -208,6 +208,8 @@ pmap_create(char *hostname, struct sockaddr_in *srvaddr, int proto)
if (IS_ERR(xprt))
return (struct rpc_clnt *)xprt;
xprt->addr.sin_port = htons(RPC_PMAP_PORT);
+ if (!privileged)
+ xprt->resvport = 0;
/* printk("pmap: create clnt\n"); */
clnt = rpc_new_client(xprt, hostname,
diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c
index ded6c63f11ec..81e00a6c19de 100644
--- a/net/sunrpc/rpc_pipe.c
+++ b/net/sunrpc/rpc_pipe.c
@@ -76,25 +76,35 @@ int
rpc_queue_upcall(struct inode *inode, struct rpc_pipe_msg *msg)
{
struct rpc_inode *rpci = RPC_I(inode);
- int res = 0;
+ int res = -EPIPE;
down(&inode->i_sem);
+ if (rpci->ops == NULL)
+ goto out;
if (rpci->nreaders) {
list_add_tail(&msg->list, &rpci->pipe);
rpci->pipelen += msg->len;
+ res = 0;
} else if (rpci->flags & RPC_PIPE_WAIT_FOR_OPEN) {
if (list_empty(&rpci->pipe))
schedule_delayed_work(&rpci->queue_timeout,
RPC_UPCALL_TIMEOUT);
list_add_tail(&msg->list, &rpci->pipe);
rpci->pipelen += msg->len;
- } else
- res = -EPIPE;
+ res = 0;
+ }
+out:
up(&inode->i_sem);
wake_up(&rpci->waitq);
return res;
}
+static inline void
+rpc_inode_setowner(struct inode *inode, void *private)
+{
+ RPC_I(inode)->private = private;
+}
+
static void
rpc_close_pipes(struct inode *inode)
{
@@ -111,15 +121,10 @@ rpc_close_pipes(struct inode *inode)
rpci->ops->release_pipe(inode);
rpci->ops = NULL;
}
+ rpc_inode_setowner(inode, NULL);
up(&inode->i_sem);
}
-static inline void
-rpc_inode_setowner(struct inode *inode, void *private)
-{
- RPC_I(inode)->private = private;
-}
-
static struct inode *
rpc_alloc_inode(struct super_block *sb)
{
@@ -501,7 +506,6 @@ repeat:
dentry = dvec[--n];
if (dentry->d_inode) {
rpc_close_pipes(dentry->d_inode);
- rpc_inode_setowner(dentry->d_inode, NULL);
simple_unlink(dir, dentry);
}
dput(dentry);
@@ -576,10 +580,8 @@ __rpc_rmdir(struct inode *dir, struct dentry *dentry)
int error;
shrink_dcache_parent(dentry);
- if (dentry->d_inode) {
+ if (dentry->d_inode)
rpc_close_pipes(dentry->d_inode);
- rpc_inode_setowner(dentry->d_inode, NULL);
- }
if ((error = simple_rmdir(dir, dentry)) != 0)
return error;
if (!error) {
@@ -601,7 +603,7 @@ rpc_lookup_negative(char *path, struct nameidata *nd)
return ERR_PTR(error);
dir = nd->dentry->d_inode;
down(&dir->i_sem);
- dentry = lookup_hash(&nd->last, nd->dentry);
+ dentry = lookup_hash(nd);
if (IS_ERR(dentry))
goto out_err;
if (dentry->d_inode) {
@@ -663,7 +665,7 @@ rpc_rmdir(char *path)
return error;
dir = nd.dentry->d_inode;
down(&dir->i_sem);
- dentry = lookup_hash(&nd.last, nd.dentry);
+ dentry = lookup_hash(&nd);
if (IS_ERR(dentry)) {
error = PTR_ERR(dentry);
goto out_release;
@@ -724,7 +726,7 @@ rpc_unlink(char *path)
return error;
dir = nd.dentry->d_inode;
down(&dir->i_sem);
- dentry = lookup_hash(&nd.last, nd.dentry);
+ dentry = lookup_hash(&nd);
if (IS_ERR(dentry)) {
error = PTR_ERR(dentry);
goto out_release;
@@ -732,7 +734,6 @@ rpc_unlink(char *path)
d_drop(dentry);
if (dentry->d_inode) {
rpc_close_pipes(dentry->d_inode);
- rpc_inode_setowner(dentry->d_inode, NULL);
error = simple_unlink(dir, dentry);
}
dput(dentry);
diff --git a/net/sunrpc/socklib.c b/net/sunrpc/socklib.c
new file mode 100644
index 000000000000..eb330d4f66d6
--- /dev/null
+++ b/net/sunrpc/socklib.c
@@ -0,0 +1,180 @@
+/*
+ * linux/net/sunrpc/socklib.c
+ *
+ * Common socket helper routines for RPC client and server
+ *
+ * Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de>
+ */
+
+#include <linux/compiler.h>
+#include <linux/netdevice.h>
+#include <linux/skbuff.h>
+#include <linux/types.h>
+#include <linux/pagemap.h>
+#include <linux/udp.h>
+#include <linux/sunrpc/xdr.h>
+
+
+/**
+ * skb_read_bits - copy some data bits from skb to internal buffer
+ * @desc: sk_buff copy helper
+ * @to: copy destination
+ * @len: number of bytes to copy
+ *
+ * Possibly called several times to iterate over an sk_buff and copy
+ * data out of it.
+ */
+static size_t skb_read_bits(skb_reader_t *desc, void *to, size_t len)
+{
+ if (len > desc->count)
+ len = desc->count;
+ if (skb_copy_bits(desc->skb, desc->offset, to, len))
+ return 0;
+ desc->count -= len;
+ desc->offset += len;
+ return len;
+}
+
+/**
+ * skb_read_and_csum_bits - copy and checksum from skb to buffer
+ * @desc: sk_buff copy helper
+ * @to: copy destination
+ * @len: number of bytes to copy
+ *
+ * Same as skb_read_bits, but calculate a checksum at the same time.
+ */
+static size_t skb_read_and_csum_bits(skb_reader_t *desc, void *to, size_t len)
+{
+ unsigned int csum2, pos;
+
+ if (len > desc->count)
+ len = desc->count;
+ pos = desc->offset;
+ csum2 = skb_copy_and_csum_bits(desc->skb, pos, to, len, 0);
+ desc->csum = csum_block_add(desc->csum, csum2, pos);
+ desc->count -= len;
+ desc->offset += len;
+ return len;
+}
+
+/**
+ * xdr_partial_copy_from_skb - copy data out of an skb
+ * @xdr: target XDR buffer
+ * @base: starting offset
+ * @desc: sk_buff copy helper
+ * @copy_actor: virtual method for copying data
+ *
+ */
+ssize_t xdr_partial_copy_from_skb(struct xdr_buf *xdr, unsigned int base, skb_reader_t *desc, skb_read_actor_t copy_actor)
+{
+ struct page **ppage = xdr->pages;
+ unsigned int len, pglen = xdr->page_len;
+ ssize_t copied = 0;
+ int ret;
+
+ len = xdr->head[0].iov_len;
+ if (base < len) {
+ len -= base;
+ ret = copy_actor(desc, (char *)xdr->head[0].iov_base + base, len);
+ copied += ret;
+ if (ret != len || !desc->count)
+ goto out;
+ base = 0;
+ } else
+ base -= len;
+
+ if (unlikely(pglen == 0))
+ goto copy_tail;
+ if (unlikely(base >= pglen)) {
+ base -= pglen;
+ goto copy_tail;
+ }
+ if (base || xdr->page_base) {
+ pglen -= base;
+ base += xdr->page_base;
+ ppage += base >> PAGE_CACHE_SHIFT;
+ base &= ~PAGE_CACHE_MASK;
+ }
+ do {
+ char *kaddr;
+
+ /* ACL likes to be lazy in allocating pages - ACLs
+ * are small by default but can get huge. */
+ if (unlikely(*ppage == NULL)) {
+ *ppage = alloc_page(GFP_ATOMIC);
+ if (unlikely(*ppage == NULL)) {
+ if (copied == 0)
+ copied = -ENOMEM;
+ goto out;
+ }
+ }
+
+ len = PAGE_CACHE_SIZE;
+ kaddr = kmap_atomic(*ppage, KM_SKB_SUNRPC_DATA);
+ if (base) {
+ len -= base;
+ if (pglen < len)
+ len = pglen;
+ ret = copy_actor(desc, kaddr + base, len);
+ base = 0;
+ } else {
+ if (pglen < len)
+ len = pglen;
+ ret = copy_actor(desc, kaddr, len);
+ }
+ flush_dcache_page(*ppage);
+ kunmap_atomic(kaddr, KM_SKB_SUNRPC_DATA);
+ copied += ret;
+ if (ret != len || !desc->count)
+ goto out;
+ ppage++;
+ } while ((pglen -= len) != 0);
+copy_tail:
+ len = xdr->tail[0].iov_len;
+ if (base < len)
+ copied += copy_actor(desc, (char *)xdr->tail[0].iov_base + base, len - base);
+out:
+ return copied;
+}
+
+/**
+ * csum_partial_copy_to_xdr - checksum and copy data
+ * @xdr: target XDR buffer
+ * @skb: source skb
+ *
+ * We have set things up such that we perform the checksum of the UDP
+ * packet in parallel with the copies into the RPC client iovec. -DaveM
+ */
+int csum_partial_copy_to_xdr(struct xdr_buf *xdr, struct sk_buff *skb)
+{
+ skb_reader_t desc;
+
+ desc.skb = skb;
+ desc.offset = sizeof(struct udphdr);
+ desc.count = skb->len - desc.offset;
+
+ if (skb->ip_summed == CHECKSUM_UNNECESSARY)
+ goto no_checksum;
+
+ desc.csum = csum_partial(skb->data, desc.offset, skb->csum);
+ if (xdr_partial_copy_from_skb(xdr, 0, &desc, skb_read_and_csum_bits) < 0)
+ return -1;
+ if (desc.offset != skb->len) {
+ unsigned int csum2;
+ csum2 = skb_checksum(skb, desc.offset, skb->len - desc.offset, 0);
+ desc.csum = csum_block_add(desc.csum, csum2, desc.offset);
+ }
+ if (desc.count)
+ return -1;
+ if ((unsigned short)csum_fold(desc.csum))
+ return -1;
+ if (unlikely(skb->ip_summed == CHECKSUM_HW))
+ netdev_rx_csum_fault(skb->dev);
+ return 0;
+no_checksum:
+ if (xdr_partial_copy_from_skb(xdr, 0, &desc, skb_read_bits) < 0)
+ return -1;
+ if (desc.count)
+ return -1;
+ return 0;
+}
diff --git a/net/sunrpc/sunrpc_syms.c b/net/sunrpc/sunrpc_syms.c
index ed48ff022d35..a03d4b600c92 100644
--- a/net/sunrpc/sunrpc_syms.c
+++ b/net/sunrpc/sunrpc_syms.c
@@ -10,7 +10,6 @@
#include <linux/module.h>
#include <linux/types.h>
-#include <linux/socket.h>
#include <linux/sched.h>
#include <linux/uio.h>
#include <linux/unistd.h>
@@ -64,8 +63,6 @@ EXPORT_SYMBOL(rpc_mkpipe);
/* Client transport */
EXPORT_SYMBOL(xprt_create_proto);
EXPORT_SYMBOL(xprt_set_timeout);
-EXPORT_SYMBOL(xprt_udp_slot_table_entries);
-EXPORT_SYMBOL(xprt_tcp_slot_table_entries);
/* Client credential cache */
EXPORT_SYMBOL(rpcauth_register);
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c
index e9bd91265f70..e4296c8b861e 100644
--- a/net/sunrpc/svc.c
+++ b/net/sunrpc/svc.c
@@ -196,12 +196,9 @@ svc_exit_thread(struct svc_rqst *rqstp)
struct svc_serv *serv = rqstp->rq_server;
svc_release_buffer(rqstp);
- if (rqstp->rq_resp)
- kfree(rqstp->rq_resp);
- if (rqstp->rq_argp)
- kfree(rqstp->rq_argp);
- if (rqstp->rq_auth_data)
- kfree(rqstp->rq_auth_data);
+ kfree(rqstp->rq_resp);
+ kfree(rqstp->rq_argp);
+ kfree(rqstp->rq_auth_data);
kfree(rqstp);
/* Release the server */
@@ -313,6 +310,11 @@ svc_process(struct svc_serv *serv, struct svc_rqst *rqstp)
rqstp->rq_proc = proc = ntohl(svc_getu32(argv)); /* procedure number */
progp = serv->sv_program;
+
+ for (progp = serv->sv_program; progp; progp = progp->pg_next)
+ if (prog == progp->pg_prog)
+ break;
+
/*
* Decode auth data, and add verifier to reply buffer.
* We do this before anything else in order to get a decent
@@ -320,7 +322,7 @@ svc_process(struct svc_serv *serv, struct svc_rqst *rqstp)
*/
auth_res = svc_authenticate(rqstp, &auth_stat);
/* Also give the program a chance to reject this call: */
- if (auth_res == SVC_OK) {
+ if (auth_res == SVC_OK && progp) {
auth_stat = rpc_autherr_badcred;
auth_res = progp->pg_authenticate(rqstp);
}
@@ -340,10 +342,7 @@ svc_process(struct svc_serv *serv, struct svc_rqst *rqstp)
case SVC_COMPLETE:
goto sendit;
}
-
- for (progp = serv->sv_program; progp; progp = progp->pg_next)
- if (prog == progp->pg_prog)
- break;
+
if (progp == NULL)
goto err_bad_prog;
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
index 691dea4a58e7..e50e7cf43737 100644
--- a/net/sunrpc/svcsock.c
+++ b/net/sunrpc/svcsock.c
@@ -548,9 +548,6 @@ svc_write_space(struct sock *sk)
/*
* Receive a datagram from a UDP socket.
*/
-extern int
-csum_partial_copy_to_xdr(struct xdr_buf *xdr, struct sk_buff *skb);
-
static int
svc_udp_recvfrom(struct svc_rqst *rqstp)
{
@@ -626,12 +623,9 @@ svc_udp_recvfrom(struct svc_rqst *rqstp)
/* we can use it in-place */
rqstp->rq_arg.head[0].iov_base = skb->data + sizeof(struct udphdr);
rqstp->rq_arg.head[0].iov_len = len;
- if (skb->ip_summed != CHECKSUM_UNNECESSARY) {
- if ((unsigned short)csum_fold(skb_checksum(skb, 0, skb->len, skb->csum))) {
- skb_free_datagram(svsk->sk_sk, skb);
- return 0;
- }
- skb->ip_summed = CHECKSUM_UNNECESSARY;
+ if (skb_checksum_complete(skb)) {
+ skb_free_datagram(svsk->sk_sk, skb);
+ return 0;
}
rqstp->rq_skbuff = skb;
}
diff --git a/net/sunrpc/sysctl.c b/net/sunrpc/sysctl.c
index 1b9616a12e24..1065904841fd 100644
--- a/net/sunrpc/sysctl.c
+++ b/net/sunrpc/sysctl.c
@@ -119,8 +119,11 @@ done:
return 0;
}
+
static unsigned int min_slot_table_size = RPC_MIN_SLOT_TABLE;
static unsigned int max_slot_table_size = RPC_MAX_SLOT_TABLE;
+static unsigned int xprt_min_resvport_limit = RPC_MIN_RESVPORT;
+static unsigned int xprt_max_resvport_limit = RPC_MAX_RESVPORT;
static ctl_table debug_table[] = {
{
@@ -177,6 +180,28 @@ static ctl_table debug_table[] = {
.extra1 = &min_slot_table_size,
.extra2 = &max_slot_table_size
},
+ {
+ .ctl_name = CTL_MIN_RESVPORT,
+ .procname = "min_resvport",
+ .data = &xprt_min_resvport,
+ .maxlen = sizeof(unsigned int),
+ .mode = 0644,
+ .proc_handler = &proc_dointvec_minmax,
+ .strategy = &sysctl_intvec,
+ .extra1 = &xprt_min_resvport_limit,
+ .extra2 = &xprt_max_resvport_limit
+ },
+ {
+ .ctl_name = CTL_MAX_RESVPORT,
+ .procname = "max_resvport",
+ .data = &xprt_max_resvport,
+ .maxlen = sizeof(unsigned int),
+ .mode = 0644,
+ .proc_handler = &proc_dointvec_minmax,
+ .strategy = &sysctl_intvec,
+ .extra1 = &xprt_min_resvport_limit,
+ .extra2 = &xprt_max_resvport_limit
+ },
{ .ctl_name = 0 }
};
diff --git a/net/sunrpc/xdr.c b/net/sunrpc/xdr.c
index fde16f40a581..aaf08cdd19f0 100644
--- a/net/sunrpc/xdr.c
+++ b/net/sunrpc/xdr.c
@@ -6,15 +6,12 @@
* Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de>
*/
+#include <linux/module.h>
#include <linux/types.h>
-#include <linux/socket.h>
#include <linux/string.h>
#include <linux/kernel.h>
#include <linux/pagemap.h>
#include <linux/errno.h>
-#include <linux/in.h>
-#include <linux/net.h>
-#include <net/sock.h>
#include <linux/sunrpc/xdr.h>
#include <linux/sunrpc/msg_prot.h>
@@ -176,178 +173,6 @@ xdr_inline_pages(struct xdr_buf *xdr, unsigned int offset,
xdr->buflen += len;
}
-ssize_t
-xdr_partial_copy_from_skb(struct xdr_buf *xdr, unsigned int base,
- skb_reader_t *desc,
- skb_read_actor_t copy_actor)
-{
- struct page **ppage = xdr->pages;
- unsigned int len, pglen = xdr->page_len;
- ssize_t copied = 0;
- int ret;
-
- len = xdr->head[0].iov_len;
- if (base < len) {
- len -= base;
- ret = copy_actor(desc, (char *)xdr->head[0].iov_base + base, len);
- copied += ret;
- if (ret != len || !desc->count)
- goto out;
- base = 0;
- } else
- base -= len;
-
- if (pglen == 0)
- goto copy_tail;
- if (base >= pglen) {
- base -= pglen;
- goto copy_tail;
- }
- if (base || xdr->page_base) {
- pglen -= base;
- base += xdr->page_base;
- ppage += base >> PAGE_CACHE_SHIFT;
- base &= ~PAGE_CACHE_MASK;
- }
- do {
- char *kaddr;
-
- /* ACL likes to be lazy in allocating pages - ACLs
- * are small by default but can get huge. */
- if (unlikely(*ppage == NULL)) {
- *ppage = alloc_page(GFP_ATOMIC);
- if (unlikely(*ppage == NULL)) {
- if (copied == 0)
- copied = -ENOMEM;
- goto out;
- }
- }
-
- len = PAGE_CACHE_SIZE;
- kaddr = kmap_atomic(*ppage, KM_SKB_SUNRPC_DATA);
- if (base) {
- len -= base;
- if (pglen < len)
- len = pglen;
- ret = copy_actor(desc, kaddr + base, len);
- base = 0;
- } else {
- if (pglen < len)
- len = pglen;
- ret = copy_actor(desc, kaddr, len);
- }
- flush_dcache_page(*ppage);
- kunmap_atomic(kaddr, KM_SKB_SUNRPC_DATA);
- copied += ret;
- if (ret != len || !desc->count)
- goto out;
- ppage++;
- } while ((pglen -= len) != 0);
-copy_tail:
- len = xdr->tail[0].iov_len;
- if (base < len)
- copied += copy_actor(desc, (char *)xdr->tail[0].iov_base + base, len - base);
-out:
- return copied;
-}
-
-
-int
-xdr_sendpages(struct socket *sock, struct sockaddr *addr, int addrlen,
- struct xdr_buf *xdr, unsigned int base, int msgflags)
-{
- struct page **ppage = xdr->pages;
- unsigned int len, pglen = xdr->page_len;
- int err, ret = 0;
- ssize_t (*sendpage)(struct socket *, struct page *, int, size_t, int);
-
- len = xdr->head[0].iov_len;
- if (base < len || (addr != NULL && base == 0)) {
- struct kvec iov = {
- .iov_base = xdr->head[0].iov_base + base,
- .iov_len = len - base,
- };
- struct msghdr msg = {
- .msg_name = addr,
- .msg_namelen = addrlen,
- .msg_flags = msgflags,
- };
- if (xdr->len > len)
- msg.msg_flags |= MSG_MORE;
-
- if (iov.iov_len != 0)
- err = kernel_sendmsg(sock, &msg, &iov, 1, iov.iov_len);
- else
- err = kernel_sendmsg(sock, &msg, NULL, 0, 0);
- if (ret == 0)
- ret = err;
- else if (err > 0)
- ret += err;
- if (err != iov.iov_len)
- goto out;
- base = 0;
- } else
- base -= len;
-
- if (pglen == 0)
- goto copy_tail;
- if (base >= pglen) {
- base -= pglen;
- goto copy_tail;
- }
- if (base || xdr->page_base) {
- pglen -= base;
- base += xdr->page_base;
- ppage += base >> PAGE_CACHE_SHIFT;
- base &= ~PAGE_CACHE_MASK;
- }
-
- sendpage = sock->ops->sendpage ? : sock_no_sendpage;
- do {
- int flags = msgflags;
-
- len = PAGE_CACHE_SIZE;
- if (base)
- len -= base;
- if (pglen < len)
- len = pglen;
-
- if (pglen != len || xdr->tail[0].iov_len != 0)
- flags |= MSG_MORE;
-
- /* Hmm... We might be dealing with highmem pages */
- if (PageHighMem(*ppage))
- sendpage = sock_no_sendpage;
- err = sendpage(sock, *ppage, base, len, flags);
- if (ret == 0)
- ret = err;
- else if (err > 0)
- ret += err;
- if (err != len)
- goto out;
- base = 0;
- ppage++;
- } while ((pglen -= len) != 0);
-copy_tail:
- len = xdr->tail[0].iov_len;
- if (base < len) {
- struct kvec iov = {
- .iov_base = xdr->tail[0].iov_base + base,
- .iov_len = len - base,
- };
- struct msghdr msg = {
- .msg_flags = msgflags,
- };
- err = kernel_sendmsg(sock, &msg, &iov, 1, iov.iov_len);
- if (ret == 0)
- ret = err;
- else if (err > 0)
- ret += err;
- }
-out:
- return ret;
-}
-
/*
* Helper routines for doing 'memmove' like operations on a struct xdr_buf
@@ -1167,8 +992,7 @@ xdr_xcode_array2(struct xdr_buf *buf, unsigned int base,
err = 0;
out:
- if (elem)
- kfree(elem);
+ kfree(elem);
if (ppages)
kunmap(*ppages);
return err;
diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c
index 3c654e06b084..6dda3860351f 100644
--- a/net/sunrpc/xprt.c
+++ b/net/sunrpc/xprt.c
@@ -10,12 +10,12 @@
* one is available. Otherwise, it sleeps on the backlog queue
* (xprt_reserve).
* - Next, the caller puts together the RPC message, stuffs it into
- * the request struct, and calls xprt_call().
- * - xprt_call transmits the message and installs the caller on the
- * socket's wait list. At the same time, it installs a timer that
+ * the request struct, and calls xprt_transmit().
+ * - xprt_transmit sends the message and installs the caller on the
+ * transport's wait list. At the same time, it installs a timer that
* is run after the packet's timeout has expired.
* - When a packet arrives, the data_ready handler walks the list of
- * pending requests for that socket. If a matching XID is found, the
+ * pending requests for that transport. If a matching XID is found, the
* caller is woken up, and the timer removed.
* - When no reply arrives within the timeout interval, the timer is
* fired by the kernel and runs xprt_timer(). It either adjusts the
@@ -33,36 +33,17 @@
*
* Copyright (C) 1995-1997, Olaf Kirch <okir@monad.swb.de>
*
- * TCP callback races fixes (C) 1998 Red Hat Software <alan@redhat.com>
- * TCP send fixes (C) 1998 Red Hat Software <alan@redhat.com>
- * TCP NFS related read + write fixes
- * (C) 1999 Dave Airlie, University of Limerick, Ireland <airlied@linux.ie>
- *
- * Rewrite of larges part of the code in order to stabilize TCP stuff.
- * Fix behaviour when socket buffer is full.
- * (C) 1999 Trond Myklebust <trond.myklebust@fys.uio.no>
+ * Transport switch API copyright (C) 2005, Chuck Lever <cel@netapp.com>
*/
+#include <linux/module.h>
+
#include <linux/types.h>
-#include <linux/slab.h>
-#include <linux/capability.h>
-#include <linux/sched.h>
-#include <linux/errno.h>
-#include <linux/socket.h>
-#include <linux/in.h>
-#include <linux/net.h>
-#include <linux/mm.h>
-#include <linux/udp.h>
-#include <linux/tcp.h>
-#include <linux/sunrpc/clnt.h>
-#include <linux/file.h>
+#include <linux/interrupt.h>
#include <linux/workqueue.h>
#include <linux/random.h>
-#include <net/sock.h>
-#include <net/checksum.h>
-#include <net/udp.h>
-#include <net/tcp.h>
+#include <linux/sunrpc/clnt.h>
/*
* Local variables
@@ -73,81 +54,90 @@
# define RPCDBG_FACILITY RPCDBG_XPRT
#endif
-#define XPRT_MAX_BACKOFF (8)
-#define XPRT_IDLE_TIMEOUT (5*60*HZ)
-#define XPRT_MAX_RESVPORT (800)
-
/*
* Local functions
*/
static void xprt_request_init(struct rpc_task *, struct rpc_xprt *);
static inline void do_xprt_reserve(struct rpc_task *);
-static void xprt_disconnect(struct rpc_xprt *);
static void xprt_connect_status(struct rpc_task *task);
-static struct rpc_xprt * xprt_setup(int proto, struct sockaddr_in *ap,
- struct rpc_timeout *to);
-static struct socket *xprt_create_socket(struct rpc_xprt *, int, int);
-static void xprt_bind_socket(struct rpc_xprt *, struct socket *);
static int __xprt_get_cong(struct rpc_xprt *, struct rpc_task *);
-static int xprt_clear_backlog(struct rpc_xprt *xprt);
-
-#ifdef RPC_DEBUG_DATA
/*
- * Print the buffer contents (first 128 bytes only--just enough for
- * diropres return).
+ * The transport code maintains an estimate on the maximum number of out-
+ * standing RPC requests, using a smoothed version of the congestion
+ * avoidance implemented in 44BSD. This is basically the Van Jacobson
+ * congestion algorithm: If a retransmit occurs, the congestion window is
+ * halved; otherwise, it is incremented by 1/cwnd when
+ *
+ * - a reply is received and
+ * - a full number of requests are outstanding and
+ * - the congestion window hasn't been updated recently.
*/
-static void
-xprt_pktdump(char *msg, u32 *packet, unsigned int count)
-{
- u8 *buf = (u8 *) packet;
- int j;
-
- dprintk("RPC: %s\n", msg);
- for (j = 0; j < count && j < 128; j += 4) {
- if (!(j & 31)) {
- if (j)
- dprintk("\n");
- dprintk("0x%04x ", j);
- }
- dprintk("%02x%02x%02x%02x ",
- buf[j], buf[j+1], buf[j+2], buf[j+3]);
- }
- dprintk("\n");
-}
-#else
-static inline void
-xprt_pktdump(char *msg, u32 *packet, unsigned int count)
-{
- /* NOP */
-}
-#endif
+#define RPC_CWNDSHIFT (8U)
+#define RPC_CWNDSCALE (1U << RPC_CWNDSHIFT)
+#define RPC_INITCWND RPC_CWNDSCALE
+#define RPC_MAXCWND(xprt) ((xprt)->max_reqs << RPC_CWNDSHIFT)
-/*
- * Look up RPC transport given an INET socket
+#define RPCXPRT_CONGESTED(xprt) ((xprt)->cong >= (xprt)->cwnd)
+
+/**
+ * xprt_reserve_xprt - serialize write access to transports
+ * @task: task that is requesting access to the transport
+ *
+ * This prevents mixing the payload of separate requests, and prevents
+ * transport connects from colliding with writes. No congestion control
+ * is provided.
*/
-static inline struct rpc_xprt *
-xprt_from_sock(struct sock *sk)
+int xprt_reserve_xprt(struct rpc_task *task)
{
- return (struct rpc_xprt *) sk->sk_user_data;
+ struct rpc_xprt *xprt = task->tk_xprt;
+ struct rpc_rqst *req = task->tk_rqstp;
+
+ if (test_and_set_bit(XPRT_LOCKED, &xprt->state)) {
+ if (task == xprt->snd_task)
+ return 1;
+ if (task == NULL)
+ return 0;
+ goto out_sleep;
+ }
+ xprt->snd_task = task;
+ if (req) {
+ req->rq_bytes_sent = 0;
+ req->rq_ntrans++;
+ }
+ return 1;
+
+out_sleep:
+ dprintk("RPC: %4d failed to lock transport %p\n",
+ task->tk_pid, xprt);
+ task->tk_timeout = 0;
+ task->tk_status = -EAGAIN;
+ if (req && req->rq_ntrans)
+ rpc_sleep_on(&xprt->resend, task, NULL, NULL);
+ else
+ rpc_sleep_on(&xprt->sending, task, NULL, NULL);
+ return 0;
}
/*
- * Serialize write access to sockets, in order to prevent different
- * requests from interfering with each other.
- * Also prevents TCP socket connects from colliding with writes.
+ * xprt_reserve_xprt_cong - serialize write access to transports
+ * @task: task that is requesting access to the transport
+ *
+ * Same as xprt_reserve_xprt, but Van Jacobson congestion control is
+ * integrated into the decision of whether a request is allowed to be
+ * woken up and given access to the transport.
*/
-static int
-__xprt_lock_write(struct rpc_xprt *xprt, struct rpc_task *task)
+int xprt_reserve_xprt_cong(struct rpc_task *task)
{
+ struct rpc_xprt *xprt = task->tk_xprt;
struct rpc_rqst *req = task->tk_rqstp;
- if (test_and_set_bit(XPRT_LOCKED, &xprt->sockstate)) {
+ if (test_and_set_bit(XPRT_LOCKED, &xprt->state)) {
if (task == xprt->snd_task)
return 1;
goto out_sleep;
}
- if (xprt->nocong || __xprt_get_cong(xprt, task)) {
+ if (__xprt_get_cong(xprt, task)) {
xprt->snd_task = task;
if (req) {
req->rq_bytes_sent = 0;
@@ -156,10 +146,10 @@ __xprt_lock_write(struct rpc_xprt *xprt, struct rpc_task *task)
return 1;
}
smp_mb__before_clear_bit();
- clear_bit(XPRT_LOCKED, &xprt->sockstate);
+ clear_bit(XPRT_LOCKED, &xprt->state);
smp_mb__after_clear_bit();
out_sleep:
- dprintk("RPC: %4d failed to lock socket %p\n", task->tk_pid, xprt);
+ dprintk("RPC: %4d failed to lock transport %p\n", task->tk_pid, xprt);
task->tk_timeout = 0;
task->tk_status = -EAGAIN;
if (req && req->rq_ntrans)
@@ -169,26 +159,52 @@ out_sleep:
return 0;
}
-static inline int
-xprt_lock_write(struct rpc_xprt *xprt, struct rpc_task *task)
+static inline int xprt_lock_write(struct rpc_xprt *xprt, struct rpc_task *task)
{
int retval;
- spin_lock_bh(&xprt->sock_lock);
- retval = __xprt_lock_write(xprt, task);
- spin_unlock_bh(&xprt->sock_lock);
+ spin_lock_bh(&xprt->transport_lock);
+ retval = xprt->ops->reserve_xprt(task);
+ spin_unlock_bh(&xprt->transport_lock);
return retval;
}
+static void __xprt_lock_write_next(struct rpc_xprt *xprt)
+{
+ struct rpc_task *task;
+ struct rpc_rqst *req;
-static void
-__xprt_lock_write_next(struct rpc_xprt *xprt)
+ if (test_and_set_bit(XPRT_LOCKED, &xprt->state))
+ return;
+
+ task = rpc_wake_up_next(&xprt->resend);
+ if (!task) {
+ task = rpc_wake_up_next(&xprt->sending);
+ if (!task)
+ goto out_unlock;
+ }
+
+ req = task->tk_rqstp;
+ xprt->snd_task = task;
+ if (req) {
+ req->rq_bytes_sent = 0;
+ req->rq_ntrans++;
+ }
+ return;
+
+out_unlock:
+ smp_mb__before_clear_bit();
+ clear_bit(XPRT_LOCKED, &xprt->state);
+ smp_mb__after_clear_bit();
+}
+
+static void __xprt_lock_write_next_cong(struct rpc_xprt *xprt)
{
struct rpc_task *task;
- if (test_and_set_bit(XPRT_LOCKED, &xprt->sockstate))
+ if (test_and_set_bit(XPRT_LOCKED, &xprt->state))
return;
- if (!xprt->nocong && RPCXPRT_CONGESTED(xprt))
+ if (RPCXPRT_CONGESTED(xprt))
goto out_unlock;
task = rpc_wake_up_next(&xprt->resend);
if (!task) {
@@ -196,7 +212,7 @@ __xprt_lock_write_next(struct rpc_xprt *xprt)
if (!task)
goto out_unlock;
}
- if (xprt->nocong || __xprt_get_cong(xprt, task)) {
+ if (__xprt_get_cong(xprt, task)) {
struct rpc_rqst *req = task->tk_rqstp;
xprt->snd_task = task;
if (req) {
@@ -207,87 +223,52 @@ __xprt_lock_write_next(struct rpc_xprt *xprt)
}
out_unlock:
smp_mb__before_clear_bit();
- clear_bit(XPRT_LOCKED, &xprt->sockstate);
+ clear_bit(XPRT_LOCKED, &xprt->state);
smp_mb__after_clear_bit();
}
-/*
- * Releases the socket for use by other requests.
+/**
+ * xprt_release_xprt - allow other requests to use a transport
+ * @xprt: transport with other tasks potentially waiting
+ * @task: task that is releasing access to the transport
+ *
+ * Note that "task" can be NULL. No congestion control is provided.
*/
-static void
-__xprt_release_write(struct rpc_xprt *xprt, struct rpc_task *task)
+void xprt_release_xprt(struct rpc_xprt *xprt, struct rpc_task *task)
{
if (xprt->snd_task == task) {
xprt->snd_task = NULL;
smp_mb__before_clear_bit();
- clear_bit(XPRT_LOCKED, &xprt->sockstate);
+ clear_bit(XPRT_LOCKED, &xprt->state);
smp_mb__after_clear_bit();
__xprt_lock_write_next(xprt);
}
}
-static inline void
-xprt_release_write(struct rpc_xprt *xprt, struct rpc_task *task)
-{
- spin_lock_bh(&xprt->sock_lock);
- __xprt_release_write(xprt, task);
- spin_unlock_bh(&xprt->sock_lock);
-}
-
-/*
- * Write data to socket.
+/**
+ * xprt_release_xprt_cong - allow other requests to use a transport
+ * @xprt: transport with other tasks potentially waiting
+ * @task: task that is releasing access to the transport
+ *
+ * Note that "task" can be NULL. Another task is awoken to use the
+ * transport if the transport's congestion window allows it.
*/
-static inline int
-xprt_sendmsg(struct rpc_xprt *xprt, struct rpc_rqst *req)
+void xprt_release_xprt_cong(struct rpc_xprt *xprt, struct rpc_task *task)
{
- struct socket *sock = xprt->sock;
- struct xdr_buf *xdr = &req->rq_snd_buf;
- struct sockaddr *addr = NULL;
- int addrlen = 0;
- unsigned int skip;
- int result;
-
- if (!sock)
- return -ENOTCONN;
-
- xprt_pktdump("packet data:",
- req->rq_svec->iov_base,
- req->rq_svec->iov_len);
-
- /* For UDP, we need to provide an address */
- if (!xprt->stream) {
- addr = (struct sockaddr *) &xprt->addr;
- addrlen = sizeof(xprt->addr);
+ if (xprt->snd_task == task) {
+ xprt->snd_task = NULL;
+ smp_mb__before_clear_bit();
+ clear_bit(XPRT_LOCKED, &xprt->state);
+ smp_mb__after_clear_bit();
+ __xprt_lock_write_next_cong(xprt);
}
- /* Dont repeat bytes */
- skip = req->rq_bytes_sent;
-
- clear_bit(SOCK_ASYNC_NOSPACE, &sock->flags);
- result = xdr_sendpages(sock, addr, addrlen, xdr, skip, MSG_DONTWAIT);
-
- dprintk("RPC: xprt_sendmsg(%d) = %d\n", xdr->len - skip, result);
-
- if (result >= 0)
- return result;
+}
- switch (result) {
- case -ECONNREFUSED:
- /* When the server has died, an ICMP port unreachable message
- * prompts ECONNREFUSED.
- */
- case -EAGAIN:
- break;
- case -ECONNRESET:
- case -ENOTCONN:
- case -EPIPE:
- /* connection broken */
- if (xprt->stream)
- result = -ENOTCONN;
- break;
- default:
- printk(KERN_NOTICE "RPC: sendmsg returned error %d\n", -result);
- }
- return result;
+static inline void xprt_release_write(struct rpc_xprt *xprt, struct rpc_task *task)
+{
+ spin_lock_bh(&xprt->transport_lock);
+ xprt->ops->release_xprt(xprt, task);
+ spin_unlock_bh(&xprt->transport_lock);
}
/*
@@ -321,26 +302,40 @@ __xprt_put_cong(struct rpc_xprt *xprt, struct rpc_rqst *req)
return;
req->rq_cong = 0;
xprt->cong -= RPC_CWNDSCALE;
- __xprt_lock_write_next(xprt);
+ __xprt_lock_write_next_cong(xprt);
}
-/*
- * Adjust RPC congestion window
+/**
+ * xprt_release_rqst_cong - housekeeping when request is complete
+ * @task: RPC request that recently completed
+ *
+ * Useful for transports that require congestion control.
+ */
+void xprt_release_rqst_cong(struct rpc_task *task)
+{
+ __xprt_put_cong(task->tk_xprt, task->tk_rqstp);
+}
+
+/**
+ * xprt_adjust_cwnd - adjust transport congestion window
+ * @task: recently completed RPC request used to adjust window
+ * @result: result code of completed RPC request
+ *
* We use a time-smoothed congestion estimator to avoid heavy oscillation.
*/
-static void
-xprt_adjust_cwnd(struct rpc_xprt *xprt, int result)
+void xprt_adjust_cwnd(struct rpc_task *task, int result)
{
- unsigned long cwnd;
+ struct rpc_rqst *req = task->tk_rqstp;
+ struct rpc_xprt *xprt = task->tk_xprt;
+ unsigned long cwnd = xprt->cwnd;
- cwnd = xprt->cwnd;
if (result >= 0 && cwnd <= xprt->cong) {
/* The (cwnd >> 1) term makes sure
* the result gets rounded properly. */
cwnd += (RPC_CWNDSCALE * RPC_CWNDSCALE + (cwnd >> 1)) / cwnd;
if (cwnd > RPC_MAXCWND(xprt))
cwnd = RPC_MAXCWND(xprt);
- __xprt_lock_write_next(xprt);
+ __xprt_lock_write_next_cong(xprt);
} else if (result == -ETIMEDOUT) {
cwnd >>= 1;
if (cwnd < RPC_CWNDSCALE)
@@ -349,11 +344,89 @@ xprt_adjust_cwnd(struct rpc_xprt *xprt, int result)
dprintk("RPC: cong %ld, cwnd was %ld, now %ld\n",
xprt->cong, xprt->cwnd, cwnd);
xprt->cwnd = cwnd;
+ __xprt_put_cong(xprt, req);
+}
+
+/**
+ * xprt_wake_pending_tasks - wake all tasks on a transport's pending queue
+ * @xprt: transport with waiting tasks
+ * @status: result code to plant in each task before waking it
+ *
+ */
+void xprt_wake_pending_tasks(struct rpc_xprt *xprt, int status)
+{
+ if (status < 0)
+ rpc_wake_up_status(&xprt->pending, status);
+ else
+ rpc_wake_up(&xprt->pending);
+}
+
+/**
+ * xprt_wait_for_buffer_space - wait for transport output buffer to clear
+ * @task: task to be put to sleep
+ *
+ */
+void xprt_wait_for_buffer_space(struct rpc_task *task)
+{
+ struct rpc_rqst *req = task->tk_rqstp;
+ struct rpc_xprt *xprt = req->rq_xprt;
+
+ task->tk_timeout = req->rq_timeout;
+ rpc_sleep_on(&xprt->pending, task, NULL, NULL);
+}
+
+/**
+ * xprt_write_space - wake the task waiting for transport output buffer space
+ * @xprt: transport with waiting tasks
+ *
+ * Can be called in a soft IRQ context, so xprt_write_space never sleeps.
+ */
+void xprt_write_space(struct rpc_xprt *xprt)
+{
+ if (unlikely(xprt->shutdown))
+ return;
+
+ spin_lock_bh(&xprt->transport_lock);
+ if (xprt->snd_task) {
+ dprintk("RPC: write space: waking waiting task on xprt %p\n",
+ xprt);
+ rpc_wake_up_task(xprt->snd_task);
+ }
+ spin_unlock_bh(&xprt->transport_lock);
+}
+
+/**
+ * xprt_set_retrans_timeout_def - set a request's retransmit timeout
+ * @task: task whose timeout is to be set
+ *
+ * Set a request's retransmit timeout based on the transport's
+ * default timeout parameters. Used by transports that don't adjust
+ * the retransmit timeout based on round-trip time estimation.
+ */
+void xprt_set_retrans_timeout_def(struct rpc_task *task)
+{
+ task->tk_timeout = task->tk_rqstp->rq_timeout;
}
/*
- * Reset the major timeout value
+ * xprt_set_retrans_timeout_rtt - set a request's retransmit timeout
+ * @task: task whose timeout is to be set
+ *
+ * Set a request's retransmit timeout using the RTT estimator.
*/
+void xprt_set_retrans_timeout_rtt(struct rpc_task *task)
+{
+ int timer = task->tk_msg.rpc_proc->p_timer;
+ struct rpc_rtt *rtt = task->tk_client->cl_rtt;
+ struct rpc_rqst *req = task->tk_rqstp;
+ unsigned long max_timeout = req->rq_xprt->timeout.to_maxval;
+
+ task->tk_timeout = rpc_calc_rto(rtt, timer);
+ task->tk_timeout <<= rpc_ntimeo(rtt, timer) + req->rq_retries;
+ if (task->tk_timeout > max_timeout || task->tk_timeout == 0)
+ task->tk_timeout = max_timeout;
+}
+
static void xprt_reset_majortimeo(struct rpc_rqst *req)
{
struct rpc_timeout *to = &req->rq_xprt->timeout;
@@ -368,8 +441,10 @@ static void xprt_reset_majortimeo(struct rpc_rqst *req)
req->rq_majortimeo += jiffies;
}
-/*
- * Adjust timeout values etc for next retransmit
+/**
+ * xprt_adjust_timeout - adjust timeout values for next retransmit
+ * @req: RPC request containing parameters to use for the adjustment
+ *
*/
int xprt_adjust_timeout(struct rpc_rqst *req)
{
@@ -391,9 +466,9 @@ int xprt_adjust_timeout(struct rpc_rqst *req)
req->rq_retries = 0;
xprt_reset_majortimeo(req);
/* Reset the RTT counters == "slow start" */
- spin_lock_bh(&xprt->sock_lock);
+ spin_lock_bh(&xprt->transport_lock);
rpc_init_rtt(req->rq_task->tk_client->cl_rtt, to->to_initval);
- spin_unlock_bh(&xprt->sock_lock);
+ spin_unlock_bh(&xprt->transport_lock);
pprintk("RPC: %lu timeout\n", jiffies);
status = -ETIMEDOUT;
}
@@ -405,133 +480,52 @@ int xprt_adjust_timeout(struct rpc_rqst *req)
return status;
}
-/*
- * Close down a transport socket
- */
-static void
-xprt_close(struct rpc_xprt *xprt)
-{
- struct socket *sock = xprt->sock;
- struct sock *sk = xprt->inet;
-
- if (!sk)
- return;
-
- write_lock_bh(&sk->sk_callback_lock);
- xprt->inet = NULL;
- xprt->sock = NULL;
-
- sk->sk_user_data = NULL;
- sk->sk_data_ready = xprt->old_data_ready;
- sk->sk_state_change = xprt->old_state_change;
- sk->sk_write_space = xprt->old_write_space;
- write_unlock_bh(&sk->sk_callback_lock);
-
- sk->sk_no_check = 0;
-
- sock_release(sock);
-}
-
-static void
-xprt_socket_autoclose(void *args)
+static void xprt_autoclose(void *args)
{
struct rpc_xprt *xprt = (struct rpc_xprt *)args;
xprt_disconnect(xprt);
- xprt_close(xprt);
+ xprt->ops->close(xprt);
xprt_release_write(xprt, NULL);
}
-/*
- * Mark a transport as disconnected
+/**
+ * xprt_disconnect - mark a transport as disconnected
+ * @xprt: transport to flag for disconnect
+ *
*/
-static void
-xprt_disconnect(struct rpc_xprt *xprt)
+void xprt_disconnect(struct rpc_xprt *xprt)
{
dprintk("RPC: disconnected transport %p\n", xprt);
- spin_lock_bh(&xprt->sock_lock);
+ spin_lock_bh(&xprt->transport_lock);
xprt_clear_connected(xprt);
- rpc_wake_up_status(&xprt->pending, -ENOTCONN);
- spin_unlock_bh(&xprt->sock_lock);
+ xprt_wake_pending_tasks(xprt, -ENOTCONN);
+ spin_unlock_bh(&xprt->transport_lock);
}
-/*
- * Used to allow disconnection when we've been idle
- */
static void
xprt_init_autodisconnect(unsigned long data)
{
struct rpc_xprt *xprt = (struct rpc_xprt *)data;
- spin_lock(&xprt->sock_lock);
+ spin_lock(&xprt->transport_lock);
if (!list_empty(&xprt->recv) || xprt->shutdown)
goto out_abort;
- if (test_and_set_bit(XPRT_LOCKED, &xprt->sockstate))
+ if (test_and_set_bit(XPRT_LOCKED, &xprt->state))
goto out_abort;
- spin_unlock(&xprt->sock_lock);
- /* Let keventd close the socket */
- if (test_bit(XPRT_CONNECTING, &xprt->sockstate) != 0)
+ spin_unlock(&xprt->transport_lock);
+ if (xprt_connecting(xprt))
xprt_release_write(xprt, NULL);
else
schedule_work(&xprt->task_cleanup);
return;
out_abort:
- spin_unlock(&xprt->sock_lock);
-}
-
-static void xprt_socket_connect(void *args)
-{
- struct rpc_xprt *xprt = (struct rpc_xprt *)args;
- struct socket *sock = xprt->sock;
- int status = -EIO;
-
- if (xprt->shutdown || xprt->addr.sin_port == 0)
- goto out;
-
- /*
- * Start by resetting any existing state
- */
- xprt_close(xprt);
- sock = xprt_create_socket(xprt, xprt->prot, xprt->resvport);
- if (sock == NULL) {
- /* couldn't create socket or bind to reserved port;
- * this is likely a permanent error, so cause an abort */
- goto out;
- }
- xprt_bind_socket(xprt, sock);
- xprt_sock_setbufsize(xprt);
-
- status = 0;
- if (!xprt->stream)
- goto out;
-
- /*
- * Tell the socket layer to start connecting...
- */
- status = sock->ops->connect(sock, (struct sockaddr *) &xprt->addr,
- sizeof(xprt->addr), O_NONBLOCK);
- dprintk("RPC: %p connect status %d connected %d sock state %d\n",
- xprt, -status, xprt_connected(xprt), sock->sk->sk_state);
- if (status < 0) {
- switch (status) {
- case -EINPROGRESS:
- case -EALREADY:
- goto out_clear;
- }
- }
-out:
- if (status < 0)
- rpc_wake_up_status(&xprt->pending, status);
- else
- rpc_wake_up(&xprt->pending);
-out_clear:
- smp_mb__before_clear_bit();
- clear_bit(XPRT_CONNECTING, &xprt->sockstate);
- smp_mb__after_clear_bit();
+ spin_unlock(&xprt->transport_lock);
}
-/*
- * Attempt to connect a TCP socket.
+/**
+ * xprt_connect - schedule a transport connect operation
+ * @task: RPC task that is requesting the connect
*
*/
void xprt_connect(struct rpc_task *task)
@@ -552,37 +546,19 @@ void xprt_connect(struct rpc_task *task)
if (!xprt_lock_write(xprt, task))
return;
if (xprt_connected(xprt))
- goto out_write;
+ xprt_release_write(xprt, task);
+ else {
+ if (task->tk_rqstp)
+ task->tk_rqstp->rq_bytes_sent = 0;
- if (task->tk_rqstp)
- task->tk_rqstp->rq_bytes_sent = 0;
-
- task->tk_timeout = RPC_CONNECT_TIMEOUT;
- rpc_sleep_on(&xprt->pending, task, xprt_connect_status, NULL);
- if (!test_and_set_bit(XPRT_CONNECTING, &xprt->sockstate)) {
- /* Note: if we are here due to a dropped connection
- * we delay reconnecting by RPC_REESTABLISH_TIMEOUT/HZ
- * seconds
- */
- if (xprt->sock != NULL)
- schedule_delayed_work(&xprt->sock_connect,
- RPC_REESTABLISH_TIMEOUT);
- else {
- schedule_work(&xprt->sock_connect);
- if (!RPC_IS_ASYNC(task))
- flush_scheduled_work();
- }
+ task->tk_timeout = xprt->connect_timeout;
+ rpc_sleep_on(&xprt->pending, task, xprt_connect_status, NULL);
+ xprt->ops->connect(task);
}
return;
- out_write:
- xprt_release_write(xprt, task);
}
-/*
- * We arrive here when awoken from waiting on connection establishment.
- */
-static void
-xprt_connect_status(struct rpc_task *task)
+static void xprt_connect_status(struct rpc_task *task)
{
struct rpc_xprt *xprt = task->tk_xprt;
@@ -592,31 +568,42 @@ xprt_connect_status(struct rpc_task *task)
return;
}
- /* if soft mounted, just cause this RPC to fail */
- if (RPC_IS_SOFT(task))
- task->tk_status = -EIO;
-
switch (task->tk_status) {
case -ECONNREFUSED:
case -ECONNRESET:
+ dprintk("RPC: %4d xprt_connect_status: server %s refused connection\n",
+ task->tk_pid, task->tk_client->cl_server);
+ break;
case -ENOTCONN:
- return;
+ dprintk("RPC: %4d xprt_connect_status: connection broken\n",
+ task->tk_pid);
+ break;
case -ETIMEDOUT:
- dprintk("RPC: %4d xprt_connect_status: timed out\n",
+ dprintk("RPC: %4d xprt_connect_status: connect attempt timed out\n",
task->tk_pid);
break;
default:
- printk(KERN_ERR "RPC: error %d connecting to server %s\n",
- -task->tk_status, task->tk_client->cl_server);
+ dprintk("RPC: %4d xprt_connect_status: error %d connecting to server %s\n",
+ task->tk_pid, -task->tk_status, task->tk_client->cl_server);
+ xprt_release_write(xprt, task);
+ task->tk_status = -EIO;
+ return;
+ }
+
+ /* if soft mounted, just cause this RPC to fail */
+ if (RPC_IS_SOFT(task)) {
+ xprt_release_write(xprt, task);
+ task->tk_status = -EIO;
}
- xprt_release_write(xprt, task);
}
-/*
- * Look up the RPC request corresponding to a reply, and then lock it.
+/**
+ * xprt_lookup_rqst - find an RPC request corresponding to an XID
+ * @xprt: transport on which the original request was transmitted
+ * @xid: RPC XID of incoming reply
+ *
*/
-static inline struct rpc_rqst *
-xprt_lookup_rqst(struct rpc_xprt *xprt, u32 xid)
+struct rpc_rqst *xprt_lookup_rqst(struct rpc_xprt *xprt, u32 xid)
{
struct list_head *pos;
struct rpc_rqst *req = NULL;
@@ -631,556 +618,68 @@ xprt_lookup_rqst(struct rpc_xprt *xprt, u32 xid)
return req;
}
-/*
- * Complete reply received.
- * The TCP code relies on us to remove the request from xprt->pending.
- */
-static void
-xprt_complete_rqst(struct rpc_xprt *xprt, struct rpc_rqst *req, int copied)
-{
- struct rpc_task *task = req->rq_task;
- struct rpc_clnt *clnt = task->tk_client;
-
- /* Adjust congestion window */
- if (!xprt->nocong) {
- unsigned timer = task->tk_msg.rpc_proc->p_timer;
- xprt_adjust_cwnd(xprt, copied);
- __xprt_put_cong(xprt, req);
- if (timer) {
- if (req->rq_ntrans == 1)
- rpc_update_rtt(clnt->cl_rtt, timer,
- (long)jiffies - req->rq_xtime);
- rpc_set_timeo(clnt->cl_rtt, timer, req->rq_ntrans - 1);
- }
- }
-
-#ifdef RPC_PROFILE
- /* Profile only reads for now */
- if (copied > 1024) {
- static unsigned long nextstat;
- static unsigned long pkt_rtt, pkt_len, pkt_cnt;
-
- pkt_cnt++;
- pkt_len += req->rq_slen + copied;
- pkt_rtt += jiffies - req->rq_xtime;
- if (time_before(nextstat, jiffies)) {
- printk("RPC: %lu %ld cwnd\n", jiffies, xprt->cwnd);
- printk("RPC: %ld %ld %ld %ld stat\n",
- jiffies, pkt_cnt, pkt_len, pkt_rtt);
- pkt_rtt = pkt_len = pkt_cnt = 0;
- nextstat = jiffies + 5 * HZ;
- }
- }
-#endif
-
- dprintk("RPC: %4d has input (%d bytes)\n", task->tk_pid, copied);
- list_del_init(&req->rq_list);
- req->rq_received = req->rq_private_buf.len = copied;
-
- /* ... and wake up the process. */
- rpc_wake_up_task(task);
- return;
-}
-
-static size_t
-skb_read_bits(skb_reader_t *desc, void *to, size_t len)
-{
- if (len > desc->count)
- len = desc->count;
- if (skb_copy_bits(desc->skb, desc->offset, to, len))
- return 0;
- desc->count -= len;
- desc->offset += len;
- return len;
-}
-
-static size_t
-skb_read_and_csum_bits(skb_reader_t *desc, void *to, size_t len)
-{
- unsigned int csum2, pos;
-
- if (len > desc->count)
- len = desc->count;
- pos = desc->offset;
- csum2 = skb_copy_and_csum_bits(desc->skb, pos, to, len, 0);
- desc->csum = csum_block_add(desc->csum, csum2, pos);
- desc->count -= len;
- desc->offset += len;
- return len;
-}
-
-/*
- * We have set things up such that we perform the checksum of the UDP
- * packet in parallel with the copies into the RPC client iovec. -DaveM
- */
-int
-csum_partial_copy_to_xdr(struct xdr_buf *xdr, struct sk_buff *skb)
-{
- skb_reader_t desc;
-
- desc.skb = skb;
- desc.offset = sizeof(struct udphdr);
- desc.count = skb->len - desc.offset;
-
- if (skb->ip_summed == CHECKSUM_UNNECESSARY)
- goto no_checksum;
-
- desc.csum = csum_partial(skb->data, desc.offset, skb->csum);
- if (xdr_partial_copy_from_skb(xdr, 0, &desc, skb_read_and_csum_bits) < 0)
- return -1;
- if (desc.offset != skb->len) {
- unsigned int csum2;
- csum2 = skb_checksum(skb, desc.offset, skb->len - desc.offset, 0);
- desc.csum = csum_block_add(desc.csum, csum2, desc.offset);
- }
- if (desc.count)
- return -1;
- if ((unsigned short)csum_fold(desc.csum))
- return -1;
- return 0;
-no_checksum:
- if (xdr_partial_copy_from_skb(xdr, 0, &desc, skb_read_bits) < 0)
- return -1;
- if (desc.count)
- return -1;
- return 0;
-}
-
-/*
- * Input handler for RPC replies. Called from a bottom half and hence
- * atomic.
- */
-static void
-udp_data_ready(struct sock *sk, int len)
-{
- struct rpc_task *task;
- struct rpc_xprt *xprt;
- struct rpc_rqst *rovr;
- struct sk_buff *skb;
- int err, repsize, copied;
- u32 _xid, *xp;
-
- read_lock(&sk->sk_callback_lock);
- dprintk("RPC: udp_data_ready...\n");
- if (!(xprt = xprt_from_sock(sk))) {
- printk("RPC: udp_data_ready request not found!\n");
- goto out;
- }
-
- dprintk("RPC: udp_data_ready client %p\n", xprt);
-
- if ((skb = skb_recv_datagram(sk, 0, 1, &err)) == NULL)
- goto out;
-
- if (xprt->shutdown)
- goto dropit;
-
- repsize = skb->len - sizeof(struct udphdr);
- if (repsize < 4) {
- printk("RPC: impossible RPC reply size %d!\n", repsize);
- goto dropit;
- }
-
- /* Copy the XID from the skb... */
- xp = skb_header_pointer(skb, sizeof(struct udphdr),
- sizeof(_xid), &_xid);
- if (xp == NULL)
- goto dropit;
-
- /* Look up and lock the request corresponding to the given XID */
- spin_lock(&xprt->sock_lock);
- rovr = xprt_lookup_rqst(xprt, *xp);
- if (!rovr)
- goto out_unlock;
- task = rovr->rq_task;
-
- dprintk("RPC: %4d received reply\n", task->tk_pid);
-
- if ((copied = rovr->rq_private_buf.buflen) > repsize)
- copied = repsize;
-
- /* Suck it into the iovec, verify checksum if not done by hw. */
- if (csum_partial_copy_to_xdr(&rovr->rq_private_buf, skb))
- goto out_unlock;
-
- /* Something worked... */
- dst_confirm(skb->dst);
-
- xprt_complete_rqst(xprt, rovr, copied);
-
- out_unlock:
- spin_unlock(&xprt->sock_lock);
- dropit:
- skb_free_datagram(sk, skb);
- out:
- read_unlock(&sk->sk_callback_lock);
-}
-
-/*
- * Copy from an skb into memory and shrink the skb.
- */
-static inline size_t
-tcp_copy_data(skb_reader_t *desc, void *p, size_t len)
-{
- if (len > desc->count)
- len = desc->count;
- if (skb_copy_bits(desc->skb, desc->offset, p, len)) {
- dprintk("RPC: failed to copy %zu bytes from skb. %zu bytes remain\n",
- len, desc->count);
- return 0;
- }
- desc->offset += len;
- desc->count -= len;
- dprintk("RPC: copied %zu bytes from skb. %zu bytes remain\n",
- len, desc->count);
- return len;
-}
-
-/*
- * TCP read fragment marker
- */
-static inline void
-tcp_read_fraghdr(struct rpc_xprt *xprt, skb_reader_t *desc)
-{
- size_t len, used;
- char *p;
-
- p = ((char *) &xprt->tcp_recm) + xprt->tcp_offset;
- len = sizeof(xprt->tcp_recm) - xprt->tcp_offset;
- used = tcp_copy_data(desc, p, len);
- xprt->tcp_offset += used;
- if (used != len)
- return;
- xprt->tcp_reclen = ntohl(xprt->tcp_recm);
- if (xprt->tcp_reclen & 0x80000000)
- xprt->tcp_flags |= XPRT_LAST_FRAG;
- else
- xprt->tcp_flags &= ~XPRT_LAST_FRAG;
- xprt->tcp_reclen &= 0x7fffffff;
- xprt->tcp_flags &= ~XPRT_COPY_RECM;
- xprt->tcp_offset = 0;
- /* Sanity check of the record length */
- if (xprt->tcp_reclen < 4) {
- printk(KERN_ERR "RPC: Invalid TCP record fragment length\n");
- xprt_disconnect(xprt);
- }
- dprintk("RPC: reading TCP record fragment of length %d\n",
- xprt->tcp_reclen);
-}
-
-static void
-tcp_check_recm(struct rpc_xprt *xprt)
-{
- dprintk("RPC: xprt = %p, tcp_copied = %lu, tcp_offset = %u, tcp_reclen = %u, tcp_flags = %lx\n",
- xprt, xprt->tcp_copied, xprt->tcp_offset, xprt->tcp_reclen, xprt->tcp_flags);
- if (xprt->tcp_offset == xprt->tcp_reclen) {
- xprt->tcp_flags |= XPRT_COPY_RECM;
- xprt->tcp_offset = 0;
- if (xprt->tcp_flags & XPRT_LAST_FRAG) {
- xprt->tcp_flags &= ~XPRT_COPY_DATA;
- xprt->tcp_flags |= XPRT_COPY_XID;
- xprt->tcp_copied = 0;
- }
- }
-}
-
-/*
- * TCP read xid
- */
-static inline void
-tcp_read_xid(struct rpc_xprt *xprt, skb_reader_t *desc)
-{
- size_t len, used;
- char *p;
-
- len = sizeof(xprt->tcp_xid) - xprt->tcp_offset;
- dprintk("RPC: reading XID (%Zu bytes)\n", len);
- p = ((char *) &xprt->tcp_xid) + xprt->tcp_offset;
- used = tcp_copy_data(desc, p, len);
- xprt->tcp_offset += used;
- if (used != len)
- return;
- xprt->tcp_flags &= ~XPRT_COPY_XID;
- xprt->tcp_flags |= XPRT_COPY_DATA;
- xprt->tcp_copied = 4;
- dprintk("RPC: reading reply for XID %08x\n",
- ntohl(xprt->tcp_xid));
- tcp_check_recm(xprt);
-}
-
-/*
- * TCP read and complete request
- */
-static inline void
-tcp_read_request(struct rpc_xprt *xprt, skb_reader_t *desc)
-{
- struct rpc_rqst *req;
- struct xdr_buf *rcvbuf;
- size_t len;
- ssize_t r;
-
- /* Find and lock the request corresponding to this xid */
- spin_lock(&xprt->sock_lock);
- req = xprt_lookup_rqst(xprt, xprt->tcp_xid);
- if (!req) {
- xprt->tcp_flags &= ~XPRT_COPY_DATA;
- dprintk("RPC: XID %08x request not found!\n",
- ntohl(xprt->tcp_xid));
- spin_unlock(&xprt->sock_lock);
- return;
- }
-
- rcvbuf = &req->rq_private_buf;
- len = desc->count;
- if (len > xprt->tcp_reclen - xprt->tcp_offset) {
- skb_reader_t my_desc;
-
- len = xprt->tcp_reclen - xprt->tcp_offset;
- memcpy(&my_desc, desc, sizeof(my_desc));
- my_desc.count = len;
- r = xdr_partial_copy_from_skb(rcvbuf, xprt->tcp_copied,
- &my_desc, tcp_copy_data);
- desc->count -= r;
- desc->offset += r;
- } else
- r = xdr_partial_copy_from_skb(rcvbuf, xprt->tcp_copied,
- desc, tcp_copy_data);
-
- if (r > 0) {
- xprt->tcp_copied += r;
- xprt->tcp_offset += r;
- }
- if (r != len) {
- /* Error when copying to the receive buffer,
- * usually because we weren't able to allocate
- * additional buffer pages. All we can do now
- * is turn off XPRT_COPY_DATA, so the request
- * will not receive any additional updates,
- * and time out.
- * Any remaining data from this record will
- * be discarded.
- */
- xprt->tcp_flags &= ~XPRT_COPY_DATA;
- dprintk("RPC: XID %08x truncated request\n",
- ntohl(xprt->tcp_xid));
- dprintk("RPC: xprt = %p, tcp_copied = %lu, tcp_offset = %u, tcp_reclen = %u\n",
- xprt, xprt->tcp_copied, xprt->tcp_offset, xprt->tcp_reclen);
- goto out;
- }
-
- dprintk("RPC: XID %08x read %Zd bytes\n",
- ntohl(xprt->tcp_xid), r);
- dprintk("RPC: xprt = %p, tcp_copied = %lu, tcp_offset = %u, tcp_reclen = %u\n",
- xprt, xprt->tcp_copied, xprt->tcp_offset, xprt->tcp_reclen);
-
- if (xprt->tcp_copied == req->rq_private_buf.buflen)
- xprt->tcp_flags &= ~XPRT_COPY_DATA;
- else if (xprt->tcp_offset == xprt->tcp_reclen) {
- if (xprt->tcp_flags & XPRT_LAST_FRAG)
- xprt->tcp_flags &= ~XPRT_COPY_DATA;
- }
-
-out:
- if (!(xprt->tcp_flags & XPRT_COPY_DATA)) {
- dprintk("RPC: %4d received reply complete\n",
- req->rq_task->tk_pid);
- xprt_complete_rqst(xprt, req, xprt->tcp_copied);
- }
- spin_unlock(&xprt->sock_lock);
- tcp_check_recm(xprt);
-}
-
-/*
- * TCP discard extra bytes from a short read
- */
-static inline void
-tcp_read_discard(struct rpc_xprt *xprt, skb_reader_t *desc)
-{
- size_t len;
-
- len = xprt->tcp_reclen - xprt->tcp_offset;
- if (len > desc->count)
- len = desc->count;
- desc->count -= len;
- desc->offset += len;
- xprt->tcp_offset += len;
- dprintk("RPC: discarded %Zu bytes\n", len);
- tcp_check_recm(xprt);
-}
-
-/*
- * TCP record receive routine
- * We first have to grab the record marker, then the XID, then the data.
+/**
+ * xprt_update_rtt - update an RPC client's RTT state after receiving a reply
+ * @task: RPC request that recently completed
+ *
*/
-static int
-tcp_data_recv(read_descriptor_t *rd_desc, struct sk_buff *skb,
- unsigned int offset, size_t len)
-{
- struct rpc_xprt *xprt = rd_desc->arg.data;
- skb_reader_t desc = {
- .skb = skb,
- .offset = offset,
- .count = len,
- .csum = 0
- };
-
- dprintk("RPC: tcp_data_recv\n");
- do {
- /* Read in a new fragment marker if necessary */
- /* Can we ever really expect to get completely empty fragments? */
- if (xprt->tcp_flags & XPRT_COPY_RECM) {
- tcp_read_fraghdr(xprt, &desc);
- continue;
- }
- /* Read in the xid if necessary */
- if (xprt->tcp_flags & XPRT_COPY_XID) {
- tcp_read_xid(xprt, &desc);
- continue;
- }
- /* Read in the request data */
- if (xprt->tcp_flags & XPRT_COPY_DATA) {
- tcp_read_request(xprt, &desc);
- continue;
- }
- /* Skip over any trailing bytes on short reads */
- tcp_read_discard(xprt, &desc);
- } while (desc.count);
- dprintk("RPC: tcp_data_recv done\n");
- return len - desc.count;
-}
-
-static void tcp_data_ready(struct sock *sk, int bytes)
+void xprt_update_rtt(struct rpc_task *task)
{
- struct rpc_xprt *xprt;
- read_descriptor_t rd_desc;
-
- read_lock(&sk->sk_callback_lock);
- dprintk("RPC: tcp_data_ready...\n");
- if (!(xprt = xprt_from_sock(sk))) {
- printk("RPC: tcp_data_ready socket info not found!\n");
- goto out;
- }
- if (xprt->shutdown)
- goto out;
-
- /* We use rd_desc to pass struct xprt to tcp_data_recv */
- rd_desc.arg.data = xprt;
- rd_desc.count = 65536;
- tcp_read_sock(sk, &rd_desc, tcp_data_recv);
-out:
- read_unlock(&sk->sk_callback_lock);
-}
-
-static void
-tcp_state_change(struct sock *sk)
-{
- struct rpc_xprt *xprt;
+ struct rpc_rqst *req = task->tk_rqstp;
+ struct rpc_rtt *rtt = task->tk_client->cl_rtt;
+ unsigned timer = task->tk_msg.rpc_proc->p_timer;
- read_lock(&sk->sk_callback_lock);
- if (!(xprt = xprt_from_sock(sk)))
- goto out;
- dprintk("RPC: tcp_state_change client %p...\n", xprt);
- dprintk("RPC: state %x conn %d dead %d zapped %d\n",
- sk->sk_state, xprt_connected(xprt),
- sock_flag(sk, SOCK_DEAD),
- sock_flag(sk, SOCK_ZAPPED));
-
- switch (sk->sk_state) {
- case TCP_ESTABLISHED:
- spin_lock_bh(&xprt->sock_lock);
- if (!xprt_test_and_set_connected(xprt)) {
- /* Reset TCP record info */
- xprt->tcp_offset = 0;
- xprt->tcp_reclen = 0;
- xprt->tcp_copied = 0;
- xprt->tcp_flags = XPRT_COPY_RECM | XPRT_COPY_XID;
- rpc_wake_up(&xprt->pending);
- }
- spin_unlock_bh(&xprt->sock_lock);
- break;
- case TCP_SYN_SENT:
- case TCP_SYN_RECV:
- break;
- default:
- xprt_disconnect(xprt);
- break;
+ if (timer) {
+ if (req->rq_ntrans == 1)
+ rpc_update_rtt(rtt, timer,
+ (long)jiffies - req->rq_xtime);
+ rpc_set_timeo(rtt, timer, req->rq_ntrans - 1);
}
- out:
- read_unlock(&sk->sk_callback_lock);
}
-/*
- * Called when more output buffer space is available for this socket.
- * We try not to wake our writers until they can make "significant"
- * progress, otherwise we'll waste resources thrashing sock_sendmsg
- * with a bunch of small requests.
+/**
+ * xprt_complete_rqst - called when reply processing is complete
+ * @task: RPC request that recently completed
+ * @copied: actual number of bytes received from the transport
+ *
+ * Caller holds transport lock.
*/
-static void
-xprt_write_space(struct sock *sk)
+void xprt_complete_rqst(struct rpc_task *task, int copied)
{
- struct rpc_xprt *xprt;
- struct socket *sock;
-
- read_lock(&sk->sk_callback_lock);
- if (!(xprt = xprt_from_sock(sk)) || !(sock = sk->sk_socket))
- goto out;
- if (xprt->shutdown)
- goto out;
-
- /* Wait until we have enough socket memory */
- if (xprt->stream) {
- /* from net/core/stream.c:sk_stream_write_space */
- if (sk_stream_wspace(sk) < sk_stream_min_wspace(sk))
- goto out;
- } else {
- /* from net/core/sock.c:sock_def_write_space */
- if (!sock_writeable(sk))
- goto out;
- }
+ struct rpc_rqst *req = task->tk_rqstp;
- if (!test_and_clear_bit(SOCK_NOSPACE, &sock->flags))
- goto out;
+ dprintk("RPC: %5u xid %08x complete (%d bytes received)\n",
+ task->tk_pid, ntohl(req->rq_xid), copied);
- spin_lock_bh(&xprt->sock_lock);
- if (xprt->snd_task)
- rpc_wake_up_task(xprt->snd_task);
- spin_unlock_bh(&xprt->sock_lock);
-out:
- read_unlock(&sk->sk_callback_lock);
+ list_del_init(&req->rq_list);
+ req->rq_received = req->rq_private_buf.len = copied;
+ rpc_wake_up_task(task);
}
-/*
- * RPC receive timeout handler.
- */
-static void
-xprt_timer(struct rpc_task *task)
+static void xprt_timer(struct rpc_task *task)
{
- struct rpc_rqst *req = task->tk_rqstp;
+ struct rpc_rqst *req = task->tk_rqstp;
struct rpc_xprt *xprt = req->rq_xprt;
- spin_lock(&xprt->sock_lock);
- if (req->rq_received)
- goto out;
-
- xprt_adjust_cwnd(req->rq_xprt, -ETIMEDOUT);
- __xprt_put_cong(xprt, req);
+ dprintk("RPC: %4d xprt_timer\n", task->tk_pid);
- dprintk("RPC: %4d xprt_timer (%s request)\n",
- task->tk_pid, req ? "pending" : "backlogged");
-
- task->tk_status = -ETIMEDOUT;
-out:
+ spin_lock(&xprt->transport_lock);
+ if (!req->rq_received) {
+ if (xprt->ops->timer)
+ xprt->ops->timer(task);
+ task->tk_status = -ETIMEDOUT;
+ }
task->tk_timeout = 0;
rpc_wake_up_task(task);
- spin_unlock(&xprt->sock_lock);
+ spin_unlock(&xprt->transport_lock);
}
-/*
- * Place the actual RPC call.
- * We have to copy the iovec because sendmsg fiddles with its contents.
+/**
+ * xprt_prepare_transmit - reserve the transport before sending a request
+ * @task: RPC task about to send a request
+ *
*/
-int
-xprt_prepare_transmit(struct rpc_task *task)
+int xprt_prepare_transmit(struct rpc_task *task)
{
struct rpc_rqst *req = task->tk_rqstp;
struct rpc_xprt *xprt = req->rq_xprt;
@@ -1191,12 +690,12 @@ xprt_prepare_transmit(struct rpc_task *task)
if (xprt->shutdown)
return -EIO;
- spin_lock_bh(&xprt->sock_lock);
+ spin_lock_bh(&xprt->transport_lock);
if (req->rq_received && !req->rq_bytes_sent) {
err = req->rq_received;
goto out_unlock;
}
- if (!__xprt_lock_write(xprt, task)) {
+ if (!xprt->ops->reserve_xprt(task)) {
err = -EAGAIN;
goto out_unlock;
}
@@ -1206,39 +705,42 @@ xprt_prepare_transmit(struct rpc_task *task)
goto out_unlock;
}
out_unlock:
- spin_unlock_bh(&xprt->sock_lock);
+ spin_unlock_bh(&xprt->transport_lock);
return err;
}
void
-xprt_transmit(struct rpc_task *task)
+xprt_abort_transmit(struct rpc_task *task)
+{
+ struct rpc_xprt *xprt = task->tk_xprt;
+
+ xprt_release_write(xprt, task);
+}
+
+/**
+ * xprt_transmit - send an RPC request on a transport
+ * @task: controlling RPC task
+ *
+ * We have to copy the iovec because sendmsg fiddles with its contents.
+ */
+void xprt_transmit(struct rpc_task *task)
{
- struct rpc_clnt *clnt = task->tk_client;
struct rpc_rqst *req = task->tk_rqstp;
struct rpc_xprt *xprt = req->rq_xprt;
- int status, retry = 0;
-
+ int status;
dprintk("RPC: %4d xprt_transmit(%u)\n", task->tk_pid, req->rq_slen);
- /* set up everything as needed. */
- /* Write the record marker */
- if (xprt->stream) {
- u32 *marker = req->rq_svec[0].iov_base;
-
- *marker = htonl(0x80000000|(req->rq_slen-sizeof(*marker)));
- }
-
smp_rmb();
if (!req->rq_received) {
if (list_empty(&req->rq_list)) {
- spin_lock_bh(&xprt->sock_lock);
+ spin_lock_bh(&xprt->transport_lock);
/* Update the softirq receive buffer */
memcpy(&req->rq_private_buf, &req->rq_rcv_buf,
sizeof(req->rq_private_buf));
/* Add request to the receive list */
list_add_tail(&req->rq_list, &xprt->recv);
- spin_unlock_bh(&xprt->sock_lock);
+ spin_unlock_bh(&xprt->transport_lock);
xprt_reset_majortimeo(req);
/* Turn off autodisconnect */
del_singleshot_timer_sync(&xprt->timer);
@@ -1246,40 +748,19 @@ xprt_transmit(struct rpc_task *task)
} else if (!req->rq_bytes_sent)
return;
- /* Continue transmitting the packet/record. We must be careful
- * to cope with writespace callbacks arriving _after_ we have
- * called xprt_sendmsg().
- */
- while (1) {
- req->rq_xtime = jiffies;
- status = xprt_sendmsg(xprt, req);
-
- if (status < 0)
- break;
-
- if (xprt->stream) {
- req->rq_bytes_sent += status;
-
- /* If we've sent the entire packet, immediately
- * reset the count of bytes sent. */
- if (req->rq_bytes_sent >= req->rq_slen) {
- req->rq_bytes_sent = 0;
- goto out_receive;
- }
- } else {
- if (status >= req->rq_slen)
- goto out_receive;
- status = -EAGAIN;
- break;
- }
-
- dprintk("RPC: %4d xmit incomplete (%d left of %d)\n",
- task->tk_pid, req->rq_slen - req->rq_bytes_sent,
- req->rq_slen);
-
- status = -EAGAIN;
- if (retry++ > 50)
- break;
+ status = xprt->ops->send_request(task);
+ if (status == 0) {
+ dprintk("RPC: %4d xmit complete\n", task->tk_pid);
+ spin_lock_bh(&xprt->transport_lock);
+ xprt->ops->set_retrans_timeout(task);
+ /* Don't race with disconnect */
+ if (!xprt_connected(xprt))
+ task->tk_status = -ENOTCONN;
+ else if (!req->rq_received)
+ rpc_sleep_on(&xprt->pending, task, NULL, xprt_timer);
+ xprt->ops->release_xprt(xprt, task);
+ spin_unlock_bh(&xprt->transport_lock);
+ return;
}
/* Note: at this point, task->tk_sleeping has not yet been set,
@@ -1289,60 +770,19 @@ xprt_transmit(struct rpc_task *task)
task->tk_status = status;
switch (status) {
- case -EAGAIN:
- if (test_bit(SOCK_ASYNC_NOSPACE, &xprt->sock->flags)) {
- /* Protect against races with xprt_write_space */
- spin_lock_bh(&xprt->sock_lock);
- /* Don't race with disconnect */
- if (!xprt_connected(xprt))
- task->tk_status = -ENOTCONN;
- else if (test_bit(SOCK_NOSPACE, &xprt->sock->flags)) {
- task->tk_timeout = req->rq_timeout;
- rpc_sleep_on(&xprt->pending, task, NULL, NULL);
- }
- spin_unlock_bh(&xprt->sock_lock);
- return;
- }
- /* Keep holding the socket if it is blocked */
- rpc_delay(task, HZ>>4);
- return;
case -ECONNREFUSED:
- task->tk_timeout = RPC_REESTABLISH_TIMEOUT;
rpc_sleep_on(&xprt->sending, task, NULL, NULL);
+ case -EAGAIN:
case -ENOTCONN:
return;
default:
- if (xprt->stream)
- xprt_disconnect(xprt);
+ break;
}
xprt_release_write(xprt, task);
return;
- out_receive:
- dprintk("RPC: %4d xmit complete\n", task->tk_pid);
- /* Set the task's receive timeout value */
- spin_lock_bh(&xprt->sock_lock);
- if (!xprt->nocong) {
- int timer = task->tk_msg.rpc_proc->p_timer;
- task->tk_timeout = rpc_calc_rto(clnt->cl_rtt, timer);
- task->tk_timeout <<= rpc_ntimeo(clnt->cl_rtt, timer) + req->rq_retries;
- if (task->tk_timeout > xprt->timeout.to_maxval || task->tk_timeout == 0)
- task->tk_timeout = xprt->timeout.to_maxval;
- } else
- task->tk_timeout = req->rq_timeout;
- /* Don't race with disconnect */
- if (!xprt_connected(xprt))
- task->tk_status = -ENOTCONN;
- else if (!req->rq_received)
- rpc_sleep_on(&xprt->pending, task, NULL, xprt_timer);
- __xprt_release_write(xprt, task);
- spin_unlock_bh(&xprt->sock_lock);
}
-/*
- * Reserve an RPC call slot.
- */
-static inline void
-do_xprt_reserve(struct rpc_task *task)
+static inline void do_xprt_reserve(struct rpc_task *task)
{
struct rpc_xprt *xprt = task->tk_xprt;
@@ -1362,22 +802,25 @@ do_xprt_reserve(struct rpc_task *task)
rpc_sleep_on(&xprt->backlog, task, NULL, NULL);
}
-void
-xprt_reserve(struct rpc_task *task)
+/**
+ * xprt_reserve - allocate an RPC request slot
+ * @task: RPC task requesting a slot allocation
+ *
+ * If no more slots are available, place the task on the transport's
+ * backlog queue.
+ */
+void xprt_reserve(struct rpc_task *task)
{
struct rpc_xprt *xprt = task->tk_xprt;
task->tk_status = -EIO;
if (!xprt->shutdown) {
- spin_lock(&xprt->xprt_lock);
+ spin_lock(&xprt->reserve_lock);
do_xprt_reserve(task);
- spin_unlock(&xprt->xprt_lock);
+ spin_unlock(&xprt->reserve_lock);
}
}
-/*
- * Allocate a 'unique' XID
- */
static inline u32 xprt_alloc_xid(struct rpc_xprt *xprt)
{
return xprt->xid++;
@@ -1388,11 +831,7 @@ static inline void xprt_init_xid(struct rpc_xprt *xprt)
get_random_bytes(&xprt->xid, sizeof(xprt->xid));
}
-/*
- * Initialize RPC request
- */
-static void
-xprt_request_init(struct rpc_task *task, struct rpc_xprt *xprt)
+static void xprt_request_init(struct rpc_task *task, struct rpc_xprt *xprt)
{
struct rpc_rqst *req = task->tk_rqstp;
@@ -1400,128 +839,104 @@ xprt_request_init(struct rpc_task *task, struct rpc_xprt *xprt)
req->rq_task = task;
req->rq_xprt = xprt;
req->rq_xid = xprt_alloc_xid(xprt);
+ req->rq_release_snd_buf = NULL;
dprintk("RPC: %4d reserved req %p xid %08x\n", task->tk_pid,
req, ntohl(req->rq_xid));
}
-/*
- * Release an RPC call slot
+/**
+ * xprt_release - release an RPC request slot
+ * @task: task which is finished with the slot
+ *
*/
-void
-xprt_release(struct rpc_task *task)
+void xprt_release(struct rpc_task *task)
{
struct rpc_xprt *xprt = task->tk_xprt;
struct rpc_rqst *req;
if (!(req = task->tk_rqstp))
return;
- spin_lock_bh(&xprt->sock_lock);
- __xprt_release_write(xprt, task);
- __xprt_put_cong(xprt, req);
+ spin_lock_bh(&xprt->transport_lock);
+ xprt->ops->release_xprt(xprt, task);
+ if (xprt->ops->release_request)
+ xprt->ops->release_request(task);
if (!list_empty(&req->rq_list))
list_del(&req->rq_list);
xprt->last_used = jiffies;
if (list_empty(&xprt->recv) && !xprt->shutdown)
- mod_timer(&xprt->timer, xprt->last_used + XPRT_IDLE_TIMEOUT);
- spin_unlock_bh(&xprt->sock_lock);
+ mod_timer(&xprt->timer,
+ xprt->last_used + xprt->idle_timeout);
+ spin_unlock_bh(&xprt->transport_lock);
task->tk_rqstp = NULL;
+ if (req->rq_release_snd_buf)
+ req->rq_release_snd_buf(req);
memset(req, 0, sizeof(*req)); /* mark unused */
dprintk("RPC: %4d release request %p\n", task->tk_pid, req);
- spin_lock(&xprt->xprt_lock);
+ spin_lock(&xprt->reserve_lock);
list_add(&req->rq_list, &xprt->free);
- xprt_clear_backlog(xprt);
- spin_unlock(&xprt->xprt_lock);
-}
-
-/*
- * Set default timeout parameters
- */
-static void
-xprt_default_timeout(struct rpc_timeout *to, int proto)
-{
- if (proto == IPPROTO_UDP)
- xprt_set_timeout(to, 5, 5 * HZ);
- else
- xprt_set_timeout(to, 5, 60 * HZ);
+ rpc_wake_up_next(&xprt->backlog);
+ spin_unlock(&xprt->reserve_lock);
}
-/*
- * Set constant timeout
+/**
+ * xprt_set_timeout - set constant RPC timeout
+ * @to: RPC timeout parameters to set up
+ * @retr: number of retries
+ * @incr: amount of increase after each retry
+ *
*/
-void
-xprt_set_timeout(struct rpc_timeout *to, unsigned int retr, unsigned long incr)
+void xprt_set_timeout(struct rpc_timeout *to, unsigned int retr, unsigned long incr)
{
to->to_initval =
to->to_increment = incr;
- to->to_maxval = incr * retr;
+ to->to_maxval = to->to_initval + (incr * retr);
to->to_retries = retr;
to->to_exponential = 0;
}
-unsigned int xprt_udp_slot_table_entries = RPC_DEF_SLOT_TABLE;
-unsigned int xprt_tcp_slot_table_entries = RPC_DEF_SLOT_TABLE;
-
-/*
- * Initialize an RPC client
- */
-static struct rpc_xprt *
-xprt_setup(int proto, struct sockaddr_in *ap, struct rpc_timeout *to)
+static struct rpc_xprt *xprt_setup(int proto, struct sockaddr_in *ap, struct rpc_timeout *to)
{
+ int result;
struct rpc_xprt *xprt;
- unsigned int entries;
- size_t slot_table_size;
struct rpc_rqst *req;
- dprintk("RPC: setting up %s transport...\n",
- proto == IPPROTO_UDP? "UDP" : "TCP");
-
- entries = (proto == IPPROTO_TCP)?
- xprt_tcp_slot_table_entries : xprt_udp_slot_table_entries;
-
if ((xprt = kmalloc(sizeof(struct rpc_xprt), GFP_KERNEL)) == NULL)
return ERR_PTR(-ENOMEM);
memset(xprt, 0, sizeof(*xprt)); /* Nnnngh! */
- xprt->max_reqs = entries;
- slot_table_size = entries * sizeof(xprt->slot[0]);
- xprt->slot = kmalloc(slot_table_size, GFP_KERNEL);
- if (xprt->slot == NULL) {
- kfree(xprt);
- return ERR_PTR(-ENOMEM);
- }
- memset(xprt->slot, 0, slot_table_size);
xprt->addr = *ap;
- xprt->prot = proto;
- xprt->stream = (proto == IPPROTO_TCP)? 1 : 0;
- if (xprt->stream) {
- xprt->cwnd = RPC_MAXCWND(xprt);
- xprt->nocong = 1;
- xprt->max_payload = (1U << 31) - 1;
- } else {
- xprt->cwnd = RPC_INITCWND;
- xprt->max_payload = (1U << 16) - (MAX_HEADER << 3);
+
+ switch (proto) {
+ case IPPROTO_UDP:
+ result = xs_setup_udp(xprt, to);
+ break;
+ case IPPROTO_TCP:
+ result = xs_setup_tcp(xprt, to);
+ break;
+ default:
+ printk(KERN_ERR "RPC: unrecognized transport protocol: %d\n",
+ proto);
+ result = -EIO;
+ break;
+ }
+ if (result) {
+ kfree(xprt);
+ return ERR_PTR(result);
}
- spin_lock_init(&xprt->sock_lock);
- spin_lock_init(&xprt->xprt_lock);
- init_waitqueue_head(&xprt->cong_wait);
+
+ spin_lock_init(&xprt->transport_lock);
+ spin_lock_init(&xprt->reserve_lock);
INIT_LIST_HEAD(&xprt->free);
INIT_LIST_HEAD(&xprt->recv);
- INIT_WORK(&xprt->sock_connect, xprt_socket_connect, xprt);
- INIT_WORK(&xprt->task_cleanup, xprt_socket_autoclose, xprt);
+ INIT_WORK(&xprt->task_cleanup, xprt_autoclose, xprt);
init_timer(&xprt->timer);
xprt->timer.function = xprt_init_autodisconnect;
xprt->timer.data = (unsigned long) xprt;
xprt->last_used = jiffies;
- xprt->port = XPRT_MAX_RESVPORT;
-
- /* Set timeout parameters */
- if (to) {
- xprt->timeout = *to;
- } else
- xprt_default_timeout(&xprt->timeout, xprt->prot);
+ xprt->cwnd = RPC_INITCWND;
rpc_init_wait_queue(&xprt->pending, "xprt_pending");
rpc_init_wait_queue(&xprt->sending, "xprt_sending");
@@ -1529,139 +944,25 @@ xprt_setup(int proto, struct sockaddr_in *ap, struct rpc_timeout *to)
rpc_init_priority_wait_queue(&xprt->backlog, "xprt_backlog");
/* initialize free list */
- for (req = &xprt->slot[entries-1]; req >= &xprt->slot[0]; req--)
+ for (req = &xprt->slot[xprt->max_reqs-1]; req >= &xprt->slot[0]; req--)
list_add(&req->rq_list, &xprt->free);
xprt_init_xid(xprt);
- /* Check whether we want to use a reserved port */
- xprt->resvport = capable(CAP_NET_BIND_SERVICE) ? 1 : 0;
-
dprintk("RPC: created transport %p with %u slots\n", xprt,
xprt->max_reqs);
return xprt;
}
-/*
- * Bind to a reserved port
- */
-static inline int xprt_bindresvport(struct rpc_xprt *xprt, struct socket *sock)
-{
- struct sockaddr_in myaddr = {
- .sin_family = AF_INET,
- };
- int err, port;
-
- /* Were we already bound to a given port? Try to reuse it */
- port = xprt->port;
- do {
- myaddr.sin_port = htons(port);
- err = sock->ops->bind(sock, (struct sockaddr *) &myaddr,
- sizeof(myaddr));
- if (err == 0) {
- xprt->port = port;
- return 0;
- }
- if (--port == 0)
- port = XPRT_MAX_RESVPORT;
- } while (err == -EADDRINUSE && port != xprt->port);
-
- printk("RPC: Can't bind to reserved port (%d).\n", -err);
- return err;
-}
-
-static void
-xprt_bind_socket(struct rpc_xprt *xprt, struct socket *sock)
-{
- struct sock *sk = sock->sk;
-
- if (xprt->inet)
- return;
-
- write_lock_bh(&sk->sk_callback_lock);
- sk->sk_user_data = xprt;
- xprt->old_data_ready = sk->sk_data_ready;
- xprt->old_state_change = sk->sk_state_change;
- xprt->old_write_space = sk->sk_write_space;
- if (xprt->prot == IPPROTO_UDP) {
- sk->sk_data_ready = udp_data_ready;
- sk->sk_no_check = UDP_CSUM_NORCV;
- xprt_set_connected(xprt);
- } else {
- tcp_sk(sk)->nonagle = 1; /* disable Nagle's algorithm */
- sk->sk_data_ready = tcp_data_ready;
- sk->sk_state_change = tcp_state_change;
- xprt_clear_connected(xprt);
- }
- sk->sk_write_space = xprt_write_space;
-
- /* Reset to new socket */
- xprt->sock = sock;
- xprt->inet = sk;
- write_unlock_bh(&sk->sk_callback_lock);
-
- return;
-}
-
-/*
- * Set socket buffer length
- */
-void
-xprt_sock_setbufsize(struct rpc_xprt *xprt)
-{
- struct sock *sk = xprt->inet;
-
- if (xprt->stream)
- return;
- if (xprt->rcvsize) {
- sk->sk_userlocks |= SOCK_RCVBUF_LOCK;
- sk->sk_rcvbuf = xprt->rcvsize * xprt->max_reqs * 2;
- }
- if (xprt->sndsize) {
- sk->sk_userlocks |= SOCK_SNDBUF_LOCK;
- sk->sk_sndbuf = xprt->sndsize * xprt->max_reqs * 2;
- sk->sk_write_space(sk);
- }
-}
-
-/*
- * Datastream sockets are created here, but xprt_connect will create
- * and connect stream sockets.
- */
-static struct socket * xprt_create_socket(struct rpc_xprt *xprt, int proto, int resvport)
-{
- struct socket *sock;
- int type, err;
-
- dprintk("RPC: xprt_create_socket(%s %d)\n",
- (proto == IPPROTO_UDP)? "udp" : "tcp", proto);
-
- type = (proto == IPPROTO_UDP)? SOCK_DGRAM : SOCK_STREAM;
-
- if ((err = sock_create_kern(PF_INET, type, proto, &sock)) < 0) {
- printk("RPC: can't create socket (%d).\n", -err);
- return NULL;
- }
-
- /* If the caller has the capability, bind to a reserved port */
- if (resvport && xprt_bindresvport(xprt, sock) < 0) {
- printk("RPC: can't bind to reserved port.\n");
- goto failed;
- }
-
- return sock;
-
-failed:
- sock_release(sock);
- return NULL;
-}
-
-/*
- * Create an RPC client transport given the protocol and peer address.
+/**
+ * xprt_create_proto - create an RPC client transport
+ * @proto: requested transport protocol
+ * @sap: remote peer's address
+ * @to: timeout parameters for new transport
+ *
*/
-struct rpc_xprt *
-xprt_create_proto(int proto, struct sockaddr_in *sap, struct rpc_timeout *to)
+struct rpc_xprt *xprt_create_proto(int proto, struct sockaddr_in *sap, struct rpc_timeout *to)
{
struct rpc_xprt *xprt;
@@ -1673,46 +974,26 @@ xprt_create_proto(int proto, struct sockaddr_in *sap, struct rpc_timeout *to)
return xprt;
}
-/*
- * Prepare for transport shutdown.
- */
-static void
-xprt_shutdown(struct rpc_xprt *xprt)
+static void xprt_shutdown(struct rpc_xprt *xprt)
{
xprt->shutdown = 1;
rpc_wake_up(&xprt->sending);
rpc_wake_up(&xprt->resend);
- rpc_wake_up(&xprt->pending);
+ xprt_wake_pending_tasks(xprt, -EIO);
rpc_wake_up(&xprt->backlog);
- wake_up(&xprt->cong_wait);
del_timer_sync(&xprt->timer);
-
- /* synchronously wait for connect worker to finish */
- cancel_delayed_work(&xprt->sock_connect);
- flush_scheduled_work();
}
-/*
- * Clear the xprt backlog queue
- */
-static int
-xprt_clear_backlog(struct rpc_xprt *xprt) {
- rpc_wake_up_next(&xprt->backlog);
- wake_up(&xprt->cong_wait);
- return 1;
-}
-
-/*
- * Destroy an RPC transport, killing off all requests.
+/**
+ * xprt_destroy - destroy an RPC transport, killing off all requests.
+ * @xprt: transport to destroy
+ *
*/
-int
-xprt_destroy(struct rpc_xprt *xprt)
+int xprt_destroy(struct rpc_xprt *xprt)
{
dprintk("RPC: destroying transport %p\n", xprt);
xprt_shutdown(xprt);
- xprt_disconnect(xprt);
- xprt_close(xprt);
- kfree(xprt->slot);
+ xprt->ops->destroy(xprt);
kfree(xprt);
return 0;
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
new file mode 100644
index 000000000000..0a51fd46a848
--- /dev/null
+++ b/net/sunrpc/xprtsock.c
@@ -0,0 +1,1261 @@
+/*
+ * linux/net/sunrpc/xprtsock.c
+ *
+ * Client-side transport implementation for sockets.
+ *
+ * TCP callback races fixes (C) 1998 Red Hat Software <alan@redhat.com>
+ * TCP send fixes (C) 1998 Red Hat Software <alan@redhat.com>
+ * TCP NFS related read + write fixes
+ * (C) 1999 Dave Airlie, University of Limerick, Ireland <airlied@linux.ie>
+ *
+ * Rewrite of larges part of the code in order to stabilize TCP stuff.
+ * Fix behaviour when socket buffer is full.
+ * (C) 1999 Trond Myklebust <trond.myklebust@fys.uio.no>
+ *
+ * IP socket transport implementation, (C) 2005 Chuck Lever <cel@netapp.com>
+ */
+
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/capability.h>
+#include <linux/sched.h>
+#include <linux/pagemap.h>
+#include <linux/errno.h>
+#include <linux/socket.h>
+#include <linux/in.h>
+#include <linux/net.h>
+#include <linux/mm.h>
+#include <linux/udp.h>
+#include <linux/tcp.h>
+#include <linux/sunrpc/clnt.h>
+#include <linux/file.h>
+
+#include <net/sock.h>
+#include <net/checksum.h>
+#include <net/udp.h>
+#include <net/tcp.h>
+
+/*
+ * xprtsock tunables
+ */
+unsigned int xprt_udp_slot_table_entries = RPC_DEF_SLOT_TABLE;
+unsigned int xprt_tcp_slot_table_entries = RPC_DEF_SLOT_TABLE;
+
+unsigned int xprt_min_resvport = RPC_DEF_MIN_RESVPORT;
+unsigned int xprt_max_resvport = RPC_DEF_MAX_RESVPORT;
+
+/*
+ * How many times to try sending a request on a socket before waiting
+ * for the socket buffer to clear.
+ */
+#define XS_SENDMSG_RETRY (10U)
+
+/*
+ * Time out for an RPC UDP socket connect. UDP socket connects are
+ * synchronous, but we set a timeout anyway in case of resource
+ * exhaustion on the local host.
+ */
+#define XS_UDP_CONN_TO (5U * HZ)
+
+/*
+ * Wait duration for an RPC TCP connection to be established. Solaris
+ * NFS over TCP uses 60 seconds, for example, which is in line with how
+ * long a server takes to reboot.
+ */
+#define XS_TCP_CONN_TO (60U * HZ)
+
+/*
+ * Wait duration for a reply from the RPC portmapper.
+ */
+#define XS_BIND_TO (60U * HZ)
+
+/*
+ * Delay if a UDP socket connect error occurs. This is most likely some
+ * kind of resource problem on the local host.
+ */
+#define XS_UDP_REEST_TO (2U * HZ)
+
+/*
+ * The reestablish timeout allows clients to delay for a bit before attempting
+ * to reconnect to a server that just dropped our connection.
+ *
+ * We implement an exponential backoff when trying to reestablish a TCP
+ * transport connection with the server. Some servers like to drop a TCP
+ * connection when they are overworked, so we start with a short timeout and
+ * increase over time if the server is down or not responding.
+ */
+#define XS_TCP_INIT_REEST_TO (3U * HZ)
+#define XS_TCP_MAX_REEST_TO (5U * 60 * HZ)
+
+/*
+ * TCP idle timeout; client drops the transport socket if it is idle
+ * for this long. Note that we also timeout UDP sockets to prevent
+ * holding port numbers when there is no RPC traffic.
+ */
+#define XS_IDLE_DISC_TO (5U * 60 * HZ)
+
+#ifdef RPC_DEBUG
+# undef RPC_DEBUG_DATA
+# define RPCDBG_FACILITY RPCDBG_TRANS
+#endif
+
+#ifdef RPC_DEBUG_DATA
+static void xs_pktdump(char *msg, u32 *packet, unsigned int count)
+{
+ u8 *buf = (u8 *) packet;
+ int j;
+
+ dprintk("RPC: %s\n", msg);
+ for (j = 0; j < count && j < 128; j += 4) {
+ if (!(j & 31)) {
+ if (j)
+ dprintk("\n");
+ dprintk("0x%04x ", j);
+ }
+ dprintk("%02x%02x%02x%02x ",
+ buf[j], buf[j+1], buf[j+2], buf[j+3]);
+ }
+ dprintk("\n");
+}
+#else
+static inline void xs_pktdump(char *msg, u32 *packet, unsigned int count)
+{
+ /* NOP */
+}
+#endif
+
+#define XS_SENDMSG_FLAGS (MSG_DONTWAIT | MSG_NOSIGNAL)
+
+static inline int xs_send_head(struct socket *sock, struct sockaddr *addr, int addrlen, struct xdr_buf *xdr, unsigned int base, unsigned int len)
+{
+ struct kvec iov = {
+ .iov_base = xdr->head[0].iov_base + base,
+ .iov_len = len - base,
+ };
+ struct msghdr msg = {
+ .msg_name = addr,
+ .msg_namelen = addrlen,
+ .msg_flags = XS_SENDMSG_FLAGS,
+ };
+
+ if (xdr->len > len)
+ msg.msg_flags |= MSG_MORE;
+
+ if (likely(iov.iov_len))
+ return kernel_sendmsg(sock, &msg, &iov, 1, iov.iov_len);
+ return kernel_sendmsg(sock, &msg, NULL, 0, 0);
+}
+
+static int xs_send_tail(struct socket *sock, struct xdr_buf *xdr, unsigned int base, unsigned int len)
+{
+ struct kvec iov = {
+ .iov_base = xdr->tail[0].iov_base + base,
+ .iov_len = len - base,
+ };
+ struct msghdr msg = {
+ .msg_flags = XS_SENDMSG_FLAGS,
+ };
+
+ return kernel_sendmsg(sock, &msg, &iov, 1, iov.iov_len);
+}
+
+/**
+ * xs_sendpages - write pages directly to a socket
+ * @sock: socket to send on
+ * @addr: UDP only -- address of destination
+ * @addrlen: UDP only -- length of destination address
+ * @xdr: buffer containing this request
+ * @base: starting position in the buffer
+ *
+ */
+static inline int xs_sendpages(struct socket *sock, struct sockaddr *addr, int addrlen, struct xdr_buf *xdr, unsigned int base)
+{
+ struct page **ppage = xdr->pages;
+ unsigned int len, pglen = xdr->page_len;
+ int err, ret = 0;
+ ssize_t (*sendpage)(struct socket *, struct page *, int, size_t, int);
+
+ if (unlikely(!sock))
+ return -ENOTCONN;
+
+ clear_bit(SOCK_ASYNC_NOSPACE, &sock->flags);
+
+ len = xdr->head[0].iov_len;
+ if (base < len || (addr != NULL && base == 0)) {
+ err = xs_send_head(sock, addr, addrlen, xdr, base, len);
+ if (ret == 0)
+ ret = err;
+ else if (err > 0)
+ ret += err;
+ if (err != (len - base))
+ goto out;
+ base = 0;
+ } else
+ base -= len;
+
+ if (unlikely(pglen == 0))
+ goto copy_tail;
+ if (unlikely(base >= pglen)) {
+ base -= pglen;
+ goto copy_tail;
+ }
+ if (base || xdr->page_base) {
+ pglen -= base;
+ base += xdr->page_base;
+ ppage += base >> PAGE_CACHE_SHIFT;
+ base &= ~PAGE_CACHE_MASK;
+ }
+
+ sendpage = sock->ops->sendpage ? : sock_no_sendpage;
+ do {
+ int flags = XS_SENDMSG_FLAGS;
+
+ len = PAGE_CACHE_SIZE;
+ if (base)
+ len -= base;
+ if (pglen < len)
+ len = pglen;
+
+ if (pglen != len || xdr->tail[0].iov_len != 0)
+ flags |= MSG_MORE;
+
+ /* Hmm... We might be dealing with highmem pages */
+ if (PageHighMem(*ppage))
+ sendpage = sock_no_sendpage;
+ err = sendpage(sock, *ppage, base, len, flags);
+ if (ret == 0)
+ ret = err;
+ else if (err > 0)
+ ret += err;
+ if (err != len)
+ goto out;
+ base = 0;
+ ppage++;
+ } while ((pglen -= len) != 0);
+copy_tail:
+ len = xdr->tail[0].iov_len;
+ if (base < len) {
+ err = xs_send_tail(sock, xdr, base, len);
+ if (ret == 0)
+ ret = err;
+ else if (err > 0)
+ ret += err;
+ }
+out:
+ return ret;
+}
+
+/**
+ * xs_nospace - place task on wait queue if transmit was incomplete
+ * @task: task to put to sleep
+ *
+ */
+static void xs_nospace(struct rpc_task *task)
+{
+ struct rpc_rqst *req = task->tk_rqstp;
+ struct rpc_xprt *xprt = req->rq_xprt;
+
+ dprintk("RPC: %4d xmit incomplete (%u left of %u)\n",
+ task->tk_pid, req->rq_slen - req->rq_bytes_sent,
+ req->rq_slen);
+
+ if (test_bit(SOCK_ASYNC_NOSPACE, &xprt->sock->flags)) {
+ /* Protect against races with write_space */
+ spin_lock_bh(&xprt->transport_lock);
+
+ /* Don't race with disconnect */
+ if (!xprt_connected(xprt))
+ task->tk_status = -ENOTCONN;
+ else if (test_bit(SOCK_NOSPACE, &xprt->sock->flags))
+ xprt_wait_for_buffer_space(task);
+
+ spin_unlock_bh(&xprt->transport_lock);
+ } else
+ /* Keep holding the socket if it is blocked */
+ rpc_delay(task, HZ>>4);
+}
+
+/**
+ * xs_udp_send_request - write an RPC request to a UDP socket
+ * @task: address of RPC task that manages the state of an RPC request
+ *
+ * Return values:
+ * 0: The request has been sent
+ * EAGAIN: The socket was blocked, please call again later to
+ * complete the request
+ * ENOTCONN: Caller needs to invoke connect logic then call again
+ * other: Some other error occured, the request was not sent
+ */
+static int xs_udp_send_request(struct rpc_task *task)
+{
+ struct rpc_rqst *req = task->tk_rqstp;
+ struct rpc_xprt *xprt = req->rq_xprt;
+ struct xdr_buf *xdr = &req->rq_snd_buf;
+ int status;
+
+ xs_pktdump("packet data:",
+ req->rq_svec->iov_base,
+ req->rq_svec->iov_len);
+
+ req->rq_xtime = jiffies;
+ status = xs_sendpages(xprt->sock, (struct sockaddr *) &xprt->addr,
+ sizeof(xprt->addr), xdr, req->rq_bytes_sent);
+
+ dprintk("RPC: xs_udp_send_request(%u) = %d\n",
+ xdr->len - req->rq_bytes_sent, status);
+
+ if (likely(status >= (int) req->rq_slen))
+ return 0;
+
+ /* Still some bytes left; set up for a retry later. */
+ if (status > 0)
+ status = -EAGAIN;
+
+ switch (status) {
+ case -ENETUNREACH:
+ case -EPIPE:
+ case -ECONNREFUSED:
+ /* When the server has died, an ICMP port unreachable message
+ * prompts ECONNREFUSED. */
+ break;
+ case -EAGAIN:
+ xs_nospace(task);
+ break;
+ default:
+ dprintk("RPC: sendmsg returned unrecognized error %d\n",
+ -status);
+ break;
+ }
+
+ return status;
+}
+
+static inline void xs_encode_tcp_record_marker(struct xdr_buf *buf)
+{
+ u32 reclen = buf->len - sizeof(rpc_fraghdr);
+ rpc_fraghdr *base = buf->head[0].iov_base;
+ *base = htonl(RPC_LAST_STREAM_FRAGMENT | reclen);
+}
+
+/**
+ * xs_tcp_send_request - write an RPC request to a TCP socket
+ * @task: address of RPC task that manages the state of an RPC request
+ *
+ * Return values:
+ * 0: The request has been sent
+ * EAGAIN: The socket was blocked, please call again later to
+ * complete the request
+ * ENOTCONN: Caller needs to invoke connect logic then call again
+ * other: Some other error occured, the request was not sent
+ *
+ * XXX: In the case of soft timeouts, should we eventually give up
+ * if sendmsg is not able to make progress?
+ */
+static int xs_tcp_send_request(struct rpc_task *task)
+{
+ struct rpc_rqst *req = task->tk_rqstp;
+ struct rpc_xprt *xprt = req->rq_xprt;
+ struct xdr_buf *xdr = &req->rq_snd_buf;
+ int status, retry = 0;
+
+ xs_encode_tcp_record_marker(&req->rq_snd_buf);
+
+ xs_pktdump("packet data:",
+ req->rq_svec->iov_base,
+ req->rq_svec->iov_len);
+
+ /* Continue transmitting the packet/record. We must be careful
+ * to cope with writespace callbacks arriving _after_ we have
+ * called sendmsg(). */
+ while (1) {
+ req->rq_xtime = jiffies;
+ status = xs_sendpages(xprt->sock, NULL, 0, xdr,
+ req->rq_bytes_sent);
+
+ dprintk("RPC: xs_tcp_send_request(%u) = %d\n",
+ xdr->len - req->rq_bytes_sent, status);
+
+ if (unlikely(status < 0))
+ break;
+
+ /* If we've sent the entire packet, immediately
+ * reset the count of bytes sent. */
+ req->rq_bytes_sent += status;
+ if (likely(req->rq_bytes_sent >= req->rq_slen)) {
+ req->rq_bytes_sent = 0;
+ return 0;
+ }
+
+ status = -EAGAIN;
+ if (retry++ > XS_SENDMSG_RETRY)
+ break;
+ }
+
+ switch (status) {
+ case -EAGAIN:
+ xs_nospace(task);
+ break;
+ case -ECONNREFUSED:
+ case -ECONNRESET:
+ case -ENOTCONN:
+ case -EPIPE:
+ status = -ENOTCONN;
+ break;
+ default:
+ dprintk("RPC: sendmsg returned unrecognized error %d\n",
+ -status);
+ xprt_disconnect(xprt);
+ break;
+ }
+
+ return status;
+}
+
+/**
+ * xs_close - close a socket
+ * @xprt: transport
+ *
+ * This is used when all requests are complete; ie, no DRC state remains
+ * on the server we want to save.
+ */
+static void xs_close(struct rpc_xprt *xprt)
+{
+ struct socket *sock = xprt->sock;
+ struct sock *sk = xprt->inet;
+
+ if (!sk)
+ return;
+
+ dprintk("RPC: xs_close xprt %p\n", xprt);
+
+ write_lock_bh(&sk->sk_callback_lock);
+ xprt->inet = NULL;
+ xprt->sock = NULL;
+
+ sk->sk_user_data = NULL;
+ sk->sk_data_ready = xprt->old_data_ready;
+ sk->sk_state_change = xprt->old_state_change;
+ sk->sk_write_space = xprt->old_write_space;
+ write_unlock_bh(&sk->sk_callback_lock);
+
+ sk->sk_no_check = 0;
+
+ sock_release(sock);
+}
+
+/**
+ * xs_destroy - prepare to shutdown a transport
+ * @xprt: doomed transport
+ *
+ */
+static void xs_destroy(struct rpc_xprt *xprt)
+{
+ dprintk("RPC: xs_destroy xprt %p\n", xprt);
+
+ cancel_delayed_work(&xprt->connect_worker);
+ flush_scheduled_work();
+
+ xprt_disconnect(xprt);
+ xs_close(xprt);
+ kfree(xprt->slot);
+}
+
+static inline struct rpc_xprt *xprt_from_sock(struct sock *sk)
+{
+ return (struct rpc_xprt *) sk->sk_user_data;
+}
+
+/**
+ * xs_udp_data_ready - "data ready" callback for UDP sockets
+ * @sk: socket with data to read
+ * @len: how much data to read
+ *
+ */
+static void xs_udp_data_ready(struct sock *sk, int len)
+{
+ struct rpc_task *task;
+ struct rpc_xprt *xprt;
+ struct rpc_rqst *rovr;
+ struct sk_buff *skb;
+ int err, repsize, copied;
+ u32 _xid, *xp;
+
+ read_lock(&sk->sk_callback_lock);
+ dprintk("RPC: xs_udp_data_ready...\n");
+ if (!(xprt = xprt_from_sock(sk)))
+ goto out;
+
+ if ((skb = skb_recv_datagram(sk, 0, 1, &err)) == NULL)
+ goto out;
+
+ if (xprt->shutdown)
+ goto dropit;
+
+ repsize = skb->len - sizeof(struct udphdr);
+ if (repsize < 4) {
+ dprintk("RPC: impossible RPC reply size %d!\n", repsize);
+ goto dropit;
+ }
+
+ /* Copy the XID from the skb... */
+ xp = skb_header_pointer(skb, sizeof(struct udphdr),
+ sizeof(_xid), &_xid);
+ if (xp == NULL)
+ goto dropit;
+
+ /* Look up and lock the request corresponding to the given XID */
+ spin_lock(&xprt->transport_lock);
+ rovr = xprt_lookup_rqst(xprt, *xp);
+ if (!rovr)
+ goto out_unlock;
+ task = rovr->rq_task;
+
+ if ((copied = rovr->rq_private_buf.buflen) > repsize)
+ copied = repsize;
+
+ /* Suck it into the iovec, verify checksum if not done by hw. */
+ if (csum_partial_copy_to_xdr(&rovr->rq_private_buf, skb))
+ goto out_unlock;
+
+ /* Something worked... */
+ dst_confirm(skb->dst);
+
+ xprt_adjust_cwnd(task, copied);
+ xprt_update_rtt(task);
+ xprt_complete_rqst(task, copied);
+
+ out_unlock:
+ spin_unlock(&xprt->transport_lock);
+ dropit:
+ skb_free_datagram(sk, skb);
+ out:
+ read_unlock(&sk->sk_callback_lock);
+}
+
+static inline size_t xs_tcp_copy_data(skb_reader_t *desc, void *p, size_t len)
+{
+ if (len > desc->count)
+ len = desc->count;
+ if (skb_copy_bits(desc->skb, desc->offset, p, len)) {
+ dprintk("RPC: failed to copy %zu bytes from skb. %zu bytes remain\n",
+ len, desc->count);
+ return 0;
+ }
+ desc->offset += len;
+ desc->count -= len;
+ dprintk("RPC: copied %zu bytes from skb. %zu bytes remain\n",
+ len, desc->count);
+ return len;
+}
+
+static inline void xs_tcp_read_fraghdr(struct rpc_xprt *xprt, skb_reader_t *desc)
+{
+ size_t len, used;
+ char *p;
+
+ p = ((char *) &xprt->tcp_recm) + xprt->tcp_offset;
+ len = sizeof(xprt->tcp_recm) - xprt->tcp_offset;
+ used = xs_tcp_copy_data(desc, p, len);
+ xprt->tcp_offset += used;
+ if (used != len)
+ return;
+
+ xprt->tcp_reclen = ntohl(xprt->tcp_recm);
+ if (xprt->tcp_reclen & RPC_LAST_STREAM_FRAGMENT)
+ xprt->tcp_flags |= XPRT_LAST_FRAG;
+ else
+ xprt->tcp_flags &= ~XPRT_LAST_FRAG;
+ xprt->tcp_reclen &= RPC_FRAGMENT_SIZE_MASK;
+
+ xprt->tcp_flags &= ~XPRT_COPY_RECM;
+ xprt->tcp_offset = 0;
+
+ /* Sanity check of the record length */
+ if (unlikely(xprt->tcp_reclen < 4)) {
+ dprintk("RPC: invalid TCP record fragment length\n");
+ xprt_disconnect(xprt);
+ return;
+ }
+ dprintk("RPC: reading TCP record fragment of length %d\n",
+ xprt->tcp_reclen);
+}
+
+static void xs_tcp_check_recm(struct rpc_xprt *xprt)
+{
+ dprintk("RPC: xprt = %p, tcp_copied = %lu, tcp_offset = %u, tcp_reclen = %u, tcp_flags = %lx\n",
+ xprt, xprt->tcp_copied, xprt->tcp_offset, xprt->tcp_reclen, xprt->tcp_flags);
+ if (xprt->tcp_offset == xprt->tcp_reclen) {
+ xprt->tcp_flags |= XPRT_COPY_RECM;
+ xprt->tcp_offset = 0;
+ if (xprt->tcp_flags & XPRT_LAST_FRAG) {
+ xprt->tcp_flags &= ~XPRT_COPY_DATA;
+ xprt->tcp_flags |= XPRT_COPY_XID;
+ xprt->tcp_copied = 0;
+ }
+ }
+}
+
+static inline void xs_tcp_read_xid(struct rpc_xprt *xprt, skb_reader_t *desc)
+{
+ size_t len, used;
+ char *p;
+
+ len = sizeof(xprt->tcp_xid) - xprt->tcp_offset;
+ dprintk("RPC: reading XID (%Zu bytes)\n", len);
+ p = ((char *) &xprt->tcp_xid) + xprt->tcp_offset;
+ used = xs_tcp_copy_data(desc, p, len);
+ xprt->tcp_offset += used;
+ if (used != len)
+ return;
+ xprt->tcp_flags &= ~XPRT_COPY_XID;
+ xprt->tcp_flags |= XPRT_COPY_DATA;
+ xprt->tcp_copied = 4;
+ dprintk("RPC: reading reply for XID %08x\n",
+ ntohl(xprt->tcp_xid));
+ xs_tcp_check_recm(xprt);
+}
+
+static inline void xs_tcp_read_request(struct rpc_xprt *xprt, skb_reader_t *desc)
+{
+ struct rpc_rqst *req;
+ struct xdr_buf *rcvbuf;
+ size_t len;
+ ssize_t r;
+
+ /* Find and lock the request corresponding to this xid */
+ spin_lock(&xprt->transport_lock);
+ req = xprt_lookup_rqst(xprt, xprt->tcp_xid);
+ if (!req) {
+ xprt->tcp_flags &= ~XPRT_COPY_DATA;
+ dprintk("RPC: XID %08x request not found!\n",
+ ntohl(xprt->tcp_xid));
+ spin_unlock(&xprt->transport_lock);
+ return;
+ }
+
+ rcvbuf = &req->rq_private_buf;
+ len = desc->count;
+ if (len > xprt->tcp_reclen - xprt->tcp_offset) {
+ skb_reader_t my_desc;
+
+ len = xprt->tcp_reclen - xprt->tcp_offset;
+ memcpy(&my_desc, desc, sizeof(my_desc));
+ my_desc.count = len;
+ r = xdr_partial_copy_from_skb(rcvbuf, xprt->tcp_copied,
+ &my_desc, xs_tcp_copy_data);
+ desc->count -= r;
+ desc->offset += r;
+ } else
+ r = xdr_partial_copy_from_skb(rcvbuf, xprt->tcp_copied,
+ desc, xs_tcp_copy_data);
+
+ if (r > 0) {
+ xprt->tcp_copied += r;
+ xprt->tcp_offset += r;
+ }
+ if (r != len) {
+ /* Error when copying to the receive buffer,
+ * usually because we weren't able to allocate
+ * additional buffer pages. All we can do now
+ * is turn off XPRT_COPY_DATA, so the request
+ * will not receive any additional updates,
+ * and time out.
+ * Any remaining data from this record will
+ * be discarded.
+ */
+ xprt->tcp_flags &= ~XPRT_COPY_DATA;
+ dprintk("RPC: XID %08x truncated request\n",
+ ntohl(xprt->tcp_xid));
+ dprintk("RPC: xprt = %p, tcp_copied = %lu, tcp_offset = %u, tcp_reclen = %u\n",
+ xprt, xprt->tcp_copied, xprt->tcp_offset, xprt->tcp_reclen);
+ goto out;
+ }
+
+ dprintk("RPC: XID %08x read %Zd bytes\n",
+ ntohl(xprt->tcp_xid), r);
+ dprintk("RPC: xprt = %p, tcp_copied = %lu, tcp_offset = %u, tcp_reclen = %u\n",
+ xprt, xprt->tcp_copied, xprt->tcp_offset, xprt->tcp_reclen);
+
+ if (xprt->tcp_copied == req->rq_private_buf.buflen)
+ xprt->tcp_flags &= ~XPRT_COPY_DATA;
+ else if (xprt->tcp_offset == xprt->tcp_reclen) {
+ if (xprt->tcp_flags & XPRT_LAST_FRAG)
+ xprt->tcp_flags &= ~XPRT_COPY_DATA;
+ }
+
+out:
+ if (!(xprt->tcp_flags & XPRT_COPY_DATA))
+ xprt_complete_rqst(req->rq_task, xprt->tcp_copied);
+ spin_unlock(&xprt->transport_lock);
+ xs_tcp_check_recm(xprt);
+}
+
+static inline void xs_tcp_read_discard(struct rpc_xprt *xprt, skb_reader_t *desc)
+{
+ size_t len;
+
+ len = xprt->tcp_reclen - xprt->tcp_offset;
+ if (len > desc->count)
+ len = desc->count;
+ desc->count -= len;
+ desc->offset += len;
+ xprt->tcp_offset += len;
+ dprintk("RPC: discarded %Zu bytes\n", len);
+ xs_tcp_check_recm(xprt);
+}
+
+static int xs_tcp_data_recv(read_descriptor_t *rd_desc, struct sk_buff *skb, unsigned int offset, size_t len)
+{
+ struct rpc_xprt *xprt = rd_desc->arg.data;
+ skb_reader_t desc = {
+ .skb = skb,
+ .offset = offset,
+ .count = len,
+ .csum = 0
+ };
+
+ dprintk("RPC: xs_tcp_data_recv started\n");
+ do {
+ /* Read in a new fragment marker if necessary */
+ /* Can we ever really expect to get completely empty fragments? */
+ if (xprt->tcp_flags & XPRT_COPY_RECM) {
+ xs_tcp_read_fraghdr(xprt, &desc);
+ continue;
+ }
+ /* Read in the xid if necessary */
+ if (xprt->tcp_flags & XPRT_COPY_XID) {
+ xs_tcp_read_xid(xprt, &desc);
+ continue;
+ }
+ /* Read in the request data */
+ if (xprt->tcp_flags & XPRT_COPY_DATA) {
+ xs_tcp_read_request(xprt, &desc);
+ continue;
+ }
+ /* Skip over any trailing bytes on short reads */
+ xs_tcp_read_discard(xprt, &desc);
+ } while (desc.count);
+ dprintk("RPC: xs_tcp_data_recv done\n");
+ return len - desc.count;
+}
+
+/**
+ * xs_tcp_data_ready - "data ready" callback for TCP sockets
+ * @sk: socket with data to read
+ * @bytes: how much data to read
+ *
+ */
+static void xs_tcp_data_ready(struct sock *sk, int bytes)
+{
+ struct rpc_xprt *xprt;
+ read_descriptor_t rd_desc;
+
+ read_lock(&sk->sk_callback_lock);
+ dprintk("RPC: xs_tcp_data_ready...\n");
+ if (!(xprt = xprt_from_sock(sk)))
+ goto out;
+ if (xprt->shutdown)
+ goto out;
+
+ /* We use rd_desc to pass struct xprt to xs_tcp_data_recv */
+ rd_desc.arg.data = xprt;
+ rd_desc.count = 65536;
+ tcp_read_sock(sk, &rd_desc, xs_tcp_data_recv);
+out:
+ read_unlock(&sk->sk_callback_lock);
+}
+
+/**
+ * xs_tcp_state_change - callback to handle TCP socket state changes
+ * @sk: socket whose state has changed
+ *
+ */
+static void xs_tcp_state_change(struct sock *sk)
+{
+ struct rpc_xprt *xprt;
+
+ read_lock(&sk->sk_callback_lock);
+ if (!(xprt = xprt_from_sock(sk)))
+ goto out;
+ dprintk("RPC: xs_tcp_state_change client %p...\n", xprt);
+ dprintk("RPC: state %x conn %d dead %d zapped %d\n",
+ sk->sk_state, xprt_connected(xprt),
+ sock_flag(sk, SOCK_DEAD),
+ sock_flag(sk, SOCK_ZAPPED));
+
+ switch (sk->sk_state) {
+ case TCP_ESTABLISHED:
+ spin_lock_bh(&xprt->transport_lock);
+ if (!xprt_test_and_set_connected(xprt)) {
+ /* Reset TCP record info */
+ xprt->tcp_offset = 0;
+ xprt->tcp_reclen = 0;
+ xprt->tcp_copied = 0;
+ xprt->tcp_flags = XPRT_COPY_RECM | XPRT_COPY_XID;
+ xprt->reestablish_timeout = XS_TCP_INIT_REEST_TO;
+ xprt_wake_pending_tasks(xprt, 0);
+ }
+ spin_unlock_bh(&xprt->transport_lock);
+ break;
+ case TCP_SYN_SENT:
+ case TCP_SYN_RECV:
+ break;
+ default:
+ xprt_disconnect(xprt);
+ break;
+ }
+ out:
+ read_unlock(&sk->sk_callback_lock);
+}
+
+/**
+ * xs_udp_write_space - callback invoked when socket buffer space
+ * becomes available
+ * @sk: socket whose state has changed
+ *
+ * Called when more output buffer space is available for this socket.
+ * We try not to wake our writers until they can make "significant"
+ * progress, otherwise we'll waste resources thrashing kernel_sendmsg
+ * with a bunch of small requests.
+ */
+static void xs_udp_write_space(struct sock *sk)
+{
+ read_lock(&sk->sk_callback_lock);
+
+ /* from net/core/sock.c:sock_def_write_space */
+ if (sock_writeable(sk)) {
+ struct socket *sock;
+ struct rpc_xprt *xprt;
+
+ if (unlikely(!(sock = sk->sk_socket)))
+ goto out;
+ if (unlikely(!(xprt = xprt_from_sock(sk))))
+ goto out;
+ if (unlikely(!test_and_clear_bit(SOCK_NOSPACE, &sock->flags)))
+ goto out;
+
+ xprt_write_space(xprt);
+ }
+
+ out:
+ read_unlock(&sk->sk_callback_lock);
+}
+
+/**
+ * xs_tcp_write_space - callback invoked when socket buffer space
+ * becomes available
+ * @sk: socket whose state has changed
+ *
+ * Called when more output buffer space is available for this socket.
+ * We try not to wake our writers until they can make "significant"
+ * progress, otherwise we'll waste resources thrashing kernel_sendmsg
+ * with a bunch of small requests.
+ */
+static void xs_tcp_write_space(struct sock *sk)
+{
+ read_lock(&sk->sk_callback_lock);
+
+ /* from net/core/stream.c:sk_stream_write_space */
+ if (sk_stream_wspace(sk) >= sk_stream_min_wspace(sk)) {
+ struct socket *sock;
+ struct rpc_xprt *xprt;
+
+ if (unlikely(!(sock = sk->sk_socket)))
+ goto out;
+ if (unlikely(!(xprt = xprt_from_sock(sk))))
+ goto out;
+ if (unlikely(!test_and_clear_bit(SOCK_NOSPACE, &sock->flags)))
+ goto out;
+
+ xprt_write_space(xprt);
+ }
+
+ out:
+ read_unlock(&sk->sk_callback_lock);
+}
+
+static void xs_udp_do_set_buffer_size(struct rpc_xprt *xprt)
+{
+ struct sock *sk = xprt->inet;
+
+ if (xprt->rcvsize) {
+ sk->sk_userlocks |= SOCK_RCVBUF_LOCK;
+ sk->sk_rcvbuf = xprt->rcvsize * xprt->max_reqs * 2;
+ }
+ if (xprt->sndsize) {
+ sk->sk_userlocks |= SOCK_SNDBUF_LOCK;
+ sk->sk_sndbuf = xprt->sndsize * xprt->max_reqs * 2;
+ sk->sk_write_space(sk);
+ }
+}
+
+/**
+ * xs_udp_set_buffer_size - set send and receive limits
+ * @xprt: generic transport
+ * @sndsize: requested size of send buffer, in bytes
+ * @rcvsize: requested size of receive buffer, in bytes
+ *
+ * Set socket send and receive buffer size limits.
+ */
+static void xs_udp_set_buffer_size(struct rpc_xprt *xprt, size_t sndsize, size_t rcvsize)
+{
+ xprt->sndsize = 0;
+ if (sndsize)
+ xprt->sndsize = sndsize + 1024;
+ xprt->rcvsize = 0;
+ if (rcvsize)
+ xprt->rcvsize = rcvsize + 1024;
+
+ xs_udp_do_set_buffer_size(xprt);
+}
+
+/**
+ * xs_udp_timer - called when a retransmit timeout occurs on a UDP transport
+ * @task: task that timed out
+ *
+ * Adjust the congestion window after a retransmit timeout has occurred.
+ */
+static void xs_udp_timer(struct rpc_task *task)
+{
+ xprt_adjust_cwnd(task, -ETIMEDOUT);
+}
+
+static int xs_bindresvport(struct rpc_xprt *xprt, struct socket *sock)
+{
+ struct sockaddr_in myaddr = {
+ .sin_family = AF_INET,
+ };
+ int err;
+ unsigned short port = xprt->port;
+
+ do {
+ myaddr.sin_port = htons(port);
+ err = sock->ops->bind(sock, (struct sockaddr *) &myaddr,
+ sizeof(myaddr));
+ if (err == 0) {
+ xprt->port = port;
+ dprintk("RPC: xs_bindresvport bound to port %u\n",
+ port);
+ return 0;
+ }
+ if (port <= xprt_min_resvport)
+ port = xprt_max_resvport;
+ else
+ port--;
+ } while (err == -EADDRINUSE && port != xprt->port);
+
+ dprintk("RPC: can't bind to reserved port (%d).\n", -err);
+ return err;
+}
+
+/**
+ * xs_udp_connect_worker - set up a UDP socket
+ * @args: RPC transport to connect
+ *
+ * Invoked by a work queue tasklet.
+ */
+static void xs_udp_connect_worker(void *args)
+{
+ struct rpc_xprt *xprt = (struct rpc_xprt *) args;
+ struct socket *sock = xprt->sock;
+ int err, status = -EIO;
+
+ if (xprt->shutdown || xprt->addr.sin_port == 0)
+ goto out;
+
+ dprintk("RPC: xs_udp_connect_worker for xprt %p\n", xprt);
+
+ /* Start by resetting any existing state */
+ xs_close(xprt);
+
+ if ((err = sock_create_kern(PF_INET, SOCK_DGRAM, IPPROTO_UDP, &sock)) < 0) {
+ dprintk("RPC: can't create UDP transport socket (%d).\n", -err);
+ goto out;
+ }
+
+ if (xprt->resvport && xs_bindresvport(xprt, sock) < 0) {
+ sock_release(sock);
+ goto out;
+ }
+
+ if (!xprt->inet) {
+ struct sock *sk = sock->sk;
+
+ write_lock_bh(&sk->sk_callback_lock);
+
+ sk->sk_user_data = xprt;
+ xprt->old_data_ready = sk->sk_data_ready;
+ xprt->old_state_change = sk->sk_state_change;
+ xprt->old_write_space = sk->sk_write_space;
+ sk->sk_data_ready = xs_udp_data_ready;
+ sk->sk_write_space = xs_udp_write_space;
+ sk->sk_no_check = UDP_CSUM_NORCV;
+
+ xprt_set_connected(xprt);
+
+ /* Reset to new socket */
+ xprt->sock = sock;
+ xprt->inet = sk;
+
+ write_unlock_bh(&sk->sk_callback_lock);
+ }
+ xs_udp_do_set_buffer_size(xprt);
+ status = 0;
+out:
+ xprt_wake_pending_tasks(xprt, status);
+ xprt_clear_connecting(xprt);
+}
+
+/*
+ * We need to preserve the port number so the reply cache on the server can
+ * find our cached RPC replies when we get around to reconnecting.
+ */
+static void xs_tcp_reuse_connection(struct rpc_xprt *xprt)
+{
+ int result;
+ struct socket *sock = xprt->sock;
+ struct sockaddr any;
+
+ dprintk("RPC: disconnecting xprt %p to reuse port\n", xprt);
+
+ /*
+ * Disconnect the transport socket by doing a connect operation
+ * with AF_UNSPEC. This should return immediately...
+ */
+ memset(&any, 0, sizeof(any));
+ any.sa_family = AF_UNSPEC;
+ result = sock->ops->connect(sock, &any, sizeof(any), 0);
+ if (result)
+ dprintk("RPC: AF_UNSPEC connect return code %d\n",
+ result);
+}
+
+/**
+ * xs_tcp_connect_worker - connect a TCP socket to a remote endpoint
+ * @args: RPC transport to connect
+ *
+ * Invoked by a work queue tasklet.
+ */
+static void xs_tcp_connect_worker(void *args)
+{
+ struct rpc_xprt *xprt = (struct rpc_xprt *)args;
+ struct socket *sock = xprt->sock;
+ int err, status = -EIO;
+
+ if (xprt->shutdown || xprt->addr.sin_port == 0)
+ goto out;
+
+ dprintk("RPC: xs_tcp_connect_worker for xprt %p\n", xprt);
+
+ if (!xprt->sock) {
+ /* start from scratch */
+ if ((err = sock_create_kern(PF_INET, SOCK_STREAM, IPPROTO_TCP, &sock)) < 0) {
+ dprintk("RPC: can't create TCP transport socket (%d).\n", -err);
+ goto out;
+ }
+
+ if (xprt->resvport && xs_bindresvport(xprt, sock) < 0) {
+ sock_release(sock);
+ goto out;
+ }
+ } else
+ /* "close" the socket, preserving the local port */
+ xs_tcp_reuse_connection(xprt);
+
+ if (!xprt->inet) {
+ struct sock *sk = sock->sk;
+
+ write_lock_bh(&sk->sk_callback_lock);
+
+ sk->sk_user_data = xprt;
+ xprt->old_data_ready = sk->sk_data_ready;
+ xprt->old_state_change = sk->sk_state_change;
+ xprt->old_write_space = sk->sk_write_space;
+ sk->sk_data_ready = xs_tcp_data_ready;
+ sk->sk_state_change = xs_tcp_state_change;
+ sk->sk_write_space = xs_tcp_write_space;
+
+ /* socket options */
+ sk->sk_userlocks |= SOCK_BINDPORT_LOCK;
+ sock_reset_flag(sk, SOCK_LINGER);
+ tcp_sk(sk)->linger2 = 0;
+ tcp_sk(sk)->nonagle |= TCP_NAGLE_OFF;
+
+ xprt_clear_connected(xprt);
+
+ /* Reset to new socket */
+ xprt->sock = sock;
+ xprt->inet = sk;
+
+ write_unlock_bh(&sk->sk_callback_lock);
+ }
+
+ /* Tell the socket layer to start connecting... */
+ status = sock->ops->connect(sock, (struct sockaddr *) &xprt->addr,
+ sizeof(xprt->addr), O_NONBLOCK);
+ dprintk("RPC: %p connect status %d connected %d sock state %d\n",
+ xprt, -status, xprt_connected(xprt), sock->sk->sk_state);
+ if (status < 0) {
+ switch (status) {
+ case -EINPROGRESS:
+ case -EALREADY:
+ goto out_clear;
+ case -ECONNREFUSED:
+ case -ECONNRESET:
+ /* retry with existing socket, after a delay */
+ break;
+ default:
+ /* get rid of existing socket, and retry */
+ xs_close(xprt);
+ break;
+ }
+ }
+out:
+ xprt_wake_pending_tasks(xprt, status);
+out_clear:
+ xprt_clear_connecting(xprt);
+}
+
+/**
+ * xs_connect - connect a socket to a remote endpoint
+ * @task: address of RPC task that manages state of connect request
+ *
+ * TCP: If the remote end dropped the connection, delay reconnecting.
+ *
+ * UDP socket connects are synchronous, but we use a work queue anyway
+ * to guarantee that even unprivileged user processes can set up a
+ * socket on a privileged port.
+ *
+ * If a UDP socket connect fails, the delay behavior here prevents
+ * retry floods (hard mounts).
+ */
+static void xs_connect(struct rpc_task *task)
+{
+ struct rpc_xprt *xprt = task->tk_xprt;
+
+ if (xprt_test_and_set_connecting(xprt))
+ return;
+
+ if (xprt->sock != NULL) {
+ dprintk("RPC: xs_connect delayed xprt %p for %lu seconds\n",
+ xprt, xprt->reestablish_timeout / HZ);
+ schedule_delayed_work(&xprt->connect_worker,
+ xprt->reestablish_timeout);
+ xprt->reestablish_timeout <<= 1;
+ if (xprt->reestablish_timeout > XS_TCP_MAX_REEST_TO)
+ xprt->reestablish_timeout = XS_TCP_MAX_REEST_TO;
+ } else {
+ dprintk("RPC: xs_connect scheduled xprt %p\n", xprt);
+ schedule_work(&xprt->connect_worker);
+
+ /* flush_scheduled_work can sleep... */
+ if (!RPC_IS_ASYNC(task))
+ flush_scheduled_work();
+ }
+}
+
+static struct rpc_xprt_ops xs_udp_ops = {
+ .set_buffer_size = xs_udp_set_buffer_size,
+ .reserve_xprt = xprt_reserve_xprt_cong,
+ .release_xprt = xprt_release_xprt_cong,
+ .connect = xs_connect,
+ .send_request = xs_udp_send_request,
+ .set_retrans_timeout = xprt_set_retrans_timeout_rtt,
+ .timer = xs_udp_timer,
+ .release_request = xprt_release_rqst_cong,
+ .close = xs_close,
+ .destroy = xs_destroy,
+};
+
+static struct rpc_xprt_ops xs_tcp_ops = {
+ .reserve_xprt = xprt_reserve_xprt,
+ .release_xprt = xprt_release_xprt,
+ .connect = xs_connect,
+ .send_request = xs_tcp_send_request,
+ .set_retrans_timeout = xprt_set_retrans_timeout_def,
+ .close = xs_close,
+ .destroy = xs_destroy,
+};
+
+/**
+ * xs_setup_udp - Set up transport to use a UDP socket
+ * @xprt: transport to set up
+ * @to: timeout parameters
+ *
+ */
+int xs_setup_udp(struct rpc_xprt *xprt, struct rpc_timeout *to)
+{
+ size_t slot_table_size;
+
+ dprintk("RPC: setting up udp-ipv4 transport...\n");
+
+ xprt->max_reqs = xprt_udp_slot_table_entries;
+ slot_table_size = xprt->max_reqs * sizeof(xprt->slot[0]);
+ xprt->slot = kmalloc(slot_table_size, GFP_KERNEL);
+ if (xprt->slot == NULL)
+ return -ENOMEM;
+ memset(xprt->slot, 0, slot_table_size);
+
+ xprt->prot = IPPROTO_UDP;
+ xprt->port = xprt_max_resvport;
+ xprt->tsh_size = 0;
+ xprt->resvport = capable(CAP_NET_BIND_SERVICE) ? 1 : 0;
+ /* XXX: header size can vary due to auth type, IPv6, etc. */
+ xprt->max_payload = (1U << 16) - (MAX_HEADER << 3);
+
+ INIT_WORK(&xprt->connect_worker, xs_udp_connect_worker, xprt);
+ xprt->bind_timeout = XS_BIND_TO;
+ xprt->connect_timeout = XS_UDP_CONN_TO;
+ xprt->reestablish_timeout = XS_UDP_REEST_TO;
+ xprt->idle_timeout = XS_IDLE_DISC_TO;
+
+ xprt->ops = &xs_udp_ops;
+
+ if (to)
+ xprt->timeout = *to;
+ else
+ xprt_set_timeout(&xprt->timeout, 5, 5 * HZ);
+
+ return 0;
+}
+
+/**
+ * xs_setup_tcp - Set up transport to use a TCP socket
+ * @xprt: transport to set up
+ * @to: timeout parameters
+ *
+ */
+int xs_setup_tcp(struct rpc_xprt *xprt, struct rpc_timeout *to)
+{
+ size_t slot_table_size;
+
+ dprintk("RPC: setting up tcp-ipv4 transport...\n");
+
+ xprt->max_reqs = xprt_tcp_slot_table_entries;
+ slot_table_size = xprt->max_reqs * sizeof(xprt->slot[0]);
+ xprt->slot = kmalloc(slot_table_size, GFP_KERNEL);
+ if (xprt->slot == NULL)
+ return -ENOMEM;
+ memset(xprt->slot, 0, slot_table_size);
+
+ xprt->prot = IPPROTO_TCP;
+ xprt->port = xprt_max_resvport;
+ xprt->tsh_size = sizeof(rpc_fraghdr) / sizeof(u32);
+ xprt->resvport = capable(CAP_NET_BIND_SERVICE) ? 1 : 0;
+ xprt->max_payload = RPC_MAX_FRAGMENT_SIZE;
+
+ INIT_WORK(&xprt->connect_worker, xs_tcp_connect_worker, xprt);
+ xprt->bind_timeout = XS_BIND_TO;
+ xprt->connect_timeout = XS_TCP_CONN_TO;
+ xprt->reestablish_timeout = XS_TCP_INIT_REEST_TO;
+ xprt->idle_timeout = XS_IDLE_DISC_TO;
+
+ xprt->ops = &xs_tcp_ops;
+
+ if (to)
+ xprt->timeout = *to;
+ else
+ xprt_set_timeout(&xprt->timeout, 2, 60 * HZ);
+
+ return 0;
+}
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index 41feca3bef86..acc73ba8bade 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -676,7 +676,7 @@ static struct sock *unix_find_other(struct sockaddr_un *sunname, int len,
err = path_lookup(sunname->sun_path, LOOKUP_FOLLOW, &nd);
if (err)
goto fail;
- err = permission(nd.dentry->d_inode,MAY_WRITE, &nd);
+ err = vfs_permission(&nd, MAY_WRITE);
if (err)
goto put_fail;
diff --git a/net/wanrouter/af_wanpipe.c b/net/wanrouter/af_wanpipe.c
index 596cb96e5f47..59fec59b2132 100644
--- a/net/wanrouter/af_wanpipe.c
+++ b/net/wanrouter/af_wanpipe.c
@@ -1099,7 +1099,7 @@ static void release_driver(struct sock *sk)
sock_reset_flag(sk, SOCK_ZAPPED);
wp = wp_sk(sk);
- if (wp && wp->mbox) {
+ if (wp) {
kfree(wp->mbox);
wp->mbox = NULL;
}
@@ -1186,10 +1186,8 @@ static void wanpipe_kill_sock_timer (unsigned long data)
return;
}
- if (wp_sk(sk)) {
- kfree(wp_sk(sk));
- wp_sk(sk) = NULL;
- }
+ kfree(wp_sk(sk));
+ wp_sk(sk) = NULL;
if (atomic_read(&sk->sk_refcnt) != 1) {
atomic_set(&sk->sk_refcnt, 1);
@@ -1219,10 +1217,8 @@ static void wanpipe_kill_sock_accept (struct sock *sk)
sk->sk_socket = NULL;
- if (wp_sk(sk)) {
- kfree(wp_sk(sk));
- wp_sk(sk) = NULL;
- }
+ kfree(wp_sk(sk));
+ wp_sk(sk) = NULL;
if (atomic_read(&sk->sk_refcnt) != 1) {
atomic_set(&sk->sk_refcnt, 1);
@@ -1243,10 +1239,8 @@ static void wanpipe_kill_sock_irq (struct sock *sk)
sk->sk_socket = NULL;
- if (wp_sk(sk)) {
- kfree(wp_sk(sk));
- wp_sk(sk) = NULL;
- }
+ kfree(wp_sk(sk));
+ wp_sk(sk) = NULL;
if (atomic_read(&sk->sk_refcnt) != 1) {
atomic_set(&sk->sk_refcnt, 1);
diff --git a/net/wanrouter/wanmain.c b/net/wanrouter/wanmain.c
index 13b650ad22e2..bcf7b3faa76a 100644
--- a/net/wanrouter/wanmain.c
+++ b/net/wanrouter/wanmain.c
@@ -714,10 +714,8 @@ static int wanrouter_device_new_if(struct wan_device *wandev,
}
/* This code has moved from del_if() function */
- if (dev->priv) {
- kfree(dev->priv);
- dev->priv = NULL;
- }
+ kfree(dev->priv);
+ dev->priv = NULL;
#ifdef CONFIG_WANPIPE_MULTPPP
if (cnf->config_id == WANCONFIG_MPPP)
@@ -851,10 +849,8 @@ static int wanrouter_delete_interface(struct wan_device *wandev, char *name)
/* Due to new interface linking method using dev->priv,
* this code has moved from del_if() function.*/
- if (dev->priv){
- kfree(dev->priv);
- dev->priv=NULL;
- }
+ kfree(dev->priv);
+ dev->priv=NULL;
unregister_netdev(dev);
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index cbb0ba34a600..0db9e57013fd 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -1192,46 +1192,6 @@ int xfrm_bundle_ok(struct xfrm_dst *first, struct flowi *fl, int family)
EXPORT_SYMBOL(xfrm_bundle_ok);
-/* Well... that's _TASK_. We need to scan through transformation
- * list and figure out what mss tcp should generate in order to
- * final datagram fit to mtu. Mama mia... :-)
- *
- * Apparently, some easy way exists, but we used to choose the most
- * bizarre ones. :-) So, raising Kalashnikov... tra-ta-ta.
- *
- * Consider this function as something like dark humour. :-)
- */
-static int xfrm_get_mss(struct dst_entry *dst, u32 mtu)
-{
- int res = mtu - dst->header_len;
-
- for (;;) {
- struct dst_entry *d = dst;
- int m = res;
-
- do {
- struct xfrm_state *x = d->xfrm;
- if (x) {
- spin_lock_bh(&x->lock);
- if (x->km.state == XFRM_STATE_VALID &&
- x->type && x->type->get_max_size)
- m = x->type->get_max_size(d->xfrm, m);
- else
- m += x->props.header_len;
- spin_unlock_bh(&x->lock);
- }
- } while ((d = d->child) != NULL);
-
- if (m <= mtu)
- break;
- res -= (m - mtu);
- if (res < 88)
- return mtu;
- }
-
- return res + dst->header_len;
-}
-
int xfrm_policy_register_afinfo(struct xfrm_policy_afinfo *afinfo)
{
int err = 0;
@@ -1252,8 +1212,6 @@ int xfrm_policy_register_afinfo(struct xfrm_policy_afinfo *afinfo)
dst_ops->negative_advice = xfrm_negative_advice;
if (likely(dst_ops->link_failure == NULL))
dst_ops->link_failure = xfrm_link_failure;
- if (likely(dst_ops->get_mss == NULL))
- dst_ops->get_mss = xfrm_get_mss;
if (likely(afinfo->garbage_collect == NULL))
afinfo->garbage_collect = __xfrm_garbage_collect;
xfrm_policy_afinfo[afinfo->family] = afinfo;
@@ -1281,7 +1239,6 @@ int xfrm_policy_unregister_afinfo(struct xfrm_policy_afinfo *afinfo)
dst_ops->check = NULL;
dst_ops->negative_advice = NULL;
dst_ops->link_failure = NULL;
- dst_ops->get_mss = NULL;
afinfo->garbage_collect = NULL;
}
}
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index 9d206c282cf1..7cf48aa6c95b 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -62,14 +62,10 @@ static void xfrm_state_gc_destroy(struct xfrm_state *x)
{
if (del_timer(&x->timer))
BUG();
- if (x->aalg)
- kfree(x->aalg);
- if (x->ealg)
- kfree(x->ealg);
- if (x->calg)
- kfree(x->calg);
- if (x->encap)
- kfree(x->encap);
+ kfree(x->aalg);
+ kfree(x->ealg);
+ kfree(x->calg);
+ kfree(x->encap);
if (x->type) {
x->type->destructor(x);
xfrm_put_type(x->type);
@@ -1026,6 +1022,12 @@ void xfrm_state_delete_tunnel(struct xfrm_state *x)
}
EXPORT_SYMBOL(xfrm_state_delete_tunnel);
+/*
+ * This function is NOT optimal. For example, with ESP it will give an
+ * MTU that's usually two bytes short of being optimal. However, it will
+ * usually give an answer that's a multiple of 4 provided the input is
+ * also a multiple of 4.
+ */
int xfrm_state_mtu(struct xfrm_state *x, int mtu)
{
int res = mtu;
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index c35336a0f71b..0cdd9a07e043 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -18,7 +18,6 @@
#include <linux/string.h>
#include <linux/net.h>
#include <linux/skbuff.h>
-#include <linux/netlink.h>
#include <linux/rtnetlink.h>
#include <linux/pfkeyv2.h>
#include <linux/ipsec.h>
@@ -26,6 +25,7 @@
#include <linux/security.h>
#include <net/sock.h>
#include <net/xfrm.h>
+#include <net/netlink.h>
#include <asm/uaccess.h>
static struct sock *xfrm_nl;
@@ -948,11 +948,6 @@ static struct xfrm_link {
[XFRM_MSG_FLUSHPOLICY - XFRM_MSG_BASE] = { .doit = xfrm_flush_policy },
};
-static int xfrm_done(struct netlink_callback *cb)
-{
- return 0;
-}
-
static int xfrm_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, int *errp)
{
struct rtattr *xfrma[XFRMA_MAX];
@@ -984,20 +979,15 @@ static int xfrm_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, int *err
if ((type == (XFRM_MSG_GETSA - XFRM_MSG_BASE) ||
type == (XFRM_MSG_GETPOLICY - XFRM_MSG_BASE)) &&
(nlh->nlmsg_flags & NLM_F_DUMP)) {
- u32 rlen;
-
if (link->dump == NULL)
goto err_einval;
if ((*errp = netlink_dump_start(xfrm_nl, skb, nlh,
- link->dump,
- xfrm_done)) != 0) {
+ link->dump, NULL)) != 0) {
return -1;
}
- rlen = NLMSG_ALIGN(nlh->nlmsg_len);
- if (rlen > skb->len)
- rlen = skb->len;
- skb_pull(skb, rlen);
+
+ netlink_queue_skip(nlh, skb);
return -1;
}
@@ -1032,60 +1022,13 @@ err_einval:
return -1;
}
-static int xfrm_user_rcv_skb(struct sk_buff *skb)
-{
- int err;
- struct nlmsghdr *nlh;
-
- while (skb->len >= NLMSG_SPACE(0)) {
- u32 rlen;
-
- nlh = (struct nlmsghdr *) skb->data;
- if (nlh->nlmsg_len < sizeof(*nlh) ||
- skb->len < nlh->nlmsg_len)
- return 0;
- rlen = NLMSG_ALIGN(nlh->nlmsg_len);
- if (rlen > skb->len)
- rlen = skb->len;
- if (xfrm_user_rcv_msg(skb, nlh, &err) < 0) {
- if (err == 0)
- return -1;
- netlink_ack(skb, nlh, err);
- } else if (nlh->nlmsg_flags & NLM_F_ACK)
- netlink_ack(skb, nlh, 0);
- skb_pull(skb, rlen);
- }
-
- return 0;
-}
-
static void xfrm_netlink_rcv(struct sock *sk, int len)
{
- unsigned int qlen = skb_queue_len(&sk->sk_receive_queue);
+ unsigned int qlen = 0;
do {
- struct sk_buff *skb;
-
down(&xfrm_cfg_sem);
-
- if (qlen > skb_queue_len(&sk->sk_receive_queue))
- qlen = skb_queue_len(&sk->sk_receive_queue);
-
- for (; qlen; qlen--) {
- skb = skb_dequeue(&sk->sk_receive_queue);
- if (xfrm_user_rcv_skb(skb)) {
- if (skb->len)
- skb_queue_head(&sk->sk_receive_queue,
- skb);
- else {
- kfree_skb(skb);
- qlen--;
- }
- break;
- }
- kfree_skb(skb);
- }
-
+ netlink_run_queue(sk, &qlen, &xfrm_user_rcv_msg);
up(&xfrm_cfg_sem);
} while (qlen);
diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile
index 2fcb244a9e18..9d67782b812f 100644
--- a/scripts/kconfig/Makefile
+++ b/scripts/kconfig/Makefile
@@ -114,25 +114,28 @@ gconf-objs := gconf.o kconfig_load.o zconf.tab.o
endif
clean-files := lkc_defs.h qconf.moc .tmp_qtcheck \
- .tmp_gtkcheck zconf.tab.c zconf.tab.h lex.zconf.c
+ .tmp_gtkcheck zconf.tab.c lex.zconf.c zconf.hash.c
+
+# Needed for systems without gettext
+KBUILD_HAVE_NLS := $(shell \
+ if echo "\#include <libintl.h>" | $(HOSTCC) $(HOSTCFLAGS) -E - > /dev/null 2>&1 ; \
+ then echo yes ; \
+ else echo no ; fi)
+ifeq ($(KBUILD_HAVE_NLS),no)
+HOSTCFLAGS += -DKBUILD_NO_NLS
+endif
# generated files seem to need this to find local include files
HOSTCFLAGS_lex.zconf.o := -I$(src)
HOSTCFLAGS_zconf.tab.o := -I$(src)
-HOSTLOADLIBES_qconf = -L$(QTLIBPATH) -Wl,-rpath,$(QTLIBPATH) -l$(QTLIB) -ldl
+HOSTLOADLIBES_qconf = -L$(QTLIBPATH) -Wl,-rpath,$(QTLIBPATH) -l$(LIBS_QT) -ldl
HOSTCXXFLAGS_qconf.o = -I$(QTDIR)/include -D LKC_DIRECT_LINK
HOSTLOADLIBES_gconf = `pkg-config gtk+-2.0 gmodule-2.0 libglade-2.0 --libs`
HOSTCFLAGS_gconf.o = `pkg-config gtk+-2.0 gmodule-2.0 libglade-2.0 --cflags` \
-D LKC_DIRECT_LINK
-$(obj)/conf.o $(obj)/mconf.o $(obj)/qconf.o $(obj)/gconf.o $(obj)/kxgettext: $(obj)/zconf.tab.h
-
-$(obj)/zconf.tab.h: $(src)/zconf.tab.h_shipped
-$(obj)/zconf.tab.c: $(src)/zconf.tab.c_shipped
-$(obj)/lex.zconf.c: $(src)/lex.zconf.c_shipped
-
$(obj)/qconf.o: $(obj)/.tmp_qtcheck
ifeq ($(qconf-target),1)
@@ -154,11 +157,16 @@ $(obj)/.tmp_qtcheck:
false; \
fi; \
LIBPATH=$$DIR/lib; LIB=qt; \
- $(HOSTCXX) -print-multi-os-directory > /dev/null 2>&1 && \
- LIBPATH=$$DIR/lib/$$($(HOSTCXX) -print-multi-os-directory); \
- if [ -f $$LIBPATH/libqt-mt.so ]; then LIB=qt-mt; fi; \
+ if [ -f $$QTLIB/libqt-mt.so ] ; then \
+ LIB=qt-mt; \
+ LIBPATH=$$QTLIB; \
+ else \
+ $(HOSTCXX) -print-multi-os-directory > /dev/null 2>&1 && \
+ LIBPATH=$$DIR/lib/$$($(HOSTCXX) -print-multi-os-directory); \
+ if [ -f $$LIBPATH/libqt-mt.so ]; then LIB=qt-mt; fi; \
+ fi; \
echo "QTDIR=$$DIR" > $@; echo "QTLIBPATH=$$LIBPATH" >> $@; \
- echo "QTLIB=$$LIB" >> $@; \
+ echo "LIBS_QT=$$LIB" >> $@; \
if [ ! -x $$DIR/bin/moc -a -x /usr/bin/moc ]; then \
echo "*"; \
echo "* Unable to find $$DIR/bin/moc, using /usr/bin/moc instead."; \
@@ -193,7 +201,7 @@ $(obj)/.tmp_gtkcheck:
fi
endif
-$(obj)/zconf.tab.o: $(obj)/lex.zconf.c
+$(obj)/zconf.tab.o: $(obj)/lex.zconf.c $(obj)/zconf.hash.c
$(obj)/kconfig_load.o: $(obj)/lkc_defs.h
@@ -209,20 +217,27 @@ $(obj)/lkc_defs.h: $(src)/lkc_proto.h
###
-# The following requires flex/bison
+# The following requires flex/bison/gperf
# By default we use the _shipped versions, uncomment the following line if
# you are modifying the flex/bison src.
# LKC_GENPARSER := 1
ifdef LKC_GENPARSER
-$(obj)/zconf.tab.c: $(obj)/zconf.y
-$(obj)/zconf.tab.h: $(obj)/zconf.tab.c
+$(obj)/zconf.tab.c: $(src)/zconf.y
+$(obj)/lex.zconf.c: $(src)/zconf.l
+$(obj)/zconf.hash.c: $(src)/zconf.gperf
%.tab.c: %.y
- bison -t -d -v -b $* -p $(notdir $*) $<
+ bison -l -b $* -p $(notdir $*) $<
+ cp $@ $@_shipped
lex.%.c: %.l
- flex -P$(notdir $*) -o$@ $<
+ flex -L -P$(notdir $*) -o$@ $<
+ cp $@ $@_shipped
+
+%.hash.c: %.gperf
+ gperf < $< > $@
+ cp $@ $@_shipped
endif
diff --git a/scripts/kconfig/conf.c b/scripts/kconfig/conf.c
index bc20cab9d0d6..8ba5d29d3d42 100644
--- a/scripts/kconfig/conf.c
+++ b/scripts/kconfig/conf.c
@@ -82,6 +82,15 @@ static void conf_askvalue(struct symbol *sym, const char *def)
}
switch (input_mode) {
+ case set_no:
+ case set_mod:
+ case set_yes:
+ case set_random:
+ if (sym_has_value(sym)) {
+ printf("%s\n", def);
+ return;
+ }
+ break;
case ask_new:
case ask_silent:
if (sym_has_value(sym)) {
@@ -467,15 +476,14 @@ static void check_conf(struct menu *menu)
return;
sym = menu->sym;
- if (sym) {
- if (sym_is_changable(sym) && !sym_has_value(sym)) {
+ if (sym && !sym_has_value(sym)) {
+ if (sym_is_changable(sym) ||
+ (sym_is_choice(sym) && sym_get_tristate_value(sym) == yes)) {
if (!conf_cnt++)
printf(_("*\n* Restart config...\n*\n"));
rootEntry = menu_get_parent_menu(menu);
conf(rootEntry);
}
- if (sym_is_choice(sym) && sym_get_tristate_value(sym) != mod)
- return;
}
for (child = menu->list; child; child = child->next)
@@ -559,6 +567,27 @@ int main(int ac, char **av)
case ask_new:
conf_read(NULL);
break;
+ case set_no:
+ case set_mod:
+ case set_yes:
+ case set_random:
+ name = getenv("KCONFIG_ALLCONFIG");
+ if (name && !stat(name, &tmpstat)) {
+ conf_read_simple(name);
+ break;
+ }
+ switch (input_mode) {
+ case set_no: name = "allno.config"; break;
+ case set_mod: name = "allmod.config"; break;
+ case set_yes: name = "allyes.config"; break;
+ case set_random: name = "allrandom.config"; break;
+ default: break;
+ }
+ if (!stat(name, &tmpstat))
+ conf_read_simple(name);
+ else if (!stat("all.config", &tmpstat))
+ conf_read_simple("all.config");
+ break;
default:
break;
}
diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c
index 02f670cc6bb9..ccd45130c482 100644
--- a/scripts/kconfig/confdata.c
+++ b/scripts/kconfig/confdata.c
@@ -14,6 +14,12 @@
#define LKC_DIRECT_LINK
#include "lkc.h"
+static void conf_warning(const char *fmt, ...)
+ __attribute__ ((format (printf, 1, 2)));
+
+static const char *conf_filename;
+static int conf_lineno, conf_warnings, conf_unsaved;
+
const char conf_def_filename[] = ".config";
const char conf_defname[] = "arch/$ARCH/defconfig";
@@ -27,6 +33,17 @@ const char *conf_confnames[] = {
NULL,
};
+static void conf_warning(const char *fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+ fprintf(stderr, "%s:%d:warning: ", conf_filename, conf_lineno);
+ vfprintf(stderr, fmt, ap);
+ fprintf(stderr, "\n");
+ va_end(ap);
+ conf_warnings++;
+}
+
static char *conf_expand_value(const char *in)
{
struct symbol *sym;
@@ -69,15 +86,12 @@ char *conf_get_default_confname(void)
return name;
}
-int conf_read(const char *name)
+int conf_read_simple(const char *name)
{
FILE *in = NULL;
char line[1024];
char *p, *p2;
- int lineno = 0;
struct symbol *sym;
- struct property *prop;
- struct expr *e;
int i;
if (name) {
@@ -95,12 +109,18 @@ int conf_read(const char *name)
}
}
}
-
if (!in)
return 1;
+ conf_filename = name;
+ conf_lineno = 0;
+ conf_warnings = 0;
+ conf_unsaved = 0;
+
for_all_symbols(i, sym) {
sym->flags |= SYMBOL_NEW | SYMBOL_CHANGED;
+ if (sym_is_choice(sym))
+ sym->flags &= ~SYMBOL_NEW;
sym->flags &= ~SYMBOL_VALID;
switch (sym->type) {
case S_INT:
@@ -115,7 +135,7 @@ int conf_read(const char *name)
}
while (fgets(line, sizeof(line), in)) {
- lineno++;
+ conf_lineno++;
sym = NULL;
switch (line[0]) {
case '#':
@@ -129,7 +149,10 @@ int conf_read(const char *name)
continue;
sym = sym_find(line + 9);
if (!sym) {
- fprintf(stderr, "%s:%d: trying to assign nonexistent symbol %s\n", name, lineno, line + 9);
+ conf_warning("trying to assign nonexistent symbol %s", line + 9);
+ break;
+ } else if (!(sym->flags & SYMBOL_NEW)) {
+ conf_warning("trying to reassign symbol %s", sym->name);
break;
}
switch (sym->type) {
@@ -143,8 +166,10 @@ int conf_read(const char *name)
}
break;
case 'C':
- if (memcmp(line, "CONFIG_", 7))
+ if (memcmp(line, "CONFIG_", 7)) {
+ conf_warning("unexpected data");
continue;
+ }
p = strchr(line + 7, '=');
if (!p)
continue;
@@ -154,7 +179,10 @@ int conf_read(const char *name)
*p2 = 0;
sym = sym_find(line + 7);
if (!sym) {
- fprintf(stderr, "%s:%d: trying to assign nonexistent symbol %s\n", name, lineno, line + 7);
+ conf_warning("trying to assign nonexistent symbol %s", line + 7);
+ break;
+ } else if (!(sym->flags & SYMBOL_NEW)) {
+ conf_warning("trying to reassign symbol %s", sym->name);
break;
}
switch (sym->type) {
@@ -175,6 +203,7 @@ int conf_read(const char *name)
sym->flags &= ~SYMBOL_NEW;
break;
}
+ conf_warning("symbol value '%s' invalid for %s", p, sym->name);
break;
case S_STRING:
if (*p++ != '"')
@@ -187,8 +216,8 @@ int conf_read(const char *name)
memmove(p2, p2 + 1, strlen(p2));
}
if (!p2) {
- fprintf(stderr, "%s:%d: invalid string found\n", name, lineno);
- exit(1);
+ conf_warning("invalid string found");
+ continue;
}
case S_INT:
case S_HEX:
@@ -196,8 +225,8 @@ int conf_read(const char *name)
sym->user.val = strdup(p);
sym->flags &= ~SYMBOL_NEW;
} else {
- fprintf(stderr, "%s:%d: symbol value '%s' invalid for %s\n", name, lineno, p, sym->name);
- exit(1);
+ conf_warning("symbol value '%s' invalid for %s", p, sym->name);
+ continue;
}
break;
default:
@@ -207,6 +236,7 @@ int conf_read(const char *name)
case '\n':
break;
default:
+ conf_warning("unexpected data");
continue;
}
if (sym && sym_is_choice_value(sym)) {
@@ -215,25 +245,63 @@ int conf_read(const char *name)
case no:
break;
case mod:
- if (cs->user.tri == yes)
- /* warn? */;
+ if (cs->user.tri == yes) {
+ conf_warning("%s creates inconsistent choice state", sym->name);
+ cs->flags |= SYMBOL_NEW;
+ }
break;
case yes:
- if (cs->user.tri != no)
- /* warn? */;
- cs->user.val = sym;
+ if (cs->user.tri != no) {
+ conf_warning("%s creates inconsistent choice state", sym->name);
+ cs->flags |= SYMBOL_NEW;
+ } else
+ cs->user.val = sym;
break;
}
cs->user.tri = E_OR(cs->user.tri, sym->user.tri);
- cs->flags &= ~SYMBOL_NEW;
}
}
fclose(in);
if (modules_sym)
sym_calc_value(modules_sym);
+ return 0;
+}
+
+int conf_read(const char *name)
+{
+ struct symbol *sym;
+ struct property *prop;
+ struct expr *e;
+ int i;
+
+ if (conf_read_simple(name))
+ return 1;
+
for_all_symbols(i, sym) {
sym_calc_value(sym);
+ if (sym_is_choice(sym) || (sym->flags & SYMBOL_AUTO))
+ goto sym_ok;
+ if (sym_has_value(sym) && (sym->flags & SYMBOL_WRITE)) {
+ /* check that calculated value agrees with saved value */
+ switch (sym->type) {
+ case S_BOOLEAN:
+ case S_TRISTATE:
+ if (sym->user.tri != sym_get_tristate_value(sym))
+ break;
+ if (!sym_is_choice(sym))
+ goto sym_ok;
+ default:
+ if (!strcmp(sym->curr.val, sym->user.val))
+ goto sym_ok;
+ break;
+ }
+ } else if (!sym_has_value(sym) && !(sym->flags & SYMBOL_WRITE))
+ /* no previous value and not saved */
+ goto sym_ok;
+ conf_unsaved++;
+ /* maybe print value in verbose mode... */
+ sym_ok:
if (sym_has_value(sym) && !sym_is_choice_value(sym)) {
if (sym->visible == no)
sym->flags |= SYMBOL_NEW;
@@ -241,8 +309,10 @@ int conf_read(const char *name)
case S_STRING:
case S_INT:
case S_HEX:
- if (!sym_string_within_range(sym, sym->user.val))
+ if (!sym_string_within_range(sym, sym->user.val)) {
sym->flags |= SYMBOL_NEW;
+ sym->flags &= ~SYMBOL_VALID;
+ }
default:
break;
}
@@ -255,7 +325,7 @@ int conf_read(const char *name)
sym->flags |= e->right.sym->flags & SYMBOL_NEW;
}
- sym_change_count = 1;
+ sym_change_count = conf_warnings && conf_unsaved;
return 0;
}
diff --git a/scripts/kconfig/expr.h b/scripts/kconfig/expr.h
index 7d39ff43e6e1..1b36ef18c48d 100644
--- a/scripts/kconfig/expr.h
+++ b/scripts/kconfig/expr.h
@@ -93,7 +93,6 @@ struct symbol {
#define SYMBOL_NEW 0x0800
#define SYMBOL_AUTO 0x1000
#define SYMBOL_CHECKED 0x2000
-#define SYMBOL_CHECK_DONE 0x4000
#define SYMBOL_WARNED 0x8000
#define SYMBOL_MAXLENGTH 256
diff --git a/scripts/kconfig/lex.zconf.c_shipped b/scripts/kconfig/lex.zconf.c_shipped
index 22dda11f758b..24e3c8cbb7ac 100644
--- a/scripts/kconfig/lex.zconf.c_shipped
+++ b/scripts/kconfig/lex.zconf.c_shipped
@@ -1,5 +1,5 @@
-#line 3 "lex.zconf.c"
+#line 3 "scripts/kconfig/lex.zconf.c"
#define YY_INT_ALIGNED short int
@@ -323,7 +323,7 @@ void zconffree (void * );
/* Begin user sect3 */
-#define zconfwrap(n) 1
+#define zconfwrap() 1
#define YY_SKIP_YYWRAP
typedef unsigned char YY_CHAR;
@@ -338,1567 +338,323 @@ int zconflineno = 1;
extern char *zconftext;
#define yytext_ptr zconftext
-static yyconst flex_int16_t yy_nxt[][38] =
+static yyconst flex_int16_t yy_nxt[][17] =
{
{
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, 0, 0, 0
},
{
11, 12, 13, 14, 12, 12, 15, 12, 12, 12,
- 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
- 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
- 12, 12, 12, 12, 12, 12, 12, 12
+ 12, 12, 12, 12, 12, 12, 12
},
{
11, 12, 13, 14, 12, 12, 15, 12, 12, 12,
- 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-
- 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
- 12, 12, 12, 12, 12, 12, 12, 12
+ 12, 12, 12, 12, 12, 12, 12
},
{
11, 16, 16, 17, 16, 16, 16, 16, 16, 16,
- 16, 16, 16, 18, 16, 16, 18, 18, 19, 20,
- 21, 22, 18, 18, 23, 24, 18, 25, 18, 26,
- 27, 18, 28, 29, 30, 18, 18, 16
+ 16, 16, 16, 18, 16, 16, 16
},
{
11, 16, 16, 17, 16, 16, 16, 16, 16, 16,
- 16, 16, 16, 18, 16, 16, 18, 18, 19, 20,
- 21, 22, 18, 18, 23, 24, 18, 25, 18, 26,
- 27, 18, 28, 29, 30, 18, 18, 16
+ 16, 16, 16, 18, 16, 16, 16
},
{
- 11, 31, 32, 33, 31, 31, 31, 31, 31, 31,
- 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
- 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
- 31, 31, 31, 31, 31, 31, 31, 31
+ 11, 19, 20, 21, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19
},
{
- 11, 31, 32, 33, 31, 31, 31, 31, 31, 31,
- 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
- 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
- 31, 31, 31, 31, 31, 31, 31, 31
+ 11, 19, 20, 21, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19
},
{
- 11, 34, 34, 35, 34, 36, 34, 34, 36, 34,
- 34, 34, 34, 34, 34, 37, 34, 34, 34, 34,
-
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34
+ 11, 22, 22, 23, 22, 24, 22, 22, 24, 22,
+ 22, 22, 22, 22, 22, 25, 22
},
{
- 11, 34, 34, 35, 34, 36, 34, 34, 36, 34,
- 34, 34, 34, 34, 34, 37, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34
+ 11, 22, 22, 23, 22, 24, 22, 22, 24, 22,
+ 22, 22, 22, 22, 22, 25, 22
},
{
- 11, 38, 38, 39, 40, 41, 42, 43, 41, 44,
- 45, 46, 47, 47, 48, 49, 47, 47, 47, 47,
- 47, 47, 47, 47, 47, 50, 47, 47, 47, 51,
- 47, 47, 47, 47, 47, 47, 47, 52
+ 11, 26, 26, 27, 28, 29, 30, 31, 29, 32,
+ 33, 34, 35, 35, 36, 37, 38
},
{
- 11, 38, 38, 39, 40, 41, 42, 43, 41, 44,
- 45, 46, 47, 47, 48, 49, 47, 47, 47, 47,
- 47, 47, 47, 47, 47, 50, 47, 47, 47, 51,
- 47, 47, 47, 47, 47, 47, 47, 52
+ 11, 26, 26, 27, 28, 29, 30, 31, 29, 32,
+ 33, 34, 35, 35, 36, 37, 38
},
{
-11, -11, -11, -11, -11, -11, -11, -11, -11, -11,
- -11, -11, -11, -11, -11, -11, -11, -11, -11, -11,
- -11, -11, -11, -11, -11, -11, -11, -11, -11, -11,
- -11, -11, -11, -11, -11, -11, -11, -11
+ -11, -11, -11, -11, -11, -11, -11
},
{
11, -12, -12, -12, -12, -12, -12, -12, -12, -12,
- -12, -12, -12, -12, -12, -12, -12, -12, -12, -12,
-
- -12, -12, -12, -12, -12, -12, -12, -12, -12, -12,
- -12, -12, -12, -12, -12, -12, -12, -12
+ -12, -12, -12, -12, -12, -12, -12
},
{
- 11, -13, 53, 54, -13, -13, 55, -13, -13, -13,
- -13, -13, -13, -13, -13, -13, -13, -13, -13, -13,
- -13, -13, -13, -13, -13, -13, -13, -13, -13, -13,
- -13, -13, -13, -13, -13, -13, -13, -13
+ 11, -13, 39, 40, -13, -13, 41, -13, -13, -13,
+ -13, -13, -13, -13, -13, -13, -13
},
{
11, -14, -14, -14, -14, -14, -14, -14, -14, -14,
- -14, -14, -14, -14, -14, -14, -14, -14, -14, -14,
- -14, -14, -14, -14, -14, -14, -14, -14, -14, -14,
- -14, -14, -14, -14, -14, -14, -14, -14
+ -14, -14, -14, -14, -14, -14, -14
},
{
- 11, 56, 56, 57, 56, 56, 56, 56, 56, 56,
- 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
- 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
- 56, 56, 56, 56, 56, 56, 56, 56
+ 11, 42, 42, 43, 42, 42, 42, 42, 42, 42,
+ 42, 42, 42, 42, 42, 42, 42
},
{
11, -16, -16, -16, -16, -16, -16, -16, -16, -16,
- -16, -16, -16, -16, -16, -16, -16, -16, -16, -16,
- -16, -16, -16, -16, -16, -16, -16, -16, -16, -16,
- -16, -16, -16, -16, -16, -16, -16, -16
+ -16, -16, -16, -16, -16, -16, -16
},
{
11, -17, -17, -17, -17, -17, -17, -17, -17, -17,
- -17, -17, -17, -17, -17, -17, -17, -17, -17, -17,
-
- -17, -17, -17, -17, -17, -17, -17, -17, -17, -17,
- -17, -17, -17, -17, -17, -17, -17, -17
+ -17, -17, -17, -17, -17, -17, -17
},
{
11, -18, -18, -18, -18, -18, -18, -18, -18, -18,
- -18, -18, -18, 58, -18, -18, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -18
+ -18, -18, -18, 44, -18, -18, -18
},
{
- 11, -19, -19, -19, -19, -19, -19, -19, -19, -19,
- -19, -19, -19, 58, -19, -19, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 59,
- 58, 58, 58, 58, 58, 58, 58, -19
+ 11, 45, 45, -19, 45, 45, 45, 45, 45, 45,
+ 45, 45, 45, 45, 45, 45, 45
},
{
- 11, -20, -20, -20, -20, -20, -20, -20, -20, -20,
- -20, -20, -20, 58, -20, -20, 58, 58, 58, 58,
- 58, 58, 58, 58, 60, 58, 58, 58, 58, 61,
- 58, 58, 58, 58, 58, 58, 58, -20
+ 11, -20, 46, 47, -20, -20, -20, -20, -20, -20,
+ -20, -20, -20, -20, -20, -20, -20
},
{
- 11, -21, -21, -21, -21, -21, -21, -21, -21, -21,
- -21, -21, -21, 58, -21, -21, 58, 58, 58, 58,
- 58, 62, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -21
+ 11, 48, -21, -21, 48, 48, 48, 48, 48, 48,
+ 48, 48, 48, 48, 48, 48, 48
},
{
- 11, -22, -22, -22, -22, -22, -22, -22, -22, -22,
- -22, -22, -22, 58, -22, -22, 58, 58, 58, 58,
-
- 58, 58, 58, 58, 58, 58, 58, 58, 63, 58,
- 58, 58, 58, 58, 58, 58, 58, -22
+ 11, 49, 49, 50, 49, -22, 49, 49, -22, 49,
+ 49, 49, 49, 49, 49, -22, 49
},
{
11, -23, -23, -23, -23, -23, -23, -23, -23, -23,
- -23, -23, -23, 58, -23, -23, 58, 58, 58, 58,
- 58, 64, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -23
+ -23, -23, -23, -23, -23, -23, -23
},
{
11, -24, -24, -24, -24, -24, -24, -24, -24, -24,
- -24, -24, -24, 58, -24, -24, 58, 58, 58, 58,
- 58, 58, 65, 58, 58, 58, 58, 58, 66, 58,
- 58, 58, 58, 58, 58, 58, 58, -24
+ -24, -24, -24, -24, -24, -24, -24
},
{
- 11, -25, -25, -25, -25, -25, -25, -25, -25, -25,
- -25, -25, -25, 58, -25, -25, 58, 67, 58, 58,
- 58, 68, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -25
+ 11, 51, 51, 52, 51, 51, 51, 51, 51, 51,
+ 51, 51, 51, 51, 51, 51, 51
},
{
11, -26, -26, -26, -26, -26, -26, -26, -26, -26,
- -26, -26, -26, 58, -26, -26, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 69, 58, 58, 58, 58, 58, 58, -26
+ -26, -26, -26, -26, -26, -26, -26
},
{
11, -27, -27, -27, -27, -27, -27, -27, -27, -27,
- -27, -27, -27, 58, -27, -27, 58, 58, 58, 58,
-
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 70, 58, 58, 58, 58, -27
+ -27, -27, -27, -27, -27, -27, -27
},
{
11, -28, -28, -28, -28, -28, -28, -28, -28, -28,
- -28, -28, -28, 58, -28, -28, 58, 71, 58, 58,
- 58, 72, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -28
+ -28, -28, -28, -28, 53, -28, -28
},
{
11, -29, -29, -29, -29, -29, -29, -29, -29, -29,
- -29, -29, -29, 58, -29, -29, 58, 58, 58, 58,
- 58, 73, 58, 58, 58, 58, 58, 58, 58, 74,
- 58, 58, 58, 58, 75, 58, 58, -29
+ -29, -29, -29, -29, -29, -29, -29
},
{
- 11, -30, -30, -30, -30, -30, -30, -30, -30, -30,
- -30, -30, -30, 58, -30, -30, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 76, 58, 58, 58, 58, -30
+ 11, 54, 54, -30, 54, 54, 54, 54, 54, 54,
+ 54, 54, 54, 54, 54, 54, 54
},
{
- 11, 77, 77, -31, 77, 77, 77, 77, 77, 77,
- 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
- 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
- 77, 77, 77, 77, 77, 77, 77, 77
+ 11, -31, -31, -31, -31, -31, -31, 55, -31, -31,
+ -31, -31, -31, -31, -31, -31, -31
},
{
- 11, -32, 78, 79, -32, -32, -32, -32, -32, -32,
- -32, -32, -32, -32, -32, -32, -32, -32, -32, -32,
-
- -32, -32, -32, -32, -32, -32, -32, -32, -32, -32,
- -32, -32, -32, -32, -32, -32, -32, -32
+ 11, -32, -32, -32, -32, -32, -32, -32, -32, -32,
+ -32, -32, -32, -32, -32, -32, -32
},
{
- 11, 80, -33, -33, 80, 80, 80, 80, 80, 80,
- 80, 80, 80, 80, 80, 80, 80, 80, 80, 80,
- 80, 80, 80, 80, 80, 80, 80, 80, 80, 80,
- 80, 80, 80, 80, 80, 80, 80, 80
+ 11, -33, -33, -33, -33, -33, -33, -33, -33, -33,
+ -33, -33, -33, -33, -33, -33, -33
},
{
- 11, 81, 81, 82, 81, -34, 81, 81, -34, 81,
- 81, 81, 81, 81, 81, -34, 81, 81, 81, 81,
- 81, 81, 81, 81, 81, 81, 81, 81, 81, 81,
- 81, 81, 81, 81, 81, 81, 81, 81
+ 11, -34, -34, -34, -34, -34, -34, -34, -34, -34,
+ -34, 56, 57, 57, -34, -34, -34
},
{
11, -35, -35, -35, -35, -35, -35, -35, -35, -35,
- -35, -35, -35, -35, -35, -35, -35, -35, -35, -35,
- -35, -35, -35, -35, -35, -35, -35, -35, -35, -35,
- -35, -35, -35, -35, -35, -35, -35, -35
+ -35, 57, 57, 57, -35, -35, -35
},
{
11, -36, -36, -36, -36, -36, -36, -36, -36, -36,
- -36, -36, -36, -36, -36, -36, -36, -36, -36, -36,
- -36, -36, -36, -36, -36, -36, -36, -36, -36, -36,
- -36, -36, -36, -36, -36, -36, -36, -36
+ -36, -36, -36, -36, -36, -36, -36
},
{
- 11, 83, 83, 84, 83, 83, 83, 83, 83, 83,
- 83, 83, 83, 83, 83, 83, 83, 83, 83, 83,
-
- 83, 83, 83, 83, 83, 83, 83, 83, 83, 83,
- 83, 83, 83, 83, 83, 83, 83, 83
+ 11, -37, -37, 58, -37, -37, -37, -37, -37, -37,
+ -37, -37, -37, -37, -37, -37, -37
},
{
11, -38, -38, -38, -38, -38, -38, -38, -38, -38,
- -38, -38, -38, -38, -38, -38, -38, -38, -38, -38,
- -38, -38, -38, -38, -38, -38, -38, -38, -38, -38,
- -38, -38, -38, -38, -38, -38, -38, -38
+ -38, -38, -38, -38, -38, -38, 59
},
{
- 11, -39, -39, -39, -39, -39, -39, -39, -39, -39,
- -39, -39, -39, -39, -39, -39, -39, -39, -39, -39,
- -39, -39, -39, -39, -39, -39, -39, -39, -39, -39,
- -39, -39, -39, -39, -39, -39, -39, -39
+ 11, -39, 39, 40, -39, -39, 41, -39, -39, -39,
+ -39, -39, -39, -39, -39, -39, -39
},
{
11, -40, -40, -40, -40, -40, -40, -40, -40, -40,
- -40, -40, -40, -40, 85, -40, -40, -40, -40, -40,
- -40, -40, -40, -40, -40, -40, -40, -40, -40, -40,
- -40, -40, -40, -40, -40, -40, -40, -40
+ -40, -40, -40, -40, -40, -40, -40
},
{
- 11, -41, -41, -41, -41, -41, -41, -41, -41, -41,
- -41, -41, -41, -41, -41, -41, -41, -41, -41, -41,
- -41, -41, -41, -41, -41, -41, -41, -41, -41, -41,
- -41, -41, -41, -41, -41, -41, -41, -41
+ 11, 42, 42, 43, 42, 42, 42, 42, 42, 42,
+ 42, 42, 42, 42, 42, 42, 42
},
{
- 11, 86, 86, -42, 86, 86, 86, 86, 86, 86,
- 86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
-
- 86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
- 86, 86, 86, 86, 86, 86, 86, 86
+ 11, 42, 42, 43, 42, 42, 42, 42, 42, 42,
+ 42, 42, 42, 42, 42, 42, 42
},
{
- 11, -43, -43, -43, -43, -43, -43, 87, -43, -43,
- -43, -43, -43, -43, -43, -43, -43, -43, -43, -43,
- -43, -43, -43, -43, -43, -43, -43, -43, -43, -43,
- -43, -43, -43, -43, -43, -43, -43, -43
+ 11, -43, -43, -43, -43, -43, -43, -43, -43, -43,
+ -43, -43, -43, -43, -43, -43, -43
},
{
11, -44, -44, -44, -44, -44, -44, -44, -44, -44,
- -44, -44, -44, -44, -44, -44, -44, -44, -44, -44,
- -44, -44, -44, -44, -44, -44, -44, -44, -44, -44,
- -44, -44, -44, -44, -44, -44, -44, -44
+ -44, -44, -44, 44, -44, -44, -44
},
{
- 11, -45, -45, -45, -45, -45, -45, -45, -45, -45,
- -45, -45, -45, -45, -45, -45, -45, -45, -45, -45,
- -45, -45, -45, -45, -45, -45, -45, -45, -45, -45,
- -45, -45, -45, -45, -45, -45, -45, -45
+ 11, 45, 45, -45, 45, 45, 45, 45, 45, 45,
+ 45, 45, 45, 45, 45, 45, 45
},
{
- 11, -46, -46, -46, -46, -46, -46, -46, -46, -46,
- -46, 88, 89, 89, -46, -46, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, -46
+ 11, -46, 46, 47, -46, -46, -46, -46, -46, -46,
+ -46, -46, -46, -46, -46, -46, -46
},
{
- 11, -47, -47, -47, -47, -47, -47, -47, -47, -47,
- -47, 89, 89, 89, -47, -47, 89, 89, 89, 89,
-
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, -47
+ 11, 48, -47, -47, 48, 48, 48, 48, 48, 48,
+ 48, 48, 48, 48, 48, 48, 48
},
{
11, -48, -48, -48, -48, -48, -48, -48, -48, -48,
- -48, -48, -48, -48, -48, -48, -48, -48, -48, -48,
- -48, -48, -48, -48, -48, -48, -48, -48, -48, -48,
- -48, -48, -48, -48, -48, -48, -48, -48
+ -48, -48, -48, -48, -48, -48, -48
},
{
- 11, -49, -49, 90, -49, -49, -49, -49, -49, -49,
- -49, -49, -49, -49, -49, -49, -49, -49, -49, -49,
- -49, -49, -49, -49, -49, -49, -49, -49, -49, -49,
- -49, -49, -49, -49, -49, -49, -49, -49
+ 11, 49, 49, 50, 49, -49, 49, 49, -49, 49,
+ 49, 49, 49, 49, 49, -49, 49
},
{
11, -50, -50, -50, -50, -50, -50, -50, -50, -50,
- -50, 89, 89, 89, -50, -50, 89, 89, 89, 89,
- 89, 89, 91, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, -50
+ -50, -50, -50, -50, -50, -50, -50
},
{
- 11, -51, -51, -51, -51, -51, -51, -51, -51, -51,
- -51, 89, 89, 89, -51, -51, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 92, 89,
- 89, 89, 89, 89, 89, 89, 89, -51
+ 11, -51, -51, 52, -51, -51, -51, -51, -51, -51,
+ -51, -51, -51, -51, -51, -51, -51
},
{
11, -52, -52, -52, -52, -52, -52, -52, -52, -52,
- -52, -52, -52, -52, -52, -52, -52, -52, -52, -52,
-
- -52, -52, -52, -52, -52, -52, -52, -52, -52, -52,
- -52, -52, -52, -52, -52, -52, -52, 93
+ -52, -52, -52, -52, -52, -52, -52
},
{
- 11, -53, 53, 54, -53, -53, 55, -53, -53, -53,
- -53, -53, -53, -53, -53, -53, -53, -53, -53, -53,
- -53, -53, -53, -53, -53, -53, -53, -53, -53, -53,
- -53, -53, -53, -53, -53, -53, -53, -53
+ 11, -53, -53, -53, -53, -53, -53, -53, -53, -53,
+ -53, -53, -53, -53, -53, -53, -53
},
{
- 11, -54, -54, -54, -54, -54, -54, -54, -54, -54,
- -54, -54, -54, -54, -54, -54, -54, -54, -54, -54,
- -54, -54, -54, -54, -54, -54, -54, -54, -54, -54,
- -54, -54, -54, -54, -54, -54, -54, -54
+ 11, 54, 54, -54, 54, 54, 54, 54, 54, 54,
+ 54, 54, 54, 54, 54, 54, 54
},
{
- 11, 56, 56, 57, 56, 56, 56, 56, 56, 56,
- 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
- 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
- 56, 56, 56, 56, 56, 56, 56, 56
+ 11, -55, -55, -55, -55, -55, -55, -55, -55, -55,
+ -55, -55, -55, -55, -55, -55, -55
},
{
- 11, 56, 56, 57, 56, 56, 56, 56, 56, 56,
- 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
- 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
- 56, 56, 56, 56, 56, 56, 56, 56
+ 11, -56, -56, -56, -56, -56, -56, -56, -56, -56,
+ -56, 60, 57, 57, -56, -56, -56
},
{
11, -57, -57, -57, -57, -57, -57, -57, -57, -57,
- -57, -57, -57, -57, -57, -57, -57, -57, -57, -57,
-
- -57, -57, -57, -57, -57, -57, -57, -57, -57, -57,
- -57, -57, -57, -57, -57, -57, -57, -57
+ -57, 57, 57, 57, -57, -57, -57
},
{
11, -58, -58, -58, -58, -58, -58, -58, -58, -58,
- -58, -58, -58, 58, -58, -58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -58
+ -58, -58, -58, -58, -58, -58, -58
},
{
11, -59, -59, -59, -59, -59, -59, -59, -59, -59,
- -59, -59, -59, 58, -59, -59, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 94,
- 58, 58, 58, 58, 58, 58, 58, -59
+ -59, -59, -59, -59, -59, -59, -59
},
{
11, -60, -60, -60, -60, -60, -60, -60, -60, -60,
- -60, -60, -60, 58, -60, -60, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 95,
- 58, 58, 58, 58, 58, 58, 58, -60
- },
-
- {
- 11, -61, -61, -61, -61, -61, -61, -61, -61, -61,
- -61, -61, -61, 58, -61, -61, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 96, 97, 58,
- 58, 58, 58, 58, 58, 58, 58, -61
- },
-
- {
- 11, -62, -62, -62, -62, -62, -62, -62, -62, -62,
- -62, -62, -62, 58, -62, -62, 58, 58, 58, 58,
-
- 58, 58, 98, 58, 58, 58, 58, 58, 58, 58,
- 99, 58, 58, 58, 58, 58, 58, -62
- },
-
- {
- 11, -63, -63, -63, -63, -63, -63, -63, -63, -63,
- -63, -63, -63, 58, -63, -63, 58, 100, 58, 58,
- 101, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -63
- },
-
- {
- 11, -64, -64, -64, -64, -64, -64, -64, -64, -64,
- -64, -64, -64, 58, -64, -64, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 102, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 103, -64
-
- },
-
- {
- 11, -65, -65, -65, -65, -65, -65, -65, -65, -65,
- -65, -65, -65, 58, -65, -65, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -65
- },
-
- {
- 11, -66, -66, -66, -66, -66, -66, -66, -66, -66,
- -66, -66, -66, 58, -66, -66, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 104, 58, 58, -66
- },
-
- {
- 11, -67, -67, -67, -67, -67, -67, -67, -67, -67,
- -67, -67, -67, 58, -67, -67, 58, 58, 58, 58,
-
- 58, 58, 58, 58, 58, 105, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -67
- },
-
- {
- 11, -68, -68, -68, -68, -68, -68, -68, -68, -68,
- -68, -68, -68, 58, -68, -68, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 106, 58,
- 58, 58, 58, 58, 58, 58, 58, -68
- },
-
- {
- 11, -69, -69, -69, -69, -69, -69, -69, -69, -69,
- -69, -69, -69, 58, -69, -69, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 107, 58, 58, -69
-
- },
-
- {
- 11, -70, -70, -70, -70, -70, -70, -70, -70, -70,
- -70, -70, -70, 58, -70, -70, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 108,
- 58, 58, 58, 58, 58, 58, 58, -70
- },
-
- {
- 11, -71, -71, -71, -71, -71, -71, -71, -71, -71,
- -71, -71, -71, 58, -71, -71, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 109, 58,
- 58, 58, 58, 58, 58, 58, 58, -71
- },
-
- {
- 11, -72, -72, -72, -72, -72, -72, -72, -72, -72,
- -72, -72, -72, 58, -72, -72, 58, 58, 58, 58,
-
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 110, 58, 58, 58, 58, 58, -72
- },
-
- {
- 11, -73, -73, -73, -73, -73, -73, -73, -73, -73,
- -73, -73, -73, 58, -73, -73, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 111, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -73
- },
-
- {
- 11, -74, -74, -74, -74, -74, -74, -74, -74, -74,
- -74, -74, -74, 58, -74, -74, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 112, 58, -74
-
- },
-
- {
- 11, -75, -75, -75, -75, -75, -75, -75, -75, -75,
- -75, -75, -75, 58, -75, -75, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 113, 58, 58, 58, 58, -75
- },
-
- {
- 11, -76, -76, -76, -76, -76, -76, -76, -76, -76,
- -76, -76, -76, 58, -76, -76, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 114, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -76
- },
-
- {
- 11, 77, 77, -77, 77, 77, 77, 77, 77, 77,
- 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
-
- 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
- 77, 77, 77, 77, 77, 77, 77, 77
- },
-
- {
- 11, -78, 78, 79, -78, -78, -78, -78, -78, -78,
- -78, -78, -78, -78, -78, -78, -78, -78, -78, -78,
- -78, -78, -78, -78, -78, -78, -78, -78, -78, -78,
- -78, -78, -78, -78, -78, -78, -78, -78
- },
-
- {
- 11, 80, -79, -79, 80, 80, 80, 80, 80, 80,
- 80, 80, 80, 80, 80, 80, 80, 80, 80, 80,
- 80, 80, 80, 80, 80, 80, 80, 80, 80, 80,
- 80, 80, 80, 80, 80, 80, 80, 80
-
- },
-
- {
- 11, -80, -80, -80, -80, -80, -80, -80, -80, -80,
- -80, -80, -80, -80, -80, -80, -80, -80, -80, -80,
- -80, -80, -80, -80, -80, -80, -80, -80, -80, -80,
- -80, -80, -80, -80, -80, -80, -80, -80
- },
-
- {
- 11, 81, 81, 82, 81, -81, 81, 81, -81, 81,
- 81, 81, 81, 81, 81, -81, 81, 81, 81, 81,
- 81, 81, 81, 81, 81, 81, 81, 81, 81, 81,
- 81, 81, 81, 81, 81, 81, 81, 81
- },
-
- {
- 11, -82, -82, -82, -82, -82, -82, -82, -82, -82,
- -82, -82, -82, -82, -82, -82, -82, -82, -82, -82,
-
- -82, -82, -82, -82, -82, -82, -82, -82, -82, -82,
- -82, -82, -82, -82, -82, -82, -82, -82
- },
-
- {
- 11, -83, -83, 84, -83, -83, -83, -83, -83, -83,
- -83, -83, -83, -83, -83, -83, -83, -83, -83, -83,
- -83, -83, -83, -83, -83, -83, -83, -83, -83, -83,
- -83, -83, -83, -83, -83, -83, -83, -83
- },
-
- {
- 11, -84, -84, -84, -84, -84, -84, -84, -84, -84,
- -84, -84, -84, -84, -84, -84, -84, -84, -84, -84,
- -84, -84, -84, -84, -84, -84, -84, -84, -84, -84,
- -84, -84, -84, -84, -84, -84, -84, -84
-
- },
-
- {
- 11, -85, -85, -85, -85, -85, -85, -85, -85, -85,
- -85, -85, -85, -85, -85, -85, -85, -85, -85, -85,
- -85, -85, -85, -85, -85, -85, -85, -85, -85, -85,
- -85, -85, -85, -85, -85, -85, -85, -85
- },
-
- {
- 11, 86, 86, -86, 86, 86, 86, 86, 86, 86,
- 86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
- 86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
- 86, 86, 86, 86, 86, 86, 86, 86
- },
-
- {
- 11, -87, -87, -87, -87, -87, -87, -87, -87, -87,
- -87, -87, -87, -87, -87, -87, -87, -87, -87, -87,
-
- -87, -87, -87, -87, -87, -87, -87, -87, -87, -87,
- -87, -87, -87, -87, -87, -87, -87, -87
- },
-
- {
- 11, -88, -88, -88, -88, -88, -88, -88, -88, -88,
- -88, 115, 89, 89, -88, -88, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, -88
- },
-
- {
- 11, -89, -89, -89, -89, -89, -89, -89, -89, -89,
- -89, 89, 89, 89, -89, -89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, -89
-
- },
-
- {
- 11, -90, -90, -90, -90, -90, -90, -90, -90, -90,
- -90, -90, -90, -90, -90, -90, -90, -90, -90, -90,
- -90, -90, -90, -90, -90, -90, -90, -90, -90, -90,
- -90, -90, -90, -90, -90, -90, -90, -90
- },
-
- {
- 11, -91, -91, -91, -91, -91, -91, -91, -91, -91,
- -91, 89, 89, 89, -91, -91, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, -91
- },
-
- {
- 11, -92, -92, -92, -92, -92, -92, -92, -92, -92,
- -92, 89, 89, 89, -92, -92, 89, 89, 89, 89,
-
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, -92
- },
-
- {
- 11, -93, -93, -93, -93, -93, -93, -93, -93, -93,
- -93, -93, -93, -93, -93, -93, -93, -93, -93, -93,
- -93, -93, -93, -93, -93, -93, -93, -93, -93, -93,
- -93, -93, -93, -93, -93, -93, -93, -93
- },
-
- {
- 11, -94, -94, -94, -94, -94, -94, -94, -94, -94,
- -94, -94, -94, 58, -94, -94, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 116, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -94
-
- },
-
- {
- 11, -95, -95, -95, -95, -95, -95, -95, -95, -95,
- -95, -95, -95, 58, -95, -95, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 117, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -95
- },
-
- {
- 11, -96, -96, -96, -96, -96, -96, -96, -96, -96,
- -96, -96, -96, 58, -96, -96, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 118, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -96
- },
-
- {
- 11, -97, -97, -97, -97, -97, -97, -97, -97, -97,
- -97, -97, -97, 58, -97, -97, 58, 58, 58, 58,
-
- 58, 58, 119, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -97
- },
-
- {
- 11, -98, -98, -98, -98, -98, -98, -98, -98, -98,
- -98, -98, -98, 58, -98, -98, 120, 121, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -98
- },
-
- {
- 11, -99, -99, -99, -99, -99, -99, -99, -99, -99,
- -99, -99, -99, 58, -99, -99, 58, 58, 58, 58,
- 58, 122, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -99
-
- },
-
- {
- 11, -100, -100, -100, -100, -100, -100, -100, -100, -100,
- -100, -100, -100, 58, -100, -100, 58, 58, 123, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -100
- },
-
- {
- 11, -101, -101, -101, -101, -101, -101, -101, -101, -101,
- -101, -101, -101, 58, -101, -101, 58, 58, 58, 124,
- 58, 58, 58, 58, 58, 125, 58, 126, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -101
- },
-
- {
- 11, -102, -102, -102, -102, -102, -102, -102, -102, -102,
- -102, -102, -102, 58, -102, -102, 58, 58, 58, 58,
-
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 127, 58, 58, 58, 58, 58, 58, -102
- },
-
- {
- 11, -103, -103, -103, -103, -103, -103, -103, -103, -103,
- -103, -103, -103, 58, -103, -103, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -103
- },
-
- {
- 11, -104, -104, -104, -104, -104, -104, -104, -104, -104,
- -104, -104, -104, 58, -104, -104, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -104
-
- },
-
- {
- 11, -105, -105, -105, -105, -105, -105, -105, -105, -105,
- -105, -105, -105, 58, -105, -105, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 128, 58,
- 58, 58, 58, 58, 58, 58, 58, -105
- },
-
- {
- 11, -106, -106, -106, -106, -106, -106, -106, -106, -106,
- -106, -106, -106, 58, -106, -106, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 129, 58, -106
- },
-
- {
- 11, -107, -107, -107, -107, -107, -107, -107, -107, -107,
- -107, -107, -107, 58, -107, -107, 58, 58, 58, 58,
-
- 58, 58, 58, 58, 58, 130, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -107
- },
-
- {
- 11, -108, -108, -108, -108, -108, -108, -108, -108, -108,
- -108, -108, -108, 58, -108, -108, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 131, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -108
- },
-
- {
- 11, -109, -109, -109, -109, -109, -109, -109, -109, -109,
- -109, -109, -109, 58, -109, -109, 58, 58, 58, 58,
- 58, 58, 58, 132, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -109
-
- },
-
- {
- 11, -110, -110, -110, -110, -110, -110, -110, -110, -110,
- -110, -110, -110, 58, -110, -110, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 133, 58, -110
- },
-
- {
- 11, -111, -111, -111, -111, -111, -111, -111, -111, -111,
- -111, -111, -111, 58, -111, -111, 58, 58, 58, 58,
- 58, 134, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -111
- },
-
- {
- 11, -112, -112, -112, -112, -112, -112, -112, -112, -112,
- -112, -112, -112, 58, -112, -112, 58, 58, 58, 58,
-
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 135, 58, 58, 58, 58, -112
- },
-
- {
- 11, -113, -113, -113, -113, -113, -113, -113, -113, -113,
- -113, -113, -113, 58, -113, -113, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 136, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -113
- },
-
- {
- 11, -114, -114, -114, -114, -114, -114, -114, -114, -114,
- -114, -114, -114, 58, -114, -114, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 137, 58, 58, 58, -114
-
- },
-
- {
- 11, -115, -115, -115, -115, -115, -115, -115, -115, -115,
- -115, 89, 89, 89, -115, -115, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, -115
- },
-
- {
- 11, -116, -116, -116, -116, -116, -116, -116, -116, -116,
- -116, -116, -116, 58, -116, -116, 58, 58, 58, 58,
- 58, 138, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -116
- },
-
- {
- 11, -117, -117, -117, -117, -117, -117, -117, -117, -117,
- -117, -117, -117, 58, -117, -117, 58, 58, 58, 139,
-
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -117
- },
-
- {
- 11, -118, -118, -118, -118, -118, -118, -118, -118, -118,
- -118, -118, -118, 58, -118, -118, 58, 58, 58, 58,
- 58, 140, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -118
- },
-
- {
- 11, -119, -119, -119, -119, -119, -119, -119, -119, -119,
- -119, -119, -119, 58, -119, -119, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 141, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -119
-
- },
-
- {
- 11, -120, -120, -120, -120, -120, -120, -120, -120, -120,
- -120, -120, -120, 58, -120, -120, 58, 58, 142, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 143, 58, 58, -120
- },
-
- {
- 11, -121, -121, -121, -121, -121, -121, -121, -121, -121,
- -121, -121, -121, 58, -121, -121, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 144, 58, -121
- },
-
- {
- 11, -122, -122, -122, -122, -122, -122, -122, -122, -122,
- -122, -122, -122, 58, -122, -122, 58, 58, 58, 58,
-
- 58, 58, 58, 58, 58, 58, 58, 58, 145, 58,
- 58, 58, 58, 58, 58, 58, 58, -122
- },
-
- {
- 11, -123, -123, -123, -123, -123, -123, -123, -123, -123,
- -123, -123, -123, 58, -123, -123, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 146, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -123
- },
-
- {
- 11, -124, -124, -124, -124, -124, -124, -124, -124, -124,
- -124, -124, -124, 58, -124, -124, 58, 58, 58, 58,
- 58, 58, 58, 58, 147, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -124
-
- },
-
- {
- 11, -125, -125, -125, -125, -125, -125, -125, -125, -125,
- -125, -125, -125, 58, -125, -125, 58, 58, 58, 58,
- 58, 58, 148, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -125
- },
-
- {
- 11, -126, -126, -126, -126, -126, -126, -126, -126, -126,
- -126, -126, -126, 58, -126, -126, 58, 58, 58, 58,
- 58, 149, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -126
- },
-
- {
- 11, -127, -127, -127, -127, -127, -127, -127, -127, -127,
- -127, -127, -127, 58, -127, -127, 58, 58, 58, 58,
-
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -127
- },
-
- {
- 11, -128, -128, -128, -128, -128, -128, -128, -128, -128,
- -128, -128, -128, 58, -128, -128, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 150, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -128
- },
-
- {
- 11, -129, -129, -129, -129, -129, -129, -129, -129, -129,
- -129, -129, -129, 58, -129, -129, 58, 58, 58, 151,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -129
-
- },
-
- {
- 11, -130, -130, -130, -130, -130, -130, -130, -130, -130,
- -130, -130, -130, 58, -130, -130, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 152,
- 58, 58, 58, 58, 58, 58, 58, -130
- },
-
- {
- 11, -131, -131, -131, -131, -131, -131, -131, -131, -131,
- -131, -131, -131, 58, -131, -131, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 153, 58, 58, 58, 58, 58, 58, -131
- },
-
- {
- 11, -132, -132, -132, -132, -132, -132, -132, -132, -132,
- -132, -132, -132, 58, -132, -132, 58, 58, 58, 58,
-
- 58, 154, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -132
- },
-
- {
- 11, -133, -133, -133, -133, -133, -133, -133, -133, -133,
- -133, -133, -133, 58, -133, -133, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 155, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -133
- },
-
- {
- 11, -134, -134, -134, -134, -134, -134, -134, -134, -134,
- -134, -134, -134, 58, -134, -134, 58, 58, 58, 156,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -134
-
- },
-
- {
- 11, -135, -135, -135, -135, -135, -135, -135, -135, -135,
- -135, -135, -135, 58, -135, -135, 58, 58, 58, 157,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -135
- },
-
- {
- 11, -136, -136, -136, -136, -136, -136, -136, -136, -136,
- -136, -136, -136, 58, -136, -136, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 158, 58,
- 58, 58, 58, 58, 58, 58, 58, -136
- },
-
- {
- 11, -137, -137, -137, -137, -137, -137, -137, -137, -137,
- -137, -137, -137, 58, -137, -137, 58, 58, 58, 58,
-
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 159, 58, 58, -137
- },
-
- {
- 11, -138, -138, -138, -138, -138, -138, -138, -138, -138,
- -138, -138, -138, 58, -138, -138, 58, 160, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -138
- },
-
- {
- 11, -139, -139, -139, -139, -139, -139, -139, -139, -139,
- -139, -139, -139, 58, -139, -139, 58, 58, 58, 58,
- 58, 161, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -139
-
- },
-
- {
- 11, -140, -140, -140, -140, -140, -140, -140, -140, -140,
- -140, -140, -140, 58, -140, -140, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 162, 58,
- 58, 58, 58, 58, 58, 58, 58, -140
- },
-
- {
- 11, -141, -141, -141, -141, -141, -141, -141, -141, -141,
- -141, -141, -141, 58, -141, -141, 58, 58, 58, 58,
- 58, 58, 58, 163, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -141
- },
-
- {
- 11, -142, -142, -142, -142, -142, -142, -142, -142, -142,
- -142, -142, -142, 58, -142, -142, 58, 58, 58, 58,
-
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 164,
- 58, 58, 58, 58, 58, 58, 58, -142
- },
-
- {
- 11, -143, -143, -143, -143, -143, -143, -143, -143, -143,
- -143, -143, -143, 58, -143, -143, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 165, 58, 58, 58, 58, -143
- },
-
- {
- 11, -144, -144, -144, -144, -144, -144, -144, -144, -144,
- -144, -144, -144, 58, -144, -144, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 166, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -144
-
- },
-
- {
- 11, -145, -145, -145, -145, -145, -145, -145, -145, -145,
- -145, -145, -145, 58, -145, -145, 58, 58, 58, 58,
- 167, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -145
- },
-
- {
- 11, -146, -146, -146, -146, -146, -146, -146, -146, -146,
- -146, -146, -146, 58, -146, -146, 58, 58, 58, 58,
- 58, 168, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -146
- },
-
- {
- 11, -147, -147, -147, -147, -147, -147, -147, -147, -147,
- -147, -147, -147, 58, -147, -147, 58, 58, 58, 58,
-
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 169,
- 58, 58, 58, 58, 58, 58, 58, -147
- },
-
- {
- 11, -148, -148, -148, -148, -148, -148, -148, -148, -148,
- -148, -148, -148, 58, -148, -148, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -148
- },
-
- {
- 11, -149, -149, -149, -149, -149, -149, -149, -149, -149,
- -149, -149, -149, 58, -149, -149, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 170, 58,
- 58, 58, 58, 58, 58, 58, 58, -149
-
- },
-
- {
- 11, -150, -150, -150, -150, -150, -150, -150, -150, -150,
- -150, -150, -150, 58, -150, -150, 58, 58, 58, 58,
- 58, 171, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -150
- },
-
- {
- 11, -151, -151, -151, -151, -151, -151, -151, -151, -151,
- -151, -151, -151, 58, -151, -151, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 172,
- 58, 58, 58, 58, 58, 58, 58, -151
- },
-
- {
- 11, -152, -152, -152, -152, -152, -152, -152, -152, -152,
- -152, -152, -152, 58, -152, -152, 58, 58, 58, 58,
-
- 58, 58, 58, 58, 58, 58, 58, 58, 173, 58,
- 58, 58, 58, 58, 58, 58, 58, -152
- },
-
- {
- 11, -153, -153, -153, -153, -153, -153, -153, -153, -153,
- -153, -153, -153, 58, -153, -153, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 174, 58, 58, -153
- },
-
- {
- 11, -154, -154, -154, -154, -154, -154, -154, -154, -154,
- -154, -154, -154, 58, -154, -154, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -154
-
- },
-
- {
- 11, -155, -155, -155, -155, -155, -155, -155, -155, -155,
- -155, -155, -155, 58, -155, -155, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 175, 58, 58, 58, 58, -155
- },
-
- {
- 11, -156, -156, -156, -156, -156, -156, -156, -156, -156,
- -156, -156, -156, 58, -156, -156, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 176, 58, 58, -156
- },
-
- {
- 11, -157, -157, -157, -157, -157, -157, -157, -157, -157,
- -157, -157, -157, 58, -157, -157, 58, 58, 58, 58,
-
- 58, 177, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -157
- },
-
- {
- 11, -158, -158, -158, -158, -158, -158, -158, -158, -158,
- -158, -158, -158, 58, -158, -158, 58, 58, 58, 58,
- 58, 58, 58, 178, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -158
- },
-
- {
- 11, -159, -159, -159, -159, -159, -159, -159, -159, -159,
- -159, -159, -159, 58, -159, -159, 58, 179, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -159
-
- },
-
- {
- 11, -160, -160, -160, -160, -160, -160, -160, -160, -160,
- -160, -160, -160, 58, -160, -160, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 180, 58,
- 58, 58, 58, 58, 58, 58, 58, -160
- },
-
- {
- 11, -161, -161, -161, -161, -161, -161, -161, -161, -161,
- -161, -161, -161, 58, -161, -161, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -161
- },
-
- {
- 11, -162, -162, -162, -162, -162, -162, -162, -162, -162,
- -162, -162, -162, 58, -162, -162, 58, 58, 58, 58,
-
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 181, 58, 58, -162
- },
-
- {
- 11, -163, -163, -163, -163, -163, -163, -163, -163, -163,
- -163, -163, -163, 58, -163, -163, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -163
- },
-
- {
- 11, -164, -164, -164, -164, -164, -164, -164, -164, -164,
- -164, -164, -164, 58, -164, -164, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 182,
- 58, 58, 58, 58, 58, 58, 58, -164
-
- },
-
- {
- 11, -165, -165, -165, -165, -165, -165, -165, -165, -165,
- -165, -165, -165, 58, -165, -165, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 183, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -165
- },
-
- {
- 11, -166, -166, -166, -166, -166, -166, -166, -166, -166,
- -166, -166, -166, 58, -166, -166, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 184, 58, 58, -166
- },
-
- {
- 11, -167, -167, -167, -167, -167, -167, -167, -167, -167,
- -167, -167, -167, 58, -167, -167, 58, 58, 58, 58,
-
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 185, 58, 58, 58, -167
- },
-
- {
- 11, -168, -168, -168, -168, -168, -168, -168, -168, -168,
- -168, -168, -168, 58, -168, -168, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -168
- },
-
- {
- 11, -169, -169, -169, -169, -169, -169, -169, -169, -169,
- -169, -169, -169, 58, -169, -169, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 186, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -169
-
- },
-
- {
- 11, -170, -170, -170, -170, -170, -170, -170, -170, -170,
- -170, -170, -170, 58, -170, -170, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 187, 58, -170
- },
-
- {
- 11, -171, -171, -171, -171, -171, -171, -171, -171, -171,
- -171, -171, -171, 58, -171, -171, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 188, 58,
- 58, 58, 58, 58, 58, 58, 58, -171
- },
-
- {
- 11, -172, -172, -172, -172, -172, -172, -172, -172, -172,
- -172, -172, -172, 58, -172, -172, 58, 58, 58, 58,
-
- 58, 58, 58, 58, 58, 58, 58, 58, 189, 58,
- 58, 58, 58, 58, 58, 58, 58, -172
- },
-
- {
- 11, -173, -173, -173, -173, -173, -173, -173, -173, -173,
- -173, -173, -173, 58, -173, -173, 58, 190, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -173
- },
-
- {
- 11, -174, -174, -174, -174, -174, -174, -174, -174, -174,
- -174, -174, -174, 58, -174, -174, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -174
-
- },
-
- {
- 11, -175, -175, -175, -175, -175, -175, -175, -175, -175,
- -175, -175, -175, 58, -175, -175, 58, 58, 58, 58,
- 58, 191, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -175
- },
-
- {
- 11, -176, -176, -176, -176, -176, -176, -176, -176, -176,
- -176, -176, -176, 58, -176, -176, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -176
- },
-
- {
- 11, -177, -177, -177, -177, -177, -177, -177, -177, -177,
- -177, -177, -177, 58, -177, -177, 58, 58, 58, 58,
-
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -177
- },
-
- {
- 11, -178, -178, -178, -178, -178, -178, -178, -178, -178,
- -178, -178, -178, 58, -178, -178, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -178
- },
-
- {
- 11, -179, -179, -179, -179, -179, -179, -179, -179, -179,
- -179, -179, -179, 58, -179, -179, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 192, 58, 58, -179
-
- },
-
- {
- 11, -180, -180, -180, -180, -180, -180, -180, -180, -180,
- -180, -180, -180, 58, -180, -180, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -180
- },
-
- {
- 11, -181, -181, -181, -181, -181, -181, -181, -181, -181,
- -181, -181, -181, 58, -181, -181, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -181
- },
-
- {
- 11, -182, -182, -182, -182, -182, -182, -182, -182, -182,
- -182, -182, -182, 58, -182, -182, 58, 58, 58, 58,
-
- 58, 58, 58, 58, 58, 58, 193, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -182
- },
-
- {
- 11, -183, -183, -183, -183, -183, -183, -183, -183, -183,
- -183, -183, -183, 58, -183, -183, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 194, 58, 58, 58, -183
- },
-
- {
- 11, -184, -184, -184, -184, -184, -184, -184, -184, -184,
- -184, -184, -184, 58, -184, -184, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -184
-
- },
-
- {
- 11, -185, -185, -185, -185, -185, -185, -185, -185, -185,
- -185, -185, -185, 58, -185, -185, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -185
- },
-
- {
- 11, -186, -186, -186, -186, -186, -186, -186, -186, -186,
- -186, -186, -186, 58, -186, -186, 58, 58, 58, 195,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -186
- },
-
- {
- 11, -187, -187, -187, -187, -187, -187, -187, -187, -187,
- -187, -187, -187, 58, -187, -187, 58, 58, 58, 58,
-
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -187
- },
-
- {
- 11, -188, -188, -188, -188, -188, -188, -188, -188, -188,
- -188, -188, -188, 58, -188, -188, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 196, 58, -188
- },
-
- {
- 11, -189, -189, -189, -189, -189, -189, -189, -189, -189,
- -189, -189, -189, 58, -189, -189, 58, 58, 58, 58,
- 58, 58, 197, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -189
-
- },
-
- {
- 11, -190, -190, -190, -190, -190, -190, -190, -190, -190,
- -190, -190, -190, 58, -190, -190, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 198, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -190
- },
-
- {
- 11, -191, -191, -191, -191, -191, -191, -191, -191, -191,
- -191, -191, -191, 58, -191, -191, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 199, 58, 58, 58, -191
- },
-
- {
- 11, -192, -192, -192, -192, -192, -192, -192, -192, -192,
- -192, -192, -192, 58, -192, -192, 58, 58, 58, 58,
-
- 58, 200, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -192
- },
-
- {
- 11, -193, -193, -193, -193, -193, -193, -193, -193, -193,
- -193, -193, -193, 58, -193, -193, 58, 58, 58, 58,
- 58, 201, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -193
- },
-
- {
- 11, -194, -194, -194, -194, -194, -194, -194, -194, -194,
- -194, -194, -194, 58, -194, -194, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 202, 58, 58, -194
-
- },
-
- {
- 11, -195, -195, -195, -195, -195, -195, -195, -195, -195,
- -195, -195, -195, 58, -195, -195, 58, 58, 58, 58,
- 58, 203, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -195
- },
-
- {
- 11, -196, -196, -196, -196, -196, -196, -196, -196, -196,
- -196, -196, -196, 58, -196, -196, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -196
- },
-
- {
- 11, -197, -197, -197, -197, -197, -197, -197, -197, -197,
- -197, -197, -197, 58, -197, -197, 58, 58, 58, 58,
-
- 58, 58, 58, 58, 58, 204, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -197
- },
-
- {
- 11, -198, -198, -198, -198, -198, -198, -198, -198, -198,
- -198, -198, -198, 58, -198, -198, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -198
- },
-
- {
- 11, -199, -199, -199, -199, -199, -199, -199, -199, -199,
- -199, -199, -199, 58, -199, -199, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -199
-
- },
-
- {
- 11, -200, -200, -200, -200, -200, -200, -200, -200, -200,
- -200, -200, -200, 58, -200, -200, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -200
- },
-
- {
- 11, -201, -201, -201, -201, -201, -201, -201, -201, -201,
- -201, -201, -201, 58, -201, -201, 58, 205, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -201
- },
-
- {
- 11, -202, -202, -202, -202, -202, -202, -202, -202, -202,
- -202, -202, -202, 58, -202, -202, 58, 206, 58, 58,
-
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -202
- },
-
- {
- 11, -203, -203, -203, -203, -203, -203, -203, -203, -203,
- -203, -203, -203, 58, -203, -203, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -203
- },
-
- {
- 11, -204, -204, -204, -204, -204, -204, -204, -204, -204,
- -204, -204, -204, 58, -204, -204, 58, 58, 58, 58,
- 58, 58, 58, 207, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -204
-
- },
-
- {
- 11, -205, -205, -205, -205, -205, -205, -205, -205, -205,
- -205, -205, -205, 58, -205, -205, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 208, 58,
- 58, 58, 58, 58, 58, 58, 58, -205
- },
-
- {
- 11, -206, -206, -206, -206, -206, -206, -206, -206, -206,
- -206, -206, -206, 58, -206, -206, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 209, 58, 58, -206
- },
-
- {
- 11, -207, -207, -207, -207, -207, -207, -207, -207, -207,
- -207, -207, -207, 58, -207, -207, 58, 58, 58, 58,
-
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -207
- },
-
- {
- 11, -208, -208, -208, -208, -208, -208, -208, -208, -208,
- -208, -208, -208, 58, -208, -208, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -208
- },
-
- {
- 11, -209, -209, -209, -209, -209, -209, -209, -209, -209,
- -209, -209, -209, 58, -209, -209, 58, 58, 58, 58,
- 58, 210, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -209
-
- },
-
- {
- 11, -210, -210, -210, -210, -210, -210, -210, -210, -210,
- -210, -210, -210, 58, -210, -210, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -210
+ -60, 57, 57, 57, -60, -60, -60
},
} ;
@@ -1918,8 +674,8 @@ static void yy_fatal_error (yyconst char msg[] );
*yy_cp = '\0'; \
(yy_c_buf_p) = yy_cp;
-#define YY_NUM_RULES 64
-#define YY_END_OF_BUFFER 65
+#define YY_NUM_RULES 33
+#define YY_END_OF_BUFFER 34
/* This struct is not used in this scanner,
but its presence is necessary. */
struct yy_trans_info
@@ -1927,31 +683,14 @@ struct yy_trans_info
flex_int32_t yy_verify;
flex_int32_t yy_nxt;
};
-static yyconst flex_int16_t yy_accept[211] =
+static yyconst flex_int16_t yy_accept[61] =
{ 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 65, 5, 4, 3, 2, 36, 37, 35, 35, 35,
- 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
- 63, 60, 62, 55, 59, 58, 57, 53, 48, 42,
- 47, 51, 53, 40, 41, 50, 50, 43, 53, 50,
- 50, 53, 4, 3, 2, 2, 1, 35, 35, 35,
- 35, 35, 35, 35, 16, 35, 35, 35, 35, 35,
- 35, 35, 35, 35, 35, 35, 63, 60, 62, 61,
- 55, 54, 57, 56, 44, 51, 38, 50, 50, 52,
- 45, 46, 39, 35, 35, 35, 35, 35, 35, 35,
-
- 35, 35, 30, 29, 35, 35, 35, 35, 35, 35,
- 35, 35, 35, 35, 49, 25, 35, 35, 35, 35,
- 35, 35, 35, 35, 35, 35, 15, 35, 7, 35,
- 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
- 35, 35, 35, 35, 35, 35, 35, 17, 35, 35,
- 35, 35, 35, 34, 35, 35, 35, 35, 35, 35,
- 10, 35, 13, 35, 35, 35, 35, 33, 35, 35,
- 35, 35, 35, 22, 35, 32, 9, 31, 35, 26,
- 12, 35, 35, 21, 18, 35, 8, 35, 35, 35,
- 35, 35, 27, 35, 35, 6, 35, 20, 19, 23,
-
- 35, 35, 11, 35, 35, 35, 14, 28, 35, 24
+ 34, 5, 4, 2, 3, 7, 8, 6, 32, 29,
+ 31, 24, 28, 27, 26, 22, 17, 13, 16, 20,
+ 22, 11, 12, 19, 19, 14, 22, 22, 4, 2,
+ 3, 3, 1, 6, 32, 29, 31, 30, 24, 23,
+ 26, 25, 15, 20, 9, 19, 19, 21, 10, 18
} ;
static yyconst flex_int32_t yy_ec[256] =
@@ -1965,11 +704,11 @@ static yyconst flex_int32_t yy_ec[256] =
14, 1, 1, 1, 13, 13, 13, 13, 13, 13,
13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
- 1, 15, 1, 1, 16, 1, 17, 18, 19, 20,
+ 1, 15, 1, 1, 13, 1, 13, 13, 13, 13,
- 21, 22, 23, 24, 25, 13, 13, 26, 27, 28,
- 29, 30, 31, 32, 33, 34, 35, 13, 13, 36,
- 13, 13, 1, 37, 1, 1, 1, 1, 1, 1,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 1, 16, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
@@ -2014,8 +753,12 @@ char *zconftext;
#define START_STRSIZE 16
-char *text;
-static char *text_ptr;
+static struct {
+ struct file *file;
+ int lineno;
+} current_pos;
+
+static char *text;
static int text_size, text_asize;
struct buffer {
@@ -2028,29 +771,28 @@ struct buffer *current_buf;
static int last_ts, first_ts;
static void zconf_endhelp(void);
-static struct buffer *zconf_endfile(void);
+static void zconf_endfile(void);
void new_string(void)
{
text = malloc(START_STRSIZE);
text_asize = START_STRSIZE;
- text_ptr = text;
text_size = 0;
- *text_ptr = 0;
+ *text = 0;
}
void append_string(const char *str, int size)
{
int new_size = text_size + size + 1;
if (new_size > text_asize) {
+ new_size += START_STRSIZE - 1;
+ new_size &= -START_STRSIZE;
text = realloc(text, new_size);
text_asize = new_size;
- text_ptr = text + text_size;
}
- memcpy(text_ptr, str, size);
- text_ptr += size;
+ memcpy(text + text_size, str, size);
text_size += size;
- *text_ptr = 0;
+ text[text_size] = 0;
}
void alloc_string(const char *str, int size)
@@ -2066,11 +808,13 @@ void alloc_string(const char *str, int size)
#define STRING 3
#define PARAM 4
+#ifndef YY_NO_UNISTD_H
/* Special case for "unistd.h", since it is non-ANSI. We include it way
* down here because we want the user's section 1 to have been scanned first.
* The user has a chance to override it with an option.
*/
#include <unistd.h>
+#endif
#ifndef YY_EXTRA_TYPE
#define YY_EXTRA_TYPE void *
@@ -2254,17 +998,17 @@ do_action: /* This label is used only to access EOF actions. */
{ /* beginning of action switch */
case 1:
/* rule 1 can match eol */
-YY_RULE_SETUP
-current_file->lineno++;
- YY_BREAK
case 2:
+/* rule 2 can match eol */
YY_RULE_SETUP
-
+{
+ current_file->lineno++;
+ return T_EOL;
+}
YY_BREAK
case 3:
-/* rule 3 can match eol */
YY_RULE_SETUP
-current_file->lineno++; return T_EOL;
+
YY_BREAK
case 4:
YY_RULE_SETUP
@@ -2282,175 +1026,63 @@ YY_RULE_SETUP
case 6:
YY_RULE_SETUP
-BEGIN(PARAM); return T_MAINMENU;
- YY_BREAK
-case 7:
-YY_RULE_SETUP
-BEGIN(PARAM); return T_MENU;
- YY_BREAK
-case 8:
-YY_RULE_SETUP
-BEGIN(PARAM); return T_ENDMENU;
- YY_BREAK
-case 9:
-YY_RULE_SETUP
-BEGIN(PARAM); return T_SOURCE;
- YY_BREAK
-case 10:
-YY_RULE_SETUP
-BEGIN(PARAM); return T_CHOICE;
- YY_BREAK
-case 11:
-YY_RULE_SETUP
-BEGIN(PARAM); return T_ENDCHOICE;
- YY_BREAK
-case 12:
-YY_RULE_SETUP
-BEGIN(PARAM); return T_COMMENT;
- YY_BREAK
-case 13:
-YY_RULE_SETUP
-BEGIN(PARAM); return T_CONFIG;
- YY_BREAK
-case 14:
-YY_RULE_SETUP
-BEGIN(PARAM); return T_MENUCONFIG;
- YY_BREAK
-case 15:
-YY_RULE_SETUP
-BEGIN(PARAM); return T_HELP;
- YY_BREAK
-case 16:
-YY_RULE_SETUP
-BEGIN(PARAM); return T_IF;
- YY_BREAK
-case 17:
-YY_RULE_SETUP
-BEGIN(PARAM); return T_ENDIF;
- YY_BREAK
-case 18:
-YY_RULE_SETUP
-BEGIN(PARAM); return T_DEPENDS;
- YY_BREAK
-case 19:
-YY_RULE_SETUP
-BEGIN(PARAM); return T_REQUIRES;
- YY_BREAK
-case 20:
-YY_RULE_SETUP
-BEGIN(PARAM); return T_OPTIONAL;
- YY_BREAK
-case 21:
-YY_RULE_SETUP
-BEGIN(PARAM); return T_DEFAULT;
- YY_BREAK
-case 22:
-YY_RULE_SETUP
-BEGIN(PARAM); return T_PROMPT;
- YY_BREAK
-case 23:
-YY_RULE_SETUP
-BEGIN(PARAM); return T_TRISTATE;
- YY_BREAK
-case 24:
-YY_RULE_SETUP
-BEGIN(PARAM); return T_DEF_TRISTATE;
- YY_BREAK
-case 25:
-YY_RULE_SETUP
-BEGIN(PARAM); return T_BOOLEAN;
- YY_BREAK
-case 26:
-YY_RULE_SETUP
-BEGIN(PARAM); return T_BOOLEAN;
- YY_BREAK
-case 27:
-YY_RULE_SETUP
-BEGIN(PARAM); return T_DEF_BOOLEAN;
- YY_BREAK
-case 28:
-YY_RULE_SETUP
-BEGIN(PARAM); return T_DEF_BOOLEAN;
- YY_BREAK
-case 29:
-YY_RULE_SETUP
-BEGIN(PARAM); return T_INT;
- YY_BREAK
-case 30:
-YY_RULE_SETUP
-BEGIN(PARAM); return T_HEX;
- YY_BREAK
-case 31:
-YY_RULE_SETUP
-BEGIN(PARAM); return T_STRING;
- YY_BREAK
-case 32:
-YY_RULE_SETUP
-BEGIN(PARAM); return T_SELECT;
- YY_BREAK
-case 33:
-YY_RULE_SETUP
-BEGIN(PARAM); return T_SELECT;
- YY_BREAK
-case 34:
-YY_RULE_SETUP
-BEGIN(PARAM); return T_RANGE;
- YY_BREAK
-case 35:
-YY_RULE_SETUP
{
+ struct kconf_id *id = kconf_id_lookup(zconftext, zconfleng);
+ BEGIN(PARAM);
+ current_pos.file = current_file;
+ current_pos.lineno = current_file->lineno;
+ if (id && id->flags & TF_COMMAND) {
+ zconflval.id = id;
+ return id->token;
+ }
alloc_string(zconftext, zconfleng);
zconflval.string = text;
return T_WORD;
}
YY_BREAK
-case 36:
+case 7:
YY_RULE_SETUP
YY_BREAK
-case 37:
-/* rule 37 can match eol */
+case 8:
+/* rule 8 can match eol */
YY_RULE_SETUP
-current_file->lineno++; BEGIN(INITIAL);
+{
+ BEGIN(INITIAL);
+ current_file->lineno++;
+ return T_EOL;
+ }
YY_BREAK
-case 38:
+case 9:
YY_RULE_SETUP
return T_AND;
YY_BREAK
-case 39:
+case 10:
YY_RULE_SETUP
return T_OR;
YY_BREAK
-case 40:
+case 11:
YY_RULE_SETUP
return T_OPEN_PAREN;
YY_BREAK
-case 41:
+case 12:
YY_RULE_SETUP
return T_CLOSE_PAREN;
YY_BREAK
-case 42:
+case 13:
YY_RULE_SETUP
return T_NOT;
YY_BREAK
-case 43:
+case 14:
YY_RULE_SETUP
return T_EQUAL;
YY_BREAK
-case 44:
+case 15:
YY_RULE_SETUP
return T_UNEQUAL;
YY_BREAK
-case 45:
-YY_RULE_SETUP
-return T_IF;
- YY_BREAK
-case 46:
-YY_RULE_SETUP
-return T_ON;
- YY_BREAK
-case 47:
+case 16:
YY_RULE_SETUP
{
str = zconftext[0];
@@ -2458,33 +1090,38 @@ YY_RULE_SETUP
BEGIN(STRING);
}
YY_BREAK
-case 48:
-/* rule 48 can match eol */
+case 17:
+/* rule 17 can match eol */
YY_RULE_SETUP
BEGIN(INITIAL); current_file->lineno++; return T_EOL;
YY_BREAK
-case 49:
+case 18:
YY_RULE_SETUP
/* ignore */
YY_BREAK
-case 50:
+case 19:
YY_RULE_SETUP
{
+ struct kconf_id *id = kconf_id_lookup(zconftext, zconfleng);
+ if (id && id->flags & TF_PARAM) {
+ zconflval.id = id;
+ return id->token;
+ }
alloc_string(zconftext, zconfleng);
zconflval.string = text;
return T_WORD;
}
YY_BREAK
-case 51:
+case 20:
YY_RULE_SETUP
/* comment */
YY_BREAK
-case 52:
-/* rule 52 can match eol */
+case 21:
+/* rule 21 can match eol */
YY_RULE_SETUP
current_file->lineno++;
YY_BREAK
-case 53:
+case 22:
YY_RULE_SETUP
YY_BREAK
@@ -2494,8 +1131,8 @@ case YY_STATE_EOF(PARAM):
}
YY_BREAK
-case 54:
-/* rule 54 can match eol */
+case 23:
+/* rule 23 can match eol */
*yy_cp = (yy_hold_char); /* undo effects of setting up zconftext */
(yy_c_buf_p) = yy_cp -= 1;
YY_DO_BEFORE_ACTION; /* set up zconftext again */
@@ -2506,14 +1143,14 @@ YY_RULE_SETUP
return T_WORD_QUOTE;
}
YY_BREAK
-case 55:
+case 24:
YY_RULE_SETUP
{
append_string(zconftext, zconfleng);
}
YY_BREAK
-case 56:
-/* rule 56 can match eol */
+case 25:
+/* rule 25 can match eol */
*yy_cp = (yy_hold_char); /* undo effects of setting up zconftext */
(yy_c_buf_p) = yy_cp -= 1;
YY_DO_BEFORE_ACTION; /* set up zconftext again */
@@ -2524,13 +1161,13 @@ YY_RULE_SETUP
return T_WORD_QUOTE;
}
YY_BREAK
-case 57:
+case 26:
YY_RULE_SETUP
{
append_string(zconftext + 1, zconfleng - 1);
}
YY_BREAK
-case 58:
+case 27:
YY_RULE_SETUP
{
if (str == zconftext[0]) {
@@ -2541,8 +1178,8 @@ YY_RULE_SETUP
append_string(zconftext, 1);
}
YY_BREAK
-case 59:
-/* rule 59 can match eol */
+case 28:
+/* rule 28 can match eol */
YY_RULE_SETUP
{
printf("%s:%d:warning: multi-line strings not supported\n", zconf_curname(), zconf_lineno());
@@ -2557,7 +1194,7 @@ case YY_STATE_EOF(STRING):
}
YY_BREAK
-case 60:
+case 29:
YY_RULE_SETUP
{
ts = 0;
@@ -2582,8 +1219,8 @@ YY_RULE_SETUP
}
}
YY_BREAK
-case 61:
-/* rule 61 can match eol */
+case 30:
+/* rule 30 can match eol */
*yy_cp = (yy_hold_char); /* undo effects of setting up zconftext */
(yy_c_buf_p) = yy_cp -= 1;
YY_DO_BEFORE_ACTION; /* set up zconftext again */
@@ -2594,15 +1231,15 @@ YY_RULE_SETUP
return T_HELPTEXT;
}
YY_BREAK
-case 62:
-/* rule 62 can match eol */
+case 31:
+/* rule 31 can match eol */
YY_RULE_SETUP
{
current_file->lineno++;
append_string("\n", 1);
}
YY_BREAK
-case 63:
+case 32:
YY_RULE_SETUP
{
append_string(zconftext, zconfleng);
@@ -2620,15 +1257,15 @@ case YY_STATE_EOF(HELP):
case YY_STATE_EOF(INITIAL):
case YY_STATE_EOF(COMMAND):
{
- if (current_buf) {
+ if (current_file) {
zconf_endfile();
- return T_EOF;
+ return T_EOL;
}
fclose(zconfin);
yyterminate();
}
YY_BREAK
-case 64:
+case 33:
YY_RULE_SETUP
YY_FATAL_ERROR( "flex scanner jammed" );
YY_BREAK
@@ -3332,16 +1969,16 @@ YY_BUFFER_STATE zconf_scan_buffer (char * base, yy_size_t size )
/** Setup the input buffer state to scan a string. The next call to zconflex() will
* scan from a @e copy of @a str.
- * @param str a NUL-terminated string to scan
+ * @param yy_str a NUL-terminated string to scan
*
* @return the newly allocated buffer state object.
* @note If you want to scan bytes that may contain NUL values, then use
* zconf_scan_bytes() instead.
*/
-YY_BUFFER_STATE zconf_scan_string (yyconst char * str )
+YY_BUFFER_STATE zconf_scan_string (yyconst char * yy_str )
{
- return zconf_scan_bytes(str,strlen(str) );
+ return zconf_scan_bytes(yy_str,strlen(yy_str) );
}
/** Setup the input buffer state to scan the given bytes. The next call to zconflex() will
@@ -3650,7 +2287,7 @@ void zconf_nextfile(const char *name)
current_file = file;
}
-static struct buffer *zconf_endfile(void)
+static void zconf_endfile(void)
{
struct buffer *parent;
@@ -3666,23 +2303,15 @@ static struct buffer *zconf_endfile(void)
}
free(current_buf);
current_buf = parent;
-
- return parent;
}
int zconf_lineno(void)
{
- if (current_buf)
- return current_file->lineno - 1;
- else
- return 0;
+ return current_pos.lineno;
}
char *zconf_curname(void)
{
- if (current_buf)
- return current_file->name;
- else
- return "<none>";
+ return current_pos.file ? current_pos.file->name : "<none>";
}
diff --git a/scripts/kconfig/lkc.h b/scripts/kconfig/lkc.h
index c3d25786a64d..527f60c99c50 100644
--- a/scripts/kconfig/lkc.h
+++ b/scripts/kconfig/lkc.h
@@ -8,7 +8,13 @@
#include "expr.h"
-#include <libintl.h>
+#ifndef KBUILD_NO_NLS
+# include <libintl.h>
+#else
+# define gettext(Msgid) ((const char *) (Msgid))
+# define textdomain(Domainname) ((const char *) (Domainname))
+# define bindtextdomain(Domainname, Dirname) ((const char *) (Dirname))
+#endif
#ifdef __cplusplus
extern "C" {
@@ -31,6 +37,17 @@ extern "C" {
#define _(text) gettext(text)
#define N_(text) (text)
+
+#define TF_COMMAND 0x0001
+#define TF_PARAM 0x0002
+
+struct kconf_id {
+ int name;
+ int token;
+ unsigned int flags;
+ enum symbol_type stype;
+};
+
int zconfparse(void);
void zconfdump(FILE *out);
@@ -44,7 +61,6 @@ char *zconf_curname(void);
/* confdata.c */
extern const char conf_def_filename[];
-extern char conf_filename[];
char *conf_get_default_confname(void);
@@ -53,7 +69,7 @@ void kconfig_load(void);
/* menu.c */
void menu_init(void);
-void menu_add_menu(void);
+struct menu *menu_add_menu(void);
void menu_end_menu(void);
void menu_add_entry(struct symbol *sym);
void menu_end_entry(void);
diff --git a/scripts/kconfig/lkc_proto.h b/scripts/kconfig/lkc_proto.h
index 6dc6d0c48e7a..b6a389c5fcbd 100644
--- a/scripts/kconfig/lkc_proto.h
+++ b/scripts/kconfig/lkc_proto.h
@@ -2,6 +2,7 @@
/* confdata.c */
P(conf_parse,void,(const char *name));
P(conf_read,int,(const char *name));
+P(conf_read_simple,int,(const char *name));
P(conf_write,int,(const char *name));
/* menu.c */
diff --git a/scripts/kconfig/mconf.c b/scripts/kconfig/mconf.c
index 457bec29511d..d1ad40531ee5 100644
--- a/scripts/kconfig/mconf.c
+++ b/scripts/kconfig/mconf.c
@@ -219,6 +219,7 @@ save_config_help[] = N_(
search_help[] = N_(
"\n"
"Search for CONFIG_ symbols and display their relations.\n"
+ "Regular expressions are allowed.\n"
"Example: search for \"^FOO\"\n"
"Result:\n"
"-----------------------------------------------------------------\n"
@@ -531,7 +532,7 @@ again:
cprint("--title");
cprint(_("Search Configuration Parameter"));
cprint("--inputbox");
- cprint(_("Enter Keyword"));
+ cprint(_("Enter CONFIG_ (sub)string to search for (omit CONFIG_)"));
cprint("10");
cprint("75");
cprint("");
diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c
index 5cfa6c405cf0..0fce20cb7f3c 100644
--- a/scripts/kconfig/menu.c
+++ b/scripts/kconfig/menu.c
@@ -61,10 +61,11 @@ void menu_end_entry(void)
{
}
-void menu_add_menu(void)
+struct menu *menu_add_menu(void)
{
- current_menu = current_entry;
+ menu_end_entry();
last_entry_ptr = &current_entry->list;
+ return current_menu = current_entry;
}
void menu_end_menu(void)
@@ -151,6 +152,12 @@ void menu_add_symbol(enum prop_type type, struct symbol *sym, struct expr *dep)
menu_add_prop(type, NULL, expr_alloc_symbol(sym), dep);
}
+static int menu_range_valid_sym(struct symbol *sym, struct symbol *sym2)
+{
+ return sym2->type == S_INT || sym2->type == S_HEX ||
+ (sym2->type == S_UNKNOWN && sym_string_valid(sym, sym2->name));
+}
+
void sym_check_prop(struct symbol *sym)
{
struct property *prop;
@@ -185,8 +192,8 @@ void sym_check_prop(struct symbol *sym)
if (sym->type != S_INT && sym->type != S_HEX)
prop_warn(prop, "range is only allowed "
"for int or hex symbols");
- if (!sym_string_valid(sym, prop->expr->left.sym->name) ||
- !sym_string_valid(sym, prop->expr->right.sym->name))
+ if (!menu_range_valid_sym(sym, prop->expr->left.sym) ||
+ !menu_range_valid_sym(sym, prop->expr->right.sym))
prop_warn(prop, "range is invalid");
break;
default:
diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c
index affa52f5c651..69c2549c0baa 100644
--- a/scripts/kconfig/symbol.c
+++ b/scripts/kconfig/symbol.c
@@ -141,6 +141,55 @@ struct property *sym_get_range_prop(struct symbol *sym)
return NULL;
}
+static int sym_get_range_val(struct symbol *sym, int base)
+{
+ sym_calc_value(sym);
+ switch (sym->type) {
+ case S_INT:
+ base = 10;
+ break;
+ case S_HEX:
+ base = 16;
+ break;
+ default:
+ break;
+ }
+ return strtol(sym->curr.val, NULL, base);
+}
+
+static void sym_validate_range(struct symbol *sym)
+{
+ struct property *prop;
+ int base, val, val2;
+ char str[64];
+
+ switch (sym->type) {
+ case S_INT:
+ base = 10;
+ break;
+ case S_HEX:
+ base = 16;
+ break;
+ default:
+ return;
+ }
+ prop = sym_get_range_prop(sym);
+ if (!prop)
+ return;
+ val = strtol(sym->curr.val, NULL, base);
+ val2 = sym_get_range_val(prop->expr->left.sym, base);
+ if (val >= val2) {
+ val2 = sym_get_range_val(prop->expr->right.sym, base);
+ if (val <= val2)
+ return;
+ }
+ if (sym->type == S_INT)
+ sprintf(str, "%d", val2);
+ else
+ sprintf(str, "0x%x", val2);
+ sym->curr.val = strdup(str);
+}
+
static void sym_calc_visibility(struct symbol *sym)
{
struct property *prop;
@@ -301,6 +350,7 @@ void sym_calc_value(struct symbol *sym)
sym->curr = newval;
if (sym_is_choice(sym) && newval.tri == yes)
sym->curr.val = sym_calc_choice(sym);
+ sym_validate_range(sym);
if (memcmp(&oldval, &sym->curr, sizeof(oldval)))
sym_set_changed(sym);
@@ -380,11 +430,22 @@ bool sym_set_tristate_value(struct symbol *sym, tristate val)
sym->flags &= ~SYMBOL_NEW;
sym_set_changed(sym);
}
+ /*
+ * setting a choice value also resets the new flag of the choice
+ * symbol and all other choice values.
+ */
if (sym_is_choice_value(sym) && val == yes) {
struct symbol *cs = prop_get_symbol(sym_get_choice_prop(sym));
+ struct property *prop;
+ struct expr *e;
cs->user.val = sym;
cs->flags &= ~SYMBOL_NEW;
+ prop = sym_get_choice_prop(cs);
+ for (e = prop->expr; e; e = e->left.expr) {
+ if (e->right.sym->visible != no)
+ e->right.sym->flags &= ~SYMBOL_NEW;
+ }
}
sym->user.tri = val;
@@ -478,8 +539,8 @@ bool sym_string_within_range(struct symbol *sym, const char *str)
if (!prop)
return true;
val = strtol(str, NULL, 10);
- return val >= strtol(prop->expr->left.sym->name, NULL, 10) &&
- val <= strtol(prop->expr->right.sym->name, NULL, 10);
+ return val >= sym_get_range_val(prop->expr->left.sym, 10) &&
+ val <= sym_get_range_val(prop->expr->right.sym, 10);
case S_HEX:
if (!sym_string_valid(sym, str))
return false;
@@ -487,8 +548,8 @@ bool sym_string_within_range(struct symbol *sym, const char *str)
if (!prop)
return true;
val = strtol(str, NULL, 16);
- return val >= strtol(prop->expr->left.sym->name, NULL, 16) &&
- val <= strtol(prop->expr->right.sym->name, NULL, 16);
+ return val >= sym_get_range_val(prop->expr->left.sym, 16) &&
+ val <= sym_get_range_val(prop->expr->right.sym, 16);
case S_BOOLEAN:
case S_TRISTATE:
switch (str[0]) {
@@ -731,12 +792,12 @@ struct symbol *sym_check_deps(struct symbol *sym)
struct symbol *sym2;
struct property *prop;
- if (sym->flags & SYMBOL_CHECK_DONE)
- return NULL;
if (sym->flags & SYMBOL_CHECK) {
printf("Warning! Found recursive dependency: %s", sym->name);
return sym;
}
+ if (sym->flags & SYMBOL_CHECKED)
+ return NULL;
sym->flags |= (SYMBOL_CHECK | SYMBOL_CHECKED);
sym2 = sym_check_expr_deps(sym->rev_dep.expr);
@@ -756,8 +817,13 @@ struct symbol *sym_check_deps(struct symbol *sym)
goto out;
}
out:
- if (sym2)
+ if (sym2) {
printf(" %s", sym->name);
+ if (sym2 == sym) {
+ printf("\n");
+ sym2 = NULL;
+ }
+ }
sym->flags &= ~SYMBOL_CHECK;
return sym2;
}
diff --git a/scripts/kconfig/zconf.gperf b/scripts/kconfig/zconf.gperf
new file mode 100644
index 000000000000..b03220600b3a
--- /dev/null
+++ b/scripts/kconfig/zconf.gperf
@@ -0,0 +1,43 @@
+%language=ANSI-C
+%define hash-function-name kconf_id_hash
+%define lookup-function-name kconf_id_lookup
+%define string-pool-name kconf_id_strings
+%compare-strncmp
+%enum
+%pic
+%struct-type
+
+struct kconf_id;
+
+%%
+mainmenu, T_MAINMENU, TF_COMMAND
+menu, T_MENU, TF_COMMAND
+endmenu, T_ENDMENU, TF_COMMAND
+source, T_SOURCE, TF_COMMAND
+choice, T_CHOICE, TF_COMMAND
+endchoice, T_ENDCHOICE, TF_COMMAND
+comment, T_COMMENT, TF_COMMAND
+config, T_CONFIG, TF_COMMAND
+menuconfig, T_MENUCONFIG, TF_COMMAND
+help, T_HELP, TF_COMMAND
+if, T_IF, TF_COMMAND|TF_PARAM
+endif, T_ENDIF, TF_COMMAND
+depends, T_DEPENDS, TF_COMMAND
+requires, T_REQUIRES, TF_COMMAND
+optional, T_OPTIONAL, TF_COMMAND
+default, T_DEFAULT, TF_COMMAND, S_UNKNOWN
+prompt, T_PROMPT, TF_COMMAND
+tristate, T_TYPE, TF_COMMAND, S_TRISTATE
+def_tristate, T_DEFAULT, TF_COMMAND, S_TRISTATE
+bool, T_TYPE, TF_COMMAND, S_BOOLEAN
+boolean, T_TYPE, TF_COMMAND, S_BOOLEAN
+def_bool, T_DEFAULT, TF_COMMAND, S_BOOLEAN
+def_boolean, T_DEFAULT, TF_COMMAND, S_BOOLEAN
+int, T_TYPE, TF_COMMAND, S_INT
+hex, T_TYPE, TF_COMMAND, S_HEX
+string, T_TYPE, TF_COMMAND, S_STRING
+select, T_SELECT, TF_COMMAND
+enable, T_SELECT, TF_COMMAND
+range, T_RANGE, TF_COMMAND
+on, T_ON, TF_PARAM
+%%
diff --git a/scripts/kconfig/zconf.hash.c_shipped b/scripts/kconfig/zconf.hash.c_shipped
new file mode 100644
index 000000000000..345f0fc07ca3
--- /dev/null
+++ b/scripts/kconfig/zconf.hash.c_shipped
@@ -0,0 +1,231 @@
+/* ANSI-C code produced by gperf version 3.0.1 */
+/* Command-line: gperf */
+/* Computed positions: -k'1,3' */
+
+#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \
+ && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \
+ && (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \
+ && ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \
+ && ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \
+ && ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \
+ && ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \
+ && ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \
+ && ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \
+ && ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \
+ && ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \
+ && ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \
+ && ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \
+ && ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \
+ && ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \
+ && ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \
+ && ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \
+ && ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \
+ && ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \
+ && ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \
+ && ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \
+ && ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \
+ && ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126))
+/* The character set is not based on ISO-646. */
+#error "gperf generated tables don't work with this execution character set. Please report a bug to <bug-gnu-gperf@gnu.org>."
+#endif
+
+struct kconf_id;
+/* maximum key range = 45, duplicates = 0 */
+
+#ifdef __GNUC__
+__inline
+#else
+#ifdef __cplusplus
+inline
+#endif
+#endif
+static unsigned int
+kconf_id_hash (register const char *str, register unsigned int len)
+{
+ static unsigned char asso_values[] =
+ {
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 25, 10, 15,
+ 0, 0, 5, 47, 0, 0, 47, 47, 0, 10,
+ 0, 20, 20, 20, 5, 0, 0, 20, 47, 47,
+ 20, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47
+ };
+ register int hval = len;
+
+ switch (hval)
+ {
+ default:
+ hval += asso_values[(unsigned char)str[2]];
+ /*FALLTHROUGH*/
+ case 2:
+ case 1:
+ hval += asso_values[(unsigned char)str[0]];
+ break;
+ }
+ return hval;
+}
+
+struct kconf_id_strings_t
+ {
+ char kconf_id_strings_str2[sizeof("if")];
+ char kconf_id_strings_str3[sizeof("int")];
+ char kconf_id_strings_str4[sizeof("help")];
+ char kconf_id_strings_str5[sizeof("endif")];
+ char kconf_id_strings_str6[sizeof("select")];
+ char kconf_id_strings_str7[sizeof("endmenu")];
+ char kconf_id_strings_str8[sizeof("tristate")];
+ char kconf_id_strings_str9[sizeof("endchoice")];
+ char kconf_id_strings_str10[sizeof("range")];
+ char kconf_id_strings_str11[sizeof("string")];
+ char kconf_id_strings_str12[sizeof("default")];
+ char kconf_id_strings_str13[sizeof("def_bool")];
+ char kconf_id_strings_str14[sizeof("menu")];
+ char kconf_id_strings_str16[sizeof("def_boolean")];
+ char kconf_id_strings_str17[sizeof("def_tristate")];
+ char kconf_id_strings_str18[sizeof("mainmenu")];
+ char kconf_id_strings_str20[sizeof("menuconfig")];
+ char kconf_id_strings_str21[sizeof("config")];
+ char kconf_id_strings_str22[sizeof("on")];
+ char kconf_id_strings_str23[sizeof("hex")];
+ char kconf_id_strings_str26[sizeof("source")];
+ char kconf_id_strings_str27[sizeof("depends")];
+ char kconf_id_strings_str28[sizeof("optional")];
+ char kconf_id_strings_str31[sizeof("enable")];
+ char kconf_id_strings_str32[sizeof("comment")];
+ char kconf_id_strings_str33[sizeof("requires")];
+ char kconf_id_strings_str34[sizeof("bool")];
+ char kconf_id_strings_str37[sizeof("boolean")];
+ char kconf_id_strings_str41[sizeof("choice")];
+ char kconf_id_strings_str46[sizeof("prompt")];
+ };
+static struct kconf_id_strings_t kconf_id_strings_contents =
+ {
+ "if",
+ "int",
+ "help",
+ "endif",
+ "select",
+ "endmenu",
+ "tristate",
+ "endchoice",
+ "range",
+ "string",
+ "default",
+ "def_bool",
+ "menu",
+ "def_boolean",
+ "def_tristate",
+ "mainmenu",
+ "menuconfig",
+ "config",
+ "on",
+ "hex",
+ "source",
+ "depends",
+ "optional",
+ "enable",
+ "comment",
+ "requires",
+ "bool",
+ "boolean",
+ "choice",
+ "prompt"
+ };
+#define kconf_id_strings ((const char *) &kconf_id_strings_contents)
+#ifdef __GNUC__
+__inline
+#endif
+struct kconf_id *
+kconf_id_lookup (register const char *str, register unsigned int len)
+{
+ enum
+ {
+ TOTAL_KEYWORDS = 30,
+ MIN_WORD_LENGTH = 2,
+ MAX_WORD_LENGTH = 12,
+ MIN_HASH_VALUE = 2,
+ MAX_HASH_VALUE = 46
+ };
+
+ static struct kconf_id wordlist[] =
+ {
+ {-1}, {-1},
+ {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str2, T_IF, TF_COMMAND|TF_PARAM},
+ {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str3, T_TYPE, TF_COMMAND, S_INT},
+ {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str4, T_HELP, TF_COMMAND},
+ {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str5, T_ENDIF, TF_COMMAND},
+ {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str6, T_SELECT, TF_COMMAND},
+ {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str7, T_ENDMENU, TF_COMMAND},
+ {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str8, T_TYPE, TF_COMMAND, S_TRISTATE},
+ {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str9, T_ENDCHOICE, TF_COMMAND},
+ {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str10, T_RANGE, TF_COMMAND},
+ {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str11, T_TYPE, TF_COMMAND, S_STRING},
+ {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str12, T_DEFAULT, TF_COMMAND, S_UNKNOWN},
+ {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str13, T_DEFAULT, TF_COMMAND, S_BOOLEAN},
+ {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str14, T_MENU, TF_COMMAND},
+ {-1},
+ {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str16, T_DEFAULT, TF_COMMAND, S_BOOLEAN},
+ {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str17, T_DEFAULT, TF_COMMAND, S_TRISTATE},
+ {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str18, T_MAINMENU, TF_COMMAND},
+ {-1},
+ {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str20, T_MENUCONFIG, TF_COMMAND},
+ {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str21, T_CONFIG, TF_COMMAND},
+ {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str22, T_ON, TF_PARAM},
+ {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str23, T_TYPE, TF_COMMAND, S_HEX},
+ {-1}, {-1},
+ {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str26, T_SOURCE, TF_COMMAND},
+ {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str27, T_DEPENDS, TF_COMMAND},
+ {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str28, T_OPTIONAL, TF_COMMAND},
+ {-1}, {-1},
+ {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str31, T_SELECT, TF_COMMAND},
+ {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str32, T_COMMENT, TF_COMMAND},
+ {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str33, T_REQUIRES, TF_COMMAND},
+ {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str34, T_TYPE, TF_COMMAND, S_BOOLEAN},
+ {-1}, {-1},
+ {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str37, T_TYPE, TF_COMMAND, S_BOOLEAN},
+ {-1}, {-1}, {-1},
+ {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str41, T_CHOICE, TF_COMMAND},
+ {-1}, {-1}, {-1}, {-1},
+ {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str46, T_PROMPT, TF_COMMAND}
+ };
+
+ if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
+ {
+ register int key = kconf_id_hash (str, len);
+
+ if (key <= MAX_HASH_VALUE && key >= 0)
+ {
+ register int o = wordlist[key].name;
+ if (o >= 0)
+ {
+ register const char *s = o + kconf_id_strings;
+
+ if (*str == *s && !strncmp (str + 1, s + 1, len - 1) && s[len] == '\0')
+ return &wordlist[key];
+ }
+ }
+ }
+ return 0;
+}
+
diff --git a/scripts/kconfig/zconf.l b/scripts/kconfig/zconf.l
index 55517b2877cd..cfa46077c6b4 100644
--- a/scripts/kconfig/zconf.l
+++ b/scripts/kconfig/zconf.l
@@ -18,8 +18,12 @@
#define START_STRSIZE 16
-char *text;
-static char *text_ptr;
+static struct {
+ struct file *file;
+ int lineno;
+} current_pos;
+
+static char *text;
static int text_size, text_asize;
struct buffer {
@@ -32,29 +36,28 @@ struct buffer *current_buf;
static int last_ts, first_ts;
static void zconf_endhelp(void);
-static struct buffer *zconf_endfile(void);
+static void zconf_endfile(void);
void new_string(void)
{
text = malloc(START_STRSIZE);
text_asize = START_STRSIZE;
- text_ptr = text;
text_size = 0;
- *text_ptr = 0;
+ *text = 0;
}
void append_string(const char *str, int size)
{
int new_size = text_size + size + 1;
if (new_size > text_asize) {
+ new_size += START_STRSIZE - 1;
+ new_size &= -START_STRSIZE;
text = realloc(text, new_size);
text_asize = new_size;
- text_ptr = text + text_size;
}
- memcpy(text_ptr, str, size);
- text_ptr += size;
+ memcpy(text + text_size, str, size);
text_size += size;
- *text_ptr = 0;
+ text[text_size] = 0;
}
void alloc_string(const char *str, int size)
@@ -72,10 +75,13 @@ n [A-Za-z0-9_]
int str = 0;
int ts, i;
-[ \t]*#.*\n current_file->lineno++;
+[ \t]*#.*\n |
+[ \t]*\n {
+ current_file->lineno++;
+ return T_EOL;
+}
[ \t]*#.*
-[ \t]*\n current_file->lineno++; return T_EOL;
[ \t]+ {
BEGIN(COMMAND);
@@ -88,42 +94,25 @@ n [A-Za-z0-9_]
<COMMAND>{
- "mainmenu" BEGIN(PARAM); return T_MAINMENU;
- "menu" BEGIN(PARAM); return T_MENU;
- "endmenu" BEGIN(PARAM); return T_ENDMENU;
- "source" BEGIN(PARAM); return T_SOURCE;
- "choice" BEGIN(PARAM); return T_CHOICE;
- "endchoice" BEGIN(PARAM); return T_ENDCHOICE;
- "comment" BEGIN(PARAM); return T_COMMENT;
- "config" BEGIN(PARAM); return T_CONFIG;
- "menuconfig" BEGIN(PARAM); return T_MENUCONFIG;
- "help" BEGIN(PARAM); return T_HELP;
- "if" BEGIN(PARAM); return T_IF;
- "endif" BEGIN(PARAM); return T_ENDIF;
- "depends" BEGIN(PARAM); return T_DEPENDS;
- "requires" BEGIN(PARAM); return T_REQUIRES;
- "optional" BEGIN(PARAM); return T_OPTIONAL;
- "default" BEGIN(PARAM); return T_DEFAULT;
- "prompt" BEGIN(PARAM); return T_PROMPT;
- "tristate" BEGIN(PARAM); return T_TRISTATE;
- "def_tristate" BEGIN(PARAM); return T_DEF_TRISTATE;
- "bool" BEGIN(PARAM); return T_BOOLEAN;
- "boolean" BEGIN(PARAM); return T_BOOLEAN;
- "def_bool" BEGIN(PARAM); return T_DEF_BOOLEAN;
- "def_boolean" BEGIN(PARAM); return T_DEF_BOOLEAN;
- "int" BEGIN(PARAM); return T_INT;
- "hex" BEGIN(PARAM); return T_HEX;
- "string" BEGIN(PARAM); return T_STRING;
- "select" BEGIN(PARAM); return T_SELECT;
- "enable" BEGIN(PARAM); return T_SELECT;
- "range" BEGIN(PARAM); return T_RANGE;
{n}+ {
+ struct kconf_id *id = kconf_id_lookup(yytext, yyleng);
+ BEGIN(PARAM);
+ current_pos.file = current_file;
+ current_pos.lineno = current_file->lineno;
+ if (id && id->flags & TF_COMMAND) {
+ zconflval.id = id;
+ return id->token;
+ }
alloc_string(yytext, yyleng);
zconflval.string = text;
return T_WORD;
}
.
- \n current_file->lineno++; BEGIN(INITIAL);
+ \n {
+ BEGIN(INITIAL);
+ current_file->lineno++;
+ return T_EOL;
+ }
}
<PARAM>{
@@ -134,8 +123,6 @@ n [A-Za-z0-9_]
"!" return T_NOT;
"=" return T_EQUAL;
"!=" return T_UNEQUAL;
- "if" return T_IF;
- "on" return T_ON;
\"|\' {
str = yytext[0];
new_string();
@@ -144,6 +131,11 @@ n [A-Za-z0-9_]
\n BEGIN(INITIAL); current_file->lineno++; return T_EOL;
--- /* ignore */
({n}|[-/.])+ {
+ struct kconf_id *id = kconf_id_lookup(yytext, yyleng);
+ if (id && id->flags & TF_PARAM) {
+ zconflval.id = id;
+ return id->token;
+ }
alloc_string(yytext, yyleng);
zconflval.string = text;
return T_WORD;
@@ -236,9 +228,9 @@ n [A-Za-z0-9_]
}
<<EOF>> {
- if (current_buf) {
+ if (current_file) {
zconf_endfile();
- return T_EOF;
+ return T_EOL;
}
fclose(yyin);
yyterminate();
@@ -329,7 +321,7 @@ void zconf_nextfile(const char *name)
current_file = file;
}
-static struct buffer *zconf_endfile(void)
+static void zconf_endfile(void)
{
struct buffer *parent;
@@ -345,22 +337,14 @@ static struct buffer *zconf_endfile(void)
}
free(current_buf);
current_buf = parent;
-
- return parent;
}
int zconf_lineno(void)
{
- if (current_buf)
- return current_file->lineno - 1;
- else
- return 0;
+ return current_pos.lineno;
}
char *zconf_curname(void)
{
- if (current_buf)
- return current_file->name;
- else
- return "<none>";
+ return current_pos.file ? current_pos.file->name : "<none>";
}
diff --git a/scripts/kconfig/zconf.tab.c_shipped b/scripts/kconfig/zconf.tab.c_shipped
index ff4fcc09720e..ea7755da82f5 100644
--- a/scripts/kconfig/zconf.tab.c_shipped
+++ b/scripts/kconfig/zconf.tab.c_shipped
@@ -1,7 +1,7 @@
-/* A Bison parser, made by GNU Bison 1.875a. */
+/* A Bison parser, made by GNU Bison 2.0. */
/* Skeleton parser for Yacc-like parsing with Bison,
- Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+ Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -45,8 +45,7 @@
/* Using locations. */
#define YYLSP_NEEDED 0
-/* If NAME_PREFIX is specified substitute the variables and functions
- names. */
+/* Substitute the variable and function names. */
#define yyparse zconfparse
#define yylex zconflex
#define yyerror zconferror
@@ -79,28 +78,21 @@
T_REQUIRES = 272,
T_OPTIONAL = 273,
T_PROMPT = 274,
- T_DEFAULT = 275,
- T_TRISTATE = 276,
- T_DEF_TRISTATE = 277,
- T_BOOLEAN = 278,
- T_DEF_BOOLEAN = 279,
- T_STRING = 280,
- T_INT = 281,
- T_HEX = 282,
- T_WORD = 283,
- T_WORD_QUOTE = 284,
- T_UNEQUAL = 285,
- T_EOF = 286,
- T_EOL = 287,
- T_CLOSE_PAREN = 288,
- T_OPEN_PAREN = 289,
- T_ON = 290,
- T_SELECT = 291,
- T_RANGE = 292,
- T_OR = 293,
- T_AND = 294,
- T_EQUAL = 295,
- T_NOT = 296
+ T_TYPE = 275,
+ T_DEFAULT = 276,
+ T_SELECT = 277,
+ T_RANGE = 278,
+ T_ON = 279,
+ T_WORD = 280,
+ T_WORD_QUOTE = 281,
+ T_UNEQUAL = 282,
+ T_CLOSE_PAREN = 283,
+ T_OPEN_PAREN = 284,
+ T_EOL = 285,
+ T_OR = 286,
+ T_AND = 287,
+ T_EQUAL = 288,
+ T_NOT = 289
};
#endif
#define T_MAINMENU 258
@@ -120,28 +112,21 @@
#define T_REQUIRES 272
#define T_OPTIONAL 273
#define T_PROMPT 274
-#define T_DEFAULT 275
-#define T_TRISTATE 276
-#define T_DEF_TRISTATE 277
-#define T_BOOLEAN 278
-#define T_DEF_BOOLEAN 279
-#define T_STRING 280
-#define T_INT 281
-#define T_HEX 282
-#define T_WORD 283
-#define T_WORD_QUOTE 284
-#define T_UNEQUAL 285
-#define T_EOF 286
-#define T_EOL 287
-#define T_CLOSE_PAREN 288
-#define T_OPEN_PAREN 289
-#define T_ON 290
-#define T_SELECT 291
-#define T_RANGE 292
-#define T_OR 293
-#define T_AND 294
-#define T_EQUAL 295
-#define T_NOT 296
+#define T_TYPE 275
+#define T_DEFAULT 276
+#define T_SELECT 277
+#define T_RANGE 278
+#define T_ON 279
+#define T_WORD 280
+#define T_WORD_QUOTE 281
+#define T_UNEQUAL 282
+#define T_CLOSE_PAREN 283
+#define T_OPEN_PAREN 284
+#define T_EOL 285
+#define T_OR 286
+#define T_AND 287
+#define T_EQUAL 288
+#define T_NOT 289
@@ -161,6 +146,11 @@
#include <string.h>
#include <stdbool.h>
+#define LKC_DIRECT_LINK
+#include "lkc.h"
+
+#include "zconf.hash.c"
+
#define printd(mask, fmt...) if (cdebug & (mask)) printf(fmt)
#define PRINTD 0x0001
@@ -170,14 +160,18 @@ int cdebug = PRINTD;
extern int zconflex(void);
static void zconfprint(const char *err, ...);
+static void zconf_error(const char *err, ...);
static void zconferror(const char *err);
-static bool zconf_endtoken(int token, int starttoken, int endtoken);
+static bool zconf_endtoken(struct kconf_id *id, int starttoken, int endtoken);
struct symbol *symbol_hash[257];
static struct menu *current_menu, *current_entry;
+#define YYDEBUG 0
+#if YYDEBUG
#define YYERROR_VERBOSE
+#endif
/* Enabling traces. */
@@ -196,13 +190,14 @@ static struct menu *current_menu, *current_entry;
#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
typedef union YYSTYPE {
- int token;
char *string;
+ struct file *file;
struct symbol *symbol;
struct expr *expr;
struct menu *menu;
+ struct kconf_id *id;
} YYSTYPE;
-/* Line 191 of yacc.c. */
+/* Line 190 of yacc.c. */
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
# define YYSTYPE_IS_DECLARED 1
@@ -214,27 +209,26 @@ typedef union YYSTYPE {
/* Copy the second part of user declarations. */
-#define LKC_DIRECT_LINK
-#include "lkc.h"
-
-
-/* Line 214 of yacc.c. */
+/* Line 213 of yacc.c. */
#if ! defined (yyoverflow) || YYERROR_VERBOSE
+# ifndef YYFREE
+# define YYFREE free
+# endif
+# ifndef YYMALLOC
+# define YYMALLOC malloc
+# endif
+
/* The parser invokes alloca or malloc; define the necessary symbols. */
-# if YYSTACK_USE_ALLOCA
-# define YYSTACK_ALLOC alloca
-# else
-# ifndef YYSTACK_USE_ALLOCA
-# if defined (alloca) || defined (_ALLOCA_H)
-# define YYSTACK_ALLOC alloca
+# ifdef YYSTACK_USE_ALLOCA
+# if YYSTACK_USE_ALLOCA
+# ifdef __GNUC__
+# define YYSTACK_ALLOC __builtin_alloca
# else
-# ifdef __GNUC__
-# define YYSTACK_ALLOC __builtin_alloca
-# endif
+# define YYSTACK_ALLOC alloca
# endif
# endif
# endif
@@ -247,20 +241,20 @@ typedef union YYSTYPE {
# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
# define YYSIZE_T size_t
# endif
-# define YYSTACK_ALLOC malloc
-# define YYSTACK_FREE free
+# define YYSTACK_ALLOC YYMALLOC
+# define YYSTACK_FREE YYFREE
# endif
#endif /* ! defined (yyoverflow) || YYERROR_VERBOSE */
#if (! defined (yyoverflow) \
&& (! defined (__cplusplus) \
- || (YYSTYPE_IS_TRIVIAL)))
+ || (defined (YYSTYPE_IS_TRIVIAL) && YYSTYPE_IS_TRIVIAL)))
/* A type that is properly aligned for any stack member. */
union yyalloc
{
- short yyss;
+ short int yyss;
YYSTYPE yyvs;
};
@@ -270,13 +264,13 @@ union yyalloc
/* The size of an array large to enough to hold all stacks, each with
N elements. */
# define YYSTACK_BYTES(N) \
- ((N) * (sizeof (short) + sizeof (YYSTYPE)) \
+ ((N) * (sizeof (short int) + sizeof (YYSTYPE)) \
+ YYSTACK_GAP_MAXIMUM)
/* Copy COUNT objects from FROM to TO. The source and destination do
not overlap. */
# ifndef YYCOPY
-# if 1 < __GNUC__
+# if defined (__GNUC__) && 1 < __GNUC__
# define YYCOPY(To, From, Count) \
__builtin_memcpy (To, From, (Count) * sizeof (*(From)))
# else
@@ -312,26 +306,26 @@ union yyalloc
#if defined (__STDC__) || defined (__cplusplus)
typedef signed char yysigned_char;
#else
- typedef short yysigned_char;
+ typedef short int yysigned_char;
#endif
/* YYFINAL -- State number of the termination state. */
-#define YYFINAL 2
+#define YYFINAL 3
/* YYLAST -- Last index in YYTABLE. */
-#define YYLAST 201
+#define YYLAST 264
/* YYNTOKENS -- Number of terminals. */
-#define YYNTOKENS 42
+#define YYNTOKENS 35
/* YYNNTS -- Number of nonterminals. */
-#define YYNNTS 41
+#define YYNNTS 42
/* YYNRULES -- Number of rules. */
#define YYNRULES 104
/* YYNRULES -- Number of states. */
-#define YYNSTATES 182
+#define YYNSTATES 175
/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
#define YYUNDEFTOK 2
-#define YYMAXUTOK 296
+#define YYMAXUTOK 289
#define YYTRANSLATE(YYX) \
((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
@@ -367,79 +361,78 @@ static const unsigned char yytranslate[] =
2, 2, 2, 2, 2, 2, 1, 2, 3, 4,
5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
- 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
- 35, 36, 37, 38, 39, 40, 41
+ 25, 26, 27, 28, 29, 30, 31, 32, 33, 34
};
#if YYDEBUG
/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
YYRHS. */
-static const unsigned short yyprhs[] =
+static const unsigned short int yyprhs[] =
{
- 0, 0, 3, 4, 7, 9, 11, 13, 17, 19,
- 21, 23, 26, 28, 30, 32, 34, 36, 38, 42,
- 45, 49, 52, 53, 56, 59, 62, 65, 69, 74,
- 78, 83, 87, 91, 95, 100, 105, 110, 116, 119,
- 122, 124, 128, 131, 132, 135, 138, 141, 144, 149,
- 153, 157, 160, 165, 166, 169, 173, 175, 179, 182,
- 183, 186, 189, 192, 196, 199, 201, 205, 208, 209,
- 212, 215, 218, 222, 226, 228, 232, 235, 238, 241,
- 242, 245, 248, 253, 257, 261, 262, 265, 267, 269,
- 272, 275, 278, 280, 282, 283, 286, 288, 292, 296,
- 300, 303, 307, 311, 313
+ 0, 0, 3, 5, 6, 9, 12, 15, 20, 23,
+ 28, 33, 37, 39, 41, 43, 45, 47, 49, 51,
+ 53, 55, 57, 59, 61, 63, 67, 70, 74, 77,
+ 81, 84, 85, 88, 91, 94, 97, 100, 104, 109,
+ 114, 119, 125, 128, 131, 133, 137, 138, 141, 144,
+ 147, 150, 153, 158, 162, 165, 170, 171, 174, 178,
+ 180, 184, 185, 188, 191, 194, 198, 201, 203, 207,
+ 208, 211, 214, 217, 221, 225, 228, 231, 234, 235,
+ 238, 241, 244, 249, 253, 257, 258, 261, 263, 265,
+ 268, 271, 274, 276, 279, 280, 283, 285, 289, 293,
+ 297, 300, 304, 308, 310
};
/* YYRHS -- A `-1'-separated list of the rules' RHS. */
static const yysigned_char yyrhs[] =
{
- 43, 0, -1, -1, 43, 44, -1, 45, -1, 55,
- -1, 66, -1, 3, 77, 79, -1, 5, -1, 15,
- -1, 8, -1, 1, 79, -1, 61, -1, 71, -1,
- 47, -1, 49, -1, 69, -1, 79, -1, 10, 28,
- 32, -1, 46, 50, -1, 11, 28, 32, -1, 48,
- 50, -1, -1, 50, 51, -1, 50, 75, -1, 50,
- 73, -1, 50, 32, -1, 21, 76, 32, -1, 22,
- 81, 80, 32, -1, 23, 76, 32, -1, 24, 81,
- 80, 32, -1, 26, 76, 32, -1, 27, 76, 32,
- -1, 25, 76, 32, -1, 19, 77, 80, 32, -1,
- 20, 81, 80, 32, -1, 36, 28, 80, 32, -1,
- 37, 82, 82, 80, 32, -1, 7, 32, -1, 52,
- 56, -1, 78, -1, 53, 58, 54, -1, 53, 58,
- -1, -1, 56, 57, -1, 56, 75, -1, 56, 73,
- -1, 56, 32, -1, 19, 77, 80, 32, -1, 21,
- 76, 32, -1, 23, 76, 32, -1, 18, 32, -1,
- 20, 28, 80, 32, -1, -1, 58, 45, -1, 14,
- 81, 32, -1, 78, -1, 59, 62, 60, -1, 59,
- 62, -1, -1, 62, 45, -1, 62, 66, -1, 62,
- 55, -1, 4, 77, 32, -1, 63, 74, -1, 78,
- -1, 64, 67, 65, -1, 64, 67, -1, -1, 67,
- 45, -1, 67, 66, -1, 67, 55, -1, 67, 1,
- 32, -1, 6, 77, 32, -1, 68, -1, 9, 77,
- 32, -1, 70, 74, -1, 12, 32, -1, 72, 13,
- -1, -1, 74, 75, -1, 74, 32, -1, 16, 35,
- 81, 32, -1, 16, 81, 32, -1, 17, 81, 32,
- -1, -1, 77, 80, -1, 28, -1, 29, -1, 5,
- 79, -1, 8, 79, -1, 15, 79, -1, 32, -1,
- 31, -1, -1, 14, 81, -1, 82, -1, 82, 40,
- 82, -1, 82, 30, 82, -1, 34, 81, 33, -1,
- 41, 81, -1, 81, 38, 81, -1, 81, 39, 81,
- -1, 28, -1, 29, -1
+ 36, 0, -1, 37, -1, -1, 37, 39, -1, 37,
+ 50, -1, 37, 61, -1, 37, 3, 71, 73, -1,
+ 37, 72, -1, 37, 25, 1, 30, -1, 37, 38,
+ 1, 30, -1, 37, 1, 30, -1, 16, -1, 19,
+ -1, 20, -1, 22, -1, 18, -1, 23, -1, 21,
+ -1, 30, -1, 56, -1, 65, -1, 42, -1, 44,
+ -1, 63, -1, 25, 1, 30, -1, 1, 30, -1,
+ 10, 25, 30, -1, 41, 45, -1, 11, 25, 30,
+ -1, 43, 45, -1, -1, 45, 46, -1, 45, 69,
+ -1, 45, 67, -1, 45, 40, -1, 45, 30, -1,
+ 20, 70, 30, -1, 19, 71, 74, 30, -1, 21,
+ 75, 74, 30, -1, 22, 25, 74, 30, -1, 23,
+ 76, 76, 74, 30, -1, 7, 30, -1, 47, 51,
+ -1, 72, -1, 48, 53, 49, -1, -1, 51, 52,
+ -1, 51, 69, -1, 51, 67, -1, 51, 30, -1,
+ 51, 40, -1, 19, 71, 74, 30, -1, 20, 70,
+ 30, -1, 18, 30, -1, 21, 25, 74, 30, -1,
+ -1, 53, 39, -1, 14, 75, 73, -1, 72, -1,
+ 54, 57, 55, -1, -1, 57, 39, -1, 57, 61,
+ -1, 57, 50, -1, 4, 71, 30, -1, 58, 68,
+ -1, 72, -1, 59, 62, 60, -1, -1, 62, 39,
+ -1, 62, 61, -1, 62, 50, -1, 6, 71, 30,
+ -1, 9, 71, 30, -1, 64, 68, -1, 12, 30,
+ -1, 66, 13, -1, -1, 68, 69, -1, 68, 30,
+ -1, 68, 40, -1, 16, 24, 75, 30, -1, 16,
+ 75, 30, -1, 17, 75, 30, -1, -1, 71, 74,
+ -1, 25, -1, 26, -1, 5, 30, -1, 8, 30,
+ -1, 15, 30, -1, 30, -1, 73, 30, -1, -1,
+ 14, 75, -1, 76, -1, 76, 33, 76, -1, 76,
+ 27, 76, -1, 29, 75, 28, -1, 34, 75, -1,
+ 75, 31, 75, -1, 75, 32, 75, -1, 25, -1,
+ 26, -1
};
/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
-static const unsigned short yyrline[] =
+static const unsigned short int yyrline[] =
{
- 0, 94, 94, 95, 98, 99, 100, 101, 102, 103,
- 104, 105, 109, 110, 111, 112, 113, 114, 120, 128,
- 134, 142, 152, 154, 155, 156, 157, 160, 166, 173,
- 179, 186, 192, 198, 204, 210, 216, 222, 230, 239,
- 245, 254, 255, 261, 263, 264, 265, 266, 269, 275,
- 281, 287, 293, 299, 301, 306, 315, 324, 325, 331,
- 333, 334, 335, 340, 347, 353, 362, 363, 369, 371,
- 372, 373, 374, 377, 383, 390, 397, 404, 410, 417,
- 418, 419, 422, 427, 432, 440, 442, 447, 448, 451,
- 452, 453, 457, 457, 459, 460, 463, 464, 465, 466,
- 467, 468, 469, 472, 473
+ 0, 103, 103, 105, 107, 108, 109, 110, 111, 112,
+ 113, 117, 121, 121, 121, 121, 121, 121, 121, 125,
+ 126, 127, 128, 129, 130, 134, 135, 141, 149, 155,
+ 163, 173, 175, 176, 177, 178, 179, 182, 190, 196,
+ 206, 212, 220, 229, 234, 242, 245, 247, 248, 249,
+ 250, 251, 254, 260, 271, 277, 287, 289, 294, 302,
+ 310, 313, 315, 316, 317, 322, 329, 334, 342, 345,
+ 347, 348, 349, 352, 360, 367, 374, 380, 387, 389,
+ 390, 391, 394, 399, 404, 412, 414, 419, 420, 423,
+ 424, 425, 429, 430, 433, 434, 437, 438, 439, 440,
+ 441, 442, 443, 446, 447
};
#endif
@@ -448,67 +441,65 @@ static const unsigned short yyrline[] =
First, the terminals, then, starting at YYNTOKENS, nonterminals. */
static const char *const yytname[] =
{
- "$end", "error", "$undefined", "T_MAINMENU", "T_MENU", "T_ENDMENU",
- "T_SOURCE", "T_CHOICE", "T_ENDCHOICE", "T_COMMENT", "T_CONFIG",
- "T_MENUCONFIG", "T_HELP", "T_HELPTEXT", "T_IF", "T_ENDIF", "T_DEPENDS",
- "T_REQUIRES", "T_OPTIONAL", "T_PROMPT", "T_DEFAULT", "T_TRISTATE",
- "T_DEF_TRISTATE", "T_BOOLEAN", "T_DEF_BOOLEAN", "T_STRING", "T_INT",
- "T_HEX", "T_WORD", "T_WORD_QUOTE", "T_UNEQUAL", "T_EOF", "T_EOL",
- "T_CLOSE_PAREN", "T_OPEN_PAREN", "T_ON", "T_SELECT", "T_RANGE", "T_OR",
- "T_AND", "T_EQUAL", "T_NOT", "$accept", "input", "block",
- "common_block", "config_entry_start", "config_stmt",
- "menuconfig_entry_start", "menuconfig_stmt", "config_option_list",
- "config_option", "choice", "choice_entry", "choice_end", "choice_stmt",
- "choice_option_list", "choice_option", "choice_block", "if", "if_end",
- "if_stmt", "if_block", "menu", "menu_entry", "menu_end", "menu_stmt",
- "menu_block", "source", "source_stmt", "comment", "comment_stmt",
- "help_start", "help", "depends_list", "depends", "prompt_stmt_opt",
- "prompt", "end", "nl_or_eof", "if_expr", "expr", "symbol", 0
+ "$end", "error", "$undefined", "T_MAINMENU", "T_MENU", "T_ENDMENU",
+ "T_SOURCE", "T_CHOICE", "T_ENDCHOICE", "T_COMMENT", "T_CONFIG",
+ "T_MENUCONFIG", "T_HELP", "T_HELPTEXT", "T_IF", "T_ENDIF", "T_DEPENDS",
+ "T_REQUIRES", "T_OPTIONAL", "T_PROMPT", "T_TYPE", "T_DEFAULT",
+ "T_SELECT", "T_RANGE", "T_ON", "T_WORD", "T_WORD_QUOTE", "T_UNEQUAL",
+ "T_CLOSE_PAREN", "T_OPEN_PAREN", "T_EOL", "T_OR", "T_AND", "T_EQUAL",
+ "T_NOT", "$accept", "input", "stmt_list", "option_name", "common_stmt",
+ "option_error", "config_entry_start", "config_stmt",
+ "menuconfig_entry_start", "menuconfig_stmt", "config_option_list",
+ "config_option", "choice", "choice_entry", "choice_end", "choice_stmt",
+ "choice_option_list", "choice_option", "choice_block", "if_entry",
+ "if_end", "if_stmt", "if_block", "menu", "menu_entry", "menu_end",
+ "menu_stmt", "menu_block", "source_stmt", "comment", "comment_stmt",
+ "help_start", "help", "depends_list", "depends", "prompt_stmt_opt",
+ "prompt", "end", "nl", "if_expr", "expr", "symbol", 0
};
#endif
# ifdef YYPRINT
/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
token YYLEX-NUM. */
-static const unsigned short yytoknum[] =
+static const unsigned short int yytoknum[] =
{
0, 256, 257, 258, 259, 260, 261, 262, 263, 264,
265, 266, 267, 268, 269, 270, 271, 272, 273, 274,
275, 276, 277, 278, 279, 280, 281, 282, 283, 284,
- 285, 286, 287, 288, 289, 290, 291, 292, 293, 294,
- 295, 296
+ 285, 286, 287, 288, 289
};
# endif
/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
static const unsigned char yyr1[] =
{
- 0, 42, 43, 43, 44, 44, 44, 44, 44, 44,
- 44, 44, 45, 45, 45, 45, 45, 45, 46, 47,
- 48, 49, 50, 50, 50, 50, 50, 51, 51, 51,
- 51, 51, 51, 51, 51, 51, 51, 51, 52, 53,
- 54, 55, 55, 56, 56, 56, 56, 56, 57, 57,
- 57, 57, 57, 58, 58, 59, 60, 61, 61, 62,
- 62, 62, 62, 63, 64, 65, 66, 66, 67, 67,
- 67, 67, 67, 68, 69, 70, 71, 72, 73, 74,
- 74, 74, 75, 75, 75, 76, 76, 77, 77, 78,
- 78, 78, 79, 79, 80, 80, 81, 81, 81, 81,
- 81, 81, 81, 82, 82
+ 0, 35, 36, 37, 37, 37, 37, 37, 37, 37,
+ 37, 37, 38, 38, 38, 38, 38, 38, 38, 39,
+ 39, 39, 39, 39, 39, 40, 40, 41, 42, 43,
+ 44, 45, 45, 45, 45, 45, 45, 46, 46, 46,
+ 46, 46, 47, 48, 49, 50, 51, 51, 51, 51,
+ 51, 51, 52, 52, 52, 52, 53, 53, 54, 55,
+ 56, 57, 57, 57, 57, 58, 59, 60, 61, 62,
+ 62, 62, 62, 63, 64, 65, 66, 67, 68, 68,
+ 68, 68, 69, 69, 69, 70, 70, 71, 71, 72,
+ 72, 72, 73, 73, 74, 74, 75, 75, 75, 75,
+ 75, 75, 75, 76, 76
};
/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
static const unsigned char yyr2[] =
{
- 0, 2, 0, 2, 1, 1, 1, 3, 1, 1,
- 1, 2, 1, 1, 1, 1, 1, 1, 3, 2,
- 3, 2, 0, 2, 2, 2, 2, 3, 4, 3,
- 4, 3, 3, 3, 4, 4, 4, 5, 2, 2,
- 1, 3, 2, 0, 2, 2, 2, 2, 4, 3,
- 3, 2, 4, 0, 2, 3, 1, 3, 2, 0,
- 2, 2, 2, 3, 2, 1, 3, 2, 0, 2,
- 2, 2, 3, 3, 1, 3, 2, 2, 2, 0,
+ 0, 2, 1, 0, 2, 2, 2, 4, 2, 4,
+ 4, 3, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 3, 2, 3, 2, 3,
+ 2, 0, 2, 2, 2, 2, 2, 3, 4, 4,
+ 4, 5, 2, 2, 1, 3, 0, 2, 2, 2,
+ 2, 2, 4, 3, 2, 4, 0, 2, 3, 1,
+ 3, 0, 2, 2, 2, 3, 2, 1, 3, 0,
+ 2, 2, 2, 3, 3, 2, 2, 2, 0, 2,
2, 2, 4, 3, 3, 0, 2, 1, 1, 2,
- 2, 2, 1, 1, 0, 2, 1, 3, 3, 3,
+ 2, 2, 1, 2, 0, 2, 1, 3, 3, 3,
2, 3, 3, 1, 1
};
@@ -517,151 +508,160 @@ static const unsigned char yyr2[] =
means the default is an error. */
static const unsigned char yydefact[] =
{
- 2, 0, 1, 0, 0, 0, 8, 0, 0, 10,
- 0, 0, 0, 0, 9, 93, 92, 3, 4, 22,
- 14, 22, 15, 43, 53, 5, 59, 12, 79, 68,
- 6, 74, 16, 79, 13, 17, 11, 87, 88, 0,
- 0, 0, 38, 0, 0, 0, 103, 104, 0, 0,
- 0, 96, 19, 21, 39, 42, 58, 64, 0, 76,
- 7, 63, 73, 75, 18, 20, 0, 100, 55, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 85, 0,
- 85, 0, 85, 85, 85, 26, 0, 0, 23, 0,
- 25, 24, 0, 0, 0, 85, 85, 47, 44, 46,
- 45, 0, 0, 0, 54, 41, 40, 60, 62, 57,
- 61, 56, 81, 80, 0, 69, 71, 66, 70, 65,
- 99, 101, 102, 98, 97, 77, 0, 0, 0, 94,
- 94, 0, 94, 94, 0, 94, 0, 0, 0, 94,
- 0, 78, 51, 94, 94, 0, 0, 89, 90, 91,
- 72, 0, 83, 84, 0, 0, 0, 27, 86, 0,
- 29, 0, 33, 31, 32, 0, 94, 0, 0, 49,
- 50, 82, 95, 34, 35, 28, 30, 36, 0, 48,
- 52, 37
+ 3, 0, 0, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 12, 16, 13, 14,
+ 18, 15, 17, 0, 19, 0, 4, 31, 22, 31,
+ 23, 46, 56, 5, 61, 20, 78, 69, 6, 24,
+ 78, 21, 8, 11, 87, 88, 0, 0, 89, 0,
+ 42, 90, 0, 0, 0, 103, 104, 0, 0, 0,
+ 96, 91, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 92, 7, 65, 73, 74, 27, 29, 0,
+ 100, 0, 0, 58, 0, 0, 9, 10, 0, 0,
+ 0, 0, 0, 85, 0, 0, 0, 0, 36, 35,
+ 32, 0, 34, 33, 0, 0, 85, 0, 50, 51,
+ 47, 49, 48, 57, 45, 44, 62, 64, 60, 63,
+ 59, 80, 81, 79, 70, 72, 68, 71, 67, 93,
+ 99, 101, 102, 98, 97, 26, 76, 0, 0, 0,
+ 94, 0, 94, 94, 94, 0, 0, 77, 54, 94,
+ 0, 94, 0, 83, 84, 0, 0, 37, 86, 0,
+ 0, 94, 25, 0, 53, 0, 82, 95, 38, 39,
+ 40, 0, 52, 55, 41
};
/* YYDEFGOTO[NTERM-NUM]. */
-static const short yydefgoto[] =
+static const short int yydefgoto[] =
{
- -1, 1, 17, 18, 19, 20, 21, 22, 52, 88,
- 23, 24, 105, 25, 54, 98, 55, 26, 109, 27,
- 56, 28, 29, 117, 30, 58, 31, 32, 33, 34,
- 89, 90, 57, 91, 131, 132, 106, 35, 155, 50,
- 51
+ -1, 1, 2, 25, 26, 99, 27, 28, 29, 30,
+ 64, 100, 31, 32, 114, 33, 66, 110, 67, 34,
+ 118, 35, 68, 36, 37, 126, 38, 70, 39, 40,
+ 41, 101, 102, 69, 103, 141, 142, 42, 73, 156,
+ 59, 60
};
/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
STATE-NUM. */
-#define YYPACT_NINF -99
-static const short yypact[] =
+#define YYPACT_NINF -78
+static const short int yypact[] =
{
- -99, 48, -99, 38, 46, 46, -99, 46, -29, -99,
- 46, -17, -3, -11, -99, -99, -99, -99, -99, -99,
- -99, -99, -99, -99, -99, -99, -99, -99, -99, -99,
- -99, -99, -99, -99, -99, -99, -99, -99, -99, 38,
- 12, 15, -99, 18, 51, 62, -99, -99, -11, -11,
- 4, -24, 138, 138, 160, 121, 110, -4, 81, -4,
- -99, -99, -99, -99, -99, -99, -19, -99, -99, -11,
- -11, 70, 70, 73, 32, -11, 46, -11, 46, -11,
- 46, -11, 46, 46, 46, -99, 36, 70, -99, 95,
- -99, -99, 96, 46, 106, 46, 46, -99, -99, -99,
- -99, 38, 38, 38, -99, -99, -99, -99, -99, -99,
- -99, -99, -99, -99, 112, -99, -99, -99, -99, -99,
- -99, 117, -99, -99, -99, -99, -11, 33, 65, 131,
- 1, 119, 131, 1, 136, 1, 153, 154, 155, 131,
- 70, -99, -99, 131, 131, 156, 157, -99, -99, -99,
- -99, 101, -99, -99, -11, 158, 159, -99, -99, 161,
- -99, 162, -99, -99, -99, 163, 131, 164, 165, -99,
- -99, -99, 99, -99, -99, -99, -99, -99, 166, -99,
- -99, -99
+ -78, 2, 159, -78, -21, 0, 0, -12, 0, 1,
+ 4, 0, 27, 38, 60, 58, -78, -78, -78, -78,
+ -78, -78, -78, 100, -78, 104, -78, -78, -78, -78,
+ -78, -78, -78, -78, -78, -78, -78, -78, -78, -78,
+ -78, -78, -78, -78, -78, -78, 86, 113, -78, 114,
+ -78, -78, 125, 127, 128, -78, -78, 60, 60, 210,
+ 65, -78, 141, 142, 39, 103, 182, 200, 6, 66,
+ 6, 131, -78, 146, -78, -78, -78, -78, -78, 196,
+ -78, 60, 60, 146, 40, 40, -78, -78, 155, 156,
+ -2, 60, 0, 0, 60, 105, 40, 194, -78, -78,
+ -78, 206, -78, -78, 183, 0, 0, 195, -78, -78,
+ -78, -78, -78, -78, -78, -78, -78, -78, -78, -78,
+ -78, -78, -78, -78, -78, -78, -78, -78, -78, -78,
+ -78, 197, -78, -78, -78, -78, -78, 60, 213, 216,
+ 212, 203, 212, 190, 212, 40, 208, -78, -78, 212,
+ 222, 212, 219, -78, -78, 60, 223, -78, -78, 224,
+ 225, 212, -78, 226, -78, 227, -78, 47, -78, -78,
+ -78, 228, -78, -78, -78
};
/* YYPGOTO[NTERM-NUM]. */
-static const short yypgoto[] =
+static const short int yypgoto[] =
{
- -99, -99, -99, 111, -99, -99, -99, -99, 178, -99,
- -99, -99, -99, 91, -99, -99, -99, -99, -99, -99,
- -99, -99, -99, -99, 115, -99, -99, -99, -99, -99,
- -99, 146, 168, 89, 27, 0, 126, -1, -98, -48,
- -63
+ -78, -78, -78, -78, 164, -36, -78, -78, -78, -78,
+ 230, -78, -78, -78, -78, 29, -78, -78, -78, -78,
+ -78, -78, -78, -78, -78, -78, 59, -78, -78, -78,
+ -78, -78, 198, 220, 24, 157, -5, 169, 202, 74,
+ -53, -77
};
/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
positive, shift that token. If negative, reduce the rule which
number is the opposite. If zero, do what YYDEFACT says.
If YYTABLE_NINF, syntax error. */
-#define YYTABLE_NINF -68
-static const short yytable[] =
+#define YYTABLE_NINF -76
+static const short int yytable[] =
{
- 66, 67, 36, 42, 39, 40, 71, 41, 123, 124,
- 43, 44, 74, 75, 120, 154, 72, 46, 47, 69,
- 70, 121, 122, 48, 140, 45, 127, 128, 112, 130,
- 49, 133, 156, 135, 158, 159, 68, 161, 60, 69,
- 70, 165, 69, 70, 61, 167, 168, 62, 2, 3,
- 63, 4, 5, 6, 7, 8, 9, 10, 11, 12,
- 46, 47, 13, 14, 139, 152, 48, 126, 178, 15,
- 16, 69, 70, 49, 37, 38, 129, 166, 151, 15,
- 16, -67, 114, 64, -67, 5, 101, 7, 8, 102,
- 10, 11, 12, 143, 65, 13, 103, 153, 46, 47,
- 147, 148, 149, 69, 70, 125, 172, 134, 141, 136,
- 137, 138, 15, 16, 5, 101, 7, 8, 102, 10,
- 11, 12, 145, 146, 13, 103, 101, 7, 142, 102,
- 10, 11, 12, 171, 144, 13, 103, 69, 70, 69,
- 70, 15, 16, 100, 150, 154, 113, 108, 113, 116,
- 73, 157, 15, 16, 74, 75, 70, 76, 77, 78,
- 79, 80, 81, 82, 83, 84, 104, 107, 160, 115,
- 85, 110, 73, 118, 86, 87, 74, 75, 92, 93,
- 94, 95, 111, 96, 119, 162, 163, 164, 169, 170,
- 173, 174, 97, 175, 176, 177, 179, 180, 181, 53,
- 99, 59
+ 46, 47, 3, 49, 79, 80, 52, 133, 134, 43,
+ 6, 7, 8, 9, 10, 11, 12, 13, 48, 145,
+ 14, 15, 137, 55, 56, 44, 45, 57, 131, 132,
+ 109, 50, 58, 122, 51, 122, 24, 138, 139, -28,
+ 88, 143, -28, -28, -28, -28, -28, -28, -28, -28,
+ -28, 89, 53, -28, -28, 90, 91, -28, 92, 93,
+ 94, 95, 96, 54, 97, 55, 56, 88, 161, 98,
+ -66, -66, -66, -66, -66, -66, -66, -66, 81, 82,
+ -66, -66, 90, 91, 152, 55, 56, 140, 61, 57,
+ 112, 97, 84, 123, 58, 123, 121, 117, 85, 125,
+ 149, 62, 167, -30, 88, 63, -30, -30, -30, -30,
+ -30, -30, -30, -30, -30, 89, 72, -30, -30, 90,
+ 91, -30, 92, 93, 94, 95, 96, 119, 97, 127,
+ 144, -75, 88, 98, -75, -75, -75, -75, -75, -75,
+ -75, -75, -75, 74, 75, -75, -75, 90, 91, -75,
+ -75, -75, -75, -75, -75, 76, 97, 77, 78, -2,
+ 4, 121, 5, 6, 7, 8, 9, 10, 11, 12,
+ 13, 86, 87, 14, 15, 16, 129, 17, 18, 19,
+ 20, 21, 22, 88, 23, 135, 136, -43, -43, 24,
+ -43, -43, -43, -43, 89, 146, -43, -43, 90, 91,
+ 104, 105, 106, 107, 155, 7, 8, 97, 10, 11,
+ 12, 13, 108, 148, 14, 15, 158, 159, 160, 147,
+ 151, 81, 82, 163, 130, 165, 155, 81, 82, 82,
+ 24, 113, 116, 157, 124, 171, 115, 120, 162, 128,
+ 72, 81, 82, 153, 81, 82, 154, 81, 82, 166,
+ 81, 82, 164, 168, 169, 170, 172, 173, 174, 65,
+ 71, 83, 0, 150, 111
};
-static const unsigned char yycheck[] =
+static const short int yycheck[] =
{
- 48, 49, 3, 32, 4, 5, 30, 7, 71, 72,
- 10, 28, 16, 17, 33, 14, 40, 28, 29, 38,
- 39, 69, 70, 34, 87, 28, 74, 75, 32, 77,
- 41, 79, 130, 81, 132, 133, 32, 135, 39, 38,
- 39, 139, 38, 39, 32, 143, 144, 32, 0, 1,
- 32, 3, 4, 5, 6, 7, 8, 9, 10, 11,
- 28, 29, 14, 15, 28, 32, 34, 35, 166, 31,
- 32, 38, 39, 41, 28, 29, 76, 140, 126, 31,
- 32, 0, 1, 32, 3, 4, 5, 6, 7, 8,
- 9, 10, 11, 93, 32, 14, 15, 32, 28, 29,
- 101, 102, 103, 38, 39, 32, 154, 80, 13, 82,
- 83, 84, 31, 32, 4, 5, 6, 7, 8, 9,
- 10, 11, 95, 96, 14, 15, 5, 6, 32, 8,
- 9, 10, 11, 32, 28, 14, 15, 38, 39, 38,
- 39, 31, 32, 54, 32, 14, 57, 56, 59, 58,
- 12, 32, 31, 32, 16, 17, 39, 19, 20, 21,
- 22, 23, 24, 25, 26, 27, 55, 56, 32, 58,
- 32, 56, 12, 58, 36, 37, 16, 17, 18, 19,
- 20, 21, 56, 23, 58, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 21,
- 54, 33
+ 5, 6, 0, 8, 57, 58, 11, 84, 85, 30,
+ 4, 5, 6, 7, 8, 9, 10, 11, 30, 96,
+ 14, 15, 24, 25, 26, 25, 26, 29, 81, 82,
+ 66, 30, 34, 69, 30, 71, 30, 90, 91, 0,
+ 1, 94, 3, 4, 5, 6, 7, 8, 9, 10,
+ 11, 12, 25, 14, 15, 16, 17, 18, 19, 20,
+ 21, 22, 23, 25, 25, 25, 26, 1, 145, 30,
+ 4, 5, 6, 7, 8, 9, 10, 11, 31, 32,
+ 14, 15, 16, 17, 137, 25, 26, 92, 30, 29,
+ 66, 25, 27, 69, 34, 71, 30, 68, 33, 70,
+ 105, 1, 155, 0, 1, 1, 3, 4, 5, 6,
+ 7, 8, 9, 10, 11, 12, 30, 14, 15, 16,
+ 17, 18, 19, 20, 21, 22, 23, 68, 25, 70,
+ 25, 0, 1, 30, 3, 4, 5, 6, 7, 8,
+ 9, 10, 11, 30, 30, 14, 15, 16, 17, 18,
+ 19, 20, 21, 22, 23, 30, 25, 30, 30, 0,
+ 1, 30, 3, 4, 5, 6, 7, 8, 9, 10,
+ 11, 30, 30, 14, 15, 16, 30, 18, 19, 20,
+ 21, 22, 23, 1, 25, 30, 30, 5, 6, 30,
+ 8, 9, 10, 11, 12, 1, 14, 15, 16, 17,
+ 18, 19, 20, 21, 14, 5, 6, 25, 8, 9,
+ 10, 11, 30, 30, 14, 15, 142, 143, 144, 13,
+ 25, 31, 32, 149, 28, 151, 14, 31, 32, 32,
+ 30, 67, 68, 30, 70, 161, 67, 68, 30, 70,
+ 30, 31, 32, 30, 31, 32, 30, 31, 32, 30,
+ 31, 32, 30, 30, 30, 30, 30, 30, 30, 29,
+ 40, 59, -1, 106, 66
};
/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
symbol of state STATE-NUM. */
static const unsigned char yystos[] =
{
- 0, 43, 0, 1, 3, 4, 5, 6, 7, 8,
- 9, 10, 11, 14, 15, 31, 32, 44, 45, 46,
- 47, 48, 49, 52, 53, 55, 59, 61, 63, 64,
- 66, 68, 69, 70, 71, 79, 79, 28, 29, 77,
- 77, 77, 32, 77, 28, 28, 28, 29, 34, 41,
- 81, 82, 50, 50, 56, 58, 62, 74, 67, 74,
- 79, 32, 32, 32, 32, 32, 81, 81, 32, 38,
- 39, 30, 40, 12, 16, 17, 19, 20, 21, 22,
- 23, 24, 25, 26, 27, 32, 36, 37, 51, 72,
- 73, 75, 18, 19, 20, 21, 23, 32, 57, 73,
- 75, 5, 8, 15, 45, 54, 78, 45, 55, 60,
- 66, 78, 32, 75, 1, 45, 55, 65, 66, 78,
- 33, 81, 81, 82, 82, 32, 35, 81, 81, 77,
- 81, 76, 77, 81, 76, 81, 76, 76, 76, 28,
- 82, 13, 32, 77, 28, 76, 76, 79, 79, 79,
- 32, 81, 32, 32, 14, 80, 80, 32, 80, 80,
- 32, 80, 32, 32, 32, 80, 82, 80, 80, 32,
- 32, 32, 81, 32, 32, 32, 32, 32, 80, 32,
- 32, 32
+ 0, 36, 37, 0, 1, 3, 4, 5, 6, 7,
+ 8, 9, 10, 11, 14, 15, 16, 18, 19, 20,
+ 21, 22, 23, 25, 30, 38, 39, 41, 42, 43,
+ 44, 47, 48, 50, 54, 56, 58, 59, 61, 63,
+ 64, 65, 72, 30, 25, 26, 71, 71, 30, 71,
+ 30, 30, 71, 25, 25, 25, 26, 29, 34, 75,
+ 76, 30, 1, 1, 45, 45, 51, 53, 57, 68,
+ 62, 68, 30, 73, 30, 30, 30, 30, 30, 75,
+ 75, 31, 32, 73, 27, 33, 30, 30, 1, 12,
+ 16, 17, 19, 20, 21, 22, 23, 25, 30, 40,
+ 46, 66, 67, 69, 18, 19, 20, 21, 30, 40,
+ 52, 67, 69, 39, 49, 72, 39, 50, 55, 61,
+ 72, 30, 40, 69, 39, 50, 60, 61, 72, 30,
+ 28, 75, 75, 76, 76, 30, 30, 24, 75, 75,
+ 71, 70, 71, 75, 25, 76, 1, 13, 30, 71,
+ 70, 25, 75, 30, 30, 14, 74, 30, 74, 74,
+ 74, 76, 30, 74, 30, 74, 30, 75, 30, 30,
+ 30, 74, 30, 30, 30
};
#if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__)
@@ -687,7 +687,7 @@ static const unsigned char yystos[] =
#define YYACCEPT goto yyacceptlab
#define YYABORT goto yyabortlab
-#define YYERROR goto yyerrlab1
+#define YYERROR goto yyerrorlab
/* Like YYERROR except do call yyerror. This remains here temporarily
@@ -715,20 +715,53 @@ do \
} \
while (0)
+
#define YYTERROR 1
#define YYERRCODE 256
-/* YYLLOC_DEFAULT -- Compute the default location (before the actions
- are run). */
+/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].
+ If N is 0, then set CURRENT to the empty location which ends
+ the previous symbol: RHS[0] (always defined). */
+
+#define YYRHSLOC(Rhs, K) ((Rhs)[K])
#ifndef YYLLOC_DEFAULT
-# define YYLLOC_DEFAULT(Current, Rhs, N) \
- Current.first_line = Rhs[1].first_line; \
- Current.first_column = Rhs[1].first_column; \
- Current.last_line = Rhs[N].last_line; \
- Current.last_column = Rhs[N].last_column;
+# define YYLLOC_DEFAULT(Current, Rhs, N) \
+ do \
+ if (N) \
+ { \
+ (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \
+ (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \
+ (Current).last_line = YYRHSLOC (Rhs, N).last_line; \
+ (Current).last_column = YYRHSLOC (Rhs, N).last_column; \
+ } \
+ else \
+ { \
+ (Current).first_line = (Current).last_line = \
+ YYRHSLOC (Rhs, 0).last_line; \
+ (Current).first_column = (Current).last_column = \
+ YYRHSLOC (Rhs, 0).last_column; \
+ } \
+ while (0)
+#endif
+
+
+/* YY_LOCATION_PRINT -- Print the location on the stream.
+ This macro was not mandated originally: define only if we know
+ we won't break user code: when these are the locations we know. */
+
+#ifndef YY_LOCATION_PRINT
+# if YYLTYPE_IS_TRIVIAL
+# define YY_LOCATION_PRINT(File, Loc) \
+ fprintf (File, "%d.%d-%d.%d", \
+ (Loc).first_line, (Loc).first_column, \
+ (Loc).last_line, (Loc).last_column)
+# else
+# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
+# endif
#endif
+
/* YYLEX -- calling `yylex' with the right arguments. */
#ifdef YYLEX_PARAM
@@ -751,36 +784,30 @@ do { \
YYFPRINTF Args; \
} while (0)
-# define YYDSYMPRINT(Args) \
-do { \
- if (yydebug) \
- yysymprint Args; \
-} while (0)
-
-# define YYDSYMPRINTF(Title, Token, Value, Location) \
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \
do { \
if (yydebug) \
{ \
YYFPRINTF (stderr, "%s ", Title); \
yysymprint (stderr, \
- Token, Value); \
+ Type, Value); \
YYFPRINTF (stderr, "\n"); \
} \
} while (0)
/*------------------------------------------------------------------.
| yy_stack_print -- Print the state stack from its BOTTOM up to its |
-| TOP (cinluded). |
+| TOP (included). |
`------------------------------------------------------------------*/
#if defined (__STDC__) || defined (__cplusplus)
static void
-yy_stack_print (short *bottom, short *top)
+yy_stack_print (short int *bottom, short int *top)
#else
static void
yy_stack_print (bottom, top)
- short *bottom;
- short *top;
+ short int *bottom;
+ short int *top;
#endif
{
YYFPRINTF (stderr, "Stack now");
@@ -810,9 +837,9 @@ yy_reduce_print (yyrule)
#endif
{
int yyi;
- unsigned int yylineno = yyrline[yyrule];
+ unsigned int yylno = yyrline[yyrule];
YYFPRINTF (stderr, "Reducing stack by rule %d (line %u), ",
- yyrule - 1, yylineno);
+ yyrule - 1, yylno);
/* Print the symbols being reduced, and their result. */
for (yyi = yyprhs[yyrule]; 0 <= yyrhs[yyi]; yyi++)
YYFPRINTF (stderr, "%s ", yytname [yyrhs[yyi]]);
@@ -830,8 +857,7 @@ do { \
int yydebug;
#else /* !YYDEBUG */
# define YYDPRINTF(Args)
-# define YYDSYMPRINT(Args)
-# define YYDSYMPRINTF(Title, Token, Value, Location)
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location)
# define YY_STACK_PRINT(Bottom, Top)
# define YY_REDUCE_PRINT(Rule)
#endif /* !YYDEBUG */
@@ -849,10 +875,6 @@ int yydebug;
SIZE_MAX < YYSTACK_BYTES (YYMAXDEPTH)
evaluated with infinite-precision integer arithmetic. */
-#if YYMAXDEPTH == 0
-# undef YYMAXDEPTH
-#endif
-
#ifndef YYMAXDEPTH
# define YYMAXDEPTH 10000
#endif
@@ -934,15 +956,15 @@ yysymprint (yyoutput, yytype, yyvaluep)
(void) yyvaluep;
if (yytype < YYNTOKENS)
- {
- YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
-# ifdef YYPRINT
- YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
-# endif
- }
+ YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
else
YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
+
+# ifdef YYPRINT
+ if (yytype < YYNTOKENS)
+ YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
+# endif
switch (yytype)
{
default:
@@ -958,10 +980,11 @@ yysymprint (yyoutput, yytype, yyvaluep)
#if defined (__STDC__) || defined (__cplusplus)
static void
-yydestruct (int yytype, YYSTYPE *yyvaluep)
+yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep)
#else
static void
-yydestruct (yytype, yyvaluep)
+yydestruct (yymsg, yytype, yyvaluep)
+ const char *yymsg;
int yytype;
YYSTYPE *yyvaluep;
#endif
@@ -969,8 +992,42 @@ yydestruct (yytype, yyvaluep)
/* Pacify ``unused variable'' warnings. */
(void) yyvaluep;
+ if (!yymsg)
+ yymsg = "Deleting";
+ YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
+
switch (yytype)
{
+ case 48: /* choice_entry */
+
+ {
+ fprintf(stderr, "%s:%d: missing end statement for this entry\n",
+ (yyvaluep->menu)->file->name, (yyvaluep->menu)->lineno);
+ if (current_menu == (yyvaluep->menu))
+ menu_end_menu();
+};
+
+ break;
+ case 54: /* if_entry */
+
+ {
+ fprintf(stderr, "%s:%d: missing end statement for this entry\n",
+ (yyvaluep->menu)->file->name, (yyvaluep->menu)->lineno);
+ if (current_menu == (yyvaluep->menu))
+ menu_end_menu();
+};
+
+ break;
+ case 59: /* menu_entry */
+
+ {
+ fprintf(stderr, "%s:%d: missing end statement for this entry\n",
+ (yyvaluep->menu)->file->name, (yyvaluep->menu)->lineno);
+ if (current_menu == (yyvaluep->menu))
+ menu_end_menu();
+};
+
+ break;
default:
break;
@@ -996,10 +1053,10 @@ int yyparse ();
-/* The lookahead symbol. */
+/* The look-ahead symbol. */
int yychar;
-/* The semantic value of the lookahead symbol. */
+/* The semantic value of the look-ahead symbol. */
YYSTYPE yylval;
/* Number of syntax errors so far. */
@@ -1035,7 +1092,7 @@ yyparse ()
int yyresult;
/* Number of tokens to shift before error messages enabled. */
int yyerrstatus;
- /* Lookahead token as an internal (translated) token number. */
+ /* Look-ahead token as an internal (translated) token number. */
int yytoken = 0;
/* Three stacks and their tools:
@@ -1047,9 +1104,9 @@ yyparse ()
to reallocate them elsewhere. */
/* The state stack. */
- short yyssa[YYINITDEPTH];
- short *yyss = yyssa;
- register short *yyssp;
+ short int yyssa[YYINITDEPTH];
+ short int *yyss = yyssa;
+ register short int *yyssp;
/* The semantic value stack. */
YYSTYPE yyvsa[YYINITDEPTH];
@@ -1086,6 +1143,9 @@ yyparse ()
yyssp = yyss;
yyvsp = yyvs;
+
+ yyvsp[0] = yylval;
+
goto yysetstate;
/*------------------------------------------------------------.
@@ -1111,7 +1171,7 @@ yyparse ()
these so that the &'s don't force the real ones into
memory. */
YYSTYPE *yyvs1 = yyvs;
- short *yyss1 = yyss;
+ short int *yyss1 = yyss;
/* Each stack pointer address is followed by the size of the
@@ -1139,7 +1199,7 @@ yyparse ()
yystacksize = YYMAXDEPTH;
{
- short *yyss1 = yyss;
+ short int *yyss1 = yyss;
union yyalloc *yyptr =
(union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
if (! yyptr)
@@ -1175,18 +1235,18 @@ yyparse ()
yybackup:
/* Do appropriate processing given the current state. */
-/* Read a lookahead token if we need one and don't already have one. */
+/* Read a look-ahead token if we need one and don't already have one. */
/* yyresume: */
- /* First try to decide what to do without reference to lookahead token. */
+ /* First try to decide what to do without reference to look-ahead token. */
yyn = yypact[yystate];
if (yyn == YYPACT_NINF)
goto yydefault;
- /* Not known => get a lookahead token if don't already have one. */
+ /* Not known => get a look-ahead token if don't already have one. */
- /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */
+ /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol. */
if (yychar == YYEMPTY)
{
YYDPRINTF ((stderr, "Reading a token: "));
@@ -1201,7 +1261,7 @@ yybackup:
else
{
yytoken = YYTRANSLATE (yychar);
- YYDSYMPRINTF ("Next token is", yytoken, &yylval, &yylloc);
+ YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
}
/* If the proper action on seeing token YYTOKEN is to reduce or to
@@ -1221,8 +1281,8 @@ yybackup:
if (yyn == YYFINAL)
YYACCEPT;
- /* Shift the lookahead token. */
- YYDPRINTF ((stderr, "Shifting token %s, ", yytname[yytoken]));
+ /* Shift the look-ahead token. */
+ YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
/* Discard the token being shifted unless it is eof. */
if (yychar != YYEOF)
@@ -1273,155 +1333,123 @@ yyreduce:
{
case 8:
- { zconfprint("unexpected 'endmenu' statement"); ;}
+ { zconf_error("unexpected end statement"); ;}
break;
case 9:
- { zconfprint("unexpected 'endif' statement"); ;}
+ { zconf_error("unknown statement \"%s\"", (yyvsp[-2].string)); ;}
break;
case 10:
- { zconfprint("unexpected 'endchoice' statement"); ;}
+ {
+ zconf_error("unexpected option \"%s\"", kconf_id_strings + (yyvsp[-2].id)->name);
+;}
break;
case 11:
- { zconfprint("syntax error"); yyerrok; ;}
+ { zconf_error("invalid statement"); ;}
break;
- case 18:
+ case 25:
- {
- struct symbol *sym = sym_lookup(yyvsp[-1].string, 0);
- sym->flags |= SYMBOL_OPTIONAL;
- menu_add_entry(sym);
- printd(DEBUG_PARSE, "%s:%d:config %s\n", zconf_curname(), zconf_lineno(), yyvsp[-1].string);
-;}
+ { zconf_error("unknown option \"%s\"", (yyvsp[-2].string)); ;}
break;
- case 19:
+ case 26:
- {
- menu_end_entry();
- printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno());
-;}
+ { zconf_error("invalid option"); ;}
break;
- case 20:
+ case 27:
{
- struct symbol *sym = sym_lookup(yyvsp[-1].string, 0);
+ struct symbol *sym = sym_lookup((yyvsp[-1].string), 0);
sym->flags |= SYMBOL_OPTIONAL;
menu_add_entry(sym);
- printd(DEBUG_PARSE, "%s:%d:menuconfig %s\n", zconf_curname(), zconf_lineno(), yyvsp[-1].string);
+ printd(DEBUG_PARSE, "%s:%d:config %s\n", zconf_curname(), zconf_lineno(), (yyvsp[-1].string));
;}
break;
- case 21:
+ case 28:
{
- if (current_entry->prompt)
- current_entry->prompt->type = P_MENU;
- else
- zconfprint("warning: menuconfig statement without prompt");
menu_end_entry();
printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno());
;}
break;
- case 27:
-
- {
- menu_set_type(S_TRISTATE);
- printd(DEBUG_PARSE, "%s:%d:tristate\n", zconf_curname(), zconf_lineno());
-;}
- break;
-
- case 28:
-
- {
- menu_add_expr(P_DEFAULT, yyvsp[-2].expr, yyvsp[-1].expr);
- menu_set_type(S_TRISTATE);
- printd(DEBUG_PARSE, "%s:%d:def_boolean\n", zconf_curname(), zconf_lineno());
-;}
- break;
-
case 29:
{
- menu_set_type(S_BOOLEAN);
- printd(DEBUG_PARSE, "%s:%d:boolean\n", zconf_curname(), zconf_lineno());
+ struct symbol *sym = sym_lookup((yyvsp[-1].string), 0);
+ sym->flags |= SYMBOL_OPTIONAL;
+ menu_add_entry(sym);
+ printd(DEBUG_PARSE, "%s:%d:menuconfig %s\n", zconf_curname(), zconf_lineno(), (yyvsp[-1].string));
;}
break;
case 30:
{
- menu_add_expr(P_DEFAULT, yyvsp[-2].expr, yyvsp[-1].expr);
- menu_set_type(S_BOOLEAN);
- printd(DEBUG_PARSE, "%s:%d:def_boolean\n", zconf_curname(), zconf_lineno());
-;}
- break;
-
- case 31:
-
- {
- menu_set_type(S_INT);
- printd(DEBUG_PARSE, "%s:%d:int\n", zconf_curname(), zconf_lineno());
-;}
- break;
-
- case 32:
-
- {
- menu_set_type(S_HEX);
- printd(DEBUG_PARSE, "%s:%d:hex\n", zconf_curname(), zconf_lineno());
+ if (current_entry->prompt)
+ current_entry->prompt->type = P_MENU;
+ else
+ zconfprint("warning: menuconfig statement without prompt");
+ menu_end_entry();
+ printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno());
;}
break;
- case 33:
+ case 37:
{
- menu_set_type(S_STRING);
- printd(DEBUG_PARSE, "%s:%d:string\n", zconf_curname(), zconf_lineno());
+ menu_set_type((yyvsp[-2].id)->stype);
+ printd(DEBUG_PARSE, "%s:%d:type(%u)\n",
+ zconf_curname(), zconf_lineno(),
+ (yyvsp[-2].id)->stype);
;}
break;
- case 34:
+ case 38:
{
- menu_add_prompt(P_PROMPT, yyvsp[-2].string, yyvsp[-1].expr);
+ menu_add_prompt(P_PROMPT, (yyvsp[-2].string), (yyvsp[-1].expr));
printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno());
;}
break;
- case 35:
+ case 39:
{
- menu_add_expr(P_DEFAULT, yyvsp[-2].expr, yyvsp[-1].expr);
- printd(DEBUG_PARSE, "%s:%d:default\n", zconf_curname(), zconf_lineno());
+ menu_add_expr(P_DEFAULT, (yyvsp[-2].expr), (yyvsp[-1].expr));
+ if ((yyvsp[-3].id)->stype != S_UNKNOWN)
+ menu_set_type((yyvsp[-3].id)->stype);
+ printd(DEBUG_PARSE, "%s:%d:default(%u)\n",
+ zconf_curname(), zconf_lineno(),
+ (yyvsp[-3].id)->stype);
;}
break;
- case 36:
+ case 40:
{
- menu_add_symbol(P_SELECT, sym_lookup(yyvsp[-2].string, 0), yyvsp[-1].expr);
+ menu_add_symbol(P_SELECT, sym_lookup((yyvsp[-2].string), 0), (yyvsp[-1].expr));
printd(DEBUG_PARSE, "%s:%d:select\n", zconf_curname(), zconf_lineno());
;}
break;
- case 37:
+ case 41:
{
- menu_add_expr(P_RANGE, expr_alloc_comp(E_RANGE,yyvsp[-3].symbol, yyvsp[-2].symbol), yyvsp[-1].expr);
+ menu_add_expr(P_RANGE, expr_alloc_comp(E_RANGE,(yyvsp[-3].symbol), (yyvsp[-2].symbol)), (yyvsp[-1].expr));
printd(DEBUG_PARSE, "%s:%d:range\n", zconf_curname(), zconf_lineno());
;}
break;
- case 38:
+ case 42:
{
struct symbol *sym = sym_lookup(NULL, 0);
@@ -1432,57 +1460,45 @@ yyreduce:
;}
break;
- case 39:
+ case 43:
{
- menu_end_entry();
- menu_add_menu();
+ (yyval.menu) = menu_add_menu();
;}
break;
- case 40:
+ case 44:
{
- if (zconf_endtoken(yyvsp[0].token, T_CHOICE, T_ENDCHOICE)) {
+ if (zconf_endtoken((yyvsp[0].id), T_CHOICE, T_ENDCHOICE)) {
menu_end_menu();
printd(DEBUG_PARSE, "%s:%d:endchoice\n", zconf_curname(), zconf_lineno());
}
;}
break;
- case 42:
-
- {
- printf("%s:%d: missing 'endchoice' for this 'choice' statement\n", current_menu->file->name, current_menu->lineno);
- zconfnerrs++;
-;}
- break;
-
- case 48:
+ case 52:
{
- menu_add_prompt(P_PROMPT, yyvsp[-2].string, yyvsp[-1].expr);
+ menu_add_prompt(P_PROMPT, (yyvsp[-2].string), (yyvsp[-1].expr));
printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno());
;}
break;
- case 49:
+ case 53:
{
- menu_set_type(S_TRISTATE);
- printd(DEBUG_PARSE, "%s:%d:tristate\n", zconf_curname(), zconf_lineno());
+ if ((yyvsp[-2].id)->stype == S_BOOLEAN || (yyvsp[-2].id)->stype == S_TRISTATE) {
+ menu_set_type((yyvsp[-2].id)->stype);
+ printd(DEBUG_PARSE, "%s:%d:type(%u)\n",
+ zconf_curname(), zconf_lineno(),
+ (yyvsp[-2].id)->stype);
+ } else
+ YYERROR;
;}
break;
- case 50:
-
- {
- menu_set_type(S_BOOLEAN);
- printd(DEBUG_PARSE, "%s:%d:boolean\n", zconf_curname(), zconf_lineno());
-;}
- break;
-
- case 51:
+ case 54:
{
current_entry->sym->flags |= SYMBOL_OPTIONAL;
@@ -1490,115 +1506,89 @@ yyreduce:
;}
break;
- case 52:
+ case 55:
{
- menu_add_symbol(P_DEFAULT, sym_lookup(yyvsp[-2].string, 0), yyvsp[-1].expr);
- printd(DEBUG_PARSE, "%s:%d:default\n", zconf_curname(), zconf_lineno());
+ if ((yyvsp[-3].id)->stype == S_UNKNOWN) {
+ menu_add_symbol(P_DEFAULT, sym_lookup((yyvsp[-2].string), 0), (yyvsp[-1].expr));
+ printd(DEBUG_PARSE, "%s:%d:default\n",
+ zconf_curname(), zconf_lineno());
+ } else
+ YYERROR;
;}
break;
- case 55:
+ case 58:
{
printd(DEBUG_PARSE, "%s:%d:if\n", zconf_curname(), zconf_lineno());
menu_add_entry(NULL);
- menu_add_dep(yyvsp[-1].expr);
- menu_end_entry();
- menu_add_menu();
+ menu_add_dep((yyvsp[-1].expr));
+ (yyval.menu) = menu_add_menu();
;}
break;
- case 56:
+ case 59:
{
- if (zconf_endtoken(yyvsp[0].token, T_IF, T_ENDIF)) {
+ if (zconf_endtoken((yyvsp[0].id), T_IF, T_ENDIF)) {
menu_end_menu();
printd(DEBUG_PARSE, "%s:%d:endif\n", zconf_curname(), zconf_lineno());
}
;}
break;
- case 58:
-
- {
- printf("%s:%d: missing 'endif' for this 'if' statement\n", current_menu->file->name, current_menu->lineno);
- zconfnerrs++;
-;}
- break;
-
- case 63:
+ case 65:
{
menu_add_entry(NULL);
- menu_add_prompt(P_MENU, yyvsp[-1].string, NULL);
+ menu_add_prompt(P_MENU, (yyvsp[-1].string), NULL);
printd(DEBUG_PARSE, "%s:%d:menu\n", zconf_curname(), zconf_lineno());
;}
break;
- case 64:
+ case 66:
{
- menu_end_entry();
- menu_add_menu();
+ (yyval.menu) = menu_add_menu();
;}
break;
- case 65:
+ case 67:
{
- if (zconf_endtoken(yyvsp[0].token, T_MENU, T_ENDMENU)) {
+ if (zconf_endtoken((yyvsp[0].id), T_MENU, T_ENDMENU)) {
menu_end_menu();
printd(DEBUG_PARSE, "%s:%d:endmenu\n", zconf_curname(), zconf_lineno());
}
;}
break;
- case 67:
-
- {
- printf("%s:%d: missing 'endmenu' for this 'menu' statement\n", current_menu->file->name, current_menu->lineno);
- zconfnerrs++;
-;}
- break;
-
- case 72:
-
- { zconfprint("invalid menu option"); yyerrok; ;}
- break;
-
case 73:
{
- yyval.string = yyvsp[-1].string;
- printd(DEBUG_PARSE, "%s:%d:source %s\n", zconf_curname(), zconf_lineno(), yyvsp[-1].string);
+ printd(DEBUG_PARSE, "%s:%d:source %s\n", zconf_curname(), zconf_lineno(), (yyvsp[-1].string));
+ zconf_nextfile((yyvsp[-1].string));
;}
break;
case 74:
{
- zconf_nextfile(yyvsp[0].string);
-;}
- break;
-
- case 75:
-
- {
menu_add_entry(NULL);
- menu_add_prompt(P_COMMENT, yyvsp[-1].string, NULL);
+ menu_add_prompt(P_COMMENT, (yyvsp[-1].string), NULL);
printd(DEBUG_PARSE, "%s:%d:comment\n", zconf_curname(), zconf_lineno());
;}
break;
- case 76:
+ case 75:
{
menu_end_entry();
;}
break;
- case 77:
+ case 76:
{
printd(DEBUG_PARSE, "%s:%d:help\n", zconf_curname(), zconf_lineno());
@@ -1606,17 +1596,17 @@ yyreduce:
;}
break;
- case 78:
+ case 77:
{
- current_entry->sym->help = yyvsp[0].string;
+ current_entry->sym->help = (yyvsp[0].string);
;}
break;
case 82:
{
- menu_add_dep(yyvsp[-1].expr);
+ menu_add_dep((yyvsp[-1].expr));
printd(DEBUG_PARSE, "%s:%d:depends on\n", zconf_curname(), zconf_lineno());
;}
break;
@@ -1624,7 +1614,7 @@ yyreduce:
case 83:
{
- menu_add_dep(yyvsp[-1].expr);
+ menu_add_dep((yyvsp[-1].expr));
printd(DEBUG_PARSE, "%s:%d:depends\n", zconf_curname(), zconf_lineno());
;}
break;
@@ -1632,7 +1622,7 @@ yyreduce:
case 84:
{
- menu_add_dep(yyvsp[-1].expr);
+ menu_add_dep((yyvsp[-1].expr));
printd(DEBUG_PARSE, "%s:%d:requires\n", zconf_curname(), zconf_lineno());
;}
break;
@@ -1640,84 +1630,84 @@ yyreduce:
case 86:
{
- menu_add_prompt(P_PROMPT, yyvsp[-1].string, yyvsp[0].expr);
+ menu_add_prompt(P_PROMPT, (yyvsp[-1].string), (yyvsp[0].expr));
;}
break;
case 89:
- { yyval.token = T_ENDMENU; ;}
+ { (yyval.id) = (yyvsp[-1].id); ;}
break;
case 90:
- { yyval.token = T_ENDCHOICE; ;}
+ { (yyval.id) = (yyvsp[-1].id); ;}
break;
case 91:
- { yyval.token = T_ENDIF; ;}
+ { (yyval.id) = (yyvsp[-1].id); ;}
break;
case 94:
- { yyval.expr = NULL; ;}
+ { (yyval.expr) = NULL; ;}
break;
case 95:
- { yyval.expr = yyvsp[0].expr; ;}
+ { (yyval.expr) = (yyvsp[0].expr); ;}
break;
case 96:
- { yyval.expr = expr_alloc_symbol(yyvsp[0].symbol); ;}
+ { (yyval.expr) = expr_alloc_symbol((yyvsp[0].symbol)); ;}
break;
case 97:
- { yyval.expr = expr_alloc_comp(E_EQUAL, yyvsp[-2].symbol, yyvsp[0].symbol); ;}
+ { (yyval.expr) = expr_alloc_comp(E_EQUAL, (yyvsp[-2].symbol), (yyvsp[0].symbol)); ;}
break;
case 98:
- { yyval.expr = expr_alloc_comp(E_UNEQUAL, yyvsp[-2].symbol, yyvsp[0].symbol); ;}
+ { (yyval.expr) = expr_alloc_comp(E_UNEQUAL, (yyvsp[-2].symbol), (yyvsp[0].symbol)); ;}
break;
case 99:
- { yyval.expr = yyvsp[-1].expr; ;}
+ { (yyval.expr) = (yyvsp[-1].expr); ;}
break;
case 100:
- { yyval.expr = expr_alloc_one(E_NOT, yyvsp[0].expr); ;}
+ { (yyval.expr) = expr_alloc_one(E_NOT, (yyvsp[0].expr)); ;}
break;
case 101:
- { yyval.expr = expr_alloc_two(E_OR, yyvsp[-2].expr, yyvsp[0].expr); ;}
+ { (yyval.expr) = expr_alloc_two(E_OR, (yyvsp[-2].expr), (yyvsp[0].expr)); ;}
break;
case 102:
- { yyval.expr = expr_alloc_two(E_AND, yyvsp[-2].expr, yyvsp[0].expr); ;}
+ { (yyval.expr) = expr_alloc_two(E_AND, (yyvsp[-2].expr), (yyvsp[0].expr)); ;}
break;
case 103:
- { yyval.symbol = sym_lookup(yyvsp[0].string, 0); free(yyvsp[0].string); ;}
+ { (yyval.symbol) = sym_lookup((yyvsp[0].string), 0); free((yyvsp[0].string)); ;}
break;
case 104:
- { yyval.symbol = sym_lookup(yyvsp[0].string, 1); free(yyvsp[0].string); ;}
+ { (yyval.symbol) = sym_lookup((yyvsp[0].string), 1); free((yyvsp[0].string)); ;}
break;
}
-/* Line 999 of yacc.c. */
+/* Line 1037 of yacc.c. */
yyvsp -= yylen;
@@ -1759,18 +1749,33 @@ yyerrlab:
{
YYSIZE_T yysize = 0;
int yytype = YYTRANSLATE (yychar);
+ const char* yyprefix;
char *yymsg;
- int yyx, yycount;
+ int yyx;
- yycount = 0;
/* Start YYX at -YYN if negative to avoid negative indexes in
YYCHECK. */
- for (yyx = yyn < 0 ? -yyn : 0;
- yyx < (int) (sizeof (yytname) / sizeof (char *)); yyx++)
+ int yyxbegin = yyn < 0 ? -yyn : 0;
+
+ /* Stay within bounds of both yycheck and yytname. */
+ int yychecklim = YYLAST - yyn;
+ int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
+ int yycount = 0;
+
+ yyprefix = ", expecting ";
+ for (yyx = yyxbegin; yyx < yyxend; ++yyx)
if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
- yysize += yystrlen (yytname[yyx]) + 15, yycount++;
- yysize += yystrlen ("syntax error, unexpected ") + 1;
- yysize += yystrlen (yytname[yytype]);
+ {
+ yysize += yystrlen (yyprefix) + yystrlen (yytname [yyx]);
+ yycount += 1;
+ if (yycount == 5)
+ {
+ yysize = 0;
+ break;
+ }
+ }
+ yysize += (sizeof ("syntax error, unexpected ")
+ + yystrlen (yytname[yytype]));
yymsg = (char *) YYSTACK_ALLOC (yysize);
if (yymsg != 0)
{
@@ -1779,16 +1784,13 @@ yyerrlab:
if (yycount < 5)
{
- yycount = 0;
- for (yyx = yyn < 0 ? -yyn : 0;
- yyx < (int) (sizeof (yytname) / sizeof (char *));
- yyx++)
+ yyprefix = ", expecting ";
+ for (yyx = yyxbegin; yyx < yyxend; ++yyx)
if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
{
- const char *yyq = ! yycount ? ", expecting " : " or ";
- yyp = yystpcpy (yyp, yyq);
+ yyp = yystpcpy (yyp, yyprefix);
yyp = yystpcpy (yyp, yytname[yyx]);
- yycount++;
+ yyprefix = " or ";
}
}
yyerror (yymsg);
@@ -1806,38 +1808,57 @@ yyerrlab:
if (yyerrstatus == 3)
{
- /* If just tried and failed to reuse lookahead token after an
+ /* If just tried and failed to reuse look-ahead token after an
error, discard it. */
- /* Return failure if at end of input. */
- if (yychar == YYEOF)
+ if (yychar <= YYEOF)
{
- /* Pop the error token. */
- YYPOPSTACK;
- /* Pop the rest of the stack. */
- while (yyss < yyssp)
- {
- YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp);
- yydestruct (yystos[*yyssp], yyvsp);
- YYPOPSTACK;
- }
- YYABORT;
+ /* If at end of input, pop the error token,
+ then the rest of the stack, then return failure. */
+ if (yychar == YYEOF)
+ for (;;)
+ {
+
+ YYPOPSTACK;
+ if (yyssp == yyss)
+ YYABORT;
+ yydestruct ("Error: popping",
+ yystos[*yyssp], yyvsp);
+ }
}
-
- YYDSYMPRINTF ("Error: discarding", yytoken, &yylval, &yylloc);
- yydestruct (yytoken, &yylval);
- yychar = YYEMPTY;
-
+ else
+ {
+ yydestruct ("Error: discarding", yytoken, &yylval);
+ yychar = YYEMPTY;
+ }
}
- /* Else will try to reuse lookahead token after shifting the error
+ /* Else will try to reuse look-ahead token after shifting the error
token. */
goto yyerrlab1;
-/*----------------------------------------------------.
-| yyerrlab1 -- error raised explicitly by an action. |
-`----------------------------------------------------*/
+/*---------------------------------------------------.
+| yyerrorlab -- error raised explicitly by YYERROR. |
+`---------------------------------------------------*/
+yyerrorlab:
+
+#ifdef __GNUC__
+ /* Pacify GCC when the user code never invokes YYERROR and the label
+ yyerrorlab therefore never appears in user code. */
+ if (0)
+ goto yyerrorlab;
+#endif
+
+yyvsp -= yylen;
+ yyssp -= yylen;
+ yystate = *yyssp;
+ goto yyerrlab1;
+
+
+/*-------------------------------------------------------------.
+| yyerrlab1 -- common code for both syntax error and YYERROR. |
+`-------------------------------------------------------------*/
yyerrlab1:
yyerrstatus = 3; /* Each real token shifted decrements this. */
@@ -1859,22 +1880,22 @@ yyerrlab1:
if (yyssp == yyss)
YYABORT;
- YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp);
- yydestruct (yystos[yystate], yyvsp);
- yyvsp--;
- yystate = *--yyssp;
+ yydestruct ("Error: popping", yystos[yystate], yyvsp);
+ YYPOPSTACK;
+ yystate = *yyssp;
YY_STACK_PRINT (yyss, yyssp);
}
if (yyn == YYFINAL)
YYACCEPT;
- YYDPRINTF ((stderr, "Shifting error token, "));
-
*++yyvsp = yylval;
+ /* Shift the error token. */
+ YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);
+
yystate = yyn;
goto yynewstate;
@@ -1890,6 +1911,9 @@ yyacceptlab:
| yyabortlab -- YYABORT comes here. |
`-----------------------------------*/
yyabortlab:
+ yydestruct ("Error: discarding lookahead",
+ yytoken, &yylval);
+ yychar = YYEMPTY;
yyresult = 1;
goto yyreturn;
@@ -1927,16 +1951,16 @@ void conf_parse(const char *name)
modules_sym = sym_lookup("MODULES", 0);
rootmenu.prompt = menu_add_prompt(P_MENU, "Linux Kernel Configuration", NULL);
- //zconfdebug = 1;
+#if YYDEBUG
+ if (getenv("ZCONF_DEBUG"))
+ zconfdebug = 1;
+#endif
zconfparse();
if (zconfnerrs)
exit(1);
menu_finalize(&rootmenu);
for_all_symbols(i, sym) {
- if (!(sym->flags & SYMBOL_CHECKED) && sym_check_deps(sym))
- printf("\n");
- else
- sym->flags |= SYMBOL_CHECK_DONE;
+ sym_check_deps(sym);
}
sym_change_count = 1;
@@ -1951,20 +1975,25 @@ const char *zconf_tokenname(int token)
case T_ENDCHOICE: return "endchoice";
case T_IF: return "if";
case T_ENDIF: return "endif";
+ case T_DEPENDS: return "depends";
}
return "<token>";
}
-static bool zconf_endtoken(int token, int starttoken, int endtoken)
+static bool zconf_endtoken(struct kconf_id *id, int starttoken, int endtoken)
{
- if (token != endtoken) {
- zconfprint("unexpected '%s' within %s block", zconf_tokenname(token), zconf_tokenname(starttoken));
+ if (id->token != endtoken) {
+ zconf_error("unexpected '%s' within %s block",
+ kconf_id_strings + id->name, zconf_tokenname(starttoken));
zconfnerrs++;
return false;
}
if (current_menu->file != current_file) {
- zconfprint("'%s' in different file than '%s'", zconf_tokenname(token), zconf_tokenname(starttoken));
- zconfprint("location of the '%s'", zconf_tokenname(starttoken));
+ zconf_error("'%s' in different file than '%s'",
+ kconf_id_strings + id->name, zconf_tokenname(starttoken));
+ fprintf(stderr, "%s:%d: location of the '%s'\n",
+ current_menu->file->name, current_menu->lineno,
+ zconf_tokenname(starttoken));
zconfnerrs++;
return false;
}
@@ -1975,7 +2004,19 @@ static void zconfprint(const char *err, ...)
{
va_list ap;
- fprintf(stderr, "%s:%d: ", zconf_curname(), zconf_lineno() + 1);
+ fprintf(stderr, "%s:%d: ", zconf_curname(), zconf_lineno());
+ va_start(ap, err);
+ vfprintf(stderr, err, ap);
+ va_end(ap);
+ fprintf(stderr, "\n");
+}
+
+static void zconf_error(const char *err, ...)
+{
+ va_list ap;
+
+ zconfnerrs++;
+ fprintf(stderr, "%s:%d: ", zconf_curname(), zconf_lineno());
va_start(ap, err);
vfprintf(stderr, err, ap);
va_end(ap);
@@ -1984,7 +2025,9 @@ static void zconfprint(const char *err, ...)
static void zconferror(const char *err)
{
+#if YYDEBUG
fprintf(stderr, "%s:%d: %s\n", zconf_curname(), zconf_lineno() + 1, err);
+#endif
}
void print_quoted_string(FILE *out, const char *str)
diff --git a/scripts/kconfig/zconf.tab.h_shipped b/scripts/kconfig/zconf.tab.h_shipped
deleted file mode 100644
index 3b191ef59985..000000000000
--- a/scripts/kconfig/zconf.tab.h_shipped
+++ /dev/null
@@ -1,125 +0,0 @@
-/* A Bison parser, made from zconf.y, by GNU bison 1.75. */
-
-/* Skeleton parser for Yacc-like parsing with Bison,
- Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA. */
-
-/* As a special exception, when this file is copied by Bison into a
- Bison output file, you may use that output file without restriction.
- This special exception was added by the Free Software Foundation
- in version 1.24 of Bison. */
-
-#ifndef BISON_ZCONF_TAB_H
-# define BISON_ZCONF_TAB_H
-
-/* Tokens. */
-#ifndef YYTOKENTYPE
-# define YYTOKENTYPE
- /* Put the tokens into the symbol table, so that GDB and other debuggers
- know about them. */
- enum yytokentype {
- T_MAINMENU = 258,
- T_MENU = 259,
- T_ENDMENU = 260,
- T_SOURCE = 261,
- T_CHOICE = 262,
- T_ENDCHOICE = 263,
- T_COMMENT = 264,
- T_CONFIG = 265,
- T_HELP = 266,
- T_HELPTEXT = 267,
- T_IF = 268,
- T_ENDIF = 269,
- T_DEPENDS = 270,
- T_REQUIRES = 271,
- T_OPTIONAL = 272,
- T_PROMPT = 273,
- T_DEFAULT = 274,
- T_TRISTATE = 275,
- T_BOOLEAN = 276,
- T_INT = 277,
- T_HEX = 278,
- T_WORD = 279,
- T_STRING = 280,
- T_UNEQUAL = 281,
- T_EOF = 282,
- T_EOL = 283,
- T_CLOSE_PAREN = 284,
- T_OPEN_PAREN = 285,
- T_ON = 286,
- T_OR = 287,
- T_AND = 288,
- T_EQUAL = 289,
- T_NOT = 290
- };
-#endif
-#define T_MAINMENU 258
-#define T_MENU 259
-#define T_ENDMENU 260
-#define T_SOURCE 261
-#define T_CHOICE 262
-#define T_ENDCHOICE 263
-#define T_COMMENT 264
-#define T_CONFIG 265
-#define T_HELP 266
-#define T_HELPTEXT 267
-#define T_IF 268
-#define T_ENDIF 269
-#define T_DEPENDS 270
-#define T_REQUIRES 271
-#define T_OPTIONAL 272
-#define T_PROMPT 273
-#define T_DEFAULT 274
-#define T_TRISTATE 275
-#define T_BOOLEAN 276
-#define T_INT 277
-#define T_HEX 278
-#define T_WORD 279
-#define T_STRING 280
-#define T_UNEQUAL 281
-#define T_EOF 282
-#define T_EOL 283
-#define T_CLOSE_PAREN 284
-#define T_OPEN_PAREN 285
-#define T_ON 286
-#define T_OR 287
-#define T_AND 288
-#define T_EQUAL 289
-#define T_NOT 290
-
-
-
-
-#ifndef YYSTYPE
-#line 33 "zconf.y"
-typedef union {
- int token;
- char *string;
- struct symbol *symbol;
- struct expr *expr;
- struct menu *menu;
-} yystype;
-/* Line 1281 of /usr/share/bison/yacc.c. */
-#line 118 "zconf.tab.h"
-# define YYSTYPE yystype
-#endif
-
-extern YYSTYPE zconflval;
-
-
-#endif /* not BISON_ZCONF_TAB_H */
-
diff --git a/scripts/kconfig/zconf.y b/scripts/kconfig/zconf.y
index e1a0f455d4a8..1f61fba6aa28 100644
--- a/scripts/kconfig/zconf.y
+++ b/scripts/kconfig/zconf.y
@@ -11,6 +11,11 @@
#include <string.h>
#include <stdbool.h>
+#define LKC_DIRECT_LINK
+#include "lkc.h"
+
+#include "zconf.hash.c"
+
#define printd(mask, fmt...) if (cdebug & (mask)) printf(fmt)
#define PRINTD 0x0001
@@ -20,61 +25,59 @@ int cdebug = PRINTD;
extern int zconflex(void);
static void zconfprint(const char *err, ...);
+static void zconf_error(const char *err, ...);
static void zconferror(const char *err);
-static bool zconf_endtoken(int token, int starttoken, int endtoken);
+static bool zconf_endtoken(struct kconf_id *id, int starttoken, int endtoken);
struct symbol *symbol_hash[257];
static struct menu *current_menu, *current_entry;
+#define YYDEBUG 0
+#if YYDEBUG
#define YYERROR_VERBOSE
+#endif
%}
-%expect 40
+%expect 26
%union
{
- int token;
char *string;
+ struct file *file;
struct symbol *symbol;
struct expr *expr;
struct menu *menu;
+ struct kconf_id *id;
}
-%token T_MAINMENU
-%token T_MENU
-%token T_ENDMENU
-%token T_SOURCE
-%token T_CHOICE
-%token T_ENDCHOICE
-%token T_COMMENT
-%token T_CONFIG
-%token T_MENUCONFIG
-%token T_HELP
+%token <id>T_MAINMENU
+%token <id>T_MENU
+%token <id>T_ENDMENU
+%token <id>T_SOURCE
+%token <id>T_CHOICE
+%token <id>T_ENDCHOICE
+%token <id>T_COMMENT
+%token <id>T_CONFIG
+%token <id>T_MENUCONFIG
+%token <id>T_HELP
%token <string> T_HELPTEXT
-%token T_IF
-%token T_ENDIF
-%token T_DEPENDS
-%token T_REQUIRES
-%token T_OPTIONAL
-%token T_PROMPT
-%token T_DEFAULT
-%token T_TRISTATE
-%token T_DEF_TRISTATE
-%token T_BOOLEAN
-%token T_DEF_BOOLEAN
-%token T_STRING
-%token T_INT
-%token T_HEX
+%token <id>T_IF
+%token <id>T_ENDIF
+%token <id>T_DEPENDS
+%token <id>T_REQUIRES
+%token <id>T_OPTIONAL
+%token <id>T_PROMPT
+%token <id>T_TYPE
+%token <id>T_DEFAULT
+%token <id>T_SELECT
+%token <id>T_RANGE
+%token <id>T_ON
%token <string> T_WORD
%token <string> T_WORD_QUOTE
%token T_UNEQUAL
-%token T_EOF
-%token T_EOL
%token T_CLOSE_PAREN
%token T_OPEN_PAREN
-%token T_ON
-%token T_SELECT
-%token T_RANGE
+%token T_EOL
%left T_OR
%left T_AND
@@ -82,38 +85,54 @@ static struct menu *current_menu, *current_entry;
%nonassoc T_NOT
%type <string> prompt
-%type <string> source
%type <symbol> symbol
%type <expr> expr
%type <expr> if_expr
-%type <token> end
+%type <id> end
+%type <id> option_name
+%type <menu> if_entry menu_entry choice_entry
+
+%destructor {
+ fprintf(stderr, "%s:%d: missing end statement for this entry\n",
+ $$->file->name, $$->lineno);
+ if (current_menu == $$)
+ menu_end_menu();
+} if_entry menu_entry choice_entry
-%{
-#define LKC_DIRECT_LINK
-#include "lkc.h"
-%}
%%
-input: /* empty */
- | input block
+input: stmt_list;
+
+stmt_list:
+ /* empty */
+ | stmt_list common_stmt
+ | stmt_list choice_stmt
+ | stmt_list menu_stmt
+ | stmt_list T_MAINMENU prompt nl
+ | stmt_list end { zconf_error("unexpected end statement"); }
+ | stmt_list T_WORD error T_EOL { zconf_error("unknown statement \"%s\"", $2); }
+ | stmt_list option_name error T_EOL
+{
+ zconf_error("unexpected option \"%s\"", kconf_id_strings + $2->name);
+}
+ | stmt_list error T_EOL { zconf_error("invalid statement"); }
;
-block: common_block
- | choice_stmt
- | menu_stmt
- | T_MAINMENU prompt nl_or_eof
- | T_ENDMENU { zconfprint("unexpected 'endmenu' statement"); }
- | T_ENDIF { zconfprint("unexpected 'endif' statement"); }
- | T_ENDCHOICE { zconfprint("unexpected 'endchoice' statement"); }
- | error nl_or_eof { zconfprint("syntax error"); yyerrok; }
+option_name:
+ T_DEPENDS | T_PROMPT | T_TYPE | T_SELECT | T_OPTIONAL | T_RANGE | T_DEFAULT
;
-common_block:
- if_stmt
+common_stmt:
+ T_EOL
+ | if_stmt
| comment_stmt
| config_stmt
| menuconfig_stmt
| source_stmt
- | nl_or_eof
+;
+
+option_error:
+ T_WORD error T_EOL { zconf_error("unknown option \"%s\"", $1); }
+ | error T_EOL { zconf_error("invalid option"); }
;
@@ -156,51 +175,16 @@ config_option_list:
| config_option_list config_option
| config_option_list depends
| config_option_list help
+ | config_option_list option_error
| config_option_list T_EOL
;
-config_option: T_TRISTATE prompt_stmt_opt T_EOL
+config_option: T_TYPE prompt_stmt_opt T_EOL
{
- menu_set_type(S_TRISTATE);
- printd(DEBUG_PARSE, "%s:%d:tristate\n", zconf_curname(), zconf_lineno());
-};
-
-config_option: T_DEF_TRISTATE expr if_expr T_EOL
-{
- menu_add_expr(P_DEFAULT, $2, $3);
- menu_set_type(S_TRISTATE);
- printd(DEBUG_PARSE, "%s:%d:def_boolean\n", zconf_curname(), zconf_lineno());
-};
-
-config_option: T_BOOLEAN prompt_stmt_opt T_EOL
-{
- menu_set_type(S_BOOLEAN);
- printd(DEBUG_PARSE, "%s:%d:boolean\n", zconf_curname(), zconf_lineno());
-};
-
-config_option: T_DEF_BOOLEAN expr if_expr T_EOL
-{
- menu_add_expr(P_DEFAULT, $2, $3);
- menu_set_type(S_BOOLEAN);
- printd(DEBUG_PARSE, "%s:%d:def_boolean\n", zconf_curname(), zconf_lineno());
-};
-
-config_option: T_INT prompt_stmt_opt T_EOL
-{
- menu_set_type(S_INT);
- printd(DEBUG_PARSE, "%s:%d:int\n", zconf_curname(), zconf_lineno());
-};
-
-config_option: T_HEX prompt_stmt_opt T_EOL
-{
- menu_set_type(S_HEX);
- printd(DEBUG_PARSE, "%s:%d:hex\n", zconf_curname(), zconf_lineno());
-};
-
-config_option: T_STRING prompt_stmt_opt T_EOL
-{
- menu_set_type(S_STRING);
- printd(DEBUG_PARSE, "%s:%d:string\n", zconf_curname(), zconf_lineno());
+ menu_set_type($1->stype);
+ printd(DEBUG_PARSE, "%s:%d:type(%u)\n",
+ zconf_curname(), zconf_lineno(),
+ $1->stype);
};
config_option: T_PROMPT prompt if_expr T_EOL
@@ -212,7 +196,11 @@ config_option: T_PROMPT prompt if_expr T_EOL
config_option: T_DEFAULT expr if_expr T_EOL
{
menu_add_expr(P_DEFAULT, $2, $3);
- printd(DEBUG_PARSE, "%s:%d:default\n", zconf_curname(), zconf_lineno());
+ if ($1->stype != S_UNKNOWN)
+ menu_set_type($1->stype);
+ printd(DEBUG_PARSE, "%s:%d:default(%u)\n",
+ zconf_curname(), zconf_lineno(),
+ $1->stype);
};
config_option: T_SELECT T_WORD if_expr T_EOL
@@ -240,8 +228,7 @@ choice: T_CHOICE T_EOL
choice_entry: choice choice_option_list
{
- menu_end_entry();
- menu_add_menu();
+ $$ = menu_add_menu();
};
choice_end: end
@@ -252,13 +239,8 @@ choice_end: end
}
};
-choice_stmt:
- choice_entry choice_block choice_end
- | choice_entry choice_block
-{
- printf("%s:%d: missing 'endchoice' for this 'choice' statement\n", current_menu->file->name, current_menu->lineno);
- zconfnerrs++;
-};
+choice_stmt: choice_entry choice_block choice_end
+;
choice_option_list:
/* empty */
@@ -266,6 +248,7 @@ choice_option_list:
| choice_option_list depends
| choice_option_list help
| choice_option_list T_EOL
+ | choice_option_list option_error
;
choice_option: T_PROMPT prompt if_expr T_EOL
@@ -274,16 +257,15 @@ choice_option: T_PROMPT prompt if_expr T_EOL
printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno());
};
-choice_option: T_TRISTATE prompt_stmt_opt T_EOL
-{
- menu_set_type(S_TRISTATE);
- printd(DEBUG_PARSE, "%s:%d:tristate\n", zconf_curname(), zconf_lineno());
-};
-
-choice_option: T_BOOLEAN prompt_stmt_opt T_EOL
+choice_option: T_TYPE prompt_stmt_opt T_EOL
{
- menu_set_type(S_BOOLEAN);
- printd(DEBUG_PARSE, "%s:%d:boolean\n", zconf_curname(), zconf_lineno());
+ if ($1->stype == S_BOOLEAN || $1->stype == S_TRISTATE) {
+ menu_set_type($1->stype);
+ printd(DEBUG_PARSE, "%s:%d:type(%u)\n",
+ zconf_curname(), zconf_lineno(),
+ $1->stype);
+ } else
+ YYERROR;
};
choice_option: T_OPTIONAL T_EOL
@@ -294,24 +276,27 @@ choice_option: T_OPTIONAL T_EOL
choice_option: T_DEFAULT T_WORD if_expr T_EOL
{
- menu_add_symbol(P_DEFAULT, sym_lookup($2, 0), $3);
- printd(DEBUG_PARSE, "%s:%d:default\n", zconf_curname(), zconf_lineno());
+ if ($1->stype == S_UNKNOWN) {
+ menu_add_symbol(P_DEFAULT, sym_lookup($2, 0), $3);
+ printd(DEBUG_PARSE, "%s:%d:default\n",
+ zconf_curname(), zconf_lineno());
+ } else
+ YYERROR;
};
choice_block:
/* empty */
- | choice_block common_block
+ | choice_block common_stmt
;
/* if entry */
-if: T_IF expr T_EOL
+if_entry: T_IF expr nl
{
printd(DEBUG_PARSE, "%s:%d:if\n", zconf_curname(), zconf_lineno());
menu_add_entry(NULL);
menu_add_dep($2);
- menu_end_entry();
- menu_add_menu();
+ $$ = menu_add_menu();
};
if_end: end
@@ -322,17 +307,12 @@ if_end: end
}
};
-if_stmt:
- if if_block if_end
- | if if_block
-{
- printf("%s:%d: missing 'endif' for this 'if' statement\n", current_menu->file->name, current_menu->lineno);
- zconfnerrs++;
-};
+if_stmt: if_entry if_block if_end
+;
if_block:
/* empty */
- | if_block common_block
+ | if_block common_stmt
| if_block menu_stmt
| if_block choice_stmt
;
@@ -348,8 +328,7 @@ menu: T_MENU prompt T_EOL
menu_entry: menu depends_list
{
- menu_end_entry();
- menu_add_menu();
+ $$ = menu_add_menu();
};
menu_end: end
@@ -360,31 +339,20 @@ menu_end: end
}
};
-menu_stmt:
- menu_entry menu_block menu_end
- | menu_entry menu_block
-{
- printf("%s:%d: missing 'endmenu' for this 'menu' statement\n", current_menu->file->name, current_menu->lineno);
- zconfnerrs++;
-};
+menu_stmt: menu_entry menu_block menu_end
+;
menu_block:
/* empty */
- | menu_block common_block
+ | menu_block common_stmt
| menu_block menu_stmt
| menu_block choice_stmt
- | menu_block error T_EOL { zconfprint("invalid menu option"); yyerrok; }
;
-source: T_SOURCE prompt T_EOL
+source_stmt: T_SOURCE prompt T_EOL
{
- $$ = $2;
printd(DEBUG_PARSE, "%s:%d:source %s\n", zconf_curname(), zconf_lineno(), $2);
-};
-
-source_stmt: source
-{
- zconf_nextfile($1);
+ zconf_nextfile($2);
};
/* comment entry */
@@ -416,9 +384,11 @@ help: help_start T_HELPTEXT
/* depends option */
-depends_list: /* empty */
- | depends_list depends
- | depends_list T_EOL
+depends_list:
+ /* empty */
+ | depends_list depends
+ | depends_list T_EOL
+ | depends_list option_error
;
depends: T_DEPENDS T_ON expr T_EOL
@@ -450,13 +420,15 @@ prompt: T_WORD
| T_WORD_QUOTE
;
-end: T_ENDMENU nl_or_eof { $$ = T_ENDMENU; }
- | T_ENDCHOICE nl_or_eof { $$ = T_ENDCHOICE; }
- | T_ENDIF nl_or_eof { $$ = T_ENDIF; }
+end: T_ENDMENU T_EOL { $$ = $1; }
+ | T_ENDCHOICE T_EOL { $$ = $1; }
+ | T_ENDIF T_EOL { $$ = $1; }
;
-nl_or_eof:
- T_EOL | T_EOF;
+nl:
+ T_EOL
+ | nl T_EOL
+;
if_expr: /* empty */ { $$ = NULL; }
| T_IF expr { $$ = $2; }
@@ -489,16 +461,16 @@ void conf_parse(const char *name)
modules_sym = sym_lookup("MODULES", 0);
rootmenu.prompt = menu_add_prompt(P_MENU, "Linux Kernel Configuration", NULL);
- //zconfdebug = 1;
+#if YYDEBUG
+ if (getenv("ZCONF_DEBUG"))
+ zconfdebug = 1;
+#endif
zconfparse();
if (zconfnerrs)
exit(1);
menu_finalize(&rootmenu);
for_all_symbols(i, sym) {
- if (!(sym->flags & SYMBOL_CHECKED) && sym_check_deps(sym))
- printf("\n");
- else
- sym->flags |= SYMBOL_CHECK_DONE;
+ sym_check_deps(sym);
}
sym_change_count = 1;
@@ -513,20 +485,25 @@ const char *zconf_tokenname(int token)
case T_ENDCHOICE: return "endchoice";
case T_IF: return "if";
case T_ENDIF: return "endif";
+ case T_DEPENDS: return "depends";
}
return "<token>";
}
-static bool zconf_endtoken(int token, int starttoken, int endtoken)
+static bool zconf_endtoken(struct kconf_id *id, int starttoken, int endtoken)
{
- if (token != endtoken) {
- zconfprint("unexpected '%s' within %s block", zconf_tokenname(token), zconf_tokenname(starttoken));
+ if (id->token != endtoken) {
+ zconf_error("unexpected '%s' within %s block",
+ kconf_id_strings + id->name, zconf_tokenname(starttoken));
zconfnerrs++;
return false;
}
if (current_menu->file != current_file) {
- zconfprint("'%s' in different file than '%s'", zconf_tokenname(token), zconf_tokenname(starttoken));
- zconfprint("location of the '%s'", zconf_tokenname(starttoken));
+ zconf_error("'%s' in different file than '%s'",
+ kconf_id_strings + id->name, zconf_tokenname(starttoken));
+ fprintf(stderr, "%s:%d: location of the '%s'\n",
+ current_menu->file->name, current_menu->lineno,
+ zconf_tokenname(starttoken));
zconfnerrs++;
return false;
}
@@ -537,7 +514,19 @@ static void zconfprint(const char *err, ...)
{
va_list ap;
- fprintf(stderr, "%s:%d: ", zconf_curname(), zconf_lineno() + 1);
+ fprintf(stderr, "%s:%d: ", zconf_curname(), zconf_lineno());
+ va_start(ap, err);
+ vfprintf(stderr, err, ap);
+ va_end(ap);
+ fprintf(stderr, "\n");
+}
+
+static void zconf_error(const char *err, ...)
+{
+ va_list ap;
+
+ zconfnerrs++;
+ fprintf(stderr, "%s:%d: ", zconf_curname(), zconf_lineno());
va_start(ap, err);
vfprintf(stderr, err, ap);
va_end(ap);
@@ -546,7 +535,9 @@ static void zconfprint(const char *err, ...)
static void zconferror(const char *err)
{
+#if YYDEBUG
fprintf(stderr, "%s:%d: %s\n", zconf_curname(), zconf_lineno() + 1, err);
+#endif
}
void print_quoted_string(FILE *out, const char *str)
diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c
index f2ee673329a7..e3d144a3f10b 100644
--- a/scripts/mod/file2alias.c
+++ b/scripts/mod/file2alias.c
@@ -359,6 +359,13 @@ static int do_vio_entry(const char *filename, struct vio_device_id *vio,
return 1;
}
+static int do_i2c_entry(const char *filename, struct i2c_device_id *i2c, char *alias)
+{
+ strcpy(alias, "i2c:");
+ ADD(alias, "id", 1, i2c->id);
+ return 1;
+}
+
/* Ignore any prefix, eg. v850 prepends _ */
static inline int sym_is(const char *symbol, const char *name)
{
@@ -443,6 +450,9 @@ void handle_moddevtable(struct module *mod, struct elf_info *info,
else if (sym_is(symname, "__mod_vio_device_table"))
do_table(symval, sym->st_size, sizeof(struct vio_device_id),
do_vio_entry, mod);
+ else if (sym_is(symname, "__mod_i2c_device_table"))
+ do_table(symval, sym->st_size, sizeof(struct i2c_device_id),
+ do_i2c_entry, mod);
}
diff --git a/security/dummy.c b/security/dummy.c
index 9623a61dfc76..3ca5f2b828a0 100644
--- a/security/dummy.c
+++ b/security/dummy.c
@@ -377,7 +377,7 @@ static int dummy_inode_removexattr (struct dentry *dentry, char *name)
return 0;
}
-static int dummy_inode_getsecurity(struct inode *inode, const char *name, void *buffer, size_t size)
+static int dummy_inode_getsecurity(struct inode *inode, const char *name, void *buffer, size_t size, int err)
{
return -EOPNOTSUPP;
}
@@ -768,7 +768,7 @@ static int dummy_socket_getpeersec(struct socket *sock, char __user *optval,
return -ENOPROTOOPT;
}
-static inline int dummy_sk_alloc_security (struct sock *sk, int family, int priority)
+static inline int dummy_sk_alloc_security (struct sock *sk, int family, gfp_t priority)
{
return 0;
}
@@ -803,6 +803,23 @@ static int dummy_setprocattr(struct task_struct *p, char *name, void *value, siz
return -EINVAL;
}
+#ifdef CONFIG_KEYS
+static inline int dummy_key_alloc(struct key *key)
+{
+ return 0;
+}
+
+static inline void dummy_key_free(struct key *key)
+{
+}
+
+static inline int dummy_key_permission(key_ref_t key_ref,
+ struct task_struct *context,
+ key_perm_t perm)
+{
+ return 0;
+}
+#endif /* CONFIG_KEYS */
struct security_operations dummy_security_ops;
@@ -954,5 +971,11 @@ void security_fixup_ops (struct security_operations *ops)
set_to_dummy_if_null(ops, sk_alloc_security);
set_to_dummy_if_null(ops, sk_free_security);
#endif /* CONFIG_SECURITY_NETWORK */
+#ifdef CONFIG_KEYS
+ set_to_dummy_if_null(ops, key_alloc);
+ set_to_dummy_if_null(ops, key_free);
+ set_to_dummy_if_null(ops, key_permission);
+#endif /* CONFIG_KEYS */
+
}
diff --git a/security/keys/key.c b/security/keys/key.c
index 2182be9e9309..01bcfecb7eae 100644
--- a/security/keys/key.c
+++ b/security/keys/key.c
@@ -1,6 +1,6 @@
/* key.c: basic authentication token and access key management
*
- * Copyright (C) 2004-5 Red Hat, Inc. All Rights Reserved.
+ * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
*
* This program is free software; you can redistribute it and/or
@@ -13,6 +13,7 @@
#include <linux/init.h>
#include <linux/sched.h>
#include <linux/slab.h>
+#include <linux/security.h>
#include <linux/workqueue.h>
#include <linux/err.h>
#include "internal.h"
@@ -114,8 +115,7 @@ struct key_user *key_user_lookup(uid_t uid)
found:
atomic_inc(&user->usage);
spin_unlock(&key_user_lock);
- if (candidate)
- kfree(candidate);
+ kfree(candidate);
out:
return user;
@@ -253,6 +253,7 @@ struct key *key_alloc(struct key_type *type, const char *desc,
struct key_user *user = NULL;
struct key *key;
size_t desclen, quotalen;
+ int ret;
key = ERR_PTR(-EINVAL);
if (!desc || !*desc)
@@ -305,6 +306,7 @@ struct key *key_alloc(struct key_type *type, const char *desc,
key->flags = 0;
key->expiry = 0;
key->payload.data = NULL;
+ key->security = NULL;
if (!not_in_quota)
key->flags |= 1 << KEY_FLAG_IN_QUOTA;
@@ -315,16 +317,34 @@ struct key *key_alloc(struct key_type *type, const char *desc,
key->magic = KEY_DEBUG_MAGIC;
#endif
+ /* let the security module know about the key */
+ ret = security_key_alloc(key);
+ if (ret < 0)
+ goto security_error;
+
/* publish the key by giving it a serial number */
atomic_inc(&user->nkeys);
key_alloc_serial(key);
- error:
+error:
return key;
- no_memory_3:
+security_error:
+ kfree(key->description);
+ kmem_cache_free(key_jar, key);
+ if (!not_in_quota) {
+ spin_lock(&user->lock);
+ user->qnkeys--;
+ user->qnbytes -= quotalen;
+ spin_unlock(&user->lock);
+ }
+ key_user_put(user);
+ key = ERR_PTR(ret);
+ goto error;
+
+no_memory_3:
kmem_cache_free(key_jar, key);
- no_memory_2:
+no_memory_2:
if (!not_in_quota) {
spin_lock(&user->lock);
user->qnkeys--;
@@ -332,11 +352,11 @@ struct key *key_alloc(struct key_type *type, const char *desc,
spin_unlock(&user->lock);
}
key_user_put(user);
- no_memory_1:
+no_memory_1:
key = ERR_PTR(-ENOMEM);
goto error;
- no_quota:
+no_quota:
spin_unlock(&user->lock);
key_user_put(user);
key = ERR_PTR(-EDQUOT);
@@ -556,6 +576,8 @@ static void key_cleanup(void *data)
key_check(key);
+ security_key_free(key);
+
/* deal with the user's key tracking and quota */
if (test_bit(KEY_FLAG_IN_QUOTA, &key->flags)) {
spin_lock(&key->user->lock);
@@ -700,8 +722,8 @@ static inline key_ref_t __key_update(key_ref_t key_ref,
int ret;
/* need write permission on the key to update it */
- ret = -EACCES;
- if (!key_permission(key_ref, KEY_WRITE))
+ ret = key_permission(key_ref, KEY_WRITE);
+ if (ret < 0)
goto error;
ret = -EEXIST;
@@ -711,7 +733,6 @@ static inline key_ref_t __key_update(key_ref_t key_ref,
down_write(&key->sem);
ret = key->type->update(key, payload, plen);
-
if (ret == 0)
/* updating a negative key instantiates it */
clear_bit(KEY_FLAG_NEGATIVE, &key->flags);
@@ -768,9 +789,11 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
/* if we're going to allocate a new key, we're going to have
* to modify the keyring */
- key_ref = ERR_PTR(-EACCES);
- if (!key_permission(keyring_ref, KEY_WRITE))
+ ret = key_permission(keyring_ref, KEY_WRITE);
+ if (ret < 0) {
+ key_ref = ERR_PTR(ret);
goto error_3;
+ }
/* search for an existing key of the same type and description in the
* destination keyring
@@ -780,8 +803,8 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
goto found_matching_key;
/* decide on the permissions we want */
- perm = KEY_POS_VIEW | KEY_POS_SEARCH | KEY_POS_LINK;
- perm |= KEY_USR_VIEW | KEY_USR_SEARCH | KEY_USR_LINK;
+ perm = KEY_POS_VIEW | KEY_POS_SEARCH | KEY_POS_LINK | KEY_POS_SETATTR;
+ perm |= KEY_USR_VIEW | KEY_USR_SEARCH | KEY_USR_LINK | KEY_USR_SETATTR;
if (ktype->read)
perm |= KEY_POS_READ | KEY_USR_READ;
@@ -840,16 +863,16 @@ int key_update(key_ref_t key_ref, const void *payload, size_t plen)
key_check(key);
/* the key must be writable */
- ret = -EACCES;
- if (!key_permission(key_ref, KEY_WRITE))
+ ret = key_permission(key_ref, KEY_WRITE);
+ if (ret < 0)
goto error;
/* attempt to update it if supported */
ret = -EOPNOTSUPP;
if (key->type->update) {
down_write(&key->sem);
- ret = key->type->update(key, payload, plen);
+ ret = key->type->update(key, payload, plen);
if (ret == 0)
/* updating a negative key instantiates it */
clear_bit(KEY_FLAG_NEGATIVE, &key->flags);
diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c
index 4c670ee6acf9..b7a468fabdf9 100644
--- a/security/keys/keyctl.c
+++ b/security/keys/keyctl.c
@@ -624,8 +624,8 @@ long keyctl_keyring_search(key_serial_t ringid,
/* link the resulting key to the destination keyring if we can */
if (dest_ref) {
- ret = -EACCES;
- if (!key_permission(key_ref, KEY_LINK))
+ ret = key_permission(key_ref, KEY_LINK);
+ if (ret < 0)
goto error6;
ret = key_link(key_ref_to_ptr(dest_ref), key_ref_to_ptr(key_ref));
@@ -676,8 +676,11 @@ long keyctl_read_key(key_serial_t keyid, char __user *buffer, size_t buflen)
key = key_ref_to_ptr(key_ref);
/* see if we can read it directly */
- if (key_permission(key_ref, KEY_READ))
+ ret = key_permission(key_ref, KEY_READ);
+ if (ret == 0)
goto can_read_key;
+ if (ret != -EACCES)
+ goto error;
/* we can't; see if it's searchable from this process's keyrings
* - we automatically take account of the fact that it may be
@@ -726,7 +729,7 @@ long keyctl_chown_key(key_serial_t id, uid_t uid, gid_t gid)
if (uid == (uid_t) -1 && gid == (gid_t) -1)
goto error;
- key_ref = lookup_user_key(NULL, id, 1, 1, 0);
+ key_ref = lookup_user_key(NULL, id, 1, 1, KEY_SETATTR);
if (IS_ERR(key_ref)) {
ret = PTR_ERR(key_ref);
goto error;
@@ -786,7 +789,7 @@ long keyctl_setperm_key(key_serial_t id, key_perm_t perm)
if (perm & ~(KEY_POS_ALL | KEY_USR_ALL | KEY_GRP_ALL | KEY_OTH_ALL))
goto error;
- key_ref = lookup_user_key(NULL, id, 1, 1, 0);
+ key_ref = lookup_user_key(NULL, id, 1, 1, KEY_SETATTR);
if (IS_ERR(key_ref)) {
ret = PTR_ERR(key_ref);
goto error;
diff --git a/security/keys/keyring.c b/security/keys/keyring.c
index 0639396dd441..c7a0ab1cfda3 100644
--- a/security/keys/keyring.c
+++ b/security/keys/keyring.c
@@ -13,6 +13,7 @@
#include <linux/init.h>
#include <linux/sched.h>
#include <linux/slab.h>
+#include <linux/security.h>
#include <linux/seq_file.h>
#include <linux/err.h>
#include <asm/uaccess.h>
@@ -309,7 +310,9 @@ struct key *keyring_alloc(const char *description, uid_t uid, gid_t gid,
int ret;
keyring = key_alloc(&key_type_keyring, description,
- uid, gid, KEY_POS_ALL | KEY_USR_ALL, not_in_quota);
+ uid, gid,
+ (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_ALL,
+ not_in_quota);
if (!IS_ERR(keyring)) {
ret = key_instantiate_and_link(keyring, NULL, 0, dest, NULL);
@@ -359,9 +362,11 @@ key_ref_t keyring_search_aux(key_ref_t keyring_ref,
key_check(keyring);
/* top keyring must have search permission to begin the search */
- key_ref = ERR_PTR(-EACCES);
- if (!key_task_permission(keyring_ref, context, KEY_SEARCH))
+ err = key_task_permission(keyring_ref, context, KEY_SEARCH);
+ if (err < 0) {
+ key_ref = ERR_PTR(err);
goto error;
+ }
key_ref = ERR_PTR(-ENOTDIR);
if (keyring->type != &key_type_keyring)
@@ -402,8 +407,8 @@ descend:
continue;
/* key must have search permissions */
- if (!key_task_permission(make_key_ref(key, possessed),
- context, KEY_SEARCH))
+ if (key_task_permission(make_key_ref(key, possessed),
+ context, KEY_SEARCH) < 0)
continue;
/* we set a different error code if we find a negative key */
@@ -429,8 +434,8 @@ ascend:
if (sp >= KEYRING_SEARCH_MAX_DEPTH)
continue;
- if (!key_task_permission(make_key_ref(key, possessed),
- context, KEY_SEARCH))
+ if (key_task_permission(make_key_ref(key, possessed),
+ context, KEY_SEARCH) < 0)
continue;
/* stack the current position */
@@ -521,7 +526,7 @@ key_ref_t __keyring_search_one(key_ref_t keyring_ref,
(!key->type->match ||
key->type->match(key, description)) &&
key_permission(make_key_ref(key, possessed),
- perm) &&
+ perm) < 0 &&
!test_bit(KEY_FLAG_REVOKED, &key->flags)
)
goto found;
@@ -616,8 +621,8 @@ struct key *find_keyring_by_name(const char *name, key_serial_t bound)
if (strcmp(keyring->description, name) != 0)
continue;
- if (!key_permission(make_key_ref(keyring, 0),
- KEY_SEARCH))
+ if (key_permission(make_key_ref(keyring, 0),
+ KEY_SEARCH) < 0)
continue;
/* found a potential candidate, but we still need to
diff --git a/security/keys/permission.c b/security/keys/permission.c
index 03db073ba45c..e7f579c0eaf5 100644
--- a/security/keys/permission.c
+++ b/security/keys/permission.c
@@ -10,6 +10,7 @@
*/
#include <linux/module.h>
+#include <linux/security.h>
#include "internal.h"
/*****************************************************************************/
@@ -63,7 +64,11 @@ use_these_perms:
kperm = kperm & perm & KEY_ALL;
- return kperm == perm;
+ if (kperm != perm)
+ return -EACCES;
+
+ /* let LSM be the final arbiter */
+ return security_key_permission(key_ref, context, perm);
} /* end key_task_permission() */
diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c
index d42d2158ce13..566b1cc0118a 100644
--- a/security/keys/process_keys.c
+++ b/security/keys/process_keys.c
@@ -39,7 +39,7 @@ struct key root_user_keyring = {
.type = &key_type_keyring,
.user = &root_key_user,
.sem = __RWSEM_INITIALIZER(root_user_keyring.sem),
- .perm = KEY_POS_ALL | KEY_USR_ALL,
+ .perm = (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_ALL,
.flags = 1 << KEY_FLAG_INSTANTIATED,
.description = "_uid.0",
#ifdef KEY_DEBUGGING
@@ -54,7 +54,7 @@ struct key root_session_keyring = {
.type = &key_type_keyring,
.user = &root_key_user,
.sem = __RWSEM_INITIALIZER(root_session_keyring.sem),
- .perm = KEY_POS_ALL | KEY_USR_ALL,
+ .perm = (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_ALL,
.flags = 1 << KEY_FLAG_INSTANTIATED,
.description = "_uid_ses.0",
#ifdef KEY_DEBUGGING
@@ -666,9 +666,8 @@ key_ref_t lookup_user_key(struct task_struct *context, key_serial_t id,
goto invalid_key;
/* check the permissions */
- ret = -EACCES;
-
- if (!key_task_permission(key_ref, context, perm))
+ ret = key_task_permission(key_ref, context, perm);
+ if (ret < 0)
goto invalid_key;
error:
diff --git a/security/keys/user_defined.c b/security/keys/user_defined.c
index e446acba73d3..cbda3b2780a1 100644
--- a/security/keys/user_defined.c
+++ b/security/keys/user_defined.c
@@ -15,18 +15,10 @@
#include <linux/slab.h>
#include <linux/seq_file.h>
#include <linux/err.h>
+#include <keys/user-type.h>
#include <asm/uaccess.h>
#include "internal.h"
-static int user_instantiate(struct key *key, const void *data, size_t datalen);
-static int user_duplicate(struct key *key, const struct key *source);
-static int user_update(struct key *key, const void *data, size_t datalen);
-static int user_match(const struct key *key, const void *criterion);
-static void user_destroy(struct key *key);
-static void user_describe(const struct key *user, struct seq_file *m);
-static long user_read(const struct key *key,
- char __user *buffer, size_t buflen);
-
/*
* user defined keys take an arbitrary string as the description and an
* arbitrary blob of data as the payload
@@ -42,19 +34,13 @@ struct key_type key_type_user = {
.read = user_read,
};
-struct user_key_payload {
- struct rcu_head rcu; /* RCU destructor */
- unsigned short datalen; /* length of this data */
- char data[0]; /* actual data */
-};
-
EXPORT_SYMBOL_GPL(key_type_user);
/*****************************************************************************/
/*
* instantiate a user defined key
*/
-static int user_instantiate(struct key *key, const void *data, size_t datalen)
+int user_instantiate(struct key *key, const void *data, size_t datalen)
{
struct user_key_payload *upayload;
int ret;
@@ -78,18 +64,20 @@ static int user_instantiate(struct key *key, const void *data, size_t datalen)
rcu_assign_pointer(key->payload.data, upayload);
ret = 0;
- error:
+error:
return ret;
} /* end user_instantiate() */
+EXPORT_SYMBOL_GPL(user_instantiate);
+
/*****************************************************************************/
/*
* duplicate a user defined key
* - both keys' semaphores are locked against further modification
* - the new key cannot yet be accessed
*/
-static int user_duplicate(struct key *key, const struct key *source)
+int user_duplicate(struct key *key, const struct key *source)
{
struct user_key_payload *upayload, *spayload;
int ret;
@@ -112,6 +100,8 @@ static int user_duplicate(struct key *key, const struct key *source)
} /* end user_duplicate() */
+EXPORT_SYMBOL_GPL(user_duplicate);
+
/*****************************************************************************/
/*
* dispose of the old data from an updated user defined key
@@ -131,7 +121,7 @@ static void user_update_rcu_disposal(struct rcu_head *rcu)
* update a user defined key
* - the key's semaphore is write-locked
*/
-static int user_update(struct key *key, const void *data, size_t datalen)
+int user_update(struct key *key, const void *data, size_t datalen)
{
struct user_key_payload *upayload, *zap;
int ret;
@@ -163,26 +153,30 @@ static int user_update(struct key *key, const void *data, size_t datalen)
call_rcu(&zap->rcu, user_update_rcu_disposal);
- error:
+error:
return ret;
} /* end user_update() */
+EXPORT_SYMBOL_GPL(user_update);
+
/*****************************************************************************/
/*
* match users on their name
*/
-static int user_match(const struct key *key, const void *description)
+int user_match(const struct key *key, const void *description)
{
return strcmp(key->description, description) == 0;
} /* end user_match() */
+EXPORT_SYMBOL_GPL(user_match);
+
/*****************************************************************************/
/*
* dispose of the data dangling from the corpse of a user
*/
-static void user_destroy(struct key *key)
+void user_destroy(struct key *key)
{
struct user_key_payload *upayload = key->payload.data;
@@ -190,11 +184,13 @@ static void user_destroy(struct key *key)
} /* end user_destroy() */
+EXPORT_SYMBOL_GPL(user_destroy);
+
/*****************************************************************************/
/*
* describe the user key
*/
-static void user_describe(const struct key *key, struct seq_file *m)
+void user_describe(const struct key *key, struct seq_file *m)
{
seq_puts(m, key->description);
@@ -202,13 +198,14 @@ static void user_describe(const struct key *key, struct seq_file *m)
} /* end user_describe() */
+EXPORT_SYMBOL_GPL(user_describe);
+
/*****************************************************************************/
/*
* read the key data
* - the key's semaphore is read-locked
*/
-static long user_read(const struct key *key,
- char __user *buffer, size_t buflen)
+long user_read(const struct key *key, char __user *buffer, size_t buflen)
{
struct user_key_payload *upayload;
long ret;
@@ -228,3 +225,5 @@ static long user_read(const struct key *key,
return ret;
} /* end user_read() */
+
+EXPORT_SYMBOL_GPL(user_read);
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index b13be15165f5..fc774436a264 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -122,11 +122,10 @@ static int task_alloc_security(struct task_struct *task)
{
struct task_security_struct *tsec;
- tsec = kmalloc(sizeof(struct task_security_struct), GFP_KERNEL);
+ tsec = kzalloc(sizeof(struct task_security_struct), GFP_KERNEL);
if (!tsec)
return -ENOMEM;
- memset(tsec, 0, sizeof(struct task_security_struct));
tsec->magic = SELINUX_MAGIC;
tsec->task = task;
tsec->osid = tsec->sid = tsec->ptrace_sid = SECINITSID_UNLABELED;
@@ -151,11 +150,10 @@ static int inode_alloc_security(struct inode *inode)
struct task_security_struct *tsec = current->security;
struct inode_security_struct *isec;
- isec = kmalloc(sizeof(struct inode_security_struct), GFP_KERNEL);
+ isec = kzalloc(sizeof(struct inode_security_struct), GFP_KERNEL);
if (!isec)
return -ENOMEM;
- memset(isec, 0, sizeof(struct inode_security_struct));
init_MUTEX(&isec->sem);
INIT_LIST_HEAD(&isec->list);
isec->magic = SELINUX_MAGIC;
@@ -193,11 +191,10 @@ static int file_alloc_security(struct file *file)
struct task_security_struct *tsec = current->security;
struct file_security_struct *fsec;
- fsec = kmalloc(sizeof(struct file_security_struct), GFP_ATOMIC);
+ fsec = kzalloc(sizeof(struct file_security_struct), GFP_ATOMIC);
if (!fsec)
return -ENOMEM;
- memset(fsec, 0, sizeof(struct file_security_struct));
fsec->magic = SELINUX_MAGIC;
fsec->file = file;
if (tsec && tsec->magic == SELINUX_MAGIC) {
@@ -227,11 +224,10 @@ static int superblock_alloc_security(struct super_block *sb)
{
struct superblock_security_struct *sbsec;
- sbsec = kmalloc(sizeof(struct superblock_security_struct), GFP_KERNEL);
+ sbsec = kzalloc(sizeof(struct superblock_security_struct), GFP_KERNEL);
if (!sbsec)
return -ENOMEM;
- memset(sbsec, 0, sizeof(struct superblock_security_struct));
init_MUTEX(&sbsec->sem);
INIT_LIST_HEAD(&sbsec->list);
INIT_LIST_HEAD(&sbsec->isec_head);
@@ -262,18 +258,17 @@ static void superblock_free_security(struct super_block *sb)
}
#ifdef CONFIG_SECURITY_NETWORK
-static int sk_alloc_security(struct sock *sk, int family, int priority)
+static int sk_alloc_security(struct sock *sk, int family, gfp_t priority)
{
struct sk_security_struct *ssec;
if (family != PF_UNIX)
return 0;
- ssec = kmalloc(sizeof(*ssec), priority);
+ ssec = kzalloc(sizeof(*ssec), priority);
if (!ssec)
return -ENOMEM;
- memset(ssec, 0, sizeof(*ssec));
ssec->magic = SELINUX_MAGIC;
ssec->sk = sk;
ssec->peer_sid = SECINITSID_UNLABELED;
@@ -1483,11 +1478,10 @@ static int selinux_bprm_alloc_security(struct linux_binprm *bprm)
{
struct bprm_security_struct *bsec;
- bsec = kmalloc(sizeof(struct bprm_security_struct), GFP_KERNEL);
+ bsec = kzalloc(sizeof(struct bprm_security_struct), GFP_KERNEL);
if (!bsec)
return -ENOMEM;
- memset(bsec, 0, sizeof *bsec);
bsec->magic = SELINUX_MAGIC;
bsec->bprm = bprm;
bsec->sid = SECINITSID_UNLABELED;
@@ -1615,7 +1609,7 @@ static inline void flush_unauthorized_files(struct files_struct * files)
if (tty) {
file_list_lock();
- file = list_entry(tty->tty_files.next, typeof(*file), f_list);
+ file = list_entry(tty->tty_files.next, typeof(*file), f_u.fu_list);
if (file) {
/* Revalidate access to controlling tty.
Use inode_has_perm on the tty inode directly rather
@@ -1992,6 +1986,9 @@ static int selinux_inode_init_security(struct inode *inode, struct inode *dir,
inode_security_set_sid(inode, newsid);
+ if (sbsec->behavior == SECURITY_FS_USE_MNTPOINT)
+ return -EOPNOTSUPP;
+
if (name) {
namep = kstrdup(XATTR_SELINUX_SUFFIX, GFP_KERNEL);
if (!namep)
@@ -2211,12 +2208,6 @@ static void selinux_inode_post_setxattr(struct dentry *dentry, char *name,
static int selinux_inode_getxattr (struct dentry *dentry, char *name)
{
- struct inode *inode = dentry->d_inode;
- struct superblock_security_struct *sbsec = inode->i_sb->s_security;
-
- if (sbsec->behavior == SECURITY_FS_USE_MNTPOINT)
- return -EOPNOTSUPP;
-
return dentry_has_perm(current, NULL, dentry, FILE__GETATTR);
}
@@ -2247,33 +2238,54 @@ static int selinux_inode_removexattr (struct dentry *dentry, char *name)
return -EACCES;
}
-static int selinux_inode_getsecurity(struct inode *inode, const char *name, void *buffer, size_t size)
+/*
+ * Copy the in-core inode security context value to the user. If the
+ * getxattr() prior to this succeeded, check to see if we need to
+ * canonicalize the value to be finally returned to the user.
+ *
+ * Permission check is handled by selinux_inode_getxattr hook.
+ */
+static int selinux_inode_getsecurity(struct inode *inode, const char *name, void *buffer, size_t size, int err)
{
struct inode_security_struct *isec = inode->i_security;
char *context;
unsigned len;
int rc;
- /* Permission check handled by selinux_inode_getxattr hook.*/
-
- if (strcmp(name, XATTR_SELINUX_SUFFIX))
- return -EOPNOTSUPP;
+ if (strcmp(name, XATTR_SELINUX_SUFFIX)) {
+ rc = -EOPNOTSUPP;
+ goto out;
+ }
rc = security_sid_to_context(isec->sid, &context, &len);
if (rc)
- return rc;
+ goto out;
+ /* Probe for required buffer size */
if (!buffer || !size) {
- kfree(context);
- return len;
+ rc = len;
+ goto out_free;
}
+
if (size < len) {
- kfree(context);
- return -ERANGE;
+ rc = -ERANGE;
+ goto out_free;
+ }
+
+ if (err > 0) {
+ if ((len == err) && !(memcmp(context, buffer, len))) {
+ /* Don't need to canonicalize value */
+ rc = err;
+ goto out_free;
+ }
+ memset(buffer, 0, size);
}
memcpy(buffer, context, len);
+ rc = len;
+out_free:
kfree(context);
- return len;
+out:
+ return rc;
}
static int selinux_inode_setsecurity(struct inode *inode, const char *name,
@@ -2704,8 +2716,7 @@ static int selinux_task_kill(struct task_struct *p, struct siginfo *info, int si
if (rc)
return rc;
- if (info && ((unsigned long)info == 1 ||
- (unsigned long)info == 2 || SI_FROMKERNEL(info)))
+ if (info != SEND_SIG_NOINFO && (is_si_special(info) || SI_FROMKERNEL(info)))
return 0;
if (!sig)
@@ -3380,7 +3391,7 @@ out:
return err;
}
-static int selinux_sk_alloc_security(struct sock *sk, int family, int priority)
+static int selinux_sk_alloc_security(struct sock *sk, int family, gfp_t priority)
{
return sk_alloc_security(sk, family, priority);
}
@@ -3599,11 +3610,10 @@ static int ipc_alloc_security(struct task_struct *task,
struct task_security_struct *tsec = task->security;
struct ipc_security_struct *isec;
- isec = kmalloc(sizeof(struct ipc_security_struct), GFP_KERNEL);
+ isec = kzalloc(sizeof(struct ipc_security_struct), GFP_KERNEL);
if (!isec)
return -ENOMEM;
- memset(isec, 0, sizeof(struct ipc_security_struct));
isec->magic = SELINUX_MAGIC;
isec->sclass = sclass;
isec->ipc_perm = perm;
@@ -3631,11 +3641,10 @@ static int msg_msg_alloc_security(struct msg_msg *msg)
{
struct msg_security_struct *msec;
- msec = kmalloc(sizeof(struct msg_security_struct), GFP_KERNEL);
+ msec = kzalloc(sizeof(struct msg_security_struct), GFP_KERNEL);
if (!msec)
return -ENOMEM;
- memset(msec, 0, sizeof(struct msg_security_struct));
msec->magic = SELINUX_MAGIC;
msec->msg = msg;
msec->sid = SECINITSID_UNLABELED;
diff --git a/security/selinux/netif.c b/security/selinux/netif.c
index 718d7be9f4dd..b10c34e8a743 100644
--- a/security/selinux/netif.c
+++ b/security/selinux/netif.c
@@ -114,13 +114,12 @@ static struct sel_netif *sel_netif_lookup(struct net_device *dev)
if (likely(netif != NULL))
goto out;
- new = kmalloc(sizeof(*new), GFP_ATOMIC);
+ new = kzalloc(sizeof(*new), GFP_ATOMIC);
if (!new) {
netif = ERR_PTR(-ENOMEM);
goto out;
}
- memset(new, 0, sizeof(*new));
nsec = &new->nsec;
ret = security_netif_sid(dev->name, &nsec->if_sid, &nsec->msg_sid);
diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c
index a45cc971e735..0e1352a555c8 100644
--- a/security/selinux/selinuxfs.c
+++ b/security/selinux/selinuxfs.c
@@ -105,7 +105,7 @@ static ssize_t sel_write_enforce(struct file * file, const char __user * buf,
ssize_t length;
int new_value;
- if (count < 0 || count >= PAGE_SIZE)
+ if (count >= PAGE_SIZE)
return -ENOMEM;
if (*ppos != 0) {
/* No partial writes. */
@@ -155,7 +155,7 @@ static ssize_t sel_write_disable(struct file * file, const char __user * buf,
int new_value;
extern int selinux_disable(void);
- if (count < 0 || count >= PAGE_SIZE)
+ if (count >= PAGE_SIZE)
return -ENOMEM;
if (*ppos != 0) {
/* No partial writes. */
@@ -242,7 +242,7 @@ static ssize_t sel_write_load(struct file * file, const char __user * buf,
goto out;
}
- if ((count < 0) || (count > 64 * 1024 * 1024)
+ if ((count > 64 * 1024 * 1024)
|| (data = vmalloc(count)) == NULL) {
length = -ENOMEM;
goto out;
@@ -271,46 +271,38 @@ static struct file_operations sel_load_ops = {
.write = sel_write_load,
};
-
-static ssize_t sel_write_context(struct file * file, const char __user * buf,
- size_t count, loff_t *ppos)
-
+static ssize_t sel_write_context(struct file * file, char *buf, size_t size)
{
- char *page;
- u32 sid;
+ char *canon;
+ u32 sid, len;
ssize_t length;
length = task_has_security(current, SECURITY__CHECK_CONTEXT);
if (length)
return length;
- if (count < 0 || count >= PAGE_SIZE)
- return -ENOMEM;
- if (*ppos != 0) {
- /* No partial writes. */
- return -EINVAL;
- }
- page = (char*)get_zeroed_page(GFP_KERNEL);
- if (!page)
- return -ENOMEM;
- length = -EFAULT;
- if (copy_from_user(page, buf, count))
- goto out;
+ length = security_context_to_sid(buf, size, &sid);
+ if (length < 0)
+ return length;
- length = security_context_to_sid(page, count, &sid);
+ length = security_sid_to_context(sid, &canon, &len);
if (length < 0)
+ return length;
+
+ if (len > SIMPLE_TRANSACTION_LIMIT) {
+ printk(KERN_ERR "%s: context size (%u) exceeds payload "
+ "max\n", __FUNCTION__, len);
+ length = -ERANGE;
goto out;
+ }
- length = count;
+ memcpy(buf, canon, len);
+ length = len;
out:
- free_page((unsigned long) page);
+ kfree(canon);
return length;
}
-static struct file_operations sel_context_ops = {
- .write = sel_write_context,
-};
-
static ssize_t sel_read_checkreqprot(struct file *filp, char __user *buf,
size_t count, loff_t *ppos)
{
@@ -332,7 +324,7 @@ static ssize_t sel_write_checkreqprot(struct file * file, const char __user * bu
if (length)
return length;
- if (count < 0 || count >= PAGE_SIZE)
+ if (count >= PAGE_SIZE)
return -ENOMEM;
if (*ppos != 0) {
/* No partial writes. */
@@ -375,6 +367,7 @@ static ssize_t (*write_op[])(struct file *, char *, size_t) = {
[SEL_RELABEL] = sel_write_relabel,
[SEL_USER] = sel_write_user,
[SEL_MEMBER] = sel_write_member,
+ [SEL_CONTEXT] = sel_write_context,
};
static ssize_t selinux_transaction_write(struct file *file, const char __user *buf, size_t size, loff_t *pos)
@@ -424,15 +417,13 @@ static ssize_t sel_write_access(struct file * file, char *buf, size_t size)
return length;
length = -ENOMEM;
- scon = kmalloc(size+1, GFP_KERNEL);
+ scon = kzalloc(size+1, GFP_KERNEL);
if (!scon)
return length;
- memset(scon, 0, size+1);
- tcon = kmalloc(size+1, GFP_KERNEL);
+ tcon = kzalloc(size+1, GFP_KERNEL);
if (!tcon)
goto out;
- memset(tcon, 0, size+1);
length = -EINVAL;
if (sscanf(buf, "%s %s %hu %x", scon, tcon, &tclass, &req) != 4)
@@ -475,15 +466,13 @@ static ssize_t sel_write_create(struct file * file, char *buf, size_t size)
return length;
length = -ENOMEM;
- scon = kmalloc(size+1, GFP_KERNEL);
+ scon = kzalloc(size+1, GFP_KERNEL);
if (!scon)
return length;
- memset(scon, 0, size+1);
- tcon = kmalloc(size+1, GFP_KERNEL);
+ tcon = kzalloc(size+1, GFP_KERNEL);
if (!tcon)
goto out;
- memset(tcon, 0, size+1);
length = -EINVAL;
if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3)
@@ -536,15 +525,13 @@ static ssize_t sel_write_relabel(struct file * file, char *buf, size_t size)
return length;
length = -ENOMEM;
- scon = kmalloc(size+1, GFP_KERNEL);
+ scon = kzalloc(size+1, GFP_KERNEL);
if (!scon)
return length;
- memset(scon, 0, size+1);
- tcon = kmalloc(size+1, GFP_KERNEL);
+ tcon = kzalloc(size+1, GFP_KERNEL);
if (!tcon)
goto out;
- memset(tcon, 0, size+1);
length = -EINVAL;
if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3)
@@ -595,15 +582,13 @@ static ssize_t sel_write_user(struct file * file, char *buf, size_t size)
return length;
length = -ENOMEM;
- con = kmalloc(size+1, GFP_KERNEL);
+ con = kzalloc(size+1, GFP_KERNEL);
if (!con)
return length;
- memset(con, 0, size+1);
- user = kmalloc(size+1, GFP_KERNEL);
+ user = kzalloc(size+1, GFP_KERNEL);
if (!user)
goto out;
- memset(user, 0, size+1);
length = -EINVAL;
if (sscanf(buf, "%s %s", con, user) != 2)
@@ -658,15 +643,13 @@ static ssize_t sel_write_member(struct file * file, char *buf, size_t size)
return length;
length = -ENOMEM;
- scon = kmalloc(size+1, GFP_KERNEL);
+ scon = kzalloc(size+1, GFP_KERNEL);
if (!scon)
return length;
- memset(scon, 0, size+1);
- tcon = kmalloc(size+1, GFP_KERNEL);
+ tcon = kzalloc(size+1, GFP_KERNEL);
if (!tcon)
goto out;
- memset(tcon, 0, size+1);
length = -EINVAL;
if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3)
@@ -739,7 +722,7 @@ static ssize_t sel_read_bool(struct file *filep, char __user *buf,
if (!filep->f_op)
goto out;
- if (count < 0 || count > PAGE_SIZE) {
+ if (count > PAGE_SIZE) {
ret = -EINVAL;
goto out;
}
@@ -800,7 +783,7 @@ static ssize_t sel_write_bool(struct file *filep, const char __user *buf,
if (!filep->f_op)
goto out;
- if (count < 0 || count >= PAGE_SIZE) {
+ if (count >= PAGE_SIZE) {
length = -ENOMEM;
goto out;
}
@@ -858,7 +841,7 @@ static ssize_t sel_commit_bools_write(struct file *filep,
if (!filep->f_op)
goto out;
- if (count < 0 || count >= PAGE_SIZE) {
+ if (count >= PAGE_SIZE) {
length = -ENOMEM;
goto out;
}
@@ -924,7 +907,7 @@ static void sel_remove_bools(struct dentry *de)
file_list_lock();
list_for_each(p, &sb->s_files) {
- struct file * filp = list_entry(p, struct file, f_list);
+ struct file * filp = list_entry(p, struct file, f_u.fu_list);
struct dentry * dentry = filp->f_dentry;
if (dentry->d_parent != de) {
@@ -1032,7 +1015,7 @@ static ssize_t sel_write_avc_cache_threshold(struct file * file,
ssize_t ret;
int new_value;
- if (count < 0 || count >= PAGE_SIZE) {
+ if (count >= PAGE_SIZE) {
ret = -ENOMEM;
goto out;
}
@@ -1230,7 +1213,7 @@ static int sel_fill_super(struct super_block * sb, void * data, int silent)
static struct tree_descr selinux_files[] = {
[SEL_LOAD] = {"load", &sel_load_ops, S_IRUSR|S_IWUSR},
[SEL_ENFORCE] = {"enforce", &sel_enforce_ops, S_IRUGO|S_IWUSR},
- [SEL_CONTEXT] = {"context", &sel_context_ops, S_IRUGO|S_IWUGO},
+ [SEL_CONTEXT] = {"context", &transaction_ops, S_IRUGO|S_IWUGO},
[SEL_ACCESS] = {"access", &transaction_ops, S_IRUGO|S_IWUGO},
[SEL_CREATE] = {"create", &transaction_ops, S_IRUGO|S_IWUGO},
[SEL_RELABEL] = {"relabel", &transaction_ops, S_IRUGO|S_IWUGO},
diff --git a/security/selinux/ss/conditional.c b/security/selinux/ss/conditional.c
index daf288007460..d2737edba541 100644
--- a/security/selinux/ss/conditional.c
+++ b/security/selinux/ss/conditional.c
@@ -220,10 +220,9 @@ int cond_read_bool(struct policydb *p, struct hashtab *h, void *fp)
u32 len;
int rc;
- booldatum = kmalloc(sizeof(struct cond_bool_datum), GFP_KERNEL);
+ booldatum = kzalloc(sizeof(struct cond_bool_datum), GFP_KERNEL);
if (!booldatum)
return -1;
- memset(booldatum, 0, sizeof(struct cond_bool_datum));
rc = next_entry(buf, fp, sizeof buf);
if (rc < 0)
@@ -321,10 +320,9 @@ static int cond_insertf(struct avtab *a, struct avtab_key *k, struct avtab_datum
goto err;
}
- list = kmalloc(sizeof(struct cond_av_list), GFP_KERNEL);
+ list = kzalloc(sizeof(struct cond_av_list), GFP_KERNEL);
if (!list)
goto err;
- memset(list, 0, sizeof(*list));
list->node = node_ptr;
if (!data->head)
@@ -414,11 +412,10 @@ static int cond_read_node(struct policydb *p, struct cond_node *node, void *fp)
if (rc < 0)
goto err;
- expr = kmalloc(sizeof(struct cond_expr), GFP_KERNEL);
+ expr = kzalloc(sizeof(struct cond_expr), GFP_KERNEL);
if (!expr) {
goto err;
}
- memset(expr, 0, sizeof(struct cond_expr));
expr->expr_type = le32_to_cpu(buf[0]);
expr->bool = le32_to_cpu(buf[1]);
@@ -460,10 +457,9 @@ int cond_read_list(struct policydb *p, void *fp)
len = le32_to_cpu(buf[0]);
for (i = 0; i < len; i++) {
- node = kmalloc(sizeof(struct cond_node), GFP_KERNEL);
+ node = kzalloc(sizeof(struct cond_node), GFP_KERNEL);
if (!node)
goto err;
- memset(node, 0, sizeof(struct cond_node));
if (cond_read_node(p, node, fp) != 0)
goto err;
diff --git a/security/selinux/ss/ebitmap.c b/security/selinux/ss/ebitmap.c
index d515154128cc..47024a6e1844 100644
--- a/security/selinux/ss/ebitmap.c
+++ b/security/selinux/ss/ebitmap.c
@@ -39,12 +39,11 @@ int ebitmap_cpy(struct ebitmap *dst, struct ebitmap *src)
n = src->node;
prev = NULL;
while (n) {
- new = kmalloc(sizeof(*new), GFP_ATOMIC);
+ new = kzalloc(sizeof(*new), GFP_ATOMIC);
if (!new) {
ebitmap_destroy(dst);
return -ENOMEM;
}
- memset(new, 0, sizeof(*new));
new->startbit = n->startbit;
new->map = n->map;
new->next = NULL;
@@ -150,10 +149,9 @@ int ebitmap_set_bit(struct ebitmap *e, unsigned long bit, int value)
if (!value)
return 0;
- new = kmalloc(sizeof(*new), GFP_ATOMIC);
+ new = kzalloc(sizeof(*new), GFP_ATOMIC);
if (!new)
return -ENOMEM;
- memset(new, 0, sizeof(*new));
new->startbit = bit & ~(MAPSIZE - 1);
new->map = (MAPBIT << (bit - new->startbit));
@@ -232,13 +230,12 @@ int ebitmap_read(struct ebitmap *e, void *fp)
printk(KERN_ERR "security: ebitmap: truncated map\n");
goto bad;
}
- n = kmalloc(sizeof(*n), GFP_KERNEL);
+ n = kzalloc(sizeof(*n), GFP_KERNEL);
if (!n) {
printk(KERN_ERR "security: ebitmap: out of memory\n");
rc = -ENOMEM;
goto bad;
}
- memset(n, 0, sizeof(*n));
n->startbit = le32_to_cpu(buf[0]);
diff --git a/security/selinux/ss/hashtab.c b/security/selinux/ss/hashtab.c
index 26661fcc00ce..24e5ec957630 100644
--- a/security/selinux/ss/hashtab.c
+++ b/security/selinux/ss/hashtab.c
@@ -15,11 +15,10 @@ struct hashtab *hashtab_create(u32 (*hash_value)(struct hashtab *h, void *key),
struct hashtab *p;
u32 i;
- p = kmalloc(sizeof(*p), GFP_KERNEL);
+ p = kzalloc(sizeof(*p), GFP_KERNEL);
if (p == NULL)
return p;
- memset(p, 0, sizeof(*p));
p->size = size;
p->nel = 0;
p->hash_value = hash_value;
@@ -55,10 +54,9 @@ int hashtab_insert(struct hashtab *h, void *key, void *datum)
if (cur && (h->keycmp(h, key, cur->key) == 0))
return -EEXIST;
- newnode = kmalloc(sizeof(*newnode), GFP_KERNEL);
+ newnode = kzalloc(sizeof(*newnode), GFP_KERNEL);
if (newnode == NULL)
return -ENOMEM;
- memset(newnode, 0, sizeof(*newnode));
newnode->key = key;
newnode->datum = datum;
if (prev) {
diff --git a/security/selinux/ss/mls.c b/security/selinux/ss/mls.c
index aaefac2921f1..640d0bfdbc68 100644
--- a/security/selinux/ss/mls.c
+++ b/security/selinux/ss/mls.c
@@ -262,8 +262,11 @@ int mls_context_to_sid(char oldc,
struct cat_datum *catdatum, *rngdatum;
int l, rc = -EINVAL;
- if (!selinux_mls_enabled)
+ if (!selinux_mls_enabled) {
+ if (def_sid != SECSID_NULL && oldc)
+ *scontext += strlen(*scontext);
return 0;
+ }
/*
* No MLS component to the security context, try and map to
diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c
index 8e6262d12aa9..0ac311dc8371 100644
--- a/security/selinux/ss/policydb.c
+++ b/security/selinux/ss/policydb.c
@@ -121,12 +121,11 @@ static int roles_init(struct policydb *p)
int rc;
struct role_datum *role;
- role = kmalloc(sizeof(*role), GFP_KERNEL);
+ role = kzalloc(sizeof(*role), GFP_KERNEL);
if (!role) {
rc = -ENOMEM;
goto out;
}
- memset(role, 0, sizeof(*role));
role->value = ++p->p_roles.nprim;
if (role->value != OBJECT_R_VAL) {
rc = -EINVAL;
@@ -633,22 +632,22 @@ void policydb_destroy(struct policydb *p)
cond_policydb_destroy(p);
for (tr = p->role_tr; tr; tr = tr->next) {
- if (ltr) kfree(ltr);
+ kfree(ltr);
ltr = tr;
}
- if (ltr) kfree(ltr);
+ kfree(ltr);
for (ra = p->role_allow; ra; ra = ra -> next) {
- if (lra) kfree(lra);
+ kfree(lra);
lra = ra;
}
- if (lra) kfree(lra);
+ kfree(lra);
for (rt = p->range_tr; rt; rt = rt -> next) {
- if (lrt) kfree(lrt);
+ kfree(lrt);
lrt = rt;
}
- if (lrt) kfree(lrt);
+ kfree(lrt);
if (p->type_attr_map) {
for (i = 0; i < p->p_types.nprim; i++)
@@ -851,12 +850,11 @@ static int perm_read(struct policydb *p, struct hashtab *h, void *fp)
__le32 buf[2];
u32 len;
- perdatum = kmalloc(sizeof(*perdatum), GFP_KERNEL);
+ perdatum = kzalloc(sizeof(*perdatum), GFP_KERNEL);
if (!perdatum) {
rc = -ENOMEM;
goto out;
}
- memset(perdatum, 0, sizeof(*perdatum));
rc = next_entry(buf, fp, sizeof buf);
if (rc < 0)
@@ -893,12 +891,11 @@ static int common_read(struct policydb *p, struct hashtab *h, void *fp)
u32 len, nel;
int i, rc;
- comdatum = kmalloc(sizeof(*comdatum), GFP_KERNEL);
+ comdatum = kzalloc(sizeof(*comdatum), GFP_KERNEL);
if (!comdatum) {
rc = -ENOMEM;
goto out;
}
- memset(comdatum, 0, sizeof(*comdatum));
rc = next_entry(buf, fp, sizeof buf);
if (rc < 0)
@@ -950,10 +947,9 @@ static int read_cons_helper(struct constraint_node **nodep, int ncons,
lc = NULL;
for (i = 0; i < ncons; i++) {
- c = kmalloc(sizeof(*c), GFP_KERNEL);
+ c = kzalloc(sizeof(*c), GFP_KERNEL);
if (!c)
return -ENOMEM;
- memset(c, 0, sizeof(*c));
if (lc) {
lc->next = c;
@@ -969,10 +965,9 @@ static int read_cons_helper(struct constraint_node **nodep, int ncons,
le = NULL;
depth = -1;
for (j = 0; j < nexpr; j++) {
- e = kmalloc(sizeof(*e), GFP_KERNEL);
+ e = kzalloc(sizeof(*e), GFP_KERNEL);
if (!e)
return -ENOMEM;
- memset(e, 0, sizeof(*e));
if (le) {
le->next = e;
@@ -1033,12 +1028,11 @@ static int class_read(struct policydb *p, struct hashtab *h, void *fp)
u32 len, len2, ncons, nel;
int i, rc;
- cladatum = kmalloc(sizeof(*cladatum), GFP_KERNEL);
+ cladatum = kzalloc(sizeof(*cladatum), GFP_KERNEL);
if (!cladatum) {
rc = -ENOMEM;
goto out;
}
- memset(cladatum, 0, sizeof(*cladatum));
rc = next_entry(buf, fp, sizeof(u32)*6);
if (rc < 0)
@@ -1127,12 +1121,11 @@ static int role_read(struct policydb *p, struct hashtab *h, void *fp)
__le32 buf[2];
u32 len;
- role = kmalloc(sizeof(*role), GFP_KERNEL);
+ role = kzalloc(sizeof(*role), GFP_KERNEL);
if (!role) {
rc = -ENOMEM;
goto out;
}
- memset(role, 0, sizeof(*role));
rc = next_entry(buf, fp, sizeof buf);
if (rc < 0)
@@ -1188,12 +1181,11 @@ static int type_read(struct policydb *p, struct hashtab *h, void *fp)
__le32 buf[3];
u32 len;
- typdatum = kmalloc(sizeof(*typdatum),GFP_KERNEL);
+ typdatum = kzalloc(sizeof(*typdatum),GFP_KERNEL);
if (!typdatum) {
rc = -ENOMEM;
return rc;
}
- memset(typdatum, 0, sizeof(*typdatum));
rc = next_entry(buf, fp, sizeof buf);
if (rc < 0)
@@ -1261,12 +1253,11 @@ static int user_read(struct policydb *p, struct hashtab *h, void *fp)
__le32 buf[2];
u32 len;
- usrdatum = kmalloc(sizeof(*usrdatum), GFP_KERNEL);
+ usrdatum = kzalloc(sizeof(*usrdatum), GFP_KERNEL);
if (!usrdatum) {
rc = -ENOMEM;
goto out;
}
- memset(usrdatum, 0, sizeof(*usrdatum));
rc = next_entry(buf, fp, sizeof buf);
if (rc < 0)
@@ -1316,12 +1307,11 @@ static int sens_read(struct policydb *p, struct hashtab *h, void *fp)
__le32 buf[2];
u32 len;
- levdatum = kmalloc(sizeof(*levdatum), GFP_ATOMIC);
+ levdatum = kzalloc(sizeof(*levdatum), GFP_ATOMIC);
if (!levdatum) {
rc = -ENOMEM;
goto out;
}
- memset(levdatum, 0, sizeof(*levdatum));
rc = next_entry(buf, fp, sizeof buf);
if (rc < 0)
@@ -1368,12 +1358,11 @@ static int cat_read(struct policydb *p, struct hashtab *h, void *fp)
__le32 buf[3];
u32 len;
- catdatum = kmalloc(sizeof(*catdatum), GFP_ATOMIC);
+ catdatum = kzalloc(sizeof(*catdatum), GFP_ATOMIC);
if (!catdatum) {
rc = -ENOMEM;
goto out;
}
- memset(catdatum, 0, sizeof(*catdatum));
rc = next_entry(buf, fp, sizeof buf);
if (rc < 0)
@@ -1567,12 +1556,11 @@ int policydb_read(struct policydb *p, void *fp)
nel = le32_to_cpu(buf[0]);
ltr = NULL;
for (i = 0; i < nel; i++) {
- tr = kmalloc(sizeof(*tr), GFP_KERNEL);
+ tr = kzalloc(sizeof(*tr), GFP_KERNEL);
if (!tr) {
rc = -ENOMEM;
goto bad;
}
- memset(tr, 0, sizeof(*tr));
if (ltr) {
ltr->next = tr;
} else {
@@ -1593,12 +1581,11 @@ int policydb_read(struct policydb *p, void *fp)
nel = le32_to_cpu(buf[0]);
lra = NULL;
for (i = 0; i < nel; i++) {
- ra = kmalloc(sizeof(*ra), GFP_KERNEL);
+ ra = kzalloc(sizeof(*ra), GFP_KERNEL);
if (!ra) {
rc = -ENOMEM;
goto bad;
}
- memset(ra, 0, sizeof(*ra));
if (lra) {
lra->next = ra;
} else {
@@ -1627,12 +1614,11 @@ int policydb_read(struct policydb *p, void *fp)
nel = le32_to_cpu(buf[0]);
l = NULL;
for (j = 0; j < nel; j++) {
- c = kmalloc(sizeof(*c), GFP_KERNEL);
+ c = kzalloc(sizeof(*c), GFP_KERNEL);
if (!c) {
rc = -ENOMEM;
goto bad;
}
- memset(c, 0, sizeof(*c));
if (l) {
l->next = c;
} else {
@@ -1743,12 +1729,11 @@ int policydb_read(struct policydb *p, void *fp)
if (rc < 0)
goto bad;
len = le32_to_cpu(buf[0]);
- newgenfs = kmalloc(sizeof(*newgenfs), GFP_KERNEL);
+ newgenfs = kzalloc(sizeof(*newgenfs), GFP_KERNEL);
if (!newgenfs) {
rc = -ENOMEM;
goto bad;
}
- memset(newgenfs, 0, sizeof(*newgenfs));
newgenfs->fstype = kmalloc(len + 1,GFP_KERNEL);
if (!newgenfs->fstype) {
@@ -1790,12 +1775,11 @@ int policydb_read(struct policydb *p, void *fp)
goto bad;
len = le32_to_cpu(buf[0]);
- newc = kmalloc(sizeof(*newc), GFP_KERNEL);
+ newc = kzalloc(sizeof(*newc), GFP_KERNEL);
if (!newc) {
rc = -ENOMEM;
goto bad;
}
- memset(newc, 0, sizeof(*newc));
newc->u.name = kmalloc(len + 1,GFP_KERNEL);
if (!newc->u.name) {
@@ -1843,12 +1827,11 @@ int policydb_read(struct policydb *p, void *fp)
nel = le32_to_cpu(buf[0]);
lrt = NULL;
for (i = 0; i < nel; i++) {
- rt = kmalloc(sizeof(*rt), GFP_KERNEL);
+ rt = kzalloc(sizeof(*rt), GFP_KERNEL);
if (!rt) {
rc = -ENOMEM;
goto bad;
}
- memset(rt, 0, sizeof(*rt));
if (lrt)
lrt->next = rt;
else
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index aecdded55e74..44eb4d74908d 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -1531,12 +1531,11 @@ int security_get_user_sids(u32 fromsid,
}
usercon.user = user->value;
- mysids = kmalloc(maxnel*sizeof(*mysids), GFP_ATOMIC);
+ mysids = kcalloc(maxnel, sizeof(*mysids), GFP_ATOMIC);
if (!mysids) {
rc = -ENOMEM;
goto out_unlock;
}
- memset(mysids, 0, maxnel*sizeof(*mysids));
ebitmap_for_each_bit(&user->roles, rnode, i) {
if (!ebitmap_node_get_bit(rnode, i))
@@ -1566,13 +1565,12 @@ int security_get_user_sids(u32 fromsid,
mysids[mynel++] = sid;
} else {
maxnel += SIDS_NEL;
- mysids2 = kmalloc(maxnel*sizeof(*mysids2), GFP_ATOMIC);
+ mysids2 = kcalloc(maxnel, sizeof(*mysids2), GFP_ATOMIC);
if (!mysids2) {
rc = -ENOMEM;
kfree(mysids);
goto out_unlock;
}
- memset(mysids2, 0, maxnel*sizeof(*mysids2));
memcpy(mysids2, mysids, mynel * sizeof(*mysids2));
kfree(mysids);
mysids = mysids2;
@@ -1714,12 +1712,11 @@ int security_get_bools(int *len, char ***names, int **values)
goto out;
}
- *names = (char**)kmalloc(sizeof(char*) * *len, GFP_ATOMIC);
+ *names = (char**)kcalloc(*len, sizeof(char*), GFP_ATOMIC);
if (!*names)
goto err;
- memset(*names, 0, sizeof(char*) * *len);
- *values = (int*)kmalloc(sizeof(int) * *len, GFP_ATOMIC);
+ *values = (int*)kcalloc(*len, sizeof(int), GFP_ATOMIC);
if (!*values)
goto err;
diff --git a/sound/Kconfig b/sound/Kconfig
index b65ee4701f98..d8f11408ce27 100644
--- a/sound/Kconfig
+++ b/sound/Kconfig
@@ -48,6 +48,14 @@ config SND
For more information, see <http://www.alsa-project.org/>
+config SND_AC97_CODEC
+ tristate
+ select SND_PCM
+ select SND_AC97_BUS
+
+config SND_AC97_BUS
+ tristate
+
source "sound/core/Kconfig"
source "sound/drivers/Kconfig"
diff --git a/sound/arm/aaci.c b/sound/arm/aaci.c
index b2d5db20ec8c..559ead6367da 100644
--- a/sound/arm/aaci.c
+++ b/sound/arm/aaci.c
@@ -20,6 +20,7 @@
#include <asm/io.h>
#include <asm/irq.h>
+#include <asm/sizes.h>
#include <asm/hardware/amba.h>
#include <sound/driver.h>
diff --git a/sound/arm/pxa2xx-ac97.c b/sound/arm/pxa2xx-ac97.c
index 38b20efc9c0b..d1f9da498729 100644
--- a/sound/arm/pxa2xx-ac97.c
+++ b/sound/arm/pxa2xx-ac97.c
@@ -13,7 +13,7 @@
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <linux/interrupt.h>
#include <linux/wait.h>
#include <linux/delay.h>
@@ -275,23 +275,23 @@ static int pxa2xx_ac97_do_resume(snd_card_t *card)
return 0;
}
-static int pxa2xx_ac97_suspend(struct device *_dev, pm_message_t state, u32 level)
+static int pxa2xx_ac97_suspend(struct device *_dev, pm_message_t state)
{
snd_card_t *card = dev_get_drvdata(_dev);
int ret = 0;
- if (card && level == SUSPEND_DISABLE)
+ if (card)
ret = pxa2xx_ac97_do_suspend(card, PMSG_SUSPEND);
return ret;
}
-static int pxa2xx_ac97_resume(struct device *_dev, u32 level)
+static int pxa2xx_ac97_resume(struct device *_dev)
{
snd_card_t *card = dev_get_drvdata(_dev);
int ret = 0;
- if (card && level == RESUME_ENABLE)
+ if (card)
ret = pxa2xx_ac97_do_resume(card);
return ret;
diff --git a/sound/core/Kconfig b/sound/core/Kconfig
index 48cf45cfd0b7..82718836f937 100644
--- a/sound/core/Kconfig
+++ b/sound/core/Kconfig
@@ -127,12 +127,6 @@ config SND_DEBUG
help
Say Y here to enable ALSA debug code.
-config SND_DEBUG_MEMORY
- bool "Debug memory"
- depends on SND_DEBUG
- help
- Say Y here to enable debugging of memory allocations.
-
config SND_DEBUG_DETECT
bool "Debug detection"
depends on SND_DEBUG
diff --git a/sound/core/Makefile b/sound/core/Makefile
index 969d75528bde..5a01c76d02e8 100644
--- a/sound/core/Makefile
+++ b/sound/core/Makefile
@@ -3,8 +3,7 @@
# Copyright (c) 1999,2001 by Jaroslav Kysela <perex@suse.cz>
#
-snd-objs := sound.o init.o memory.o info.o control.o misc.o \
- device.o wrappers.o
+snd-objs := sound.o init.o memory.o info.o control.o misc.o device.o
ifeq ($(CONFIG_ISA_DMA_API),y)
snd-objs += isadma.o
endif
diff --git a/sound/core/control.c b/sound/core/control.c
index 736edf358e05..212c46a94376 100644
--- a/sound/core/control.c
+++ b/sound/core/control.c
@@ -144,7 +144,7 @@ void snd_ctl_notify(snd_card_t *card, unsigned int mask, snd_ctl_elem_id_t *id)
snd_ctl_file_t *ctl;
snd_kctl_event_t *ev;
- snd_runtime_check(card != NULL && id != NULL, return);
+ snd_assert(card != NULL && id != NULL, return);
read_lock(&card->ctl_files_rwlock);
#if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE)
card->mixer_oss_change_count++;
@@ -193,8 +193,8 @@ snd_kcontrol_t *snd_ctl_new(snd_kcontrol_t * control, unsigned int access)
snd_kcontrol_t *kctl;
unsigned int idx;
- snd_runtime_check(control != NULL, return NULL);
- snd_runtime_check(control->count > 0, return NULL);
+ snd_assert(control != NULL, return NULL);
+ snd_assert(control->count > 0, return NULL);
kctl = kzalloc(sizeof(*kctl) + sizeof(snd_kcontrol_volatile_t) * control->count, GFP_KERNEL);
if (kctl == NULL)
return NULL;
@@ -220,7 +220,7 @@ snd_kcontrol_t *snd_ctl_new1(const snd_kcontrol_new_t * ncontrol, void *private_
snd_kcontrol_t kctl;
unsigned int access;
- snd_runtime_check(ncontrol != NULL, return NULL);
+ snd_assert(ncontrol != NULL, return NULL);
snd_assert(ncontrol->info != NULL, return NULL);
memset(&kctl, 0, sizeof(kctl));
kctl.id.iface = ncontrol->iface;
@@ -309,7 +309,7 @@ int snd_ctl_add(snd_card_t * card, snd_kcontrol_t * kcontrol)
snd_ctl_elem_id_t id;
unsigned int idx;
- snd_runtime_check(card != NULL && kcontrol != NULL, return -EINVAL);
+ snd_assert(card != NULL && kcontrol != NULL, return -EINVAL);
snd_assert(kcontrol->info != NULL, return -EINVAL);
id = kcontrol->id;
down_write(&card->controls_rwsem);
@@ -355,7 +355,7 @@ int snd_ctl_remove(snd_card_t * card, snd_kcontrol_t * kcontrol)
snd_ctl_elem_id_t id;
unsigned int idx;
- snd_runtime_check(card != NULL && kcontrol != NULL, return -EINVAL);
+ snd_assert(card != NULL && kcontrol != NULL, return -EINVAL);
list_del(&kcontrol->list);
card->controls_count -= kcontrol->count;
id = kcontrol->id;
@@ -468,7 +468,7 @@ snd_kcontrol_t *snd_ctl_find_numid(snd_card_t * card, unsigned int numid)
struct list_head *list;
snd_kcontrol_t *kctl;
- snd_runtime_check(card != NULL && numid != 0, return NULL);
+ snd_assert(card != NULL && numid != 0, return NULL);
list_for_each(list, &card->controls) {
kctl = snd_kcontrol(list);
if (kctl->id.numid <= numid && kctl->id.numid + kctl->count > numid)
@@ -494,7 +494,7 @@ snd_kcontrol_t *snd_ctl_find_id(snd_card_t * card, snd_ctl_elem_id_t *id)
struct list_head *list;
snd_kcontrol_t *kctl;
- snd_runtime_check(card != NULL && id != NULL, return NULL);
+ snd_assert(card != NULL && id != NULL, return NULL);
if (id->numid != 0)
return snd_ctl_find_numid(card, id->numid);
list_for_each(list, &card->controls) {
@@ -1215,7 +1215,7 @@ static int _snd_ctl_unregister_ioctl(snd_kctl_ioctl_func_t fcn, struct list_head
struct list_head *list;
snd_kctl_ioctl_t *p;
- snd_runtime_check(fcn != NULL, return -EINVAL);
+ snd_assert(fcn != NULL, return -EINVAL);
down_write(&snd_ioctl_rwsem);
list_for_each(list, lists) {
p = list_entry(list, snd_kctl_ioctl_t, list);
diff --git a/sound/core/hwdep.c b/sound/core/hwdep.c
index 9383f1294fb5..e91cee35a4b9 100644
--- a/sound/core/hwdep.c
+++ b/sound/core/hwdep.c
@@ -81,20 +81,16 @@ static int snd_hwdep_open(struct inode *inode, struct file * file)
int err;
wait_queue_t wait;
- switch (major) {
- case CONFIG_SND_MAJOR:
+ if (major == snd_major) {
cardnum = SNDRV_MINOR_CARD(iminor(inode));
device = SNDRV_MINOR_DEVICE(iminor(inode)) - SNDRV_MINOR_HWDEP;
- break;
#ifdef CONFIG_SND_OSSEMUL
- case SOUND_MAJOR:
+ } else if (major == SOUND_MAJOR) {
cardnum = SNDRV_MINOR_OSS_CARD(iminor(inode));
device = 0;
- break;
#endif
- default:
+ } else
return -ENXIO;
- }
cardnum %= SNDRV_CARDS;
device %= SNDRV_MINOR_HWDEPS;
hw = snd_hwdep_devices[(cardnum * SNDRV_MINOR_HWDEPS) + device];
diff --git a/sound/core/info.c b/sound/core/info.c
index 37024d68a26e..39f9b97d9219 100644
--- a/sound/core/info.c
+++ b/sound/core/info.c
@@ -566,7 +566,6 @@ int __init snd_info_init(void)
}
#endif
snd_info_version_init();
- snd_memory_info_init();
snd_minor_info_init();
snd_minor_info_oss_init();
snd_card_info_init();
@@ -578,7 +577,6 @@ int __exit snd_info_done(void)
snd_card_info_done();
snd_minor_info_oss_done();
snd_minor_info_done();
- snd_memory_info_done();
snd_info_version_done();
if (snd_proc_root) {
#if defined(CONFIG_SND_SEQUENCER) || defined(CONFIG_SND_SEQUENCER_MODULE)
diff --git a/sound/core/init.c b/sound/core/init.c
index c72a79115cca..d9ee27ae9a51 100644
--- a/sound/core/init.c
+++ b/sound/core/init.c
@@ -28,6 +28,8 @@
#include <linux/ctype.h>
#include <linux/pci.h>
#include <linux/pm.h>
+#include <linux/platform_device.h>
+
#include <sound/core.h>
#include <sound/control.h>
#include <sound/info.h>
@@ -418,7 +420,7 @@ int snd_card_register(snd_card_t * card)
int err;
snd_info_entry_t *entry;
- snd_runtime_check(card != NULL, return -EINVAL);
+ snd_assert(card != NULL, return -EINVAL);
if ((err = snd_device_register_all(card)) < 0)
return err;
write_lock(&snd_card_rwlock);
@@ -522,7 +524,8 @@ int __init snd_card_info_init(void)
snd_info_entry_t *entry;
entry = snd_info_create_module_entry(THIS_MODULE, "cards", NULL);
- snd_runtime_check(entry != NULL, return -ENOMEM);
+ if (! entry)
+ return -ENOMEM;
entry->c.text.read_size = PAGE_SIZE;
entry->c.text.read = snd_card_info_read;
if (snd_info_register(entry) < 0) {
@@ -676,8 +679,8 @@ struct snd_generic_device {
#define SND_GENERIC_NAME "snd_generic"
#ifdef CONFIG_PM
-static int snd_generic_suspend(struct device *dev, pm_message_t state, u32 level);
-static int snd_generic_resume(struct device *dev, u32 level);
+static int snd_generic_suspend(struct device *dev, pm_message_t state);
+static int snd_generic_resume(struct device *dev);
#endif
/* initialized in sound.c */
@@ -818,13 +821,10 @@ int snd_card_set_pm_callback(snd_card_t *card,
#ifdef CONFIG_SND_GENERIC_DRIVER
/* suspend/resume callbacks for snd_generic platform device */
-static int snd_generic_suspend(struct device *dev, pm_message_t state, u32 level)
+static int snd_generic_suspend(struct device *dev, pm_message_t state)
{
snd_card_t *card;
- if (level != SUSPEND_DISABLE)
- return 0;
-
card = get_snd_generic_card(dev);
if (card->power_state == SNDRV_CTL_POWER_D3hot)
return 0;
@@ -834,17 +834,14 @@ static int snd_generic_suspend(struct device *dev, pm_message_t state, u32 level
return 0;
}
-static int snd_generic_resume(struct device *dev, u32 level)
+static int snd_generic_resume(struct device *dev)
{
snd_card_t *card;
- if (level != RESUME_ENABLE)
- return 0;
-
card = get_snd_generic_card(dev);
if (card->power_state == SNDRV_CTL_POWER_D0)
return 0;
- if (card->pm_suspend)
+ if (card->pm_resume)
card->pm_resume(card);
snd_power_change_state(card, SNDRV_CTL_POWER_D0);
return 0;
diff --git a/sound/core/memalloc.c b/sound/core/memalloc.c
index e72cec77f0db..129abab5ce98 100644
--- a/sound/core/memalloc.c
+++ b/sound/core/memalloc.c
@@ -190,7 +190,7 @@ static void unmark_pages(struct page *page, int order)
*
* Returns the pointer of the buffer, or NULL if no enoguh memory.
*/
-void *snd_malloc_pages(size_t size, unsigned int gfp_flags)
+void *snd_malloc_pages(size_t size, gfp_t gfp_flags)
{
int pg;
void *res;
@@ -235,7 +235,7 @@ static void *snd_malloc_dev_pages(struct device *dev, size_t size, dma_addr_t *d
{
int pg;
void *res;
- unsigned int gfp_flags;
+ gfp_t gfp_flags;
snd_assert(size > 0, return NULL);
snd_assert(dma != NULL, return NULL);
diff --git a/sound/core/memory.c b/sound/core/memory.c
index 7d8e2eebba51..862d62d2e144 100644
--- a/sound/core/memory.c
+++ b/sound/core/memory.c
@@ -1,7 +1,7 @@
/*
* Copyright (c) by Jaroslav Kysela <perex@suse.cz>
*
- * Memory allocation helpers.
+ * Misc memory accessors
*
*
* This program is free software; you can redistribute it and/or modify
@@ -20,221 +20,9 @@
*
*/
-#include <sound/driver.h>
+#include <linux/config.h>
#include <asm/io.h>
#include <asm/uaccess.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/time.h>
-#include <linux/pci.h>
-#include <sound/core.h>
-#include <sound/info.h>
-
-/*
- * memory allocation helpers and debug routines
- */
-
-#ifdef CONFIG_SND_DEBUG_MEMORY
-
-struct snd_alloc_track {
- unsigned long magic;
- void *caller;
- size_t size;
- struct list_head list;
- long data[0];
-};
-
-#define snd_alloc_track_entry(obj) (struct snd_alloc_track *)((char*)obj - (unsigned long)((struct snd_alloc_track *)0)->data)
-
-static long snd_alloc_kmalloc;
-static long snd_alloc_vmalloc;
-static LIST_HEAD(snd_alloc_kmalloc_list);
-static LIST_HEAD(snd_alloc_vmalloc_list);
-static DEFINE_SPINLOCK(snd_alloc_kmalloc_lock);
-static DEFINE_SPINLOCK(snd_alloc_vmalloc_lock);
-#define KMALLOC_MAGIC 0x87654321
-#define VMALLOC_MAGIC 0x87654320
-static snd_info_entry_t *snd_memory_info_entry;
-
-void __init snd_memory_init(void)
-{
- snd_alloc_kmalloc = 0;
- snd_alloc_vmalloc = 0;
-}
-
-void snd_memory_done(void)
-{
- struct list_head *head;
- struct snd_alloc_track *t;
-
- if (snd_alloc_kmalloc > 0)
- snd_printk(KERN_ERR "Not freed snd_alloc_kmalloc = %li\n", snd_alloc_kmalloc);
- if (snd_alloc_vmalloc > 0)
- snd_printk(KERN_ERR "Not freed snd_alloc_vmalloc = %li\n", snd_alloc_vmalloc);
- list_for_each_prev(head, &snd_alloc_kmalloc_list) {
- t = list_entry(head, struct snd_alloc_track, list);
- if (t->magic != KMALLOC_MAGIC) {
- snd_printk(KERN_ERR "Corrupted kmalloc\n");
- break;
- }
- snd_printk(KERN_ERR "kmalloc(%ld) from %p not freed\n", (long) t->size, t->caller);
- }
- list_for_each_prev(head, &snd_alloc_vmalloc_list) {
- t = list_entry(head, struct snd_alloc_track, list);
- if (t->magic != VMALLOC_MAGIC) {
- snd_printk(KERN_ERR "Corrupted vmalloc\n");
- break;
- }
- snd_printk(KERN_ERR "vmalloc(%ld) from %p not freed\n", (long) t->size, t->caller);
- }
-}
-
-static void *__snd_kmalloc(size_t size, gfp_t flags, void *caller)
-{
- unsigned long cpu_flags;
- struct snd_alloc_track *t;
- void *ptr;
-
- ptr = snd_wrapper_kmalloc(size + sizeof(struct snd_alloc_track), flags);
- if (ptr != NULL) {
- t = (struct snd_alloc_track *)ptr;
- t->magic = KMALLOC_MAGIC;
- t->caller = caller;
- spin_lock_irqsave(&snd_alloc_kmalloc_lock, cpu_flags);
- list_add_tail(&t->list, &snd_alloc_kmalloc_list);
- spin_unlock_irqrestore(&snd_alloc_kmalloc_lock, cpu_flags);
- t->size = size;
- snd_alloc_kmalloc += size;
- ptr = t->data;
- }
- return ptr;
-}
-
-#define _snd_kmalloc(size, flags) __snd_kmalloc((size), (flags), __builtin_return_address(0));
-void *snd_hidden_kmalloc(size_t size, gfp_t flags)
-{
- return _snd_kmalloc(size, flags);
-}
-
-void *snd_hidden_kzalloc(size_t size, gfp_t flags)
-{
- void *ret = _snd_kmalloc(size, flags);
- if (ret)
- memset(ret, 0, size);
- return ret;
-}
-EXPORT_SYMBOL(snd_hidden_kzalloc);
-
-void *snd_hidden_kcalloc(size_t n, size_t size, gfp_t flags)
-{
- void *ret = NULL;
- if (n != 0 && size > INT_MAX / n)
- return ret;
- return snd_hidden_kzalloc(n * size, flags);
-}
-
-void snd_hidden_kfree(const void *obj)
-{
- unsigned long flags;
- struct snd_alloc_track *t;
- if (obj == NULL)
- return;
- t = snd_alloc_track_entry(obj);
- if (t->magic != KMALLOC_MAGIC) {
- snd_printk(KERN_WARNING "bad kfree (called from %p)\n", __builtin_return_address(0));
- return;
- }
- spin_lock_irqsave(&snd_alloc_kmalloc_lock, flags);
- list_del(&t->list);
- spin_unlock_irqrestore(&snd_alloc_kmalloc_lock, flags);
- t->magic = 0;
- snd_alloc_kmalloc -= t->size;
- obj = t;
- snd_wrapper_kfree(obj);
-}
-
-void *snd_hidden_vmalloc(unsigned long size)
-{
- void *ptr;
- ptr = snd_wrapper_vmalloc(size + sizeof(struct snd_alloc_track));
- if (ptr) {
- struct snd_alloc_track *t = (struct snd_alloc_track *)ptr;
- t->magic = VMALLOC_MAGIC;
- t->caller = __builtin_return_address(0);
- spin_lock(&snd_alloc_vmalloc_lock);
- list_add_tail(&t->list, &snd_alloc_vmalloc_list);
- spin_unlock(&snd_alloc_vmalloc_lock);
- t->size = size;
- snd_alloc_vmalloc += size;
- ptr = t->data;
- }
- return ptr;
-}
-
-void snd_hidden_vfree(void *obj)
-{
- struct snd_alloc_track *t;
- if (obj == NULL)
- return;
- t = snd_alloc_track_entry(obj);
- if (t->magic != VMALLOC_MAGIC) {
- snd_printk(KERN_ERR "bad vfree (called from %p)\n", __builtin_return_address(0));
- return;
- }
- spin_lock(&snd_alloc_vmalloc_lock);
- list_del(&t->list);
- spin_unlock(&snd_alloc_vmalloc_lock);
- t->magic = 0;
- snd_alloc_vmalloc -= t->size;
- obj = t;
- snd_wrapper_vfree(obj);
-}
-
-char *snd_hidden_kstrdup(const char *s, gfp_t flags)
-{
- int len;
- char *buf;
-
- if (!s) return NULL;
-
- len = strlen(s) + 1;
- buf = _snd_kmalloc(len, flags);
- if (buf)
- memcpy(buf, s, len);
- return buf;
-}
-
-static void snd_memory_info_read(snd_info_entry_t *entry, snd_info_buffer_t * buffer)
-{
- snd_iprintf(buffer, "kmalloc: %li bytes\n", snd_alloc_kmalloc);
- snd_iprintf(buffer, "vmalloc: %li bytes\n", snd_alloc_vmalloc);
-}
-
-int __init snd_memory_info_init(void)
-{
- snd_info_entry_t *entry;
-
- entry = snd_info_create_module_entry(THIS_MODULE, "meminfo", NULL);
- if (entry) {
- entry->c.text.read_size = 256;
- entry->c.text.read = snd_memory_info_read;
- if (snd_info_register(entry) < 0) {
- snd_info_free_entry(entry);
- entry = NULL;
- }
- }
- snd_memory_info_entry = entry;
- return 0;
-}
-
-int __exit snd_memory_info_done(void)
-{
- if (snd_memory_info_entry)
- snd_info_unregister(snd_memory_info_entry);
- return 0;
-}
-
-#endif /* CONFIG_SND_DEBUG_MEMORY */
/**
* copy_to_user_fromio - copy data from mmio-space to user-space
diff --git a/sound/core/misc.c b/sound/core/misc.c
index 1a81fe4df218..b53e563c09e6 100644
--- a/sound/core/misc.c
+++ b/sound/core/misc.c
@@ -23,17 +23,15 @@
#include <linux/init.h>
#include <linux/sched.h>
#include <linux/time.h>
+#include <linux/ioport.h>
#include <sound/core.h>
-int snd_task_name(struct task_struct *task, char *name, size_t size)
+void release_and_free_resource(struct resource *res)
{
- unsigned int idx;
-
- snd_assert(task != NULL && name != NULL && size >= 2, return -EINVAL);
- for (idx = 0; idx < sizeof(task->comm) && idx + 1 < size; idx++)
- name[idx] = task->comm[idx];
- name[idx] = '\0';
- return 0;
+ if (res) {
+ release_resource(res);
+ kfree(res);
+ }
}
#ifdef CONFIG_SND_VERBOSE_PRINTK
diff --git a/sound/core/oss/mixer_oss.c b/sound/core/oss/mixer_oss.c
index 69e1059112d1..214933cf5d49 100644
--- a/sound/core/oss/mixer_oss.c
+++ b/sound/core/oss/mixer_oss.c
@@ -521,9 +521,13 @@ static void snd_mixer_oss_get_volume1_vol(snd_mixer_oss_file_t *fmixer,
uctl = kzalloc(sizeof(*uctl), GFP_KERNEL);
if (uinfo == NULL || uctl == NULL)
goto __unalloc;
- snd_runtime_check(!kctl->info(kctl, uinfo), goto __unalloc);
- snd_runtime_check(!kctl->get(kctl, uctl), goto __unalloc);
- snd_runtime_check(uinfo->type != SNDRV_CTL_ELEM_TYPE_BOOLEAN || uinfo->value.integer.min != 0 || uinfo->value.integer.max != 1, goto __unalloc);
+ if (kctl->info(kctl, uinfo))
+ goto __unalloc;
+ if (kctl->get(kctl, uctl))
+ goto __unalloc;
+ if (uinfo->type == SNDRV_CTL_ELEM_TYPE_BOOLEAN &&
+ uinfo->value.integer.min == 0 && uinfo->value.integer.max == 1)
+ goto __unalloc;
*left = snd_mixer_oss_conv1(uctl->value.integer.value[0], uinfo->value.integer.min, uinfo->value.integer.max, &pslot->volume[0]);
if (uinfo->count > 1)
*right = snd_mixer_oss_conv1(uctl->value.integer.value[1], uinfo->value.integer.min, uinfo->value.integer.max, &pslot->volume[1]);
@@ -555,8 +559,10 @@ static void snd_mixer_oss_get_volume1_sw(snd_mixer_oss_file_t *fmixer,
uctl = kzalloc(sizeof(*uctl), GFP_KERNEL);
if (uinfo == NULL || uctl == NULL)
goto __unalloc;
- snd_runtime_check(!kctl->info(kctl, uinfo), goto __unalloc);
- snd_runtime_check(!kctl->get(kctl, uctl), goto __unalloc);
+ if (kctl->info(kctl, uinfo))
+ goto __unalloc;
+ if (kctl->get(kctl, uctl))
+ goto __unalloc;
if (!uctl->value.integer.value[0]) {
*left = 0;
if (uinfo->count == 1)
@@ -616,12 +622,16 @@ static void snd_mixer_oss_put_volume1_vol(snd_mixer_oss_file_t *fmixer,
uctl = kzalloc(sizeof(*uctl), GFP_KERNEL);
if (uinfo == NULL || uctl == NULL)
goto __unalloc;
- snd_runtime_check(!kctl->info(kctl, uinfo), goto __unalloc);
- snd_runtime_check(uinfo->type != SNDRV_CTL_ELEM_TYPE_BOOLEAN || uinfo->value.integer.min != 0 || uinfo->value.integer.max != 1, goto __unalloc);
+ if (kctl->info(kctl, uinfo))
+ goto __unalloc;
+ if (uinfo->type == SNDRV_CTL_ELEM_TYPE_BOOLEAN &&
+ uinfo->value.integer.min == 0 && uinfo->value.integer.max == 1)
+ goto __unalloc;
uctl->value.integer.value[0] = snd_mixer_oss_conv2(left, uinfo->value.integer.min, uinfo->value.integer.max);
if (uinfo->count > 1)
uctl->value.integer.value[1] = snd_mixer_oss_conv2(right, uinfo->value.integer.min, uinfo->value.integer.max);
- snd_runtime_check((res = kctl->put(kctl, uctl)) >= 0, goto __unalloc);
+ if ((res = kctl->put(kctl, uctl)) < 0)
+ goto __unalloc;
if (res > 0)
snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE, &kctl->id);
__unalloc:
@@ -653,7 +663,8 @@ static void snd_mixer_oss_put_volume1_sw(snd_mixer_oss_file_t *fmixer,
uctl = kzalloc(sizeof(*uctl), GFP_KERNEL);
if (uinfo == NULL || uctl == NULL)
goto __unalloc;
- snd_runtime_check(!kctl->info(kctl, uinfo), goto __unalloc);
+ if (kctl->info(kctl, uinfo))
+ goto __unalloc;
if (uinfo->count > 1) {
uctl->value.integer.value[0] = left > 0 ? 1 : 0;
uctl->value.integer.value[route ? 3 : 1] = right > 0 ? 1 : 0;
@@ -664,7 +675,8 @@ static void snd_mixer_oss_put_volume1_sw(snd_mixer_oss_file_t *fmixer,
} else {
uctl->value.integer.value[0] = (left > 0 || right > 0) ? 1 : 0;
}
- snd_runtime_check((res = kctl->put(kctl, uctl)) >= 0, goto __unalloc);
+ if ((res = kctl->put(kctl, uctl)) < 0)
+ goto __unalloc;
if (res > 0)
snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE, &kctl->id);
__unalloc:
@@ -776,9 +788,14 @@ static int snd_mixer_oss_get_recsrc2(snd_mixer_oss_file_t *fmixer, unsigned int
}
down_read(&card->controls_rwsem);
kctl = snd_mixer_oss_test_id(mixer, "Capture Source", 0);
- snd_runtime_check(kctl != NULL, err = -ENOENT; goto __unlock);
- snd_runtime_check(!(err = kctl->info(kctl, uinfo)), goto __unlock);
- snd_runtime_check(!(err = kctl->get(kctl, uctl)), goto __unlock);
+ if (! kctl) {
+ err = -ENOENT;
+ goto __unlock;
+ }
+ if ((err = kctl->info(kctl, uinfo)) < 0)
+ goto __unlock;
+ if ((err = kctl->get(kctl, uctl)) < 0)
+ goto __unlock;
for (idx = 0; idx < 32; idx++) {
if (!(mixer->mask_recsrc & (1 << idx)))
continue;
@@ -821,8 +838,12 @@ static int snd_mixer_oss_put_recsrc2(snd_mixer_oss_file_t *fmixer, unsigned int
}
down_read(&card->controls_rwsem);
kctl = snd_mixer_oss_test_id(mixer, "Capture Source", 0);
- snd_runtime_check(kctl != NULL, err = -ENOENT; goto __unlock);
- snd_runtime_check(!(err = kctl->info(kctl, uinfo)), goto __unlock);
+ if (! kctl) {
+ err = -ENOENT;
+ goto __unlock;
+ }
+ if ((err = kctl->info(kctl, uinfo)) < 0)
+ goto __unlock;
for (idx = 0; idx < 32; idx++) {
if (!(mixer->mask_recsrc & (1 << idx)))
continue;
@@ -836,10 +857,11 @@ static int snd_mixer_oss_put_recsrc2(snd_mixer_oss_file_t *fmixer, unsigned int
break;
slot = NULL;
}
- snd_runtime_check(slot != NULL, goto __unlock);
+ if (! slot)
+ goto __unlock;
for (idx = 0; idx < uinfo->count; idx++)
uctl->value.enumerated.item[idx] = slot->capture_item;
- snd_runtime_check((err = kctl->put(kctl, uctl)) >= 0, );
+ err = kctl->put(kctl, uctl);
if (err > 0)
snd_ctl_notify(fmixer->card, SNDRV_CTL_EVENT_MASK_VALUE, &kctl->id);
err = 0;
@@ -1008,7 +1030,8 @@ static int snd_mixer_oss_build_input(snd_mixer_oss_t *mixer, struct snd_mixer_os
up_read(&mixer->card->controls_rwsem);
if (slot.present != 0) {
pslot = (struct slot *)kmalloc(sizeof(slot), GFP_KERNEL);
- snd_runtime_check(pslot != NULL, return -ENOMEM);
+ if (! pslot)
+ return -ENOMEM;
*pslot = slot;
pslot->signature = SNDRV_MIXER_OSS_SIGNATURE;
pslot->assigned = ptr;
@@ -1271,7 +1294,8 @@ static int snd_mixer_oss_notify_handler(snd_card_t * card, int cmd)
card, 0,
&snd_mixer_oss_reg,
name)) < 0) {
- snd_printk("unable to register OSS mixer device %i:%i\n", card->number, 0);
+ snd_printk(KERN_ERR "unable to register OSS mixer device %i:%i\n",
+ card->number, 0);
kfree(mixer);
return err;
}
diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c
index 842c28b2ed55..bcc970759134 100644
--- a/sound/core/oss/pcm_oss.c
+++ b/sound/core/oss/pcm_oss.c
@@ -1821,6 +1821,17 @@ static int snd_pcm_oss_open_file(struct file *file,
}
+static int snd_task_name(struct task_struct *task, char *name, size_t size)
+{
+ unsigned int idx;
+
+ snd_assert(task != NULL && name != NULL && size >= 2, return -EINVAL);
+ for (idx = 0; idx < sizeof(task->comm) && idx + 1 < size; idx++)
+ name[idx] = task->comm[idx];
+ name[idx] = '\0';
+ return 0;
+}
+
static int snd_pcm_oss_open(struct inode *inode, struct file *file)
{
int minor = iminor(inode);
@@ -2446,7 +2457,8 @@ static void register_oss_dsp(snd_pcm_t *pcm, int index)
if (snd_register_oss_device(SNDRV_OSS_DEVICE_TYPE_PCM,
pcm->card, index, &snd_pcm_oss_reg,
name) < 0) {
- snd_printk("unable to register OSS PCM device %i:%i\n", pcm->card->number, pcm->device);
+ snd_printk(KERN_ERR "unable to register OSS PCM device %i:%i\n",
+ pcm->card->number, pcm->device);
}
}
@@ -2528,11 +2540,13 @@ static int __init alsa_pcm_oss_init(void)
/* check device map table */
for (i = 0; i < SNDRV_CARDS; i++) {
if (dsp_map[i] < 0 || dsp_map[i] >= SNDRV_PCM_DEVICES) {
- snd_printk("invalid dsp_map[%d] = %d\n", i, dsp_map[i]);
+ snd_printk(KERN_ERR "invalid dsp_map[%d] = %d\n",
+ i, dsp_map[i]);
dsp_map[i] = 0;
}
if (adsp_map[i] < 0 || adsp_map[i] >= SNDRV_PCM_DEVICES) {
- snd_printk("invalid adsp_map[%d] = %d\n", i, adsp_map[i]);
+ snd_printk(KERN_ERR "invalid adsp_map[%d] = %d\n",
+ i, adsp_map[i]);
adsp_map[i] = 1;
}
}
diff --git a/sound/core/pcm.c b/sound/core/pcm.c
index 1be470e942ef..184e74b75ba9 100644
--- a/sound/core/pcm.c
+++ b/sound/core/pcm.c
@@ -273,7 +273,8 @@ static void snd_pcm_proc_info_read(snd_pcm_substream_t *substream, snd_info_buff
snd_pcm_info_t *info;
int err;
- snd_runtime_check(substream, return);
+ if (! substream)
+ return;
info = kmalloc(sizeof(*info), GFP_KERNEL);
if (! info) {
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c
index 0503980c23d9..3dbf9bf2ac16 100644
--- a/sound/core/pcm_lib.c
+++ b/sound/core/pcm_lib.c
@@ -152,13 +152,12 @@ static inline snd_pcm_uframes_t snd_pcm_update_hw_ptr_pos(snd_pcm_substream_t *s
if (pos == SNDRV_PCM_POS_XRUN)
return pos; /* XRUN */
if (runtime->tstamp_mode & SNDRV_PCM_TSTAMP_MMAP)
- snd_timestamp_now((snd_timestamp_t*)&runtime->status->tstamp, runtime->tstamp_timespec);
+ getnstimeofday((struct timespec *)&runtime->status->tstamp);
#ifdef CONFIG_SND_DEBUG
if (pos >= runtime->buffer_size) {
snd_printk(KERN_ERR "BUG: stream = %i, pos = 0x%lx, buffer size = 0x%lx, period size = 0x%lx\n", substream->stream, pos, runtime->buffer_size, runtime->period_size);
- } else
+ }
#endif
- snd_runtime_check(pos < runtime->buffer_size, return 0);
pos -= pos % runtime->min_align;
return pos;
}
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index 67abebabf83e..16e252f54954 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -565,9 +565,9 @@ int snd_pcm_status(snd_pcm_substream_t *substream,
if (runtime->tstamp_mode & SNDRV_PCM_TSTAMP_MMAP)
status->tstamp = runtime->status->tstamp;
else
- snd_timestamp_now(&status->tstamp, runtime->tstamp_timespec);
+ getnstimeofday(&status->tstamp);
} else
- snd_timestamp_now(&status->tstamp, runtime->tstamp_timespec);
+ getnstimeofday(&status->tstamp);
status->appl_ptr = runtime->control->appl_ptr;
status->hw_ptr = runtime->status->hw_ptr;
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
@@ -652,7 +652,7 @@ static void snd_pcm_trigger_tstamp(snd_pcm_substream_t *substream)
if (runtime->trigger_master == NULL)
return;
if (runtime->trigger_master == substream) {
- snd_timestamp_now(&runtime->trigger_tstamp, runtime->tstamp_timespec);
+ getnstimeofday(&runtime->trigger_tstamp);
} else {
snd_pcm_trigger_tstamp(runtime->trigger_master);
runtime->trigger_tstamp = runtime->trigger_master->runtime->trigger_tstamp;
@@ -1522,7 +1522,6 @@ static int snd_pcm_drop(snd_pcm_substream_t *substream)
/* WARNING: Don't forget to fput back the file */
-extern int snd_major;
static struct file *snd_pcm_file_fd(int fd)
{
struct file *file;
@@ -2053,7 +2052,8 @@ static int snd_pcm_open(struct inode *inode, struct file *file)
snd_pcm_file_t *pcm_file;
wait_queue_t wait;
- snd_runtime_check(device >= SNDRV_MINOR_PCM_PLAYBACK && device < SNDRV_MINOR_DEVICES, return -ENXIO);
+ if (device < SNDRV_MINOR_PCM_PLAYBACK || device >= SNDRV_MINOR_DEVICES)
+ return -ENXIO;
pcm = snd_pcm_devices[(cardnum * SNDRV_PCM_DEVICES) + (device % SNDRV_MINOR_PCMS)];
if (pcm == NULL) {
err = -ENODEV;
@@ -2445,14 +2445,8 @@ static int snd_pcm_common_ioctl1(snd_pcm_substream_t *substream,
return put_user(SNDRV_PCM_VERSION, (int __user *)arg) ? -EFAULT : 0;
case SNDRV_PCM_IOCTL_INFO:
return snd_pcm_info_user(substream, arg);
- case SNDRV_PCM_IOCTL_TSTAMP:
- {
- int xarg;
- if (get_user(xarg, (int __user *)arg))
- return -EFAULT;
- substream->runtime->tstamp_timespec = xarg ? 1 : 0;
+ case SNDRV_PCM_IOCTL_TSTAMP: /* just for compatibility */
return 0;
- }
case SNDRV_PCM_IOCTL_HW_REFINE:
return snd_pcm_hw_refine_user(substream, arg);
case SNDRV_PCM_IOCTL_HW_PARAMS:
@@ -2949,8 +2943,7 @@ static struct page * snd_pcm_mmap_status_nopage(struct vm_area_struct *area, uns
return NOPAGE_OOM;
runtime = substream->runtime;
page = virt_to_page(runtime->status);
- if (!PageReserved(page))
- get_page(page);
+ get_page(page);
if (type)
*type = VM_FAULT_MINOR;
return page;
@@ -2992,8 +2985,7 @@ static struct page * snd_pcm_mmap_control_nopage(struct vm_area_struct *area, un
return NOPAGE_OOM;
runtime = substream->runtime;
page = virt_to_page(runtime->control);
- if (!PageReserved(page))
- get_page(page);
+ get_page(page);
if (type)
*type = VM_FAULT_MINOR;
return page;
@@ -3066,8 +3058,7 @@ static struct page *snd_pcm_mmap_data_nopage(struct vm_area_struct *area, unsign
vaddr = runtime->dma_area + offset;
page = virt_to_page(vaddr);
}
- if (!PageReserved(page))
- get_page(page);
+ get_page(page);
if (type)
*type = VM_FAULT_MINOR;
return page;
diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c
index 7c20eafecb8a..d033e61c05c7 100644
--- a/sound/core/rawmidi.c
+++ b/sound/core/rawmidi.c
@@ -378,24 +378,20 @@ static int snd_rawmidi_open(struct inode *inode, struct file *file)
struct list_head *list;
snd_ctl_file_t *kctl;
- switch (maj) {
- case CONFIG_SND_MAJOR:
+ if (maj == snd_major) {
cardnum = SNDRV_MINOR_CARD(iminor(inode));
cardnum %= SNDRV_CARDS;
device = SNDRV_MINOR_DEVICE(iminor(inode)) - SNDRV_MINOR_RAWMIDI;
device %= SNDRV_MINOR_RAWMIDIS;
- break;
#ifdef CONFIG_SND_OSSEMUL
- case SOUND_MAJOR:
+ } else if (maj == SOUND_MAJOR) {
cardnum = SNDRV_MINOR_OSS_CARD(iminor(inode));
cardnum %= SNDRV_CARDS;
device = SNDRV_MINOR_OSS_DEVICE(iminor(inode)) == SNDRV_MINOR_OSS_MIDI ?
midi_map[cardnum] : amidi_map[cardnum];
- break;
#endif
- default:
+ } else
return -ENXIO;
- }
rmidi = snd_rawmidi_devices[(cardnum * SNDRV_RAWMIDI_DEVICES) + device];
if (rmidi == NULL)
@@ -411,7 +407,7 @@ static int snd_rawmidi_open(struct inode *inode, struct file *file)
if (err < 0)
return -ENODEV;
fflags = snd_rawmidi_file_flags(file);
- if ((file->f_flags & O_APPEND) || maj != CONFIG_SND_MAJOR) /* OSS emul? */
+ if ((file->f_flags & O_APPEND) || maj == SOUND_MAJOR) /* OSS emul? */
fflags |= SNDRV_RAWMIDI_LFLG_APPEND;
fflags |= SNDRV_RAWMIDI_LFLG_NOOPENLOCK;
rawmidi_file = kmalloc(sizeof(*rawmidi_file), GFP_KERNEL);
diff --git a/sound/core/rtctimer.c b/sound/core/rtctimer.c
index bd5d584d284d..c3c18568207e 100644
--- a/sound/core/rtctimer.c
+++ b/sound/core/rtctimer.c
@@ -60,7 +60,6 @@ static struct _snd_timer_hardware rtc_hw = {
static int rtctimer_freq = RTC_FREQ; /* frequency */
static snd_timer_t *rtctimer;
-static atomic_t rtc_inc = ATOMIC_INIT(0);
static rtc_task_t rtc_task;
@@ -94,7 +93,6 @@ rtctimer_start(snd_timer_t *timer)
snd_assert(rtc != NULL, return -EINVAL);
rtc_control(rtc, RTC_IRQP_SET, rtctimer_freq);
rtc_control(rtc, RTC_PIE_ON, 0);
- atomic_set(&rtc_inc, 0);
return 0;
}
@@ -112,12 +110,7 @@ rtctimer_stop(snd_timer_t *timer)
*/
static void rtctimer_interrupt(void *private_data)
{
- int ticks;
-
- atomic_inc(&rtc_inc);
- ticks = atomic_read(&rtc_inc);
- snd_timer_interrupt((snd_timer_t*)private_data, ticks);
- atomic_sub(ticks, &rtc_inc);
+ snd_timer_interrupt(private_data, 1);
}
@@ -126,17 +119,13 @@ static void rtctimer_interrupt(void *private_data)
*/
static int __init rtctimer_init(void)
{
- int order, err;
+ int err;
snd_timer_t *timer;
- if (rtctimer_freq < 2 || rtctimer_freq > 8192) {
- snd_printk(KERN_ERR "rtctimer: invalid frequency %d\n", rtctimer_freq);
- return -EINVAL;
- }
- for (order = 1; rtctimer_freq > order; order <<= 1)
- ;
- if (rtctimer_freq != order) {
- snd_printk(KERN_ERR "rtctimer: invalid frequency %d\n", rtctimer_freq);
+ if (rtctimer_freq < 2 || rtctimer_freq > 8192 ||
+ (rtctimer_freq & (rtctimer_freq - 1)) != 0) {
+ snd_printk(KERN_ERR "rtctimer: invalid frequency %d\n",
+ rtctimer_freq);
return -EINVAL;
}
@@ -145,6 +134,7 @@ static int __init rtctimer_init(void)
if (err < 0)
return err;
+ timer->module = THIS_MODULE;
strcpy(timer->name, "RTC timer");
timer->hw = rtc_hw;
timer->hw.resolution = NANO_SEC / rtctimer_freq;
diff --git a/sound/core/seq/instr/ainstr_gf1.c b/sound/core/seq/instr/ainstr_gf1.c
index 207c2c54bf1d..0e4df8826eed 100644
--- a/sound/core/seq/instr/ainstr_gf1.c
+++ b/sound/core/seq/instr/ainstr_gf1.c
@@ -51,7 +51,7 @@ static int snd_seq_gf1_copy_wave_from_stream(snd_gf1_ops_t *ops,
gf1_wave_t *wp, *prev;
gf1_xwave_t xp;
int err;
- unsigned int gfp_mask;
+ gfp_t gfp_mask;
unsigned int real_size;
gfp_mask = atomic ? GFP_ATOMIC : GFP_KERNEL;
@@ -144,7 +144,8 @@ static int snd_seq_gf1_put(void *private_data, snd_seq_kinstr_t *instr,
snd_gf1_ops_t *ops = (snd_gf1_ops_t *)private_data;
gf1_instrument_t *ip;
gf1_xinstrument_t ix;
- int err, gfp_mask;
+ int err;
+ gfp_t gfp_mask;
if (cmd != SNDRV_SEQ_INSTR_PUT_CMD_CREATE)
return -EINVAL;
diff --git a/sound/core/seq/instr/ainstr_iw.c b/sound/core/seq/instr/ainstr_iw.c
index 67c24c8e8e7b..7c19fbbc5d0f 100644
--- a/sound/core/seq/instr/ainstr_iw.c
+++ b/sound/core/seq/instr/ainstr_iw.c
@@ -129,7 +129,7 @@ static int snd_seq_iwffff_copy_wave_from_stream(snd_iwffff_ops_t *ops,
iwffff_wave_t *wp, *prev;
iwffff_xwave_t xp;
int err;
- unsigned int gfp_mask;
+ gfp_t gfp_mask;
unsigned int real_size;
gfp_mask = atomic ? GFP_ATOMIC : GFP_KERNEL;
@@ -236,7 +236,7 @@ static int snd_seq_iwffff_put(void *private_data, snd_seq_kinstr_t *instr,
iwffff_layer_t *lp, *prev_lp;
iwffff_xlayer_t lx;
int err;
- unsigned int gfp_mask;
+ gfp_t gfp_mask;
if (cmd != SNDRV_SEQ_INSTR_PUT_CMD_CREATE)
return -EINVAL;
diff --git a/sound/core/seq/instr/ainstr_simple.c b/sound/core/seq/instr/ainstr_simple.c
index 6183d2151034..17ab94e76073 100644
--- a/sound/core/seq/instr/ainstr_simple.c
+++ b/sound/core/seq/instr/ainstr_simple.c
@@ -57,7 +57,8 @@ static int snd_seq_simple_put(void *private_data, snd_seq_kinstr_t *instr,
snd_simple_ops_t *ops = (snd_simple_ops_t *)private_data;
simple_instrument_t *ip;
simple_xinstrument_t ix;
- int err, gfp_mask;
+ int err;
+ gfp_t gfp_mask;
unsigned int real_size;
if (cmd != SNDRV_SEQ_INSTR_PUT_CMD_CREATE)
diff --git a/sound/core/seq/seq_instr.c b/sound/core/seq/seq_instr.c
index 019d43a462d7..1d525b13ebb6 100644
--- a/sound/core/seq/seq_instr.c
+++ b/sound/core/seq/seq_instr.c
@@ -109,8 +109,7 @@ void snd_seq_instr_list_free(snd_seq_kinstr_list_t **list_ptr)
spin_lock_irqsave(&list->lock, flags);
while (instr->use) {
spin_unlock_irqrestore(&list->lock, flags);
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(1);
+ schedule_timeout_interruptible(1);
spin_lock_irqsave(&list->lock, flags);
}
spin_unlock_irqrestore(&list->lock, flags);
@@ -199,10 +198,8 @@ int snd_seq_instr_list_free_cond(snd_seq_kinstr_list_t *list,
while (flist) {
instr = flist;
flist = instr->next;
- while (instr->use) {
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(1);
- }
+ while (instr->use)
+ schedule_timeout_interruptible(1);
if (snd_seq_instr_free(instr, atomic)<0)
snd_printk(KERN_WARNING "instrument free problem\n");
instr = next;
@@ -554,8 +551,7 @@ static int instr_free(snd_seq_kinstr_ops_t *ops,
instr->ops->notify(instr->ops->private_data, instr, SNDRV_SEQ_INSTR_NOTIFY_REMOVE);
while (instr->use) {
spin_unlock_irqrestore(&list->lock, flags);
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(1);
+ schedule_timeout_interruptible(1);
spin_lock_irqsave(&list->lock, flags);
}
spin_unlock_irqrestore(&list->lock, flags);
diff --git a/sound/core/seq/seq_lock.c b/sound/core/seq/seq_lock.c
index b09cee058fa7..a837a94b2d2a 100644
--- a/sound/core/seq/seq_lock.c
+++ b/sound/core/seq/seq_lock.c
@@ -39,8 +39,7 @@ void snd_use_lock_sync_helper(snd_use_lock_t *lockp, const char *file, int line)
snd_printk(KERN_WARNING "seq_lock: timeout [%d left] in %s:%d\n", atomic_read(lockp), file, line);
break;
}
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(1);
+ schedule_timeout_uninterruptible(1);
max_count--;
}
}
diff --git a/sound/core/seq/seq_memory.c b/sound/core/seq/seq_memory.c
index d4d7d326c4b1..8416bcffa091 100644
--- a/sound/core/seq/seq_memory.c
+++ b/sound/core/seq/seq_memory.c
@@ -423,8 +423,7 @@ int snd_seq_pool_done(pool_t *pool)
snd_printk(KERN_WARNING "snd_seq_pool_done timeout: %d cells remain\n", atomic_read(&pool->counter));
break;
}
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(1);
+ schedule_timeout_uninterruptible(1);
max_count--;
}
diff --git a/sound/core/seq/seq_midi.c b/sound/core/seq/seq_midi.c
index b4674ae3bc30..f89f40f44876 100644
--- a/sound/core/seq/seq_midi.c
+++ b/sound/core/seq/seq_midi.c
@@ -449,11 +449,9 @@ snd_seq_midisynth_unregister_port(snd_seq_device_t *dev)
client->ports_per_device[device] = 0;
msynth = client->ports[device];
client->ports[device] = NULL;
- snd_runtime_check(msynth != NULL || ports <= 0, goto __skip);
for (p = 0; p < ports; p++)
snd_seq_midisynth_delete(&msynth[p]);
kfree(msynth);
- __skip:
client->num_ports--;
if (client->num_ports <= 0) {
snd_seq_delete_kernel_client(client->seq_client);
diff --git a/sound/core/seq/seq_timer.c b/sound/core/seq/seq_timer.c
index b57a3c07ff6f..65b64a7c456d 100644
--- a/sound/core/seq/seq_timer.c
+++ b/sound/core/seq/seq_timer.c
@@ -34,10 +34,15 @@ extern int seq_default_timer_device;
extern int seq_default_timer_subdevice;
extern int seq_default_timer_resolution;
+/* allowed sequencer timer frequencies, in Hz */
+#define MIN_FREQUENCY 10
+#define MAX_FREQUENCY 6250
+#define DEFAULT_FREQUENCY 1000
+
#define SKEW_BASE 0x10000 /* 16bit shift */
static void snd_seq_timer_set_tick_resolution(seq_timer_tick_t *tick,
- int tempo, int ppq, int nticks)
+ int tempo, int ppq)
{
if (tempo < 1000000)
tick->resolution = (tempo * 1000) / ppq;
@@ -51,7 +56,6 @@ static void snd_seq_timer_set_tick_resolution(seq_timer_tick_t *tick,
}
if (tick->resolution <= 0)
tick->resolution = 1;
- tick->resolution *= nticks;
snd_seq_timer_update_tick(tick, 0);
}
@@ -100,7 +104,7 @@ void snd_seq_timer_defaults(seq_timer_t * tmr)
/* setup defaults */
tmr->ppq = 96; /* 96 PPQ */
tmr->tempo = 500000; /* 120 BPM */
- snd_seq_timer_set_tick_resolution(&tmr->tick, tmr->tempo, tmr->ppq, 1);
+ snd_seq_timer_set_tick_resolution(&tmr->tick, tmr->tempo, tmr->ppq);
tmr->running = 0;
tmr->type = SNDRV_SEQ_TIMER_ALSA;
@@ -183,7 +187,7 @@ int snd_seq_timer_set_tempo(seq_timer_t * tmr, int tempo)
spin_lock_irqsave(&tmr->lock, flags);
if ((unsigned int)tempo != tmr->tempo) {
tmr->tempo = tempo;
- snd_seq_timer_set_tick_resolution(&tmr->tick, tmr->tempo, tmr->ppq, 1);
+ snd_seq_timer_set_tick_resolution(&tmr->tick, tmr->tempo, tmr->ppq);
}
spin_unlock_irqrestore(&tmr->lock, flags);
return 0;
@@ -207,7 +211,7 @@ int snd_seq_timer_set_ppq(seq_timer_t * tmr, int ppq)
}
tmr->ppq = ppq;
- snd_seq_timer_set_tick_resolution(&tmr->tick, tmr->tempo, tmr->ppq, 1);
+ snd_seq_timer_set_tick_resolution(&tmr->tick, tmr->tempo, tmr->ppq);
spin_unlock_irqrestore(&tmr->lock, flags);
return 0;
}
@@ -326,17 +330,26 @@ int snd_seq_timer_stop(seq_timer_t * tmr)
static int initialize_timer(seq_timer_t *tmr)
{
snd_timer_t *t;
+ unsigned long freq;
+
t = tmr->timeri->timer;
snd_assert(t, return -EINVAL);
+ freq = tmr->preferred_resolution;
+ if (!freq)
+ freq = DEFAULT_FREQUENCY;
+ else if (freq < MIN_FREQUENCY)
+ freq = MIN_FREQUENCY;
+ else if (freq > MAX_FREQUENCY)
+ freq = MAX_FREQUENCY;
+
tmr->ticks = 1;
- if (tmr->preferred_resolution &&
- ! (t->hw.flags & SNDRV_TIMER_HW_SLAVE)) {
+ if (!(t->hw.flags & SNDRV_TIMER_HW_SLAVE)) {
unsigned long r = t->hw.resolution;
if (! r && t->hw.c_resolution)
r = t->hw.c_resolution(t);
if (r) {
- tmr->ticks = (unsigned int)(1000000000uL / (r * tmr->preferred_resolution));
+ tmr->ticks = (unsigned int)(1000000000uL / (r * freq));
if (! tmr->ticks)
tmr->ticks = 1;
}
diff --git a/sound/core/sound.c b/sound/core/sound.c
index 9e76bddb2c0b..1139dd8ca8eb 100644
--- a/sound/core/sound.c
+++ b/sound/core/sound.c
@@ -130,7 +130,7 @@ static int snd_open(struct inode *inode, struct file *file)
struct file_operations *old_fops;
int err = 0;
- if (dev != SNDRV_MINOR_SEQUENCER && dev != SNDRV_MINOR_TIMER) {
+ if (dev != SNDRV_MINOR_GLOBAL) {
if (snd_cards[card] == NULL) {
#ifdef CONFIG_KMOD
snd_request_card(card);
@@ -231,7 +231,7 @@ int snd_register_device(int type, snd_card_t * card, int dev, snd_minor_t * reg,
devfs_mk_cdev(MKDEV(major, minor), S_IFCHR | device_mode, "snd/%s", name);
if (card)
device = card->dev;
- class_device_create(sound_class, MKDEV(major, minor), device, "%s", name);
+ class_device_create(sound_class, NULL, MKDEV(major, minor), device, "%s", name);
up(&sound_mutex);
return 0;
@@ -287,7 +287,7 @@ static void snd_minor_info_read(snd_info_entry_t *entry, snd_info_buffer_t * buf
for (card = 0; card < SNDRV_CARDS; card++) {
list_for_each(list, &snd_minors_hash[card]) {
mptr = list_entry(list, snd_minor_t, list);
- if (SNDRV_MINOR_DEVICE(mptr->number) != SNDRV_MINOR_SEQUENCER) {
+ if (SNDRV_MINOR_DEVICE(mptr->number) != SNDRV_MINOR_GLOBAL) {
if ((device = mptr->device) >= 0)
snd_iprintf(buffer, "%3i: [%i-%2i]: %s\n", mptr->number, card, device, mptr->comment);
else
@@ -350,9 +350,7 @@ static int __init alsa_sound_init(void)
devfs_remove("snd");
return -EIO;
}
- snd_memory_init();
if (snd_info_init() < 0) {
- snd_memory_done();
unregister_chrdev(major, "alsa");
devfs_remove("snd");
return -ENOMEM;
@@ -381,7 +379,6 @@ static void __exit alsa_sound_exit(void)
#endif
snd_info_minor_unregister();
snd_info_done();
- snd_memory_done();
if (unregister_chrdev(major, "alsa") != 0)
snd_printk(KERN_ERR "unable to unregister major device number %d\n", major);
devfs_remove("snd");
@@ -403,14 +400,6 @@ EXPORT_SYMBOL(snd_register_oss_device);
EXPORT_SYMBOL(snd_unregister_oss_device);
#endif
/* memory.c */
-#ifdef CONFIG_SND_DEBUG_MEMORY
-EXPORT_SYMBOL(snd_hidden_kmalloc);
-EXPORT_SYMBOL(snd_hidden_kcalloc);
-EXPORT_SYMBOL(snd_hidden_kfree);
-EXPORT_SYMBOL(snd_hidden_vmalloc);
-EXPORT_SYMBOL(snd_hidden_vfree);
-EXPORT_SYMBOL(snd_hidden_kstrdup);
-#endif
EXPORT_SYMBOL(copy_to_user_fromio);
EXPORT_SYMBOL(copy_from_user_toio);
/* init.c */
@@ -487,17 +476,10 @@ EXPORT_SYMBOL(snd_ctl_unregister_ioctl_compat);
EXPORT_SYMBOL(snd_ctl_elem_read);
EXPORT_SYMBOL(snd_ctl_elem_write);
/* misc.c */
-EXPORT_SYMBOL(snd_task_name);
+EXPORT_SYMBOL(release_and_free_resource);
#ifdef CONFIG_SND_VERBOSE_PRINTK
EXPORT_SYMBOL(snd_verbose_printk);
#endif
#if defined(CONFIG_SND_DEBUG) && defined(CONFIG_SND_VERBOSE_PRINTK)
EXPORT_SYMBOL(snd_verbose_printd);
#endif
- /* wrappers */
-#ifdef CONFIG_SND_DEBUG_MEMORY
-EXPORT_SYMBOL(snd_wrapper_kmalloc);
-EXPORT_SYMBOL(snd_wrapper_kfree);
-EXPORT_SYMBOL(snd_wrapper_vmalloc);
-EXPORT_SYMBOL(snd_wrapper_vfree);
-#endif
diff --git a/sound/core/timer.c b/sound/core/timer.c
index 22b104624084..1b90a38d10ff 100644
--- a/sound/core/timer.c
+++ b/sound/core/timer.c
@@ -55,7 +55,7 @@ MODULE_PARM_DESC(timer_limit, "Maximum global timers in system.");
typedef struct {
snd_timer_instance_t *timeri;
- int tread; /* enhanced read with timestamps and events */
+ int tread; /* enhanced read with timestamps and events */
unsigned long ticks;
unsigned long overrun;
int qhead;
@@ -95,7 +95,8 @@ static void snd_timer_reschedule(snd_timer_t * timer, unsigned long ticks_left);
* create a timer instance with the given owner string.
* when timer is not NULL, increments the module counter
*/
-static snd_timer_instance_t *snd_timer_instance_new(char *owner, snd_timer_t *timer)
+static snd_timer_instance_t *snd_timer_instance_new(char *owner,
+ snd_timer_t *timer)
{
snd_timer_instance_t *timeri;
timeri = kzalloc(sizeof(*timeri), GFP_KERNEL);
@@ -113,7 +114,7 @@ static snd_timer_instance_t *snd_timer_instance_new(char *owner, snd_timer_t *ti
INIT_LIST_HEAD(&timeri->slave_active_head);
timeri->timer = timer;
- if (timer && timer->card && !try_module_get(timer->card->module)) {
+ if (timer && !try_module_get(timer->module)) {
kfree(timeri->owner);
kfree(timeri);
return NULL;
@@ -131,7 +132,7 @@ static snd_timer_t *snd_timer_find(snd_timer_id_t *tid)
struct list_head *p;
list_for_each(p, &snd_timer_list) {
- timer = (snd_timer_t *)list_entry(p, snd_timer_t, device_list);
+ timer = list_entry(p, snd_timer_t, device_list);
if (timer->tmr_class != tid->dev_class)
continue;
@@ -186,13 +187,14 @@ static void snd_timer_check_slave(snd_timer_instance_t *slave)
/* FIXME: it's really dumb to look up all entries.. */
list_for_each(p, &snd_timer_list) {
- timer = (snd_timer_t *)list_entry(p, snd_timer_t, device_list);
+ timer = list_entry(p, snd_timer_t, device_list);
list_for_each(q, &timer->open_list_head) {
- master = (snd_timer_instance_t *)list_entry(q, snd_timer_instance_t, open_list);
+ master = list_entry(q, snd_timer_instance_t, open_list);
if (slave->slave_class == master->slave_class &&
slave->slave_id == master->slave_id) {
list_del(&slave->open_list);
- list_add_tail(&slave->open_list, &master->slave_list_head);
+ list_add_tail(&slave->open_list,
+ &master->slave_list_head);
spin_lock_irq(&slave_active_lock);
slave->master = master;
slave->timer = master->timer;
@@ -216,7 +218,7 @@ static void snd_timer_check_master(snd_timer_instance_t *master)
/* check all pending slaves */
list_for_each_safe(p, n, &snd_timer_slave_list) {
- slave = (snd_timer_instance_t *)list_entry(p, snd_timer_instance_t, open_list);
+ slave = list_entry(p, snd_timer_instance_t, open_list);
if (slave->slave_class == master->slave_class &&
slave->slave_id == master->slave_id) {
list_del(p);
@@ -225,7 +227,8 @@ static void snd_timer_check_master(snd_timer_instance_t *master)
slave->master = master;
slave->timer = master->timer;
if (slave->flags & SNDRV_TIMER_IFLG_RUNNING)
- list_add_tail(&slave->active_list, &master->slave_active_head);
+ list_add_tail(&slave->active_list,
+ &master->slave_active_head);
spin_unlock_irq(&slave_active_lock);
}
}
@@ -241,7 +244,7 @@ int snd_timer_open(snd_timer_instance_t **ti,
{
snd_timer_t *timer;
snd_timer_instance_t *timeri = NULL;
-
+
if (tid->dev_class == SNDRV_TIMER_CLASS_SLAVE) {
/* open a slave instance */
if (tid->dev_sclass <= SNDRV_TIMER_SCLASS_NONE ||
@@ -251,6 +254,10 @@ int snd_timer_open(snd_timer_instance_t **ti,
}
down(&register_mutex);
timeri = snd_timer_instance_new(owner, NULL);
+ if (!timeri) {
+ up(&register_mutex);
+ return -ENOMEM;
+ }
timeri->slave_class = tid->dev_sclass;
timeri->slave_id = tid->device;
timeri->flags |= SNDRV_TIMER_IFLG_SLAVE;
@@ -272,33 +279,36 @@ int snd_timer_open(snd_timer_instance_t **ti,
timer = snd_timer_find(tid);
}
#endif
- if (timer) {
- if (!list_empty(&timer->open_list_head)) {
- timeri = (snd_timer_instance_t *)list_entry(timer->open_list_head.next, snd_timer_instance_t, open_list);
- if (timeri->flags & SNDRV_TIMER_IFLG_EXCLUSIVE) {
- up(&register_mutex);
- return -EBUSY;
- }
- }
- timeri = snd_timer_instance_new(owner, timer);
- if (timeri) {
- timeri->slave_class = tid->dev_sclass;
- timeri->slave_id = slave_id;
- if (list_empty(&timer->open_list_head) && timer->hw.open)
- timer->hw.open(timer);
- list_add_tail(&timeri->open_list, &timer->open_list_head);
- snd_timer_check_master(timeri);
- }
- } else {
+ if (!timer) {
up(&register_mutex);
return -ENODEV;
}
+ if (!list_empty(&timer->open_list_head)) {
+ timeri = list_entry(timer->open_list_head.next,
+ snd_timer_instance_t, open_list);
+ if (timeri->flags & SNDRV_TIMER_IFLG_EXCLUSIVE) {
+ up(&register_mutex);
+ return -EBUSY;
+ }
+ }
+ timeri = snd_timer_instance_new(owner, timer);
+ if (!timeri) {
+ up(&register_mutex);
+ return -ENOMEM;
+ }
+ timeri->slave_class = tid->dev_sclass;
+ timeri->slave_id = slave_id;
+ if (list_empty(&timer->open_list_head) && timer->hw.open)
+ timer->hw.open(timer);
+ list_add_tail(&timeri->open_list, &timer->open_list_head);
+ snd_timer_check_master(timeri);
up(&register_mutex);
*ti = timeri;
return 0;
}
-static int _snd_timer_stop(snd_timer_instance_t * timeri, int keep_flag, enum sndrv_timer_event event);
+static int _snd_timer_stop(snd_timer_instance_t * timeri,
+ int keep_flag, enum sndrv_timer_event event);
/*
* close a timer instance
@@ -338,11 +348,12 @@ int snd_timer_close(snd_timer_instance_t * timeri)
spin_unlock_irq(&timer->lock);
down(&register_mutex);
list_del(&timeri->open_list);
- if (timer && list_empty(&timer->open_list_head) && timer->hw.close)
+ if (timer && list_empty(&timer->open_list_head) &&
+ timer->hw.close)
timer->hw.close(timer);
/* remove slave links */
list_for_each_safe(p, n, &timeri->slave_list_head) {
- slave = (snd_timer_instance_t *)list_entry(p, snd_timer_instance_t, open_list);
+ slave = list_entry(p, snd_timer_instance_t, open_list);
spin_lock_irq(&slave_active_lock);
_snd_timer_stop(slave, 1, SNDRV_TIMER_EVENT_RESOLUTION);
list_del(p);
@@ -357,8 +368,8 @@ int snd_timer_close(snd_timer_instance_t * timeri)
timeri->private_free(timeri);
kfree(timeri->owner);
kfree(timeri);
- if (timer && timer->card)
- module_put(timer->card->module);
+ if (timer)
+ module_put(timer->module);
return 0;
}
@@ -376,7 +387,8 @@ unsigned long snd_timer_resolution(snd_timer_instance_t * timeri)
return 0;
}
-static void snd_timer_notify1(snd_timer_instance_t *ti, enum sndrv_timer_event event)
+static void snd_timer_notify1(snd_timer_instance_t *ti,
+ enum sndrv_timer_event event)
{
snd_timer_t *timer;
unsigned long flags;
@@ -385,9 +397,11 @@ static void snd_timer_notify1(snd_timer_instance_t *ti, enum sndrv_timer_event e
struct list_head *n;
struct timespec tstamp;
- snd_timestamp_now(&tstamp, 1);
- snd_assert(event >= SNDRV_TIMER_EVENT_START && event <= SNDRV_TIMER_EVENT_PAUSE, return);
- if (event == SNDRV_TIMER_EVENT_START || event == SNDRV_TIMER_EVENT_CONTINUE)
+ getnstimeofday(&tstamp);
+ snd_assert(event >= SNDRV_TIMER_EVENT_START &&
+ event <= SNDRV_TIMER_EVENT_PAUSE, return);
+ if (event == SNDRV_TIMER_EVENT_START ||
+ event == SNDRV_TIMER_EVENT_CONTINUE)
resolution = snd_timer_resolution(ti);
if (ti->ccallback)
ti->ccallback(ti, SNDRV_TIMER_EVENT_START, &tstamp, resolution);
@@ -400,14 +414,15 @@ static void snd_timer_notify1(snd_timer_instance_t *ti, enum sndrv_timer_event e
return;
spin_lock_irqsave(&timer->lock, flags);
list_for_each(n, &ti->slave_active_head) {
- ts = (snd_timer_instance_t *)list_entry(n, snd_timer_instance_t, active_list);
+ ts = list_entry(n, snd_timer_instance_t, active_list);
if (ts->ccallback)
ts->ccallback(ti, event + 100, &tstamp, resolution);
}
spin_unlock_irqrestore(&timer->lock, flags);
}
-static int snd_timer_start1(snd_timer_t *timer, snd_timer_instance_t *timeri, unsigned long sticks)
+static int snd_timer_start1(snd_timer_t *timer, snd_timer_instance_t *timeri,
+ unsigned long sticks)
{
list_del(&timeri->active_list);
list_add_tail(&timeri->active_list, &timer->active_list_head);
@@ -434,14 +449,15 @@ static int snd_timer_start_slave(snd_timer_instance_t *timeri)
spin_lock_irqsave(&slave_active_lock, flags);
timeri->flags |= SNDRV_TIMER_IFLG_RUNNING;
if (timeri->master)
- list_add_tail(&timeri->active_list, &timeri->master->slave_active_head);
+ list_add_tail(&timeri->active_list,
+ &timeri->master->slave_active_head);
spin_unlock_irqrestore(&slave_active_lock, flags);
return 1; /* delayed start */
}
/*
* start the timer instance
- */
+ */
int snd_timer_start(snd_timer_instance_t * timeri, unsigned int ticks)
{
snd_timer_t *timer;
@@ -467,7 +483,8 @@ int snd_timer_start(snd_timer_instance_t * timeri, unsigned int ticks)
return result;
}
-static int _snd_timer_stop(snd_timer_instance_t * timeri, int keep_flag, enum sndrv_timer_event event)
+static int _snd_timer_stop(snd_timer_instance_t * timeri,
+ int keep_flag, enum sndrv_timer_event event)
{
snd_timer_t *timer;
unsigned long flags;
@@ -501,7 +518,8 @@ static int _snd_timer_stop(snd_timer_instance_t * timeri, int keep_flag, enum sn
}
}
if (!keep_flag)
- timeri->flags &= ~(SNDRV_TIMER_IFLG_RUNNING|SNDRV_TIMER_IFLG_START);
+ timeri->flags &=
+ ~(SNDRV_TIMER_IFLG_RUNNING | SNDRV_TIMER_IFLG_START);
spin_unlock_irqrestore(&timer->lock, flags);
__end:
if (event != SNDRV_TIMER_EVENT_RESOLUTION)
@@ -578,7 +596,7 @@ static void snd_timer_reschedule(snd_timer_t * timer, unsigned long ticks_left)
struct list_head *p;
list_for_each(p, &timer->active_list_head) {
- ti = (snd_timer_instance_t *)list_entry(p, snd_timer_instance_t, active_list);
+ ti = list_entry(p, snd_timer_instance_t, active_list);
if (ti->flags & SNDRV_TIMER_IFLG_START) {
ti->flags &= ~SNDRV_TIMER_IFLG_START;
ti->flags |= SNDRV_TIMER_IFLG_RUNNING;
@@ -615,11 +633,11 @@ static void snd_timer_tasklet(unsigned long arg)
/* now process all callbacks */
while (!list_empty(&timer->sack_list_head)) {
p = timer->sack_list_head.next; /* get first item */
- ti = (snd_timer_instance_t *)list_entry(p, snd_timer_instance_t, ack_list);
+ ti = list_entry(p, snd_timer_instance_t, ack_list);
/* remove from ack_list and make empty */
list_del_init(p);
-
+
ticks = ti->pticks;
ti->pticks = 0;
resolution = ti->resolution;
@@ -644,7 +662,7 @@ void snd_timer_interrupt(snd_timer_t * timer, unsigned long ticks_left)
{
snd_timer_instance_t *ti, *ts;
unsigned long resolution, ticks;
- struct list_head *p, *q, *n;
+ struct list_head *p, *q, *n, *ack_list_head;
int use_tasklet = 0;
if (timer == NULL)
@@ -659,11 +677,12 @@ void snd_timer_interrupt(snd_timer_t * timer, unsigned long ticks_left)
resolution = timer->hw.resolution;
/* loop for all active instances
- * here we cannot use list_for_each because the active_list of a processed
- * instance is relinked to done_list_head before callback is called.
+ * Here we cannot use list_for_each because the active_list of a
+ * processed instance is relinked to done_list_head before the callback
+ * is called.
*/
list_for_each_safe(p, n, &timer->active_list_head) {
- ti = (snd_timer_instance_t *)list_entry(p, snd_timer_instance_t, active_list);
+ ti = list_entry(p, snd_timer_instance_t, active_list);
if (!(ti->flags & SNDRV_TIMER_IFLG_RUNNING))
continue;
ti->pticks += ticks_left;
@@ -681,26 +700,19 @@ void snd_timer_interrupt(snd_timer_t * timer, unsigned long ticks_left)
if (--timer->running)
list_del(p);
}
- if (list_empty(&ti->ack_list)) {
- if ((timer->hw.flags & SNDRV_TIMER_HW_TASKLET) ||
- (ti->flags & SNDRV_TIMER_IFLG_FAST)) {
- list_add_tail(&ti->ack_list, &timer->ack_list_head);
- } else {
- list_add_tail(&ti->ack_list, &timer->sack_list_head);
- }
- }
+ if ((timer->hw.flags & SNDRV_TIMER_HW_TASKLET) ||
+ (ti->flags & SNDRV_TIMER_IFLG_FAST))
+ ack_list_head = &timer->ack_list_head;
+ else
+ ack_list_head = &timer->sack_list_head;
+ if (list_empty(&ti->ack_list))
+ list_add_tail(&ti->ack_list, ack_list_head);
list_for_each(q, &ti->slave_active_head) {
- ts = (snd_timer_instance_t *)list_entry(q, snd_timer_instance_t, active_list);
+ ts = list_entry(q, snd_timer_instance_t, active_list);
ts->pticks = ti->pticks;
ts->resolution = resolution;
- if (list_empty(&ts->ack_list)) {
- if ((timer->hw.flags & SNDRV_TIMER_HW_TASKLET) ||
- (ti->flags & SNDRV_TIMER_IFLG_FAST)) {
- list_add_tail(&ts->ack_list, &timer->ack_list_head);
- } else {
- list_add_tail(&ts->ack_list, &timer->sack_list_head);
- }
- }
+ if (list_empty(&ts->ack_list))
+ list_add_tail(&ts->ack_list, ack_list_head);
}
}
if (timer->flags & SNDRV_TIMER_FLG_RESCHED)
@@ -723,11 +735,11 @@ void snd_timer_interrupt(snd_timer_t * timer, unsigned long ticks_left)
/* now process all fast callbacks */
while (!list_empty(&timer->ack_list_head)) {
p = timer->ack_list_head.next; /* get first item */
- ti = (snd_timer_instance_t *)list_entry(p, snd_timer_instance_t, ack_list);
-
+ ti = list_entry(p, snd_timer_instance_t, ack_list);
+
/* remove from ack_list and make empty */
list_del_init(p);
-
+
ticks = ti->pticks;
ti->pticks = 0;
@@ -751,7 +763,8 @@ void snd_timer_interrupt(snd_timer_t * timer, unsigned long ticks_left)
*/
-int snd_timer_new(snd_card_t *card, char *id, snd_timer_id_t *tid, snd_timer_t ** rtimer)
+int snd_timer_new(snd_card_t *card, char *id, snd_timer_id_t *tid,
+ snd_timer_t **rtimer)
{
snd_timer_t *timer;
int err;
@@ -779,9 +792,12 @@ int snd_timer_new(snd_card_t *card, char *id, snd_timer_id_t *tid, snd_timer_t *
INIT_LIST_HEAD(&timer->ack_list_head);
INIT_LIST_HEAD(&timer->sack_list_head);
spin_lock_init(&timer->lock);
- tasklet_init(&timer->task_queue, snd_timer_tasklet, (unsigned long)timer);
+ tasklet_init(&timer->task_queue, snd_timer_tasklet,
+ (unsigned long)timer);
if (card != NULL) {
- if ((err = snd_device_new(card, SNDRV_DEV_TIMER, timer, &ops)) < 0) {
+ timer->module = card->module;
+ err = snd_device_new(card, SNDRV_DEV_TIMER, timer, &ops);
+ if (err < 0) {
snd_timer_free(timer);
return err;
}
@@ -811,14 +827,15 @@ static int snd_timer_dev_register(snd_device_t *dev)
snd_timer_t *timer1;
struct list_head *p;
- snd_assert(timer != NULL && timer->hw.start != NULL && timer->hw.stop != NULL, return -ENXIO);
+ snd_assert(timer != NULL && timer->hw.start != NULL &&
+ timer->hw.stop != NULL, return -ENXIO);
if (!(timer->hw.flags & SNDRV_TIMER_HW_SLAVE) &&
!timer->hw.resolution && timer->hw.c_resolution == NULL)
return -EINVAL;
down(&register_mutex);
list_for_each(p, &snd_timer_list) {
- timer1 = (snd_timer_t *)list_entry(p, snd_timer_t, device_list);
+ timer1 = list_entry(p, snd_timer_t, device_list);
if (timer1->tmr_class > timer->tmr_class)
break;
if (timer1->tmr_class < timer->tmr_class)
@@ -857,7 +874,7 @@ static int snd_timer_unregister(snd_timer_t *timer)
snd_printk(KERN_WARNING "timer 0x%lx is busy?\n", (long)timer);
list_for_each_safe(p, n, &timer->open_list_head) {
list_del_init(p);
- ti = (snd_timer_instance_t *)list_entry(p, snd_timer_instance_t, open_list);
+ ti = list_entry(p, snd_timer_instance_t, open_list);
ti->timer = NULL;
}
}
@@ -872,15 +889,18 @@ static int snd_timer_dev_unregister(snd_device_t *device)
return snd_timer_unregister(timer);
}
-void snd_timer_notify(snd_timer_t *timer, enum sndrv_timer_event event, struct timespec *tstamp)
+void snd_timer_notify(snd_timer_t *timer, enum sndrv_timer_event event,
+ struct timespec *tstamp)
{
unsigned long flags;
unsigned long resolution = 0;
snd_timer_instance_t *ti, *ts;
struct list_head *p, *n;
- snd_runtime_check(timer->hw.flags & SNDRV_TIMER_HW_SLAVE, return);
- snd_assert(event >= SNDRV_TIMER_EVENT_MSTART && event <= SNDRV_TIMER_EVENT_MRESUME, return);
+ if (! (timer->hw.flags & SNDRV_TIMER_HW_SLAVE))
+ return;
+ snd_assert(event >= SNDRV_TIMER_EVENT_MSTART &&
+ event <= SNDRV_TIMER_EVENT_MRESUME, return);
spin_lock_irqsave(&timer->lock, flags);
if (event == SNDRV_TIMER_EVENT_MSTART ||
event == SNDRV_TIMER_EVENT_MCONTINUE ||
@@ -891,11 +911,11 @@ void snd_timer_notify(snd_timer_t *timer, enum sndrv_timer_event event, struct t
resolution = timer->hw.resolution;
}
list_for_each(p, &timer->active_list_head) {
- ti = (snd_timer_instance_t *)list_entry(p, snd_timer_instance_t, active_list);
+ ti = list_entry(p, snd_timer_instance_t, active_list);
if (ti->ccallback)
ti->ccallback(ti, event, tstamp, resolution);
list_for_each(n, &ti->slave_active_head) {
- ts = (snd_timer_instance_t *)list_entry(n, snd_timer_instance_t, active_list);
+ ts = list_entry(n, snd_timer_instance_t, active_list);
if (ts->ccallback)
ts->ccallback(ts, event, tstamp, resolution);
}
@@ -909,7 +929,7 @@ void snd_timer_notify(snd_timer_t *timer, enum sndrv_timer_event event, struct t
int snd_timer_global_new(char *id, int device, snd_timer_t **rtimer)
{
snd_timer_id_t tid;
-
+
tid.dev_class = SNDRV_TIMER_CLASS_GLOBAL;
tid.dev_sclass = SNDRV_TIMER_SCLASS_NONE;
tid.card = -1;
@@ -937,7 +957,7 @@ int snd_timer_global_unregister(snd_timer_t *timer)
return snd_timer_unregister(timer);
}
-/*
+/*
* System timer
*/
@@ -1013,7 +1033,8 @@ static int snd_timer_register_system(void)
struct snd_timer_system_private *priv;
int err;
- if ((err = snd_timer_global_new("system", SNDRV_TIMER_GLOBAL_SYSTEM, &timer)) < 0)
+ err = snd_timer_global_new("system", SNDRV_TIMER_GLOBAL_SYSTEM, &timer);
+ if (err < 0)
return err;
strcpy(timer->name, "system timer");
timer->hw = snd_timer_system;
@@ -1044,33 +1065,41 @@ static void snd_timer_proc_read(snd_info_entry_t *entry,
down(&register_mutex);
list_for_each(p, &snd_timer_list) {
- timer = (snd_timer_t *)list_entry(p, snd_timer_t, device_list);
+ timer = list_entry(p, snd_timer_t, device_list);
switch (timer->tmr_class) {
case SNDRV_TIMER_CLASS_GLOBAL:
snd_iprintf(buffer, "G%i: ", timer->tmr_device);
break;
case SNDRV_TIMER_CLASS_CARD:
- snd_iprintf(buffer, "C%i-%i: ", timer->card->number, timer->tmr_device);
+ snd_iprintf(buffer, "C%i-%i: ",
+ timer->card->number, timer->tmr_device);
break;
case SNDRV_TIMER_CLASS_PCM:
- snd_iprintf(buffer, "P%i-%i-%i: ", timer->card->number, timer->tmr_device, timer->tmr_subdevice);
+ snd_iprintf(buffer, "P%i-%i-%i: ", timer->card->number,
+ timer->tmr_device, timer->tmr_subdevice);
break;
default:
- snd_iprintf(buffer, "?%i-%i-%i-%i: ", timer->tmr_class, timer->card ? timer->card->number : -1, timer->tmr_device, timer->tmr_subdevice);
+ snd_iprintf(buffer, "?%i-%i-%i-%i: ", timer->tmr_class,
+ timer->card ? timer->card->number : -1,
+ timer->tmr_device, timer->tmr_subdevice);
}
snd_iprintf(buffer, "%s :", timer->name);
if (timer->hw.resolution)
- snd_iprintf(buffer, " %lu.%03luus (%lu ticks)", timer->hw.resolution / 1000, timer->hw.resolution % 1000, timer->hw.ticks);
+ snd_iprintf(buffer, " %lu.%03luus (%lu ticks)",
+ timer->hw.resolution / 1000,
+ timer->hw.resolution % 1000,
+ timer->hw.ticks);
if (timer->hw.flags & SNDRV_TIMER_HW_SLAVE)
snd_iprintf(buffer, " SLAVE");
snd_iprintf(buffer, "\n");
spin_lock_irqsave(&timer->lock, flags);
list_for_each(q, &timer->open_list_head) {
- ti = (snd_timer_instance_t *)list_entry(q, snd_timer_instance_t, open_list);
- snd_iprintf(buffer, " Client %s : %s : lost interrupts %li\n",
- ti->owner ? ti->owner : "unknown",
- ti->flags & (SNDRV_TIMER_IFLG_START|SNDRV_TIMER_IFLG_RUNNING) ? "running" : "stopped",
- ti->lost);
+ ti = list_entry(q, snd_timer_instance_t, open_list);
+ snd_iprintf(buffer, " Client %s : %s\n",
+ ti->owner ? ti->owner : "unknown",
+ ti->flags & (SNDRV_TIMER_IFLG_START |
+ SNDRV_TIMER_IFLG_RUNNING)
+ ? "running" : "stopped");
}
spin_unlock_irqrestore(&timer->lock, flags);
}
@@ -1088,7 +1117,7 @@ static void snd_timer_user_interrupt(snd_timer_instance_t *timeri,
snd_timer_user_t *tu = timeri->callback_data;
snd_timer_read_t *r;
int prev;
-
+
spin_lock(&tu->qlock);
if (tu->qused > 0) {
prev = tu->qtail == 0 ? tu->queue_size - 1 : tu->qtail - 1;
@@ -1113,7 +1142,8 @@ static void snd_timer_user_interrupt(snd_timer_instance_t *timeri,
wake_up(&tu->qchange_sleep);
}
-static void snd_timer_user_append_to_tqueue(snd_timer_user_t *tu, snd_timer_tread_t *tread)
+static void snd_timer_user_append_to_tqueue(snd_timer_user_t *tu,
+ snd_timer_tread_t *tread)
{
if (tu->qused >= tu->queue_size) {
tu->overrun++;
@@ -1132,7 +1162,8 @@ static void snd_timer_user_ccallback(snd_timer_instance_t *timeri,
snd_timer_user_t *tu = timeri->callback_data;
snd_timer_tread_t r1;
- if (event >= SNDRV_TIMER_EVENT_START && event <= SNDRV_TIMER_EVENT_PAUSE)
+ if (event >= SNDRV_TIMER_EVENT_START &&
+ event <= SNDRV_TIMER_EVENT_PAUSE)
tu->tstamp = *tstamp;
if ((tu->filter & (1 << event)) == 0 || !tu->tread)
return;
@@ -1155,15 +1186,17 @@ static void snd_timer_user_tinterrupt(snd_timer_instance_t *timeri,
struct timespec tstamp;
int prev, append = 0;
- snd_timestamp_zero(&tstamp);
+ memset(&tstamp, 0, sizeof(tstamp));
spin_lock(&tu->qlock);
- if ((tu->filter & ((1 << SNDRV_TIMER_EVENT_RESOLUTION)|(1 << SNDRV_TIMER_EVENT_TICK))) == 0) {
+ if ((tu->filter & ((1 << SNDRV_TIMER_EVENT_RESOLUTION) |
+ (1 << SNDRV_TIMER_EVENT_TICK))) == 0) {
spin_unlock(&tu->qlock);
return;
}
if (tu->last_resolution != resolution || ticks > 0)
- snd_timestamp_now(&tstamp, 1);
- if ((tu->filter & (1 << SNDRV_TIMER_EVENT_RESOLUTION)) && tu->last_resolution != resolution) {
+ getnstimeofday(&tstamp);
+ if ((tu->filter & (1 << SNDRV_TIMER_EVENT_RESOLUTION)) &&
+ tu->last_resolution != resolution) {
r1.event = SNDRV_TIMER_EVENT_RESOLUTION;
r1.tstamp = tstamp;
r1.val = resolution;
@@ -1201,7 +1234,7 @@ static void snd_timer_user_tinterrupt(snd_timer_instance_t *timeri,
static int snd_timer_user_open(struct inode *inode, struct file *file)
{
snd_timer_user_t *tu;
-
+
tu = kzalloc(sizeof(*tu), GFP_KERNEL);
if (tu == NULL)
return -ENOMEM;
@@ -1210,7 +1243,8 @@ static int snd_timer_user_open(struct inode *inode, struct file *file)
init_MUTEX(&tu->tread_sem);
tu->ticks = 1;
tu->queue_size = 128;
- tu->queue = (snd_timer_read_t *)kmalloc(tu->queue_size * sizeof(snd_timer_read_t), GFP_KERNEL);
+ tu->queue = kmalloc(tu->queue_size * sizeof(snd_timer_read_t),
+ GFP_KERNEL);
if (tu->queue == NULL) {
kfree(tu);
return -ENOMEM;
@@ -1259,7 +1293,7 @@ static int snd_timer_user_next_device(snd_timer_id_t __user *_tid)
snd_timer_id_t id;
snd_timer_t *timer;
struct list_head *p;
-
+
if (copy_from_user(&id, _tid, sizeof(id)))
return -EFAULT;
down(&register_mutex);
@@ -1267,7 +1301,8 @@ static int snd_timer_user_next_device(snd_timer_id_t __user *_tid)
if (list_empty(&snd_timer_list))
snd_timer_user_zero_id(&id);
else {
- timer = (snd_timer_t *)list_entry(snd_timer_list.next, snd_timer_t, device_list);
+ timer = list_entry(snd_timer_list.next,
+ snd_timer_t, device_list);
snd_timer_user_copy_id(&id, timer);
}
} else {
@@ -1275,7 +1310,7 @@ static int snd_timer_user_next_device(snd_timer_id_t __user *_tid)
case SNDRV_TIMER_CLASS_GLOBAL:
id.device = id.device < 0 ? 0 : id.device + 1;
list_for_each(p, &snd_timer_list) {
- timer = (snd_timer_t *)list_entry(p, snd_timer_t, device_list);
+ timer = list_entry(p, snd_timer_t, device_list);
if (timer->tmr_class > SNDRV_TIMER_CLASS_GLOBAL) {
snd_timer_user_copy_id(&id, timer);
break;
@@ -1299,12 +1334,16 @@ static int snd_timer_user_next_device(snd_timer_id_t __user *_tid)
if (id.device < 0) {
id.device = 0;
} else {
- id.subdevice = id.subdevice < 0 ? 0 : id.subdevice + 1;
+ if (id.subdevice < 0) {
+ id.subdevice = 0;
+ } else {
+ id.subdevice++;
+ }
}
}
}
list_for_each(p, &snd_timer_list) {
- timer = (snd_timer_t *)list_entry(p, snd_timer_t, device_list);
+ timer = list_entry(p, snd_timer_t, device_list);
if (timer->tmr_class > id.dev_class) {
snd_timer_user_copy_id(&id, timer);
break;
@@ -1343,9 +1382,10 @@ static int snd_timer_user_next_device(snd_timer_id_t __user *_tid)
if (copy_to_user(_tid, &id, sizeof(*_tid)))
return -EFAULT;
return 0;
-}
+}
-static int snd_timer_user_ginfo(struct file *file, snd_timer_ginfo_t __user *_ginfo)
+static int snd_timer_user_ginfo(struct file *file,
+ snd_timer_ginfo_t __user *_ginfo)
{
snd_timer_ginfo_t *ginfo;
snd_timer_id_t tid;
@@ -1389,7 +1429,8 @@ static int snd_timer_user_ginfo(struct file *file, snd_timer_ginfo_t __user *_gi
return err;
}
-static int snd_timer_user_gparams(struct file *file, snd_timer_gparams_t __user *_gparams)
+static int snd_timer_user_gparams(struct file *file,
+ snd_timer_gparams_t __user *_gparams)
{
snd_timer_gparams_t gparams;
snd_timer_t *t;
@@ -1399,23 +1440,26 @@ static int snd_timer_user_gparams(struct file *file, snd_timer_gparams_t __user
return -EFAULT;
down(&register_mutex);
t = snd_timer_find(&gparams.tid);
- if (t != NULL) {
- if (list_empty(&t->open_list_head)) {
- if (t->hw.set_period)
- err = t->hw.set_period(t, gparams.period_num, gparams.period_den);
- else
- err = -ENOSYS;
- } else {
- err = -EBUSY;
- }
- } else {
+ if (!t) {
err = -ENODEV;
+ goto _error;
+ }
+ if (!list_empty(&t->open_list_head)) {
+ err = -EBUSY;
+ goto _error;
}
+ if (!t->hw.set_period) {
+ err = -ENOSYS;
+ goto _error;
+ }
+ err = t->hw.set_period(t, gparams.period_num, gparams.period_den);
+_error:
up(&register_mutex);
return err;
}
-static int snd_timer_user_gstatus(struct file *file, snd_timer_gstatus_t __user *_gstatus)
+static int snd_timer_user_gstatus(struct file *file,
+ snd_timer_gstatus_t __user *_gstatus)
{
snd_timer_gstatus_t gstatus;
snd_timer_id_t tid;
@@ -1435,7 +1479,8 @@ static int snd_timer_user_gstatus(struct file *file, snd_timer_gstatus_t __user
else
gstatus.resolution = t->hw.resolution;
if (t->hw.precise_resolution) {
- t->hw.precise_resolution(t, &gstatus.resolution_num, &gstatus.resolution_den);
+ t->hw.precise_resolution(t, &gstatus.resolution_num,
+ &gstatus.resolution_den);
} else {
gstatus.resolution_num = gstatus.resolution;
gstatus.resolution_den = 1000000000uL;
@@ -1449,13 +1494,14 @@ static int snd_timer_user_gstatus(struct file *file, snd_timer_gstatus_t __user
return err;
}
-static int snd_timer_user_tselect(struct file *file, snd_timer_select_t __user *_tselect)
+static int snd_timer_user_tselect(struct file *file,
+ snd_timer_select_t __user *_tselect)
{
snd_timer_user_t *tu;
snd_timer_select_t tselect;
char str[32];
int err = 0;
-
+
tu = file->private_data;
down(&tu->tread_sem);
if (tu->timeri) {
@@ -1469,7 +1515,8 @@ static int snd_timer_user_tselect(struct file *file, snd_timer_select_t __user *
sprintf(str, "application %i", current->pid);
if (tselect.id.dev_class != SNDRV_TIMER_CLASS_SLAVE)
tselect.id.dev_sclass = SNDRV_TIMER_SCLASS_APPLICATION;
- if ((err = snd_timer_open(&tu->timeri, str, &tselect.id, current->pid)) < 0)
+ err = snd_timer_open(&tu->timeri, str, &tselect.id, current->pid);
+ if (err < 0)
goto __err;
kfree(tu->queue);
@@ -1477,21 +1524,24 @@ static int snd_timer_user_tselect(struct file *file, snd_timer_select_t __user *
kfree(tu->tqueue);
tu->tqueue = NULL;
if (tu->tread) {
- tu->tqueue = (snd_timer_tread_t *)kmalloc(tu->queue_size * sizeof(snd_timer_tread_t), GFP_KERNEL);
+ tu->tqueue = kmalloc(tu->queue_size * sizeof(snd_timer_tread_t),
+ GFP_KERNEL);
if (tu->tqueue == NULL)
err = -ENOMEM;
} else {
- tu->queue = (snd_timer_read_t *)kmalloc(tu->queue_size * sizeof(snd_timer_read_t), GFP_KERNEL);
+ tu->queue = kmalloc(tu->queue_size * sizeof(snd_timer_read_t),
+ GFP_KERNEL);
if (tu->queue == NULL)
err = -ENOMEM;
}
-
+
if (err < 0) {
snd_timer_close(tu->timeri);
tu->timeri = NULL;
} else {
tu->timeri->flags |= SNDRV_TIMER_IFLG_FAST;
- tu->timeri->callback = tu->tread ? snd_timer_user_tinterrupt : snd_timer_user_interrupt;
+ tu->timeri->callback = tu->tread
+ ? snd_timer_user_tinterrupt : snd_timer_user_interrupt;
tu->timeri->ccallback = snd_timer_user_ccallback;
tu->timeri->callback_data = (void *)tu;
}
@@ -1501,7 +1551,8 @@ static int snd_timer_user_tselect(struct file *file, snd_timer_select_t __user *
return err;
}
-static int snd_timer_user_info(struct file *file, snd_timer_info_t __user *_info)
+static int snd_timer_user_info(struct file *file,
+ snd_timer_info_t __user *_info)
{
snd_timer_user_t *tu;
snd_timer_info_t *info;
@@ -1528,7 +1579,8 @@ static int snd_timer_user_info(struct file *file, snd_timer_info_t __user *_info
return err;
}
-static int snd_timer_user_params(struct file *file, snd_timer_params_t __user *_params)
+static int snd_timer_user_params(struct file *file,
+ snd_timer_params_t __user *_params)
{
snd_timer_user_t *tu;
snd_timer_params_t params;
@@ -1536,7 +1588,7 @@ static int snd_timer_user_params(struct file *file, snd_timer_params_t __user *_
snd_timer_read_t *tr;
snd_timer_tread_t *ttr;
int err;
-
+
tu = file->private_data;
snd_assert(tu->timeri != NULL, return -ENXIO);
t = tu->timeri->timer;
@@ -1547,7 +1599,8 @@ static int snd_timer_user_params(struct file *file, snd_timer_params_t __user *_
err = -EINVAL;
goto _end;
}
- if (params.queue_size > 0 && (params.queue_size < 32 || params.queue_size > 1024)) {
+ if (params.queue_size > 0 &&
+ (params.queue_size < 32 || params.queue_size > 1024)) {
err = -EINVAL;
goto _end;
}
@@ -1580,16 +1633,19 @@ static int snd_timer_user_params(struct file *file, snd_timer_params_t __user *_
if (params.flags & SNDRV_TIMER_PSFLG_EARLY_EVENT)
tu->timeri->flags |= SNDRV_TIMER_IFLG_EARLY_EVENT;
spin_unlock_irq(&t->lock);
- if (params.queue_size > 0 && (unsigned int)tu->queue_size != params.queue_size) {
+ if (params.queue_size > 0 &&
+ (unsigned int)tu->queue_size != params.queue_size) {
if (tu->tread) {
- ttr = (snd_timer_tread_t *)kmalloc(params.queue_size * sizeof(snd_timer_tread_t), GFP_KERNEL);
+ ttr = kmalloc(params.queue_size * sizeof(*ttr),
+ GFP_KERNEL);
if (ttr) {
kfree(tu->tqueue);
tu->queue_size = params.queue_size;
tu->tqueue = ttr;
}
} else {
- tr = (snd_timer_read_t *)kmalloc(params.queue_size * sizeof(snd_timer_read_t), GFP_KERNEL);
+ tr = kmalloc(params.queue_size * sizeof(*tr),
+ GFP_KERNEL);
if (tr) {
kfree(tu->queue);
tu->queue_size = params.queue_size;
@@ -1613,7 +1669,6 @@ static int snd_timer_user_params(struct file *file, snd_timer_params_t __user *_
tu->qused++;
tu->qtail++;
}
-
}
tu->filter = params.filter;
tu->ticks = params.ticks;
@@ -1624,11 +1679,12 @@ static int snd_timer_user_params(struct file *file, snd_timer_params_t __user *_
return err;
}
-static int snd_timer_user_status(struct file *file, snd_timer_status_t __user *_status)
+static int snd_timer_user_status(struct file *file,
+ snd_timer_status_t __user *_status)
{
snd_timer_user_t *tu;
snd_timer_status_t status;
-
+
tu = file->private_data;
snd_assert(tu->timeri != NULL, return -ENXIO);
memset(&status, 0, sizeof(status));
@@ -1648,7 +1704,7 @@ static int snd_timer_user_start(struct file *file)
{
int err;
snd_timer_user_t *tu;
-
+
tu = file->private_data;
snd_assert(tu->timeri != NULL, return -ENXIO);
snd_timer_stop(tu->timeri);
@@ -1661,7 +1717,7 @@ static int snd_timer_user_stop(struct file *file)
{
int err;
snd_timer_user_t *tu;
-
+
tu = file->private_data;
snd_assert(tu->timeri != NULL, return -ENXIO);
return (err = snd_timer_stop(tu->timeri)) < 0 ? err : 0;
@@ -1671,7 +1727,7 @@ static int snd_timer_user_continue(struct file *file)
{
int err;
snd_timer_user_t *tu;
-
+
tu = file->private_data;
snd_assert(tu->timeri != NULL, return -ENXIO);
tu->timeri->lost = 0;
@@ -1682,7 +1738,7 @@ static int snd_timer_user_pause(struct file *file)
{
int err;
snd_timer_user_t *tu;
-
+
tu = file->private_data;
snd_assert(tu->timeri != NULL, return -ENXIO);
return (err = snd_timer_pause(tu->timeri)) < 0 ? err : 0;
@@ -1695,12 +1751,13 @@ enum {
SNDRV_TIMER_IOCTL_PAUSE_OLD = _IO('T', 0x23),
};
-static long snd_timer_user_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+static long snd_timer_user_ioctl(struct file *file, unsigned int cmd,
+ unsigned long arg)
{
snd_timer_user_t *tu;
void __user *argp = (void __user *)arg;
int __user *p = argp;
-
+
tu = file->private_data;
switch (cmd) {
case SNDRV_TIMER_IOCTL_PVERSION:
@@ -1710,7 +1767,7 @@ static long snd_timer_user_ioctl(struct file *file, unsigned int cmd, unsigned l
case SNDRV_TIMER_IOCTL_TREAD:
{
int xarg;
-
+
down(&tu->tread_sem);
if (tu->timeri) { /* too late */
up(&tu->tread_sem);
@@ -1758,7 +1815,7 @@ static int snd_timer_user_fasync(int fd, struct file * file, int on)
{
snd_timer_user_t *tu;
int err;
-
+
tu = file->private_data;
err = fasync_helper(fd, file, on, &tu->fasync);
if (err < 0)
@@ -1766,12 +1823,13 @@ static int snd_timer_user_fasync(int fd, struct file * file, int on)
return 0;
}
-static ssize_t snd_timer_user_read(struct file *file, char __user *buffer, size_t count, loff_t *offset)
+static ssize_t snd_timer_user_read(struct file *file, char __user *buffer,
+ size_t count, loff_t *offset)
{
snd_timer_user_t *tu;
long result = 0, unit;
int err = 0;
-
+
tu = file->private_data;
unit = tu->tread ? sizeof(snd_timer_tread_t) : sizeof(snd_timer_read_t);
spin_lock_irq(&tu->qlock);
@@ -1805,12 +1863,14 @@ static ssize_t snd_timer_user_read(struct file *file, char __user *buffer, size_
goto _error;
if (tu->tread) {
- if (copy_to_user(buffer, &tu->tqueue[tu->qhead++], sizeof(snd_timer_tread_t))) {
+ if (copy_to_user(buffer, &tu->tqueue[tu->qhead++],
+ sizeof(snd_timer_tread_t))) {
err = -EFAULT;
goto _error;
}
} else {
- if (copy_to_user(buffer, &tu->queue[tu->qhead++], sizeof(snd_timer_read_t))) {
+ if (copy_to_user(buffer, &tu->queue[tu->qhead++],
+ sizeof(snd_timer_read_t))) {
err = -EFAULT;
goto _error;
}
@@ -1837,7 +1897,7 @@ static unsigned int snd_timer_user_poll(struct file *file, poll_table * wait)
tu = file->private_data;
poll_wait(file, &tu->qchange_sleep, wait);
-
+
mask = 0;
if (tu->qused)
mask |= POLLIN | POLLRDNORM;
@@ -1881,9 +1941,11 @@ static int __init alsa_timer_init(void)
snd_info_entry_t *entry;
#ifdef SNDRV_OSS_INFO_DEV_TIMERS
- snd_oss_info_register(SNDRV_OSS_INFO_DEV_TIMERS, SNDRV_CARDS - 1, "system timer");
+ snd_oss_info_register(SNDRV_OSS_INFO_DEV_TIMERS, SNDRV_CARDS - 1,
+ "system timer");
#endif
- if ((entry = snd_info_create_module_entry(THIS_MODULE, "timers", NULL)) != NULL) {
+ entry = snd_info_create_module_entry(THIS_MODULE, "timers", NULL);
+ if (entry != NULL) {
entry->c.text.read_size = SNDRV_TIMER_DEVICES * 128;
entry->c.text.read = snd_timer_proc_read;
if (snd_info_register(entry) < 0) {
@@ -1893,10 +1955,12 @@ static int __init alsa_timer_init(void)
}
snd_timer_proc_entry = entry;
if ((err = snd_timer_register_system()) < 0)
- snd_printk(KERN_ERR "unable to register system timer (%i)\n", err);
+ snd_printk(KERN_ERR "unable to register system timer (%i)\n",
+ err);
if ((err = snd_register_device(SNDRV_DEVICE_TYPE_TIMER,
NULL, 0, &snd_timer_reg, "timer"))<0)
- snd_printk(KERN_ERR "unable to register timer device (%i)\n", err);
+ snd_printk(KERN_ERR "unable to register timer device (%i)\n",
+ err);
return 0;
}
@@ -1907,7 +1971,7 @@ static void __exit alsa_timer_exit(void)
snd_unregister_device(SNDRV_DEVICE_TYPE_TIMER, NULL, 0);
/* unregister the system timer */
list_for_each_safe(p, n, &snd_timer_list) {
- snd_timer_t *timer = (snd_timer_t *)list_entry(p, snd_timer_t, device_list);
+ snd_timer_t *timer = list_entry(p, snd_timer_t, device_list);
snd_timer_unregister(timer);
}
if (snd_timer_proc_entry) {
diff --git a/sound/core/wrappers.c b/sound/core/wrappers.c
deleted file mode 100644
index 296b716f1376..000000000000
--- a/sound/core/wrappers.c
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Various wrappers
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * 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/config.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/ioport.h>
-#include <linux/vmalloc.h>
-#include <linux/fs.h>
-
-#ifdef CONFIG_SND_DEBUG_MEMORY
-void *snd_wrapper_kmalloc(size_t size, gfp_t flags)
-{
- return kmalloc(size, flags);
-}
-
-void snd_wrapper_kfree(const void *obj)
-{
- kfree(obj);
-}
-
-void *snd_wrapper_vmalloc(unsigned long size)
-{
- return vmalloc(size);
-}
-
-void snd_wrapper_vfree(void *obj)
-{
- vfree(obj);
-}
-#endif
-
diff --git a/sound/drivers/mpu401/mpu401_uart.c b/sound/drivers/mpu401/mpu401_uart.c
index fe3f921ffbe3..bdeb2c00dac5 100644
--- a/sound/drivers/mpu401/mpu401_uart.c
+++ b/sound/drivers/mpu401/mpu401_uart.c
@@ -423,10 +423,7 @@ static void snd_mpu401_uart_free(snd_rawmidi_t *rmidi)
mpu401_t *mpu = rmidi->private_data;
if (mpu->irq_flags && mpu->irq >= 0)
free_irq(mpu->irq, (void *) mpu);
- if (mpu->res) {
- release_resource(mpu->res);
- kfree_nocheck(mpu->res);
- }
+ release_and_free_resource(mpu->res);
kfree(mpu);
}
diff --git a/sound/drivers/mtpav.c b/sound/drivers/mtpav.c
index 3a25c89d2983..e9d52c668edc 100644
--- a/sound/drivers/mtpav.c
+++ b/sound/drivers/mtpav.c
@@ -717,10 +717,7 @@ static void free_mtpav(mtpav_t * crd)
spin_unlock_irqrestore(&crd->spinlock, flags);
if (crd->irq >= 0)
free_irq(crd->irq, (void *)crd);
- if (crd->res_port) {
- release_resource(crd->res_port);
- kfree_nocheck(crd->res_port);
- }
+ release_and_free_resource(crd->res_port);
kfree(crd);
}
diff --git a/sound/drivers/opl3/opl3_lib.c b/sound/drivers/opl3/opl3_lib.c
index 1f84d78260de..06246503083c 100644
--- a/sound/drivers/opl3/opl3_lib.c
+++ b/sound/drivers/opl3/opl3_lib.c
@@ -325,14 +325,8 @@ static int snd_opl3_free(opl3_t *opl3)
snd_assert(opl3 != NULL, return -ENXIO);
if (opl3->private_free)
opl3->private_free(opl3);
- if (opl3->res_l_port) {
- release_resource(opl3->res_l_port);
- kfree_nocheck(opl3->res_l_port);
- }
- if (opl3->res_r_port) {
- release_resource(opl3->res_r_port);
- kfree_nocheck(opl3->res_r_port);
- }
+ release_and_free_resource(opl3->res_l_port);
+ release_and_free_resource(opl3->res_r_port);
kfree(opl3);
return 0;
}
diff --git a/sound/drivers/opl4/opl4_lib.c b/sound/drivers/opl4/opl4_lib.c
index 380c2c704c54..4ae5dd8f011e 100644
--- a/sound/drivers/opl4/opl4_lib.c
+++ b/sound/drivers/opl4/opl4_lib.c
@@ -169,14 +169,8 @@ static void snd_opl4_free(opl4_t *opl4)
#ifdef CONFIG_PROC_FS
snd_opl4_free_proc(opl4);
#endif
- if (opl4->res_fm_port) {
- release_resource(opl4->res_fm_port);
- kfree_nocheck(opl4->res_fm_port);
- }
- if (opl4->res_pcm_port) {
- release_resource(opl4->res_pcm_port);
- kfree_nocheck(opl4->res_pcm_port);
- }
+ release_and_free_resource(opl4->res_fm_port);
+ release_and_free_resource(opl4->res_pcm_port);
kfree(opl4);
}
diff --git a/sound/drivers/serial-u16550.c b/sound/drivers/serial-u16550.c
index 416172ea1f47..1ed58df42671 100644
--- a/sound/drivers/serial-u16550.c
+++ b/sound/drivers/serial-u16550.c
@@ -749,10 +749,7 @@ static int snd_uart16550_free(snd_uart16550_t *uart)
{
if (uart->irq >= 0)
free_irq(uart->irq, (void *)uart);
- if (uart->res_base) {
- release_resource(uart->res_base);
- kfree_nocheck(uart->res_base);
- }
+ release_and_free_resource(uart->res_base);
kfree(uart);
return 0;
};
diff --git a/sound/drivers/vx/vx_hwdep.c b/sound/drivers/vx/vx_hwdep.c
index 9a3dc3c3b3de..c4993b004c42 100644
--- a/sound/drivers/vx/vx_hwdep.c
+++ b/sound/drivers/vx/vx_hwdep.c
@@ -23,6 +23,7 @@
#include <sound/driver.h>
#include <linux/device.h>
#include <linux/firmware.h>
+#include <linux/vmalloc.h>
#include <sound/core.h>
#include <sound/hwdep.h>
#include <sound/vx_core.h>
diff --git a/sound/drivers/vx/vx_pcm.c b/sound/drivers/vx/vx_pcm.c
index c2312d912fc7..2b46758fe86f 100644
--- a/sound/drivers/vx/vx_pcm.c
+++ b/sound/drivers/vx/vx_pcm.c
@@ -79,7 +79,7 @@ static int snd_pcm_alloc_vmalloc_buffer(snd_pcm_substream_t *subs, size_t size)
/* already allocated */
if (runtime->dma_bytes >= size)
return 0; /* already enough large */
- vfree_nocheck(runtime->dma_area); /* bypass the memory wrapper */
+ vfree(runtime->dma_area);
}
runtime->dma_area = vmalloc_32(size);
if (! runtime->dma_area)
@@ -98,7 +98,7 @@ static int snd_pcm_free_vmalloc_buffer(snd_pcm_substream_t *subs)
{
snd_pcm_runtime_t *runtime = subs->runtime;
if (runtime->dma_area) {
- vfree_nocheck(runtime->dma_area); /* bypass the memory wrapper */
+ vfree(runtime->dma_area);
runtime->dma_area = NULL;
}
return 0;
diff --git a/sound/i2c/cs8427.c b/sound/i2c/cs8427.c
index a21f7d541f86..1a05cfbdc7c6 100644
--- a/sound/i2c/cs8427.c
+++ b/sound/i2c/cs8427.c
@@ -75,7 +75,7 @@ int snd_cs8427_reg_write(snd_i2c_device_t *device, unsigned char reg, unsigned c
buf[0] = reg & 0x7f;
buf[1] = val;
if ((err = snd_i2c_sendbytes(device, buf, 2)) != 2) {
- snd_printk("unable to send bytes 0x%02x:0x%02x to CS8427 (%i)\n", buf[0], buf[1], err);
+ snd_printk(KERN_ERR "unable to send bytes 0x%02x:0x%02x to CS8427 (%i)\n", buf[0], buf[1], err);
return err < 0 ? err : -EIO;
}
return 0;
@@ -87,11 +87,11 @@ static int snd_cs8427_reg_read(snd_i2c_device_t *device, unsigned char reg)
unsigned char buf;
if ((err = snd_i2c_sendbytes(device, &reg, 1)) != 1) {
- snd_printk("unable to send register 0x%x byte to CS8427\n", reg);
+ snd_printk(KERN_ERR "unable to send register 0x%x byte to CS8427\n", reg);
return err < 0 ? err : -EIO;
}
if ((err = snd_i2c_readbytes(device, &buf, 1)) != 1) {
- snd_printk("unable to read register 0x%x byte from CS8427\n", reg);
+ snd_printk(KERN_ERR "unable to read register 0x%x byte from CS8427\n", reg);
return err < 0 ? err : -EIO;
}
return buf;
@@ -210,7 +210,7 @@ int snd_cs8427_create(snd_i2c_bus_t *bus,
snd_i2c_lock(bus);
if ((err = snd_cs8427_reg_read(device, CS8427_REG_ID_AND_VER)) != CS8427_VER8427A) {
snd_i2c_unlock(bus);
- snd_printk("unable to find CS8427 signature (expected 0x%x, read 0x%x), initialization is not completed\n", CS8427_VER8427A, err);
+ snd_printk(KERN_ERR "unable to find CS8427 signature (expected 0x%x, read 0x%x), initialization is not completed\n", CS8427_VER8427A, err);
return -EFAULT;
}
/* turn off run bit while making changes to configuration */
@@ -260,7 +260,7 @@ int snd_cs8427_create(snd_i2c_bus_t *bus,
snd_i2c_sendbytes(device, buf, 1);
snd_i2c_readbytes(device, buf, 127);
for (xx = 0; xx < 127; xx++)
- printk("reg[0x%x] = 0x%x\n", xx+1, buf[xx]);
+ printk(KERN_DEBUG "reg[0x%x] = 0x%x\n", xx+1, buf[xx]);
}
#endif
@@ -302,8 +302,7 @@ static void snd_cs8427_reset(snd_i2c_device_t *cs8427)
snd_i2c_unlock(cs8427->bus);
if (!(data & CS8427_UNLOCK))
break;
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(1);
+ schedule_timeout_uninterruptible(1);
}
snd_i2c_lock(cs8427->bus);
chip->regmap[CS8427_REG_CLOCKSOURCE] &= ~CS8427_RXDMASK;
@@ -354,12 +353,12 @@ static int snd_cs8427_qsubcode_get(snd_kcontrol_t *kcontrol,
snd_i2c_lock(device->bus);
if ((err = snd_i2c_sendbytes(device, &reg, 1)) != 1) {
- snd_printk("unable to send register 0x%x byte to CS8427\n", reg);
+ snd_printk(KERN_ERR "unable to send register 0x%x byte to CS8427\n", reg);
snd_i2c_unlock(device->bus);
return err < 0 ? err : -EIO;
}
if ((err = snd_i2c_readbytes(device, ucontrol->value.bytes.data, 10)) != 10) {
- snd_printk("unable to read Q-subcode bytes from CS8427\n");
+ snd_printk(KERN_ERR "unable to read Q-subcode bytes from CS8427\n");
snd_i2c_unlock(device->bus);
return err < 0 ? err : -EIO;
}
diff --git a/sound/i2c/other/ak4114.c b/sound/i2c/other/ak4114.c
index af5eadcddd92..d351b3aa1916 100644
--- a/sound/i2c/other/ak4114.c
+++ b/sound/i2c/other/ak4114.c
@@ -56,9 +56,9 @@ static void reg_dump(ak4114_t *ak4114)
{
int i;
- printk("AK4114 REG DUMP:\n");
+ printk(KERN_DEBUG "AK4114 REG DUMP:\n");
for (i = 0; i < 0x20; i++)
- printk("reg[%02x] = %02x (%02x)\n", i, reg_read(ak4114, i), i < sizeof(ak4114->regmap) ? ak4114->regmap[i] : 0);
+ printk(KERN_DEBUG "reg[%02x] = %02x (%02x)\n", i, reg_read(ak4114, i), i < sizeof(ak4114->regmap) ? ak4114->regmap[i] : 0);
}
#endif
@@ -552,7 +552,7 @@ int snd_ak4114_check_rate_and_errors(ak4114_t *ak4114, unsigned int flags)
if (!(flags & AK4114_CHECK_NO_RATE) && runtime && runtime->rate != res) {
snd_pcm_stream_lock_irqsave(ak4114->capture_substream, _flags);
if (snd_pcm_running(ak4114->capture_substream)) {
- // printk("rate changed (%i <- %i)\n", runtime->rate, res);
+ // printk(KERN_DEBUG "rate changed (%i <- %i)\n", runtime->rate, res);
snd_pcm_stop(ak4114->capture_substream, SNDRV_PCM_STATE_DRAINING);
res = 1;
}
diff --git a/sound/i2c/other/ak4117.c b/sound/i2c/other/ak4117.c
index d51b51dd86d6..35b4584483a3 100644
--- a/sound/i2c/other/ak4117.c
+++ b/sound/i2c/other/ak4117.c
@@ -54,9 +54,9 @@ static void reg_dump(ak4117_t *ak4117)
{
int i;
- printk("AK4117 REG DUMP:\n");
+ printk(KERN_DEBUG "AK4117 REG DUMP:\n");
for (i = 0; i < 0x1b; i++)
- printk("reg[%02x] = %02x (%02x)\n", i, reg_read(ak4117, i), i < sizeof(ak4117->regmap) ? ak4117->regmap[i] : 0);
+ printk(KERN_DEBUG "reg[%02x] = %02x (%02x)\n", i, reg_read(ak4117, i), i < sizeof(ak4117->regmap) ? ak4117->regmap[i] : 0);
}
#endif
@@ -477,7 +477,7 @@ int snd_ak4117_check_rate_and_errors(ak4117_t *ak4117, unsigned int flags)
goto __rate;
rcs0 = reg_read(ak4117, AK4117_REG_RCS0);
rcs2 = reg_read(ak4117, AK4117_REG_RCS2);
- // printk("AK IRQ: rcs0 = 0x%x, rcs1 = 0x%x, rcs2 = 0x%x\n", rcs0, rcs1, rcs2);
+ // printk(KERN_DEBUG "AK IRQ: rcs0 = 0x%x, rcs1 = 0x%x, rcs2 = 0x%x\n", rcs0, rcs1, rcs2);
spin_lock_irqsave(&ak4117->lock, _flags);
if (rcs0 & AK4117_PAR)
ak4117->parity_errors++;
@@ -530,7 +530,7 @@ int snd_ak4117_check_rate_and_errors(ak4117_t *ak4117, unsigned int flags)
if (!(flags & AK4117_CHECK_NO_RATE) && runtime && runtime->rate != res) {
snd_pcm_stream_lock_irqsave(ak4117->substream, _flags);
if (snd_pcm_running(ak4117->substream)) {
- // printk("rate changed (%i <- %i)\n", runtime->rate, res);
+ // printk(KERN_DEBUG "rate changed (%i <- %i)\n", runtime->rate, res);
snd_pcm_stop(ak4117->substream, SNDRV_PCM_STATE_DRAINING);
wake_up(&runtime->sleep);
res = 1;
diff --git a/sound/i2c/tea6330t.c b/sound/i2c/tea6330t.c
index fd65da654267..4fdd1fb57dfe 100644
--- a/sound/i2c/tea6330t.c
+++ b/sound/i2c/tea6330t.c
@@ -58,7 +58,7 @@ static void snd_tea6330t_set(tea6330t_t *tea,
unsigned char addr, unsigned char value)
{
#if 0
- printk("set - 0x%x/0x%x\n", addr, value);
+ printk(KERN_DEBUG "set - 0x%x/0x%x\n", addr, value);
#endif
snd_i2c_write(tea->bus, TEA6330T_ADDR, addr, value, 1);
}
diff --git a/sound/isa/ad1816a/ad1816a_lib.c b/sound/isa/ad1816a/ad1816a_lib.c
index 27a9dcfbba00..7ae02396cae2 100644
--- a/sound/isa/ad1816a/ad1816a_lib.c
+++ b/sound/isa/ad1816a/ad1816a_lib.c
@@ -542,10 +542,7 @@ static int snd_ad1816a_probe(ad1816a_t *chip)
static int snd_ad1816a_free(ad1816a_t *chip)
{
- if (chip->res_port) {
- release_resource(chip->res_port);
- kfree_nocheck(chip->res_port);
- }
+ release_and_free_resource(chip->res_port);
if (chip->irq >= 0)
free_irq(chip->irq, (void *) chip);
if (chip->dma1 >= 0) {
diff --git a/sound/isa/ad1848/ad1848_lib.c b/sound/isa/ad1848/ad1848_lib.c
index 303861cd03cd..891bacc94f68 100644
--- a/sound/isa/ad1848/ad1848_lib.c
+++ b/sound/isa/ad1848/ad1848_lib.c
@@ -109,7 +109,7 @@ void snd_ad1848_out(ad1848_t *chip,
udelay(100);
#ifdef CONFIG_SND_DEBUG
if (inb(AD1848P(chip, REGSEL)) & AD1848_INIT)
- snd_printk("auto calibration time out - reg = 0x%x, value = 0x%x\n", reg, value);
+ snd_printk(KERN_WARNING "auto calibration time out - reg = 0x%x, value = 0x%x\n", reg, value);
#endif
outb(chip->mce_bit | reg, AD1848P(chip, REGSEL));
outb(chip->image[reg] = value, AD1848P(chip, REG));
@@ -139,7 +139,7 @@ static unsigned char snd_ad1848_in(ad1848_t *chip, unsigned char reg)
udelay(100);
#ifdef CONFIG_SND_DEBUG
if (inb(AD1848P(chip, REGSEL)) & AD1848_INIT)
- snd_printk("auto calibration time out - reg = 0x%x\n", reg);
+ snd_printk(KERN_WARNING "auto calibration time out - reg = 0x%x\n", reg);
#endif
outb(chip->mce_bit | reg, AD1848P(chip, REGSEL));
mb();
@@ -185,13 +185,13 @@ static void snd_ad1848_mce_up(ad1848_t *chip)
udelay(100);
#ifdef CONFIG_SND_DEBUG
if (inb(AD1848P(chip, REGSEL)) & AD1848_INIT)
- snd_printk("mce_up - auto calibration time out (0)\n");
+ snd_printk(KERN_WARNING "mce_up - auto calibration time out (0)\n");
#endif
spin_lock_irqsave(&chip->reg_lock, flags);
chip->mce_bit |= AD1848_MCE;
timeout = inb(AD1848P(chip, REGSEL));
if (timeout == 0x80)
- snd_printk("mce_up [0x%lx]: serious init problem - codec still busy\n", chip->port);
+ snd_printk(KERN_WARNING "mce_up [0x%lx]: serious init problem - codec still busy\n", chip->port);
if (!(timeout & AD1848_MCE))
outb(chip->mce_bit | (timeout & 0x1f), AD1848P(chip, REGSEL));
spin_unlock_irqrestore(&chip->reg_lock, flags);
@@ -214,13 +214,13 @@ static void snd_ad1848_mce_down(ad1848_t *chip)
#endif
#ifdef CONFIG_SND_DEBUG
if (inb(AD1848P(chip, REGSEL)) & AD1848_INIT)
- snd_printk("mce_down [0x%lx] - auto calibration time out (0)\n", AD1848P(chip, REGSEL));
+ snd_printk(KERN_WARNING "mce_down [0x%lx] - auto calibration time out (0)\n", AD1848P(chip, REGSEL));
#endif
chip->mce_bit &= ~AD1848_MCE;
timeout = inb(AD1848P(chip, REGSEL));
outb(chip->mce_bit | (timeout & 0x1f), AD1848P(chip, REGSEL));
if (timeout == 0x80)
- snd_printk("mce_down [0x%lx]: serious init problem - codec still busy\n", chip->port);
+ snd_printk(KERN_WARNING "mce_down [0x%lx]: serious init problem - codec still busy\n", chip->port);
if ((timeout & AD1848_MCE) == 0) {
spin_unlock_irqrestore(&chip->reg_lock, flags);
return;
@@ -240,11 +240,10 @@ static void snd_ad1848_mce_down(ad1848_t *chip)
while (snd_ad1848_in(chip, AD1848_TEST_INIT) & AD1848_CALIB_IN_PROGRESS) {
spin_unlock_irqrestore(&chip->reg_lock, flags);
if (time <= 0) {
- snd_printk("mce_down - auto calibration time out (2)\n");
+ snd_printk(KERN_ERR "mce_down - auto calibration time out (2)\n");
return;
}
- set_current_state(TASK_INTERRUPTIBLE);
- time = schedule_timeout(time);
+ time = schedule_timeout_interruptible(time);
spin_lock_irqsave(&chip->reg_lock, flags);
}
#if 0
@@ -254,11 +253,10 @@ static void snd_ad1848_mce_down(ad1848_t *chip)
while (inb(AD1848P(chip, REGSEL)) & AD1848_INIT) {
spin_unlock_irqrestore(&chip->reg_lock, flags);
if (time <= 0) {
- snd_printk("mce_down - auto calibration time out (3)\n");
+ snd_printk(KERN_ERR "mce_down - auto calibration time out (3)\n");
return;
}
- set_current_state(TASK_INTERRUPTIBLE);
- time = schedule_timeout(time);
+ time = schedule_timeout_interruptible(time);
spin_lock_irqsave(&chip->reg_lock, flags);
}
spin_unlock_irqrestore(&chip->reg_lock, flags);
@@ -846,10 +844,7 @@ static int snd_ad1848_capture_close(snd_pcm_substream_t * substream)
static int snd_ad1848_free(ad1848_t *chip)
{
- if (chip->res_port) {
- release_resource(chip->res_port);
- kfree_nocheck(chip->res_port);
- }
+ release_and_free_resource(chip->res_port);
if (chip->irq >= 0)
free_irq(chip->irq, (void *) chip);
if (chip->dma >= 0) {
diff --git a/sound/isa/cs423x/cs4231_lib.c b/sound/isa/cs423x/cs4231_lib.c
index 32318258cd8e..4af769030beb 100644
--- a/sound/isa/cs423x/cs4231_lib.c
+++ b/sound/isa/cs423x/cs4231_lib.c
@@ -1417,14 +1417,8 @@ static int snd_cs4231_pm_resume(snd_card_t *card)
static int snd_cs4231_free(cs4231_t *chip)
{
- if (chip->res_port) {
- release_resource(chip->res_port);
- kfree_nocheck(chip->res_port);
- }
- if (chip->res_cport) {
- release_resource(chip->res_cport);
- kfree_nocheck(chip->res_cport);
- }
+ release_and_free_resource(chip->res_port);
+ release_and_free_resource(chip->res_cport);
if (chip->irq >= 0) {
disable_irq(chip->irq);
if (!(chip->hwshare & CS4231_HWSHARE_IRQ))
diff --git a/sound/isa/cs423x/cs4236.c b/sound/isa/cs423x/cs4236.c
index d28315dc72f7..d60a55e6a0b1 100644
--- a/sound/isa/cs423x/cs4236.c
+++ b/sound/isa/cs423x/cs4236.c
@@ -379,12 +379,8 @@ static void snd_card_cs4236_free(snd_card_t *card)
{
struct snd_card_cs4236 *acard = (struct snd_card_cs4236 *)card->private_data;
- if (acard) {
- if (acard->res_sb_port) {
- release_resource(acard->res_sb_port);
- kfree_nocheck(acard->res_sb_port);
- }
- }
+ if (acard)
+ release_and_free_resource(acard->res_sb_port);
}
#ifdef CONFIG_PNP
diff --git a/sound/isa/cs423x/cs4236_lib.c b/sound/isa/cs423x/cs4236_lib.c
index 2128d4bdef41..1adb88d5f8f4 100644
--- a/sound/isa/cs423x/cs4236_lib.c
+++ b/sound/isa/cs423x/cs4236_lib.c
@@ -173,7 +173,10 @@ static unsigned char divisor_to_rate_register(unsigned int divisor)
case 2117: return 6;
case 2558: return 7;
default:
- snd_runtime_check(divisor >= 21 && divisor <= 192, return 192);
+ if (divisor < 21 || divisor > 192) {
+ snd_BUG();
+ return 192;
+ }
return divisor;
}
}
diff --git a/sound/isa/es1688/es1688_lib.c b/sound/isa/es1688/es1688_lib.c
index aac898765c02..2edc9c9f0445 100644
--- a/sound/isa/es1688/es1688_lib.c
+++ b/sound/isa/es1688/es1688_lib.c
@@ -606,8 +606,7 @@ static int snd_es1688_free(es1688_t *chip)
{
if (chip->res_port) {
snd_es1688_init(chip, 0);
- release_resource(chip->res_port);
- kfree_nocheck(chip->res_port);
+ release_and_free_resource(chip->res_port);
}
if (chip->irq >= 0)
free_irq(chip->irq, (void *) chip);
diff --git a/sound/isa/es18xx.c b/sound/isa/es18xx.c
index d0ea19f42703..970e2aaade27 100644
--- a/sound/isa/es18xx.c
+++ b/sound/isa/es18xx.c
@@ -173,7 +173,7 @@ static int snd_es18xx_dsp_command(es18xx_t *chip, unsigned char val)
outb(val, chip->port + 0x0C);
return 0;
}
- snd_printk("dsp_command: timeout (0x%x)\n", val);
+ snd_printk(KERN_ERR "dsp_command: timeout (0x%x)\n", val);
return -EINVAL;
}
@@ -184,7 +184,8 @@ static int snd_es18xx_dsp_get_byte(es18xx_t *chip)
for(i = MILLISECOND/10; i; i--)
if (inb(chip->port + 0x0C) & 0x40)
return inb(chip->port + 0x0A);
- snd_printk("dsp_get_byte failed: 0x%lx = 0x%x!!!\n", chip->port + 0x0A, inb(chip->port + 0x0A));
+ snd_printk(KERN_ERR "dsp_get_byte failed: 0x%lx = 0x%x!!!\n",
+ chip->port + 0x0A, inb(chip->port + 0x0A));
return -ENODEV;
}
@@ -204,7 +205,7 @@ static int snd_es18xx_write(es18xx_t *chip,
end:
spin_unlock_irqrestore(&chip->reg_lock, flags);
#ifdef REG_DEBUG
- snd_printk("Reg %02x set to %02x\n", reg, data);
+ snd_printk(KERN_DEBUG "Reg %02x set to %02x\n", reg, data);
#endif
return ret;
}
@@ -223,7 +224,7 @@ static int snd_es18xx_read(es18xx_t *chip, unsigned char reg)
data = snd_es18xx_dsp_get_byte(chip);
ret = data;
#ifdef REG_DEBUG
- snd_printk("Reg %02x now is %02x (%d)\n", reg, data, ret);
+ snd_printk(KERN_DEBUG "Reg %02x now is %02x (%d)\n", reg, data, ret);
#endif
end:
spin_unlock_irqrestore(&chip->reg_lock, flags);
@@ -259,7 +260,8 @@ static int snd_es18xx_bits(es18xx_t *chip, unsigned char reg,
if (ret < 0)
goto end;
#ifdef REG_DEBUG
- snd_printk("Reg %02x was %02x, set to %02x (%d)\n", reg, old, new, ret);
+ snd_printk(KERN_DEBUG "Reg %02x was %02x, set to %02x (%d)\n",
+ reg, old, new, ret);
#endif
}
ret = oval;
@@ -277,7 +279,7 @@ static inline void snd_es18xx_mixer_write(es18xx_t *chip,
outb(data, chip->port + 0x05);
spin_unlock_irqrestore(&chip->mixer_lock, flags);
#ifdef REG_DEBUG
- snd_printk("Mixer reg %02x set to %02x\n", reg, data);
+ snd_printk(KERN_DEBUG "Mixer reg %02x set to %02x\n", reg, data);
#endif
}
@@ -290,7 +292,7 @@ static inline int snd_es18xx_mixer_read(es18xx_t *chip, unsigned char reg)
data = inb(chip->port + 0x05);
spin_unlock_irqrestore(&chip->mixer_lock, flags);
#ifdef REG_DEBUG
- snd_printk("Mixer reg %02x now is %02x\n", reg, data);
+ snd_printk(KERN_DEBUG "Mixer reg %02x now is %02x\n", reg, data);
#endif
return data;
}
@@ -309,7 +311,8 @@ static inline int snd_es18xx_mixer_bits(es18xx_t *chip, unsigned char reg,
new = (old & ~mask) | (val & mask);
outb(new, chip->port + 0x05);
#ifdef REG_DEBUG
- snd_printk("Mixer reg %02x was %02x, set to %02x\n", reg, old, new);
+ snd_printk(KERN_DEBUG "Mixer reg %02x was %02x, set to %02x\n",
+ reg, old, new);
#endif
}
spin_unlock_irqrestore(&chip->mixer_lock, flags);
@@ -329,7 +332,8 @@ static inline int snd_es18xx_mixer_writable(es18xx_t *chip, unsigned char reg,
new = inb(chip->port + 0x05);
spin_unlock_irqrestore(&chip->mixer_lock, flags);
#ifdef REG_DEBUG
- snd_printk("Mixer reg %02x was %02x, set to %02x, now is %02x\n", reg, old, expected, new);
+ snd_printk(KERN_DEBUG "Mixer reg %02x was %02x, set to %02x, now is %02x\n",
+ reg, old, expected, new);
#endif
return expected == new;
}
@@ -1281,7 +1285,7 @@ static void __devinit snd_es18xx_config_write(es18xx_t *chip,
outb(reg, chip->ctrl_port);
outb(data, chip->ctrl_port + 1);
#ifdef REG_DEBUG
- snd_printk("Config reg %02x set to %02x\n", reg, data);
+ snd_printk(KERN_DEBUG "Config reg %02x set to %02x\n", reg, data);
#endif
}
@@ -1346,7 +1350,7 @@ static int __devinit snd_es18xx_initialize(es18xx_t *chip)
irqmask = 3;
break;
default:
- snd_printk("invalid irq %d\n", chip->irq);
+ snd_printk(KERN_ERR "invalid irq %d\n", chip->irq);
return -ENODEV;
}
switch (chip->dma1) {
@@ -1360,7 +1364,7 @@ static int __devinit snd_es18xx_initialize(es18xx_t *chip)
dma1mask = 3;
break;
default:
- snd_printk("invalid dma1 %d\n", chip->dma1);
+ snd_printk(KERN_ERR "invalid dma1 %d\n", chip->dma1);
return -ENODEV;
}
switch (chip->dma2) {
@@ -1377,7 +1381,7 @@ static int __devinit snd_es18xx_initialize(es18xx_t *chip)
dma2mask = 3;
break;
default:
- snd_printk("invalid dma2 %d\n", chip->dma2);
+ snd_printk(KERN_ERR "invalid dma2 %d\n", chip->dma2);
return -ENODEV;
}
@@ -1440,7 +1444,7 @@ static int __devinit snd_es18xx_identify(es18xx_t *chip)
/* reset */
if (snd_es18xx_reset(chip) < 0) {
- snd_printk("reset at 0x%lx failed!!!\n", chip->port);
+ snd_printk(KERN_ERR "reset at 0x%lx failed!!!\n", chip->port);
return -ENODEV;
}
@@ -1527,7 +1531,7 @@ static int __devinit snd_es18xx_probe(es18xx_t *chip)
chip->caps = ES18XX_PCM2 | ES18XX_RECMIX | ES18XX_AUXB | ES18XX_DUPLEX_SAME | ES18XX_HWV;
break;
default:
- snd_printk("[0x%lx] unsupported chip ES%x\n",
+ snd_printk(KERN_ERR "[0x%lx] unsupported chip ES%x\n",
chip->port, chip->version);
return -ENODEV;
}
@@ -1640,18 +1644,9 @@ static int snd_es18xx_resume(snd_card_t *card)
static int snd_es18xx_free(es18xx_t *chip)
{
- if (chip->res_port) {
- release_resource(chip->res_port);
- kfree_nocheck(chip->res_port);
- }
- if (chip->res_ctrl_port) {
- release_resource(chip->res_ctrl_port);
- kfree_nocheck(chip->res_ctrl_port);
- }
- if (chip->res_mpu_port) {
- release_resource(chip->res_mpu_port);
- kfree_nocheck(chip->res_mpu_port);
- }
+ release_and_free_resource(chip->res_port);
+ release_and_free_resource(chip->res_ctrl_port);
+ release_and_free_resource(chip->res_mpu_port);
if (chip->irq >= 0)
free_irq(chip->irq, (void *) chip);
if (chip->dma1 >= 0) {
diff --git a/sound/isa/gus/gus_dma.c b/sound/isa/gus/gus_dma.c
index de4b56d80b35..ef1b2e9832e4 100644
--- a/sound/isa/gus/gus_dma.c
+++ b/sound/isa/gus/gus_dma.c
@@ -199,7 +199,7 @@ int snd_gf1_dma_transfer_block(snd_gus_card_t * gus,
block = kmalloc(sizeof(*block), atomic ? GFP_ATOMIC : GFP_KERNEL);
if (block == NULL) {
- snd_printk("gf1: DMA transfer failure; not enough memory\n");
+ snd_printk(KERN_ERR "gf1: DMA transfer failure; not enough memory\n");
return -ENOMEM;
}
*block = *__block;
diff --git a/sound/isa/gus/gus_io.c b/sound/isa/gus/gus_io.c
index 23e1b5f19e1a..8d5752b23787 100644
--- a/sound/isa/gus/gus_io.c
+++ b/sound/isa/gus/gus_io.c
@@ -343,7 +343,7 @@ void snd_gf1_pokew(snd_gus_card_t * gus, unsigned int addr, unsigned short data)
#ifdef CONFIG_SND_DEBUG
if (!gus->interwave)
- snd_printk("snd_gf1_pokew - GF1!!!\n");
+ snd_printk(KERN_DEBUG "snd_gf1_pokew - GF1!!!\n");
#endif
spin_lock_irqsave(&gus->reg_lock, flags);
outb(SNDRV_GF1_GW_DRAM_IO_LOW, gus->gf1.reg_regsel);
@@ -367,7 +367,7 @@ unsigned short snd_gf1_peekw(snd_gus_card_t * gus, unsigned int addr)
#ifdef CONFIG_SND_DEBUG
if (!gus->interwave)
- snd_printk("snd_gf1_peekw - GF1!!!\n");
+ snd_printk(KERN_DEBUG "snd_gf1_peekw - GF1!!!\n");
#endif
spin_lock_irqsave(&gus->reg_lock, flags);
outb(SNDRV_GF1_GW_DRAM_IO_LOW, gus->gf1.reg_regsel);
@@ -393,7 +393,7 @@ void snd_gf1_dram_setmem(snd_gus_card_t * gus, unsigned int addr,
#ifdef CONFIG_SND_DEBUG
if (!gus->interwave)
- snd_printk("snd_gf1_dram_setmem - GF1!!!\n");
+ snd_printk(KERN_DEBUG "snd_gf1_dram_setmem - GF1!!!\n");
#endif
addr &= ~1;
count >>= 1;
@@ -449,30 +449,30 @@ void snd_gf1_print_voice_registers(snd_gus_card_t * gus)
int voice, ctrl;
voice = gus->gf1.active_voice;
- printk(" -%i- GF1 voice ctrl, ramp ctrl = 0x%x, 0x%x\n", voice, ctrl = snd_gf1_i_read8(gus, 0), snd_gf1_i_read8(gus, 0x0d));
- printk(" -%i- GF1 frequency = 0x%x\n", voice, snd_gf1_i_read16(gus, 1));
- printk(" -%i- GF1 loop start, end = 0x%x (0x%x), 0x%x (0x%x)\n", voice, snd_gf1_i_read_addr(gus, 2, ctrl & 4), snd_gf1_i_read_addr(gus, 2, (ctrl & 4) ^ 4), snd_gf1_i_read_addr(gus, 4, ctrl & 4), snd_gf1_i_read_addr(gus, 4, (ctrl & 4) ^ 4));
- printk(" -%i- GF1 ramp start, end, rate = 0x%x, 0x%x, 0x%x\n", voice, snd_gf1_i_read8(gus, 7), snd_gf1_i_read8(gus, 8), snd_gf1_i_read8(gus, 6));
- printk(" -%i- GF1 volume = 0x%x\n", voice, snd_gf1_i_read16(gus, 9));
- printk(" -%i- GF1 position = 0x%x (0x%x)\n", voice, snd_gf1_i_read_addr(gus, 0x0a, ctrl & 4), snd_gf1_i_read_addr(gus, 0x0a, (ctrl & 4) ^ 4));
+ printk(KERN_INFO " -%i- GF1 voice ctrl, ramp ctrl = 0x%x, 0x%x\n", voice, ctrl = snd_gf1_i_read8(gus, 0), snd_gf1_i_read8(gus, 0x0d));
+ printk(KERN_INFO " -%i- GF1 frequency = 0x%x\n", voice, snd_gf1_i_read16(gus, 1));
+ printk(KERN_INFO " -%i- GF1 loop start, end = 0x%x (0x%x), 0x%x (0x%x)\n", voice, snd_gf1_i_read_addr(gus, 2, ctrl & 4), snd_gf1_i_read_addr(gus, 2, (ctrl & 4) ^ 4), snd_gf1_i_read_addr(gus, 4, ctrl & 4), snd_gf1_i_read_addr(gus, 4, (ctrl & 4) ^ 4));
+ printk(KERN_INFO " -%i- GF1 ramp start, end, rate = 0x%x, 0x%x, 0x%x\n", voice, snd_gf1_i_read8(gus, 7), snd_gf1_i_read8(gus, 8), snd_gf1_i_read8(gus, 6));
+ printk(KERN_INFO" -%i- GF1 volume = 0x%x\n", voice, snd_gf1_i_read16(gus, 9));
+ printk(KERN_INFO " -%i- GF1 position = 0x%x (0x%x)\n", voice, snd_gf1_i_read_addr(gus, 0x0a, ctrl & 4), snd_gf1_i_read_addr(gus, 0x0a, (ctrl & 4) ^ 4));
if (gus->interwave && snd_gf1_i_read8(gus, 0x19) & 0x01) { /* enhanced mode */
mode = snd_gf1_i_read8(gus, 0x15);
- printk(" -%i- GFA1 mode = 0x%x\n", voice, mode);
+ printk(KERN_INFO " -%i- GFA1 mode = 0x%x\n", voice, mode);
if (mode & 0x01) { /* Effect processor */
- printk(" -%i- GFA1 effect address = 0x%x\n", voice, snd_gf1_i_read_addr(gus, 0x11, ctrl & 4));
- printk(" -%i- GFA1 effect volume = 0x%x\n", voice, snd_gf1_i_read16(gus, 0x16));
- printk(" -%i- GFA1 effect volume final = 0x%x\n", voice, snd_gf1_i_read16(gus, 0x1d));
- printk(" -%i- GFA1 effect acumulator = 0x%x\n", voice, snd_gf1_i_read8(gus, 0x14));
+ printk(KERN_INFO " -%i- GFA1 effect address = 0x%x\n", voice, snd_gf1_i_read_addr(gus, 0x11, ctrl & 4));
+ printk(KERN_INFO " -%i- GFA1 effect volume = 0x%x\n", voice, snd_gf1_i_read16(gus, 0x16));
+ printk(KERN_INFO " -%i- GFA1 effect volume final = 0x%x\n", voice, snd_gf1_i_read16(gus, 0x1d));
+ printk(KERN_INFO " -%i- GFA1 effect acumulator = 0x%x\n", voice, snd_gf1_i_read8(gus, 0x14));
}
if (mode & 0x20) {
- printk(" -%i- GFA1 left offset = 0x%x (%i)\n", voice, snd_gf1_i_read16(gus, 0x13), snd_gf1_i_read16(gus, 0x13) >> 4);
- printk(" -%i- GFA1 left offset final = 0x%x (%i)\n", voice, snd_gf1_i_read16(gus, 0x1c), snd_gf1_i_read16(gus, 0x1c) >> 4);
- printk(" -%i- GFA1 right offset = 0x%x (%i)\n", voice, snd_gf1_i_read16(gus, 0x0c), snd_gf1_i_read16(gus, 0x0c) >> 4);
- printk(" -%i- GFA1 right offset final = 0x%x (%i)\n", voice, snd_gf1_i_read16(gus, 0x1b), snd_gf1_i_read16(gus, 0x1b) >> 4);
+ printk(KERN_INFO " -%i- GFA1 left offset = 0x%x (%i)\n", voice, snd_gf1_i_read16(gus, 0x13), snd_gf1_i_read16(gus, 0x13) >> 4);
+ printk(KERN_INFO " -%i- GFA1 left offset final = 0x%x (%i)\n", voice, snd_gf1_i_read16(gus, 0x1c), snd_gf1_i_read16(gus, 0x1c) >> 4);
+ printk(KERN_INFO " -%i- GFA1 right offset = 0x%x (%i)\n", voice, snd_gf1_i_read16(gus, 0x0c), snd_gf1_i_read16(gus, 0x0c) >> 4);
+ printk(KERN_INFO " -%i- GFA1 right offset final = 0x%x (%i)\n", voice, snd_gf1_i_read16(gus, 0x1b), snd_gf1_i_read16(gus, 0x1b) >> 4);
} else
- printk(" -%i- GF1 pan = 0x%x\n", voice, snd_gf1_i_read8(gus, 0x0c));
+ printk(KERN_INFO " -%i- GF1 pan = 0x%x\n", voice, snd_gf1_i_read8(gus, 0x0c));
} else
- printk(" -%i- GF1 pan = 0x%x\n", voice, snd_gf1_i_read8(gus, 0x0c));
+ printk(KERN_INFO " -%i- GF1 pan = 0x%x\n", voice, snd_gf1_i_read8(gus, 0x0c));
}
#if 0
@@ -481,45 +481,45 @@ void snd_gf1_print_global_registers(snd_gus_card_t * gus)
{
unsigned char global_mode = 0x00;
- printk(" -G- GF1 active voices = 0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_ACTIVE_VOICES));
+ printk(KERN_INFO " -G- GF1 active voices = 0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_ACTIVE_VOICES));
if (gus->interwave) {
global_mode = snd_gf1_i_read8(gus, SNDRV_GF1_GB_GLOBAL_MODE);
- printk(" -G- GF1 global mode = 0x%x\n", global_mode);
+ printk(KERN_INFO " -G- GF1 global mode = 0x%x\n", global_mode);
}
if (global_mode & 0x02) /* LFO enabled? */
- printk(" -G- GF1 LFO base = 0x%x\n", snd_gf1_i_look16(gus, SNDRV_GF1_GW_LFO_BASE));
- printk(" -G- GF1 voices IRQ read = 0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_VOICES_IRQ_READ));
- printk(" -G- GF1 DRAM DMA control = 0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_DRAM_DMA_CONTROL));
- printk(" -G- GF1 DRAM DMA high/low = 0x%x/0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_DRAM_DMA_HIGH), snd_gf1_i_read16(gus, SNDRV_GF1_GW_DRAM_DMA_LOW));
- printk(" -G- GF1 DRAM IO high/low = 0x%x/0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_DRAM_IO_HIGH), snd_gf1_i_read16(gus, SNDRV_GF1_GW_DRAM_IO_LOW));
+ printk(KERN_INFO " -G- GF1 LFO base = 0x%x\n", snd_gf1_i_look16(gus, SNDRV_GF1_GW_LFO_BASE));
+ printk(KERN_INFO " -G- GF1 voices IRQ read = 0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_VOICES_IRQ_READ));
+ printk(KERN_INFO " -G- GF1 DRAM DMA control = 0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_DRAM_DMA_CONTROL));
+ printk(KERN_INFO " -G- GF1 DRAM DMA high/low = 0x%x/0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_DRAM_DMA_HIGH), snd_gf1_i_read16(gus, SNDRV_GF1_GW_DRAM_DMA_LOW));
+ printk(KERN_INFO " -G- GF1 DRAM IO high/low = 0x%x/0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_DRAM_IO_HIGH), snd_gf1_i_read16(gus, SNDRV_GF1_GW_DRAM_IO_LOW));
if (!gus->interwave)
- printk(" -G- GF1 record DMA control = 0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_REC_DMA_CONTROL));
- printk(" -G- GF1 DRAM IO 16 = 0x%x\n", snd_gf1_i_look16(gus, SNDRV_GF1_GW_DRAM_IO16));
+ printk(KERN_INFO " -G- GF1 record DMA control = 0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_REC_DMA_CONTROL));
+ printk(KERN_INFO " -G- GF1 DRAM IO 16 = 0x%x\n", snd_gf1_i_look16(gus, SNDRV_GF1_GW_DRAM_IO16));
if (gus->gf1.enh_mode) {
- printk(" -G- GFA1 memory config = 0x%x\n", snd_gf1_i_look16(gus, SNDRV_GF1_GW_MEMORY_CONFIG));
- printk(" -G- GFA1 memory control = 0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_MEMORY_CONTROL));
- printk(" -G- GFA1 FIFO record base = 0x%x\n", snd_gf1_i_look16(gus, SNDRV_GF1_GW_FIFO_RECORD_BASE_ADDR));
- printk(" -G- GFA1 FIFO playback base = 0x%x\n", snd_gf1_i_look16(gus, SNDRV_GF1_GW_FIFO_PLAY_BASE_ADDR));
- printk(" -G- GFA1 interleave control = 0x%x\n", snd_gf1_i_look16(gus, SNDRV_GF1_GW_INTERLEAVE));
+ printk(KERN_INFO " -G- GFA1 memory config = 0x%x\n", snd_gf1_i_look16(gus, SNDRV_GF1_GW_MEMORY_CONFIG));
+ printk(KERN_INFO " -G- GFA1 memory control = 0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_MEMORY_CONTROL));
+ printk(KERN_INFO " -G- GFA1 FIFO record base = 0x%x\n", snd_gf1_i_look16(gus, SNDRV_GF1_GW_FIFO_RECORD_BASE_ADDR));
+ printk(KERN_INFO " -G- GFA1 FIFO playback base = 0x%x\n", snd_gf1_i_look16(gus, SNDRV_GF1_GW_FIFO_PLAY_BASE_ADDR));
+ printk(KERN_INFO " -G- GFA1 interleave control = 0x%x\n", snd_gf1_i_look16(gus, SNDRV_GF1_GW_INTERLEAVE));
}
}
void snd_gf1_print_setup_registers(snd_gus_card_t * gus)
{
- printk(" -S- mix control = 0x%x\n", inb(GUSP(gus, MIXCNTRLREG)));
- printk(" -S- IRQ status = 0x%x\n", inb(GUSP(gus, IRQSTAT)));
- printk(" -S- timer control = 0x%x\n", inb(GUSP(gus, TIMERCNTRL)));
- printk(" -S- timer data = 0x%x\n", inb(GUSP(gus, TIMERDATA)));
- printk(" -S- status read = 0x%x\n", inb(GUSP(gus, REGCNTRLS)));
- printk(" -S- Sound Blaster control = 0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_SOUND_BLASTER_CONTROL));
- printk(" -S- AdLib timer 1/2 = 0x%x/0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_ADLIB_TIMER_1), snd_gf1_i_look8(gus, SNDRV_GF1_GB_ADLIB_TIMER_2));
- printk(" -S- reset = 0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_RESET));
+ printk(KERN_INFO " -S- mix control = 0x%x\n", inb(GUSP(gus, MIXCNTRLREG)));
+ printk(KERN_INFO " -S- IRQ status = 0x%x\n", inb(GUSP(gus, IRQSTAT)));
+ printk(KERN_INFO " -S- timer control = 0x%x\n", inb(GUSP(gus, TIMERCNTRL)));
+ printk(KERN_INFO " -S- timer data = 0x%x\n", inb(GUSP(gus, TIMERDATA)));
+ printk(KERN_INFO " -S- status read = 0x%x\n", inb(GUSP(gus, REGCNTRLS)));
+ printk(KERN_INFO " -S- Sound Blaster control = 0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_SOUND_BLASTER_CONTROL));
+ printk(KERN_INFO " -S- AdLib timer 1/2 = 0x%x/0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_ADLIB_TIMER_1), snd_gf1_i_look8(gus, SNDRV_GF1_GB_ADLIB_TIMER_2));
+ printk(KERN_INFO " -S- reset = 0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_RESET));
if (gus->interwave) {
- printk(" -S- compatibility = 0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_COMPATIBILITY));
- printk(" -S- decode control = 0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_DECODE_CONTROL));
- printk(" -S- version number = 0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_VERSION_NUMBER));
- printk(" -S- MPU-401 emul. control A/B = 0x%x/0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_MPU401_CONTROL_A), snd_gf1_i_look8(gus, SNDRV_GF1_GB_MPU401_CONTROL_B));
- printk(" -S- emulation IRQ = 0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_EMULATION_IRQ));
+ printk(KERN_INFO " -S- compatibility = 0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_COMPATIBILITY));
+ printk(KERN_INFO " -S- decode control = 0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_DECODE_CONTROL));
+ printk(KERN_INFO " -S- version number = 0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_VERSION_NUMBER));
+ printk(KERN_INFO " -S- MPU-401 emul. control A/B = 0x%x/0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_MPU401_CONTROL_A), snd_gf1_i_look8(gus, SNDRV_GF1_GB_MPU401_CONTROL_B));
+ printk(KERN_INFO " -S- emulation IRQ = 0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_EMULATION_IRQ));
}
}
diff --git a/sound/isa/gus/gus_main.c b/sound/isa/gus/gus_main.c
index 8f2872f8e8f6..4f57ff4ab351 100644
--- a/sound/isa/gus/gus_main.c
+++ b/sound/isa/gus/gus_main.c
@@ -113,14 +113,8 @@ static int snd_gus_free(snd_gus_card_t *gus)
snd_gf1_stop(gus);
snd_gus_init_dma_irq(gus, 0);
__hw_end:
- if (gus->gf1.res_port1) {
- release_resource(gus->gf1.res_port1);
- kfree_nocheck(gus->gf1.res_port1);
- }
- if (gus->gf1.res_port2) {
- release_resource(gus->gf1.res_port2);
- kfree_nocheck(gus->gf1.res_port2);
- }
+ release_and_free_resource(gus->gf1.res_port1);
+ release_and_free_resource(gus->gf1.res_port2);
if (gus->gf1.irq >= 0)
free_irq(gus->gf1.irq, (void *) gus);
if (gus->gf1.dma1 >= 0) {
@@ -252,7 +246,7 @@ static int snd_gus_detect_memory(snd_gus_card_t * gus)
snd_gf1_poke(gus, 0L, 0xaa);
snd_gf1_poke(gus, 1L, 0x55);
if (snd_gf1_peek(gus, 0L) != 0xaa || snd_gf1_peek(gus, 1L) != 0x55) {
- snd_printk("plain GF1 card at 0x%lx without onboard DRAM?\n", gus->gf1.port);
+ snd_printk(KERN_ERR "plain GF1 card at 0x%lx without onboard DRAM?\n", gus->gf1.port);
return -ENOMEM;
}
for (idx = 1, d = 0xab; idx < 4; idx++, d++) {
@@ -305,20 +299,17 @@ static int snd_gus_init_dma_irq(snd_gus_card_t * gus, int latches)
dma2 = gus->gf1.dma2;
dma2 = dma2 < 0 ? -dma2 : dma2;
dma2 = dmas[dma2 & 7];
-#if 0
- printk("dma1 = %i, dma2 = %i\n", gus->gf1.dma1, gus->gf1.dma2);
-#endif
dma1 |= gus->equal_dma ? 0x40 : (dma2 << 3);
if ((dma1 & 7) == 0 || (dma2 & 7) == 0) {
- snd_printk("Error! DMA isn't defined.\n");
+ snd_printk(KERN_ERR "Error! DMA isn't defined.\n");
return -EINVAL;
}
irq = gus->gf1.irq;
irq = irq < 0 ? -irq : irq;
irq = irqs[irq & 0x0f];
if (irq == 0) {
- snd_printk("Error! IRQ isn't defined.\n");
+ snd_printk(KERN_ERR "Error! IRQ isn't defined.\n");
return -EINVAL;
}
irq |= 0x40;
@@ -406,8 +397,8 @@ static int snd_gus_check_version(snd_gus_card_t * gus)
strcpy(card->longname, "Gravis UltraSound Extreme");
gus->ess_flag = 1;
} else {
- snd_printk("unknown GF1 revision number at 0x%lx - 0x%x (0x%x)\n", gus->gf1.port, rev, val);
- snd_printk(" please - report to <perex@suse.cz>\n");
+ snd_printk(KERN_ERR "unknown GF1 revision number at 0x%lx - 0x%x (0x%x)\n", gus->gf1.port, rev, val);
+ snd_printk(KERN_ERR " please - report to <perex@suse.cz>\n");
}
}
}
@@ -431,7 +422,7 @@ int snd_gus_initialize(snd_gus_card_t *gus)
if (!gus->interwave) {
if ((err = snd_gus_check_version(gus)) < 0) {
- snd_printk("version check failed\n");
+ snd_printk(KERN_ERR "version check failed\n");
return err;
}
if ((err = snd_gus_detect_memory(gus)) < 0)
diff --git a/sound/isa/gus/gus_mem.c b/sound/isa/gus/gus_mem.c
index 5eb766dd564b..2e23f2a8c627 100644
--- a/sound/isa/gus/gus_mem.c
+++ b/sound/isa/gus/gus_mem.c
@@ -198,7 +198,7 @@ snd_gf1_mem_block_t *snd_gf1_mem_alloc(snd_gf1_mem_t * alloc, int owner,
if (nblock != NULL) {
if (size != (int)nblock->size) {
/* TODO: remove in the future */
- snd_printk("snd_gf1_mem_alloc - share: sizes differ\n");
+ snd_printk(KERN_ERR "snd_gf1_mem_alloc - share: sizes differ\n");
goto __std;
}
nblock->share++;
diff --git a/sound/isa/gus/gus_pcm.c b/sound/isa/gus/gus_pcm.c
index beb01365dc46..1cc89fb67bf2 100644
--- a/sound/isa/gus/gus_pcm.c
+++ b/sound/isa/gus/gus_pcm.c
@@ -333,8 +333,7 @@ static int snd_gf1_pcm_poke_block(snd_gus_card_t *gus, unsigned char *buf,
}
}
if (count > 0 && !in_interrupt()) {
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(1);
+ schedule_timeout_interruptible(1);
if (signal_pending(current))
return -EAGAIN;
}
@@ -698,7 +697,7 @@ static int snd_gf1_pcm_playback_close(snd_pcm_substream_t * substream)
gus_pcm_private_t *pcmp = runtime->private_data;
if (!wait_event_timeout(pcmp->sleep, (atomic_read(&pcmp->dma_count) <= 0), 2*HZ))
- snd_printk("gf1 pcm - serious DMA problem\n");
+ snd_printk(KERN_ERR "gf1 pcm - serious DMA problem\n");
snd_gf1_dma_done(gus);
return 0;
diff --git a/sound/isa/gus/gus_reset.c b/sound/isa/gus/gus_reset.c
index ef687abc7070..90710969ef7f 100644
--- a/sound/isa/gus/gus_reset.c
+++ b/sound/isa/gus/gus_reset.c
@@ -134,7 +134,7 @@ void snd_gf1_smart_stop_voice(snd_gus_card_t * gus, unsigned short voice)
spin_lock_irqsave(&gus->reg_lock, flags);
snd_gf1_select_voice(gus, voice);
#if 0
- printk(" -%i- smart stop voice - volume = 0x%x\n", voice, snd_gf1_i_read16(gus, SNDRV_GF1_VW_VOLUME));
+ printk(KERN_DEBUG " -%i- smart stop voice - volume = 0x%x\n", voice, snd_gf1_i_read16(gus, SNDRV_GF1_VW_VOLUME));
#endif
snd_gf1_ctrl_stop(gus, SNDRV_GF1_VB_ADDRESS_CONTROL);
snd_gf1_ctrl_stop(gus, SNDRV_GF1_VB_VOLUME_CONTROL);
@@ -148,7 +148,7 @@ void snd_gf1_stop_voice(snd_gus_card_t * gus, unsigned short voice)
spin_lock_irqsave(&gus->reg_lock, flags);
snd_gf1_select_voice(gus, voice);
#if 0
- printk(" -%i- stop voice - volume = 0x%x\n", voice, snd_gf1_i_read16(gus, SNDRV_GF1_VW_VOLUME));
+ printk(KERN_DEBUG " -%i- stop voice - volume = 0x%x\n", voice, snd_gf1_i_read16(gus, SNDRV_GF1_VW_VOLUME));
#endif
snd_gf1_ctrl_stop(gus, SNDRV_GF1_VB_ADDRESS_CONTROL);
snd_gf1_ctrl_stop(gus, SNDRV_GF1_VB_VOLUME_CONTROL);
diff --git a/sound/isa/gus/gus_simple.c b/sound/isa/gus/gus_simple.c
index c122e7be6ceb..dfed85b58b3a 100644
--- a/sound/isa/gus/gus_simple.c
+++ b/sound/isa/gus/gus_simple.c
@@ -136,7 +136,7 @@ static void do_volume_envelope(snd_gus_card_t *gus, snd_gus_voice_t *voice)
snd_gf1_select_voice(gus, voice->number);
snd_gf1_ctrl_stop(gus, SNDRV_GF1_VB_VOLUME_CONTROL);
snd_gf1_write16(gus, SNDRV_GF1_VW_VOLUME, voice->gf1_volume);
- printk("gf1_volume = 0x%x\n", voice->gf1_volume);
+ /* printk("gf1_volume = 0x%x\n", voice->gf1_volume); */
spin_unlock_irqrestore(&gus->reg_lock, flags);
return;
}
diff --git a/sound/isa/gus/gus_uart.c b/sound/isa/gus/gus_uart.c
index 1bc2da8784e0..fbc95e99105c 100644
--- a/sound/isa/gus/gus_uart.c
+++ b/sound/isa/gus/gus_uart.c
@@ -104,7 +104,7 @@ static int snd_gf1_uart_output_open(snd_rawmidi_substream_t * substream)
gus->midi_substream_output = substream;
spin_unlock_irqrestore(&gus->uart_cmd_lock, flags);
#if 0
- snd_printk("write init - cmd = 0x%x, stat = 0x%x\n", gus->gf1.uart_cmd, snd_gf1_uart_stat(gus));
+ snd_printk(KERN_DEBUG "write init - cmd = 0x%x, stat = 0x%x\n", gus->gf1.uart_cmd, snd_gf1_uart_stat(gus));
#endif
return 0;
}
@@ -126,7 +126,7 @@ static int snd_gf1_uart_input_open(snd_rawmidi_substream_t * substream)
for (i = 0; i < 1000 && (snd_gf1_uart_stat(gus) & 0x01); i++)
snd_gf1_uart_get(gus); /* clean Rx */
if (i >= 1000)
- snd_printk("gus midi uart init read - cleanup error\n");
+ snd_printk(KERN_ERR "gus midi uart init read - cleanup error\n");
}
spin_unlock_irqrestore(&gus->uart_cmd_lock, flags);
#if 0
diff --git a/sound/isa/gus/gus_volume.c b/sound/isa/gus/gus_volume.c
index 3d36f6c8ee6a..b3382fec5298 100644
--- a/sound/isa/gus/gus_volume.c
+++ b/sound/isa/gus/gus_volume.c
@@ -119,7 +119,7 @@ unsigned short snd_gf1_translate_freq(snd_gus_card_t * gus, unsigned int freq16)
freq16 = 50;
if (freq16 & 0xf8000000) {
freq16 = ~0xf8000000;
- snd_printk("snd_gf1_translate_freq: overflow - freq = 0x%x\n", freq16);
+ snd_printk(KERN_ERR "snd_gf1_translate_freq: overflow - freq = 0x%x\n", freq16);
}
return ((freq16 << 9) + (gus->gf1.playback_freq >> 1)) / gus->gf1.playback_freq;
}
@@ -203,14 +203,14 @@ unsigned short snd_gf1_compute_freq(unsigned int freq,
fc = (freq << 10) / rate;
if (fc > 97391L) {
fc = 97391;
- snd_printk("patch: (1) fc frequency overflow - %u\n", fc);
+ snd_printk(KERN_ERR "patch: (1) fc frequency overflow - %u\n", fc);
}
fc = (fc * 44100UL) / mix_rate;
while (scale--)
fc <<= 1;
if (fc > 65535L) {
fc = 65535;
- snd_printk("patch: (2) fc frequency overflow - %u\n", fc);
+ snd_printk(KERN_ERR "patch: (2) fc frequency overflow - %u\n", fc);
}
return (unsigned short) fc;
}
diff --git a/sound/isa/gus/interwave.c b/sound/isa/gus/interwave.c
index 358cba9d738f..f703a9f4257c 100644
--- a/sound/isa/gus/interwave.c
+++ b/sound/isa/gus/interwave.c
@@ -437,7 +437,7 @@ static void __devinit snd_interwave_detect_memory(snd_gus_card_t * gus)
for (i = 0; i < 8; ++i)
iwave[i] = snd_gf1_peek(gus, bank_pos + i);
#ifdef CONFIG_SND_DEBUG_ROM
- printk("ROM at 0x%06x = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n", bank_pos,
+ printk(KERN_DEBUG "ROM at 0x%06x = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n", bank_pos,
iwave[0], iwave[1], iwave[2], iwave[3],
iwave[4], iwave[5], iwave[6], iwave[7]);
#endif
@@ -447,7 +447,7 @@ static void __devinit snd_interwave_detect_memory(snd_gus_card_t * gus)
for (i = 0; i < sizeof(struct rom_hdr); i++)
csum += snd_gf1_peek(gus, bank_pos + i);
#ifdef CONFIG_SND_DEBUG_ROM
- printk("ROM checksum = 0x%x (computed)\n", csum);
+ printk(KERN_DEBUG "ROM checksum = 0x%x (computed)\n", csum);
#endif
if (csum != 0)
continue; /* not valid rom */
@@ -638,10 +638,7 @@ static void snd_interwave_free(snd_card_t *card)
if (iwcard == NULL)
return;
#ifdef SNDRV_STB
- if (iwcard->i2c_res) {
- release_resource(iwcard->i2c_res);
- kfree_nocheck(iwcard->i2c_res);
- }
+ release_and_free_resource(iwcard->i2c_res);
#endif
if (iwcard->irq >= 0)
free_irq(iwcard->irq, (void *)iwcard);
diff --git a/sound/isa/opl3sa2.c b/sound/isa/opl3sa2.c
index 4ba268f251e3..47cabda792b6 100644
--- a/sound/isa/opl3sa2.c
+++ b/sound/isa/opl3sa2.c
@@ -656,10 +656,7 @@ static int snd_opl3sa2_free(opl3sa2_t *chip)
{
if (chip->irq >= 0)
free_irq(chip->irq, (void *)chip);
- if (chip->res_port) {
- release_resource(chip->res_port);
- kfree_nocheck(chip->res_port);
- }
+ release_and_free_resource(chip->res_port);
kfree(chip);
return 0;
}
diff --git a/sound/isa/opti9xx/opti92x-ad1848.c b/sound/isa/opti9xx/opti92x-ad1848.c
index 73573cb1db6a..b94339f8306f 100644
--- a/sound/isa/opti9xx/opti92x-ad1848.c
+++ b/sound/isa/opti9xx/opti92x-ad1848.c
@@ -299,10 +299,8 @@ static char * snd_opti9xx_names[] = {
static long snd_legacy_find_free_ioport(long *port_table, long size)
{
while (*port_table != -1) {
- struct resource *res;
- if ((res = request_region(*port_table, size, "ALSA test")) != NULL) {
- release_resource(res);
- kfree_nocheck(res);
+ if (request_region(*port_table, size, "ALSA test")) {
+ release_region(*port_table, size);
return *port_table;
}
port_table++;
@@ -1227,10 +1225,7 @@ static int snd_opti93x_probe(opti93x_t *chip)
static int snd_opti93x_free(opti93x_t *chip)
{
- if (chip->res_port) {
- release_resource(chip->res_port);
- kfree_nocheck(chip->res_port);
- }
+ release_and_free_resource(chip->res_port);
if (chip->dma1 >= 0) {
disable_dma(chip->dma1);
free_dma(chip->dma1);
@@ -1656,8 +1651,7 @@ static int __devinit snd_card_opti9xx_detect(snd_card_t *card, opti9xx_t *chip)
if (value == snd_opti9xx_read(chip, OPTi9XX_MC_REG(1)))
return 1;
- release_resource(chip->res_mc_base);
- kfree_nocheck(chip->res_mc_base);
+ release_and_free_resource(chip->res_mc_base);
chip->res_mc_base = NULL;
}
@@ -1683,8 +1677,7 @@ static int __devinit snd_card_opti9xx_detect(snd_card_t *card, opti9xx_t *chip)
if (snd_opti9xx_read(chip, OPTi9XX_MC_REG(7)) == 0xff - value)
return 1;
- release_resource(chip->res_mc_base);
- kfree_nocheck(chip->res_mc_base);
+ release_and_free_resource(chip->res_mc_base);
chip->res_mc_base = NULL;
}
#endif /* OPTi93X */
@@ -1886,12 +1879,8 @@ static void snd_card_opti9xx_free(snd_card_t *card)
{
opti9xx_t *chip = (opti9xx_t *)card->private_data;
- if (chip) {
- if (chip->res_mc_base) {
- release_resource(chip->res_mc_base);
- kfree_nocheck(chip->res_mc_base);
- }
- }
+ if (chip)
+ release_and_free_resource(chip->res_mc_base);
}
static int snd_card_opti9xx_probe(struct pnp_card_link *pcard,
diff --git a/sound/isa/sb/emu8000.c b/sound/isa/sb/emu8000.c
index 5375705c054b..b09c6575e01a 100644
--- a/sound/isa/sb/emu8000.c
+++ b/sound/isa/sb/emu8000.c
@@ -135,8 +135,7 @@ static void __init
snd_emu8000_read_wait(emu8000_t *emu)
{
while ((EMU8000_SMALR_READ(emu) & 0x80000000) != 0) {
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(1);
+ schedule_timeout_interruptible(1);
if (signal_pending(current))
break;
}
@@ -148,8 +147,7 @@ static void __init
snd_emu8000_write_wait(emu8000_t *emu)
{
while ((EMU8000_SMALW_READ(emu) & 0x80000000) != 0) {
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(1);
+ schedule_timeout_interruptible(1);
if (signal_pending(current))
break;
}
@@ -437,8 +435,7 @@ size_dram(emu8000_t *emu)
for (i = 0; i < 10000; i++) {
if ((EMU8000_SMALW_READ(emu) & 0x80000000) == 0)
break;
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(1);
+ schedule_timeout_interruptible(1);
if (signal_pending(current))
break;
}
@@ -1054,18 +1051,9 @@ __error:
*/
static int snd_emu8000_free(emu8000_t *hw)
{
- if (hw->res_port1) {
- release_resource(hw->res_port1);
- kfree_nocheck(hw->res_port1);
- }
- if (hw->res_port2) {
- release_resource(hw->res_port2);
- kfree_nocheck(hw->res_port2);
- }
- if (hw->res_port3) {
- release_resource(hw->res_port3);
- kfree_nocheck(hw->res_port3);
- }
+ release_and_free_resource(hw->res_port1);
+ release_and_free_resource(hw->res_port2);
+ release_and_free_resource(hw->res_port3);
kfree(hw);
return 0;
}
diff --git a/sound/isa/sb/emu8000_patch.c b/sound/isa/sb/emu8000_patch.c
index 26e693078cb3..2fea67e71c78 100644
--- a/sound/isa/sb/emu8000_patch.c
+++ b/sound/isa/sb/emu8000_patch.c
@@ -109,8 +109,7 @@ static void
snd_emu8000_write_wait(emu8000_t *emu)
{
while ((EMU8000_SMALW_READ(emu) & 0x80000000) != 0) {
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(1);
+ schedule_timeout_interruptible(1);
if (signal_pending(current))
break;
}
diff --git a/sound/isa/sb/emu8000_pcm.c b/sound/isa/sb/emu8000_pcm.c
index 0209790dc4b5..b323beeeda15 100644
--- a/sound/isa/sb/emu8000_pcm.c
+++ b/sound/isa/sb/emu8000_pcm.c
@@ -117,8 +117,7 @@ snd_emu8000_write_wait(emu8000_t *emu, int can_schedule)
{
while ((EMU8000_SMALW_READ(emu) & 0x80000000) != 0) {
if (can_schedule) {
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(1);
+ schedule_timeout_interruptible(1);
if (signal_pending(current))
break;
}
diff --git a/sound/isa/sb/emu8000_synth.c b/sound/isa/sb/emu8000_synth.c
index 1f63aa52d596..f68e217416a6 100644
--- a/sound/isa/sb/emu8000_synth.c
+++ b/sound/isa/sb/emu8000_synth.c
@@ -56,7 +56,7 @@ static int snd_emu8000_new_device(snd_seq_device_t *dev)
emu->num_ports = hw->seq_ports;
if (hw->memhdr) {
- snd_printk("memhdr is already initialized!?\n");
+ snd_printk(KERN_ERR "memhdr is already initialized!?\n");
snd_util_memhdr_free(hw->memhdr);
}
hw->memhdr = snd_util_memhdr_new(hw->mem_size);
diff --git a/sound/isa/sb/sb16.c b/sound/isa/sb/sb16.c
index 7888783d68f5..c2fa451bc8f0 100644
--- a/sound/isa/sb/sb16.c
+++ b/sound/isa/sb/sb16.c
@@ -345,10 +345,7 @@ static void snd_sb16_free(snd_card_t *card)
if (acard == NULL)
return;
- if (acard->fm_res) {
- release_resource(acard->fm_res);
- kfree_nocheck(acard->fm_res);
- }
+ release_and_free_resource(acard->fm_res);
}
#ifdef CONFIG_PNP
diff --git a/sound/isa/sb/sb16_main.c b/sound/isa/sb/sb16_main.c
index a99e642a68b5..556b95e3e22f 100644
--- a/sound/isa/sb/sb16_main.c
+++ b/sound/isa/sb/sb16_main.c
@@ -747,7 +747,7 @@ int snd_sb16dsp_configure(sb_t * chip)
unsigned char realirq, realdma, realmpureg;
/* note: mpu register should be present only on SB16 Vibra soundcards */
- // printk("codec->irq=%i, codec->dma8=%i, codec->dma16=%i\n", chip->irq, chip->dma8, chip->dma16);
+ // printk(KERN_DEBUG "codec->irq=%i, codec->dma8=%i, codec->dma16=%i\n", chip->irq, chip->dma8, chip->dma16);
spin_lock_irqsave(&chip->mixer_lock, flags);
mpureg = snd_sbmixer_read(chip, SB_DSP4_MPUSETUP) & ~0x06;
spin_unlock_irqrestore(&chip->mixer_lock, flags);
@@ -821,9 +821,9 @@ int snd_sb16dsp_configure(sb_t * chip)
spin_unlock_irqrestore(&chip->mixer_lock, flags);
if ((~realirq) & irqreg || (~realdma) & dmareg) {
- snd_printk("SB16 [0x%lx]: unable to set DMA & IRQ (PnP device?)\n", chip->port);
- snd_printk("SB16 [0x%lx]: wanted: irqreg=0x%x, dmareg=0x%x, mpureg = 0x%x\n", chip->port, realirq, realdma, realmpureg);
- snd_printk("SB16 [0x%lx]: got: irqreg=0x%x, dmareg=0x%x, mpureg = 0x%x\n", chip->port, irqreg, dmareg, mpureg);
+ snd_printk(KERN_ERR "SB16 [0x%lx]: unable to set DMA & IRQ (PnP device?)\n", chip->port);
+ snd_printk(KERN_ERR "SB16 [0x%lx]: wanted: irqreg=0x%x, dmareg=0x%x, mpureg = 0x%x\n", chip->port, realirq, realdma, realmpureg);
+ snd_printk(KERN_ERR "SB16 [0x%lx]: got: irqreg=0x%x, dmareg=0x%x, mpureg = 0x%x\n", chip->port, irqreg, dmareg, mpureg);
return -ENODEV;
}
return 0;
diff --git a/sound/isa/sb/sb8.c b/sound/isa/sb/sb8.c
index c41ac25e85ca..0bc0a3afdabc 100644
--- a/sound/isa/sb/sb8.c
+++ b/sound/isa/sb/sb8.c
@@ -78,10 +78,7 @@ static void snd_sb8_free(snd_card_t *card)
if (acard == NULL)
return;
- if (acard->fm_res) {
- release_resource(acard->fm_res);
- kfree_nocheck(acard->fm_res);
- }
+ release_and_free_resource(acard->fm_res);
}
static int __init snd_sb8_probe(int dev)
diff --git a/sound/isa/sb/sb8_main.c b/sound/isa/sb/sb8_main.c
index 87c9b1ba06cf..5ddc6e41d909 100644
--- a/sound/isa/sb/sb8_main.c
+++ b/sound/isa/sb/sb8_main.c
@@ -334,9 +334,6 @@ irqreturn_t snd_sb8dsp_interrupt(sb_t *chip)
snd_pcm_substream_t *substream;
snd_pcm_runtime_t *runtime;
-#if 0
- snd_printk("sb8: interrupt\n");
-#endif
snd_sb_ack_8bit(chip);
switch (chip->mode) {
case SB_MODE_PLAYBACK_8: /* ok.. playback is active */
diff --git a/sound/isa/sb/sb_common.c b/sound/isa/sb/sb_common.c
index f0f205ae425f..603e923b5d2f 100644
--- a/sound/isa/sb/sb_common.c
+++ b/sound/isa/sb/sb_common.c
@@ -45,7 +45,7 @@ int snd_sbdsp_command(sb_t *chip, unsigned char val)
{
int i;
#ifdef IO_DEBUG
- snd_printk("command 0x%x\n", val);
+ snd_printk(KERN_DEBUG "command 0x%x\n", val);
#endif
for (i = BUSY_LOOPS; i; i--)
if ((inb(SBP(chip, STATUS)) & 0x80) == 0) {
@@ -64,7 +64,7 @@ int snd_sbdsp_get_byte(sb_t *chip)
if (inb(SBP(chip, DATA_AVAIL)) & 0x80) {
val = inb(SBP(chip, READ));
#ifdef IO_DEBUG
- snd_printk("get_byte 0x%x\n", val);
+ snd_printk(KERN_DEBUG "get_byte 0x%x\n", val);
#endif
return val;
}
@@ -154,7 +154,7 @@ static int snd_sbdsp_probe(sb_t * chip)
str = "16";
break;
default:
- snd_printk("SB [0x%lx]: unknown DSP chip version %i.%i\n",
+ snd_printk(KERN_INFO "SB [0x%lx]: unknown DSP chip version %i.%i\n",
chip->port, major, minor);
return -ENODEV;
}
@@ -178,10 +178,8 @@ static int snd_sbdsp_probe(sb_t * chip)
static int snd_sbdsp_free(sb_t *chip)
{
- if (chip->res_port) {
- release_resource(chip->res_port);
- kfree_nocheck(chip->res_port);
- }
+ if (chip->res_port)
+ release_and_free_resource(chip->res_port);
if (chip->irq >= 0)
free_irq(chip->irq, (void *) chip);
#ifdef CONFIG_ISA
diff --git a/sound/isa/sb/sb_mixer.c b/sound/isa/sb/sb_mixer.c
index ff4b59968027..5a926a452d38 100644
--- a/sound/isa/sb/sb_mixer.c
+++ b/sound/isa/sb/sb_mixer.c
@@ -36,7 +36,7 @@ void snd_sbmixer_write(sb_t *chip, unsigned char reg, unsigned char data)
outb(data, SBP(chip, MIXER_DATA));
udelay(10);
#ifdef IO_DEBUG
- snd_printk("mixer_write 0x%x 0x%x\n", reg, data);
+ snd_printk(KERN_DEBUG "mixer_write 0x%x 0x%x\n", reg, data);
#endif
}
@@ -49,7 +49,7 @@ unsigned char snd_sbmixer_read(sb_t *chip, unsigned char reg)
result = inb(SBP(chip, MIXER_DATA));
udelay(10);
#ifdef IO_DEBUG
- snd_printk("mixer_read 0x%x 0x%x\n", reg, result);
+ snd_printk(KERN_DEBUG "mixer_read 0x%x 0x%x\n", reg, result);
#endif
return result;
}
diff --git a/sound/isa/sscape.c b/sound/isa/sscape.c
index 9f6b58c79209..11588067fa4f 100644
--- a/sound/isa/sscape.c
+++ b/sound/isa/sscape.c
@@ -338,25 +338,11 @@ static inline void activate_ad1845_unsafe(unsigned io_base)
static void soundscape_free(snd_card_t * c)
{
register struct soundscape *sscape = get_card_soundscape(c);
- release_resource(sscape->io_res);
- kfree_nocheck(sscape->io_res);
+ release_and_free_resource(sscape->io_res);
free_dma(sscape->chip->dma1);
}
/*
- * Put this process into an idle wait-state for a certain number
- * of "jiffies". The process can almost certainly be rescheduled
- * while we're waiting, and so we must NOT be holding any spinlocks
- * when we call this function. If we are then we risk DEADLOCK in
- * SMP (Ha!) or pre-emptible kernels.
- */
-static inline void sleep(long jiffs, int state)
-{
- set_current_state(state);
- schedule_timeout(jiffs);
-}
-
-/*
* Tell the SoundScape to begin a DMA tranfer using the given channel.
* All locking issues are left to the caller.
*/
@@ -393,7 +379,7 @@ static int obp_startup_ack(struct soundscape *s, unsigned timeout)
unsigned long flags;
unsigned char x;
- sleep(1, TASK_INTERRUPTIBLE);
+ schedule_timeout_interruptible(1);
spin_lock_irqsave(&s->lock, flags);
x = inb(HOST_DATA_IO(s->io_base));
@@ -420,7 +406,7 @@ static int host_startup_ack(struct soundscape *s, unsigned timeout)
unsigned long flags;
unsigned char x;
- sleep(1, TASK_INTERRUPTIBLE);
+ schedule_timeout_interruptible(1);
spin_lock_irqsave(&s->lock, flags);
x = inb(HOST_DATA_IO(s->io_base));
@@ -1288,8 +1274,7 @@ static int __devinit create_sscape(const struct params *params, snd_card_t **rca
free_dma(params->dma1);
_release_region:
- release_resource(io_res);
- kfree_nocheck(io_res);
+ release_and_free_resource(io_res);
return err;
}
diff --git a/sound/isa/wavefront/wavefront.c b/sound/isa/wavefront/wavefront.c
index 0a572e0a47e6..1818f1013c3f 100644
--- a/sound/isa/wavefront/wavefront.c
+++ b/sound/isa/wavefront/wavefront.c
@@ -379,10 +379,7 @@ snd_wavefront_free(snd_card_t *card)
snd_wavefront_card_t *acard = (snd_wavefront_card_t *)card->private_data;
if (acard) {
- if (acard->wavefront.res_base != NULL) {
- release_resource(acard->wavefront.res_base);
- kfree_nocheck(acard->wavefront.res_base);
- }
+ release_and_free_resource(acard->wavefront.res_base);
if (acard->wavefront.irq > 0)
free_irq(acard->wavefront.irq, (void *)acard);
}
diff --git a/sound/isa/wavefront/wavefront_synth.c b/sound/isa/wavefront/wavefront_synth.c
index 0c3c951009d8..abd79b781412 100644
--- a/sound/isa/wavefront/wavefront_synth.c
+++ b/sound/isa/wavefront/wavefront_synth.c
@@ -275,8 +275,7 @@ static int
wavefront_sleep (int limit)
{
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(limit);
+ schedule_timeout_interruptible(limit);
return signal_pending(current);
}
@@ -1788,8 +1787,7 @@ wavefront_should_cause_interrupt (snd_wavefront_t *dev,
outb (val,port);
spin_unlock_irq(&dev->irq_lock);
while (1) {
- set_current_state(TASK_INTERRUPTIBLE);
- if ((timeout = schedule_timeout(timeout)) == 0)
+ if ((timeout = schedule_timeout_interruptible(timeout)) == 0)
return;
if (dev->irq_ok)
return;
diff --git a/sound/mips/au1x00.c b/sound/mips/au1x00.c
index 3f9684f1d1d2..d08a42b24b1f 100644
--- a/sound/mips/au1x00.c
+++ b/sound/mips/au1x00.c
@@ -57,8 +57,6 @@ MODULE_CLASSES("{sound}");
MODULE_DEVICES("{{AMD,Au1000 AC'97}}");
#endif
-#define chip_t au1000_t
-
#define PLAYBACK 0
#define CAPTURE 1
#define AC97_SLOT_3 0x01
@@ -474,7 +472,7 @@ snd_au1000_ac97_read(ac97_t *ac97, unsigned short reg)
u32 volatile cmd;
u16 volatile data;
int i;
- spin_lock(au1000->ac97_lock);
+ spin_lock(&au1000->ac97_lock);
/* would rather use the interupt than this polling but it works and I can't
get the interupt driven case to work efficiently */
for (i = 0; i < 0x5000; i++)
@@ -497,7 +495,7 @@ get the interupt driven case to work efficiently */
}
data = au1000->ac97_ioport->cmd & 0xffff;
- spin_unlock(au1000->ac97_lock);
+ spin_unlock(&au1000->ac97_lock);
return data;
@@ -509,7 +507,7 @@ snd_au1000_ac97_write(ac97_t *ac97, unsigned short reg, unsigned short val)
{
u32 cmd;
int i;
- spin_lock(au1000->ac97_lock);
+ spin_lock(&au1000->ac97_lock);
/* would rather use the interupt than this polling but it works and I can't
get the interupt driven case to work efficiently */
for (i = 0; i < 0x5000; i++)
@@ -522,7 +520,7 @@ get the interupt driven case to work efficiently */
cmd &= ~AC97C_READ;
cmd |= ((u32) val << AC97C_WD_BIT);
au1000->ac97_ioport->cmd = cmd;
- spin_unlock(au1000->ac97_lock);
+ spin_unlock(&au1000->ac97_lock);
}
static void
snd_au1000_ac97_free(ac97_t *ac97)
@@ -606,8 +604,7 @@ snd_au1000_free(snd_card_t *card)
/* put internal AC97 block into reset */
au1000->ac97_ioport->cntrl = AC97C_RS;
au1000->ac97_ioport = NULL;
- release_resource(au1000->ac97_res_port);
- kfree_nocheck(au1000->ac97_res_port);
+ release_and_free_resource(au1000->ac97_res_port);
}
if (au1000->stream[PLAYBACK]->dma >= 0)
diff --git a/sound/oss/Kconfig b/sound/oss/Kconfig
index 953e5f3ea03d..88e52dc84c09 100644
--- a/sound/oss/Kconfig
+++ b/sound/oss/Kconfig
@@ -4,9 +4,24 @@
# More hacking for modularisation.
#
# Prompt user for primary drivers.
+
+config OBSOLETE_OSS_DRIVER
+ bool "Obsolete OSS drivers"
+ depends on SOUND_PRIME
+ help
+ This option enables support for obsolete OSS drivers that
+ are scheduled for removal in the near future since there
+ are ALSA drivers for the same hardware.
+
+ Please contact Adrian Bunk <bunk@stusta.de> if you had to
+ say Y here because your soundcard is not properly supported
+ by ALSA.
+
+ If unsure, say N.
+
config SOUND_BT878
tristate "BT878 audio dma"
- depends on SOUND_PRIME && PCI
+ depends on SOUND_PRIME && PCI && OBSOLETE_OSS_DRIVER
---help---
Audio DMA support for bt878 based grabber boards. As you might have
already noticed, bt878 is listed with two functions in /proc/pci.
@@ -22,7 +37,7 @@ config SOUND_BT878
config SOUND_CMPCI
tristate "C-Media PCI (CMI8338/8738)"
- depends on SOUND_PRIME && PCI
+ depends on SOUND_PRIME && PCI && OBSOLETE_OSS_DRIVER
help
Say Y or M if you have a PCI sound card using the CMI8338
or the CMI8738 chipset. Data on these chips are available at
@@ -61,7 +76,7 @@ config SOUND_CMPCI_JOYSTICK
config SOUND_EMU10K1
tristate "Creative SBLive! (EMU10K1)"
- depends on SOUND_PRIME && PCI
+ depends on SOUND_PRIME && PCI && OBSOLETE_OSS_DRIVER
---help---
Say Y or M if you have a PCI sound card using the EMU10K1 chipset,
such as the Creative SBLive!, SB PCI512 or Emu-APS.
@@ -95,7 +110,7 @@ config SOUND_FUSION
config SOUND_CS4281
tristate "Crystal Sound CS4281"
- depends on SOUND_PRIME && PCI
+ depends on SOUND_PRIME && PCI && OBSOLETE_OSS_DRIVER
help
Picture and feature list at
<http://www.pcbroker.com/crystal4281.html>.
@@ -112,7 +127,7 @@ config SOUND_BCM_CS4297A
config SOUND_ES1370
tristate "Ensoniq AudioPCI (ES1370)"
- depends on SOUND_PRIME && PCI
+ depends on SOUND_PRIME && PCI && OBSOLETE_OSS_DRIVER
help
Say Y or M if you have a PCI sound card utilizing the Ensoniq
ES1370 chipset, such as Ensoniq's AudioPCI (non-97). To find
@@ -125,7 +140,7 @@ config SOUND_ES1370
config SOUND_ES1371
tristate "Creative Ensoniq AudioPCI 97 (ES1371)"
- depends on SOUND_PRIME && PCI
+ depends on SOUND_PRIME && PCI && OBSOLETE_OSS_DRIVER
help
Say Y or M if you have a PCI sound card utilizing the Ensoniq
ES1371 chipset, such as Ensoniq's AudioPCI97. To find out if
@@ -138,7 +153,7 @@ config SOUND_ES1371
config SOUND_ESSSOLO1
tristate "ESS Technology Solo1"
- depends on SOUND_PRIME && PCI
+ depends on SOUND_PRIME && PCI && OBSOLETE_OSS_DRIVER
help
Say Y or M if you have a PCI sound card utilizing the ESS Technology
Solo1 chip. To find out if your sound card uses a
@@ -149,7 +164,7 @@ config SOUND_ESSSOLO1
config SOUND_MAESTRO
tristate "ESS Maestro, Maestro2, Maestro2E driver"
- depends on SOUND_PRIME && PCI
+ depends on SOUND_PRIME && PCI && OBSOLETE_OSS_DRIVER
help
Say Y or M if you have a sound system driven by ESS's Maestro line
of PCI sound chips. These include the Maestro 1, Maestro 2, and
@@ -158,7 +173,7 @@ config SOUND_MAESTRO
config SOUND_MAESTRO3
tristate "ESS Maestro3/Allegro driver (EXPERIMENTAL)"
- depends on SOUND_PRIME && PCI && EXPERIMENTAL
+ depends on SOUND_PRIME && PCI && EXPERIMENTAL && OBSOLETE_OSS_DRIVER
help
Say Y or M if you have a sound system driven by ESS's Maestro 3
PCI sound chip.
@@ -172,14 +187,14 @@ config SOUND_ICH
config SOUND_HARMONY
tristate "PA Harmony audio driver"
- depends on GSC_LASI && SOUND_PRIME
+ depends on GSC_LASI && SOUND_PRIME && OBSOLETE_OSS_DRIVER
help
Say 'Y' or 'M' to include support for Harmony soundchip
on HP 712, 715/new and many other GSC based machines.
config SOUND_SONICVIBES
tristate "S3 SonicVibes"
- depends on SOUND_PRIME && PCI
+ depends on SOUND_PRIME && PCI && OBSOLETE_OSS_DRIVER
help
Say Y or M if you have a PCI sound card utilizing the S3
SonicVibes chipset. To find out if your sound card uses a
@@ -218,7 +233,7 @@ config SOUND_VRC5477
config SOUND_AU1000
tristate "Au1000 Sound"
- depends on SOUND_PRIME && (SOC_AU1000 || SOC_AU1100 || SOC_AU1500)
+ depends on SOUND_PRIME && (SOC_AU1000 || SOC_AU1100 || SOC_AU1500) && OBSOLETE_OSS_DRIVER
config SOUND_AU1550_AC97
tristate "Au1550 AC97 Sound"
@@ -492,7 +507,7 @@ config MSND_FIFOSIZE
config SOUND_VIA82CXXX
tristate "VIA 82C686 Audio Codec"
- depends on SOUND_PRIME && PCI
+ depends on SOUND_PRIME && PCI && OBSOLETE_OSS_DRIVER
help
Say Y here to include support for the audio codec found on VIA
82Cxxx-based chips. Typically these are built into a motherboard.
@@ -563,7 +578,7 @@ config SOUND_AD1889
config SOUND_SGALAXY
tristate "Aztech Sound Galaxy (non-PnP) cards"
- depends on SOUND_OSS
+ depends on SOUND_OSS && OBSOLETE_OSS_DRIVER
help
This module initializes the older non Plug and Play sound galaxy
cards from Aztech. It supports the Waverider Pro 32 - 3D and the
@@ -599,7 +614,7 @@ config SOUND_ACI_MIXER
config SOUND_CS4232
tristate "Crystal CS4232 based (PnP) cards"
- depends on SOUND_OSS
+ depends on SOUND_OSS && OBSOLETE_OSS_DRIVER
help
Say Y here if you have a card based on the Crystal CS4232 chip set,
which uses its own Plug and Play protocol.
@@ -613,7 +628,7 @@ config SOUND_CS4232
config SOUND_SSCAPE
tristate "Ensoniq SoundScape support"
- depends on SOUND_OSS
+ depends on SOUND_OSS && OBSOLETE_OSS_DRIVER
help
Answer Y if you have a sound card based on the Ensoniq SoundScape
chipset. Such cards are being manufactured at least by Ensoniq, Spea
@@ -625,7 +640,7 @@ config SOUND_SSCAPE
config SOUND_GUS
tristate "Gravis Ultrasound support"
- depends on SOUND_OSS
+ depends on SOUND_OSS && OBSOLETE_OSS_DRIVER
help
Say Y here for any type of Gravis Ultrasound card, including the GUS
or GUS MAX. See also <file:Documentation/sound/oss/ultrasound> for more
@@ -727,7 +742,7 @@ config SOUND_MPU401
config SOUND_NM256
tristate "NM256AV/NM256ZX audio support"
- depends on SOUND_OSS
+ depends on SOUND_OSS && OBSOLETE_OSS_DRIVER
help
Say M here to include audio support for the NeoMagic 256AV/256ZX
chipsets. These are the audio chipsets found in the Sony
@@ -739,7 +754,7 @@ config SOUND_NM256
config SOUND_MAD16
tristate "OPTi MAD16 and/or Mozart based cards"
- depends on SOUND_OSS
+ depends on SOUND_OSS && OBSOLETE_OSS_DRIVER
---help---
Answer Y if your card has a Mozart (OAK OTI-601) or MAD16 (OPTi
82C928 or 82C929 or 82C931) audio interface chip. These chips are
@@ -860,7 +875,7 @@ config SOUND_SB
config SOUND_AWE32_SYNTH
tristate "AWE32 synth"
- depends on SOUND_OSS
+ depends on SOUND_OSS && OBSOLETE_OSS_DRIVER
help
Say Y here if you have a Sound Blaster SB32, AWE32-PnP, SB AWE64 or
similar sound card. See <file:Documentation/sound/oss/README.awe>,
@@ -870,7 +885,7 @@ config SOUND_AWE32_SYNTH
config SOUND_WAVEFRONT
tristate "Full support for Turtle Beach WaveFront (Tropez Plus, Tropez, Maui) synth/soundcards"
- depends on SOUND_OSS && m
+ depends on SOUND_OSS && m && OBSOLETE_OSS_DRIVER
help
Answer Y or M if you have a Tropez Plus, Tropez or Maui sound card
and read the files <file:Documentation/sound/oss/Wavefront> and
@@ -878,7 +893,7 @@ config SOUND_WAVEFRONT
config SOUND_MAUI
tristate "Limited support for Turtle Beach Wave Front (Maui, Tropez) synthesizers"
- depends on SOUND_OSS
+ depends on SOUND_OSS && OBSOLETE_OSS_DRIVER
help
Say Y here if you have a Turtle Beach Wave Front, Maui, or Tropez
sound card.
@@ -904,7 +919,7 @@ config MAUI_BOOT_FILE
config SOUND_YM3812
tristate "Yamaha FM synthesizer (YM3812/OPL-3) support"
- depends on SOUND_OSS
+ depends on SOUND_OSS && OBSOLETE_OSS_DRIVER
---help---
Answer Y if your card has a FM chip made by Yamaha (OPL2/OPL3/OPL4).
Answering Y is usually a safe and recommended choice, however some
@@ -920,7 +935,7 @@ config SOUND_YM3812
config SOUND_OPL3SA1
tristate "Yamaha OPL3-SA1 audio controller"
- depends on SOUND_OSS
+ depends on SOUND_OSS && OBSOLETE_OSS_DRIVER
help
Say Y or M if you have a Yamaha OPL3-SA1 sound chip, which is
usually built into motherboards. Read
@@ -946,7 +961,7 @@ config SOUND_OPL3SA2
config SOUND_YMFPCI
tristate "Yamaha YMF7xx PCI audio (native mode)"
- depends on SOUND_OSS && PCI
+ depends on SOUND_OSS && PCI && OBSOLETE_OSS_DRIVER
help
Support for Yamaha cards including the YMF711, YMF715, YMF718,
YMF719, YMF724, Waveforce 192XG, and Waveforce 192 Digital.
@@ -1088,11 +1103,11 @@ config SOUND_KAHLUA
config SOUND_ALI5455
tristate "ALi5455 audio support"
- depends on SOUND_PRIME && PCI
+ depends on SOUND_PRIME && PCI && OBSOLETE_OSS_DRIVER
config SOUND_FORTE
tristate "ForteMedia FM801 driver"
- depends on SOUND_PRIME && PCI
+ depends on SOUND_PRIME && PCI && OBSOLETE_OSS_DRIVER
help
Say Y or M if you want driver support for the ForteMedia FM801 PCI
audio controller (Abit AU10, Genius Sound Maker, HP Workstation
@@ -1100,7 +1115,7 @@ config SOUND_FORTE
config SOUND_RME96XX
tristate "RME Hammerfall (RME96XX) support"
- depends on SOUND_PRIME && PCI
+ depends on SOUND_PRIME && PCI && OBSOLETE_OSS_DRIVER
help
Say Y or M if you have a Hammerfall or Hammerfall light
multichannel card from RME. If you want to access advanced
@@ -1108,7 +1123,7 @@ config SOUND_RME96XX
config SOUND_AD1980
tristate "AD1980 front/back switch plugin"
- depends on SOUND_PRIME
+ depends on SOUND_PRIME && OBSOLETE_OSS_DRIVER
config SOUND_SH_DAC_AUDIO
tristate "SuperH DAC audio support"
diff --git a/sound/oss/ac97_codec.c b/sound/oss/ac97_codec.c
index 3ecef4689f1b..fd25aca25120 100644
--- a/sound/oss/ac97_codec.c
+++ b/sound/oss/ac97_codec.c
@@ -55,6 +55,7 @@
#include <linux/pci.h>
#include <linux/ac97_codec.h>
#include <asm/uaccess.h>
+#include <asm/semaphore.h>
#define CODEC_ID_BUFSZ 14
diff --git a/sound/oss/au1000.c b/sound/oss/au1000.c
index 2c2ae2ee01ac..c407de86cbb6 100644
--- a/sound/oss/au1000.c
+++ b/sound/oss/au1000.c
@@ -563,7 +563,7 @@ static void start_adc(struct au1000_state *s)
#define DMABUF_DEFAULTORDER (17-PAGE_SHIFT)
#define DMABUF_MINORDER 1
-extern inline void dealloc_dmabuf(struct au1000_state *s, struct dmabuf *db)
+static inline void dealloc_dmabuf(struct au1000_state *s, struct dmabuf *db)
{
struct page *page, *pend;
@@ -667,14 +667,14 @@ static int prog_dmabuf(struct au1000_state *s, struct dmabuf *db)
return 0;
}
-extern inline int prog_dmabuf_adc(struct au1000_state *s)
+static inline int prog_dmabuf_adc(struct au1000_state *s)
{
stop_adc(s);
return prog_dmabuf(s, &s->dma_adc);
}
-extern inline int prog_dmabuf_dac(struct au1000_state *s)
+static inline int prog_dmabuf_dac(struct au1000_state *s)
{
stop_dac(s);
return prog_dmabuf(s, &s->dma_dac);
diff --git a/sound/oss/au1550_ac97.c b/sound/oss/au1550_ac97.c
index a78e48d412d2..6b46a8a4b1cc 100644
--- a/sound/oss/au1550_ac97.c
+++ b/sound/oss/au1550_ac97.c
@@ -35,7 +35,6 @@
#undef DEBUG
-#include <linux/version.h>
#include <linux/module.h>
#include <linux/string.h>
#include <linux/ioport.h>
diff --git a/sound/oss/awe_wave.c b/sound/oss/awe_wave.c
index d2b9beda8ace..b3ea719d33db 100644
--- a/sound/oss/awe_wave.c
+++ b/sound/oss/awe_wave.c
@@ -6062,7 +6062,7 @@ static int awe_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id
io1 = pnp_port_start(dev,0);
io2 = pnp_port_start(dev,1);
io3 = pnp_port_start(dev,2);
- printk(KERN_INFO "AWE32: A PnP Wave Table was detected at IO's %#x,%#x,%#x\n.",
+ printk(KERN_INFO "AWE32: A PnP Wave Table was detected at IO's %#x,%#x,%#x.\n",
io1, io2, io3);
setup_ports(io1, io2, io3);
diff --git a/sound/oss/cs4232.c b/sound/oss/cs4232.c
index 6ec308f5d935..7c59e2d4003a 100644
--- a/sound/oss/cs4232.c
+++ b/sound/oss/cs4232.c
@@ -195,10 +195,12 @@ static int __init probe_cs4232(struct address_info *hw_config, int isapnp_config
CS_OUT2(0x15, 0x00); /* Select logical device 0 (WSS/SB/FM) */
CS_OUT3(0x47, (base >> 8) & 0xff, base & 0xff); /* WSS base */
- if (check_region(0x388, 4)) /* Not free */
+ if (!request_region(0x388, 4, "FM")) /* Not free */
CS_OUT3(0x48, 0x00, 0x00) /* FM base off */
- else
+ else {
+ release_region(0x388, 4);
CS_OUT3(0x48, 0x03, 0x88); /* FM base 0x388 */
+ }
CS_OUT3(0x42, 0x00, 0x00); /* SB base off */
CS_OUT2(0x22, irq); /* SB+WSS IRQ */
diff --git a/sound/oss/dmasound/dmasound.h b/sound/oss/dmasound/dmasound.h
index 9a2f50f0b184..222014cafc1a 100644
--- a/sound/oss/dmasound/dmasound.h
+++ b/sound/oss/dmasound/dmasound.h
@@ -116,7 +116,7 @@ typedef struct {
const char *name;
const char *name2;
struct module *owner;
- void *(*dma_alloc)(unsigned int, int);
+ void *(*dma_alloc)(unsigned int, gfp_t);
void (*dma_free)(void *, unsigned int);
int (*irqinit)(void);
#ifdef MODULE
diff --git a/sound/oss/dmasound/dmasound_atari.c b/sound/oss/dmasound/dmasound_atari.c
index 8daaf87664ba..59eb53f89318 100644
--- a/sound/oss/dmasound/dmasound_atari.c
+++ b/sound/oss/dmasound/dmasound_atari.c
@@ -114,7 +114,7 @@ static ssize_t ata_ctx_u16le(const u_char *userPtr, size_t userCount,
/*** Low level stuff *********************************************************/
-static void *AtaAlloc(unsigned int size, int flags);
+static void *AtaAlloc(unsigned int size, gfp_t flags);
static void AtaFree(void *, unsigned int size);
static int AtaIrqInit(void);
#ifdef MODULE
@@ -810,7 +810,7 @@ static TRANS transFalconExpanding = {
* Atari (TT/Falcon)
*/
-static void *AtaAlloc(unsigned int size, int flags)
+static void *AtaAlloc(unsigned int size, gfp_t flags)
{
return atari_stram_alloc(size, "dmasound");
}
diff --git a/sound/oss/dmasound/dmasound_awacs.c b/sound/oss/dmasound/dmasound_awacs.c
index 2ceb46f1d40f..cebd881b91ae 100644
--- a/sound/oss/dmasound/dmasound_awacs.c
+++ b/sound/oss/dmasound/dmasound_awacs.c
@@ -271,7 +271,7 @@ int expand_read_bal; /* Balance factor for expanding reads (not volume!) */
/*** Low level stuff *********************************************************/
-static void *PMacAlloc(unsigned int size, int flags);
+static void *PMacAlloc(unsigned int size, gfp_t flags);
static void PMacFree(void *ptr, unsigned int size);
static int PMacIrqInit(void);
#ifdef MODULE
@@ -614,7 +614,7 @@ tas_init_frame_rates(unsigned int *prop, unsigned int l)
/*
* PCI PowerMac, with AWACS, Screamer, Burgundy, DACA or Tumbler and DBDMA.
*/
-static void *PMacAlloc(unsigned int size, int flags)
+static void *PMacAlloc(unsigned int size, gfp_t flags)
{
return kmalloc(size, flags);
}
@@ -2805,16 +2805,7 @@ __init setup_beep(void)
return 0 ;
}
-static struct input_dev awacs_beep_dev = {
- .evbit = { BIT(EV_SND) },
- .sndbit = { BIT(SND_BELL) | BIT(SND_TONE) },
- .event = awacs_beep_event,
- .name = "dmasound beeper",
- .phys = "macio/input0", /* what the heck is this?? */
- .id = {
- .bustype = BUS_HOST,
- },
-};
+static struct input_dev *awacs_beep_dev;
int __init dmasound_awacs_init(void)
{
@@ -2907,6 +2898,22 @@ printk("dmasound_pmac: couldn't find a Codec we can handle\n");
return -ENODEV;
}
+ awacs_beep_dev = input_allocate_device();
+ if (!awacs_beep_dev) {
+ release_OF_resource(io, 0);
+ release_OF_resource(io, 1);
+ release_OF_resource(io, 2);
+ printk(KERN_ERR "dmasound: can't allocate input device !\n");
+ return -ENOMEM;
+ }
+
+ awacs_beep_dev->name = "dmasound beeper";
+ awacs_beep_dev->phys = "macio/input0";
+ awacs_beep_dev->id.bustype = BUS_HOST;
+ awacs_beep_dev->event = awacs_beep_event;
+ awacs_beep_dev->sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE);
+ awacs_beep_dev->evbit[0] = BIT(EV_SND);
+
/* all OF versions I've seen use this value */
if (i2s_node)
i2s = ioremap(io->addrs[0].address, 0x1000);
@@ -3140,14 +3147,14 @@ printk("dmasound_pmac: Awacs/Screamer Codec Mfct: %d Rev %d\n", mfg, rev);
* XXX: we should handle errors here, but that would mean
* rewriting the whole init code. later..
*/
- input_register_device(&awacs_beep_dev);
+ input_register_device(awacs_beep_dev);
return dmasound_init();
}
static void __exit dmasound_awacs_cleanup(void)
{
- input_unregister_device(&awacs_beep_dev);
+ input_unregister_device(awacs_beep_dev);
switch (awacs_revision) {
case AWACS_TUMBLER:
diff --git a/sound/oss/dmasound/dmasound_paula.c b/sound/oss/dmasound/dmasound_paula.c
index 558db5311e06..d59f60b26410 100644
--- a/sound/oss/dmasound/dmasound_paula.c
+++ b/sound/oss/dmasound/dmasound_paula.c
@@ -69,7 +69,7 @@ static int write_sq_block_size_half, write_sq_block_size_quarter;
/*** Low level stuff *********************************************************/
-static void *AmiAlloc(unsigned int size, int flags);
+static void *AmiAlloc(unsigned int size, gfp_t flags);
static void AmiFree(void *obj, unsigned int size);
static int AmiIrqInit(void);
#ifdef MODULE
@@ -317,7 +317,7 @@ static inline void StopDMA(void)
enable_heartbeat();
}
-static void *AmiAlloc(unsigned int size, int flags)
+static void *AmiAlloc(unsigned int size, gfp_t flags)
{
return amiga_chip_alloc((long)size, "dmasound [Paula]");
}
diff --git a/sound/oss/dmasound/dmasound_q40.c b/sound/oss/dmasound/dmasound_q40.c
index 92c25a0174db..1ddaa6284b08 100644
--- a/sound/oss/dmasound/dmasound_q40.c
+++ b/sound/oss/dmasound/dmasound_q40.c
@@ -36,7 +36,7 @@ static int expand_data; /* Data for expanding */
/*** Low level stuff *********************************************************/
-static void *Q40Alloc(unsigned int size, int flags);
+static void *Q40Alloc(unsigned int size, gfp_t flags);
static void Q40Free(void *, unsigned int);
static int Q40IrqInit(void);
#ifdef MODULE
@@ -358,7 +358,7 @@ static TRANS transQ40Compressing = {
/*** Low level stuff *********************************************************/
-static void *Q40Alloc(unsigned int size, int flags)
+static void *Q40Alloc(unsigned int size, gfp_t flags)
{
return kmalloc(size, flags); /* change to vmalloc */
}
diff --git a/sound/oss/msnd.c b/sound/oss/msnd.c
index 4f1ff1bccdce..a7ad2b0a2ac0 100644
--- a/sound/oss/msnd.c
+++ b/sound/oss/msnd.c
@@ -24,7 +24,6 @@
*
********************************************************************/
-#include <linux/version.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/slab.h>
diff --git a/sound/oss/nec_vrc5477.c b/sound/oss/nec_vrc5477.c
index 0481e5e54ddf..9ac4bf7e1e89 100644
--- a/sound/oss/nec_vrc5477.c
+++ b/sound/oss/nec_vrc5477.c
@@ -435,7 +435,7 @@ static int ac97_codec_not_present(struct ac97_codec *codec)
/* --------------------------------------------------------------------- */
-extern inline void
+static inline void
stop_dac(struct vrc5477_ac97_state *s)
{
struct dmabuf* db = &s->dma_dac;
@@ -553,7 +553,7 @@ static void start_dac(struct vrc5477_ac97_state *s)
spin_unlock_irqrestore(&s->lock, flags);
}
-extern inline void stop_adc(struct vrc5477_ac97_state *s)
+static inline void stop_adc(struct vrc5477_ac97_state *s)
{
struct dmabuf* db = &s->dma_adc;
unsigned long flags;
@@ -652,7 +652,7 @@ static void start_adc(struct vrc5477_ac97_state *s)
#define DMABUF_DEFAULTORDER (16-PAGE_SHIFT)
#define DMABUF_MINORDER 1
-extern inline void dealloc_dmabuf(struct vrc5477_ac97_state *s,
+static inline void dealloc_dmabuf(struct vrc5477_ac97_state *s,
struct dmabuf *db)
{
if (db->lbuf) {
diff --git a/sound/oss/os.h b/sound/oss/os.h
index 80dce329cc3a..0490562c7f7f 100644
--- a/sound/oss/os.h
+++ b/sound/oss/os.h
@@ -5,10 +5,8 @@
#undef DO_TIMINGS
#include <linux/module.h>
-#include <linux/version.h>
#ifdef __KERNEL__
-#include <linux/utsname.h>
#include <linux/string.h>
#include <linux/fs.h>
#include <asm/dma.h>
diff --git a/sound/oss/rme96xx.c b/sound/oss/rme96xx.c
index 7609c68a89f4..318dc51009fe 100644
--- a/sound/oss/rme96xx.c
+++ b/sound/oss/rme96xx.c
@@ -44,7 +44,6 @@ TODO:
#define RMEVERSION "0.8"
#endif
-#include <linux/version.h>
#include <linux/module.h>
#include <linux/string.h>
#include <linux/sched.h>
diff --git a/sound/oss/sequencer_syms.c b/sound/oss/sequencer_syms.c
index 45edfd767e4e..5d008798c310 100644
--- a/sound/oss/sequencer_syms.c
+++ b/sound/oss/sequencer_syms.c
@@ -19,7 +19,6 @@ EXPORT_SYMBOL(sequencer_timer);
EXPORT_SYMBOL(sound_timer_init);
EXPORT_SYMBOL(sound_timer_interrupt);
EXPORT_SYMBOL(sound_timer_syncinterval);
-EXPORT_SYMBOL(reprogram_timer);
/* Tuning */
diff --git a/sound/oss/sh_dac_audio.c b/sound/oss/sh_dac_audio.c
index c09cdeedc191..8a9917c919c2 100644
--- a/sound/oss/sh_dac_audio.c
+++ b/sound/oss/sh_dac_audio.c
@@ -2,7 +2,6 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/sched.h>
-#include <linux/version.h>
#include <linux/linkage.h>
#include <linux/slab.h>
#include <linux/fs.h>
diff --git a/sound/oss/soundcard.c b/sound/oss/soundcard.c
index 95fa81e26de2..d33bb464f70e 100644
--- a/sound/oss/soundcard.c
+++ b/sound/oss/soundcard.c
@@ -567,7 +567,7 @@ static int __init oss_init(void)
devfs_mk_cdev(MKDEV(SOUND_MAJOR, dev_list[i].minor),
S_IFCHR | dev_list[i].mode,
"sound/%s", dev_list[i].name);
- class_device_create(sound_class,
+ class_device_create(sound_class, NULL,
MKDEV(SOUND_MAJOR, dev_list[i].minor),
NULL, "%s", dev_list[i].name);
@@ -579,7 +579,7 @@ static int __init oss_init(void)
dev_list[i].minor + (j*0x10)),
S_IFCHR | dev_list[i].mode,
"sound/%s%d", dev_list[i].name, j);
- class_device_create(sound_class,
+ class_device_create(sound_class, NULL,
MKDEV(SOUND_MAJOR, dev_list[i].minor + (j*0x10)),
NULL, "%s%d", dev_list[i].name, j);
}
diff --git a/sound/oss/wavfront.c b/sound/oss/wavfront.c
index b92ba8921638..b1a4eeb9dc08 100644
--- a/sound/oss/wavfront.c
+++ b/sound/oss/wavfront.c
@@ -2434,7 +2434,7 @@ static int __init detect_wavefront (int irq, int io_base)
consumes 16.
*/
- if (check_region (io_base, 16)) {
+ if (!request_region (io_base, 16, "wavfront")) {
printk (KERN_ERR LOGNAME "IO address range 0x%x - 0x%x "
"already in use - ignored\n", dev.base,
dev.base+15);
@@ -2466,10 +2466,13 @@ static int __init detect_wavefront (int irq, int io_base)
} else {
printk (KERN_WARNING LOGNAME "not raw, but no "
"hardware version!\n");
+ release_region (io_base, 16);
return 0;
}
if (!wf_raw) {
+ /* will re-acquire region in install_wavefront() */
+ release_region (io_base, 16);
return 1;
} else {
printk (KERN_INFO LOGNAME
@@ -2489,6 +2492,7 @@ static int __init detect_wavefront (int irq, int io_base)
if (wavefront_hw_reset ()) {
printk (KERN_WARNING LOGNAME "hardware reset failed\n");
+ release_region (io_base, 16);
return 0;
}
@@ -2496,6 +2500,8 @@ static int __init detect_wavefront (int irq, int io_base)
dev.has_fx = (detect_wffx () == 0);
+ /* will re-acquire region in install_wavefront() */
+ release_region (io_base, 16);
return 1;
}
@@ -2804,17 +2810,27 @@ static int __init wavefront_init (int atboot)
}
static int __init install_wavefront (void)
-
{
+ if (!request_region (dev.base+2, 6, "wavefront synth"))
+ return -1;
+
+ if (dev.has_fx) {
+ if (!request_region (dev.base+8, 8, "wavefront fx")) {
+ release_region (dev.base+2, 6);
+ return -1;
+ }
+ }
+
if ((dev.synth_dev = register_sound_synth (&wavefront_fops, -1)) < 0) {
printk (KERN_ERR LOGNAME "cannot register raw synth\n");
- return -1;
+ goto err_out;
}
#if OSS_SUPPORT_LEVEL & OSS_SUPPORT_SEQ
if ((dev.oss_dev = sound_alloc_synthdev()) == -1) {
printk (KERN_ERR LOGNAME "Too many sequencers\n");
- return -1;
+ /* FIXME: leak: should unregister sound synth */
+ goto err_out;
} else {
synth_devs[dev.oss_dev] = &wavefront_operations;
}
@@ -2827,20 +2843,20 @@ static int __init install_wavefront (void)
sound_unload_synthdev (dev.oss_dev);
#endif /* OSS_SUPPORT_SEQ */
- return -1;
+ goto err_out;
}
- request_region (dev.base+2, 6, "wavefront synth");
-
- if (dev.has_fx) {
- request_region (dev.base+8, 8, "wavefront fx");
- }
-
if (wavefront_config_midi ()) {
printk (KERN_WARNING LOGNAME "could not initialize MIDI.\n");
}
return dev.oss_dev;
+
+err_out:
+ release_region (dev.base+2, 6);
+ if (dev.has_fx)
+ release_region (dev.base+8, 8);
+ return -1;
}
static void __exit uninstall_wavefront (void)
diff --git a/sound/oss/ymfpci.c b/sound/oss/ymfpci.c
index 05203ad523f7..8dae59bd05a2 100644
--- a/sound/oss/ymfpci.c
+++ b/sound/oss/ymfpci.c
@@ -107,14 +107,15 @@ static LIST_HEAD(ymf_devs);
*/
static struct pci_device_id ymf_id_tbl[] = {
-#define DEV(v, d, data) \
- { PCI_VENDOR_ID_##v, PCI_DEVICE_ID_##v##_##d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (unsigned long)data }
- DEV (YAMAHA, 724, "YMF724"),
- DEV (YAMAHA, 724F, "YMF724F"),
- DEV (YAMAHA, 740, "YMF740"),
- DEV (YAMAHA, 740C, "YMF740C"),
- DEV (YAMAHA, 744, "YMF744"),
- DEV (YAMAHA, 754, "YMF754"),
+#define DEV(dev, data) \
+ { PCI_VENDOR_ID_YAMAHA, dev, PCI_ANY_ID, PCI_ANY_ID, 0, 0, \
+ (unsigned long)data }
+ DEV (PCI_DEVICE_ID_YAMAHA_724, "YMF724"),
+ DEV (PCI_DEVICE_ID_YAMAHA_724F, "YMF724F"),
+ DEV (PCI_DEVICE_ID_YAMAHA_740, "YMF740"),
+ DEV (PCI_DEVICE_ID_YAMAHA_740C, "YMF740C"),
+ DEV (PCI_DEVICE_ID_YAMAHA_744, "YMF744"),
+ DEV (PCI_DEVICE_ID_YAMAHA_754, "YMF754"),
#undef DEV
{ }
};
diff --git a/sound/parisc/harmony.c b/sound/parisc/harmony.c
index f560dd8cdb90..d833349ed518 100644
--- a/sound/parisc/harmony.c
+++ b/sound/parisc/harmony.c
@@ -197,7 +197,7 @@ snd_harmony_interrupt(int irq, void *dev, struct pt_regs *regs)
spin_unlock(&h->lock);
if (dstatus & HARMONY_DSTATUS_PN) {
- if (h->psubs) {
+ if (h->psubs && h->st.playing) {
spin_lock(&h->lock);
h->pbuf.buf += h->pbuf.count; /* PAGE_SIZE */
h->pbuf.buf %= h->pbuf.size; /* MAX_BUFS*PAGE_SIZE */
@@ -216,7 +216,7 @@ snd_harmony_interrupt(int irq, void *dev, struct pt_regs *regs)
}
if (dstatus & HARMONY_DSTATUS_RN) {
- if (h->csubs) {
+ if (h->csubs && h->st.capturing) {
spin_lock(&h->lock);
h->cbuf.buf += h->cbuf.count;
h->cbuf.buf %= h->cbuf.size;
@@ -316,6 +316,7 @@ snd_harmony_playback_trigger(snd_pcm_substream_t *ss, int cmd)
case SNDRV_PCM_TRIGGER_STOP:
h->st.playing = 0;
harmony_mute(h);
+ harmony_write(h, HARMONY_PNXTADD, h->sdma.addr);
harmony_disable_interrupts(h);
break;
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
@@ -351,8 +352,9 @@ snd_harmony_capture_trigger(snd_pcm_substream_t *ss, int cmd)
break;
case SNDRV_PCM_TRIGGER_STOP:
h->st.capturing = 0;
- harmony_mute(h);
- harmony_disable_interrupts(h);
+ harmony_mute(h);
+ harmony_write(h, HARMONY_RNXTADD, h->gdma.addr);
+ harmony_disable_interrupts(h);
break;
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
@@ -408,7 +410,8 @@ snd_harmony_playback_prepare(snd_pcm_substream_t *ss)
h->pbuf.size = snd_pcm_lib_buffer_bytes(ss);
h->pbuf.count = snd_pcm_lib_period_bytes(ss);
- h->pbuf.buf = 0;
+ if (h->pbuf.buf >= h->pbuf.size)
+ h->pbuf.buf = 0;
h->st.playing = 0;
h->st.rate = snd_harmony_rate_bits(rt->rate);
@@ -437,7 +440,8 @@ snd_harmony_capture_prepare(snd_pcm_substream_t *ss)
h->cbuf.size = snd_pcm_lib_buffer_bytes(ss);
h->cbuf.count = snd_pcm_lib_period_bytes(ss);
- h->cbuf.buf = 0;
+ if (h->cbuf.buf >= h->cbuf.size)
+ h->cbuf.buf = 0;
h->st.capturing = 0;
h->st.rate = snd_harmony_rate_bits(rt->rate);
@@ -712,13 +716,14 @@ snd_harmony_volume_get(snd_kcontrol_t *kc,
left = (h->st.gain >> shift_left) & mask;
right = (h->st.gain >> shift_right) & mask;
-
if (invert) {
left = mask - left;
right = mask - right;
}
+
ucontrol->value.integer.value[0] = left;
- ucontrol->value.integer.value[1] = right;
+ if (shift_left != shift_right)
+ ucontrol->value.integer.value[1] = right;
spin_unlock_irqrestore(&h->mixer_lock, flags);
@@ -738,22 +743,82 @@ snd_harmony_volume_put(snd_kcontrol_t *kc,
int old_gain = h->st.gain;
unsigned long flags;
+ spin_lock_irqsave(&h->mixer_lock, flags);
+
left = ucontrol->value.integer.value[0] & mask;
- right = ucontrol->value.integer.value[1] & mask;
- if (invert) {
+ if (invert)
left = mask - left;
- right = mask - right;
+ h->st.gain &= ~( (mask << shift_left ) );
+ h->st.gain |= (left << shift_left);
+
+ if (shift_left != shift_right) {
+ right = ucontrol->value.integer.value[1] & mask;
+ if (invert)
+ right = mask - right;
+ h->st.gain &= ~( (mask << shift_right) );
+ h->st.gain |= (right << shift_right);
}
+
+ snd_harmony_set_new_gain(h);
+
+ spin_unlock_irqrestore(&h->mixer_lock, flags);
+
+ return h->st.gain != old_gain;
+}
+
+static int
+snd_harmony_captureroute_info(snd_kcontrol_t *kc,
+ snd_ctl_elem_info_t *uinfo)
+{
+ static char *texts[2] = { "Line", "Mic" };
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
+ uinfo->count = 1;
+ uinfo->value.enumerated.items = 2;
+ if (uinfo->value.enumerated.item > 1)
+ uinfo->value.enumerated.item = 1;
+ strcpy(uinfo->value.enumerated.name,
+ texts[uinfo->value.enumerated.item]);
+ return 0;
+}
+
+static int
+snd_harmony_captureroute_get(snd_kcontrol_t *kc,
+ snd_ctl_elem_value_t *ucontrol)
+{
+ harmony_t *h = snd_kcontrol_chip(kc);
+ int value;
+ unsigned long flags;
+
+ spin_lock_irqsave(&h->mixer_lock, flags);
+
+ value = (h->st.gain >> HARMONY_GAIN_IS_SHIFT) & 1;
+ ucontrol->value.enumerated.item[0] = value;
+
+ spin_unlock_irqrestore(&h->mixer_lock, flags);
+
+ return 0;
+}
+
+static int
+snd_harmony_captureroute_put(snd_kcontrol_t *kc,
+ snd_ctl_elem_value_t *ucontrol)
+{
+ harmony_t *h = snd_kcontrol_chip(kc);
+ int value;
+ int old_gain = h->st.gain;
+ unsigned long flags;
spin_lock_irqsave(&h->mixer_lock, flags);
- h->st.gain &= ~( (mask << shift_right) | (mask << shift_left) );
- h->st.gain |= ( (left << shift_left) | (right << shift_right) );
+ value = ucontrol->value.enumerated.item[0] & 1;
+ h->st.gain &= ~HARMONY_GAIN_IS_MASK;
+ h->st.gain |= value << HARMONY_GAIN_IS_SHIFT;
+
snd_harmony_set_new_gain(h);
spin_unlock_irqrestore(&h->mixer_lock, flags);
- return (old_gain - h->st.gain);
+ return h->st.gain != old_gain;
}
#define HARMONY_CONTROLS (sizeof(snd_harmony_controls)/ \
@@ -767,10 +832,25 @@ snd_harmony_volume_put(snd_kcontrol_t *kc,
((mask) << 16) | ((invert) << 24)) }
static snd_kcontrol_new_t snd_harmony_controls[] = {
- HARMONY_VOLUME("Playback Volume", HARMONY_GAIN_LO_SHIFT,
+ HARMONY_VOLUME("Master Playback Volume", HARMONY_GAIN_LO_SHIFT,
HARMONY_GAIN_RO_SHIFT, HARMONY_GAIN_OUT, 1),
HARMONY_VOLUME("Capture Volume", HARMONY_GAIN_LI_SHIFT,
HARMONY_GAIN_RI_SHIFT, HARMONY_GAIN_IN, 0),
+ HARMONY_VOLUME("Monitor Volume", HARMONY_GAIN_MA_SHIFT,
+ HARMONY_GAIN_MA_SHIFT, HARMONY_GAIN_MA, 1),
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "Input Route",
+ .info = snd_harmony_captureroute_info,
+ .get = snd_harmony_captureroute_get,
+ .put = snd_harmony_captureroute_put
+ },
+ HARMONY_VOLUME("Internal Speaker Switch", HARMONY_GAIN_SE_SHIFT,
+ HARMONY_GAIN_SE_SHIFT, 1, 0),
+ HARMONY_VOLUME("Line-Out Switch", HARMONY_GAIN_LE_SHIFT,
+ HARMONY_GAIN_LE_SHIFT, 1, 0),
+ HARMONY_VOLUME("Headphones Switch", HARMONY_GAIN_HE_SHIFT,
+ HARMONY_GAIN_HE_SHIFT, 1, 0),
};
static void __init
@@ -852,14 +932,14 @@ snd_harmony_create(snd_card_t *card,
memset(&h->pbuf, 0, sizeof(h->pbuf));
memset(&h->cbuf, 0, sizeof(h->cbuf));
- h->hpa = padev->hpa;
+ h->hpa = padev->hpa.start;
h->card = card;
h->dev = padev;
h->irq = padev->irq;
- h->iobase = ioremap_nocache(padev->hpa, HARMONY_SIZE);
+ h->iobase = ioremap_nocache(padev->hpa.start, HARMONY_SIZE);
if (h->iobase == NULL) {
printk(KERN_ERR PFX "unable to remap hpa 0x%lx\n",
- padev->hpa);
+ padev->hpa.start);
err = -EBUSY;
goto free_and_ret;
}
diff --git a/sound/parisc/harmony.h b/sound/parisc/harmony.h
index ef77f9a577d5..526c52389de2 100644
--- a/sound/parisc/harmony.h
+++ b/sound/parisc/harmony.h
@@ -61,7 +61,7 @@ typedef struct snd_card_harmony {
#define HARMONY_SIZE 64
#define BUF_SIZE PAGE_SIZE
-#define MAX_BUFS 10
+#define MAX_BUFS 16
#define MAX_BUF_SIZE (MAX_BUFS * BUF_SIZE)
#define PLAYBACK_BUFS MAX_BUFS
@@ -101,28 +101,31 @@ typedef struct snd_card_harmony {
#define HARMONY_SS_MONO 0x00000000
#define HARMONY_SS_STEREO 0x00000001
-#define HARMONY_GAIN_SILENCE 0x00F00FFF
-#define HARMONY_GAIN_DEFAULT 0x0FF00000
+#define HARMONY_GAIN_SILENCE 0x01F00FFF
+#define HARMONY_GAIN_DEFAULT 0x01F00FFF
-#define HARMONY_GAIN_HE_SHIFT 27
+#define HARMONY_GAIN_HE_SHIFT 27 /* headphones enabled */
#define HARMONY_GAIN_HE_MASK (1 << HARMONY_GAIN_HE_SHIFT)
-#define HARMONY_GAIN_LE_SHIFT 26
+#define HARMONY_GAIN_LE_SHIFT 26 /* line-out enabled */
#define HARMONY_GAIN_LE_MASK (1 << HARMONY_GAIN_LE_SHIFT)
-#define HARMONY_GAIN_SE_SHIFT 25
+#define HARMONY_GAIN_SE_SHIFT 25 /* internal-speaker enabled */
#define HARMONY_GAIN_SE_MASK (1 << HARMONY_GAIN_SE_SHIFT)
-#define HARMONY_GAIN_IS_SHIFT 24
+#define HARMONY_GAIN_IS_SHIFT 24 /* input select - 0 for line, 1 for mic */
#define HARMONY_GAIN_IS_MASK (1 << HARMONY_GAIN_IS_SHIFT)
+/* monitor attenuation */
#define HARMONY_GAIN_MA 0x0f
#define HARMONY_GAIN_MA_SHIFT 20
#define HARMONY_GAIN_MA_MASK (HARMONY_GAIN_MA << HARMONY_GAIN_MA_SHIFT)
+/* input gain */
#define HARMONY_GAIN_IN 0x0f
#define HARMONY_GAIN_LI_SHIFT 16
#define HARMONY_GAIN_LI_MASK (HARMONY_GAIN_IN << HARMONY_GAIN_LI_SHIFT)
#define HARMONY_GAIN_RI_SHIFT 12
#define HARMONY_GAIN_RI_MASK (HARMONY_GAIN_IN << HARMONY_GAIN_RI_SHIFT)
+/* output gain (master volume) */
#define HARMONY_GAIN_OUT 0x3f
#define HARMONY_GAIN_LO_SHIFT 6
#define HARMONY_GAIN_LO_MASK (HARMONY_GAIN_OUT << HARMONY_GAIN_LO_SHIFT)
diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig
index a5d593c66f9f..0fb16cf335ea 100644
--- a/sound/pci/Kconfig
+++ b/sound/pci/Kconfig
@@ -1,13 +1,5 @@
# ALSA PCI drivers
-config SND_AC97_CODEC
- tristate
- select SND_PCM
- select SND_AC97_BUS
-
-config SND_AC97_BUS
- tristate
-
menu "PCI devices"
depends on SND!=n && PCI
@@ -192,6 +184,7 @@ config SND_CA0106
tristate "SB Audigy LS / Live 24bit"
depends on SND
select SND_AC97_CODEC
+ select SND_RAWMIDI
help
Say Y here to include support for the Sound Blaster Audigy LS
and Live 24bit.
diff --git a/sound/pci/ac97/ac97_bus.c b/sound/pci/ac97/ac97_bus.c
index becbc420ba41..ec70fadde7d9 100644
--- a/sound/pci/ac97/ac97_bus.c
+++ b/sound/pci/ac97/ac97_bus.c
@@ -31,7 +31,8 @@ static int ac97_bus_suspend(struct device *dev, pm_message_t state)
int ret = 0;
if (dev->driver && dev->driver->suspend)
- ret = dev->driver->suspend(dev, state, SUSPEND_POWER_DOWN);
+ ret = dev->driver->suspend(dev, state);
+
return ret;
}
@@ -40,7 +41,8 @@ static int ac97_bus_resume(struct device *dev)
int ret = 0;
if (dev->driver && dev->driver->resume)
- ret = dev->driver->resume(dev, RESUME_POWER_ON);
+ ret = dev->driver->resume(dev);
+
return ret;
}
diff --git a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c
index 41fc290149ed..9bde76c4c6a2 100644
--- a/sound/pci/ac97/ac97_codec.c
+++ b/sound/pci/ac97/ac97_codec.c
@@ -220,12 +220,6 @@ const char *snd_ac97_stereo_enhancements[] =
/* 31 */ "Reserved 31"
};
-/*
- * Shared AC97 controllers (ICH, ATIIXP...)
- */
-static DECLARE_MUTEX(shared_codec_mutex);
-static ac97_t *shared_codec[AC97_SHARED_TYPES][4];
-
/*
* I/O routines
@@ -996,14 +990,8 @@ static int snd_ac97_free(ac97_t *ac97)
{
if (ac97) {
snd_ac97_proc_done(ac97);
- if (ac97->bus) {
+ if (ac97->bus)
ac97->bus->codec[ac97->num] = NULL;
- if (ac97->bus->shared_type) {
- down(&shared_codec_mutex);
- shared_codec[ac97->bus->shared_type-1][ac97->num] = NULL;
- up(&shared_codec_mutex);
- }
- }
if (ac97->private_free)
ac97->private_free(ac97);
kfree(ac97);
@@ -1139,7 +1127,6 @@ snd_kcontrol_t *snd_ac97_cnew(const snd_kcontrol_new_t *_template, ac97_t * ac97
{
snd_kcontrol_new_t template;
memcpy(&template, _template, sizeof(template));
- snd_runtime_check(!template.index, return NULL);
template.index = ac97->num;
return snd_ctl_new1(&template, ac97);
}
@@ -1758,8 +1745,7 @@ static int ac97_reset_wait(ac97_t *ac97, int timeout, int with_modem)
if ((snd_ac97_read(ac97, AC97_REC_GAIN) & 0x7fff) == 0x0a05)
return 0;
}
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(1);
+ schedule_timeout_uninterruptible(1);
} while (time_after_eq(end_time, jiffies));
return -ENODEV;
}
@@ -1889,21 +1875,6 @@ int snd_ac97_mixer(ac97_bus_t *bus, ac97_template_t *template, ac97_t **rac97)
snd_assert(bus != NULL && template != NULL, return -EINVAL);
snd_assert(template->num < 4 && bus->codec[template->num] == NULL, return -EINVAL);
- snd_assert(bus->shared_type <= AC97_SHARED_TYPES, return -EINVAL);
- if (bus->shared_type) {
- /* already shared? */
- down(&shared_codec_mutex);
- ac97 = shared_codec[bus->shared_type-1][template->num];
- if (ac97) {
- if ((ac97_is_audio(ac97) && (template->scaps & AC97_SCAP_SKIP_AUDIO)) ||
- (ac97_is_modem(ac97) && (template->scaps & AC97_SCAP_SKIP_MODEM))) {
- up(&shared_codec_mutex);
- return -EACCES; /* skip this */
- }
- }
- up(&shared_codec_mutex);
- }
-
card = bus->card;
ac97 = kzalloc(sizeof(*ac97), GFP_KERNEL);
if (ac97 == NULL)
@@ -2020,8 +1991,7 @@ int snd_ac97_mixer(ac97_bus_t *bus, ac97_template_t *template, ac97_t **rac97)
do {
if ((snd_ac97_read(ac97, AC97_POWERDOWN) & 0x0f) == 0x0f)
goto __ready_ok;
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(1);
+ schedule_timeout_uninterruptible(1);
} while (time_after_eq(end_time, jiffies));
snd_printk(KERN_WARNING "AC'97 %d analog subsections not ready\n", ac97->num);
}
@@ -2053,8 +2023,7 @@ int snd_ac97_mixer(ac97_bus_t *bus, ac97_template_t *template, ac97_t **rac97)
do {
if ((snd_ac97_read(ac97, AC97_EXTENDED_MSTATUS) & tmp) == tmp)
goto __ready_ok;
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(1);
+ schedule_timeout_uninterruptible(1);
} while (time_after_eq(end_time, jiffies));
snd_printk(KERN_WARNING "MC'97 %d converters and GPIO not ready (0x%x)\n", ac97->num, snd_ac97_read(ac97, AC97_EXTENDED_MSTATUS));
}
@@ -2077,6 +2046,8 @@ int snd_ac97_mixer(ac97_bus_t *bus, ac97_template_t *template, ac97_t **rac97)
snd_ac97_update_bits(ac97, AC97_GENERAL_PURPOSE, AC97_GP_DRSS_MASK, AC97_GP_DRSS_78);
if ((snd_ac97_read(ac97, AC97_GENERAL_PURPOSE) & AC97_GP_DRSS_MASK) == AC97_GP_DRSS_78)
ac97->flags |= AC97_DOUBLE_RATE;
+ /* restore to slots 10/11 to avoid the confliction with surrounds */
+ snd_ac97_update_bits(ac97, AC97_GENERAL_PURPOSE, AC97_GP_DRSS_MASK, 0);
}
if (ac97->ext_id & AC97_EI_VRA) { /* VRA support */
snd_ac97_determine_rates(ac97, AC97_PCM_FRONT_DAC_RATE, 0, &ac97->rates[AC97_RATES_FRONT_DAC]);
@@ -2153,7 +2124,7 @@ int snd_ac97_mixer(ac97_bus_t *bus, ac97_template_t *template, ac97_t **rac97)
}
}
/* make sure the proper powerdown bits are cleared */
- if (ac97->scaps) {
+ if (ac97->scaps && ac97_is_audio(ac97)) {
reg = snd_ac97_read(ac97, AC97_EXTENDED_STATUS);
if (ac97->scaps & AC97_SCAP_SURROUND_DAC)
reg &= ~AC97_EA_PRJ;
@@ -2167,13 +2138,6 @@ int snd_ac97_mixer(ac97_bus_t *bus, ac97_template_t *template, ac97_t **rac97)
return err;
}
*rac97 = ac97;
-
- if (bus->shared_type) {
- down(&shared_codec_mutex);
- shared_codec[bus->shared_type-1][ac97->num] = ac97;
- up(&shared_codec_mutex);
- }
-
return 0;
}
@@ -2295,8 +2259,7 @@ void snd_ac97_resume(ac97_t *ac97)
do {
if (snd_ac97_read(ac97, AC97_MASTER) == 0x8101)
break;
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(1);
+ schedule_timeout_uninterruptible(1);
} while (time_after_eq(end_time, jiffies));
/* FIXME: extra delay */
ac97->bus->ops->write(ac97, AC97_MASTER, 0x8000);
@@ -2308,8 +2271,7 @@ void snd_ac97_resume(ac97_t *ac97)
unsigned short val = snd_ac97_read(ac97, AC97_EXTENDED_MID);
if (val != 0xffff && (val & 1) != 0)
break;
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(1);
+ schedule_timeout_uninterruptible(1);
} while (time_after_eq(end_time, jiffies));
}
__reset_ready:
diff --git a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c
index 0238cc65d32a..de1c72ad2c6b 100644
--- a/sound/pci/ac97/ac97_patch.c
+++ b/sound/pci/ac97/ac97_patch.c
@@ -163,14 +163,24 @@ static int ac97_channel_mode_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t
.private_value = 1, \
}
+static inline int is_surround_on(ac97_t *ac97)
+{
+ return ac97->channel_mode >= 1;
+}
+
+static inline int is_clfe_on(ac97_t *ac97)
+{
+ return ac97->channel_mode >= 2;
+}
+
static inline int is_shared_linein(ac97_t *ac97)
{
- return ! ac97->indep_surround && ac97->channel_mode >= 1;
+ return ! ac97->indep_surround && is_surround_on(ac97);
}
static inline int is_shared_micin(ac97_t *ac97)
{
- return ! ac97->indep_surround && ac97->channel_mode >= 2;
+ return ! ac97->indep_surround && is_clfe_on(ac97);
}
@@ -1450,7 +1460,8 @@ int patch_ad1881(ac97_t * ac97)
codecs[1] = patch_ad1881_unchained(ac97, 1, (1<<14));
codecs[2] = patch_ad1881_unchained(ac97, 2, (1<<13));
- snd_runtime_check(codecs[0] | codecs[1] | codecs[2], goto __end);
+ if (! (codecs[0] || codecs[1] || codecs[2]))
+ goto __end;
for (idx = 0; idx < 3; idx++)
if (ac97->spec.ad18xx.unchained[idx])
@@ -1753,12 +1764,13 @@ static int snd_ac97_ad1888_downmix_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_va
static void ad1888_update_jacks(ac97_t *ac97)
{
+ unsigned short val = 0;
+ if (! is_shared_linein(ac97))
+ val |= (1 << 12);
+ if (! is_shared_micin(ac97))
+ val |= (1 << 11);
/* shared Line-In */
- snd_ac97_update_bits(ac97, AC97_AD_MISC, 1 << 12,
- is_shared_linein(ac97) ? 0 : 1 << 12);
- /* shared Mic */
- snd_ac97_update_bits(ac97, AC97_AD_MISC, 1 << 11,
- is_shared_micin(ac97) ? 0 : 1 << 11);
+ snd_ac97_update_bits(ac97, AC97_AD_MISC, (1 << 11) | (1 << 12), val);
}
static const snd_kcontrol_new_t snd_ac97_ad1888_controls[] = {
@@ -1852,12 +1864,7 @@ static const snd_kcontrol_new_t snd_ac97_ad1985_controls[] = {
static void ad1985_update_jacks(ac97_t *ac97)
{
- /* shared Line-In */
- snd_ac97_update_bits(ac97, AC97_AD_MISC, 1 << 12,
- is_shared_linein(ac97) ? 0 : 1 << 12);
- /* shared Mic */
- snd_ac97_update_bits(ac97, AC97_AD_MISC, 1 << 11,
- is_shared_micin(ac97) ? 0 : 1 << 11);
+ ad1888_update_jacks(ac97);
snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG, 1 << 9,
is_shared_micin(ac97) ? 0 : 1 << 9);
}
@@ -2442,21 +2449,37 @@ int patch_cm9739(ac97_t * ac97)
static void cm9761_update_jacks(ac97_t *ac97)
{
- unsigned short surr_vals[2][2] = {
- { 0x0008, 0x0400 }, /* off, on */
- { 0x0000, 0x0408 }, /* off, on (9761-82 rev.B) */
+ /* FIXME: check the bits for each model
+ * model 83 is confirmed to work
+ */
+ static unsigned short surr_on[3][2] = {
+ { 0x0008, 0x0000 }, /* 9761-78 & 82 */
+ { 0x0000, 0x0008 }, /* 9761-82 rev.B */
+ { 0x0000, 0x0008 }, /* 9761-83 */
+ };
+ static unsigned short clfe_on[3][2] = {
+ { 0x0000, 0x1000 }, /* 9761-78 & 82 */
+ { 0x1000, 0x0000 }, /* 9761-82 rev.B */
+ { 0x0000, 0x1000 }, /* 9761-83 */
+ };
+ static unsigned short surr_shared[3][2] = {
+ { 0x0000, 0x0400 }, /* 9761-78 & 82 */
+ { 0x0000, 0x0400 }, /* 9761-82 rev.B */
+ { 0x0000, 0x0400 }, /* 9761-83 */
};
- unsigned short clfe_vals[2][2] = {
- { 0x2000, 0x1880 }, /* off, on */
- { 0x1000, 0x2880 }, /* off, on (9761-82 rev.B) */
+ static unsigned short clfe_shared[3][2] = {
+ { 0x2000, 0x0880 }, /* 9761-78 & 82 */
+ { 0x0000, 0x2880 }, /* 9761-82 rev.B */
+ { 0x2000, 0x0800 }, /* 9761-83 */
};
+ unsigned short val = 0;
- /* shared Line-In */
- snd_ac97_update_bits(ac97, AC97_CM9761_MULTI_CHAN, 0x0408,
- surr_vals[ac97->spec.dev_flags][is_shared_linein(ac97)]);
- /* shared Mic */
- snd_ac97_update_bits(ac97, AC97_CM9761_MULTI_CHAN, 0x3880,
- clfe_vals[ac97->spec.dev_flags][is_shared_micin(ac97)]);
+ val |= surr_on[ac97->spec.dev_flags][is_surround_on(ac97)];
+ val |= clfe_on[ac97->spec.dev_flags][is_clfe_on(ac97)];
+ val |= surr_shared[ac97->spec.dev_flags][is_shared_linein(ac97)];
+ val |= clfe_shared[ac97->spec.dev_flags][is_shared_micin(ac97)];
+
+ snd_ac97_update_bits(ac97, AC97_CM9761_MULTI_CHAN, 0x3c88, val);
}
static const snd_kcontrol_new_t snd_ac97_cm9761_controls[] = {
@@ -2551,7 +2574,7 @@ int patch_cm9761(ac97_t *ac97)
snd_ac97_write_cache(ac97, AC97_MASTER, 0x8808);
snd_ac97_write_cache(ac97, AC97_PCM, 0x8808);
- ac97->spec.dev_flags = 0; /* 1 = model 82 revision B */
+ ac97->spec.dev_flags = 0; /* 1 = model 82 revision B, 2 = model 83 */
if (ac97->id == AC97_ID_CM9761_82) {
unsigned short tmp;
/* check page 1, reg 0x60 */
@@ -2560,7 +2583,8 @@ int patch_cm9761(ac97_t *ac97)
tmp = snd_ac97_read(ac97, 0x60);
ac97->spec.dev_flags = tmp & 1; /* revision B? */
snd_ac97_write_cache(ac97, AC97_INT_PAGING, val);
- }
+ } else if (ac97->id == AC97_ID_CM9761_83)
+ ac97->spec.dev_flags = 2;
ac97->build_ops = &patch_cm9761_ops;
diff --git a/sound/pci/ac97/ac97_pcm.c b/sound/pci/ac97/ac97_pcm.c
index dd289b9512e1..ded13165d635 100644
--- a/sound/pci/ac97/ac97_pcm.c
+++ b/sound/pci/ac97/ac97_pcm.c
@@ -303,6 +303,15 @@ int snd_ac97_set_rate(ac97_t *ac97, int reg, unsigned int rate)
AC97_EA_DRA, dbl ? AC97_EA_DRA : 0);
snd_ac97_update(ac97, reg, tmp & 0xffff);
snd_ac97_read(ac97, reg);
+ if ((ac97->ext_id & AC97_EI_DRA) && reg == AC97_PCM_FRONT_DAC_RATE) {
+ /* Intel controllers require double rate data to be put in
+ * slots 7+8
+ */
+ snd_ac97_update_bits(ac97, AC97_GENERAL_PURPOSE,
+ AC97_GP_DRSS_MASK,
+ dbl ? AC97_GP_DRSS_78 : 0);
+ snd_ac97_read(ac97, AC97_GENERAL_PURPOSE);
+ }
return 0;
}
diff --git a/sound/pci/ad1889.c b/sound/pci/ad1889.c
index d7d99a25c5e5..1fdae678a345 100644
--- a/sound/pci/ad1889.c
+++ b/sound/pci/ad1889.c
@@ -50,7 +50,7 @@
#include "ad1889.h"
#include "ac97/ac97_id.h"
-#define AD1889_DRVVER "$Revision: 1.3 $"
+#define AD1889_DRVVER "$Revision: 1.4 $"
MODULE_AUTHOR("Kyle McMartin <kyle@parisc-linux.org>, Thibaut Varene <t-bone@parisc-linux.org>");
MODULE_DESCRIPTION("Analog Devices AD1889 ALSA sound driver");
@@ -982,8 +982,7 @@ snd_ad1889_create(snd_card_t *card,
return 0;
free_and_ret:
- if (chip)
- kfree(chip);
+ kfree(chip);
pci_disable_device(pci);
return err;
@@ -1068,7 +1067,6 @@ MODULE_DEVICE_TABLE(pci, snd_ad1889_ids);
static struct pci_driver ad1889_pci = {
.name = "AD1889 Audio",
- .owner = THIS_MODULE,
.id_table = snd_ad1889_ids,
.probe = snd_ad1889_probe,
.remove = __devexit_p(snd_ad1889_remove),
diff --git a/sound/pci/ali5451/ali5451.c b/sound/pci/ali5451/ali5451.c
index f35b558c29b2..feffbe73387e 100644
--- a/sound/pci/ali5451/ali5451.c
+++ b/sound/pci/ali5451/ali5451.c
@@ -45,23 +45,25 @@ MODULE_DESCRIPTION("ALI M5451");
MODULE_LICENSE("GPL");
MODULE_SUPPORTED_DEVICE("{{ALI,M5451,pci},{ALI,M5451}}");
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
-static int pcm_channels[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 32};
-static int spdif[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0};
+static int index = SNDRV_DEFAULT_IDX1; /* Index */
+static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */
+static int pcm_channels = 32;
+static int spdif = 0;
-module_param_array(index, int, NULL, 0444);
+module_param(index, int, 0444);
MODULE_PARM_DESC(index, "Index value for ALI M5451 PCI Audio.");
-module_param_array(id, charp, NULL, 0444);
+module_param(id, charp, 0444);
MODULE_PARM_DESC(id, "ID string for ALI M5451 PCI Audio.");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable ALI 5451 PCI Audio.");
-module_param_array(pcm_channels, int, NULL, 0444);
+module_param(pcm_channels, int, 0444);
MODULE_PARM_DESC(pcm_channels, "PCM Channels");
-module_param_array(spdif, bool, NULL, 0444);
+module_param(spdif, bool, 0444);
MODULE_PARM_DESC(spdif, "Support SPDIF I/O");
+/* just for backward compatibility */
+static int enable;
+module_param(enable, bool, 0444);
+
+
/*
* Debug part definitions
*/
@@ -396,10 +398,8 @@ static int snd_ali_codec_ready( ali_t *codec,
res = snd_ali_5451_peek(codec,port);
if (! (res & 0x8000))
return 0;
- if (sched) {
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(1);
- }
+ if (sched)
+ schedule_timeout_uninterruptible(1);
} while (time_after_eq(end_time, jiffies));
snd_ali_5451_poke(codec, port, res & ~0x8000);
snd_printdd("ali_codec_ready: codec is not ready.\n ");
@@ -419,12 +419,10 @@ static int snd_ali_stimer_ready(ali_t *codec, int sched)
dwChk2 = snd_ali_5451_peek(codec, ALI_STIMER);
if (dwChk2 != dwChk1)
return 0;
- if (sched) {
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(1);
- }
+ if (sched)
+ schedule_timeout_uninterruptible(1);
} while (time_after_eq(end_time, jiffies));
- snd_printk("ali_stimer_read: stimer is not ready.\n");
+ snd_printk(KERN_ERR "ali_stimer_read: stimer is not ready.\n");
return -EIO;
}
@@ -436,7 +434,7 @@ static void snd_ali_codec_poke(ali_t *codec,int secondary,
unsigned int port = 0;
if (reg >= 0x80) {
- snd_printk("ali_codec_poke: reg(%xh) invalid.\n", reg);
+ snd_printk(KERN_ERR "ali_codec_poke: reg(%xh) invalid.\n", reg);
return;
}
@@ -465,7 +463,7 @@ static unsigned short snd_ali_codec_peek( ali_t *codec,
unsigned int port = 0;
if (reg >= 0x80) {
- snd_printk("ali_codec_peek: reg(%xh) invalid.\n", reg);
+ snd_printk(KERN_ERR "ali_codec_peek: reg(%xh) invalid.\n", reg);
return ~0;
}
@@ -669,7 +667,7 @@ static int snd_ali_alloc_pcm_channel(ali_t *codec, int channel)
unsigned int idx = channel & 0x1f;
if (codec->synth.chcnt >= ALI_CHANNELS){
- snd_printk("ali_alloc_pcm_channel: no free channels.\n");
+ snd_printk(KERN_ERR "ali_alloc_pcm_channel: no free channels.\n");
return -1;
}
@@ -700,7 +698,7 @@ static int snd_ali_find_free_channel(ali_t * codec, int rec)
if ((result = snd_ali_alloc_pcm_channel(codec,idx)) >= 0) {
return result;
} else {
- snd_printk("ali_find_free_channel: record channel is busy now.\n");
+ snd_printk(KERN_ERR "ali_find_free_channel: record channel is busy now.\n");
return -1;
}
}
@@ -712,7 +710,7 @@ static int snd_ali_find_free_channel(ali_t * codec, int rec)
if ((result = snd_ali_alloc_pcm_channel(codec,idx)) >= 0) {
return result;
} else {
- snd_printk("ali_find_free_channel: S/PDIF out channel is in busy now.\n");
+ snd_printk(KERN_ERR "ali_find_free_channel: S/PDIF out channel is in busy now.\n");
}
}
@@ -720,7 +718,7 @@ static int snd_ali_find_free_channel(ali_t * codec, int rec)
if ((result = snd_ali_alloc_pcm_channel(codec,idx)) >= 0)
return result;
}
- snd_printk("ali_find_free_channel: no free channels.\n");
+ snd_printk(KERN_ERR "ali_find_free_channel: no free channels.\n");
return -1;
}
@@ -734,7 +732,7 @@ static void snd_ali_free_channel_pcm(ali_t *codec, int channel)
return;
if (!(codec->synth.chmap & (1 << idx))) {
- snd_printk("ali_free_channel_pcm: channel %d is not in use.\n",channel);
+ snd_printk(KERN_ERR "ali_free_channel_pcm: channel %d is not in use.\n",channel);
return;
} else {
codec->synth.chmap &= ~(1 << idx);
@@ -796,7 +794,7 @@ static void snd_ali_detect_spdif_rate(ali_t *codec)
}
if (count > 50000) {
- snd_printk("ali_detect_spdif_rate: timeout!\n");
+ snd_printk(KERN_ERR "ali_detect_spdif_rate: timeout!\n");
return;
}
@@ -809,7 +807,7 @@ static void snd_ali_detect_spdif_rate(ali_t *codec)
}
if (count > 50000) {
- snd_printk("ali_detect_spdif_rate: timeout!\n");
+ snd_printk(KERN_ERR "ali_detect_spdif_rate: timeout!\n");
return;
}
@@ -1077,7 +1075,7 @@ static snd_ali_voice_t *snd_ali_alloc_voice(ali_t * codec, int type, int rec, in
idx = channel > 0 ? snd_ali_alloc_pcm_channel(codec, channel) :
snd_ali_find_free_channel(codec,rec);
if(idx < 0) {
- snd_printk("ali_alloc_voice: err.\n");
+ snd_printk(KERN_ERR "ali_alloc_voice: err.\n");
spin_unlock_irqrestore(&codec->voice_alloc, flags);
return NULL;
}
@@ -1479,13 +1477,13 @@ static int snd_ali_prepare(snd_pcm_substream_t * substream)
}
rate = snd_ali_get_spdif_in_rate(codec);
if (rate == 0) {
- snd_printk("ali_capture_preapre: spdif rate detect err!\n");
+ snd_printk(KERN_WARNING "ali_capture_preapre: spdif rate detect err!\n");
rate = 48000;
}
bValue = inb(ALI_REG(codec,ALI_SPDIF_CTRL));
if (bValue & 0x10) {
outb(bValue,ALI_REG(codec,ALI_SPDIF_CTRL));
- printk("clear SPDIF parity error flag.\n");
+ printk(KERN_WARNING "clear SPDIF parity error flag.\n");
}
if (rate != 48000)
@@ -1795,6 +1793,7 @@ struct ali_pcm_description {
unsigned int capture_num;
snd_pcm_ops_t *playback_ops;
snd_pcm_ops_t *capture_ops;
+ unsigned short class;
};
@@ -1813,12 +1812,11 @@ static int __devinit snd_ali_pcm(ali_t * codec, int device, struct ali_pcm_descr
err = snd_pcm_new(codec->card, desc->name, device,
desc->playback_num, desc->capture_num, &pcm);
if (err < 0) {
- snd_printk("snd_ali_pcm: err called snd_pcm_new.\n");
+ snd_printk(KERN_ERR "snd_ali_pcm: err called snd_pcm_new.\n");
return err;
}
pcm->private_data = codec;
pcm->private_free = snd_ali_pcm_free;
- pcm->info_flags = 0;
if (desc->playback_ops)
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, desc->playback_ops);
if (desc->capture_ops)
@@ -1828,6 +1826,7 @@ static int __devinit snd_ali_pcm(ali_t * codec, int device, struct ali_pcm_descr
snd_dma_pci_data(codec->pci), 64*1024, 128*1024);
pcm->info_flags = 0;
+ pcm->dev_class = desc->class;
pcm->dev_subclass = SNDRV_PCM_SUBCLASS_GENERIC_MIX;
strcpy(pcm->name, desc->name);
codec->pcm[0] = pcm;
@@ -1836,7 +1835,7 @@ static int __devinit snd_ali_pcm(ali_t * codec, int device, struct ali_pcm_descr
static struct ali_pcm_description ali_pcms[] = {
{ "ALI 5451", ALI_CHANNELS, 1, &snd_ali_playback_ops, &snd_ali_capture_ops },
- { "ALI 5451 modem", 1, 1, &snd_ali_modem_playback_ops, &snd_ali_modem_capture_ops }
+ { "ALI 5451 modem", 1, 1, &snd_ali_modem_playback_ops, &snd_ali_modem_capture_ops, SNDRV_PCM_CLASS_MODEM }
};
static int __devinit snd_ali_build_pcms(ali_t *codec)
@@ -1991,7 +1990,7 @@ static int __devinit snd_ali_mixer(ali_t * codec)
for ( i = 0 ; i < codec->num_of_codecs ; i++) {
ac97.num = i;
if ((err = snd_ac97_mixer(codec->ac97_bus, &ac97, &codec->ac97[i])) < 0) {
- snd_printk("ali mixer %d creating error.\n", i);
+ snd_printk(KERN_ERR "ali mixer %d creating error.\n", i);
if(i == 0)
return err;
codec->num_of_codecs = 1;
@@ -2125,7 +2124,7 @@ static int snd_ali_chip_init(ali_t *codec)
snd_ali_printk("chip initializing ... \n");
if (snd_ali_reset_5451(codec)) {
- snd_printk("ali_chip_init: reset 5451 error.\n");
+ snd_printk(KERN_ERR "ali_chip_init: reset 5451 error.\n");
return -1;
}
@@ -2200,7 +2199,7 @@ static int __devinit snd_ali_resources(ali_t *codec)
codec->port = pci_resource_start(codec->pci, 0);
if (request_irq(codec->pci->irq, snd_ali_card_interrupt, SA_INTERRUPT|SA_SHIRQ, "ALI 5451", (void *)codec)) {
- snd_printk("Unable to request irq.\n");
+ snd_printk(KERN_ERR "Unable to request irq.\n");
return -EBUSY;
}
codec->irq = codec->pci->irq;
@@ -2240,7 +2239,7 @@ static int __devinit snd_ali_create(snd_card_t * card,
/* check, if we can restrict PCI DMA transfers to 31 bits */
if (pci_set_dma_mask(pci, 0x7fffffff) < 0 ||
pci_set_consistent_dma_mask(pci, 0x7fffffff) < 0) {
- snd_printk("architecture does not support 31bit PCI busmaster DMA\n");
+ snd_printk(KERN_ERR "architecture does not support 31bit PCI busmaster DMA\n");
pci_disable_device(pci);
return -ENXIO;
}
@@ -2329,7 +2328,7 @@ static int __devinit snd_ali_create(snd_card_t * card,
}
if ((err = snd_ali_chip_init(codec)) < 0) {
- snd_printk("ali create: chip init error.\n");
+ snd_printk(KERN_ERR "ali create: chip init error.\n");
return err;
}
@@ -2352,25 +2351,17 @@ static int __devinit snd_ali_create(snd_card_t * card,
static int __devinit snd_ali_probe(struct pci_dev *pci,
const struct pci_device_id *pci_id)
{
- static int dev;
snd_card_t *card;
ali_t *codec;
int err;
snd_ali_printk("probe ...\n");
- if (dev >= SNDRV_CARDS)
- return -ENODEV;
- if (!enable[dev]) {
- dev++;
- return -ENOENT;
- }
-
- card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
+ card = snd_card_new(index, id, THIS_MODULE, 0);
if (card == NULL)
return -ENOMEM;
- if ((err = snd_ali_create(card, pci, pcm_channels[dev], spdif[dev], &codec)) < 0) {
+ if ((err = snd_ali_create(card, pci, pcm_channels, spdif, &codec)) < 0) {
snd_card_free(card);
return err;
}
@@ -2401,7 +2392,6 @@ static int __devinit snd_ali_probe(struct pci_dev *pci,
return err;
}
pci_set_drvdata(pci, card);
- dev++;
return 0;
}
@@ -2413,7 +2403,6 @@ static void __devexit snd_ali_remove(struct pci_dev *pci)
static struct pci_driver driver = {
.name = "ALI 5451",
- .owner = THIS_MODULE,
.id_table = snd_ali_ids,
.probe = snd_ali_probe,
.remove = __devexit_p(snd_ali_remove),
diff --git a/sound/pci/als4000.c b/sound/pci/als4000.c
index 196ec1c61bb4..1904df650265 100644
--- a/sound/pci/als4000.c
+++ b/sound/pci/als4000.c
@@ -594,8 +594,7 @@ static int __devinit snd_als4000_create_gameport(snd_card_als4000_t *acard, int
acard->gameport = gp = gameport_allocate_port();
if (!gp) {
printk(KERN_ERR "als4000: cannot allocate memory for gameport\n");
- release_resource(r);
- kfree_nocheck(r);
+ release_and_free_resource(r);
return -ENOMEM;
}
@@ -622,8 +621,7 @@ static void snd_als4000_free_gameport(snd_card_als4000_t *acard)
acard->gameport = NULL;
snd_als4000_set_addr(acard->gcr, 0, 0, 0, 0); /* disable joystick */
- release_resource(r);
- kfree_nocheck(r);
+ release_and_free_resource(r);
}
}
#else
@@ -669,7 +667,7 @@ static int __devinit snd_card_als4000_probe(struct pci_dev *pci,
/* check, if we can restrict PCI DMA transfers to 24 bits */
if (pci_set_dma_mask(pci, 0x00ffffff) < 0 ||
pci_set_consistent_dma_mask(pci, 0x00ffffff) < 0) {
- snd_printk("architecture does not support 24bit PCI busmaster DMA\n");
+ snd_printk(KERN_ERR "architecture does not support 24bit PCI busmaster DMA\n");
pci_disable_device(pci);
return -ENXIO;
}
@@ -770,7 +768,6 @@ static void __devexit snd_card_als4000_remove(struct pci_dev *pci)
static struct pci_driver driver = {
.name = "ALS4000",
- .owner = THIS_MODULE,
.id_table = snd_als4000_ids,
.probe = snd_card_als4000_probe,
.remove = __devexit_p(snd_card_als4000_remove),
diff --git a/sound/pci/atiixp.c b/sound/pci/atiixp.c
index 241eacf1e652..8bae10d93529 100644
--- a/sound/pci/atiixp.c
+++ b/sound/pci/atiixp.c
@@ -39,26 +39,27 @@ MODULE_DESCRIPTION("ATI IXP AC97 controller");
MODULE_LICENSE("GPL");
MODULE_SUPPORTED_DEVICE("{{ATI,IXP150/200/250/300/400}}");
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
-static int ac97_clock[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 48000};
-static char *ac97_quirk[SNDRV_CARDS];
-static int spdif_aclink[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1};
-
-module_param_array(index, int, NULL, 0444);
+static int index = SNDRV_DEFAULT_IDX1; /* Index 0-MAX */
+static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */
+static int ac97_clock = 48000;
+static char *ac97_quirk;
+static int spdif_aclink = 1;
+
+module_param(index, int, 0444);
MODULE_PARM_DESC(index, "Index value for ATI IXP controller.");
-module_param_array(id, charp, NULL, 0444);
+module_param(id, charp, 0444);
MODULE_PARM_DESC(id, "ID string for ATI IXP controller.");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable audio part of ATI IXP controller.");
-module_param_array(ac97_clock, int, NULL, 0444);
+module_param(ac97_clock, int, 0444);
MODULE_PARM_DESC(ac97_clock, "AC'97 codec clock (default 48000Hz).");
-module_param_array(ac97_quirk, charp, NULL, 0444);
+module_param(ac97_quirk, charp, 0444);
MODULE_PARM_DESC(ac97_quirk, "AC'97 workaround for strange hardware.");
-module_param_array(spdif_aclink, bool, NULL, 0444);
+module_param(spdif_aclink, bool, 0444);
MODULE_PARM_DESC(spdif_aclink, "S/PDIF over AC-link.");
+/* just for backward compatibility */
+static int enable;
+module_param(enable, bool, 0444);
+
/*
*/
@@ -329,8 +330,7 @@ static int snd_atiixp_update_bits(atiixp_t *chip, unsigned int reg,
/* delay for one tick */
#define do_delay() do { \
- set_current_state(TASK_UNINTERRUPTIBLE); \
- schedule_timeout(1); \
+ schedule_timeout_uninterruptible(1); \
} while (0)
@@ -1372,7 +1372,6 @@ static int __devinit snd_atiixp_mixer_new(atiixp_t *chip, int clock, const char
if ((err = snd_ac97_bus(chip->card, 0, &ops, chip, &pbus)) < 0)
return err;
pbus->clock = clock;
- pbus->shared_type = AC97_SHARED_TYPE_ATIIXP; /* shared with modem driver */
chip->ac97_bus = pbus;
codec_count = 0;
@@ -1579,26 +1578,18 @@ static int __devinit snd_atiixp_create(snd_card_t *card,
static int __devinit snd_atiixp_probe(struct pci_dev *pci,
const struct pci_device_id *pci_id)
{
- static int dev;
snd_card_t *card;
atiixp_t *chip;
unsigned char revision;
int err;
- if (dev >= SNDRV_CARDS)
- return -ENODEV;
- if (!enable[dev]) {
- dev++;
- return -ENOENT;
- }
-
- card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
+ card = snd_card_new(index, id, THIS_MODULE, 0);
if (card == NULL)
return -ENOMEM;
pci_read_config_byte(pci, PCI_REVISION_ID, &revision);
- strcpy(card->driver, spdif_aclink[dev] ? "ATIIXP" : "ATIIXP-SPDMA");
+ strcpy(card->driver, spdif_aclink ? "ATIIXP" : "ATIIXP-SPDMA");
strcpy(card->shortname, "ATI IXP");
if ((err = snd_atiixp_create(card, pci, &chip)) < 0)
goto __error;
@@ -1606,9 +1597,9 @@ static int __devinit snd_atiixp_probe(struct pci_dev *pci,
if ((err = snd_atiixp_aclink_reset(chip)) < 0)
goto __error;
- chip->spdif_over_aclink = spdif_aclink[dev];
+ chip->spdif_over_aclink = spdif_aclink;
- if ((err = snd_atiixp_mixer_new(chip, ac97_clock[dev], ac97_quirk[dev])) < 0)
+ if ((err = snd_atiixp_mixer_new(chip, ac97_clock, ac97_quirk)) < 0)
goto __error;
if ((err = snd_atiixp_pcm_new(chip)) < 0)
@@ -1629,7 +1620,6 @@ static int __devinit snd_atiixp_probe(struct pci_dev *pci,
goto __error;
pci_set_drvdata(pci, card);
- dev++;
return 0;
__error:
@@ -1645,7 +1635,6 @@ static void __devexit snd_atiixp_remove(struct pci_dev *pci)
static struct pci_driver driver = {
.name = "ATI IXP AC97 controller",
- .owner = THIS_MODULE,
.id_table = snd_atiixp_ids,
.probe = snd_atiixp_probe,
.remove = __devexit_p(snd_atiixp_remove),
diff --git a/sound/pci/atiixp_modem.c b/sound/pci/atiixp_modem.c
index c1a239a4dac6..3174b6625419 100644
--- a/sound/pci/atiixp_modem.c
+++ b/sound/pci/atiixp_modem.c
@@ -39,20 +39,21 @@ MODULE_DESCRIPTION("ATI IXP MC97 controller");
MODULE_LICENSE("GPL");
MODULE_SUPPORTED_DEVICE("{{ATI,IXP150/200/250}}");
-static int index[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = -2}; /* Exclude the first card */
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
-static int ac97_clock[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 48000};
+static int index = -2; /* Exclude the first card */
+static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */
+static int ac97_clock = 48000;
-module_param_array(index, int, NULL, 0444);
+module_param(index, int, 0444);
MODULE_PARM_DESC(index, "Index value for ATI IXP controller.");
-module_param_array(id, charp, NULL, 0444);
+module_param(id, charp, 0444);
MODULE_PARM_DESC(id, "ID string for ATI IXP controller.");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable audio part of ATI IXP controller.");
-module_param_array(ac97_clock, int, NULL, 0444);
+module_param(ac97_clock, int, 0444);
MODULE_PARM_DESC(ac97_clock, "AC'97 codec clock (default 48000Hz).");
+/* just for backward compatibility */
+static int enable;
+module_param(enable, bool, 0444);
+
/*
*/
@@ -306,8 +307,7 @@ static int snd_atiixp_update_bits(atiixp_t *chip, unsigned int reg,
/* delay for one tick */
#define do_delay() do { \
- set_current_state(TASK_UNINTERRUPTIBLE); \
- schedule_timeout(1); \
+ schedule_timeout_uninterruptible(1); \
} while (0)
@@ -989,6 +989,7 @@ static int __devinit snd_atiixp_pcm_new(atiixp_t *chip)
return err;
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_atiixp_playback_ops);
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_atiixp_capture_ops);
+ pcm->dev_class = SNDRV_PCM_CLASS_MODEM;
pcm->private_data = chip;
strcpy(pcm->name, "ATI IXP MC97");
chip->pcmdevs[ATI_PCMDEV_ANALOG] = pcm;
@@ -1067,7 +1068,6 @@ static int __devinit snd_atiixp_mixer_new(atiixp_t *chip, int clock)
if ((err = snd_ac97_bus(chip->card, 0, &ops, chip, &pbus)) < 0)
return err;
pbus->clock = clock;
- pbus->shared_type = AC97_SHARED_TYPE_ATIIXP; /* shared with audio driver */
chip->ac97_bus = pbus;
codec_count = 0;
@@ -1256,20 +1256,12 @@ static int __devinit snd_atiixp_create(snd_card_t *card,
static int __devinit snd_atiixp_probe(struct pci_dev *pci,
const struct pci_device_id *pci_id)
{
- static int dev;
snd_card_t *card;
atiixp_t *chip;
unsigned char revision;
int err;
- if (dev >= SNDRV_CARDS)
- return -ENODEV;
- if (!enable[dev]) {
- dev++;
- return -ENOENT;
- }
-
- card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
+ card = snd_card_new(index, id, THIS_MODULE, 0);
if (card == NULL)
return -ENOMEM;
@@ -1283,7 +1275,7 @@ static int __devinit snd_atiixp_probe(struct pci_dev *pci,
if ((err = snd_atiixp_aclink_reset(chip)) < 0)
goto __error;
- if ((err = snd_atiixp_mixer_new(chip, ac97_clock[dev])) < 0)
+ if ((err = snd_atiixp_mixer_new(chip, ac97_clock)) < 0)
goto __error;
if ((err = snd_atiixp_pcm_new(chip)) < 0)
@@ -1302,7 +1294,6 @@ static int __devinit snd_atiixp_probe(struct pci_dev *pci,
goto __error;
pci_set_drvdata(pci, card);
- dev++;
return 0;
__error:
@@ -1318,7 +1309,6 @@ static void __devexit snd_atiixp_remove(struct pci_dev *pci)
static struct pci_driver driver = {
.name = "ATI IXP MC97 controller",
- .owner = THIS_MODULE,
.id_table = snd_atiixp_ids,
.probe = snd_atiixp_probe,
.remove = __devexit_p(snd_atiixp_remove),
diff --git a/sound/pci/au88x0/au8810.h b/sound/pci/au88x0/au8810.h
index 3837d2ba5e67..5d69c31fe3f4 100644
--- a/sound/pci/au88x0/au8810.h
+++ b/sound/pci/au88x0/au8810.h
@@ -178,11 +178,6 @@
#define EN_SPDIF 0x000c0000
#define VORTEX_CODEC_CHN 0x29080
-#define VORTEX_CODEC_WRITE 0x00800000
-#define VORTEX_CODEC_ADDSHIFT 16
-#define VORTEX_CODEC_ADDMASK 0x7f0000 /* 0x000f0000 */
-#define VORTEX_CODEC_DATSHIFT 0
-#define VORTEX_CODEC_DATMASK 0xffff
#define VORTEX_CODEC_IO 0x29188
/* SPDIF */
diff --git a/sound/pci/au88x0/au8820.h b/sound/pci/au88x0/au8820.h
index be8022e78714..abbe85e4f7a9 100644
--- a/sound/pci/au88x0/au8820.h
+++ b/sound/pci/au88x0/au8820.h
@@ -162,11 +162,6 @@
#define EN_SPORT 0x00030000
#define EN_SPDIF 0x000c0000
#define VORTEX_CODEC_CHN 0x11880
-#define VORTEX_CODEC_WRITE 0x00800000
-#define VORTEX_CODEC_ADDSHIFT 16
-#define VORTEX_CODEC_ADDMASK 0x7f0000 /* 0x000f0000 */
-#define VORTEX_CODEC_DATSHIFT 0
-#define VORTEX_CODEC_DATMASK 0xffff
#define VORTEX_CODEC_IO 0x11988
#define VORTEX_SPDIF_FLAGS 0x1005c /* FIXME */
diff --git a/sound/pci/au88x0/au8830.h b/sound/pci/au88x0/au8830.h
index aa77826b5e59..04ece1b1c218 100644
--- a/sound/pci/au88x0/au8830.h
+++ b/sound/pci/au88x0/au8830.h
@@ -194,11 +194,6 @@
#define VORTEX_CODEC_CTRL 0x29184
#define VORTEX_CODEC_IO 0x29188
-#define VORTEX_CODEC_WRITE 0x00800000
-#define VORTEX_CODEC_ADDSHIFT 16
-#define VORTEX_CODEC_ADDMASK 0x7f0000 /* 0x000f0000 */
-#define VORTEX_CODEC_DATSHIFT 0
-#define VORTEX_CODEC_DATMASK 0xffff
#define VORTEX_CODEC_SPORTCTRL 0x2918c
diff --git a/sound/pci/au88x0/au88x0.c b/sound/pci/au88x0/au88x0.c
index 04b695d6fd48..d965609d8b38 100644
--- a/sound/pci/au88x0/au88x0.c
+++ b/sound/pci/au88x0/au88x0.c
@@ -303,7 +303,7 @@ snd_vortex_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
if (snd_seq_device_new(card, 1, SNDRV_SEQ_DEV_ID_VORTEX_SYNTH,
sizeof(snd_vortex_synth_arg_t), &wave) < 0
|| wave == NULL) {
- snd_printk("Can't initialize Aureal wavetable synth\n");
+ snd_printk(KERN_ERR "Can't initialize Aureal wavetable synth\n");
} else {
snd_vortex_synth_arg_t *arg;
@@ -373,7 +373,6 @@ static void __devexit snd_vortex_remove(struct pci_dev *pci)
// pci_driver definition
static struct pci_driver driver = {
.name = CARD_NAME_SHORT,
- .owner = THIS_MODULE,
.id_table = snd_vortex_ids,
.probe = snd_vortex_probe,
.remove = __devexit_p(snd_vortex_remove),
diff --git a/sound/pci/au88x0/au88x0.h b/sound/pci/au88x0/au88x0.h
index ee1ede1979f6..b1197cfab3fb 100644
--- a/sound/pci/au88x0/au88x0.h
+++ b/sound/pci/au88x0/au88x0.h
@@ -79,6 +79,14 @@
#define VORTEX_RESOURCE_A3D 0x00000004
#define VORTEX_RESOURCE_LAST 0x00000005
+/* codec io: VORTEX_CODEC_IO bits */
+#define VORTEX_CODEC_ID_SHIFT 24
+#define VORTEX_CODEC_WRITE 0x00800000
+#define VORTEX_CODEC_ADDSHIFT 16
+#define VORTEX_CODEC_ADDMASK 0x7f0000
+#define VORTEX_CODEC_DATSHIFT 0
+#define VORTEX_CODEC_DATMASK 0xffff
+
/* Check for SDAC bit in "Extended audio ID" AC97 register */
//#define VORTEX_IS_QUAD(x) (((x)->codec == NULL) ? 0 : ((x)->codec->ext_id&0x80))
#define VORTEX_IS_QUAD(x) ((x)->isquad)
diff --git a/sound/pci/au88x0/au88x0_a3d.c b/sound/pci/au88x0/au88x0_a3d.c
index 9ea2ba7bc3c8..d5755db5141f 100644
--- a/sound/pci/au88x0/au88x0_a3d.c
+++ b/sound/pci/au88x0/au88x0_a3d.c
@@ -488,7 +488,7 @@ static void a3dsrc_ZeroStateA3D(a3dsrc_t * a)
int i, var, var2;
if ((a->vortex) == NULL) {
- printk("vortex: ZeroStateA3D: ERROR: a->vortex is NULL\n");
+ printk(KERN_ERR "vortex: ZeroStateA3D: ERROR: a->vortex is NULL\n");
return;
}
diff --git a/sound/pci/au88x0/au88x0_core.c b/sound/pci/au88x0/au88x0_core.c
index f0eda4bbbb39..5905188d06b5 100644
--- a/sound/pci/au88x0/au88x0_core.c
+++ b/sound/pci/au88x0/au88x0_core.c
@@ -2033,7 +2033,7 @@ vortex_adb_checkinout(vortex_t * vortex, int resmap[], int out, int restype)
}
}
}
- printk("vortex: FATAL: ResManager: resource type %d exhausted.\n", restype);
+ printk(KERN_ERR "vortex: FATAL: ResManager: resource type %d exhausted.\n", restype);
return -ENOMEM;
}
@@ -2165,7 +2165,7 @@ vortex_adb_allocroute(vortex_t * vortex, int dma, int nr_ch, int dir, int type)
memset(stream->resources, 0,
sizeof(unsigned char) *
VORTEX_RESOURCE_LAST);
- printk("vortex: out of A3D sources. Sorry\n");
+ printk(KERN_ERR "vortex: out of A3D sources. Sorry\n");
return -EBUSY;
}
/* (De)Initialize A3D hardware source. */
@@ -2532,7 +2532,8 @@ vortex_codec_write(ac97_t * codec, unsigned short addr, unsigned short data)
hwwrite(card->mmio, VORTEX_CODEC_IO,
((addr << VORTEX_CODEC_ADDSHIFT) & VORTEX_CODEC_ADDMASK) |
((data << VORTEX_CODEC_DATSHIFT) & VORTEX_CODEC_DATMASK) |
- VORTEX_CODEC_WRITE);
+ VORTEX_CODEC_WRITE |
+ (codec->num << VORTEX_CODEC_ID_SHIFT) );
/* Flush Caches. */
hwread(card->mmio, VORTEX_CODEC_IO);
@@ -2554,7 +2555,8 @@ static unsigned short vortex_codec_read(ac97_t * codec, unsigned short addr)
}
}
/* set up read address */
- read_addr = ((addr << VORTEX_CODEC_ADDSHIFT) & VORTEX_CODEC_ADDMASK);
+ read_addr = ((addr << VORTEX_CODEC_ADDSHIFT) & VORTEX_CODEC_ADDMASK) |
+ (codec->num << VORTEX_CODEC_ID_SHIFT) ;
hwwrite(card->mmio, VORTEX_CODEC_IO, read_addr);
/* wait for address */
diff --git a/sound/pci/au88x0/au88x0_eq.c b/sound/pci/au88x0/au88x0_eq.c
index 53b47a42c7d8..9d933cc0ea0b 100644
--- a/sound/pci/au88x0/au88x0_eq.c
+++ b/sound/pci/au88x0/au88x0_eq.c
@@ -854,7 +854,7 @@ snd_vortex_peaks_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
vortex_Eqlzr_GetAllPeaks(vortex, peaks, &count);
if (count != 20) {
- printk("vortex: peak count error 20 != %d \n", count);
+ printk(KERN_ERR "vortex: peak count error 20 != %d \n", count);
return -1;
}
for (i = 0; i < 20; i++)
diff --git a/sound/pci/au88x0/au88x0_synth.c b/sound/pci/au88x0/au88x0_synth.c
index 400417d34609..65f375bad43a 100644
--- a/sound/pci/au88x0/au88x0_synth.c
+++ b/sound/pci/au88x0/au88x0_synth.c
@@ -90,7 +90,7 @@ static int vortex_wt_allocroute(vortex_t * vortex, int wt, int nr_ch)
hwwrite(vortex->mmio, WT_PARM(wt, 2), 0);
temp = hwread(vortex->mmio, WT_PARM(wt, 3));
- printk("vortex: WT PARM3: %x\n", temp);
+ printk(KERN_DEBUG "vortex: WT PARM3: %x\n", temp);
//hwwrite(vortex->mmio, WT_PARM(wt, 3), temp);
hwwrite(vortex->mmio, WT_DELAY(wt, 0), 0);
@@ -98,7 +98,7 @@ static int vortex_wt_allocroute(vortex_t * vortex, int wt, int nr_ch)
hwwrite(vortex->mmio, WT_DELAY(wt, 2), 0);
hwwrite(vortex->mmio, WT_DELAY(wt, 3), 0);
- printk("vortex: WT GMODE: %x\n", hwread(vortex->mmio, WT_GMODE(wt)));
+ printk(KERN_DEBUG "vortex: WT GMODE: %x\n", hwread(vortex->mmio, WT_GMODE(wt)));
hwwrite(vortex->mmio, WT_PARM(wt, 2), 0xffffffff);
hwwrite(vortex->mmio, WT_PARM(wt, 3), 0xcff1c810);
@@ -106,7 +106,7 @@ static int vortex_wt_allocroute(vortex_t * vortex, int wt, int nr_ch)
voice->parm0 = voice->parm1 = 0xcfb23e2f;
hwwrite(vortex->mmio, WT_PARM(wt, 0), voice->parm0);
hwwrite(vortex->mmio, WT_PARM(wt, 1), voice->parm1);
- printk("vortex: WT GMODE 2 : %x\n", hwread(vortex->mmio, WT_GMODE(wt)));
+ printk(KERN_DEBUG "vortex: WT GMODE 2 : %x\n", hwread(vortex->mmio, WT_GMODE(wt)));
return 0;
}
@@ -203,7 +203,7 @@ vortex_wt_SetReg(vortex_t * vortex, unsigned char reg, int wt,
}
} else {
if (wt >= NR_WT) {
- printk("vortex: WT SetReg: voice out of range\n");
+ printk(KERN_ERR "vortex: WT SetReg: voice out of range\n");
return 0;
}
}
diff --git a/sound/pci/azt3328.c b/sound/pci/azt3328.c
index d5261bdec583..ab737d6df41d 100644
--- a/sound/pci/azt3328.c
+++ b/sound/pci/azt3328.c
@@ -1,6 +1,6 @@
/*
* azt3328.c - driver for Aztech AZF3328 based soundcards (e.g. PCI168).
- * Copyright (C) 2002 by Andreas Mohr <hw7oshyuv3001@sneakemail.com>
+ * Copyright (C) 2002, 2005 by Andreas Mohr <andi AT lisas.de>
*
* Framework borrowed from Bart Hartgers's als4000.c.
* Driver developed on PCI168 AP(W) version (PCI rev. 10, subsystem ID 1801),
@@ -46,7 +46,7 @@
* - MPU401 (+ legacy address support) FIXME: how to enable legacy addr??
* - game port (legacy address support)
* - built-in General DirectX timer having a 20 bits counter
- * with 1us resolution (FIXME: where is it?)
+ * with 1us resolution (see below!)
* - I2S serial port for external DAC
* - supports 33MHz PCI spec 2.1, PCI power management 1.0, compliant with ACPI
* - supports hardware volume control
@@ -55,13 +55,23 @@
* required for Microsoft's logo compliance (FIXME: where?)
* - PCI168 AP(W) card: power amplifier with 4 Watts/channel at 4 Ohms
*
+ * Note that this driver now is actually *better* than the Windows driver,
+ * since it additionally supports the card's 1MHz DirectX timer - just try
+ * the following snd-seq module parameters etc.:
+ * - options snd-seq seq_default_timer_class=2 seq_default_timer_sclass=0
+ * seq_default_timer_card=0 seq_client_load=1 seq_default_timer_device=0
+ * seq_default_timer_subdevice=0 seq_default_timer_resolution=1000000
+ * - "timidity -iAv -B2,8 -Os -EFreverb=0"
+ * - "pmidi -p 128:0 jazz.mid"
+ *
* Certain PCI versions of this card are susceptible to DMA traffic underruns
* in some systems (resulting in sound crackling/clicking/popping),
* probably because they don't have a DMA FIFO buffer or so.
* Overview (PCI ID/PCI subID/PCI rev.):
* - no DMA crackling on SiS735: 0x50DC/0x1801/16
* - unknown performance: 0x50DC/0x1801/10
- *
+ * (well, it's not bad on an Athlon 1800 with now very optimized IRQ handler)
+ *
* Crackling happens with VIA chipsets or, in my case, an SiS735, which is
* supposed to be very fast and supposed to get rid of crackling much
* better than a VIA, yet ironically I still get crackling, like many other
@@ -76,18 +86,13 @@
* - Disable ACPI/power management/"Auto Detect RAM/PCI Clk" in BIOS
*
* BUGS
- * - when Ctrl-C'ing mpg321, the playback loops a bit
- * (premature DMA playback reset?)
- * - full-duplex sometimes breaks (IRQ management issues?).
- * Once even a spontaneous REBOOT happened!!!
+ * - full-duplex might *still* be problematic, not fully tested recently
*
* TODO
* - test MPU401 MIDI playback etc.
- * - power management (CONFIG_PM). See e.g. intel8x0 or cs4281.
+ * - power management. See e.g. intel8x0 or cs4281.
* This would be nice since the chip runs a bit hot, and it's *required*
- * anyway for proper ACPI power management. In other words: rest
- * assured that I *will* implement this very soon; as soon as Linux 2.5.x
- * has power management that's bugfree enough to work properly on my desktop.
+ * anyway for proper ACPI power management.
* - figure out what all unknown port bits are responsible for
*/
@@ -108,7 +113,7 @@
#include <sound/initval.h>
#include "azt3328.h"
-MODULE_AUTHOR("Andreas Mohr <hw7oshyuv3001@sneakemail.com>");
+MODULE_AUTHOR("Andreas Mohr <andi AT lisas.de>");
MODULE_DESCRIPTION("Aztech AZF3328 (PCI168)");
MODULE_LICENSE("GPL");
MODULE_SUPPORTED_DEVICE("{{Aztech,AZF3328}}");
@@ -122,6 +127,7 @@ MODULE_SUPPORTED_DEVICE("{{Aztech,AZF3328}}");
#define DEBUG_MIXER 0
#define DEBUG_PLAY_REC 0
#define DEBUG_IO 0
+#define DEBUG_TIMER 0
#define MIXER_TESTING 0
#if DEBUG_MISC
@@ -132,8 +138,8 @@ MODULE_SUPPORTED_DEVICE("{{Aztech,AZF3328}}");
#if DEBUG_CALLS
#define snd_azf3328_dbgcalls(format, args...) printk(format, ##args)
-#define snd_azf3328_dbgcallenter() printk(KERN_ERR "entering %s\n", __FUNCTION__)
-#define snd_azf3328_dbgcallleave() printk(KERN_ERR "leaving %s\n", __FUNCTION__)
+#define snd_azf3328_dbgcallenter() printk(KERN_ERR "--> %s\n", __FUNCTION__)
+#define snd_azf3328_dbgcallleave() printk(KERN_ERR "<-- %s\n", __FUNCTION__)
#else
#define snd_azf3328_dbgcalls(format, args...)
#define snd_azf3328_dbgcallenter()
@@ -152,13 +158,12 @@ MODULE_SUPPORTED_DEVICE("{{Aztech,AZF3328}}");
#define snd_azf3328_dbgplay(format, args...)
#endif
-#if DEBUG_IO
-#define snd_azf3328_dbgio(chip, where) \
- printk(KERN_ERR "%s: IDX_IO_PLAY_FLAGS %04x, IDX_IO_PLAY_IRQMASK %04x, IDX_IO_IRQSTATUS %04x\n", where, inw(chip->codec_port+IDX_IO_PLAY_FLAGS), inw(chip->codec_port+IDX_IO_PLAY_IRQMASK), inw(chip->codec_port+IDX_IO_IRQSTATUS))
+#if DEBUG_MISC
+#define snd_azf3328_dbgtimer(format, args...) printk(KERN_ERR format, ##args)
#else
-#define snd_azf3328_dbgio(chip, where)
-#endif
-
+#define snd_azf3328_dbgtimer(format, args...)
+#endif
+
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
module_param_array(index, int, NULL, 0444);
MODULE_PARM_DESC(index, "Index value for AZF3328 soundcard.");
@@ -177,35 +182,40 @@ module_param_array(joystick, bool, NULL, 0444);
MODULE_PARM_DESC(joystick, "Enable joystick for AZF3328 soundcard.");
#endif
-typedef struct _snd_azf3328 azf3328_t;
-
-struct _snd_azf3328 {
- int irq;
+static int seqtimer_scaling = 128;
+module_param(seqtimer_scaling, int, 0444);
+MODULE_PARM_DESC(seqtimer_scaling, "Set 1024000Hz sequencer timer scale factor (lockup danger!). Default 128.");
+typedef struct _snd_azf3328 {
+ /* often-used fields towards beginning, then grouped */
unsigned long codec_port;
unsigned long io2_port;
unsigned long mpu_port;
unsigned long synth_port;
unsigned long mixer_port;
-#ifdef SUPPORT_JOYSTICK
- struct gameport *gameport;
-#endif
-
- struct pci_dev *pci;
- snd_card_t *card;
+ spinlock_t reg_lock;
+ snd_timer_t *timer;
+
snd_pcm_t *pcm;
- snd_rawmidi_t *rmidi;
snd_pcm_substream_t *playback_substream;
snd_pcm_substream_t *capture_substream;
unsigned int is_playing;
unsigned int is_recording;
- spinlock_t reg_lock;
-};
+ snd_card_t *card;
+ snd_rawmidi_t *rmidi;
+
+#ifdef SUPPORT_JOYSTICK
+ struct gameport *gameport;
+#endif
-static struct pci_device_id snd_azf3328_ids[] = {
+ struct pci_dev *pci;
+ int irq;
+} azf3328_t;
+
+static const struct pci_device_id snd_azf3328_ids[] = {
{ 0x122D, 0x50DC, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* PCI168/3328 */
{ 0x122D, 0x80DA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* 3328 */
{ 0, }
@@ -213,57 +223,90 @@ static struct pci_device_id snd_azf3328_ids[] = {
MODULE_DEVICE_TABLE(pci, snd_azf3328_ids);
-static inline void snd_azf3328_io2_write(azf3328_t *chip, int reg, unsigned char value)
+static inline void
+snd_azf3328_codec_outb(const azf3328_t *chip, int reg, u8 value)
+{
+ outb(value, chip->codec_port + reg);
+}
+
+static inline u8
+snd_azf3328_codec_inb(const azf3328_t *chip, int reg)
+{
+ return inb(chip->codec_port + reg);
+}
+
+static inline void
+snd_azf3328_codec_outw(const azf3328_t *chip, int reg, u16 value)
+{
+ outw(value, chip->codec_port + reg);
+}
+
+static inline u16
+snd_azf3328_codec_inw(const azf3328_t *chip, int reg)
+{
+ return inw(chip->codec_port + reg);
+}
+
+static inline void
+snd_azf3328_codec_outl(const azf3328_t *chip, int reg, u32 value)
+{
+ outl(value, chip->codec_port + reg);
+}
+
+static inline void
+snd_azf3328_io2_outb(const azf3328_t *chip, int reg, u8 value)
{
outb(value, chip->io2_port + reg);
}
-static inline unsigned char snd_azf3328_io2_read(azf3328_t *chip, int reg)
+static inline u8
+snd_azf3328_io2_inb(const azf3328_t *chip, int reg)
{
return inb(chip->io2_port + reg);
}
-static void snd_azf3328_mixer_write(azf3328_t *chip, int reg, unsigned long value, int type)
+static inline void
+snd_azf3328_mixer_outw(const azf3328_t *chip, int reg, u16 value)
{
- switch(type) {
- case WORD_VALUE:
- outw(value, chip->mixer_port + reg);
- break;
- case DWORD_VALUE:
- outl(value, chip->mixer_port + reg);
- break;
- case BYTE_VALUE:
- outb(value, chip->mixer_port + reg);
- break;
- }
+ outw(value, chip->mixer_port + reg);
+}
+
+static inline u16
+snd_azf3328_mixer_inw(const azf3328_t *chip, int reg)
+{
+ return inw(chip->mixer_port + reg);
}
-static void snd_azf3328_mixer_set_mute(azf3328_t *chip, int reg, int do_mute)
+static void
+snd_azf3328_mixer_set_mute(const azf3328_t *chip, int reg, int do_mute)
{
+ unsigned long portbase = chip->mixer_port + reg + 1;
unsigned char oldval;
/* the mute bit is on the *second* (i.e. right) register of a
* left/right channel setting */
- oldval = inb(chip->mixer_port + reg + 1);
+ oldval = inb(portbase);
if (do_mute)
oldval |= 0x80;
else
oldval &= ~0x80;
- outb(oldval, chip->mixer_port + reg + 1);
+ outb(oldval, portbase);
}
-static void snd_azf3328_mixer_write_volume_gradually(azf3328_t *chip, int reg, unsigned char dst_vol_left, unsigned char dst_vol_right, int chan_sel, int delay)
+static void
+snd_azf3328_mixer_write_volume_gradually(const azf3328_t *chip, int reg, unsigned char dst_vol_left, unsigned char dst_vol_right, int chan_sel, int delay)
{
+ unsigned long portbase = chip->mixer_port + reg;
unsigned char curr_vol_left = 0, curr_vol_right = 0;
int left_done = 0, right_done = 0;
snd_azf3328_dbgcallenter();
if (chan_sel & SET_CHAN_LEFT)
- curr_vol_left = inb(chip->mixer_port + reg + 1);
+ curr_vol_left = inb(portbase + 1);
else
left_done = 1;
if (chan_sel & SET_CHAN_RIGHT)
- curr_vol_right = inb(chip->mixer_port + reg + 0);
+ curr_vol_right = inb(portbase + 0);
else
right_done = 1;
@@ -284,7 +327,7 @@ static void snd_azf3328_mixer_write_volume_gradually(azf3328_t *chip, int reg, u
curr_vol_left++;
else
left_done = 1;
- outb(curr_vol_left, chip->mixer_port + reg + 1);
+ outb(curr_vol_left, portbase + 1);
}
if (!right_done)
{
@@ -298,7 +341,7 @@ static void snd_azf3328_mixer_write_volume_gradually(azf3328_t *chip, int reg, u
/* during volume change, the right channel is crackling
* somewhat more than the left channel, unfortunately.
* This seems to be a hardware issue. */
- outb(curr_vol_right, chip->mixer_port + reg + 0);
+ outb(curr_vol_right, portbase + 0);
}
if (delay)
mdelay(delay);
@@ -320,7 +363,11 @@ typedef struct azf3328_mixer_reg {
} azf3328_mixer_reg_t;
#define COMPOSE_MIXER_REG(reg,lchan_shift,rchan_shift,mask,invert,stereo,enum_c) \
- ((reg) | (lchan_shift << 8) | (rchan_shift << 12) | (mask << 16) | (invert << 24) | (stereo << 25) | (enum_c << 26))
+ ((reg) | (lchan_shift << 8) | (rchan_shift << 12) | \
+ (mask << 16) | \
+ (invert << 24) | \
+ (stereo << 25) | \
+ (enum_c << 26))
static void snd_azf3328_mixer_reg_decode(azf3328_mixer_reg_t *r, unsigned long val)
{
@@ -372,13 +419,15 @@ static void snd_azf3328_mixer_reg_decode(azf3328_mixer_reg_t *r, unsigned long v
.private_value = COMPOSE_MIXER_REG(reg, shift, 0, 0, 0, 0, enum_c), \
}
-static int snd_azf3328_info_mixer(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+static int
+snd_azf3328_info_mixer(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
{
azf3328_mixer_reg_t reg;
snd_azf3328_dbgcallenter();
snd_azf3328_mixer_reg_decode(&reg, kcontrol->private_value);
- uinfo->type = reg.mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER;
+ uinfo->type = reg.mask == 1 ?
+ SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER;
uinfo->count = reg.stereo + 1;
uinfo->value.integer.min = 0;
uinfo->value.integer.max = reg.mask;
@@ -386,7 +435,8 @@ static int snd_azf3328_info_mixer(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t
return 0;
}
-static int snd_azf3328_get_mixer(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int
+snd_azf3328_get_mixer(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
{
azf3328_t *chip = snd_kcontrol_chip(kcontrol);
azf3328_mixer_reg_t reg;
@@ -395,7 +445,7 @@ static int snd_azf3328_get_mixer(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t
snd_azf3328_dbgcallenter();
snd_azf3328_mixer_reg_decode(&reg, kcontrol->private_value);
- oreg = inw(chip->mixer_port + reg.reg);
+ oreg = snd_azf3328_mixer_inw(chip, reg.reg);
val = (oreg >> reg.lchan_shift) & reg.mask;
if (reg.invert)
val = reg.mask - val;
@@ -406,12 +456,17 @@ static int snd_azf3328_get_mixer(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t
val = reg.mask - val;
ucontrol->value.integer.value[1] = val;
}
- snd_azf3328_dbgmixer("get: %02x is %04x -> vol %02lx|%02lx (shift %02d|%02d, mask %02x, inv. %d, stereo %d)\n", reg.reg, oreg, ucontrol->value.integer.value[0], ucontrol->value.integer.value[1], reg.lchan_shift, reg.rchan_shift, reg.mask, reg.invert, reg.stereo);
+ snd_azf3328_dbgmixer("get: %02x is %04x -> vol %02lx|%02lx "
+ "(shift %02d|%02d, mask %02x, inv. %d, stereo %d)\n",
+ reg.reg, oreg,
+ ucontrol->value.integer.value[0], ucontrol->value.integer.value[1],
+ reg.lchan_shift, reg.rchan_shift, reg.mask, reg.invert, reg.stereo);
snd_azf3328_dbgcallleave();
return 0;
}
-static int snd_azf3328_put_mixer(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int
+snd_azf3328_put_mixer(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
{
azf3328_t *chip = snd_kcontrol_chip(kcontrol);
azf3328_mixer_reg_t reg;
@@ -419,7 +474,7 @@ static int snd_azf3328_put_mixer(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t
snd_azf3328_dbgcallenter();
snd_azf3328_mixer_reg_decode(&reg, kcontrol->private_value);
- oreg = inw(chip->mixer_port + reg.reg);
+ oreg = snd_azf3328_mixer_inw(chip, reg.reg);
val = ucontrol->value.integer.value[0] & reg.mask;
if (reg.invert)
val = reg.mask - val;
@@ -433,24 +488,37 @@ static int snd_azf3328_put_mixer(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t
nreg |= (val << reg.rchan_shift);
}
if (reg.mask >= 0x07) /* it's a volume control, so better take care */
- snd_azf3328_mixer_write_volume_gradually(chip, reg.reg, nreg >> 8, nreg & 0xff, SET_CHAN_LEFT|SET_CHAN_RIGHT, 0); /* just set both channels, doesn't matter */
+ snd_azf3328_mixer_write_volume_gradually(
+ chip, reg.reg, nreg >> 8, nreg & 0xff,
+ /* just set both channels, doesn't matter */
+ SET_CHAN_LEFT|SET_CHAN_RIGHT,
+ 0);
else
- outw(nreg, chip->mixer_port + reg.reg);
+ snd_azf3328_mixer_outw(chip, reg.reg, nreg);
- snd_azf3328_dbgmixer("put: %02x to %02lx|%02lx, oreg %04x; shift %02d|%02d -> nreg %04x; after: %04x\n", reg.reg, ucontrol->value.integer.value[0], ucontrol->value.integer.value[1], oreg, reg.lchan_shift, reg.rchan_shift, nreg, inw(chip->mixer_port + reg.reg));
+ snd_azf3328_dbgmixer("put: %02x to %02lx|%02lx, "
+ "oreg %04x; shift %02d|%02d -> nreg %04x; after: %04x\n",
+ reg.reg, ucontrol->value.integer.value[0], ucontrol->value.integer.value[1],
+ oreg, reg.lchan_shift, reg.rchan_shift,
+ nreg, snd_azf3328_mixer_inw(chip, reg.reg));
snd_azf3328_dbgcallleave();
return (nreg != oreg);
}
-static int snd_azf3328_info_mixer_enum(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int
+snd_azf3328_info_mixer_enum(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
{
- azf3328_mixer_reg_t reg;
- static char *texts1[2] = { "ModemOut1", "ModemOut2" };
- static char *texts2[2] = { "MonoSelectSource1", "MonoSelectSource2" };
- static char *texts3[8] = {
- "Mic", "CD", "Video", "Aux", "Line",
- "Mix", "Mix Mono", "Phone"
+ static const char * const texts1[] = {
+ "ModemOut1", "ModemOut2"
+ };
+ static const char * const texts2[] = {
+ "MonoSelectSource1", "MonoSelectSource2"
+ };
+ static const char * const texts3[] = {
+ "Mic", "CD", "Video", "Aux",
+ "Line", "Mix", "Mix Mono", "Phone"
};
+ azf3328_mixer_reg_t reg;
snd_azf3328_mixer_reg_decode(&reg, kcontrol->private_value);
uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
@@ -471,14 +539,15 @@ static int snd_azf3328_info_mixer_enum(snd_kcontrol_t *kcontrol, snd_ctl_elem_in
return 0;
}
-static int snd_azf3328_get_mixer_enum(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int
+snd_azf3328_get_mixer_enum(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
{
- azf3328_mixer_reg_t reg;
azf3328_t *chip = snd_kcontrol_chip(kcontrol);
+ azf3328_mixer_reg_t reg;
unsigned short val;
snd_azf3328_mixer_reg_decode(&reg, kcontrol->private_value);
- val = inw(chip->mixer_port + reg.reg);
+ val = snd_azf3328_mixer_inw(chip, reg.reg);
if (reg.reg == IDX_MIXER_REC_SELECT)
{
ucontrol->value.enumerated.item[0] = (val >> 8) & (reg.enum_c - 1);
@@ -486,18 +555,22 @@ static int snd_azf3328_get_mixer_enum(snd_kcontrol_t * kcontrol, snd_ctl_elem_va
}
else
ucontrol->value.enumerated.item[0] = (val >> reg.lchan_shift) & (reg.enum_c - 1);
- snd_azf3328_dbgmixer("get_enum: %02x is %04x -> %d|%d (shift %02d, enum_c %d)\n", reg.reg, val, ucontrol->value.enumerated.item[0], ucontrol->value.enumerated.item[1], reg.lchan_shift, reg.enum_c);
+
+ snd_azf3328_dbgmixer("get_enum: %02x is %04x -> %d|%d (shift %02d, enum_c %d)\n",
+ reg.reg, val, ucontrol->value.enumerated.item[0], ucontrol->value.enumerated.item[1],
+ reg.lchan_shift, reg.enum_c);
return 0;
}
-static int snd_azf3328_put_mixer_enum(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int
+snd_azf3328_put_mixer_enum(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
{
- azf3328_mixer_reg_t reg;
azf3328_t *chip = snd_kcontrol_chip(kcontrol);
+ azf3328_mixer_reg_t reg;
unsigned int oreg, nreg, val;
snd_azf3328_mixer_reg_decode(&reg, kcontrol->private_value);
- oreg = inw(chip->mixer_port + reg.reg);
+ oreg = snd_azf3328_mixer_inw(chip, reg.reg);
val = oreg;
if (reg.reg == IDX_MIXER_REC_SELECT)
{
@@ -514,19 +587,19 @@ static int snd_azf3328_put_mixer_enum(snd_kcontrol_t * kcontrol, snd_ctl_elem_va
val &= ~((reg.enum_c - 1) << reg.lchan_shift);
val |= (ucontrol->value.enumerated.item[0] << reg.lchan_shift);
}
- outw(val, chip->mixer_port + reg.reg);
+ snd_azf3328_mixer_outw(chip, reg.reg, val);
nreg = val;
snd_azf3328_dbgmixer("put_enum: %02x to %04x, oreg %04x\n", reg.reg, val, oreg);
return (nreg != oreg);
}
-static snd_kcontrol_new_t snd_azf3328_mixer_controls[] __devinitdata = {
+static const snd_kcontrol_new_t snd_azf3328_mixer_controls[] __devinitdata = {
AZF3328_MIXER_SWITCH("Master Playback Switch", IDX_MIXER_PLAY_MASTER, 15, 1),
AZF3328_MIXER_VOL_STEREO("Master Playback Volume", IDX_MIXER_PLAY_MASTER, 0x1f, 1),
AZF3328_MIXER_SWITCH("Wave Playback Switch", IDX_MIXER_WAVEOUT, 15, 1),
AZF3328_MIXER_VOL_STEREO("Wave Playback Volume", IDX_MIXER_WAVEOUT, 0x1f, 1),
- AZF3328_MIXER_SWITCH("Wave Playback 3D Bypass", IDX_MIXER_ADVCTL2, 7, 1),
+ AZF3328_MIXER_SWITCH("Wave 3D Bypass Playback Switch", IDX_MIXER_ADVCTL2, 7, 1),
AZF3328_MIXER_SWITCH("FM Playback Switch", IDX_MIXER_FMSYNTH, 15, 1),
AZF3328_MIXER_VOL_STEREO("FM Playback Volume", IDX_MIXER_FMSYNTH, 0x1f, 1),
AZF3328_MIXER_SWITCH("CD Playback Switch", IDX_MIXER_CDAUDIO, 15, 1),
@@ -539,8 +612,8 @@ static snd_kcontrol_new_t snd_azf3328_mixer_controls[] __devinitdata = {
AZF3328_MIXER_SWITCH("Mic Boost (+20dB)", IDX_MIXER_MIC, 6, 0),
AZF3328_MIXER_SWITCH("Line Playback Switch", IDX_MIXER_LINEIN, 15, 1),
AZF3328_MIXER_VOL_STEREO("Line Playback Volume", IDX_MIXER_LINEIN, 0x1f, 1),
- AZF3328_MIXER_SWITCH("PCBeep Playback Switch", IDX_MIXER_PCBEEP, 15, 1),
- AZF3328_MIXER_VOL_SPECIAL("PCBeep Playback Volume", IDX_MIXER_PCBEEP, 0x0f, 1, 1),
+ AZF3328_MIXER_SWITCH("PC Speaker Playback Switch", IDX_MIXER_PCBEEP, 15, 1),
+ AZF3328_MIXER_VOL_SPECIAL("PC Speaker Playback Volume", IDX_MIXER_PCBEEP, 0x0f, 1, 1),
AZF3328_MIXER_SWITCH("Video Playback Switch", IDX_MIXER_VIDEO, 15, 1),
AZF3328_MIXER_VOL_STEREO("Video Playback Volume", IDX_MIXER_VIDEO, 0x1f, 1),
AZF3328_MIXER_SWITCH("Aux Playback Switch", IDX_MIXER_AUX, 15, 1),
@@ -553,8 +626,8 @@ static snd_kcontrol_new_t snd_azf3328_mixer_controls[] __devinitdata = {
AZF3328_MIXER_ENUM("Mono Select Source", IDX_MIXER_ADVCTL2, 2, 9),
AZF3328_MIXER_VOL_SPECIAL("Tone Control - Treble", IDX_MIXER_BASSTREBLE, 0x07, 1, 0),
AZF3328_MIXER_VOL_SPECIAL("Tone Control - Bass", IDX_MIXER_BASSTREBLE, 0x07, 9, 0),
- AZF3328_MIXER_SWITCH("3D Control - Toggle", IDX_MIXER_ADVCTL2, 13, 0),
- AZF3328_MIXER_VOL_SPECIAL("3D Control - Volume", IDX_MIXER_ADVCTL1, 0x07, 1, 0), /* "3D Width" */
+ AZF3328_MIXER_SWITCH("3D Control - Switch", IDX_MIXER_ADVCTL2, 13, 0),
+ AZF3328_MIXER_VOL_SPECIAL("3D Control - Wide", IDX_MIXER_ADVCTL1, 0x07, 1, 0), /* "3D Width" */
AZF3328_MIXER_VOL_SPECIAL("3D Control - Space", IDX_MIXER_ADVCTL1, 0x03, 8, 0), /* "Hifi 3D" */
#if MIXER_TESTING
AZF3328_MIXER_SWITCH("0", IDX_MIXER_ADVCTL2, 0, 0),
@@ -576,9 +649,7 @@ static snd_kcontrol_new_t snd_azf3328_mixer_controls[] __devinitdata = {
#endif
};
-#define AZF3328_INIT_VALUES (sizeof(snd_azf3328_init_values)/sizeof(unsigned int)/2)
-
-static unsigned int snd_azf3328_init_values[][2] = {
+static const u16 __devinitdata snd_azf3328_init_values[][2] = {
{ IDX_MIXER_PLAY_MASTER, MIXER_MUTE_MASK|0x1f1f },
{ IDX_MIXER_MODEMOUT, MIXER_MUTE_MASK|0x1f1f },
{ IDX_MIXER_BASSTREBLE, 0x0000 },
@@ -594,10 +665,11 @@ static unsigned int snd_azf3328_init_values[][2] = {
{ IDX_MIXER_REC_VOLUME, MIXER_MUTE_MASK|0x0707 },
};
-static int __devinit snd_azf3328_mixer_new(azf3328_t *chip)
+static int __devinit
+snd_azf3328_mixer_new(azf3328_t *chip)
{
snd_card_t *card;
- snd_kcontrol_new_t *sw;
+ const snd_kcontrol_new_t *sw;
unsigned int idx;
int err;
@@ -607,11 +679,13 @@ static int __devinit snd_azf3328_mixer_new(azf3328_t *chip)
card = chip->card;
/* mixer reset */
- snd_azf3328_mixer_write(chip, IDX_MIXER_RESET, 0x0, WORD_VALUE);
+ snd_azf3328_mixer_outw(chip, IDX_MIXER_RESET, 0x0000);
/* mute and zero volume channels */
- for (idx = 0; idx < AZF3328_INIT_VALUES; idx++) {
- snd_azf3328_mixer_write(chip, snd_azf3328_init_values[idx][0], snd_azf3328_init_values[idx][1], WORD_VALUE);
+ for (idx = 0; idx < ARRAY_SIZE(snd_azf3328_init_values); idx++) {
+ snd_azf3328_mixer_outw(chip,
+ snd_azf3328_init_values[idx][0],
+ snd_azf3328_init_values[idx][1]);
}
/* add mixer controls */
@@ -627,7 +701,8 @@ static int __devinit snd_azf3328_mixer_new(azf3328_t *chip)
return 0;
}
-static int snd_azf3328_hw_params(snd_pcm_substream_t * substream,
+static int
+snd_azf3328_hw_params(snd_pcm_substream_t * substream,
snd_pcm_hw_params_t * hw_params)
{
int res;
@@ -637,7 +712,8 @@ static int snd_azf3328_hw_params(snd_pcm_substream_t * substream,
return res;
}
-static int snd_azf3328_hw_free(snd_pcm_substream_t * substream)
+static int
+snd_azf3328_hw_free(snd_pcm_substream_t * substream)
{
snd_azf3328_dbgcallenter();
snd_pcm_lib_free_pages(substream);
@@ -645,43 +721,48 @@ static int snd_azf3328_hw_free(snd_pcm_substream_t * substream)
return 0;
}
-static void snd_azf3328_setfmt(azf3328_t *chip,
+static void
+snd_azf3328_setfmt(azf3328_t *chip,
unsigned int reg,
unsigned int bitrate,
unsigned int format_width,
unsigned int channels
)
{
- unsigned int val = 0xff00;
+ u16 val = 0xff00;
unsigned long flags;
snd_azf3328_dbgcallenter();
switch (bitrate) {
- case 5512: val |= 0x0d; break; /* the AZF3328 names it "5510" for some strange reason */
- case 6620: val |= 0x0b; break;
- case 8000: val |= 0x00; break;
- case 9600: val |= 0x08; break;
- case 11025: val |= 0x01; break;
- case 16000: val |= 0x02; break;
- case 22050: val |= 0x03; break;
- case 32000: val |= 0x04; break;
- case 44100: val |= 0x05; break;
- case 48000: val |= 0x06; break;
- case 64000: val |= 0x07; break;
+ case 4000: val |= SOUNDFORMAT_FREQ_SUSPECTED_4000; break;
+ case 4800: val |= SOUNDFORMAT_FREQ_SUSPECTED_4800; break;
+ case 5512: val |= SOUNDFORMAT_FREQ_5510; break; /* the AZF3328 names it "5510" for some strange reason */
+ case 6620: val |= SOUNDFORMAT_FREQ_6620; break;
+ case 8000: val |= SOUNDFORMAT_FREQ_8000; break;
+ case 9600: val |= SOUNDFORMAT_FREQ_9600; break;
+ case 11025: val |= SOUNDFORMAT_FREQ_11025; break;
+ case 13240: val |= SOUNDFORMAT_FREQ_SUSPECTED_13240; break;
+ case 16000: val |= SOUNDFORMAT_FREQ_16000; break;
+ case 22050: val |= SOUNDFORMAT_FREQ_22050; break;
+ case 32000: val |= SOUNDFORMAT_FREQ_32000; break;
+ case 44100: val |= SOUNDFORMAT_FREQ_44100; break;
+ case 48000: val |= SOUNDFORMAT_FREQ_48000; break;
+ case 66200: val |= SOUNDFORMAT_FREQ_SUSPECTED_66200; break;
default:
- snd_printk("unknown bitrate %d, assuming 44.1kHz!\n", bitrate);
- val |= 0x05; /* 44100 */
+ snd_printk(KERN_WARNING "unknown bitrate %d, assuming 44.1kHz!\n", bitrate);
+ val |= SOUNDFORMAT_FREQ_44100;
break;
}
- /* val = 0xff07; 3m27.993s (65301Hz; -> 64000Hz???) */
- /* val = 0xff09; 17m15.098s (13123,478Hz; -> 12000Hz???) */
- /* val = 0xff0a; 47m30.599s (4764,891Hz; -> 4800Hz???) */
- /* val = 0xff0c; 57m0.510s (4010,263Hz; -> 4000Hz???) */
+ /* val = 0xff07; 3m27.993s (65301Hz; -> 64000Hz???) hmm, 66120, 65967, 66123 */
+ /* val = 0xff09; 17m15.098s (13123,478Hz; -> 12000Hz???) hmm, 13237.2Hz? */
+ /* val = 0xff0a; 47m30.599s (4764,891Hz; -> 4800Hz???) yup, 4803Hz */
+ /* val = 0xff0c; 57m0.510s (4010,263Hz; -> 4000Hz???) yup, 4003Hz */
/* val = 0xff05; 5m11.556s (... -> 44100Hz) */
/* val = 0xff03; 10m21.529s (21872,463Hz; -> 22050Hz???) */
/* val = 0xff0f; 20m41.883s (10937,993Hz; -> 11025Hz???) */
/* val = 0xff0d; 41m23.135s (5523,600Hz; -> 5512Hz???) */
/* val = 0xff0e; 28m30.777s (8017Hz; -> 8000Hz???) */
+
if (channels == 2)
val |= SOUNDFORMAT_FLAG_2CHANNELS;
@@ -691,7 +772,7 @@ static void snd_azf3328_setfmt(azf3328_t *chip,
spin_lock_irqsave(&chip->reg_lock, flags);
/* set bitrate/format */
- outw(val, chip->codec_port+reg);
+ snd_azf3328_codec_outw(chip, reg, val);
/* changing the bitrate/format settings switches off the
* audio output with an annoying click in case of 8/16bit format change
@@ -701,47 +782,67 @@ static void snd_azf3328_setfmt(azf3328_t *chip,
* FIXME: does this have some side effects for full-duplex
* or other dramatic side effects? */
if (reg == IDX_IO_PLAY_SOUNDFORMAT) /* only do it for playback */
- outw(inw(chip->codec_port + IDX_IO_PLAY_FLAGS)|DMA_PLAY_SOMETHING1|DMA_PLAY_SOMETHING2|SOMETHING_ALMOST_ALWAYS_SET|DMA_EPILOGUE_SOMETHING|DMA_SOMETHING_ELSE, chip->codec_port + IDX_IO_PLAY_FLAGS);
+ snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS,
+ snd_azf3328_codec_inw(chip, IDX_IO_PLAY_FLAGS) |
+ DMA_PLAY_SOMETHING1 |
+ DMA_PLAY_SOMETHING2 |
+ SOMETHING_ALMOST_ALWAYS_SET |
+ DMA_EPILOGUE_SOMETHING |
+ DMA_SOMETHING_ELSE
+ );
spin_unlock_irqrestore(&chip->reg_lock, flags);
snd_azf3328_dbgcallleave();
}
-static void snd_azf3328_setdmaa(azf3328_t *chip,
+static void
+snd_azf3328_setdmaa(azf3328_t *chip,
long unsigned int addr,
unsigned int count,
unsigned int size,
int do_recording)
{
- long unsigned int addr1;
- long unsigned int addr2;
- unsigned int count1;
- unsigned int count2;
- unsigned long flags;
- int reg_offs = do_recording ? 0x20 : 0x00;
+ unsigned long flags, portbase;
+ unsigned int is_running;
snd_azf3328_dbgcallenter();
+ if (do_recording)
+ {
+ /* access capture registers, i.e. skip playback reg section */
+ portbase = chip->codec_port + 0x20;
+ is_running = chip->is_recording;
+ }
+ else
+ {
+ /* access the playback register section */
+ portbase = chip->codec_port + 0x00;
+ is_running = chip->is_playing;
+ }
+
/* AZF3328 uses a two buffer pointer DMA playback approach */
- if (!chip->is_playing)
+ if (!is_running)
{
- addr1 = addr;
- addr2 = addr+(size/2);
- count1 = (size/2)-1;
- count2 = (size/2)-1;
-#if DEBUG_PLAY_REC
- snd_azf3328_dbgplay("setting dma: buf1 %08lx[%d], buf2 %08lx[%d]\n", addr1, count1, addr2, count2);
-#endif
+ unsigned long addr_area2;
+ unsigned long count_areas, count_tmp; /* width 32bit -- overflow!! */
+ count_areas = size/2;
+ addr_area2 = addr+count_areas;
+ count_areas--; /* max. index */
+ snd_azf3328_dbgplay("set DMA: buf1 %08lx[%lu], buf2 %08lx[%lu]\n", addr, count_areas, addr_area2, count_areas);
+
+ /* build combined I/O buffer length word */
+ count_tmp = count_areas;
+ count_areas |= (count_tmp << 16);
spin_lock_irqsave(&chip->reg_lock, flags);
- outl(addr1, chip->codec_port+reg_offs+IDX_IO_PLAY_DMA_START_1);
- outl(addr2, chip->codec_port+reg_offs+IDX_IO_PLAY_DMA_START_2);
- outw(count1, chip->codec_port+reg_offs+IDX_IO_PLAY_DMA_LEN_1);
- outw(count2, chip->codec_port+reg_offs+IDX_IO_PLAY_DMA_LEN_2);
+ outl(addr, portbase + IDX_IO_PLAY_DMA_START_1);
+ outl(addr_area2, portbase + IDX_IO_PLAY_DMA_START_2);
+ outl(count_areas, portbase + IDX_IO_PLAY_DMA_LEN_1);
spin_unlock_irqrestore(&chip->reg_lock, flags);
}
snd_azf3328_dbgcallleave();
}
-static int snd_azf3328_playback_prepare(snd_pcm_substream_t *substream)
+static int
+snd_azf3328_playback_prepare(snd_pcm_substream_t *substream)
{
#if 0
azf3328_t *chip = snd_pcm_substream_chip(substream);
@@ -752,14 +853,18 @@ static int snd_azf3328_playback_prepare(snd_pcm_substream_t *substream)
snd_azf3328_dbgcallenter();
#if 0
- snd_azf3328_setfmt(chip, IDX_IO_PLAY_SOUNDFORMAT, runtime->rate, snd_pcm_format_width(runtime->format), runtime->channels);
+ snd_azf3328_setfmt(chip, IDX_IO_PLAY_SOUNDFORMAT,
+ runtime->rate,
+ snd_pcm_format_width(runtime->format),
+ runtime->channels);
snd_azf3328_setdmaa(chip, runtime->dma_addr, count, size, 0);
#endif
snd_azf3328_dbgcallleave();
return 0;
}
-static int snd_azf3328_capture_prepare(snd_pcm_substream_t * substream)
+static int
+snd_azf3328_capture_prepare(snd_pcm_substream_t * substream)
{
#if 0
azf3328_t *chip = snd_pcm_substream_chip(substream);
@@ -770,14 +875,18 @@ static int snd_azf3328_capture_prepare(snd_pcm_substream_t * substream)
snd_azf3328_dbgcallenter();
#if 0
- snd_azf3328_setfmt(chip, IDX_IO_REC_SOUNDFORMAT, runtime->rate, snd_pcm_format_width(runtime->format), runtime->channels);
+ snd_azf3328_setfmt(chip, IDX_IO_REC_SOUNDFORMAT,
+ runtime->rate,
+ snd_pcm_format_width(runtime->format),
+ runtime->channels);
snd_azf3328_setdmaa(chip, runtime->dma_addr, count, size, 1);
#endif
snd_azf3328_dbgcallleave();
return 0;
}
-static int snd_azf3328_playback_trigger(snd_pcm_substream_t * substream, int cmd)
+static int
+snd_azf3328_playback_trigger(snd_pcm_substream_t * substream, int cmd)
{
azf3328_t *chip = snd_pcm_substream_chip(substream);
snd_pcm_runtime_t *runtime = substream->runtime;
@@ -785,79 +894,98 @@ static int snd_azf3328_playback_trigger(snd_pcm_substream_t * substream, int cmd
unsigned int status1;
snd_azf3328_dbgcalls("snd_azf3328_playback_trigger cmd %d\n", cmd);
+
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
-
- snd_azf3328_dbgio(chip, "trigger1");
+ snd_azf3328_dbgplay("START PLAYBACK\n");
/* mute WaveOut */
snd_azf3328_mixer_set_mute(chip, IDX_MIXER_WAVEOUT, 1);
- snd_azf3328_setfmt(chip, IDX_IO_PLAY_SOUNDFORMAT, runtime->rate, snd_pcm_format_width(runtime->format), runtime->channels);
+ snd_azf3328_setfmt(chip, IDX_IO_PLAY_SOUNDFORMAT,
+ runtime->rate,
+ snd_pcm_format_width(runtime->format),
+ runtime->channels);
spin_lock(&chip->reg_lock);
/* stop playback */
- status1 = inw(chip->codec_port+IDX_IO_PLAY_FLAGS);
+ status1 = snd_azf3328_codec_inw(chip, IDX_IO_PLAY_FLAGS);
status1 &= ~DMA_RESUME;
- outw(status1, chip->codec_port+IDX_IO_PLAY_FLAGS);
+ snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS, status1);
/* FIXME: clear interrupts or what??? */
- outw(0xffff, chip->codec_port+IDX_IO_PLAY_IRQMASK);
+ snd_azf3328_codec_outw(chip, IDX_IO_PLAY_IRQTYPE, 0xffff);
spin_unlock(&chip->reg_lock);
- snd_azf3328_setdmaa(chip, runtime->dma_addr, snd_pcm_lib_period_bytes(substream), snd_pcm_lib_buffer_bytes(substream), 0);
+ snd_azf3328_setdmaa(chip, runtime->dma_addr,
+ snd_pcm_lib_period_bytes(substream),
+ snd_pcm_lib_buffer_bytes(substream),
+ 0);
spin_lock(&chip->reg_lock);
#ifdef WIN9X
/* FIXME: enable playback/recording??? */
status1 |= DMA_PLAY_SOMETHING1 | DMA_PLAY_SOMETHING2;
- outw(status1, chip->codec_port+IDX_IO_PLAY_FLAGS);
+ snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS, status1);
/* start playback again */
/* FIXME: what is this value (0x0010)??? */
status1 |= DMA_RESUME | DMA_EPILOGUE_SOMETHING;
- outw(status1, chip->codec_port+IDX_IO_PLAY_FLAGS);
+ snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS, status1);
#else /* NT4 */
- outw(0x00, chip->codec_port+IDX_IO_PLAY_FLAGS);
- outw(DMA_PLAY_SOMETHING1, chip->codec_port+IDX_IO_PLAY_FLAGS);
- outw(DMA_PLAY_SOMETHING1|DMA_PLAY_SOMETHING2, chip->codec_port+IDX_IO_PLAY_FLAGS);
- outw(DMA_RESUME|SOMETHING_ALMOST_ALWAYS_SET|DMA_EPILOGUE_SOMETHING|DMA_SOMETHING_ELSE, chip->codec_port+IDX_IO_PLAY_FLAGS);
+ snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS,
+ 0x0000);
+ snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS,
+ DMA_PLAY_SOMETHING1);
+ snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS,
+ DMA_PLAY_SOMETHING1 |
+ DMA_PLAY_SOMETHING2);
+ snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS,
+ DMA_RESUME |
+ SOMETHING_ALMOST_ALWAYS_SET |
+ DMA_EPILOGUE_SOMETHING |
+ DMA_SOMETHING_ELSE);
#endif
spin_unlock(&chip->reg_lock);
/* now unmute WaveOut */
snd_azf3328_mixer_set_mute(chip, IDX_MIXER_WAVEOUT, 0);
- snd_azf3328_dbgio(chip, "trigger2");
chip->is_playing = 1;
+ snd_azf3328_dbgplay("STARTED PLAYBACK\n");
break;
- case SNDRV_PCM_TRIGGER_STOP:
+ case SNDRV_PCM_TRIGGER_STOP:
+ snd_azf3328_dbgplay("STOP PLAYBACK\n");
+
/* mute WaveOut */
snd_azf3328_mixer_set_mute(chip, IDX_MIXER_WAVEOUT, 1);
spin_lock(&chip->reg_lock);
/* stop playback */
- status1 = inw(chip->codec_port+IDX_IO_PLAY_FLAGS);
+ status1 = snd_azf3328_codec_inw(chip, IDX_IO_PLAY_FLAGS);
status1 &= ~DMA_RESUME;
- outw(status1, chip->codec_port+IDX_IO_PLAY_FLAGS);
+ snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS, status1);
+ /* hmm, is this really required? we're resetting the same bit
+ * immediately thereafter... */
status1 |= DMA_PLAY_SOMETHING1;
- outw(status1, chip->codec_port+IDX_IO_PLAY_FLAGS);
+ snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS, status1);
status1 &= ~DMA_PLAY_SOMETHING1;
- outw(status1, chip->codec_port+IDX_IO_PLAY_FLAGS);
+ snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS, status1);
spin_unlock(&chip->reg_lock);
/* now unmute WaveOut */
snd_azf3328_mixer_set_mute(chip, IDX_MIXER_WAVEOUT, 0);
chip->is_playing = 0;
+ snd_azf3328_dbgplay("STOPPED PLAYBACK\n");
break;
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- snd_printk("FIXME: SNDRV_PCM_TRIGGER_PAUSE_PUSH NIY!\n");
+ snd_printk(KERN_ERR "FIXME: SNDRV_PCM_TRIGGER_PAUSE_PUSH NIY!\n");
break;
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- snd_printk("FIXME: SNDRV_PCM_TRIGGER_PAUSE_RELEASE NIY!\n");
+ snd_printk(KERN_ERR "FIXME: SNDRV_PCM_TRIGGER_PAUSE_RELEASE NIY!\n");
break;
default:
return -EINVAL;
@@ -869,7 +997,8 @@ static int snd_azf3328_playback_trigger(snd_pcm_substream_t * substream, int cmd
/* this is just analogous to playback; I'm not quite sure whether recording
* should actually be triggered like that */
-static int snd_azf3328_capture_trigger(snd_pcm_substream_t * substream, int cmd)
+static int
+snd_azf3328_capture_trigger(snd_pcm_substream_t * substream, int cmd)
{
azf3328_t *chip = snd_pcm_substream_chip(substream);
snd_pcm_runtime_t *runtime = substream->runtime;
@@ -877,68 +1006,86 @@ static int snd_azf3328_capture_trigger(snd_pcm_substream_t * substream, int cmd)
unsigned int status1;
snd_azf3328_dbgcalls("snd_azf3328_capture_trigger cmd %d\n", cmd);
+
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
- snd_azf3328_dbgio(chip, "trigger1");
+ snd_azf3328_dbgplay("START CAPTURE\n");
- snd_azf3328_setfmt(chip, IDX_IO_REC_SOUNDFORMAT, runtime->rate, snd_pcm_format_width(runtime->format), runtime->channels);
+ snd_azf3328_setfmt(chip, IDX_IO_REC_SOUNDFORMAT,
+ runtime->rate,
+ snd_pcm_format_width(runtime->format),
+ runtime->channels);
spin_lock(&chip->reg_lock);
/* stop recording */
- status1 = inw(chip->codec_port+IDX_IO_REC_FLAGS);
+ status1 = snd_azf3328_codec_inw(chip, IDX_IO_REC_FLAGS);
status1 &= ~DMA_RESUME;
- outw(status1, chip->codec_port+IDX_IO_REC_FLAGS);
+ snd_azf3328_codec_outw(chip, IDX_IO_REC_FLAGS, status1);
/* FIXME: clear interrupts or what??? */
- outw(0xffff, chip->codec_port+IDX_IO_REC_IRQMASK);
+ snd_azf3328_codec_outw(chip, IDX_IO_REC_IRQTYPE, 0xffff);
spin_unlock(&chip->reg_lock);
- snd_azf3328_setdmaa(chip, runtime->dma_addr, snd_pcm_lib_period_bytes(substream), snd_pcm_lib_buffer_bytes(substream), 1);
+ snd_azf3328_setdmaa(chip, runtime->dma_addr,
+ snd_pcm_lib_period_bytes(substream),
+ snd_pcm_lib_buffer_bytes(substream),
+ 1);
spin_lock(&chip->reg_lock);
#ifdef WIN9X
/* FIXME: enable playback/recording??? */
status1 |= DMA_PLAY_SOMETHING1 | DMA_PLAY_SOMETHING2;
- outw(status1, chip->codec_port+IDX_IO_REC_FLAGS);
+ snd_azf3328_codec_outw(chip, IDX_IO_REC_FLAGS, status1);
- /* start playback again */
+ /* start capture again */
/* FIXME: what is this value (0x0010)??? */
status1 |= DMA_RESUME | DMA_EPILOGUE_SOMETHING;
- outw(status1, chip->codec_port+IDX_IO_REC_FLAGS);
+ snd_azf3328_codec_outw(chip, IDX_IO_REC_FLAGS, status1);
#else
- outw(0x00, chip->codec_port+IDX_IO_REC_FLAGS);
- outw(DMA_PLAY_SOMETHING1, chip->codec_port+IDX_IO_REC_FLAGS);
- outw(DMA_PLAY_SOMETHING1|DMA_PLAY_SOMETHING2, chip->codec_port+IDX_IO_REC_FLAGS);
- outw(DMA_RESUME|SOMETHING_ALMOST_ALWAYS_SET|DMA_EPILOGUE_SOMETHING|DMA_SOMETHING_ELSE, chip->codec_port+IDX_IO_REC_FLAGS);
+ snd_azf3328_codec_outw(chip, IDX_IO_REC_FLAGS,
+ 0x0000);
+ snd_azf3328_codec_outw(chip, IDX_IO_REC_FLAGS,
+ DMA_PLAY_SOMETHING1);
+ snd_azf3328_codec_outw(chip, IDX_IO_REC_FLAGS,
+ DMA_PLAY_SOMETHING1 |
+ DMA_PLAY_SOMETHING2);
+ snd_azf3328_codec_outw(chip, IDX_IO_REC_FLAGS,
+ DMA_RESUME |
+ SOMETHING_ALMOST_ALWAYS_SET |
+ DMA_EPILOGUE_SOMETHING |
+ DMA_SOMETHING_ELSE);
#endif
spin_unlock(&chip->reg_lock);
- snd_azf3328_dbgio(chip, "trigger2");
- chip->is_playing = 1;
+ chip->is_recording = 1;
+ snd_azf3328_dbgplay("STARTED CAPTURE\n");
break;
case SNDRV_PCM_TRIGGER_STOP:
+ snd_azf3328_dbgplay("STOP CAPTURE\n");
+
spin_lock(&chip->reg_lock);
/* stop recording */
- status1 = inw(chip->codec_port+IDX_IO_REC_FLAGS);
+ status1 = snd_azf3328_codec_inw(chip, IDX_IO_REC_FLAGS);
status1 &= ~DMA_RESUME;
- outw(status1, chip->codec_port+IDX_IO_REC_FLAGS);
+ snd_azf3328_codec_outw(chip, IDX_IO_REC_FLAGS, status1);
status1 |= DMA_PLAY_SOMETHING1;
- outw(status1, chip->codec_port+IDX_IO_REC_FLAGS);
+ snd_azf3328_codec_outw(chip, IDX_IO_REC_FLAGS, status1);
status1 &= ~DMA_PLAY_SOMETHING1;
- outw(status1, chip->codec_port+IDX_IO_REC_FLAGS);
+ snd_azf3328_codec_outw(chip, IDX_IO_REC_FLAGS, status1);
spin_unlock(&chip->reg_lock);
- chip->is_playing = 0;
+ chip->is_recording = 0;
+ snd_azf3328_dbgplay("STOPPED CAPTURE\n");
break;
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- snd_printk("FIXME: SNDRV_PCM_TRIGGER_PAUSE_PUSH NIY!\n");
+ snd_printk(KERN_ERR "FIXME: SNDRV_PCM_TRIGGER_PAUSE_PUSH NIY!\n");
break;
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- snd_printk("FIXME: SNDRV_PCM_TRIGGER_PAUSE_RELEASE NIY!\n");
+ snd_printk(KERN_ERR "FIXME: SNDRV_PCM_TRIGGER_PAUSE_RELEASE NIY!\n");
break;
default:
return -EINVAL;
@@ -948,11 +1095,11 @@ static int snd_azf3328_capture_trigger(snd_pcm_substream_t * substream, int cmd)
return result;
}
-static snd_pcm_uframes_t snd_azf3328_playback_pointer(snd_pcm_substream_t * substream)
+static snd_pcm_uframes_t
+snd_azf3328_playback_pointer(snd_pcm_substream_t * substream)
{
azf3328_t *chip = snd_pcm_substream_chip(substream);
- unsigned long bufptr, playptr;
- unsigned long result;
+ unsigned long bufptr, result;
snd_pcm_uframes_t frmres;
#ifdef QUERY_HARDWARE
@@ -960,19 +1107,20 @@ static snd_pcm_uframes_t snd_azf3328_playback_pointer(snd_pcm_substream_t * subs
#else
bufptr = substream->runtime->dma_addr;
#endif
- playptr = inl(chip->codec_port+IDX_IO_PLAY_DMA_CURRPOS);
+ result = inl(chip->codec_port+IDX_IO_PLAY_DMA_CURRPOS);
- result = playptr - bufptr;
- frmres = bytes_to_frames( substream->runtime, result );
- snd_azf3328_dbgplay("result %lx, playptr %lx (base %x), frames %ld\n", result, playptr, substream->runtime->dma_addr, frmres);
+ /* calculate offset */
+ result -= bufptr;
+ frmres = bytes_to_frames( substream->runtime, result);
+ snd_azf3328_dbgplay("PLAY @ 0x%8lx, frames %8ld\n", result, frmres);
return frmres;
}
-static snd_pcm_uframes_t snd_azf3328_capture_pointer(snd_pcm_substream_t * substream)
+static snd_pcm_uframes_t
+snd_azf3328_capture_pointer(snd_pcm_substream_t * substream)
{
azf3328_t *chip = snd_pcm_substream_chip(substream);
- unsigned long bufptr, recptr;
- unsigned long result;
+ unsigned long bufptr, result;
snd_pcm_uframes_t frmres;
#ifdef QUERY_HARDWARE
@@ -980,96 +1128,116 @@ static snd_pcm_uframes_t snd_azf3328_capture_pointer(snd_pcm_substream_t * subst
#else
bufptr = substream->runtime->dma_addr;
#endif
- recptr = inl(chip->codec_port+IDX_IO_REC_DMA_CURRPOS);
+ result = inl(chip->codec_port+IDX_IO_REC_DMA_CURRPOS);
- result = recptr - bufptr;
- frmres = bytes_to_frames( substream->runtime, result );
- snd_azf3328_dbgplay("result %lx, rec ptr %lx (base %x), frames %ld\n", result, recptr, substream->runtime->dma_addr, frmres);
+ /* calculate offset */
+ result -= bufptr;
+ frmres = bytes_to_frames( substream->runtime, result);
+ snd_azf3328_dbgplay("REC @ 0x%8lx, frames %8ld\n", result, frmres);
return frmres;
}
-static irqreturn_t snd_azf3328_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t
+snd_azf3328_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
azf3328_t *chip = dev_id;
- unsigned int status, which;
- static unsigned long count;
+ u8 status, which;
+ static unsigned long irq_count;
- status = inw(chip->codec_port+IDX_IO_IRQSTATUS);
+ status = snd_azf3328_codec_inb(chip, IDX_IO_IRQSTATUS);
/* fast path out, to ease interrupt sharing */
- if (!(status & (IRQ_PLAYBACK|IRQ_RECORDING|IRQ_MPU401|IRQ_SOMEIRQ)))
+ if (!(status & (IRQ_PLAYBACK|IRQ_RECORDING|IRQ_MPU401|IRQ_TIMER)))
return IRQ_NONE; /* must be interrupt for another device */
- snd_azf3328_dbgplay("Interrupt %ld!\nIDX_IO_PLAY_FLAGS %04x, IDX_IO_PLAY_IRQMASK %04x, IDX_IO_IRQSTATUS %04x\n", count, inw(chip->codec_port+IDX_IO_PLAY_FLAGS), inw(chip->codec_port+IDX_IO_PLAY_IRQMASK), inw(chip->codec_port+IDX_IO_IRQSTATUS));
+ snd_azf3328_dbgplay("Interrupt %ld!\nIDX_IO_PLAY_FLAGS %04x, IDX_IO_PLAY_IRQTYPE %04x, IDX_IO_IRQSTATUS %04x\n",
+ irq_count,
+ snd_azf3328_codec_inw(chip, IDX_IO_PLAY_FLAGS),
+ snd_azf3328_codec_inw(chip, IDX_IO_PLAY_IRQTYPE),
+ status);
+ if (status & IRQ_TIMER)
+ {
+ /* snd_azf3328_dbgplay("timer %ld\n", inl(chip->codec_port+IDX_IO_TIMER_VALUE) & TIMER_VALUE_MASK); */
+ if (chip->timer)
+ snd_timer_interrupt(chip->timer, chip->timer->sticks);
+ /* ACK timer */
+ spin_lock(&chip->reg_lock);
+ snd_azf3328_codec_outb(chip, IDX_IO_TIMER_VALUE + 3, 0x07);
+ spin_unlock(&chip->reg_lock);
+ snd_azf3328_dbgplay("azt3328: timer IRQ\n");
+ }
if (status & IRQ_PLAYBACK)
{
spin_lock(&chip->reg_lock);
- which = inw(chip->codec_port+IDX_IO_PLAY_IRQMASK);
- if (which & IRQ_FINISHED_PLAYBUF_1)
- /* ack IRQ */
- outw(which | IRQ_FINISHED_PLAYBUF_1, chip->codec_port+IDX_IO_PLAY_IRQMASK);
- if (which & IRQ_FINISHED_PLAYBUF_2)
- /* ack IRQ */
- outw(which | IRQ_FINISHED_PLAYBUF_2, chip->codec_port+IDX_IO_PLAY_IRQMASK);
- if (which & IRQ_PLAY_SOMETHING)
- {
- snd_azf3328_dbgplay("azt3328: unknown play IRQ type occurred, please report!\n");
- }
+ which = snd_azf3328_codec_inb(chip, IDX_IO_PLAY_IRQTYPE);
+ /* ack all IRQ types immediately */
+ snd_azf3328_codec_outb(chip, IDX_IO_PLAY_IRQTYPE, which);
+ spin_unlock(&chip->reg_lock);
+
if (chip->pcm && chip->playback_substream)
{
- snd_azf3328_dbgplay("which %x, playptr %lx\n", which, inl(chip->codec_port+IDX_IO_PLAY_DMA_CURRPOS));
snd_pcm_period_elapsed(chip->playback_substream);
- snd_azf3328_dbgplay("period done, playptr %lx.\n", inl(chip->codec_port+IDX_IO_PLAY_DMA_CURRPOS));
+ snd_azf3328_dbgplay("PLAY period done (#%x), @ %x\n",
+ which,
+ inl(chip->codec_port+IDX_IO_PLAY_DMA_CURRPOS));
}
else
snd_azf3328_dbgplay("azt3328: ouch, irq handler problem!\n");
- spin_unlock(&chip->reg_lock);
+ if (which & IRQ_PLAY_SOMETHING)
+ snd_azf3328_dbgplay("azt3328: unknown play IRQ type occurred, please report!\n");
}
if (status & IRQ_RECORDING)
{
spin_lock(&chip->reg_lock);
- which = inw(chip->codec_port+IDX_IO_REC_IRQMASK);
- if (which & IRQ_FINISHED_RECBUF_1)
- /* ack interrupt */
- outw(which | IRQ_FINISHED_RECBUF_1, chip->codec_port+IDX_IO_REC_IRQMASK);
- if (which & IRQ_FINISHED_RECBUF_2)
- /* ack interrupt */
- outw(which | IRQ_FINISHED_RECBUF_2, chip->codec_port+IDX_IO_REC_IRQMASK);
- if (which & IRQ_REC_SOMETHING)
- {
- snd_azf3328_dbgplay("azt3328: unknown rec IRQ type occurred, please report!\n");
- }
+ which = snd_azf3328_codec_inb(chip, IDX_IO_REC_IRQTYPE);
+ /* ack all IRQ types immediately */
+ snd_azf3328_codec_outb(chip, IDX_IO_REC_IRQTYPE, which);
+ spin_unlock(&chip->reg_lock);
+
if (chip->pcm && chip->capture_substream)
{
- snd_azf3328_dbgplay("which %x, recptr %lx\n", which, inl(chip->codec_port+IDX_IO_REC_DMA_CURRPOS));
- spin_unlock(&chip->reg_lock);
snd_pcm_period_elapsed(chip->capture_substream);
- spin_lock(&chip->reg_lock);
- snd_azf3328_dbgplay("period done, recptr %lx.\n", inl(chip->codec_port+IDX_IO_REC_DMA_CURRPOS));
+ snd_azf3328_dbgplay("REC period done (#%x), @ %x\n",
+ which,
+ inl(chip->codec_port+IDX_IO_REC_DMA_CURRPOS));
}
- spin_unlock(&chip->reg_lock);
+ else
+ snd_azf3328_dbgplay("azt3328: ouch, irq handler problem!\n");
+ if (which & IRQ_REC_SOMETHING)
+ snd_azf3328_dbgplay("azt3328: unknown rec IRQ type occurred, please report!\n");
}
+ /* MPU401 has less critical IRQ requirements
+ * than timer and playback/recording, right? */
if (status & IRQ_MPU401)
+ {
snd_mpu401_uart_interrupt(irq, chip->rmidi->private_data, regs);
- if (status & IRQ_SOMEIRQ)
- snd_azf3328_dbgplay("azt3328: unknown IRQ type occurred, please report!\n");
- count++;
+
+ /* hmm, do we have to ack the IRQ here somehow?
+ * If so, then I don't know how... */
+ snd_azf3328_dbgplay("azt3328: MPU401 IRQ\n");
+ }
+ irq_count++;
return IRQ_HANDLED;
}
/*****************************************************************/
-static snd_pcm_hardware_t snd_azf3328_playback =
+static const snd_pcm_hardware_t snd_azf3328_playback =
{
/* FIXME!! Correct? */
- .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_MMAP_VALID),
- .formats = SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U8 |
- SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U16_LE,
- .rates = SNDRV_PCM_RATE_8000_48000 | SNDRV_PCM_RATE_64000 | SNDRV_PCM_RATE_KNOT,
- .rate_min = 5512,
- .rate_max = 64000,
+ .info = SNDRV_PCM_INFO_MMAP |
+ SNDRV_PCM_INFO_INTERLEAVED |
+ SNDRV_PCM_INFO_MMAP_VALID,
+ .formats = SNDRV_PCM_FMTBIT_S8 |
+ SNDRV_PCM_FMTBIT_U8 |
+ SNDRV_PCM_FMTBIT_S16_LE |
+ SNDRV_PCM_FMTBIT_U16_LE,
+ .rates = SNDRV_PCM_RATE_5512 |
+ SNDRV_PCM_RATE_8000_48000 |
+ SNDRV_PCM_RATE_KNOT,
+ .rate_min = 4000,
+ .rate_max = 66200,
.channels_min = 1,
.channels_max = 2,
.buffer_bytes_max = 65536,
@@ -1083,16 +1251,21 @@ static snd_pcm_hardware_t snd_azf3328_playback =
.fifo_size = 0,
};
-static snd_pcm_hardware_t snd_azf3328_capture =
+static const snd_pcm_hardware_t snd_azf3328_capture =
{
/* FIXME */
- .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_MMAP_VALID),
- .formats = SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U8 |
- SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U16_LE,
- .rates = SNDRV_PCM_RATE_8000_48000 | SNDRV_PCM_RATE_64000 | SNDRV_PCM_RATE_KNOT,
- .rate_min = 5512,
- .rate_max = 64000,
+ .info = SNDRV_PCM_INFO_MMAP |
+ SNDRV_PCM_INFO_INTERLEAVED |
+ SNDRV_PCM_INFO_MMAP_VALID,
+ .formats = SNDRV_PCM_FMTBIT_S8 |
+ SNDRV_PCM_FMTBIT_U8 |
+ SNDRV_PCM_FMTBIT_S16_LE |
+ SNDRV_PCM_FMTBIT_U16_LE,
+ .rates = SNDRV_PCM_RATE_5512 |
+ SNDRV_PCM_RATE_8000_48000 |
+ SNDRV_PCM_RATE_KNOT,
+ .rate_min = 4000,
+ .rate_max = 66200,
.channels_min = 1,
.channels_max = 2,
.buffer_bytes_max = 65536,
@@ -1105,8 +1278,8 @@ static snd_pcm_hardware_t snd_azf3328_capture =
static unsigned int snd_azf3328_fixed_rates[] = {
- 5512, 6620, 8000, 9600, 11025, 16000, 22050, 32000, 44100, 48000, 64000
-};
+ 4000, 4800, 5512, 6620, 8000, 9600, 11025, 13240, 16000, 22050, 32000,
+ 44100, 48000, 66200 };
static snd_pcm_hw_constraint_list_t snd_azf3328_hw_constraints_rates = {
.count = ARRAY_SIZE(snd_azf3328_fixed_rates),
.list = snd_azf3328_fixed_rates,
@@ -1115,7 +1288,8 @@ static snd_pcm_hw_constraint_list_t snd_azf3328_hw_constraints_rates = {
/*****************************************************************/
-static int snd_azf3328_playback_open(snd_pcm_substream_t * substream)
+static int
+snd_azf3328_playback_open(snd_pcm_substream_t * substream)
{
azf3328_t *chip = snd_pcm_substream_chip(substream);
snd_pcm_runtime_t *runtime = substream->runtime;
@@ -1129,7 +1303,8 @@ static int snd_azf3328_playback_open(snd_pcm_substream_t * substream)
return 0;
}
-static int snd_azf3328_capture_open(snd_pcm_substream_t * substream)
+static int
+snd_azf3328_capture_open(snd_pcm_substream_t * substream)
{
azf3328_t *chip = snd_pcm_substream_chip(substream);
snd_pcm_runtime_t *runtime = substream->runtime;
@@ -1143,7 +1318,8 @@ static int snd_azf3328_capture_open(snd_pcm_substream_t * substream)
return 0;
}
-static int snd_azf3328_playback_close(snd_pcm_substream_t * substream)
+static int
+snd_azf3328_playback_close(snd_pcm_substream_t * substream)
{
azf3328_t *chip = snd_pcm_substream_chip(substream);
@@ -1154,7 +1330,8 @@ static int snd_azf3328_playback_close(snd_pcm_substream_t * substream)
return 0;
}
-static int snd_azf3328_capture_close(snd_pcm_substream_t * substream)
+static int
+snd_azf3328_capture_close(snd_pcm_substream_t * substream)
{
azf3328_t *chip = snd_pcm_substream_chip(substream);
@@ -1188,14 +1365,16 @@ static snd_pcm_ops_t snd_azf3328_capture_ops = {
.pointer = snd_azf3328_capture_pointer
};
-static void snd_azf3328_pcm_free(snd_pcm_t *pcm)
+static void
+snd_azf3328_pcm_free(snd_pcm_t *pcm)
{
azf3328_t *chip = pcm->private_data;
chip->pcm = NULL;
snd_pcm_lib_preallocate_free_for_all(pcm);
}
-static int __devinit snd_azf3328_pcm(azf3328_t *chip, int device)
+static int __devinit
+snd_azf3328_pcm(azf3328_t *chip, int device)
{
snd_pcm_t *pcm;
int err;
@@ -1222,7 +1401,8 @@ static int __devinit snd_azf3328_pcm(azf3328_t *chip, int device)
/******************************************************************/
#ifdef SUPPORT_JOYSTICK
-static int __devinit snd_azf3328_config_joystick(azf3328_t *chip, int dev)
+static int __devinit
+snd_azf3328_config_joystick(azf3328_t *chip, int dev)
{
struct gameport *gp;
struct resource *r;
@@ -1238,8 +1418,7 @@ static int __devinit snd_azf3328_config_joystick(azf3328_t *chip, int dev)
chip->gameport = gp = gameport_allocate_port();
if (!gp) {
printk(KERN_ERR "azt3328: cannot allocate memory for gameport\n");
- release_resource(r);
- kfree_nocheck(r);
+ release_and_free_resource(r);
return -ENOMEM;
}
@@ -1249,15 +1428,16 @@ static int __devinit snd_azf3328_config_joystick(azf3328_t *chip, int dev)
gp->io = 0x200;
gameport_set_port_data(gp, r);
- snd_azf3328_io2_write(chip, IDX_IO2_LEGACY_ADDR,
- snd_azf3328_io2_read(chip, IDX_IO2_LEGACY_ADDR) | LEGACY_JOY);
+ snd_azf3328_io2_outb(chip, IDX_IO2_LEGACY_ADDR,
+ snd_azf3328_io2_inb(chip, IDX_IO2_LEGACY_ADDR) | LEGACY_JOY);
gameport_register_port(chip->gameport);
return 0;
}
-static void snd_azf3328_free_joystick(azf3328_t *chip)
+static void
+snd_azf3328_free_joystick(azf3328_t *chip)
{
if (chip->gameport) {
struct resource *r = gameport_get_port_data(chip->gameport);
@@ -1265,33 +1445,36 @@ static void snd_azf3328_free_joystick(azf3328_t *chip)
gameport_unregister_port(chip->gameport);
chip->gameport = NULL;
/* disable gameport */
- snd_azf3328_io2_write(chip, IDX_IO2_LEGACY_ADDR,
- snd_azf3328_io2_read(chip, IDX_IO2_LEGACY_ADDR) & ~LEGACY_JOY);
- release_resource(r);
- kfree_nocheck(r);
+ snd_azf3328_io2_outb(chip, IDX_IO2_LEGACY_ADDR,
+ snd_azf3328_io2_inb(chip, IDX_IO2_LEGACY_ADDR) & ~LEGACY_JOY);
+ release_and_free_resource(r);
}
}
#else
-static inline int snd_azf3328_config_joystick(azf3328_t *chip, int dev) { return -ENOSYS; }
-static inline void snd_azf3328_free_joystick(azf3328_t *chip) { }
+static inline int
+snd_azf3328_config_joystick(azf3328_t *chip, int dev) { return -ENOSYS; }
+static inline void
+snd_azf3328_free_joystick(azf3328_t *chip) { }
#endif
/******************************************************************/
-static int snd_azf3328_free(azf3328_t *chip)
+static int
+snd_azf3328_free(azf3328_t *chip)
{
if (chip->irq < 0)
goto __end_hw;
/* reset (close) mixer */
snd_azf3328_mixer_set_mute(chip, IDX_MIXER_PLAY_MASTER, 1); /* first mute master volume */
- snd_azf3328_mixer_write(chip, IDX_MIXER_RESET, 0x0, WORD_VALUE);
+ snd_azf3328_mixer_outw(chip, IDX_MIXER_RESET, 0x0000);
- /* interrupt setup - mask everything */
- /* FIXME */
+ /* interrupt setup - mask everything (FIXME!) */
+ /* well, at least we know how to disable the timer IRQ */
+ snd_azf3328_codec_outb(chip, IDX_IO_TIMER_VALUE + 3, 0x00);
synchronize_irq(chip->irq);
- __end_hw:
+__end_hw:
snd_azf3328_free_joystick(chip);
if (chip->irq >= 0)
free_irq(chip->irq, (void *)chip);
@@ -1302,15 +1485,129 @@ static int snd_azf3328_free(azf3328_t *chip)
return 0;
}
-static int snd_azf3328_dev_free(snd_device_t *device)
+static int
+snd_azf3328_dev_free(snd_device_t *device)
{
azf3328_t *chip = device->device_data;
return snd_azf3328_free(chip);
}
+/******************************************************************/
+
+/*** NOTE: the physical timer resolution actually is 1024000 ticks per second,
+ *** but announcing those attributes to user-space would make programs
+ *** configure the timer to a 1 tick value, resulting in an absolutely fatal
+ *** timer IRQ storm.
+ *** Thus I chose to announce a down-scaled virtual timer to the outside and
+ *** calculate real timer countdown values internally.
+ *** (the scale factor can be set via module parameter "seqtimer_scaling").
+ ***/
+
+static int
+snd_azf3328_timer_start(snd_timer_t *timer)
+{
+ azf3328_t *chip;
+ unsigned long flags;
+ unsigned int delay;
+
+ snd_azf3328_dbgcallenter();
+ chip = snd_timer_chip(timer);
+ delay = ((timer->sticks * seqtimer_scaling) - 1) & TIMER_VALUE_MASK;
+ if (delay < 49)
+ {
+ /* uhoh, that's not good, since user-space won't know about
+ * this timing tweak
+ * (we need to do it to avoid a lockup, though) */
+
+ snd_azf3328_dbgtimer("delay was too low (%d)!\n", delay);
+ delay = 49; /* minimum time is 49 ticks */
+ }
+ snd_azf3328_dbgtimer("setting timer countdown value %d, add COUNTDOWN|IRQ\n", delay);
+ delay |= TIMER_ENABLE_COUNTDOWN | TIMER_ENABLE_IRQ;
+ spin_lock_irqsave(&chip->reg_lock, flags);
+ snd_azf3328_codec_outl(chip, IDX_IO_TIMER_VALUE, delay);
+ spin_unlock_irqrestore(&chip->reg_lock, flags);
+ snd_azf3328_dbgcallleave();
+ return 0;
+}
+
+static int
+snd_azf3328_timer_stop(snd_timer_t *timer)
+{
+ azf3328_t *chip;
+ unsigned long flags;
+
+ snd_azf3328_dbgcallenter();
+ chip = snd_timer_chip(timer);
+ spin_lock_irqsave(&chip->reg_lock, flags);
+ /* disable timer countdown and interrupt */
+ /* FIXME: should we write TIMER_ACK_IRQ here? */
+ snd_azf3328_codec_outb(chip, IDX_IO_TIMER_VALUE + 3, 0);
+ spin_unlock_irqrestore(&chip->reg_lock, flags);
+ snd_azf3328_dbgcallleave();
+ return 0;
+}
+
+
+static int
+snd_azf3328_timer_precise_resolution(snd_timer_t *timer,
+ unsigned long *num, unsigned long *den)
+{
+ snd_azf3328_dbgcallenter();
+ *num = 1;
+ *den = 1024000 / seqtimer_scaling;
+ snd_azf3328_dbgcallleave();
+ return 0;
+}
+
+static struct _snd_timer_hardware snd_azf3328_timer_hw = {
+ .flags = SNDRV_TIMER_HW_AUTO,
+ .resolution = 977, /* 1000000/1024000 = 0.9765625us */
+ .ticks = 1024000, /* max tick count, defined by the value register; actually it's not 1024000, but 1048576, but we don't care */
+ .start = snd_azf3328_timer_start,
+ .stop = snd_azf3328_timer_stop,
+ .precise_resolution = snd_azf3328_timer_precise_resolution,
+};
+
+static int __devinit
+snd_azf3328_timer(azf3328_t *chip, int device)
+{
+ snd_timer_t *timer = NULL;
+ snd_timer_id_t tid;
+ int err;
+
+ snd_azf3328_dbgcallenter();
+ tid.dev_class = SNDRV_TIMER_CLASS_CARD;
+ tid.dev_sclass = SNDRV_TIMER_SCLASS_NONE;
+ tid.card = chip->card->number;
+ tid.device = device;
+ tid.subdevice = 0;
+
+ snd_azf3328_timer_hw.resolution *= seqtimer_scaling;
+ snd_azf3328_timer_hw.ticks /= seqtimer_scaling;
+ if ((err = snd_timer_new(chip->card, "AZF3328", &tid, &timer)) < 0) {
+ goto out;
+ }
+
+ strcpy(timer->name, "AZF3328 timer");
+ timer->private_data = chip;
+ timer->hw = snd_azf3328_timer_hw;
+
+ chip->timer = timer;
+
+ err = 0;
+
+out:
+ snd_azf3328_dbgcallleave();
+ return err;
+}
+
+/******************************************************************/
+
#if 0
/* check whether a bit can be modified */
-static void snd_azf3328_test_bit(unsigned int reg, int bit)
+static void
+snd_azf3328_test_bit(unsigned int reg, int bit)
{
unsigned char val, valoff, valon;
@@ -1328,7 +1625,26 @@ static void snd_azf3328_test_bit(unsigned int reg, int bit)
}
#endif
-static int __devinit snd_azf3328_create(snd_card_t * card,
+static void
+snd_azf3328_debug_show_ports(const azf3328_t *chip)
+{
+#if DEBUG_MISC
+ u16 tmp;
+
+ snd_azf3328_dbgmisc("codec_port 0x%lx, io2_port 0x%lx, mpu_port 0x%lx, synth_port 0x%lx, mixer_port 0x%lx, irq %d\n", chip->codec_port, chip->io2_port, chip->mpu_port, chip->synth_port, chip->mixer_port, chip->irq);
+
+ snd_azf3328_dbgmisc("io2 %02x %02x %02x %02x %02x %02x\n", snd_azf3328_io2_inb(chip, 0), snd_azf3328_io2_inb(chip, 1), snd_azf3328_io2_inb(chip, 2), snd_azf3328_io2_inb(chip, 3), snd_azf3328_io2_inb(chip, 4), snd_azf3328_io2_inb(chip, 5));
+
+ for (tmp=0; tmp <= 0x01; tmp += 1)
+ snd_azf3328_dbgmisc("0x%02x: opl 0x%04x, mpu300 0x%04x, mpu310 0x%04x, mpu320 0x%04x, mpu330 0x%04x\n", tmp, inb(0x388 + tmp), inb(0x300 + tmp), inb(0x310 + tmp), inb(0x320 + tmp), inb(0x330 + tmp));
+
+ for (tmp = 0; tmp <= 0x6E; tmp += 2)
+ snd_azf3328_dbgmisc("0x%02x: 0x%04x\n", tmp, snd_azf3328_codec_inb(chip, tmp));
+#endif
+}
+
+static int __devinit
+snd_azf3328_create(snd_card_t * card,
struct pci_dev *pci,
unsigned long device_type,
azf3328_t ** rchip)
@@ -1347,8 +1663,8 @@ static int __devinit snd_azf3328_create(snd_card_t * card,
chip = kzalloc(sizeof(*chip), GFP_KERNEL);
if (chip == NULL) {
- pci_disable_device(pci);
- return -ENOMEM;
+ err = -ENOMEM;
+ goto out_err;
}
spin_lock_init(&chip->reg_lock);
chip->card = card;
@@ -1358,47 +1674,39 @@ static int __devinit snd_azf3328_create(snd_card_t * card,
/* check if we can restrict PCI DMA transfers to 24 bits */
if (pci_set_dma_mask(pci, 0x00ffffff) < 0 ||
pci_set_consistent_dma_mask(pci, 0x00ffffff) < 0) {
- snd_printk("architecture does not support 24bit PCI busmaster DMA\n");
- pci_disable_device(pci);
- return -ENXIO;
+ snd_printk(KERN_ERR "architecture does not support 24bit PCI busmaster DMA\n");
+ err = -ENXIO;
+ goto out_err;
}
if ((err = pci_request_regions(pci, "Aztech AZF3328")) < 0) {
- kfree(chip);
- pci_disable_device(pci);
- return err;
+ goto out_err;
}
chip->codec_port = pci_resource_start(pci, 0);
- chip->io2_port = pci_resource_start(pci, 1);
- chip->mpu_port = pci_resource_start(pci, 2);
+ chip->io2_port = pci_resource_start(pci, 1);
+ chip->mpu_port = pci_resource_start(pci, 2);
chip->synth_port = pci_resource_start(pci, 3);
chip->mixer_port = pci_resource_start(pci, 4);
if (request_irq(pci->irq, snd_azf3328_interrupt, SA_INTERRUPT|SA_SHIRQ, card->shortname, (void *)chip)) {
- snd_printk("unable to grab IRQ %d\n", pci->irq);
- snd_azf3328_free(chip);
- return -EBUSY;
+ snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
+ err = -EBUSY;
+ goto out_err;
}
chip->irq = pci->irq;
pci_set_master(pci);
synchronize_irq(chip->irq);
- snd_azf3328_dbgmisc("codec_port 0x%lx, io2_port 0x%lx, mpu_port 0x%lx, synth_port 0x%lx, mixer_port 0x%lx, irq %d\n", chip->codec_port, chip->io2_port, chip->mpu_port, chip->synth_port, chip->mixer_port, chip->irq);
-
- snd_azf3328_dbgmisc("io2 %02x %02x %02x %02x %02x %02x\n", snd_azf3328_io2_read(chip, 0), snd_azf3328_io2_read(chip, 1), snd_azf3328_io2_read(chip, 2), snd_azf3328_io2_read(chip, 3), snd_azf3328_io2_read(chip, 4), snd_azf3328_io2_read(chip, 5));
-
- for (tmp=0; tmp <= 0x01; tmp += 1)
- snd_azf3328_dbgmisc("0x%02x: opl 0x%04x, mpu300 0x%04x, mpu310 0x%04x, mpu320 0x%04x, mpu330 0x%04x\n", tmp, inb(0x388 + tmp), inb(0x300 + tmp), inb(0x310 + tmp), inb(0x320 + tmp), inb(0x330 + tmp));
-
+ snd_azf3328_debug_show_ports(chip);
+
if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
- snd_azf3328_free(chip);
- return err;
+ goto out_err;
}
/* create mixer interface & switches */
if ((err = snd_azf3328_mixer_new(chip)) < 0)
- return err;
+ goto out_err;
#if 0
/* set very low bitrate to reduce noise and power consumption? */
@@ -1406,22 +1714,34 @@ static int __devinit snd_azf3328_create(snd_card_t * card,
#endif
/* standard chip init stuff */
- spin_lock_irq(&chip->reg_lock);
- outb(DMA_PLAY_SOMETHING2|DMA_EPILOGUE_SOMETHING|DMA_SOMETHING_ELSE, chip->codec_port + IDX_IO_PLAY_FLAGS);
- outb(DMA_PLAY_SOMETHING2|DMA_EPILOGUE_SOMETHING|DMA_SOMETHING_ELSE, chip->codec_port + IDX_IO_SOMETHING_FLAGS);
- outb(DMA_PLAY_SOMETHING2|DMA_EPILOGUE_SOMETHING|DMA_SOMETHING_ELSE, chip->codec_port + IDX_IO_REC_FLAGS);
- outb(0x0, chip->codec_port + IDX_IO_IRQ63H);
+ /* default IRQ init value */
+ tmp = DMA_PLAY_SOMETHING2|DMA_EPILOGUE_SOMETHING|DMA_SOMETHING_ELSE;
+ spin_lock_irq(&chip->reg_lock);
+ snd_azf3328_codec_outb(chip, IDX_IO_PLAY_FLAGS, tmp);
+ snd_azf3328_codec_outb(chip, IDX_IO_REC_FLAGS, tmp);
+ snd_azf3328_codec_outb(chip, IDX_IO_SOMETHING_FLAGS, tmp);
+ snd_azf3328_codec_outb(chip, IDX_IO_TIMER_VALUE + 3, 0x00); /* disable timer */
spin_unlock_irq(&chip->reg_lock);
snd_card_set_dev(card, &pci->dev);
*rchip = chip;
- return 0;
+
+ err = 0;
+ goto out;
+
+out_err:
+ if (chip)
+ snd_azf3328_free(chip);
+ pci_disable_device(pci);
+
+out:
+ return err;
}
-static int __devinit snd_azf3328_probe(struct pci_dev *pci,
- const struct pci_device_id *pci_id)
+static int __devinit
+snd_azf3328_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
{
static int dev;
snd_card_t *card;
@@ -1445,63 +1765,70 @@ static int __devinit snd_azf3328_probe(struct pci_dev *pci,
strcpy(card->shortname, "Aztech AZF3328 (PCI168)");
if ((err = snd_azf3328_create(card, pci, pci_id->driver_data, &chip)) < 0) {
- snd_card_free(card);
- return err;
+ goto out_err;
}
if ((err = snd_mpu401_uart_new( card, 0, MPU401_HW_MPU401,
chip->mpu_port, 1, pci->irq, 0,
&chip->rmidi)) < 0) {
- snd_printk("azf3328: no MPU-401 device at 0x%lx?\n", chip->mpu_port);
- snd_card_free(card);
- return err;
+ snd_printk(KERN_ERR "azf3328: no MPU-401 device at 0x%lx?\n", chip->mpu_port);
+ goto out_err;
+ }
+
+ if ((err = snd_azf3328_timer(chip, 0)) < 0) {
+ goto out_err;
}
if ((err = snd_azf3328_pcm(chip, 0)) < 0) {
- snd_card_free(card);
- return err;
+ goto out_err;
}
if (snd_opl3_create(card, chip->synth_port, chip->synth_port+2,
OPL3_HW_AUTO, 1, &opl3) < 0) {
- snd_printk("azf3328: no OPL3 device at 0x%lx-0x%lx?\n",
+ snd_printk(KERN_ERR "azf3328: no OPL3 device at 0x%lx-0x%lx?\n",
chip->synth_port, chip->synth_port+2 );
} else {
if ((err = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0) {
- snd_card_free(card);
- return err;
+ goto out_err;
}
}
- snd_azf3328_dbgio(chip, "create");
-
sprintf(card->longname, "%s at 0x%lx, irq %i",
card->shortname, chip->codec_port, chip->irq);
if ((err = snd_card_register(card)) < 0) {
- snd_card_free(card);
- return err;
+ goto out_err;
}
#ifdef MODULE
printk(
-"azt3328: Experimental driver for Aztech AZF3328-based soundcards such as PCI168.\n"
-"azt3328: ZERO support from Aztech: you might think hard about future purchase.\n"
-"azt3328: Feel free to contact hw7oshyuv3001@sneakemail.com for bug reports etc.!\n");
+"azt3328: Sound driver for Aztech AZF3328-based soundcards such as PCI168\n"
+"azt3328: (hardware was completely undocumented - ZERO support from Aztech).\n"
+"azt3328: Feel free to contact andi AT lisas.de for bug reports etc.!\n"
+"azt3328: User-scalable sequencer timer set to %dHz (1024000Hz / %d).\n",
+ 1024000 / seqtimer_scaling, seqtimer_scaling);
#endif
if (snd_azf3328_config_joystick(chip, dev) < 0)
- snd_azf3328_io2_write(chip, IDX_IO2_LEGACY_ADDR,
- snd_azf3328_io2_read(chip, IDX_IO2_LEGACY_ADDR) & ~LEGACY_JOY);
+ snd_azf3328_io2_outb(chip, IDX_IO2_LEGACY_ADDR,
+ snd_azf3328_io2_inb(chip, IDX_IO2_LEGACY_ADDR) & ~LEGACY_JOY);
pci_set_drvdata(pci, card);
dev++;
+ err = 0;
+ goto out;
+
+out_err:
+ snd_card_free(card);
+
+out:
snd_azf3328_dbgcallleave();
- return 0;
+ return err;
}
-static void __devexit snd_azf3328_remove(struct pci_dev *pci)
+static void __devexit
+snd_azf3328_remove(struct pci_dev *pci)
{
snd_azf3328_dbgcallenter();
snd_card_free(pci_get_drvdata(pci));
@@ -1511,13 +1838,13 @@ static void __devexit snd_azf3328_remove(struct pci_dev *pci)
static struct pci_driver driver = {
.name = "AZF3328",
- .owner = THIS_MODULE,
.id_table = snd_azf3328_ids,
.probe = snd_azf3328_probe,
.remove = __devexit_p(snd_azf3328_remove),
};
-static int __init alsa_card_azf3328_init(void)
+static int __init
+alsa_card_azf3328_init(void)
{
int err;
snd_azf3328_dbgcallenter();
@@ -1526,7 +1853,8 @@ static int __init alsa_card_azf3328_init(void)
return err;
}
-static void __exit alsa_card_azf3328_exit(void)
+static void __exit
+alsa_card_azf3328_exit(void)
{
snd_azf3328_dbgcallenter();
pci_unregister_driver(&driver);
diff --git a/sound/pci/azt3328.h b/sound/pci/azt3328.h
index 7e0e79180977..f489bdaf6d40 100644
--- a/sound/pci/azt3328.h
+++ b/sound/pci/azt3328.h
@@ -1,19 +1,17 @@
-#ifndef __SOUND_AZF3328_H
-#define __SOUND_AZF3328_H
+#ifndef __SOUND_AZT3328_H
+#define __SOUND_AZT3328_H
-/* type argument to use for the I/O functions */
-#define WORD_VALUE 0x1000
-#define DWORD_VALUE 0x2000
-#define BYTE_VALUE 0x4000
+/* "PU" == "power-up value", as tested on PCI168 PCI rev. 10 */
/*** main I/O area port indices ***/
/* (only 0x70 of 0x80 bytes saved/restored by Windows driver) */
-/* the driver initialisation suggests a layout of 3 main areas:
- * from 0x00 (playback), from 0x20 (recording) and from 0x40 (maybe DirectX
- * timer ???). and probably another area from 0x60 to 0x6f
- * (IRQ management, power management etc. ???). */
-/* playback area */
-#define IDX_IO_PLAY_FLAGS 0x00
+/* the driver initialisation suggests a layout of 4 main areas:
+ * from 0x00 (playback), from 0x20 (recording) and from 0x40 (maybe MPU401??).
+ * And another area from 0x60 to 0x6f (DirectX timer, IRQ management,
+ * power management etc.???). */
+
+/** playback area **/
+#define IDX_IO_PLAY_FLAGS 0x00 /* PU:0x0000 */
/* able to reactivate output after output muting due to 8/16bit
* output change, just like 0x0002.
* 0x0001 is the only bit that's able to start the DMA counter */
@@ -29,7 +27,7 @@
#define DMA_EPILOGUE_SOMETHING 0x0010
#define DMA_SOMETHING_ELSE 0x0020 /* ??? */
#define SOMETHING_UNMODIFIABLE 0xffc0 /* unused ? not modifiable */
-#define IDX_IO_PLAY_IRQMASK 0x02
+#define IDX_IO_PLAY_IRQTYPE 0x02 /* PU:0x0001 */
/* write back to flags in case flags are set, in order to ACK IRQ in handler
* (bit 1 of port 0x64 indicates interrupt for one of these three types)
* sometimes in this case it just writes 0xffff to globally ACK all IRQs
@@ -41,36 +39,39 @@
#define IRQMASK_SOME_STATUS_1 0x0008 /* \ related bits */
#define IRQMASK_SOME_STATUS_2 0x0010 /* / (checked together in loop) */
#define IRQMASK_UNMODIFIABLE 0xffe0 /* unused ? not modifiable */
-#define IDX_IO_PLAY_DMA_START_1 0x04 /* start address of 1st DMA play area */
-#define IDX_IO_PLAY_DMA_START_2 0x08 /* start address of 2nd DMA play area */
-#define IDX_IO_PLAY_DMA_LEN_1 0x0c /* length of 1st DMA play area */
-#define IDX_IO_PLAY_DMA_LEN_2 0x0e /* length of 2nd DMA play area */
-#define IDX_IO_PLAY_DMA_CURRPOS 0x10 /* current DMA position */
-#define IDX_IO_PLAY_DMA_CURROFS 0x14 /* offset within current DMA play area */
-#define IDX_IO_PLAY_SOUNDFORMAT 0x16
+#define IDX_IO_PLAY_DMA_START_1 0x04 /* start address of 1st DMA play area, PU:0x00000000 */
+#define IDX_IO_PLAY_DMA_START_2 0x08 /* start address of 2nd DMA play area, PU:0x00000000 */
+#define IDX_IO_PLAY_DMA_LEN_1 0x0c /* length of 1st DMA play area, PU:0x0000 */
+#define IDX_IO_PLAY_DMA_LEN_2 0x0e /* length of 2nd DMA play area, PU:0x0000 */
+#define IDX_IO_PLAY_DMA_CURRPOS 0x10 /* current DMA position, PU:0x00000000 */
+#define IDX_IO_PLAY_DMA_CURROFS 0x14 /* offset within current DMA play area, PU:0x0000 */
+#define IDX_IO_PLAY_SOUNDFORMAT 0x16 /* PU:0x0010 */
/* all unspecified bits can't be modified */
#define SOUNDFORMAT_FREQUENCY_MASK 0x000f
+ #define SOUNDFORMAT_XTAL1 0x00
+ #define SOUNDFORMAT_XTAL2 0x01
/* all _SUSPECTED_ values are not used by Windows drivers, so we don't
* have any hard facts, only rough measurements */
- #define SOUNDFORMAT_FREQ_SUSPECTED_4000 0x0c
- #define SOUNDFORMAT_FREQ_SUSPECTED_4800 0x0a
- #define SOUNDFORMAT_FREQ_5510 0x0d
- #define SOUNDFORMAT_FREQ_6620 0x0b
- #define SOUNDFORMAT_FREQ_8000 0x00 /* also 0x0e ? */
- #define SOUNDFORMAT_FREQ_9600 0x08
- #define SOUNDFORMAT_FREQ_SUSPECTED_12000 0x09
- #define SOUNDFORMAT_FREQ_11025 0x01 /* also 0x0f ? */
- #define SOUNDFORMAT_FREQ_16000 0x02
- #define SOUNDFORMAT_FREQ_22050 0x03
- #define SOUNDFORMAT_FREQ_32000 0x04
- #define SOUNDFORMAT_FREQ_44100 0x05
- #define SOUNDFORMAT_FREQ_48000 0x06
- #define SOUNDFORMAT_FREQ_SUSPECTED_64000 0x07
+ #define SOUNDFORMAT_FREQ_SUSPECTED_4000 0x0c | SOUNDFORMAT_XTAL1
+ #define SOUNDFORMAT_FREQ_SUSPECTED_4800 0x0a | SOUNDFORMAT_XTAL1
+ #define SOUNDFORMAT_FREQ_5510 0x0c | SOUNDFORMAT_XTAL2
+ #define SOUNDFORMAT_FREQ_6620 0x0a | SOUNDFORMAT_XTAL2
+ #define SOUNDFORMAT_FREQ_8000 0x00 | SOUNDFORMAT_XTAL1 /* also 0x0e | SOUNDFORMAT_XTAL1? */
+ #define SOUNDFORMAT_FREQ_9600 0x08 | SOUNDFORMAT_XTAL1
+ #define SOUNDFORMAT_FREQ_11025 0x00 | SOUNDFORMAT_XTAL2 /* also 0x0e | SOUNDFORMAT_XTAL2? */
+ #define SOUNDFORMAT_FREQ_SUSPECTED_13240 0x08 | SOUNDFORMAT_XTAL2 /* seems to be 6620 *2 */
+ #define SOUNDFORMAT_FREQ_16000 0x02 | SOUNDFORMAT_XTAL1
+ #define SOUNDFORMAT_FREQ_22050 0x02 | SOUNDFORMAT_XTAL2
+ #define SOUNDFORMAT_FREQ_32000 0x04 | SOUNDFORMAT_XTAL1
+ #define SOUNDFORMAT_FREQ_44100 0x04 | SOUNDFORMAT_XTAL2
+ #define SOUNDFORMAT_FREQ_48000 0x06 | SOUNDFORMAT_XTAL1
+ #define SOUNDFORMAT_FREQ_SUSPECTED_66200 0x06 | SOUNDFORMAT_XTAL2 /* 66200 (13240 * 5); 64000 may have been nicer :-\ */
#define SOUNDFORMAT_FLAG_16BIT 0x0010
#define SOUNDFORMAT_FLAG_2CHANNELS 0x0020
-/* recording area (see also: playback bit flag definitions) */
-#define IDX_IO_REC_FLAGS 0x20 /* ?? */
-#define IDX_IO_REC_IRQMASK 0x22 /* ?? */
+
+/** recording area (see also: playback bit flag definitions) **/
+#define IDX_IO_REC_FLAGS 0x20 /* ??, PU:0x0000 */
+#define IDX_IO_REC_IRQTYPE 0x22 /* ??, PU:0x0000 */
#define IRQ_REC_SOMETHING 0x0001 /* something & ACK */
#define IRQ_FINISHED_RECBUF_1 0x0002 /* 1st dmabuf finished & ACK */
#define IRQ_FINISHED_RECBUF_2 0x0004 /* 2nd dmabuf finished & ACK */
@@ -78,39 +79,47 @@
* but OTOH they are most likely at port 0x22 instead */
#define IRQMASK_SOME_STATUS_1 0x0008 /* \ related bits */
#define IRQMASK_SOME_STATUS_2 0x0010 /* / (checked together in loop) */
-#define IDX_IO_REC_DMA_START_1 0x24
-#define IDX_IO_REC_DMA_START_2 0x28
-#define IDX_IO_REC_DMA_LEN_1 0x2c
-#define IDX_IO_REC_DMA_LEN_2 0x2e
-#define IDX_IO_REC_DMA_CURRPOS 0x30
-#define IDX_IO_REC_DMA_CURROFS 0x34
-#define IDX_IO_REC_SOUNDFORMAT 0x36
-/* some third area ? (after playback and recording) */
-#define IDX_IO_SOMETHING_FLAGS 0x40 /* gets set to 0x34 just like port 0x0 and 0x20 on card init */
+#define IDX_IO_REC_DMA_START_1 0x24 /* PU:0x00000000 */
+#define IDX_IO_REC_DMA_START_2 0x28 /* PU:0x00000000 */
+#define IDX_IO_REC_DMA_LEN_1 0x2c /* PU:0x0000 */
+#define IDX_IO_REC_DMA_LEN_2 0x2e /* PU:0x0000 */
+#define IDX_IO_REC_DMA_CURRPOS 0x30 /* PU:0x00000000 */
+#define IDX_IO_REC_DMA_CURROFS 0x34 /* PU:0x00000000 */
+#define IDX_IO_REC_SOUNDFORMAT 0x36 /* PU:0x0000 */
+
+/** hmm, what is this I/O area for? MPU401?? (after playback, recording, ???, timer) **/
+#define IDX_IO_SOMETHING_FLAGS 0x40 /* gets set to 0x34 just like port 0x0 and 0x20 on card init, PU:0x0000 */
/* general */
-#define IDX_IO_60H 0x60 /* writing 0xffff returns 0xffff */
-#define IDX_IO_62H 0x62 /* writing to WORD 0x0062 can hang the box ! --> responsible for IRQ management as a whole ?? */
-#define IDX_IO_IRQ63H 0x63 /* FIXME !! */
- #define IO_IRQ63H_SOMETHING 0x04 /* being set in IRQ handler in case port 0x00 had 0x0020 set upon IRQ handler */
+#define IDX_IO_42H 0x42 /* PU:0x0001 */
+
+/** DirectX timer, main interrupt area (FIXME: and something else?) **/
+#define IDX_IO_TIMER_VALUE 0x60 /* found this timer area by pure luck :-) */
+ #define TIMER_VALUE_MASK 0x000fffffUL /* timer countdown value; triggers IRQ when timer is finished */
+ #define TIMER_ENABLE_COUNTDOWN 0x01000000UL /* activate the timer countdown */
+ #define TIMER_ENABLE_IRQ 0x02000000UL /* trigger timer IRQ on zero transition */
+ #define TIMER_ACK_IRQ 0x04000000UL /* being set in IRQ handler in case port 0x00 (hmm, not port 0x64!?!?) had 0x0020 set upon IRQ handler */
#define IDX_IO_IRQSTATUS 0x64
#define IRQ_PLAYBACK 0x0001
#define IRQ_RECORDING 0x0002
#define IRQ_MPU401 0x0010
- #define IRQ_SOMEIRQ 0x0020 /* ???? */
- #define IRQ_WHO_KNOWS_UNUSED 0x00e0 /* probably unused */
+ #define IRQ_TIMER 0x0020 /* DirectX timer */
+ #define IRQ_UNKNOWN1 0x0040 /* probably unused */
+ #define IRQ_UNKNOWN2 0x0080 /* probably unused */
#define IDX_IO_66H 0x66 /* writing 0xffff returns 0x0000 */
-#define IDX_IO_SOME_VALUE 0x68 /* this is always set to 0x3ff, and writable; maybe some buffer limit, but I couldn't find out more */
-#define IDX_IO_6AH 0x6A /* this WORD can be set to have bits 0x0028 activated; actually inhibits PCM playback !!! maybe power management ?? */
-#define IDX_IO_6CH 0x6C /* this WORD can have all its bits activated ? */
+#define IDX_IO_SOME_VALUE 0x68 /* this is set to e.g. 0x3ff or 0x300, and writable; maybe some buffer limit, but I couldn't find out more, PU:0x00ff */
+#define IDX_IO_6AH 0x6A /* this WORD can be set to have bits 0x0028 activated; actually inhibits PCM playback!!! maybe power management?? */
+#define IDX_IO_6CH 0x6C
#define IDX_IO_6EH 0x6E /* writing 0xffff returns 0x83fe */
/* further I/O indices not saved/restored, so probably not used */
+
/*** I/O 2 area port indices ***/
/* (only 0x06 of 0x08 bytes saved/restored by Windows driver) */
#define IDX_IO2_LEGACY_ADDR 0x04
- #define LEGACY_SOMETHING 0x01 /* OPL3 ?? */
+ #define LEGACY_SOMETHING 0x01 /* OPL3?? */
#define LEGACY_JOY 0x08
+
/*** mixer I/O area port indices ***/
/* (only 0x22 of 0x40 bytes saved/restored by Windows driver)
* generally spoken: AC97 register index = AZF3328 mixer reg index + 2
@@ -148,18 +157,18 @@
/* unlisted bits are unmodifiable */
#define MIXER_ADVCTL1_3DWIDTH_MASK 0x000e
#define MIXER_ADVCTL1_HIFI3D_MASK 0x0300
-#define IDX_MIXER_ADVCTL2 0x20 /* resembles AC97_GENERAL_PURPOSE reg ! */
+#define IDX_MIXER_ADVCTL2 0x20 /* resembles AC97_GENERAL_PURPOSE reg! */
/* unlisted bits are unmodifiable */
- #define MIXER_ADVCTL2_BIT7 0x0080 /* WaveOut 3D Bypass ? mutes WaveOut at LineOut */
- #define MIXER_ADVCTL2_BIT8 0x0100 /* is this Modem Out Select ? */
- #define MIXER_ADVCTL2_BIT9 0x0200 /* Mono Select Source ? */
- #define MIXER_ADVCTL2_BIT13 0x2000 /* 3D enable ? */
+ #define MIXER_ADVCTL2_BIT7 0x0080 /* WaveOut 3D Bypass? mutes WaveOut at LineOut */
+ #define MIXER_ADVCTL2_BIT8 0x0100 /* is this Modem Out Select? */
+ #define MIXER_ADVCTL2_BIT9 0x0200 /* Mono Select Source? */
+ #define MIXER_ADVCTL2_BIT13 0x2000 /* 3D enable? */
#define MIXER_ADVCTL2_BIT15 0x8000 /* unknown */
-#define IDX_MIXER_SOMETHING30H 0x30 /* used, but unknown ??? */
+#define IDX_MIXER_SOMETHING30H 0x30 /* used, but unknown??? */
/* driver internal flags */
#define SET_CHAN_LEFT 1
#define SET_CHAN_RIGHT 2
-#endif /* __SOUND_AZF3328_H */
+#endif /* __SOUND_AZT3328_H */
diff --git a/sound/pci/bt87x.c b/sound/pci/bt87x.c
index 2236c958aec0..8feca228c6d4 100644
--- a/sound/pci/bt87x.c
+++ b/sound/pci/bt87x.c
@@ -761,15 +761,18 @@ static int __devinit snd_bt87x_create(snd_card_t *card,
#define BT_DEVICE(chip, subvend, subdev, rate) \
{ .vendor = PCI_VENDOR_ID_BROOKTREE, \
- .device = PCI_DEVICE_ID_BROOKTREE_##chip, \
+ .device = chip, \
.subvendor = subvend, .subdevice = subdev, \
.driver_data = rate }
/* driver_data is the default digital_rate value for that device */
static struct pci_device_id snd_bt87x_ids[] = {
- BT_DEVICE(878, 0x0070, 0x13eb, 32000), /* Hauppauge WinTV series */
- BT_DEVICE(879, 0x0070, 0x13eb, 32000), /* Hauppauge WinTV series */
- BT_DEVICE(878, 0x0070, 0xff01, 44100), /* Viewcast Osprey 200 */
+ /* Hauppauge WinTV series */
+ BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x0070, 0x13eb, 32000),
+ /* Hauppauge WinTV series */
+ BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_879, 0x0070, 0x13eb, 32000),
+ /* Viewcast Osprey 200 */
+ BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x0070, 0xff01, 44100),
{ }
};
MODULE_DEVICE_TABLE(pci, snd_bt87x_ids);
@@ -894,14 +897,13 @@ static void __devexit snd_bt87x_remove(struct pci_dev *pci)
/* default entries for all Bt87x cards - it's not exported */
/* driver_data is set to 0 to call detection */
static struct pci_device_id snd_bt87x_default_ids[] = {
- BT_DEVICE(878, PCI_ANY_ID, PCI_ANY_ID, 0),
- BT_DEVICE(879, PCI_ANY_ID, PCI_ANY_ID, 0),
+ BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, PCI_ANY_ID, PCI_ANY_ID, 0),
+ BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_879, PCI_ANY_ID, PCI_ANY_ID, 0),
{ }
};
static struct pci_driver driver = {
.name = "Bt87x",
- .owner = THIS_MODULE,
.id_table = snd_bt87x_ids,
.probe = snd_bt87x_probe,
.remove = __devexit_p(snd_bt87x_remove),
diff --git a/sound/pci/ca0106/Makefile b/sound/pci/ca0106/Makefile
index 89c6ceee21f3..dcbae7b31546 100644
--- a/sound/pci/ca0106/Makefile
+++ b/sound/pci/ca0106/Makefile
@@ -1,3 +1,3 @@
-snd-ca0106-objs := ca0106_main.o ca0106_proc.o ca0106_mixer.o
+snd-ca0106-objs := ca0106_main.o ca0106_proc.o ca0106_mixer.o ca_midi.o
obj-$(CONFIG_SND_CA0106) += snd-ca0106.o
diff --git a/sound/pci/ca0106/ca0106.h b/sound/pci/ca0106/ca0106.h
index da09cab405a9..9a4b6406f7a5 100644
--- a/sound/pci/ca0106/ca0106.h
+++ b/sound/pci/ca0106/ca0106.h
@@ -399,10 +399,24 @@
#define PLAYBACK_VOLUME2 0x6a /* Playback Analog volume per channel. Does not effect AC3 output */
/* Similar to register 0x66, except that the destination is the I2S mixer instead of the SPDIF mixer. I.E. Outputs to the Analog outputs instead of SPDIF. */
#define UNKNOWN6b 0x6b /* Unknown. Readonly. Default 00400000 00400000 00400000 00400000 */
-#define UART_A_DATA 0x6c /* Uart, used in setting sample rates, bits per sample etc. */
-#define UART_A_CMD 0x6d /* Uart, used in setting sample rates, bits per sample etc. */
-#define UART_B_DATA 0x6e /* Uart, Unknown. */
-#define UART_B_CMD 0x6f /* Uart, Unknown. */
+#define MIDI_UART_A_DATA 0x6c /* Midi Uart A Data */
+#define MIDI_UART_A_CMD 0x6d /* Midi Uart A Command/Status */
+#define MIDI_UART_B_DATA 0x6e /* Midi Uart B Data (currently unused) */
+#define MIDI_UART_B_CMD 0x6f /* Midi Uart B Command/Status (currently unused) */
+
+/* unique channel identifier for midi->channel */
+
+#define CA0106_MIDI_CHAN_A 0x1
+#define CA0106_MIDI_CHAN_B 0x2
+
+/* from mpu401 */
+
+#define CA0106_MIDI_INPUT_AVAIL 0x80
+#define CA0106_MIDI_OUTPUT_READY 0x40
+#define CA0106_MPU401_RESET 0xff
+#define CA0106_MPU401_ENTER_UART 0x3f
+#define CA0106_MPU401_ACK 0xfe
+
#define SAMPLE_RATE_TRACKER_STATUS 0x70 /* Readonly. Default 00108000 00108000 00500000 00500000 */
/* Estimated sample rate [19:0] Relative to 48kHz. 0x8000 = 1.0
* Rate Locked [20]
@@ -538,6 +552,8 @@
#define CONTROL_CENTER_LFE_CHANNEL 1
#define CONTROL_UNKNOWN_CHANNEL 2
+#include "ca_midi.h"
+
typedef struct snd_ca0106_channel ca0106_channel_t;
typedef struct snd_ca0106 ca0106_t;
typedef struct snd_ca0106_pcm ca0106_pcm_t;
@@ -592,6 +608,9 @@ struct snd_ca0106 {
int capture_mic_line_in;
struct snd_dma_buffer buffer;
+
+ ca_midi_t midi;
+ ca_midi_t midi2;
};
int __devinit snd_ca0106_mixer(ca0106_t *emu);
diff --git a/sound/pci/ca0106/ca0106_main.c b/sound/pci/ca0106/ca0106_main.c
index ba07960921d8..389d967c97f4 100644
--- a/sound/pci/ca0106/ca0106_main.c
+++ b/sound/pci/ca0106/ca0106_main.c
@@ -281,7 +281,7 @@ int snd_ca0106_i2c_write(ca0106_t *emu,
int retry;
if ((reg > 0x7f) || (value > 0x1ff))
{
- snd_printk("i2c_write: invalid values.\n");
+ snd_printk(KERN_ERR "i2c_write: invalid values.\n");
return -EINVAL;
}
@@ -319,7 +319,7 @@ int snd_ca0106_i2c_write(ca0106_t *emu,
if(retry==10)
{
- snd_printk("Writing to ADC failed!\n");
+ snd_printk(KERN_ERR "Writing to ADC failed!\n");
return -EINVAL;
}
@@ -338,6 +338,18 @@ static void snd_ca0106_intr_enable(ca0106_t *emu, unsigned int intrenb)
spin_unlock_irqrestore(&emu->emu_lock, flags);
}
+static void snd_ca0106_intr_disable(ca0106_t *emu, unsigned int intrenb)
+{
+ unsigned long flags;
+ unsigned int enable;
+
+ spin_lock_irqsave(&emu->emu_lock, flags);
+ enable = inl(emu->port + INTE) & ~intrenb;
+ outl(enable, emu->port + INTE);
+ spin_unlock_irqrestore(&emu->emu_lock, flags);
+}
+
+
static void snd_ca0106_pcm_free_substream(snd_pcm_runtime_t *runtime)
{
kfree(runtime->private_data);
@@ -421,7 +433,7 @@ static int snd_ca0106_pcm_open_capture_channel(snd_pcm_substream_t *substream, i
epcm = kzalloc(sizeof(*epcm), GFP_KERNEL);
if (epcm == NULL) {
- snd_printk("open_capture_channel: failed epcm alloc\n");
+ snd_printk(KERN_ERR "open_capture_channel: failed epcm alloc\n");
return -ENOMEM;
}
epcm->emu = chip;
@@ -969,10 +981,8 @@ static int snd_ca0106_free(ca0106_t *chip)
#endif
// release the i/o port
- if (chip->res_port) {
- release_resource(chip->res_port);
- kfree_nocheck(chip->res_port);
- }
+ release_and_free_resource(chip->res_port);
+
// release the irq
if (chip->irq >= 0)
free_irq(chip->irq, (void *)chip);
@@ -1042,6 +1052,15 @@ static irqreturn_t snd_ca0106_interrupt(int irq, void *dev_id,
snd_ca0106_ptr_write(chip, EXTENDED_INT, 0, stat76);
spin_lock(&chip->emu_lock);
+
+ if (chip->midi.dev_id &&
+ (status & (chip->midi.ipr_tx|chip->midi.ipr_rx))) {
+ if (chip->midi.interrupt)
+ chip->midi.interrupt(&chip->midi, status);
+ else
+ chip->midi.interrupt_disable(&chip->midi, chip->midi.tx_enable | chip->midi.rx_enable);
+ }
+
// acknowledge the interrupt if necessary
outl(status, chip->port+IPR);
@@ -1311,6 +1330,88 @@ static int __devinit snd_ca0106_create(snd_card_t *card,
return 0;
}
+
+static void ca0106_midi_interrupt_enable(ca_midi_t *midi, int intr)
+{
+ snd_ca0106_intr_enable((ca0106_t *)(midi->dev_id), intr);
+}
+
+static void ca0106_midi_interrupt_disable(ca_midi_t *midi, int intr)
+{
+ snd_ca0106_intr_disable((ca0106_t *)(midi->dev_id), intr);
+}
+
+static unsigned char ca0106_midi_read(ca_midi_t *midi, int idx)
+{
+ return (unsigned char)snd_ca0106_ptr_read((ca0106_t *)(midi->dev_id), midi->port + idx, 0);
+}
+
+static void ca0106_midi_write(ca_midi_t *midi, int data, int idx)
+{
+ snd_ca0106_ptr_write((ca0106_t *)(midi->dev_id), midi->port + idx, 0, data);
+}
+
+static snd_card_t *ca0106_dev_id_card(void *dev_id)
+{
+ return ((ca0106_t *)dev_id)->card;
+}
+
+static int ca0106_dev_id_port(void *dev_id)
+{
+ return ((ca0106_t *)dev_id)->port;
+}
+
+static int __devinit snd_ca0106_midi(ca0106_t *chip, unsigned int channel)
+{
+ ca_midi_t *midi;
+ char *name;
+ int err;
+
+ if(channel==CA0106_MIDI_CHAN_B) {
+ name = "CA0106 MPU-401 (UART) B";
+ midi = &chip->midi2;
+ midi->tx_enable = INTE_MIDI_TX_B;
+ midi->rx_enable = INTE_MIDI_RX_B;
+ midi->ipr_tx = IPR_MIDI_TX_B;
+ midi->ipr_rx = IPR_MIDI_RX_B;
+ midi->port = MIDI_UART_B_DATA;
+ } else {
+ name = "CA0106 MPU-401 (UART)";
+ midi = &chip->midi;
+ midi->tx_enable = INTE_MIDI_TX_A;
+ midi->rx_enable = INTE_MIDI_TX_B;
+ midi->ipr_tx = IPR_MIDI_TX_A;
+ midi->ipr_rx = IPR_MIDI_RX_A;
+ midi->port = MIDI_UART_A_DATA;
+ }
+
+ midi->reset = CA0106_MPU401_RESET;
+ midi->enter_uart = CA0106_MPU401_ENTER_UART;
+ midi->ack = CA0106_MPU401_ACK;
+
+ midi->input_avail = CA0106_MIDI_INPUT_AVAIL;
+ midi->output_ready = CA0106_MIDI_OUTPUT_READY;
+
+ midi->channel = channel;
+
+ midi->interrupt_enable = ca0106_midi_interrupt_enable;
+ midi->interrupt_disable = ca0106_midi_interrupt_disable;
+
+ midi->read = ca0106_midi_read;
+ midi->write = ca0106_midi_write;
+
+ midi->get_dev_id_card = ca0106_dev_id_card;
+ midi->get_dev_id_port = ca0106_dev_id_port;
+
+ midi->dev_id = chip;
+
+ if ((err = ca_midi_init(chip, midi, 0, name)) < 0)
+ return err;
+
+ return 0;
+}
+
+
static int __devinit snd_ca0106_probe(struct pci_dev *pci,
const struct pci_device_id *pci_id)
{
@@ -1362,6 +1463,14 @@ static int __devinit snd_ca0106_probe(struct pci_dev *pci,
return err;
}
+ snd_printdd("ca0106: probe for MIDI channel A ...");
+ if ((err = snd_ca0106_midi(chip,CA0106_MIDI_CHAN_A)) < 0) {
+ snd_card_free(card);
+ snd_printdd(" failed, err=0x%x\n",err);
+ return err;
+ }
+ snd_printdd(" done.\n");
+
snd_ca0106_proc_init(chip);
if ((err = snd_card_register(card)) < 0) {
@@ -1390,7 +1499,6 @@ MODULE_DEVICE_TABLE(pci, snd_ca0106_ids);
// pci_driver definition
static struct pci_driver driver = {
.name = "CA0106",
- .owner = THIS_MODULE,
.id_table = snd_ca0106_ids,
.probe = snd_ca0106_probe,
.remove = __devexit_p(snd_ca0106_remove),
diff --git a/sound/pci/ca0106/ca_midi.c b/sound/pci/ca0106/ca_midi.c
new file mode 100644
index 000000000000..2e08b27b8349
--- /dev/null
+++ b/sound/pci/ca0106/ca_midi.c
@@ -0,0 +1,306 @@
+/*
+ * Copyright 10/16/2005 Tilman Kranz <tilde@tk-sls.de>
+ * Creative Audio MIDI, for the CA0106 Driver
+ * Version: 0.0.1
+ *
+ * Changelog:
+ * Implementation is based on mpu401 and emu10k1x and
+ * tested with ca0106.
+ * mpu401: Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * emu10k1x: Copyright (c) by Francisco Moraes <fmoraes@nc.rr.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ *
+ */
+
+#include <linux/spinlock.h>
+#include <sound/driver.h>
+#include <sound/core.h>
+#include <sound/rawmidi.h>
+
+#include "ca_midi.h"
+
+#define ca_midi_write_data(midi, data) midi->write(midi, data, 0)
+#define ca_midi_write_cmd(midi, data) midi->write(midi, data, 1)
+#define ca_midi_read_data(midi) midi->read(midi, 0)
+#define ca_midi_read_stat(midi) midi->read(midi, 1)
+#define ca_midi_input_avail(midi) (!(ca_midi_read_stat(midi) & midi->input_avail))
+#define ca_midi_output_ready(midi) (!(ca_midi_read_stat(midi) & midi->output_ready))
+
+static void ca_midi_clear_rx(ca_midi_t *midi)
+{
+ int timeout = 100000;
+ for (; timeout > 0 && ca_midi_input_avail(midi); timeout--)
+ ca_midi_read_data(midi);
+#ifdef CONFIG_SND_DEBUG
+ if (timeout <= 0)
+ snd_printk(KERN_ERR "ca_midi_clear_rx: timeout (status = 0x%x)\n", ca_midi_read_stat(midi));
+#endif
+}
+
+static void ca_midi_interrupt(ca_midi_t *midi, unsigned int status) {
+ unsigned char byte;
+
+ if (midi->rmidi == NULL) {
+ midi->interrupt_disable(midi,midi->tx_enable | midi->rx_enable);
+ return;
+ }
+
+ spin_lock(&midi->input_lock);
+ if ((status & midi->ipr_rx) && ca_midi_input_avail(midi)) {
+ if (!(midi->midi_mode & CA_MIDI_MODE_INPUT)) {
+ ca_midi_clear_rx(midi);
+ } else {
+ byte = ca_midi_read_data(midi);
+ if(midi->substream_input)
+ snd_rawmidi_receive(midi->substream_input, &byte, 1);
+
+
+ }
+ }
+ spin_unlock(&midi->input_lock);
+
+ spin_lock(&midi->output_lock);
+ if ((status & midi->ipr_tx) && ca_midi_output_ready(midi)) {
+ if (midi->substream_output &&
+ snd_rawmidi_transmit(midi->substream_output, &byte, 1) == 1) {
+ ca_midi_write_data(midi, byte);
+ } else {
+ midi->interrupt_disable(midi,midi->tx_enable);
+ }
+ }
+ spin_unlock(&midi->output_lock);
+
+}
+
+static void ca_midi_cmd(ca_midi_t *midi, unsigned char cmd, int ack)
+{
+ unsigned long flags;
+ int timeout, ok;
+
+ spin_lock_irqsave(&midi->input_lock, flags);
+ ca_midi_write_data(midi, 0x00);
+ /* ca_midi_clear_rx(midi); */
+
+ ca_midi_write_cmd(midi, cmd);
+ if (ack) {
+ ok = 0;
+ timeout = 10000;
+ while (!ok && timeout-- > 0) {
+ if (ca_midi_input_avail(midi)) {
+ if (ca_midi_read_data(midi) == midi->ack)
+ ok = 1;
+ }
+ }
+ if (!ok && ca_midi_read_data(midi) == midi->ack)
+ ok = 1;
+ } else {
+ ok = 1;
+ }
+ spin_unlock_irqrestore(&midi->input_lock, flags);
+ if (!ok)
+ snd_printk(KERN_ERR "ca_midi_cmd: 0x%x failed at 0x%x (status = 0x%x, data = 0x%x)!!!\n",
+ cmd,
+ midi->get_dev_id_port(midi->dev_id),
+ ca_midi_read_stat(midi),
+ ca_midi_read_data(midi));
+}
+
+static int ca_midi_input_open(snd_rawmidi_substream_t * substream)
+{
+ ca_midi_t *midi = (ca_midi_t *)substream->rmidi->private_data;
+ unsigned long flags;
+
+ snd_assert(midi->dev_id, return -ENXIO);
+ spin_lock_irqsave(&midi->open_lock, flags);
+ midi->midi_mode |= CA_MIDI_MODE_INPUT;
+ midi->substream_input = substream;
+ if (!(midi->midi_mode & CA_MIDI_MODE_OUTPUT)) {
+ spin_unlock_irqrestore(&midi->open_lock, flags);
+ ca_midi_cmd(midi, midi->reset, 1);
+ ca_midi_cmd(midi, midi->enter_uart, 1);
+ } else {
+ spin_unlock_irqrestore(&midi->open_lock, flags);
+ }
+ return 0;
+}
+
+static int ca_midi_output_open(snd_rawmidi_substream_t * substream)
+{
+ ca_midi_t *midi = (ca_midi_t *)substream->rmidi->private_data;
+ unsigned long flags;
+
+ snd_assert(midi->dev_id, return -ENXIO);
+ spin_lock_irqsave(&midi->open_lock, flags);
+ midi->midi_mode |= CA_MIDI_MODE_OUTPUT;
+ midi->substream_output = substream;
+ if (!(midi->midi_mode & CA_MIDI_MODE_INPUT)) {
+ spin_unlock_irqrestore(&midi->open_lock, flags);
+ ca_midi_cmd(midi, midi->reset, 1);
+ ca_midi_cmd(midi, midi->enter_uart, 1);
+ } else {
+ spin_unlock_irqrestore(&midi->open_lock, flags);
+ }
+ return 0;
+}
+
+static int ca_midi_input_close(snd_rawmidi_substream_t * substream)
+{
+ ca_midi_t *midi = (ca_midi_t *)substream->rmidi->private_data;
+ unsigned long flags;
+
+ snd_assert(midi->dev_id, return -ENXIO);
+ spin_lock_irqsave(&midi->open_lock, flags);
+ midi->interrupt_disable(midi,midi->rx_enable);
+ midi->midi_mode &= ~CA_MIDI_MODE_INPUT;
+ midi->substream_input = NULL;
+ if (!(midi->midi_mode & CA_MIDI_MODE_OUTPUT)) {
+ spin_unlock_irqrestore(&midi->open_lock, flags);
+ ca_midi_cmd(midi, midi->reset, 0);
+ } else {
+ spin_unlock_irqrestore(&midi->open_lock, flags);
+ }
+ return 0;
+}
+
+static int ca_midi_output_close(snd_rawmidi_substream_t * substream)
+{
+ ca_midi_t *midi = (ca_midi_t *)substream->rmidi->private_data;
+ unsigned long flags;
+ snd_assert(midi->dev_id, return -ENXIO);
+
+ spin_lock_irqsave(&midi->open_lock, flags);
+
+ midi->interrupt_disable(midi,midi->tx_enable);
+ midi->midi_mode &= ~CA_MIDI_MODE_OUTPUT;
+ midi->substream_output = NULL;
+
+ if (!(midi->midi_mode & CA_MIDI_MODE_INPUT)) {
+ spin_unlock_irqrestore(&midi->open_lock, flags);
+ ca_midi_cmd(midi, midi->reset, 0);
+ } else {
+ spin_unlock_irqrestore(&midi->open_lock, flags);
+ }
+ return 0;
+}
+
+static void ca_midi_input_trigger(snd_rawmidi_substream_t * substream, int up)
+{
+ ca_midi_t *midi = (ca_midi_t *)substream->rmidi->private_data;
+ snd_assert(midi->dev_id, return);
+
+ if (up) {
+ midi->interrupt_enable(midi,midi->rx_enable);
+ } else {
+ midi->interrupt_disable(midi, midi->rx_enable);
+ }
+}
+
+static void ca_midi_output_trigger(snd_rawmidi_substream_t * substream, int up)
+{
+ ca_midi_t *midi = (ca_midi_t *)substream->rmidi->private_data;
+ unsigned long flags;
+
+ snd_assert(midi->dev_id, return);
+
+ if (up) {
+ int max = 4;
+ unsigned char byte;
+
+ spin_lock_irqsave(&midi->output_lock, flags);
+
+ /* try to send some amount of bytes here before interrupts */
+ while (max > 0) {
+ if (ca_midi_output_ready(midi)) {
+ if (!(midi->midi_mode & CA_MIDI_MODE_OUTPUT) ||
+ snd_rawmidi_transmit(substream, &byte, 1) != 1) {
+ /* no more data */
+ spin_unlock_irqrestore(&midi->output_lock, flags);
+ return;
+ }
+ ca_midi_write_data(midi, byte);
+ max--;
+ } else {
+ break;
+ }
+ }
+
+ spin_unlock_irqrestore(&midi->output_lock, flags);
+ midi->interrupt_enable(midi,midi->tx_enable);
+
+ } else {
+ midi->interrupt_disable(midi,midi->tx_enable);
+ }
+}
+
+static snd_rawmidi_ops_t ca_midi_output =
+{
+ .open = ca_midi_output_open,
+ .close = ca_midi_output_close,
+ .trigger = ca_midi_output_trigger,
+};
+
+static snd_rawmidi_ops_t ca_midi_input =
+{
+ .open = ca_midi_input_open,
+ .close = ca_midi_input_close,
+ .trigger = ca_midi_input_trigger,
+};
+
+static void ca_midi_free(ca_midi_t *midi) {
+ midi->interrupt = NULL;
+ midi->interrupt_enable = NULL;
+ midi->interrupt_disable = NULL;
+ midi->read = NULL;
+ midi->write = NULL;
+ midi->get_dev_id_card = NULL;
+ midi->get_dev_id_port = NULL;
+ midi->rmidi = NULL;
+}
+
+static void ca_rmidi_free(snd_rawmidi_t *rmidi)
+{
+ ca_midi_free((ca_midi_t *)rmidi->private_data);
+}
+
+int __devinit ca_midi_init(void *dev_id, ca_midi_t *midi, int device, char *name)
+{
+ snd_rawmidi_t *rmidi;
+ int err;
+
+ if ((err = snd_rawmidi_new(midi->get_dev_id_card(midi->dev_id), name, device, 1, 1, &rmidi)) < 0)
+ return err;
+
+ midi->dev_id = dev_id;
+ midi->interrupt = ca_midi_interrupt;
+
+ spin_lock_init(&midi->open_lock);
+ spin_lock_init(&midi->input_lock);
+ spin_lock_init(&midi->output_lock);
+
+ strcpy(rmidi->name, name);
+ snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, &ca_midi_output);
+ snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, &ca_midi_input);
+ rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT |
+ SNDRV_RAWMIDI_INFO_INPUT |
+ SNDRV_RAWMIDI_INFO_DUPLEX;
+ rmidi->private_data = midi;
+ rmidi->private_free = ca_rmidi_free;
+
+ midi->rmidi = rmidi;
+ return 0;
+}
+
diff --git a/sound/pci/ca0106/ca_midi.h b/sound/pci/ca0106/ca_midi.h
new file mode 100644
index 000000000000..b452cec2bf57
--- /dev/null
+++ b/sound/pci/ca0106/ca_midi.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright 10/16/2005 Tilman Kranz <tilde@tk-sls.de>
+ * Creative Audio MIDI, for the CA0106 Driver
+ * Version: 0.0.1
+ *
+ * Changelog:
+ * See ca_midi.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include<linux/spinlock.h>
+#include<sound/rawmidi.h>
+#include<sound/mpu401.h>
+
+#define CA_MIDI_MODE_INPUT MPU401_MODE_INPUT
+#define CA_MIDI_MODE_OUTPUT MPU401_MODE_OUTPUT
+
+typedef struct ca_midi ca_midi_t;
+struct ca_midi {
+
+ snd_rawmidi_t *rmidi;
+ snd_rawmidi_substream_t *substream_input;
+ snd_rawmidi_substream_t *substream_output;
+
+ void *dev_id;
+
+ spinlock_t input_lock;
+ spinlock_t output_lock;
+ spinlock_t open_lock;
+
+ unsigned int channel;
+
+ unsigned int midi_mode;
+ int port;
+ int tx_enable, rx_enable;
+ int ipr_tx, ipr_rx;
+
+ int input_avail, output_ready;
+ int ack, reset, enter_uart;
+
+ void (*interrupt)(ca_midi_t *midi, unsigned int status);
+ void (*interrupt_enable)(ca_midi_t *midi, int intr);
+ void (*interrupt_disable)(ca_midi_t *midi, int intr);
+
+ unsigned char (*read)(ca_midi_t *midi, int idx);
+ void (*write)(ca_midi_t *midi, int data, int idx);
+
+ /* get info from dev_id */
+ snd_card_t *(*get_dev_id_card)(void *dev_id);
+ int (*get_dev_id_port)(void *dev_id);
+};
+
+int __devinit ca_midi_init(void *card, ca_midi_t *midi, int device, char *name);
+
+
diff --git a/sound/pci/cmipci.c b/sound/pci/cmipci.c
index 1eb3315d136d..db605373b3bc 100644
--- a/sound/pci/cmipci.c
+++ b/sound/pci/cmipci.c
@@ -446,9 +446,6 @@ struct snd_stru_cmipci {
snd_kcontrol_t *mixer_res_ctl[CM_SAVED_MIXERS];
int mixer_res_status[CM_SAVED_MIXERS];
- opl3_t *opl3;
- snd_hwdep_t *opl3hwdep;
-
cmipci_pcm_t channel[2]; /* ch0 - DAC, ch1 - ADC or 2nd DAC */
/* external MIDI */
@@ -2686,8 +2683,7 @@ static int __devinit snd_cmipci_create_gameport(cmipci_t *cm, int dev)
cm->gameport = gp = gameport_allocate_port();
if (!gp) {
printk(KERN_ERR "cmipci: cannot allocate memory for gameport\n");
- release_resource(r);
- kfree_nocheck(r);
+ release_and_free_resource(r);
return -ENOMEM;
}
gameport_set_name(gp, "C-Media Gameport");
@@ -2712,8 +2708,7 @@ static void snd_cmipci_free_gameport(cmipci_t *cm)
cm->gameport = NULL;
snd_cmipci_clear_bit(cm, CM_REG_FUNCTRL1, CM_JYSTK_EN);
- release_resource(r);
- kfree_nocheck(r);
+ release_and_free_resource(r);
}
}
#else
@@ -2753,6 +2748,51 @@ static int snd_cmipci_dev_free(snd_device_t *device)
return snd_cmipci_free(cm);
}
+static int __devinit snd_cmipci_create_fm(cmipci_t *cm, long fm_port)
+{
+ long iosynth;
+ unsigned int val;
+ opl3_t *opl3;
+ int err;
+
+ /* first try FM regs in PCI port range */
+ iosynth = cm->iobase + CM_REG_FM_PCI;
+ err = snd_opl3_create(cm->card, iosynth, iosynth + 2,
+ OPL3_HW_OPL3, 1, &opl3);
+ if (err < 0) {
+ /* then try legacy ports */
+ val = snd_cmipci_read(cm, CM_REG_LEGACY_CTRL) & ~CM_FMSEL_MASK;
+ iosynth = fm_port;
+ switch (iosynth) {
+ case 0x3E8: val |= CM_FMSEL_3E8; break;
+ case 0x3E0: val |= CM_FMSEL_3E0; break;
+ case 0x3C8: val |= CM_FMSEL_3C8; break;
+ case 0x388: val |= CM_FMSEL_388; break;
+ default:
+ return 0;
+ }
+ snd_cmipci_write(cm, CM_REG_LEGACY_CTRL, val);
+ /* enable FM */
+ snd_cmipci_set_bit(cm, CM_REG_MISC_CTRL, CM_FM_EN);
+
+ if (snd_opl3_create(cm->card, iosynth, iosynth + 2,
+ OPL3_HW_OPL3, 0, &opl3) < 0) {
+ printk(KERN_ERR "cmipci: no OPL device at %#lx, "
+ "skipping...\n", iosynth);
+ /* disable FM */
+ snd_cmipci_write(cm, CM_REG_LEGACY_CTRL,
+ val & ~CM_FMSEL_MASK);
+ snd_cmipci_clear_bit(cm, CM_REG_MISC_CTRL, CM_FM_EN);
+ return 0;
+ }
+ }
+ if ((err = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0) {
+ printk(KERN_ERR "cmipci: cannot create OPL3 hwdep\n");
+ return err;
+ }
+ return 0;
+}
+
static int __devinit snd_cmipci_create(snd_card_t *card, struct pci_dev *pci,
int dev, cmipci_t **rcmipci)
{
@@ -2762,8 +2802,8 @@ static int __devinit snd_cmipci_create(snd_card_t *card, struct pci_dev *pci,
.dev_free = snd_cmipci_dev_free,
};
unsigned int val = 0;
- long iomidi = mpu_port[dev];
- long iosynth = fm_port[dev];
+ long iomidi;
+ int integrated_midi;
int pcm_index, pcm_spdif_index;
static struct pci_device_id intel_82437vx[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82437VX) },
@@ -2799,7 +2839,7 @@ static int __devinit snd_cmipci_create(snd_card_t *card, struct pci_dev *pci,
cm->iobase = pci_resource_start(pci, 0);
if (request_irq(pci->irq, snd_cmipci_interrupt, SA_INTERRUPT|SA_SHIRQ, card->driver, (void *)cm)) {
- snd_printk("unable to grab IRQ %d\n", pci->irq);
+ snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
snd_cmipci_free(cm);
return -EBUSY;
}
@@ -2867,52 +2907,28 @@ static int __devinit snd_cmipci_create(snd_card_t *card, struct pci_dev *pci,
return err;
}
- /* set MPU address */
- switch (iomidi) {
- case 0x320: val = CM_VMPU_320; break;
- case 0x310: val = CM_VMPU_310; break;
- case 0x300: val = CM_VMPU_300; break;
- case 0x330: val = CM_VMPU_330; break;
- default:
- iomidi = 0; break;
- }
- if (iomidi > 0) {
- snd_cmipci_write(cm, CM_REG_LEGACY_CTRL, val);
- /* enable UART */
- snd_cmipci_set_bit(cm, CM_REG_FUNCTRL1, CM_UART_EN);
- }
-
- /* set FM address */
- val = snd_cmipci_read(cm, CM_REG_LEGACY_CTRL) & ~CM_FMSEL_MASK;
- switch (iosynth) {
- case 0x3E8: val |= CM_FMSEL_3E8; break;
- case 0x3E0: val |= CM_FMSEL_3E0; break;
- case 0x3C8: val |= CM_FMSEL_3C8; break;
- case 0x388: val |= CM_FMSEL_388; break;
- default:
- iosynth = 0; break;
- }
- if (iosynth > 0) {
- snd_cmipci_write(cm, CM_REG_LEGACY_CTRL, val);
- /* enable FM */
- snd_cmipci_set_bit(cm, CM_REG_MISC_CTRL, CM_FM_EN);
-
- if (snd_opl3_create(card, iosynth, iosynth + 2,
- OPL3_HW_OPL3, 0, &cm->opl3) < 0) {
- printk(KERN_ERR "cmipci: no OPL device at 0x%lx, skipping...\n", iosynth);
- iosynth = 0;
- } else {
- if ((err = snd_opl3_hwdep_new(cm->opl3, 0, 1, &cm->opl3hwdep)) < 0) {
- printk(KERN_ERR "cmipci: cannot create OPL3 hwdep\n");
- return err;
- }
+ integrated_midi = snd_cmipci_read_b(cm, CM_REG_MPU_PCI) != 0xff;
+ if (integrated_midi)
+ iomidi = cm->iobase + CM_REG_MPU_PCI;
+ else {
+ iomidi = mpu_port[dev];
+ switch (iomidi) {
+ case 0x320: val = CM_VMPU_320; break;
+ case 0x310: val = CM_VMPU_310; break;
+ case 0x300: val = CM_VMPU_300; break;
+ case 0x330: val = CM_VMPU_330; break;
+ default:
+ iomidi = 0; break;
+ }
+ if (iomidi > 0) {
+ snd_cmipci_write(cm, CM_REG_LEGACY_CTRL, val);
+ /* enable UART */
+ snd_cmipci_set_bit(cm, CM_REG_FUNCTRL1, CM_UART_EN);
}
}
- if (! iosynth) {
- /* disable FM */
- snd_cmipci_write(cm, CM_REG_LEGACY_CTRL, val & ~CM_FMSEL_MASK);
- snd_cmipci_clear_bit(cm, CM_REG_MISC_CTRL, CM_FM_EN);
- }
+
+ if ((err = snd_cmipci_create_fm(cm, fm_port[dev])) < 0)
+ return err;
/* reset mixer */
snd_cmipci_mixer_write(cm, 0, 0);
@@ -2941,7 +2957,7 @@ static int __devinit snd_cmipci_create(snd_card_t *card, struct pci_dev *pci,
if (iomidi > 0) {
if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_CMIPCI,
- iomidi, 0,
+ iomidi, integrated_midi,
cm->irq, 0, &cm->rmidi)) < 0) {
printk(KERN_ERR "cmipci: no UART401 device at 0x%lx\n", iomidi);
}
@@ -3037,7 +3053,6 @@ static void __devexit snd_cmipci_remove(struct pci_dev *pci)
static struct pci_driver driver = {
.name = "C-Media PCI",
- .owner = THIS_MODULE,
.id_table = snd_cmipci_ids,
.probe = snd_cmipci_probe,
.remove = __devexit_p(snd_cmipci_remove),
diff --git a/sound/pci/cs4281.c b/sound/pci/cs4281.c
index dc87e0144b5a..034ff3755a3b 100644
--- a/sound/pci/cs4281.c
+++ b/sound/pci/cs4281.c
@@ -523,8 +523,7 @@ static void snd_cs4281_delay(unsigned int delay)
delay = 1;
end_time = jiffies + delay;
do {
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(1);
+ schedule_timeout_uninterruptible(1);
} while (time_after_eq(end_time, jiffies));
} else {
udelay(delay);
@@ -533,8 +532,7 @@ static void snd_cs4281_delay(unsigned int delay)
static inline void snd_cs4281_delay_long(void)
{
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(1);
+ schedule_timeout_uninterruptible(1);
}
static inline void snd_cs4281_pokeBA0(cs4281_t *chip, unsigned long offset, unsigned int val)
@@ -2108,7 +2106,6 @@ static int cs4281_resume(snd_card_t *card)
static struct pci_driver driver = {
.name = "CS4281",
- .owner = THIS_MODULE,
.id_table = snd_cs4281_ids,
.probe = snd_cs4281_probe,
.remove = __devexit_p(snd_cs4281_remove),
diff --git a/sound/pci/cs46xx/cs46xx.c b/sound/pci/cs46xx/cs46xx.c
index 32b4f8465cef..b9fff4ee6f9d 100644
--- a/sound/pci/cs46xx/cs46xx.c
+++ b/sound/pci/cs46xx/cs46xx.c
@@ -163,7 +163,6 @@ static void __devexit snd_card_cs46xx_remove(struct pci_dev *pci)
static struct pci_driver driver = {
.name = "Sound Fusion CS46xx",
- .owner = THIS_MODULE,
.id_table = snd_cs46xx_ids,
.probe = snd_card_cs46xx_probe,
.remove = __devexit_p(snd_card_cs46xx_remove),
diff --git a/sound/pci/cs46xx/cs46xx_lib.c b/sound/pci/cs46xx/cs46xx_lib.c
index 6e3855b8b33d..9b8af5bcbb04 100644
--- a/sound/pci/cs46xx/cs46xx_lib.c
+++ b/sound/pci/cs46xx/cs46xx_lib.c
@@ -163,7 +163,7 @@ static unsigned short snd_cs46xx_codec_read(cs46xx_t *chip,
goto ok1;
}
- snd_printk("AC'97 read problem (ACCTL_DCV), reg = 0x%x\n", reg);
+ snd_printk(KERN_ERR "AC'97 read problem (ACCTL_DCV), reg = 0x%x\n", reg);
result = 0xffff;
goto end;
@@ -182,7 +182,7 @@ static unsigned short snd_cs46xx_codec_read(cs46xx_t *chip,
udelay(10);
}
- snd_printk("AC'97 read problem (ACSTS_VSTS), codec_index %d, reg = 0x%x\n", codec_index, reg);
+ snd_printk(KERN_ERR "AC'97 read problem (ACSTS_VSTS), codec_index %d, reg = 0x%x\n", codec_index, reg);
result = 0xffff;
goto end;
@@ -281,7 +281,7 @@ static void snd_cs46xx_codec_write(cs46xx_t *chip,
goto end;
}
}
- snd_printk("AC'97 write problem, codec_index = %d, reg = 0x%x, val = 0x%x\n", codec_index, reg, val);
+ snd_printk(KERN_ERR "AC'97 write problem, codec_index = %d, reg = 0x%x, val = 0x%x\n", codec_index, reg, val);
end:
chip->active_ctrl(chip, -1);
}
@@ -510,7 +510,7 @@ static void snd_cs46xx_proc_start(cs46xx_t *chip)
}
if (snd_cs46xx_peek(chip, BA1_SPCR) & SPCR_RUNFR)
- snd_printk("SPCR_RUNFR never reset\n");
+ snd_printk(KERN_ERR "SPCR_RUNFR never reset\n");
}
static void snd_cs46xx_proc_stop(cs46xx_t *chip)
@@ -2403,7 +2403,7 @@ static void snd_cs46xx_codec_reset (ac97_t * ac97)
msleep(10);
} while (time_after_eq(end_time, jiffies));
- snd_printk("CS46xx secondary codec dont respond!\n");
+ snd_printk(KERN_ERR "CS46xx secondary codec doesn't respond!\n");
}
#endif
@@ -2906,10 +2906,7 @@ static int snd_cs46xx_free(cs46xx_t *chip)
snd_cs46xx_region_t *region = &chip->region.idx[idx];
if (region->remap_addr)
iounmap(region->remap_addr);
- if (region->resource) {
- release_resource(region->resource);
- kfree_nocheck(region->resource);
- }
+ release_and_free_resource(region->resource);
}
if (chip->irq >= 0)
free_irq(chip->irq, (void *)chip);
@@ -3075,8 +3072,8 @@ static int snd_cs46xx_chip_init(cs46xx_t *chip)
}
- snd_printk("create - never read codec ready from AC'97\n");
- snd_printk("it is not probably bug, try to use CS4236 driver\n");
+ snd_printk(KERN_ERR "create - never read codec ready from AC'97\n");
+ snd_printk(KERN_ERR "it is not probably bug, try to use CS4236 driver\n");
return -EIO;
ok1:
#ifdef CONFIG_SND_CS46XX_NEW_DSP
@@ -3124,17 +3121,17 @@ static int snd_cs46xx_chip_init(cs46xx_t *chip)
}
#ifndef CONFIG_SND_CS46XX_NEW_DSP
- snd_printk("create - never read ISV3 & ISV4 from AC'97\n");
+ snd_printk(KERN_ERR "create - never read ISV3 & ISV4 from AC'97\n");
return -EIO;
#else
/* This may happen on a cold boot with a Terratec SiXPack 5.1.
Reloading the driver may help, if there's other soundcards
with the same problem I would like to know. (Benny) */
- snd_printk("ERROR: snd-cs46xx: never read ISV3 & ISV4 from AC'97\n");
- snd_printk(" Try reloading the ALSA driver, if you find something\n");
- snd_printk(" broken or not working on your soundcard upon\n");
- snd_printk(" this message please report to alsa-devel@lists.sourceforge.net\n");
+ snd_printk(KERN_ERR "ERROR: snd-cs46xx: never read ISV3 & ISV4 from AC'97\n");
+ snd_printk(KERN_ERR " Try reloading the ALSA driver, if you find something\n");
+ snd_printk(KERN_ERR " broken or not working on your soundcard upon\n");
+ snd_printk(KERN_ERR " this message please report to alsa-devel@lists.sourceforge.net\n");
return -EIO;
#endif
@@ -3215,7 +3212,7 @@ int __devinit snd_cs46xx_start_dsp(cs46xx_t *chip)
#else
/* old image */
if (snd_cs46xx_download_image(chip) < 0) {
- snd_printk("image download error\n");
+ snd_printk(KERN_ERR "image download error\n");
return -EIO;
}
@@ -3790,7 +3787,7 @@ int __devinit snd_cs46xx_create(snd_card_t * card,
chip->ba1_addr = pci_resource_start(pci, 1);
if (chip->ba0_addr == 0 || chip->ba0_addr == (unsigned long)~0 ||
chip->ba1_addr == 0 || chip->ba1_addr == (unsigned long)~0) {
- snd_printk("wrong address(es) - ba0 = 0x%lx, ba1 = 0x%lx\n", chip->ba0_addr, chip->ba1_addr);
+ snd_printk(KERN_ERR "wrong address(es) - ba0 = 0x%lx, ba1 = 0x%lx\n", chip->ba0_addr, chip->ba1_addr);
snd_cs46xx_free(chip);
return -ENOMEM;
}
@@ -3839,12 +3836,12 @@ int __devinit snd_cs46xx_create(snd_card_t * card,
}
if (external_amp) {
- snd_printk("Crystal EAPD support forced on.\n");
+ snd_printk(KERN_INFO "Crystal EAPD support forced on.\n");
chip->amplifier_ctrl = amp_voyetra;
}
if (thinkpad) {
- snd_printk("Activating CLKRUN hack for Thinkpad.\n");
+ snd_printk(KERN_INFO "Activating CLKRUN hack for Thinkpad.\n");
chip->active_ctrl = clkrun_hack;
clkrun_init(chip);
}
@@ -3861,20 +3858,20 @@ int __devinit snd_cs46xx_create(snd_card_t * card,
for (idx = 0; idx < 5; idx++) {
region = &chip->region.idx[idx];
if ((region->resource = request_mem_region(region->base, region->size, region->name)) == NULL) {
- snd_printk("unable to request memory region 0x%lx-0x%lx\n", region->base, region->base + region->size - 1);
+ snd_printk(KERN_ERR "unable to request memory region 0x%lx-0x%lx\n", region->base, region->base + region->size - 1);
snd_cs46xx_free(chip);
return -EBUSY;
}
region->remap_addr = ioremap_nocache(region->base, region->size);
if (region->remap_addr == NULL) {
- snd_printk("%s ioremap problem\n", region->name);
+ snd_printk(KERN_ERR "%s ioremap problem\n", region->name);
snd_cs46xx_free(chip);
return -ENOMEM;
}
}
if (request_irq(pci->irq, snd_cs46xx_interrupt, SA_INTERRUPT|SA_SHIRQ, "CS46XX", (void *) chip)) {
- snd_printk("unable to grab IRQ %d\n", pci->irq);
+ snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
snd_cs46xx_free(chip);
return -EBUSY;
}
diff --git a/sound/pci/emu10k1/emu10k1.c b/sound/pci/emu10k1/emu10k1.c
index b0e00f0a7c2f..78270f8710ff 100644
--- a/sound/pci/emu10k1/emu10k1.c
+++ b/sound/pci/emu10k1/emu10k1.c
@@ -188,7 +188,7 @@ static int __devinit snd_card_emu10k1_probe(struct pci_dev *pci,
if (snd_seq_device_new(card, 1, SNDRV_SEQ_DEV_ID_EMU10K1_SYNTH,
sizeof(snd_emu10k1_synth_arg_t), &wave) < 0 ||
wave == NULL) {
- snd_printk("can't initialize Emu10k1 wavetable synth\n");
+ snd_printk(KERN_WARNING "can't initialize Emu10k1 wavetable synth\n");
} else {
snd_emu10k1_synth_arg_t *arg;
arg = SNDRV_SEQ_DEVICE_ARGPTR(wave);
@@ -223,7 +223,6 @@ static void __devexit snd_card_emu10k1_remove(struct pci_dev *pci)
static struct pci_driver driver = {
.name = "EMU10K1_Audigy",
- .owner = THIS_MODULE,
.id_table = snd_emu10k1_ids,
.probe = snd_card_emu10k1_probe,
.remove = __devexit_p(snd_card_emu10k1_remove),
diff --git a/sound/pci/emu10k1/emu10k1_callback.c b/sound/pci/emu10k1/emu10k1_callback.c
index 7cf2f908eed9..6589bf24abcd 100644
--- a/sound/pci/emu10k1/emu10k1_callback.c
+++ b/sound/pci/emu10k1/emu10k1_callback.c
@@ -241,7 +241,7 @@ lookup_voices(snd_emux_t *emu, emu10k1_t *hw, best_voice_t *best, int active_onl
else if (state == SNDRV_EMUX_ST_RELEASED ||
state == SNDRV_EMUX_ST_PENDING) {
bp = best + V_RELEASED;
-#if 0
+#if 1
val = snd_emu10k1_ptr_read(hw, CVCF_CURRENTVOL, vp->ch);
if (! val)
bp = best + V_OFF;
@@ -349,7 +349,7 @@ start_voice(snd_emux_voice_t *vp)
}
/* channel to be silent and idle */
- snd_emu10k1_ptr_write(hw, DCYSUSV, ch, 0x0080);
+ snd_emu10k1_ptr_write(hw, DCYSUSV, ch, 0x0000);
snd_emu10k1_ptr_write(hw, VTFT, ch, 0x0000FFFF);
snd_emu10k1_ptr_write(hw, CVCF, ch, 0x0000FFFF);
snd_emu10k1_ptr_write(hw, PTRX, ch, 0);
diff --git a/sound/pci/emu10k1/emu10k1_main.c b/sound/pci/emu10k1/emu10k1_main.c
index e9cd8e054f25..53aeff0b783a 100644
--- a/sound/pci/emu10k1/emu10k1_main.c
+++ b/sound/pci/emu10k1/emu10k1_main.c
@@ -579,6 +579,30 @@ static int __devinit snd_emu10k1_ecard_init(emu10k1_t * emu)
return 0;
}
+static int __devinit snd_emu10k1_cardbus_init(emu10k1_t * emu)
+{
+ unsigned long special_port;
+ unsigned int value;
+
+ /* Special initialisation routine
+ * before the rest of the IO-Ports become active.
+ */
+ special_port = emu->port + 0x38;
+ value = inl(special_port);
+ outl(0x00d00000, special_port);
+ value = inl(special_port);
+ outl(0x00d00001, special_port);
+ value = inl(special_port);
+ outl(0x00d0005f, special_port);
+ value = inl(special_port);
+ outl(0x00d0007f, special_port);
+ value = inl(special_port);
+ outl(0x0090007f, special_port);
+ value = inl(special_port);
+
+ return 0;
+}
+
/*
* Create the EMU10K1 instance
*/
@@ -624,6 +648,16 @@ static emu_chip_details_t emu_chip_details[] = {
.ca0108_chip = 1,
.spk71 = 1,
.ac97_chip = 1} ,
+ /* Audigy 2 ZS Notebook Cardbus card.*/
+ /* Tested by James@superbug.co.uk 30th October 2005 */
+ /* Not working yet, but progressing. */
+ {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x20011102,
+ .driver = "Audigy2", .name = "Audigy 2 ZS Notebook [SB0530]",
+ .id = "Audigy2",
+ .emu10k2_chip = 1,
+ .ca0108_chip = 1,
+ .ca_cardbus_chip = 1,
+ .spk71 = 1} ,
{.vendor = 0x1102, .device = 0x0008,
.driver = "Audigy2", .name = "Audigy 2 Value [Unknown]",
.id = "Audigy2",
@@ -1011,6 +1045,11 @@ int __devinit snd_emu10k1_create(snd_card_t * card,
snd_emu10k1_free(emu);
return err;
}
+ } else if (emu->card_capabilities->ca_cardbus_chip) {
+ if ((err = snd_emu10k1_cardbus_init(emu)) < 0) {
+ snd_emu10k1_free(emu);
+ return err;
+ }
} else {
/* 5.1: Enable the additional AC97 Slots. If the emu10k1 version
does not support this, it shouldn't do any harm */
diff --git a/sound/pci/emu10k1/emu10k1x.c b/sound/pci/emu10k1/emu10k1x.c
index ad15755a63c3..795577716a5d 100644
--- a/sound/pci/emu10k1/emu10k1x.c
+++ b/sound/pci/emu10k1/emu10k1x.c
@@ -759,10 +759,8 @@ static int snd_emu10k1x_free(emu10k1x_t *chip)
outl(HCFG_LOCKSOUNDCACHE, chip->port + HCFG);
// release the i/o port
- if (chip->res_port) {
- release_resource(chip->res_port);
- kfree_nocheck(chip->res_port);
- }
+ release_and_free_resource(chip->res_port);
+
// release the irq
if (chip->irq >= 0)
free_irq(chip->irq, (void *)chip);
@@ -1615,7 +1613,6 @@ MODULE_DEVICE_TABLE(pci, snd_emu10k1x_ids);
// pci_driver definition
static struct pci_driver driver = {
.name = "EMU10K1X",
- .owner = THIS_MODULE,
.id_table = snd_emu10k1x_ids,
.probe = snd_emu10k1x_probe,
.remove = __devexit_p(snd_emu10k1x_remove),
diff --git a/sound/pci/emu10k1/emufx.c b/sound/pci/emu10k1/emufx.c
index 646b5d972e6f..03e8c1678952 100644
--- a/sound/pci/emu10k1/emufx.c
+++ b/sound/pci/emu10k1/emufx.c
@@ -364,12 +364,18 @@ static int snd_emu10k1_gpr_ctl_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value
snd_emu10k1_ptr_write(emu, emu->gpr_base + ctl->gpr[i], 0, db_table[val]);
break;
case EMU10K1_GPR_TRANSLATION_BASS:
- snd_runtime_check((ctl->count % 5) == 0 && (ctl->count / 5) == ctl->vcount, change = -EIO; goto __error);
+ if ((ctl->count % 5) != 0 || (ctl->count / 5) != ctl->vcount) {
+ change = -EIO;
+ goto __error;
+ }
for (j = 0; j < 5; j++)
snd_emu10k1_ptr_write(emu, emu->gpr_base + ctl->gpr[j * ctl->vcount + i], 0, bass_table[val][j]);
break;
case EMU10K1_GPR_TRANSLATION_TREBLE:
- snd_runtime_check((ctl->count % 5) == 0 && (ctl->count / 5) == ctl->vcount, change = -EIO; goto __error);
+ if ((ctl->count % 5) != 0 || (ctl->count / 5) != ctl->vcount) {
+ change = -EIO;
+ goto __error;
+ }
for (j = 0; j < 5; j++)
snd_emu10k1_ptr_write(emu, emu->gpr_base + ctl->gpr[j * ctl->vcount + i], 0, treble_table[val][j]);
break;
@@ -412,8 +418,6 @@ int snd_emu10k1_fx8010_register_irq_handler(emu10k1_t *emu,
snd_emu10k1_fx8010_irq_t *irq;
unsigned long flags;
- snd_runtime_check(emu, return -EINVAL);
- snd_runtime_check(handler, return -EINVAL);
irq = kmalloc(sizeof(*irq), GFP_ATOMIC);
if (irq == NULL)
return -ENOMEM;
@@ -442,7 +446,6 @@ int snd_emu10k1_fx8010_unregister_irq_handler(emu10k1_t *emu,
snd_emu10k1_fx8010_irq_t *tmp;
unsigned long flags;
- snd_runtime_check(irq, return -EINVAL);
spin_lock_irqsave(&emu->fx8010.irq_lock, flags);
if ((tmp = emu->fx8010.irq_handlers) == irq) {
emu->fx8010.irq_handlers = tmp->next;
@@ -717,9 +720,15 @@ static int snd_emu10k1_add_controls(emu10k1_t *emu, emu10k1_fx8010_code_t *icode
err = -EFAULT;
goto __error;
}
- snd_runtime_check(gctl->id.iface == SNDRV_CTL_ELEM_IFACE_MIXER ||
- gctl->id.iface == SNDRV_CTL_ELEM_IFACE_PCM, err = -EINVAL; goto __error);
- snd_runtime_check(gctl->id.name[0] != '\0', err = -EINVAL; goto __error);
+ if (gctl->id.iface != SNDRV_CTL_ELEM_IFACE_MIXER &&
+ gctl->id.iface != SNDRV_CTL_ELEM_IFACE_PCM) {
+ err = -EINVAL;
+ goto __error;
+ }
+ if (! gctl->id.name[0]) {
+ err = -EINVAL;
+ goto __error;
+ }
ctl = snd_emu10k1_look_for_ctl(emu, &gctl->id);
memset(&knew, 0, sizeof(knew));
knew.iface = gctl->id.iface;
@@ -783,7 +792,8 @@ static int snd_emu10k1_del_controls(emu10k1_t *emu, emu10k1_fx8010_code_t *icode
for (i = 0, _id = icode->gpr_del_controls;
i < icode->gpr_del_control_count; i++, _id++) {
- snd_runtime_check(copy_from_user(&id, _id, sizeof(id)) == 0, return -EFAULT);
+ if (copy_from_user(&id, _id, sizeof(id)))
+ return -EFAULT;
down_write(&card->controls_rwsem);
ctl = snd_emu10k1_look_for_ctl(emu, &id);
if (ctl)
@@ -964,8 +974,8 @@ static int snd_emu10k1_ipcm_peek(emu10k1_t *emu, emu10k1_fx8010_pcm_t *ipcm)
return err;
}
-#define SND_EMU10K1_GPR_CONTROLS 41
-#define SND_EMU10K1_INPUTS 10
+#define SND_EMU10K1_GPR_CONTROLS 44
+#define SND_EMU10K1_INPUTS 12
#define SND_EMU10K1_PLAYBACK_CHANNELS 8
#define SND_EMU10K1_CAPTURE_CHANNELS 4
@@ -1382,7 +1392,7 @@ A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input))
A_SWITCH(icode, &ptr, tmp + 1, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, tmp + 1);
if ((z==1) && (emu->card_capabilities->spdif_bug)) {
/* Due to a SPDIF output bug on some Audigy cards, this code delays the Right channel by 1 sample */
- snd_printk("Installing spdif_bug patch: %s\n", emu->card_capabilities->name);
+ snd_printk(KERN_INFO "Installing spdif_bug patch: %s\n", emu->card_capabilities->name);
A_OP(icode, &ptr, iACC3, A_EXTOUT(A_EXTOUT_FRONT_L + z), A_GPR(gpr - 3), A_C_00000000, A_C_00000000);
A_OP(icode, &ptr, iACC3, A_GPR(gpr - 3), A_GPR(tmp + 0), A_GPR(tmp + 1), A_C_00000000);
} else {
@@ -1527,7 +1537,7 @@ static int __devinit _snd_emu10k1_init_efx(emu10k1_t *emu)
strcpy(icode->name, "SB Live! FX8010 code for ALSA v1.2 by Jaroslav Kysela");
ptr = 0; i = 0;
- /* we have 10 inputs */
+ /* we have 12 inputs */
playback = SND_EMU10K1_INPUTS;
/* we have 6 playback channels and tone control doubles */
capture = playback + (SND_EMU10K1_PLAYBACK_CHANNELS * 2);
@@ -1551,6 +1561,8 @@ static int __devinit _snd_emu10k1_init_efx(emu10k1_t *emu)
OP(icode, &ptr, iMACINT0, GPR(7), C_00000000, FXBUS(FXBUS_PCM_LFE), C_00000004);
OP(icode, &ptr, iMACINT0, GPR(8), C_00000000, C_00000000, C_00000000); /* S/PDIF left */
OP(icode, &ptr, iMACINT0, GPR(9), C_00000000, C_00000000, C_00000000); /* S/PDIF right */
+ OP(icode, &ptr, iMACINT0, GPR(10), C_00000000, FXBUS(FXBUS_PCM_LEFT_FRONT), C_00000004);
+ OP(icode, &ptr, iMACINT0, GPR(11), C_00000000, FXBUS(FXBUS_PCM_RIGHT_FRONT), C_00000004);
/* Raw S/PDIF PCM */
ipcm->substream = 0;
@@ -1697,6 +1709,21 @@ static int __devinit _snd_emu10k1_init_efx(emu10k1_t *emu)
VOLUME_ADD(icode, &ptr, playback + 5, 7, gpr);
snd_emu10k1_init_mono_control(controls + i++, "LFE Digital Playback Volume", gpr++, 100);
+ /* Front Playback Volume */
+ for (z = 0; z < 2; z++)
+ VOLUME_ADD(icode, &ptr, playback + z, 10 + z, gpr + z);
+ snd_emu10k1_init_stereo_control(controls + i++, "Front Playback Volume", gpr, 100);
+ gpr += 2;
+
+ /* Front Capture Volume + Switch */
+ for (z = 0; z < 2; z++) {
+ SWITCH(icode, &ptr, tmp + 0, 10 + z, gpr + 2);
+ VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
+ }
+ snd_emu10k1_init_stereo_control(controls + i++, "Front Capture Volume", gpr, 0);
+ snd_emu10k1_init_mono_onoff_control(controls + i++, "Front Capture Switch", gpr + 2, 0);
+ gpr += 3;
+
/*
* Process inputs
*/
@@ -2058,14 +2085,16 @@ void snd_emu10k1_free_efx(emu10k1_t *emu)
#if 0 // FIXME: who use them?
int snd_emu10k1_fx8010_tone_control_activate(emu10k1_t *emu, int output)
{
- snd_runtime_check(output >= 0 && output < 6, return -EINVAL);
+ if (output < 0 || output >= 6)
+ return -EINVAL;
snd_emu10k1_ptr_write(emu, emu->gpr_base + 0x94 + output, 0, 1);
return 0;
}
int snd_emu10k1_fx8010_tone_control_deactivate(emu10k1_t *emu, int output)
{
- snd_runtime_check(output >= 0 && output < 6, return -EINVAL);
+ if (output < 0 || output >= 6)
+ return -EINVAL;
snd_emu10k1_ptr_write(emu, emu->gpr_base + 0x94 + output, 0, 0);
return 0;
}
diff --git a/sound/pci/emu10k1/emupcm.c b/sound/pci/emu10k1/emupcm.c
index 66ba27afe962..bf7490dae09b 100644
--- a/sound/pci/emu10k1/emupcm.c
+++ b/sound/pci/emu10k1/emupcm.c
@@ -965,7 +965,8 @@ static void snd_emu10k1_pcm_mixer_notify1(emu10k1_t *emu, snd_kcontrol_t *kctl,
{
snd_ctl_elem_id_t id;
- snd_runtime_check(kctl != NULL, return);
+ if (! kctl)
+ return;
if (activate)
kctl->vd[idx].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
else
diff --git a/sound/pci/emu10k1/irq.c b/sound/pci/emu10k1/irq.c
index cd8460d56752..594ea063b140 100644
--- a/sound/pci/emu10k1/irq.c
+++ b/sound/pci/emu10k1/irq.c
@@ -41,7 +41,7 @@ irqreturn_t snd_emu10k1_interrupt(int irq, void *dev_id, struct pt_regs *regs)
orig_status = status;
handled = 1;
if (status & IPR_PCIERROR) {
- snd_printk("interrupt: PCI error\n");
+ snd_printk(KERN_ERR "interrupt: PCI error\n");
snd_emu10k1_intr_disable(emu, INTE_PCIERRORENABLE);
status &= ~IPR_PCIERROR;
}
diff --git a/sound/pci/emu10k1/memory.c b/sound/pci/emu10k1/memory.c
index 6afeaeab3e13..d42e4aeaa73a 100644
--- a/sound/pci/emu10k1/memory.c
+++ b/sound/pci/emu10k1/memory.c
@@ -232,11 +232,11 @@ __found_pages:
static int is_valid_page(emu10k1_t *emu, dma_addr_t addr)
{
if (addr & ~emu->dma_mask) {
- snd_printk("max memory size is 0x%lx (addr = 0x%lx)!!\n", emu->dma_mask, (unsigned long)addr);
+ snd_printk(KERN_ERR "max memory size is 0x%lx (addr = 0x%lx)!!\n", emu->dma_mask, (unsigned long)addr);
return 0;
}
if (addr & (EMUPAGESIZE-1)) {
- snd_printk("page is not aligned\n");
+ snd_printk(KERN_ERR "page is not aligned\n");
return 0;
}
return 1;
@@ -501,7 +501,7 @@ static inline void *offset_ptr(emu10k1_t *emu, int page, int offset)
snd_assert(page >= 0 && page < emu->max_cache_pages, return NULL);
ptr = emu->page_ptr_table[page];
if (! ptr) {
- printk("emu10k1: access to NULL ptr: page = %d\n", page);
+ printk(KERN_ERR "emu10k1: access to NULL ptr: page = %d\n", page);
return NULL;
}
ptr += offset & (PAGE_SIZE - 1);
diff --git a/sound/pci/emu10k1/p16v.c b/sound/pci/emu10k1/p16v.c
index d59c7f345ad6..e27ebb9bb74a 100644
--- a/sound/pci/emu10k1/p16v.c
+++ b/sound/pci/emu10k1/p16v.c
@@ -546,7 +546,7 @@ snd_p16v_pcm_pointer_capture(snd_pcm_substream_t *substream)
ptr=ptr2;
if (ptr >= runtime->buffer_size) {
ptr -= runtime->buffer_size;
- printk("buffer capture limited!\n");
+ printk(KERN_WARNING "buffer capture limited!\n");
}
//printk("ptr1 = 0x%lx, ptr2=0x%lx, ptr=0x%lx, buffer_size = 0x%x, period_size = 0x%x, bits=%d, rate=%d\n", ptr1, ptr2, ptr, (int)runtime->buffer_size, (int)runtime->period_size, (int)runtime->frame_bits, (int)runtime->rate);
diff --git a/sound/pci/ens1370.c b/sound/pci/ens1370.c
index bef9a59f46d7..2daa575f43ff 100644
--- a/sound/pci/ens1370.c
+++ b/sound/pci/ens1370.c
@@ -508,7 +508,7 @@ static unsigned int snd_es1371_wait_src_ready(ensoniq_t * ensoniq)
return r;
cond_resched();
}
- snd_printk("wait source ready timeout 0x%lx [0x%x]\n", ES_REG(ensoniq, 1371_SMPRATE), r);
+ snd_printk(KERN_ERR "wait source ready timeout 0x%lx [0x%x]\n", ES_REG(ensoniq, 1371_SMPRATE), r);
return 0;
}
@@ -576,10 +576,9 @@ static void snd_es1370_codec_write(ak4531_t *ak4531,
outw(ES_1370_CODEC_WRITE(reg, val), ES_REG(ensoniq, 1370_CODEC));
return;
}
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(1);
+ schedule_timeout_uninterruptible(1);
} while (time_after(end_time, jiffies));
- snd_printk("codec write timeout, status = 0x%x\n", inl(ES_REG(ensoniq, STATUS)));
+ snd_printk(KERN_ERR "codec write timeout, status = 0x%x\n", inl(ES_REG(ensoniq, STATUS)));
}
#endif /* CHIP1370 */
@@ -620,7 +619,7 @@ static void snd_es1371_codec_write(ac97_t *ac97,
}
}
up(&ensoniq->src_mutex);
- snd_printk("codec write timeout at 0x%lx [0x%x]\n", ES_REG(ensoniq, 1371_CODEC), inl(ES_REG(ensoniq, 1371_CODEC)));
+ snd_printk(KERN_ERR "codec write timeout at 0x%lx [0x%x]\n", ES_REG(ensoniq, 1371_CODEC), inl(ES_REG(ensoniq, 1371_CODEC)));
}
static unsigned short snd_es1371_codec_read(ac97_t *ac97,
@@ -667,14 +666,14 @@ static unsigned short snd_es1371_codec_read(ac97_t *ac97,
}
up(&ensoniq->src_mutex);
if (++fail > 10) {
- snd_printk("codec read timeout (final) at 0x%lx, reg = 0x%x [0x%x]\n", ES_REG(ensoniq, 1371_CODEC), reg, inl(ES_REG(ensoniq, 1371_CODEC)));
+ snd_printk(KERN_ERR "codec read timeout (final) at 0x%lx, reg = 0x%x [0x%x]\n", ES_REG(ensoniq, 1371_CODEC), reg, inl(ES_REG(ensoniq, 1371_CODEC)));
return 0;
}
goto __again;
}
}
up(&ensoniq->src_mutex);
- snd_printk("es1371: codec read timeout at 0x%lx [0x%x]\n", ES_REG(ensoniq, 1371_CODEC), inl(ES_REG(ensoniq, 1371_CODEC)));
+ snd_printk(KERN_ERR "es1371: codec read timeout at 0x%lx [0x%x]\n", ES_REG(ensoniq, 1371_CODEC), inl(ES_REG(ensoniq, 1371_CODEC)));
return 0;
}
@@ -1960,7 +1959,7 @@ static int __devinit snd_ensoniq_create(snd_card_t * card,
}
ensoniq->port = pci_resource_start(pci, 0);
if (request_irq(pci->irq, snd_audiopci_interrupt, SA_INTERRUPT|SA_SHIRQ, "Ensoniq AudioPCI", (void *)ensoniq)) {
- snd_printk("unable to grab IRQ %d\n", pci->irq);
+ snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
snd_ensoniq_free(ensoniq);
return -EBUSY;
}
@@ -1968,7 +1967,7 @@ static int __devinit snd_ensoniq_create(snd_card_t * card,
#ifdef CHIP1370
if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci),
16, &ensoniq->dma_bug) < 0) {
- snd_printk("unable to allocate space for phantom area - dma_bug\n");
+ snd_printk(KERN_ERR "unable to allocate space for phantom area - dma_bug\n");
snd_ensoniq_free(ensoniq);
return -EBUSY;
}
@@ -2387,7 +2386,6 @@ static void __devexit snd_audiopci_remove(struct pci_dev *pci)
static struct pci_driver driver = {
.name = DRIVER_NAME,
- .owner = THIS_MODULE,
.id_table = snd_audiopci_ids,
.probe = snd_audiopci_probe,
.remove = __devexit_p(snd_audiopci_remove),
diff --git a/sound/pci/es1938.c b/sound/pci/es1938.c
index 17fa80c23870..c134f48152b0 100644
--- a/sound/pci/es1938.c
+++ b/sound/pci/es1938.c
@@ -267,7 +267,7 @@ static void snd_es1938_mixer_write(es1938_t *chip, unsigned char reg, unsigned c
outb(val, SLSB_REG(chip, MIXERDATA));
spin_unlock_irqrestore(&chip->mixer_lock, flags);
#ifdef REG_DEBUG
- snd_printk("Mixer reg %02x set to %02x\n", reg, val);
+ snd_printk(KERN_DEBUG "Mixer reg %02x set to %02x\n", reg, val);
#endif
}
@@ -283,7 +283,7 @@ static int snd_es1938_mixer_read(es1938_t *chip, unsigned char reg)
data = inb(SLSB_REG(chip, MIXERDATA));
spin_unlock_irqrestore(&chip->mixer_lock, flags);
#ifdef REG_DEBUG
- snd_printk("Mixer reg %02x now is %02x\n", reg, data);
+ snd_printk(KERN_DEBUG "Mixer reg %02x now is %02x\n", reg, data);
#endif
return data;
}
@@ -303,7 +303,8 @@ static int snd_es1938_mixer_bits(es1938_t *chip, unsigned char reg, unsigned cha
new = (old & ~mask) | (val & mask);
outb(new, SLSB_REG(chip, MIXERDATA));
#ifdef REG_DEBUG
- snd_printk("Mixer reg %02x was %02x, set to %02x\n", reg, old, new);
+ snd_printk(KERN_DEBUG "Mixer reg %02x was %02x, set to %02x\n",
+ reg, old, new);
#endif
}
spin_unlock_irqrestore(&chip->mixer_lock, flags);
@@ -323,7 +324,7 @@ static void snd_es1938_write_cmd(es1938_t *chip, unsigned char cmd)
return;
}
}
- printk("snd_es1938_write_cmd timeout (0x02%x/0x02%x)\n", cmd, v);
+ printk(KERN_ERR "snd_es1938_write_cmd timeout (0x02%x/0x02%x)\n", cmd, v);
}
/* -----------------------------------------------------------------
@@ -336,7 +337,7 @@ static int snd_es1938_get_byte(es1938_t *chip)
for (i = GET_LOOP_TIMEOUT; i; i--)
if ((v = inb(SLSB_REG(chip, STATUS))) & 0x80)
return inb(SLSB_REG(chip, READDATA));
- snd_printk("get_byte timeout: status 0x02%x\n", v);
+ snd_printk(KERN_ERR "get_byte timeout: status 0x02%x\n", v);
return -ENODEV;
}
@@ -351,7 +352,7 @@ static void snd_es1938_write(es1938_t *chip, unsigned char reg, unsigned char va
snd_es1938_write_cmd(chip, val);
spin_unlock_irqrestore(&chip->reg_lock, flags);
#ifdef REG_DEBUG
- snd_printk("Reg %02x set to %02x\n", reg, val);
+ snd_printk(KERN_DEBUG "Reg %02x set to %02x\n", reg, val);
#endif
}
@@ -368,7 +369,7 @@ static unsigned char snd_es1938_read(es1938_t *chip, unsigned char reg)
val = snd_es1938_get_byte(chip);
spin_unlock_irqrestore(&chip->reg_lock, flags);
#ifdef REG_DEBUG
- snd_printk("Reg %02x now is %02x\n", reg, val);
+ snd_printk(KERN_DEBUG "Reg %02x now is %02x\n", reg, val);
#endif
return val;
}
@@ -390,7 +391,8 @@ static int snd_es1938_bits(es1938_t *chip, unsigned char reg, unsigned char mask
new = (old & ~mask) | (val & mask);
snd_es1938_write_cmd(chip, new);
#ifdef REG_DEBUG
- snd_printk("Reg %02x was %02x, set to %02x\n", reg, old, new);
+ snd_printk(KERN_DEBUG "Reg %02x was %02x, set to %02x\n",
+ reg, old, new);
#endif
}
spin_unlock_irqrestore(&chip->reg_lock, flags);
@@ -413,7 +415,7 @@ static void snd_es1938_reset(es1938_t *chip)
goto __next;
}
}
- snd_printk("ESS Solo-1 reset failed\n");
+ snd_printk(KERN_ERR "ESS Solo-1 reset failed\n");
__next:
snd_es1938_write_cmd(chip, ESS_CMD_ENABLEEXT);
@@ -543,10 +545,12 @@ static int snd_es1938_capture_trigger(snd_pcm_substream_t * substream,
int val;
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
+ case SNDRV_PCM_TRIGGER_RESUME:
val = 0x0f;
chip->active |= ADC1;
break;
case SNDRV_PCM_TRIGGER_STOP:
+ case SNDRV_PCM_TRIGGER_SUSPEND:
val = 0x00;
chip->active &= ~ADC1;
break;
@@ -563,6 +567,7 @@ static int snd_es1938_playback1_trigger(snd_pcm_substream_t * substream,
es1938_t *chip = snd_pcm_substream_chip(substream);
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
+ case SNDRV_PCM_TRIGGER_RESUME:
/* According to the documentation this should be:
0x13 but that value may randomly swap stereo channels */
snd_es1938_mixer_write(chip, ESSSB_IREG_AUDIO2CONTROL1, 0x92);
@@ -575,6 +580,7 @@ static int snd_es1938_playback1_trigger(snd_pcm_substream_t * substream,
chip->active |= DAC2;
break;
case SNDRV_PCM_TRIGGER_STOP:
+ case SNDRV_PCM_TRIGGER_SUSPEND:
outb(0, SLIO_REG(chip, AUDIO2MODE));
snd_es1938_mixer_write(chip, ESSSB_IREG_AUDIO2CONTROL1, 0);
chip->active &= ~DAC2;
@@ -592,10 +598,12 @@ static int snd_es1938_playback2_trigger(snd_pcm_substream_t * substream,
int val;
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
+ case SNDRV_PCM_TRIGGER_RESUME:
val = 5;
chip->active |= DAC1;
break;
case SNDRV_PCM_TRIGGER_STOP:
+ case SNDRV_PCM_TRIGGER_SUSPEND:
val = 0;
chip->active &= ~DAC1;
break;
@@ -1390,7 +1398,8 @@ static int es1938_suspend(snd_card_t *card, pm_message_t state)
*d = snd_es1938_reg_read(chip, *s);
outb(0x00, SLIO_REG(chip, IRQCONTROL)); /* disable irqs */
-
+ if (chip->irq >= 0)
+ free_irq(chip->irq, (void *)chip);
pci_disable_device(chip->pci);
return 0;
}
@@ -1401,6 +1410,9 @@ static int es1938_resume(snd_card_t *card)
unsigned char *s, *d;
pci_enable_device(chip->pci);
+ request_irq(chip->pci->irq, snd_es1938_interrupt,
+ SA_INTERRUPT|SA_SHIRQ, "ES1938", (void *)chip);
+ chip->irq = chip->pci->irq;
snd_es1938_chip_init(chip);
/* restore mixer-related registers */
@@ -1489,7 +1501,7 @@ static int __devinit snd_es1938_create(snd_card_t * card,
/* check, if we can restrict PCI DMA transfers to 24 bits */
if (pci_set_dma_mask(pci, 0x00ffffff) < 0 ||
pci_set_consistent_dma_mask(pci, 0x00ffffff) < 0) {
- snd_printk("architecture does not support 24bit PCI busmaster DMA\n");
+ snd_printk(KERN_ERR "architecture does not support 24bit PCI busmaster DMA\n");
pci_disable_device(pci);
return -ENXIO;
}
@@ -1514,13 +1526,13 @@ static int __devinit snd_es1938_create(snd_card_t * card,
chip->mpu_port = pci_resource_start(pci, 3);
chip->game_port = pci_resource_start(pci, 4);
if (request_irq(pci->irq, snd_es1938_interrupt, SA_INTERRUPT|SA_SHIRQ, "ES1938", (void *)chip)) {
- snd_printk("unable to grab IRQ %d\n", pci->irq);
+ snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
snd_es1938_free(chip);
return -EBUSY;
}
chip->irq = pci->irq;
#ifdef ES1938_DDEBUG
- snd_printk("create: io: 0x%lx, sb: 0x%lx, vc: 0x%lx, mpu: 0x%lx, game: 0x%lx\n",
+ snd_printk(KERN_DEBUG "create: io: 0x%lx, sb: 0x%lx, vc: 0x%lx, mpu: 0x%lx, game: 0x%lx\n",
chip->io_port, chip->sb_port, chip->vc_port, chip->mpu_port, chip->game_port);
#endif
@@ -1746,7 +1758,6 @@ static void __devexit snd_es1938_remove(struct pci_dev *pci)
static struct pci_driver driver = {
.name = "ESS ES1938 (Solo-1)",
- .owner = THIS_MODULE,
.id_table = snd_es1938_ids,
.probe = snd_es1938_probe,
.remove = __devexit_p(snd_es1938_remove),
diff --git a/sound/pci/es1968.c b/sound/pci/es1968.c
index ecdcada90ca2..50079dc90743 100644
--- a/sound/pci/es1968.c
+++ b/sound/pci/es1968.c
@@ -1462,13 +1462,13 @@ snd_es1968_init_dmabuf(es1968_t *chip)
snd_dma_pci_data(chip->pci),
chip->total_bufsize, &chip->dma);
if (err < 0 || ! chip->dma.area) {
- snd_printk("es1968: can't allocate dma pages for size %d\n",
+ snd_printk(KERN_ERR "es1968: can't allocate dma pages for size %d\n",
chip->total_bufsize);
return -ENOMEM;
}
if ((chip->dma.addr + chip->dma.bytes - 1) & ~((1 << 28) - 1)) {
snd_dma_free_pages(&chip->dma);
- snd_printk("es1968: DMA buffer beyond 256MB.\n");
+ snd_printk(KERN_ERR "es1968: DMA buffer beyond 256MB.\n");
return -ENOMEM;
}
}
@@ -1741,11 +1741,11 @@ static void __devinit es1968_measure_clock(es1968_t *chip)
/* search 2 APUs (although one apu is enough) */
if ((apu = snd_es1968_alloc_apu_pair(chip, ESM_APU_PCM_PLAY)) < 0) {
- snd_printk("Hmm, cannot find empty APU pair!?\n");
+ snd_printk(KERN_ERR "Hmm, cannot find empty APU pair!?\n");
return;
}
if ((memory = snd_es1968_new_memory(chip, CLOCK_MEASURE_BUFSIZE)) == NULL) {
- snd_printk("cannot allocate dma buffer - using default clock %d\n", chip->clock);
+ snd_printk(KERN_ERR "cannot allocate dma buffer - using default clock %d\n", chip->clock);
snd_es1968_free_apu_pair(chip, apu);
return;
}
@@ -1806,7 +1806,7 @@ static void __devinit es1968_measure_clock(es1968_t *chip)
else
t += stop_time.tv_usec - start_time.tv_usec;
if (t == 0) {
- snd_printk("?? calculation error..\n");
+ snd_printk(KERN_ERR "?? calculation error..\n");
} else {
offset *= 1000;
offset = (offset / t) * 1000 + ((offset % t) * 1000) / t;
@@ -2090,7 +2090,7 @@ static void snd_es1968_ac97_reset(es1968_t *chip)
outw(inw(ioaddr + 0x3c) & 0xfffc, ioaddr + 0x3c);
#if 0 /* the loop here needs to be much better if we want it.. */
- snd_printk("trying software reset\n");
+ snd_printk(KERN_INFO "trying software reset\n");
/* try and do a software reset */
outb(0x80 | 0x7c, ioaddr + 0x30);
for (w = 0;; w++) {
@@ -2461,8 +2461,7 @@ static int __devinit snd_es1968_create_gameport(es1968_t *chip, int dev)
chip->gameport = gp = gameport_allocate_port();
if (!gp) {
printk(KERN_ERR "es1968: cannot allocate memory for gameport\n");
- release_resource(r);
- kfree_nocheck(r);
+ release_and_free_resource(r);
return -ENOMEM;
}
@@ -2488,8 +2487,7 @@ static void snd_es1968_free_gameport(es1968_t *chip)
gameport_unregister_port(chip->gameport);
chip->gameport = NULL;
- release_resource(r);
- kfree_nocheck(r);
+ release_and_free_resource(r);
}
}
#else
@@ -2564,7 +2562,7 @@ static int __devinit snd_es1968_create(snd_card_t * card,
/* check, if we can restrict PCI DMA transfers to 28 bits */
if (pci_set_dma_mask(pci, 0x0fffffff) < 0 ||
pci_set_consistent_dma_mask(pci, 0x0fffffff) < 0) {
- snd_printk("architecture does not support 28bit PCI busmaster DMA\n");
+ snd_printk(KERN_ERR "architecture does not support 28bit PCI busmaster DMA\n");
pci_disable_device(pci);
return -ENXIO;
}
@@ -2599,7 +2597,7 @@ static int __devinit snd_es1968_create(snd_card_t * card,
chip->io_port = pci_resource_start(pci, 0);
if (request_irq(pci->irq, snd_es1968_interrupt, SA_INTERRUPT|SA_SHIRQ,
"ESS Maestro", (void*)chip)) {
- snd_printk("unable to grab IRQ %d\n", pci->irq);
+ snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
snd_es1968_free(chip);
return -EBUSY;
}
@@ -2763,7 +2761,6 @@ static void __devexit snd_es1968_remove(struct pci_dev *pci)
static struct pci_driver driver = {
.name = "ES1968 (ESS Maestro)",
- .owner = THIS_MODULE,
.id_table = snd_es1968_ids,
.probe = snd_es1968_probe,
.remove = __devexit_p(snd_es1968_remove),
diff --git a/sound/pci/fm801.c b/sound/pci/fm801.c
index e5cfa2a0c246..4e1d3434888d 100644
--- a/sound/pci/fm801.c
+++ b/sound/pci/fm801.c
@@ -237,7 +237,7 @@ static void snd_fm801_codec_write(ac97_t *ac97,
goto ok1;
udelay(10);
}
- snd_printk("AC'97 interface is busy (1)\n");
+ snd_printk(KERN_ERR "AC'97 interface is busy (1)\n");
return;
ok1:
@@ -252,7 +252,7 @@ static void snd_fm801_codec_write(ac97_t *ac97,
return;
udelay(10);
}
- snd_printk("AC'97 interface #%d is busy (2)\n", ac97->num);
+ snd_printk(KERN_ERR "AC'97 interface #%d is busy (2)\n", ac97->num);
}
static unsigned short snd_fm801_codec_read(ac97_t *ac97, unsigned short reg)
@@ -268,7 +268,7 @@ static unsigned short snd_fm801_codec_read(ac97_t *ac97, unsigned short reg)
goto ok1;
udelay(10);
}
- snd_printk("AC'97 interface is busy (1)\n");
+ snd_printk(KERN_ERR "AC'97 interface is busy (1)\n");
return 0;
ok1:
@@ -279,7 +279,7 @@ static unsigned short snd_fm801_codec_read(ac97_t *ac97, unsigned short reg)
goto ok2;
udelay(10);
}
- snd_printk("AC'97 interface #%d is busy (2)\n", ac97->num);
+ snd_printk(KERN_ERR "AC'97 interface #%d is busy (2)\n", ac97->num);
return 0;
ok2:
@@ -288,7 +288,7 @@ static unsigned short snd_fm801_codec_read(ac97_t *ac97, unsigned short reg)
goto ok3;
udelay(10);
}
- snd_printk("AC'97 interface #%d is not valid (2)\n", ac97->num);
+ snd_printk(KERN_ERR "AC'97 interface #%d is not valid (2)\n", ac97->num);
return 0;
ok3:
@@ -1279,7 +1279,7 @@ static int __devinit snd_fm801_create(snd_card_t * card,
}
chip->port = pci_resource_start(pci, 0);
if (request_irq(pci->irq, snd_fm801_interrupt, SA_INTERRUPT|SA_SHIRQ, "FM801", (void *)chip)) {
- snd_printk("unable to grab IRQ %d\n", chip->irq);
+ snd_printk(KERN_ERR "unable to grab IRQ %d\n", chip->irq);
snd_fm801_free(chip);
return -EBUSY;
}
@@ -1303,10 +1303,9 @@ static int __devinit snd_fm801_create(snd_card_t * card,
do {
if ((inw(FM801_REG(chip, AC97_CMD)) & (3<<8)) == (1<<8))
goto __ac97_secondary;
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(1);
+ schedule_timeout_uninterruptible(1);
} while (time_after(timeout, jiffies));
- snd_printk("Primary AC'97 codec not found\n");
+ snd_printk(KERN_ERR "Primary AC'97 codec not found\n");
snd_fm801_free(chip);
return -EIO;
@@ -1329,8 +1328,7 @@ static int __devinit snd_fm801_create(snd_card_t * card,
goto __ac97_ok;
}
}
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(1);
+ schedule_timeout_uninterruptible(1);
} while (time_after(timeout, jiffies));
}
@@ -1343,10 +1341,9 @@ static int __devinit snd_fm801_create(snd_card_t * card,
do {
if ((inw(FM801_REG(chip, AC97_CMD)) & (3<<8)) == (1<<8))
goto __ac97_ok;
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(1);
+ schedule_timeout_uninterruptible(1);
} while (time_after(timeout, jiffies));
- snd_printk("Primary AC'97 codec not responding\n");
+ snd_printk(KERN_ERR "Primary AC'97 codec not responding\n");
snd_fm801_free(chip);
return -EIO;
@@ -1462,7 +1459,6 @@ static void __devexit snd_card_fm801_remove(struct pci_dev *pci)
static struct pci_driver driver = {
.name = "FM801",
- .owner = THIS_MODULE,
.id_table = snd_fm801_ids,
.probe = snd_card_fm801_probe,
.remove = __devexit_p(snd_card_fm801_remove),
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index 3815403ed095..0dbeeaf6113a 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -518,6 +518,13 @@ int snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr,
return -ENODEV;
}
+ if (! codec->subsystem_id) {
+ hda_nid_t nid = codec->afg ? codec->afg : codec->mfg;
+ codec->subsystem_id = snd_hda_codec_read(codec, nid, 0,
+ AC_VERB_GET_SUBSYSTEM_ID,
+ 0);
+ }
+
codec->preset = find_codec_preset(codec);
if (! *bus->card->mixername)
snd_hda_get_codec_name(codec, bus->card->mixername,
@@ -814,6 +821,51 @@ int snd_hda_mixer_amp_switch_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t
}
/*
+ * bound volume controls
+ *
+ * bind multiple volumes (# indices, from 0)
+ */
+
+#define AMP_VAL_IDX_SHIFT 19
+#define AMP_VAL_IDX_MASK (0x0f<<19)
+
+int snd_hda_mixer_bind_switch_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+{
+ struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+ unsigned long pval;
+ int err;
+
+ down(&codec->spdif_mutex); /* reuse spdif_mutex */
+ pval = kcontrol->private_value;
+ kcontrol->private_value = pval & ~AMP_VAL_IDX_MASK; /* index 0 */
+ err = snd_hda_mixer_amp_switch_get(kcontrol, ucontrol);
+ kcontrol->private_value = pval;
+ up(&codec->spdif_mutex);
+ return err;
+}
+
+int snd_hda_mixer_bind_switch_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+{
+ struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+ unsigned long pval;
+ int i, indices, err = 0, change = 0;
+
+ down(&codec->spdif_mutex); /* reuse spdif_mutex */
+ pval = kcontrol->private_value;
+ indices = (pval & AMP_VAL_IDX_MASK) >> AMP_VAL_IDX_SHIFT;
+ for (i = 0; i < indices; i++) {
+ kcontrol->private_value = (pval & ~AMP_VAL_IDX_MASK) | (i << AMP_VAL_IDX_SHIFT);
+ err = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
+ if (err < 0)
+ break;
+ change |= err;
+ }
+ kcontrol->private_value = pval;
+ up(&codec->spdif_mutex);
+ return err < 0 ? err : change;
+}
+
+/*
* SPDIF out controls
*/
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
index bb53bcf76742..1179d6cfa82a 100644
--- a/sound/pci/hda/hda_codec.h
+++ b/sound/pci/hda/hda_codec.h
@@ -79,6 +79,8 @@ enum {
#define AC_VERB_GET_GPIO_MASK 0x0f16
#define AC_VERB_GET_GPIO_DIRECTION 0x0f17
#define AC_VERB_GET_CONFIG_DEFAULT 0x0f1c
+/* f20: AFG/MFG */
+#define AC_VERB_GET_SUBSYSTEM_ID 0x0f20
/*
* SET verbs
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index 6fe696e53ea6..ed525c03c996 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -47,23 +47,24 @@
#include "hda_codec.h"
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
-static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
-static char *model[SNDRV_CARDS];
-static int position_fix[SNDRV_CARDS];
+static int index = SNDRV_DEFAULT_IDX1;
+static char *id = SNDRV_DEFAULT_STR1;
+static char *model;
+static int position_fix;
-module_param_array(index, int, NULL, 0444);
+module_param(index, int, 0444);
MODULE_PARM_DESC(index, "Index value for Intel HD audio interface.");
-module_param_array(id, charp, NULL, 0444);
+module_param(id, charp, 0444);
MODULE_PARM_DESC(id, "ID string for Intel HD audio interface.");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable Intel HD audio interface.");
-module_param_array(model, charp, NULL, 0444);
+module_param(model, charp, 0444);
MODULE_PARM_DESC(model, "Use the given board model.");
-module_param_array(position_fix, int, NULL, 0444);
+module_param(position_fix, int, 0444);
MODULE_PARM_DESC(position_fix, "Fix DMA pointer (0 = auto, 1 = none, 2 = POSBUF, 3 = FIFO size).");
+/* just for backward compatibility */
+static int enable;
+module_param(enable, bool, 0444);
+
MODULE_LICENSE("GPL");
MODULE_SUPPORTED_DEVICE("{{Intel, ICH6},"
"{Intel, ICH6M},"
@@ -223,6 +224,9 @@ enum {
#define ATI_SB450_HDAUDIO_MISC_CNTR2_ADDR 0x42
#define ATI_SB450_HDAUDIO_ENABLE_SNOOP 0x02
+/* Defines for Nvidia HDA support */
+#define NVIDIA_HDA_TRANSREG_ADDR 0x4e
+#define NVIDIA_HDA_ENABLE_COHBITS 0x0f
/*
* Use CORB/RIRB for communication from/to codecs.
@@ -328,6 +332,7 @@ enum {
AZX_DRIVER_VIA,
AZX_DRIVER_SIS,
AZX_DRIVER_ULI,
+ AZX_DRIVER_NVIDIA,
};
static char *driver_short_names[] __devinitdata = {
@@ -335,7 +340,8 @@ static char *driver_short_names[] __devinitdata = {
[AZX_DRIVER_ATI] = "HDA ATI SB",
[AZX_DRIVER_VIA] = "HDA VIA VT82xx",
[AZX_DRIVER_SIS] = "HDA SIS966",
- [AZX_DRIVER_ULI] = "HDA ULI M5461"
+ [AZX_DRIVER_ULI] = "HDA ULI M5461",
+ [AZX_DRIVER_NVIDIA] = "HDA NVidia",
};
/*
@@ -710,14 +716,14 @@ static void azx_stream_stop(azx_t *chip, azx_dev_t *azx_dev)
*/
static void azx_init_chip(azx_t *chip)
{
- unsigned char tcsel_reg, ati_misc_cntl2;
+ unsigned char reg;
/* Clear bits 0-2 of PCI register TCSEL (at offset 0x44)
* TCSEL == Traffic Class Select Register, which sets PCI express QOS
* Ensuring these bits are 0 clears playback static on some HD Audio codecs
*/
- pci_read_config_byte (chip->pci, ICH6_PCIREG_TCSEL, &tcsel_reg);
- pci_write_config_byte(chip->pci, ICH6_PCIREG_TCSEL, tcsel_reg & 0xf8);
+ pci_read_config_byte (chip->pci, ICH6_PCIREG_TCSEL, &reg);
+ pci_write_config_byte(chip->pci, ICH6_PCIREG_TCSEL, reg & 0xf8);
/* reset controller */
azx_reset(chip);
@@ -733,13 +739,21 @@ static void azx_init_chip(azx_t *chip)
azx_writel(chip, DPLBASE, (u32)chip->posbuf.addr);
azx_writel(chip, DPUBASE, upper_32bit(chip->posbuf.addr));
- /* For ATI SB450 azalia HD audio, we need to enable snoop */
- if (chip->driver_type == AZX_DRIVER_ATI) {
+ switch (chip->driver_type) {
+ case AZX_DRIVER_ATI:
+ /* For ATI SB450 azalia HD audio, we need to enable snoop */
pci_read_config_byte(chip->pci, ATI_SB450_HDAUDIO_MISC_CNTR2_ADDR,
- &ati_misc_cntl2);
+ &reg);
pci_write_config_byte(chip->pci, ATI_SB450_HDAUDIO_MISC_CNTR2_ADDR,
- (ati_misc_cntl2 & 0xf8) | ATI_SB450_HDAUDIO_ENABLE_SNOOP);
- }
+ (reg & 0xf8) | ATI_SB450_HDAUDIO_ENABLE_SNOOP);
+ break;
+ case AZX_DRIVER_NVIDIA:
+ /* For NVIDIA HDA, enable snoop */
+ pci_read_config_byte(chip->pci,NVIDIA_HDA_TRANSREG_ADDR, &reg);
+ pci_write_config_byte(chip->pci,NVIDIA_HDA_TRANSREG_ADDR,
+ (reg & 0xf0) | NVIDIA_HDA_ENABLE_COHBITS);
+ break;
+ }
}
@@ -1264,6 +1278,7 @@ static int __devinit azx_pcm_create(azx_t *chip)
err = create_codec_pcm(chip, codec, &codec->pcm_info[c], pcm_dev);
if (err < 0)
return err;
+ chip->pcm[pcm_dev]->dev_class = SNDRV_PCM_CLASS_MODEM;
pcm_dev++;
}
}
@@ -1530,32 +1545,24 @@ static int __devinit azx_create(snd_card_t *card, struct pci_dev *pci,
static int __devinit azx_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
{
- static int dev;
snd_card_t *card;
azx_t *chip;
int err = 0;
- if (dev >= SNDRV_CARDS)
- return -ENODEV;
- if (! enable[dev]) {
- dev++;
- return -ENOENT;
- }
-
- card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
+ card = snd_card_new(index, id, THIS_MODULE, 0);
if (NULL == card) {
snd_printk(KERN_ERR SFX "Error creating card!\n");
return -ENOMEM;
}
- if ((err = azx_create(card, pci, position_fix[dev], pci_id->driver_data,
+ if ((err = azx_create(card, pci, position_fix, pci_id->driver_data,
&chip)) < 0) {
snd_card_free(card);
return err;
}
/* create codec instances */
- if ((err = azx_codec_create(chip, model[dev])) < 0) {
+ if ((err = azx_codec_create(chip, model)) < 0) {
snd_card_free(card);
return err;
}
@@ -1581,7 +1588,6 @@ static int __devinit azx_probe(struct pci_dev *pci, const struct pci_device_id *
}
pci_set_drvdata(pci, card);
- dev++;
return err;
}
@@ -1601,6 +1607,8 @@ static struct pci_device_id azx_ids[] = {
{ 0x1106, 0x3288, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_VIA }, /* VIA VT8251/VT8237A */
{ 0x1039, 0x7502, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_SIS }, /* SIS966 */
{ 0x10b9, 0x5461, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ULI }, /* ULI M5461 */
+ { 0x10de, 0x026c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_NVIDIA }, /* NVIDIA 026c */
+ { 0x10de, 0x0371, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_NVIDIA }, /* NVIDIA 0371 */
{ 0, }
};
MODULE_DEVICE_TABLE(pci, azx_ids);
@@ -1608,7 +1616,6 @@ MODULE_DEVICE_TABLE(pci, azx_ids);
/* pci_driver definition */
static struct pci_driver driver = {
.name = "HDA Intel",
- .owner = THIS_MODULE,
.id_table = azx_ids,
.probe = azx_probe,
.remove = __devexit_p(azx_remove),
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h
index 810cfd2d9bba..f51a56f813c8 100644
--- a/sound/pci/hda/hda_local.h
+++ b/sound/pci/hda/hda_local.h
@@ -27,28 +27,36 @@
* for mixer controls
*/
#define HDA_COMPOSE_AMP_VAL(nid,chs,idx,dir) ((nid) | ((chs)<<16) | ((dir)<<18) | ((idx)<<19))
+/* mono volume with index (index=0,1,...) (channel=1,2) */
#define HDA_CODEC_VOLUME_MONO_IDX(xname, xcidx, nid, channel, xindex, direction) \
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xcidx, \
.info = snd_hda_mixer_amp_volume_info, \
.get = snd_hda_mixer_amp_volume_get, \
.put = snd_hda_mixer_amp_volume_put, \
.private_value = HDA_COMPOSE_AMP_VAL(nid, channel, xindex, direction) }
+/* stereo volume with index */
#define HDA_CODEC_VOLUME_IDX(xname, xcidx, nid, xindex, direction) \
HDA_CODEC_VOLUME_MONO_IDX(xname, xcidx, nid, 3, xindex, direction)
+/* mono volume */
#define HDA_CODEC_VOLUME_MONO(xname, nid, channel, xindex, direction) \
HDA_CODEC_VOLUME_MONO_IDX(xname, 0, nid, channel, xindex, direction)
+/* stereo volume */
#define HDA_CODEC_VOLUME(xname, nid, xindex, direction) \
HDA_CODEC_VOLUME_MONO(xname, nid, 3, xindex, direction)
+/* mono mute switch with index (index=0,1,...) (channel=1,2) */
#define HDA_CODEC_MUTE_MONO_IDX(xname, xcidx, nid, channel, xindex, direction) \
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xcidx, \
.info = snd_hda_mixer_amp_switch_info, \
.get = snd_hda_mixer_amp_switch_get, \
.put = snd_hda_mixer_amp_switch_put, \
.private_value = HDA_COMPOSE_AMP_VAL(nid, channel, xindex, direction) }
+/* stereo mute switch with index */
#define HDA_CODEC_MUTE_IDX(xname, xcidx, nid, xindex, direction) \
HDA_CODEC_MUTE_MONO_IDX(xname, xcidx, nid, 3, xindex, direction)
+/* mono mute switch */
#define HDA_CODEC_MUTE_MONO(xname, nid, channel, xindex, direction) \
HDA_CODEC_MUTE_MONO_IDX(xname, 0, nid, channel, xindex, direction)
+/* stereo mute switch */
#define HDA_CODEC_MUTE(xname, nid, xindex, direction) \
HDA_CODEC_MUTE_MONO(xname, nid, 3, xindex, direction)
@@ -59,6 +67,20 @@ int snd_hda_mixer_amp_switch_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t
int snd_hda_mixer_amp_switch_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol);
int snd_hda_mixer_amp_switch_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol);
+/* mono switch binding multiple inputs */
+#define HDA_BIND_MUTE_MONO(xname, nid, channel, indices, direction) \
+ { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
+ .info = snd_hda_mixer_amp_switch_info, \
+ .get = snd_hda_mixer_bind_switch_get, \
+ .put = snd_hda_mixer_bind_switch_put, \
+ .private_value = HDA_COMPOSE_AMP_VAL(nid, channel, indices, direction) }
+
+/* stereo switch binding multiple inputs */
+#define HDA_BIND_MUTE(xname,nid,indices,dir) HDA_BIND_MUTE_MONO(xname,nid,3,indices,dir)
+
+int snd_hda_mixer_bind_switch_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol);
+int snd_hda_mixer_bind_switch_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol);
+
int snd_hda_create_spdif_out_ctls(struct hda_codec *codec, hda_nid_t nid);
int snd_hda_create_spdif_in_ctls(struct hda_codec *codec, hda_nid_t nid);
diff --git a/sound/pci/hda/hda_proc.c b/sound/pci/hda/hda_proc.c
index 08f6a6efc5e6..39ddf1cd9019 100644
--- a/sound/pci/hda/hda_proc.c
+++ b/sound/pci/hda/hda_proc.c
@@ -281,6 +281,11 @@ static void print_codec_info(snd_info_entry_t *entry, snd_info_buffer_t *buffer)
print_pcm_caps(buffer, codec, nid);
}
+ if (wid_caps & AC_WCAP_POWER)
+ snd_iprintf(buffer, " Power: 0x%x\n",
+ snd_hda_codec_read(codec, nid, 0,
+ AC_VERB_GET_POWER_STATE, 0));
+
if (wid_caps & AC_WCAP_CONN_LIST) {
int c, curr = -1;
if (conn_len > 1 && wid_type != AC_WID_AUD_MIX)
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c
index da6874d3988c..d7d636decef8 100644
--- a/sound/pci/hda/patch_analog.c
+++ b/sound/pci/hda/patch_analog.c
@@ -28,15 +28,38 @@
#include "hda_local.h"
struct ad198x_spec {
- struct semaphore amp_mutex; /* PCM volume/mute control mutex */
- struct hda_multi_out multiout; /* playback */
- hda_nid_t adc_nid;
+ snd_kcontrol_new_t *mixers[5];
+ int num_mixers;
+
+ const struct hda_verb *init_verbs[3]; /* initialization verbs
+ * don't forget NULL termination!
+ */
+ unsigned int num_init_verbs;
+
+ /* playback */
+ struct hda_multi_out multiout; /* playback set-up
+ * max_channels, dacs must be set
+ * dig_out_nid and hp_nid are optional
+ */
+
+ /* capture */
+ unsigned int num_adc_nids;
+ hda_nid_t *adc_nids;
+ hda_nid_t dig_in_nid; /* digital-in NID; optional */
+
+ /* capture source */
const struct hda_input_mux *input_mux;
- unsigned int cur_mux; /* capture source */
+ unsigned int cur_mux[3];
+
+ /* channel model */
+ const struct alc_channel_mode *channel_mode;
+ int num_channel_mode;
+
+ /* PCM information */
+ struct hda_pcm pcm_rec[2]; /* used in alc_build_pcms() */
+
+ struct semaphore amp_mutex; /* PCM volume/mute control mutex */
unsigned int spdif_route;
- snd_kcontrol_new_t *mixers;
- const struct hda_verb *init_verbs;
- struct hda_pcm pcm_rec[2]; /* PCM information */
};
/*
@@ -54,8 +77,9 @@ static int ad198x_mux_enum_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *u
{
struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
struct ad198x_spec *spec = codec->spec;
+ unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
- ucontrol->value.enumerated.item[0] = spec->cur_mux;
+ ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
return 0;
}
@@ -63,9 +87,10 @@ static int ad198x_mux_enum_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *u
{
struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
struct ad198x_spec *spec = codec->spec;
+ unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,
- spec->adc_nid, &spec->cur_mux);
+ spec->adc_nids[adc_idx], &spec->cur_mux[adc_idx]);
}
/*
@@ -74,22 +99,34 @@ static int ad198x_mux_enum_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *u
static int ad198x_init(struct hda_codec *codec)
{
struct ad198x_spec *spec = codec->spec;
- snd_hda_sequence_write(codec, spec->init_verbs);
+ int i;
+
+ for (i = 0; i < spec->num_init_verbs; i++)
+ snd_hda_sequence_write(codec, spec->init_verbs[i]);
return 0;
}
static int ad198x_build_controls(struct hda_codec *codec)
{
struct ad198x_spec *spec = codec->spec;
+ unsigned int i;
int err;
- err = snd_hda_add_new_ctls(codec, spec->mixers);
- if (err < 0)
- return err;
- if (spec->multiout.dig_out_nid)
+ for (i = 0; i < spec->num_mixers; i++) {
+ err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
+ if (err < 0)
+ return err;
+ }
+ if (spec->multiout.dig_out_nid) {
err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid);
- if (err < 0)
- return err;
+ if (err < 0)
+ return err;
+ }
+ if (spec->dig_in_nid) {
+ err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
+ if (err < 0)
+ return err;
+ }
return 0;
}
@@ -152,7 +189,8 @@ static int ad198x_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
snd_pcm_substream_t *substream)
{
struct ad198x_spec *spec = codec->spec;
- snd_hda_codec_setup_stream(codec, spec->adc_nid, stream_tag, 0, format);
+ snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
+ stream_tag, 0, format);
return 0;
}
@@ -161,7 +199,8 @@ static int ad198x_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
snd_pcm_substream_t *substream)
{
struct ad198x_spec *spec = codec->spec;
- snd_hda_codec_setup_stream(codec, spec->adc_nid, 0, 0, 0);
+ snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
+ 0, 0, 0);
return 0;
}
@@ -171,7 +210,7 @@ static int ad198x_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
static struct hda_pcm_stream ad198x_pcm_analog_playback = {
.substreams = 1,
.channels_min = 2,
- .channels_max = 6,
+ .channels_max = 6, /* changed later */
.nid = 0, /* fill later */
.ops = {
.open = ad198x_playback_pcm_open,
@@ -181,7 +220,7 @@ static struct hda_pcm_stream ad198x_pcm_analog_playback = {
};
static struct hda_pcm_stream ad198x_pcm_analog_capture = {
- .substreams = 2,
+ .substreams = 1,
.channels_min = 2,
.channels_max = 2,
.nid = 0, /* fill later */
@@ -202,6 +241,13 @@ static struct hda_pcm_stream ad198x_pcm_digital_playback = {
},
};
+static struct hda_pcm_stream ad198x_pcm_digital_capture = {
+ .substreams = 1,
+ .channels_min = 2,
+ .channels_max = 2,
+ /* NID is set in alc_build_pcms */
+};
+
static int ad198x_build_pcms(struct hda_codec *codec)
{
struct ad198x_spec *spec = codec->spec;
@@ -215,7 +261,8 @@ static int ad198x_build_pcms(struct hda_codec *codec)
info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->multiout.max_channels;
info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
info->stream[SNDRV_PCM_STREAM_CAPTURE] = ad198x_pcm_analog_capture;
- info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nid;
+ info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = spec->num_adc_nids;
+ info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
if (spec->multiout.dig_out_nid) {
info++;
@@ -223,6 +270,10 @@ static int ad198x_build_pcms(struct hda_codec *codec)
info->name = "AD198x Digital";
info->stream[SNDRV_PCM_STREAM_PLAYBACK] = ad198x_pcm_digital_playback;
info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
+ if (spec->dig_in_nid) {
+ info->stream[SNDRV_PCM_STREAM_CAPTURE] = ad198x_pcm_digital_capture;
+ info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
+ }
}
return 0;
@@ -237,10 +288,15 @@ static void ad198x_free(struct hda_codec *codec)
static int ad198x_resume(struct hda_codec *codec)
{
struct ad198x_spec *spec = codec->spec;
+ int i;
ad198x_init(codec);
- snd_hda_resume_ctls(codec, spec->mixers);
- snd_hda_resume_spdif_out(codec);
+ for (i = 0; i < spec->num_mixers; i++)
+ snd_hda_resume_ctls(codec, spec->mixers[i]);
+ if (spec->multiout.dig_out_nid)
+ snd_hda_resume_spdif_out(codec);
+ if (spec->dig_in_nid)
+ snd_hda_resume_spdif_in(codec);
return 0;
}
#endif
@@ -269,6 +325,7 @@ static struct hda_codec_ops ad198x_patch_ops = {
static hda_nid_t ad1986a_dac_nids[3] = {
AD1986A_FRONT_DAC, AD1986A_SURR_DAC, AD1986A_CLFE_DAC
};
+static hda_nid_t ad1986a_adc_nids[1] = { AD1986A_ADC };
static struct hda_input_mux ad1986a_capture_source = {
.num_items = 7,
@@ -476,10 +533,13 @@ static int patch_ad1986a(struct hda_codec *codec)
spec->multiout.num_dacs = ARRAY_SIZE(ad1986a_dac_nids);
spec->multiout.dac_nids = ad1986a_dac_nids;
spec->multiout.dig_out_nid = AD1986A_SPDIF_OUT;
- spec->adc_nid = AD1986A_ADC;
+ spec->num_adc_nids = 1;
+ spec->adc_nids = ad1986a_adc_nids;
spec->input_mux = &ad1986a_capture_source;
- spec->mixers = ad1986a_mixers;
- spec->init_verbs = ad1986a_init_verbs;
+ spec->num_mixers = 1;
+ spec->mixers[0] = ad1986a_mixers;
+ spec->num_init_verbs = 1;
+ spec->init_verbs[0] = ad1986a_init_verbs;
codec->patch_ops = ad198x_patch_ops;
@@ -495,6 +555,7 @@ static int patch_ad1986a(struct hda_codec *codec)
#define AD1983_ADC 0x04
static hda_nid_t ad1983_dac_nids[1] = { AD1983_DAC };
+static hda_nid_t ad1983_adc_nids[1] = { AD1983_ADC };
static struct hda_input_mux ad1983_capture_source = {
.num_items = 4,
@@ -619,6 +680,7 @@ static struct hda_verb ad1983_init_verbs[] = {
{ } /* end */
};
+
static int patch_ad1983(struct hda_codec *codec)
{
struct ad198x_spec *spec;
@@ -634,10 +696,13 @@ static int patch_ad1983(struct hda_codec *codec)
spec->multiout.num_dacs = ARRAY_SIZE(ad1983_dac_nids);
spec->multiout.dac_nids = ad1983_dac_nids;
spec->multiout.dig_out_nid = AD1983_SPDIF_OUT;
- spec->adc_nid = AD1983_ADC;
+ spec->num_adc_nids = 1;
+ spec->adc_nids = ad1983_adc_nids;
spec->input_mux = &ad1983_capture_source;
- spec->mixers = ad1983_mixers;
- spec->init_verbs = ad1983_init_verbs;
+ spec->num_mixers = 1;
+ spec->mixers[0] = ad1983_mixers;
+ spec->num_init_verbs = 1;
+ spec->init_verbs[0] = ad1983_init_verbs;
spec->spdif_route = 0;
codec->patch_ops = ad198x_patch_ops;
@@ -655,6 +720,7 @@ static int patch_ad1983(struct hda_codec *codec)
#define AD1981_ADC 0x04
static hda_nid_t ad1981_dac_nids[1] = { AD1981_DAC };
+static hda_nid_t ad1981_adc_nids[1] = { AD1981_ADC };
/* 0x0c, 0x09, 0x0e, 0x0f, 0x19, 0x05, 0x18, 0x17 */
static struct hda_input_mux ad1981_capture_source = {
@@ -775,10 +841,13 @@ static int patch_ad1981(struct hda_codec *codec)
spec->multiout.num_dacs = ARRAY_SIZE(ad1981_dac_nids);
spec->multiout.dac_nids = ad1981_dac_nids;
spec->multiout.dig_out_nid = AD1981_SPDIF_OUT;
- spec->adc_nid = AD1981_ADC;
+ spec->num_adc_nids = 1;
+ spec->adc_nids = ad1981_adc_nids;
spec->input_mux = &ad1981_capture_source;
- spec->mixers = ad1981_mixers;
- spec->init_verbs = ad1981_init_verbs;
+ spec->num_mixers = 1;
+ spec->mixers[0] = ad1981_mixers;
+ spec->num_init_verbs = 1;
+ spec->init_verbs[0] = ad1981_init_verbs;
spec->spdif_route = 0;
codec->patch_ops = ad198x_patch_ops;
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 7327deb6df9f..cffb83fdcff7 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -57,6 +57,7 @@ enum {
enum {
ALC260_BASIC,
ALC260_HP,
+ ALC260_FUJITSU_S702x,
ALC260_MODEL_LAST /* last tag */
};
@@ -72,6 +73,7 @@ enum {
#define PIN_VREF50 0x21
#define PIN_OUT 0x40
#define PIN_HP 0xc0
+#define PIN_HP_AMP 0x80
struct alc_spec {
/* codec parameterization */
@@ -113,8 +115,6 @@ struct alc_spec {
/* PCM information */
struct hda_pcm pcm_rec[2]; /* used in alc_build_pcms() */
- struct semaphore bind_mutex; /* for bound controls */
-
/* dynamic controls, init_verbs and input_mux */
struct auto_pin_cfg autocfg;
unsigned int num_kctl_alloc, num_kctl_used;
@@ -218,72 +218,53 @@ static int alc880_ch_mode_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *uc
/*
- * bound volume controls
- *
- * bind multiple volumes (# indices, from 0)
+ * Control of pin widget settings via the mixer. Only boolean settings are
+ * supported, so VrefEn can't be controlled using these functions as they
+ * stand.
*/
-
-#define AMP_VAL_IDX_SHIFT 19
-#define AMP_VAL_IDX_MASK (0x0f<<19)
-
-static int alc_bind_switch_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+static int alc_pinctl_switch_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct alc_spec *spec = codec->spec;
- unsigned long pval;
-
- down(&spec->bind_mutex);
- pval = kcontrol->private_value;
- kcontrol->private_value = pval & ~AMP_VAL_IDX_MASK; /* index 0 */
- snd_hda_mixer_amp_switch_info(kcontrol, uinfo);
- kcontrol->private_value = pval;
- up(&spec->bind_mutex);
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
+ uinfo->count = 1;
+ uinfo->value.integer.min = 0;
+ uinfo->value.integer.max = 1;
return 0;
}
-static int alc_bind_switch_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int alc_pinctl_switch_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
{
struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct alc_spec *spec = codec->spec;
- unsigned long pval;
-
- down(&spec->bind_mutex);
- pval = kcontrol->private_value;
- kcontrol->private_value = pval & ~AMP_VAL_IDX_MASK; /* index 0 */
- snd_hda_mixer_amp_switch_get(kcontrol, ucontrol);
- kcontrol->private_value = pval;
- up(&spec->bind_mutex);
+ hda_nid_t nid = kcontrol->private_value & 0xffff;
+ long mask = (kcontrol->private_value >> 16) & 0xff;
+ long *valp = ucontrol->value.integer.value;
+
+ *valp = 0;
+ if (snd_hda_codec_read(codec,nid,0,AC_VERB_GET_PIN_WIDGET_CONTROL,0x00) & mask)
+ *valp = 1;
return 0;
}
-static int alc_bind_switch_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int alc_pinctl_switch_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
{
struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct alc_spec *spec = codec->spec;
- unsigned long pval;
- int i, indices, change = 0;
-
- down(&spec->bind_mutex);
- pval = kcontrol->private_value;
- indices = (pval & AMP_VAL_IDX_MASK) >> AMP_VAL_IDX_SHIFT;
- for (i = 0; i < indices; i++) {
- kcontrol->private_value = (pval & ~AMP_VAL_IDX_MASK) | (i << AMP_VAL_IDX_SHIFT);
- change |= snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
- }
- kcontrol->private_value = pval;
- up(&spec->bind_mutex);
+ hda_nid_t nid = kcontrol->private_value & 0xffff;
+ long mask = (kcontrol->private_value >> 16) & 0xff;
+ long *valp = ucontrol->value.integer.value;
+ unsigned int pinctl = snd_hda_codec_read(codec,nid,0,AC_VERB_GET_PIN_WIDGET_CONTROL,0x00);
+ int change = ((pinctl & mask)!=0) != *valp;
+
+ if (change)
+ snd_hda_codec_write(codec,nid,0,AC_VERB_SET_PIN_WIDGET_CONTROL,
+ *valp?(pinctl|mask):(pinctl&~mask));
return change;
}
-#define ALC_BIND_MUTE_MONO(xname, nid, channel, indices, direction) \
+#define ALC_PINCTL_SWITCH(xname, nid, mask) \
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
- .info = alc_bind_switch_info, \
- .get = alc_bind_switch_get, \
- .put = alc_bind_switch_put, \
- .private_value = HDA_COMPOSE_AMP_VAL(nid, channel, indices, direction) }
-
-#define ALC_BIND_MUTE(xname,nid,indices,dir) ALC_BIND_MUTE_MONO(xname,nid,3,indices,dir)
-
+ .info = alc_pinctl_switch_info, \
+ .get = alc_pinctl_switch_get, \
+ .put = alc_pinctl_switch_put, \
+ .private_value = (nid) | (mask<<16) }
/*
* ALC880 3-stack model
@@ -354,13 +335,13 @@ static struct alc_channel_mode alc880_threestack_modes[2] = {
static snd_kcontrol_new_t alc880_three_stack_mixer[] = {
HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
- ALC_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
+ HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
- ALC_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
+ HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
- ALC_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
- ALC_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
+ HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
+ HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
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),
@@ -441,7 +422,7 @@ static snd_kcontrol_new_t alc880_capture_alt_mixer[] = {
/* additional mixers to alc880_three_stack_mixer */
static snd_kcontrol_new_t alc880_five_stack_mixer[] = {
HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
- ALC_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
+ HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
{ } /* end */
};
@@ -498,15 +479,15 @@ static struct alc_channel_mode alc880_sixstack_modes[1] = {
static snd_kcontrol_new_t alc880_six_stack_mixer[] = {
HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
- ALC_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
+ HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
- ALC_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
+ HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
- ALC_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
- ALC_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
+ HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
+ HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
- ALC_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
+ HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
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),
@@ -566,13 +547,13 @@ static struct alc_channel_mode alc880_w810_modes[1] = {
/* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
static snd_kcontrol_new_t alc880_w810_base_mixer[] = {
HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
- ALC_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
+ HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
- ALC_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
+ HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
- ALC_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
- ALC_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
+ HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
+ HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
{ } /* end */
};
@@ -597,9 +578,9 @@ static struct alc_channel_mode alc880_2_jack_modes[1] = {
static snd_kcontrol_new_t alc880_z71v_mixer[] = {
HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
- ALC_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
+ HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
- ALC_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
+ HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
@@ -623,9 +604,9 @@ static hda_nid_t alc880_f1734_dac_nids[1] = {
static snd_kcontrol_new_t alc880_f1734_mixer[] = {
HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
- ALC_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
+ HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
HDA_CODEC_VOLUME("Internal Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
- ALC_BIND_MUTE("Internal Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
+ HDA_BIND_MUTE("Internal Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
@@ -648,13 +629,13 @@ static snd_kcontrol_new_t alc880_f1734_mixer[] = {
static snd_kcontrol_new_t alc880_asus_mixer[] = {
HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
- ALC_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
+ HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
- ALC_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
+ HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
- ALC_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
- ALC_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
+ HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
+ HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
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),
@@ -1383,10 +1364,10 @@ static snd_kcontrol_new_t alc880_test_mixer[] = {
HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
- ALC_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
- ALC_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
- ALC_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
- ALC_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
+ HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
+ HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
+ HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
+ HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
PIN_CTL_TEST("Front Pin Mode", 0x14),
PIN_CTL_TEST("Surround Pin Mode", 0x15),
PIN_CTL_TEST("CLFE Pin Mode", 0x16),
@@ -1769,7 +1750,7 @@ enum {
static snd_kcontrol_new_t alc880_control_templates[] = {
HDA_CODEC_VOLUME(NULL, 0, 0, 0),
HDA_CODEC_MUTE(NULL, 0, 0, 0),
- ALC_BIND_MUTE(NULL, 0, 0, 0),
+ HDA_BIND_MUTE(NULL, 0, 0, 0),
};
/* add dynamic controls */
@@ -2087,7 +2068,6 @@ static int patch_alc880(struct hda_codec *codec)
if (spec == NULL)
return -ENOMEM;
- init_MUTEX(&spec->bind_mutex);
codec->spec = spec;
board_config = snd_hda_check_board_config(codec, alc880_cfg_tbl);
@@ -2205,6 +2185,17 @@ static struct hda_input_mux alc260_capture_source = {
},
};
+/* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack
+ * and the internal CD lines.
+ */
+static struct hda_input_mux alc260_fujitsu_capture_source = {
+ .num_items = 2,
+ .items = {
+ { "Mic/Line", 0x0 },
+ { "CD", 0x4 },
+ },
+};
+
/*
* This is just place-holder, so there's something for alc_build_pcms to look
* at when it calculates the maximum number of channels. ALC260 has no mixer
@@ -2217,7 +2208,7 @@ static struct alc_channel_mode alc260_modes[1] = {
static snd_kcontrol_new_t alc260_base_mixer[] = {
HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
- ALC_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
+ HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
@@ -2229,9 +2220,9 @@ static snd_kcontrol_new_t alc260_base_mixer[] = {
HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x07, 0x05, HDA_INPUT),
HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x07, 0x05, HDA_INPUT),
HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
- ALC_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
+ HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
- ALC_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
+ HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
HDA_CODEC_VOLUME("Capture Volume", 0x04, 0x0, HDA_INPUT),
HDA_CODEC_MUTE("Capture Switch", 0x04, 0x0, HDA_INPUT),
{
@@ -2246,7 +2237,7 @@ static snd_kcontrol_new_t alc260_base_mixer[] = {
static snd_kcontrol_new_t alc260_hp_mixer[] = {
HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
- ALC_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
+ HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
@@ -2256,9 +2247,9 @@ static snd_kcontrol_new_t alc260_hp_mixer[] = {
HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
- ALC_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
+ HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
- ALC_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
+ HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
HDA_CODEC_VOLUME("Capture Volume", 0x05, 0x0, HDA_INPUT),
HDA_CODEC_MUTE("Capture Switch", 0x05, 0x0, HDA_INPUT),
{
@@ -2271,6 +2262,30 @@ static snd_kcontrol_new_t alc260_hp_mixer[] = {
{ } /* end */
};
+static snd_kcontrol_new_t alc260_fujitsu_mixer[] = {
+ HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
+ HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
+ ALC_PINCTL_SWITCH("Headphone Amp Switch", 0x14, PIN_HP_AMP),
+ HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
+ HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
+ HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
+ HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
+ HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
+ HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
+ HDA_CODEC_VOLUME("Internal Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
+ HDA_BIND_MUTE("Internal Speaker Playback Switch", 0x09, 2, HDA_INPUT),
+ HDA_CODEC_VOLUME("Capture Volume", 0x04, 0x0, HDA_INPUT),
+ HDA_CODEC_MUTE("Capture Switch", 0x04, 0x0, HDA_INPUT),
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "Capture Source",
+ .info = alc_mux_enum_info,
+ .get = alc_mux_enum_get,
+ .put = alc_mux_enum_put,
+ },
+ { } /* end */
+};
+
static struct hda_verb alc260_init_verbs[] = {
/* Line In pin widget for input */
{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
@@ -2332,6 +2347,60 @@ static struct hda_verb alc260_init_verbs[] = {
{ }
};
+/* Initialisation sequence for ALC260 as configured in Fujitsu S702x
+ * laptops.
+ */
+static struct hda_verb alc260_fujitsu_init_verbs[] = {
+ /* Disable all GPIOs */
+ {0x01, AC_VERB_SET_GPIO_MASK, 0},
+ /* Internal speaker is connected to headphone pin */
+ {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
+ /* Headphone/Line-out jack connects to Line1 pin; make it an output */
+ {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+ /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
+ {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
+ /* Ensure all other unused pins are disabled and muted.
+ * Note: trying to set widget 0x15 to anything blocks all audio
+ * output for some reason, so just leave that at the default.
+ */
+ {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
+ {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+ {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
+ {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+ {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
+ {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+ /* Disable digital (SPDIF) pins */
+ {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
+ {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
+
+ /* Start with mixer outputs muted */
+ {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
+ {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
+ {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
+
+ /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
+ {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+ /* Unmute Line1 pin widget amp left and right (no equiv mixer ctrl) */
+ {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+ /* Unmute pin widget used for Line-in (no equiv mixer ctrl) */
+ {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+
+ /* Mute capture amp left and right */
+ {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+ /* Set ADC connection select to line in (on mic1 pin) */
+ {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
+
+ /* Mute all inputs to mixer widget (even unconnected ones) */
+ {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
+ {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
+ {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
+ {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
+ {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
+ {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
+ {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
+ {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
+};
+
static struct hda_pcm_stream alc260_pcm_analog_playback = {
.substreams = 1,
.channels_min = 2,
@@ -2347,6 +2416,8 @@ static struct hda_pcm_stream alc260_pcm_analog_capture = {
static struct hda_board_config alc260_cfg_tbl[] = {
{ .modelname = "hp", .config = ALC260_HP },
{ .pci_subvendor = 0x103c, .config = ALC260_HP },
+ { .modelname = "fujitsu", .config = ALC260_FUJITSU_S702x },
+ { .pci_subvendor = 0x10cf, .pci_subdevice = 0x1326, .config = ALC260_FUJITSU_S702x },
{}
};
@@ -2359,7 +2430,6 @@ static int patch_alc260(struct hda_codec *codec)
if (spec == NULL)
return -ENOMEM;
- init_MUTEX(&spec->bind_mutex);
codec->spec = spec;
board_config = snd_hda_check_board_config(codec, alc260_cfg_tbl);
@@ -2373,14 +2443,23 @@ static int patch_alc260(struct hda_codec *codec)
spec->mixers[spec->num_mixers] = alc260_hp_mixer;
spec->num_mixers++;
break;
+ case ALC260_FUJITSU_S702x:
+ spec->mixers[spec->num_mixers] = alc260_fujitsu_mixer;
+ spec->num_mixers++;
+ break;
default:
spec->mixers[spec->num_mixers] = alc260_base_mixer;
spec->num_mixers++;
break;
}
- spec->init_verbs[0] = alc260_init_verbs;
- spec->num_init_verbs = 1;
+ if (board_config != ALC260_FUJITSU_S702x) {
+ spec->init_verbs[0] = alc260_init_verbs;
+ spec->num_init_verbs = 1;
+ } else {
+ spec->init_verbs[0] = alc260_fujitsu_init_verbs;
+ spec->num_init_verbs = 1;
+ }
spec->channel_mode = alc260_modes;
spec->num_channel_mode = ARRAY_SIZE(alc260_modes);
@@ -2393,7 +2472,11 @@ static int patch_alc260(struct hda_codec *codec)
spec->multiout.num_dacs = ARRAY_SIZE(alc260_dac_nids);
spec->multiout.dac_nids = alc260_dac_nids;
- spec->input_mux = &alc260_capture_source;
+ if (board_config != ALC260_FUJITSU_S702x) {
+ spec->input_mux = &alc260_capture_source;
+ } else {
+ spec->input_mux = &alc260_fujitsu_capture_source;
+ }
switch (board_config) {
case ALC260_HP:
spec->num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids);
@@ -2483,15 +2566,15 @@ static int alc882_mux_enum_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *u
*/
static snd_kcontrol_new_t alc882_base_mixer[] = {
HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
- ALC_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
+ HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
- ALC_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
+ HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
- ALC_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
- ALC_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
+ HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
+ HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
- ALC_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
+ HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
@@ -2609,7 +2692,6 @@ static int patch_alc882(struct hda_codec *codec)
if (spec == NULL)
return -ENOMEM;
- init_MUTEX(&spec->bind_mutex);
codec->spec = spec;
spec->mixers[spec->num_mixers] = alc882_base_mixer;
diff --git a/sound/pci/hda/patch_si3054.c b/sound/pci/hda/patch_si3054.c
index d014b7bb70df..9c7fe0b3200a 100644
--- a/sound/pci/hda/patch_si3054.c
+++ b/sound/pci/hda/patch_si3054.c
@@ -3,7 +3,7 @@
*
* HD audio interface patch for Silicon Labs 3054/5 modem codec
*
- * Copyright (c) 2005 Sasha Khapyorsky <sashak@smlink.com>
+ * Copyright (c) 2005 Sasha Khapyorsky <sashak@alsa-project.org>
* Takashi Iwai <tiwai@suse.de>
*
*
diff --git a/sound/pci/ice1712/aureon.c b/sound/pci/ice1712/aureon.c
index 2e0a31613ee6..db12b038286b 100644
--- a/sound/pci/ice1712/aureon.c
+++ b/sound/pci/ice1712/aureon.c
@@ -960,7 +960,7 @@ static int wm_adc_mux_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *ucont
if (change)
wm_put(ice, WM_ADC_MUX, nval);
snd_ice1712_restore_gpio_status(ice);
- return 0;
+ return change;
}
/*
@@ -1672,9 +1672,9 @@ static int __devinit aureon_add_controls(ice1712_t *ice)
snd_ice1712_save_gpio_status(ice);
id = aureon_cs8415_get(ice, CS8415_ID);
if (id != 0x41)
- snd_printk("No CS8415 chip. Skipping CS8415 controls.\n");
+ snd_printk(KERN_INFO "No CS8415 chip. Skipping CS8415 controls.\n");
else if ((id & 0x0F) != 0x01)
- snd_printk("Detected unsupported CS8415 rev. (%c)\n", (char)((id & 0x0F) + 'A' - 1));
+ snd_printk(KERN_INFO "Detected unsupported CS8415 rev. (%c)\n", (char)((id & 0x0F) + 'A' - 1));
else {
for (i = 0; i< ARRAY_SIZE(cs8415_controls); i++) {
snd_kcontrol_t *kctl;
diff --git a/sound/pci/ice1712/delta.c b/sound/pci/ice1712/delta.c
index 39fbe662965d..576f69d482c9 100644
--- a/sound/pci/ice1712/delta.c
+++ b/sound/pci/ice1712/delta.c
@@ -546,7 +546,7 @@ static int __devinit snd_ice1712_delta_init(ice1712_t *ice)
case ICE1712_SUBDEVICE_DELTA1010LT:
case ICE1712_SUBDEVICE_VX442:
if ((err = snd_i2c_bus_create(ice->card, "ICE1712 GPIO 1", NULL, &ice->i2c)) < 0) {
- snd_printk("unable to create I2C bus\n");
+ snd_printk(KERN_ERR "unable to create I2C bus\n");
return err;
}
ice->i2c->private_data = ice;
diff --git a/sound/pci/ice1712/ews.c b/sound/pci/ice1712/ews.c
index e36efa1bdac3..c8ec5cac3c17 100644
--- a/sound/pci/ice1712/ews.c
+++ b/sound/pci/ice1712/ews.c
@@ -438,7 +438,7 @@ static int __devinit snd_ice1712_ews_init(ice1712_t *ice)
/* create i2c */
if ((err = snd_i2c_bus_create(ice->card, "ICE1712 GPIO 1", NULL, &ice->i2c)) < 0) {
- snd_printk("unable to create I2C bus\n");
+ snd_printk(KERN_ERR "unable to create I2C bus\n");
return err;
}
ice->i2c->private_data = ice;
@@ -448,7 +448,7 @@ static int __devinit snd_ice1712_ews_init(ice1712_t *ice)
switch (ice->eeprom.subvendor) {
case ICE1712_SUBDEVICE_DMX6FIRE:
if ((err = snd_i2c_device_create(ice->i2c, "PCF9554", ICE1712_6FIRE_PCF9554_ADDR, &ice->spec.i2cdevs[EWS_I2C_6FIRE])) < 0) {
- snd_printk("PCF9554 initialization failed\n");
+ snd_printk(KERN_ERR "PCF9554 initialization failed\n");
return err;
}
snd_ice1712_6fire_write_pca(ice, PCF9554_REG_CONFIG, 0x80);
@@ -791,7 +791,7 @@ static int snd_ice1712_6fire_read_pca(ice1712_t *ice, unsigned char reg)
byte = 0;
if (snd_i2c_readbytes(ice->spec.i2cdevs[EWS_I2C_6FIRE], &byte, 1) != 1) {
snd_i2c_unlock(ice->i2c);
- printk("cannot read pca\n");
+ printk(KERN_ERR "cannot read pca\n");
return -EIO;
}
snd_i2c_unlock(ice->i2c);
diff --git a/sound/pci/ice1712/ice1712.c b/sound/pci/ice1712/ice1712.c
index a6d98013c331..bd71bf424549 100644
--- a/sound/pci/ice1712/ice1712.c
+++ b/sound/pci/ice1712/ice1712.c
@@ -387,7 +387,7 @@ int __devinit snd_ice1712_init_cs8427(ice1712_t *ice, int addr)
if ((err = snd_cs8427_create(ice->i2c, addr,
(ice->cs8427_timeout * HZ) / 1000,
&ice->cs8427)) < 0) {
- snd_printk("CS8427 initialization failed\n");
+ snd_printk(KERN_ERR "CS8427 initialization failed\n");
return err;
}
ice->spdif.ops.open = open_cs8427;
@@ -2348,12 +2348,12 @@ static int __devinit snd_ice1712_read_eeprom(ice1712_t *ice, const char *modelna
if (ice->eeprom.size < 6)
ice->eeprom.size = 32; /* FIXME: any cards without the correct size? */
else if (ice->eeprom.size > 32) {
- snd_printk("invalid EEPROM (size = %i)\n", ice->eeprom.size);
+ snd_printk(KERN_ERR "invalid EEPROM (size = %i)\n", ice->eeprom.size);
return -EIO;
}
ice->eeprom.version = snd_ice1712_read_i2c(ice, dev, 0x05);
if (ice->eeprom.version != 1) {
- snd_printk("invalid EEPROM version %i\n", ice->eeprom.version);
+ snd_printk(KERN_ERR "invalid EEPROM version %i\n", ice->eeprom.version);
/* return -EIO; */
}
size = ice->eeprom.size - 6;
@@ -2524,7 +2524,7 @@ static int __devinit snd_ice1712_create(snd_card_t * card,
/* check, if we can restrict PCI DMA transfers to 28 bits */
if (pci_set_dma_mask(pci, 0x0fffffff) < 0 ||
pci_set_consistent_dma_mask(pci, 0x0fffffff) < 0) {
- snd_printk("architecture does not support 28bit PCI busmaster DMA\n");
+ snd_printk(KERN_ERR "architecture does not support 28bit PCI busmaster DMA\n");
pci_disable_device(pci);
return -ENXIO;
}
@@ -2573,7 +2573,7 @@ static int __devinit snd_ice1712_create(snd_card_t * card,
ice->profi_port = pci_resource_start(pci, 3);
if (request_irq(pci->irq, snd_ice1712_interrupt, SA_INTERRUPT|SA_SHIRQ, "ICE1712", (void *) ice)) {
- snd_printk("unable to grab IRQ %d\n", pci->irq);
+ snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
snd_ice1712_free(ice);
return -EIO;
}
@@ -2735,7 +2735,6 @@ static void __devexit snd_ice1712_remove(struct pci_dev *pci)
static struct pci_driver driver = {
.name = "ICE1712",
- .owner = THIS_MODULE,
.id_table = snd_ice1712_ids,
.probe = snd_ice1712_probe,
.remove = __devexit_p(snd_ice1712_remove),
diff --git a/sound/pci/ice1712/ice1724.c b/sound/pci/ice1712/ice1724.c
index c3ce8f93740b..0b5389ee26d5 100644
--- a/sound/pci/ice1712/ice1724.c
+++ b/sound/pci/ice1712/ice1724.c
@@ -675,9 +675,12 @@ static snd_pcm_hardware_t snd_vt1724_spdif =
SNDRV_PCM_INFO_MMAP_VALID |
SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_SYNC_START),
.formats = SNDRV_PCM_FMTBIT_S32_LE,
- .rates = SNDRV_PCM_RATE_32000|SNDRV_PCM_RATE_44100|SNDRV_PCM_RATE_48000,
+ .rates = (SNDRV_PCM_RATE_32000|SNDRV_PCM_RATE_44100|
+ SNDRV_PCM_RATE_48000|SNDRV_PCM_RATE_88200|
+ SNDRV_PCM_RATE_96000|SNDRV_PCM_RATE_176400|
+ SNDRV_PCM_RATE_192000),
.rate_min = 32000,
- .rate_max = 48000,
+ .rate_max = 192000,
.channels_min = 2,
.channels_max = 2,
.buffer_bytes_max = (1UL << 18), /* 16bits dword */
@@ -905,6 +908,10 @@ static void update_spdif_rate(ice1712_t *ice, unsigned int rate)
case 44100: break;
case 48000: nval |= 2 << 12; break;
case 32000: nval |= 3 << 12; break;
+ case 88200: nval |= 4 << 12; break;
+ case 96000: nval |= 5 << 12; break;
+ case 192000: nval |= 6 << 12; break;
+ case 176400: nval |= 7 << 12; break;
}
if (val != nval)
update_spdif_bits(ice, nval);
@@ -1292,22 +1299,32 @@ static int snd_vt1724_spdif_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *
static unsigned int encode_spdif_bits(snd_aes_iec958_t *diga)
{
- unsigned int val;
+ unsigned int val, rbits;
val = diga->status[0] & 0x03; /* professional, non-audio */
if (val & 0x01) {
/* professional */
if ((diga->status[0] & IEC958_AES0_PRO_EMPHASIS) == IEC958_AES0_PRO_EMPHASIS_5015)
val |= 1U << 3;
- switch (diga->status[0] & IEC958_AES0_PRO_FS) {
- case IEC958_AES0_PRO_FS_44100:
- break;
- case IEC958_AES0_PRO_FS_32000:
- val |= 3U << 12;
- break;
- default:
- val |= 2U << 12;
- break;
+ rbits = (diga->status[4] >> 3) & 0x0f;
+ if (rbits) {
+ switch (rbits) {
+ case 2: val |= 5 << 12; break; /* 96k */
+ case 3: val |= 6 << 12; break; /* 192k */
+ case 10: val |= 4 << 12; break; /* 88.2k */
+ case 11: val |= 7 << 12; break; /* 176.4k */
+ }
+ } else {
+ switch (diga->status[0] & IEC958_AES0_PRO_FS) {
+ case IEC958_AES0_PRO_FS_44100:
+ break;
+ case IEC958_AES0_PRO_FS_32000:
+ val |= 3U << 12;
+ break;
+ default:
+ val |= 2U << 12;
+ break;
+ }
}
} else {
/* consumer */
@@ -2154,7 +2171,7 @@ static int __devinit snd_vt1724_create(snd_card_t * card,
ice->profi_port = pci_resource_start(pci, 1);
if (request_irq(pci->irq, snd_vt1724_interrupt, SA_INTERRUPT|SA_SHIRQ, "ICE1724", (void *) ice)) {
- snd_printk("unable to grab IRQ %d\n", pci->irq);
+ snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
snd_vt1724_free(ice);
return -EIO;
}
@@ -2315,7 +2332,6 @@ static void __devexit snd_vt1724_remove(struct pci_dev *pci)
static struct pci_driver driver = {
.name = "ICE1724",
- .owner = THIS_MODULE,
.id_table = snd_vt1724_ids,
.probe = snd_vt1724_probe,
.remove = __devexit_p(snd_vt1724_remove),
diff --git a/sound/pci/ice1712/pontis.c b/sound/pci/ice1712/pontis.c
index a5f852b1f575..773a1ecb75ce 100644
--- a/sound/pci/ice1712/pontis.c
+++ b/sound/pci/ice1712/pontis.c
@@ -794,8 +794,7 @@ static int __devinit pontis_init(ice1712_t *ice)
/* initialize WM8776 codec */
for (i = 0; i < ARRAY_SIZE(wm_inits); i += 2)
wm_put(ice, wm_inits[i], wm_inits[i+1]);
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(1);
+ schedule_timeout_uninterruptible(1);
for (i = 0; i < ARRAY_SIZE(wm_inits2); i += 2)
wm_put(ice, wm_inits2[i], wm_inits2[i+1]);
diff --git a/sound/pci/ice1712/revo.c b/sound/pci/ice1712/revo.c
index d48d42524ac5..1fe21009ca84 100644
--- a/sound/pci/ice1712/revo.c
+++ b/sound/pci/ice1712/revo.c
@@ -128,17 +128,6 @@ static struct snd_ak4xxx_private akm_revo_surround_priv __devinitdata = {
.mask_flags = 0,
};
-static unsigned int rates[] = {
- 32000, 44100, 48000, 64000, 88200, 96000,
- 176400, 192000,
-};
-
-static snd_pcm_hw_constraint_list_t revo_rates = {
- .count = ARRAY_SIZE(rates),
- .list = rates,
- .mask = 0,
-};
-
static int __devinit revo_init(ice1712_t *ice)
{
akm4xxx_t *ak;
@@ -173,8 +162,6 @@ static int __devinit revo_init(ice1712_t *ice)
break;
}
- ice->hw_rates = &revo_rates; /* AK codecs don't support lower than 32k */
-
return 0;
}
diff --git a/sound/pci/ice1712/vt1720_mobo.c b/sound/pci/ice1712/vt1720_mobo.c
index ab61e383024f..90c85cd95479 100644
--- a/sound/pci/ice1712/vt1720_mobo.c
+++ b/sound/pci/ice1712/vt1720_mobo.c
@@ -71,6 +71,22 @@ static unsigned char k8x800_eeprom[] __devinitdata = {
0x00, /* - */
};
+static unsigned char sn25p_eeprom[] __devinitdata = {
+ 0x01, /* SYSCONF: clock 256, 1ADC, 2DACs */
+ 0x02, /* ACLINK: ACLINK, packed */
+ 0x00, /* I2S: - */
+ 0x41, /* SPDIF: - */
+ 0xff, /* GPIO_DIR */
+ 0xff, /* GPIO_DIR1 */
+ 0x00, /* - */
+ 0xff, /* GPIO_MASK */
+ 0xff, /* GPIO_MASK1 */
+ 0x00, /* - */
+ 0x00, /* GPIO_STATE */
+ 0x00, /* GPIO_STATE1 */
+ 0x00, /* - */
+};
+
/* entry point */
struct snd_ice1712_card_info snd_vt1720_mobo_cards[] __devinitdata = {
@@ -113,11 +129,11 @@ struct snd_ice1712_card_info snd_vt1720_mobo_cards[] __devinitdata = {
{
.subvendor = VT1720_SUBDEVICE_SN25P,
.name = "Shuttle SN25P",
- /* identical with k8x800 */
+ .model = "sn25p",
.chip_init = k8x800_init,
.build_controls = k8x800_add_controls,
.eeprom_size = sizeof(k8x800_eeprom),
- .eeprom_data = k8x800_eeprom,
+ .eeprom_data = sn25p_eeprom,
},
{ } /* terminator */
};
diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c
index 1a96198a17ae..cf7801d2dd10 100644
--- a/sound/pci/intel8x0.c
+++ b/sound/pci/intel8x0.c
@@ -64,36 +64,35 @@ MODULE_SUPPORTED_DEVICE("{{Intel,82801AA-ICH},"
"{AMD,AMD8111},"
"{ALI,M5455}}");
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
-static int ac97_clock[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0};
-static char *ac97_quirk[SNDRV_CARDS];
-static int buggy_semaphore[SNDRV_CARDS];
-static int buggy_irq[SNDRV_CARDS];
-static int xbox[SNDRV_CARDS];
-
-#ifdef SUPPORT_MIDI
-static int mpu_port[SNDRV_CARDS]; /* disabled */
-#endif
-
-module_param_array(index, int, NULL, 0444);
+static int index = SNDRV_DEFAULT_IDX1; /* Index 0-MAX */
+static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */
+static int ac97_clock = 0;
+static char *ac97_quirk;
+static int buggy_semaphore;
+static int buggy_irq = -1; /* auto-check */
+static int xbox;
+
+module_param(index, int, 0444);
MODULE_PARM_DESC(index, "Index value for Intel i8x0 soundcard.");
-module_param_array(id, charp, NULL, 0444);
+module_param(id, charp, 0444);
MODULE_PARM_DESC(id, "ID string for Intel i8x0 soundcard.");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable Intel i8x0 soundcard.");
-module_param_array(ac97_clock, int, NULL, 0444);
+module_param(ac97_clock, int, 0444);
MODULE_PARM_DESC(ac97_clock, "AC'97 codec clock (0 = auto-detect).");
-module_param_array(ac97_quirk, charp, NULL, 0444);
+module_param(ac97_quirk, charp, 0444);
MODULE_PARM_DESC(ac97_quirk, "AC'97 workaround for strange hardware.");
-module_param_array(buggy_semaphore, bool, NULL, 0444);
+module_param(buggy_semaphore, bool, 0444);
MODULE_PARM_DESC(buggy_semaphore, "Enable workaround for hardwares with problematic codec semaphores.");
-module_param_array(buggy_irq, bool, NULL, 0444);
+module_param(buggy_irq, bool, 0444);
MODULE_PARM_DESC(buggy_irq, "Enable workaround for buggy interrupts on some motherboards.");
-module_param_array(xbox, bool, NULL, 0444);
+module_param(xbox, bool, 0444);
MODULE_PARM_DESC(xbox, "Set to 1 for Xbox, if you have problems with the AC'97 codec detection.");
+/* just for backward compatibility */
+static int enable;
+module_param(enable, bool, 0444);
+static int joystick;
+module_param(joystick, int, 0444);
+
/*
* Direct registers
*/
@@ -539,7 +538,7 @@ static int snd_intel8x0_codec_semaphore(intel8x0_t *chip, unsigned int codec)
/* access to some forbidden (non existant) ac97 registers will not
* reset the semaphore. So even if you don't get the semaphore, still
* continue the access. We don't need the semaphore anyway. */
- snd_printk("codec_semaphore: semaphore is not ready [0x%x][0x%x]\n",
+ snd_printk(KERN_ERR "codec_semaphore: semaphore is not ready [0x%x][0x%x]\n",
igetbyte(chip, ICHREG(ACC_SEMA)), igetdword(chip, ICHREG(GLOB_STA)));
iagetword(chip, 0); /* clear semaphore flag */
/* I don't care about the semaphore */
@@ -554,7 +553,7 @@ static void snd_intel8x0_codec_write(ac97_t *ac97,
if (snd_intel8x0_codec_semaphore(chip, ac97->num) < 0) {
if (! chip->in_ac97_init)
- snd_printk("codec_write %d: semaphore is not ready for register 0x%x\n", ac97->num, reg);
+ snd_printk(KERN_ERR "codec_write %d: semaphore is not ready for register 0x%x\n", ac97->num, reg);
}
iaputword(chip, reg + ac97->num * 0x80, val);
}
@@ -568,7 +567,7 @@ static unsigned short snd_intel8x0_codec_read(ac97_t *ac97,
if (snd_intel8x0_codec_semaphore(chip, ac97->num) < 0) {
if (! chip->in_ac97_init)
- snd_printk("codec_read %d: semaphore is not ready for register 0x%x\n", ac97->num, reg);
+ snd_printk(KERN_ERR "codec_read %d: semaphore is not ready for register 0x%x\n", ac97->num, reg);
res = 0xffff;
} else {
res = iagetword(chip, reg + ac97->num * 0x80);
@@ -576,7 +575,7 @@ static unsigned short snd_intel8x0_codec_read(ac97_t *ac97,
/* reset RCS and preserve other R/WC bits */
iputdword(chip, ICHREG(GLOB_STA), tmp & ~(ICH_SRI|ICH_PRI|ICH_TRI|ICH_GSCI));
if (! chip->in_ac97_init)
- snd_printk("codec_read %d: read timeout for register 0x%x\n", ac97->num, reg);
+ snd_printk(KERN_ERR "codec_read %d: read timeout for register 0x%x\n", ac97->num, reg);
res = 0xffff;
}
}
@@ -607,16 +606,19 @@ static int snd_intel8x0_ali_codec_ready(intel8x0_t *chip, int mask)
if (val & mask)
return 0;
}
- snd_printd(KERN_WARNING "intel8x0: AC97 codec ready timeout.\n");
+ if (! chip->in_ac97_init)
+ snd_printd(KERN_WARNING "intel8x0: AC97 codec ready timeout.\n");
return -EBUSY;
}
static int snd_intel8x0_ali_codec_semaphore(intel8x0_t *chip)
{
int time = 100;
+ if (chip->buggy_semaphore)
+ return 0; /* just ignore ... */
while (time-- && (igetdword(chip, ICHREG(ALI_CAS)) & ALI_CAS_SEM_BUSY))
udelay(1);
- if (! time)
+ if (! time && ! chip->in_ac97_init)
snd_printk(KERN_WARNING "ali_codec_semaphore timeout\n");
return snd_intel8x0_ali_codec_ready(chip, ALI_CSPSR_CODEC_READY);
}
@@ -1716,6 +1718,12 @@ static struct ac97_quirk ac97_quirks[] __devinitdata = {
.type = AC97_TUNE_HP_ONLY
},
{
+ .subvendor = 0x1025,
+ .subdevice = 0x0083,
+ .name = "Acer Aspire 3003LCi",
+ .type = AC97_TUNE_HP_ONLY
+ },
+ {
.subvendor = 0x1028,
.subdevice = 0x00d8,
.name = "Dell Precision 530", /* AD1885 */
@@ -1758,6 +1766,12 @@ static struct ac97_quirk ac97_quirks[] __devinitdata = {
.type = AC97_TUNE_HP_ONLY
},
{
+ .subvendor = 0x1028,
+ .subdevice = 0x0191,
+ .name = "Dell Inspiron 8600",
+ .type = AC97_TUNE_HP_ONLY
+ },
+ {
.subvendor = 0x103c,
.subdevice = 0x006d,
.name = "HP zv5000",
@@ -2022,7 +2036,6 @@ static int __devinit snd_intel8x0_mixer(intel8x0_t *chip, int ac97_clock, const
if ((err = snd_ac97_bus(chip->card, 0, ops, chip, &pbus)) < 0)
goto __err;
pbus->private_free = snd_intel8x0_mixer_free_ac97_bus;
- pbus->shared_type = AC97_SHARED_TYPE_ICH; /* shared with modem driver */
if (ac97_clock >= 8000 && ac97_clock <= 48000)
pbus->clock = ac97_clock;
/* FIXME: my test board doesn't work well with VRA... */
@@ -2131,14 +2144,13 @@ static void do_ali_reset(intel8x0_t *chip)
iputdword(chip, ICHREG(ALI_FIFOCR2), 0x83838383);
iputdword(chip, ICHREG(ALI_FIFOCR3), 0x83838383);
iputdword(chip, ICHREG(ALI_INTERFACECR),
- ICH_ALI_IF_MC|ICH_ALI_IF_PI|ICH_ALI_IF_PO);
+ ICH_ALI_IF_PI|ICH_ALI_IF_PO);
iputdword(chip, ICHREG(ALI_INTERRUPTCR), 0x00000000);
iputdword(chip, ICHREG(ALI_INTERRUPTSR), 0x00000000);
}
#define do_delay(chip) do {\
- set_current_state(TASK_UNINTERRUPTIBLE);\
- schedule_timeout(1);\
+ schedule_timeout_uninterruptible(1);\
} while (0)
static int snd_intel8x0_ich_chip_init(intel8x0_t *chip, int probing)
@@ -2166,7 +2178,7 @@ static int snd_intel8x0_ich_chip_init(intel8x0_t *chip, int probing)
goto __ok;
do_delay(chip);
} while (time_after_eq(end_time, jiffies));
- snd_printk("AC'97 warm reset still in progress? [0x%x]\n", igetdword(chip, ICHREG(GLOB_CNT)));
+ snd_printk(KERN_ERR "AC'97 warm reset still in progress? [0x%x]\n", igetdword(chip, ICHREG(GLOB_CNT)));
return -EIO;
__ok:
@@ -2441,7 +2453,7 @@ static void __devinit intel8x0_measure_ac97_clock(intel8x0_t *chip)
subs = chip->pcm[0]->streams[0].substream;
if (! subs || subs->dma_buffer.bytes < INTEL8X0_TESTBUF_SIZE) {
- snd_printk("no playback buffer allocated - aborting measure ac97 clock\n");
+ snd_printk(KERN_WARNING "no playback buffer allocated - aborting measure ac97 clock\n");
return;
}
ichdev = &chip->ichd[ICHD_PCMOUT];
@@ -2477,7 +2489,7 @@ static void __devinit intel8x0_measure_ac97_clock(intel8x0_t *chip)
do_gettimeofday(&stop_time);
/* stop */
if (chip->device_type == DEVICE_ALI) {
- iputdword(chip, ICHREG(ALI_DMACR), 1 << (ichdev->ali_slot + 8));
+ iputdword(chip, ICHREG(ALI_DMACR), 1 << (ichdev->ali_slot + 16));
iputbyte(chip, port + ICH_REG_OFF_CR, 0);
while (igetbyte(chip, port + ICH_REG_OFF_CR))
;
@@ -2556,7 +2568,6 @@ struct ich_reg_info {
static int __devinit snd_intel8x0_create(snd_card_t * card,
struct pci_dev *pci,
unsigned long device_type,
- int buggy_sem,
intel8x0_t ** r_intel8x0)
{
intel8x0_t *chip;
@@ -2614,18 +2625,17 @@ static int __devinit snd_intel8x0_create(snd_card_t * card,
chip->card = card;
chip->pci = pci;
chip->irq = -1;
- chip->buggy_semaphore = buggy_sem;
+
+ /* module parameters */
+ chip->buggy_irq = buggy_irq;
+ chip->buggy_semaphore = buggy_semaphore;
+ if (xbox)
+ chip->xbox = 1;
if (pci->vendor == PCI_VENDOR_ID_INTEL &&
pci->device == PCI_DEVICE_ID_INTEL_440MX)
chip->fix_nocache = 1; /* enable workaround */
- /* some Nforce[2] and ICH boards have problems with IRQ handling.
- * Needs to return IRQ_HANDLED for unknown irqs.
- */
- if (device_type == DEVICE_NFORCE)
- chip->buggy_irq = 1;
-
if ((err = pci_request_regions(pci, card->shortname)) < 0) {
kfree(chip);
pci_disable_device(pci);
@@ -2644,7 +2654,7 @@ static int __devinit snd_intel8x0_create(snd_card_t * card,
chip->remap_addr = ioremap_nocache(chip->addr,
pci_resource_len(pci, 2));
if (chip->remap_addr == NULL) {
- snd_printk("AC'97 space ioremap problem\n");
+ snd_printk(KERN_ERR "AC'97 space ioremap problem\n");
snd_intel8x0_free(chip);
return -EIO;
}
@@ -2657,7 +2667,7 @@ static int __devinit snd_intel8x0_create(snd_card_t * card,
chip->remap_bmaddr = ioremap_nocache(chip->bmaddr,
pci_resource_len(pci, 3));
if (chip->remap_bmaddr == NULL) {
- snd_printk("Controller space ioremap problem\n");
+ snd_printk(KERN_ERR "Controller space ioremap problem\n");
snd_intel8x0_free(chip);
return -EIO;
}
@@ -2666,15 +2676,6 @@ static int __devinit snd_intel8x0_create(snd_card_t * card,
}
port_inited:
- if (request_irq(pci->irq, snd_intel8x0_interrupt, SA_INTERRUPT|SA_SHIRQ, card->shortname, (void *)chip)) {
- snd_printk("unable to grab IRQ %d\n", pci->irq);
- snd_intel8x0_free(chip);
- return -EBUSY;
- }
- chip->irq = pci->irq;
- pci_set_master(pci);
- synchronize_irq(chip->irq);
-
chip->bdbars_count = bdbars[device_type];
/* initialize offsets */
@@ -2725,13 +2726,27 @@ static int __devinit snd_intel8x0_create(snd_card_t * card,
int_sta_masks = 0;
for (i = 0; i < chip->bdbars_count; i++) {
ichdev = &chip->ichd[i];
- ichdev->bdbar = ((u32 *)chip->bdbars.area) + (i * ICH_MAX_FRAGS * 2);
- ichdev->bdbar_addr = chip->bdbars.addr + (i * sizeof(u32) * ICH_MAX_FRAGS * 2);
+ ichdev->bdbar = ((u32 *)chip->bdbars.area) +
+ (i * ICH_MAX_FRAGS * 2);
+ ichdev->bdbar_addr = chip->bdbars.addr +
+ (i * sizeof(u32) * ICH_MAX_FRAGS * 2);
int_sta_masks |= ichdev->int_sta_mask;
}
- chip->int_sta_reg = device_type == DEVICE_ALI ? ICH_REG_ALI_INTERRUPTSR : ICH_REG_GLOB_STA;
+ chip->int_sta_reg = device_type == DEVICE_ALI ?
+ ICH_REG_ALI_INTERRUPTSR : ICH_REG_GLOB_STA;
chip->int_sta_mask = int_sta_masks;
+ /* request irq after initializaing int_sta_mask, etc */
+ if (request_irq(pci->irq, snd_intel8x0_interrupt,
+ SA_INTERRUPT|SA_SHIRQ, card->shortname, (void *)chip)) {
+ snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
+ snd_intel8x0_free(chip);
+ return -EBUSY;
+ }
+ chip->irq = pci->irq;
+ pci_set_master(pci);
+ synchronize_irq(chip->irq);
+
if ((err = snd_intel8x0_chip_init(chip, 1)) < 0) {
snd_intel8x0_free(chip);
return err;
@@ -2782,20 +2797,12 @@ static struct shortname_table {
static int __devinit snd_intel8x0_probe(struct pci_dev *pci,
const struct pci_device_id *pci_id)
{
- static int dev;
snd_card_t *card;
intel8x0_t *chip;
int err;
struct shortname_table *name;
- if (dev >= SNDRV_CARDS)
- return -ENODEV;
- if (!enable[dev]) {
- dev++;
- return -ENOENT;
- }
-
- card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
+ card = snd_card_new(index, id, THIS_MODULE, 0);
if (card == NULL)
return -ENOMEM;
@@ -2819,17 +2826,23 @@ static int __devinit snd_intel8x0_probe(struct pci_dev *pci,
}
}
+ if (buggy_irq < 0) {
+ /* some Nforce[2] and ICH boards have problems with IRQ handling.
+ * Needs to return IRQ_HANDLED for unknown irqs.
+ */
+ if (pci_id->driver_data == DEVICE_NFORCE)
+ buggy_irq = 1;
+ else
+ buggy_irq = 0;
+ }
+
if ((err = snd_intel8x0_create(card, pci, pci_id->driver_data,
- buggy_semaphore[dev], &chip)) < 0) {
+ &chip)) < 0) {
snd_card_free(card);
return err;
}
- if (buggy_irq[dev])
- chip->buggy_irq = 1;
- if (xbox[dev])
- chip->xbox = 1;
- if ((err = snd_intel8x0_mixer(chip, ac97_clock[dev], ac97_quirk[dev])) < 0) {
+ if ((err = snd_intel8x0_mixer(chip, ac97_clock, ac97_quirk)) < 0) {
snd_card_free(card);
return err;
}
@@ -2844,7 +2857,7 @@ static int __devinit snd_intel8x0_probe(struct pci_dev *pci,
"%s with %s at %#lx, irq %i", card->shortname,
snd_ac97_get_short_name(chip->ac97[0]), chip->addr, chip->irq);
- if (! ac97_clock[dev])
+ if (! ac97_clock)
intel8x0_measure_ac97_clock(chip);
if ((err = snd_card_register(card)) < 0) {
@@ -2852,7 +2865,6 @@ static int __devinit snd_intel8x0_probe(struct pci_dev *pci,
return err;
}
pci_set_drvdata(pci, card);
- dev++;
return 0;
}
@@ -2864,7 +2876,6 @@ static void __devexit snd_intel8x0_remove(struct pci_dev *pci)
static struct pci_driver driver = {
.name = "Intel ICH",
- .owner = THIS_MODULE,
.id_table = snd_intel8x0_ids,
.probe = snd_intel8x0_probe,
.remove = __devexit_p(snd_intel8x0_remove),
diff --git a/sound/pci/intel8x0m.c b/sound/pci/intel8x0m.c
index 9e2060d56c24..a42091860da7 100644
--- a/sound/pci/intel8x0m.c
+++ b/sound/pci/intel8x0m.c
@@ -3,7 +3,7 @@
*
* Copyright (c) 2000 Jaroslav Kysela <perex@suse.cz>
*
- * This is modified (by Sasha Khapyorsky <sashak@smlink.com>) version
+ * This is modified (by Sasha Khapyorsky <sashak@alsa-project.org>) version
* of ALSA ICH sound driver intel8x0.c .
*
*
@@ -56,20 +56,21 @@ MODULE_SUPPORTED_DEVICE("{{Intel,82801AA-ICH},"
"{NVidia,NForce3 Modem},"
"{AMD,AMD768}}");
-static int index[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = -2}; /* Exclude the first card */
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
-static int ac97_clock[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0};
+static int index = -2; /* Exclude the first card */
+static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */
+static int ac97_clock = 0;
-module_param_array(index, int, NULL, 0444);
+module_param(index, int, 0444);
MODULE_PARM_DESC(index, "Index value for Intel i8x0 modemcard.");
-module_param_array(id, charp, NULL, 0444);
+module_param(id, charp, 0444);
MODULE_PARM_DESC(id, "ID string for Intel i8x0 modemcard.");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable Intel i8x0 modemcard.");
-module_param_array(ac97_clock, int, NULL, 0444);
+module_param(ac97_clock, int, 0444);
MODULE_PARM_DESC(ac97_clock, "AC'97 codec clock (0 = auto-detect).");
+/* just for backward compatibility */
+static int enable;
+module_param(enable, bool, 0444);
+
/*
* Direct registers
*/
@@ -362,7 +363,7 @@ static int snd_intel8x0m_codec_semaphore(intel8x0_t *chip, unsigned int codec)
/* access to some forbidden (non existant) ac97 registers will not
* reset the semaphore. So even if you don't get the semaphore, still
* continue the access. We don't need the semaphore anyway. */
- snd_printk("codec_semaphore: semaphore is not ready [0x%x][0x%x]\n",
+ snd_printk(KERN_ERR "codec_semaphore: semaphore is not ready [0x%x][0x%x]\n",
igetbyte(chip, ICHREG(ACC_SEMA)), igetdword(chip, ICHREG(GLOB_STA)));
iagetword(chip, 0); /* clear semaphore flag */
/* I don't care about the semaphore */
@@ -377,7 +378,7 @@ static void snd_intel8x0_codec_write(ac97_t *ac97,
if (snd_intel8x0m_codec_semaphore(chip, ac97->num) < 0) {
if (! chip->in_ac97_init)
- snd_printk("codec_write %d: semaphore is not ready for register 0x%x\n", ac97->num, reg);
+ snd_printk(KERN_ERR "codec_write %d: semaphore is not ready for register 0x%x\n", ac97->num, reg);
}
iaputword(chip, reg + ac97->num * 0x80, val);
}
@@ -391,7 +392,7 @@ static unsigned short snd_intel8x0_codec_read(ac97_t *ac97,
if (snd_intel8x0m_codec_semaphore(chip, ac97->num) < 0) {
if (! chip->in_ac97_init)
- snd_printk("codec_read %d: semaphore is not ready for register 0x%x\n", ac97->num, reg);
+ snd_printk(KERN_ERR "codec_read %d: semaphore is not ready for register 0x%x\n", ac97->num, reg);
res = 0xffff;
} else {
res = iagetword(chip, reg + ac97->num * 0x80);
@@ -399,7 +400,7 @@ static unsigned short snd_intel8x0_codec_read(ac97_t *ac97,
/* reset RCS and preserve other R/WC bits */
iputdword(chip, ICHREG(GLOB_STA), tmp & ~(ICH_SRI|ICH_PRI|ICH_TRI|ICH_GSCI));
if (! chip->in_ac97_init)
- snd_printk("codec_read %d: read timeout for register 0x%x\n", ac97->num, reg);
+ snd_printk(KERN_ERR "codec_read %d: read timeout for register 0x%x\n", ac97->num, reg);
res = 0xffff;
}
}
@@ -746,6 +747,7 @@ static int __devinit snd_intel8x0_pcm1(intel8x0_t *chip, int device, struct ich_
pcm->private_data = chip;
pcm->info_flags = 0;
+ pcm->dev_class = SNDRV_PCM_CLASS_MODEM;
if (rec->suffix)
sprintf(pcm->name, "%s - %s", chip->card->shortname, rec->suffix);
else
@@ -854,7 +856,6 @@ static int __devinit snd_intel8x0_mixer(intel8x0_t *chip, int ac97_clock)
if ((err = snd_ac97_bus(chip->card, 0, &ops, chip, &pbus)) < 0)
goto __err;
pbus->private_free = snd_intel8x0_mixer_free_ac97_bus;
- pbus->shared_type = AC97_SHARED_TYPE_ICH; /* shared with audio driver */
if (ac97_clock >= 8000 && ac97_clock <= 48000)
pbus->clock = ac97_clock;
chip->ac97_bus = pbus;
@@ -889,8 +890,7 @@ static int __devinit snd_intel8x0_mixer(intel8x0_t *chip, int ac97_clock)
*/
#define do_delay(chip) do {\
- set_current_state(TASK_UNINTERRUPTIBLE);\
- schedule_timeout(1);\
+ schedule_timeout_uninterruptible(1);\
} while (0)
static int snd_intel8x0m_ich_chip_init(intel8x0_t *chip, int probing)
@@ -916,7 +916,7 @@ static int snd_intel8x0m_ich_chip_init(intel8x0_t *chip, int probing)
goto __ok;
do_delay(chip);
} while (time_after_eq(end_time, jiffies));
- snd_printk("AC'97 warm reset still in progress? [0x%x]\n", igetdword(chip, ICHREG(GLOB_CNT)));
+ snd_printk(KERN_ERR "AC'97 warm reset still in progress? [0x%x]\n", igetdword(chip, ICHREG(GLOB_CNT)));
return -EIO;
__ok:
@@ -1142,7 +1142,7 @@ static int __devinit snd_intel8x0m_create(snd_card_t * card,
chip->remap_addr = ioremap_nocache(chip->addr,
pci_resource_len(pci, 2));
if (chip->remap_addr == NULL) {
- snd_printk("AC'97 space ioremap problem\n");
+ snd_printk(KERN_ERR "AC'97 space ioremap problem\n");
snd_intel8x0_free(chip);
return -EIO;
}
@@ -1155,7 +1155,7 @@ static int __devinit snd_intel8x0m_create(snd_card_t * card,
chip->remap_bmaddr = ioremap_nocache(chip->bmaddr,
pci_resource_len(pci, 3));
if (chip->remap_bmaddr == NULL) {
- snd_printk("Controller space ioremap problem\n");
+ snd_printk(KERN_ERR "Controller space ioremap problem\n");
snd_intel8x0_free(chip);
return -EIO;
}
@@ -1165,7 +1165,7 @@ static int __devinit snd_intel8x0m_create(snd_card_t * card,
port_inited:
if (request_irq(pci->irq, snd_intel8x0_interrupt, SA_INTERRUPT|SA_SHIRQ, card->shortname, (void *)chip)) {
- snd_printk("unable to grab IRQ %d\n", pci->irq);
+ snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
snd_intel8x0_free(chip);
return -EBUSY;
}
@@ -1263,20 +1263,12 @@ static struct shortname_table {
static int __devinit snd_intel8x0m_probe(struct pci_dev *pci,
const struct pci_device_id *pci_id)
{
- static int dev;
snd_card_t *card;
intel8x0_t *chip;
int err;
struct shortname_table *name;
- if (dev >= SNDRV_CARDS)
- return -ENODEV;
- if (!enable[dev]) {
- dev++;
- return -ENOENT;
- }
-
- card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
+ card = snd_card_new(index, id, THIS_MODULE, 0);
if (card == NULL)
return -ENOMEM;
@@ -1295,7 +1287,7 @@ static int __devinit snd_intel8x0m_probe(struct pci_dev *pci,
return err;
}
- if ((err = snd_intel8x0_mixer(chip, ac97_clock[dev])) < 0) {
+ if ((err = snd_intel8x0_mixer(chip, ac97_clock)) < 0) {
snd_card_free(card);
return err;
}
@@ -1314,7 +1306,6 @@ static int __devinit snd_intel8x0m_probe(struct pci_dev *pci,
return err;
}
pci_set_drvdata(pci, card);
- dev++;
return 0;
}
@@ -1326,7 +1317,6 @@ static void __devexit snd_intel8x0m_remove(struct pci_dev *pci)
static struct pci_driver driver = {
.name = "Intel ICH Modem",
- .owner = THIS_MODULE,
.id_table = snd_intel8x0m_ids,
.probe = snd_intel8x0m_probe,
.remove = __devexit_p(snd_intel8x0m_remove),
diff --git a/sound/pci/korg1212/korg1212.c b/sound/pci/korg1212/korg1212.c
index 5561fd4091e8..a110d664f626 100644
--- a/sound/pci/korg1212/korg1212.c
+++ b/sound/pci/korg1212/korg1212.c
@@ -2534,7 +2534,6 @@ static void __devexit snd_korg1212_remove(struct pci_dev *pci)
static struct pci_driver driver = {
.name = "korg1212",
- .owner = THIS_MODULE,
.id_table = snd_korg1212_ids,
.probe = snd_korg1212_probe,
.remove = __devexit_p(snd_korg1212_remove),
diff --git a/sound/pci/maestro3.c b/sound/pci/maestro3.c
index 2693b6f731f3..ede7a75bfe08 100644
--- a/sound/pci/maestro3.c
+++ b/sound/pci/maestro3.c
@@ -1492,7 +1492,7 @@ static int snd_m3_pcm_hw_params(snd_pcm_substream_t * substream,
/* set buffer address */
s->buffer_addr = substream->runtime->dma_addr;
if (s->buffer_addr & 0x3) {
- snd_printk("oh my, not aligned\n");
+ snd_printk(KERN_ERR "oh my, not aligned\n");
s->buffer_addr = s->buffer_addr & ~0x3;
}
return 0;
@@ -1942,7 +1942,7 @@ static int snd_m3_ac97_wait(m3_t *chip)
return 0;
} while (i-- > 0);
- snd_printk("ac97 serial bus busy\n");
+ snd_printk(KERN_ERR "ac97 serial bus busy\n");
return 1;
}
@@ -2046,8 +2046,7 @@ static void snd_m3_ac97_reset(m3_t *chip)
outw(0, io + GPIO_DATA);
outw(dir | GPO_PRIMARY_AC97, io + GPIO_DIRECTION);
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout((delay1 * HZ) / 1000);
+ schedule_timeout_uninterruptible(msecs_to_jiffies(delay1));
outw(GPO_PRIMARY_AC97, io + GPIO_DATA);
udelay(5);
@@ -2055,8 +2054,7 @@ static void snd_m3_ac97_reset(m3_t *chip)
outw(IO_SRAM_ENABLE | SERIAL_AC_LINK_ENABLE, io + RING_BUS_CTRL_A);
outw(~0, io + GPIO_MASK);
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout((delay2 * HZ) / 1000);
+ schedule_timeout_uninterruptible(msecs_to_jiffies(delay2));
if (! snd_m3_try_read_vendor(chip))
break;
@@ -2101,8 +2099,7 @@ static int __devinit snd_m3_mixer(m3_t *chip)
/* seems ac97 PCM needs initialization.. hack hack.. */
snd_ac97_write(chip->ac97, AC97_PCM, 0x8000 | (15 << 8) | 15);
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(HZ / 10);
+ schedule_timeout_uninterruptible(msecs_to_jiffies(100));
snd_ac97_write(chip->ac97, AC97_PCM, 0);
memset(&id, 0, sizeof(id));
@@ -2367,7 +2364,7 @@ static int __devinit snd_m3_assp_client_init(m3_t *chip, m3_dma_t *s, int index)
address = 0x1100 + ((data_bytes/2) * index);
if ((address + (data_bytes/2)) >= 0x1c00) {
- snd_printk("no memory for %d bytes at ind %d (addr 0x%x)\n",
+ snd_printk(KERN_ERR "no memory for %d bytes at ind %d (addr 0x%x)\n",
data_bytes, index, address);
return -ENOMEM;
}
@@ -2476,6 +2473,7 @@ snd_m3_chip_init(m3_t *chip)
t |= ASSP_0_WS_ENABLE;
outb(t, chip->iobase + ASSP_CONTROL_A);
+ snd_m3_assp_init(chip); /* download DSP code before starting ASSP below */
outb(RUN_ASSP, chip->iobase + ASSP_CONTROL_B);
outb(0x00, io + HARDWARE_VOL_CTRL);
@@ -2655,7 +2653,7 @@ snd_m3_create(snd_card_t *card, struct pci_dev *pci,
/* check, if we can restrict PCI DMA transfers to 28 bits */
if (pci_set_dma_mask(pci, 0x0fffffff) < 0 ||
pci_set_consistent_dma_mask(pci, 0x0fffffff) < 0) {
- snd_printk("architecture does not support 28bit PCI busmaster DMA\n");
+ snd_printk(KERN_ERR "architecture does not support 28bit PCI busmaster DMA\n");
pci_disable_device(pci);
return -ENXIO;
}
@@ -2734,14 +2732,13 @@ snd_m3_create(snd_card_t *card, struct pci_dev *pci,
snd_m3_ac97_reset(chip);
- snd_m3_assp_init(chip);
snd_m3_amp_enable(chip, 1);
tasklet_init(&chip->hwvol_tq, snd_m3_update_hw_volume, (unsigned long)chip);
if (request_irq(pci->irq, snd_m3_interrupt, SA_INTERRUPT|SA_SHIRQ,
card->driver, (void *)chip)) {
- snd_printk("unable to grab IRQ %d\n", pci->irq);
+ snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
snd_m3_free(chip);
return -ENOMEM;
}
@@ -2861,7 +2858,6 @@ static void __devexit snd_m3_remove(struct pci_dev *pci)
static struct pci_driver driver = {
.name = "Maestro3",
- .owner = THIS_MODULE,
.id_table = snd_m3_ids,
.probe = snd_m3_probe,
.remove = __devexit_p(snd_m3_remove),
diff --git a/sound/pci/mixart/mixart.c b/sound/pci/mixart/mixart.c
index 1a62c7f6c52b..b3090a13edab 100644
--- a/sound/pci/mixart/mixart.c
+++ b/sound/pci/mixart/mixart.c
@@ -451,8 +451,7 @@ static int mixart_sync_nonblock_events(mixart_mgr_t *mgr)
snd_printk(KERN_ERR "mixart: cannot process nonblock events!\n");
return -EBUSY;
}
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(1);
+ schedule_timeout_uninterruptible(1);
}
return 0;
}
@@ -1424,7 +1423,6 @@ static void __devexit snd_mixart_remove(struct pci_dev *pci)
static struct pci_driver driver = {
.name = "Digigram miXart",
- .owner = THIS_MODULE,
.id_table = snd_mixart_ids,
.probe = snd_mixart_probe,
.remove = __devexit_p(snd_mixart_remove),
diff --git a/sound/pci/nm256/nm256.c b/sound/pci/nm256/nm256.c
index 5c55a3b1d121..089d23b4a002 100644
--- a/sound/pci/nm256/nm256.c
+++ b/sound/pci/nm256/nm256.c
@@ -52,37 +52,43 @@ MODULE_SUPPORTED_DEVICE("{{NeoMagic,NM256AV},"
* some compile conditions.
*/
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
-static int playback_bufsize[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 16};
-static int capture_bufsize[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 16};
-static int force_ac97[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0}; /* disabled as default */
-static int buffer_top[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0}; /* not specified */
-static int use_cache[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0}; /* disabled */
-static int vaio_hack[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0}; /* disabled */
-static int reset_workaround[SNDRV_CARDS];
-
-module_param_array(index, int, NULL, 0444);
+static int index = SNDRV_DEFAULT_IDX1; /* Index */
+static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */
+static int playback_bufsize = 16;
+static int capture_bufsize = 16;
+static int force_ac97; /* disabled as default */
+static int buffer_top; /* not specified */
+static int use_cache; /* disabled */
+static int vaio_hack; /* disabled */
+static int reset_workaround;
+static int reset_workaround_2;
+
+module_param(index, int, 0444);
MODULE_PARM_DESC(index, "Index value for " CARD_NAME " soundcard.");
-module_param_array(id, charp, NULL, 0444);
+module_param(id, charp, 0444);
MODULE_PARM_DESC(id, "ID string for " CARD_NAME " soundcard.");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable this soundcard.");
-module_param_array(playback_bufsize, int, NULL, 0444);
+module_param(playback_bufsize, int, 0444);
MODULE_PARM_DESC(playback_bufsize, "DAC frame size in kB for " CARD_NAME " soundcard.");
-module_param_array(capture_bufsize, int, NULL, 0444);
+module_param(capture_bufsize, int, 0444);
MODULE_PARM_DESC(capture_bufsize, "ADC frame size in kB for " CARD_NAME " soundcard.");
-module_param_array(force_ac97, bool, NULL, 0444);
+module_param(force_ac97, bool, 0444);
MODULE_PARM_DESC(force_ac97, "Force to use AC97 codec for " CARD_NAME " soundcard.");
-module_param_array(buffer_top, int, NULL, 0444);
+module_param(buffer_top, int, 0444);
MODULE_PARM_DESC(buffer_top, "Set the top address of audio buffer for " CARD_NAME " soundcard.");
-module_param_array(use_cache, bool, NULL, 0444);
+module_param(use_cache, bool, 0444);
MODULE_PARM_DESC(use_cache, "Enable the cache for coefficient table access.");
-module_param_array(vaio_hack, bool, NULL, 0444);
+module_param(vaio_hack, bool, 0444);
MODULE_PARM_DESC(vaio_hack, "Enable workaround for Sony VAIO notebooks.");
-module_param_array(reset_workaround, bool, NULL, 0444);
+module_param(reset_workaround, bool, 0444);
MODULE_PARM_DESC(reset_workaround, "Enable AC97 RESET workaround for some laptops.");
+module_param(reset_workaround_2, bool, 0444);
+MODULE_PARM_DESC(reset_workaround_2, "Enable extended AC97 RESET workaround for some other laptops.");
+
+/* just for backward compatibility */
+static int enable;
+module_param(enable, bool, 0444);
+
+
/*
* hw definitions
@@ -226,6 +232,7 @@ struct snd_nm256 {
unsigned int coeffs_current: 1; /* coeff. table is loaded? */
unsigned int use_cache: 1; /* use one big coef. table */
unsigned int reset_workaround: 1; /* Workaround for some laptops to avoid freeze */
+ unsigned int reset_workaround_2: 1; /* Extended workaround for some other laptops to avoid freeze */
int mixer_base; /* register offset of ac97 mixer */
int mixer_status_offset; /* offset of mixer status reg. */
@@ -313,9 +320,9 @@ static inline void
snd_nm256_write_buffer(nm256_t *chip, void *src, int offset, int size)
{
offset -= chip->buffer_start;
-#ifdef SNDRV_CONFIG_DEBUG
+#ifdef CONFIG_SND_DEBUG
if (offset < 0 || offset >= chip->buffer_size) {
- snd_printk("write_buffer invalid offset = %d size = %d\n", offset, size);
+ snd_printk(KERN_ERR "write_buffer invalid offset = %d size = %d\n", offset, size);
return;
}
#endif
@@ -459,7 +466,7 @@ static int snd_nm256_acquire_irq(nm256_t *chip)
if (chip->irq < 0) {
if (request_irq(chip->pci->irq, chip->interrupt, SA_INTERRUPT|SA_SHIRQ,
chip->card->driver, (void*)chip)) {
- snd_printk("unable to grab IRQ %d\n", chip->pci->irq);
+ snd_printk(KERN_ERR "unable to grab IRQ %d\n", chip->pci->irq);
up(&chip->irq_mutex);
return -EBUSY;
}
@@ -1199,8 +1206,11 @@ snd_nm256_ac97_reset(ac97_t *ac97)
/* Dell latitude LS will lock up by this */
snd_nm256_writeb(chip, 0x6cc, 0x87);
}
- snd_nm256_writeb(chip, 0x6cc, 0x80);
- snd_nm256_writeb(chip, 0x6cc, 0x0);
+ if (! chip->reset_workaround_2) {
+ /* Dell latitude CSx will lock up by this */
+ snd_nm256_writeb(chip, 0x6cc, 0x80);
+ snd_nm256_writeb(chip, 0x6cc, 0x0);
+ }
}
/* create an ac97 mixer interface */
@@ -1263,7 +1273,7 @@ snd_nm256_peek_for_sig(nm256_t *chip)
temp = ioremap_nocache(chip->buffer_addr + chip->buffer_end - 0x400, 16);
if (temp == NULL) {
- snd_printk("Unable to scan for card signature in video RAM\n");
+ snd_printk(KERN_ERR "Unable to scan for card signature in video RAM\n");
return -EBUSY;
}
@@ -1277,7 +1287,7 @@ snd_nm256_peek_for_sig(nm256_t *chip)
if (pointer == 0xffffffff ||
pointer < chip->buffer_size ||
pointer > chip->buffer_end) {
- snd_printk("invalid signature found: 0x%x\n", pointer);
+ snd_printk(KERN_ERR "invalid signature found: 0x%x\n", pointer);
iounmap(temp);
return -ENODEV;
} else {
@@ -1347,14 +1357,8 @@ static int snd_nm256_free(nm256_t *chip)
iounmap(chip->cport);
if (chip->buffer)
iounmap(chip->buffer);
- if (chip->res_cport) {
- release_resource(chip->res_cport);
- kfree_nocheck(chip->res_cport);
- }
- if (chip->res_buffer) {
- release_resource(chip->res_buffer);
- kfree_nocheck(chip->res_buffer);
- }
+ release_and_free_resource(chip->res_cport);
+ release_and_free_resource(chip->res_buffer);
if (chip->irq >= 0)
free_irq(chip->irq, (void*)chip);
@@ -1420,14 +1424,14 @@ snd_nm256_create(snd_card_t *card, struct pci_dev *pci,
chip->res_cport = request_mem_region(chip->cport_addr, NM_PORT2_SIZE,
card->driver);
if (chip->res_cport == NULL) {
- snd_printk("memory region 0x%lx (size 0x%x) busy\n",
+ snd_printk(KERN_ERR "memory region 0x%lx (size 0x%x) busy\n",
chip->cport_addr, NM_PORT2_SIZE);
err = -EBUSY;
goto __error;
}
chip->cport = ioremap_nocache(chip->cport_addr, NM_PORT2_SIZE);
if (chip->cport == NULL) {
- snd_printk("unable to map control port %lx\n", chip->cport_addr);
+ snd_printk(KERN_ERR "unable to map control port %lx\n", chip->cport_addr);
err = -ENOMEM;
goto __error;
}
@@ -1485,7 +1489,7 @@ snd_nm256_create(snd_card_t *card, struct pci_dev *pci,
chip->buffer_size,
card->driver);
if (chip->res_buffer == NULL) {
- snd_printk("nm256: buffer 0x%lx (size 0x%x) busy\n",
+ snd_printk(KERN_ERR "nm256: buffer 0x%lx (size 0x%x) busy\n",
chip->buffer_addr, chip->buffer_size);
err = -EBUSY;
goto __error;
@@ -1493,7 +1497,7 @@ snd_nm256_create(snd_card_t *card, struct pci_dev *pci,
chip->buffer = ioremap_nocache(chip->buffer_addr, chip->buffer_size);
if (chip->buffer == NULL) {
err = -ENOMEM;
- snd_printk("unable to map ring buffer at %lx\n", chip->buffer_addr);
+ snd_printk(KERN_ERR "unable to map ring buffer at %lx\n", chip->buffer_addr);
goto __error;
}
@@ -1542,7 +1546,7 @@ struct nm256_quirk {
int type;
};
-enum { NM_BLACKLISTED, NM_RESET_WORKAROUND };
+enum { NM_BLACKLISTED, NM_RESET_WORKAROUND, NM_RESET_WORKAROUND_2 };
static struct nm256_quirk nm256_quirks[] __devinitdata = {
/* HP omnibook 4150 has cs4232 codec internally */
@@ -1551,6 +1555,8 @@ static struct nm256_quirk nm256_quirks[] __devinitdata = {
{ .vendor = 0x104d, .device = 0x8041, .type = NM_RESET_WORKAROUND },
/* Dell Latitude LS */
{ .vendor = 0x1028, .device = 0x0080, .type = NM_RESET_WORKAROUND },
+ /* Dell Latitude CSx */
+ { .vendor = 0x1028, .device = 0x0091, .type = NM_RESET_WORKAROUND_2 },
{ } /* terminator */
};
@@ -1558,7 +1564,6 @@ static struct nm256_quirk nm256_quirks[] __devinitdata = {
static int __devinit snd_nm256_probe(struct pci_dev *pci,
const struct pci_device_id *pci_id)
{
- static int dev;
snd_card_t *card;
nm256_t *chip;
int err;
@@ -1566,13 +1571,6 @@ static int __devinit snd_nm256_probe(struct pci_dev *pci,
struct nm256_quirk *q;
u16 subsystem_vendor, subsystem_device;
- if (dev >= SNDRV_CARDS)
- return -ENODEV;
- if (!enable[dev]) {
- dev++;
- return -ENOENT;
- }
-
pci_read_config_word(pci, PCI_SUBSYSTEM_VENDOR_ID, &subsystem_vendor);
pci_read_config_word(pci, PCI_SUBSYSTEM_ID, &subsystem_device);
@@ -1582,14 +1580,17 @@ static int __devinit snd_nm256_probe(struct pci_dev *pci,
case NM_BLACKLISTED:
printk(KERN_INFO "nm256: The device is blacklisted. Loading stopped\n");
return -ENODEV;
+ case NM_RESET_WORKAROUND_2:
+ reset_workaround_2 = 1;
+ /* Fall-through */
case NM_RESET_WORKAROUND:
- reset_workaround[dev] = 1;
+ reset_workaround = 1;
break;
}
}
}
- card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
+ card = snd_card_new(index, id, THIS_MODULE, 0);
if (card == NULL)
return -ENOMEM;
@@ -1604,40 +1605,45 @@ static int __devinit snd_nm256_probe(struct pci_dev *pci,
strcpy(card->driver, "NM256XL+");
break;
default:
- snd_printk("invalid device id 0x%x\n", pci->device);
+ snd_printk(KERN_ERR "invalid device id 0x%x\n", pci->device);
snd_card_free(card);
return -EINVAL;
}
- if (vaio_hack[dev])
+ if (vaio_hack)
xbuffer_top = 0x25a800; /* this avoids conflicts with XFree86 server */
else
- xbuffer_top = buffer_top[dev];
-
- if (playback_bufsize[dev] < 4)
- playback_bufsize[dev] = 4;
- if (playback_bufsize[dev] > 128)
- playback_bufsize[dev] = 128;
- if (capture_bufsize[dev] < 4)
- capture_bufsize[dev] = 4;
- if (capture_bufsize[dev] > 128)
- capture_bufsize[dev] = 128;
+ xbuffer_top = buffer_top;
+
+ if (playback_bufsize < 4)
+ playback_bufsize = 4;
+ if (playback_bufsize > 128)
+ playback_bufsize = 128;
+ if (capture_bufsize < 4)
+ capture_bufsize = 4;
+ if (capture_bufsize > 128)
+ capture_bufsize = 128;
if ((err = snd_nm256_create(card, pci,
- playback_bufsize[dev] * 1024, /* in bytes */
- capture_bufsize[dev] * 1024, /* in bytes */
- force_ac97[dev],
+ playback_bufsize * 1024, /* in bytes */
+ capture_bufsize * 1024, /* in bytes */
+ force_ac97,
xbuffer_top,
- use_cache[dev],
+ use_cache,
&chip)) < 0) {
snd_card_free(card);
return err;
}
- if (reset_workaround[dev]) {
+ if (reset_workaround) {
snd_printdd(KERN_INFO "nm256: reset_workaround activated\n");
chip->reset_workaround = 1;
}
+ if (reset_workaround_2) {
+ snd_printdd(KERN_INFO "nm256: reset_workaround_2 activated\n");
+ chip->reset_workaround_2 = 1;
+ }
+
if ((err = snd_nm256_pcm(chip, 0)) < 0 ||
(err = snd_nm256_mixer(chip)) < 0) {
snd_card_free(card);
@@ -1655,7 +1661,6 @@ static int __devinit snd_nm256_probe(struct pci_dev *pci,
}
pci_set_drvdata(pci, card);
- dev++;
return 0;
}
@@ -1668,7 +1673,6 @@ static void __devexit snd_nm256_remove(struct pci_dev *pci)
static struct pci_driver driver = {
.name = "NeoMagic 256",
- .owner = THIS_MODULE,
.id_table = snd_nm256_ids,
.probe = snd_nm256_probe,
.remove = __devexit_p(snd_nm256_remove),
diff --git a/sound/pci/rme32.c b/sound/pci/rme32.c
index cd313af6ebcf..783df7625c1c 100644
--- a/sound/pci/rme32.c
+++ b/sound/pci/rme32.c
@@ -1369,13 +1369,13 @@ static int __devinit snd_rme32_create(rme32_t * rme32)
rme32->port = pci_resource_start(rme32->pci, 0);
if (request_irq(pci->irq, snd_rme32_interrupt, SA_INTERRUPT | SA_SHIRQ, "RME32", (void *) rme32)) {
- snd_printk("unable to grab IRQ %d\n", pci->irq);
+ snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
return -EBUSY;
}
rme32->irq = pci->irq;
if ((rme32->iobase = ioremap_nocache(rme32->port, RME32_IO_SIZE)) == 0) {
- snd_printk("unable to remap memory region 0x%lx-0x%lx\n",
+ snd_printk(KERN_ERR "unable to remap memory region 0x%lx-0x%lx\n",
rme32->port, rme32->port + RME32_IO_SIZE - 1);
return -ENOMEM;
}
@@ -2012,7 +2012,6 @@ static void __devexit snd_rme32_remove(struct pci_dev *pci)
static struct pci_driver driver = {
.name = "RME Digi32",
- .owner = THIS_MODULE,
.id_table = snd_rme32_ids,
.probe = snd_rme32_probe,
.remove = __devexit_p(snd_rme32_remove),
diff --git a/sound/pci/rme96.c b/sound/pci/rme96.c
index c495cae78dbf..6d422ef64999 100644
--- a/sound/pci/rme96.c
+++ b/sound/pci/rme96.c
@@ -1570,13 +1570,13 @@ snd_rme96_create(rme96_t *rme96)
rme96->port = pci_resource_start(rme96->pci, 0);
if (request_irq(pci->irq, snd_rme96_interrupt, SA_INTERRUPT|SA_SHIRQ, "RME96", (void *)rme96)) {
- snd_printk("unable to grab IRQ %d\n", pci->irq);
+ snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
return -EBUSY;
}
rme96->irq = pci->irq;
if ((rme96->iobase = ioremap_nocache(rme96->port, RME96_IO_SIZE)) == 0) {
- snd_printk("unable to remap memory region 0x%lx-0x%lx\n", rme96->port, rme96->port + RME96_IO_SIZE - 1);
+ snd_printk(KERN_ERR "unable to remap memory region 0x%lx-0x%lx\n", rme96->port, rme96->port + RME96_IO_SIZE - 1);
return -ENOMEM;
}
@@ -2413,7 +2413,6 @@ static void __devexit snd_rme96_remove(struct pci_dev *pci)
static struct pci_driver driver = {
.name = "RME Digi96",
- .owner = THIS_MODULE,
.id_table = snd_rme96_ids,
.probe = snd_rme96_probe,
.remove = __devexit_p(snd_rme96_remove),
diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c
index 52525eb198c7..d15ffb3e9b0a 100644
--- a/sound/pci/rme9652/hdsp.c
+++ b/sound/pci/rme9652/hdsp.c
@@ -671,11 +671,7 @@ static int snd_hdsp_load_firmware_from_cache(hdsp_t *hdsp) {
}
}
- if ((1000 / HZ) < 3000) {
- ssleep(3);
- } else {
- mdelay(3000);
- }
+ ssleep(3);
if (hdsp_fifo_wait (hdsp, 0, HDSP_LONG_WAIT)) {
snd_printk ("Hammerfall-DSP: timeout at end of firmware loading\n");
@@ -692,7 +688,7 @@ static int snd_hdsp_load_firmware_from_cache(hdsp_t *hdsp) {
}
if (hdsp->state & HDSP_InitializationComplete) {
- snd_printk("Hammerfall-DSP: firmware loaded from cache, restoring defaults\n");
+ snd_printk(KERN_INFO "Hammerfall-DSP: firmware loaded from cache, restoring defaults\n");
spin_lock_irqsave(&hdsp->lock, flags);
snd_hdsp_set_defaults(hdsp);
spin_unlock_irqrestore(&hdsp->lock, flags);
@@ -709,9 +705,8 @@ static int hdsp_get_iobox_version (hdsp_t *hdsp)
hdsp_write (hdsp, HDSP_control2Reg, HDSP_PROGRAM);
hdsp_write (hdsp, HDSP_fifoData, 0);
- if (hdsp_fifo_wait (hdsp, 0, HDSP_SHORT_WAIT) < 0) {
+ if (hdsp_fifo_wait (hdsp, 0, HDSP_SHORT_WAIT) < 0)
return -EIO;
- }
hdsp_write (hdsp, HDSP_control2Reg, HDSP_S_LOAD);
hdsp_write (hdsp, HDSP_fifoData, 0);
@@ -726,22 +721,30 @@ static int hdsp_get_iobox_version (hdsp_t *hdsp)
}
} else {
/* firmware was already loaded, get iobox type */
- if (hdsp_read(hdsp, HDSP_status2Register) & HDSP_version1) {
+ if (hdsp_read(hdsp, HDSP_status2Register) & HDSP_version1)
hdsp->io_type = Multiface;
- } else {
+ else
hdsp->io_type = Digiface;
- }
}
return 0;
}
-static int hdsp_check_for_firmware (hdsp_t *hdsp)
+static int hdsp_check_for_firmware (hdsp_t *hdsp, int show_err)
{
if (hdsp->io_type == H9652 || hdsp->io_type == H9632) return 0;
if ((hdsp_read (hdsp, HDSP_statusRegister) & HDSP_DllError) != 0) {
- snd_printk("Hammerfall-DSP: firmware not present.\n");
+ snd_printk(KERN_ERR "Hammerfall-DSP: firmware not present.\n");
hdsp->state &= ~HDSP_FirmwareLoaded;
+ if (! show_err)
+ return -EIO;
+ /* try to load firmware */
+ if (hdsp->state & HDSP_FirmwareCached) {
+ if (snd_hdsp_load_firmware_from_cache(hdsp) != 0)
+ snd_printk(KERN_ERR "Hammerfall-DSP: Firmware loading from cache failed, please upload manually.\n");
+ } else {
+ snd_printk(KERN_ERR "Hammerfall-DSP: No firmware loaded nor cached, please upload firmware.\n");
+ }
return -EIO;
}
return 0;
@@ -775,9 +778,9 @@ static int hdsp_fifo_wait(hdsp_t *hdsp, int count, int timeout)
static int hdsp_read_gain (hdsp_t *hdsp, unsigned int addr)
{
- if (addr >= HDSP_MATRIX_MIXER_SIZE) {
+ if (addr >= HDSP_MATRIX_MIXER_SIZE)
return 0;
- }
+
return hdsp->mixer_matrix[addr];
}
@@ -802,13 +805,11 @@ static int hdsp_write_gain(hdsp_t *hdsp, unsigned int addr, unsigned short data)
memory."
*/
- if (hdsp->io_type == H9632 && addr >= 512) {
+ if (hdsp->io_type == H9632 && addr >= 512)
return 0;
- }
- if (hdsp->io_type == H9652 && addr >= 1352) {
+ if (hdsp->io_type == H9652 && addr >= 1352)
return 0;
- }
hdsp->mixer_matrix[addr] = data;
@@ -832,9 +833,8 @@ static int hdsp_write_gain(hdsp_t *hdsp, unsigned int addr, unsigned short data)
ad = (addr << 16) + data;
- if (hdsp_fifo_wait(hdsp, 127, HDSP_LONG_WAIT)) {
+ if (hdsp_fifo_wait(hdsp, 127, HDSP_LONG_WAIT))
return -1;
- }
hdsp_write (hdsp, HDSP_fifoData, ad);
hdsp->mixer_matrix[addr] = data;
@@ -851,9 +851,8 @@ static int snd_hdsp_use_is_exclusive(hdsp_t *hdsp)
spin_lock_irqsave(&hdsp->lock, flags);
if ((hdsp->playback_pid != hdsp->capture_pid) &&
- (hdsp->playback_pid >= 0) && (hdsp->capture_pid >= 0)) {
+ (hdsp->playback_pid >= 0) && (hdsp->capture_pid >= 0))
ret = 0;
- }
spin_unlock_irqrestore(&hdsp->lock, flags);
return ret;
}
@@ -880,9 +879,8 @@ static int hdsp_spdif_sample_rate(hdsp_t *hdsp)
unsigned int status = hdsp_read(hdsp, HDSP_statusRegister);
unsigned int rate_bits = (status & HDSP_spdifFrequencyMask);
- if (status & HDSP_SPDIFErrorFlag) {
+ if (status & HDSP_SPDIFErrorFlag)
return 0;
- }
switch (rate_bits) {
case HDSP_spdifFrequency32KHz: return 32000;
@@ -918,9 +916,8 @@ static snd_pcm_uframes_t hdsp_hw_pointer(hdsp_t *hdsp)
position = hdsp_read(hdsp, HDSP_statusRegister);
- if (!hdsp->precise_ptr) {
+ if (!hdsp->precise_ptr)
return (position & HDSP_BufferID) ? (hdsp->period_bytes / 4) : 0;
- }
position &= HDSP_BufferPositionMask;
position /= 4;
@@ -989,19 +986,19 @@ static int hdsp_set_rate(hdsp_t *hdsp, int rate, int called_internally)
if (!(hdsp->control_register & HDSP_ClockModeMaster)) {
if (called_internally) {
/* request from ctl or card initialization */
- snd_printk("Hammerfall-DSP: device is not running as a clock master: cannot set sample rate.\n");
+ snd_printk(KERN_ERR "Hammerfall-DSP: device is not running as a clock master: cannot set sample rate.\n");
return -1;
} else {
/* hw_param request while in AutoSync mode */
int external_freq = hdsp_external_sample_rate(hdsp);
int spdif_freq = hdsp_spdif_sample_rate(hdsp);
- if ((spdif_freq == external_freq*2) && (hdsp_autosync_ref(hdsp) >= HDSP_AUTOSYNC_FROM_ADAT1)) {
- snd_printk("Hammerfall-DSP: Detected ADAT in double speed mode\n");
- } else if (hdsp->io_type == H9632 && (spdif_freq == external_freq*4) && (hdsp_autosync_ref(hdsp) >= HDSP_AUTOSYNC_FROM_ADAT1)) {
- snd_printk("Hammerfall-DSP: Detected ADAT in quad speed mode\n");
- } else if (rate != external_freq) {
- snd_printk("Hammerfall-DSP: No AutoSync source for requested rate\n");
+ if ((spdif_freq == external_freq*2) && (hdsp_autosync_ref(hdsp) >= HDSP_AUTOSYNC_FROM_ADAT1))
+ snd_printk(KERN_INFO "Hammerfall-DSP: Detected ADAT in double speed mode\n");
+ else if (hdsp->io_type == H9632 && (spdif_freq == external_freq*4) && (hdsp_autosync_ref(hdsp) >= HDSP_AUTOSYNC_FROM_ADAT1))
+ snd_printk(KERN_INFO "Hammerfall-DSP: Detected ADAT in quad speed mode\n");
+ else if (rate != external_freq) {
+ snd_printk(KERN_INFO "Hammerfall-DSP: No AutoSync source for requested rate\n");
return -1;
}
}
@@ -1019,63 +1016,53 @@ static int hdsp_set_rate(hdsp_t *hdsp, int rate, int called_internally)
exists for externally-driven rate changes. All we can do
is to flag rate changes in the read/write routines. */
- if (rate > 96000 && hdsp->io_type != H9632) {
+ if (rate > 96000 && hdsp->io_type != H9632)
return -EINVAL;
- }
switch (rate) {
case 32000:
- if (current_rate > 48000) {
+ if (current_rate > 48000)
reject_if_open = 1;
- }
rate_bits = HDSP_Frequency32KHz;
break;
case 44100:
- if (current_rate > 48000) {
+ if (current_rate > 48000)
reject_if_open = 1;
- }
rate_bits = HDSP_Frequency44_1KHz;
break;
case 48000:
- if (current_rate > 48000) {
+ if (current_rate > 48000)
reject_if_open = 1;
- }
rate_bits = HDSP_Frequency48KHz;
break;
case 64000:
- if (current_rate <= 48000 || current_rate > 96000) {
+ if (current_rate <= 48000 || current_rate > 96000)
reject_if_open = 1;
- }
rate_bits = HDSP_Frequency64KHz;
break;
case 88200:
- if (current_rate <= 48000 || current_rate > 96000) {
+ if (current_rate <= 48000 || current_rate > 96000)
reject_if_open = 1;
- }
rate_bits = HDSP_Frequency88_2KHz;
break;
case 96000:
- if (current_rate <= 48000 || current_rate > 96000) {
+ if (current_rate <= 48000 || current_rate > 96000)
reject_if_open = 1;
- }
rate_bits = HDSP_Frequency96KHz;
break;
case 128000:
- if (current_rate < 128000) {
+ if (current_rate < 128000)
reject_if_open = 1;
- }
rate_bits = HDSP_Frequency128KHz;
break;
case 176400:
- if (current_rate < 128000) {
+ if (current_rate < 128000)
reject_if_open = 1;
- }
rate_bits = HDSP_Frequency176_4KHz;
break;
case 192000:
- if (current_rate < 128000) {
+ if (current_rate < 128000)
reject_if_open = 1;
- }
rate_bits = HDSP_Frequency192KHz;
break;
default:
@@ -1096,11 +1083,10 @@ static int hdsp_set_rate(hdsp_t *hdsp, int rate, int called_internally)
if (rate >= 128000) {
hdsp->channel_map = channel_map_H9632_qs;
} else if (rate > 48000) {
- if (hdsp->io_type == H9632) {
+ if (hdsp->io_type == H9632)
hdsp->channel_map = channel_map_H9632_ds;
- } else {
+ else
hdsp->channel_map = channel_map_ds;
- }
} else {
switch (hdsp->io_type) {
case Multiface:
@@ -1131,54 +1117,48 @@ static int hdsp_set_rate(hdsp_t *hdsp, int rate, int called_internally)
static unsigned char snd_hdsp_midi_read_byte (hdsp_t *hdsp, int id)
{
/* the hardware already does the relevant bit-mask with 0xff */
- if (id) {
+ if (id)
return hdsp_read(hdsp, HDSP_midiDataIn1);
- } else {
+ else
return hdsp_read(hdsp, HDSP_midiDataIn0);
- }
}
static void snd_hdsp_midi_write_byte (hdsp_t *hdsp, int id, int val)
{
/* the hardware already does the relevant bit-mask with 0xff */
- if (id) {
+ if (id)
hdsp_write(hdsp, HDSP_midiDataOut1, val);
- } else {
+ else
hdsp_write(hdsp, HDSP_midiDataOut0, val);
- }
}
static int snd_hdsp_midi_input_available (hdsp_t *hdsp, int id)
{
- if (id) {
+ if (id)
return (hdsp_read(hdsp, HDSP_midiStatusIn1) & 0xff);
- } else {
+ else
return (hdsp_read(hdsp, HDSP_midiStatusIn0) & 0xff);
- }
}
static int snd_hdsp_midi_output_possible (hdsp_t *hdsp, int id)
{
int fifo_bytes_used;
- if (id) {
+ if (id)
fifo_bytes_used = hdsp_read(hdsp, HDSP_midiStatusOut1) & 0xff;
- } else {
+ else
fifo_bytes_used = hdsp_read(hdsp, HDSP_midiStatusOut0) & 0xff;
- }
- if (fifo_bytes_used < 128) {
+ if (fifo_bytes_used < 128)
return 128 - fifo_bytes_used;
- } else {
+ else
return 0;
- }
}
static void snd_hdsp_flush_midi_input (hdsp_t *hdsp, int id)
{
- while (snd_hdsp_midi_input_available (hdsp, id)) {
+ while (snd_hdsp_midi_input_available (hdsp, id))
snd_hdsp_midi_read_byte (hdsp, id);
- }
}
static int snd_hdsp_midi_output_write (hdsp_midi_t *hmidi)
@@ -1219,28 +1199,23 @@ static int snd_hdsp_midi_input_read (hdsp_midi_t *hmidi)
spin_lock_irqsave (&hmidi->lock, flags);
if ((n_pending = snd_hdsp_midi_input_available (hmidi->hdsp, hmidi->id)) > 0) {
if (hmidi->input) {
- if (n_pending > (int)sizeof (buf)) {
+ if (n_pending > (int)sizeof (buf))
n_pending = sizeof (buf);
- }
- for (i = 0; i < n_pending; ++i) {
+ for (i = 0; i < n_pending; ++i)
buf[i] = snd_hdsp_midi_read_byte (hmidi->hdsp, hmidi->id);
- }
- if (n_pending) {
+ if (n_pending)
snd_rawmidi_receive (hmidi->input, buf, n_pending);
- }
} else {
/* flush the MIDI input FIFO */
- while (--n_pending) {
+ while (--n_pending)
snd_hdsp_midi_read_byte (hmidi->hdsp, hmidi->id);
- }
}
}
hmidi->pending = 0;
- if (hmidi->id) {
+ if (hmidi->id)
hmidi->hdsp->control_register |= HDSP_Midi1InterruptEnable;
- } else {
+ else
hmidi->hdsp->control_register |= HDSP_Midi0InterruptEnable;
- }
hdsp_write(hmidi->hdsp, HDSP_controlRegister, hmidi->hdsp->control_register);
spin_unlock_irqrestore (&hmidi->lock, flags);
return snd_hdsp_midi_output_write (hmidi);
@@ -1310,9 +1285,8 @@ static void snd_hdsp_midi_output_trigger(snd_rawmidi_substream_t * substream, in
hmidi->istimer++;
}
} else {
- if (hmidi->istimer && --hmidi->istimer <= 0) {
+ if (hmidi->istimer && --hmidi->istimer <= 0)
del_timer (&hmidi->timer);
- }
}
spin_unlock_irqrestore (&hmidi->lock, flags);
if (up)
@@ -1400,9 +1374,8 @@ static int __devinit snd_hdsp_create_midi (snd_card_t *card, hdsp_t *hdsp, int i
spin_lock_init (&hdsp->midi[id].lock);
sprintf (buf, "%s MIDI %d", card->shortname, id+1);
- if (snd_rawmidi_new (card, buf, id, 1, 1, &hdsp->midi[id].rmidi) < 0) {
+ if (snd_rawmidi_new (card, buf, id, 1, 1, &hdsp->midi[id].rmidi) < 0)
return -1;
- }
sprintf (hdsp->midi[id].rmidi->name, "%s MIDI %d", card->id, id+1);
hdsp->midi[id].rmidi->private_data = &hdsp->midi[id];
@@ -1588,11 +1561,10 @@ static int hdsp_spdif_out(hdsp_t *hdsp)
static int hdsp_set_spdif_output(hdsp_t *hdsp, int out)
{
- if (out) {
+ if (out)
hdsp->control_register |= HDSP_SPDIFOpticalOut;
- } else {
+ else
hdsp->control_register &= ~HDSP_SPDIFOpticalOut;
- }
hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
return 0;
}
@@ -1642,11 +1614,10 @@ static int hdsp_spdif_professional(hdsp_t *hdsp)
static int hdsp_set_spdif_professional(hdsp_t *hdsp, int val)
{
- if (val) {
+ if (val)
hdsp->control_register |= HDSP_SPDIFProfessional;
- } else {
+ else
hdsp->control_register &= ~HDSP_SPDIFProfessional;
- }
hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
return 0;
}
@@ -1687,11 +1658,10 @@ static int hdsp_spdif_emphasis(hdsp_t *hdsp)
static int hdsp_set_spdif_emphasis(hdsp_t *hdsp, int val)
{
- if (val) {
+ if (val)
hdsp->control_register |= HDSP_SPDIFEmphasis;
- } else {
+ else
hdsp->control_register &= ~HDSP_SPDIFEmphasis;
- }
hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
return 0;
}
@@ -1732,11 +1702,10 @@ static int hdsp_spdif_nonaudio(hdsp_t *hdsp)
static int hdsp_set_spdif_nonaudio(hdsp_t *hdsp, int val)
{
- if (val) {
+ if (val)
hdsp->control_register |= HDSP_SPDIFNonAudio;
- } else {
+ else
hdsp->control_register &= ~HDSP_SPDIFNonAudio;
- }
hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
return 0;
}
@@ -1921,11 +1890,10 @@ static int snd_hdsp_get_autosync_sample_rate(snd_kcontrol_t * kcontrol, snd_ctl_
static int hdsp_system_clock_mode(hdsp_t *hdsp)
{
- if (hdsp->control_register & HDSP_ClockModeMaster) {
+ if (hdsp->control_register & HDSP_ClockModeMaster)
return 0;
- } else if (hdsp_external_sample_rate(hdsp) != hdsp->system_sample_rate) {
+ else if (hdsp_external_sample_rate(hdsp) != hdsp->system_sample_rate)
return 0;
- }
return 1;
}
@@ -2074,16 +2042,17 @@ static int snd_hdsp_put_clock_source(snd_kcontrol_t * kcontrol, snd_ctl_elem_val
val = ucontrol->value.enumerated.item[0];
if (val < 0) val = 0;
if (hdsp->io_type == H9632) {
- if (val > 9) val = 9;
+ if (val > 9)
+ val = 9;
} else {
- if (val > 6) val = 6;
+ if (val > 6)
+ val = 6;
}
spin_lock_irq(&hdsp->lock);
- if (val != hdsp_clock_source(hdsp)) {
+ if (val != hdsp_clock_source(hdsp))
change = (hdsp_set_clock_source(hdsp, val) == 0) ? 1 : 0;
- } else {
+ else
change = 0;
- }
spin_unlock_irq(&hdsp->lock);
return change;
}
@@ -2193,11 +2162,10 @@ static int snd_hdsp_put_da_gain(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t
if (val < 0) val = 0;
if (val > 2) val = 2;
spin_lock_irq(&hdsp->lock);
- if (val != hdsp_da_gain(hdsp)) {
+ if (val != hdsp_da_gain(hdsp))
change = (hdsp_set_da_gain(hdsp, val) == 0) ? 1 : 0;
- } else {
+ else
change = 0;
- }
spin_unlock_irq(&hdsp->lock);
return change;
}
@@ -2279,11 +2247,10 @@ static int snd_hdsp_put_ad_gain(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t
if (val < 0) val = 0;
if (val > 2) val = 2;
spin_lock_irq(&hdsp->lock);
- if (val != hdsp_ad_gain(hdsp)) {
+ if (val != hdsp_ad_gain(hdsp))
change = (hdsp_set_ad_gain(hdsp, val) == 0) ? 1 : 0;
- } else {
+ else
change = 0;
- }
spin_unlock_irq(&hdsp->lock);
return change;
}
@@ -2365,11 +2332,10 @@ static int snd_hdsp_put_phone_gain(snd_kcontrol_t * kcontrol, snd_ctl_elem_value
if (val < 0) val = 0;
if (val > 2) val = 2;
spin_lock_irq(&hdsp->lock);
- if (val != hdsp_phone_gain(hdsp)) {
+ if (val != hdsp_phone_gain(hdsp))
change = (hdsp_set_phone_gain(hdsp, val) == 0) ? 1 : 0;
- } else {
+ else
change = 0;
- }
spin_unlock_irq(&hdsp->lock);
return change;
}
@@ -2385,19 +2351,17 @@ static int snd_hdsp_put_phone_gain(snd_kcontrol_t * kcontrol, snd_ctl_elem_value
static int hdsp_xlr_breakout_cable(hdsp_t *hdsp)
{
- if (hdsp->control_register & HDSP_XLRBreakoutCable) {
+ if (hdsp->control_register & HDSP_XLRBreakoutCable)
return 1;
- }
return 0;
}
static int hdsp_set_xlr_breakout_cable(hdsp_t *hdsp, int mode)
{
- if (mode) {
+ if (mode)
hdsp->control_register |= HDSP_XLRBreakoutCable;
- } else {
+ else
hdsp->control_register &= ~HDSP_XLRBreakoutCable;
- }
hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
return 0;
}
@@ -2450,19 +2414,17 @@ static int snd_hdsp_put_xlr_breakout_cable(snd_kcontrol_t * kcontrol, snd_ctl_el
static int hdsp_aeb(hdsp_t *hdsp)
{
- if (hdsp->control_register & HDSP_AnalogExtensionBoard) {
+ if (hdsp->control_register & HDSP_AnalogExtensionBoard)
return 1;
- }
return 0;
}
static int hdsp_set_aeb(hdsp_t *hdsp, int mode)
{
- if (mode) {
+ if (mode)
hdsp->control_register |= HDSP_AnalogExtensionBoard;
- } else {
+ else
hdsp->control_register &= ~HDSP_AnalogExtensionBoard;
- }
hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
return 0;
}
@@ -2705,11 +2667,10 @@ static int hdsp_line_out(hdsp_t *hdsp)
static int hdsp_set_line_output(hdsp_t *hdsp, int out)
{
- if (out) {
+ if (out)
hdsp->control_register |= HDSP_LineOut;
- } else {
+ else
hdsp->control_register &= ~HDSP_LineOut;
- }
hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
return 0;
}
@@ -2760,11 +2721,10 @@ static int snd_hdsp_put_line_out(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t
static int hdsp_set_precise_pointer(hdsp_t *hdsp, int precise)
{
- if (precise) {
+ if (precise)
hdsp->precise_ptr = 1;
- } else {
+ else
hdsp->precise_ptr = 0;
- }
return 0;
}
@@ -2814,11 +2774,10 @@ static int snd_hdsp_put_precise_pointer(snd_kcontrol_t * kcontrol, snd_ctl_elem_
static int hdsp_set_use_midi_tasklet(hdsp_t *hdsp, int use_tasklet)
{
- if (use_tasklet) {
+ if (use_tasklet)
hdsp->use_midi_tasklet = 1;
- } else {
+ else
hdsp->use_midi_tasklet = 0;
- }
return 0;
}
@@ -2889,11 +2848,10 @@ static int snd_hdsp_get_mixer(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *
source = ucontrol->value.integer.value[0];
destination = ucontrol->value.integer.value[1];
- if (source >= hdsp->max_channels) {
+ if (source >= hdsp->max_channels)
addr = hdsp_playback_to_output_key(hdsp,source-hdsp->max_channels,destination);
- } else {
+ else
addr = hdsp_input_to_output_key(hdsp,source, destination);
- }
spin_lock_irq(&hdsp->lock);
ucontrol->value.integer.value[2] = hdsp_read_gain (hdsp, addr);
@@ -2916,11 +2874,10 @@ static int snd_hdsp_put_mixer(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *
source = ucontrol->value.integer.value[0];
destination = ucontrol->value.integer.value[1];
- if (source >= hdsp->max_channels) {
+ if (source >= hdsp->max_channels)
addr = hdsp_playback_to_output_key(hdsp,source-hdsp->max_channels, destination);
- } else {
+ else
addr = hdsp_input_to_output_key(hdsp,source, destination);
- }
gain = ucontrol->value.integer.value[2];
@@ -2957,14 +2914,12 @@ static int hdsp_wc_sync_check(hdsp_t *hdsp)
{
int status2 = hdsp_read(hdsp, HDSP_status2Register);
if (status2 & HDSP_wc_lock) {
- if (status2 & HDSP_wc_sync) {
+ if (status2 & HDSP_wc_sync)
return 2;
- } else {
+ else
return 1;
- }
- } else {
+ } else
return 0;
- }
return 0;
}
@@ -2988,14 +2943,13 @@ static int snd_hdsp_get_wc_sync_check(snd_kcontrol_t * kcontrol, snd_ctl_elem_va
static int hdsp_spdif_sync_check(hdsp_t *hdsp)
{
int status = hdsp_read(hdsp, HDSP_statusRegister);
- if (status & HDSP_SPDIFErrorFlag) {
+ if (status & HDSP_SPDIFErrorFlag)
return 0;
- } else {
- if (status & HDSP_SPDIFSync) {
+ else {
+ if (status & HDSP_SPDIFSync)
return 2;
- } else {
+ else
return 1;
- }
}
return 0;
}
@@ -3021,14 +2975,12 @@ static int hdsp_adatsync_sync_check(hdsp_t *hdsp)
{
int status = hdsp_read(hdsp, HDSP_statusRegister);
if (status & HDSP_TimecodeLock) {
- if (status & HDSP_TimecodeSync) {
+ if (status & HDSP_TimecodeSync)
return 2;
- } else {
+ else
return 1;
- }
- } else {
+ } else
return 0;
- }
}
static int snd_hdsp_get_adatsync_sync_check(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
@@ -3051,14 +3003,12 @@ static int hdsp_adat_sync_check(hdsp_t *hdsp, int idx)
int status = hdsp_read(hdsp, HDSP_statusRegister);
if (status & (HDSP_Lock0>>idx)) {
- if (status & (HDSP_Sync0>>idx)) {
+ if (status & (HDSP_Sync0>>idx))
return 2;
- } else {
+ else
return 1;
- }
- } else {
+ } else
return 0;
- }
}
static int snd_hdsp_get_adat_sync_check(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
@@ -3171,9 +3121,8 @@ static int snd_hdsp_create_controls(snd_card_t *card, hdsp_t *hdsp)
snd_kcontrol_t *kctl;
for (idx = 0; idx < ARRAY_SIZE(snd_hdsp_controls); idx++) {
- if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_hdsp_controls[idx], hdsp))) < 0) {
+ if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_hdsp_controls[idx], hdsp))) < 0)
return err;
- }
if (idx == 1) /* IEC958 (S/PDIF) Stream */
hdsp->spdif_ctl = kctl;
}
@@ -3181,32 +3130,28 @@ static int snd_hdsp_create_controls(snd_card_t *card, hdsp_t *hdsp)
/* ADAT SyncCheck status */
snd_hdsp_adat_sync_check.name = "ADAT Lock Status";
snd_hdsp_adat_sync_check.index = 1;
- if ((err = snd_ctl_add (card, kctl = snd_ctl_new1(&snd_hdsp_adat_sync_check, hdsp)))) {
+ if ((err = snd_ctl_add (card, kctl = snd_ctl_new1(&snd_hdsp_adat_sync_check, hdsp))))
return err;
- }
if (hdsp->io_type == Digiface || hdsp->io_type == H9652) {
for (idx = 1; idx < 3; ++idx) {
snd_hdsp_adat_sync_check.index = idx+1;
- if ((err = snd_ctl_add (card, kctl = snd_ctl_new1(&snd_hdsp_adat_sync_check, hdsp)))) {
+ if ((err = snd_ctl_add (card, kctl = snd_ctl_new1(&snd_hdsp_adat_sync_check, hdsp))))
return err;
- }
}
}
/* DA, AD and Phone gain and XLR breakout cable controls for H9632 cards */
if (hdsp->io_type == H9632) {
for (idx = 0; idx < ARRAY_SIZE(snd_hdsp_9632_controls); idx++) {
- if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_hdsp_9632_controls[idx], hdsp))) < 0) {
+ if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_hdsp_9632_controls[idx], hdsp))) < 0)
return err;
- }
}
}
/* AEB control for H96xx card */
if (hdsp->io_type == H9632 || hdsp->io_type == H9652) {
- if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_hdsp_96xx_aeb, hdsp))) < 0) {
+ if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_hdsp_96xx_aeb, hdsp))) < 0)
return err;
- }
}
return 0;
@@ -3228,12 +3173,11 @@ snd_hdsp_proc_read(snd_info_entry_t *entry, snd_info_buffer_t *buffer)
char *clock_source;
int x;
- if (hdsp_check_for_iobox (hdsp)) {
+ if (hdsp_check_for_iobox (hdsp))
snd_iprintf(buffer, "No I/O box connected.\nPlease connect one and upload firmware.\n");
return;
- }
- if (hdsp_check_for_firmware(hdsp)) {
+ if (hdsp_check_for_firmware(hdsp, 0)) {
if (hdsp->state & HDSP_FirmwareCached) {
if (snd_hdsp_load_firmware_from_cache(hdsp) != 0) {
snd_iprintf(buffer, "Firmware loading from cache failed, please upload manually.\n");
@@ -3314,11 +3258,10 @@ snd_hdsp_proc_read(snd_info_entry_t *entry, snd_info_buffer_t *buffer)
}
snd_iprintf (buffer, "Sample Clock Source: %s\n", clock_source);
- if (hdsp_system_clock_mode(hdsp)) {
+ if (hdsp_system_clock_mode(hdsp))
system_clock_mode = "Slave";
- } else {
+ else
system_clock_mode = "Master";
- }
switch (hdsp_pref_sync_ref (hdsp)) {
case HDSP_SYNC_FROM_WORD:
@@ -3400,85 +3343,75 @@ snd_hdsp_proc_read(snd_info_entry_t *entry, snd_info_buffer_t *buffer)
break;
}
- if (hdsp->control_register & HDSP_SPDIFOpticalOut) {
+ if (hdsp->control_register & HDSP_SPDIFOpticalOut)
snd_iprintf(buffer, "IEC958 output: Coaxial & ADAT1\n");
- } else {
+ else
snd_iprintf(buffer, "IEC958 output: Coaxial only\n");
- }
- if (hdsp->control_register & HDSP_SPDIFProfessional) {
+ if (hdsp->control_register & HDSP_SPDIFProfessional)
snd_iprintf(buffer, "IEC958 quality: Professional\n");
- } else {
+ else
snd_iprintf(buffer, "IEC958 quality: Consumer\n");
- }
- if (hdsp->control_register & HDSP_SPDIFEmphasis) {
+ if (hdsp->control_register & HDSP_SPDIFEmphasis)
snd_iprintf(buffer, "IEC958 emphasis: on\n");
- } else {
+ else
snd_iprintf(buffer, "IEC958 emphasis: off\n");
- }
- if (hdsp->control_register & HDSP_SPDIFNonAudio) {
+ if (hdsp->control_register & HDSP_SPDIFNonAudio)
snd_iprintf(buffer, "IEC958 NonAudio: on\n");
- } else {
+ else
snd_iprintf(buffer, "IEC958 NonAudio: off\n");
- }
- if ((x = hdsp_spdif_sample_rate (hdsp)) != 0) {
+ if ((x = hdsp_spdif_sample_rate (hdsp)) != 0)
snd_iprintf (buffer, "IEC958 sample rate: %d\n", x);
- } else {
+ else
snd_iprintf (buffer, "IEC958 sample rate: Error flag set\n");
- }
snd_iprintf(buffer, "\n");
/* Sync Check */
x = status & HDSP_Sync0;
- if (status & HDSP_Lock0) {
+ if (status & HDSP_Lock0)
snd_iprintf(buffer, "ADAT1: %s\n", x ? "Sync" : "Lock");
- } else {
+ else
snd_iprintf(buffer, "ADAT1: No Lock\n");
- }
switch (hdsp->io_type) {
case Digiface:
case H9652:
x = status & HDSP_Sync1;
- if (status & HDSP_Lock1) {
+ if (status & HDSP_Lock1)
snd_iprintf(buffer, "ADAT2: %s\n", x ? "Sync" : "Lock");
- } else {
+ else
snd_iprintf(buffer, "ADAT2: No Lock\n");
- }
x = status & HDSP_Sync2;
- if (status & HDSP_Lock2) {
+ if (status & HDSP_Lock2)
snd_iprintf(buffer, "ADAT3: %s\n", x ? "Sync" : "Lock");
- } else {
+ else
snd_iprintf(buffer, "ADAT3: No Lock\n");
- }
+ break;
default:
/* relax */
break;
}
x = status & HDSP_SPDIFSync;
- if (status & HDSP_SPDIFErrorFlag) {
+ if (status & HDSP_SPDIFErrorFlag)
snd_iprintf (buffer, "SPDIF: No Lock\n");
- } else {
+ else
snd_iprintf (buffer, "SPDIF: %s\n", x ? "Sync" : "Lock");
- }
x = status2 & HDSP_wc_sync;
- if (status2 & HDSP_wc_lock) {
+ if (status2 & HDSP_wc_lock)
snd_iprintf (buffer, "Word Clock: %s\n", x ? "Sync" : "Lock");
- } else {
+ else
snd_iprintf (buffer, "Word Clock: No Lock\n");
- }
x = status & HDSP_TimecodeSync;
- if (status & HDSP_TimecodeLock) {
+ if (status & HDSP_TimecodeLock)
snd_iprintf(buffer, "ADAT Sync: %s\n", x ? "Sync" : "Lock");
- } else {
+ else
snd_iprintf(buffer, "ADAT Sync: No Lock\n");
- }
snd_iprintf(buffer, "\n");
@@ -3527,11 +3460,10 @@ snd_hdsp_proc_read(snd_info_entry_t *entry, snd_info_buffer_t *buffer)
snd_iprintf(buffer, "XLR Breakout Cable : %s\n", hdsp_xlr_breakout_cable(hdsp) ? "yes" : "no");
- if (hdsp->control_register & HDSP_AnalogExtensionBoard) {
+ if (hdsp->control_register & HDSP_AnalogExtensionBoard)
snd_iprintf(buffer, "AEB : on (ADAT1 internal)\n");
- } else {
+ else
snd_iprintf(buffer, "AEB : off (ADAT1 external)\n");
- }
snd_iprintf(buffer, "\n");
}
@@ -3610,25 +3542,22 @@ static int snd_hdsp_set_defaults(hdsp_t *hdsp)
#else
hdsp->control2_register = 0;
#endif
- if (hdsp->io_type == H9652) {
+ if (hdsp->io_type == H9652)
snd_hdsp_9652_enable_mixer (hdsp);
- } else {
- hdsp_write (hdsp, HDSP_control2Reg, hdsp->control2_register);
- }
+ else
+ hdsp_write (hdsp, HDSP_control2Reg, hdsp->control2_register);
hdsp_reset_hw_pointer(hdsp);
hdsp_compute_period_size(hdsp);
/* silence everything */
- for (i = 0; i < HDSP_MATRIX_MIXER_SIZE; ++i) {
+ for (i = 0; i < HDSP_MATRIX_MIXER_SIZE; ++i)
hdsp->mixer_matrix[i] = MINUS_INFINITY_GAIN;
- }
for (i = 0; i < ((hdsp->io_type == H9652 || hdsp->io_type == H9632) ? 1352 : HDSP_MATRIX_MIXER_SIZE); ++i) {
- if (hdsp_write_gain (hdsp, i, MINUS_INFINITY_GAIN)) {
+ if (hdsp_write_gain (hdsp, i, MINUS_INFINITY_GAIN))
return -EIO;
- }
}
/* H9632 specific defaults */
@@ -3649,12 +3578,10 @@ static void hdsp_midi_tasklet(unsigned long arg)
{
hdsp_t *hdsp = (hdsp_t *)arg;
- if (hdsp->midi[0].pending) {
+ if (hdsp->midi[0].pending)
snd_hdsp_midi_input_read (&hdsp->midi[0]);
- }
- if (hdsp->midi[1].pending) {
+ if (hdsp->midi[1].pending)
snd_hdsp_midi_input_read (&hdsp->midi[1]);
- }
}
static irqreturn_t snd_hdsp_interrupt(int irq, void *dev_id, struct pt_regs *regs)
@@ -3674,9 +3601,8 @@ static irqreturn_t snd_hdsp_interrupt(int irq, void *dev_id, struct pt_regs *reg
midi0 = status & HDSP_midi0IRQPending;
midi1 = status & HDSP_midi1IRQPending;
- if (!audio && !midi0 && !midi1) {
+ if (!audio && !midi0 && !midi1)
return IRQ_NONE;
- }
hdsp_write(hdsp, HDSP_interruptConfirmation, 0);
@@ -3684,13 +3610,11 @@ static irqreturn_t snd_hdsp_interrupt(int irq, void *dev_id, struct pt_regs *reg
midi1status = hdsp_read (hdsp, HDSP_midiStatusIn1) & 0xff;
if (audio) {
- if (hdsp->capture_substream) {
+ if (hdsp->capture_substream)
snd_pcm_period_elapsed(hdsp->pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream);
- }
- if (hdsp->playback_substream) {
+ if (hdsp->playback_substream)
snd_pcm_period_elapsed(hdsp->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream);
- }
}
if (midi0 && midi0status) {
@@ -3735,15 +3659,13 @@ static char *hdsp_channel_buffer_location(hdsp_t *hdsp,
snd_assert(channel >= 0 && channel < hdsp->max_channels, return NULL);
- if ((mapped_channel = hdsp->channel_map[channel]) < 0) {
+ if ((mapped_channel = hdsp->channel_map[channel]) < 0)
return NULL;
- }
- if (stream == SNDRV_PCM_STREAM_CAPTURE) {
+ if (stream == SNDRV_PCM_STREAM_CAPTURE)
return hdsp->capture_buffer + (mapped_channel * HDSP_CHANNEL_BUFFER_BYTES);
- } else {
+ else
return hdsp->playback_buffer + (mapped_channel * HDSP_CHANNEL_BUFFER_BYTES);
- }
}
static int snd_hdsp_playback_copy(snd_pcm_substream_t *substream, int channel,
@@ -3824,20 +3746,11 @@ static int snd_hdsp_hw_params(snd_pcm_substream_t *substream,
pid_t this_pid;
pid_t other_pid;
- if (hdsp_check_for_iobox (hdsp)) {
+ if (hdsp_check_for_iobox (hdsp))
return -EIO;
- }
- if (hdsp_check_for_firmware(hdsp)) {
- if (hdsp->state & HDSP_FirmwareCached) {
- if (snd_hdsp_load_firmware_from_cache(hdsp) != 0) {
- snd_printk("Hammerfall-DSP: Firmware loading from cache failed, please upload manually.\n");
- }
- } else {
- snd_printk("Hammerfall-DSP: No firmware loaded nor cached, please upload firmware.\n");
- }
+ if (hdsp_check_for_firmware(hdsp, 1))
return -EIO;
- }
spin_lock_irq(&hdsp->lock);
@@ -3908,9 +3821,8 @@ static int snd_hdsp_channel_info(snd_pcm_substream_t *substream,
snd_assert(info->channel < hdsp->max_channels, return -EINVAL);
- if ((mapped_channel = hdsp->channel_map[info->channel]) < 0) {
+ if ((mapped_channel = hdsp->channel_map[info->channel]) < 0)
return -EINVAL;
- }
info->offset = mapped_channel * HDSP_CHANNEL_BUFFER_BYTES;
info->first = 0;
@@ -3923,14 +3835,9 @@ static int snd_hdsp_ioctl(snd_pcm_substream_t *substream,
{
switch (cmd) {
case SNDRV_PCM_IOCTL1_RESET:
- {
return snd_hdsp_reset(substream);
- }
case SNDRV_PCM_IOCTL1_CHANNEL_INFO:
- {
- snd_pcm_channel_info_t *info = arg;
- return snd_hdsp_channel_info(substream, info);
- }
+ return snd_hdsp_channel_info(substream, arg);
default:
break;
}
@@ -3944,20 +3851,11 @@ static int snd_hdsp_trigger(snd_pcm_substream_t *substream, int cmd)
snd_pcm_substream_t *other;
int running;
- if (hdsp_check_for_iobox (hdsp)) {
+ if (hdsp_check_for_iobox (hdsp))
return -EIO;
- }
- if (hdsp_check_for_firmware(hdsp)) {
- if (hdsp->state & HDSP_FirmwareCached) {
- if (snd_hdsp_load_firmware_from_cache(hdsp) != 0) {
- snd_printk("Hammerfall-DSP: Firmware loading from cache failed, please upload manually.\n");
- }
- } else {
- snd_printk("Hammerfall-DSP: No firmware loaded nor cached, please upload firmware.\n");
- }
+ if (hdsp_check_for_firmware(hdsp, 1))
return -EIO;
- }
spin_lock(&hdsp->lock);
running = hdsp->running;
@@ -4022,20 +3920,11 @@ static int snd_hdsp_prepare(snd_pcm_substream_t *substream)
hdsp_t *hdsp = snd_pcm_substream_chip(substream);
int result = 0;
- if (hdsp_check_for_iobox (hdsp)) {
+ if (hdsp_check_for_iobox (hdsp))
return -EIO;
- }
- if (hdsp_check_for_firmware(hdsp)) {
- if (hdsp->state & HDSP_FirmwareCached) {
- if (snd_hdsp_load_firmware_from_cache(hdsp) != 0) {
- snd_printk("Hammerfall-DSP: Firmware loading from cache failed, please upload manually.\n");
- }
- } else {
- snd_printk("Hammerfall-DSP: No firmware loaded nor cached, please upload firmware.\n");
- }
+ if (hdsp_check_for_firmware(hdsp, 1))
return -EIO;
- }
spin_lock_irq(&hdsp->lock);
if (!hdsp->running)
@@ -4285,20 +4174,11 @@ static int snd_hdsp_playback_open(snd_pcm_substream_t *substream)
hdsp_t *hdsp = snd_pcm_substream_chip(substream);
snd_pcm_runtime_t *runtime = substream->runtime;
- if (hdsp_check_for_iobox (hdsp)) {
+ if (hdsp_check_for_iobox (hdsp))
return -EIO;
- }
- if (hdsp_check_for_firmware(hdsp)) {
- if (hdsp->state & HDSP_FirmwareCached) {
- if (snd_hdsp_load_firmware_from_cache(hdsp) != 0) {
- snd_printk("Hammerfall-DSP: Firmware loading from cache failed, please upload manually.\n");
- }
- } else {
- snd_printk("Hammerfall-DSP: No firmware loaded nor cached, please upload firmware.\n");
- }
+ if (hdsp_check_for_firmware(hdsp, 1))
return -EIO;
- }
spin_lock_irq(&hdsp->lock);
@@ -4367,20 +4247,11 @@ static int snd_hdsp_capture_open(snd_pcm_substream_t *substream)
hdsp_t *hdsp = snd_pcm_substream_chip(substream);
snd_pcm_runtime_t *runtime = substream->runtime;
- if (hdsp_check_for_iobox (hdsp)) {
+ if (hdsp_check_for_iobox (hdsp))
return -EIO;
- }
- if (hdsp_check_for_firmware(hdsp)) {
- if (hdsp->state & HDSP_FirmwareCached) {
- if (snd_hdsp_load_firmware_from_cache(hdsp) != 0) {
- snd_printk("Hammerfall-DSP: Firmware loading from cache failed, please upload manually.\n");
- }
- } else {
- snd_printk("Hammerfall-DSP: No firmware loaded nor cached, please upload firmware.\n");
- }
+ if (hdsp_check_for_firmware(hdsp, 1))
return -EIO;
- }
spin_lock_irq(&hdsp->lock);
@@ -4589,19 +4460,17 @@ static int snd_hdsp_hwdep_ioctl(snd_hwdep_t *hw, struct file *file, unsigned int
int i;
if (!(hdsp->state & HDSP_FirmwareLoaded)) {
- snd_printk("Hammerfall-DSP: Firmware needs to be uploaded to the card.\n");
+ snd_printk(KERN_ERR "Hammerfall-DSP: Firmware needs to be uploaded to the card.\n");
return -EINVAL;
}
spin_lock_irqsave(&hdsp->lock, flags);
info.pref_sync_ref = (unsigned char)hdsp_pref_sync_ref(hdsp);
info.wordclock_sync_check = (unsigned char)hdsp_wc_sync_check(hdsp);
- if (hdsp->io_type != H9632) {
+ if (hdsp->io_type != H9632)
info.adatsync_sync_check = (unsigned char)hdsp_adatsync_sync_check(hdsp);
- }
info.spdif_sync_check = (unsigned char)hdsp_spdif_sync_check(hdsp);
- for (i = 0; i < ((hdsp->io_type != Multiface && hdsp->io_type != H9632) ? 3 : 1); ++i) {
+ for (i = 0; i < ((hdsp->io_type != Multiface && hdsp->io_type != H9632) ? 3 : 1); ++i)
info.adat_sync_check[i] = (unsigned char)hdsp_adat_sync_check(hdsp, i);
- }
info.spdif_in = (unsigned char)hdsp_spdif_in(hdsp);
info.spdif_out = (unsigned char)hdsp_spdif_out(hdsp);
info.spdif_professional = (unsigned char)hdsp_spdif_professional(hdsp);
@@ -4621,9 +4490,8 @@ static int snd_hdsp_hwdep_ioctl(snd_hwdep_t *hw, struct file *file, unsigned int
info.xlr_breakout_cable = (unsigned char)hdsp_xlr_breakout_cable(hdsp);
}
- if (hdsp->io_type == H9632 || hdsp->io_type == H9652) {
+ if (hdsp->io_type == H9632 || hdsp->io_type == H9652)
info.analog_extension_board = (unsigned char)hdsp_aeb(hdsp);
- }
spin_unlock_irqrestore(&hdsp->lock, flags);
if (copy_to_user(argp, &info, sizeof(info)))
return -EFAULT;
@@ -4645,15 +4513,13 @@ static int snd_hdsp_hwdep_ioctl(snd_hwdep_t *hw, struct file *file, unsigned int
if (hdsp->io_type == H9652 || hdsp->io_type == H9632) return -EINVAL;
if (hdsp->io_type == Undefined) {
- if ((err = hdsp_get_iobox_version(hdsp)) < 0) {
+ if ((err = hdsp_get_iobox_version(hdsp)) < 0)
return err;
- }
}
hdsp_version.io_type = hdsp->io_type;
hdsp_version.firmware_rev = hdsp->firmware_rev;
- if ((err = copy_to_user(argp, &hdsp_version, sizeof(hdsp_version)))) {
+ if ((err = copy_to_user(argp, &hdsp_version, sizeof(hdsp_version))))
return -EFAULT;
- }
break;
}
case SNDRV_HDSP_IOCTL_UPLOAD_FIRMWARE: {
@@ -4668,38 +4534,33 @@ static int snd_hdsp_hwdep_ioctl(snd_hwdep_t *hw, struct file *file, unsigned int
if (hdsp->state & (HDSP_FirmwareCached | HDSP_FirmwareLoaded))
return -EBUSY;
- snd_printk("Hammerfall-DSP: initializing firmware upload\n");
+ snd_printk(KERN_INFO "Hammerfall-DSP: initializing firmware upload\n");
firmware = (hdsp_firmware_t __user *)argp;
- if (get_user(firmware_data, &firmware->firmware_data)) {
+ if (get_user(firmware_data, &firmware->firmware_data))
return -EFAULT;
- }
- if (hdsp_check_for_iobox (hdsp)) {
+ if (hdsp_check_for_iobox (hdsp))
return -EIO;
- }
- if (copy_from_user(hdsp->firmware_cache, firmware_data, sizeof(hdsp->firmware_cache)) != 0) {
+ if (copy_from_user(hdsp->firmware_cache, firmware_data, sizeof(hdsp->firmware_cache)) != 0)
return -EFAULT;
- }
hdsp->state |= HDSP_FirmwareCached;
- if ((err = snd_hdsp_load_firmware_from_cache(hdsp)) < 0) {
+ if ((err = snd_hdsp_load_firmware_from_cache(hdsp)) < 0)
return err;
- }
if (!(hdsp->state & HDSP_InitializationComplete)) {
- if ((err = snd_hdsp_enable_io(hdsp)) < 0) {
+ if ((err = snd_hdsp_enable_io(hdsp)) < 0)
return err;
- }
snd_hdsp_initialize_channels(hdsp);
snd_hdsp_initialize_midi_flush(hdsp);
if ((err = snd_hdsp_create_alsa_devices(hdsp->card, hdsp)) < 0) {
- snd_printk("Hammerfall-DSP: error creating alsa devices\n");
- return err;
+ snd_printk(KERN_ERR "Hammerfall-DSP: error creating alsa devices\n");
+ return err;
}
}
break;
@@ -4790,7 +4651,7 @@ static int snd_hdsp_enable_io (hdsp_t *hdsp)
int i;
if (hdsp_fifo_wait (hdsp, 0, 100)) {
- snd_printk("Hammerfall-DSP: enable_io fifo_wait failed\n");
+ snd_printk(KERN_ERR "Hammerfall-DSP: enable_io fifo_wait failed\n");
return -EIO;
}
@@ -4856,25 +4717,25 @@ static int snd_hdsp_create_alsa_devices(snd_card_t *card, hdsp_t *hdsp)
int err;
if ((err = snd_hdsp_create_pcm(card, hdsp)) < 0) {
- snd_printk("Hammerfall-DSP: Error creating pcm interface\n");
+ snd_printk(KERN_ERR "Hammerfall-DSP: Error creating pcm interface\n");
return err;
}
if ((err = snd_hdsp_create_midi(card, hdsp, 0)) < 0) {
- snd_printk("Hammerfall-DSP: Error creating first midi interface\n");
+ snd_printk(KERN_ERR "Hammerfall-DSP: Error creating first midi interface\n");
return err;
}
if (hdsp->io_type == Digiface || hdsp->io_type == H9652) {
if ((err = snd_hdsp_create_midi(card, hdsp, 1)) < 0) {
- snd_printk("Hammerfall-DSP: Error creating second midi interface\n");
+ snd_printk(KERN_ERR "Hammerfall-DSP: Error creating second midi interface\n");
return err;
}
}
if ((err = snd_hdsp_create_controls(card, hdsp)) < 0) {
- snd_printk("Hammerfall-DSP: Error creating ctl interface\n");
+ snd_printk(KERN_ERR "Hammerfall-DSP: Error creating ctl interface\n");
return err;
}
@@ -4887,7 +4748,7 @@ static int snd_hdsp_create_alsa_devices(snd_card_t *card, hdsp_t *hdsp)
hdsp->playback_substream = NULL;
if ((err = snd_hdsp_set_defaults(hdsp)) < 0) {
- snd_printk("Hammerfall-DSP: Error setting default values\n");
+ snd_printk(KERN_ERR "Hammerfall-DSP: Error setting default values\n");
return err;
}
@@ -4897,7 +4758,7 @@ static int snd_hdsp_create_alsa_devices(snd_card_t *card, hdsp_t *hdsp)
hdsp->port, hdsp->irq);
if ((err = snd_card_register(card)) < 0) {
- snd_printk("Hammerfall-DSP: error registering card\n");
+ snd_printk(KERN_ERR "Hammerfall-DSP: error registering card\n");
return err;
}
hdsp->state |= HDSP_InitializationComplete;
@@ -4963,18 +4824,17 @@ static int __devinit hdsp_request_fw_loader(hdsp_t *hdsp)
return err;
if (!(hdsp->state & HDSP_InitializationComplete)) {
- if ((err = snd_hdsp_enable_io(hdsp)) < 0) {
+ if ((err = snd_hdsp_enable_io(hdsp)) < 0)
return err;
- }
if ((err = snd_hdsp_create_hwdep(hdsp->card, hdsp)) < 0) {
- snd_printk("Hammerfall-DSP: error creating hwdep device\n");
+ snd_printk(KERN_ERR "Hammerfall-DSP: error creating hwdep device\n");
return err;
}
snd_hdsp_initialize_channels(hdsp);
snd_hdsp_initialize_midi_flush(hdsp);
if ((err = snd_hdsp_create_alsa_devices(hdsp->card, hdsp)) < 0) {
- snd_printk("Hammerfall-DSP: error creating alsa devices\n");
+ snd_printk(KERN_ERR "Hammerfall-DSP: error creating alsa devices\n");
return err;
}
}
@@ -5029,11 +4889,11 @@ static int __devinit snd_hdsp_create(snd_card_t *card,
strcpy(card->driver, "H-DSP");
strcpy(card->mixername, "Xilinx FPGA");
- if (hdsp->firmware_rev < 0xa) {
+ if (hdsp->firmware_rev < 0xa)
return -ENODEV;
- } else if (hdsp->firmware_rev < 0x64) {
+ else if (hdsp->firmware_rev < 0x64)
hdsp->card_name = "RME Hammerfall DSP";
- } else if (hdsp->firmware_rev < 0x96) {
+ else if (hdsp->firmware_rev < 0x96) {
hdsp->card_name = "RME HDSP 9652";
is_9652 = 1;
} else {
@@ -5042,9 +4902,8 @@ static int __devinit snd_hdsp_create(snd_card_t *card,
is_9632 = 1;
}
- if ((err = pci_enable_device(pci)) < 0) {
+ if ((err = pci_enable_device(pci)) < 0)
return err;
- }
pci_set_master(hdsp->pci);
@@ -5052,12 +4911,12 @@ static int __devinit snd_hdsp_create(snd_card_t *card,
return err;
hdsp->port = pci_resource_start(pci, 0);
if ((hdsp->iobase = ioremap_nocache(hdsp->port, HDSP_IO_EXTENT)) == NULL) {
- snd_printk("Hammerfall-DSP: unable to remap region 0x%lx-0x%lx\n", hdsp->port, hdsp->port + HDSP_IO_EXTENT - 1);
+ snd_printk(KERN_ERR "Hammerfall-DSP: unable to remap region 0x%lx-0x%lx\n", hdsp->port, hdsp->port + HDSP_IO_EXTENT - 1);
return -EBUSY;
}
if (request_irq(pci->irq, snd_hdsp_interrupt, SA_INTERRUPT|SA_SHIRQ, "hdsp", (void *)hdsp)) {
- snd_printk("Hammerfall-DSP: unable to use IRQ %d\n", pci->irq);
+ snd_printk(KERN_ERR "Hammerfall-DSP: unable to use IRQ %d\n", pci->irq);
return -EBUSY;
}
@@ -5065,71 +4924,58 @@ static int __devinit snd_hdsp_create(snd_card_t *card,
hdsp->precise_ptr = 1;
hdsp->use_midi_tasklet = 1;
- if ((err = snd_hdsp_initialize_memory(hdsp)) < 0) {
+ if ((err = snd_hdsp_initialize_memory(hdsp)) < 0)
return err;
- }
if (!is_9652 && !is_9632) {
/* we wait 2 seconds to let freshly inserted cardbus cards do their hardware init */
- if ((1000 / HZ) < 2000) {
- ssleep(2);
- } else {
- mdelay(2000);
- }
+ ssleep(2);
if ((hdsp_read (hdsp, HDSP_statusRegister) & HDSP_DllError) != 0) {
#ifdef HDSP_FW_LOADER
- if ((err = hdsp_request_fw_loader(hdsp)) < 0) {
+ if ((err = hdsp_request_fw_loader(hdsp)) < 0)
/* we don't fail as this can happen
if userspace is not ready for
firmware upload
*/
- snd_printk("Hammerfall-DSP: couldn't get firmware from userspace. try using hdsploader\n");
- } else {
+ snd_printk(KERN_ERR "Hammerfall-DSP: couldn't get firmware from userspace. try using hdsploader\n");
+ else
/* init is complete, we return */
return 0;
- }
#endif
/* no iobox connected, we defer initialization */
- snd_printk("Hammerfall-DSP: card initialization pending : waiting for firmware\n");
- if ((err = snd_hdsp_create_hwdep(card, hdsp)) < 0) {
+ snd_printk(KERN_INFO "Hammerfall-DSP: card initialization pending : waiting for firmware\n");
+ if ((err = snd_hdsp_create_hwdep(card, hdsp)) < 0)
return err;
- }
return 0;
} else {
- snd_printk("Hammerfall-DSP: Firmware already present, initializing card.\n");
- if (hdsp_read(hdsp, HDSP_status2Register) & HDSP_version1) {
+ snd_printk(KERN_INFO "Hammerfall-DSP: Firmware already present, initializing card.\n");
+ if (hdsp_read(hdsp, HDSP_status2Register) & HDSP_version1)
hdsp->io_type = Multiface;
- } else {
+ else
hdsp->io_type = Digiface;
- }
}
}
- if ((err = snd_hdsp_enable_io(hdsp)) != 0) {
+ if ((err = snd_hdsp_enable_io(hdsp)) != 0)
return err;
- }
- if (is_9652) {
+ if (is_9652)
hdsp->io_type = H9652;
- }
- if (is_9632) {
+ if (is_9632)
hdsp->io_type = H9632;
- }
- if ((err = snd_hdsp_create_hwdep(card, hdsp)) < 0) {
+ if ((err = snd_hdsp_create_hwdep(card, hdsp)) < 0)
return err;
- }
snd_hdsp_initialize_channels(hdsp);
snd_hdsp_initialize_midi_flush(hdsp);
hdsp->state |= HDSP_FirmwareLoaded;
- if ((err = snd_hdsp_create_alsa_devices(card, hdsp)) < 0) {
+ if ((err = snd_hdsp_create_alsa_devices(card, hdsp)) < 0)
return err;
- }
return 0;
}
@@ -5216,7 +5062,6 @@ static void __devexit snd_hdsp_remove(struct pci_dev *pci)
static struct pci_driver driver = {
.name = "RME Hammerfall DSP",
- .owner = THIS_MODULE,
.id_table = snd_hdsp_ids,
.probe = snd_hdsp_probe,
.remove = __devexit_p(snd_hdsp_remove),
diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c
index fc3f3283ff37..a1aef6f6767e 100644
--- a/sound/pci/rme9652/hdspm.c
+++ b/sound/pci/rme9652/hdspm.c
@@ -3563,8 +3563,7 @@ static int snd_hdspm_free(hdspm_t * hdspm)
free_irq(hdspm->irq, (void *) hdspm);
- if (hdspm->mixer)
- kfree(hdspm->mixer);
+ kfree(hdspm->mixer);
if (hdspm->iobase)
iounmap(hdspm->iobase);
@@ -3640,7 +3639,6 @@ static void __devexit snd_hdspm_remove(struct pci_dev *pci)
static struct pci_driver driver = {
.name = "RME Hammerfall DSP MADI",
- .owner = THIS_MODULE,
.id_table = snd_hdspm_ids,
.probe = snd_hdspm_probe,
.remove = __devexit_p(snd_hdspm_remove),
diff --git a/sound/pci/rme9652/rme9652.c b/sound/pci/rme9652/rme9652.c
index b600f45e1834..f9d0c126c213 100644
--- a/sound/pci/rme9652/rme9652.c
+++ b/sound/pci/rme9652/rme9652.c
@@ -779,7 +779,7 @@ static inline int rme9652_spdif_sample_rate(rme9652_t *s)
break;
default:
- snd_printk("%s: unknown S/PDIF input rate (bits = 0x%x)\n",
+ snd_printk(KERN_ERR "%s: unknown S/PDIF input rate (bits = 0x%x)\n",
s->card_name, rate_bits);
return 0;
break;
@@ -2496,12 +2496,12 @@ static int __devinit snd_rme9652_create(snd_card_t *card,
rme9652->port = pci_resource_start(pci, 0);
rme9652->iobase = ioremap_nocache(rme9652->port, RME9652_IO_EXTENT);
if (rme9652->iobase == NULL) {
- snd_printk("unable to remap region 0x%lx-0x%lx\n", rme9652->port, rme9652->port + RME9652_IO_EXTENT - 1);
+ snd_printk(KERN_ERR "unable to remap region 0x%lx-0x%lx\n", rme9652->port, rme9652->port + RME9652_IO_EXTENT - 1);
return -EBUSY;
}
if (request_irq(pci->irq, snd_rme9652_interrupt, SA_INTERRUPT|SA_SHIRQ, "rme9652", (void *)rme9652)) {
- snd_printk("unable to request IRQ %d\n", pci->irq);
+ snd_printk(KERN_ERR "unable to request IRQ %d\n", pci->irq);
return -EBUSY;
}
rme9652->irq = pci->irq;
@@ -2654,7 +2654,6 @@ static void __devexit snd_rme9652_remove(struct pci_dev *pci)
static struct pci_driver driver = {
.name = "RME Digi9652 (Hammerfall)",
- .owner = THIS_MODULE,
.id_table = snd_rme9652_ids,
.probe = snd_rme9652_probe,
.remove = __devexit_p(snd_rme9652_remove),
diff --git a/sound/pci/sonicvibes.c b/sound/pci/sonicvibes.c
index 1f6c2bfd43fd..e92ef3ae2ca1 100644
--- a/sound/pci/sonicvibes.c
+++ b/sound/pci/sonicvibes.c
@@ -591,7 +591,7 @@ static irqreturn_t snd_sonicvibes_interrupt(int irq, void *dev_id, struct pt_reg
return IRQ_NONE;
if (status == 0xff) { /* failure */
outb(sonic->irqmask = ~0, SV_REG(sonic, IRQMASK));
- snd_printk("IRQ failure - interrupts disabled!!\n");
+ snd_printk(KERN_ERR "IRQ failure - interrupts disabled!!\n");
return IRQ_HANDLED;
}
if (sonic->pcm) {
@@ -1205,14 +1205,8 @@ static int snd_sonicvibes_free(sonicvibes_t *sonic)
pci_write_config_dword(sonic->pci, 0x48, sonic->dmac_port);
if (sonic->irq >= 0)
free_irq(sonic->irq, (void *)sonic);
- if (sonic->res_dmaa) {
- release_resource(sonic->res_dmaa);
- kfree_nocheck(sonic->res_dmaa);
- }
- if (sonic->res_dmac) {
- release_resource(sonic->res_dmac);
- kfree_nocheck(sonic->res_dmac);
- }
+ release_and_free_resource(sonic->res_dmaa);
+ release_and_free_resource(sonic->res_dmac);
pci_release_regions(sonic->pci);
pci_disable_device(sonic->pci);
kfree(sonic);
@@ -1245,7 +1239,7 @@ static int __devinit snd_sonicvibes_create(snd_card_t * card,
/* check, if we can restrict PCI DMA transfers to 24 bits */
if (pci_set_dma_mask(pci, 0x00ffffff) < 0 ||
pci_set_consistent_dma_mask(pci, 0x00ffffff) < 0) {
- snd_printk("architecture does not support 24bit PCI busmaster DMA\n");
+ snd_printk(KERN_ERR "architecture does not support 24bit PCI busmaster DMA\n");
pci_disable_device(pci);
return -ENXIO;
}
@@ -1273,7 +1267,7 @@ static int __devinit snd_sonicvibes_create(snd_card_t * card,
sonic->game_port = pci_resource_start(pci, 4);
if (request_irq(pci->irq, snd_sonicvibes_interrupt, SA_INTERRUPT|SA_SHIRQ, "S3 SonicVibes", (void *)sonic)) {
- snd_printk("unable to grab IRQ %d\n", pci->irq);
+ snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
snd_sonicvibes_free(sonic);
return -EBUSY;
}
@@ -1287,24 +1281,24 @@ static int __devinit snd_sonicvibes_create(snd_card_t * card,
if (!dmaa) {
dmaa = dmaio;
dmaio += 0x10;
- snd_printk("BIOS did not allocate DDMA channel A i/o, allocated at 0x%x\n", dmaa);
+ snd_printk(KERN_INFO "BIOS did not allocate DDMA channel A i/o, allocated at 0x%x\n", dmaa);
}
if (!dmac) {
dmac = dmaio;
dmaio += 0x10;
- snd_printk("BIOS did not allocate DDMA channel C i/o, allocated at 0x%x\n", dmac);
+ snd_printk(KERN_INFO "BIOS did not allocate DDMA channel C i/o, allocated at 0x%x\n", dmac);
}
pci_write_config_dword(pci, 0x40, dmaa);
pci_write_config_dword(pci, 0x48, dmac);
if ((sonic->res_dmaa = request_region(dmaa, 0x10, "S3 SonicVibes DDMA-A")) == NULL) {
snd_sonicvibes_free(sonic);
- snd_printk("unable to grab DDMA-A port at 0x%x-0x%x\n", dmaa, dmaa + 0x10 - 1);
+ snd_printk(KERN_ERR "unable to grab DDMA-A port at 0x%x-0x%x\n", dmaa, dmaa + 0x10 - 1);
return -EBUSY;
}
if ((sonic->res_dmac = request_region(dmac, 0x10, "S3 SonicVibes DDMA-C")) == NULL) {
snd_sonicvibes_free(sonic);
- snd_printk("unable to grab DDMA-C port at 0x%x-0x%x\n", dmac, dmac + 0x10 - 1);
+ snd_printk(KERN_ERR "unable to grab DDMA-C port at 0x%x-0x%x\n", dmac, dmac + 0x10 - 1);
return -EBUSY;
}
@@ -1508,7 +1502,6 @@ static void __devexit snd_sonic_remove(struct pci_dev *pci)
static struct pci_driver driver = {
.name = "S3 SonicVibes",
- .owner = THIS_MODULE,
.id_table = snd_sonic_ids,
.probe = snd_sonic_probe,
.remove = __devexit_p(snd_sonic_remove),
diff --git a/sound/pci/trident/trident.c b/sound/pci/trident/trident.c
index a8ca8e17853f..940d531575c0 100644
--- a/sound/pci/trident/trident.c
+++ b/sound/pci/trident/trident.c
@@ -177,7 +177,6 @@ static void __devexit snd_trident_remove(struct pci_dev *pci)
static struct pci_driver driver = {
.name = "Trident4DWaveAudio",
- .owner = THIS_MODULE,
.id_table = snd_trident_ids,
.probe = snd_trident_probe,
.remove = __devexit_p(snd_trident_remove),
diff --git a/sound/pci/trident/trident_main.c b/sound/pci/trident/trident_main.c
index 777da9a7298b..b9b93c7faafd 100644
--- a/sound/pci/trident/trident_main.c
+++ b/sound/pci/trident/trident_main.c
@@ -153,7 +153,7 @@ static unsigned short snd_trident_codec_read(ac97_t *ac97, unsigned short reg)
}
if (count == 0 && !trident->ac97_detect) {
- snd_printk("ac97 codec read TIMEOUT [0x%x/0x%x]!!!\n", reg, data);
+ snd_printk(KERN_ERR "ac97 codec read TIMEOUT [0x%x/0x%x]!!!\n", reg, data);
data = 0;
}
@@ -2893,7 +2893,8 @@ static void snd_trident_notify_pcm_change1(snd_card_t * card, snd_kcontrol_t *kc
{
snd_ctl_elem_id_t id;
- snd_runtime_check(kctl != NULL, return);
+ if (! kctl)
+ return;
if (activate)
kctl->vd[num].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
else
@@ -2989,13 +2990,13 @@ static int __devinit snd_trident_mixer(trident_t * trident, int pcm_spdif_device
_ac97.num = 1;
err = snd_ac97_mixer(trident->ac97_bus, &_ac97, &trident->ac97_sec);
if (err < 0)
- snd_printk("SI7018: the secondary codec - invalid access\n");
+ snd_printk(KERN_ERR "SI7018: the secondary codec - invalid access\n");
#if 0 // only for my testing purpose --jk
{
ac97_t *mc97;
err = snd_ac97_modem(trident->card, &_ac97, &mc97);
if (err < 0)
- snd_printk("snd_ac97_modem returned error %i\n", err);
+ snd_printk(KERN_ERR "snd_ac97_modem returned error %i\n", err);
}
#endif
}
@@ -3206,8 +3207,7 @@ static inline void snd_trident_free_gameport(trident_t *chip) { }
*/
static inline void do_delay(trident_t *chip)
{
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(1);
+ schedule_timeout_uninterruptible(1);
}
/*
@@ -3243,7 +3243,7 @@ static int snd_trident_sis_reset(trident_t *trident)
goto __si7018_ok;
do_delay(trident);
} while (time_after_eq(end_time, jiffies));
- snd_printk("AC'97 codec ready error [0x%x]\n", inl(TRID_REG(trident, SI_SERIAL_INTF_CTRL)));
+ snd_printk(KERN_ERR "AC'97 codec ready error [0x%x]\n", inl(TRID_REG(trident, SI_SERIAL_INTF_CTRL)));
if (r-- > 0) {
end_time = jiffies + HZ;
do {
@@ -3541,7 +3541,7 @@ int __devinit snd_trident_create(snd_card_t * card,
/* check, if we can restrict PCI DMA transfers to 30 bits */
if (pci_set_dma_mask(pci, 0x3fffffff) < 0 ||
pci_set_consistent_dma_mask(pci, 0x3fffffff) < 0) {
- snd_printk("architecture does not support 30bit PCI busmaster DMA\n");
+ snd_printk(KERN_ERR "architecture does not support 30bit PCI busmaster DMA\n");
pci_disable_device(pci);
return -ENXIO;
}
@@ -3578,7 +3578,7 @@ int __devinit snd_trident_create(snd_card_t * card,
trident->port = pci_resource_start(pci, 0);
if (request_irq(pci->irq, snd_trident_interrupt, SA_INTERRUPT|SA_SHIRQ, "Trident Audio", (void *) trident)) {
- snd_printk("unable to grab IRQ %d\n", pci->irq);
+ snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
snd_trident_free(trident);
return -EBUSY;
}
diff --git a/sound/pci/trident/trident_memory.c b/sound/pci/trident/trident_memory.c
index 333d3790692a..f3e6c546af74 100644
--- a/sound/pci/trident/trident_memory.c
+++ b/sound/pci/trident/trident_memory.c
@@ -170,11 +170,11 @@ __found_pages:
static int is_valid_page(unsigned long ptr)
{
if (ptr & ~0x3fffffffUL) {
- snd_printk("max memory size is 1GB!!\n");
+ snd_printk(KERN_ERR "max memory size is 1GB!!\n");
return 0;
}
if (ptr & (SNDRV_TRIDENT_PAGE_SIZE-1)) {
- snd_printk("page is not aligned\n");
+ snd_printk(KERN_ERR "page is not aligned\n");
return 0;
}
return 1;
diff --git a/sound/pci/via82xx.c b/sound/pci/via82xx.c
index 3c0205b91e10..fad2a2413bf6 100644
--- a/sound/pci/via82xx.c
+++ b/sound/pci/via82xx.c
@@ -41,6 +41,9 @@
* device for applications.
* - clean up the code, separate low-level initialization
* routines for each chipset.
+ *
+ * Sep. 26, 2005 Karsten Wiese <annabellesgarden@yahoo.de>
+ * - Optimize position calculation for the 823x chips.
*/
#include <sound/driver.h>
@@ -73,36 +76,37 @@ MODULE_SUPPORTED_DEVICE("{{VIA,VT82C686A/B/C,pci},{VIA,VT8233A/C,8235}}");
#define SUPPORT_JOYSTICK 1
#endif
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
-static long mpu_port[SNDRV_CARDS];
+static int index = SNDRV_DEFAULT_IDX1; /* Index 0-MAX */
+static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */
+static long mpu_port;
#ifdef SUPPORT_JOYSTICK
-static int joystick[SNDRV_CARDS];
+static int joystick;
#endif
-static int ac97_clock[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 48000};
-static char *ac97_quirk[SNDRV_CARDS];
-static int dxs_support[SNDRV_CARDS];
+static int ac97_clock = 48000;
+static char *ac97_quirk;
+static int dxs_support;
-module_param_array(index, int, NULL, 0444);
+module_param(index, int, 0444);
MODULE_PARM_DESC(index, "Index value for VIA 82xx bridge.");
-module_param_array(id, charp, NULL, 0444);
+module_param(id, charp, 0444);
MODULE_PARM_DESC(id, "ID string for VIA 82xx bridge.");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable audio part of VIA 82xx bridge.");
-module_param_array(mpu_port, long, NULL, 0444);
+module_param(mpu_port, long, 0444);
MODULE_PARM_DESC(mpu_port, "MPU-401 port. (VT82C686x only)");
#ifdef SUPPORT_JOYSTICK
-module_param_array(joystick, bool, NULL, 0444);
+module_param(joystick, bool, 0444);
MODULE_PARM_DESC(joystick, "Enable joystick. (VT82C686x only)");
#endif
-module_param_array(ac97_clock, int, NULL, 0444);
+module_param(ac97_clock, int, 0444);
MODULE_PARM_DESC(ac97_clock, "AC'97 codec clock (default 48000Hz).");
-module_param_array(ac97_quirk, charp, NULL, 0444);
+module_param(ac97_quirk, charp, 0444);
MODULE_PARM_DESC(ac97_quirk, "AC'97 workaround for strange hardware.");
-module_param_array(dxs_support, int, NULL, 0444);
+module_param(dxs_support, int, 0444);
MODULE_PARM_DESC(dxs_support, "Support for DXS channels (0 = auto, 1 = enable, 2 = disable, 3 = 48k only, 4 = no VRA, 5 = enable any sample rate)");
+/* just for backward compatibility */
+static int enable;
+module_param(enable, bool, 0444);
+
/* revision numbers for via686 */
#define VIA_REV_686_A 0x10
@@ -130,6 +134,7 @@ MODULE_PARM_DESC(dxs_support, "Support for DXS channels (0 = auto, 1 = enable, 2
/* common offsets */
#define VIA_REG_OFFSET_STATUS 0x00 /* byte - channel status */
#define VIA_REG_STAT_ACTIVE 0x80 /* RO */
+#define VIA8233_SHADOW_STAT_ACTIVE 0x08 /* RO */
#define VIA_REG_STAT_PAUSED 0x40 /* RO */
#define VIA_REG_STAT_TRIGGER_QUEUED 0x08 /* RO */
#define VIA_REG_STAT_STOPPED 0x04 /* RWC */
@@ -328,6 +333,9 @@ struct via_dev {
unsigned int fragsize;
unsigned int bufsize;
unsigned int bufsize2;
+ int hwptr_done; /* processed frame position in the buffer */
+ int in_interrupt;
+ int shadow_shift;
};
@@ -360,7 +368,8 @@ struct _snd_via82xx {
unsigned int mpu_port_saved;
#endif
- unsigned char playback_volume[2]; /* for VIA8233/C/8235; default = 0 */
+ unsigned char playback_volume[4][2]; /* for VIA8233/C/8235; default = 0 */
+ unsigned char playback_volume_c[2]; /* for VIA8233/C/8235; default = 0 */
unsigned int intr_mask; /* SGD_SHADOW mask to check interrupts */
@@ -393,8 +402,10 @@ struct _snd_via82xx {
};
static struct pci_device_id snd_via82xx_ids[] = {
- { 0x1106, 0x3058, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TYPE_CARD_VIA686, }, /* 686A */
- { 0x1106, 0x3059, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TYPE_CARD_VIA8233, }, /* VT8233 */
+ /* 0x1106, 0x3058 */
+ { PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_5, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TYPE_CARD_VIA686, }, /* 686A */
+ /* 0x1106, 0x3059 */
+ { PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8233_5, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TYPE_CARD_VIA8233, }, /* VT8233 */
{ 0, }
};
@@ -548,7 +559,7 @@ static void snd_via82xx_codec_write(ac97_t *ac97,
{
via82xx_t *chip = ac97->private_data;
unsigned int xval;
-
+
xval = !ac97->num ? VIA_REG_AC97_CODEC_ID_PRIMARY : VIA_REG_AC97_CODEC_ID_SECONDARY;
xval <<= VIA_REG_AC97_CODEC_ID_SHIFT;
xval |= reg << VIA_REG_AC97_CMD_SHIFT;
@@ -596,14 +607,15 @@ static void snd_via82xx_channel_reset(via82xx_t *chip, viadev_t *viadev)
outb(0x00, VIADEV_REG(viadev, OFFSET_TYPE)); /* for via686 */
// outl(0, VIADEV_REG(viadev, OFFSET_CURR_PTR));
viadev->lastpos = 0;
+ viadev->hwptr_done = 0;
}
/*
* Interrupt handler
+ * Used for 686 and 8233A
*/
-
-static irqreturn_t snd_via82xx_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t snd_via686_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
via82xx_t *chip = dev_id;
unsigned int status;
@@ -622,13 +634,23 @@ static irqreturn_t snd_via82xx_interrupt(int irq, void *dev_id, struct pt_regs *
for (i = 0; i < chip->num_devs; i++) {
viadev_t *viadev = &chip->devs[i];
unsigned char c_status = inb(VIADEV_REG(viadev, OFFSET_STATUS));
- c_status &= (VIA_REG_STAT_EOL|VIA_REG_STAT_FLAG|VIA_REG_STAT_STOPPED);
- if (! c_status)
+ if (! (c_status & (VIA_REG_STAT_EOL|VIA_REG_STAT_FLAG|VIA_REG_STAT_STOPPED)))
continue;
if (viadev->substream && viadev->running) {
+ /*
+ * Update hwptr_done based on 'period elapsed'
+ * interrupts. We'll use it, when the chip returns 0
+ * for OFFSET_CURR_COUNT.
+ */
+ if (c_status & VIA_REG_STAT_EOL)
+ viadev->hwptr_done = 0;
+ else
+ viadev->hwptr_done += viadev->fragsize;
+ viadev->in_interrupt = c_status;
spin_unlock(&chip->reg_lock);
snd_pcm_period_elapsed(viadev->substream);
spin_lock(&chip->reg_lock);
+ viadev->in_interrupt = 0;
}
outb(c_status, VIADEV_REG(viadev, OFFSET_STATUS)); /* ack */
}
@@ -637,6 +659,60 @@ static irqreturn_t snd_via82xx_interrupt(int irq, void *dev_id, struct pt_regs *
}
/*
+ * Interrupt handler
+ */
+static irqreturn_t snd_via8233_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+ via82xx_t *chip = dev_id;
+ unsigned int status;
+ unsigned int i;
+ int irqreturn = 0;
+
+ /* check status for each stream */
+ spin_lock(&chip->reg_lock);
+ status = inl(VIAREG(chip, SGD_SHADOW));
+
+ for (i = 0; i < chip->num_devs; i++) {
+ viadev_t *viadev = &chip->devs[i];
+ snd_pcm_substream_t *substream;
+ unsigned char c_status, shadow_status;
+
+ shadow_status = (status >> viadev->shadow_shift) &
+ (VIA8233_SHADOW_STAT_ACTIVE|VIA_REG_STAT_EOL|
+ VIA_REG_STAT_FLAG);
+ c_status = shadow_status & (VIA_REG_STAT_EOL|VIA_REG_STAT_FLAG);
+ if (!c_status)
+ continue;
+
+ substream = viadev->substream;
+ if (substream && viadev->running) {
+ /*
+ * Update hwptr_done based on 'period elapsed'
+ * interrupts. We'll use it, when the chip returns 0
+ * for OFFSET_CURR_COUNT.
+ */
+ if (c_status & VIA_REG_STAT_EOL)
+ viadev->hwptr_done = 0;
+ else
+ viadev->hwptr_done += viadev->fragsize;
+ viadev->in_interrupt = c_status;
+ if (shadow_status & VIA8233_SHADOW_STAT_ACTIVE)
+ viadev->in_interrupt |= VIA_REG_STAT_ACTIVE;
+ spin_unlock(&chip->reg_lock);
+
+ snd_pcm_period_elapsed(substream);
+
+ spin_lock(&chip->reg_lock);
+ viadev->in_interrupt = 0;
+ }
+ outb(c_status, VIADEV_REG(viadev, OFFSET_STATUS)); /* ack */
+ irqreturn = 1;
+ }
+ spin_unlock(&chip->reg_lock);
+ return IRQ_RETVAL(irqreturn);
+}
+
+/*
* PCM callbacks
*/
@@ -699,6 +775,8 @@ static inline unsigned int calc_linear_pos(viadev_t *viadev, unsigned int idx, u
size = viadev->idx_table[idx].size;
base = viadev->idx_table[idx].offset;
res = base + size - count;
+ if (res >= viadev->bufsize)
+ res -= viadev->bufsize;
/* check the validity of the calculated position */
if (size < count) {
@@ -728,9 +806,6 @@ static inline unsigned int calc_linear_pos(viadev_t *viadev, unsigned int idx, u
}
}
}
- viadev->lastpos = res; /* remember the last position */
- if (res >= viadev->bufsize)
- res -= viadev->bufsize;
return res;
}
@@ -758,6 +833,7 @@ static snd_pcm_uframes_t snd_via686_pcm_pointer(snd_pcm_substream_t *substream)
else /* CURR_PTR holds the address + 8 */
idx = ((ptr - (unsigned int)viadev->table.addr) / 8 - 1) % viadev->tbl_entries;
res = calc_linear_pos(viadev, idx, count);
+ viadev->lastpos = res; /* remember the last position */
spin_unlock(&chip->reg_lock);
return bytes_to_frames(substream->runtime, res);
@@ -771,30 +847,44 @@ static snd_pcm_uframes_t snd_via8233_pcm_pointer(snd_pcm_substream_t *substream)
via82xx_t *chip = snd_pcm_substream_chip(substream);
viadev_t *viadev = (viadev_t *)substream->runtime->private_data;
unsigned int idx, count, res;
- int timeout = 5000;
+ int status;
snd_assert(viadev->tbl_entries, return 0);
- if (!(inb(VIADEV_REG(viadev, OFFSET_STATUS)) & VIA_REG_STAT_ACTIVE))
- return 0;
+
spin_lock(&chip->reg_lock);
- do {
- count = inl(VIADEV_REG(viadev, OFFSET_CURR_COUNT));
- /* some mobos read 0 count */
- if ((count & 0xffffff) || ! viadev->running)
- break;
- } while (--timeout);
- if (! timeout)
- snd_printd(KERN_ERR "zero position is read\n");
- idx = count >> 24;
- if (idx >= viadev->tbl_entries) {
+ count = inl(VIADEV_REG(viadev, OFFSET_CURR_COUNT));
+ status = viadev->in_interrupt;
+ if (!status)
+ status = inb(VIADEV_REG(viadev, OFFSET_STATUS));
+
+ if (!(status & VIA_REG_STAT_ACTIVE)) {
+ res = 0;
+ goto unlock;
+ }
+ if (count & 0xffffff) {
+ idx = count >> 24;
+ if (idx >= viadev->tbl_entries) {
#ifdef POINTER_DEBUG
- printk("fail: invalid idx = %i/%i\n", idx, viadev->tbl_entries);
+ printk(KERN_DEBUG "fail: invalid idx = %i/%i\n", idx, viadev->tbl_entries);
#endif
- res = viadev->lastpos;
+ res = viadev->lastpos;
+ } else {
+ count &= 0xffffff;
+ res = calc_linear_pos(viadev, idx, count);
+ }
} else {
- count &= 0xffffff;
- res = calc_linear_pos(viadev, idx, count);
- }
+ res = viadev->hwptr_done;
+ if (!viadev->in_interrupt) {
+ if (status & VIA_REG_STAT_EOL) {
+ res = 0;
+ } else
+ if (status & VIA_REG_STAT_FLAG) {
+ res += viadev->fragsize;
+ }
+ }
+ }
+unlock:
+ viadev->lastpos = res;
spin_unlock(&chip->reg_lock);
return bytes_to_frames(substream->runtime, res);
@@ -936,8 +1026,8 @@ static int snd_via8233_playback_prepare(snd_pcm_substream_t *substream)
snd_assert((rbits & ~0xfffff) == 0, return -EINVAL);
snd_via82xx_channel_reset(chip, viadev);
snd_via82xx_set_table_ptr(chip, viadev);
- outb(chip->playback_volume[0], VIADEV_REG(viadev, OFS_PLAYBACK_VOLUME_L));
- outb(chip->playback_volume[1], VIADEV_REG(viadev, OFS_PLAYBACK_VOLUME_R));
+ outb(chip->playback_volume[viadev->reg_offset / 0x10][0], VIADEV_REG(viadev, OFS_PLAYBACK_VOLUME_L));
+ outb(chip->playback_volume[viadev->reg_offset / 0x10][1], VIADEV_REG(viadev, OFS_PLAYBACK_VOLUME_R));
outl((runtime->format == SNDRV_PCM_FORMAT_S16_LE ? VIA8233_REG_TYPE_16BIT : 0) | /* format */
(runtime->channels > 1 ? VIA8233_REG_TYPE_STEREO : 0) | /* stereo */
rbits | /* rate */
@@ -1239,9 +1329,10 @@ static snd_pcm_ops_t snd_via8233_capture_ops = {
};
-static void init_viadev(via82xx_t *chip, int idx, unsigned int reg_offset, int direction)
+static void init_viadev(via82xx_t *chip, int idx, unsigned int reg_offset, int shadow_pos, int direction)
{
chip->devs[idx].reg_offset = reg_offset;
+ chip->devs[idx].shadow_shift = shadow_pos * 4;
chip->devs[idx].direction = direction;
chip->devs[idx].port = chip->port + reg_offset;
}
@@ -1271,9 +1362,9 @@ static int __devinit snd_via8233_pcm_new(via82xx_t *chip)
chip->pcms[0] = pcm;
/* set up playbacks */
for (i = 0; i < 4; i++)
- init_viadev(chip, i, 0x10 * i, 0);
+ init_viadev(chip, i, 0x10 * i, i, 0);
/* capture */
- init_viadev(chip, chip->capture_devno, VIA_REG_CAPTURE_8233_STATUS, 1);
+ init_viadev(chip, chip->capture_devno, VIA_REG_CAPTURE_8233_STATUS, 6, 1);
if ((err = snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
snd_dma_pci_data(chip->pci), 64*1024, 128*1024)) < 0)
@@ -1289,9 +1380,9 @@ static int __devinit snd_via8233_pcm_new(via82xx_t *chip)
strcpy(pcm->name, chip->card->shortname);
chip->pcms[1] = pcm;
/* set up playback */
- init_viadev(chip, chip->multi_devno, VIA_REG_MULTPLAY_STATUS, 0);
+ init_viadev(chip, chip->multi_devno, VIA_REG_MULTPLAY_STATUS, 4, 0);
/* set up capture */
- init_viadev(chip, chip->capture_devno + 1, VIA_REG_CAPTURE_8233_STATUS + 0x10, 1);
+ init_viadev(chip, chip->capture_devno + 1, VIA_REG_CAPTURE_8233_STATUS + 0x10, 7, 1);
if ((err = snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
snd_dma_pci_data(chip->pci), 64*1024, 128*1024)) < 0)
@@ -1324,9 +1415,9 @@ static int __devinit snd_via8233a_pcm_new(via82xx_t *chip)
strcpy(pcm->name, chip->card->shortname);
chip->pcms[0] = pcm;
/* set up playback */
- init_viadev(chip, chip->multi_devno, VIA_REG_MULTPLAY_STATUS, 0);
+ init_viadev(chip, chip->multi_devno, VIA_REG_MULTPLAY_STATUS, 4, 0);
/* capture */
- init_viadev(chip, chip->capture_devno, VIA_REG_CAPTURE_8233_STATUS, 1);
+ init_viadev(chip, chip->capture_devno, VIA_REG_CAPTURE_8233_STATUS, 6, 1);
if ((err = snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
snd_dma_pci_data(chip->pci), 64*1024, 128*1024)) < 0)
@@ -1345,7 +1436,7 @@ static int __devinit snd_via8233a_pcm_new(via82xx_t *chip)
strcpy(pcm->name, chip->card->shortname);
chip->pcms[1] = pcm;
/* set up playback */
- init_viadev(chip, chip->playback_devno, 0x30, 0);
+ init_viadev(chip, chip->playback_devno, 0x30, 3, 0);
if ((err = snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
snd_dma_pci_data(chip->pci), 64*1024, 128*1024)) < 0)
@@ -1375,8 +1466,8 @@ static int __devinit snd_via686_pcm_new(via82xx_t *chip)
pcm->private_data = chip;
strcpy(pcm->name, chip->card->shortname);
chip->pcms[0] = pcm;
- init_viadev(chip, 0, VIA_REG_PLAYBACK_STATUS, 0);
- init_viadev(chip, 1, VIA_REG_CAPTURE_STATUS, 1);
+ init_viadev(chip, 0, VIA_REG_PLAYBACK_STATUS, 0, 0);
+ init_viadev(chip, 1, VIA_REG_CAPTURE_STATUS, 0, 1);
if ((err = snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
snd_dma_pci_data(chip->pci), 64*1024, 128*1024)) < 0)
@@ -1497,14 +1588,46 @@ static int snd_via8233_dxs_volume_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_in
static int snd_via8233_dxs_volume_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
{
via82xx_t *chip = snd_kcontrol_chip(kcontrol);
- ucontrol->value.integer.value[0] = VIA_DXS_MAX_VOLUME - chip->playback_volume[0];
- ucontrol->value.integer.value[1] = VIA_DXS_MAX_VOLUME - chip->playback_volume[1];
+ unsigned int idx = snd_ctl_get_ioff(kcontrol, &ucontrol->id);
+
+ ucontrol->value.integer.value[0] = VIA_DXS_MAX_VOLUME - chip->playback_volume[idx][0];
+ ucontrol->value.integer.value[1] = VIA_DXS_MAX_VOLUME - chip->playback_volume[idx][1];
+ return 0;
+}
+
+static int snd_via8233_pcmdxs_volume_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+{
+ via82xx_t *chip = snd_kcontrol_chip(kcontrol);
+ ucontrol->value.integer.value[0] = VIA_DXS_MAX_VOLUME - chip->playback_volume_c[0];
+ ucontrol->value.integer.value[1] = VIA_DXS_MAX_VOLUME - chip->playback_volume_c[1];
return 0;
}
static int snd_via8233_dxs_volume_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
{
via82xx_t *chip = snd_kcontrol_chip(kcontrol);
+ unsigned int idx = snd_ctl_get_ioff(kcontrol, &ucontrol->id);
+ unsigned long port = chip->port + 0x10 * idx;
+ unsigned char val;
+ int i, change = 0;
+
+ for (i = 0; i < 2; i++) {
+ val = ucontrol->value.integer.value[i];
+ if (val > VIA_DXS_MAX_VOLUME)
+ val = VIA_DXS_MAX_VOLUME;
+ val = VIA_DXS_MAX_VOLUME - val;
+ change |= val != chip->playback_volume[idx][i];
+ if (change) {
+ chip->playback_volume[idx][i] = val;
+ outb(val, port + VIA_REG_OFS_PLAYBACK_VOLUME_L + i);
+ }
+ }
+ return change;
+}
+
+static int snd_via8233_pcmdxs_volume_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+{
+ via82xx_t *chip = snd_kcontrol_chip(kcontrol);
unsigned int idx;
unsigned char val;
int i, change = 0;
@@ -1514,11 +1637,12 @@ static int snd_via8233_dxs_volume_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_val
if (val > VIA_DXS_MAX_VOLUME)
val = VIA_DXS_MAX_VOLUME;
val = VIA_DXS_MAX_VOLUME - val;
- if (val != chip->playback_volume[i]) {
+ if (val != chip->playback_volume_c[i]) {
change = 1;
- chip->playback_volume[i] = val;
+ chip->playback_volume_c[i] = val;
for (idx = 0; idx < 4; idx++) {
unsigned long port = chip->port + 0x10 * idx;
+ chip->playback_volume[idx][i] = val;
outb(val, port + VIA_REG_OFS_PLAYBACK_VOLUME_L + i);
}
}
@@ -1526,10 +1650,19 @@ static int snd_via8233_dxs_volume_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_val
return change;
}
-static snd_kcontrol_new_t snd_via8233_dxs_volume_control __devinitdata = {
+static snd_kcontrol_new_t snd_via8233_pcmdxs_volume_control __devinitdata = {
.name = "PCM Playback Volume",
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.info = snd_via8233_dxs_volume_info,
+ .get = snd_via8233_pcmdxs_volume_get,
+ .put = snd_via8233_pcmdxs_volume_put,
+};
+
+static snd_kcontrol_new_t snd_via8233_dxs_volume_control __devinitdata = {
+ .name = "VIA DXS Playback Volume",
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .count = 4,
+ .info = snd_via8233_dxs_volume_info,
.get = snd_via8233_dxs_volume_get,
.put = snd_via8233_dxs_volume_put,
};
@@ -1616,12 +1749,12 @@ static int __devinit snd_via82xx_mixer_new(via82xx_t *chip, const char *quirk_ov
return err;
chip->ac97_bus->private_free = snd_via82xx_mixer_free_ac97_bus;
chip->ac97_bus->clock = chip->ac97_clock;
- chip->ac97_bus->shared_type = AC97_SHARED_TYPE_VIA;
memset(&ac97, 0, sizeof(ac97));
ac97.private_data = chip;
ac97.private_free = snd_via82xx_mixer_free_ac97;
ac97.pci = chip->pci;
+ ac97.scaps = AC97_SCAP_SKIP_MODEM;
if ((err = snd_ac97_mixer(chip->ac97_bus, &ac97, &chip->ac97)) < 0)
return err;
@@ -1637,12 +1770,12 @@ static int __devinit snd_via82xx_mixer_new(via82xx_t *chip, const char *quirk_ov
#ifdef SUPPORT_JOYSTICK
#define JOYSTICK_ADDR 0x200
-static int __devinit snd_via686_create_gameport(via82xx_t *chip, int dev, unsigned char *legacy)
+static int __devinit snd_via686_create_gameport(via82xx_t *chip, unsigned char *legacy)
{
struct gameport *gp;
struct resource *r;
- if (!joystick[dev])
+ if (!joystick)
return -ENODEV;
r = request_region(JOYSTICK_ADDR, 8, "VIA686 gameport");
@@ -1654,8 +1787,7 @@ static int __devinit snd_via686_create_gameport(via82xx_t *chip, int dev, unsign
chip->gameport = gp = gameport_allocate_port();
if (!gp) {
printk(KERN_ERR "via82xx: cannot allocate memory for gameport\n");
- release_resource(r);
- kfree_nocheck(r);
+ release_and_free_resource(r);
return -ENOMEM;
}
@@ -1681,12 +1813,11 @@ static void snd_via686_free_gameport(via82xx_t *chip)
gameport_unregister_port(chip->gameport);
chip->gameport = NULL;
- release_resource(r);
- kfree_nocheck(r);
+ release_and_free_resource(r);
}
}
#else
-static inline int snd_via686_create_gameport(via82xx_t *chip, int dev, unsigned char *legacy)
+static inline int snd_via686_create_gameport(via82xx_t *chip, unsigned char *legacy)
{
return -ENOSYS;
}
@@ -1698,7 +1829,7 @@ static inline void snd_via686_free_gameport(via82xx_t *chip) { }
*
*/
-static int __devinit snd_via8233_init_misc(via82xx_t *chip, int dev)
+static int __devinit snd_via8233_init_misc(via82xx_t *chip)
{
int i, err, caps;
unsigned char val;
@@ -1724,12 +1855,19 @@ static int __devinit snd_via8233_init_misc(via82xx_t *chip, int dev)
strcpy(sid.name, "PCM Playback Volume");
sid.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
if (! snd_ctl_find_id(chip->card, &sid)) {
+ snd_printd(KERN_INFO "Using DXS as PCM Playback\n");
+ err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_via8233_pcmdxs_volume_control, chip));
+ if (err < 0)
+ return err;
+ }
+ else /* Using DXS when PCM emulation is enabled is really weird */
+ {
+ /* Standalone DXS controls */
err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_via8233_dxs_volume_control, chip));
if (err < 0)
return err;
}
}
-
/* select spdif data slot 10/11 */
pci_read_config_byte(chip->pci, VIA8233_SPDIF_CTRL, &val);
val = (val & ~VIA8233_SPDIF_SLOT_MASK) | VIA8233_SPDIF_SLOT_1011;
@@ -1739,7 +1877,7 @@ static int __devinit snd_via8233_init_misc(via82xx_t *chip, int dev)
return 0;
}
-static int __devinit snd_via686_init_misc(via82xx_t *chip, int dev)
+static int __devinit snd_via686_init_misc(via82xx_t *chip)
{
unsigned char legacy, legacy_cfg;
int rev_h = 0;
@@ -1750,32 +1888,33 @@ static int __devinit snd_via686_init_misc(via82xx_t *chip, int dev)
legacy &= ~VIA_FUNC_ENABLE_GAME; /* disable joystick */
if (chip->revision >= VIA_REV_686_H) {
rev_h = 1;
- if (mpu_port[dev] >= 0x200) { /* force MIDI */
- mpu_port[dev] &= 0xfffc;
- pci_write_config_dword(chip->pci, 0x18, mpu_port[dev] | 0x01);
+ if (mpu_port >= 0x200) { /* force MIDI */
+ mpu_port &= 0xfffc;
+ pci_write_config_dword(chip->pci, 0x18, mpu_port | 0x01);
#ifdef CONFIG_PM
- chip->mpu_port_saved = mpu_port[dev];
+ chip->mpu_port_saved = mpu_port;
#endif
} else {
- mpu_port[dev] = pci_resource_start(chip->pci, 2);
+ mpu_port = pci_resource_start(chip->pci, 2);
}
} else {
- switch (mpu_port[dev]) { /* force MIDI */
+ switch (mpu_port) { /* force MIDI */
case 0x300:
case 0x310:
case 0x320:
case 0x330:
legacy_cfg &= ~(3 << 2);
- legacy_cfg |= (mpu_port[dev] & 0x0030) >> 2;
+ legacy_cfg |= (mpu_port & 0x0030) >> 2;
break;
default: /* no, use BIOS settings */
if (legacy & VIA_FUNC_ENABLE_MIDI)
- mpu_port[dev] = 0x300 + ((legacy_cfg & 0x000c) << 2);
+ mpu_port = 0x300 + ((legacy_cfg & 0x000c) << 2);
break;
}
}
- if (mpu_port[dev] >= 0x200 &&
- (chip->mpu_res = request_region(mpu_port[dev], 2, "VIA82xx MPU401")) != NULL) {
+ if (mpu_port >= 0x200 &&
+ (chip->mpu_res = request_region(mpu_port, 2, "VIA82xx MPU401"))
+ != NULL) {
if (rev_h)
legacy |= VIA_FUNC_MIDI_PNP; /* enable PCI I/O 2 */
legacy |= VIA_FUNC_ENABLE_MIDI;
@@ -1783,16 +1922,17 @@ static int __devinit snd_via686_init_misc(via82xx_t *chip, int dev)
if (rev_h)
legacy &= ~VIA_FUNC_MIDI_PNP; /* disable PCI I/O 2 */
legacy &= ~VIA_FUNC_ENABLE_MIDI;
- mpu_port[dev] = 0;
+ mpu_port = 0;
}
pci_write_config_byte(chip->pci, VIA_FUNC_ENABLE, legacy);
pci_write_config_byte(chip->pci, VIA_PNP_CONTROL, legacy_cfg);
if (chip->mpu_res) {
if (snd_mpu401_uart_new(chip->card, 0, MPU401_HW_VIA686A,
- mpu_port[dev], 1,
+ mpu_port, 1,
chip->irq, 0, &chip->rmidi) < 0) {
- printk(KERN_WARNING "unable to initialize MPU-401 at 0x%lx, skipping\n", mpu_port[dev]);
+ printk(KERN_WARNING "unable to initialize MPU-401"
+ " at 0x%lx, skipping\n", mpu_port);
legacy &= ~VIA_FUNC_ENABLE_MIDI;
} else {
legacy &= ~VIA_FUNC_MIDI_IRQMASK; /* enable MIDI interrupt */
@@ -1800,7 +1940,7 @@ static int __devinit snd_via686_init_misc(via82xx_t *chip, int dev)
pci_write_config_byte(chip->pci, VIA_FUNC_ENABLE, legacy);
}
- snd_via686_create_gameport(chip, dev, &legacy);
+ snd_via686_create_gameport(chip, &legacy);
#ifdef CONFIG_PM
chip->legacy_saved = legacy;
@@ -1887,12 +2027,11 @@ static int snd_via82xx_chip_init(via82xx_t *chip)
pci_read_config_byte(chip->pci, VIA_ACLINK_STAT, &pval);
if (pval & VIA_ACLINK_C00_READY) /* primary codec ready */
break;
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(1);
+ schedule_timeout_uninterruptible(1);
} while (time_before(jiffies, end_time));
if ((val = snd_via82xx_codec_xread(chip)) & VIA_REG_AC97_BUSY)
- snd_printk("AC'97 codec is not ready [0x%x]\n", val);
+ snd_printk(KERN_ERR "AC'97 codec is not ready [0x%x]\n", val);
#if 0 /* FIXME: we don't support the second codec yet so skip the detection now.. */
snd_via82xx_codec_xwrite(chip, VIA_REG_AC97_READ |
@@ -1907,8 +2046,7 @@ static int snd_via82xx_chip_init(via82xx_t *chip)
chip->ac97_secondary = 1;
goto __ac97_ok2;
}
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(1);
+ schedule_timeout_interruptible(1);
} while (time_before(jiffies, end_time));
/* This is ok, the most of motherboards have only one codec */
@@ -1940,8 +2078,10 @@ static int snd_via82xx_chip_init(via82xx_t *chip)
int i, idx;
for (idx = 0; idx < 4; idx++) {
unsigned long port = chip->port + 0x10 * idx;
- for (i = 0; i < 2; i++)
- outb(chip->playback_volume[i], port + VIA_REG_OFS_PLAYBACK_VOLUME_L + i);
+ for (i = 0; i < 2; i++) {
+ chip->playback_volume[idx][i]=chip->playback_volume_c[i];
+ outb(chip->playback_volume_c[i], port + VIA_REG_OFS_PLAYBACK_VOLUME_L + i);
+ }
}
}
@@ -2020,10 +2160,7 @@ static int snd_via82xx_free(via82xx_t *chip)
__end_hw:
if (chip->irq >= 0)
free_irq(chip->irq, (void *)chip);
- if (chip->mpu_res) {
- release_resource(chip->mpu_res);
- kfree_nocheck(chip->mpu_res);
- }
+ release_and_free_resource(chip->mpu_res);
pci_release_regions(chip->pci);
if (chip->chip_type == TYPE_VIA686) {
@@ -2084,9 +2221,12 @@ static int __devinit snd_via82xx_create(snd_card_t * card,
return err;
}
chip->port = pci_resource_start(pci, 0);
- if (request_irq(pci->irq, snd_via82xx_interrupt, SA_INTERRUPT|SA_SHIRQ,
+ if (request_irq(pci->irq,
+ chip_type == TYPE_VIA8233 ?
+ snd_via8233_interrupt : snd_via686_interrupt,
+ SA_INTERRUPT|SA_SHIRQ,
card->driver, (void *)chip)) {
- snd_printk("unable to grab IRQ %d\n", pci->irq);
+ snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
snd_via82xx_free(chip);
return -EBUSY;
}
@@ -2178,6 +2318,7 @@ static int __devinit check_dxs_list(struct pci_dev *pci)
{ .subvendor = 0x147b, .subdevice = 0x1415, .action = VIA_DXS_NO_VRA }, /* Abit AV8 */
{ .subvendor = 0x14ff, .subdevice = 0x0403, .action = VIA_DXS_ENABLE }, /* Twinhead mobo */
{ .subvendor = 0x14ff, .subdevice = 0x0408, .action = VIA_DXS_SRC }, /* Twinhead laptop */
+ { .subvendor = 0x1558, .subdevice = 0x4701, .action = VIA_DXS_SRC }, /* Clevo D470 */
{ .subvendor = 0x1584, .subdevice = 0x8120, .action = VIA_DXS_ENABLE }, /* Gericom/Targa/Vobis/Uniwill laptop */
{ .subvendor = 0x1584, .subdevice = 0x8123, .action = VIA_DXS_NO_VRA }, /* Uniwill (Targa Visionary XP-210) */
{ .subvendor = 0x161f, .subdevice = 0x202b, .action = VIA_DXS_NO_VRA }, /* Amira Note book */
@@ -2221,7 +2362,6 @@ static int __devinit check_dxs_list(struct pci_dev *pci)
static int __devinit snd_via82xx_probe(struct pci_dev *pci,
const struct pci_device_id *pci_id)
{
- static int dev;
snd_card_t *card;
via82xx_t *chip;
unsigned char revision;
@@ -2229,14 +2369,7 @@ static int __devinit snd_via82xx_probe(struct pci_dev *pci,
unsigned int i;
int err;
- if (dev >= SNDRV_CARDS)
- return -ENODEV;
- if (!enable[dev]) {
- dev++;
- return -ENOENT;
- }
-
- card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
+ card = snd_card_new(index, id, THIS_MODULE, 0);
if (card == NULL)
return -ENOMEM;
@@ -2259,12 +2392,12 @@ static int __devinit snd_via82xx_probe(struct pci_dev *pci,
}
}
if (chip_type != TYPE_VIA8233A) {
- if (dxs_support[dev] == VIA_DXS_AUTO)
- dxs_support[dev] = check_dxs_list(pci);
+ if (dxs_support == VIA_DXS_AUTO)
+ dxs_support = check_dxs_list(pci);
/* force to use VIA8233 or 8233A model according to
* dxs_support module option
*/
- if (dxs_support[dev] == VIA_DXS_DISABLE)
+ if (dxs_support == VIA_DXS_DISABLE)
chip_type = TYPE_VIA8233A;
else
chip_type = TYPE_VIA8233;
@@ -2282,14 +2415,15 @@ static int __devinit snd_via82xx_probe(struct pci_dev *pci,
goto __error;
}
- if ((err = snd_via82xx_create(card, pci, chip_type, revision, ac97_clock[dev], &chip)) < 0)
+ if ((err = snd_via82xx_create(card, pci, chip_type, revision,
+ ac97_clock, &chip)) < 0)
goto __error;
- if ((err = snd_via82xx_mixer_new(chip, ac97_quirk[dev])) < 0)
+ if ((err = snd_via82xx_mixer_new(chip, ac97_quirk)) < 0)
goto __error;
if (chip_type == TYPE_VIA686) {
if ((err = snd_via686_pcm_new(chip)) < 0 ||
- (err = snd_via686_init_misc(chip, dev)) < 0)
+ (err = snd_via686_init_misc(chip)) < 0)
goto __error;
} else {
if (chip_type == TYPE_VIA8233A) {
@@ -2299,16 +2433,16 @@ static int __devinit snd_via82xx_probe(struct pci_dev *pci,
} else {
if ((err = snd_via8233_pcm_new(chip)) < 0)
goto __error;
- if (dxs_support[dev] == VIA_DXS_48K)
+ if (dxs_support == VIA_DXS_48K)
chip->dxs_fixed = 1;
- else if (dxs_support[dev] == VIA_DXS_NO_VRA)
+ else if (dxs_support == VIA_DXS_NO_VRA)
chip->no_vra = 1;
- else if (dxs_support[dev] == VIA_DXS_SRC) {
+ else if (dxs_support == VIA_DXS_SRC) {
chip->no_vra = 1;
chip->dxs_src = 1;
}
}
- if ((err = snd_via8233_init_misc(chip, dev)) < 0)
+ if ((err = snd_via8233_init_misc(chip)) < 0)
goto __error;
}
@@ -2329,7 +2463,6 @@ static int __devinit snd_via82xx_probe(struct pci_dev *pci,
return err;
}
pci_set_drvdata(pci, card);
- dev++;
return 0;
__error:
@@ -2345,7 +2478,6 @@ static void __devexit snd_via82xx_remove(struct pci_dev *pci)
static struct pci_driver driver = {
.name = "VIA 82xx Audio",
- .owner = THIS_MODULE,
.id_table = snd_via82xx_ids,
.probe = snd_via82xx_probe,
.remove = __devexit_p(snd_via82xx_remove),
diff --git a/sound/pci/via82xx_modem.c b/sound/pci/via82xx_modem.c
index 7eac6f6ac737..b83660bd05b0 100644
--- a/sound/pci/via82xx_modem.c
+++ b/sound/pci/via82xx_modem.c
@@ -26,7 +26,7 @@
/*
* Changes:
*
- * Sep. 2, 2004 Sasha Khapyorsky <sashak@smlink.com>
+ * Sep. 2, 2004 Sasha Khapyorsky <sashak@alsa-project.org>
* Modified from original audio driver 'via82xx.c' to support AC97
* modems.
*/
@@ -55,20 +55,21 @@ MODULE_DESCRIPTION("VIA VT82xx modem");
MODULE_LICENSE("GPL");
MODULE_SUPPORTED_DEVICE("{{VIA,VT82C686A/B/C modem,pci}}");
-static int index[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = -2}; /* Exclude the first card */
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
-static int ac97_clock[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 48000};
+static int index = -2; /* Exclude the first card */
+static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */
+static int ac97_clock = 48000;
-module_param_array(index, int, NULL, 0444);
+module_param(index, int, 0444);
MODULE_PARM_DESC(index, "Index value for VIA 82xx bridge.");
-module_param_array(id, charp, NULL, 0444);
+module_param(id, charp, 0444);
MODULE_PARM_DESC(id, "ID string for VIA 82xx bridge.");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable modem part of VIA 82xx bridge.");
-module_param_array(ac97_clock, int, NULL, 0444);
+module_param(ac97_clock, int, 0444);
MODULE_PARM_DESC(ac97_clock, "AC'97 codec clock (default 48000Hz).");
+/* just for backward compatibility */
+static int enable;
+module_param(enable, bool, 0444);
+
/*
* Direct registers
@@ -569,7 +570,7 @@ static inline unsigned int calc_linear_pos(viadev_t *viadev, unsigned int idx, u
res = viadev->lastpos;
} else if (check_invalid_pos(viadev, res)) {
#ifdef POINTER_DEBUG
- printk("fail: idx = %i/%i, lastpos = 0x%x, bufsize2 = 0x%x, offsize = 0x%x, size = 0x%x, count = 0x%x\n", idx, viadev->tbl_entries, viadev->lastpos, viadev->bufsize2, viadev->idx_table[idx].offset, viadev->idx_table[idx].size, count);
+ printk(KERN_DEBUG "fail: idx = %i/%i, lastpos = 0x%x, bufsize2 = 0x%x, offsize = 0x%x, size = 0x%x, count = 0x%x\n", idx, viadev->tbl_entries, viadev->lastpos, viadev->bufsize2, viadev->idx_table[idx].offset, viadev->idx_table[idx].size, count);
#endif
if (count && size < count) {
snd_printd(KERN_ERR "invalid via82xx_cur_ptr, using last valid pointer\n");
@@ -832,6 +833,7 @@ static int __devinit snd_via686_pcm_new(via82xx_t *chip)
return err;
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_via686_playback_ops);
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_via686_capture_ops);
+ pcm->dev_class = SNDRV_PCM_CLASS_MODEM;
pcm->private_data = chip;
strcpy(pcm->name, chip->card->shortname);
chip->pcms[0] = pcm;
@@ -878,7 +880,6 @@ static int __devinit snd_via82xx_mixer_new(via82xx_t *chip)
return err;
chip->ac97_bus->private_free = snd_via82xx_mixer_free_ac97_bus;
chip->ac97_bus->clock = chip->ac97_clock;
- chip->ac97_bus->shared_type = AC97_SHARED_TYPE_VIA;
memset(&ac97, 0, sizeof(ac97));
ac97.private_data = chip;
@@ -967,12 +968,11 @@ static int snd_via82xx_chip_init(via82xx_t *chip)
pci_read_config_byte(chip->pci, VIA_ACLINK_STAT, &pval);
if (pval & VIA_ACLINK_C00_READY) /* primary codec ready */
break;
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(1);
+ schedule_timeout_uninterruptible(1);
} while (time_before(jiffies, end_time));
if ((val = snd_via82xx_codec_xread(chip)) & VIA_REG_AC97_BUSY)
- snd_printk("AC'97 codec is not ready [0x%x]\n", val);
+ snd_printk(KERN_ERR "AC'97 codec is not ready [0x%x]\n", val);
snd_via82xx_codec_xwrite(chip, VIA_REG_AC97_READ |
VIA_REG_AC97_SECONDARY_VALID |
@@ -986,8 +986,7 @@ static int snd_via82xx_chip_init(via82xx_t *chip)
chip->ac97_secondary = 1;
goto __ac97_ok2;
}
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(1);
+ schedule_timeout_interruptible(1);
} while (time_before(jiffies, end_time));
/* This is ok, the most of motherboards have only one codec */
@@ -1101,7 +1100,7 @@ static int __devinit snd_via82xx_create(snd_card_t * card,
chip->port = pci_resource_start(pci, 0);
if (request_irq(pci->irq, snd_via82xx_interrupt, SA_INTERRUPT|SA_SHIRQ,
card->driver, (void *)chip)) {
- snd_printk("unable to grab IRQ %d\n", pci->irq);
+ snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
snd_via82xx_free(chip);
return -EBUSY;
}
@@ -1135,7 +1134,6 @@ static int __devinit snd_via82xx_create(snd_card_t * card,
static int __devinit snd_via82xx_probe(struct pci_dev *pci,
const struct pci_device_id *pci_id)
{
- static int dev;
snd_card_t *card;
via82xx_t *chip;
unsigned char revision;
@@ -1143,14 +1141,7 @@ static int __devinit snd_via82xx_probe(struct pci_dev *pci,
unsigned int i;
int err;
- if (dev >= SNDRV_CARDS)
- return -ENODEV;
- if (!enable[dev]) {
- dev++;
- return -ENOENT;
- }
-
- card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
+ card = snd_card_new(index, id, THIS_MODULE, 0);
if (card == NULL)
return -ENOMEM;
@@ -1167,7 +1158,8 @@ static int __devinit snd_via82xx_probe(struct pci_dev *pci,
goto __error;
}
- if ((err = snd_via82xx_create(card, pci, chip_type, revision, ac97_clock[dev], &chip)) < 0)
+ if ((err = snd_via82xx_create(card, pci, chip_type, revision,
+ ac97_clock, &chip)) < 0)
goto __error;
if ((err = snd_via82xx_mixer_new(chip)) < 0)
goto __error;
@@ -1191,7 +1183,6 @@ static int __devinit snd_via82xx_probe(struct pci_dev *pci,
return err;
}
pci_set_drvdata(pci, card);
- dev++;
return 0;
__error:
@@ -1207,7 +1198,6 @@ static void __devexit snd_via82xx_remove(struct pci_dev *pci)
static struct pci_driver driver = {
.name = "VIA 82xx Modem",
- .owner = THIS_MODULE,
.id_table = snd_via82xx_modem_ids,
.probe = snd_via82xx_probe,
.remove = __devexit_p(snd_via82xx_remove),
diff --git a/sound/pci/vx222/vx222.c b/sound/pci/vx222/vx222.c
index 2a7ad9dec021..dca6bd2c7580 100644
--- a/sound/pci/vx222/vx222.c
+++ b/sound/pci/vx222/vx222.c
@@ -252,7 +252,6 @@ static void __devexit snd_vx222_remove(struct pci_dev *pci)
static struct pci_driver driver = {
.name = "Digigram VX222",
- .owner = THIS_MODULE,
.id_table = snd_vx222_ids,
.probe = snd_vx222_probe,
.remove = __devexit_p(snd_vx222_remove),
diff --git a/sound/pci/ymfpci/ymfpci.c b/sound/pci/ymfpci/ymfpci.c
index 2e69abe51aa9..d013237205d8 100644
--- a/sound/pci/ymfpci/ymfpci.c
+++ b/sound/pci/ymfpci/ymfpci.c
@@ -130,8 +130,7 @@ static int __devinit snd_ymfpci_create_gameport(ymfpci_t *chip, int dev,
chip->gameport = gp = gameport_allocate_port();
if (!gp) {
printk(KERN_ERR "ymfpci: cannot allocate memory for gameport\n");
- release_resource(r);
- kfree_nocheck(r);
+ release_and_free_resource(r);
return -ENOMEM;
}
@@ -161,8 +160,7 @@ void snd_ymfpci_free_gameport(ymfpci_t *chip)
gameport_unregister_port(chip->gameport);
chip->gameport = NULL;
- release_resource(r);
- kfree_nocheck(r);
+ release_and_free_resource(r);
}
}
#else
@@ -267,14 +265,8 @@ static int __devinit snd_card_ymfpci_probe(struct pci_dev *pci,
old_legacy_ctrl,
&chip)) < 0) {
snd_card_free(card);
- if (mpu_res) {
- release_resource(mpu_res);
- kfree_nocheck(mpu_res);
- }
- if (fm_res) {
- release_resource(fm_res);
- kfree_nocheck(fm_res);
- }
+ release_and_free_resource(mpu_res);
+ release_and_free_resource(fm_res);
return err;
}
chip->fm_res = fm_res;
@@ -328,7 +320,7 @@ static int __devinit snd_card_ymfpci_probe(struct pci_dev *pci,
pci_write_config_word(pci, PCIR_DSXG_LEGACY, legacy_ctrl);
} else if ((err = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0) {
snd_card_free(card);
- snd_printk("cannot create opl3 hwdep\n");
+ snd_printk(KERN_ERR "cannot create opl3 hwdep\n");
return err;
}
}
@@ -352,7 +344,6 @@ static void __devexit snd_card_ymfpci_remove(struct pci_dev *pci)
static struct pci_driver driver = {
.name = "Yamaha DS-XG PCI",
- .owner = THIS_MODULE,
.id_table = snd_ymfpci_ids,
.probe = snd_card_ymfpci_probe,
.remove = __devexit_p(snd_card_ymfpci_remove),
diff --git a/sound/pci/ymfpci/ymfpci_main.c b/sound/pci/ymfpci/ymfpci_main.c
index 27fa523639ae..88a43e091d77 100644
--- a/sound/pci/ymfpci/ymfpci_main.c
+++ b/sound/pci/ymfpci/ymfpci_main.c
@@ -92,9 +92,9 @@ static int snd_ymfpci_codec_ready(ymfpci_t *chip, int secondary)
if ((snd_ymfpci_readw(chip, reg) & 0x8000) == 0)
return 0;
set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(1);
+ schedule_timeout_uninterruptible(1);
} while (time_before(jiffies, end_time));
- snd_printk("codec_ready: codec %i is not ready [0x%x]\n", secondary, snd_ymfpci_readw(chip, reg));
+ snd_printk(KERN_ERR "codec_ready: codec %i is not ready [0x%x]\n", secondary, snd_ymfpci_readw(chip, reg));
return -EBUSY;
}
@@ -728,8 +728,7 @@ static void snd_ymfpci_irq_wait(ymfpci_t *chip)
init_waitqueue_entry(&wait, current);
add_wait_queue(&chip->interrupt_sleep, &wait);
atomic_inc(&chip->interrupt_sleep_count);
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(HZ/20);
+ schedule_timeout_uninterruptible(msecs_to_jiffies(50));
remove_wait_queue(&chip->interrupt_sleep, &wait);
}
}
@@ -1421,15 +1420,18 @@ static snd_kcontrol_new_t snd_ymfpci_drec_source __devinitdata = {
* Mixer controls
*/
-#define YMFPCI_SINGLE(xname, xindex, reg) \
+#define YMFPCI_SINGLE(xname, xindex, reg, shift) \
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
.info = snd_ymfpci_info_single, \
.get = snd_ymfpci_get_single, .put = snd_ymfpci_put_single, \
- .private_value = reg }
+ .private_value = ((reg) | ((shift) << 16)) }
-static int snd_ymfpci_info_single(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_ymfpci_info_single(snd_kcontrol_t *kcontrol,
+ snd_ctl_elem_info_t *uinfo)
{
- switch (kcontrol->private_value) {
+ int reg = kcontrol->private_value & 0xffff;
+
+ switch (reg) {
case YDSXGR_SPDIFOUTCTRL: break;
case YDSXGR_SPDIFINCTRL: break;
default: return -EINVAL;
@@ -1441,30 +1443,35 @@ static int snd_ymfpci_info_single(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t
return 0;
}
-static int snd_ymfpci_get_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_ymfpci_get_single(snd_kcontrol_t *kcontrol,
+ snd_ctl_elem_value_t *ucontrol)
{
ymfpci_t *chip = snd_kcontrol_chip(kcontrol);
- int reg = kcontrol->private_value;
- unsigned int shift = 0, mask = 1;
+ int reg = kcontrol->private_value & 0xffff;
+ unsigned int shift = (kcontrol->private_value >> 16) & 0xff;
+ unsigned int mask = 1;
- switch (kcontrol->private_value) {
+ switch (reg) {
case YDSXGR_SPDIFOUTCTRL: break;
case YDSXGR_SPDIFINCTRL: break;
default: return -EINVAL;
}
- ucontrol->value.integer.value[0] = (snd_ymfpci_readl(chip, reg) >> shift) & mask;
+ ucontrol->value.integer.value[0] =
+ (snd_ymfpci_readl(chip, reg) >> shift) & mask;
return 0;
}
-static int snd_ymfpci_put_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_ymfpci_put_single(snd_kcontrol_t *kcontrol,
+ snd_ctl_elem_value_t *ucontrol)
{
ymfpci_t *chip = snd_kcontrol_chip(kcontrol);
- int reg = kcontrol->private_value;
- unsigned int shift = 0, mask = 1;
+ int reg = kcontrol->private_value & 0xffff;
+ unsigned int shift = (kcontrol->private_value >> 16) & 0xff;
+ unsigned int mask = 1;
int change;
unsigned int val, oval;
- switch (kcontrol->private_value) {
+ switch (reg) {
case YDSXGR_SPDIFOUTCTRL: break;
case YDSXGR_SPDIFINCTRL: break;
default: return -EINVAL;
@@ -1583,8 +1590,9 @@ YMFPCI_DOUBLE(SNDRV_CTL_NAME_IEC958("AC97 ", PLAYBACK,VOLUME), 0, YDSXGR_ZVOUTVO
YMFPCI_DOUBLE(SNDRV_CTL_NAME_IEC958("", CAPTURE,VOLUME), 0, YDSXGR_ZVLOOPVOL),
YMFPCI_DOUBLE(SNDRV_CTL_NAME_IEC958("AC97 ",PLAYBACK,VOLUME), 1, YDSXGR_SPDIFOUTVOL),
YMFPCI_DOUBLE(SNDRV_CTL_NAME_IEC958("",CAPTURE,VOLUME), 1, YDSXGR_SPDIFLOOPVOL),
-YMFPCI_SINGLE(SNDRV_CTL_NAME_IEC958("",PLAYBACK,SWITCH), 0, YDSXGR_SPDIFOUTCTRL),
-YMFPCI_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH), 0, YDSXGR_SPDIFINCTRL),
+YMFPCI_SINGLE(SNDRV_CTL_NAME_IEC958("",PLAYBACK,SWITCH), 0, YDSXGR_SPDIFOUTCTRL, 0),
+YMFPCI_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH), 0, YDSXGR_SPDIFINCTRL, 0),
+YMFPCI_SINGLE(SNDRV_CTL_NAME_IEC958("Loop",NONE,NONE), 0, YDSXGR_SPDIFINCTRL, 4),
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "4ch Duplication",
@@ -1842,9 +1850,7 @@ static int snd_ymfpci_timer_start(snd_timer_t *timer)
unsigned int count;
chip = snd_timer_chip(timer);
- count = timer->sticks - 1;
- if (count == 0) /* minimum time is 20.8 us */
- count = 1;
+ count = (timer->sticks << 1) - 1;
spin_lock_irqsave(&chip->reg_lock, flags);
snd_ymfpci_writew(chip, YDSXGR_TIMERCOUNT, count);
snd_ymfpci_writeb(chip, YDSXGR_TIMERCTRL, 0x03);
@@ -1868,14 +1874,14 @@ static int snd_ymfpci_timer_precise_resolution(snd_timer_t *timer,
unsigned long *num, unsigned long *den)
{
*num = 1;
- *den = 96000;
+ *den = 48000;
return 0;
}
static struct _snd_timer_hardware snd_ymfpci_timer_hw = {
.flags = SNDRV_TIMER_HW_AUTO,
- .resolution = 10417, /* 1/2fs = 10.41666...us */
- .ticks = 65536,
+ .resolution = 20833, /* 1/fs = 20.8333...us */
+ .ticks = 0x8000,
.start = snd_ymfpci_timer_start,
.stop = snd_ymfpci_timer_stop,
.precise_resolution = snd_ymfpci_timer_precise_resolution,
@@ -2142,14 +2148,8 @@ static int snd_ymfpci_free(ymfpci_t *chip)
#ifdef CONFIG_PM
vfree(chip->saved_regs);
#endif
- if (chip->mpu_res) {
- release_resource(chip->mpu_res);
- kfree_nocheck(chip->mpu_res);
- }
- if (chip->fm_res) {
- release_resource(chip->fm_res);
- kfree_nocheck(chip->fm_res);
- }
+ release_and_free_resource(chip->mpu_res);
+ release_and_free_resource(chip->fm_res);
snd_ymfpci_free_gameport(chip);
if (chip->reg_area_virt)
iounmap(chip->reg_area_virt);
@@ -2158,10 +2158,7 @@ static int snd_ymfpci_free(ymfpci_t *chip)
if (chip->irq >= 0)
free_irq(chip->irq, (void *)chip);
- if (chip->res_reg_area) {
- release_resource(chip->res_reg_area);
- kfree_nocheck(chip->res_reg_area);
- }
+ release_and_free_resource(chip->res_reg_area);
pci_write_config_word(chip->pci, 0x40, chip->old_legacy_ctrl);
@@ -2290,12 +2287,12 @@ int __devinit snd_ymfpci_create(snd_card_t * card,
pci_set_master(pci);
if ((chip->res_reg_area = request_mem_region(chip->reg_area_phys, 0x8000, "YMFPCI")) == NULL) {
- snd_printk("unable to grab memory region 0x%lx-0x%lx\n", chip->reg_area_phys, chip->reg_area_phys + 0x8000 - 1);
+ snd_printk(KERN_ERR "unable to grab memory region 0x%lx-0x%lx\n", chip->reg_area_phys, chip->reg_area_phys + 0x8000 - 1);
snd_ymfpci_free(chip);
return -EBUSY;
}
if (request_irq(pci->irq, snd_ymfpci_interrupt, SA_INTERRUPT|SA_SHIRQ, "YMFPCI", (void *) chip)) {
- snd_printk("unable to grab IRQ %d\n", pci->irq);
+ snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
snd_ymfpci_free(chip);
return -EBUSY;
}
diff --git a/sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c b/sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c
index 0a954dc11b73..20b86d8df7a3 100644
--- a/sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c
+++ b/sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c
@@ -50,9 +50,9 @@ static int snd_pcm_alloc_vmalloc_buffer(snd_pcm_substream_t *subs, size_t size)
if (runtime->dma_area) {
if (runtime->dma_bytes >= size)
return 0; /* already enough large */
- vfree_nocheck(runtime->dma_area);
+ vfree(runtime->dma_area);
}
- runtime->dma_area = vmalloc_nocheck(size);
+ runtime->dma_area = vmalloc_32(size);
if (! runtime->dma_area)
return -ENOMEM;
runtime->dma_bytes = size;
@@ -67,7 +67,7 @@ static int snd_pcm_free_vmalloc_buffer(snd_pcm_substream_t *subs)
{
snd_pcm_runtime_t *runtime = subs->runtime;
if (runtime->dma_area) {
- vfree_nocheck(runtime->dma_area);
+ vfree(runtime->dma_area);
runtime->dma_area = NULL;
}
return 0;
diff --git a/sound/ppc/beep.c b/sound/ppc/beep.c
index 31ea7a4c069f..d4ec6cc3f1c5 100644
--- a/sound/ppc/beep.c
+++ b/sound/ppc/beep.c
@@ -31,14 +31,14 @@
#include "pmac.h"
struct snd_pmac_beep {
- int running; /* boolean */
- int volume; /* mixer volume: 0-100 */
+ int running; /* boolean */
+ int volume; /* mixer volume: 0-100 */
int volume_play; /* currently playing volume */
int hz;
int nsamples;
short *buf; /* allocated wave buffer */
dma_addr_t addr; /* physical address of buffer */
- struct input_dev dev;
+ struct input_dev *dev;
};
/*
@@ -171,8 +171,6 @@ static int snd_pmac_beep_event(struct input_dev *dev, unsigned int type, unsigne
* beep volume mixer
*/
-#define chip_t pmac_t
-
static int snd_pmac_info_beep(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
{
uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
@@ -212,47 +210,55 @@ static snd_kcontrol_new_t snd_pmac_beep_mixer = {
int __init snd_pmac_attach_beep(pmac_t *chip)
{
pmac_beep_t *beep;
- int err;
-
- beep = kmalloc(sizeof(*beep), GFP_KERNEL);
- if (! beep)
- return -ENOMEM;
+ struct input_dev *input_dev;
+ void *dmabuf;
+ int err = -ENOMEM;
- memset(beep, 0, sizeof(*beep));
- beep->buf = dma_alloc_coherent(&chip->pdev->dev, BEEP_BUFLEN * 4,
- &beep->addr, GFP_KERNEL);
-
- beep->dev.evbit[0] = BIT(EV_SND);
- beep->dev.sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE);
- beep->dev.event = snd_pmac_beep_event;
- beep->dev.private = chip;
+ beep = kzalloc(sizeof(*beep), GFP_KERNEL);
+ dmabuf = dma_alloc_coherent(&chip->pdev->dev, BEEP_BUFLEN * 4,
+ &beep->addr, GFP_KERNEL);
+ input_dev = input_allocate_device();
+ if (!beep || !dmabuf || !input_dev)
+ goto fail;
/* FIXME: set more better values */
- beep->dev.name = "PowerMac Beep";
- beep->dev.phys = "powermac/beep";
- beep->dev.id.bustype = BUS_ADB;
- beep->dev.id.vendor = 0x001f;
- beep->dev.id.product = 0x0001;
- beep->dev.id.version = 0x0100;
+ input_dev->name = "PowerMac Beep";
+ input_dev->phys = "powermac/beep";
+ input_dev->id.bustype = BUS_ADB;
+ input_dev->id.vendor = 0x001f;
+ input_dev->id.product = 0x0001;
+ input_dev->id.version = 0x0100;
+
+ input_dev->evbit[0] = BIT(EV_SND);
+ input_dev->sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE);
+ input_dev->event = snd_pmac_beep_event;
+ input_dev->private = chip;
+ input_dev->cdev.dev = &chip->pdev->dev;
+ beep->dev = input_dev;
+ beep->buf = dmabuf;
beep->volume = BEEP_VOLUME;
beep->running = 0;
- if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_pmac_beep_mixer, chip))) < 0) {
- kfree(beep->buf);
- kfree(beep);
- return err;
- }
+
+ err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_pmac_beep_mixer, chip));
+ if (err < 0)
+ goto fail;
chip->beep = beep;
- input_register_device(&beep->dev);
+ input_register_device(beep->dev);
return 0;
+
+ fail: input_free_device(input_dev);
+ kfree(dmabuf);
+ kfree(beep);
+ return err;
}
void snd_pmac_detach_beep(pmac_t *chip)
{
if (chip->beep) {
- input_unregister_device(&chip->beep->dev);
+ input_unregister_device(chip->beep->dev);
dma_free_coherent(&chip->pdev->dev, BEEP_BUFLEN * 4,
chip->beep->buf, chip->beep->addr);
kfree(chip->beep);
diff --git a/sound/ppc/pmac.c b/sound/ppc/pmac.c
index 392b2abd9f13..db2f1815fc30 100644
--- a/sound/ppc/pmac.c
+++ b/sound/ppc/pmac.c
@@ -220,7 +220,8 @@ static int snd_pmac_pcm_prepare(pmac_t *chip, pmac_stream_t *rec, snd_pcm_substr
/* set up constraints */
astr = snd_pmac_get_stream(chip, another_stream(rec->stream));
- snd_runtime_check(astr, return -EINVAL);
+ if (! astr)
+ return -EINVAL;
astr->cur_freqs = 1 << rate_index;
astr->cur_formats = 1 << runtime->format;
chip->rate_index = rate_index;
@@ -467,7 +468,8 @@ static int snd_pmac_hw_rule_rate(snd_pcm_hw_params_t *params,
pmac_stream_t *rec = snd_pmac_get_stream(chip, rule->deps[0]);
int i, freq_table[8], num_freqs;
- snd_runtime_check(rec, return -EINVAL);
+ if (! rec)
+ return -EINVAL;
num_freqs = 0;
for (i = chip->num_freqs - 1; i >= 0; i--) {
if (rec->cur_freqs & (1 << i))
@@ -484,7 +486,8 @@ static int snd_pmac_hw_rule_format(snd_pcm_hw_params_t *params,
pmac_t *chip = rule->private;
pmac_stream_t *rec = snd_pmac_get_stream(chip, rule->deps[0]);
- snd_runtime_check(rec, return -EINVAL);
+ if (! rec)
+ return -EINVAL;
return snd_mask_refine_set(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT),
rec->cur_formats);
}
@@ -569,7 +572,8 @@ static int snd_pmac_pcm_close(pmac_t *chip, pmac_stream_t *rec, snd_pcm_substrea
snd_pmac_dma_stop(rec);
astr = snd_pmac_get_stream(chip, another_stream(rec->stream));
- snd_runtime_check(astr, return -EINVAL);
+ if (! astr)
+ return -EINVAL;
/* reset constraints */
astr->cur_freqs = chip->freqs_ok;
@@ -1158,7 +1162,6 @@ int __init snd_pmac_new(snd_card_t *card, pmac_t **chip_return)
.dev_free = snd_pmac_dev_free,
};
- snd_runtime_check(chip_return, return -EINVAL);
*chip_return = NULL;
chip = kzalloc(sizeof(*chip), GFP_KERNEL);
@@ -1382,7 +1385,8 @@ static int snd_pmac_sleep_notify(struct pmu_sleep_notifier *self, int when)
pmac_t *chip;
chip = sleeping_pmac;
- snd_runtime_check(chip, return 0);
+ if (! chip)
+ return 0;
switch (when) {
case PBOOK_SLEEP_NOW:
diff --git a/sound/ppc/pmac.h b/sound/ppc/pmac.h
index ae3bb6c6edff..bfff788e9847 100644
--- a/sound/ppc/pmac.h
+++ b/sound/ppc/pmac.h
@@ -22,7 +22,6 @@
#ifndef __PMAC_H
#define __PMAC_H
-#include <linux/version.h>
#include <sound/control.h>
#include <sound/pcm.h>
#include "awacs.h"
diff --git a/sound/sound_core.c b/sound/sound_core.c
index 954f994592ab..394b53e20cb8 100644
--- a/sound/sound_core.c
+++ b/sound/sound_core.c
@@ -174,7 +174,7 @@ static int sound_insert_unit(struct sound_unit **list, struct file_operations *f
devfs_mk_cdev(MKDEV(SOUND_MAJOR, s->unit_minor),
S_IFCHR | mode, s->name);
- class_device_create(sound_class, MKDEV(SOUND_MAJOR, s->unit_minor),
+ class_device_create(sound_class, NULL, MKDEV(SOUND_MAJOR, s->unit_minor),
dev, s->name+6);
return r;
diff --git a/sound/sparc/cs4231.c b/sound/sparc/cs4231.c
index f4361c518e46..1f8d27a6152e 100644
--- a/sound/sparc/cs4231.c
+++ b/sound/sparc/cs4231.c
@@ -61,13 +61,37 @@ MODULE_DESCRIPTION("Sun CS4231");
MODULE_LICENSE("GPL");
MODULE_SUPPORTED_DEVICE("{{Sun,CS4231}}");
-typedef struct snd_cs4231 {
- spinlock_t lock;
- void __iomem *port;
+#ifdef SBUS_SUPPORT
+typedef struct sbus_dma_info {
+ spinlock_t lock;
+ int dir;
+ void __iomem *regs;
+} sbus_dma_info_t;
+#endif
+
+typedef struct snd_cs4231 cs4231_t;
+
+typedef struct cs4231_dma_control {
+ void (*prepare)(struct cs4231_dma_control *dma_cont, int dir);
+ void (*enable)(struct cs4231_dma_control *dma_cont, int on);
+ int (*request)(struct cs4231_dma_control *dma_cont, dma_addr_t bus_addr, size_t len);
+ unsigned int (*address)(struct cs4231_dma_control *dma_cont);
+ void (*reset)(cs4231_t *chip);
+ void (*preallocate)(cs4231_t *chip, snd_pcm_t *pcm);
#ifdef EBUS_SUPPORT
- struct ebus_dma_info eb2c;
- struct ebus_dma_info eb2p;
+ struct ebus_dma_info ebus_info;
+#endif
+#ifdef SBUS_SUPPORT
+ struct sbus_dma_info sbus_info;
#endif
+} cs4231_dma_control_t;
+
+struct snd_cs4231 {
+ spinlock_t lock;
+ void __iomem *port;
+
+ cs4231_dma_control_t p_dma;
+ cs4231_dma_control_t c_dma;
u32 flags;
#define CS4231_FLAG_EBUS 0x00000001
@@ -106,7 +130,7 @@ typedef struct snd_cs4231 {
unsigned int irq[2];
unsigned int regs_size;
struct snd_cs4231 *next;
-} cs4231_t;
+};
static cs4231_t *cs4231_list;
@@ -251,6 +275,15 @@ static cs4231_t *cs4231_list;
#define APCPNVA 0x38UL /* APC Play DMA Next Address */
#define APCPNC 0x3cUL /* APC Play Next Count */
+/* Defines for SBUS DMA-routines */
+
+#define APCVA 0x0UL /* APC DMA Address */
+#define APCC 0x4UL /* APC Count */
+#define APCNVA 0x8UL /* APC DMA Next Address */
+#define APCNC 0xcUL /* APC Next Count */
+#define APC_PLAY 0x30UL /* Play registers start at 0x30 */
+#define APC_RECORD 0x20UL /* Record registers start at 0x20 */
+
/* APCCSR bits */
#define APC_INT_PENDING 0x800000 /* Interrupt Pending */
@@ -569,8 +602,7 @@ static void snd_cs4231_mce_down(cs4231_t *chip)
spin_unlock_irqrestore(&chip->lock, flags);
}
-#ifdef EBUS_SUPPORT
-static void snd_cs4231_ebus_advance_dma(struct ebus_dma_info *p, snd_pcm_substream_t *substream, unsigned int *periods_sent)
+static void snd_cs4231_advance_dma(struct cs4231_dma_control *dma_cont, snd_pcm_substream_t *substream, unsigned int *periods_sent)
{
snd_pcm_runtime_t *runtime = substream->runtime;
@@ -581,129 +613,41 @@ static void snd_cs4231_ebus_advance_dma(struct ebus_dma_info *p, snd_pcm_substre
if (period_size >= (1 << 24))
BUG();
- if (ebus_dma_request(p, runtime->dma_addr + offset, period_size))
+ if (dma_cont->request(dma_cont, runtime->dma_addr + offset, period_size))
return;
(*periods_sent) = ((*periods_sent) + 1) % runtime->periods;
}
}
-#endif
-
-#ifdef SBUS_SUPPORT
-static void snd_cs4231_sbus_advance_dma(snd_pcm_substream_t *substream, unsigned int *periods_sent)
-{
- cs4231_t *chip = snd_pcm_substream_chip(substream);
- snd_pcm_runtime_t *runtime = substream->runtime;
-
- unsigned int period_size = snd_pcm_lib_period_bytes(substream);
- unsigned int offset = period_size * (*periods_sent % runtime->periods);
-
- if (runtime->period_size > 0xffff + 1)
- BUG();
-
- switch (substream->stream) {
- case SNDRV_PCM_STREAM_PLAYBACK:
- sbus_writel(runtime->dma_addr + offset, chip->port + APCPNVA);
- sbus_writel(period_size, chip->port + APCPNC);
- break;
- case SNDRV_PCM_STREAM_CAPTURE:
- sbus_writel(runtime->dma_addr + offset, chip->port + APCCNVA);
- sbus_writel(period_size, chip->port + APCCNC);
- break;
- }
-
- (*periods_sent) = (*periods_sent + 1) % runtime->periods;
-}
-#endif
static void cs4231_dma_trigger(snd_pcm_substream_t *substream, unsigned int what, int on)
{
cs4231_t *chip = snd_pcm_substream_chip(substream);
+ cs4231_dma_control_t *dma_cont;
-#ifdef EBUS_SUPPORT
- if (chip->flags & CS4231_FLAG_EBUS) {
- if (what & CS4231_PLAYBACK_ENABLE) {
- if (on) {
- ebus_dma_prepare(&chip->eb2p, 0);
- ebus_dma_enable(&chip->eb2p, 1);
- snd_cs4231_ebus_advance_dma(&chip->eb2p,
- chip->playback_substream,
- &chip->p_periods_sent);
- } else {
- ebus_dma_enable(&chip->eb2p, 0);
- }
- }
- if (what & CS4231_RECORD_ENABLE) {
- if (on) {
- ebus_dma_prepare(&chip->eb2c, 1);
- ebus_dma_enable(&chip->eb2c, 1);
- snd_cs4231_ebus_advance_dma(&chip->eb2c,
- chip->capture_substream,
- &chip->c_periods_sent);
- } else {
- ebus_dma_enable(&chip->eb2c, 0);
- }
- }
- } else {
-#endif
-#ifdef SBUS_SUPPORT
- u32 csr = sbus_readl(chip->port + APCCSR);
- /* I don't know why, but on sbus the period counter must
- * only start counting after the first period is sent.
- * Therefore this dummy thing.
- */
- unsigned int dummy = 0;
-
- switch (what) {
- case CS4231_PLAYBACK_ENABLE:
+ if (what & CS4231_PLAYBACK_ENABLE) {
+ dma_cont = &chip->p_dma;
if (on) {
- csr &= ~APC_XINT_PLAY;
- sbus_writel(csr, chip->port + APCCSR);
-
- csr &= ~APC_PPAUSE;
- sbus_writel(csr, chip->port + APCCSR);
-
- snd_cs4231_sbus_advance_dma(substream, &dummy);
-
- csr |= APC_GENL_INT | APC_PLAY_INT | APC_XINT_ENA |
- APC_XINT_PLAY | APC_XINT_EMPT | APC_XINT_GENL |
- APC_XINT_PENA | APC_PDMA_READY;
- sbus_writel(csr, chip->port + APCCSR);
+ dma_cont->prepare(dma_cont, 0);
+ dma_cont->enable(dma_cont, 1);
+ snd_cs4231_advance_dma(dma_cont,
+ chip->playback_substream,
+ &chip->p_periods_sent);
} else {
- csr |= APC_PPAUSE;
- sbus_writel(csr, chip->port + APCCSR);
-
- csr &= ~APC_PDMA_READY;
- sbus_writel(csr, chip->port + APCCSR);
+ dma_cont->enable(dma_cont, 0);
}
- break;
- case CS4231_RECORD_ENABLE:
+ }
+ if (what & CS4231_RECORD_ENABLE) {
+ dma_cont = &chip->c_dma;
if (on) {
- csr &= ~APC_XINT_CAPT;
- sbus_writel(csr, chip->port + APCCSR);
-
- csr &= ~APC_CPAUSE;
- sbus_writel(csr, chip->port + APCCSR);
-
- snd_cs4231_sbus_advance_dma(substream, &dummy);
-
- csr |= APC_GENL_INT | APC_CAPT_INT | APC_XINT_ENA |
- APC_XINT_CAPT | APC_XINT_CEMP | APC_XINT_GENL |
- APC_CDMA_READY;
-
- sbus_writel(csr, chip->port + APCCSR);
+ dma_cont->prepare(dma_cont, 1);
+ dma_cont->enable(dma_cont, 1);
+ snd_cs4231_advance_dma(dma_cont,
+ chip->capture_substream,
+ &chip->c_periods_sent);
} else {
- csr |= APC_CPAUSE;
- sbus_writel(csr, chip->port + APCCSR);
-
- csr &= ~APC_CDMA_READY;
- sbus_writel(csr, chip->port + APCCSR);
+ dma_cont->enable(dma_cont, 0);
}
- break;
- }
-#endif
-#ifdef EBUS_SUPPORT
}
-#endif
}
static int snd_cs4231_trigger(snd_pcm_substream_t *substream, int cmd)
@@ -1136,10 +1080,7 @@ static int snd_cs4231_playback_prepare(snd_pcm_substream_t *substream)
if (runtime->period_size > 0xffff + 1)
BUG();
- snd_cs4231_out(chip, CS4231_PLY_LWR_CNT, (runtime->period_size - 1) & 0x00ff);
- snd_cs4231_out(chip, CS4231_PLY_UPR_CNT, (runtime->period_size - 1) >> 8 & 0x00ff);
chip->p_periods_sent = 0;
-
spin_unlock_irqrestore(&chip->lock, flags);
return 0;
@@ -1171,16 +1112,14 @@ static int snd_cs4231_capture_hw_free(snd_pcm_substream_t *substream)
static int snd_cs4231_capture_prepare(snd_pcm_substream_t *substream)
{
cs4231_t *chip = snd_pcm_substream_chip(substream);
- snd_pcm_runtime_t *runtime = substream->runtime;
unsigned long flags;
spin_lock_irqsave(&chip->lock, flags);
chip->image[CS4231_IFACE_CTRL] &= ~(CS4231_RECORD_ENABLE |
CS4231_RECORD_PIO);
- snd_cs4231_out(chip, CS4231_REC_LWR_CNT, (runtime->period_size - 1) & 0x00ff);
- snd_cs4231_out(chip, CS4231_REC_LWR_CNT, (runtime->period_size - 1) >> 8 & 0x00ff);
+ chip->c_periods_sent = 0;
spin_unlock_irqrestore(&chip->lock, flags);
return 0;
@@ -1199,134 +1138,55 @@ static void snd_cs4231_overrange(cs4231_t *chip)
chip->capture_substream->runtime->overrange++;
}
-static irqreturn_t snd_cs4231_generic_interrupt(cs4231_t *chip)
-{
- unsigned long flags;
- unsigned char status;
-
- /*This is IRQ is not raised by the cs4231*/
- if (!(__cs4231_readb(chip, CS4231P(chip, STATUS)) & CS4231_GLOBALIRQ))
- return IRQ_NONE;
-
- status = snd_cs4231_in(chip, CS4231_IRQ_STATUS);
-
- if (status & CS4231_TIMER_IRQ) {
- if (chip->timer)
- snd_timer_interrupt(chip->timer, chip->timer->sticks);
- }
-
- if (status & CS4231_RECORD_IRQ)
- snd_cs4231_overrange(chip);
-
- /* ACK the CS4231 interrupt. */
- spin_lock_irqsave(&chip->lock, flags);
- snd_cs4231_outm(chip, CS4231_IRQ_STATUS, ~CS4231_ALL_IRQS | ~status, 0);
- spin_unlock_irqrestore(&chip->lock, flags);
-
- return 0;
-}
-
-#ifdef SBUS_SUPPORT
-static irqreturn_t snd_cs4231_sbus_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-{
- cs4231_t *chip = dev_id;
-
- /* ACK the APC interrupt. */
- u32 csr = sbus_readl(chip->port + APCCSR);
-
- sbus_writel(csr, chip->port + APCCSR);
-
- if ((chip->image[CS4231_IFACE_CTRL] & CS4231_PLAYBACK_ENABLE) &&
- (csr & APC_PLAY_INT) &&
- (csr & APC_XINT_PNVA) &&
- !(csr & APC_XINT_EMPT)) {
- snd_cs4231_sbus_advance_dma(chip->playback_substream,
- &chip->p_periods_sent);
- snd_pcm_period_elapsed(chip->playback_substream);
- }
-
- if ((chip->image[CS4231_IFACE_CTRL] & CS4231_RECORD_ENABLE) &&
- (csr & APC_CAPT_INT) &&
- (csr & APC_XINT_CNVA)) {
- snd_cs4231_sbus_advance_dma(chip->capture_substream,
- &chip->c_periods_sent);
- snd_pcm_period_elapsed(chip->capture_substream);
- }
-
- return snd_cs4231_generic_interrupt(chip);
-}
-#endif
-
-#ifdef EBUS_SUPPORT
-static void snd_cs4231_ebus_play_callback(struct ebus_dma_info *p, int event, void *cookie)
+static void snd_cs4231_play_callback(cs4231_t *cookie)
{
cs4231_t *chip = cookie;
if (chip->image[CS4231_IFACE_CTRL] & CS4231_PLAYBACK_ENABLE) {
snd_pcm_period_elapsed(chip->playback_substream);
- snd_cs4231_ebus_advance_dma(p, chip->playback_substream,
+ snd_cs4231_advance_dma(&chip->p_dma, chip->playback_substream,
&chip->p_periods_sent);
}
}
-static void snd_cs4231_ebus_capture_callback(struct ebus_dma_info *p, int event, void *cookie)
+static void snd_cs4231_capture_callback(cs4231_t *cookie)
{
cs4231_t *chip = cookie;
if (chip->image[CS4231_IFACE_CTRL] & CS4231_RECORD_ENABLE) {
snd_pcm_period_elapsed(chip->capture_substream);
- snd_cs4231_ebus_advance_dma(p, chip->capture_substream,
+ snd_cs4231_advance_dma(&chip->c_dma, chip->capture_substream,
&chip->c_periods_sent);
}
}
-#endif
static snd_pcm_uframes_t snd_cs4231_playback_pointer(snd_pcm_substream_t *substream)
{
cs4231_t *chip = snd_pcm_substream_chip(substream);
- size_t ptr, residue, period_bytes;
-
+ cs4231_dma_control_t *dma_cont = &chip->p_dma;
+ size_t ptr;
+
if (!(chip->image[CS4231_IFACE_CTRL] & CS4231_PLAYBACK_ENABLE))
return 0;
- period_bytes = snd_pcm_lib_period_bytes(substream);
- ptr = period_bytes * chip->p_periods_sent;
-#ifdef EBUS_SUPPORT
- if (chip->flags & CS4231_FLAG_EBUS) {
- residue = ebus_dma_residue(&chip->eb2p);
- } else {
-#endif
-#ifdef SBUS_SUPPORT
- residue = sbus_readl(chip->port + APCPC);
-#endif
-#ifdef EBUS_SUPPORT
- }
-#endif
- ptr += period_bytes - residue;
-
+ ptr = dma_cont->address(dma_cont);
+ if (ptr != 0)
+ ptr -= substream->runtime->dma_addr;
+
return bytes_to_frames(substream->runtime, ptr);
}
static snd_pcm_uframes_t snd_cs4231_capture_pointer(snd_pcm_substream_t * substream)
{
cs4231_t *chip = snd_pcm_substream_chip(substream);
- size_t ptr, residue, period_bytes;
+ cs4231_dma_control_t *dma_cont = &chip->c_dma;
+ size_t ptr;
if (!(chip->image[CS4231_IFACE_CTRL] & CS4231_RECORD_ENABLE))
return 0;
- period_bytes = snd_pcm_lib_period_bytes(substream);
- ptr = period_bytes * chip->c_periods_sent;
-#ifdef EBUS_SUPPORT
- if (chip->flags & CS4231_FLAG_EBUS) {
- residue = ebus_dma_residue(&chip->eb2c);
- } else {
-#endif
-#ifdef SBUS_SUPPORT
- residue = sbus_readl(chip->port + APCCC);
-#endif
-#ifdef EBUS_SUPPORT
- }
-#endif
- ptr += period_bytes - residue;
+ ptr = dma_cont->address(dma_cont);
+ if (ptr != 0)
+ ptr -= substream->runtime->dma_addr;
+
return bytes_to_frames(substream->runtime, ptr);
}
@@ -1362,30 +1222,8 @@ static int snd_cs4231_probe(cs4231_t *chip)
spin_lock_irqsave(&chip->lock, flags);
- /* Reset DMA engine. */
-#ifdef EBUS_SUPPORT
- if (chip->flags & CS4231_FLAG_EBUS) {
- /* Done by ebus_dma_register */
- } else {
-#endif
-#ifdef SBUS_SUPPORT
- sbus_writel(APC_CHIP_RESET, chip->port + APCCSR);
- sbus_writel(0x00, chip->port + APCCSR);
- sbus_writel(sbus_readl(chip->port + APCCSR) | APC_CDC_RESET,
- chip->port + APCCSR);
-
- udelay(20);
-
- sbus_writel(sbus_readl(chip->port + APCCSR) & ~APC_CDC_RESET,
- chip->port + APCCSR);
- sbus_writel(sbus_readl(chip->port + APCCSR) | (APC_XINT_ENA |
- APC_XINT_PENA |
- APC_XINT_CENA),
- chip->port + APCCSR);
-#endif
-#ifdef EBUS_SUPPORT
- }
-#endif
+ /* Reset DMA engine (sbus only). */
+ chip->p_dma.reset(chip);
__cs4231_readb(chip, CS4231P(chip, STATUS)); /* clear any pendings IRQ */
__cs4231_writeb(chip, 0, CS4231P(chip, STATUS));
@@ -1505,8 +1343,8 @@ static int snd_cs4231_playback_close(snd_pcm_substream_t *substream)
{
cs4231_t *chip = snd_pcm_substream_chip(substream);
- chip->playback_substream = NULL;
snd_cs4231_close(chip, CS4231_MODE_PLAY);
+ chip->playback_substream = NULL;
return 0;
}
@@ -1515,8 +1353,8 @@ static int snd_cs4231_capture_close(snd_pcm_substream_t *substream)
{
cs4231_t *chip = snd_pcm_substream_chip(substream);
- chip->capture_substream = NULL;
snd_cs4231_close(chip, CS4231_MODE_RECORD);
+ chip->capture_substream = NULL;
return 0;
}
@@ -1571,21 +1409,7 @@ int snd_cs4231_pcm(cs4231_t *chip)
pcm->info_flags = SNDRV_PCM_INFO_JOINT_DUPLEX;
strcpy(pcm->name, "CS4231");
-#ifdef EBUS_SUPPORT
- if (chip->flags & CS4231_FLAG_EBUS) {
- snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
- snd_dma_pci_data(chip->dev_u.pdev),
- 64*1024, 128*1024);
- } else {
-#endif
-#ifdef SBUS_SUPPORT
- snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_SBUS,
- snd_dma_sbus_data(chip->dev_u.sdev),
- 64*1024, 128*1024);
-#endif
-#ifdef EBUS_SUPPORT
- }
-#endif
+ chip->p_dma.preallocate(chip, pcm);
chip->pcm = pcm;
@@ -1942,6 +1766,180 @@ out_err:
}
#ifdef SBUS_SUPPORT
+
+static irqreturn_t snd_cs4231_sbus_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+ unsigned long flags;
+ unsigned char status;
+ u32 csr;
+ cs4231_t *chip = dev_id;
+
+ /*This is IRQ is not raised by the cs4231*/
+ if (!(__cs4231_readb(chip, CS4231P(chip, STATUS)) & CS4231_GLOBALIRQ))
+ return IRQ_NONE;
+
+ /* ACK the APC interrupt. */
+ csr = sbus_readl(chip->port + APCCSR);
+
+ sbus_writel(csr, chip->port + APCCSR);
+
+ if ((csr & APC_PDMA_READY) &&
+ (csr & APC_PLAY_INT) &&
+ (csr & APC_XINT_PNVA) &&
+ !(csr & APC_XINT_EMPT))
+ snd_cs4231_play_callback(chip);
+
+ if ((csr & APC_CDMA_READY) &&
+ (csr & APC_CAPT_INT) &&
+ (csr & APC_XINT_CNVA) &&
+ !(csr & APC_XINT_EMPT))
+ snd_cs4231_capture_callback(chip);
+
+ status = snd_cs4231_in(chip, CS4231_IRQ_STATUS);
+
+ if (status & CS4231_TIMER_IRQ) {
+ if (chip->timer)
+ snd_timer_interrupt(chip->timer, chip->timer->sticks);
+ }
+
+ if ((status & CS4231_RECORD_IRQ) && (csr & APC_CDMA_READY))
+ snd_cs4231_overrange(chip);
+
+ /* ACK the CS4231 interrupt. */
+ spin_lock_irqsave(&chip->lock, flags);
+ snd_cs4231_outm(chip, CS4231_IRQ_STATUS, ~CS4231_ALL_IRQS | ~status, 0);
+ spin_unlock_irqrestore(&chip->lock, flags);
+
+ return 0;
+}
+
+/*
+ * SBUS DMA routines
+ */
+
+int sbus_dma_request(struct cs4231_dma_control *dma_cont, dma_addr_t bus_addr, size_t len)
+{
+ unsigned long flags;
+ u32 test, csr;
+ int err;
+ sbus_dma_info_t *base = &dma_cont->sbus_info;
+
+ if (len >= (1 << 24))
+ return -EINVAL;
+ spin_lock_irqsave(&base->lock, flags);
+ csr = sbus_readl(base->regs + APCCSR);
+ err = -EINVAL;
+ test = APC_CDMA_READY;
+ if ( base->dir == APC_PLAY )
+ test = APC_PDMA_READY;
+ if (!(csr & test))
+ goto out;
+ err = -EBUSY;
+ csr = sbus_readl(base->regs + APCCSR);
+ test = APC_XINT_CNVA;
+ if ( base->dir == APC_PLAY )
+ test = APC_XINT_PNVA;
+ if (!(csr & test))
+ goto out;
+ err = 0;
+ sbus_writel(bus_addr, base->regs + base->dir + APCNVA);
+ sbus_writel(len, base->regs + base->dir + APCNC);
+out:
+ spin_unlock_irqrestore(&base->lock, flags);
+ return err;
+}
+
+void sbus_dma_prepare(struct cs4231_dma_control *dma_cont, int d)
+{
+ unsigned long flags;
+ u32 csr, test;
+ sbus_dma_info_t *base = &dma_cont->sbus_info;
+
+ spin_lock_irqsave(&base->lock, flags);
+ csr = sbus_readl(base->regs + APCCSR);
+ test = APC_GENL_INT | APC_PLAY_INT | APC_XINT_ENA |
+ APC_XINT_PLAY | APC_XINT_PEMP | APC_XINT_GENL |
+ APC_XINT_PENA;
+ if ( base->dir == APC_RECORD )
+ test = APC_GENL_INT | APC_CAPT_INT | APC_XINT_ENA |
+ APC_XINT_CAPT | APC_XINT_CEMP | APC_XINT_GENL;
+ csr |= test;
+ sbus_writel(csr, base->regs + APCCSR);
+ spin_unlock_irqrestore(&base->lock, flags);
+}
+
+void sbus_dma_enable(struct cs4231_dma_control *dma_cont, int on)
+{
+ unsigned long flags;
+ u32 csr, shift;
+ sbus_dma_info_t *base = &dma_cont->sbus_info;
+
+ spin_lock_irqsave(&base->lock, flags);
+ if (!on) {
+ if (base->dir == APC_PLAY) {
+ sbus_writel(0, base->regs + base->dir + APCNVA);
+ sbus_writel(1, base->regs + base->dir + APCC);
+ }
+ else
+ {
+ sbus_writel(0, base->regs + base->dir + APCNC);
+ sbus_writel(0, base->regs + base->dir + APCVA);
+ }
+ }
+ udelay(600);
+ csr = sbus_readl(base->regs + APCCSR);
+ shift = 0;
+ if ( base->dir == APC_PLAY )
+ shift = 1;
+ if (on)
+ csr &= ~(APC_CPAUSE << shift);
+ else
+ csr |= (APC_CPAUSE << shift);
+ sbus_writel(csr, base->regs + APCCSR);
+ if (on)
+ csr |= (APC_CDMA_READY << shift);
+ else
+ csr &= ~(APC_CDMA_READY << shift);
+ sbus_writel(csr, base->regs + APCCSR);
+
+ spin_unlock_irqrestore(&base->lock, flags);
+}
+
+unsigned int sbus_dma_addr(struct cs4231_dma_control *dma_cont)
+{
+ sbus_dma_info_t *base = &dma_cont->sbus_info;
+
+ return sbus_readl(base->regs + base->dir + APCVA);
+}
+
+void sbus_dma_reset(cs4231_t *chip)
+{
+ sbus_writel(APC_CHIP_RESET, chip->port + APCCSR);
+ sbus_writel(0x00, chip->port + APCCSR);
+ sbus_writel(sbus_readl(chip->port + APCCSR) | APC_CDC_RESET,
+ chip->port + APCCSR);
+
+ udelay(20);
+
+ sbus_writel(sbus_readl(chip->port + APCCSR) & ~APC_CDC_RESET,
+ chip->port + APCCSR);
+ sbus_writel(sbus_readl(chip->port + APCCSR) | (APC_XINT_ENA |
+ APC_XINT_PENA |
+ APC_XINT_CENA),
+ chip->port + APCCSR);
+}
+
+void sbus_dma_preallocate(cs4231_t *chip, snd_pcm_t *pcm)
+{
+ snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_SBUS,
+ snd_dma_sbus_data(chip->dev_u.sdev),
+ 64*1024, 128*1024);
+}
+
+/*
+ * Init and exit routines
+ */
+
static int snd_cs4231_sbus_free(cs4231_t *chip)
{
if (chip->irq[0])
@@ -1983,6 +1981,8 @@ static int __init snd_cs4231_sbus_create(snd_card_t *card,
return -ENOMEM;
spin_lock_init(&chip->lock);
+ spin_lock_init(&chip->c_dma.sbus_info.lock);
+ spin_lock_init(&chip->p_dma.sbus_info.lock);
init_MUTEX(&chip->mce_mutex);
init_MUTEX(&chip->open_mutex);
chip->card = card;
@@ -1998,6 +1998,25 @@ static int __init snd_cs4231_sbus_create(snd_card_t *card,
return -EIO;
}
+ chip->c_dma.sbus_info.regs = chip->port;
+ chip->p_dma.sbus_info.regs = chip->port;
+ chip->c_dma.sbus_info.dir = APC_RECORD;
+ chip->p_dma.sbus_info.dir = APC_PLAY;
+
+ chip->p_dma.prepare = sbus_dma_prepare;
+ chip->p_dma.enable = sbus_dma_enable;
+ chip->p_dma.request = sbus_dma_request;
+ chip->p_dma.address = sbus_dma_addr;
+ chip->p_dma.reset = sbus_dma_reset;
+ chip->p_dma.preallocate = sbus_dma_preallocate;
+
+ chip->c_dma.prepare = sbus_dma_prepare;
+ chip->c_dma.enable = sbus_dma_enable;
+ chip->c_dma.request = sbus_dma_request;
+ chip->c_dma.address = sbus_dma_addr;
+ chip->c_dma.reset = sbus_dma_reset;
+ chip->c_dma.preallocate = sbus_dma_preallocate;
+
if (request_irq(sdev->irqs[0], snd_cs4231_sbus_interrupt,
SA_SHIRQ, "cs4231", chip)) {
snd_printdd("cs4231-%d: Unable to grab SBUS IRQ %s\n",
@@ -2051,15 +2070,70 @@ static int cs4231_sbus_attach(struct sbus_dev *sdev)
#endif
#ifdef EBUS_SUPPORT
+
+static void snd_cs4231_ebus_play_callback(struct ebus_dma_info *p, int event, void *cookie)
+{
+ cs4231_t *chip = cookie;
+
+ snd_cs4231_play_callback(chip);
+}
+
+static void snd_cs4231_ebus_capture_callback(struct ebus_dma_info *p, int event, void *cookie)
+{
+ cs4231_t *chip = cookie;
+
+ snd_cs4231_capture_callback(chip);
+}
+
+/*
+ * EBUS DMA wrappers
+ */
+
+int _ebus_dma_request(struct cs4231_dma_control *dma_cont, dma_addr_t bus_addr, size_t len)
+{
+ return ebus_dma_request(&dma_cont->ebus_info, bus_addr, len);
+}
+
+void _ebus_dma_enable(struct cs4231_dma_control *dma_cont, int on)
+{
+ ebus_dma_enable(&dma_cont->ebus_info, on);
+}
+
+void _ebus_dma_prepare(struct cs4231_dma_control *dma_cont, int dir)
+{
+ ebus_dma_prepare(&dma_cont->ebus_info, dir);
+}
+
+unsigned int _ebus_dma_addr(struct cs4231_dma_control *dma_cont)
+{
+ return ebus_dma_addr(&dma_cont->ebus_info);
+}
+
+void _ebus_dma_reset(cs4231_t *chip)
+{
+ return;
+}
+
+void _ebus_dma_preallocate(cs4231_t *chip, snd_pcm_t *pcm)
+{
+ snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
+ snd_dma_pci_data(chip->dev_u.pdev),
+ 64*1024, 128*1024);
+}
+
+/*
+ * Init and exit routines
+ */
+
static int snd_cs4231_ebus_free(cs4231_t *chip)
{
- if (chip->eb2c.regs) {
- ebus_dma_unregister(&chip->eb2c);
- iounmap(chip->eb2c.regs);
+ if (chip->c_dma.ebus_info.regs) {
+ ebus_dma_unregister(&chip->c_dma.ebus_info);
+ iounmap(chip->c_dma.ebus_info.regs);
}
- if (chip->eb2p.regs) {
- ebus_dma_unregister(&chip->eb2p);
- iounmap(chip->eb2p.regs);
+ if (chip->p_dma.ebus_info.regs) {
+ ebus_dma_unregister(&chip->p_dma.ebus_info);
+ iounmap(chip->p_dma.ebus_info.regs);
}
if (chip->port)
@@ -2097,8 +2171,8 @@ static int __init snd_cs4231_ebus_create(snd_card_t *card,
return -ENOMEM;
spin_lock_init(&chip->lock);
- spin_lock_init(&chip->eb2c.lock);
- spin_lock_init(&chip->eb2p.lock);
+ spin_lock_init(&chip->c_dma.ebus_info.lock);
+ spin_lock_init(&chip->p_dma.ebus_info.lock);
init_MUTEX(&chip->mce_mutex);
init_MUTEX(&chip->open_mutex);
chip->flags |= CS4231_FLAG_EBUS;
@@ -2106,43 +2180,57 @@ static int __init snd_cs4231_ebus_create(snd_card_t *card,
chip->dev_u.pdev = edev->bus->self;
memcpy(&chip->image, &snd_cs4231_original_image,
sizeof(snd_cs4231_original_image));
- strcpy(chip->eb2c.name, "cs4231(capture)");
- chip->eb2c.flags = EBUS_DMA_FLAG_USE_EBDMA_HANDLER;
- chip->eb2c.callback = snd_cs4231_ebus_capture_callback;
- chip->eb2c.client_cookie = chip;
- chip->eb2c.irq = edev->irqs[0];
- strcpy(chip->eb2p.name, "cs4231(play)");
- chip->eb2p.flags = EBUS_DMA_FLAG_USE_EBDMA_HANDLER;
- chip->eb2p.callback = snd_cs4231_ebus_play_callback;
- chip->eb2p.client_cookie = chip;
- chip->eb2p.irq = edev->irqs[1];
+ strcpy(chip->c_dma.ebus_info.name, "cs4231(capture)");
+ chip->c_dma.ebus_info.flags = EBUS_DMA_FLAG_USE_EBDMA_HANDLER;
+ chip->c_dma.ebus_info.callback = snd_cs4231_ebus_capture_callback;
+ chip->c_dma.ebus_info.client_cookie = chip;
+ chip->c_dma.ebus_info.irq = edev->irqs[0];
+ strcpy(chip->p_dma.ebus_info.name, "cs4231(play)");
+ chip->p_dma.ebus_info.flags = EBUS_DMA_FLAG_USE_EBDMA_HANDLER;
+ chip->p_dma.ebus_info.callback = snd_cs4231_ebus_play_callback;
+ chip->p_dma.ebus_info.client_cookie = chip;
+ chip->p_dma.ebus_info.irq = edev->irqs[1];
+
+ chip->p_dma.prepare = _ebus_dma_prepare;
+ chip->p_dma.enable = _ebus_dma_enable;
+ chip->p_dma.request = _ebus_dma_request;
+ chip->p_dma.address = _ebus_dma_addr;
+ chip->p_dma.reset = _ebus_dma_reset;
+ chip->p_dma.preallocate = _ebus_dma_preallocate;
+
+ chip->c_dma.prepare = _ebus_dma_prepare;
+ chip->c_dma.enable = _ebus_dma_enable;
+ chip->c_dma.request = _ebus_dma_request;
+ chip->c_dma.address = _ebus_dma_addr;
+ chip->c_dma.reset = _ebus_dma_reset;
+ chip->c_dma.preallocate = _ebus_dma_preallocate;
chip->port = ioremap(edev->resource[0].start, 0x10);
- chip->eb2p.regs = ioremap(edev->resource[1].start, 0x10);
- chip->eb2c.regs = ioremap(edev->resource[2].start, 0x10);
- if (!chip->port || !chip->eb2p.regs || !chip->eb2c.regs) {
+ chip->p_dma.ebus_info.regs = ioremap(edev->resource[1].start, 0x10);
+ chip->c_dma.ebus_info.regs = ioremap(edev->resource[2].start, 0x10);
+ if (!chip->port || !chip->p_dma.ebus_info.regs || !chip->c_dma.ebus_info.regs) {
snd_cs4231_ebus_free(chip);
snd_printdd("cs4231-%d: Unable to map chip registers.\n", dev);
return -EIO;
}
- if (ebus_dma_register(&chip->eb2c)) {
+ if (ebus_dma_register(&chip->c_dma.ebus_info)) {
snd_cs4231_ebus_free(chip);
snd_printdd("cs4231-%d: Unable to register EBUS capture DMA\n", dev);
return -EBUSY;
}
- if (ebus_dma_irq_enable(&chip->eb2c, 1)) {
+ if (ebus_dma_irq_enable(&chip->c_dma.ebus_info, 1)) {
snd_cs4231_ebus_free(chip);
snd_printdd("cs4231-%d: Unable to enable EBUS capture IRQ\n", dev);
return -EBUSY;
}
- if (ebus_dma_register(&chip->eb2p)) {
+ if (ebus_dma_register(&chip->p_dma.ebus_info)) {
snd_cs4231_ebus_free(chip);
snd_printdd("cs4231-%d: Unable to register EBUS play DMA\n", dev);
return -EBUSY;
}
- if (ebus_dma_irq_enable(&chip->eb2p, 1)) {
+ if (ebus_dma_irq_enable(&chip->p_dma.ebus_info, 1)) {
snd_cs4231_ebus_free(chip);
snd_printdd("cs4231-%d: Unable to enable EBUS play IRQ\n", dev);
return -EBUSY;
diff --git a/sound/sparc/dbri.c b/sound/sparc/dbri.c
index b5c4c15ae7f0..59a771294709 100644
--- a/sound/sparc/dbri.c
+++ b/sound/sparc/dbri.c
@@ -343,9 +343,6 @@ typedef struct snd_dbri {
struct snd_dbri *next;
} snd_dbri_t;
-/* Needed for the ALSA macros to work */
-#define chip_t snd_dbri_t
-
#define DBRI_MAX_VOLUME 63 /* Output volume */
#define DBRI_MAX_GAIN 15 /* Input gain */
#define DBRI_RIGHT_BALANCE 255
@@ -1767,7 +1764,7 @@ play:
spin_unlock_irqrestore(&dbri->lock, flags);
}
-DECLARE_TASKLET(xmit_descs_task, xmit_descs, 0);
+static DECLARE_TASKLET(xmit_descs_task, xmit_descs, 0);
/* transmission_complete_intr()
*
diff --git a/sound/synth/emux/emux_synth.c b/sound/synth/emux/emux_synth.c
index 751bf1272af3..bd71b73be657 100644
--- a/sound/synth/emux/emux_synth.c
+++ b/sound/synth/emux/emux_synth.c
@@ -171,7 +171,6 @@ snd_emux_note_off(void *p, int note, int vel, snd_midi_channel_t *chan)
vp = &emu->voices[ch];
if (STATE_IS_PLAYING(vp->state) &&
vp->chan == chan && vp->key == note) {
- vp->time = emu->use_time++;
vp->state = SNDRV_EMUX_ST_RELEASED;
if (vp->ontime == jiffies) {
/* if note-off is sent too shortly after
diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c
index 2ead878bcb8f..99dae024b640 100644
--- a/sound/usb/usbaudio.c
+++ b/sound/usb/usbaudio.c
@@ -41,7 +41,6 @@
#include <sound/driver.h>
#include <linux/bitops.h>
#include <linux/init.h>
-#include <linux/interrupt.h>
#include <linux/list.h>
#include <linux/slab.h>
#include <linux/string.h>
@@ -185,7 +184,6 @@ struct snd_usb_substream {
unsigned int num_formats; /* number of supported audio formats (list) */
struct list_head fmt_list; /* format list */
spinlock_t lock;
- struct tasklet_struct start_period_elapsed; /* for start trigger */
struct snd_urb_ops ops; /* callbacks (must be filled at init) */
};
@@ -480,6 +478,28 @@ static int retire_playback_sync_urb_hs(snd_usb_substream_t *subs,
}
/*
+ * Prepare urb for streaming before playback starts.
+ *
+ * We don't care about (or have) any data, so we just send a transfer delimiter.
+ */
+static int prepare_startup_playback_urb(snd_usb_substream_t *subs,
+ snd_pcm_runtime_t *runtime,
+ struct urb *urb)
+{
+ unsigned int i;
+ snd_urb_ctx_t *ctx = urb->context;
+
+ urb->dev = ctx->subs->dev;
+ urb->number_of_packets = subs->packs_per_ms;
+ for (i = 0; i < subs->packs_per_ms; ++i) {
+ urb->iso_frame_desc[i].offset = 0;
+ urb->iso_frame_desc[i].length = 0;
+ }
+ urb->transfer_buffer_length = 0;
+ return 0;
+}
+
+/*
* prepare urb for playback data pipe
*
* Since a URB can handle only a single linear buffer, we must use double
@@ -568,12 +588,8 @@ static int prepare_playback_urb(snd_usb_substream_t *subs,
subs->hwptr_done -= runtime->buffer_size;
spin_unlock_irqrestore(&subs->lock, flags);
urb->transfer_buffer_length = offs * stride;
- if (period_elapsed) {
- if (likely(subs->running))
- snd_pcm_period_elapsed(subs->pcm_substream);
- else
- tasklet_hi_schedule(&subs->start_period_elapsed);
- }
+ if (period_elapsed)
+ snd_pcm_period_elapsed(subs->pcm_substream);
return 0;
}
@@ -588,22 +604,12 @@ static int retire_playback_urb(snd_usb_substream_t *subs,
return 0;
}
-/*
- * Delay the snd_pcm_period_elapsed() call until after the start trigger
- * callback so that we're not longer in the substream's lock.
- */
-static void start_period_elapsed(unsigned long data)
-{
- snd_usb_substream_t *subs = (snd_usb_substream_t *)data;
- snd_pcm_period_elapsed(subs->pcm_substream);
-}
-
/*
*/
static struct snd_urb_ops audio_urb_ops[2] = {
{
- .prepare = prepare_playback_urb,
+ .prepare = prepare_startup_playback_urb,
.retire = retire_playback_urb,
.prepare_sync = prepare_playback_sync_urb,
.retire_sync = retire_playback_sync_urb,
@@ -618,7 +624,7 @@ static struct snd_urb_ops audio_urb_ops[2] = {
static struct snd_urb_ops audio_urb_ops_high_speed[2] = {
{
- .prepare = prepare_playback_urb,
+ .prepare = prepare_startup_playback_urb,
.retire = retire_playback_urb,
.prepare_sync = prepare_playback_sync_urb_hs,
.retire_sync = retire_playback_sync_urb_hs,
@@ -692,9 +698,9 @@ static int snd_pcm_alloc_vmalloc_buffer(snd_pcm_substream_t *subs, size_t size)
if (runtime->dma_area) {
if (runtime->dma_bytes >= size)
return 0; /* already large enough */
- vfree_nocheck(runtime->dma_area);
+ vfree(runtime->dma_area);
}
- runtime->dma_area = vmalloc_nocheck(size);
+ runtime->dma_area = vmalloc(size);
if (! runtime->dma_area)
return -ENOMEM;
runtime->dma_bytes = size;
@@ -706,7 +712,7 @@ static int snd_pcm_free_vmalloc_buffer(snd_pcm_substream_t *subs)
{
snd_pcm_runtime_t *runtime = subs->runtime;
if (runtime->dma_area) {
- vfree_nocheck(runtime->dma_area);
+ vfree(runtime->dma_area);
runtime->dma_area = NULL;
}
return 0;
@@ -838,8 +844,7 @@ static int wait_clear_urbs(snd_usb_substream_t *subs)
}
if (! alive)
break;
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(1);
+ schedule_timeout_uninterruptible(1);
} while (time_before(jiffies, end_time));
if (alive)
snd_printk(KERN_ERR "timeout: still %d active urbs..\n", alive);
@@ -864,25 +869,40 @@ static snd_pcm_uframes_t snd_usb_pcm_pointer(snd_pcm_substream_t *substream)
/*
- * start/stop substream
+ * start/stop playback substream
*/
-static int snd_usb_pcm_trigger(snd_pcm_substream_t *substream, int cmd)
+static int snd_usb_pcm_playback_trigger(snd_pcm_substream_t *substream,
+ int cmd)
{
- snd_usb_substream_t *subs = (snd_usb_substream_t *)substream->runtime->private_data;
- int err;
+ snd_usb_substream_t *subs = substream->runtime->private_data;
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
- err = start_urbs(subs, substream->runtime);
- break;
+ subs->ops.prepare = prepare_playback_urb;
+ return 0;
case SNDRV_PCM_TRIGGER_STOP:
- err = deactivate_urbs(subs, 0, 0);
- break;
+ return deactivate_urbs(subs, 0, 0);
default:
- err = -EINVAL;
- break;
+ return -EINVAL;
+ }
+}
+
+/*
+ * start/stop capture substream
+ */
+static int snd_usb_pcm_capture_trigger(snd_pcm_substream_t *substream,
+ int cmd)
+{
+ snd_usb_substream_t *subs = substream->runtime->private_data;
+
+ switch (cmd) {
+ case SNDRV_PCM_TRIGGER_START:
+ return start_urbs(subs, substream->runtime);
+ case SNDRV_PCM_TRIGGER_STOP:
+ return deactivate_urbs(subs, 0, 0);
+ default:
+ return -EINVAL;
}
- return err < 0 ? err : 0;
}
@@ -1044,7 +1064,7 @@ static int init_substream_urbs(snd_usb_substream_t *subs, unsigned int period_by
u->urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP;
u->urb->interval = 1 << subs->datainterval;
u->urb->context = u;
- u->urb->complete = snd_usb_complete_callback(snd_complete_urb);
+ u->urb->complete = snd_complete_urb;
}
if (subs->syncpipe) {
@@ -1070,7 +1090,7 @@ static int init_substream_urbs(snd_usb_substream_t *subs, unsigned int period_by
u->urb->number_of_packets = 1;
u->urb->interval = 1 << subs->syncinterval;
u->urb->context = u;
- u->urb->complete = snd_usb_complete_callback(snd_complete_sync_urb);
+ u->urb->complete = snd_complete_sync_urb;
}
}
return 0;
@@ -1414,7 +1434,7 @@ static int snd_usb_hw_free(snd_pcm_substream_t *substream)
static int snd_usb_pcm_prepare(snd_pcm_substream_t *substream)
{
snd_pcm_runtime_t *runtime = substream->runtime;
- snd_usb_substream_t *subs = (snd_usb_substream_t *)runtime->private_data;
+ snd_usb_substream_t *subs = runtime->private_data;
if (! subs->cur_audiofmt) {
snd_printk(KERN_ERR "usbaudio: no format is specified!\n");
@@ -1434,7 +1454,13 @@ static int snd_usb_pcm_prepare(snd_pcm_substream_t *substream)
deactivate_urbs(subs, 0, 1);
wait_clear_urbs(subs);
- return 0;
+ /* for playback, submit the URBs now; otherwise, the first hwptr_done
+ * updates for all URBs would happen at the same time when starting */
+ if (subs->direction == SNDRV_PCM_STREAM_PLAYBACK) {
+ subs->ops.prepare = prepare_startup_playback_urb;
+ return start_urbs(subs, runtime);
+ } else
+ return 0;
}
static snd_pcm_hardware_t snd_usb_playback =
@@ -1848,7 +1874,7 @@ static snd_pcm_ops_t snd_usb_playback_ops = {
.hw_params = snd_usb_hw_params,
.hw_free = snd_usb_hw_free,
.prepare = snd_usb_pcm_prepare,
- .trigger = snd_usb_pcm_trigger,
+ .trigger = snd_usb_pcm_playback_trigger,
.pointer = snd_usb_pcm_pointer,
.page = snd_pcm_get_vmalloc_page,
};
@@ -1860,7 +1886,7 @@ static snd_pcm_ops_t snd_usb_capture_ops = {
.hw_params = snd_usb_hw_params,
.hw_free = snd_usb_hw_free,
.prepare = snd_usb_pcm_prepare,
- .trigger = snd_usb_pcm_trigger,
+ .trigger = snd_usb_pcm_capture_trigger,
.pointer = snd_usb_pcm_pointer,
.page = snd_pcm_get_vmalloc_page,
};
@@ -2079,9 +2105,6 @@ static void init_substream(snd_usb_stream_t *as, int stream, struct audioformat
INIT_LIST_HEAD(&subs->fmt_list);
spin_lock_init(&subs->lock);
- if (stream == SNDRV_PCM_STREAM_PLAYBACK)
- tasklet_init(&subs->start_period_elapsed, start_period_elapsed,
- (unsigned long)subs);
subs->stream = as;
subs->direction = stream;
@@ -2755,9 +2778,9 @@ static int create_fixed_stream_quirk(snd_usb_audio_t *chip,
/*
* create a stream for an interface with proper descriptors
*/
-static int create_standard_interface_quirk(snd_usb_audio_t *chip,
- struct usb_interface *iface,
- const snd_usb_audio_quirk_t *quirk)
+static int create_standard_audio_quirk(snd_usb_audio_t *chip,
+ struct usb_interface *iface,
+ const snd_usb_audio_quirk_t *quirk)
{
struct usb_host_interface *alts;
struct usb_interface_descriptor *altsd;
@@ -2765,24 +2788,14 @@ static int create_standard_interface_quirk(snd_usb_audio_t *chip,
alts = &iface->altsetting[0];
altsd = get_iface_desc(alts);
- switch (quirk->type) {
- case QUIRK_AUDIO_STANDARD_INTERFACE:
- err = parse_audio_endpoints(chip, altsd->bInterfaceNumber);
- if (!err)
- usb_set_interface(chip->dev, altsd->bInterfaceNumber, 0); /* reset the current interface */
- break;
- case QUIRK_MIDI_STANDARD_INTERFACE:
- err = snd_usb_create_midi_interface(chip, iface, NULL);
- break;
- default:
- snd_printd(KERN_ERR "invalid quirk type %d\n", quirk->type);
- return -ENXIO;
- }
+ err = parse_audio_endpoints(chip, altsd->bInterfaceNumber);
if (err < 0) {
snd_printk(KERN_ERR "cannot setup if %d: error %d\n",
altsd->bInterfaceNumber, err);
return err;
}
+ /* reset the current interface */
+ usb_set_interface(chip->dev, altsd->bInterfaceNumber, 0);
return 0;
}
@@ -3044,7 +3057,7 @@ static int snd_usb_create_quirk(snd_usb_audio_t *chip,
[QUIRK_MIDI_RAW] = snd_usb_create_midi_interface,
[QUIRK_MIDI_EMAGIC] = snd_usb_create_midi_interface,
[QUIRK_MIDI_MIDITECH] = snd_usb_create_midi_interface,
- [QUIRK_AUDIO_STANDARD_INTERFACE] = create_standard_interface_quirk,
+ [QUIRK_AUDIO_STANDARD_INTERFACE] = create_standard_audio_quirk,
[QUIRK_AUDIO_FIXED_ENDPOINT] = create_fixed_stream_quirk,
[QUIRK_AUDIO_EDIROL_UA700_UA25] = create_ua700_ua25_quirk,
[QUIRK_AUDIO_EDIROL_UA1000] = create_ua1000_quirk,
@@ -3222,7 +3235,6 @@ static void *snd_usb_audio_probe(struct usb_device *dev,
struct usb_interface *intf,
const struct usb_device_id *usb_id)
{
- struct usb_host_config *config = dev->actconfig;
const snd_usb_audio_quirk_t *quirk = (const snd_usb_audio_quirk_t *)usb_id->driver_info;
int i, err;
snd_usb_audio_t *chip;
@@ -3243,7 +3255,6 @@ static void *snd_usb_audio_probe(struct usb_device *dev,
if (id == USB_ID(0x041e, 0x3000)) {
if (snd_usb_extigy_boot_quirk(dev, intf) < 0)
goto __err_val;
- config = dev->actconfig;
}
/* SB Audigy 2 NX needs its own boot-up magic, too */
if (id == USB_ID(0x041e, 0x3020)) {
@@ -3272,11 +3283,6 @@ static void *snd_usb_audio_probe(struct usb_device *dev,
/* it's a fresh one.
* now look for an empty slot and create a new card instance
*/
- /* first, set the current configuration for this device */
- if (usb_reset_configuration(dev) < 0) {
- snd_printk(KERN_ERR "cannot reset configuration (value 0x%x)\n", get_cfg_desc(config)->bConfigurationValue);
- goto __error;
- }
for (i = 0; i < SNDRV_CARDS; i++)
if (enable[i] && ! usb_chip[i] &&
(vid[i] == -1 || vid[i] == USB_ID_VENDOR(id)) &&
diff --git a/sound/usb/usbaudio.h b/sound/usb/usbaudio.h
index ad9eab211d8f..b5802022bb19 100644
--- a/sound/usb/usbaudio.h
+++ b/sound/usb/usbaudio.h
@@ -249,14 +249,6 @@ void snd_usbmidi_disconnect(struct list_head *p);
#define get_cfg_desc(cfg) (&(cfg)->desc)
#endif
-#ifndef usb_pipe_needs_resubmit
-#define usb_pipe_needs_resubmit(pipe) 1
-#endif
-
-#ifndef snd_usb_complete_callback
-#define snd_usb_complete_callback(x) (x)
-#endif
-
#ifndef snd_usb_get_speed
#define snd_usb_get_speed(dev) ((dev)->speed)
#endif
diff --git a/sound/usb/usbmidi.c b/sound/usb/usbmidi.c
index e0d0365453b3..f8aa662562a0 100644
--- a/sound/usb/usbmidi.c
+++ b/sound/usb/usbmidi.c
@@ -47,7 +47,6 @@
#include <linux/timer.h>
#include <linux/usb.h>
#include <sound/core.h>
-#include <sound/minors.h>
#include <sound/rawmidi.h>
#include "usbaudio.h"
@@ -163,7 +162,7 @@ static const uint8_t snd_usbmidi_cin_length[] = {
/*
* Submits the URB, with error handling.
*/
-static int snd_usbmidi_submit_urb(struct urb* urb, int flags)
+static int snd_usbmidi_submit_urb(struct urb* urb, gfp_t flags)
{
int err = usb_submit_urb(urb, flags);
if (err < 0 && err != -ENODEV)
@@ -246,10 +245,8 @@ static void snd_usbmidi_in_urb_complete(struct urb* urb, struct pt_regs *regs)
}
}
- if (usb_pipe_needs_resubmit(urb->pipe)) {
- urb->dev = ep->umidi->chip->dev;
- snd_usbmidi_submit_urb(urb, GFP_ATOMIC);
- }
+ urb->dev = ep->umidi->chip->dev;
+ snd_usbmidi_submit_urb(urb, GFP_ATOMIC);
}
static void snd_usbmidi_out_urb_complete(struct urb* urb, struct pt_regs *regs)
@@ -863,13 +860,12 @@ static int snd_usbmidi_in_endpoint_create(snd_usb_midi_t* umidi,
return -ENOMEM;
}
if (ep_info->in_interval)
- usb_fill_int_urb(ep->urb, umidi->chip->dev, pipe, buffer, length,
- snd_usb_complete_callback(snd_usbmidi_in_urb_complete),
- ep, ep_info->in_interval);
+ usb_fill_int_urb(ep->urb, umidi->chip->dev, pipe, buffer,
+ length, snd_usbmidi_in_urb_complete, ep,
+ ep_info->in_interval);
else
- usb_fill_bulk_urb(ep->urb, umidi->chip->dev, pipe, buffer, length,
- snd_usb_complete_callback(snd_usbmidi_in_urb_complete),
- ep);
+ usb_fill_bulk_urb(ep->urb, umidi->chip->dev, pipe, buffer,
+ length, snd_usbmidi_in_urb_complete, ep);
ep->urb->transfer_flags = URB_NO_TRANSFER_DMA_MAP;
rep->in = ep;
@@ -933,8 +929,7 @@ static int snd_usbmidi_out_endpoint_create(snd_usb_midi_t* umidi,
return -ENOMEM;
}
usb_fill_bulk_urb(ep->urb, umidi->chip->dev, pipe, buffer,
- ep->max_transfer,
- snd_usb_complete_callback(snd_usbmidi_out_urb_complete), ep);
+ ep->max_transfer, snd_usbmidi_out_urb_complete, ep);
ep->urb->transfer_flags = URB_NO_TRANSFER_DMA_MAP;
spin_lock_init(&ep->buffer_lock);
@@ -1550,46 +1545,45 @@ int snd_usb_create_midi_interface(snd_usb_audio_t* chip,
/* detect the endpoint(s) to use */
memset(endpoints, 0, sizeof(endpoints));
- if (!quirk) {
+ switch (quirk ? quirk->type : QUIRK_MIDI_STANDARD_INTERFACE) {
+ case QUIRK_MIDI_STANDARD_INTERFACE:
err = snd_usbmidi_get_ms_info(umidi, endpoints);
- } else {
- switch (quirk->type) {
- case QUIRK_MIDI_FIXED_ENDPOINT:
- memcpy(&endpoints[0], quirk->data,
- sizeof(snd_usb_midi_endpoint_info_t));
- err = snd_usbmidi_detect_endpoints(umidi, &endpoints[0], 1);
- break;
- case QUIRK_MIDI_YAMAHA:
- err = snd_usbmidi_detect_yamaha(umidi, &endpoints[0]);
- break;
- case QUIRK_MIDI_MIDIMAN:
- umidi->usb_protocol_ops = &snd_usbmidi_midiman_ops;
- memcpy(&endpoints[0], quirk->data,
- sizeof(snd_usb_midi_endpoint_info_t));
- err = 0;
- break;
- case QUIRK_MIDI_NOVATION:
- umidi->usb_protocol_ops = &snd_usbmidi_novation_ops;
- err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints);
- break;
- case QUIRK_MIDI_RAW:
- umidi->usb_protocol_ops = &snd_usbmidi_raw_ops;
- err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints);
- break;
- case QUIRK_MIDI_EMAGIC:
- umidi->usb_protocol_ops = &snd_usbmidi_emagic_ops;
- memcpy(&endpoints[0], quirk->data,
- sizeof(snd_usb_midi_endpoint_info_t));
- err = snd_usbmidi_detect_endpoints(umidi, &endpoints[0], 1);
- break;
- case QUIRK_MIDI_MIDITECH:
- err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints);
- break;
- default:
- snd_printd(KERN_ERR "invalid quirk type %d\n", quirk->type);
- err = -ENXIO;
- break;
- }
+ break;
+ case QUIRK_MIDI_FIXED_ENDPOINT:
+ memcpy(&endpoints[0], quirk->data,
+ sizeof(snd_usb_midi_endpoint_info_t));
+ err = snd_usbmidi_detect_endpoints(umidi, &endpoints[0], 1);
+ break;
+ case QUIRK_MIDI_YAMAHA:
+ err = snd_usbmidi_detect_yamaha(umidi, &endpoints[0]);
+ break;
+ case QUIRK_MIDI_MIDIMAN:
+ umidi->usb_protocol_ops = &snd_usbmidi_midiman_ops;
+ memcpy(&endpoints[0], quirk->data,
+ sizeof(snd_usb_midi_endpoint_info_t));
+ err = 0;
+ break;
+ case QUIRK_MIDI_NOVATION:
+ umidi->usb_protocol_ops = &snd_usbmidi_novation_ops;
+ err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints);
+ break;
+ case QUIRK_MIDI_RAW:
+ umidi->usb_protocol_ops = &snd_usbmidi_raw_ops;
+ err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints);
+ break;
+ case QUIRK_MIDI_EMAGIC:
+ umidi->usb_protocol_ops = &snd_usbmidi_emagic_ops;
+ memcpy(&endpoints[0], quirk->data,
+ sizeof(snd_usb_midi_endpoint_info_t));
+ err = snd_usbmidi_detect_endpoints(umidi, &endpoints[0], 1);
+ break;
+ case QUIRK_MIDI_MIDITECH:
+ err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints);
+ break;
+ default:
+ snd_printd(KERN_ERR "invalid quirk type %d\n", quirk->type);
+ err = -ENXIO;
+ break;
}
if (err < 0) {
kfree(umidi);
diff --git a/sound/usb/usbmixer.c b/sound/usb/usbmixer.c
index c3c08c9cb46e..e570d140258d 100644
--- a/sound/usb/usbmixer.c
+++ b/sound/usb/usbmixer.c
@@ -911,7 +911,7 @@ static void build_feature_ctl(mixer_build_t *state, unsigned char *desc,
case USB_ID(0x0672, 0x1041):
if (!strcmp(kctl->id.name, "PCM Playback Volume") &&
cval->min == -15616) {
- snd_printk("using volume control quirk for the UDA1321/N101 chip\n");
+ snd_printk(KERN_INFO "using volume control quirk for the UDA1321/N101 chip\n");
cval->max = -256;
}
}
diff --git a/sound/usb/usbquirks.h b/sound/usb/usbquirks.h
index 948759da6563..ba506c3871f4 100644
--- a/sound/usb/usbquirks.h
+++ b/sound/usb/usbquirks.h
@@ -294,6 +294,7 @@ YAMAHA_DEVICE(0x7010, "UB99"),
}
},
{
+ /* a later revision uses ID 0x0099 */
USB_DEVICE(0x0582, 0x0005),
.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
.vendor_name = "EDIROL",
@@ -384,6 +385,7 @@ YAMAHA_DEVICE(0x7010, "UB99"),
}
},
{
+ /* a later revision uses ID 0x009d */
USB_DEVICE(0x0582, 0x0009),
.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
.vendor_name = "EDIROL",
@@ -532,6 +534,7 @@ YAMAHA_DEVICE(0x7010, "UB99"),
}
},
{
+ /* has ID 0x0013 when not in "Advanced Driver" mode */
USB_DEVICE(0x0582, 0x0012),
.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
.vendor_name = "Roland",
@@ -545,6 +548,7 @@ YAMAHA_DEVICE(0x7010, "UB99"),
}
},
{
+ /* has ID 0x0015 when not in "Advanced Driver" mode */
USB_DEVICE(0x0582, 0x0014),
.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
.vendor_name = "EDIROL",
@@ -558,6 +562,7 @@ YAMAHA_DEVICE(0x7010, "UB99"),
}
},
{
+ /* has ID 0x0017 when not in "Advanced Driver" mode */
USB_DEVICE(0x0582, 0x0016),
.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
.vendor_name = "EDIROL",
@@ -588,6 +593,7 @@ YAMAHA_DEVICE(0x7010, "UB99"),
}
},
{
+ /* has ID 0x001c when not in "Advanced Driver" mode */
USB_DEVICE(0x0582, 0x001b),
.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
.vendor_name = "Roland",
@@ -618,6 +624,7 @@ YAMAHA_DEVICE(0x7010, "UB99"),
}
},
{
+ /* has ID 0x001e when not in "Advanced Driver" mode */
USB_DEVICE(0x0582, 0x001d),
.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
.vendor_name = "Roland",
@@ -631,6 +638,7 @@ YAMAHA_DEVICE(0x7010, "UB99"),
}
},
{
+ /* has ID 0x0024 when not in "Advanced Driver" mode */
USB_DEVICE(0x0582, 0x0023),
.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
.vendor_name = "EDIROL",
@@ -675,6 +683,7 @@ YAMAHA_DEVICE(0x7010, "UB99"),
}
},
{
+ /* has ID 0x0028 when not in "Advanced Driver" mode */
USB_DEVICE(0x0582, 0x0027),
.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
.vendor_name = "EDIROL",
@@ -688,6 +697,7 @@ YAMAHA_DEVICE(0x7010, "UB99"),
}
},
{
+ /* has ID 0x002a when not in "Advanced Driver" mode */
USB_DEVICE(0x0582, 0x0029),
.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
.vendor_name = "EDIROL",
@@ -732,6 +742,7 @@ YAMAHA_DEVICE(0x7010, "UB99"),
}
},
{
+ /* has ID 0x002e when not in "Advanced Driver" mode */
USB_DEVICE(0x0582, 0x002d),
.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
.vendor_name = "Roland",
@@ -745,6 +756,7 @@ YAMAHA_DEVICE(0x7010, "UB99"),
}
},
{
+ /* has ID 0x0030 when not in "Advanced Driver" mode */
USB_DEVICE(0x0582, 0x002f),
.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
.vendor_name = "Roland",
@@ -758,6 +770,7 @@ YAMAHA_DEVICE(0x7010, "UB99"),
}
},
{
+ /* has ID 0x0034 when not in "Advanced Driver" mode */
USB_DEVICE(0x0582, 0x0033),
.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
.vendor_name = "EDIROL",
@@ -770,7 +783,12 @@ YAMAHA_DEVICE(0x7010, "UB99"),
}
}
},
+ /* TODO: add Roland M-1000 support */
{
+ /*
+ * Has ID 0x0038 when not in "Advanced Driver" mode;
+ * later revisions use IDs 0x0054 and 0x00a2.
+ */
USB_DEVICE(0x0582, 0x0037),
.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
.vendor_name = "Roland",
@@ -815,6 +833,7 @@ YAMAHA_DEVICE(0x7010, "UB99"),
}
},
{
+ /* has ID 0x0041 when not in "Advanced Driver" mode */
USB_DEVICE(0x0582, 0x0040),
.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
.vendor_name = "Roland",
@@ -828,6 +847,7 @@ YAMAHA_DEVICE(0x7010, "UB99"),
}
},
{
+ /* has ID 0x0043 when not in "Advanced Driver" mode */
USB_DEVICE(0x0582, 0x0042),
.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
.vendor_name = "Roland",
@@ -871,6 +891,7 @@ YAMAHA_DEVICE(0x7010, "UB99"),
}
},
{
+ /* has ID 0x004a when not in "Advanced Driver" mode */
USB_DEVICE(0x0582, 0x0048),
.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
.vendor_name = "EDIROL",
@@ -883,7 +904,9 @@ YAMAHA_DEVICE(0x7010, "UB99"),
}
}
},
+ /* TODO: add Edirol M-100FX support */
{
+ /* has ID 0x004f when not in "Advanced Driver" mode */
USB_DEVICE(0x0582, 0x004d),
.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
.vendor_name = "EDIROL",
@@ -931,7 +954,9 @@ YAMAHA_DEVICE(0x7010, "UB99"),
.type = QUIRK_MIDI_STANDARD_INTERFACE
}
},
+ /* TODO: add Roland EXR support */
{
+ /* has ID 0x0067 when not in "Advanced Driver" mode */
USB_DEVICE(0x0582, 0x0065),
.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
.vendor_name = "EDIROL",
@@ -945,6 +970,7 @@ YAMAHA_DEVICE(0x7010, "UB99"),
}
},
{
+ /* has ID 0x006b when not in "Advanced Driver" mode */
USB_DEVICE_VENDOR_SPEC(0x0582, 0x006a),
.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
.vendor_name = "Roland",
@@ -958,6 +984,7 @@ YAMAHA_DEVICE(0x7010, "UB99"),
}
},
{
+ /* has ID 0x006e when not in "Advanced Driver" mode */
USB_DEVICE(0x0582, 0x006d),
.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
.vendor_name = "Roland",
@@ -1002,6 +1029,7 @@ YAMAHA_DEVICE(0x7010, "UB99"),
}
},
{
+ /* has ID 0x0076 when not in "Advanced Driver" mode */
USB_DEVICE(0x0582, 0x0075),
.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
.vendor_name = "BOSS",
@@ -1015,10 +1043,11 @@ YAMAHA_DEVICE(0x7010, "UB99"),
}
},
{
+ /* has ID 0x007b when not in "Advanced Driver" mode */
USB_DEVICE_VENDOR_SPEC(0x0582, 0x007a),
.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
.vendor_name = "Roland",
- /* RD-700SX, RD-300SX */
+ /* "RD" or "RD-700SX"? */
.ifnum = 0,
.type = QUIRK_MIDI_FIXED_ENDPOINT,
.data = & (const snd_usb_midi_endpoint_info_t) {
@@ -1048,6 +1077,15 @@ YAMAHA_DEVICE(0x7010, "UB99"),
}
}
},
+ /* TODO: add Edirol UA-101 support */
+ /* TODO: add Roland G-70 support */
+ /* TODO: add Roland V-SYNTH XT support */
+ /* TODO: add BOSS GT-PRO support */
+ /* TODO: add Edirol PC-50 support */
+ /* TODO: add Edirol PC-80 support */
+ /* TODO: add Edirol UA-1EX support */
+ /* TODO: add Edirol UM-3 support */
+ /* TODO: add Edirol MD-P1 support */
/* Midiman/M-Audio devices */
{
diff --git a/sound/usb/usx2y/usX2Yhwdep.c b/sound/usb/usx2y/usX2Yhwdep.c
index 0281a362857a..8abe08611df6 100644
--- a/sound/usb/usx2y/usX2Yhwdep.c
+++ b/sound/usb/usx2y/usX2Yhwdep.c
@@ -193,7 +193,7 @@ static int usX2Y_create_alsa_devices(snd_card_t* card)
do {
if ((err = usX2Y_create_usbmidi(card)) < 0) {
- snd_printk("usX2Y_create_alsa_devices: usX2Y_create_usbmidi error %i \n", err);
+ snd_printk(KERN_ERR "usX2Y_create_alsa_devices: usX2Y_create_usbmidi error %i \n", err);
break;
}
if ((err = usX2Y_audio_create(card)) < 0)
@@ -224,7 +224,7 @@ static int snd_usX2Y_hwdep_dsp_load(snd_hwdep_t *hw, snd_hwdep_dsp_image_t *dsp)
}
err = usb_set_interface(dev, 0, 1);
if (err)
- snd_printk("usb_set_interface error \n");
+ snd_printk(KERN_ERR "usb_set_interface error \n");
else
err = usb_bulk_msg(dev, usb_sndbulkpipe(dev, 2), buf, dsp->length, &lret, 6000);
kfree(buf);
@@ -235,17 +235,17 @@ static int snd_usX2Y_hwdep_dsp_load(snd_hwdep_t *hw, snd_hwdep_dsp_image_t *dsp)
msleep(250); // give the device some time
err = usX2Y_AsyncSeq04_init(priv);
if (err) {
- snd_printk("usX2Y_AsyncSeq04_init error \n");
+ snd_printk(KERN_ERR "usX2Y_AsyncSeq04_init error \n");
return err;
}
err = usX2Y_In04_init(priv);
if (err) {
- snd_printk("usX2Y_In04_init error \n");
+ snd_printk(KERN_ERR "usX2Y_In04_init error \n");
return err;
}
err = usX2Y_create_alsa_devices(hw->card);
if (err) {
- snd_printk("usX2Y_create_alsa_devices error %i \n", err);
+ snd_printk(KERN_ERR "usX2Y_create_alsa_devices error %i \n", err);
snd_card_free(hw->card);
return err;
}
diff --git a/sound/usb/usx2y/usbusx2y.c b/sound/usb/usx2y/usbusx2y.c
index e6e6da159671..cf77313c609d 100644
--- a/sound/usb/usx2y/usbusx2y.c
+++ b/sound/usb/usx2y/usbusx2y.c
@@ -251,9 +251,8 @@ static void i_usX2Y_In04Int(struct urb* urb, struct pt_regs *regs)
}
}
- if (err) {
- snd_printk("In04Int() usb_submit_urb err=%i\n", err);
- }
+ if (err)
+ snd_printk(KERN_ERR "In04Int() usb_submit_urb err=%i\n", err);
urb->dev = usX2Y->chip.dev;
usb_submit_urb(urb, GFP_ATOMIC);
diff --git a/sound/usb/usx2y/usbusx2yaudio.c b/sound/usb/usx2y/usbusx2yaudio.c
index 0f09e0de52dd..affda973cece 100644
--- a/sound/usb/usx2y/usbusx2yaudio.c
+++ b/sound/usb/usx2y/usbusx2yaudio.c
@@ -78,7 +78,7 @@ static int usX2Y_urb_capt_retire(snd_usX2Y_substream_t *subs)
for (i = 0; i < nr_of_packs(); i++) {
cp = (unsigned char*)urb->transfer_buffer + urb->iso_frame_desc[i].offset;
if (urb->iso_frame_desc[i].status) { /* active? hmm, skip this */
- snd_printk("activ frame status %i. Most propably some hardware problem.\n", urb->iso_frame_desc[i].status);
+ snd_printk(KERN_ERR "activ frame status %i. Most propably some hardware problem.\n", urb->iso_frame_desc[i].status);
return urb->iso_frame_desc[i].status;
}
len = urb->iso_frame_desc[i].actual_length / usX2Y->stride;
@@ -134,7 +134,7 @@ static int usX2Y_urb_play_prepare(snd_usX2Y_substream_t *subs,
counts = cap_urb->iso_frame_desc[pack].actual_length / usX2Y->stride;
count += counts;
if (counts < 43 || counts > 50) {
- snd_printk("should not be here with counts=%i\n", counts);
+ snd_printk(KERN_ERR "should not be here with counts=%i\n", counts);
return -EPIPE;
}
/* set up descriptor */
@@ -196,7 +196,7 @@ static int usX2Y_urb_submit(snd_usX2Y_substream_t *subs, struct urb *urb, int fr
urb->hcpriv = NULL;
urb->dev = subs->usX2Y->chip.dev; /* we need to set this at each time */
if ((err = usb_submit_urb(urb, GFP_ATOMIC)) < 0) {
- snd_printk("usb_submit_urb() returned %i\n", err);
+ snd_printk(KERN_ERR "usb_submit_urb() returned %i\n", err);
return err;
}
return 0;
@@ -283,16 +283,16 @@ static void usX2Y_clients_stop(usX2Ydev_t *usX2Y)
static void usX2Y_error_urb_status(usX2Ydev_t *usX2Y, snd_usX2Y_substream_t *subs, struct urb *urb)
{
- snd_printk("ep=%i stalled with status=%i\n", subs->endpoint, urb->status);
+ snd_printk(KERN_ERR "ep=%i stalled with status=%i\n", subs->endpoint, urb->status);
urb->status = 0;
usX2Y_clients_stop(usX2Y);
}
static void usX2Y_error_sequence(usX2Ydev_t *usX2Y, snd_usX2Y_substream_t *subs, struct urb *urb)
{
- snd_printk("Sequence Error!(hcd_frame=%i ep=%i%s;wait=%i,frame=%i).\n"
- "Most propably some urb of usb-frame %i is still missing.\n"
- "Cause could be too long delays in usb-hcd interrupt handling.\n",
+ snd_printk(KERN_ERR "Sequence Error!(hcd_frame=%i ep=%i%s;wait=%i,frame=%i).\n"
+ KERN_ERR "Most propably some urb of usb-frame %i is still missing.\n"
+ KERN_ERR "Cause could be too long delays in usb-hcd interrupt handling.\n",
usb_get_current_frame_number(usX2Y->chip.dev),
subs->endpoint, usb_pipein(urb->pipe) ? "in" : "out", usX2Y->wait_iso_frame, urb->start_frame, usX2Y->wait_iso_frame);
usX2Y_clients_stop(usX2Y);
@@ -653,9 +653,8 @@ static void i_usX2Y_04Int(struct urb* urb, struct pt_regs *regs)
{
usX2Ydev_t* usX2Y = urb->context;
- if (urb->status) {
- snd_printk("snd_usX2Y_04Int() urb->status=%i\n", urb->status);
- }
+ if (urb->status)
+ snd_printk(KERN_ERR "snd_usX2Y_04Int() urb->status=%i\n", urb->status);
if (0 == --usX2Y->US04->len)
wake_up(&usX2Y->In04WaitQueue);
}
@@ -740,7 +739,7 @@ static int usX2Y_format_set(usX2Ydev_t *usX2Y, snd_pcm_format_t format)
}
usb_kill_urb(usX2Y->In04urb);
if ((err = usb_set_interface(usX2Y->chip.dev, 0, alternate))) {
- snd_printk("usb_set_interface error \n");
+ snd_printk(KERN_ERR "usb_set_interface error \n");
return err;
}
usX2Y->In04urb->dev = usX2Y->chip.dev;
@@ -787,7 +786,7 @@ static int snd_usX2Y_pcm_hw_params(snd_pcm_substream_t *substream,
}
}
if (0 > (err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params)))) {
- snd_printk("snd_pcm_lib_malloc_pages(%p, %i) returned %i\n", substream, params_buffer_bytes(hw_params), err);
+ snd_printk(KERN_ERR "snd_pcm_lib_malloc_pages(%p, %i) returned %i\n", substream, params_buffer_bytes(hw_params), err);
return err;
}
return 0;
diff --git a/sound/usb/usx2y/usx2yhwdeppcm.c b/sound/usb/usx2y/usx2yhwdeppcm.c
index d0199c4e5551..0dc828ff9e94 100644
--- a/sound/usb/usx2y/usx2yhwdeppcm.c
+++ b/sound/usb/usx2y/usx2yhwdeppcm.c
@@ -73,7 +73,7 @@ static int usX2Y_usbpcm_urb_capt_retire(snd_usX2Y_substream_t *subs)
}
for (i = 0; i < nr_of_packs(); i++) {
if (urb->iso_frame_desc[i].status) { /* active? hmm, skip this */
- snd_printk("activ frame status %i. Most propably some hardware problem.\n", urb->iso_frame_desc[i].status);
+ snd_printk(KERN_ERR "activ frame status %i. Most propably some hardware problem.\n", urb->iso_frame_desc[i].status);
return urb->iso_frame_desc[i].status;
}
lens += urb->iso_frame_desc[i].actual_length / usX2Y->stride;
@@ -126,7 +126,7 @@ static int usX2Y_hwdep_urb_play_prepare(snd_usX2Y_substream_t *subs,
/* calculate the size of a packet */
counts = shm->captured_iso[shm->playback_iso_head].length / usX2Y->stride;
if (counts < 43 || counts > 50) {
- snd_printk("should not be here with counts=%i\n", counts);
+ snd_printk(KERN_ERR "should not be here with counts=%i\n", counts);
return -EPIPE;
}
/* set up descriptor */